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 (TI) <[email protected]>
---
 arch/arm/mach-k3/am62ax/am62a7_init.c |  5 +++
 arch/arm/mach-k3/am62px/am62p5_init.c |  5 +++
 arch/arm/mach-k3/am62x/am625_init.c   |  5 +++
 arch/arm/mach-k3/am62xx-lpm-common.c  | 85 +++++++++++++++++++++++++++++++++++
 arch/arm/mach-k3/am62xx-lpm-common.h  |  1 +
 5 files changed, 101 insertions(+)

diff --git a/arch/arm/mach-k3/am62ax/am62a7_init.c 
b/arch/arm/mach-k3/am62ax/am62a7_init.c
index 0d86d52ef267..401d6a8e41fa 100644
--- a/arch/arm/mach-k3/am62ax/am62a7_init.c
+++ b/arch/arm/mach-k3/am62ax/am62a7_init.c
@@ -14,6 +14,7 @@
 
 #include "../sysfw-loader.h"
 #include "../common.h"
+#include "../am62xx-lpm-common.h"
 
 #define CTRLMMR_MCU_RST_CTRL             0x04518170
 #define RST_CTRL_ESM_ERROR_RST_EN_Z_MASK 0xFFFDFFFF
@@ -139,6 +140,10 @@ void board_init_f(ulong dummy)
        /* Init DM early */
        spl_early_init();
 
+       ret = wkup_ctrl_remove_can_io_isolation_if_set();
+       if (ret)
+               panic("Failed to remove can IO isolation when set %d\n", ret);
+
        /*
         * 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 599ea7cf2dd8..2b7fc5f3315f 100644
--- a/arch/arm/mach-k3/am62px/am62p5_init.c
+++ b/arch/arm/mach-k3/am62px/am62p5_init.c
@@ -14,6 +14,7 @@
 
 #include "../sysfw-loader.h"
 #include "../common.h"
+#include "../am62xx-lpm-common.h"
 
 #define CTRLMMR_MCU_RST_CTRL             0x04518170
 #define RST_CTRL_ESM_ERROR_RST_EN_Z_MASK 0xFFFDFFFF
@@ -123,6 +124,10 @@ void board_init_f(ulong dummy)
        if (ret)
                panic("spl_early_init() failed: %d\n", ret);
 
+       ret = wkup_ctrl_remove_can_io_isolation_if_set();
+       if (ret)
+               panic("Failed to remove can IO isolation when set %d\n", ret);
+
        /*
         * 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 decb50bf853d..fa7dcb7a6cce 100644
--- a/arch/arm/mach-k3/am62x/am625_init.c
+++ b/arch/arm/mach-k3/am62x/am625_init.c
@@ -15,6 +15,7 @@
 
 #include "../sysfw-loader.h"
 #include "../common.h"
+#include "../am62xx-lpm-common.h"
 
 #define RTC_BASE_ADDRESS               0x2b1f0000
 #define REG_K3RTC_S_CNT_LSW            (RTC_BASE_ADDRESS + 0x18)
@@ -163,6 +164,10 @@ void board_init_f(ulong dummy)
        /* Init DM early */
        spl_early_init();
 
+       ret = wkup_ctrl_remove_can_io_isolation_if_set();
+       if (ret)
+               panic("Failed to remove can IO isolation when set %d\n", ret);
+
        /*
         * 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/am62xx-lpm-common.c 
b/arch/arm/mach-k3/am62xx-lpm-common.c
index 424d7457c596..54d86b0474df 100644
--- a/arch/arm/mach-k3/am62xx-lpm-common.c
+++ b/arch/arm/mach-k3/am62xx-lpm-common.c
@@ -9,15 +9,93 @@
 #include <config.h>
 #include <asm/arch/hardware.h>
 #include <asm/io.h>
+#include <wait_bit.h>
 
 #include "am62xx-lpm-common.h"
 
+/*
+ * Shared WKUP_CTRL_MMR0 definitions used to remove IO isolation
+ */
+#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 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_CANUART_WAKE_OFF_MODE_STAT               0x18318
 #define WKUP_CTRL_MMR_CANUART_WAKE_OFF_MODE_STAT_MW            0x555555
 
+#define CLKSTOP_TRANSITION_TIMEOUT_MS  10
+
+static int 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 ret;
+
+       /* 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);
+
+       /* Release all IOs from deepsleep mode and clear IO daisy chain control 
*/
+       writel(0, WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_DEEPSLEEP_CTRL);
+       writel(0, WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_PMCTRL_IO_GLB);
+
+       return 0;
+}
+
 static bool wkup_ctrl_canuart_wakeup_active(void)
 {
        return !!(readl(WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_CANUART_WAKE_STAT1) 
&
@@ -36,3 +114,10 @@ bool wkup_ctrl_is_lpm_exit(void)
                wkup_ctrl_canuart_wakeup_active() &&
                wkup_ctrl_canuart_magic_word_set();
 }
+
+int __maybe_unused wkup_ctrl_remove_can_io_isolation_if_set(void)
+{
+       if (wkup_ctrl_canuart_wakeup_active() && 
!wkup_ctrl_canuart_magic_word_set())
+               return wkup_ctrl_remove_can_io_isolation();
+       return 0;
+}
diff --git a/arch/arm/mach-k3/am62xx-lpm-common.h 
b/arch/arm/mach-k3/am62xx-lpm-common.h
index 36dcd20a9b80..2d110bcca0fc 100644
--- a/arch/arm/mach-k3/am62xx-lpm-common.h
+++ b/arch/arm/mach-k3/am62xx-lpm-common.h
@@ -12,5 +12,6 @@
 #include <asm/io.h>
 
 bool wkup_ctrl_is_lpm_exit(void);
+int wkup_ctrl_remove_can_io_isolation_if_set(void);
 
 #endif  /* _AM62XX_LPM_COMMON_H_ */

-- 
2.55.0

Reply via email to