summaryrefslogtreecommitdiff
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/pci-emul-uclass.c55
-rw-r--r--drivers/pci/pci-uclass.c5
-rw-r--r--drivers/pci/pci_auto.c12
-rw-r--r--drivers/pci/pci_auto_common.c4
-rw-r--r--drivers/pci/pci_rom.c2
-rw-r--r--drivers/pci/pci_x86.c16
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[] = {