1 /* $NetBSD: mvsata_pci.c,v 1.1 2009/07/27 12:34:14 kiyohara Exp $ */
3 * Copyright (c) 2008 KIYOHARA Takashi
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: mvsata_pci.c,v 1.1 2009/07/27 12:34:14 kiyohara Exp $");
31 #include <sys/param.h>
33 #include <sys/device.h>
34 #include <sys/errno.h>
37 #include <dev/pci/pcivar.h>
38 #include <dev/pci/pcidevs.h>
39 #include <dev/pci/pciidereg.h>
40 #include <dev/pci/pciidevar.h>
42 #include <dev/ic/mvsatareg.h>
43 #include <dev/ic/mvsatavar.h>
45 #define MVSATA_PCI_HCARBITER_SPACE_OFFSET 0x20000
47 #define MVSATA_PCI_COMMAND 0x00c00
48 #define MVSATA_PCI_COMMAND_MWRITECOMBINE (1 << 4)
49 #define MVSATA_PCI_COMMAND_MREADCOMBINE (1 << 5)
50 #define MVSATA_PCI_SERRMASK 0x00c28
51 #define MVSATA_PCI_MSITRIGGER 0x00c38
52 #define MVSATA_PCI_MODE 0x00d00
53 #define MVSATA_PCI_DISCTIMER 0x00d04
54 #define MVSATA_PCI_EROMBAR 0x00d2c
55 #define MVSATA_PCI_MAINCS 0x00d30
56 #define MVSATA_PCI_MAINCS_SPM (1 << 2) /* stop pci master */
57 #define MVSATA_PCI_MAINCS_PME (1 << 3) /* pci master empty */
58 #define MVSATA_PCI_MAINCS_GSR (1 << 4) /* glab soft reset */
59 #define MVSATA_PCI_E_IRQCAUSE 0x01900
60 #define MVSATA_PCI_E_IRQMASK 0x01910
61 #define MVSATA_PCI_XBARTIMEOUT 0x01d04
62 #define MVSATA_PCI_ERRLOWADDR 0x01d40
63 #define MVSATA_PCI_ERRHIGHADDR 0x01d44
64 #define MVSATA_PCI_ERRATTRIBUTE 0x01d48
65 #define MVSATA_PCI_ERRCOMMAND 0x01d50
66 #define MVSATA_PCI_IRQCAUSE 0x01d58
67 #define MVSATA_PCI_IRQMASK 0x01d5c
68 #define MVSATA_PCI_MAINIRQCAUSE 0x01d60
69 #define MVSATA_PCI_MAINIRQMASK 0x01d64
70 #define MVSATA_PCI_MAINIRQ_SATAERR(hc, port) \
71 (1 << (((port) << 1) + (hc) * 9))
72 #define MVSATA_PCI_MAINIRQ_SATADONE(hc, port) \
73 (1 << (((port) << 1) + (hc) * 9 + 1))
74 #define MVSATA_PCI_MAINIRQ_SATACOALDONE(hc) (1 << ((hc) * 9 + 8))
75 #define MVSATA_PCI_MAINIRQ_PCI (1 << 18)
76 #define MVSATA_PCI_FLASHCTL 0x1046c
77 #define MVSATA_PCI_GPIOPORTCTL 0x104f0
78 #define MVSATA_PCI_RESETCFG 0x180d8
80 #define MVSATA_PCI_DEV(psc) (psc->psc_sc.sc_wdcdev.sc_atac.atac_dev)
83 struct mvsata_pci_softc
{
84 struct mvsata_softc psc_sc
;
86 pci_chipset_tag_t psc_pc
;
89 bus_space_tag_t psc_iot
;
90 bus_space_handle_t psc_ioh
;
96 static int mvsata_pci_match(device_t
, struct cfdata
*, void *);
97 static void mvsata_pci_attach(device_t
, device_t
, void *);
98 static int mvsata_pci_detach(device_t
, int);
100 static int mvsata_pci_intr(void *);
101 static bool mvsata_pci_resume(device_t
, pmf_qual_t qual
);
103 static int mvsata_pci_sreset(struct mvsata_softc
*);
104 static int mvsata_pci_misc_reset(struct mvsata_softc
*);
105 static void mvsata_pci_enable_intr(struct mvsata_port
*, int);
108 CFATTACH_DECL_NEW(mvsata_pci
, sizeof(struct mvsata_pci_softc
),
109 mvsata_pci_match
, mvsata_pci_attach
, mvsata_pci_detach
, NULL
);
114 * This function returns 2, because mvsata is high priority more than pciide.
117 mvsata_pci_match(device_t parent
, struct cfdata
*match
, void *aux
)
119 struct pci_attach_args
*pa
= aux
;
121 if (PCI_VENDOR(pa
->pa_id
) == PCI_VENDOR_MARVELL
)
122 switch (PCI_PRODUCT(pa
->pa_id
)) {
123 case PCI_PRODUCT_MARVELL_88SX5040
:
124 case PCI_PRODUCT_MARVELL_88SX5041
:
125 case PCI_PRODUCT_MARVELL_88SX5080
:
126 case PCI_PRODUCT_MARVELL_88SX5081
:
127 case PCI_PRODUCT_MARVELL_88SX6040
:
128 case PCI_PRODUCT_MARVELL_88SX6041
:
129 case PCI_PRODUCT_MARVELL_88SX6042
:
130 case PCI_PRODUCT_MARVELL_88SX6080
:
131 case PCI_PRODUCT_MARVELL_88SX6081
:
132 case PCI_PRODUCT_MARVELL_88SX7042
:
135 if (PCI_VENDOR(pa
->pa_id
) == PCI_VENDOR_ADP2
)
136 switch (PCI_PRODUCT(pa
->pa_id
)) {
137 case PCI_PRODUCT_ADP2_1420SA
:
138 case PCI_PRODUCT_ADP2_1430SA
:
141 if (PCI_VENDOR(pa
->pa_id
) == PCI_VENDOR_TRIONES
&&
142 PCI_PRODUCT(pa
->pa_id
) == PCI_PRODUCT_TRIONES_ROCKETRAID_2310
)
148 mvsata_pci_attach(device_t parent
, device_t self
, void *aux
)
150 struct pci_attach_args
*pa
= aux
;
151 struct mvsata_pci_softc
*psc
= device_private(self
);
152 struct mvsata_softc
*sc
= &psc
->psc_sc
;
153 pci_intr_handle_t intrhandle
;
157 int read_pre_amps
, hc
, port
, rv
;
161 sc
->sc_wdcdev
.sc_atac
.atac_dev
= self
;
162 sc
->sc_model
= PCI_PRODUCT(pa
->pa_id
);
163 sc
->sc_rev
= PCI_REVISION(pa
->pa_class
);
164 sc
->sc_dmat
= pa
->pa_dmat
;
165 sc
->sc_enable_intr
= mvsata_pci_enable_intr
;
167 pci_devinfo(pa
->pa_id
, pa
->pa_class
, 0, devinfo
, sizeof(devinfo
));
168 aprint_naive(": Marvell Serial-ATA Host Controller\n");
169 aprint_normal(": %s\n", devinfo
);
171 /* Map I/O register */
172 if (pci_mapreg_map(pa
, PCI_MAPREG_START
,
173 PCI_MAPREG_TYPE_MEM
| PCI_MAPREG_MEM_TYPE_32BIT
, 0,
174 &psc
->psc_iot
, &psc
->psc_ioh
, NULL
, &size
) != 0) {
175 aprint_error_dev(self
, "can't map registers\n");
178 psc
->psc_pc
= pa
->pa_pc
;
179 psc
->psc_tag
= pa
->pa_tag
;
181 if (bus_space_subregion(psc
->psc_iot
, psc
->psc_ioh
,
182 MVSATA_PCI_HCARBITER_SPACE_OFFSET
,
183 size
- MVSATA_PCI_HCARBITER_SPACE_OFFSET
, &sc
->sc_ioh
)) {
184 aprint_error_dev(self
, "can't subregion registers\n");
187 sc
->sc_iot
= psc
->psc_iot
;
190 csr
= pci_conf_read(psc
->psc_pc
, psc
->psc_tag
, PCI_COMMAND_STATUS_REG
);
191 csr
|= PCI_COMMAND_MASTER_ENABLE
;
192 pci_conf_write(psc
->psc_pc
, psc
->psc_tag
, PCI_COMMAND_STATUS_REG
, csr
);
194 if (pci_intr_map(pa
, &intrhandle
) != 0) {
195 aprint_error_dev(self
, "couldn't map interrupt\n");
198 intrstr
= pci_intr_string(psc
->psc_pc
, intrhandle
);
199 psc
->psc_ih
= pci_intr_establish(psc
->psc_pc
, intrhandle
, IPL_BIO
,
200 mvsata_pci_intr
, sc
);
201 if (psc
->psc_ih
== NULL
) {
202 aprint_error_dev(self
, "couldn't establish interrupt\n");
205 aprint_normal_dev(self
, "interrupting at %s\n",
206 intrstr
? intrstr
: "unknown interrupt");
209 * Check if TWSI serial ROM initialization was triggered.
210 * If so, then PRE/AMP configuration probably are set after
211 * reset by serial ROM. If not then override the PRE/AMP
214 reg
= bus_space_read_4(psc
->psc_iot
, psc
->psc_ioh
, MVSATA_PCI_RESETCFG
);
215 read_pre_amps
= (reg
& 0x00000001) ? 1 : 0;
217 rv
= mvsata_attach(sc
, mvsata_pci_sreset
, mvsata_pci_misc_reset
,
220 pci_intr_disestablish(psc
->psc_pc
, psc
->psc_ih
);
224 mask
= MVSATA_PCI_MAINIRQ_PCI
;
225 for (hc
= 0; hc
< sc
->sc_hc
; hc
++)
226 for (port
= 0; port
< sc
->sc_port
; port
++)
228 MVSATA_PCI_MAINIRQ_SATAERR(hc
, port
) |
229 MVSATA_PCI_MAINIRQ_SATADONE(hc
, port
);
230 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
, MVSATA_PCI_MAINIRQMASK
,
233 if (!pmf_device_register(self
, NULL
, mvsata_pci_resume
))
234 aprint_error_dev(self
, "couldn't establish power handler\n");
238 mvsata_pci_detach(device_t self
, int flags
)
240 struct mvsata_pci_softc
*psc
= device_private(self
);
242 /* XXXX: needs reset ? */
244 pci_intr_disestablish(psc
->psc_pc
, psc
->psc_ih
);
245 pmf_device_deregister(self
);
250 mvsata_pci_intr(void *arg
)
252 struct mvsata_pci_softc
*psc
= (struct mvsata_pci_softc
*)arg
;
253 struct mvsata_softc
*sc
= &psc
->psc_sc
;
255 int hc
, port
, handled
= 0;
257 cause
= bus_space_read_4(psc
->psc_iot
, psc
->psc_ioh
,
258 MVSATA_PCI_MAINIRQCAUSE
);
259 for (hc
= 0; hc
< sc
->sc_hc
; hc
++)
260 for (port
= 0; port
< sc
->sc_port
; port
++)
261 if (cause
& MVSATA_PCI_MAINIRQ_SATAERR(hc
, port
)) {
262 struct mvsata_port
*mvport
;
264 mvport
= sc
->sc_hcs
[hc
].hc_ports
[port
];
265 handled
|= mvsata_error(mvport
);
267 for (hc
= 0; hc
< sc
->sc_hc
; hc
++)
269 (MVSATA_PCI_MAINIRQ_SATADONE(hc
, 0) |
270 MVSATA_PCI_MAINIRQ_SATADONE(hc
, 1) |
271 MVSATA_PCI_MAINIRQ_SATADONE(hc
, 2) |
272 MVSATA_PCI_MAINIRQ_SATADONE(hc
, 3)))
273 handled
|= mvsata_intr(&sc
->sc_hcs
[hc
]);
275 if (cause
& MVSATA_PCI_MAINIRQ_PCI
) {
278 if (sc
->sc_flags
& MVSATA_FLAGS_PCIE
) {
279 pe_cause
= bus_space_read_4(psc
->psc_iot
, psc
->psc_ioh
,
280 MVSATA_PCI_E_IRQCAUSE
);
281 aprint_error_dev(MVSATA_PCI_DEV(psc
),
282 "PCIe error: 0x%x\n", pe_cause
);
283 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
284 MVSATA_PCI_E_IRQCAUSE
, ~pe_cause
);
286 pe_cause
= bus_space_read_4(psc
->psc_iot
, psc
->psc_ioh
,
287 MVSATA_PCI_IRQCAUSE
);
288 aprint_error_dev(MVSATA_PCI_DEV(psc
),
289 "PCI error: 0x%x\n", pe_cause
);
290 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
291 MVSATA_PCI_IRQCAUSE
, ~pe_cause
);
294 handled
= 1; /* XXXXX */
301 mvsata_pci_resume(device_t dev
, pmf_qual_t qual
)
311 mvsata_pci_sreset(struct mvsata_softc
*sc
)
313 struct mvsata_pci_softc
*psc
= (struct mvsata_pci_softc
*)sc
;
317 val
= bus_space_read_4(psc
->psc_iot
, psc
->psc_ioh
, MVSATA_PCI_MAINCS
);
318 val
|= MVSATA_PCI_MAINCS_SPM
;
319 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
, MVSATA_PCI_MAINCS
, val
);
321 for (i
= 0; i
< 1000; i
++) {
323 val
= bus_space_read_4(psc
->psc_iot
, psc
->psc_ioh
,
325 if (val
& MVSATA_PCI_MAINCS_PME
)
328 if (!(val
& MVSATA_PCI_MAINCS_PME
)) {
329 aprint_error_dev(MVSATA_PCI_DEV(psc
),
330 "PCI master won't flush\n");
335 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
, MVSATA_PCI_MAINCS
,
336 val
| MVSATA_PCI_MAINCS_GSR
);
337 val
= bus_space_read_4(psc
->psc_iot
, psc
->psc_ioh
, MVSATA_PCI_MAINCS
);
339 if (!(val
& MVSATA_PCI_MAINCS_GSR
)) {
340 aprint_error_dev(MVSATA_PCI_DEV(psc
),
341 "can't set global reset\n");
345 /* clear reset and *reenable the PCI master* (not mentioned in spec) */
346 val
&= ~(MVSATA_PCI_MAINCS_GSR
| MVSATA_PCI_MAINCS_SPM
);
347 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
, MVSATA_PCI_MAINCS
, val
);
348 val
= bus_space_read_4(psc
->psc_iot
, psc
->psc_ioh
, MVSATA_PCI_MAINCS
);
350 if (val
& MVSATA_PCI_MAINCS_GSR
) {
351 aprint_error_dev(MVSATA_PCI_DEV(psc
),
352 "can't set global reset\n");
360 mvsata_pci_misc_reset(struct mvsata_softc
*sc
)
362 struct mvsata_pci_softc
*psc
= (struct mvsata_pci_softc
*)sc
;
363 #define MVSATA_PCI_COMMAND_DEFAULT 0x0107e371
364 #define MVSATA_PCI_COMMAND_PCI_CONVENTIONAL_ONLY 0x800003e0
365 uint32_t val
, pci_command
= MVSATA_PCI_COMMAND_DEFAULT
;
367 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
, MVSATA_PCI_FLASHCTL
,
370 if (sc
->sc_gen
== gen2
|| sc
->sc_gen
== gen2e
) {
371 val
= bus_space_read_4(psc
->psc_iot
, psc
->psc_ioh
,
372 MVSATA_PCI_GPIOPORTCTL
);
379 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
380 MVSATA_PCI_GPIOPORTCTL
, val
);
383 if (sc
->sc_gen
== gen1
) {
384 /* Expansion ROM BAR Enable */
385 val
= bus_space_read_4(psc
->psc_iot
, psc
->psc_ioh
,
387 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
388 MVSATA_PCI_EROMBAR
, val
| 0x00000001);
391 if (sc
->sc_flags
& MVSATA_FLAGS_PCIE
) {
392 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
393 MVSATA_PCI_MAINIRQMASK
, 0);
394 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
395 MVSATA_PCI_E_IRQCAUSE
, 0);
396 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
397 MVSATA_PCI_E_IRQMASK
, 0);
399 val
= bus_space_read_4(psc
->psc_iot
, psc
->psc_ioh
,
401 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
402 MVSATA_PCI_MODE
, val
& 0xff00ffff);
403 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
404 MVSATA_PCI_DISCTIMER
, 0);
405 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
406 MVSATA_PCI_MSITRIGGER
, 0);
407 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
408 MVSATA_PCI_XBARTIMEOUT
, 0x000100ff);
409 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
410 MVSATA_PCI_MAINIRQMASK
, 0);
411 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
412 MVSATA_PCI_SERRMASK
, 0);
413 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
414 MVSATA_PCI_IRQCAUSE
, 0);
415 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
416 MVSATA_PCI_IRQMASK
, 0);
417 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
418 MVSATA_PCI_ERRLOWADDR
, 0);
419 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
420 MVSATA_PCI_ERRHIGHADDR
, 0);
421 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
422 MVSATA_PCI_ERRATTRIBUTE
, 0);
423 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
424 MVSATA_PCI_ERRCOMMAND
, 0);
428 if (sc
->sc_gen
== gen1
) {
429 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
430 MVSATA_PCI_GPIOPORTCTL
, 0);
432 /* XXXX: 50xxB2 errata ? */
434 if (sc
->sc_rev
== 3) {
437 val
= bus_space_read_4(psc
->psc_iot
, psc
->psc_ioh
,
438 MVSATA_PCI_GPIOPORTCTL
);
440 /* XXXX: check HDD connected */
442 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
443 MVSATA_PCI_GPIOPORTCTL
, val
);
447 /* Disable Flash controller clock */
448 val
= bus_space_read_4(psc
->psc_iot
, psc
->psc_ioh
,
450 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
451 MVSATA_PCI_EROMBAR
, val
& ~0x00000001);
454 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
455 MVSATA_PCI_GPIOPORTCTL
, 0x00000060);
457 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
458 MVSATA_PCI_GPIOPORTCTL
, 0x00000070);
461 if (sc
->sc_flags
& MVSATA_FLAGS_PCIE
)
462 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
463 MVSATA_PCI_E_IRQMASK
, 0x0000070a);
465 val
= bus_space_read_4(psc
->psc_iot
, psc
->psc_ioh
,
467 if ((val
& 0x30) >> 4) { /* PCI-X */
469 ((sc
->sc_model
== PCI_PRODUCT_MARVELL_88SX6041
||
470 sc
->sc_model
== PCI_PRODUCT_MARVELL_88SX6081
) &&
474 ~MVSATA_PCI_COMMAND_PCI_CONVENTIONAL_ONLY
;
475 if (sc
->sc_gen
== gen1
|| mv60x1b2
)
477 ~MVSATA_PCI_COMMAND_MWRITECOMBINE
;
479 if (sc
->sc_gen
== gen1
)
481 ~(MVSATA_PCI_COMMAND_MWRITECOMBINE
|
482 MVSATA_PCI_COMMAND_MREADCOMBINE
);
483 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
484 MVSATA_PCI_COMMAND
, pci_command
);
486 #define MVSATA_PCI_INTERRUPT_MASK 0x00d77fe6
487 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
488 MVSATA_PCI_SERRMASK
, MVSATA_PCI_INTERRUPT_MASK
);
489 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
,
490 MVSATA_PCI_IRQMASK
, MVSATA_PCI_INTERRUPT_MASK
);
497 mvsata_pci_enable_intr(struct mvsata_port
*mvport
, int on
)
499 struct mvsata_pci_softc
*psc
=
500 device_private(mvport
->port_ata_channel
.ch_atac
->atac_dev
);
502 int hc
= mvport
->port_hc
->hc
, port
= mvport
->port
;
504 mask
= bus_space_read_4(psc
->psc_iot
, psc
->psc_ioh
,
505 MVSATA_PCI_MAINIRQMASK
);
507 mask
|= MVSATA_PCI_MAINIRQ_SATADONE(hc
, port
);
509 mask
&= ~MVSATA_PCI_MAINIRQ_SATADONE(hc
, port
);
510 bus_space_write_4(psc
->psc_iot
, psc
->psc_ioh
, MVSATA_PCI_MAINIRQMASK
,