ark_nand_spl.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2014 Gateworks Corporation
  4. * Author: Tim Harvey <tharvey@gateworks.com>
  5. */
  6. #include <common.h>
  7. #include <malloc.h>
  8. #define NAND_BASE CONFIG_SYS_NAND_BASE
  9. /* NAND Flash Controller */
  10. #define rNAND_CR (*(volatile unsigned int *) (NAND_BASE + 0x00))
  11. #define rNAND_CLE_WR (*(volatile unsigned char *) (NAND_BASE + 0x04))
  12. #define rNAND_ALE_WR (*(volatile unsigned char *) (NAND_BASE + 0x08))
  13. #define rNAND_ID_RD (*(volatile unsigned char *) (NAND_BASE + 0x0c))
  14. #define rNAND_STATUS_RD (*(volatile unsigned char *) (NAND_BASE + 0x10))
  15. #define rNAND_DATA (*(volatile unsigned int *) (NAND_BASE + 0x14))
  16. #define rNAND_TX_FIFO (*(volatile unsigned int *) (NAND_BASE + 0x18))
  17. #define rNAND_RX_FIFO (*(volatile unsigned int *) (NAND_BASE + 0x1c))
  18. #define rNAND_WRBLK_START (*(volatile unsigned int *) (NAND_BASE + 0x20))
  19. #define rNAND_RDBLK_START (*(volatile unsigned int *) (NAND_BASE + 0x24))
  20. #define rEX_BCH_ENCODE_STATUS (*(volatile unsigned int *) (NAND_BASE + 0x274))
  21. #define rEX_BCH_DECODE_STATUS (*(volatile unsigned int *) (NAND_BASE + 0x278))
  22. #define rBCH_CR (*(volatile unsigned int *) (NAND_BASE + 0x27c))
  23. #define rBCH_NAND_STATUS (*(volatile unsigned int *) (NAND_BASE + 0x280))
  24. #define rBCH_DECODE_STATUS (*(volatile unsigned int *) (NAND_BASE + 0x284))
  25. #define rBCH_INT (*(volatile unsigned int *) (NAND_BASE + 0x288))
  26. #define rBCH_INT_MASK (*(volatile unsigned int *) (NAND_BASE + 0x28c))
  27. #define EX_BCH_DECODE_RESULT_ADDR (NAND_BASE + 0x29c)
  28. #define NAND_INT_GLOBAL (1<<3)
  29. #define NAND_INT_DECODE_ERR (1<<2)
  30. #define NAND_INT_DECODE_END (1<<1)
  31. #define NAND_INT_ENCODE_END (1<<0)
  32. //BCH_CR register fields defination
  33. #define BCH_CR_SECTOR_MODE (1<<8)
  34. #define BCH_CR_ENCODER_RESET (1<<3)
  35. #define BCH_CR_DECODER_RESET (1<<2)
  36. #define BCH_CR_SOFT_ECC_ENABLE (1<<1)
  37. #define BCH_CR_BCH_ENABLE (1<<0)
  38. #define CMD_ERASE1 0x60
  39. #define CMD_ERASE2 0xD0
  40. #define CMD_READ1 0x00
  41. #define CMD_READ2 0x30
  42. #define CMD_PAGEPROGRAM1 0x80
  43. #define CMD_PAGEPROGRAM2 0x10
  44. #define CMD_READ_ID 0x90
  45. #define CMD_RESET 0xFF
  46. #define CMD_RADOM_OUTPUT1 0x05
  47. #define CMD_RADOM_OUTPUT2 0xE0
  48. #define CMD_RADOM_INPUT 0x85
  49. #define CMD_READ_STATUS 0x70
  50. #define NAND_MFR_TOSHIBA 0x98
  51. #define NAND_MFR_SAMSUNG 0xec
  52. #define NAND_MFR_FUJITSU 0x04
  53. #define NAND_MFR_NATIONAL 0x8f
  54. #define NAND_MFR_RENESAS 0x07
  55. #define NAND_MFR_STMICRO 0x20
  56. #define NAND_MFR_HYNIX 0xad
  57. #define NAND_MFR_MICRO 0x2c
  58. #define NAND_MFR_AMD 0x01
  59. struct nand_maker{
  60. int id;
  61. const char *name;
  62. struct nand_dev *dev_desc;
  63. int (*match_id)(unsigned char *id);
  64. };
  65. struct nandflash_info {
  66. const char *name;
  67. unsigned int id;
  68. unsigned int id2;
  69. int pagesize;
  70. int chipsize;
  71. int blocksize;
  72. int oobsize;
  73. int options;
  74. };
  75. struct nand_info{
  76. int chipsize;
  77. int blksize;
  78. int blknum;
  79. int pagesize;
  80. int pagesblk;
  81. int oobsize;
  82. int colcycle;
  83. int rowcycle;
  84. int bchecccodesize;
  85. int bchsegsize;
  86. };
  87. struct nand_dev {
  88. const char *name;
  89. int id;
  90. int pagesize;
  91. int chipsize;
  92. int blocksize;
  93. };
  94. enum nand_chip_sel {
  95. NAND_CHIP0 = 0,
  96. NAND_CHIP1,
  97. NAND_CHIP2,
  98. NAND_CHIP3,
  99. };
  100. enum nand_data_width {
  101. NAND_DATA_WIDTH8 = 0,
  102. NAND_DATA_WIDTH16,
  103. };
  104. struct nand_dev nand_flash_ids[] = {
  105. // name id pagesize chipsize blocksize
  106. {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000},
  107. {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000},
  108. {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000},
  109. /*
  110. * These are the new chips with large page size. The pagesize and the
  111. * blocksize is determined from the extended id bytes
  112. */
  113. /*512 Megabit */
  114. {"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0},
  115. {"NAND 64MiB 3,3V 8-bit", 0xD0, 0, 64, 0},
  116. /* 1 Gigabit */
  117. {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0},
  118. {"NAND 128MiB 3,3V 8-bit", 0xD1, 0, 128, 0},
  119. /* 2 Gigabit */
  120. {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0},
  121. /* 4 Gigabit */
  122. {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0},
  123. /* 8 Gigabit */
  124. {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0},
  125. /* 16 Gigabit */
  126. {"NAND 2GiB 3,3V 8-bit", 0xD5, 0, 2048, 0},
  127. /* 32 Gigabit */
  128. {"NAND 4GiB 3,3V 8-bit", 0xD7, 0, 4096, 0},
  129. /* 64 Gigabit */
  130. {"NAND 8GiB 3,3V 8-bit", 0xDE, 0, 8192, 0},
  131. /*
  132. * Renesas AND 1 Gigabit. Those chips do not support extended id and
  133. * have a strange page/block layout ! The chosen minimum blocksize is
  134. * 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page
  135. * planes 1 block = 2 pages, but due to plane arrangement the blocks
  136. * 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7 Anyway JFFS2 would
  137. * increase the eraseblock size so we chose a combined one which can be
  138. * erased in one go There are more speed improvements for reads and
  139. * writes possible, but not implemented now
  140. */
  141. {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000},
  142. {NULL,},
  143. };
  144. static const struct nandflash_info nandflash_devices[] = {
  145. {"TC58BVG0S3HTAI0", 0x98, 0xF18015F2, 2048, 128, 128, 64, 0},
  146. {"K9F1G08U0C", 0xec, 0xf1009540, 2048, 128, 128, 64, 0},
  147. {"K9F1G08U0E", 0xec, 0xf1009541, 2048, 128, 128, 64, 0},
  148. {"HY27UF081G2A", 0xad, 0xf1801dad, 2048, 128, 128, 64, 0},
  149. {"TC58NVG0S3ETA00", 0x98, 0xD1901576, 2048, 128, 128, 64, 0},
  150. {"TC58NVG0S3HTA00", 0x98, 0xF1801572, 2048, 128, 128, 128, 0},
  151. {"TC58NVG1S3HTA00", 0x98, 0xDA901576, 2048, 256, 128, 128, 0},
  152. {"W29N01GV", 0xEF, 0xF1809500, 2048, 128, 128, 64, 0},
  153. {"FMND1GXXX3D", 0xF8, 0xF1809500, 2048, 128, 128, 64, 0},
  154. {"XT27G02ETSIGA", 0x2C, 0xDA909506, 2048, 256, 128, 128, 0},
  155. //此款flash芯片不支持,在此处强制将OOB128字节
  156. {"9FU1G8F2AMGF", 0xC8, 0xF1801D42, 2048, 128, 128, 128, 0},
  157. {"TC58NVG2S0HTAI0", 0x98, 0xDC902676, 4096, 512, 256, 256, 0},
  158. };
  159. static struct nand_info nand_info;
  160. static void nand_reset(void)
  161. {
  162. rNAND_CLE_WR = CMD_RESET;
  163. do {
  164. rNAND_CLE_WR = CMD_READ_STATUS;
  165. udelay(10);//do not delete this delay avoiding to elapse the time for tWHR
  166. } while (!(rNAND_STATUS_RD & 0x40));
  167. }
  168. static void nand_readid(unsigned char *id)
  169. {
  170. int i;
  171. rNAND_CLE_WR = CMD_READ_ID;
  172. rNAND_ALE_WR = 0x00;
  173. udelay(100);
  174. for(i = 0; i < 8; i++)
  175. *id++ = rNAND_ID_RD;
  176. }
  177. static int nand_scan_table(unsigned char *flashid)
  178. {
  179. int i;
  180. unsigned int id = flashid[0];
  181. unsigned int id2 = (flashid[1] << 24) | (flashid[2] << 16) | (flashid[3] << 8) | flashid[4];
  182. for(i = 0; i < sizeof(nandflash_devices) / sizeof(nandflash_devices[0]); i++) {
  183. if(id == nandflash_devices[i].id && id2 == nandflash_devices[i].id2) {
  184. nand_info.blksize = nandflash_devices[i].blocksize * 1024;
  185. nand_info.chipsize = nandflash_devices[i].chipsize * 1024 * 1024;
  186. nand_info.pagesize = nandflash_devices[i].pagesize;
  187. nand_info.oobsize = nandflash_devices[i].oobsize;
  188. return 0;
  189. }
  190. }
  191. puts("NO Device in Table\n");
  192. return -1;
  193. }
  194. static int get_cycle(unsigned int addr)
  195. {
  196. int cycle;
  197. for (cycle = 0; cycle < 4; cycle++) {
  198. if(addr & (0xff000000 >> (8 * cycle)))
  199. return 4-cycle;
  200. }
  201. return 0;
  202. }
  203. static void get_samsung_nandinfo(unsigned char *id)
  204. {
  205. int extid = id[3];
  206. nand_info.pagesize = 2048 << (extid & 0x03);
  207. extid >>= 2;
  208. //K9GBG08U0A ID:0xECD794766443
  209. switch ((extid & 0x03) | ((extid >> 2) & 0x04)) {
  210. case 1:
  211. nand_info.oobsize= 128;
  212. break;
  213. case 2:
  214. nand_info.oobsize = 218;
  215. break;
  216. case 3:
  217. nand_info.oobsize = 400;
  218. break;
  219. case 4:
  220. nand_info.oobsize = 436;
  221. break;
  222. default:
  223. nand_info.oobsize = 640;
  224. break;
  225. }
  226. extid >>= 2;
  227. /* Calc blocksize */
  228. nand_info.blksize = (128 * 1024) << (((extid >> 1) & 0x04) | (extid & 0x03));
  229. }
  230. static void get_hynix_nandinfo(unsigned char *id)
  231. {
  232. int extid = id[3];
  233. /* Calc pagesize */
  234. nand_info.pagesize = 2048 << (extid & 0x03);
  235. extid >>= 2;
  236. switch ((extid & 0x03) | ((extid>>2) & 0x04)) {
  237. case 0:
  238. nand_info.oobsize= 128;
  239. break;
  240. case 1:
  241. nand_info.oobsize = 224;
  242. break;
  243. case 2:
  244. nand_info.oobsize = 448;
  245. break;
  246. case 3:
  247. nand_info.oobsize = 64;
  248. break;
  249. case 4:
  250. nand_info.oobsize = 32;
  251. break;
  252. case 5:
  253. nand_info.oobsize = 16;
  254. break;
  255. case 6:
  256. nand_info.oobsize = 640;
  257. break;
  258. }
  259. extid >>= 2;
  260. switch(((extid >> 1) & 0x04) | (extid & 0x03)) {
  261. case 0:
  262. nand_info.blksize = 128 << 10;
  263. break;
  264. case 1:
  265. nand_info.blksize = 256 << 10;
  266. break;
  267. case 2:
  268. nand_info.blksize = 512 << 10;
  269. break;
  270. case 3:
  271. nand_info.blksize = 768 << 10;
  272. break;
  273. case 4:
  274. nand_info.blksize = 1 << 20;
  275. break;
  276. case 5:
  277. nand_info.blksize = 2 << 20;
  278. break;
  279. case 6:
  280. nand_info.blksize = 4 << 20;
  281. break;
  282. }
  283. }
  284. static int nand_readoob(int block, int page, int offset, unsigned int *buf, int size)
  285. {
  286. int i;
  287. unsigned int page_addr;
  288. page_addr = block * nand_info.pagesblk + page;
  289. rBCH_NAND_STATUS = 0x1;
  290. if(nand_info.pagesize > 512) {
  291. rNAND_CLE_WR = CMD_READ1;//0x00;
  292. rNAND_ALE_WR = offset;
  293. rNAND_ALE_WR = nand_info.pagesize >> 8;
  294. } else {
  295. rNAND_CLE_WR = 0x50;
  296. rNAND_ALE_WR = offset;
  297. }
  298. //send address
  299. for (i = 0; i < nand_info.rowcycle; i++)
  300. rNAND_ALE_WR = (page_addr >> (i * 8)) & 0xff;
  301. if (nand_info.pagesize >= 2048)
  302. rNAND_CLE_WR = CMD_READ2;
  303. while(!(rBCH_NAND_STATUS & (1 << 18)));
  304. for ( i = 0; i < size; i ++)
  305. *buf++ = rNAND_DATA;
  306. return 0;
  307. }
  308. static int nand_is_bad_block(int block)
  309. {
  310. unsigned int val;
  311. nand_readoob(block, 0, 0, &val, 1);
  312. if ((val & 0xffff) != 0xffff)
  313. return 1;
  314. return 0;
  315. }
  316. static int nand_read_page(int block, int page, void *dst)
  317. {
  318. unsigned int PhyAddr;
  319. int i,j;
  320. unsigned int *data = (unsigned int *)dst;
  321. unsigned char *buf = (unsigned char*)dst;
  322. unsigned int ECCData;
  323. unsigned int BchDecode;
  324. unsigned char BchDecodeStatus;
  325. unsigned int ErrByteAddr[2];
  326. unsigned int ErrBitAddr[2];
  327. int nBCH_DECODE_REGs = 4, nBCH_ENCODE_REGs = 4;
  328. unsigned int nMaxBCHSectors;
  329. int result = 0;
  330. int nECCCodeSize;
  331. nECCCodeSize = nand_info.bchecccodesize;
  332. PhyAddr = block * nand_info.pagesblk + page;
  333. //clear rb bit status
  334. rBCH_NAND_STATUS = 0x1; //add by frank
  335. //send cmd
  336. rNAND_CLE_WR = CMD_READ1;//0x00;
  337. //send address
  338. for (i = 0; i < nand_info.colcycle; i++)
  339. rNAND_ALE_WR = 0x00;
  340. for(i = 0; i < nand_info.rowcycle; i++)
  341. rNAND_ALE_WR = (PhyAddr >> (i*8)) & 0xff;
  342. if(nand_info.pagesize >= 2048)
  343. rNAND_CLE_WR = CMD_READ2;
  344. nMaxBCHSectors = nand_info.pagesize/nand_info.bchsegsize;
  345. while (!(rBCH_NAND_STATUS & (1 << 18)));
  346. for(i = 0; i < nMaxBCHSectors; i++) {
  347. rBCH_CR |= BCH_CR_SECTOR_MODE;
  348. //enable ecc controller, it will auto caculate the ecc code while data reading in the following code
  349. rBCH_CR |= BCH_CR_DECODER_RESET;//reset
  350. rBCH_CR &= ~BCH_CR_DECODER_RESET;
  351. rBCH_CR |= (BCH_CR_SOFT_ECC_ENABLE|BCH_CR_BCH_ENABLE);
  352. //read data from fifo with block process
  353. rNAND_RDBLK_START = 1;
  354. for (j = 0; j < (nand_info.bchsegsize >> 2); j++)
  355. *data++ = rNAND_RX_FIFO;
  356. //wait for data decode end while useing block process
  357. while(!(rBCH_INT & NAND_INT_DECODE_END));
  358. rBCH_INT = 1;
  359. //read ecc data stored in spare area
  360. rNAND_CLE_WR = CMD_RADOM_OUTPUT1;//0x05;
  361. for (j = 0; j < nand_info.colcycle; j++)
  362. rNAND_ALE_WR = ((nand_info.pagesize + nand_info.oobsize - nMaxBCHSectors * nECCCodeSize
  363. + i * nECCCodeSize) >> (8 * j)) & 0xff;
  364. rNAND_CLE_WR = CMD_RADOM_OUTPUT2;//0xE0;
  365. switch(nECCCodeSize) {
  366. case 13:
  367. nBCH_ENCODE_REGs = 4;
  368. nBCH_DECODE_REGs = 4;//7 BITS
  369. break;
  370. case 23:
  371. nBCH_ENCODE_REGs = 6;
  372. nBCH_DECODE_REGs = 7;//13 BITS
  373. break;
  374. case 42:
  375. nBCH_ENCODE_REGs = 11;//24 BITS
  376. nBCH_DECODE_REGs = 12;
  377. break;
  378. case 53:
  379. nBCH_ENCODE_REGs = 14;//30 BITS
  380. nBCH_DECODE_REGs = 15;
  381. break;
  382. case 84:
  383. nBCH_ENCODE_REGs = 21;//48 BITS
  384. nBCH_DECODE_REGs = 24;
  385. break;
  386. }
  387. for (j=0; j < nBCH_ENCODE_REGs; j++)
  388. ECCData = rNAND_DATA;
  389. ECCData = ECCData; //remove compile warning
  390. //wait for ecc data read end
  391. while (rEX_BCH_DECODE_STATUS & 0x01);
  392. //begin to check data read at the forward step according the ecc decord result just now.
  393. BchDecode = rEX_BCH_DECODE_STATUS;
  394. BchDecodeStatus = (char)(BchDecode&0x7);
  395. if(BchDecodeStatus&0x2) {
  396. //All Data is right
  397. ;
  398. } else if(BchDecodeStatus&0x4) {
  399. //err more than 8 bit
  400. rBCH_CR &= ~BCH_CR_BCH_ENABLE;
  401. puts("uncorrectable ECC error\n");
  402. result = -1;
  403. } else {
  404. for(j=0;j<nBCH_DECODE_REGs;j++) {
  405. unsigned int val;
  406. val = *(volatile unsigned int*)(EX_BCH_DECODE_RESULT_ADDR + 4 * j);
  407. ErrByteAddr[0] = (val&0x3ff8)>>3;
  408. ErrBitAddr[0] = val&0x7;
  409. val = val >> 14;
  410. ErrByteAddr[1] = (val&0x3ff8)>>3;
  411. ErrBitAddr[1] = val&0x7;
  412. if(ErrByteAddr[0] < 1024)
  413. *(buf + nand_info.bchsegsize * i + ErrByteAddr[0]) ^= 1 << ErrBitAddr[0];
  414. if(ErrByteAddr[1] < 1024)
  415. *(buf + nand_info.bchsegsize * i + ErrByteAddr[1]) ^= 1 << ErrBitAddr[1];
  416. }
  417. }
  418. rBCH_INT = 1;
  419. //if there are some other sector in this page to read, then begin to send their row address
  420. if(i<(nMaxBCHSectors-1) && nMaxBCHSectors>1) {
  421. rNAND_CLE_WR = CMD_RADOM_OUTPUT1;//0x85;
  422. rNAND_ALE_WR = 0x00;
  423. rNAND_ALE_WR = ((i + 1) * nand_info.bchsegsize) >> 8;
  424. rNAND_CLE_WR = CMD_RADOM_OUTPUT2;
  425. }
  426. }
  427. rBCH_INT = 1;
  428. rBCH_CR &= ~BCH_CR_BCH_ENABLE;
  429. return result;
  430. }
  431. int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
  432. {
  433. unsigned int block, lastblock;
  434. unsigned int page, page_offset;
  435. /* offs has to be aligned to a page address! */
  436. block = offs / nand_info.blksize;
  437. lastblock = (offs + size - 1) / nand_info.blksize;
  438. page = (offs % nand_info.blksize) / nand_info.pagesize;
  439. page_offset = offs % nand_info.pagesize;
  440. while (block <= lastblock) {
  441. if (!nand_is_bad_block(block)) {
  442. /* Skip bad blocks */
  443. while (page < nand_info.pagesblk) {
  444. nand_read_page(block, page, dst);
  445. /*
  446. * When offs is not aligned to page address the
  447. * extra offset is copied to dst as well. Copy
  448. * the image such that its first byte will be
  449. * at the dst.
  450. */
  451. if (unlikely(page_offset)) {
  452. memmove(dst, dst + page_offset,
  453. nand_info.pagesize);
  454. dst = (void *)((int)dst - page_offset);
  455. page_offset = 0;
  456. }
  457. dst += nand_info.pagesize;
  458. page++;
  459. }
  460. page = 0;
  461. } else {
  462. lastblock++;
  463. }
  464. block++;
  465. }
  466. return 0;
  467. }
  468. void nand_init(void)
  469. {
  470. unsigned char flash_id[8];
  471. int i, num;
  472. struct nand_dev nand_dev;
  473. unsigned char deviceid, devicecellid, extid;
  474. unsigned int val;
  475. rNAND_CR = 0;
  476. rNAND_CR = (1<<22)|(1<<21)|(0<<20)|(0x4<<16)|(0x3<<12)|(0x3<<8)|(0x3<<4)|(0x4<<0);
  477. nand_reset();
  478. nand_readid(flash_id);
  479. if(!nand_scan_table(flash_id)) {
  480. nand_info.blknum = nand_info.chipsize / nand_info.blksize;
  481. nand_info.pagesblk = nand_info.blksize / nand_info.pagesize;
  482. if(nand_info.pagesize == 512)
  483. nand_info.colcycle = 1;
  484. else
  485. nand_info.colcycle = get_cycle(nand_info.pagesize);
  486. nand_info.rowcycle = get_cycle(nand_info.chipsize / nand_info.pagesize - 1);
  487. } else {
  488. deviceid = flash_id[1];
  489. num = sizeof(nand_flash_ids) / sizeof(nand_flash_ids[0]);
  490. for(i = 0; i < num; i++) {
  491. if(deviceid ==nand_flash_ids[i].id) {
  492. nand_dev = nand_flash_ids[i];
  493. nand_info.chipsize = nand_flash_ids[i].chipsize << 20;
  494. break;
  495. }
  496. }
  497. /* Unkown Maker */
  498. if(i == num) {
  499. puts("Unknown Maker,Not Support The Chip!!\n");
  500. return;
  501. }
  502. if (!nand_dev.pagesize) {
  503. /* The 3rd id byte holds MLC / multichip data */
  504. devicecellid = flash_id[2];
  505. /* The 4th id byte is the important one */
  506. extid = flash_id[3];
  507. /*
  508. * Field definitions are in the following datasheets:
  509. * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
  510. * New style (6 byte ID): Samsung K9GBG08U0M (p.40)
  511. *
  512. * Check for wraparound + Samsung ID + nonzero 6th byte
  513. * to decide what to do.
  514. */
  515. if ((flash_id[0] == flash_id[6]) && (flash_id[1] == flash_id[7]) &&
  516. // FlashId[0] == NAND_MFR_SAMSUNG &&
  517. (devicecellid & 0x0C) &&
  518. (flash_id[5] != 0x00)) {
  519. if(flash_id[0] == NAND_MFR_SAMSUNG) {
  520. get_samsung_nandinfo(flash_id);
  521. goto nandinfo_over;
  522. } else if(flash_id[0] == NAND_MFR_HYNIX) {
  523. get_hynix_nandinfo(flash_id);
  524. goto nandinfo_over;
  525. }
  526. }
  527. /* Calc pagesize */
  528. nand_info.pagesize = 1024 << (extid & 0x03);
  529. extid >>= 2;
  530. /* Calc oobsize */
  531. nand_info.oobsize = (8 << (extid & 0x01)) *
  532. (nand_info.pagesize >> 9);
  533. extid >>= 2;
  534. /* Calc blocksize. Blocksize is multiples of 64KiB */
  535. nand_info.blksize= (64 * 1024) << (extid & 0x03);
  536. }
  537. else {
  538. /*
  539. * Old devices have chip data hardcoded in the device id table
  540. */
  541. nand_info.blksize = nand_dev.blocksize;
  542. nand_info.pagesize = nand_dev.pagesize;
  543. nand_info.oobsize = nand_info.pagesize / 32;
  544. /*
  545. * Check for Spansion/AMD ID + repeating 5th, 6th byte since
  546. * some Spansion chips have blocksize that conflicts with size
  547. * listed in nand_ids table
  548. * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39)
  549. */
  550. if (flash_id[0] == NAND_MFR_AMD && flash_id[4] != 0x00 &&
  551. flash_id[5] == 0x00 && flash_id[6] == 0x00 &&
  552. flash_id[7] == 0x00 && nand_info.pagesize == 512) {
  553. nand_info.blksize = 128 * 1024;
  554. nand_info.blksize <<= ((flash_id[3] & 0x03) << 1);
  555. }
  556. }
  557. nandinfo_over:
  558. if(nand_info.pagesize == 512)
  559. nand_info.colcycle = 1;
  560. else
  561. nand_info.colcycle = get_cycle(nand_info.pagesize);
  562. nand_info.rowcycle = get_cycle(nand_info.chipsize / nand_info.pagesize - 1);
  563. nand_info.pagesblk = nand_info.blksize / nand_info.pagesize;
  564. nand_info.blknum = nand_info.chipsize / nand_info.blksize;
  565. }
  566. if(nand_info.oobsize == 64) {
  567. val = rNAND_CR;
  568. val &= ~(3 << 25);
  569. rNAND_CR = val;
  570. nand_info.bchsegsize = 1024;
  571. nand_info.bchecccodesize = 23;
  572. val = rBCH_CR;
  573. val &= ~((1 << 7) | (7 << 4));
  574. val |= (1 << 7) | (1 << 4);
  575. rBCH_CR = val;
  576. debug("ECC 13 bit !!\n");
  577. } else if(nand_info.oobsize >= 128) {
  578. val = rNAND_CR;
  579. val &= ~(3<<25);
  580. rNAND_CR = val;
  581. nand_info.bchsegsize = 1024;
  582. nand_info.bchecccodesize = 42;
  583. val = rBCH_CR;
  584. val &= ~((1 << 8) | (1 << 7) | (7 << 4));
  585. val |= (1 << 7) | (2 << 4);
  586. rBCH_CR = val;
  587. debug("ECC 24 bit !!\n");
  588. }
  589. return;
  590. }
  591. void nand_deselect(void)
  592. {
  593. }