dm: treewide: Rename auto_alloc_size members to be shorter
[platform/kernel/u-boot.git] / drivers / pci / pci-uclass.c
index 51871bf..6093072 100644 (file)
@@ -539,7 +539,8 @@ int pci_auto_config_devices(struct udevice *bus)
                int ret;
 
                debug("%s: device %s\n", __func__, dev->name);
-               if (dev_read_bool(dev, "pci,no-autoconfig"))
+               if (dev_of_valid(dev) &&
+                   dev_read_bool(dev, "pci,no-autoconfig"))
                        continue;
                ret = dm_pciauto_config_device(dev);
                if (ret < 0)
@@ -749,8 +750,8 @@ static int pci_find_and_bind_driver(struct udevice *parent,
                         * find another driver. For now this doesn't seem
                         * necesssary, so just bind the first match.
                         */
-                       ret = device_bind_ofnode(parent, drv, drv->name, NULL,
-                                                node, &dev);
+                       ret = device_bind(parent, drv, drv->name, NULL, node,
+                                         &dev);
                        if (ret)
                                goto error;
                        debug("%s: Match found: %s\n", __func__, drv->name);
@@ -798,6 +799,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 +873,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;
@@ -884,8 +911,8 @@ static void decode_regions(struct pci_controller *hose, ofnode parent_node,
                           ofnode node)
 {
        int pci_addr_cells, addr_cells, size_cells;
-       struct bd_info *bd = gd->bd;
        int cells_per_record;
+       struct bd_info *bd;
        const u32 *prop;
        int max_regions;
        int len;
@@ -962,6 +989,7 @@ static void decode_regions(struct pci_controller *hose, ofnode parent_node,
        }
 
        /* Add a region for our local memory */
+       bd = gd->bd;
        if (!bd)
                return;
 
@@ -999,8 +1027,11 @@ static int pci_uclass_pre_probe(struct udevice *bus)
        hose->bus = bus;
        hose->first_busno = bus->seq;
        hose->last_busno = bus->seq;
-       hose->skip_auto_config_until_reloc =
-               dev_read_bool(bus, "u-boot,skip-auto-config-until-reloc");
+       if (dev_of_valid(bus)) {
+               hose->skip_auto_config_until_reloc =
+                       dev_read_bool(bus,
+                                     "u-boot,skip-auto-config-until-reloc");
+       }
 
        return 0;
 }
@@ -1409,14 +1440,55 @@ pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t phys_addr,
        return bus_addr;
 }
 
+static phys_addr_t dm_pci_map_ea_virt(struct udevice *dev, int ea_off,
+                                     struct pci_child_platdata *pdata)
+{
+       phys_addr_t addr = 0;
+
+       /*
+        * In the case of a Virtual Function device using BAR
+        * base and size, add offset for VFn BAR(1, 2, 3...n)
+        */
+       if (pdata->is_virtfn) {
+               size_t sz;
+               u32 ea_entry;
+
+               /* MaxOffset, 1st DW */
+               dm_pci_read_config32(dev, ea_off + 8, &ea_entry);
+               sz = ea_entry & PCI_EA_FIELD_MASK;
+               /* Fill up lower 2 bits */
+               sz |= (~PCI_EA_FIELD_MASK);
+
+               if (ea_entry & PCI_EA_IS_64) {
+                       /* MaxOffset 2nd DW */
+                       dm_pci_read_config32(dev, ea_off + 16, &ea_entry);
+                       sz |= ((u64)ea_entry) << 32;
+               }
+
+               addr = (pdata->virtid - 1) * (sz + 1);
+       }
+
+       return addr;
+}
+
 static void *dm_pci_map_ea_bar(struct udevice *dev, int bar, int flags,
-                              int ea_off)
+                              int ea_off, struct pci_child_platdata *pdata)
 {
        int ea_cnt, i, entry_size;
        int bar_id = (bar - PCI_BASE_ADDRESS_0) >> 2;
        u32 ea_entry;
        phys_addr_t addr;
 
+       if (IS_ENABLED(CONFIG_PCI_SRIOV)) {
+               /*
+                * In the case of a Virtual Function device, device is
+                * Physical function, so pdata will point to required VF
+                * specific data.
+                */
+               if (pdata->is_virtfn)
+                       bar_id += PCI_EA_BEI_VF_BAR0;
+       }
+
        /* EA capability structure header */
        dm_pci_read_config32(dev, ea_off, &ea_entry);
        ea_cnt = (ea_entry >> 16) & PCI_EA_NUM_ENT_MASK;
@@ -1439,6 +1511,9 @@ static void *dm_pci_map_ea_bar(struct udevice *dev, int bar, int flags,
                        addr |= ((u64)ea_entry) << 32;
                }
 
+               if (IS_ENABLED(CONFIG_PCI_SRIOV))
+                       addr += dm_pci_map_ea_virt(dev, ea_off, pdata);
+
                /* size ignored for now */
                return map_physmem(addr, 0, flags);
        }
@@ -1448,20 +1523,33 @@ static void *dm_pci_map_ea_bar(struct udevice *dev, int bar, int flags,
 
 void *dm_pci_map_bar(struct udevice *dev, int bar, int flags)
 {
+       struct pci_child_platdata *pdata = dev_get_parent_platdata(dev);
+       struct udevice *udev = dev;
        pci_addr_t pci_bus_addr;
        u32 bar_response;
        int ea_off;
 
+       if (IS_ENABLED(CONFIG_PCI_SRIOV)) {
+               /*
+                * In case of Virtual Function devices, use PF udevice
+                * as EA capability is defined in Physical Function
+                */
+               if (pdata->is_virtfn)
+                       udev = pdata->pfdev;
+       }
+
        /*
         * if the function supports Enhanced Allocation use that instead of
         * BARs
+        * Incase of virtual functions, pdata will help read VF BEI
+        * and EA entry size.
         */
-       ea_off = dm_pci_find_capability(dev, PCI_CAP_ID_EA);
+       ea_off = dm_pci_find_capability(udev, PCI_CAP_ID_EA);
        if (ea_off)
-               return dm_pci_map_ea_bar(dev, bar, flags, ea_off);
+               return dm_pci_map_ea_bar(udev, bar, flags, ea_off, pdata);
 
        /* read BAR address */
-       dm_pci_read_config32(dev, bar, &bar_response);
+       dm_pci_read_config32(udev, bar, &bar_response);
        pci_bus_addr = (pci_addr_t)(bar_response & ~0xf);
 
        /*
@@ -1470,7 +1558,7 @@ void *dm_pci_map_bar(struct udevice *dev, int bar, int flags)
         * linear mapping.  In the future, this could read the BAR size
         * and pass that as the size if needed.
         */
-       return dm_pci_bus_to_virt(dev, pci_bus_addr, flags, 0, MAP_NOCACHE);
+       return dm_pci_bus_to_virt(udev, pci_bus_addr, flags, 0, MAP_NOCACHE);
 }
 
 static int _dm_pci_find_next_capability(struct udevice *dev, u8 pos, int cap)
@@ -1708,8 +1796,8 @@ UCLASS_DRIVER(pci) = {
        .pre_probe      = pci_uclass_pre_probe,
        .post_probe     = pci_uclass_post_probe,
        .child_post_bind = pci_uclass_child_post_bind,
-       .per_device_auto_alloc_size = sizeof(struct pci_controller),
-       .per_child_platdata_auto_alloc_size =
+       .per_device_auto        = sizeof(struct pci_controller),
+       .per_child_platdata_auto        =
                        sizeof(struct pci_child_platdata),
 };