Merge branch 'master' of git://git.denx.de/u-boot-samsung
[oweals/u-boot.git] / drivers / mtd / nand / sunxi_nand_spl.c
1 /*
2  * Copyright (c) 2014-2015, Antmicro Ltd <www.antmicro.com>
3  * Copyright (c) 2015, AW-SOM Technologies <www.aw-som.com>
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <asm/arch/clock.h>
9 #include <asm/io.h>
10 #include <common.h>
11 #include <config.h>
12 #include <nand.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_ADR               (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_PAGE_CMD               (2 << 30)
71
72 #define NFC_ST_CMD_INT_FLAG        (1 << 1)
73 #define NFC_ST_DMA_INT_FLAG        (1 << 2)
74
75 #define NFC_READ_CMD_OFFSET         0
76 #define NFC_RANDOM_READ_CMD0_OFFSET 8
77 #define NFC_RANDOM_READ_CMD1_OFFSET 16
78
79 #define NFC_CMD_RNDOUTSTART        0xE0
80 #define NFC_CMD_RNDOUT             0x05
81 #define NFC_CMD_READSTART          0x30
82
83 #define SUNXI_DMA_CFG_REG0              0x300
84 #define SUNXI_DMA_SRC_START_ADDR_REG0   0x304
85 #define SUNXI_DMA_DEST_START_ADDRR_REG0 0x308
86 #define SUNXI_DMA_DDMA_BC_REG0          0x30C
87 #define SUNXI_DMA_DDMA_PARA_REG0        0x318
88
89 #define SUNXI_DMA_DDMA_CFG_REG_LOADING  (1 << 31)
90 #define SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32 (2 << 25)
91 #define SUNXI_DMA_DDMA_CFG_REG_DDMA_DST_DRQ_TYPE_DRAM (1 << 16)
92 #define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32 (2 << 9)
93 #define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO (1 << 5)
94 #define SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC (3 << 0)
95
96 #define SUNXI_DMA_DDMA_PARA_REG_SRC_WAIT_CYC (0x0F << 0)
97 #define SUNXI_DMA_DDMA_PARA_REG_SRC_BLK_SIZE (0x7F << 8)
98
99 struct nfc_config {
100         int page_size;
101         int ecc_strength;
102         int ecc_size;
103         int addr_cycles;
104         int nseeds;
105         bool randomize;
106         bool valid;
107 };
108
109 /* minimal "boot0" style NAND support for Allwinner A20 */
110
111 /* random seed used by linux */
112 const uint16_t random_seed[128] = {
113         0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72,
114         0x0d67, 0x67f9, 0x1be7, 0x077d, 0x032f, 0x0dac, 0x2716, 0x2436,
115         0x7922, 0x1510, 0x3860, 0x5287, 0x480f, 0x4252, 0x1789, 0x5a2d,
116         0x2a49, 0x5e10, 0x437f, 0x4b4e, 0x2f45, 0x216e, 0x5cb7, 0x7130,
117         0x2a3f, 0x60e4, 0x4dc9, 0x0ef0, 0x0f52, 0x1bb9, 0x6211, 0x7a56,
118         0x226d, 0x4ea7, 0x6f36, 0x3692, 0x38bf, 0x0c62, 0x05eb, 0x4c55,
119         0x60f4, 0x728c, 0x3b6f, 0x2037, 0x7f69, 0x0936, 0x651a, 0x4ceb,
120         0x6218, 0x79f3, 0x383f, 0x18d9, 0x4f05, 0x5c82, 0x2912, 0x6f17,
121         0x6856, 0x5938, 0x1007, 0x61ab, 0x3e7f, 0x57c2, 0x542f, 0x4f62,
122         0x7454, 0x2eac, 0x7739, 0x42d4, 0x2f90, 0x435a, 0x2e52, 0x2064,
123         0x637c, 0x66ad, 0x2c90, 0x0bad, 0x759c, 0x0029, 0x0986, 0x7126,
124         0x1ca7, 0x1605, 0x386a, 0x27f5, 0x1380, 0x6d75, 0x24c3, 0x0f8e,
125         0x2b7a, 0x1418, 0x1fd1, 0x7dc1, 0x2d8e, 0x43af, 0x2267, 0x7da3,
126         0x4e3d, 0x1338, 0x50db, 0x454d, 0x764d, 0x40a3, 0x42e6, 0x262b,
127         0x2d2e, 0x1aea, 0x2e17, 0x173d, 0x3a6e, 0x71bf, 0x25f9, 0x0a5d,
128         0x7c57, 0x0fbe, 0x46ce, 0x4939, 0x6b17, 0x37bb, 0x3e91, 0x76db,
129 };
130
131 #define DEFAULT_TIMEOUT_US      100000
132
133 static int check_value_inner(int offset, int expected_bits,
134                              int timeout_us, int negation)
135 {
136         do {
137                 int val = readl(offset) & expected_bits;
138                 if (negation ? !val : val)
139                         return 1;
140                 udelay(1);
141         } while (--timeout_us);
142
143         return 0;
144 }
145
146 static inline int check_value(int offset, int expected_bits,
147                               int timeout_us)
148 {
149         return check_value_inner(offset, expected_bits, timeout_us, 0);
150 }
151
152 static inline int check_value_negated(int offset, int unexpected_bits,
153                                       int timeout_us)
154 {
155         return check_value_inner(offset, unexpected_bits, timeout_us, 1);
156 }
157
158 void nand_init(void)
159 {
160         uint32_t val;
161
162         board_nand_init();
163
164         val = readl(SUNXI_NFC_BASE + NFC_CTL);
165         /* enable and reset CTL */
166         writel(val | NFC_CTL_EN | NFC_CTL_RESET,
167                SUNXI_NFC_BASE + NFC_CTL);
168
169         if (!check_value_negated(SUNXI_NFC_BASE + NFC_CTL,
170                                  NFC_CTL_RESET, DEFAULT_TIMEOUT_US)) {
171                 printf("Couldn't initialize nand\n");
172         }
173
174         /* reset NAND */
175         writel(NFC_ST_CMD_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
176         writel(NFC_SEND_CMD1 | NFC_WAIT_FLAG | NAND_CMD_RESET,
177                SUNXI_NFC_BASE + NFC_CMD);
178
179         if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_CMD_INT_FLAG,
180                          DEFAULT_TIMEOUT_US)) {
181                 printf("Error timeout waiting for nand reset\n");
182                 return;
183         }
184         writel(NFC_ST_CMD_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
185 }
186
187 static void nand_apply_config(const struct nfc_config *conf)
188 {
189         u32 val;
190
191         val = readl(SUNXI_NFC_BASE + NFC_CTL);
192         val &= ~NFC_CTL_PAGE_SIZE_MASK;
193         writel(val | NFC_CTL_RAM_METHOD | NFC_CTL_PAGE_SIZE(conf->page_size),
194                SUNXI_NFC_BASE + NFC_CTL);
195         writel(conf->ecc_size, SUNXI_NFC_BASE + NFC_CNT);
196         writel(conf->page_size, SUNXI_NFC_BASE + NFC_SPARE_AREA);
197 }
198
199 static int nand_load_page(const struct nfc_config *conf, u32 offs)
200 {
201         int page = offs / conf->page_size;
202
203         writel((NFC_CMD_RNDOUTSTART << NFC_RANDOM_READ_CMD1_OFFSET) |
204                (NFC_CMD_RNDOUT << NFC_RANDOM_READ_CMD0_OFFSET) |
205                (NFC_CMD_READSTART << NFC_READ_CMD_OFFSET),
206                SUNXI_NFC_BASE + NFC_RCMD_SET);
207         writel(((page & 0xFFFF) << 16), SUNXI_NFC_BASE + NFC_ADDR_LOW);
208         writel((page >> 16) & 0xFF, SUNXI_NFC_BASE + NFC_ADDR_HIGH);
209         writel(NFC_ST_CMD_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
210         writel(NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_RAW_CMD | NFC_WAIT_FLAG |
211                ((conf->addr_cycles - 1) << NFC_ADDR_NUM_OFFSET) | NFC_SEND_ADR,
212                SUNXI_NFC_BASE + NFC_CMD);
213
214         if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_CMD_INT_FLAG,
215                          DEFAULT_TIMEOUT_US)) {
216                 printf("Error while initializing dma interrupt\n");
217                 return -EIO;
218         }
219
220         return 0;
221 }
222
223 static int nand_reset_column(void)
224 {
225         writel((NFC_CMD_RNDOUTSTART << NFC_RANDOM_READ_CMD1_OFFSET) |
226                (NFC_CMD_RNDOUT << NFC_RANDOM_READ_CMD0_OFFSET) |
227                (NFC_CMD_RNDOUTSTART << NFC_READ_CMD_OFFSET),
228                SUNXI_NFC_BASE + NFC_RCMD_SET);
229         writel(0, SUNXI_NFC_BASE + NFC_ADDR_LOW);
230         writel(NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_RAW_CMD |
231                (1 << NFC_ADDR_NUM_OFFSET) | NFC_SEND_ADR | NFC_CMD_RNDOUT,
232                SUNXI_NFC_BASE + NFC_CMD);
233
234         if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_CMD_INT_FLAG,
235                          DEFAULT_TIMEOUT_US)) {
236                 printf("Error while initializing dma interrupt\n");
237                 return -1;
238         }
239
240         return 0;
241 }
242
243 static int nand_read_page(const struct nfc_config *conf, u32 offs,
244                           void *dest, int len)
245 {
246         dma_addr_t dst = (dma_addr_t)dest;
247         int nsectors = len / conf->ecc_size;
248         u16 rand_seed = 0;
249         u32 val;
250         int page;
251
252         page = offs / conf->page_size;
253
254         if (offs % conf->page_size || len % conf->ecc_size ||
255             len > conf->page_size || len < 0)
256                 return -EINVAL;
257
258         /* clear ecc status */
259         writel(0, SUNXI_NFC_BASE + NFC_ECC_ST);
260
261         /* Choose correct seed if randomized */
262         if (conf->randomize)
263                 rand_seed = random_seed[page % conf->nseeds];
264
265         writel((rand_seed << 16) | (conf->ecc_strength << 12) |
266                 (conf->randomize ? NFC_ECC_RANDOM_EN : 0) |
267                 (conf->ecc_size == 512 ? NFC_ECC_BLOCK_SIZE : 0) |
268                 NFC_ECC_EN | NFC_ECC_PIPELINE | NFC_ECC_EXCEPTION,
269                 SUNXI_NFC_BASE + NFC_ECC_CTL);
270
271         flush_dcache_range(dst, ALIGN(dst + conf->ecc_size, ARCH_DMA_MINALIGN));
272
273         /* SUNXI_DMA */
274         writel(0x0, SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0); /* clr dma cmd */
275         /* read from REG_IO_DATA */
276         writel(SUNXI_NFC_BASE + NFC_IO_DATA,
277                SUNXI_DMA_BASE + SUNXI_DMA_SRC_START_ADDR_REG0);
278         /* read to RAM */
279         writel(dst, SUNXI_DMA_BASE + SUNXI_DMA_DEST_START_ADDRR_REG0);
280         writel(SUNXI_DMA_DDMA_PARA_REG_SRC_WAIT_CYC |
281                SUNXI_DMA_DDMA_PARA_REG_SRC_BLK_SIZE,
282                SUNXI_DMA_BASE + SUNXI_DMA_DDMA_PARA_REG0);
283         writel(len, SUNXI_DMA_BASE + SUNXI_DMA_DDMA_BC_REG0);
284         writel(SUNXI_DMA_DDMA_CFG_REG_LOADING |
285                SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32 |
286                SUNXI_DMA_DDMA_CFG_REG_DDMA_DST_DRQ_TYPE_DRAM |
287                SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32 |
288                SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO |
289                SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC,
290                SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0);
291
292         writel(nsectors, SUNXI_NFC_BASE + NFC_SECTOR_NUM);
293         writel(NFC_ST_DMA_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
294         writel(NFC_DATA_TRANS | NFC_PAGE_CMD | NFC_DATA_SWAP_METHOD,
295                SUNXI_NFC_BASE + NFC_CMD);
296
297         if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_DMA_INT_FLAG,
298                          DEFAULT_TIMEOUT_US)) {
299                 printf("Error while initializing dma interrupt\n");
300                 return -EIO;
301         }
302         writel(NFC_ST_DMA_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
303
304         if (!check_value_negated(SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0,
305                                  SUNXI_DMA_DDMA_CFG_REG_LOADING,
306                                  DEFAULT_TIMEOUT_US)) {
307                 printf("Error while waiting for dma transfer to finish\n");
308                 return -EIO;
309         }
310
311         invalidate_dcache_range(dst,
312                                 ALIGN(dst + conf->ecc_size, ARCH_DMA_MINALIGN));
313
314         val = readl(SUNXI_NFC_BASE + NFC_ECC_ST);
315
316         /* ECC error detected. */
317         if (val & 0xffff)
318                 return -EIO;
319
320         /*
321          * Return 1 if the page is empty.
322          * We consider the page as empty if the first ECC block is marked
323          * empty.
324          */
325         return (val & 0x10000) ? 1 : 0;
326 }
327
328 static int nand_max_ecc_strength(struct nfc_config *conf)
329 {
330         static const int ecc_bytes[] = { 32, 46, 54, 60, 74, 88, 102, 110, 116 };
331         int max_oobsize, max_ecc_bytes;
332         int nsectors = conf->page_size / conf->ecc_size;
333         int i;
334
335         /*
336          * ECC strength is limited by the size of the OOB area which is
337          * correlated with the page size.
338          */
339         switch (conf->page_size) {
340         case 2048:
341                 max_oobsize = 64;
342                 break;
343         case 4096:
344                 max_oobsize = 256;
345                 break;
346         case 8192:
347                 max_oobsize = 640;
348                 break;
349         case 16384:
350                 max_oobsize = 1664;
351                 break;
352         default:
353                 return -EINVAL;
354         }
355
356         max_ecc_bytes = max_oobsize / nsectors;
357
358         for (i = 0; i < ARRAY_SIZE(ecc_bytes); i++) {
359                 if (ecc_bytes[i] > max_ecc_bytes)
360                         break;
361         }
362
363         if (!i)
364                 return -EINVAL;
365
366         return i - 1;
367 }
368
369 static int nand_detect_ecc_config(struct nfc_config *conf, u32 offs,
370                                   void *dest)
371 {
372         /* NAND with pages > 4k will likely require 1k sector size. */
373         int min_ecc_size = conf->page_size > 4096 ? 1024 : 512;
374         int page = offs / conf->page_size;
375         int ret;
376
377         /*
378          * In most cases, 1k sectors are preferred over 512b ones, start
379          * testing this config first.
380          */
381         for (conf->ecc_size = 1024; conf->ecc_size >= min_ecc_size;
382              conf->ecc_size >>= 1) {
383                 int max_ecc_strength = nand_max_ecc_strength(conf);
384
385                 nand_apply_config(conf);
386
387                 /*
388                  * We are starting from the maximum ECC strength because
389                  * most of the time NAND vendors provide an OOB area that
390                  * barely meets the ECC requirements.
391                  */
392                 for (conf->ecc_strength = max_ecc_strength;
393                      conf->ecc_strength >= 0;
394                      conf->ecc_strength--) {
395                         conf->randomize = false;
396                         if (nand_reset_column())
397                                 return -EIO;
398
399                         /*
400                          * Only read the first sector to speedup detection.
401                          */
402                         ret = nand_read_page(conf, offs, dest, conf->ecc_size);
403                         if (!ret) {
404                                 return 0;
405                         } else if (ret > 0) {
406                                 /*
407                                  * If page is empty we can't deduce anything
408                                  * about the ECC config => stop the detection.
409                                  */
410                                 return -EINVAL;
411                         }
412
413                         conf->randomize = true;
414                         conf->nseeds = ARRAY_SIZE(random_seed);
415                         do {
416                                 if (nand_reset_column())
417                                         return -EIO;
418
419                                 if (!nand_read_page(conf, offs, dest,
420                                                     conf->ecc_size))
421                                         return 0;
422
423                                 /*
424                                  * Find the next ->nseeds value that would
425                                  * change the randomizer seed for the page
426                                  * we're trying to read.
427                                  */
428                                 while (conf->nseeds >= 16) {
429                                         int seed = page % conf->nseeds;
430
431                                         conf->nseeds >>= 1;
432                                         if (seed != page % conf->nseeds)
433                                                 break;
434                                 }
435                         } while (conf->nseeds >= 16);
436                 }
437         }
438
439         return -EINVAL;
440 }
441
442 static int nand_detect_config(struct nfc_config *conf, u32 offs, void *dest)
443 {
444         if (conf->valid)
445                 return 0;
446
447         /*
448          * Modern NANDs are more likely than legacy ones, so we start testing
449          * with 5 address cycles.
450          */
451         for (conf->addr_cycles = 5;
452              conf->addr_cycles >= 4;
453              conf->addr_cycles--) {
454                 int max_page_size = conf->addr_cycles == 4 ? 2048 : 16384;
455
456                 /*
457                  * Ignoring 1k pages cause I'm not even sure this case exist
458                  * in the real world.
459                  */
460                 for (conf->page_size = 2048; conf->page_size <= max_page_size;
461                      conf->page_size <<= 1) {
462                         if (nand_load_page(conf, offs))
463                                 return -1;
464
465                         if (!nand_detect_ecc_config(conf, offs, dest)) {
466                                 conf->valid = true;
467                                 return 0;
468                         }
469                 }
470         }
471
472         return -EINVAL;
473 }
474
475 static int nand_read_buffer(struct nfc_config *conf, uint32_t offs,
476                             unsigned int size, void *dest)
477 {
478         int first_seed, page, ret;
479
480         size = ALIGN(size, conf->page_size);
481         page = offs / conf->page_size;
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_reset_column())
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 }