This is a common function that helps to resume from DDR. There are two pointers which are fetched from DDR to resume, the TIFS context pointer which points to the context in DDR. There is another pointer to the DM loadaddr to jump back into DM.
Signed-off-by: Markus Schneider-Pargmann <m...@baylibre.com> --- arch/arm/mach-k3/common.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-k3/common.h | 1 + 2 files changed, 46 insertions(+) diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index e3554ee6aa8957b8cfcacb452ba391d7b3abf2a9..2d9f34e61d916ce3a252e9cc3c2fd5475e60799e 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -152,6 +152,51 @@ bool wkup_ctrl_is_lpm_exit(void) wkup_ctrl_canuart_magic_word_set(); } +#if IS_ENABLED(CONFIG_K3_IODDR) +static int lpm_restore_context(u64 ctx_addr) +{ + struct ti_sci_handle *ti_sci = get_ti_sci_handle(); + int ret; + + ret = ti_sci->ops.lpm_ops.restore_context(ti_sci, ctx_addr); + if (ret) + printf("Failed to restore context from DDR %d\n", ret); + + return ret; +} + +struct lpm_meta_data { + u64 dm_jump_address; + u64 tifs_context_save_address; + u64 reserved[30]; +} __packed__; + +void __noreturn lpm_resume_from_ddr(u64 meta_data_addr) +{ + struct lpm_meta_data *lpm_data = (struct lpm_meta_data *)meta_data_addr; + typedef void __noreturn (*image_entry_noargs_t)(void); + image_entry_noargs_t image_entry; + int ret; + + ret = lpm_restore_context(lpm_data->tifs_context_save_address); + if (ret) + panic("Failed to restore context from 0x%p\n", + (void *)lpm_data->tifs_context_save_address); + + image_entry = (image_entry_noargs_t)(u64 *)lpm_data->dm_jump_address; + printf("Resuming from DDR, jumping to stored DM loadaddr 0x%p, TIFS context restored from 0x%p\n", + image_entry, (void *)lpm_data->tifs_context_save_address); + + image_entry(); +} +#else + +void __noreturn lpm_resume_from_ddr(u64 meta_data_addr) +{ + panic("No IO+DDR support"); +} +#endif + bool is_rom_loaded_sysfw(struct rom_extended_boot_data *data) { if (strncmp(data->header, K3_ROM_BOOT_HEADER_MAGIC, 7)) diff --git a/arch/arm/mach-k3/common.h b/arch/arm/mach-k3/common.h index 5d347c7252d18c06dac21813b8247fa2c57902bc..47f2dbf2accd9029d6f1905fe8d3f93381032a81 100644 --- a/arch/arm/mach-k3/common.h +++ b/arch/arm/mach-k3/common.h @@ -47,6 +47,7 @@ void do_board_detect(void); void ti_secure_image_check_binary(void **p_image, size_t *p_size); void wkup_ctrl_remove_can_io_isolation_if_set(void); bool wkup_ctrl_is_lpm_exit(void); +void lpm_resume_from_ddr(u64 meta_data_addr); #if (IS_ENABLED(CONFIG_K3_QOS)) void setup_qos(void); -- 2.47.2