Pali Rohár | aaed328 | 2022-05-06 11:05:14 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
| 2 | |
| 3 | #include <config.h> |
| 4 | #include <linux/linkage.h> |
Pali Rohár | 596f05b | 2022-09-08 16:06:52 +0200 | [diff] [blame] | 5 | #include <asm/system.h> |
Pali Rohár | ae1244c | 2022-09-08 16:06:54 +0200 | [diff] [blame] | 6 | #include <asm/pl310.h> |
Pali Rohár | aaed328 | 2022-05-06 11:05:14 +0200 | [diff] [blame] | 7 | |
| 8 | ENTRY(arch_very_early_init) |
| 9 | #ifdef CONFIG_ARMADA_38X |
| 10 | /* |
| 11 | * Only with disabled MMU its possible to switch the base |
| 12 | * register address on Armada 38x. Without this the SDRAM |
| 13 | * located at >= 0x4000.0000 is also not accessible, as its |
| 14 | * still locked to cache. |
Pali Rohár | ae1244c | 2022-09-08 16:06:54 +0200 | [diff] [blame] | 15 | * |
| 16 | * So to fully release / unlock this area from cache, we need |
| 17 | * to first flush all caches, then disable the MMU and |
| 18 | * disable the L2 cache. |
Pali Rohár | aaed328 | 2022-05-06 11:05:14 +0200 | [diff] [blame] | 19 | */ |
Pali Rohár | ae1244c | 2022-09-08 16:06:54 +0200 | [diff] [blame] | 20 | |
| 21 | /* Invalidate L1 I/D */ |
| 22 | mov r0, #0 @ set up for MCR |
| 23 | mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs |
| 24 | mcr p15, 0, r0, c7, c5, 0 @ invalidate icache |
| 25 | mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array |
| 26 | mcr p15, 0, r0, c7, c10, 4 @ DSB |
| 27 | mcr p15, 0, r0, c7, c5, 4 @ ISB |
| 28 | |
| 29 | /* Disable MMU */ |
Pali Rohár | aaed328 | 2022-05-06 11:05:14 +0200 | [diff] [blame] | 30 | mrc p15, 0, r0, c1, c0, 0 |
Pali Rohár | 596f05b | 2022-09-08 16:06:52 +0200 | [diff] [blame] | 31 | bic r0, #CR_M |
Pali Rohár | aaed328 | 2022-05-06 11:05:14 +0200 | [diff] [blame] | 32 | mcr p15, 0, r0, c1, c0, 0 |
Pali Rohár | ae1244c | 2022-09-08 16:06:54 +0200 | [diff] [blame] | 33 | |
| 34 | /* |
| 35 | * Disable L2 cache |
| 36 | * |
| 37 | * NOTE: Internal registers are still at address INTREG_BASE_ADDR_REG |
| 38 | * but CONFIG_SYS_PL310_BASE is already calculated from base |
| 39 | * address SOC_REGS_PHY_BASE. |
| 40 | */ |
| 41 | ldr r1, =(CONFIG_SYS_PL310_BASE - SOC_REGS_PHY_BASE + INTREG_BASE_ADDR_REG) |
| 42 | ldr r0, [r1, #L2X0_CTRL_OFF] |
| 43 | bic r0, #L2X0_CTRL_EN |
| 44 | str r0, [r1, #L2X0_CTRL_OFF] |
Pali Rohár | aaed328 | 2022-05-06 11:05:14 +0200 | [diff] [blame] | 45 | #endif |
| 46 | |
| 47 | /* Move internal registers from INTREG_BASE_ADDR_REG to SOC_REGS_PHY_BASE */ |
| 48 | ldr r0, =SOC_REGS_PHY_BASE |
| 49 | ldr r1, =INTREG_BASE_ADDR_REG |
| 50 | str r0, [r1] |
| 51 | add r0, r0, #0xC000 |
| 52 | mcr p15, 4, r0, c15, c0 |
| 53 | |
| 54 | bx lr |
| 55 | ENDPROC(arch_very_early_init) |