diff --git a/src/soc/qualcomm/x1p42100/Makefile.mk b/src/soc/qualcomm/x1p42100/Makefile.mk index dbb125aff9..cfb8410e60 100644 --- a/src/soc/qualcomm/x1p42100/Makefile.mk +++ b/src/soc/qualcomm/x1p42100/Makefile.mk @@ -56,6 +56,7 @@ ramstage-$(CONFIG_PCI) += ../common/pcie_common.c ramstage-y += ../common/spmi.c ramstage-$(CONFIG_PCI) += pcie.c ramstage-y += cpucp_load_reset.c +ramstage-y += adsp_load_reset.c ramstage-y += ../common/cmd_db.c ramstage-y += ../common/rpmh.c ../common/rpmh_bcm.c ../common/rpmh_regulator.c ../common/rpmh_rsc.c ramstage-y += rpmh_rsc_init.c @@ -249,6 +250,23 @@ $(CPUCP_DTBS_CBFS)-type := payload $(CPUCP_DTBS_CBFS)-compression := $(CBFS_COMPRESS_FLAG) cbfs-files-y += $(CPUCP_DTBS_CBFS) +################################################################################ +# ADSP (Audio DSP) Lite Firmware for Off-mode charging +################################################################################ +ADSP_LITE_FILE := $(X1P42100_BLOB)/adsp/adsp.mbn +ADSP_LITE_CBFS := $(CONFIG_CBFS_PREFIX)/adsp_lite +$(ADSP_LITE_CBFS)-file := $(ADSP_LITE_FILE) +$(ADSP_LITE_CBFS)-type := payload +$(ADSP_LITE_CBFS)-compression := $(CBFS_COMPRESS_FLAG) +cbfs-files-y += $(ADSP_LITE_CBFS) + +################################################################################ +ADSP_DTBS_FILE := $(X1P42100_BLOB)/adsp/adsp_dtbs.elf +ADSP_DTBS_CBFS := $(CONFIG_CBFS_PREFIX)/adsp_dtbs +$(ADSP_DTBS_CBFS)-file := $(ADSP_DTBS_FILE) +$(ADSP_DTBS_CBFS)-type := payload +cbfs-files-y += $(ADSP_DTBS_CBFS) + ################################################################################ SHRM_FILE := $(X1P42100_BLOB)/$(BLOB_VARIANT)/shrm/shrm.elf SHRM_CBFS := $(CONFIG_CBFS_PREFIX)/shrm diff --git a/src/soc/qualcomm/x1p42100/adsp_load_reset.c b/src/soc/qualcomm/x1p42100/adsp_load_reset.c new file mode 100644 index 0000000000..03433e8e6f --- /dev/null +++ b/src/soc/qualcomm/x1p42100/adsp_load_reset.c @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include + +/** + * lpass_program_boot_addr() - Program ADSP boot address override + * @addr: ADSP firmware entry address + * + * Program EVB address/select so Q6 boots from @addr. + */ +static void lpass_program_boot_addr(uintptr_t addr) +{ + write32(&lpass_efuse_q6ss->evb_addr, (addr>>4)); + write32(&lpass_efuse_q6ss->evb_sel, EVB_ENABLE); + dsb(); +} + +/** + * lpass_dtb_bring_up() - Configure ADSP Device Tree Boot parameters + * @dtb_entry_addr: Physical address where Device Tree image is loaded + * @dtb_size: Size of Device Tree image in bytes + * + * Configure the QDSP6SS boot parameter registers with: + * - Device Tree blob location and size + * - Chip identification (family and ID) + * - Chip version information + * - Platform type and version + * + * Boot Parameter Register Layout: + * BOOT_PARAMS[0]: DTB address (lower 32 bits) + * BOOT_PARAMS[1]: DTB address (upper 32 bits) + * BOOT_PARAMS[2]: Chip family (bits 31:16) | Chip ID (bits 15:0) + * BOOT_PARAMS[3]: Chip version - Major (bits 15:8) | Minor (bits 7:0) + * BOOT_PARAMS[4]: Platform type (bits 31:24) | Subtype (bits 23:16) | + * Version major (bits 15:8) | Version minor (bits 7:0) not programmed + * BOOT_PARAMS[5]: DTB size + * + * Return: CB_SUCCESS on success, CB_ERR on failure + */ +static enum cb_err lpass_dtb_bring_up(uintptr_t dtb_entry_addr, size_t dtb_size) +{ + uint32_t chip_family, chip_id; + uint32_t chip_major, chip_minor; + uint32_t boot_params2, boot_params3; + + write32(&lpass_qdsp6ss->boot_params[0], (uint32_t)(dtb_entry_addr & 0xFFFFFFFF)); + write32(&lpass_qdsp6ss->boot_params[1], (uint32_t)(dtb_entry_addr >> 32)); + + /* x1p42100 uses fixed SoC boot args; do not depend on SMEM init ordering. */ + + chip_family = CHIPINFO_FAMILY & CHIP_FAMILY_MASK; + chip_id = CHIPINFO_ID_SCP & CHIP_ID_MASK; + boot_params2 = (chip_family << CHIP_FAMILY_SHIFT) | chip_id; + + chip_major = CHIPINFO_CHIP_VERSION_MAJOR; + chip_minor = CHIPINFO_CHIP_VERSION_MINOR; + boot_params3 = ((chip_major & CHIP_VERSION_MASK) << CHIP_VERSION_MAJOR_SHIFT) | + (chip_minor & CHIP_VERSION_MASK); + + write32(&lpass_qdsp6ss->boot_params[2], boot_params2); + write32(&lpass_qdsp6ss->boot_params[3], boot_params3); + write32(&lpass_qdsp6ss->boot_params[5], (uint32_t)dtb_size); + dsb(); + + return CB_SUCCESS; +} + +/** + * adsp_fw_load() - Main entry point for ADSP firmware loading + * + * Orchestrate the complete ADSP firmware loading sequence: + * 1. Load ADSP Device Tree Blob from CBFS + * 2. Configure QDSP6SS boot parameters with DTB location and platform info + * 3. Load ADSP firmware from CBFS + * 4. Program ADSP boot address via EFUSE EVB registers + */ +void adsp_fw_load(void) +{ + struct prog adsp_dtbs_prog = PROG_INIT(PROG_PAYLOAD, ADSP_CBFS_DTBS); + struct prog adsp_fw_prog = PROG_INIT(PROG_PAYLOAD, ADSP_CBFS_FIRMWARE); + uintptr_t dtb_entry_addr; + uintptr_t fw_entry_addr; + size_t dtb_size; + + dtb_size = cbfs_get_size(ADSP_CBFS_DTBS); + if (dtb_size == 0) { + printk(BIOS_ERR, "ADSP: Failed to get DTBS size from CBFS\n"); + return; + } + + if (!selfload(&adsp_dtbs_prog)) { + printk(BIOS_ERR, "ADSP: DTBS load failed\n"); + return; + } + + dtb_entry_addr = (uintptr_t)prog_entry(&adsp_dtbs_prog); + + if (lpass_dtb_bring_up(dtb_entry_addr, dtb_size) != CB_SUCCESS) { + printk(BIOS_ERR, "ADSP: DTB bring up failed\n"); + return; + } + + if (!selfload(&adsp_fw_prog)) { + printk(BIOS_ERR, "ADSP: Firmware load failed\n"); + return; + } + + fw_entry_addr = (uintptr_t)prog_entry(&adsp_fw_prog); + + lpass_program_boot_addr(fw_entry_addr); + + printk(BIOS_INFO, "SOC: LPASS/ADSP image loaded successfully\n"); +} diff --git a/src/soc/qualcomm/x1p42100/include/soc/addressmap.h b/src/soc/qualcomm/x1p42100/include/soc/addressmap.h index dc45a668d6..6cb4b231e2 100644 --- a/src/soc/qualcomm/x1p42100/include/soc/addressmap.h +++ b/src/soc/qualcomm/x1p42100/include/soc/addressmap.h @@ -24,6 +24,8 @@ #define LPASS_AON_CC_BASE (LPASS_BASE + 0x00E08000) #define LPASS_AON_CC_PLL_CM_BASE (LPASS_BASE + 0x00E01000) #define LPASS_CORE_GDSC_REG_BASE (LPASS_BASE + 0x01E00000) +#define LPASS_QDSP6SS_PUB_BASE (LPASS_BASE + 0x00800000) +#define LPASS_EFUSE_Q6SS_BASE (LPASS_BASE + 0x0125B000) #define RPMH_BASE 0x17520000 #define CMD_DB_BASE_ADDR 0x81c60000 diff --git a/src/soc/qualcomm/x1p42100/include/soc/adsp.h b/src/soc/qualcomm/x1p42100/include/soc/adsp.h new file mode 100644 index 0000000000..5e156f210b --- /dev/null +++ b/src/soc/qualcomm/x1p42100/include/soc/adsp.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_QUALCOMM_X1P42100_ADSP_H__ +#define __SOC_QUALCOMM_X1P42100_ADSP_H__ + +#include +#include +#include +#include + +/* ADSP CBFS firmware paths */ +#define ADSP_CBFS_DTBS CONFIG_CBFS_PREFIX "/adsp_dtbs" +#define ADSP_CBFS_FIRMWARE CONFIG_CBFS_PREFIX "/adsp_lite" + +/* LPASS QDSP6SS Register Structure */ +struct x1p42100_lpass_qdsp6ss { + u8 _res0[0x10]; + u32 rst_evb; + u8 _res1[0x60 - 0x14]; + u32 boot_params[6]; +}; + +check_member(x1p42100_lpass_qdsp6ss, rst_evb, 0x10); +check_member(x1p42100_lpass_qdsp6ss, boot_params, 0x60); + +/* LPASS EFUSE Q6SS Register Structure */ +struct x1p42100_lpass_efuse_q6ss { + u32 evb_sel; + u32 evb_addr; +}; + +check_member(x1p42100_lpass_efuse_q6ss, evb_sel, 0x0); +check_member(x1p42100_lpass_efuse_q6ss, evb_addr, 0x4); + +static struct x1p42100_lpass_qdsp6ss *const lpass_qdsp6ss = (void *)LPASS_QDSP6SS_PUB_BASE; +static struct x1p42100_lpass_efuse_q6ss *const lpass_efuse_q6ss = (void *)LPASS_EFUSE_Q6SS_BASE; + +void adsp_fw_load(void); + +#endif /* __SOC_QUALCOMM_X1P42100_ADSP_H__ */ diff --git a/src/soc/qualcomm/x1p42100/include/soc/platform_info.h b/src/soc/qualcomm/x1p42100/include/soc/platform_info.h new file mode 100644 index 0000000000..bf27c7cb92 --- /dev/null +++ b/src/soc/qualcomm/x1p42100/include/soc/platform_info.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __SOC_QUALCOMM_X1P42100_PLATFORM_INFO_H__ +#define __SOC_QUALCOMM_X1P42100_PLATFORM_INFO_H__ + +/* ADSP BOOT_PARAMS helpers */ + +/* BOOT_PARAMS bitfield definitions */ +#define CHIP_FAMILY_MASK 0xFFFF +#define CHIP_FAMILY_SHIFT 16 +#define CHIP_ID_MASK 0xFFFF +#define CHIP_VERSION_MAJOR_SHIFT 8 +#define CHIP_VERSION_MASK 0xFF +#define PLATFORM_FIELD_MASK 0xFF +#define PLATFORM_SUBTYPE_SHIFT 16 +#define PLATFORM_TYPE_SHIFT 24 +#define PLATFORM_VERSION_MAJOR_SHIFT 8 + +#define EVB_ENABLE 1 + +/* + * ADSP BOOT_PARAMS chipinfo identifiers. + * + * Keep values as macros (no literals in packer code) to match SMEM chipinfo: + * - CHIPINFO_FAMILY_*: eChipInfoFamily + * - CHIPINFO_ID_SCP_*: eChipInfoId (SCP) + */ +#if CONFIG(SOC_QUALCOMM_HAMOA) +/* Hamoa (SC8380XP) identifiers used by ADSP BOOT_PARAMS on x1p42100 platforms. */ +#define CHIPINFO_FAMILY 0x0088 +#define CHIPINFO_ID_SCP 0x022B + +/* Hamoa chip version used for BOOT_PARAMS[3] packing. */ +#define CHIPINFO_CHIP_VERSION 0x00020000 /* nChipVersion (SMEM) */ +#define CHIPINFO_CHIP_VERSION_MAJOR 0x02 +#define CHIPINFO_CHIP_VERSION_MINOR 0x00 +#else +/* Purwa Compute (SC8340XP / X1P4x100) */ +#define CHIPINFO_FAMILY 0x009A +#define CHIPINFO_ID_SCP 0x027B + +#define CHIPINFO_CHIP_VERSION 0x00020000 /* nChipVersion (SMEM) */ +#define CHIPINFO_CHIP_VERSION_MAJOR 0x02 +#define CHIPINFO_CHIP_VERSION_MINOR 0x00 +#endif + +/* x1p42100 platform info used for BOOT_PARAMS[4] packing. */ +#define PLATFORMINFO_TYPE 0x28 /* ePlatformType */ +#define PLATFORMINFO_SUBTYPE 0x00 /* nPlatformSubtype */ +#define PLATFORMINFO_VERSION 0x00010000 /* nPlatformVersion */ +#define PLATFORMINFO_VERSION_MAJOR 0x01 +#define PLATFORMINFO_VERSION_MINOR 0x00 + +#endif /* __SOC_QUALCOMM_X1P42100_PLATFORM_INFO_H__ */