static void __init pcibios_fixup_resources(struct pci_dev *dev) { ulong flags; uint coreidx; if (dev->bus->number == 0) { /* * Chipcommon, RAM controller and PCI bridge must not be reset! */ if (dev->device == SB_MIPS || dev->device == SB_MIPS33 || dev->device == SB_EXTIF || dev->device == SB_MEMC || dev->device == SB_PCI || dev->device == SB_CC) return; spin_lock_irqsave(&sbh_lock, flags); coreidx = sb_coreidx(sbh); if (!sb_setcoreidx(sbh, PCI_SLOT(dev->devfn))) return; /* * The USB core requires a special bit to be set during core * reset to enable host (OHCI) mode. Resetting the SB core here * 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. */ if (sb_coreid(sbh) == SB_USB) { sb_core_disable(sbh, sb_coreflags(sbh, 0, 0)); sb_core_reset(sbh, 1 << 29); } else sb_core_reset(sbh, 0); sb_setcoreidx(sbh, coreidx); spin_unlock_irqrestore(&sbh_lock, flags); return; } if (dev->bus->number != 1 || PCI_SLOT(dev->devfn) != 0) return; printk("PCI: Fixing up bridge\n"); /* Enable PCI bridge bus mastering */ pci_set_master(dev); /* Enable PCI bridge BAR1 prefetch and burst */ pci_write_config_dword(dev, PCI_BAR1_CONTROL, 0x3); }
static uint _sb_scan(si_info_t *sii, u32 sba, void *regs, uint bus, u32 sbba, uint numcores) { uint next; uint ncc = 0; uint i; if (bus >= SB_MAXBUSES) { SI_ERROR(("_sb_scan: bus 0x%08x at level %d is too deep to " "scan\n", sbba, bus)); return 0; } SI_MSG(("_sb_scan: scan bus 0x%08x assume %u cores\n", sbba, numcores)); /* Scan all cores on the bus starting from core 0. * Core addresses must be contiguous on each bus. */ for (i = 0, next = sii->numcores; i < numcores && next < SB_BUS_MAXCORES; i++, next++) { sii->coresba[next] = sbba + (i * SI_CORE_SIZE); /* change core to 'next' and read its coreid */ sii->curmap = _sb_setcoreidx(sii, next); sii->curidx = next; sii->coreid[next] = sb_coreid(&sii->pub); /* core specific processing... */ /* chipc provides # cores */ if (sii->coreid[next] == CC_CORE_ID) { chipcregs_t *cc = (chipcregs_t *) sii->curmap; u32 ccrev = sb_corerev(&sii->pub); /* determine numcores - this is the total # cores in the chip */ if (((ccrev == 4) || (ccrev >= 6))) numcores = (R_REG(sii->osh, &cc->chipid) & CID_CC_MASK) >> CID_CC_SHIFT; else { /* Older chips */ SI_ERROR(("sb_chip2numcores: unsupported chip " "0x%x\n", sii->pub.chip)); ASSERT(0); numcores = 1; } SI_VMSG(("_sb_scan: %u cores in the chip %s\n", numcores, sii->pub.issim ? "QT" : "")); }
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; }