fsl_upm.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * FSL UPM NAND driver
  3. *
  4. * Copyright (C) 2007 MontaVista Software, Inc.
  5. * Anton Vorontsov <avorontsov@ru.mvista.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. #include <config.h>
  13. #if defined(CONFIG_CMD_NAND) && defined(CONFIG_NAND_FSL_UPM)
  14. #include <common.h>
  15. #include <asm/io.h>
  16. #include <asm/errno.h>
  17. #include <linux/mtd/mtd.h>
  18. #include <linux/mtd/fsl_upm.h>
  19. #include <nand.h>
  20. #define FSL_UPM_MxMR_OP_NO (0 << 28) /* normal operation */
  21. #define FSL_UPM_MxMR_OP_WA (1 << 28) /* write array */
  22. #define FSL_UPM_MxMR_OP_RA (2 << 28) /* read array */
  23. #define FSL_UPM_MxMR_OP_RP (3 << 28) /* run pattern */
  24. static void fsl_upm_start_pattern(struct fsl_upm *upm, u32 pat_offset)
  25. {
  26. out_be32(upm->mxmr, FSL_UPM_MxMR_OP_RP | pat_offset);
  27. }
  28. static void fsl_upm_end_pattern(struct fsl_upm *upm)
  29. {
  30. out_be32(upm->mxmr, FSL_UPM_MxMR_OP_NO);
  31. while (in_be32(upm->mxmr) != FSL_UPM_MxMR_OP_NO)
  32. eieio();
  33. }
  34. static void fsl_upm_run_pattern(struct fsl_upm *upm, int width, u32 cmd)
  35. {
  36. out_be32(upm->mar, cmd << (32 - width * 8));
  37. out_8(upm->io_addr, 0x0);
  38. }
  39. static void fsl_upm_setup(struct fsl_upm *upm)
  40. {
  41. int i;
  42. /* write upm array */
  43. out_be32(upm->mxmr, FSL_UPM_MxMR_OP_WA);
  44. for (i = 0; i < 64; i++) {
  45. out_be32(upm->mdr, upm->array[i]);
  46. out_8(upm->io_addr, 0x0);
  47. }
  48. /* normal operation */
  49. out_be32(upm->mxmr, FSL_UPM_MxMR_OP_NO);
  50. while (in_be32(upm->mxmr) != FSL_UPM_MxMR_OP_NO)
  51. eieio();
  52. }
  53. static void fun_cmdfunc(struct mtd_info *mtd, unsigned command, int column,
  54. int page_addr)
  55. {
  56. struct nand_chip *chip = mtd->priv;
  57. struct fsl_upm_nand *fun = chip->priv;
  58. fsl_upm_start_pattern(&fun->upm, fun->upm_cmd_offset);
  59. if (command == NAND_CMD_SEQIN) {
  60. int readcmd;
  61. if (column >= mtd->oobblock) {
  62. /* OOB area */
  63. column -= mtd->oobblock;
  64. readcmd = NAND_CMD_READOOB;
  65. } else if (column < 256) {
  66. /* First 256 bytes --> READ0 */
  67. readcmd = NAND_CMD_READ0;
  68. } else {
  69. column -= 256;
  70. readcmd = NAND_CMD_READ1;
  71. }
  72. fsl_upm_run_pattern(&fun->upm, fun->width, readcmd);
  73. }
  74. fsl_upm_run_pattern(&fun->upm, fun->width, command);
  75. fsl_upm_end_pattern(&fun->upm);
  76. fsl_upm_start_pattern(&fun->upm, fun->upm_addr_offset);
  77. if (column != -1)
  78. fsl_upm_run_pattern(&fun->upm, fun->width, column);
  79. if (page_addr != -1) {
  80. fsl_upm_run_pattern(&fun->upm, fun->width, page_addr);
  81. fsl_upm_run_pattern(&fun->upm, fun->width,
  82. (page_addr >> 8) & 0xFF);
  83. if (chip->chipsize > (32 << 20)) {
  84. fsl_upm_run_pattern(&fun->upm, fun->width,
  85. (page_addr >> 16) & 0x0f);
  86. }
  87. }
  88. fsl_upm_end_pattern(&fun->upm);
  89. if (fun->wait_pattern) {
  90. /*
  91. * Some boards/chips needs this. At least on MPC8360E-RDK we
  92. * need it. Probably weird chip, because I don't see any need
  93. * for this on MPC8555E + Samsung K9F1G08U0A. Usually here are
  94. * 0-2 unexpected busy states per block read.
  95. */
  96. while (!fun->dev_ready())
  97. debug("unexpected busy state\n");
  98. }
  99. }
  100. static void nand_write_byte(struct mtd_info *mtd, u_char byte)
  101. {
  102. struct nand_chip *chip = mtd->priv;
  103. out_8(chip->IO_ADDR_W, byte);
  104. }
  105. static u8 nand_read_byte(struct mtd_info *mtd)
  106. {
  107. struct nand_chip *chip = mtd->priv;
  108. return in_8(chip->IO_ADDR_R);
  109. }
  110. static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
  111. {
  112. int i;
  113. struct nand_chip *chip = mtd->priv;
  114. for (i = 0; i < len; i++)
  115. out_8(chip->IO_ADDR_W, buf[i]);
  116. }
  117. static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
  118. {
  119. int i;
  120. struct nand_chip *chip = mtd->priv;
  121. for (i = 0; i < len; i++)
  122. buf[i] = in_8(chip->IO_ADDR_R);
  123. }
  124. static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
  125. {
  126. int i;
  127. struct nand_chip *chip = mtd->priv;
  128. for (i = 0; i < len; i++) {
  129. if (buf[i] != in_8(chip->IO_ADDR_R))
  130. return -EFAULT;
  131. }
  132. return 0;
  133. }
  134. static void nand_hwcontrol(struct mtd_info *mtd, int cmd)
  135. {
  136. }
  137. static int nand_dev_ready(struct mtd_info *mtd)
  138. {
  139. struct nand_chip *chip = mtd->priv;
  140. struct fsl_upm_nand *fun = chip->priv;
  141. return fun->dev_ready();
  142. }
  143. int fsl_upm_nand_init(struct nand_chip *chip, struct fsl_upm_nand *fun)
  144. {
  145. /* yet only 8 bit accessors implemented */
  146. if (fun->width != 1)
  147. return -ENOSYS;
  148. fsl_upm_setup(&fun->upm);
  149. chip->priv = fun;
  150. chip->chip_delay = fun->chip_delay;
  151. chip->eccmode = NAND_ECC_SOFT;
  152. chip->cmdfunc = fun_cmdfunc;
  153. chip->hwcontrol = nand_hwcontrol;
  154. chip->read_byte = nand_read_byte;
  155. chip->read_buf = nand_read_buf;
  156. chip->write_byte = nand_write_byte;
  157. chip->write_buf = nand_write_buf;
  158. chip->verify_buf = nand_verify_buf;
  159. chip->dev_ready = nand_dev_ready;
  160. return 0;
  161. }
  162. #endif /* CONFIG_CMD_NAND */