blob: b296ea25226e399818900e94833291a1ba8bdbd0 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Heiko Schocherf853c6c2014-07-18 06:07:22 +02002/*
3 * (C) Copyright 2014
4 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
5 *
6 * Based on:
7 * Copyright (C) 2012 Freescale Semiconductor, Inc.
8 *
9 * Author: Fabio Estevam <fabio.estevam@freescale.com>
Heiko Schocherf853c6c2014-07-18 06:07:22 +020010 */
11
12#include <asm/arch/clock.h>
13#include <asm/arch/imx-regs.h>
14#include <asm/arch/iomux.h>
15#include <asm/arch/mx6-pins.h>
Masahiro Yamada56a931c2016-09-21 11:28:55 +090016#include <linux/errno.h>
Heiko Schocherf853c6c2014-07-18 06:07:22 +020017#include <asm/gpio.h>
Stefano Babic33731bc2017-06-29 10:16:06 +020018#include <asm/mach-imx/iomux-v3.h>
19#include <asm/mach-imx/boot_mode.h>
20#include <asm/mach-imx/mxc_i2c.h>
21#include <asm/mach-imx/video.h>
Heiko Schocherf853c6c2014-07-18 06:07:22 +020022#include <mmc.h>
Yangbo Lu73340382019-06-21 11:42:28 +080023#include <fsl_esdhc_imx.h>
Heiko Schocherf853c6c2014-07-18 06:07:22 +020024#include <miiphy.h>
25#include <netdev.h>
26#include <asm/arch/mxc_hdmi.h>
27#include <asm/arch/crm_regs.h>
28#include <linux/fb.h>
29#include <ipu_pixfmt.h>
Diego Dorta2661c9c2017-09-22 12:12:18 -030030#include <input.h>
Heiko Schocherf853c6c2014-07-18 06:07:22 +020031#include <asm/io.h>
32#include <asm/arch/sys_proto.h>
33#include <pwm.h>
Heiko Schocher54333792019-12-01 11:23:12 +010034#include <dm/root.h>
Heiko Schochera051ee92019-12-01 11:23:11 +010035#include <env.h>
36#include <micrel.h>
37#include <spi.h>
38#include <video.h>
39#include <../drivers/video/imx/ipu.h>
40#if defined(CONFIG_VIDEO_BMP_LOGO)
41 #include <bmp_logo.h>
42#endif
Heiko Schocherf853c6c2014-07-18 06:07:22 +020043
44DECLARE_GLOBAL_DATA_PTR;
45
46#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
47 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
48 PAD_CTL_SRE_FAST | PAD_CTL_HYS)
49
50#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \
51 PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \
52 PAD_CTL_SRE_FAST | PAD_CTL_HYS)
53
54#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
55 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
56
57#define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \
58 PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
59
60#define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
61 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
62 PAD_CTL_ODE | PAD_CTL_SRE_FAST)
63
64#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
65
66#define DISP_PAD_CTRL (0x10)
67
68#define ECSPI4_CS1 IMX_GPIO_NR(5, 2)
69
Heiko Schochera051ee92019-12-01 11:23:11 +010070#define USDHC2_PAD_CTRL (PAD_CTL_SPEED_LOW | \
71 PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
72
73#if (CONFIG_SYS_BOARD_VERSION == 2)
74 /* 4.3 display controller */
75 #define ECSPI1_CS0 IMX_GPIO_NR(4, 9)
76 #define ECSPI4_CS0 IMX_GPIO_NR(3, 29)
77#elif (CONFIG_SYS_BOARD_VERSION == 3)
78 #define ECSPI1_CS0 IMX_GPIO_NR(2, 30) /* NOR flash */
79 /* 4.3 display controller */
80 #define ECSPI1_CS1 IMX_GPIO_NR(4, 10)
81#endif
82
83#define SOFT_RESET_GPIO IMX_GPIO_NR(7, 13)
84#define SD2_DRIVER_ENABLE IMX_GPIO_NR(7, 8)
85
Heiko Schocher54333792019-12-01 11:23:12 +010086enum {
87 BOARD_TYPE_4 = 4,
88 BOARD_TYPE_7 = 7,
89};
90
91#define ARI_BT_4 "aristainetos2_4@2"
92#define ARI_BT_7 "aristainetos2_7@1"
93
Heiko Schochera051ee92019-12-01 11:23:11 +010094struct i2c_pads_info i2c_pad_info3 = {
95 .scl = {
96 .i2c_mode = MX6_PAD_GPIO_5__I2C3_SCL | PC,
97 .gpio_mode = MX6_PAD_GPIO_5__GPIO1_IO05 | PC,
98 .gp = IMX_GPIO_NR(1, 5)
99 },
100 .sda = {
101 .i2c_mode = MX6_PAD_GPIO_6__I2C3_SDA | PC,
102 .gpio_mode = MX6_PAD_GPIO_6__GPIO1_IO06 | PC,
103 .gp = IMX_GPIO_NR(1, 6)
104 }
105};
106
107struct i2c_pads_info i2c_pad_info4 = {
108 .scl = {
109 .i2c_mode = MX6_PAD_GPIO_7__I2C4_SCL | PC,
110 .gpio_mode = MX6_PAD_GPIO_7__GPIO1_IO07 | PC,
111 .gp = IMX_GPIO_NR(1, 7)
112 },
113 .sda = {
114 .i2c_mode = MX6_PAD_GPIO_8__I2C4_SDA | PC,
115 .gpio_mode = MX6_PAD_GPIO_8__GPIO1_IO08 | PC,
116 .gp = IMX_GPIO_NR(1, 8)
117 }
118};
119
120iomux_v3_cfg_t const uart1_pads[] = {
121 MX6_PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
122 MX6_PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
123 MX6_PAD_EIM_D19__UART1_CTS_B | MUX_PAD_CTRL(UART_PAD_CTRL),
124 MX6_PAD_EIM_D20__UART1_RTS_B | MUX_PAD_CTRL(UART_PAD_CTRL),
125};
126
127iomux_v3_cfg_t const uart2_pads[] = {
128 MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
129 MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
130};
131
132iomux_v3_cfg_t const uart3_pads[] = {
133 MX6_PAD_EIM_D24__UART3_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
134 MX6_PAD_EIM_D25__UART3_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
135 MX6_PAD_EIM_D31__UART3_RTS_B | MUX_PAD_CTRL(UART_PAD_CTRL),
136 MX6_PAD_EIM_D23__UART3_CTS_B | MUX_PAD_CTRL(UART_PAD_CTRL),
137};
138
139iomux_v3_cfg_t const uart4_pads[] = {
140 MX6_PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
141 MX6_PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
142};
143
144iomux_v3_cfg_t const gpio_pads[] = {
145 /* LED enable*/
146 MX6_PAD_ENET_CRS_DV__GPIO1_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL),
147 /* LED yellow */
148 MX6_PAD_NANDF_CS3__GPIO6_IO16 | MUX_PAD_CTRL(NO_PAD_CTRL),
149 /* LED red */
150#if (CONFIG_SYS_BOARD_VERSION == 2)
151 MX6_PAD_EIM_EB0__GPIO2_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL),
152#elif (CONFIG_SYS_BOARD_VERSION == 3)
153 MX6_PAD_EIM_WAIT__GPIO5_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL),
154#endif
155 /* LED green */
156 MX6_PAD_EIM_A24__GPIO5_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL),
157 /* LED blue */
158 MX6_PAD_EIM_EB1__GPIO2_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
159 /* spi flash WP protect */
160 MX6_PAD_SD4_DAT7__GPIO2_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
161 /* spi CS 0 */
162 MX6_PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
163 /* spi bus #2 SS driver enable */
164 MX6_PAD_EIM_A23__GPIO6_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
165 /* RST_LOC# PHY reset input (has pull-down!)*/
166 MX6_PAD_GPIO_18__GPIO7_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL),
167 /* SD 2 level shifter output enable */
168 MX6_PAD_SD3_RST__GPIO7_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
169 /* SD1 card detect input */
170 MX6_PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
171 /* SD1 write protect input */
172 MX6_PAD_DI0_PIN4__GPIO4_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
173 /* SD2 card detect input */
174 MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
175 /* SD2 write protect input */
176 MX6_PAD_SD4_DAT2__GPIO2_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
177 /* Touchscreen IRQ */
178 MX6_PAD_SD4_DAT1__GPIO2_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),
179};
180
181static iomux_v3_cfg_t const misc_pads[] = {
182 /* USB_OTG_ID = GPIO1_24*/
183 MX6_PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
184 /* H1 Power enable = GPIO1_0*/
185 MX6_PAD_GPIO_0__USB_H1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
186 /* OTG Power enable = GPIO4_15*/
187 MX6_PAD_KEY_ROW4__USB_OTG_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
188};
189
190iomux_v3_cfg_t const enet_pads[] = {
191 MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
192 MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
193 MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
194 MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
195 MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
196 MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
197 MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
198 MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
199 MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
200 MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
201 MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
202 MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
203 MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
204 MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
205 MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
206};
207
208static iomux_v3_cfg_t const backlight_pads[] = {
209 /* backlight PWM brightness control */
210 MX6_PAD_GPIO_9__PWM1_OUT | MUX_PAD_CTRL(NO_PAD_CTRL),
211 /* backlight enable */
212 MX6_PAD_EIM_BCLK__GPIO6_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL),
213 /* LCD power enable */
214 MX6_PAD_NANDF_CS2__GPIO6_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
215};
216
217static iomux_v3_cfg_t const ecspi1_pads[] = {
218 MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
219 MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
220 MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
221#if (CONFIG_SYS_BOARD_VERSION == 2)
222 MX6_PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(SPI_PAD_CTRL),
223#elif (CONFIG_SYS_BOARD_VERSION == 3)
224 MX6_PAD_EIM_EB2__GPIO2_IO30 | MUX_PAD_CTRL(SPI_PAD_CTRL),
225 MX6_PAD_KEY_COL2__GPIO4_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
226#endif
227};
228
229static void setup_iomux_enet(void)
230{
231 imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
232}
233
234#if (CONFIG_SYS_BOARD_VERSION == 2)
235iomux_v3_cfg_t const ecspi4_pads[] = {
236 MX6_PAD_EIM_D21__ECSPI4_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL),
237 MX6_PAD_EIM_D22__ECSPI4_MISO | MUX_PAD_CTRL(NO_PAD_CTRL),
238 MX6_PAD_EIM_D28__ECSPI4_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL),
239 MX6_PAD_EIM_A25__GPIO5_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL),
240 MX6_PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
241};
242#endif
243
244static iomux_v3_cfg_t const display_pads[] = {
245 MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK | MUX_PAD_CTRL(DISP_PAD_CTRL),
246 MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15,
247 MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02,
248 MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03,
249 MX6_PAD_DISP0_DAT0__IPU1_DISP0_DATA00,
250 MX6_PAD_DISP0_DAT1__IPU1_DISP0_DATA01,
251 MX6_PAD_DISP0_DAT2__IPU1_DISP0_DATA02,
252 MX6_PAD_DISP0_DAT3__IPU1_DISP0_DATA03,
253 MX6_PAD_DISP0_DAT4__IPU1_DISP0_DATA04,
254 MX6_PAD_DISP0_DAT5__IPU1_DISP0_DATA05,
255 MX6_PAD_DISP0_DAT6__IPU1_DISP0_DATA06,
256 MX6_PAD_DISP0_DAT7__IPU1_DISP0_DATA07,
257 MX6_PAD_DISP0_DAT8__IPU1_DISP0_DATA08,
258 MX6_PAD_DISP0_DAT9__IPU1_DISP0_DATA09,
259 MX6_PAD_DISP0_DAT10__IPU1_DISP0_DATA10,
260 MX6_PAD_DISP0_DAT11__IPU1_DISP0_DATA11,
261 MX6_PAD_DISP0_DAT12__IPU1_DISP0_DATA12,
262 MX6_PAD_DISP0_DAT13__IPU1_DISP0_DATA13,
263 MX6_PAD_DISP0_DAT14__IPU1_DISP0_DATA14,
264 MX6_PAD_DISP0_DAT15__IPU1_DISP0_DATA15,
265 MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16,
266 MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17,
267 MX6_PAD_DISP0_DAT18__IPU1_DISP0_DATA18,
268 MX6_PAD_DISP0_DAT19__IPU1_DISP0_DATA19,
269 MX6_PAD_DISP0_DAT20__IPU1_DISP0_DATA20,
270 MX6_PAD_DISP0_DAT21__IPU1_DISP0_DATA21,
271 MX6_PAD_DISP0_DAT22__IPU1_DISP0_DATA22,
272 MX6_PAD_DISP0_DAT23__IPU1_DISP0_DATA23,
273};
274
275int board_spi_cs_gpio(unsigned int bus, unsigned int cs)
276{
277 if (bus == CONFIG_SF_DEFAULT_BUS && cs == CONFIG_SF_DEFAULT_CS)
278#if (CONFIG_SYS_BOARD_VERSION == 2)
279 return IMX_GPIO_NR(5, 2);
280
281 if (bus == 0 && cs == 0)
282 return IMX_GPIO_NR(4, 9);
283#elif (CONFIG_SYS_BOARD_VERSION == 3)
284 return ECSPI1_CS0;
285
286 if (bus == 0 && cs == 1)
287 return ECSPI1_CS1;
Heiko Schocher05729822015-05-18 13:32:31 +0200288#endif
Heiko Schochera051ee92019-12-01 11:23:11 +0100289 return -1;
290}
291
292static void setup_spi(void)
293{
294 int i;
295
296 imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads));
297
298#if (CONFIG_SYS_BOARD_VERSION == 2)
299 imx_iomux_v3_setup_multiple_pads(ecspi4_pads, ARRAY_SIZE(ecspi4_pads));
300#endif
301
302 for (i = 0; i < 4; i++)
303 enable_spi_clk(true, i);
304
305 gpio_direction_output(ECSPI1_CS0, 1);
306#if (CONFIG_SYS_BOARD_VERSION == 2)
307 gpio_direction_output(ECSPI4_CS1, 0);
308 /* set cs0 to high (second device on spi bus #4) */
309 gpio_direction_output(ECSPI4_CS0, 1);
310#elif (CONFIG_SYS_BOARD_VERSION == 3)
311 gpio_direction_output(ECSPI1_CS1, 1);
312#endif
313}
314
315static void setup_iomux_uart(void)
316{
317 switch (CONFIG_MXC_UART_BASE) {
318 case UART1_BASE:
319 imx_iomux_v3_setup_multiple_pads(uart1_pads,
320 ARRAY_SIZE(uart1_pads));
321 break;
322 case UART2_BASE:
323 imx_iomux_v3_setup_multiple_pads(uart2_pads,
324 ARRAY_SIZE(uart2_pads));
325 break;
326 case UART3_BASE:
327 imx_iomux_v3_setup_multiple_pads(uart3_pads,
328 ARRAY_SIZE(uart3_pads));
329 break;
330 case UART4_BASE:
331 imx_iomux_v3_setup_multiple_pads(uart4_pads,
332 ARRAY_SIZE(uart4_pads));
333 break;
334 }
335}
336
337int board_phy_config(struct phy_device *phydev)
338{
339 /* control data pad skew - devaddr = 0x02, register = 0x04 */
340 ksz9031_phy_extended_write(phydev, 0x02,
341 MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW,
342 MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
343 /* rx data pad skew - devaddr = 0x02, register = 0x05 */
344 ksz9031_phy_extended_write(phydev, 0x02,
345 MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW,
346 MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
347 /* tx data pad skew - devaddr = 0x02, register = 0x06 */
348 ksz9031_phy_extended_write(phydev, 0x02,
349 MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW,
350 MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
351 /* gtx and rx clock pad skew - devaddr = 0x02, register = 0x08 */
352 ksz9031_phy_extended_write(phydev, 0x02,
353 MII_KSZ9031_EXT_RGMII_CLOCK_SKEW,
354 MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x03FF);
355
356 if (phydev->drv->config)
357 phydev->drv->config(phydev);
358
359 return 0;
360}
361
362int board_eth_init(bd_t *bis)
363{
364 setup_iomux_enet();
365 return cpu_eth_init(bis);
366}
367
368static int rotate_logo_one(unsigned char *out, unsigned char *in)
369{
370 int i, j;
371
372 for (i = 0; i < BMP_LOGO_WIDTH; i++)
373 for (j = 0; j < BMP_LOGO_HEIGHT; j++)
374 out[j * BMP_LOGO_WIDTH + BMP_LOGO_HEIGHT - 1 - i] =
375 in[i * BMP_LOGO_WIDTH + j];
376 return 0;
377}
378
379/*
380 * Rotate the BMP_LOGO (only)
381 * Will only work, if the logo is square, as
382 * BMP_LOGO_HEIGHT and BMP_LOGO_WIDTH are defines, not variables
383 */
384void rotate_logo(int rotations)
385{
386 unsigned char out_logo[BMP_LOGO_WIDTH * BMP_LOGO_HEIGHT];
387 unsigned char *in_logo;
388 int i, j;
389
390 if (BMP_LOGO_WIDTH != BMP_LOGO_HEIGHT)
391 return;
392
393 in_logo = bmp_logo_bitmap;
394
395 /* one 90 degree rotation */
396 if (rotations == 1 || rotations == 2 || rotations == 3)
397 rotate_logo_one(out_logo, in_logo);
398
399 /* second 90 degree rotation */
400 if (rotations == 2 || rotations == 3)
401 rotate_logo_one(in_logo, out_logo);
402
403 /* third 90 degree rotation */
404 if (rotations == 3)
405 rotate_logo_one(out_logo, in_logo);
406
407 /* copy result back to original array */
408 if (rotations == 1 || rotations == 3)
409 for (i = 0; i < BMP_LOGO_WIDTH; i++)
410 for (j = 0; j < BMP_LOGO_HEIGHT; j++)
411 in_logo[i * BMP_LOGO_WIDTH + j] =
412 out_logo[i * BMP_LOGO_WIDTH + j];
413}
414
415static void enable_display_power(void)
416{
417 imx_iomux_v3_setup_multiple_pads(backlight_pads,
418 ARRAY_SIZE(backlight_pads));
419
420 /* backlight enable */
421 gpio_direction_output(IMX_GPIO_NR(6, 31), 1);
422 /* LCD power enable */
423 gpio_direction_output(IMX_GPIO_NR(6, 15), 1);
424
425 /* enable backlight PWM 1 */
426 if (pwm_init(0, 0, 0))
427 goto error;
428 /* duty cycle 500ns, period: 3000ns */
429 if (pwm_config(0, 50000, 300000))
430 goto error;
431 if (pwm_enable(0))
432 goto error;
433 return;
434
435error:
436 puts("error init pwm for backlight\n");
437}
438
439static void enable_lvds(struct display_info_t const *dev)
440{
441 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
442 struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
443 int reg;
444 s32 timeout = 100000;
445
446 /* set PLL5 clock */
447 reg = readl(&ccm->analog_pll_video);
448 reg |= BM_ANADIG_PLL_VIDEO_POWERDOWN;
449 writel(reg, &ccm->analog_pll_video);
450
451 /* set PLL5 to 232720000Hz */
452 reg &= ~BM_ANADIG_PLL_VIDEO_DIV_SELECT;
453 reg |= BF_ANADIG_PLL_VIDEO_DIV_SELECT(0x26);
454 reg &= ~BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT;
455 reg |= BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(0);
456 writel(reg, &ccm->analog_pll_video);
457
458 writel(BF_ANADIG_PLL_VIDEO_NUM_A(0xC0238),
459 &ccm->analog_pll_video_num);
460 writel(BF_ANADIG_PLL_VIDEO_DENOM_B(0xF4240),
461 &ccm->analog_pll_video_denom);
462
463 reg &= ~BM_ANADIG_PLL_VIDEO_POWERDOWN;
464 writel(reg, &ccm->analog_pll_video);
465
466 while (timeout--)
467 if (readl(&ccm->analog_pll_video) & BM_ANADIG_PLL_VIDEO_LOCK)
468 break;
469 if (timeout < 0)
470 printf("Warning: video pll lock timeout!\n");
471
472 reg = readl(&ccm->analog_pll_video);
473 reg |= BM_ANADIG_PLL_VIDEO_ENABLE;
474 reg &= ~BM_ANADIG_PLL_VIDEO_BYPASS;
475 writel(reg, &ccm->analog_pll_video);
476
477 /* set LDB0, LDB1 clk select to 000/000 (PLL5 clock) */
478 reg = readl(&ccm->cs2cdr);
479 reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
480 | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
481 reg |= (0 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
482 | (0 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
483 writel(reg, &ccm->cs2cdr);
484
485 reg = readl(&ccm->cscmr2);
486 reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
487 writel(reg, &ccm->cscmr2);
488
489 reg = readl(&ccm->chsccdr);
490 reg |= (CHSCCDR_CLK_SEL_LDB_DI0
491 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
492 writel(reg, &ccm->chsccdr);
493
494 reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
495 | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
496 | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_HIGH
497 | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
498 | IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT
499 | IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED
500 | IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
501 writel(reg, &iomux->gpr[2]);
502
503 reg = readl(&iomux->gpr[3]);
504 reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)
505 | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
506 << IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
507 writel(reg, &iomux->gpr[3]);
508}
509
510static void enable_spi_display(struct display_info_t const *dev)
511{
512 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
513 struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
514 int reg;
515 s32 timeout = 100000;
516
517#if defined(CONFIG_VIDEO_BMP_LOGO)
518 rotate_logo(3); /* portrait display in landscape mode */
519#endif
520
521 /*
522 * set ldb clock to 28341000 Hz calculated through the formula:
523 * (XRES + LEFT_M + RIGHT_M + HSYNC_LEN) *
524 * (YRES + UPPER_M + LOWER_M + VSYNC_LEN) * REFRESH)
525 * see:
526 * https://community.freescale.com/thread/308170
527 */
528 ipu_set_ldb_clock(28341000);
529
530 reg = readl(&ccm->cs2cdr);
531
532 /* select pll 5 clock */
533 reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
534 | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
535 writel(reg, &ccm->cs2cdr);
536
537 /* set PLL5 to 197994996Hz */
538 reg &= ~BM_ANADIG_PLL_VIDEO_DIV_SELECT;
539 reg |= BF_ANADIG_PLL_VIDEO_DIV_SELECT(0x21);
540 reg &= ~BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT;
541 reg |= BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(0);
542 writel(reg, &ccm->analog_pll_video);
543
544 writel(BF_ANADIG_PLL_VIDEO_NUM_A(0xfbf4),
545 &ccm->analog_pll_video_num);
546 writel(BF_ANADIG_PLL_VIDEO_DENOM_B(0xf4240),
547 &ccm->analog_pll_video_denom);
548
549 reg &= ~BM_ANADIG_PLL_VIDEO_POWERDOWN;
550 writel(reg, &ccm->analog_pll_video);
551
552 while (timeout--)
553 if (readl(&ccm->analog_pll_video) & BM_ANADIG_PLL_VIDEO_LOCK)
554 break;
555 if (timeout < 0)
556 printf("Warning: video pll lock timeout!\n");
557
558 reg = readl(&ccm->analog_pll_video);
559 reg |= BM_ANADIG_PLL_VIDEO_ENABLE;
560 reg &= ~BM_ANADIG_PLL_VIDEO_BYPASS;
561 writel(reg, &ccm->analog_pll_video);
562
563 /* set LDB0, LDB1 clk select to 000/000 (PLL5 clock) */
564 reg = readl(&ccm->cs2cdr);
565 reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
566 | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
567 reg |= (0 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
568 | (0 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
569 writel(reg, &ccm->cs2cdr);
570
571 reg = readl(&ccm->cscmr2);
572 reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
573 writel(reg, &ccm->cscmr2);
574
575 reg = readl(&ccm->chsccdr);
576 reg |= (CHSCCDR_CLK_SEL_LDB_DI0
577 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
578 reg &= ~MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK;
579 reg |= (2 << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET);
580 reg &= ~MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK;
581 reg |= (2 << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
582 writel(reg, &ccm->chsccdr);
583
584 reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
585 | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
586 | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_HIGH
587 | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
588 | IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT
589 | IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED
590 | IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
591 writel(reg, &iomux->gpr[2]);
592
593 reg = readl(&iomux->gpr[3]);
594 reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)
595 | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
596 << IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
597 writel(reg, &iomux->gpr[3]);
598
599 imx_iomux_v3_setup_multiple_pads(display_pads,
600 ARRAY_SIZE(display_pads));
601}
602
603static void setup_display(void)
604{
605 enable_ipu_clock();
606 enable_display_power();
607}
608
609static void setup_iomux_gpio(void)
610{
611 imx_iomux_v3_setup_multiple_pads(gpio_pads, ARRAY_SIZE(gpio_pads));
612}
613
614static void set_gpr_register(void)
615{
616 struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
617
618 writel(IOMUXC_GPR1_APP_CLK_REQ_N | IOMUXC_GPR1_PCIE_RDY_L23 |
619 IOMUXC_GPR1_EXC_MON_SLVE |
620 (2 << IOMUXC_GPR1_ADDRS0_OFFSET) |
621 IOMUXC_GPR1_ACT_CS0,
622 &iomuxc_regs->gpr[1]);
623 writel(0x0, &iomuxc_regs->gpr[8]);
624 writel(IOMUXC_GPR12_ARMP_IPG_CLK_EN | IOMUXC_GPR12_ARMP_AHB_CLK_EN |
625 IOMUXC_GPR12_ARMP_ATB_CLK_EN | IOMUXC_GPR12_ARMP_APB_CLK_EN,
626 &iomuxc_regs->gpr[12]);
627}
628
Heiko Schocher54333792019-12-01 11:23:12 +0100629extern char __bss_start[], __bss_end[];
Heiko Schochera051ee92019-12-01 11:23:11 +0100630int board_early_init_f(void)
631{
632 setup_iomux_uart();
633 setup_iomux_gpio();
634
635 gpio_direction_output(SOFT_RESET_GPIO, 1);
636 gpio_direction_output(SD2_DRIVER_ENABLE, 1);
637 setup_display();
638 set_gpr_register();
Heiko Schocher54333792019-12-01 11:23:12 +0100639
640 /*
641 * clear bss here, so we can use spi driver
642 * before relocation and read Environment
643 * from spi flash.
644 */
645 memset(__bss_start, 0x00, __bss_end - __bss_start);
646
Heiko Schochera051ee92019-12-01 11:23:11 +0100647 return 0;
648}
649
650static void setup_i2c4(void)
651{
652 setup_i2c(3, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE,
653 &i2c_pad_info4);
654}
655
656static void setup_board_gpio(void)
657{
658 /* enable all LEDs */
659 gpio_request(IMX_GPIO_NR(2, 13), "LED ena"); /* 25 */
660 gpio_direction_output(IMX_GPIO_NR(1, 25), 0);
661
662 /* switch off Status LEDs */
663#if (CONFIG_SYS_BOARD_VERSION == 2)
664 gpio_request(IMX_GPIO_NR(6, 16), "LED yellow"); /* 176 */
665 gpio_direction_output(IMX_GPIO_NR(6, 16), 1);
666 gpio_request(IMX_GPIO_NR(2, 28), "LED red"); /* 60 */
667 gpio_direction_output(IMX_GPIO_NR(2, 28), 1);
668 gpio_request(IMX_GPIO_NR(5, 4), "LED green"); /* 132 */
669 gpio_direction_output(IMX_GPIO_NR(5, 4), 1);
670 gpio_request(IMX_GPIO_NR(2, 29), "LED blue"); /* 61 */
671 gpio_direction_output(IMX_GPIO_NR(2, 29), 1);
672#elif (CONFIG_SYS_BOARD_VERSION == 3)
673 gpio_request(IMX_GPIO_NR(6, 16), "LED yellow"); /* 176 */
674 gpio_direction_output(IMX_GPIO_NR(6, 16), 0);
675 gpio_request(IMX_GPIO_NR(5, 0), "LED red"); /* 128 */
676 gpio_direction_output(IMX_GPIO_NR(5, 0), 0);
677 gpio_request(IMX_GPIO_NR(5, 4), "LED green"); /* 132 */
678 gpio_direction_output(IMX_GPIO_NR(5, 4), 0);
679 gpio_request(IMX_GPIO_NR(2, 29), "LED blue"); /* 61 */
680 gpio_direction_output(IMX_GPIO_NR(2, 29), 0);
681#endif
682}
683
684static void setup_board_spi(void)
685{
686 /* enable spi bus #2 SS drivers (and spi bus #4 SS1 for rev2b) */
687 gpio_direction_output(IMX_GPIO_NR(6, 6), 1);
688}
689
690int board_late_init(void)
691{
692 char *my_bootdelay;
693 char bootmode = 0;
694 char const *panel = env_get("panel");
695
696 /*
697 * Check the boot-source. If booting from NOR Flash,
698 * disable bootdelay
699 */
700 gpio_request(IMX_GPIO_NR(7, 6), "bootsel0");
701 gpio_direction_input(IMX_GPIO_NR(7, 6));
702 gpio_request(IMX_GPIO_NR(7, 7), "bootsel1");
703 gpio_direction_input(IMX_GPIO_NR(7, 7));
704 gpio_request(IMX_GPIO_NR(7, 1), "bootsel2");
705 gpio_direction_input(IMX_GPIO_NR(7, 1));
706 bootmode |= (gpio_get_value(IMX_GPIO_NR(7, 6)) ? 1 : 0) << 0;
707 bootmode |= (gpio_get_value(IMX_GPIO_NR(7, 7)) ? 1 : 0) << 1;
708 bootmode |= (gpio_get_value(IMX_GPIO_NR(7, 1)) ? 1 : 0) << 2;
709
710 if (bootmode == 7) {
711 my_bootdelay = env_get("nor_bootdelay");
712 if (my_bootdelay != NULL)
713 env_set("bootdelay", my_bootdelay);
714 else
715 env_set("bootdelay", "-2");
716 }
717
718 /* if we have the lg panel, we can initialze it now */
719 if (panel)
720 if (!strcmp(panel, displays[1].mode.name))
721 lg4573_spi_startup(CONFIG_LG4573_BUS,
722 CONFIG_LG4573_CS,
723 10000000, SPI_MODE_0);
Heiko Schocher05729822015-05-18 13:32:31 +0200724
Heiko Schocher54333792019-12-01 11:23:12 +0100725 /* set board_type */
726 if (gd->board_type == BOARD_TYPE_4)
727 env_set("board_type", ARI_BT_4);
728 else
729 env_set("board_type", ARI_BT_7);
730
Heiko Schochera051ee92019-12-01 11:23:11 +0100731 return 0;
732}
Heiko Schocher05729822015-05-18 13:32:31 +0200733
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200734struct i2c_pads_info i2c_pad_info1 = {
735 .scl = {
736 .i2c_mode = MX6_PAD_CSI0_DAT9__I2C1_SCL | PC,
737 .gpio_mode = MX6_PAD_CSI0_DAT9__GPIO5_IO27 | PC,
738 .gp = IMX_GPIO_NR(5, 27)
739 },
740 .sda = {
741 .i2c_mode = MX6_PAD_CSI0_DAT8__I2C1_SDA | PC,
742 .gpio_mode = MX6_PAD_CSI0_DAT8__GPIO5_IO26 | PC,
743 .gp = IMX_GPIO_NR(5, 26)
744 }
745};
746
747struct i2c_pads_info i2c_pad_info2 = {
748 .scl = {
749 .i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL | PC,
750 .gpio_mode = MX6_PAD_KEY_COL3__GPIO4_IO12 | PC,
751 .gp = IMX_GPIO_NR(4, 12)
752 },
753 .sda = {
754 .i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | PC,
755 .gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13 | PC,
756 .gp = IMX_GPIO_NR(4, 13)
757 }
758};
759
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200760iomux_v3_cfg_t const usdhc1_pads[] = {
761 MX6_PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
762 MX6_PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
763 MX6_PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
764 MX6_PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
765 MX6_PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
766 MX6_PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
767};
768
Heiko Schocher05729822015-05-18 13:32:31 +0200769int dram_init(void)
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200770{
Fabio Estevam1b23fe52016-07-23 13:23:39 -0300771 gd->ram_size = imx_ddr_size();
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200772
Heiko Schocher05729822015-05-18 13:32:31 +0200773 return 0;
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200774}
775
Yangbo Lu73340382019-06-21 11:42:28 +0800776#ifdef CONFIG_FSL_ESDHC_IMX
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200777struct fsl_esdhc_cfg usdhc_cfg[2] = {
778 {USDHC1_BASE_ADDR},
779 {USDHC2_BASE_ADDR},
780};
781
782int board_mmc_getcd(struct mmc *mmc)
783{
784 return 1;
785}
786
787int board_mmc_init(bd_t *bis)
788{
789 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200790 imx_iomux_v3_setup_multiple_pads(usdhc1_pads, ARRAY_SIZE(usdhc1_pads));
Heiko Schocher05729822015-05-18 13:32:31 +0200791#if (CONFIG_SYS_BOARD_VERSION == 2)
792 /*
793 * usdhc2 has a levelshifter on the carrier board Rev. DV1,
794 * that will automatically detect the driving direction.
795 * During initialisation this isn't working correctly,
796 * which causes DAT3 to be driven low towards the SD-card.
797 * This causes a SD-card enetring the SPI-Mode
798 * and therefore getting inaccessible until next power cycle.
799 * As workaround we drive the DAT3 line as GPIO and set it high.
800 * This makes usdhc2 unusable in u-boot, but works for the
801 * initialisation in Linux
802 */
803 imx_iomux_v3_setup_pad(MX6_PAD_SD2_DAT3__GPIO1_IO12 |
804 MUX_PAD_CTRL(NO_PAD_CTRL));
805 gpio_direction_output(IMX_GPIO_NR(1, 12) , 1);
806#endif
807 return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200808}
809#endif
810
811/*
812 * Do not overwrite the console
813 * Use always serial for U-Boot console
814 */
815int overwrite_console(void)
816{
817 return 1;
818}
819
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200820struct display_info_t const displays[] = {
821 {
822 .bus = -1,
823 .addr = 0,
824 .pixfmt = IPU_PIX_FMT_RGB24,
825 .detect = NULL,
826 .enable = enable_lvds,
827 .mode = {
828 .name = "lb07wv8",
829 .refresh = 60,
830 .xres = 800,
831 .yres = 480,
Heiko Schocher27813292015-08-11 08:09:44 +0200832 .pixclock = 30066,
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200833 .left_margin = 88,
834 .right_margin = 88,
Heiko Schocher27813292015-08-11 08:09:44 +0200835 .upper_margin = 20,
836 .lower_margin = 20,
Heiko Schocher69f0e442015-01-20 10:06:18 +0100837 .hsync_len = 80,
Heiko Schocher27813292015-08-11 08:09:44 +0200838 .vsync_len = 5,
839 .sync = FB_SYNC_EXT,
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200840 .vmode = FB_VMODE_NONINTERLACED
841 }
842 }
Heiko Schocher8fb9f3f2015-08-24 11:36:40 +0200843#if ((CONFIG_SYS_BOARD_VERSION == 2) || (CONFIG_SYS_BOARD_VERSION == 3))
Heiko Schocher05729822015-05-18 13:32:31 +0200844 , {
845 .bus = -1,
846 .addr = 0,
847 .pixfmt = IPU_PIX_FMT_RGB24,
848 .detect = NULL,
849 .enable = enable_spi_display,
850 .mode = {
851 .name = "lg4573",
Heiko Schocher27813292015-08-11 08:09:44 +0200852 .refresh = 57,
Heiko Schocher05729822015-05-18 13:32:31 +0200853 .xres = 480,
854 .yres = 800,
855 .pixclock = 37037,
856 .left_margin = 59,
857 .right_margin = 10,
858 .upper_margin = 15,
859 .lower_margin = 15,
860 .hsync_len = 10,
861 .vsync_len = 15,
862 .sync = FB_SYNC_EXT | FB_SYNC_HOR_HIGH_ACT |
863 FB_SYNC_VERT_HIGH_ACT,
864 .vmode = FB_VMODE_NONINTERLACED
865 }
866 }
867#endif
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200868};
869size_t display_count = ARRAY_SIZE(displays);
870
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200871/* no console on this board */
872int board_cfb_skip(void)
873{
874 return 1;
875}
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200876
877iomux_v3_cfg_t nfc_pads[] = {
878 MX6_PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(NO_PAD_CTRL),
879 MX6_PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(NO_PAD_CTRL),
880 MX6_PAD_NANDF_WP_B__NAND_WP_B | MUX_PAD_CTRL(NO_PAD_CTRL),
881 MX6_PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NO_PAD_CTRL),
882 MX6_PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(NO_PAD_CTRL),
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200883 MX6_PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(NO_PAD_CTRL),
884 MX6_PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(NO_PAD_CTRL),
885 MX6_PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(NO_PAD_CTRL),
886 MX6_PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(NO_PAD_CTRL),
887 MX6_PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(NO_PAD_CTRL),
888 MX6_PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(NO_PAD_CTRL),
889 MX6_PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(NO_PAD_CTRL),
890 MX6_PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(NO_PAD_CTRL),
891 MX6_PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(NO_PAD_CTRL),
892 MX6_PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(NO_PAD_CTRL),
893 MX6_PAD_SD4_DAT0__NAND_DQS | MUX_PAD_CTRL(NO_PAD_CTRL),
894};
895
896static void setup_gpmi_nand(void)
897{
898 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
899
900 /* config gpmi nand iomux */
901 imx_iomux_v3_setup_multiple_pads(nfc_pads,
902 ARRAY_SIZE(nfc_pads));
903
Heiko Schocher05729822015-05-18 13:32:31 +0200904 /* gate ENFC_CLK_ROOT clock first,before clk source switch */
905 clrbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
906
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200907 /* config gpmi and bch clock to 100 MHz */
908 clrsetbits_le32(&mxc_ccm->cs2cdr,
909 MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |
910 MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |
911 MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK,
912 MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) |
913 MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) |
914 MXC_CCM_CS2CDR_ENFC_CLK_SEL(3));
915
Heiko Schocher05729822015-05-18 13:32:31 +0200916 /* enable ENFC_CLK_ROOT clock */
917 setbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
918
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200919 /* enable gpmi and bch clock gating */
920 setbits_le32(&mxc_ccm->CCGR4,
921 MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
922 MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
923 MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
924 MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
925 MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_OFFSET);
926
927 /* enable apbh clock gating */
928 setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
929}
930
931int board_init(void)
932{
933 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
934
935 /* address of boot parameters */
936 gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
937
938 setup_spi();
939
940 setup_i2c(0, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE,
941 &i2c_pad_info1);
942 setup_i2c(1, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE,
943 &i2c_pad_info2);
944 setup_i2c(2, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE,
945 &i2c_pad_info3);
Heiko Schocher05729822015-05-18 13:32:31 +0200946 setup_i2c4();
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200947
948 /* SPI NOR Flash read only */
949 gpio_request(CONFIG_GPIO_ENABLE_SPI_FLASH, "ena_spi_nor");
950 gpio_direction_output(CONFIG_GPIO_ENABLE_SPI_FLASH, 0);
951 gpio_free(CONFIG_GPIO_ENABLE_SPI_FLASH);
952
Heiko Schocher05729822015-05-18 13:32:31 +0200953 setup_board_gpio();
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200954 setup_gpmi_nand();
Heiko Schocher05729822015-05-18 13:32:31 +0200955 setup_board_spi();
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200956
957 /* GPIO_1 for USB_OTG_ID */
Heiko Schocher05729822015-05-18 13:32:31 +0200958 clrsetbits_le32(&iomux->gpr[1], IOMUXC_GPR1_USB_OTG_ID_SEL_MASK, 0);
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200959 imx_iomux_v3_setup_multiple_pads(misc_pads, ARRAY_SIZE(misc_pads));
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200960 return 0;
961}
962
963int checkboard(void)
964{
Heiko Schocher05729822015-05-18 13:32:31 +0200965 printf("Board: %s\n", CONFIG_BOARDNAME);
Heiko Schocherf853c6c2014-07-18 06:07:22 +0200966 return 0;
967}
968
969#ifdef CONFIG_USB_EHCI_MX6
970int board_ehci_hcd_init(int port)
971{
972 int ret;
973
974 ret = gpio_request(ARISTAINETOS_USB_H1_PWR, "usb-h1-pwr");
975 if (!ret)
976 gpio_direction_output(ARISTAINETOS_USB_H1_PWR, 1);
977 ret = gpio_request(ARISTAINETOS_USB_OTG_PWR, "usb-OTG-pwr");
978 if (!ret)
979 gpio_direction_output(ARISTAINETOS_USB_OTG_PWR, 1);
980 return 0;
981}
982
983int board_ehci_power(int port, int on)
984{
985 if (port)
986 gpio_set_value(ARISTAINETOS_USB_OTG_PWR, on);
987 else
988 gpio_set_value(ARISTAINETOS_USB_H1_PWR, on);
Heiko Schocher54333792019-12-01 11:23:12 +0100989
990 return 0;
991}
992#endif
993
994int board_fit_config_name_match(const char *name)
995{
996 if (gd->board_type == BOARD_TYPE_4 &&
997 strchr(name, 0x34))
998 return 0;
999
1000 if (gd->board_type == BOARD_TYPE_7 &&
1001 strchr(name, 0x37))
1002 return 0;
1003
1004 return -1;
1005}
1006
1007static void do_board_detect(void)
1008{
1009 int ret;
1010 char s[30];
1011
1012 /* default use board type 7 */
1013 gd->board_type = BOARD_TYPE_7;
1014 if (env_init())
1015 return;
1016
1017 ret = env_get_f("panel", s, sizeof(s));
1018 if (ret < 0)
1019 return;
1020
1021 if (!strncmp("lg4573", s, 6))
1022 gd->board_type = BOARD_TYPE_4;
1023}
1024
1025#ifdef CONFIG_DTB_RESELECT
1026int embedded_dtb_select(void)
1027{
1028 int rescan;
1029
1030 do_board_detect();
1031 fdtdec_resetup(&rescan);
1032
Heiko Schocherf853c6c2014-07-18 06:07:22 +02001033 return 0;
1034}
1035#endif