diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/pci-emul-uclass.c | 55 | ||||
-rw-r--r-- | drivers/pci/pci-uclass.c | 5 | ||||
-rw-r--r-- | drivers/pci/pci_auto.c | 12 | ||||
-rw-r--r-- | drivers/pci/pci_auto_common.c | 4 | ||||
-rw-r--r-- | drivers/pci/pci_rom.c | 2 | ||||
-rw-r--r-- | drivers/pci/pci_x86.c | 16 |
6 files changed, 79 insertions, 15 deletions
diff --git a/drivers/pci/pci-emul-uclass.c b/drivers/pci/pci-emul-uclass.c index 3822758354..0dcf937d9a 100644 --- a/drivers/pci/pci-emul-uclass.c +++ b/drivers/pci/pci-emul-uclass.c @@ -30,17 +30,38 @@ int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn, } *containerp = dev; - if (device_get_uclass_id(dev) == UCLASS_PCI_GENERIC) { - ret = device_find_first_child(dev, emulp); - if (ret) - return ret; - } else { + /* + * See commit 4345998ae9df, + * "pci: sandbox: Support dynamically binding device driver" + */ + ret = uclass_get_device_by_phandle(UCLASS_PCI_EMUL, dev, "sandbox,emul", + emulp); + if (ret && device_get_uclass_id(dev) != UCLASS_PCI_GENERIC) *emulp = dev; - } return *emulp ? 0 : -ENODEV; } +uint sandbox_pci_read_bar(u32 barval, int type, uint size) +{ + u32 result; + + result = barval; + if (result == 0xffffffff) { + if (type == PCI_BASE_ADDRESS_SPACE_IO) { + result = (~(size - 1) & + PCI_BASE_ADDRESS_IO_MASK) | + PCI_BASE_ADDRESS_SPACE_IO; + } else { + result = (~(size - 1) & + PCI_BASE_ADDRESS_MEM_MASK) | + PCI_BASE_ADDRESS_MEM_TYPE_32; + } + } + + return result; +} + static int sandbox_pci_emul_post_probe(struct udevice *dev) { struct sandbox_pci_emul_priv *priv = dev->uclass->priv; @@ -68,3 +89,25 @@ UCLASS_DRIVER(pci_emul) = { .pre_remove = sandbox_pci_emul_pre_remove, .priv_auto_alloc_size = sizeof(struct sandbox_pci_emul_priv), }; + +/* + * This uclass is a child of the pci bus. Its platdata is not defined here so + * is defined by its parent, UCLASS_PCI, which uses struct pci_child_platdata. + * See per_child_platdata_auto_alloc_size in UCLASS_DRIVER(pci). + */ +UCLASS_DRIVER(pci_emul_parent) = { + .id = UCLASS_PCI_EMUL_PARENT, + .name = "pci_emul_parent", + .post_bind = dm_scan_fdt_dev, +}; + +static const struct udevice_id pci_emul_parent_ids[] = { + { .compatible = "sandbox,pci-emul-parent" }, + { } +}; + +U_BOOT_DRIVER(pci_emul_parent_drv) = { + .name = "pci_emul_parent_drv", + .id = UCLASS_PCI_EMUL_PARENT, + .of_match = pci_emul_parent_ids, +}; diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index ab3e1310eb..896cb6b23a 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -790,7 +790,7 @@ int pci_bind_bus_devices(struct udevice *bus) if (!PCI_FUNC(bdf)) found_multi = header_type & 0x80; - debug("%s: bus %d/%s: found device %x, function %d\n", __func__, + debug("%s: bus %d/%s: found device %x, function %d", __func__, bus->seq, bus->name, PCI_DEV(bdf), PCI_FUNC(bdf)); pci_bus_read_config(bus, bdf, PCI_DEVICE_ID, &device, PCI_SIZE_16); @@ -800,6 +800,7 @@ int pci_bind_bus_devices(struct udevice *bus) /* Find this device in the device tree */ ret = pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), &dev); + debug(": find ret=%d\n", ret); /* If nothing in the device tree, bind a device */ if (ret == -ENODEV) { @@ -982,7 +983,7 @@ static int pci_uclass_post_probe(struct udevice *bus) if (ret) return ret; -#ifdef CONFIG_PCI_PNP +#if CONFIG_IS_ENABLED(PCI_PNP) ret = pci_auto_config_devices(bus); if (ret < 0) return ret; diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index 1a3bf70834..28667bde8d 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -39,6 +39,8 @@ void dm_pciauto_setup_device(struct udevice *dev, int bars_num, for (bar = PCI_BASE_ADDRESS_0; bar < PCI_BASE_ADDRESS_0 + (bars_num * 4); bar += 4) { + int ret = 0; + /* Tickle the BAR and get the response */ if (!enum_only) dm_pci_write_config32(dev, bar, 0xffffffff); @@ -97,9 +99,13 @@ void dm_pciauto_setup_device(struct udevice *dev, int bars_num, (unsigned long long)bar_size); } - if (!enum_only && pciauto_region_allocate(bar_res, bar_size, - &bar_value, - found_mem64) == 0) { + if (!enum_only) { + ret = pciauto_region_allocate(bar_res, bar_size, + &bar_value, found_mem64); + if (ret) + printf("PCI: Failed autoconfig bar %x\n", bar); + } + if (!enum_only && !ret) { /* Write it out and update our limit */ dm_pci_write_config32(dev, bar, (u32)bar_value); diff --git a/drivers/pci/pci_auto_common.c b/drivers/pci/pci_auto_common.c index 84908e6154..8690316610 100644 --- a/drivers/pci/pci_auto_common.c +++ b/drivers/pci/pci_auto_common.c @@ -45,7 +45,9 @@ int pciauto_region_allocate(struct pci_region *res, pci_size_t size, addr = ((res->bus_lower - 1) | (size - 1)) + 1; if (addr - res->bus_start + size > res->size) { - debug("No room in resource"); + debug("No room in resource, avail start=%llx / size=%llx, " + "need=%llx\n", (unsigned long long)res->bus_lower, + (unsigned long long)res->size, (unsigned long long)size); goto error; } diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index 2cede1211b..1d4064e376 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -35,7 +35,7 @@ #include <linux/screen_info.h> #ifdef CONFIG_X86 -#include <asm/acpi_s3.h> +#include <acpi_s3.h> DECLARE_GLOBAL_DATA_PTR; #endif diff --git a/drivers/pci/pci_x86.c b/drivers/pci/pci_x86.c index 520ea4649e..e76a9c6e44 100644 --- a/drivers/pci/pci_x86.c +++ b/drivers/pci/pci_x86.c @@ -8,9 +8,21 @@ #include <pci.h> #include <asm/pci.h> +static int _pci_x86_read_config(struct udevice *bus, pci_dev_t bdf, uint offset, + ulong *valuep, enum pci_size_t size) +{ + return pci_x86_read_config(bdf, offset, valuep, size); +} + +static int _pci_x86_write_config(struct udevice *bus, pci_dev_t bdf, + uint offset, ulong value, enum pci_size_t size) +{ + return pci_x86_write_config(bdf, offset, value, size); +} + static const struct dm_pci_ops pci_x86_ops = { - .read_config = pci_x86_read_config, - .write_config = pci_x86_write_config, + .read_config = _pci_x86_read_config, + .write_config = _pci_x86_write_config, }; static const struct udevice_id pci_x86_ids[] = { |