| |
| #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" |
| ); |
| |
| |