blob: 22486d6f14bb20961099d5c8597198d5354cab49 [file] [log] [blame]
/*
* 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"
);