/***************************************************************************** * Orion has one PCIe controller and one PCI controller. * * Note1: The local PCIe bus number is '0'. The local PCI bus number * follows the scanned PCIe bridged busses, if any. * * Note2: It is possible for PCI/PCIe agents to access many subsystem's * space, by configuring BARs and Address Decode Windows, e.g. flashes on * device bus, Orion registers, etc. However this code only enable the * access to DDR banks.
****************************************************************************/
staticint pcie_valid_config(int bus, int dev)
{ /* * Don't go out when trying to access -- * 1. nonexisting device on local bus * 2. where there's no device connected (no link)
*/ if (bus == 0 && dev == 0) return 1;
if (!orion_pcie_link_up(PCIE_BASE)) return 0;
if (bus == 0 && dev != 1) return 0;
return 1;
}
/* * PCIe config cycles are done by programming the PCIE_CONF_ADDR register * and then reading the PCIE_CONF_DATA register. Need to make sure these * transactions are atomic.
*/ static DEFINE_SPINLOCK(orion5x_pcie_lock);
staticint pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 *val)
{ unsignedlong flags; int ret;
/* * We only support access to the non-extended configuration * space when using the WA access method (or we would have to * sacrifice 256M of CPU virtual address space.)
*/ if (where >= 0x100) {
*val = 0xffffffff; return PCIBIOS_DEVICE_NOT_FOUND;
}
ret = orion_pcie_rd_conf_wa(ORION5X_PCIE_WA_VIRT_BASE,
bus, devfn, where, size, val);
return ret;
}
staticint pcie_wr_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 val)
{ unsignedlong flags; int ret;
if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) return PCIBIOS_DEVICE_NOT_FOUND;
/* * PCI config cycles are done by programming the PCI_CONF_ADDR register * and then reading the PCI_CONF_DATA register. Need to make sure these * transactions are atomic.
*/ static DEFINE_SPINLOCK(orion5x_pci_lock);
staticint orion5x_pci_valid_config(int bus, u32 devfn)
{ if (bus == orion5x_pci_local_bus_nr()) { /* * Don't go out for local device
*/ if (PCI_SLOT(devfn) == 0 && PCI_FUNC(devfn) != 0) return 0;
/* * When the PCI signals are directly connected to a * Cardbus slot, ignore all but device IDs 0 and 1.
*/ if (orion5x_pci_cardbus_mode && PCI_SLOT(devfn) > 1) return 0;
}
return 1;
}
staticint orion5x_pci_rd_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 *val)
{ if (!orion5x_pci_valid_config(bus->number, devfn)) {
*val = 0xffffffff; return PCIBIOS_DEVICE_NOT_FOUND;
}
/***************************************************************************** * General PCIe + PCI
****************************************************************************/
/* * The root complex has a hardwired class of PCI_CLASS_MEMORY_OTHER, when it * is operating as a root complex this needs to be switched to * PCI_CLASS_BRIDGE_HOST or Linux will errantly try to process the BAR's on * the device. Decoding setup is handled by the orion code.
*/ staticvoid rc_pci_fixup(struct pci_dev *dev)
{ if (dev->bus->parent == NULL && dev->devfn == 0) { struct resource *r;
int __init orion5x_pci_map_irq(conststruct pci_dev *dev, u8 slot, u8 pin)
{ int bus = dev->bus->number;
/* * PCIe endpoint?
*/ if (orion5x_pci_disabled || bus < orion5x_pci_local_bus_nr()) return IRQ_ORION5X_PCIE0_INT;
return -1;
}
Messung V0.5 in Prozent
¤ 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.1Bemerkung:
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-04-29)
¤
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.