omap_gpmc.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830
  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;
  28. static __maybe_unused struct nand_ecclayout omap_ecclayout;
  29. /*
  30. * omap_nand_hwcontrol - Set the address pointers corretly for the
  31. * following address/data/command operation
  32. */
  33. static void omap_nand_hwcontrol(struct mtd_info *mtd, int32_t cmd,
  34. uint32_t ctrl)
  35. {
  36. register struct nand_chip *this = mtd->priv;
  37. /*
  38. * Point the IO_ADDR to DATA and ADDRESS registers instead
  39. * of chip address
  40. */
  41. switch (ctrl) {
  42. case NAND_CTRL_CHANGE | NAND_CTRL_CLE:
  43. this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
  44. break;
  45. case NAND_CTRL_CHANGE | NAND_CTRL_ALE:
  46. this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_adr;
  47. break;
  48. case NAND_CTRL_CHANGE | NAND_NCE:
  49. this->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
  50. break;
  51. }
  52. if (cmd != NAND_CMD_NONE)
  53. writeb(cmd, this->IO_ADDR_W);
  54. }
  55. #ifdef CONFIG_SPL_BUILD
  56. /* Check wait pin as dev ready indicator */
  57. int omap_spl_dev_ready(struct mtd_info *mtd)
  58. {
  59. return gpmc_cfg->status & (1 << 8);
  60. }
  61. #endif
  62. /*
  63. * gen_true_ecc - This function will generate true ECC value, which
  64. * can be used when correcting data read from NAND flash memory core
  65. *
  66. * @ecc_buf: buffer to store ecc code
  67. *
  68. * @return: re-formatted ECC value
  69. */
  70. static uint32_t gen_true_ecc(uint8_t *ecc_buf)
  71. {
  72. return ecc_buf[0] | (ecc_buf[1] << 16) | ((ecc_buf[2] & 0xF0) << 20) |
  73. ((ecc_buf[2] & 0x0F) << 8);
  74. }
  75. /*
  76. * omap_correct_data - Compares the ecc read from nand spare area with ECC
  77. * registers values and corrects one bit error if it has occured
  78. * Further details can be had from OMAP TRM and the following selected links:
  79. * http://en.wikipedia.org/wiki/Hamming_code
  80. * http://www.cs.utexas.edu/users/plaxton/c/337/05f/slides/ErrorCorrection-4.pdf
  81. *
  82. * @mtd: MTD device structure
  83. * @dat: page data
  84. * @read_ecc: ecc read from nand flash
  85. * @calc_ecc: ecc read from ECC registers
  86. *
  87. * @return 0 if data is OK or corrected, else returns -1
  88. */
  89. static int __maybe_unused omap_correct_data(struct mtd_info *mtd, uint8_t *dat,
  90. uint8_t *read_ecc, uint8_t *calc_ecc)
  91. {
  92. uint32_t orig_ecc, new_ecc, res, hm;
  93. uint16_t parity_bits, byte;
  94. uint8_t bit;
  95. /* Regenerate the orginal ECC */
  96. orig_ecc = gen_true_ecc(read_ecc);
  97. new_ecc = gen_true_ecc(calc_ecc);
  98. /* Get the XOR of real ecc */
  99. res = orig_ecc ^ new_ecc;
  100. if (res) {
  101. /* Get the hamming width */
  102. hm = hweight32(res);
  103. /* Single bit errors can be corrected! */
  104. if (hm == 12) {
  105. /* Correctable data! */
  106. parity_bits = res >> 16;
  107. bit = (parity_bits & 0x7);
  108. byte = (parity_bits >> 3) & 0x1FF;
  109. /* Flip the bit to correct */
  110. dat[byte] ^= (0x1 << bit);
  111. } else if (hm == 1) {
  112. printf("Error: Ecc is wrong\n");
  113. /* ECC itself is corrupted */
  114. return 2;
  115. } else {
  116. /*
  117. * hm distance != parity pairs OR one, could mean 2 bit
  118. * error OR potentially be on a blank page..
  119. * orig_ecc: contains spare area data from nand flash.
  120. * new_ecc: generated ecc while reading data area.
  121. * Note: if the ecc = 0, all data bits from which it was
  122. * generated are 0xFF.
  123. * The 3 byte(24 bits) ecc is generated per 512byte
  124. * chunk of a page. If orig_ecc(from spare area)
  125. * is 0xFF && new_ecc(computed now from data area)=0x0,
  126. * this means that data area is 0xFF and spare area is
  127. * 0xFF. A sure sign of a erased page!
  128. */
  129. if ((orig_ecc == 0x0FFF0FFF) && (new_ecc == 0x00000000))
  130. return 0;
  131. printf("Error: Bad compare! failed\n");
  132. /* detected 2 bit error */
  133. return -1;
  134. }
  135. }
  136. return 0;
  137. }
  138. /*
  139. * Generic BCH interface
  140. */
  141. struct nand_bch_priv {
  142. uint8_t mode;
  143. uint8_t type;
  144. struct bch_control *control;
  145. enum omap_ecc ecc_scheme;
  146. };
  147. /* bch types */
  148. #define ECC_BCH4 0
  149. #define ECC_BCH8 1
  150. #define ECC_BCH16 2
  151. /*
  152. * This can be a single instance cause all current users have only one NAND
  153. * with nearly the same setup (BCH8, some with ELM and others with sw BCH
  154. * library).
  155. * When some users with other BCH strength will exists this have to change!
  156. */
  157. static __maybe_unused struct nand_bch_priv bch_priv = {
  158. .type = ECC_BCH8,
  159. .control = NULL
  160. };
  161. /*
  162. * omap_reverse_list - re-orders list elements in reverse order [internal]
  163. * @list: pointer to start of list
  164. * @length: length of list
  165. */
  166. void omap_reverse_list(u8 *list, unsigned int length)
  167. {
  168. unsigned int i, j;
  169. unsigned int half_length = length / 2;
  170. u8 tmp;
  171. for (i = 0, j = length - 1; i < half_length; i++, j--) {
  172. tmp = list[i];
  173. list[i] = list[j];
  174. list[j] = tmp;
  175. }
  176. }
  177. /*
  178. * omap_enable_hwecc - configures GPMC as per ECC scheme before read/write
  179. * @mtd: MTD device structure
  180. * @mode: Read/Write mode
  181. */
  182. __maybe_unused
  183. static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
  184. {
  185. struct nand_chip *nand = mtd->priv;
  186. struct nand_bch_priv *bch = nand->priv;
  187. unsigned int dev_width = (nand->options & NAND_BUSWIDTH_16) ? 1 : 0;
  188. unsigned int ecc_algo = 0;
  189. unsigned int bch_type = 0;
  190. unsigned int eccsize1 = 0x00, eccsize0 = 0x00, bch_wrapmode = 0x00;
  191. u32 ecc_size_config_val = 0;
  192. u32 ecc_config_val = 0;
  193. /* configure GPMC for specific ecc-scheme */
  194. switch (bch->ecc_scheme) {
  195. case OMAP_ECC_HAM1_CODE_SW:
  196. return;
  197. case OMAP_ECC_HAM1_CODE_HW:
  198. ecc_algo = 0x0;
  199. bch_type = 0x0;
  200. bch_wrapmode = 0x00;
  201. eccsize0 = 0xFF;
  202. eccsize1 = 0xFF;
  203. break;
  204. case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
  205. case OMAP_ECC_BCH8_CODE_HW:
  206. ecc_algo = 0x1;
  207. bch_type = 0x1;
  208. if (mode == NAND_ECC_WRITE) {
  209. bch_wrapmode = 0x01;
  210. eccsize0 = 0; /* extra bits in nibbles per sector */
  211. eccsize1 = 28; /* OOB bits in nibbles per sector */
  212. } else {
  213. bch_wrapmode = 0x01;
  214. eccsize0 = 26; /* ECC bits in nibbles per sector */
  215. eccsize1 = 2; /* non-ECC bits in nibbles per sector */
  216. }
  217. break;
  218. default:
  219. return;
  220. }
  221. /* Clear ecc and enable bits */
  222. writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
  223. /* Configure ecc size for BCH */
  224. ecc_size_config_val = (eccsize1 << 22) | (eccsize0 << 12);
  225. writel(ecc_size_config_val, &gpmc_cfg->ecc_size_config);
  226. /* Configure device details for BCH engine */
  227. ecc_config_val = ((ecc_algo << 16) | /* HAM1 | BCHx */
  228. (bch_type << 12) | /* BCH4/BCH8/BCH16 */
  229. (bch_wrapmode << 8) | /* wrap mode */
  230. (dev_width << 7) | /* bus width */
  231. (0x0 << 4) | /* number of sectors */
  232. (cs << 1) | /* ECC CS */
  233. (0x1)); /* enable ECC */
  234. writel(ecc_config_val, &gpmc_cfg->ecc_config);
  235. }
  236. /*
  237. * omap_calculate_ecc - Read ECC result
  238. * @mtd: MTD structure
  239. * @dat: unused
  240. * @ecc_code: ecc_code buffer
  241. * Using noninverted ECC can be considered ugly since writing a blank
  242. * page ie. padding will clear the ECC bytes. This is no problem as
  243. * long nobody is trying to write data on the seemingly unused page.
  244. * Reading an erased page will produce an ECC mismatch between
  245. * generated and read ECC bytes that has to be dealt with separately.
  246. * E.g. if page is 0xFF (fresh erased), and if HW ECC engine within GPMC
  247. * is used, the result of read will be 0x0 while the ECC offsets of the
  248. * spare area will be 0xFF which will result in an ECC mismatch.
  249. */
  250. static int omap_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
  251. uint8_t *ecc_code)
  252. {
  253. struct nand_chip *chip = mtd->priv;
  254. struct nand_bch_priv *bch = chip->priv;
  255. uint32_t *ptr, val = 0;
  256. int8_t i = 0, j;
  257. switch (bch->ecc_scheme) {
  258. case OMAP_ECC_HAM1_CODE_HW:
  259. val = readl(&gpmc_cfg->ecc1_result);
  260. ecc_code[0] = val & 0xFF;
  261. ecc_code[1] = (val >> 16) & 0xFF;
  262. ecc_code[2] = ((val >> 8) & 0x0F) | ((val >> 20) & 0xF0);
  263. break;
  264. #ifdef CONFIG_BCH
  265. case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
  266. #endif
  267. case OMAP_ECC_BCH8_CODE_HW:
  268. ptr = &gpmc_cfg->bch_result_0_3[0].bch_result_x[3];
  269. val = readl(ptr);
  270. ecc_code[i++] = (val >> 0) & 0xFF;
  271. ptr--;
  272. for (j = 0; j < 3; j++) {
  273. val = readl(ptr);
  274. ecc_code[i++] = (val >> 24) & 0xFF;
  275. ecc_code[i++] = (val >> 16) & 0xFF;
  276. ecc_code[i++] = (val >> 8) & 0xFF;
  277. ecc_code[i++] = (val >> 0) & 0xFF;
  278. ptr--;
  279. }
  280. break;
  281. default:
  282. return -EINVAL;
  283. }
  284. /* ECC scheme specific syndrome customizations */
  285. switch (bch->ecc_scheme) {
  286. case OMAP_ECC_HAM1_CODE_HW:
  287. break;
  288. #ifdef CONFIG_BCH
  289. case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
  290. for (i = 0; i < chip->ecc.bytes; i++)
  291. *(ecc_code + i) = *(ecc_code + i) ^
  292. bch8_polynomial[i];
  293. break;
  294. #endif
  295. case OMAP_ECC_BCH8_CODE_HW:
  296. ecc_code[chip->ecc.bytes - 1] = 0x00;
  297. break;
  298. default:
  299. return -EINVAL;
  300. }
  301. return 0;
  302. }
  303. #ifdef CONFIG_NAND_OMAP_ELM
  304. /*
  305. * omap_correct_data_bch - Compares the ecc read from nand spare area
  306. * with ECC registers values and corrects one bit error if it has occured
  307. *
  308. * @mtd: MTD device structure
  309. * @dat: page data
  310. * @read_ecc: ecc read from nand flash (ignored)
  311. * @calc_ecc: ecc read from ECC registers
  312. *
  313. * @return 0 if data is OK or corrected, else returns -1
  314. */
  315. static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
  316. uint8_t *read_ecc, uint8_t *calc_ecc)
  317. {
  318. struct nand_chip *chip = mtd->priv;
  319. struct nand_bch_priv *bch = chip->priv;
  320. uint32_t eccbytes = chip->ecc.bytes;
  321. uint32_t error_count = 0, error_max;
  322. uint32_t error_loc[8];
  323. uint32_t i, ecc_flag = 0;
  324. uint8_t count, err = 0;
  325. uint32_t byte_pos, bit_pos;
  326. /* check calculated ecc */
  327. for (i = 0; i < chip->ecc.bytes && !ecc_flag; i++) {
  328. if (calc_ecc[i] != 0x00)
  329. ecc_flag = 1;
  330. }
  331. if (!ecc_flag)
  332. return 0;
  333. /* check for whether its a erased-page */
  334. ecc_flag = 0;
  335. for (i = 0; i < chip->ecc.bytes && !ecc_flag; i++) {
  336. if (read_ecc[i] != 0xff)
  337. ecc_flag = 1;
  338. }
  339. if (!ecc_flag)
  340. return 0;
  341. /*
  342. * while reading ECC result we read it in big endian.
  343. * Hence while loading to ELM we have rotate to get the right endian.
  344. */
  345. switch (bch->ecc_scheme) {
  346. case OMAP_ECC_BCH8_CODE_HW:
  347. omap_reverse_list(calc_ecc, eccbytes - 1);
  348. break;
  349. default:
  350. return -EINVAL;
  351. }
  352. /* use elm module to check for errors */
  353. elm_config((enum bch_level)(bch->type));
  354. if (elm_check_error(calc_ecc, (enum bch_level)bch->type,
  355. &error_count, error_loc)) {
  356. printf("nand: error: uncorrectable ECC errors\n");
  357. return -EINVAL;
  358. }
  359. /* correct bch error */
  360. for (count = 0; count < error_count; count++) {
  361. switch (bch->type) {
  362. case ECC_BCH8:
  363. /* 14th byte in ECC is reserved to match ROM layout */
  364. error_max = SECTOR_BYTES + (eccbytes - 1);
  365. break;
  366. default:
  367. return -EINVAL;
  368. }
  369. byte_pos = error_max - (error_loc[count] / 8) - 1;
  370. bit_pos = error_loc[count] % 8;
  371. if (byte_pos < SECTOR_BYTES) {
  372. dat[byte_pos] ^= 1 << bit_pos;
  373. printf("nand: bit-flip corrected @data=%d\n", byte_pos);
  374. } else if (byte_pos < error_max) {
  375. read_ecc[byte_pos - SECTOR_BYTES] ^= 1 << bit_pos;
  376. printf("nand: bit-flip corrected @oob=%d\n", byte_pos -
  377. SECTOR_BYTES);
  378. } else {
  379. err = -EBADMSG;
  380. printf("nand: error: invalid bit-flip location\n");
  381. }
  382. }
  383. return (err) ? err : error_count;
  384. }
  385. /**
  386. * omap_read_page_bch - hardware ecc based page read function
  387. * @mtd: mtd info structure
  388. * @chip: nand chip info structure
  389. * @buf: buffer to store read data
  390. * @oob_required: caller expects OOB data read to chip->oob_poi
  391. * @page: page number to read
  392. *
  393. */
  394. static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
  395. uint8_t *buf, int oob_required, int page)
  396. {
  397. int i, eccsize = chip->ecc.size;
  398. int eccbytes = chip->ecc.bytes;
  399. int eccsteps = chip->ecc.steps;
  400. uint8_t *p = buf;
  401. uint8_t *ecc_calc = chip->buffers->ecccalc;
  402. uint8_t *ecc_code = chip->buffers->ecccode;
  403. uint32_t *eccpos = chip->ecc.layout->eccpos;
  404. uint8_t *oob = chip->oob_poi;
  405. uint32_t data_pos;
  406. uint32_t oob_pos;
  407. data_pos = 0;
  408. /* oob area start */
  409. oob_pos = (eccsize * eccsteps) + chip->ecc.layout->eccpos[0];
  410. oob += chip->ecc.layout->eccpos[0];
  411. for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize,
  412. oob += eccbytes) {
  413. chip->ecc.hwctl(mtd, NAND_ECC_READ);
  414. /* read data */
  415. chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_pos, page);
  416. chip->read_buf(mtd, p, eccsize);
  417. /* read respective ecc from oob area */
  418. chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, page);
  419. chip->read_buf(mtd, oob, eccbytes);
  420. /* read syndrome */
  421. chip->ecc.calculate(mtd, p, &ecc_calc[i]);
  422. data_pos += eccsize;
  423. oob_pos += eccbytes;
  424. }
  425. for (i = 0; i < chip->ecc.total; i++)
  426. ecc_code[i] = chip->oob_poi[eccpos[i]];
  427. eccsteps = chip->ecc.steps;
  428. p = buf;
  429. for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
  430. int stat;
  431. stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
  432. if (stat < 0)
  433. mtd->ecc_stats.failed++;
  434. else
  435. mtd->ecc_stats.corrected += stat;
  436. }
  437. return 0;
  438. }
  439. #endif /* CONFIG_NAND_OMAP_ELM */
  440. /*
  441. * OMAP3 BCH8 support (with BCH library)
  442. */
  443. #ifdef CONFIG_BCH
  444. /**
  445. * omap_correct_data_bch_sw - Decode received data and correct errors
  446. * @mtd: MTD device structure
  447. * @data: page data
  448. * @read_ecc: ecc read from nand flash
  449. * @calc_ecc: ecc read from HW ECC registers
  450. */
  451. static int omap_correct_data_bch_sw(struct mtd_info *mtd, u_char *data,
  452. u_char *read_ecc, u_char *calc_ecc)
  453. {
  454. int i, count;
  455. /* cannot correct more than 8 errors */
  456. unsigned int errloc[8];
  457. struct nand_chip *chip = mtd->priv;
  458. struct nand_bch_priv *chip_priv = chip->priv;
  459. struct bch_control *bch = chip_priv->control;
  460. count = decode_bch(bch, NULL, 512, read_ecc, calc_ecc, NULL, errloc);
  461. if (count > 0) {
  462. /* correct errors */
  463. for (i = 0; i < count; i++) {
  464. /* correct data only, not ecc bytes */
  465. if (errloc[i] < 8*512)
  466. data[errloc[i]/8] ^= 1 << (errloc[i] & 7);
  467. printf("corrected bitflip %u\n", errloc[i]);
  468. #ifdef DEBUG
  469. puts("read_ecc: ");
  470. /*
  471. * BCH8 have 13 bytes of ECC; BCH4 needs adoption
  472. * here!
  473. */
  474. for (i = 0; i < 13; i++)
  475. printf("%02x ", read_ecc[i]);
  476. puts("\n");
  477. puts("calc_ecc: ");
  478. for (i = 0; i < 13; i++)
  479. printf("%02x ", calc_ecc[i]);
  480. puts("\n");
  481. #endif
  482. }
  483. } else if (count < 0) {
  484. puts("ecc unrecoverable error\n");
  485. }
  486. return count;
  487. }
  488. /**
  489. * omap_free_bch - Release BCH ecc resources
  490. * @mtd: MTD device structure
  491. */
  492. static void __maybe_unused omap_free_bch(struct mtd_info *mtd)
  493. {
  494. struct nand_chip *chip = mtd->priv;
  495. struct nand_bch_priv *chip_priv = chip->priv;
  496. struct bch_control *bch = NULL;
  497. if (chip_priv)
  498. bch = chip_priv->control;
  499. if (bch) {
  500. free_bch(bch);
  501. chip_priv->control = NULL;
  502. }
  503. }
  504. #endif /* CONFIG_BCH */
  505. /**
  506. * omap_select_ecc_scheme - configures driver for particular ecc-scheme
  507. * @nand: NAND chip device structure
  508. * @ecc_scheme: ecc scheme to configure
  509. * @pagesize: number of main-area bytes per page of NAND device
  510. * @oobsize: number of OOB/spare bytes per page of NAND device
  511. */
  512. static int omap_select_ecc_scheme(struct nand_chip *nand,
  513. enum omap_ecc ecc_scheme, unsigned int pagesize, unsigned int oobsize) {
  514. struct nand_bch_priv *bch = nand->priv;
  515. struct nand_ecclayout *ecclayout = &omap_ecclayout;
  516. int eccsteps = pagesize / SECTOR_BYTES;
  517. int i;
  518. switch (ecc_scheme) {
  519. case OMAP_ECC_HAM1_CODE_SW:
  520. debug("nand: selected OMAP_ECC_HAM1_CODE_SW\n");
  521. /* For this ecc-scheme, ecc.bytes, ecc.layout, ... are
  522. * initialized in nand_scan_tail(), so just set ecc.mode */
  523. bch_priv.control = NULL;
  524. bch_priv.type = 0;
  525. nand->ecc.mode = NAND_ECC_SOFT;
  526. nand->ecc.layout = NULL;
  527. nand->ecc.size = 0;
  528. bch->ecc_scheme = OMAP_ECC_HAM1_CODE_SW;
  529. break;
  530. case OMAP_ECC_HAM1_CODE_HW:
  531. debug("nand: selected OMAP_ECC_HAM1_CODE_HW\n");
  532. /* check ecc-scheme requirements before updating ecc info */
  533. if ((3 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
  534. printf("nand: error: insufficient OOB: require=%d\n", (
  535. (3 * eccsteps) + BADBLOCK_MARKER_LENGTH));
  536. return -EINVAL;
  537. }
  538. bch_priv.control = NULL;
  539. bch_priv.type = 0;
  540. /* populate ecc specific fields */
  541. memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
  542. nand->ecc.mode = NAND_ECC_HW;
  543. nand->ecc.strength = 1;
  544. nand->ecc.size = SECTOR_BYTES;
  545. nand->ecc.bytes = 3;
  546. nand->ecc.hwctl = omap_enable_hwecc;
  547. nand->ecc.correct = omap_correct_data;
  548. nand->ecc.calculate = omap_calculate_ecc;
  549. /* define ecc-layout */
  550. ecclayout->eccbytes = nand->ecc.bytes * eccsteps;
  551. for (i = 0; i < ecclayout->eccbytes; i++) {
  552. if (nand->options & NAND_BUSWIDTH_16)
  553. ecclayout->eccpos[i] = i + 2;
  554. else
  555. ecclayout->eccpos[i] = i + 1;
  556. }
  557. ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
  558. ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
  559. BADBLOCK_MARKER_LENGTH;
  560. bch->ecc_scheme = OMAP_ECC_HAM1_CODE_HW;
  561. break;
  562. case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
  563. #ifdef CONFIG_BCH
  564. debug("nand: selected OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n");
  565. /* check ecc-scheme requirements before updating ecc info */
  566. if ((13 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
  567. printf("nand: error: insufficient OOB: require=%d\n", (
  568. (13 * eccsteps) + BADBLOCK_MARKER_LENGTH));
  569. return -EINVAL;
  570. }
  571. /* check if BCH S/W library can be used for error detection */
  572. bch_priv.control = init_bch(13, 8, 0x201b);
  573. if (!bch_priv.control) {
  574. printf("nand: error: could not init_bch()\n");
  575. return -ENODEV;
  576. }
  577. bch_priv.type = ECC_BCH8;
  578. /* populate ecc specific fields */
  579. memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
  580. nand->ecc.mode = NAND_ECC_HW;
  581. nand->ecc.strength = 8;
  582. nand->ecc.size = SECTOR_BYTES;
  583. nand->ecc.bytes = 13;
  584. nand->ecc.hwctl = omap_enable_hwecc;
  585. nand->ecc.correct = omap_correct_data_bch_sw;
  586. nand->ecc.calculate = omap_calculate_ecc;
  587. /* define ecc-layout */
  588. ecclayout->eccbytes = nand->ecc.bytes * eccsteps;
  589. ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH;
  590. for (i = 1; i < ecclayout->eccbytes; i++) {
  591. if (i % nand->ecc.bytes)
  592. ecclayout->eccpos[i] =
  593. ecclayout->eccpos[i - 1] + 1;
  594. else
  595. ecclayout->eccpos[i] =
  596. ecclayout->eccpos[i - 1] + 2;
  597. }
  598. ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
  599. ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
  600. BADBLOCK_MARKER_LENGTH;
  601. bch->ecc_scheme = OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
  602. break;
  603. #else
  604. printf("nand: error: CONFIG_BCH required for ECC\n");
  605. return -EINVAL;
  606. #endif
  607. case OMAP_ECC_BCH8_CODE_HW:
  608. #ifdef CONFIG_NAND_OMAP_ELM
  609. debug("nand: selected OMAP_ECC_BCH8_CODE_HW\n");
  610. /* check ecc-scheme requirements before updating ecc info */
  611. if ((14 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
  612. printf("nand: error: insufficient OOB: require=%d\n", (
  613. (14 * eccsteps) + BADBLOCK_MARKER_LENGTH));
  614. return -EINVAL;
  615. }
  616. /* intialize ELM for ECC error detection */
  617. elm_init();
  618. bch_priv.type = ECC_BCH8;
  619. /* populate ecc specific fields */
  620. memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
  621. nand->ecc.mode = NAND_ECC_HW;
  622. nand->ecc.strength = 8;
  623. nand->ecc.size = SECTOR_BYTES;
  624. nand->ecc.bytes = 14;
  625. nand->ecc.hwctl = omap_enable_hwecc;
  626. nand->ecc.correct = omap_correct_data_bch;
  627. nand->ecc.calculate = omap_calculate_ecc;
  628. nand->ecc.read_page = omap_read_page_bch;
  629. /* define ecc-layout */
  630. ecclayout->eccbytes = nand->ecc.bytes * eccsteps;
  631. for (i = 0; i < ecclayout->eccbytes; i++)
  632. ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH;
  633. ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
  634. ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
  635. BADBLOCK_MARKER_LENGTH;
  636. bch->ecc_scheme = OMAP_ECC_BCH8_CODE_HW;
  637. break;
  638. #else
  639. printf("nand: error: CONFIG_NAND_OMAP_ELM required for ECC\n");
  640. return -EINVAL;
  641. #endif
  642. default:
  643. debug("nand: error: ecc scheme not enabled or supported\n");
  644. return -EINVAL;
  645. }
  646. /* nand_scan_tail() sets ham1 sw ecc; hw ecc layout is set by driver */
  647. if (ecc_scheme != OMAP_ECC_HAM1_CODE_SW)
  648. nand->ecc.layout = ecclayout;
  649. return 0;
  650. }
  651. #ifndef CONFIG_SPL_BUILD
  652. /*
  653. * omap_nand_switch_ecc - switch the ECC operation between different engines
  654. * (h/w and s/w) and different algorithms (hamming and BCHx)
  655. *
  656. * @hardware - true if one of the HW engines should be used
  657. * @eccstrength - the number of bits that could be corrected
  658. * (1 - hamming, 4 - BCH4, 8 - BCH8, 16 - BCH16)
  659. */
  660. int __maybe_unused omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength)
  661. {
  662. struct nand_chip *nand;
  663. struct mtd_info *mtd;
  664. int err = 0;
  665. if (nand_curr_device < 0 ||
  666. nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
  667. !nand_info[nand_curr_device].name) {
  668. printf("nand: error: no NAND devices found\n");
  669. return -ENODEV;
  670. }
  671. mtd = &nand_info[nand_curr_device];
  672. nand = mtd->priv;
  673. nand->options |= NAND_OWN_BUFFERS;
  674. nand->options &= ~NAND_SUBPAGE_READ;
  675. /* Setup the ecc configurations again */
  676. if (hardware) {
  677. if (eccstrength == 1) {
  678. err = omap_select_ecc_scheme(nand,
  679. OMAP_ECC_HAM1_CODE_HW,
  680. mtd->writesize, mtd->oobsize);
  681. } else if (eccstrength == 8) {
  682. err = omap_select_ecc_scheme(nand,
  683. OMAP_ECC_BCH8_CODE_HW,
  684. mtd->writesize, mtd->oobsize);
  685. } else {
  686. printf("nand: error: unsupported ECC scheme\n");
  687. return -EINVAL;
  688. }
  689. } else {
  690. err = omap_select_ecc_scheme(nand, OMAP_ECC_HAM1_CODE_SW,
  691. mtd->writesize, mtd->oobsize);
  692. }
  693. /* Update NAND handling after ECC mode switch */
  694. if (!err)
  695. err = nand_scan_tail(mtd);
  696. return err;
  697. }
  698. #endif /* CONFIG_SPL_BUILD */
  699. /*
  700. * Board-specific NAND initialization. The following members of the
  701. * argument are board-specific:
  702. * - IO_ADDR_R: address to read the 8 I/O lines of the flash device
  703. * - IO_ADDR_W: address to write the 8 I/O lines of the flash device
  704. * - cmd_ctrl: hardwarespecific function for accesing control-lines
  705. * - waitfunc: hardwarespecific function for accesing device ready/busy line
  706. * - ecc.hwctl: function to enable (reset) hardware ecc generator
  707. * - ecc.mode: mode of ecc, see defines
  708. * - chip_delay: chip dependent delay for transfering data from array to
  709. * read regs (tR)
  710. * - options: various chip options. They can partly be set to inform
  711. * nand_scan about special functionality. See the defines for further
  712. * explanation
  713. */
  714. int board_nand_init(struct nand_chip *nand)
  715. {
  716. int32_t gpmc_config = 0;
  717. cs = 0;
  718. int err = 0;
  719. /*
  720. * xloader/Uboot's gpmc configuration would have configured GPMC for
  721. * nand type of memory. The following logic scans and latches on to the
  722. * first CS with NAND type memory.
  723. * TBD: need to make this logic generic to handle multiple CS NAND
  724. * devices.
  725. */
  726. while (cs < GPMC_MAX_CS) {
  727. /* Check if NAND type is set */
  728. if ((readl(&gpmc_cfg->cs[cs].config1) & 0xC00) == 0x800) {
  729. /* Found it!! */
  730. break;
  731. }
  732. cs++;
  733. }
  734. if (cs >= GPMC_MAX_CS) {
  735. printf("nand: error: Unable to find NAND settings in "
  736. "GPMC Configuration - quitting\n");
  737. return -ENODEV;
  738. }
  739. gpmc_config = readl(&gpmc_cfg->config);
  740. /* Disable Write protect */
  741. gpmc_config |= 0x10;
  742. writel(gpmc_config, &gpmc_cfg->config);
  743. nand->IO_ADDR_R = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
  744. nand->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
  745. nand->priv = &bch_priv;
  746. nand->cmd_ctrl = omap_nand_hwcontrol;
  747. nand->options |= NAND_NO_PADDING | NAND_CACHEPRG;
  748. /* If we are 16 bit dev, our gpmc config tells us that */
  749. if ((readl(&gpmc_cfg->cs[cs].config1) & 0x3000) == 0x1000)
  750. nand->options |= NAND_BUSWIDTH_16;
  751. nand->chip_delay = 100;
  752. nand->ecc.layout = &omap_ecclayout;
  753. /* select ECC scheme */
  754. #if defined(CONFIG_NAND_OMAP_ECCSCHEME)
  755. err = omap_select_ecc_scheme(nand, CONFIG_NAND_OMAP_ECCSCHEME,
  756. CONFIG_SYS_NAND_PAGE_SIZE, CONFIG_SYS_NAND_OOBSIZE);
  757. #else
  758. /* pagesize and oobsize are not required to configure sw ecc-scheme */
  759. err = omap_select_ecc_scheme(nand, OMAP_ECC_HAM1_CODE_SW,
  760. 0, 0);
  761. #endif
  762. if (err)
  763. return err;
  764. #ifdef CONFIG_SPL_BUILD
  765. if (nand->options & NAND_BUSWIDTH_16)
  766. nand->read_buf = nand_read_buf16;
  767. else
  768. nand->read_buf = nand_read_buf;
  769. nand->dev_ready = omap_spl_dev_ready;
  770. #endif
  771. return 0;
  772. }