Add support for resuming from suspend in board_init_f.
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 <[email protected]>
---
 arch/arm/mach-k3/j721e/j721e_init.c           | 64 +++++++++++++++++++
 .../arm64/ti/k3-j7200-ti-ipc-firmware.dtsi    |  7 ++
 2 files changed, 71 insertions(+)

diff --git a/arch/arm/mach-k3/j721e/j721e_init.c 
b/arch/arm/mach-k3/j721e/j721e_init.c
index 220cb700ff7..2a492826e7f 100644
--- a/arch/arm/mach-k3/j721e/j721e_init.c
+++ b/arch/arm/mach-k3/j721e/j721e_init.c
@@ -243,6 +243,48 @@ static void store_boot_info_from_rom(void)
               sizeof(struct rom_extended_boot_data));
 }
 
+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, 
(uintptr_t)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 *)(uintptr_t)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;
+}
+
 #ifdef CONFIG_SPL_OF_LIST
 void do_dt_magic(void)
 {
@@ -458,6 +500,9 @@ void board_init_f(ulong dummy)
                panic("DRAM init failed: %d\n", ret);
 
        if (board_is_resuming()) {
+               typedef void __noreturn (*image_entry_noargs_t)(void);
+               u32 loadaddr, size_int;
+               void *image_addr;
                /*
                 * The DDR resume sequence is:
                 * - exit DDR from retention
@@ -469,6 +514,25 @@ void board_init_f(ulong dummy)
                k3_deassert_DDR_RET();
                k3_ddrss_lpddr4_change_freq(dev);
                k3_ddrss_lpddr4_exit_low_power(dev, &regs);
+               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();
        }
 #endif
        spl_enable_cache();
diff --git a/dts/upstream/src/arm64/ti/k3-j7200-ti-ipc-firmware.dtsi 
b/dts/upstream/src/arm64/ti/k3-j7200-ti-ipc-firmware.dtsi
index 9477f1efbbc..c5bec876a8a 100644
--- a/dts/upstream/src/arm64/ti/k3-j7200-ti-ipc-firmware.dtsi
+++ b/dts/upstream/src/arm64/ti/k3-j7200-ti-ipc-firmware.dtsi
@@ -47,6 +47,13 @@
                alignment = <0x1000>;
                no-map;
        };
+
+       lpm_memory_region: lpm-memory@a4800000 {
+               reg = <0x00 0xa4800000 0x00 0x00300000>;
+               alignment = <0x1000>;
+               no-map;
+               bootph-all;
+       };
 };
 
 &mailbox0_cluster0 {
-- 
2.34.1

Reply via email to