From: Andreas Dannenberg <dannenb...@ti.com>

By default the device control module registers are locked,
preventing any writes to its registers.
Unlock those registers as part of the init flow.

Reviewed-by: Tom Rini <tr...@konsulko.com>
Signed-off-by: Andreas Dannenberg <dannenb...@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvu...@ti.com>
---
 arch/arm/mach-k3/am6_init.c                  | 38 ++++++++++++++++++++
 arch/arm/mach-k3/include/mach/am6_hardware.h | 21 +++++++++++
 2 files changed, 59 insertions(+)

diff --git a/arch/arm/mach-k3/am6_init.c b/arch/arm/mach-k3/am6_init.c
index 671498a99b..8a3a99f23a 100644
--- a/arch/arm/mach-k3/am6_init.c
+++ b/arch/arm/mach-k3/am6_init.c
@@ -12,6 +12,41 @@
 #include <asm/arch/hardware.h>
 
 #ifdef CONFIG_SPL_BUILD
+static void mmr_unlock(u32 base, u32 partition)
+{
+       /* Translate the base address */
+       phys_addr_t part_base = base + partition * CTRL_MMR0_PARTITION_SIZE;
+
+       /* Unlock the requested partition if locked using two-step sequence */
+       writel(CTRLMMR_LOCK_KICK0_UNLOCK_VAL, part_base + CTRLMMR_LOCK_KICK0);
+       writel(CTRLMMR_LOCK_KICK1_UNLOCK_VAL, part_base + CTRLMMR_LOCK_KICK1);
+}
+
+static void ctrl_mmr_unlock(void)
+{
+       /* Unlock all WKUP_CTRL_MMR0 module registers */
+       mmr_unlock(WKUP_CTRL_MMR0_BASE, 0);
+       mmr_unlock(WKUP_CTRL_MMR0_BASE, 1);
+       mmr_unlock(WKUP_CTRL_MMR0_BASE, 2);
+       mmr_unlock(WKUP_CTRL_MMR0_BASE, 3);
+       mmr_unlock(WKUP_CTRL_MMR0_BASE, 6);
+       mmr_unlock(WKUP_CTRL_MMR0_BASE, 7);
+
+       /* Unlock all MCU_CTRL_MMR0 module registers */
+       mmr_unlock(MCU_CTRL_MMR0_BASE, 0);
+       mmr_unlock(MCU_CTRL_MMR0_BASE, 1);
+       mmr_unlock(MCU_CTRL_MMR0_BASE, 2);
+       mmr_unlock(MCU_CTRL_MMR0_BASE, 6);
+
+       /* Unlock all CTRL_MMR0 module registers */
+       mmr_unlock(CTRL_MMR0_BASE, 0);
+       mmr_unlock(CTRL_MMR0_BASE, 1);
+       mmr_unlock(CTRL_MMR0_BASE, 2);
+       mmr_unlock(CTRL_MMR0_BASE, 3);
+       mmr_unlock(CTRL_MMR0_BASE, 6);
+       mmr_unlock(CTRL_MMR0_BASE, 7);
+}
+
 static void store_boot_index_from_rom(void)
 {
        u32 *boot_index = (u32 *)K3_BOOT_PARAM_TABLE_INDEX_VAL;
@@ -27,6 +62,9 @@ void board_init_f(ulong dummy)
         */
        store_boot_index_from_rom();
 
+       /* Make all control module registers accessible */
+       ctrl_mmr_unlock();
+
        /* Init DM early in-order to invoke system controller */
        spl_early_init();
 
diff --git a/arch/arm/mach-k3/include/mach/am6_hardware.h 
b/arch/arm/mach-k3/include/mach/am6_hardware.h
index 1f918404c0..e4b78f8617 100644
--- a/arch/arm/mach-k3/include/mach/am6_hardware.h
+++ b/arch/arm/mach-k3/include/mach/am6_hardware.h
@@ -17,6 +17,27 @@
 #define CTRLMMR_MAIN_DEVSTAT_BKUP_BOOTMODE_MASK                GENMASK(6, 4)
 #define CTRLMMR_MAIN_DEVSTAT_BKUP_BOOTMODE_SHIFT       4
 
+#define WKUP_CTRL_MMR0_BASE                            0x43000000
+#define MCU_CTRL_MMR0_BASE                             0x40f00000
+
+/*
+ * The CTRL_MMR0 memory space is divided into several equally-spaced
+ * partitions, so defining the partition size allows us to determine
+ * register addresses common to those partitions.
+ */
+#define CTRL_MMR0_PARTITION_SIZE                       0x4000
+
+/*
+ * CTRL_MMR0, WKUP_CTRL_MMR0, and MCU_CTR_MMR0 lock/kick-mechanism
+ * shared register definitions.
+ */
+#define CTRLMMR_LOCK_KICK0                             0x01008
+#define CTRLMMR_LOCK_KICK0_UNLOCK_VAL                  0x68ef3490
+#define CTRLMMR_LOCK_KICK0_UNLOCKED_MASK               BIT(0)
+#define CTRLMMR_LOCK_KICK0_UNLOCKED_SHIFT              0
+#define CTRLMMR_LOCK_KICK1                             0x0100c
+#define CTRLMMR_LOCK_KICK1_UNLOCK_VAL                  0xd172bc5a
+
 /* MCU SCRATCHPAD usage */
 #define K3_BOOT_PARAM_TABLE_INDEX_VAL  CONFIG_SYS_K3_MCU_SCRATCHPAD_BASE
 
-- 
2.18.0

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to