File indexing completed on 2025-05-11 08:23:52
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 #include <sys/cdefs.h>
0045 __KERNEL_RCSID(0, "$NetBSD: gt.c,v 1.5 2003/07/14 15:47:16 lukem Exp $");
0046
0047 #include "opt_marvell.h"
0048
0049 #include <sys/param.h>
0050 #include <sys/types.h>
0051 #include <sys/cdefs.h>
0052 #include <sys/extent.h>
0053 #include <sys/device.h>
0054 #include <sys/kernel.h>
0055 #include <sys/malloc.h>
0056
0057 #define _BUS_SPACE_PRIVATE
0058 #define _BUS_DMA_PRIVATE
0059 #include <machine/bus.h>
0060
0061 #include <powerpc/spr.h>
0062 #include <powerpc/oea/hid.h>
0063
0064 #include <dev/marvell/gtreg.h>
0065 #include <dev/marvell/gtintrreg.h>
0066 #include <dev/marvell/gtvar.h>
0067 #include <dev/marvell/gtethreg.h>
0068
0069 #ifdef DEBUG
0070 #include <sys/systm.h> /* for Debugger() */
0071 #endif
0072
0073 #if ((GT_MPP_WATCHDOG & 0xf0f0f0f0) != 0)
0074 # error
0075 #endif
0076 #if ((GT_MPP_WATCHDOG & GT_MPP_INTERRUPTS) != 0)
0077 # error
0078 #endif
0079
0080 static void gt_comm_intr_enb(struct gt_softc *);
0081 static void gt_devbus_intr_enb(struct gt_softc *);
0082 #ifdef GT_ECC
0083 static void gt_ecc_intr_enb(struct gt_softc *);
0084 #endif
0085
0086 void gt_init_hostid (struct gt_softc *);
0087 void gt_init_interrupt (struct gt_softc *);
0088 static int gt_comm_intr (void *);
0089
0090 void gt_watchdog_init(struct gt_softc *);
0091 void gt_watchdog_enable(void);
0092 void gt_watchdog_disable(void);
0093 void gt_watchdog_reset(void);
0094
0095 extern struct cfdriver gt_cd;
0096
0097 static int gtfound = 0;
0098
0099 static struct gt_softc *gt_watchdog_sc = 0;
0100 static int gt_watchdog_state = 0;
0101
0102 int
0103 gt_cfprint (void *aux, const char *pnp)
0104 {
0105 struct gt_attach_args *ga = aux;
0106
0107 if (pnp) {
0108 aprint_normal("%s at %s", ga->ga_name, pnp);
0109 }
0110
0111 aprint_normal(" unit %d", ga->ga_unit);
0112 return (UNCONF);
0113 }
0114
0115
0116 static int
0117 gt_cfsearch(struct device *parent, struct cfdata *cf, void *aux)
0118 {
0119 struct gt_softc *gt = (struct gt_softc *) parent;
0120 struct gt_attach_args ga;
0121
0122 ga.ga_name = cf->cf_name;
0123 ga.ga_dmat = gt->gt_dmat;
0124 ga.ga_memt = gt->gt_memt;
0125 ga.ga_memh = gt->gt_memh;
0126 ga.ga_unit = cf->cf_loc[GTCF_UNIT];
0127
0128 if (config_match(parent, cf, &ga) > 0)
0129 config_attach(parent, cf, &ga, gt_cfprint);
0130
0131 return (0);
0132 }
0133
0134 void
0135 gt_attach_common(struct gt_softc *gt)
0136 {
0137 uint32_t cpucfg, cpumode, cpumstr;
0138 #ifdef DEBUG
0139 uint32_t loaddr, hiaddr;
0140 #endif
0141
0142 gtfound = 1;
0143
0144 cpumode = gt_read(gt, GT_CPU_Mode);
0145 aprint_normal(": id %d", GT_CPUMode_MultiGTID_GET(cpumode));
0146 if (cpumode & GT_CPUMode_MultiGT)
0147 aprint_normal (" (multi)");
0148 switch (GT_CPUMode_CPUType_GET(cpumode)) {
0149 case 4: aprint_normal(", 60x bus"); break;
0150 case 5: aprint_normal(", MPX bus"); break;
0151 default: aprint_normal(", %#x(?) bus", GT_CPUMode_CPUType_GET(cpumode)); break;
0152 }
0153
0154 cpumstr = gt_read(gt, GT_CPU_Master_Ctl);
0155 cpumstr &= ~(GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock);
0156 #if 0
0157 cpumstr |= GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock;
0158 #endif
0159 gt_write(gt, GT_CPU_Master_Ctl, cpumstr);
0160
0161 switch (cpumstr & (GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock)) {
0162 case 0: break;
0163 case GT_CPUMstrCtl_CleanBlock: aprint_normal(", snoop=clean"); break;
0164 case GT_CPUMstrCtl_FlushBlock: aprint_normal(", snoop=flush"); break;
0165 case GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock:
0166 aprint_normal(", snoop=clean&flush"); break;
0167 }
0168 aprint_normal(" wdog=%#x,%#x\n",
0169 gt_read(gt, GT_WDOG_Config),
0170 gt_read(gt, GT_WDOG_Value));
0171
0172 #if DEBUG
0173 loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS0_Low_Decode));
0174 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS0_High_Decode));
0175 aprint_normal("%s: scs[0]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
0176
0177 loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS1_Low_Decode));
0178 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS1_High_Decode));
0179 aprint_normal("%s: scs[1]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
0180
0181 loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS2_Low_Decode));
0182 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS2_High_Decode));
0183 aprint_normal("%s: scs[2]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
0184
0185 loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS3_Low_Decode));
0186 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS3_High_Decode));
0187 aprint_normal("%s: scs[3]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
0188
0189 loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS0_Low_Decode));
0190 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS0_High_Decode));
0191 aprint_normal("%s: cs[0]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
0192
0193 loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS1_Low_Decode));
0194 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS1_High_Decode));
0195 aprint_normal("%s: cs[1]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
0196
0197 loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS2_Low_Decode));
0198 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS2_High_Decode));
0199 aprint_normal("%s: cs[2]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
0200
0201 loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS3_Low_Decode));
0202 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS3_High_Decode));
0203 aprint_normal("%s: cs[3]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
0204
0205 loaddr = GT_LowAddr_GET(gt_read(gt, GT_BootCS_Low_Decode));
0206 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_BootCS_High_Decode));
0207 aprint_normal("%s: bootcs=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
0208
0209 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_IO_Low_Decode));
0210 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_IO_High_Decode));
0211 aprint_normal("%s: pci0io=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
0212
0213 loaddr = gt_read(gt, GT_PCI0_IO_Remap);
0214 aprint_normal("remap=%#010x\n", loaddr);
0215
0216 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem0_Low_Decode));
0217 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem0_High_Decode));
0218 aprint_normal("%s: pci0mem[0]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
0219
0220 loaddr = gt_read(gt, GT_PCI0_Mem0_Remap_Low);
0221 hiaddr = gt_read(gt, GT_PCI0_Mem0_Remap_High);
0222 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
0223
0224 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem1_Low_Decode));
0225 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem1_High_Decode));
0226 aprint_normal("%s: pci0mem[1]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
0227
0228 loaddr = gt_read(gt, GT_PCI0_Mem1_Remap_Low);
0229 hiaddr = gt_read(gt, GT_PCI0_Mem1_Remap_High);
0230 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
0231
0232 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem2_Low_Decode));
0233 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem2_High_Decode));
0234 aprint_normal("%s: pci0mem[2]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
0235
0236 loaddr = gt_read(gt, GT_PCI0_Mem2_Remap_Low);
0237 hiaddr = gt_read(gt, GT_PCI0_Mem2_Remap_High);
0238 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
0239
0240 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem3_Low_Decode));
0241 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem3_High_Decode));
0242 aprint_normal("%s: pci0mem[3]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
0243
0244 loaddr = gt_read(gt, GT_PCI0_Mem3_Remap_Low);
0245 hiaddr = gt_read(gt, GT_PCI0_Mem3_Remap_High);
0246 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
0247
0248 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_IO_Low_Decode));
0249 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_IO_High_Decode));
0250 aprint_normal("%s: pci1io=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
0251
0252 loaddr = gt_read(gt, GT_PCI1_IO_Remap);
0253 aprint_normal("remap=%#010x\n", loaddr);
0254
0255 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem0_Low_Decode));
0256 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem0_High_Decode));
0257 aprint_normal("%s: pci1mem[0]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
0258
0259 loaddr = gt_read(gt, GT_PCI1_Mem0_Remap_Low);
0260 hiaddr = gt_read(gt, GT_PCI1_Mem0_Remap_High);
0261 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
0262
0263 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem1_Low_Decode));
0264 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem1_High_Decode));
0265 aprint_normal("%s: pci1mem[1]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
0266
0267 loaddr = gt_read(gt, GT_PCI1_Mem1_Remap_Low);
0268 hiaddr = gt_read(gt, GT_PCI1_Mem1_Remap_High);
0269 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
0270
0271 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem2_Low_Decode));
0272 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem2_High_Decode));
0273 aprint_normal("%s: pci1mem[2]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
0274
0275 loaddr = gt_read(gt, GT_PCI1_Mem2_Remap_Low);
0276 hiaddr = gt_read(gt, GT_PCI1_Mem2_Remap_High);
0277 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
0278
0279 loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem3_Low_Decode));
0280 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem3_High_Decode));
0281 aprint_normal("%s: pci1mem[3]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
0282
0283 loaddr = gt_read(gt, GT_PCI1_Mem3_Remap_Low);
0284 hiaddr = gt_read(gt, GT_PCI1_Mem3_Remap_High);
0285 aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
0286
0287 loaddr = GT_LowAddr_GET(gt_read(gt, GT_Internal_Decode));
0288 aprint_normal("%s: internal=%#10x-%#10x\n", gt->gt_dev.dv_xname,
0289 loaddr, loaddr+256*1024);
0290
0291 loaddr = GT_LowAddr_GET(gt_read(gt, GT_CPU0_Low_Decode));
0292 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CPU0_High_Decode));
0293 aprint_normal("%s: cpu0=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
0294
0295 loaddr = GT_LowAddr_GET(gt_read(gt, GT_CPU1_Low_Decode));
0296 hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CPU1_High_Decode));
0297 aprint_normal("%s: cpu1=%#10x-%#10x", gt->gt_dev.dv_xname, loaddr, hiaddr);
0298 #endif
0299
0300 aprint_normal("%s:", gt->gt_dev.dv_xname);
0301
0302 cpucfg = gt_read(gt, GT_CPU_Cfg);
0303 cpucfg |= GT_CPUCfg_ConfSBDis;
0304 cpucfg |= GT_CPUCfg_AACKDelay;
0305 gt_write(gt, GT_CPU_Cfg, cpucfg);
0306 if (cpucfg & GT_CPUCfg_Pipeline)
0307 aprint_normal(" pipeline");
0308 if (cpucfg & GT_CPUCfg_AACKDelay)
0309 aprint_normal(" aack-delay");
0310 if (cpucfg & GT_CPUCfg_RdOOO)
0311 aprint_normal(" read-ooo");
0312 if (cpucfg & GT_CPUCfg_IOSBDis)
0313 aprint_normal(" io-sb-dis");
0314 if (cpucfg & GT_CPUCfg_ConfSBDis)
0315 aprint_normal(" conf-sb-dis");
0316 if (cpucfg & GT_CPUCfg_ClkSync)
0317 aprint_normal(" clk-sync");
0318 aprint_normal("\n");
0319
0320 gt_init_hostid(gt);
0321
0322 gt_watchdog_init(gt);
0323
0324 gt_init_interrupt(gt);
0325
0326 #ifdef GT_ECC
0327 gt_ecc_intr_enb(gt);
0328 #endif
0329
0330 gt_comm_intr_enb(gt);
0331 gt_devbus_intr_enb(gt);
0332
0333 gt_watchdog_disable();
0334 config_search(gt_cfsearch, >->gt_dev, NULL);
0335 gt_watchdog_service();
0336 gt_watchdog_enable();
0337 }
0338
0339 void
0340 gt_init_hostid(struct gt_softc *gt)
0341 {
0342
0343 hostid = 1;
0344 }
0345
0346 void
0347 gt_init_interrupt(struct gt_softc *gt)
0348 {
0349 u_int32_t mppirpts = GT_MPP_INTERRUPTS;
0350 u_int32_t r;
0351 u_int32_t mppbit;
0352 u_int32_t mask;
0353 u_int32_t mppsel;
0354 u_int32_t regoff;
0355
0356 gt_write(gt, ICR_CIM_LO, 0);
0357 gt_write(gt, ICR_CIM_HI, 0);
0358
0359
0360
0361
0362
0363
0364 #ifdef DEBUG
0365 printf("%s: mpp cfg ", gt->gt_dev.dv_xname);
0366 for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4)
0367 printf("%#x ", gt_read(gt, regoff));
0368 printf(", mppirpts 0x%x\n", mppirpts);
0369 #endif
0370 mppbit = 0x1;
0371 for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4) {
0372 mask = 0;
0373 for (mppsel = 0xf; mppsel; mppsel <<= 4) {
0374 if (mppirpts & mppbit)
0375 mask |= mppsel;
0376 mppbit <<= 1;
0377 }
0378 if (mask) {
0379 r = gt_read(gt, regoff);
0380 r &= ~mask;
0381 gt_write(gt, regoff, r);
0382 }
0383 }
0384
0385 r = gt_read(gt, GT_GPP_IO_Control);
0386 r &= ~mppirpts;
0387 gt_write(gt, GT_GPP_IO_Control, r);
0388
0389 r = gt_read(gt, GT_GPP_Level_Control);
0390 r |= mppirpts;
0391 gt_write(gt, GT_GPP_Level_Control, r);
0392
0393 r = gt_read(gt, GT_GPP_Interrupt_Mask);
0394 r |= mppirpts;
0395 gt_write(gt, GT_GPP_Interrupt_Mask, r);
0396 }
0397
0398 uint32_t
0399 gt_read_mpp (void)
0400 {
0401 return gt_read((struct gt_softc *)gt_cd.cd_devs[0], GT_GPP_Value);
0402 }
0403
0404 #if 0
0405 int
0406 gt_bs_extent_init(struct discovery_bus_space *bs, char *name)
0407 {
0408 u_long start, end;
0409 int i, j, error;
0410
0411 if (bs->bs_nregion == 0) {
0412 bs->bs_extent = extent_create(name, 0xffffffffUL, 0xffffffffUL,
0413 M_DEVBUF, NULL, 0, EX_NOCOALESCE|EX_WAITOK);
0414 KASSERT(bs->bs_extent != NULL);
0415 return 0;
0416 }
0417
0418
0419
0420 start = bs->bs_regions[0].br_start;
0421 end = bs->bs_regions[0].br_end;
0422 #ifdef DEBUG
0423 if (gtpci_debug > 1)
0424 printf("gtpci_bs_extent_init: %s: region %d: %#lx-%#lx\n",
0425 name, 0, bs->bs_regions[0].br_start,
0426 bs->bs_regions[0].br_end);
0427 #endif
0428 for (i = 1; i < bs->bs_nregion; i++) {
0429 if (bs->bs_regions[i].br_start < start)
0430 start = bs->bs_regions[i].br_start;
0431 if (bs->bs_regions[i].br_end > end)
0432 end = bs->bs_regions[i].br_end;
0433 #ifdef DEBUG
0434 if (gtpci_debug > 1)
0435 printf("gtpci_bs_extent_init: %s: region %d:"
0436 " %#lx-%#lx\n",
0437 name, i, bs->bs_regions[i].br_start,
0438 bs->bs_regions[i].br_end);
0439 #endif
0440 }
0441
0442
0443
0444
0445
0446 #ifdef DEBUG
0447 if (gtpci_debug > 1)
0448 printf("gtpci_bs_extent_init: %s: create: %#lx-%#lx\n",
0449 name, start, end);
0450 #endif
0451 bs->bs_extent = extent_create(name, start, end, M_DEVBUF,
0452 NULL, 0, EX_NOCOALESCE|EX_WAITOK);
0453 KASSERT(bs->bs_extent != NULL);
0454
0455
0456
0457
0458
0459 for (i = 0; i < bs->bs_nregion && bs->bs_nregion > 1; i++) {
0460
0461
0462
0463 start = ~0UL;
0464 end = bs->bs_regions[i].br_end;
0465
0466
0467
0468
0469 for (j = 0; j < bs->bs_nregion && start > end + 1; j++) {
0470 if (i == j)
0471 continue;
0472 if (bs->bs_regions[j].br_start > end &&
0473 bs->bs_regions[j].br_start < start)
0474 start = bs->bs_regions[j].br_start;
0475 }
0476
0477
0478
0479 if (start != ~0UL && start != end + 1) {
0480 #ifdef DEBUG
0481 if (gtpci_debug > 1)
0482 printf("gtpci_bs_extent_init: %s: alloc(hole): %#lx-%#lx\n",
0483 name, end + 1, start - 1);
0484 #endif
0485 error = extent_alloc_region(bs->bs_extent, end + 1,
0486 start - (end + 1), EX_NOWAIT);
0487 KASSERT(error == 0);
0488 }
0489 }
0490 return 1;
0491 }
0492 #endif
0493
0494
0495
0496
0497 # define GT_CommUnitIntr_DFLT GT_CommUnitIntr_S0|GT_CommUnitIntr_S1 \
0498 |GT_CommUnitIntr_E0|GT_CommUnitIntr_E1 \
0499 |GT_CommUnitIntr_E2
0500
0501 static const char * const gt_comm_subunit_name[8] = {
0502 "ethernet 0",
0503 "ethernet 1",
0504 "ethernet 2",
0505 "(reserved)",
0506 "MPSC 0",
0507 "MPSC 1",
0508 "(reserved)",
0509 "(sel)",
0510 };
0511
0512 static int
0513 gt_comm_intr(void *arg)
0514 {
0515 struct gt_softc *gt = (struct gt_softc *)arg;
0516 u_int32_t cause;
0517 u_int32_t addr;
0518 unsigned int mask;
0519 int i;
0520
0521 cause = gt_read(gt, GT_CommUnitIntr_Cause);
0522 gt_write(gt, GT_CommUnitIntr_Cause, ~cause);
0523 addr = gt_read(gt, GT_CommUnitIntr_ErrAddr);
0524
0525 printf("%s: Comm Unit irpt, cause %#x addr %#x\n",
0526 gt->gt_dev.dv_xname, cause, addr);
0527
0528 cause &= GT_CommUnitIntr_DFLT;
0529 if (cause == 0)
0530 return 0;
0531
0532 mask = 0x7;
0533 for (i=0; i<7; i++) {
0534 if (cause & mask) {
0535 printf("%s: Comm Unit %s:", gt->gt_dev.dv_xname,
0536 gt_comm_subunit_name[i]);
0537 if (cause & 1)
0538 printf(" AddrMiss");
0539 if (cause & 2)
0540 printf(" AccProt");
0541 if (cause & 4)
0542 printf(" WrProt");
0543 printf("\n");
0544 }
0545 cause >>= 4;
0546 }
0547 return 1;
0548 }
0549
0550
0551
0552
0553 static void
0554 gt_comm_intr_enb(struct gt_softc *gt)
0555 {
0556 u_int32_t cause;
0557
0558 cause = gt_read(gt, GT_CommUnitIntr_Cause);
0559 if (cause)
0560 gt_write(gt, GT_CommUnitIntr_Cause, ~cause);
0561 gt_write(gt, GT_CommUnitIntr_Mask, GT_CommUnitIntr_DFLT);
0562 (void)gt_read(gt, GT_CommUnitIntr_ErrAddr);
0563
0564 intr_establish(IRQ_COMM, IST_LEVEL, IPL_GTERR, gt_comm_intr, gt);
0565 printf("%s: Comm Unit irpt at %d\n", gt->gt_dev.dv_xname, IRQ_COMM);
0566 }
0567
0568 #ifdef GT_ECC
0569 static char *gt_ecc_intr_str[4] = {
0570 "(none)",
0571 "single bit",
0572 "double bit",
0573 "(reserved)"
0574 };
0575
0576 static int
0577 gt_ecc_intr(void *arg)
0578 {
0579 struct gt_softc *gt = (struct gt_softc *)arg;
0580 u_int32_t addr;
0581 u_int32_t dlo;
0582 u_int32_t dhi;
0583 u_int32_t rec;
0584 u_int32_t calc;
0585 u_int32_t count;
0586 int err;
0587
0588 count = gt_read(gt, GT_ECC_Count);
0589 dlo = gt_read(gt, GT_ECC_Data_Lo);
0590 dhi = gt_read(gt, GT_ECC_Data_Hi);
0591 rec = gt_read(gt, GT_ECC_Rec);
0592 calc = gt_read(gt, GT_ECC_Calc);
0593 addr = gt_read(gt, GT_ECC_Addr);
0594 gt_write(gt, GT_ECC_Addr, 0);
0595
0596 err = addr & 0x3;
0597
0598 printf("%s: ECC error: %s: "
0599 "addr %#x data %#x.%#x rec %#x calc %#x cnt %#x\n",
0600 gt->gt_dev.dv_xname, gt_ecc_intr_str[err],
0601 addr, dhi, dlo, rec, calc, count);
0602
0603 if (err == 2)
0604 panic("ecc");
0605
0606 return (err == 1);
0607 }
0608
0609
0610
0611
0612 static void
0613 gt_ecc_intr_enb(struct gt_softc *gt)
0614 {
0615 u_int32_t ctl;
0616
0617 ctl = gt_read(gt, GT_ECC_Ctl);
0618 ctl |= 1 << 16;
0619 gt_write(gt, GT_ECC_Ctl, ctl);
0620 (void)gt_read(gt, GT_ECC_Data_Lo);
0621 (void)gt_read(gt, GT_ECC_Data_Hi);
0622 (void)gt_read(gt, GT_ECC_Rec);
0623 (void)gt_read(gt, GT_ECC_Calc);
0624 (void)gt_read(gt, GT_ECC_Addr);
0625 gt_write(gt, GT_ECC_Addr, 0);
0626
0627 intr_establish(IRQ_ECC, IST_LEVEL, IPL_GTERR, gt_ecc_intr, gt);
0628 printf("%s: ECC irpt at %d\n", gt->gt_dev.dv_xname, IRQ_ECC);
0629 }
0630 #endif
0631
0632
0633 #ifndef GT_MPP_WATCHDOG
0634 void
0635 gt_watchdog_init(struct gt_softc *gt)
0636 {
0637 u_int32_t r;
0638 unsigned int omsr;
0639
0640 omsr = extintr_disable();
0641
0642 printf("%s: watchdog", gt->gt_dev.dv_xname);
0643
0644
0645
0646
0647 r = gt_read(gt, GT_WDOG_Config);
0648 printf(" status %#x,%#x:",
0649 r, gt_read(gt, GT_WDOG_Value));
0650 if ((r & 0x80000000) != 0) {
0651 gt_watchdog_sc = gt;
0652 gt_watchdog_state = 1;
0653 printf(" firmware-enabled\n");
0654 gt_watchdog_service();
0655 return;
0656 } else {
0657 printf(" firmware-disabled\n");
0658 }
0659
0660 extintr_restore(omsr);
0661 }
0662
0663 #else
0664
0665 void
0666 gt_watchdog_init(struct gt_softc *gt)
0667 {
0668 u_int32_t mpp_watchdog = GT_MPP_WATCHDOG;
0669 u_int32_t r;
0670 u_int32_t cfgbits;
0671 u_int32_t mppbits;
0672 u_int32_t mppmask=0;
0673 u_int32_t regoff;
0674 unsigned int omsr;
0675
0676 printf("%s: watchdog", gt->gt_dev.dv_xname);
0677
0678 if (mpp_watchdog == 0) {
0679 printf(" not configured\n");
0680 return;
0681 }
0682
0683 #if 0
0684 if (afw_wdog_ctl == 1) {
0685 printf(" admin disabled\n");
0686 return;
0687 }
0688 #endif
0689
0690 omsr = extintr_disable();
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700 r = gt_read(gt, GT_WDOG_Config);
0701 if (r != ~0) {
0702 if ((r & GT_WDOG_Config_Enb) != 0) {
0703 gt_write(gt, GT_WDOG_Config,
0704 (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
0705 gt_write(gt, GT_WDOG_Config,
0706 (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
0707 }
0708 } else {
0709 #if 0
0710 if (afw_wdog_state == 1) {
0711 gt_write(gt, GT_WDOG_Config,
0712 (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
0713 gt_write(gt, GT_WDOG_Config,
0714 (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
0715 }
0716 #endif
0717 }
0718
0719
0720
0721
0722
0723 mppbits = 0;
0724 cfgbits = 0x3;
0725 for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4) {
0726 if ((mpp_watchdog & cfgbits) == cfgbits) {
0727 mppbits = 0x99;
0728 mppmask = 0xff;
0729 break;
0730 }
0731 cfgbits <<= 2;
0732 if ((mpp_watchdog & cfgbits) == cfgbits) {
0733 mppbits = 0x9900;
0734 mppmask = 0xff00;
0735 break;
0736 }
0737 cfgbits <<= 6;
0738 }
0739 if (mppbits == 0) {
0740 printf(" config error\n");
0741 extintr_restore(omsr);
0742 return;
0743 }
0744
0745 r = gt_read(gt, regoff);
0746 r &= ~mppmask;
0747 r |= mppbits;
0748 gt_write(gt, regoff, r);
0749 printf(" mpp %#x %#x", regoff, mppbits);
0750
0751 gt_write(gt, GT_WDOG_Value, GT_WDOG_NMI_DFLT);
0752
0753 gt_write(gt, GT_WDOG_Config,
0754 (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
0755 gt_write(gt, GT_WDOG_Config,
0756 (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
0757
0758
0759 r = gt_read(gt, GT_WDOG_Config),
0760 printf(" status %#x,%#x: %s",
0761 r, gt_read(gt, GT_WDOG_Value),
0762 ((r & GT_WDOG_Config_Enb) != 0) ? "enabled" : "botch");
0763
0764 if ((r & GT_WDOG_Config_Enb) != 0) {
0765 register_t hid0;
0766
0767 gt_watchdog_sc = gt;
0768 gt_watchdog_state = 1;
0769
0770
0771
0772
0773 __asm __volatile("sync":::"memory");
0774 hid0 = mfspr(SPR_HID0);
0775 if ((hid0 & HID0_EMCP) == 0) {
0776 hid0 |= HID0_EMCP;
0777 __asm __volatile("sync":::"memory"); mtspr(SPR_HID0, hid0);
0778 __asm __volatile("sync":::"memory"); hid0 = mfspr(SPR_HID0);
0779 printf(", EMCP set");
0780 }
0781 }
0782 printf("\n");
0783
0784 extintr_restore(omsr);
0785 }
0786 #endif
0787
0788 #ifdef DEBUG
0789 u_int32_t hid0_print(void);
0790 u_int32_t
0791 hid0_print()
0792 {
0793 u_int32_t hid0;
0794 __asm __volatile("sync; mfspr %0,1008;" : "=r"(hid0)::"memory");
0795 printf("hid0: %#x\n", hid0);
0796 return hid0;
0797 }
0798 #endif
0799
0800 void
0801 gt_watchdog_enable(void)
0802 {
0803 struct gt_softc *gt;
0804 unsigned int omsr;
0805
0806 omsr = extintr_disable();
0807 gt = gt_watchdog_sc;
0808 if ((gt != NULL) && (gt_watchdog_state == 0)) {
0809 gt_watchdog_state = 1;
0810
0811 gt_write(gt, GT_WDOG_Config,
0812 (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
0813 gt_write(gt, GT_WDOG_Config,
0814 (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
0815 }
0816 extintr_restore(omsr);
0817 }
0818
0819 void
0820 gt_watchdog_disable(void)
0821 {
0822 struct gt_softc *gt;
0823 unsigned int omsr;
0824
0825 omsr = extintr_disable();
0826 gt = gt_watchdog_sc;
0827 if ((gt != NULL) && (gt_watchdog_state != 0)) {
0828 gt_watchdog_state = 0;
0829
0830 gt_write(gt, GT_WDOG_Config,
0831 (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
0832 gt_write(gt, GT_WDOG_Config,
0833 (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
0834 }
0835 extintr_restore(omsr);
0836 }
0837
0838 #ifdef DEBUG
0839 int inhibit_watchdog_service = 0;
0840 #endif
0841 void
0842 gt_watchdog_service(void)
0843 {
0844 struct gt_softc *gt = gt_watchdog_sc;
0845
0846 if ((gt == NULL) || (gt_watchdog_state == 0))
0847 return;
0848 #ifdef DEBUG
0849 if (inhibit_watchdog_service)
0850 return;
0851 #endif
0852
0853 gt_write(gt, GT_WDOG_Config,
0854 (GT_WDOG_Config_Ctl2a | GT_WDOG_Preset_DFLT));
0855 gt_write(gt, GT_WDOG_Config,
0856 (GT_WDOG_Config_Ctl2b | GT_WDOG_Preset_DFLT));
0857 }
0858
0859
0860
0861
0862 void
0863 gt_watchdog_reset()
0864 {
0865 struct gt_softc *gt = gt_watchdog_sc;
0866 u_int32_t r;
0867
0868 (void)extintr_disable();
0869 r = gt_read(gt, GT_WDOG_Config);
0870 gt_write(gt, GT_WDOG_Config, (GT_WDOG_Config_Ctl1a | 0));
0871 gt_write(gt, GT_WDOG_Config, (GT_WDOG_Config_Ctl1b | 0));
0872 if ((r & GT_WDOG_Config_Enb) != 0) {
0873
0874
0875
0876 gt_write(gt, GT_WDOG_Config,
0877 (GT_WDOG_Config_Ctl1a | 0));
0878 gt_write(gt, GT_WDOG_Config,
0879 (GT_WDOG_Config_Ctl1b | 0));
0880 }
0881 for(;;);
0882 }
0883
0884 static int
0885 gt_devbus_intr(void *arg)
0886 {
0887 struct gt_softc *gt = (struct gt_softc *)arg;
0888 u_int32_t cause;
0889 u_int32_t addr;
0890
0891 cause = gt_read(gt, GT_DEVBUS_ICAUSE);
0892 addr = gt_read(gt, GT_DEVBUS_ERR_ADDR);
0893 gt_write(gt, GT_DEVBUS_ICAUSE, 0);
0894
0895 if (cause & GT_DEVBUS_DBurstErr) {
0896 printf("%s: Device Bus error: burst violation",
0897 gt->gt_dev.dv_xname);
0898 if ((cause & GT_DEVBUS_Sel) == 0)
0899 printf(", addr %#x", addr);
0900 printf("\n");
0901 }
0902 if (cause & GT_DEVBUS_DRdyErr) {
0903 printf("%s: Device Bus error: ready timer expired",
0904 gt->gt_dev.dv_xname);
0905 if ((cause & GT_DEVBUS_Sel) != 0)
0906 printf(", addr %#x\n", addr);
0907 printf("\n");
0908 }
0909
0910 return (cause != 0);
0911 }
0912
0913
0914
0915
0916 static void
0917 gt_devbus_intr_enb(struct gt_softc *gt)
0918 {
0919 gt_write(gt, GT_DEVBUS_IMASK,
0920 GT_DEVBUS_DBurstErr|GT_DEVBUS_DRdyErr);
0921 (void)gt_read(gt, GT_DEVBUS_ERR_ADDR);
0922 gt_write(gt, GT_ECC_Addr, 0);
0923
0924 intr_establish(IRQ_DEV, IST_LEVEL, IPL_GTERR, gt_devbus_intr, gt);
0925 printf("%s: Device Bus Error irpt at %d\n",
0926 gt->gt_dev.dv_xname, IRQ_DEV);
0927 }
0928
0929
0930 int
0931 gt_mii_read(
0932 struct device *child,
0933 struct device *parent,
0934 int phy,
0935 int reg)
0936 {
0937 struct gt_softc * const gt = (struct gt_softc *) parent;
0938 uint32_t data;
0939 int count = 10000;
0940
0941 do {
0942 DELAY(10);
0943 data = gt_read(gt, ETH_ESMIR);
0944 } while ((data & ETH_ESMIR_Busy) && count-- > 0);
0945
0946 if (count == 0) {
0947 printf("%s: mii read for phy %d reg %d busied out\n",
0948 child->dv_xname, phy, reg);
0949 return ETH_ESMIR_Value_GET(data);
0950 }
0951
0952 gt_write(gt, ETH_ESMIR, ETH_ESMIR_READ(phy, reg));
0953
0954 count = 10000;
0955 do {
0956 DELAY(10);
0957 data = gt_read(gt, ETH_ESMIR);
0958 } while ((data & ETH_ESMIR_ReadValid) == 0 && count-- > 0);
0959
0960 if (count == 0)
0961 printf("%s: mii read for phy %d reg %d timed out\n",
0962 child->dv_xname, phy, reg);
0963 #if defined(GTMIIDEBUG)
0964 printf("%s: mii_read(%d, %d): %#x data %#x\n",
0965 child->dv_xname, phy, reg,
0966 data, ETH_ESMIR_Value_GET(data));
0967 #endif
0968 return ETH_ESMIR_Value_GET(data);
0969 }
0970
0971 void
0972 gt_mii_write (
0973 struct device *child,
0974 struct device *parent,
0975 int phy, int reg,
0976 int value)
0977 {
0978 struct gt_softc * const gt = (struct gt_softc *) parent;
0979 uint32_t data;
0980 int count = 10000;
0981
0982 do {
0983 DELAY(10);
0984 data = gt_read(gt, ETH_ESMIR);
0985 } while ((data & ETH_ESMIR_Busy) && count-- > 0);
0986
0987 if (count == 0) {
0988 printf("%s: mii write for phy %d reg %d busied out (busy)\n",
0989 child->dv_xname, phy, reg);
0990 return;
0991 }
0992
0993 gt_write(gt, ETH_ESMIR,
0994 ETH_ESMIR_WRITE(phy, reg, value));
0995
0996 count = 10000;
0997 do {
0998 DELAY(10);
0999 data = gt_read(gt, ETH_ESMIR);
1000 } while ((data & ETH_ESMIR_Busy) && count-- > 0);
1001
1002 if (count == 0)
1003 printf("%s: mii write for phy %d reg %d timed out\n",
1004 child->dv_xname, phy, reg);
1005 #if defined(GTMIIDEBUG)
1006 printf("%s: mii_write(%d, %d, %#x)\n",
1007 child->dv_xname, phy, reg, value);
1008 #endif
1009 }
1010