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