rockchip: boot-mode: fix lost boot-mode from register

PH and PL is from boot mode register, reading once.
PM is from misc.img and should be updated if BCB offset is changed.
Return the boot mode according to priority: PH > PM > PL.

Fixes:
(3aaa96e8af rockchip: boot-mode: reinitialize static variable "boot_mode")

Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
Change-Id: Ibd577dd8ebfb0d4c36ac8b90e176d3b1103f347e
This commit is contained in:
Joseph Chen 2020-11-19 17:12:31 +08:00 committed by Jianhong Chen
parent 22edf95882
commit ea8b124a0e
1 changed files with 62 additions and 42 deletions

View File

@ -29,6 +29,13 @@ DECLARE_GLOBAL_DATA_PTR;
* - "reboot recovery" command;
* - recovery key pressed without usb attach;
*/
enum {
PH = 0, /* P: Priority, H: high, M: middle, L: low*/
PM,
PL,
};
int rockchip_get_boot_mode(void)
{
struct bootloader_message *bmsg = NULL;
@ -36,8 +43,9 @@ int rockchip_get_boot_mode(void)
disk_partition_t part_info;
uint32_t reg_boot_mode;
char *env_reboot_mode;
static int boot_mode = -1; /* static */
static int bcb_offset = -1; /* static */
static int boot_mode[] = /* static */
{ -EINVAL, -EINVAL, -EINVAL };
static int bcb_offset = -EINVAL; /* static */
int clear_boot_reg = 0;
int ret, cnt;
#ifdef CONFIG_ANDROID_BOOT_IMAGE
@ -45,6 +53,29 @@ int rockchip_get_boot_mode(void)
#else
u32 offset = BCB_MESSAGE_BLK_OFFSET;
#endif
/*
* Here, we mainly check for:
* In rockusb_download(), that recovery key is pressed without
* USB attach will do env_set("reboot_mode", "recovery");
*/
env_reboot_mode = env_get("reboot_mode");
if (env_reboot_mode) {
if (!strcmp(env_reboot_mode, "recovery-key")) {
printf("boot mode: recovery (key)\n");
return BOOT_MODE_RECOVERY;
} else if (!strcmp(env_reboot_mode, "recovery-usb")) {
printf("boot mode: recovery (usb)\n");
return BOOT_MODE_RECOVERY;
} else if (!strcmp(env_reboot_mode, "recovery")) {
printf("boot mode: recovery (env)\n");
return BOOT_MODE_RECOVERY;
} else if (!strcmp(env_reboot_mode, "fastboot")) {
printf("boot mode: fastboot\n");
return BOOT_MODE_BOOTLOADER;
}
}
/*
* Special handle:
* Once the BCB offset changes, reinitalize "boot_mode".
@ -61,36 +92,23 @@ int rockchip_get_boot_mode(void)
* set as BOOT_MODE_RECOVERY according to BCB at 0x20 offset.
* After that, this function always return static variable "boot_mode"
* as BOOT_MODE_RECOVERY even android(>=10) boot flow enter here.
*
* PH and PL is from boot mode register, reading once.
* PM is from misc.img and should be updated if BCB offset is changed.
* Return the boot mode according to priority: PH > PM > PL.
*/
if (bcb_offset != offset) {
boot_mode = -1;
boot_mode[PM] = -EINVAL;
bcb_offset = offset;
}
/*
* Here, we mainly check for:
* In rockusb_download(), that recovery key is pressed without
* USB attach will do env_set("reboot_mode", "recovery");
*/
env_reboot_mode = env_get("reboot_mode");
if (env_reboot_mode) {
if (!strcmp(env_reboot_mode, "recovery-key")) {
boot_mode = BOOT_MODE_RECOVERY;
printf("boot mode: recovery (key)\n");
} else if (!strcmp(env_reboot_mode, "recovery-usb")) {
boot_mode = BOOT_MODE_RECOVERY;
printf("boot mode: recovery (usb)\n");
} else if (!strcmp(env_reboot_mode, "recovery")) {
boot_mode = BOOT_MODE_RECOVERY;
printf("boot mode: recovery(env)\n");
} else if (!strcmp(env_reboot_mode, "fastboot")) {
boot_mode = BOOT_MODE_BOOTLOADER;
printf("boot mode: fastboot\n");
}
}
if (boot_mode != -1)
return boot_mode;
/* directly return if there is already valid mode */
if (boot_mode[PH] != -EINVAL)
return boot_mode[PH];
else if (boot_mode[PM] != -EINVAL)
return boot_mode[PM];
else if (boot_mode[PL] != -EINVAL)
return boot_mode[PL];
dev_desc = rockchip_get_bootdev();
if (!dev_desc) {
@ -106,9 +124,7 @@ int rockchip_get_boot_mode(void)
cnt = DIV_ROUND_UP(sizeof(struct bootloader_message), dev_desc->blksz);
bmsg = memalign(ARCH_DMA_MINALIGN, cnt * dev_desc->blksz);
ret = blk_dread(dev_desc,
part_info.start + bcb_offset,
cnt, bmsg);
ret = blk_dread(dev_desc, part_info.start + bcb_offset, cnt, bmsg);
if (ret != cnt) {
free(bmsg);
return -EIO;
@ -125,49 +141,48 @@ fallback:
reg_boot_mode = readl((void *)CONFIG_ROCKCHIP_BOOT_MODE_REG);
if (reg_boot_mode == BOOT_LOADER) {
printf("boot mode: loader\n");
boot_mode = BOOT_MODE_LOADER;
boot_mode[PH] = BOOT_MODE_LOADER;
clear_boot_reg = 1;
} else if (reg_boot_mode == BOOT_FASTBOOT) {
printf("boot mode: bootloader\n");
boot_mode = BOOT_MODE_BOOTLOADER;
boot_mode[PH] = BOOT_MODE_BOOTLOADER;
clear_boot_reg = 1;
} else if (bmsg && !strcmp(bmsg->command, "boot-recovery")) {
printf("boot mode: recovery (misc)\n");
boot_mode = BOOT_MODE_RECOVERY;
clear_boot_reg = 1;
boot_mode[PM] = BOOT_MODE_RECOVERY;
} else {
switch (reg_boot_mode) {
case BOOT_NORMAL:
printf("boot mode: normal\n");
boot_mode = BOOT_MODE_NORMAL;
boot_mode[PL] = BOOT_MODE_NORMAL;
clear_boot_reg = 1;
break;
case BOOT_RECOVERY:
printf("boot mode: recovery (cmd)\n");
boot_mode = BOOT_MODE_RECOVERY;
boot_mode[PL] = BOOT_MODE_RECOVERY;
clear_boot_reg = 1;
break;
case BOOT_UMS:
printf("boot mode: ums\n");
boot_mode = BOOT_MODE_UMS;
boot_mode[PL] = BOOT_MODE_UMS;
clear_boot_reg = 1;
break;
case BOOT_CHARGING:
printf("boot mode: charging\n");
boot_mode = BOOT_MODE_CHARGING;
boot_mode[PL] = BOOT_MODE_CHARGING;
clear_boot_reg = 1;
break;
case BOOT_PANIC:
printf("boot mode: panic\n");
boot_mode = BOOT_MODE_PANIC;
boot_mode[PL] = BOOT_MODE_PANIC;
break;
case BOOT_WATCHDOG:
printf("boot mode: watchdog\n");
boot_mode = BOOT_MODE_WATCHDOG;
boot_mode[PL] = BOOT_MODE_WATCHDOG;
break;
default:
printf("boot mode: None\n");
boot_mode = BOOT_MODE_UNDEFINE;
boot_mode[PL] = BOOT_MODE_UNDEFINE;
}
}
@ -178,7 +193,12 @@ fallback:
if (clear_boot_reg)
writel(BOOT_NORMAL, (void *)CONFIG_ROCKCHIP_BOOT_MODE_REG);
return boot_mode;
if (boot_mode[PH] != -EINVAL)
return boot_mode[PH];
else if (boot_mode[PM] != -EINVAL)
return boot_mode[PM];
else
return boot_mode[PL];
}
int setup_boot_mode(void)