204 lines
4.7 KiB
C
204 lines
4.7 KiB
C
|
|
|||
|
#include <common.h>
|
|||
|
|
|||
|
#include <nand.h>
|
|||
|
#include "diag.h"
|
|||
|
|
|||
|
extern nand_info_t nand_info[];
|
|||
|
|
|||
|
/*******************************************************************************
|
|||
|
* mvNandDetectTest - Detect NAND flash with it’s geometry and prints details.
|
|||
|
*
|
|||
|
* DESCRIPTION:
|
|||
|
* This routine prints NAND detection status. Also displays NAND flash size,
|
|||
|
* page size, number of blocks if detected.
|
|||
|
*
|
|||
|
* INPUT:
|
|||
|
* None.
|
|||
|
*
|
|||
|
* OUTPUT:
|
|||
|
* None.
|
|||
|
*
|
|||
|
* RETURN:
|
|||
|
* Returns 1 on failure, else 0
|
|||
|
*******************************************************************************/
|
|||
|
int mvNandDetectTest(void)
|
|||
|
{
|
|||
|
int testFlag;
|
|||
|
testFlag = DIAG_PASS;
|
|||
|
|
|||
|
if(NULL != nand_info[0].name)
|
|||
|
{
|
|||
|
printf("\tDevice: 0, Size: %lu MB, Page Size: %d KB, Block Size: %d KB\n", \
|
|||
|
(nand_info[0].size/1024)/1024, nand_info[0].oobblock/1024, \
|
|||
|
nand_info[0].erasesize/1024);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf("\tError: NAND not detected!");
|
|||
|
testFlag = DIAG_FAIL;
|
|||
|
}
|
|||
|
|
|||
|
printf("\tNAND detection test ");
|
|||
|
printf(((testFlag==DIAG_PASS)?"PASSED\n":"FAIL\n"));
|
|||
|
|
|||
|
return testFlag;
|
|||
|
}
|
|||
|
|
|||
|
/*******************************************************************************
|
|||
|
* mvNandBadBlockTest - Prints all bad blocks on NAND memory
|
|||
|
*
|
|||
|
* DESCRIPTION:
|
|||
|
* This routine checks all blocks against bad block table and prints the
|
|||
|
* block if it is marked as bad.
|
|||
|
*
|
|||
|
* INPUT:
|
|||
|
* None.
|
|||
|
*
|
|||
|
* OUTPUT:
|
|||
|
* None.
|
|||
|
*
|
|||
|
* RETURN:
|
|||
|
* Returns 1 on failure, else 0
|
|||
|
*******************************************************************************/
|
|||
|
int mvNandBadBlockTest(void)
|
|||
|
{
|
|||
|
int testFlag;
|
|||
|
unsigned int off;
|
|||
|
testFlag = DIAG_PASS;
|
|||
|
|
|||
|
for (off=0; off < nand_info[0].size; off += nand_info[0].erasesize)
|
|||
|
{
|
|||
|
if (nand_block_isbad(&nand_info[0], off))
|
|||
|
{
|
|||
|
printf("\tBad Block: %08x\n", off);
|
|||
|
}
|
|||
|
}
|
|||
|
printf("\tNAND bad-block detection test ");
|
|||
|
printf((testFlag==DIAG_PASS)?"PASSED\n":"FAIL\n");
|
|||
|
|
|||
|
return testFlag;
|
|||
|
}
|
|||
|
|
|||
|
/*******************************************************************************
|
|||
|
* mvNandReadWriteTest - Performs read-write test on NAND chip.
|
|||
|
*
|
|||
|
* DESCRIPTION:
|
|||
|
* This routine writes pattern 0x55,0xaa in 16 blocks at offset immediately
|
|||
|
* after ENV section and reads them back and verifies.
|
|||
|
*
|
|||
|
* INPUT:
|
|||
|
* None.
|
|||
|
*
|
|||
|
* OUTPUT:
|
|||
|
* None.
|
|||
|
*
|
|||
|
* RETURN:
|
|||
|
* Returns 1 on failure, else 0
|
|||
|
*******************************************************************************/
|
|||
|
int mvNandReadWriteTest(void)
|
|||
|
{
|
|||
|
int i,j,ret;
|
|||
|
int testFlag;
|
|||
|
unsigned int pageSize;
|
|||
|
unsigned char rbuf[2048];
|
|||
|
nand_write_options_t wr_opts;
|
|||
|
nand_erase_options_t er_opts;
|
|||
|
nand_read_options_t rd_opts;
|
|||
|
testFlag = DIAG_PASS;
|
|||
|
|
|||
|
printf("\tNAND read/write test ");
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
pageSize = nand_info[0].oobblock;
|
|||
|
|
|||
|
/***************** ERASE ***********************/
|
|||
|
memset(&er_opts, 0, sizeof(er_opts));
|
|||
|
er_opts.offset = CFG_ENV_OFFSET + CFG_ENV_SIZE;
|
|||
|
er_opts.length = pageSize * PAGES_PER_BLOCK * 16;
|
|||
|
er_opts.quiet = 1;
|
|||
|
ret = nand_erase_opts(&nand_info[0], &er_opts);
|
|||
|
if (ret)
|
|||
|
{
|
|||
|
printf("\tError: NAND Erase faild!\n");
|
|||
|
testFlag = DIAG_FAIL;
|
|||
|
break;
|
|||
|
}
|
|||
|
if(DIAG_PASS != testFlag)
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
/***************** WRITE ***********************/
|
|||
|
memset(&wr_opts, 0, sizeof(wr_opts));
|
|||
|
for(i=0; i < pageSize; i=i+2)
|
|||
|
{
|
|||
|
wr_opts.buffer[i] = 0x55;
|
|||
|
wr_opts.buffer[i+1] = 0xaa;
|
|||
|
}
|
|||
|
wr_opts.length = pageSize;
|
|||
|
wr_opts.offset = CFG_ENV_OFFSET + CFG_ENV_SIZE;
|
|||
|
/* opts.forcejffs2 = 1; */
|
|||
|
wr_opts.pad = 1;
|
|||
|
wr_opts.blockalign = 1;
|
|||
|
wr_opts.quiet = 1;
|
|||
|
|
|||
|
for(i=0; i < PAGES_PER_BLOCK * 16;i++)
|
|||
|
{
|
|||
|
ret = nand_write_opts(&nand_info[0], &wr_opts);
|
|||
|
if (ret)
|
|||
|
{
|
|||
|
printf("\tError: NAND write faild!\n");
|
|||
|
testFlag = DIAG_FAIL;
|
|||
|
break;
|
|||
|
}
|
|||
|
wr_opts.offset += pageSize;
|
|||
|
}
|
|||
|
if(DIAG_PASS != testFlag)
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
/**************** READ *************************/
|
|||
|
memset(&rd_opts, 0, sizeof(rd_opts));
|
|||
|
rd_opts.buffer = rbuf;
|
|||
|
rd_opts.length = (ulong)pageSize;
|
|||
|
rd_opts.offset = CFG_ENV_OFFSET + CFG_ENV_SIZE;
|
|||
|
rd_opts.quiet = 1;
|
|||
|
|
|||
|
for(i=0; i < PAGES_PER_BLOCK * 16;i++)
|
|||
|
{
|
|||
|
ret = nand_read_opts(&nand_info[0], &rd_opts);
|
|||
|
if (ret)
|
|||
|
{
|
|||
|
printf("\tError: NAND read faild!\n");
|
|||
|
testFlag = DIAG_FAIL;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
for(j=0; j < pageSize; j=j+4)
|
|||
|
{
|
|||
|
if (rbuf[j] != 0x55 && rbuf[j+1] != 0xaa && rbuf[j+2] != 0x55 && rbuf[j+3] != 0xaa)
|
|||
|
{
|
|||
|
printf("\tError: Data verify failed\n");
|
|||
|
testFlag = DIAG_FAIL;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
rd_opts.offset += pageSize;
|
|||
|
}
|
|||
|
if(DIAG_PASS != testFlag)
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
}while(0);
|
|||
|
|
|||
|
printf((testFlag==DIAG_PASS)?"PASSED\n":"FAIL\n");
|
|||
|
|
|||
|
return testFlag;
|
|||
|
}
|
|||
|
|
|||
|
|