omap_gpmc.c 29 KB

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