This patch adds the basic board init routines that invoke the common and mach-snapdragon specific SPL frameworks to proceed with the hand over from boot rom to the next stage i.e. U-Boot proper. This also provides the linker script to generate the SPL image in the format expected by the boot rom.
Reviewed-by: Balaji Selvanathan <[email protected]> Reviewed-by: Simon Glass <[email protected]> Signed-off-by: Varadarajan Narayanan <[email protected]> --- arch/arm/mach-snapdragon/board_spl.c | 2 + arch/arm/mach-snapdragon/include/mach/spl.h | 13 ++++ board/qualcomm/ipq5210/Makefile | 3 + board/qualcomm/ipq5210/ipq5210-spl-wrap-elf.lds | 18 +++++ board/qualcomm/ipq5210/spl-ipq5210.c | 99 +++++++++++++++++++++++++ include/configs/ipq5210.h | 11 +++ 6 files changed, 146 insertions(+) diff --git a/arch/arm/mach-snapdragon/board_spl.c b/arch/arm/mach-snapdragon/board_spl.c index 2655803b31e..3293eab8f81 100644 --- a/arch/arm/mach-snapdragon/board_spl.c +++ b/arch/arm/mach-snapdragon/board_spl.c @@ -12,6 +12,8 @@ #include <spl.h> #include <soc/qcom/smem.h> +DECLARE_GLOBAL_DATA_PTR; + /* in SPL, we always use internal DT */ int __weak board_fdt_blob_setup(void **fdtp) { diff --git a/arch/arm/mach-snapdragon/include/mach/spl.h b/arch/arm/mach-snapdragon/include/mach/spl.h new file mode 100644 index 00000000000..50cc8dc4e8f --- /dev/null +++ b/arch/arm/mach-snapdragon/include/mach/spl.h @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef __SPL_H__ +#define __SPL_H__ + +void qcom_spl_malloc_init_f(void); +int qcom_spl_loader_pre_ddr(u8 boot_device); +void qcom_spl_error_handler(void *arg); + +#endif /* __SPL_H__ */ diff --git a/board/qualcomm/ipq5210/Makefile b/board/qualcomm/ipq5210/Makefile new file mode 100644 index 00000000000..d808c106524 --- /dev/null +++ b/board/qualcomm/ipq5210/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_SPL) := spl-ipq5210.o diff --git a/board/qualcomm/ipq5210/ipq5210-spl-wrap-elf.lds b/board/qualcomm/ipq5210/ipq5210-spl-wrap-elf.lds new file mode 100644 index 00000000000..f0ced6765da --- /dev/null +++ b/board/qualcomm/ipq5210/ipq5210-spl-wrap-elf.lds @@ -0,0 +1,18 @@ +/* + * SPDX-License-Identifier: GPL-2.0 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +PHDRS { + ptype PT_LOAD FLAGS(0x7); +} + +ENTRY(_entry) + +SECTIONS { + . = CONFIG_PLATFORM_ELFENTRY; + _entry = . ; + data : { + *(.data) + . = ALIGN(4); + } :ptype +} diff --git a/board/qualcomm/ipq5210/spl-ipq5210.c b/board/qualcomm/ipq5210/spl-ipq5210.c new file mode 100644 index 00000000000..5fc42e64c11 --- /dev/null +++ b/board/qualcomm/ipq5210/spl-ipq5210.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +#include <hang.h> +#include <cpu_func.h> +#include <event.h> +#include <init.h> +#include <image.h> +#include <linux/string.h> +#include <spl.h> +#include <spl_load.h> +#include <asm/io.h> +#include <asm/system.h> +#include <asm/sections.h> +#include <soc/qcom/smem.h> +#include <atf_common.h> +#include <linux/err.h> +#include <dm/device-internal.h> +#include <part.h> +#include <blk.h> +#include <dm/uclass.h> +#include <mach/qclib.h> +#include <mach/spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define QCCONFIG "qc_config" + +/** + * qcom_spl_soc_qclib_override() - Populate ipq5210-specific interface table + * entries. + * @table: Pointer to the QCLIB interface table being built. + * @fit: Pointer to the FIT image blob. + * @images_node: FIT "images" node offset. + * + * Appends the "qc_config" entry and a placeholder "qcsdi" entry, filled in by QCLIB itself. + * + * Return: 0 on success, or a negative error code on failure. + */ +int qcom_spl_soc_qclib_override(struct interface_table *table, + const void *fit, int images_node) +{ + int ret; + int entry_idx; + int qcconfig_node; + + qcconfig_node = fdt_subnode_offset(fit, images_node, "qcconfig_1"); + if (qcconfig_node < 0) { + pr_err("Failed to find qcconfig_1 node in FIT\n"); + return -ENOENT; + } + + entry_idx = table->num_entries; + memcpy(table->if_table_entries[entry_idx].entry_name, + QCCONFIG, strlen(QCCONFIG)); + + ret = qcom_spl_get_fit_img_entry_point((void *)fit, qcconfig_node, + &table->if_table_entries[entry_idx].address); + if (ret) { + pr_err("Failed to get qcconfig_1 entry point (%d)\n", ret); + return ret; + } + table->if_table_entries[entry_idx].attributes = 0; + table->num_entries = entry_idx + 1; + + entry_idx++; + memcpy(table->if_table_entries[entry_idx].entry_name, + QCSDI, strlen(QCSDI)); + table->if_table_entries[entry_idx].address = 0; + table->if_table_entries[entry_idx].attributes = 0; + table->num_entries = entry_idx + 1; + + return 0; +} + +/** + * qcom_spl_soc_post_qclib_routine() - Cache the QCSDI address after QCLIB + * returns. + * @if_tbl: Pointer to the QCLIB interface table, populated by QCLIB. + * + * Return: 0 on success, or a negative error code on failure. + */ +int qcom_spl_soc_post_qclib_routine(struct interface_table *if_tbl) +{ + int ret; + struct interface_table_entry qcsdi_entry; + + ret = qcom_spl_get_iftbl_entry_by_name(if_tbl, QCSDI, &qcsdi_entry); + if (ret) { + pr_err("Failed to get QCSDI entry from interface table (%d)\n", ret); + return ret; + } + + qclib_set_qcsdi_address(qcsdi_entry.address); + pr_info("QCSDI address: 0x%llx\n", qcsdi_entry.address); + + return 0; +} diff --git a/include/configs/ipq5210.h b/include/configs/ipq5210.h new file mode 100644 index 00000000000..5cbf838af82 --- /dev/null +++ b/include/configs/ipq5210.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef __CONFIGS_IPQ5210_H +#define __CONFIGS_IPQ5210_H + +#include <linux/sizes.h> + +#endif -- 2.34.1
