Merge branch 'master' of git://git.denx.de/u-boot-spi
[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 <asm/arch/clock.h>
17 #include <asm/arch/imx-regs.h>
18 #include <asm/arch/iomux.h>
19 #include <asm/arch/mx6-pins.h>
20 #include <asm/arch/mxc_hdmi.h>
21 #include <linux/errno.h>
22 #include <asm/gpio.h>
23 #include <asm/mach-imx/iomux-v3.h>
24 #include <asm/mach-imx/sata.h>
25 #include <asm/mach-imx/video.h>
26 #include <mmc.h>
27 #include <fsl_esdhc.h>
28 #include <malloc.h>
29 #include <miiphy.h>
30 #include <netdev.h>
31 #include <asm/arch/crm_regs.h>
32 #include <asm/io.h>
33 #include <asm/arch/sys_proto.h>
34 #include <spl.h>
35 #include <usb.h>
36 #include <usb/ehci-ci.h>
37
38 DECLARE_GLOBAL_DATA_PTR;
39
40 #define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                   \
41         PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |                 \
42         PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
43
44 #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP |                    \
45         PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm |                 \
46         PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
47
48 #define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                   \
49         PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
50
51 #define ENET_PAD_CTRL_PD  (PAD_CTL_PUS_100K_DOWN |              \
52         PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
53
54 #define ENET_PAD_CTRL_CLK  ((PAD_CTL_PUS_100K_UP & ~PAD_CTL_PKE) | \
55         PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
56
57 #define ETH_PHY_RESET   IMX_GPIO_NR(4, 15)
58 #define USB_H1_VBUS     IMX_GPIO_NR(1, 0)
59
60 enum board_type {
61         CUBOXI          = 0x00,
62         HUMMINGBOARD    = 0x01,
63         HUMMINGBOARD2   = 0x02,
64         UNKNOWN         = 0x03,
65 };
66
67 #define MEM_STRIDE 0x4000000
68 static u32 get_ram_size_stride_test(u32 *base, u32 maxsize)
69 {
70         volatile u32 *addr;
71         u32          save[64];
72         u32          cnt;
73         u32          size;
74         int          i = 0;
75
76         /* First save the data */
77         for (cnt = 0; cnt < maxsize; cnt += MEM_STRIDE) {
78                 addr = (volatile u32 *)((u32)base + cnt);       /* pointer arith! */
79                 sync ();
80                 save[i++] = *addr;
81                 sync ();
82         }
83
84         /* First write a signature */
85         * (volatile u32 *)base = 0x12345678;
86         for (size = MEM_STRIDE; size < maxsize; size += MEM_STRIDE) {
87                 * (volatile u32 *)((u32)base + size) = size;
88                 sync ();
89                 if (* (volatile u32 *)((u32)base) == size) {    /* We reached the overlapping address */
90                         break;
91                 }
92         }
93
94         /* Restore the data */
95         for (cnt = (maxsize - MEM_STRIDE); i > 0; cnt -= MEM_STRIDE) {
96                 addr = (volatile u32 *)((u32)base + cnt);       /* pointer arith! */
97                 sync ();
98                 *addr = save[i--];
99                 sync ();
100         }
101
102         return (size);
103 }
104
105 int dram_init(void)
106 {
107         u32 max_size = imx_ddr_size();
108
109         gd->ram_size = get_ram_size_stride_test((u32 *) CONFIG_SYS_SDRAM_BASE,
110                                                 (u32)max_size);
111
112         return 0;
113 }
114
115 static iomux_v3_cfg_t const uart1_pads[] = {
116         IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
117         IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
118 };
119
120 static iomux_v3_cfg_t const usdhc2_pads[] = {
121         IOMUX_PADS(PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
122         IOMUX_PADS(PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
123         IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
124         IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
125         IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
126         IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
127 };
128
129 static iomux_v3_cfg_t const board_detect[] = {
130         /* These pins are for sensing if it is a CuBox-i or a HummingBoard */
131         IOMUX_PADS(PAD_KEY_ROW1__GPIO4_IO09  | MUX_PAD_CTRL(UART_PAD_CTRL)),
132         IOMUX_PADS(PAD_EIM_DA4__GPIO3_IO04   | MUX_PAD_CTRL(UART_PAD_CTRL)),
133         IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08  | MUX_PAD_CTRL(UART_PAD_CTRL)),
134 };
135
136 static iomux_v3_cfg_t const som_rev_detect[] = {
137         /* These pins are for sensing if it is a CuBox-i or a HummingBoard */
138         IOMUX_PADS(PAD_CSI0_DAT14__GPIO6_IO00  | MUX_PAD_CTRL(UART_PAD_CTRL)),
139         IOMUX_PADS(PAD_CSI0_DAT18__GPIO6_IO04  | MUX_PAD_CTRL(UART_PAD_CTRL)),
140 };
141
142 static iomux_v3_cfg_t const usb_pads[] = {
143         IOMUX_PADS(PAD_GPIO_0__GPIO1_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL)),
144 };
145
146 static void setup_iomux_uart(void)
147 {
148         SETUP_IOMUX_PADS(uart1_pads);
149 }
150
151 static struct fsl_esdhc_cfg usdhc_cfg[1] = {
152         {USDHC2_BASE_ADDR},
153 };
154
155 int board_mmc_getcd(struct mmc *mmc)
156 {
157         return 1; /* uSDHC2 is always present */
158 }
159
160 int board_mmc_init(bd_t *bis)
161 {
162         SETUP_IOMUX_PADS(usdhc2_pads);
163         usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
164         usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
165         gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
166
167         return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
168 }
169
170 static iomux_v3_cfg_t const enet_pads[] = {
171         IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)),
172         IOMUX_PADS(PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
173         /* AR8035 reset */
174         IOMUX_PADS(PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD)),
175         /* AR8035 interrupt */
176         IOMUX_PADS(PAD_DI0_PIN2__GPIO4_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL)),
177         /* GPIO16 -> AR8035 25MHz */
178         IOMUX_PADS(PAD_GPIO_16__ENET_REF_CLK      | MUX_PAD_CTRL(NO_PAD_CTRL)),
179         IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC       | MUX_PAD_CTRL(NO_PAD_CTRL)),
180         IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
181         IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
182         IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
183         IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
184         IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
185         /* AR8035 CLK_25M --> ENET_REF_CLK (V22) */
186         IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL_CLK)),
187         IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
188         IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD)),
189         IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD)),
190         IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
191         IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
192         IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL_PD)),
193         IOMUX_PADS(PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD)),
194         IOMUX_PADS(PAD_ENET_RXD1__GPIO1_IO26 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD)),
195 };
196
197 static void setup_iomux_enet(void)
198 {
199         SETUP_IOMUX_PADS(enet_pads);
200
201         gpio_direction_output(ETH_PHY_RESET, 0);
202         mdelay(10);
203         gpio_set_value(ETH_PHY_RESET, 1);
204         udelay(100);
205 }
206
207 int board_phy_config(struct phy_device *phydev)
208 {
209         if (phydev->drv->config)
210                 phydev->drv->config(phydev);
211
212         return 0;
213 }
214
215 /* On Cuboxi Ethernet PHY can be located at addresses 0x0 or 0x4 */
216 #define ETH_PHY_MASK    ((1 << 0x0) | (1 << 0x4))
217
218 int board_eth_init(bd_t *bis)
219 {
220         struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
221         struct mii_dev *bus;
222         struct phy_device *phydev;
223
224         int ret = enable_fec_anatop_clock(0, ENET_25MHZ);
225         if (ret)
226                 return ret;
227
228         /* set gpr1[ENET_CLK_SEL] */
229         setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_ENET_CLK_SEL_MASK);
230
231         setup_iomux_enet();
232
233         bus = fec_get_miibus(IMX_FEC_BASE, -1);
234         if (!bus)
235                 return -EINVAL;
236
237         phydev = phy_find_by_mask(bus, ETH_PHY_MASK, PHY_INTERFACE_MODE_RGMII);
238         if (!phydev) {
239                 ret = -EINVAL;
240                 goto free_bus;
241         }
242
243         debug("using phy at address %d\n", phydev->addr);
244         ret = fec_probe(bis, -1, IMX_FEC_BASE, bus, phydev);
245         if (ret)
246                 goto free_phydev;
247
248         return 0;
249
250 free_phydev:
251         free(phydev);
252 free_bus:
253         free(bus);
254         return ret;
255 }
256
257 #ifdef CONFIG_VIDEO_IPUV3
258 static void do_enable_hdmi(struct display_info_t const *dev)
259 {
260         imx_enable_hdmi_phy();
261 }
262
263 struct display_info_t const displays[] = {
264         {
265                 .bus    = -1,
266                 .addr   = 0,
267                 .pixfmt = IPU_PIX_FMT_RGB24,
268                 .detect = detect_hdmi,
269                 .enable = do_enable_hdmi,
270                 .mode   = {
271                         .name           = "HDMI",
272                         /* 1024x768@60Hz (VESA)*/
273                         .refresh        = 60,
274                         .xres           = 1024,
275                         .yres           = 768,
276                         .pixclock       = 15384,
277                         .left_margin    = 160,
278                         .right_margin   = 24,
279                         .upper_margin   = 29,
280                         .lower_margin   = 3,
281                         .hsync_len      = 136,
282                         .vsync_len      = 6,
283                         .sync           = FB_SYNC_EXT,
284                         .vmode          = FB_VMODE_NONINTERLACED
285                 }
286         }
287 };
288
289 size_t display_count = ARRAY_SIZE(displays);
290
291 static int setup_display(void)
292 {
293         struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
294         int reg;
295         int timeout = 100000;
296
297         enable_ipu_clock();
298         imx_setup_hdmi();
299
300         /* set video pll to 455MHz (24MHz * (37+11/12) / 2) */
301         setbits_le32(&ccm->analog_pll_video, BM_ANADIG_PLL_VIDEO_POWERDOWN);
302
303         reg = readl(&ccm->analog_pll_video);
304         reg &= ~BM_ANADIG_PLL_VIDEO_DIV_SELECT;
305         reg |= BF_ANADIG_PLL_VIDEO_DIV_SELECT(37);
306         reg &= ~BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT;
307         reg |= BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(1);
308         writel(reg, &ccm->analog_pll_video);
309
310         writel(BF_ANADIG_PLL_VIDEO_NUM_A(11), &ccm->analog_pll_video_num);
311         writel(BF_ANADIG_PLL_VIDEO_DENOM_B(12), &ccm->analog_pll_video_denom);
312
313         reg &= ~BM_ANADIG_PLL_VIDEO_POWERDOWN;
314         writel(reg, &ccm->analog_pll_video);
315
316         while (timeout--)
317                 if (readl(&ccm->analog_pll_video) & BM_ANADIG_PLL_VIDEO_LOCK)
318                         break;
319         if (timeout < 0) {
320                 printf("Warning: video pll lock timeout!\n");
321                 return -ETIMEDOUT;
322         }
323
324         reg = readl(&ccm->analog_pll_video);
325         reg |= BM_ANADIG_PLL_VIDEO_ENABLE;
326         reg &= ~BM_ANADIG_PLL_VIDEO_BYPASS;
327         writel(reg, &ccm->analog_pll_video);
328
329         /* gate ipu1_di0_clk */
330         clrbits_le32(&ccm->CCGR3, MXC_CCM_CCGR3_LDB_DI0_MASK);
331
332         /* select video_pll clock / 7  for ipu1_di0_clk -> 65MHz pixclock */
333         reg = readl(&ccm->chsccdr);
334         reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK |
335                  MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK |
336                  MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK);
337         reg |= (2 << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET) |
338                (6 << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET) |
339                (0 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
340         writel(reg, &ccm->chsccdr);
341
342         /* enable ipu1_di0_clk */
343         setbits_le32(&ccm->CCGR3, MXC_CCM_CCGR3_LDB_DI0_MASK);
344
345         return 0;
346 }
347 #endif /* CONFIG_VIDEO_IPUV3 */
348
349 #ifdef CONFIG_USB_EHCI_MX6
350 static void setup_usb(void)
351 {
352         SETUP_IOMUX_PADS(usb_pads);
353 }
354
355 int board_ehci_hcd_init(int port)
356 {
357         if (port == 1)
358                 gpio_direction_output(USB_H1_VBUS, 1);
359
360         return 0;
361 }
362 #endif
363
364 int board_early_init_f(void)
365 {
366         setup_iomux_uart();
367
368 #ifdef CONFIG_CMD_SATA
369         setup_sata();
370 #endif
371
372 #ifdef CONFIG_USB_EHCI_MX6
373         setup_usb();
374 #endif
375         return 0;
376 }
377
378 int board_init(void)
379 {
380         int ret = 0;
381
382         /* address of boot parameters */
383         gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
384
385 #ifdef CONFIG_VIDEO_IPUV3
386         ret = setup_display();
387 #endif
388
389         return ret;
390 }
391
392 static enum board_type board_type(void)
393 {
394         int val1, val2, val3;
395
396         SETUP_IOMUX_PADS(board_detect);
397
398         /*
399          * Machine selection -
400          * Machine      val1, val2, val3
401          * ----------------------------
402          * HB2            x     x    0
403          * HB rev 3.x     x     0    x
404          * CBi            0     1    x
405          * HB             1     1    x
406          */
407
408         gpio_direction_input(IMX_GPIO_NR(2, 8));
409         val3 = gpio_get_value(IMX_GPIO_NR(2, 8));
410
411         if (val3 == 0)
412                 return HUMMINGBOARD2;
413
414         gpio_direction_input(IMX_GPIO_NR(3, 4));
415         val2 = gpio_get_value(IMX_GPIO_NR(3, 4));
416
417         if (val2 == 0)
418                 return HUMMINGBOARD;
419
420         gpio_direction_input(IMX_GPIO_NR(4, 9));
421         val1 = gpio_get_value(IMX_GPIO_NR(4, 9));
422
423         if (val1 == 0) {
424                 return CUBOXI;
425         } else {
426                 return HUMMINGBOARD;
427         }
428 }
429
430 static bool is_rev_15_som(void)
431 {
432         int val1, val2;
433         SETUP_IOMUX_PADS(som_rev_detect);
434
435         val1 = gpio_get_value(IMX_GPIO_NR(6, 0));
436         val2 = gpio_get_value(IMX_GPIO_NR(6, 4));
437
438         if (val1 == 1 && val2 == 0)
439                 return true;
440
441         return false;
442 }
443
444 int checkboard(void)
445 {
446         switch (board_type()) {
447         case CUBOXI:
448                 puts("Board: MX6 Cubox-i");
449                 break;
450         case HUMMINGBOARD:
451                 puts("Board: MX6 HummingBoard");
452                 break;
453         case HUMMINGBOARD2:
454                 puts("Board: MX6 HummingBoard2");
455                 break;
456         case UNKNOWN:
457         default:
458                 puts("Board: Unknown\n");
459                 goto out;
460         }
461
462         if (is_rev_15_som())
463                 puts(" (som rev 1.5)\n");
464         else
465                 puts("\n");
466
467 out:
468         return 0;
469 }
470
471 int board_late_init(void)
472 {
473 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
474         switch (board_type()) {
475         case CUBOXI:
476                 env_set("board_name", "CUBOXI");
477                 break;
478         case HUMMINGBOARD:
479                 env_set("board_name", "HUMMINGBOARD");
480                 break;
481         case HUMMINGBOARD2:
482                 env_set("board_name", "HUMMINGBOARD2");
483                 break;
484         case UNKNOWN:
485         default:
486                 env_set("board_name", "CUBOXI");
487         }
488
489         if (is_mx6dq())
490                 env_set("board_rev", "MX6Q");
491         else
492                 env_set("board_rev", "MX6DL");
493
494         if (is_rev_15_som())
495                 env_set("som_rev", "V15");
496 #endif
497
498         return 0;
499 }
500
501 #ifdef CONFIG_SPL_BUILD
502 #include <asm/arch/mx6-ddr.h>
503 static const struct mx6dq_iomux_ddr_regs mx6q_ddr_ioregs = {
504         .dram_sdclk_0 =  0x00020030,
505         .dram_sdclk_1 =  0x00020030,
506         .dram_cas =  0x00020030,
507         .dram_ras =  0x00020030,
508         .dram_reset =  0x000c0030,
509         .dram_sdcke0 =  0x00003000,
510         .dram_sdcke1 =  0x00003000,
511         .dram_sdba2 =  0x00000000,
512         .dram_sdodt0 =  0x00003030,
513         .dram_sdodt1 =  0x00003030,
514         .dram_sdqs0 =  0x00000030,
515         .dram_sdqs1 =  0x00000030,
516         .dram_sdqs2 =  0x00000030,
517         .dram_sdqs3 =  0x00000030,
518         .dram_sdqs4 =  0x00000030,
519         .dram_sdqs5 =  0x00000030,
520         .dram_sdqs6 =  0x00000030,
521         .dram_sdqs7 =  0x00000030,
522         .dram_dqm0 =  0x00020030,
523         .dram_dqm1 =  0x00020030,
524         .dram_dqm2 =  0x00020030,
525         .dram_dqm3 =  0x00020030,
526         .dram_dqm4 =  0x00020030,
527         .dram_dqm5 =  0x00020030,
528         .dram_dqm6 =  0x00020030,
529         .dram_dqm7 =  0x00020030,
530 };
531
532 static const struct mx6sdl_iomux_ddr_regs mx6dl_ddr_ioregs = {
533         .dram_sdclk_0 = 0x00000028,
534         .dram_sdclk_1 = 0x00000028,
535         .dram_cas =     0x00000028,
536         .dram_ras =     0x00000028,
537         .dram_reset =   0x000c0028,
538         .dram_sdcke0 =  0x00003000,
539         .dram_sdcke1 =  0x00003000,
540         .dram_sdba2 =   0x00000000,
541         .dram_sdodt0 =  0x00003030,
542         .dram_sdodt1 =  0x00003030,
543         .dram_sdqs0 =   0x00000028,
544         .dram_sdqs1 =   0x00000028,
545         .dram_sdqs2 =   0x00000028,
546         .dram_sdqs3 =   0x00000028,
547         .dram_sdqs4 =   0x00000028,
548         .dram_sdqs5 =   0x00000028,
549         .dram_sdqs6 =   0x00000028,
550         .dram_sdqs7 =   0x00000028,
551         .dram_dqm0 =    0x00000028,
552         .dram_dqm1 =    0x00000028,
553         .dram_dqm2 =    0x00000028,
554         .dram_dqm3 =    0x00000028,
555         .dram_dqm4 =    0x00000028,
556         .dram_dqm5 =    0x00000028,
557         .dram_dqm6 =    0x00000028,
558         .dram_dqm7 =    0x00000028,
559 };
560
561 static const struct mx6dq_iomux_grp_regs mx6q_grp_ioregs = {
562         .grp_ddr_type =  0x000C0000,
563         .grp_ddrmode_ctl =  0x00020000,
564         .grp_ddrpke =  0x00000000,
565         .grp_addds =  0x00000030,
566         .grp_ctlds =  0x00000030,
567         .grp_ddrmode =  0x00020000,
568         .grp_b0ds =  0x00000030,
569         .grp_b1ds =  0x00000030,
570         .grp_b2ds =  0x00000030,
571         .grp_b3ds =  0x00000030,
572         .grp_b4ds =  0x00000030,
573         .grp_b5ds =  0x00000030,
574         .grp_b6ds =  0x00000030,
575         .grp_b7ds =  0x00000030,
576 };
577
578 static const struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = {
579         .grp_ddr_type = 0x000c0000,
580         .grp_ddrmode_ctl = 0x00020000,
581         .grp_ddrpke = 0x00000000,
582         .grp_addds = 0x00000028,
583         .grp_ctlds = 0x00000028,
584         .grp_ddrmode = 0x00020000,
585         .grp_b0ds = 0x00000028,
586         .grp_b1ds = 0x00000028,
587         .grp_b2ds = 0x00000028,
588         .grp_b3ds = 0x00000028,
589         .grp_b4ds = 0x00000028,
590         .grp_b5ds = 0x00000028,
591         .grp_b6ds = 0x00000028,
592         .grp_b7ds = 0x00000028,
593 };
594
595 /* microSOM with Dual processor and 1GB memory */
596 static const struct mx6_mmdc_calibration mx6q_1g_mmcd_calib = {
597         .p0_mpwldectrl0 =  0x00000000,
598         .p0_mpwldectrl1 =  0x00000000,
599         .p1_mpwldectrl0 =  0x00000000,
600         .p1_mpwldectrl1 =  0x00000000,
601         .p0_mpdgctrl0 =    0x0314031c,
602         .p0_mpdgctrl1 =    0x023e0304,
603         .p1_mpdgctrl0 =    0x03240330,
604         .p1_mpdgctrl1 =    0x03180260,
605         .p0_mprddlctl =    0x3630323c,
606         .p1_mprddlctl =    0x3436283a,
607         .p0_mpwrdlctl =    0x36344038,
608         .p1_mpwrdlctl =    0x422a423c,
609 };
610
611 /* microSOM with Quad processor and 2GB memory */
612 static const struct mx6_mmdc_calibration mx6q_2g_mmcd_calib = {
613         .p0_mpwldectrl0 =  0x00000000,
614         .p0_mpwldectrl1 =  0x00000000,
615         .p1_mpwldectrl0 =  0x00000000,
616         .p1_mpwldectrl1 =  0x00000000,
617         .p0_mpdgctrl0 =    0x0314031c,
618         .p0_mpdgctrl1 =    0x023e0304,
619         .p1_mpdgctrl0 =    0x03240330,
620         .p1_mpdgctrl1 =    0x03180260,
621         .p0_mprddlctl =    0x3630323c,
622         .p1_mprddlctl =    0x3436283a,
623         .p0_mpwrdlctl =    0x36344038,
624         .p1_mpwrdlctl =    0x422a423c,
625 };
626
627 /* microSOM with Solo processor and 512MB memory */
628 static const struct mx6_mmdc_calibration mx6dl_512m_mmcd_calib = {
629         .p0_mpwldectrl0 = 0x0045004D,
630         .p0_mpwldectrl1 = 0x003A0047,
631         .p0_mpdgctrl0 =   0x023C0224,
632         .p0_mpdgctrl1 =   0x02000220,
633         .p0_mprddlctl =   0x44444846,
634         .p0_mpwrdlctl =   0x32343032,
635 };
636
637 /* microSOM with Dual lite processor and 1GB memory */
638 static const struct mx6_mmdc_calibration mx6dl_1g_mmcd_calib = {
639         .p0_mpwldectrl0 =  0x0045004D,
640         .p0_mpwldectrl1 =  0x003A0047,
641         .p1_mpwldectrl0 =  0x001F001F,
642         .p1_mpwldectrl1 =  0x00210035,
643         .p0_mpdgctrl0 =    0x023C0224,
644         .p0_mpdgctrl1 =    0x02000220,
645         .p1_mpdgctrl0 =    0x02200220,
646         .p1_mpdgctrl1 =    0x02040208,
647         .p0_mprddlctl =    0x44444846,
648         .p1_mprddlctl =    0x4042463C,
649         .p0_mpwrdlctl =    0x32343032,
650         .p1_mpwrdlctl =    0x36363430,
651 };
652
653 static struct mx6_ddr3_cfg mem_ddr_2g = {
654         .mem_speed = 1600,
655         .density   = 2,
656         .width     = 16,
657         .banks     = 8,
658         .rowaddr   = 14,
659         .coladdr   = 10,
660         .pagesz    = 2,
661         .trcd      = 1375,
662         .trcmin    = 4875,
663         .trasmin   = 3500,
664 };
665
666 static struct mx6_ddr3_cfg mem_ddr_4g = {
667         .mem_speed = 1600,
668         .density = 4,
669         .width = 16,
670         .banks = 8,
671         .rowaddr = 16,
672         .coladdr = 10,
673         .pagesz = 2,
674         .trcd = 1375,
675         .trcmin = 4875,
676         .trasmin = 3500,
677 };
678
679 static void ccgr_init(void)
680 {
681         struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
682
683         writel(0x00C03F3F, &ccm->CCGR0);
684         writel(0x0030FC03, &ccm->CCGR1);
685         writel(0x0FFFC000, &ccm->CCGR2);
686         writel(0x3FF00000, &ccm->CCGR3);
687         writel(0x00FFF300, &ccm->CCGR4);
688         writel(0x0F0000C3, &ccm->CCGR5);
689         writel(0x000003FF, &ccm->CCGR6);
690 }
691
692 static void spl_dram_init(int width)
693 {
694         struct mx6_ddr_sysinfo sysinfo = {
695                 /* width of data bus: 0=16, 1=32, 2=64 */
696                 .dsize = width / 32,
697                 /* config for full 4GB range so that get_mem_size() works */
698                 .cs_density = 32,       /* 32Gb per CS */
699                 .ncs = 1,               /* single chip select */
700                 .cs1_mirror = 0,
701                 .rtt_wr = 1 /*DDR3_RTT_60_OHM*/,        /* RTT_Wr = RZQ/4 */
702                 .rtt_nom = 1 /*DDR3_RTT_60_OHM*/,       /* RTT_Nom = RZQ/4 */
703                 .walat = 1,     /* Write additional latency */
704                 .ralat = 5,     /* Read additional latency */
705                 .mif3_mode = 3, /* Command prediction working mode */
706                 .bi_on = 1,     /* Bank interleaving enabled */
707                 .sde_to_rst = 0x10,     /* 14 cycles, 200us (JEDEC default) */
708                 .rst_to_cke = 0x23,     /* 33 cycles, 500us (JEDEC default) */
709                 .ddr_type = DDR_TYPE_DDR3,
710                 .refsel = 1,    /* Refresh cycles at 32KHz */
711                 .refr = 7,      /* 8 refresh commands per refresh cycle */
712         };
713
714         if (is_mx6dq())
715                 mx6dq_dram_iocfg(width, &mx6q_ddr_ioregs, &mx6q_grp_ioregs);
716         else
717                 mx6sdl_dram_iocfg(width, &mx6dl_ddr_ioregs, &mx6sdl_grp_ioregs);
718
719         if (is_cpu_type(MXC_CPU_MX6D))
720                 mx6_dram_cfg(&sysinfo, &mx6q_1g_mmcd_calib, &mem_ddr_2g);
721         else if (is_cpu_type(MXC_CPU_MX6Q))
722                 mx6_dram_cfg(&sysinfo, &mx6q_2g_mmcd_calib, &mem_ddr_4g);
723         else if (is_cpu_type(MXC_CPU_MX6DL))
724                 mx6_dram_cfg(&sysinfo, &mx6dl_1g_mmcd_calib, &mem_ddr_2g);
725         else if (is_cpu_type(MXC_CPU_MX6SOLO))
726                 mx6_dram_cfg(&sysinfo, &mx6dl_512m_mmcd_calib, &mem_ddr_2g);
727 }
728
729 void board_init_f(ulong dummy)
730 {
731         /* setup AIPS and disable watchdog */
732         arch_cpu_init();
733
734         ccgr_init();
735         gpr_init();
736
737         /* iomux and setup of i2c */
738         board_early_init_f();
739
740         /* setup GP timer */
741         timer_init();
742
743         /* UART clocks enabled and gd valid - init serial console */
744         preloader_console_init();
745
746         /* DDR initialization */
747         if (is_cpu_type(MXC_CPU_MX6SOLO))
748                 spl_dram_init(32);
749         else
750                 spl_dram_init(64);
751
752         /* Clear the BSS. */
753         memset(__bss_start, 0, __bss_end - __bss_start);
754
755         /* load/boot image from boot device */
756         board_init_r(NULL, 0);
757 }
758 #endif