1 1.10 jdolecek /* $NetBSD: mvsata_pci.c,v 1.10 2018/08/31 18:43:29 jdolecek 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.10 jdolecek __KERNEL_RCSID(0, "$NetBSD: mvsata_pci.c,v 1.10 2018/08/31 18:43:29 jdolecek 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.10 jdolecek static const struct mvsata_product mvsata_pci_products[] = { 112 1.4 kiyohara #define PCI_VP(v, p) PCI_VENDOR_ ## v, PCI_PRODUCT_ ## v ## _ ## p 113 1.4 kiyohara { PCI_VP(MARVELL, 88SX5040), 1, 4, gen1, 0 }, 114 1.4 kiyohara { PCI_VP(MARVELL, 88SX5041), 1, 4, gen1, 0 }, 115 1.4 kiyohara { PCI_VP(MARVELL, 88SX5080), 2, 4, gen1, 0 }, 116 1.4 kiyohara { PCI_VP(MARVELL, 88SX5081), 2, 4, gen1, 0 }, 117 1.4 kiyohara { PCI_VP(MARVELL, 88SX6040), 1, 4, gen2, 0 }, 118 1.4 kiyohara { PCI_VP(MARVELL, 88SX6041), 1, 4, gen2, 0 }, 119 1.6 jakllsch { PCI_VP(ADP2, 1420SA), 1, 4, gen2, 0 }, /* 88SX6041 */ 120 1.4 kiyohara { PCI_VP(MARVELL, 88SX6042), 1, 4, gen2e, 0 }, 121 1.4 kiyohara { PCI_VP(MARVELL, 88SX6080), 2, 4, gen2, MVSATA_FLAGS_PCIE }, 122 1.4 kiyohara { PCI_VP(MARVELL, 88SX6081), 2, 4, gen2, MVSATA_FLAGS_PCIE }, 123 1.4 kiyohara { PCI_VP(MARVELL, 88SX7042), 1, 4, gen2e, 0 }, 124 1.6 jakllsch { PCI_VP(ADP2, 1430SA), 1, 4, gen2e, 0 }, /* 88SX7042 */ 125 1.4 kiyohara { PCI_VP(TRIONES, ROCKETRAID_2310), 1, 4, gen2e, 0 }, 126 1.4 kiyohara #undef PCI_VP 127 1.4 kiyohara }; 128 1.4 kiyohara 129 1.1 kiyohara 130 1.1 kiyohara /* 131 1.1 kiyohara * mvsata_pci_match() 132 1.1 kiyohara * This function returns 2, because mvsata is high priority more than pciide. 133 1.1 kiyohara */ 134 1.1 kiyohara static int 135 1.1 kiyohara mvsata_pci_match(device_t parent, struct cfdata *match, void *aux) 136 1.1 kiyohara { 137 1.1 kiyohara struct pci_attach_args *pa = aux; 138 1.4 kiyohara int i; 139 1.1 kiyohara 140 1.4 kiyohara for (i = 0; i < __arraycount(mvsata_pci_products); i++) 141 1.4 kiyohara if (PCI_VENDOR(pa->pa_id) == mvsata_pci_products[i].vendor && 142 1.4 kiyohara PCI_PRODUCT(pa->pa_id) == mvsata_pci_products[i].model) 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.4 kiyohara int read_pre_amps, hc, port, rv, i; 158 1.1 kiyohara const char *intrstr; 159 1.8 christos char intrbuf[PCI_INTRSTR_LEN]; 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.7 drochner pci_aprint_devinfo(pa, "Marvell Serial-ATA Host Controller"); 168 1.1 kiyohara 169 1.1 kiyohara /* Map I/O register */ 170 1.1 kiyohara if (pci_mapreg_map(pa, PCI_MAPREG_START, 171 1.1 kiyohara PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, 172 1.1 kiyohara &psc->psc_iot, &psc->psc_ioh, NULL, &size) != 0) { 173 1.1 kiyohara aprint_error_dev(self, "can't map registers\n"); 174 1.1 kiyohara return; 175 1.1 kiyohara } 176 1.1 kiyohara psc->psc_pc = pa->pa_pc; 177 1.1 kiyohara psc->psc_tag = pa->pa_tag; 178 1.1 kiyohara 179 1.1 kiyohara if (bus_space_subregion(psc->psc_iot, psc->psc_ioh, 180 1.1 kiyohara MVSATA_PCI_HCARBITER_SPACE_OFFSET, 181 1.1 kiyohara size - MVSATA_PCI_HCARBITER_SPACE_OFFSET, &sc->sc_ioh)) { 182 1.1 kiyohara aprint_error_dev(self, "can't subregion registers\n"); 183 1.1 kiyohara return; 184 1.1 kiyohara } 185 1.1 kiyohara sc->sc_iot = psc->psc_iot; 186 1.1 kiyohara 187 1.1 kiyohara /* Enable device */ 188 1.1 kiyohara csr = pci_conf_read(psc->psc_pc, psc->psc_tag, PCI_COMMAND_STATUS_REG); 189 1.1 kiyohara csr |= PCI_COMMAND_MASTER_ENABLE; 190 1.1 kiyohara pci_conf_write(psc->psc_pc, psc->psc_tag, PCI_COMMAND_STATUS_REG, csr); 191 1.1 kiyohara 192 1.1 kiyohara if (pci_intr_map(pa, &intrhandle) != 0) { 193 1.1 kiyohara aprint_error_dev(self, "couldn't map interrupt\n"); 194 1.1 kiyohara return; 195 1.1 kiyohara } 196 1.8 christos intrstr = pci_intr_string(psc->psc_pc, intrhandle, intrbuf, sizeof(intrbuf)); 197 1.9 jdolecek psc->psc_ih = pci_intr_establish_xname(psc->psc_pc, intrhandle, IPL_BIO, 198 1.9 jdolecek mvsata_pci_intr, sc, device_xname(self)); 199 1.1 kiyohara if (psc->psc_ih == NULL) { 200 1.1 kiyohara aprint_error_dev(self, "couldn't establish interrupt\n"); 201 1.1 kiyohara return; 202 1.1 kiyohara } 203 1.1 kiyohara aprint_normal_dev(self, "interrupting at %s\n", 204 1.1 kiyohara intrstr ? intrstr : "unknown interrupt"); 205 1.1 kiyohara 206 1.1 kiyohara /* 207 1.1 kiyohara * Check if TWSI serial ROM initialization was triggered. 208 1.1 kiyohara * If so, then PRE/AMP configuration probably are set after 209 1.1 kiyohara * reset by serial ROM. If not then override the PRE/AMP 210 1.1 kiyohara * values. 211 1.1 kiyohara */ 212 1.1 kiyohara reg = bus_space_read_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_RESETCFG); 213 1.1 kiyohara read_pre_amps = (reg & 0x00000001) ? 1 : 0; 214 1.1 kiyohara 215 1.4 kiyohara for (i = 0; i < __arraycount(mvsata_pci_products); i++) 216 1.4 kiyohara if (PCI_VENDOR(pa->pa_id) == mvsata_pci_products[i].vendor && 217 1.4 kiyohara PCI_PRODUCT(pa->pa_id) == mvsata_pci_products[i].model) 218 1.4 kiyohara break; 219 1.4 kiyohara KASSERT(i < __arraycount(mvsata_pci_products)); 220 1.4 kiyohara 221 1.4 kiyohara rv = mvsata_attach(sc, &mvsata_pci_products[i], 222 1.4 kiyohara mvsata_pci_sreset, mvsata_pci_misc_reset, read_pre_amps); 223 1.1 kiyohara if (rv != 0) { 224 1.1 kiyohara pci_intr_disestablish(psc->psc_pc, psc->psc_ih); 225 1.1 kiyohara return; 226 1.1 kiyohara } 227 1.1 kiyohara 228 1.1 kiyohara mask = MVSATA_PCI_MAINIRQ_PCI; 229 1.1 kiyohara for (hc = 0; hc < sc->sc_hc; hc++) 230 1.1 kiyohara for (port = 0; port < sc->sc_port; port++) 231 1.1 kiyohara mask |= 232 1.1 kiyohara MVSATA_PCI_MAINIRQ_SATAERR(hc, port) | 233 1.1 kiyohara MVSATA_PCI_MAINIRQ_SATADONE(hc, port); 234 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINIRQMASK, 235 1.1 kiyohara mask); 236 1.1 kiyohara 237 1.1 kiyohara if (!pmf_device_register(self, NULL, mvsata_pci_resume)) 238 1.1 kiyohara aprint_error_dev(self, "couldn't establish power handler\n"); 239 1.1 kiyohara } 240 1.1 kiyohara 241 1.1 kiyohara static int 242 1.1 kiyohara mvsata_pci_detach(device_t self, int flags) 243 1.1 kiyohara { 244 1.1 kiyohara struct mvsata_pci_softc *psc = device_private(self); 245 1.1 kiyohara 246 1.1 kiyohara /* XXXX: needs reset ? */ 247 1.1 kiyohara 248 1.1 kiyohara pci_intr_disestablish(psc->psc_pc, psc->psc_ih); 249 1.1 kiyohara pmf_device_deregister(self); 250 1.1 kiyohara return 0; 251 1.1 kiyohara } 252 1.1 kiyohara 253 1.1 kiyohara static int 254 1.1 kiyohara mvsata_pci_intr(void *arg) 255 1.1 kiyohara { 256 1.1 kiyohara struct mvsata_pci_softc *psc = (struct mvsata_pci_softc *)arg; 257 1.1 kiyohara struct mvsata_softc *sc = &psc->psc_sc; 258 1.1 kiyohara uint32_t cause; 259 1.1 kiyohara int hc, port, handled = 0; 260 1.1 kiyohara 261 1.1 kiyohara cause = bus_space_read_4(psc->psc_iot, psc->psc_ioh, 262 1.1 kiyohara MVSATA_PCI_MAINIRQCAUSE); 263 1.1 kiyohara for (hc = 0; hc < sc->sc_hc; hc++) 264 1.1 kiyohara for (port = 0; port < sc->sc_port; port++) 265 1.1 kiyohara if (cause & MVSATA_PCI_MAINIRQ_SATAERR(hc, port)) { 266 1.1 kiyohara struct mvsata_port *mvport; 267 1.1 kiyohara 268 1.1 kiyohara mvport = sc->sc_hcs[hc].hc_ports[port]; 269 1.1 kiyohara handled |= mvsata_error(mvport); 270 1.1 kiyohara } 271 1.1 kiyohara for (hc = 0; hc < sc->sc_hc; hc++) 272 1.1 kiyohara if (cause & 273 1.1 kiyohara (MVSATA_PCI_MAINIRQ_SATADONE(hc, 0) | 274 1.1 kiyohara MVSATA_PCI_MAINIRQ_SATADONE(hc, 1) | 275 1.1 kiyohara MVSATA_PCI_MAINIRQ_SATADONE(hc, 2) | 276 1.1 kiyohara MVSATA_PCI_MAINIRQ_SATADONE(hc, 3))) 277 1.1 kiyohara handled |= mvsata_intr(&sc->sc_hcs[hc]); 278 1.1 kiyohara 279 1.1 kiyohara if (cause & MVSATA_PCI_MAINIRQ_PCI) { 280 1.1 kiyohara uint32_t pe_cause; 281 1.1 kiyohara 282 1.1 kiyohara if (sc->sc_flags & MVSATA_FLAGS_PCIE) { 283 1.1 kiyohara pe_cause = bus_space_read_4(psc->psc_iot, psc->psc_ioh, 284 1.1 kiyohara MVSATA_PCI_E_IRQCAUSE); 285 1.1 kiyohara aprint_error_dev(MVSATA_PCI_DEV(psc), 286 1.1 kiyohara "PCIe error: 0x%x\n", pe_cause); 287 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 288 1.1 kiyohara MVSATA_PCI_E_IRQCAUSE, ~pe_cause); 289 1.1 kiyohara } else { 290 1.1 kiyohara pe_cause = bus_space_read_4(psc->psc_iot, psc->psc_ioh, 291 1.1 kiyohara MVSATA_PCI_IRQCAUSE); 292 1.1 kiyohara aprint_error_dev(MVSATA_PCI_DEV(psc), 293 1.1 kiyohara "PCI error: 0x%x\n", pe_cause); 294 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 295 1.1 kiyohara MVSATA_PCI_IRQCAUSE, ~pe_cause); 296 1.1 kiyohara } 297 1.1 kiyohara 298 1.1 kiyohara handled = 1; /* XXXXX */ 299 1.1 kiyohara } 300 1.1 kiyohara 301 1.1 kiyohara return handled; 302 1.1 kiyohara } 303 1.1 kiyohara 304 1.1 kiyohara static bool 305 1.3 dyoung mvsata_pci_resume(device_t dev, const pmf_qual_t *qual) 306 1.1 kiyohara { 307 1.1 kiyohara 308 1.1 kiyohara /* not yet... */ 309 1.1 kiyohara 310 1.1 kiyohara return true; 311 1.1 kiyohara } 312 1.1 kiyohara 313 1.1 kiyohara 314 1.1 kiyohara static int 315 1.1 kiyohara mvsata_pci_sreset(struct mvsata_softc *sc) 316 1.1 kiyohara { 317 1.1 kiyohara struct mvsata_pci_softc *psc = (struct mvsata_pci_softc *)sc; 318 1.1 kiyohara uint32_t val; 319 1.1 kiyohara int i; 320 1.1 kiyohara 321 1.1 kiyohara val = bus_space_read_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINCS); 322 1.1 kiyohara val |= MVSATA_PCI_MAINCS_SPM; 323 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINCS, val); 324 1.1 kiyohara 325 1.1 kiyohara for (i = 0; i < 1000; i++) { 326 1.1 kiyohara delay(1); 327 1.1 kiyohara val = bus_space_read_4(psc->psc_iot, psc->psc_ioh, 328 1.1 kiyohara MVSATA_PCI_MAINCS); 329 1.1 kiyohara if (val & MVSATA_PCI_MAINCS_PME) 330 1.1 kiyohara break; 331 1.1 kiyohara } 332 1.1 kiyohara if (!(val & MVSATA_PCI_MAINCS_PME)) { 333 1.1 kiyohara aprint_error_dev(MVSATA_PCI_DEV(psc), 334 1.1 kiyohara "PCI master won't flush\n"); 335 1.1 kiyohara return -1; 336 1.1 kiyohara } 337 1.1 kiyohara 338 1.1 kiyohara /* reset */ 339 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINCS, 340 1.1 kiyohara val | MVSATA_PCI_MAINCS_GSR); 341 1.1 kiyohara val = bus_space_read_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINCS); 342 1.1 kiyohara delay(5); 343 1.1 kiyohara if (!(val & MVSATA_PCI_MAINCS_GSR)) { 344 1.1 kiyohara aprint_error_dev(MVSATA_PCI_DEV(psc), 345 1.1 kiyohara "can't set global reset\n"); 346 1.1 kiyohara return -1; 347 1.1 kiyohara } 348 1.1 kiyohara 349 1.1 kiyohara /* clear reset and *reenable the PCI master* (not mentioned in spec) */ 350 1.1 kiyohara val &= ~(MVSATA_PCI_MAINCS_GSR | MVSATA_PCI_MAINCS_SPM); 351 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINCS, val); 352 1.1 kiyohara val = bus_space_read_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINCS); 353 1.1 kiyohara delay(5); 354 1.1 kiyohara if (val & MVSATA_PCI_MAINCS_GSR) { 355 1.1 kiyohara aprint_error_dev(MVSATA_PCI_DEV(psc), 356 1.1 kiyohara "can't set global reset\n"); 357 1.1 kiyohara return -1; 358 1.1 kiyohara } 359 1.1 kiyohara 360 1.1 kiyohara return 0; 361 1.1 kiyohara } 362 1.1 kiyohara 363 1.1 kiyohara static int 364 1.1 kiyohara mvsata_pci_misc_reset(struct mvsata_softc *sc) 365 1.1 kiyohara { 366 1.1 kiyohara struct mvsata_pci_softc *psc = (struct mvsata_pci_softc *)sc; 367 1.1 kiyohara #define MVSATA_PCI_COMMAND_DEFAULT 0x0107e371 368 1.1 kiyohara #define MVSATA_PCI_COMMAND_PCI_CONVENTIONAL_ONLY 0x800003e0 369 1.1 kiyohara uint32_t val, pci_command = MVSATA_PCI_COMMAND_DEFAULT; 370 1.1 kiyohara 371 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_FLASHCTL, 372 1.1 kiyohara 0x0fcfffff); 373 1.1 kiyohara 374 1.1 kiyohara if (sc->sc_gen == gen2 || sc->sc_gen == gen2e) { 375 1.1 kiyohara val = bus_space_read_4(psc->psc_iot, psc->psc_ioh, 376 1.1 kiyohara MVSATA_PCI_GPIOPORTCTL); 377 1.1 kiyohara val &= 0x3; 378 1.1 kiyohara #if 0 379 1.1 kiyohara val |= 0x00000060; 380 1.1 kiyohara #else /* XXXX */ 381 1.1 kiyohara val |= 0x00000070; 382 1.1 kiyohara #endif 383 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 384 1.1 kiyohara MVSATA_PCI_GPIOPORTCTL, val); 385 1.1 kiyohara } 386 1.1 kiyohara 387 1.1 kiyohara if (sc->sc_gen == gen1) { 388 1.1 kiyohara /* Expansion ROM BAR Enable */ 389 1.1 kiyohara val = bus_space_read_4(psc->psc_iot, psc->psc_ioh, 390 1.1 kiyohara MVSATA_PCI_EROMBAR); 391 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 392 1.1 kiyohara MVSATA_PCI_EROMBAR, val | 0x00000001); 393 1.1 kiyohara } 394 1.1 kiyohara 395 1.1 kiyohara if (sc->sc_flags & MVSATA_FLAGS_PCIE) { 396 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 397 1.1 kiyohara MVSATA_PCI_MAINIRQMASK, 0); 398 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 399 1.1 kiyohara MVSATA_PCI_E_IRQCAUSE, 0); 400 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 401 1.1 kiyohara MVSATA_PCI_E_IRQMASK, 0); 402 1.1 kiyohara } else { 403 1.1 kiyohara val = bus_space_read_4(psc->psc_iot, psc->psc_ioh, 404 1.1 kiyohara MVSATA_PCI_MODE); 405 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 406 1.1 kiyohara MVSATA_PCI_MODE, val & 0xff00ffff); 407 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 408 1.1 kiyohara MVSATA_PCI_DISCTIMER, 0); 409 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 410 1.1 kiyohara MVSATA_PCI_MSITRIGGER, 0); 411 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 412 1.1 kiyohara MVSATA_PCI_XBARTIMEOUT, 0x000100ff); 413 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 414 1.1 kiyohara MVSATA_PCI_MAINIRQMASK, 0); 415 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 416 1.1 kiyohara MVSATA_PCI_SERRMASK, 0); 417 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 418 1.1 kiyohara MVSATA_PCI_IRQCAUSE, 0); 419 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 420 1.1 kiyohara MVSATA_PCI_IRQMASK, 0); 421 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 422 1.1 kiyohara MVSATA_PCI_ERRLOWADDR, 0); 423 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 424 1.1 kiyohara MVSATA_PCI_ERRHIGHADDR, 0); 425 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 426 1.1 kiyohara MVSATA_PCI_ERRATTRIBUTE, 0); 427 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 428 1.1 kiyohara MVSATA_PCI_ERRCOMMAND, 0); 429 1.1 kiyohara } 430 1.1 kiyohara 431 1.1 kiyohara /* Enable LED */ 432 1.1 kiyohara if (sc->sc_gen == gen1) { 433 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 434 1.1 kiyohara MVSATA_PCI_GPIOPORTCTL, 0); 435 1.1 kiyohara 436 1.1 kiyohara /* XXXX: 50xxB2 errata ? */ 437 1.1 kiyohara #if 0 438 1.1 kiyohara if (sc->sc_rev == 3) { 439 1.1 kiyohara int port; 440 1.1 kiyohara 441 1.1 kiyohara val = bus_space_read_4(psc->psc_iot, psc->psc_ioh, 442 1.1 kiyohara MVSATA_PCI_GPIOPORTCTL); 443 1.1 kiyohara 444 1.1 kiyohara /* XXXX: check HDD connected */ 445 1.1 kiyohara 446 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 447 1.1 kiyohara MVSATA_PCI_GPIOPORTCTL, val); 448 1.1 kiyohara } 449 1.1 kiyohara #endif 450 1.1 kiyohara 451 1.1 kiyohara /* Disable Flash controller clock */ 452 1.1 kiyohara val = bus_space_read_4(psc->psc_iot, psc->psc_ioh, 453 1.1 kiyohara MVSATA_PCI_EROMBAR); 454 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 455 1.1 kiyohara MVSATA_PCI_EROMBAR, val & ~0x00000001); 456 1.1 kiyohara } else 457 1.1 kiyohara #if 0 458 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 459 1.1 kiyohara MVSATA_PCI_GPIOPORTCTL, 0x00000060); 460 1.1 kiyohara #else /* XXXX */ 461 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 462 1.1 kiyohara MVSATA_PCI_GPIOPORTCTL, 0x00000070); 463 1.1 kiyohara #endif 464 1.1 kiyohara 465 1.1 kiyohara if (sc->sc_flags & MVSATA_FLAGS_PCIE) 466 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 467 1.1 kiyohara MVSATA_PCI_E_IRQMASK, 0x0000070a); 468 1.1 kiyohara else { 469 1.1 kiyohara val = bus_space_read_4(psc->psc_iot, psc->psc_ioh, 470 1.1 kiyohara MVSATA_PCI_MODE); 471 1.1 kiyohara if ((val & 0x30) >> 4) { /* PCI-X */ 472 1.1 kiyohara int mv60x1b2 = 473 1.1 kiyohara ((sc->sc_model == PCI_PRODUCT_MARVELL_88SX6041 || 474 1.1 kiyohara sc->sc_model == PCI_PRODUCT_MARVELL_88SX6081) && 475 1.1 kiyohara sc->sc_rev == 7); 476 1.1 kiyohara 477 1.1 kiyohara pci_command &= 478 1.1 kiyohara ~MVSATA_PCI_COMMAND_PCI_CONVENTIONAL_ONLY; 479 1.1 kiyohara if (sc->sc_gen == gen1 || mv60x1b2) 480 1.1 kiyohara pci_command &= 481 1.1 kiyohara ~MVSATA_PCI_COMMAND_MWRITECOMBINE; 482 1.1 kiyohara } else 483 1.1 kiyohara if (sc->sc_gen == gen1) 484 1.1 kiyohara pci_command &= 485 1.1 kiyohara ~(MVSATA_PCI_COMMAND_MWRITECOMBINE | 486 1.1 kiyohara MVSATA_PCI_COMMAND_MREADCOMBINE); 487 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 488 1.1 kiyohara MVSATA_PCI_COMMAND, pci_command); 489 1.1 kiyohara 490 1.1 kiyohara #define MVSATA_PCI_INTERRUPT_MASK 0x00d77fe6 491 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 492 1.1 kiyohara MVSATA_PCI_SERRMASK, MVSATA_PCI_INTERRUPT_MASK); 493 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, 494 1.1 kiyohara MVSATA_PCI_IRQMASK, MVSATA_PCI_INTERRUPT_MASK); 495 1.1 kiyohara } 496 1.1 kiyohara 497 1.1 kiyohara return 0; 498 1.1 kiyohara } 499 1.1 kiyohara 500 1.1 kiyohara static void 501 1.1 kiyohara mvsata_pci_enable_intr(struct mvsata_port *mvport, int on) 502 1.1 kiyohara { 503 1.1 kiyohara struct mvsata_pci_softc *psc = 504 1.1 kiyohara device_private(mvport->port_ata_channel.ch_atac->atac_dev); 505 1.1 kiyohara uint32_t mask; 506 1.1 kiyohara int hc = mvport->port_hc->hc, port = mvport->port; 507 1.1 kiyohara 508 1.1 kiyohara mask = bus_space_read_4(psc->psc_iot, psc->psc_ioh, 509 1.1 kiyohara MVSATA_PCI_MAINIRQMASK); 510 1.1 kiyohara if (on) 511 1.1 kiyohara mask |= MVSATA_PCI_MAINIRQ_SATADONE(hc, port); 512 1.1 kiyohara else 513 1.1 kiyohara mask &= ~MVSATA_PCI_MAINIRQ_SATADONE(hc, port); 514 1.1 kiyohara bus_space_write_4(psc->psc_iot, psc->psc_ioh, MVSATA_PCI_MAINIRQMASK, 515 1.1 kiyohara mask); 516 1.1 kiyohara } 517