+ /*
+ * The configuration space of the PCI Bridge on primary (first) bus is
+ * not accessible via PIO transfers like all other PCIe devices. PCI
+ * Bridge config registers are available directly in Aardvark memory
+ * space starting at offset zero. The PCI Bridge config space is of
+ * Type 0, but the BAR registers (including ROM BAR) don't have the same
+ * meaning as in the PCIe specification. Therefore do not access BAR
+ * registers and non-common registers (those which have different
+ * meaning for Type 0 and Type 1 config space) of the primary PCI Bridge
+ * and instead read their content from driver virtual cfgcache[].
+ */
+ if (busno == pcie->first_busno) {
+ if ((offset >= 0x10 && offset < 0x34) || (offset >= 0x38 && offset < 0x3c))
+ data = pcie->cfgcache[(offset - 0x10) / 4];
+ else
+ data = advk_readl(pcie, offset & ~3);
+
+ if ((offset & ~3) == (PCI_HEADER_TYPE & ~3)) {
+ /*
+ * Change Header Type of PCI Bridge device to Type 1
+ * (0x01, used by PCI Bridges) because hardwired value
+ * is Type 0 (0x00, used by Endpoint devices).
+ */
+ data &= ~0x007f0000;
+ data |= PCI_HEADER_TYPE_BRIDGE << 16;
+ }
+
+ if ((offset & ~3) == PCIE_CORE_PCIEXP_CAP_OFF + PCI_EXP_RTCTL) {
+ /* CRSSVE bit is stored only in cache */
+ if (pcie->cfgcrssve)
+ data |= PCI_EXP_RTCTL_CRSSVE;
+ }
+
+ if ((offset & ~3) == PCIE_CORE_PCIEXP_CAP_OFF +
+ (PCI_EXP_RTCAP & ~3)) {
+ /* CRS is emulated below, so set CRSVIS capability */
+ data |= PCI_EXP_RTCAP_CRSVIS << 16;
+ }
+
+ *valuep = pci_conv_32_to_size(data, offset, size);
+
+ return 0;
+ }
+
+ /*
+ * Returning fabricated CRS value (0xFFFF0001) by PCIe Root Complex to
+ * OS is allowed only for 4-byte PCI_VENDOR_ID config read request and
+ * only when CRSSVE bit in Root Port PCIe device is enabled. In all
+ * other error PCIe Root Complex must return all-ones.
+ *
+ * U-Boot currently does not support handling of CRS return value for
+ * PCI_VENDOR_ID config read request and also does not set CRSSVE bit.
+ * So it means that pcie->cfgcrssve is false. But the code is prepared
+ * for returning CRS, so that if U-Boot does support CRS in the future,
+ * it will work for Aardvark.
+ */
+ allow_crs = (offset == PCI_VENDOR_ID) && (size == PCI_SIZE_32) && pcie->cfgcrssve;
+