blob: 9b4713164d5da390d8c4411317268cad2f6e71c7 [file] [log] [blame]
#include "global.h"
#include <asm/arch/cpu.h>
#include <asm/io.h>
#include "common.h"
#define ST_WAIT_SYNC_FLAG (0x0)
#define ST_WAIT_REG_CONFIG (0x1)
#define ST_REG_CONFIG (0x2)
#define ST_WAIT_DOWNLOAD (0x3)
#define ST_DOWNLOAD_HEAD (0x4)
#define ST_DOWNLOAD_DATA (0x5)
#define ST_DOWNLOAD_ADDR (0x6)
#define SYNC_FLAG (0x5a) // "Z"
#define REG_CONFIG_FLAG (0x6a) // ""
#define DOWNLOAD_FLAG (0x7a) // "z"
#define RUN_FLAG (0x8a) // ""
#define GET_ID (0x9a) // new added
extern void USB3Slave_boot(void);
extern WORD32 usb_read(BYTE *pchBuf, WORD32 dwLen);
extern WORD32 usb_write(BYTE *pchBuf, WORD32 dwLen);
extern int UART_Read(char *pchBuf, int dwLen);
extern int UART_Write(char *pchBuf, int dwLen);
WORD32 Para_Section SyncACK=0xa5;
__align(4) BYTE Para_Section CHIP_ID[8]={'Z','X','7','5','2','0','V','2'};
WORD32 Para_Section UsbACK = 0;
void Boot_Process(BYTE *pkt,int len)
{
int i=0;
static int count=0;
static int addr;
static int value;
char cTmp=0;
//WORD32 SyncACK=0xa5;
int case_state;
if(0==len)
return ;
while(i<len)
{
cTmp=pkt[i++];
case_state = global.g_State;
if( ST_WAIT_SYNC_FLAG == case_state)
{
if(SYNC_FLAG==cTmp)
{
global.g_State=ST_WAIT_DOWNLOAD;
#if CFG_USB
usb_write((BYTE *)&SyncACK,1);
#else
UART_Write((BYTE *)&SyncACK,1);
#endif
}
}
else if(ST_REG_CONFIG ==case_state)
{
if(count<4) // 4 bytes addr
{
addr<<=8;
addr|=cTmp;
}
else if(count<8) // 4 byte data
{
value<<=8;
value|=cTmp;
}
count++;
if(4==count)
{
if(0==addr)
{
global.g_State=ST_WAIT_DOWNLOAD;
UsbACK=0xA6;
#if CFG_USB
usb_write(&UsbACK,1);
#else
UART_Write(&UsbACK,1);
#endif
}
}
else if(8==count)
{
REG32(addr)=value;
count=0;
}
}
else if (ST_WAIT_DOWNLOAD==case_state)
{
if(REG_CONFIG_FLAG==cTmp)
{
global.g_State=ST_REG_CONFIG;
count=0;
}
else if(DOWNLOAD_FLAG==cTmp)
{
global.g_State=ST_DOWNLOAD_HEAD;
count=0;
value=0;
}
else if(RUN_FLAG==cTmp) //Ö§³Ö¶à´ÎÏÂÔØ0818
{
global.g_State=ST_DOWNLOAD_ADDR;
count=0;
value=0;
}
}
else if( ST_DOWNLOAD_HEAD==case_state)
{
if(count<4) // 4 byte addr
{
addr<<=8;
addr|=cTmp;
}
else if(count<8) // 4 byte size
{
value<<=8;
value|=cTmp;
}
count++;
if(count==8)
{
count=0;
global.g_bootaddr=addr; //µØÖ·
global.g_bootsize=value;//³¤¶È
global.g_State=ST_DOWNLOAD_DATA;
UsbACK=0xA1;
#if CFG_USB
usb_write(&UsbACK,1);
#else
UART_Write(&UsbACK,1);
#endif
}
}
else if( ST_DOWNLOAD_DATA==case_state)
{
if(global.g_bootsize==len)
{
if(global.g_bootaddr==(int)pkt)
{
global.g_State=ST_WAIT_DOWNLOAD;//Ö§³Ö¶à´ÎÏÂÔØ0818
UsbACK=0xA7;
#if CFG_USB
usb_write(&UsbACK,1);
#else
UART_Write(&UsbACK,1);
#endif
return;
}
}
else
{
global.g_bootaddr+=len;
global.g_bootsize-=len;
return ;
}
}
else if( ST_DOWNLOAD_ADDR==case_state)
{
if(count<4) // 4 byte addr
{
addr<<=8;
addr|=cTmp;
}
count++;
if(count==4)
{
count=0;
global.g_bootaddr=addr;
global.g_bootfinish=1;
UsbACK=0xA8;
#if CFG_USB
usb_write(&UsbACK,1);
#else
UART_Write(&UsbACK,1);
#endif
return ;
}
}
else
{
}
}
}
__align(4) BYTE Para_Section tmp[64]={0};
void USB_Boot(void)
{
WORD32 dwLen;
WORD32 dwMaxLen;
BYTE *pbyBuf;
printf("USB_Boot\n");
global.g_State = ST_WAIT_SYNC_FLAG;
pbyBuf = (BYTE*)tmp;
for(dwMaxLen = 0; dwMaxLen < 64; dwMaxLen++)
{
tmp[dwMaxLen] = 0;
}
dwMaxLen = 512; //¿ØÖÆÆ÷ÓÐÒªÇóbulk outʱ£¬½ÓÊÕ³¤¶È´óÓÚµÈÓÚ512
/* µ±usb_mode =1ʱ£¬ÓÃÓÚHSIC,µ±usb_mode =0ʱ£¬ÓÃÓÚUSB */
if(global.g_USB_MODE == 0)
{
dwLen=USB_Check_Sync(pbyBuf,dwMaxLen);
if(0==dwLen)
{
return ;
}
Boot_Process(pbyBuf,dwLen);
}
while(0 == global.g_bootfinish)
{
dwLen=usb_read(pbyBuf,dwMaxLen);
Boot_Process(pbyBuf,dwLen);
if((ST_DOWNLOAD_DATA==global.g_State)&&(global.g_bootaddr!=0))
{
pbyBuf=(BYTE *)global.g_bootaddr;
dwMaxLen= 512;//global.g_bootsize;
}
else
{
pbyBuf=tmp;
dwMaxLen=512;//½ÓÊÕµØÖ·£¬³¤¶ÈÐÅÏ¢
}
}
if(1==global.g_bootfinish)
{
#if 0 /*shield dma function*/
dwc_otg_core_dev_disconnet(global.g_dwc_otg_pcd_tp.core_if);
printf("disconnect usb controller\n");
#endif
writel(0xE59ff000, SYS_IRAM1_BASE); /* Ìø×ªµ½r7Ö´ÐÐtboot */
writel(global.g_bootaddr, SYS_IRAM1_BASE + 8);
printf("Starting the tboot...\n");
writel(0xf, CPU_A9_SUBSYS_CFG);
}
}
void usb_boot(WORD32 USB_ADDR)
{
global.g_USB_TIMEOUT = 0xff;
//USB3Slave_boot();
tsp_usb_init();
USB_Boot(); /*usb bootÏÂÔØÄ£Ê½*/
}
/*******************************************************************************
* Function: uart_boot
* Description: download from uart-bootrom
* Parameters:
* Input:
*
* Output:
*
* Returns:
*
*
* Others:
********************************************************************************/
void UART_Boot(void)
{
WORD32 dwLen;
WORD32 dwMaxLen;
BYTE *pbyBuf;
printf("UART_Boot\n");
global.g_State = ST_WAIT_SYNC_FLAG;
pbyBuf = (BYTE*)tmp;
for(dwMaxLen = 0; dwMaxLen < 64; dwMaxLen++)
{
tmp[dwMaxLen] = 0;
}
dwMaxLen = 512; //¿ØÖÆÆ÷ÓÐÒªÇóbulk outʱ£¬½ÓÊÕ³¤¶È´óÓÚµÈÓÚ512
/* µ±usb_mode =1ʱ£¬ÓÃÓÚHSIC,µ±usb_mode =0ʱ£¬ÓÃÓÚUSB */
if(global.g_USB_MODE == 0)
{
dwLen=UART_Check_Sync(pbyBuf,dwMaxLen);
if(0==dwLen)
{
return ;
}
Boot_Process(pbyBuf,dwLen);
}
while(0 == global.g_bootfinish)
{
dwLen=UART_Read(pbyBuf,1); //0x7a uart
if(*pbyBuf == 0x7a)
{
dwLen=UART_Read(pbyBuf,4);
global.g_bootaddr = pbyBuf[3]|pbyBuf[2]<<8|pbyBuf[1]<<16|pbyBuf[0]<<24;
dwLen=UART_Read(pbyBuf,4);
global.g_bootsize = pbyBuf[3]|pbyBuf[2]<<8|pbyBuf[1]<<16|pbyBuf[0]<<24;
}
dwLen=UART_Read(global.g_bootaddr,global.g_bootsize);
dwLen=UART_Read(pbyBuf,1); //0x8a
if(*pbyBuf == 0x8a)
{
global.g_bootfinish = 1;
dwLen=UART_Read(pbyBuf,4);
global.g_bootaddr = pbyBuf[3]|pbyBuf[2]<<8|pbyBuf[1]<<16|pbyBuf[0]<<24;
}
}
if(1==global.g_bootfinish)
{
writel(0xE59ff000, SYS_IRAM1_BASE); /* Ìø×ªµ½r7Ö´ÐÐtboot */
writel(global.g_bootaddr, SYS_IRAM1_BASE + 8);
printf("Starting the tboot ...\n");
writel(0xf, CPU_A9_SUBSYS_CFG);
}
}
void uart_boot(void)
{
global.g_USB_TIMEOUT = 0xff;
UART_Boot(); /*uart bootÏÂÔØÄ£Ê½*/
}