
#include "../include/phynand.h"

extern int amlnand_init(unsigned char flag);
extern void amlchip_dumpinfo(struct amlnand_chip *aml_chip);
extern void amldev_dumpinfo(struct amlnand_phydev *phydev);
//static int plane_mode = 0;
//struct aml_nftl_dev * nftl_device;

/* just like memset function but the paraments' type is  little different */
void *memset_nand_test(void *s, u32 c, size_t count)
{
	u32 *sl = (u32 *) s;
	u32 cl = 0;
	//char *s8;
	int i;

	/* do it one word at a time (32 bits or 64 bits) while possible */
	if ( ((ulong)s & (sizeof(*sl) - 1)) == 0) {

		for (i = 0; i < sizeof(*sl); i++) {
			cl <<= 8;
			cl |= c & 0xff;
			c =c >>8;
		}
		while (count >= sizeof(*sl)) {
			*sl++ = cl;
			count -= sizeof(*sl);
		}
	}
	/* fill 8 bits at a time */
	/*s8 = (char *)sl;            //this can write one byte
	while (count--)
		*s8++ = c;*/

	return s;
}
static int nand_erase_ops_test(struct amlnand_phydev *phydev, uint64_t off, uint64_t len)
{
	//struct amlnand_chip *aml_chip = phydev->priv;
	struct phydev_ops *devops = &(phydev->ops);
	//struct hw_controller *controller = &(aml_chip->controller);
	//struct chip_operation *operation = &(aml_chip->operation);
	//struct chip_ops_para *ops_para = &(aml_chip->ops_para);

	uint64_t erase_addr, erase_len, erase_off;
	int ret = 0;

	erase_addr = erase_off = off;
	erase_len = len ;

	if ((erase_off+erase_len) > phydev->size ) {
		aml_nand_msg("nand write size is out of space");
		ret= -NAND_ERASE_FAILED;
		goto exit_error;
	}

	for (; erase_addr < erase_off + erase_len; erase_addr +=  phydev->erasesize) {

		memset(devops, 0x0, sizeof(struct phydev_ops));
		devops->addr = erase_addr;
		devops->len = phydev->erasesize;
		devops->mode = NAND_HW_ECC;

		 ret = phydev->block_isbad(phydev);
		if (ret > 0) {
			aml_nand_msg("Skipping bad block at 0x%08llx", erase_addr);
			continue;

		} else if (ret < 0) {
			aml_nand_msg("nand get bad block failed: ret=%d at addr=%llx",ret, erase_addr);
			ret =  -NAND_ERASE_FAILED;
		}
		extern int nand_erase(struct amlnand_phydev *phydev);
		ret = nand_erase(phydev);
		if (ret < 0) {
			aml_nand_msg("nand Erase failure: %d %llx", ret, erase_addr);
			ret =  -NAND_ERASE_FAILED;
		}
	}


exit_error:

	return ret;
}

static int nand_read_ops_test(struct amlnand_phydev *phydev,uint64_t off , uint64_t len , unsigned char * dat_buf)
{
	//struct amlnand_chip *aml_chip =phydev->priv;
	struct phydev_ops *devops = &(phydev->ops);
	uint64_t offset , write_len;
	unsigned char * buffer = NULL;
	int ret = 0;

	offset = off;
	write_len = len;
	buffer = aml_nand_malloc(2 * phydev->writesize);
	if (!buffer) {
		aml_nand_msg("nand read test malloc failed");
		ret = -NAND_READ_FAILED;
		goto exit_error;
	}

	if (!dat_buf) {
		aml_nand_msg("nand read no buf");
		return -NAND_READ_FAILED;
	}

	if ((offset & (phydev->writesize - 1)) != 0 ||(write_len & (phydev->writesize - 1)) != 0) {
		aml_nand_msg ("Attempt to read non page aligned data");
		return -NAND_READ_FAILED;
	}

	if ((offset + write_len) > phydev->size) {
		aml_nand_msg("Attemp to read out side the dev area");
		return -NAND_READ_FAILED;
	}
	memset(devops, 0x0, sizeof(struct phydev_ops));
	devops->addr = offset;
	devops->len = phydev->writesize;
	devops->datbuf = buffer;
	devops->oobbuf = NULL;
	devops->mode = NAND_HW_ECC;
	aml_nand_dbg("phydev->writesize= %x",phydev->writesize);
	do {
		if ((devops->addr % phydev->erasesize) == 0 ) {
			ret =  phydev->block_isbad(phydev);
			if (ret > 0) {
				aml_nand_msg("Skipping bad block at %llx", devops->addr);
				devops->addr += phydev->erasesize;
				continue;
			} else if (ret < 0) {
				aml_nand_msg("AMLNAND get bad block failed: ret=%d at addr=%llx",ret, devops->addr);
				return -1;
			}
		}
		memset(buffer,0x0,(2 * phydev->writesize));
		ret = phydev->read(phydev);
		if ((ret)) {
			aml_nand_msg("nand read failed at %llx",devops->addr);
		}
		if (memcmp(buffer,dat_buf,phydev->writesize)) {
			aml_nand_msg("nand read test verify failed");
			break;
		}
		devops->addr +=  phydev->writesize;

	}while(devops->addr < (offset + write_len));


exit_error:

	if (buffer) {
		aml_nand_free(buffer);
	}

	return ret;
}
#if 0
static int nand_read_oob_ops_test(struct amlnand_phydev *phydev,uint64_t off , uint64_t len , unsigned char * dat_buf)
{
	//struct amlnand_chip *aml_chip =phydev->priv;
	struct phydev_ops *devops = &(phydev->ops);
	uint64_t offset , write_len;
	unsigned char * buffer = NULL;
	int ret = 0;

	offset = off;
	write_len = len;
	buffer = aml_nand_malloc(2 * phydev->writesize);
	if (!buffer) {
		aml_nand_msg("nand read oob test malloc failed");
		ret = -NAND_READ_FAILED;
		goto exit_error;
	}

	if (!dat_buf) {
		aml_nand_msg("nand read oob no buf");
		return -NAND_READ_FAILED;
	}

	if ((offset & (phydev->writesize - 1)) != 0 ||(write_len & (phydev->writesize - 1)) != 0) {
		aml_nand_msg ("Attempt to read non page aligned data");
		return -NAND_READ_FAILED;
	}

	if ((offset + write_len) > phydev->size) {
		aml_nand_msg("Attemp to read out side the dev area");
		return -NAND_READ_FAILED;
	}
	memset(devops, 0x0, sizeof(struct phydev_ops));
	devops->addr = offset;
	devops->len = phydev->writesize;
	devops->datbuf = NULL;
	devops->oobbuf = buffer;
	devops->mode = NAND_HW_ECC;
	aml_nand_dbg("phydev->writesize= %x",phydev->writesize);
	do {
		if ((devops->addr % phydev->erasesize) == 0 ) {
			ret =  phydev->block_isbad(phydev);
			if (ret > 0) {
				aml_nand_msg("Skipping bad block at %llx", devops->addr);
				devops->addr += phydev->erasesize;
				continue;
			} else if (ret < 0) {
				aml_nand_msg("AMLNAND get bad block failed: ret=%d at addr=%llx",ret, devops->addr);
				return -1;
			}
		}
		memset(buffer,0x0,(2 * phydev->writesize));
		ret = phydev->read_oob(phydev);
		if ((ret)) {
			aml_nand_msg("nand read oob failed at %llx",devops->addr);
		}
		if (memcmp(buffer,dat_buf,phydev->writesize)) {
			aml_nand_msg("nand read oob test verify failed");
			break;
		}
		devops->addr +=  phydev->writesize;

	}while(devops->addr < (offset + write_len));


exit_error:

	if (buffer) {
		aml_nand_free(buffer);
	}

	return ret;
}
#endif

static int nand_write_ops_test(struct amlnand_phydev *phydev , uint64_t off, uint64_t len, unsigned char * dat_buf, int flag)
{
	//struct amlnand_chip *aml_chip = phydev->priv;
	struct phydev_ops *devops = &(phydev->ops);
	unsigned char * verify_buf =NULL;
	unsigned char * buffer = NULL;
	uint64_t offset , write_len;
	int ret = 0;

	offset = off;
	write_len = len;
	buffer = dat_buf;
	flag = 1; /* fixme, verify flag! */
	if (!buffer) {
		aml_nand_msg("nand write no buf");
		return -NAND_WRITE_FAILED;
	}

	if ((offset & (phydev->writesize - 1)) != 0 ||(write_len & (phydev->writesize - 1)) != 0) {
		aml_nand_msg ("Attempt to write non page aligned data");
		return -NAND_WRITE_FAILED;
	}

	if ((offset + write_len) > phydev->size) {
		aml_nand_msg("Attemp to write out side the dev area : %llx, %llx",(offset + write_len),phydev->size);
		return -NAND_WRITE_FAILED;
	}

	if (flag == 1) {
		verify_buf = aml_nand_malloc(2*phydev->writesize);
		if (!verify_buf) {
			aml_nand_msg("Attemp to write out side the dev area");
			ret =  -NAND_WRITE_FAILED;
			goto exit_error;
		}
	}
	memset(devops, 0x0, sizeof(struct phydev_ops));
	devops->addr = offset;
	devops->len = phydev->writesize;
	devops->datbuf = buffer;
	devops->oobbuf = NULL;
	devops->mode = NAND_HW_ECC;
	aml_nand_dbg("phydev->writesize= %x",phydev->writesize);
	do {
		if ((devops->addr % phydev->erasesize) == 0 ) {
			ret =  phydev->block_isbad(phydev);
			if (ret > 0) {
				aml_nand_msg("Skipping bad block at %llx", devops->addr);
				devops->addr += phydev->erasesize;
				continue;
			} else if (ret < 0) {
				aml_nand_msg("AMLNAND get bad block failed: ret=%d at addr=%llx",ret, devops->addr);
				return -1;
			}
		}
		ret = phydev->write(phydev);
		if (ret < 0) {
			aml_nand_msg("nand write failed at %llx",devops->addr);
			ret = -NAND_WRITE_FAILED;
			goto exit_error;
		}

		if (flag == 1) { // verify data
			memset(verify_buf, 0x0, (2*phydev->writesize));
			devops->datbuf = verify_buf;
			ret = phydev->read(phydev);
			if (ret) {
				aml_nand_msg("nand test read data failed at  %llx",devops->addr);
				ret = -NAND_WRITE_FAILED;
				goto exit_error;
			}
			if (memcmp(verify_buf, buffer, phydev->writesize)) {
				aml_nand_msg("nand test verify data failed at  %llx",devops->addr);
				ret = -NAND_WRITE_FAILED;
				goto exit_error;
			}
			devops->datbuf = buffer;
		}

		devops->addr +=  phydev->writesize;

		if ((((phydev->offset + devops->addr) % phydev->erasesize) == 0))
			aml_nand_msg("aml nand write devops->addr %llx OK",devops->addr);

	}while(devops->addr < (offset + write_len));


exit_error:

	if (flag == 1) {
		if (verify_buf) {
			aml_nand_free(verify_buf);
		}
	}
	return ret;
}
//nand_test  4 write and read  every block test
static int amlnand_test4(void)
{
    struct amlnand_phydev *phydev = NULL;
    //struct amlnand_chip *aml_chip;
    //struct phydev_ops  *devops;

    int ret =0, j = 0, verify_lag  =0;
    unsigned char * data_buf = NULL;
    uint64_t offset = 0 , write_len = 0,read_len=0;
    uint64_t erase_len, erase_off;

    list_for_each_entry(phydev,&nphy_dev_list,list){
        data_buf = aml_nand_malloc( phydev->writesize);
        if (!data_buf) {
            aml_nand_msg("malloc failed");
            goto exit_0;
        }
    memset(data_buf, 0xa5, phydev->writesize);
    if (strncmp(phydev->name,NAND_BOOT_NAME,strlen((const char*)NAND_BOOT_NAME))) {
        aml_nand_msg("nand test 4 : phydev->name %s",phydev->name);
        //aml_chip = (struct amlnand_chip *)phydev->priv;
        //devops = &phydev->ops;
//erase
        erase_off = 0;
        erase_len = phydev->size ;
        ret = nand_erase_ops_test(phydev, erase_off, erase_len);
        if (ret < 0) {
            aml_nand_msg("nand test 4 : erase failed ");
            ret= -NAND_ERASE_FAILED;
            goto exit_0;
        }
        aml_nand_msg("nand test 4 : erase %d times OK ",j);
//write
        offset = 0;
        write_len =  phydev->size;
        verify_lag = 0;  // 1 indicate verify data when write
        ret = nand_write_ops_test(phydev, offset, write_len,data_buf,verify_lag);
        if (ret < 0 ) {
            aml_nand_msg("nand test 4 : write failed ");
            ret= -NAND_WRITE_FAILED;
            goto exit_0;
        }
        aml_nand_msg("nand test 4 : write %d times OK ",j);
//read disturb
        offset = 0;
        read_len =  phydev->size;
        ret = nand_read_ops_test(phydev, offset, read_len,data_buf);
        if (ret < 0 ) {
            aml_nand_msg("nand test 4 : read failed ");
            ret= -NAND_READ_FAILED;
            goto exit_0;
        }
        aml_nand_msg("nand test 4 : read %d times OK ",j);
    }
    if (data_buf)
       {
        kfree(data_buf);
        data_buf = NULL;
       }
    }

exit_0:
    if (data_buf) {
        kfree(data_buf);
        data_buf = NULL;
    }

    return ret;

}

static int amlnand_test3(void)
{
    struct amlnand_phydev *phydev = NULL;
    //struct amlnand_chip *aml_chip;
    //struct phydev_ops  *devops;

    int ret =0, verify_lag  =0;
    unsigned char * data_buf = NULL;
    uint64_t offset = 0 , write_len = 0,read_len=0, i = 0;
    uint64_t erase_len, erase_off;

    list_for_each_entry(phydev,&nphy_dev_list,list){
        data_buf = aml_nand_malloc( phydev->writesize);
        if (!data_buf) {
            aml_nand_msg("malloc failed");
            goto exit_0;
        }
    memset(data_buf, 0xa5, phydev->writesize);
    if (strncmp(phydev->name,NAND_BOOT_NAME,strlen((const char*)NAND_BOOT_NAME))) {
        aml_nand_msg("nand test 3 : phydev->name %s",phydev->name);
        //aml_chip = (struct amlnand_chip *)phydev->priv;
        //devops = &phydev->ops;
        aml_nand_msg("nand test 3 : phydev->size=%llx ",phydev->size);
//erase
        erase_off = 0;
        erase_len = phydev->size ;
        ret = nand_erase_ops_test(phydev, erase_off, erase_len);
        if (ret < 0) {
            aml_nand_msg("nand test 3 : erase failed ");
            ret= -NAND_ERASE_FAILED;
            goto exit_0;
        }
        aml_nand_msg("nand test 3 : erase OK ");
        for (i=0;i<(phydev->size>>phydev->erasesize_shift)-1;i++) {
    //write
            offset = i<<phydev->erasesize_shift;
            write_len =  (i&0xff)*phydev->writesize;
            verify_lag = 1;  // 1 indicate verify data when write
            aml_nand_msg("nand test 3 : poffset=%llx ",offset);
            ret = nand_write_ops_test(phydev, offset, write_len,data_buf,verify_lag);
            if (ret < 0 ) {
                aml_nand_msg("nand test 3 : write failed ");
                ret= -NAND_WRITE_FAILED;
                goto exit_0;
            }
            aml_nand_msg("nand test 3 : write OK ");
    //read disturb
            offset = i<<phydev->erasesize_shift;
            read_len =  (i&0xff)*phydev->writesize;
            ret = nand_read_ops_test(phydev, offset, read_len,data_buf);
            if (ret < 0 ) {
                aml_nand_msg("nand test 3 : read failed ");
                ret= -NAND_READ_FAILED;
                goto exit_0;
            }
            aml_nand_msg("nand test 3 : read OK ");
        }
    }
    if (data_buf)
       {
        kfree(data_buf);
        data_buf = NULL;
       }
    }

exit_0:
    if (data_buf) {
        kfree(data_buf);
        data_buf = NULL;
    }

    return ret;

}

//nand_test  2 Endurance test
static int amlnand_test2(void)
{
    struct amlnand_phydev *phydev = NULL;
    //struct amlnand_chip *aml_chip;
    //struct phydev_ops  *devops;

    int ret =0, j = 0, verify_lag  =0;
    unsigned char * data_buf = NULL;
    uint64_t offset = 0 , write_len = 0,read_len=0;
    uint64_t erase_len, erase_off;
    //int read_times  = 1000;

    list_for_each_entry(phydev,&nphy_dev_list,list){
        data_buf = aml_nand_malloc( phydev->writesize);
        if (!data_buf) {
            aml_nand_msg("malloc failed");
            goto exit_0;
        }
        for (j=1;j<3000;j++)
        {
            memset(data_buf, 0xa5, phydev->writesize);
        if (strncmp(phydev->name,NAND_BOOT_NAME,strlen((const char*)NAND_BOOT_NAME))) {
            aml_nand_msg("nand test 2 : phydev->name %s",phydev->name);
            //aml_chip = (struct amlnand_chip *)phydev->priv;
            //devops = &phydev->ops;
//erase
            erase_off = 0;
            erase_len = phydev->size ;
            ret = nand_erase_ops_test(phydev, erase_off, erase_len);
            if (ret < 0) {
                aml_nand_msg("nand test 2 : erase failed ");
                ret= -NAND_ERASE_FAILED;
                goto exit_0;
            }
            aml_nand_msg("nand test 2 : erase %d times OK ",j);
//write
            offset = 0;
            write_len =  phydev->size;
            verify_lag = 0;  // 1 indicate verify data when write
            ret = nand_write_ops_test(phydev, offset, write_len,data_buf,verify_lag);
            if (ret < 0 ) {
                aml_nand_msg("nand test 2 : write failed ");
                ret= -NAND_WRITE_FAILED;
                goto exit_0;
            }
            aml_nand_msg("nand test 2 : write %d times OK ",j);
//read disturb
            offset = 0;
            read_len =  phydev->size;
            ret = nand_read_ops_test(phydev, offset, read_len,data_buf);
            if (ret < 0 ) {
                aml_nand_msg("nand test 2 : read failed ");
                ret= -NAND_READ_FAILED;
                goto exit_0;
            }
            aml_nand_msg("nand test 2 : read %d times OK ",j);
        }
     }
    if (data_buf)
       {
        kfree(data_buf);
        data_buf = NULL;
       }
    }

exit_0:
    if (data_buf) {
        kfree(data_buf);
        data_buf = NULL;
    }

    return ret;


}
//nand_test  1 Read Distub test
static int amlnand_test1(void)
{
	struct amlnand_phydev *phydev = NULL;
	//struct amlnand_chip *aml_chip;
	//struct phydev_ops  *devops;

	int ret =0, i = 0, verify_lag  =0;
	unsigned char * data_buf = NULL;
	uint64_t offset = 0 , write_len = 0,read_len=0;
	uint64_t erase_len, erase_off;
	int read_times  = 10000;

	list_for_each_entry(phydev,&nphy_dev_list,list){
		data_buf = aml_nand_malloc( phydev->writesize);
		if (!data_buf) {
			aml_nand_msg("malloc failed");
			goto exit_0;
		}
		memset(data_buf, 0xa5, phydev->writesize);

		if (strncmp(phydev->name,NAND_BOOT_NAME,strlen((const char*)NAND_BOOT_NAME))) {
			aml_nand_msg("nand test 1 : phydev->name %s",phydev->name);
			// aml_chip = (struct amlnand_chip *)phydev->priv;
			// devops = &phydev->ops;
//erase
			erase_off = 0;
			erase_len = phydev->size ;
			ret = nand_erase_ops_test(phydev, erase_off, erase_len);
			if (ret < 0) {
				aml_nand_msg("nand test 1 : erase failed ");
				ret= -NAND_ERASE_FAILED;
				goto exit_0;
			}
            aml_nand_msg("nand test 1 : erase OK");
//write
			offset = 0;
			write_len =  phydev->size;
			verify_lag = 0;  // 1 indicate verify data when write
			ret = nand_write_ops_test(phydev, offset, write_len,data_buf,verify_lag);
			if (ret < 0 ) {
				aml_nand_msg("nand test 1 : write failed ");
				ret= -NAND_WRITE_FAILED;
				goto exit_0;
			}
            aml_nand_msg("nand test 1 : write OK");
//read disturb
			for (i = 0; i < read_times; i++) {
				offset = 0;
				read_len =	4*phydev->erasesize;
				ret = nand_read_ops_test(phydev, offset, read_len,data_buf);
				if (ret < 0 ) {
					aml_nand_msg("nand test 1 : read failed ");
					ret= -NAND_WRITE_FAILED;
					goto exit_0;
				}
                aml_nand_msg("nand test 1 : read %d times OK",i);
			}

//erase
			erase_off = 0;
			erase_len = phydev->size ;
			ret = nand_erase_ops_test(phydev, erase_off, erase_len);
			if (ret < 0) {
				aml_nand_msg("nand test 1 : erase failed ");
				ret= -NAND_ERASE_FAILED;
				goto exit_0;
			}

		}

		if (data_buf) {
			kfree(data_buf);
			data_buf = NULL;
		}

	}

exit_0:
	if (data_buf) {
		kfree(data_buf);
		data_buf = NULL;
	}

	return ret;
}
//nand_test  0 E/P/R Cycle Whole chip
static int amlnand_test0(void)
{
	struct amlnand_phydev *phydev = NULL;
	//struct amlnand_chip *aml_chip;
	//struct phydev_ops  *devops;

	int ret =0, verify_lag  =0;
	unsigned char * data_buf = NULL;
	uint64_t offset = 0 , write_len = 0,read_len=0;
	uint64_t erase_len, erase_off;

	list_for_each_entry(phydev,&nphy_dev_list,list){

		data_buf = aml_nand_malloc(phydev->writesize);
		if (!data_buf) {
			aml_nand_msg("malloc failed");
			ret = -1;
			goto exit_0;
		}
		memset(data_buf, 0xa5, phydev->writesize);

		if (strncmp(phydev->name,NAND_BOOT_NAME,strlen((const char*)NAND_BOOT_NAME))) {
			aml_nand_msg("nand test 0 : phydev->name %s",phydev->name);
			// aml_chip = (struct amlnand_chip *)phydev->priv;
			// devops = &phydev->ops;
//erase
			aml_nand_msg("nand test 0 : erase");
			erase_off = 0;
			erase_len = phydev->size ;
			ret = nand_erase_ops_test(phydev, erase_off, erase_len);
			if (ret < 0) {
				aml_nand_msg("nand test 0 : erase failed ");
				ret= -NAND_ERASE_FAILED;
				goto exit_0;
			}
//write
			aml_nand_msg("nand test 0 : write");
			offset = 0;
			write_len =  phydev->size;
			verify_lag = 0;  // 1 indicate verify data when write
			ret = nand_write_ops_test(phydev, offset, write_len,data_buf,verify_lag);
			if (ret < 0 ) {
				aml_nand_msg("nand test 0 : write failed ");
				ret= -NAND_WRITE_FAILED;
				goto exit_0;
			}
//read
			aml_nand_msg("nand test 0 : read");
			offset = 0;
			read_len =  phydev->size;
			ret = nand_read_ops_test(phydev, offset, read_len,data_buf);
			if (ret < 0 ) {
				aml_nand_msg("nand test 0 : read failed ");
				ret= -NAND_WRITE_FAILED;
				goto exit_0;
			}
//erase
			erase_off = 0;
			erase_len = phydev->size ;
			ret = nand_erase_ops_test(phydev, erase_off, erase_len);
			if (ret < 0) {
				aml_nand_msg("nand test 0 : erase failed ");
				ret= -NAND_ERASE_FAILED;
				goto exit_0;
			}

		}

		if (data_buf) {
			kfree(data_buf);
			data_buf = NULL;
		}
	}

exit_0:
	if (data_buf) {
		kfree(data_buf);
		data_buf = NULL;
	}

	return ret;
}


int do_amlnand_test(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	int ret = 0;
	//ulong addr;
	//ulong data_write;
	//loff_t off, size;
	char *cmd;

	if (argc < 2) {
		printf("argc less than 2 :\n");
		goto usage;
	}

	cmd = argv[1];

	if (strncmp(cmd, "0", 1) == 0) {
		ret = amlnand_test0();
		if (ret < 0) {
			aml_nand_msg("amlnand_test0: E/P/R Cycle failed");
		}else
			aml_nand_msg("amlnand_test0: E/P/R Cycle OK");
		return 0;
	}else if (strncmp(cmd, "1", 1) == 0){
		ret = amlnand_test1();
		if (ret < 0) {
			aml_nand_msg("amlnand_test1: Read Distub test failed");
		}else
			aml_nand_msg("amlnand_test1: Read Distub test OK");
		return 0;
	}else if (strncmp(cmd, "2", 1) == 0){
		ret = amlnand_test2();
		if (ret < 0) {
			aml_nand_msg("amlnand_test2: Endurance test failed");
		}else
			aml_nand_msg("amlnand_test2: Endurance test OK");
		return 0;
	}else if (strncmp(cmd, "3", 1) == 0){
		ret = amlnand_test3();
		if (ret < 0) {
			aml_nand_msg("amlnand_test3: write and read random pages of every block test failed");
		}else
			aml_nand_msg("amlnand_test3: write and read random pages of every block test OK");

		return 0;
	}else if (strncmp(cmd, "4", 1) == 0){
		ret = amlnand_test4();
		if (ret < 0) {
			aml_nand_msg("amlnand_test4: READ all page  every block test failed");
		}else
			aml_nand_msg("amlnand_test4: READ all page  every block test OK");

		return 0;
	}else{
			goto usage;
	}

usage:
	cmd_usage(cmdtp);
	return 1;

}

U_BOOT_CMD(amlnf_test, CONFIG_SYS_MAXARGS, 1, do_amlnand_test,
	"AMLPHYNAND sub-system",
	"amlnf_test  0 E/P/R Cycle Whole chip \n"
	"amlnf_test  1 Read Distub test,read block 0~3 10k times \n"
	"amlnf_test  2 Endurance test, E/W/R 10 block 3000 times  \n"
	"amlnf_test  3 write and read random pages of every block test \n"
	"amlnf_test  4 READ all page every block   \n"
	"amlnf_test  5 ...... \n"
	"amlnf_test  8 exit sync \n"
);


