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