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