bool si_iscoreup(si_t *sih) { if (CHIPTYPE(sih->socitype) == SOCI_SB) return sb_iscoreup(sih); else if (CHIPTYPE(sih->socitype) == SOCI_AI) return ai_iscoreup(sih); else { ASSERT(0); return FALSE; } }
/* * Setup the gige core. * Resetting the core will lose all settings. */ void sb_gige_init(sb_t *sbh, uint32 unit, bool *rgmii) { volatile pci_config_regs *pci; sbgige_pcishim_t *ocp; sbconfig_t *sb; osl_t *osh; uint32 statelow; uint32 statehigh; uint32 base; uint32 idx; void *regs; /* Sanity checks */ ASSERT(sbh); ASSERT(rgmii); idx = sb_coreidx(sbh); /* point to the gige core registers */ regs = sb_setcore(sbh, SB_GIGETH, unit); ASSERT(regs); osh = sb_osh(sbh); pci = &((sbgige_t *)regs)->pcicfg; ocp = &((sbgige_t *)regs)->pcishim; sb = &((sbgige_t *)regs)->sbconfig; /* Enable the core clock and memory access */ if (!sb_iscoreup(sbh)) sb_core_reset(sbh, 0, 0); /* * Setup the 64K memory-mapped region base address through BAR0. * Leave the other BAR values alone. */ base = sb_base(R_REG(osh, &sb->sbadmatch1)); W_REG(osh, &pci->base[0], base); W_REG(osh, &pci->base[1], 0); /* * Enable the PCI memory access anyway. Any PCI config commands * issued before the core is enabled will go to the emulation * only and will not go to the real PCI config registers. */ OR_REG(osh, &pci->command, 2); /* * Enable the posted write flush scheme as follows: * * - Enable flush on any core register read * - Enable timeout on the flush * - Disable the interrupt mask when flushing * * This differs from the default setting only in that interrupts are * not masked. Since posted writes are not flushed on interrupt, the * driver must explicitly request a flush in its interrupt handling * by reading a core register. */ W_REG(osh, &ocp->FlushStatusControl, 0x68); /* * Determine whether the GbE is in GMII or RGMII mode. This is * indicated in bit 16 of the SBTMStateHigh register, which is * part of the core-specific flags field. * * For GMII, bypass the Rx/Tx DLLs, i.e. add no delay to RXC/GTXC * within the core. For RGMII, do not bypass the DLLs, resulting * in added delay for RXC/GTXC. The SBTMStateLow register contains * the controls for doing this in the core-specific flags field: * * bit 24 - Enable DLL controls * bit 20 - Bypass Rx DLL * bit 19 - Bypass Tx DLL */ statelow = R_REG(osh, &sb->sbtmstatelow); /* DLL controls */ statehigh = R_REG(osh, &sb->sbtmstatehigh); /* GMII/RGMII mode */ if ((statehigh & (1 << 16)) != 0) /* RGMII */ { statelow &= ~(1 << 20); /* no Rx bypass (delay) */ statelow &= ~(1 << 19); /* no Tx bypass (delay) */ *rgmii = TRUE; } else /* GMII */ { statelow |= (1 << 20); /* Rx bypass (no delay) */ statelow |= (1 << 19); /* Tx bypass (no delay) */ *rgmii = FALSE; } statelow |= (1 << 24); /* enable DLL controls */ W_REG(osh, &sb->sbtmstatelow, statelow); sb_setcoreidx(sbh, idx); }
int pcibios_enable_device(struct pci_dev *dev, int mask) { ulong flags; uint coreidx; void *regs; /* External PCI device enable */ if (dev->bus->number != 0) return pcibios_enable_resources(dev); /* These cores come out of reset enabled */ if (dev->device == SB_MIPS || dev->device == SB_MIPS33 || dev->device == SB_EXTIF || dev->device == SB_CC) return 0; spin_lock_irqsave(&sbh_lock, flags); coreidx = sb_coreidx(sbh); regs = sb_setcoreidx(sbh, PCI_SLOT(dev->devfn)); if (!regs) return PCIBIOS_DEVICE_NOT_FOUND; /* * The USB core requires a special bit to be set during core * reset to enable host (OHCI) mode. Resetting the SB core in * pcibios_enable_device() is a hack for compatibility with * vanilla usb-ohci so that it does not have to know about * SB. A driver that wants to use the USB core in device mode * should know about SB and should reset the bit back to 0 * after calling pcibios_enable_device(). */ if (sb_coreid(sbh) == SB_USB) { sb_core_disable(sbh, sb_coreflags(sbh, 0, 0)); sb_core_reset(sbh, 1 << 29, 0); } /* * USB 2.0 special considerations: * * 1. Since the core supports both OHCI and EHCI functions, it must * only be reset once. * * 2. In addition to the standard SB reset sequence, the Host Control * Register must be programmed to bring the USB core and various * phy components out of reset. */ else if (sb_coreid(sbh) == SB_USB20H) { if (!sb_iscoreup(sbh)) { sb_core_reset(sbh, 0, 0); writel(0x7FF, (ulong)regs + 0x200); udelay(1); } } else sb_core_reset(sbh, 0, 0); sb_setcoreidx(sbh, coreidx); spin_unlock_irqrestore(&sbh_lock, flags); return 0; }