From: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
To: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>,
rayagonda.kokatanur@broadcom.com, trini@konsulko.com,
casey.connolly@linaro.org, neil.armstrong@linaro.org,
sumit.garg@kernel.org, peng.fan@nxp.com, jh80.chung@samsung.com,
lukma@denx.de, tien.fong.chee@altera.com,
tingting.meng@altera.com, anshuld@ti.com,
alif.zakuan.yuslaimi@altera.com, alice.guo@nxp.com,
quentin.schulz@cherry.de, ilias.apalodimas@linaro.org,
sjg@chromium.org, mkorpershoek@kernel.org, h-salunke@ti.com,
alchark@gmail.com, dario.binacchi@amarulasolutions.com,
ye.li@nxp.com, andre.przywara@arm.com, dinesh.maniyam@altera.com,
luca.weiss@fairphone.com, danila@jiaxyga.com,
aswin.murugan@oss.qualcomm.com, adrian@mainlining.org,
n-francis@ti.com, wens@kernel.org, jamie.gibbons@microchip.com,
justin@tidylabs.net, ycliang@andestech.com,
david.wronek@mainlining.org, james.hilliard1@gmail.com,
richard.genoud@bootlin.com, michael@amarulasolutions.com,
philip.molloy@analog.com, sughosh.ganu@arm.com,
u-boot@lists.denx.de, u-boot-qcom@groups.io
Subject: Re: [PATCH v3 06/10] mach-snapdragon: Add initial support for IPQ5210 SPL
Date: Fri, 17 Apr 2026 09:52:46 +0530 [thread overview]
Message-ID: <47e34f39-e247-4d37-9fb2-2d6154615fc4@oss.qualcomm.com> (raw)
In-Reply-To: <20260416053928.2834699-7-varadarajan.narayanan@oss.qualcomm.com>
Hi,
On 4/16/2026 11:09 AM, Varadarajan Narayanan wrote:
> Add basic SPL infrastructure for IPQ5210 SoC. This handles basic serial
> console init, identifying the boot media, loading the additional
> firmware binaries to setup DDR, TFA and eventually jump to U-Boot.
>
> Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
> ---
> v3: Move SMEM updates to separate patch
> Loop upto if_tbl->num_entries instead of MAX_ENTRIES
> Remove invalid 'if (!fit)' check
> Return failure if qclib_post_process_from_spl fails
>
> v2: Remove couple of unused local variables
> ---
> arch/arm/Kconfig | 5 +-
> arch/arm/mach-snapdragon/Makefile | 3 +
> arch/arm/mach-snapdragon/spl.c | 640 ++++++++++++++++++++++++++++++
> 3 files changed, 646 insertions(+), 2 deletions(-)
> create mode 100644 arch/arm/mach-snapdragon/spl.c
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 03416c55265..54fa4cb2dac 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1135,12 +1135,13 @@ config ARCH_SNAPDRAGON
> select SPMI
> select BOARD_LATE_INIT
> select OF_BOARD
> - select SAVE_PREV_BL_FDT_ADDR if !ENABLE_ARM_SOC_BOOT0_HOOK
> - select LINUX_KERNEL_IMAGE_HEADER if !ENABLE_ARM_SOC_BOOT0_HOOK
> + select SAVE_PREV_BL_FDT_ADDR if !ENABLE_ARM_SOC_BOOT0_HOOK && !SPL
> + select LINUX_KERNEL_IMAGE_HEADER if !ENABLE_ARM_SOC_BOOT0_HOOK && !SPL
> select SYSRESET
> select SYSRESET_PSCI
> select ANDROID_BOOT_IMAGE_IGNORE_BLOB_ADDR
> select MMU_PGPROT
> + select SUPPORT_SPL
> imply OF_UPSTREAM
> imply CMD_DM
> imply DM_USB_GADGET
> diff --git a/arch/arm/mach-snapdragon/Makefile b/arch/arm/mach-snapdragon/Makefile
> index 343e825c6fd..70a2ce585f2 100644
> --- a/arch/arm/mach-snapdragon/Makefile
> +++ b/arch/arm/mach-snapdragon/Makefile
> @@ -2,6 +2,9 @@
> #
> # (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
>
> +ifndef CONFIG_XPL_BUILD
> obj-y += board.o
> obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += capsule_update.o
> obj-$(CONFIG_OF_LIVE) += of_fixup.o
> +endif
> +obj-$(CONFIG_SPL_BUILD) += spl.o
> diff --git a/arch/arm/mach-snapdragon/spl.c b/arch/arm/mach-snapdragon/spl.c
> new file mode 100644
> index 00000000000..8cc28bbee82
> --- /dev/null
> +++ b/arch/arm/mach-snapdragon/spl.c
> @@ -0,0 +1,640 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +#include <hang.h>
> +#include <cpu_func.h>
> +#include <init.h>
> +#include <image.h>
> +#include <spl.h>
> +#include <spl_load.h>
> +#include <asm/io.h>
> +#include <asm/system.h>
> +#include <asm/sections.h>
> +#include <atf_common.h>
> +#include <linux/err.h>
> +#include <dm/device-internal.h>
> +#include <part.h>
> +#include <blk.h>
> +#include <dm/uclass.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +#define QCOM_SPL_TCSR_REG_ADDR 0x195c100
> +#define QCOM_SPL_DLOAD_MASK BIT(4)
> +#define QCOM_SPL_DLOAD_SHFT 0x4
> +
> +#define QCOM_SPL_IS_DLOAD_BIT_SET ((readl(QCOM_SPL_TCSR_REG_ADDR) & \
> + QCOM_SPL_DLOAD_MASK) >> \
> + QCOM_SPL_DLOAD_SHFT)
> +
> +#define QCOM_SPL_FIT_IMG_PARTITION "0:BOOTLDR"
> +
> +#define MAGIC_KEY "QCLIB_CB"
> +#define MAX_ENTRIES 0xF
> +#define IF_TABLE_VERSION 0x1
> +#define QCCONFIG "qc_config"
> +#define QCSDI "qcsdi"
> +
> +/**
> + * struct interface_table_entry - Meta data for blobs in QCLIB interface
> + * @entry_name: Name of the data blob (e.g., "dcb_settings").
> + * @address: Address of the data blob.
> + * @size: Size of the data blob.
> + * @attributes: Attributes for the blob (e.g., save to storage).
> + */
> +struct interface_table_entry {
> + char entry_name[24];
> + u64 address;
> + u32 size;
> + u32 attributes;
> +};
> +
> +/**
> + * struct interface_table - QCLIB Interface table header
> + * @magic_key: Magic key for validation ("QCLIB_CB").
> + * @version: Interface table version.
> + * @num_entries: Number of valid entries.
> + * @max_entries: Maximum allowable entries.
> + * @global_attributes: Flags for global attributes (e.g., SDI path).
> + * @reserved1: Reserved for future use.
> + * @reserved2: Reserved for future use.
> + * @if_table_entries: Array of interface table entries.
> + */
> +struct interface_table {
> + char magic_key[8];
> + u32 version;
> + u32 num_entries;
> + u32 max_entries;
> + u32 global_attributes;
> + u32 reserved1;
> + u32 reserved2;
> + struct interface_table_entry if_table_entries[MAX_ENTRIES];
> +};
> +
> +/**
> + * qcom_spl_jump_img_entry_t - Type definition for image entry point functions.
> + * @arg1: First argument passed to the entry point.
> + * @arg2: Second argument passed to the entry point.
> + */
> +typedef void (*qcom_spl_jump_img_entry_t)(void *arg1, void *arg2);
> +
> +/*
> + * Global QCSDI address populated by qclib_post_process_from_spl
> + * Placed in .data section to ensure it persists
> + */
> +static u64 g_qcsdi_address __section(".data");
> +
> +/**
> + * lowlevel_init() - Early low-level initialization.
> + *
> + * This function performs very early hardware initialization,
> + * specifically disabling the MMU if enabled by PBL.
> + */
> +void lowlevel_init(void)
> +{
> + unsigned long sctlr;
> +
> + sctlr = get_sctlr();
> + set_sctlr(sctlr & ~(CR_M)); /* Early disable the MMU */
> +}
> +
> +/**
> + * qcom_spl_error_handler() - Centralized SPL error handler.
> + * @arg: Generic argument (unused).
> + *
> + * This function is invoked upon critical errors during the SPL boot process.
> + */
> +void qcom_spl_error_handler(void *arg)
> +{
> + pr_err("Entered the SPL Error Handler\n");
> + hang();
> +}
> +
> +/**
> + * qcom_spl_malloc_init_f() - Initialize malloc for SPL.
> + *
> + * This function initializes the malloc subsystem using the memory region
> + */
> +void qcom_spl_malloc_init_f(void)
> +{
> + if (!CONFIG_IS_ENABLED(SYS_MALLOC_F))
> + return;
> + /*
> + * Set up by crt0.S
> + */
> + assert(gd->malloc_base);
> + gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN);
> + gd->malloc_ptr = 0;
> +
> + mem_malloc_init(gd->malloc_base, gd->malloc_limit);
> + gd->flags |= GD_FLG_FULL_MALLOC_INIT;
> +}
> +
> +/**
> + * qcom_spl_get_fit_img_entry_point() - Get entry point from FIT image node.
> + * @fit: Pointer to the FIT image blob.
> + * @node: Node ID within the FIT image.
> + * @entry_point:Pointer to store the retrieved entry point.
> + *
> + * Return: 0 on success, or a negative error code on failure.
> + */
> +static int qcom_spl_get_fit_img_entry_point(void *fit, int node,
> + u64 *entry_point)
> +{
> + int ret;
> +
> + if (!fit) {
> + pr_err("FIT image blob is NULL\n");
> + return -EINVAL;
> + }
> + if (node <= 0) {
> + pr_err("Invalid FIT node ID %d\n", node);
> + return -EINVAL;
> + }
> + if (!entry_point) {
> + pr_err("Entry point pointer is NULL\n");
> + return -EINVAL;
> + }
> +
> + ret = fit_image_get_entry(fit, node, (ulong *)entry_point);
> + if (ret) {
> + pr_debug("No entry point for node %d, trying load address\n",
> + node);
> + ret = fit_image_get_load(fit, node, (ulong *)entry_point);
> + if (ret)
> + pr_err("No load address for node %d (%d)\n", node, ret);
> + }
> +
> + return ret;
> +}
> +
> +/**
> + * qcom_spl_get_iftbl_entry_by_name() - Get an interface table entry by name.
> + * @if_tbl: Pointer to the QCLIB interface table.
> + * @name: Name of the entry to find.
> + * @entry: Pointer to a buffer where the found entry will be copied.
> + *
> + * Return: 0 on success, or a negative error code on failure.
> + */
> +static int qcom_spl_get_iftbl_entry_by_name(struct interface_table *if_tbl,
> + char *name,
> + struct interface_table_entry *entry)
> +{
> + uint uc_index;
> +
> + if (!if_tbl) {
> + pr_err("Invalid interface table\n");
> + return -EINVAL;
> + }
> + if (!name) {
> + pr_err("Invalid name\n");
> + return -EINVAL;
> + }
> + if (!entry) {
> + pr_err("Invalid entry pointer\n");
> + return -EINVAL;
> + }
> +
> + for (uc_index = 0; uc_index < if_tbl->num_entries; uc_index++) {
> + if (!strcmp(if_tbl->if_table_entries[uc_index].entry_name, name)) {
> + memcpy(entry,
> + &if_tbl->if_table_entries[uc_index],
> + sizeof(struct interface_table_entry));
> + return 0;
> + }
> + }
> + pr_err("Interface table entry '%s' not found\n", name);
> +
> + return -ENOENT;
> +}
> +
> +/**
> + * qclib_post_process_from_spl() - Post-process QCLIB image from SPL FIT address
> + *
> + * This function performs the same operations as qclib_post_process() but
> + * takes no arguments. It gets the FIT image from CONFIG_SPL_LOAD_FIT_ADDRESS
> + * and finds the qclib_1 node automatically.
> + *
> + * Return: 0 on success, or a negative error code on failure.
> + */
> +int qclib_post_process_from_spl(void)
> +{
> + int ret;
> + int entry_idx;
> + int images_node;
> + int qcconfig_node;
> + int qclib_node;
> + const void *fit;
> + struct interface_table if_tbl;
> + struct interface_table_entry qcsdi_entry;
> + qcom_spl_jump_img_entry_t qclib_entry;
> + u64 entry_point;
> +
> + /* Get FIT image from SPL load address */
> + fit = (const void *)CONFIG_SPL_LOAD_FIT_ADDRESS;
> +
> + pr_debug("QCLIB post-processing from SPL: fit=%p\n", fit);
> +
> + /*
> + * Find "images" node in FIT (get it once and reuse)
> + */
> + images_node = fdt_subnode_offset(fit, 0, "images");
> + if (images_node < 0) {
> + pr_err("Failed to find images node in FIT\n");
> + return -ENOENT;
> + }
> +
> + /*
> + * Find "qcconfig_1" image 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;
> + }
> +
> + /*
> + * Find "qclib_1" image node
> + */
> + qclib_node = fdt_subnode_offset(fit, images_node, "qclib_1");
> + if (qclib_node < 0) {
> + pr_err("Failed to find qclib_1 node in FIT\n");
> + return -ENOENT;
> + }
> +
> + /*
> + * Initialize the local interface table
> + */
> + memset(&if_tbl, 0, sizeof(struct interface_table));
> + memcpy(if_tbl.magic_key, MAGIC_KEY, strlen(MAGIC_KEY));
> +
> + if_tbl.version = IF_TABLE_VERSION;
> + if_tbl.num_entries = 0;
> + if_tbl.max_entries = MAX_ENTRIES;
> +
> + /*
> + * Add QCCONFIG entry to the interface table
> + */
> + entry_idx = 0;
> + memcpy(if_tbl.if_table_entries[entry_idx].entry_name,
> + QCCONFIG, strlen(QCCONFIG));
> +
> + ret = qcom_spl_get_fit_img_entry_point((void *)fit,
> + qcconfig_node,
> + &if_tbl.if_table_entries[entry_idx].address);
> + if (ret) {
> + pr_err("Failed to get qcconfig_1 entry point (%d)\n", ret);
> + return ret;
> + }
> + if_tbl.if_table_entries[entry_idx].attributes = 0;
> + if_tbl.num_entries = entry_idx + 1;
> +
> + /*
> + * Add QCSDI entry to the interface table
> + */
> + entry_idx++;
> + memcpy(if_tbl.if_table_entries[entry_idx].entry_name,
> + QCSDI, strlen(QCSDI));
> +
> + if_tbl.if_table_entries[entry_idx].address = 0;
> + if_tbl.if_table_entries[entry_idx].attributes = 0;
> + if_tbl.num_entries = entry_idx + 1;
> +
> + /*
> + * Get qclib_1 entry point
> + */
> + ret = qcom_spl_get_fit_img_entry_point((void *)fit,
> + qclib_node,
> + &entry_point);
> + if (ret) {
> + pr_err("Failed to get qclib_1 entry point (%d)\n", ret);
> + return ret;
> + }
> +
> + qclib_entry = (qcom_spl_jump_img_entry_t)entry_point;
> +
> + pr_info("Jumping to qclib_1 at 0x%llx\n", entry_point);
> + qclib_entry(&if_tbl, NULL);
> +
> + /* Parse the interface table to extract QCSDI address */
> + 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;
> + }
> +
> + g_qcsdi_address = qcsdi_entry.address;
> + pr_info("QCSDI address: 0x%llx\n", g_qcsdi_address);
> +
> + return 0;
> +}
> +
> +
> +/**
> + * spl_get_load_buffer() - Allocate a cache-aligned buffer for image loading.
> + * @offset: Offset (unused, typically 0 for SPL).
> + * @size: Size of the buffer to allocate.
> + *
> + * Return: Pointer to the allocated buffer, or NULL on failure.
> + */
> +struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size)
> +{
> + return (void *)(CONFIG_SPL_LOAD_FIT_ADDRESS);
> +}
> +
> +/**
> + * board_spl_fit_buffer_addr() - Get the address of the FIT image buffer.
> + * @fit_size: Size of the FIT image.
> + * @sectors: Number of sectors.
> + * @bl_len: Block length.
> + *
> + * Return: Address of the FIT image buffer.
> + */
> +void *board_spl_fit_buffer_addr(ulong fit_size, int sectors, int bl_len)
> +{
> + void *buffer = spl_get_load_buffer(0, sectors * bl_len);
> +
> + if (!buffer) {
> + pr_err("Failed to get FIT load buffer\n");
> + qcom_spl_error_handler(NULL);
> + }
> +
> + return buffer;
> +}
> +
> +/**
> + * bl2_plat_get_bl31_params_v2() - Retrieve and fixup BL31 parameters.
> + * @bl32_entry: Entry point for BL32 (OP-TEE).
> + * @bl33_entry: Entry point for BL33 (U-Boot/kernel).
> + * @fdt_addr: Address of the Device Tree Blob (FDT).
> + *
> + * Return: Pointer to the populated BL31 parameters structure.
> + */
> +struct bl_params *bl2_plat_get_bl31_params_v2(uintptr_t bl32_entry,
> + uintptr_t bl33_entry,
> + uintptr_t fdt_addr)
> +{
> + struct bl_params *bl_params;
> + struct bl_params_node *node;
> +
> + /*
> + * Populate the bl31 params with default values.
> + */
> + bl_params = bl2_plat_get_bl31_params_v2_default(bl32_entry, bl33_entry,
> + fdt_addr);
> +
> + /*
> + * Fixup the bl31 params based on platform requirements.
> + */
> + for_each_bl_params_node(bl_params, node) {
> + if (node->image_id == ATF_BL31_IMAGE_ID) {
> + /*
> + * Pass QCSDI address to BL31 via arg0
> + * This address was populated by qclib_post_process()
> + */
> + if (g_qcsdi_address == 0)
> + pr_warn("QCSDI address not set, BL31 may not function correctly\n");
> +
> + node->ep_info->args.arg0 = g_qcsdi_address;
> + pr_debug("Setting BL31 arg0 to QCSDI address: 0x%llx\n", g_qcsdi_address);
> + }
> + }
> +
> + return bl_params;
> +}
> +
> +/**
> + * qcom_spl_loader_pre_ddr() - SPL loader for pre-DDR stage.
> + * @boot_device:Type of boot device.
> + *
> + * Return: 0 on success, or a negative error code on failure.
> + */
> +static int qcom_spl_loader_pre_ddr(u8 boot_device)
> +{
> + struct spl_image_loader *loader, *drv;
> + struct spl_image_info spl_image = { 0 };
> + struct spl_boot_device boot_dev = { .boot_device = boot_device, };
> + int ret = -ENODEV, n_ents;
> +
> + drv = ll_entry_start(struct spl_image_loader, spl_image_loader);
> + n_ents = ll_entry_count(struct spl_image_loader, spl_image_loader);
> +
> + for (loader = drv; loader && (loader != drv + n_ents); loader++) {
> + if (boot_device != loader->boot_device)
> + continue;
> +
> + ret = loader->load_image(&spl_image, &boot_dev);
> + if (!ret)
> + break;
> +
> + printf("%s: Error: %d\n", __func__, ret);
> + }
> +
> + return ret;
> +}
> +
> +/**
> + * spl_find_partition_info() - Find partition information by name
> + * @uclass_id: Device class ID (UCLASS_MMC)
> + * @device_num: Device number within the class
> + * @part_name: Name of the partition to find
> + * @info: Pointer to store partition information
> + *
> + * This function provides partition lookup logic for MMC.
> + * Return: Partition number on success, negative error code on failure
> + */
> +static int spl_find_partition_info(enum uclass_id uclass_id, int device_num,
> + const char *part_name,
> + struct disk_partition *info)
> +{
> + int ret;
> + struct blk_desc *desc;
> +
> + if (!part_name || !info) {
> + printf("Invalid parameters for partition lookup\n");
> + return -EINVAL;
> + }
> +
> + /*
> + * Get block device descriptor
> + */
> + desc = blk_get_devnum_by_uclass_id(uclass_id, device_num);
> + if (!desc) {
> + printf("Block device not found for class %d, device %d\n",
> + uclass_id, device_num);
> + return -ENODEV;
> + }
> +
> + /*
> + * Initialize partition table if needed
> + */
> + if (desc->part_type == PART_TYPE_UNKNOWN) {
> + printf("Initializing partition table\n");
> + /*
> + * Prefer EFI/GPT
> + */
> + desc->part_type = PART_TYPE_EFI;
> + }
> +
> + /*
> + * Find partition by name
> + */
> + ret = part_get_info_by_name(desc, part_name, info);
> + if (ret < 0) {
> + printf("Partition '%s' not found\n", part_name);
> + return -ENOENT;
> + }
> +
> + printf("Found partition '%s' at partition number %d\n", part_name, ret);
> + return ret;
> +}
> +
> +#if CONFIG_IS_ENABLED(MMC)
> +/**
> + * spl_mmc_boot_mode() - Determine the boot mode for MMC
> + * @mmc: Pointer to the MMC device
> + * @boot_device: Boot device ID
> + *
> + * Return: MMCSD_MODE_RAW to use raw partition access
> + */
> +u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
> +{
> + return MMCSD_MODE_RAW;
> +}
> +
> +/**
> + * spl_mmc_boot_partition() - Determine which partition to boot from
> + * @boot_device: Boot device ID
> + *
> + * Return: Partition number to boot from, or default partition on error
> + */
> +int spl_mmc_boot_partition(const u32 boot_device)
> +{
> + int ret;
> + struct disk_partition info;
> +
> + /*
> + * Use common partition lookup function
> + */
> + ret = spl_find_partition_info(UCLASS_MMC, 0, QCOM_SPL_FIT_IMG_PARTITION, &info);
> + if (ret < 0) {
> + printf("Using default MMC partition %d\n",
> + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION);
> + return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION;
> + }
> +
> + return ret;
> +}
> +
> +/**
> + * spl_mmc_get_uboot_raw_sector() - Find the raw sector offset
> + * @mmc: Pointer to the MMC device
> + * @raw_sect: Sector
> + *
> + * Return: 0 if the image is at the starting of the partition without any offset.
> + */
> +unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc, ulong raw_sect)
> +{
> + return 0;
> +}
> +#endif /* CONFIG_IS_ENABLED(MMC) */
> +
> +/**
> + * spl_boot_device() - Determine the boot device.
> + *
> + * Return: The mapped boot device type,
> + * or BOOT_DEVICE_NONE if the device is invalid.
> + */
> +u32 spl_boot_device(void)
> +{
> + if (IS_ENABLED(CONFIG_SPL_MMC)) {
> + printf("Selected boot device: MMC\n");
> + return BOOT_DEVICE_MMC1;
> + }
> +
> + pr_err("No boot device configured\n");
> + return BOOT_DEVICE_NONE;
> +}
> +
> +#if defined(CONFIG_SPL_BUILD) && !defined(CONFIG_SPL_FRAMEWORK_BOARD_INIT_F)
I think support for CONFIG_SPL_FRAMEWORK_BOARD_INIT_F config is removed.
So can we remove the check based on this config?
Regards,
Balaji
> +/**
> + * board_init_f() - Main entry point for SPL.
> + * @dummy: Dummy argument (unused).
> + */
> +void board_init_f(ulong dummy)
> +{
> + int ret;
> +
> + memset(__bss_start, 0, __bss_end - __bss_start); /* Clear BSS */
> +
> + qcom_spl_malloc_init_f();
> +
> + ret = spl_early_init();
> + if (ret) {
> + pr_debug("spl_early_init() failed (%d)\n", ret);
> + goto fail;
> + }
> +
> + preloader_console_init();
> +
> + ret = qcom_spl_loader_pre_ddr(spl_boot_device());
> + if (ret) {
> + pr_debug("qcom_spl_loader_pre_ddr() failed (%d)\n", ret);
> + goto fail;
> + }
> +
> + ret = qclib_post_process_from_spl();
> + if (ret) {
> + pr_debug("qclib_post_process_from_spl() failed (%d)\n", ret);
> + goto fail;
> + }
> +
> + board_init_r(NULL, 0);
> +
> +fail:
> + if (ret)
> + qcom_spl_error_handler(NULL);
> +}
> +#endif /* CONFIG_SPL_BUILD && !defined(CONFIG_SPL_FRAMEWORK_BOARD_INIT_F) */
> +
> +int board_fit_config_name_match(const char *name)
> +{
> + /*
> + * SPL loads the pre-HLOS images from bootldr FIT image
> + * as below
> + *
> + * In board_init_f() - Matches "pre-ddr" configuration node and
> + * load the images mentioned in its <loadables>
> + *
> + * In board_init_r() - Matches "post-ddr" configuration node and
> + * load the images mentioned in its <loadables>
> + *
> + */
> + if (!(gd->flags & GD_FLG_SPL_INIT)) {
> + if (!strcmp(name, "pre-ddr")) {
> + printf("Selected FIT Config: %s\n", name);
> + return 0;
> + }
> + } else {
> + if (!strcmp(name, "post-ddr")) {
> + printf("Selected FIT Config: %s\n", name);
> + return 0;
> + }
> + }
> +
> + return -EINVAL;
> +}
> +
> +int board_fdt_blob_setup(void **fdtp)
> +{
> + return 0;
> +}
> +
> +void reset_cpu(void)
> +{
> + /*
> + * Empty placeholder for arch/arm/lib/reset.c:do_reset(),
> + * to avoid "undefined reference to `reset_cpu'"
> + */
> +}
next prev parent reply other threads:[~2026-04-17 12:47 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-16 5:39 [PATCH v3 00/10] Qualcomm IPQ5210 SoC bringup Varadarajan Narayanan
2026-04-16 5:39 ` [PATCH v3 01/10] dts: ipq5210-rdp504-u-boot: add override dtsi Varadarajan Narayanan
2026-04-16 5:39 ` [PATCH v3 02/10] clk/qcom: add initial clock driver for ipq5210 Varadarajan Narayanan
2026-04-16 20:52 ` Simon Glass
2026-04-16 5:39 ` [PATCH v3 03/10] pinctrl: qcom: Add ipq5210 pinctrl driver Varadarajan Narayanan
2026-04-16 20:53 ` Simon Glass
2026-04-16 5:39 ` [PATCH v3 04/10] misc: qcom_geni: Add minicore support Varadarajan Narayanan
2026-04-16 20:53 ` Simon Glass
2026-04-16 5:39 ` [PATCH v3 05/10] spl: Include SMEM driver in SPL Varadarajan Narayanan
2026-04-16 5:39 ` [PATCH v3 06/10] mach-snapdragon: Add initial support for IPQ5210 SPL Varadarajan Narayanan
2026-04-16 20:53 ` Simon Glass
2026-04-17 4:22 ` Balaji Selvanathan [this message]
2026-04-16 5:39 ` [PATCH v3 07/10] mach-snapdragon: spl: Update SMEM with boot details Varadarajan Narayanan
2026-04-16 20:54 ` Simon Glass
2026-04-16 5:39 ` [PATCH v3 08/10] mach-snapdragon: Add commands to create wrapper ELF Varadarajan Narayanan
2026-04-16 20:54 ` Simon Glass
2026-04-16 5:39 ` [PATCH v3 09/10] configs: add qcom_ipq5210_mmc_defconfig Varadarajan Narayanan
2026-04-16 5:39 ` [PATCH v3 10/10] doc: board/qualcomm: Update RDP build instructions Varadarajan Narayanan
2026-04-16 20:54 ` Simon Glass
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=47e34f39-e247-4d37-9fb2-2d6154615fc4@oss.qualcomm.com \
--to=balaji.selvanathan@oss.qualcomm.com \
--cc=adrian@mainlining.org \
--cc=alchark@gmail.com \
--cc=alice.guo@nxp.com \
--cc=alif.zakuan.yuslaimi@altera.com \
--cc=andre.przywara@arm.com \
--cc=anshuld@ti.com \
--cc=aswin.murugan@oss.qualcomm.com \
--cc=casey.connolly@linaro.org \
--cc=danila@jiaxyga.com \
--cc=dario.binacchi@amarulasolutions.com \
--cc=david.wronek@mainlining.org \
--cc=dinesh.maniyam@altera.com \
--cc=h-salunke@ti.com \
--cc=ilias.apalodimas@linaro.org \
--cc=james.hilliard1@gmail.com \
--cc=jamie.gibbons@microchip.com \
--cc=jh80.chung@samsung.com \
--cc=justin@tidylabs.net \
--cc=luca.weiss@fairphone.com \
--cc=lukma@denx.de \
--cc=michael@amarulasolutions.com \
--cc=mkorpershoek@kernel.org \
--cc=n-francis@ti.com \
--cc=neil.armstrong@linaro.org \
--cc=peng.fan@nxp.com \
--cc=philip.molloy@analog.com \
--cc=quentin.schulz@cherry.de \
--cc=rayagonda.kokatanur@broadcom.com \
--cc=richard.genoud@bootlin.com \
--cc=sjg@chromium.org \
--cc=sughosh.ganu@arm.com \
--cc=sumit.garg@kernel.org \
--cc=tien.fong.chee@altera.com \
--cc=tingting.meng@altera.com \
--cc=trini@konsulko.com \
--cc=u-boot-qcom@groups.io \
--cc=u-boot@lists.denx.de \
--cc=varadarajan.narayanan@oss.qualcomm.com \
--cc=wens@kernel.org \
--cc=ycliang@andestech.com \
--cc=ye.li@nxp.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox