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