summaryrefslogtreecommitdiff
path: root/arch/arm/cpu
diff options
context:
space:
mode:
authorYork Sun <yorksun@freescale.com>2015-03-20 19:28:11 -0700
committerYork Sun <yorksun@freescale.com>2015-04-23 08:55:56 -0700
commit12eaf31c0709840d6448d45ebfaecccadc34afa3 (patch)
tree1f7a0050e84866641c07288410e9f2564a965a37 /arch/arm/cpu
parent07c6600068da31d0f7c67ac3eb92dfc4270f4c07 (diff)
armv8/fsl-lsch3: Update early MMU table
During booting, IFC is mapped to low region. After booting up, IFC is remapped to high region for larger space. The environmental variables are also stored at high region. In order to read the variables during booting, a virtual mapping is required. Cache was enabled for entire IFC space before. Actually the first two entries are big enough (4MB) to cover the boot code and environmental variables. Remove extra entries. Move OCRAM entry out of ifdef. Signed-off-by: York Sun <yorksun@freescale.com>
Diffstat (limited to 'arch/arm/cpu')
-rw-r--r--arch/arm/cpu/armv8/fsl-lsch3/cpu.c56
1 files changed, 39 insertions, 17 deletions
diff --git a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
index 0e5aa5ca95..595dbd1d63 100644
--- a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
+++ b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
@@ -25,8 +25,9 @@ DECLARE_GLOBAL_DATA_PTR;
* levels of translation tables here to cover 40-bit address space.
* We use 4KB granule size, with 40 bits physical address, T0SZ=24
* Level 0 IA[39], table address @0
- * Level 1 IA[31:30], table address @01000, 0x2000
- * Level 2 IA[29:21], table address @0x3000
+ * Level 1 IA[31:30], table address @0x1000, 0x2000
+ * Level 2 IA[29:21], table address @0x3000, 0x4000
+ * Address above 0x5000 is free for other purpose.
*/
#define SECTION_SHIFT_L0 39UL
@@ -61,12 +62,12 @@ static inline void early_mmu_setup(void)
{
int el;
u64 i;
- u64 section_l1t0, section_l1t1, section_l2;
+ u64 section_l1t0, section_l1t1, section_l2t0, section_l2t1;
u64 *level0_table = (u64 *)CONFIG_SYS_FSL_OCRAM_BASE;
u64 *level1_table_0 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x1000);
u64 *level1_table_1 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x2000);
- u64 *level2_table = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x3000);
-
+ u64 *level2_table_0 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x3000);
+ u64 *level2_table_1 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x4000);
level0_table[0] =
(u64)level1_table_0 | PMD_TYPE_TABLE;
@@ -80,21 +81,25 @@ static inline void early_mmu_setup(void)
*/
section_l1t0 = 0;
section_l1t1 = BLOCK_SIZE_L0;
- section_l2 = 0;
+ section_l2t0 = 0;
+ section_l2t1 = CONFIG_SYS_FLASH_BASE;
for (i = 0; i < 512; i++) {
set_pgtable_section(level1_table_0, i, section_l1t0,
MT_DEVICE_NGNRNE);
set_pgtable_section(level1_table_1, i, section_l1t1,
MT_NORMAL);
- set_pgtable_section(level2_table, i, section_l2,
+ set_pgtable_section(level2_table_0, i, section_l2t0,
+ MT_DEVICE_NGNRNE);
+ set_pgtable_section(level2_table_1, i, section_l2t1,
MT_DEVICE_NGNRNE);
section_l1t0 += BLOCK_SIZE_L1;
section_l1t1 += BLOCK_SIZE_L1;
- section_l2 += BLOCK_SIZE_L2;
+ section_l2t0 += BLOCK_SIZE_L2;
+ section_l2t1 += BLOCK_SIZE_L2;
}
level1_table_0[0] =
- (u64)level2_table | PMD_TYPE_TABLE;
+ (u64)level2_table_0 | PMD_TYPE_TABLE;
level1_table_0[1] =
0x40000000 | PMD_SECT_AF | PMD_TYPE_SECT |
PMD_ATTRINDX(MT_DEVICE_NGNRNE);
@@ -105,17 +110,34 @@ static inline void early_mmu_setup(void)
0xc0000000 | PMD_SECT_AF | PMD_TYPE_SECT |
PMD_ATTRINDX(MT_NORMAL);
- /* Rewrite table to enable cache */
- set_pgtable_section(level2_table,
+ /* Rewerite table to enable cache for OCRAM */
+ set_pgtable_section(level2_table_0,
CONFIG_SYS_FSL_OCRAM_BASE >> SECTION_SHIFT_L2,
CONFIG_SYS_FSL_OCRAM_BASE,
MT_NORMAL);
- for (i = CONFIG_SYS_IFC_BASE >> SECTION_SHIFT_L2;
- i < (CONFIG_SYS_IFC_BASE + CONFIG_SYS_IFC_SIZE)
- >> SECTION_SHIFT_L2; i++) {
- section_l2 = i << SECTION_SHIFT_L2;
- set_pgtable_section(level2_table, i,
- section_l2, MT_NORMAL);
+
+#if defined(CONFIG_SYS_NOR0_CSPR_EARLY) && defined(CONFIG_SYS_NOR_AMASK_EARLY)
+ /* Rewrite table to enable cache for two entries (4MB) */
+ section_l2t1 = CONFIG_SYS_IFC_BASE;
+ set_pgtable_section(level2_table_0,
+ section_l2t1 >> SECTION_SHIFT_L2,
+ section_l2t1,
+ MT_NORMAL);
+ section_l2t1 += BLOCK_SIZE_L2;
+ set_pgtable_section(level2_table_0,
+ section_l2t1 >> SECTION_SHIFT_L2,
+ section_l2t1,
+ MT_NORMAL);
+#endif
+
+ /* Create a mapping for 256MB IFC region to final flash location */
+ level1_table_0[CONFIG_SYS_FLASH_BASE >> SECTION_SHIFT_L1] =
+ (u64)level2_table_1 | PMD_TYPE_TABLE;
+ section_l2t1 = CONFIG_SYS_IFC_BASE;
+ for (i = 0; i < 0x10000000 >> SECTION_SHIFT_L2; i++) {
+ set_pgtable_section(level2_table_1, i,
+ section_l2t1, MT_DEVICE_NGNRNE);
+ section_l2t1 += BLOCK_SIZE_L2;
}
el = current_el();