1
0
uboot-1.1.4-kirkwood/diag/diag_nand.c
2024-01-09 13:43:28 +01:00

204 lines
4.7 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <common.h>
#include <nand.h>
#include "diag.h"
extern nand_info_t nand_info[];
/*******************************************************************************
* mvNandDetectTest - Detect NAND flash with its 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;
}