From: KR Sowmiya <[email protected]> Add support for loading the Config/Chip Data Table (CDT) from eMMC during the Shikra SPL boot flow and registering it with QCLIB via the interface table.
Signed-off-by: KR Sowmiya <[email protected]> Signed-off-by: Abhilash V <[email protected]> --- arch/arm/mach-snapdragon/Kconfig | 73 +++++++++++++++ arch/arm/mach-snapdragon/board_spl.c | 98 +++++++++++++++++++++ arch/arm/mach-snapdragon/include/mach/spl.h | 1 + arch/arm/mach-snapdragon/qclib.c | 8 ++ board/qualcomm/shikra/spl-shikra.c | 10 +++ 5 files changed, 190 insertions(+) diff --git a/arch/arm/mach-snapdragon/Kconfig b/arch/arm/mach-snapdragon/Kconfig index 9e23d6d8948..7efdc5d6dfe 100644 --- a/arch/arm/mach-snapdragon/Kconfig +++ b/arch/arm/mach-snapdragon/Kconfig @@ -76,6 +76,79 @@ config QCOM_HWDETECT Hardware parameter detection from SMEM and TCSR for DTB selection and other platform subsystems. +config QCOM_SPL_CDT_SUPPORTED + bool "Enable CDT support in SPL" + depends on SPL && (SPL_PARTITIONS || SPL_PARTITION_TYPE_GUID) + help + Enable support for reading the CDT off the boot medium during + SPL and staging it in IMEM, so that QCLIB can pick it up via + the interface table. + +if QCOM_SPL_CDT_SUPPORTED + +choice + prompt "CDT partition lookup method" + default QCOM_SPL_CDT_USE_PARTITION_NAME + help + Locate the CDT partition on the boot media either using partition + name or partition type GUID. + +config QCOM_SPL_CDT_USE_PARTITION_NAME + bool "Look up the CDT partition by GPT partition name" + depends on SPL_PARTITIONS + help + Locate the CDT partition on the boot medium by its GPT partition + name (CONFIG_QCOM_SPL_CDT_PARTITION_NAME). + +config QCOM_SPL_CDT_USE_PARTITION_GUID + bool "Look up the CDT partition by GPT partition type GUID" + depends on SPL_PARTITION_TYPE_GUID + help + Locate the CDT partition on the boot medium by its GPT partition + type GUID (CONFIG_QCOM_SPL_CDT_PARTITION_GUID). + +endchoice + +config QCOM_SPL_CDT_PARTITION_NAME + string "CDT GPT partition name" + depends on QCOM_SPL_CDT_USE_PARTITION_NAME + default "cdt" + help + Name of the GPT partition on the boot medium containing the CDT + (Config/Chip Data Table) data. + +config QCOM_SPL_CDT_PARTITION_GUID + string "CDT GPT partition type GUID" + depends on QCOM_SPL_CDT_USE_PARTITION_GUID + default "a19f205f-ccd8-4b6d-8f1e-2d9bc24cffb1" + help + GPT partition type GUID identifying the CDT (Config/Chip Data + Table) partition on the boot medium. + +config QCOM_SPL_CDT_MMC_PARTITION_NUM + int "eMMC hardware partition containing the CDT partition" + default 0 + help + eMMC hardware partition number (0 = default user data area) on + which the CDT GPT partition is located. Ignored for non-MMC boot + media. + +config QCOM_SPL_BOOTIMEM_CDT_BASE + hex "IMEM address to stage the CDT contents at" + help + Address within BOOTIMEM where the CDT contents read from the boot + medium are staged, to be consumed by QCLIB via the interface + table. + +config QCOM_SPL_BOOTIMEM_CDT_SIZE + hex "Maximum number of bytes to stage for the CDT" + default 0x200 + help + Maximum number of bytes read from the CDT partition and staged at + CONFIG_QCOM_SPL_BOOTIMEM_CDT_BASE. + +endif # QCOM_SPL_CDT_SUPPORTED + config QCOM_TMEL_ELF string "TME Elf to concatenate with U-Boot SPL MBN image" depends on SPL && QCOM_GENERATE_MBN diff --git a/arch/arm/mach-snapdragon/board_spl.c b/arch/arm/mach-snapdragon/board_spl.c index 31a06b1e002..f1f91bf09c9 100644 --- a/arch/arm/mach-snapdragon/board_spl.c +++ b/arch/arm/mach-snapdragon/board_spl.c @@ -10,8 +10,12 @@ #include <dm/uclass.h> #include <hang.h> #include <init.h> +#include <linux/kernel.h> #include <linux/err.h> #include <mach/qclib.h> +#include <mach/spl.h> +#include <memalign.h> +#include <part.h> #include <spl.h> #include <soc/qcom/smem.h> @@ -38,6 +42,100 @@ void __weak qcom_spl_soc_rpm_reset(void) { } +if (IS_ENABLED(CONFIG_QCOM_SPL_CDT_SUPPORTED)) +/** + * qcom_spl_cdt_load() - Load the CDT from the boot medium. + * + * This functions read the boot medium for CDT information which gets saved + * in IMEM location. + * + * Return: 0 on success, or a negative error code on failure. + */ +int qcom_spl_cdt_load(void) +{ + struct blk_desc *desc; + struct disk_partition info; + lbaint_t blocks; + bool is_mmc; + int ret; + void *blk_buf = NULL; + + ret = qcom_spl_get_boot_blk_desc(&desc); + if (ret) { + pr_debug("CDT: boot device not supported for CDT staging (%d)\n", + ret); + return ret; + } + + is_mmc = desc->uclass_id == UCLASS_MMC; + if (is_mmc) { + ret = blk_dselect_hwpart(desc, CONFIG_QCOM_SPL_CDT_MMC_PARTITION_NUM); + if (ret) + return ret; + + part_init(desc); + } + +#if defined(CONFIG_QCOM_SPL_CDT_USE_PARTITION_NAME) + ret = part_get_info_by_name(desc, CONFIG_QCOM_SPL_CDT_PARTITION_NAME, &info); +#elif defined(CONFIG_QCOM_SPL_CDT_USE_PARTITION_GUID) + ret = part_get_info_by_type_guid(desc, CONFIG_QCOM_SPL_CDT_PARTITION_GUID, + &info); +#else + ret = -EINVAL; +#endif + if (ret < 0) { + pr_err("CDT: partition not found (%d)\n", ret); + goto restore_hwpart; + } + + blocks = DIV_ROUND_UP(CONFIG_QCOM_SPL_BOOTIMEM_CDT_SIZE, info.blksz); + if (blocks > info.size) + blocks = info.size; + + { + blk_buf = malloc_cache_aligned(blocks * info.blksz); + + if (!blk_buf) { + ret = -ENOMEM; + goto restore_hwpart; + } + + size_t read_size = blocks * info.blksz; + size_t copy_size = min_t(size_t, CONFIG_QCOM_SPL_BOOTIMEM_CDT_SIZE, + read_size); + + if (blk_dread(desc, info.start, blocks, blk_buf) != blocks) { + pr_err("CDT: failed to read CDT partition\n"); + ret = -EIO; + goto restore_hwpart; + } + + memcpy((u8 *)CONFIG_QCOM_SPL_BOOTIMEM_CDT_BASE, blk_buf, copy_size); + } + + ret = 0; + +restore_hwpart: + free(blk_buf); + + /* Restore the default hardware partition, if eMMC. */ + if (is_mmc) { + int rc = blk_dselect_hwpart(desc, 0); + + if (rc) { + if (!ret) + ret = rc; + return ret; + } + + part_init(desc); + } + + return ret; +} +#endif + /** * qcom_spl_get_boot_blk_desc() - Get the boot medium's block device. * @descp: Set to the resolved block device on success. diff --git a/arch/arm/mach-snapdragon/include/mach/spl.h b/arch/arm/mach-snapdragon/include/mach/spl.h index a32a85c48fd..ed3e5910e7a 100644 --- a/arch/arm/mach-snapdragon/include/mach/spl.h +++ b/arch/arm/mach-snapdragon/include/mach/spl.h @@ -12,5 +12,6 @@ void qcom_spl_malloc_init_f(void); int qcom_spl_loader_pre_ddr(u8 boot_device); void qcom_spl_error_handler(void *arg); int qcom_spl_get_boot_blk_desc(struct blk_desc **descp); +int qcom_spl_cdt_load(void); #endif /* __SPL_H__ */ diff --git a/arch/arm/mach-snapdragon/qclib.c b/arch/arm/mach-snapdragon/qclib.c index b9a74863c1c..1c03df7ef77 100644 --- a/arch/arm/mach-snapdragon/qclib.c +++ b/arch/arm/mach-snapdragon/qclib.c @@ -123,6 +123,14 @@ int __weak qclib_populate_interface_table(struct interface_table *if_tbl, if (ret) return ret; +#if IS_ENABLED(CONFIG_QCOM_SPL_CDT_SUPPORTED) + ret = qclib_add_iftbl_entry(if_tbl, CONFIG_QCOM_SPL_CDT_PARTITION_NAME, + CONFIG_QCOM_SPL_BOOTIMEM_CDT_BASE, + CONFIG_QCOM_SPL_BOOTIMEM_CDT_SIZE); + if (ret) + return ret; +#endif + return qcom_spl_soc_qclib_override(if_tbl, fit, images_node); } diff --git a/board/qualcomm/shikra/spl-shikra.c b/board/qualcomm/shikra/spl-shikra.c index c2a5d2d692b..94d005f65ea 100644 --- a/board/qualcomm/shikra/spl-shikra.c +++ b/board/qualcomm/shikra/spl-shikra.c @@ -12,6 +12,7 @@ #include <dm/uclass.h> #include <init.h> #include <linux/err.h> +#include <linux/kernel.h> #include <linux/sizes.h> #include <linux/string.h> #include <malloc.h> @@ -333,6 +334,12 @@ fail: reset_cpu(); } #endif + +/** + * qcom_spl_soc_qclib_override() - Populate Shikra-specific interface table. + * + * Adds Shikra-specific blobs/entries to the QCLIB interface table. + */ int qcom_spl_soc_qclib_override(struct interface_table *table, const void *fit, int images_node) { @@ -383,6 +390,9 @@ int qcom_spl_soc_pre_qclib_routine(void) { qcom_spl_soc_shrm_reset(); + if (IS_ENABLED(CONFIG_QCOM_SPL_CDT_SUPPORTED)) + return qcom_spl_cdt_load(); + return 0; } -- 2.34.1
