[PATCH 17/20] board: evm: Enable de-isolation of IOs at resume for j7200 and j784s4
Richard Genoud (TI)
richard.genoud at bootlin.com
Thu Apr 30 10:44:10 CEST 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>
---
.../arm/mach-k3/include/mach/j721e_hardware.h | 11 +++++++
.../mach-k3/include/mach/j784s4_hardware.h | 10 +++++++
board/ti/j721e/evm.c | 29 ++++++++++++++++++
board/ti/j784s4/evm.c | 30 +++++++++++++++++++
4 files changed, 80 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..587dd10eb1ea 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 29a894baed34..dd51473419dd 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 67ff13828514..41eea1bdea95 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"
@@ -473,14 +474,42 @@ err_free_gpio:
#if (IS_ENABLED(CONFIG_SPL_BUILD) && IS_ENABLED(CONFIG_TARGET_J7200_R5_EVM))
+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");
+}
+
bool j7xx_board_is_resuming(void)
{
struct udevice *pmica;
+ u32 pmctrl_val = readl(PMCTRL_IO_1);
int ret;
if (gd_k3_resuming() != K3_RESUME_STATE_UNKNOWN)
goto end;
+ if ((pmctrl_val & IO_ISO_STATUS) == IO_ISO_STATUS) {
+ clear_isolation();
+ gd_set_k3_resuming(K3_RESUME_STATE_RESUMING);
+ debug("Resuming from IO_DDR mode\n");
+ goto end;
+ }
+
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 57c2f7018323..eef56556a33c 100644
--- a/board/ti/j784s4/evm.c
+++ b/board/ti/j784s4/evm.c
@@ -13,8 +13,10 @@
#include <spl.h>
#include <asm/arch/k3-ddr.h>
#include <power/pmic.h>
+#include <wait_bit.h>
#include "../common/fdt_ops.h"
#include "../common/k3-lpm.h"
+#include "../common.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -66,15 +68,43 @@ int board_late_init(void)
#if (IS_ENABLED(CONFIG_SPL_BUILD) && (IS_ENABLED(CONFIG_TARGET_J784S4_R5_EVM) || \
IS_ENABLED(CONFIG_TARGET_J742S2_R5_EVM)))
+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 */
bool j7xx_board_is_resuming(void)
{
struct udevice *pmic;
+ u32 pmctrl_val = readl(WKUP_CTRL_MMR0_BASE + PMCTRL_IO_0);
int err;
if (gd_k3_resuming() != K3_RESUME_STATE_UNKNOWN)
goto end;
+ if ((pmctrl_val & IO_ISO_STATUS) == IO_ISO_STATUS) {
+ clear_isolation();
+ gd_set_k3_resuming(K3_RESUME_STATE_RESUMING);
+ debug("board is resuming from IO_DDR mode\n");
+ goto end;
+ }
+
err = uclass_get_device_by_name(UCLASS_PMIC,
"pmic at 48", &pmic);
if (err) {
More information about the U-Boot
mailing list