uboot/board/wandboard/wandboard.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2013 Freescale Semiconductor, Inc.
   3 * Copyright (C) 2014 O.S. Systems Software LTDA.
   4 *
   5 * Author: Fabio Estevam <fabio.estevam@freescale.com>
   6 *
   7 * SPDX-License-Identifier:     GPL-2.0+
   8 */
   9
  10#include <asm/arch/clock.h>
  11#include <asm/arch/crm_regs.h>
  12#include <asm/arch/iomux.h>
  13#include <asm/arch/imx-regs.h>
  14#include <asm/arch/mx6-pins.h>
  15#include <asm/arch/mxc_hdmi.h>
  16#include <asm/arch/sys_proto.h>
  17#include <asm/gpio.h>
  18#include <asm/mach-imx/iomux-v3.h>
  19#include <asm/mach-imx/mxc_i2c.h>
  20#include <asm/mach-imx/boot_mode.h>
  21#include <asm/mach-imx/video.h>
  22#include <asm/mach-imx/sata.h>
  23#include <asm/io.h>
  24#include <linux/sizes.h>
  25#include <common.h>
  26#include <fsl_esdhc.h>
  27#include <mmc.h>
  28#include <miiphy.h>
  29#include <netdev.h>
  30#include <phy.h>
  31#include <input.h>
  32#include <i2c.h>
  33
  34DECLARE_GLOBAL_DATA_PTR;
  35
  36#define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                   \
  37        PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |                 \
  38        PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
  39
  40#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP |                    \
  41        PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm |                 \
  42        PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
  43
  44#define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                   \
  45        PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
  46
  47#define I2C_PAD_CTRL    (PAD_CTL_PUS_100K_UP |                  \
  48        PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS |   \
  49        PAD_CTL_ODE | PAD_CTL_SRE_FAST)
  50
  51#define USDHC1_CD_GPIO          IMX_GPIO_NR(1, 2)
  52#define USDHC3_CD_GPIO          IMX_GPIO_NR(3, 9)
  53#define ETH_PHY_RESET           IMX_GPIO_NR(3, 29)
  54#define REV_DETECTION           IMX_GPIO_NR(2, 28)
  55
  56int dram_init(void)
  57{
  58        gd->ram_size = imx_ddr_size();
  59
  60        return 0;
  61}
  62
  63static iomux_v3_cfg_t const uart1_pads[] = {
  64        IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
  65        IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
  66};
  67
  68static iomux_v3_cfg_t const usdhc1_pads[] = {
  69        IOMUX_PADS(PAD_SD1_CLK__SD1_CLK    | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  70        IOMUX_PADS(PAD_SD1_CMD__SD1_CMD    | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  71        IOMUX_PADS(PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  72        IOMUX_PADS(PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  73        IOMUX_PADS(PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  74        IOMUX_PADS(PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  75        /* Carrier MicroSD Card Detect */
  76        IOMUX_PADS(PAD_GPIO_2__GPIO1_IO02  | MUX_PAD_CTRL(NO_PAD_CTRL)),
  77};
  78
  79static iomux_v3_cfg_t const usdhc3_pads[] = {
  80        IOMUX_PADS(PAD_SD3_CLK__SD3_CLK    | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  81        IOMUX_PADS(PAD_SD3_CMD__SD3_CMD    | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  82        IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  83        IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  84        IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  85        IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
  86        /* SOM MicroSD Card Detect */
  87        IOMUX_PADS(PAD_EIM_DA9__GPIO3_IO09  | MUX_PAD_CTRL(NO_PAD_CTRL)),
  88};
  89
  90static iomux_v3_cfg_t const enet_pads[] = {
  91        IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  92        IOMUX_PADS(PAD_ENET_MDC__ENET_MDC    | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  93        IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  94        IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  95        IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  96        IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  97        IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  98        IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  99        IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
 100        IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
 101        IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
 102        IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
 103        IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
 104        IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
 105        IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
 106        /* AR8031 PHY Reset */
 107        IOMUX_PADS(PAD_EIM_D29__GPIO3_IO29    | MUX_PAD_CTRL(NO_PAD_CTRL)),
 108};
 109
 110static iomux_v3_cfg_t const rev_detection_pad[] = {
 111        IOMUX_PADS(PAD_EIM_EB0__GPIO2_IO28  | MUX_PAD_CTRL(NO_PAD_CTRL)),
 112};
 113
 114static void setup_iomux_uart(void)
 115{
 116        SETUP_IOMUX_PADS(uart1_pads);
 117}
 118
 119static void setup_iomux_enet(void)
 120{
 121        SETUP_IOMUX_PADS(enet_pads);
 122
 123        /* Reset AR8031 PHY */
 124        gpio_direction_output(ETH_PHY_RESET, 0);
 125        mdelay(10);
 126        gpio_set_value(ETH_PHY_RESET, 1);
 127        udelay(100);
 128}
 129
 130static struct fsl_esdhc_cfg usdhc_cfg[2] = {
 131        {USDHC3_BASE_ADDR},
 132        {USDHC1_BASE_ADDR},
 133};
 134
 135int board_mmc_getcd(struct mmc *mmc)
 136{
 137        struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
 138        int ret = 0;
 139
 140        switch (cfg->esdhc_base) {
 141        case USDHC1_BASE_ADDR:
 142                ret = !gpio_get_value(USDHC1_CD_GPIO);
 143                break;
 144        case USDHC3_BASE_ADDR:
 145                ret = !gpio_get_value(USDHC3_CD_GPIO);
 146                break;
 147        }
 148
 149        return ret;
 150}
 151
 152int board_mmc_init(bd_t *bis)
 153{
 154        int ret;
 155        u32 index = 0;
 156
 157        /*
 158         * Following map is done:
 159         * (U-Boot device node)    (Physical Port)
 160         * mmc0                    SOM MicroSD
 161         * mmc1                    Carrier board MicroSD
 162         */
 163        for (index = 0; index < CONFIG_SYS_FSL_USDHC_NUM; ++index) {
 164                switch (index) {
 165                case 0:
 166                        SETUP_IOMUX_PADS(usdhc3_pads);
 167                        usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
 168                        usdhc_cfg[0].max_bus_width = 4;
 169                        gpio_direction_input(USDHC3_CD_GPIO);
 170                        break;
 171                case 1:
 172                        SETUP_IOMUX_PADS(usdhc1_pads);
 173                        usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
 174                        usdhc_cfg[1].max_bus_width = 4;
 175                        gpio_direction_input(USDHC1_CD_GPIO);
 176                        break;
 177                default:
 178                        printf("Warning: you configured more USDHC controllers"
 179                               "(%d) then supported by the board (%d)\n",
 180                               index + 1, CONFIG_SYS_FSL_USDHC_NUM);
 181                        return -EINVAL;
 182                }
 183
 184                ret = fsl_esdhc_initialize(bis, &usdhc_cfg[index]);
 185                if (ret)
 186                        return ret;
 187        }
 188
 189        return 0;
 190}
 191
 192static int ar8031_phy_fixup(struct phy_device *phydev)
 193{
 194        unsigned short val;
 195
 196        /* To enable AR8031 ouput a 125MHz clk from CLK_25M */
 197        phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
 198        phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
 199        phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
 200
 201        val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
 202        val &= 0xffe3;
 203        val |= 0x18;
 204        phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
 205
 206        /* introduce tx clock delay */
 207        phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
 208        val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
 209        val |= 0x0100;
 210        phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
 211
 212        return 0;
 213}
 214
 215int board_phy_config(struct phy_device *phydev)
 216{
 217        ar8031_phy_fixup(phydev);
 218
 219        if (phydev->drv->config)
 220                phydev->drv->config(phydev);
 221
 222        return 0;
 223}
 224
 225#if defined(CONFIG_VIDEO_IPUV3)
 226struct i2c_pads_info mx6q_i2c2_pad_info = {
 227        .scl = {
 228                .i2c_mode = MX6Q_PAD_KEY_COL3__I2C2_SCL
 229                        | MUX_PAD_CTRL(I2C_PAD_CTRL),
 230                .gpio_mode = MX6Q_PAD_KEY_COL3__GPIO4_IO12
 231                        | MUX_PAD_CTRL(I2C_PAD_CTRL),
 232                .gp = IMX_GPIO_NR(4, 12)
 233        },
 234        .sda = {
 235                .i2c_mode = MX6Q_PAD_KEY_ROW3__I2C2_SDA
 236                        | MUX_PAD_CTRL(I2C_PAD_CTRL),
 237                .gpio_mode = MX6Q_PAD_KEY_ROW3__GPIO4_IO13
 238                        | MUX_PAD_CTRL(I2C_PAD_CTRL),
 239                .gp = IMX_GPIO_NR(4, 13)
 240        }
 241};
 242
 243struct i2c_pads_info mx6dl_i2c2_pad_info = {
 244        .scl = {
 245                .i2c_mode = MX6DL_PAD_KEY_COL3__I2C2_SCL
 246                        | MUX_PAD_CTRL(I2C_PAD_CTRL),
 247                .gpio_mode = MX6DL_PAD_KEY_COL3__GPIO4_IO12
 248                        | MUX_PAD_CTRL(I2C_PAD_CTRL),
 249                .gp = IMX_GPIO_NR(4, 12)
 250        },
 251        .sda = {
 252                .i2c_mode = MX6DL_PAD_KEY_ROW3__I2C2_SDA
 253                        | MUX_PAD_CTRL(I2C_PAD_CTRL),
 254                .gpio_mode = MX6DL_PAD_KEY_ROW3__GPIO4_IO13
 255                        | MUX_PAD_CTRL(I2C_PAD_CTRL),
 256                .gp = IMX_GPIO_NR(4, 13)
 257        }
 258};
 259
 260static iomux_v3_cfg_t const fwadapt_7wvga_pads[] = {
 261        IOMUX_PADS(PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK),
 262        IOMUX_PADS(PAD_DI0_PIN2__IPU1_DI0_PIN02), /* HSync */
 263        IOMUX_PADS(PAD_DI0_PIN3__IPU1_DI0_PIN03), /* VSync */
 264        IOMUX_PADS(PAD_DI0_PIN4__IPU1_DI0_PIN04 | MUX_PAD_CTRL(PAD_CTL_DSE_120ohm)), /* Contrast */
 265        IOMUX_PADS(PAD_DI0_PIN15__IPU1_DI0_PIN15), /* DISP0_DRDY */
 266        IOMUX_PADS(PAD_DISP0_DAT0__IPU1_DISP0_DATA00),
 267        IOMUX_PADS(PAD_DISP0_DAT1__IPU1_DISP0_DATA01),
 268        IOMUX_PADS(PAD_DISP0_DAT2__IPU1_DISP0_DATA02),
 269        IOMUX_PADS(PAD_DISP0_DAT3__IPU1_DISP0_DATA03),
 270        IOMUX_PADS(PAD_DISP0_DAT4__IPU1_DISP0_DATA04),
 271        IOMUX_PADS(PAD_DISP0_DAT5__IPU1_DISP0_DATA05),
 272        IOMUX_PADS(PAD_DISP0_DAT6__IPU1_DISP0_DATA06),
 273        IOMUX_PADS(PAD_DISP0_DAT7__IPU1_DISP0_DATA07),
 274        IOMUX_PADS(PAD_DISP0_DAT8__IPU1_DISP0_DATA08),
 275        IOMUX_PADS(PAD_DISP0_DAT9__IPU1_DISP0_DATA09),
 276        IOMUX_PADS(PAD_DISP0_DAT10__IPU1_DISP0_DATA10),
 277        IOMUX_PADS(PAD_DISP0_DAT11__IPU1_DISP0_DATA11),
 278        IOMUX_PADS(PAD_DISP0_DAT12__IPU1_DISP0_DATA12),
 279        IOMUX_PADS(PAD_DISP0_DAT13__IPU1_DISP0_DATA13),
 280        IOMUX_PADS(PAD_DISP0_DAT14__IPU1_DISP0_DATA14),
 281        IOMUX_PADS(PAD_DISP0_DAT15__IPU1_DISP0_DATA15),
 282        IOMUX_PADS(PAD_DISP0_DAT16__IPU1_DISP0_DATA16),
 283        IOMUX_PADS(PAD_DISP0_DAT17__IPU1_DISP0_DATA17),
 284        IOMUX_PADS(PAD_SD4_DAT2__GPIO2_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL)), /* DISP0_BKLEN */
 285        IOMUX_PADS(PAD_SD4_DAT3__GPIO2_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL)), /* DISP0_VDDEN */
 286};
 287
 288static void do_enable_hdmi(struct display_info_t const *dev)
 289{
 290        imx_enable_hdmi_phy();
 291}
 292
 293static int detect_i2c(struct display_info_t const *dev)
 294{
 295        return (0 == i2c_set_bus_num(dev->bus)) &&
 296                        (0 == i2c_probe(dev->addr));
 297}
 298
 299static void enable_fwadapt_7wvga(struct display_info_t const *dev)
 300{
 301        SETUP_IOMUX_PADS(fwadapt_7wvga_pads);
 302
 303        gpio_direction_output(IMX_GPIO_NR(2, 10), 1);
 304        gpio_direction_output(IMX_GPIO_NR(2, 11), 1);
 305}
 306
 307struct display_info_t const displays[] = {{
 308        .bus    = -1,
 309        .addr   = 0,
 310        .pixfmt = IPU_PIX_FMT_RGB24,
 311        .detect = detect_hdmi,
 312        .enable = do_enable_hdmi,
 313        .mode   = {
 314                .name           = "HDMI",
 315                .refresh        = 60,
 316                .xres           = 1024,
 317                .yres           = 768,
 318                .pixclock       = 15385,
 319                .left_margin    = 220,
 320                .right_margin   = 40,
 321                .upper_margin   = 21,
 322                .lower_margin   = 7,
 323                .hsync_len      = 60,
 324                .vsync_len      = 10,
 325                .sync           = FB_SYNC_EXT,
 326                .vmode          = FB_VMODE_NONINTERLACED
 327} }, {
 328        .bus    = 1,
 329        .addr   = 0x10,
 330        .pixfmt = IPU_PIX_FMT_RGB666,
 331        .detect = detect_i2c,
 332        .enable = enable_fwadapt_7wvga,
 333        .mode   = {
 334                .name           = "FWBADAPT-LCD-F07A-0102",
 335                .refresh        = 60,
 336                .xres           = 800,
 337                .yres           = 480,
 338                .pixclock       = 33260,
 339                .left_margin    = 128,
 340                .right_margin   = 128,
 341                .upper_margin   = 22,
 342                .lower_margin   = 22,
 343                .hsync_len      = 1,
 344                .vsync_len      = 1,
 345                .sync           = 0,
 346                .vmode          = FB_VMODE_NONINTERLACED
 347} } };
 348size_t display_count = ARRAY_SIZE(displays);
 349
 350static void setup_display(void)
 351{
 352        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 353        int reg;
 354
 355        enable_ipu_clock();
 356        imx_setup_hdmi();
 357
 358        reg = readl(&mxc_ccm->chsccdr);
 359        reg |= (CHSCCDR_CLK_SEL_LDB_DI0
 360                << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
 361        writel(reg, &mxc_ccm->chsccdr);
 362
 363        /* Disable LCD backlight */
 364        SETUP_IOMUX_PAD(PAD_DI0_PIN4__GPIO4_IO20);
 365        gpio_direction_input(IMX_GPIO_NR(4, 20));
 366}
 367#endif /* CONFIG_VIDEO_IPUV3 */
 368
 369int board_eth_init(bd_t *bis)
 370{
 371        setup_iomux_enet();
 372
 373        return cpu_eth_init(bis);
 374}
 375
 376int board_early_init_f(void)
 377{
 378        setup_iomux_uart();
 379#if defined(CONFIG_VIDEO_IPUV3)
 380        setup_display();
 381#endif
 382#ifdef CONFIG_SATA
 383        /* Only mx6q wandboard has SATA */
 384        if (is_cpu_type(MXC_CPU_MX6Q))
 385                setup_sata();
 386#endif
 387
 388        return 0;
 389}
 390
 391/*
 392 * Do not overwrite the console
 393 * Use always serial for U-Boot console
 394 */
 395int overwrite_console(void)
 396{
 397        return 1;
 398}
 399
 400#ifdef CONFIG_CMD_BMODE
 401static const struct boot_mode board_boot_modes[] = {
 402        /* 4 bit bus width */
 403        {"mmc0",          MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
 404        {"mmc1",          MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)},
 405        {NULL,   0},
 406};
 407#endif
 408
 409static bool is_revc1(void)
 410{
 411        SETUP_IOMUX_PADS(rev_detection_pad);
 412        gpio_direction_input(REV_DETECTION);
 413
 414        if (gpio_get_value(REV_DETECTION))
 415                return true;
 416        else
 417                return false;
 418}
 419
 420int board_late_init(void)
 421{
 422#ifdef CONFIG_CMD_BMODE
 423        add_board_boot_modes(board_boot_modes);
 424#endif
 425
 426#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 427        if (is_mx6dq())
 428                env_set("board_rev", "MX6Q");
 429        else
 430                env_set("board_rev", "MX6DL");
 431
 432        if (is_revc1())
 433                env_set("board_name", "C1");
 434        else
 435                env_set("board_name", "B1");
 436#endif
 437        return 0;
 438}
 439
 440int board_init(void)
 441{
 442        /* address of boot parameters */
 443        gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
 444
 445#if defined(CONFIG_VIDEO_IPUV3)
 446        setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c2_pad_info);
 447        if (is_mx6dq())
 448                setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c2_pad_info);
 449        else
 450                setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c2_pad_info);
 451#endif
 452
 453        return 0;
 454}
 455
 456int checkboard(void)
 457{
 458        if (is_revc1())
 459                puts("Board: Wandboard rev C1\n");
 460        else
 461                puts("Board: Wandboard rev B1\n");
 462
 463        return 0;
 464}
 465