[U-Boot] [PATCH] ARM: renesas: Update Gen3 PCIe dma-ranges before boot

Update "dma-ranges" DT property of all PCIe controllers in the system with the up-to-date DRAM layout. This allows the PCIe controller take full advantage of all the available DRAM, at least in theory.
This patch only populates up to two dma-ranges entry though, this is because older versions of Linux kernel would fail to probe the PCIe driver if there are more regions in the DT than the PCIe IP can use.
Signed-off-by: Marek Vasut marek.vasut+renesas@gmail.com Cc: Nobuhiro Iwamatsu iwamatsu@nigauri.org --- arch/arm/mach-rmobile/Kconfig | 1 + board/renesas/rcar-common/common.c | 53 ++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+)
diff --git a/arch/arm/mach-rmobile/Kconfig b/arch/arm/mach-rmobile/Kconfig index aafeb355ef..52ab891425 100644 --- a/arch/arm/mach-rmobile/Kconfig +++ b/arch/arm/mach-rmobile/Kconfig @@ -21,6 +21,7 @@ config RCAR_GEN3 imply CMD_GPT imply CMD_UUID imply CMD_MMC_SWRITE if MMC + imply OF_BOARD_SETUP if PCI imply SUPPORT_EMMC_RPMB if MMC imply SPL imply SPL_BOARD_INIT diff --git a/board/renesas/rcar-common/common.c b/board/renesas/rcar-common/common.c index 292867e496..17127d4124 100644 --- a/board/renesas/rcar-common/common.c +++ b/board/renesas/rcar-common/common.c @@ -8,6 +8,8 @@ */
#include <common.h> +#include <dm.h> +#include <dm/uclass-internal.h> #include <asm/arch/rmobile.h>
#ifdef CONFIG_RCAR_GEN3 @@ -46,4 +48,55 @@ int dram_init_banksize(void)
return 0; } + +#if CONFIG_IS_ENABLED(OF_BOARD_SETUP) && CONFIG_IS_ENABLED(PCI) +int ft_board_setup(void *blob, bd_t *bd) +{ + struct udevice *dev; + struct uclass *uc; + fdt_addr_t regs_addr; + int i, off, ret; + + ret = uclass_get(UCLASS_PCI, &uc); + if (ret) + return ret; + + uclass_foreach_dev(dev, uc) { + struct pci_controller hose = { 0 }; + + /* + * Limit the number of memory regions to 2, which is the + * maximum that older Linux kernel versions can handle + * without aborting. + */ + for (i = 0; i < min(CONFIG_NR_DRAM_BANKS, 2); i++) { + if (hose.region_count == MAX_PCI_REGIONS) { + printf("maximum number of regions parsed, aborting\n"); + break; + } + + if (bd->bi_dram[i].size) { + pci_set_region(&hose.regions[hose.region_count++], + bd->bi_dram[i].start, + bd->bi_dram[i].start, + bd->bi_dram[i].size, + PCI_REGION_MEM | + PCI_REGION_SYS_MEMORY); + } + } + + regs_addr = devfdt_get_addr_index(dev, 0); + off = fdt_node_offset_by_compat_reg(blob, + "renesas,pcie-rcar-gen3", regs_addr); + if (off < 0) { + printf("Failed to find PCIe node@%llx\n", regs_addr); + return off; + } + + fdt_pci_dma_ranges(blob, off, &hose); + } + + return 0; +} +#endif #endif
participants (1)
-
Marek Vasut