public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [PATCH v3 00/10] Qualcomm IPQ5210 SoC bringup
@ 2026-04-16  5:39 Varadarajan Narayanan
  2026-04-16  5:39 ` [PATCH v3 01/10] dts: ipq5210-rdp504-u-boot: add override dtsi Varadarajan Narayanan
                   ` (9 more replies)
  0 siblings, 10 replies; 19+ messages in thread
From: Varadarajan Narayanan @ 2026-04-16  5:39 UTC (permalink / raw)
  To: rayagonda.kokatanur, trini, casey.connolly, neil.armstrong,
	sumit.garg, peng.fan, jh80.chung, lukma, tien.fong.chee,
	tingting.meng, anshuld, alif.zakuan.yuslaimi, alice.guo,
	quentin.schulz, ilias.apalodimas, varadarajan.narayanan, sjg,
	mkorpershoek, h-salunke, alchark, dario.binacchi, ye.li,
	andre.przywara, dinesh.maniyam, luca.weiss, danila, aswin.murugan,
	balaji.selvanathan, adrian, n-francis, wens, jamie.gibbons,
	justin, ycliang, david.wronek, james.hilliard1, richard.genoud,
	michael, philip.molloy, sughosh.ganu, u-boot, u-boot-qcom

Add pinctrl, clock drivers and SPL to support the IPPQ5210 SoC in U-Boot.

The relevant DT files are available in linux-next [1].

Working features, as tested on RDP504:
	* Serial console
	* UART
	* MMC
	* Boot sequence transitions from Boot ROM to U-Boot SPL, proprietary
	  binaries (a.k.a QCLib) load and execute as appropriate and eventual
	  jump to U-Boot.
	* The QCLib handles
		- DDR initialization
		- Clock setup

1 - https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm64/boot/dts/qcom/ipq5210.dtsi
    https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm64/boot/dts/qcom/ipq5210-rdp504.dts
    https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/include/dt-bindings/clock/qcom,ipq5210-gcc.h
    https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/include/dt-bindings/reset/qcom,ipq5210-gcc.h

v3:	- Move stack range
	- Split spl.c patch
	- Move documentation towards the end of the series
	- Pick couple of R-b

v2:	- Add QCOM_GENI_MINICORE config option
	- Move minicore register settings to separate file and include
	  if QCOM_GENI_MINICORE is enabled
	- Remove bootph-all from override dts and moved them to kernel
	  DT - https://lore.kernel.org/linux-arm-msm/20260409-add_bootph-v1-1-cb2b5093f7d7@oss.qualcomm.com/T/#u
	- https://lore.kernel.org/u-boot/20260410091154.1001021-1-varadarajan.narayanan@oss.qualcomm.com/

v1: https://lore.kernel.org/u-boot/20260408091136.2794546-1-varadarajan.narayanan@oss.qualcomm.com/

Varadarajan Narayanan (10):
  dts: ipq5210-rdp504-u-boot: add override dtsi
  clk/qcom: add initial clock driver for ipq5210
  pinctrl: qcom: Add ipq5210 pinctrl driver
  misc: qcom_geni: Add minicore support
  spl: Include SMEM driver in SPL
  mach-snapdragon: Add initial support for IPQ5210 SPL
  mach-snapdragon: spl: Update SMEM with boot details
  mach-snapdragon: Add commands to create wrapper ELF
  configs: add qcom_ipq5210_mmc_defconfig
  doc: board/qualcomm: Update RDP build instructions

 arch/arm/Kconfig                              |   5 +-
 arch/arm/dts/ipq5210-rdp504-u-boot.dtsi       |  15 +
 arch/arm/mach-snapdragon/Kconfig              |   7 +
 arch/arm/mach-snapdragon/Makefile             |   3 +
 .../mach-snapdragon/ipq5210-spl-wrap-elf.lds  |  18 +
 arch/arm/mach-snapdragon/spl.c                | 705 ++++++++++++++++++
 common/spl/Kconfig                            |   8 +
 configs/qcom_ipq5210_mmc_defconfig            | 106 +++
 doc/board/qualcomm/rdp.rst                    |  70 ++
 drivers/Makefile                              |   1 +
 drivers/clk/qcom/Kconfig                      |   8 +
 drivers/clk/qcom/Makefile                     |   1 +
 drivers/clk/qcom/clock-ipq5210.c              |  97 +++
 drivers/misc/Kconfig                          |   6 +
 drivers/misc/Makefile                         |   1 +
 drivers/misc/qcom_geni-minicore.c             | 102 +++
 drivers/misc/qcom_geni.c                      |  94 ++-
 drivers/pinctrl/qcom/Kconfig                  |   8 +
 drivers/pinctrl/qcom/Makefile                 |   1 +
 drivers/pinctrl/qcom/pinctrl-ipq5210.c        | 349 +++++++++
 include/smem.h                                |   3 +
 include/soc/qcom/geni-se.h                    |   2 +
 include/soc/qcom/qup-fw-load.h                |  15 +
 scripts/Makefile.xpl                          |  24 +
 24 files changed, 1635 insertions(+), 14 deletions(-)
 create mode 100644 arch/arm/dts/ipq5210-rdp504-u-boot.dtsi
 create mode 100644 arch/arm/mach-snapdragon/ipq5210-spl-wrap-elf.lds
 create mode 100644 arch/arm/mach-snapdragon/spl.c
 create mode 100644 configs/qcom_ipq5210_mmc_defconfig
 create mode 100644 drivers/clk/qcom/clock-ipq5210.c
 create mode 100644 drivers/misc/qcom_geni-minicore.c
 create mode 100644 drivers/pinctrl/qcom/pinctrl-ipq5210.c

-- 
2.34.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v3 01/10] dts: ipq5210-rdp504-u-boot: add override dtsi
  2026-04-16  5:39 [PATCH v3 00/10] Qualcomm IPQ5210 SoC bringup Varadarajan Narayanan
@ 2026-04-16  5:39 ` Varadarajan Narayanan
  2026-04-16  5:39 ` [PATCH v3 02/10] clk/qcom: add initial clock driver for ipq5210 Varadarajan Narayanan
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Varadarajan Narayanan @ 2026-04-16  5:39 UTC (permalink / raw)
  To: rayagonda.kokatanur, trini, casey.connolly, neil.armstrong,
	sumit.garg, peng.fan, jh80.chung, lukma, tien.fong.chee,
	tingting.meng, anshuld, alif.zakuan.yuslaimi, alice.guo,
	quentin.schulz, ilias.apalodimas, varadarajan.narayanan, sjg,
	mkorpershoek, h-salunke, alchark, dario.binacchi, ye.li,
	andre.przywara, dinesh.maniyam, luca.weiss, danila, aswin.murugan,
	balaji.selvanathan, adrian, n-francis, wens, jamie.gibbons,
	justin, ycliang, david.wronek, james.hilliard1, richard.genoud,
	michael, philip.molloy, sughosh.ganu, u-boot, u-boot-qcom

* Add initial support for the IPQ5210 MMC based RDP platforms.
* Define memory layout statically.
* Mark the nodes that would be needed for SPL.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
---
v3: Pick R-b Simon
v2: Remove sdhc as it is in kernel DT already
    Move bootph-all to kernel DT - https://lore.kernel.org/linux-arm-msm/20260409-add_bootph-v1-1-cb2b5093f7d7@oss.qualcomm.com/T/#u
---
 arch/arm/dts/ipq5210-rdp504-u-boot.dtsi | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
 create mode 100644 arch/arm/dts/ipq5210-rdp504-u-boot.dtsi

diff --git a/arch/arm/dts/ipq5210-rdp504-u-boot.dtsi b/arch/arm/dts/ipq5210-rdp504-u-boot.dtsi
new file mode 100644
index 00000000000..5f0105d20de
--- /dev/null
+++ b/arch/arm/dts/ipq5210-rdp504-u-boot.dtsi
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IPQ5210 RDP504 board device tree source
+ *
+ * Copyright (c) 2025 The Linux Foundation. All rights reserved.
+ */
+
+/ {
+	/* Will be removed when SMEM parsing is updated */
+	memory@80000000 {
+		bootph-all;
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x0 0x20000000>;
+	};
+};
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 02/10] clk/qcom: add initial clock driver for ipq5210
  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 ` 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
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Varadarajan Narayanan @ 2026-04-16  5:39 UTC (permalink / raw)
  To: rayagonda.kokatanur, trini, casey.connolly, neil.armstrong,
	sumit.garg, peng.fan, jh80.chung, lukma, tien.fong.chee,
	tingting.meng, anshuld, alif.zakuan.yuslaimi, alice.guo,
	quentin.schulz, ilias.apalodimas, varadarajan.narayanan, sjg,
	mkorpershoek, h-salunke, alchark, dario.binacchi, ye.li,
	andre.przywara, dinesh.maniyam, luca.weiss, danila, aswin.murugan,
	balaji.selvanathan, adrian, n-francis, wens, jamie.gibbons,
	justin, ycliang, david.wronek, james.hilliard1, richard.genoud,
	michael, philip.molloy, sughosh.ganu, u-boot, u-boot-qcom

Add initial set of clocks and resets for enabling U-Boot on ipq5210
based RDP platforms.

Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
---
 drivers/clk/qcom/Kconfig         |  8 +++
 drivers/clk/qcom/Makefile        |  1 +
 drivers/clk/qcom/clock-ipq5210.c | 97 ++++++++++++++++++++++++++++++++
 3 files changed, 106 insertions(+)
 create mode 100644 drivers/clk/qcom/clock-ipq5210.c

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 8504ed5d656..a0a8778d5f0 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -31,6 +31,14 @@ config CLK_QCOM_IPQ4019
 	  on the Snapdragon IPQ4019 SoC. This driver supports the clocks
 	  and resets exposed by the GCC hardware block.
 
+config CLK_QCOM_IPQ5210
+	bool "Qualcomm IPQ5210 GCC"
+	select CLK_QCOM
+	help
+	  Say Y here to enable support for the Global Clock Controller
+	  on the Qualcomm IPQ5210 SoC. This driver supports the clocks
+	  and resets exposed by the GCC hardware block.
+
 config CLK_QCOM_IPQ5424
 	bool "Qualcomm IPQ5424 GCC"
 	select CLK_QCOM
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 82a5b166196..7116be963e7 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_CLK_QCOM_SDM845) += clock-sdm845.o
 obj-$(CONFIG_CLK_QCOM_APQ8016) += clock-apq8016.o
 obj-$(CONFIG_CLK_QCOM_APQ8096) += clock-apq8096.o
 obj-$(CONFIG_CLK_QCOM_IPQ4019) += clock-ipq4019.o
+obj-$(CONFIG_CLK_QCOM_IPQ5210) += clock-ipq5210.o
 obj-$(CONFIG_CLK_QCOM_IPQ5424) += clock-ipq5424.o
 obj-$(CONFIG_CLK_QCOM_IPQ9574) += clock-ipq9574.o
 obj-$(CONFIG_CLK_QCOM_QCM2290) += clock-qcm2290.o
diff --git a/drivers/clk/qcom/clock-ipq5210.c b/drivers/clk/qcom/clock-ipq5210.c
new file mode 100644
index 00000000000..f0a6ee8711d
--- /dev/null
+++ b/drivers/clk/qcom/clock-ipq5210.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock drivers for Qualcomm IPQ5210
+ *
+ * (C) Copyright 2024 Linaro Ltd.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <linux/types.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <linux/bug.h>
+#include <linux/bitops.h>
+#include <dm/device-internal.h>
+#include <dt-bindings/clock/qcom,ipq5210-gcc.h>
+#include <dt-bindings/reset/qcom,ipq5210-gcc.h>
+#include "clock-qcom.h"
+
+static ulong ipq5210_set_rate(struct clk *clk, ulong rate)
+{
+	struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+	switch (clk->id) {
+	case GCC_QUPV3_WRAP_SE1_CLK:
+		clk_rcg_set_rate_mnd(priv->base, priv->data->clks[clk->id].cbcr_reg,
+				     0, 2, 217, CFG_CLK_SRC_GPLL0, 16);
+		break;
+	case GCC_SDCC1_AHB_CLK:
+		break;
+	case GCC_SDCC1_APPS_CLK:
+		clk_rcg_set_rate_mnd(priv->base, priv->data->clks[clk->id].cbcr_reg,
+				     0, 6, 25, CFG_CLK_SRC_GPLL0, 16);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return rate;
+}
+
+static const struct gate_clk ipq5210_clks[] = {
+	GATE_CLK_POLLED(GCC_QUPV3_WRAP_SE1_CLK,	0x05020, BIT(0),	0x05004),
+	GATE_CLK_POLLED(GCC_SDCC1_AHB_CLK,	0x3303c, BIT(0),	0x3303c),
+	GATE_CLK_POLLED(GCC_SDCC1_APPS_CLK,	0x3302c, BIT(0),	0x33004),
+	GATE_CLK_POLLED(GCC_IM_SLEEP_CLK,	0x34020, BIT(0),	0x34020),
+};
+
+static int ipq5210_enable(struct clk *clk)
+{
+	struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+	if (priv->data->num_clks <= clk->id) {
+		debug("%s: unknown clk id %lu\n", __func__, clk->id);
+		return 0;
+	}
+
+	debug("%s: clk %s\n", __func__, ipq5210_clks[clk->id].name);
+
+	qcom_gate_clk_en(priv, clk->id);
+
+	return 0;
+}
+
+static const struct qcom_reset_map ipq5210_gcc_resets[] = {
+	[GCC_SDCC_BCR]			= {0x33000, 0},
+	[GCC_USB0_PHY_BCR]		= {0x2c06c, 0},
+	[GCC_USB3PHY_0_PHY_BCR]		= {0x2c070, 0},
+	[GCC_QUSB2_0_PHY_BCR]		= {0x2c068, 0},
+	[GCC_USB_BCR]			= {0x2c000, 0},
+};
+
+static struct msm_clk_data ipq5210_gcc_data = {
+	.resets = ipq5210_gcc_resets,
+	.num_resets = ARRAY_SIZE(ipq5210_gcc_resets),
+	.clks = ipq5210_clks,
+	.num_clks = ARRAY_SIZE(ipq5210_clks),
+	.enable = ipq5210_enable,
+	.set_rate = ipq5210_set_rate,
+};
+
+static const struct udevice_id gcc_ipq5210_of_match[] = {
+	{
+		.compatible = "qcom,ipq5210-gcc",
+		.data = (ulong)&ipq5210_gcc_data,
+	},
+	{ }
+};
+
+U_BOOT_DRIVER(gcc_ipq5210) = {
+	.name		= "gcc_ipq5210",
+	.id		= UCLASS_NOP,
+	.of_match	= gcc_ipq5210_of_match,
+	.bind		= qcom_cc_bind,
+	.flags		= DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
+};
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 03/10] pinctrl: qcom: Add ipq5210 pinctrl driver
  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  5:39 ` 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
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Varadarajan Narayanan @ 2026-04-16  5:39 UTC (permalink / raw)
  To: rayagonda.kokatanur, trini, casey.connolly, neil.armstrong,
	sumit.garg, peng.fan, jh80.chung, lukma, tien.fong.chee,
	tingting.meng, anshuld, alif.zakuan.yuslaimi, alice.guo,
	quentin.schulz, ilias.apalodimas, varadarajan.narayanan, sjg,
	mkorpershoek, h-salunke, alchark, dario.binacchi, ye.li,
	andre.przywara, dinesh.maniyam, luca.weiss, danila, aswin.murugan,
	balaji.selvanathan, adrian, n-francis, wens, jamie.gibbons,
	justin, ycliang, david.wronek, james.hilliard1, richard.genoud,
	michael, philip.molloy, sughosh.ganu, u-boot, u-boot-qcom

Add pinctrl driver for the TLMM block found in the ipq5210 SoC.

Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
---
 drivers/pinctrl/qcom/Kconfig           |   8 +
 drivers/pinctrl/qcom/Makefile          |   1 +
 drivers/pinctrl/qcom/pinctrl-ipq5210.c | 349 +++++++++++++++++++++++++
 3 files changed, 358 insertions(+)
 create mode 100644 drivers/pinctrl/qcom/pinctrl-ipq5210.c

diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
index 580308621b1..d30526b0167 100644
--- a/drivers/pinctrl/qcom/Kconfig
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -38,6 +38,14 @@ config PINCTRL_QCOM_IPQ4019
 	  Say Y here to enable support for pinctrl on the IPQ4019 SoC,
 	  as well as the associated GPIO driver.
 
+config PINCTRL_QCOM_IPQ5210
+	bool "Qualcomm IPQ5210 Pinctrl"
+	default y if PINCTRL_QCOM_GENERIC
+	select PINCTRL_QCOM
+	help
+	  Say Y here to enable support for pinctrl on the IPQ5210 SoC,
+	  as well as the associated GPIO driver.
+
 config PINCTRL_QCOM_IPQ5424
 	bool "Qualcomm IPQ5424 Pinctrl"
 	default y if PINCTRL_QCOM_GENERIC
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
index b5a111605ed..34ae56bb007 100644
--- a/drivers/pinctrl/qcom/Makefile
+++ b/drivers/pinctrl/qcom/Makefile
@@ -5,6 +5,7 @@
 obj-$(CONFIG_PINCTRL_QCOM) += pinctrl-qcom.o
 obj-$(CONFIG_PINCTRL_QCOM_APQ8016) += pinctrl-apq8016.o
 obj-$(CONFIG_PINCTRL_QCOM_IPQ4019) += pinctrl-ipq4019.o
+obj-$(CONFIG_PINCTRL_QCOM_IPQ5210) += pinctrl-ipq5210.o
 obj-$(CONFIG_PINCTRL_QCOM_IPQ5424) += pinctrl-ipq5424.o
 obj-$(CONFIG_PINCTRL_QCOM_IPQ9574) += pinctrl-ipq9574.o
 obj-$(CONFIG_PINCTRL_QCOM_APQ8096) += pinctrl-apq8096.o
diff --git a/drivers/pinctrl/qcom/pinctrl-ipq5210.c b/drivers/pinctrl/qcom/pinctrl-ipq5210.c
new file mode 100644
index 00000000000..2baff884bf3
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-ipq5210.c
@@ -0,0 +1,349 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Qualcomm IPQ5210 pinctrl
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <dm.h>
+
+#include "pinctrl-qcom.h"
+
+#define MAX_PIN_NAME_LEN 32
+static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
+
+enum ipq5210_functions {
+	msm_mux_atest_char_start,
+	msm_mux_atest_char_status0,
+	msm_mux_atest_char_status1,
+	msm_mux_atest_char_status2,
+	msm_mux_atest_char_status3,
+	msm_mux_atest_tic_en,
+	msm_mux_audio_pri,
+	msm_mux_audio_pri_mclk_out0,
+	msm_mux_audio_pri_mclk_in0,
+	msm_mux_audio_pri_mclk_out1,
+	msm_mux_audio_pri_mclk_in1,
+	msm_mux_audio_pri_mclk_out2,
+	msm_mux_audio_pri_mclk_in2,
+	msm_mux_audio_pri_mclk_out3,
+	msm_mux_audio_pri_mclk_in3,
+	msm_mux_audio_sec,
+	msm_mux_audio_sec_mclk_out0,
+	msm_mux_audio_sec_mclk_in0,
+	msm_mux_audio_sec_mclk_out1,
+	msm_mux_audio_sec_mclk_in1,
+	msm_mux_audio_sec_mclk_out2,
+	msm_mux_audio_sec_mclk_in2,
+	msm_mux_audio_sec_mclk_out3,
+	msm_mux_audio_sec_mclk_in3,
+	msm_mux_core_voltage_0,
+	msm_mux_cri_trng0,
+	msm_mux_cri_trng1,
+	msm_mux_cri_trng2,
+	msm_mux_cri_trng3,
+	msm_mux_dbg_out_clk,
+	msm_mux_dg_out,
+	msm_mux_gcc_plltest_bypassnl,
+	msm_mux_gcc_plltest_resetn,
+	msm_mux_gcc_tlmm,
+	msm_mux_gpio,
+	msm_mux_led0,
+	msm_mux_led1,
+	msm_mux_led2,
+	msm_mux_mdc_mst,
+	msm_mux_mdc_slv0,
+	msm_mux_mdc_slv1,
+	msm_mux_mdc_slv2,
+	msm_mux_mdio_mst,
+	msm_mux_mdio_slv0,
+	msm_mux_mdio_slv1,
+	msm_mux_mdio_slv2,
+	msm_mux_mux_tod_out,
+	msm_mux_pcie0_clk_req_n,
+	msm_mux_pcie0_wake,
+	msm_mux_pcie1_clk_req_n,
+	msm_mux_pcie1_wake,
+	msm_mux_pll_test,
+	msm_mux_pon_active_led,
+	msm_mux_pon_mux_sel,
+	msm_mux_pon_rx,
+	msm_mux_pon_rx_los,
+	msm_mux_pon_tx,
+	msm_mux_pon_tx_burst,
+	msm_mux_pon_tx_dis,
+	msm_mux_pon_tx_fault,
+	msm_mux_pon_tx_sd,
+	msm_mux_gpn_rx_los,
+	msm_mux_gpn_tx_burst,
+	msm_mux_gpn_tx_dis,
+	msm_mux_gpn_tx_fault,
+	msm_mux_gpn_tx_sd,
+	msm_mux_pps,
+	msm_mux_pwm0,
+	msm_mux_pwm1,
+	msm_mux_pwm2,
+	msm_mux_pwm3,
+	msm_mux_qdss_cti_trig_in_a0,
+	msm_mux_qdss_cti_trig_in_a1,
+	msm_mux_qdss_cti_trig_in_b0,
+	msm_mux_qdss_cti_trig_in_b1,
+	msm_mux_qdss_cti_trig_out_a0,
+	msm_mux_qdss_cti_trig_out_a1,
+	msm_mux_qdss_cti_trig_out_b0,
+	msm_mux_qdss_cti_trig_out_b1,
+	msm_mux_qdss_traceclk_a,
+	msm_mux_qdss_tracectl_a,
+	msm_mux_qdss_tracedata_a,
+	msm_mux_qrng_rosc0,
+	msm_mux_qrng_rosc1,
+	msm_mux_qrng_rosc2,
+	msm_mux_qspi_data,
+	msm_mux_qspi_clk,
+	msm_mux_qspi_cs_n,
+	msm_mux_qup_se0,
+	msm_mux_qup_se1,
+	msm_mux_qup_se2,
+	msm_mux_qup_se3,
+	msm_mux_qup_se4,
+	msm_mux_qup_se5,
+	msm_mux_qup_se5_l1,
+	msm_mux_resout,
+	msm_mux_rx_los0,
+	msm_mux_rx_los1,
+	msm_mux_rx_los2,
+	msm_mux_sdc_clk,
+	msm_mux_sdc_cmd,
+	msm_mux_sdc_data,
+	msm_mux_tsens_max,
+	msm_mux__,
+};
+
+#define MSM_PIN_FUNCTION(fname)				\
+	[msm_mux_##fname] = {#fname, msm_mux_##fname}
+
+static const struct pinctrl_function msm_pinctrl_functions[] = {
+	MSM_PIN_FUNCTION(atest_char_start),
+	MSM_PIN_FUNCTION(atest_char_status0),
+	MSM_PIN_FUNCTION(atest_char_status1),
+	MSM_PIN_FUNCTION(atest_char_status2),
+	MSM_PIN_FUNCTION(atest_char_status3),
+	MSM_PIN_FUNCTION(atest_tic_en),
+	MSM_PIN_FUNCTION(audio_pri),
+	MSM_PIN_FUNCTION(audio_pri_mclk_out0),
+	MSM_PIN_FUNCTION(audio_pri_mclk_in0),
+	MSM_PIN_FUNCTION(audio_pri_mclk_out1),
+	MSM_PIN_FUNCTION(audio_pri_mclk_in1),
+	MSM_PIN_FUNCTION(audio_pri_mclk_out2),
+	MSM_PIN_FUNCTION(audio_pri_mclk_in2),
+	MSM_PIN_FUNCTION(audio_pri_mclk_out3),
+	MSM_PIN_FUNCTION(audio_pri_mclk_in3),
+	MSM_PIN_FUNCTION(audio_sec),
+	MSM_PIN_FUNCTION(audio_sec_mclk_out0),
+	MSM_PIN_FUNCTION(audio_sec_mclk_in0),
+	MSM_PIN_FUNCTION(audio_sec_mclk_out1),
+	MSM_PIN_FUNCTION(audio_sec_mclk_in1),
+	MSM_PIN_FUNCTION(audio_sec_mclk_out2),
+	MSM_PIN_FUNCTION(audio_sec_mclk_in2),
+	MSM_PIN_FUNCTION(audio_sec_mclk_out3),
+	MSM_PIN_FUNCTION(audio_sec_mclk_in3),
+	MSM_PIN_FUNCTION(core_voltage_0),
+	MSM_PIN_FUNCTION(cri_trng0),
+	MSM_PIN_FUNCTION(cri_trng1),
+	MSM_PIN_FUNCTION(cri_trng2),
+	MSM_PIN_FUNCTION(cri_trng3),
+	MSM_PIN_FUNCTION(dbg_out_clk),
+	MSM_PIN_FUNCTION(dg_out),
+	MSM_PIN_FUNCTION(gcc_plltest_bypassnl),
+	MSM_PIN_FUNCTION(gcc_plltest_resetn),
+	MSM_PIN_FUNCTION(gcc_tlmm),
+	MSM_PIN_FUNCTION(gpio),
+	MSM_PIN_FUNCTION(led0),
+	MSM_PIN_FUNCTION(led1),
+	MSM_PIN_FUNCTION(led2),
+	MSM_PIN_FUNCTION(mdc_mst),
+	MSM_PIN_FUNCTION(mdc_slv0),
+	MSM_PIN_FUNCTION(mdc_slv1),
+	MSM_PIN_FUNCTION(mdc_slv2),
+	MSM_PIN_FUNCTION(mdio_mst),
+	MSM_PIN_FUNCTION(mdio_slv0),
+	MSM_PIN_FUNCTION(mdio_slv1),
+	MSM_PIN_FUNCTION(mdio_slv2),
+	MSM_PIN_FUNCTION(mux_tod_out),
+	MSM_PIN_FUNCTION(pcie0_clk_req_n),
+	MSM_PIN_FUNCTION(pcie0_wake),
+	MSM_PIN_FUNCTION(pcie1_clk_req_n),
+	MSM_PIN_FUNCTION(pcie1_wake),
+	MSM_PIN_FUNCTION(pll_test),
+	MSM_PIN_FUNCTION(pon_active_led),
+	MSM_PIN_FUNCTION(pon_mux_sel),
+	MSM_PIN_FUNCTION(pon_rx),
+	MSM_PIN_FUNCTION(pon_rx_los),
+	MSM_PIN_FUNCTION(pon_tx),
+	MSM_PIN_FUNCTION(pon_tx_burst),
+	MSM_PIN_FUNCTION(pon_tx_dis),
+	MSM_PIN_FUNCTION(pon_tx_fault),
+	MSM_PIN_FUNCTION(pon_tx_sd),
+	MSM_PIN_FUNCTION(gpn_rx_los),
+	MSM_PIN_FUNCTION(gpn_tx_burst),
+	MSM_PIN_FUNCTION(gpn_tx_dis),
+	MSM_PIN_FUNCTION(gpn_tx_fault),
+	MSM_PIN_FUNCTION(gpn_tx_sd),
+	MSM_PIN_FUNCTION(pps),
+	MSM_PIN_FUNCTION(pwm0),
+	MSM_PIN_FUNCTION(pwm1),
+	MSM_PIN_FUNCTION(pwm2),
+	MSM_PIN_FUNCTION(pwm3),
+	MSM_PIN_FUNCTION(qdss_cti_trig_in_a0),
+	MSM_PIN_FUNCTION(qdss_cti_trig_in_a1),
+	MSM_PIN_FUNCTION(qdss_cti_trig_in_b0),
+	MSM_PIN_FUNCTION(qdss_cti_trig_in_b1),
+	MSM_PIN_FUNCTION(qdss_cti_trig_out_a0),
+	MSM_PIN_FUNCTION(qdss_cti_trig_out_a1),
+	MSM_PIN_FUNCTION(qdss_cti_trig_out_b0),
+	MSM_PIN_FUNCTION(qdss_cti_trig_out_b1),
+	MSM_PIN_FUNCTION(qdss_traceclk_a),
+	MSM_PIN_FUNCTION(qdss_tracectl_a),
+	MSM_PIN_FUNCTION(qdss_tracedata_a),
+	MSM_PIN_FUNCTION(qrng_rosc0),
+	MSM_PIN_FUNCTION(qrng_rosc1),
+	MSM_PIN_FUNCTION(qrng_rosc2),
+	MSM_PIN_FUNCTION(qspi_data),
+	MSM_PIN_FUNCTION(qspi_clk),
+	MSM_PIN_FUNCTION(qspi_cs_n),
+	MSM_PIN_FUNCTION(qup_se0),
+	MSM_PIN_FUNCTION(qup_se1),
+	MSM_PIN_FUNCTION(qup_se2),
+	MSM_PIN_FUNCTION(qup_se3),
+	MSM_PIN_FUNCTION(qup_se4),
+	MSM_PIN_FUNCTION(qup_se5),
+	MSM_PIN_FUNCTION(qup_se5_l1),
+	MSM_PIN_FUNCTION(resout),
+	MSM_PIN_FUNCTION(rx_los0),
+	MSM_PIN_FUNCTION(rx_los1),
+	MSM_PIN_FUNCTION(rx_los2),
+	MSM_PIN_FUNCTION(sdc_clk),
+	MSM_PIN_FUNCTION(sdc_cmd),
+	MSM_PIN_FUNCTION(sdc_data),
+	MSM_PIN_FUNCTION(tsens_max),
+};
+
+typedef unsigned int msm_pin_function[10];
+
+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9) \
+	[id] = {        msm_mux_gpio, /* gpio mode */	\
+			msm_mux_##f1,			\
+			msm_mux_##f2,			\
+			msm_mux_##f3,			\
+			msm_mux_##f4,			\
+			msm_mux_##f5,			\
+			msm_mux_##f6,			\
+			msm_mux_##f7,			\
+			msm_mux_##f8,			\
+			msm_mux_##f9,			\
+	}
+
+static const msm_pin_function ipq5210_pin_functions[] = {
+	PINGROUP(0, sdc_data, qspi_data, pwm2, _, _, _, _, _, _),
+	PINGROUP(1, sdc_data, qspi_data, pwm2, _, _, _, _, _, _),
+	PINGROUP(2, sdc_data, qspi_data, pwm2, _, _, _, _, _, _),
+	PINGROUP(3, sdc_data, qspi_data, pwm2, _, _, _, _, _, _),
+	PINGROUP(4, sdc_cmd, qspi_cs_n, _, _, _, _, _, _, _),
+	PINGROUP(5, sdc_clk, qspi_clk, _, _, _, _, _, _, _),
+	PINGROUP(6, qup_se0, led0, pwm1, _, cri_trng0, qdss_tracedata_a, _, _, _),
+	PINGROUP(7, qup_se0, led1, pwm1, _, cri_trng1, qdss_tracedata_a, _, _, _),
+	PINGROUP(8, qup_se0, pwm1, audio_pri_mclk_out2, audio_pri_mclk_in2, _, cri_trng2, qdss_tracedata_a, _, _),
+	PINGROUP(9, qup_se0, led2, pwm1, _, cri_trng3, qdss_tracedata_a, _, _, _),
+	PINGROUP(10, pon_rx_los, qup_se3, pwm0, _, _, qdss_tracedata_a, _, _, _),
+	PINGROUP(11, pon_active_led, qup_se3, pwm0, _, _, qdss_tracedata_a, _, _, _),
+	PINGROUP(12, pon_tx_dis, qup_se2, pwm0, audio_pri_mclk_out0, audio_pri_mclk_in0, _, qrng_rosc0, qdss_tracedata_a, _),
+	PINGROUP(13, gpn_tx_dis, qup_se2, pwm0, audio_pri_mclk_out3, audio_pri_mclk_in3, _, qrng_rosc1, qdss_tracedata_a, _),
+	PINGROUP(14, pon_tx_burst, qup_se0, _, qrng_rosc2, qdss_tracedata_a, _, _, _, _),
+	PINGROUP(15, pon_tx, qup_se0, _, qdss_tracedata_a, _, _, _, _, _),
+	PINGROUP(16, pon_tx_sd, audio_sec_mclk_out1, audio_sec_mclk_in1, qdss_cti_trig_out_b0, _, _, _, _, _),
+	PINGROUP(17, pon_tx_fault, audio_sec_mclk_out0, audio_sec_mclk_in0, _, _, _, _, _, _),
+	PINGROUP(18, pps, pll_test, _, _, _, _, _, _, _),
+	PINGROUP(19, mux_tod_out, audio_pri_mclk_out1, audio_pri_mclk_in1, _, _, _, _, _, _),
+	PINGROUP(20, qup_se2, mdc_slv1, tsens_max, qdss_tracedata_a, _, _, _, _, _),
+	PINGROUP(21, qup_se2, mdio_slv1, qdss_tracedata_a, _, _, _, _, _, _),
+	PINGROUP(22, core_voltage_0, qup_se3, pwm3, _, _, _, _, _, _),
+	PINGROUP(23, led0, qup_se3, dbg_out_clk, qdss_traceclk_a, _, _, _, _, _),
+	PINGROUP(24, _, _, _, _, _, _, _, _, _),
+	PINGROUP(25, _, _, _, _, _, _, _, _, _),
+	PINGROUP(26, mdc_mst, led2, _, qdss_tracectl_a, _, _, _, _, _),
+	PINGROUP(27, mdio_mst, led1, _, _, _, _, _, _, _),
+	PINGROUP(28, pcie1_clk_req_n, qup_se1, _, _, qdss_cti_trig_out_a0, _, _, _, _),
+	PINGROUP(29, _, _, _, _, _, _, _, _, _),
+	PINGROUP(30, pcie1_wake, qup_se1, _, _, qdss_cti_trig_in_a0, _, _, _, _),
+	PINGROUP(31, pcie0_clk_req_n, mdc_slv0, _, qdss_cti_trig_out_a1, _, _, _, _, _),
+	PINGROUP(32, _, _, _, _, _, _, _, _, _),
+	PINGROUP(33, pcie0_wake, mdio_slv0, qdss_cti_trig_in_a1, _, _, _, _, _, _),
+	PINGROUP(34, audio_pri, atest_char_status0, qdss_cti_trig_in_b0, _, _, _, _, _, _),
+	PINGROUP(35, audio_pri, rx_los2, atest_char_status1, qdss_cti_trig_out_b1, _, _, _, _, _),
+	PINGROUP(36, audio_pri, _, rx_los1, atest_char_status2, _, _, _, _, _),
+	PINGROUP(37, audio_pri, rx_los0, atest_char_status3, _, qdss_cti_trig_in_b1, _, _, _, _),
+	PINGROUP(38, qup_se1, led2, gcc_plltest_bypassnl, qdss_tracedata_a, _, _, _, _, _),
+	PINGROUP(39, qup_se1, led1, led0, gcc_tlmm, qdss_tracedata_a, _, _, _, _),
+	PINGROUP(40, qup_se4, rx_los2, audio_sec, gcc_plltest_resetn, qdss_tracedata_a, _, _, _, _),
+	PINGROUP(41, qup_se4, rx_los1, audio_sec, qdss_tracedata_a, _, _, _, _, _),
+	PINGROUP(42, qup_se4, rx_los0, audio_sec, atest_tic_en, _, _, _, _, _),
+	PINGROUP(43, qup_se4, audio_sec, _, _, _, _, _, _, _),
+	PINGROUP(44, resout, _, _, _, _, _, _, _, _),
+	PINGROUP(45, pon_mux_sel, _, _, _, _, _, _, _, _),
+	PINGROUP(46, dg_out, atest_char_start, _, _, _, _, _, _, _),
+	PINGROUP(47, gpn_rx_los, mdc_slv2, qup_se5, _, _, _, _, _, _),
+	PINGROUP(48, pon_rx, qup_se5, _, _, _, _, _, _, _),
+	PINGROUP(49, gpn_tx_fault, mdio_slv2, qup_se5, audio_sec_mclk_out2, audio_sec_mclk_in2, _, _, _, _),
+	PINGROUP(50, gpn_tx_sd, qup_se5, audio_sec_mclk_out3, audio_sec_mclk_in3, _, _, _, _, _),
+	PINGROUP(51, gpn_tx_burst, qup_se5, _, _, _, _, _, _, _),
+	PINGROUP(52, qup_se2, qup_se5, qup_se4, qup_se5_l1, _, _, _, _, _),
+	PINGROUP(53, qup_se2, qup_se4, qup_se5_l1, _, _, _, _, _, _),
+};
+
+static const char *ipq5210_get_function_name(struct udevice *dev, uint selector)
+{
+	return msm_pinctrl_functions[selector].name;
+}
+
+static const char *ipq5210_get_pin_name(struct udevice *dev, uint selector)
+{
+	snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
+	return pin_name;
+}
+
+static int ipq5210_get_function_mux(unsigned int pin, uint selector)
+{
+	unsigned int i;
+	const msm_pin_function *func = ipq5210_pin_functions + pin;
+
+	for (i = 0; i < 10; i++)
+		if ((*func)[i] == selector)
+			return i;
+
+	pr_err("Can't find requested function for pin %u pin\n", pin);
+	return -EINVAL;
+}
+
+static const struct msm_pinctrl_data ipq5210_data = {
+	.pin_data = {
+		.pin_count = 53,
+		.special_pins_start = 53, /* There are no special pins */
+	},
+	.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
+	.get_function_name = ipq5210_get_function_name,
+	.get_function_mux = ipq5210_get_function_mux,
+	.get_pin_name = ipq5210_get_pin_name,
+};
+
+static const struct udevice_id msm_pinctrl_ids[] = {
+	{ .compatible = "qcom,ipq5210-tlmm", .data = (ulong)&ipq5210_data },
+	{ /* Sentinal */ }
+};
+
+U_BOOT_DRIVER(pinctrl_ipq5210) = {
+	.name		= "pinctrl_ipq5210",
+	.id		= UCLASS_NOP,
+	.of_match	= msm_pinctrl_ids,
+	.ops		= &msm_pinctrl_ops,
+	.bind		= msm_pinctrl_bind,
+	.flags = DM_FLAG_PRE_RELOC,
+};
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 04/10] misc: qcom_geni: Add minicore support
  2026-04-16  5:39 [PATCH v3 00/10] Qualcomm IPQ5210 SoC bringup Varadarajan Narayanan
                   ` (2 preceding siblings ...)
  2026-04-16  5:39 ` [PATCH v3 03/10] pinctrl: qcom: Add ipq5210 pinctrl driver Varadarajan Narayanan
@ 2026-04-16  5:39 ` 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
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Varadarajan Narayanan @ 2026-04-16  5:39 UTC (permalink / raw)
  To: rayagonda.kokatanur, trini, casey.connolly, neil.armstrong,
	sumit.garg, peng.fan, jh80.chung, lukma, tien.fong.chee,
	tingting.meng, anshuld, alif.zakuan.yuslaimi, alice.guo,
	quentin.schulz, ilias.apalodimas, varadarajan.narayanan, sjg,
	mkorpershoek, h-salunke, alchark, dario.binacchi, ye.li,
	andre.przywara, dinesh.maniyam, luca.weiss, danila, aswin.murugan,
	balaji.selvanathan, adrian, n-francis, wens, jamie.gibbons,
	justin, ycliang, david.wronek, james.hilliard1, richard.genoud,
	michael, philip.molloy, sughosh.ganu, u-boot, u-boot-qcom

The qcom_geni driver reads an ELF from storage and configures a set of
registers and programs the firmware to the GENI Serial Engine (GENI-SE)
wrapper device for the expected functionality.

Unlike the GENI-SE wrapper found in MSM SoCs, the IPQ5210's GENI-SE
wrapper is pre-configured for one of the functions defined in 'enum
geni_se_protocol_type'. Hence, the firmware download is not needed.
Only the register configuration part is needed.

Earlier, the boot stages before U-Boot would configure the GENI-SE (to
access UART/SPI etc). Since for IPQ5210 U-Boot SPL, the previous stage
(i.e. boot ROM) doesn't do that modify the driver to do the register
configuration part alone without reading an ELF from the storage.

Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
---
v3: Use wrapper probe fn to call qcom_geni_fw_initialise() for SPL
    Return error if ELF is not found and it is not a minicore

v2: * Add CONFIG_QCOM_GENI_MINICORE option
    * Move register settings to separate file and include if
      CONFIG_QCOM_GENI_MINICORE is defined
    * Remove duplicate definition of GEN_USE_MINICORES
    * s/GEN_USE_MINICORES/GENI_USE_MINICORES
    * Skip find_qupfw_part() if it is a minicore
---
 drivers/misc/Kconfig              |   6 ++
 drivers/misc/Makefile             |   1 +
 drivers/misc/qcom_geni-minicore.c | 102 ++++++++++++++++++++++++++++++
 drivers/misc/qcom_geni.c          |  94 +++++++++++++++++++++++----
 include/soc/qcom/geni-se.h        |   2 +
 include/soc/qcom/qup-fw-load.h    |  15 +++++
 6 files changed, 208 insertions(+), 12 deletions(-)
 create mode 100644 drivers/misc/qcom_geni-minicore.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index ea785793d18..4bf75ecf5c7 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -93,6 +93,12 @@ config QCOM_GENI
 	  for providing a common interface for various peripherals like UART, I2C, SPI,
 	  etc.
 
+config QCOM_GENI_MINICORE
+	bool "Support minicores in Qualcomm Generic Interface (GENI) driver"
+	depends on QCOM_GENI
+	help
+	  Enable support for minicores in Qualcomm GENI and it's peripherals.
+
 config ROCKCHIP_EFUSE
         bool "Rockchip e-fuse support"
 	depends on MISC
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index e2170212e5a..2daccbba74d 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_QFW_SMBIOS) += qfw_smbios.o
 obj-$(CONFIG_SANDBOX) += qfw_sandbox.o
 endif
 obj-$(CONFIG_QCOM_GENI) += qcom_geni.o
+obj-$(CONFIG_QCOM_GENI_MINICORE) += qcom_geni-minicore.o
 obj-$(CONFIG_$(PHASE_)ROCKCHIP_EFUSE) += rockchip-efuse.o
 obj-$(CONFIG_$(PHASE_)ROCKCHIP_OTP) += rockchip-otp.o
 obj-$(CONFIG_$(PHASE_)ROCKCHIP_IODOMAIN) += rockchip-io-domain.o
diff --git a/drivers/misc/qcom_geni-minicore.c b/drivers/misc/qcom_geni-minicore.c
new file mode 100644
index 00000000000..33bc61ddf35
--- /dev/null
+++ b/drivers/misc/qcom_geni-minicore.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <soc/qcom/geni-se.h>
+#include <soc/qcom/qup-fw-load.h>
+
+/*
+ * Register configuration for the QUP minicores to setup the corresponding
+ * functionality of SPI/I2C/UART.
+ */
+static u8 cfg_reg_idx[] = {
+	/* 0 to 18 */
+	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+	/* 64 to 113 */
+	64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+	81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+	98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+	112, 113,
+};
+
+static u32 spi_cfg_val[] = {
+	/* 0 to 18 */
+	0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00240E78, 0x00011088,
+	0x00240007, 0x00000000, 0x00000000, 0x0001000A, 0x00000300, 0x00000000,
+	0x00000000, 0x00000000, 0x00154400, 0x001483A0, 0x00AA8128, 0x00641002,
+	0x00004000,
+	/* 64 to 113 */
+	0x00000201, 0x0001FE05, 0x0002C2E7, 0x0A435C00, 0x0010011A, 0x08800000,
+	0x00000000, 0x100CAC00, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000018E4, 0x00000000,
+	0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x0007F807, 0x000FFEFE, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00200000, 0x00000004, 0x00000009, 0x0007F807, 0x000FFEFE, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00C0033F, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000055,
+};
+
+static u32 uart_cfg_val[] = {
+	/* 0 to 18 */
+	0x00000024, 0x00000000, 0x00000024, 0x00000000, 0x00019A00, 0x00400000,
+	0x00E00000, 0x00010020, 0x00000000, 0x00000000, 0x00000300, 0x00000700,
+	0x00000400, 0x00000000, 0x00000000, 0x00C00000, 0x00000000, 0x00C00024,
+	0x00000B00,
+	/* 64 to 113 */
+	0x00020231, 0x0000CE05, 0x000360E7, 0x0941E6A8, 0x00100510, 0x42C01E51,
+	0x00000401, 0x002E8400, 0x1694581A, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x0000031C, 0x00000000,
+	0x0000000F, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00081C06, 0x00004010, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x0000000D, 0x00000000, 0x00081C06, 0x00004010, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00C02415, 0x0000000E, 0x00000001,
+	0x00000001, 0x00000000, 0x00C00000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000055,
+};
+
+static u32 i2c_cfg_val[] = {
+	/* 0 to 18 */
+	0x00000090, 0x00000000, 0x00000090, 0x00000000, 0x00038028, 0x00084080,
+	0x00000343, 0x00010000, 0x00000000, 0x00001A00, 0x00000100, 0x00000000,
+	0x00000000, 0x00000000, 0x00808008, 0x001C0020, 0x00000000, 0x00020000,
+	0x00000000,
+	/* 64 to 113 */
+	0x00000201, 0x0001FC01, 0x00036222, 0x09C01FFC, 0x00100120, 0x02C00000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000409, 0x00000003,
+	0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x0007F8FE, 0x000FFEFE, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000001, 0x0007F807, 0x000FFEFE, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00C00000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000055,
+};
+
+struct qup_mini_core_info qup_mini_cores[] = {
+	{
+		.serial_protocol = GENI_SE_SPI,
+		.fw_version = 0xb02,
+		.cfg_version = 0x9,
+		.cfg_count = ARRAY_SIZE(spi_cfg_val),
+		.cfg_val = spi_cfg_val,
+		.cfg_idx = cfg_reg_idx,
+	}, {
+		.serial_protocol = GENI_SE_UART,
+		.fw_version = 0x405,
+		.cfg_version = 0xa,
+		.cfg_count = ARRAY_SIZE(uart_cfg_val),
+		.cfg_val = uart_cfg_val,
+		.cfg_idx = cfg_reg_idx,
+	}, {
+		.serial_protocol = GENI_SE_I2C,
+		.fw_version = 0x204,
+		.cfg_version = 0x9,
+		.cfg_count = ARRAY_SIZE(i2c_cfg_val),
+		.cfg_val = i2c_cfg_val,
+		.cfg_idx = cfg_reg_idx,
+	}, {
+		.serial_protocol = GENI_SE_INVALID_PROTO,
+	},
+};
diff --git a/drivers/misc/qcom_geni.c b/drivers/misc/qcom_geni.c
index a62ae6a2478..829228f37ec 100644
--- a/drivers/misc/qcom_geni.c
+++ b/drivers/misc/qcom_geni.c
@@ -34,8 +34,15 @@ struct qup_se_rsc {
 
 struct geni_se_plat {
 	bool need_firmware_load;
+#if IS_ENABLED(CONFIG_QCOM_GENI_MINICORE)
+	bool is_mini_core;
+#endif
 };
 
+#if IS_ENABLED(CONFIG_QCOM_GENI_MINICORE)
+extern struct qup_mini_core_info qup_mini_cores[];
+#endif
+
 /**
  * geni_enable_interrupts() Enable interrupts.
  * @rsc: Pointer to a structure representing SE-related resources.
@@ -163,16 +170,47 @@ static void geni_config_common_control(struct qup_se_rsc *rsc)
 		       COMMON_CSR_SLV_CLK_CGC_ON_BMASK);
 }
 
-static int load_se_firmware(struct qup_se_rsc *rsc, struct elf_se_hdr *hdr)
+static int load_se_firmware(struct qup_se_rsc *rsc, bool elf, void *info)
 {
+	struct elf_se_hdr *hdr, tmp_hdr;
 	const u32 *fw_val_arr, *cfg_val_arr;
 	const u8 *cfg_idx_arr;
 	u32 i, reg_value, mask, ramn_cnt;
 	int ret;
 
-	fw_val_arr = (const u32 *)((u8 *)hdr + hdr->fw_offset);
-	cfg_idx_arr = (const u8 *)hdr + hdr->cfg_idx_offset;
-	cfg_val_arr = (const u32 *)((u8 *)hdr + hdr->cfg_val_offset);
+	if (elf) {
+		hdr = info;
+		fw_val_arr = (const u32 *)((u8 *)hdr + hdr->fw_offset);
+		cfg_idx_arr = (const u8 *)hdr + hdr->cfg_idx_offset;
+		cfg_val_arr = (const u32 *)((u8 *)hdr + hdr->cfg_val_offset);
+	} else if (IS_ENABLED(CONFIG_QCOM_GENI_MINICORE)) {
+		/*
+		 * Minicore controllers come with pre-configured functionality
+		 * and don't need a firmware download and just need the register
+		 * configuration. Hence, skipping the firmware part and setting
+		 * up just the register configuration related information.
+		 */
+		struct qup_mini_core_info *qmc = info;
+
+		for (; qmc->serial_protocol != GENI_SE_INVALID_PROTO; qmc++)
+			if (qmc->serial_protocol == rsc->protocol)
+				break;
+
+		tmp_hdr.magic = MAGIC_NUM_SE;
+		tmp_hdr.version = 1;
+		tmp_hdr.serial_protocol = rsc->protocol;
+		tmp_hdr.fw_version = qmc->fw_version;
+		tmp_hdr.cfg_version = qmc->cfg_version;
+		tmp_hdr.fw_size_in_items = qmc->cfg_ram_count;
+		tmp_hdr.cfg_size_in_items = qmc->cfg_count;
+		hdr = &tmp_hdr;
+		fw_val_arr = (const u32 *)qmc->cfg_ram;
+		cfg_idx_arr = (const u8 *)qmc->cfg_idx;
+		cfg_val_arr = (const u32 *)qmc->cfg_val;
+	} else {
+		dev_err(rsc->dev, "Neither fw nor register settings found\n");
+		return -EINVAL;
+	}
 
 	geni_config_common_control(rsc);
 
@@ -350,8 +388,9 @@ int qcom_geni_load_firmware(phys_addr_t qup_base,
 {
 	struct qup_se_rsc rsc;
 	struct elf_se_hdr *hdr;
+	bool elf;
 	int ret;
-	void *fw;
+	void *fw, *info;
 
 	rsc.dev = dev;
 	rsc.base = qup_base;
@@ -377,15 +416,22 @@ int qcom_geni_load_firmware(phys_addr_t qup_base,
 	/* The firmware blob is the private data of the GENI wrapper (parent) */
 	fw = dev_get_priv(dev->parent);
 
-	ret = read_elf(&rsc, fw, &hdr);
-	if (ret) {
-		dev_err(dev, "Failed to read ELF: %d\n", ret);
-		return ret;
+	if (IS_ELF(*(Elf32_Ehdr *)fw)) {
+		ret = read_elf(&rsc, fw, &hdr);
+		if (ret) {
+			dev_err(dev, "Failed to read ELF: %d\n", ret);
+			return ret;
+		}
+		elf = true;
+		info = hdr;
+	} else {
+		elf = false;
+		info = fw;
 	}
 
 	dev_info(dev, "Loading QUP firmware...\n");
 
-	return load_se_firmware(&rsc, hdr);
+	return load_se_firmware(&rsc, elf, info);
 }
 
 /*
@@ -414,6 +460,11 @@ static int geni_se_of_to_plat(struct udevice *dev)
 
 		if (proto == GENI_SE_INVALID_PROTO)
 			plat->need_firmware_load = true;
+
+#if IS_ENABLED(CONFIG_QCOM_GENI_MINICORE)
+		if (readl(res.start + QUPV3_SE_HW_PARAM_2) & GENI_USE_MINICORES)
+			plat->is_mini_core = true;
+#endif
 	}
 
 	return 0;
@@ -473,7 +524,7 @@ static int probe_children_load_firmware(struct udevice *dev)
 		ret = 0;
 		/* Find the device for this ofnode, or bind it */
 		if (device_find_global_by_ofnode(child, &child_dev))
-			ret = lists_bind_fdt(dev, child, &child_dev, NULL, false);	
+			ret = lists_bind_fdt(dev, child, &child_dev, NULL, false);
 		if (ret) {
 			/* Skip nodes that don't have drivers */
 			debug("Failed to probe child %s: %d\n", ofnode_get_name(child), ret);
@@ -492,7 +543,7 @@ static int probe_children_load_firmware(struct udevice *dev)
  * Load firmware for QCOM GENI peripherals from the dedicated partition on storage and bind/probe
  * all the peripheral devices that need firmware to be loaded.
  */
-static int qcom_geni_fw_initialise(void)
+int qcom_geni_fw_initialise(void)
 {
 	debug("Loading firmware for QCOM GENI SE\n");
 	struct udevice *geni_wrapper, *blk_dev;
@@ -518,6 +569,12 @@ static int qcom_geni_fw_initialise(void)
 		return 0;
 	}
 
+#if IS_ENABLED(CONFIG_QCOM_GENI_MINICORE)
+	if (plat->is_mini_core) {
+		fw_buf = qup_mini_cores;
+		goto mini_core;
+	}
+#endif
 	ret = find_qupfw_part(&blk_dev, &part_info);
 	if (ret) {
 		pr_err("QUP firmware partition not found\n");
@@ -544,6 +601,9 @@ static int qcom_geni_fw_initialise(void)
 		return 0;
 	}
 
+#if IS_ENABLED(CONFIG_QCOM_GENI_MINICORE)
+mini_core:
+#endif
 	/*
 	 * OK! Firmware is loaded, now bind and probe remaining children. They will attempt to load
 	 * firmware during probe. Do this for each GENI SE wrapper that needs firmware loading.
@@ -563,7 +623,14 @@ static int qcom_geni_fw_initialise(void)
 	return 0;
 }
 
+#if CONFIG_XPL_BUILD
+int qcom_geni_fw_probe(struct udevice *dev)
+{
+	return qcom_geni_fw_initialise();
+}
+#else
 EVENT_SPY_SIMPLE(EVT_LAST_STAGE_INIT, qcom_geni_fw_initialise);
+#endif
 
 static const struct udevice_id geni_ids[] = {
 	{ .compatible = "qcom,geni-se-qup" },
@@ -577,4 +644,7 @@ U_BOOT_DRIVER(geni_se_qup) = {
 	.of_to_plat = geni_se_of_to_plat,
 	.plat_auto = sizeof(struct geni_se_plat),
 	.flags = DM_FLAG_DEFAULT_PD_CTRL_OFF,
+#if CONFIG_XPL_BUILD
+	.probe = qcom_geni_fw_probe,
+#endif
 };
diff --git a/include/soc/qcom/geni-se.h b/include/soc/qcom/geni-se.h
index fc9a8e82cd8..94f3e5c8c7e 100644
--- a/include/soc/qcom/geni-se.h
+++ b/include/soc/qcom/geni-se.h
@@ -77,6 +77,7 @@ enum geni_se_protocol_type {
 #define SE_IRQ_EN			0xe1c
 #define SE_HW_PARAM_0			0xe24
 #define SE_HW_PARAM_1			0xe28
+#define SE_HW_PARAM_2			0xe2c
 #define SE_DMA_GENERAL_CFG		0xe30
 
 /* GENI_DFS_IF_CFG fields */
@@ -248,6 +249,7 @@ enum geni_se_protocol_type {
 /* SE_HW_PARAM_0 fields */
 #define TX_FIFO_WIDTH_MSK		GENMASK(29, 24)
 #define TX_FIFO_WIDTH_SHFT		24
+
 /*
  * For QUP HW Version >= 3.10 Tx fifo depth support is increased
  * to 256bytes and corresponding bits are 16 to 23
diff --git a/include/soc/qcom/qup-fw-load.h b/include/soc/qcom/qup-fw-load.h
index a67a93c72a4..4e876e650a2 100644
--- a/include/soc/qcom/qup-fw-load.h
+++ b/include/soc/qcom/qup-fw-load.h
@@ -14,6 +14,7 @@
 #define GENI_INIT_CFG_REVISION		0x0
 #define GENI_S_INIT_CFG_REVISION	0x4
 #define GENI_FORCE_DEFAULT_REG		0x20
+#define GENI_OUTPUT_CTRL		0x24
 #define GENI_CGC_CTRL			0x28
 #define GENI_CFG_REG0			0x100
 
@@ -21,6 +22,9 @@
 #define RX_FIFO_WIDTH_BIT		24
 #define RX_FIFO_WIDTH_MASK		0x3F
 
+#define QUPV3_SE_HW_PARAM_2		0xe2c
+#define GENI_USE_MINICORES		BIT(12)
+
 /*Same registers as GENI_DMA_MODE_EN*/
 #define QUPV3_SE_GENI_DMA_MODE_EN	0x258
 #define GENI_M_IRQ_ENABLE		0x614
@@ -173,6 +177,17 @@ struct elf_se_hdr {
 
 struct udevice;
 
+struct qup_mini_core_info {
+	u16 serial_protocol;
+	u16 fw_version;
+	u16 cfg_version;
+	u16 cfg_count;
+	u32 *cfg_val;
+	u8 *cfg_idx;
+	u32 *cfg_ram;
+	u32 cfg_ram_count;
+};
+
 int qcom_geni_load_firmware(phys_addr_t qup_base, struct udevice *dev);
 
 #endif /* _LINUX_QCOM_QUP_FW_LOAD */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 05/10] spl: Include SMEM driver in SPL
  2026-04-16  5:39 [PATCH v3 00/10] Qualcomm IPQ5210 SoC bringup Varadarajan Narayanan
                   ` (3 preceding siblings ...)
  2026-04-16  5:39 ` [PATCH v3 04/10] misc: qcom_geni: Add minicore support Varadarajan Narayanan
@ 2026-04-16  5:39 ` Varadarajan Narayanan
  2026-04-16  5:39 ` [PATCH v3 06/10] mach-snapdragon: Add initial support for IPQ5210 SPL Varadarajan Narayanan
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Varadarajan Narayanan @ 2026-04-16  5:39 UTC (permalink / raw)
  To: rayagonda.kokatanur, trini, casey.connolly, neil.armstrong,
	sumit.garg, peng.fan, jh80.chung, lukma, tien.fong.chee,
	tingting.meng, anshuld, alif.zakuan.yuslaimi, alice.guo,
	quentin.schulz, ilias.apalodimas, varadarajan.narayanan, sjg,
	mkorpershoek, h-salunke, alchark, dario.binacchi, ye.li,
	andre.przywara, dinesh.maniyam, luca.weiss, danila, aswin.murugan,
	balaji.selvanathan, adrian, n-francis, wens, jamie.gibbons,
	justin, ycliang, david.wronek, james.hilliard1, richard.genoud,
	michael, philip.molloy, sughosh.ganu, u-boot, u-boot-qcom

Add SPL_SMEM config to enable/disable SMEM driver in SPL.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
---
v3: Pick R-b Simon
---
 common/spl/Kconfig | 8 ++++++++
 drivers/Makefile   | 1 +
 2 files changed, 9 insertions(+)

diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index a21b71ad5d1..97c4e8236a4 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -1384,6 +1384,14 @@ config SPL_RAM_DEVICE
 	  be already in memory when SPL takes over, e.g. loaded by the boot
 	  ROM.
 
+config SPL_SMEM
+	bool "Support SMEM (Shared Memory manager)"
+	depends on SMEM
+	help
+	  Enable support for the Shared Memory Manager. The driver provides an
+	  interface to items in a heap shared among all processors. This enables
+	  the drivers in drivers/smem as part of an SPL build.
+
 config SPL_PCI_DFU
 	bool "PCIe boot support"
 	depends on SPL_PCI_ENDPOINT
diff --git a/drivers/Makefile b/drivers/Makefile
index 43d0ba33281..ead082450ca 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_SPL_SATA) += ata/ scsi/
 obj-$(CONFIG_SPL_LEGACY_BLOCK) += block/
 obj-$(CONFIG_SPL_THERMAL) += thermal/
 obj-$(CONFIG_SPL_UFS_SUPPORT) += scsi/ ufs/
+obj-$(CONFIG_SPL_SMEM) += smem/
 
 endif
 endif
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 06/10] mach-snapdragon: Add initial support for IPQ5210 SPL
  2026-04-16  5:39 [PATCH v3 00/10] Qualcomm IPQ5210 SoC bringup Varadarajan Narayanan
                   ` (4 preceding siblings ...)
  2026-04-16  5:39 ` [PATCH v3 05/10] spl: Include SMEM driver in SPL Varadarajan Narayanan
@ 2026-04-16  5:39 ` Varadarajan Narayanan
  2026-04-16 20:53   ` Simon Glass
  2026-04-17  4:22   ` Balaji Selvanathan
  2026-04-16  5:39 ` [PATCH v3 07/10] mach-snapdragon: spl: Update SMEM with boot details Varadarajan Narayanan
                   ` (3 subsequent siblings)
  9 siblings, 2 replies; 19+ messages in thread
From: Varadarajan Narayanan @ 2026-04-16  5:39 UTC (permalink / raw)
  To: rayagonda.kokatanur, trini, casey.connolly, neil.armstrong,
	sumit.garg, peng.fan, jh80.chung, lukma, tien.fong.chee,
	tingting.meng, anshuld, alif.zakuan.yuslaimi, alice.guo,
	quentin.schulz, ilias.apalodimas, varadarajan.narayanan, sjg,
	mkorpershoek, h-salunke, alchark, dario.binacchi, ye.li,
	andre.przywara, dinesh.maniyam, luca.weiss, danila, aswin.murugan,
	balaji.selvanathan, adrian, n-francis, wens, jamie.gibbons,
	justin, ycliang, david.wronek, james.hilliard1, richard.genoud,
	michael, philip.molloy, sughosh.ganu, u-boot, u-boot-qcom

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)
+/**
+ * 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'"
+	 */
+}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 07/10] mach-snapdragon: spl: Update SMEM with boot details
  2026-04-16  5:39 [PATCH v3 00/10] Qualcomm IPQ5210 SoC bringup Varadarajan Narayanan
                   ` (5 preceding siblings ...)
  2026-04-16  5:39 ` [PATCH v3 06/10] mach-snapdragon: Add initial support for IPQ5210 SPL Varadarajan Narayanan
@ 2026-04-16  5:39 ` 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
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Varadarajan Narayanan @ 2026-04-16  5:39 UTC (permalink / raw)
  To: rayagonda.kokatanur, trini, casey.connolly, neil.armstrong,
	sumit.garg, peng.fan, jh80.chung, lukma, tien.fong.chee,
	tingting.meng, anshuld, alif.zakuan.yuslaimi, alice.guo,
	quentin.schulz, ilias.apalodimas, varadarajan.narayanan, sjg,
	mkorpershoek, h-salunke, alchark, dario.binacchi, ye.li,
	andre.przywara, dinesh.maniyam, luca.weiss, danila, aswin.murugan,
	balaji.selvanathan, adrian, n-francis, wens, jamie.gibbons,
	justin, ycliang, david.wronek, james.hilliard1, richard.genoud,
	michael, philip.molloy, sughosh.ganu, u-boot, u-boot-qcom

Update SMEM with the storage medium from which the system booted.

Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
---
v3: Move SMEM init from previous patch to this new patch
---
 arch/arm/mach-snapdragon/spl.c | 65 ++++++++++++++++++++++++++++++++++
 include/smem.h                 |  3 ++
 2 files changed, 68 insertions(+)

diff --git a/arch/arm/mach-snapdragon/spl.c b/arch/arm/mach-snapdragon/spl.c
index 8cc28bbee82..82b390ba3d7 100644
--- a/arch/arm/mach-snapdragon/spl.c
+++ b/arch/arm/mach-snapdragon/spl.c
@@ -11,6 +11,7 @@
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/sections.h>
+#include <smem.h>
 #include <atf_common.h>
 #include <linux/err.h>
 #include <dm/device-internal.h>
@@ -169,6 +170,46 @@ static int qcom_spl_get_fit_img_entry_point(void *fit, int node,
 	return ret;
 }
 
+#if IS_ENABLED(CONFIG_SPL_SMEM)
+/**
+ * qcom_spl_populate_smem() - Populate shared memory (SMEM) information.
+ * @ctx:	Pointer to the global SPL context.
+ *
+ * This function initializes and populates various SMEM items with boot-related
+ * information, such as flash type, try-mode status, and ATF enable status.
+ * Return: 0 on success, or a negative error code on failure.
+ */
+static int qcom_spl_populate_smem(void *ctx)
+{
+	int ret;
+	size_t size;
+	struct udevice *smem;
+	u32 *fltype;
+
+	ret = uclass_get_device(UCLASS_SMEM, 0, &smem);
+	if (ret) {
+		pr_err("Failed to find SMEM node (%d)\n", ret);
+		return ret;
+	}
+
+	size = sizeof(u32);
+	ret = smem_alloc(smem, -1, SMEM_BOOT_FLASH_TYPE, size);
+	if (ret) {
+		pr_err("Failed to alloc item: SMEM_BOOT_FLASH_TYPE (%d)\n", ret);
+		return ret;
+	}
+
+	fltype = (u32 *)smem_get(smem, -1, SMEM_BOOT_FLASH_TYPE, &size);
+	if (!fltype) {
+		pr_err("Failed to get item: SMEM_BOOT_FLASH_TYPE\n");
+		return -ENOENT;
+	}
+
+	if (IS_ENABLED(CONFIG_SPL_MMC))
+		*fltype = SMEM_BOOT_MMC_FLASH;
+	return 0;
+}
+#endif /* IS_ENABLED(CONFIG_SPL_SMEM) */
 /**
  * qcom_spl_get_iftbl_entry_by_name() - Get an interface table entry by name.
  * @if_tbl:	Pointer to the QCLIB interface table.
@@ -330,6 +371,30 @@ int qclib_post_process_from_spl(void)
 	return 0;
 }
 
+#if IS_ENABLED(CONFIG_SPL_SMEM)
+/**
+ * spl_board_prepare_for_boot() - Prepare board for boot
+ *
+ * This function is called by SPL before jumping to the next stage.
+ * It populates SMEM during coldboot.
+ */
+void spl_board_prepare_for_boot(void)
+{
+	int ret;
+
+	/*
+	 * Populate SMEM in coldboot (Dload bit not set)
+	 */
+	if (!QCOM_SPL_IS_DLOAD_BIT_SET) {
+		printf("Populating SMEM\n");
+		ret = qcom_spl_populate_smem(NULL);
+		if (ret) {
+			pr_err("Failed to populate SMEM (%d)\n", ret);
+			qcom_spl_error_handler(NULL);
+		}
+	}
+}
+#endif /* IS_ENABLED(CONFIG_SPL_SMEM) */
 
 /**
  * spl_get_load_buffer() - Allocate a cache-aligned buffer for image loading.
diff --git a/include/smem.h b/include/smem.h
index b19c534ebc4..f16ba7d63dc 100644
--- a/include/smem.h
+++ b/include/smem.h
@@ -87,4 +87,7 @@ void *smem_get(struct udevice *dev, unsigned int host, unsigned int item, size_t
  */
 int smem_get_free_space(struct udevice *dev, unsigned int host);
 
+#define SMEM_BOOT_FLASH_TYPE			498
+#define SMEM_BOOT_MMC_FLASH			5
+
 #endif /* _smem_h_ */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 08/10] mach-snapdragon: Add commands to create wrapper ELF
  2026-04-16  5:39 [PATCH v3 00/10] Qualcomm IPQ5210 SoC bringup Varadarajan Narayanan
                   ` (6 preceding siblings ...)
  2026-04-16  5:39 ` [PATCH v3 07/10] mach-snapdragon: spl: Update SMEM with boot details Varadarajan Narayanan
@ 2026-04-16  5:39 ` 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
  9 siblings, 1 reply; 19+ messages in thread
From: Varadarajan Narayanan @ 2026-04-16  5:39 UTC (permalink / raw)
  To: rayagonda.kokatanur, trini, casey.connolly, neil.armstrong,
	sumit.garg, peng.fan, jh80.chung, lukma, tien.fong.chee,
	tingting.meng, anshuld, alif.zakuan.yuslaimi, alice.guo,
	quentin.schulz, ilias.apalodimas, varadarajan.narayanan, sjg,
	mkorpershoek, h-salunke, alchark, dario.binacchi, ye.li,
	andre.przywara, dinesh.maniyam, luca.weiss, danila, aswin.murugan,
	balaji.selvanathan, adrian, n-francis, wens, jamie.gibbons,
	justin, ycliang, david.wronek, james.hilliard1, richard.genoud,
	michael, philip.molloy, sughosh.ganu, u-boot, u-boot-qcom

The IPQ5210 boot ROM expects the SPL binary image to be embedded within
an ELF along with additional binaries. Hence add the relevant commands
and linker script needed to convert u-boot-spl.bin to the expected
format.

Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
---
v3: s/a image/an image/
    Add SPDX header to linker script
    Pre-process linker script to use IMAGE_TEXT_BASE instead of hard coding it
---
 arch/arm/mach-snapdragon/Kconfig              |  7 ++++++
 .../mach-snapdragon/ipq5210-spl-wrap-elf.lds  | 18 ++++++++++++++
 scripts/Makefile.xpl                          | 24 +++++++++++++++++++
 3 files changed, 49 insertions(+)
 create mode 100644 arch/arm/mach-snapdragon/ipq5210-spl-wrap-elf.lds

diff --git a/arch/arm/mach-snapdragon/Kconfig b/arch/arm/mach-snapdragon/Kconfig
index d3de8693b5a..d94cb6206e8 100644
--- a/arch/arm/mach-snapdragon/Kconfig
+++ b/arch/arm/mach-snapdragon/Kconfig
@@ -42,4 +42,11 @@ config SYS_CONFIG_NAME
 	  Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
 	  will be used for board configuration.
 
+config SPL_WRAPPER_ELF
+	bool "Create wrapper ELF for applicable platforms"
+	depends on SPL
+	help
+	  Some platforms embed the U-Boot SPL binary within an ELF as a segment.
+	  Additional tools are used to convert this ELF into an image that is
+	  usable for the boot ROM.
 endif
diff --git a/arch/arm/mach-snapdragon/ipq5210-spl-wrap-elf.lds b/arch/arm/mach-snapdragon/ipq5210-spl-wrap-elf.lds
new file mode 100644
index 00000000000..5a582e65ca0
--- /dev/null
+++ b/arch/arm/mach-snapdragon/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 {
+	. = IMAGE_TEXT_BASE;
+	_entry = . ;
+	data : {
+		*(.data)
+		. = ALIGN(4);
+	} :ptype
+}
diff --git a/scripts/Makefile.xpl b/scripts/Makefile.xpl
index c5ddf64c73f..930ca2c0e91 100644
--- a/scripts/Makefile.xpl
+++ b/scripts/Makefile.xpl
@@ -255,6 +255,26 @@ MKIMAGEFLAGS_boot.bin = -T zynqmpimage -R $(srctree)/$(CONFIG_BOOT_INIT_FILE) \
 	-n "$(shell cd $(srctree); readlink -f $(CONFIG_PMUFW_INIT_FILE))"
 endif
 
+ifeq ($(CONFIG_SPL_WRAPPER_ELF),y)
+# Convert ELF to object file
+OBJCOPYFLAGS_$(SPL_BIN).bin.o = -I binary -O elf64-littleaarch64
+
+# Wrap the object file inside a ELF
+QCOM_SPL_SOC = $(shell echo $(notdir "$(CONFIG_DEFAULT_DEVICE_TREE)") | cut -f1 -d-)
+QCOM_SPL_WRAP_LDS = $(srctree)/arch/arm/mach-snapdragon/$(QCOM_SPL_SOC)-spl-wrap-elf.lds
+LDFLAGS_$(SPL_BIN).wrap-elf = -T $(obj)/$(SPL_BIN).wrap-elf.lds
+
+$(obj)/$(SPL_BIN).wrap-elf.lds: $(QCOM_SPL_WRAP_LDS) FORCE
+	$(call if_changed_dep,cpp_lds)
+
+$(obj)/$(SPL_BIN).bin.o: $(obj)/$(SPL_BIN).bin $(obj)/$(SPL_BIN).wrap-elf.lds FORCE
+	$(call if_changed,objcopy)
+
+$(obj)/$(SPL_BIN).wrap-elf: $(obj)/$(SPL_BIN).bin.o FORCE
+	$(call if_changed,ld)
+
+endif
+
 $(obj)/$(SPL_BIN)-align.bin: $(obj)/$(SPL_BIN).bin
 	@dd if=$< of=$@ conv=block,sync bs=4 2>/dev/null;
 
@@ -301,6 +321,10 @@ INPUTS-$(CONFIG_ARCH_ZYNQMP)	+= $(obj)/boot.bin
 
 INPUTS-$(CONFIG_ARCH_MEDIATEK)	+= $(obj)/u-boot-spl-mtk.bin
 
+ifeq ($(CONFIG_ARCH_SNAPDRAGON),y)
+INPUTS-$(CONFIG_SPL_WRAPPER_ELF) += spl/u-boot-spl.wrap-elf
+endif
+
 all:	$(INPUTS-y)
 
 quiet_cmd_cat = CAT     $@
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 09/10] configs: add qcom_ipq5210_mmc_defconfig
  2026-04-16  5:39 [PATCH v3 00/10] Qualcomm IPQ5210 SoC bringup Varadarajan Narayanan
                   ` (7 preceding siblings ...)
  2026-04-16  5:39 ` [PATCH v3 08/10] mach-snapdragon: Add commands to create wrapper ELF Varadarajan Narayanan
@ 2026-04-16  5:39 ` Varadarajan Narayanan
  2026-04-16  5:39 ` [PATCH v3 10/10] doc: board/qualcomm: Update RDP build instructions Varadarajan Narayanan
  9 siblings, 0 replies; 19+ messages in thread
From: Varadarajan Narayanan @ 2026-04-16  5:39 UTC (permalink / raw)
  To: rayagonda.kokatanur, trini, casey.connolly, neil.armstrong,
	sumit.garg, peng.fan, jh80.chung, lukma, tien.fong.chee,
	tingting.meng, anshuld, alif.zakuan.yuslaimi, alice.guo,
	quentin.schulz, ilias.apalodimas, varadarajan.narayanan, sjg,
	mkorpershoek, h-salunke, alchark, dario.binacchi, ye.li,
	andre.przywara, dinesh.maniyam, luca.weiss, danila, aswin.murugan,
	balaji.selvanathan, adrian, n-francis, wens, jamie.gibbons,
	justin, ycliang, david.wronek, james.hilliard1, richard.genoud,
	michael, philip.molloy, sughosh.ganu, u-boot, u-boot-qcom

Introduce a defconfig for the Qualcomm IPQ5210 SoC based RDPs.
Presently supports eMMC.

Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
---
v3: Change CONFIG_SPL_STACK from 0x08c60000 to 0x08c24000

v2: Enable CONFIG_QCOM_GENI_MINICORE
---
 configs/qcom_ipq5210_mmc_defconfig | 106 +++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)
 create mode 100644 configs/qcom_ipq5210_mmc_defconfig

diff --git a/configs/qcom_ipq5210_mmc_defconfig b/configs/qcom_ipq5210_mmc_defconfig
new file mode 100644
index 00000000000..e903daa581c
--- /dev/null
+++ b/configs/qcom_ipq5210_mmc_defconfig
@@ -0,0 +1,106 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_SYS_INIT_SP_BSS_OFFSET=0x180000
+CONFIG_ARCH_SNAPDRAGON=y
+CONFIG_TEXT_BASE=0x87980000
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_ENV_SIZE=0x40000
+CONFIG_ENV_OFFSET=0
+CONFIG_DEFAULT_DEVICE_TREE="qcom/ipq5210-rdp504"
+CONFIG_SYS_LOAD_ADDR=0x90000000
+CONFIG_REMAKE_ELF=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+# CONFIG_BOOTSTD is not set
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_USE_PREBOOT=y
+CONFIG_SYS_PBSIZE=1024
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_EFI_PARTITION=y
+CONFIG_OF_LIVE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_CLK=y
+CONFIG_CLK_QCOM_IPQ5210=y
+CONFIG_MSM_GPIO=y
+# CONFIG_I2C is not set
+# CONFIG_INPUT is not set
+CONFIG_MISC=y
+CONFIG_QCOM_GENI=y
+CONFIG_QCOM_GENI_MINICORE=y
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_SDHCI=y
+# CONFIG_MMC_SDHCI_ADMA_HELPERS is not set
+# CONFIG_MMC_SDHCI_ADMA is not set
+# CONFIG_MMC_SDHCI_ADMA_FORCE_32BIT is not set
+# CONFIG_MMC_SDHCI_ADMA_64BIT is not set
+CONFIG_MMC_SDHCI_MSM=y
+CONFIG_MTD=y
+CONFIG_DM_MDIO=y
+CONFIG_DM_ETH_PHY=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_QCOM=y
+CONFIG_RGMII=y
+CONFIG_PHY=y
+CONFIG_PHY_QCOM_QMP_UFS=y
+CONFIG_PHY_QCOM_QUSB2=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_QCOM_IPQ5210=y
+CONFIG_DEBUG_UART_MSM_GENI=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_MSM_SERIAL=y
+CONFIG_MSM_GENI_SERIAL=y
+CONFIG_SOC_QCOM=y
+CONFIG_SPL=y
+CONFIG_SPL_FRAMEWORK=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_OF_LIBFDT=y
+CONFIG_SPL_DM=y
+CONFIG_SPL_GPIO=y
+CONFIG_SPL_DM_GPIO=y
+CONFIG_SPL_DM_RESET=y
+CONFIG_SPL_PINCTRL=y
+CONFIG_SPL_CLK=y
+CONFIG_SPL_DRIVERS_MISC=y
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_SMEM=y
+CONFIG_DM_STATS=y
+CONFIG_SPL_SYS_MALLOC_F=y
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x20000
+CONFIG_SPL_SYS_MALLOC=y
+CONFIG_SYS_MALLOC_DEFAULT_TO_INIT=y
+CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y
+CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0x80008000
+CONFIG_SPL_SYS_MALLOC_SIZE=0x20000
+# CONFIG_SPL_SEPARATE_BSS is not set
+# CONFIG_SPL_USE_TINY_PRINTF is not set
+CONFIG_SPL_BSS_MAX_SIZE=0x4000
+CONFIG_SPL_TEXT_BASE=0x08c24000
+CONFIG_SPL_MAX_SIZE=0x3D000
+CONFIG_SPL_MMC=y
+CONFIG_SPL_MMC_SDHCI_ADMA=y
+CONFIG_SPL_MMC_WRITE=y
+CONFIG_SPL_SYS_MMCSD_RAW_MODE=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=0x00
+CONFIG_COUNTER_FREQUENCY=24000000
+CONFIG_SPL_STACKPROTECTOR=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_ATF=y
+CONFIG_SPL_ATF_LOAD_IMAGE_V2=y
+CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y
+CONFIG_SPL_HAS_LOAD_FIT_ADDRESS=y
+CONFIG_SPL_LOAD_FIT_ADDRESS=0x08cbe000
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_HAVE_INIT_STACK=y
+CONFIG_SPL_STACK=0x08c24000
+# CONFIG_SAVE_PREV_BL_FDT_ADDR is not set
+CONFIG_SPL_WRAPPER_ELF=y
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 10/10] doc: board/qualcomm: Update RDP build instructions
  2026-04-16  5:39 [PATCH v3 00/10] Qualcomm IPQ5210 SoC bringup Varadarajan Narayanan
                   ` (8 preceding siblings ...)
  2026-04-16  5:39 ` [PATCH v3 09/10] configs: add qcom_ipq5210_mmc_defconfig Varadarajan Narayanan
@ 2026-04-16  5:39 ` Varadarajan Narayanan
  2026-04-16 20:54   ` Simon Glass
  9 siblings, 1 reply; 19+ messages in thread
From: Varadarajan Narayanan @ 2026-04-16  5:39 UTC (permalink / raw)
  To: rayagonda.kokatanur, trini, casey.connolly, neil.armstrong,
	sumit.garg, peng.fan, jh80.chung, lukma, tien.fong.chee,
	tingting.meng, anshuld, alif.zakuan.yuslaimi, alice.guo,
	quentin.schulz, ilias.apalodimas, varadarajan.narayanan, sjg,
	mkorpershoek, h-salunke, alchark, dario.binacchi, ye.li,
	andre.przywara, dinesh.maniyam, luca.weiss, danila, aswin.murugan,
	balaji.selvanathan, adrian, n-francis, wens, jamie.gibbons,
	justin, ycliang, david.wronek, james.hilliard1, richard.genoud,
	michael, philip.molloy, sughosh.ganu, u-boot, u-boot-qcom

Add details about the SPL & U-Boot proper build steps, converting to
flashable images, source URLs for the needed binaries and scripts.

Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
---
v3: Use '-' for sub heading instead of '='
    Add location for template.its and sort the list alphabetically
---
 doc/board/qualcomm/rdp.rst | 70 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/doc/board/qualcomm/rdp.rst b/doc/board/qualcomm/rdp.rst
index 99cf8eba57c..3a96476dd32 100644
--- a/doc/board/qualcomm/rdp.rst
+++ b/doc/board/qualcomm/rdp.rst
@@ -42,6 +42,67 @@ on your device with::
 
 U-Boot should be running after a reboot (``reset``).
 
+Build steps for IPQ5210 based Qualcomm Dragonwing F8 & N8 Platforms:
+--------------------------------------------------------------------
+
+Please refer to the following URLs for more details about the platforms.
+
+	F8: https://www.qualcomm.com/networking-infrastructure/products/f-series/f8-platform
+
+	N8: https://www.qualcomm.com/networking-infrastructure/products/n-series/n8-platform
+
+1. Since U-Boot SPL is enabled on these platforms, the build command generates
+   both the U-Boot SPL and U-Boot proper images. Assuming ${uboot_dir} is the
+   top of the U-Boot sources and ${out_dir} as the output directory,
+
+	$ cd ${uboot_dir}
+	$ export CROSS_COMPILE=<aarch64 toolchain prefix>
+	$ make -j8 O=${out_dir} qcom_ipq5210_mmc_defconfig
+	$ make -j8 O=${out_dir}
+
+   U-Boot SPL image:	${out_dir}/spl/u-boot-spl.wrap-elf
+   U-Boot image:	${out_dir}/u-boot.elf
+
+2. Convert the SPL image to multi ELF
+
+	$ cd ${out_dir}/spl
+	$ python elftombn.py -f u-boot-spl.wrap-elf -o u-boot-spl.mbn -v7
+	$ python create_multielf.py -f u-boot-spl.mbn,tmel-ipq52xx-patch.elf \
+					-o u-boot-spl.melf
+
+   This u-boot-spl.melf should be flashed into 0:SPL partition.
+   Please see below for the location of ``tmel-ipq52xx-patch.elf``
+
+3. Convert the U-Boot image to bootloader image
+
+	$ cd ${out_dir}
+	$ python elftombn.py -f u-boot.elf -o u-boot.mbn -v7
+
+   The u-boot.mbn has to be combined with qc_config.elf, QCLib.elf, TFA and
+   OPTEE. Please see below for the location for these ELFs. TFA and OPTEE can be
+   built from the sources using the following commands
+
+   TFA:
+	$ make PLAT=ipq52xx QTISECLIB_PATH=path/to/libqtisec_dbg.a SPD=opteed
+
+   OPTEE:
+	$ make PLATFORM=qcom-ipq52xx -j16
+
+   These binaries can be combined into a flashable image using ``gen_its.py``.
+
+	$ python gen_its.py --arch ipq5210		\
+		--qclib_path QCLib.elf			\
+		--qcconfig_path qc_config.elf		\
+		--tfa_bl31_path bl31.mbn		\
+		--uboot_path u-boot.mbn			\
+		--optee_path tee-raw.mbn		\
+		-p qcconfig qclib			\
+		-P tfa_bl31 uboot optee			\
+		-o output/hm_503_test_uboot.img		\
+		--template template.its
+
+   This should be flashed into 0:BOOTLDR partition.
+
 .. WARNING
 	Boards with newer software versions would automatically go the emergency
 	download (EDL) mode if U-Boot is not functioning as expected. If its a
@@ -54,5 +115,14 @@ U-Boot should be running after a reboot (``reset``).
 	Note that the support added is very basic. Restoring the original U-Boot
 	on boards with older version of the software requires a debugger.
 
+.. _create_multielf.py: https://raw.githubusercontent.com/coreboot/coreboot/refs/heads/main/util/qualcomm/create_multielf.py
 .. _elftombn.py: https://git.codelinaro.org/clo/qsdk/oss/system/tools/meta/-/tree/NHSS.QSDK.13.0.5.r2/scripts?ref_type=heads
 .. _edl: https://github.com/bkerler/edl
+.. _gen_its.py: https://git.codelinaro.org/clo/qsdk/oss/system/tools/meta/-/tree/win.platform_tools.1.0.r34/scripts?ref_type=heads
+.. _libqtisec_dbg.a: https://softwarecenter.qualcomm.com/nexus/generic/product/chip/software-product/IPQ5210.NLQ.14.0/ipq5210.nlq.14.0-qca-oem-qartifact/r00036.1/WIN.TFA.1.0.R4/apss_proc/out/proprietary/qtiseclib/output/ipq52xx/release/libqtisec_dbg.a
+.. _OPTEE: https://git.codelinaro.org/clo/trusted-firmware/optee_os/optee_os/-/tree/win.optee.1.0?ref_type=heads
+.. _qc_config.elf: https://softwarecenter.qualcomm.com/nexus/generic/product/chip/software-product/IPQ5210.NLQ.14.0/ipq5210.nlq.14.0-qca-oem-qartifact/r00036.1/BOOT.MXF.2.3.1.1/boot_images/boot/QcomPkg/SocPkg/Hermosa/Bin/LC/RELEASE/qc_config.elf
+.. _QCLib.elf: https://softwarecenter.qualcomm.com/nexus/generic/product/chip/software-product/IPQ5210.NLQ.14.0/ipq5210.nlq.14.0-qca-oem-qartifact/r00036.1/BOOT.MXF.2.3.1.1/boot_images/boot/QcomPkg/SocPkg/Hermosa/Bin/LC/RELEASE/QCLib.elf
+.. _template.its: https://git.codelinaro.org/clo/qsdk/oss/system/tools/meta/-/tree/win.platform_tools.1.0.r34/scripts?ref_type=heads
+.. _TFA: https://git.codelinaro.org/clo/trusted-firmware/tf-a/trusted-firmware-a/-/tree/win.tfa.1.0.r4?ref_type=heads
+.. _tmel-ipq52xx-patch.elf: https://softwarecenter.qualcomm.com/nexus/generic/product/chip/software-product/IPQ5210.NLQ.14.0/ipq5210.nlq.14.0-qca-oem-qartifact/r00036.1/TMEL.WNS.2.4/tmel-ipq52xx-patch.elf
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 02/10] clk/qcom: add initial clock driver for ipq5210
  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
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2026-04-16 20:52 UTC (permalink / raw)
  To: varadarajan.narayanan
  Cc: rayagonda.kokatanur, trini, casey.connolly, neil.armstrong,
	sumit.garg, peng.fan, jh80.chung, lukma, tien.fong.chee,
	tingting.meng, anshuld, alif.zakuan.yuslaimi, alice.guo,
	quentin.schulz, ilias.apalodimas, sjg, mkorpershoek, h-salunke,
	alchark, dario.binacchi, ye.li, andre.przywara, dinesh.maniyam,
	luca.weiss, danila, aswin.murugan, balaji.selvanathan, adrian,
	n-francis, wens, jamie.gibbons, justin, ycliang, david.wronek,
	james.hilliard1, richard.genoud, michael, philip.molloy,
	sughosh.ganu, u-boot, u-boot-qcom

Hi Varadarajan,

On 2026-04-16T05:39:18, Varadarajan Narayanan
<varadarajan.narayanan@oss.qualcomm.com> wrote:
> clk/qcom: add initial clock driver for ipq5210
>
> Add initial set of clocks and resets for enabling U-Boot on ipq5210
> based RDP platforms.
>
> Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
>
> drivers/clk/qcom/Kconfig         |  8 ++++
>  drivers/clk/qcom/Makefile        |  1 +
>  drivers/clk/qcom/clock-ipq5210.c | 97 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 106 insertions(+)

> +#include <dm/device-internal.h>

Is this needed?

> +static ulong ipq5210_set_rate(struct clk *clk, ulong rate)
> +{
> +     struct msm_clk_priv *priv = dev_get_priv(clk->dev);
> +
> +     switch (clk->id) {
> +     case GCC_QUPV3_WRAP_SE1_CLK:
> +             clk_rcg_set_rate_mnd(priv->base, priv->data->clks[clk->id].cbcr_reg,

cbcr_reg is a bit confusing since that name suggests a CBCR register -
see the ipq5424 driver which uses 'reg'. What do you think about using
reg consistently, or maybe add a comment explaining this?

> +static int ipq5210_enable(struct clk *clk)
> +{
> +     struct msm_clk_priv *priv = dev_get_priv(clk->dev);
> +
> +     if (priv->data->num_clks <= clk->id) {
> +             debug("%s: unknown clk id %lu\n", __func__, clk->id);
> +             return 0;
> +     }

Shouldn't the comparison be <  ?

Also, should return an error, not 0.

> +     qcom_gate_clk_en(priv, clk->id);
> +
> +     return 0;

Should return any error from qcom_gate_clk_en()

Regards,
Simon

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 03/10] pinctrl: qcom: Add ipq5210 pinctrl driver
  2026-04-16  5:39 ` [PATCH v3 03/10] pinctrl: qcom: Add ipq5210 pinctrl driver Varadarajan Narayanan
@ 2026-04-16 20:53   ` Simon Glass
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2026-04-16 20:53 UTC (permalink / raw)
  To: varadarajan.narayanan
  Cc: rayagonda.kokatanur, trini, casey.connolly, neil.armstrong,
	sumit.garg, peng.fan, jh80.chung, lukma, tien.fong.chee,
	tingting.meng, anshuld, alif.zakuan.yuslaimi, alice.guo,
	quentin.schulz, ilias.apalodimas, sjg, mkorpershoek, h-salunke,
	alchark, dario.binacchi, ye.li, andre.przywara, dinesh.maniyam,
	luca.weiss, danila, aswin.murugan, balaji.selvanathan, adrian,
	n-francis, wens, jamie.gibbons, justin, ycliang, david.wronek,
	james.hilliard1, richard.genoud, michael, philip.molloy,
	sughosh.ganu, u-boot, u-boot-qcom

Hi Varadarajan,

On 2026-04-16T05:39:18, Varadarajan Narayanan
<varadarajan.narayanan@oss.qualcomm.com> wrote:
> pinctrl: qcom: Add ipq5210 pinctrl driver
>
> Add pinctrl driver for the TLMM block found in the ipq5210 SoC.
>
> Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
>
> drivers/pinctrl/qcom/Kconfig           |   8 +
>  drivers/pinctrl/qcom/Makefile          |   1 +
>  drivers/pinctrl/qcom/pinctrl-ipq5210.c | 349 +++++++++++++++++++++++++++++++++
>  3 files changed, 358 insertions(+)

> +static const struct msm_pinctrl_data ipq5210_data = {
> +     .pin_data = {
> +             .pin_count = 53,
> +             .special_pins_start = 53, /* There are no special pins */

From my reading, the PINGROUP definitions run from 0 to 53, which is
54 pins, so shouldn't these two be 54 ?

> +     pr_err("Can't find requested function for pin %u pin\n", pin);

The word 'pin' appears twice

Regards,
Simon

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 04/10] misc: qcom_geni: Add minicore support
  2026-04-16  5:39 ` [PATCH v3 04/10] misc: qcom_geni: Add minicore support Varadarajan Narayanan
@ 2026-04-16 20:53   ` Simon Glass
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2026-04-16 20:53 UTC (permalink / raw)
  To: varadarajan.narayanan
  Cc: rayagonda.kokatanur, trini, casey.connolly, neil.armstrong,
	sumit.garg, peng.fan, jh80.chung, lukma, tien.fong.chee,
	tingting.meng, anshuld, alif.zakuan.yuslaimi, alice.guo,
	quentin.schulz, ilias.apalodimas, sjg, mkorpershoek, h-salunke,
	alchark, dario.binacchi, ye.li, andre.przywara, dinesh.maniyam,
	luca.weiss, danila, aswin.murugan, balaji.selvanathan, adrian,
	n-francis, wens, jamie.gibbons, justin, ycliang, david.wronek,
	james.hilliard1, richard.genoud, michael, philip.molloy,
	sughosh.ganu, u-boot, u-boot-qcom

Hi Varadarajan,

On 2026-04-16T05:39:18, Varadarajan Narayanan
<varadarajan.narayanan@oss.qualcomm.com> wrote:
> misc: qcom_geni: Add minicore support
>
> The qcom_geni driver reads an ELF from storage and configures a set of
> registers and programs the firmware to the GENI Serial Engine (GENI-SE)
> wrapper device for the expected functionality.
>
> Unlike the GENI-SE wrapper found in MSM SoCs, the IPQ5210's GENI-SE
> wrapper is pre-configured for one of the functions defined in 'enum
> geni_se_protocol_type'. Hence, the firmware download is not needed.
> Only the register configuration part is needed.
>
> Earlier, the boot stages before U-Boot would configure the GENI-SE (to
> access UART/SPI etc). Since for IPQ5210 U-Boot SPL, the previous stage
> (i.e. boot ROM) doesn't do that modify the driver to do the register
> configuration part alone without reading an ELF from the storage.
>
> Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
>
> drivers/misc/Kconfig              |   6 +++
>  drivers/misc/Makefile             |   1 +
>  drivers/misc/qcom_geni-minicore.c | 102 ++++++++++++++++++++++++++++++++++++++
>  drivers/misc/qcom_geni.c          |  94 ++++++++++++++++++++++++++++++-----
>  include/soc/qcom/geni-se.h        |   2 +
>  include/soc/qcom/qup-fw-load.h    |  15 ++++++
>  6 files changed, 208 insertions(+), 12 deletions(-)

> +config QCOM_GENI_MINICORE
> +     bool "Support minicores in Qualcomm Generic Interface (GENI) driver"
> +     depends on QCOM_GENI
> +     help
> +       Enable support for minicores in Qualcomm GENI and it's peripherals.

its

> +     } else if (IS_ENABLED(CONFIG_QCOM_GENI_MINICORE)) {
> +             struct qup_mini_core_info *qmc = info;
> +
> +             for (; qmc->serial_protocol != GENI_SE_INVALID_PROTO; qmc++)
> +                     if (qmc->serial_protocol == rsc->protocol)
> +                             break;
> +
> +             tmp_hdr.magic = MAGIC_NUM_SE;

Please add an error return when no matching protocol is found.

> +#define QUPV3_SE_HW_PARAM_2          0xe2c
> +#define GENI_USE_MINICORES           BIT(12)

SE_HW_PARAM_2 is already added in geni-se.h in this same patch - maybe
use the one in geni-se.h and move the GENI_USE_MINICORES definition
there as well?

Regards,
Simon

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 06/10] mach-snapdragon: Add initial support for IPQ5210 SPL
  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
  1 sibling, 0 replies; 19+ messages in thread
From: Simon Glass @ 2026-04-16 20:53 UTC (permalink / raw)
  To: varadarajan.narayanan
  Cc: rayagonda.kokatanur, trini, casey.connolly, neil.armstrong,
	sumit.garg, peng.fan, jh80.chung, lukma, tien.fong.chee,
	tingting.meng, anshuld, alif.zakuan.yuslaimi, alice.guo,
	quentin.schulz, ilias.apalodimas, sjg, mkorpershoek, h-salunke,
	alchark, dario.binacchi, ye.li, andre.przywara, dinesh.maniyam,
	luca.weiss, danila, aswin.murugan, balaji.selvanathan, adrian,
	n-francis, wens, jamie.gibbons, justin, ycliang, david.wronek,
	james.hilliard1, richard.genoud, michael, philip.molloy,
	sughosh.ganu, u-boot, u-boot-qcom

Hi Varadarajan,

On 2026-04-16T05:39:18, Varadarajan Narayanan
<varadarajan.narayanan@oss.qualcomm.com> wrote:
> mach-snapdragon: Add initial support for IPQ5210 SPL
>
> 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>
>
> arch/arm/Kconfig                  |   5 +-
>  arch/arm/mach-snapdragon/Makefile |   3 +
>  arch/arm/mach-snapdragon/spl.c    | 640 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 646 insertions(+), 2 deletions(-)

> +static int spl_find_partition_info(enum uclass_id uclass_id, int device_num,
> +                                const char *part_name,
> +                                struct disk_partition *info)

This function is defined unconditionally but only called within the
CONFIG_IS_ENABLED(MMC) block - you could use __maybe_unused ?

> +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);
> +     }

spl_get_load_buffer() always returns a non-null address so this code
is not needed

> + * @entry_point:Pointer to store the retrieved entry point.

nit: missing space after the colon

> +     if (desc->part_type == PART_TYPE_UNKNOWN) {
> +             printf("Initializing partition table\n");
> +             /*
> +              * Prefer EFI/GPT
> +              */
> +             desc->part_type = PART_TYPE_EFI;
> +     }

Simply setting part_type to PART_TYPE_EFI doesn't actually initialise
the partition table - it just tells the partition code to assume GPT.
If the device doesn't have GPT, it will fail - how about calling
part_init() or letting part_driver_lookup_type() auto-detect?

Regards,
Simon

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 07/10] mach-snapdragon: spl: Update SMEM with boot details
  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
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2026-04-16 20:54 UTC (permalink / raw)
  To: varadarajan.narayanan
  Cc: rayagonda.kokatanur, trini, casey.connolly, neil.armstrong,
	sumit.garg, peng.fan, jh80.chung, lukma, tien.fong.chee,
	tingting.meng, anshuld, alif.zakuan.yuslaimi, alice.guo,
	quentin.schulz, ilias.apalodimas, sjg, mkorpershoek, h-salunke,
	alchark, dario.binacchi, ye.li, andre.przywara, dinesh.maniyam,
	luca.weiss, danila, aswin.murugan, balaji.selvanathan, adrian,
	n-francis, wens, jamie.gibbons, justin, ycliang, david.wronek,
	james.hilliard1, richard.genoud, michael, philip.molloy,
	sughosh.ganu, u-boot, u-boot-qcom

Hi Varadarajan,

On 2026-04-16T05:39:18, Varadarajan Narayanan
<varadarajan.narayanan@oss.qualcomm.com> wrote:
> mach-snapdragon: spl: Update SMEM with boot details
>
> Update SMEM with the storage medium from which the system booted.
>
> Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
>
> arch/arm/mach-snapdragon/spl.c | 65 ++++++++++++++++++++++++++++++++++++++++++
>  include/smem.h                 |  3 ++
>  2 files changed, 68 insertions(+)

> +     if (IS_ENABLED(CONFIG_SPL_MMC))
> +             *fltype = SMEM_BOOT_MMC_FLASH;
> +     return 0;
> +}

If CONFIG_SPL_MMC is not enabled, fltype is left uninitialised. The
function should either set a default value or return an error when no
boot medium matches.

> +}
> +#endif /* IS_ENABLED(CONFIG_SPL_SMEM) */
> +/**

Missing blank line between the #endif and the next function comment.

> +void spl_board_prepare_for_boot(void)
> +{
> +     int ret;
> +
> +     /*
> +      * Populate SMEM in coldboot (Dload bit not set)
> +      */
> +     if (!QCOM_SPL_IS_DLOAD_BIT_SET) {
> +             printf("Populating SMEM\n");

This printf() is user-visible during every coldboot - try log_debug() etc.

Regards,
Simon

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 08/10] mach-snapdragon: Add commands to create wrapper ELF
  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
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2026-04-16 20:54 UTC (permalink / raw)
  To: varadarajan.narayanan
  Cc: rayagonda.kokatanur, trini, casey.connolly, neil.armstrong,
	sumit.garg, peng.fan, jh80.chung, lukma, tien.fong.chee,
	tingting.meng, anshuld, alif.zakuan.yuslaimi, alice.guo,
	quentin.schulz, ilias.apalodimas, sjg, mkorpershoek, h-salunke,
	alchark, dario.binacchi, ye.li, andre.przywara, dinesh.maniyam,
	luca.weiss, danila, aswin.murugan, balaji.selvanathan, adrian,
	n-francis, wens, jamie.gibbons, justin, ycliang, david.wronek,
	james.hilliard1, richard.genoud, michael, philip.molloy,
	sughosh.ganu, u-boot, u-boot-qcom

Hi Varadarajan,

On 2026-04-16T05:39:18, Varadarajan Narayanan
<varadarajan.narayanan@oss.qualcomm.com> wrote:
> mach-snapdragon: Add commands to create wrapper ELF
>
> The IPQ5210 boot ROM expects the SPL binary image to be embedded within
> an ELF along with additional binaries. Hence add the relevant commands
> and linker script needed to convert u-boot-spl.bin to the expected
> format.
>
> Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
>
> arch/arm/mach-snapdragon/Kconfig                  |  7 +++++++
>  arch/arm/mach-snapdragon/ipq5210-spl-wrap-elf.lds | 18 +++++++++++++++++
>  scripts/Makefile.xpl                              | 24 +++++++++++++++++++++++
>  3 files changed, 49 insertions(+)

> +ifeq ($(CONFIG_ARCH_SNAPDRAGON),y)
> +INPUTS-$(CONFIG_SPL_WRAPPER_ELF) += spl/u-boot-spl.wrap-elf
> +endif

Please can you use $(obj)/$(SPL_BIN).wrap-elf here to follow the
convention used elsewhere in this file. The hardcoded path would break
out-of-tree builds.

> +/*
> + * SPDX-License-Identifier: GPL-2.0

U-Boot convention for new files is GPL-2.0+ - is that OK, or do you need 2.0 ?

Regards,
Simon

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 10/10] doc: board/qualcomm: Update RDP build instructions
  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
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2026-04-16 20:54 UTC (permalink / raw)
  To: varadarajan.narayanan
  Cc: rayagonda.kokatanur, trini, casey.connolly, neil.armstrong,
	sumit.garg, peng.fan, jh80.chung, lukma, tien.fong.chee,
	tingting.meng, anshuld, alif.zakuan.yuslaimi, alice.guo,
	quentin.schulz, ilias.apalodimas, sjg, mkorpershoek, h-salunke,
	alchark, dario.binacchi, ye.li, andre.przywara, dinesh.maniyam,
	luca.weiss, danila, aswin.murugan, balaji.selvanathan, adrian,
	n-francis, wens, jamie.gibbons, justin, ycliang, david.wronek,
	james.hilliard1, richard.genoud, michael, philip.molloy,
	sughosh.ganu, u-boot, u-boot-qcom

Hi Varadarajan,

On 2026-04-16T05:39:18, Varadarajan Narayanan
<varadarajan.narayanan@oss.qualcomm.com> wrote:
> doc: board/qualcomm: Update RDP build instructions
>
> Add details about the SPL & U-Boot proper build steps, converting to
> flashable images, source URLs for the needed binaries and scripts.
>
> Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
>
> doc/board/qualcomm/rdp.rst | 70 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 70 insertions(+)

> +.. _create_multielf.py: https://raw.githubusercontent.com/coreboot/coreboot/refs/heads/main/util/qualcomm/create_multielf.py
> +.. _gen_its.py: https://git.codelinaro.org/clo/qsdk/oss/system/tools/meta/-/tree/win.platform_tools.1.0.r34/scripts?ref_type=heads
> +.. _libqtisec_dbg.a: https://softwarecenter.qualcomm.com/nexus/generic/product/chip/software-product/IPQ5210.NLQ.14.0/ipq5210.nlq.14.0-qca-oem-qartifact/r00036.1/WIN.TFA.1.0.R4/apss_proc/out/proprietary/qtiseclib/output/ipq52xx/release/libqtisec_dbg.a
> +.. _OPTEE: ...
> +.. _qc_config.elf: ...
> +.. _QCLib.elf: ...
> +.. _template.its: ...
> +.. _TFA: ...
> +.. _tmel-ipq52xx-patch.elf: ...

These link definitions are not referenced in the document body -
please can you add the references in the text?

Regards,
Simon

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 06/10] mach-snapdragon: Add initial support for IPQ5210 SPL
  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
  1 sibling, 0 replies; 19+ messages in thread
From: Balaji Selvanathan @ 2026-04-17  4:22 UTC (permalink / raw)
  To: Varadarajan Narayanan, rayagonda.kokatanur, trini, casey.connolly,
	neil.armstrong, sumit.garg, peng.fan, jh80.chung, lukma,
	tien.fong.chee, tingting.meng, anshuld, alif.zakuan.yuslaimi,
	alice.guo, quentin.schulz, ilias.apalodimas, sjg, mkorpershoek,
	h-salunke, alchark, dario.binacchi, ye.li, andre.przywara,
	dinesh.maniyam, luca.weiss, danila, aswin.murugan, adrian,
	n-francis, wens, jamie.gibbons, justin, ycliang, david.wronek,
	james.hilliard1, richard.genoud, michael, philip.molloy,
	sughosh.ganu, u-boot, u-boot-qcom

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'"
> +	 */
> +}

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2026-04-17 12:47 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox