/drivers/block/sun3i_nand/nandtest/nand_test.c

https://bitbucket.org/ndreys/linux-sunxi · C · 1292 lines · 937 code · 265 blank · 90 comment · 107 complexity · f931f3ab0b809dfc34b084e210e62260 MD5 · raw file

  1. /*
  2. * drivers/block/sun3i_nand/nandtest/nand_test.c
  3. *
  4. * (C) Copyright 2007-2012
  5. * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20. * MA 02111-1307 USA
  21. */
  22. #include <linux/device.h>
  23. #include <linux/module.h>
  24. #include <linux/kernel.h>
  25. #include <linux/init.h>
  26. #include <linux/string.h>
  27. #include <linux/sysfs.h>
  28. #include <linux/stat.h>
  29. #include <linux/module.h>
  30. #include <linux/moduleparam.h>
  31. #include <linux/ioport.h>
  32. #include <linux/device.h>
  33. #include <linux/interrupt.h>
  34. #include <linux/delay.h>
  35. #include <linux/err.h>
  36. #include <linux/clk.h>
  37. #include <linux/scatterlist.h>
  38. #include <linux/platform_device.h>
  39. #include <linux/dma-mapping.h>
  40. #include <linux/cpufreq.h>
  41. #include <linux/sched.h>
  42. #include "../src/include/nand_type.h"
  43. #include "../src/include/nand_drv_cfg.h"
  44. #include "../src/include/nand_format.h"
  45. #include "../src/include/nand_logic.h"
  46. #include "../src/include/nand_oal.h"
  47. #include "../src/include/nand_physic.h"
  48. #include "../src/include/nand_scan.h"
  49. #include "../src/include/nand_simple.h"
  50. #include "../nfd/nand_blk.h"
  51. #include "../nfd/mbr.h"
  52. #include "nand_test.h"
  53. #ifdef CONFIG_SUN3I_NANDFLASH_TEST // open nand test module
  54. #define NAND_TEST "[nand_test]:"
  55. #define RESULT_OK (0)
  56. #define RESULT_FAIL (1)
  57. #define MAX_SECTORS (100) // max alloc buffer
  58. #define BUFFER_SIZE (512*MAX_SECTORS)
  59. static ssize_t nand_test_store(struct kobject *kobject,struct attribute *attr, const char *buf, size_t count);
  60. static ssize_t nand_test_show(struct kobject *kobject,struct attribute *attr, char *buf);
  61. void obj_test_release(struct kobject *kobject);
  62. struct nand_test_card {
  63. u8 *buffer;
  64. u8 *scratch;
  65. unsigned int sector_cnt;
  66. };
  67. struct nand_test_case {
  68. const char *name;
  69. int sectors_cnt;
  70. int (*prepare)(struct nand_test_card *, int sectors_cnt);
  71. int (*run)(struct nand_test_card * );
  72. int (*cleanup)(struct nand_test_card *);
  73. };
  74. struct attribute prompt_attr = {
  75. .name = "nand_test",
  76. .mode = S_IRWXUGO
  77. };
  78. static struct attribute *def_attrs[] = {
  79. &prompt_attr,
  80. NULL
  81. };
  82. struct sysfs_ops obj_test_sysops =
  83. {
  84. .show = nand_test_show,
  85. .store = nand_test_store
  86. };
  87. struct kobj_type ktype =
  88. {
  89. .release = obj_test_release,
  90. .sysfs_ops=&obj_test_sysops,
  91. .default_attrs=def_attrs
  92. };
  93. void obj_test_release(struct kobject *kobject)
  94. {
  95. printk(NAND_TEST "release .\n");
  96. }
  97. /* prepare buffer data for read and write*/
  98. static int __nand_test_prepare(struct nand_test_card *test, int sector_cnt,int write)
  99. {
  100. int i;
  101. test->sector_cnt = sector_cnt;
  102. if (write){
  103. memset(test->buffer, 0xDF, 512 * (sector_cnt) +4);
  104. }
  105. else {
  106. for (i = 0; i < 512 * (sector_cnt) + 4; i++){
  107. test->buffer[i] = i%256;
  108. }
  109. }
  110. return 0;
  111. }
  112. static int nand_test_prepare_write(struct nand_test_card *test, int sector_cnt)
  113. {
  114. return __nand_test_prepare(test, sector_cnt, 1);
  115. }
  116. static int nand_test_prepare_read(struct nand_test_card *test, int sector_cnt)
  117. {
  118. return __nand_test_prepare(test, sector_cnt, 0);
  119. }
  120. static int nand_test_prepare_pwm(struct nand_test_card *test, int sector_cnt)
  121. {
  122. test->sector_cnt = sector_cnt;
  123. return 0;
  124. }
  125. /* read /write one sector with out verification*/
  126. static int nand_test_simple_transfer(struct nand_test_card *test,
  127. unsigned dev_addr,unsigned start,
  128. unsigned nsector, int write)
  129. {
  130. int ret;
  131. if (write){
  132. #ifndef NAND_CACHE_RW
  133. ret = LML_Write(start, nsector, test->buffer + dev_addr);
  134. #else
  135. //printk("Ws %lu %lu \n",start, nsector);
  136. ret = NAND_CacheWrite(start, nsector, test->buffer + dev_addr);
  137. #endif
  138. if(ret){
  139. return -EIO;
  140. }
  141. return 0;
  142. }
  143. else {
  144. #ifndef NAND_CACHE_RW
  145. LML_FlushPageCache();
  146. ret = LML_Read(start, nsector, test->buffer + dev_addr);
  147. #else
  148. //printk("Rs %lu %lu \n",start, nsector);
  149. LML_FlushPageCache();
  150. ret = NAND_CacheRead(start, nsector, test->buffer + dev_addr);
  151. #endif // read
  152. if (ret){
  153. return -EIO;
  154. }
  155. return 0;
  156. }
  157. }
  158. /* read /write one or more sectors with verification*/
  159. static int nand_test_transfer(struct nand_test_card *test,
  160. unsigned dev_addr,unsigned start,
  161. unsigned nsector, int write)
  162. {
  163. int ret;
  164. int i;
  165. if (!write){
  166. ret = nand_test_simple_transfer(test, 0, start, nsector, 1); // write to sectors for read
  167. if (ret){
  168. return ret;
  169. }
  170. memset(test->buffer, 0, nsector * 512 +4); // clean mem for read
  171. }
  172. if ( ( ret = nand_test_simple_transfer(test, dev_addr, start, nsector, write ) ) ) { // read or write
  173. return ret;
  174. }
  175. if(write){
  176. memset(test->buffer, 0, nsector * 512 + 4); // clean mem for read
  177. ret = nand_test_simple_transfer(test, 0 , start, nsector, 0); // read
  178. if (ret){
  179. return ret;
  180. }
  181. for(i = 0; i < nsector * 512; i++){ // verify data
  182. if (test->buffer[i] != 0xDF){
  183. printk(KERN_INFO "[nand_test] Ttest->buffer[i] = %d, i = %d, dev_addr = %d, nsector = %d\n", test->buffer[i], i, dev_addr,nsector);
  184. return RESULT_FAIL;
  185. }
  186. }
  187. }
  188. else { //read
  189. for(i = 0 + dev_addr; i < nsector * 512 + dev_addr ; i++){ // verify data
  190. if (test->buffer[i] != (i-dev_addr)%256){
  191. printk(KERN_INFO "[nand_test] Ttest->buffer[i] = %d, i = %d, dev_addr = %d, nsector = %d\n", test->buffer[i], i, dev_addr,nsector);
  192. return RESULT_FAIL;
  193. }
  194. }
  195. }
  196. return RESULT_OK;
  197. }
  198. /* write one sector without verification*/
  199. static int nand_test_single_write(struct nand_test_card *test)
  200. {
  201. int ret;
  202. ret = nand_test_simple_transfer(test, 0, 0, test->sector_cnt,1);
  203. if(ret){
  204. return ret;
  205. }
  206. return nand_test_simple_transfer(test, 0, DiskSize/2, test->sector_cnt, 1 );
  207. }
  208. /* read one sector without verification*/
  209. static int nand_test_single_read(struct nand_test_card *test)
  210. {
  211. int ret;
  212. ret = nand_test_simple_transfer(test, 0, 0, test->sector_cnt,0);
  213. if(ret){
  214. return ret;
  215. }
  216. return nand_test_simple_transfer(test, 0, DiskSize/2, test->sector_cnt, 0);
  217. }
  218. /* write one sector with verification */
  219. static int nand_test_verify_write(struct nand_test_card *test)
  220. {
  221. return nand_test_transfer(test, 0, 1, test->sector_cnt, 1);
  222. }
  223. /* read one sector with verification */
  224. static int nand_test_verify_read(struct nand_test_card *test)
  225. {
  226. return nand_test_transfer(test, 0, 1, test->sector_cnt, 0);
  227. }
  228. /* write multi sector with start sector num 5*/
  229. static int nand_test_multi_write(struct nand_test_card *test)
  230. {
  231. return nand_test_transfer(test, 0, 5, test->sector_cnt, 1);
  232. }
  233. /* write multi sector with start sector num 29*/
  234. static int nand_test_multi_read(struct nand_test_card *test)
  235. {
  236. return nand_test_transfer(test, 0, 29, test->sector_cnt, 0);
  237. }
  238. /* write from buffer+1, buffer+2, and buffer+3, where buffer is 4 bytes algin */
  239. static int nand_test_align_write(struct nand_test_card *test)
  240. {
  241. int ret;
  242. int i;
  243. for (i = 1;i < 4;i++) {
  244. ret = nand_test_transfer(test, i, 1, test->sector_cnt, 1);
  245. }
  246. return ret;
  247. }
  248. /* read to buffer+1, buffer+2, and buffer+3, where buffer is 4 bytes algin */
  249. static int nand_test_align_read(struct nand_test_card *test)
  250. {
  251. int ret;
  252. int i;
  253. for (i = 1;i < 4;i++) {
  254. ret = nand_test_transfer(test, i, 1, test->sector_cnt, 0);
  255. }
  256. if (ret){
  257. return ret;
  258. }
  259. return 0;
  260. }
  261. /* write to incorrect sector num such as -1, DiskSize, DiskSize +1 */
  262. static int nand_test_negstart_write(struct nand_test_card *test)
  263. {
  264. int ret;
  265. /* start + sectnum > 0, start < 0*/
  266. ret = nand_test_simple_transfer(test, 0, -5 , 11, 1);
  267. if (!ret){
  268. return RESULT_FAIL;
  269. }
  270. printk(NAND_TEST "start + sectnum > 0 pass\n");
  271. /* start + sectnum < 0 , start < 0 */
  272. ret = nand_test_simple_transfer(test, 0, -62, 5, 1);
  273. if (!ret){
  274. return RESULT_FAIL;
  275. }
  276. return RESULT_OK;
  277. }
  278. /* read from negative sector num start + sectnum > 0, and start + setnum < 0 */
  279. static int nand_test_negstart_read(struct nand_test_card *test)
  280. {
  281. int ret;
  282. /* start + sectnum > 0, start < 0*/
  283. ret = nand_test_simple_transfer(test, 0, -1, 3, 0);
  284. if (!ret){
  285. return RESULT_FAIL;
  286. }
  287. printk(NAND_TEST "start + sectnum > 0 pass\n");
  288. /* start + sectnum < 0 , start < 0 */
  289. ret = nand_test_simple_transfer(test, 0, -90, 15, 0);
  290. if (!ret){
  291. return RESULT_FAIL;
  292. }
  293. return RESULT_OK;
  294. }
  295. static int nand_test_beyond(struct nand_test_card *test, int write)
  296. {
  297. int ret;
  298. ret = nand_test_simple_transfer(test, 0, DiskSize -3 , 5, write);
  299. if (!ret){
  300. return 1;
  301. }
  302. printk(NAND_TEST "DiskSize -3 , 5 pass\n");
  303. ret = nand_test_simple_transfer(test, 0, DiskSize -1 , 2, write);
  304. if (!ret){
  305. return 1;
  306. }
  307. printk(NAND_TEST "DiskSize -1 , 2 pass\n");
  308. ret = nand_test_simple_transfer(test, 0, DiskSize , 3, write);
  309. if (!ret){
  310. return 1;
  311. }
  312. printk(NAND_TEST "DiskSize , 3 pass\n");
  313. ret = nand_test_simple_transfer(test, 0, DiskSize + 3 , 0, write);
  314. if (!ret){
  315. return 1;
  316. }
  317. printk(NAND_TEST "DiskSize + 3 , 0 pass\n");
  318. ret = nand_test_simple_transfer(test, 0, DiskSize - 3 , -2, write);
  319. if (!ret){
  320. return 1;
  321. }
  322. printk(NAND_TEST "DiskSize - 3 , -2 pass\n");
  323. return RESULT_OK;
  324. }
  325. static int nand_test_beyond_write(struct nand_test_card *test)
  326. {
  327. return (nand_test_beyond(test, 1));
  328. }
  329. /* read from incorrect sector num such as -1, DiskSize(max sector num + 1), DiskSize +1 */
  330. static int nand_test_beyond_read(struct nand_test_card *test)
  331. {
  332. return (nand_test_beyond(test, 0));
  333. }
  334. /* write all sectors from sector num 0 to DiskSize - 1(max sector num )*/
  335. static int nand_test_write_all_ascending(struct nand_test_card *test)
  336. {
  337. int ret;
  338. int i = 0;
  339. int j = 0;
  340. printk(KERN_INFO "DiskSize = %x\n", DiskSize);
  341. for (i = 0; i < DiskSize; i++) { // write all sectors
  342. ret = nand_test_simple_transfer(test, 0, i, test->sector_cnt,1);
  343. if(ret){
  344. printk(KERN_INFO "nand_test_write_all_ascending fail, sector num %d\n", i);
  345. return ret;
  346. }
  347. }
  348. /* start check */
  349. printk(KERN_INFO "[nand test]:start check\n");
  350. for (i = 0; i < DiskSize; i++){
  351. memset(test->buffer, 0, test->sector_cnt * 512); // clear buffer
  352. ret = nand_test_simple_transfer(test, 0 , i, test->sector_cnt, 0); // read
  353. if(ret){
  354. return ret;
  355. }
  356. for(j = 0; j < test->sector_cnt * 512; j++) { // verify
  357. if (test->buffer[j] != 0xDF){
  358. printk(KERN_INFO "nand_test_write_all_ascending, Ttest->buffer[j] = %d, i = %d\n", test->buffer[j], i);
  359. return RESULT_FAIL;
  360. }
  361. }
  362. }
  363. return RESULT_OK;
  364. }
  365. /* read all sectors from sector num 0 to DiskSize - 1(max sector num )*/
  366. static int nand_test_read_all_ascending(struct nand_test_card *test)
  367. {
  368. int ret;
  369. int i = 0;
  370. int j = 0;
  371. /* before reading, write */
  372. for (i = 0; i < DiskSize; i++) {
  373. ret = nand_test_simple_transfer(test, 0, i, test->sector_cnt,1); // write all sectors
  374. if(ret){
  375. printk(KERN_INFO "nand_test_read_all_ascending fail, sector num %d\n", i);
  376. return ret;
  377. }
  378. }
  379. /* finish write, start to read and check */
  380. for (i = 0; i < DiskSize; i++)
  381. {
  382. if (i%100000 == 0){
  383. printk(KERN_INFO "[nand test]: sector num:%d\n", i);
  384. }
  385. memset(test->buffer, 0, test->sector_cnt * 512); // clear buffer
  386. ret = nand_test_simple_transfer(test, 0 , i, test->sector_cnt, 0); // read
  387. if(ret){
  388. return ret;
  389. }
  390. for(j = 0 ; j < test->sector_cnt * 512 ; j++){
  391. if (test->buffer[j] != (j)%256){
  392. printk(KERN_INFO "nand_test_read_all_ascending fial! Ttest->buffer[j] = %d, i = %d\n", test->buffer[i], j);
  393. return RESULT_FAIL;
  394. }
  395. }
  396. }
  397. return RESULT_OK;
  398. }
  399. /* write all sectors from sector num DiskSize - 1(max sector num ) to 0 */
  400. static int nand_test_write_all_descending(struct nand_test_card *test)
  401. {
  402. int ret;
  403. int i = 0;
  404. int j = 0;
  405. printk(KERN_INFO "nand_test: DiskSize = %x\n", DiskSize);
  406. for (i = DiskSize - 1; i >= 0; i--){
  407. memset(test->buffer, i%256, 512);
  408. if (i%100000 == 0){
  409. printk(KERN_INFO "[nand test]: sector num:%d\n", i);
  410. }
  411. ret = nand_test_simple_transfer(test, 0, i, test->sector_cnt,1); // write all sectors
  412. if(ret){
  413. printk(KERN_INFO "[nand_test]: nand_test_write_all_ascending fail, sector num %d\n", i);
  414. return ret;
  415. }
  416. }
  417. printk(KERN_INFO "[nand test]: check start\n");
  418. for (i = DiskSize - 1; i >= 0; i--){
  419. if (i%100000 == 0){
  420. printk(KERN_INFO "[nand test]: sector num:%d\n", i);
  421. }
  422. memset(test->buffer, 0, test->sector_cnt * 512); // clear buffer
  423. ret = nand_test_simple_transfer(test, 0 , i, test->sector_cnt, 0); // read
  424. if(ret){
  425. return ret;
  426. }
  427. for(j = 0; j < 512; j++){ // verify
  428. if (test->buffer[j] != i%256){
  429. printk(KERN_INFO "[nand_test]: nand_test_write_all_ascending, Ttest->buffer[j] = %d, i = %d\n", test->buffer[j], i);
  430. return RESULT_FAIL;
  431. }
  432. }
  433. }
  434. return RESULT_OK;
  435. }
  436. /* read all sectors from sector num DiskSize - 1(max sector num ) to 0 */
  437. static int nand_test_read_all_descending(struct nand_test_card *test)
  438. {
  439. int ret;
  440. int i = 0;
  441. int j = 0;
  442. for (i = DiskSize - 1; i >= 0; i--){
  443. memset(test->buffer, i%256, 512);
  444. ret = nand_test_simple_transfer(test, 0, i, test->sector_cnt,1); // write all sectors
  445. if(ret){
  446. printk(KERN_INFO "[nand_test]: nand_test_read_all_ascending fail, sector num %d\n", i);
  447. return ret;
  448. }
  449. }
  450. printk(KERN_INFO "[nand test]: check start\n");
  451. for (i = DiskSize - 1; i >= 0; i--){
  452. if (i%100000 == 0){
  453. printk(KERN_INFO "[nand test]: sector num:%d\n", i);
  454. }
  455. memset(test->buffer, 0, test->sector_cnt * 512); // clear buffer
  456. ret = nand_test_simple_transfer(test, 0 , i, test->sector_cnt, 0); // read
  457. if(ret){
  458. return ret;
  459. }
  460. for(j = 0 ; j < test->sector_cnt * 512 ; j++){ // verify data
  461. if (test->buffer[j] != (i)%256){
  462. printk(KERN_INFO "[nand_test]:nand_test_read_all_ascending fial! Ttest->buffer[j] = %d, i = %d\n", test->buffer[j], i);
  463. return RESULT_FAIL;
  464. }
  465. }
  466. }
  467. return RESULT_OK;
  468. }
  469. /* write a sector for n times without verification to test stability */
  470. static int nand_test_repeat_single_write(struct nand_test_card *test)
  471. {
  472. int ret;
  473. int i = 0;
  474. printk(NAND_TEST "DiskSize = %d\n", DiskSize);
  475. for(i = 0; i < REPEAT_TIMES*1000; i++){
  476. ret = nand_test_simple_transfer(test, 0 , DiskSize/7, test->sector_cnt, 1);
  477. if(ret){
  478. return ret;
  479. }
  480. }
  481. return 0;
  482. }
  483. /* read a sector for n times with verification to test stability*/
  484. static int nand_test_repeat_single_read(struct nand_test_card *test)
  485. {
  486. int ret;
  487. int i = 0;
  488. for(i = 0; i < REPEAT_TIMES*30; i++){
  489. ret = nand_test_simple_transfer(test, 0 , DiskSize/4 + 7, test->sector_cnt, 0);
  490. if(ret){
  491. return ret;
  492. }
  493. }
  494. return 0;
  495. }
  496. /* write multi sectors for n times without verification to test stability*/
  497. static int nand_test_repeat_multi_write(struct nand_test_card *test)
  498. {
  499. int ret;
  500. int i = 0;
  501. for(i = 0; i < 1100000; i++){
  502. ret = nand_test_simple_transfer(test, 0 , DiskSize/2, test->sector_cnt, 1);
  503. if(ret) {
  504. return ret;
  505. }
  506. }
  507. return 0;
  508. }
  509. /* read multi sectors for n times without verification to test stability*/
  510. static int nand_test_repeat_multi_read(struct nand_test_card *test)
  511. {
  512. int ret;
  513. int i = 0;
  514. for(i = 0; i < 9200000; i++){
  515. ret = nand_test_simple_transfer(test, 0 , DiskSize/3, test->sector_cnt, 0);
  516. if(ret){
  517. return ret;
  518. }
  519. }
  520. return 0;
  521. }
  522. /* random write one or more sectors*/
  523. static int nand_test_random_write(struct nand_test_card *test)
  524. {
  525. int ret;
  526. ret = nand_test_simple_transfer(test, 0 , 0, test->sector_cnt, 1);
  527. if(ret){
  528. return ret;
  529. }
  530. ret = nand_test_simple_transfer(test, 0 , DiskSize -1, test->sector_cnt, 1);
  531. if(ret) {
  532. return ret;
  533. }
  534. ret = nand_test_simple_transfer(test, 0 , DiskSize/2, test->sector_cnt, 1);
  535. if(ret){
  536. return ret;
  537. }
  538. return 0;
  539. }
  540. /* random read one or more sectors*/
  541. static int nand_test_random_read(struct nand_test_card *test)
  542. {
  543. int ret;
  544. ret = nand_test_simple_transfer(test, 0 , 0, test->sector_cnt, 0);
  545. if(ret) {
  546. return ret;
  547. }
  548. ret = nand_test_simple_transfer(test, 0 , DiskSize -1, test->sector_cnt, 0);
  549. if(ret){
  550. return ret;
  551. }
  552. ret = nand_test_simple_transfer(test, 0 , DiskSize/2, test->sector_cnt, 0);
  553. if(ret){
  554. return ret;
  555. }
  556. return 0;
  557. }
  558. /* clear r/w buffer to 0*/
  559. static int nand_test_cleanup(struct nand_test_card *test)
  560. {
  561. memset(test->buffer, 0, 512* (test->sector_cnt));
  562. return 0;
  563. }
  564. /* test cases */
  565. static const struct nand_test_case nand_test_cases[] = {
  566. {
  567. .name = "single sector write (no data verification)",
  568. .sectors_cnt = 1,
  569. .prepare = nand_test_prepare_write,
  570. .run = nand_test_single_write,
  571. .cleanup = nand_test_cleanup
  572. },
  573. {
  574. .name = "single sector read (no data verification)",
  575. .sectors_cnt = 1,
  576. .prepare = nand_test_prepare_read,
  577. .run = nand_test_single_read,
  578. .cleanup = nand_test_cleanup
  579. },
  580. {
  581. .name = "single sector write(verify data)",
  582. .sectors_cnt = 1,
  583. .prepare = nand_test_prepare_write,
  584. .run = nand_test_verify_write,
  585. .cleanup = nand_test_cleanup
  586. },
  587. {
  588. .name = "single sector read(verify data)",
  589. .sectors_cnt = 1,
  590. .prepare = nand_test_prepare_read,
  591. .run = nand_test_verify_read,
  592. .cleanup = nand_test_cleanup
  593. },
  594. /* multi read/write*/
  595. {
  596. .name = "multi sector read(2 sectors, verify)",
  597. .sectors_cnt = 2,
  598. .prepare = nand_test_prepare_read,
  599. .run = nand_test_multi_read,
  600. .cleanup = nand_test_cleanup
  601. },
  602. {
  603. .name = "multi sector read(3 sectors, verify)",
  604. .sectors_cnt = 3,
  605. .prepare = nand_test_prepare_read,
  606. .run = nand_test_multi_read,
  607. .cleanup = nand_test_cleanup
  608. },
  609. {
  610. .name = "multi sector read(8 sectors, verify)",
  611. .sectors_cnt = 8,
  612. .prepare = nand_test_prepare_read,
  613. .run = nand_test_multi_read,
  614. .cleanup = nand_test_cleanup
  615. },
  616. {
  617. .name = "multi sector read(18 sectors, verify)",
  618. .sectors_cnt = 18,
  619. .prepare = nand_test_prepare_read,
  620. .run = nand_test_multi_read,
  621. .cleanup = nand_test_cleanup
  622. },
  623. {
  624. .name = "multi sector read(53 sectors, verify)",
  625. .sectors_cnt = 53,
  626. .prepare = nand_test_prepare_read,
  627. .run = nand_test_multi_read,
  628. .cleanup = nand_test_cleanup
  629. },
  630. {
  631. .name = "multi sector write(2 sectors ,verify)",
  632. .sectors_cnt = 2,
  633. .prepare = nand_test_prepare_write,
  634. .run = nand_test_multi_write,
  635. .cleanup = nand_test_cleanup
  636. },
  637. {
  638. .name = "multi sector write(5 sectors ,verify)",
  639. .sectors_cnt = 5,
  640. .prepare = nand_test_prepare_write,
  641. .run = nand_test_multi_write,
  642. .cleanup = nand_test_cleanup,
  643. },
  644. {
  645. .name = "multi sector write(12 sectors ,verify)",
  646. .sectors_cnt = 12,
  647. .prepare = nand_test_prepare_write,
  648. .run = nand_test_multi_write,
  649. .cleanup = nand_test_cleanup,
  650. },
  651. {
  652. .name = "multi sector write(15 sectors ,verify)",
  653. .sectors_cnt = 15,
  654. .prepare = nand_test_prepare_write,
  655. .run = nand_test_multi_write,
  656. .cleanup = nand_test_cleanup,
  657. },
  658. {
  659. .name = "multi sector write(26 sectors ,verify)",
  660. .sectors_cnt = 26,
  661. .prepare = nand_test_prepare_write,
  662. .run = nand_test_multi_write,
  663. .cleanup = nand_test_cleanup,
  664. },
  665. {
  666. .name = "multi sector write(93 sectors ,verify)",
  667. .sectors_cnt = 93,
  668. .prepare = nand_test_prepare_write,
  669. .run = nand_test_multi_write,
  670. .cleanup = nand_test_cleanup,
  671. },
  672. /*align test*/
  673. {
  674. .name = "align write(1 sector ,verify)",
  675. .sectors_cnt = 1,
  676. .prepare = nand_test_prepare_write,
  677. .run = nand_test_align_write,
  678. .cleanup = nand_test_cleanup,
  679. },
  680. {
  681. .name = "align read(1 sector ,verify)",
  682. .sectors_cnt = 1,
  683. .prepare = nand_test_prepare_read,
  684. .run = nand_test_align_read,
  685. .cleanup = nand_test_cleanup,
  686. },
  687. /* stability test */
  688. {
  689. .name = "weird write(negative start)", // 18
  690. .sectors_cnt = 10,
  691. .prepare = nand_test_prepare_write,
  692. .run = nand_test_negstart_write,
  693. .cleanup = nand_test_cleanup,
  694. },
  695. {
  696. .name = "weid read(nagative satrt)",
  697. .sectors_cnt = 10,
  698. .prepare = nand_test_prepare_read,
  699. .run = nand_test_negstart_read,
  700. .cleanup = nand_test_cleanup,
  701. },
  702. {
  703. .name = "weird write(beyond start)", // 20
  704. .sectors_cnt = 10,
  705. .prepare = nand_test_prepare_write,
  706. .run = nand_test_beyond_write,
  707. .cleanup = nand_test_cleanup,
  708. },
  709. {
  710. .name = "weid read(bayond start)",
  711. .sectors_cnt = 10,
  712. .prepare = nand_test_prepare_read,
  713. .run = nand_test_beyond_read,
  714. .cleanup = nand_test_cleanup,
  715. },
  716. { // 22
  717. .name = "write all ascending",
  718. .sectors_cnt = 1,
  719. .prepare = nand_test_prepare_write,
  720. .run = nand_test_write_all_ascending,
  721. .cleanup = nand_test_cleanup,
  722. },
  723. {
  724. .name = "read all ascending",
  725. .sectors_cnt = 1,
  726. .prepare = nand_test_prepare_read,
  727. .run = nand_test_read_all_ascending,
  728. .cleanup = nand_test_cleanup,
  729. },
  730. {
  731. .name = "write all descending",
  732. .sectors_cnt = 1,
  733. .prepare = nand_test_prepare_write,
  734. .run = nand_test_write_all_descending,
  735. .cleanup = nand_test_cleanup,
  736. },
  737. {
  738. .name = "read all descending",
  739. .sectors_cnt = 1,
  740. .prepare = nand_test_prepare_read,
  741. .run = nand_test_read_all_descending,
  742. .cleanup = nand_test_cleanup,
  743. },
  744. { // 26
  745. .name = " repeat write (no data verification) ",
  746. .sectors_cnt = 1,
  747. .prepare = nand_test_prepare_write,
  748. .run = nand_test_repeat_single_write,
  749. .cleanup = nand_test_cleanup,
  750. },
  751. { // 27
  752. .name = " repeat read (no data verification) ",
  753. .sectors_cnt = 1,
  754. .prepare = nand_test_prepare_read,
  755. .run = nand_test_repeat_single_read,
  756. .cleanup = nand_test_cleanup,
  757. },
  758. { // 28
  759. .name = " repeat multi write (no data verification)",
  760. .sectors_cnt = 43,
  761. .prepare = nand_test_prepare_write,
  762. .run = nand_test_repeat_multi_write,
  763. .cleanup = nand_test_cleanup,
  764. },
  765. { // 29
  766. .name = " repeat multi read (no data verification)",
  767. .sectors_cnt = 81,
  768. .prepare = nand_test_prepare_read,
  769. .run = nand_test_repeat_multi_read,
  770. .cleanup = nand_test_cleanup,
  771. },
  772. { // 30
  773. .name = " random write (no data verification)",
  774. .sectors_cnt = 1,
  775. .prepare = nand_test_prepare_write,
  776. .run = nand_test_random_write,
  777. .cleanup = nand_test_cleanup,
  778. },
  779. { // 31
  780. .name = " random read (no data verification)",
  781. .sectors_cnt = 1,
  782. .prepare = nand_test_prepare_read,
  783. .run = nand_test_random_read,
  784. .cleanup = nand_test_cleanup,
  785. },
  786. { // 32
  787. .name = " pwm test (no data verification)",
  788. .sectors_cnt = 1,
  789. .prepare = nand_test_prepare_pwm,
  790. //.run = nand_test_pwm,
  791. .cleanup = nand_test_cleanup,
  792. },
  793. };
  794. static DEFINE_MUTEX(nand_test_lock);
  795. /* run test cases*/
  796. static void nand_test_run(struct nand_test_card *test, int testcase)
  797. {
  798. int i, ret;
  799. printk(KERN_INFO "[nand_test]: Starting tests of nand\n");
  800. for (i = 0;i < ARRAY_SIZE(nand_test_cases);i++) {
  801. if (testcase && ((i + 1) != testcase)){
  802. continue;
  803. }
  804. printk(KERN_INFO "[nand_test]: Test case %d. %s...\n", i + 1, nand_test_cases[i].name);
  805. if (nand_test_cases[i].prepare) {
  806. ret = nand_test_cases[i].prepare(test, nand_test_cases[i].sectors_cnt);
  807. if (ret) {
  808. printk(KERN_INFO "[nand_test]: Result: Prepare stage failed! (%d)\n", ret);
  809. continue;
  810. }
  811. }
  812. ret = nand_test_cases[i].run(test);
  813. switch (ret) {
  814. case RESULT_OK:
  815. printk(KERN_INFO "[nand_test]: Result: OK\n");
  816. break;
  817. case RESULT_FAIL:
  818. printk(KERN_INFO "[nand_test]:Result: FAILED\n");
  819. break;
  820. // case RESULT_UNSUP_HOST: //grace del
  821. // printk(KERN_INFO "%s: Result: UNSUPPORTED "
  822. // "(by host)\n",
  823. // mmc_hostname(test->card->host));
  824. // break;
  825. // case RESULT_UNSUP_CARD:
  826. // printk(KERN_INFO "%s: Result: UNSUPPORTED "
  827. // "(by card)\n",
  828. // mmc_hostname(test->card->host));
  829. // break;
  830. default:
  831. printk(KERN_INFO "[nand_test]:Result: ERROR (%d)\n", ret);
  832. }
  833. if (nand_test_cases[i].cleanup) {
  834. ret = nand_test_cases[i].cleanup(test);
  835. if (ret) {
  836. printk(KERN_INFO "[nand_test]:Warning: Cleanup"
  837. "stage failed! (%d)\n", ret);
  838. }
  839. }
  840. }
  841. //mmc_release_host(test->card->host);
  842. printk(KERN_INFO "[nand_test]: Nand tests completed.\n");
  843. }
  844. /* do nothing */
  845. static ssize_t nand_test_show(struct kobject *kobject,struct attribute *attr, char *buf)
  846. {
  847. return 0;
  848. }
  849. /* receive testcase num from echo command */
  850. static ssize_t nand_test_store(struct kobject *kobject,struct attribute *attr, const char *buf, size_t count)
  851. {
  852. struct nand_test_card *test;
  853. int testcase;
  854. testcase = simple_strtol(buf, NULL, 10); // get test case number >> grace
  855. test = kzalloc(sizeof(struct nand_test_card), GFP_KERNEL);
  856. if (!test){
  857. return -ENOMEM;
  858. }
  859. test->buffer = kzalloc(BUFFER_SIZE, GFP_KERNEL); // alloc buffer for r/w
  860. test->scratch = kzalloc(BUFFER_SIZE, GFP_KERNEL); // not used now
  861. if (test->buffer && test->scratch) {
  862. mutex_lock(&nand_test_lock);
  863. nand_test_run(test, testcase); // run test cases
  864. mutex_unlock(&nand_test_lock);
  865. }
  866. kfree(test->buffer);
  867. kfree(test->scratch);
  868. kfree(test);
  869. return count;
  870. }
  871. struct kobject kobj;
  872. /* if nand driver is not inited , functions below will be used */
  873. #ifdef INIT_NAND_IN_TESTDRIVER
  874. static void set_nand_pio(void)
  875. {
  876. __u32 cfg0;
  877. __u32 cfg1;
  878. __u32 cfg2;
  879. void* gpio_base;
  880. //modify for f20
  881. gpio_base = (void *)SW_VA_PORTC_IO_BASE;
  882. cfg0 = *(volatile __u32 *)(gpio_base + 0x48);
  883. cfg1 = *(volatile __u32 *)(gpio_base + 0x4c);
  884. cfg2 = *(volatile __u32 *)(gpio_base + 0x50);
  885. /*set PIOC for nand*/
  886. cfg0 &= 0x0;
  887. cfg0 |= 0x22222222;
  888. cfg1 &= 0x0;
  889. cfg1 |= 0x22222222;
  890. cfg2 &= 0x0;
  891. cfg2 |= 0x22222222;
  892. *(volatile __u32 *)(gpio_base + 0x48) = cfg0;
  893. *(volatile __u32 *)(gpio_base + 0x4c) = cfg1;
  894. *(volatile __u32 *)(gpio_base + 0x50) = cfg2;
  895. //iounmap(gpio_base);
  896. }
  897. static __u32 get_cmu_clk(void)
  898. {
  899. __u32 cmu_clk;
  900. __u32 cfg;
  901. __u32 ccmu_base;
  902. ccmu_base = 0xf1c20000;
  903. /*get cmu clock*/
  904. cfg = *(volatile __u32 *)(ccmu_base + 0x0);
  905. if (cfg & (0x1 << 26)){
  906. /*bypass enable*/
  907. cmu_clk = 24/((cfg >> 16) & 0x7f);
  908. }
  909. else{
  910. cmu_clk = 24 + 6 * (((cfg >> 16) & 0x7f) + 1);
  911. }
  912. return cmu_clk;
  913. }
  914. static void set_nand_clock(__u32 nand_max_clock,__u32 cmu_clk)
  915. {
  916. __u32 edo_clk;
  917. __u32 cfg;
  918. __u32 nand_clk_divid_ratio;
  919. __u32 ccmu_base;
  920. ccmu_base = 0xf1c20000;
  921. /*open ahb nand clk */
  922. cfg = *(volatile __u32 *)(ccmu_base + 0x0C);
  923. cfg |= (0x1<<12);
  924. *(volatile __u32 *)(ccmu_base + 0x0C) = cfg;
  925. /*set nand clock*/
  926. edo_clk = nand_max_clock * 2;
  927. nand_clk_divid_ratio = cmu_clk / edo_clk;
  928. if (cmu_clk % edo_clk)
  929. nand_clk_divid_ratio++;
  930. if (nand_clk_divid_ratio){
  931. if (nand_clk_divid_ratio > 16){
  932. nand_clk_divid_ratio = 15;
  933. }
  934. else{
  935. nand_clk_divid_ratio--;
  936. }
  937. }
  938. /*set nand clock gate on*/
  939. cfg = *(volatile __u32 *)(ccmu_base + 0x14);
  940. /*gate on nand clock*/
  941. cfg |= (1 << 15);
  942. /*take cmu pll as nand src block*/
  943. cfg &= (~(0x3<<12));
  944. cfg |= (0x3 << 12);
  945. /*set ratio*/
  946. cfg &= ((~(0xf << 8))&0xffffffff);
  947. cfg |= (nand_clk_divid_ratio & 0xf) << 8;
  948. *(volatile __u32 *)(ccmu_base + 0x14) = cfg;
  949. }
  950. #endif
  951. static int __init nand_test_init(void)
  952. {
  953. int ret;
  954. #ifdef INIT_NAND_IN_TESTDRIVER
  955. __u32 cmu_clk;
  956. #endif
  957. printk("[nand_test]:nand_test_init test init.\n");
  958. if((ret = kobject_init_and_add(&kobj,&ktype,NULL,"nand")) != 0 ) {
  959. return ret;
  960. }
  961. #ifdef INIT_NAND_IN_TESTDRIVER
  962. /* init nand resource */
  963. printk("[nand_test]:init nand resource \n");
  964. //set nand clk
  965. cmu_clk = get_cmu_clk();
  966. set_nand_clock(20, cmu_clk);
  967. //set nand pio
  968. set_nand_pio();
  969. clear_NAND_ZI();
  970. printk("/*********************************************************/ \n");
  971. printk("[nand_test]: init nand block layer start \n");
  972. printk("/*********************************************************/ \n");
  973. ret = PHY_Init();
  974. if (ret) {
  975. PHY_Exit();
  976. return -1;
  977. }
  978. ret = SCN_AnalyzeNandSystem();
  979. if (ret < 0){
  980. return ret;
  981. }
  982. ret = PHY_ChangeMode(1);
  983. if (ret < 0){
  984. return ret;
  985. }
  986. ret = FMT_Init();
  987. if (ret < 0){
  988. return ret;
  989. }
  990. ret = FMT_FormatNand();
  991. if (ret < 0){
  992. return ret;
  993. }
  994. FMT_Exit();
  995. /*init logic layer*/
  996. ret = LML_Init();
  997. if (ret < 0){
  998. return ret;
  999. }
  1000. #ifdef NAND_CACHE_RW
  1001. NAND_CacheOpen();
  1002. #endif
  1003. #endif
  1004. return 0; // init success
  1005. }
  1006. static void __exit nand_test_exit(void)
  1007. {
  1008. printk("[nand_test]:nand test exit.\n");
  1009. kobject_del(&kobj);
  1010. #ifdef INIT_NAND_IN_TESTDRIVER
  1011. LML_FlushPageCache();
  1012. BMM_WriteBackAllMapTbl();
  1013. LML_Exit();
  1014. FMT_Exit();
  1015. PHY_Exit();
  1016. #ifdef NAND_CACHE_RW
  1017. NAND_CacheOpen();
  1018. #endif
  1019. #endif
  1020. return;
  1021. }
  1022. module_init(nand_test_init);
  1023. module_exit(nand_test_exit);
  1024. MODULE_LICENSE("GPL");
  1025. MODULE_DESCRIPTION("Nand test driver");
  1026. MODULE_AUTHOR("Grace Miao");
  1027. #endif