mx6cuboxi: customize board_boot_order to access eMMC
[oweals/u-boot.git] / board / solidrun / mx6cuboxi / mx6cuboxi.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2015 Freescale Semiconductor, Inc.
4  *
5  * Author: Fabio Estevam <fabio.estevam@freescale.com>
6  *
7  * Copyright (C) 2013 Jon Nettleton <jon.nettleton@gmail.com>
8  *
9  * Based on SPL code from Solidrun tree, which is:
10  * Author: Tungyi Lin <tungyilin1127@gmail.com>
11  *
12  * Derived from EDM_CF_IMX6 code by TechNexion,Inc
13  * Ported to SolidRun microSOM by Rabeeh Khoury <rabeeh@solid-run.com>
14  */
15
16 #include <common.h>
17 #include <image.h>
18 #include <init.h>
19 #include <log.h>
20 #include <asm/arch/clock.h>
21 #include <asm/arch/imx-regs.h>
22 #include <asm/arch/iomux.h>
23 #include <asm/arch/mx6-pins.h>
24 #include <asm/arch/mxc_hdmi.h>
25 #include <env.h>
26 #include <linux/delay.h>
27 #include <linux/errno.h>
28 #include <asm/gpio.h>
29 #include <asm/mach-imx/iomux-v3.h>
30 #include <asm/mach-imx/sata.h>
31 #include <asm/mach-imx/video.h>
32 #include <mmc.h>
33 #include <fsl_esdhc_imx.h>
34 #include <malloc.h>
35 #include <asm/arch/crm_regs.h>
36 #include <asm/io.h>
37 #include <asm/arch/sys_proto.h>
38 #include <spl.h>
39 #include <usb.h>
40 #include <usb/ehci-ci.h>
41
42 DECLARE_GLOBAL_DATA_PTR;
43
44 #define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                   \
45         PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |                 \
46         PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
47
48 #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP |                    \
49         PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm |                 \
50         PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
51
52 #define USB_H1_VBUS     IMX_GPIO_NR(1, 0)
53
54 enum board_type {
55         CUBOXI          = 0x00,
56         HUMMINGBOARD    = 0x01,
57         HUMMINGBOARD2   = 0x02,
58         UNKNOWN         = 0x03,
59 };
60
61 static struct gpio_desc board_detect_desc[5];
62
63 #define MEM_STRIDE 0x4000000
64 static u32 get_ram_size_stride_test(u32 *base, u32 maxsize)
65 {
66         volatile u32 *addr;
67         u32          save[64];
68         u32          cnt;
69         u32          size;
70         int          i = 0;
71
72         /* First save the data */
73         for (cnt = 0; cnt < maxsize; cnt += MEM_STRIDE) {
74                 addr = (volatile u32 *)((u32)base + cnt);       /* pointer arith! */
75                 sync ();
76                 save[i++] = *addr;
77                 sync ();
78         }
79
80         /* First write a signature */
81         * (volatile u32 *)base = 0x12345678;
82         for (size = MEM_STRIDE; size < maxsize; size += MEM_STRIDE) {
83                 * (volatile u32 *)((u32)base + size) = size;
84                 sync ();
85                 if (* (volatile u32 *)((u32)base) == size) {    /* We reached the overlapping address */
86                         break;
87                 }
88         }
89
90         /* Restore the data */
91         for (cnt = (maxsize - MEM_STRIDE); i > 0; cnt -= MEM_STRIDE) {
92                 addr = (volatile u32 *)((u32)base + cnt);       /* pointer arith! */
93                 sync ();
94                 *addr = save[i--];
95                 sync ();
96         }
97
98         return (size);
99 }
100
101 int dram_init(void)
102 {
103         u32 max_size = imx_ddr_size();
104
105         gd->ram_size = get_ram_size_stride_test((u32 *) CONFIG_SYS_SDRAM_BASE,
106                                                 (u32)max_size);
107
108         return 0;
109 }
110
111 static iomux_v3_cfg_t const uart1_pads[] = {
112         IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
113         IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
114 };
115
116 static iomux_v3_cfg_t const usdhc2_pads[] = {
117         IOMUX_PADS(PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
118         IOMUX_PADS(PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
119         IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
120         IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
121         IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
122         IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
123 };
124
125 static iomux_v3_cfg_t const usdhc3_pads[] = {
126         IOMUX_PADS(PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
127         IOMUX_PADS(PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
128         IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
129         IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
130         IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
131         IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
132         IOMUX_PADS(PAD_SD3_DAT4__SD3_DATA4      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
133         IOMUX_PADS(PAD_SD3_DAT5__SD3_DATA5      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
134         IOMUX_PADS(PAD_SD3_DAT6__SD3_DATA6      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
135         IOMUX_PADS(PAD_SD3_DAT7__SD3_DATA7      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
136         IOMUX_PADS(PAD_SD3_RST__SD3_RESET       | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
137 };
138
139 static iomux_v3_cfg_t const board_detect[] = {
140         /* These pins are for sensing if it is a CuBox-i or a HummingBoard */
141         IOMUX_PADS(PAD_KEY_ROW1__GPIO4_IO09  | MUX_PAD_CTRL(UART_PAD_CTRL)),
142         IOMUX_PADS(PAD_EIM_DA4__GPIO3_IO04   | MUX_PAD_CTRL(UART_PAD_CTRL)),
143         IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08  | MUX_PAD_CTRL(UART_PAD_CTRL)),
144 };
145
146 static iomux_v3_cfg_t const som_rev_detect[] = {
147         /* These pins are for sensing if it is a CuBox-i or a HummingBoard */
148         IOMUX_PADS(PAD_CSI0_DAT14__GPIO6_IO00  | MUX_PAD_CTRL(UART_PAD_CTRL)),
149         IOMUX_PADS(PAD_CSI0_DAT18__GPIO6_IO04  | MUX_PAD_CTRL(UART_PAD_CTRL)),
150 };
151
152 static void setup_iomux_uart(void)
153 {
154         SETUP_IOMUX_PADS(uart1_pads);
155 }
156
157 static struct fsl_esdhc_cfg usdhc_cfg = {
158         .esdhc_base = USDHC2_BASE_ADDR,
159         .max_bus_width = 4,
160 };
161
162 static struct fsl_esdhc_cfg emmc_cfg = {
163         .esdhc_base = USDHC3_BASE_ADDR,
164         .max_bus_width = 8,
165 };
166
167 int board_mmc_get_env_dev(int devno)
168 {
169         return devno;
170 }
171
172 #define USDHC2_CD_GPIO  IMX_GPIO_NR(1, 4)
173
174 int board_mmc_getcd(struct mmc *mmc)
175 {
176         struct fsl_esdhc_cfg *cfg = mmc->priv;
177         int ret = 0;
178
179         switch (cfg->esdhc_base) {
180         case USDHC2_BASE_ADDR:
181                 ret = !gpio_get_value(USDHC2_CD_GPIO);
182                 break;
183         case USDHC3_BASE_ADDR:
184                 ret = (mmc_get_op_cond(mmc) < 0) ? 0 : 1; /* eMMC/uSDHC3 has no CD GPIO */
185                 break;
186         }
187
188         return ret;
189 }
190
191 static int mmc_init_spl(bd_t *bis)
192 {
193         struct src *psrc = (struct src *)SRC_BASE_ADDR;
194         unsigned reg = readl(&psrc->sbmr1) >> 11;
195
196         /*
197          * Upon reading BOOT_CFG register the following map is done:
198          * Bit 11 and 12 of BOOT_CFG register can determine the current
199          * mmc port
200          * 0x1                  SD2
201          * 0x2                  SD3
202          */
203         switch (reg & 0x3) {
204         case 0x1:
205                 SETUP_IOMUX_PADS(usdhc2_pads);
206                 usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
207                 gd->arch.sdhc_clk = usdhc_cfg.sdhc_clk;
208                 return fsl_esdhc_initialize(bis, &usdhc_cfg);
209         case 0x2:
210                 SETUP_IOMUX_PADS(usdhc3_pads);
211                 emmc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
212                 gd->arch.sdhc_clk = emmc_cfg.sdhc_clk;
213                 return fsl_esdhc_initialize(bis, &emmc_cfg);
214         }
215
216         return -ENODEV;
217 }
218
219 int board_mmc_init(bd_t *bis)
220 {
221         if (IS_ENABLED(CONFIG_SPL_BUILD))
222                 return mmc_init_spl(bis);
223
224         return 0;
225 }
226
227 #ifdef CONFIG_VIDEO_IPUV3
228 static void do_enable_hdmi(struct display_info_t const *dev)
229 {
230         imx_enable_hdmi_phy();
231 }
232
233 struct display_info_t const displays[] = {
234         {
235                 .bus    = -1,
236                 .addr   = 0,
237                 .pixfmt = IPU_PIX_FMT_RGB24,
238                 .detect = detect_hdmi,
239                 .enable = do_enable_hdmi,
240                 .mode   = {
241                         .name           = "HDMI",
242                         /* 1024x768@60Hz (VESA)*/
243                         .refresh        = 60,
244                         .xres           = 1024,
245                         .yres           = 768,
246                         .pixclock       = 15384,
247                         .left_margin    = 160,
248                         .right_margin   = 24,
249                         .upper_margin   = 29,
250                         .lower_margin   = 3,
251                         .hsync_len      = 136,
252                         .vsync_len      = 6,
253                         .sync           = FB_SYNC_EXT,
254                         .vmode          = FB_VMODE_NONINTERLACED
255                 }
256         }
257 };
258
259 size_t display_count = ARRAY_SIZE(displays);
260
261 static int setup_display(void)
262 {
263         struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
264         int reg;
265         int timeout = 100000;
266
267         enable_ipu_clock();
268         imx_setup_hdmi();
269
270         /* set video pll to 455MHz (24MHz * (37+11/12) / 2) */
271         setbits_le32(&ccm->analog_pll_video, BM_ANADIG_PLL_VIDEO_POWERDOWN);
272
273         reg = readl(&ccm->analog_pll_video);
274         reg &= ~BM_ANADIG_PLL_VIDEO_DIV_SELECT;
275         reg |= BF_ANADIG_PLL_VIDEO_DIV_SELECT(37);
276         reg &= ~BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT;
277         reg |= BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(1);
278         writel(reg, &ccm->analog_pll_video);
279
280         writel(BF_ANADIG_PLL_VIDEO_NUM_A(11), &ccm->analog_pll_video_num);
281         writel(BF_ANADIG_PLL_VIDEO_DENOM_B(12), &ccm->analog_pll_video_denom);
282
283         reg &= ~BM_ANADIG_PLL_VIDEO_POWERDOWN;
284         writel(reg, &ccm->analog_pll_video);
285
286         while (timeout--)
287                 if (readl(&ccm->analog_pll_video) & BM_ANADIG_PLL_VIDEO_LOCK)
288                         break;
289         if (timeout < 0) {
290                 printf("Warning: video pll lock timeout!\n");
291                 return -ETIMEDOUT;
292         }
293
294         reg = readl(&ccm->analog_pll_video);
295         reg |= BM_ANADIG_PLL_VIDEO_ENABLE;
296         reg &= ~BM_ANADIG_PLL_VIDEO_BYPASS;
297         writel(reg, &ccm->analog_pll_video);
298
299         /* gate ipu1_di0_clk */
300         clrbits_le32(&ccm->CCGR3, MXC_CCM_CCGR3_LDB_DI0_MASK);
301
302         /* select video_pll clock / 7  for ipu1_di0_clk -> 65MHz pixclock */
303         reg = readl(&ccm->chsccdr);
304         reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK |
305                  MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK |
306                  MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK);
307         reg |= (2 << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET) |
308                (6 << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET) |
309                (0 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
310         writel(reg, &ccm->chsccdr);
311
312         /* enable ipu1_di0_clk */
313         setbits_le32(&ccm->CCGR3, MXC_CCM_CCGR3_LDB_DI0_MASK);
314
315         return 0;
316 }
317 #endif /* CONFIG_VIDEO_IPUV3 */
318
319 static int setup_fec(void)
320 {
321         struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
322         int ret;
323
324         ret = enable_fec_anatop_clock(0, ENET_25MHZ);
325         if (ret)
326                 return ret;
327
328         /* set gpr1[ENET_CLK_SEL] */
329         setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_ENET_CLK_SEL_MASK);
330
331         return 0;
332 }
333
334 int board_early_init_f(void)
335 {
336         setup_iomux_uart();
337
338 #ifdef CONFIG_CMD_SATA
339         setup_sata();
340 #endif
341         setup_fec();
342
343         return 0;
344 }
345
346 int board_init(void)
347 {
348         int ret = 0;
349
350         /* address of boot parameters */
351         gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
352
353 #ifdef CONFIG_VIDEO_IPUV3
354         ret = setup_display();
355 #endif
356
357         return ret;
358 }
359
360 static int request_detect_gpios(void)
361 {
362         int node;
363         int ret;
364
365         node = fdt_node_offset_by_compatible(gd->fdt_blob, 0,
366                 "solidrun,hummingboard-detect");
367         if (node < 0)
368                 return -ENODEV;
369
370         ret = gpio_request_list_by_name_nodev(offset_to_ofnode(node),
371                 "detect-gpios", board_detect_desc,
372                 ARRAY_SIZE(board_detect_desc), GPIOD_IS_IN);
373
374         return ret;
375 }
376
377 static int free_detect_gpios(void)
378 {
379         return gpio_free_list_nodev(board_detect_desc,
380                 ARRAY_SIZE(board_detect_desc));
381 }
382
383 static enum board_type board_type(void)
384 {
385         int val1, val2, val3;
386
387         SETUP_IOMUX_PADS(board_detect);
388
389         /*
390          * Machine selection -
391          * Machine      val1, val2, val3
392          * ----------------------------
393          * HB2            x     x    0
394          * HB rev 3.x     x     0    x
395          * CBi            0     1    x
396          * HB             1     1    x
397          */
398
399         gpio_direction_input(IMX_GPIO_NR(2, 8));
400         val3 = gpio_get_value(IMX_GPIO_NR(2, 8));
401
402         if (val3 == 0)
403                 return HUMMINGBOARD2;
404
405         gpio_direction_input(IMX_GPIO_NR(3, 4));
406         val2 = gpio_get_value(IMX_GPIO_NR(3, 4));
407
408         if (val2 == 0)
409                 return HUMMINGBOARD;
410
411         gpio_direction_input(IMX_GPIO_NR(4, 9));
412         val1 = gpio_get_value(IMX_GPIO_NR(4, 9));
413
414         if (val1 == 0) {
415                 return CUBOXI;
416         } else {
417                 return HUMMINGBOARD;
418         }
419 }
420
421 static bool is_rev_15_som(void)
422 {
423         int val1, val2;
424         SETUP_IOMUX_PADS(som_rev_detect);
425
426         val1 = gpio_get_value(IMX_GPIO_NR(6, 0));
427         val2 = gpio_get_value(IMX_GPIO_NR(6, 4));
428
429         if (val1 == 1 && val2 == 0)
430                 return true;
431
432         return false;
433 }
434
435 static bool has_emmc(void)
436 {
437         struct mmc *mmc;
438         mmc = find_mmc_device(2);
439         if (!mmc)
440                 return 0;
441         return (mmc_get_op_cond(mmc) < 0) ? 0 : 1;
442 }
443
444 int checkboard(void)
445 {
446         request_detect_gpios();
447
448         switch (board_type()) {
449         case CUBOXI:
450                 puts("Board: MX6 Cubox-i");
451                 break;
452         case HUMMINGBOARD:
453                 puts("Board: MX6 HummingBoard");
454                 break;
455         case HUMMINGBOARD2:
456                 puts("Board: MX6 HummingBoard2");
457                 break;
458         case UNKNOWN:
459         default:
460                 puts("Board: Unknown\n");
461                 goto out;
462         }
463
464         if (is_rev_15_som())
465                 puts(" (som rev 1.5)\n");
466         else
467                 puts("\n");
468
469         free_detect_gpios();
470 out:
471         return 0;
472 }
473
474 /* Override the default implementation, DT model is not accurate */
475 int show_board_info(void)
476 {
477         return checkboard();
478 }
479
480 int board_late_init(void)
481 {
482 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
483         request_detect_gpios();
484
485         switch (board_type()) {
486         case CUBOXI:
487                 env_set("board_name", "CUBOXI");
488                 break;
489         case HUMMINGBOARD:
490                 env_set("board_name", "HUMMINGBOARD");
491                 break;
492         case HUMMINGBOARD2:
493                 env_set("board_name", "HUMMINGBOARD2");
494                 break;
495         case UNKNOWN:
496         default:
497                 env_set("board_name", "CUBOXI");
498         }
499
500         if (is_mx6dq())
501                 env_set("board_rev", "MX6Q");
502         else
503                 env_set("board_rev", "MX6DL");
504
505         if (is_rev_15_som())
506                 env_set("som_rev", "V15");
507
508         if (has_emmc())
509                 env_set("has_emmc", "yes");
510
511         free_detect_gpios();
512 #endif
513
514         return 0;
515 }
516
517 /*
518  * This is not a perfect match. Avoid dependency on the DM GPIO driver needed
519  * for accurate board detection. Hummingboard2 DT is good enough for U-Boot on
520  * all Hummingboard/Cubox-i platforms.
521  */
522 int board_fit_config_name_match(const char *name)
523 {
524         char tmp_name[36];
525
526         snprintf(tmp_name, sizeof(tmp_name), "%s-hummingboard2-emmc-som-v15",
527                         is_mx6dq() ? "imx6q" : "imx6dl");
528
529         return strcmp(name, tmp_name);
530 }
531
532 void board_boot_order(u32 *spl_boot_list)
533 {
534         struct src *psrc = (struct src *)SRC_BASE_ADDR;
535         unsigned int reg = readl(&psrc->sbmr1) >> 11;
536         u32 boot_mode = imx6_src_get_boot_mode() & IMX6_BMODE_MASK;
537         unsigned int bmode = readl(&src_base->sbmr2);
538
539         /* If bmode is serial or USB phy is active, return serial */
540         if (((bmode >> 24) & 0x03) == 0x01 || is_usbotg_phy_active()) {
541                 spl_boot_list[0] = BOOT_DEVICE_BOARD;
542                 return;
543         }
544
545         switch (boot_mode >> IMX6_BMODE_SHIFT) {
546         case IMX6_BMODE_SD:
547         case IMX6_BMODE_ESD:
548         case IMX6_BMODE_MMC:
549         case IMX6_BMODE_EMMC:
550                 /*
551                  * Upon reading BOOT_CFG register the following map is done:
552                  * Bit 11 and 12 of BOOT_CFG register can determine the current
553                  * mmc port
554                  * 0x1                  SD2
555                  * 0x2                  SD3
556                  */
557
558                 reg &= 0x3; /* Only care about bottom 2 bits */
559                 switch (reg) {
560                 case 1:
561                         SETUP_IOMUX_PADS(usdhc2_pads);
562                         spl_boot_list[0] = BOOT_DEVICE_MMC1;
563                         break;
564                 case 2:
565                         SETUP_IOMUX_PADS(usdhc3_pads);
566                         spl_boot_list[0] = BOOT_DEVICE_MMC2;
567                         break;
568                 }
569                 break;
570         default:
571                 /* By default use USB downloader */
572                 spl_boot_list[0] = BOOT_DEVICE_BOARD;
573                 break;
574         }
575
576         /* As a last resort, use serial downloader */
577         spl_boot_list[1] = BOOT_DEVICE_BOARD;
578 }
579
580 #ifdef CONFIG_SPL_BUILD
581 #include <asm/arch/mx6-ddr.h>
582 static const struct mx6dq_iomux_ddr_regs mx6q_ddr_ioregs = {
583         .dram_sdclk_0 =  0x00020030,
584         .dram_sdclk_1 =  0x00020030,
585         .dram_cas =  0x00020030,
586         .dram_ras =  0x00020030,
587         .dram_reset =  0x000c0030,
588         .dram_sdcke0 =  0x00003000,
589         .dram_sdcke1 =  0x00003000,
590         .dram_sdba2 =  0x00000000,
591         .dram_sdodt0 =  0x00003030,
592         .dram_sdodt1 =  0x00003030,
593         .dram_sdqs0 =  0x00000030,
594         .dram_sdqs1 =  0x00000030,
595         .dram_sdqs2 =  0x00000030,
596         .dram_sdqs3 =  0x00000030,
597         .dram_sdqs4 =  0x00000030,
598         .dram_sdqs5 =  0x00000030,
599         .dram_sdqs6 =  0x00000030,
600         .dram_sdqs7 =  0x00000030,
601         .dram_dqm0 =  0x00020030,
602         .dram_dqm1 =  0x00020030,
603         .dram_dqm2 =  0x00020030,
604         .dram_dqm3 =  0x00020030,
605         .dram_dqm4 =  0x00020030,
606         .dram_dqm5 =  0x00020030,
607         .dram_dqm6 =  0x00020030,
608         .dram_dqm7 =  0x00020030,
609 };
610
611 static const struct mx6sdl_iomux_ddr_regs mx6dl_ddr_ioregs = {
612         .dram_sdclk_0 = 0x00000028,
613         .dram_sdclk_1 = 0x00000028,
614         .dram_cas =     0x00000028,
615         .dram_ras =     0x00000028,
616         .dram_reset =   0x000c0028,
617         .dram_sdcke0 =  0x00003000,
618         .dram_sdcke1 =  0x00003000,
619         .dram_sdba2 =   0x00000000,
620         .dram_sdodt0 =  0x00003030,
621         .dram_sdodt1 =  0x00003030,
622         .dram_sdqs0 =   0x00000028,
623         .dram_sdqs1 =   0x00000028,
624         .dram_sdqs2 =   0x00000028,
625         .dram_sdqs3 =   0x00000028,
626         .dram_sdqs4 =   0x00000028,
627         .dram_sdqs5 =   0x00000028,
628         .dram_sdqs6 =   0x00000028,
629         .dram_sdqs7 =   0x00000028,
630         .dram_dqm0 =    0x00000028,
631         .dram_dqm1 =    0x00000028,
632         .dram_dqm2 =    0x00000028,
633         .dram_dqm3 =    0x00000028,
634         .dram_dqm4 =    0x00000028,
635         .dram_dqm5 =    0x00000028,
636         .dram_dqm6 =    0x00000028,
637         .dram_dqm7 =    0x00000028,
638 };
639
640 static const struct mx6dq_iomux_grp_regs mx6q_grp_ioregs = {
641         .grp_ddr_type =  0x000C0000,
642         .grp_ddrmode_ctl =  0x00020000,
643         .grp_ddrpke =  0x00000000,
644         .grp_addds =  0x00000030,
645         .grp_ctlds =  0x00000030,
646         .grp_ddrmode =  0x00020000,
647         .grp_b0ds =  0x00000030,
648         .grp_b1ds =  0x00000030,
649         .grp_b2ds =  0x00000030,
650         .grp_b3ds =  0x00000030,
651         .grp_b4ds =  0x00000030,
652         .grp_b5ds =  0x00000030,
653         .grp_b6ds =  0x00000030,
654         .grp_b7ds =  0x00000030,
655 };
656
657 static const struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = {
658         .grp_ddr_type = 0x000c0000,
659         .grp_ddrmode_ctl = 0x00020000,
660         .grp_ddrpke = 0x00000000,
661         .grp_addds = 0x00000028,
662         .grp_ctlds = 0x00000028,
663         .grp_ddrmode = 0x00020000,
664         .grp_b0ds = 0x00000028,
665         .grp_b1ds = 0x00000028,
666         .grp_b2ds = 0x00000028,
667         .grp_b3ds = 0x00000028,
668         .grp_b4ds = 0x00000028,
669         .grp_b5ds = 0x00000028,
670         .grp_b6ds = 0x00000028,
671         .grp_b7ds = 0x00000028,
672 };
673
674 /* microSOM with Dual processor and 1GB memory */
675 static const struct mx6_mmdc_calibration mx6q_1g_mmcd_calib = {
676         .p0_mpwldectrl0 =  0x00000000,
677         .p0_mpwldectrl1 =  0x00000000,
678         .p1_mpwldectrl0 =  0x00000000,
679         .p1_mpwldectrl1 =  0x00000000,
680         .p0_mpdgctrl0 =    0x0314031c,
681         .p0_mpdgctrl1 =    0x023e0304,
682         .p1_mpdgctrl0 =    0x03240330,
683         .p1_mpdgctrl1 =    0x03180260,
684         .p0_mprddlctl =    0x3630323c,
685         .p1_mprddlctl =    0x3436283a,
686         .p0_mpwrdlctl =    0x36344038,
687         .p1_mpwrdlctl =    0x422a423c,
688 };
689
690 /* microSOM with Quad processor and 2GB memory */
691 static const struct mx6_mmdc_calibration mx6q_2g_mmcd_calib = {
692         .p0_mpwldectrl0 =  0x00000000,
693         .p0_mpwldectrl1 =  0x00000000,
694         .p1_mpwldectrl0 =  0x00000000,
695         .p1_mpwldectrl1 =  0x00000000,
696         .p0_mpdgctrl0 =    0x0314031c,
697         .p0_mpdgctrl1 =    0x023e0304,
698         .p1_mpdgctrl0 =    0x03240330,
699         .p1_mpdgctrl1 =    0x03180260,
700         .p0_mprddlctl =    0x3630323c,
701         .p1_mprddlctl =    0x3436283a,
702         .p0_mpwrdlctl =    0x36344038,
703         .p1_mpwrdlctl =    0x422a423c,
704 };
705
706 /* microSOM with Solo processor and 512MB memory */
707 static const struct mx6_mmdc_calibration mx6dl_512m_mmcd_calib = {
708         .p0_mpwldectrl0 = 0x0045004D,
709         .p0_mpwldectrl1 = 0x003A0047,
710         .p0_mpdgctrl0 =   0x023C0224,
711         .p0_mpdgctrl1 =   0x02000220,
712         .p0_mprddlctl =   0x44444846,
713         .p0_mpwrdlctl =   0x32343032,
714 };
715
716 /* microSOM with Dual lite processor and 1GB memory */
717 static const struct mx6_mmdc_calibration mx6dl_1g_mmcd_calib = {
718         .p0_mpwldectrl0 =  0x0045004D,
719         .p0_mpwldectrl1 =  0x003A0047,
720         .p1_mpwldectrl0 =  0x001F001F,
721         .p1_mpwldectrl1 =  0x00210035,
722         .p0_mpdgctrl0 =    0x023C0224,
723         .p0_mpdgctrl1 =    0x02000220,
724         .p1_mpdgctrl0 =    0x02200220,
725         .p1_mpdgctrl1 =    0x02040208,
726         .p0_mprddlctl =    0x44444846,
727         .p1_mprddlctl =    0x4042463C,
728         .p0_mpwrdlctl =    0x32343032,
729         .p1_mpwrdlctl =    0x36363430,
730 };
731
732 static struct mx6_ddr3_cfg mem_ddr_2g = {
733         .mem_speed = 1600,
734         .density   = 2,
735         .width     = 16,
736         .banks     = 8,
737         .rowaddr   = 14,
738         .coladdr   = 10,
739         .pagesz    = 2,
740         .trcd      = 1375,
741         .trcmin    = 4875,
742         .trasmin   = 3500,
743 };
744
745 static struct mx6_ddr3_cfg mem_ddr_4g = {
746         .mem_speed = 1600,
747         .density = 4,
748         .width = 16,
749         .banks = 8,
750         .rowaddr = 16,
751         .coladdr = 10,
752         .pagesz = 2,
753         .trcd = 1375,
754         .trcmin = 4875,
755         .trasmin = 3500,
756 };
757
758 static void ccgr_init(void)
759 {
760         struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
761
762         writel(0x00C03F3F, &ccm->CCGR0);
763         writel(0x0030FC03, &ccm->CCGR1);
764         writel(0x0FFFC000, &ccm->CCGR2);
765         writel(0x3FF00000, &ccm->CCGR3);
766         writel(0x00FFF300, &ccm->CCGR4);
767         writel(0x0F0000C3, &ccm->CCGR5);
768         writel(0x000003FF, &ccm->CCGR6);
769 }
770
771 static void spl_dram_init(int width)
772 {
773         struct mx6_ddr_sysinfo sysinfo = {
774                 /* width of data bus: 0=16, 1=32, 2=64 */
775                 .dsize = width / 32,
776                 /* config for full 4GB range so that get_mem_size() works */
777                 .cs_density = 32,       /* 32Gb per CS */
778                 .ncs = 1,               /* single chip select */
779                 .cs1_mirror = 0,
780                 .rtt_wr = 1 /*DDR3_RTT_60_OHM*/,        /* RTT_Wr = RZQ/4 */
781                 .rtt_nom = 1 /*DDR3_RTT_60_OHM*/,       /* RTT_Nom = RZQ/4 */
782                 .walat = 1,     /* Write additional latency */
783                 .ralat = 5,     /* Read additional latency */
784                 .mif3_mode = 3, /* Command prediction working mode */
785                 .bi_on = 1,     /* Bank interleaving enabled */
786                 .sde_to_rst = 0x10,     /* 14 cycles, 200us (JEDEC default) */
787                 .rst_to_cke = 0x23,     /* 33 cycles, 500us (JEDEC default) */
788                 .ddr_type = DDR_TYPE_DDR3,
789                 .refsel = 1,    /* Refresh cycles at 32KHz */
790                 .refr = 7,      /* 8 refresh commands per refresh cycle */
791         };
792
793         if (is_mx6dq())
794                 mx6dq_dram_iocfg(width, &mx6q_ddr_ioregs, &mx6q_grp_ioregs);
795         else
796                 mx6sdl_dram_iocfg(width, &mx6dl_ddr_ioregs, &mx6sdl_grp_ioregs);
797
798         if (is_cpu_type(MXC_CPU_MX6D))
799                 mx6_dram_cfg(&sysinfo, &mx6q_1g_mmcd_calib, &mem_ddr_2g);
800         else if (is_cpu_type(MXC_CPU_MX6Q))
801                 mx6_dram_cfg(&sysinfo, &mx6q_2g_mmcd_calib, &mem_ddr_4g);
802         else if (is_cpu_type(MXC_CPU_MX6DL))
803                 mx6_dram_cfg(&sysinfo, &mx6dl_1g_mmcd_calib, &mem_ddr_2g);
804         else if (is_cpu_type(MXC_CPU_MX6SOLO))
805                 mx6_dram_cfg(&sysinfo, &mx6dl_512m_mmcd_calib, &mem_ddr_2g);
806 }
807
808 void board_init_f(ulong dummy)
809 {
810         /* setup AIPS and disable watchdog */
811         arch_cpu_init();
812
813         ccgr_init();
814         gpr_init();
815
816         /* iomux and setup of i2c */
817         board_early_init_f();
818
819         /* setup GP timer */
820         timer_init();
821
822         /* UART clocks enabled and gd valid - init serial console */
823         preloader_console_init();
824
825         /* DDR initialization */
826         if (is_cpu_type(MXC_CPU_MX6SOLO))
827                 spl_dram_init(32);
828         else
829                 spl_dram_init(64);
830
831         /* Clear the BSS. */
832         memset(__bss_start, 0, __bss_end - __bss_start);
833
834         /* load/boot image from boot device */
835         board_init_r(NULL, 0);
836 }
837 #endif