[U-Boot] [PATCH 08/23] pci: Make PCI bridge memory alignment configurable
Simon Glass
sjg at chromium.org
Tue Sep 27 02:35:19 CEST 2016
Hi Paul,
On 26 September 2016 at 12:29, Paul Burton <paul.burton at imgtec.com> 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 at imgtec.com>
>
> ---
>
> drivers/pci/Kconfig | 7 +++++++
> drivers/pci/pci_auto.c | 24 ++++++++++++++++--------
> 2 files changed, 23 insertions(+), 8 deletions(-)
Reviewed-by: Simon Glass <sjg at chromium.org>
Please see below
>
> diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
> index 9a7c187..35bf8fe 100644
> --- a/drivers/pci/Kconfig
> +++ b/drivers/pci/Kconfig
> @@ -18,6 +18,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.
Can you also add why this is useful, and why 1MB is a suitable default?
> +
> config PCI_SANDBOX
> bool "Sandbox PCI support"
> depends on SANDBOX && DM_PCI
> diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c
> index ee9a854..0326316 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)
Can you update the pciauto_region_align() so you can omit this if () ?
> + 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);
>
> 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);
> --
> 2.10.0
>
Regards,
Simon
More information about the U-Boot
mailing list