Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
cdfeda6
tee: optee: Export OP-TEE message UID check API
b49020 Jan 22, 2026
53cd27d
mach-snapdragon: of_fixup: Add OP-TEE DT fixup support
b49020 Dec 29, 2025
387b3e2
board/qualcomm: Introduce TF-A and OP-TEE config fragment
b49020 Jan 22, 2026
fe1e923
fs: fat: Handle 'FAT sector size mismatch'
varada-qcom Jan 22, 2026
26a7fb0
mach-snapdragon: Add generic SMEM cache infrastructure
aswinm94 Jan 23, 2026
0dcc1fe
mach-snapdragon: Add FIT multi-DTB selection support
aswinm94 Jan 23, 2026
c1ac060
configs: snapdragon: Enable FIT multi-DTB and configure IMEM
aswinm94 Jan 27, 2026
9f7088e
Add device tree fixup handler infrastructure to support runtime modif…
aswinm94 Jan 28, 2026
2670e64
firmware: psci: Refactor EFI runtime PSCI reset handling
aswinm94 Jan 14, 2026
56da4df
qcom_defconfig: Disable CONFIG_EFI_PSCI_RESET_RUNTIME
aswinm94 Jan 14, 2026
e52e169
mach-snapdragon:: Add support for fastboot reboot reason detection
aswinm94 Jan 8, 2026
146ade7
arm: snapdragon: Add EFI reserved memory regions for QCS615/QCM6490
balajiselvanathan Jan 7, 2026
f1200eb
arm: dts: qcs615-ride: Remove unsupported USB clock reference
balajiselvanathan Jan 20, 2026
36b2dfb
clk: qcom: qcs615: Add GCC_AHB2PHY_WEST_CLK clock support
balajiselvanathan Jan 20, 2026
aa0ea70
phy: qcom: qusb2: Add QCS615 QUSB2 PHY support
balajiselvanathan Jan 20, 2026
5be382b
dts: qcs6490-rb3gen2: Switch USB controller to peripheral mode
balajiselvanathan Nov 14, 2025
0427e68
drivers: clk: qcom: sc7280: Add USB3 PHY pipe clock
balajiselvanathan Dec 3, 2025
3121fcd
drivers: usb: dwc3: Add delay after core soft reset
balajiselvanathan Dec 3, 2025
5b7b957
drivers: phy: qcom: Add QMP USB3-DP Combo PHY driver
balajiselvanathan Dec 3, 2025
e167968
arch: arm: mach-snapdragon: Auto-detect USB SSPHY driver support
balajiselvanathan Dec 3, 2025
6092792
configs: qcm6490: Enable super-speed USB support
balajiselvanathan Dec 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions arch/arm/dts/qcs615-ride-u-boot.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,18 @@
<0x0 0xc0000000 0x0 0xc0000000>,
<0x1 0x80000000 0x1 0x00000000>;
};
soc@0 {
/* Remove GCC_USB3_PRIM_CLKREF_CLK from usb_1 node to avoid U-Boot clock warnings */
usb_1: usb@a6f8800 {
/delete-property/ clocks;
/delete-property/ clock-names;
/* Keep only the clocks that are implemented in U-Boot clock driver */
clocks = <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>,
<&gcc GCC_USB30_PRIM_MASTER_CLK>,
<&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>,
<&gcc GCC_USB30_PRIM_SLEEP_CLK>,
<&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>;
clock-names = "cfg_noc", "core", "iface", "sleep", "mock_utmi";
};
};
};
2 changes: 1 addition & 1 deletion arch/arm/dts/qcs6490-rb3gen2-u-boot.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
};

&usb_1 {
dr_mode = "host";
dr_mode = "peripheral";
};

// RAM Entry 0 : Base 0x0080000000 Size 0x003A800000
Expand Down
18 changes: 18 additions & 0 deletions arch/arm/mach-snapdragon/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,22 @@ config SYS_CONFIG_NAME
Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
will be used for board configuration.

config QCOM_FIT_MULTIDTB
bool "Enable FIT multi-DTB selection for Qualcomm platforms"
depends on FIT
help
Enable FIT multi-DTB selection for Qualcomm platforms.
This allows U-Boot to select the appropriate device tree
from a FIT image based on board parameters like SoC ID,
platform ID, variant ID, OEM variant ID, foundry ID, etc.

config QCOM_IMEM_SIZE
hex "QCOM IMEM size"
default 0x0
help
Platform-specific IMEM size for calculating shared IMEM base address.
Set to 0x2B000 (172KB) for most platforms or 0x59000 (356KB) for
LeMans/Monaco. If not set (0x0), boot device detection will return
default UFS type.

endif
5 changes: 5 additions & 0 deletions arch/arm/mach-snapdragon/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,9 @@

obj-y += board.o
obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += capsule_update.o
obj-$(CONFIG_EFI_LOADER) += qcom_reserved_memory.o
obj-$(CONFIG_OF_LIVE) += qcom_fixup_boardinfo.o
obj-$(CONFIG_OF_LIVE) += qcom_fixup_ddrinfo.o
obj-$(CONFIG_OF_LIVE) += qcom_fixup_subsetparts.o
obj-$(CONFIG_OF_LIVE) += of_fixup.o
obj-$(CONFIG_QCOM_FIT_MULTIDTB) += qcom_fit_multidtb.o
268 changes: 268 additions & 0 deletions arch/arm/mach-snapdragon/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <dm/uclass-internal.h>
#include <dm/read.h>
#include <power/regulator.h>
#include <power/pmic.h>
#include <env.h>
#include <fdt_support.h>
#include <init.h>
Expand All @@ -30,15 +31,47 @@
#include <malloc.h>
#include <fdt_support.h>
#include <usb.h>
#include <smem.h>
#include <sort.h>
#include <time.h>
#include <command.h>

#include "qcom_fit_multidtb.h"
#include "qcom-priv.h"

/* Reboot mode definitions */
#define QCOM_REBOOT_MODE_FASTBOOT 0x2
#define QCOM_REBOOT_MODE_MASK 0xFE

/* PON (Power On) register addresses - Gen 4 PMICs */
#define QCOM_PON_BASE_ADDR 0x800
#define QCOM_PON_PERPH_SUBTYPE (QCOM_PON_BASE_ADDR + 0x5)
#define QCOM_PON_SOFT_RB_SPARE (QCOM_PON_BASE_ADDR + 0x8F)

/* PON register addresses - Newer PMICs (SDAM-based) */
#define QCOM_PON_REBOOT_REASON_SDAM 0x7148

/* PMIC Revision ID registers */
#define QCOM_PMIC_REVID_BASE 0x0100
#define QCOM_PMIC_METAL_REV (QCOM_PMIC_REVID_BASE + 0x02)

/* PMIC identification values */
#define QCOM_PMIC_TYPE_QC 0x51
#define QCOM_PMIC_SUBTYPE_GEN4 0x4
#define QCOM_PMIC_MODEL_PM855 30
#define QCOM_PMIC_MODEL_INVALID 0x00

DECLARE_GLOBAL_DATA_PTR;

enum qcom_boot_source qcom_boot_source __section(".data") = 0;

/* SMEM cache structure */
static struct {
struct udevice *smem_dev;
struct socinfo *soc_info;
struct usable_ram_partition_table *ram_partition_table;
} smem_cache;

static struct mm_region rbx_mem_map[CONFIG_NR_DRAM_BANKS + 2] = { { 0 } };

struct mm_region *mem_map = rbx_mem_map;
Expand Down Expand Up @@ -489,6 +522,125 @@ static void configure_env(void)
qcom_set_serialno();
}

/**
* detect_pmic_model() - Detect PMIC model from revision ID registers
* @dev: PMIC device
*
* Reads the PMIC revision ID registers to identify the PMIC model.
* This is used to determine which register addresses to use for
* reading the reboot reason.
*
* Return: PMIC model number or QCOM_PMIC_MODEL_INVALID on error
*/
static int detect_pmic_model(struct udevice *dev)
{
u8 rev_id[4] = {0};
int ret, i;
u8 pmic_model;

/* Read 4 bytes from PMIC REVID registers */
for (i = 0; i < 4; i++) {
ret = pmic_reg_read(dev, QCOM_PMIC_METAL_REV + i);
if (ret < 0) {
log_debug("Failed to read PMIC REVID reg 0x%X: %d\n",
QCOM_PMIC_METAL_REV + i, ret);
return QCOM_PMIC_MODEL_INVALID;
}
rev_id[i] = (u8)ret;
}

/* Verify this is a Qualcomm PMIC device */
if (rev_id[2] != QCOM_PMIC_TYPE_QC) {
log_debug("Not a Qualcomm PMIC (type=0x%02X)\n",
rev_id[2]);
return QCOM_PMIC_MODEL_INVALID;
}

pmic_model = rev_id[3];
log_debug("PMIC Model: 0x%02X (Metal=0x%02X, Layer=0x%02X)\n",
pmic_model, rev_id[0], rev_id[1]);

return pmic_model;
}

/**
* check_fastboot_mode() - Check if device should enter fastboot mode
*
* Reads the PMIC PON (Power On) register to check if the reboot reason
* indicates that fastboot mode should be entered. The register address
* varies depending on the PMIC generation.
*
* For Gen 4 PMICs: Uses PON_SOFT_RB_SPARE register
* For newer PMICs: Uses SDAM-based PON_REBOOT_REASON register
*
* If fastboot mode is detected, clears the reboot reason and enters
* fastboot mode via the "run fastboot" command.
*
* Return: 0 on success, negative error code on failure
*/
static int check_fastboot_mode(void)
{
struct udevice *dev;
int ret, reboot_reason, reg_val;
u32 pon_reset_addr;
u8 peripheral_subtype;
int pmic_model;

if (!IS_ENABLED(CONFIG_DM_PMIC))
return 0;

ret = pmic_get("pmic@0", &dev);
if (ret)
return ret;

/* Detect PMIC model for address resolution */
pmic_model = detect_pmic_model(dev);
if (pmic_model == QCOM_PMIC_MODEL_INVALID)
return -1;

peripheral_subtype = pmic_reg_read(dev, QCOM_PON_PERPH_SUBTYPE);

/* Select register address based on PMIC generation */
if (peripheral_subtype == QCOM_PMIC_SUBTYPE_GEN4)
pon_reset_addr = QCOM_PON_SOFT_RB_SPARE;
else
pon_reset_addr = QCOM_PON_REBOOT_REASON_SDAM;

log_debug("PON reg: 0x%X (subtype=0x%X, model=0x%X)\n",
pon_reset_addr, peripheral_subtype, pmic_model);

/* Read reboot reason */
reg_val = pmic_reg_read(dev, pon_reset_addr);
if (reg_val < 0) {
log_debug("Failed to read reboot reason: %d\n", reg_val);
return reg_val;
}

reboot_reason = (reg_val & QCOM_REBOOT_MODE_MASK) >> 1;
log_debug("Reboot reason: 0x%02X (raw=0x%02X)\n",
reboot_reason, reg_val);

if (reboot_reason == QCOM_REBOOT_MODE_FASTBOOT) {
log_info("Fastboot mode detected, entering fastboot...\n");

/* Clear reboot reason */
reg_val &= (~QCOM_REBOOT_MODE_MASK);

if (pmic_model == QCOM_PMIC_MODEL_PM855)
pon_reset_addr = QCOM_PON_SOFT_RB_SPARE;

ret = pmic_reg_write(dev, pon_reset_addr, reg_val);
if (ret != 0)
log_warning("Failed to clear reboot reason (%d)\n",
ret);

/* Enter fastboot mode */
ret = run_command("run fastboot", 0);
}

return ret;
}

void qcom_show_boot_source(void)
{
const char *name = "UNKNOWN";
Expand Down Expand Up @@ -573,6 +725,15 @@ int board_late_init(void)
/* Configure the dfu_string for capsule updates */
qcom_configure_capsule_updates();

/* Check reboot reason for fastboot */
check_fastboot_mode();

/* Try FIT multi-DTB selection if enabled */
if (IS_ENABLED(CONFIG_QCOM_FIT_MULTIDTB)) {
if (qcom_fit_multidtb_setup() != 0)
log_debug("FIT multi-DTB selection not available or failed\n");
}

return 0;
}

Expand Down Expand Up @@ -709,6 +870,21 @@ static void carve_out_reserved_memory(void)
}
}

#ifdef CONFIG_EFI_LOADER
/**
* efi_add_known_memory() - Add platform-specific reserved memory to EFI map
*
* This function is called by the EFI memory initialization code to allow
* platforms to add their reserved memory regions to the EFI memory map.
* For Qualcomm platforms, this delegates to qcom_add_reserved_memory_to_efi()
* which handles SoC-specific reserved memory regions.
*/
void efi_add_known_memory(void)
{
qcom_add_reserved_memory_to_efi();
}
#endif /* CONFIG_EFI_LOADER */

/* This function open-codes setup_all_pgtables() so that we can
* insert additional mappings *before* turning on the MMU.
*/
Expand Down Expand Up @@ -749,3 +925,95 @@ void enable_caches(void)
}
dcache_enable();
}

/**
* qcom_get_smem_device() - Get cached SMEM device
*
* This function provides cached access to the SMEM device.
* On first call, it initializes the SMEM device.
* Subsequent calls return the cached pointer.
*
* Return: Pointer to SMEM device on success, NULL on failure
*/
struct udevice *qcom_get_smem_device(void)
{
/* Return cached value if already initialized */
if (smem_cache.smem_dev)
return smem_cache.smem_dev;

/* Get SMEM device */
if (uclass_get_device(UCLASS_SMEM, 0, &smem_cache.smem_dev)) {
log_err("Failed to get SMEM device\n");
return NULL;
}

return smem_cache.smem_dev;
}

/**
* qcom_get_socinfo() - Get cached socinfo from SMEM
*
* This function provides cached access to the socinfo structure from SMEM.
* On first call, it initializes the SMEM device and retrieves the socinfo.
* Subsequent calls return the cached pointer.
*
* Return: Pointer to socinfo structure on success, NULL on failure
*/
struct socinfo *qcom_get_socinfo(void)
{
size_t size;
struct udevice *dev;

/* Return cached value if already initialized */
if (smem_cache.soc_info)
return smem_cache.soc_info;

/* Get SMEM device */
dev = qcom_get_smem_device();
if (!dev)
return NULL;

/* Get socinfo from SMEM */
smem_cache.soc_info = smem_get(dev, 0, SMEM_HW_SW_BUILD_ID, &size);
if (!smem_cache.soc_info) {
log_err("Failed to get socinfo from SMEM\n");
return NULL;
}

return smem_cache.soc_info;
}

/**
* qcom_get_ram_partitions() - Get cached RAM partition table from SMEM
*
* This function provides cached access to the RAM partition table from SMEM.
* On first call, it retrieves the partition table from SMEM.
* Subsequent calls return the cached pointer.
*
* Return: Pointer to RAM partition table on success, NULL on failure
*/
struct usable_ram_partition_table *qcom_get_ram_partitions(void)
{
size_t size;
struct udevice *dev;

/* Return cached value if already initialized */
if (smem_cache.ram_partition_table)
return smem_cache.ram_partition_table;

/* Get SMEM device */
dev = qcom_get_smem_device();
if (!dev)
return NULL;

/* Get RAM partition table from SMEM */
smem_cache.ram_partition_table = smem_get(dev, 0,
SMEM_USABLE_RAM_PARTITION_TABLE,
&size);
if (!smem_cache.ram_partition_table) {
log_err("Failed to get RAM partition table from SMEM\n");
return NULL;
}

return smem_cache.ram_partition_table;
}
Loading