📄 tcl_gdi_flash_cfi.c
字号:
FLASH_DEBUG(("Sector%d, start:%x,size:%d\n",puSectorNum,pFlashInfo->eSectorInfo[puSectorNum].uStartAdress,
pFlashInfo->eSectorInfo[puSectorNum].uSecLength));
*/
puSectorNum = puSectorNum +1;
size += gEraseRegionInfo.sectorSize;
}
if(size>=gFlashTotalSize)
{
gNumEraseRegions = i+1;
break;
}
}
/*if this is defined, the small sectors in the flash will not be used for TopMode Flash */
#ifdef DONT_USE_SMALL_SECTOR
{
TCL_UINT8 uSmallSecNum = 0;
/* Check from the end of the table, find how many small sectors after the normal sector */
i = *puSectorNum;
while(1)
{
if(pFlashInfo->eSectionInfo[i-1].uSecLength < 65536)
{
uSmallSecNum++;
i--;
}
else
{
/* once there is normal one, terminate the detection. */
break;
}
}
*puSectorNum = *puSectorNum - uSmallSecNum;
}
#endif
/* Issue Reset command */
WRITE_FLASH(CMD_RESET_ADDR[gIsSst16Bit], CMD_RESET_DATA[gIsSst16Bit]);
/* Disable writes to the flash */
DisableFlash();
pFlashInfo->uSectorNum = puSectorNum;
return TCL_TRUE;
}
/******************************************************************************
* Function: DTV_BoardIs8BitsFlash
* Description: 判断是否是8 位的Flash
* Calls: omit
* Called By: omit
* Table Accessed: none
* Table Updated: none
* Input: none
* Output: none
* Return: TCL_TRUE - 是8 位的Flash
TCL_FALSE - 不是8 位的Flash
* Others:
* Note:
* Author Date Purpose
*----------------------------------------------------------------------------
* JokQu 20080229 create
******************************************************************************/
static TCL_BOOL DTV_BoardIs8BitsFlash(TCL_VOID)
{
return TCL_FALSE;
}
/******************************************************************************
* Function: FlashAutoSelect
* Description: 获取Flash 信息
* Calls: omit
* Called By: omit
* Table Accessed: none
* Table Updated: none
* Input: TCL_GDI_FLASH_INFO *pFlashInfo - Flash 信息指针
* Output: TCL_GDI_FLASH_INFO *pFlashInfo - Flash 信息
* Return: TCL_NO_ERROR
* Others:
* Note:
* Author Date Purpose
*----------------------------------------------------------------------------
* JokQu 20080229 create
******************************************************************************/
static TCL_BOOL FlashAutoSelect(TCL_GDI_FLASH_INFO *pFlashInfo)
{
TCL_UINT16 id;
TCL_UINT8 i;
TCL_UINT8 j;
TCL_UINT32 size;
FL_ERASE_REGION_INFO gEraseRegionInfo[4];
pFlashInfo->eBootMode = 0xFF;
if (DTV_BoardIs8BitsFlash())
{
WorkMode = 1;
gIsSst16Bit = TCL_FALSE;
#if 0
cbus_write( 0x1a00, 0x454500 ); // Guest 0
cbus_write( 0x1a01, 0x321045 );
cbus_write( 0x1a31, 0x300 ); // time out addr
#endif
}
else
{
WorkMode = 2;
}
FLASH_DEBUG(("Flash works mode: %s\n", (WorkMode == WORK_MODE_8BIT)?"8 Bits":"16 Bits"));
/* Enable writes to the flash */
EnableFlash( );
/* Issue Reset command */
if (!gIsSst16Bit)
{
WRITE_FLASH(CMD_RESET_ADDR[gIsSst16Bit], CMD_RESET_DATA[gIsSst16Bit]);
}
else
{
WRITE_FLASH(CMD_RESET_ADDR[gIsSst16Bit]/WorkMode, CMD_RESET_DATA[gIsSst16Bit]);
}
/* Issue unlock command */
FLASH_UnlockCmd();
/* Issue AutoSelect command */
WRITE_FLASH(CMD_AUTOSELECT_ADDR[gIsSst16Bit]/ WorkMode, CMD_AUTOSELECT_DATA[gIsSst16Bit]);
/* Read Manufacturer ID and Device ID */
id = READ_FLASH( MANUFACTURER_ID_ADDR / WorkMode )<<8;
id |= READ_FLASH( DEVICE_ID_ADDR / WorkMode ) & 0xFF;
/* SST39VF088 read Device ID from 0x01 instead of 0x02 */
if( 0xBF00 == (id & 0xFF00) )
{
id = 0xBF00 | READ_FLASH( 0x01 );
}
if( 0xBF00 == id)
{
id |= READ_FLASH( DEVICE_ID_ADDR );
}
pFlashInfo->uManufactId = id&0xFF00;
pFlashInfo->uDeviceId = id&0xFF;
/* Issue Reset command */
if (!gIsSst16Bit)
{
WRITE_FLASH(CMD_RESET_ADDR[gIsSst16Bit], CMD_RESET_DATA[gIsSst16Bit]);
}
else
{
WRITE_FLASH(CMD_RESET_ADDR[gIsSst16Bit]/WorkMode, CMD_RESET_DATA[gIsSst16Bit]);
}
/* Disable writes to the flash */
DisableFlash( );
FLASH_DEBUG(("Flash ID: %x\n", id));
if ((gIsSst16Bit) && (id != 0xBF5B) && (id != 0xBF5A) && (id != 0xBF4A) && (id != 0xBF4B))
{
return TCL_FALSE;
}
gUseDQ5ForTimeout = TCL_TRUE;
switch(id>>8)
{
case 0xBF: /* SST */
{
/* SST Flash Do not use DQ5 for timeout detection */
gUseDQ5ForTimeout = TCL_FALSE;
}
break;
}
pFlashInfo->uSectorNum = 0;
memset(gEraseRegionInfo,0,sizeof(gEraseRegionInfo));
switch( id )
{
case 0xC2C4: /* Uti/MXIC 29LV160AT 2M Top (for Mico) */
{
pFlashInfo->eBootMode = TCL_GDI_FLBOOT_TOP;
pFlashInfo->uCFI = 1;
pFlashInfo->uSectorNum = 35;
pFlashInfo->uFlashSize = 4 * 1024 * 1024;
gEraseRegionInfo[0].numSectors = 31;
gEraseRegionInfo[0].sectorSize = 0x10000;
gEraseRegionInfo[1].numSectors = 1;
gEraseRegionInfo[1].sectorSize = 0x8000;
gEraseRegionInfo[2].numSectors = 2;
gEraseRegionInfo[2].sectorSize = 0x2000;
gEraseRegionInfo[3].numSectors = 1;
gEraseRegionInfo[3].sectorSize = 0x4000;
}
break;
case 0xC249: /* MXIC 29LV160AB 2M Bottom (for ShenZhou) */
{
pFlashInfo->eBootMode = TCL_GDI_FLBOOT_BOTTOM;
pFlashInfo->uCFI = 1;
pFlashInfo->uSectorNum = 35;
pFlashInfo->uFlashSize = 4 * 1024 * 1024;
gEraseRegionInfo[3].numSectors = 31;
gEraseRegionInfo[3].sectorSize = 0x10000;
gEraseRegionInfo[2].numSectors = 1;
gEraseRegionInfo[2].sectorSize = 0x8000;
gEraseRegionInfo[1].numSectors = 2;
gEraseRegionInfo[1].sectorSize = 0x2000;
gEraseRegionInfo[0].numSectors = 1;
gEraseRegionInfo[0].sectorSize = 0x4000;
}
break;
case 0x01DA: /* AMD Am29LV800BT 1M Top */
case 0x04DA: /* FUJITSU MBM29LV800TE/TA 1M Top */
{
pFlashInfo->eBootMode = TCL_GDI_FLBOOT_TOP;
pFlashInfo->uCFI = 1;
pFlashInfo->uSectorNum = 19;
pFlashInfo->uFlashSize = 4 * 1024 * 1024;
gEraseRegionInfo[0].numSectors = 15;
gEraseRegionInfo[0].sectorSize = 0x10000;
gEraseRegionInfo[1].numSectors = 1;
gEraseRegionInfo[1].sectorSize = 0x8000;
gEraseRegionInfo[2].numSectors = 2;
gEraseRegionInfo[2].sectorSize = 0x2000;
gEraseRegionInfo[3].numSectors = 1;
gEraseRegionInfo[3].sectorSize = 0x4000;
}
break;
case 0x015B: /* AMD Am29LV800BB 1M Bottom */
case 0x045B: /* FUJITSU MBM29LV800BE/BA 1M Bottom */
case 0x8C5B: /* ESMT F49L800 1M BOTTOM */
{
pFlashInfo->eBootMode = TCL_GDI_FLBOOT_BOTTOM;
pFlashInfo->uCFI = 1;
pFlashInfo->uSectorNum = 19;
pFlashInfo->uFlashSize = 4 * 1024 * 1024;
gEraseRegionInfo[3].numSectors = 15;
gEraseRegionInfo[3].sectorSize = 0x10000;
gEraseRegionInfo[2].numSectors = 1;
gEraseRegionInfo[2].sectorSize = 0x8000;
gEraseRegionInfo[1].numSectors = 2;
gEraseRegionInfo[1].sectorSize = 0x2000;
gEraseRegionInfo[0].numSectors = 1;
gEraseRegionInfo[0].sectorSize = 0x4000;
}
break;
case 0xBF4B: /* SST39VF1601C */
{
pFlashInfo->eBootMode = TCL_GDI_FLBOOT_BOTTOM;
pFlashInfo->uCFI = 1;
pFlashInfo->uSectorNum = 32;
pFlashInfo->uFlashSize = 4 * 1024 * 1024;
gEraseRegionInfo[0].numSectors = 32;
gEraseRegionInfo[0].sectorSize = 0x10000;
gEraseRegionInfo[1].numSectors = 0;
gUseDQ5ForTimeout = TCL_FALSE;
mEraseCmd=CMD_BLOCK_ERASE;
}
break;
case 0xBF5B: /* SST39VF3201 */
{
pFlashInfo->eBootMode = TCL_GDI_FLBOOT_BOTTOM;
pFlashInfo->uCFI = 1;
pFlashInfo->uSectorNum = 64;
pFlashInfo->uFlashSize = 4 * 1024 * 1024;
gEraseRegionInfo[0].numSectors = 64;
gEraseRegionInfo[0].sectorSize = 0x10000;
gEraseRegionInfo[1].numSectors = 0;
gUseDQ5ForTimeout = TCL_FALSE;
mEraseCmd=CMD_BLOCK_ERASE;
}
break;
case 0xBFD8: /* SST39VF088 */
{
pFlashInfo->eBootMode = TCL_GDI_FLBOOT_BOTTOM;
pFlashInfo->uCFI = 1;
pFlashInfo->uSectorNum = 16;
pFlashInfo->uFlashSize = 4 * 1024 * 1024;
gEraseRegionInfo[0].numSectors = 16;
gEraseRegionInfo[0].sectorSize = 0x10000;
gEraseRegionInfo[1].numSectors = 0;
}
break;
case 0xBFC8: /* SST39VF1681 */
case 0xBFC9: /* SST39VF1682 */
{
pFlashInfo->eBootMode = TCL_GDI_FLBOOT_BOTTOM;
pFlashInfo->uCFI = 1;
pFlashInfo->uSectorNum = 32;
pFlashInfo->uFlashSize = 4 * 1024 * 1024;
gEraseRegionInfo[0].numSectors = 32;
gEraseRegionInfo[0].sectorSize = 0x10000;
gEraseRegionInfo[1].numSectors = 0;
gUseDQ5ForTimeout = TCL_FALSE;
}
break;
case 0x04C4: /* Fujitsu(/Malaysia) 29LV160TE */
case 0x37A8: /* Amic A29L160 Top */
case 0x01C4: /* AMD S29AL160M top */
case 0x1FC2: /* ATMEL AT49BV162/3AT top */
{
pFlashInfo->eBootMode = TCL_GDI_FLBOOT_TOP;
}
break;
default:
break;
}
if( 0 == pFlashInfo->uSectorNum)
{
/* If not special Flash, return FALSE to use CFI */
return FlashProbeCFI(pFlashInfo);
}
id = 0;
size = 0;
for(i = 0; i < 4; i++)
{
if(0 == gEraseRegionInfo[i].numSectors)
{
break;
}
for(j = 0; j < gEraseRegionInfo[i].numSectors; j++)
{
pFlashInfo->eSectorInfo[id ].uSectorNo = id ;
pFlashInfo->eSectorInfo[id ].uStartAdress = size;
pFlashInfo->eSectorInfo[id ].uSecLength = gEraseRegionInfo[j].sectorSize;
id += 1;
size += gEraseRegionInfo[i].sectorSize;
}
}
return TCL_TRUE;
}
/******************************************************************************
* Function: CFI_FlashGetInfo
* Description: 获取Flash 信息
* Calls: omit
* Called By: omit
* Table Accessed: none
* Table Updated: none
* Input: TCL_GDI_FLASH_INFO *pFlashInfo - Flash 信息指针
* Output: TCL_GDI_FLASH_INFO *pFlashInfo - Flash 信息
* Return: TCL_NO_ERROR
* Others:
* Note:
* Author Date Purpose
*----------------------------------------------------------------------------
* JokQu 20080229 create
******************************************************************************/
TCL_UINT32 CFI_FlashGetInfo(TCL_GDI_FLASH_INFO *pFlashInfo)
{
if( (TCL_FALSE == FlashAutoSelect(pFlashInfo) )
&& (WORK_MODE_16BIT == WorkMode))
{
if (gIsSst16Bit)
{
gIsSst16Bit = TCL_FALSE;
FlashAutoSelect(pFlashInfo);
}
}
return TCL_NO_ERROR;
}
/******************************************************************************
* Function: CFI_FlashSecStartAddr
* Description: 得到一个地址所在的扇区号
* Calls: omit
* Called By: omit
* Table Accessed: none
* Table Updated: none
* Input: TCL_UINT32 uAddr - 地址
* Output: none
* Return: 扇区号
* Others:
* Note:
* Author Date Purpose
*----------------------------------------------------------------------------
* JokQu 20080229 create
******************************************************************************/
static TCL_UINT32 CFI_FlashSecNum(TCL_UINT32 uAddr)
{
extern TCL_INT32 TCL_GDI_Flash_GetSecNum(TCL_UINT32 );
return TCL_GDI_Flash_GetSecNum(uAddr);
}
/******************************************************************************
* Function: CFI_FlashSecStartAddr
* Description: 得到一个扇区的起始地址
* Calls: omit
* Called By: omit
* Table Accessed: none
* Table Updated: none
* Input: TCL_UINT32 uSector - 扇区号
* Output: none
* Return: 起始地址
* Others:
* Note:
* Author Date Purpose
*----------------------------------------------------------------------------
* JokQu 20080229 create
******************************************************************************/
static TCL_UINT32 CFI_FlashSecStartAddr(TCL_UINT32 uSector)
{
extern TCL_UINT32 TCL_GDI_Flash_GetSecStartAddr(TCL_UINT32);
return TCL_GDI_Flash_GetSecStartAddr(uSector);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -