/* XXX Could be per-controller, but I don't think we risk anything by
* assuming we won't have both UniNorth and Bandit */ staticint has_uninorth; #ifdef CONFIG_PPC64 staticstruct pci_controller *u3_agp; #else staticint has_second_ohare; #endif/* CONFIG_PPC64 */
staticint __init fixup_one_level_bus_range(struct device_node *node, int higher)
{ for (; node; node = node->sibling) { constint * bus_range; constunsignedint *class_code; int len;
/* For PCI<->PCI bridges or CardBus bridges, we go down */
class_code = of_get_property(node, "class-code", NULL); if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) continue;
bus_range = of_get_property(node, "bus-range", &len); if (bus_range != NULL && len > 2 * sizeof(int)) { if (bus_range[1] > higher)
higher = bus_range[1];
}
higher = fixup_one_level_bus_range(node->child, higher);
} return higher;
}
/* This routine fixes the "bus-range" property of all bridges in the *systemsincetheytendtohavetheir"last"memberwrongonmacs * *NotethatthebusnumbersmanipulatedhereareOFbusnumbers,they *arenotLinuxbusnumbers.
*/ staticvoid __init fixup_bus_range(struct device_node *bridge)
{ int *bus_range, len; struct property *prop;
/* Lookup the "bus-range" property for the hose */
prop = of_find_property(bridge, "bus-range", &len); if (prop == NULL || prop->length < 2 * sizeof(int)) return;
/* We only allow config cycles to devices that are in OF device-tree *asweareapparentlyhavingsomeweirdthingsgoingonwithsome *revsofK2onrecentG5s,exceptforthehostbridgeitself,which *ismissingfromthetreebutweknowwecanprobe.
*/ if (bus->self)
busdn = pci_device_to_OF_node(bus->self); elseif (devfn == 0) return0; else
busdn = hose->dn; for (dn = busdn->child; dn; dn = dn->sibling) if (PCI_DN(dn) && PCI_DN(dn)->devfn == devfn) break; if (dn == NULL) return -1;
/* *WhenadeviceinK2ispowereddown,wedieonconfig *cycleaccesses.Fixthathere.
*/ for (i=0; i<2; i++) if (k2_skiplist[i] == dn) return1;
/* XXX it would be better here to identify the specific
PCI-PCI bridge chip we have. */
p2pbridge = of_find_node_by_name(NULL, "pci-bridge"); if (p2pbridge == NULL || !of_node_name_eq(p2pbridge->parent, "pci")) goto done; if (pci_device_from_OF_node(p2pbridge, &bus, &devfn) < 0) {
DBG("Can't find PCI infos for PCI<->PCI bridge\n"); goto done;
} /* Warning: At this point, we have not yet renumbered all busses. *SowemustuseOFwalkingtofindouthose
*/
hose = pci_find_hose_for_OF_device(p2pbridge); if (!hose) {
DBG("Can't find hose for PCI<->PCI bridge\n"); goto done;
} if (early_read_config_word(hose, bus, devfn,
PCI_BRIDGE_CONTROL, &val) < 0) {
printk(KERN_ERR "init_p2pbridge: couldn't read bridge" " control\n"); goto done;
}
val &= ~PCI_BRIDGE_CTL_MASTER_ABORT;
early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val);
done:
of_node_put(p2pbridge);
}
staticint __init setup_uninorth(struct pci_controller *hose, struct resource *addr)
{
pci_add_flags(PCI_REASSIGN_ALL_BUS);
has_uninorth = 1;
hose->ops = ¯isc_pci_ops;
hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000);
hose->cfg_data = ioremap(addr->start + 0xc00000, 0x1000); /* We "know" that the bridge at f2000000 has the PCI slots. */ return addr->start == 0xf2000000;
} #endif/* CONFIG_PPC32 */
#ifdef CONFIG_PPC64 staticvoid __init setup_u3_agp(struct pci_controller* hose)
{ /* On G5, we move AGP up to high bus number so we don't need *toreassignbusnumbersforHT.IfweeverhaveP2Pbridges *onAGP,we'llhavetomovepci_assign_all_bussestothe *pci_controllerstructuresoweenableitforAGPandnotfor *HTchilds. *Wehardcodetheaddressbecauseofthedifferentsizeof *theregaddresscell,weshallfixthatbykillingstruct *reg_propertyandusingsomeaccessorfunctionsinstead
*/
hose->first_busno = 0xf0;
hose->last_busno = 0xff;
has_uninorth = 1;
hose->ops = ¯isc_pci_ops;
hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
u3_agp = hose;
}
staticvoid __init setup_u4_pcie(struct pci_controller* hose)
{ /* We currently only implement the "non-atomic" config space, to *beoptimisedlater.
*/
hose->ops = &u4_pcie_pci_ops;
hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
/* The bus contains a bridge from root -> device, we need to *makeitvisibleonbus0sothatwepicktherighttype *ofconfigcycles.Ifwedidn't,wewouldhavetoforceall *configcyclestobetype1.Soweoverridethe"bus-range" *propertyhere
*/
hose->first_busno = 0x00;
hose->last_busno = 0xff;
}
staticvoid __init parse_region_decode(struct pci_controller *hose,
u32 decode)
{ unsignedlong base, end, next = -1; int i, cur = -1;
/* Iterate through all bits. We ignore the last bit as this region is *reservedfortheROMamongotherniceties
*/ for (i = 0; i < 31; i++) { if ((decode & (0x80000000 >> i)) == 0) continue; if (i < 16) {
base = 0xf0000000 | (((u32)i) << 24);
end = base + 0x00ffffff;
} else {
base = ((u32)i-16) << 28;
end = base + 0x0fffffff;
} if (base != next) { if (++cur >= 3) {
printk(KERN_WARNING "PCI: Too many ranges !\n"); break;
}
hose->mem_resources[cur].flags = IORESOURCE_MEM;
hose->mem_resources[cur].name = hose->dn->full_name;
hose->mem_resources[cur].start = base;
hose->mem_resources[cur].end = end;
hose->mem_offset[cur] = 0;
DBG(" %d: 0x%08lx-0x%08lx\n", cur, base, end);
} else {
DBG(" : -0x%08lx\n", end);
hose->mem_resources[cur].end = end;
}
next = end + 1;
}
}
/* Get base addresses from OF tree
*/ if (of_address_to_resource(np, 0, &cfg_res) ||
of_address_to_resource(np, 1, &self_res)) {
printk(KERN_ERR "PCI: Failed to get U3/U4 HT resources !\n"); return;
}
/* Map external cfg space access into cfg_data and self registers *intocfg_addr
*/
hose->cfg_data = ioremap(cfg_res.start, 0x02000000);
hose->cfg_addr = ioremap(self_res.start, resource_size(&self_res));
/* Get bus range if any */
bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) {
printk(KERN_WARNING "Can't get bus-range for %pOF, assume" " bus 0\n", dev);
}
/* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We *assumethereisnoP2PbridgeontheAGPbus,whichshouldbea *safeassumptionsfornow.Weshoulddosomethingbetterinthe *futurethough
*/
np = hose->dn;
PCI_DN(np)->busno = 0xf0;
for_each_child_of_node(np, child)
PCI_DN(child)->busno = 0xf0;
/* We are still having some issues with the Xserve G4, enabling *someoffsetbetweenbusnumberanddomainsfornowwhenwe *assignallbussesshouldhelpfornow
*/ if (pci_has_flag(PCI_REASSIGN_ALL_BUS))
pcibios_assign_bus_offset = 0x10; #endif
}
#ifdef CONFIG_PPC32 staticbool pmac_pci_enable_device_hook(struct pci_dev *dev)
{ struct device_node* node; int updatecfg = 0; int uninorth_child;
node = pci_device_to_OF_node(dev);
/* We don't want to enable USB controllers absent from the OF tree *(iBooksecondcontroller)
*/ if (dev->vendor == PCI_VENDOR_ID_APPLE
&& dev->class == PCI_CLASS_SERIAL_USB_OHCI
&& !node) {
printk(KERN_INFO "Apple USB OHCI %s disabled by firmware\n",
pci_name(dev)); returnfalse;
}
/* We don't want to assign resources to USB controllers *absentfromtheOFtree(iBooksecondcontroller)
*/ if (dev->class == PCI_CLASS_SERIAL_USB_OHCI && !node)
dev->resource[0].flags = 0;
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_APPLE, PCI_ANY_ID, pmac_pci_fixup_ohci);
/* We power down some devices after they have been probed. They'll *bepoweredbackonlateron
*/ void __init pmac_pcibios_after_init(void)
{ struct device_node* nd;
/* *OnPowerMacs,wetrytoswitchanyPCIATAcontrollerto *fullynativemode
*/ if (!machine_is(powermac)) return;
/* Some controllers don't have the class IDE */ if (dev->vendor == PCI_VENDOR_ID_PROMISE) switch(dev->device) { case PCI_DEVICE_ID_PROMISE_20246: case PCI_DEVICE_ID_PROMISE_20262: case PCI_DEVICE_ID_PROMISE_20263: case PCI_DEVICE_ID_PROMISE_20265: case PCI_DEVICE_ID_PROMISE_20267: case PCI_DEVICE_ID_PROMISE_20268: case PCI_DEVICE_ID_PROMISE_20269: case PCI_DEVICE_ID_PROMISE_20270: case PCI_DEVICE_ID_PROMISE_20271: case PCI_DEVICE_ID_PROMISE_20275: case PCI_DEVICE_ID_PROMISE_20276: case PCI_DEVICE_ID_PROMISE_20277: goto good;
} /* Others, check PCI class */ if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) return;
good:
pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); if ((progif & 5) != 5) {
printk(KERN_INFO "PCI: %s Forcing PCI IDE into native mode\n",
pci_name(dev));
(void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5); if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) ||
(progif & 5) != 5)
printk(KERN_ERR "Rewrite of PROGIF failed !\n"); else { /* Clear IO BARs, they will be reassigned */
pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0);
pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0);
pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, 0);
pci_write_config_dword(dev, PCI_BASE_ADDRESS_3, 0);
}
}
}
DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata); #endif/* CONFIG_PPC32 */
/* Only do that on PowerMac */ if (!machine_is(powermac)) return;
/* Find the largest MMIO region */ for (i = 0; i < 3; i++) { struct resource *r = &host->mem_resources[i]; if (!(r->flags & IORESOURCE_MEM)) continue; /* Skip the 0xf0xxxxxx..f2xxxxxx regions, we know they *arereservedbyHWforotherthings
*/ if (r->start >= 0xf0000000 && r->start < 0xf3000000) continue; if (!region || resource_size(r) > resource_size(region))
region = r;
} /* Nothing found, bail */ if (!region) return;
/* Print things out */
printk(KERN_INFO "PCI: Fixup U4 PCIe bridge range: %pR\n", region);
/* We need to use normal PCI probing for the AGP bus, *sincethedevicefortheAGPbridgeisn'tinthetree. *SameforthePCIehostonU4andtheHThostbridge.
*/ if (bus->self == NULL && (of_device_is_compatible(node, "u3-agp") ||
of_device_is_compatible(node, "u4-pcie") ||
of_device_is_compatible(node, "u3-ht"))) return PCI_PROBE_NORMAL; return PCI_PROBE_DEVTREE;
} #endif/* CONFIG_PPC64 */
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.19Bemerkung:
(vorverarbeitet am 2026-09-27)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.