1 /* $NetBSD: gt.c,v 1.29 2021/04/24 23:36:56 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed for the NetBSD Project by 18 * Allegro Networks, Inc., and Wasabi Systems, Inc. 19 * 4. The name of Allegro Networks, Inc. may not be used to endorse 20 * or promote products derived from this software without specific prior 21 * written permission. 22 * 5. The name of Wasabi Systems, Inc. may not be used to endorse 23 * or promote products derived from this software without specific prior 24 * written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND 27 * WASABI SYSTEMS, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 28 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 29 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 30 * IN NO EVENT SHALL EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC. 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * gt.c -- GT system controller driver 42 */ 43 44 #include <sys/cdefs.h> 45 __KERNEL_RCSID(0, "$NetBSD: gt.c,v 1.29 2021/04/24 23:36:56 thorpej Exp $"); 46 47 #include "opt_marvell.h" 48 #include "gtmpsc.h" 49 #include "opt_multiprocessor.h" 50 #include "locators.h" 51 52 #include <sys/param.h> 53 #include <sys/bus.h> 54 #include <sys/device.h> 55 #include <sys/kernel.h> 56 #include <sys/types.h> 57 58 #include <dev/marvell/gtintrreg.h> 59 #include <dev/marvell/gtsdmareg.h> 60 #if NGTMPSC > 0 61 #include <dev/marvell/gtmpscreg.h> 62 #include <dev/marvell/gtmpscvar.h> 63 #endif 64 #include <dev/marvell/gtpcireg.h> 65 #include <dev/marvell/gtreg.h> 66 #include <dev/marvell/gtvar.h> 67 #include <dev/marvell/marvellreg.h> 68 #include <dev/marvell/marvellvar.h> 69 70 #include <dev/pci/pcireg.h> 71 72 #if ((GT_MPP_WATCHDOG & 0xf0f0f0f0) != 0) 73 # error /* unqualified: configuration botch! */ 74 #endif 75 76 #define gt_read(sc,r) bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (r)) 77 #define gt_write(sc,r,v) bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (r), (v)) 78 79 80 static int gt_cfprint(void *, const char *); 81 static int gt_cfsearch(device_t, cfdata_t, const int *, void *); 82 static void gt_attach_peripherals(struct gt_softc *); 83 84 #ifdef GT_DEVBUS 85 static int gt_devbus_intr(void *); 86 static void gt_devbus_intr_enb(struct gt_softc *); 87 #endif 88 #ifdef GT_ECC 89 static int gt_ecc_intr(void *); 90 static void gt_ecc_intr_enb(struct gt_softc *); 91 #endif 92 #if NGTMPSC > 0 93 static void gt_sdma_intr_enb(struct gt_softc *); 94 #endif 95 #ifdef GT_COMM 96 static int gt_comm_intr(void *); 97 static void gt_comm_intr_enb(struct gt_softc *); 98 #endif 99 100 101 #ifdef GT_WATCHDOG 102 static void gt_watchdog_init(struct gt_softc *); 103 static void gt_watchdog_enable(struct gt_softc *); 104 #ifndef GT_MPP_WATCHDOG 105 static void gt_watchdog_disable(struct gt_softc *); 106 #endif 107 108 static struct gt_softc *gt_watchdog_sc = NULL; 109 static int gt_watchdog_state = 0; 110 #endif 111 112 113 #define OFFSET_DEFAULT MVA_OFFSET_DEFAULT 114 #define IRQ_DEFAULT MVA_IRQ_DEFAULT 115 static const struct gt_dev { 116 int model; 117 const char *name; 118 int unit; 119 bus_size_t offset; 120 int irq; 121 } gt_devs[] = { 122 { MARVELL_DISCOVERY, "gfec", 0, 0x0000, IRQ_DEFAULT }, 123 { MARVELL_DISCOVERY, "gtidmac", 0, 0x0000, 4 /*...7 */ }, 124 { MARVELL_DISCOVERY, "gtmpsc", 0, 0x8000, 40 }, 125 { MARVELL_DISCOVERY, "gtmpsc", 1, 0x9000, 42 }, 126 { MARVELL_DISCOVERY, "gtpci", 0, OFFSET_DEFAULT, IRQ_DEFAULT }, 127 { MARVELL_DISCOVERY, "gtpci", 1, OFFSET_DEFAULT, IRQ_DEFAULT }, 128 { MARVELL_DISCOVERY, "gttwsi", 0, 0xc000, 37 }, 129 { MARVELL_DISCOVERY, "obio", 0, OFFSET_DEFAULT, IRQ_DEFAULT }, 130 { MARVELL_DISCOVERY, "obio", 1, OFFSET_DEFAULT, IRQ_DEFAULT }, 131 { MARVELL_DISCOVERY, "obio", 2, OFFSET_DEFAULT, IRQ_DEFAULT }, 132 { MARVELL_DISCOVERY, "obio", 3, OFFSET_DEFAULT, IRQ_DEFAULT }, 133 { MARVELL_DISCOVERY, "obio", 4, OFFSET_DEFAULT, IRQ_DEFAULT }, 134 135 { MARVELL_DISCOVERY_II, "gtidmac", 0, 0x0000, 4 /*...7 */ }, 136 { MARVELL_DISCOVERY_II, "gtmpsc", 0, 0x8000, 40 }, 137 { MARVELL_DISCOVERY_II, "gtmpsc", 1, 0x9000, 42 }, 138 { MARVELL_DISCOVERY_II, "gtpci", 0, OFFSET_DEFAULT, IRQ_DEFAULT }, 139 { MARVELL_DISCOVERY_II, "gtpci", 1, OFFSET_DEFAULT, IRQ_DEFAULT }, 140 { MARVELL_DISCOVERY_II, "gttwsi", 0, 0xc000, 37 }, 141 { MARVELL_DISCOVERY_II, "mvgbec", 0, 0x0000, IRQ_DEFAULT }, 142 143 { MARVELL_DISCOVERY_III,"gtidmac", 0, 0x0000, 4 /*...7 */ }, 144 { MARVELL_DISCOVERY_III,"gtmpsc", 0, 0x8000, 40 }, 145 { MARVELL_DISCOVERY_III,"gtmpsc", 1, 0x9000, 42 }, 146 { MARVELL_DISCOVERY_III,"gtpci", 0, OFFSET_DEFAULT, IRQ_DEFAULT }, 147 { MARVELL_DISCOVERY_III,"gtpci", 1, OFFSET_DEFAULT, IRQ_DEFAULT }, 148 { MARVELL_DISCOVERY_III,"gttwsi", 0, 0xc000, 37 }, 149 { MARVELL_DISCOVERY_III,"mvgbec", 0, 0x0000, IRQ_DEFAULT }, 150 151 #if 0 /* XXXXXX: from www.marvell.com */ 152 /* Discovery LT (Discovery Light) MV644[23]0 */ 153 { MARVELL_DISCOVERY_LT, "gtidmac", 0, 0x?000, ? /*...? */ }, 154 { MARVELL_DISCOVERY_LT, "gtmpsc", 0, 0x?000, ? }, 155 { MARVELL_DISCOVERY_LT, "gtmpsc", 1, 0x?000, ? }, 156 { MARVELL_DISCOVERY_LT, "gtpci", 0, OFFSET_DEFAULT, IRQ_DEFAULT }, 157 { MARVELL_DISCOVERY_LT, "gtpci", 1, OFFSET_DEFAULT, IRQ_DEFAULT }, 158 { MARVELL_DISCOVERY_LT, "gttwsi", 0, 0x?000, ? }, 159 { MARVELL_DISCOVERY_LT, "mvgbec", 0, 0x?000, IRQ_DEFAULT }, 160 161 /* Discovery V MV64560 */ 162 { MARVELL_DISCOVERY_V, "com", ?, 0x?0000, ? }, 163 { MARVELL_DISCOVERY_V, "ehci", 0, 0x?0000, ? }, 164 { MARVELL_DISCOVERY_V, "ehci", 1, 0x?0000, ? }, 165 { MARVELL_DISCOVERY_V, "gtidmac", 0, 0x?0000, ? /*...? */ }, 166 { MARVELL_DISCOVERY_V, "gtpci", 0, 0x?0000, IRQ_DEFAULT }, 167 { MARVELL_DISCOVERY_V, "gttwsi", 0, 0x?0000, ? }, 168 { MARVELL_DISCOVERY_V, "mvgbec", 0, 0x?0000, IRQ_DEFAULT }, 169 { MARVELL_DISCOVERY_V, "mvpex or gtpci?", 0, 0x?0000, IRQ_DEFAULT }, 170 { MARVELL_DISCOVERY_V, "obio", 0, OFFSET_DEFAULT, IRQ_DEFAULT }, 171 172 /* Discovery VI MV64660 */ 173 /* MV64560 + SATA? */ 174 { MARVELL_DISCOVERY_VI, "mvsata", 0, 0x?0000, ? }, 175 #endif 176 }; 177 178 179 static int 180 gt_cfprint(void *aux, const char *pnp) 181 { 182 struct marvell_attach_args *mva = aux; 183 184 if (pnp) 185 aprint_normal("%s at %s unit %d", 186 mva->mva_name, pnp, mva->mva_unit); 187 else { 188 if (mva->mva_unit != MVA_UNIT_DEFAULT) 189 aprint_normal(" unit %d", mva->mva_unit); 190 if (mva->mva_offset != MVA_OFFSET_DEFAULT) { 191 aprint_normal(" offset 0x%04x", mva->mva_offset); 192 if (mva->mva_size > 0) 193 aprint_normal("-0x%04x", 194 mva->mva_offset + mva->mva_size - 1); 195 } 196 if (mva->mva_irq != MVA_IRQ_DEFAULT) 197 aprint_normal(" irq %d", mva->mva_irq); 198 } 199 200 return UNCONF; 201 } 202 203 204 /* ARGSUSED */ 205 static int 206 gt_cfsearch(device_t parent, cfdata_t cf, const int *ldesc, void *aux) 207 { 208 struct marvell_attach_args *mva = aux; 209 210 if (cf->cf_loc[GTCF_IRQ] != MVA_IRQ_DEFAULT) 211 mva->mva_irq = cf->cf_loc[GTCF_IRQ]; 212 213 return config_match(parent, cf, aux); 214 } 215 216 static void 217 gt_attach_peripherals(struct gt_softc *sc) 218 { 219 struct marvell_attach_args mva; 220 int i; 221 222 for (i = 0; i < __arraycount(gt_devs); i++) { 223 if (gt_devs[i].model != sc->sc_model) 224 continue; 225 226 mva.mva_name = gt_devs[i].name; 227 mva.mva_model = sc->sc_model; 228 mva.mva_revision = sc->sc_rev; 229 mva.mva_iot = sc->sc_iot; 230 mva.mva_ioh = sc->sc_ioh; 231 mva.mva_unit = gt_devs[i].unit; 232 mva.mva_addr = sc->sc_addr; 233 mva.mva_offset = gt_devs[i].offset; 234 mva.mva_size = 0; 235 mva.mva_dmat = sc->sc_dmat; 236 mva.mva_irq = gt_devs[i].irq; 237 238 config_found(sc->sc_dev, &mva, gt_cfprint, 239 CFARG_SUBMATCH, gt_cfsearch, 240 CFARG_EOL); 241 } 242 } 243 244 void 245 gt_attach_common(struct gt_softc *gt) 246 { 247 uint32_t cpucfg, cpumode, cpumstr; 248 #ifdef GT_DEBUG 249 uint32_t loaddr, hiaddr; 250 #endif 251 252 gt_write(gt, GTPCI_CA(0), PCI_ID_REG); 253 gt->sc_model = PCI_PRODUCT(gt_read(gt, GTPCI_CD(0))); 254 gt_write(gt, GTPCI_CA(0), PCI_CLASS_REG); 255 gt->sc_rev = PCI_REVISION(gt_read(gt, GTPCI_CD(0))); 256 257 aprint_naive("\n"); 258 switch (gt->sc_model) { 259 case MARVELL_DISCOVERY: 260 aprint_normal(": GT-6426x%c Discovery\n", 261 (gt->sc_rev == MARVELL_DISCOVERY_REVA) ? 'A' : 'B'); 262 break; 263 case MARVELL_DISCOVERY_II: 264 aprint_normal(": MV6436x Discovery II\n"); 265 break; 266 267 case MARVELL_DISCOVERY_III: 268 aprint_normal(": MV6446x Discovery III\n"); 269 break; 270 #if 0 271 case MARVELL_DISCOVERY_LT: 272 case MARVELL_DISCOVERY_V: 273 case MARVELL_DISCOVERY_VI: 274 #endif 275 276 default: 277 aprint_normal(": type unknown\n"); break; 278 } 279 280 cpumode = gt_read(gt, GT_CPU_Mode); 281 aprint_normal_dev(gt->sc_dev, 282 "id %d", GT_CPUMode_MultiGTID_GET(cpumode)); 283 if (cpumode & GT_CPUMode_MultiGT) 284 aprint_normal (" (multi)"); 285 switch (GT_CPUMode_CPUType_GET(cpumode)) { 286 case 4: aprint_normal(", 60x bus"); break; 287 case 5: aprint_normal(", MPX bus"); break; 288 289 default: 290 aprint_normal(", %#x(?) bus", GT_CPUMode_CPUType_GET(cpumode)); 291 break; 292 } 293 294 cpumstr = gt_read(gt, GT_CPU_Master_Ctl); 295 switch (cpumstr & (GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock)) { 296 case 0: break; 297 case GT_CPUMstrCtl_CleanBlock: aprint_normal(", snoop=clean"); break; 298 case GT_CPUMstrCtl_FlushBlock: aprint_normal(", snoop=flush"); break; 299 case GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock: 300 aprint_normal(", snoop=clean&flush"); break; 301 } 302 aprint_normal(" wdog=%#x,%#x\n", 303 gt_read(gt, GT_WDOG_Config), gt_read(gt, GT_WDOG_Value)); 304 305 #ifdef GT_DEBUG 306 loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS0_Low_Decode), gt->sc_model); 307 hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS0_High_Decode), gt->sc_model); 308 aprint_normal_dev(gt->sc_dev, " scs[0]=%#10x-%#10x\n", 309 loaddr, hiaddr); 310 311 loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS1_Low_Decode), gt->sc_model); 312 hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS1_High_Decode), gt->sc_model); 313 aprint_normal_dev(gt->sc_dev, " scs[1]=%#10x-%#10x\n", 314 loaddr, hiaddr); 315 316 loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS2_Low_Decode), gt->sc_model); 317 hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS2_High_Decode), gt->sc_model); 318 aprint_normal_dev(gt->sc_dev, " scs[2]=%#10x-%#10x\n", 319 loaddr, hiaddr); 320 321 loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS3_Low_Decode), gt->sc_model); 322 hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS3_High_Decode), gt->sc_model); 323 aprint_normal_dev(gt->sc_dev, " scs[3]=%#10x-%#10x\n", 324 loaddr, hiaddr); 325 326 loaddr = GT_LADDR_GET(gt_read(gt, GT_CS0_Low_Decode), gt->sc_model); 327 hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS0_High_Decode), gt->sc_model); 328 aprint_normal_dev(gt->sc_dev, " cs[0]=%#10x-%#10x\n", 329 loaddr, hiaddr); 330 331 loaddr = GT_LADDR_GET(gt_read(gt, GT_CS1_Low_Decode), gt->sc_model); 332 hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS1_High_Decode), gt->sc_model); 333 aprint_normal_dev(gt->sc_dev, " cs[1]=%#10x-%#10x\n", 334 loaddr, hiaddr); 335 336 loaddr = GT_LADDR_GET(gt_read(gt, GT_CS2_Low_Decode), gt->sc_model); 337 hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS2_High_Decode), gt->sc_model); 338 aprint_normal_dev(gt->sc_dev, " cs[2]=%#10x-%#10x\n", 339 loaddr, hiaddr); 340 341 loaddr = GT_LADDR_GET(gt_read(gt, GT_CS3_Low_Decode), gt->sc_model); 342 hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS3_High_Decode), gt->sc_model); 343 aprint_normal_dev(gt->sc_dev, " cs[3]=%#10x-%#10x\n", 344 loaddr, hiaddr); 345 346 loaddr = GT_LADDR_GET(gt_read(gt, GT_BootCS_Low_Decode), gt->sc_model); 347 hiaddr = GT_HADDR_GET(gt_read(gt, GT_BootCS_High_Decode), gt->sc_model); 348 aprint_normal_dev(gt->sc_dev, " bootcs=%#10x-%#10x\n", 349 loaddr, hiaddr); 350 351 loaddr = GT_LADDR_GET(gt_read(gt, GT_PCI0_IO_Low_Decode), gt->sc_model); 352 hiaddr = 353 GT_HADDR_GET(gt_read(gt, GT_PCI0_IO_High_Decode), gt->sc_model); 354 aprint_normal_dev(gt->sc_dev, " pci0io=%#10x-%#10x ", 355 loaddr, hiaddr); 356 357 loaddr = gt_read(gt, GT_PCI0_IO_Remap); 358 aprint_normal("remap=%#010x\n", loaddr); 359 360 loaddr = 361 GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem0_Low_Decode), gt->sc_model); 362 hiaddr = 363 GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem0_High_Decode), gt->sc_model); 364 aprint_normal_dev(gt->sc_dev, " pci0mem[0]=%#10x-%#10x ", 365 loaddr, hiaddr); 366 367 loaddr = gt_read(gt, GT_PCI0_Mem0_Remap_Low); 368 hiaddr = gt_read(gt, GT_PCI0_Mem0_Remap_High); 369 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 370 371 loaddr = 372 GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem1_Low_Decode), gt->sc_model); 373 hiaddr = 374 GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem1_High_Decode), gt->sc_model); 375 aprint_normal_dev(gt->sc_dev, " pci0mem[1]=%#10x-%#10x ", 376 loaddr, hiaddr); 377 378 loaddr = gt_read(gt, GT_PCI0_Mem1_Remap_Low); 379 hiaddr = gt_read(gt, GT_PCI0_Mem1_Remap_High); 380 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 381 382 loaddr = 383 GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem2_Low_Decode), gt->sc_model); 384 hiaddr = 385 GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem2_High_Decode), gt->sc_model); 386 aprint_normal_dev(gt->sc_dev, " pci0mem[2]=%#10x-%#10x ", 387 loaddr, hiaddr); 388 389 loaddr = gt_read(gt, GT_PCI0_Mem2_Remap_Low); 390 hiaddr = gt_read(gt, GT_PCI0_Mem2_Remap_High); 391 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 392 393 loaddr = 394 GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem3_Low_Decode), gt->sc_model); 395 hiaddr = 396 GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem3_High_Decode), gt->sc_model); 397 aprint_normal_dev(gt->sc_dev, " pci0mem[3]=%#10x-%#10x ", 398 loaddr, hiaddr); 399 400 loaddr = gt_read(gt, GT_PCI0_Mem3_Remap_Low); 401 hiaddr = gt_read(gt, GT_PCI0_Mem3_Remap_High); 402 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 403 404 loaddr = GT_LADDR_GET(gt_read(gt, GT_PCI1_IO_Low_Decode), gt->sc_model); 405 hiaddr = 406 GT_HADDR_GET(gt_read(gt, GT_PCI1_IO_High_Decode), gt->sc_model); 407 aprint_normal_dev(gt->sc_dev, " pci1io=%#10x-%#10x ", 408 loaddr, hiaddr); 409 410 loaddr = gt_read(gt, GT_PCI1_IO_Remap); 411 aprint_normal("remap=%#010x\n", loaddr); 412 413 loaddr = 414 GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem0_Low_Decode), gt->sc_model); 415 hiaddr = 416 GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem0_High_Decode), gt->sc_model); 417 aprint_normal_dev(gt->sc_dev, " pci1mem[0]=%#10x-%#10x ", 418 loaddr, hiaddr); 419 420 loaddr = gt_read(gt, GT_PCI1_Mem0_Remap_Low); 421 hiaddr = gt_read(gt, GT_PCI1_Mem0_Remap_High); 422 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 423 424 loaddr = 425 GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem1_Low_Decode), gt->sc_model); 426 hiaddr = 427 GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem1_High_Decode), gt->sc_model); 428 aprint_normal_dev(gt->sc_dev, " pci1mem[1]=%#10x-%#10x ", 429 loaddr, hiaddr); 430 431 loaddr = gt_read(gt, GT_PCI1_Mem1_Remap_Low); 432 hiaddr = gt_read(gt, GT_PCI1_Mem1_Remap_High); 433 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 434 435 loaddr = 436 GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem2_Low_Decode), gt->sc_model); 437 hiaddr = 438 GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem2_High_Decode), gt->sc_model); 439 aprint_normal_dev(gt->sc_dev, " pci1mem[2]=%#10x-%#10x ", 440 loaddr, hiaddr); 441 442 loaddr = gt_read(gt, GT_PCI1_Mem2_Remap_Low); 443 hiaddr = gt_read(gt, GT_PCI1_Mem2_Remap_High); 444 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 445 446 loaddr = 447 GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem3_Low_Decode), gt->sc_model); 448 hiaddr = 449 GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem3_High_Decode), gt->sc_model); 450 aprint_normal_dev(gt->sc_dev, " pci1mem[3]=%#10x-%#10x ", 451 loaddr, hiaddr); 452 453 loaddr = gt_read(gt, GT_PCI1_Mem3_Remap_Low); 454 hiaddr = gt_read(gt, GT_PCI1_Mem3_Remap_High); 455 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 456 457 loaddr = GT_LADDR_GET(gt_read(gt, GT_Internal_Decode), gt->sc_model); 458 aprint_normal_dev(gt->sc_dev, " internal=%#10x-%#10x\n", 459 loaddr, loaddr + 256 * 1024); 460 461 loaddr = GT_LADDR_GET(gt_read(gt, GT_CPU0_Low_Decode), gt->sc_model); 462 hiaddr = GT_HADDR_GET(gt_read(gt, GT_CPU0_High_Decode), gt->sc_model); 463 aprint_normal_dev(gt->sc_dev, " cpu0=%#10x-%#10x\n", 464 loaddr, hiaddr); 465 466 #ifdef MULTIPROCESSOR 467 loaddr = GT_LADDR_GET(gt_read(gt, GT_CPU1_Low_Decode), gt->sc_model); 468 hiaddr = GT_HADDR_GET(gt_read(gt, GT_CPU1_High_Decode), gt->sc_model); 469 aprint_normal_dev(gt->sc_dev, " cpu1=%#10x-%#10x", 470 loaddr, hiaddr); 471 #endif 472 #endif 473 474 aprint_normal("%s:", device_xname(gt->sc_dev)); 475 476 cpucfg = gt_read(gt, GT_CPU_Cfg); 477 cpucfg |= GT_CPUCfg_ConfSBDis; /* per errata #46 */ 478 cpucfg |= GT_CPUCfg_AACKDelay; /* per restriction #18 */ 479 gt_write(gt, GT_CPU_Cfg, cpucfg); 480 if (cpucfg & GT_CPUCfg_Pipeline) 481 aprint_normal(" pipeline"); 482 if (cpucfg & GT_CPUCfg_AACKDelay) 483 aprint_normal(" aack-delay"); 484 if (cpucfg & GT_CPUCfg_RdOOO) 485 aprint_normal(" read-ooo"); 486 if (cpucfg & GT_CPUCfg_IOSBDis) 487 aprint_normal(" io-sb-dis"); 488 if (cpucfg & GT_CPUCfg_ConfSBDis) 489 aprint_normal(" conf-sb-dis"); 490 if (cpucfg & GT_CPUCfg_ClkSync) 491 aprint_normal(" clk-sync"); 492 aprint_normal("\n"); 493 494 #ifdef GT_WATCHDOG 495 gt_watchdog_init(gt); 496 #endif 497 498 #ifdef GT_DEVBUS 499 gt_devbus_intr_enb(gt); 500 #endif 501 #ifdef GT_ECC 502 gt_ecc_intr_enb(gt); 503 #endif 504 #if NGTMPSC > 0 505 gt_sdma_intr_enb(gt); 506 #endif 507 #ifdef GT_COMM 508 gt_comm_intr_enb(gt); 509 #endif 510 511 gt_attach_peripherals(gt); 512 513 #ifdef GT_WATCHDOG 514 gt_watchdog_service(); 515 gt_watchdog_enable(gt); 516 #endif 517 } 518 519 520 #ifdef GT_DEVBUS 521 static int 522 gt_devbus_intr(void *arg) 523 { 524 struct gt_softc *gt = (struct gt_softc *)arg; 525 u_int32_t cause; 526 u_int32_t addr; 527 528 cause = gt_read(gt, GT_DEVBUS_ICAUSE); 529 addr = gt_read(gt, GT_DEVBUS_ERR_ADDR); 530 gt_write(gt, GT_DEVBUS_ICAUSE, 0); /* clear intr */ 531 532 if (cause & GT_DEVBUS_DBurstErr) { 533 aprint_error_dev(gt->sc_dev, 534 "Device Bus error: burst violation"); 535 if ((cause & GT_DEVBUS_Sel) == 0) 536 aprint_error(", addr %#x", addr); 537 aprint_error("\n"); 538 } 539 if (cause & GT_DEVBUS_DRdyErr) { 540 aprint_error_dev(gt->sc_dev, 541 "Device Bus error: ready timer expired"); 542 if ((cause & GT_DEVBUS_Sel) != 0) 543 aprint_error(", addr %#x\n", addr); 544 aprint_error("\n"); 545 } 546 547 return cause != 0; 548 } 549 550 /* 551 * gt_devbus_intr_enb - enable GT-64260 Device Bus interrupts 552 */ 553 static void 554 gt_devbus_intr_enb(struct gt_softc *gt) 555 { 556 gt_write(gt, GT_DEVBUS_IMASK, 557 GT_DEVBUS_DBurstErr|GT_DEVBUS_DRdyErr); 558 (void)gt_read(gt, GT_DEVBUS_ERR_ADDR); /* clear addr */ 559 gt_write(gt, GT_DEVBUS_ICAUSE, 0); /* clear intr */ 560 561 (void)marvell_intr_establish(IRQ_DEV, IPL_VM, gt_devbus_intr, gt); 562 } 563 #endif /* GT_DEVBUS */ 564 565 #ifdef GT_ECC 566 const static char *gt_ecc_intr_str[4] = { 567 "(none)", 568 "single bit", 569 "double bit", 570 "(reserved)" 571 }; 572 573 static int 574 gt_ecc_intr(void *arg) 575 { 576 struct gt_softc *gt = (struct gt_softc *)arg; 577 uint32_t addr, dlo, dhi, rec, calc, count; 578 int err; 579 580 count = gt_read(gt, GT_ECC_Count); 581 dlo = gt_read(gt, GT_ECC_Data_Lo); 582 dhi = gt_read(gt, GT_ECC_Data_Hi); 583 rec = gt_read(gt, GT_ECC_Rec); 584 calc = gt_read(gt, GT_ECC_Calc); 585 addr = gt_read(gt, GT_ECC_Addr); /* read last! */ 586 gt_write(gt, GT_ECC_Addr, 0); /* clear intr */ 587 588 err = addr & 0x3; 589 590 aprint_error_dev(gt->sc_dev, 591 "ECC error: %s: addr %#x data %#x.%#x rec %#x calc %#x cnt %#x\n", 592 gt_ecc_intr_str[err], addr, dhi, dlo, rec, calc, count); 593 594 if (err == 2) 595 panic("ecc"); 596 597 return err == 1; 598 } 599 600 /* 601 * gt_ecc_intr_enb - enable GT-64260 ECC interrupts 602 */ 603 static void 604 gt_ecc_intr_enb(struct gt_softc *gt) 605 { 606 uint32_t ctl; 607 608 ctl = gt_read(gt, GT_ECC_Ctl); 609 ctl |= 1 << 16; /* XXX 1-bit threshold == 1 */ 610 gt_write(gt, GT_ECC_Ctl, ctl); 611 (void)gt_read(gt, GT_ECC_Data_Lo); 612 (void)gt_read(gt, GT_ECC_Data_Hi); 613 (void)gt_read(gt, GT_ECC_Rec); 614 (void)gt_read(gt, GT_ECC_Calc); 615 (void)gt_read(gt, GT_ECC_Addr); /* read last! */ 616 gt_write(gt, GT_ECC_Addr, 0); /* clear intr */ 617 618 (void)marvell_intr_establish(IRQ_ECC, IPL_VM, gt_ecc_intr, gt); 619 } 620 #endif /* GT_ECC */ 621 622 #if NGTMPSC > 0 623 /* 624 * gt_sdma_intr_enb - enable GT-64260 SDMA interrupts 625 */ 626 static void 627 gt_sdma_intr_enb(struct gt_softc *gt) 628 { 629 630 (void)marvell_intr_establish(IRQ_SDMA, IPL_SERIAL, gtmpsc_intr, gt); 631 } 632 #endif 633 634 #ifdef GT_COMM 635 /* 636 * unknown board, enable everything 637 */ 638 # define GT_CommUnitIntr_DFLT \ 639 GT_CommUnitIntr_S0 |\ 640 GT_CommUnitIntr_S1 |\ 641 GT_CommUnitIntr_E0 |\ 642 GT_CommUnitIntr_E1 |\ 643 GT_CommUnitIntr_E2 644 645 static const char * const gt_comm_subunit_name[8] = { 646 "ethernet 0", 647 "ethernet 1", 648 "ethernet 2", 649 "(reserved)", 650 "MPSC 0", 651 "MPSC 1", 652 "(reserved)", 653 "(sel)", 654 }; 655 656 static int 657 gt_comm_intr(void *arg) 658 { 659 struct gt_softc *gt = (struct gt_softc *)arg; 660 uint32_t cause, addr; 661 unsigned int mask; 662 int i; 663 664 cause = gt_read(gt, GT_CommUnitIntr_Cause); 665 gt_write(gt, GT_CommUnitIntr_Cause, ~cause); 666 addr = gt_read(gt, GT_CommUnitIntr_ErrAddr); 667 668 aprint_error_dev(gt->sc_dev, 669 "Communications Unit Controller interrupt, cause %#x addr %#x\n", 670 cause, addr); 671 672 cause &= GT_CommUnitIntr_DFLT; 673 if (cause == 0) 674 return 0; 675 676 mask = 0x7; 677 for (i=0; i<7; i++) { 678 if (cause & mask) { 679 printf("%s: Comm Unit %s:", device_xname(gt->sc_dev), 680 gt_comm_subunit_name[i]); 681 if (cause & 1) 682 printf(" AddrMiss"); 683 if (cause & 2) 684 printf(" AccProt"); 685 if (cause & 4) 686 printf(" WrProt"); 687 printf("\n"); 688 } 689 cause >>= 4; 690 } 691 return 1; 692 } 693 694 /* 695 * gt_comm_intr_init - enable GT-64260 Comm Unit interrupts 696 */ 697 static void 698 gt_comm_intr_enb(struct gt_softc *gt) 699 { 700 uint32_t cause; 701 702 cause = gt_read(gt, GT_CommUnitIntr_Cause); 703 if (cause) 704 gt_write(gt, GT_CommUnitIntr_Cause, ~cause); 705 gt_write(gt, GT_CommUnitIntr_Mask, GT_CommUnitIntr_DFLT); 706 (void)gt_read(gt, GT_CommUnitIntr_ErrAddr); 707 708 (void)marvell_intr_establish(IRQ_COMM, IPL_VM, gt_comm_intr, gt); 709 } 710 #endif /* GT_COMM */ 711 712 713 #ifdef GT_WATCHDOG 714 #ifndef GT_MPP_WATCHDOG 715 static void 716 gt_watchdog_init(struct gt_softc *gt) 717 { 718 u_int32_t r; 719 720 aprint_normal_dev(gt->sc_dev, "watchdog"); 721 722 /* 723 * handle case where firmware started watchdog 724 */ 725 r = gt_read(gt, GT_WDOG_Config); 726 aprint_normal(" status %#x,%#x:", r, gt_read(gt, GT_WDOG_Value)); 727 if ((r & 0x80000000) != 0) { 728 gt_watchdog_sc = gt; /* enabled */ 729 gt_watchdog_state = 1; 730 aprint_normal(" firmware-enabled\n"); 731 gt_watchdog_disable(gt); 732 } else 733 aprint_normal(" firmware-disabled\n"); 734 } 735 736 #elif GT_MPP_WATCHDOG == 0 737 738 static void 739 gt_watchdog_init(struct gt_softc *gt) 740 { 741 742 aprint_normal_dev(gt->sc_dev, "watchdog not configured\n"); 743 return; 744 } 745 746 #else /* GT_MPP_WATCHDOG > 0 */ 747 748 static void 749 gt_watchdog_init(struct gt_softc *gt) 750 { 751 u_int32_t mpp_watchdog = GT_MPP_WATCHDOG; /* from config */ 752 u_int32_t cfgbits, mppbits, mppmask, regoff, r; 753 754 mppmask = 0; 755 756 aprint_normal_dev(gt->sc_dev, "watchdog"); 757 758 /* 759 * if firmware started watchdog, we disable and start 760 * from scratch to get it in a known state. 761 * 762 * on GT-64260A we always see 0xffffffff 763 * in both the GT_WDOG_Config_Enb and GT_WDOG_Value registers. 764 */ 765 r = gt_read(gt, GT_WDOG_Config); 766 if (r != ~0) { 767 if ((r & GT_WDOG_Config_Enb) != 0) { 768 gt_write(gt, GT_WDOG_Config, 769 GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT); 770 gt_write(gt, GT_WDOG_Config, 771 GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT); 772 } 773 } 774 775 /* 776 * "the watchdog timer can be activated only after 777 * configuring two MPP pins to act as WDE and WDNMI" 778 */ 779 mppbits = 0; 780 cfgbits = 0x3; 781 for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4) { 782 if ((mpp_watchdog & cfgbits) == cfgbits) { 783 mppbits = 0x99; 784 mppmask = 0xff; 785 break; 786 } 787 cfgbits <<= 2; 788 if ((mpp_watchdog & cfgbits) == cfgbits) { 789 mppbits = 0x9900; 790 mppmask = 0xff00; 791 break; 792 } 793 cfgbits <<= 6; /* skip unqualified bits */ 794 } 795 if (mppbits == 0) { 796 aprint_error(" config error\n"); 797 return; 798 } 799 800 r = gt_read(gt, regoff); 801 r &= ~mppmask; 802 r |= mppbits; 803 gt_write(gt, regoff, r); 804 aprint_normal(" mpp %#x %#x", regoff, mppbits); 805 806 gt_write(gt, GT_WDOG_Value, GT_WDOG_NMI_DFLT); 807 808 gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1a|GT_WDOG_Preset_DFLT); 809 gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1b|GT_WDOG_Preset_DFLT); 810 811 r = gt_read(gt, GT_WDOG_Config); 812 aprint_normal(" status %#x,%#x: %s\n", 813 r, gt_read(gt, GT_WDOG_Value), 814 ((r & GT_WDOG_Config_Enb) != 0) ? "enabled" : "botch"); 815 } 816 #endif /* GT_MPP_WATCHDOG */ 817 818 static void 819 gt_watchdog_enable(struct gt_softc *gt) 820 { 821 822 if (gt_watchdog_state == 0) { 823 gt_watchdog_state = 1; 824 825 gt_write(gt, GT_WDOG_Config, 826 GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT); 827 gt_write(gt, GT_WDOG_Config, 828 GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT); 829 } 830 } 831 832 #ifndef GT_MPP_WATCHDOG 833 static void 834 gt_watchdog_disable(struct gt_softc *gt) 835 { 836 837 if (gt_watchdog_state != 0) { 838 gt_watchdog_state = 0; 839 840 gt_write(gt, GT_WDOG_Config, 841 GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT); 842 gt_write(gt, GT_WDOG_Config, 843 GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT); 844 } 845 } 846 #endif 847 848 /* 849 * XXXX: gt_watchdog_service/reset functions need mutex lock... 850 */ 851 852 #ifdef GT_DEBUG 853 int inhibit_watchdog_service = 0; 854 #endif 855 void 856 gt_watchdog_service(void) 857 { 858 struct gt_softc *gt = gt_watchdog_sc; 859 860 if ((gt == NULL) || (gt_watchdog_state == 0)) 861 return; /* not enabled */ 862 #ifdef GT_DEBUG 863 if (inhibit_watchdog_service) 864 return; 865 #endif 866 867 gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl2a|GT_WDOG_Preset_DFLT); 868 gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl2b|GT_WDOG_Preset_DFLT); 869 } 870 871 /* 872 * gt_watchdog_reset - force a watchdog reset using Preset_VAL=0 873 */ 874 void 875 gt_watchdog_reset(void) 876 { 877 struct gt_softc *gt = gt_watchdog_sc; 878 u_int32_t r; 879 880 r = gt_read(gt, GT_WDOG_Config); 881 gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1a); 882 gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1b); 883 if ((r & GT_WDOG_Config_Enb) != 0) { 884 /* 885 * was enabled, we just toggled it off, toggle on again 886 */ 887 gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1a); 888 gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1b); 889 } 890 for(;;); 891 } 892 #endif 893 894 895 int 896 marvell_winparams_by_tag(device_t dev, int tag, int *target, int *attr, 897 uint64_t *base, uint32_t *size) 898 { 899 static const struct { 900 int tag; 901 uint32_t attribute; 902 uint32_t basereg; 903 uint32_t sizereg; 904 } tagtbl[] = { 905 { MARVELL_TAG_SDRAM_CS0, MARVELL_ATTR_SDRAM_CS0, 906 GT_SCS0_Low_Decode, GT_SCS0_High_Decode }, 907 { MARVELL_TAG_SDRAM_CS1, MARVELL_ATTR_SDRAM_CS1, 908 GT_SCS1_Low_Decode, GT_SCS1_High_Decode }, 909 { MARVELL_TAG_SDRAM_CS2, MARVELL_ATTR_SDRAM_CS2, 910 GT_SCS2_Low_Decode, GT_SCS2_High_Decode }, 911 { MARVELL_TAG_SDRAM_CS3, MARVELL_ATTR_SDRAM_CS3, 912 GT_SCS3_Low_Decode, GT_SCS3_High_Decode }, 913 914 { MARVELL_TAG_UNDEFINED, 0, 0 } 915 }; 916 struct gt_softc *sc = device_private(dev); 917 int i; 918 919 for (i = 0; tagtbl[i].tag != MARVELL_TAG_UNDEFINED; i++) 920 if (tag == tagtbl[i].tag) 921 break; 922 if (tagtbl[i].tag == MARVELL_TAG_UNDEFINED) 923 return -1; 924 925 if (target != NULL) 926 *target = 0; 927 if (attr != NULL) 928 *attr = tagtbl[i].attribute; 929 if (base != NULL) 930 *base = gt_read(sc, tagtbl[i].basereg) << 931 (sc->sc_model == MARVELL_DISCOVERY ? 20 : 16); 932 if (size != NULL) { 933 const uint32_t s = gt_read(sc, tagtbl[i].sizereg); 934 935 if (s != 0) 936 *size = (s + 1) << 937 (sc->sc_model == MARVELL_DISCOVERY ? 20 : 16); 938 else 939 *size = 0; 940 } 941 942 return 0; 943 } 944