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