197d8c39f5af026d6d09befc9e66b9445cce0c45
[oweals/u-boot.git] / board / toradex / colibri_imx6 / colibri_imx6.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
4  * Copyright (C) 2013, Boundary Devices <info@boundarydevices.com>
5  * Copyright (C) 2014-2019, Toradex AG
6  * copied from nitrogen6x
7  */
8
9 #include <common.h>
10 #include <cpu_func.h>
11 #include <dm.h>
12 #include <env.h>
13 #include <init.h>
14 #include <net.h>
15
16 #include <asm/arch/clock.h>
17 #include <asm/arch/crm_regs.h>
18 #include <asm/arch/imx-regs.h>
19 #include <asm/arch/mx6-ddr.h>
20 #include <asm/arch/mx6-pins.h>
21 #include <asm/arch/mxc_hdmi.h>
22 #include <asm/arch/sys_proto.h>
23 #include <asm/bootm.h>
24 #include <asm/gpio.h>
25 #include <asm/mach-imx/boot_mode.h>
26 #include <asm/mach-imx/iomux-v3.h>
27 #include <asm/mach-imx/sata.h>
28 #include <asm/mach-imx/video.h>
29 #include <cpu.h>
30 #include <dm/platform_data/serial_mxc.h>
31 #include <fsl_esdhc_imx.h>
32 #include <imx_thermal.h>
33 #include <miiphy.h>
34 #include <netdev.h>
35 #include <cpu.h>
36
37 #include "../common/tdx-cfg-block.h"
38 #ifdef CONFIG_TDX_CMD_IMX_MFGR
39 #include "pf0100.h"
40 #endif
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_40ohm |                 \
50         PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
51
52 #define USDHC_EMMC_PAD_CTRL (PAD_CTL_PUS_47K_UP |               \
53         PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm |                 \
54         PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
55
56 #define WEAK_PULLUP     (PAD_CTL_PUS_100K_UP |                  \
57         PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS |   \
58         PAD_CTL_SRE_SLOW)
59
60 #define NO_PULLUP       (                                       \
61         PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS |   \
62         PAD_CTL_SRE_SLOW)
63
64 #define WEAK_PULLDOWN   (PAD_CTL_PUS_100K_DOWN |                \
65         PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |                 \
66         PAD_CTL_HYS | PAD_CTL_SRE_SLOW)
67
68 #define OUTPUT_RGB (PAD_CTL_SPEED_MED|PAD_CTL_DSE_60ohm|PAD_CTL_SRE_FAST)
69
70 int dram_init(void)
71 {
72         /* use the DDR controllers configured size */
73         gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
74                                     (ulong)imx_ddr_size());
75
76         return 0;
77 }
78
79 /* Colibri UARTA */
80 iomux_v3_cfg_t const uart1_pads[] = {
81         MX6_PAD_CSI0_DAT10__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
82         MX6_PAD_CSI0_DAT11__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
83 };
84
85 #if defined(CONFIG_FSL_ESDHC_IMX) && defined(CONFIG_SPL_BUILD)
86 /* Colibri MMC */
87 iomux_v3_cfg_t const usdhc1_pads[] = {
88         MX6_PAD_SD1_CLK__SD1_CLK    | MUX_PAD_CTRL(USDHC_PAD_CTRL),
89         MX6_PAD_SD1_CMD__SD1_CMD    | MUX_PAD_CTRL(USDHC_PAD_CTRL),
90         MX6_PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
91         MX6_PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
92         MX6_PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
93         MX6_PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
94         MX6_PAD_NANDF_D5__GPIO2_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
95 #       define GPIO_MMC_CD IMX_GPIO_NR(2, 5)
96 };
97
98 /* eMMC */
99 iomux_v3_cfg_t const usdhc3_pads[] = {
100         MX6_PAD_SD3_CLK__SD3_CLK    | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
101         MX6_PAD_SD3_CMD__SD3_CMD    | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
102         MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
103         MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
104         MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
105         MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
106         MX6_PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
107         MX6_PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
108         MX6_PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
109         MX6_PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
110         MX6_PAD_SD3_RST__SD3_RESET  | MUX_PAD_CTRL(USDHC_PAD_CTRL),
111 };
112 #endif /* CONFIG_FSL_ESDHC_IMX & CONFIG_SPL_BUILD */
113
114 /* mux auxiliary pins to GPIO, so they can be used from the U-Boot cmdline */
115 iomux_v3_cfg_t const gpio_pads[] = {
116         /* ADDRESS[17:18] [25] used as GPIO */
117         MX6_PAD_KEY_ROW2__GPIO4_IO11    | MUX_PAD_CTRL(WEAK_PULLUP) |
118                                           MUX_MODE_SION,
119         MX6_PAD_KEY_COL2__GPIO4_IO10    | MUX_PAD_CTRL(WEAK_PULLUP) |
120                                           MUX_MODE_SION,
121         MX6_PAD_NANDF_D1__GPIO2_IO01    | MUX_PAD_CTRL(WEAK_PULLUP) |
122                                           MUX_MODE_SION,
123         /* ADDRESS[19:24] used as GPIO */
124         MX6_PAD_DISP0_DAT23__GPIO5_IO17 | MUX_PAD_CTRL(WEAK_PULLUP) |
125                                           MUX_MODE_SION,
126         MX6_PAD_DISP0_DAT22__GPIO5_IO16 | MUX_PAD_CTRL(WEAK_PULLUP) |
127                                           MUX_MODE_SION,
128         MX6_PAD_DISP0_DAT21__GPIO5_IO15 | MUX_PAD_CTRL(WEAK_PULLUP) |
129                                           MUX_MODE_SION,
130         MX6_PAD_DISP0_DAT20__GPIO5_IO14 | MUX_PAD_CTRL(WEAK_PULLUP) |
131                                           MUX_MODE_SION,
132         MX6_PAD_DISP0_DAT19__GPIO5_IO13 | MUX_PAD_CTRL(WEAK_PULLUP) |
133                                           MUX_MODE_SION,
134         MX6_PAD_DISP0_DAT18__GPIO5_IO12 | MUX_PAD_CTRL(WEAK_PULLUP) |
135                                           MUX_MODE_SION,
136         /* DATA[16:29] [31]      used as GPIO */
137         MX6_PAD_EIM_LBA__GPIO2_IO27     | MUX_PAD_CTRL(WEAK_PULLUP) |
138                                           MUX_MODE_SION,
139         MX6_PAD_EIM_BCLK__GPIO6_IO31    | MUX_PAD_CTRL(WEAK_PULLUP) |
140                                           MUX_MODE_SION,
141         MX6_PAD_NANDF_CS3__GPIO6_IO16   | MUX_PAD_CTRL(WEAK_PULLUP) |
142                                           MUX_MODE_SION,
143         MX6_PAD_NANDF_CS1__GPIO6_IO14   | MUX_PAD_CTRL(WEAK_PULLUP) |
144                                           MUX_MODE_SION,
145         MX6_PAD_NANDF_RB0__GPIO6_IO10   | MUX_PAD_CTRL(WEAK_PULLUP) |
146                                           MUX_MODE_SION,
147         MX6_PAD_NANDF_ALE__GPIO6_IO08   | MUX_PAD_CTRL(WEAK_PULLUP) |
148                                           MUX_MODE_SION,
149         MX6_PAD_NANDF_WP_B__GPIO6_IO09  | MUX_PAD_CTRL(WEAK_PULLUP) |
150                                           MUX_MODE_SION,
151         MX6_PAD_NANDF_CS0__GPIO6_IO11   | MUX_PAD_CTRL(WEAK_PULLUP) |
152                                           MUX_MODE_SION,
153         MX6_PAD_NANDF_CLE__GPIO6_IO07   | MUX_PAD_CTRL(WEAK_PULLUP) |
154                                           MUX_MODE_SION,
155         MX6_PAD_GPIO_19__GPIO4_IO05     | MUX_PAD_CTRL(WEAK_PULLUP) |
156                                           MUX_MODE_SION,
157         MX6_PAD_CSI0_MCLK__GPIO5_IO19   | MUX_PAD_CTRL(WEAK_PULLUP) |
158                                           MUX_MODE_SION,
159         MX6_PAD_CSI0_PIXCLK__GPIO5_IO18 | MUX_PAD_CTRL(WEAK_PULLUP) |
160                                           MUX_MODE_SION,
161         MX6_PAD_GPIO_4__GPIO1_IO04      | MUX_PAD_CTRL(WEAK_PULLUP) |
162                                           MUX_MODE_SION,
163         MX6_PAD_GPIO_5__GPIO1_IO05      | MUX_PAD_CTRL(WEAK_PULLUP) |
164                                           MUX_MODE_SION,
165         MX6_PAD_GPIO_2__GPIO1_IO02      | MUX_PAD_CTRL(WEAK_PULLUP) |
166                                           MUX_MODE_SION,
167         /* DQM[0:3]      used as GPIO */
168         MX6_PAD_EIM_EB0__GPIO2_IO28     | MUX_PAD_CTRL(WEAK_PULLUP) |
169                                           MUX_MODE_SION,
170         MX6_PAD_EIM_EB1__GPIO2_IO29     | MUX_PAD_CTRL(WEAK_PULLUP) |
171                                           MUX_MODE_SION,
172         MX6_PAD_SD2_DAT2__GPIO1_IO13    | MUX_PAD_CTRL(WEAK_PULLUP) |
173                                           MUX_MODE_SION,
174         MX6_PAD_NANDF_D0__GPIO2_IO00    | MUX_PAD_CTRL(WEAK_PULLUP) |
175                                           MUX_MODE_SION,
176         /* RDY  used as GPIO */
177         MX6_PAD_EIM_WAIT__GPIO5_IO00    | MUX_PAD_CTRL(WEAK_PULLUP) |
178                                           MUX_MODE_SION,
179         /* ADDRESS[16] DATA[30]  used as GPIO */
180         MX6_PAD_KEY_ROW4__GPIO4_IO15    | MUX_PAD_CTRL(WEAK_PULLDOWN) |
181                                           MUX_MODE_SION,
182         MX6_PAD_KEY_COL4__GPIO4_IO14    | MUX_PAD_CTRL(WEAK_PULLUP) |
183                                           MUX_MODE_SION,
184         /* CSI pins used as GPIO */
185         MX6_PAD_EIM_A24__GPIO5_IO04     | MUX_PAD_CTRL(WEAK_PULLUP) |
186                                           MUX_MODE_SION,
187         MX6_PAD_SD2_CMD__GPIO1_IO11     | MUX_PAD_CTRL(WEAK_PULLUP) |
188                                           MUX_MODE_SION,
189         MX6_PAD_NANDF_CS2__GPIO6_IO15   | MUX_PAD_CTRL(WEAK_PULLUP) |
190                                           MUX_MODE_SION,
191         MX6_PAD_EIM_D18__GPIO3_IO18     | MUX_PAD_CTRL(WEAK_PULLUP) |
192                                           MUX_MODE_SION,
193         MX6_PAD_EIM_A19__GPIO2_IO19     | MUX_PAD_CTRL(WEAK_PULLUP) |
194                                           MUX_MODE_SION,
195         MX6_PAD_EIM_D29__GPIO3_IO29     | MUX_PAD_CTRL(WEAK_PULLDOWN) |
196                                           MUX_MODE_SION,
197         MX6_PAD_EIM_A23__GPIO6_IO06     | MUX_PAD_CTRL(WEAK_PULLUP) |
198                                           MUX_MODE_SION,
199         MX6_PAD_EIM_A20__GPIO2_IO18     | MUX_PAD_CTRL(WEAK_PULLUP) |
200                                           MUX_MODE_SION,
201         MX6_PAD_EIM_A17__GPIO2_IO21     | MUX_PAD_CTRL(WEAK_PULLUP) |
202                                           MUX_MODE_SION,
203         MX6_PAD_EIM_A18__GPIO2_IO20     | MUX_PAD_CTRL(WEAK_PULLUP) |
204                                           MUX_MODE_SION,
205         MX6_PAD_EIM_EB3__GPIO2_IO31     | MUX_PAD_CTRL(WEAK_PULLUP) |
206                                           MUX_MODE_SION,
207         MX6_PAD_EIM_D17__GPIO3_IO17     | MUX_PAD_CTRL(WEAK_PULLUP) |
208                                           MUX_MODE_SION,
209         MX6_PAD_SD2_DAT0__GPIO1_IO15    | MUX_PAD_CTRL(WEAK_PULLUP) |
210                                           MUX_MODE_SION,
211         /* GPIO */
212         MX6_PAD_EIM_D26__GPIO3_IO26     | MUX_PAD_CTRL(WEAK_PULLUP) |
213                                           MUX_MODE_SION,
214         MX6_PAD_EIM_D27__GPIO3_IO27     | MUX_PAD_CTRL(WEAK_PULLUP) |
215                                           MUX_MODE_SION,
216         MX6_PAD_NANDF_D6__GPIO2_IO06    | MUX_PAD_CTRL(WEAK_PULLUP) |
217                                           MUX_MODE_SION,
218         MX6_PAD_NANDF_D3__GPIO2_IO03    | MUX_PAD_CTRL(WEAK_PULLUP) |
219                                           MUX_MODE_SION,
220         MX6_PAD_ENET_REF_CLK__GPIO1_IO23 | MUX_PAD_CTRL(WEAK_PULLUP) |
221                                           MUX_MODE_SION,
222         MX6_PAD_DI0_PIN4__GPIO4_IO20    | MUX_PAD_CTRL(WEAK_PULLUP) |
223                                           MUX_MODE_SION,
224         MX6_PAD_SD4_DAT3__GPIO2_IO11    | MUX_PAD_CTRL(WEAK_PULLUP) |
225                                           MUX_MODE_SION,
226         MX6_PAD_NANDF_D4__GPIO2_IO04    | MUX_PAD_CTRL(WEAK_PULLUP) |
227                                           MUX_MODE_SION,
228         MX6_PAD_SD4_DAT0__GPIO2_IO08    | MUX_PAD_CTRL(WEAK_PULLUP) |
229                                           MUX_MODE_SION,
230         MX6_PAD_GPIO_7__GPIO1_IO07      | MUX_PAD_CTRL(WEAK_PULLUP) |
231                                           MUX_MODE_SION,
232         MX6_PAD_GPIO_8__GPIO1_IO08      | MUX_PAD_CTRL(WEAK_PULLUP) |
233                                           MUX_MODE_SION,
234         /* USBH_OC */
235         MX6_PAD_EIM_D30__GPIO3_IO30     | MUX_PAD_CTRL(WEAK_PULLUP),
236         /* USBC_ID */
237         MX6_PAD_NANDF_D2__GPIO2_IO02    | MUX_PAD_CTRL(WEAK_PULLUP),
238         /* USBC_DET */
239         MX6_PAD_GPIO_17__GPIO7_IO12     | MUX_PAD_CTRL(WEAK_PULLUP),
240 };
241
242 static void setup_iomux_gpio(void)
243 {
244         imx_iomux_v3_setup_multiple_pads(gpio_pads, ARRAY_SIZE(gpio_pads));
245 }
246
247 iomux_v3_cfg_t const usb_pads[] = {
248         /* USBH_PEN */
249         MX6_PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL) | MUX_MODE_SION,
250 #       define GPIO_USBH_EN IMX_GPIO_NR(3, 31)
251 };
252
253 /*
254  * UARTs are used in DTE mode, switch the mode on all UARTs before
255  * any pinmuxing connects a (DCE) output to a transceiver output.
256  */
257 #define UCR3            0x88    /* FIFO Control Register */
258 #define UCR3_RI         BIT(8)  /* RIDELT DTE mode */
259 #define UCR3_DCD        BIT(9)  /* DCDDELT DTE mode */
260 #define UFCR            0x90    /* FIFO Control Register */
261 #define UFCR_DCEDTE     BIT(6)  /* DCE=0 */
262
263 static void setup_dtemode_uart(void)
264 {
265         setbits_le32((u32 *)(UART1_BASE + UFCR), UFCR_DCEDTE);
266         setbits_le32((u32 *)(UART2_BASE + UFCR), UFCR_DCEDTE);
267         setbits_le32((u32 *)(UART3_BASE + UFCR), UFCR_DCEDTE);
268
269         clrbits_le32((u32 *)(UART1_BASE + UCR3), UCR3_DCD | UCR3_RI);
270         clrbits_le32((u32 *)(UART2_BASE + UCR3), UCR3_DCD | UCR3_RI);
271         clrbits_le32((u32 *)(UART3_BASE + UCR3), UCR3_DCD | UCR3_RI);
272 }
273
274 static void setup_iomux_uart(void)
275 {
276         setup_dtemode_uart();
277         imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
278 }
279
280 #ifdef CONFIG_USB_EHCI_MX6
281 int board_ehci_hcd_init(int port)
282 {
283         imx_iomux_v3_setup_multiple_pads(usb_pads, ARRAY_SIZE(usb_pads));
284         return 0;
285 }
286 #endif
287
288 #if defined(CONFIG_FSL_ESDHC_IMX) && defined(CONFIG_SPL_BUILD)
289 /* use the following sequence: eMMC, MMC */
290 struct fsl_esdhc_cfg usdhc_cfg[CONFIG_SYS_FSL_USDHC_NUM] = {
291         {USDHC3_BASE_ADDR},
292         {USDHC1_BASE_ADDR},
293 };
294
295 int board_mmc_getcd(struct mmc *mmc)
296 {
297         struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
298         int ret = true; /* default: assume inserted */
299
300         switch (cfg->esdhc_base) {
301         case USDHC1_BASE_ADDR:
302                 gpio_request(GPIO_MMC_CD, "MMC_CD");
303                 gpio_direction_input(GPIO_MMC_CD);
304                 ret = !gpio_get_value(GPIO_MMC_CD);
305                 break;
306         }
307
308         return ret;
309 }
310
311 int board_mmc_init(bd_t *bis)
312 {
313         struct src *psrc = (struct src *)SRC_BASE_ADDR;
314         unsigned reg = readl(&psrc->sbmr1) >> 11;
315         /*
316          * Upon reading BOOT_CFG register the following map is done:
317          * Bit 11 and 12 of BOOT_CFG register can determine the current
318          * mmc port
319          * 0x1                  SD1
320          * 0x2                  SD2
321          * 0x3                  SD4
322          */
323
324         switch (reg & 0x3) {
325         case 0x0:
326                 imx_iomux_v3_setup_multiple_pads(
327                         usdhc1_pads, ARRAY_SIZE(usdhc1_pads));
328                 usdhc_cfg[0].esdhc_base = USDHC1_BASE_ADDR;
329                 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
330                 gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
331                 break;
332         case 0x2:
333                 imx_iomux_v3_setup_multiple_pads(
334                         usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
335                 usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
336                 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
337                 gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
338                 break;
339         default:
340                 puts("MMC boot device not available");
341         }
342
343         return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
344 }
345 #endif /* CONFIG_FSL_ESDHC_IMX & CONFIG_SPL_BUILD */
346
347 int board_phy_config(struct phy_device *phydev)
348 {
349         if (phydev->drv->config)
350                 phydev->drv->config(phydev);
351
352         return 0;
353 }
354
355 int setup_fec(void)
356 {
357         int ret;
358         struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
359
360         /* provide the PHY clock from the i.MX 6 */
361         ret = enable_fec_anatop_clock(0, ENET_50MHZ);
362         if (ret)
363                 return ret;
364
365         setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_ENET_CLK_SEL_MASK);
366
367         return 0;
368 }
369
370 static iomux_v3_cfg_t const pwr_intb_pads[] = {
371         /*
372          * the bootrom sets the iomux to vselect, potentially connecting
373          * two outputs. Set this back to GPIO
374          */
375         MX6_PAD_GPIO_18__GPIO7_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL)
376 };
377
378 #if defined(CONFIG_VIDEO_IPUV3)
379
380 static iomux_v3_cfg_t const backlight_pads[] = {
381         /* Backlight On */
382         MX6_PAD_EIM_D26__GPIO3_IO26 | MUX_PAD_CTRL(NO_PAD_CTRL) | MUX_MODE_SION,
383 #define RGB_BACKLIGHT_GP IMX_GPIO_NR(3, 26)
384         /* Backlight PWM, used as GPIO in U-Boot */
385         MX6_PAD_EIM_A22__GPIO2_IO16  | MUX_PAD_CTRL(NO_PULLUP),
386         MX6_PAD_SD4_DAT1__GPIO2_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL) |
387                                        MUX_MODE_SION,
388 #define RGB_BACKLIGHTPWM_GP IMX_GPIO_NR(2, 9)
389 };
390
391 static iomux_v3_cfg_t const rgb_pads[] = {
392         MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK | MUX_PAD_CTRL(OUTPUT_RGB),
393         MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15 | MUX_PAD_CTRL(OUTPUT_RGB),
394         MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02 | MUX_PAD_CTRL(OUTPUT_RGB),
395         MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03 | MUX_PAD_CTRL(OUTPUT_RGB),
396         MX6_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 | MUX_PAD_CTRL(OUTPUT_RGB),
397         MX6_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 | MUX_PAD_CTRL(OUTPUT_RGB),
398         MX6_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 | MUX_PAD_CTRL(OUTPUT_RGB),
399         MX6_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 | MUX_PAD_CTRL(OUTPUT_RGB),
400         MX6_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 | MUX_PAD_CTRL(OUTPUT_RGB),
401         MX6_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 | MUX_PAD_CTRL(OUTPUT_RGB),
402         MX6_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 | MUX_PAD_CTRL(OUTPUT_RGB),
403         MX6_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 | MUX_PAD_CTRL(OUTPUT_RGB),
404         MX6_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 | MUX_PAD_CTRL(OUTPUT_RGB),
405         MX6_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 | MUX_PAD_CTRL(OUTPUT_RGB),
406         MX6_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 | MUX_PAD_CTRL(OUTPUT_RGB),
407         MX6_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 | MUX_PAD_CTRL(OUTPUT_RGB),
408         MX6_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 | MUX_PAD_CTRL(OUTPUT_RGB),
409         MX6_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 | MUX_PAD_CTRL(OUTPUT_RGB),
410         MX6_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 | MUX_PAD_CTRL(OUTPUT_RGB),
411         MX6_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 | MUX_PAD_CTRL(OUTPUT_RGB),
412         MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 | MUX_PAD_CTRL(OUTPUT_RGB),
413         MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 | MUX_PAD_CTRL(OUTPUT_RGB),
414 };
415
416 static void do_enable_hdmi(struct display_info_t const *dev)
417 {
418         imx_enable_hdmi_phy();
419 }
420
421 static void enable_rgb(struct display_info_t const *dev)
422 {
423         imx_iomux_v3_setup_multiple_pads(
424                 rgb_pads,
425                 ARRAY_SIZE(rgb_pads));
426         gpio_direction_output(RGB_BACKLIGHT_GP, 1);
427         gpio_direction_output(RGB_BACKLIGHTPWM_GP, 0);
428 }
429
430 static int detect_default(struct display_info_t const *dev)
431 {
432         (void) dev;
433         return 1;
434 }
435
436 struct display_info_t const displays[] = {{
437         .bus    = -1,
438         .addr   = 0,
439         .pixfmt = IPU_PIX_FMT_RGB24,
440         .detect = detect_hdmi,
441         .enable = do_enable_hdmi,
442         .mode   = {
443                 .name           = "HDMI",
444                 .refresh        = 60,
445                 .xres           = 1024,
446                 .yres           = 768,
447                 .pixclock       = 15385,
448                 .left_margin    = 220,
449                 .right_margin   = 40,
450                 .upper_margin   = 21,
451                 .lower_margin   = 7,
452                 .hsync_len      = 60,
453                 .vsync_len      = 10,
454                 .sync           = FB_SYNC_EXT,
455                 .vmode          = FB_VMODE_NONINTERLACED
456 } }, {
457         .bus    = -1,
458         .addr   = 0,
459         .pixfmt = IPU_PIX_FMT_RGB666,
460         .detect = detect_default,
461         .enable = enable_rgb,
462         .mode   = {
463                 .name           = "vga-rgb",
464                 .refresh        = 60,
465                 .xres           = 640,
466                 .yres           = 480,
467                 .pixclock       = 33000,
468                 .left_margin    = 48,
469                 .right_margin   = 16,
470                 .upper_margin   = 31,
471                 .lower_margin   = 11,
472                 .hsync_len      = 96,
473                 .vsync_len      = 2,
474                 .sync           = 0,
475                 .vmode          = FB_VMODE_NONINTERLACED
476 } }, {
477         .bus    = -1,
478         .addr   = 0,
479         .pixfmt = IPU_PIX_FMT_RGB666,
480         .enable = enable_rgb,
481         .mode   = {
482                 .name           = "wvga-rgb",
483                 .refresh        = 60,
484                 .xres           = 800,
485                 .yres           = 480,
486                 .pixclock       = 25000,
487                 .left_margin    = 40,
488                 .right_margin   = 88,
489                 .upper_margin   = 33,
490                 .lower_margin   = 10,
491                 .hsync_len      = 128,
492                 .vsync_len      = 2,
493                 .sync           = 0,
494                 .vmode          = FB_VMODE_NONINTERLACED
495 } } };
496 size_t display_count = ARRAY_SIZE(displays);
497
498 static void setup_display(void)
499 {
500         struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
501         struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
502         int reg;
503
504         enable_ipu_clock();
505         imx_setup_hdmi();
506         /* Turn on LDB0,IPU,IPU DI0 clocks */
507         reg = __raw_readl(&mxc_ccm->CCGR3);
508         reg |= MXC_CCM_CCGR3_LDB_DI0_MASK;
509         writel(reg, &mxc_ccm->CCGR3);
510
511         /* set LDB0, LDB1 clk select to 011/011 */
512         reg = readl(&mxc_ccm->cs2cdr);
513         reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
514                  |MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
515         reg |= (3<<MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
516               |(3<<MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
517         writel(reg, &mxc_ccm->cs2cdr);
518
519         reg = readl(&mxc_ccm->cscmr2);
520         reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
521         writel(reg, &mxc_ccm->cscmr2);
522
523         reg = readl(&mxc_ccm->chsccdr);
524         reg |= (CHSCCDR_CLK_SEL_LDB_DI0
525                 <<MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
526         writel(reg, &mxc_ccm->chsccdr);
527
528         reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
529              |IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
530              |IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
531              |IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
532              |IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
533              |IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
534              |IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
535              |IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED
536              |IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
537         writel(reg, &iomux->gpr[2]);
538
539         reg = readl(&iomux->gpr[3]);
540         reg = (reg & ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK
541                         |IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
542             | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
543                <<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
544         writel(reg, &iomux->gpr[3]);
545
546         /* backlight unconditionally on for now */
547         imx_iomux_v3_setup_multiple_pads(backlight_pads,
548                                          ARRAY_SIZE(backlight_pads));
549         /* use 0 for EDT 7", use 1 for LG fullHD panel */
550         gpio_request(RGB_BACKLIGHTPWM_GP, "PWM<A>");
551         gpio_request(RGB_BACKLIGHT_GP, "BL_ON");
552         gpio_direction_output(RGB_BACKLIGHTPWM_GP, 0);
553         gpio_direction_output(RGB_BACKLIGHT_GP, 1);
554 }
555
556 /*
557  * Backlight off before OS handover
558  */
559 void board_preboot_os(void)
560 {
561         gpio_direction_output(RGB_BACKLIGHTPWM_GP, 1);
562         gpio_direction_output(RGB_BACKLIGHT_GP, 0);
563 }
564 #endif /* defined(CONFIG_VIDEO_IPUV3) */
565
566 int board_early_init_f(void)
567 {
568         imx_iomux_v3_setup_multiple_pads(pwr_intb_pads,
569                                          ARRAY_SIZE(pwr_intb_pads));
570         setup_iomux_uart();
571
572         return 0;
573 }
574
575 /*
576  * Do not overwrite the console
577  * Use always serial for U-Boot console
578  */
579 int overwrite_console(void)
580 {
581         return 1;
582 }
583
584 int board_init(void)
585 {
586         /* address of boot parameters */
587         gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
588 #if defined(CONFIG_FEC_MXC)
589         setup_fec();
590 #endif
591 #if defined(CONFIG_VIDEO_IPUV3)
592         setup_display();
593 #endif
594
595 #ifdef CONFIG_TDX_CMD_IMX_MFGR
596         (void) pmic_init();
597 #endif
598
599 #ifdef CONFIG_SATA
600         setup_sata();
601 #endif
602
603         setup_iomux_gpio();
604
605         return 0;
606 }
607
608 #ifdef CONFIG_BOARD_LATE_INIT
609 int board_late_init(void)
610 {
611 #if defined(CONFIG_REVISION_TAG) && \
612     defined(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG)
613         char env_str[256];
614         u32 rev;
615
616         rev = get_board_rev();
617         snprintf(env_str, ARRAY_SIZE(env_str), "%.4x", rev);
618         env_set("board_rev", env_str);
619 #endif
620
621 #ifdef CONFIG_CMD_USB_SDP
622         if (is_boot_from_usb()) {
623                 printf("Serial Downloader recovery mode, using sdp command\n");
624                 env_set("bootdelay", "0");
625                 env_set("bootcmd", "sdp 0");
626         }
627 #endif /* CONFIG_CMD_USB_SDP */
628
629         return 0;
630 }
631 #endif /* CONFIG_BOARD_LATE_INIT */
632
633 int checkboard(void)
634 {
635         char it[] = " IT";
636         int minc, maxc;
637
638         switch (get_cpu_temp_grade(&minc, &maxc)) {
639         case TEMP_AUTOMOTIVE:
640         case TEMP_INDUSTRIAL:
641                 break;
642         case TEMP_EXTCOMMERCIAL:
643         default:
644                 it[0] = 0;
645         };
646         printf("Model: Toradex Colibri iMX6 %s %sMB%s\n",
647                is_cpu_type(MXC_CPU_MX6DL) ? "DualLite" : "Solo",
648                (gd->ram_size == 0x20000000) ? "512" : "256", it);
649         return 0;
650 }
651
652 #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
653 int ft_board_setup(void *blob, bd_t *bd)
654 {
655         u32 cma_size;
656
657         ft_common_board_setup(blob, bd);
658
659         cma_size = env_get_ulong("cma-size", 10, 320 * 1024 * 1024);
660         cma_size = min((u32)(gd->ram_size >> 1), cma_size);
661
662         fdt_setprop_u32(blob,
663                         fdt_path_offset(blob, "/reserved-memory/linux,cma"),
664                         "size",
665                         cma_size);
666         return 0;
667 }
668 #endif
669
670 #ifdef CONFIG_CMD_BMODE
671 static const struct boot_mode board_boot_modes[] = {
672         {"mmc", MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)},
673         {NULL,  0},
674 };
675 #endif
676
677 int misc_init_r(void)
678 {
679 #ifdef CONFIG_CMD_BMODE
680         add_board_boot_modes(board_boot_modes);
681 #endif
682         return 0;
683 }
684
685 #ifdef CONFIG_LDO_BYPASS_CHECK
686 /* TODO, use external pmic, for now always ldo_enable */
687 void ldo_mode_set(int ldo_bypass)
688 {
689         return;
690 }
691 #endif
692
693 #ifdef CONFIG_SPL_BUILD
694 #include <spl.h>
695 #include <linux/libfdt.h>
696 #include "asm/arch/mx6dl-ddr.h"
697 #include "asm/arch/iomux.h"
698 #include "asm/arch/crm_regs.h"
699
700 static int mx6s_dcd_table[] = {
701 /* ddr-setup.cfg */
702
703 MX6_IOM_DRAM_SDQS0, 0x00000030,
704 MX6_IOM_DRAM_SDQS1, 0x00000030,
705 MX6_IOM_DRAM_SDQS2, 0x00000030,
706 MX6_IOM_DRAM_SDQS3, 0x00000030,
707 MX6_IOM_DRAM_SDQS4, 0x00000030,
708 MX6_IOM_DRAM_SDQS5, 0x00000030,
709 MX6_IOM_DRAM_SDQS6, 0x00000030,
710 MX6_IOM_DRAM_SDQS7, 0x00000030,
711
712 MX6_IOM_GRP_B0DS, 0x00000030,
713 MX6_IOM_GRP_B1DS, 0x00000030,
714 MX6_IOM_GRP_B2DS, 0x00000030,
715 MX6_IOM_GRP_B3DS, 0x00000030,
716 MX6_IOM_GRP_B4DS, 0x00000030,
717 MX6_IOM_GRP_B5DS, 0x00000030,
718 MX6_IOM_GRP_B6DS, 0x00000030,
719 MX6_IOM_GRP_B7DS, 0x00000030,
720 MX6_IOM_GRP_ADDDS, 0x00000030,
721 /* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */
722 MX6_IOM_GRP_CTLDS, 0x00000030,
723
724 MX6_IOM_DRAM_DQM0, 0x00020030,
725 MX6_IOM_DRAM_DQM1, 0x00020030,
726 MX6_IOM_DRAM_DQM2, 0x00020030,
727 MX6_IOM_DRAM_DQM3, 0x00020030,
728 MX6_IOM_DRAM_DQM4, 0x00020030,
729 MX6_IOM_DRAM_DQM5, 0x00020030,
730 MX6_IOM_DRAM_DQM6, 0x00020030,
731 MX6_IOM_DRAM_DQM7, 0x00020030,
732
733 MX6_IOM_DRAM_CAS, 0x00020030,
734 MX6_IOM_DRAM_RAS, 0x00020030,
735 MX6_IOM_DRAM_SDCLK_0, 0x00020030,
736 MX6_IOM_DRAM_SDCLK_1, 0x00020030,
737
738 MX6_IOM_DRAM_RESET, 0x00020030,
739 MX6_IOM_DRAM_SDCKE0, 0x00003000,
740 MX6_IOM_DRAM_SDCKE1, 0x00003000,
741
742 MX6_IOM_DRAM_SDODT0, 0x00003030,
743 MX6_IOM_DRAM_SDODT1, 0x00003030,
744
745 /* (differential input) */
746 MX6_IOM_DDRMODE_CTL, 0x00020000,
747 /* (differential input) */
748 MX6_IOM_GRP_DDRMODE, 0x00020000,
749 /* disable ddr pullups */
750 MX6_IOM_GRP_DDRPKE, 0x00000000,
751 MX6_IOM_DRAM_SDBA2, 0x00000000,
752 /* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */
753 MX6_IOM_GRP_DDR_TYPE, 0x000C0000,
754
755 /* Read data DQ Byte0-3 delay */
756 MX6_MMDC_P0_MPRDDQBY0DL, 0x33333333,
757 MX6_MMDC_P0_MPRDDQBY1DL, 0x33333333,
758 MX6_MMDC_P0_MPRDDQBY2DL, 0x33333333,
759 MX6_MMDC_P0_MPRDDQBY3DL, 0x33333333,
760 MX6_MMDC_P1_MPRDDQBY0DL, 0x33333333,
761 MX6_MMDC_P1_MPRDDQBY1DL, 0x33333333,
762 MX6_MMDC_P1_MPRDDQBY2DL, 0x33333333,
763 MX6_MMDC_P1_MPRDDQBY3DL, 0x33333333,
764
765 /*
766  * MDMISC       mirroring       interleaved (row/bank/col)
767  */
768 /* TODO: check what the RALAT field does */
769 MX6_MMDC_P0_MDMISC, 0x00081740,
770
771 /*
772  * MDSCR        con_req
773  */
774 MX6_MMDC_P0_MDSCR, 0x00008000,
775
776
777 /* 800mhz_2x64mx16.cfg */
778
779 MX6_MMDC_P0_MDPDC, 0x0002002D,
780 MX6_MMDC_P0_MDCFG0, 0x2C305503,
781 MX6_MMDC_P0_MDCFG1, 0xB66D8D63,
782 MX6_MMDC_P0_MDCFG2, 0x01FF00DB,
783 MX6_MMDC_P0_MDRWD, 0x000026D2,
784 MX6_MMDC_P0_MDOR, 0x00301023,
785 MX6_MMDC_P0_MDOTC, 0x00333030,
786 MX6_MMDC_P0_MDPDC, 0x0002556D,
787 /* CS0 End: 7MSB of ((0x10000000, + 512M) -1) >> 25 */
788 MX6_MMDC_P0_MDASP, 0x00000017,
789 /* DDR3 DATA BUS SIZE: 64BIT */
790 /* MX6_MMDC_P0_MDCTL, 0x821A0000, */
791 /* DDR3 DATA BUS SIZE: 32BIT */
792 MX6_MMDC_P0_MDCTL, 0x82190000,
793
794 /* Write commands to DDR */
795 /* Load Mode Registers */
796 /* TODO Use Auto Self-Refresh mode (Extended Temperature)*/
797 /* MX6_MMDC_P0_MDSCR, 0x04408032, */
798 MX6_MMDC_P0_MDSCR, 0x04008032,
799 MX6_MMDC_P0_MDSCR, 0x00008033,
800 MX6_MMDC_P0_MDSCR, 0x00048031,
801 MX6_MMDC_P0_MDSCR, 0x13208030,
802 /* ZQ calibration */
803 MX6_MMDC_P0_MDSCR, 0x04008040,
804
805 MX6_MMDC_P0_MPZQHWCTRL, 0xA1390003,
806 MX6_MMDC_P1_MPZQHWCTRL, 0xA1390003,
807 MX6_MMDC_P0_MDREF, 0x00005800,
808
809 MX6_MMDC_P0_MPODTCTRL, 0x00000000,
810 MX6_MMDC_P1_MPODTCTRL, 0x00000000,
811
812 MX6_MMDC_P0_MPDGCTRL0, 0x42360232,
813 MX6_MMDC_P0_MPDGCTRL1, 0x021F022A,
814 MX6_MMDC_P1_MPDGCTRL0, 0x421E0224,
815 MX6_MMDC_P1_MPDGCTRL1, 0x02110218,
816
817 MX6_MMDC_P0_MPRDDLCTL, 0x41434344,
818 MX6_MMDC_P1_MPRDDLCTL, 0x4345423E,
819 MX6_MMDC_P0_MPWRDLCTL, 0x39383339,
820 MX6_MMDC_P1_MPWRDLCTL, 0x3E363930,
821
822 MX6_MMDC_P0_MPWLDECTRL0, 0x00340039,
823 MX6_MMDC_P0_MPWLDECTRL1, 0x002C002D,
824 MX6_MMDC_P1_MPWLDECTRL0, 0x00120019,
825 MX6_MMDC_P1_MPWLDECTRL1, 0x0012002D,
826
827 MX6_MMDC_P0_MPMUR0, 0x00000800,
828 MX6_MMDC_P1_MPMUR0, 0x00000800,
829 MX6_MMDC_P0_MDSCR, 0x00000000,
830 MX6_MMDC_P0_MAPSR, 0x00011006,
831 };
832
833 static int mx6dl_dcd_table[] = {
834 /* ddr-setup.cfg */
835
836 MX6_IOM_DRAM_SDQS0, 0x00000030,
837 MX6_IOM_DRAM_SDQS1, 0x00000030,
838 MX6_IOM_DRAM_SDQS2, 0x00000030,
839 MX6_IOM_DRAM_SDQS3, 0x00000030,
840 MX6_IOM_DRAM_SDQS4, 0x00000030,
841 MX6_IOM_DRAM_SDQS5, 0x00000030,
842 MX6_IOM_DRAM_SDQS6, 0x00000030,
843 MX6_IOM_DRAM_SDQS7, 0x00000030,
844
845 MX6_IOM_GRP_B0DS, 0x00000030,
846 MX6_IOM_GRP_B1DS, 0x00000030,
847 MX6_IOM_GRP_B2DS, 0x00000030,
848 MX6_IOM_GRP_B3DS, 0x00000030,
849 MX6_IOM_GRP_B4DS, 0x00000030,
850 MX6_IOM_GRP_B5DS, 0x00000030,
851 MX6_IOM_GRP_B6DS, 0x00000030,
852 MX6_IOM_GRP_B7DS, 0x00000030,
853 MX6_IOM_GRP_ADDDS, 0x00000030,
854 /* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */
855 MX6_IOM_GRP_CTLDS, 0x00000030,
856
857 MX6_IOM_DRAM_DQM0, 0x00020030,
858 MX6_IOM_DRAM_DQM1, 0x00020030,
859 MX6_IOM_DRAM_DQM2, 0x00020030,
860 MX6_IOM_DRAM_DQM3, 0x00020030,
861 MX6_IOM_DRAM_DQM4, 0x00020030,
862 MX6_IOM_DRAM_DQM5, 0x00020030,
863 MX6_IOM_DRAM_DQM6, 0x00020030,
864 MX6_IOM_DRAM_DQM7, 0x00020030,
865
866 MX6_IOM_DRAM_CAS, 0x00020030,
867 MX6_IOM_DRAM_RAS, 0x00020030,
868 MX6_IOM_DRAM_SDCLK_0, 0x00020030,
869 MX6_IOM_DRAM_SDCLK_1, 0x00020030,
870
871 MX6_IOM_DRAM_RESET, 0x00020030,
872 MX6_IOM_DRAM_SDCKE0, 0x00003000,
873 MX6_IOM_DRAM_SDCKE1, 0x00003000,
874
875 MX6_IOM_DRAM_SDODT0, 0x00003030,
876 MX6_IOM_DRAM_SDODT1, 0x00003030,
877
878 /* (differential input) */
879 MX6_IOM_DDRMODE_CTL, 0x00020000,
880 /* (differential input) */
881 MX6_IOM_GRP_DDRMODE, 0x00020000,
882 /* disable ddr pullups */
883 MX6_IOM_GRP_DDRPKE, 0x00000000,
884 MX6_IOM_DRAM_SDBA2, 0x00000000,
885 /* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */
886 MX6_IOM_GRP_DDR_TYPE, 0x000C0000,
887
888 /* Read data DQ Byte0-3 delay */
889 MX6_MMDC_P0_MPRDDQBY0DL, 0x33333333,
890 MX6_MMDC_P0_MPRDDQBY1DL, 0x33333333,
891 MX6_MMDC_P0_MPRDDQBY2DL, 0x33333333,
892 MX6_MMDC_P0_MPRDDQBY3DL, 0x33333333,
893 MX6_MMDC_P1_MPRDDQBY0DL, 0x33333333,
894 MX6_MMDC_P1_MPRDDQBY1DL, 0x33333333,
895 MX6_MMDC_P1_MPRDDQBY2DL, 0x33333333,
896 MX6_MMDC_P1_MPRDDQBY3DL, 0x33333333,
897
898 /*
899  * MDMISC       mirroring       interleaved (row/bank/col)
900  */
901 /* TODO: check what the RALAT field does */
902 MX6_MMDC_P0_MDMISC, 0x00081740,
903
904 /*
905  * MDSCR        con_req
906  */
907 MX6_MMDC_P0_MDSCR, 0x00008000,
908
909
910 /* 800mhz_2x64mx16.cfg */
911
912 MX6_MMDC_P0_MDPDC, 0x0002002D,
913 MX6_MMDC_P0_MDCFG0, 0x2C305503,
914 MX6_MMDC_P0_MDCFG1, 0xB66D8D63,
915 MX6_MMDC_P0_MDCFG2, 0x01FF00DB,
916 MX6_MMDC_P0_MDRWD, 0x000026D2,
917 MX6_MMDC_P0_MDOR, 0x00301023,
918 MX6_MMDC_P0_MDOTC, 0x00333030,
919 MX6_MMDC_P0_MDPDC, 0x0002556D,
920 /* CS0 End: 7MSB of ((0x10000000, + 512M) -1) >> 25 */
921 MX6_MMDC_P0_MDASP, 0x00000017,
922 /* DDR3 DATA BUS SIZE: 64BIT */
923 MX6_MMDC_P0_MDCTL, 0x821A0000,
924 /* DDR3 DATA BUS SIZE: 32BIT */
925 /* MX6_MMDC_P0_MDCTL, 0x82190000, */
926
927 /* Write commands to DDR */
928 /* Load Mode Registers */
929 /* TODO Use Auto Self-Refresh mode (Extended Temperature)*/
930 /* MX6_MMDC_P0_MDSCR, 0x04408032, */
931 MX6_MMDC_P0_MDSCR, 0x04008032,
932 MX6_MMDC_P0_MDSCR, 0x00008033,
933 MX6_MMDC_P0_MDSCR, 0x00048031,
934 MX6_MMDC_P0_MDSCR, 0x13208030,
935 /* ZQ calibration */
936 MX6_MMDC_P0_MDSCR, 0x04008040,
937
938 MX6_MMDC_P0_MPZQHWCTRL, 0xA1390003,
939 MX6_MMDC_P1_MPZQHWCTRL, 0xA1390003,
940 MX6_MMDC_P0_MDREF, 0x00005800,
941
942 MX6_MMDC_P0_MPODTCTRL, 0x00000000,
943 MX6_MMDC_P1_MPODTCTRL, 0x00000000,
944
945 MX6_MMDC_P0_MPDGCTRL0, 0x42360232,
946 MX6_MMDC_P0_MPDGCTRL1, 0x021F022A,
947 MX6_MMDC_P1_MPDGCTRL0, 0x421E0224,
948 MX6_MMDC_P1_MPDGCTRL1, 0x02110218,
949
950 MX6_MMDC_P0_MPRDDLCTL, 0x41434344,
951 MX6_MMDC_P1_MPRDDLCTL, 0x4345423E,
952 MX6_MMDC_P0_MPWRDLCTL, 0x39383339,
953 MX6_MMDC_P1_MPWRDLCTL, 0x3E363930,
954
955 MX6_MMDC_P0_MPWLDECTRL0, 0x00340039,
956 MX6_MMDC_P0_MPWLDECTRL1, 0x002C002D,
957 MX6_MMDC_P1_MPWLDECTRL0, 0x00120019,
958 MX6_MMDC_P1_MPWLDECTRL1, 0x0012002D,
959
960 MX6_MMDC_P0_MPMUR0, 0x00000800,
961 MX6_MMDC_P1_MPMUR0, 0x00000800,
962 MX6_MMDC_P0_MDSCR, 0x00000000,
963 MX6_MMDC_P0_MAPSR, 0x00011006,
964 };
965
966 static void ccgr_init(void)
967 {
968         struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
969
970         writel(0x00C03F3F, &ccm->CCGR0);
971         writel(0x0030FC03, &ccm->CCGR1);
972         writel(0x0FFFFFF3, &ccm->CCGR2);
973         writel(0x3FF0300F, &ccm->CCGR3);
974         writel(0x00FFF300, &ccm->CCGR4);
975         writel(0x0F0000F3, &ccm->CCGR5);
976         writel(0x000003FF, &ccm->CCGR6);
977
978 /*
979  * Setup CCM_CCOSR register as follows:
980  *
981  * cko1_en  = 1    --> CKO1 enabled
982  * cko1_div = 111  --> divide by 8
983  * cko1_sel = 1011 --> ahb_clk_root
984  *
985  * This sets CKO1 at ahb_clk_root/8 = 132/8 = 16.5 MHz
986  */
987         writel(0x000000FB, &ccm->ccosr);
988 }
989
990 static void ddr_init(int *table, int size)
991 {
992         int i;
993
994         for (i = 0; i < size / 2 ; i++)
995                 writel(table[2 * i + 1], table[2 * i]);
996 }
997
998 static void spl_dram_init(void)
999 {
1000         int minc, maxc;
1001
1002         switch (get_cpu_temp_grade(&minc, &maxc)) {
1003         case TEMP_COMMERCIAL:
1004         case TEMP_EXTCOMMERCIAL:
1005                 if (is_cpu_type(MXC_CPU_MX6DL)) {
1006                         puts("Commercial temperature grade DDR3 timings, 64bit bus width.\n");
1007                         ddr_init(mx6dl_dcd_table, ARRAY_SIZE(mx6dl_dcd_table));
1008                 } else {
1009                         puts("Commercial temperature grade DDR3 timings, 32bit bus width.\n");
1010                         ddr_init(mx6s_dcd_table, ARRAY_SIZE(mx6s_dcd_table));
1011                 }
1012                 break;
1013         case TEMP_INDUSTRIAL:
1014         case TEMP_AUTOMOTIVE:
1015         default:
1016                 if (is_cpu_type(MXC_CPU_MX6DL)) {
1017                         puts("Industrial temperature grade DDR3 timings, 64bit bus width.\n");
1018                         ddr_init(mx6dl_dcd_table, ARRAY_SIZE(mx6dl_dcd_table));
1019                 } else {
1020                         puts("Industrial temperature grade DDR3 timings, 32bit bus width.\n");
1021                         ddr_init(mx6s_dcd_table, ARRAY_SIZE(mx6s_dcd_table));
1022                 }
1023                 break;
1024         };
1025         udelay(100);
1026 }
1027
1028 static iomux_v3_cfg_t const gpio_reset_pad[] = {
1029         MX6_PAD_RGMII_RD1__GPIO6_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL) |
1030                                         MUX_MODE_SION
1031 #define GPIO_NRESET IMX_GPIO_NR(6, 27)
1032 };
1033
1034 #define IMX_RESET_CAUSE_POR 0x00011
1035 static void nreset_out(void)
1036 {
1037         int reset_cause = get_imx_reset_cause();
1038
1039         if (reset_cause != IMX_RESET_CAUSE_POR) {
1040                 imx_iomux_v3_setup_multiple_pads(gpio_reset_pad,
1041                                                  ARRAY_SIZE(gpio_reset_pad));
1042                 gpio_direction_output(GPIO_NRESET, 1);
1043                 udelay(100);
1044                 gpio_direction_output(GPIO_NRESET, 0);
1045         }
1046 }
1047
1048 void board_init_f(ulong dummy)
1049 {
1050         /* setup AIPS and disable watchdog */
1051         arch_cpu_init();
1052
1053         ccgr_init();
1054         gpr_init();
1055
1056         /* iomux */
1057         board_early_init_f();
1058
1059         /* setup GP timer */
1060         timer_init();
1061
1062         /* UART clocks enabled and gd valid - init serial console */
1063         preloader_console_init();
1064
1065         /* Make sure we use dte mode */
1066         setup_dtemode_uart();
1067
1068         /* DDR initialization */
1069         spl_dram_init();
1070
1071         /* Clear the BSS. */
1072         memset(__bss_start, 0, __bss_end - __bss_start);
1073
1074         /* Assert nReset_Out */
1075         nreset_out();
1076
1077         /* load/boot image from boot device */
1078         board_init_r(NULL, 0);
1079 }
1080
1081 void reset_cpu(ulong addr)
1082 {
1083 }
1084
1085 #endif /* CONFIG_SPL_BUILD */
1086
1087 static struct mxc_serial_platdata mxc_serial_plat = {
1088         .reg = (struct mxc_uart *)UART1_BASE,
1089         .use_dte = true,
1090 };
1091
1092 U_BOOT_DEVICE(mxc_serial) = {
1093         .name = "serial_mxc",
1094         .platdata = &mxc_serial_plat,
1095 };