[RFC PATCH 12/19] board: evm: Enable de-isolation of IOs at resume for j7200 and j784s4

Prasanth Babu Mantena p-mantena at ti.com
Fri Mar 13 14:58:53 CET 2026


From: Abhash Kumar Jha <a-kumar2 at ti.com>

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 <a-kumar2 at ti.com>
Signed-off-by: Prasanth Babu Mantena <p-mantena at ti.com>
---
 .../arm/mach-k3/include/mach/j721e_hardware.h | 11 +++++++
 .../mach-k3/include/mach/j784s4_hardware.h    | 10 +++++++
 board/ti/j721e/evm.c                          | 28 +++++++++++++++++
 board/ti/j784s4/evm.c                         | 30 +++++++++++++++++++
 4 files changed, 79 insertions(+)

diff --git a/arch/arm/mach-k3/include/mach/j721e_hardware.h b/arch/arm/mach-k3/include/mach/j721e_hardware.h
index 5bef309af0a..587dd10eb1e 100644
--- a/arch/arm/mach-k3/include/mach/j721e_hardware.h
+++ b/arch/arm/mach-k3/include/mach/j721e_hardware.h
@@ -15,6 +15,17 @@
 #define MCU_CTRL_MMR0_BASE				0x40f00000
 #define CTRL_MMR0_BASE					0x00100000
 
+#define PMCTRL_IO_1						(DMSC_PWRCTRL_BASE + 0x88)
+#define DMSC_PWRCTRL_BASE				0x44130000
+#define CANUART_WAKE_CTRL				0x18300
+#define CANUART_WAKE_STAT0				0x18308
+#define CANUART_WAKE_STAT1				0x1830C
+
+#define IO_ISO_MAGIC_VAL			0x55555554
+#define IO_ISO_STATUS				BIT(25)
+#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)
 #define MAIN_DEVSTAT_BOOT_MODE_B_SHIFT		0
diff --git a/arch/arm/mach-k3/include/mach/j784s4_hardware.h b/arch/arm/mach-k3/include/mach/j784s4_hardware.h
index 29a894baed3..dd51473419d 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					0x14084
+#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 IO_ISO_STATUS					BIT(25)
+#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/board/ti/j721e/evm.c b/board/ti/j721e/evm.c
index 20c77ff804f..368381c422a 100644
--- a/board/ti/j721e/evm.c
+++ b/board/ti/j721e/evm.c
@@ -18,6 +18,7 @@
 #include <dm.h>
 #include <asm/arch/k3-ddr.h>
 #include <power/pmic.h>
+#include <wait_bit.h>
 
 #include "../common/board_detect.h"
 #include "../common/fdt_ops.h"
@@ -475,16 +476,43 @@ err_free_gpio:
 #define SCRATCH_PAD_REG_3 0xCB
 
 #define MAGIC_SUSPEND 0xBA
+static 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)
+		pr_err("Deisolation timeout");
+}
 
 int board_is_resuming(void)
 {
 	struct udevice *pmica;
 	struct udevice *pmicb;
+	u32 pmctrl_val = readl(PMCTRL_IO_1);
 	int ret;
 
 	if (gd_k3_resuming() >= 0)
 		goto end;
 
+	if ((pmctrl_val & IO_ISO_STATUS) == IO_ISO_STATUS) {
+		clear_isolation();
+		gd_set_k3_resuming(1);
+		debug("Resuming from IO_DDR mode\n");
+		return gd_k3_resuming();
+	}
+
 	ret = uclass_get_device_by_name(UCLASS_PMIC,
 					"pmic at 48", &pmica);
 	if (ret) {
diff --git a/board/ti/j784s4/evm.c b/board/ti/j784s4/evm.c
index 42fb819c553..56d5abea6a9 100644
--- a/board/ti/j784s4/evm.c
+++ b/board/ti/j784s4/evm.c
@@ -13,7 +13,9 @@
 #include <spl.h>
 #include <asm/arch/k3-ddr.h>
 #include <power/pmic.h>
+#include <wait_bit.h>
 #include "../common/fdt_ops.h"
+#include "../common.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -68,15 +70,43 @@ int board_late_init(void)
 
 #define MAGIC_SUSPEND 0xBA
 
+static 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)
+		pr_err("Deisolation timeout");
+}
+
 /* in board_init_f(), there's no BSS, so we can't use global/static variables */
 int board_is_resuming(void)
 {
 	struct udevice *pmic;
+	u32 pmctrl_val = readl(WKUP_CTRL_MMR0_BASE + PMCTRL_IO_0);
 	int err;
 
 	if (gd_k3_resuming() >= 0)
 		goto end;
 
+	if ((pmctrl_val & IO_ISO_STATUS) == IO_ISO_STATUS) {
+		clear_isolation();
+		gd_set_k3_resuming(1);
+		debug("board is resuming from IO_DDR mode\n");
+		return gd_k3_resuming();
+	}
+
 	err = uclass_get_device_by_name(UCLASS_PMIC,
 					"pmic at 48", &pmic);
 	if (err) {
-- 
2.34.1



More information about the U-Boot mailing list