xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/spl_boot_mode.c (revision 57504d998fc512618c6e02c21bf2d4cc82969d49)
1*57504d99SJoseph Chen /*
2*57504d99SJoseph Chen  * (C) Copyright 2021 Rockchip Electronics Co., Ltd
3*57504d99SJoseph Chen  *
4*57504d99SJoseph Chen  * SPDX-License-Identifier:     GPL-2.0+
5*57504d99SJoseph Chen  */
6*57504d99SJoseph Chen 
7*57504d99SJoseph Chen #include <common.h>
8*57504d99SJoseph Chen #include <boot_rkimg.h>
9*57504d99SJoseph Chen #include <malloc.h>
10*57504d99SJoseph Chen #include <asm/io.h>
11*57504d99SJoseph Chen #include <asm/arch/boot_mode.h>
12*57504d99SJoseph Chen 
misc_require_recovery(struct blk_desc * dev_desc,u32 bcb_offset)13*57504d99SJoseph Chen static int misc_require_recovery(struct blk_desc *dev_desc, u32 bcb_offset)
14*57504d99SJoseph Chen {
15*57504d99SJoseph Chen 	struct bootloader_message *bmsg;
16*57504d99SJoseph Chen 	disk_partition_t part;
17*57504d99SJoseph Chen 	int cnt, recovery;
18*57504d99SJoseph Chen 
19*57504d99SJoseph Chen 	if (!dev_desc)
20*57504d99SJoseph Chen 		return 0;
21*57504d99SJoseph Chen 
22*57504d99SJoseph Chen 	if (part_get_info_by_name(dev_desc, PART_MISC, &part) < 0) {
23*57504d99SJoseph Chen 		printf("No misc partition\n");
24*57504d99SJoseph Chen 		return 0;
25*57504d99SJoseph Chen 	}
26*57504d99SJoseph Chen 
27*57504d99SJoseph Chen 	cnt = DIV_ROUND_UP(sizeof(struct bootloader_message), dev_desc->blksz);
28*57504d99SJoseph Chen 	bmsg = memalign(ARCH_DMA_MINALIGN, cnt * dev_desc->blksz);
29*57504d99SJoseph Chen 	if (!bmsg)
30*57504d99SJoseph Chen 		return 0;
31*57504d99SJoseph Chen 
32*57504d99SJoseph Chen 	if (blk_dread(dev_desc, part.start + bcb_offset, cnt, bmsg) != cnt)
33*57504d99SJoseph Chen 		return 0;
34*57504d99SJoseph Chen 
35*57504d99SJoseph Chen 	recovery = !strcmp(bmsg->command, "boot-recovery");
36*57504d99SJoseph Chen 	free(bmsg);
37*57504d99SJoseph Chen 
38*57504d99SJoseph Chen 	return recovery;
39*57504d99SJoseph Chen }
40*57504d99SJoseph Chen 
rockchip_get_boot_mode(struct blk_desc * dev_desc,u32 bcb_sector_offset)41*57504d99SJoseph Chen int rockchip_get_boot_mode(struct blk_desc *dev_desc, u32 bcb_sector_offset)
42*57504d99SJoseph Chen {
43*57504d99SJoseph Chen 	uint32_t reg_boot_mode;
44*57504d99SJoseph Chen 	int boot_mode;
45*57504d99SJoseph Chen 
46*57504d99SJoseph Chen 	/*
47*57504d99SJoseph Chen 	 * Boot mode priority
48*57504d99SJoseph Chen 	 *
49*57504d99SJoseph Chen 	 * Anyway, we should set download boot mode as the highest priority, so:
50*57504d99SJoseph Chen 	 * reboot loader/bootloader/fastboot > misc partition "recovery" > reboot xxx.
51*57504d99SJoseph Chen 	 */
52*57504d99SJoseph Chen 	reg_boot_mode = readl((void *)CONFIG_ROCKCHIP_BOOT_MODE_REG);
53*57504d99SJoseph Chen 	if (reg_boot_mode == BOOT_LOADER) {
54*57504d99SJoseph Chen 		printf("boot mode: loader\n");
55*57504d99SJoseph Chen 		boot_mode = BOOT_MODE_LOADER;
56*57504d99SJoseph Chen 	} else if (reg_boot_mode == BOOT_DFU) {
57*57504d99SJoseph Chen 		printf("boot mode: dfu\n");
58*57504d99SJoseph Chen 		boot_mode = BOOT_MODE_DFU;
59*57504d99SJoseph Chen 	} else if (reg_boot_mode == BOOT_FASTBOOT) {
60*57504d99SJoseph Chen 		printf("boot mode: bootloader\n");
61*57504d99SJoseph Chen 		boot_mode = BOOT_MODE_BOOTLOADER;
62*57504d99SJoseph Chen 	} else if (misc_require_recovery(dev_desc, bcb_sector_offset)) {
63*57504d99SJoseph Chen 		printf("boot mode: recovery (misc)\n");
64*57504d99SJoseph Chen 		boot_mode = BOOT_MODE_RECOVERY;
65*57504d99SJoseph Chen 	} else {
66*57504d99SJoseph Chen 		switch (reg_boot_mode) {
67*57504d99SJoseph Chen 		case BOOT_NORMAL:
68*57504d99SJoseph Chen 			printf("boot mode: normal\n");
69*57504d99SJoseph Chen 			boot_mode = BOOT_MODE_NORMAL;
70*57504d99SJoseph Chen 			break;
71*57504d99SJoseph Chen 		case BOOT_RECOVERY:
72*57504d99SJoseph Chen 			printf("boot mode: recovery (cmd)\n");
73*57504d99SJoseph Chen 			boot_mode = BOOT_MODE_RECOVERY;
74*57504d99SJoseph Chen 			break;
75*57504d99SJoseph Chen 		case BOOT_UMS:
76*57504d99SJoseph Chen 			printf("boot mode: ums\n");
77*57504d99SJoseph Chen 			boot_mode = BOOT_MODE_UMS;
78*57504d99SJoseph Chen 			break;
79*57504d99SJoseph Chen 		case BOOT_CHARGING:
80*57504d99SJoseph Chen 			printf("boot mode: charging\n");
81*57504d99SJoseph Chen 			boot_mode = BOOT_MODE_CHARGING;
82*57504d99SJoseph Chen 			break;
83*57504d99SJoseph Chen 		case BOOT_PANIC:
84*57504d99SJoseph Chen 			printf("boot mode: panic\n");
85*57504d99SJoseph Chen 			boot_mode = BOOT_MODE_PANIC;
86*57504d99SJoseph Chen 			break;
87*57504d99SJoseph Chen 		case BOOT_WATCHDOG:
88*57504d99SJoseph Chen 			printf("boot mode: watchdog\n");
89*57504d99SJoseph Chen 			boot_mode = BOOT_MODE_WATCHDOG;
90*57504d99SJoseph Chen 			break;
91*57504d99SJoseph Chen 		default:
92*57504d99SJoseph Chen 			printf("boot mode: None\n");
93*57504d99SJoseph Chen 			boot_mode = BOOT_MODE_UNDEFINE;
94*57504d99SJoseph Chen 		}
95*57504d99SJoseph Chen 	}
96*57504d99SJoseph Chen 
97*57504d99SJoseph Chen 	return boot_mode;
98*57504d99SJoseph Chen }
99