[RFC PATCH 19/19] arm: mach-k3: j784s4: Enable lpm resume flow for J784S4

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


Add support for resuming from suspend in board_init_f for J784S4.
The resume state of the SOC is identified and lpm resume
sequence is followed accordingly.

- Extract context address from devicetree and send to TIFS.
- Power on the rproc cluster.
- Replay the certificates attached to saved images of ATF and OPTEE.
- Resume sequence for context restore and rproc resume.
- Image entry to DM firmware.

The context address area is firewalled by TIFS to protect it from
other hosts. Same with the resume flow.

Signed-off-by: Prasanth Babu Mantena <p-mantena at ti.com>
---
 arch/arm/mach-k3/j784s4/j784s4_init.c         | 65 +++++++++++++++++++
 ...-j784s4-j742s2-ti-ipc-firmware-common.dtsi |  6 ++
 2 files changed, 71 insertions(+)

diff --git a/arch/arm/mach-k3/j784s4/j784s4_init.c b/arch/arm/mach-k3/j784s4/j784s4_init.c
index be04f88d23e..37b2f584db4 100644
--- a/arch/arm/mach-k3/j784s4/j784s4_init.c
+++ b/arch/arm/mach-k3/j784s4/j784s4_init.c
@@ -270,6 +270,48 @@ void k3_spl_init(void)
 		k3_dm_print_ver();
 }
 
+void lpm_process(void)
+{
+	int ret = 0;
+	struct ti_sci_handle *ti_sci = get_ti_sci_handle();
+	save_certificate();
+
+	ret = ti_sci->ops.lpm_ops.lpm_save_addr(ti_sci, (u32)mem_addr_lpm.context_save_addr, mem_addr_lpm.size);
+	if (ret)
+		pr_err("TIFS lpm save addr fail\n");
+}
+
+int extract_lpm_region(void)
+{
+    ofnode node;
+	u32 lpm_reg_addr, lpm_reg_size;
+
+	node = ofnode_path("/reserved-memory/lpm-memory");
+	if (!ofnode_valid(node)) {
+	    printf("lpm will not be functional\n");
+		return -ENODEV;
+	}
+
+	lpm_reg_addr = ofnode_get_addr(node);
+	if (lpm_reg_addr == FDT_ADDR_T_NONE) {
+		printf("Can't find a valid reserved node!\n");
+		return -ENODEV;
+    }
+
+	lpm_reg_size = ofnode_get_size(node);
+	if (lpm_reg_size == FDT_ADDR_T_NONE) {
+		printf("Can't find a valid reserved node!\n");
+		return -ENODEV;
+    }
+
+	mem_addr_lpm.context_save_addr = (u32 *)lpm_reg_addr;
+	mem_addr_lpm.atf_cert_addr =  (u32 *)((uintptr_t)mem_addr_lpm.context_save_addr + FW_IMAGE_SIZE);
+	mem_addr_lpm.optee_cert_addr = (u32 *)((uintptr_t)mem_addr_lpm.atf_cert_addr + FW_IMAGE_SIZE);
+	mem_addr_lpm.dm_save_addr = (u32 *)((uintptr_t)mem_addr_lpm.optee_cert_addr + (2*FW_IMAGE_SIZE));
+	mem_addr_lpm.size = lpm_reg_size;
+	return 0;
+}
+
 #define DDR_RET_VAL BIT(5)
 #define GPIO_OUT_1 0x3D
 #define PMIC_NSLEEP_REG 0x86
@@ -322,6 +364,9 @@ void k3_mem_init(void)
 		}
 
 		if (board_is_resuming()) {
+			typedef void __noreturn (*image_entry_noargs_t)(void);
+			u32 loadaddr, size_int;
+			void *image_addr;
 			/* exit DDRs from retention */
 			for (ctrl = 0; ctrl < MAX_DDR_CONTROLLERS; ctrl++) {
 				k3_ddrss_lpddr4_exit_retention(devs[ctrl],
@@ -340,6 +385,26 @@ void k3_mem_init(void)
 				k3_ddrss_lpddr4_exit_low_power(devs[ctrl],
 							       &regs[ctrl]);
 			}
+			printf("Initialized %d DRAM controllers\n", ctrl);
+			ret = extract_lpm_region();
+			if (ret)
+				panic("Cannot find valid LPM address range..LPM resume failed \n");
+			image_addr = (void *)mem_addr_lpm.atf_cert_addr;
+			ret = rproc_load(1, (ulong)image_addr, 0x200);
+			if (ret)
+				panic("rproc failed to be initialized (%d)\n", ret);
+
+			image_addr = mem_addr_lpm.atf_cert_addr;
+			size_int = FW_IMAGE_SIZE;
+			ti_secure_image_replay_cert(&image_addr, &size_int);
+			image_addr = mem_addr_lpm.optee_cert_addr;
+			ti_secure_image_replay_cert(&image_addr, &size_int);
+			loadaddr = resume_to_dm_f();
+			printf("Starting ATF on ARM64 core...\n\n");
+			resume_rproc_f();
+
+			image_entry_noargs_t image_entry = (image_entry_noargs_t)loadaddr;
+			image_entry();
 		}
 		printf("Initialized %d DRAM controllers\n", ctrl);
 	}
diff --git a/dts/upstream/src/arm64/ti/k3-j784s4-j742s2-ti-ipc-firmware-common.dtsi b/dts/upstream/src/arm64/ti/k3-j784s4-j742s2-ti-ipc-firmware-common.dtsi
index 455397227d4..f285f4d65b2 100644
--- a/dts/upstream/src/arm64/ti/k3-j784s4-j742s2-ti-ipc-firmware-common.dtsi
+++ b/dts/upstream/src/arm64/ti/k3-j784s4-j742s2-ti-ipc-firmware-common.dtsi
@@ -125,6 +125,12 @@
 		reg = <0x00 0xaa100000 0x00 0xf00000>;
 		no-map;
 	};
+
+	lpm_memory_region: lpm-memory at ab000000 {
+		reg = <0x00 0xab000000 0x00 0x00300000>;
+		no-map;
+		bootph-all;
+	};
 };
 
 &mailbox0_cluster0 {
-- 
2.34.1



More information about the U-Boot mailing list