/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ /* * common/cmd_reboot.c * * Copyright (C) 2020 Amlogic, Inc. All rights reserved. * */ #include #include #include #include #include #include #include #include #include #include #ifdef CONFIG_REBOOT_VIA_RESET_PIN_STICKY #include #endif /* run get_rebootmode //set reboot_mode env with current mode */ unsigned int do_get_reboot_reason(void) { uint32_t reboot_reason; reboot_reason = ((readl(AO_SEC_SD_CFG15) >> 12) & 0xf); return reboot_reason; } int do_get_rebootmode (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint32_t reboot_mode_val; #ifdef CONFIG_REBOOT_VIA_RESET_PIN_STICKY u32 stick_reboot_flag; #endif reboot_mode_val = ((readl(AO_SEC_SD_CFG15) >> 12) & 0xf); #ifdef CONFIG_REBOOT_VIA_RESET_PIN_STICKY //this step prevent the reboot mode val stored in sticky register lost //during the exceptional reset, such as reset pin disturbance stick_reboot_flag = get_stick_reboot_flag_mbx(); if (reboot_mode_val == AMLOGIC_COLD_BOOT && stick_reboot_flag == AMLOGIC_WATCHDOG_REBOOT) { printf("Warning: system is reset abnormally!\n"); printf("Set reboot_mode to watchdog reboot\n"); reboot_mode_val = AMLOGIC_WATCHDOG_REBOOT; } #endif debug("reboot_mode(0x%x)=0x%x\n", AO_SEC_SD_CFG15, reboot_mode_val); switch (reboot_mode_val) { case AMLOGIC_COLD_BOOT: { setenv("reboot_mode","cold_boot"); break; } case AMLOGIC_NORMAL_BOOT: { setenv("reboot_mode","normal"); break; } case AMLOGIC_FACTORY_RESET_REBOOT: { setenv("reboot_mode","factory_reset"); break; } case AMLOGIC_UPDATE_REBOOT: { setenv("reboot_mode","update"); break; } case AMLOGIC_FASTBOOT_REBOOT: { setenv("reboot_mode","fastboot"); break; } case AMLOGIC_BOOTLOADER_REBOOT: { setenv("reboot_mode","bootloader"); break; } case AMLOGIC_SUSPEND_REBOOT: { setenv("reboot_mode","suspend_off"); break; } case AMLOGIC_HIBERNATE_REBOOT: { setenv("reboot_mode","hibernate"); break; } case AMLOGIC_SHUTDOWN_REBOOT: { setenv("reboot_mode","shutdown_reboot"); break; } case AMLOGIC_RESCUEPARTY_REBOOT: { setenv("reboot_mode", "rescueparty"); break; } case AMLOGIC_KERNEL_PANIC: { setenv("reboot_mode","kernel_panic"); break; } case AMLOGIC_WATCHDOG_REBOOT: { setenv("reboot_mode","watchdog_reboot"); break; } case AMLOGIC_RPMBP_REBOOT: { setenv("reboot_mode","rpmbp"); break; } case AMLOGIC_QUIESCENT_REBOOT: { setenv("reboot_mode","quiescent"); break; } case AMLOGIC_RECOVERY_QUIESCENT_REBOOT: { setenv("reboot_mode","recovery_quiescent"); break; } case AMLOGIC_FFV_REBOOT: { setenv("reboot_mode","ffv_reboot"); break; } /* remove default, fix coverity error DEADCODE*/ } #ifdef CONFIG_CMD_FASTBOOT switch (reboot_mode_val) { case AMLOGIC_FASTBOOT_REBOOT: { setenv("reboot_mode","fastboot"); break; } case AMLOGIC_BOOTLOADER_REBOOT: { if (dynamic_partition) setenv("reboot_mode","fastboot"); break; } } #endif #ifdef CONFIG_AML_PRODUCT_MODE if (reboot_mode_val == AMLOGIC_FASTBOOT_REBOOT || reboot_mode_val == AMLOGIC_BOOTLOADER_REBOOT) setenv("reboot_mode", "normal"); #endif//#ifdef CONFIG_AML_PRODUCT_MODE #if !defined(CONFIG_AML_RPMB_DISABLE) run_command("rpmb_state",0); #endif return 0; } int do_reboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint32_t reboot_mode_val = AMLOGIC_NORMAL_BOOT; if (argc <= 1) { printf("reboot use default mode: normal\n"); } else { printf("reboot mode: %s\n", argv[1]); char * mode = argv[1]; if (strcmp(mode, "cold_boot") == 0) reboot_mode_val = AMLOGIC_COLD_BOOT; else if (strcmp(mode, "quiescent") == 0) reboot_mode_val = AMLOGIC_QUIESCENT_REBOOT; else if (strcmp(mode, "normal") == 0) reboot_mode_val = AMLOGIC_NORMAL_BOOT; else if (strcmp(mode, "recovery") == 0) { reboot_mode_val = AMLOGIC_FACTORY_RESET_REBOOT; run_command("bcb recovery", 0); } else if (strcmp(mode, "factory_reset") == 0) reboot_mode_val = AMLOGIC_FACTORY_RESET_REBOOT; else if (strcmp(mode, "update") == 0) reboot_mode_val = AMLOGIC_UPDATE_REBOOT; else if (strcmp(mode, "fastboot") == 0) { if (dynamic_partition) { printf("dynamic partition, enter fastbootd"); reboot_mode_val = AMLOGIC_FACTORY_RESET_REBOOT; run_command("bcb fastbootd",0); } else reboot_mode_val = AMLOGIC_FASTBOOT_REBOOT; } else if (strcmp(mode, "bootloader") == 0) reboot_mode_val = AMLOGIC_BOOTLOADER_REBOOT; else if (strcmp(mode, "suspend_off") == 0) reboot_mode_val = AMLOGIC_SUSPEND_REBOOT; else if (strcmp(mode, "hibernate") == 0) reboot_mode_val = AMLOGIC_HIBERNATE_REBOOT; else if (strcmp(mode, "rescueparty") == 0) reboot_mode_val = AMLOGIC_RESCUEPARTY_REBOOT; else if (strcmp(mode, "kernel_panic") == 0) reboot_mode_val = AMLOGIC_KERNEL_PANIC; else if (strcmp(mode, "rpmbp") == 0) reboot_mode_val = AMLOGIC_RPMBP_REBOOT; else { printf("Can not find match reboot mode, use normal by default\n"); reboot_mode_val = AMLOGIC_NORMAL_BOOT; } } #ifdef CONFIG_USB_DEVICE_V2 *P_RESET1_REGISTER |= (1<<17); mdelay(200); #endif aml_reboot (PSCI_SYS_REBOOT, reboot_mode_val, 0, 0); return 0; } /* USB BOOT FUNC sub command list*/ #define CLEAR_USB_BOOT 1 #define FORCE_USB_BOOT 2 #define RUN_COMD_USB_BOOT 3 #define PANIC_DUMP_USB_BOOT 4 int do_set_usb_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned int usb_mode = 0; if (argc <= 1) { printf("usb flag default 0\n"); } else { usb_mode = simple_strtoul(argv[1], NULL, 16); } printf("usb flag: %d\n", usb_mode); set_usb_boot_function(usb_mode); return 0; } U_BOOT_CMD( get_rebootmode, 1, 0, do_get_rebootmode, "get reboot mode", "/N\n" " This command will get and setenv 'reboot_mode'\n" "get_rebootmode\n" ); U_BOOT_CMD( reboot, 2, 0, do_reboot, "set reboot mode and reboot system", "[rebootmode]/N\n" " This command will set reboot mode and reboot system\n" "\n" " support following [rebootmode]:\n" " cold_boot\n" " normal[default]\n" " factory_reset/recovery\n" " update\n" " fastboot\n" " bootloader\n" " suspend_off\n" " hibernate\n" " crash_dump\n" ); U_BOOT_CMD( set_usb_boot, 2, 0, do_set_usb_boot, "set usb boot mode", "[usb boot mode]/N\n" " support following [usb boot mode]:\n" " 1: CLEAR_USB_BOOT\n" " 2: FORCE_USB_BOOT[default]\n" " 3: RUN_COMD_USB_BOOT/recovery\n" " 4: PANIC_DUMP_USB_BOOT\n" ); int do_systemoff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { //aml_system_off(); pm_poweroff(); return 0; } U_BOOT_CMD( systemoff, 2, 1, do_systemoff, "system off ", "systemoff " ); int do_systemsuspend(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { pm_suspend(); return 0; } U_BOOT_CMD(systemsuspend, 2, 1, do_systemsuspend, "system suspend ", "systemsuspend ");