/drivers/block/sun3i_nand/src/physic/nand_simple_r.c

https://bitbucket.org/ndreys/linux-sunxi · C · 695 lines · 432 code · 117 blank · 146 comment · 84 complexity · 6a80b1bfad05ca458a59a1f196e6f46e MD5 · raw file

  1. /*
  2. * drivers/block/sun3i_nand/src/physic/nand_simple_r.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 "../include/nand_type.h"
  23. #include "../include/nand_physic.h"
  24. #include "../include/nand_simple.h"
  25. #include "../../nfc/nfc.h"
  26. #include <linux/io.h>
  27. struct __NandStorageInfo_t NandStorageInfo;
  28. struct __NandPageCachePool_t PageCachePool;
  29. void __iomem *nand_base;
  30. /**************************************************************************
  31. ************************* add one cmd to cmd list******************************
  32. ****************************************************************************/
  33. void _add_cmd_list(NFC_CMD_LIST *cmd,__u32 value,__u32 addr_cycle,__u8 *addr,__u8 data_fetch_flag,
  34. __u8 main_data_fetch,__u32 bytecnt,__u8 wait_rb_flag)
  35. {
  36. cmd->addr = addr;
  37. cmd->addr_cycle = addr_cycle;
  38. cmd->data_fetch_flag = data_fetch_flag;
  39. cmd->main_data_fetch = main_data_fetch;
  40. cmd->bytecnt = bytecnt;
  41. cmd->value = value;
  42. cmd->wait_rb_flag = wait_rb_flag;
  43. cmd->next = NULL;
  44. }
  45. /****************************************************************************
  46. *********************translate (block + page+ sector) into 5 bytes addr***************
  47. *****************************************************************************/
  48. void _cal_addr_in_chip(__u32 block, __u32 page, __u32 sector,__u8 *addr, __u8 cycle)
  49. {
  50. __u32 row;
  51. __u32 column;
  52. column = 512 * sector;
  53. row = block * PAGE_CNT_OF_PHY_BLK + page;
  54. switch(cycle){
  55. case 1:
  56. addr[0] = 0x00;
  57. break;
  58. case 2:
  59. addr[0] = column & 0xff;
  60. addr[1] = (column >> 8) & 0xff;
  61. break;
  62. case 3:
  63. addr[0] = row & 0xff;
  64. addr[1] = (row >> 8) & 0xff;
  65. addr[2] = (row >> 16) & 0xff;
  66. break;
  67. case 4:
  68. addr[0] = column && 0xff;
  69. addr[1] = (column >> 8) & 0xff;
  70. addr[2] = row & 0xff;
  71. addr[3] = (row >> 8) & 0xff;
  72. break;
  73. case 5:
  74. addr[0] = column & 0xff;
  75. addr[1] = (column >> 8) & 0xff;
  76. addr[2] = row & 0xff;
  77. addr[3] = (row >> 8) & 0xff;
  78. addr[4] = (row >> 16) & 0xff;
  79. break;
  80. default:
  81. break;
  82. }
  83. }
  84. #if 0
  85. __u8 _cal_real_chip(__u32 global_bank)
  86. {
  87. __u8 chip;
  88. __u8 i,cnt;
  89. cnt = 0;
  90. chip = global_bank / BNK_CNT_OF_CHIP;
  91. for (i = 0; i <MAX_CHIP_SELECT_CNT; i++ ){
  92. if (CHIP_CONNECT_INFO & (1 << i)) {
  93. cnt++;
  94. if (cnt == (chip+1)){
  95. chip = i;
  96. return chip;
  97. }
  98. }
  99. }
  100. PHY_ERR("wrong chip number ,chip = %d, chip info = %x\n",chip,CHIP_CONNECT_INFO);
  101. return 0xff;
  102. }
  103. #endif
  104. __u8 _cal_real_chip(__u32 global_bank)
  105. {
  106. __u8 chip = 0;
  107. if((RB_CONNECT_MODE == 0)&&(global_bank<=2))
  108. {
  109. if(global_bank)
  110. chip = 7;
  111. else
  112. chip = 0;
  113. return chip;
  114. }
  115. if((RB_CONNECT_MODE == 1)&&(global_bank<=1))
  116. {
  117. chip = global_bank;
  118. return chip;
  119. }
  120. if((RB_CONNECT_MODE == 2)&&(global_bank<=2))
  121. {
  122. chip = global_bank;
  123. return chip;
  124. }
  125. if((RB_CONNECT_MODE == 3)&&(global_bank<=2))
  126. {
  127. chip = global_bank*2;
  128. return chip;
  129. }
  130. if((RB_CONNECT_MODE == 4)&&(global_bank<=4))
  131. {
  132. switch(global_bank){
  133. case 0:
  134. chip = 0;
  135. break;
  136. case 1:
  137. chip = 2;
  138. break;
  139. case 2:
  140. chip = 1;
  141. break;
  142. case 3:
  143. chip = 3;
  144. break;
  145. default :
  146. chip =0;
  147. }
  148. return chip;
  149. }
  150. if((RB_CONNECT_MODE == 5)&&(global_bank<=4))
  151. {
  152. chip = global_bank*2;
  153. return chip;
  154. }
  155. if((RB_CONNECT_MODE == 8)&&(global_bank<=8))
  156. {
  157. switch(global_bank){
  158. case 0:
  159. chip = 0;
  160. break;
  161. case 1:
  162. chip = 2;
  163. break;
  164. case 2:
  165. chip = 1;
  166. break;
  167. case 3:
  168. chip = 3;
  169. break;
  170. case 4:
  171. chip = 4;
  172. break;
  173. case 5:
  174. chip = 6;
  175. break;
  176. case 6:
  177. chip = 5;
  178. break;
  179. case 7:
  180. chip = 7;
  181. break;
  182. default : chip =0;
  183. }
  184. return chip;
  185. }
  186. //dump_stack();
  187. PHY_ERR("wrong chip number ,rb_mode = %d, bank = %d, chip = %d, chip info = %x\n",RB_CONNECT_MODE, global_bank, chip, CHIP_CONNECT_INFO);
  188. return 0xff;
  189. }
  190. __u8 _cal_real_rb(__u32 chip)
  191. {
  192. __u8 rb;
  193. rb = 0;
  194. if(RB_CONNECT_MODE == 0)
  195. {
  196. rb = 0;
  197. }
  198. if(RB_CONNECT_MODE == 1)
  199. {
  200. rb = chip;
  201. }
  202. if(RB_CONNECT_MODE == 2)
  203. {
  204. rb = chip;
  205. }
  206. if(RB_CONNECT_MODE == 3)
  207. {
  208. rb = chip/2;
  209. }
  210. if(RB_CONNECT_MODE == 4)
  211. {
  212. rb = chip/2;
  213. }
  214. if(RB_CONNECT_MODE == 5)
  215. {
  216. rb = (chip/2)%2;
  217. }
  218. if(RB_CONNECT_MODE == 8)
  219. {
  220. rb = (chip/2)%2;
  221. }
  222. if((rb!=0)&&(rb!=1))
  223. {
  224. PHY_ERR("wrong Rb connect Mode ,chip = %d, RbConnectMode = %d \n",chip,RB_CONNECT_MODE);
  225. return 0xff;
  226. }
  227. return rb;
  228. }
  229. /*******************************************************************
  230. **********************get status**************************************
  231. ********************************************************************/
  232. __s32 _read_status(__u32 cmd_value, __u32 nBank)
  233. {
  234. /*get status*/
  235. __u8 addr[5];
  236. __u32 addr_cycle;
  237. NFC_CMD_LIST cmd_list;
  238. addr_cycle = 0;
  239. if(!(cmd_value == 0x70 || cmd_value == 0x71))
  240. {
  241. /* not 0x70 or 0x71, need send some address cycle */
  242. if(cmd_value == 0x78)
  243. addr_cycle = 3;
  244. else
  245. addr_cycle = 1;
  246. _cal_addr_in_chip(nBank*BLOCK_CNT_OF_DIE,0,0,addr,addr_cycle);
  247. }
  248. _add_cmd_list(&cmd_list, cmd_value, addr_cycle, addr, 1,NFC_IGNORE,1,NFC_IGNORE);
  249. return (NFC_GetStatus(&cmd_list));
  250. }
  251. /********************************************************************
  252. ***************************wait rb ready*******************************
  253. *********************************************************************/
  254. __s32 _wait_rb_ready(__u32 chip)
  255. {
  256. __s32 timeout = 0xffff;
  257. __u32 rb;
  258. rb = _cal_real_rb(chip);
  259. /*wait rb ready*/
  260. while((timeout--) && (NFC_CheckRbReady(rb)));
  261. if (timeout < 0)
  262. return -ERR_TIMEOUT;
  263. return 0;
  264. }
  265. void _pending_dma_irq_sem(void)
  266. {
  267. return;
  268. }
  269. __s32 _read_single_page(struct boot_physical_param *readop,__u8 dma_wait_mode)
  270. {
  271. __s32 ret;
  272. __u32 rb;
  273. //__u8 *sparebuf;
  274. __u8 sparebuf[4*16];
  275. __u8 addr[5];
  276. NFC_CMD_LIST cmd_list[4];
  277. __u32 list_len,i;
  278. //sparebuf = (__u8 *)MALLOC(SECTOR_CNT_OF_SINGLE_PAGE * 4);
  279. /*create cmd list*/
  280. /*samll block*/
  281. if (SECTOR_CNT_OF_SINGLE_PAGE == 1){
  282. _cal_addr_in_chip(readop->block,readop->page,0,addr,4);
  283. _add_cmd_list(cmd_list,0x00,4,addr,NFC_DATA_FETCH,NFC_IGNORE,NFC_IGNORE,NFC_WAIT_RB);
  284. }
  285. /*large block*/
  286. else{
  287. /*the cammand have no corresponding feature if IGNORE was set, */
  288. _cal_addr_in_chip(readop->block,readop->page,0,addr,5);
  289. _add_cmd_list(cmd_list,0x00,5,addr,NFC_NO_DATA_FETCH,NFC_IGNORE,NFC_IGNORE,NFC_NO_WAIT_RB);
  290. }
  291. _add_cmd_list(cmd_list + 1,0x05,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE);
  292. _add_cmd_list(cmd_list + 2,0xe0,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE);
  293. _add_cmd_list(cmd_list + 3,0x30,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE,NFC_IGNORE);
  294. list_len = 4;
  295. for(i = 0; i < list_len - 1; i++){
  296. cmd_list[i].next = &(cmd_list[i+1]);
  297. }
  298. /*wait rb ready*/
  299. ret = _wait_rb_ready(readop->chip);
  300. if (ret)
  301. return ret;
  302. rb = _cal_real_rb(readop->chip);
  303. NFC_SelectChip(readop->chip);
  304. NFC_SelectRb(rb);
  305. ret = NFC_Read(cmd_list, readop->mainbuf, sparebuf, dma_wait_mode , NFC_PAGE_MODE);
  306. if (dma_wait_mode)
  307. _pending_dma_irq_sem();
  308. if (readop->oobbuf){
  309. MEMCPY(readop->oobbuf,sparebuf, 2 * 4);
  310. }
  311. NFC_DeSelectChip(readop->chip);
  312. NFC_DeSelectRb(rb);
  313. //FREE(sparebuf);
  314. return ret;
  315. }
  316. /*
  317. ************************************************************************************************************************
  318. * INIT NAND FLASH DRIVER PHYSICAL MODULE
  319. *
  320. * Description: init nand flash driver physical module.
  321. *
  322. * Aguments : none
  323. *
  324. * Returns : the resutl of initial.
  325. * = 0 initial successful;
  326. * = -1 initial failed.
  327. ************************************************************************************************************************
  328. */
  329. __s32 PHY_Init(void)
  330. {
  331. NFC_INIT_INFO nand_info;
  332. nand_info.bus_width = 0x0;
  333. nand_info.ce_ctl = 0x0;
  334. nand_info.ce_ctl1 = 0x0;
  335. nand_info.debug = 0x0;
  336. nand_info.pagesize = 4;
  337. nand_info.rb_sel = 1;
  338. nand_info.serial_access_mode = 1;
  339. //nand_base = ioremap(0x01C03000, 4096 );
  340. //modify by penggang for f20 linux
  341. // if (nand_base == NULL) {
  342. // printk(KERN_ERR "dma failed to remap register block\n");
  343. // return -ENOMEM;
  344. // }
  345. return (NFC_Init(&nand_info));
  346. }
  347. __s32 PHY_ChangeMode(__u8 serial_mode)
  348. {
  349. NFC_INIT_INFO nand_info;
  350. /*memory allocate*/
  351. if (!PageCachePool.PageCache0){
  352. PageCachePool.PageCache0 = (__u8 *)MALLOC(SECTOR_CNT_OF_SUPER_PAGE * 512);
  353. if (!PageCachePool.PageCache0)
  354. return -1;
  355. }
  356. if (!PageCachePool.SpareCache){
  357. PageCachePool.SpareCache = (__u8 *)MALLOC(SECTOR_CNT_OF_SUPER_PAGE * 4);
  358. if (!PageCachePool.SpareCache)
  359. return -1;
  360. }
  361. if (!PageCachePool.TmpPageCache){
  362. PageCachePool.TmpPageCache = (__u8 *)MALLOC(SECTOR_CNT_OF_SUPER_PAGE * 512);
  363. if (!PageCachePool.TmpPageCache)
  364. return -1;
  365. }
  366. NFC_SetEccMode(ECC_MODE);
  367. nand_info.bus_width = 0x0;
  368. nand_info.ce_ctl = 0x0;
  369. nand_info.ce_ctl1 = 0x0;
  370. nand_info.debug = 0x0;
  371. nand_info.pagesize = SECTOR_CNT_OF_SINGLE_PAGE;
  372. nand_info.serial_access_mode = serial_mode;
  373. return (NFC_ChangMode(&nand_info));
  374. }
  375. /*
  376. ************************************************************************************************************************
  377. * NAND FLASH DRIVER PHYSICAL MODULE EXIT
  378. *
  379. * Description: nand flash driver physical module exit.
  380. *
  381. * Aguments : none
  382. *
  383. * Returns : the resutl of exit.
  384. * = 0 exit successful;
  385. * = -1 exit failed.
  386. ************************************************************************************************************************
  387. */
  388. __s32 PHY_Exit(void)
  389. {
  390. if (PageCachePool.PageCache0){
  391. FREE(PageCachePool.PageCache0,SECTOR_CNT_OF_SUPER_PAGE * 512);
  392. PageCachePool.PageCache0 = NULL;
  393. }
  394. if (PageCachePool.SpareCache){
  395. FREE(PageCachePool.SpareCache,SECTOR_CNT_OF_SUPER_PAGE * 4);
  396. PageCachePool.SpareCache = NULL;
  397. }
  398. if (PageCachePool.TmpPageCache){
  399. FREE(PageCachePool.TmpPageCache,SECTOR_CNT_OF_SUPER_PAGE * 512);
  400. PageCachePool.TmpPageCache = NULL;
  401. }
  402. NFC_Exit();
  403. return 0;
  404. }
  405. /*
  406. ************************************************************************************************************************
  407. * RESET ONE NAND FLASH CHIP
  408. *
  409. *Description: Reset the given nand chip;
  410. *
  411. *Arguments : nChip the chip select number, which need be reset.
  412. *
  413. *Return : the result of chip reset;
  414. * = 0 reset nand chip successful;
  415. * = -1 reset nand chip failed.
  416. ************************************************************************************************************************
  417. */
  418. __s32 PHY_ResetChip(__u32 nChip)
  419. {
  420. __s32 ret;
  421. __s32 timeout = 0xffff;
  422. NFC_CMD_LIST cmd;
  423. NFC_SelectChip(nChip);
  424. _add_cmd_list(&cmd, 0xff, 0 , NFC_IGNORE, NFC_NO_DATA_FETCH, NFC_IGNORE, NFC_IGNORE, NFC_NO_WAIT_RB);
  425. ret = NFC_ResetChip(&cmd);
  426. /*wait rb0 ready*/
  427. NFC_SelectRb(0);
  428. while((timeout--) && (NFC_CheckRbReady(0)));
  429. if (timeout < 0)
  430. return -ERR_TIMEOUT;
  431. /*wait rb0 ready*/
  432. NFC_SelectRb(1);
  433. while((timeout--) && (NFC_CheckRbReady(1)));
  434. if (timeout < 0)
  435. return -ERR_TIMEOUT;
  436. NFC_DeSelectChip(nChip);
  437. return ret;
  438. }
  439. /*
  440. ************************************************************************************************************************
  441. * READ NAND FLASH ID
  442. *
  443. *Description: Read nand flash ID from the given nand chip.
  444. *
  445. *Arguments : nChip the chip number whoes ID need be read;
  446. * pChipID the po__s32er to the chip ID buffer.
  447. *
  448. *Return : read nand chip ID result;
  449. * = 0 read chip ID successful, the chip ID has been stored in given buffer;
  450. * = -1 read chip ID failed.
  451. ************************************************************************************************************************
  452. */
  453. __s32 PHY_ReadNandId(__s32 nChip, void *pChipID)
  454. {
  455. __s32 ret;
  456. NFC_CMD_LIST cmd;
  457. __u8 addr = 0;
  458. NFC_SelectChip(nChip);
  459. _add_cmd_list(&cmd, 0x90,1 , &addr, NFC_DATA_FETCH, NFC_IGNORE, 5, NFC_NO_WAIT_RB);
  460. ret = NFC_GetId(&cmd, pChipID);
  461. NFC_DeSelectChip(nChip);
  462. return ret;
  463. }
  464. /*
  465. ************************************************************************************************************************
  466. * CHECK WRITE PROTECT STATUS
  467. *
  468. *Description: check the status of write protect.
  469. *
  470. *Arguments : nChip the number of chip, which nand chip need be checked.
  471. *
  472. *Return : the result of status check;
  473. * = 0 the nand flash is not write proteced;
  474. * = 1 the nand flash is write proteced;
  475. * = -1 check status failed.
  476. ************************************************************************************************************************
  477. */
  478. __s32 PHY_CheckWp(__u32 nChip)
  479. {
  480. __s32 status;
  481. __u32 rb;
  482. rb = _cal_real_rb(nChip);
  483. NFC_SelectChip(nChip);
  484. NFC_SelectRb(rb);
  485. status = _read_status(0x70,nChip);
  486. NFC_DeSelectChip(nChip);
  487. NFC_DeSelectRb(rb);
  488. if (status < 0)
  489. return status;
  490. if (status & NAND_WRITE_PROTECT){
  491. return 1;
  492. }
  493. else
  494. return 0;
  495. }
  496. void _pending_rb_irq_sem(void)
  497. {
  498. return;
  499. }
  500. void _do_irq(void)
  501. {
  502. }
  503. __s32 PHY_SimpleRead (struct boot_physical_param *readop)
  504. {
  505. //if (_read_single_page(readop,0) < 0)
  506. // return FAIL;
  507. //return SUCESS;
  508. return (_read_single_page(readop,0));
  509. }
  510. /*
  511. ************************************************************************************************************************
  512. * SYNC NAND FLASH PHYSIC OPERATION
  513. *
  514. *Description: Sync nand flash operation, check nand flash program/erase operation status.
  515. *
  516. *Arguments : nBank the number of the bank which need be synchronized;
  517. * bMode the type of synch,
  518. * = 0 sync the chip which the bank belonged to, wait the whole chip
  519. * to be ready, and report status. if the chip support cacheprogram,
  520. * need check if the chip is true ready;
  521. * = 1 only sync the the bank, wait the bank ready and report the status,
  522. * if the chip support cache program, need not check if the cache is
  523. * true ready.
  524. *
  525. *Return : the result of synch;
  526. * = 0 synch nand flash successful, nand operation ok;
  527. * = -1 synch nand flash failed.
  528. ************************************************************************************************************************
  529. */
  530. __s32 PHY_SynchBank(__u32 nBank, __u32 bMode)
  531. {
  532. __s32 ret,status;
  533. __u32 chip;
  534. __u32 rb;
  535. __u32 cmd_value;
  536. __s32 timeout = 0xffff;
  537. ret = 0;
  538. /*get chip no*/
  539. chip = _cal_real_chip(nBank);
  540. rb = _cal_real_rb(chip);
  541. if (0xff == chip){
  542. PHY_ERR("PHY_SynchBank : beyond chip count\n");
  543. return -ERR_INVALIDPHYADDR;
  544. }
  545. if ( (bMode == 1) && SUPPORT_INT_INTERLEAVE){
  546. if (nBank%BNK_CNT_OF_CHIP == 0)
  547. cmd_value = NandStorageInfo.OptPhyOpPar.InterBnk0StatusCmd;
  548. else
  549. cmd_value = NandStorageInfo.OptPhyOpPar.InterBnk1StatusCmd;
  550. }
  551. else{
  552. if (SUPPORT_MULTI_PROGRAM)
  553. cmd_value = NandStorageInfo.OptPhyOpPar.MultiPlaneStatusCmd;
  554. else
  555. cmd_value = 0x70;
  556. }
  557. /*if support rb irq , last op is erase or write*/
  558. if (SUPPORT_RB_IRQ)
  559. _pending_rb_irq_sem();
  560. NFC_SelectChip(chip);
  561. NFC_SelectRb(rb);
  562. while(1){
  563. status = _read_status(cmd_value,nBank%BNK_CNT_OF_CHIP);
  564. if (status < 0)
  565. return status;
  566. if (status & NAND_STATUS_READY)
  567. break;
  568. if (timeout-- < 0){
  569. PHY_ERR("PHY_SynchBank : wait nand ready timeout,chip = %x, bank = %x, cmd value = %x, status = %x\n",chip,nBank,cmd_value,status);
  570. return -ERR_TIMEOUT;
  571. }
  572. }
  573. if(status & NAND_OPERATE_FAIL)
  574. ret = NAND_OP_FALSE;
  575. NFC_DeSelectChip(chip);
  576. NFC_DeSelectRb(rb);
  577. return ret;
  578. }