[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