summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Ma <make@marvell.com>2017-03-31 15:54:12 +0800
committerHua Jing <jinghua@marvell.com>2017-04-25 04:17:25 +0300
commitbf1cb8d4f6253e0b74d7097b11e15a0c23ed677b (patch)
treee7b6ed9075041a0c0ea4f2f02d4c8f2e9466b3f3
parent5c7ad73cf49c4f1fd598e61a40f38284ff55484a (diff)
cpu-win: a3700: support 4GB DRAM CPU decode window configuration
- To support 4GB DRAM, CPU decode window needs to be updated: there are at most 5 configurable cpu decode windows and each window could only supports the size with 2 powers of N; since the address range is 4GB and Internal Regs, CCI-400 and Boot Rom windows hold fixed ranges, so it means that the configurable window size could be 2GB, 1GB, 512MB, 256MB...; and cpu dram windows number must increase to utilize memory as much as possible, they will take place of some unused cpu io windows; - If total dram size is more than 2GB, now there is only one case - 4GB dram, the cpu windows configuration is as below: - Internal Regs, CCI-400 and Boot Rom windows are kept as default; - Use 4 CPU decode windows for DRAM, which cover 3.75GB DRAM; since DDR window 0 is configured in tim header with 2GB size, this patch only configures cpu dram windows 1/2/3 with sizes of 1GB/256MB/512MB; - The only one CPU decode window left is for PCIe, which has 64MB address; - If total dram size is no more than 2GB, then pcie cpu window is modified to be aligned with 4GB dram's configuration, other cpu windows are kept as default. Change-Id: I178df27fd5a38d18472f35e7ba89227ef269572a Signed-off-by: Ken Ma <make@marvell.com> Reviewed-on: http://vgitil04.il.marvell.com:8080/38762 Reviewed-by: Hua Jing <jinghua@marvell.com> Tested-by: iSoC Platform CI <ykjenk@marvell.com>
-rw-r--r--plat/marvell/a3700/a3700/plat_bl31_setup.c3
-rw-r--r--plat/marvell/a3700/common/dram_win.c159
-rw-r--r--plat/marvell/a3700/common/include/dram_win.h1
-rw-r--r--plat/marvell/a3700/common/include/platform_def.h4
4 files changed, 167 insertions, 0 deletions
diff --git a/plat/marvell/a3700/a3700/plat_bl31_setup.c b/plat/marvell/a3700/a3700/plat_bl31_setup.c
index ed66f372..4b16bc23 100644
--- a/plat/marvell/a3700/a3700/plat_bl31_setup.c
+++ b/plat/marvell/a3700/a3700/plat_bl31_setup.c
@@ -90,6 +90,9 @@ void bl31_plat_arch_setup(void)
/* initiliaze the timer for delay functionality */
plat_delay_timer_init();
+ /* CPU address decoder windows initialization. */
+ cpu_wins_init();
+
/* Pass DRAM size value so that u-boot could get it later */
pass_dram_sys_info();
diff --git a/plat/marvell/a3700/common/dram_win.c b/plat/marvell/a3700/common/dram_win.c
index 094c8f53..24439ce0 100644
--- a/plat/marvell/a3700/common/dram_win.c
+++ b/plat/marvell/a3700/common/dram_win.c
@@ -37,6 +37,109 @@
#include <plat_marvell.h>
#include <io_addr_dec.h>
#include <dram_win.h>
+#include <a3700_dram_cs.h>
+
+/* Armada 3700 has 5 configurable windows */
+#define MV_CPU_WIN_NUM 5
+
+#define CPU_WIN_DISABLED 0
+#define CPU_WIN_ENABLED 1
+
+/*
+ * There are 2 different cpu decode window configuration cases:
+ * - DRAM size is not over 2GB;
+ * - DRAM size is 4GB.
+ */
+enum cpu_win_config_num {
+ CPU_WIN_CONFIG_DRAM_NOT_OVER_2GB = 0,
+ CPU_WIN_CONFIG_DRAM_4GB,
+ CPU_WIN_CONFIG_MAX
+};
+
+enum cpu_win_target {
+ CPU_WIN_TARGET_DRAM = 0,
+ CPU_WIN_TARGET_INTERNAL_REG,
+ CPU_WIN_TARGET_PCIE,
+ CPU_WIN_TARGET_PCIE_OVER_MCI,
+ CPU_WIN_TARGET_BOOT_ROM,
+ CPU_WIN_TARGET_MCI_EXTERNAL,
+ CPU_WIN_TARGET_RWTM_RAM = 7,
+ CPU_WIN_TARGET_CCI400_REG
+};
+
+struct cpu_win_configuration {
+ uint32_t enabled;
+ enum cpu_win_target target;
+ uint64_t base_addr;
+ uint64_t size;
+ uint64_t remap_addr;
+};
+
+struct cpu_win_configuration mv_cpu_wins[CPU_WIN_CONFIG_MAX][MV_CPU_WIN_NUM] = {
+ /*
+ * When total dram size is not over 2GB:
+ * DDR window 0 is configured in tim header, its size may be not 512MB but the
+ * actual dram size, no need to configure it again; the cpu pcie decode window is
+ * modified to be aligned with 4GB dram's configuration as below, other cpu windows
+ * are kept as default.
+ */
+ {
+ /* enabled target base size remap */
+ {CPU_WIN_ENABLED, CPU_WIN_TARGET_DRAM, 0x0, 0x08000000, 0x0},
+ {CPU_WIN_ENABLED, CPU_WIN_TARGET_MCI_EXTERNAL, 0xe0000000, 0x08000000, 0xe0000000},
+ {CPU_WIN_ENABLED, CPU_WIN_TARGET_PCIE, 0xd8200000, 0x04000000, 0xd8200000},
+ {CPU_WIN_ENABLED, CPU_WIN_TARGET_RWTM_RAM, 0xf0000000, 0x00020000, 0x1fff0000},
+ {CPU_WIN_ENABLED, CPU_WIN_TARGET_PCIE_OVER_MCI, 0x80000000, 0x10000000, 0x80000000},
+ },
+
+ /*
+ * If total dram size is more than 2GB, now there is only one case - 4GB dram;
+ * we will use below cpu windows configurations:
+ * - Internal Regs, CCI-400 and Boot Rom windows are kept as default;
+ * - Use 4 CPU decode windows for DRAM, which cover 3.75GB DRAM; DDR window
+ * 0 is configured in tim header with 2GB size, no need to configure it again here;
+ * - The only one CPU decode window left is for PCIe, which has 32MB address.
+
+ 0xFFFFFFFF ---> |-----------------------|
+ | Boot ROM | 64KB
+ 0xFFF00000 ---> +-----------------------+
+ : :
+ 0xFC200000 ---> +-----------------------+
+ | DDR window 3 | 512 MB
+ 0xDC200000 ---> |-----------------------|
+ | PCIE | 64 MB
+ 0xD8200000 ---> |-----------------------|
+ : :
+ 0xD8010000 ---> |-----------------------|
+ | CCI Regs | 64 KB
+ 0xD8000000 ---> +-----------------------+
+ : :
+ : :
+ 0xD2000000 ---> +-----------------------+
+ | Internal Regs | 32MB
+ 0xD0000000 ---> |-----------------------|
+ | DDR window 2 | 256 MB
+ 0xC0000000 ---> |-----------------------|
+ | |
+ | DDR window 1 | 1 GB
+ | |
+ 0x80000000 ---> |-----------------------|
+ | |
+ | |
+ | DDR window 0 | 2 GB
+ | |
+ | |
+ 0x00000000 ---> +-----------------------+
+ */
+ {
+ /* win_id target base size remap */
+ {CPU_WIN_ENABLED, CPU_WIN_TARGET_DRAM, 0x0, 0x80000000, 0x0},
+ {CPU_WIN_ENABLED, CPU_WIN_TARGET_DRAM, 0x80000000, 0x40000000, 0x80000000},
+ {CPU_WIN_ENABLED, CPU_WIN_TARGET_DRAM, 0xc0000000, 0x10000000, 0xc0000000},
+ {CPU_WIN_ENABLED, CPU_WIN_TARGET_DRAM, 0xdc200000, 0x20000000, 0xd0000000},
+ {CPU_WIN_ENABLED, CPU_WIN_TARGET_PCIE, 0xd8200000, 0x04000000, 0xd8200000},
+ },
+};
/*
* dram_win_map_build
@@ -87,3 +190,59 @@ void dram_win_map_build(struct dram_win_map *win_map)
return;
}
+static void cpu_win_set(uint32_t win_id, struct cpu_win_configuration *win_cfg)
+{
+ uint32_t base_reg, ctrl_reg, size_reg, remap_reg;
+
+ /* Disable window */
+ ctrl_reg = mmio_read_32(CPU_DEC_WIN_CTRL_REG(win_id));
+ ctrl_reg &= ~CPU_DEC_CR_WIN_ENABLE;
+ mmio_write_32(CPU_DEC_WIN_CTRL_REG(win_id), ctrl_reg);
+
+ /* For an disabled window, only disable it. */
+ if (!win_cfg->enabled)
+ return;
+
+ /* Set Base Register */
+ base_reg = (uint32_t)(win_cfg->base_addr / CPU_DEC_CR_WIN_SIZE_ALIGNMENT);
+ base_reg <<= CPU_DEC_BR_BASE_OFFS;
+ base_reg &= CPU_DEC_BR_BASE_MASK;
+ mmio_write_32(CPU_DEC_WIN_BASE_REG(win_id), base_reg);
+
+ /* Set Remap Register with the same value as the <Base> field in Base Register */
+ remap_reg = (uint32_t)(win_cfg->remap_addr / CPU_DEC_CR_WIN_SIZE_ALIGNMENT);
+ remap_reg <<= CPU_DEC_RLR_REMAP_LOW_OFFS;
+ remap_reg &= CPU_DEC_RLR_REMAP_LOW_MASK;
+ mmio_write_32(CPU_DEC_REMAP_LOW_REG(win_id), remap_reg);
+
+ /* Set Size Register */
+ size_reg = (win_cfg->size / CPU_DEC_CR_WIN_SIZE_ALIGNMENT) - 1;
+ size_reg <<= CPU_DEC_CR_WIN_SIZE_OFFS;
+ size_reg &= CPU_DEC_CR_WIN_SIZE_MASK;
+ mmio_write_32(CPU_DEC_WIN_SIZE_REG(win_id), size_reg);
+
+ /* Set Control Register - set target id and enable window */
+ ctrl_reg &= ~CPU_DEC_CR_WIN_TARGET_MASK;
+ ctrl_reg |= (win_cfg->target << CPU_DEC_CR_WIN_TARGET_OFFS);
+ ctrl_reg |= CPU_DEC_CR_WIN_ENABLE;
+ mmio_write_32(CPU_DEC_WIN_CTRL_REG(win_id), ctrl_reg);
+}
+
+void cpu_wins_init(void)
+{
+ uint32_t cfg_idx, win_id, cs_id, base_low, base_high, size_mbytes, total_mbytes = 0;
+
+ for (cs_id = 0; cs_id < MVEBU_MAX_CS_MMAP_NUM; cs_id++)
+ if (!marvell_get_dram_cs_base_size(cs_id, &base_low, &base_high, &size_mbytes))
+ total_mbytes += size_mbytes;
+
+ if (total_mbytes <= 2048)
+ cfg_idx = CPU_WIN_CONFIG_DRAM_NOT_OVER_2GB;
+ else
+ cfg_idx = CPU_WIN_CONFIG_DRAM_4GB;
+
+ /* Window 0 is configured always for DRAM in tim header already, no need to configure it again here */
+ for (win_id = 1; win_id < MV_CPU_WIN_NUM; win_id++)
+ cpu_win_set(win_id, &mv_cpu_wins[cfg_idx][win_id]);
+}
+
diff --git a/plat/marvell/a3700/common/include/dram_win.h b/plat/marvell/a3700/common/include/dram_win.h
index ebc8ecb4..61640860 100644
--- a/plat/marvell/a3700/common/include/dram_win.h
+++ b/plat/marvell/a3700/common/include/dram_win.h
@@ -36,6 +36,7 @@
#define _DRAM_WIN_H_
void dram_win_map_build(struct dram_win_map *win_map);
+void cpu_wins_init(void);
#endif /* _DRAM_WIN_H_ */
diff --git a/plat/marvell/a3700/common/include/platform_def.h b/plat/marvell/a3700/common/include/platform_def.h
index d7f9c23d..75266811 100644
--- a/plat/marvell/a3700/common/include/platform_def.h
+++ b/plat/marvell/a3700/common/include/platform_def.h
@@ -195,4 +195,8 @@ Trusted SRAM section 0x4000000..0x4200000:
#define CPU_DEC_BR_BASE_OFFS 0
#define CPU_DEC_BR_BASE_MASK (0xffff << CPU_DEC_BR_BASE_OFFS)
+#define CPU_DEC_REMAP_LOW_REG(win_num) (MVEBU_CPU_DEC_WIN_REG_BASE + 0xC + (win_num) * 0x10)
+#define CPU_DEC_RLR_REMAP_LOW_OFFS 0
+#define CPU_DEC_RLR_REMAP_LOW_MASK (0xffff << CPU_DEC_BR_BASE_OFFS)
+
#endif /* __PLATFORM_DEF_H__ */