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