sharpsl.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2004 Richard Purdie
  4. * Copyright (C) 2008 Dmitry Baryshkov
  5. *
  6. * Based on Sharp's NAND driver sharp_sl.c
  7. */
  8. #include <linux/slab.h>
  9. #include <linux/module.h>
  10. #include <linux/delay.h>
  11. #include <linux/mtd/mtd.h>
  12. #include <linux/mtd/rawnand.h>
  13. #include <linux/mtd/partitions.h>
  14. #include <linux/mtd/sharpsl.h>
  15. #include <linux/interrupt.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/io.h>
  18. struct sharpsl_nand {
  19. struct nand_controller controller;
  20. struct nand_chip chip;
  21. void __iomem *io;
  22. };
  23. static inline struct sharpsl_nand *mtd_to_sharpsl(struct mtd_info *mtd)
  24. {
  25. return container_of(mtd_to_nand(mtd), struct sharpsl_nand, chip);
  26. }
  27. /* register offset */
  28. #define ECCLPLB 0x00 /* line parity 7 - 0 bit */
  29. #define ECCLPUB 0x04 /* line parity 15 - 8 bit */
  30. #define ECCCP 0x08 /* column parity 5 - 0 bit */
  31. #define ECCCNTR 0x0C /* ECC byte counter */
  32. #define ECCCLRR 0x10 /* cleare ECC */
  33. #define FLASHIO 0x14 /* Flash I/O */
  34. #define FLASHCTL 0x18 /* Flash Control */
  35. /* Flash control bit */
  36. #define FLRYBY (1 << 5)
  37. #define FLCE1 (1 << 4)
  38. #define FLWP (1 << 3)
  39. #define FLALE (1 << 2)
  40. #define FLCLE (1 << 1)
  41. #define FLCE0 (1 << 0)
  42. /*
  43. * hardware specific access to control-lines
  44. * ctrl:
  45. * NAND_CNE: bit 0 -> ! bit 0 & 4
  46. * NAND_CLE: bit 1 -> bit 1
  47. * NAND_ALE: bit 2 -> bit 2
  48. *
  49. */
  50. static void sharpsl_nand_hwcontrol(struct nand_chip *chip, int cmd,
  51. unsigned int ctrl)
  52. {
  53. struct sharpsl_nand *sharpsl = mtd_to_sharpsl(nand_to_mtd(chip));
  54. if (ctrl & NAND_CTRL_CHANGE) {
  55. unsigned char bits = ctrl & 0x07;
  56. bits |= (ctrl & 0x01) << 4;
  57. bits ^= 0x11;
  58. writeb((readb(sharpsl->io + FLASHCTL) & ~0x17) | bits, sharpsl->io + FLASHCTL);
  59. }
  60. if (cmd != NAND_CMD_NONE)
  61. writeb(cmd, chip->legacy.IO_ADDR_W);
  62. }
  63. static int sharpsl_nand_dev_ready(struct nand_chip *chip)
  64. {
  65. struct sharpsl_nand *sharpsl = mtd_to_sharpsl(nand_to_mtd(chip));
  66. return !((readb(sharpsl->io + FLASHCTL) & FLRYBY) == 0);
  67. }
  68. static void sharpsl_nand_enable_hwecc(struct nand_chip *chip, int mode)
  69. {
  70. struct sharpsl_nand *sharpsl = mtd_to_sharpsl(nand_to_mtd(chip));
  71. writeb(0, sharpsl->io + ECCCLRR);
  72. }
  73. static int sharpsl_nand_calculate_ecc(struct nand_chip *chip,
  74. const u_char * dat, u_char * ecc_code)
  75. {
  76. struct sharpsl_nand *sharpsl = mtd_to_sharpsl(nand_to_mtd(chip));
  77. ecc_code[0] = ~readb(sharpsl->io + ECCLPUB);
  78. ecc_code[1] = ~readb(sharpsl->io + ECCLPLB);
  79. ecc_code[2] = (~readb(sharpsl->io + ECCCP) << 2) | 0x03;
  80. return readb(sharpsl->io + ECCCNTR) != 0;
  81. }
  82. static int sharpsl_attach_chip(struct nand_chip *chip)
  83. {
  84. if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST)
  85. return 0;
  86. chip->ecc.size = 256;
  87. chip->ecc.bytes = 3;
  88. chip->ecc.strength = 1;
  89. chip->ecc.hwctl = sharpsl_nand_enable_hwecc;
  90. chip->ecc.calculate = sharpsl_nand_calculate_ecc;
  91. chip->ecc.correct = rawnand_sw_hamming_correct;
  92. return 0;
  93. }
  94. static const struct nand_controller_ops sharpsl_ops = {
  95. .attach_chip = sharpsl_attach_chip,
  96. };
  97. /*
  98. * Main initialization routine
  99. */
  100. static int sharpsl_nand_probe(struct platform_device *pdev)
  101. {
  102. struct nand_chip *this;
  103. struct mtd_info *mtd;
  104. struct resource *r;
  105. int err = 0;
  106. struct sharpsl_nand *sharpsl;
  107. struct sharpsl_nand_platform_data *data = dev_get_platdata(&pdev->dev);
  108. if (!data) {
  109. dev_err(&pdev->dev, "no platform data!\n");
  110. return -EINVAL;
  111. }
  112. /* Allocate memory for MTD device structure and private data */
  113. sharpsl = kzalloc(sizeof(struct sharpsl_nand), GFP_KERNEL);
  114. if (!sharpsl)
  115. return -ENOMEM;
  116. r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  117. if (!r) {
  118. dev_err(&pdev->dev, "no io memory resource defined!\n");
  119. err = -ENODEV;
  120. goto err_get_res;
  121. }
  122. /* map physical address */
  123. sharpsl->io = ioremap(r->start, resource_size(r));
  124. if (!sharpsl->io) {
  125. dev_err(&pdev->dev, "ioremap to access Sharp SL NAND chip failed\n");
  126. err = -EIO;
  127. goto err_ioremap;
  128. }
  129. /* Get pointer to private data */
  130. this = (struct nand_chip *)(&sharpsl->chip);
  131. nand_controller_init(&sharpsl->controller);
  132. sharpsl->controller.ops = &sharpsl_ops;
  133. this->controller = &sharpsl->controller;
  134. /* Link the private data with the MTD structure */
  135. mtd = nand_to_mtd(this);
  136. mtd->dev.parent = &pdev->dev;
  137. mtd_set_ooblayout(mtd, data->ecc_layout);
  138. platform_set_drvdata(pdev, sharpsl);
  139. /*
  140. * PXA initialize
  141. */
  142. writeb(readb(sharpsl->io + FLASHCTL) | FLWP, sharpsl->io + FLASHCTL);
  143. /* Set address of NAND IO lines */
  144. this->legacy.IO_ADDR_R = sharpsl->io + FLASHIO;
  145. this->legacy.IO_ADDR_W = sharpsl->io + FLASHIO;
  146. /* Set address of hardware control function */
  147. this->legacy.cmd_ctrl = sharpsl_nand_hwcontrol;
  148. this->legacy.dev_ready = sharpsl_nand_dev_ready;
  149. /* 15 us command delay time */
  150. this->legacy.chip_delay = 15;
  151. this->badblock_pattern = data->badblock_pattern;
  152. /* Scan to find existence of the device */
  153. err = nand_scan(this, 1);
  154. if (err)
  155. goto err_scan;
  156. /* Register the partitions */
  157. mtd->name = "sharpsl-nand";
  158. err = mtd_device_parse_register(mtd, data->part_parsers, NULL,
  159. data->partitions, data->nr_partitions);
  160. if (err)
  161. goto err_add;
  162. /* Return happy */
  163. return 0;
  164. err_add:
  165. nand_cleanup(this);
  166. err_scan:
  167. iounmap(sharpsl->io);
  168. err_ioremap:
  169. err_get_res:
  170. kfree(sharpsl);
  171. return err;
  172. }
  173. /*
  174. * Clean up routine
  175. */
  176. static int sharpsl_nand_remove(struct platform_device *pdev)
  177. {
  178. struct sharpsl_nand *sharpsl = platform_get_drvdata(pdev);
  179. struct nand_chip *chip = &sharpsl->chip;
  180. int ret;
  181. /* Unregister device */
  182. ret = mtd_device_unregister(nand_to_mtd(chip));
  183. WARN_ON(ret);
  184. /* Release resources */
  185. nand_cleanup(chip);
  186. iounmap(sharpsl->io);
  187. /* Free the driver's structure */
  188. kfree(sharpsl);
  189. return 0;
  190. }
  191. static struct platform_driver sharpsl_nand_driver = {
  192. .driver = {
  193. .name = "sharpsl-nand",
  194. },
  195. .probe = sharpsl_nand_probe,
  196. .remove = sharpsl_nand_remove,
  197. };
  198. module_platform_driver(sharpsl_nand_driver);
  199. MODULE_LICENSE("GPL");
  200. MODULE_AUTHOR("Richard Purdie <[email protected]>");
  201. MODULE_DESCRIPTION("Device specific logic for NAND flash on Sharp SL-C7xx Series");