uboot/board/freescale/mx6sxsabreauto/mx6sxsabreauto.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2014 Freescale Semiconductor, Inc.
   3 *
   4 * Author: Ye Li <ye.li@nxp.com>
   5 *
   6 * SPDX-License-Identifier:     GPL-2.0+
   7 */
   8
   9#include <asm/arch/clock.h>
  10#include <asm/arch/crm_regs.h>
  11#include <asm/arch/iomux.h>
  12#include <asm/arch/imx-regs.h>
  13#include <asm/arch/mx6-pins.h>
  14#include <asm/arch/sys_proto.h>
  15#include <asm/gpio.h>
  16#include <asm/imx-common/iomux-v3.h>
  17#include <asm/imx-common/boot_mode.h>
  18#include <asm/io.h>
  19#include <asm/imx-common/mxc_i2c.h>
  20#include <linux/sizes.h>
  21#include <common.h>
  22#include <fsl_esdhc.h>
  23#include <mmc.h>
  24#include <i2c.h>
  25#include <miiphy.h>
  26#include <netdev.h>
  27#include <power/pmic.h>
  28#include <power/pfuze100_pmic.h>
  29#include "../common/pfuze.h"
  30#include <usb.h>
  31#include <usb/ehci-ci.h>
  32#include <pca953x.h>
  33
  34DECLARE_GLOBAL_DATA_PTR;
  35
  36#define UART_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |             \
  37        PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |               \
  38        PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
  39
  40#define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |             \
  41        PAD_CTL_PUS_22K_UP  | PAD_CTL_SPEED_LOW |               \
  42        PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
  43
  44#define I2C_PAD_CTRL    (PAD_CTL_PKE | PAD_CTL_PUE |            \
  45        PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |               \
  46        PAD_CTL_DSE_40ohm | PAD_CTL_HYS |                       \
  47        PAD_CTL_ODE)
  48
  49#define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE |     \
  50        PAD_CTL_SPEED_HIGH   |                                   \
  51        PAD_CTL_DSE_48ohm   | PAD_CTL_SRE_FAST)
  52
  53#define ENET_CLK_PAD_CTRL  (PAD_CTL_SPEED_MED | \
  54        PAD_CTL_DSE_120ohm   | PAD_CTL_SRE_FAST)
  55
  56#define ENET_RX_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |          \
  57        PAD_CTL_SPEED_HIGH   | PAD_CTL_SRE_FAST)
  58
  59#define I2C_PMIC        1
  60
  61#define GPMI_PAD_CTRL0 (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
  62#define GPMI_PAD_CTRL1 (PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | \
  63                        PAD_CTL_SRE_FAST)
  64#define GPMI_PAD_CTRL2 (GPMI_PAD_CTRL0 | GPMI_PAD_CTRL1)
  65
  66/*Define for building port exp gpio, pin starts from 0*/
  67#define PORTEXP_IO_NR(chip, pin) \
  68        ((chip << 5) + pin)
  69
  70/*Get the chip addr from a ioexp gpio*/
  71#define PORTEXP_IO_TO_CHIP(gpio_nr) \
  72        (gpio_nr >> 5)
  73
  74/*Get the pin number from a ioexp gpio*/
  75#define PORTEXP_IO_TO_PIN(gpio_nr) \
  76        (gpio_nr & 0x1f)
  77
  78#define CPU_PER_RST_B   PORTEXP_IO_NR(0x30, 4)
  79#define STEER_ENET              PORTEXP_IO_NR(0x32, 2)
  80
  81static int port_exp_direction_output(unsigned gpio, int value)
  82{
  83        int ret;
  84
  85        i2c_set_bus_num(2);
  86        ret = i2c_probe(PORTEXP_IO_TO_CHIP(gpio));
  87        if (ret)
  88                return ret;
  89
  90        ret = pca953x_set_dir(PORTEXP_IO_TO_CHIP(gpio),
  91                (1 << PORTEXP_IO_TO_PIN(gpio)),
  92                (PCA953X_DIR_OUT << PORTEXP_IO_TO_PIN(gpio)));
  93
  94        if (ret)
  95                return ret;
  96
  97        ret = pca953x_set_val(PORTEXP_IO_TO_CHIP(gpio),
  98                (1 << PORTEXP_IO_TO_PIN(gpio)),
  99                (value << PORTEXP_IO_TO_PIN(gpio)));
 100
 101        if (ret)
 102                return ret;
 103
 104        return 0;
 105}
 106
 107int dram_init(void)
 108{
 109        gd->ram_size = PHYS_SDRAM_SIZE;
 110
 111        return 0;
 112}
 113
 114static iomux_v3_cfg_t const uart1_pads[] = {
 115        MX6_PAD_GPIO1_IO04__UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
 116        MX6_PAD_GPIO1_IO05__UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
 117};
 118
 119static iomux_v3_cfg_t const usdhc3_pads[] = {
 120        MX6_PAD_SD3_CLK__USDHC3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 121        MX6_PAD_SD3_CMD__USDHC3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 122        MX6_PAD_SD3_DATA0__USDHC3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 123        MX6_PAD_SD3_DATA1__USDHC3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 124        MX6_PAD_SD3_DATA2__USDHC3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 125        MX6_PAD_SD3_DATA3__USDHC3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 126        MX6_PAD_SD3_DATA4__USDHC3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 127        MX6_PAD_SD3_DATA5__USDHC3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 128        MX6_PAD_SD3_DATA6__USDHC3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 129        MX6_PAD_SD3_DATA7__USDHC3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 130
 131        /* CD pin */
 132        MX6_PAD_USB_H_DATA__GPIO7_IO_10 | MUX_PAD_CTRL(NO_PAD_CTRL),
 133
 134        /* RST_B, used for power reset cycle */
 135        MX6_PAD_KEY_COL1__GPIO2_IO_11 | MUX_PAD_CTRL(NO_PAD_CTRL),
 136};
 137
 138static iomux_v3_cfg_t const usdhc4_pads[] = {
 139        MX6_PAD_SD4_CLK__USDHC4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 140        MX6_PAD_SD4_CMD__USDHC4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 141        MX6_PAD_SD4_DATA0__USDHC4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 142        MX6_PAD_SD4_DATA1__USDHC4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 143        MX6_PAD_SD4_DATA2__USDHC4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 144        MX6_PAD_SD4_DATA3__USDHC4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 145        MX6_PAD_SD4_DATA4__USDHC4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 146        MX6_PAD_SD4_DATA5__USDHC4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 147        MX6_PAD_SD4_DATA6__USDHC4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 148        MX6_PAD_SD4_DATA7__USDHC4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 149
 150        /* CD pin */
 151        MX6_PAD_USB_H_STROBE__GPIO7_IO_11 | MUX_PAD_CTRL(NO_PAD_CTRL),
 152};
 153
 154static iomux_v3_cfg_t const fec2_pads[] = {
 155        MX6_PAD_ENET1_MDC__ENET2_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
 156        MX6_PAD_ENET1_MDIO__ENET2_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
 157        MX6_PAD_RGMII2_RX_CTL__ENET2_RX_EN | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
 158        MX6_PAD_RGMII2_RD0__ENET2_RX_DATA_0 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
 159        MX6_PAD_RGMII2_RD1__ENET2_RX_DATA_1 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
 160        MX6_PAD_RGMII2_RD2__ENET2_RX_DATA_2 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
 161        MX6_PAD_RGMII2_RD3__ENET2_RX_DATA_3 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
 162        MX6_PAD_RGMII2_RXC__ENET2_RX_CLK | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
 163        MX6_PAD_RGMII2_TX_CTL__ENET2_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
 164        MX6_PAD_RGMII2_TD0__ENET2_TX_DATA_0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
 165        MX6_PAD_RGMII2_TD1__ENET2_TX_DATA_1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
 166        MX6_PAD_RGMII2_TD2__ENET2_TX_DATA_2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
 167        MX6_PAD_RGMII2_TD3__ENET2_TX_DATA_3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
 168        MX6_PAD_RGMII2_TXC__ENET2_RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
 169};
 170
 171static void setup_iomux_uart(void)
 172{
 173        imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
 174}
 175
 176static int setup_fec(void)
 177{
 178        struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
 179
 180        /* Use 125MHz anatop loopback REF_CLK1 for ENET2 */
 181        clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC2_MASK, 0);
 182
 183        return enable_fec_anatop_clock(1, ENET_125MHZ);
 184}
 185
 186int board_eth_init(bd_t *bis)
 187{
 188        int ret;
 189
 190        imx_iomux_v3_setup_multiple_pads(fec2_pads, ARRAY_SIZE(fec2_pads));
 191        setup_fec();
 192
 193        ret = fecmxc_initialize_multi(bis, 1,
 194                CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
 195        if (ret)
 196                printf("FEC%d MXC: %s:failed\n", 1, __func__);
 197
 198        return ret;
 199}
 200
 201int board_phy_config(struct phy_device *phydev)
 202{
 203        /*
 204         * Enable 1.8V(SEL_1P5_1P8_POS_REG) on
 205         * Phy control debug reg 0
 206         */
 207        phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f);
 208        phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8);
 209
 210        /* rgmii tx clock delay enable */
 211        phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
 212        phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100);
 213
 214        if (phydev->drv->config)
 215                phydev->drv->config(phydev);
 216
 217        return 0;
 218}
 219
 220#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
 221/* I2C2 for PMIC */
 222struct i2c_pads_info i2c_pad_info2 = {
 223        .scl = {
 224                .i2c_mode = MX6_PAD_GPIO1_IO02__I2C2_SCL | PC,
 225                .gpio_mode = MX6_PAD_GPIO1_IO02__GPIO1_IO_2 | PC,
 226                .gp = IMX_GPIO_NR(1, 2),
 227        },
 228        .sda = {
 229                .i2c_mode = MX6_PAD_GPIO1_IO03__I2C2_SDA | PC,
 230                .gpio_mode = MX6_PAD_GPIO1_IO03__GPIO1_IO_3 | PC,
 231                .gp = IMX_GPIO_NR(1, 3),
 232        },
 233};
 234
 235/* I2C3 for IO Expander */
 236struct i2c_pads_info i2c_pad_info3 = {
 237        .scl = {
 238                .i2c_mode = MX6_PAD_KEY_COL4__I2C3_SCL | PC,
 239                .gpio_mode = MX6_PAD_KEY_COL4__GPIO2_IO_14 | PC,
 240                .gp = IMX_GPIO_NR(2, 14),
 241        },
 242        .sda = {
 243                .i2c_mode = MX6_PAD_KEY_ROW4__I2C3_SDA | PC,
 244                .gpio_mode = MX6_PAD_KEY_ROW4__GPIO2_IO_19 | PC,
 245                .gp = IMX_GPIO_NR(2, 19),
 246        },
 247};
 248
 249int power_init_board(void)
 250{
 251        struct pmic *p;
 252
 253        p = pfuze_common_init(I2C_PMIC);
 254        if (!p)
 255                return -ENODEV;
 256
 257        return 0;
 258}
 259
 260#ifdef CONFIG_USB_EHCI_MX6
 261#define USB_OTHERREGS_OFFSET    0x800
 262#define UCTRL_PWR_POL           (1 << 9)
 263
 264static iomux_v3_cfg_t const usb_otg_pads[] = {
 265        /* OGT1 */
 266        MX6_PAD_GPIO1_IO09__USB_OTG1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
 267        MX6_PAD_GPIO1_IO10__ANATOP_OTG1_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
 268        /* OTG2 */
 269        MX6_PAD_GPIO1_IO12__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL)
 270};
 271
 272static void setup_usb(void)
 273{
 274        imx_iomux_v3_setup_multiple_pads(usb_otg_pads,
 275                                         ARRAY_SIZE(usb_otg_pads));
 276}
 277
 278int board_usb_phy_mode(int port)
 279{
 280        if (port == 1)
 281                return USB_INIT_HOST;
 282        else
 283                return usb_phy_mode(port);
 284}
 285
 286int board_ehci_hcd_init(int port)
 287{
 288        u32 *usbnc_usb_ctrl;
 289
 290        if (port > 1)
 291                return -EINVAL;
 292
 293        usbnc_usb_ctrl = (u32 *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET +
 294                                 port * 4);
 295
 296        /* Set Power polarity */
 297        setbits_le32(usbnc_usb_ctrl, UCTRL_PWR_POL);
 298
 299        return 0;
 300}
 301#endif
 302
 303int board_early_init_f(void)
 304{
 305        setup_iomux_uart();
 306
 307        return 0;
 308}
 309
 310static struct fsl_esdhc_cfg usdhc_cfg[3] = {
 311        {USDHC3_BASE_ADDR},
 312        {USDHC4_BASE_ADDR},
 313};
 314
 315#define USDHC3_CD_GPIO  IMX_GPIO_NR(7, 10)
 316#define USDHC3_RST_GPIO IMX_GPIO_NR(2, 11)
 317#define USDHC4_CD_GPIO  IMX_GPIO_NR(7, 11)
 318
 319int board_mmc_getcd(struct mmc *mmc)
 320{
 321        struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
 322        int ret = 0;
 323
 324        switch (cfg->esdhc_base) {
 325        case USDHC3_BASE_ADDR:
 326                ret = !gpio_get_value(USDHC3_CD_GPIO);
 327                break;
 328        case USDHC4_BASE_ADDR:
 329                ret = !gpio_get_value(USDHC4_CD_GPIO);
 330                break;
 331        }
 332
 333        return ret;
 334}
 335
 336int board_mmc_init(bd_t *bis)
 337{
 338        int i, ret;
 339
 340        /*
 341         * According to the board_mmc_init() the following map is done:
 342         * (U-Boot device node)    (Physical Port)
 343         * mmc0                    USDHC3
 344         * mmc1                    USDHC4
 345         */
 346        for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
 347                switch (i) {
 348                case 0:
 349                        imx_iomux_v3_setup_multiple_pads(
 350                                usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
 351                        gpio_direction_input(USDHC3_CD_GPIO);
 352
 353                        /* This starts a power cycle for UHS-I. Need to set steer to B0 to A*/
 354                        gpio_direction_output(USDHC3_RST_GPIO, 0);
 355                        udelay(1000); /* need 1ms at least */
 356                        gpio_direction_output(USDHC3_RST_GPIO, 1);
 357
 358                        usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
 359                        break;
 360                case 1:
 361                        imx_iomux_v3_setup_multiple_pads(
 362                                usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
 363                        gpio_direction_input(USDHC4_CD_GPIO);
 364                        usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
 365                        break;
 366                default:
 367                        printf("Warning: you configured more USDHC controllers"
 368                                "(%d) than supported by the board\n", i + 1);
 369                        return -EINVAL;
 370                        }
 371
 372                        ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
 373                        if (ret) {
 374                                printf("Warning: failed to initialize mmc dev %d\n", i);
 375                                return ret;
 376                        }
 377        }
 378
 379        return 0;
 380}
 381
 382#ifdef CONFIG_FSL_QSPI
 383
 384#define QSPI_PAD_CTRL1  \
 385        (PAD_CTL_SRE_FAST | PAD_CTL_SPEED_HIGH | \
 386         PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_40ohm)
 387
 388static iomux_v3_cfg_t const quadspi_pads[] = {
 389        MX6_PAD_QSPI1A_SS0_B__QSPI1_A_SS0_B   | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 390        MX6_PAD_QSPI1A_SCLK__QSPI1_A_SCLK     | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 391        MX6_PAD_QSPI1A_DATA0__QSPI1_A_DATA_0  | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 392        MX6_PAD_QSPI1A_DATA1__QSPI1_A_DATA_1  | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 393        MX6_PAD_QSPI1A_DATA2__QSPI1_A_DATA_2  | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 394        MX6_PAD_QSPI1A_DATA3__QSPI1_A_DATA_3  | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 395        MX6_PAD_QSPI1B_SS0_B__QSPI1_B_SS0_B   | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 396        MX6_PAD_QSPI1B_SCLK__QSPI1_B_SCLK     | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 397        MX6_PAD_QSPI1B_DATA0__QSPI1_B_DATA_0  | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 398        MX6_PAD_QSPI1B_DATA1__QSPI1_B_DATA_1  | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 399        MX6_PAD_QSPI1B_DATA2__QSPI1_B_DATA_2  | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 400        MX6_PAD_QSPI1B_DATA3__QSPI1_B_DATA_3  | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
 401};
 402
 403int board_qspi_init(void)
 404{
 405        /* Set the iomux */
 406        imx_iomux_v3_setup_multiple_pads(quadspi_pads,
 407                                         ARRAY_SIZE(quadspi_pads));
 408
 409        /* Set the clock */
 410        enable_qspi_clk(0);
 411
 412        return 0;
 413}
 414#endif
 415
 416#ifdef CONFIG_NAND_MXS
 417iomux_v3_cfg_t gpmi_pads[] = {
 418        MX6_PAD_NAND_CLE__RAWNAND_CLE           | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 419        MX6_PAD_NAND_ALE__RAWNAND_ALE           | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 420        MX6_PAD_NAND_WP_B__RAWNAND_WP_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 421        MX6_PAD_NAND_READY_B__RAWNAND_READY_B   | MUX_PAD_CTRL(GPMI_PAD_CTRL0),
 422        MX6_PAD_NAND_CE0_B__RAWNAND_CE0_B               | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 423        MX6_PAD_NAND_RE_B__RAWNAND_RE_B         | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 424        MX6_PAD_NAND_WE_B__RAWNAND_WE_B         | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 425        MX6_PAD_NAND_DATA00__RAWNAND_DATA00     | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 426        MX6_PAD_NAND_DATA01__RAWNAND_DATA01     | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 427        MX6_PAD_NAND_DATA02__RAWNAND_DATA02     | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 428        MX6_PAD_NAND_DATA03__RAWNAND_DATA03     | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 429        MX6_PAD_NAND_DATA04__RAWNAND_DATA04     | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 430        MX6_PAD_NAND_DATA05__RAWNAND_DATA05     | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 431        MX6_PAD_NAND_DATA06__RAWNAND_DATA06     | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 432        MX6_PAD_NAND_DATA07__RAWNAND_DATA07     | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 433};
 434
 435static void setup_gpmi_nand(void)
 436{
 437        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 438
 439        /* config gpmi nand iomux */
 440        imx_iomux_v3_setup_multiple_pads(gpmi_pads, ARRAY_SIZE(gpmi_pads));
 441
 442        setup_gpmi_io_clk((MXC_CCM_CS2CDR_QSPI2_CLK_PODF(0) |
 443                        MXC_CCM_CS2CDR_QSPI2_CLK_PRED(3) |
 444                        MXC_CCM_CS2CDR_QSPI2_CLK_SEL(3)));
 445
 446        /* enable apbh clock gating */
 447        setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
 448}
 449#endif
 450
 451int board_init(void)
 452{
 453        /* Address of boot parameters */
 454        gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
 455
 456#ifdef CONFIG_SYS_I2C_MXC
 457        setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
 458        setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info3);
 459#endif
 460
 461        /* Reset CPU_PER_RST_B signal for enet phy and PCIE */
 462        port_exp_direction_output(CPU_PER_RST_B, 0);
 463        udelay(500);
 464        port_exp_direction_output(CPU_PER_RST_B, 1);
 465
 466        /* Set steering signal to L for selecting B0 */
 467        port_exp_direction_output(STEER_ENET, 0);
 468
 469#ifdef CONFIG_USB_EHCI_MX6
 470        setup_usb();
 471#endif
 472
 473#ifdef CONFIG_FSL_QSPI
 474        board_qspi_init();
 475#endif
 476
 477#ifdef CONFIG_NAND_MXS
 478        setup_gpmi_nand();
 479#endif
 480
 481        return 0;
 482}
 483
 484#ifdef CONFIG_CMD_BMODE
 485static const struct boot_mode board_boot_modes[] = {
 486        {"sda", MAKE_CFGVAL(0x42, 0x30, 0x00, 0x00)},
 487        {"sdb", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)},
 488        {"qspi1", MAKE_CFGVAL(0x10, 0x00, 0x00, 0x00)},
 489        {"nand", MAKE_CFGVAL(0x82, 0x00, 0x00, 0x00)},
 490        {NULL,   0},
 491};
 492#endif
 493
 494int board_late_init(void)
 495{
 496#ifdef CONFIG_CMD_BMODE
 497        add_board_boot_modes(board_boot_modes);
 498#endif
 499
 500        return 0;
 501}
 502
 503int checkboard(void)
 504{
 505        puts("Board: MX6SX SABRE AUTO\n");
 506
 507        return 0;
 508}
 509