sunxi_nand_spl.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2014-2015, Antmicro Ltd <www.antmicro.com>
  4. * Copyright (c) 2015, AW-SOM Technologies <www.aw-som.com>
  5. */
  6. #include <asm/arch/clock.h>
  7. #include <asm/io.h>
  8. #include <common.h>
  9. #include <config.h>
  10. #include <nand.h>
  11. #include <linux/ctype.h>
  12. /* registers */
  13. #define NFC_CTL 0x00000000
  14. #define NFC_ST 0x00000004
  15. #define NFC_INT 0x00000008
  16. #define NFC_TIMING_CTL 0x0000000C
  17. #define NFC_TIMING_CFG 0x00000010
  18. #define NFC_ADDR_LOW 0x00000014
  19. #define NFC_ADDR_HIGH 0x00000018
  20. #define NFC_SECTOR_NUM 0x0000001C
  21. #define NFC_CNT 0x00000020
  22. #define NFC_CMD 0x00000024
  23. #define NFC_RCMD_SET 0x00000028
  24. #define NFC_WCMD_SET 0x0000002C
  25. #define NFC_IO_DATA 0x00000030
  26. #define NFC_ECC_CTL 0x00000034
  27. #define NFC_ECC_ST 0x00000038
  28. #define NFC_DEBUG 0x0000003C
  29. #define NFC_ECC_CNT0 0x00000040
  30. #define NFC_ECC_CNT1 0x00000044
  31. #define NFC_ECC_CNT2 0x00000048
  32. #define NFC_ECC_CNT3 0x0000004C
  33. #define NFC_USER_DATA_BASE 0x00000050
  34. #define NFC_EFNAND_STATUS 0x00000090
  35. #define NFC_SPARE_AREA 0x000000A0
  36. #define NFC_PATTERN_ID 0x000000A4
  37. #define NFC_RAM0_BASE 0x00000400
  38. #define NFC_RAM1_BASE 0x00000800
  39. #define NFC_CTL_EN (1 << 0)
  40. #define NFC_CTL_RESET (1 << 1)
  41. #define NFC_CTL_RAM_METHOD (1 << 14)
  42. #define NFC_CTL_PAGE_SIZE_MASK (0xf << 8)
  43. #define NFC_CTL_PAGE_SIZE(a) ((fls(a) - 11) << 8)
  44. #define NFC_ECC_EN (1 << 0)
  45. #define NFC_ECC_PIPELINE (1 << 3)
  46. #define NFC_ECC_EXCEPTION (1 << 4)
  47. #define NFC_ECC_BLOCK_SIZE (1 << 5)
  48. #define NFC_ECC_RANDOM_EN (1 << 9)
  49. #define NFC_ECC_RANDOM_DIRECTION (1 << 10)
  50. #define NFC_ADDR_NUM_OFFSET 16
  51. #define NFC_SEND_ADDR (1 << 19)
  52. #define NFC_ACCESS_DIR (1 << 20)
  53. #define NFC_DATA_TRANS (1 << 21)
  54. #define NFC_SEND_CMD1 (1 << 22)
  55. #define NFC_WAIT_FLAG (1 << 23)
  56. #define NFC_SEND_CMD2 (1 << 24)
  57. #define NFC_SEQ (1 << 25)
  58. #define NFC_DATA_SWAP_METHOD (1 << 26)
  59. #define NFC_ROW_AUTO_INC (1 << 27)
  60. #define NFC_SEND_CMD3 (1 << 28)
  61. #define NFC_SEND_CMD4 (1 << 29)
  62. #define NFC_RAW_CMD (0 << 30)
  63. #define NFC_ECC_CMD (1 << 30)
  64. #define NFC_PAGE_CMD (2 << 30)
  65. #define NFC_ST_CMD_INT_FLAG (1 << 1)
  66. #define NFC_ST_DMA_INT_FLAG (1 << 2)
  67. #define NFC_ST_CMD_FIFO_STAT (1 << 3)
  68. #define NFC_READ_CMD_OFFSET 0
  69. #define NFC_RANDOM_READ_CMD0_OFFSET 8
  70. #define NFC_RANDOM_READ_CMD1_OFFSET 16
  71. #define NFC_CMD_RNDOUTSTART 0xE0
  72. #define NFC_CMD_RNDOUT 0x05
  73. #define NFC_CMD_READSTART 0x30
  74. struct nfc_config {
  75. int page_size;
  76. int ecc_strength;
  77. int ecc_size;
  78. int addr_cycles;
  79. int nseeds;
  80. bool randomize;
  81. bool valid;
  82. };
  83. /* minimal "boot0" style NAND support for Allwinner A20 */
  84. /* random seed used by linux */
  85. const uint16_t random_seed[128] = {
  86. 0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72,
  87. 0x0d67, 0x67f9, 0x1be7, 0x077d, 0x032f, 0x0dac, 0x2716, 0x2436,
  88. 0x7922, 0x1510, 0x3860, 0x5287, 0x480f, 0x4252, 0x1789, 0x5a2d,
  89. 0x2a49, 0x5e10, 0x437f, 0x4b4e, 0x2f45, 0x216e, 0x5cb7, 0x7130,
  90. 0x2a3f, 0x60e4, 0x4dc9, 0x0ef0, 0x0f52, 0x1bb9, 0x6211, 0x7a56,
  91. 0x226d, 0x4ea7, 0x6f36, 0x3692, 0x38bf, 0x0c62, 0x05eb, 0x4c55,
  92. 0x60f4, 0x728c, 0x3b6f, 0x2037, 0x7f69, 0x0936, 0x651a, 0x4ceb,
  93. 0x6218, 0x79f3, 0x383f, 0x18d9, 0x4f05, 0x5c82, 0x2912, 0x6f17,
  94. 0x6856, 0x5938, 0x1007, 0x61ab, 0x3e7f, 0x57c2, 0x542f, 0x4f62,
  95. 0x7454, 0x2eac, 0x7739, 0x42d4, 0x2f90, 0x435a, 0x2e52, 0x2064,
  96. 0x637c, 0x66ad, 0x2c90, 0x0bad, 0x759c, 0x0029, 0x0986, 0x7126,
  97. 0x1ca7, 0x1605, 0x386a, 0x27f5, 0x1380, 0x6d75, 0x24c3, 0x0f8e,
  98. 0x2b7a, 0x1418, 0x1fd1, 0x7dc1, 0x2d8e, 0x43af, 0x2267, 0x7da3,
  99. 0x4e3d, 0x1338, 0x50db, 0x454d, 0x764d, 0x40a3, 0x42e6, 0x262b,
  100. 0x2d2e, 0x1aea, 0x2e17, 0x173d, 0x3a6e, 0x71bf, 0x25f9, 0x0a5d,
  101. 0x7c57, 0x0fbe, 0x46ce, 0x4939, 0x6b17, 0x37bb, 0x3e91, 0x76db,
  102. };
  103. #define DEFAULT_TIMEOUT_US 100000
  104. static int check_value_inner(int offset, int expected_bits,
  105. int timeout_us, int negation)
  106. {
  107. do {
  108. int val = readl(offset) & expected_bits;
  109. if (negation ? !val : val)
  110. return 1;
  111. udelay(1);
  112. } while (--timeout_us);
  113. return 0;
  114. }
  115. static inline int check_value(int offset, int expected_bits,
  116. int timeout_us)
  117. {
  118. return check_value_inner(offset, expected_bits, timeout_us, 0);
  119. }
  120. static inline int check_value_negated(int offset, int unexpected_bits,
  121. int timeout_us)
  122. {
  123. return check_value_inner(offset, unexpected_bits, timeout_us, 1);
  124. }
  125. static int nand_wait_cmd_fifo_empty(void)
  126. {
  127. if (!check_value_negated(SUNXI_NFC_BASE + NFC_ST, NFC_ST_CMD_FIFO_STAT,
  128. DEFAULT_TIMEOUT_US)) {
  129. printf("nand: timeout waiting for empty cmd FIFO\n");
  130. return -ETIMEDOUT;
  131. }
  132. return 0;
  133. }
  134. static int nand_wait_int(void)
  135. {
  136. if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_CMD_INT_FLAG,
  137. DEFAULT_TIMEOUT_US)) {
  138. printf("nand: timeout waiting for interruption\n");
  139. return -ETIMEDOUT;
  140. }
  141. return 0;
  142. }
  143. static int nand_exec_cmd(u32 cmd)
  144. {
  145. int ret;
  146. ret = nand_wait_cmd_fifo_empty();
  147. if (ret)
  148. return ret;
  149. writel(NFC_ST_CMD_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
  150. writel(cmd, SUNXI_NFC_BASE + NFC_CMD);
  151. return nand_wait_int();
  152. }
  153. void nand_init(void)
  154. {
  155. uint32_t val;
  156. board_nand_init();
  157. val = readl(SUNXI_NFC_BASE + NFC_CTL);
  158. /* enable and reset CTL */
  159. writel(val | NFC_CTL_EN | NFC_CTL_RESET,
  160. SUNXI_NFC_BASE + NFC_CTL);
  161. if (!check_value_negated(SUNXI_NFC_BASE + NFC_CTL,
  162. NFC_CTL_RESET, DEFAULT_TIMEOUT_US)) {
  163. printf("Couldn't initialize nand\n");
  164. }
  165. /* reset NAND */
  166. nand_exec_cmd(NFC_SEND_CMD1 | NFC_WAIT_FLAG | NAND_CMD_RESET);
  167. }
  168. static void nand_apply_config(const struct nfc_config *conf)
  169. {
  170. u32 val;
  171. nand_wait_cmd_fifo_empty();
  172. val = readl(SUNXI_NFC_BASE + NFC_CTL);
  173. val &= ~NFC_CTL_PAGE_SIZE_MASK;
  174. writel(val | NFC_CTL_RAM_METHOD | NFC_CTL_PAGE_SIZE(conf->page_size),
  175. SUNXI_NFC_BASE + NFC_CTL);
  176. writel(conf->ecc_size, SUNXI_NFC_BASE + NFC_CNT);
  177. writel(conf->page_size, SUNXI_NFC_BASE + NFC_SPARE_AREA);
  178. }
  179. static int nand_load_page(const struct nfc_config *conf, u32 offs)
  180. {
  181. int page = offs / conf->page_size;
  182. writel((NFC_CMD_RNDOUTSTART << NFC_RANDOM_READ_CMD1_OFFSET) |
  183. (NFC_CMD_RNDOUT << NFC_RANDOM_READ_CMD0_OFFSET) |
  184. (NFC_CMD_READSTART << NFC_READ_CMD_OFFSET),
  185. SUNXI_NFC_BASE + NFC_RCMD_SET);
  186. writel(((page & 0xFFFF) << 16), SUNXI_NFC_BASE + NFC_ADDR_LOW);
  187. writel((page >> 16) & 0xFF, SUNXI_NFC_BASE + NFC_ADDR_HIGH);
  188. return nand_exec_cmd(NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_RAW_CMD |
  189. NFC_SEND_ADDR | NFC_WAIT_FLAG |
  190. ((conf->addr_cycles - 1) << NFC_ADDR_NUM_OFFSET));
  191. }
  192. static int nand_change_column(u16 column)
  193. {
  194. int ret;
  195. writel((NFC_CMD_RNDOUTSTART << NFC_RANDOM_READ_CMD1_OFFSET) |
  196. (NFC_CMD_RNDOUT << NFC_RANDOM_READ_CMD0_OFFSET) |
  197. (NFC_CMD_RNDOUTSTART << NFC_READ_CMD_OFFSET),
  198. SUNXI_NFC_BASE + NFC_RCMD_SET);
  199. writel(column, SUNXI_NFC_BASE + NFC_ADDR_LOW);
  200. ret = nand_exec_cmd(NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_RAW_CMD |
  201. (1 << NFC_ADDR_NUM_OFFSET) | NFC_SEND_ADDR |
  202. NFC_CMD_RNDOUT);
  203. if (ret)
  204. return ret;
  205. /* Ensure tCCS has passed before reading data */
  206. udelay(1);
  207. return 0;
  208. }
  209. static const int ecc_bytes[] = {32, 46, 54, 60, 74, 88, 102, 110, 116};
  210. static int nand_read_page(const struct nfc_config *conf, u32 offs,
  211. void *dest, int len)
  212. {
  213. int nsectors = len / conf->ecc_size;
  214. u16 rand_seed = 0;
  215. int oob_chunk_sz = ecc_bytes[conf->ecc_strength];
  216. int page = offs / conf->page_size;
  217. u32 ecc_st;
  218. int i;
  219. if (offs % conf->page_size || len % conf->ecc_size ||
  220. len > conf->page_size || len < 0)
  221. return -EINVAL;
  222. /* Choose correct seed if randomized */
  223. if (conf->randomize)
  224. rand_seed = random_seed[page % conf->nseeds];
  225. /* Retrieve data from SRAM (PIO) */
  226. for (i = 0; i < nsectors; i++) {
  227. int data_off = i * conf->ecc_size;
  228. int oob_off = conf->page_size + (i * oob_chunk_sz);
  229. u8 *data = dest + data_off;
  230. /* Clear ECC status and restart ECC engine */
  231. writel(0, SUNXI_NFC_BASE + NFC_ECC_ST);
  232. writel((rand_seed << 16) | (conf->ecc_strength << 12) |
  233. (conf->randomize ? NFC_ECC_RANDOM_EN : 0) |
  234. (conf->ecc_size == 512 ? NFC_ECC_BLOCK_SIZE : 0) |
  235. NFC_ECC_EN | NFC_ECC_EXCEPTION,
  236. SUNXI_NFC_BASE + NFC_ECC_CTL);
  237. /* Move the data in SRAM */
  238. nand_change_column(data_off);
  239. writel(conf->ecc_size, SUNXI_NFC_BASE + NFC_CNT);
  240. nand_exec_cmd(NFC_DATA_TRANS);
  241. /*
  242. * Let the ECC engine consume the ECC bytes and possibly correct
  243. * the data.
  244. */
  245. nand_change_column(oob_off);
  246. nand_exec_cmd(NFC_DATA_TRANS | NFC_ECC_CMD);
  247. /* Get the ECC status */
  248. ecc_st = readl(SUNXI_NFC_BASE + NFC_ECC_ST);
  249. /* ECC error detected. */
  250. if (ecc_st & 0xffff)
  251. return -EIO;
  252. /*
  253. * Return 1 if the first chunk is empty (needed for
  254. * configuration detection).
  255. */
  256. if (!i && (ecc_st & 0x10000))
  257. return 1;
  258. /* Retrieve the data from SRAM */
  259. memcpy_fromio(data, SUNXI_NFC_BASE + NFC_RAM0_BASE,
  260. conf->ecc_size);
  261. /* Stop the ECC engine */
  262. writel(readl(SUNXI_NFC_BASE + NFC_ECC_CTL) & ~NFC_ECC_EN,
  263. SUNXI_NFC_BASE + NFC_ECC_CTL);
  264. if (data_off + conf->ecc_size >= len)
  265. break;
  266. }
  267. return 0;
  268. }
  269. static int nand_max_ecc_strength(struct nfc_config *conf)
  270. {
  271. int max_oobsize, max_ecc_bytes;
  272. int nsectors = conf->page_size / conf->ecc_size;
  273. int i;
  274. /*
  275. * ECC strength is limited by the size of the OOB area which is
  276. * correlated with the page size.
  277. */
  278. switch (conf->page_size) {
  279. case 2048:
  280. max_oobsize = 64;
  281. break;
  282. case 4096:
  283. max_oobsize = 256;
  284. break;
  285. case 8192:
  286. max_oobsize = 640;
  287. break;
  288. case 16384:
  289. max_oobsize = 1664;
  290. break;
  291. default:
  292. return -EINVAL;
  293. }
  294. max_ecc_bytes = max_oobsize / nsectors;
  295. for (i = 0; i < ARRAY_SIZE(ecc_bytes); i++) {
  296. if (ecc_bytes[i] > max_ecc_bytes)
  297. break;
  298. }
  299. if (!i)
  300. return -EINVAL;
  301. return i - 1;
  302. }
  303. static int nand_detect_ecc_config(struct nfc_config *conf, u32 offs,
  304. void *dest)
  305. {
  306. /* NAND with pages > 4k will likely require 1k sector size. */
  307. int min_ecc_size = conf->page_size > 4096 ? 1024 : 512;
  308. int page = offs / conf->page_size;
  309. int ret;
  310. /*
  311. * In most cases, 1k sectors are preferred over 512b ones, start
  312. * testing this config first.
  313. */
  314. for (conf->ecc_size = 1024; conf->ecc_size >= min_ecc_size;
  315. conf->ecc_size >>= 1) {
  316. int max_ecc_strength = nand_max_ecc_strength(conf);
  317. nand_apply_config(conf);
  318. /*
  319. * We are starting from the maximum ECC strength because
  320. * most of the time NAND vendors provide an OOB area that
  321. * barely meets the ECC requirements.
  322. */
  323. for (conf->ecc_strength = max_ecc_strength;
  324. conf->ecc_strength >= 0;
  325. conf->ecc_strength--) {
  326. conf->randomize = false;
  327. if (nand_change_column(0))
  328. return -EIO;
  329. /*
  330. * Only read the first sector to speedup detection.
  331. */
  332. ret = nand_read_page(conf, offs, dest, conf->ecc_size);
  333. if (!ret) {
  334. return 0;
  335. } else if (ret > 0) {
  336. /*
  337. * If page is empty we can't deduce anything
  338. * about the ECC config => stop the detection.
  339. */
  340. return -EINVAL;
  341. }
  342. conf->randomize = true;
  343. conf->nseeds = ARRAY_SIZE(random_seed);
  344. do {
  345. if (nand_change_column(0))
  346. return -EIO;
  347. if (!nand_read_page(conf, offs, dest,
  348. conf->ecc_size))
  349. return 0;
  350. /*
  351. * Find the next ->nseeds value that would
  352. * change the randomizer seed for the page
  353. * we're trying to read.
  354. */
  355. while (conf->nseeds >= 16) {
  356. int seed = page % conf->nseeds;
  357. conf->nseeds >>= 1;
  358. if (seed != page % conf->nseeds)
  359. break;
  360. }
  361. } while (conf->nseeds >= 16);
  362. }
  363. }
  364. return -EINVAL;
  365. }
  366. static int nand_detect_config(struct nfc_config *conf, u32 offs, void *dest)
  367. {
  368. if (conf->valid)
  369. return 0;
  370. /*
  371. * Modern NANDs are more likely than legacy ones, so we start testing
  372. * with 5 address cycles.
  373. */
  374. for (conf->addr_cycles = 5;
  375. conf->addr_cycles >= 4;
  376. conf->addr_cycles--) {
  377. int max_page_size = conf->addr_cycles == 4 ? 2048 : 16384;
  378. /*
  379. * Ignoring 1k pages cause I'm not even sure this case exist
  380. * in the real world.
  381. */
  382. for (conf->page_size = 2048; conf->page_size <= max_page_size;
  383. conf->page_size <<= 1) {
  384. if (nand_load_page(conf, offs))
  385. return -1;
  386. if (!nand_detect_ecc_config(conf, offs, dest)) {
  387. conf->valid = true;
  388. return 0;
  389. }
  390. }
  391. }
  392. return -EINVAL;
  393. }
  394. static int nand_read_buffer(struct nfc_config *conf, uint32_t offs,
  395. unsigned int size, void *dest)
  396. {
  397. int first_seed = 0, page, ret;
  398. size = ALIGN(size, conf->page_size);
  399. page = offs / conf->page_size;
  400. if (conf->randomize)
  401. first_seed = page % conf->nseeds;
  402. for (; size; size -= conf->page_size) {
  403. if (nand_load_page(conf, offs))
  404. return -1;
  405. ret = nand_read_page(conf, offs, dest, conf->page_size);
  406. /*
  407. * The ->nseeds value should be equal to the number of pages
  408. * in an eraseblock. Since we don't know this information in
  409. * advance we might have picked a wrong value.
  410. */
  411. if (ret < 0 && conf->randomize) {
  412. int cur_seed = page % conf->nseeds;
  413. /*
  414. * We already tried all the seed values => we are
  415. * facing a real corruption.
  416. */
  417. if (cur_seed < first_seed)
  418. return -EIO;
  419. /* Try to adjust ->nseeds and read the page again... */
  420. conf->nseeds = cur_seed;
  421. if (nand_change_column(0))
  422. return -EIO;
  423. /* ... it still fails => it's a real corruption. */
  424. if (nand_read_page(conf, offs, dest, conf->page_size))
  425. return -EIO;
  426. } else if (ret && conf->randomize) {
  427. memset(dest, 0xff, conf->page_size);
  428. }
  429. page++;
  430. offs += conf->page_size;
  431. dest += conf->page_size;
  432. }
  433. return 0;
  434. }
  435. int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest)
  436. {
  437. static struct nfc_config conf = { };
  438. int ret;
  439. ret = nand_detect_config(&conf, offs, dest);
  440. if (ret)
  441. return ret;
  442. return nand_read_buffer(&conf, offs, size, dest);
  443. }
  444. void nand_deselect(void)
  445. {
  446. struct sunxi_ccm_reg *const ccm =
  447. (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
  448. clrbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0));
  449. #ifdef CONFIG_MACH_SUN9I
  450. clrbits_le32(&ccm->ahb_gate1, (1 << AHB_GATE_OFFSET_DMA));
  451. #else
  452. clrbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_DMA));
  453. #endif
  454. clrbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1);
  455. }