dm: pci: Allow delaying auto-config until after relocation
authorSimon Glass <sjg@chromium.org>
Sat, 7 Dec 2019 04:41:37 +0000 (21:41 -0700)
committerBin Meng <bmeng.cn@gmail.com>
Sun, 15 Dec 2019 00:52:29 +0000 (08:52 +0800)
At present PCI auto-configuration happens in U-Boot both before and after
relocation. This is a waste of time and may mess up static addresses used
in board_init_f(). Adjust the code to supporting doing auto-configuration
once, after relocation, under control of a device-tree property.

This is needed for Apollo Lake for debugging the silicon-init code. Once
the UART is moved to a different MMIO address the debug UART does not work
and any debug output in Apollo Lake's arch_fsp_init_r() causes a hang.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
doc/device-tree-bindings/pci/x86-pci.txt [new file with mode: 0644]
drivers/pci/pci-uclass.c
include/pci.h

diff --git a/doc/device-tree-bindings/pci/x86-pci.txt b/doc/device-tree-bindings/pci/x86-pci.txt
new file mode 100644 (file)
index 0000000..3aa5bd9
--- /dev/null
@@ -0,0 +1,24 @@
+x86 PCI DT details:
+===================
+
+Some options are available to affect how PCI operates on x86.
+
+Optional properties:
+- u-boot,skip-auto-config-until-reloc : Don't set up PCI configuration until
+       after U-Boot has relocated. Normally if PCI is used before relocation,
+       this happens before relocation also. Some platforms set up static
+       configuration in TPL/SPL to reduce code size and boot time, since these
+       phases only know about a small subset of PCI devices.
+
+Example:
+
+pci {
+       compatible = "pci-x86";
+       #address-cells = <3>;
+       #size-cells = <2>;
+       u-boot,dm-pre-reloc;
+       ranges = <0x02000000 0x0 0xc0000000 0xc0000000 0 0x10000000
+               0x42000000 0x0 0xb0000000 0xb0000000 0 0x10000000
+               0x01000000 0x0 0x1000 0x1000 0 0xefff>;
+       u-boot,skip-auto-config-until-reloc;
+};
index fab20fc60e55bf9fcd3681f26be77735a8b37489..8e13adb156e984640252982cfd2d26bdd58e05dd 100644 (file)
@@ -975,12 +975,15 @@ 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");
 
        return 0;
 }
 
 static int pci_uclass_post_probe(struct udevice *bus)
 {
+       struct pci_controller *hose = dev_get_uclass_priv(bus);
        int ret;
 
        debug("%s: probing bus %d\n", __func__, bus->seq);
@@ -988,11 +991,13 @@ static int pci_uclass_post_probe(struct udevice *bus)
        if (ret)
                return ret;
 
-#if CONFIG_IS_ENABLED(PCI_PNP)
-       ret = pci_auto_config_devices(bus);
-       if (ret < 0)
-               return ret;
-#endif
+       if (CONFIG_IS_ENABLED(PCI_PNP) &&
+           (!hose->skip_auto_config_until_reloc ||
+            (gd->flags & GD_FLG_RELOC))) {
+               ret = pci_auto_config_devices(bus);
+               if (ret < 0)
+                       return log_msg_ret("pci auto-config", ret);
+       }
 
 #if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
        /*
index ff59ac0e69553584b83ec44d6d7657807a4836bf..de17d0ffbae4bd44d8ad0eac5aaa2d5c251506f9 100644 (file)
@@ -571,15 +571,22 @@ extern void pci_cfgfunc_config_device(struct pci_controller* hose, pci_dev_t dev
 
 #define INDIRECT_TYPE_NO_PCIE_LINK     1
 
-/*
+/**
  * Structure of a PCI controller (host bridge)
  *
  * With driver model this is dev_get_uclass_priv(bus)
+ *
+ * @skip_auto_config_until_reloc: true to avoid auto-config until U-Boot has
+ *     relocated. Normally if PCI is used before relocation, this happens
+ *     before relocation also. Some platforms set up static configuration in
+ *     TPL/SPL to reduce code size and boot time, since these phases only know
+ *     about a small subset of PCI devices. This is normally false.
  */
 struct pci_controller {
 #ifdef CONFIG_DM_PCI
        struct udevice *bus;
        struct udevice *ctlr;
+       bool skip_auto_config_until_reloc;
 #else
        struct pci_controller *next;
 #endif