📄 initm803xx.c
字号:
Modem_Addr=(unsigned long *)(CSM_addr+TX_FIFO_SIZE);
while( Swap_Word(*(Modem_Addr)) >= 0x80)
{
;
}
for(j = 0; j < 30; j++)
{
;
}
Modem_Addr=(unsigned long *)(CSM_addr + HOST_START_DATA_ADD);
#if 0 /* 由于pw指针已经是网络字节序,因此不再需要转换 */
*Modem_Addr = Swap_Word(*pw);
#else
*Modem_Addr = *pw;
#endif
pw ++;
}
}
/*write 60000 byte to M803xx 64M SDRAM in a write circle*/
LOCAL void LoadData_ToCSM(unsigned long *pw,unsigned long size,unsigned long base_addr,unsigned long CSM_addr)
{
MBOX_PACKET msg;
unsigned short bCount;
while (size)
{
bCount = (0xea60 < size) ? 0xea60 : size; /* 60000 Byte */
while ((ReadFromRegister(FIFO_STA_REG,CSM_addr) & TXE_MASK) == 0)
{
;
}
if ( bCount <=0xff )
{
trans_data_tofifo(pw,bCount,CSM_addr);
WriteToMbox((unsigned short)bCount,(unsigned short)(base_addr>>16),
(unsigned short)base_addr,PCI_BRM_FIFOWRITE,CSM_addr);
}
else
{
WriteToMbox((unsigned short)bCount,(unsigned short)(base_addr>>16),
(unsigned short)base_addr,PCI_BRM_FIFOWRITE,CSM_addr);
trans_data_tofifo(pw,bCount,CSM_addr);
}
WriteToRegister(FIFO_STA_REG,CSM_addr,TXM3IAK_MASK);
ReadFromMbox(&msg,CSM_addr);
if (msg.message != PCI_BRM_CMD_ACK) /*BspOnRedLed()*/
{
;/*这里是否有相应的提示信息*/
}
size = size - bCount;
base_addr = base_addr + bCount;
pw = (unsigned long *)(pw + bCount/4);
}
}
BOOL Programstart(unsigned long prog_entry,unsigned long CSM_addr)
{
MBOX_PACKET msg;
if(!WriteToMbox(0,(unsigned short)(prog_entry>>16),(unsigned short)prog_entry,PCI_BRM_PROGSTART,CSM_addr))
return FALSE;
if(!ReadFromMbox(&msg,CSM_addr)) return FALSE;
if (msg.message != SUPVSR ) return FALSE;
return TRUE;
}
LOCAL unsigned char DownLoadFirmware(unsigned long CSM_addr)
{
unsigned long Addrtemp, fat_offset,dest;
unsigned long fat_size, file_offset_next, *FirmWare_File_Header;
volatile unsigned long *pw,prog_entry;
FAT_AIF_HEADER fat_aif_header,*fataif;
/* download CODE*/
pw=(unsigned long *)(bDmFile + 0x80); /*code_offset*/
LoadData_ToCSM((unsigned long *)pw,aif_header.image_readonly_size,aif_header.image_base,CSM_addr);
/* if(!CheckLoadedData(pw,aif_header.image_readonly_size,aif_header.image_base,CSM_addr))
return FALSE;*/
/* download data*/
pw=(unsigned long *)(bDmFile + 0x80 + aif_header.image_readonly_size);
dest = aif_header.image_base + aif_header.image_readonly_size;
LoadData_ToCSM((unsigned long *)pw,aif_header.image_readwrite_size,dest,CSM_addr);
/* if(!CheckLoadedData(pw,aif_header.image_readwrite_size,dest,CSM_addr))
return FALSE;*/
/*download fat*/
fat_offset = aif_header.first_fat;
while(fat_offset)
{
FirmWare_File_Header = (unsigned long *)(bDmFile + fat_offset);
fataif = (FAT_AIF_HEADER*) FirmWare_File_Header;
fat_aif_header = *fataif; /* set the fat header struct */
file_offset_next = Swap_Word(*(FirmWare_File_Header)); /* 1st byte is offset */
Addrtemp = Swap_Word(*(FirmWare_File_Header+0x01)); /* 2ed byte is addr */
fat_size = Swap_Word(*(FirmWare_File_Header+0x02)); /* 3th byte is size */
pw = (unsigned long *)(bDmFile + fat_offset + 0x002c);
if( (fat_aif_header.region_name[0]!=0x56) ||
(fat_aif_header.region_name[1]!=0x45) ||
(fat_aif_header.region_name[2]!=0x43) ||
(fat_aif_header.region_name[3]!=0x54) ||
(fat_aif_header.region_name[4]!=0x4f) ||
(fat_aif_header.region_name[5]!=0x52) ||
(fat_aif_header.region_name[6]!=0x53) ||
(fat_aif_header.region_name[7]!=0x5f) ||
(fat_aif_header.region_name[8]!=0x4c) ||
(fat_aif_header.region_name[9]!=0x52) )
{
if(fat_size)
{
LoadData_ToCSM((unsigned long *)pw,fat_size,Addrtemp,CSM_addr);
}
}
fat_offset=file_offset_next;
}
prog_entry = aif_header.image_base + aif_header.bl_image_entry_point;
if(!Programstart(prog_entry,CSM_addr)) return FALSE;
return TRUE;
}
BOOL M803xx_ZeroInit(UINT32 Addr)
{
UINT32 bcount,size,memaddr,database;
bcount = 0x10000;
size = aif_header.image_zero_init_size;
if(aif_header.data_base)
database = aif_header.data_base;
else
database = aif_header.image_base + aif_header.image_readonly_size;
memaddr = database + aif_header.image_readwrite_size;
while(size)
{
if(size < bcount)
{
bcount = size;
}
if(!WriteToMbox( (UINT16)memaddr, (UINT16)(memaddr>>16), bcount, PCI_BRM_ZEROFILL, Addr))
{
return FALSE;
}
else
{
;
}
size -= bcount;
memaddr += bcount;
}
return TRUE;
}
LOCAL BOOL TDM_Setup(unsigned long CSM_addr)
{
MBOX_PACKET msg;
#if 0
WriteToMbox(0x0,0x0400,0x8320,0xd7ff,CSM_addr);
#else
WriteToMbox(0x0,0x0400,0x9b20,0xd7ff,CSM_addr);
#endif
ReadFromMbox(&msg,CSM_addr);
if (msg.message == PCI_BRM_ERRIND) return FALSE;
return TRUE;
}
/*************************************************************************/
/* Function name: InitChan */
/* Description : Initialize Channel */
/* Return type : void */
/* Argument : void */
/* Author/Date : Cao WanMing/2003-1-16 15:57 */
/* Note: */
/* */
/*************************************************************************/
LOCAL void InitChan(UINT8 PinNo, UINT32 Addr)
{
int ackMsgNum;
UINT8 PortNum;
MBOX_PACKET msg;
unsigned short chan,i,creatAck;
UINT32 rxBufAddrH,rxBufAddrL;
UINT32 *bufAddr, *buf;
void *tempAddr;
STATUS rc = ERROR;
for(chan = 0; chan < PORTS_OF_CHIP; chan++)
{
rc = ERROR;
PortNum = chan + PORTS_OF_CHIP * PinNo;
/* 配置通道类型和时隙 */
if (TRUE != WriteToMbox(0x0, (UINT16)chan, 0x2, 0xd0ff, Addr))
{
printf("When Init slot(%d) chan(%d), WriteToMbox failed!!!\n", PinNo, chan);
ASSERT(0);
}
#if M803xx_INIT_DEBUG
M80320_PRINTF("chan = %d, j = %d\n", chan, j);
#endif
creatAck = 0;
ackMsgNum = 0;
for(i = 0; i < 50; i++)
{
if(!ReadFromMbox(&msg,Addr))
continue ;
if((msg.message == SUPVSR_CREATE_CHANNEL_ACK) && (msg.p0 == LFXS_UP))
{
creatAck = 1;
m_channel[PortNum].ChanId = msg.p1;
m_channel[PortNum].TimeSlot = msg.p2;
ackMsgNum ++;
}
if((msg.message & 0xFF00) == CMD_DATAREQ)
{
/*2006-8-5 ZhengQishan 1 - 可以发送数据,0 - 不能发送数据*/
m_channel[PortNum].tx_data_requested = 1 /*msg.p0*/;
ackMsgNum ++;
}
if((msg.message & 0xFF00) == CMD_CMDREQ)
{
m_channel[PortNum].tx_cmd_requested = 1;
ackMsgNum ++;
}
/*如果三个消息都已经接收到,中断循环*/
if(3 == ackMsgNum)
break;
}
if(creatAck == 1)
{
m_channel[PortNum].Active = IDLE;
#if M803xx_INIT_DEBUG
M80320_PRINTF("M803xx Create_channel Command Ok");
#endif
}
else
{
printf("InitChan: Create channel {slot(%d) chan(%d)} failed!!!\n", PinNo, chan);
ASSERT(0);
}
}
Init_Port_Channel(PinNo);
/* 向这些通道发送初始化命令 */
for(chan = 0; chan < PORTS_OF_CHIP; chan++)
{
PortNum = chan + PORTS_OF_CHIP * PinNo;
if(m_channel[PortNum].Active == FAIL) continue;
if((m_channel[PortNum].Port) < ((PinNo+1)*M803XX_MAX_PORT_NUM))
{
WriteToMbox(0,0x0001,(UINT16)(m_port[m_channel[PortNum].Port].Slot),CMD_SETTSA|chan,Addr);
M80320_PRINTF("Port %d Slot %d\n", m_channel[PortNum].Port, m_port[m_channel[PortNum].Port].Slot);
}
M803xx_ALLOC_PCI_ADDR(bufAddr,tempAddr,buf);
if (buf == NULL)
{
M80320_PRINTF("M803xx Init PktAlloc Fail\n");
}
else
{
M80320_PRINTF("Port %d PktAlloc Pci Addr = %x, Mem Addr = %x\n",
PortNum, (unsigned int)bufAddr, (unsigned int)buf);
PciReadBuf[PortNum] = bufAddr;
rxBufAddrH = ((UINT32)((UINT8 *)bufAddr+PACKET_START_SIZE)) >> 16;
rxBufAddrL = ((UINT32)((UINT8 *)bufAddr+PACKET_START_SIZE)) & 0x0000ffff;
WriteToMbox(0, 0, 0, CMD_SETSYNC | chan, Addr);
WriteToMbox(rxBufAddrL,rxBufAddrH,0x400,CMD_PCIREQ | chan, Addr);
}
WriteToMbox(0, 0, 0x80, CMD_CMDREQ|chan, Addr);
}
M80320_PRINTF("PowerOnStart Ok\n");
}
void M803xx_Init(UINT8 PinNo, UINT32 Addr)
{
int i;
STATUS rc = ERROR;
aif_open(&aif_header);
/* 重复三次,都失败则上报初始化失败 */
for(i = 0; i < 3; i++)
{
if(!M803xx_HandShake(Addr))
{
printf("Slot(%d) M803xx Hand Shake Fail\n", (int)PinNo);
continue;
}
M80320_PRINTF("M803xx Hand Shake OK\n");
M803xx_DMAFIFO_Enable(Addr);
if(!M803xx_DeviceInit(Addr))
{
printf("Slot(%d) M803xx DeviceInit Fail\n", (int)PinNo);
continue;
}
M80320_PRINTF("M803xx DeviceInit OK\n");
if(!DownLoadFirmware(Addr))
{
printf("Slot(%d) M803xx Download Firmware Fail\n", (int)PinNo);
continue;
}
M80320_PRINTF("M803xx Download Firmware OK\n");
if(!M803xx_ZeroInit(Addr))
{
printf("Slot(%d) M803xx ZeroInit Fail\n", (int)PinNo);
continue;
}
M80320_PRINTF("M803xx ZeroInit OK\n");
if(!TDM_Setup(Addr))
{
printf("Slot(%d) M803xx Setup TDM Fail\n", (int)PinNo);
continue;
}
M80320_PRINTF("M803xx Setup TDM OK\n");
/* 置标志:芯片下载成功,可以工作 */
PinStatus[PinNo] = TRUE;
/* 下载完毕,初始化芯片上所有的通道 */
InitChan(PinNo, Addr);
M80320_PRINTF("M803xx Init OK\n");
rc = OK;
break;
}
if (OK != rc)
{
printf("Init M803xx which in Slot(%d) is failed!!!", (int)PinNo);
ASSERT(0);
}
}
/*-----------------------------
* setPortDefaultArg - 设置语音通道的缺省状态值
*
* Description:
*
* Argument:
* int PortNo - PortNo = (slot - 1) * 8 (每一个槽位最多8个端口) + port - 1
*
* Modified history
*------------------------------
* 2006-6-15 15:13 ZhengaQishan Created.
*
**/
void initGlobalVariableForM80320(void)
{
static int firstTimeInitM80320GV = 0;
if (0 == firstTimeInitM80320GV)
{
memset(m_txmbox, 0, MAX_PIN_NUM * sizeof(M80320_QUEUE));
memset(m_OpenChannelMailboxQueue, 0, MAX_PIN_NUM*M803XX_MAX_PORT_NUM*sizeof(M80320_QUEUE));
memset(m_TxDataQueue, 0, MAX_PIN_NUM*M803XX_MAX_PORT_NUM*sizeof(M80320_QUEUE));
memset(m_port, 0, MAX_PIN_NUM*M803XX_MAX_PORT_NUM*sizeof(M803xx_PORT_STATE));
memset(m_channel, 0, MAX_PIN_NUM*PORTS_OF_CHIP*sizeof(CHANNEL));
memset(Receive_Message, 0, MAX_PIN_NUM*MAX_RX_MSG_NUM*sizeof(MBOX_PACKET));
firstTimeInitM80320GV = 1;
}
else
printf("All global variable have been initilized.\n");
}
/*************************************************************************
* Function name: InitTxMboxQueue
* Description : Initialize TX Mailbox Queue
* Return type : void
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -