diff options
author | Ken Ma <make@marvell.com> | 2017-03-31 15:54:12 +0800 |
---|---|---|
committer | Hua Jing <jinghua@marvell.com> | 2017-04-25 04:17:25 +0300 |
commit | bf1cb8d4f6253e0b74d7097b11e15a0c23ed677b (patch) | |
tree | e7b6ed9075041a0c0ea4f2f02d4c8f2e9466b3f3 | |
parent | 5c7ad73cf49c4f1fd598e61a40f38284ff55484a (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.c | 3 | ||||
-rw-r--r-- | plat/marvell/a3700/common/dram_win.c | 159 | ||||
-rw-r--r-- | plat/marvell/a3700/common/include/dram_win.h | 1 | ||||
-rw-r--r-- | plat/marvell/a3700/common/include/platform_def.h | 4 |
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__ */ |