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