nand_boot_fsl_ifc.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /*
  2. * NAND boot for FSL Integrated Flash Controller, NAND Flash Control Machine
  3. *
  4. * Copyright 2011 Freescale Semiconductor, Inc.
  5. * Author: Dipen Dudhat <dipen.dudhat@freescale.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 <common.h>
  23. #include <asm/io.h>
  24. #include <asm/fsl_ifc.h>
  25. #include <linux/mtd/nand.h>
  26. static inline int is_blank(uchar *addr, int page_size)
  27. {
  28. int i;
  29. for (i = 0; i < page_size; i++) {
  30. if (__raw_readb(&addr[i]) != 0xff)
  31. return 0;
  32. }
  33. /*
  34. * For the SPL, don't worry about uncorrectable errors
  35. * where the main area is all FFs but shouldn't be.
  36. */
  37. return 1;
  38. }
  39. /* returns nonzero if entire page is blank */
  40. static inline int check_read_ecc(uchar *buf, u32 *eccstat,
  41. unsigned int bufnum, int page_size)
  42. {
  43. u32 reg = eccstat[bufnum / 4];
  44. int errors = (reg >> ((3 - bufnum % 4) * 8)) & 15;
  45. if (errors == 15) { /* uncorrectable */
  46. /* Blank pages fail hw ECC checks */
  47. if (is_blank(buf, page_size))
  48. return 1;
  49. puts("ecc error\n");
  50. for (;;)
  51. ;
  52. }
  53. return 0;
  54. }
  55. static inline void nand_wait(uchar *buf, int bufnum, int page_size)
  56. {
  57. struct fsl_ifc *ifc = IFC_BASE_ADDR;
  58. u32 status;
  59. u32 eccstat[4];
  60. int bufperpage = page_size / 512;
  61. int bufnum_end, i;
  62. bufnum *= bufperpage;
  63. bufnum_end = bufnum + bufperpage - 1;
  64. do {
  65. status = in_be32(&ifc->ifc_nand.nand_evter_stat);
  66. } while (!(status & IFC_NAND_EVTER_STAT_OPC));
  67. if (status & IFC_NAND_EVTER_STAT_FTOER) {
  68. puts("flash time out error\n");
  69. for (;;)
  70. ;
  71. }
  72. for (i = bufnum / 4; i <= bufnum_end / 4; i++)
  73. eccstat[i] = in_be32(&ifc->ifc_nand.nand_eccstat[i]);
  74. for (i = bufnum; i <= bufnum_end; i++) {
  75. if (check_read_ecc(buf, eccstat, i, page_size))
  76. break;
  77. }
  78. out_be32(&ifc->ifc_nand.nand_evter_stat, status);
  79. }
  80. static inline int bad_block(uchar *marker, int port_size)
  81. {
  82. if (port_size == 8)
  83. return __raw_readb(marker) != 0xff;
  84. else
  85. return __raw_readw((u16 *)marker) != 0xffff;
  86. }
  87. static void nand_load(unsigned int offs, int uboot_size, uchar *dst)
  88. {
  89. struct fsl_ifc *ifc = IFC_BASE_ADDR;
  90. uchar *buf = (uchar *)CONFIG_SYS_NAND_BASE;
  91. int page_size;
  92. int port_size;
  93. int pages_per_blk;
  94. int blk_size;
  95. int bad_marker = 0;
  96. int bufnum_mask, bufnum;
  97. int csor, cspr;
  98. int pos = 0;
  99. int j = 0;
  100. int sram_addr;
  101. int pg_no;
  102. /* Get NAND Flash configuration */
  103. csor = CONFIG_SYS_NAND_CSOR;
  104. cspr = CONFIG_SYS_NAND_CSPR;
  105. if (!(csor & CSOR_NAND_ECC_DEC_EN)) {
  106. /* soft ECC in SPL is unimplemented */
  107. puts("WARNING: soft ECC not checked in SPL\n");
  108. } else {
  109. u32 hwcsor;
  110. /* make sure board is configured with ECC on boot */
  111. hwcsor = in_be32(&ifc->csor_cs[0].csor);
  112. if (!(hwcsor & CSOR_NAND_ECC_DEC_EN))
  113. puts("WARNING: ECC not checked in SPL, "
  114. "check board cfg\n");
  115. }
  116. port_size = (cspr & CSPR_PORT_SIZE_16) ? 16 : 8;
  117. if (csor & CSOR_NAND_PGS_4K) {
  118. page_size = 4096;
  119. bufnum_mask = 1;
  120. } else if (csor & CSOR_NAND_PGS_2K) {
  121. page_size = 2048;
  122. bufnum_mask = 3;
  123. } else {
  124. page_size = 512;
  125. bufnum_mask = 15;
  126. if (port_size == 8)
  127. bad_marker = 5;
  128. }
  129. pages_per_blk =
  130. 32 << ((csor & CSOR_NAND_PB_MASK) >> CSOR_NAND_PB_SHIFT);
  131. blk_size = pages_per_blk * page_size;
  132. /* Open Full SRAM mapping for spare are access */
  133. out_be32(&ifc->ifc_nand.ncfgr, 0x0);
  134. /* Clear Boot events */
  135. out_be32(&ifc->ifc_nand.nand_evter_stat, 0xffffffff);
  136. /* Program FIR/FCR for Large/Small page */
  137. if (page_size > 512) {
  138. out_be32(&ifc->ifc_nand.nand_fir0,
  139. (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
  140. (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
  141. (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
  142. (IFC_FIR_OP_CMD1 << IFC_NAND_FIR0_OP3_SHIFT) |
  143. (IFC_FIR_OP_BTRD << IFC_NAND_FIR0_OP4_SHIFT));
  144. out_be32(&ifc->ifc_nand.nand_fir1, 0x0);
  145. out_be32(&ifc->ifc_nand.nand_fcr0,
  146. (NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT) |
  147. (NAND_CMD_READSTART << IFC_NAND_FCR0_CMD1_SHIFT));
  148. } else {
  149. out_be32(&ifc->ifc_nand.nand_fir0,
  150. (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
  151. (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
  152. (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
  153. (IFC_FIR_OP_BTRD << IFC_NAND_FIR0_OP3_SHIFT));
  154. out_be32(&ifc->ifc_nand.nand_fir1, 0x0);
  155. out_be32(&ifc->ifc_nand.nand_fcr0,
  156. NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT);
  157. }
  158. /* Program FBCR = 0 for full page read */
  159. out_be32(&ifc->ifc_nand.nand_fbcr, 0);
  160. /* Read and copy u-boot on SDRAM from NAND device, In parallel
  161. * check for Bad block if found skip it and read continue to
  162. * next Block
  163. */
  164. while (pos < uboot_size) {
  165. int i = 0;
  166. do {
  167. pg_no = offs / page_size;
  168. bufnum = pg_no & bufnum_mask;
  169. sram_addr = bufnum * page_size * 2;
  170. out_be32(&ifc->ifc_nand.row0, pg_no);
  171. out_be32(&ifc->ifc_nand.col0, 0);
  172. /* start read */
  173. out_be32(&ifc->ifc_nand.nandseq_strt,
  174. IFC_NAND_SEQ_STRT_FIR_STRT);
  175. /* wait for read to complete */
  176. nand_wait(&buf[sram_addr], bufnum, page_size);
  177. /*
  178. * If either of the first two pages are marked bad,
  179. * continue to the next block.
  180. */
  181. if (i++ < 2 &&
  182. bad_block(&buf[sram_addr + page_size + bad_marker],
  183. port_size)) {
  184. puts("skipping\n");
  185. offs = (offs + blk_size) & ~(blk_size - 1);
  186. pos &= ~(blk_size - 1);
  187. break;
  188. }
  189. for (j = 0; j < page_size; j++)
  190. dst[pos + j] = __raw_readb(&buf[sram_addr + j]);
  191. pos += page_size;
  192. offs += page_size;
  193. } while ((offs & (blk_size - 1)) && (pos < uboot_size));
  194. }
  195. }
  196. /*
  197. * Main entrypoint for NAND Boot. It's necessary that SDRAM is already
  198. * configured and available since this code loads the main U-boot image
  199. * from NAND into SDRAM and starts from there.
  200. */
  201. void nand_boot(void)
  202. {
  203. __attribute__((noreturn)) void (*uboot)(void);
  204. /*
  205. * Load U-Boot image from NAND into RAM
  206. */
  207. nand_load(CONFIG_SYS_NAND_U_BOOT_OFFS, CONFIG_SYS_NAND_U_BOOT_SIZE,
  208. (uchar *)CONFIG_SYS_NAND_U_BOOT_DST);
  209. #ifdef CONFIG_NAND_ENV_DST
  210. nand_load(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE,
  211. (uchar *)CONFIG_NAND_ENV_DST);
  212. #ifdef CONFIG_ENV_OFFSET_REDUND
  213. nand_load(CONFIG_ENV_OFFSET_REDUND, CONFIG_ENV_SIZE,
  214. (uchar *)CONFIG_NAND_ENV_DST + CONFIG_ENV_SIZE);
  215. #endif
  216. #endif
  217. /*
  218. * Jump to U-Boot image
  219. */
  220. /*
  221. * Clean d-cache and invalidate i-cache, to
  222. * make sure that no stale data is executed.
  223. */
  224. flush_cache(CONFIG_SYS_NAND_U_BOOT_DST, CONFIG_SYS_NAND_U_BOOT_SIZE);
  225. uboot = (void *)CONFIG_SYS_NAND_U_BOOT_START;
  226. uboot();
  227. }