[PATCH v2 08/10] arm: K3: sysfw-loader: Add a config_pm_pre_callback()
Jaehoon Chung
jh80.chung at samsung.com
Wed Jan 29 00:30:44 CET 2020
On 1/24/20 8:52 PM, Faiz Abbas wrote:
> System firmware does not guarantee that clocks going out of the device
> will be stable during power management configuration. There are some
> DCRC errors when SPL tries to get the next stage during eMMC boot after
> sysfw pm configuration.
>
> Therefore add a config_pm_pre_callback() to switch off the eMMC clock
> before power management and restart it after it is done.
>
> Signed-off-by: Faiz Abbas <faiz_abbas at ti.com>
> Signed-off-by: Lokesh Vutla <lokeshvutla at ti.com>
> ---
> arch/arm/mach-k3/am6_init.c | 33 +++++++++++++++++++-
> arch/arm/mach-k3/include/mach/sysfw-loader.h | 2 +-
> arch/arm/mach-k3/j721e_init.c | 33 +++++++++++++++++++-
> arch/arm/mach-k3/sysfw-loader.c | 6 +++-
> 4 files changed, 70 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/mach-k3/am6_init.c b/arch/arm/mach-k3/am6_init.c
> index 8d107b870b..9d3c62b3f4 100644
> --- a/arch/arm/mach-k3/am6_init.c
> +++ b/arch/arm/mach-k3/am6_init.c
> @@ -17,6 +17,7 @@
> #include <dm/uclass-internal.h>
> #include <dm/pinctrl.h>
> #include <linux/soc/ti/ti_sci_protocol.h>
> +#include <mmc.h>
>
> #ifdef CONFIG_SPL_BUILD
> #ifdef CONFIG_K3_LOAD_SYSFW
> @@ -86,6 +87,33 @@ static void store_boot_index_from_rom(void)
> bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX);
> }
>
> +#if defined(CONFIG_K3_LOAD_SYSFW)
> +void k3_mmc_stop_clock(void)
> +{
> + if (spl_boot_device() == BOOT_DEVICE_MMC1) {
> + struct mmc *mmc = find_mmc_device(0);
> +
> + if (!mmc)
> + return;
> +
> + mmc->saved_clock = mmc->clock;
> + mmc_set_clock(mmc, 0, true);
> + }
> +}
> +
> +void k3_mmc_restart_clock(void)
> +{
> + if (spl_boot_device() == BOOT_DEVICE_MMC1) {
> + struct mmc *mmc = find_mmc_device(0);
> +
> + if (!mmc)
> + return;
> +
> + mmc_set_clock(mmc, mmc->saved_clock, false);
> + }
> +}
> +#endif
> +
> void board_init_f(ulong dummy)
> {
> #if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM654_DDRSS)
> @@ -128,7 +156,10 @@ void board_init_f(ulong dummy)
> * callback hook, effectively switching on (or over) the console
> * output.
> */
> - k3_sysfw_loader(preloader_console_init);
> + k3_sysfw_loader(k3_mmc_stop_clock, k3_mmc_restart_clock);
> +
> + /* Prepare console output */
> + preloader_console_init();
>
> /* Disable ROM configured firewalls right after loading sysfw */
> #ifdef CONFIG_TI_SECURE_DEVICE
> diff --git a/arch/arm/mach-k3/include/mach/sysfw-loader.h b/arch/arm/mach-k3/include/mach/sysfw-loader.h
> index 36eb265348..6f5612b4fd 100644
> --- a/arch/arm/mach-k3/include/mach/sysfw-loader.h
> +++ b/arch/arm/mach-k3/include/mach/sysfw-loader.h
> @@ -7,6 +7,6 @@
> #ifndef _SYSFW_LOADER_H_
> #define _SYSFW_LOADER_H_
>
> -void k3_sysfw_loader(void (*config_pm_done_callback)(void));
> +void k3_sysfw_loader(void (*config_pm_pre_callback)(void), void (*config_pm_done_callback)(void));
>
> #endif
> diff --git a/arch/arm/mach-k3/j721e_init.c b/arch/arm/mach-k3/j721e_init.c
> index f7f7398081..0994522f6c 100644
> --- a/arch/arm/mach-k3/j721e_init.c
> +++ b/arch/arm/mach-k3/j721e_init.c
> @@ -18,6 +18,7 @@
> #include <dm.h>
> #include <dm/uclass-internal.h>
> #include <dm/pinctrl.h>
> +#include <mmc.h>
>
> #ifdef CONFIG_SPL_BUILD
> #ifdef CONFIG_K3_LOAD_SYSFW
> @@ -100,6 +101,33 @@ static void ctrl_mmr_unlock(void)
> mmr_unlock(CTRL_MMR0_BASE, 7);
> }
>
> +#if defined(CONFIG_K3_LOAD_SYSFW)
> +void k3_mmc_stop_clock(void)
> +{
> + if (spl_boot_device() == BOOT_DEVICE_MMC1) {
> + struct mmc *mmc = find_mmc_device(0);
> +
> + if (!mmc)
> + return;
> +
> + mmc->saved_clock = mmc->clock;
> + mmc_set_clock(mmc, 0, true);
Use MMC_CLK_DISABLE instead of true.
> + }
> +}
> +
> +void k3_mmc_restart_clock(void)
> +{
> + if (spl_boot_device() == BOOT_DEVICE_MMC1) {
> + struct mmc *mmc = find_mmc_device(0);
> +
> + if (!mmc)
> + return;
> +
> + mmc_set_clock(mmc, mmc->saved_clock, false);
ditto.
> + }
> +}
> +#endif
> +
> /*
> * This uninitialized global variable would normal end up in the .bss section,
> * but the .bss is cleared between writing and reading this variable, so move
> @@ -154,7 +182,10 @@ void board_init_f(ulong dummy)
> * callback hook, effectively switching on (or over) the console
> * output.
> */
> - k3_sysfw_loader(preloader_console_init);
> + k3_sysfw_loader(k3_mmc_stop_clock, k3_mmc_restart_clock);
> +
> + /* Prepare console output */
> + preloader_console_init();
>
> /* Disable ROM configured firewalls right after loading sysfw */
> #ifdef CONFIG_TI_SECURE_DEVICE
> diff --git a/arch/arm/mach-k3/sysfw-loader.c b/arch/arm/mach-k3/sysfw-loader.c
> index 5903bbe12a..8386499ed6 100644
> --- a/arch/arm/mach-k3/sysfw-loader.c
> +++ b/arch/arm/mach-k3/sysfw-loader.c
> @@ -172,7 +172,8 @@ static void k3_sysfw_configure_using_fit(void *fit,
> ret);
> }
>
> -void k3_sysfw_loader(void (*config_pm_done_callback)(void))
> +void k3_sysfw_loader(void (*config_pm_pre_callback) (void),
> + void (*config_pm_done_callback)(void))
> {
> struct spl_image_info spl_image = { 0 };
> struct spl_boot_device bootdev = { 0 };
> @@ -264,6 +265,9 @@ void k3_sysfw_loader(void (*config_pm_done_callback)(void))
> /* Parse and apply the different SYSFW configuration fragments */
> k3_sysfw_configure_using_fit(sysfw_load_address, ti_sci);
>
> + if (config_pm_pre_callback)
> + config_pm_pre_callback();
> +
> /*
> * Now that all clocks and PM aspects are setup, invoke a user-
> * provided callback function. Usually this callback would be used
>
More information about the U-Boot
mailing list