Home | History | Annotate | Line # | Download | only in pci
mvsata_pci.c revision 1.3
      1  1.3    dyoung /*	$NetBSD: mvsata_pci.c,v 1.3 2010/02/24 22:38:01 dyoung Exp $	*/
      2  1.1  kiyohara /*
      3  1.1  kiyohara  * Copyright (c) 2008 KIYOHARA Takashi
      4  1.1  kiyohara  * All rights reserved.
      5  1.1  kiyohara  *
      6  1.1  kiyohara  * Redistribution and use in source and binary forms, with or without
      7  1.1  kiyohara  * modification, are permitted provided that the following conditions
      8  1.1  kiyohara  * are met:
      9  1.1  kiyohara  * 1. Redistributions of source code must retain the above copyright
     10  1.1  kiyohara  *    notice, this list of conditions and the following disclaimer.
     11  1.1  kiyohara  * 2. Redistributions in binary form must reproduce the above copyright
     12  1.1  kiyohara  *    notice, this list of conditions and the following disclaimer in the
     13  1.1  kiyohara  *    documentation and/or other materials provided with the distribution.
     14  1.1  kiyohara  *
     15  1.1  kiyohara  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  1.1  kiyohara  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17  1.1  kiyohara  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18  1.1  kiyohara  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     19  1.1  kiyohara  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     20  1.1  kiyohara  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     21  1.1  kiyohara  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22  1.1  kiyohara  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     23  1.1  kiyohara  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     24  1.1  kiyohara  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25  1.1  kiyohara  * POSSIBILITY OF SUCH DAMAGE.
     26  1.1  kiyohara  */
     27  1.1  kiyohara 
     28  1.1  kiyohara #include <sys/cdefs.h>
     29  1.3    dyoung __KERNEL_RCSID(0, "$NetBSD: mvsata_pci.c,v 1.3 2010/02/24 22:38:01 dyoung Exp $");
     30  1.1  kiyohara 
     31  1.1  kiyohara #include <sys/param.h>
     32  1.1  kiyohara #include <sys/bus.h>
     33  1.1  kiyohara #include <sys/device.h>
     34  1.1  kiyohara #include <sys/errno.h>
     35  1.1  kiyohara #include <sys/pmf.h>
     36  1.1  kiyohara 
     37  1.1  kiyohara #include <dev/pci/pcivar.h>
     38  1.1  kiyohara #include <dev/pci/pcidevs.h>
     39  1.1  kiyohara #include <dev/pci/pciidereg.h>
     40  1.1  kiyohara #include <dev/pci/pciidevar.h>
     41  1.1  kiyohara 
     42  1.1  kiyohara #include <dev/ic/mvsatareg.h>
     43  1.1  kiyohara #include <dev/ic/mvsatavar.h>
     44  1.1  kiyohara 
     45  1.1  kiyohara #define MVSATA_PCI_HCARBITER_SPACE_OFFSET	0x20000
     46  1.1  kiyohara 
     47  1.1  kiyohara #define MVSATA_PCI_COMMAND	0x00c00
     48  1.1  kiyohara #define MVSATA_PCI_COMMAND_MWRITECOMBINE	(1 << 4)
     49  1.1  kiyohara #define MVSATA_PCI_COMMAND_MREADCOMBINE		(1 << 5)
     50  1.1  kiyohara #define MVSATA_PCI_SERRMASK	0x00c28
     51  1.1  kiyohara #define MVSATA_PCI_MSITRIGGER	0x00c38
     52  1.1  kiyohara #define MVSATA_PCI_MODE		0x00d00
     53  1.1  kiyohara #define MVSATA_PCI_DISCTIMER	0x00d04
     54  1.1  kiyohara #define MVSATA_PCI_EROMBAR	0x00d2c
     55  1.1  kiyohara #define MVSATA_PCI_MAINCS	0x00d30
     56  1.1  kiyohara #define MVSATA_PCI_MAINCS_SPM		(1 << 2)	/* stop pci master */
     57  1.1  kiyohara #define MVSATA_PCI_MAINCS_PME		(1 << 3)	/* pci master empty */
     58  1.1  kiyohara #define MVSATA_PCI_MAINCS_GSR		(1 << 4)	/* glab soft reset */
     59  1.1  kiyohara #define MVSATA_PCI_E_IRQCAUSE	0x01900
     60  1.1  kiyohara #define MVSATA_PCI_E_IRQMASK	0x01910
     61  1.1  kiyohara #define MVSATA_PCI_XBARTIMEOUT	0x01d04
     62  1.1  kiyohara #define MVSATA_PCI_ERRLOWADDR	0x01d40
     63  1.1  kiyohara #define MVSATA_PCI_ERRHIGHADDR	0x01d44
     64  1.1  kiyohara #define MVSATA_PCI_ERRATTRIBUTE	0x01d48
     65  1.1  kiyohara #define MVSATA_PCI_ERRCOMMAND	0x01d50
     66  1.1  kiyohara #define MVSATA_PCI_IRQCAUSE	0x01d58
     67  1.1  kiyohara #define MVSATA_PCI_IRQMASK	0x01d5c
     68  1.1  kiyohara #define MVSATA_PCI_MAINIRQCAUSE	0x01d60
     69  1.1  kiyohara #define MVSATA_PCI_MAINIRQMASK	0x01d64
     70  1.1  kiyohara #define MVSATA_PCI_MAINIRQ_SATAERR(hc, port) \
     71  1.1  kiyohara 					(1 << (((port) << 1) + (hc) * 9))
     72  1.1  kiyohara #define MVSATA_PCI_MAINIRQ_SATADONE(hc, port) \
     73  1.1  kiyohara 					(1 << (((port) << 1) + (hc) * 9 + 1))
     74  1.1  kiyohara #define MVSATA_PCI_MAINIRQ_SATACOALDONE(hc)	(1 << ((hc) * 9 + 8))
     75  1.1  kiyohara #define MVSATA_PCI_MAINIRQ_PCI		(1 << 18)
     76  1.1  kiyohara #define MVSATA_PCI_FLASHCTL	0x1046c
     77  1.1  kiyohara #define MVSATA_PCI_GPIOPORTCTL	0x104f0
     78  1.1  kiyohara #define MVSATA_PCI_RESETCFG	0x180d8
     79  1.1  kiyohara 
     80  1.1  kiyohara #define MVSATA_PCI_DEV(psc)	(psc->psc_sc.sc_wdcdev.sc_atac.atac_dev)
     81  1.1  kiyohara 
     82  1.1  kiyohara 
     83  1.1  kiyohara struct mvsata_pci_softc {
     84  1.1  kiyohara 	struct mvsata_softc psc_sc;
     85  1.1  kiyohara 
     86  1.1  kiyohara 	pci_chipset_tag_t psc_pc;
     87  1.1  kiyohara 	pcitag_t psc_tag;
     88  1.1  kiyohara 
     89  1.1  kiyohara 	bus_space_tag_t psc_iot;
     90  1.1  kiyohara 	bus_space_handle_t psc_ioh;
     91  1.1  kiyohara 
     92  1.1  kiyohara 	void *psc_ih;
     93  1.1  kiyohara };
     94  1.1  kiyohara 
     95  1.1  kiyohara 
     96  1.1  kiyohara static int  mvsata_pci_match(device_t, struct cfdata *, void *);
     97  1.1  kiyohara static void mvsata_pci_attach(device_t, device_t, void *);
     98  1.1  kiyohara static int mvsata_pci_detach(device_t, int);
     99  1.1  kiyohara 
    100  1.1  kiyohara static int mvsata_pci_intr(void *);
    101  1.3    dyoung static bool mvsata_pci_resume(device_t, const pmf_qual_t *qual);
    102  1.1  kiyohara 
    103  1.1  kiyohara static int mvsata_pci_sreset(struct mvsata_softc *);
    104  1.1  kiyohara static int mvsata_pci_misc_reset(struct mvsata_softc *);
    105  1.1  kiyohara static void mvsata_pci_enable_intr(struct mvsata_port *, int);
    106  1.1  kiyohara 
    107  1.1  kiyohara 
    108  1.1  kiyohara CFATTACH_DECL_NEW(mvsata_pci, sizeof(struct mvsata_pci_softc),
    109  1.1  kiyohara     mvsata_pci_match, mvsata_pci_attach, mvsata_pci_detach, NULL);
    110  1.1  kiyohara 
    111  1.1  kiyohara 
    112  1.1  kiyohara /*
    113  1.1  kiyohara  * mvsata_pci_match()
    114  1.1  kiyohara  *    This function returns 2, because mvsata is high priority more than pciide.
    115  1.1  kiyohara  */
    116  1.1  kiyohara static int
    117  1.1  kiyohara mvsata_pci_match(device_t parent, struct cfdata *match, void *aux)
    118  1.1  kiyohara {
    119  1.1  kiyohara 	struct pci_attach_args *pa = aux;
    120  1.1  kiyohara 
    121  1.1  kiyohara 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_MARVELL)
    122  1.1  kiyohara 		switch (PCI_PRODUCT(pa->pa_id)) {
    123  1.1  kiyohara 		case PCI_PRODUCT_MARVELL_88SX5040:
    124  1.1  kiyohara 		case PCI_PRODUCT_MARVELL_88SX5041:
    125  1.1  kiyohara 		case PCI_PRODUCT_MARVELL_88SX5080:
    126  1.1  kiyohara 		case PCI_PRODUCT_MARVELL_88SX5081:
    127  1.1  kiyohara 		case PCI_PRODUCT_MARVELL_88SX6040:
    128  1.1  kiyohara 		case PCI_PRODUCT_MARVELL_88SX6041:
    129  1.1  kiyohara 		case PCI_PRODUCT_MARVELL_88SX6042:
    130  1.1  kiyohara 		case PCI_PRODUCT_MARVELL_88SX6080:
    131  1.1  kiyohara 		case PCI_PRODUCT_MARVELL_88SX6081:
    132  1.1  kiyohara 		case PCI_PRODUCT_MARVELL_88SX7042:
    133  1.1  kiyohara 			return 2;
    134  1.1  kiyohara 		}
    135  1.1  kiyohara 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ADP2)
    136  1.1  kiyohara 		switch (PCI_PRODUCT(pa->pa_id)) {
    137  1.1  kiyohara 		case PCI_PRODUCT_ADP2_1420SA:
    138  1.1  kiyohara 		case PCI_PRODUCT_ADP2_1430SA:
    139  1.1  kiyohara 			return 2;
    140  1.1  kiyohara 		}
    141  1.1  kiyohara 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_TRIONES &&
    142  1.1  kiyohara 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_TRIONES_ROCKETRAID_2310)
    143  1.1  kiyohara 			return 2;
    144  1.1  kiyohara 	return 0;
    145  1.1  kiyohara }
    146  1.1  kiyohara 
    147  1.1  kiyohara static void
    148  1.1  kiyohara mvsata_pci_attach(device_t parent, device_t self, void *aux)
    149  1.1  kiyohara {
    150  1.1  kiyohara 	struct pci_attach_args *pa = aux;
    151  1.1  kiyohara 	struct mvsata_pci_softc *psc = device_private(self);
    152  1.1  kiyohara 	struct mvsata_softc *sc = &psc->psc_sc;
    153  1.1  kiyohara 	pci_intr_handle_t intrhandle;
    154  1.1  kiyohara 	pcireg_t csr;
    155  1.1  kiyohara 	bus_size_t size;
    156  1.1  kiyohara 	uint32_t reg, mask;
    157  1.1  kiyohara 	int read_pre_amps, hc, port, rv;
    158  1.1  kiyohara 	char devinfo[256];
    159  1.1  kiyohara 	const char *intrstr;
    160  1.1  kiyohara 
    161  1.1  kiyohara 	sc->sc_wdcdev.sc_atac.atac_dev = self;
    162  1.1  kiyohara 	sc->sc_model = PCI_PRODUCT(pa->pa_id);
    163  1.1  kiyohara 	sc->sc_rev = PCI_REVISION(pa->pa_class);
    164  1.1  kiyohara 	sc->sc_dmat = pa->pa_dmat;
    165  1.1  kiyohara 	sc->sc_enable_intr = mvsata_pci_enable_intr;
    166  1.1  kiyohara 
    167  1.1  kiyohara 	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
    168  1.1  kiyohara 	aprint_naive(": Marvell Serial-ATA Host Controller\n");
    169  1.1  kiyohara 	aprint_normal(": %s\n", devinfo);
    170  1.1  kiyohara 
    171  1.1  kiyohara 	/* Map I/O register */
    172  1.1  kiyohara 	if (pci_mapreg_map(pa, PCI_MAPREG_START,
    173  1.1  kiyohara 	    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
    174  1.1  kiyohara 	    &psc->psc_iot, &psc->psc_ioh, NULL, &size) != 0) {
    175  1.1  kiyohara 		aprint_error_dev(self, "can't map registers\n");
    176  1.1  kiyohara 		return;
    177  1.1  kiyohara 	}
    178  1.1  kiyohara 	psc->psc_pc = pa->pa_pc;
    179  1.1  kiyohara 	psc->psc_tag = pa->pa_tag;
    180  1.1  kiyohara 
    181  1.1  kiyohara 	if (bus_space_subregion(psc->psc_iot, psc->psc_ioh,
    182  1.1  kiyohara 	    MVSATA_PCI_HCARBITER_SPACE_OFFSET,
    183  1.1  kiyohara 	    size - MVSATA_PCI_HCARBITER_SPACE_OFFSET, &sc->sc_ioh)) {
    184  1.1  kiyohara 		aprint_error_dev(self, "can't subregion registers\n");
    185  1.1  kiyohara 		return;
    186  1.1  kiyohara 	}
    187  1.1  kiyohara 	sc->sc_iot = psc->psc_iot;
    188  1.1  kiyohara 
    189  1.1  kiyohara 	/* Enable device */
    190  1.1  kiyohara 	csr = pci_conf_read(psc->psc_pc, psc->psc_tag, PCI_COMMAND_STATUS_REG);
    191  1.1  kiyohara 	csr |= PCI_COMMAND_MASTER_ENABLE;
    192  1.1  kiyohara 	pci_conf_write(psc->psc_pc, psc->psc_tag, PCI_COMMAND_STATUS_REG, csr);
    193  1.1  kiyohara 
    194  1.1  kiyohara 	if (pci_intr_map(pa, &intrhandle) != 0) {
    195  1.1  kiyohara 		aprint_error_dev(self, "couldn't map interrupt\n");
    196  1.1  kiyohara 		return;
    197  1.1  kiyohara 	}
    198  1.1  kiyohara 	intrstr = pci_intr_string(psc->psc_pc, intrhandle);
    199  1.1  kiyohara 	psc->psc_ih = pci_intr_establish(psc->psc_pc, intrhandle, IPL_BIO,
    200  1.1  kiyohara 	    mvsata_pci_intr, sc);
    201  1.1  kiyohara 	if (psc->psc_ih == NULL) {
    202  1.1  kiyohara 		aprint_error_dev(self, "couldn't establish interrupt\n");
    203  1.1  kiyohara 		return;
    204  1.1  kiyohara 	}
    205  1.1  kiyohara 	aprint_normal_dev(self, "interrupting at %s\n",
    206  1.1  kiyohara 	    intrstr ? intrstr : "unknown interrupt");
    207  1.1  kiyohara 
    208  1.1  kiyohara 	/*
    209  1.1  kiyohara 	 * Check if TWSI serial ROM initialization was triggered.
    210  1.1  kiyohara 	 * If so, then PRE/AMP configuration probably are set after
    211  1.1  kiyohara 	 * reset by serial ROM. If not then override the PRE/AMP
    212  1.1  kiyohara 	 * values.
    213  1.1  kiyohara 	 */
    214  1.1  kiyohara 	reg = bus_space_read_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_RESETCFG);
    215  1.1  kiyohara 	read_pre_amps = (reg & 0x00000001) ? 1 : 0;
    216  1.1  kiyohara 
    217  1.1  kiyohara 	rv = mvsata_attach(sc, mvsata_pci_sreset, mvsata_pci_misc_reset,
    218  1.1  kiyohara 	    read_pre_amps);
    219  1.1  kiyohara 	if (rv != 0) {
    220  1.1  kiyohara 		pci_intr_disestablish(psc->psc_pc, psc->psc_ih);
    221  1.1  kiyohara 		return;
    222  1.1  kiyohara 	}
    223  1.1  kiyohara 
    224  1.1  kiyohara 	mask = MVSATA_PCI_MAINIRQ_PCI;
    225  1.1  kiyohara 	for (hc = 0; hc < sc->sc_hc; hc++)
    226  1.1  kiyohara 		for (port = 0; port < sc->sc_port; port++)
    227  1.1  kiyohara 			mask |=
    228  1.1  kiyohara 			    MVSATA_PCI_MAINIRQ_SATAERR(hc, port) |
    229  1.1  kiyohara 			    MVSATA_PCI_MAINIRQ_SATADONE(hc, port);
    230  1.1  kiyohara 	bus_space_write_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINIRQMASK,
    231  1.1  kiyohara 	    mask);
    232  1.1  kiyohara 
    233  1.1  kiyohara 	if (!pmf_device_register(self, NULL, mvsata_pci_resume))
    234  1.1  kiyohara 		aprint_error_dev(self, "couldn't establish power handler\n");
    235  1.1  kiyohara }
    236  1.1  kiyohara 
    237  1.1  kiyohara static int
    238  1.1  kiyohara mvsata_pci_detach(device_t self, int flags)
    239  1.1  kiyohara {
    240  1.1  kiyohara 	struct mvsata_pci_softc *psc = device_private(self);
    241  1.1  kiyohara 
    242  1.1  kiyohara /* XXXX: needs reset ? */
    243  1.1  kiyohara 
    244  1.1  kiyohara 	pci_intr_disestablish(psc->psc_pc, psc->psc_ih);
    245  1.1  kiyohara 	pmf_device_deregister(self);
    246  1.1  kiyohara 	return 0;
    247  1.1  kiyohara }
    248  1.1  kiyohara 
    249  1.1  kiyohara static int
    250  1.1  kiyohara mvsata_pci_intr(void *arg)
    251  1.1  kiyohara {
    252  1.1  kiyohara 	struct mvsata_pci_softc *psc = (struct mvsata_pci_softc *)arg;
    253  1.1  kiyohara 	struct mvsata_softc *sc = &psc->psc_sc;
    254  1.1  kiyohara 	uint32_t cause;
    255  1.1  kiyohara 	int hc, port, handled = 0;
    256  1.1  kiyohara 
    257  1.1  kiyohara 	cause = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
    258  1.1  kiyohara 	    MVSATA_PCI_MAINIRQCAUSE);
    259  1.1  kiyohara 	for (hc = 0; hc < sc->sc_hc; hc++)
    260  1.1  kiyohara 		for (port = 0; port < sc->sc_port; port++)
    261  1.1  kiyohara 			if (cause & MVSATA_PCI_MAINIRQ_SATAERR(hc, port)) {
    262  1.1  kiyohara 				struct mvsata_port *mvport;
    263  1.1  kiyohara 
    264  1.1  kiyohara 				mvport = sc->sc_hcs[hc].hc_ports[port];
    265  1.1  kiyohara 				handled |= mvsata_error(mvport);
    266  1.1  kiyohara 			}
    267  1.1  kiyohara 	for (hc = 0; hc < sc->sc_hc; hc++)
    268  1.1  kiyohara 		if (cause &
    269  1.1  kiyohara 		    (MVSATA_PCI_MAINIRQ_SATADONE(hc, 0) |
    270  1.1  kiyohara 		     MVSATA_PCI_MAINIRQ_SATADONE(hc, 1) |
    271  1.1  kiyohara 		     MVSATA_PCI_MAINIRQ_SATADONE(hc, 2) |
    272  1.1  kiyohara 		     MVSATA_PCI_MAINIRQ_SATADONE(hc, 3)))
    273  1.1  kiyohara 			handled |= mvsata_intr(&sc->sc_hcs[hc]);
    274  1.1  kiyohara 
    275  1.1  kiyohara 	if (cause & MVSATA_PCI_MAINIRQ_PCI) {
    276  1.1  kiyohara 		uint32_t pe_cause;
    277  1.1  kiyohara 
    278  1.1  kiyohara 		if (sc->sc_flags & MVSATA_FLAGS_PCIE) {
    279  1.1  kiyohara 			pe_cause = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
    280  1.1  kiyohara 			    MVSATA_PCI_E_IRQCAUSE);
    281  1.1  kiyohara 			aprint_error_dev(MVSATA_PCI_DEV(psc),
    282  1.1  kiyohara 			    "PCIe error: 0x%x\n", pe_cause);
    283  1.1  kiyohara 			bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    284  1.1  kiyohara 			    MVSATA_PCI_E_IRQCAUSE, ~pe_cause);
    285  1.1  kiyohara 		} else {
    286  1.1  kiyohara 			pe_cause = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
    287  1.1  kiyohara 			    MVSATA_PCI_IRQCAUSE);
    288  1.1  kiyohara 			aprint_error_dev(MVSATA_PCI_DEV(psc),
    289  1.1  kiyohara 			    "PCI error: 0x%x\n", pe_cause);
    290  1.1  kiyohara 			bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    291  1.1  kiyohara 			    MVSATA_PCI_IRQCAUSE, ~pe_cause);
    292  1.1  kiyohara 		}
    293  1.1  kiyohara 
    294  1.1  kiyohara 		handled = 1;	/* XXXXX */
    295  1.1  kiyohara 	}
    296  1.1  kiyohara 
    297  1.1  kiyohara 	return handled;
    298  1.1  kiyohara }
    299  1.1  kiyohara 
    300  1.1  kiyohara static bool
    301  1.3    dyoung mvsata_pci_resume(device_t dev, const pmf_qual_t *qual)
    302  1.1  kiyohara {
    303  1.1  kiyohara 
    304  1.1  kiyohara 	/* not yet... */
    305  1.1  kiyohara 
    306  1.1  kiyohara 	return true;
    307  1.1  kiyohara }
    308  1.1  kiyohara 
    309  1.1  kiyohara 
    310  1.1  kiyohara static int
    311  1.1  kiyohara mvsata_pci_sreset(struct mvsata_softc *sc)
    312  1.1  kiyohara {
    313  1.1  kiyohara 	struct mvsata_pci_softc *psc = (struct mvsata_pci_softc *)sc;
    314  1.1  kiyohara 	uint32_t val;
    315  1.1  kiyohara 	int i;
    316  1.1  kiyohara 
    317  1.1  kiyohara 	val = bus_space_read_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINCS);
    318  1.1  kiyohara 	val |= MVSATA_PCI_MAINCS_SPM;
    319  1.1  kiyohara 	bus_space_write_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINCS, val);
    320  1.1  kiyohara 
    321  1.1  kiyohara 	for (i = 0; i < 1000; i++) {
    322  1.1  kiyohara 		delay(1);
    323  1.1  kiyohara 		val = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
    324  1.1  kiyohara 		    MVSATA_PCI_MAINCS);
    325  1.1  kiyohara 		if (val & MVSATA_PCI_MAINCS_PME)
    326  1.1  kiyohara 			break;
    327  1.1  kiyohara 	}
    328  1.1  kiyohara 	if (!(val & MVSATA_PCI_MAINCS_PME)) {
    329  1.1  kiyohara 		aprint_error_dev(MVSATA_PCI_DEV(psc),
    330  1.1  kiyohara 		    "PCI master won't flush\n");
    331  1.1  kiyohara 		return -1;
    332  1.1  kiyohara 	}
    333  1.1  kiyohara 
    334  1.1  kiyohara 	/* reset */
    335  1.1  kiyohara 	bus_space_write_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINCS,
    336  1.1  kiyohara 	    val | MVSATA_PCI_MAINCS_GSR);
    337  1.1  kiyohara 	val = bus_space_read_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINCS);
    338  1.1  kiyohara 	delay(5);
    339  1.1  kiyohara 	if (!(val & MVSATA_PCI_MAINCS_GSR)) {
    340  1.1  kiyohara 		aprint_error_dev(MVSATA_PCI_DEV(psc),
    341  1.1  kiyohara 		    "can't set global reset\n");
    342  1.1  kiyohara 		return -1;
    343  1.1  kiyohara 	}
    344  1.1  kiyohara 
    345  1.1  kiyohara 	/* clear reset and *reenable the PCI master* (not mentioned in spec) */
    346  1.1  kiyohara 	val &= ~(MVSATA_PCI_MAINCS_GSR | MVSATA_PCI_MAINCS_SPM);
    347  1.1  kiyohara 	bus_space_write_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINCS, val);
    348  1.1  kiyohara 	val = bus_space_read_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINCS);
    349  1.1  kiyohara 	delay(5);
    350  1.1  kiyohara 	if (val & MVSATA_PCI_MAINCS_GSR) {
    351  1.1  kiyohara 		aprint_error_dev(MVSATA_PCI_DEV(psc),
    352  1.1  kiyohara 		    "can't set global reset\n");
    353  1.1  kiyohara 		return -1;
    354  1.1  kiyohara 	}
    355  1.1  kiyohara 
    356  1.1  kiyohara 	return 0;
    357  1.1  kiyohara }
    358  1.1  kiyohara 
    359  1.1  kiyohara static int
    360  1.1  kiyohara mvsata_pci_misc_reset(struct mvsata_softc *sc)
    361  1.1  kiyohara {
    362  1.1  kiyohara 	struct mvsata_pci_softc *psc = (struct mvsata_pci_softc *)sc;
    363  1.1  kiyohara #define MVSATA_PCI_COMMAND_DEFAULT			0x0107e371
    364  1.1  kiyohara #define MVSATA_PCI_COMMAND_PCI_CONVENTIONAL_ONLY	0x800003e0
    365  1.1  kiyohara 	uint32_t val, pci_command = MVSATA_PCI_COMMAND_DEFAULT;
    366  1.1  kiyohara 
    367  1.1  kiyohara 	bus_space_write_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_FLASHCTL,
    368  1.1  kiyohara 	    0x0fcfffff);
    369  1.1  kiyohara 
    370  1.1  kiyohara 	if (sc->sc_gen == gen2 || sc->sc_gen == gen2e) {
    371  1.1  kiyohara 		val = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
    372  1.1  kiyohara 		    MVSATA_PCI_GPIOPORTCTL);
    373  1.1  kiyohara 		val &= 0x3;
    374  1.1  kiyohara #if 0
    375  1.1  kiyohara 		val |= 0x00000060;
    376  1.1  kiyohara #else	/* XXXX */
    377  1.1  kiyohara 		val |= 0x00000070;
    378  1.1  kiyohara #endif
    379  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    380  1.1  kiyohara 		    MVSATA_PCI_GPIOPORTCTL, val);
    381  1.1  kiyohara 	}
    382  1.1  kiyohara 
    383  1.1  kiyohara 	if (sc->sc_gen == gen1) {
    384  1.1  kiyohara 		/* Expansion ROM BAR Enable */
    385  1.1  kiyohara 		val = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
    386  1.1  kiyohara 		    MVSATA_PCI_EROMBAR);
    387  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    388  1.1  kiyohara 		    MVSATA_PCI_EROMBAR, val | 0x00000001);
    389  1.1  kiyohara 	}
    390  1.1  kiyohara 
    391  1.1  kiyohara 	if (sc->sc_flags & MVSATA_FLAGS_PCIE) {
    392  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    393  1.1  kiyohara 		    MVSATA_PCI_MAINIRQMASK, 0);
    394  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    395  1.1  kiyohara 		    MVSATA_PCI_E_IRQCAUSE, 0);
    396  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    397  1.1  kiyohara 		    MVSATA_PCI_E_IRQMASK, 0);
    398  1.1  kiyohara 	} else {
    399  1.1  kiyohara 		val = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
    400  1.1  kiyohara 		    MVSATA_PCI_MODE);
    401  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    402  1.1  kiyohara 		    MVSATA_PCI_MODE, val & 0xff00ffff);
    403  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    404  1.1  kiyohara 		    MVSATA_PCI_DISCTIMER, 0);
    405  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    406  1.1  kiyohara 		    MVSATA_PCI_MSITRIGGER, 0);
    407  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    408  1.1  kiyohara 		    MVSATA_PCI_XBARTIMEOUT, 0x000100ff);
    409  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    410  1.1  kiyohara 		    MVSATA_PCI_MAINIRQMASK, 0);
    411  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    412  1.1  kiyohara 		    MVSATA_PCI_SERRMASK, 0);
    413  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    414  1.1  kiyohara 		    MVSATA_PCI_IRQCAUSE, 0);
    415  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    416  1.1  kiyohara 		    MVSATA_PCI_IRQMASK, 0);
    417  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    418  1.1  kiyohara 		    MVSATA_PCI_ERRLOWADDR, 0);
    419  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    420  1.1  kiyohara 		    MVSATA_PCI_ERRHIGHADDR, 0);
    421  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    422  1.1  kiyohara 		    MVSATA_PCI_ERRATTRIBUTE, 0);
    423  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    424  1.1  kiyohara 		    MVSATA_PCI_ERRCOMMAND, 0);
    425  1.1  kiyohara 	}
    426  1.1  kiyohara 
    427  1.1  kiyohara 	/* Enable LED */
    428  1.1  kiyohara 	if (sc->sc_gen == gen1) {
    429  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    430  1.1  kiyohara 		    MVSATA_PCI_GPIOPORTCTL, 0);
    431  1.1  kiyohara 
    432  1.1  kiyohara /* XXXX: 50xxB2 errata ? */
    433  1.1  kiyohara #if 0
    434  1.1  kiyohara 		if (sc->sc_rev == 3) {
    435  1.1  kiyohara 			int port;
    436  1.1  kiyohara 
    437  1.1  kiyohara 			val = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
    438  1.1  kiyohara 			    MVSATA_PCI_GPIOPORTCTL);
    439  1.1  kiyohara 
    440  1.1  kiyohara 			/* XXXX: check HDD connected  */
    441  1.1  kiyohara 
    442  1.1  kiyohara 			bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    443  1.1  kiyohara 			    MVSATA_PCI_GPIOPORTCTL, val);
    444  1.1  kiyohara 		}
    445  1.1  kiyohara #endif
    446  1.1  kiyohara 
    447  1.1  kiyohara 		/* Disable Flash controller clock */
    448  1.1  kiyohara 		val = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
    449  1.1  kiyohara 		    MVSATA_PCI_EROMBAR);
    450  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    451  1.1  kiyohara 		    MVSATA_PCI_EROMBAR, val & ~0x00000001);
    452  1.1  kiyohara 	} else
    453  1.1  kiyohara #if 0
    454  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    455  1.1  kiyohara 		    MVSATA_PCI_GPIOPORTCTL, 0x00000060);
    456  1.1  kiyohara #else	/* XXXX */
    457  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    458  1.1  kiyohara 		    MVSATA_PCI_GPIOPORTCTL, 0x00000070);
    459  1.1  kiyohara #endif
    460  1.1  kiyohara 
    461  1.1  kiyohara 	if (sc->sc_flags & MVSATA_FLAGS_PCIE)
    462  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    463  1.1  kiyohara 		    MVSATA_PCI_E_IRQMASK, 0x0000070a);
    464  1.1  kiyohara 	else {
    465  1.1  kiyohara 		val = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
    466  1.1  kiyohara 		    MVSATA_PCI_MODE);
    467  1.1  kiyohara 		if ((val & 0x30) >> 4) {	/* PCI-X */
    468  1.1  kiyohara 			int mv60x1b2 =
    469  1.1  kiyohara 			    ((sc->sc_model == PCI_PRODUCT_MARVELL_88SX6041 ||
    470  1.1  kiyohara 			    sc->sc_model == PCI_PRODUCT_MARVELL_88SX6081) &&
    471  1.1  kiyohara 			    sc->sc_rev == 7);
    472  1.1  kiyohara 
    473  1.1  kiyohara 			pci_command &=
    474  1.1  kiyohara 			    ~MVSATA_PCI_COMMAND_PCI_CONVENTIONAL_ONLY;
    475  1.1  kiyohara 			if (sc->sc_gen == gen1 || mv60x1b2)
    476  1.1  kiyohara 				pci_command &=
    477  1.1  kiyohara 				    ~MVSATA_PCI_COMMAND_MWRITECOMBINE;
    478  1.1  kiyohara 		} else
    479  1.1  kiyohara 			if (sc->sc_gen == gen1)
    480  1.1  kiyohara 				pci_command &=
    481  1.1  kiyohara 				    ~(MVSATA_PCI_COMMAND_MWRITECOMBINE |
    482  1.1  kiyohara 				    MVSATA_PCI_COMMAND_MREADCOMBINE);
    483  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    484  1.1  kiyohara 		    MVSATA_PCI_COMMAND, pci_command);
    485  1.1  kiyohara 
    486  1.1  kiyohara #define MVSATA_PCI_INTERRUPT_MASK	0x00d77fe6
    487  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    488  1.1  kiyohara 		    MVSATA_PCI_SERRMASK, MVSATA_PCI_INTERRUPT_MASK);
    489  1.1  kiyohara 		bus_space_write_4(psc->psc_iot, psc->psc_ioh,
    490  1.1  kiyohara 		    MVSATA_PCI_IRQMASK, MVSATA_PCI_INTERRUPT_MASK);
    491  1.1  kiyohara 	}
    492  1.1  kiyohara 
    493  1.1  kiyohara 	return 0;
    494  1.1  kiyohara }
    495  1.1  kiyohara 
    496  1.1  kiyohara static void
    497  1.1  kiyohara mvsata_pci_enable_intr(struct mvsata_port *mvport, int on)
    498  1.1  kiyohara {
    499  1.1  kiyohara 	struct mvsata_pci_softc *psc =
    500  1.1  kiyohara 	    device_private(mvport->port_ata_channel.ch_atac->atac_dev);
    501  1.1  kiyohara 	uint32_t mask;
    502  1.1  kiyohara 	int hc = mvport->port_hc->hc, port = mvport->port;
    503  1.1  kiyohara 
    504  1.1  kiyohara 	mask = bus_space_read_4(psc->psc_iot, psc->psc_ioh,
    505  1.1  kiyohara 	    MVSATA_PCI_MAINIRQMASK);
    506  1.1  kiyohara 	if (on)
    507  1.1  kiyohara 		mask |= MVSATA_PCI_MAINIRQ_SATADONE(hc, port);
    508  1.1  kiyohara 	else
    509  1.1  kiyohara 		mask &= ~MVSATA_PCI_MAINIRQ_SATADONE(hc, port);
    510  1.1  kiyohara 	bus_space_write_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINIRQMASK,
    511  1.1  kiyohara 	    mask);
    512  1.1  kiyohara }
    513