1/* SPDX-License-Identifier: GPL-2.0+ */ 2 3#include <config.h> 4#include <linux/linkage.h> 5#include <asm/system.h> 6#include <asm/pl310.h> 7 8ENTRY(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. 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. 19 */ 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 */ 30 mrc p15, 0, r0, c1, c0, 0 31 bic r0, #CR_M 32 mcr p15, 0, r0, c1, c0, 0 33 34 /* 35 * Disable L2 cache 36 * 37 * NOTE: Internal registers are still at address INTREG_BASE_ADDR_REG 38 * but CFG_SYS_PL310_BASE is already calculated from base 39 * address SOC_REGS_PHY_BASE. 40 */ 41 ldr r1, =(CFG_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] 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 55ENDPROC(arch_very_early_init) 56