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, ®s); + 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

