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
