1 /* $NetBSD: gt.c,v 1.6 2004/03/20 01:55:00 matt 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.6 2004/03/20 01:55:00 matt Exp $"); 46 47 #include "opt_marvell.h" 48 49 #include <sys/param.h> 50 #include <sys/types.h> 51 #include <sys/cdefs.h> 52 #include <sys/extent.h> 53 #include <sys/device.h> 54 #include <sys/kernel.h> 55 #include <sys/malloc.h> 56 57 #define _BUS_SPACE_PRIVATE 58 #define _BUS_DMA_PRIVATE 59 #include <machine/bus.h> 60 61 #include <powerpc/spr.h> 62 #include <powerpc/oea/hid.h> 63 64 #include <dev/marvell/gtreg.h> 65 #include <dev/marvell/gtintrreg.h> 66 #include <dev/marvell/gtvar.h> 67 #include <dev/marvell/gtethreg.h> 68 69 #ifdef DEBUG 70 #include <sys/systm.h> /* for Debugger() */ 71 #endif 72 73 #if ((GT_MPP_WATCHDOG & 0xf0f0f0f0) != 0) 74 # error /* unqualified: configuration botch! */ 75 #endif 76 #if ((GT_MPP_WATCHDOG & GT_MPP_INTERRUPTS) != 0) 77 # error /* conflict: configuration botch! */ 78 #endif 79 80 static void gt_comm_intr_enb(struct gt_softc *); 81 static void gt_devbus_intr_enb(struct gt_softc *); 82 #ifdef GT_ECC 83 static void gt_ecc_intr_enb(struct gt_softc *); 84 #endif 85 86 87 void gt_init_hostid (struct gt_softc *); 88 void gt_init_interrupt (struct gt_softc *); 89 static int gt_comm_intr (void *); 90 91 void gt_watchdog_init(struct gt_softc *); 92 void gt_watchdog_enable(void); 93 void gt_watchdog_disable(void); 94 void gt_watchdog_reset(void); 95 96 extern struct cfdriver gt_cd; 97 98 static int gtfound = 0; 99 100 static struct gt_softc *gt_watchdog_sc = 0; 101 static int gt_watchdog_state = 0; 102 103 int 104 gt_cfprint (void *aux, const char *pnp) 105 { 106 struct gt_attach_args *ga = aux; 107 108 if (pnp) { 109 aprint_normal("%s at %s", ga->ga_name, pnp); 110 } 111 112 aprint_normal(" unit %d", ga->ga_unit); 113 return (UNCONF); 114 } 115 116 117 static int 118 gt_cfsearch(struct device *parent, struct cfdata *cf, void *aux) 119 { 120 struct gt_softc *gt = (struct gt_softc *) parent; 121 struct gt_attach_args ga; 122 123 ga.ga_name = cf->cf_name; 124 ga.ga_dmat = gt->gt_dmat; 125 ga.ga_memt = gt->gt_memt; 126 ga.ga_memh = gt->gt_memh; 127 ga.ga_unit = cf->cf_loc[GTCF_UNIT]; 128 129 if (config_match(parent, cf, &ga) > 0) 130 config_attach(parent, cf, &ga, gt_cfprint); 131 132 return (0); 133 } 134 135 void 136 gt_attach_common(struct gt_softc *gt) 137 { 138 uint32_t cpucfg, cpumode, cpumstr; 139 #ifdef DEBUG 140 uint32_t loaddr, hiaddr; 141 #endif 142 143 gtfound = 1; 144 145 cpumode = gt_read(gt, GT_CPU_Mode); 146 aprint_normal(": id %d", GT_CPUMode_MultiGTID_GET(cpumode)); 147 if (cpumode & GT_CPUMode_MultiGT) 148 aprint_normal (" (multi)"); 149 switch (GT_CPUMode_CPUType_GET(cpumode)) { 150 case 4: aprint_normal(", 60x bus"); break; 151 case 5: aprint_normal(", MPX bus"); break; 152 default: aprint_normal(", %#x(?) bus", GT_CPUMode_CPUType_GET(cpumode)); break; 153 } 154 155 cpumstr = gt_read(gt, GT_CPU_Master_Ctl); 156 cpumstr &= ~(GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock); 157 #if 0 158 cpumstr |= GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock; 159 #endif 160 gt_write(gt, GT_CPU_Master_Ctl, cpumstr); 161 162 switch (cpumstr & (GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock)) { 163 case 0: break; 164 case GT_CPUMstrCtl_CleanBlock: aprint_normal(", snoop=clean"); break; 165 case GT_CPUMstrCtl_FlushBlock: aprint_normal(", snoop=flush"); break; 166 case GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock: 167 aprint_normal(", snoop=clean&flush"); break; 168 } 169 aprint_normal(" wdog=%#x,%#x\n", 170 gt_read(gt, GT_WDOG_Config), 171 gt_read(gt, GT_WDOG_Value)); 172 173 #if DEBUG 174 loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS0_Low_Decode)); 175 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS0_High_Decode)); 176 aprint_normal("%s: scs[0]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); 177 178 loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS1_Low_Decode)); 179 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS1_High_Decode)); 180 aprint_normal("%s: scs[1]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); 181 182 loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS2_Low_Decode)); 183 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS2_High_Decode)); 184 aprint_normal("%s: scs[2]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); 185 186 loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS3_Low_Decode)); 187 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS3_High_Decode)); 188 aprint_normal("%s: scs[3]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); 189 190 loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS0_Low_Decode)); 191 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS0_High_Decode)); 192 aprint_normal("%s: cs[0]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); 193 194 loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS1_Low_Decode)); 195 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS1_High_Decode)); 196 aprint_normal("%s: cs[1]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); 197 198 loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS2_Low_Decode)); 199 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS2_High_Decode)); 200 aprint_normal("%s: cs[2]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); 201 202 loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS3_Low_Decode)); 203 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS3_High_Decode)); 204 aprint_normal("%s: cs[3]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); 205 206 loaddr = GT_LowAddr_GET(gt_read(gt, GT_BootCS_Low_Decode)); 207 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_BootCS_High_Decode)); 208 aprint_normal("%s: bootcs=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); 209 210 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_IO_Low_Decode)); 211 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_IO_High_Decode)); 212 aprint_normal("%s: pci0io=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); 213 214 loaddr = gt_read(gt, GT_PCI0_IO_Remap); 215 aprint_normal("remap=%#010x\n", loaddr); 216 217 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem0_Low_Decode)); 218 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem0_High_Decode)); 219 aprint_normal("%s: pci0mem[0]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); 220 221 loaddr = gt_read(gt, GT_PCI0_Mem0_Remap_Low); 222 hiaddr = gt_read(gt, GT_PCI0_Mem0_Remap_High); 223 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 224 225 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem1_Low_Decode)); 226 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem1_High_Decode)); 227 aprint_normal("%s: pci0mem[1]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); 228 229 loaddr = gt_read(gt, GT_PCI0_Mem1_Remap_Low); 230 hiaddr = gt_read(gt, GT_PCI0_Mem1_Remap_High); 231 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 232 233 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem2_Low_Decode)); 234 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem2_High_Decode)); 235 aprint_normal("%s: pci0mem[2]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); 236 237 loaddr = gt_read(gt, GT_PCI0_Mem2_Remap_Low); 238 hiaddr = gt_read(gt, GT_PCI0_Mem2_Remap_High); 239 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 240 241 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem3_Low_Decode)); 242 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem3_High_Decode)); 243 aprint_normal("%s: pci0mem[3]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); 244 245 loaddr = gt_read(gt, GT_PCI0_Mem3_Remap_Low); 246 hiaddr = gt_read(gt, GT_PCI0_Mem3_Remap_High); 247 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 248 249 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_IO_Low_Decode)); 250 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_IO_High_Decode)); 251 aprint_normal("%s: pci1io=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); 252 253 loaddr = gt_read(gt, GT_PCI1_IO_Remap); 254 aprint_normal("remap=%#010x\n", loaddr); 255 256 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem0_Low_Decode)); 257 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem0_High_Decode)); 258 aprint_normal("%s: pci1mem[0]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); 259 260 loaddr = gt_read(gt, GT_PCI1_Mem0_Remap_Low); 261 hiaddr = gt_read(gt, GT_PCI1_Mem0_Remap_High); 262 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 263 264 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem1_Low_Decode)); 265 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem1_High_Decode)); 266 aprint_normal("%s: pci1mem[1]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); 267 268 loaddr = gt_read(gt, GT_PCI1_Mem1_Remap_Low); 269 hiaddr = gt_read(gt, GT_PCI1_Mem1_Remap_High); 270 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 271 272 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem2_Low_Decode)); 273 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem2_High_Decode)); 274 aprint_normal("%s: pci1mem[2]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); 275 276 loaddr = gt_read(gt, GT_PCI1_Mem2_Remap_Low); 277 hiaddr = gt_read(gt, GT_PCI1_Mem2_Remap_High); 278 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 279 280 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem3_Low_Decode)); 281 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem3_High_Decode)); 282 aprint_normal("%s: pci1mem[3]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); 283 284 loaddr = gt_read(gt, GT_PCI1_Mem3_Remap_Low); 285 hiaddr = gt_read(gt, GT_PCI1_Mem3_Remap_High); 286 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); 287 288 loaddr = GT_LowAddr_GET(gt_read(gt, GT_Internal_Decode)); 289 aprint_normal("%s: internal=%#10x-%#10x\n", gt->gt_dev.dv_xname, 290 loaddr, loaddr+256*1024); 291 292 loaddr = GT_LowAddr_GET(gt_read(gt, GT_CPU0_Low_Decode)); 293 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CPU0_High_Decode)); 294 aprint_normal("%s: cpu0=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); 295 296 loaddr = GT_LowAddr_GET(gt_read(gt, GT_CPU1_Low_Decode)); 297 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CPU1_High_Decode)); 298 aprint_normal("%s: cpu1=%#10x-%#10x", gt->gt_dev.dv_xname, loaddr, hiaddr); 299 #endif 300 301 aprint_normal("%s:", gt->gt_dev.dv_xname); 302 303 cpucfg = gt_read(gt, GT_CPU_Cfg); 304 cpucfg |= GT_CPUCfg_ConfSBDis; /* per errata #46 */ 305 cpucfg |= GT_CPUCfg_AACKDelay; /* per restriction #18 */ 306 gt_write(gt, GT_CPU_Cfg, cpucfg); 307 if (cpucfg & GT_CPUCfg_Pipeline) 308 aprint_normal(" pipeline"); 309 if (cpucfg & GT_CPUCfg_AACKDelay) 310 aprint_normal(" aack-delay"); 311 if (cpucfg & GT_CPUCfg_RdOOO) 312 aprint_normal(" read-ooo"); 313 if (cpucfg & GT_CPUCfg_IOSBDis) 314 aprint_normal(" io-sb-dis"); 315 if (cpucfg & GT_CPUCfg_ConfSBDis) 316 aprint_normal(" conf-sb-dis"); 317 if (cpucfg & GT_CPUCfg_ClkSync) 318 aprint_normal(" clk-sync"); 319 aprint_normal("\n"); 320 321 gt_init_hostid(gt); 322 323 gt_watchdog_init(gt); 324 325 gt_init_interrupt(gt); 326 327 #ifdef GT_ECC 328 gt_ecc_intr_enb(gt); 329 #endif 330 331 gt_comm_intr_enb(gt); 332 gt_devbus_intr_enb(gt); 333 334 gt_watchdog_disable(); 335 config_search(gt_cfsearch, >->gt_dev, NULL); 336 gt_watchdog_service(); 337 gt_watchdog_enable(); 338 } 339 340 void 341 gt_init_hostid(struct gt_softc *gt) 342 { 343 344 hostid = 1; /* XXX: Used by i2c; needs work -- AKB */ 345 } 346 347 void 348 gt_init_interrupt(struct gt_softc *gt) 349 { 350 u_int32_t mppirpts = GT_MPP_INTERRUPTS; /* from config */ 351 u_int32_t r; 352 u_int32_t mppbit; 353 u_int32_t mask; 354 u_int32_t mppsel; 355 u_int32_t regoff; 356 357 gt_write(gt, ICR_CIM_LO, 0); 358 gt_write(gt, ICR_CIM_HI, 0); 359 360 /* 361 * configure the GPP interrupts: 362 * - set the configured MPP pins in GPP mode 363 * - set the configured GPP pins to input, active low, interrupt enbl 364 */ 365 #ifdef DEBUG 366 printf("%s: mpp cfg ", gt->gt_dev.dv_xname); 367 for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4) 368 printf("%#x ", gt_read(gt, regoff)); 369 printf(", mppirpts 0x%x\n", mppirpts); 370 #endif 371 mppbit = 0x1; 372 for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4) { 373 mask = 0; 374 for (mppsel = 0xf; mppsel; mppsel <<= 4) { 375 if (mppirpts & mppbit) 376 mask |= mppsel; 377 mppbit <<= 1; 378 } 379 if (mask) { 380 r = gt_read(gt, regoff); 381 r &= ~mask; 382 gt_write(gt, regoff, r); 383 } 384 } 385 386 r = gt_read(gt, GT_GPP_IO_Control); 387 r &= ~mppirpts; 388 gt_write(gt, GT_GPP_IO_Control, r); 389 390 r = gt_read(gt, GT_GPP_Level_Control); 391 r |= mppirpts; 392 gt_write(gt, GT_GPP_Level_Control, r); 393 394 r = gt_read(gt, GT_GPP_Interrupt_Mask); 395 r |= mppirpts; 396 gt_write(gt, GT_GPP_Interrupt_Mask, r); 397 } 398 399 uint32_t 400 gt_read_mpp (void) 401 { 402 return gt_read((struct gt_softc *)gt_cd.cd_devs[0], GT_GPP_Value); 403 } 404 405 #if 0 406 int 407 gt_bs_extent_init(struct discovery_bus_space *bs, char *name) 408 { 409 u_long start, end; 410 int i, j, error; 411 412 if (bs->bs_nregion == 0) { 413 bs->bs_extent = extent_create(name, 0xffffffffUL, 0xffffffffUL, 414 M_DEVBUF, NULL, 0, EX_NOCOALESCE|EX_WAITOK); 415 KASSERT(bs->bs_extent != NULL); 416 return 0; 417 } 418 /* 419 * Find the top and bottoms of this bus space. 420 */ 421 start = bs->bs_regions[0].br_start; 422 end = bs->bs_regions[0].br_end; 423 #ifdef DEBUG 424 if (gtpci_debug > 1) 425 printf("gtpci_bs_extent_init: %s: region %d: %#lx-%#lx\n", 426 name, 0, bs->bs_regions[0].br_start, 427 bs->bs_regions[0].br_end); 428 #endif 429 for (i = 1; i < bs->bs_nregion; i++) { 430 if (bs->bs_regions[i].br_start < start) 431 start = bs->bs_regions[i].br_start; 432 if (bs->bs_regions[i].br_end > end) 433 end = bs->bs_regions[i].br_end; 434 #ifdef DEBUG 435 if (gtpci_debug > 1) 436 printf("gtpci_bs_extent_init: %s: region %d:" 437 " %#lx-%#lx\n", 438 name, i, bs->bs_regions[i].br_start, 439 bs->bs_regions[i].br_end); 440 #endif 441 } 442 /* 443 * Now that we have the top and bottom limits of this 444 * bus space, create the extent map that will manage this 445 * space for us. 446 */ 447 #ifdef DEBUG 448 if (gtpci_debug > 1) 449 printf("gtpci_bs_extent_init: %s: create: %#lx-%#lx\n", 450 name, start, end); 451 #endif 452 bs->bs_extent = extent_create(name, start, end, M_DEVBUF, 453 NULL, 0, EX_NOCOALESCE|EX_WAITOK); 454 KASSERT(bs->bs_extent != NULL); 455 456 /* If there was more than one bus space region, then there 457 * might gaps in between them. Allocate the gap so that 458 * they will not be legal addresses in the extent. 459 */ 460 for (i = 0; i < bs->bs_nregion && bs->bs_nregion > 1; i++) { 461 /* Initial start is "infinity" and the inital end is 462 * is the end of this bus region. 463 */ 464 start = ~0UL; 465 end = bs->bs_regions[i].br_end; 466 /* For each region, if it starts after this region but less 467 * than the saved start, use its start address. If the start 468 * address is one past the end address, then we're done 469 */ 470 for (j = 0; j < bs->bs_nregion && start > end + 1; j++) { 471 if (i == j) 472 continue; 473 if (bs->bs_regions[j].br_start > end && 474 bs->bs_regions[j].br_start < start) 475 start = bs->bs_regions[j].br_start; 476 } 477 /* 478 * If we found a gap, allocate it away. 479 */ 480 if (start != ~0UL && start != end + 1) { 481 #ifdef DEBUG 482 if (gtpci_debug > 1) 483 printf("gtpci_bs_extent_init: %s: alloc(hole): %#lx-%#lx\n", 484 name, end + 1, start - 1); 485 #endif 486 error = extent_alloc_region(bs->bs_extent, end + 1, 487 start - (end + 1), EX_NOWAIT); 488 KASSERT(error == 0); 489 } 490 } 491 return 1; 492 } 493 #endif 494 495 /* 496 * unknown board, enable everything 497 */ 498 # define GT_CommUnitIntr_DFLT GT_CommUnitIntr_S0|GT_CommUnitIntr_S1 \ 499 |GT_CommUnitIntr_E0|GT_CommUnitIntr_E1 \ 500 |GT_CommUnitIntr_E2 501 502 static const char * const gt_comm_subunit_name[8] = { 503 "ethernet 0", 504 "ethernet 1", 505 "ethernet 2", 506 "(reserved)", 507 "MPSC 0", 508 "MPSC 1", 509 "(reserved)", 510 "(sel)", 511 }; 512 513 static int 514 gt_comm_intr(void *arg) 515 { 516 struct gt_softc *gt = (struct gt_softc *)arg; 517 u_int32_t cause; 518 u_int32_t addr; 519 unsigned int mask; 520 int i; 521 522 cause = gt_read(gt, GT_CommUnitIntr_Cause); 523 gt_write(gt, GT_CommUnitIntr_Cause, ~cause); 524 addr = gt_read(gt, GT_CommUnitIntr_ErrAddr); 525 526 printf("%s: Comm Unit irpt, cause %#x addr %#x\n", 527 gt->gt_dev.dv_xname, cause, addr); 528 529 cause &= GT_CommUnitIntr_DFLT; 530 if (cause == 0) 531 return 0; 532 533 mask = 0x7; 534 for (i=0; i<7; i++) { 535 if (cause & mask) { 536 printf("%s: Comm Unit %s:", gt->gt_dev.dv_xname, 537 gt_comm_subunit_name[i]); 538 if (cause & 1) 539 printf(" AddrMiss"); 540 if (cause & 2) 541 printf(" AccProt"); 542 if (cause & 4) 543 printf(" WrProt"); 544 printf("\n"); 545 } 546 cause >>= 4; 547 } 548 return 1; 549 } 550 551 /* 552 * gt_comm_intr_init - enable GT-64260 Comm Unit interrupts 553 */ 554 static void 555 gt_comm_intr_enb(struct gt_softc *gt) 556 { 557 u_int32_t cause; 558 559 cause = gt_read(gt, GT_CommUnitIntr_Cause); 560 if (cause) 561 gt_write(gt, GT_CommUnitIntr_Cause, ~cause); 562 gt_write(gt, GT_CommUnitIntr_Mask, GT_CommUnitIntr_DFLT); 563 (void)gt_read(gt, GT_CommUnitIntr_ErrAddr); 564 565 intr_establish(IRQ_COMM, IST_LEVEL, IPL_GTERR, gt_comm_intr, gt); 566 printf("%s: Comm Unit irpt at %d\n", gt->gt_dev.dv_xname, IRQ_COMM); 567 } 568 569 #ifdef GT_ECC 570 static char *gt_ecc_intr_str[4] = { 571 "(none)", 572 "single bit", 573 "double bit", 574 "(reserved)" 575 }; 576 577 static int 578 gt_ecc_intr(void *arg) 579 { 580 struct gt_softc *gt = (struct gt_softc *)arg; 581 u_int32_t addr; 582 u_int32_t dlo; 583 u_int32_t dhi; 584 u_int32_t rec; 585 u_int32_t calc; 586 u_int32_t count; 587 int err; 588 589 count = gt_read(gt, GT_ECC_Count); 590 dlo = gt_read(gt, GT_ECC_Data_Lo); 591 dhi = gt_read(gt, GT_ECC_Data_Hi); 592 rec = gt_read(gt, GT_ECC_Rec); 593 calc = gt_read(gt, GT_ECC_Calc); 594 addr = gt_read(gt, GT_ECC_Addr); /* read last! */ 595 gt_write(gt, GT_ECC_Addr, 0); /* clear irpt */ 596 597 err = addr & 0x3; 598 599 printf("%s: ECC error: %s: " 600 "addr %#x data %#x.%#x rec %#x calc %#x cnt %#x\n", 601 gt->gt_dev.dv_xname, gt_ecc_intr_str[err], 602 addr, dhi, dlo, rec, calc, count); 603 604 if (err == 2) 605 panic("ecc"); 606 607 return (err == 1); 608 } 609 610 /* 611 * gt_ecc_intr_enb - enable GT-64260 ECC interrupts 612 */ 613 static void 614 gt_ecc_intr_enb(struct gt_softc *gt) 615 { 616 u_int32_t ctl; 617 618 ctl = gt_read(gt, GT_ECC_Ctl); 619 ctl |= 1 << 16; /* XXX 1-bit threshold == 1 */ 620 gt_write(gt, GT_ECC_Ctl, ctl); 621 (void)gt_read(gt, GT_ECC_Data_Lo); 622 (void)gt_read(gt, GT_ECC_Data_Hi); 623 (void)gt_read(gt, GT_ECC_Rec); 624 (void)gt_read(gt, GT_ECC_Calc); 625 (void)gt_read(gt, GT_ECC_Addr); /* read last! */ 626 gt_write(gt, GT_ECC_Addr, 0); /* clear irpt */ 627 628 intr_establish(IRQ_ECC, IST_LEVEL, IPL_GTERR, gt_ecc_intr, gt); 629 printf("%s: ECC irpt at %d\n", gt->gt_dev.dv_xname, IRQ_ECC); 630 } 631 #endif /* GT_ECC */ 632 633 634 #ifndef GT_MPP_WATCHDOG 635 void 636 gt_watchdog_init(struct gt_softc *gt) 637 { 638 u_int32_t r; 639 unsigned int omsr; 640 641 omsr = extintr_disable(); 642 643 printf("%s: watchdog", gt->gt_dev.dv_xname); 644 645 /* 646 * handle case where firmware started watchdog 647 */ 648 r = gt_read(gt, GT_WDOG_Config); 649 printf(" status %#x,%#x:", 650 r, gt_read(gt, GT_WDOG_Value)); 651 if ((r & 0x80000000) != 0) { 652 gt_watchdog_sc = gt; /* enabled */ 653 gt_watchdog_state = 1; 654 printf(" firmware-enabled\n"); 655 gt_watchdog_service(); 656 return; 657 } else { 658 printf(" firmware-disabled\n"); 659 } 660 661 extintr_restore(omsr); 662 } 663 664 #else /* GT_MPP_WATCHDOG */ 665 666 void 667 gt_watchdog_init(struct gt_softc *gt) 668 { 669 u_int32_t mpp_watchdog = GT_MPP_WATCHDOG; /* from config */ 670 u_int32_t r; 671 u_int32_t cfgbits; 672 u_int32_t mppbits; 673 u_int32_t mppmask=0; 674 u_int32_t regoff; 675 unsigned int omsr; 676 677 printf("%s: watchdog", gt->gt_dev.dv_xname); 678 679 if (mpp_watchdog == 0) { 680 printf(" not configured\n"); 681 return; 682 } 683 684 #if 0 685 if (afw_wdog_ctl == 1) { 686 printf(" admin disabled\n"); 687 return; 688 } 689 #endif 690 691 omsr = extintr_disable(); 692 693 /* 694 * if firmware started watchdog, we disable and start 695 * from scratch to get it in a known state. 696 * 697 * on GT-64260A we always see 0xffffffff 698 * in both the GT_WDOG_Config_Enb and GT_WDOG_Value regsiters. 699 * Use AFW-supplied flag to determine run state. 700 */ 701 r = gt_read(gt, GT_WDOG_Config); 702 if (r != ~0) { 703 if ((r & GT_WDOG_Config_Enb) != 0) { 704 gt_write(gt, GT_WDOG_Config, 705 (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT)); 706 gt_write(gt, GT_WDOG_Config, 707 (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT)); 708 } 709 } else { 710 #if 0 711 if (afw_wdog_state == 1) { 712 gt_write(gt, GT_WDOG_Config, 713 (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT)); 714 gt_write(gt, GT_WDOG_Config, 715 (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT)); 716 } 717 #endif 718 } 719 720 /* 721 * "the watchdog timer can be activated only after 722 * configuring two MPP pins to act as WDE and WDNMI" 723 */ 724 mppbits = 0; 725 cfgbits = 0x3; 726 for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4) { 727 if ((mpp_watchdog & cfgbits) == cfgbits) { 728 mppbits = 0x99; 729 mppmask = 0xff; 730 break; 731 } 732 cfgbits <<= 2; 733 if ((mpp_watchdog & cfgbits) == cfgbits) { 734 mppbits = 0x9900; 735 mppmask = 0xff00; 736 break; 737 } 738 cfgbits <<= 6; /* skip unqualified bits */ 739 } 740 if (mppbits == 0) { 741 printf(" config error\n"); 742 extintr_restore(omsr); 743 return; 744 } 745 746 r = gt_read(gt, regoff); 747 r &= ~mppmask; 748 r |= mppbits; 749 gt_write(gt, regoff, r); 750 printf(" mpp %#x %#x", regoff, mppbits); 751 752 gt_write(gt, GT_WDOG_Value, GT_WDOG_NMI_DFLT); 753 754 gt_write(gt, GT_WDOG_Config, 755 (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT)); 756 gt_write(gt, GT_WDOG_Config, 757 (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT)); 758 759 760 r = gt_read(gt, GT_WDOG_Config), 761 printf(" status %#x,%#x: %s", 762 r, gt_read(gt, GT_WDOG_Value), 763 ((r & GT_WDOG_Config_Enb) != 0) ? "enabled" : "botch"); 764 765 if ((r & GT_WDOG_Config_Enb) != 0) { 766 register_t hid0; 767 768 gt_watchdog_sc = gt; /* enabled */ 769 gt_watchdog_state = 1; 770 771 /* 772 * configure EMCP in HID0 in case it's not already set 773 */ 774 __asm __volatile("sync"); 775 hid0 = mfspr(SPR_HID0); 776 if ((hid0 & HID0_EMCP) == 0) { 777 hid0 |= HID0_EMCP; 778 __asm __volatile("sync"); mtspr(SPR_HID0, hid0); 779 __asm __volatile("sync"); hid0 = mfspr(SPR_HID0); 780 printf(", EMCP set"); 781 } 782 } 783 printf("\n"); 784 785 extintr_restore(omsr); 786 } 787 #endif /* GT_MPP_WATCHDOG */ 788 789 #ifdef DEBUG 790 u_int32_t hid0_print(void); 791 u_int32_t 792 hid0_print() 793 { 794 u_int32_t hid0; 795 __asm __volatile("sync; mfspr %0,1008;" : "=r"(hid0)); 796 printf("hid0: %#x\n", hid0); 797 return hid0; 798 } 799 #endif 800 801 void 802 gt_watchdog_enable(void) 803 { 804 struct gt_softc *gt; 805 unsigned int omsr; 806 807 omsr = extintr_disable(); 808 gt = gt_watchdog_sc; 809 if ((gt != NULL) && (gt_watchdog_state == 0)) { 810 gt_watchdog_state = 1; 811 812 gt_write(gt, GT_WDOG_Config, 813 (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT)); 814 gt_write(gt, GT_WDOG_Config, 815 (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT)); 816 } 817 extintr_restore(omsr); 818 } 819 820 void 821 gt_watchdog_disable(void) 822 { 823 struct gt_softc *gt; 824 unsigned int omsr; 825 826 omsr = extintr_disable(); 827 gt = gt_watchdog_sc; 828 if ((gt != NULL) && (gt_watchdog_state != 0)) { 829 gt_watchdog_state = 0; 830 831 gt_write(gt, GT_WDOG_Config, 832 (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT)); 833 gt_write(gt, GT_WDOG_Config, 834 (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT)); 835 } 836 extintr_restore(omsr); 837 } 838 839 #ifdef DEBUG 840 int inhibit_watchdog_service = 0; 841 #endif 842 void 843 gt_watchdog_service(void) 844 { 845 struct gt_softc *gt = gt_watchdog_sc; 846 847 if ((gt == NULL) || (gt_watchdog_state == 0)) 848 return; /* not enabled */ 849 #ifdef DEBUG 850 if (inhibit_watchdog_service) 851 return; 852 #endif 853 854 gt_write(gt, GT_WDOG_Config, 855 (GT_WDOG_Config_Ctl2a | GT_WDOG_Preset_DFLT)); 856 gt_write(gt, GT_WDOG_Config, 857 (GT_WDOG_Config_Ctl2b | GT_WDOG_Preset_DFLT)); 858 } 859 860 /* 861 * gt_watchdog_reset - force a watchdog reset using Preset_VAL=0 862 */ 863 void 864 gt_watchdog_reset() 865 { 866 struct gt_softc *gt = gt_watchdog_sc; 867 u_int32_t r; 868 869 (void)extintr_disable(); 870 r = gt_read(gt, GT_WDOG_Config); 871 gt_write(gt, GT_WDOG_Config, (GT_WDOG_Config_Ctl1a | 0)); 872 gt_write(gt, GT_WDOG_Config, (GT_WDOG_Config_Ctl1b | 0)); 873 if ((r & GT_WDOG_Config_Enb) != 0) { 874 /* 875 * was enabled, we just toggled it off, toggle on again 876 */ 877 gt_write(gt, GT_WDOG_Config, 878 (GT_WDOG_Config_Ctl1a | 0)); 879 gt_write(gt, GT_WDOG_Config, 880 (GT_WDOG_Config_Ctl1b | 0)); 881 } 882 for(;;); 883 } 884 885 static int 886 gt_devbus_intr(void *arg) 887 { 888 struct gt_softc *gt = (struct gt_softc *)arg; 889 u_int32_t cause; 890 u_int32_t addr; 891 892 cause = gt_read(gt, GT_DEVBUS_ICAUSE); 893 addr = gt_read(gt, GT_DEVBUS_ERR_ADDR); 894 gt_write(gt, GT_DEVBUS_ICAUSE, 0); /* clear irpt */ 895 896 if (cause & GT_DEVBUS_DBurstErr) { 897 printf("%s: Device Bus error: burst violation", 898 gt->gt_dev.dv_xname); 899 if ((cause & GT_DEVBUS_Sel) == 0) 900 printf(", addr %#x", addr); 901 printf("\n"); 902 } 903 if (cause & GT_DEVBUS_DRdyErr) { 904 printf("%s: Device Bus error: ready timer expired", 905 gt->gt_dev.dv_xname); 906 if ((cause & GT_DEVBUS_Sel) != 0) 907 printf(", addr %#x\n", addr); 908 printf("\n"); 909 } 910 911 return (cause != 0); 912 } 913 914 /* 915 * gt_ecc_intr_enb - enable GT-64260 ECC interrupts 916 */ 917 static void 918 gt_devbus_intr_enb(struct gt_softc *gt) 919 { 920 gt_write(gt, GT_DEVBUS_IMASK, 921 GT_DEVBUS_DBurstErr|GT_DEVBUS_DRdyErr); 922 (void)gt_read(gt, GT_DEVBUS_ERR_ADDR); /* clear addr */ 923 gt_write(gt, GT_ECC_Addr, 0); /* clear irpt */ 924 925 intr_establish(IRQ_DEV, IST_LEVEL, IPL_GTERR, gt_devbus_intr, gt); 926 printf("%s: Device Bus Error irpt at %d\n", 927 gt->gt_dev.dv_xname, IRQ_DEV); 928 } 929 930 931 int 932 gt_mii_read( 933 struct device *child, 934 struct device *parent, 935 int phy, 936 int reg) 937 { 938 struct gt_softc * const gt = (struct gt_softc *) parent; 939 uint32_t data; 940 int count = 10000; 941 942 do { 943 DELAY(10); 944 data = gt_read(gt, ETH_ESMIR); 945 } while ((data & ETH_ESMIR_Busy) && count-- > 0); 946 947 if (count == 0) { 948 printf("%s: mii read for phy %d reg %d busied out\n", 949 child->dv_xname, phy, reg); 950 return ETH_ESMIR_Value_GET(data); 951 } 952 953 gt_write(gt, ETH_ESMIR, ETH_ESMIR_READ(phy, reg)); 954 955 count = 10000; 956 do { 957 DELAY(10); 958 data = gt_read(gt, ETH_ESMIR); 959 } while ((data & ETH_ESMIR_ReadValid) == 0 && count-- > 0); 960 961 if (count == 0) 962 printf("%s: mii read for phy %d reg %d timed out\n", 963 child->dv_xname, phy, reg); 964 #if defined(GTMIIDEBUG) 965 printf("%s: mii_read(%d, %d): %#x data %#x\n", 966 child->dv_xname, phy, reg, 967 data, ETH_ESMIR_Value_GET(data)); 968 #endif 969 return ETH_ESMIR_Value_GET(data); 970 } 971 972 void 973 gt_mii_write ( 974 struct device *child, 975 struct device *parent, 976 int phy, int reg, 977 int value) 978 { 979 struct gt_softc * const gt = (struct gt_softc *) parent; 980 uint32_t data; 981 int count = 10000; 982 983 do { 984 DELAY(10); 985 data = gt_read(gt, ETH_ESMIR); 986 } while ((data & ETH_ESMIR_Busy) && count-- > 0); 987 988 if (count == 0) { 989 printf("%s: mii write for phy %d reg %d busied out (busy)\n", 990 child->dv_xname, phy, reg); 991 return; 992 } 993 994 gt_write(gt, ETH_ESMIR, 995 ETH_ESMIR_WRITE(phy, reg, value)); 996 997 count = 10000; 998 do { 999 DELAY(10); 1000 data = gt_read(gt, ETH_ESMIR); 1001 } while ((data & ETH_ESMIR_Busy) && count-- > 0); 1002 1003 if (count == 0) 1004 printf("%s: mii write for phy %d reg %d timed out\n", 1005 child->dv_xname, phy, reg); 1006 #if defined(GTMIIDEBUG) 1007 printf("%s: mii_write(%d, %d, %#x)\n", 1008 child->dv_xname, phy, reg, value); 1009 #endif 1010 } 1011 1012 /* 1013 * Since the memory and pci spaces are mapped 1:1 we just need 1014 * to return unity here 1015 */ 1016 bus_addr_t 1017 gt_dma_phys_to_bus_mem(bus_dma_tag_t t, bus_addr_t a) 1018 { 1019 return a; 1020 } 1021 bus_addr_t 1022 gt_dma_bus_mem_to_phys(bus_dma_tag_t t, bus_addr_t a) 1023 { 1024 return a; 1025 } 1026