uboot/board/freescale/mx6sabresd/mx6sabresd.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2012 Freescale Semiconductor, Inc.
   4 *
   5 * Author: Fabio Estevam <fabio.estevam@freescale.com>
   6 */
   7
   8#include <image.h>
   9#include <init.h>
  10#include <net.h>
  11#include <asm/arch/clock.h>
  12#include <asm/arch/imx-regs.h>
  13#include <asm/arch/iomux.h>
  14#include <asm/arch/mx6-pins.h>
  15#include <asm/global_data.h>
  16#include <asm/mach-imx/spi.h>
  17#include <env.h>
  18#include <linux/errno.h>
  19#include <asm/gpio.h>
  20#include <asm/mach-imx/mxc_i2c.h>
  21#include <asm/mach-imx/iomux-v3.h>
  22#include <asm/mach-imx/boot_mode.h>
  23#include <asm/mach-imx/video.h>
  24#include <mmc.h>
  25#include <fsl_esdhc_imx.h>
  26#include <miiphy.h>
  27#include <asm/arch/mxc_hdmi.h>
  28#include <asm/arch/crm_regs.h>
  29#include <asm/io.h>
  30#include <asm/arch/sys_proto.h>
  31#include <i2c.h>
  32#include <input.h>
  33#include <power/pmic.h>
  34#include <power/pfuze100_pmic.h>
  35#include "../common/pfuze.h"
  36#include <usb.h>
  37#include <usb/ehci-ci.h>
  38
  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 SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \
  50                      PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
  51
  52#define I2C_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                    \
  53        PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS |   \
  54        PAD_CTL_ODE | PAD_CTL_SRE_FAST)
  55
  56#define I2C_PMIC        1
  57
  58#define I2C_PAD MUX_PAD_CTRL(I2C_PAD_CTRL)
  59
  60#define DISP0_PWR_EN    IMX_GPIO_NR(1, 21)
  61
  62#define KEY_VOL_UP      IMX_GPIO_NR(1, 4)
  63
  64int dram_init(void)
  65{
  66        gd->ram_size = imx_ddr_size();
  67        return 0;
  68}
  69
  70static iomux_v3_cfg_t const uart1_pads[] = {
  71        IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
  72        IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
  73};
  74
  75static iomux_v3_cfg_t const usdhc2_pads[] = {
  76        IOMUX_PADS(PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  77        IOMUX_PADS(PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  78        IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  79        IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  80        IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  81        IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  82        IOMUX_PADS(PAD_NANDF_D4__SD2_DATA4      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  83        IOMUX_PADS(PAD_NANDF_D5__SD2_DATA5      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  84        IOMUX_PADS(PAD_NANDF_D6__SD2_DATA6      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  85        IOMUX_PADS(PAD_NANDF_D7__SD2_DATA7      | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  86        IOMUX_PADS(PAD_NANDF_D2__GPIO2_IO02     | MUX_PAD_CTRL(NO_PAD_CTRL)), /* CD */
  87};
  88
  89static iomux_v3_cfg_t const usdhc3_pads[] = {
  90        IOMUX_PADS(PAD_SD3_CLK__SD3_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  91        IOMUX_PADS(PAD_SD3_CMD__SD3_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  92        IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  93        IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  94        IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  95        IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  96        IOMUX_PADS(PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  97        IOMUX_PADS(PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  98        IOMUX_PADS(PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  99        IOMUX_PADS(PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
 100        IOMUX_PADS(PAD_NANDF_D0__GPIO2_IO00    | MUX_PAD_CTRL(NO_PAD_CTRL)), /* CD */
 101};
 102
 103static iomux_v3_cfg_t const usdhc4_pads[] = {
 104        IOMUX_PADS(PAD_SD4_CLK__SD4_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
 105        IOMUX_PADS(PAD_SD4_CMD__SD4_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
 106        IOMUX_PADS(PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
 107        IOMUX_PADS(PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
 108        IOMUX_PADS(PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
 109        IOMUX_PADS(PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
 110        IOMUX_PADS(PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
 111        IOMUX_PADS(PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
 112        IOMUX_PADS(PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
 113        IOMUX_PADS(PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
 114};
 115
 116static iomux_v3_cfg_t const ecspi1_pads[] = {
 117        IOMUX_PADS(PAD_KEY_COL0__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL)),
 118        IOMUX_PADS(PAD_KEY_COL1__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL)),
 119        IOMUX_PADS(PAD_KEY_ROW0__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL)),
 120        IOMUX_PADS(PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 121};
 122
 123static iomux_v3_cfg_t const rgb_pads[] = {
 124        IOMUX_PADS(PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK | MUX_PAD_CTRL(NO_PAD_CTRL)),
 125        IOMUX_PADS(PAD_DI0_PIN15__IPU1_DI0_PIN15 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 126        IOMUX_PADS(PAD_DI0_PIN2__IPU1_DI0_PIN02 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 127        IOMUX_PADS(PAD_DI0_PIN3__IPU1_DI0_PIN03 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 128        IOMUX_PADS(PAD_DI0_PIN4__IPU1_DI0_PIN04 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 129        IOMUX_PADS(PAD_DISP0_DAT0__IPU1_DISP0_DATA00 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 130        IOMUX_PADS(PAD_DISP0_DAT1__IPU1_DISP0_DATA01 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 131        IOMUX_PADS(PAD_DISP0_DAT2__IPU1_DISP0_DATA02 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 132        IOMUX_PADS(PAD_DISP0_DAT3__IPU1_DISP0_DATA03 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 133        IOMUX_PADS(PAD_DISP0_DAT4__IPU1_DISP0_DATA04 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 134        IOMUX_PADS(PAD_DISP0_DAT5__IPU1_DISP0_DATA05 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 135        IOMUX_PADS(PAD_DISP0_DAT6__IPU1_DISP0_DATA06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 136        IOMUX_PADS(PAD_DISP0_DAT7__IPU1_DISP0_DATA07 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 137        IOMUX_PADS(PAD_DISP0_DAT8__IPU1_DISP0_DATA08 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 138        IOMUX_PADS(PAD_DISP0_DAT9__IPU1_DISP0_DATA09 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 139        IOMUX_PADS(PAD_DISP0_DAT10__IPU1_DISP0_DATA10 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 140        IOMUX_PADS(PAD_DISP0_DAT11__IPU1_DISP0_DATA11 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 141        IOMUX_PADS(PAD_DISP0_DAT12__IPU1_DISP0_DATA12 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 142        IOMUX_PADS(PAD_DISP0_DAT13__IPU1_DISP0_DATA13 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 143        IOMUX_PADS(PAD_DISP0_DAT14__IPU1_DISP0_DATA14 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 144        IOMUX_PADS(PAD_DISP0_DAT15__IPU1_DISP0_DATA15 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 145        IOMUX_PADS(PAD_DISP0_DAT16__IPU1_DISP0_DATA16 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 146        IOMUX_PADS(PAD_DISP0_DAT17__IPU1_DISP0_DATA17 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 147        IOMUX_PADS(PAD_DISP0_DAT18__IPU1_DISP0_DATA18 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 148        IOMUX_PADS(PAD_DISP0_DAT19__IPU1_DISP0_DATA19 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 149        IOMUX_PADS(PAD_DISP0_DAT20__IPU1_DISP0_DATA20 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 150        IOMUX_PADS(PAD_DISP0_DAT21__IPU1_DISP0_DATA21 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 151        IOMUX_PADS(PAD_DISP0_DAT22__IPU1_DISP0_DATA22 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 152        IOMUX_PADS(PAD_DISP0_DAT23__IPU1_DISP0_DATA23 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 153};
 154
 155static iomux_v3_cfg_t const bl_pads[] = {
 156        IOMUX_PADS(PAD_SD1_DAT3__GPIO1_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL)),
 157};
 158
 159static void enable_backlight(void)
 160{
 161        SETUP_IOMUX_PADS(bl_pads);
 162        gpio_request(DISP0_PWR_EN, "Display Power Enable");
 163        gpio_direction_output(DISP0_PWR_EN, 1);
 164}
 165
 166static void enable_rgb(struct display_info_t const *dev)
 167{
 168        SETUP_IOMUX_PADS(rgb_pads);
 169        enable_backlight();
 170}
 171
 172static void enable_lvds(struct display_info_t const *dev)
 173{
 174        enable_backlight();
 175}
 176
 177static struct i2c_pads_info mx6q_i2c_pad_info1 = {
 178        .scl = {
 179                .i2c_mode = MX6Q_PAD_KEY_COL3__I2C2_SCL | I2C_PAD,
 180                .gpio_mode = MX6Q_PAD_KEY_COL3__GPIO4_IO12 | I2C_PAD,
 181                .gp = IMX_GPIO_NR(4, 12)
 182        },
 183        .sda = {
 184                .i2c_mode = MX6Q_PAD_KEY_ROW3__I2C2_SDA | I2C_PAD,
 185                .gpio_mode = MX6Q_PAD_KEY_ROW3__GPIO4_IO13 | I2C_PAD,
 186                .gp = IMX_GPIO_NR(4, 13)
 187        }
 188};
 189
 190static struct i2c_pads_info mx6dl_i2c_pad_info1 = {
 191        .scl = {
 192                .i2c_mode = MX6DL_PAD_KEY_COL3__I2C2_SCL | I2C_PAD,
 193                .gpio_mode = MX6DL_PAD_KEY_COL3__GPIO4_IO12 | I2C_PAD,
 194                .gp = IMX_GPIO_NR(4, 12)
 195        },
 196        .sda = {
 197                .i2c_mode = MX6DL_PAD_KEY_ROW3__I2C2_SDA | I2C_PAD,
 198                .gpio_mode = MX6DL_PAD_KEY_ROW3__GPIO4_IO13 | I2C_PAD,
 199                .gp = IMX_GPIO_NR(4, 13)
 200        }
 201};
 202
 203static void setup_spi(void)
 204{
 205        SETUP_IOMUX_PADS(ecspi1_pads);
 206}
 207
 208iomux_v3_cfg_t const di0_pads[] = {
 209        IOMUX_PADS(PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK),        /* DISP0_CLK */
 210        IOMUX_PADS(PAD_DI0_PIN2__IPU1_DI0_PIN02),               /* DISP0_HSYNC */
 211        IOMUX_PADS(PAD_DI0_PIN3__IPU1_DI0_PIN03),               /* DISP0_VSYNC */
 212};
 213
 214static void setup_iomux_uart(void)
 215{
 216        SETUP_IOMUX_PADS(uart1_pads);
 217}
 218
 219#ifdef CONFIG_FSL_ESDHC_IMX
 220struct fsl_esdhc_cfg usdhc_cfg[3] = {
 221        {USDHC2_BASE_ADDR},
 222        {USDHC3_BASE_ADDR},
 223        {USDHC4_BASE_ADDR},
 224};
 225
 226#define USDHC2_CD_GPIO  IMX_GPIO_NR(2, 2)
 227#define USDHC3_CD_GPIO  IMX_GPIO_NR(2, 0)
 228
 229int board_mmc_get_env_dev(int devno)
 230{
 231        return devno - 1;
 232}
 233
 234int board_mmc_getcd(struct mmc *mmc)
 235{
 236        struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
 237        int ret = 0;
 238
 239        switch (cfg->esdhc_base) {
 240        case USDHC2_BASE_ADDR:
 241                ret = !gpio_get_value(USDHC2_CD_GPIO);
 242                break;
 243        case USDHC3_BASE_ADDR:
 244                ret = !gpio_get_value(USDHC3_CD_GPIO);
 245                break;
 246        case USDHC4_BASE_ADDR:
 247                ret = 1; /* eMMC/uSDHC4 is always present */
 248                break;
 249        }
 250
 251        return ret;
 252}
 253
 254int board_mmc_init(struct bd_info *bis)
 255{
 256        struct src *psrc = (struct src *)SRC_BASE_ADDR;
 257        unsigned reg = readl(&psrc->sbmr1) >> 11;
 258        /*
 259         * Upon reading BOOT_CFG register the following map is done:
 260         * Bit 11 and 12 of BOOT_CFG register can determine the current
 261         * mmc port
 262         * 0x1                  SD1
 263         * 0x2                  SD2
 264         * 0x3                  SD4
 265         */
 266
 267        switch (reg & 0x3) {
 268        case 0x1:
 269                SETUP_IOMUX_PADS(usdhc2_pads);
 270                usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
 271                usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
 272                gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
 273                break;
 274        case 0x2:
 275                SETUP_IOMUX_PADS(usdhc3_pads);
 276                usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
 277                usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
 278                gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
 279                break;
 280        case 0x3:
 281                SETUP_IOMUX_PADS(usdhc4_pads);
 282                usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR;
 283                usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
 284                gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
 285                break;
 286        }
 287
 288        return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
 289}
 290#endif
 291
 292static int ar8031_phy_fixup(struct phy_device *phydev)
 293{
 294        unsigned short val;
 295
 296        /* To enable AR8031 ouput a 125MHz clk from CLK_25M */
 297        phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
 298        phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
 299        phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
 300
 301        val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
 302        val &= 0xffe3;
 303        val |= 0x18;
 304        phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
 305
 306        /* introduce tx clock delay */
 307        phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
 308        val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
 309        val |= 0x0100;
 310        phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
 311
 312        return 0;
 313}
 314
 315int board_phy_config(struct phy_device *phydev)
 316{
 317        ar8031_phy_fixup(phydev);
 318
 319        if (phydev->drv->config)
 320                phydev->drv->config(phydev);
 321
 322        return 0;
 323}
 324
 325#if defined(CONFIG_VIDEO_IPUV3)
 326static void disable_lvds(struct display_info_t const *dev)
 327{
 328        struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
 329
 330        int reg = readl(&iomux->gpr[2]);
 331
 332        reg &= ~(IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
 333                 IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
 334
 335        writel(reg, &iomux->gpr[2]);
 336}
 337
 338static void do_enable_hdmi(struct display_info_t const *dev)
 339{
 340        disable_lvds(dev);
 341        imx_enable_hdmi_phy();
 342}
 343
 344struct display_info_t const displays[] = {{
 345        .bus    = -1,
 346        .addr   = 0,
 347        .pixfmt = IPU_PIX_FMT_RGB666,
 348        .detect = NULL,
 349        .enable = enable_lvds,
 350        .mode   = {
 351                .name           = "Hannstar-XGA",
 352                .refresh        = 60,
 353                .xres           = 1024,
 354                .yres           = 768,
 355                .pixclock       = 15384,
 356                .left_margin    = 160,
 357                .right_margin   = 24,
 358                .upper_margin   = 29,
 359                .lower_margin   = 3,
 360                .hsync_len      = 136,
 361                .vsync_len      = 6,
 362                .sync           = FB_SYNC_EXT,
 363                .vmode          = FB_VMODE_NONINTERLACED
 364} }, {
 365        .bus    = -1,
 366        .addr   = 0,
 367        .pixfmt = IPU_PIX_FMT_RGB24,
 368        .detect = detect_hdmi,
 369        .enable = do_enable_hdmi,
 370        .mode   = {
 371                .name           = "HDMI",
 372                .refresh        = 60,
 373                .xres           = 1024,
 374                .yres           = 768,
 375                .pixclock       = 15384,
 376                .left_margin    = 160,
 377                .right_margin   = 24,
 378                .upper_margin   = 29,
 379                .lower_margin   = 3,
 380                .hsync_len      = 136,
 381                .vsync_len      = 6,
 382                .sync           = FB_SYNC_EXT,
 383                .vmode          = FB_VMODE_NONINTERLACED
 384} }, {
 385        .bus    = 0,
 386        .addr   = 0,
 387        .pixfmt = IPU_PIX_FMT_RGB24,
 388        .detect = NULL,
 389        .enable = enable_rgb,
 390        .mode   = {
 391                .name           = "SEIKO-WVGA",
 392                .refresh        = 60,
 393                .xres           = 800,
 394                .yres           = 480,
 395                .pixclock       = 29850,
 396                .left_margin    = 89,
 397                .right_margin   = 164,
 398                .upper_margin   = 23,
 399                .lower_margin   = 10,
 400                .hsync_len      = 10,
 401                .vsync_len      = 10,
 402                .sync           = 0,
 403                .vmode          = FB_VMODE_NONINTERLACED
 404} } };
 405size_t display_count = ARRAY_SIZE(displays);
 406
 407static void setup_display(void)
 408{
 409        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 410        struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
 411        int reg;
 412
 413        /* Setup HSYNC, VSYNC, DISP_CLK for debugging purposes */
 414        SETUP_IOMUX_PADS(di0_pads);
 415
 416        enable_ipu_clock();
 417        imx_setup_hdmi();
 418
 419        /* Turn on LDB0, LDB1, IPU,IPU DI0 clocks */
 420        reg = readl(&mxc_ccm->CCGR3);
 421        reg |=  MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
 422        writel(reg, &mxc_ccm->CCGR3);
 423
 424        /* set LDB0, LDB1 clk select to 011/011 */
 425        reg = readl(&mxc_ccm->cs2cdr);
 426        reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
 427                 | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
 428        reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
 429              | (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
 430        writel(reg, &mxc_ccm->cs2cdr);
 431
 432        reg = readl(&mxc_ccm->cscmr2);
 433        reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
 434        writel(reg, &mxc_ccm->cscmr2);
 435
 436        reg = readl(&mxc_ccm->chsccdr);
 437        reg |= (CHSCCDR_CLK_SEL_LDB_DI0
 438                << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
 439        reg |= (CHSCCDR_CLK_SEL_LDB_DI0
 440                << MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
 441        writel(reg, &mxc_ccm->chsccdr);
 442
 443        reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
 444             | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW
 445             | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
 446             | IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
 447             | IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
 448             | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
 449             | IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
 450             | IOMUXC_GPR2_LVDS_CH0_MODE_DISABLED
 451             | IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0;
 452        writel(reg, &iomux->gpr[2]);
 453
 454        reg = readl(&iomux->gpr[3]);
 455        reg = (reg & ~(IOMUXC_GPR3_LVDS1_MUX_CTL_MASK
 456                        | IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
 457            | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
 458               << IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET);
 459        writel(reg, &iomux->gpr[3]);
 460}
 461#endif /* CONFIG_VIDEO_IPUV3 */
 462
 463/*
 464 * Do not overwrite the console
 465 * Use always serial for U-Boot console
 466 */
 467int overwrite_console(void)
 468{
 469        return 1;
 470}
 471
 472#ifdef CONFIG_USB_EHCI_MX6
 473static void setup_usb(void)
 474{
 475        /*
 476         * set daisy chain for otg_pin_id on 6q.
 477         * for 6dl, this bit is reserved
 478         */
 479        imx_iomux_set_gpr_register(1, 13, 1, 0);
 480}
 481#endif
 482
 483int board_early_init_f(void)
 484{
 485        setup_iomux_uart();
 486
 487        return 0;
 488}
 489
 490int board_init(void)
 491{
 492        /* address of boot parameters */
 493        gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
 494
 495#ifdef CONFIG_MXC_SPI
 496        setup_spi();
 497#endif
 498        if (is_mx6dq() || is_mx6dqp())
 499                setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info1);
 500        else
 501                setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info1);
 502#if defined(CONFIG_VIDEO_IPUV3)
 503        setup_display();
 504#endif
 505#ifdef CONFIG_USB_EHCI_MX6
 506        setup_usb();
 507#endif
 508
 509        return 0;
 510}
 511
 512int power_init_board(void)
 513{
 514        struct pmic *p;
 515        unsigned int reg;
 516        int ret;
 517
 518        p = pfuze_common_init(I2C_PMIC);
 519        if (!p)
 520                return -ENODEV;
 521
 522        ret = pfuze_mode_init(p, APS_PFM);
 523        if (ret < 0)
 524                return ret;
 525
 526        /* Increase VGEN3 from 2.5 to 2.8V */
 527        pmic_reg_read(p, PFUZE100_VGEN3VOL, &reg);
 528        reg &= ~LDO_VOL_MASK;
 529        reg |= LDOB_2_80V;
 530        pmic_reg_write(p, PFUZE100_VGEN3VOL, reg);
 531
 532        /* Increase VGEN5 from 2.8 to 3V */
 533        pmic_reg_read(p, PFUZE100_VGEN5VOL, &reg);
 534        reg &= ~LDO_VOL_MASK;
 535        reg |= LDOB_3_00V;
 536        pmic_reg_write(p, PFUZE100_VGEN5VOL, reg);
 537
 538        return 0;
 539}
 540
 541#ifdef CONFIG_MXC_SPI
 542int board_spi_cs_gpio(unsigned bus, unsigned cs)
 543{
 544        return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 9)) : -1;
 545}
 546#endif
 547
 548#ifdef CONFIG_CMD_BMODE
 549static const struct boot_mode board_boot_modes[] = {
 550        /* 4 bit bus width */
 551        {"sd2",  MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
 552        {"sd3",  MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
 553        /* 8 bit bus width */
 554        {"emmc", MAKE_CFGVAL(0x60, 0x58, 0x00, 0x00)},
 555        {NULL,   0},
 556};
 557#endif
 558
 559int board_late_init(void)
 560{
 561#ifdef CONFIG_CMD_BMODE
 562        add_board_boot_modes(board_boot_modes);
 563#endif
 564
 565#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 566        env_set("board_name", "SABRESD");
 567
 568        if (is_mx6dqp())
 569                env_set("board_rev", "MX6QP");
 570        else if (is_mx6dq())
 571                env_set("board_rev", "MX6Q");
 572        else if (is_mx6sdl())
 573                env_set("board_rev", "MX6DL");
 574#endif
 575
 576        return 0;
 577}
 578
 579#ifdef CONFIG_SPL_BUILD
 580#include <asm/arch/mx6-ddr.h>
 581#include <spl.h>
 582#include <linux/libfdt.h>
 583
 584#ifdef CONFIG_SPL_OS_BOOT
 585int spl_start_uboot(void)
 586{
 587        gpio_request(KEY_VOL_UP, "KEY Volume UP");
 588        gpio_direction_input(KEY_VOL_UP);
 589
 590        /* Only enter in Falcon mode if KEY_VOL_UP is pressed */
 591        return gpio_get_value(KEY_VOL_UP);
 592}
 593#endif
 594
 595static void ccgr_init(void)
 596{
 597        struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 598
 599        writel(0x00C03F3F, &ccm->CCGR0);
 600        writel(0x0030FC03, &ccm->CCGR1);
 601        writel(0x0FFFC000, &ccm->CCGR2);
 602        writel(0x3FF00000, &ccm->CCGR3);
 603        writel(0x00FFF300, &ccm->CCGR4);
 604        writel(0x0F0000C3, &ccm->CCGR5);
 605        writel(0x000003FF, &ccm->CCGR6);
 606}
 607
 608static int mx6q_dcd_table[] = {
 609        0x020e0798, 0x000C0000,
 610        0x020e0758, 0x00000000,
 611        0x020e0588, 0x00000030,
 612        0x020e0594, 0x00000030,
 613        0x020e056c, 0x00000030,
 614        0x020e0578, 0x00000030,
 615        0x020e074c, 0x00000030,
 616        0x020e057c, 0x00000030,
 617        0x020e058c, 0x00000000,
 618        0x020e059c, 0x00000030,
 619        0x020e05a0, 0x00000030,
 620        0x020e078c, 0x00000030,
 621        0x020e0750, 0x00020000,
 622        0x020e05a8, 0x00000030,
 623        0x020e05b0, 0x00000030,
 624        0x020e0524, 0x00000030,
 625        0x020e051c, 0x00000030,
 626        0x020e0518, 0x00000030,
 627        0x020e050c, 0x00000030,
 628        0x020e05b8, 0x00000030,
 629        0x020e05c0, 0x00000030,
 630        0x020e0774, 0x00020000,
 631        0x020e0784, 0x00000030,
 632        0x020e0788, 0x00000030,
 633        0x020e0794, 0x00000030,
 634        0x020e079c, 0x00000030,
 635        0x020e07a0, 0x00000030,
 636        0x020e07a4, 0x00000030,
 637        0x020e07a8, 0x00000030,
 638        0x020e0748, 0x00000030,
 639        0x020e05ac, 0x00000030,
 640        0x020e05b4, 0x00000030,
 641        0x020e0528, 0x00000030,
 642        0x020e0520, 0x00000030,
 643        0x020e0514, 0x00000030,
 644        0x020e0510, 0x00000030,
 645        0x020e05bc, 0x00000030,
 646        0x020e05c4, 0x00000030,
 647        0x021b0800, 0xa1390003,
 648        0x021b080c, 0x001F001F,
 649        0x021b0810, 0x001F001F,
 650        0x021b480c, 0x001F001F,
 651        0x021b4810, 0x001F001F,
 652        0x021b083c, 0x43270338,
 653        0x021b0840, 0x03200314,
 654        0x021b483c, 0x431A032F,
 655        0x021b4840, 0x03200263,
 656        0x021b0848, 0x4B434748,
 657        0x021b4848, 0x4445404C,
 658        0x021b0850, 0x38444542,
 659        0x021b4850, 0x4935493A,
 660        0x021b081c, 0x33333333,
 661        0x021b0820, 0x33333333,
 662        0x021b0824, 0x33333333,
 663        0x021b0828, 0x33333333,
 664        0x021b481c, 0x33333333,
 665        0x021b4820, 0x33333333,
 666        0x021b4824, 0x33333333,
 667        0x021b4828, 0x33333333,
 668        0x021b08b8, 0x00000800,
 669        0x021b48b8, 0x00000800,
 670        0x021b0004, 0x00020036,
 671        0x021b0008, 0x09444040,
 672        0x021b000c, 0x555A7975,
 673        0x021b0010, 0xFF538F64,
 674        0x021b0014, 0x01FF00DB,
 675        0x021b0018, 0x00001740,
 676        0x021b001c, 0x00008000,
 677        0x021b002c, 0x000026d2,
 678        0x021b0030, 0x005A1023,
 679        0x021b0040, 0x00000027,
 680        0x021b0000, 0x831A0000,
 681        0x021b001c, 0x04088032,
 682        0x021b001c, 0x00008033,
 683        0x021b001c, 0x00048031,
 684        0x021b001c, 0x09408030,
 685        0x021b001c, 0x04008040,
 686        0x021b0020, 0x00005800,
 687        0x021b0818, 0x00011117,
 688        0x021b4818, 0x00011117,
 689        0x021b0004, 0x00025576,
 690        0x021b0404, 0x00011006,
 691        0x021b001c, 0x00000000,
 692};
 693
 694static int mx6qp_dcd_table[] = {
 695        0x020e0798, 0x000c0000,
 696        0x020e0758, 0x00000000,
 697        0x020e0588, 0x00000030,
 698        0x020e0594, 0x00000030,
 699        0x020e056c, 0x00000030,
 700        0x020e0578, 0x00000030,
 701        0x020e074c, 0x00000030,
 702        0x020e057c, 0x00000030,
 703        0x020e058c, 0x00000000,
 704        0x020e059c, 0x00000030,
 705        0x020e05a0, 0x00000030,
 706        0x020e078c, 0x00000030,
 707        0x020e0750, 0x00020000,
 708        0x020e05a8, 0x00000030,
 709        0x020e05b0, 0x00000030,
 710        0x020e0524, 0x00000030,
 711        0x020e051c, 0x00000030,
 712        0x020e0518, 0x00000030,
 713        0x020e050c, 0x00000030,
 714        0x020e05b8, 0x00000030,
 715        0x020e05c0, 0x00000030,
 716        0x020e0774, 0x00020000,
 717        0x020e0784, 0x00000030,
 718        0x020e0788, 0x00000030,
 719        0x020e0794, 0x00000030,
 720        0x020e079c, 0x00000030,
 721        0x020e07a0, 0x00000030,
 722        0x020e07a4, 0x00000030,
 723        0x020e07a8, 0x00000030,
 724        0x020e0748, 0x00000030,
 725        0x020e05ac, 0x00000030,
 726        0x020e05b4, 0x00000030,
 727        0x020e0528, 0x00000030,
 728        0x020e0520, 0x00000030,
 729        0x020e0514, 0x00000030,
 730        0x020e0510, 0x00000030,
 731        0x020e05bc, 0x00000030,
 732        0x020e05c4, 0x00000030,
 733        0x021b0800, 0xa1390003,
 734        0x021b080c, 0x001b001e,
 735        0x021b0810, 0x002e0029,
 736        0x021b480c, 0x001b002a,
 737        0x021b4810, 0x0019002c,
 738        0x021b083c, 0x43240334,
 739        0x021b0840, 0x0324031a,
 740        0x021b483c, 0x43340344,
 741        0x021b4840, 0x03280276,
 742        0x021b0848, 0x44383A3E,
 743        0x021b4848, 0x3C3C3846,
 744        0x021b0850, 0x2e303230,
 745        0x021b4850, 0x38283E34,
 746        0x021b081c, 0x33333333,
 747        0x021b0820, 0x33333333,
 748        0x021b0824, 0x33333333,
 749        0x021b0828, 0x33333333,
 750        0x021b481c, 0x33333333,
 751        0x021b4820, 0x33333333,
 752        0x021b4824, 0x33333333,
 753        0x021b4828, 0x33333333,
 754        0x021b08c0, 0x24912249,
 755        0x021b48c0, 0x24914289,
 756        0x021b08b8, 0x00000800,
 757        0x021b48b8, 0x00000800,
 758        0x021b0004, 0x00020036,
 759        0x021b0008, 0x24444040,
 760        0x021b000c, 0x555A7955,
 761        0x021b0010, 0xFF320F64,
 762        0x021b0014, 0x01ff00db,
 763        0x021b0018, 0x00001740,
 764        0x021b001c, 0x00008000,
 765        0x021b002c, 0x000026d2,
 766        0x021b0030, 0x005A1023,
 767        0x021b0040, 0x00000027,
 768        0x021b0400, 0x14420000,
 769        0x021b0000, 0x831A0000,
 770        0x021b0890, 0x00400C58,
 771        0x00bb0008, 0x00000000,
 772        0x00bb000c, 0x2891E41A,
 773        0x00bb0038, 0x00000564,
 774        0x00bb0014, 0x00000040,
 775        0x00bb0028, 0x00000020,
 776        0x00bb002c, 0x00000020,
 777        0x021b001c, 0x04088032,
 778        0x021b001c, 0x00008033,
 779        0x021b001c, 0x00048031,
 780        0x021b001c, 0x09408030,
 781        0x021b001c, 0x04008040,
 782        0x021b0020, 0x00005800,
 783        0x021b0818, 0x00011117,
 784        0x021b4818, 0x00011117,
 785        0x021b0004, 0x00025576,
 786        0x021b0404, 0x00011006,
 787        0x021b001c, 0x00000000,
 788};
 789
 790static int mx6dl_dcd_table[] = {
 791        0x020e0774, 0x000C0000,
 792        0x020e0754, 0x00000000,
 793        0x020e04ac, 0x00000030,
 794        0x020e04b0, 0x00000030,
 795        0x020e0464, 0x00000030,
 796        0x020e0490, 0x00000030,
 797        0x020e074c, 0x00000030,
 798        0x020e0494, 0x00000030,
 799        0x020e04a0, 0x00000000,
 800        0x020e04b4, 0x00000030,
 801        0x020e04b8, 0x00000030,
 802        0x020e076c, 0x00000030,
 803        0x020e0750, 0x00020000,
 804        0x020e04bc, 0x00000030,
 805        0x020e04c0, 0x00000030,
 806        0x020e04c4, 0x00000030,
 807        0x020e04c8, 0x00000030,
 808        0x020e04cc, 0x00000030,
 809        0x020e04d0, 0x00000030,
 810        0x020e04d4, 0x00000030,
 811        0x020e04d8, 0x00000030,
 812        0x020e0760, 0x00020000,
 813        0x020e0764, 0x00000030,
 814        0x020e0770, 0x00000030,
 815        0x020e0778, 0x00000030,
 816        0x020e077c, 0x00000030,
 817        0x020e0780, 0x00000030,
 818        0x020e0784, 0x00000030,
 819        0x020e078c, 0x00000030,
 820        0x020e0748, 0x00000030,
 821        0x020e0470, 0x00000030,
 822        0x020e0474, 0x00000030,
 823        0x020e0478, 0x00000030,
 824        0x020e047c, 0x00000030,
 825        0x020e0480, 0x00000030,
 826        0x020e0484, 0x00000030,
 827        0x020e0488, 0x00000030,
 828        0x020e048c, 0x00000030,
 829        0x021b0800, 0xa1390003,
 830        0x021b080c, 0x001F001F,
 831        0x021b0810, 0x001F001F,
 832        0x021b480c, 0x001F001F,
 833        0x021b4810, 0x001F001F,
 834        0x021b083c, 0x4220021F,
 835        0x021b0840, 0x0207017E,
 836        0x021b483c, 0x4201020C,
 837        0x021b4840, 0x01660172,
 838        0x021b0848, 0x4A4D4E4D,
 839        0x021b4848, 0x4A4F5049,
 840        0x021b0850, 0x3F3C3D31,
 841        0x021b4850, 0x3238372B,
 842        0x021b081c, 0x33333333,
 843        0x021b0820, 0x33333333,
 844        0x021b0824, 0x33333333,
 845        0x021b0828, 0x33333333,
 846        0x021b481c, 0x33333333,
 847        0x021b4820, 0x33333333,
 848        0x021b4824, 0x33333333,
 849        0x021b4828, 0x33333333,
 850        0x021b08b8, 0x00000800,
 851        0x021b48b8, 0x00000800,
 852        0x021b0004, 0x0002002D,
 853        0x021b0008, 0x00333030,
 854        0x021b000c, 0x3F435313,
 855        0x021b0010, 0xB66E8B63,
 856        0x021b0014, 0x01FF00DB,
 857        0x021b0018, 0x00001740,
 858        0x021b001c, 0x00008000,
 859        0x021b002c, 0x000026d2,
 860        0x021b0030, 0x00431023,
 861        0x021b0040, 0x00000027,
 862        0x021b0000, 0x831A0000,
 863        0x021b001c, 0x04008032,
 864        0x021b001c, 0x00008033,
 865        0x021b001c, 0x00048031,
 866        0x021b001c, 0x05208030,
 867        0x021b001c, 0x04008040,
 868        0x021b0020, 0x00005800,
 869        0x021b0818, 0x00011117,
 870        0x021b4818, 0x00011117,
 871        0x021b0004, 0x0002556D,
 872        0x021b0404, 0x00011006,
 873        0x021b001c, 0x00000000,
 874};
 875
 876static void ddr_init(int *table, int size)
 877{
 878        int i;
 879
 880        for (i = 0; i < size / 2 ; i++)
 881                writel(table[2 * i + 1], table[2 * i]);
 882}
 883
 884static void spl_dram_init(void)
 885{
 886        if (is_mx6dq())
 887                ddr_init(mx6q_dcd_table, ARRAY_SIZE(mx6q_dcd_table));
 888        else if (is_mx6dqp())
 889                ddr_init(mx6qp_dcd_table, ARRAY_SIZE(mx6qp_dcd_table));
 890        else if (is_mx6sdl())
 891                ddr_init(mx6dl_dcd_table, ARRAY_SIZE(mx6dl_dcd_table));
 892}
 893
 894void board_init_f(ulong dummy)
 895{
 896        /* DDR initialization */
 897        spl_dram_init();
 898
 899        /* setup AIPS and disable watchdog */
 900        arch_cpu_init();
 901
 902        ccgr_init();
 903        gpr_init();
 904
 905        /* iomux and setup of i2c */
 906        board_early_init_f();
 907
 908        /* setup GP timer */
 909        timer_init();
 910
 911        /* UART clocks enabled and gd valid - init serial console */
 912        preloader_console_init();
 913
 914        /* Clear the BSS. */
 915        memset(__bss_start, 0, __bss_end - __bss_start);
 916
 917        /* load/boot image from boot device */
 918        board_init_r(NULL, 0);
 919}
 920#endif
 921
 922#ifdef CONFIG_SPL_LOAD_FIT
 923int board_fit_config_name_match(const char *name)
 924{
 925        if (is_mx6dq()) {
 926                if (!strcmp(name, "imx6q-sabresd"))
 927                        return 0;
 928        } else if (is_mx6dqp()) {
 929                if (!strcmp(name, "imx6qp-sabresd"))
 930                        return 0;
 931        } else if (is_mx6dl()) {
 932                if (!strcmp(name, "imx6dl-sabresd"))
 933                        return 0;
 934        }
 935
 936        return -1;
 937}
 938#endif
 939