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