blob: b72ce9325f7222582d0761b2c215cf5725eb0320 [file] [log] [blame]
/*
* Copyright (C) 2016 ZXIC Inc.
*
*/
#include <common.h>
#include <version.h>
#include <asm/io.h>
#include <asm/string.h>
#include <asm/arch/cpu.h>
#include <image.h>
#include <linux/byteorder/generic.h>
#include <load_mode.h>
#include <asm/arch/top_clock.h>
#include <asm/arch/uart.h>
#include "config.h"
#include "ddr.h"
#include "../drivers/efuse.h"
#include "../drivers/flash.h"
#include "pub_flags.h"
#define FLAGS_PARTITION_ERROR (0x1111) /*·ÖÇøÒì³£*/
//xf.li@20230815 add for download without powerkey start
#define GPIO0_REG_BASE 0x0013D000
#define GPIO24_PSHOLD (24)
#define IO_CFG_BASE (0x0013C000+0x800)
//xf.li@20230815 add for download without powerkey end
typedef short (init_fnc_t) (void);
int print_info(void)
{
#if defined(CFG_ZLOAD)
printf ("\nInc zloader 1.3.4\n");
#else
printf ("\nInc tLoader 1.3.4\n");
#endif
return 0;
}
void copy_to_iram1(void)
{
memcpy(0x100000, 0x8a000, 0x2000); /* TEXT_BASE=0x100000 */
writel(CFG_START_STAGE1_STATE, CFG_START_STAGE1_ADDR);
}
/*
******************************************************************************
* Function:
* Description:
* Parameters:
* Input:
* Output:
* Returns:
* Others: IRAM addr is provided from ap
*******************************************************************************
*/
void clear_iram( void )
{
uint32_t i = 0;
for( i=0x82000400; i<=0x82003400; i+=4 )
{
writel(0x0, i);
}
}
/*
******************************************************************************
* Function:
* Description:
* Parameters:
* Input:
* Output:
* Returns:
* Others:
*******************************************************************************
*/
void write_loader_mode(uint32_t mode)
{
writel(mode, CFG_BOOT_MODE_SAVE_ADDR_FOR_UBOOT);
}
void hang (void)
{
/* call board specific hang function */
for (;;);
}
/*******************************************************************************
* Function:
* Description:
* Parameters:
* Input:
*
* Output:
*
* Returns:
*
*
* Others:
********************************************************************************/
void usb_apcore_poweroff(void)
{
u32 tmp;
tmp =readl(USB_RESET); /*usb hsic reset*/
tmp &= ~0x7;
writel(tmp, USB_RESET);
tmp =readl(CORE_OUTPUT_SWITCH_CONFIG_REG);/*ap clk&mg control by sw*/
tmp &= ~((0x1<<2)|(0x1<<5));
writel(tmp, CORE_OUTPUT_SWITCH_CONFIG_REG);
tmp =readl(CORE_OUTPUT_SW_CONFIG_REG1);/*ap clk off*/
tmp &= ~(0x1<<2);
writel(tmp, CORE_OUTPUT_SW_CONFIG_REG1);
tmp =readl(CORE_OUTPUT_SW_CONFIG_REG2);/*ap mg iso*/
tmp |= (0x1<<5);
writel(tmp, CORE_OUTPUT_SW_CONFIG_REG2);
usdelay(1);
tmp =readl(CORE_OUTPUT_SW_CONFIG_REG2);/*ap mg rst*/
tmp |= (0x1<<4);
writel(tmp, CORE_OUTPUT_SW_CONFIG_REG2);
usdelay(1);
tmp =readl(CORE_OUTPUT_SW_CONFIG_REG2);/*ap mg off*/
tmp &= ~(0x1<<3);
writel(tmp, CORE_OUTPUT_SW_CONFIG_REG2);
//__REG(0x0013a0ac) &= ~((0x1<<2)|(0x1<<5)); /*ap clk&mg control by sw*/
//__REG(0x0013a0b8) &= ~(0x1<<2); /*ap clk off*/
//__REG(0x0013a0bc) |= (0x1<<5); /*ap mg iso*/
//__REG(0x0013a0bc) |= (0x1<<4); /*ap mg rst*/
//__REG(0x0013a0bc) &= ~(0x1<<3); /*ap mg off*/
}
//#ifdef CONFIG_ZX297520V3E_MDL_AB
#if defined(CONFIG_ZX297520V3E_MDL_AB) || defined(CONFIG_ZX297520V3E_VEHICLE_DC) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF)
void start_armboot (void)
{
int32_t ret = 0;
int32_t add;
uint32_t amt_value = 0;
int32_t err_flag = 0;
T_BOOT_TARGET bootTarget;
T_FLAGS flagsData;
T_FLAGS_INFO *fotaFlag;
T_BOOT_DUALSYSTEM_TYPE dualSystemType;
clk_init();
timer_init();
#if CFG_PRINTF
uart_init();
#endif
//xf.li@20230815 add for download without powerkey start
#if 1//pshold on
amt_value = readl(IO_CFG_BASE+0x4);
amt_value &= ~(3<<28);
writel(amt_value, (IO_CFG_BASE+0x4));
/*direction: out*/
amt_value = readl(GPIO0_REG_BASE + (GPIO24_PSHOLD/16)*0x40);
amt_value &= ~(1<<(24%16));
writel(amt_value, GPIO0_REG_BASE + (GPIO24_PSHOLD/16)*0x40);
/*set out 1*/
amt_value = readl(GPIO0_REG_BASE + 0x18+ (GPIO24_PSHOLD/16)*0x40);
amt_value |= (1<<(24%16));
writel(amt_value, GPIO0_REG_BASE + 0x18+ (GPIO24_PSHOLD/16)*0x40);
#endif
//xf.li@20230815 add for download without powerkey end
print_info();
/* After reset, Copy zloader forcely. */
/* Now IRAM1 maybe occupied by dirty data. */
writel(0, CFG_START_STAGE1_ADDR);
amt_value = readl(CFG_AMT_MODE_SWITCH_ADDR);
clear_iram();
writel(amt_value, CFG_AMT_MODE_SWITCH_ADDR);
ret = board_flash_init();
if(ret != 0)
{
goto error;
}
efuse_init();
if(get_ddr_flag() == CHIP_DDR_IS_32M)
{
ddr_init(CHIP_DDR_IS_32M);
}
else if(get_ddr_flag() == CHIP_DDR_IS_64M)
{
ddr_init(CHIP_DDR_IS_64M);
}
else if(get_ddr_flag() == CHIP_DDR_IS_128M)
{
ddr_init(CHIP_DDR_IS_128M);
}
else if(get_ddr_flag() == CHIP_DDR_IS_256M)
{
ddr_init(CHIP_DDR_IS_256M);
}
else if(get_ddr_flag() == CHIP_DDR_IS_512M)
{
ddr_init(CHIP_DDR_IS_512M);
}
else
{
ddr_init(CHIP_DDR_IS_128M);
}
usb_apcore_poweroff();
/********************* ÔËÐÐT-LOAD,½øÈëÏÂÔØÄ£Ê½ ******************/
#if defined(CFG_TLOAD)
write_loader_mode(CFG_TLOAD_MODE);
#if CFG_USB
usb_boot(SYS_USB_BASE);
#endif
#if CFG_UART
uart_boot();
#endif
#endif /* CFG_TLOAD */
/********************* ÔËÐÐZ-LOAD,½øÈëÕý³£Æô¶¯Ä£Ê½ **********/
#if defined(CFG_ZLOAD)
uint32_t uboot_entry_point = 0;
char boot_mode = 0;
write_loader_mode(CFG_ZLOAD_MODE);
/*read flags·ÖÇø*/
ret = read_flags_image((uint8_t *)FLAGS_IMAGE);
if( ret != 0 )
{
printf("read flags partition error! Use default parameters\n");
//goto error;
err_flag = 1;
/*ĬÈÏflags·ÖÇøÊý¾Ý*/
flagsData.magic_start = FLAGS_MAGIC;
flagsData.boot_fota_flag.boot_to = DUAL_SYSTEM;
flagsData.boot_fota_flag.fota_status = 1;
flagsData.boot_fota_flag.system.status = DUALSYSTEM_STATUS_BOOTABLE;
flagsData.boot_fota_flag.system2.status = DUALSYSTEM_STATUS_BOOTABLE;
flagsData.magic_end = FLAGS_MAGIC;
fotaFlag = &flagsData;
}
else
{
fotaFlag = (T_FLAGS_INFO *)(CFG_TEMP_ADDR);
}
bootTarget = fotaFlag->boot_fota_flag.boot_to;
writel(DUALSYSTEM_STATUS_BOOTABLE, BOOT_FLAG_ADDR);/*ĬÈÏ¿ÉÆô¶¯*/
if(bootTarget == DUAL_SYSTEM)
{
if (fotaFlag->boot_fota_flag.system.status == DUALSYSTEM_STATUS_UNBOOTABLE)
{
printf("dual_system status is unbootable!");
goto error;
}
ret = read_uboot_image((uint8_t *)UBOOT_IMAGE, &uboot_entry_point);
if( ret != 0)
{
printf("read uboot1 image error, goto uboot2!");
writel(DUALSYSTEM_STATUS_UNBOOTABLE, BOOT_FLAG_ADDR);
ret = read_uboot_image((uint8_t *)UBOOT2_IMAGE, &uboot_entry_point);
if( ret != 0)
{
printf("read uboot2 iamge error!");
goto error;
}
}
else
printf("goto uboot!");
}
else if(bootTarget == DUAL_SYSTEM2)
{
if (fotaFlag->boot_fota_flag.system2.status == DUALSYSTEM_STATUS_UNBOOTABLE)
{
printf("dual_system2 status is unbootable!");
goto error;
}
ret = read_uboot_image((uint8_t *)UBOOT2_IMAGE, &uboot_entry_point);
if( ret != 0)
{
printf("read uboot2 iamge error, goto uboot!");
writel(DUALSYSTEM_STATUS_UNBOOTABLE, BOOT_FLAG_ADDR);
ret = read_uboot_image((uint8_t *)UBOOT_IMAGE, &uboot_entry_point);
if( ret != 0)
{
printf("read uboot iamge error!");
goto error;
}
}
else
printf("goto uboot2!");
}
else
{
printf("boot target get error!");
goto error;
}
if(err_flag == 1)
{
writel(FLAGS_PARTITION_ERROR, BOOT_FLAG_ADDR);
}
printf("read uboot ok.\n");
/* set arm jump PC start code */
writel(0xE59ff000, SYS_IRAM1_BASE);
writel(uboot_entry_point, SYS_IRAM1_BASE + 8);
printf("start uboot...\n");
/* Relese A9 Core, A9 start to run uboot right now. */
writel(CPU_UFI_SW_RSTEN, CPU_A9_SUBSYS_CFG);
/* waiting for uboot read m0 image. */
uint32_t m0_entry_point = 0;
ret = nand_read_m0(&m0_entry_point);
if(ret != 0)
{
goto error;
}
/* M0 Core start to run cpurpm right now. */
((init_fnc_t *)m0_entry_point)();
#endif
error:
printf("ERR\n");
hang();
}
#else
void start_armboot (void)
{
int32_t ret = 0;
uint32_t amt_value = 0;
clk_init();
timer_init();
#if CFG_PRINTF
uart_init();
#endif
print_info();
/* After reset, Copy zloader forcely. */
/* Now IRAM1 maybe occupied by dirty data. */
writel(0, CFG_START_STAGE1_ADDR);
amt_value = readl(CFG_AMT_MODE_SWITCH_ADDR);
clear_iram();
writel(amt_value, CFG_AMT_MODE_SWITCH_ADDR);
ret = board_flash_init();
if(ret != 0)
{
goto error;
}
efuse_init();
if(get_ddr_flag() == CHIP_DDR_IS_32M)
{
ddr_init(CHIP_DDR_IS_32M);
}
else if(get_ddr_flag() == CHIP_DDR_IS_64M)
{
ddr_init(CHIP_DDR_IS_64M);
}
else if(get_ddr_flag() == CHIP_DDR_IS_128M)
{
ddr_init(CHIP_DDR_IS_128M);
}
else if(get_ddr_flag() == CHIP_DDR_IS_256M)
{
ddr_init(CHIP_DDR_IS_256M);
}
else if(get_ddr_flag() == CHIP_DDR_IS_512M)
{
ddr_init(CHIP_DDR_IS_512M);
}
else
{
ddr_init(CHIP_DDR_IS_128M);
}
usb_apcore_poweroff();
/********************* ÔËÐÐT-LOAD,½øÈëÏÂÔØÄ£Ê½ ******************/
#if defined(CFG_TLOAD)
write_loader_mode(CFG_TLOAD_MODE);
#if CFG_USB
usb_boot(SYS_USB_BASE);
#endif
#if CFG_UART
uart_boot();
#endif
#endif /* CFG_TLOAD */
/********************* ÔËÐÐZ-LOAD,½øÈëÕý³£Æô¶¯Ä£Ê½ **********/
#if defined(CFG_ZLOAD)
uint32_t uboot_entry_point = 0;
char boot_mode = 0;
write_loader_mode(CFG_ZLOAD_MODE);
ret = read_uboot_image((uint8_t *)UBOOT_IMAGE, &uboot_entry_point);
if( ret != 0 )
{
boot_mode = get_boot_mode();
if((boot_mode == SPI_NAND_BOOT) || (boot_mode == NAND_BOOT))
{
ret = read_uboot_image((uint8_t *)UBOOT_MIRROR_IMAGE,
&uboot_entry_point);
if(ret != 0)
{
goto error;
}
}
else
{
goto error;
}
}
//printf("read uboot ok.\n");
/* set arm jump PC start code */
writel(0xE59ff000, SYS_IRAM1_BASE);
writel(uboot_entry_point, SYS_IRAM1_BASE + 8);
printf("start uboot...\n");
/* Relese A9 Core, A9 start to run uboot right now. */
writel(CPU_UFI_SW_RSTEN, CPU_A9_SUBSYS_CFG);
/* waiting for uboot read m0 image. */
uint32_t m0_entry_point = 0;
ret = nand_read_m0(&m0_entry_point);
if(ret != 0)
{
goto error;
}
/* M0 Core start to run cpurpm right now. */
((init_fnc_t *)m0_entry_point)();
#endif
error:
printf("ERR\n");
hang();
}
#endif