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