1d67b0d97SEric Nelson /*
2d67b0d97SEric Nelson * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
3d67b0d97SEric Nelson * Copyright (C) 2013, Boundary Devices <info@boundarydevices.com>
4d67b0d97SEric Nelson *
51a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+
6d67b0d97SEric Nelson */
7d67b0d97SEric Nelson
8d67b0d97SEric Nelson #include <common.h>
9d67b0d97SEric Nelson #include <asm/io.h>
10d67b0d97SEric Nelson #include <asm/arch/clock.h>
11d67b0d97SEric Nelson #include <asm/arch/imx-regs.h>
12d67b0d97SEric Nelson #include <asm/arch/iomux.h>
13d67b0d97SEric Nelson #include <asm/arch/sys_proto.h>
14d67b0d97SEric Nelson #include <malloc.h>
15d67b0d97SEric Nelson #include <asm/arch/mx6-pins.h>
161221ce45SMasahiro Yamada #include <linux/errno.h>
17d67b0d97SEric Nelson #include <asm/gpio.h>
18552a848eSStefano Babic #include <asm/mach-imx/iomux-v3.h>
19552a848eSStefano Babic #include <asm/mach-imx/mxc_i2c.h>
20552a848eSStefano Babic #include <asm/mach-imx/sata.h>
21552a848eSStefano Babic #include <asm/mach-imx/spi.h>
22552a848eSStefano Babic #include <asm/mach-imx/boot_mode.h>
23552a848eSStefano Babic #include <asm/mach-imx/video.h>
24d67b0d97SEric Nelson #include <mmc.h>
25d67b0d97SEric Nelson #include <fsl_esdhc.h>
26d67b0d97SEric Nelson #include <micrel.h>
27d67b0d97SEric Nelson #include <miiphy.h>
28d67b0d97SEric Nelson #include <netdev.h>
29d67b0d97SEric Nelson #include <asm/arch/crm_regs.h>
30d67b0d97SEric Nelson #include <asm/arch/mxc_hdmi.h>
31d67b0d97SEric Nelson #include <i2c.h>
329fc42527SEric Nelson #include <input.h>
339fc42527SEric Nelson #include <netdev.h>
34e162c6b1SMateusz Kulikowski #include <usb/ehci-ci.h>
35d67b0d97SEric Nelson
36d67b0d97SEric Nelson DECLARE_GLOBAL_DATA_PTR;
3708ce074eSTroy Kisky #define GP_USB_OTG_PWR IMX_GPIO_NR(3, 22)
38d67b0d97SEric Nelson
397e2173cfSBenoît Thébaudeau #define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
407e2173cfSBenoît Thébaudeau PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
417e2173cfSBenoît Thébaudeau PAD_CTL_SRE_FAST | PAD_CTL_HYS)
42d67b0d97SEric Nelson
437e2173cfSBenoît Thébaudeau #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \
447e2173cfSBenoît Thébaudeau PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \
457e2173cfSBenoît Thébaudeau PAD_CTL_SRE_FAST | PAD_CTL_HYS)
46d67b0d97SEric Nelson
477e2173cfSBenoît Thébaudeau #define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
487e2173cfSBenoît Thébaudeau PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
49d67b0d97SEric Nelson
507e2173cfSBenoît Thébaudeau #define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \
51d67b0d97SEric Nelson PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
52d67b0d97SEric Nelson
537e2173cfSBenoît Thébaudeau #define BUTTON_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
547e2173cfSBenoît Thébaudeau PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
55d67b0d97SEric Nelson
567e2173cfSBenoît Thébaudeau #define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
577e2173cfSBenoît Thébaudeau PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
58d67b0d97SEric Nelson PAD_CTL_ODE | PAD_CTL_SRE_FAST)
59d67b0d97SEric Nelson
607e2173cfSBenoît Thébaudeau #define WEAK_PULLUP (PAD_CTL_PUS_100K_UP | \
617e2173cfSBenoît Thébaudeau PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
62d67b0d97SEric Nelson PAD_CTL_SRE_SLOW)
63d67b0d97SEric Nelson
647e2173cfSBenoît Thébaudeau #define WEAK_PULLDOWN (PAD_CTL_PUS_100K_DOWN | \
657e2173cfSBenoît Thébaudeau PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
667e2173cfSBenoît Thébaudeau PAD_CTL_HYS | PAD_CTL_SRE_SLOW)
67d67b0d97SEric Nelson
68d67b0d97SEric Nelson #define OUTPUT_40OHM (PAD_CTL_SPEED_MED|PAD_CTL_DSE_40ohm)
69d67b0d97SEric Nelson
dram_init(void)70d67b0d97SEric Nelson int dram_init(void)
71d67b0d97SEric Nelson {
7219a0f7faSfabio.estevam@freescale.com gd->ram_size = ((ulong)CONFIG_DDR_MB * 1024 * 1024);
73d67b0d97SEric Nelson
74d67b0d97SEric Nelson return 0;
75d67b0d97SEric Nelson }
76d67b0d97SEric Nelson
779fc42527SEric Nelson static iomux_v3_cfg_t const uart1_pads[] = {
7810fda487SEric Nelson MX6_PAD_SD3_DAT6__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
7910fda487SEric Nelson MX6_PAD_SD3_DAT7__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
80d67b0d97SEric Nelson };
81d67b0d97SEric Nelson
829fc42527SEric Nelson static iomux_v3_cfg_t const uart2_pads[] = {
8310fda487SEric Nelson MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
8410fda487SEric Nelson MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
85d67b0d97SEric Nelson };
86d67b0d97SEric Nelson
87d67b0d97SEric Nelson #define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
88d67b0d97SEric Nelson
89d67b0d97SEric Nelson /* I2C1, SGTL5000 */
909fc42527SEric Nelson static struct i2c_pads_info i2c_pad_info0 = {
91d67b0d97SEric Nelson .scl = {
92d67b0d97SEric Nelson .i2c_mode = MX6_PAD_EIM_D21__I2C1_SCL | PC,
9310fda487SEric Nelson .gpio_mode = MX6_PAD_EIM_D21__GPIO3_IO21 | PC,
94d67b0d97SEric Nelson .gp = IMX_GPIO_NR(3, 21)
95d67b0d97SEric Nelson },
96d67b0d97SEric Nelson .sda = {
97d67b0d97SEric Nelson .i2c_mode = MX6_PAD_EIM_D28__I2C1_SDA | PC,
9810fda487SEric Nelson .gpio_mode = MX6_PAD_EIM_D28__GPIO3_IO28 | PC,
99d67b0d97SEric Nelson .gp = IMX_GPIO_NR(3, 28)
100d67b0d97SEric Nelson }
101d67b0d97SEric Nelson };
102d67b0d97SEric Nelson
103d67b0d97SEric Nelson /* I2C2 Camera, MIPI */
1049fc42527SEric Nelson static struct i2c_pads_info i2c_pad_info1 = {
105d67b0d97SEric Nelson .scl = {
106d67b0d97SEric Nelson .i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL | PC,
10710fda487SEric Nelson .gpio_mode = MX6_PAD_KEY_COL3__GPIO4_IO12 | PC,
108d67b0d97SEric Nelson .gp = IMX_GPIO_NR(4, 12)
109d67b0d97SEric Nelson },
110d67b0d97SEric Nelson .sda = {
111d67b0d97SEric Nelson .i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | PC,
11210fda487SEric Nelson .gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13 | PC,
113d67b0d97SEric Nelson .gp = IMX_GPIO_NR(4, 13)
114d67b0d97SEric Nelson }
115d67b0d97SEric Nelson };
116d67b0d97SEric Nelson
117d67b0d97SEric Nelson /* I2C3, J15 - RGB connector */
1189fc42527SEric Nelson static struct i2c_pads_info i2c_pad_info2 = {
119d67b0d97SEric Nelson .scl = {
120d67b0d97SEric Nelson .i2c_mode = MX6_PAD_GPIO_5__I2C3_SCL | PC,
12110fda487SEric Nelson .gpio_mode = MX6_PAD_GPIO_5__GPIO1_IO05 | PC,
122d67b0d97SEric Nelson .gp = IMX_GPIO_NR(1, 5)
123d67b0d97SEric Nelson },
124d67b0d97SEric Nelson .sda = {
125d67b0d97SEric Nelson .i2c_mode = MX6_PAD_GPIO_16__I2C3_SDA | PC,
12610fda487SEric Nelson .gpio_mode = MX6_PAD_GPIO_16__GPIO7_IO11 | PC,
127d67b0d97SEric Nelson .gp = IMX_GPIO_NR(7, 11)
128d67b0d97SEric Nelson }
129d67b0d97SEric Nelson };
130d67b0d97SEric Nelson
13141612472SEric Nelson static iomux_v3_cfg_t const usdhc2_pads[] = {
13241612472SEric Nelson MX6_PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
13341612472SEric Nelson MX6_PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
13441612472SEric Nelson MX6_PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
13541612472SEric Nelson MX6_PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
13641612472SEric Nelson MX6_PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
13741612472SEric Nelson MX6_PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
13841612472SEric Nelson };
13941612472SEric Nelson
1409fc42527SEric Nelson static iomux_v3_cfg_t const usdhc3_pads[] = {
14110fda487SEric Nelson MX6_PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
14210fda487SEric Nelson MX6_PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
14310fda487SEric Nelson MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
14410fda487SEric Nelson MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
14510fda487SEric Nelson MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
14610fda487SEric Nelson MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
14710fda487SEric Nelson MX6_PAD_SD3_DAT5__GPIO7_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
148d67b0d97SEric Nelson };
149d67b0d97SEric Nelson
1509fc42527SEric Nelson static iomux_v3_cfg_t const usdhc4_pads[] = {
15110fda487SEric Nelson MX6_PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
15210fda487SEric Nelson MX6_PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
15310fda487SEric Nelson MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
15410fda487SEric Nelson MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
15510fda487SEric Nelson MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
15610fda487SEric Nelson MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
15710fda487SEric Nelson MX6_PAD_NANDF_D6__GPIO2_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
158d67b0d97SEric Nelson };
159d67b0d97SEric Nelson
1609fc42527SEric Nelson static iomux_v3_cfg_t const enet_pads1[] = {
161d67b0d97SEric Nelson MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
162d67b0d97SEric Nelson MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
16310fda487SEric Nelson MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
16410fda487SEric Nelson MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
16510fda487SEric Nelson MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
16610fda487SEric Nelson MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
16710fda487SEric Nelson MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
168d67b0d97SEric Nelson MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
169d67b0d97SEric Nelson MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
170d67b0d97SEric Nelson /* pin 35 - 1 (PHY_AD2) on reset */
17110fda487SEric Nelson MX6_PAD_RGMII_RXC__GPIO6_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL),
172d67b0d97SEric Nelson /* pin 32 - 1 - (MODE0) all */
17310fda487SEric Nelson MX6_PAD_RGMII_RD0__GPIO6_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL),
174d67b0d97SEric Nelson /* pin 31 - 1 - (MODE1) all */
17510fda487SEric Nelson MX6_PAD_RGMII_RD1__GPIO6_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
176d67b0d97SEric Nelson /* pin 28 - 1 - (MODE2) all */
17710fda487SEric Nelson MX6_PAD_RGMII_RD2__GPIO6_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL),
178d67b0d97SEric Nelson /* pin 27 - 1 - (MODE3) all */
17910fda487SEric Nelson MX6_PAD_RGMII_RD3__GPIO6_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
180d67b0d97SEric Nelson /* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
18110fda487SEric Nelson MX6_PAD_RGMII_RX_CTL__GPIO6_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL),
182d67b0d97SEric Nelson /* pin 42 PHY nRST */
18310fda487SEric Nelson MX6_PAD_EIM_D23__GPIO3_IO23 | MUX_PAD_CTRL(NO_PAD_CTRL),
18410fda487SEric Nelson MX6_PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
185d67b0d97SEric Nelson };
186d67b0d97SEric Nelson
1879fc42527SEric Nelson static iomux_v3_cfg_t const enet_pads2[] = {
18810fda487SEric Nelson MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
18910fda487SEric Nelson MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
19010fda487SEric Nelson MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
19110fda487SEric Nelson MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
19210fda487SEric Nelson MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
193d67b0d97SEric Nelson MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
194d67b0d97SEric Nelson };
195d67b0d97SEric Nelson
19608ce074eSTroy Kisky static iomux_v3_cfg_t const misc_pads[] = {
19708ce074eSTroy Kisky MX6_PAD_GPIO_1__USB_OTG_ID | MUX_PAD_CTRL(WEAK_PULLUP),
19810fda487SEric Nelson MX6_PAD_KEY_COL4__USB_OTG_OC | MUX_PAD_CTRL(WEAK_PULLUP),
19910fda487SEric Nelson MX6_PAD_EIM_D30__USB_H1_OC | MUX_PAD_CTRL(WEAK_PULLUP),
20008ce074eSTroy Kisky /* OTG Power enable */
20110fda487SEric Nelson MX6_PAD_EIM_D22__GPIO3_IO22 | MUX_PAD_CTRL(OUTPUT_40OHM),
20208ce074eSTroy Kisky };
20308ce074eSTroy Kisky
204d67b0d97SEric Nelson /* wl1271 pads on nitrogen6x */
2059fc42527SEric Nelson static iomux_v3_cfg_t const wl12xx_pads[] = {
20610fda487SEric Nelson (MX6_PAD_NANDF_CS1__GPIO6_IO14 & ~MUX_PAD_CTRL_MASK)
207d67b0d97SEric Nelson | MUX_PAD_CTRL(WEAK_PULLDOWN),
20810fda487SEric Nelson (MX6_PAD_NANDF_CS2__GPIO6_IO15 & ~MUX_PAD_CTRL_MASK)
209d67b0d97SEric Nelson | MUX_PAD_CTRL(OUTPUT_40OHM),
21010fda487SEric Nelson (MX6_PAD_NANDF_CS3__GPIO6_IO16 & ~MUX_PAD_CTRL_MASK)
211d67b0d97SEric Nelson | MUX_PAD_CTRL(OUTPUT_40OHM),
212d67b0d97SEric Nelson };
213d67b0d97SEric Nelson #define WL12XX_WL_IRQ_GP IMX_GPIO_NR(6, 14)
214d67b0d97SEric Nelson #define WL12XX_WL_ENABLE_GP IMX_GPIO_NR(6, 15)
215d67b0d97SEric Nelson #define WL12XX_BT_ENABLE_GP IMX_GPIO_NR(6, 16)
216d67b0d97SEric Nelson
217d67b0d97SEric Nelson /* Button assignments for J14 */
218d67b0d97SEric Nelson static iomux_v3_cfg_t const button_pads[] = {
219d67b0d97SEric Nelson /* Menu */
22010fda487SEric Nelson MX6_PAD_NANDF_D1__GPIO2_IO01 | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
221d67b0d97SEric Nelson /* Back */
22210fda487SEric Nelson MX6_PAD_NANDF_D2__GPIO2_IO02 | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
223d67b0d97SEric Nelson /* Labelled Search (mapped to Power under Android) */
22410fda487SEric Nelson MX6_PAD_NANDF_D3__GPIO2_IO03 | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
225d67b0d97SEric Nelson /* Home */
22610fda487SEric Nelson MX6_PAD_NANDF_D4__GPIO2_IO04 | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
227d67b0d97SEric Nelson /* Volume Down */
22810fda487SEric Nelson MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
229d67b0d97SEric Nelson /* Volume Up */
23010fda487SEric Nelson MX6_PAD_GPIO_18__GPIO7_IO13 | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
231d67b0d97SEric Nelson };
232d67b0d97SEric Nelson
setup_iomux_enet(void)233d67b0d97SEric Nelson static void setup_iomux_enet(void)
234d67b0d97SEric Nelson {
235d67b0d97SEric Nelson gpio_direction_output(IMX_GPIO_NR(3, 23), 0); /* SABRE Lite PHY rst */
236d67b0d97SEric Nelson gpio_direction_output(IMX_GPIO_NR(1, 27), 0); /* Nitrogen6X PHY rst */
237d67b0d97SEric Nelson gpio_direction_output(IMX_GPIO_NR(6, 30), 1);
238d67b0d97SEric Nelson gpio_direction_output(IMX_GPIO_NR(6, 25), 1);
239d67b0d97SEric Nelson gpio_direction_output(IMX_GPIO_NR(6, 27), 1);
240d67b0d97SEric Nelson gpio_direction_output(IMX_GPIO_NR(6, 28), 1);
241d67b0d97SEric Nelson gpio_direction_output(IMX_GPIO_NR(6, 29), 1);
242d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(enet_pads1, ARRAY_SIZE(enet_pads1));
243d67b0d97SEric Nelson gpio_direction_output(IMX_GPIO_NR(6, 24), 1);
244d67b0d97SEric Nelson
245d67b0d97SEric Nelson /* Need delay 10ms according to KSZ9021 spec */
246d67b0d97SEric Nelson udelay(1000 * 10);
247d67b0d97SEric Nelson gpio_set_value(IMX_GPIO_NR(3, 23), 1); /* SABRE Lite PHY reset */
248d67b0d97SEric Nelson gpio_set_value(IMX_GPIO_NR(1, 27), 1); /* Nitrogen6X PHY reset */
249d67b0d97SEric Nelson
250d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(enet_pads2, ARRAY_SIZE(enet_pads2));
251adc4a2bdSTroy Kisky udelay(100); /* Wait 100 us before using mii interface */
252d67b0d97SEric Nelson }
253d67b0d97SEric Nelson
2549fc42527SEric Nelson static iomux_v3_cfg_t const usb_pads[] = {
25510fda487SEric Nelson MX6_PAD_GPIO_17__GPIO7_IO12 | MUX_PAD_CTRL(NO_PAD_CTRL),
256d67b0d97SEric Nelson };
257d67b0d97SEric Nelson
setup_iomux_uart(void)258d67b0d97SEric Nelson static void setup_iomux_uart(void)
259d67b0d97SEric Nelson {
260d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
261d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
262d67b0d97SEric Nelson }
263d67b0d97SEric Nelson
264d67b0d97SEric Nelson #ifdef CONFIG_USB_EHCI_MX6
board_ehci_hcd_init(int port)265d67b0d97SEric Nelson int board_ehci_hcd_init(int port)
266d67b0d97SEric Nelson {
267d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(usb_pads, ARRAY_SIZE(usb_pads));
268d67b0d97SEric Nelson
269d67b0d97SEric Nelson /* Reset USB hub */
270d67b0d97SEric Nelson gpio_direction_output(IMX_GPIO_NR(7, 12), 0);
271d67b0d97SEric Nelson mdelay(2);
272d67b0d97SEric Nelson gpio_set_value(IMX_GPIO_NR(7, 12), 1);
273d67b0d97SEric Nelson
274d67b0d97SEric Nelson return 0;
275d67b0d97SEric Nelson }
27608ce074eSTroy Kisky
board_ehci_power(int port,int on)27708ce074eSTroy Kisky int board_ehci_power(int port, int on)
27808ce074eSTroy Kisky {
27908ce074eSTroy Kisky if (port)
28008ce074eSTroy Kisky return 0;
28108ce074eSTroy Kisky gpio_set_value(GP_USB_OTG_PWR, on);
28208ce074eSTroy Kisky return 0;
28308ce074eSTroy Kisky }
28408ce074eSTroy Kisky
285d67b0d97SEric Nelson #endif
286d67b0d97SEric Nelson
287d67b0d97SEric Nelson #ifdef CONFIG_FSL_ESDHC
2889fc42527SEric Nelson static struct fsl_esdhc_cfg usdhc_cfg[2] = {
289d67b0d97SEric Nelson {USDHC3_BASE_ADDR},
290d67b0d97SEric Nelson {USDHC4_BASE_ADDR},
291d67b0d97SEric Nelson };
292d67b0d97SEric Nelson
board_mmc_getcd(struct mmc * mmc)293d67b0d97SEric Nelson int board_mmc_getcd(struct mmc *mmc)
294d67b0d97SEric Nelson {
295d67b0d97SEric Nelson struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
296213e9e33STroy Kisky int gp_cd = (cfg->esdhc_base == USDHC3_BASE_ADDR) ? IMX_GPIO_NR(7, 0) :
297213e9e33STroy Kisky IMX_GPIO_NR(2, 6);
298d67b0d97SEric Nelson
299213e9e33STroy Kisky gpio_direction_input(gp_cd);
300213e9e33STroy Kisky return !gpio_get_value(gp_cd);
301d67b0d97SEric Nelson }
302d67b0d97SEric Nelson
board_mmc_init(bd_t * bis)303d67b0d97SEric Nelson int board_mmc_init(bd_t *bis)
304d67b0d97SEric Nelson {
305612f2dc0SFabio Estevam int ret;
306d67b0d97SEric Nelson u32 index = 0;
307d67b0d97SEric Nelson
308d67b0d97SEric Nelson usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
309d67b0d97SEric Nelson usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
310d67b0d97SEric Nelson
311aad4659aSAbbas Raza usdhc_cfg[0].max_bus_width = 4;
312aad4659aSAbbas Raza usdhc_cfg[1].max_bus_width = 4;
313aad4659aSAbbas Raza
314d67b0d97SEric Nelson for (index = 0; index < CONFIG_SYS_FSL_USDHC_NUM; ++index) {
315d67b0d97SEric Nelson switch (index) {
316d67b0d97SEric Nelson case 0:
317d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(
318d67b0d97SEric Nelson usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
319d67b0d97SEric Nelson break;
320d67b0d97SEric Nelson case 1:
321d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(
322d67b0d97SEric Nelson usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
323d67b0d97SEric Nelson break;
324d67b0d97SEric Nelson default:
325d67b0d97SEric Nelson printf("Warning: you configured more USDHC controllers"
326d67b0d97SEric Nelson "(%d) then supported by the board (%d)\n",
327d67b0d97SEric Nelson index + 1, CONFIG_SYS_FSL_USDHC_NUM);
328612f2dc0SFabio Estevam return -EINVAL;
329d67b0d97SEric Nelson }
330d67b0d97SEric Nelson
331612f2dc0SFabio Estevam ret = fsl_esdhc_initialize(bis, &usdhc_cfg[index]);
332612f2dc0SFabio Estevam if (ret)
333612f2dc0SFabio Estevam return ret;
334d67b0d97SEric Nelson }
335d67b0d97SEric Nelson
336612f2dc0SFabio Estevam return 0;
337d67b0d97SEric Nelson }
338d67b0d97SEric Nelson #endif
339d67b0d97SEric Nelson
340d67b0d97SEric Nelson #ifdef CONFIG_MXC_SPI
board_spi_cs_gpio(unsigned bus,unsigned cs)341155fa9afSNikita Kiryanov int board_spi_cs_gpio(unsigned bus, unsigned cs)
342155fa9afSNikita Kiryanov {
343155fa9afSNikita Kiryanov return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(3, 19)) : -1;
344155fa9afSNikita Kiryanov }
345155fa9afSNikita Kiryanov
3469fc42527SEric Nelson static iomux_v3_cfg_t const ecspi1_pads[] = {
347d67b0d97SEric Nelson /* SS1 */
3483b31605aSFabio Estevam MX6_PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
349d67b0d97SEric Nelson MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
350d67b0d97SEric Nelson MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
351d67b0d97SEric Nelson MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
352d67b0d97SEric Nelson };
353d67b0d97SEric Nelson
setup_spi(void)3549fc42527SEric Nelson static void setup_spi(void)
355d67b0d97SEric Nelson {
356d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(ecspi1_pads,
357d67b0d97SEric Nelson ARRAY_SIZE(ecspi1_pads));
358d67b0d97SEric Nelson }
359d67b0d97SEric Nelson #endif
360d67b0d97SEric Nelson
board_phy_config(struct phy_device * phydev)361d67b0d97SEric Nelson int board_phy_config(struct phy_device *phydev)
362d67b0d97SEric Nelson {
363d67b0d97SEric Nelson /* min rx data delay */
364d67b0d97SEric Nelson ksz9021_phy_extended_write(phydev,
365d67b0d97SEric Nelson MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0x0);
366d67b0d97SEric Nelson /* min tx data delay */
367d67b0d97SEric Nelson ksz9021_phy_extended_write(phydev,
368d67b0d97SEric Nelson MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW, 0x0);
369d67b0d97SEric Nelson /* max rx/tx clock delay, min rx/tx control */
370d67b0d97SEric Nelson ksz9021_phy_extended_write(phydev,
371d67b0d97SEric Nelson MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, 0xf0f0);
372d67b0d97SEric Nelson if (phydev->drv->config)
373d67b0d97SEric Nelson phydev->drv->config(phydev);
374d67b0d97SEric Nelson
375d67b0d97SEric Nelson return 0;
376d67b0d97SEric Nelson }
377d67b0d97SEric Nelson
board_eth_init(bd_t * bis)378d67b0d97SEric Nelson int board_eth_init(bd_t *bis)
379d67b0d97SEric Nelson {
380d67b0d97SEric Nelson uint32_t base = IMX_FEC_BASE;
381d67b0d97SEric Nelson struct mii_dev *bus = NULL;
382d67b0d97SEric Nelson struct phy_device *phydev = NULL;
383d67b0d97SEric Nelson int ret;
384d67b0d97SEric Nelson
385d67b0d97SEric Nelson setup_iomux_enet();
386d67b0d97SEric Nelson
387d67b0d97SEric Nelson #ifdef CONFIG_FEC_MXC
388d67b0d97SEric Nelson bus = fec_get_miibus(base, -1);
389d67b0d97SEric Nelson if (!bus)
390747472bbSFabio Estevam return -EINVAL;
391d67b0d97SEric Nelson /* scan phy 4,5,6,7 */
392d67b0d97SEric Nelson phydev = phy_find_by_mask(bus, (0xf << 4), PHY_INTERFACE_MODE_RGMII);
393d67b0d97SEric Nelson if (!phydev) {
394747472bbSFabio Estevam ret = -EINVAL;
395747472bbSFabio Estevam goto free_bus;
396d67b0d97SEric Nelson }
397d67b0d97SEric Nelson printf("using phy at %d\n", phydev->addr);
398d67b0d97SEric Nelson ret = fec_probe(bis, -1, base, bus, phydev);
399747472bbSFabio Estevam if (ret)
400747472bbSFabio Estevam goto free_phydev;
401d67b0d97SEric Nelson #endif
40208ce074eSTroy Kisky
403f016f8caSMarek Vasut #ifdef CONFIG_CI_UDC
40408ce074eSTroy Kisky /* For otg ethernet*/
40508ce074eSTroy Kisky usb_eth_initialize(bis);
40608ce074eSTroy Kisky #endif
407d67b0d97SEric Nelson return 0;
408747472bbSFabio Estevam
409747472bbSFabio Estevam free_phydev:
410747472bbSFabio Estevam free(phydev);
411747472bbSFabio Estevam free_bus:
412747472bbSFabio Estevam free(bus);
413747472bbSFabio Estevam return ret;
414d67b0d97SEric Nelson }
415d67b0d97SEric Nelson
setup_buttons(void)416d67b0d97SEric Nelson static void setup_buttons(void)
417d67b0d97SEric Nelson {
418d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(button_pads,
419d67b0d97SEric Nelson ARRAY_SIZE(button_pads));
420d67b0d97SEric Nelson }
421d67b0d97SEric Nelson
422d67b0d97SEric Nelson #if defined(CONFIG_VIDEO_IPUV3)
423d67b0d97SEric Nelson
424d67b0d97SEric Nelson static iomux_v3_cfg_t const backlight_pads[] = {
425d67b0d97SEric Nelson /* Backlight on RGB connector: J15 */
42610fda487SEric Nelson MX6_PAD_SD1_DAT3__GPIO1_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL),
427d67b0d97SEric Nelson #define RGB_BACKLIGHT_GP IMX_GPIO_NR(1, 21)
428d67b0d97SEric Nelson
429d67b0d97SEric Nelson /* Backlight on LVDS connector: J6 */
43010fda487SEric Nelson MX6_PAD_SD1_CMD__GPIO1_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
431d67b0d97SEric Nelson #define LVDS_BACKLIGHT_GP IMX_GPIO_NR(1, 18)
432d67b0d97SEric Nelson };
433d67b0d97SEric Nelson
434d67b0d97SEric Nelson static iomux_v3_cfg_t const rgb_pads[] = {
435d67b0d97SEric Nelson MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
436d67b0d97SEric Nelson MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15,
43710fda487SEric Nelson MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02,
43810fda487SEric Nelson MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03,
43910fda487SEric Nelson MX6_PAD_DI0_PIN4__GPIO4_IO20,
44010fda487SEric Nelson MX6_PAD_DISP0_DAT0__IPU1_DISP0_DATA00,
44110fda487SEric Nelson MX6_PAD_DISP0_DAT1__IPU1_DISP0_DATA01,
44210fda487SEric Nelson MX6_PAD_DISP0_DAT2__IPU1_DISP0_DATA02,
44310fda487SEric Nelson MX6_PAD_DISP0_DAT3__IPU1_DISP0_DATA03,
44410fda487SEric Nelson MX6_PAD_DISP0_DAT4__IPU1_DISP0_DATA04,
44510fda487SEric Nelson MX6_PAD_DISP0_DAT5__IPU1_DISP0_DATA05,
44610fda487SEric Nelson MX6_PAD_DISP0_DAT6__IPU1_DISP0_DATA06,
44710fda487SEric Nelson MX6_PAD_DISP0_DAT7__IPU1_DISP0_DATA07,
44810fda487SEric Nelson MX6_PAD_DISP0_DAT8__IPU1_DISP0_DATA08,
44910fda487SEric Nelson MX6_PAD_DISP0_DAT9__IPU1_DISP0_DATA09,
45010fda487SEric Nelson MX6_PAD_DISP0_DAT10__IPU1_DISP0_DATA10,
45110fda487SEric Nelson MX6_PAD_DISP0_DAT11__IPU1_DISP0_DATA11,
45210fda487SEric Nelson MX6_PAD_DISP0_DAT12__IPU1_DISP0_DATA12,
45310fda487SEric Nelson MX6_PAD_DISP0_DAT13__IPU1_DISP0_DATA13,
45410fda487SEric Nelson MX6_PAD_DISP0_DAT14__IPU1_DISP0_DATA14,
45510fda487SEric Nelson MX6_PAD_DISP0_DAT15__IPU1_DISP0_DATA15,
45610fda487SEric Nelson MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16,
45710fda487SEric Nelson MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17,
45810fda487SEric Nelson MX6_PAD_DISP0_DAT18__IPU1_DISP0_DATA18,
45910fda487SEric Nelson MX6_PAD_DISP0_DAT19__IPU1_DISP0_DATA19,
46010fda487SEric Nelson MX6_PAD_DISP0_DAT20__IPU1_DISP0_DATA20,
46110fda487SEric Nelson MX6_PAD_DISP0_DAT21__IPU1_DISP0_DATA21,
46210fda487SEric Nelson MX6_PAD_DISP0_DAT22__IPU1_DISP0_DATA22,
46310fda487SEric Nelson MX6_PAD_DISP0_DAT23__IPU1_DISP0_DATA23,
464d67b0d97SEric Nelson };
465d67b0d97SEric Nelson
do_enable_hdmi(struct display_info_t const * dev)4665ea7f0e3SPardeep Kumar Singla static void do_enable_hdmi(struct display_info_t const *dev)
467d67b0d97SEric Nelson {
4685ea7f0e3SPardeep Kumar Singla imx_enable_hdmi_phy();
469d67b0d97SEric Nelson }
470d67b0d97SEric Nelson
detect_i2c(struct display_info_t const * dev)471d67b0d97SEric Nelson static int detect_i2c(struct display_info_t const *dev)
472d67b0d97SEric Nelson {
473d67b0d97SEric Nelson return ((0 == i2c_set_bus_num(dev->bus))
474d67b0d97SEric Nelson &&
475d67b0d97SEric Nelson (0 == i2c_probe(dev->addr)));
476d67b0d97SEric Nelson }
477d67b0d97SEric Nelson
enable_lvds(struct display_info_t const * dev)478d67b0d97SEric Nelson static void enable_lvds(struct display_info_t const *dev)
479d67b0d97SEric Nelson {
480d67b0d97SEric Nelson struct iomuxc *iomux = (struct iomuxc *)
481d67b0d97SEric Nelson IOMUXC_BASE_ADDR;
482d67b0d97SEric Nelson u32 reg = readl(&iomux->gpr[2]);
483d67b0d97SEric Nelson reg |= IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT;
484d67b0d97SEric Nelson writel(reg, &iomux->gpr[2]);
485d67b0d97SEric Nelson gpio_direction_output(LVDS_BACKLIGHT_GP, 1);
486d67b0d97SEric Nelson }
487d67b0d97SEric Nelson
enable_lvds_jeida(struct display_info_t const * dev)4884328fb05SRobert Winkler static void enable_lvds_jeida(struct display_info_t const *dev)
4894328fb05SRobert Winkler {
4904328fb05SRobert Winkler struct iomuxc *iomux = (struct iomuxc *)
4914328fb05SRobert Winkler IOMUXC_BASE_ADDR;
4924328fb05SRobert Winkler u32 reg = readl(&iomux->gpr[2]);
4934328fb05SRobert Winkler reg |= IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT
4944328fb05SRobert Winkler |IOMUXC_GPR2_BIT_MAPPING_CH0_JEIDA;
4954328fb05SRobert Winkler writel(reg, &iomux->gpr[2]);
4964328fb05SRobert Winkler gpio_direction_output(LVDS_BACKLIGHT_GP, 1);
4974328fb05SRobert Winkler }
4984328fb05SRobert Winkler
enable_rgb(struct display_info_t const * dev)499d67b0d97SEric Nelson static void enable_rgb(struct display_info_t const *dev)
500d67b0d97SEric Nelson {
501d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(
502d67b0d97SEric Nelson rgb_pads,
503d67b0d97SEric Nelson ARRAY_SIZE(rgb_pads));
504d67b0d97SEric Nelson gpio_direction_output(RGB_BACKLIGHT_GP, 1);
505d67b0d97SEric Nelson }
506d67b0d97SEric Nelson
507a47e4495SEric Benard struct display_info_t const displays[] = {{
508ce9507b7SEric Nelson .bus = 1,
509ce9507b7SEric Nelson .addr = 0x50,
510d67b0d97SEric Nelson .pixfmt = IPU_PIX_FMT_RGB24,
511ce9507b7SEric Nelson .detect = detect_i2c,
5125ea7f0e3SPardeep Kumar Singla .enable = do_enable_hdmi,
513d67b0d97SEric Nelson .mode = {
514d67b0d97SEric Nelson .name = "HDMI",
515d67b0d97SEric Nelson .refresh = 60,
516d67b0d97SEric Nelson .xres = 1024,
517d67b0d97SEric Nelson .yres = 768,
518d67b0d97SEric Nelson .pixclock = 15385,
519d67b0d97SEric Nelson .left_margin = 220,
520d67b0d97SEric Nelson .right_margin = 40,
521d67b0d97SEric Nelson .upper_margin = 21,
522d67b0d97SEric Nelson .lower_margin = 7,
523d67b0d97SEric Nelson .hsync_len = 60,
524d67b0d97SEric Nelson .vsync_len = 10,
525d67b0d97SEric Nelson .sync = FB_SYNC_EXT,
526d67b0d97SEric Nelson .vmode = FB_VMODE_NONINTERLACED
527d67b0d97SEric Nelson } }, {
5284328fb05SRobert Winkler .bus = 0,
5294328fb05SRobert Winkler .addr = 0,
5304328fb05SRobert Winkler .pixfmt = IPU_PIX_FMT_RGB24,
5314328fb05SRobert Winkler .detect = NULL,
5324328fb05SRobert Winkler .enable = enable_lvds_jeida,
5334328fb05SRobert Winkler .mode = {
5344328fb05SRobert Winkler .name = "LDB-WXGA",
5354328fb05SRobert Winkler .refresh = 60,
5364328fb05SRobert Winkler .xres = 1280,
5374328fb05SRobert Winkler .yres = 800,
5384328fb05SRobert Winkler .pixclock = 14065,
5394328fb05SRobert Winkler .left_margin = 40,
5404328fb05SRobert Winkler .right_margin = 40,
5414328fb05SRobert Winkler .upper_margin = 3,
5424328fb05SRobert Winkler .lower_margin = 80,
5434328fb05SRobert Winkler .hsync_len = 10,
5444328fb05SRobert Winkler .vsync_len = 10,
5454328fb05SRobert Winkler .sync = FB_SYNC_EXT,
5464328fb05SRobert Winkler .vmode = FB_VMODE_NONINTERLACED
5474328fb05SRobert Winkler } }, {
548d6949e3fSEric Nelson .bus = 0,
549d6949e3fSEric Nelson .addr = 0,
550d6949e3fSEric Nelson .pixfmt = IPU_PIX_FMT_RGB24,
551d6949e3fSEric Nelson .detect = NULL,
552d6949e3fSEric Nelson .enable = enable_lvds,
553d6949e3fSEric Nelson .mode = {
554d6949e3fSEric Nelson .name = "LDB-WXGA-S",
555d6949e3fSEric Nelson .refresh = 60,
556d6949e3fSEric Nelson .xres = 1280,
557d6949e3fSEric Nelson .yres = 800,
558d6949e3fSEric Nelson .pixclock = 14065,
559d6949e3fSEric Nelson .left_margin = 40,
560d6949e3fSEric Nelson .right_margin = 40,
561d6949e3fSEric Nelson .upper_margin = 3,
562d6949e3fSEric Nelson .lower_margin = 80,
563d6949e3fSEric Nelson .hsync_len = 10,
564d6949e3fSEric Nelson .vsync_len = 10,
565d6949e3fSEric Nelson .sync = FB_SYNC_EXT,
566d6949e3fSEric Nelson .vmode = FB_VMODE_NONINTERLACED
567d6949e3fSEric Nelson } }, {
568d67b0d97SEric Nelson .bus = 2,
569d67b0d97SEric Nelson .addr = 0x4,
570d67b0d97SEric Nelson .pixfmt = IPU_PIX_FMT_LVDS666,
571d67b0d97SEric Nelson .detect = detect_i2c,
572d67b0d97SEric Nelson .enable = enable_lvds,
573d67b0d97SEric Nelson .mode = {
574d67b0d97SEric Nelson .name = "Hannstar-XGA",
575d67b0d97SEric Nelson .refresh = 60,
576d67b0d97SEric Nelson .xres = 1024,
577d67b0d97SEric Nelson .yres = 768,
578d67b0d97SEric Nelson .pixclock = 15385,
579d67b0d97SEric Nelson .left_margin = 220,
580d67b0d97SEric Nelson .right_margin = 40,
581d67b0d97SEric Nelson .upper_margin = 21,
582d67b0d97SEric Nelson .lower_margin = 7,
583d67b0d97SEric Nelson .hsync_len = 60,
584d67b0d97SEric Nelson .vsync_len = 10,
585d67b0d97SEric Nelson .sync = FB_SYNC_EXT,
586d67b0d97SEric Nelson .vmode = FB_VMODE_NONINTERLACED
587d67b0d97SEric Nelson } }, {
5884adc1127SEric Nelson .bus = 0,
5894adc1127SEric Nelson .addr = 0,
5904adc1127SEric Nelson .pixfmt = IPU_PIX_FMT_LVDS666,
5914adc1127SEric Nelson .detect = NULL,
5924adc1127SEric Nelson .enable = enable_lvds,
5934adc1127SEric Nelson .mode = {
5944adc1127SEric Nelson .name = "LG-9.7",
5954adc1127SEric Nelson .refresh = 60,
5964adc1127SEric Nelson .xres = 1024,
5974adc1127SEric Nelson .yres = 768,
5984adc1127SEric Nelson .pixclock = 15385, /* ~65MHz */
5994adc1127SEric Nelson .left_margin = 480,
6004adc1127SEric Nelson .right_margin = 260,
6014adc1127SEric Nelson .upper_margin = 16,
6024adc1127SEric Nelson .lower_margin = 6,
6034adc1127SEric Nelson .hsync_len = 250,
6044adc1127SEric Nelson .vsync_len = 10,
6054adc1127SEric Nelson .sync = FB_SYNC_EXT,
6064adc1127SEric Nelson .vmode = FB_VMODE_NONINTERLACED
6074adc1127SEric Nelson } }, {
608d67b0d97SEric Nelson .bus = 2,
609d67b0d97SEric Nelson .addr = 0x38,
610d67b0d97SEric Nelson .pixfmt = IPU_PIX_FMT_LVDS666,
611d67b0d97SEric Nelson .detect = detect_i2c,
612d67b0d97SEric Nelson .enable = enable_lvds,
613d67b0d97SEric Nelson .mode = {
614d67b0d97SEric Nelson .name = "wsvga-lvds",
615d67b0d97SEric Nelson .refresh = 60,
616d67b0d97SEric Nelson .xres = 1024,
617d67b0d97SEric Nelson .yres = 600,
618d67b0d97SEric Nelson .pixclock = 15385,
619d67b0d97SEric Nelson .left_margin = 220,
620d67b0d97SEric Nelson .right_margin = 40,
621d67b0d97SEric Nelson .upper_margin = 21,
622d67b0d97SEric Nelson .lower_margin = 7,
623d67b0d97SEric Nelson .hsync_len = 60,
624d67b0d97SEric Nelson .vsync_len = 10,
625d67b0d97SEric Nelson .sync = FB_SYNC_EXT,
626d67b0d97SEric Nelson .vmode = FB_VMODE_NONINTERLACED
627d67b0d97SEric Nelson } }, {
628d67b0d97SEric Nelson .bus = 2,
62904edda26SEric Nelson .addr = 0x10,
63004edda26SEric Nelson .pixfmt = IPU_PIX_FMT_RGB666,
63104edda26SEric Nelson .detect = detect_i2c,
63204edda26SEric Nelson .enable = enable_rgb,
63304edda26SEric Nelson .mode = {
63404edda26SEric Nelson .name = "fusion7",
63504edda26SEric Nelson .refresh = 60,
63604edda26SEric Nelson .xres = 800,
63704edda26SEric Nelson .yres = 480,
63804edda26SEric Nelson .pixclock = 33898,
63904edda26SEric Nelson .left_margin = 96,
64004edda26SEric Nelson .right_margin = 24,
64104edda26SEric Nelson .upper_margin = 3,
64204edda26SEric Nelson .lower_margin = 10,
64304edda26SEric Nelson .hsync_len = 72,
64404edda26SEric Nelson .vsync_len = 7,
64504edda26SEric Nelson .sync = 0x40000002,
64604edda26SEric Nelson .vmode = FB_VMODE_NONINTERLACED
64704edda26SEric Nelson } }, {
64813566306SEric Nelson .bus = 0,
64913566306SEric Nelson .addr = 0,
65013566306SEric Nelson .pixfmt = IPU_PIX_FMT_RGB666,
65113566306SEric Nelson .detect = NULL,
65213566306SEric Nelson .enable = enable_rgb,
65313566306SEric Nelson .mode = {
65413566306SEric Nelson .name = "svga",
65513566306SEric Nelson .refresh = 60,
65613566306SEric Nelson .xres = 800,
65713566306SEric Nelson .yres = 600,
65813566306SEric Nelson .pixclock = 15385,
65913566306SEric Nelson .left_margin = 220,
66013566306SEric Nelson .right_margin = 40,
66113566306SEric Nelson .upper_margin = 21,
66213566306SEric Nelson .lower_margin = 7,
66313566306SEric Nelson .hsync_len = 60,
66413566306SEric Nelson .vsync_len = 10,
66513566306SEric Nelson .sync = 0,
66613566306SEric Nelson .vmode = FB_VMODE_NONINTERLACED
66713566306SEric Nelson } }, {
66804edda26SEric Nelson .bus = 2,
669865aa30bSEric Nelson .addr = 0x41,
670865aa30bSEric Nelson .pixfmt = IPU_PIX_FMT_LVDS666,
671865aa30bSEric Nelson .detect = detect_i2c,
672865aa30bSEric Nelson .enable = enable_lvds,
673865aa30bSEric Nelson .mode = {
674865aa30bSEric Nelson .name = "amp1024x600",
675865aa30bSEric Nelson .refresh = 60,
676865aa30bSEric Nelson .xres = 1024,
677865aa30bSEric Nelson .yres = 600,
678865aa30bSEric Nelson .pixclock = 15385,
679865aa30bSEric Nelson .left_margin = 220,
680865aa30bSEric Nelson .right_margin = 40,
681865aa30bSEric Nelson .upper_margin = 21,
682865aa30bSEric Nelson .lower_margin = 7,
683865aa30bSEric Nelson .hsync_len = 60,
684865aa30bSEric Nelson .vsync_len = 10,
685865aa30bSEric Nelson .sync = FB_SYNC_EXT,
686865aa30bSEric Nelson .vmode = FB_VMODE_NONINTERLACED
687865aa30bSEric Nelson } }, {
688c745de71SEric Nelson .bus = 0,
689c745de71SEric Nelson .addr = 0,
690c745de71SEric Nelson .pixfmt = IPU_PIX_FMT_LVDS666,
691c745de71SEric Nelson .detect = 0,
692c745de71SEric Nelson .enable = enable_lvds,
693c745de71SEric Nelson .mode = {
694c745de71SEric Nelson .name = "wvga-lvds",
695c745de71SEric Nelson .refresh = 57,
696c745de71SEric Nelson .xres = 800,
697c745de71SEric Nelson .yres = 480,
698c745de71SEric Nelson .pixclock = 15385,
699c745de71SEric Nelson .left_margin = 220,
700c745de71SEric Nelson .right_margin = 40,
701c745de71SEric Nelson .upper_margin = 21,
702c745de71SEric Nelson .lower_margin = 7,
703c745de71SEric Nelson .hsync_len = 60,
704c745de71SEric Nelson .vsync_len = 10,
705c745de71SEric Nelson .sync = FB_SYNC_EXT,
706c745de71SEric Nelson .vmode = FB_VMODE_NONINTERLACED
707c745de71SEric Nelson } }, {
708865aa30bSEric Nelson .bus = 2,
709d67b0d97SEric Nelson .addr = 0x48,
710d67b0d97SEric Nelson .pixfmt = IPU_PIX_FMT_RGB666,
711d67b0d97SEric Nelson .detect = detect_i2c,
712d67b0d97SEric Nelson .enable = enable_rgb,
713d67b0d97SEric Nelson .mode = {
714d67b0d97SEric Nelson .name = "wvga-rgb",
715d67b0d97SEric Nelson .refresh = 57,
716d67b0d97SEric Nelson .xres = 800,
717d67b0d97SEric Nelson .yres = 480,
718d67b0d97SEric Nelson .pixclock = 37037,
719d67b0d97SEric Nelson .left_margin = 40,
720d67b0d97SEric Nelson .right_margin = 60,
721d67b0d97SEric Nelson .upper_margin = 10,
722d67b0d97SEric Nelson .lower_margin = 10,
723d67b0d97SEric Nelson .hsync_len = 20,
724d67b0d97SEric Nelson .vsync_len = 10,
725d67b0d97SEric Nelson .sync = 0,
726d67b0d97SEric Nelson .vmode = FB_VMODE_NONINTERLACED
727443d4d15SEric Nelson } }, {
728443d4d15SEric Nelson .bus = 0,
729443d4d15SEric Nelson .addr = 0,
730443d4d15SEric Nelson .pixfmt = IPU_PIX_FMT_RGB24,
731443d4d15SEric Nelson .detect = NULL,
732443d4d15SEric Nelson .enable = enable_rgb,
733443d4d15SEric Nelson .mode = {
734443d4d15SEric Nelson .name = "qvga",
735443d4d15SEric Nelson .refresh = 60,
736443d4d15SEric Nelson .xres = 320,
737443d4d15SEric Nelson .yres = 240,
738443d4d15SEric Nelson .pixclock = 37037,
739443d4d15SEric Nelson .left_margin = 38,
740443d4d15SEric Nelson .right_margin = 37,
741443d4d15SEric Nelson .upper_margin = 16,
742443d4d15SEric Nelson .lower_margin = 15,
743443d4d15SEric Nelson .hsync_len = 30,
744443d4d15SEric Nelson .vsync_len = 3,
745443d4d15SEric Nelson .sync = 0,
746443d4d15SEric Nelson .vmode = FB_VMODE_NONINTERLACED
747d67b0d97SEric Nelson } } };
748a47e4495SEric Benard size_t display_count = ARRAY_SIZE(displays);
749d67b0d97SEric Nelson
board_cfb_skip(void)750c9c86bdeSEric Nelson int board_cfb_skip(void)
751c9c86bdeSEric Nelson {
752*00caae6dSSimon Glass return NULL != env_get("novideo");
753c9c86bdeSEric Nelson }
754c9c86bdeSEric Nelson
setup_display(void)755d67b0d97SEric Nelson static void setup_display(void)
756d67b0d97SEric Nelson {
757d67b0d97SEric Nelson struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
758d67b0d97SEric Nelson struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
759d67b0d97SEric Nelson int reg;
760d67b0d97SEric Nelson
7615ea7f0e3SPardeep Kumar Singla enable_ipu_clock();
7625ea7f0e3SPardeep Kumar Singla imx_setup_hdmi();
763d67b0d97SEric Nelson /* Turn on LDB0,IPU,IPU DI0 clocks */
764d67b0d97SEric Nelson reg = __raw_readl(&mxc_ccm->CCGR3);
7655ea7f0e3SPardeep Kumar Singla reg |= MXC_CCM_CCGR3_LDB_DI0_MASK;
766d67b0d97SEric Nelson writel(reg, &mxc_ccm->CCGR3);
767d67b0d97SEric Nelson
768d67b0d97SEric Nelson /* set LDB0, LDB1 clk select to 011/011 */
769d67b0d97SEric Nelson reg = readl(&mxc_ccm->cs2cdr);
770d67b0d97SEric Nelson reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
771d67b0d97SEric Nelson |MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
772d67b0d97SEric Nelson reg |= (3<<MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
773d67b0d97SEric Nelson |(3<<MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
774d67b0d97SEric Nelson writel(reg, &mxc_ccm->cs2cdr);
775d67b0d97SEric Nelson
776d67b0d97SEric Nelson reg = readl(&mxc_ccm->cscmr2);
777d67b0d97SEric Nelson reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
778d67b0d97SEric Nelson writel(reg, &mxc_ccm->cscmr2);
779d67b0d97SEric Nelson
780d67b0d97SEric Nelson reg = readl(&mxc_ccm->chsccdr);
781d67b0d97SEric Nelson reg |= (CHSCCDR_CLK_SEL_LDB_DI0
7825ea7f0e3SPardeep Kumar Singla <<MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
783d67b0d97SEric Nelson writel(reg, &mxc_ccm->chsccdr);
784d67b0d97SEric Nelson
785d67b0d97SEric Nelson reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
786d67b0d97SEric Nelson |IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
787d67b0d97SEric Nelson |IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
788d67b0d97SEric Nelson |IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
789d67b0d97SEric Nelson |IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
790d67b0d97SEric Nelson |IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
791d67b0d97SEric Nelson |IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
792d67b0d97SEric Nelson |IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED
793d67b0d97SEric Nelson |IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
794d67b0d97SEric Nelson writel(reg, &iomux->gpr[2]);
795d67b0d97SEric Nelson
796d67b0d97SEric Nelson reg = readl(&iomux->gpr[3]);
7978907c2c5SEric Nelson reg = (reg & ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK
7988907c2c5SEric Nelson |IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
799d67b0d97SEric Nelson | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
800d67b0d97SEric Nelson <<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
801d67b0d97SEric Nelson writel(reg, &iomux->gpr[3]);
802d67b0d97SEric Nelson
803d67b0d97SEric Nelson /* backlights off until needed */
804d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(backlight_pads,
805d67b0d97SEric Nelson ARRAY_SIZE(backlight_pads));
806d67b0d97SEric Nelson gpio_direction_input(LVDS_BACKLIGHT_GP);
807d67b0d97SEric Nelson gpio_direction_input(RGB_BACKLIGHT_GP);
808d67b0d97SEric Nelson }
809d67b0d97SEric Nelson #endif
810d67b0d97SEric Nelson
811a3b527a9SEric Nelson static iomux_v3_cfg_t const init_pads[] = {
812693cccf4STroy Kisky /* SGTL5000 sys_mclk */
813693cccf4STroy Kisky NEW_PAD_CTRL(MX6_PAD_GPIO_0__CCM_CLKO1, OUTPUT_40OHM),
814693cccf4STroy Kisky
815693cccf4STroy Kisky /* J5 - Camera MCLK */
816693cccf4STroy Kisky NEW_PAD_CTRL(MX6_PAD_GPIO_3__CCM_CLKO2, OUTPUT_40OHM),
817693cccf4STroy Kisky
818693cccf4STroy Kisky /* wl1271 pads on nitrogen6x */
819a3b527a9SEric Nelson /* WL12XX_WL_IRQ_GP */
820a3b527a9SEric Nelson NEW_PAD_CTRL(MX6_PAD_NANDF_CS1__GPIO6_IO14, WEAK_PULLDOWN),
821a3b527a9SEric Nelson /* WL12XX_WL_ENABLE_GP */
822a3b527a9SEric Nelson NEW_PAD_CTRL(MX6_PAD_NANDF_CS2__GPIO6_IO15, OUTPUT_40OHM),
823a3b527a9SEric Nelson /* WL12XX_BT_ENABLE_GP */
824a3b527a9SEric Nelson NEW_PAD_CTRL(MX6_PAD_NANDF_CS3__GPIO6_IO16, OUTPUT_40OHM),
825a3b527a9SEric Nelson /* USB otg power */
826a3b527a9SEric Nelson NEW_PAD_CTRL(MX6_PAD_EIM_D22__GPIO3_IO22, OUTPUT_40OHM),
827a3b527a9SEric Nelson NEW_PAD_CTRL(MX6_PAD_NANDF_D5__GPIO2_IO05, OUTPUT_40OHM),
828a3b527a9SEric Nelson NEW_PAD_CTRL(MX6_PAD_NANDF_WP_B__GPIO6_IO09, OUTPUT_40OHM),
829a3b527a9SEric Nelson NEW_PAD_CTRL(MX6_PAD_GPIO_8__GPIO1_IO08, OUTPUT_40OHM),
830a3b527a9SEric Nelson NEW_PAD_CTRL(MX6_PAD_GPIO_6__GPIO1_IO06, OUTPUT_40OHM),
831a3b527a9SEric Nelson };
832a3b527a9SEric Nelson
833a3b527a9SEric Nelson #define WL12XX_WL_IRQ_GP IMX_GPIO_NR(6, 14)
834a3b527a9SEric Nelson
835a3b527a9SEric Nelson static unsigned gpios_out_low[] = {
836a3b527a9SEric Nelson /* Disable wl1271 */
837a3b527a9SEric Nelson IMX_GPIO_NR(6, 15), /* disable wireless */
838a3b527a9SEric Nelson IMX_GPIO_NR(6, 16), /* disable bluetooth */
839a3b527a9SEric Nelson IMX_GPIO_NR(3, 22), /* disable USB otg power */
840a3b527a9SEric Nelson IMX_GPIO_NR(2, 5), /* ov5640 mipi camera reset */
841a3b527a9SEric Nelson IMX_GPIO_NR(1, 8), /* ov5642 reset */
842a3b527a9SEric Nelson };
843a3b527a9SEric Nelson
844a3b527a9SEric Nelson static unsigned gpios_out_high[] = {
845a3b527a9SEric Nelson IMX_GPIO_NR(1, 6), /* ov5642 powerdown */
846a3b527a9SEric Nelson IMX_GPIO_NR(6, 9), /* ov5640 mipi camera power down */
847a3b527a9SEric Nelson };
848a3b527a9SEric Nelson
set_gpios(unsigned * p,int cnt,int val)849a3b527a9SEric Nelson static void set_gpios(unsigned *p, int cnt, int val)
850a3b527a9SEric Nelson {
851a3b527a9SEric Nelson int i;
852a3b527a9SEric Nelson
853a3b527a9SEric Nelson for (i = 0; i < cnt; i++)
854a3b527a9SEric Nelson gpio_direction_output(*p++, val);
855a3b527a9SEric Nelson }
856a3b527a9SEric Nelson
board_early_init_f(void)857d67b0d97SEric Nelson int board_early_init_f(void)
858d67b0d97SEric Nelson {
859d67b0d97SEric Nelson setup_iomux_uart();
860d67b0d97SEric Nelson
861a3b527a9SEric Nelson set_gpios(gpios_out_high, ARRAY_SIZE(gpios_out_high), 1);
862a3b527a9SEric Nelson set_gpios(gpios_out_low, ARRAY_SIZE(gpios_out_low), 0);
863d67b0d97SEric Nelson gpio_direction_input(WL12XX_WL_IRQ_GP);
864d67b0d97SEric Nelson
865d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(wl12xx_pads, ARRAY_SIZE(wl12xx_pads));
866a3b527a9SEric Nelson imx_iomux_v3_setup_multiple_pads(init_pads, ARRAY_SIZE(init_pads));
867d67b0d97SEric Nelson setup_buttons();
868d67b0d97SEric Nelson
869d67b0d97SEric Nelson #if defined(CONFIG_VIDEO_IPUV3)
870d67b0d97SEric Nelson setup_display();
871d67b0d97SEric Nelson #endif
872d67b0d97SEric Nelson return 0;
873d67b0d97SEric Nelson }
874d67b0d97SEric Nelson
875d67b0d97SEric Nelson /*
876d67b0d97SEric Nelson * Do not overwrite the console
877d67b0d97SEric Nelson * Use always serial for U-Boot console
878d67b0d97SEric Nelson */
overwrite_console(void)879d67b0d97SEric Nelson int overwrite_console(void)
880d67b0d97SEric Nelson {
881d67b0d97SEric Nelson return 1;
882d67b0d97SEric Nelson }
883d67b0d97SEric Nelson
board_init(void)884d67b0d97SEric Nelson int board_init(void)
885d67b0d97SEric Nelson {
8860a11d6f2SFabio Estevam struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
8877132869dSTroy Kisky
8887132869dSTroy Kisky clrsetbits_le32(&iomuxc_regs->gpr[1],
8897132869dSTroy Kisky IOMUXC_GPR1_OTG_ID_MASK,
8907132869dSTroy Kisky IOMUXC_GPR1_OTG_ID_GPIO1);
8917132869dSTroy Kisky
89208ce074eSTroy Kisky imx_iomux_v3_setup_multiple_pads(misc_pads, ARRAY_SIZE(misc_pads));
89308ce074eSTroy Kisky
894d67b0d97SEric Nelson /* address of boot parameters */
895d67b0d97SEric Nelson gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
896d67b0d97SEric Nelson
897d67b0d97SEric Nelson #ifdef CONFIG_MXC_SPI
898d67b0d97SEric Nelson setup_spi();
899d67b0d97SEric Nelson #endif
90041612472SEric Nelson imx_iomux_v3_setup_multiple_pads(
90141612472SEric Nelson usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
902d67b0d97SEric Nelson setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info0);
903d67b0d97SEric Nelson setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
904d67b0d97SEric Nelson setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
905d67b0d97SEric Nelson
90610e40d54SSimon Glass #ifdef CONFIG_SATA
907d67b0d97SEric Nelson setup_sata();
908d67b0d97SEric Nelson #endif
909d67b0d97SEric Nelson
910d67b0d97SEric Nelson return 0;
911d67b0d97SEric Nelson }
912d67b0d97SEric Nelson
checkboard(void)913d67b0d97SEric Nelson int checkboard(void)
914d67b0d97SEric Nelson {
915d67b0d97SEric Nelson if (gpio_get_value(WL12XX_WL_IRQ_GP))
916d67b0d97SEric Nelson puts("Board: Nitrogen6X\n");
917d67b0d97SEric Nelson else
918d67b0d97SEric Nelson puts("Board: SABRE Lite\n");
919d67b0d97SEric Nelson
920d67b0d97SEric Nelson return 0;
921d67b0d97SEric Nelson }
922d67b0d97SEric Nelson
923d67b0d97SEric Nelson struct button_key {
924d67b0d97SEric Nelson char const *name;
925d67b0d97SEric Nelson unsigned gpnum;
926d67b0d97SEric Nelson char ident;
927d67b0d97SEric Nelson };
928d67b0d97SEric Nelson
929d67b0d97SEric Nelson static struct button_key const buttons[] = {
930d67b0d97SEric Nelson {"back", IMX_GPIO_NR(2, 2), 'B'},
931d67b0d97SEric Nelson {"home", IMX_GPIO_NR(2, 4), 'H'},
932d67b0d97SEric Nelson {"menu", IMX_GPIO_NR(2, 1), 'M'},
933d67b0d97SEric Nelson {"search", IMX_GPIO_NR(2, 3), 'S'},
934d67b0d97SEric Nelson {"volup", IMX_GPIO_NR(7, 13), 'V'},
935d67b0d97SEric Nelson {"voldown", IMX_GPIO_NR(4, 5), 'v'},
936d67b0d97SEric Nelson };
937d67b0d97SEric Nelson
938d67b0d97SEric Nelson /*
939d67b0d97SEric Nelson * generate a null-terminated string containing the buttons pressed
940d67b0d97SEric Nelson * returns number of keys pressed
941d67b0d97SEric Nelson */
read_keys(char * buf)942d67b0d97SEric Nelson static int read_keys(char *buf)
943d67b0d97SEric Nelson {
944d67b0d97SEric Nelson int i, numpressed = 0;
945d67b0d97SEric Nelson for (i = 0; i < ARRAY_SIZE(buttons); i++) {
946d67b0d97SEric Nelson if (!gpio_get_value(buttons[i].gpnum))
947d67b0d97SEric Nelson buf[numpressed++] = buttons[i].ident;
948d67b0d97SEric Nelson }
949d67b0d97SEric Nelson buf[numpressed] = '\0';
950d67b0d97SEric Nelson return numpressed;
951d67b0d97SEric Nelson }
952d67b0d97SEric Nelson
do_kbd(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])953d67b0d97SEric Nelson static int do_kbd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
954d67b0d97SEric Nelson {
955d67b0d97SEric Nelson char envvalue[ARRAY_SIZE(buttons)+1];
956d67b0d97SEric Nelson int numpressed = read_keys(envvalue);
957382bee57SSimon Glass env_set("keybd", envvalue);
958d67b0d97SEric Nelson return numpressed == 0;
959d67b0d97SEric Nelson }
960d67b0d97SEric Nelson
961d67b0d97SEric Nelson U_BOOT_CMD(
962d67b0d97SEric Nelson kbd, 1, 1, do_kbd,
963d67b0d97SEric Nelson "Tests for keypresses, sets 'keybd' environment variable",
964d67b0d97SEric Nelson "Returns 0 (true) to shell if key is pressed."
965d67b0d97SEric Nelson );
966d67b0d97SEric Nelson
967d67b0d97SEric Nelson #ifdef CONFIG_PREBOOT
968d67b0d97SEric Nelson static char const kbd_magic_prefix[] = "key_magic";
969d67b0d97SEric Nelson static char const kbd_command_prefix[] = "key_cmd";
970d67b0d97SEric Nelson
preboot_keys(void)971d67b0d97SEric Nelson static void preboot_keys(void)
972d67b0d97SEric Nelson {
973d67b0d97SEric Nelson int numpressed;
974d67b0d97SEric Nelson char keypress[ARRAY_SIZE(buttons)+1];
975d67b0d97SEric Nelson numpressed = read_keys(keypress);
976d67b0d97SEric Nelson if (numpressed) {
977*00caae6dSSimon Glass char *kbd_magic_keys = env_get("magic_keys");
978d67b0d97SEric Nelson char *suffix;
979d67b0d97SEric Nelson /*
980d67b0d97SEric Nelson * loop over all magic keys
981d67b0d97SEric Nelson */
982d67b0d97SEric Nelson for (suffix = kbd_magic_keys; *suffix; ++suffix) {
983d67b0d97SEric Nelson char *keys;
984d67b0d97SEric Nelson char magic[sizeof(kbd_magic_prefix) + 1];
985d67b0d97SEric Nelson sprintf(magic, "%s%c", kbd_magic_prefix, *suffix);
986*00caae6dSSimon Glass keys = env_get(magic);
987d67b0d97SEric Nelson if (keys) {
988d67b0d97SEric Nelson if (!strcmp(keys, keypress))
989d67b0d97SEric Nelson break;
990d67b0d97SEric Nelson }
991d67b0d97SEric Nelson }
992d67b0d97SEric Nelson if (*suffix) {
993d67b0d97SEric Nelson char cmd_name[sizeof(kbd_command_prefix) + 1];
994d67b0d97SEric Nelson char *cmd;
995d67b0d97SEric Nelson sprintf(cmd_name, "%s%c", kbd_command_prefix, *suffix);
996*00caae6dSSimon Glass cmd = env_get(cmd_name);
997d67b0d97SEric Nelson if (cmd) {
998382bee57SSimon Glass env_set("preboot", cmd);
999d67b0d97SEric Nelson return;
1000d67b0d97SEric Nelson }
1001d67b0d97SEric Nelson }
1002d67b0d97SEric Nelson }
1003d67b0d97SEric Nelson }
1004d67b0d97SEric Nelson #endif
1005d67b0d97SEric Nelson
1006d67b0d97SEric Nelson #ifdef CONFIG_CMD_BMODE
1007d67b0d97SEric Nelson static const struct boot_mode board_boot_modes[] = {
1008d67b0d97SEric Nelson /* 4 bit bus width */
1009d67b0d97SEric Nelson {"mmc0", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
1010d67b0d97SEric Nelson {"mmc1", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)},
1011d67b0d97SEric Nelson {NULL, 0},
1012d67b0d97SEric Nelson };
1013d67b0d97SEric Nelson #endif
1014d67b0d97SEric Nelson
misc_init_r(void)1015d67b0d97SEric Nelson int misc_init_r(void)
1016d67b0d97SEric Nelson {
1017d67b0d97SEric Nelson #ifdef CONFIG_PREBOOT
1018d67b0d97SEric Nelson preboot_keys();
1019d67b0d97SEric Nelson #endif
1020d67b0d97SEric Nelson
1021d67b0d97SEric Nelson #ifdef CONFIG_CMD_BMODE
1022d67b0d97SEric Nelson add_board_boot_modes(board_boot_modes);
1023d67b0d97SEric Nelson #endif
1024018f5303SSimon Glass env_set_hex("reset_cause", get_imx_reset_cause());
1025d67b0d97SEric Nelson return 0;
1026d67b0d97SEric Nelson }
1027