From: Abhash Kumar Jha <[email protected]>

In IO_ONLY_PLUS_DDR low power mode, the DDR is in self refresh, and the
SoC is powered off except wake-up IOs.

When resuming from IO_ONLY_PLUS_DDR low power mode, the IOs are
isolated. Remove that isolation in resume sequence.

On j7200, The canuart IOs are isolated whereas on j784s4, the
mcu_general IOs are isolated.

Signed-off-by: Abhash Kumar Jha <[email protected]>
Co-developed-by: Richard Genoud (TI) <[email protected]>
Signed-off-by: Richard Genoud (TI) <[email protected]>
---
 .../arm/mach-k3/include/mach/j721e_hardware.h | 11 ++++++++
 .../mach-k3/include/mach/j784s4_hardware.h    | 10 ++++++++
 arch/arm/mach-k3/r5/lpm-common.c              | 16 ++++++++++++
 board/ti/j721e/evm.c                          | 25 +++++++++++++++++++
 board/ti/j784s4/evm.c                         | 24 ++++++++++++++++++
 5 files changed, 86 insertions(+)

diff --git a/arch/arm/mach-k3/include/mach/j721e_hardware.h 
b/arch/arm/mach-k3/include/mach/j721e_hardware.h
index 5bef309af0a4..e6e437af4ec0 100644
--- a/arch/arm/mach-k3/include/mach/j721e_hardware.h
+++ b/arch/arm/mach-k3/include/mach/j721e_hardware.h
@@ -14,6 +14,17 @@
 #define WKUP_CTRL_MMR0_BASE                            0x43000000
 #define MCU_CTRL_MMR0_BASE                             0x40f00000
 #define CTRL_MMR0_BASE                                 0x00100000
+#define DMSC_PWRCTRL_BASE                              0x44130000
+
+#define PMCTRL_IO_1                                    (DMSC_PWRCTRL_BASE + 
0x88)
+#define PMCTRL_IO_LPM                                  PMCTRL_IO_1
+#define CANUART_WAKE_CTRL                              0x18300
+#define CANUART_WAKE_STAT0                             0x18308
+#define CANUART_WAKE_STAT1                             0x1830C
+
+#define IO_ISO_MAGIC_VAL                               0x55555554
+#define CANUART_WAKE_STAT1_CANUART_IO_MODE             BIT(0)
+#define DEISOLATION_TIMEOUT_MS                         10
 
 #define CTRLMMR_MAIN_DEVSTAT                           (CTRL_MMR0_BASE + 0x30)
 #define MAIN_DEVSTAT_BOOT_MODE_B_MASK          BIT(0)
diff --git a/arch/arm/mach-k3/include/mach/j784s4_hardware.h 
b/arch/arm/mach-k3/include/mach/j784s4_hardware.h
index 29a894baed34..033ae153d674 100644
--- a/arch/arm/mach-k3/include/mach/j784s4_hardware.h
+++ b/arch/arm/mach-k3/include/mach/j784s4_hardware.h
@@ -15,6 +15,16 @@
 #define MCU_CTRL_MMR0_BASE                             0x40f00000
 #define CTRL_MMR0_BASE                                 0x00100000
 
+#define PMCTRL_IO_0                                    (WKUP_CTRL_MMR0_BASE + 
0x14084)
+#define PMCTRL_IO_LPM                                  PMCTRL_IO_0
+#define MCU_GEN_WAKE_CTRL                              0x18310
+#define MCU_GEN_WAKE_STAT0                             0x18318
+#define MCU_GEN_WAKE_STAT1                             0x1831C
+
+#define IO_ISO_MAGIC_VAL                               0x55555554
+#define MCU_GEN_WAKE_STAT1_MCU_GEN_IO_MODE             BIT(0)
+#define DEISOLATION_TIMEOUT_MS                         10
+
 #define CTRLMMR_MAIN_DEVSTAT                           (CTRL_MMR0_BASE + 0x30)
 #define MAIN_DEVSTAT_BOOT_MODE_B_MASK                  BIT(0)
 #define MAIN_DEVSTAT_BOOT_MODE_B_SHIFT                 0
diff --git a/arch/arm/mach-k3/r5/lpm-common.c b/arch/arm/mach-k3/r5/lpm-common.c
index f949ff0904ed..96306f307973 100644
--- a/arch/arm/mach-k3/r5/lpm-common.c
+++ b/arch/arm/mach-k3/r5/lpm-common.c
@@ -6,6 +6,7 @@
  * Copyright (C) 2026 Bootlin
  */
 
+#include <asm/arch/hardware.h>
 #include <clk.h>
 #include <dm/device.h>
 #include <dm/read.h>
@@ -26,6 +27,8 @@
 /* PMIC register where the magic value resides */
 #define K3_LPM_SCRATCH_PAD_REG_3 0xcb
 
+#define IO_ISO_STATUS BIT(25)
+
 #define CONTEXT_SAVE_SZ        0x80000
 #define ATF_CERT_SZ    0x80000
 #define OPTEE_CERT_SZ  0x100000
@@ -46,6 +49,8 @@ enum k3_resume_state {
        K3_RESUME_STATE_RESUMING
 };
 
+__weak void clear_isolation(void) { }
+
 #define GPIO_OUT_1 0x3D
 void k3_deassert_ddr_ret(const char *pmic_name, unsigned int ddr_ret_val,
                         unsigned int ddr_ret_clk, bool toggle)
@@ -77,11 +82,22 @@ bool j7xx_board_is_resuming(void)
 {
        static enum k3_resume_state k3_resuming;
        struct udevice *pmic;
+       u32 pmctrl_val = 0;
        int ret, magic;
 
        if (k3_resuming != K3_RESUME_STATE_UNKNOWN)
                goto end;
 
+#ifdef PMCTRL_IO_LPM
+       pmctrl_val = readl(PMCTRL_IO_LPM);
+#endif
+       if ((pmctrl_val & IO_ISO_STATUS) == IO_ISO_STATUS) {
+               clear_isolation();
+               k3_resuming = K3_RESUME_STATE_RESUMING;
+               debug("board is resuming from IO_DDR mode\n");
+               goto end;
+       }
+
        ret = uclass_get_device_by_name(UCLASS_PMIC,
                                        "pmic@48", &pmic);
        if (ret) {
diff --git a/board/ti/j721e/evm.c b/board/ti/j721e/evm.c
index 881392bd963a..489b705e57e3 100644
--- a/board/ti/j721e/evm.c
+++ b/board/ti/j721e/evm.c
@@ -17,6 +17,7 @@
 #include <spl.h>
 #include <dm.h>
 #include <asm/arch/k3-ddr.h>
+#include <wait_bit.h>
 
 #include "../common/board_detect.h"
 #include "../common/fdt_ops.h"
@@ -469,6 +470,30 @@ err_free_gpio:
        }
 }
 
+#if (IS_ENABLED(CONFIG_SPL_BUILD) && IS_ENABLED(CONFIG_TARGET_J7200_R5_EVM))
+
+void clear_isolation(void)
+{
+       int ret;
+       const void *wait_reg = (const void *)(WKUP_CTRL_MMR0_BASE + 
CANUART_WAKE_STAT1);
+
+       /* un-set the magic word for canuart IOs */
+       writel(IO_ISO_MAGIC_VAL, WKUP_CTRL_MMR0_BASE + CANUART_WAKE_CTRL);
+       writel((IO_ISO_MAGIC_VAL + 0x1), WKUP_CTRL_MMR0_BASE + 
CANUART_WAKE_CTRL);
+       writel(IO_ISO_MAGIC_VAL, WKUP_CTRL_MMR0_BASE + CANUART_WAKE_CTRL);
+
+       /* wait for CANUART_IO_MODE bit to be cleared */
+       ret = wait_for_bit_32(wait_reg,
+                             CANUART_WAKE_STAT1_CANUART_IO_MODE,
+                             false,
+                             DEISOLATION_TIMEOUT_MS,
+                             false);
+       if (ret < 0)
+               panic("Deisolation timeout");
+}
+
+#endif /* CONFIG_SPL_BUILD && CONFIG_TARGET_J7200_R5_EVM */
+
 void spl_board_init(void)
 {
        struct udevice *dev;
diff --git a/board/ti/j784s4/evm.c b/board/ti/j784s4/evm.c
index 8a4d40a5a959..5e9b9944a15f 100644
--- a/board/ti/j784s4/evm.c
+++ b/board/ti/j784s4/evm.c
@@ -11,7 +11,9 @@
 #include <efi_loader.h>
 #include <init.h>
 #include <spl.h>
+#include <asm/arch/hardware.h>
 #include <asm/arch/k3-ddr.h>
+#include <wait_bit.h>
 #include "../common/fdt_ops.h"
 
 struct efi_fw_image fw_images[] = {
@@ -59,6 +61,28 @@ int board_late_init(void)
 }
 #endif
 
+#if (IS_ENABLED(CONFIG_SPL_BUILD) && IS_ENABLED(CONFIG_TARGET_J784S4_R5_EVM))
+void clear_isolation(void)
+{
+       int ret;
+       const void *wait_reg = (const void *)(WKUP_CTRL_MMR0_BASE + 
MCU_GEN_WAKE_STAT1);
+
+       /* un-set the magic word for MCU_GENERAL IOs */
+       writel(IO_ISO_MAGIC_VAL, WKUP_CTRL_MMR0_BASE + MCU_GEN_WAKE_CTRL);
+       writel((IO_ISO_MAGIC_VAL + 0x1), WKUP_CTRL_MMR0_BASE + 
MCU_GEN_WAKE_CTRL);
+       writel(IO_ISO_MAGIC_VAL, WKUP_CTRL_MMR0_BASE + MCU_GEN_WAKE_CTRL);
+
+       /* wait for MCU_GEN_IO_MODE bit to be cleared */
+       ret = wait_for_bit_32(wait_reg,
+                             MCU_GEN_WAKE_STAT1_MCU_GEN_IO_MODE,
+                             false,
+                             DEISOLATION_TIMEOUT_MS,
+                             false);
+       if (ret < 0)
+               panic("Deisolation timeout");
+}
+#endif /* CONFIG_SPL_BUILD && CONFIG_TARGET_J784s4_R5_EVM */
+
 void spl_board_init(void)
 {
        struct udevice *dev;
-- 
2.55.0

Reply via email to