nand.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /*
  2. * (C) Copyright 2008
  3. * Sergei Poselenov, Emcraft Systems, sposelenov@emcraft.com.
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. #include <common.h>
  24. #if defined(CFG_NAND_BASE)
  25. #include <nand.h>
  26. #include <asm/errno.h>
  27. #include <asm/io.h>
  28. static int state;
  29. static void nand_write_byte(struct mtd_info *mtd, u_char byte);
  30. static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len);
  31. static void nand_write_word(struct mtd_info *mtd, u16 word);
  32. static u_char nand_read_byte(struct mtd_info *mtd);
  33. static u16 nand_read_word(struct mtd_info *mtd);
  34. static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len);
  35. static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len);
  36. static int nand_device_ready(struct mtd_info *mtdinfo);
  37. static void nand_hwcontrol(struct mtd_info *mtdinfo, int cmd);
  38. #define FPGA_NAND_CMD_MASK (0x7 << 28)
  39. #define FPGA_NAND_CMD_COMMAND (0x0 << 28)
  40. #define FPGA_NAND_CMD_ADDR (0x1 << 28)
  41. #define FPGA_NAND_CMD_READ (0x2 << 28)
  42. #define FPGA_NAND_CMD_WRITE (0x3 << 28)
  43. #define FPGA_NAND_BUSY (0x1 << 15)
  44. #define FPGA_NAND_ENABLE (0x1 << 31)
  45. #define FPGA_NAND_DATA_SHIFT 16
  46. /**
  47. * nand_write_byte - write one byte to the chip
  48. * @mtd: MTD device structure
  49. * @byte: pointer to data byte to write
  50. */
  51. static void nand_write_byte(struct mtd_info *mtd, u_char byte)
  52. {
  53. nand_write_buf(mtd, (const uchar *)&byte, sizeof(byte));
  54. }
  55. /**
  56. * nand_write_word - write one word to the chip
  57. * @mtd: MTD device structure
  58. * @word: data word to write
  59. */
  60. static void nand_write_word(struct mtd_info *mtd, u16 word)
  61. {
  62. nand_write_buf(mtd, (const uchar *)&word, sizeof(word));
  63. }
  64. /**
  65. * nand_write_buf - write buffer to chip
  66. * @mtd: MTD device structure
  67. * @buf: data buffer
  68. * @len: number of bytes to write
  69. */
  70. static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
  71. {
  72. int i;
  73. struct nand_chip *this = mtd->priv;
  74. long val;
  75. if ((state & FPGA_NAND_CMD_MASK) == FPGA_NAND_CMD_MASK) {
  76. /* Write data */
  77. val = (state & FPGA_NAND_ENABLE) | FPGA_NAND_CMD_WRITE;
  78. } else {
  79. /* Write address or command */
  80. val = state;
  81. }
  82. for (i = 0; i < len; i++) {
  83. out_be32(this->IO_ADDR_W, val | (buf[i] << FPGA_NAND_DATA_SHIFT));
  84. }
  85. }
  86. /**
  87. * nand_read_byte - read one byte from the chip
  88. * @mtd: MTD device structure
  89. */
  90. static u_char nand_read_byte(struct mtd_info *mtd)
  91. {
  92. u8 byte;
  93. nand_read_buf(mtd, (uchar *)&byte, sizeof(byte));
  94. return byte;
  95. }
  96. /**
  97. * nand_read_word - read one word from the chip
  98. * @mtd: MTD device structure
  99. */
  100. static u16 nand_read_word(struct mtd_info *mtd)
  101. {
  102. u16 word;
  103. nand_read_buf(mtd, (uchar *)&word, sizeof(word));
  104. return word;
  105. }
  106. /**
  107. * nand_read_buf - read chip data into buffer
  108. * @mtd: MTD device structure
  109. * @buf: buffer to store date
  110. * @len: number of bytes to read
  111. */
  112. static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
  113. {
  114. int i;
  115. struct nand_chip *this = mtd->priv;
  116. int val;
  117. val = (state & FPGA_NAND_ENABLE) | FPGA_NAND_CMD_READ;
  118. out_be32(this->IO_ADDR_W, val);
  119. for (i = 0; i < len; i++) {
  120. buf[i] = (in_be32(this->IO_ADDR_R) >> FPGA_NAND_DATA_SHIFT) & 0xff;
  121. }
  122. }
  123. /**
  124. * nand_verify_buf - Verify chip data against buffer
  125. * @mtd: MTD device structure
  126. * @buf: buffer containing the data to compare
  127. * @len: number of bytes to compare
  128. */
  129. static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
  130. {
  131. int i;
  132. for (i = 0; i < len; i++) {
  133. if (buf[i] != nand_read_byte(mtd));
  134. return -EFAULT;
  135. }
  136. return 0;
  137. }
  138. /**
  139. * nand_device_ready - Check the NAND device is ready for next command.
  140. * @mtd: MTD device structure
  141. */
  142. static int nand_device_ready(struct mtd_info *mtdinfo)
  143. {
  144. struct nand_chip *this = mtdinfo->priv;
  145. if (in_be32(this->IO_ADDR_W) & FPGA_NAND_BUSY)
  146. return 0; /* busy */
  147. return 1;
  148. }
  149. /**
  150. * nand_hwcontrol - NAND control functions wrapper.
  151. * @mtd: MTD device structure
  152. * @cmd: Command
  153. */
  154. static void nand_hwcontrol(struct mtd_info *mtdinfo, int cmd)
  155. {
  156. switch(cmd) {
  157. case NAND_CTL_CLRALE:
  158. state |= FPGA_NAND_CMD_MASK; /* use all 1s to mark */
  159. break;
  160. case NAND_CTL_CLRCLE:
  161. state |= FPGA_NAND_CMD_MASK; /* use all 1s to mark */
  162. break;
  163. case NAND_CTL_SETCLE:
  164. state = (state & ~FPGA_NAND_CMD_MASK) | FPGA_NAND_CMD_COMMAND;
  165. break;
  166. case NAND_CTL_SETALE:
  167. state = (state & ~FPGA_NAND_CMD_MASK) | FPGA_NAND_CMD_ADDR;
  168. break;
  169. case NAND_CTL_SETNCE:
  170. state |= FPGA_NAND_ENABLE;
  171. break;
  172. case NAND_CTL_CLRNCE:
  173. state &= ~FPGA_NAND_ENABLE;
  174. break;
  175. default:
  176. printf("%s: unknown cmd %#x\n", __FUNCTION__, cmd);
  177. break;
  178. }
  179. }
  180. int board_nand_init(struct nand_chip *nand)
  181. {
  182. nand->hwcontrol = nand_hwcontrol;
  183. nand->eccmode = NAND_ECC_SOFT;
  184. nand->dev_ready = nand_device_ready;
  185. nand->write_byte = nand_write_byte;
  186. nand->read_byte = nand_read_byte;
  187. nand->write_word = nand_write_word;
  188. nand->read_word = nand_read_word;
  189. nand->write_buf = nand_write_buf;
  190. nand->read_buf = nand_read_buf;
  191. nand->verify_buf = nand_verify_buf;
  192. return 0;
  193. }
  194. #endif