Add helpers for adding QCLIB interface-table entries and FIT blobs, expose the DDR self-refresh exit address, preserve U-Boot global data across the QCLIB call, and provide weak reset hooks for SoC-specific SPL code.
Signed-off-by: Abhilash V <[email protected]> --- arch/arm/mach-snapdragon/board_spl.c | 8 ++ arch/arm/mach-snapdragon/include/mach/qclib.h | 16 +++- arch/arm/mach-snapdragon/qclib.c | 77 +++++++++++++++---- 3 files changed, 85 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-snapdragon/board_spl.c b/arch/arm/mach-snapdragon/board_spl.c index 3293eab8f81..5aa84a3a6d1 100644 --- a/arch/arm/mach-snapdragon/board_spl.c +++ b/arch/arm/mach-snapdragon/board_spl.c @@ -27,6 +27,14 @@ __weak void reset_cpu(void) hang(); } +void __weak qcom_spl_soc_shrm_reset(void) +{ +} + +void __weak qcom_spl_soc_rpm_reset(void) +{ +} + #if IS_ENABLED(CONFIG_SPL_SMEM) /** * qcom_spl_populate_smem() - Populate shared memory (SMEM) information. diff --git a/arch/arm/mach-snapdragon/include/mach/qclib.h b/arch/arm/mach-snapdragon/include/mach/qclib.h index b44874c514e..10865b03ea1 100644 --- a/arch/arm/mach-snapdragon/include/mach/qclib.h +++ b/arch/arm/mach-snapdragon/include/mach/qclib.h @@ -65,11 +65,25 @@ void qclib_set_qcsdi_address(u64 address); u64 qclib_get_log_buffer_entry(void); void qclib_set_log_buffer_entry(u64 address); +/* DDR self-refresh exit address accessors, populated post-QCLIB */ +u64 qclib_get_ddr_sr_exit_address(void); +void qclib_set_ddr_sr_exit_address(u64 address); + +/* Interface-table entry helpers */ +int qclib_add_iftbl_entry(struct interface_table *table, + const char *name, u64 address, u32 size); +int qclib_add_iftbl_fit_blob(struct interface_table *table, + const void *fit, int images_node, + const char *name, u32 size); + /* * __weak SoC extension points. A board's spl-<soc>.c may provide a strong - * override for any of these; the defaults in qclib.c are all no-ops. + * override for any of these; the defaults are provided by the common + * Snapdragon SPL implementation. */ bool qcom_spl_soc_check_dload_mode(void); +void qcom_spl_soc_shrm_reset(void); +void qcom_spl_soc_rpm_reset(void); int qcom_spl_soc_pre_qclib_routine(void); int qcom_spl_soc_qclib_override(struct interface_table *table, const void *fit, int images_node); diff --git a/arch/arm/mach-snapdragon/qclib.c b/arch/arm/mach-snapdragon/qclib.c index 7f25f37b5d9..b9a74863c1c 100644 --- a/arch/arm/mach-snapdragon/qclib.c +++ b/arch/arm/mach-snapdragon/qclib.c @@ -2,7 +2,8 @@ /* * QCLIB interface-table protocol: generic, SoC-agnostic orchestration of the * hand-off to the QCLIB firmware image, plus __weak extension points a - * per-board spl-<soc>.c may override to populate SoC-specific table entries. + * per-board spl-<soc>.c may override to populate SoC-specific table entries + * and provide SoC-specific reset sequences. */ #include <cpu_func.h> @@ -15,6 +16,17 @@ static u64 g_qcsdi_address __section(".data"); static u64 g_log_buffer_entry __section(".data"); +static u64 g_ddr_sr_exit_address __section(".data"); + +u64 qclib_get_ddr_sr_exit_address(void) +{ + return g_ddr_sr_exit_address; +} + +void qclib_set_ddr_sr_exit_address(u64 address) +{ + g_ddr_sr_exit_address = address; +} u64 qclib_get_qcsdi_address(void) { @@ -36,6 +48,42 @@ void qclib_set_log_buffer_entry(u64 address) g_log_buffer_entry = address; } +int qclib_add_iftbl_entry(struct interface_table *table, + const char *name, u64 address, u32 size) +{ + uint entry_idx = table->num_entries; + + if (entry_idx >= table->max_entries) + return -ENOSPC; + + memset(&table->if_table_entries[entry_idx], 0, + sizeof(table->if_table_entries[entry_idx])); + memcpy(table->if_table_entries[entry_idx].entry_name, name, strlen(name)); + table->if_table_entries[entry_idx].address = address; + table->if_table_entries[entry_idx].size = size; + table->num_entries = entry_idx + 1; + + return 0; +} + +int qclib_add_iftbl_fit_blob(struct interface_table *table, + const void *fit, int images_node, + const char *name, u32 size) +{ + int node, ret; + u64 address; + + node = fdt_subnode_offset(fit, images_node, name); + if (node < 0) + return -ENOENT; + + ret = qcom_spl_get_fit_img_entry_point((void *)fit, node, &address); + if (ret) + return ret; + + return qclib_add_iftbl_entry(table, name, address, size); +} + bool __weak qcom_spl_soc_check_dload_mode(void) { return false; @@ -43,6 +91,8 @@ bool __weak qcom_spl_soc_check_dload_mode(void) int __weak qcom_spl_soc_pre_qclib_routine(void) { + qcom_spl_soc_shrm_reset(); + return 0; } @@ -60,7 +110,7 @@ int __weak qcom_spl_soc_post_qclib_routine(struct interface_table *if_tbl) int __weak qclib_populate_interface_table(struct interface_table *if_tbl, const void *fit, int images_node) { - struct interface_table_entry *log_buffer_entry; + int ret; memset(if_tbl, 0, sizeof(struct interface_table)); memcpy(if_tbl->magic_key, MAGIC_KEY, strlen(MAGIC_KEY)); @@ -68,17 +118,10 @@ int __weak qclib_populate_interface_table(struct interface_table *if_tbl, if_tbl->num_entries = 0; if_tbl->max_entries = MAX_ENTRIES; - /* - * Reserve the "qclib_log_buffer" slot ??? common to every SoC. - * QCLIB fills in the address itself; SPL just allocates the entry. - */ - log_buffer_entry = &if_tbl->if_table_entries[if_tbl->num_entries]; - memcpy(log_buffer_entry->entry_name, QCLIB_LOG_BUFFER, - strlen(QCLIB_LOG_BUFFER)); - log_buffer_entry->address = 0; - log_buffer_entry->size = 0; - log_buffer_entry->attributes = 0; - if_tbl->num_entries++; + /* Reserve the common qclib_log_buffer slot. */ + ret = qclib_add_iftbl_entry(if_tbl, QCLIB_LOG_BUFFER, 0, 0); + if (ret) + return ret; return qcom_spl_soc_qclib_override(if_tbl, fit, images_node); } @@ -146,9 +189,13 @@ int qcom_spl_invoke_qclib(void) register void *x0 asm("x0") = &if_tbl; register void *x1 asm("x1") = NULL; register u64 x8 asm("x8") = entry_point; + u64 saved_x18; - asm volatile ("blr x8" - : "+r" (x0) + /* U-Boot keeps global data in x18 on AArch64. */ + asm volatile ("str x18, %1\n\t" + "blr x8\n\t" + "ldr x18, %1" + : "+r" (x0), "=m" (saved_x18) : "r" (x1), "r" (x8) : "x2", "x3", "x4", "x5", "x6", "x7", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", -- 2.34.1
