1*d67b0d97SEric Nelson /* 2*d67b0d97SEric Nelson * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. 3*d67b0d97SEric Nelson * Copyright (C) 2013, Boundary Devices <info@boundarydevices.com> 4*d67b0d97SEric Nelson * 5*d67b0d97SEric Nelson * See file CREDITS for list of people who contributed to this 6*d67b0d97SEric Nelson * project. 7*d67b0d97SEric Nelson * 8*d67b0d97SEric Nelson * This program is free software; you can redistribute it and/or 9*d67b0d97SEric Nelson * modify it under the terms of the GNU General Public License as 10*d67b0d97SEric Nelson * published by the Free Software Foundation; either version 2 of 11*d67b0d97SEric Nelson * the License, or (at your option) any later version. 12*d67b0d97SEric Nelson * 13*d67b0d97SEric Nelson * This program is distributed in the hope that it will be useful, 14*d67b0d97SEric Nelson * but WITHOUT ANY WARRANTY; without even the implied warranty of 15*d67b0d97SEric Nelson * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*d67b0d97SEric Nelson * GNU General Public License for more details. 17*d67b0d97SEric Nelson * 18*d67b0d97SEric Nelson * You should have received a copy of the GNU General Public License 19*d67b0d97SEric Nelson * along with this program; if not, write to the Free Software 20*d67b0d97SEric Nelson * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21*d67b0d97SEric Nelson * MA 02111-1307 USA 22*d67b0d97SEric Nelson */ 23*d67b0d97SEric Nelson 24*d67b0d97SEric Nelson #include <common.h> 25*d67b0d97SEric Nelson #include <asm/io.h> 26*d67b0d97SEric Nelson #include <asm/arch/clock.h> 27*d67b0d97SEric Nelson #include <asm/arch/imx-regs.h> 28*d67b0d97SEric Nelson #include <asm/arch/iomux.h> 29*d67b0d97SEric Nelson #include <asm/arch/sys_proto.h> 30*d67b0d97SEric Nelson #include <malloc.h> 31*d67b0d97SEric Nelson #include <asm/arch/mx6-pins.h> 32*d67b0d97SEric Nelson #include <asm/errno.h> 33*d67b0d97SEric Nelson #include <asm/gpio.h> 34*d67b0d97SEric Nelson #include <asm/imx-common/iomux-v3.h> 35*d67b0d97SEric Nelson #include <asm/imx-common/mxc_i2c.h> 36*d67b0d97SEric Nelson #include <asm/imx-common/boot_mode.h> 37*d67b0d97SEric Nelson #include <mmc.h> 38*d67b0d97SEric Nelson #include <fsl_esdhc.h> 39*d67b0d97SEric Nelson #include <micrel.h> 40*d67b0d97SEric Nelson #include <miiphy.h> 41*d67b0d97SEric Nelson #include <netdev.h> 42*d67b0d97SEric Nelson #include <linux/fb.h> 43*d67b0d97SEric Nelson #include <ipu_pixfmt.h> 44*d67b0d97SEric Nelson #include <asm/arch/crm_regs.h> 45*d67b0d97SEric Nelson #include <asm/arch/mxc_hdmi.h> 46*d67b0d97SEric Nelson #include <i2c.h> 47*d67b0d97SEric Nelson 48*d67b0d97SEric Nelson DECLARE_GLOBAL_DATA_PTR; 49*d67b0d97SEric Nelson 50*d67b0d97SEric Nelson #define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ 51*d67b0d97SEric Nelson PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ 52*d67b0d97SEric Nelson PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) 53*d67b0d97SEric Nelson 54*d67b0d97SEric Nelson #define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ 55*d67b0d97SEric Nelson PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \ 56*d67b0d97SEric Nelson PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) 57*d67b0d97SEric Nelson 58*d67b0d97SEric Nelson #define ENET_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ 59*d67b0d97SEric Nelson PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ 60*d67b0d97SEric Nelson PAD_CTL_DSE_40ohm | PAD_CTL_HYS) 61*d67b0d97SEric Nelson 62*d67b0d97SEric Nelson #define SPI_PAD_CTRL (PAD_CTL_HYS | \ 63*d67b0d97SEric Nelson PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED | \ 64*d67b0d97SEric Nelson PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) 65*d67b0d97SEric Nelson 66*d67b0d97SEric Nelson #define BUTTON_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ 67*d67b0d97SEric Nelson PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ 68*d67b0d97SEric Nelson PAD_CTL_DSE_40ohm | PAD_CTL_HYS) 69*d67b0d97SEric Nelson 70*d67b0d97SEric Nelson #define I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ 71*d67b0d97SEric Nelson PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ 72*d67b0d97SEric Nelson PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ 73*d67b0d97SEric Nelson PAD_CTL_ODE | PAD_CTL_SRE_FAST) 74*d67b0d97SEric Nelson 75*d67b0d97SEric Nelson #define WEAK_PULLUP (PAD_CTL_PKE | PAD_CTL_PUE | \ 76*d67b0d97SEric Nelson PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ 77*d67b0d97SEric Nelson PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ 78*d67b0d97SEric Nelson PAD_CTL_SRE_SLOW) 79*d67b0d97SEric Nelson 80*d67b0d97SEric Nelson #define WEAK_PULLDOWN (PAD_CTL_PKE | PAD_CTL_PUE | \ 81*d67b0d97SEric Nelson PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED | \ 82*d67b0d97SEric Nelson PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ 83*d67b0d97SEric Nelson PAD_CTL_SRE_SLOW) 84*d67b0d97SEric Nelson 85*d67b0d97SEric Nelson #define OUTPUT_40OHM (PAD_CTL_SPEED_MED|PAD_CTL_DSE_40ohm) 86*d67b0d97SEric Nelson 87*d67b0d97SEric Nelson int dram_init(void) 88*d67b0d97SEric Nelson { 89*d67b0d97SEric Nelson gd->ram_size = CONFIG_DDR_MB * 1024 * 1024; 90*d67b0d97SEric Nelson 91*d67b0d97SEric Nelson return 0; 92*d67b0d97SEric Nelson } 93*d67b0d97SEric Nelson 94*d67b0d97SEric Nelson iomux_v3_cfg_t const uart1_pads[] = { 95*d67b0d97SEric Nelson MX6_PAD_SD3_DAT6__UART1_RXD | MUX_PAD_CTRL(UART_PAD_CTRL), 96*d67b0d97SEric Nelson MX6_PAD_SD3_DAT7__UART1_TXD | MUX_PAD_CTRL(UART_PAD_CTRL), 97*d67b0d97SEric Nelson }; 98*d67b0d97SEric Nelson 99*d67b0d97SEric Nelson iomux_v3_cfg_t const uart2_pads[] = { 100*d67b0d97SEric Nelson MX6_PAD_EIM_D26__UART2_TXD | MUX_PAD_CTRL(UART_PAD_CTRL), 101*d67b0d97SEric Nelson MX6_PAD_EIM_D27__UART2_RXD | MUX_PAD_CTRL(UART_PAD_CTRL), 102*d67b0d97SEric Nelson }; 103*d67b0d97SEric Nelson 104*d67b0d97SEric Nelson #define PC MUX_PAD_CTRL(I2C_PAD_CTRL) 105*d67b0d97SEric Nelson 106*d67b0d97SEric Nelson /* I2C1, SGTL5000 */ 107*d67b0d97SEric Nelson struct i2c_pads_info i2c_pad_info0 = { 108*d67b0d97SEric Nelson .scl = { 109*d67b0d97SEric Nelson .i2c_mode = MX6_PAD_EIM_D21__I2C1_SCL | PC, 110*d67b0d97SEric Nelson .gpio_mode = MX6_PAD_EIM_D21__GPIO_3_21 | PC, 111*d67b0d97SEric Nelson .gp = IMX_GPIO_NR(3, 21) 112*d67b0d97SEric Nelson }, 113*d67b0d97SEric Nelson .sda = { 114*d67b0d97SEric Nelson .i2c_mode = MX6_PAD_EIM_D28__I2C1_SDA | PC, 115*d67b0d97SEric Nelson .gpio_mode = MX6_PAD_EIM_D28__GPIO_3_28 | PC, 116*d67b0d97SEric Nelson .gp = IMX_GPIO_NR(3, 28) 117*d67b0d97SEric Nelson } 118*d67b0d97SEric Nelson }; 119*d67b0d97SEric Nelson 120*d67b0d97SEric Nelson /* I2C2 Camera, MIPI */ 121*d67b0d97SEric Nelson struct i2c_pads_info i2c_pad_info1 = { 122*d67b0d97SEric Nelson .scl = { 123*d67b0d97SEric Nelson .i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL | PC, 124*d67b0d97SEric Nelson .gpio_mode = MX6_PAD_KEY_COL3__GPIO_4_12 | PC, 125*d67b0d97SEric Nelson .gp = IMX_GPIO_NR(4, 12) 126*d67b0d97SEric Nelson }, 127*d67b0d97SEric Nelson .sda = { 128*d67b0d97SEric Nelson .i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | PC, 129*d67b0d97SEric Nelson .gpio_mode = MX6_PAD_KEY_ROW3__GPIO_4_13 | PC, 130*d67b0d97SEric Nelson .gp = IMX_GPIO_NR(4, 13) 131*d67b0d97SEric Nelson } 132*d67b0d97SEric Nelson }; 133*d67b0d97SEric Nelson 134*d67b0d97SEric Nelson /* I2C3, J15 - RGB connector */ 135*d67b0d97SEric Nelson struct i2c_pads_info i2c_pad_info2 = { 136*d67b0d97SEric Nelson .scl = { 137*d67b0d97SEric Nelson .i2c_mode = MX6_PAD_GPIO_5__I2C3_SCL | PC, 138*d67b0d97SEric Nelson .gpio_mode = MX6_PAD_GPIO_5__GPIO_1_5 | PC, 139*d67b0d97SEric Nelson .gp = IMX_GPIO_NR(1, 5) 140*d67b0d97SEric Nelson }, 141*d67b0d97SEric Nelson .sda = { 142*d67b0d97SEric Nelson .i2c_mode = MX6_PAD_GPIO_16__I2C3_SDA | PC, 143*d67b0d97SEric Nelson .gpio_mode = MX6_PAD_GPIO_16__GPIO_7_11 | PC, 144*d67b0d97SEric Nelson .gp = IMX_GPIO_NR(7, 11) 145*d67b0d97SEric Nelson } 146*d67b0d97SEric Nelson }; 147*d67b0d97SEric Nelson 148*d67b0d97SEric Nelson iomux_v3_cfg_t const usdhc3_pads[] = { 149*d67b0d97SEric Nelson MX6_PAD_SD3_CLK__USDHC3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), 150*d67b0d97SEric Nelson MX6_PAD_SD3_CMD__USDHC3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), 151*d67b0d97SEric Nelson MX6_PAD_SD3_DAT0__USDHC3_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 152*d67b0d97SEric Nelson MX6_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 153*d67b0d97SEric Nelson MX6_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 154*d67b0d97SEric Nelson MX6_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 155*d67b0d97SEric Nelson MX6_PAD_SD3_DAT5__GPIO_7_0 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */ 156*d67b0d97SEric Nelson }; 157*d67b0d97SEric Nelson 158*d67b0d97SEric Nelson iomux_v3_cfg_t const usdhc4_pads[] = { 159*d67b0d97SEric Nelson MX6_PAD_SD4_CLK__USDHC4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), 160*d67b0d97SEric Nelson MX6_PAD_SD4_CMD__USDHC4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), 161*d67b0d97SEric Nelson MX6_PAD_SD4_DAT0__USDHC4_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 162*d67b0d97SEric Nelson MX6_PAD_SD4_DAT1__USDHC4_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 163*d67b0d97SEric Nelson MX6_PAD_SD4_DAT2__USDHC4_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 164*d67b0d97SEric Nelson MX6_PAD_SD4_DAT3__USDHC4_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 165*d67b0d97SEric Nelson MX6_PAD_NANDF_D6__GPIO_2_6 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */ 166*d67b0d97SEric Nelson }; 167*d67b0d97SEric Nelson 168*d67b0d97SEric Nelson iomux_v3_cfg_t const enet_pads1[] = { 169*d67b0d97SEric Nelson MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL), 170*d67b0d97SEric Nelson MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL), 171*d67b0d97SEric Nelson MX6_PAD_RGMII_TXC__ENET_RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL), 172*d67b0d97SEric Nelson MX6_PAD_RGMII_TD0__ENET_RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), 173*d67b0d97SEric Nelson MX6_PAD_RGMII_TD1__ENET_RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), 174*d67b0d97SEric Nelson MX6_PAD_RGMII_TD2__ENET_RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), 175*d67b0d97SEric Nelson MX6_PAD_RGMII_TD3__ENET_RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), 176*d67b0d97SEric Nelson MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), 177*d67b0d97SEric Nelson MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL), 178*d67b0d97SEric Nelson /* pin 35 - 1 (PHY_AD2) on reset */ 179*d67b0d97SEric Nelson MX6_PAD_RGMII_RXC__GPIO_6_30 | MUX_PAD_CTRL(NO_PAD_CTRL), 180*d67b0d97SEric Nelson /* pin 32 - 1 - (MODE0) all */ 181*d67b0d97SEric Nelson MX6_PAD_RGMII_RD0__GPIO_6_25 | MUX_PAD_CTRL(NO_PAD_CTRL), 182*d67b0d97SEric Nelson /* pin 31 - 1 - (MODE1) all */ 183*d67b0d97SEric Nelson MX6_PAD_RGMII_RD1__GPIO_6_27 | MUX_PAD_CTRL(NO_PAD_CTRL), 184*d67b0d97SEric Nelson /* pin 28 - 1 - (MODE2) all */ 185*d67b0d97SEric Nelson MX6_PAD_RGMII_RD2__GPIO_6_28 | MUX_PAD_CTRL(NO_PAD_CTRL), 186*d67b0d97SEric Nelson /* pin 27 - 1 - (MODE3) all */ 187*d67b0d97SEric Nelson MX6_PAD_RGMII_RD3__GPIO_6_29 | MUX_PAD_CTRL(NO_PAD_CTRL), 188*d67b0d97SEric Nelson /* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */ 189*d67b0d97SEric Nelson MX6_PAD_RGMII_RX_CTL__GPIO_6_24 | MUX_PAD_CTRL(NO_PAD_CTRL), 190*d67b0d97SEric Nelson /* pin 42 PHY nRST */ 191*d67b0d97SEric Nelson MX6_PAD_EIM_D23__GPIO_3_23 | MUX_PAD_CTRL(NO_PAD_CTRL), 192*d67b0d97SEric Nelson MX6_PAD_ENET_RXD0__GPIO_1_27 | MUX_PAD_CTRL(NO_PAD_CTRL), 193*d67b0d97SEric Nelson }; 194*d67b0d97SEric Nelson 195*d67b0d97SEric Nelson iomux_v3_cfg_t const enet_pads2[] = { 196*d67b0d97SEric Nelson MX6_PAD_RGMII_RXC__ENET_RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL), 197*d67b0d97SEric Nelson MX6_PAD_RGMII_RD0__ENET_RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), 198*d67b0d97SEric Nelson MX6_PAD_RGMII_RD1__ENET_RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), 199*d67b0d97SEric Nelson MX6_PAD_RGMII_RD2__ENET_RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), 200*d67b0d97SEric Nelson MX6_PAD_RGMII_RD3__ENET_RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), 201*d67b0d97SEric Nelson MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), 202*d67b0d97SEric Nelson }; 203*d67b0d97SEric Nelson 204*d67b0d97SEric Nelson /* wl1271 pads on nitrogen6x */ 205*d67b0d97SEric Nelson iomux_v3_cfg_t const wl12xx_pads[] = { 206*d67b0d97SEric Nelson (MX6_PAD_NANDF_CS1__GPIO_6_14 & ~MUX_PAD_CTRL_MASK) 207*d67b0d97SEric Nelson | MUX_PAD_CTRL(WEAK_PULLDOWN), 208*d67b0d97SEric Nelson (MX6_PAD_NANDF_CS2__GPIO_6_15 & ~MUX_PAD_CTRL_MASK) 209*d67b0d97SEric Nelson | MUX_PAD_CTRL(OUTPUT_40OHM), 210*d67b0d97SEric Nelson (MX6_PAD_NANDF_CS3__GPIO_6_16 & ~MUX_PAD_CTRL_MASK) 211*d67b0d97SEric Nelson | MUX_PAD_CTRL(OUTPUT_40OHM), 212*d67b0d97SEric Nelson }; 213*d67b0d97SEric Nelson #define WL12XX_WL_IRQ_GP IMX_GPIO_NR(6, 14) 214*d67b0d97SEric Nelson #define WL12XX_WL_ENABLE_GP IMX_GPIO_NR(6, 15) 215*d67b0d97SEric Nelson #define WL12XX_BT_ENABLE_GP IMX_GPIO_NR(6, 16) 216*d67b0d97SEric Nelson 217*d67b0d97SEric Nelson /* Button assignments for J14 */ 218*d67b0d97SEric Nelson static iomux_v3_cfg_t const button_pads[] = { 219*d67b0d97SEric Nelson /* Menu */ 220*d67b0d97SEric Nelson MX6_PAD_NANDF_D1__GPIO_2_1 | MUX_PAD_CTRL(BUTTON_PAD_CTRL), 221*d67b0d97SEric Nelson /* Back */ 222*d67b0d97SEric Nelson MX6_PAD_NANDF_D2__GPIO_2_2 | MUX_PAD_CTRL(BUTTON_PAD_CTRL), 223*d67b0d97SEric Nelson /* Labelled Search (mapped to Power under Android) */ 224*d67b0d97SEric Nelson MX6_PAD_NANDF_D3__GPIO_2_3 | MUX_PAD_CTRL(BUTTON_PAD_CTRL), 225*d67b0d97SEric Nelson /* Home */ 226*d67b0d97SEric Nelson MX6_PAD_NANDF_D4__GPIO_2_4 | MUX_PAD_CTRL(BUTTON_PAD_CTRL), 227*d67b0d97SEric Nelson /* Volume Down */ 228*d67b0d97SEric Nelson MX6_PAD_GPIO_19__GPIO_4_5 | MUX_PAD_CTRL(BUTTON_PAD_CTRL), 229*d67b0d97SEric Nelson /* Volume Up */ 230*d67b0d97SEric Nelson MX6_PAD_GPIO_18__GPIO_7_13 | MUX_PAD_CTRL(BUTTON_PAD_CTRL), 231*d67b0d97SEric Nelson }; 232*d67b0d97SEric Nelson 233*d67b0d97SEric Nelson static void setup_iomux_enet(void) 234*d67b0d97SEric Nelson { 235*d67b0d97SEric Nelson gpio_direction_output(IMX_GPIO_NR(3, 23), 0); /* SABRE Lite PHY rst */ 236*d67b0d97SEric Nelson gpio_direction_output(IMX_GPIO_NR(1, 27), 0); /* Nitrogen6X PHY rst */ 237*d67b0d97SEric Nelson gpio_direction_output(IMX_GPIO_NR(6, 30), 1); 238*d67b0d97SEric Nelson gpio_direction_output(IMX_GPIO_NR(6, 25), 1); 239*d67b0d97SEric Nelson gpio_direction_output(IMX_GPIO_NR(6, 27), 1); 240*d67b0d97SEric Nelson gpio_direction_output(IMX_GPIO_NR(6, 28), 1); 241*d67b0d97SEric Nelson gpio_direction_output(IMX_GPIO_NR(6, 29), 1); 242*d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(enet_pads1, ARRAY_SIZE(enet_pads1)); 243*d67b0d97SEric Nelson gpio_direction_output(IMX_GPIO_NR(6, 24), 1); 244*d67b0d97SEric Nelson 245*d67b0d97SEric Nelson /* Need delay 10ms according to KSZ9021 spec */ 246*d67b0d97SEric Nelson udelay(1000 * 10); 247*d67b0d97SEric Nelson gpio_set_value(IMX_GPIO_NR(3, 23), 1); /* SABRE Lite PHY reset */ 248*d67b0d97SEric Nelson gpio_set_value(IMX_GPIO_NR(1, 27), 1); /* Nitrogen6X PHY reset */ 249*d67b0d97SEric Nelson 250*d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(enet_pads2, ARRAY_SIZE(enet_pads2)); 251*d67b0d97SEric Nelson } 252*d67b0d97SEric Nelson 253*d67b0d97SEric Nelson iomux_v3_cfg_t const usb_pads[] = { 254*d67b0d97SEric Nelson MX6_PAD_GPIO_17__GPIO_7_12 | MUX_PAD_CTRL(NO_PAD_CTRL), 255*d67b0d97SEric Nelson }; 256*d67b0d97SEric Nelson 257*d67b0d97SEric Nelson static void setup_iomux_uart(void) 258*d67b0d97SEric Nelson { 259*d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); 260*d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads)); 261*d67b0d97SEric Nelson } 262*d67b0d97SEric Nelson 263*d67b0d97SEric Nelson #ifdef CONFIG_USB_EHCI_MX6 264*d67b0d97SEric Nelson int board_ehci_hcd_init(int port) 265*d67b0d97SEric Nelson { 266*d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(usb_pads, ARRAY_SIZE(usb_pads)); 267*d67b0d97SEric Nelson 268*d67b0d97SEric Nelson /* Reset USB hub */ 269*d67b0d97SEric Nelson gpio_direction_output(IMX_GPIO_NR(7, 12), 0); 270*d67b0d97SEric Nelson mdelay(2); 271*d67b0d97SEric Nelson gpio_set_value(IMX_GPIO_NR(7, 12), 1); 272*d67b0d97SEric Nelson 273*d67b0d97SEric Nelson return 0; 274*d67b0d97SEric Nelson } 275*d67b0d97SEric Nelson #endif 276*d67b0d97SEric Nelson 277*d67b0d97SEric Nelson #ifdef CONFIG_FSL_ESDHC 278*d67b0d97SEric Nelson struct fsl_esdhc_cfg usdhc_cfg[2] = { 279*d67b0d97SEric Nelson {USDHC3_BASE_ADDR}, 280*d67b0d97SEric Nelson {USDHC4_BASE_ADDR}, 281*d67b0d97SEric Nelson }; 282*d67b0d97SEric Nelson 283*d67b0d97SEric Nelson int board_mmc_getcd(struct mmc *mmc) 284*d67b0d97SEric Nelson { 285*d67b0d97SEric Nelson struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; 286*d67b0d97SEric Nelson int ret; 287*d67b0d97SEric Nelson 288*d67b0d97SEric Nelson if (cfg->esdhc_base == USDHC3_BASE_ADDR) { 289*d67b0d97SEric Nelson gpio_direction_input(IMX_GPIO_NR(7, 0)); 290*d67b0d97SEric Nelson ret = !gpio_get_value(IMX_GPIO_NR(7, 0)); 291*d67b0d97SEric Nelson } else { 292*d67b0d97SEric Nelson gpio_direction_input(IMX_GPIO_NR(2, 6)); 293*d67b0d97SEric Nelson ret = !gpio_get_value(IMX_GPIO_NR(2, 6)); 294*d67b0d97SEric Nelson } 295*d67b0d97SEric Nelson 296*d67b0d97SEric Nelson return ret; 297*d67b0d97SEric Nelson } 298*d67b0d97SEric Nelson 299*d67b0d97SEric Nelson int board_mmc_init(bd_t *bis) 300*d67b0d97SEric Nelson { 301*d67b0d97SEric Nelson s32 status = 0; 302*d67b0d97SEric Nelson u32 index = 0; 303*d67b0d97SEric Nelson 304*d67b0d97SEric Nelson usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); 305*d67b0d97SEric Nelson usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); 306*d67b0d97SEric Nelson 307*d67b0d97SEric Nelson for (index = 0; index < CONFIG_SYS_FSL_USDHC_NUM; ++index) { 308*d67b0d97SEric Nelson switch (index) { 309*d67b0d97SEric Nelson case 0: 310*d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads( 311*d67b0d97SEric Nelson usdhc3_pads, ARRAY_SIZE(usdhc3_pads)); 312*d67b0d97SEric Nelson break; 313*d67b0d97SEric Nelson case 1: 314*d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads( 315*d67b0d97SEric Nelson usdhc4_pads, ARRAY_SIZE(usdhc4_pads)); 316*d67b0d97SEric Nelson break; 317*d67b0d97SEric Nelson default: 318*d67b0d97SEric Nelson printf("Warning: you configured more USDHC controllers" 319*d67b0d97SEric Nelson "(%d) then supported by the board (%d)\n", 320*d67b0d97SEric Nelson index + 1, CONFIG_SYS_FSL_USDHC_NUM); 321*d67b0d97SEric Nelson return status; 322*d67b0d97SEric Nelson } 323*d67b0d97SEric Nelson 324*d67b0d97SEric Nelson status |= fsl_esdhc_initialize(bis, &usdhc_cfg[index]); 325*d67b0d97SEric Nelson } 326*d67b0d97SEric Nelson 327*d67b0d97SEric Nelson return status; 328*d67b0d97SEric Nelson } 329*d67b0d97SEric Nelson #endif 330*d67b0d97SEric Nelson 331*d67b0d97SEric Nelson u32 get_board_rev(void) 332*d67b0d97SEric Nelson { 333*d67b0d97SEric Nelson return 0x63000; 334*d67b0d97SEric Nelson } 335*d67b0d97SEric Nelson 336*d67b0d97SEric Nelson #ifdef CONFIG_MXC_SPI 337*d67b0d97SEric Nelson iomux_v3_cfg_t const ecspi1_pads[] = { 338*d67b0d97SEric Nelson /* SS1 */ 339*d67b0d97SEric Nelson MX6_PAD_EIM_D19__GPIO_3_19 | MUX_PAD_CTRL(SPI_PAD_CTRL), 340*d67b0d97SEric Nelson MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL), 341*d67b0d97SEric Nelson MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL), 342*d67b0d97SEric Nelson MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL), 343*d67b0d97SEric Nelson }; 344*d67b0d97SEric Nelson 345*d67b0d97SEric Nelson void setup_spi(void) 346*d67b0d97SEric Nelson { 347*d67b0d97SEric Nelson gpio_direction_output(CONFIG_SF_DEFAULT_CS, 1); 348*d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(ecspi1_pads, 349*d67b0d97SEric Nelson ARRAY_SIZE(ecspi1_pads)); 350*d67b0d97SEric Nelson } 351*d67b0d97SEric Nelson #endif 352*d67b0d97SEric Nelson 353*d67b0d97SEric Nelson int board_phy_config(struct phy_device *phydev) 354*d67b0d97SEric Nelson { 355*d67b0d97SEric Nelson /* min rx data delay */ 356*d67b0d97SEric Nelson ksz9021_phy_extended_write(phydev, 357*d67b0d97SEric Nelson MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0x0); 358*d67b0d97SEric Nelson /* min tx data delay */ 359*d67b0d97SEric Nelson ksz9021_phy_extended_write(phydev, 360*d67b0d97SEric Nelson MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW, 0x0); 361*d67b0d97SEric Nelson /* max rx/tx clock delay, min rx/tx control */ 362*d67b0d97SEric Nelson ksz9021_phy_extended_write(phydev, 363*d67b0d97SEric Nelson MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, 0xf0f0); 364*d67b0d97SEric Nelson if (phydev->drv->config) 365*d67b0d97SEric Nelson phydev->drv->config(phydev); 366*d67b0d97SEric Nelson 367*d67b0d97SEric Nelson return 0; 368*d67b0d97SEric Nelson } 369*d67b0d97SEric Nelson 370*d67b0d97SEric Nelson int board_eth_init(bd_t *bis) 371*d67b0d97SEric Nelson { 372*d67b0d97SEric Nelson uint32_t base = IMX_FEC_BASE; 373*d67b0d97SEric Nelson struct mii_dev *bus = NULL; 374*d67b0d97SEric Nelson struct phy_device *phydev = NULL; 375*d67b0d97SEric Nelson int ret; 376*d67b0d97SEric Nelson 377*d67b0d97SEric Nelson setup_iomux_enet(); 378*d67b0d97SEric Nelson 379*d67b0d97SEric Nelson #ifdef CONFIG_FEC_MXC 380*d67b0d97SEric Nelson bus = fec_get_miibus(base, -1); 381*d67b0d97SEric Nelson if (!bus) 382*d67b0d97SEric Nelson return 0; 383*d67b0d97SEric Nelson /* scan phy 4,5,6,7 */ 384*d67b0d97SEric Nelson phydev = phy_find_by_mask(bus, (0xf << 4), PHY_INTERFACE_MODE_RGMII); 385*d67b0d97SEric Nelson if (!phydev) { 386*d67b0d97SEric Nelson free(bus); 387*d67b0d97SEric Nelson return 0; 388*d67b0d97SEric Nelson } 389*d67b0d97SEric Nelson printf("using phy at %d\n", phydev->addr); 390*d67b0d97SEric Nelson ret = fec_probe(bis, -1, base, bus, phydev); 391*d67b0d97SEric Nelson if (ret) { 392*d67b0d97SEric Nelson printf("FEC MXC: %s:failed\n", __func__); 393*d67b0d97SEric Nelson free(phydev); 394*d67b0d97SEric Nelson free(bus); 395*d67b0d97SEric Nelson } 396*d67b0d97SEric Nelson #endif 397*d67b0d97SEric Nelson return 0; 398*d67b0d97SEric Nelson } 399*d67b0d97SEric Nelson 400*d67b0d97SEric Nelson static void setup_buttons(void) 401*d67b0d97SEric Nelson { 402*d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(button_pads, 403*d67b0d97SEric Nelson ARRAY_SIZE(button_pads)); 404*d67b0d97SEric Nelson } 405*d67b0d97SEric Nelson 406*d67b0d97SEric Nelson #ifdef CONFIG_CMD_SATA 407*d67b0d97SEric Nelson 408*d67b0d97SEric Nelson int setup_sata(void) 409*d67b0d97SEric Nelson { 410*d67b0d97SEric Nelson struct iomuxc_base_regs *const iomuxc_regs 411*d67b0d97SEric Nelson = (struct iomuxc_base_regs *) IOMUXC_BASE_ADDR; 412*d67b0d97SEric Nelson int ret = enable_sata_clock(); 413*d67b0d97SEric Nelson if (ret) 414*d67b0d97SEric Nelson return ret; 415*d67b0d97SEric Nelson 416*d67b0d97SEric Nelson clrsetbits_le32(&iomuxc_regs->gpr[13], 417*d67b0d97SEric Nelson IOMUXC_GPR13_SATA_MASK, 418*d67b0d97SEric Nelson IOMUXC_GPR13_SATA_PHY_8_RXEQ_3P0DB 419*d67b0d97SEric Nelson |IOMUXC_GPR13_SATA_PHY_7_SATA2M 420*d67b0d97SEric Nelson |IOMUXC_GPR13_SATA_SPEED_3G 421*d67b0d97SEric Nelson |(3<<IOMUXC_GPR13_SATA_PHY_6_SHIFT) 422*d67b0d97SEric Nelson |IOMUXC_GPR13_SATA_SATA_PHY_5_SS_DISABLED 423*d67b0d97SEric Nelson |IOMUXC_GPR13_SATA_SATA_PHY_4_ATTEN_9_16 424*d67b0d97SEric Nelson |IOMUXC_GPR13_SATA_PHY_3_TXBOOST_0P00_DB 425*d67b0d97SEric Nelson |IOMUXC_GPR13_SATA_PHY_2_TX_1P104V 426*d67b0d97SEric Nelson |IOMUXC_GPR13_SATA_PHY_1_SLOW); 427*d67b0d97SEric Nelson 428*d67b0d97SEric Nelson return 0; 429*d67b0d97SEric Nelson } 430*d67b0d97SEric Nelson #endif 431*d67b0d97SEric Nelson 432*d67b0d97SEric Nelson #if defined(CONFIG_VIDEO_IPUV3) 433*d67b0d97SEric Nelson 434*d67b0d97SEric Nelson static iomux_v3_cfg_t const backlight_pads[] = { 435*d67b0d97SEric Nelson /* Backlight on RGB connector: J15 */ 436*d67b0d97SEric Nelson MX6_PAD_SD1_DAT3__GPIO_1_21 | MUX_PAD_CTRL(NO_PAD_CTRL), 437*d67b0d97SEric Nelson #define RGB_BACKLIGHT_GP IMX_GPIO_NR(1, 21) 438*d67b0d97SEric Nelson 439*d67b0d97SEric Nelson /* Backlight on LVDS connector: J6 */ 440*d67b0d97SEric Nelson MX6_PAD_SD1_CMD__GPIO_1_18 | MUX_PAD_CTRL(NO_PAD_CTRL), 441*d67b0d97SEric Nelson #define LVDS_BACKLIGHT_GP IMX_GPIO_NR(1, 18) 442*d67b0d97SEric Nelson }; 443*d67b0d97SEric Nelson 444*d67b0d97SEric Nelson static iomux_v3_cfg_t const rgb_pads[] = { 445*d67b0d97SEric Nelson MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK, 446*d67b0d97SEric Nelson MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15, 447*d67b0d97SEric Nelson MX6_PAD_DI0_PIN2__IPU1_DI0_PIN2, 448*d67b0d97SEric Nelson MX6_PAD_DI0_PIN3__IPU1_DI0_PIN3, 449*d67b0d97SEric Nelson MX6_PAD_DI0_PIN4__GPIO_4_20, 450*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0, 451*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1, 452*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2, 453*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3, 454*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4, 455*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5, 456*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6, 457*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7, 458*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8, 459*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9, 460*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10, 461*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11, 462*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12, 463*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13, 464*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14, 465*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15, 466*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16, 467*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17, 468*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18, 469*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19, 470*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20, 471*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21, 472*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22, 473*d67b0d97SEric Nelson MX6_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23, 474*d67b0d97SEric Nelson }; 475*d67b0d97SEric Nelson 476*d67b0d97SEric Nelson struct display_info_t { 477*d67b0d97SEric Nelson int bus; 478*d67b0d97SEric Nelson int addr; 479*d67b0d97SEric Nelson int pixfmt; 480*d67b0d97SEric Nelson int (*detect)(struct display_info_t const *dev); 481*d67b0d97SEric Nelson void (*enable)(struct display_info_t const *dev); 482*d67b0d97SEric Nelson struct fb_videomode mode; 483*d67b0d97SEric Nelson }; 484*d67b0d97SEric Nelson 485*d67b0d97SEric Nelson 486*d67b0d97SEric Nelson static int detect_hdmi(struct display_info_t const *dev) 487*d67b0d97SEric Nelson { 488*d67b0d97SEric Nelson struct hdmi_regs *hdmi = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR; 489*d67b0d97SEric Nelson return readb(&hdmi->phy_stat0) & HDMI_PHY_HPD; 490*d67b0d97SEric Nelson } 491*d67b0d97SEric Nelson 492*d67b0d97SEric Nelson static void enable_hdmi(struct display_info_t const *dev) 493*d67b0d97SEric Nelson { 494*d67b0d97SEric Nelson struct hdmi_regs *hdmi = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR; 495*d67b0d97SEric Nelson u8 reg; 496*d67b0d97SEric Nelson printf("%s: setup HDMI monitor\n", __func__); 497*d67b0d97SEric Nelson reg = readb(&hdmi->phy_conf0); 498*d67b0d97SEric Nelson reg |= HDMI_PHY_CONF0_PDZ_MASK; 499*d67b0d97SEric Nelson writeb(reg, &hdmi->phy_conf0); 500*d67b0d97SEric Nelson 501*d67b0d97SEric Nelson udelay(3000); 502*d67b0d97SEric Nelson reg |= HDMI_PHY_CONF0_ENTMDS_MASK; 503*d67b0d97SEric Nelson writeb(reg, &hdmi->phy_conf0); 504*d67b0d97SEric Nelson udelay(3000); 505*d67b0d97SEric Nelson reg |= HDMI_PHY_CONF0_GEN2_TXPWRON_MASK; 506*d67b0d97SEric Nelson writeb(reg, &hdmi->phy_conf0); 507*d67b0d97SEric Nelson writeb(HDMI_MC_PHYRSTZ_ASSERT, &hdmi->mc_phyrstz); 508*d67b0d97SEric Nelson } 509*d67b0d97SEric Nelson 510*d67b0d97SEric Nelson static int detect_i2c(struct display_info_t const *dev) 511*d67b0d97SEric Nelson { 512*d67b0d97SEric Nelson return ((0 == i2c_set_bus_num(dev->bus)) 513*d67b0d97SEric Nelson && 514*d67b0d97SEric Nelson (0 == i2c_probe(dev->addr))); 515*d67b0d97SEric Nelson } 516*d67b0d97SEric Nelson 517*d67b0d97SEric Nelson static void enable_lvds(struct display_info_t const *dev) 518*d67b0d97SEric Nelson { 519*d67b0d97SEric Nelson struct iomuxc *iomux = (struct iomuxc *) 520*d67b0d97SEric Nelson IOMUXC_BASE_ADDR; 521*d67b0d97SEric Nelson u32 reg = readl(&iomux->gpr[2]); 522*d67b0d97SEric Nelson reg |= IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT; 523*d67b0d97SEric Nelson writel(reg, &iomux->gpr[2]); 524*d67b0d97SEric Nelson gpio_direction_output(LVDS_BACKLIGHT_GP, 1); 525*d67b0d97SEric Nelson } 526*d67b0d97SEric Nelson 527*d67b0d97SEric Nelson static void enable_rgb(struct display_info_t const *dev) 528*d67b0d97SEric Nelson { 529*d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads( 530*d67b0d97SEric Nelson rgb_pads, 531*d67b0d97SEric Nelson ARRAY_SIZE(rgb_pads)); 532*d67b0d97SEric Nelson gpio_direction_output(RGB_BACKLIGHT_GP, 1); 533*d67b0d97SEric Nelson } 534*d67b0d97SEric Nelson 535*d67b0d97SEric Nelson static struct display_info_t const displays[] = {{ 536*d67b0d97SEric Nelson .bus = -1, 537*d67b0d97SEric Nelson .addr = 0, 538*d67b0d97SEric Nelson .pixfmt = IPU_PIX_FMT_RGB24, 539*d67b0d97SEric Nelson .detect = detect_hdmi, 540*d67b0d97SEric Nelson .enable = enable_hdmi, 541*d67b0d97SEric Nelson .mode = { 542*d67b0d97SEric Nelson .name = "HDMI", 543*d67b0d97SEric Nelson .refresh = 60, 544*d67b0d97SEric Nelson .xres = 1024, 545*d67b0d97SEric Nelson .yres = 768, 546*d67b0d97SEric Nelson .pixclock = 15385, 547*d67b0d97SEric Nelson .left_margin = 220, 548*d67b0d97SEric Nelson .right_margin = 40, 549*d67b0d97SEric Nelson .upper_margin = 21, 550*d67b0d97SEric Nelson .lower_margin = 7, 551*d67b0d97SEric Nelson .hsync_len = 60, 552*d67b0d97SEric Nelson .vsync_len = 10, 553*d67b0d97SEric Nelson .sync = FB_SYNC_EXT, 554*d67b0d97SEric Nelson .vmode = FB_VMODE_NONINTERLACED 555*d67b0d97SEric Nelson } }, { 556*d67b0d97SEric Nelson .bus = 2, 557*d67b0d97SEric Nelson .addr = 0x4, 558*d67b0d97SEric Nelson .pixfmt = IPU_PIX_FMT_LVDS666, 559*d67b0d97SEric Nelson .detect = detect_i2c, 560*d67b0d97SEric Nelson .enable = enable_lvds, 561*d67b0d97SEric Nelson .mode = { 562*d67b0d97SEric Nelson .name = "Hannstar-XGA", 563*d67b0d97SEric Nelson .refresh = 60, 564*d67b0d97SEric Nelson .xres = 1024, 565*d67b0d97SEric Nelson .yres = 768, 566*d67b0d97SEric Nelson .pixclock = 15385, 567*d67b0d97SEric Nelson .left_margin = 220, 568*d67b0d97SEric Nelson .right_margin = 40, 569*d67b0d97SEric Nelson .upper_margin = 21, 570*d67b0d97SEric Nelson .lower_margin = 7, 571*d67b0d97SEric Nelson .hsync_len = 60, 572*d67b0d97SEric Nelson .vsync_len = 10, 573*d67b0d97SEric Nelson .sync = FB_SYNC_EXT, 574*d67b0d97SEric Nelson .vmode = FB_VMODE_NONINTERLACED 575*d67b0d97SEric Nelson } }, { 576*d67b0d97SEric Nelson .bus = 2, 577*d67b0d97SEric Nelson .addr = 0x38, 578*d67b0d97SEric Nelson .pixfmt = IPU_PIX_FMT_LVDS666, 579*d67b0d97SEric Nelson .detect = detect_i2c, 580*d67b0d97SEric Nelson .enable = enable_lvds, 581*d67b0d97SEric Nelson .mode = { 582*d67b0d97SEric Nelson .name = "wsvga-lvds", 583*d67b0d97SEric Nelson .refresh = 60, 584*d67b0d97SEric Nelson .xres = 1024, 585*d67b0d97SEric Nelson .yres = 600, 586*d67b0d97SEric Nelson .pixclock = 15385, 587*d67b0d97SEric Nelson .left_margin = 220, 588*d67b0d97SEric Nelson .right_margin = 40, 589*d67b0d97SEric Nelson .upper_margin = 21, 590*d67b0d97SEric Nelson .lower_margin = 7, 591*d67b0d97SEric Nelson .hsync_len = 60, 592*d67b0d97SEric Nelson .vsync_len = 10, 593*d67b0d97SEric Nelson .sync = FB_SYNC_EXT, 594*d67b0d97SEric Nelson .vmode = FB_VMODE_NONINTERLACED 595*d67b0d97SEric Nelson } }, { 596*d67b0d97SEric Nelson .bus = 2, 597*d67b0d97SEric Nelson .addr = 0x48, 598*d67b0d97SEric Nelson .pixfmt = IPU_PIX_FMT_RGB666, 599*d67b0d97SEric Nelson .detect = detect_i2c, 600*d67b0d97SEric Nelson .enable = enable_rgb, 601*d67b0d97SEric Nelson .mode = { 602*d67b0d97SEric Nelson .name = "wvga-rgb", 603*d67b0d97SEric Nelson .refresh = 57, 604*d67b0d97SEric Nelson .xres = 800, 605*d67b0d97SEric Nelson .yres = 480, 606*d67b0d97SEric Nelson .pixclock = 37037, 607*d67b0d97SEric Nelson .left_margin = 40, 608*d67b0d97SEric Nelson .right_margin = 60, 609*d67b0d97SEric Nelson .upper_margin = 10, 610*d67b0d97SEric Nelson .lower_margin = 10, 611*d67b0d97SEric Nelson .hsync_len = 20, 612*d67b0d97SEric Nelson .vsync_len = 10, 613*d67b0d97SEric Nelson .sync = 0, 614*d67b0d97SEric Nelson .vmode = FB_VMODE_NONINTERLACED 615*d67b0d97SEric Nelson } } }; 616*d67b0d97SEric Nelson 617*d67b0d97SEric Nelson int board_video_skip(void) 618*d67b0d97SEric Nelson { 619*d67b0d97SEric Nelson int i; 620*d67b0d97SEric Nelson int ret; 621*d67b0d97SEric Nelson char const *panel = getenv("panel"); 622*d67b0d97SEric Nelson if (!panel) { 623*d67b0d97SEric Nelson for (i = 0; i < ARRAY_SIZE(displays); i++) { 624*d67b0d97SEric Nelson struct display_info_t const *dev = displays+i; 625*d67b0d97SEric Nelson if (dev->detect(dev)) { 626*d67b0d97SEric Nelson panel = dev->mode.name; 627*d67b0d97SEric Nelson printf("auto-detected panel %s\n", panel); 628*d67b0d97SEric Nelson break; 629*d67b0d97SEric Nelson } 630*d67b0d97SEric Nelson } 631*d67b0d97SEric Nelson if (!panel) { 632*d67b0d97SEric Nelson panel = displays[0].mode.name; 633*d67b0d97SEric Nelson printf("No panel detected: default to %s\n", panel); 634*d67b0d97SEric Nelson } 635*d67b0d97SEric Nelson } else { 636*d67b0d97SEric Nelson for (i = 0; i < ARRAY_SIZE(displays); i++) { 637*d67b0d97SEric Nelson if (!strcmp(panel, displays[i].mode.name)) 638*d67b0d97SEric Nelson break; 639*d67b0d97SEric Nelson } 640*d67b0d97SEric Nelson } 641*d67b0d97SEric Nelson if (i < ARRAY_SIZE(displays)) { 642*d67b0d97SEric Nelson ret = ipuv3_fb_init(&displays[i].mode, 0, 643*d67b0d97SEric Nelson displays[i].pixfmt); 644*d67b0d97SEric Nelson if (!ret) { 645*d67b0d97SEric Nelson displays[i].enable(displays+i); 646*d67b0d97SEric Nelson printf("Display: %s (%ux%u)\n", 647*d67b0d97SEric Nelson displays[i].mode.name, 648*d67b0d97SEric Nelson displays[i].mode.xres, 649*d67b0d97SEric Nelson displays[i].mode.yres); 650*d67b0d97SEric Nelson } else 651*d67b0d97SEric Nelson printf("LCD %s cannot be configured: %d\n", 652*d67b0d97SEric Nelson displays[i].mode.name, ret); 653*d67b0d97SEric Nelson } else { 654*d67b0d97SEric Nelson printf("unsupported panel %s\n", panel); 655*d67b0d97SEric Nelson ret = -EINVAL; 656*d67b0d97SEric Nelson } 657*d67b0d97SEric Nelson return (0 != ret); 658*d67b0d97SEric Nelson } 659*d67b0d97SEric Nelson 660*d67b0d97SEric Nelson static void setup_display(void) 661*d67b0d97SEric Nelson { 662*d67b0d97SEric Nelson struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 663*d67b0d97SEric Nelson struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; 664*d67b0d97SEric Nelson struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; 665*d67b0d97SEric Nelson struct hdmi_regs *hdmi = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR; 666*d67b0d97SEric Nelson 667*d67b0d97SEric Nelson int reg; 668*d67b0d97SEric Nelson 669*d67b0d97SEric Nelson /* Turn on LDB0,IPU,IPU DI0 clocks */ 670*d67b0d97SEric Nelson reg = __raw_readl(&mxc_ccm->CCGR3); 671*d67b0d97SEric Nelson reg |= MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET 672*d67b0d97SEric Nelson |MXC_CCM_CCGR3_LDB_DI0_MASK; 673*d67b0d97SEric Nelson writel(reg, &mxc_ccm->CCGR3); 674*d67b0d97SEric Nelson 675*d67b0d97SEric Nelson /* Turn on HDMI PHY clock */ 676*d67b0d97SEric Nelson reg = __raw_readl(&mxc_ccm->CCGR2); 677*d67b0d97SEric Nelson reg |= MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_MASK 678*d67b0d97SEric Nelson |MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_MASK; 679*d67b0d97SEric Nelson writel(reg, &mxc_ccm->CCGR2); 680*d67b0d97SEric Nelson 681*d67b0d97SEric Nelson /* clear HDMI PHY reset */ 682*d67b0d97SEric Nelson writeb(HDMI_MC_PHYRSTZ_DEASSERT, &hdmi->mc_phyrstz); 683*d67b0d97SEric Nelson 684*d67b0d97SEric Nelson /* set PFD1_FRAC to 0x13 == 455 MHz (480*18)/0x13 */ 685*d67b0d97SEric Nelson writel(ANATOP_PFD_480_PFD1_FRAC_MASK, &anatop->pfd_480_clr); 686*d67b0d97SEric Nelson writel(0x13<<ANATOP_PFD_480_PFD1_FRAC_SHIFT, &anatop->pfd_480_set); 687*d67b0d97SEric Nelson 688*d67b0d97SEric Nelson /* set LDB0, LDB1 clk select to 011/011 */ 689*d67b0d97SEric Nelson reg = readl(&mxc_ccm->cs2cdr); 690*d67b0d97SEric Nelson reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK 691*d67b0d97SEric Nelson |MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK); 692*d67b0d97SEric Nelson reg |= (3<<MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) 693*d67b0d97SEric Nelson |(3<<MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET); 694*d67b0d97SEric Nelson writel(reg, &mxc_ccm->cs2cdr); 695*d67b0d97SEric Nelson 696*d67b0d97SEric Nelson reg = readl(&mxc_ccm->cscmr2); 697*d67b0d97SEric Nelson reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV; 698*d67b0d97SEric Nelson writel(reg, &mxc_ccm->cscmr2); 699*d67b0d97SEric Nelson 700*d67b0d97SEric Nelson reg = readl(&mxc_ccm->chsccdr); 701*d67b0d97SEric Nelson reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK 702*d67b0d97SEric Nelson |MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK 703*d67b0d97SEric Nelson |MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK); 704*d67b0d97SEric Nelson reg |= (CHSCCDR_CLK_SEL_LDB_DI0 705*d67b0d97SEric Nelson <<MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET) 706*d67b0d97SEric Nelson |(CHSCCDR_PODF_DIVIDE_BY_3 707*d67b0d97SEric Nelson <<MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET) 708*d67b0d97SEric Nelson |(CHSCCDR_IPU_PRE_CLK_540M_PFD 709*d67b0d97SEric Nelson <<MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET); 710*d67b0d97SEric Nelson writel(reg, &mxc_ccm->chsccdr); 711*d67b0d97SEric Nelson 712*d67b0d97SEric Nelson reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES 713*d67b0d97SEric Nelson |IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH 714*d67b0d97SEric Nelson |IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW 715*d67b0d97SEric Nelson |IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG 716*d67b0d97SEric Nelson |IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT 717*d67b0d97SEric Nelson |IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG 718*d67b0d97SEric Nelson |IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT 719*d67b0d97SEric Nelson |IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED 720*d67b0d97SEric Nelson |IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0; 721*d67b0d97SEric Nelson writel(reg, &iomux->gpr[2]); 722*d67b0d97SEric Nelson 723*d67b0d97SEric Nelson reg = readl(&iomux->gpr[3]); 724*d67b0d97SEric Nelson reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK) 725*d67b0d97SEric Nelson | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 726*d67b0d97SEric Nelson <<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET); 727*d67b0d97SEric Nelson writel(reg, &iomux->gpr[3]); 728*d67b0d97SEric Nelson 729*d67b0d97SEric Nelson /* backlights off until needed */ 730*d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(backlight_pads, 731*d67b0d97SEric Nelson ARRAY_SIZE(backlight_pads)); 732*d67b0d97SEric Nelson gpio_direction_input(LVDS_BACKLIGHT_GP); 733*d67b0d97SEric Nelson gpio_direction_input(RGB_BACKLIGHT_GP); 734*d67b0d97SEric Nelson } 735*d67b0d97SEric Nelson #endif 736*d67b0d97SEric Nelson 737*d67b0d97SEric Nelson int board_early_init_f(void) 738*d67b0d97SEric Nelson { 739*d67b0d97SEric Nelson setup_iomux_uart(); 740*d67b0d97SEric Nelson 741*d67b0d97SEric Nelson /* Disable wl1271 For Nitrogen6w */ 742*d67b0d97SEric Nelson gpio_direction_input(WL12XX_WL_IRQ_GP); 743*d67b0d97SEric Nelson gpio_direction_output(WL12XX_WL_ENABLE_GP, 0); 744*d67b0d97SEric Nelson gpio_direction_output(WL12XX_BT_ENABLE_GP, 0); 745*d67b0d97SEric Nelson 746*d67b0d97SEric Nelson imx_iomux_v3_setup_multiple_pads(wl12xx_pads, ARRAY_SIZE(wl12xx_pads)); 747*d67b0d97SEric Nelson setup_buttons(); 748*d67b0d97SEric Nelson 749*d67b0d97SEric Nelson #if defined(CONFIG_VIDEO_IPUV3) 750*d67b0d97SEric Nelson setup_display(); 751*d67b0d97SEric Nelson #endif 752*d67b0d97SEric Nelson return 0; 753*d67b0d97SEric Nelson } 754*d67b0d97SEric Nelson 755*d67b0d97SEric Nelson /* 756*d67b0d97SEric Nelson * Do not overwrite the console 757*d67b0d97SEric Nelson * Use always serial for U-Boot console 758*d67b0d97SEric Nelson */ 759*d67b0d97SEric Nelson int overwrite_console(void) 760*d67b0d97SEric Nelson { 761*d67b0d97SEric Nelson return 1; 762*d67b0d97SEric Nelson } 763*d67b0d97SEric Nelson 764*d67b0d97SEric Nelson int board_init(void) 765*d67b0d97SEric Nelson { 766*d67b0d97SEric Nelson /* address of boot parameters */ 767*d67b0d97SEric Nelson gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; 768*d67b0d97SEric Nelson 769*d67b0d97SEric Nelson #ifdef CONFIG_MXC_SPI 770*d67b0d97SEric Nelson setup_spi(); 771*d67b0d97SEric Nelson #endif 772*d67b0d97SEric Nelson setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info0); 773*d67b0d97SEric Nelson setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1); 774*d67b0d97SEric Nelson setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2); 775*d67b0d97SEric Nelson 776*d67b0d97SEric Nelson #ifdef CONFIG_CMD_SATA 777*d67b0d97SEric Nelson setup_sata(); 778*d67b0d97SEric Nelson #endif 779*d67b0d97SEric Nelson 780*d67b0d97SEric Nelson return 0; 781*d67b0d97SEric Nelson } 782*d67b0d97SEric Nelson 783*d67b0d97SEric Nelson int checkboard(void) 784*d67b0d97SEric Nelson { 785*d67b0d97SEric Nelson if (gpio_get_value(WL12XX_WL_IRQ_GP)) 786*d67b0d97SEric Nelson puts("Board: Nitrogen6X\n"); 787*d67b0d97SEric Nelson else 788*d67b0d97SEric Nelson puts("Board: SABRE Lite\n"); 789*d67b0d97SEric Nelson 790*d67b0d97SEric Nelson return 0; 791*d67b0d97SEric Nelson } 792*d67b0d97SEric Nelson 793*d67b0d97SEric Nelson struct button_key { 794*d67b0d97SEric Nelson char const *name; 795*d67b0d97SEric Nelson unsigned gpnum; 796*d67b0d97SEric Nelson char ident; 797*d67b0d97SEric Nelson }; 798*d67b0d97SEric Nelson 799*d67b0d97SEric Nelson static struct button_key const buttons[] = { 800*d67b0d97SEric Nelson {"back", IMX_GPIO_NR(2, 2), 'B'}, 801*d67b0d97SEric Nelson {"home", IMX_GPIO_NR(2, 4), 'H'}, 802*d67b0d97SEric Nelson {"menu", IMX_GPIO_NR(2, 1), 'M'}, 803*d67b0d97SEric Nelson {"search", IMX_GPIO_NR(2, 3), 'S'}, 804*d67b0d97SEric Nelson {"volup", IMX_GPIO_NR(7, 13), 'V'}, 805*d67b0d97SEric Nelson {"voldown", IMX_GPIO_NR(4, 5), 'v'}, 806*d67b0d97SEric Nelson }; 807*d67b0d97SEric Nelson 808*d67b0d97SEric Nelson /* 809*d67b0d97SEric Nelson * generate a null-terminated string containing the buttons pressed 810*d67b0d97SEric Nelson * returns number of keys pressed 811*d67b0d97SEric Nelson */ 812*d67b0d97SEric Nelson static int read_keys(char *buf) 813*d67b0d97SEric Nelson { 814*d67b0d97SEric Nelson int i, numpressed = 0; 815*d67b0d97SEric Nelson for (i = 0; i < ARRAY_SIZE(buttons); i++) { 816*d67b0d97SEric Nelson if (!gpio_get_value(buttons[i].gpnum)) 817*d67b0d97SEric Nelson buf[numpressed++] = buttons[i].ident; 818*d67b0d97SEric Nelson } 819*d67b0d97SEric Nelson buf[numpressed] = '\0'; 820*d67b0d97SEric Nelson return numpressed; 821*d67b0d97SEric Nelson } 822*d67b0d97SEric Nelson 823*d67b0d97SEric Nelson static int do_kbd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 824*d67b0d97SEric Nelson { 825*d67b0d97SEric Nelson char envvalue[ARRAY_SIZE(buttons)+1]; 826*d67b0d97SEric Nelson int numpressed = read_keys(envvalue); 827*d67b0d97SEric Nelson setenv("keybd", envvalue); 828*d67b0d97SEric Nelson return numpressed == 0; 829*d67b0d97SEric Nelson } 830*d67b0d97SEric Nelson 831*d67b0d97SEric Nelson U_BOOT_CMD( 832*d67b0d97SEric Nelson kbd, 1, 1, do_kbd, 833*d67b0d97SEric Nelson "Tests for keypresses, sets 'keybd' environment variable", 834*d67b0d97SEric Nelson "Returns 0 (true) to shell if key is pressed." 835*d67b0d97SEric Nelson ); 836*d67b0d97SEric Nelson 837*d67b0d97SEric Nelson #ifdef CONFIG_PREBOOT 838*d67b0d97SEric Nelson static char const kbd_magic_prefix[] = "key_magic"; 839*d67b0d97SEric Nelson static char const kbd_command_prefix[] = "key_cmd"; 840*d67b0d97SEric Nelson 841*d67b0d97SEric Nelson static void preboot_keys(void) 842*d67b0d97SEric Nelson { 843*d67b0d97SEric Nelson int numpressed; 844*d67b0d97SEric Nelson char keypress[ARRAY_SIZE(buttons)+1]; 845*d67b0d97SEric Nelson numpressed = read_keys(keypress); 846*d67b0d97SEric Nelson if (numpressed) { 847*d67b0d97SEric Nelson char *kbd_magic_keys = getenv("magic_keys"); 848*d67b0d97SEric Nelson char *suffix; 849*d67b0d97SEric Nelson /* 850*d67b0d97SEric Nelson * loop over all magic keys 851*d67b0d97SEric Nelson */ 852*d67b0d97SEric Nelson for (suffix = kbd_magic_keys; *suffix; ++suffix) { 853*d67b0d97SEric Nelson char *keys; 854*d67b0d97SEric Nelson char magic[sizeof(kbd_magic_prefix) + 1]; 855*d67b0d97SEric Nelson sprintf(magic, "%s%c", kbd_magic_prefix, *suffix); 856*d67b0d97SEric Nelson keys = getenv(magic); 857*d67b0d97SEric Nelson if (keys) { 858*d67b0d97SEric Nelson if (!strcmp(keys, keypress)) 859*d67b0d97SEric Nelson break; 860*d67b0d97SEric Nelson } 861*d67b0d97SEric Nelson } 862*d67b0d97SEric Nelson if (*suffix) { 863*d67b0d97SEric Nelson char cmd_name[sizeof(kbd_command_prefix) + 1]; 864*d67b0d97SEric Nelson char *cmd; 865*d67b0d97SEric Nelson sprintf(cmd_name, "%s%c", kbd_command_prefix, *suffix); 866*d67b0d97SEric Nelson cmd = getenv(cmd_name); 867*d67b0d97SEric Nelson if (cmd) { 868*d67b0d97SEric Nelson setenv("preboot", cmd); 869*d67b0d97SEric Nelson return; 870*d67b0d97SEric Nelson } 871*d67b0d97SEric Nelson } 872*d67b0d97SEric Nelson } 873*d67b0d97SEric Nelson } 874*d67b0d97SEric Nelson #endif 875*d67b0d97SEric Nelson 876*d67b0d97SEric Nelson #ifdef CONFIG_CMD_BMODE 877*d67b0d97SEric Nelson static const struct boot_mode board_boot_modes[] = { 878*d67b0d97SEric Nelson /* 4 bit bus width */ 879*d67b0d97SEric Nelson {"mmc0", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)}, 880*d67b0d97SEric Nelson {"mmc1", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)}, 881*d67b0d97SEric Nelson {NULL, 0}, 882*d67b0d97SEric Nelson }; 883*d67b0d97SEric Nelson #endif 884*d67b0d97SEric Nelson 885*d67b0d97SEric Nelson int misc_init_r(void) 886*d67b0d97SEric Nelson { 887*d67b0d97SEric Nelson #ifdef CONFIG_PREBOOT 888*d67b0d97SEric Nelson preboot_keys(); 889*d67b0d97SEric Nelson #endif 890*d67b0d97SEric Nelson 891*d67b0d97SEric Nelson #ifdef CONFIG_CMD_BMODE 892*d67b0d97SEric Nelson add_board_boot_modes(board_boot_modes); 893*d67b0d97SEric Nelson #endif 894*d67b0d97SEric Nelson return 0; 895*d67b0d97SEric Nelson } 896