
/*
 * 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/aml_v2_burning.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 <asm/arch/watchdog.h>

/*
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;
	reboot_mode_val = ((readl(AO_SEC_SD_CFG15) >> 12) & 0xf);

	debug("reboot_mode(0x%x)=0x%x\n", AO_SEC_SD_CFG15, reboot_mode_val);

	// When executing from USB via `update bl2_boot`, stop in fastboot.
	if (is_tpl_loaded_from_usb()) {
		printf("overriding reboot_mode_val to fastboot for BL2 USB boot\n");
		reboot_mode_val = AMLOGIC_FASTBOOT_REBOOT;
	}

#if defined(CONFIG_NAND_FTS)
	extern bool amlnf_is_inited(void);
	if (amlnf_is_inited()) {
#endif

#if defined(CONFIG_MMC_FTS)
	extern bool amlmmc_is_inited(void);
	if (amlmmc_is_inited()) {
#endif
		flash_ts_init();

		const char *fts_key = "bootloader.command";
		char fts_value[256] = { 0 };

		flash_ts_get(fts_key, fts_value, sizeof(fts_value));
#ifdef BL33_DEBUG_PRINT
		printf("FTS read: bootloader.command -> %s (not used)\n", fts_value);
#endif
	}

	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;
		}
		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: {
			env_set("bootdelay","-1");
			break;
		}
	}
#endif

#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, "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)
			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 {
			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 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"
	"    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 "
);
