From mboxrd@z Thu Jan 1 00:00:00 1970 From: Simon Glass Date: Thu, 21 Nov 2019 21:17:29 -0700 Subject: [U-Boot] [PATCH v4 004/100] dm: pci: Allow delaying auto-config until after relocation In-Reply-To: <20191122041905.224686-1-sjg@chromium.org> References: <20191122041905.224686-1-sjg@chromium.org> Message-ID: <20191122041905.224686-5-sjg@chromium.org> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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 --- Changes in v4: - Change the behaviour to be a device-tree option - apollolake -> Apollo Lake Changes in v3: None Changes in v2: None doc/device-tree-bindings/pci/x86-pci.txt | 24 ++++++++++++++++++++++++ drivers/pci/pci-uclass.c | 15 ++++++++++----- include/pci.h | 9 ++++++++- 3 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 doc/device-tree-bindings/pci/x86-pci.txt diff --git a/doc/device-tree-bindings/pci/x86-pci.txt b/doc/device-tree-bindings/pci/x86-pci.txt new file mode 100644 index 0000000000..3aa5bd9a46 --- /dev/null +++ b/doc/device-tree-bindings/pci/x86-pci.txt @@ -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; +}; diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 896cb6b23a..b09fb4f993 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -970,12 +970,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); @@ -983,11 +986,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) /* diff --git a/include/pci.h b/include/pci.h index ff59ac0e69..de17d0ffba 100644 --- a/include/pci.h +++ b/include/pci.h @@ -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 -- 2.24.0.432.g9d3f5f5b63-goog