After leaving the Partial-IO mode or other deep sleep states, the IO
isolation needs to be removed. This routine is shared by at least am62,
am62a and am62p.

The original function for testing was developed by
Akashdeep Kaur <[email protected]>

Signed-off-by: Markus Schneider-Pargmann <[email protected]>
---
 arch/arm/mach-k3/am62ax/am62a7_init.c    |  2 ++
 arch/arm/mach-k3/am62px/am62p5_init.c    |  2 ++
 arch/arm/mach-k3/am62x/am625_init.c      |  2 ++
 arch/arm/mach-k3/common.c                | 56 ++++++++++++++++++++++++++++++++
 arch/arm/mach-k3/common.h                |  1 +
 arch/arm/mach-k3/include/mach/hardware.h | 29 +++++++++++++++++
 6 files changed, 92 insertions(+)

diff --git a/arch/arm/mach-k3/am62ax/am62a7_init.c 
b/arch/arm/mach-k3/am62ax/am62a7_init.c
index 
ac4d30052f3d2508d84fb71ee1958f3408aa1fd0..62b90726cf14273cfc1cdbeb89d6723ed864818a
 100644
--- a/arch/arm/mach-k3/am62ax/am62a7_init.c
+++ b/arch/arm/mach-k3/am62ax/am62a7_init.c
@@ -102,6 +102,8 @@ void board_init_f(ulong dummy)
        /* Init DM early */
        spl_early_init();
 
+       wkup_ctrl_remove_can_io_isolation_if_set();
+
        /*
         * Process pinctrl for the serial0 and serial3, aka WKUP_UART0 and
         * MAIN_UART1 modules and continue regardless of the result of pinctrl.
diff --git a/arch/arm/mach-k3/am62px/am62p5_init.c 
b/arch/arm/mach-k3/am62px/am62p5_init.c
index 
44a2d445d24cc3aabbcd20e6191d1dc766b1e733..aeec07f6067abb40dfa4019344e0782ea7b7f5a0
 100644
--- a/arch/arm/mach-k3/am62px/am62p5_init.c
+++ b/arch/arm/mach-k3/am62px/am62p5_init.c
@@ -160,6 +160,8 @@ void board_init_f(ulong dummy)
        if (ret)
                panic("spl_early_init() failed: %d\n", ret);
 
+       wkup_ctrl_remove_can_io_isolation_if_set();
+
        /*
         * Process pinctrl for the serial0 and serial3, aka WKUP_UART0 and
         * MAIN_UART1 modules and continue regardless of the result of pinctrl.
diff --git a/arch/arm/mach-k3/am62x/am625_init.c 
b/arch/arm/mach-k3/am62x/am625_init.c
index 
a422919fab131a099b1f7786f2a84ca0a413dd38..9a5eb6e47249e18f7f4e3ded62d936490f2fec6d
 100644
--- a/arch/arm/mach-k3/am62x/am625_init.c
+++ b/arch/arm/mach-k3/am62x/am625_init.c
@@ -201,6 +201,8 @@ void board_init_f(ulong dummy)
        /* Init DM early */
        spl_early_init();
 
+       wkup_ctrl_remove_can_io_isolation_if_set();
+
        /*
         * Process pinctrl for the serial0 and serial3, aka WKUP_UART0 and
         * MAIN_UART1 modules and continue regardless of the result of pinctrl.
diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c
index 
f8c53b286eb778554789349fff53a2cdb0466ee0..ff4f2150d318689a87909eb106b0b6fa8ff98f70
 100644
--- a/arch/arm/mach-k3/common.c
+++ b/arch/arm/mach-k3/common.c
@@ -30,6 +30,9 @@
 #include <soc.h>
 #include <dm/uclass-internal.h>
 #include <dm/device-internal.h>
+#include <wait_bit.h>
+
+#define CLKSTOP_TRANSITION_TIMEOUT_MS  10
 
 #define PROC_BOOT_CTRL_FLAG_R5_CORE_HALT       0x00000001
 #define PROC_BOOT_STATUS_FLAG_R5_WFI           0x00000002
@@ -112,6 +115,59 @@ void mmr_unlock(uintptr_t base, u32 partition)
        writel(CTRLMMR_LOCK_KICK1_UNLOCK_VAL, part_base + CTRLMMR_LOCK_KICK1);
 }
 
+static void wkup_ctrl_remove_can_io_isolation(void)
+{
+       const void *wait_reg = (const void *)(WKUP_CTRL_MMR0_BASE +
+                                             WKUP_CTRL_MMR_CANUART_WAKE_STAT1);
+       int ret;
+       u32 reg = 0;
+
+       /* Program magic word */
+       reg = readl(WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_CANUART_WAKE_CTRL);
+       reg |= WKUP_CTRL_MMR_CANUART_WAKE_CTRL_MW << 
WKUP_CTRL_MMR_CANUART_WAKE_CTRL_MW_SHIFT;
+       writel(reg, WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_CANUART_WAKE_CTRL);
+
+       /* Set enable bit. */
+       reg |= WKUP_CTRL_MMR_CANUART_WAKE_CTRL_MW_LOAD_EN;
+       writel(reg, WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_CANUART_WAKE_CTRL);
+
+       /* Clear enable bit. */
+       reg &= ~WKUP_CTRL_MMR_CANUART_WAKE_CTRL_MW_LOAD_EN;
+       writel(reg, WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_CANUART_WAKE_CTRL);
+
+       /* wait for CAN_ONLY_IO signal to be 0 */
+       ret = wait_for_bit_32(wait_reg,
+                             WKUP_CTRL_MMR_CANUART_WAKE_STAT1_CANUART_IO_MODE,
+                             false,
+                             CLKSTOP_TRANSITION_TIMEOUT_MS,
+                             false);
+       if (ret < 0)
+               return;
+
+       /* Reset magic word */
+       writel(0, WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_CANUART_WAKE_CTRL);
+
+       /* Remove WKUP IO isolation */
+       reg = readl(WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_PMCTRL_IO_0);
+       reg = reg & WKUP_CTRL_MMR_PMCTRL_IO_0_WRITE_MASK & 
~WKUP_CTRL_MMR_PMCTRL_IO_0_GLOBAL_WUEN_0;
+       writel(reg, WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_PMCTRL_IO_0);
+
+       /* clear global IO isolation */
+       reg = readl(WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_PMCTRL_IO_0);
+       reg = reg & WKUP_CTRL_MMR_PMCTRL_IO_0_WRITE_MASK & 
~WKUP_CTRL_MMR_PMCTRL_IO_0_IO_ISO_CTRL_0;
+       writel(reg, WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_PMCTRL_IO_0);
+
+       writel(0, WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_DEEPSLEEP_CTRL);
+       writel(0, WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_PMCTRL_IO_GLB);
+}
+
+void wkup_ctrl_remove_can_io_isolation_if_set(void)
+{
+       if (readl(WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_CANUART_WAKE_STAT1) &
+           WKUP_CTRL_MMR_CANUART_WAKE_STAT1_CANUART_IO_MODE)
+               wkup_ctrl_remove_can_io_isolation();
+}
+
 bool is_rom_loaded_sysfw(struct rom_extended_boot_data *data)
 {
        if (strncmp(data->header, K3_ROM_BOOT_HEADER_MAGIC, 7))
diff --git a/arch/arm/mach-k3/common.h b/arch/arm/mach-k3/common.h
index 
52d3faaab5c94578cf4f7e288cbf840500d490a1..49417679e2ec7210d5c95540f476a5d8ee548617
 100644
--- a/arch/arm/mach-k3/common.h
+++ b/arch/arm/mach-k3/common.h
@@ -51,6 +51,7 @@ struct ti_sci_handle *get_ti_sci_handle(void);
 void do_board_detect(void);
 void ti_secure_image_check_binary(void **p_image, size_t *p_size);
 int shutdown_mcu_r5_core1(void);
+void wkup_ctrl_remove_can_io_isolation_if_set(void);
 
 #if (IS_ENABLED(CONFIG_K3_QOS))
 void setup_qos(void);
diff --git a/arch/arm/mach-k3/include/mach/hardware.h 
b/arch/arm/mach-k3/include/mach/hardware.h
index 
81b5f1fa45ea30456a43c6640aad01388ea6a3f2..d7c759420524faf48ea26c66607c6a899d1321b3
 100644
--- a/arch/arm/mach-k3/include/mach/hardware.h
+++ b/arch/arm/mach-k3/include/mach/hardware.h
@@ -117,6 +117,35 @@ K3_SOC_ID(j722s, J722S)
 #define CTRLMMR_LOCK_KICK1                     0x100c
 #define CTRLMMR_LOCK_KICK1_UNLOCK_VAL          0xd172bc5a
 
+/*
+ * Shared WKUP_CTRL_MMR0 definitions used to remove IO isolation
+ */
+#define WKUP_CTRL_MMR_CANUART_WAKE_CTRL                                0x18300
+#define WKUP_CTRL_MMR_CANUART_WAKE_CTRL_MW                     0x2aaaaaaa
+#define WKUP_CTRL_MMR_CANUART_WAKE_CTRL_MW_SHIFT               1
+#define WKUP_CTRL_MMR_CANUART_WAKE_CTRL_MW_LOAD_EN             BIT(0)
+
+#define WKUP_CTRL_MMR_CANUART_WAKE_STAT1                       0x1830c
+#define WKUP_CTRL_MMR_CANUART_WAKE_STAT1_CANUART_IO_MODE       BIT(0)
+
+#define WKUP_CTRL_MMR_PMCTRL_IO_0                              0x18084
+#define WKUP_CTRL_MMR_PMCTRL_IO_0_ISOCLK_OVRD_0                        BIT(0)
+#define WKUP_CTRL_MMR_PMCTRL_IO_0_ISOOVR_EXTEND_0              BIT(4)
+#define WKUP_CTRL_MMR_PMCTRL_IO_0_ISO_BYPASS_OVR_0             BIT(6)
+#define WKUP_CTRL_MMR_PMCTRL_IO_0_WUCLK_CTRL_0                 BIT(8)
+#define WKUP_CTRL_MMR_PMCTRL_IO_0_GLOBAL_WUEN_0                        BIT(16)
+#define WKUP_CTRL_MMR_PMCTRL_IO_0_IO_ISO_CTRL_0                        BIT(24)
+#define WKUP_CTRL_MMR_PMCTRL_IO_0_WRITE_MASK ( \
+               WKUP_CTRL_MMR_PMCTRL_IO_0_ISOCLK_OVRD_0 |       \
+               WKUP_CTRL_MMR_PMCTRL_IO_0_ISOOVR_EXTEND_0 |     \
+               WKUP_CTRL_MMR_PMCTRL_IO_0_ISO_BYPASS_OVR_0 |    \
+               WKUP_CTRL_MMR_PMCTRL_IO_0_WUCLK_CTRL_0 |        \
+               WKUP_CTRL_MMR_PMCTRL_IO_0_GLOBAL_WUEN_0 |       \
+               WKUP_CTRL_MMR_PMCTRL_IO_0_IO_ISO_CTRL_0)
+
+#define WKUP_CTRL_MMR_PMCTRL_IO_GLB                            0x1809c
+#define WKUP_CTRL_MMR_DEEPSLEEP_CTRL                           0x18160
+
 #define K3_ROM_BOOT_HEADER_MAGIC       "EXTBOOT"
 
 struct rom_extended_boot_data {

-- 
2.49.0

Reply via email to