Prepare QUP firmware support before serial-engine children are probed during SPL initialization.
Enable QUP wrapper clocks before firmware detection. Initialize the boot MMC before the last-stage init event. This makes QUP firmware available from the boot medium. Release the dynamic firmware buffer after children are probed so SPL can reserve memory for the MMU page table. Signed-off-by: Abhilash V <[email protected]> --- board/qualcomm/shikra/spl-shikra.c | 112 +++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/board/qualcomm/shikra/spl-shikra.c b/board/qualcomm/shikra/spl-shikra.c index 358023b24e4..c2a5d2d692b 100644 --- a/board/qualcomm/shikra/spl-shikra.c +++ b/board/qualcomm/shikra/spl-shikra.c @@ -3,6 +3,7 @@ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include <blk.h> +#include <clk.h> #include <cpu_func.h> #include <asm/io.h> #include <asm/sections.h> @@ -16,6 +17,7 @@ #include <malloc.h> #include <mach/qclib.h> #include <mach/spl.h> +#include <mmc.h> #include <part.h> #include <spl.h> @@ -174,6 +176,103 @@ static int shikra_boot_device(int *mmc_seq) } #if defined(CONFIG_SPL_BUILD) +/** + * shikra_prepare_qup_clocks() - Enable QUP wrapper clocks. + * + * Enable wrapper clocks before detecting the QUP firmware state. + * + * Return: 0 on success, or a negative error code. + */ +static int shikra_prepare_qup_clocks(void) +{ + struct clk_bulk clks; + struct uclass *uc; + struct udevice *dev; + int ret; + + ret = uclass_get(UCLASS_MISC, &uc); + if (ret) + return ret; + + uclass_foreach_dev(dev, uc) { + if (!device_is_compatible(dev, "qcom,geni-se-qup")) + continue; + + ret = clk_get_bulk(dev, &clks); + if (ret) + return ret; + + ret = clk_enable_bulk(&clks); + if (ret) + clk_release_bulk(&clks); + + return ret; + } + + return -ENODEV; +} + +/** + * shikra_prepare_boot_mmc() - Initialize the boot MMC device. + * + * Make the boot MMC device available before loading QUP firmware. + * + * Return: 0 on success, or a negative error code. + */ +static int shikra_prepare_boot_mmc(void) +{ + struct udevice *dev; + struct mmc *mmc; + int boot_device, seq, ret; + + boot_device = shikra_boot_device(&seq); + if (boot_device != BOOT_DEVICE_MMC1 && boot_device != BOOT_DEVICE_MMC2) + return -ENODEV; + + ret = uclass_get_device_by_seq(UCLASS_MMC, seq, &dev); + if (ret) + return ret; + + mmc = mmc_get_mmc_dev(dev); + if (!mmc) + return -ENODEV; + + /* + * Poll SD because SPL cannot resolve its card-detect GPIO. + */ + if (boot_device == BOOT_DEVICE_MMC2) + ((struct mmc_config *)mmc->cfg)->host_caps |= MMC_CAP_NEEDS_POLL; + + return mmc_init(mmc); +} + +/** + * shikra_release_qupfw() - Free the QUP firmware buffer. + * + * Free the dynamic QUPFW buffer before allocating the MMU table. + */ +static void shikra_release_qupfw(void) +{ +#if !IS_ENABLED(CONFIG_QCOM_GENI_MINICORE) + struct uclass *uc; + struct udevice *dev; + void *fw; + + if (uclass_get(UCLASS_MISC, &uc)) + return; + + uclass_foreach_dev(dev, uc) { + if (!device_is_compatible(dev, "qcom,geni-se-qup")) + continue; + + fw = dev_get_priv(dev); + if (fw) + free(fw); + return; + } +#endif +} + void board_init_f(ulong dummy) { int ret = 0; @@ -188,7 +287,20 @@ void board_init_f(ulong dummy) goto fail; } + ret = shikra_prepare_qup_clocks(); + if (ret) { + pr_debug("failed to prepare QUP clocks (%d)\n", ret); + goto fail; + } + + ret = shikra_prepare_boot_mmc(); + if (ret) { + pr_debug("failed to prepare boot MMC (%d)\n", ret); + goto fail; + } + event_notify_null(EVT_LAST_STAGE_INIT); + shikra_release_qupfw(); preloader_console_init(); -- 2.34.1
