| /* |
| * Copyright (C) 2017 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., |
| * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| * * |
| Description: |
| */ |
| |
| #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); |
| optimus_work_mode_set(OPTIMUS_WORK_MODE_USB_PRODUCE); |
| |
| 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; |
| } |
| |
| int aml_try_factory_usb_burning(int flag, bd_t* bis) |
| { |
| if (!is_tpl_loaded_from_usb()) return 1; |
| |
| if ( !flag ) { |
| #ifdef CONFIG_GENERIC_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; |
| } |
| |