omap_gpmc.c 26 KB

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