arm: mvebu: Fix internal register config on A38x
Currently booting on A38x is broken. As the current code tries to detect
the SoC family to disable the MMU for the A38x at runtime. But before the
internal registers are switched to the new location (0xf100.0000), this
runtime detection does not work. As all macros / defines are already
assigned to the new location at 0xf100.0000. But the registers are sill
mapped to the default location at 0xd000.0000.
This patch now makes sure, no such runtime detection is used before
the internal registers are configured to the new location. After this,
the remaining cache cleanup is executed.
Signed-off-by: Stefan Roese <sr@denx.de>
Reported-by: Kevin Smith <kevin.smith@elecsyscorp.com>
Cc: Luka Perkov <luka.perkov@sartura.hr>
diff --git a/arch/arm/mach-mvebu/cpu.c b/arch/arm/mach-mvebu/cpu.c
index ea83e21..efd4d04 100644
--- a/arch/arm/mach-mvebu/cpu.c
+++ b/arch/arm/mach-mvebu/cpu.c
@@ -214,32 +214,40 @@
int arch_cpu_init(void)
{
-#ifndef CONFIG_SPL_BUILD
- if (mvebu_soc_family() == MVEBU_SOC_A38X) {
- struct pl310_regs *const pl310 =
- (struct pl310_regs *)CONFIG_SYS_PL310_BASE;
-
- /*
- * Only with disabled MMU its possible to switch the base
- * register address on Armada 38x. Without this the SDRAM
- * located at >= 0x4000.0000 is also not accessible, as its
- * still locked to cache.
- *
- * So to fully release / unlock this area from cache, we need
- * to first flush all caches, then disable the MMU and
- * disable the L2 cache.
- */
- icache_disable();
- dcache_disable();
- mmu_disable();
- clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
- }
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_ARMADA_38X)
+ /*
+ * Only with disabled MMU its possible to switch the base
+ * register address on Armada 38x. Without this the SDRAM
+ * located at >= 0x4000.0000 is also not accessible, as its
+ * still locked to cache.
+ */
+ mmu_disable();
#endif
/* Linux expects the internal registers to be at 0xf1000000 */
writel(SOC_REGS_PHY_BASE, INTREG_BASE_ADDR_REG);
set_cbar(SOC_REGS_PHY_BASE + 0xC000);
+#if !defined(CONFIG_SPL_BUILD)
+ /*
+ * From this stage on, the SoC detection is working. As we have
+ * configured the internal register base to the value used
+ * in the macros / defines in the U-Boot header (soc.h).
+ */
+ if (mvebu_soc_family() == MVEBU_SOC_A38X) {
+ struct pl310_regs *const pl310 =
+ (struct pl310_regs *)CONFIG_SYS_PL310_BASE;
+
+ /*
+ * To fully release / unlock this area from cache, we need
+ * to flush all caches and disable the L2 cache.
+ */
+ icache_disable();
+ dcache_disable();
+ clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
+ }
+#endif
+
/*
* We need to call mvebu_mbus_probe() before calling
* update_sdram_window_sizes() as it disables all previously