diff options
author | Tom Rini <trini@konsulko.com> | 2015-08-26 17:48:05 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2015-08-26 17:48:05 -0400 |
commit | 79c884d7e449a63fa8f07b7495f8f9873355c48f (patch) | |
tree | 19adcc1b9d3520a68937a1f5f81b06775c790d8a /drivers/pci/pci-uclass.c | |
parent | ad608a21f89bf7467059ed59d60b080aace7ef99 (diff) | |
parent | f4b5db7c5309dd7f3ecc6369f3c1f41e8bfe93ae (diff) | |
download | blackbird-obmc-uboot-79c884d7e449a63fa8f07b7495f8f9873355c48f.tar.gz blackbird-obmc-uboot-79c884d7e449a63fa8f07b7495f8f9873355c48f.zip |
Merge git://git.denx.de/u-boot-x86
Diffstat (limited to 'drivers/pci/pci-uclass.c')
-rw-r--r-- | drivers/pci/pci-uclass.c | 73 |
1 files changed, 60 insertions, 13 deletions
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 7d41d56fd4..b25298fb5e 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -14,6 +14,9 @@ #include <dm/lists.h> #include <dm/root.h> #include <dm/device-internal.h> +#if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP) +#include <asm/fsp/fsp_support.h> +#endif DECLARE_GLOBAL_DATA_PTR; @@ -461,6 +464,7 @@ static int pci_find_and_bind_driver(struct udevice *parent, int n_ents; int ret; char name[30], *str; + bool bridge; *devp = NULL; @@ -480,6 +484,17 @@ static int pci_find_and_bind_driver(struct udevice *parent, continue; drv = entry->driver; + + /* + * In the pre-relocation phase, we only bind devices + * whose driver has the DM_FLAG_PRE_RELOC set, to save + * precious memory space as on some platforms as that + * space is pretty limited (ie: using Cache As RAM). + */ + if (!(gd->flags & GD_FLG_RELOC) && + !(drv->flags & DM_FLAG_PRE_RELOC)) + return 0; + /* * We could pass the descriptor to the driver as * platdata (instead of NULL) and allow its bind() @@ -499,14 +514,23 @@ static int pci_find_and_bind_driver(struct udevice *parent, } } + bridge = (find_id->class >> 8) == PCI_CLASS_BRIDGE_PCI; + /* + * In the pre-relocation phase, we only bind bridge devices to save + * precious memory space as on some platforms as that space is pretty + * limited (ie: using Cache As RAM). + */ + if (!(gd->flags & GD_FLG_RELOC) && !bridge) + return 0; + /* Bind a generic driver so that the device can be used */ sprintf(name, "pci_%x:%x.%x", parent->seq, PCI_DEV(bdf), PCI_FUNC(bdf)); str = strdup(name); if (!str) return -ENOMEM; - drv = (find_id->class >> 8) == PCI_CLASS_BRIDGE_PCI ? "pci_bridge_drv" : - "pci_generic_drv"; + drv = bridge ? "pci_bridge_drv" : "pci_generic_drv"; + ret = device_bind_driver(parent, drv, str, devp); if (ret) { debug("%s: Failed to bind generic driver: %d", __func__, ret); @@ -589,11 +613,13 @@ int pci_bind_bus_devices(struct udevice *bus) return ret; /* Update the platform data */ - pplat = dev_get_parent_platdata(dev); - pplat->devfn = PCI_MASK_BUS(bdf); - pplat->vendor = vendor; - pplat->device = device; - pplat->class = class; + if (dev) { + pplat = dev_get_parent_platdata(dev); + pplat->devfn = PCI_MASK_BUS(bdf); + pplat->vendor = vendor; + pplat->device = device; + pplat->class = class; + } } return 0; @@ -606,6 +632,13 @@ error: static int pci_uclass_post_bind(struct udevice *bus) { /* + * If there is no pci device listed in the device tree, + * don't bother scanning the device tree. + */ + if (bus->of_offset == -1) + return 0; + + /* * Scan the device tree for devices. This does not probe the PCI bus, * as this is not permitted while binding. It just finds devices * mentioned in the device tree. @@ -717,10 +750,6 @@ static int pci_uclass_post_probe(struct udevice *bus) { int ret; - /* Don't scan buses before relocation */ - if (!(gd->flags & GD_FLG_RELOC)) - return 0; - debug("%s: probing bus %d\n", __func__, bus->seq); ret = pci_bind_bus_devices(bus); if (ret) @@ -730,6 +759,24 @@ static int pci_uclass_post_probe(struct udevice *bus) ret = pci_auto_config_devices(bus); #endif +#if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP) + /* + * Per Intel FSP specification, we should call FSP notify API to + * inform FSP that PCI enumeration has been done so that FSP will + * do any necessary initialization as required by the chipset's + * BIOS Writer's Guide (BWG). + * + * Unfortunately we have to put this call here as with driver model, + * the enumeration is all done on a lazy basis as needed, so until + * something is touched on PCI it won't happen. + * + * Note we only call this 1) after U-Boot is relocated, and 2) + * root bus has finished probing. + */ + if ((gd->flags & GD_FLG_RELOC) && (bus->seq == 0)) + ret = fsp_init_phase_pci(); +#endif + return ret < 0 ? ret : 0; } @@ -754,8 +801,8 @@ static int pci_uclass_child_post_bind(struct udevice *dev) if (ret != -ENOENT) return -EINVAL; } else { - /* extract the bdf from fdt_pci_addr */ - pplat->devfn = addr.phys_hi & 0xffff00; + /* extract the devfn from fdt_pci_addr */ + pplat->devfn = addr.phys_hi & 0xff00; } return 0; |