| |
| /* |
| * common/cmd_reboot.c |
| * |
| * Copyright (C) 2015 Amlogic, Inc. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| * more details. |
| * |
| * You should have received a copy of the GNU General Public License along |
| * with this program; if not, write to the Free Software Foundation, Inc., |
| * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| */ |
| |
| #include <common.h> |
| #include <command.h> |
| #include <amlogic/flash_ts.h> |
| #include <asm/arch/reboot.h> |
| #include <asm/arch/secure_apb.h> |
| #include <asm/io.h> |
| #include <asm/arch/bl31_apis.h> |
| #include <partition_table.h> |
| #include <amlogic/storage.h> |
| |
| uint32_t get_reboot_mode_val(void) |
| { |
| uint32_t reboot_mode_val; |
| #if defined(CONFIG_MESON_C1) || defined(CONFIG_MESON_C2) || defined(CONFIG_MESON_A1) |
| reboot_mode_val = ((readl(SYSCTRL_SEC_STATUS_REG2 ) >> 12) & 0xf); |
| pr_info("reboot_mode(0x%x)=0x%x\n", SYSCTRL_SEC_STATUS_REG2, reboot_mode_val); |
| #else |
| reboot_mode_val = ((readl(AO_SEC_SD_CFG15) >> 12) & 0xf); |
| pr_info("reboot_mode(0x%x)=0x%x\n", AO_SEC_SD_CFG15, reboot_mode_val); |
| #endif |
| return reboot_mode_val; |
| } |
| |
| /* |
| run get_rebootmode //set reboot_mode env with current mode |
| */ |
| |
| int do_get_rebootmode (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
| { |
| uint32_t reboot_mode_val; |
| char reboot_mode[16]; |
| |
| reboot_mode_val = get_reboot_mode_val(); |
| |
| strcpy(reboot_mode, "reboot_mode"); |
| if(is_flash_inited()) { |
| flash_ts_init(); |
| |
| const char *fts_key = "bootloader.command"; |
| char fts_value[256] = { 0 }; |
| |
| pr_info("default reboot_mode_val is %d\n", reboot_mode_val); |
| flash_ts_get(fts_key, fts_value, sizeof(fts_value)); |
| pr_info("FTS read: bootloader.command -> %s\n", fts_value); |
| |
| if (strncmp(fts_value, "boot-recovery", sizeof(fts_value)) == 0) { |
| #ifndef CONFIG_G_AB_SYSTEM |
| /* Disable the recovery mode support in A/B system */ |
| reboot_mode_val = AMLOGIC_FACTORY_RESET_REBOOT; |
| pr_info("overwriting reboot_mode_val to: %d\n", reboot_mode_val); |
| #endif |
| } else if (strncmp(fts_value, "boot-factory", sizeof(fts_value)) == 0) { |
| /* forece to u-boot console in factory mode */ |
| if (reboot_mode_val == AMLOGIC_BOOTLOADER_REBOOT) { |
| env_set("bootdelay","-1"); |
| } else { |
| pr_info("overwriting reboot_mode_val to: %d\n", reboot_mode_val); |
| env_set(reboot_mode, "factory_boot"); |
| strcpy(reboot_mode, "real_reboot_mode"); |
| } |
| } |
| } |
| |
| switch (reboot_mode_val) |
| { |
| case AMLOGIC_COLD_BOOT: |
| { |
| env_set(reboot_mode,"cold_boot"); |
| break; |
| } |
| case AMLOGIC_NORMAL_BOOT: |
| { |
| env_set(reboot_mode,"normal"); |
| break; |
| } |
| case AMLOGIC_QUIESCENT_REBOOT: |
| { |
| env_set(reboot_mode,"factory_boot"); |
| break; |
| } |
| case AMLOGIC_FACTORY_RESET_REBOOT: |
| { |
| env_set(reboot_mode,"factory_reset"); |
| break; |
| } |
| case AMLOGIC_UPDATE_REBOOT: |
| { |
| env_set(reboot_mode,"update"); |
| break; |
| } |
| case AMLOGIC_FASTBOOT_REBOOT: |
| { |
| env_set(reboot_mode,"fastboot"); |
| break; |
| } |
| case AMLOGIC_BOOTLOADER_REBOOT: |
| { |
| env_set(reboot_mode,"bootloader"); |
| break; |
| } |
| case AMLOGIC_SUSPEND_REBOOT: |
| { |
| env_set(reboot_mode,"suspend_off"); |
| break; |
| } |
| case AMLOGIC_HIBERNATE_REBOOT: |
| { |
| env_set(reboot_mode,"hibernate"); |
| break; |
| } |
| case AMLOGIC_SHUTDOWN_REBOOT: |
| { |
| env_set(reboot_mode,"shutdown_reboot"); |
| break; |
| } |
| case AMLOGIC_CRASH_REBOOT: |
| { |
| env_set(reboot_mode,"crash_dump"); |
| break; |
| } |
| case AMLOGIC_KERNEL_PANIC: |
| { |
| env_set(reboot_mode,"kernel_panic"); |
| break; |
| } |
| case AMLOGIC_WATCHDOG_REBOOT: |
| { |
| env_set(reboot_mode,"watchdog_reboot"); |
| break; |
| } |
| case AMLOGIC_RPMBP_REBOOT: |
| { |
| env_set(reboot_mode,"rpmbp"); |
| break; |
| } |
| case AMLOGIC_DELAYED_REBOOT: |
| { |
| env_set(reboot_mode,"delayed_reboot"); |
| break; |
| } |
| default: |
| { |
| env_set(reboot_mode,"charging"); |
| break; |
| } |
| } |
| |
| #ifdef CONFIG_CMD_FASTBOOT |
| switch (reboot_mode_val) { |
| case AMLOGIC_FASTBOOT_REBOOT: { |
| env_set("reboot_mode","fastboot"); |
| break; |
| } |
| case AMLOGIC_BOOTLOADER_REBOOT: { |
| if (dynamic_partition) |
| env_set("reboot_mode","fastboot"); |
| break; |
| } |
| } |
| #endif |
| |
| #if defined(CONFIG_AML_RPMB) |
| 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) |
| pr_info("reboot use default mode: normal\n"); |
| else { |
| pr_info("reboot mode: %s\n", argv[1]); |
| char * mode = argv[1]; |
| |
| if (strcmp(mode, "next") == 0) { |
| store_restore_bootidx(); |
| reboot_mode_val = AMLOGIC_COLD_BOOT; |
| } else if (strcmp(mode, "cold_boot") == 0) |
| reboot_mode_val = AMLOGIC_COLD_BOOT; |
| else if (strcmp(mode, "normal") == 0) |
| reboot_mode_val = AMLOGIC_NORMAL_BOOT; |
| else if (strcmp(mode, "recovery") == 0 || strcmp(mode, "factory_reset") == 0) |
| reboot_mode_val = AMLOGIC_FACTORY_RESET_REBOOT; |
| else if (strcmp(mode, "factory_boot") == 0) |
| reboot_mode_val = AMLOGIC_QUIESCENT_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, "crash_dump") == 0) |
| reboot_mode_val = AMLOGIC_CRASH_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 { |
| pr_info("Can not find match reboot mode, use normal by default\n"); |
| reboot_mode_val = AMLOGIC_NORMAL_BOOT; |
| } |
| } |
| #ifdef CONFIG_USB_DEVICE_V2 |
| #if !(defined AML_USB_V2) |
| *P_RESET1_REGISTER |= (1<<17); |
| mdelay(200); |
| #endif |
| #endif |
| dcache_disable(); |
| |
| 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) { |
| pr_info("usb flag default 0\n"); |
| } |
| else { |
| usb_mode = simple_strtoul(argv[1], NULL, 16); |
| } |
| pr_info("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 set env '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" |
| " factory_boot\n" |
| " update\n" |
| " fastboot\n" |
| " bootloader\n" |
| " suspend_off\n" |
| " hibernate\n" |
| " next <ONLY work for SC2>\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(); |
| return 0; |
| } |
| |
| U_BOOT_CMD( |
| systemoff, 2, 1, do_systemoff, |
| "system off ", |
| "systemoff " |
| ); |
| |
| int do_delayed_reboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
| { |
| uint32_t delay_time; |
| |
| delay_time = readl(SYSCTRL_STICKY_REG5); |
| if (delay_time == 0) |
| delay_time = 30; |
| |
| pr_info("delay %ds before booting...\n", delay_time); |
| udelay(delay_time * 1000 * 1000); |
| return 0; |
| } |
| |
| U_BOOT_CMD( |
| delayed_reboot, 1, 1, do_delayed_reboot, |
| "delayed_reboot ", |
| "delayed_reboot " |
| ); |
| |
| int do_set_panic_count(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
| { |
| char key[] = "kernel_panic_counter"; |
| uint32_t reboot_mode_val = 0; |
| char value[16] = "\0"; |
| int ret = 0; |
| int count = 0; |
| |
| reboot_mode_val = get_reboot_mode_val(); |
| |
| if((reboot_mode_val == AMLOGIC_KERNEL_PANIC) && is_flash_inited()) { |
| flash_ts_init(); |
| |
| flash_ts_get(key, value, sizeof(value)); |
| |
| count = simple_strtoul(value, NULL, 10); |
| count++; |
| ret = flash_ts_set(key, simple_itoa(count)); |
| pr_info("FTS set:%s -> %d\nReturn: %d\n", key, count, ret); |
| } |
| |
| return ret; |
| } |
| |
| U_BOOT_CMD( |
| set_panic_count, 1, 0, do_set_panic_count, |
| "Set FTS flag to record panic.", |
| "set_panic_count\n" |
| ); |