pci: pci-uclass: Add support for Alternate-RoutingID capability
authorSuneel Garapati <sgarapati@marvell.com>
Thu, 24 Oct 2019 01:40:36 +0000 (18:40 -0700)
committerStefan Roese <sr@denx.de>
Tue, 25 Aug 2020 06:01:16 +0000 (08:01 +0200)
If ARI capability is found on device, use it to update next function
number in bus scan and also helps to skip unnecessary bdf scans.

Signed-off-by: Suneel Garapati <sgarapati@marvell.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
drivers/pci/Kconfig
drivers/pci/pci-uclass.c

index 4635752..377806f 100644 (file)
@@ -63,6 +63,15 @@ config PCI_SRIOV
          if available on a PCI Physical Function device and probe for
          applicable drivers.
 
+config PCI_ARID
+        bool "Enable Alternate Routing-ID support for PCI"
+        depends on PCI || DM_PCI
+        default n
+        help
+          Say Y here if you want to enable Alternate Routing-ID capability
+          support on PCI devices. This helps to skip some devices in BDF
+          scan that are not present.
+
 config PCIE_ECAM_GENERIC
        bool "Generic ECAM-based PCI host controller support"
        default n
index 23135eb..fc60dfe 100644 (file)
@@ -798,6 +798,7 @@ int pci_bind_bus_devices(struct udevice *bus)
        ulong header_type;
        pci_dev_t bdf, end;
        bool found_multi;
+       int ari_off;
        int ret;
 
        found_multi = false;
@@ -871,6 +872,31 @@ int pci_bind_bus_devices(struct udevice *bus)
                pplat->vendor = vendor;
                pplat->device = device;
                pplat->class = class;
+
+               if (IS_ENABLED(CONFIG_PCI_ARID)) {
+                       ari_off = dm_pci_find_ext_capability(dev,
+                                                            PCI_EXT_CAP_ID_ARI);
+                       if (ari_off) {
+                               u16 ari_cap;
+
+                               /*
+                                * Read Next Function number in ARI Cap
+                                * Register
+                                */
+                               dm_pci_read_config16(dev, ari_off + 4,
+                                                    &ari_cap);
+                               /*
+                                * Update next scan on this function number,
+                                * subtract 1 in BDF to satisfy loop increment.
+                                */
+                               if (ari_cap & 0xff00) {
+                                       bdf = PCI_BDF(PCI_BUS(bdf),
+                                                     PCI_DEV(ari_cap),
+                                                     PCI_FUNC(ari_cap));
+                                       bdf = bdf - 0x100;
+                               }
+                       }
+               }
        }
 
        return 0;