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