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