static PXA_DFC_NAND_SPEC stm1GbX16 =
{
{
10, /* tCH, Enable signal hold time */
35, /* tCS, Enable signal setup time */
15, /* tWH, ND_nWE high duration */
25, /* tWP, ND_nWE pulse time */
30, /* tRH, ND_nRE high duration */
25, /* tRP, ND_nRE pulse width */
25000, /* tR = tR+tRR+tWB+1, ND_nWE high to ND_nRE low for read */
60, /* tWHR, ND_nWE high to ND_nRE low delay for status read */
10, /* tAR, ND_ALE low to ND_nRE low delay */
},
1, /* Data flash bus arbiter enable */
64, /* Pages per block */
1, /* Second cycle start, Row address start position */
4, /* Returned ID bytes */
0, /* NAND mode */
0,
2048, /* Page size in bytes */
64, //spare size
16, /* Width of Flash memory */
16, /* Width of flash controller */
1024, /* Number of physical blocks in Flash */
4, // Number of bytes for read1 and program addresses.
0xB120, //result of read ID, device code + manufacturer code
/* command codes */
0x3000, /* Read */
0x0050, /* Read1 unused, current DFC don't support */
0x1080, /* Write, two cycle command */
0x0070, /* Read status */
0x0090, /* Read ID */
0xD060, /* Erase, two cycle command */
0x00FF, /* Reset */
0x002A, /* Lock whole flash */
0x2423, /* Unlock, two cycle command, supporting partial unlock */
0x007A, /* Read block lock status */
STM1GbX16Addr2NDCB1,
STM1GbX16NDBBR2Addr,
};
static PXA_DFC_NAND_SPEC stm1GbX8 =
{
{
10, /* tCH, Enable signal hold time */
35, /* tCS, Enable signal setup time */
15, /* tWH, ND_nWE high duration */
25, /* tWP, ND_nWE pulse time */
30, /* tRH, ND_nRE high duration */
25, /* tRP, ND_nRE pulse width */
25000, /* tR = tR+tRR+tWB+1, ND_nWE high to ND_nRE low for read */
60, /* tWHR, ND_nWE high to ND_nRE low delay for status read */
10, /* tAR, ND_ALE low to ND_nRE low delay */
},
1, /* Data flash bus arbiter enable */
64, /* Pages per block */
1, /* Second cycle start, Row address start position */
7, /* Returned ID bytes */
0, /* NAND mode */
0,
2048, /* Page size in bytes */
64, //spare size
8, /* Width of Flash memory */
8, /* Width of flash controller */
1024, /* Number of physical blocks in Flash */
4, // Number of bytes for read1 and program addresses.
0xA120, //result of read ID, device code + manufacturer code
/* command codes */
0x3000, /* Read */
0x0050, /* Read1 unused, current DFC don't support */
0x1080, /* Write, two cycle command */
0x0070, /* Read status */
0x0090, /* Read ID */
0xD060, /* Erase, two cycle command */
0x00FF, /* Reset */
0x002A, /* Lock whole flash */
0x2423, /* Unlock, two cycle command, supporting partial unlock */
0x007A, /* Read block lock status */
STM1GbX8Addr2NDCB1,
STM1GbX8NDBBR2Addr,
};//
static PXA_DFC_NAND_SPEC stm2GbX16 =
{
{
10, /* tCH, Enable signal hold time */
35, /* tCS, Enable signal setup time */
15, /* tWH, ND_nWE high duration */
25, /* tWP, ND_nWE pulse time */
15, /* tRH, ND_nRE high duration */
25, /* tRP, ND_nRE pulse width */
25000, /* tR = tR+tRR+tWB+1, ND_nWE high to ND_nRE low for read */
60, /* tWHR, ND_nWE high to ND_nRE low delay for status read */
10, /* tAR, ND_ALE low to ND_nRE low delay */
},
1, /* Data flash bus arbiter enable */
64, /* Pages per block */
1, /* Second cycle start, Row address start position */
4, /* Returned ID bytes */
0, /* NAND mode */
0,
2048, /* Page size in bytes */
64, //spare size
16, /* Width of Flash memory */
16, /* Width of flash controller */
2048, /* Number of physical blocks in Flash */
5, // Number of bytes for read1 and program addresses.
0xBA20, //result of read ID, device code + manufacturer code
/* command codes */
0x3000, /* Read */
0x0050, /* Read1 unused, current DFC don't support */
0x1080, /* Write, two cycle command */
0x0070, /* Read status */
0x0090, /* Read ID */
0xD060, /* Erase, two cycle command */
0x00FF, /* Reset */
0x002A, /* Lock whole flash */
0x2423, /* Unlock, two cycle command, supporting partial unlock */
0x007A, /* Read block lock status */
STM2GbX16Addr2NDCB1,
STM2GbX16NDBBR2Addr,
};
static PXA_DFC_NAND_SPEC toshiba2GbX16 =
{
{
6, /* tCH, Enable signal hold time */
10, /* tCS, Enable signal setup time */
10, /* tWH, ND_nWE high duration */
15, /* tWP, ND_nWE pulse time */
14, /* tRH, ND_nRE high duration */
25, /* tRP, ND_nRE pulse width */
25000, /* tR = tR+tRR+tWB+1, ND_nWE high to ND_nRE low for read */
100, /* tWHR, ND_nWE high to ND_nRE low delay for status read */
10, /* tAR, ND_ALE low to ND_nRE low delay */
},
1, /* Data flash bus arbiter enable */
64, /* Pages per block */
1, /* Second cycle start, Row address start position */
4, /* Returned ID bytes */
0, /* NAND mode */
0,
2048, /* Page size in bytes */
64, //spare size
16, /* Width of Flash memory */
16, /* Width of flash controller */
2048, /* Number of physical blocks in Flash */
5, // Number of bytes for read1 and program addresses.
0xBA98, //result of read ID, device code + manufacturer code
/* command codes */
0x3000, /* Read */
0x0050, /* Read1 unused, current DFC don't support */
0x1080, /* Write, two cycle command */
0x0070, /* Read status */
0x0090, /* Read ID */
0xD060, /* Erase, two cycle command */
0x00FF, /* Reset */
0x002A, /* Lock whole flash */
0x2423, /* Unlock, two cycle command, supporting partial unlock */
0x007A, /* Read block lock status */
TOSHIBA2GbX16Addr2NDCB1,
TOSHIBA2GbX16NDBBR2Addr,
};
static PXA_PLATFROM_DFC_FLASH_TYPE_INFO typeInfo[] = {
{SAMSUNG_CODE, 0x46, PXA_PLATFORM_DFC_FLASH_Samsung512MbX16, &samsung512MbX16},
{MICRON_CODE, 0xA1, PXA_PLATFORM_DFC_FLASH_Micron1GbX8, µn1GbX8},
{MICRON_CODE, 0xB1, PXA_PLATFORM_DFC_FLASH_Micron1GbX16, µn1GbX16},
{STM_CODE, 0xA1, PXA_PLATFORM_DFC_FLASH_STM1GbX8, &stm1GbX8},
{STM_CODE, 0xBA, PXA_PLATFORM_DFC_FLASH_STM2GbX16, &stm2GbX16},
{TOSHIBA_CODE, 0xBA, PXA_PLATFORM_DFC_FLASH_TOSHIBA2GbX16, &toshiba2GbX16},
{STM_CODE, 0xB1, PXA_PLATFORM_DFC_FLASH_STM1GbX16, &stm1GbX16},
{0, 0, PXA_PLATFORM_DFC_FLASH_NULL},
};
static INT32 Samsung512MbX16Addr2NDCB1(UINT16 cmd, UINT32 addr, UINT32 *pNdcb1)
{
UINT32 ndcb1 = 0;
if (addr >= 0x4000000)
return DFC_API_ILLEGAL_ADDR;
if (cmd == samsung512MbX16.read1 || cmd == samsung512MbX16.program) {
ndcb1 = (addr & 0xFF) | ((addr >> 1) & 0x01FFFF00);
}
else if (cmd == samsung512MbX16.erase) {
ndcb1 = ((addr >> 9) & 0x00FFFFFF);
}
*pNdcb1 = ndcb1;
return DFC_API_SUCCESS;
}
static INT32 Samsung512MbX16NDBBR2Addr(UINT16 cmd, UINT32 ndbbr, UINT32 *pAddr)
{
*pAddr = ndbbr << 9;
return DFC_API_SUCCESS;
}
static INT32 Micron1GbX8Addr2NDCB1(UINT16 cmd, UINT32 addr, UINT32 *pNdcb1)
{
UINT32 ndcb1 = 0;
UINT32 page;
if (addr >= 0x8000000)
return DFC_API_ILLEGAL_ADDR;
page = addr / micron1GbX8.pageSize;
addr = (page / micron1GbX8.pagePerBlock) << 18 | (page % micron1GbX8.pagePerBlock) << 12;
if (cmd == micron1GbX8.read1 || cmd == micron1GbX8.program) {
ndcb1 = (addr & 0xFFF) | ((addr << 4) & 0xFFFF0000);
}
else if (cmd == micron1GbX8.erase) {
ndcb1 = ((addr >> 18) << 6) & 0xFFFF;
}
*pNdcb1 = ndcb1;
return DFC_API_SUCCESS;
}
static INT32 Micron1GbX8NDBBR2Addr(UINT16 cmd, UINT32 ndbbr, UINT32 *pAddr)
{
if (cmd == micron1GbX8.read1 || cmd == micron1GbX8.program) {
*pAddr = ((ndbbr & 0xF) << 8) | ((ndbbr >> 8) << 16);
}
else if (cmd == micron1GbX8.erase) {
*pAddr = (ndbbr >> 6) << 18;
}
return DFC_API_SUCCESS;
}
static INT32 Micron1GbX16Addr2NDCB1(UINT16 cmd, UINT32 addr, UINT32 *pNdcb1)
{
UINT32 ndcb1 = 0;
UINT32 page;
if (addr >= 0x8000000)
return DFC_API_ILLEGAL_ADDR;
page = addr / micron1GbX16.pageSize;
addr = (page / micron1GbX16.pagePerBlock) << 17 | (page % micron1GbX16.pagePerBlock) << 11;
if (cmd == micron1GbX16.read1 || cmd == micron1GbX16.program) {
ndcb1 = (addr & 0x7FF) | ((addr << 5) & 0xFFFF0000);
}
else if (cmd == micron1GbX16.erase) {
ndcb1 = ((addr >> 17) << 6) & 0xFFFF;
}
*pNdcb1 = ndcb1;
return DFC_API_SUCCESS;
}
static INT32 Micron1GbX16NDBBR2Addr(UINT16 cmd, UINT32 ndbbr, UINT32 *pAddr)
{
if (cmd == micron1GbX16.read1 || cmd == micron1GbX16.program) {
*pAddr = ((ndbbr & 0x7) << 8) | ((ndbbr >> 8) << 16);
}
else if (cmd == micron1GbX16.erase) {
*pAddr = (ndbbr >> 6) << 17;
}
return DFC_API_SUCCESS;
}
static INT32 STM1GbX16Addr2NDCB1(UINT16 cmd, UINT32 addr, UINT32 *pNdcb1)
{
UINT32 ndcb1 = 0;
UINT32 page;
if (addr >= 0x8000000)
return DFC_API_ILLEGAL_ADDR;
page = addr / stm1GbX16.pageSize;
addr = (page / stm1GbX16.pagePerBlock) << 17 | (page % stm1GbX16.pagePerBlock) << 11;
if (cmd == stm1GbX16.read1 || cmd == stm1GbX16.program) {
ndcb1 = (addr & 0x7FF) | ((addr << 5) & 0xFFFF0000);
}
else if (cmd == stm1GbX16.erase) {
ndcb1 = ((addr >> 17) << 6) & 0xFFFF;
}
*pNdcb1 = ndcb1;
return DFC_API_SUCCESS;
}
static INT32 STM1GbX16NDBBR2Addr(UINT16 cmd, UINT32 ndbbr, UINT32 *pAddr)
{
if (cmd == stm1GbX16.read1 || cmd == stm1GbX16.program) {
*pAddr = ((ndbbr & 0x7) << 8) | ((ndbbr >> 8) << 16);
}
else if (cmd == stm1GbX16.erase) {
*pAddr = (ndbbr >> 6) << 17;
}
return DFC_API_SUCCESS;
}
static INT32 STM1GbX8Addr2NDCB1(UINT16 cmd, UINT32 addr, UINT32 *pNdcb1)
{
UINT32 ndcb1 = 0;
UINT32 page;
if (addr >= 0x8000000)
return DFC_API_ILLEGAL_ADDR;
page = addr / stm1GbX8.pageSize;
addr = (page / stm1GbX8.pagePerBlock) << 18 | (page % stm1GbX8.pagePerBlock) << 12;
if (cmd == stm1GbX8.read1 || cmd == stm1GbX8.program) {
ndcb1 = (addr & 0xFFF) | ((addr << 4) & 0xFFFF0000);
}
else if (cmd == stm1GbX8.erase) {
ndcb1 = ((addr >> 18) << 6) & 0xFFFF;
}
*pNdcb1 = ndcb1;
return DFC_API_SUCCESS;
}
static INT32 STM1GbX8NDBBR2Addr(UINT16 cmd, UINT32 ndbbr, UINT32 *pAddr)
{
if (cmd == stm1GbX8.read1 || cmd == stm1GbX8.program) {
*pAddr = ((ndbbr & 0xF) << 8) | ((ndbbr >> 8) << 16);
}
else if (cmd == stm1GbX8.erase) {
*pAddr = (ndbbr >> 6) << 18;
}
return DFC_API_SUCCESS;
}
static INT32 STM2GbX16Addr2NDCB1(UINT16 cmd, UINT32 addr, UINT32 *pNdcb1)
{
UINT32 ndcb1 = 0;
UINT32 page;
page = addr / stm2GbX16.pageSize;
addr = (page / stm2GbX16.pagePerBlock) << 17 |(page % stm2GbX16.pagePerBlock) << 11;
if (cmd == stm2GbX16.read1 || cmd == stm2GbX16.program) {
ndcb1 = (addr & 0x7FF) | ((addr << 5) & 0xFFFF0000);
}
else if (cmd == stm2GbX16.erase) {
ndcb1 = ((addr >> 17) << 6) & 0x1FFFF;
}
*pNdcb1 = ndcb1;
return DFC_API_SUCCESS;
}
static INT32 STM2GbX16NDBBR2Addr(UINT16 cmd, UINT32 ndbbr, UINT32 *pAddr)
{
if (cmd == stm2GbX16.read1 || cmd == stm2GbX16.program) {
*pAddr = ((ndbbr & 0x7) << 8) | ((ndbbr >> 8) << 16);
}
else if (cmd == stm2GbX16.erase) {
*pAddr = (ndbbr >> 6) << 17;
}
return DFC_API_SUCCESS;
}
static INT32 TOSHIBA2GbX16Addr2NDCB1(UINT16 cmd, UINT32 addr, UINT32 *pNdcb1)
{
UINT32 ndcb1 = 0;
UINT32 page;
page = addr / toshiba2GbX16.pageSize;
addr = (page / toshiba2GbX16.pagePerBlock) << 17 |(page % toshiba2GbX16.pagePerBlock) << 11;
if (cmd == toshiba2GbX16.read1 || cmd == toshiba2GbX16.program) {
ndcb1 = (addr & 0x7FF) | ((addr << 5) & 0xFFFF0000);
}
else if (cmd == toshiba2GbX16.erase) {
ndcb1 = ((addr >> 17) << 6) & 0x1FFFF;
}
*pNdcb1 = ndcb1;
return DFC_API_SUCCESS;
}
static INT32 TOSHIBA2GbX16NDBBR2Addr(UINT16 cmd, UINT32 ndbbr, UINT32 *pAddr)
{
if (cmd == toshiba2GbX16.read1 || cmd == toshiba2GbX16.program) {
*pAddr = ((ndbbr & 0x7) << 8) | ((ndbbr >> 8) << 16);
}
else if (cmd == toshiba2GbX16.erase) {
*pAddr = (ndbbr >> 6) << 17;
}
return DFC_API_SUCCESS;
}
INT32 PXA_Platform_DfcNandProbe(PXA_DFC_NAND_CONTEXT *pContext)
{
UINT8 manufacturer=0, device=0;
INT32 ret;
UINT32 i ;
i=0;
while(typeInfo.type != PXA_PLATFORM_DFC_FLASH_NULL) {
pContext->pSpec = typeInfo.pSpec;
if ((ret = PXA_DfcNandInit(pContext, PXA_DFC_CLOCK)) != DFC_API_SUCCESS) {
i++;
continue;
}
if ((ret = PXA_DfcNandReadID(pContext, &manufacturer, &device)) != DFC_API_SUCCESS) {
i++;
continue;
}
if (manufacturer != typeInfo.manufacturerId ||device != typeInfo.deviceId) {
i++;
continue;
}
break;
}
if (typeInfo.type != PXA_PLATFORM_DFC_FLASH_NULL) {
pContext->pSpec->chipid = (device << 8) | manufacturer;
if (pContext->pSpec->chipid ==0xBA20) {
pContext->pSpec->read1=0x3100;
}
}
else {
pContext->pSpec=NULL;
return DFC_API_FAILURE;
}
RETAILMSG(1, (TEXT("[FMD]: GONA4 0x%x\r\n"), pContext->pSpec));
return DFC_API_SUCCESS;
}