[RFC] rockchip: Reset to bootrom download mode on hang

Dragan Simic dsimic at manjaro.org
Fri Feb 2 05:26:58 CET 2024


Hello Jonas,

On 2024-02-02 01:12, Jonas Karlman wrote:
> Add support to reset to bootrom download mode on hang in U-Boot SPL and
> proper. ROCKCHIP_HANG_TO_BROM can be used to enable this feature.
> 
> Example when SPL cannot load FIT:
> 
>   U-Boot SPL 2024.04-rc1 (Feb 01 2024 - 23:01:12 +0000)
>   Trying to boot from MMC1
>   mmc_load_image_raw_sector: mmc block read error
>   Trying to boot from MMC2
>   Card did not respond to voltage select! : -110
>   spl: mmc init failed with error: -95
>   Trying to boot from MMC1
>   mmc_load_image_raw_sector: mmc block read error
>   SPL: failed to boot from all boot devices
>   ### ERROR ### Please RESET the board ###
>   entering download mode ...
>   resetting ...
> 
> Procedure to start bootrom download mode:
> - U-Boot SPL or proper write 0xEF08A53C to BOOT_MODE_REG and then reset
> - Bootrom loads and run boot code (TPL) from e.g. SPI > eMMC > SD-card
> - TPL check for 0xEF08A53C in BOOT_MODE_REG very early, i.e. Rockchip
>   TPL blobs check for this value directly at start
> - TPL return to bootrom with a return value != 0
> - Bootrom enter download mode
> 
> This also fixes an issue where the BOOT_MODE_REG is reset to 0 when
> board is reset on RK35xx after TF-A has been loaded. To fix this the
> SOC_CON1 reg value is reset prior to issuing a global reset.
> 
> The RK356x TF-A blobs will clear SOC_CON1 as part of a PSCI reset,
> however the RK3588 TF-A blobs does not seem to clear SOC_CON1.
> 
> Signed-off-by: Jonas Karlman <jonas at kwiboo.se>
> ---
> - Is reset to bootrom download mode on hang a feature of intereset to
>   anyone else?

I find this usable, for example during development.  Thus, I'd support
this feature to be polished further and eventually merged.

> - How can we best handle the issue with BOOT_MODE_REG being reset?
> - Should we instead enable SYSRESET_PSCI and relay on TF-A to properly
>   reset without loosing value in BOOT_MODE_REG? Currently works on
>   RK356x bl31 blobs but not on the RK3588 bl31 blobs.
> ---
>  arch/arm/mach-rockchip/Kconfig     |  9 +++++++
>  arch/arm/mach-rockchip/Makefile    |  9 ++++---
>  arch/arm/mach-rockchip/boot_mode.c | 38 ++++++++++++++++++++++++++----
>  configs/generic-rk3568_defconfig   |  1 +
>  configs/generic-rk3588_defconfig   |  1 +
>  5 files changed, 48 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm/mach-rockchip/Kconfig 
> b/arch/arm/mach-rockchip/Kconfig
> index 6ff0aa6911e2..66556d30af27 100644
> --- a/arch/arm/mach-rockchip/Kconfig
> +++ b/arch/arm/mach-rockchip/Kconfig
> @@ -508,6 +508,15 @@ config TPL_ROCKCHIP_EARLYRETURN_TO_BROM
>  	  This enables support code in the BOOT0 hook for the TPL stage
>  	  to allow multiple entries.
> 
> +config ROCKCHIP_HANG_TO_BROM
> +	bool "Reset to bootrom download mode on hang"
> +	select SHOW_BOOT_PROGRESS
> +
> +config SPL_ROCKCHIP_HANG_TO_BROM
> +	bool "Reset to bootrom download mode on hang in SPL"
> +	default y if ROCKCHIP_HANG_TO_BROM
> +	select SPL_SHOW_BOOT_PROGRESS
> +
>  config SPL_MMC
>  	default y if !SPL_ROCKCHIP_BACK_TO_BROM
> 
> diff --git a/arch/arm/mach-rockchip/Makefile 
> b/arch/arm/mach-rockchip/Makefile
> index 1dc92066bbf3..ab4446bb6b51 100644
> --- a/arch/arm/mach-rockchip/Makefile
> +++ b/arch/arm/mach-rockchip/Makefile
> @@ -16,17 +16,16 @@ obj-tpl-$(CONFIG_ROCKCHIP_PX30) += px30-board-tpl.o
>  obj-spl-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board-spl.o
> 
>  ifeq ($(CONFIG_SPL_BUILD)$(CONFIG_TPL_BUILD),)
> +obj-$(CONFIG_ROCKCHIP_COMMON_BOARD) += board.o
> +obj-$(CONFIG_MISC_INIT_R) += misc.o
> +endif
> 
> +ifeq ($(CONFIG_TPL_BUILD),)
>  # Always include boot_mode.o, as we bypass it (i.e. turn it off)
>  # inside of boot_mode.c when CONFIG_ROCKCHIP_BOOT_MODE_REG is 0.  This 
> way,
>  # we can have the preprocessor correctly recognise both 0x0 and 0
>  # meaning "turn it off".
>  obj-y += boot_mode.o
> -obj-$(CONFIG_ROCKCHIP_COMMON_BOARD) += board.o
> -obj-$(CONFIG_MISC_INIT_R) += misc.o
> -endif
> -
> -ifeq ($(CONFIG_TPL_BUILD),)
>  obj-$(CONFIG_DISPLAY_CPUINFO) += cpu-info.o
>  endif
> 
> diff --git a/arch/arm/mach-rockchip/boot_mode.c
> b/arch/arm/mach-rockchip/boot_mode.c
> index eb8f65ae4e9d..de9ec1414926 100644
> --- a/arch/arm/mach-rockchip/boot_mode.c
> +++ b/arch/arm/mach-rockchip/boot_mode.c
> @@ -5,6 +5,7 @@
> 
>  #include <common.h>
>  #include <adc.h>
> +#include <bootstage.h>
>  #include <command.h>
>  #include <env.h>
>  #include <log.h>
> @@ -23,11 +24,31 @@ int setup_boot_mode(void)
> 
>  #else
> 
> -void set_back_to_bootrom_dnl_flag(void)
> +static void set_back_to_bootrom_dnl_flag(void)
>  {
> +	/*
> +	 * These SOC_CON1 regs needs to be cleared before a reset or the
> +	 * BOOT_MODE_REG do not retain its value and it is not possible
> +	 * to reset to bootrom download mode once TF-A has been started.
> +	 *
> +	 * TF-A blobs for RK3568 already clear SOC_CON1 for PSCI reset.
> +	 * However, the TF-A blobs for RK3588 does not clear SOC_CON1.
> +	 */
> +	if (IS_ENABLED(CONFIG_ROCKCHIP_RK3568))
> +		writel(0x40000, 0xFDC20104);
> +	if (IS_ENABLED(CONFIG_ROCKCHIP_RK3588))
> +		writel(0xFFFF0000, 0xFD58A004);
> +
>  	writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG);
>  }
> 
> +static void rockchip_reset_to_dnl_mode(void)
> +{
> +	puts("entering download mode ...\n");
> +	set_back_to_bootrom_dnl_flag();
> +	do_reset(NULL, 0, 0, NULL);
> +}
> +
>  /*
>   * detect download key status by adc, most rockchip
>   * based boards use adc sample the download key status,
> @@ -71,12 +92,19 @@ __weak int rockchip_dnl_key_pressed(void)
>  		return false;
>  }
> 
> -void rockchip_dnl_mode_check(void)
> +#if CONFIG_IS_ENABLED(ROCKCHIP_HANG_TO_BROM)
> +void show_boot_progress(int val)
> +{
> +	if (val == -BOOTSTAGE_ID_NEED_RESET)
> +		rockchip_reset_to_dnl_mode();
> +}
> +#endif
> +
> +static void rockchip_dnl_mode_check(void)
>  {
>  	if (rockchip_dnl_key_pressed()) {
> -		printf("download key pressed, entering download mode...");
> -		set_back_to_bootrom_dnl_flag();
> -		do_reset(NULL, 0, 0, NULL);
> +		puts("download key pressed, ");
> +		rockchip_reset_to_dnl_mode();
>  	}
>  }
> 
> diff --git a/configs/generic-rk3568_defconfig 
> b/configs/generic-rk3568_defconfig
> index b90ecb643dc7..9edd4c33000e 100644
> --- a/configs/generic-rk3568_defconfig
> +++ b/configs/generic-rk3568_defconfig
> @@ -11,6 +11,7 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc00000
>  CONFIG_DEFAULT_DEVICE_TREE="rk3568-generic"
>  CONFIG_ROCKCHIP_RK3568=y
>  CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y
> +CONFIG_ROCKCHIP_HANG_TO_BROM=y
>  CONFIG_SPL_SERIAL=y
>  CONFIG_SPL_STACK_R_ADDR=0x600000
>  CONFIG_SPL_STACK=0x400000
> diff --git a/configs/generic-rk3588_defconfig 
> b/configs/generic-rk3588_defconfig
> index a9329eb1c625..5872bd4802c5 100644
> --- a/configs/generic-rk3588_defconfig
> +++ b/configs/generic-rk3588_defconfig
> @@ -11,6 +11,7 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc00000
>  CONFIG_DEFAULT_DEVICE_TREE="rk3588-generic"
>  CONFIG_ROCKCHIP_RK3588=y
>  CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y
> +CONFIG_ROCKCHIP_HANG_TO_BROM=y
>  CONFIG_SPL_SERIAL=y
>  CONFIG_SPL_STACK_R_ADDR=0x600000
>  CONFIG_TARGET_EVB_RK3588=y


More information about the U-Boot mailing list