From patchwork Wed Apr 8 17:25:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 237442 List-Id: U-Boot discussion From: marek.behun at nic.cz (=?UTF-8?q?Marek=20Beh=C3=BAn?=) Date: Wed, 8 Apr 2020 19:25:18 +0200 Subject: [PATCH v1 u-boot-marvell 1/5] arm64: mvebu: armada-8k: move dram init code In-Reply-To: <20200408172522.18941-1-marek.behun@nic.cz> References: <20200408172522.18941-1-marek.behun@nic.cz> Message-ID: <20200408172522.18941-2-marek.behun@nic.cz> Move Armada-8k specific DRAM init code into armada-8k specific directory. Signed-off-by: Marek Beh?n Reviewed-by: Stefan Roese --- arch/arm/mach-mvebu/arm64-common.c | 46 +---------------------- arch/arm/mach-mvebu/armada8k/Makefile | 3 +- arch/arm/mach-mvebu/armada8k/dram.c | 52 ++++++++++++++++++++++++++ arch/arm/mach-mvebu/include/mach/cpu.h | 4 ++ 4 files changed, 59 insertions(+), 46 deletions(-) create mode 100644 arch/arm/mach-mvebu/armada8k/dram.c diff --git a/arch/arm/mach-mvebu/arm64-common.c b/arch/arm/mach-mvebu/arm64-common.c index 40b98dbf08..244ea49d8a 100644 --- a/arch/arm/mach-mvebu/arm64-common.c +++ b/arch/arm/mach-mvebu/arm64-common.c @@ -45,54 +45,12 @@ const struct mbus_dram_target_info *mvebu_mbus_dram_info(void) return NULL; } -/* DRAM init code ... */ - -#define MV_SIP_DRAM_SIZE 0x82000010 - -static u64 a8k_dram_scan_ap_sz(void) -{ - struct pt_regs pregs; - - pregs.regs[0] = MV_SIP_DRAM_SIZE; - pregs.regs[1] = SOC_REGS_PHY_BASE; - smc_call(&pregs); - - return pregs.regs[0]; -} - -static void a8k_dram_init_banksize(void) -{ - /* - * The firmware (ATF) leaves a 1G whole above the 3G mark for IO - * devices. Higher RAM is mapped at 4G. - * - * Config 2 DRAM banks: - * Bank 0 - max size 4G - 1G - * Bank 1 - ram size - 4G + 1G - */ - phys_size_t max_bank0_size = SZ_4G - SZ_1G; - - gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; - if (gd->ram_size <= max_bank0_size) { - gd->bd->bi_dram[0].size = gd->ram_size; - return; - } - - gd->bd->bi_dram[0].size = max_bank0_size; - if (CONFIG_NR_DRAM_BANKS > 1) { - gd->bd->bi_dram[1].start = SZ_4G; - gd->bd->bi_dram[1].size = gd->ram_size - max_bank0_size; - } -} - __weak int dram_init_banksize(void) { if (CONFIG_IS_ENABLED(ARMADA_8K)) - a8k_dram_init_banksize(); + return a8k_dram_init_banksize(); else - fdtdec_setup_memory_banksize(); - - return 0; + return fdtdec_setup_memory_banksize(); } __weak int dram_init(void) diff --git a/arch/arm/mach-mvebu/armada8k/Makefile b/arch/arm/mach-mvebu/armada8k/Makefile index 82cb25b417..0a4756717a 100644 --- a/arch/arm/mach-mvebu/armada8k/Makefile +++ b/arch/arm/mach-mvebu/armada8k/Makefile @@ -2,5 +2,4 @@ # # Copyright (C) 2016 Stefan Roese -obj-y = cpu.o -obj-y += cache_llc.o +obj-y = cpu.o cache_llc.o dram.o diff --git a/arch/arm/mach-mvebu/armada8k/dram.c b/arch/arm/mach-mvebu/armada8k/dram.c new file mode 100644 index 0000000000..265a8b0ae8 --- /dev/null +++ b/arch/arm/mach-mvebu/armada8k/dram.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016 Stefan Roese + */ + +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define MV_SIP_DRAM_SIZE 0x82000010 + +u64 a8k_dram_scan_ap_sz(void) +{ + struct pt_regs pregs; + + pregs.regs[0] = MV_SIP_DRAM_SIZE; + pregs.regs[1] = SOC_REGS_PHY_BASE; + smc_call(&pregs); + + return pregs.regs[0]; +} + +int a8k_dram_init_banksize(void) +{ + /* + * The firmware (ATF) leaves a 1G whole above the 3G mark for IO + * devices. Higher RAM is mapped at 4G. + * + * Config 2 DRAM banks: + * Bank 0 - max size 4G - 1G + * Bank 1 - ram size - 4G + 1G + */ + phys_size_t max_bank0_size = SZ_4G - SZ_1G; + + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + if (gd->ram_size <= max_bank0_size) { + gd->bd->bi_dram[0].size = gd->ram_size; + return 0; + } + + gd->bd->bi_dram[0].size = max_bank0_size; + if (CONFIG_NR_DRAM_BANKS > 1) { + gd->bd->bi_dram[1].start = SZ_4G; + gd->bd->bi_dram[1].size = gd->ram_size - max_bank0_size; + } + + return 0; +} diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h index 2e2d72aac8..7af8e5d09f 100644 --- a/arch/arm/mach-mvebu/include/mach/cpu.h +++ b/arch/arm/mach-mvebu/include/mach/cpu.h @@ -170,6 +170,10 @@ void mv_avs_init(void); static inline void mv_avs_init(void) {} #endif +/* A8K dram functions */ +u64 a8k_dram_scan_ap_sz(void); +int a8k_dram_init_banksize(void); + /* * get_ref_clk * From patchwork Wed Apr 8 17:25:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 237445 List-Id: U-Boot discussion From: marek.behun at nic.cz (=?UTF-8?q?Marek=20Beh=C3=BAn?=) Date: Wed, 8 Apr 2020 19:25:19 +0200 Subject: [PATCH v1 u-boot-marvell 2/5] arm64: mvebu: a37xx: improve code determining memory info structures In-Reply-To: <20200408172522.18941-1-marek.behun@nic.cz> References: <20200408172522.18941-1-marek.behun@nic.cz> Message-ID: <20200408172522.18941-3-marek.behun@nic.cz> Currently on Armada-37xx the mem_map structure is statically defined to map first 2 GB of memory as RAM region, and system registers and PCIe region device region. This is insufficient for when there is more RAM or when for example the PCIe windows is mapped to another address by the CPU Address Decoder. In the case when the board has 4 GB RAM, on some boards the ARM Trusted Firmware can move the PCIe window to another address, in order to maximize possible usable RAM. Also the dram_init and dram_init_banksize looks for information in device-tree, and therefore different device trees are needed for boards with different RAM sizes. Therefore we add code that looks at how the ARM Trusted Firmware has configured the CPU Address Decoder windows, and then we update the mem_map structure and compute gd->ram_size and gd->bd->bi_dram bank base addresses and sizes accordingly. Signed-off-by: Marek Beh?n Reviewed-by: Stefan Roese --- arch/arm/mach-mvebu/arm64-common.c | 5 + arch/arm/mach-mvebu/armada3700/cpu.c | 252 ++++++++++++++++++++++--- arch/arm/mach-mvebu/include/mach/cpu.h | 4 + 3 files changed, 235 insertions(+), 26 deletions(-) diff --git a/arch/arm/mach-mvebu/arm64-common.c b/arch/arm/mach-mvebu/arm64-common.c index 244ea49d8a..34cc0479a8 100644 --- a/arch/arm/mach-mvebu/arm64-common.c +++ b/arch/arm/mach-mvebu/arm64-common.c @@ -49,6 +49,8 @@ __weak int dram_init_banksize(void) { if (CONFIG_IS_ENABLED(ARMADA_8K)) return a8k_dram_init_banksize(); + else if (CONFIG_IS_ENABLED(ARMADA_3700)) + return a3700_dram_init_banksize(); else return fdtdec_setup_memory_banksize(); } @@ -61,6 +63,9 @@ __weak int dram_init(void) return 0; } + if (CONFIG_IS_ENABLED(ARMADA_3700)) + return a3700_dram_init(); + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; diff --git a/arch/arm/mach-mvebu/armada3700/cpu.c b/arch/arm/mach-mvebu/armada3700/cpu.c index c83268181b..959a909d8a 100644 --- a/arch/arm/mach-mvebu/armada3700/cpu.c +++ b/arch/arm/mach-mvebu/armada3700/cpu.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2016 Stefan Roese + * Copyright (C) 2020 Marek Behun */ #include @@ -13,6 +14,7 @@ #include #include #include +#include /* Armada 3700 */ #define MVEBU_GPIO_NB_REG_BASE (MVEBU_REGISTER(0x13800)) @@ -26,39 +28,237 @@ #define MVEBU_NB_WARM_RST_REG (MVEBU_GPIO_NB_REG_BASE + 0x40) #define MVEBU_NB_WARM_RST_MAGIC_NUM 0x1d1e -static struct mm_region mvebu_mem_map[] = { - { - /* RAM */ - .phys = 0x0UL, - .virt = 0x0UL, - .size = 0x80000000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | - PTE_BLOCK_INNER_SHARE - }, +/* Armada 3700 CPU Address Decoder registers */ +#define MVEBU_CPU_DEC_WIN_REG_BASE (size_t)(MVEBU_REGISTER(0xcf00)) +#define MVEBU_CPU_DEC_WIN_CTRL(w) \ + (MVEBU_CPU_DEC_WIN_REG_BASE + ((w) << 4)) +#define MVEBU_CPU_DEC_WIN_CTRL_EN BIT(0) +#define MVEBU_CPU_DEC_WIN_CTRL_TGT_MASK 0xf +#define MVEBU_CPU_DEC_WIN_CTRL_TGT_OFFS 4 +#define MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM 0 +#define MVEBU_CPU_DEC_WIN_CTRL_TGT_PCIE 2 +#define MVEBU_CPU_DEC_WIN_SIZE(w) (MVEBU_CPU_DEC_WIN_CTRL(w) + 0x4) +#define MVEBU_CPU_DEC_WIN_BASE(w) (MVEBU_CPU_DEC_WIN_CTRL(w) + 0x8) +#define MVEBU_CPU_DEC_WIN_REMAP(w) (MVEBU_CPU_DEC_WIN_CTRL(w) + 0xc) +#define MVEBU_CPU_DEC_WIN_GRANULARITY 16 +#define MVEBU_CPU_DEC_WINS 5 + +#define MAX_MEM_MAP_REGIONS (MVEBU_CPU_DEC_WINS + 2) + +#define A3700_PTE_BLOCK_NORMAL \ + (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE) +#define A3700_PTE_BLOCK_DEVICE \ + (PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE) + +DECLARE_GLOBAL_DATA_PTR; + +static struct mm_region mvebu_mem_map[MAX_MEM_MAP_REGIONS] = { { - /* SRAM, MMIO regions */ - .phys = 0xd0000000UL, - .virt = 0xd0000000UL, + /* + * SRAM, MMIO regions + * Don't remove this, a3700_build_mem_map needs it. + */ + .phys = SOC_REGS_PHY_BASE, + .virt = SOC_REGS_PHY_BASE, .size = 0x02000000UL, /* 32MiB internal registers */ - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE - }, - { - /* PCI regions */ - .phys = 0xe8000000UL, - .virt = 0xe8000000UL, - .size = 0x02000000UL, /* 32MiB master PCI space */ - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE + .attrs = A3700_PTE_BLOCK_DEVICE }, - { - /* List terminator */ - 0, - } }; struct mm_region *mem_map = mvebu_mem_map; +static int get_cpu_dec_win(int win, u32 *tgt, u32 *base, u32 *size) +{ + u32 reg; + + reg = readl(MVEBU_CPU_DEC_WIN_CTRL(win)); + if (!(reg & MVEBU_CPU_DEC_WIN_CTRL_EN)) + return -1; + + if (tgt) { + reg >>= MVEBU_CPU_DEC_WIN_CTRL_TGT_OFFS; + reg &= MVEBU_CPU_DEC_WIN_CTRL_TGT_MASK; + *tgt = reg; + } + + if (base) { + reg = readl(MVEBU_CPU_DEC_WIN_BASE(win)); + *base = reg << MVEBU_CPU_DEC_WIN_GRANULARITY; + } + + if (size) { + /* + * Window size is encoded as the number of 1s from LSB to MSB, + * followed by 0s. The number of 1s specifies the size in 64 KiB + * granularity. + */ + reg = readl(MVEBU_CPU_DEC_WIN_SIZE(win)); + *size = ((reg + 1) << MVEBU_CPU_DEC_WIN_GRANULARITY); + } + + return 0; +} + +/* + * Builds mem_map according to CPU Address Decoder settings, which were set by + * the TIMH image on the Cortex-M3 secure processor, or by ARM Trusted Firmware + */ +static void build_mem_map(void) +{ + int win, region; + + region = 1; + for (win = 0; win < MVEBU_CPU_DEC_WINS; ++win) { + u32 base, tgt, size; + u64 attrs; + + /* skip disabled windows */ + if (get_cpu_dec_win(win, &tgt, &base, &size)) + continue; + + if (tgt == MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM) + attrs = A3700_PTE_BLOCK_NORMAL; + else if (tgt == MVEBU_CPU_DEC_WIN_CTRL_TGT_PCIE) + attrs = A3700_PTE_BLOCK_DEVICE; + else + /* skip windows with other targets */ + continue; + + mvebu_mem_map[region].phys = base; + mvebu_mem_map[region].virt = base; + mvebu_mem_map[region].size = size; + mvebu_mem_map[region].attrs = attrs; + ++region; + } + + /* add list terminator */ + mvebu_mem_map[region].size = 0; + mvebu_mem_map[region].attrs = 0; +} + +void enable_caches(void) +{ + build_mem_map(); + + icache_enable(); + dcache_enable(); +} + +int a3700_dram_init(void) +{ + int win; + + gd->ram_size = 0; + for (win = 0; win < MVEBU_CPU_DEC_WINS; ++win) { + u32 base, tgt, size; + + /* skip disabled windows */ + if (get_cpu_dec_win(win, &tgt, &base, &size)) + continue; + + /* skip non-DRAM windows */ + if (tgt != MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM) + continue; + + /* + * It is possible that one image was built for boards with + * different RAM sizes, for example 512 MiB and 1 GiB. + * We therefore try to determine the actual RAM size in the + * window with get_ram_size. + */ + gd->ram_size += get_ram_size((void *)(size_t)base, size); + } + + return 0; +} + +struct a3700_dram_window { + size_t base, size; +}; + +static int dram_win_cmp(const void *a, const void *b) +{ + size_t ab, bb; + + ab = ((const struct a3700_dram_window *)a)->base; + bb = ((const struct a3700_dram_window *)b)->base; + + if (ab < bb) + return -1; + else if (ab > bb) + return 1; + else + return 0; +} + +int a3700_dram_init_banksize(void) +{ + struct a3700_dram_window dram_wins[MVEBU_CPU_DEC_WINS]; + int bank, win, ndram_wins; + u32 last_end; + size_t size; + + ndram_wins = 0; + for (win = 0; win < MVEBU_CPU_DEC_WINS; ++win) { + u32 base, tgt, size; + + /* skip disabled windows */ + if (get_cpu_dec_win(win, &tgt, &base, &size)) + continue; + + /* skip non-DRAM windows */ + if (tgt != MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM) + continue; + + dram_wins[win].base = base; + dram_wins[win].size = size; + ++ndram_wins; + } + + qsort(dram_wins, ndram_wins, sizeof(dram_wins[0]), dram_win_cmp); + + bank = 0; + last_end = -1; + + for (win = 0; win < ndram_wins; ++win) { + /* again determining actual RAM size as in a3700_dram_init */ + size = get_ram_size((void *)dram_wins[win].base, + dram_wins[win].size); + + /* + * Check if previous window ends as the current starts. If yes, + * merge these windows into one "bank". This is possible by this + * simple check thanks to mem_map regions being qsorted in + * build_mem_map. + */ + if (last_end == dram_wins[win].base) { + gd->bd->bi_dram[bank - 1].size += size; + last_end += size; + } else { + if (bank == CONFIG_NR_DRAM_BANKS) { + printf("Need more CONFIG_NR_DRAM_BANKS\n"); + return -ENOBUFS; + } + + gd->bd->bi_dram[bank].start = dram_wins[win].base; + gd->bd->bi_dram[bank].size = size; + last_end = dram_wins[win].base + size; + ++bank; + } + } + + /* + * If there is more place for DRAM BANKS definitions than needed, fill + * the rest with zeros. + */ + for (; bank < CONFIG_NR_DRAM_BANKS; ++bank) { + gd->bd->bi_dram[bank].start = 0; + gd->bd->bi_dram[bank].size = 0; + } + + return 0; +} + void reset_cpu(ulong ignored) { /* diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h index 7af8e5d09f..2a53329420 100644 --- a/arch/arm/mach-mvebu/include/mach/cpu.h +++ b/arch/arm/mach-mvebu/include/mach/cpu.h @@ -174,6 +174,10 @@ static inline void mv_avs_init(void) {} u64 a8k_dram_scan_ap_sz(void); int a8k_dram_init_banksize(void); +/* A3700 dram functions */ +int a3700_dram_init(void); +int a3700_dram_init_banksize(void); + /* * get_ref_clk * From patchwork Wed Apr 8 17:25:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 237443 List-Id: U-Boot discussion From: marek.behun at nic.cz (=?UTF-8?q?Marek=20Beh=C3=BAn?=) Date: Wed, 8 Apr 2020 19:25:20 +0200 Subject: [PATCH v1 u-boot-marvell 3/5] arm: mvebu: turris_mox: support devices with RAM > 1 GB In-Reply-To: <20200408172522.18941-1-marek.behun@nic.cz> References: <20200408172522.18941-1-marek.behun@nic.cz> Message-ID: <20200408172522.18941-4-marek.behun@nic.cz> In order to support MOX boards with 2 GB or 4 GB RAM, we use the new Armada-3700 generic code for memory information structures. This is done by removing dram_init and dram_init_banksize from turris_mox.c, in order for the generic, weak definitions to be used. Also for boards with 4 GB RAM it is needed to increase CONFIG_NR_DRAM_BANKS to 2 in turris_mox_defconfig. Signed-off-by: Marek Beh?n Reviewed-by: Stefan Roese --- board/CZ.NIC/turris_mox/turris_mox.c | 16 ---------------- configs/turris_mox_defconfig | 2 +- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/board/CZ.NIC/turris_mox/turris_mox.c b/board/CZ.NIC/turris_mox/turris_mox.c index 5bb53b1260..8e4c023103 100644 --- a/board/CZ.NIC/turris_mox/turris_mox.c +++ b/board/CZ.NIC/turris_mox/turris_mox.c @@ -43,22 +43,6 @@ DECLARE_GLOBAL_DATA_PTR; -int dram_init(void) -{ - gd->ram_base = 0; - gd->ram_size = (phys_size_t)get_ram_size(0, 0x40000000); - - return 0; -} - -int dram_init_banksize(void) -{ - gd->bd->bi_dram[0].start = (phys_addr_t)0; - gd->bd->bi_dram[0].size = gd->ram_size; - - return 0; -} - #if defined(CONFIG_OF_BOARD_FIXUP) int board_fix_fdt(void *blob) { diff --git a/configs/turris_mox_defconfig b/configs/turris_mox_defconfig index 3bc69cda4d..d786255d1d 100644 --- a/configs/turris_mox_defconfig +++ b/configs/turris_mox_defconfig @@ -8,7 +8,7 @@ CONFIG_ENV_SIZE=0x10000 CONFIG_ENV_SECT_SIZE=0x10000 CONFIG_ENV_OFFSET=0x180000 CONFIG_DM_GPIO=y -CONFIG_NR_DRAM_BANKS=1 +CONFIG_NR_DRAM_BANKS=2 CONFIG_DEBUG_UART_BASE=0xd0012000 CONFIG_DEBUG_UART_CLOCK=25804800 CONFIG_DEBUG_UART=y From patchwork Wed Apr 8 17:25:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 237444 List-Id: U-Boot discussion From: marek.behun at nic.cz (=?UTF-8?q?Marek=20Beh=C3=BAn?=) Date: Wed, 8 Apr 2020 19:25:21 +0200 Subject: [PATCH v1 u-boot-marvell 4/5] arm64: mvebu: a37xx: add device-tree fixer for PCIe regions In-Reply-To: <20200408172522.18941-1-marek.behun@nic.cz> References: <20200408172522.18941-1-marek.behun@nic.cz> Message-ID: <20200408172522.18941-5-marek.behun@nic.cz> In case when ARM Trusted Firmware changes the default address of PCIe regions (which can be done for devices with 4 GB RAM to maximize the amount of RAM the device can use) we add code that looks at how ATF changed the PCIe windows in the CPU Address Decoder and changes given device-tree blob accordingly. Signed-off-by: Marek Beh?n Reviewed-by: Stefan Roese --- arch/arm/mach-mvebu/armada3700/cpu.c | 52 ++++++++++++++++++++++++++ arch/arm/mach-mvebu/include/mach/cpu.h | 3 ++ 2 files changed, 55 insertions(+) diff --git a/arch/arm/mach-mvebu/armada3700/cpu.c b/arch/arm/mach-mvebu/armada3700/cpu.c index 959a909d8a..17d2d43bab 100644 --- a/arch/arm/mach-mvebu/armada3700/cpu.c +++ b/arch/arm/mach-mvebu/armada3700/cpu.c @@ -50,6 +50,8 @@ #define A3700_PTE_BLOCK_DEVICE \ (PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE) +#define PCIE_PATH "/soc/pcie at d0070000" + DECLARE_GLOBAL_DATA_PTR; static struct mm_region mvebu_mem_map[MAX_MEM_MAP_REGIONS] = { @@ -259,6 +261,56 @@ int a3700_dram_init_banksize(void) return 0; } +static u32 find_pcie_window_base(void) +{ + int win; + + for (win = 0; win < MVEBU_CPU_DEC_WINS; ++win) { + u32 base, tgt; + + /* skip disabled windows */ + if (get_cpu_dec_win(win, &tgt, &base, NULL)) + continue; + + if (tgt == MVEBU_CPU_DEC_WIN_CTRL_TGT_PCIE) + return base; + } + + return -1; +} + +int a3700_fdt_fix_pcie_regions(void *blob) +{ + u32 new_ranges[14], base; + const u32 *ranges; + int node, len; + + node = fdt_path_offset(blob, PCIE_PATH); + if (node < 0) + return node; + + ranges = fdt_getprop(blob, node, "ranges", &len); + if (!ranges) + return -ENOENT; + + if (len != sizeof(new_ranges)) + return -EINVAL; + + memcpy(new_ranges, ranges, len); + + base = find_pcie_window_base(); + if (base == -1) + return -ENOENT; + + new_ranges[2] = cpu_to_fdt32(base); + new_ranges[4] = new_ranges[2]; + + new_ranges[9] = cpu_to_fdt32(base + 0x1000000); + new_ranges[11] = new_ranges[9]; + + return fdt_setprop_inplace(blob, node, "ranges", new_ranges, len); +} + void reset_cpu(ulong ignored) { /* diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h index 2a53329420..1d619c4e49 100644 --- a/arch/arm/mach-mvebu/include/mach/cpu.h +++ b/arch/arm/mach-mvebu/include/mach/cpu.h @@ -178,6 +178,9 @@ int a8k_dram_init_banksize(void); int a3700_dram_init(void); int a3700_dram_init_banksize(void); +/* A3700 PCIe regions fixer for device tree */ +int a3700_fdt_fix_pcie_regions(void *blob); + /* * get_ref_clk * From patchwork Wed Apr 8 17:25:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 237446 List-Id: U-Boot discussion From: marek.behun at nic.cz (=?UTF-8?q?Marek=20Beh=C3=BAn?=) Date: Wed, 8 Apr 2020 19:25:22 +0200 Subject: [PATCH v1 u-boot-marvell 5/5] arm: mvebu: turris_mox: fix PCIe ranges in device tree In-Reply-To: <20200408172522.18941-1-marek.behun@nic.cz> References: <20200408172522.18941-1-marek.behun@nic.cz> Message-ID: <20200408172522.18941-6-marek.behun@nic.cz> Use the new a3700_fdt_fix_pcie_regions function in turris_mox.c so that MOX boards with 4 GB RAM are fully supported. Signed-off-by: Marek Beh?n Reviewed-by: Stefan Roese --- board/CZ.NIC/turris_mox/turris_mox.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/board/CZ.NIC/turris_mox/turris_mox.c b/board/CZ.NIC/turris_mox/turris_mox.c index 8e4c023103..470ea32f9c 100644 --- a/board/CZ.NIC/turris_mox/turris_mox.c +++ b/board/CZ.NIC/turris_mox/turris_mox.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -104,6 +105,11 @@ int board_fix_fdt(void *blob) return 0; } + if (a3700_fdt_fix_pcie_regions(blob) < 0) { + printf("Cannot fix PCIe regions in U-Boot's device tree!\n"); + return 0; + } + return 0; } #endif @@ -708,6 +714,11 @@ int ft_board_setup(void *blob, bd_t *bd) res = fdt_setprop_string(blob, node, "status", "okay"); if (res < 0) return res; + + /* Fix PCIe regions for devices with 4 GB RAM */ + res = a3700_fdt_fix_pcie_regions(blob); + if (res < 0) + return res; } /*