Message ID | 20171121203347.10908-2-paul.burton@mips.com |
---|---|
State | Deferred |
Delegated to: | Daniel Schwierzeck |
Headers | show |
Series | boston: Ethernet support for MIPS Boston board | expand |
On 21.11.2017 21:33, Paul Burton wrote: > On some systems aligning PCI memory to a 1MB boundary every time a > bridge is encountered may lead to exhausting the available memory space > before all devices have been assigned addresses. > > For example on the MIPS Boston development board we have an Intel EG20T > Platform Controller Hub connected to a Xilinx AXI to PCIe root port > which is only assigned a 1MB memory region. The Intel EG20T contains a > bridge device beneath which all of its peripheral devices can be found, > and that bridge device contains a ROM. If we align to 1MB when we > encounter each bridge device we therefore do something like this: > > - Start with bus_lower at 0x16000000. > > - Find the Xilinx root bridge, which has no visible BARs so we do very > little to it. > > - Probe the bus beneath the Xilinx bridge device, aligning bus_lower > to a 1MB boundary first. That leaves it still at 0x16000000. > > - Find the EG20T bridge device, which we find has a 64KiB ROM. We > assign it the address range 0x16000000-0x1600ffff which leaves > bus_lower at 0x16010000. > > - Probe the bus beneath the EG20T bridge device, aligning bus_lower to > a 1MB boundary first. This leaves bus_lower at 0x16100000, which is > the end of the available memory space. > > - Find the various peripheral devices the EG20T contains, but fail to > assign any memory space to them since bus_lower is at the end of the > memory space available to the PCI bus. > > This patch allows that 1MB alignment to be changed or disabled via > Kconfig, so that systems such as this can select an alignment which > works for them. > > Signed-off-by: Paul Burton <paul.burton@imgtec.com> > Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> > Cc: Simon Glass <sjg@chromium.org> > Cc: u-boot@lists.denx.de > Signed-off-by: Paul Burton <paul.burton@mips.com> > --- > > drivers/pci/Kconfig | 7 +++++++ > drivers/pci/pci_auto.c | 24 ++++++++++++++++-------- > 2 files changed, 23 insertions(+), 8 deletions(-) > Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 58f128d8a6..1605cfc8fa 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -26,6 +26,13 @@ config DM_PCI_COMPAT measure when porting a board to use driver model for PCI. Once the board is fully supported, this option should be disabled. +config DM_PCI_BRIDGE_MEM_ALIGN + hex "PCI bridge memory alignment" + default 0x100000 + help + PCI memory space will be aligned to be a multiple of this value + whenever a PCI-to-PCI bridge is encountered. + config PCI_PNP bool "Enable Plug & Play support for PCI" depends on PCI || DM_PCI diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index c2bc32678a..c4eee6f0ba 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -186,8 +186,10 @@ void dm_pciauto_prescan_setup_bridge(struct udevice *dev, int sub_bus) dm_pci_write_config8(dev, PCI_SUBORDINATE_BUS, 0xff); if (pci_mem) { - /* Round memory allocator to 1MB boundary */ - pciauto_region_align(pci_mem, 0x100000); + /* Round memory allocator to a suitable boundary */ + if (CONFIG_DM_PCI_BRIDGE_MEM_ALIGN) + pciauto_region_align(pci_mem, + CONFIG_DM_PCI_BRIDGE_MEM_ALIGN); /* * Set up memory and I/O filter limits, assume 32-bit @@ -200,8 +202,10 @@ void dm_pciauto_prescan_setup_bridge(struct udevice *dev, int sub_bus) } if (pci_prefetch) { - /* Round memory allocator to 1MB boundary */ - pciauto_region_align(pci_prefetch, 0x100000); + /* Round memory allocator to a suitable boundary */ + if (CONFIG_DM_PCI_BRIDGE_MEM_ALIGN) + pciauto_region_align(pci_prefetch, + CONFIG_DM_PCI_BRIDGE_MEM_ALIGN); /* * Set up memory and I/O filter limits, assume 32-bit @@ -260,8 +264,10 @@ void dm_pciauto_postscan_setup_bridge(struct udevice *dev, int sub_bus) dm_pci_write_config8(dev, PCI_SUBORDINATE_BUS, sub_bus - ctlr->seq); if (pci_mem) { - /* Round memory allocator to 1MB boundary */ - pciauto_region_align(pci_mem, 0x100000); + /* Round memory allocator to a suitable boundary */ + if (CONFIG_DM_PCI_BRIDGE_MEM_ALIGN) + pciauto_region_align(pci_mem, + CONFIG_DM_PCI_BRIDGE_MEM_ALIGN); dm_pci_write_config16(dev, PCI_MEMORY_LIMIT, (pci_mem->bus_lower - 1) >> 16); @@ -274,8 +280,10 @@ void dm_pciauto_postscan_setup_bridge(struct udevice *dev, int sub_bus) &prefechable_64); prefechable_64 &= PCI_PREF_RANGE_TYPE_MASK; - /* Round memory allocator to 1MB boundary */ - pciauto_region_align(pci_prefetch, 0x100000); + /* Round memory allocator to a suitable boundary */ + if (CONFIG_DM_PCI_BRIDGE_MEM_ALIGN) + pciauto_region_align(pci_prefetch, + CONFIG_DM_PCI_BRIDGE_MEM_ALIGN); dm_pci_write_config16(dev, PCI_PREF_MEMORY_LIMIT, (pci_prefetch->bus_lower - 1) >> 16);