summaryrefslogtreecommitdiffstats
path: root/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/cpu/armv8/fsl-lsch3/cpu.c')
-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();
OpenPOWER on IntegriCloud