blob: 8800b53553b94a80615754236023a90f50ca433b [file] [log] [blame]
/*
* \file aml_v2_burning.c
* \brief common interfaces for version 2 burning
*
* \version 1.0.0
* \date 09/15/2013
* \author Sam.Wu <yihui.wu@amlgic.com>
*
* Copyright (c) 2013 Amlogic. All Rights Reserved.
*
*/
#include "v2_burning_i.h"
#include <mmc.h>
#include <asm/arch/secure_apb.h>
#include <asm/arch/io.h>
#include <asm/arch/bl31_apis.h>
#ifndef BOOT_DEVICE_USB
#define BOOT_DEVICE_SD 4
#define BOOT_DEVICE_USB 5
#endif// #ifndef BOOT_DEVICE_USB
extern int v2_usbburning(unsigned timeout);
extern int optimus_burn_package_in_sdmmc(const char* sdc_cfg_file);
extern void close_usb_phy_clock(int cfg);
//check ${sdcburncfg} exist in external mmc and internal flash not burned yet!
int aml_check_is_ready_for_sdc_produce(void)
{
char* sdc_cfg_file = NULL;
const char* cmd = NULL;
int ret = 0;
//if reboot_mode is MESON_SDC_BURNER_REBOOT, then this booting is skip_booted for sdc_burning
if (/*MESON_SDC_BURNER_REBOOT != reboot_mode*/ 0) {
/*DWN_MSG("reboot_mode=0x%x\n", (unsigned int)reboot_mode);*/
return 1;//not ready
}
cmd = "mmcinfo";
ret = run_command(cmd, 0);
if (ret) {
DWN_MSG("mmcinfo failed!\n");
return 0;//not ready
}
sdc_cfg_file = getenv("sdcburncfg");
if (!sdc_cfg_file) {
sdc_cfg_file = "aml_sdc_burn.ini";
setenv("sdcburncfg", sdc_cfg_file); }
cmd = "fatsize mmc 0 ${sdcburncfg}";
ret = run_command(cmd, 0);
if (ret) {
DWN_DBG("%s not exist\n", sdc_cfg_file);
return 0;
}
return 1;//is ready for sdcard producing
}
static unsigned _get_romcode_boot_id(void)
{
DWN_DBG("P_AO_SEC_GP_CFG0=0x%p\n", P_AO_SEC_GP_CFG0);
const unsigned boot_id = readl(P_AO_SEC_GP_CFG0) & 0xf;
DWN_DBG("boot_id()=%x\n", boot_id);
return boot_id;
}
//is the uboot loaded from usb otg
int is_tpl_loaded_from_usb(void)
{
const int boot_id = _get_romcode_boot_id();
const unsigned forceUsbBoot = readl(P_AO_SEC_GP_CFG7) ;
DWN_DBG("forceUsbBoot=%p, %x\n", P_AO_SEC_GP_CFG7, forceUsbBoot);
int ret = (BOOT_DEVICE_USB == boot_id) || ( forceUsbBoot & (1U<<31) );
return ret;
}
//is the uboot loaded from sdcard mmc 0
//note only sdmmc supported by romcode when external device boot
int is_tpl_loaded_from_ext_sdmmc(void)
{
return (BOOT_DEVICE_SD == _get_romcode_boot_id());
}
//Check if uboot loaded from external sdmmc or usb otg
int aml_burn_check_uboot_loaded_for_burn(int flag)
{
int usb_boot = is_tpl_loaded_from_usb();
int sdc_boot = is_tpl_loaded_from_ext_sdmmc();
return usb_boot || sdc_boot;
}
//1, is booted from external sdmmc: check if aml_sdc_burn.ini existed
//2, if loaded from usb, ready for burn
int aml_burn_check_is_ready_for_burn(int flag, bd_t* bis)
{
if (is_tpl_loaded_from_usb()) {
return 1;
}
if (is_tpl_loaded_from_ext_sdmmc())
{
return aml_check_is_ready_for_sdc_produce();
}
return 0;
}
//producing mode means boot from raw flash, i.e, uboot is loaded from usb
int aml_burn_usb_producing(int flag, bd_t* bis)
{
flag = flag; bis = bis;//avoid compile warning
set_usb_boot_function(CLEAR_USB_BOOT);
#if (defined AML_USB_BURN_TOOL)
optimus_work_mode_set(OPTIMUS_WORK_MODE_USB_PRODUCE);
#endif//#if (defined AML_USB_BURN_TOOL)
close_usb_phy_clock(0);//disconect before re-connect to enhance pc compatibility
return v2_usbburning(20000);
}
int aml_burn_sdc_producing(int flag, bd_t* bis)
{
optimus_work_mode_set(OPTIMUS_WORK_MODE_SDC_PRODUCE);
return optimus_burn_package_in_sdmmc(getenv("sdcburncfg"));
}
//burning flash from romboot stage
int aml_burn_factory_producing(int flag, bd_t* bis)
{
if (is_tpl_loaded_from_usb())
{
return aml_burn_usb_producing(flag, bis);
}
if (is_tpl_loaded_from_ext_sdmmc())
{
return aml_burn_sdc_producing(flag, bis);
}
DWN_ERR("Shouldnot reach here!\n");
return 0;
}
extern void serial_initialize(void);
int aml_try_factory_usb_burning(int flag, bd_t* bis)
{
if (!is_tpl_loaded_from_usb()) return 1;
if ( !flag ) {
serial_initialize();//init for write memory
#ifdef CONFIG_MMC
DWN_MSG("MMC init in usb\n");
mmc_initialize(bis);
#endif
}
return aml_burn_usb_producing(flag, bis);
}
int aml_try_factory_sdcard_burning(int flag, bd_t* bis)
{
if (!is_tpl_loaded_from_ext_sdmmc()) return 1;
if ( aml_check_is_ready_for_sdc_produce() )
{
return aml_burn_sdc_producing(flag, bis);
}
return 0;
}