v3_nand.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. #include <linux/module.h>
  2. #include <linux/types.h>
  3. #include <linux/init.h>
  4. #include <linux/kernel.h>
  5. #include <linux/string.h>
  6. #include <linux/ioport.h>
  7. #include <linux/platform_device.h>
  8. #include <linux/delay.h>
  9. #include <linux/err.h>
  10. #include <linux/slab.h>
  11. #include <linux/io.h>
  12. #include <linux/bitops.h>
  13. #include <linux/mtd/mtd.h>
  14. #include <linux/mtd/nand.h>
  15. #include <linux/mtd/nand_ecc.h>
  16. #include <linux/mtd/partitions.h>
  17. #include <mach/nand_m3.h>
  18. #define a3_nand_debug(a...) printk(a)
  19. static struct aml_nand_device *to_nand_dev(struct platform_device *pdev)
  20. {
  21. return pdev->dev.platform_data;
  22. }
  23. #if 0 //Fix compile warning Lee.Rong 2011.04.18
  24. static int a3_nand_boot_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int page)
  25. {
  26. struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd);
  27. uint8_t *oob_buf = chip->oob_poi;
  28. unsigned nand_page_size = A3_BOOT_WRITE_SIZE;
  29. unsigned pages_per_blk_shift = (chip->phys_erase_shift - chip->page_shift);
  30. int user_byte_num = (((nand_page_size + chip->ecc.size - 1) / chip->ecc.size) * aml_chip->user_byte_mode);
  31. int error = 0, i = 0, stat = 0;
  32. memset(buf, 0xff, (1 << chip->page_shift));
  33. WARN_ON(!aml_chip->valid_chip[0]);
  34. if (aml_chip->valid_chip[i]) {
  35. if (!aml_chip->aml_nand_wait_devready(aml_chip, i)) {
  36. printk ("read couldn`t found selected chip: %d ready\n", i);
  37. error = -EBUSY;
  38. goto exit;
  39. }
  40. error = aml_chip->aml_nand_dma_read(aml_chip, buf, nand_page_size, aml_chip->bch_mode);
  41. if (error)
  42. goto exit;
  43. aml_chip->aml_nand_get_user_byte(aml_chip, oob_buf, user_byte_num);
  44. stat = aml_chip->aml_nand_hwecc_correct(aml_chip, buf, nand_page_size, oob_buf);
  45. if (stat < 0) {
  46. mtd->ecc_stats.failed++;
  47. printk("aml nand read data ecc failed at blk %d chip %d\n", (page >> pages_per_blk_shift), i);
  48. }
  49. else
  50. mtd->ecc_stats.corrected += stat;
  51. }
  52. else {
  53. error = -ENODEV;
  54. goto exit;
  55. }
  56. exit:
  57. return error;
  58. }
  59. static void a3_nand_boot_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, const uint8_t *buf)
  60. {
  61. struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd);
  62. uint8_t *oob_buf = chip->oob_poi;
  63. unsigned nand_page_size = A3_BOOT_WRITE_SIZE;
  64. int user_byte_num = (((nand_page_size + chip->ecc.size - 1) / chip->ecc.size) * aml_chip->user_byte_mode);
  65. int error = 0, i = 0;
  66. WARN_ON(!aml_chip->valid_chip[0]);
  67. if (aml_chip->valid_chip[i]) {
  68. aml_chip->aml_nand_select_chip(aml_chip, i);
  69. aml_chip->aml_nand_set_user_byte(aml_chip, oob_buf, user_byte_num);
  70. error = aml_chip->aml_nand_dma_write(aml_chip, (unsigned char *)buf, nand_page_size, aml_chip->bch_mode);
  71. if (error)
  72. goto exit;
  73. aml_chip->aml_nand_command(aml_chip, NAND_CMD_PAGEPROG, -1, -1, i);
  74. }
  75. else {
  76. error = -ENODEV;
  77. goto exit;
  78. }
  79. exit:
  80. return;
  81. }
  82. static int a3_nand_boot_write_page(struct mtd_info *mtd, struct nand_chip *chip, const uint8_t *buf, int page, int cached, int raw)
  83. {
  84. int status, i, write_page;
  85. for (i=0; i<A3_BOOT_COPY_NUM; i++) {
  86. write_page = page + i*A3_BOOT_PAGES_PER_COPY;
  87. chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, write_page);
  88. if (unlikely(raw))
  89. chip->ecc.write_page_raw(mtd, chip, buf);
  90. else
  91. chip->ecc.write_page(mtd, chip, buf);
  92. if (!cached || !(chip->options & NAND_CACHEPRG)) {
  93. status = chip->waitfunc(mtd, chip);
  94. if ((status & NAND_STATUS_FAIL) && (chip->errstat))
  95. status = chip->errstat(mtd, chip, FL_WRITING, status, write_page);
  96. if (status & NAND_STATUS_FAIL)
  97. return -EIO;
  98. } else {
  99. status = chip->waitfunc(mtd, chip);
  100. }
  101. }
  102. return 0;
  103. }
  104. #endif
  105. #define ECC_INFORMATION(name_a,bch_a,size_a,parity_a,user_a) { \
  106. .name=name_a,.bch=bch_a,.size=size_a,.parity=parity_a,.user=user_a \
  107. }
  108. static struct ecc_desc_s ecc_list[]={
  109. [0]=ECC_INFORMATION("NAND_RAW_MODE",NAND_ECC_SOFT_MODE,0,0,0),
  110. [1]=ECC_INFORMATION("NAND_BCH8_512_MODE",NAND_ECC_BCH8_512_MODE,NAND_ECC_UNIT_SIZE,NAND_BCH8_512_ECC_SIZE,2),
  111. [2]=ECC_INFORMATION("NAND_BCH8_1K_MODE" ,NAND_ECC_BCH8_1K_MODE,NAND_ECC_UNIT_1KSIZE,NAND_BCH8_1K_ECC_SIZE,2),
  112. [3]=ECC_INFORMATION("NAND_BCH16_MODE" ,NAND_ECC_BCH16_MODE,NAND_ECC_UNIT_1KSIZE,NAND_BCH16_ECC_SIZE,2),
  113. [4]=ECC_INFORMATION("NAND_BCH24_MODE" ,NAND_ECC_BCH24_MODE,NAND_ECC_UNIT_1KSIZE,NAND_BCH24_ECC_SIZE,2),
  114. [5]=ECC_INFORMATION("NAND_BCH30_MODE" ,NAND_ECC_BCH30_MODE,NAND_ECC_UNIT_1KSIZE,NAND_BCH30_ECC_SIZE,2),
  115. [6]=ECC_INFORMATION("NAND_BCH40_MODE" ,NAND_ECC_BCH40_MODE,NAND_ECC_UNIT_1KSIZE,NAND_BCH40_ECC_SIZE,2),
  116. [7]=ECC_INFORMATION("NAND_BCH60_MODE" ,NAND_ECC_BCH60_MODE,NAND_ECC_UNIT_1KSIZE,NAND_BCH60_ECC_SIZE,2),
  117. [8]=ECC_INFORMATION("NAND_SHORT_MODE" ,NAND_ECC_SHORT_MODE,NAND_ECC_UNIT_SHORT,NAND_BCH60_ECC_SIZE,2),
  118. };
  119. static int aml_nand_probe(struct aml_nand_platform *plat, struct device *dev)
  120. {
  121. struct aml_nand_chip *aml_chip = NULL;
  122. struct nand_chip *chip = NULL;
  123. struct mtd_info *mtd = NULL;
  124. int err = 0;
  125. aml_chip = kzalloc(sizeof(*aml_chip), GFP_KERNEL);
  126. if (aml_chip == NULL) {
  127. printk("no memory for flash info\n");
  128. err = -ENOMEM;
  129. goto exit_error;
  130. }
  131. //platform_set_drvdata(pdev, aml_chip);
  132. /* initialize mtd info data struct */
  133. dev->coherent_dma_mask = DMA_BIT_MASK(32);
  134. aml_chip->device = dev;
  135. aml_chip->platform = plat;
  136. plat->aml_chip = aml_chip;
  137. chip = &aml_chip->chip;
  138. chip->priv = &aml_chip->mtd;
  139. mtd = &aml_chip->mtd;
  140. mtd->priv = chip;
  141. mtd->owner = THIS_MODULE;
  142. aml_chip->max_ecc=sizeof(ecc_list)/sizeof(ecc_list[0]);
  143. aml_chip->ecc=ecc_list;
  144. #if 0
  145. a3_nand_debug("A3 NAND Chip ECC ability\n");
  146. for(err=1;err<aml_chip->max_ecc;err++)
  147. {
  148. a3_nand_debug("name=%s,"
  149. }
  150. #endif
  151. err = aml_nand_init(aml_chip);
  152. if (err)
  153. goto exit_error;
  154. if (!strncmp((char*)plat->name, NAND_BOOT_NAME, strlen((const char*)NAND_BOOT_NAME))) {
  155. chip->ecc.read_page = NULL; //a3_nand_boot_read_page_hwecc;
  156. chip->ecc.write_page =NULL; // a3_nand_boot_write_page_hwecc;
  157. chip->write_page =NULL ; //a3_nand_boot_write_page;
  158. }
  159. return 0;
  160. exit_error:
  161. if (aml_chip)
  162. kfree(aml_chip);
  163. return err;
  164. }
  165. static int a3_nand_probe(struct platform_device *pdev)
  166. {
  167. struct aml_nand_device *aml_nand_dev = to_nand_dev(pdev);
  168. struct aml_nand_platform *plat = NULL;
  169. int err = 0, i;
  170. printk(&pdev->dev, "(%p)\n", pdev);
  171. if (!aml_nand_dev) {
  172. printk(&pdev->dev, "no platform specific information\n");
  173. err = -ENOMEM;
  174. goto exit_error;
  175. }
  176. platform_set_drvdata(pdev, aml_nand_dev);
  177. for (i=0; i<aml_nand_dev->dev_num; i++) {
  178. plat = &aml_nand_dev->aml_nand_platform[i];
  179. if (!plat) {
  180. printk("error for not platform data\n");
  181. continue;
  182. }
  183. err = aml_nand_probe(plat, &pdev->dev);
  184. if (err) {
  185. printk("%s dev probe failed %d\n", plat->name, err);
  186. continue;
  187. }
  188. }
  189. exit_error:
  190. return err;
  191. }
  192. static int a3_nand_remove(struct platform_device *pdev)
  193. {
  194. struct aml_nand_device *aml_nand_dev = to_nand_dev(pdev);
  195. struct aml_nand_platform *plat = NULL;
  196. struct aml_nand_chip *aml_chip = NULL;
  197. struct mtd_info *mtd = NULL;
  198. int i;
  199. platform_set_drvdata(pdev, NULL);
  200. for (i=0; i<aml_nand_dev->dev_num; i++) {
  201. aml_chip = plat->aml_chip;
  202. if (aml_chip) {
  203. mtd = &aml_chip->mtd;
  204. if (mtd) {
  205. nand_release(mtd);
  206. kfree(mtd);
  207. }
  208. kfree(aml_chip);
  209. }
  210. }
  211. return 0;
  212. }
  213. #define DRV_NAME "aml_m3_nand"
  214. #define DRV_VERSION "1.0"
  215. #define DRV_AUTHOR "xiaojun_yoyo"
  216. #define DRV_DESC "Amlogic nand flash host controll driver for m3"
  217. /* driver device registration */
  218. static struct platform_driver a3_nand_driver = {
  219. .probe = a3_nand_probe,
  220. .remove = a3_nand_remove,
  221. .driver = {
  222. .name = DRV_NAME,
  223. .owner = THIS_MODULE,
  224. },
  225. };
  226. static int __init a3_nand_init(void)
  227. {
  228. printk(KERN_INFO "%s, Version %s (c) 2010 Amlogic Inc.\n", DRV_DESC, DRV_VERSION);
  229. return platform_driver_register(&a3_nand_driver);
  230. }
  231. static void __exit a3_nand_exit(void)
  232. {
  233. platform_driver_unregister(&a3_nand_driver);
  234. }
  235. module_init(a3_nand_init);
  236. module_exit(a3_nand_exit);
  237. MODULE_LICENSE("GPL");
  238. MODULE_AUTHOR(DRV_AUTHOR);
  239. MODULE_DESCRIPTION(DRV_DESC);
  240. MODULE_ALIAS("platform:" DRV_NAME);