blob: a410803bc47dd6e958e4d73c4b5650ae64100877 [file] [log] [blame]
#include "../v2_burning_i.h"
#include "usb_pcd.h"
#include "platform.h"
//#include <partition_table.h>
#include <asm/arch/cpu_id.h>
#define MYDBG(fmt ...) printf("OPT]"fmt)
#ifdef CONFIG_CMD_AML
#define USB_BURN_POWER_CONTROL 1
#endif// #ifdef CONFIG_CMD_AML
static inline int str2longlong(char *p, unsigned long long *num)
{
char *endptr;
*num = simple_strtoull(p, &endptr, 16);
if (*endptr != '\0')
{
switch (*endptr)
{
case 'g':
case 'G':
*num<<=10;
case 'm':
case 'M':
*num<<=10;
case 'k':
case 'K':
*num<<=10;
endptr++;
break;
}
}
return (*p != '\0' && *endptr == '\0') ? 1 : 0;
}
int optimus_mem_md (int argc, char * const argv[], char *info)
{
ulong addr, length = 0x100;
int size;
int rc = 0;
if ((size = cmd_get_data_size(argv[0], 4)) < 0)
return 1;
/* Address is specified since argc > 1
*/
addr = simple_strtoul(argv[1], NULL, 16);
/* If another parameter, it is the length to display.
* Length is the number of objects, not number of bytes.
*/
if (argc > 2)
length = simple_strtoul(argv[2], NULL, 16);
/* Print the lines. */
print_buffer(addr, (void*)addr, size, length, 16/size);
strcpy(info, "success");
return rc;
}
int set_low_power_for_usb_burn(int arg, char* buff)
{
if (OPTIMUS_WORK_MODE_USB_PRODUCE == optimus_work_mode_get()) {
return 0;//just return ok as usb producing mode as LCD not initialized yet!
}
#if defined(CONFIG_VIDEO_AMLLCD)
int ret1=0;
//axp to low power off LCD, no-charging
MYDBG("To close LCD\n");
ret1 = run_command("video dev disable", 0);
if (ret1) {
if (buff) sprintf(buff, "Fail to close back light") ;
printf("Fail to close back light\n");
/*return __LINE__;*/
}
#endif// #if defined(CONFIG_VIDEO_AMLLCD)
#if USB_BURN_POWER_CONTROL
int ret2=0;
//limit vbus curretn to 500mA, i.e, if hub is 4A, 8 devices at most, arg3 to not set_env as it's not inited yet!!
MYDBG("set_usbcur_limit 500 0\n");
ret2 = run_command("set_usbcur_limit 500 0", 0);
if (ret2) {
if (buff) sprintf(buff, "Fail to set_usb_cur_limit") ;
printf("Fail to set_usb_cur_limit\n");
return __LINE__;
}
#endif//#if USB_BURN_POWER_CONTROL
return 0;
}
int cb_4_dis_connect_intr(void)
{
if (optimus_burn_complete(OPTIMUS_BURN_COMPLETE__QUERY))
{
close_usb_phy_clock(0);//disconnect to avoid k200 platfrom which can't relally poweroff
DWN_MSG("User Want poweroff after disconnect\n");
optimus_poweroff();
}
return 0;
}
static int _cpu_temp_in_valid_range(int argc, char* argv[], char* errInfo)
{
int ret = 0;
int minTemp = 0;
int maxTemp = 0;
int cpu_temp = 0;
char* env_cpu_temp = NULL;
if (3 > argc) {
sprintf(errInfo, "argc %d < 3 is invalid\n", argc);
return __LINE__;
}
minTemp = simple_strtol(argv[1], NULL, 0);
maxTemp = simple_strtol(argv[2], NULL, 0);
if (minTemp <=0 || maxTemp <= 0 || minTemp >= maxTemp) {
sprintf(errInfo, "Invalid:minTemp=%s, maxTemp=%s\n", argv[1], argv[2]);
return __LINE__;
}
ret = run_command("read_temp", 0);
if (ret < 0) {
sprintf(errInfo, "cmd[cpu_temp] failed\n");
return __LINE__;
}
env_cpu_temp = getenv("tempa");
if (!env_cpu_temp) {
sprintf(errInfo, "Can't get cpu_temp, cpu is not calibrated.\n");
return __LINE__;
}
cpu_temp = simple_strtol(env_cpu_temp, NULL, 0);
ret = (cpu_temp >= minTemp && cpu_temp <= maxTemp) ? 0 : __LINE__;
if (!ret) {
sprintf(errInfo, "%s", env_cpu_temp);
}
else{
sprintf(errInfo, "%s is out of temp range[%d, %d], errInfo[%s]\n", env_cpu_temp, minTemp, maxTemp, getenv("err_info_tempa"));
}
return ret;
}
static int _get_chipid(char* buff)
{
int i = 0;
unsigned char chipid[16];
int ret = get_chip_id(chipid, 16);
if ( ret ) {
DWN_ERR("_get_chipid %d", ret);
return ret;
}
buff[0] = ':', buff[1]='\0';
for (; i < 12; ++i) {
sprintf(buff, "%s%02x", buff, chipid[15-i]);
}
return 0;
}
int optimus_working (const char *cmd, char* buff)
{
static char cmdBuf[CMD_BUFF_SIZE] = {0};
int ret = 0;
int argc = 33;
char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */
const char* optCmd = NULL;
memset(buff, 0, CMD_BUFF_SIZE);
memcpy(cmdBuf, cmd, CMD_BUFF_SIZE);
if ((argc = cli_simple_parse_line(cmdBuf, argv)) == 0)
{
strcpy(buff, "failed:no command at all");
printf("no command at all\n");
return -1; /* no command at all */
}
optCmd = argv[0];
if (!strcmp("low_power", optCmd))
{
ret = set_low_power_for_usb_burn(1, buff);
}
else if(strcmp(optCmd, "disk_initial") == 0)
{
unsigned erase = argc > 1 ? simple_strtoul(argv[1], NULL, 0) : 0;
ret = optimus_storage_init(erase);
}
else if(!strcmp(optCmd, "bootloader_is_old"))
{
ret = is_tpl_loaded_from_usb();
if (ret)sprintf(buff, "Failed, bootloader is new\n") ;
}
else if(!strcmp(optCmd, "erase_bootloader"))
{
ret = optimus_erase_bootloader("usb");
if (ret)sprintf(buff, "Failed to erase bootloader\n") ;
}
else if(strcmp(optCmd, "reset") == 0)
{
close_usb_phy_clock(0);
optimus_reset(OPTIMUS_BURN_COMPLETE__REBOOT_NORMAL);
}
else if(strcmp(optCmd, "poweroff") == 0)
{
optimus_poweroff();
}
else if(strncmp(optCmd, "md", 2) == 0)
{
ret = optimus_mem_md(argc, argv, buff);
}
else if(!strcmp(optCmd, "download") || !strcmp("upload", optCmd))
{
ret = optimus_parse_download_cmd(argc, argv);
}
else if(!strcmp("key", optCmd))
{
ret = v2_key_command(argc, argv, buff);
}
else if(!strcmp("verify", optCmd))
{
ret = optimus_media_download_verify(argc, argv, buff);
}
else if(!strcmp("save_setting", optCmd))
{
ret = optimus_set_burn_complete_flag();
}
else if(!strcmp("burn_complete", optCmd))
{
unsigned choice = simple_strtoul(argv[1], NULL, 0);//0 is poweroff, 1 is reset system
if (OPTIMUS_BURN_COMPLETE__POWEROFF_AFTER_DISCONNECT != choice) {//disconnect except OPTIMUS_BURN_COMPLETE__POWEROFF_AFTER_DISCONNECT
close_usb_phy_clock(0);//some platform can't poweroff but dis-connect needed by pc
}
ret = optimus_burn_complete(choice);
}
else if(!strcmp(optCmd, "support_tempcontrol"))
{
#ifndef CONFIG_CMD_CPU_TEMP
ret = __LINE__;
#else
ret = 0;
#endif// #ifdef CONFIG_CMD_CPU_TEMP
sprintf(buff + 7, "cpu temp control cmd %s supported.\n", ret ? "NOT" : "DO");//7 == strlen("failed")
}
else if(!strcmp(optCmd, "tempcontrol"))
{
ret = _cpu_temp_in_valid_range(argc, argv, buff + 7);
}
else if(!strcmp(optCmd, "get_chipid"))
{
ret = _get_chipid(buff + 7);
}
else
{
int flag = 0;
ret = run_command(cmd, flag);
DWN_MSG("ret = %d\n", ret);
/*ret = ret < 0 ? ret : 0;*/
}
if (ret)
{
memcpy(buff, "failed:", strlen("failed:"));//use memcpy but not strcpy to not overwrite storage/key info
}
else
{
memcpy(buff, "success", strlen("success"));//use memcpy but not strcpy to not overwrite storage/key info
}
printf("[info]%s\n",buff);
return ret;
}