Merge tag 'u-boot-atmel-fixes-2020.07-a' of https://gitlab.denx.de/u-boot/custodians...
[oweals/u-boot.git] / board / embest / mx6boards / mx6boards.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2014 Eukréa Electromatique
4  * Author: Eric Bénard <eric@eukrea.com>
5  *         Fabio Estevam <fabio.estevam@freescale.com>
6  *         Jon Nettleton <jon.nettleton@gmail.com>
7  *
8  * based on sabresd.c which is :
9  * Copyright (C) 2012 Freescale Semiconductor, Inc.
10  * and on hummingboard.c which is :
11  * Copyright (C) 2013 SolidRun ltd.
12  * Copyright (C) 2013 Jon Nettleton <jon.nettleton@gmail.com>.
13  */
14
15 #include <common.h>
16 #include <init.h>
17 #include <net.h>
18 #include <asm/arch/clock.h>
19 #include <asm/arch/sys_proto.h>
20 #include <asm/arch/imx-regs.h>
21 #include <asm/arch/iomux.h>
22 #include <asm/arch/mx6-pins.h>
23 #include <linux/delay.h>
24 #include <linux/errno.h>
25 #include <asm/gpio.h>
26 #include <asm/mach-imx/iomux-v3.h>
27 #include <asm/mach-imx/boot_mode.h>
28 #include <asm/mach-imx/mxc_i2c.h>
29 #include <asm/mach-imx/spi.h>
30 #include <asm/mach-imx/video.h>
31 #include <i2c.h>
32 #include <input.h>
33 #include <mmc.h>
34 #include <fsl_esdhc_imx.h>
35 #include <miiphy.h>
36 #include <netdev.h>
37 #include <asm/arch/mxc_hdmi.h>
38 #include <asm/arch/crm_regs.h>
39 #include <linux/fb.h>
40 #include <ipu_pixfmt.h>
41 #include <asm/io.h>
42
43 DECLARE_GLOBAL_DATA_PTR;
44
45 #define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                   \
46         PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |                 \
47         PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
48
49 #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP |                    \
50         PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm |                 \
51         PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
52
53 #define USDHC_PAD_CLK_CTRL (PAD_CTL_SPEED_LOW |         \
54         PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST |                  \
55         PAD_CTL_HYS)
56
57 #define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                   \
58         PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
59
60 #define ENET_PAD_CTRL_PD  (PAD_CTL_PUS_100K_DOWN |              \
61         PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
62
63 #define ENET_PAD_CTRL_CLK  ((PAD_CTL_PUS_100K_UP & ~PAD_CTL_PKE) | \
64         PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
65
66 #define I2C_PAD_CTRL    (PAD_CTL_PUS_100K_UP |                  \
67         PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS |   \
68         PAD_CTL_ODE | PAD_CTL_SRE_FAST)
69
70 #define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \
71                       PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
72
73 static int board_type = -1;
74 #define BOARD_IS_MARSBOARD      0
75 #define BOARD_IS_RIOTBOARD      1
76
77 int dram_init(void)
78 {
79         gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
80
81         return 0;
82 }
83
84 static iomux_v3_cfg_t const uart2_pads[] = {
85         MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
86         MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
87 };
88
89 static void setup_iomux_uart(void)
90 {
91         imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
92 }
93
94 iomux_v3_cfg_t const enet_pads[] = {
95         MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
96         MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
97         /* GPIO16 -> AR8035 25MHz */
98         MX6_PAD_GPIO_16__ENET_REF_CLK | MUX_PAD_CTRL(NO_PAD_CTRL),
99         MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(NO_PAD_CTRL),
100         MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
101         MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
102         MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
103         MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
104         MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
105         /* AR8035 CLK_25M --> ENET_REF_CLK (V22) */
106         MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL_CLK),
107         MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
108         MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD),
109         MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD),
110         MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
111         MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
112         MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL_PD),
113         /* AR8035 PHY Reset */
114         MX6_PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD),
115         /* AR8035 PHY Interrupt */
116         MX6_PAD_ENET_TX_EN__GPIO1_IO28 | MUX_PAD_CTRL(ENET_PAD_CTRL),
117 };
118
119 static void setup_iomux_enet(void)
120 {
121         imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
122
123         /* Reset AR8035 PHY */
124         gpio_direction_output(IMX_GPIO_NR(3, 31) , 0);
125         mdelay(2);
126         gpio_set_value(IMX_GPIO_NR(3, 31), 1);
127 }
128
129 int mx6_rgmii_rework(struct phy_device *phydev)
130 {
131         /* from linux/arch/arm/mach-imx/mach-imx6q.c :
132          * Ar803x phy SmartEEE feature cause link status generates glitch,
133          * which cause ethernet link down/up issue, so disable SmartEEE
134          */
135         phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
136         phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x805d);
137         phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4003);
138
139         return 0;
140 }
141
142 int board_phy_config(struct phy_device *phydev)
143 {
144         mx6_rgmii_rework(phydev);
145
146         if (phydev->drv->config)
147                 phydev->drv->config(phydev);
148
149         return 0;
150 }
151
152 iomux_v3_cfg_t const usdhc2_pads[] = {
153         MX6_PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CLK_CTRL),
154         MX6_PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
155         MX6_PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
156         MX6_PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
157         MX6_PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
158         MX6_PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
159         MX6_PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL), /* WP */
160         MX6_PAD_GPIO_4__GPIO1_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
161 };
162
163 iomux_v3_cfg_t const usdhc3_pads[] = {
164         MX6_PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CLK_CTRL),
165         MX6_PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
166         MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
167         MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
168         MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
169         MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
170 };
171
172 iomux_v3_cfg_t const riotboard_usdhc3_pads[] = {
173         MX6_PAD_SD3_DAT4__GPIO7_IO01 | MUX_PAD_CTRL(NO_PAD_CTRL), /* WP */
174         MX6_PAD_SD3_DAT5__GPIO7_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
175 };
176
177 iomux_v3_cfg_t const usdhc4_pads[] = {
178         MX6_PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(USDHC_PAD_CLK_CTRL),
179         MX6_PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
180         MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
181         MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
182         MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
183         MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
184         /* eMMC RST */
185         MX6_PAD_NANDF_ALE__GPIO6_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
186 };
187
188 #ifdef CONFIG_FSL_ESDHC_IMX
189 struct fsl_esdhc_cfg usdhc_cfg[3] = {
190         {USDHC2_BASE_ADDR},
191         {USDHC3_BASE_ADDR},
192         {USDHC4_BASE_ADDR},
193 };
194
195 #define USDHC2_CD_GPIO  IMX_GPIO_NR(1, 4)
196 #define USDHC3_CD_GPIO  IMX_GPIO_NR(7, 0)
197
198 int board_mmc_getcd(struct mmc *mmc)
199 {
200         struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
201         int ret = 0;
202
203         switch (cfg->esdhc_base) {
204         case USDHC2_BASE_ADDR:
205                 ret = !gpio_get_value(USDHC2_CD_GPIO);
206                 break;
207         case USDHC3_BASE_ADDR:
208                 if (board_type == BOARD_IS_RIOTBOARD)
209                         ret = !gpio_get_value(USDHC3_CD_GPIO);
210                 else if (board_type == BOARD_IS_MARSBOARD)
211                         ret = 1; /* eMMC/uSDHC3 is always present */
212                 break;
213         case USDHC4_BASE_ADDR:
214                 ret = 1; /* eMMC/uSDHC4 is always present */
215                 break;
216         }
217
218         return ret;
219 }
220
221 int board_mmc_init(bd_t *bis)
222 {
223         int ret;
224         int i;
225
226         /*
227          * According to the board_mmc_init() the following map is done:
228          * (U-Boot device node)    (Physical Port)
229          * ** RiOTboard :
230          * mmc0                    SDCard slot (bottom)
231          * mmc1                    uSDCard slot (top)
232          * mmc2                    eMMC
233          * ** MarSBoard :
234          * mmc0                    uSDCard slot (bottom)
235          * mmc1                    eMMC
236          */
237         for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
238                 switch (i) {
239                 case 0:
240                         imx_iomux_v3_setup_multiple_pads(
241                                 usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
242                         gpio_direction_input(USDHC2_CD_GPIO);
243                         usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
244                         usdhc_cfg[0].max_bus_width = 4;
245                         break;
246                 case 1:
247                         imx_iomux_v3_setup_multiple_pads(
248                                 usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
249                         if (board_type == BOARD_IS_RIOTBOARD) {
250                                 imx_iomux_v3_setup_multiple_pads(
251                                         riotboard_usdhc3_pads,
252                                         ARRAY_SIZE(riotboard_usdhc3_pads));
253                                 gpio_direction_input(USDHC3_CD_GPIO);
254                         } else {
255                                 gpio_direction_output(IMX_GPIO_NR(7, 8) , 0);
256                                 udelay(250);
257                                 gpio_set_value(IMX_GPIO_NR(7, 8), 1);
258                         }
259                         usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
260                         usdhc_cfg[1].max_bus_width = 4;
261                         break;
262                 case 2:
263                         imx_iomux_v3_setup_multiple_pads(
264                                 usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
265                         usdhc_cfg[2].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
266                         usdhc_cfg[2].max_bus_width = 4;
267                         gpio_direction_output(IMX_GPIO_NR(6, 8) , 0);
268                         udelay(250);
269                         gpio_set_value(IMX_GPIO_NR(6, 8), 1);
270                         break;
271                 default:
272                         printf("Warning: you configured more USDHC controllers"
273                                "(%d) then supported by the board (%d)\n",
274                                i + 1, CONFIG_SYS_FSL_USDHC_NUM);
275                         return -EINVAL;
276                 }
277
278                 ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
279                 if (ret)
280                         return ret;
281         }
282
283         return 0;
284 }
285 #endif
286
287 #ifdef CONFIG_MXC_SPI
288 iomux_v3_cfg_t const ecspi1_pads[] = {
289         MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
290         MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
291         MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
292         MX6_PAD_EIM_EB2__GPIO2_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL),
293 };
294
295 int board_spi_cs_gpio(unsigned bus, unsigned cs)
296 {
297         return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(2, 30)) : -1;
298 }
299
300 static void setup_spi(void)
301 {
302         imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads));
303 }
304 #endif
305
306 struct i2c_pads_info i2c_pad_info1 = {
307         .scl = {
308                 .i2c_mode = MX6_PAD_CSI0_DAT9__I2C1_SCL
309                                 | MUX_PAD_CTRL(I2C_PAD_CTRL),
310                 .gpio_mode = MX6_PAD_CSI0_DAT9__GPIO5_IO27
311                                 | MUX_PAD_CTRL(I2C_PAD_CTRL),
312                 .gp = IMX_GPIO_NR(5, 27)
313         },
314         .sda = {
315                 .i2c_mode = MX6_PAD_CSI0_DAT8__I2C1_SDA
316                                 | MUX_PAD_CTRL(I2C_PAD_CTRL),
317                 .gpio_mode = MX6_PAD_CSI0_DAT8__GPIO5_IO26
318                                 | MUX_PAD_CTRL(I2C_PAD_CTRL),
319                 .gp = IMX_GPIO_NR(5, 26)
320         }
321 };
322
323 struct i2c_pads_info i2c_pad_info2 = {
324         .scl = {
325                 .i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL
326                                 | MUX_PAD_CTRL(I2C_PAD_CTRL),
327                 .gpio_mode = MX6_PAD_KEY_COL3__GPIO4_IO12
328                                 | MUX_PAD_CTRL(I2C_PAD_CTRL),
329                 .gp = IMX_GPIO_NR(4, 12)
330         },
331         .sda = {
332                 .i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA
333                                 | MUX_PAD_CTRL(I2C_PAD_CTRL),
334                 .gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13
335                                 | MUX_PAD_CTRL(I2C_PAD_CTRL),
336                 .gp = IMX_GPIO_NR(4, 13)
337         }
338 };
339
340 struct i2c_pads_info i2c_pad_info3 = {
341         .scl = {
342                 .i2c_mode = MX6_PAD_GPIO_5__I2C3_SCL
343                                 | MUX_PAD_CTRL(I2C_PAD_CTRL),
344                 .gpio_mode = MX6_PAD_GPIO_5__GPIO1_IO05
345                                 | MUX_PAD_CTRL(I2C_PAD_CTRL),
346                 .gp = IMX_GPIO_NR(1, 5)
347         },
348         .sda = {
349                 .i2c_mode = MX6_PAD_GPIO_6__I2C3_SDA
350                                 | MUX_PAD_CTRL(I2C_PAD_CTRL),
351                 .gpio_mode = MX6_PAD_GPIO_6__GPIO1_IO06
352                                 | MUX_PAD_CTRL(I2C_PAD_CTRL),
353                 .gp = IMX_GPIO_NR(1, 6)
354         }
355 };
356
357 iomux_v3_cfg_t const tft_pads_riot[] = {
358         /* LCD_PWR_EN */
359         MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
360         /* TOUCH_INT */
361         MX6_PAD_NANDF_CS1__GPIO6_IO14 | MUX_PAD_CTRL(NO_PAD_CTRL),
362         /* LED_PWR_EN */
363         MX6_PAD_NANDF_CS2__GPIO6_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
364         /* BL LEVEL */
365         MX6_PAD_SD1_CMD__GPIO1_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
366 };
367
368 iomux_v3_cfg_t const tft_pads_mars[] = {
369         /* LCD_PWR_EN */
370         MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
371         /* TOUCH_INT */
372         MX6_PAD_NANDF_CS1__GPIO6_IO14 | MUX_PAD_CTRL(NO_PAD_CTRL),
373         /* LED_PWR_EN */
374         MX6_PAD_NANDF_CS2__GPIO6_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
375         /* BL LEVEL (PWM4) */
376         MX6_PAD_SD4_DAT2__GPIO2_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
377 };
378
379 #if defined(CONFIG_VIDEO_IPUV3)
380
381 static void enable_lvds(struct display_info_t const *dev)
382 {
383         struct iomuxc *iomux = (struct iomuxc *)
384                                 IOMUXC_BASE_ADDR;
385         setbits_le32(&iomux->gpr[2],
386                      IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT);
387         /* set backlight level to ON */
388         if (board_type == BOARD_IS_RIOTBOARD)
389                 gpio_direction_output(IMX_GPIO_NR(1, 18) , 1);
390         else if (board_type == BOARD_IS_MARSBOARD)
391                 gpio_direction_output(IMX_GPIO_NR(2, 10) , 1);
392 }
393
394 static void disable_lvds(struct display_info_t const *dev)
395 {
396         struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
397
398         /* set backlight level to OFF */
399         if (board_type == BOARD_IS_RIOTBOARD)
400                 gpio_direction_output(IMX_GPIO_NR(1, 18) , 0);
401         else if (board_type == BOARD_IS_MARSBOARD)
402                 gpio_direction_output(IMX_GPIO_NR(2, 10) , 0);
403
404         clrbits_le32(&iomux->gpr[2],
405                      IOMUXC_GPR2_LVDS_CH0_MODE_MASK);
406 }
407
408 static void do_enable_hdmi(struct display_info_t const *dev)
409 {
410         disable_lvds(dev);
411         imx_enable_hdmi_phy();
412 }
413
414 static int detect_i2c(struct display_info_t const *dev)
415 {
416         return (0 == i2c_set_bus_num(dev->bus)) &&
417                 (0 == i2c_probe(dev->addr));
418 }
419
420 struct display_info_t const displays[] = {{
421         .bus    = -1,
422         .addr   = 0,
423         .pixfmt = IPU_PIX_FMT_RGB24,
424         .detect = detect_hdmi,
425         .enable = do_enable_hdmi,
426         .mode   = {
427                 .name           = "HDMI",
428                 .refresh        = 60,
429                 .xres           = 1024,
430                 .yres           = 768,
431                 .pixclock       = 15385,
432                 .left_margin    = 220,
433                 .right_margin   = 40,
434                 .upper_margin   = 21,
435                 .lower_margin   = 7,
436                 .hsync_len      = 60,
437                 .vsync_len      = 10,
438                 .sync           = FB_SYNC_EXT,
439                 .vmode          = FB_VMODE_NONINTERLACED
440 } }, {
441         .bus    = 2,
442         .addr   = 0x1,
443         .pixfmt = IPU_PIX_FMT_LVDS666,
444         .detect = detect_i2c,
445         .enable = enable_lvds,
446         .mode   = {
447                 .name           = "LCD8000-97C",
448                 .refresh        = 60,
449                 .xres           = 1024,
450                 .yres           = 768,
451                 .pixclock       = 15385,
452                 .left_margin    = 100,
453                 .right_margin   = 200,
454                 .upper_margin   = 10,
455                 .lower_margin   = 20,
456                 .hsync_len      = 20,
457                 .vsync_len      = 8,
458                 .sync           = FB_SYNC_EXT,
459                 .vmode          = FB_VMODE_NONINTERLACED
460 } } };
461 size_t display_count = ARRAY_SIZE(displays);
462
463 static void setup_display(void)
464 {
465         struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
466         struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
467         int reg;
468
469         enable_ipu_clock();
470         imx_setup_hdmi();
471
472         /* Turn on LDB0, IPU,IPU DI0 clocks */
473         setbits_le32(&mxc_ccm->CCGR3,
474                      MXC_CCM_CCGR3_LDB_DI0_MASK);
475
476         /* set LDB0 clk select to 011/011 */
477         clrsetbits_le32(&mxc_ccm->cs2cdr,
478                         MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK,
479                         (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET));
480
481         setbits_le32(&mxc_ccm->cscmr2,
482                      MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV);
483
484         setbits_le32(&mxc_ccm->chsccdr,
485                      (CHSCCDR_CLK_SEL_LDB_DI0
486                      << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET));
487
488         reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
489              | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
490              | IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
491              | IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
492              | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
493              | IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
494              | IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED
495              | IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
496         writel(reg, &iomux->gpr[2]);
497
498         clrsetbits_le32(&iomux->gpr[3],
499                         IOMUXC_GPR3_LVDS0_MUX_CTL_MASK |
500                         IOMUXC_GPR3_HDMI_MUX_CTL_MASK,
501                         IOMUXC_GPR3_MUX_SRC_IPU1_DI0
502                         << IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
503 }
504 #endif /* CONFIG_VIDEO_IPUV3 */
505
506 /*
507  * Do not overwrite the console
508  * Use always serial for U-Boot console
509  */
510 int overwrite_console(void)
511 {
512         return 1;
513 }
514
515 int board_eth_init(bd_t *bis)
516 {
517         setup_iomux_enet();
518
519         return cpu_eth_init(bis);
520 }
521
522 int board_early_init_f(void)
523 {
524         u32 cputype = cpu_type(get_cpu_rev());
525
526         switch (cputype) {
527         case MXC_CPU_MX6SOLO:
528                 board_type = BOARD_IS_RIOTBOARD;
529                 break;
530         case MXC_CPU_MX6D:
531                 board_type = BOARD_IS_MARSBOARD;
532                 break;
533         }
534
535         setup_iomux_uart();
536
537         if (board_type == BOARD_IS_RIOTBOARD)
538                 imx_iomux_v3_setup_multiple_pads(
539                         tft_pads_riot, ARRAY_SIZE(tft_pads_riot));
540         else if (board_type == BOARD_IS_MARSBOARD)
541                 imx_iomux_v3_setup_multiple_pads(
542                         tft_pads_mars, ARRAY_SIZE(tft_pads_mars));
543 #if defined(CONFIG_VIDEO_IPUV3)
544         /* power ON LCD */
545         gpio_direction_output(IMX_GPIO_NR(1, 29) , 1);
546         /* touch interrupt is an input */
547         gpio_direction_input(IMX_GPIO_NR(6, 14));
548         /* power ON backlight */
549         gpio_direction_output(IMX_GPIO_NR(6, 15) , 1);
550         /* set backlight level to off */
551         if (board_type == BOARD_IS_RIOTBOARD)
552                 gpio_direction_output(IMX_GPIO_NR(1, 18) , 0);
553         else if (board_type == BOARD_IS_MARSBOARD)
554                 gpio_direction_output(IMX_GPIO_NR(2, 10) , 0);
555         setup_display();
556 #endif
557
558         return 0;
559 }
560
561 int board_init(void)
562 {
563         /* address of boot parameters */
564         gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
565         /* i2c1 : PMIC, Audio codec on RiOT, Expansion connector on MarS */
566         setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
567         /* i2c2 : HDMI EDID */
568         setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
569         /* i2c3 : LVDS, Expansion connector */
570         setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info3);
571 #ifdef CONFIG_MXC_SPI
572         setup_spi();
573 #endif
574         return 0;
575 }
576
577 #ifdef CONFIG_CMD_BMODE
578 static const struct boot_mode riotboard_boot_modes[] = {
579         {"sd2",  MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
580         {"sd3",  MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
581         {"emmc", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)},
582         {NULL,   0},
583 };
584 static const struct boot_mode marsboard_boot_modes[] = {
585         {"sd2",  MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
586         {"emmc", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
587         {NULL,   0},
588 };
589 #endif
590
591 int board_late_init(void)
592 {
593 #ifdef CONFIG_CMD_BMODE
594         if (board_type == BOARD_IS_RIOTBOARD)
595                 add_board_boot_modes(riotboard_boot_modes);
596         else if (board_type == BOARD_IS_RIOTBOARD)
597                 add_board_boot_modes(marsboard_boot_modes);
598 #endif
599
600         return 0;
601 }
602
603 int checkboard(void)
604 {
605         puts("Board: ");
606         if (board_type == BOARD_IS_MARSBOARD)
607                 puts("MarSBoard\n");
608         else if (board_type == BOARD_IS_RIOTBOARD)
609                 puts("RIoTboard\n");
610         else
611                 printf("unknown - cputype : %02x\n", cpu_type(get_cpu_rev()));
612
613         return 0;
614 }
615
616 #ifdef CONFIG_SPL_BUILD
617 #include <spl.h>
618
619 void board_init_f(ulong dummy)
620 {
621         u32 cputype = cpu_type(get_cpu_rev());
622
623         switch (cputype) {
624         case MXC_CPU_MX6SOLO:
625                 board_type = BOARD_IS_RIOTBOARD;
626                 break;
627         case MXC_CPU_MX6D:
628                 board_type = BOARD_IS_MARSBOARD;
629                 break;
630         }
631         arch_cpu_init();
632
633         /* setup GP timer */
634         timer_init();
635
636 #ifdef CONFIG_SPL_SERIAL_SUPPORT
637         setup_iomux_uart();
638         preloader_console_init();
639 #endif
640 }
641
642 void board_boot_order(u32 *spl_boot_list)
643 {
644         spl_boot_list[0] = BOOT_DEVICE_MMC1;
645 }
646
647 /*
648  * In order to jump to standard u-boot shell, you have to connect pin 5 of J13
649  * to pin 3 (ground).
650  */
651 int spl_start_uboot(void)
652 {
653         int gpio_key = IMX_GPIO_NR(4, 16);
654
655         gpio_direction_input(gpio_key);
656         if (gpio_get_value(gpio_key) == 0)
657                 return 1;
658         else
659                 return 0;
660 }
661
662 #endif