blob: 439066eecbf11776da51712fb88538d10764aaed [file] [log] [blame]
Bo Lv72d0e902023-01-02 14:27:34 +00001// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2/*
3 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
4 */
5
6#include <common.h>
7#include <command.h>
8#include <asm/amlogic/arch/reboot.h>
9#include <asm/amlogic/arch/secure_apb.h>
10#include <asm/io.h>
11#include <asm/amlogic/arch/bl31_apis.h>
12#include <amlogic/partition_table.h>
13#include <amlogic/storage.h>
Yao Jie608e7b12023-11-20 17:01:54 +080014#include <asm/amlogic/arch/cpu_config.h>
Bo Lv72d0e902023-01-02 14:27:34 +000015#include <asm/amlogic/arch/stick_mem.h>
Jianyi Shi18eda7e2024-05-07 02:00:30 +000016#include <amlogic/pm.h>
Bo Lv72d0e902023-01-02 14:27:34 +000017/*
18run get_rebootmode //set reboot_mode env with current mode
19*/
20
21int do_get_rebootmode (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
22{
23 uint32_t reboot_mode_val;
Xindong Xu15e83fa2024-03-15 08:56:00 +080024 char *quiescent_env_bk;
Yao Jie608e7b12023-11-20 17:01:54 +080025 u32 stick_reboot_flag;
26 u32 bit_mask;
Bo Lv72d0e902023-01-02 14:27:34 +000027
Yao Jie608e7b12023-11-20 17:01:54 +080028#ifdef NO_EXTEND_REBOOT_MODE
29 bit_mask = 0xf;
30#else
31 bit_mask = 0x7f;
32#endif
33 reboot_mode_val = ((readl(AO_SEC_SD_CFG15) >> 12) & bit_mask);
Bo Lv72d0e902023-01-02 14:27:34 +000034 //this step prevent the reboot mode val stored in sticky register lost
Yao Jie608e7b12023-11-20 17:01:54 +080035 //during the exceptional reset, such as reset pin disturbance
36 stick_reboot_flag = get_stick_reboot_flag();
37 if (reboot_mode_val == AMLOGIC_COLD_BOOT &&
38 stick_reboot_flag == AMLOGIC_WATCHDOG_REBOOT) {
39 printf("Warning: system is reset abnormally!\n");
40 printf("Set reboot_mode to watchdog reboot\n");
41 reboot_mode_val = AMLOGIC_WATCHDOG_REBOOT;
42 }
Bo Lv72d0e902023-01-02 14:27:34 +000043
44 debug("reboot_mode(0x%x)=0x%x\n", AO_SEC_SD_CFG15, reboot_mode_val);
45
46 switch (reboot_mode_val)
47 {
48 case AMLOGIC_COLD_BOOT:
49 {
50 env_set("reboot_mode","cold_boot");
51 break;
52 }
53 case AMLOGIC_NORMAL_BOOT:
54 {
55 env_set("reboot_mode","normal");
56 break;
57 }
58 case AMLOGIC_FACTORY_RESET_REBOOT:
59 {
60 env_set("reboot_mode","factory_reset");
61 break;
62 }
63 case AMLOGIC_UPDATE_REBOOT:
64 {
65 env_set("reboot_mode","update");
66 break;
67 }
68 case AMLOGIC_FASTBOOT_REBOOT:
69 {
70 env_set("reboot_mode","fastboot");
71 break;
72 }
73 case AMLOGIC_BOOTLOADER_REBOOT:
74 {
75 env_set("reboot_mode","bootloader");
76 break;
77 }
78 case AMLOGIC_SUSPEND_REBOOT:
79 {
80 env_set("reboot_mode","suspend_off");
81 break;
82 }
83 case AMLOGIC_HIBERNATE_REBOOT:
84 {
85 env_set("reboot_mode","hibernate");
86 break;
87 }
88 case AMLOGIC_SHUTDOWN_REBOOT:
89 {
90 env_set("reboot_mode","shutdown_reboot");
91 break;
92 }
93 case AMLOGIC_RESCUEPARTY_REBOOT:
94 {
95 env_set("reboot_mode", "rescueparty");
96 break;
97 }
98 case AMLOGIC_KERNEL_PANIC:
99 {
100 env_set("reboot_mode","kernel_panic");
101 break;
102 }
103 case AMLOGIC_WATCHDOG_REBOOT:
104 {
105 env_set("reboot_mode","watchdog_reboot");
106 break;
107 }
108 case AMLOGIC_RPMBP_REBOOT:
109 {
110 env_set("reboot_mode","rpmbp");
111 break;
112 }
113 case AMLOGIC_QUIESCENT_REBOOT:
114 {
Xindong Xu15e83fa2024-03-15 08:56:00 +0800115 env_set("quiescent_env_bk", "quiescent");
116#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
117 run_command("update_env_part -p quiescent_env_bk;", 0);
118#else
119 run_command("defenv_reserv; saveenv;", 0);
120#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000121 env_set("reboot_mode","quiescent");
122 break;
123 }
124 case AMLOGIC_RECOVERY_QUIESCENT_REBOOT:
125 {
Xindong Xu15e83fa2024-03-15 08:56:00 +0800126 env_set("quiescent_env_bk", "recovery_quiescent");
127#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
128 run_command("update_env_part -p quiescent_env_bk;", 0);
129#else
130 run_command("defenv_reserv; saveenv;", 0);
131#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000132 env_set("reboot_mode","recovery_quiescent");
133 break;
134 }
135#ifdef AMLOGIC_FFV_REBOOT
136 case AMLOGIC_FFV_REBOOT:
137 {
138 env_set("reboot_mode", "ffv_reboot");
139 break;
140 }
141#endif
142 default:
143 {
144 env_set("reboot_mode","charging");
145 break;
146 }
147 }
148
149#ifdef CONFIG_CMD_FASTBOOT
150 switch (reboot_mode_val) {
151 case AMLOGIC_FASTBOOT_REBOOT: {
152 env_set("reboot_mode","fastboot");
153 break;
154 }
155 case AMLOGIC_BOOTLOADER_REBOOT: {
Xindong Xud9441422024-01-18 10:20:45 +0800156 env_set("reboot_mode", "fastboot");
Bo Lv72d0e902023-01-02 14:27:34 +0000157 break;
158 }
159 }
160#endif
161
Xindong Xu15e83fa2024-03-15 08:56:00 +0800162 quiescent_env_bk = env_get("quiescent_env_bk");
163 if (quiescent_env_bk &&
164 ((strcmp(quiescent_env_bk, "quiescent") == 0) ||
165 (strcmp(quiescent_env_bk, "recovery_quiescent") == 0))) {
166 printf("quiescent_env_bk: %s\n", quiescent_env_bk);
167 switch (reboot_mode_val) {
168 case AMLOGIC_COLD_BOOT:
169 case AMLOGIC_KERNEL_PANIC:
170 case AMLOGIC_WATCHDOG_REBOOT: {
171 printf("set reboot_mode %s\n", quiescent_env_bk);
172 env_set("reboot_mode", quiescent_env_bk);
173 break;
174 }
175 default: {
176 printf("clear quiescent_env_bk\n");
177 env_set("quiescent_env_bk", "0");
178#if CONFIG_IS_ENABLED(AML_UPDATE_ENV)
179 run_command("update_env_part -p quiescent_env_bk;", 0);
180#else
181 run_command("defenv_reserv; saveenv;", 0);
182#endif
183 break;
184 }
185 }
186 }
187
Bo Lv72d0e902023-01-02 14:27:34 +0000188#if defined(CONFIG_AML_RPMB)
189 run_command("rpmb_state",0);
190#endif
191
192 return 0;
193}
194
195int do_reboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
196{
197 uint32_t reboot_mode_val = AMLOGIC_NORMAL_BOOT;
198 if (argc <= 1) {
199 printf("reboot use default mode: normal\n");
200 }
201 else {
202 printf("reboot mode: %s\n", argv[1]);
203 char * mode = argv[1];
204
205 if (strcmp(mode, "next") == 0) {
206 store_restore_bootidx();
Xindong Xu22e8daf2024-03-12 18:08:41 +0800207 reboot_mode_val = AMLOGIC_NORMAL_BOOT;
Bo Lv72d0e902023-01-02 14:27:34 +0000208 } else if (strcmp(mode, "next,quiescent") == 0) {
209 store_restore_bootidx();
210 reboot_mode_val = AMLOGIC_QUIESCENT_REBOOT;
Xindong Xu22e8daf2024-03-12 18:08:41 +0800211 } else if (strcmp(mode, "next,bootloader") == 0) {
212 store_restore_bootidx();
213 reboot_mode_val = AMLOGIC_BOOTLOADER_REBOOT;
Xindong Xu591b9f42024-07-03 08:52:40 +0800214 } else if (strcmp(mode, "quiescent") == 0) {
215 reboot_mode_val = AMLOGIC_QUIESCENT_REBOOT;
Bo Lv72d0e902023-01-02 14:27:34 +0000216 } else if (strcmp(mode, "cold_boot") == 0)
217 reboot_mode_val = AMLOGIC_COLD_BOOT;
218 else if (strcmp(mode, "normal") == 0)
219 reboot_mode_val = AMLOGIC_NORMAL_BOOT;
Xindong Xud9441422024-01-18 10:20:45 +0800220 else if (strcmp(mode, "recovery") == 0) {
221 reboot_mode_val = AMLOGIC_FACTORY_RESET_REBOOT;
222 run_command("bcb recovery", 0);
223 } else if (strcmp(mode, "factory_reset") == 0)
Bo Lv72d0e902023-01-02 14:27:34 +0000224 reboot_mode_val = AMLOGIC_FACTORY_RESET_REBOOT;
225 else if (strcmp(mode, "update") == 0)
226 reboot_mode_val = AMLOGIC_UPDATE_REBOOT;
227 else if (strcmp(mode, "fastboot") == 0) {
228 if (dynamic_partition) {
229 printf("dynamic partition, enter fastbootd");
230 reboot_mode_val = AMLOGIC_FACTORY_RESET_REBOOT;
231 run_command("bcb fastbootd",0);
232 } else
233 reboot_mode_val = AMLOGIC_FASTBOOT_REBOOT;
234 } else if (strcmp(mode, "bootloader") == 0)
235 reboot_mode_val = AMLOGIC_BOOTLOADER_REBOOT;
236 else if (strcmp(mode, "suspend_off") == 0)
237 reboot_mode_val = AMLOGIC_SUSPEND_REBOOT;
238 else if (strcmp(mode, "hibernate") == 0)
239 reboot_mode_val = AMLOGIC_HIBERNATE_REBOOT;
240 else if (strcmp(mode, "rescueparty") == 0)
241 reboot_mode_val = AMLOGIC_RESCUEPARTY_REBOOT;
242 else if (strcmp(mode, "kernel_panic") == 0)
243 reboot_mode_val = AMLOGIC_KERNEL_PANIC;
244 else if (strcmp(mode, "rpmbp") == 0)
245 reboot_mode_val = AMLOGIC_RPMBP_REBOOT;
246#ifdef AMLOGIC_FFV_REBOOT
247 else if (strcmp(mode, "ffv_reboot") == 0)
248 reboot_mode_val = AMLOGIC_FFV_REBOOT;
249#endif
250 else {
251 printf("Can not find match reboot mode, use normal by default\n");
252 reboot_mode_val = AMLOGIC_NORMAL_BOOT;
253 }
254 }
255#ifdef CONFIG_USB_DEVICE_V2
256#if !(defined AML_USB_V2)
257 *P_RESET1_REGISTER |= (1<<17);
258 mdelay(200);
259#endif
260#endif
261 dcache_disable();
262
263 aml_reboot (PSCI_SYS_REBOOT, reboot_mode_val, 0, 0);
264 return 0;
265}
266
267/* USB BOOT FUNC sub command list*/
268#define CLEAR_USB_BOOT 1
269#define FORCE_USB_BOOT 2
270#define RUN_COMD_USB_BOOT 3
271#define PANIC_DUMP_USB_BOOT 4
272
273int do_set_usb_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
274{
275 unsigned int usb_mode = 0;
276 if (argc <= 1) {
277 printf("usb flag default 0\n");
278 }
279 else {
280 usb_mode = simple_strtoul(argv[1], NULL, 16);
281 }
282 printf("usb flag: %d\n", usb_mode);
283 set_usb_boot_function(usb_mode);
284
285 return 0;
286}
287
288U_BOOT_CMD(
289 get_rebootmode, 1, 0, do_get_rebootmode,
290 "get reboot mode",
291 "/N\n"
292 " This command will get and set env 'reboot_mode'\n"
293 "get_rebootmode\n"
294);
295
296U_BOOT_CMD(
297 reboot, 2, 0, do_reboot,
298 "set reboot mode and reboot system",
299 "[rebootmode]/N\n"
300 " This command will set reboot mode and reboot system\n"
301 "\n"
302 " support following [rebootmode]:\n"
303 " cold_boot\n"
304 " normal[default]\n"
305 " factory_reset/recovery\n"
306 " update\n"
307 " fastboot\n"
308 " bootloader\n"
309 " suspend_off\n"
310 " hibernate\n"
311 " next <ONLY work for SC2>\n"
312 " crash_dump\n"
313);
314
315U_BOOT_CMD(
316 set_usb_boot, 2, 0, do_set_usb_boot,
317 "set usb boot mode",
318 "[usb boot mode]/N\n"
319 " support following [usb boot mode]:\n"
320 " 1: CLEAR_USB_BOOT\n"
321 " 2: FORCE_USB_BOOT[default]\n"
322 " 3: RUN_COMD_USB_BOOT/recovery\n"
323 " 4: PANIC_DUMP_USB_BOOT\n"
324);
325
326int do_systemoff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
327{
xiangyang.yan226ae3b2024-11-20 14:43:38 +0800328 pm_poweroff();
Bo Lv72d0e902023-01-02 14:27:34 +0000329 return 0;
330}
331
332
333U_BOOT_CMD(
334 systemoff, 2, 1, do_systemoff,
335 "system off ",
336 "systemoff "
337);
Jianyi Shi18eda7e2024-05-07 02:00:30 +0000338
339int do_systemsuspend(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
340{
341 pm_suspend();
342 return 0;
343}
344
345U_BOOT_CMD(systemsuspend, 2, 1, do_systemsuspend,
346 "system suspend ", "systemsuspend ");
347