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