omap_gpmc.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041
  1. /*
  2. * (C) Copyright 2004-2008 Texas Instruments, <www.ti.com>
  3. * Rohit Choraria <rohitkc@ti.com>
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. #include <common.h>
  8. #include <asm/io.h>
  9. #include <asm/errno.h>
  10. #include <asm/arch/mem.h>
  11. #include <linux/mtd/omap_gpmc.h>
  12. #include <linux/mtd/nand_ecc.h>
  13. #include <linux/bch.h>
  14. #include <linux/compiler.h>
  15. #include <nand.h>
  16. #include <linux/mtd/omap_elm.h>
  17. #define BADBLOCK_MARKER_LENGTH 2
  18. #define SECTOR_BYTES 512
  19. #define ECCCLEAR (0x1 << 8)
  20. #define ECCRESULTREG1 (0x1 << 0)
  21. /* 4 bit padding to make byte aligned, 56 = 52 + 4 */
  22. #define BCH4_BIT_PAD 4
  23. #ifdef CONFIG_BCH
  24. static u8 bch8_polynomial[] = {0xef, 0x51, 0x2e, 0x09, 0xed, 0x93, 0x9a, 0xc2,
  25. 0x97, 0x79, 0xe5, 0x24, 0xb5};
  26. #endif
  27. static uint8_t cs_next;
  28. static __maybe_unused struct nand_ecclayout omap_ecclayout;
  29. #if defined(CONFIG_NAND_OMAP_GPMC_WSCFG)
  30. static const int8_t wscfg[CONFIG_SYS_MAX_NAND_DEVICE] =
  31. { CONFIG_NAND_OMAP_GPMC_WSCFG };
  32. #else
  33. /* wscfg is preset to zero since its a static variable */
  34. static const int8_t wscfg[CONFIG_SYS_MAX_NAND_DEVICE];
  35. #endif
  36. /*
  37. * Driver configurations
  38. */
  39. struct omap_nand_info {
  40. struct bch_control *control;
  41. enum omap_ecc ecc_scheme;
  42. uint8_t cs;
  43. uint8_t ws; /* wait status pin (0,1) */
  44. };
  45. /* We are wasting a bit of memory but al least we are safe */
  46. static struct omap_nand_info omap_nand_info[GPMC_MAX_CS];
  47. /*
  48. * omap_nand_hwcontrol - Set the address pointers corretly for the
  49. * following address/data/command operation
  50. */
  51. static void omap_nand_hwcontrol(struct mtd_info *mtd, int32_t cmd,
  52. uint32_t ctrl)
  53. {
  54. register struct nand_chip *this = mtd_to_nand(mtd);
  55. struct omap_nand_info *info = nand_get_controller_data(this);
  56. int cs = info->cs;
  57. /*
  58. * Point the IO_ADDR to DATA and ADDRESS registers instead
  59. * of chip address
  60. */
  61. switch (ctrl) {
  62. case NAND_CTRL_CHANGE | NAND_CTRL_CLE:
  63. this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
  64. break;
  65. case NAND_CTRL_CHANGE | NAND_CTRL_ALE:
  66. this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_adr;
  67. break;
  68. case NAND_CTRL_CHANGE | NAND_NCE:
  69. this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
  70. break;
  71. }
  72. if (cmd != NAND_CMD_NONE)
  73. writeb(cmd, this->IO_ADDR_W);
  74. }
  75. /* Check wait pin as dev ready indicator */
  76. static int omap_dev_ready(struct mtd_info *mtd)
  77. {
  78. register struct nand_chip *this = mtd_to_nand(mtd);
  79. struct omap_nand_info *info = nand_get_controller_data(this);
  80. return gpmc_cfg->status & (1 << (8 + info->ws));
  81. }
  82. /*
  83. * gen_true_ecc - This function will generate true ECC value, which
  84. * can be used when correcting data read from NAND flash memory core
  85. *
  86. * @ecc_buf: buffer to store ecc code
  87. *
  88. * @return: re-formatted ECC value
  89. */
  90. static uint32_t gen_true_ecc(uint8_t *ecc_buf)
  91. {
  92. return ecc_buf[0] | (ecc_buf[1] << 16) | ((ecc_buf[2] & 0xF0) << 20) |
  93. ((ecc_buf[2] & 0x0F) << 8);
  94. }
  95. /*
  96. * omap_correct_data - Compares the ecc read from nand spare area with ECC
  97. * registers values and corrects one bit error if it has occurred
  98. * Further details can be had from OMAP TRM and the following selected links:
  99. * http://en.wikipedia.org/wiki/Hamming_code
  100. * http://www.cs.utexas.edu/users/plaxton/c/337/05f/slides/ErrorCorrection-4.pdf
  101. *
  102. * @mtd: MTD device structure
  103. * @dat: page data
  104. * @read_ecc: ecc read from nand flash
  105. * @calc_ecc: ecc read from ECC registers
  106. *
  107. * @return 0 if data is OK or corrected, else returns -1
  108. */
  109. static int __maybe_unused omap_correct_data(struct mtd_info *mtd, uint8_t *dat,
  110. uint8_t *read_ecc, uint8_t *calc_ecc)
  111. {
  112. uint32_t orig_ecc, new_ecc, res, hm;
  113. uint16_t parity_bits, byte;
  114. uint8_t bit;
  115. /* Regenerate the orginal ECC */
  116. orig_ecc = gen_true_ecc(read_ecc);
  117. new_ecc = gen_true_ecc(calc_ecc);
  118. /* Get the XOR of real ecc */
  119. res = orig_ecc ^ new_ecc;
  120. if (res) {
  121. /* Get the hamming width */
  122. hm = hweight32(res);
  123. /* Single bit errors can be corrected! */
  124. if (hm == 12) {
  125. /* Correctable data! */
  126. parity_bits = res >> 16;
  127. bit = (parity_bits & 0x7);
  128. byte = (parity_bits >> 3) & 0x1FF;
  129. /* Flip the bit to correct */
  130. dat[byte] ^= (0x1 << bit);
  131. } else if (hm == 1) {
  132. printf("Error: Ecc is wrong\n");
  133. /* ECC itself is corrupted */
  134. return 2;
  135. } else {
  136. /*
  137. * hm distance != parity pairs OR one, could mean 2 bit
  138. * error OR potentially be on a blank page..
  139. * orig_ecc: contains spare area data from nand flash.
  140. * new_ecc: generated ecc while reading data area.
  141. * Note: if the ecc = 0, all data bits from which it was
  142. * generated are 0xFF.
  143. * The 3 byte(24 bits) ecc is generated per 512byte
  144. * chunk of a page. If orig_ecc(from spare area)
  145. * is 0xFF && new_ecc(computed now from data area)=0x0,
  146. * this means that data area is 0xFF and spare area is
  147. * 0xFF. A sure sign of a erased page!
  148. */
  149. if ((orig_ecc == 0x0FFF0FFF) && (new_ecc == 0x00000000))
  150. return 0;
  151. printf("Error: Bad compare! failed\n");
  152. /* detected 2 bit error */
  153. return -EBADMSG;
  154. }
  155. }
  156. return 0;
  157. }
  158. /*
  159. * omap_enable_hwecc - configures GPMC as per ECC scheme before read/write
  160. * @mtd: MTD device structure
  161. * @mode: Read/Write mode
  162. */
  163. __maybe_unused
  164. static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
  165. {
  166. struct nand_chip *nand = mtd_to_nand(mtd);
  167. struct omap_nand_info *info = nand_get_controller_data(nand);
  168. unsigned int dev_width = (nand->options & NAND_BUSWIDTH_16) ? 1 : 0;
  169. unsigned int ecc_algo = 0;
  170. unsigned int bch_type = 0;
  171. unsigned int eccsize1 = 0x00, eccsize0 = 0x00, bch_wrapmode = 0x00;
  172. u32 ecc_size_config_val = 0;
  173. u32 ecc_config_val = 0;
  174. int cs = info->cs;
  175. /* configure GPMC for specific ecc-scheme */
  176. switch (info->ecc_scheme) {
  177. case OMAP_ECC_HAM1_CODE_SW:
  178. return;
  179. case OMAP_ECC_HAM1_CODE_HW:
  180. ecc_algo = 0x0;
  181. bch_type = 0x0;
  182. bch_wrapmode = 0x00;
  183. eccsize0 = 0xFF;
  184. eccsize1 = 0xFF;
  185. break;
  186. case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
  187. case OMAP_ECC_BCH8_CODE_HW:
  188. ecc_algo = 0x1;
  189. bch_type = 0x1;
  190. if (mode == NAND_ECC_WRITE) {
  191. bch_wrapmode = 0x01;
  192. eccsize0 = 0; /* extra bits in nibbles per sector */
  193. eccsize1 = 28; /* OOB bits in nibbles per sector */
  194. } else {
  195. bch_wrapmode = 0x01;
  196. eccsize0 = 26; /* ECC bits in nibbles per sector */
  197. eccsize1 = 2; /* non-ECC bits in nibbles per sector */
  198. }
  199. break;
  200. case OMAP_ECC_BCH16_CODE_HW:
  201. ecc_algo = 0x1;
  202. bch_type = 0x2;
  203. if (mode == NAND_ECC_WRITE) {
  204. bch_wrapmode = 0x01;
  205. eccsize0 = 0; /* extra bits in nibbles per sector */
  206. eccsize1 = 52; /* OOB bits in nibbles per sector */
  207. } else {
  208. bch_wrapmode = 0x01;
  209. eccsize0 = 52; /* ECC bits in nibbles per sector */
  210. eccsize1 = 0; /* non-ECC bits in nibbles per sector */
  211. }
  212. break;
  213. default:
  214. return;
  215. }
  216. /* Clear ecc and enable bits */
  217. writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
  218. /* Configure ecc size for BCH */
  219. ecc_size_config_val = (eccsize1 << 22) | (eccsize0 << 12);
  220. writel(ecc_size_config_val, &gpmc_cfg->ecc_size_config);
  221. /* Configure device details for BCH engine */
  222. ecc_config_val = ((ecc_algo << 16) | /* HAM1 | BCHx */
  223. (bch_type << 12) | /* BCH4/BCH8/BCH16 */
  224. (bch_wrapmode << 8) | /* wrap mode */
  225. (dev_width << 7) | /* bus width */
  226. (0x0 << 4) | /* number of sectors */
  227. (cs << 1) | /* ECC CS */
  228. (0x1)); /* enable ECC */
  229. writel(ecc_config_val, &gpmc_cfg->ecc_config);
  230. }
  231. /*
  232. * omap_calculate_ecc - Read ECC result
  233. * @mtd: MTD structure
  234. * @dat: unused
  235. * @ecc_code: ecc_code buffer
  236. * Using noninverted ECC can be considered ugly since writing a blank
  237. * page ie. padding will clear the ECC bytes. This is no problem as
  238. * long nobody is trying to write data on the seemingly unused page.
  239. * Reading an erased page will produce an ECC mismatch between
  240. * generated and read ECC bytes that has to be dealt with separately.
  241. * E.g. if page is 0xFF (fresh erased), and if HW ECC engine within GPMC
  242. * is used, the result of read will be 0x0 while the ECC offsets of the
  243. * spare area will be 0xFF which will result in an ECC mismatch.
  244. */
  245. static int omap_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
  246. uint8_t *ecc_code)
  247. {
  248. struct nand_chip *chip = mtd_to_nand(mtd);
  249. struct omap_nand_info *info = nand_get_controller_data(chip);
  250. const uint32_t *ptr;
  251. uint32_t val = 0;
  252. int8_t i = 0, j;
  253. switch (info->ecc_scheme) {
  254. case OMAP_ECC_HAM1_CODE_HW:
  255. val = readl(&gpmc_cfg->ecc1_result);
  256. ecc_code[0] = val & 0xFF;
  257. ecc_code[1] = (val >> 16) & 0xFF;
  258. ecc_code[2] = ((val >> 8) & 0x0F) | ((val >> 20) & 0xF0);
  259. break;
  260. #ifdef CONFIG_BCH
  261. case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
  262. #endif
  263. case OMAP_ECC_BCH8_CODE_HW:
  264. ptr = &gpmc_cfg->bch_result_0_3[0].bch_result_x[3];
  265. val = readl(ptr);
  266. ecc_code[i++] = (val >> 0) & 0xFF;
  267. ptr--;
  268. for (j = 0; j < 3; j++) {
  269. val = readl(ptr);
  270. ecc_code[i++] = (val >> 24) & 0xFF;
  271. ecc_code[i++] = (val >> 16) & 0xFF;
  272. ecc_code[i++] = (val >> 8) & 0xFF;
  273. ecc_code[i++] = (val >> 0) & 0xFF;
  274. ptr--;
  275. }
  276. break;
  277. case OMAP_ECC_BCH16_CODE_HW:
  278. val = readl(&gpmc_cfg->bch_result_4_6[0].bch_result_x[2]);
  279. ecc_code[i++] = (val >> 8) & 0xFF;
  280. ecc_code[i++] = (val >> 0) & 0xFF;
  281. val = readl(&gpmc_cfg->bch_result_4_6[0].bch_result_x[1]);
  282. ecc_code[i++] = (val >> 24) & 0xFF;
  283. ecc_code[i++] = (val >> 16) & 0xFF;
  284. ecc_code[i++] = (val >> 8) & 0xFF;
  285. ecc_code[i++] = (val >> 0) & 0xFF;
  286. val = readl(&gpmc_cfg->bch_result_4_6[0].bch_result_x[0]);
  287. ecc_code[i++] = (val >> 24) & 0xFF;
  288. ecc_code[i++] = (val >> 16) & 0xFF;
  289. ecc_code[i++] = (val >> 8) & 0xFF;
  290. ecc_code[i++] = (val >> 0) & 0xFF;
  291. for (j = 3; j >= 0; j--) {
  292. val = readl(&gpmc_cfg->bch_result_0_3[0].bch_result_x[j]
  293. );
  294. ecc_code[i++] = (val >> 24) & 0xFF;
  295. ecc_code[i++] = (val >> 16) & 0xFF;
  296. ecc_code[i++] = (val >> 8) & 0xFF;
  297. ecc_code[i++] = (val >> 0) & 0xFF;
  298. }
  299. break;
  300. default:
  301. return -EINVAL;
  302. }
  303. /* ECC scheme specific syndrome customizations */
  304. switch (info->ecc_scheme) {
  305. case OMAP_ECC_HAM1_CODE_HW:
  306. break;
  307. #ifdef CONFIG_BCH
  308. case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
  309. for (i = 0; i < chip->ecc.bytes; i++)
  310. *(ecc_code + i) = *(ecc_code + i) ^
  311. bch8_polynomial[i];
  312. break;
  313. #endif
  314. case OMAP_ECC_BCH8_CODE_HW:
  315. ecc_code[chip->ecc.bytes - 1] = 0x00;
  316. break;
  317. case OMAP_ECC_BCH16_CODE_HW:
  318. break;
  319. default:
  320. return -EINVAL;
  321. }
  322. return 0;
  323. }
  324. #ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH
  325. #define PREFETCH_CONFIG1_CS_SHIFT 24
  326. #define PREFETCH_FIFOTHRESHOLD_MAX 0x40
  327. #define PREFETCH_FIFOTHRESHOLD(val) ((val) << 8)
  328. #define PREFETCH_STATUS_COUNT(val) (val & 0x00003fff)
  329. #define PREFETCH_STATUS_FIFO_CNT(val) ((val >> 24) & 0x7F)
  330. #define ENABLE_PREFETCH (1 << 7)
  331. /**
  332. * omap_prefetch_enable - configures and starts prefetch transfer
  333. * @fifo_th: fifo threshold to be used for read/ write
  334. * @count: number of bytes to be transferred
  335. * @is_write: prefetch read(0) or write post(1) mode
  336. * @cs: chip select to use
  337. */
  338. static int omap_prefetch_enable(int fifo_th, unsigned int count, int is_write, int cs)
  339. {
  340. uint32_t val;
  341. if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX)
  342. return -EINVAL;
  343. if (readl(&gpmc_cfg->prefetch_control))
  344. return -EBUSY;
  345. /* Set the amount of bytes to be prefetched */
  346. writel(count, &gpmc_cfg->prefetch_config2);
  347. val = (cs << PREFETCH_CONFIG1_CS_SHIFT) | (is_write & 1) |
  348. PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH;
  349. writel(val, &gpmc_cfg->prefetch_config1);
  350. /* Start the prefetch engine */
  351. writel(1, &gpmc_cfg->prefetch_control);
  352. return 0;
  353. }
  354. /**
  355. * omap_prefetch_reset - disables and stops the prefetch engine
  356. */
  357. static void omap_prefetch_reset(void)
  358. {
  359. writel(0, &gpmc_cfg->prefetch_control);
  360. writel(0, &gpmc_cfg->prefetch_config1);
  361. }
  362. static int __read_prefetch_aligned(struct nand_chip *chip, uint32_t *buf, int len)
  363. {
  364. int ret;
  365. uint32_t cnt;
  366. struct omap_nand_info *info = nand_get_controller_data(chip);
  367. ret = omap_prefetch_enable(PREFETCH_FIFOTHRESHOLD_MAX, len, 0, info->cs);
  368. if (ret < 0)
  369. return ret;
  370. do {
  371. int i;
  372. cnt = readl(&gpmc_cfg->prefetch_status);
  373. cnt = PREFETCH_STATUS_FIFO_CNT(cnt);
  374. for (i = 0; i < cnt / 4; i++) {
  375. *buf++ = readl(CONFIG_SYS_NAND_BASE);
  376. len -= 4;
  377. }
  378. } while (len);
  379. omap_prefetch_reset();
  380. return 0;
  381. }
  382. static inline void omap_nand_read(struct mtd_info *mtd, uint8_t *buf, int len)
  383. {
  384. struct nand_chip *chip = mtd_to_nand(mtd);
  385. if (chip->options & NAND_BUSWIDTH_16)
  386. nand_read_buf16(mtd, buf, len);
  387. else
  388. nand_read_buf(mtd, buf, len);
  389. }
  390. static void omap_nand_read_prefetch(struct mtd_info *mtd, uint8_t *buf, int len)
  391. {
  392. int ret;
  393. uint32_t head, tail;
  394. struct nand_chip *chip = mtd_to_nand(mtd);
  395. /*
  396. * If the destination buffer is unaligned, start with reading
  397. * the overlap byte-wise.
  398. */
  399. head = ((uint32_t) buf) % 4;
  400. if (head) {
  401. omap_nand_read(mtd, buf, head);
  402. buf += head;
  403. len -= head;
  404. }
  405. /*
  406. * Only transfer multiples of 4 bytes in a pre-fetched fashion.
  407. * If there's a residue, care for it byte-wise afterwards.
  408. */
  409. tail = len % 4;
  410. ret = __read_prefetch_aligned(chip, (uint32_t *)buf, len - tail);
  411. if (ret < 0) {
  412. /* fallback in case the prefetch engine is busy */
  413. omap_nand_read(mtd, buf, len);
  414. } else if (tail) {
  415. buf += len - tail;
  416. omap_nand_read(mtd, buf, tail);
  417. }
  418. }
  419. #endif /* CONFIG_NAND_OMAP_GPMC_PREFETCH */
  420. #ifdef CONFIG_NAND_OMAP_ELM
  421. /*
  422. * omap_reverse_list - re-orders list elements in reverse order [internal]
  423. * @list: pointer to start of list
  424. * @length: length of list
  425. */
  426. static void omap_reverse_list(u8 *list, unsigned int length)
  427. {
  428. unsigned int i, j;
  429. unsigned int half_length = length / 2;
  430. u8 tmp;
  431. for (i = 0, j = length - 1; i < half_length; i++, j--) {
  432. tmp = list[i];
  433. list[i] = list[j];
  434. list[j] = tmp;
  435. }
  436. }
  437. /*
  438. * omap_correct_data_bch - Compares the ecc read from nand spare area
  439. * with ECC registers values and corrects one bit error if it has occurred
  440. *
  441. * @mtd: MTD device structure
  442. * @dat: page data
  443. * @read_ecc: ecc read from nand flash (ignored)
  444. * @calc_ecc: ecc read from ECC registers
  445. *
  446. * @return 0 if data is OK or corrected, else returns -1
  447. */
  448. static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
  449. uint8_t *read_ecc, uint8_t *calc_ecc)
  450. {
  451. struct nand_chip *chip = mtd_to_nand(mtd);
  452. struct omap_nand_info *info = nand_get_controller_data(chip);
  453. struct nand_ecc_ctrl *ecc = &chip->ecc;
  454. uint32_t error_count = 0, error_max;
  455. uint32_t error_loc[ELM_MAX_ERROR_COUNT];
  456. enum bch_level bch_type;
  457. uint32_t i, ecc_flag = 0;
  458. uint8_t count;
  459. uint32_t byte_pos, bit_pos;
  460. int err = 0;
  461. /* check calculated ecc */
  462. for (i = 0; i < ecc->bytes && !ecc_flag; i++) {
  463. if (calc_ecc[i] != 0x00)
  464. ecc_flag = 1;
  465. }
  466. if (!ecc_flag)
  467. return 0;
  468. /* check for whether its a erased-page */
  469. ecc_flag = 0;
  470. for (i = 0; i < ecc->bytes && !ecc_flag; i++) {
  471. if (read_ecc[i] != 0xff)
  472. ecc_flag = 1;
  473. }
  474. if (!ecc_flag)
  475. return 0;
  476. /*
  477. * while reading ECC result we read it in big endian.
  478. * Hence while loading to ELM we have rotate to get the right endian.
  479. */
  480. switch (info->ecc_scheme) {
  481. case OMAP_ECC_BCH8_CODE_HW:
  482. bch_type = BCH_8_BIT;
  483. omap_reverse_list(calc_ecc, ecc->bytes - 1);
  484. break;
  485. case OMAP_ECC_BCH16_CODE_HW:
  486. bch_type = BCH_16_BIT;
  487. omap_reverse_list(calc_ecc, ecc->bytes);
  488. break;
  489. default:
  490. return -EINVAL;
  491. }
  492. /* use elm module to check for errors */
  493. elm_config(bch_type);
  494. err = elm_check_error(calc_ecc, bch_type, &error_count, error_loc);
  495. if (err)
  496. return err;
  497. /* correct bch error */
  498. for (count = 0; count < error_count; count++) {
  499. switch (info->ecc_scheme) {
  500. case OMAP_ECC_BCH8_CODE_HW:
  501. /* 14th byte in ECC is reserved to match ROM layout */
  502. error_max = SECTOR_BYTES + (ecc->bytes - 1);
  503. break;
  504. case OMAP_ECC_BCH16_CODE_HW:
  505. error_max = SECTOR_BYTES + ecc->bytes;
  506. break;
  507. default:
  508. return -EINVAL;
  509. }
  510. byte_pos = error_max - (error_loc[count] / 8) - 1;
  511. bit_pos = error_loc[count] % 8;
  512. if (byte_pos < SECTOR_BYTES) {
  513. dat[byte_pos] ^= 1 << bit_pos;
  514. debug("nand: bit-flip corrected @data=%d\n", byte_pos);
  515. } else if (byte_pos < error_max) {
  516. read_ecc[byte_pos - SECTOR_BYTES] ^= 1 << bit_pos;
  517. debug("nand: bit-flip corrected @oob=%d\n", byte_pos -
  518. SECTOR_BYTES);
  519. } else {
  520. err = -EBADMSG;
  521. printf("nand: error: invalid bit-flip location\n");
  522. }
  523. }
  524. return (err) ? err : error_count;
  525. }
  526. /**
  527. * omap_read_page_bch - hardware ecc based page read function
  528. * @mtd: mtd info structure
  529. * @chip: nand chip info structure
  530. * @buf: buffer to store read data
  531. * @oob_required: caller expects OOB data read to chip->oob_poi
  532. * @page: page number to read
  533. *
  534. */
  535. static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
  536. uint8_t *buf, int oob_required, int page)
  537. {
  538. int i, eccsize = chip->ecc.size;
  539. int eccbytes = chip->ecc.bytes;
  540. int eccsteps = chip->ecc.steps;
  541. uint8_t *p = buf;
  542. uint8_t *ecc_calc = chip->buffers->ecccalc;
  543. uint8_t *ecc_code = chip->buffers->ecccode;
  544. uint32_t *eccpos = chip->ecc.layout->eccpos;
  545. uint8_t *oob = chip->oob_poi;
  546. uint32_t data_pos;
  547. uint32_t oob_pos;
  548. data_pos = 0;
  549. /* oob area start */
  550. oob_pos = (eccsize * eccsteps) + chip->ecc.layout->eccpos[0];
  551. oob += chip->ecc.layout->eccpos[0];
  552. for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize,
  553. oob += eccbytes) {
  554. chip->ecc.hwctl(mtd, NAND_ECC_READ);
  555. /* read data */
  556. chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_pos, -1);
  557. chip->read_buf(mtd, p, eccsize);
  558. /* read respective ecc from oob area */
  559. chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, -1);
  560. chip->read_buf(mtd, oob, eccbytes);
  561. /* read syndrome */
  562. chip->ecc.calculate(mtd, p, &ecc_calc[i]);
  563. data_pos += eccsize;
  564. oob_pos += eccbytes;
  565. }
  566. for (i = 0; i < chip->ecc.total; i++)
  567. ecc_code[i] = chip->oob_poi[eccpos[i]];
  568. eccsteps = chip->ecc.steps;
  569. p = buf;
  570. for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
  571. int stat;
  572. stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
  573. if (stat < 0)
  574. mtd->ecc_stats.failed++;
  575. else
  576. mtd->ecc_stats.corrected += stat;
  577. }
  578. return 0;
  579. }
  580. #endif /* CONFIG_NAND_OMAP_ELM */
  581. /*
  582. * OMAP3 BCH8 support (with BCH library)
  583. */
  584. #ifdef CONFIG_BCH
  585. /**
  586. * omap_correct_data_bch_sw - Decode received data and correct errors
  587. * @mtd: MTD device structure
  588. * @data: page data
  589. * @read_ecc: ecc read from nand flash
  590. * @calc_ecc: ecc read from HW ECC registers
  591. */
  592. static int omap_correct_data_bch_sw(struct mtd_info *mtd, u_char *data,
  593. u_char *read_ecc, u_char *calc_ecc)
  594. {
  595. int i, count;
  596. /* cannot correct more than 8 errors */
  597. unsigned int errloc[8];
  598. struct nand_chip *chip = mtd_to_nand(mtd);
  599. struct omap_nand_info *info = nand_get_controller_data(chip);
  600. count = decode_bch(info->control, NULL, 512, read_ecc, calc_ecc,
  601. NULL, errloc);
  602. if (count > 0) {
  603. /* correct errors */
  604. for (i = 0; i < count; i++) {
  605. /* correct data only, not ecc bytes */
  606. if (errloc[i] < 8*512)
  607. data[errloc[i]/8] ^= 1 << (errloc[i] & 7);
  608. debug("corrected bitflip %u\n", errloc[i]);
  609. #ifdef DEBUG
  610. puts("read_ecc: ");
  611. /*
  612. * BCH8 have 13 bytes of ECC; BCH4 needs adoption
  613. * here!
  614. */
  615. for (i = 0; i < 13; i++)
  616. printf("%02x ", read_ecc[i]);
  617. puts("\n");
  618. puts("calc_ecc: ");
  619. for (i = 0; i < 13; i++)
  620. printf("%02x ", calc_ecc[i]);
  621. puts("\n");
  622. #endif
  623. }
  624. } else if (count < 0) {
  625. puts("ecc unrecoverable error\n");
  626. }
  627. return count;
  628. }
  629. /**
  630. * omap_free_bch - Release BCH ecc resources
  631. * @mtd: MTD device structure
  632. */
  633. static void __maybe_unused omap_free_bch(struct mtd_info *mtd)
  634. {
  635. struct nand_chip *chip = mtd_to_nand(mtd);
  636. struct omap_nand_info *info = nand_get_controller_data(chip);
  637. if (info->control) {
  638. free_bch(info->control);
  639. info->control = NULL;
  640. }
  641. }
  642. #endif /* CONFIG_BCH */
  643. /**
  644. * omap_select_ecc_scheme - configures driver for particular ecc-scheme
  645. * @nand: NAND chip device structure
  646. * @ecc_scheme: ecc scheme to configure
  647. * @pagesize: number of main-area bytes per page of NAND device
  648. * @oobsize: number of OOB/spare bytes per page of NAND device
  649. */
  650. static int omap_select_ecc_scheme(struct nand_chip *nand,
  651. enum omap_ecc ecc_scheme, unsigned int pagesize, unsigned int oobsize) {
  652. struct omap_nand_info *info = nand_get_controller_data(nand);
  653. struct nand_ecclayout *ecclayout = &omap_ecclayout;
  654. int eccsteps = pagesize / SECTOR_BYTES;
  655. int i;
  656. switch (ecc_scheme) {
  657. case OMAP_ECC_HAM1_CODE_SW:
  658. debug("nand: selected OMAP_ECC_HAM1_CODE_SW\n");
  659. /* For this ecc-scheme, ecc.bytes, ecc.layout, ... are
  660. * initialized in nand_scan_tail(), so just set ecc.mode */
  661. info->control = NULL;
  662. nand->ecc.mode = NAND_ECC_SOFT;
  663. nand->ecc.layout = NULL;
  664. nand->ecc.size = 0;
  665. break;
  666. case OMAP_ECC_HAM1_CODE_HW:
  667. debug("nand: selected OMAP_ECC_HAM1_CODE_HW\n");
  668. /* check ecc-scheme requirements before updating ecc info */
  669. if ((3 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
  670. printf("nand: error: insufficient OOB: require=%d\n", (
  671. (3 * eccsteps) + BADBLOCK_MARKER_LENGTH));
  672. return -EINVAL;
  673. }
  674. info->control = NULL;
  675. /* populate ecc specific fields */
  676. memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
  677. nand->ecc.mode = NAND_ECC_HW;
  678. nand->ecc.strength = 1;
  679. nand->ecc.size = SECTOR_BYTES;
  680. nand->ecc.bytes = 3;
  681. nand->ecc.hwctl = omap_enable_hwecc;
  682. nand->ecc.correct = omap_correct_data;
  683. nand->ecc.calculate = omap_calculate_ecc;
  684. /* define ecc-layout */
  685. ecclayout->eccbytes = nand->ecc.bytes * eccsteps;
  686. for (i = 0; i < ecclayout->eccbytes; i++) {
  687. if (nand->options & NAND_BUSWIDTH_16)
  688. ecclayout->eccpos[i] = i + 2;
  689. else
  690. ecclayout->eccpos[i] = i + 1;
  691. }
  692. ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
  693. ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
  694. BADBLOCK_MARKER_LENGTH;
  695. break;
  696. case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
  697. #ifdef CONFIG_BCH
  698. debug("nand: selected OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n");
  699. /* check ecc-scheme requirements before updating ecc info */
  700. if ((13 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
  701. printf("nand: error: insufficient OOB: require=%d\n", (
  702. (13 * eccsteps) + BADBLOCK_MARKER_LENGTH));
  703. return -EINVAL;
  704. }
  705. /* check if BCH S/W library can be used for error detection */
  706. info->control = init_bch(13, 8, 0x201b);
  707. if (!info->control) {
  708. printf("nand: error: could not init_bch()\n");
  709. return -ENODEV;
  710. }
  711. /* populate ecc specific fields */
  712. memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
  713. nand->ecc.mode = NAND_ECC_HW;
  714. nand->ecc.strength = 8;
  715. nand->ecc.size = SECTOR_BYTES;
  716. nand->ecc.bytes = 13;
  717. nand->ecc.hwctl = omap_enable_hwecc;
  718. nand->ecc.correct = omap_correct_data_bch_sw;
  719. nand->ecc.calculate = omap_calculate_ecc;
  720. /* define ecc-layout */
  721. ecclayout->eccbytes = nand->ecc.bytes * eccsteps;
  722. ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH;
  723. for (i = 1; i < ecclayout->eccbytes; i++) {
  724. if (i % nand->ecc.bytes)
  725. ecclayout->eccpos[i] =
  726. ecclayout->eccpos[i - 1] + 1;
  727. else
  728. ecclayout->eccpos[i] =
  729. ecclayout->eccpos[i - 1] + 2;
  730. }
  731. ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
  732. ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
  733. BADBLOCK_MARKER_LENGTH;
  734. break;
  735. #else
  736. printf("nand: error: CONFIG_BCH required for ECC\n");
  737. return -EINVAL;
  738. #endif
  739. case OMAP_ECC_BCH8_CODE_HW:
  740. #ifdef CONFIG_NAND_OMAP_ELM
  741. debug("nand: selected OMAP_ECC_BCH8_CODE_HW\n");
  742. /* check ecc-scheme requirements before updating ecc info */
  743. if ((14 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
  744. printf("nand: error: insufficient OOB: require=%d\n", (
  745. (14 * eccsteps) + BADBLOCK_MARKER_LENGTH));
  746. return -EINVAL;
  747. }
  748. /* intialize ELM for ECC error detection */
  749. elm_init();
  750. info->control = NULL;
  751. /* populate ecc specific fields */
  752. memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
  753. nand->ecc.mode = NAND_ECC_HW;
  754. nand->ecc.strength = 8;
  755. nand->ecc.size = SECTOR_BYTES;
  756. nand->ecc.bytes = 14;
  757. nand->ecc.hwctl = omap_enable_hwecc;
  758. nand->ecc.correct = omap_correct_data_bch;
  759. nand->ecc.calculate = omap_calculate_ecc;
  760. nand->ecc.read_page = omap_read_page_bch;
  761. /* define ecc-layout */
  762. ecclayout->eccbytes = nand->ecc.bytes * eccsteps;
  763. for (i = 0; i < ecclayout->eccbytes; i++)
  764. ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH;
  765. ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
  766. ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
  767. BADBLOCK_MARKER_LENGTH;
  768. break;
  769. #else
  770. printf("nand: error: CONFIG_NAND_OMAP_ELM required for ECC\n");
  771. return -EINVAL;
  772. #endif
  773. case OMAP_ECC_BCH16_CODE_HW:
  774. #ifdef CONFIG_NAND_OMAP_ELM
  775. debug("nand: using OMAP_ECC_BCH16_CODE_HW\n");
  776. /* check ecc-scheme requirements before updating ecc info */
  777. if ((26 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
  778. printf("nand: error: insufficient OOB: require=%d\n", (
  779. (26 * eccsteps) + BADBLOCK_MARKER_LENGTH));
  780. return -EINVAL;
  781. }
  782. /* intialize ELM for ECC error detection */
  783. elm_init();
  784. /* populate ecc specific fields */
  785. nand->ecc.mode = NAND_ECC_HW;
  786. nand->ecc.size = SECTOR_BYTES;
  787. nand->ecc.bytes = 26;
  788. nand->ecc.strength = 16;
  789. nand->ecc.hwctl = omap_enable_hwecc;
  790. nand->ecc.correct = omap_correct_data_bch;
  791. nand->ecc.calculate = omap_calculate_ecc;
  792. nand->ecc.read_page = omap_read_page_bch;
  793. /* define ecc-layout */
  794. ecclayout->eccbytes = nand->ecc.bytes * eccsteps;
  795. for (i = 0; i < ecclayout->eccbytes; i++)
  796. ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH;
  797. ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
  798. ecclayout->oobfree[0].length = oobsize - nand->ecc.bytes -
  799. BADBLOCK_MARKER_LENGTH;
  800. break;
  801. #else
  802. printf("nand: error: CONFIG_NAND_OMAP_ELM required for ECC\n");
  803. return -EINVAL;
  804. #endif
  805. default:
  806. debug("nand: error: ecc scheme not enabled or supported\n");
  807. return -EINVAL;
  808. }
  809. /* nand_scan_tail() sets ham1 sw ecc; hw ecc layout is set by driver */
  810. if (ecc_scheme != OMAP_ECC_HAM1_CODE_SW)
  811. nand->ecc.layout = ecclayout;
  812. info->ecc_scheme = ecc_scheme;
  813. return 0;
  814. }
  815. #ifndef CONFIG_SPL_BUILD
  816. /*
  817. * omap_nand_switch_ecc - switch the ECC operation between different engines
  818. * (h/w and s/w) and different algorithms (hamming and BCHx)
  819. *
  820. * @hardware - true if one of the HW engines should be used
  821. * @eccstrength - the number of bits that could be corrected
  822. * (1 - hamming, 4 - BCH4, 8 - BCH8, 16 - BCH16)
  823. */
  824. int __maybe_unused omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength)
  825. {
  826. struct nand_chip *nand;
  827. struct mtd_info *mtd;
  828. int err = 0;
  829. if (nand_curr_device < 0 ||
  830. nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
  831. !nand_info[nand_curr_device]) {
  832. printf("nand: error: no NAND devices found\n");
  833. return -ENODEV;
  834. }
  835. mtd = nand_info[nand_curr_device];
  836. nand = mtd_to_nand(mtd);
  837. nand->options |= NAND_OWN_BUFFERS;
  838. nand->options &= ~NAND_SUBPAGE_READ;
  839. /* Setup the ecc configurations again */
  840. if (hardware) {
  841. if (eccstrength == 1) {
  842. err = omap_select_ecc_scheme(nand,
  843. OMAP_ECC_HAM1_CODE_HW,
  844. mtd->writesize, mtd->oobsize);
  845. } else if (eccstrength == 8) {
  846. err = omap_select_ecc_scheme(nand,
  847. OMAP_ECC_BCH8_CODE_HW,
  848. mtd->writesize, mtd->oobsize);
  849. } else if (eccstrength == 16) {
  850. err = omap_select_ecc_scheme(nand,
  851. OMAP_ECC_BCH16_CODE_HW,
  852. mtd->writesize, mtd->oobsize);
  853. } else {
  854. printf("nand: error: unsupported ECC scheme\n");
  855. return -EINVAL;
  856. }
  857. } else {
  858. if (eccstrength == 1) {
  859. err = omap_select_ecc_scheme(nand,
  860. OMAP_ECC_HAM1_CODE_SW,
  861. mtd->writesize, mtd->oobsize);
  862. } else if (eccstrength == 8) {
  863. err = omap_select_ecc_scheme(nand,
  864. OMAP_ECC_BCH8_CODE_HW_DETECTION_SW,
  865. mtd->writesize, mtd->oobsize);
  866. } else {
  867. printf("nand: error: unsupported ECC scheme\n");
  868. return -EINVAL;
  869. }
  870. }
  871. /* Update NAND handling after ECC mode switch */
  872. if (!err)
  873. err = nand_scan_tail(mtd);
  874. return err;
  875. }
  876. #endif /* CONFIG_SPL_BUILD */
  877. /*
  878. * Board-specific NAND initialization. The following members of the
  879. * argument are board-specific:
  880. * - IO_ADDR_R: address to read the 8 I/O lines of the flash device
  881. * - IO_ADDR_W: address to write the 8 I/O lines of the flash device
  882. * - cmd_ctrl: hardwarespecific function for accesing control-lines
  883. * - waitfunc: hardwarespecific function for accesing device ready/busy line
  884. * - ecc.hwctl: function to enable (reset) hardware ecc generator
  885. * - ecc.mode: mode of ecc, see defines
  886. * - chip_delay: chip dependent delay for transfering data from array to
  887. * read regs (tR)
  888. * - options: various chip options. They can partly be set to inform
  889. * nand_scan about special functionality. See the defines for further
  890. * explanation
  891. */
  892. int board_nand_init(struct nand_chip *nand)
  893. {
  894. int32_t gpmc_config = 0;
  895. int cs = cs_next++;
  896. int err = 0;
  897. /*
  898. * xloader/Uboot's gpmc configuration would have configured GPMC for
  899. * nand type of memory. The following logic scans and latches on to the
  900. * first CS with NAND type memory.
  901. * TBD: need to make this logic generic to handle multiple CS NAND
  902. * devices.
  903. */
  904. while (cs < GPMC_MAX_CS) {
  905. /* Check if NAND type is set */
  906. if ((readl(&gpmc_cfg->cs[cs].config1) & 0xC00) == 0x800) {
  907. /* Found it!! */
  908. break;
  909. }
  910. cs++;
  911. }
  912. if (cs >= GPMC_MAX_CS) {
  913. printf("nand: error: Unable to find NAND settings in "
  914. "GPMC Configuration - quitting\n");
  915. return -ENODEV;
  916. }
  917. gpmc_config = readl(&gpmc_cfg->config);
  918. /* Disable Write protect */
  919. gpmc_config |= 0x10;
  920. writel(gpmc_config, &gpmc_cfg->config);
  921. nand->IO_ADDR_R = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
  922. nand->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
  923. omap_nand_info[cs].control = NULL;
  924. omap_nand_info[cs].cs = cs;
  925. omap_nand_info[cs].ws = wscfg[cs];
  926. nand_set_controller_data(nand, &omap_nand_info[cs]);
  927. nand->cmd_ctrl = omap_nand_hwcontrol;
  928. nand->options |= NAND_NO_PADDING | NAND_CACHEPRG;
  929. nand->chip_delay = 100;
  930. nand->ecc.layout = &omap_ecclayout;
  931. /* configure driver and controller based on NAND device bus-width */
  932. gpmc_config = readl(&gpmc_cfg->cs[cs].config1);
  933. #if defined(CONFIG_SYS_NAND_BUSWIDTH_16BIT)
  934. nand->options |= NAND_BUSWIDTH_16;
  935. writel(gpmc_config | (0x1 << 12), &gpmc_cfg->cs[cs].config1);
  936. #else
  937. nand->options &= ~NAND_BUSWIDTH_16;
  938. writel(gpmc_config & ~(0x1 << 12), &gpmc_cfg->cs[cs].config1);
  939. #endif
  940. /* select ECC scheme */
  941. #if defined(CONFIG_NAND_OMAP_ECCSCHEME)
  942. err = omap_select_ecc_scheme(nand, CONFIG_NAND_OMAP_ECCSCHEME,
  943. CONFIG_SYS_NAND_PAGE_SIZE, CONFIG_SYS_NAND_OOBSIZE);
  944. #else
  945. /* pagesize and oobsize are not required to configure sw ecc-scheme */
  946. err = omap_select_ecc_scheme(nand, OMAP_ECC_HAM1_CODE_SW,
  947. 0, 0);
  948. #endif
  949. if (err)
  950. return err;
  951. #ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH
  952. nand->read_buf = omap_nand_read_prefetch;
  953. #else
  954. if (nand->options & NAND_BUSWIDTH_16)
  955. nand->read_buf = nand_read_buf16;
  956. else
  957. nand->read_buf = nand_read_buf;
  958. #endif
  959. nand->dev_ready = omap_dev_ready;
  960. return 0;
  961. }