ark_nand.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181
  1. /*
  2. * (C) Copyright 2006 DENX Software Engineering
  3. * (C) Copyright 2012 Ho Ka Leung, ASTRI, kalho@astri.org
  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 <linux/err.h>
  25. #include <nand.h>
  26. #include <linux/mtd/mtd.h>
  27. #include <linux/mtd/nand_ecc.h>
  28. #include <asm/arch/ark-nand.h>
  29. #include <asm/io.h>
  30. #include <errno.h>
  31. #define BIT_7_ECC_BYTE 13
  32. #define BIT_13_ECC_BYTE 23
  33. #define BIT_24_ECC_BYTE 42
  34. #define BIT_30_ECC_BYTE 53
  35. #define BIT_48_ECC_BYTE 84
  36. #define EC809_NAND_ADDR_UNALIGNED 0x1
  37. #define EC809_NAND_LEN_UNALIGNED 0x2
  38. //#define USE_DATA_INTERFACE 1
  39. //#define DEBUG
  40. #if 0
  41. static struct nand_ecclayout nand_hw_eccoob_16 = { /* small page 512 byte with 16 byte oob */
  42. .eccbytes = BIT_7_ECC_BYTE,
  43. .eccpos = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
  44. .oobfree = {}
  45. };
  46. static struct nand_ecclayout nand_hw_eccoob_64 = { /* large page 2k with 64 byte oob */
  47. .eccbytes = BIT_7_ECC_BYTE,
  48. .eccpos = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  49. 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
  50. },
  51. .oobfree = { {32, 32} }
  52. };
  53. #endif
  54. static struct nand_ecclayout nand_hw_eccoob_bootstrap = { /* large page 2k with 64 byte oob */
  55. .eccbytes = BIT_7_ECC_BYTE,
  56. .eccpos = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  57. 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  58. 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
  59. 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54
  60. },
  61. .oobfree = { {56, 8} }
  62. };
  63. static struct nand_ecclayout nand_hw_eccoob_64 = { /* large page 2k with 64 byte oob */
  64. .eccbytes = BIT_13_ECC_BYTE,
  65. .eccpos = {18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
  66. 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
  67. 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
  68. },
  69. .oobfree = { {2, 16} }
  70. };
  71. //1024--24
  72. static struct nand_ecclayout nand_hw_eccoob_128 = { /* large page 2k with 64 byte oob */
  73. .eccbytes = BIT_24_ECC_BYTE,
  74. .eccpos = {44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  75. 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
  76. 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
  77. 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
  78. 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
  79. 124, 125, 126, 127
  80. },
  81. .oobfree = { {2, 42} }
  82. };
  83. //1024--24
  84. static struct nand_ecclayout nand_hw_eccoob_256 = {
  85. .eccbytes = BIT_24_ECC_BYTE,
  86. .eccpos = {88, 89,
  87. 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
  88. 100, 101, 102, 103, 104, 105,106, 107, 108, 109,
  89. 110, 111, 112, 113, 114, 115,116, 117, 118, 119,
  90. 120, 121, 122, 123, 124, 125,126, 127, 128, 129,
  91. 130, 131, 132, 133, 134, 135,136, 137, 138, 139,
  92. 140, 141, 142, 143, 144, 145,146, 147, 148, 149,
  93. 150, 151, 152, 153, 154, 155,156, 157, 158, 159,
  94. 160, 161, 162, 163, 164, 165,166, 167, 168, 169,
  95. 170, 171, 172, 173, 174, 175,176, 177, 178, 179,
  96. 180, 181, 182, 183, 184, 185,186, 187, 188, 189,
  97. 190, 191, 192, 193, 194, 195,196, 197, 198, 199,
  98. 200, 201, 202, 203, 204, 205,206, 207, 208, 209,
  99. 210, 211, 212, 213, 214, 215,216, 217, 218, 219,
  100. 220, 221, 222, 223, 224, 225,226, 227, 228, 229,
  101. 230, 231, 232, 233, 234, 235,236, 237, 238, 239,
  102. 240, 241, 242, 243, 244, 245,246, 247, 248, 249,
  103. 250, 251, 252, 253, 254, 255,
  104. },
  105. .oobfree = { {2, 86} }
  106. };
  107. /*static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
  108. static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
  109. static struct nand_bbt_descr Ark_OOB128_bbt_main_descr = {
  110. .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
  111. | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
  112. .offs = 96,
  113. .len = 4,
  114. .veroffs = 100,
  115. .maxblocks = 4,
  116. .pattern = bbt_pattern
  117. };
  118. static struct nand_bbt_descr Ark_OOB128_bbt_mirror_descr = {
  119. .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
  120. | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
  121. .offs = 96,
  122. .len = 4,
  123. .veroffs = 100,
  124. .maxblocks = 4,
  125. .pattern = mirror_pattern
  126. };
  127. static struct nand_bbt_descr Ark_OOB64_bbt_main_descr = {
  128. .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
  129. | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
  130. .offs = 55,
  131. .len = 4,
  132. .veroffs = 59,
  133. .maxblocks = 4,
  134. .pattern = bbt_pattern
  135. };
  136. static struct nand_bbt_descr Ark_OOB64_bbt_mirror_descr = {
  137. .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
  138. | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
  139. .offs =55,
  140. .len = 4,
  141. .veroffs = 59,
  142. .maxblocks = 4,
  143. .pattern = mirror_pattern
  144. };*/
  145. struct ark_nand {
  146. struct mtd_info mtd;
  147. struct nand_chip *nand;
  148. int max_chip;
  149. int chip_num;
  150. int raw_rw;
  151. };
  152. static struct ark_nand ark_nand_info = {0};
  153. static void ark_nand_select_chip(struct mtd_info *mtd, int chipnr)
  154. {
  155. struct nand_chip *chip = mtd->priv;
  156. struct ark_nand *nand_info = chip->priv;
  157. unsigned int nand_cr;
  158. debug("ark_nand_select_chip\n");
  159. if(chipnr == -1){
  160. chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
  161. return;
  162. }
  163. if(chipnr < nand_info->max_chip){
  164. nand_cr = readl(rNAND_CR);
  165. nand_cr &= ~(0x3<<23);
  166. nand_cr |= (chipnr<<23);
  167. writel(nand_cr, rNAND_CR);
  168. nand_info->chip_num = chipnr;
  169. }
  170. return;
  171. }
  172. static void ark_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
  173. {
  174. struct nand_chip *chip = mtd->priv;
  175. debug("ark_nand_hwcontrol\n");
  176. /*
  177. * Point the IO_ADDR to DATA and ADDRESS registers instead
  178. * of chip address
  179. */
  180. switch (ctrl) {
  181. case NAND_CTRL_CHANGE | NAND_CTRL_CLE:
  182. debug("NAND_CTRL_CLE\n");
  183. chip->IO_ADDR_W = (void __iomem *)rNAND_CLE_WR;
  184. break;
  185. case NAND_CTRL_CHANGE | NAND_CTRL_ALE:
  186. debug("NAND_CTRL_ALE\n");
  187. chip->IO_ADDR_W = (void __iomem *)rNAND_ALE_WR;
  188. break;
  189. case NAND_CTRL_CHANGE:
  190. debug("NAND_CTRL_DATA\n");
  191. chip->IO_ADDR_W = (void __iomem *)rNAND_DATA; /* Must be a 32-bit read at ARK1680 NFC */
  192. break;
  193. }
  194. if(ctrl & NAND_NCE){
  195. ; /* TODO: Chip Enable activate */
  196. }else{
  197. ; /* TODO: Chip Enable de-activate */
  198. }
  199. /*#ifndef USE_DATA_INTERFACE
  200. if ((cmd == NAND_CMD_READ0 || cmd == NAND_CMD_SEQIN) && (ctrl & NAND_CLE)) {
  201. writel(1, rBCH_NAND_STATUS);
  202. }
  203. #endif*/
  204. if (cmd != NAND_CMD_NONE){
  205. debug("cmd 0x%X\n",cmd);
  206. writeb(cmd, chip->IO_ADDR_W);
  207. }
  208. }
  209. /**
  210. * ark_nand_read_buf - read chip data into buffer
  211. * @mtd: MTD device structure
  212. * @buf: buffer to store date
  213. * @len: number of bytes to read
  214. *
  215. * Default read function for 8bit buswith
  216. */
  217. static int rcount = 0;
  218. void ark_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
  219. {
  220. int i;
  221. unsigned int* tmp_buf32;
  222. uint8_t* tmp_buf8;
  223. unsigned int unaligned_flag = 0;
  224. unsigned int excess_len;
  225. unsigned int addr_aligned;
  226. unsigned int read_addr = rNAND_DATA;
  227. struct nand_chip *chip = (struct nand_chip *)mtd->priv;
  228. struct ark_nand *nand_info = chip->priv;
  229. union{
  230. unsigned int word;
  231. unsigned char byte[4];
  232. } tmp;
  233. debug("ark_nand_read_buf\n");
  234. addr_aligned = ((unsigned int)buf)%4;
  235. if(addr_aligned){ // Address not aligned to 32 bit word
  236. debug("EC809_NAND_ADDR_UNALIGNED\n");
  237. unaligned_flag |= EC809_NAND_ADDR_UNALIGNED;
  238. }
  239. excess_len = len % 0x4;
  240. if(excess_len){ // length not aligned to 32 bit word
  241. debug("EC809_NAND_LEN_UNALIGNED\n");
  242. unaligned_flag |= EC809_NAND_LEN_UNALIGNED;
  243. }
  244. #ifndef USE_DATA_INTERFACE
  245. if (len >= chip->ecc.size && !nand_info->raw_rw)
  246. read_addr = rNAND_RX_FIFO;
  247. #endif
  248. switch(unaligned_flag){
  249. case 0:
  250. tmp_buf32 = (unsigned int*)buf;
  251. for (i = 0; i < len >> 2; i++){
  252. *tmp_buf32++ = readl(read_addr);
  253. debug("0. tmp_buf32 0x%08X\n",*(tmp_buf32-1));
  254. if(rcount)
  255. printf("%d %d 0x%08X\n",len, i, *(tmp_buf32-1));
  256. }
  257. break;
  258. case 1:
  259. tmp_buf8 = buf;
  260. for (i = 0; i < len >> 2; i++){
  261. tmp.word = readl(read_addr);
  262. debug("0. tmp.word 0x%08X\n",tmp.word);
  263. *tmp_buf8++ = tmp.byte[0];
  264. *tmp_buf8++ = tmp.byte[1];
  265. *tmp_buf8++ = tmp.byte[2];
  266. *tmp_buf8++ = tmp.byte[3];
  267. }
  268. break;
  269. case 2:
  270. tmp_buf32 = (unsigned int*)buf;
  271. for (i = 0; i < len >> 2; i++){
  272. *tmp_buf32++ = readl(read_addr);
  273. debug("1. tmp_buf32 0x%08X\n",*(tmp_buf32-1));
  274. }
  275. /* read the excess byte */
  276. tmp_buf8 = (uint8_t*)tmp_buf32;
  277. tmp.word = readl(read_addr);
  278. debug("1. tmp.word 0x%08X\n",tmp.word);
  279. for(i = 0; i < excess_len; i++){
  280. *tmp_buf8++ = tmp.byte[i];
  281. }
  282. break;
  283. case 3:
  284. tmp_buf8 = buf;
  285. for (i = 0; i < len >> 2; i++){
  286. tmp.word = readl(read_addr);
  287. debug("2. tmp.word 0x%08X\n",tmp.word);
  288. *tmp_buf8++ = tmp.byte[0];
  289. *tmp_buf8++ = tmp.byte[1];
  290. *tmp_buf8++ = tmp.byte[2];
  291. *tmp_buf8++ = tmp.byte[3];
  292. }
  293. tmp.word = readl(read_addr);
  294. debug("3. tmp.word 0x%08X\n",tmp.word);
  295. for(i = 0; i < excess_len; i++){
  296. *tmp_buf8++ = tmp.byte[i];
  297. }
  298. break;
  299. }
  300. }
  301. /**
  302. * ark_nand_write_buf - write buffer to chip
  303. * @mtd: MTD device structure
  304. * @buf: data buffer
  305. * @len: number of bytes to write
  306. *
  307. * Default write function for 8bit buswith
  308. */
  309. void ark_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
  310. {
  311. int i;
  312. unsigned int* tmp_buf32;
  313. uint8_t* tmp_buf8;
  314. unsigned int unaligned_flag = 0;
  315. unsigned int excess_len;
  316. unsigned int addr_aligned;
  317. unsigned int write_addr = rNAND_DATA;
  318. struct nand_chip *chip = (struct nand_chip *)mtd->priv;
  319. struct ark_nand *nand_info = chip->priv;
  320. union{
  321. unsigned int word;
  322. unsigned char byte[4];
  323. } tmp;
  324. debug("ark_nand_write_buf\n");
  325. tmp.word = 0xFFFFFFFF;
  326. addr_aligned = (unsigned int)buf % 4;
  327. if(addr_aligned){ // Address not aligned to 32 bit word
  328. unaligned_flag |= EC809_NAND_ADDR_UNALIGNED;
  329. }
  330. excess_len = len % 0x4;
  331. if(excess_len){ // length not aligned to 32 bit word
  332. unaligned_flag |= EC809_NAND_LEN_UNALIGNED;
  333. }
  334. #ifndef USE_DATA_INTERFACE
  335. if (len >= chip->ecc.size && !nand_info->raw_rw)
  336. write_addr = rNAND_TX_FIFO;
  337. #endif
  338. switch(unaligned_flag){
  339. case 0:
  340. tmp_buf32 = (unsigned int*)buf;
  341. for (i = 0; i < len >> 2; i++){
  342. debug("0 rNAND_DATA = 0x%08X\n",*tmp_buf32);
  343. writel(*tmp_buf32++, write_addr);
  344. }
  345. break;
  346. case 1:
  347. tmp_buf8 = (uint8_t*)buf;
  348. for (i = 0; i < len >> 2; i++){
  349. tmp.byte[0] = *tmp_buf8++;
  350. tmp.byte[1] = *tmp_buf8++;
  351. tmp.byte[2] = *tmp_buf8++;
  352. tmp.byte[3] = *tmp_buf8++;
  353. debug("1 rNAND_DATA = 0x%08X\n",tmp.word);
  354. writel(tmp.word, write_addr);
  355. }
  356. break;
  357. case 2:
  358. tmp_buf32 = (unsigned int*)buf;
  359. for (i = 0; i < len >> 2; i++){
  360. debug("2 rNAND_DATA = 0x%08X\n",*tmp_buf32);
  361. writel(*tmp_buf32++, write_addr);
  362. }
  363. /* write the excess byte */
  364. tmp_buf8 = (uint8_t*)tmp_buf32;
  365. tmp.word = 0xFFFFFFFF;
  366. for(i = 0; i < excess_len; i++){
  367. *tmp_buf8++ = tmp.byte[i];
  368. }
  369. debug("2.1 rNAND_DATA = 0x%08X\n",tmp.word);
  370. writel(tmp.word, write_addr);
  371. break;
  372. case 3:
  373. tmp_buf8 = (uint8_t*)buf;
  374. for (i = 0; i < len >> 2; i++){
  375. tmp.byte[0] = *tmp_buf8++;
  376. tmp.byte[1] = *tmp_buf8++;
  377. tmp.byte[2] = *tmp_buf8++;
  378. tmp.byte[3] = *tmp_buf8++;
  379. debug("3 rNAND_DATA = 0x%08X\n",tmp.word);
  380. writel(tmp.word, write_addr);
  381. }
  382. tmp.word = 0xFFFFFFFF;
  383. for(i = 0; i < excess_len; i++){
  384. *tmp_buf8++ = tmp.byte[i];
  385. }
  386. debug("3.1 rNAND_DATA = 0x%08X\n",tmp.word);
  387. writel(tmp.word, write_addr);
  388. break;
  389. }
  390. }
  391. /**
  392. * ark_nand_verify_buf - Verify chip data against buffer
  393. * @mtd: MTD device structure
  394. * @buf: buffer containing the data to compare
  395. * @len: number of bytes to compare
  396. *
  397. * Default verify function for 8bit buswith
  398. */
  399. /*static int ark_nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
  400. {
  401. int i,j;
  402. const uint8_t* tmp_buf8;
  403. unsigned int excess_len;
  404. union{
  405. unsigned int word;
  406. unsigned char byte[4];
  407. } tmp;
  408. debug("ark_nand_verify_buf\n");
  409. tmp_buf8 = buf;
  410. excess_len = len % 0x4;
  411. for (i = 0; i < len >> 2; i++){
  412. tmp.word = readl(rNAND_DATA);
  413. for (j = 0; j < 4; j++){
  414. if(tmp.byte[j] != *tmp_buf8++)
  415. return -EFAULT;
  416. }
  417. }
  418. if(excess_len){
  419. tmp.word = readl(rNAND_DATA);
  420. for(i = 0; i < excess_len; i++){
  421. if(tmp.byte[i] != *tmp_buf8++)
  422. return -EFAULT;
  423. }
  424. }
  425. return 0;
  426. }*/
  427. static void ark_nand_enable_hwecc(struct mtd_info *mtd, int mode)
  428. {
  429. debug("ark_nand_enable_hwecc\n");
  430. #if 0
  431. switch(mode){
  432. case NAND_ECC_READ:
  433. writel(readl(rBCH_CR) | BCH_CR_SECTOR_MODE,
  434. rBCH_CR);
  435. writel(readl(rBCH_CR) | BCH_CR_DECODER_RESET,
  436. rBCH_CR);
  437. writel(readl(rBCH_CR) & ~BCH_CR_DECODER_RESET,
  438. rBCH_CR);
  439. writel(readl(rBCH_CR) | BCH_CR_BCH_ENABLE,
  440. rBCH_CR);
  441. printf("\r\n>>>>>NAND_ECC_READ rBCH_CR 0x%08X\n",readl(rBCH_CR));
  442. break;
  443. case NAND_ECC_WRITE:
  444. writel(readl(rBCH_CR) | BCH_CR_SECTOR_MODE,
  445. rBCH_CR);
  446. writel(readl(rBCH_CR) | BCH_CR_ENCODER_RESET,
  447. rBCH_CR);
  448. writel(readl(rBCH_CR) & ~BCH_CR_ENCODER_RESET,
  449. rBCH_CR);
  450. writel(readl(rBCH_CR) | (BCH_CR_SOFT_ECC_ENABLE|BCH_CR_BCH_ENABLE),
  451. rBCH_CR);
  452. printf("\r\n>>>>>sNAND_ECC_WRITE rBCH_CR 0x%08X\n",readl(rBCH_CR));
  453. break;
  454. #else
  455. switch(mode){
  456. case NAND_ECC_READ:
  457. writel(readl(rBCH_CR) | BCH_CR_SECTOR_MODE,
  458. rBCH_CR);
  459. writel(readl(rBCH_CR) | BCH_CR_DECODER_RESET,
  460. rBCH_CR);
  461. writel(readl(rBCH_CR) & ~BCH_CR_DECODER_RESET,
  462. rBCH_CR);
  463. writel(readl(rBCH_CR) | (BCH_CR_SOFT_ECC_ENABLE|BCH_CR_BCH_ENABLE),
  464. rBCH_CR);
  465. debug("\r\n>>>>>NAND_ECC_READ rBCH_CR 0x%08X\n",readl(rBCH_CR));
  466. #ifndef USE_DATA_INTERFACE
  467. writel(1, rNAND_RDBLK_START);
  468. #endif
  469. break;
  470. case NAND_ECC_WRITE:
  471. writel(readl(rBCH_CR) | BCH_CR_SECTOR_MODE,
  472. rBCH_CR);
  473. writel(readl(rBCH_CR) | BCH_CR_ENCODER_RESET,
  474. rBCH_CR);
  475. writel(readl(rBCH_CR) & ~BCH_CR_ENCODER_RESET,
  476. rBCH_CR);
  477. writel(readl(rBCH_CR) | (BCH_CR_SOFT_ECC_ENABLE|BCH_CR_BCH_ENABLE),
  478. rBCH_CR);
  479. debug("\r\n>>>>>sNAND_ECC_WRITE rBCH_CR 0x%08X\n",readl(rBCH_CR));
  480. #ifndef USE_DATA_INTERFACE
  481. writel(1, rNAND_WRBLK_START);
  482. #endif
  483. break;
  484. #endif
  485. case NAND_ECC_READSYN:
  486. #ifndef USE_DATA_INTERFACE
  487. //wait for data decode end while useing block process
  488. while(!(readl(rBCH_INT) & NAND_INT_DECODE_END));
  489. debug("NAND_ECC_READSYN rBCH_INT 0x%08X\n",readl(rBCH_INT));
  490. writel(1, rBCH_INT);
  491. #endif
  492. debug("\r\n>>>>NAND_ECC_READSYN rBCH_CR 0x%08X\n",readl(rBCH_CR));
  493. break;
  494. }
  495. }
  496. #if 0 //512---7bit
  497. #else //1024---7bit
  498. static int ark_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
  499. u_char *ecc_code)
  500. {
  501. struct nand_chip *chip = mtd->priv;
  502. unsigned int bch_encode_no = 0;
  503. int i;
  504. union{
  505. unsigned int word;
  506. unsigned char byte[4];
  507. } tmp;
  508. debug("ark_nand_calculate_ecc\n");
  509. #ifndef USE_DATA_INTERFACE
  510. //wait for data encode end with block process
  511. while(!(readl(rBCH_INT) & NAND_INT_ENCODE_END));
  512. debug("rBCH_INT 0x%08X\n",readl(rBCH_INT));
  513. writel(1, rBCH_INT);
  514. #endif
  515. writel(readl(rBCH_CR) & ~BCH_CR_BCH_ENABLE,
  516. rBCH_CR); //disable BCH for write ECC Code
  517. #if 1
  518. debug("rBCH_NAND_STATUS 0x%08X : 0x%x\n", rBCH_NAND_STATUS, readl(rBCH_NAND_STATUS));
  519. #ifdef USE_DATA_INTERFACE
  520. while((readl(rBCH_NAND_STATUS) & 0x3F) != 0 ); //wait for fsm to idle state
  521. #else
  522. while((readl(rBCH_NAND_STATUS) >> 14) & 0x0F); //wait for all data in fifo to be transfered over.
  523. while((readl(rBCH_NAND_STATUS) & 0x3F) != 0 );//wait for fsm to idle state
  524. #endif
  525. debug("wait rBCH_NAND_STATUS done\n");
  526. #endif
  527. switch(chip->ecc.bytes){
  528. case BIT_7_ECC_BYTE:
  529. bch_encode_no = 4;
  530. break;
  531. case BIT_13_ECC_BYTE:
  532. bch_encode_no = 6;
  533. break;
  534. case BIT_24_ECC_BYTE:
  535. bch_encode_no = 11;
  536. break;
  537. case BIT_30_ECC_BYTE:
  538. bch_encode_no = 14;
  539. break;
  540. case BIT_48_ECC_BYTE:
  541. bch_encode_no = 21;
  542. break;
  543. }
  544. for(i = 0; i < bch_encode_no; i++){
  545. tmp.word = readl(EX_BCH_ENCODE_RESULT_ADDR + i*4);
  546. *ecc_code++ = tmp.byte[0];
  547. *ecc_code++ = tmp.byte[1];
  548. *ecc_code++ = tmp.byte[2];
  549. *ecc_code++ = tmp.byte[3];
  550. debug("EX_BCH_ENCODE_RESULT_ADDR %d: 0x%08X\n", i, tmp.word);
  551. }
  552. return 0;
  553. }
  554. static int ark_nand_correct_data(struct mtd_info *mtd, u_char *dat,
  555. u_char *read_ecc, u_char *calc_ecc)
  556. {
  557. struct nand_chip *chip = mtd->priv;
  558. unsigned int bch_decode_no = 0;
  559. unsigned char bch_decode_status;
  560. unsigned int err_byte_addr[2];
  561. unsigned int err_bit_addr[2];
  562. int i = 0, ret = 0;
  563. debug("ark_nand_correct_data\n");
  564. switch(chip->ecc.bytes){
  565. case BIT_7_ECC_BYTE:
  566. bch_decode_no = 4; /* no. of loops to correct 2 bits per loop */
  567. break;
  568. case BIT_13_ECC_BYTE:
  569. bch_decode_no = 7;
  570. break;
  571. case BIT_24_ECC_BYTE:
  572. bch_decode_no = 12;
  573. break;
  574. case BIT_30_ECC_BYTE:
  575. bch_decode_no = 15;
  576. break;
  577. case BIT_48_ECC_BYTE:
  578. bch_decode_no = 24;
  579. break;
  580. }
  581. //wait for ecc data read end
  582. while(readl(rEX_BCH_DECODE_STATUS)&0x01);
  583. #ifdef DEBUG
  584. debug("ECC code:");
  585. for(i = 0; i<chip->ecc.bytes; i++)
  586. debug("0x%X ",*read_ecc++);
  587. debug("\n");
  588. #endif
  589. /*
  590. printf("\r\nECC code:");
  591. for(i = 0; i<chip->ecc.bytes; i++)
  592. printf("0x%x ",*read_ecc++);
  593. temp=readl(rEX_BCH_DECODE_STATUS);
  594. printf("\n!! status:0x%x\n",temp);
  595. temp=readl(rBCH_CR);
  596. printf("\n!!rBCH_CR status:0x%x\n",temp);
  597. */
  598. bch_decode_status = (unsigned char)(readl(rEX_BCH_DECODE_STATUS) & 0x7);
  599. if(bch_decode_status & 0x2)
  600. { //All Data is right
  601. debug("\nAll data are correct\n");
  602. //continue;
  603. }
  604. else if(bch_decode_status & 0x4)
  605. { //err more than 8 bit
  606. writel(readl(rBCH_CR) & ~BCH_CR_BCH_ENABLE,
  607. rBCH_CR);
  608. printf("\n!!Read Data err more than 8 bit and Group = %d status:0x%x\n",i,bch_decode_status);
  609. return -EBADMSG;
  610. }
  611. else
  612. {
  613. for(i=0; i<bch_decode_no; i++){
  614. unsigned int val;
  615. val = readl(EX_BCH_DECODE_RESULT_ADDR+4*i);
  616. err_byte_addr[0] = (val&0x3ff8)>>3;
  617. err_bit_addr[0] = val&0x7;
  618. val = val >> 14;
  619. err_byte_addr[1] = (val&0x3ff8)>>3;
  620. err_bit_addr[1] = val&0x7;
  621. if(err_byte_addr[0] < 1024){
  622. (*(dat+err_byte_addr[0]) )^= (1<<err_bit_addr[0]);
  623. ret++;
  624. }
  625. if(err_byte_addr[1] < 1024){
  626. (*(dat+err_byte_addr[1]) )^= (1<<err_bit_addr[1]);
  627. ret++;
  628. }
  629. }
  630. }
  631. debug("Bit error no.: %d\n",ret);
  632. return ret;
  633. }
  634. #endif
  635. /**
  636. * ark_nand_read_page_raw_syndrome - [Intern] read raw page data without ecc
  637. * @mtd: mtd info structure
  638. * @chip: nand chip info structure
  639. * @buf: buffer to store read data
  640. * @page: page number to read
  641. *
  642. * We need a special oob layout and handling even when OOB isn't used.
  643. */
  644. static int ark_nand_read_page_raw_syndrome(struct mtd_info *mtd,
  645. struct nand_chip *chip,
  646. uint8_t *buf, int oob_required, int page)
  647. {
  648. struct ark_nand *nand_info = chip->priv;
  649. debug("ark_nand_read_page_raw_syndrome\n");
  650. debug("page %d, mtd->writesize %d\n",page, mtd->writesize);
  651. nand_info->raw_rw = 1;
  652. chip->read_buf(mtd, buf, mtd->writesize);
  653. chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
  654. nand_info->raw_rw = 0;
  655. return 0;
  656. }
  657. /**
  658. * ark_nand_read_page_syndrome - hardware ecc syndrom based page read
  659. * @mtd: mtd info structure
  660. * @chip: nand chip info structure
  661. * @buf: buffer to store read data
  662. * @page: page number to read
  663. *
  664. */
  665. static int ark_nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
  666. uint8_t *buf, int oob_required, int page)
  667. {
  668. int i, eccsize = chip->ecc.size;
  669. int eccbytes = chip->ecc.bytes;
  670. int eccsteps = chip->ecc.steps;
  671. uint8_t *p = buf;
  672. uint8_t *oob = chip->oob_poi;
  673. int oob_pos = 0, pos = 0;
  674. debug("ark_nand_read_page_syndrome\n");
  675. oob_pos += mtd->writesize;
  676. if(chip->ecc.prepad){
  677. oob_pos += chip->ecc.prepad;
  678. oob += chip->ecc.prepad;
  679. }
  680. for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
  681. int stat;
  682. chip->ecc.hwctl(mtd, NAND_ECC_READ);
  683. chip->read_buf(mtd, p, eccsize);
  684. chip->ecc.hwctl(mtd, NAND_ECC_READSYN);
  685. if (mtd->writesize > 512){
  686. chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, -1);
  687. }else{
  688. chip->cmdfunc(mtd, NAND_CMD_READ0, oob_pos, page);
  689. }
  690. oob_pos += eccbytes;
  691. chip->read_buf(mtd, oob, eccbytes);
  692. stat = chip->ecc.correct(mtd, p, oob, NULL);
  693. oob += eccbytes;
  694. if (stat < 0) {
  695. mtd->ecc_stats.failed++;
  696. } else {
  697. mtd->ecc_stats.corrected += stat;
  698. }
  699. if(eccsteps > 1)
  700. {
  701. pos += eccsize;
  702. if (mtd->writesize > 512)
  703. {
  704. chip->cmdfunc(mtd, NAND_CMD_RNDOUT, pos, -1);
  705. }
  706. else
  707. {
  708. chip->cmdfunc(mtd, NAND_CMD_READ0, pos, page);
  709. }
  710. }
  711. }
  712. writel(1,rBCH_INT);
  713. writel(readl(rBCH_CR) & ~BCH_CR_BCH_ENABLE, rBCH_CR);
  714. /* the whole oob area if there is prepad or postpad area */
  715. if (chip->ecc.prepad){
  716. oob_pos = mtd->writesize;
  717. if (mtd->writesize > 512){
  718. chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, -1);
  719. }else{
  720. chip->cmdfunc(mtd, NAND_CMD_READ0, oob_pos, page);
  721. }
  722. chip->read_buf(mtd, chip->oob_poi, chip->ecc.prepad);
  723. }
  724. if (chip->ecc.postpad){
  725. oob_pos = mtd->writesize + chip->ecc.prepad + (chip->ecc.steps * chip->ecc.bytes);
  726. if (mtd->writesize > 512){
  727. chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, -1);
  728. }else{
  729. chip->cmdfunc(mtd, NAND_CMD_READ0, oob_pos, page);
  730. }
  731. chip->read_buf(mtd, (chip->oob_poi + chip->ecc.prepad + (chip->ecc.steps * chip->ecc.bytes)),
  732. chip->ecc.postpad);
  733. }
  734. return 0;
  735. }
  736. /**
  737. * ark_nand_read_oob_syndrome - OOB data read function
  738. * @mtd: mtd info structure
  739. * @chip: nand chip info structure
  740. * @page: page number to read
  741. * @sndcmd: flag whether to issue read command or not
  742. */
  743. static int ark_nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
  744. int page)
  745. {
  746. debug("ark_nand_read_oob_syndrome\n");
  747. chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
  748. chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
  749. return 0;
  750. }
  751. /**
  752. * ark_nand_write_oob_syndrome - OOB data write function for HW ECC
  753. * with syndrome - only for large page flash !
  754. * @mtd: mtd info structure
  755. * @chip: nand chip info structure
  756. * @page: page number to write
  757. */
  758. static int ark_nand_write_oob_syndrome(struct mtd_info *mtd,
  759. struct nand_chip *chip, int page)
  760. {
  761. int status = 0;
  762. const uint8_t *buf = chip->oob_poi;
  763. int length = mtd->oobsize;
  764. debug("ark_nand_write_oob_syndrome\n");
  765. chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
  766. chip->write_buf(mtd, buf, length);
  767. /* Send command to program the OOB data */
  768. chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
  769. status = chip->waitfunc(mtd, chip);
  770. return status & NAND_STATUS_FAIL ? -EIO : 0;
  771. }
  772. /**
  773. * ark_nand_write_page_raw_syndrome - raw page write function
  774. * @mtd: mtd info structure
  775. * @chip: nand chip info structure
  776. * @buf: data buffer
  777. *
  778. * We need a special oob layout and handling even when ECC isn't checked.
  779. */
  780. static int ark_nand_write_page_raw_syndrome(struct mtd_info *mtd,
  781. struct nand_chip *chip,
  782. const uint8_t *buf,
  783. int oob_required, int page)
  784. {
  785. struct ark_nand *nand_info = chip->priv;
  786. debug("ark_nand_write_page_raw_syndrome\n");
  787. nand_info->raw_rw = 1;
  788. chip->write_buf(mtd, buf, mtd->writesize);
  789. chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
  790. nand_info->raw_rw = 0;
  791. return 0;
  792. }
  793. /**
  794. * ark_nand_write_page_syndrome - hardware ecc syndrom based page write
  795. * @mtd: mtd info structure
  796. * @chip: nand chip info structure
  797. * @buf: data buffer
  798. *
  799. * The hw generator calculates the error syndrome automatically. Therefor
  800. * we need a special oob layout and handling.
  801. */
  802. static int ark_nand_write_page_syndrome(struct mtd_info *mtd,
  803. struct nand_chip *chip, const uint8_t *buf,
  804. int oob_required, int page)
  805. {
  806. int i, eccsize = chip->ecc.size;
  807. int eccbytes = chip->ecc.bytes;
  808. int eccsteps = chip->ecc.steps;
  809. const uint8_t *p = buf;
  810. uint8_t *oob = chip->oob_poi;
  811. debug("ark_nand_write_page_syndrome\n");
  812. debug("eccsize %d, eccbytes %d, eccsteps %d\n", eccsize, eccbytes, eccsteps);
  813. debug("rBCH_NAND_STATUS 0x%x\n", readl(rBCH_NAND_STATUS));
  814. if(chip->ecc.prepad){
  815. oob += chip->ecc.prepad;
  816. }
  817. for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
  818. chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
  819. chip->write_buf(mtd, p, eccsize);
  820. chip->ecc.calculate(mtd, p, oob);
  821. oob += eccbytes;
  822. }
  823. debug("ark_nand: write ecc\n");
  824. chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
  825. return 0;
  826. }
  827. static int ark_nand_hw_init(struct nand_chip *chip)
  828. {
  829. unsigned int val;
  830. debug("ark_nand_hw_init\n");
  831. writel(0, rNAND_CR);
  832. val =0;
  833. #ifdef CONFIG_ARK1668EFAMILY
  834. val =(NAND_PAGE_TYPE(0) )|NAND_SEL_CHIP(0)| NAND_PRO_WRITE|NAND_CE_ENABLE |
  835. NAND_WR_SETPASS |NAND_RD_TRP_NUM(4) |NAND_RD_TREH_NUM(3)|
  836. NAND_WR_HOLD_NUM(3)|NAND_WR_WP_NUM(3)|NAND_WR_SET_NUM(4);
  837. #else
  838. val =(NAND_PAGE_TYPE(0) )|NAND_SEL_CHIP(0)| NAND_PRO_WRITE|NAND_CE_ENABLE |
  839. NAND_WR_SETPASS |NAND_RD_TRP_NUM(2) |NAND_RD_TREH_NUM(1)|
  840. NAND_WR_HOLD_NUM(3)|NAND_WR_WP_NUM(3)|NAND_WR_SET_NUM(4);
  841. #endif
  842. /* val =(NAND_PAGE_TYPE(0) )|NAND_SEL_CHIP(0)| NAND_PRO_WRITE|NAND_CE_ENABLE |
  843. NAND_WR_SETPASS |NAND_RD_TRP_NUM(2) |NAND_RD_TREH_NUM(2)|
  844. NAND_WR_HOLD_NUM(2)|NAND_WR_WP_NUM(2)|NAND_WR_SET_NUM(2); */
  845. writel(val,rNAND_CR);
  846. return 0;
  847. }
  848. static int ark_dev_ready(struct mtd_info *mtd)
  849. {
  850. struct nand_chip *chip = mtd->priv;
  851. struct ark_nand *nand_info = chip->priv;
  852. //return readl(rBCH_NAND_STATUS) & (1 << (18 + nand_info->chip_num));
  853. return readl(rBCH_NAND_STATUS) & (1 << (6 + nand_info->chip_num));
  854. }
  855. static int ark_hwecc_nand_init_param(struct nand_chip *chip, struct mtd_info *mtd)
  856. {
  857. u32 val;
  858. chip->ecc.mode = NAND_ECC_HW_SYNDROME;
  859. chip->ecc.calculate = ark_nand_calculate_ecc;
  860. chip->ecc.hwctl = ark_nand_enable_hwecc;
  861. chip->ecc.correct = ark_nand_correct_data;
  862. chip->ecc.read_page = ark_nand_read_page_syndrome;
  863. chip->ecc.read_page_raw = ark_nand_read_page_raw_syndrome;
  864. chip->ecc.read_oob = ark_nand_read_oob_syndrome;
  865. chip->ecc.write_page = ark_nand_write_page_syndrome;
  866. chip->ecc.write_page_raw = ark_nand_write_page_raw_syndrome;
  867. chip->ecc.write_oob = ark_nand_write_oob_syndrome;
  868. chip->ecc.size = 1024;
  869. if (mtd->oobsize == 64) {
  870. chip->ecc.bytes = BIT_13_ECC_BYTE; // should be 13 bytes but the ECC encoder register is in 32 bit word
  871. chip->ecc.strength = 13;
  872. chip->ecc.layout = &nand_hw_eccoob_64;
  873. chip->ecc.prepad = nand_hw_eccoob_64.eccpos[0];
  874. chip->ecc.postpad = nand_hw_eccoob_64.oobfree[0].offset;
  875. val = readl(rBCH_CR);
  876. val &= ~(0x7 << 4);
  877. val |= (1 << 8) | (1 << 7) | (1 << 4) | (1 << 0);
  878. writel(val, rBCH_CR);
  879. } else if(mtd->oobsize >= 128 && mtd->oobsize < 256) {
  880. chip->ecc.bytes = BIT_24_ECC_BYTE; // should be 13 bytes but the ECC encoder register is in 32 bit word
  881. chip->ecc.strength = 24;
  882. chip->ecc.layout = &nand_hw_eccoob_128;
  883. chip->ecc.prepad = nand_hw_eccoob_128.eccpos[0];
  884. chip->ecc.postpad = nand_hw_eccoob_128.oobfree[0].offset;
  885. val = readl(rBCH_CR);
  886. val &= ~(0x7 << 4);
  887. val |= (1 << 8) | (1 << 7) | (2 << 4) | (1 << 0);
  888. writel(val, rBCH_CR);
  889. } else if(mtd->oobsize >= 256) {
  890. chip->ecc.bytes = BIT_24_ECC_BYTE;
  891. chip->ecc.strength = 24;
  892. chip->ecc.layout = &nand_hw_eccoob_256;
  893. chip->ecc.prepad = nand_hw_eccoob_256.eccpos[0];
  894. chip->ecc.postpad = nand_hw_eccoob_256.oobfree[0].offset;
  895. val = readl(rBCH_CR);
  896. val &= ~(0x7 << 4);
  897. val |= (1 << 8) | (1 << 7) | (2 << 4) | (1 << 0);
  898. writel(val, rBCH_CR);
  899. }
  900. return 0;
  901. }
  902. static int ark_nand_init(struct nand_chip *chip, int devnum)
  903. {
  904. struct mtd_info *mtd;
  905. struct ark_nand *nand_info = &ark_nand_info;
  906. int ret;
  907. ark_nand_hw_init(chip);
  908. debug("board_nand_init\n");
  909. mtd = nand_to_mtd(chip);
  910. mtd->priv = chip;
  911. chip->priv = nand_info;
  912. nand_info->max_chip = 4;
  913. nand_info->chip_num = 0;
  914. /* 5 us command delay time */
  915. chip->chip_delay = 100;
  916. chip->IO_ADDR_R = (void __iomem *)rNAND_STATUS_RD;
  917. chip->IO_ADDR_W = (void __iomem *)rNAND_DATA;
  918. #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
  919. chip->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
  920. #endif
  921. chip->options |= NAND_NO_SUBPAGE_WRITE;//refer kernel
  922. chip->cmd_ctrl = ark_nand_hwcontrol;
  923. chip->select_chip = ark_nand_select_chip;
  924. chip->write_buf = ark_nand_write_buf;
  925. chip->read_buf = ark_nand_read_buf;
  926. chip->dev_ready = ark_dev_ready;
  927. #if 0 /* TODO: it needs to be fixed due to the 32 bit width of the data read write register */
  928. nand->verify_buf = ark_nand_verify_buf;
  929. #endif
  930. ret = nand_scan_ident(mtd, CONFIG_SYS_NAND_MAX_CHIPS, NULL);
  931. if (ret)
  932. return ret;
  933. ret = ark_hwecc_nand_init_param(chip, mtd);
  934. if (ret)
  935. return ret;
  936. ret = nand_scan_tail(mtd);
  937. if (!ret)
  938. nand_register(devnum, mtd);
  939. return ret;
  940. }
  941. static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];
  942. void board_nand_init(void)
  943. {
  944. struct nand_chip *nand = &nand_chip[0];
  945. if (ark_nand_init(nand, 0))
  946. puts("ARK NAND init failed\n");
  947. }
  948. static int do_switchecc(cmd_tbl_t *cmdtp, int flag, int argc,
  949. char * const argv[])
  950. {
  951. struct nand_chip *chip = &nand_chip[0];
  952. struct mtd_info *mtd = nand_to_mtd(chip);
  953. ulong bootecc;
  954. unsigned int val;
  955. if (argc >= 2) {
  956. bootecc = simple_strtoul(argv[1], NULL, 16);
  957. if (bootecc) {
  958. chip->ecc.size = 512;
  959. chip->ecc.steps = mtd->writesize / chip->ecc.size;
  960. chip->ecc.bytes = BIT_7_ECC_BYTE; // should be 13 bytes but the ECC encoder register is in 32 bit word
  961. chip->ecc.strength = 7;
  962. chip->ecc.layout = &nand_hw_eccoob_bootstrap;
  963. chip->ecc.prepad = nand_hw_eccoob_bootstrap.eccpos[0];
  964. chip->ecc.postpad = nand_hw_eccoob_bootstrap.oobfree[0].offset;
  965. val = readl(rBCH_CR);
  966. val &= ~((1 << 7) | (0x7 << 4));
  967. val |= (1 << 8) | (1 << 0);
  968. writel(val, rBCH_CR);
  969. } else {
  970. chip->ecc.size = 1024;
  971. chip->ecc.steps = mtd->writesize / chip->ecc.size;
  972. if (mtd->oobsize == 64) {
  973. chip->ecc.bytes = BIT_13_ECC_BYTE; // should be 13 bytes but the ECC encoder register is in 32 bit word
  974. chip->ecc.strength = 13;
  975. chip->ecc.layout = &nand_hw_eccoob_64;
  976. chip->ecc.prepad = nand_hw_eccoob_64.eccpos[0];
  977. chip->ecc.postpad = nand_hw_eccoob_64.oobfree[0].offset;
  978. val = readl(rBCH_CR);
  979. val &= ~(0x7 << 4);
  980. val |= (1 << 8) | (1 << 7) | (1 << 4) | (1 << 0);
  981. writel(val, rBCH_CR);
  982. } else if(mtd->oobsize >= 128 && mtd->oobsize <256) {
  983. chip->ecc.bytes = BIT_24_ECC_BYTE; // should be 13 bytes but the ECC encoder register is in 32 bit word
  984. chip->ecc.strength = 24;
  985. chip->ecc.layout = &nand_hw_eccoob_128;
  986. chip->ecc.prepad = nand_hw_eccoob_128.eccpos[0];
  987. chip->ecc.postpad = nand_hw_eccoob_128.oobfree[0].offset;
  988. val = readl(rBCH_CR);
  989. val &= ~(0x7 << 4);
  990. val |= (1 << 8) | (1 << 7) | (2 << 4) | (1 << 0);
  991. writel(val, rBCH_CR);
  992. } else if(mtd->oobsize >= 256) {
  993. chip->ecc.bytes = BIT_24_ECC_BYTE;
  994. chip->ecc.strength = 24;
  995. chip->ecc.layout = &nand_hw_eccoob_256;
  996. chip->ecc.prepad = nand_hw_eccoob_256.eccpos[0];
  997. chip->ecc.postpad = nand_hw_eccoob_256.oobfree[0].offset;
  998. val = readl(rBCH_CR);
  999. val &= ~(0x7 << 4);
  1000. val |= (1 << 8) | (1 << 7) | (2 << 4) | (1 << 0);
  1001. writel(val, rBCH_CR);
  1002. }
  1003. }
  1004. }
  1005. return 0;
  1006. }
  1007. U_BOOT_CMD(switchecc, 4, 1, do_switchecc,
  1008. "switch or restore nand ecc to/from bootstrap setting",
  1009. "1:to bootstrap ecc; 0:restore to normal ecc"
  1010. );