1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * (C) Copyright 2015
3*4882a593Smuzhiyun * Heiko Schocher, DENX Software Engineering, hs@denx.de.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Based on:
6*4882a593Smuzhiyun * Copyright (C) 2012 Freescale Semiconductor, Inc.
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * Author: Fabio Estevam <fabio.estevam@freescale.com>
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
11*4882a593Smuzhiyun */
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #include <asm/arch/clock.h>
14*4882a593Smuzhiyun #include <asm/arch/imx-regs.h>
15*4882a593Smuzhiyun #include <asm/arch/iomux.h>
16*4882a593Smuzhiyun #include <asm/arch/mx6-pins.h>
17*4882a593Smuzhiyun #include <linux/errno.h>
18*4882a593Smuzhiyun #include <asm/gpio.h>
19*4882a593Smuzhiyun #include <asm/mach-imx/iomux-v3.h>
20*4882a593Smuzhiyun #include <asm/mach-imx/boot_mode.h>
21*4882a593Smuzhiyun #include <asm/mach-imx/mxc_i2c.h>
22*4882a593Smuzhiyun #include <asm/mach-imx/video.h>
23*4882a593Smuzhiyun #include <mmc.h>
24*4882a593Smuzhiyun #include <fsl_esdhc.h>
25*4882a593Smuzhiyun #include <miiphy.h>
26*4882a593Smuzhiyun #include <netdev.h>
27*4882a593Smuzhiyun #include <asm/arch/mxc_hdmi.h>
28*4882a593Smuzhiyun #include <asm/arch/crm_regs.h>
29*4882a593Smuzhiyun #include <linux/fb.h>
30*4882a593Smuzhiyun #include <ipu_pixfmt.h>
31*4882a593Smuzhiyun #include <asm/io.h>
32*4882a593Smuzhiyun #include <asm/arch/sys_proto.h>
33*4882a593Smuzhiyun #include <pwm.h>
34*4882a593Smuzhiyun #include <micrel.h>
35*4882a593Smuzhiyun #include <spi.h>
36*4882a593Smuzhiyun #include <video.h>
37*4882a593Smuzhiyun #include <../drivers/video/ipu.h>
38*4882a593Smuzhiyun #if defined(CONFIG_VIDEO_BMP_LOGO)
39*4882a593Smuzhiyun #include <bmp_logo.h>
40*4882a593Smuzhiyun #endif
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun #define USDHC2_PAD_CTRL (PAD_CTL_SPEED_LOW | \
43*4882a593Smuzhiyun PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun #if (CONFIG_SYS_BOARD_VERSION == 2)
46*4882a593Smuzhiyun /* 4.3 display controller */
47*4882a593Smuzhiyun #define ECSPI1_CS0 IMX_GPIO_NR(4, 9)
48*4882a593Smuzhiyun #define ECSPI4_CS0 IMX_GPIO_NR(3, 29)
49*4882a593Smuzhiyun #elif (CONFIG_SYS_BOARD_VERSION == 3)
50*4882a593Smuzhiyun #define ECSPI1_CS0 IMX_GPIO_NR(2, 30) /* NOR flash */
51*4882a593Smuzhiyun /* 4.3 display controller */
52*4882a593Smuzhiyun #define ECSPI1_CS1 IMX_GPIO_NR(4, 10)
53*4882a593Smuzhiyun #endif
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun #define SOFT_RESET_GPIO IMX_GPIO_NR(7, 13)
56*4882a593Smuzhiyun #define SD2_DRIVER_ENABLE IMX_GPIO_NR(7, 8)
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun struct i2c_pads_info i2c_pad_info3 = {
59*4882a593Smuzhiyun .scl = {
60*4882a593Smuzhiyun .i2c_mode = MX6_PAD_GPIO_5__I2C3_SCL | PC,
61*4882a593Smuzhiyun .gpio_mode = MX6_PAD_GPIO_5__GPIO1_IO05 | PC,
62*4882a593Smuzhiyun .gp = IMX_GPIO_NR(1, 5)
63*4882a593Smuzhiyun },
64*4882a593Smuzhiyun .sda = {
65*4882a593Smuzhiyun .i2c_mode = MX6_PAD_GPIO_6__I2C3_SDA | PC,
66*4882a593Smuzhiyun .gpio_mode = MX6_PAD_GPIO_6__GPIO1_IO06 | PC,
67*4882a593Smuzhiyun .gp = IMX_GPIO_NR(1, 6)
68*4882a593Smuzhiyun }
69*4882a593Smuzhiyun };
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun struct i2c_pads_info i2c_pad_info4 = {
72*4882a593Smuzhiyun .scl = {
73*4882a593Smuzhiyun .i2c_mode = MX6_PAD_GPIO_7__I2C4_SCL | PC,
74*4882a593Smuzhiyun .gpio_mode = MX6_PAD_GPIO_7__GPIO1_IO07 | PC,
75*4882a593Smuzhiyun .gp = IMX_GPIO_NR(1, 7)
76*4882a593Smuzhiyun },
77*4882a593Smuzhiyun .sda = {
78*4882a593Smuzhiyun .i2c_mode = MX6_PAD_GPIO_8__I2C4_SDA | PC,
79*4882a593Smuzhiyun .gpio_mode = MX6_PAD_GPIO_8__GPIO1_IO08 | PC,
80*4882a593Smuzhiyun .gp = IMX_GPIO_NR(1, 8)
81*4882a593Smuzhiyun }
82*4882a593Smuzhiyun };
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun iomux_v3_cfg_t const uart1_pads[] = {
85*4882a593Smuzhiyun MX6_PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
86*4882a593Smuzhiyun MX6_PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
87*4882a593Smuzhiyun MX6_PAD_EIM_D19__UART1_CTS_B | MUX_PAD_CTRL(UART_PAD_CTRL),
88*4882a593Smuzhiyun MX6_PAD_EIM_D20__UART1_RTS_B | MUX_PAD_CTRL(UART_PAD_CTRL),
89*4882a593Smuzhiyun };
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun iomux_v3_cfg_t const uart2_pads[] = {
92*4882a593Smuzhiyun MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
93*4882a593Smuzhiyun MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
94*4882a593Smuzhiyun };
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun iomux_v3_cfg_t const uart3_pads[] = {
97*4882a593Smuzhiyun MX6_PAD_EIM_D24__UART3_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
98*4882a593Smuzhiyun MX6_PAD_EIM_D25__UART3_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
99*4882a593Smuzhiyun MX6_PAD_EIM_D31__UART3_RTS_B | MUX_PAD_CTRL(UART_PAD_CTRL),
100*4882a593Smuzhiyun MX6_PAD_EIM_D23__UART3_CTS_B | MUX_PAD_CTRL(UART_PAD_CTRL),
101*4882a593Smuzhiyun };
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun iomux_v3_cfg_t const uart4_pads[] = {
104*4882a593Smuzhiyun MX6_PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
105*4882a593Smuzhiyun MX6_PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
106*4882a593Smuzhiyun };
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun iomux_v3_cfg_t const gpio_pads[] = {
109*4882a593Smuzhiyun /* LED enable*/
110*4882a593Smuzhiyun MX6_PAD_ENET_CRS_DV__GPIO1_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL),
111*4882a593Smuzhiyun /* LED yellow */
112*4882a593Smuzhiyun MX6_PAD_NANDF_CS3__GPIO6_IO16 | MUX_PAD_CTRL(NO_PAD_CTRL),
113*4882a593Smuzhiyun /* LED red */
114*4882a593Smuzhiyun #if (CONFIG_SYS_BOARD_VERSION == 2)
115*4882a593Smuzhiyun MX6_PAD_EIM_EB0__GPIO2_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL),
116*4882a593Smuzhiyun #elif (CONFIG_SYS_BOARD_VERSION == 3)
117*4882a593Smuzhiyun MX6_PAD_EIM_WAIT__GPIO5_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL),
118*4882a593Smuzhiyun #endif
119*4882a593Smuzhiyun /* LED green */
120*4882a593Smuzhiyun MX6_PAD_EIM_A24__GPIO5_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL),
121*4882a593Smuzhiyun /* LED blue */
122*4882a593Smuzhiyun MX6_PAD_EIM_EB1__GPIO2_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
123*4882a593Smuzhiyun /* spi flash WP protect */
124*4882a593Smuzhiyun MX6_PAD_SD4_DAT7__GPIO2_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
125*4882a593Smuzhiyun /* spi CS 0 */
126*4882a593Smuzhiyun MX6_PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
127*4882a593Smuzhiyun /* spi bus #2 SS driver enable */
128*4882a593Smuzhiyun MX6_PAD_EIM_A23__GPIO6_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
129*4882a593Smuzhiyun /* RST_LOC# PHY reset input (has pull-down!)*/
130*4882a593Smuzhiyun MX6_PAD_GPIO_18__GPIO7_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL),
131*4882a593Smuzhiyun /* SD 2 level shifter output enable */
132*4882a593Smuzhiyun MX6_PAD_SD3_RST__GPIO7_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
133*4882a593Smuzhiyun /* SD1 card detect input */
134*4882a593Smuzhiyun MX6_PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
135*4882a593Smuzhiyun /* SD1 write protect input */
136*4882a593Smuzhiyun MX6_PAD_DI0_PIN4__GPIO4_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
137*4882a593Smuzhiyun /* SD2 card detect input */
138*4882a593Smuzhiyun MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
139*4882a593Smuzhiyun /* SD2 write protect input */
140*4882a593Smuzhiyun MX6_PAD_SD4_DAT2__GPIO2_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
141*4882a593Smuzhiyun /* Touchscreen IRQ */
142*4882a593Smuzhiyun MX6_PAD_SD4_DAT1__GPIO2_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),
143*4882a593Smuzhiyun };
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun static iomux_v3_cfg_t const misc_pads[] = {
146*4882a593Smuzhiyun /* USB_OTG_ID = GPIO1_24*/
147*4882a593Smuzhiyun MX6_PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
148*4882a593Smuzhiyun /* H1 Power enable = GPIO1_0*/
149*4882a593Smuzhiyun MX6_PAD_GPIO_0__USB_H1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
150*4882a593Smuzhiyun /* OTG Power enable = GPIO4_15*/
151*4882a593Smuzhiyun MX6_PAD_KEY_ROW4__USB_OTG_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
152*4882a593Smuzhiyun };
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun iomux_v3_cfg_t const enet_pads[] = {
155*4882a593Smuzhiyun MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
156*4882a593Smuzhiyun MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
157*4882a593Smuzhiyun MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
158*4882a593Smuzhiyun MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
159*4882a593Smuzhiyun MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
160*4882a593Smuzhiyun MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
161*4882a593Smuzhiyun MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
162*4882a593Smuzhiyun MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
163*4882a593Smuzhiyun MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
164*4882a593Smuzhiyun MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
165*4882a593Smuzhiyun MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
166*4882a593Smuzhiyun MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
167*4882a593Smuzhiyun MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
168*4882a593Smuzhiyun MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
169*4882a593Smuzhiyun MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
170*4882a593Smuzhiyun };
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun static iomux_v3_cfg_t const backlight_pads[] = {
173*4882a593Smuzhiyun /* backlight PWM brightness control */
174*4882a593Smuzhiyun MX6_PAD_GPIO_9__PWM1_OUT | MUX_PAD_CTRL(NO_PAD_CTRL),
175*4882a593Smuzhiyun /* backlight enable */
176*4882a593Smuzhiyun MX6_PAD_EIM_BCLK__GPIO6_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL),
177*4882a593Smuzhiyun /* LCD power enable */
178*4882a593Smuzhiyun MX6_PAD_NANDF_CS2__GPIO6_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
179*4882a593Smuzhiyun };
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun static iomux_v3_cfg_t const ecspi1_pads[] = {
182*4882a593Smuzhiyun MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
183*4882a593Smuzhiyun MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
184*4882a593Smuzhiyun MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
185*4882a593Smuzhiyun #if (CONFIG_SYS_BOARD_VERSION == 2)
186*4882a593Smuzhiyun MX6_PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(SPI_PAD_CTRL),
187*4882a593Smuzhiyun #elif (CONFIG_SYS_BOARD_VERSION == 3)
188*4882a593Smuzhiyun MX6_PAD_EIM_EB2__GPIO2_IO30 | MUX_PAD_CTRL(SPI_PAD_CTRL),
189*4882a593Smuzhiyun MX6_PAD_KEY_COL2__GPIO4_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
190*4882a593Smuzhiyun #endif
191*4882a593Smuzhiyun };
192*4882a593Smuzhiyun
setup_iomux_enet(void)193*4882a593Smuzhiyun static void setup_iomux_enet(void)
194*4882a593Smuzhiyun {
195*4882a593Smuzhiyun imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun #if (CONFIG_SYS_BOARD_VERSION == 2)
199*4882a593Smuzhiyun iomux_v3_cfg_t const ecspi4_pads[] = {
200*4882a593Smuzhiyun MX6_PAD_EIM_D21__ECSPI4_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL),
201*4882a593Smuzhiyun MX6_PAD_EIM_D22__ECSPI4_MISO | MUX_PAD_CTRL(NO_PAD_CTRL),
202*4882a593Smuzhiyun MX6_PAD_EIM_D28__ECSPI4_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL),
203*4882a593Smuzhiyun MX6_PAD_EIM_A25__GPIO5_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL),
204*4882a593Smuzhiyun MX6_PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
205*4882a593Smuzhiyun };
206*4882a593Smuzhiyun #endif
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun static iomux_v3_cfg_t const display_pads[] = {
209*4882a593Smuzhiyun MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK | MUX_PAD_CTRL(DISP_PAD_CTRL),
210*4882a593Smuzhiyun MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15,
211*4882a593Smuzhiyun MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02,
212*4882a593Smuzhiyun MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03,
213*4882a593Smuzhiyun MX6_PAD_DISP0_DAT0__IPU1_DISP0_DATA00,
214*4882a593Smuzhiyun MX6_PAD_DISP0_DAT1__IPU1_DISP0_DATA01,
215*4882a593Smuzhiyun MX6_PAD_DISP0_DAT2__IPU1_DISP0_DATA02,
216*4882a593Smuzhiyun MX6_PAD_DISP0_DAT3__IPU1_DISP0_DATA03,
217*4882a593Smuzhiyun MX6_PAD_DISP0_DAT4__IPU1_DISP0_DATA04,
218*4882a593Smuzhiyun MX6_PAD_DISP0_DAT5__IPU1_DISP0_DATA05,
219*4882a593Smuzhiyun MX6_PAD_DISP0_DAT6__IPU1_DISP0_DATA06,
220*4882a593Smuzhiyun MX6_PAD_DISP0_DAT7__IPU1_DISP0_DATA07,
221*4882a593Smuzhiyun MX6_PAD_DISP0_DAT8__IPU1_DISP0_DATA08,
222*4882a593Smuzhiyun MX6_PAD_DISP0_DAT9__IPU1_DISP0_DATA09,
223*4882a593Smuzhiyun MX6_PAD_DISP0_DAT10__IPU1_DISP0_DATA10,
224*4882a593Smuzhiyun MX6_PAD_DISP0_DAT11__IPU1_DISP0_DATA11,
225*4882a593Smuzhiyun MX6_PAD_DISP0_DAT12__IPU1_DISP0_DATA12,
226*4882a593Smuzhiyun MX6_PAD_DISP0_DAT13__IPU1_DISP0_DATA13,
227*4882a593Smuzhiyun MX6_PAD_DISP0_DAT14__IPU1_DISP0_DATA14,
228*4882a593Smuzhiyun MX6_PAD_DISP0_DAT15__IPU1_DISP0_DATA15,
229*4882a593Smuzhiyun MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16,
230*4882a593Smuzhiyun MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17,
231*4882a593Smuzhiyun MX6_PAD_DISP0_DAT18__IPU1_DISP0_DATA18,
232*4882a593Smuzhiyun MX6_PAD_DISP0_DAT19__IPU1_DISP0_DATA19,
233*4882a593Smuzhiyun MX6_PAD_DISP0_DAT20__IPU1_DISP0_DATA20,
234*4882a593Smuzhiyun MX6_PAD_DISP0_DAT21__IPU1_DISP0_DATA21,
235*4882a593Smuzhiyun MX6_PAD_DISP0_DAT22__IPU1_DISP0_DATA22,
236*4882a593Smuzhiyun MX6_PAD_DISP0_DAT23__IPU1_DISP0_DATA23,
237*4882a593Smuzhiyun };
238*4882a593Smuzhiyun
board_spi_cs_gpio(unsigned bus,unsigned cs)239*4882a593Smuzhiyun int board_spi_cs_gpio(unsigned bus, unsigned cs)
240*4882a593Smuzhiyun {
241*4882a593Smuzhiyun if (bus == CONFIG_SF_DEFAULT_BUS && cs == CONFIG_SF_DEFAULT_CS)
242*4882a593Smuzhiyun #if (CONFIG_SYS_BOARD_VERSION == 2)
243*4882a593Smuzhiyun return IMX_GPIO_NR(5, 2);
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun if (bus == 0 && cs == 0)
246*4882a593Smuzhiyun return IMX_GPIO_NR(4, 9);
247*4882a593Smuzhiyun #elif (CONFIG_SYS_BOARD_VERSION == 3)
248*4882a593Smuzhiyun return ECSPI1_CS0;
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun if (bus == 0 && cs == 1)
251*4882a593Smuzhiyun return ECSPI1_CS1;
252*4882a593Smuzhiyun #endif
253*4882a593Smuzhiyun return -1;
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun
setup_spi(void)256*4882a593Smuzhiyun static void setup_spi(void)
257*4882a593Smuzhiyun {
258*4882a593Smuzhiyun int i;
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads));
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun #if (CONFIG_SYS_BOARD_VERSION == 2)
263*4882a593Smuzhiyun imx_iomux_v3_setup_multiple_pads(ecspi4_pads, ARRAY_SIZE(ecspi4_pads));
264*4882a593Smuzhiyun #endif
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun for (i = 0; i < 4; i++)
267*4882a593Smuzhiyun enable_spi_clk(true, i);
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun gpio_direction_output(ECSPI1_CS0, 1);
270*4882a593Smuzhiyun #if (CONFIG_SYS_BOARD_VERSION == 2)
271*4882a593Smuzhiyun gpio_direction_output(ECSPI4_CS1, 0);
272*4882a593Smuzhiyun /* set cs0 to high (second device on spi bus #4) */
273*4882a593Smuzhiyun gpio_direction_output(ECSPI4_CS0, 1);
274*4882a593Smuzhiyun #elif (CONFIG_SYS_BOARD_VERSION == 3)
275*4882a593Smuzhiyun gpio_direction_output(ECSPI1_CS1, 1);
276*4882a593Smuzhiyun #endif
277*4882a593Smuzhiyun }
278*4882a593Smuzhiyun
setup_iomux_uart(void)279*4882a593Smuzhiyun static void setup_iomux_uart(void)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun switch (CONFIG_MXC_UART_BASE) {
282*4882a593Smuzhiyun case UART1_BASE:
283*4882a593Smuzhiyun imx_iomux_v3_setup_multiple_pads(uart1_pads,
284*4882a593Smuzhiyun ARRAY_SIZE(uart1_pads));
285*4882a593Smuzhiyun break;
286*4882a593Smuzhiyun case UART2_BASE:
287*4882a593Smuzhiyun imx_iomux_v3_setup_multiple_pads(uart2_pads,
288*4882a593Smuzhiyun ARRAY_SIZE(uart2_pads));
289*4882a593Smuzhiyun break;
290*4882a593Smuzhiyun case UART3_BASE:
291*4882a593Smuzhiyun imx_iomux_v3_setup_multiple_pads(uart3_pads,
292*4882a593Smuzhiyun ARRAY_SIZE(uart3_pads));
293*4882a593Smuzhiyun break;
294*4882a593Smuzhiyun case UART4_BASE:
295*4882a593Smuzhiyun imx_iomux_v3_setup_multiple_pads(uart4_pads,
296*4882a593Smuzhiyun ARRAY_SIZE(uart4_pads));
297*4882a593Smuzhiyun break;
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun
board_phy_config(struct phy_device * phydev)301*4882a593Smuzhiyun int board_phy_config(struct phy_device *phydev)
302*4882a593Smuzhiyun {
303*4882a593Smuzhiyun /* control data pad skew - devaddr = 0x02, register = 0x04 */
304*4882a593Smuzhiyun ksz9031_phy_extended_write(phydev, 0x02,
305*4882a593Smuzhiyun MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW,
306*4882a593Smuzhiyun MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
307*4882a593Smuzhiyun /* rx data pad skew - devaddr = 0x02, register = 0x05 */
308*4882a593Smuzhiyun ksz9031_phy_extended_write(phydev, 0x02,
309*4882a593Smuzhiyun MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW,
310*4882a593Smuzhiyun MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
311*4882a593Smuzhiyun /* tx data pad skew - devaddr = 0x02, register = 0x06 */
312*4882a593Smuzhiyun ksz9031_phy_extended_write(phydev, 0x02,
313*4882a593Smuzhiyun MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW,
314*4882a593Smuzhiyun MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
315*4882a593Smuzhiyun /* gtx and rx clock pad skew - devaddr = 0x02, register = 0x08 */
316*4882a593Smuzhiyun ksz9031_phy_extended_write(phydev, 0x02,
317*4882a593Smuzhiyun MII_KSZ9031_EXT_RGMII_CLOCK_SKEW,
318*4882a593Smuzhiyun MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x03FF);
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun if (phydev->drv->config)
321*4882a593Smuzhiyun phydev->drv->config(phydev);
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun return 0;
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun
board_eth_init(bd_t * bis)326*4882a593Smuzhiyun int board_eth_init(bd_t *bis)
327*4882a593Smuzhiyun {
328*4882a593Smuzhiyun setup_iomux_enet();
329*4882a593Smuzhiyun return cpu_eth_init(bis);
330*4882a593Smuzhiyun }
331*4882a593Smuzhiyun
rotate_logo_one(unsigned char * out,unsigned char * in)332*4882a593Smuzhiyun static int rotate_logo_one(unsigned char *out, unsigned char *in)
333*4882a593Smuzhiyun {
334*4882a593Smuzhiyun int i, j;
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun for (i = 0; i < BMP_LOGO_WIDTH; i++)
337*4882a593Smuzhiyun for (j = 0; j < BMP_LOGO_HEIGHT; j++)
338*4882a593Smuzhiyun out[j * BMP_LOGO_WIDTH + BMP_LOGO_HEIGHT - 1 - i] =
339*4882a593Smuzhiyun in[i * BMP_LOGO_WIDTH + j];
340*4882a593Smuzhiyun return 0;
341*4882a593Smuzhiyun }
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun /*
344*4882a593Smuzhiyun * Rotate the BMP_LOGO (only)
345*4882a593Smuzhiyun * Will only work, if the logo is square, as
346*4882a593Smuzhiyun * BMP_LOGO_HEIGHT and BMP_LOGO_WIDTH are defines, not variables
347*4882a593Smuzhiyun */
rotate_logo(int rotations)348*4882a593Smuzhiyun void rotate_logo(int rotations)
349*4882a593Smuzhiyun {
350*4882a593Smuzhiyun unsigned char out_logo[BMP_LOGO_WIDTH * BMP_LOGO_HEIGHT];
351*4882a593Smuzhiyun unsigned char *in_logo;
352*4882a593Smuzhiyun int i, j;
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun if (BMP_LOGO_WIDTH != BMP_LOGO_HEIGHT)
355*4882a593Smuzhiyun return;
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun in_logo = bmp_logo_bitmap;
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun /* one 90 degree rotation */
360*4882a593Smuzhiyun if (rotations == 1 || rotations == 2 || rotations == 3)
361*4882a593Smuzhiyun rotate_logo_one(out_logo, in_logo);
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun /* second 90 degree rotation */
364*4882a593Smuzhiyun if (rotations == 2 || rotations == 3)
365*4882a593Smuzhiyun rotate_logo_one(in_logo, out_logo);
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun /* third 90 degree rotation */
368*4882a593Smuzhiyun if (rotations == 3)
369*4882a593Smuzhiyun rotate_logo_one(out_logo, in_logo);
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun /* copy result back to original array */
372*4882a593Smuzhiyun if (rotations == 1 || rotations == 3)
373*4882a593Smuzhiyun for (i = 0; i < BMP_LOGO_WIDTH; i++)
374*4882a593Smuzhiyun for (j = 0; j < BMP_LOGO_HEIGHT; j++)
375*4882a593Smuzhiyun in_logo[i * BMP_LOGO_WIDTH + j] =
376*4882a593Smuzhiyun out_logo[i * BMP_LOGO_WIDTH + j];
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun
enable_display_power(void)379*4882a593Smuzhiyun static void enable_display_power(void)
380*4882a593Smuzhiyun {
381*4882a593Smuzhiyun imx_iomux_v3_setup_multiple_pads(backlight_pads,
382*4882a593Smuzhiyun ARRAY_SIZE(backlight_pads));
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun /* backlight enable */
385*4882a593Smuzhiyun gpio_direction_output(IMX_GPIO_NR(6, 31), 1);
386*4882a593Smuzhiyun /* LCD power enable */
387*4882a593Smuzhiyun gpio_direction_output(IMX_GPIO_NR(6, 15), 1);
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun /* enable backlight PWM 1 */
390*4882a593Smuzhiyun if (pwm_init(0, 0, 0))
391*4882a593Smuzhiyun goto error;
392*4882a593Smuzhiyun /* duty cycle 500ns, period: 3000ns */
393*4882a593Smuzhiyun if (pwm_config(0, 50000, 300000))
394*4882a593Smuzhiyun goto error;
395*4882a593Smuzhiyun if (pwm_enable(0))
396*4882a593Smuzhiyun goto error;
397*4882a593Smuzhiyun return;
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun error:
400*4882a593Smuzhiyun puts("error init pwm for backlight\n");
401*4882a593Smuzhiyun return;
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun
enable_lvds(struct display_info_t const * dev)404*4882a593Smuzhiyun static void enable_lvds(struct display_info_t const *dev)
405*4882a593Smuzhiyun {
406*4882a593Smuzhiyun struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
407*4882a593Smuzhiyun struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
408*4882a593Smuzhiyun int reg;
409*4882a593Smuzhiyun s32 timeout = 100000;
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun /* set PLL5 clock */
412*4882a593Smuzhiyun reg = readl(&ccm->analog_pll_video);
413*4882a593Smuzhiyun reg |= BM_ANADIG_PLL_VIDEO_POWERDOWN;
414*4882a593Smuzhiyun writel(reg, &ccm->analog_pll_video);
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun /* set PLL5 to 232720000Hz */
417*4882a593Smuzhiyun reg &= ~BM_ANADIG_PLL_VIDEO_DIV_SELECT;
418*4882a593Smuzhiyun reg |= BF_ANADIG_PLL_VIDEO_DIV_SELECT(0x26);
419*4882a593Smuzhiyun reg &= ~BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT;
420*4882a593Smuzhiyun reg |= BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(0);
421*4882a593Smuzhiyun writel(reg, &ccm->analog_pll_video);
422*4882a593Smuzhiyun
423*4882a593Smuzhiyun writel(BF_ANADIG_PLL_VIDEO_NUM_A(0xC0238),
424*4882a593Smuzhiyun &ccm->analog_pll_video_num);
425*4882a593Smuzhiyun writel(BF_ANADIG_PLL_VIDEO_DENOM_B(0xF4240),
426*4882a593Smuzhiyun &ccm->analog_pll_video_denom);
427*4882a593Smuzhiyun
428*4882a593Smuzhiyun reg &= ~BM_ANADIG_PLL_VIDEO_POWERDOWN;
429*4882a593Smuzhiyun writel(reg, &ccm->analog_pll_video);
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun while (timeout--)
432*4882a593Smuzhiyun if (readl(&ccm->analog_pll_video) & BM_ANADIG_PLL_VIDEO_LOCK)
433*4882a593Smuzhiyun break;
434*4882a593Smuzhiyun if (timeout < 0)
435*4882a593Smuzhiyun printf("Warning: video pll lock timeout!\n");
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun reg = readl(&ccm->analog_pll_video);
438*4882a593Smuzhiyun reg |= BM_ANADIG_PLL_VIDEO_ENABLE;
439*4882a593Smuzhiyun reg &= ~BM_ANADIG_PLL_VIDEO_BYPASS;
440*4882a593Smuzhiyun writel(reg, &ccm->analog_pll_video);
441*4882a593Smuzhiyun
442*4882a593Smuzhiyun /* set LDB0, LDB1 clk select to 000/000 (PLL5 clock) */
443*4882a593Smuzhiyun reg = readl(&ccm->cs2cdr);
444*4882a593Smuzhiyun reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
445*4882a593Smuzhiyun | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
446*4882a593Smuzhiyun reg |= (0 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
447*4882a593Smuzhiyun | (0 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
448*4882a593Smuzhiyun writel(reg, &ccm->cs2cdr);
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun reg = readl(&ccm->cscmr2);
451*4882a593Smuzhiyun reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
452*4882a593Smuzhiyun writel(reg, &ccm->cscmr2);
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun reg = readl(&ccm->chsccdr);
455*4882a593Smuzhiyun reg |= (CHSCCDR_CLK_SEL_LDB_DI0
456*4882a593Smuzhiyun << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
457*4882a593Smuzhiyun writel(reg, &ccm->chsccdr);
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
460*4882a593Smuzhiyun | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
461*4882a593Smuzhiyun | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_HIGH
462*4882a593Smuzhiyun | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
463*4882a593Smuzhiyun | IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT
464*4882a593Smuzhiyun | IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED
465*4882a593Smuzhiyun | IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
466*4882a593Smuzhiyun writel(reg, &iomux->gpr[2]);
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun reg = readl(&iomux->gpr[3]);
469*4882a593Smuzhiyun reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)
470*4882a593Smuzhiyun | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
471*4882a593Smuzhiyun << IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
472*4882a593Smuzhiyun writel(reg, &iomux->gpr[3]);
473*4882a593Smuzhiyun
474*4882a593Smuzhiyun return;
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun
enable_spi_display(struct display_info_t const * dev)477*4882a593Smuzhiyun static void enable_spi_display(struct display_info_t const *dev)
478*4882a593Smuzhiyun {
479*4882a593Smuzhiyun struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
480*4882a593Smuzhiyun struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
481*4882a593Smuzhiyun int reg;
482*4882a593Smuzhiyun s32 timeout = 100000;
483*4882a593Smuzhiyun
484*4882a593Smuzhiyun #if defined(CONFIG_VIDEO_BMP_LOGO)
485*4882a593Smuzhiyun rotate_logo(3); /* portrait display in landscape mode */
486*4882a593Smuzhiyun #endif
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun /*
489*4882a593Smuzhiyun * set ldb clock to 28341000 Hz calculated through the formula:
490*4882a593Smuzhiyun * (XRES + LEFT_M + RIGHT_M + HSYNC_LEN) *
491*4882a593Smuzhiyun * (YRES + UPPER_M + LOWER_M + VSYNC_LEN) * REFRESH)
492*4882a593Smuzhiyun * see:
493*4882a593Smuzhiyun * https://community.freescale.com/thread/308170
494*4882a593Smuzhiyun */
495*4882a593Smuzhiyun ipu_set_ldb_clock(28341000);
496*4882a593Smuzhiyun
497*4882a593Smuzhiyun reg = readl(&ccm->cs2cdr);
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun /* select pll 5 clock */
500*4882a593Smuzhiyun reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
501*4882a593Smuzhiyun | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
502*4882a593Smuzhiyun writel(reg, &ccm->cs2cdr);
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun /* set PLL5 to 197994996Hz */
505*4882a593Smuzhiyun reg &= ~BM_ANADIG_PLL_VIDEO_DIV_SELECT;
506*4882a593Smuzhiyun reg |= BF_ANADIG_PLL_VIDEO_DIV_SELECT(0x21);
507*4882a593Smuzhiyun reg &= ~BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT;
508*4882a593Smuzhiyun reg |= BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(0);
509*4882a593Smuzhiyun writel(reg, &ccm->analog_pll_video);
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun writel(BF_ANADIG_PLL_VIDEO_NUM_A(0xfbf4),
512*4882a593Smuzhiyun &ccm->analog_pll_video_num);
513*4882a593Smuzhiyun writel(BF_ANADIG_PLL_VIDEO_DENOM_B(0xf4240),
514*4882a593Smuzhiyun &ccm->analog_pll_video_denom);
515*4882a593Smuzhiyun
516*4882a593Smuzhiyun reg &= ~BM_ANADIG_PLL_VIDEO_POWERDOWN;
517*4882a593Smuzhiyun writel(reg, &ccm->analog_pll_video);
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun while (timeout--)
520*4882a593Smuzhiyun if (readl(&ccm->analog_pll_video) & BM_ANADIG_PLL_VIDEO_LOCK)
521*4882a593Smuzhiyun break;
522*4882a593Smuzhiyun if (timeout < 0)
523*4882a593Smuzhiyun printf("Warning: video pll lock timeout!\n");
524*4882a593Smuzhiyun
525*4882a593Smuzhiyun reg = readl(&ccm->analog_pll_video);
526*4882a593Smuzhiyun reg |= BM_ANADIG_PLL_VIDEO_ENABLE;
527*4882a593Smuzhiyun reg &= ~BM_ANADIG_PLL_VIDEO_BYPASS;
528*4882a593Smuzhiyun writel(reg, &ccm->analog_pll_video);
529*4882a593Smuzhiyun
530*4882a593Smuzhiyun /* set LDB0, LDB1 clk select to 000/000 (PLL5 clock) */
531*4882a593Smuzhiyun reg = readl(&ccm->cs2cdr);
532*4882a593Smuzhiyun reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
533*4882a593Smuzhiyun | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
534*4882a593Smuzhiyun reg |= (0 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
535*4882a593Smuzhiyun | (0 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
536*4882a593Smuzhiyun writel(reg, &ccm->cs2cdr);
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun reg = readl(&ccm->cscmr2);
539*4882a593Smuzhiyun reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
540*4882a593Smuzhiyun writel(reg, &ccm->cscmr2);
541*4882a593Smuzhiyun
542*4882a593Smuzhiyun reg = readl(&ccm->chsccdr);
543*4882a593Smuzhiyun reg |= (CHSCCDR_CLK_SEL_LDB_DI0
544*4882a593Smuzhiyun << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
545*4882a593Smuzhiyun reg &= ~MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK;
546*4882a593Smuzhiyun reg |= (2 << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET);
547*4882a593Smuzhiyun reg &= ~MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK;
548*4882a593Smuzhiyun reg |= (2 << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
549*4882a593Smuzhiyun writel(reg, &ccm->chsccdr);
550*4882a593Smuzhiyun
551*4882a593Smuzhiyun reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
552*4882a593Smuzhiyun | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
553*4882a593Smuzhiyun | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_HIGH
554*4882a593Smuzhiyun | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
555*4882a593Smuzhiyun | IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT
556*4882a593Smuzhiyun | IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED
557*4882a593Smuzhiyun | IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
558*4882a593Smuzhiyun writel(reg, &iomux->gpr[2]);
559*4882a593Smuzhiyun
560*4882a593Smuzhiyun reg = readl(&iomux->gpr[3]);
561*4882a593Smuzhiyun reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)
562*4882a593Smuzhiyun | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
563*4882a593Smuzhiyun << IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
564*4882a593Smuzhiyun writel(reg, &iomux->gpr[3]);
565*4882a593Smuzhiyun
566*4882a593Smuzhiyun imx_iomux_v3_setup_multiple_pads(
567*4882a593Smuzhiyun display_pads,
568*4882a593Smuzhiyun ARRAY_SIZE(display_pads));
569*4882a593Smuzhiyun
570*4882a593Smuzhiyun return;
571*4882a593Smuzhiyun }
setup_display(void)572*4882a593Smuzhiyun static void setup_display(void)
573*4882a593Smuzhiyun {
574*4882a593Smuzhiyun enable_ipu_clock();
575*4882a593Smuzhiyun enable_display_power();
576*4882a593Smuzhiyun }
577*4882a593Smuzhiyun
setup_iomux_gpio(void)578*4882a593Smuzhiyun static void setup_iomux_gpio(void)
579*4882a593Smuzhiyun {
580*4882a593Smuzhiyun imx_iomux_v3_setup_multiple_pads(gpio_pads, ARRAY_SIZE(gpio_pads));
581*4882a593Smuzhiyun }
582*4882a593Smuzhiyun
set_gpr_register(void)583*4882a593Smuzhiyun static void set_gpr_register(void)
584*4882a593Smuzhiyun {
585*4882a593Smuzhiyun struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
586*4882a593Smuzhiyun
587*4882a593Smuzhiyun writel(IOMUXC_GPR1_APP_CLK_REQ_N | IOMUXC_GPR1_PCIE_RDY_L23 |
588*4882a593Smuzhiyun IOMUXC_GPR1_EXC_MON_SLVE |
589*4882a593Smuzhiyun (2 << IOMUXC_GPR1_ADDRS0_OFFSET) |
590*4882a593Smuzhiyun IOMUXC_GPR1_ACT_CS0,
591*4882a593Smuzhiyun &iomuxc_regs->gpr[1]);
592*4882a593Smuzhiyun writel(0x0, &iomuxc_regs->gpr[8]);
593*4882a593Smuzhiyun writel(IOMUXC_GPR12_ARMP_IPG_CLK_EN | IOMUXC_GPR12_ARMP_AHB_CLK_EN |
594*4882a593Smuzhiyun IOMUXC_GPR12_ARMP_ATB_CLK_EN | IOMUXC_GPR12_ARMP_APB_CLK_EN,
595*4882a593Smuzhiyun &iomuxc_regs->gpr[12]);
596*4882a593Smuzhiyun }
597*4882a593Smuzhiyun
board_early_init_f(void)598*4882a593Smuzhiyun int board_early_init_f(void)
599*4882a593Smuzhiyun {
600*4882a593Smuzhiyun setup_iomux_uart();
601*4882a593Smuzhiyun setup_iomux_gpio();
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun gpio_direction_output(SOFT_RESET_GPIO, 1);
604*4882a593Smuzhiyun gpio_direction_output(SD2_DRIVER_ENABLE, 1);
605*4882a593Smuzhiyun setup_display();
606*4882a593Smuzhiyun set_gpr_register();
607*4882a593Smuzhiyun return 0;
608*4882a593Smuzhiyun }
609*4882a593Smuzhiyun
setup_i2c4(void)610*4882a593Smuzhiyun static void setup_i2c4(void)
611*4882a593Smuzhiyun {
612*4882a593Smuzhiyun setup_i2c(3, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE,
613*4882a593Smuzhiyun &i2c_pad_info4);
614*4882a593Smuzhiyun }
615*4882a593Smuzhiyun
setup_board_gpio(void)616*4882a593Smuzhiyun static void setup_board_gpio(void)
617*4882a593Smuzhiyun {
618*4882a593Smuzhiyun /* enable all LEDs */
619*4882a593Smuzhiyun gpio_request(IMX_GPIO_NR(2, 13), "LED ena"); /* 25 */
620*4882a593Smuzhiyun gpio_direction_output(IMX_GPIO_NR(1, 25), 0);
621*4882a593Smuzhiyun
622*4882a593Smuzhiyun /* switch off Status LEDs */
623*4882a593Smuzhiyun #if (CONFIG_SYS_BOARD_VERSION == 2)
624*4882a593Smuzhiyun gpio_request(IMX_GPIO_NR(6, 16), "LED yellow"); /* 176 */
625*4882a593Smuzhiyun gpio_direction_output(IMX_GPIO_NR(6, 16), 1);
626*4882a593Smuzhiyun gpio_request(IMX_GPIO_NR(2, 28), "LED red"); /* 60 */
627*4882a593Smuzhiyun gpio_direction_output(IMX_GPIO_NR(2, 28), 1);
628*4882a593Smuzhiyun gpio_request(IMX_GPIO_NR(5, 4), "LED green"); /* 132 */
629*4882a593Smuzhiyun gpio_direction_output(IMX_GPIO_NR(5, 4), 1);
630*4882a593Smuzhiyun gpio_request(IMX_GPIO_NR(2, 29), "LED blue"); /* 61 */
631*4882a593Smuzhiyun gpio_direction_output(IMX_GPIO_NR(2, 29), 1);
632*4882a593Smuzhiyun #elif (CONFIG_SYS_BOARD_VERSION == 3)
633*4882a593Smuzhiyun gpio_request(IMX_GPIO_NR(6, 16), "LED yellow"); /* 176 */
634*4882a593Smuzhiyun gpio_direction_output(IMX_GPIO_NR(6, 16), 0);
635*4882a593Smuzhiyun gpio_request(IMX_GPIO_NR(5, 0), "LED red"); /* 128 */
636*4882a593Smuzhiyun gpio_direction_output(IMX_GPIO_NR(5, 0), 0);
637*4882a593Smuzhiyun gpio_request(IMX_GPIO_NR(5, 4), "LED green"); /* 132 */
638*4882a593Smuzhiyun gpio_direction_output(IMX_GPIO_NR(5, 4), 0);
639*4882a593Smuzhiyun gpio_request(IMX_GPIO_NR(2, 29), "LED blue"); /* 61 */
640*4882a593Smuzhiyun gpio_direction_output(IMX_GPIO_NR(2, 29), 0);
641*4882a593Smuzhiyun #endif
642*4882a593Smuzhiyun }
643*4882a593Smuzhiyun
setup_board_spi(void)644*4882a593Smuzhiyun static void setup_board_spi(void)
645*4882a593Smuzhiyun {
646*4882a593Smuzhiyun /* enable spi bus #2 SS drivers (and spi bus #4 SS1 for rev2b) */
647*4882a593Smuzhiyun gpio_direction_output(IMX_GPIO_NR(6, 6), 1);
648*4882a593Smuzhiyun }
649*4882a593Smuzhiyun
board_late_init(void)650*4882a593Smuzhiyun int board_late_init(void)
651*4882a593Smuzhiyun {
652*4882a593Smuzhiyun char *my_bootdelay;
653*4882a593Smuzhiyun char bootmode = 0;
654*4882a593Smuzhiyun char const *panel = env_get("panel");
655*4882a593Smuzhiyun
656*4882a593Smuzhiyun /*
657*4882a593Smuzhiyun * Check the boot-source. If booting from NOR Flash,
658*4882a593Smuzhiyun * disable bootdelay
659*4882a593Smuzhiyun */
660*4882a593Smuzhiyun gpio_request(IMX_GPIO_NR(7, 6), "bootsel0");
661*4882a593Smuzhiyun gpio_direction_input(IMX_GPIO_NR(7, 6));
662*4882a593Smuzhiyun gpio_request(IMX_GPIO_NR(7, 7), "bootsel1");
663*4882a593Smuzhiyun gpio_direction_input(IMX_GPIO_NR(7, 7));
664*4882a593Smuzhiyun gpio_request(IMX_GPIO_NR(7, 1), "bootsel2");
665*4882a593Smuzhiyun gpio_direction_input(IMX_GPIO_NR(7, 1));
666*4882a593Smuzhiyun bootmode |= (gpio_get_value(IMX_GPIO_NR(7, 6)) ? 1 : 0) << 0;
667*4882a593Smuzhiyun bootmode |= (gpio_get_value(IMX_GPIO_NR(7, 7)) ? 1 : 0) << 1;
668*4882a593Smuzhiyun bootmode |= (gpio_get_value(IMX_GPIO_NR(7, 1)) ? 1 : 0) << 2;
669*4882a593Smuzhiyun
670*4882a593Smuzhiyun if (bootmode == 7) {
671*4882a593Smuzhiyun my_bootdelay = env_get("nor_bootdelay");
672*4882a593Smuzhiyun if (my_bootdelay != NULL)
673*4882a593Smuzhiyun env_set("bootdelay", my_bootdelay);
674*4882a593Smuzhiyun else
675*4882a593Smuzhiyun env_set("bootdelay", "-2");
676*4882a593Smuzhiyun }
677*4882a593Smuzhiyun
678*4882a593Smuzhiyun /* if we have the lg panel, we can initialze it now */
679*4882a593Smuzhiyun if (panel)
680*4882a593Smuzhiyun if (!strcmp(panel, displays[1].mode.name))
681*4882a593Smuzhiyun lg4573_spi_startup(CONFIG_LG4573_BUS,
682*4882a593Smuzhiyun CONFIG_LG4573_CS,
683*4882a593Smuzhiyun 10000000, SPI_MODE_0);
684*4882a593Smuzhiyun
685*4882a593Smuzhiyun return 0;
686*4882a593Smuzhiyun }
687