c04dbe7c80be3f55852e35a09d4d90e62584b702
[platform/kernel/u-boot.git] / board / engicam / icorem6 / icorem6.c
1 /*
2  * Copyright (C) 2016 Amarula Solutions B.V.
3  * Copyright (C) 2016 Engicam S.r.l.
4  * Author: Jagan Teki <jagan@amarulasolutions.com>
5  *
6  * SPDX-License-Identifier:     GPL-2.0+
7  */
8
9 #include <common.h>
10 #include <mmc.h>
11
12 #include <asm/io.h>
13 #include <asm/gpio.h>
14 #include <linux/sizes.h>
15
16 #include <asm/arch/clock.h>
17 #include <asm/arch/crm_regs.h>
18 #include <asm/arch/iomux.h>
19 #include <asm/arch/mx6-pins.h>
20 #include <asm/arch/sys_proto.h>
21 #include <asm/imx-common/iomux-v3.h>
22 #include <asm/imx-common/video.h>
23
24 DECLARE_GLOBAL_DATA_PTR;
25
26 #ifdef CONFIG_NAND_MXS
27
28 #define GPMI_PAD_CTRL0  (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
29 #define GPMI_PAD_CTRL1  (PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | \
30                         PAD_CTL_SRE_FAST)
31 #define GPMI_PAD_CTRL2  (GPMI_PAD_CTRL0 | GPMI_PAD_CTRL1)
32
33 iomux_v3_cfg_t gpmi_pads[] = {
34         IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE      | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
35         IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE      | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
36         IOMUX_PADS(PAD_NANDF_WP_B__NAND_WP_B    | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
37         IOMUX_PADS(PAD_NANDF_RB0__NAND_READY_B  | MUX_PAD_CTRL(GPMI_PAD_CTRL0)),
38         IOMUX_PADS(PAD_NANDF_CS0__NAND_CE0_B    | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
39         IOMUX_PADS(PAD_SD4_CMD__NAND_RE_B       | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
40         IOMUX_PADS(PAD_SD4_CLK__NAND_WE_B       | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
41         IOMUX_PADS(PAD_NANDF_D0__NAND_DATA00    | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
42         IOMUX_PADS(PAD_NANDF_D1__NAND_DATA01    | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
43         IOMUX_PADS(PAD_NANDF_D2__NAND_DATA02    | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
44         IOMUX_PADS(PAD_NANDF_D3__NAND_DATA03    | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
45         IOMUX_PADS(PAD_NANDF_D4__NAND_DATA04    | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
46         IOMUX_PADS(PAD_NANDF_D5__NAND_DATA05    | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
47         IOMUX_PADS(PAD_NANDF_D6__NAND_DATA06    | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
48         IOMUX_PADS(PAD_NANDF_D7__NAND_DATA07    | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
49 };
50
51 static void setup_gpmi_nand(void)
52 {
53         struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
54
55         /* config gpmi nand iomux */
56         SETUP_IOMUX_PADS(gpmi_pads);
57
58         /* gate ENFC_CLK_ROOT clock first,before clk source switch */
59         clrbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
60
61         /* config gpmi and bch clock to 100 MHz */
62         clrsetbits_le32(&mxc_ccm->cs2cdr,
63                         MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |
64                         MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |
65                         MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK,
66                         MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) |
67                         MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) |
68                         MXC_CCM_CS2CDR_ENFC_CLK_SEL(3));
69
70         /* enable ENFC_CLK_ROOT clock */
71         setbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
72
73         /* enable gpmi and bch clock gating */
74         setbits_le32(&mxc_ccm->CCGR4,
75                      MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
76                      MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
77                      MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
78                      MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
79                      MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_OFFSET);
80
81         /* enable apbh clock gating */
82         setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
83 }
84 #endif
85
86 #if defined(CONFIG_VIDEO_IPUV3)
87 static iomux_v3_cfg_t const rgb_pads[] = {
88         IOMUX_PADS(PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK),
89         IOMUX_PADS(PAD_DI0_PIN15__IPU1_DI0_PIN15),
90         IOMUX_PADS(PAD_DI0_PIN2__IPU1_DI0_PIN02),
91         IOMUX_PADS(PAD_DI0_PIN3__IPU1_DI0_PIN03),
92         IOMUX_PADS(PAD_DISP0_DAT0__IPU1_DISP0_DATA00),
93         IOMUX_PADS(PAD_DISP0_DAT1__IPU1_DISP0_DATA01),
94         IOMUX_PADS(PAD_DISP0_DAT2__IPU1_DISP0_DATA02),
95         IOMUX_PADS(PAD_DISP0_DAT3__IPU1_DISP0_DATA03),
96         IOMUX_PADS(PAD_DISP0_DAT4__IPU1_DISP0_DATA04),
97         IOMUX_PADS(PAD_DISP0_DAT5__IPU1_DISP0_DATA05),
98         IOMUX_PADS(PAD_DISP0_DAT6__IPU1_DISP0_DATA06),
99         IOMUX_PADS(PAD_DISP0_DAT7__IPU1_DISP0_DATA07),
100         IOMUX_PADS(PAD_DISP0_DAT8__IPU1_DISP0_DATA08),
101         IOMUX_PADS(PAD_DISP0_DAT9__IPU1_DISP0_DATA09),
102         IOMUX_PADS(PAD_DISP0_DAT10__IPU1_DISP0_DATA10),
103         IOMUX_PADS(PAD_DISP0_DAT11__IPU1_DISP0_DATA11),
104         IOMUX_PADS(PAD_DISP0_DAT12__IPU1_DISP0_DATA12),
105         IOMUX_PADS(PAD_DISP0_DAT13__IPU1_DISP0_DATA13),
106         IOMUX_PADS(PAD_DISP0_DAT14__IPU1_DISP0_DATA14),
107         IOMUX_PADS(PAD_DISP0_DAT15__IPU1_DISP0_DATA15),
108         IOMUX_PADS(PAD_DISP0_DAT16__IPU1_DISP0_DATA16),
109         IOMUX_PADS(PAD_DISP0_DAT17__IPU1_DISP0_DATA17),
110 };
111
112 static void enable_rgb(struct display_info_t const *dev)
113 {
114         SETUP_IOMUX_PADS(rgb_pads);
115 }
116
117 struct display_info_t const displays[] = {
118         {
119                 .bus    = -1,
120                 .addr   = 0,
121                 .pixfmt = IPU_PIX_FMT_RGB666,
122                 .detect = NULL,
123                 .enable = enable_rgb,
124                 .mode   = {
125                         .name           = "Amp-WD",
126                         .refresh        = 60,
127                         .xres           = 800,
128                         .yres           = 480,
129                         .pixclock       = 30000,
130                         .left_margin    = 30,
131                         .right_margin   = 30,
132                         .upper_margin   = 5,
133                         .lower_margin   = 5,
134                         .hsync_len      = 64,
135                         .vsync_len      = 20,
136                         .sync           = FB_SYNC_EXT,
137                         .vmode          = FB_VMODE_NONINTERLACED
138                 }
139         },
140 };
141
142 size_t display_count = ARRAY_SIZE(displays);
143
144 static void setup_display(void)
145 {
146         struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
147         struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
148         int reg;
149
150         enable_ipu_clock();
151
152         /* Turn on LDB0,IPU,IPU DI0 clocks */
153         reg = __raw_readl(&mxc_ccm->CCGR3);
154         reg |=  (MXC_CCM_CCGR3_LDB_DI0_MASK | 0xffff);
155         writel(reg, &mxc_ccm->CCGR3);
156
157         /* set LDB0, LDB1 clk select to 011/011 */
158         reg = readl(&mxc_ccm->cs2cdr);
159         reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK |
160                 MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
161         reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) |
162                 (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
163         writel(reg, &mxc_ccm->cs2cdr);
164
165         reg = readl(&mxc_ccm->cscmr2);
166         reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
167         writel(reg, &mxc_ccm->cscmr2);
168
169         reg = readl(&mxc_ccm->chsccdr);
170         reg |= (CHSCCDR_CLK_SEL_LDB_DI0 <<
171                 MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
172         writel(reg, &mxc_ccm->chsccdr);
173
174         reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES |
175                 IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH |
176                 IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW |
177                 IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG |
178                 IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT |
179                 IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG |
180                 IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT |
181                 IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED |
182                 IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
183         writel(reg, &iomux->gpr[2]);
184
185         reg = readl(&iomux->gpr[3]);
186         reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK) |
187                 (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
188                 IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
189         writel(reg, &iomux->gpr[3]);
190 }
191 #endif /* CONFIG_VIDEO_IPUV3 */
192
193 #ifdef CONFIG_ENV_IS_IN_MMC
194 static void mmc_late_init(void)
195 {
196         char cmd[32];
197         char mmcblk[32];
198         u32 dev_no = mmc_get_env_dev();
199
200         setenv_ulong("mmcdev", dev_no);
201
202         /* Set mmcblk env */
203         sprintf(mmcblk, "/dev/mmcblk%dp2 rootwait rw", dev_no);
204         setenv("mmcroot", mmcblk);
205
206         sprintf(cmd, "mmc dev %d", dev_no);
207         run_command(cmd, 0);
208 }
209 #endif
210
211 int board_late_init(void)
212 {
213         switch ((imx6_src_get_boot_mode() & IMX6_BMODE_MASK) >>
214                         IMX6_BMODE_SHIFT) {
215         case IMX6_BMODE_SD:
216         case IMX6_BMODE_ESD:
217 #ifdef CONFIG_ENV_IS_IN_MMC
218                 mmc_late_init();
219 #endif
220                 setenv("modeboot", "mmcboot");
221                 break;
222         case IMX6_BMODE_NAND:
223                 setenv("modeboot", "nandboot");
224                 break;
225         default:
226                 setenv("modeboot", "");
227                 break;
228         }
229
230         if (is_mx6dq())
231                 setenv("fdt_file", "imx6q-icore.dtb");
232         else if(is_mx6dl() || is_mx6solo())
233                 setenv("fdt_file", "imx6dl-icore.dtb");
234
235         return 0;
236 }
237
238 int board_init(void)
239 {
240         /* Address of boot parameters */
241         gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
242
243 #ifdef CONFIG_NAND_MXS
244         setup_gpmi_nand();
245 #endif
246
247 #ifdef CONFIG_VIDEO_IPUV3
248         setup_display();
249 #endif
250
251         return 0;
252 }
253
254 int dram_init(void)
255 {
256         gd->ram_size = imx_ddr_size();
257
258         return 0;
259 }
260
261 #ifdef CONFIG_SPL_BUILD
262 #include <libfdt.h>
263 #include <spl.h>
264
265 #include <asm/arch/crm_regs.h>
266 #include <asm/arch/mx6-ddr.h>
267
268 #define UART_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |             \
269         PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |               \
270         PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
271
272 static iomux_v3_cfg_t const uart4_pads[] = {
273         IOMUX_PADS(PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
274         IOMUX_PADS(PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
275 };
276
277 /* MMC board initialization is needed till adding DM support in SPL */
278 #if defined(CONFIG_FSL_ESDHC) && !defined(CONFIG_DM_MMC)
279 #include <mmc.h>
280 #include <fsl_esdhc.h>
281
282 #define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |             \
283         PAD_CTL_PUS_22K_UP  | PAD_CTL_SPEED_LOW |               \
284         PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
285
286 static iomux_v3_cfg_t const usdhc1_pads[] = {
287         IOMUX_PADS(PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
288         IOMUX_PADS(PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
289         IOMUX_PADS(PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
290         IOMUX_PADS(PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
291         IOMUX_PADS(PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
292         IOMUX_PADS(PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
293         IOMUX_PADS(PAD_GPIO_1__GPIO1_IO01 | MUX_PAD_CTRL(NO_PAD_CTRL)),/* CD */
294 };
295
296 #define USDHC1_CD_GPIO  IMX_GPIO_NR(1, 1)
297
298 struct fsl_esdhc_cfg usdhc_cfg[1] = {
299         {USDHC1_BASE_ADDR, 0, 4},
300 };
301
302 int board_mmc_getcd(struct mmc *mmc)
303 {
304         struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
305         int ret = 0;
306
307         switch (cfg->esdhc_base) {
308         case USDHC1_BASE_ADDR:
309                 ret = !gpio_get_value(USDHC1_CD_GPIO);
310                 break;
311         }
312
313         return ret;
314 }
315
316 int board_mmc_init(bd_t *bis)
317 {
318         int i, ret;
319
320         /*
321         * According to the board_mmc_init() the following map is done:
322         * (U-boot device node)    (Physical Port)
323         * mmc0                          USDHC1
324         */
325         for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
326                 switch (i) {
327                 case 0:
328                         SETUP_IOMUX_PADS(usdhc1_pads);
329                         gpio_direction_input(USDHC1_CD_GPIO);
330                         usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
331                         break;
332                 default:
333                         printf("Warning - USDHC%d controller not supporting\n",
334                                i + 1);
335                         return 0;
336                 }
337
338                 ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
339                 if (ret) {
340                         printf("Warning: failed to initialize mmc dev %d\n", i);
341                         return ret;
342                 }
343         }
344
345         return 0;
346 }
347 #endif
348
349 #ifdef CONFIG_SPL_LOAD_FIT
350 int board_fit_config_name_match(const char *name)
351 {
352         if (is_mx6dq() && !strcmp(name, "imx6q-icore"))
353                 return 0;
354         else if ((is_mx6dl() || is_mx6solo()) && !strcmp(name, "imx6dl-icore"))
355                 return 0;
356         else
357                 return -1;
358 }
359 #endif
360
361 /*
362  * Driving strength:
363  *   0x30 == 40 Ohm
364  *   0x28 == 48 Ohm
365  */
366
367 #define IMX6DQ_DRIVE_STRENGTH           0x30
368 #define IMX6SDL_DRIVE_STRENGTH          0x28
369
370 /* configure MX6Q/DUAL mmdc DDR io registers */
371 static struct mx6dq_iomux_ddr_regs mx6dq_ddr_ioregs = {
372         .dram_sdqs0 = IMX6DQ_DRIVE_STRENGTH,
373         .dram_sdqs1 = IMX6DQ_DRIVE_STRENGTH,
374         .dram_sdqs2 = IMX6DQ_DRIVE_STRENGTH,
375         .dram_sdqs3 = IMX6DQ_DRIVE_STRENGTH,
376         .dram_sdqs4 = IMX6DQ_DRIVE_STRENGTH,
377         .dram_sdqs5 = IMX6DQ_DRIVE_STRENGTH,
378         .dram_sdqs6 = IMX6DQ_DRIVE_STRENGTH,
379         .dram_sdqs7 = IMX6DQ_DRIVE_STRENGTH,
380         .dram_dqm0 = IMX6DQ_DRIVE_STRENGTH,
381         .dram_dqm1 = IMX6DQ_DRIVE_STRENGTH,
382         .dram_dqm2 = IMX6DQ_DRIVE_STRENGTH,
383         .dram_dqm3 = IMX6DQ_DRIVE_STRENGTH,
384         .dram_dqm4 = IMX6DQ_DRIVE_STRENGTH,
385         .dram_dqm5 = IMX6DQ_DRIVE_STRENGTH,
386         .dram_dqm6 = IMX6DQ_DRIVE_STRENGTH,
387         .dram_dqm7 = IMX6DQ_DRIVE_STRENGTH,
388         .dram_cas = IMX6DQ_DRIVE_STRENGTH,
389         .dram_ras = IMX6DQ_DRIVE_STRENGTH,
390         .dram_sdclk_0 = IMX6DQ_DRIVE_STRENGTH,
391         .dram_sdclk_1 = IMX6DQ_DRIVE_STRENGTH,
392         .dram_reset = IMX6DQ_DRIVE_STRENGTH,
393         .dram_sdcke0 = IMX6DQ_DRIVE_STRENGTH,
394         .dram_sdcke1 = IMX6DQ_DRIVE_STRENGTH,
395         .dram_sdba2 = 0x00000000,
396         .dram_sdodt0 = IMX6DQ_DRIVE_STRENGTH,
397         .dram_sdodt1 = IMX6DQ_DRIVE_STRENGTH,
398 };
399
400 /* configure MX6Q/DUAL mmdc GRP io registers */
401 static struct mx6dq_iomux_grp_regs mx6dq_grp_ioregs = {
402         .grp_b0ds = IMX6DQ_DRIVE_STRENGTH,
403         .grp_b1ds = IMX6DQ_DRIVE_STRENGTH,
404         .grp_b2ds = IMX6DQ_DRIVE_STRENGTH,
405         .grp_b3ds = IMX6DQ_DRIVE_STRENGTH,
406         .grp_b4ds = IMX6DQ_DRIVE_STRENGTH,
407         .grp_b5ds = IMX6DQ_DRIVE_STRENGTH,
408         .grp_b6ds = IMX6DQ_DRIVE_STRENGTH,
409         .grp_b7ds = IMX6DQ_DRIVE_STRENGTH,
410         .grp_addds = IMX6DQ_DRIVE_STRENGTH,
411         .grp_ddrmode_ctl = 0x00020000,
412         .grp_ddrpke = 0x00000000,
413         .grp_ddrmode = 0x00020000,
414         .grp_ctlds = IMX6DQ_DRIVE_STRENGTH,
415         .grp_ddr_type = 0x000c0000,
416 };
417
418 /* configure MX6SOLO/DUALLITE mmdc DDR io registers */
419 struct mx6sdl_iomux_ddr_regs mx6sdl_ddr_ioregs = {
420         .dram_sdclk_0 = IMX6SDL_DRIVE_STRENGTH,
421         .dram_sdclk_1 = IMX6SDL_DRIVE_STRENGTH,
422         .dram_cas = IMX6SDL_DRIVE_STRENGTH,
423         .dram_ras = IMX6SDL_DRIVE_STRENGTH,
424         .dram_reset = IMX6SDL_DRIVE_STRENGTH,
425         .dram_sdcke0 = IMX6SDL_DRIVE_STRENGTH,
426         .dram_sdcke1 = IMX6SDL_DRIVE_STRENGTH,
427         .dram_sdba2 = 0x00000000,
428         .dram_sdodt0 = IMX6SDL_DRIVE_STRENGTH,
429         .dram_sdodt1 = IMX6SDL_DRIVE_STRENGTH,
430         .dram_sdqs0 = IMX6SDL_DRIVE_STRENGTH,
431         .dram_sdqs1 = IMX6SDL_DRIVE_STRENGTH,
432         .dram_sdqs2 = IMX6SDL_DRIVE_STRENGTH,
433         .dram_sdqs3 = IMX6SDL_DRIVE_STRENGTH,
434         .dram_sdqs4 = IMX6SDL_DRIVE_STRENGTH,
435         .dram_sdqs5 = IMX6SDL_DRIVE_STRENGTH,
436         .dram_sdqs6 = IMX6SDL_DRIVE_STRENGTH,
437         .dram_sdqs7 = IMX6SDL_DRIVE_STRENGTH,
438         .dram_dqm0 = IMX6SDL_DRIVE_STRENGTH,
439         .dram_dqm1 = IMX6SDL_DRIVE_STRENGTH,
440         .dram_dqm2 = IMX6SDL_DRIVE_STRENGTH,
441         .dram_dqm3 = IMX6SDL_DRIVE_STRENGTH,
442         .dram_dqm4 = IMX6SDL_DRIVE_STRENGTH,
443         .dram_dqm5 = IMX6SDL_DRIVE_STRENGTH,
444         .dram_dqm6 = IMX6SDL_DRIVE_STRENGTH,
445         .dram_dqm7 = IMX6SDL_DRIVE_STRENGTH,
446 };
447
448 /* configure MX6SOLO/DUALLITE mmdc GRP io registers */
449 struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = {
450         .grp_ddr_type = 0x000c0000,
451         .grp_ddrmode_ctl = 0x00020000,
452         .grp_ddrpke = 0x00000000,
453         .grp_addds = IMX6SDL_DRIVE_STRENGTH,
454         .grp_ctlds = IMX6SDL_DRIVE_STRENGTH,
455         .grp_ddrmode = 0x00020000,
456         .grp_b0ds = IMX6SDL_DRIVE_STRENGTH,
457         .grp_b1ds = IMX6SDL_DRIVE_STRENGTH,
458         .grp_b2ds = IMX6SDL_DRIVE_STRENGTH,
459         .grp_b3ds = IMX6SDL_DRIVE_STRENGTH,
460         .grp_b4ds = IMX6SDL_DRIVE_STRENGTH,
461         .grp_b5ds = IMX6SDL_DRIVE_STRENGTH,
462         .grp_b6ds = IMX6SDL_DRIVE_STRENGTH,
463         .grp_b7ds = IMX6SDL_DRIVE_STRENGTH,
464 };
465
466 /* mt41j256 */
467 static struct mx6_ddr3_cfg mt41j256 = {
468         .mem_speed = 1066,
469         .density = 2,
470         .width = 16,
471         .banks = 8,
472         .rowaddr = 13,
473         .coladdr = 10,
474         .pagesz = 2,
475         .trcd = 1375,
476         .trcmin = 4875,
477         .trasmin = 3500,
478         .SRT = 0,
479 };
480
481 static struct mx6_mmdc_calibration mx6dq_mmdc_calib = {
482         .p0_mpwldectrl0 = 0x000E0009,
483         .p0_mpwldectrl1 = 0x0018000E,
484         .p1_mpwldectrl0 = 0x00000007,
485         .p1_mpwldectrl1 = 0x00000000,
486         .p0_mpdgctrl0 = 0x43280334,
487         .p0_mpdgctrl1 = 0x031C0314,
488         .p1_mpdgctrl0 = 0x4318031C,
489         .p1_mpdgctrl1 = 0x030C0258,
490         .p0_mprddlctl = 0x3E343A40,
491         .p1_mprddlctl = 0x383C3844,
492         .p0_mpwrdlctl = 0x40404440,
493         .p1_mpwrdlctl = 0x4C3E4446,
494 };
495
496 /* DDR 64bit */
497 static struct mx6_ddr_sysinfo mem_q = {
498         .ddr_type       = DDR_TYPE_DDR3,
499         .dsize          = 2,
500         .cs1_mirror     = 0,
501         /* config for full 4GB range so that get_mem_size() works */
502         .cs_density     = 32,
503         .ncs            = 1,
504         .bi_on          = 1,
505         .rtt_nom        = 2,
506         .rtt_wr         = 2,
507         .ralat          = 5,
508         .walat          = 0,
509         .mif3_mode      = 3,
510         .rst_to_cke     = 0x23,
511         .sde_to_rst     = 0x10,
512 };
513
514 static struct mx6_mmdc_calibration mx6dl_mmdc_calib = {
515         .p0_mpwldectrl0 = 0x001F0024,
516         .p0_mpwldectrl1 = 0x00110018,
517         .p1_mpwldectrl0 = 0x001F0024,
518         .p1_mpwldectrl1 = 0x00110018,
519         .p0_mpdgctrl0 = 0x4230022C,
520         .p0_mpdgctrl1 = 0x02180220,
521         .p1_mpdgctrl0 = 0x42440248,
522         .p1_mpdgctrl1 = 0x02300238,
523         .p0_mprddlctl = 0x44444A48,
524         .p1_mprddlctl = 0x46484A42,
525         .p0_mpwrdlctl = 0x38383234,
526         .p1_mpwrdlctl = 0x3C34362E,
527 };
528
529 /* DDR 64bit 1GB */
530 static struct mx6_ddr_sysinfo mem_dl = {
531         .dsize          = 2,
532         .cs1_mirror     = 0,
533         /* config for full 4GB range so that get_mem_size() works */
534         .cs_density     = 32,
535         .ncs            = 1,
536         .bi_on          = 1,
537         .rtt_nom        = 1,
538         .rtt_wr         = 1,
539         .ralat          = 5,
540         .walat          = 0,
541         .mif3_mode      = 3,
542         .rst_to_cke     = 0x23,
543         .sde_to_rst     = 0x10,
544 };
545
546 /* DDR 32bit 512MB */
547 static struct mx6_ddr_sysinfo mem_s = {
548         .dsize          = 1,
549         .cs1_mirror     = 0,
550         /* config for full 4GB range so that get_mem_size() works */
551         .cs_density     = 32,
552         .ncs            = 1,
553         .bi_on          = 1,
554         .rtt_nom        = 1,
555         .rtt_wr         = 1,
556         .ralat          = 5,
557         .walat          = 0,
558         .mif3_mode      = 3,
559         .rst_to_cke     = 0x23,
560         .sde_to_rst     = 0x10,
561 };
562
563 static void ccgr_init(void)
564 {
565         struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
566
567         writel(0x00003F3F, &ccm->CCGR0);
568         writel(0x0030FC00, &ccm->CCGR1);
569         writel(0x000FC000, &ccm->CCGR2);
570         writel(0x3F300000, &ccm->CCGR3);
571         writel(0xFF00F300, &ccm->CCGR4);
572         writel(0x0F0000C3, &ccm->CCGR5);
573         writel(0x000003CC, &ccm->CCGR6);
574 }
575
576 static void gpr_init(void)
577 {
578         struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
579
580         /* enable AXI cache for VDOA/VPU/IPU */
581         writel(0xF00000CF, &iomux->gpr[4]);
582         /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
583         writel(0x007F007F, &iomux->gpr[6]);
584         writel(0x007F007F, &iomux->gpr[7]);
585 }
586
587 static void spl_dram_init(void)
588 {
589         if (is_mx6solo()) {
590                 mx6sdl_dram_iocfg(32, &mx6sdl_ddr_ioregs, &mx6sdl_grp_ioregs);
591                 mx6_dram_cfg(&mem_s, &mx6dl_mmdc_calib, &mt41j256);
592         } else if (is_mx6dl()) {
593                 mx6sdl_dram_iocfg(64, &mx6sdl_ddr_ioregs, &mx6sdl_grp_ioregs);
594                 mx6_dram_cfg(&mem_dl, &mx6dl_mmdc_calib, &mt41j256);
595         } else if (is_mx6dq()) {
596                 mx6dq_dram_iocfg(64, &mx6dq_ddr_ioregs, &mx6dq_grp_ioregs);
597                 mx6_dram_cfg(&mem_q, &mx6dq_mmdc_calib, &mt41j256);
598         }
599
600         udelay(100);
601 }
602
603 void board_init_f(ulong dummy)
604 {
605         ccgr_init();
606
607         /* setup AIPS and disable watchdog */
608         arch_cpu_init();
609
610         gpr_init();
611
612         /* iomux */
613         SETUP_IOMUX_PADS(uart4_pads);
614
615         /* setup GP timer */
616         timer_init();
617
618         /* UART clocks enabled and gd valid - init serial console */
619         preloader_console_init();
620
621         /* DDR initialization */
622         spl_dram_init();
623
624         /* Clear the BSS. */
625         memset(__bss_start, 0, __bss_end - __bss_start);
626
627         /* load/boot image from boot device */
628         board_init_r(NULL, 0);
629 }
630 #endif