
#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;
}


