U-Boot Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support
@ 2026-06-01  8:12 Sam Day via B4 Relay
  2026-06-01  8:12 ` [PATCH RESEND 01/16] serial: msm: UARTDM <1.4 support Sam Day via B4 Relay
                   ` (17 more replies)
  0 siblings, 18 replies; 26+ messages in thread
From: Sam Day via B4 Relay @ 2026-06-01  8:12 UTC (permalink / raw)
  To: Sumit Garg, u-boot-qcom, u-boot
  Cc: Casey Connolly, Neil Armstrong, Tom Rini, Stephan Gerhold,
	Michal Simek, Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu,
	Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel, Sam Day

** Resending because I found new ways to dislike Proton Mail (it failed
the series midway due to "spamming". Sigh.). **

This patch series introduces support for ARMv7 Qualcomm SoCs, starting
with MSM8960/MSM8930/MSM8227.

An overview of the changes:
 * serial_msm reintroduces the previous packed RX/TX software mode
   operation, as this is compatible with all UARTDM versions (1.4 and
   older). It's added alongside the newer single-char mode for 1.4.
 * A timer driver is introduced for KPSS. I don't know if *all* ARMv7
   qcom SoCs lack generic ARM CP15 debug timer support, but at least
   MSM8960/MSM8930 do.
 * mach-snapdragon board code is shuffled around a bit to build cleanly
   on ARM64.
 * prev_bl_data support is extended to ARM32 (which uses r2 for passing
   FDT/ATAGS pointers, rather than r0)
 * qcom_parse_memory is revised to support arm32 memory nodes (which are
   1-cell rather than 2-cell).
 * Basic ATAGS support is introduced, so that the memory info can be
   used from previous bootloaders that do not understand FDTs at all.
 * PS_HOLD sysreset and pinctrl-qcom needed some minor tweaks to handle
   some nuances that challenge the current assumptions.
 * A pinctrl driver is introduced for MSM8960.
 * Initial MSM8960 GCC infra is introduced.

I tested this series on:
 * Nokia Lumia 520 (msm8227). No working buttons yet as these are
   exposed as GPIO-over-PMIC-over-SSBI (drivers will be proposed at a
   later date).
 * Samsung Galaxy Express GT-I8730 (msm8930). Volume rockers + home
   button are working via the new pinctrl-msm8960 driver. Power
   button not working yet (needs PMIC driver infra).
 * I have no msm8960/apq8064 devices, looking for folks to test those.

To confirm there was no regressions with ARM64 and/or newer devices, I
also tested on:
 * db410c (msm8916)
 * google-sargo (sdm670)

Signed-off-by: Sam Day <me@samcday.com>
---
Sam Day (16):
      serial: msm: UARTDM <1.4 support
      timer: Qualcomm KPSS timer support
      arm: save_prev_bl_data: ARM32 support
      mach-snapdragon: qcom_parse_memory 32-bit support
      mach-snapdragon: gate ARM64 features
      mach-snapdragon: introduce ARCH_SNAPDRAGON_ARM32
      configs: introduce qcom_armv7_defconfig
      board: qualcomm: add MSM8960 debug UART config
      sysreset: qcom-pshold: offset support
      pinctrl: qcom: configurable GPIO offset/stride
      pinctrl: qcom: introduce MSM8960 driver
      mach-snapdragon: parse incoming ARM32 ATAGS
      clk: qcom: MSM8960 GCC driver
      clk: qcom: arch-agnostic pointer fmtstrings
      serial: msm: wait for TX empty before reinit
      button: remap phone HOMEPAGE button

 arch/arm/Kconfig                             |  11 +-
 arch/arm/lib/save_prev_bl_data.c             |  49 ++++---
 arch/arm/mach-snapdragon/Kconfig             |   6 +
 arch/arm/mach-snapdragon/board.c             | 188 ++++++++++++++++++--------
 arch/arm/mach-snapdragon/include/mach/gpio.h |  12 +-
 board/qualcomm/debug-msm8960.config          |   5 +
 configs/qcom_armv7_defconfig                 |  61 +++++++++
 drivers/button/Kconfig                       |   2 +-
 drivers/button/button-uclass.c               |   1 +
 drivers/clk/qcom/Kconfig                     |   8 ++
 drivers/clk/qcom/Makefile                    |   1 +
 drivers/clk/qcom/clock-msm8960.c             | 189 +++++++++++++++++++++++++++
 drivers/clk/qcom/clock-qcom.c                |   8 +-
 drivers/gpio/msm_gpio.c                      |   2 +-
 drivers/pinctrl/qcom/Kconfig                 |   9 ++
 drivers/pinctrl/qcom/Makefile                |   1 +
 drivers/pinctrl/qcom/pinctrl-msm8960.c       | 135 +++++++++++++++++++
 drivers/pinctrl/qcom/pinctrl-qcom.c          |   2 +-
 drivers/serial/serial_msm.c                  | 142 +++++++++++++++++---
 drivers/sysreset/sysreset_qcom-pshold.c      |   9 +-
 drivers/timer/Kconfig                        |   7 +
 drivers/timer/Makefile                       |   1 +
 drivers/timer/qcom-kpss-timer.c              |  98 ++++++++++++++
 23 files changed, 843 insertions(+), 104 deletions(-)
---
base-commit: 8d3ba3753bdb5068884196ff696cc48177bfdda5
change-id: 20260530-qcom-armv7-1486308a835c

Best regards,
-- 
Sam Day <me@samcday.com>



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

* [PATCH RESEND 01/16] serial: msm: UARTDM <1.4 support
  2026-06-01  8:12 [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Sam Day via B4 Relay
@ 2026-06-01  8:12 ` Sam Day via B4 Relay
  2026-06-01  8:12 ` [PATCH RESEND 02/16] timer: Qualcomm KPSS timer support Sam Day via B4 Relay
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Sam Day via B4 Relay @ 2026-06-01  8:12 UTC (permalink / raw)
  To: Sumit Garg, u-boot-qcom, u-boot
  Cc: Casey Connolly, Neil Armstrong, Tom Rini, Stephan Gerhold,
	Michal Simek, Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu,
	Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel, Sam Day

From: Sam Day <me@samcday.com>

Prior to ff701837850e, this driver already operated in the packed FIFO
mode that is supported by all UARTDM versions. In order to work around
longstanding issues with the RX path, it was switched to the simpler
"single char mode", which avoids the necessary CMD_FORCE_STALE usage
that a non-IRQ polled environment like U-Boot requires.

Interestingly, the previous iteration of this driver would already have
worked on older UARTDM versions, except it was referencing the newer 1.4
register layout. The older register layout is supported by *all* UARTDM
versions, so in addition to restoring the packed mode behaviour, the
registers are switched up a bit.

I spoke with Stephan Gerhold about this at length and we decided that,
to ensure there's zero risk of re-introducing the previous issue, we'll
maintain both modes, preferring single-char for 1.4 peripherals, and
packed mode for everything else. This ensures we don't regress the
autoboot behaviour of db410c.

Signed-off-by: Sam Day <me@samcday.com>
---
 drivers/serial/serial_msm.c | 140 +++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 124 insertions(+), 16 deletions(-)

diff --git a/drivers/serial/serial_msm.c b/drivers/serial/serial_msm.c
index 18d15b7b15b..10948e2aede 100644
--- a/drivers/serial/serial_msm.c
+++ b/drivers/serial/serial_msm.c
@@ -23,7 +23,12 @@
 
 #define UARTDM_DMEN			0x3C /* DMA/data-packing mode */
 #define UARTDM_DMEN_TXRX_SC_ENABLE	(BIT(4) | BIT(5))
+#define UARTDM_DMRX             0x34 /* Max RX transfer length */
+#define UARTDM_NCF_TX           0x40 /* Number of chars to TX */
 
+#define UARTDM_RXFS             0x50 /* RX channel status register */
+#define UARTDM_RXFS_BUF_SHIFT   0x7  /* Number of bytes in the packing buffer */
+#define UARTDM_RXFS_BUF_MASK    0x7
 #define UARTDM_MR1				 0x00
 #define UARTDM_MR1_RX_RDY_CTL			 BIT(7)
 #define UARTDM_MR2				 0x04
@@ -38,18 +43,30 @@
  * The baud rate is the core clock frequency divided by the fixed divider value
  * programmed into this register (defined in calc_csr_bitrate()).
  */
-#define UARTDM_CSR				 0xA0
+#define UARTDM_CSR				 0x08
 
-#define UARTDM_SR                0xA4 /* Status register */
+#define UARTDM_SR                0x08 /* Status register */
 #define UARTDM_SR_RX_READY       (1 << 0) /* Receiver FIFO has data */
 #define UARTDM_SR_TX_READY       (1 << 2) /* Transmitter FIFO has space */
 #define UARTDM_SR_TX_EMPTY       (1 << 3) /* Transmitter underrun */
+#define UARTDM_SR_UART_OVERRUN   (1 << 4) /* Receive overrun */
 
-#define UARTDM_CR                         0xA8 /* Command register */
+#define UARTDM_CR                         0x10 /* Command register */
 #define UARTDM_CR_RX_ENABLE               (1 << 0) /* Enable receiver */
 #define UARTDM_CR_TX_ENABLE               (1 << 2) /* Enable transmitter */
 #define UARTDM_CR_CMD_RESET_RX            (1 << 4) /* Reset receiver */
 #define UARTDM_CR_CMD_RESET_TX            (2 << 4) /* Reset transmitter */
+#define UARTDM_CR_CMD_RESET_ERR           (3 << 4) /* Clear overrun error */
+#define UARTDM_CR_CMD_RESET_STALE_INT     (8 << 4) /* Clears stale irq */
+#define UARTDM_CR_CMD_RESET_TX_READY      (3 << 8) /* Clears TX Ready irq*/
+#define UARTDM_CR_CMD_FORCE_STALE         (4 << 8) /* Causes stale event */
+#define UARTDM_CR_CMD_STALE_EVENT_DISABLE (6 << 8) /* Disable stale event */
+
+#define UARTDM_IMR                0x14 /* Interrupt mask register */
+#define UARTDM_ISR                0x14 /* Interrupt status register */
+#define UARTDM_ISR_TX_READY       0x80 /* TX FIFO empty */
+
+#define MSM_UART_TF_RF		  0x70
 
 #define UARTDM_TF               0x100 /* UART Transmit FIFO register */
 #define UARTDM_RF               0x140 /* UART Receive FIFO register */
@@ -59,27 +76,97 @@ DECLARE_GLOBAL_DATA_PTR;
 
 struct msm_serial_data {
 	phys_addr_t base;
+	u32 chars_cnt; /* number of buffered chars */
+	u32 chars_buf; /* buffered chars */
 	uint32_t clk_rate; /* core clock rate */
+	bool single_char;
 };
 
+static int msm_serial_fetch(struct udevice *dev)
+{
+	struct msm_serial_data *priv = dev_get_priv(dev);
+	u32 sr;
+
+	if (priv->chars_cnt)
+		return priv->chars_cnt;
+
+	/* Clear error in case of buffer overrun */
+	if (readl(priv->base + UARTDM_SR) & UARTDM_SR_UART_OVERRUN)
+		writel(UARTDM_CR_CMD_RESET_ERR, priv->base + UARTDM_CR);
+
+	/* We need to fetch new character */
+	sr = readl(priv->base + UARTDM_SR);
+
+	if (sr & UARTDM_SR_RX_READY) {
+		/* There are at least 4 bytes in fifo */
+		priv->chars_buf = readl(priv->base + MSM_UART_TF_RF);
+		priv->chars_cnt = 4;
+	} else {
+		/* Check if there is anything in fifo */
+		priv->chars_cnt = readl(priv->base + UARTDM_RXFS);
+		/* Extract number of characters in UART packing buffer*/
+		priv->chars_cnt = (priv->chars_cnt >>
+				   UARTDM_RXFS_BUF_SHIFT) &
+				  UARTDM_RXFS_BUF_MASK;
+		if (!priv->chars_cnt)
+			return 0;
+
+		/* There is at least one character, move it to fifo */
+		writel(UARTDM_CR_CMD_FORCE_STALE,
+		       priv->base + UARTDM_CR);
+
+		priv->chars_buf = readl(priv->base + MSM_UART_TF_RF);
+		writel(UARTDM_CR_CMD_RESET_STALE_INT,
+		       priv->base + UARTDM_CR);
+		writel(0x7, priv->base + UARTDM_DMRX);
+	}
+
+	return priv->chars_cnt;
+}
+
 static int msm_serial_getc(struct udevice *dev)
 {
 	struct msm_serial_data *priv = dev_get_priv(dev);
+	char c;
+
+	if (priv->single_char) {
+		if (!(readl(priv->base + UARTDM_SR) & UARTDM_SR_RX_READY))
+			return -EAGAIN;
+
+		return readl(priv->base + UARTDM_RF) & UARTDM_RF_CHAR;
+	}
 
-	if (!(readl(priv->base + UARTDM_SR) & UARTDM_SR_RX_READY))
+	if (!msm_serial_fetch(dev))
 		return -EAGAIN;
 
-	return readl(priv->base + UARTDM_RF) & UARTDM_RF_CHAR;
+	c = priv->chars_buf & 0xFF;
+	priv->chars_buf >>= 8;
+	priv->chars_cnt--;
+
+	return c;
 }
 
 static int msm_serial_putc(struct udevice *dev, const char ch)
 {
 	struct msm_serial_data *priv = dev_get_priv(dev);
 
-	if (!(readl(priv->base + UARTDM_SR) & UARTDM_SR_TX_READY))
+	if (priv->single_char) {
+		if (!(readl(priv->base + UARTDM_SR) & UARTDM_SR_TX_READY))
+			return -EAGAIN;
+
+		writel(ch, priv->base + UARTDM_TF);
+		return 0;
+	}
+
+	if (!(readl(priv->base + UARTDM_SR) & UARTDM_SR_TX_EMPTY) &&
+	    !(readl(priv->base + UARTDM_ISR) & UARTDM_ISR_TX_READY))
 		return -EAGAIN;
 
-	writel(ch, priv->base + UARTDM_TF);
+	writel(UARTDM_CR_CMD_RESET_TX_READY, priv->base + UARTDM_CR);
+
+	writel(1, priv->base + UARTDM_NCF_TX);
+	writel(ch, priv->base + MSM_UART_TF_RF);
+
 	return 0;
 }
 
@@ -87,10 +174,21 @@ static int msm_serial_pending(struct udevice *dev, bool input)
 {
 	struct msm_serial_data *priv = dev_get_priv(dev);
 
-	if (input)
-		return !!(readl(priv->base + UARTDM_SR) & UARTDM_SR_RX_READY);
-	else
-		return !(readl(priv->base + UARTDM_SR) & UARTDM_SR_TX_EMPTY);
+	if (priv->single_char) {
+		if (input)
+			return !!(readl(priv->base + UARTDM_SR) &
+				  UARTDM_SR_RX_READY);
+		else
+			return !(readl(priv->base + UARTDM_SR) &
+				 UARTDM_SR_TX_EMPTY);
+	}
+
+	if (input) {
+		if (msm_serial_fetch(dev))
+			return 1;
+	}
+
+	return 0;
 }
 
 static const struct dm_serial_ops msm_serial_ops = {
@@ -156,8 +254,12 @@ static void uart_dm_init(struct msm_serial_data *priv)
 	writel(UARTDM_MR1_RX_RDY_CTL, priv->base + UARTDM_MR1);
 	writel(UARTDM_MR2_8_N_1_MODE, priv->base + UARTDM_MR2);
 
-	/* Enable single character mode */
-	writel(UARTDM_DMEN_TXRX_SC_ENABLE, priv->base + UARTDM_DMEN);
+	if (priv->single_char)
+		/* Enable single character mode */
+		writel(UARTDM_DMEN_TXRX_SC_ENABLE, priv->base + UARTDM_DMEN);
+	else
+		/* Make sure BAM/single character mode is disabled */
+		writel(0x0, priv->base + UARTDM_DMEN);
 
 	writel(UARTDM_CR_CMD_RESET_RX, priv->base + UARTDM_CR);
 	writel(UARTDM_CR_CMD_RESET_TX, priv->base + UARTDM_CR);
@@ -200,6 +302,8 @@ static int msm_serial_of_to_plat(struct udevice *dev)
 	if (priv->base == FDT_ADDR_T_NONE)
 		return -EINVAL;
 
+	priv->single_char = device_is_compatible(dev, "qcom,msm-uartdm-v1.4");
+
 	ret = dev_read_u32(dev, "clock-frequency", &priv->clk_rate);
 	if (ret < 0) {
 		log_debug("No clock frequency specified, using default rate\n");
@@ -211,7 +315,7 @@ static int msm_serial_of_to_plat(struct udevice *dev)
 }
 
 static const struct udevice_id msm_serial_ids[] = {
-	{ .compatible = "qcom,msm-uartdm-v1.4" },
+	{ .compatible = "qcom,msm-uartdm" },
 	{ }
 };
 
@@ -254,10 +358,14 @@ static inline void _debug_uart_putc(int ch)
 {
 	struct msm_serial_data *priv = &init_serial_data;
 
-	while (!(readl(priv->base + UARTDM_SR) & UARTDM_SR_TX_READY))
+	while (!(readl(priv->base + UARTDM_SR) & UARTDM_SR_TX_EMPTY) &&
+	       !(readl(priv->base + UARTDM_ISR) & UARTDM_ISR_TX_READY))
 		;
 
-	writel(ch, priv->base + UARTDM_TF);
+	writel(UARTDM_CR_CMD_RESET_TX_READY, priv->base + UARTDM_CR);
+
+	writel(1, priv->base + UARTDM_NCF_TX);
+	writel(ch, priv->base + MSM_UART_TF_RF);
 }
 
 DEBUG_UART_FUNCS

-- 
2.54.0



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

* [PATCH RESEND 02/16] timer: Qualcomm KPSS timer support
  2026-06-01  8:12 [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Sam Day via B4 Relay
  2026-06-01  8:12 ` [PATCH RESEND 01/16] serial: msm: UARTDM <1.4 support Sam Day via B4 Relay
@ 2026-06-01  8:12 ` Sam Day via B4 Relay
  2026-06-01  8:12 ` [PATCH RESEND 03/16] arm: save_prev_bl_data: ARM32 support Sam Day via B4 Relay
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Sam Day via B4 Relay @ 2026-06-01  8:12 UTC (permalink / raw)
  To: Sumit Garg, u-boot-qcom, u-boot
  Cc: Casey Connolly, Neil Armstrong, Tom Rini, Stephan Gerhold,
	Michal Simek, Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu,
	Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel, Sam Day

From: Sam Day <me@samcday.com>

SoCs like MSM8960 and APQ8064 do not support the generic ARM CP15 timer.
Instead KPSS must be used as a timer source.

Signed-off-by: Sam Day <me@samcday.com>
---
 drivers/timer/Kconfig           |  7 +++
 drivers/timer/Makefile          |  1 +
 drivers/timer/qcom-kpss-timer.c | 98 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 106 insertions(+)

diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index 500a25638a9..8de8ce6c14a 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -223,6 +223,13 @@ config ORION_TIMER
 	  Select this to enable an timer for Orion and Armada devices
 	  like Armada XP etc.
 
+config QCOM_KPSS_TIMER
+	bool "Qualcomm KPSS/SCSS timer support"
+	depends on TIMER && ARM
+	help
+	  Select this to enable the Qualcomm KPSS/SCSS digital general
+	  purpose timer used on older 32-bit Snapdragon SoCs.
+
 config RISCV_TIMER
 	bool "RISC-V timer support"
 	depends on TIMER && RISCV
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index d8b3f2b65d4..3bd167d73c2 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_NOMADIK_MTU_TIMER)	+= nomadik-mtu-timer.o
 obj-$(CONFIG_NPCM_TIMER)        += npcm-timer.o
 obj-$(CONFIG_OMAP_TIMER)	+= omap-timer.o
 obj-$(CONFIG_ORION_TIMER)	+= orion-timer.o
+obj-$(CONFIG_QCOM_KPSS_TIMER)	+= qcom-kpss-timer.o
 obj-$(CONFIG_RENESAS_OSTM_TIMER) += ostm_timer.o
 obj-$(CONFIG_RISCV_TIMER) += riscv_timer.o
 obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o
diff --git a/drivers/timer/qcom-kpss-timer.c b/drivers/timer/qcom-kpss-timer.c
new file mode 100644
index 00000000000..543fb2fa44f
--- /dev/null
+++ b/drivers/timer/qcom-kpss-timer.c
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Qualcomm KPSS/SCSS timer driver
+ * Adapted from Linux drivers/clocksource/timer-qcom.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2009-2012,2014, The Linux Foundation. All rights reserved.
+ */
+
+#include <dm.h>
+#include <div64.h>
+#include <errno.h>
+#include <timer.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define TIMER_COUNT_VAL   0x04
+#define TIMER_ENABLE      0x08
+#define TIMER_ENABLE_EN   BIT(0)
+#define DGT_CLK_CTL       0x10
+#define DGT_CLK_CTL_DIV_4 0x3
+
+#define QCOM_TIMER_DGT_OFFSET   0x24
+#define QCOM_TIMER_DGT_RATE_DIV 4
+
+struct qcom_kpss_timer_priv {
+	void __iomem *source_base;
+	void __iomem *counter;
+};
+
+static u64 notrace qcom_kpss_timer_get_count(struct udevice *dev)
+{
+	struct qcom_kpss_timer_priv *priv = dev_get_priv(dev);
+
+	return timer_conv_64(readl(priv->counter));
+}
+
+static int qcom_kpss_timer_probe(struct udevice *dev)
+{
+	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct qcom_kpss_timer_priv *priv = dev_get_priv(dev);
+	u32 rate;
+	int ret;
+
+	ret = dev_read_u32(dev, "clock-frequency", &rate);
+	if (ret)
+		return ret;
+
+	uc_priv->clock_rate = rate / QCOM_TIMER_DGT_RATE_DIV;
+
+	writel(DGT_CLK_CTL_DIV_4, priv->source_base + DGT_CLK_CTL);
+	writel(TIMER_ENABLE_EN, priv->source_base + TIMER_ENABLE);
+
+	return 0;
+}
+
+static int qcom_kpss_timer_of_to_plat(struct udevice *dev)
+{
+	struct qcom_kpss_timer_priv *priv = dev_get_priv(dev);
+	phys_addr_t base;
+	phys_addr_t source_base;
+	u32 cpu_offset;
+
+	base = dev_read_addr(dev);
+	if (base == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	cpu_offset = dev_read_u32_default(dev, "cpu-offset", 0);
+	source_base = base + cpu_offset + QCOM_TIMER_DGT_OFFSET;
+	priv->source_base = map_physmem(source_base, 0x100, MAP_NOCACHE);
+	priv->counter = priv->source_base + TIMER_COUNT_VAL;
+
+	return 0;
+}
+
+static const struct timer_ops qcom_kpss_timer_ops = {
+	.get_count = qcom_kpss_timer_get_count,
+};
+
+static const struct udevice_id qcom_kpss_timer_ids[] = {
+	{ .compatible = "qcom,kpss-timer" },
+	{ .compatible = "qcom,scss-timer" },
+	{ }
+};
+
+U_BOOT_DRIVER(qcom_kpss_timer) = {
+	.name		= "qcom_kpss_timer",
+	.id		= UCLASS_TIMER,
+	.of_match	= qcom_kpss_timer_ids,
+	.of_to_plat	= qcom_kpss_timer_of_to_plat,
+	.probe		= qcom_kpss_timer_probe,
+	.ops		= &qcom_kpss_timer_ops,
+	.priv_auto	= sizeof(struct qcom_kpss_timer_priv),
+	.flags		= DM_FLAG_PRE_RELOC,
+};

-- 
2.54.0



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

* [PATCH RESEND 03/16] arm: save_prev_bl_data: ARM32 support
  2026-06-01  8:12 [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Sam Day via B4 Relay
  2026-06-01  8:12 ` [PATCH RESEND 01/16] serial: msm: UARTDM <1.4 support Sam Day via B4 Relay
  2026-06-01  8:12 ` [PATCH RESEND 02/16] timer: Qualcomm KPSS timer support Sam Day via B4 Relay
@ 2026-06-01  8:12 ` Sam Day via B4 Relay
  2026-06-01  8:12 ` [PATCH RESEND 04/16] mach-snapdragon: qcom_parse_memory 32-bit support Sam Day via B4 Relay
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Sam Day via B4 Relay @ 2026-06-01  8:12 UTC (permalink / raw)
  To: Sumit Garg, u-boot-qcom, u-boot
  Cc: Casey Connolly, Neil Armstrong, Tom Rini, Stephan Gerhold,
	Michal Simek, Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu,
	Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel, Sam Day

From: Sam Day <me@samcday.com>

The main change here is to make is_addr_accessible() portable, by using
gd->bd->bi_ram rather than the ARMv8 memory map. AFAICT, at the point
that this is running, these two things are 1:1 anyway (see
qcom_configure_bi_dram).

Once that's out of the way, we add ARM32 support by looking at r2 rather
than r0 and using portable pointer types.

Signed-off-by: Sam Day <me@samcday.com>
---
 arch/arm/lib/save_prev_bl_data.c | 49 ++++++++++++++++++++++++----------------
 1 file changed, 29 insertions(+), 20 deletions(-)

diff --git a/arch/arm/lib/save_prev_bl_data.c b/arch/arm/lib/save_prev_bl_data.c
index 4357acaef6c..83670541c50 100644
--- a/arch/arm/lib/save_prev_bl_data.c
+++ b/arch/arm/lib/save_prev_bl_data.c
@@ -12,33 +12,41 @@
 #include <fdt.h>
 #include <linux/errno.h>
 #include <asm/system.h>
-#include <asm/armv8/mmu.h>
 
-static ulong reg0 __section(".data");
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static phys_addr_t prev_bl_fdt_addr __section(".data");
 
 /**
- * Save x0 register value, assuming previous bootloader set it to
- * point on loaded fdt or (for older linux kernels)atags.
+ * Save the register value used by Linux boot ABI to pass the FDT or ATAGS.
  */
-void save_boot_params(ulong r0)
+void save_boot_params(ulong r0, ulong __always_unused r1, ulong r2)
 {
-	reg0 = r0;
+	if (IS_ENABLED(CONFIG_ARM64))
+		prev_bl_fdt_addr = r0;
+	else
+		prev_bl_fdt_addr = r2;
+
 	save_boot_params_ret();
 }
 
 bool is_addr_accessible(phys_addr_t addr)
 {
-	struct mm_region *mem = mem_map;
 	phys_addr_t bank_start;
 	phys_addr_t bank_end;
 
-	while (mem->size) {
-		bank_start = mem->phys;
-		bank_end = bank_start + mem->size;
-		debug("check if block %pap - %pap includes %pap\n", &bank_start, &bank_end, &addr);
-		if (addr > bank_start && addr < bank_end)
+	for (int i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		if (!gd->bd->bi_dram[i].size)
+			continue;
+
+		bank_start = gd->bd->bi_dram[i].start;
+		bank_end = bank_start + gd->bd->bi_dram[i].size;
+		debug("check if block %pap - %pap includes %pap\n",
+		      &bank_start, &bank_end, &addr);
+		if (addr >= bank_start && addr < bank_end)
 			return true;
-		mem++;
 	}
 
 	return false;
@@ -46,33 +54,34 @@ bool is_addr_accessible(phys_addr_t addr)
 
 phys_addr_t get_prev_bl_fdt_addr(void)
 {
-	return reg0;
+	return prev_bl_fdt_addr;
 }
 
 int save_prev_bl_data(void)
 {
 	struct fdt_header *fdt_blob;
 	int node;
-	u64 initrd_start_prop;
+	phys_addr_t initrd_start_prop;
 
-	if (!is_addr_accessible((phys_addr_t)reg0))
+	if (!is_addr_accessible(prev_bl_fdt_addr))
 		return -ENODATA;
 
-	fdt_blob = (struct fdt_header *)reg0;
+	fdt_blob = (struct fdt_header *)prev_bl_fdt_addr;
 	if (!fdt_valid(&fdt_blob)) {
-		pr_warn("%s: address 0x%lx is not a valid fdt\n", __func__, reg0);
+		pr_warn("%s: address 0x%lx is not a valid fdt\n",
+			__func__, prev_bl_fdt_addr);
 		return -ENODATA;
 	}
 
 	if (IS_ENABLED(CONFIG_SAVE_PREV_BL_FDT_ADDR))
-		env_set_addr("prevbl_fdt_addr", (void *)reg0);
+		env_set_addr("prevbl_fdt_addr", (const void *)prev_bl_fdt_addr);
 	if (!IS_ENABLED(CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR))
 		return 0;
 
 	node = fdt_path_offset(fdt_blob, "/chosen");
 	if (!node) {
 		pr_warn("%s: chosen node not found in device tree at addr: 0x%lx\n",
-					__func__, reg0);
+					__func__, prev_bl_fdt_addr);
 		return -ENODATA;
 	}
 	/*

-- 
2.54.0



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

* [PATCH RESEND 04/16] mach-snapdragon: qcom_parse_memory 32-bit support
  2026-06-01  8:12 [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Sam Day via B4 Relay
                   ` (2 preceding siblings ...)
  2026-06-01  8:12 ` [PATCH RESEND 03/16] arm: save_prev_bl_data: ARM32 support Sam Day via B4 Relay
@ 2026-06-01  8:12 ` Sam Day via B4 Relay
  2026-06-01  8:12 ` [PATCH RESEND 05/16] mach-snapdragon: gate ARM64 features Sam Day via B4 Relay
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Sam Day via B4 Relay @ 2026-06-01  8:12 UTC (permalink / raw)
  To: Sumit Garg, u-boot-qcom, u-boot
  Cc: Casey Connolly, Neil Armstrong, Tom Rini, Stephan Gerhold,
	Michal Simek, Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu,
	Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel, Sam Day

From: Sam Day <me@samcday.com>

qcom_parse_memory is updated to handle varying address/size cell counts,
rather than assuming a count of 2 (64 bit). This means it can now parse
/memory nodes in both arm64 and arm32 devicetrees.

Signed-off-by: Sam Day <me@samcday.com>
---
 arch/arm/mach-snapdragon/board.c | 42 ++++++++++++++++++++++++++--------------
 1 file changed, 28 insertions(+), 14 deletions(-)

diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
index 829a0109ac7..56e943058ed 100644
--- a/arch/arm/mach-snapdragon/board.c
+++ b/arch/arm/mach-snapdragon/board.c
@@ -115,8 +115,9 @@ int dram_init_banksize(void)
 static int qcom_parse_memory(const void *fdt)
 {
 	int offset;
-	const fdt64_t *memory;
+	const fdt32_t *memory;
 	int memsize;
+	int parent, addr_cells, size_cells, entry_cells;
 	phys_addr_t ram_end = 0;
 	int i, j, banks;
 
@@ -124,33 +125,46 @@ static int qcom_parse_memory(const void *fdt)
 	if (offset < 0)
 		return -ENODATA;
 
+	parent = fdt_parent_offset(fdt, offset);
+	if (parent < 0)
+		return -ENODATA;
+
+	addr_cells = fdt_address_cells(fdt, parent);
+	size_cells = fdt_size_cells(fdt, parent);
+	entry_cells = addr_cells + size_cells;
+	if (addr_cells <= 0 || size_cells <= 0)
+		return -ENODATA;
+
 	memory = fdt_getprop(fdt, offset, "reg", &memsize);
 	if (!memory)
 		return -ENODATA;
 
-	banks = min(memsize / (2 * sizeof(u64)), (ulong)CONFIG_NR_DRAM_BANKS);
-
-	if (memsize / sizeof(u64) > CONFIG_NR_DRAM_BANKS * 2)
-		log_err("Provided more than the max of %d memory banks\n", CONFIG_NR_DRAM_BANKS);
+	banks = min(memsize / (entry_cells * (int)sizeof(fdt32_t)),
+		    (int)CONFIG_NR_DRAM_BANKS);
 
 	if (banks > CONFIG_NR_DRAM_BANKS)
 		log_err("Provided more memory banks than we can handle\n");
 
-	for (i = 0, j = 0; i < banks * 2; i += 2, j++) {
-		prevbl_ddr_banks[j].start = get_unaligned_be64(&memory[i]);
-		prevbl_ddr_banks[j].size = get_unaligned_be64(&memory[i + 1]);
-		if (!prevbl_ddr_banks[j].size) {
-			j--;
+	for (i = 0, j = 0; i < banks; i++) {
+		phys_addr_t start = fdt_read_number(memory, addr_cells);
+		phys_size_t size = fdt_read_number(memory + addr_cells,
+						   size_cells);
+
+		memory += entry_cells;
+		if (!size)
 			continue;
-		}
-		ram_end = max(ram_end, prevbl_ddr_banks[j].start + prevbl_ddr_banks[j].size);
+
+		prevbl_ddr_banks[j].start = start;
+		prevbl_ddr_banks[j].size = size;
+		ram_end = max(ram_end, start + size);
+		j++;
 	}
 
-	if (!banks || !prevbl_ddr_banks[0].size)
+	if (!j)
 		return -ENODATA;
 
 	/* Sort our RAM banks -_- */
-	qsort(prevbl_ddr_banks, banks, sizeof(prevbl_ddr_banks[0]), ddr_bank_cmp);
+	qsort(prevbl_ddr_banks, j, sizeof(prevbl_ddr_banks[0]), ddr_bank_cmp);
 
 	gd->ram_base = prevbl_ddr_banks[0].start;
 	gd->ram_size = ram_end - gd->ram_base;

-- 
2.54.0



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

* [PATCH RESEND 05/16] mach-snapdragon: gate ARM64 features
  2026-06-01  8:12 [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Sam Day via B4 Relay
                   ` (3 preceding siblings ...)
  2026-06-01  8:12 ` [PATCH RESEND 04/16] mach-snapdragon: qcom_parse_memory 32-bit support Sam Day via B4 Relay
@ 2026-06-01  8:12 ` Sam Day via B4 Relay
  2026-06-01  8:12 ` [PATCH RESEND 06/16] mach-snapdragon: introduce ARCH_SNAPDRAGON_ARM32 Sam Day via B4 Relay
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Sam Day via B4 Relay @ 2026-06-01  8:12 UTC (permalink / raw)
  To: Sumit Garg, u-boot-qcom, u-boot
  Cc: Casey Connolly, Neil Armstrong, Tom Rini, Stephan Gerhold,
	Michal Simek, Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu,
	Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel, Sam Day

From: Sam Day <me@samcday.com>

With some strategic (and minimal) #ifdef ARM64 gating, we can ensure
that mach-snapdragon board code compiles cleanly on arm32 toolchains.

Signed-off-by: Sam Day <me@samcday.com>
---
 arch/arm/mach-snapdragon/board.c | 29 +++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
index 56e943058ed..627b566d178 100644
--- a/arch/arm/mach-snapdragon/board.c
+++ b/arch/arm/mach-snapdragon/board.c
@@ -9,10 +9,8 @@
 #define LOG_CATEGORY LOGC_BOARD
 #define pr_fmt(fmt) "QCOM: " fmt
 
-#include <asm/armv8/mmu.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
-#include <asm/psci.h>
 #include <asm/system.h>
 #include <dm/device.h>
 #include <dm/pinctrl.h>
@@ -22,9 +20,7 @@
 #include <env.h>
 #include <fdt_support.h>
 #include <init.h>
-#include <linux/arm-smccc.h>
 #include <linux/bug.h>
-#include <linux/psci.h>
 #include <linux/sizes.h>
 #include <lmb.h>
 #include <malloc.h>
@@ -35,13 +31,20 @@
 
 #include "qcom-priv.h"
 
-DECLARE_GLOBAL_DATA_PTR;
-
-enum qcom_boot_source qcom_boot_source __section(".data") = 0;
+#ifdef CONFIG_ARM64
+#include <asm/armv8/mmu.h>
+#include <asm/psci.h>
+#include <linux/arm-smccc.h>
+#include <linux/psci.h>
 
 static struct mm_region rbx_mem_map[CONFIG_NR_DRAM_BANKS + 2] = { { 0 } };
 
 struct mm_region *mem_map = rbx_mem_map;
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum qcom_boot_source qcom_boot_source __section(".data") = 0;
 
 static struct {
 	phys_addr_t start;
@@ -174,6 +177,7 @@ static int qcom_parse_memory(const void *fdt)
 
 static void show_psci_version(void)
 {
+#ifdef CONFIG_ARM64
 	struct arm_smccc_res res;
 
 	arm_smccc_smc(ARM_PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0, 0, 0, 0, 0, &res);
@@ -185,6 +189,7 @@ static void show_psci_version(void)
 	debug("PSCI:  v%ld.%ld\n",
 	      PSCI_VERSION_MAJOR(res.a0),
 	      PSCI_VERSION_MINOR(res.a0));
+#endif
 }
 
 /**
@@ -196,6 +201,7 @@ static void show_psci_version(void)
  */
 static void qcom_psci_fixup(void *fdt)
 {
+#ifdef CONFIG_ARM64
 	int offset, ret;
 	struct arm_smccc_res res;
 
@@ -212,6 +218,7 @@ static void qcom_psci_fixup(void *fdt)
 	ret = fdt_del_node(fdt, offset);
 	if (ret)
 		log_err("Failed to delete /psci node: %d\n", ret);
+#endif
 }
 
 /* We support booting U-Boot with an internal DT when running as a first-stage bootloader
@@ -234,8 +241,8 @@ int board_fdt_blob_setup(void **fdtp)
 	 * Bail out while we can still print a useful error message.
 	 */
 	if (!internal_valid && !external_valid)
-		panic("Internal FDT is invalid and no external FDT was provided! (fdt=%#llx)\n",
-		      (phys_addr_t)external_fdt);
+		panic("Internal FDT is invalid and no external FDT was provided! (fdt=%p)\n",
+		      external_fdt);
 
 	/* Prefer memory information from internal DT if it's present */
 	if (internal_valid)
@@ -261,7 +268,7 @@ int board_fdt_blob_setup(void **fdtp)
 		qcom_boot_source = QCOM_BOOT_SOURCE_XBL;
 
 	debug("ram_base = %#011lx, ram_size = %#011llx\n",
-	      gd->ram_base, gd->ram_size);
+	      gd->ram_base, (unsigned long long)gd->ram_size);
 
 	if (internal_valid) {
 		debug("Using built in FDT\n");
@@ -595,6 +602,7 @@ int board_late_init(void)
 	return 0;
 }
 
+#ifdef CONFIG_ARM64
 static void build_mem_map(void)
 {
 	int i, j;
@@ -768,3 +776,4 @@ void enable_caches(void)
 	}
 	dcache_enable();
 }
+#endif

-- 
2.54.0



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

* [PATCH RESEND 06/16] mach-snapdragon: introduce ARCH_SNAPDRAGON_ARM32
  2026-06-01  8:12 [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Sam Day via B4 Relay
                   ` (4 preceding siblings ...)
  2026-06-01  8:12 ` [PATCH RESEND 05/16] mach-snapdragon: gate ARM64 features Sam Day via B4 Relay
@ 2026-06-01  8:12 ` Sam Day via B4 Relay
  2026-06-01  8:12 ` [PATCH RESEND 07/16] configs: introduce qcom_armv7_defconfig Sam Day via B4 Relay
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Sam Day via B4 Relay @ 2026-06-01  8:12 UTC (permalink / raw)
  To: Sumit Garg, u-boot-qcom, u-boot
  Cc: Casey Connolly, Neil Armstrong, Tom Rini, Stephan Gerhold,
	Michal Simek, Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu,
	Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel, Sam Day

From: Sam Day <me@samcday.com>

This config symbol lays the groundwork for arm32 support in the
Snapdragon board code.

Signed-off-by: Sam Day <me@samcday.com>
---
 arch/arm/Kconfig                 | 11 ++++++-----
 arch/arm/mach-snapdragon/Kconfig |  6 ++++++
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 514bf2000b4..0847985a367 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1134,7 +1134,8 @@ config ARCH_RENESAS
 
 config ARCH_SNAPDRAGON
 	bool "Qualcomm Snapdragon SoCs"
-	select ARM64
+	select ARM64 if !ARCH_SNAPDRAGON_ARM32
+	select CPU_V7A if ARCH_SNAPDRAGON_ARM32
 	select DM
 	select DM_GPIO
 	select DM_SERIAL
@@ -1148,11 +1149,11 @@ config ARCH_SNAPDRAGON
 	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 LINUX_KERNEL_IMAGE_HEADER if ARM64 && !ENABLE_ARM_SOC_BOOT0_HOOK
 	select SYSRESET
-	select SYSRESET_PSCI
-	select ANDROID_BOOT_IMAGE_IGNORE_BLOB_ADDR
-	select MMU_PGPROT
+	select SYSRESET_PSCI if ARM64
+	select ANDROID_BOOT_IMAGE_IGNORE_BLOB_ADDR if ARM64
+	select MMU_PGPROT if ARM64
 	imply OF_UPSTREAM
 	imply CMD_DM
 	imply DM_USB_GADGET
diff --git a/arch/arm/mach-snapdragon/Kconfig b/arch/arm/mach-snapdragon/Kconfig
index d3de8693b5a..e663b0015c7 100644
--- a/arch/arm/mach-snapdragon/Kconfig
+++ b/arch/arm/mach-snapdragon/Kconfig
@@ -1,5 +1,11 @@
 if ARCH_SNAPDRAGON
 
+config ARCH_SNAPDRAGON_ARM32
+	bool "Build Snapdragon support for ARMv7-A SoCs"
+	help
+	  Enable this when building U-Boot for older 32-bit Snapdragon
+	  platforms, such as the MSM8960 family.
+
 config SYS_SOC
 	default "snapdragon"
 

-- 
2.54.0



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

* [PATCH RESEND 07/16] configs: introduce qcom_armv7_defconfig
  2026-06-01  8:12 [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Sam Day via B4 Relay
                   ` (5 preceding siblings ...)
  2026-06-01  8:12 ` [PATCH RESEND 06/16] mach-snapdragon: introduce ARCH_SNAPDRAGON_ARM32 Sam Day via B4 Relay
@ 2026-06-01  8:12 ` Sam Day via B4 Relay
  2026-06-01  8:12 ` [PATCH RESEND 08/16] board: qualcomm: add MSM8960 debug UART config Sam Day via B4 Relay
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Sam Day via B4 Relay @ 2026-06-01  8:12 UTC (permalink / raw)
  To: Sumit Garg, u-boot-qcom, u-boot
  Cc: Casey Connolly, Neil Armstrong, Tom Rini, Stephan Gerhold,
	Michal Simek, Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu,
	Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel, Sam Day

From: Sam Day <me@samcday.com>

This new config aims to be analogous to qcom_defconfig, but for armv7
devices. It can compose with qcom-phone.config.

Signed-off-by: Sam Day <me@samcday.com>
---
 configs/qcom_armv7_defconfig | 59 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/configs/qcom_armv7_defconfig b/configs/qcom_armv7_defconfig
new file mode 100644
index 00000000000..7d64ee68ecd
--- /dev/null
+++ b/configs/qcom_armv7_defconfig
@@ -0,0 +1,59 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_SYS_ICACHE_OFF=y
+CONFIG_SYS_DCACHE_OFF=y
+CONFIG_ARCH_SNAPDRAGON=y
+CONFIG_TEXT_BASE=0x80208000
+CONFIG_NR_DRAM_BANKS=24
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x88FE0000
+CONFIG_DEFAULT_DEVICE_TREE="qcom/qcom-msm8960-cdp"
+CONFIG_SYS_LOAD_ADDR=0x82000000
+CONFIG_ARCH_SNAPDRAGON_ARM32=y
+CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
+CONFIG_EFI_CAPSULE_ON_DISK=y
+CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
+# CONFIG_ANDROID_BOOT_IMAGE is not set
+CONFIG_BOOTSTD_FULL=y
+CONFIG_BOOTDELAY=1
+CONFIG_SYS_CBSIZE=512
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_CMD_BOOTMENU=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MEMINFO_MAP=y
+# CONFIG_CMD_BIND is not set
+CONFIG_CMD_CLK=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+CONFIG_CMD_CAT=y
+CONFIG_CMD_BMP=y
+CONFIG_CMD_LOG=y
+CONFIG_OF_UPSTREAM_BUILD_VENDOR=y
+CONFIG_ENV_USE_DEFAULT_ENV_TEXT_FILE=y
+CONFIG_ENV_DEFAULT_ENV_TEXT_FILE="board/qualcomm/default.env"
+CONFIG_CLK=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x0
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_MMC_USER_SUPPORT=y
+CONFIG_MSM_GPIO=y
+CONFIG_DM_KEYBOARD=y
+CONFIG_BUTTON_KEYBOARD=y
+CONFIG_PINCTRL=y
+CONFIG_MSM_SERIAL=y
+CONFIG_SYSRESET_QCOM_PSHOLD=y
+CONFIG_TIMER=y
+CONFIG_QCOM_KPSS_TIMER=y
+CONFIG_USB=y
+# CONFIG_DM_USB_GADGET is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_MSM=y
+CONFIG_USB_GADGET=y
+CONFIG_CI_UDC=y
+CONFIG_VIDEO=y
+CONFIG_SYS_WHITE_ON_BLACK=y
+CONFIG_NO_FB_CLEAR=y
+CONFIG_VIDEO_SIMPLE=y

-- 
2.54.0



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

* [PATCH RESEND 08/16] board: qualcomm: add MSM8960 debug UART config
  2026-06-01  8:12 [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Sam Day via B4 Relay
                   ` (6 preceding siblings ...)
  2026-06-01  8:12 ` [PATCH RESEND 07/16] configs: introduce qcom_armv7_defconfig Sam Day via B4 Relay
@ 2026-06-01  8:12 ` Sam Day via B4 Relay
  2026-06-01  8:12 ` [PATCH RESEND 09/16] sysreset: qcom-pshold: offset support Sam Day via B4 Relay
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Sam Day via B4 Relay @ 2026-06-01  8:12 UTC (permalink / raw)
  To: Sumit Garg, u-boot-qcom, u-boot
  Cc: Casey Connolly, Neil Armstrong, Tom Rini, Stephan Gerhold,
	Michal Simek, Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu,
	Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel, Sam Day

From: Sam Day <me@samcday.com>

UARTDM lives in the GSBI aperture for this SoC family.

Signed-off-by: Sam Day <me@samcday.com>
---
 board/qualcomm/debug-msm8960.config | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/board/qualcomm/debug-msm8960.config b/board/qualcomm/debug-msm8960.config
new file mode 100644
index 00000000000..f33f6b64920
--- /dev/null
+++ b/board/qualcomm/debug-msm8960.config
@@ -0,0 +1,5 @@
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEBUG_UART_BASE=0x16440000
+CONFIG_DEBUG_UART_MSM=y
+CONFIG_DEBUG_UART_CLOCK=1843200

-- 
2.54.0



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

* [PATCH RESEND 09/16] sysreset: qcom-pshold: offset support
  2026-06-01  8:12 [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Sam Day via B4 Relay
                   ` (7 preceding siblings ...)
  2026-06-01  8:12 ` [PATCH RESEND 08/16] board: qualcomm: add MSM8960 debug UART config Sam Day via B4 Relay
@ 2026-06-01  8:12 ` Sam Day via B4 Relay
  2026-06-01  8:12 ` [PATCH RESEND 10/16] pinctrl: qcom: configurable GPIO offset/stride Sam Day via B4 Relay
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Sam Day via B4 Relay @ 2026-06-01  8:12 UTC (permalink / raw)
  To: Sumit Garg, u-boot-qcom, u-boot
  Cc: Casey Connolly, Neil Armstrong, Tom Rini, Stephan Gerhold,
	Michal Simek, Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu,
	Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel, Sam Day

From: Sam Day <me@samcday.com>

On older SoCs (such as MSM8960/MSM8930), PS_HOLD is exposed through
the TLMM aperture. To prepare for that use-case, this driver is updated
to accept arbitrary offsets from regbase.

Signed-off-by: Sam Day <me@samcday.com>
---
 drivers/sysreset/sysreset_qcom-pshold.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/sysreset/sysreset_qcom-pshold.c b/drivers/sysreset/sysreset_qcom-pshold.c
index 45290478536..f8be1f2f593 100644
--- a/drivers/sysreset/sysreset_qcom-pshold.c
+++ b/drivers/sysreset/sysreset_qcom-pshold.c
@@ -10,6 +10,7 @@
  */
 
 #include <dm.h>
+#include <errno.h>
 #include <sysreset.h>
 #include <asm/io.h>
 #include <linux/delay.h>
@@ -35,9 +36,15 @@ static struct sysreset_ops qcom_pshold_ops = {
 static int qcom_pshold_probe(struct udevice *dev)
 {
 	struct qcom_pshold_priv *priv = dev_get_priv(dev);
+	ulong offset = dev_get_driver_data(dev);
 
 	priv->base = dev_read_addr(dev);
-	return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0;
+	if (priv->base == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->base += offset;
+
+	return 0;
 }
 
 static const struct udevice_id qcom_pshold_ids[] = {

-- 
2.54.0



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

* [PATCH RESEND 10/16] pinctrl: qcom: configurable GPIO offset/stride
  2026-06-01  8:12 [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Sam Day via B4 Relay
                   ` (8 preceding siblings ...)
  2026-06-01  8:12 ` [PATCH RESEND 09/16] sysreset: qcom-pshold: offset support Sam Day via B4 Relay
@ 2026-06-01  8:12 ` Sam Day via B4 Relay
  2026-06-01  8:12 ` [PATCH RESEND 11/16] pinctrl: qcom: introduce MSM8960 driver Sam Day via B4 Relay
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Sam Day via B4 Relay @ 2026-06-01  8:12 UTC (permalink / raw)
  To: Sumit Garg, u-boot-qcom, u-boot
  Cc: Casey Connolly, Neil Armstrong, Tom Rini, Stephan Gerhold,
	Michal Simek, Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu,
	Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel, Sam Day

From: Sam Day <me@samcday.com>

The infra currently assumes that each GPIO register block is 0x1000
wide. This is not the case on older TLMM versions.

For example, the GPIOs on MSM8960's TLMM hav an *offset* of 0x1000,
and each register block is only 0x10 wide.

Signed-off-by: Sam Day <me@samcday.com>
---
 arch/arm/mach-snapdragon/include/mach/gpio.h | 12 ++++++++----
 drivers/gpio/msm_gpio.c                      |  2 +-
 drivers/pinctrl/qcom/pinctrl-qcom.c          |  2 +-
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-snapdragon/include/mach/gpio.h b/arch/arm/mach-snapdragon/include/mach/gpio.h
index 11e8104baf2..49bf480c903 100644
--- a/arch/arm/mach-snapdragon/include/mach/gpio.h
+++ b/arch/arm/mach-snapdragon/include/mach/gpio.h
@@ -27,16 +27,20 @@ struct msm_special_pin_data {
 struct msm_pin_data {
 	int pin_count;
 	const unsigned int *pin_offsets;
+	u32 gpio_base;
+	/* defaults to 0x1000 */
+	u32 gpio_stride;
 	unsigned int special_pins_start;
 	const struct msm_special_pin_data *special_pins_data;
 };
 
-static inline u32 qcom_pin_offset(const unsigned int *offs, unsigned int selector)
+static inline u32 qcom_pin_offset(const struct msm_pin_data *pindata, unsigned int selector)
 {
-	u32 out = (selector * 0x1000);
+	u32 stride = pindata->gpio_stride ? pindata->gpio_stride : 0x1000;
+	u32 out = pindata->gpio_base + selector * stride;
 
-	if (offs)
-		return out + offs[selector];
+	if (pindata->pin_offsets)
+		return out + pindata->pin_offsets[selector];
 
 	return out;
 }
diff --git a/drivers/gpio/msm_gpio.c b/drivers/gpio/msm_gpio.c
index 7de332c66ae..a24d0f03398 100644
--- a/drivers/gpio/msm_gpio.c
+++ b/drivers/gpio/msm_gpio.c
@@ -29,7 +29,7 @@ struct msm_gpio_bank {
 };
 
 #define GPIO_CONFIG_REG(dev, x) \
-	(qcom_pin_offset(((struct msm_gpio_bank *)dev_get_priv(dev))->pin_data->pin_offsets, x))
+	(qcom_pin_offset(((struct msm_gpio_bank *)dev_get_priv(dev))->pin_data, x))
 
 #define GPIO_IN_OUT_REG(dev, x) \
 	(GPIO_CONFIG_REG(dev, x) + 0x4)
diff --git a/drivers/pinctrl/qcom/pinctrl-qcom.c b/drivers/pinctrl/qcom/pinctrl-qcom.c
index c95db56bc47..82817c2316f 100644
--- a/drivers/pinctrl/qcom/pinctrl-qcom.c
+++ b/drivers/pinctrl/qcom/pinctrl-qcom.c
@@ -30,7 +30,7 @@ struct msm_pinctrl_priv {
 };
 
 #define GPIO_CONFIG_REG(priv, x) \
-	(qcom_pin_offset((priv)->data->pin_data.pin_offsets, x))
+	(qcom_pin_offset(&(priv)->data->pin_data, x))
 
 #define GPIO_IN_OUT_REG(priv, x) \
 	(GPIO_CONFIG_REG(priv, x) + 0x4)

-- 
2.54.0



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

* [PATCH RESEND 11/16] pinctrl: qcom: introduce MSM8960 driver
  2026-06-01  8:12 [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Sam Day via B4 Relay
                   ` (9 preceding siblings ...)
  2026-06-01  8:12 ` [PATCH RESEND 10/16] pinctrl: qcom: configurable GPIO offset/stride Sam Day via B4 Relay
@ 2026-06-01  8:12 ` Sam Day via B4 Relay
  2026-06-01  8:12 ` [PATCH RESEND 12/16] mach-snapdragon: parse incoming ARM32 ATAGS Sam Day via B4 Relay
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Sam Day via B4 Relay @ 2026-06-01  8:12 UTC (permalink / raw)
  To: Sumit Garg, u-boot-qcom, u-boot
  Cc: Casey Connolly, Neil Armstrong, Tom Rini, Stephan Gerhold,
	Michal Simek, Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu,
	Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel, Sam Day

From: Sam Day <me@samcday.com>

This flavour of TLMM has a different layout to the existing versions
already supported in U-Boot. The GPIOs are offset by 0x1000 and have a
stride of 0x10. We prepared the generic pinctrl-qcom infra for that in
the previous commit. Otherwise, this driver quacks like the others.

Signed-off-by: Sam Day <me@samcday.com>
---
 configs/qcom_armv7_defconfig           |   1 +
 drivers/pinctrl/qcom/Kconfig           |   9 +++
 drivers/pinctrl/qcom/Makefile          |   1 +
 drivers/pinctrl/qcom/pinctrl-msm8960.c | 135 +++++++++++++++++++++++++++++++++
 4 files changed, 146 insertions(+)

diff --git a/configs/qcom_armv7_defconfig b/configs/qcom_armv7_defconfig
index 7d64ee68ecd..aef8838c8a8 100644
--- a/configs/qcom_armv7_defconfig
+++ b/configs/qcom_armv7_defconfig
@@ -43,6 +43,7 @@ CONFIG_MSM_GPIO=y
 CONFIG_DM_KEYBOARD=y
 CONFIG_BUTTON_KEYBOARD=y
 CONFIG_PINCTRL=y
+CONFIG_PINCTRL_QCOM_MSM8960=y
 CONFIG_MSM_SERIAL=y
 CONFIG_SYSRESET_QCOM_PSHOLD=y
 CONFIG_TIMER=y
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
index 11e6763b5f3..04d888535fa 100644
--- a/drivers/pinctrl/qcom/Kconfig
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -30,6 +30,15 @@ config PINCTRL_QCOM_APQ8096
 	  Say Y here to enable support for pinctrl on the MSM8996 / APQ8096
 	  Snapdragon 820 SoC, as well as the associated GPIO driver.
 
+config PINCTRL_QCOM_MSM8960
+	bool "Qualcomm MSM8960 Pinctrl"
+	default y if PINCTRL_QCOM_GENERIC
+	select PINCTRL_QCOM
+	help
+	  Say Y here to enable TLMM support on the MSM8960 family, including
+	  MSM8930. This provides pinctrl/GPIO support as well as the PS_HOLD
+	  sysreset child exposed by TLMM.
+
 config PINCTRL_QCOM_IPQ4019
 	bool "Qualcomm IPQ4019 Pinctrl"
 	default y if PINCTRL_QCOM_GENERIC
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
index 4096c1aa491..d518f488db2 100644
--- a/drivers/pinctrl/qcom/Makefile
+++ b/drivers/pinctrl/qcom/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_PINCTRL_QCOM_IPQ4019) += pinctrl-ipq4019.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
+obj-$(CONFIG_PINCTRL_QCOM_MSM8960) += pinctrl-msm8960.o
 obj-$(CONFIG_PINCTRL_QCOM_MILOS) += pinctrl-milos.o
 obj-$(CONFIG_PINCTRL_QCOM_QCM2290) += pinctrl-qcm2290.o
 obj-$(CONFIG_PINCTRL_QCOM_QCS404) += pinctrl-qcs404.o
diff --git a/drivers/pinctrl/qcom/pinctrl-msm8960.c b/drivers/pinctrl/qcom/pinctrl-msm8960.c
new file mode 100644
index 00000000000..32a474c89bc
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-msm8960.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0+
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <errno.h>
+
+#include "pinctrl-qcom.h"
+#include "dm/device_compat.h"
+
+#define MSM8960_PS_HOLD_OFFSET 0x820
+
+#define MAX_PIN_NAME_LEN   32
+#define MSM8960_NUM_GPIO   152
+#define MSM8960_NUM_PINS   158
+#define MSM8960_GPIO_BASE  0x1000
+#define MSM8960_GPIO_STRIDE 0x10
+
+static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
+
+static const struct pinctrl_function msm8960_functions[] = {
+	{ "gpio", 0 },
+	{ "gsbi1", 1 },
+	{ "gsbi2", 1 },
+	{ "gsbi3", 1 },
+	{ "gsbi4", 1 },
+	{ "gsbi5", 1 },
+	{ "gsbi6", 1 },
+	{ "gsbi7", 1 },
+	{ "gsbi8", 1 },
+	{ "gsbi9", 1 },
+	{ "gsbi10", 1 },
+	{ "gsbi11", 1 },
+	{ "gsbi12", 1 },
+};
+
+#define SDC_PINGROUP(pg_name, ctl, pull, drv) \
+	{ \
+		.name = pg_name, \
+		.ctl_reg = ctl, \
+		.io_reg = 0, \
+		.pull_bit = pull, \
+		.drv_bit = drv, \
+		.oe_bit = -1, \
+		.in_bit = -1, \
+		.out_bit = -1, \
+	}
+
+static const struct msm_special_pin_data msm8960_special_pins_data[] = {
+	SDC_PINGROUP("sdc1_clk", 0x20a0, 13, 6),
+	SDC_PINGROUP("sdc1_cmd", 0x20a0, 11, 3),
+	SDC_PINGROUP("sdc1_data", 0x20a0, 9, 0),
+	SDC_PINGROUP("sdc3_clk", 0x20a4, 14, 6),
+	SDC_PINGROUP("sdc3_cmd", 0x20a4, 11, 3),
+	SDC_PINGROUP("sdc3_data", 0x20a4, 9, 0),
+};
+
+static const char *msm8960_get_function_name(struct udevice *dev,
+					     unsigned int selector)
+{
+	return msm8960_functions[selector].name;
+}
+
+static int msm8960_get_function_mux(__maybe_unused unsigned int pin,
+				    unsigned int selector)
+{
+	if (selector >= ARRAY_SIZE(msm8960_functions))
+		return -EINVAL;
+
+	return msm8960_functions[selector].val;
+}
+
+static const char *msm8960_get_pin_name(struct udevice *dev,
+					unsigned int selector)
+{
+	if (selector < MSM8960_NUM_GPIO)
+		snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
+	else
+		snprintf(pin_name, MAX_PIN_NAME_LEN, "%s",
+			 msm8960_special_pins_data[selector -
+						   MSM8960_NUM_GPIO].name);
+
+	return pin_name;
+}
+
+static const struct msm_pinctrl_data msm8960_data = {
+	.pin_data = {
+		.pin_count = MSM8960_NUM_PINS,
+		.gpio_base = MSM8960_GPIO_BASE,
+		.gpio_stride = MSM8960_GPIO_STRIDE,
+		.special_pins_start = MSM8960_NUM_GPIO,
+		.special_pins_data = msm8960_special_pins_data,
+	},
+	.functions_count = ARRAY_SIZE(msm8960_functions),
+	.get_function_name = msm8960_get_function_name,
+	.get_function_mux = msm8960_get_function_mux,
+	.get_pin_name = msm8960_get_pin_name,
+};
+
+static int msm8960_bind_pshold(struct udevice *dev)
+{
+	struct driver *drv;
+
+	drv = lists_driver_lookup_name("qcom_pshold");
+	if (!drv)
+		return -ENOENT;
+
+	return device_bind_with_driver_data(dev, drv, "msm8960-pshold",
+					    MSM8960_PS_HOLD_OFFSET,
+					    dev_ofnode(dev), NULL);
+}
+
+static int msm8960_pinctrl_bind(struct udevice *dev)
+{
+	int ret;
+
+	if (IS_ENABLED(CONFIG_SYSRESET_QCOM_PSHOLD)) {
+		ret = msm8960_bind_pshold(dev);
+		if (ret)
+			dev_err(dev, "Failed to bind pshold: %d\n", ret);
+	}
+
+	return msm_pinctrl_bind(dev);
+}
+
+static const struct udevice_id msm8960_pinctrl_ids[] = {
+	{ .compatible = "qcom,msm8960-pinctrl", .data = (ulong)&msm8960_data },
+	{ }
+};
+
+U_BOOT_DRIVER(pinctrl_msm8960) = {
+	.name = "pinctrl_msm8960",
+	.id = UCLASS_NOP,
+	.of_match = msm8960_pinctrl_ids,
+	.bind = msm8960_pinctrl_bind,
+};

-- 
2.54.0



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

* [PATCH RESEND 12/16] mach-snapdragon: parse incoming ARM32 ATAGS
  2026-06-01  8:12 [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Sam Day via B4 Relay
                   ` (10 preceding siblings ...)
  2026-06-01  8:12 ` [PATCH RESEND 11/16] pinctrl: qcom: introduce MSM8960 driver Sam Day via B4 Relay
@ 2026-06-01  8:12 ` Sam Day via B4 Relay
  2026-06-03 13:47   ` Casey Connolly
  2026-06-01  8:12 ` [PATCH RESEND 13/16] clk: qcom: MSM8960 GCC driver Sam Day via B4 Relay
                   ` (5 subsequent siblings)
  17 siblings, 1 reply; 26+ messages in thread
From: Sam Day via B4 Relay @ 2026-06-01  8:12 UTC (permalink / raw)
  To: Sumit Garg, u-boot-qcom, u-boot
  Cc: Casey Connolly, Neil Armstrong, Tom Rini, Stephan Gerhold,
	Michal Simek, Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu,
	Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel, Sam Day

From: Sam Day <me@samcday.com>

Many (often fused) bootloaders on older ARMv7 qcom SoCs do not support
FDTs at all, and instead pass along ATAGS in r2.

Minimal support for parsing memory info out of these tags is introduced,
so that we can support mainline devicetrees, which expect the bootloader
to populate /memory nodes.

Signed-off-by: Sam Day <me@samcday.com>
---
 arch/arm/mach-snapdragon/board.c | 119 ++++++++++++++++++++++++++++++---------
 1 file changed, 91 insertions(+), 28 deletions(-)

diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
index 627b566d178..753983467a0 100644
--- a/arch/arm/mach-snapdragon/board.c
+++ b/arch/arm/mach-snapdragon/board.c
@@ -11,6 +11,7 @@
 
 #include <asm/gpio.h>
 #include <asm/io.h>
+#include <asm/setup.h>
 #include <asm/system.h>
 #include <dm/device.h>
 #include <dm/pinctrl.h>
@@ -175,6 +176,67 @@ static int qcom_parse_memory(const void *fdt)
 	return 0;
 }
 
+static bool qcom_atags_valid(const phys_addr_t p)
+{
+	const struct tag *tags = (const struct tag *)p;
+
+	return tags && tags->hdr.tag == ATAG_CORE &&
+	       tags->hdr.size >= sizeof(struct tag_header) / sizeof(u32);
+}
+
+static int qcom_parse_atags(const struct tag *tags)
+{
+	phys_addr_t ram_end = 0;
+	const struct tag *t;
+	bool atags_end = false;
+	u32 words = 0;
+	int j = 0;
+
+	memset(prevbl_ddr_banks, 0, sizeof(prevbl_ddr_banks));
+
+	for (t = tags; words < SZ_16K / sizeof(u32); t = tag_next(t)) {
+		if (t->hdr.tag == ATAG_NONE) {
+			atags_end = true;
+			break;
+		}
+		if (t->hdr.size < sizeof(struct tag_header) / sizeof(u32))
+			return -EINVAL;
+		if (t->hdr.size > SZ_16K / sizeof(u32) - words)
+			return -EINVAL;
+
+		words += t->hdr.size;
+
+		if (t->hdr.tag != ATAG_MEM)
+			continue;
+		if (t->hdr.size < tag_size(tag_mem32))
+			return -EINVAL;
+		if (!t->u.mem.size)
+			continue;
+
+		prevbl_ddr_banks[j].start = t->u.mem.start;
+		prevbl_ddr_banks[j].size = t->u.mem.size;
+		ram_end = max(ram_end, (phys_addr_t)t->u.mem.start + t->u.mem.size);
+		j++;
+
+		if (j == CONFIG_NR_DRAM_BANKS)
+			break;
+	}
+
+	if (!atags_end && j < CONFIG_NR_DRAM_BANKS) {
+		log_err("Provided more memory banks than we can handle\n");
+		return -EINVAL;
+	}
+	if (!j)
+		return -ENODATA;
+
+	qsort(prevbl_ddr_banks, j, sizeof(prevbl_ddr_banks[0]), ddr_bank_cmp);
+
+	gd->ram_base = prevbl_ddr_banks[0].start;
+	gd->ram_size = ram_end - gd->ram_base;
+
+	return 0;
+}
+
 static void show_psci_version(void)
 {
 #ifdef CONFIG_ARM64
@@ -227,42 +289,52 @@ static void qcom_psci_fixup(void *fdt)
  */
 int board_fdt_blob_setup(void **fdtp)
 {
-	struct fdt_header *external_fdt, *internal_fdt;
-	bool internal_valid, external_valid;
-	int ret = -ENODATA;
-
-	internal_fdt = (struct fdt_header *)*fdtp;
-	external_fdt = (struct fdt_header *)get_prev_bl_fdt_addr();
-	external_valid = external_fdt && !fdt_check_header(external_fdt);
-	internal_valid = !fdt_check_header(internal_fdt);
+	int ret = -ENODATA, setup_ret = -EEXIST;
+	struct fdt_header *internal_fdt = *fdtp;
+	phys_addr_t prev_bl_arg = get_prev_bl_fdt_addr();
+	bool internal_valid = internal_fdt && !fdt_check_header(internal_fdt);
+	bool external_is_fdt = prev_bl_arg &&
+			       !fdt_check_header((const void *)prev_bl_arg);
 
-	/*
-	 * There is no point returning an error here, U-Boot can't do anything useful in this situation.
-	 * Bail out while we can still print a useful error message.
-	 */
-	if (!internal_valid && !external_valid)
+	if (internal_valid) {
+		debug("Using built in FDT\n");
+	} else if (external_is_fdt) {
+		debug("Using external FDT\n");
+		*fdtp = (void *)prev_bl_arg;
+		setup_ret = 0;
+	} else {
+		/*
+		 * There is no point returning an error here, U-Boot can't do
+		 * anything useful in this situation. Bail out while we can
+		 * still print a useful error message.
+		 */
 		panic("Internal FDT is invalid and no external FDT was provided! (fdt=%p)\n",
-		      external_fdt);
+		      (void *)prev_bl_arg);
+	}
 
 	/* Prefer memory information from internal DT if it's present */
 	if (internal_valid)
 		ret = qcom_parse_memory(internal_fdt);
 
-	if (ret < 0 && external_valid) {
+	if (ret < 0 && prev_bl_arg) {
 		/* No internal FDT or it lacks a proper /memory node.
 		 * The previous bootloader handed us something, let's try that.
 		 */
 		if (internal_valid)
 			debug("No memory info in internal FDT, falling back to external\n");
 
-		ret = qcom_parse_memory(external_fdt);
+		/* the prev BL arg is either an FDT or ATAGS */
+		if (external_is_fdt)
+			ret = qcom_parse_memory((const void *)prev_bl_arg);
+		if (ret < 0 && qcom_atags_valid(prev_bl_arg))
+			ret = qcom_parse_atags((const struct tag *)prev_bl_arg);
 	}
 
 	if (ret < 0)
 		panic("No valid memory ranges found!\n");
 
-	/* If we have an external FDT, it can only have come from the Android bootloader. */
-	if (external_valid)
+	/* If we have a prev BL arg, we assume it came from ABL */
+	if (prev_bl_arg)
 		qcom_boot_source = QCOM_BOOT_SOURCE_ANDROID;
 	else
 		qcom_boot_source = QCOM_BOOT_SOURCE_XBL;
@@ -270,18 +342,9 @@ int board_fdt_blob_setup(void **fdtp)
 	debug("ram_base = %#011lx, ram_size = %#011llx\n",
 	      gd->ram_base, (unsigned long long)gd->ram_size);
 
-	if (internal_valid) {
-		debug("Using built in FDT\n");
-		ret = -EEXIST;
-	} else {
-		debug("Using external FDT\n");
-		*fdtp = external_fdt;
-		ret = 0;
-	}
-
 	qcom_psci_fixup(*fdtp);
 
-	return ret;
+	return setup_ret;
 }
 
 /*

-- 
2.54.0



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

* [PATCH RESEND 13/16] clk: qcom: MSM8960 GCC driver
  2026-06-01  8:12 [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Sam Day via B4 Relay
                   ` (11 preceding siblings ...)
  2026-06-01  8:12 ` [PATCH RESEND 12/16] mach-snapdragon: parse incoming ARM32 ATAGS Sam Day via B4 Relay
@ 2026-06-01  8:12 ` Sam Day via B4 Relay
  2026-06-01  8:12 ` [PATCH RESEND 14/16] clk: qcom: arch-agnostic pointer fmtstrings Sam Day via B4 Relay
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Sam Day via B4 Relay @ 2026-06-01  8:12 UTC (permalink / raw)
  To: Sumit Garg, u-boot-qcom, u-boot
  Cc: Casey Connolly, Neil Armstrong, Tom Rini, Stephan Gerhold,
	Michal Simek, Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu,
	Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel, Sam Day

From: Sam Day <me@samcday.com>

This older GCC does not use RCGR/CBCR, but rather NS/MD/HALT registers.
We can't benefit as much from shared qcom clk infra, nor the `clk dump`
helpers (which assume newer RCGR/PLL register layout).

We start with just the UART clocks.

Signed-off-by: Sam Day <me@samcday.com>
---
 configs/qcom_armv7_defconfig     |   1 +
 drivers/clk/qcom/Kconfig         |   8 ++
 drivers/clk/qcom/Makefile        |   1 +
 drivers/clk/qcom/clock-msm8960.c | 189 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 199 insertions(+)

diff --git a/configs/qcom_armv7_defconfig b/configs/qcom_armv7_defconfig
index aef8838c8a8..91525138ec9 100644
--- a/configs/qcom_armv7_defconfig
+++ b/configs/qcom_armv7_defconfig
@@ -34,6 +34,7 @@ CONFIG_OF_UPSTREAM_BUILD_VENDOR=y
 CONFIG_ENV_USE_DEFAULT_ENV_TEXT_FILE=y
 CONFIG_ENV_DEFAULT_ENV_TEXT_FILE="board/qualcomm/default.env"
 CONFIG_CLK=y
+CONFIG_CLK_QCOM_MSM8960=y
 CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x0
 CONFIG_FASTBOOT_FLASH=y
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 0a2ce55aaa2..3526a4c218b 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -55,6 +55,14 @@ config CLK_QCOM_MILOS
 	  on the Snapdragon Milos SoC. This driver supports the clocks
 	  and resets exposed by the GCC hardware block.
 
+config CLK_QCOM_MSM8960
+	bool "Qualcomm MSM8960 GCC"
+	select CLK_QCOM
+	help
+	  Say Y here to enable support for the Global Clock Controller
+	  on the Snapdragon MSM8960 SoC. This driver supports the clocks
+	  and resets exposed by the GCC hardware block.
+
 config CLK_QCOM_QCM2290
 	bool "Qualcomm QCM2290 GCC"
 	select CLK_QCOM
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index b96d61b603e..60a39a7cb39 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_CLK_QCOM_IPQ4019) += clock-ipq4019.o
 obj-$(CONFIG_CLK_QCOM_IPQ5424) += clock-ipq5424.o
 obj-$(CONFIG_CLK_QCOM_IPQ9574) += clock-ipq9574.o
 obj-$(CONFIG_CLK_QCOM_MILOS) += clock-milos.o
+obj-$(CONFIG_CLK_QCOM_MSM8960) += clock-msm8960.o
 obj-$(CONFIG_CLK_QCOM_QCM2290) += clock-qcm2290.o
 obj-$(CONFIG_CLK_QCOM_QCS404) += clock-qcs404.o
 obj-$(CONFIG_CLK_QCOM_QCS8300) += clock-qcs8300.o
diff --git a/drivers/clk/qcom/clock-msm8960.c b/drivers/clk/qcom/clock-msm8960.c
new file mode 100644
index 00000000000..b17fc48fd02
--- /dev/null
+++ b/drivers/clk/qcom/clock-msm8960.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <dt-bindings/clock/qcom,gcc-msm8960.h>
+
+#include "clock-qcom.h"
+
+#define GPLL8_STATUS        0x3158
+#define APCS_GPLL_ENA_VOTE  0x34c0
+#define GPLL8_STATUS_ACTIVE BIT(16)
+
+#define GSBI5_H_NS    0x2a40
+#define GSBI5_UART_MD 0x2a50
+#define GSBI5_UART_NS 0x2a54
+#define GSBI5_HALT    0x2fd0
+
+#define GSBI5_UART_HALT_BIT 22
+#define GSBI5_H_HALT_BIT    23
+
+#define GSBI_H_CLK_EN    BIT(4)
+#define GSBI_H_HWC_EN    BIT(6)
+#define GSBI_UART_CLK_EN BIT(9)
+#define GSBI_UART_SRC_EN BIT(11)
+
+#define RCG_SRC_SEL_MASK  GENMASK(2, 0)
+#define RCG_PRE_DIV_MASK  GENMASK(4, 3)
+#define RCG_MN_MODE_MASK  GENMASK(6, 5)
+#define RCG_MN_MODE_DUAL  (2 << 5)
+#define RCG_MN_RESET      BIT(7)
+#define RCG_MN_EN         BIT(8)
+#define RCG_MND_MASK      GENMASK(15, 0)
+#define RCG_N_VAL_SHIFT   16
+#define RCG_M_VAL_SHIFT   16
+#define RCG_PRE_DIV_SHIFT 3
+
+#define MSM8960_SRC_PLL8 3
+
+static const struct pll_vote_clk pll8_vote_clk = {
+	.status = GPLL8_STATUS,
+	.status_bit = GPLL8_STATUS_ACTIVE,
+	.ena_vote = APCS_GPLL_ENA_VOTE,
+	.vote_bit = BIT(8),
+};
+
+static const struct freq_tbl gsbi_uart_freqs[] = {
+	{  1843200, MSM8960_SRC_PLL8, 2,  6, 625 },
+	{  3686400, MSM8960_SRC_PLL8, 2, 12, 625 },
+	{  7372800, MSM8960_SRC_PLL8, 2, 24, 625 },
+	{ 14745600, MSM8960_SRC_PLL8, 2, 48, 625 },
+	{ }
+};
+
+static const struct gate_clk msm8960_clks[] = {
+	GATE_CLK(GSBI5_H_CLK, GSBI5_H_NS, GSBI_H_CLK_EN),
+	GATE_CLK(GSBI5_UART_CLK, GSBI5_UART_NS, GSBI_UART_CLK_EN),
+};
+
+static int msm8960_branch_wait(phys_addr_t base, unsigned int halt_bit)
+{
+	u32 count;
+
+	for (count = 0; count < 200; count++) {
+		if (!(readl(base + GSBI5_HALT) & BIT(halt_bit)))
+			return 0;
+		udelay(1);
+	}
+
+	log_warning("MSM8960 GCC branch clock %u stuck off\n", halt_bit);
+	return -EBUSY;
+}
+
+static int msm8960_enable_gsbi5_h_clk(phys_addr_t base)
+{
+	setbits_le32(base + GSBI5_H_NS, GSBI_H_CLK_EN);
+
+	if (readl(base + GSBI5_H_NS) & GSBI_H_HWC_EN)
+		return 0;
+
+	return msm8960_branch_wait(base, GSBI5_H_HALT_BIT);
+}
+
+static void msm8960_rcg_set_rate(phys_addr_t base, const struct freq_tbl *freq)
+{
+	u32 md;
+	u32 ns;
+
+	setbits_le32(base + GSBI5_UART_NS, RCG_MN_RESET);
+
+	md = (freq->m << RCG_M_VAL_SHIFT) | (~freq->n & RCG_MND_MASK);
+	writel(md, base + GSBI5_UART_MD);
+
+	ns = readl(base + GSBI5_UART_NS);
+	ns &= ~(RCG_SRC_SEL_MASK | RCG_PRE_DIV_MASK | RCG_MN_MODE_MASK |
+		RCG_MN_EN | (RCG_MND_MASK << RCG_N_VAL_SHIFT));
+
+	if (freq->n) {
+		ns |= RCG_MN_EN | RCG_MN_MODE_DUAL;
+		ns |= (~(freq->n - freq->m) & RCG_MND_MASK) << RCG_N_VAL_SHIFT;
+	}
+
+	ns |= (freq->pre_div - 1) << RCG_PRE_DIV_SHIFT;
+	ns |= freq->src;
+	writel(ns, base + GSBI5_UART_NS);
+
+	clrbits_le32(base + GSBI5_UART_NS, RCG_MN_RESET);
+}
+
+static ulong msm8960_gsbi5_uart_set_rate(struct msm_clk_priv *priv, ulong rate)
+{
+	const struct freq_tbl *freq = qcom_find_freq(gsbi_uart_freqs, rate);
+	int ret;
+
+	if (!freq || !freq->freq)
+		return 0;
+
+	clk_enable_gpll0(priv->base, &pll8_vote_clk);
+	msm8960_rcg_set_rate(priv->base, freq);
+
+	setbits_le32(priv->base + GSBI5_UART_NS, GSBI_UART_SRC_EN |
+		      GSBI_UART_CLK_EN);
+	ret = msm8960_branch_wait(priv->base, GSBI5_UART_HALT_BIT);
+	if (ret)
+		return 0;
+
+	ret = msm8960_enable_gsbi5_h_clk(priv->base);
+	if (ret)
+		return 0;
+
+	return freq->freq;
+}
+
+static ulong msm8960_clk_set_rate(struct clk *clk, ulong rate)
+{
+	struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+	switch (clk->id) {
+	case GSBI5_UART_SRC:
+	case GSBI5_UART_CLK:
+		return msm8960_gsbi5_uart_set_rate(priv, rate);
+	default:
+		return 0;
+	}
+}
+
+static int msm8960_clk_enable(struct clk *clk)
+{
+	struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+	switch (clk->id) {
+	case GSBI5_H_CLK:
+		return msm8960_enable_gsbi5_h_clk(priv->base);
+	case GSBI5_UART_SRC:
+		setbits_le32(priv->base + GSBI5_UART_NS, GSBI_UART_SRC_EN);
+		return 0;
+	case GSBI5_UART_CLK:
+		setbits_le32(priv->base + GSBI5_UART_NS, GSBI_UART_CLK_EN);
+		return msm8960_branch_wait(priv->base, GSBI5_UART_HALT_BIT);
+	default:
+		return -ENOENT;
+	}
+}
+
+static struct msm_clk_data msm8960_clk_data = {
+	.clks = msm8960_clks,
+	.num_clks = ARRAY_SIZE(msm8960_clks),
+	.set_rate = msm8960_clk_set_rate,
+	.enable = msm8960_clk_enable,
+};
+
+static const struct udevice_id gcc_msm8960_of_match[] = {
+	{
+		.compatible = "qcom,gcc-msm8960",
+		.data = (ulong)&msm8960_clk_data,
+	},
+	{ }
+};
+
+U_BOOT_DRIVER(gcc_msm8960) = {
+	.name = "gcc_msm8960",
+	.id = UCLASS_NOP,
+	.of_match = gcc_msm8960_of_match,
+	.bind = qcom_cc_bind,
+	.flags = DM_FLAG_PRE_RELOC,
+};

-- 
2.54.0



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

* [PATCH RESEND 14/16] clk: qcom: arch-agnostic pointer fmtstrings
  2026-06-01  8:12 [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Sam Day via B4 Relay
                   ` (12 preceding siblings ...)
  2026-06-01  8:12 ` [PATCH RESEND 13/16] clk: qcom: MSM8960 GCC driver Sam Day via B4 Relay
@ 2026-06-01  8:12 ` Sam Day via B4 Relay
  2026-06-01  8:12 ` [PATCH RESEND 15/16] serial: msm: wait for TX empty before reinit Sam Day via B4 Relay
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Sam Day via B4 Relay @ 2026-06-01  8:12 UTC (permalink / raw)
  To: Sumit Garg, u-boot-qcom, u-boot
  Cc: Casey Connolly, Neil Armstrong, Tom Rini, Stephan Gerhold,
	Michal Simek, Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu,
	Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel, Sam Day

From: Sam Day <me@samcday.com>

Cleans up some warnings when building on arm32.

Signed-off-by: Sam Day <me@samcday.com>
---
 drivers/clk/qcom/clock-qcom.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c
index 6b46d9db744..0f8c7155784 100644
--- a/drivers/clk/qcom/clock-qcom.c
+++ b/drivers/clk/qcom/clock-qcom.c
@@ -77,8 +77,8 @@ void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk)
 int qcom_gate_clk_en(const struct msm_clk_priv *priv, unsigned long id)
 {
 	if (id >= priv->data->num_clks || priv->data->clks[id].reg == 0) {
-		log_err("gcc@%#08llx: unknown clock ID %lu!\n",
-			priv->base, id);
+		log_err("gcc@%p: unknown clock ID %lu!\n",
+			(void *)priv->base, id);
 		return -ENOENT;
 	}
 
@@ -115,8 +115,8 @@ void clk_bcr_update(phys_addr_t apps_cmd_rcgr)
 			break;
 		udelay(1);
 	}
-	WARN(count == 50000, "WARNING: RCG @ %#llx [%#010x] stuck at off\n",
-	     apps_cmd_rcgr, readl(apps_cmd_rcgr));
+	WARN(count == 50000, "WARNING: RCG @ %p [%#010x] stuck at off\n",
+	     (void *)apps_cmd_rcgr, readl(apps_cmd_rcgr));
 }
 
 #define CFG_SRC_DIV_MASK	0b11111

-- 
2.54.0



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

* [PATCH RESEND 15/16] serial: msm: wait for TX empty before reinit
  2026-06-01  8:12 [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Sam Day via B4 Relay
                   ` (13 preceding siblings ...)
  2026-06-01  8:12 ` [PATCH RESEND 14/16] clk: qcom: arch-agnostic pointer fmtstrings Sam Day via B4 Relay
@ 2026-06-01  8:12 ` Sam Day via B4 Relay
  2026-06-01  8:41   ` Stephan Gerhold
  2026-06-01  8:12 ` [PATCH RESEND 16/16] button: remap phone HOMEPAGE button Sam Day via B4 Relay
                   ` (2 subsequent siblings)
  17 siblings, 1 reply; 26+ messages in thread
From: Sam Day via B4 Relay @ 2026-06-01  8:12 UTC (permalink / raw)
  To: Sumit Garg, u-boot-qcom, u-boot
  Cc: Casey Connolly, Neil Armstrong, Tom Rini, Stephan Gerhold,
	Michal Simek, Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu,
	Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel, Sam Day

From: Sam Day <me@samcday.com>

At least on UARTDM 1.3, I was noticing the early UART debug banner
getting corrupted. It turns out this is because U-Boot was
re-initializing the UARTDM block and writing to it before it had
finished shifting out the FIFO from the previous bootloader. Waiting for
TX_EMPTY in the status register consistently fixes the issue.

Signed-off-by: Sam Day <me@samcday.com>
---
 drivers/serial/serial_msm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/serial/serial_msm.c b/drivers/serial/serial_msm.c
index 10948e2aede..db085d68a0d 100644
--- a/drivers/serial/serial_msm.c
+++ b/drivers/serial/serial_msm.c
@@ -351,6 +351,8 @@ static inline void _debug_uart_init(void)
 	 *   - HMIBSC: GCC_BLSP1_UART1_APPS_CLK
 	 */
 	//apq8016_clk_init_uart(0x1800000, <uart_clk_id>);
+	while (!(readl(init_serial_data.base + UARTDM_SR) & UARTDM_SR_TX_EMPTY))
+		;
 	uart_dm_init(&init_serial_data);
 }
 

-- 
2.54.0



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

* [PATCH RESEND 16/16] button: remap phone HOMEPAGE button
  2026-06-01  8:12 [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Sam Day via B4 Relay
                   ` (14 preceding siblings ...)
  2026-06-01  8:12 ` [PATCH RESEND 15/16] serial: msm: wait for TX empty before reinit Sam Day via B4 Relay
@ 2026-06-01  8:12 ` Sam Day via B4 Relay
  2026-06-01  8:16 ` [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Luca Weiss
  2026-06-06 21:36 ` Antony Kurniawan Soemardi
  17 siblings, 0 replies; 26+ messages in thread
From: Sam Day via B4 Relay @ 2026-06-01  8:12 UTC (permalink / raw)
  To: Sumit Garg, u-boot-qcom, u-boot
  Cc: Casey Connolly, Neil Armstrong, Tom Rini, Stephan Gerhold,
	Michal Simek, Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu,
	Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel, Sam Day

From: Sam Day <me@samcday.com>

If I'm being honest, I thought of doing this primarily because I
haven't wired up the PMIC power button on my samsung-expressltexx yet.
But, I think it does make sense to remap the center button on older
Android phones to act as the Enter key anyway.

Signed-off-by: Sam Day <me@samcday.com>
---
 drivers/button/Kconfig         | 2 +-
 drivers/button/button-uclass.c | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
index 6cae16fcc8b..8e6bab74cf1 100644
--- a/drivers/button/Kconfig
+++ b/drivers/button/Kconfig
@@ -18,7 +18,7 @@ config BUTTON_REMAP_PHONE_KEYS
 	  are remapped to the following navigation keys:
 	  - Volume up: Up
 	  - Volume down: Down
-	  - Power: Enter
+	  - Home/Power: Enter
 
 config BUTTON_ADC
 	bool "Button adc"
diff --git a/drivers/button/button-uclass.c b/drivers/button/button-uclass.c
index 025917887e8..4e37180fc09 100644
--- a/drivers/button/button-uclass.c
+++ b/drivers/button/button-uclass.c
@@ -45,6 +45,7 @@ static int button_remap_phone_keys(int code)
 		return KEY_UP;
 	case KEY_VOLUMEDOWN:
 		return KEY_DOWN;
+	case KEY_HOMEPAGE:
 	case KEY_POWER:
 		return KEY_ENTER;
 	default:

-- 
2.54.0



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

* Re: [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support
  2026-06-01  8:12 [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Sam Day via B4 Relay
                   ` (15 preceding siblings ...)
  2026-06-01  8:12 ` [PATCH RESEND 16/16] button: remap phone HOMEPAGE button Sam Day via B4 Relay
@ 2026-06-01  8:16 ` Luca Weiss
  2026-06-06 21:36 ` Antony Kurniawan Soemardi
  17 siblings, 0 replies; 26+ messages in thread
From: Luca Weiss @ 2026-06-01  8:16 UTC (permalink / raw)
  To: me, Sumit Garg, u-boot-qcom, u-boot
  Cc: Casey Connolly, Neil Armstrong, Tom Rini, Stephan Gerhold,
	Michal Simek, Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu,
	Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel

On Mon Jun 1, 2026 at 10:12 AM CEST, Sam Day via B4 Relay wrote:
> ** Resending because I found new ways to dislike Proton Mail (it failed
> the series midway due to "spamming". Sigh.). **
>
> This patch series introduces support for ARMv7 Qualcomm SoCs, starting
> with MSM8960/MSM8930/MSM8227.
>
> An overview of the changes:
>  * serial_msm reintroduces the previous packed RX/TX software mode
>    operation, as this is compatible with all UARTDM versions (1.4 and
>    older). It's added alongside the newer single-char mode for 1.4.
>  * A timer driver is introduced for KPSS. I don't know if *all* ARMv7
>    qcom SoCs lack generic ARM CP15 debug timer support, but at least
>    MSM8960/MSM8930 do.
>  * mach-snapdragon board code is shuffled around a bit to build cleanly
>    on ARM64.
>  * prev_bl_data support is extended to ARM32 (which uses r2 for passing
>    FDT/ATAGS pointers, rather than r0)
>  * qcom_parse_memory is revised to support arm32 memory nodes (which are
>    1-cell rather than 2-cell).
>  * Basic ATAGS support is introduced, so that the memory info can be
>    used from previous bootloaders that do not understand FDTs at all.
>  * PS_HOLD sysreset and pinctrl-qcom needed some minor tweaks to handle
>    some nuances that challenge the current assumptions.
>  * A pinctrl driver is introduced for MSM8960.
>  * Initial MSM8960 GCC infra is introduced.
>
> I tested this series on:
>  * Nokia Lumia 520 (msm8227). No working buttons yet as these are
>    exposed as GPIO-over-PMIC-over-SSBI (drivers will be proposed at a
>    later date).
>  * Samsung Galaxy Express GT-I8730 (msm8930). Volume rockers + home
>    button are working via the new pinctrl-msm8960 driver. Power
>    button not working yet (needs PMIC driver infra).
>  * I have no msm8960/apq8064 devices, looking for folks to test those.
>
> To confirm there was no regressions with ARM64 and/or newer devices, I
> also tested on:
>  * db410c (msm8916)
>  * google-sargo (sdm670)

Nice, I'll need to try this on msm8974 & msm8226!

Regards
Luca

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

* Re: [PATCH RESEND 15/16] serial: msm: wait for TX empty before reinit
  2026-06-01  8:12 ` [PATCH RESEND 15/16] serial: msm: wait for TX empty before reinit Sam Day via B4 Relay
@ 2026-06-01  8:41   ` Stephan Gerhold
  2026-06-07  1:26     ` Sam Day
  0 siblings, 1 reply; 26+ messages in thread
From: Stephan Gerhold @ 2026-06-01  8:41 UTC (permalink / raw)
  To: me
  Cc: Sumit Garg, u-boot-qcom, u-boot, Casey Connolly, Neil Armstrong,
	Tom Rini, Michal Simek, Angelo Dureghello, Eugen Hristev,
	Kuan-Wei Chiu, Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel

On Mon, Jun 01, 2026 at 06:12:56PM +1000, Sam Day via B4 Relay wrote:
> From: Sam Day <me@samcday.com>
> 
> At least on UARTDM 1.3, I was noticing the early UART debug banner
> getting corrupted. It turns out this is because U-Boot was
> re-initializing the UARTDM block and writing to it before it had
> finished shifting out the FIFO from the previous bootloader. Waiting for
> TX_EMPTY in the status register consistently fixes the issue.
> 
> Signed-off-by: Sam Day <me@samcday.com>
> ---
>  drivers/serial/serial_msm.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/serial/serial_msm.c b/drivers/serial/serial_msm.c
> index 10948e2aede..db085d68a0d 100644
> --- a/drivers/serial/serial_msm.c
> +++ b/drivers/serial/serial_msm.c
> @@ -351,6 +351,8 @@ static inline void _debug_uart_init(void)
>  	 *   - HMIBSC: GCC_BLSP1_UART1_APPS_CLK
>  	 */
>  	//apq8016_clk_init_uart(0x1800000, <uart_clk_id>);
> +	while (!(readl(init_serial_data.base + UARTDM_SR) & UARTDM_SR_TX_EMPTY))
> +		;

I think you need to add some timeout here. There is some funky SoC where
the UART is left in some half-disabled state and this bit will never
become unset. Maybe it was MSM8909, I don't remember exactly. I have
similar code in TF-A and there I had to add the timeout to prevent the
device from getting completely stuck during boot sometimes because of
this loop:

https://github.com/ARM-software/arm-trusted-firmware/blob/da738d5eae93af342fdc4995dd3c05acb4c9d757/plat/qti/bear/msm8916/aarch32/uartdm_console.S#L68-L81

Thanks,
Stephan

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

* Re: [PATCH RESEND 12/16] mach-snapdragon: parse incoming ARM32 ATAGS
  2026-06-01  8:12 ` [PATCH RESEND 12/16] mach-snapdragon: parse incoming ARM32 ATAGS Sam Day via B4 Relay
@ 2026-06-03 13:47   ` Casey Connolly
  2026-06-03 22:27     ` Sam Day
  0 siblings, 1 reply; 26+ messages in thread
From: Casey Connolly @ 2026-06-03 13:47 UTC (permalink / raw)
  To: me, Sumit Garg, u-boot-qcom, u-boot
  Cc: Neil Armstrong, Tom Rini, Stephan Gerhold, Michal Simek,
	Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu, Yao Zi,
	Simon Glass, Sughosh Ganu, George Chan, Antony Kurniawan Soemardi,
	Rayagonda Kokatanur, Tien Fong Chee, Peng Fan,
	Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut, Tingting Meng,
	Alice Guo, Quentin Schulz, Ilias Apalodimas, Luca Weiss,
	Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel

Hi Sam,

(CC list definitely needs some tuning on the next revision XD)

On 6/1/26 10:12, Sam Day via B4 Relay wrote:
> From: Sam Day <me@samcday.com>
> 
> Many (often fused) bootloaders on older ARMv7 qcom SoCs do not support
> FDTs at all, and instead pass along ATAGS in r2.
> 
> Minimal support for parsing memory info out of these tags is introduced,
> so that we can support mainline devicetrees, which expect the bootloader
> to populate /memory nodes.

I think this should go its own armv7-specific file. It would probably 
also make sense to just have a separate implementation of 
board_fdt_blob_setup() since it's already really quite complicated.

The SMEM series will do a bit of rework, in the next spin I'll probably 
move the caching stuff out as well, maybe I should also take 
board_fdt_blob_setup() then the file can be arm64 specific?

> 
> Signed-off-by: Sam Day <me@samcday.com>
> ---
>   arch/arm/mach-snapdragon/board.c | 119 ++++++++++++++++++++++++++++++---------
>   1 file changed, 91 insertions(+), 28 deletions(-)
> 
> diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
> index 627b566d178..753983467a0 100644
> --- a/arch/arm/mach-snapdragon/board.c
> +++ b/arch/arm/mach-snapdragon/board.c
> @@ -11,6 +11,7 @@
>   
>   #include <asm/gpio.h>
>   #include <asm/io.h>
> +#include <asm/setup.h>
>   #include <asm/system.h>
>   #include <dm/device.h>
>   #include <dm/pinctrl.h>
> @@ -175,6 +176,67 @@ static int qcom_parse_memory(const void *fdt)
>   	return 0;
>   }
>   
> +static bool qcom_atags_valid(const phys_addr_t p)
> +{
> +	const struct tag *tags = (const struct tag *)p;
> +
> +	return tags && tags->hdr.tag == ATAG_CORE &&
> +	       tags->hdr.size >= sizeof(struct tag_header) / sizeof(u32);
> +}
> +
> +static int qcom_parse_atags(const struct tag *tags)
> +{
> +	phys_addr_t ram_end = 0;
> +	const struct tag *t;
> +	bool atags_end = false;
> +	u32 words = 0;
> +	int j = 0;
> +
> +	memset(prevbl_ddr_banks, 0, sizeof(prevbl_ddr_banks));
> +
> +	for (t = tags; words < SZ_16K / sizeof(u32); t = tag_next(t)) {
> +		if (t->hdr.tag == ATAG_NONE) {
> +			atags_end = true;
> +			break;
> +		}
> +		if (t->hdr.size < sizeof(struct tag_header) / sizeof(u32))
> +			return -EINVAL;
> +		if (t->hdr.size > SZ_16K / sizeof(u32) - words)
> +			return -EINVAL;
> +
> +		words += t->hdr.size;
> +
> +		if (t->hdr.tag != ATAG_MEM)
> +			continue;
> +		if (t->hdr.size < tag_size(tag_mem32))
> +			return -EINVAL;
> +		if (!t->u.mem.size)
> +			continue;
> +
> +		prevbl_ddr_banks[j].start = t->u.mem.start;
> +		prevbl_ddr_banks[j].size = t->u.mem.size;
> +		ram_end = max(ram_end, (phys_addr_t)t->u.mem.start + t->u.mem.size);
> +		j++;
> +
> +		if (j == CONFIG_NR_DRAM_BANKS)
> +			break;
> +	}
> +
> +	if (!atags_end && j < CONFIG_NR_DRAM_BANKS) {
> +		log_err("Provided more memory banks than we can handle\n");
> +		return -EINVAL;
> +	}
> +	if (!j)
> +		return -ENODATA;
> +
> +	qsort(prevbl_ddr_banks, j, sizeof(prevbl_ddr_banks[0]), ddr_bank_cmp);
> +
> +	gd->ram_base = prevbl_ddr_banks[0].start;
> +	gd->ram_size = ram_end - gd->ram_base;
> +
> +	return 0;
> +}
> +
>   static void show_psci_version(void)
>   {
>   #ifdef CONFIG_ARM64
> @@ -227,42 +289,52 @@ static void qcom_psci_fixup(void *fdt)
>    */
>   int board_fdt_blob_setup(void **fdtp)
>   {
> -	struct fdt_header *external_fdt, *internal_fdt;
> -	bool internal_valid, external_valid;
> -	int ret = -ENODATA;
> -
> -	internal_fdt = (struct fdt_header *)*fdtp;
> -	external_fdt = (struct fdt_header *)get_prev_bl_fdt_addr();
> -	external_valid = external_fdt && !fdt_check_header(external_fdt);
> -	internal_valid = !fdt_check_header(internal_fdt);
> +	int ret = -ENODATA, setup_ret = -EEXIST;
> +	struct fdt_header *internal_fdt = *fdtp;
> +	phys_addr_t prev_bl_arg = get_prev_bl_fdt_addr();
> +	bool internal_valid = internal_fdt && !fdt_check_header(internal_fdt);
> +	bool external_is_fdt = prev_bl_arg &&
> +			       !fdt_check_header((const void *)prev_bl_arg);
>   
> -	/*
> -	 * There is no point returning an error here, U-Boot can't do anything useful in this situation.
> -	 * Bail out while we can still print a useful error message.
> -	 */
> -	if (!internal_valid && !external_valid)
> +	if (internal_valid) {
> +		debug("Using built in FDT\n");
> +	} else if (external_is_fdt) {
> +		debug("Using external FDT\n");
> +		*fdtp = (void *)prev_bl_arg;
> +		setup_ret = 0;
> +	} else {
> +		/*
> +		 * There is no point returning an error here, U-Boot can't do
> +		 * anything useful in this situation. Bail out while we can
> +		 * still print a useful error message.
> +		 */
>   		panic("Internal FDT is invalid and no external FDT was provided! (fdt=%p)\n",
> -		      external_fdt);
> +		      (void *)prev_bl_arg);
> +	}
>   
>   	/* Prefer memory information from internal DT if it's present */
>   	if (internal_valid)
>   		ret = qcom_parse_memory(internal_fdt);
>   
> -	if (ret < 0 && external_valid) {
> +	if (ret < 0 && prev_bl_arg) {
>   		/* No internal FDT or it lacks a proper /memory node.
>   		 * The previous bootloader handed us something, let's try that.
>   		 */
>   		if (internal_valid)
>   			debug("No memory info in internal FDT, falling back to external\n");
>   
> -		ret = qcom_parse_memory(external_fdt);
> +		/* the prev BL arg is either an FDT or ATAGS */
> +		if (external_is_fdt)
> +			ret = qcom_parse_memory((const void *)prev_bl_arg);
> +		if (ret < 0 && qcom_atags_valid(prev_bl_arg))
> +			ret = qcom_parse_atags((const struct tag *)prev_bl_arg);
>   	}
>   
>   	if (ret < 0)
>   		panic("No valid memory ranges found!\n");
>   
> -	/* If we have an external FDT, it can only have come from the Android bootloader. */
> -	if (external_valid)
> +	/* If we have a prev BL arg, we assume it came from ABL */
> +	if (prev_bl_arg)
>   		qcom_boot_source = QCOM_BOOT_SOURCE_ANDROID;
>   	else
>   		qcom_boot_source = QCOM_BOOT_SOURCE_XBL;
> @@ -270,18 +342,9 @@ int board_fdt_blob_setup(void **fdtp)
>   	debug("ram_base = %#011lx, ram_size = %#011llx\n",
>   	      gd->ram_base, (unsigned long long)gd->ram_size);
>   
> -	if (internal_valid) {
> -		debug("Using built in FDT\n");
> -		ret = -EEXIST;
> -	} else {
> -		debug("Using external FDT\n");
> -		*fdtp = external_fdt;
> -		ret = 0;
> -	}
> -
>   	qcom_psci_fixup(*fdtp);
>   
> -	return ret;
> +	return setup_ret;
>   }
>   
>   /*
> 


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

* Re: [PATCH RESEND 12/16] mach-snapdragon: parse incoming ARM32 ATAGS
  2026-06-03 13:47   ` Casey Connolly
@ 2026-06-03 22:27     ` Sam Day
  2026-06-04 15:01       ` Casey Connolly
  0 siblings, 1 reply; 26+ messages in thread
From: Sam Day @ 2026-06-03 22:27 UTC (permalink / raw)
  To: Casey Connolly
  Cc: Sumit Garg, u-boot-qcom, u-boot, Neil Armstrong, Tom Rini,
	Stephan Gerhold, Michal Simek, Angelo Dureghello, Eugen Hristev,
	Kuan-Wei Chiu, Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel

Heya Casey,

On Wednesday, 3 June 2026 at 11:47 PM, Casey Connolly <casey.connolly@linaro.org> wrote:

> Hi Sam,
> 
> (CC list definitely needs some tuning on the next revision XD)

Hmm? Is it incorrect to use `b4 prep --auto-to-cc` nowadays?

> 
> On 6/1/26 10:12, Sam Day via B4 Relay wrote:
> > From: Sam Day <me@samcday.com>
> >
> > Many (often fused) bootloaders on older ARMv7 qcom SoCs do not support
> > FDTs at all, and instead pass along ATAGS in r2.
> >
> > Minimal support for parsing memory info out of these tags is introduced,
> > so that we can support mainline devicetrees, which expect the bootloader
> > to populate /memory nodes.
> 
> I think this should go its own armv7-specific file. It would probably
> also make sense to just have a separate implementation of
> board_fdt_blob_setup() since it's already really quite complicated.

I was considering that as well but decided against it, since sprinkling #ifdef
everywhere is quite ugly, and the ATAGS handling code is quite minimal. Are you
sure it really needs to be split out?

> 
> The SMEM series will do a bit of rework, in the next spin I'll probably
> move the caching stuff out as well, maybe I should also take
> board_fdt_blob_setup() then the file can be arm64 specific?

I'm not sure how we can have a separate version of board_fdt_blob_setup. On
ARMv7, sometimes you'll br receiving ATAGS in r2, sometimes it'll be FDT. It
depends on which bootloader you're chaining from.

e.g my nokia-fame can run U-Boot directly chained from SBL3 since the bootchain
on this device has been broken enough, in which case U-Boot gets ATAGS. My
samsung-expressltexx chains from lk2nd, in which case U-Boot gets an FDT.

Cheers,
-Sam

> 
> >
> > Signed-off-by: Sam Day <me@samcday.com>
> > ---
> >   arch/arm/mach-snapdragon/board.c | 119 ++++++++++++++++++++++++++++++---------
> >   1 file changed, 91 insertions(+), 28 deletions(-)
> >
> > diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
> > index 627b566d178..753983467a0 100644
> > --- a/arch/arm/mach-snapdragon/board.c
> > +++ b/arch/arm/mach-snapdragon/board.c
> > @@ -11,6 +11,7 @@
> >
> >   #include <asm/gpio.h>
> >   #include <asm/io.h>
> > +#include <asm/setup.h>
> >   #include <asm/system.h>
> >   #include <dm/device.h>
> >   #include <dm/pinctrl.h>
> > @@ -175,6 +176,67 @@ static int qcom_parse_memory(const void *fdt)
> >   	return 0;
> >   }
> >
> > +static bool qcom_atags_valid(const phys_addr_t p)
> > +{
> > +	const struct tag *tags = (const struct tag *)p;
> > +
> > +	return tags && tags->hdr.tag == ATAG_CORE &&
> > +	       tags->hdr.size >= sizeof(struct tag_header) / sizeof(u32);
> > +}
> > +
> > +static int qcom_parse_atags(const struct tag *tags)
> > +{
> > +	phys_addr_t ram_end = 0;
> > +	const struct tag *t;
> > +	bool atags_end = false;
> > +	u32 words = 0;
> > +	int j = 0;
> > +
> > +	memset(prevbl_ddr_banks, 0, sizeof(prevbl_ddr_banks));
> > +
> > +	for (t = tags; words < SZ_16K / sizeof(u32); t = tag_next(t)) {
> > +		if (t->hdr.tag == ATAG_NONE) {
> > +			atags_end = true;
> > +			break;
> > +		}
> > +		if (t->hdr.size < sizeof(struct tag_header) / sizeof(u32))
> > +			return -EINVAL;
> > +		if (t->hdr.size > SZ_16K / sizeof(u32) - words)
> > +			return -EINVAL;
> > +
> > +		words += t->hdr.size;
> > +
> > +		if (t->hdr.tag != ATAG_MEM)
> > +			continue;
> > +		if (t->hdr.size < tag_size(tag_mem32))
> > +			return -EINVAL;
> > +		if (!t->u.mem.size)
> > +			continue;
> > +
> > +		prevbl_ddr_banks[j].start = t->u.mem.start;
> > +		prevbl_ddr_banks[j].size = t->u.mem.size;
> > +		ram_end = max(ram_end, (phys_addr_t)t->u.mem.start + t->u.mem.size);
> > +		j++;
> > +
> > +		if (j == CONFIG_NR_DRAM_BANKS)
> > +			break;
> > +	}
> > +
> > +	if (!atags_end && j < CONFIG_NR_DRAM_BANKS) {
> > +		log_err("Provided more memory banks than we can handle\n");
> > +		return -EINVAL;
> > +	}
> > +	if (!j)
> > +		return -ENODATA;
> > +
> > +	qsort(prevbl_ddr_banks, j, sizeof(prevbl_ddr_banks[0]), ddr_bank_cmp);
> > +
> > +	gd->ram_base = prevbl_ddr_banks[0].start;
> > +	gd->ram_size = ram_end - gd->ram_base;
> > +
> > +	return 0;
> > +}
> > +
> >   static void show_psci_version(void)
> >   {
> >   #ifdef CONFIG_ARM64
> > @@ -227,42 +289,52 @@ static void qcom_psci_fixup(void *fdt)
> >    */
> >   int board_fdt_blob_setup(void **fdtp)
> >   {
> > -	struct fdt_header *external_fdt, *internal_fdt;
> > -	bool internal_valid, external_valid;
> > -	int ret = -ENODATA;
> > -
> > -	internal_fdt = (struct fdt_header *)*fdtp;
> > -	external_fdt = (struct fdt_header *)get_prev_bl_fdt_addr();
> > -	external_valid = external_fdt && !fdt_check_header(external_fdt);
> > -	internal_valid = !fdt_check_header(internal_fdt);
> > +	int ret = -ENODATA, setup_ret = -EEXIST;
> > +	struct fdt_header *internal_fdt = *fdtp;
> > +	phys_addr_t prev_bl_arg = get_prev_bl_fdt_addr();
> > +	bool internal_valid = internal_fdt && !fdt_check_header(internal_fdt);
> > +	bool external_is_fdt = prev_bl_arg &&
> > +			       !fdt_check_header((const void *)prev_bl_arg);
> >
> > -	/*
> > -	 * There is no point returning an error here, U-Boot can't do anything useful in this situation.
> > -	 * Bail out while we can still print a useful error message.
> > -	 */
> > -	if (!internal_valid && !external_valid)
> > +	if (internal_valid) {
> > +		debug("Using built in FDT\n");
> > +	} else if (external_is_fdt) {
> > +		debug("Using external FDT\n");
> > +		*fdtp = (void *)prev_bl_arg;
> > +		setup_ret = 0;
> > +	} else {
> > +		/*
> > +		 * There is no point returning an error here, U-Boot can't do
> > +		 * anything useful in this situation. Bail out while we can
> > +		 * still print a useful error message.
> > +		 */
> >   		panic("Internal FDT is invalid and no external FDT was provided! (fdt=%p)\n",
> > -		      external_fdt);
> > +		      (void *)prev_bl_arg);
> > +	}
> >
> >   	/* Prefer memory information from internal DT if it's present */
> >   	if (internal_valid)
> >   		ret = qcom_parse_memory(internal_fdt);
> >
> > -	if (ret < 0 && external_valid) {
> > +	if (ret < 0 && prev_bl_arg) {
> >   		/* No internal FDT or it lacks a proper /memory node.
> >   		 * The previous bootloader handed us something, let's try that.
> >   		 */
> >   		if (internal_valid)
> >   			debug("No memory info in internal FDT, falling back to external\n");
> >
> > -		ret = qcom_parse_memory(external_fdt);
> > +		/* the prev BL arg is either an FDT or ATAGS */
> > +		if (external_is_fdt)
> > +			ret = qcom_parse_memory((const void *)prev_bl_arg);
> > +		if (ret < 0 && qcom_atags_valid(prev_bl_arg))
> > +			ret = qcom_parse_atags((const struct tag *)prev_bl_arg);
> >   	}
> >
> >   	if (ret < 0)
> >   		panic("No valid memory ranges found!\n");
> >
> > -	/* If we have an external FDT, it can only have come from the Android bootloader. */
> > -	if (external_valid)
> > +	/* If we have a prev BL arg, we assume it came from ABL */
> > +	if (prev_bl_arg)
> >   		qcom_boot_source = QCOM_BOOT_SOURCE_ANDROID;
> >   	else
> >   		qcom_boot_source = QCOM_BOOT_SOURCE_XBL;
> > @@ -270,18 +342,9 @@ int board_fdt_blob_setup(void **fdtp)
> >   	debug("ram_base = %#011lx, ram_size = %#011llx\n",
> >   	      gd->ram_base, (unsigned long long)gd->ram_size);
> >
> > -	if (internal_valid) {
> > -		debug("Using built in FDT\n");
> > -		ret = -EEXIST;
> > -	} else {
> > -		debug("Using external FDT\n");
> > -		*fdtp = external_fdt;
> > -		ret = 0;
> > -	}
> > -
> >   	qcom_psci_fixup(*fdtp);
> >
> > -	return ret;
> > +	return setup_ret;
> >   }
> >
> >   /*
> >
> 
>

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

* Re: [PATCH RESEND 12/16] mach-snapdragon: parse incoming ARM32 ATAGS
  2026-06-03 22:27     ` Sam Day
@ 2026-06-04 15:01       ` Casey Connolly
  2026-06-07  3:41         ` Sam Day
  0 siblings, 1 reply; 26+ messages in thread
From: Casey Connolly @ 2026-06-04 15:01 UTC (permalink / raw)
  To: Sam Day
  Cc: Sumit Garg, u-boot-qcom, u-boot, Neil Armstrong, Tom Rini,
	Stephan Gerhold, Michal Simek, Angelo Dureghello, Eugen Hristev,
	Kuan-Wei Chiu, Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel



On 6/4/26 00:27, Sam Day wrote:
> Heya Casey,
> 
> On Wednesday, 3 June 2026 at 11:47 PM, Casey Connolly <casey.connolly@linaro.org> wrote:
> 
>> Hi Sam,
>>
>> (CC list definitely needs some tuning on the next revision XD)
> 
> Hmm? Is it incorrect to use `b4 prep --auto-to-cc` nowadays?

Urgh yeah I think this is a U-Boot issue with MAINTAINERS, needs some 
improvement but not your fault.
> 
>>
>> On 6/1/26 10:12, Sam Day via B4 Relay wrote:
>>> From: Sam Day <me@samcday.com>
>>>
>>> Many (often fused) bootloaders on older ARMv7 qcom SoCs do not support
>>> FDTs at all, and instead pass along ATAGS in r2.
>>>
>>> Minimal support for parsing memory info out of these tags is introduced,
>>> so that we can support mainline devicetrees, which expect the bootloader
>>> to populate /memory nodes.
>>
>> I think this should go its own armv7-specific file. It would probably
>> also make sense to just have a separate implementation of
>> board_fdt_blob_setup() since it's already really quite complicated.
> 
> I was considering that as well but decided against it, since sprinkling #ifdef
> everywhere is quite ugly, and the ATAGS handling code is quite minimal. Are you
> sure it really needs to be split out?

I would have the two implementations in different files
> 
>>
>> The SMEM series will do a bit of rework, in the next spin I'll probably
>> move the caching stuff out as well, maybe I should also take
>> board_fdt_blob_setup() then the file can be arm64 specific?
> 
> I'm not sure how we can have a separate version of board_fdt_blob_setup. On
> ARMv7, sometimes you'll br receiving ATAGS in r2, sometimes it'll be FDT. It
> depends on which bootloader you're chaining from.

I see, can we impose any limitations on this in practise? If not then I 
guess this is fine. I'd like to see all this logic cleaned up a bit as 
I'm just worried about introducing bugs

At the very least I'd like it if the atags parsing was moved to a 
different file then here we can do if 
(CONFIG_IS_ENABLED(...SNAPDRAGON_ARM32)
	qcom_parse_atags()

the compiler will optimise out the function call so there's no need for 
a stub version

> 
> e.g my nokia-fame can run U-Boot directly chained from SBL3 since the bootchain
> on this device has been broken enough, in which case U-Boot gets ATAGS. My
> samsung-expressltexx chains from lk2nd, in which case U-Boot gets an FDT.
> 
> Cheers,
> -Sam
> 
>>
>>>
>>> Signed-off-by: Sam Day <me@samcday.com>
>>> ---
>>>    arch/arm/mach-snapdragon/board.c | 119 ++++++++++++++++++++++++++++++---------
>>>    1 file changed, 91 insertions(+), 28 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
>>> index 627b566d178..753983467a0 100644
>>> --- a/arch/arm/mach-snapdragon/board.c
>>> +++ b/arch/arm/mach-snapdragon/board.c
>>> @@ -11,6 +11,7 @@
>>>
>>>    #include <asm/gpio.h>
>>>    #include <asm/io.h>
>>> +#include <asm/setup.h>
>>>    #include <asm/system.h>
>>>    #include <dm/device.h>
>>>    #include <dm/pinctrl.h>
>>> @@ -175,6 +176,67 @@ static int qcom_parse_memory(const void *fdt)
>>>    	return 0;
>>>    }
>>>
>>> +static bool qcom_atags_valid(const phys_addr_t p)
>>> +{
>>> +	const struct tag *tags = (const struct tag *)p;
>>> +
>>> +	return tags && tags->hdr.tag == ATAG_CORE &&
>>> +	       tags->hdr.size >= sizeof(struct tag_header) / sizeof(u32);
>>> +}
>>> +
>>> +static int qcom_parse_atags(const struct tag *tags)
>>> +{
>>> +	phys_addr_t ram_end = 0;
>>> +	const struct tag *t;
>>> +	bool atags_end = false;
>>> +	u32 words = 0;
>>> +	int j = 0;
>>> +
>>> +	memset(prevbl_ddr_banks, 0, sizeof(prevbl_ddr_banks));
>>> +
>>> +	for (t = tags; words < SZ_16K / sizeof(u32); t = tag_next(t)) {
>>> +		if (t->hdr.tag == ATAG_NONE) {
>>> +			atags_end = true;
>>> +			break;
>>> +		}
>>> +		if (t->hdr.size < sizeof(struct tag_header) / sizeof(u32))
>>> +			return -EINVAL;
>>> +		if (t->hdr.size > SZ_16K / sizeof(u32) - words)
>>> +			return -EINVAL;
>>> +
>>> +		words += t->hdr.size;
>>> +
>>> +		if (t->hdr.tag != ATAG_MEM)
>>> +			continue;
>>> +		if (t->hdr.size < tag_size(tag_mem32))
>>> +			return -EINVAL;
>>> +		if (!t->u.mem.size)
>>> +			continue;
>>> +
>>> +		prevbl_ddr_banks[j].start = t->u.mem.start;
>>> +		prevbl_ddr_banks[j].size = t->u.mem.size;
>>> +		ram_end = max(ram_end, (phys_addr_t)t->u.mem.start + t->u.mem.size);
>>> +		j++;
>>> +
>>> +		if (j == CONFIG_NR_DRAM_BANKS)
>>> +			break;
>>> +	}
>>> +
>>> +	if (!atags_end && j < CONFIG_NR_DRAM_BANKS) {
>>> +		log_err("Provided more memory banks than we can handle\n");
>>> +		return -EINVAL;
>>> +	}
>>> +	if (!j)
>>> +		return -ENODATA;
>>> +
>>> +	qsort(prevbl_ddr_banks, j, sizeof(prevbl_ddr_banks[0]), ddr_bank_cmp);
>>> +
>>> +	gd->ram_base = prevbl_ddr_banks[0].start;
>>> +	gd->ram_size = ram_end - gd->ram_base;
>>> +
>>> +	return 0;
>>> +}
>>> +
>>>    static void show_psci_version(void)
>>>    {
>>>    #ifdef CONFIG_ARM64
>>> @@ -227,42 +289,52 @@ static void qcom_psci_fixup(void *fdt)
>>>     */
>>>    int board_fdt_blob_setup(void **fdtp)
>>>    {
>>> -	struct fdt_header *external_fdt, *internal_fdt;
>>> -	bool internal_valid, external_valid;
>>> -	int ret = -ENODATA;
>>> -
>>> -	internal_fdt = (struct fdt_header *)*fdtp;
>>> -	external_fdt = (struct fdt_header *)get_prev_bl_fdt_addr();
>>> -	external_valid = external_fdt && !fdt_check_header(external_fdt);
>>> -	internal_valid = !fdt_check_header(internal_fdt);
>>> +	int ret = -ENODATA, setup_ret = -EEXIST;
>>> +	struct fdt_header *internal_fdt = *fdtp;
>>> +	phys_addr_t prev_bl_arg = get_prev_bl_fdt_addr();
>>> +	bool internal_valid = internal_fdt && !fdt_check_header(internal_fdt);
>>> +	bool external_is_fdt = prev_bl_arg &&
>>> +			       !fdt_check_header((const void *)prev_bl_arg);
>>>
>>> -	/*
>>> -	 * There is no point returning an error here, U-Boot can't do anything useful in this situation.
>>> -	 * Bail out while we can still print a useful error message.
>>> -	 */
>>> -	if (!internal_valid && !external_valid)
>>> +	if (internal_valid) {
>>> +		debug("Using built in FDT\n");
>>> +	} else if (external_is_fdt) {
>>> +		debug("Using external FDT\n");
>>> +		*fdtp = (void *)prev_bl_arg;
>>> +		setup_ret = 0;
>>> +	} else {
>>> +		/*
>>> +		 * There is no point returning an error here, U-Boot can't do
>>> +		 * anything useful in this situation. Bail out while we can
>>> +		 * still print a useful error message.
>>> +		 */
>>>    		panic("Internal FDT is invalid and no external FDT was provided! (fdt=%p)\n",
>>> -		      external_fdt);
>>> +		      (void *)prev_bl_arg);
>>> +	}
>>>
>>>    	/* Prefer memory information from internal DT if it's present */
>>>    	if (internal_valid)
>>>    		ret = qcom_parse_memory(internal_fdt);
>>>
>>> -	if (ret < 0 && external_valid) {
>>> +	if (ret < 0 && prev_bl_arg) {
>>>    		/* No internal FDT or it lacks a proper /memory node.
>>>    		 * The previous bootloader handed us something, let's try that.
>>>    		 */
>>>    		if (internal_valid)
>>>    			debug("No memory info in internal FDT, falling back to external\n");
>>>
>>> -		ret = qcom_parse_memory(external_fdt);
>>> +		/* the prev BL arg is either an FDT or ATAGS */
>>> +		if (external_is_fdt)
>>> +			ret = qcom_parse_memory((const void *)prev_bl_arg);
>>> +		if (ret < 0 && qcom_atags_valid(prev_bl_arg))
>>> +			ret = qcom_parse_atags((const struct tag *)prev_bl_arg);
>>>    	}
>>>
>>>    	if (ret < 0)
>>>    		panic("No valid memory ranges found!\n");
>>>
>>> -	/* If we have an external FDT, it can only have come from the Android bootloader. */
>>> -	if (external_valid)
>>> +	/* If we have a prev BL arg, we assume it came from ABL */
>>> +	if (prev_bl_arg)
>>>    		qcom_boot_source = QCOM_BOOT_SOURCE_ANDROID;
>>>    	else
>>>    		qcom_boot_source = QCOM_BOOT_SOURCE_XBL;
>>> @@ -270,18 +342,9 @@ int board_fdt_blob_setup(void **fdtp)
>>>    	debug("ram_base = %#011lx, ram_size = %#011llx\n",
>>>    	      gd->ram_base, (unsigned long long)gd->ram_size);
>>>
>>> -	if (internal_valid) {
>>> -		debug("Using built in FDT\n");
>>> -		ret = -EEXIST;
>>> -	} else {
>>> -		debug("Using external FDT\n");
>>> -		*fdtp = external_fdt;
>>> -		ret = 0;
>>> -	}
>>> -
>>>    	qcom_psci_fixup(*fdtp);
>>>
>>> -	return ret;
>>> +	return setup_ret;
>>>    }
>>>
>>>    /*
>>>
>>
>>


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

* Re: [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support
  2026-06-01  8:12 [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Sam Day via B4 Relay
                   ` (16 preceding siblings ...)
  2026-06-01  8:16 ` [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Luca Weiss
@ 2026-06-06 21:36 ` Antony Kurniawan Soemardi
  2026-06-06 23:18   ` Sam Day
  17 siblings, 1 reply; 26+ messages in thread
From: Antony Kurniawan Soemardi @ 2026-06-06 21:36 UTC (permalink / raw)
  To: me, Sumit Garg, u-boot-qcom, u-boot
  Cc: Casey Connolly, Neil Armstrong, Tom Rini, Stephan Gerhold,
	Michal Simek, Angelo Dureghello, Eugen Hristev, Kuan-Wei Chiu,
	Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Rayagonda Kokatanur, Tien Fong Chee, Peng Fan,
	Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut, Tingting Meng,
	Alice Guo, Quentin Schulz, Ilias Apalodimas, Luca Weiss,
	Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel

On 6/1/2026 3:12 PM, Sam Day via B4 Relay wrote:
> ** Resending because I found new ways to dislike Proton Mail (it failed
> the series midway due to "spamming". Sigh.). **
> 
> This patch series introduces support for ARMv7 Qualcomm SoCs, starting
> with MSM8960/MSM8930/MSM8227.
> 
> An overview of the changes:
>   * serial_msm reintroduces the previous packed RX/TX software mode
>     operation, as this is compatible with all UARTDM versions (1.4 and
>     older). It's added alongside the newer single-char mode for 1.4.
>   * A timer driver is introduced for KPSS. I don't know if *all* ARMv7
>     qcom SoCs lack generic ARM CP15 debug timer support, but at least
>     MSM8960/MSM8930 do.
>   * mach-snapdragon board code is shuffled around a bit to build cleanly
>     on ARM64.
>   * prev_bl_data support is extended to ARM32 (which uses r2 for passing
>     FDT/ATAGS pointers, rather than r0)
>   * qcom_parse_memory is revised to support arm32 memory nodes (which are
>     1-cell rather than 2-cell).
>   * Basic ATAGS support is introduced, so that the memory info can be
>     used from previous bootloaders that do not understand FDTs at all.
>   * PS_HOLD sysreset and pinctrl-qcom needed some minor tweaks to handle
>     some nuances that challenge the current assumptions.
>   * A pinctrl driver is introduced for MSM8960.
>   * Initial MSM8960 GCC infra is introduced.
> 
> I tested this series on:
>   * Nokia Lumia 520 (msm8227). No working buttons yet as these are
>     exposed as GPIO-over-PMIC-over-SSBI (drivers will be proposed at a
>     later date).
>   * Samsung Galaxy Express GT-I8730 (msm8930). Volume rockers + home
>     button are working via the new pinctrl-msm8960 driver. Power
>     button not working yet (needs PMIC driver infra).
>   * I have no msm8960/apq8064 devices, looking for folks to test those.
> 
> To confirm there was no regressions with ARM64 and/or newer devices, I
> also tested on:
>   * db410c (msm8916)
>   * google-sargo (sdm670)
> 
> Signed-off-by: Sam Day <me@samcday.com>
> ---
> Sam Day (16):
>        serial: msm: UARTDM <1.4 support
>        timer: Qualcomm KPSS timer support
>        arm: save_prev_bl_data: ARM32 support
>        mach-snapdragon: qcom_parse_memory 32-bit support
>        mach-snapdragon: gate ARM64 features
>        mach-snapdragon: introduce ARCH_SNAPDRAGON_ARM32
>        configs: introduce qcom_armv7_defconfig
>        board: qualcomm: add MSM8960 debug UART config
>        sysreset: qcom-pshold: offset support
>        pinctrl: qcom: configurable GPIO offset/stride
>        pinctrl: qcom: introduce MSM8960 driver
>        mach-snapdragon: parse incoming ARM32 ATAGS
>        clk: qcom: MSM8960 GCC driver
>        clk: qcom: arch-agnostic pointer fmtstrings
>        serial: msm: wait for TX empty before reinit
>        button: remap phone HOMEPAGE button
> 
>   arch/arm/Kconfig                             |  11 +-
>   arch/arm/lib/save_prev_bl_data.c             |  49 ++++---
>   arch/arm/mach-snapdragon/Kconfig             |   6 +
>   arch/arm/mach-snapdragon/board.c             | 188 ++++++++++++++++++--------
>   arch/arm/mach-snapdragon/include/mach/gpio.h |  12 +-
>   board/qualcomm/debug-msm8960.config          |   5 +
>   configs/qcom_armv7_defconfig                 |  61 +++++++++
>   drivers/button/Kconfig                       |   2 +-
>   drivers/button/button-uclass.c               |   1 +
>   drivers/clk/qcom/Kconfig                     |   8 ++
>   drivers/clk/qcom/Makefile                    |   1 +
>   drivers/clk/qcom/clock-msm8960.c             | 189 +++++++++++++++++++++++++++
>   drivers/clk/qcom/clock-qcom.c                |   8 +-
>   drivers/gpio/msm_gpio.c                      |   2 +-
>   drivers/pinctrl/qcom/Kconfig                 |   9 ++
>   drivers/pinctrl/qcom/Makefile                |   1 +
>   drivers/pinctrl/qcom/pinctrl-msm8960.c       | 135 +++++++++++++++++++
>   drivers/pinctrl/qcom/pinctrl-qcom.c          |   2 +-
>   drivers/serial/serial_msm.c                  | 142 +++++++++++++++++---
>   drivers/sysreset/sysreset_qcom-pshold.c      |   9 +-
>   drivers/timer/Kconfig                        |   7 +
>   drivers/timer/Makefile                       |   1 +
>   drivers/timer/qcom-kpss-timer.c              |  98 ++++++++++++++
>   23 files changed, 843 insertions(+), 104 deletions(-)
> ---
> base-commit: 8d3ba3753bdb5068884196ff696cc48177bfdda5
> change-id: 20260530-qcom-armv7-1486308a835c
> 
> Best regards,

This looks great! I have a Sony Xperia SP (MSM8960T) and would like to 
test it.

Before I dive in, I need to clarify the build setup:

- For cross-compilation, should I use `CROSS_COMPILE=arm-none-eabi-`?
- Which defconfig is appropriate for the Xperia SP?
- Is the config generated with `make qcom_armv7_defconfig 
qcom-phone.config`?

Would appreciate a quick pointer on the build workflow.

-- 
Thanks,
Antony K. S.

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

* Re: [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support
  2026-06-06 21:36 ` Antony Kurniawan Soemardi
@ 2026-06-06 23:18   ` Sam Day
  0 siblings, 0 replies; 26+ messages in thread
From: Sam Day @ 2026-06-06 23:18 UTC (permalink / raw)
  To: Antony Kurniawan Soemardi
  Cc: Sumit Garg, u-boot-qcom, u-boot, Casey Connolly, Neil Armstrong,
	Tom Rini, Stephan Gerhold, Michal Simek, Angelo Dureghello,
	Eugen Hristev, Kuan-Wei Chiu, Yao Zi, Simon Glass, Sughosh Ganu,
	George Chan, Rayagonda Kokatanur, Tien Fong Chee, Peng Fan,
	Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut, Tingting Meng,
	Alice Guo, Quentin Schulz, Ilias Apalodimas, Luca Weiss,
	Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel

Hi Antony,

On Sunday, 7 June 2026 at 7:37 AM, Antony Kurniawan Soemardi <linux@smankusors.com> wrote:

> On 6/1/2026 3:12 PM, Sam Day via B4 Relay wrote:
> > ** Resending because I found new ways to dislike Proton Mail (it failed
> > the series midway due to "spamming". Sigh.). **
> >
> > This patch series introduces support for ARMv7 Qualcomm SoCs, starting
> > with MSM8960/MSM8930/MSM8227.
> >
> > An overview of the changes:
> >   * serial_msm reintroduces the previous packed RX/TX software mode
> >     operation, as this is compatible with all UARTDM versions (1.4 and
> >     older). It's added alongside the newer single-char mode for 1.4.
> >   * A timer driver is introduced for KPSS. I don't know if *all* ARMv7
> >     qcom SoCs lack generic ARM CP15 debug timer support, but at least
> >     MSM8960/MSM8930 do.
> >   * mach-snapdragon board code is shuffled around a bit to build cleanly
> >     on ARM64.
> >   * prev_bl_data support is extended to ARM32 (which uses r2 for passing
> >     FDT/ATAGS pointers, rather than r0)
> >   * qcom_parse_memory is revised to support arm32 memory nodes (which are
> >     1-cell rather than 2-cell).
> >   * Basic ATAGS support is introduced, so that the memory info can be
> >     used from previous bootloaders that do not understand FDTs at all.
> >   * PS_HOLD sysreset and pinctrl-qcom needed some minor tweaks to handle
> >     some nuances that challenge the current assumptions.
> >   * A pinctrl driver is introduced for MSM8960.
> >   * Initial MSM8960 GCC infra is introduced.
> >
> > I tested this series on:
> >   * Nokia Lumia 520 (msm8227). No working buttons yet as these are
> >     exposed as GPIO-over-PMIC-over-SSBI (drivers will be proposed at a
> >     later date).
> >   * Samsung Galaxy Express GT-I8730 (msm8930). Volume rockers + home
> >     button are working via the new pinctrl-msm8960 driver. Power
> >     button not working yet (needs PMIC driver infra).
> >   * I have no msm8960/apq8064 devices, looking for folks to test those.
> >
> > To confirm there was no regressions with ARM64 and/or newer devices, I
> > also tested on:
> >   * db410c (msm8916)
> >   * google-sargo (sdm670)
> >
> > Signed-off-by: Sam Day <me@samcday.com>
> > ---
> > Sam Day (16):
> >        serial: msm: UARTDM <1.4 support
> >        timer: Qualcomm KPSS timer support
> >        arm: save_prev_bl_data: ARM32 support
> >        mach-snapdragon: qcom_parse_memory 32-bit support
> >        mach-snapdragon: gate ARM64 features
> >        mach-snapdragon: introduce ARCH_SNAPDRAGON_ARM32
> >        configs: introduce qcom_armv7_defconfig
> >        board: qualcomm: add MSM8960 debug UART config
> >        sysreset: qcom-pshold: offset support
> >        pinctrl: qcom: configurable GPIO offset/stride
> >        pinctrl: qcom: introduce MSM8960 driver
> >        mach-snapdragon: parse incoming ARM32 ATAGS
> >        clk: qcom: MSM8960 GCC driver
> >        clk: qcom: arch-agnostic pointer fmtstrings
> >        serial: msm: wait for TX empty before reinit
> >        button: remap phone HOMEPAGE button
> >
> >   arch/arm/Kconfig                             |  11 +-
> >   arch/arm/lib/save_prev_bl_data.c             |  49 ++++---
> >   arch/arm/mach-snapdragon/Kconfig             |   6 +
> >   arch/arm/mach-snapdragon/board.c             | 188 ++++++++++++++++++--------
> >   arch/arm/mach-snapdragon/include/mach/gpio.h |  12 +-
> >   board/qualcomm/debug-msm8960.config          |   5 +
> >   configs/qcom_armv7_defconfig                 |  61 +++++++++
> >   drivers/button/Kconfig                       |   2 +-
> >   drivers/button/button-uclass.c               |   1 +
> >   drivers/clk/qcom/Kconfig                     |   8 ++
> >   drivers/clk/qcom/Makefile                    |   1 +
> >   drivers/clk/qcom/clock-msm8960.c             | 189 +++++++++++++++++++++++++++
> >   drivers/clk/qcom/clock-qcom.c                |   8 +-
> >   drivers/gpio/msm_gpio.c                      |   2 +-
> >   drivers/pinctrl/qcom/Kconfig                 |   9 ++
> >   drivers/pinctrl/qcom/Makefile                |   1 +
> >   drivers/pinctrl/qcom/pinctrl-msm8960.c       | 135 +++++++++++++++++++
> >   drivers/pinctrl/qcom/pinctrl-qcom.c          |   2 +-
> >   drivers/serial/serial_msm.c                  | 142 +++++++++++++++++---
> >   drivers/sysreset/sysreset_qcom-pshold.c      |   9 +-
> >   drivers/timer/Kconfig                        |   7 +
> >   drivers/timer/Makefile                       |   1 +
> >   drivers/timer/qcom-kpss-timer.c              |  98 ++++++++++++++
> >   23 files changed, 843 insertions(+), 104 deletions(-)
> > ---
> > base-commit: 8d3ba3753bdb5068884196ff696cc48177bfdda5
> > change-id: 20260530-qcom-armv7-1486308a835c
> >
> > Best regards,
> 
> This looks great! I have a Sony Xperia SP (MSM8960T) and would like to
> test it.

Awesome, I look forward to seeing more qcom armv7 devices booting U-Boot!

> 
> Before I dive in, I need to clarify the build setup:
> 
> - For cross-compilation, should I use `CROSS_COMPILE=arm-none-eabi-`?

Yes, that's right.

> - Which defconfig is appropriate for the Xperia SP?
> - Is the config generated with `make qcom_armv7_defconfig
> qcom-phone.config`?

Yep. You might consider tacking debug-msm8960.config to the end as well, to
enable debug UART.

> 
> Would appreciate a quick pointer on the build workflow.

I think you've just about nailed it already :) If you have any further
questions don't hesitate to DM me on Matrix: @human:samcday.com

Warm Regards,
-Sam

> 
> --
> Thanks,
> Antony K. S.
>

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

* Re: [PATCH RESEND 15/16] serial: msm: wait for TX empty before reinit
  2026-06-01  8:41   ` Stephan Gerhold
@ 2026-06-07  1:26     ` Sam Day
  0 siblings, 0 replies; 26+ messages in thread
From: Sam Day @ 2026-06-07  1:26 UTC (permalink / raw)
  To: Stephan Gerhold
  Cc: Sumit Garg, u-boot-qcom, u-boot, Casey Connolly, Neil Armstrong,
	Tom Rini, Michal Simek, Angelo Dureghello, Eugen Hristev,
	Kuan-Wei Chiu, Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel

Hey Stephan,

On Monday, 1 June 2026 at 6:41 PM, Stephan Gerhold <stephan.gerhold@linaro.org> wrote:

> On Mon, Jun 01, 2026 at 06:12:56PM +1000, Sam Day via B4 Relay wrote:
> > From: Sam Day <me@samcday.com>
> >
> > At least on UARTDM 1.3, I was noticing the early UART debug banner
> > getting corrupted. It turns out this is because U-Boot was
> > re-initializing the UARTDM block and writing to it before it had
> > finished shifting out the FIFO from the previous bootloader. Waiting for
> > TX_EMPTY in the status register consistently fixes the issue.
> >
> > Signed-off-by: Sam Day <me@samcday.com>
> > ---
> >  drivers/serial/serial_msm.c | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/drivers/serial/serial_msm.c b/drivers/serial/serial_msm.c
> > index 10948e2aede..db085d68a0d 100644
> > --- a/drivers/serial/serial_msm.c
> > +++ b/drivers/serial/serial_msm.c
> > @@ -351,6 +351,8 @@ static inline void _debug_uart_init(void)
> >  	 *   - HMIBSC: GCC_BLSP1_UART1_APPS_CLK
> >  	 */
> >  	//apq8016_clk_init_uart(0x1800000, <uart_clk_id>);
> > +	while (!(readl(init_serial_data.base + UARTDM_SR) & UARTDM_SR_TX_EMPTY))
> > +		;
> 
> I think you need to add some timeout here. There is some funky SoC where
> the UART is left in some half-disabled state and this bit will never
> become unset. Maybe it was MSM8909, I don't remember exactly. I have
> similar code in TF-A and there I had to add the timeout to prevent the
> device from getting completely stuck during boot sometimes because of
> this loop:
> 
> https://github.com/ARM-software/arm-trusted-firmware/blob/da738d5eae93af342fdc4995dd3c05acb4c9d757/plat/qti/bear/msm8916/aarch32/uartdm_console.S#L68-L81

Thanks, that makes sense. v2 will bound this wait loop to 10ms.

-Sam

> 
> Thanks,
> Stephan
>

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

* Re: [PATCH RESEND 12/16] mach-snapdragon: parse incoming ARM32 ATAGS
  2026-06-04 15:01       ` Casey Connolly
@ 2026-06-07  3:41         ` Sam Day
  0 siblings, 0 replies; 26+ messages in thread
From: Sam Day @ 2026-06-07  3:41 UTC (permalink / raw)
  To: Casey Connolly
  Cc: Sumit Garg, u-boot-qcom, u-boot, Neil Armstrong, Tom Rini,
	Stephan Gerhold, Michal Simek, Angelo Dureghello, Eugen Hristev,
	Kuan-Wei Chiu, Yao Zi, Simon Glass, Sughosh Ganu, George Chan,
	Antony Kurniawan Soemardi, Rayagonda Kokatanur, Tien Fong Chee,
	Peng Fan, Alif Zakuan Yuslaimi, Anshul Dalal, Marek Vasut,
	Tingting Meng, Alice Guo, Quentin Schulz, Ilias Apalodimas,
	Luca Weiss, Aswin Murugan, David Wronek, Danila Tikhonov,
	Varadarajan Narayanan, Lukasz Majewski, Balaji Selvanathan,
	Jens Reidel

Hej Casey,

On Friday, 5 June 2026 at 1:01 AM, Casey Connolly <casey.connolly@linaro.org> wrote:

> 
> 
> On 6/4/26 00:27, Sam Day wrote:
> > Heya Casey,
> >
> > On Wednesday, 3 June 2026 at 11:47 PM, Casey Connolly <casey.connolly@linaro.org> wrote:
> >
> >> Hi Sam,
> >>
> >> (CC list definitely needs some tuning on the next revision XD)
> >
> > Hmm? Is it incorrect to use `b4 prep --auto-to-cc` nowadays?
> 
> Urgh yeah I think this is a U-Boot issue with MAINTAINERS, needs some
> improvement but not your fault.
> >
> >>
> >> On 6/1/26 10:12, Sam Day via B4 Relay wrote:
> >>> From: Sam Day <me@samcday.com>
> >>>
> >>> Many (often fused) bootloaders on older ARMv7 qcom SoCs do not support
> >>> FDTs at all, and instead pass along ATAGS in r2.
> >>>
> >>> Minimal support for parsing memory info out of these tags is introduced,
> >>> so that we can support mainline devicetrees, which expect the bootloader
> >>> to populate /memory nodes.
> >>
> >> I think this should go its own armv7-specific file. It would probably
> >> also make sense to just have a separate implementation of
> >> board_fdt_blob_setup() since it's already really quite complicated.
> >
> > I was considering that as well but decided against it, since sprinkling #ifdef
> > everywhere is quite ugly, and the ATAGS handling code is quite minimal. Are you
> > sure it really needs to be split out?
> 
> I would have the two implementations in different files
> >
> >>
> >> The SMEM series will do a bit of rework, in the next spin I'll probably
> >> move the caching stuff out as well, maybe I should also take
> >> board_fdt_blob_setup() then the file can be arm64 specific?
> >
> > I'm not sure how we can have a separate version of board_fdt_blob_setup. On
> > ARMv7, sometimes you'll br receiving ATAGS in r2, sometimes it'll be FDT. It
> > depends on which bootloader you're chaining from.
> 
> I see, can we impose any limitations on this in practise?

I'm not sure what you mean here. If we want U-Boot to support chaining from
fused bootloaders on ARMv7 qcom devices, then we need to meet them where
they're at.

> If not then I
> guess this is fine. I'd like to see all this logic cleaned up a bit as
> I'm just worried about introducing bugs

FWIW, I share your concern (remember that my fingerprints are on this
unhinged function too xD) and I spent quite a bit of time looking at this
before proposing it. I also tested it on sdm845/sdm670. Happy to address
any further specific concerns you have, though.

Otherwise, it's starting to look like maybe we should abandon the
"big tent" aspirations? I have no issues with respinning this series to
introduce a separate mach-snapdragon-armv7 to avoid any potential breakages
for newer hardware. As you can see, these older SoCs are different enough
from "modern qcom" that we're not really gaining much by co-habitating
everything.

> 
> At the very least I'd like it if the atags parsing was moved to a
> different file then here we can do if
> (CONFIG_IS_ENABLED(...SNAPDRAGON_ARM32)
> 	qcom_parse_atags()

I've queued up that change for v2. Note that it's still slightly messy.
The anonymous prevbl_ddr_banks struct definition and ddr_bank_cmp prototype
need to be hoisted into qcom-priv.h so that atags.c can use them.

> 
> the compiler will optimise out the function call so there's no need for
> a stub version

Huh, TIL. That's very useful to know thanks :D

Peace,
-Sam

> 
> >
> > e.g my nokia-fame can run U-Boot directly chained from SBL3 since the bootchain
> > on this device has been broken enough, in which case U-Boot gets ATAGS. My
> > samsung-expressltexx chains from lk2nd, in which case U-Boot gets an FDT.
> >
> > Cheers,
> > -Sam
> >
> >>
> >>>
> >>> Signed-off-by: Sam Day <me@samcday.com>
> >>> ---
> >>>    arch/arm/mach-snapdragon/board.c | 119 ++++++++++++++++++++++++++++++---------
> >>>    1 file changed, 91 insertions(+), 28 deletions(-)
> >>>
> >>> diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
> >>> index 627b566d178..753983467a0 100644
> >>> --- a/arch/arm/mach-snapdragon/board.c
> >>> +++ b/arch/arm/mach-snapdragon/board.c
> >>> @@ -11,6 +11,7 @@
> >>>
> >>>    #include <asm/gpio.h>
> >>>    #include <asm/io.h>
> >>> +#include <asm/setup.h>
> >>>    #include <asm/system.h>
> >>>    #include <dm/device.h>
> >>>    #include <dm/pinctrl.h>
> >>> @@ -175,6 +176,67 @@ static int qcom_parse_memory(const void *fdt)
> >>>    	return 0;
> >>>    }
> >>>
> >>> +static bool qcom_atags_valid(const phys_addr_t p)
> >>> +{
> >>> +	const struct tag *tags = (const struct tag *)p;
> >>> +
> >>> +	return tags && tags->hdr.tag == ATAG_CORE &&
> >>> +	       tags->hdr.size >= sizeof(struct tag_header) / sizeof(u32);
> >>> +}
> >>> +
> >>> +static int qcom_parse_atags(const struct tag *tags)
> >>> +{
> >>> +	phys_addr_t ram_end = 0;
> >>> +	const struct tag *t;
> >>> +	bool atags_end = false;
> >>> +	u32 words = 0;
> >>> +	int j = 0;
> >>> +
> >>> +	memset(prevbl_ddr_banks, 0, sizeof(prevbl_ddr_banks));
> >>> +
> >>> +	for (t = tags; words < SZ_16K / sizeof(u32); t = tag_next(t)) {
> >>> +		if (t->hdr.tag == ATAG_NONE) {
> >>> +			atags_end = true;
> >>> +			break;
> >>> +		}
> >>> +		if (t->hdr.size < sizeof(struct tag_header) / sizeof(u32))
> >>> +			return -EINVAL;
> >>> +		if (t->hdr.size > SZ_16K / sizeof(u32) - words)
> >>> +			return -EINVAL;
> >>> +
> >>> +		words += t->hdr.size;
> >>> +
> >>> +		if (t->hdr.tag != ATAG_MEM)
> >>> +			continue;
> >>> +		if (t->hdr.size < tag_size(tag_mem32))
> >>> +			return -EINVAL;
> >>> +		if (!t->u.mem.size)
> >>> +			continue;
> >>> +
> >>> +		prevbl_ddr_banks[j].start = t->u.mem.start;
> >>> +		prevbl_ddr_banks[j].size = t->u.mem.size;
> >>> +		ram_end = max(ram_end, (phys_addr_t)t->u.mem.start + t->u.mem.size);
> >>> +		j++;
> >>> +
> >>> +		if (j == CONFIG_NR_DRAM_BANKS)
> >>> +			break;
> >>> +	}
> >>> +
> >>> +	if (!atags_end && j < CONFIG_NR_DRAM_BANKS) {
> >>> +		log_err("Provided more memory banks than we can handle\n");
> >>> +		return -EINVAL;
> >>> +	}
> >>> +	if (!j)
> >>> +		return -ENODATA;
> >>> +
> >>> +	qsort(prevbl_ddr_banks, j, sizeof(prevbl_ddr_banks[0]), ddr_bank_cmp);
> >>> +
> >>> +	gd->ram_base = prevbl_ddr_banks[0].start;
> >>> +	gd->ram_size = ram_end - gd->ram_base;
> >>> +
> >>> +	return 0;
> >>> +}
> >>> +
> >>>    static void show_psci_version(void)
> >>>    {
> >>>    #ifdef CONFIG_ARM64
> >>> @@ -227,42 +289,52 @@ static void qcom_psci_fixup(void *fdt)
> >>>     */
> >>>    int board_fdt_blob_setup(void **fdtp)
> >>>    {
> >>> -	struct fdt_header *external_fdt, *internal_fdt;
> >>> -	bool internal_valid, external_valid;
> >>> -	int ret = -ENODATA;
> >>> -
> >>> -	internal_fdt = (struct fdt_header *)*fdtp;
> >>> -	external_fdt = (struct fdt_header *)get_prev_bl_fdt_addr();
> >>> -	external_valid = external_fdt && !fdt_check_header(external_fdt);
> >>> -	internal_valid = !fdt_check_header(internal_fdt);
> >>> +	int ret = -ENODATA, setup_ret = -EEXIST;
> >>> +	struct fdt_header *internal_fdt = *fdtp;
> >>> +	phys_addr_t prev_bl_arg = get_prev_bl_fdt_addr();
> >>> +	bool internal_valid = internal_fdt && !fdt_check_header(internal_fdt);
> >>> +	bool external_is_fdt = prev_bl_arg &&
> >>> +			       !fdt_check_header((const void *)prev_bl_arg);
> >>>
> >>> -	/*
> >>> -	 * There is no point returning an error here, U-Boot can't do anything useful in this situation.
> >>> -	 * Bail out while we can still print a useful error message.
> >>> -	 */
> >>> -	if (!internal_valid && !external_valid)
> >>> +	if (internal_valid) {
> >>> +		debug("Using built in FDT\n");
> >>> +	} else if (external_is_fdt) {
> >>> +		debug("Using external FDT\n");
> >>> +		*fdtp = (void *)prev_bl_arg;
> >>> +		setup_ret = 0;
> >>> +	} else {
> >>> +		/*
> >>> +		 * There is no point returning an error here, U-Boot can't do
> >>> +		 * anything useful in this situation. Bail out while we can
> >>> +		 * still print a useful error message.
> >>> +		 */
> >>>    		panic("Internal FDT is invalid and no external FDT was provided! (fdt=%p)\n",
> >>> -		      external_fdt);
> >>> +		      (void *)prev_bl_arg);
> >>> +	}
> >>>
> >>>    	/* Prefer memory information from internal DT if it's present */
> >>>    	if (internal_valid)
> >>>    		ret = qcom_parse_memory(internal_fdt);
> >>>
> >>> -	if (ret < 0 && external_valid) {
> >>> +	if (ret < 0 && prev_bl_arg) {
> >>>    		/* No internal FDT or it lacks a proper /memory node.
> >>>    		 * The previous bootloader handed us something, let's try that.
> >>>    		 */
> >>>    		if (internal_valid)
> >>>    			debug("No memory info in internal FDT, falling back to external\n");
> >>>
> >>> -		ret = qcom_parse_memory(external_fdt);
> >>> +		/* the prev BL arg is either an FDT or ATAGS */
> >>> +		if (external_is_fdt)
> >>> +			ret = qcom_parse_memory((const void *)prev_bl_arg);
> >>> +		if (ret < 0 && qcom_atags_valid(prev_bl_arg))
> >>> +			ret = qcom_parse_atags((const struct tag *)prev_bl_arg);
> >>>    	}
> >>>
> >>>    	if (ret < 0)
> >>>    		panic("No valid memory ranges found!\n");
> >>>
> >>> -	/* If we have an external FDT, it can only have come from the Android bootloader. */
> >>> -	if (external_valid)
> >>> +	/* If we have a prev BL arg, we assume it came from ABL */
> >>> +	if (prev_bl_arg)
> >>>    		qcom_boot_source = QCOM_BOOT_SOURCE_ANDROID;
> >>>    	else
> >>>    		qcom_boot_source = QCOM_BOOT_SOURCE_XBL;
> >>> @@ -270,18 +342,9 @@ int board_fdt_blob_setup(void **fdtp)
> >>>    	debug("ram_base = %#011lx, ram_size = %#011llx\n",
> >>>    	      gd->ram_base, (unsigned long long)gd->ram_size);
> >>>
> >>> -	if (internal_valid) {
> >>> -		debug("Using built in FDT\n");
> >>> -		ret = -EEXIST;
> >>> -	} else {
> >>> -		debug("Using external FDT\n");
> >>> -		*fdtp = external_fdt;
> >>> -		ret = 0;
> >>> -	}
> >>> -
> >>>    	qcom_psci_fixup(*fdtp);
> >>>
> >>> -	return ret;
> >>> +	return setup_ret;
> >>>    }
> >>>
> >>>    /*
> >>>
> >>
> >>
> 
>

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

end of thread, other threads:[~2026-06-07  5:11 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-01  8:12 [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Sam Day via B4 Relay
2026-06-01  8:12 ` [PATCH RESEND 01/16] serial: msm: UARTDM <1.4 support Sam Day via B4 Relay
2026-06-01  8:12 ` [PATCH RESEND 02/16] timer: Qualcomm KPSS timer support Sam Day via B4 Relay
2026-06-01  8:12 ` [PATCH RESEND 03/16] arm: save_prev_bl_data: ARM32 support Sam Day via B4 Relay
2026-06-01  8:12 ` [PATCH RESEND 04/16] mach-snapdragon: qcom_parse_memory 32-bit support Sam Day via B4 Relay
2026-06-01  8:12 ` [PATCH RESEND 05/16] mach-snapdragon: gate ARM64 features Sam Day via B4 Relay
2026-06-01  8:12 ` [PATCH RESEND 06/16] mach-snapdragon: introduce ARCH_SNAPDRAGON_ARM32 Sam Day via B4 Relay
2026-06-01  8:12 ` [PATCH RESEND 07/16] configs: introduce qcom_armv7_defconfig Sam Day via B4 Relay
2026-06-01  8:12 ` [PATCH RESEND 08/16] board: qualcomm: add MSM8960 debug UART config Sam Day via B4 Relay
2026-06-01  8:12 ` [PATCH RESEND 09/16] sysreset: qcom-pshold: offset support Sam Day via B4 Relay
2026-06-01  8:12 ` [PATCH RESEND 10/16] pinctrl: qcom: configurable GPIO offset/stride Sam Day via B4 Relay
2026-06-01  8:12 ` [PATCH RESEND 11/16] pinctrl: qcom: introduce MSM8960 driver Sam Day via B4 Relay
2026-06-01  8:12 ` [PATCH RESEND 12/16] mach-snapdragon: parse incoming ARM32 ATAGS Sam Day via B4 Relay
2026-06-03 13:47   ` Casey Connolly
2026-06-03 22:27     ` Sam Day
2026-06-04 15:01       ` Casey Connolly
2026-06-07  3:41         ` Sam Day
2026-06-01  8:12 ` [PATCH RESEND 13/16] clk: qcom: MSM8960 GCC driver Sam Day via B4 Relay
2026-06-01  8:12 ` [PATCH RESEND 14/16] clk: qcom: arch-agnostic pointer fmtstrings Sam Day via B4 Relay
2026-06-01  8:12 ` [PATCH RESEND 15/16] serial: msm: wait for TX empty before reinit Sam Day via B4 Relay
2026-06-01  8:41   ` Stephan Gerhold
2026-06-07  1:26     ` Sam Day
2026-06-01  8:12 ` [PATCH RESEND 16/16] button: remap phone HOMEPAGE button Sam Day via B4 Relay
2026-06-01  8:16 ` [PATCH RESEND 00/16] MSM8960 / mach-snapdragon ARMv7 support Luca Weiss
2026-06-06 21:36 ` Antony Kurniawan Soemardi
2026-06-06 23:18   ` Sam Day

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