uboot/board/aristainetos/aristainetos-v2.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2015
   4 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
   5 *
   6 * Based on:
   7 * Copyright (C) 2012 Freescale Semiconductor, Inc.
   8 *
   9 * Author: Fabio Estevam <fabio.estevam@freescale.com>
  10 */
  11
  12#include <asm/arch/clock.h>
  13#include <asm/arch/imx-regs.h>
  14#include <asm/arch/iomux.h>
  15#include <asm/arch/mx6-pins.h>
  16#include <linux/errno.h>
  17#include <asm/gpio.h>
  18#include <asm/mach-imx/iomux-v3.h>
  19#include <asm/mach-imx/boot_mode.h>
  20#include <asm/mach-imx/mxc_i2c.h>
  21#include <asm/mach-imx/video.h>
  22#include <mmc.h>
  23#include <fsl_esdhc.h>
  24#include <miiphy.h>
  25#include <netdev.h>
  26#include <asm/arch/mxc_hdmi.h>
  27#include <asm/arch/crm_regs.h>
  28#include <linux/fb.h>
  29#include <ipu_pixfmt.h>
  30#include <asm/io.h>
  31#include <asm/arch/sys_proto.h>
  32#include <pwm.h>
  33#include <micrel.h>
  34#include <spi.h>
  35#include <video.h>
  36#include <../drivers/video/ipu.h>
  37#if defined(CONFIG_VIDEO_BMP_LOGO)
  38        #include <bmp_logo.h>
  39#endif
  40
  41#define USDHC2_PAD_CTRL (PAD_CTL_SPEED_LOW |                    \
  42        PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
  43
  44#if (CONFIG_SYS_BOARD_VERSION == 2)
  45        /* 4.3 display controller */
  46        #define ECSPI1_CS0              IMX_GPIO_NR(4, 9)
  47        #define ECSPI4_CS0              IMX_GPIO_NR(3, 29)
  48#elif (CONFIG_SYS_BOARD_VERSION == 3)
  49        #define ECSPI1_CS0              IMX_GPIO_NR(2, 30)   /* NOR flash */
  50        /* 4.3 display controller */
  51        #define ECSPI1_CS1              IMX_GPIO_NR(4, 10)
  52#endif
  53
  54#define SOFT_RESET_GPIO         IMX_GPIO_NR(7, 13)
  55#define SD2_DRIVER_ENABLE       IMX_GPIO_NR(7, 8)
  56
  57struct i2c_pads_info i2c_pad_info3 = {
  58        .scl = {
  59                .i2c_mode = MX6_PAD_GPIO_5__I2C3_SCL | PC,
  60                .gpio_mode = MX6_PAD_GPIO_5__GPIO1_IO05 | PC,
  61                .gp = IMX_GPIO_NR(1, 5)
  62        },
  63        .sda = {
  64                .i2c_mode = MX6_PAD_GPIO_6__I2C3_SDA | PC,
  65                .gpio_mode = MX6_PAD_GPIO_6__GPIO1_IO06 | PC,
  66                .gp = IMX_GPIO_NR(1, 6)
  67        }
  68};
  69
  70struct i2c_pads_info i2c_pad_info4 = {
  71        .scl = {
  72                .i2c_mode = MX6_PAD_GPIO_7__I2C4_SCL | PC,
  73                .gpio_mode = MX6_PAD_GPIO_7__GPIO1_IO07 | PC,
  74                .gp = IMX_GPIO_NR(1, 7)
  75        },
  76        .sda = {
  77                .i2c_mode = MX6_PAD_GPIO_8__I2C4_SDA | PC,
  78                .gpio_mode = MX6_PAD_GPIO_8__GPIO1_IO08 | PC,
  79                .gp = IMX_GPIO_NR(1, 8)
  80        }
  81};
  82
  83iomux_v3_cfg_t const uart1_pads[] = {
  84        MX6_PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  85        MX6_PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  86        MX6_PAD_EIM_D19__UART1_CTS_B    | MUX_PAD_CTRL(UART_PAD_CTRL),
  87        MX6_PAD_EIM_D20__UART1_RTS_B    | MUX_PAD_CTRL(UART_PAD_CTRL),
  88};
  89
  90iomux_v3_cfg_t const uart2_pads[] = {
  91        MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  92        MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  93};
  94
  95iomux_v3_cfg_t const uart3_pads[] = {
  96        MX6_PAD_EIM_D24__UART3_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  97        MX6_PAD_EIM_D25__UART3_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  98        MX6_PAD_EIM_D31__UART3_RTS_B | MUX_PAD_CTRL(UART_PAD_CTRL),
  99        MX6_PAD_EIM_D23__UART3_CTS_B | MUX_PAD_CTRL(UART_PAD_CTRL),
 100};
 101
 102iomux_v3_cfg_t const uart4_pads[] = {
 103        MX6_PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
 104        MX6_PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
 105};
 106
 107iomux_v3_cfg_t const gpio_pads[] = {
 108        /* LED enable*/
 109        MX6_PAD_ENET_CRS_DV__GPIO1_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL),
 110        /* LED yellow */
 111        MX6_PAD_NANDF_CS3__GPIO6_IO16 | MUX_PAD_CTRL(NO_PAD_CTRL),
 112        /* LED red */
 113#if (CONFIG_SYS_BOARD_VERSION == 2)
 114        MX6_PAD_EIM_EB0__GPIO2_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL),
 115#elif (CONFIG_SYS_BOARD_VERSION == 3)
 116        MX6_PAD_EIM_WAIT__GPIO5_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL),
 117#endif
 118        /* LED green */
 119        MX6_PAD_EIM_A24__GPIO5_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL),
 120        /* LED blue */
 121        MX6_PAD_EIM_EB1__GPIO2_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
 122        /* spi flash WP protect */
 123        MX6_PAD_SD4_DAT7__GPIO2_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
 124        /* spi CS 0 */
 125        MX6_PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
 126        /* spi bus #2 SS driver enable */
 127        MX6_PAD_EIM_A23__GPIO6_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
 128        /* RST_LOC# PHY reset input (has pull-down!)*/
 129        MX6_PAD_GPIO_18__GPIO7_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL),
 130        /* SD 2 level shifter output enable */
 131        MX6_PAD_SD3_RST__GPIO7_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
 132        /* SD1 card detect input */
 133        MX6_PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
 134        /* SD1 write protect input */
 135        MX6_PAD_DI0_PIN4__GPIO4_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
 136        /* SD2 card detect input */
 137        MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
 138        /* SD2 write protect input */
 139        MX6_PAD_SD4_DAT2__GPIO2_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
 140        /* Touchscreen IRQ */
 141        MX6_PAD_SD4_DAT1__GPIO2_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),
 142};
 143
 144static iomux_v3_cfg_t const misc_pads[] = {
 145        /* USB_OTG_ID = GPIO1_24*/
 146        MX6_PAD_ENET_RX_ER__USB_OTG_ID          | MUX_PAD_CTRL(NO_PAD_CTRL),
 147        /* H1 Power enable = GPIO1_0*/
 148        MX6_PAD_GPIO_0__USB_H1_PWR              | MUX_PAD_CTRL(NO_PAD_CTRL),
 149        /* OTG Power enable = GPIO4_15*/
 150        MX6_PAD_KEY_ROW4__USB_OTG_PWR           | MUX_PAD_CTRL(NO_PAD_CTRL),
 151};
 152
 153iomux_v3_cfg_t const enet_pads[] = {
 154        MX6_PAD_ENET_MDIO__ENET_MDIO            | MUX_PAD_CTRL(ENET_PAD_CTRL),
 155        MX6_PAD_ENET_MDC__ENET_MDC              | MUX_PAD_CTRL(ENET_PAD_CTRL),
 156        MX6_PAD_RGMII_TXC__RGMII_TXC    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 157        MX6_PAD_RGMII_TD0__RGMII_TD0    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 158        MX6_PAD_RGMII_TD1__RGMII_TD1    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 159        MX6_PAD_RGMII_TD2__RGMII_TD2    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 160        MX6_PAD_RGMII_TD3__RGMII_TD3    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 161        MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
 162        MX6_PAD_ENET_REF_CLK__ENET_TX_CLK       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 163        MX6_PAD_RGMII_RXC__RGMII_RXC    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 164        MX6_PAD_RGMII_RD0__RGMII_RD0    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 165        MX6_PAD_RGMII_RD1__RGMII_RD1    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 166        MX6_PAD_RGMII_RD2__RGMII_RD2    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 167        MX6_PAD_RGMII_RD3__RGMII_RD3    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 168        MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
 169};
 170
 171static iomux_v3_cfg_t const backlight_pads[] = {
 172        /* backlight PWM brightness control */
 173        MX6_PAD_GPIO_9__PWM1_OUT | MUX_PAD_CTRL(NO_PAD_CTRL),
 174        /* backlight enable */
 175        MX6_PAD_EIM_BCLK__GPIO6_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL),
 176        /* LCD power enable */
 177        MX6_PAD_NANDF_CS2__GPIO6_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
 178};
 179
 180static iomux_v3_cfg_t const ecspi1_pads[] = {
 181        MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
 182        MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
 183        MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
 184#if (CONFIG_SYS_BOARD_VERSION == 2)
 185        MX6_PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(SPI_PAD_CTRL),
 186#elif (CONFIG_SYS_BOARD_VERSION == 3)
 187        MX6_PAD_EIM_EB2__GPIO2_IO30  | MUX_PAD_CTRL(SPI_PAD_CTRL),
 188        MX6_PAD_KEY_COL2__GPIO4_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
 189#endif
 190};
 191
 192static void setup_iomux_enet(void)
 193{
 194        imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
 195}
 196
 197#if (CONFIG_SYS_BOARD_VERSION == 2)
 198iomux_v3_cfg_t const ecspi4_pads[] = {
 199        MX6_PAD_EIM_D21__ECSPI4_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL),
 200        MX6_PAD_EIM_D22__ECSPI4_MISO | MUX_PAD_CTRL(NO_PAD_CTRL),
 201        MX6_PAD_EIM_D28__ECSPI4_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL),
 202        MX6_PAD_EIM_A25__GPIO5_IO02  | MUX_PAD_CTRL(NO_PAD_CTRL),
 203        MX6_PAD_EIM_D29__GPIO3_IO29  | MUX_PAD_CTRL(NO_PAD_CTRL),
 204};
 205#endif
 206
 207static iomux_v3_cfg_t const display_pads[] = {
 208        MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK | MUX_PAD_CTRL(DISP_PAD_CTRL),
 209        MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15,
 210        MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02,
 211        MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03,
 212        MX6_PAD_DISP0_DAT0__IPU1_DISP0_DATA00,
 213        MX6_PAD_DISP0_DAT1__IPU1_DISP0_DATA01,
 214        MX6_PAD_DISP0_DAT2__IPU1_DISP0_DATA02,
 215        MX6_PAD_DISP0_DAT3__IPU1_DISP0_DATA03,
 216        MX6_PAD_DISP0_DAT4__IPU1_DISP0_DATA04,
 217        MX6_PAD_DISP0_DAT5__IPU1_DISP0_DATA05,
 218        MX6_PAD_DISP0_DAT6__IPU1_DISP0_DATA06,
 219        MX6_PAD_DISP0_DAT7__IPU1_DISP0_DATA07,
 220        MX6_PAD_DISP0_DAT8__IPU1_DISP0_DATA08,
 221        MX6_PAD_DISP0_DAT9__IPU1_DISP0_DATA09,
 222        MX6_PAD_DISP0_DAT10__IPU1_DISP0_DATA10,
 223        MX6_PAD_DISP0_DAT11__IPU1_DISP0_DATA11,
 224        MX6_PAD_DISP0_DAT12__IPU1_DISP0_DATA12,
 225        MX6_PAD_DISP0_DAT13__IPU1_DISP0_DATA13,
 226        MX6_PAD_DISP0_DAT14__IPU1_DISP0_DATA14,
 227        MX6_PAD_DISP0_DAT15__IPU1_DISP0_DATA15,
 228        MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16,
 229        MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17,
 230        MX6_PAD_DISP0_DAT18__IPU1_DISP0_DATA18,
 231        MX6_PAD_DISP0_DAT19__IPU1_DISP0_DATA19,
 232        MX6_PAD_DISP0_DAT20__IPU1_DISP0_DATA20,
 233        MX6_PAD_DISP0_DAT21__IPU1_DISP0_DATA21,
 234        MX6_PAD_DISP0_DAT22__IPU1_DISP0_DATA22,
 235        MX6_PAD_DISP0_DAT23__IPU1_DISP0_DATA23,
 236};
 237
 238int board_spi_cs_gpio(unsigned bus, unsigned cs)
 239{
 240        if (bus == CONFIG_SF_DEFAULT_BUS && cs == CONFIG_SF_DEFAULT_CS)
 241#if (CONFIG_SYS_BOARD_VERSION == 2)
 242                return IMX_GPIO_NR(5, 2);
 243
 244        if (bus == 0 && cs == 0)
 245                return IMX_GPIO_NR(4, 9);
 246#elif (CONFIG_SYS_BOARD_VERSION == 3)
 247                return ECSPI1_CS0;
 248
 249        if (bus == 0 && cs == 1)
 250                return ECSPI1_CS1;
 251#endif
 252        return -1;
 253}
 254
 255static void setup_spi(void)
 256{
 257        int i;
 258
 259        imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads));
 260
 261#if (CONFIG_SYS_BOARD_VERSION == 2)
 262        imx_iomux_v3_setup_multiple_pads(ecspi4_pads, ARRAY_SIZE(ecspi4_pads));
 263#endif
 264
 265        for (i = 0; i < 4; i++)
 266                enable_spi_clk(true, i);
 267
 268        gpio_direction_output(ECSPI1_CS0, 1);
 269#if (CONFIG_SYS_BOARD_VERSION == 2)
 270        gpio_direction_output(ECSPI4_CS1, 0);
 271        /* set cs0 to high (second device on spi bus #4) */
 272        gpio_direction_output(ECSPI4_CS0, 1);
 273#elif (CONFIG_SYS_BOARD_VERSION == 3)
 274        gpio_direction_output(ECSPI1_CS1, 1);
 275#endif
 276}
 277
 278static void setup_iomux_uart(void)
 279{
 280        switch (CONFIG_MXC_UART_BASE) {
 281        case UART1_BASE:
 282                imx_iomux_v3_setup_multiple_pads(uart1_pads,
 283                                                 ARRAY_SIZE(uart1_pads));
 284                break;
 285        case UART2_BASE:
 286                imx_iomux_v3_setup_multiple_pads(uart2_pads,
 287                                                 ARRAY_SIZE(uart2_pads));
 288                break;
 289        case UART3_BASE:
 290                imx_iomux_v3_setup_multiple_pads(uart3_pads,
 291                                                 ARRAY_SIZE(uart3_pads));
 292                break;
 293        case UART4_BASE:
 294                imx_iomux_v3_setup_multiple_pads(uart4_pads,
 295                                                 ARRAY_SIZE(uart4_pads));
 296                break;
 297        }
 298}
 299
 300int board_phy_config(struct phy_device *phydev)
 301{
 302        /* control data pad skew - devaddr = 0x02, register = 0x04 */
 303        ksz9031_phy_extended_write(phydev, 0x02,
 304                                   MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW,
 305                                   MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
 306        /* rx data pad skew - devaddr = 0x02, register = 0x05 */
 307        ksz9031_phy_extended_write(phydev, 0x02,
 308                                   MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW,
 309                                   MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
 310        /* tx data pad skew - devaddr = 0x02, register = 0x06 */
 311        ksz9031_phy_extended_write(phydev, 0x02,
 312                                   MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW,
 313                                   MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
 314        /* gtx and rx clock pad skew - devaddr = 0x02, register = 0x08 */
 315        ksz9031_phy_extended_write(phydev, 0x02,
 316                                   MII_KSZ9031_EXT_RGMII_CLOCK_SKEW,
 317                                   MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x03FF);
 318
 319        if (phydev->drv->config)
 320                phydev->drv->config(phydev);
 321
 322        return 0;
 323}
 324
 325int board_eth_init(bd_t *bis)
 326{
 327        setup_iomux_enet();
 328        return cpu_eth_init(bis);
 329}
 330
 331static int rotate_logo_one(unsigned char *out, unsigned char *in)
 332{
 333        int   i, j;
 334
 335        for (i = 0; i < BMP_LOGO_WIDTH; i++)
 336                for (j = 0; j < BMP_LOGO_HEIGHT; j++)
 337                        out[j * BMP_LOGO_WIDTH + BMP_LOGO_HEIGHT - 1 - i] =
 338                        in[i * BMP_LOGO_WIDTH + j];
 339        return 0;
 340}
 341
 342/*
 343 * Rotate the BMP_LOGO (only)
 344 * Will only work, if the logo is square, as
 345 * BMP_LOGO_HEIGHT and BMP_LOGO_WIDTH are defines, not variables
 346 */
 347void rotate_logo(int rotations)
 348{
 349        unsigned char out_logo[BMP_LOGO_WIDTH * BMP_LOGO_HEIGHT];
 350        unsigned char *in_logo;
 351        int   i, j;
 352
 353        if (BMP_LOGO_WIDTH != BMP_LOGO_HEIGHT)
 354                return;
 355
 356        in_logo = bmp_logo_bitmap;
 357
 358        /* one 90 degree rotation */
 359        if (rotations == 1  ||  rotations == 2  ||  rotations == 3)
 360                rotate_logo_one(out_logo, in_logo);
 361
 362        /* second 90 degree rotation */
 363        if (rotations == 2  ||  rotations == 3)
 364                rotate_logo_one(in_logo, out_logo);
 365
 366        /* third 90 degree rotation */
 367        if (rotations == 3)
 368                rotate_logo_one(out_logo, in_logo);
 369
 370        /* copy result back to original array */
 371        if (rotations == 1  ||  rotations == 3)
 372                for (i = 0; i < BMP_LOGO_WIDTH; i++)
 373                        for (j = 0; j < BMP_LOGO_HEIGHT; j++)
 374                                in_logo[i * BMP_LOGO_WIDTH + j] =
 375                                out_logo[i * BMP_LOGO_WIDTH + j];
 376}
 377
 378static void enable_display_power(void)
 379{
 380        imx_iomux_v3_setup_multiple_pads(backlight_pads,
 381                                         ARRAY_SIZE(backlight_pads));
 382
 383        /* backlight enable */
 384        gpio_direction_output(IMX_GPIO_NR(6, 31), 1);
 385        /* LCD power enable */
 386        gpio_direction_output(IMX_GPIO_NR(6, 15), 1);
 387
 388        /* enable backlight PWM 1 */
 389        if (pwm_init(0, 0, 0))
 390                goto error;
 391        /* duty cycle 500ns, period: 3000ns */
 392        if (pwm_config(0, 50000, 300000))
 393                goto error;
 394        if (pwm_enable(0))
 395                goto error;
 396        return;
 397
 398error:
 399        puts("error init pwm for backlight\n");
 400        return;
 401}
 402
 403static void enable_lvds(struct display_info_t const *dev)
 404{
 405        struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
 406        struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 407        int reg;
 408        s32 timeout = 100000;
 409
 410        /* set PLL5 clock */
 411        reg = readl(&ccm->analog_pll_video);
 412        reg |= BM_ANADIG_PLL_VIDEO_POWERDOWN;
 413        writel(reg, &ccm->analog_pll_video);
 414
 415        /* set PLL5 to 232720000Hz */
 416        reg &= ~BM_ANADIG_PLL_VIDEO_DIV_SELECT;
 417        reg |= BF_ANADIG_PLL_VIDEO_DIV_SELECT(0x26);
 418        reg &= ~BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT;
 419        reg |= BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(0);
 420        writel(reg, &ccm->analog_pll_video);
 421
 422        writel(BF_ANADIG_PLL_VIDEO_NUM_A(0xC0238),
 423               &ccm->analog_pll_video_num);
 424        writel(BF_ANADIG_PLL_VIDEO_DENOM_B(0xF4240),
 425               &ccm->analog_pll_video_denom);
 426
 427        reg &= ~BM_ANADIG_PLL_VIDEO_POWERDOWN;
 428        writel(reg, &ccm->analog_pll_video);
 429
 430        while (timeout--)
 431                if (readl(&ccm->analog_pll_video) & BM_ANADIG_PLL_VIDEO_LOCK)
 432                        break;
 433        if (timeout < 0)
 434                printf("Warning: video pll lock timeout!\n");
 435
 436        reg = readl(&ccm->analog_pll_video);
 437        reg |= BM_ANADIG_PLL_VIDEO_ENABLE;
 438        reg &= ~BM_ANADIG_PLL_VIDEO_BYPASS;
 439        writel(reg, &ccm->analog_pll_video);
 440
 441        /* set LDB0, LDB1 clk select to 000/000 (PLL5 clock) */
 442        reg = readl(&ccm->cs2cdr);
 443        reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
 444                 | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
 445        reg |= (0 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
 446                | (0 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
 447        writel(reg, &ccm->cs2cdr);
 448
 449        reg = readl(&ccm->cscmr2);
 450        reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
 451        writel(reg, &ccm->cscmr2);
 452
 453        reg = readl(&ccm->chsccdr);
 454        reg |= (CHSCCDR_CLK_SEL_LDB_DI0
 455                << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
 456        writel(reg, &ccm->chsccdr);
 457
 458        reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
 459              | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
 460              | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_HIGH
 461              | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
 462              | IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT
 463              | IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED
 464              | IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
 465        writel(reg, &iomux->gpr[2]);
 466
 467        reg = readl(&iomux->gpr[3]);
 468        reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)
 469               | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
 470                  << IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
 471        writel(reg, &iomux->gpr[3]);
 472
 473        return;
 474}
 475
 476static void enable_spi_display(struct display_info_t const *dev)
 477{
 478        struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
 479        struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 480        int reg;
 481        s32 timeout = 100000;
 482
 483#if defined(CONFIG_VIDEO_BMP_LOGO)
 484        rotate_logo(3);  /* portrait display in landscape mode */
 485#endif
 486
 487        /*
 488         * set ldb clock to 28341000 Hz calculated through the formula:
 489         * (XRES + LEFT_M + RIGHT_M + HSYNC_LEN) *
 490         * (YRES + UPPER_M + LOWER_M + VSYNC_LEN) * REFRESH)
 491         * see:
 492         * https://community.freescale.com/thread/308170
 493         */
 494        ipu_set_ldb_clock(28341000);
 495
 496        reg = readl(&ccm->cs2cdr);
 497
 498        /* select pll 5 clock */
 499        reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
 500                | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
 501        writel(reg, &ccm->cs2cdr);
 502
 503        /* set PLL5 to 197994996Hz */
 504        reg &= ~BM_ANADIG_PLL_VIDEO_DIV_SELECT;
 505        reg |= BF_ANADIG_PLL_VIDEO_DIV_SELECT(0x21);
 506        reg &= ~BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT;
 507        reg |= BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(0);
 508        writel(reg, &ccm->analog_pll_video);
 509
 510        writel(BF_ANADIG_PLL_VIDEO_NUM_A(0xfbf4),
 511               &ccm->analog_pll_video_num);
 512        writel(BF_ANADIG_PLL_VIDEO_DENOM_B(0xf4240),
 513               &ccm->analog_pll_video_denom);
 514
 515        reg &= ~BM_ANADIG_PLL_VIDEO_POWERDOWN;
 516        writel(reg, &ccm->analog_pll_video);
 517
 518        while (timeout--)
 519                if (readl(&ccm->analog_pll_video) & BM_ANADIG_PLL_VIDEO_LOCK)
 520                        break;
 521        if (timeout < 0)
 522                printf("Warning: video pll lock timeout!\n");
 523
 524        reg = readl(&ccm->analog_pll_video);
 525        reg |= BM_ANADIG_PLL_VIDEO_ENABLE;
 526        reg &= ~BM_ANADIG_PLL_VIDEO_BYPASS;
 527        writel(reg, &ccm->analog_pll_video);
 528
 529        /* set LDB0, LDB1 clk select to 000/000 (PLL5 clock) */
 530        reg = readl(&ccm->cs2cdr);
 531        reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
 532                 | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
 533        reg |= (0 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
 534                | (0 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
 535        writel(reg, &ccm->cs2cdr);
 536
 537        reg = readl(&ccm->cscmr2);
 538        reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
 539        writel(reg, &ccm->cscmr2);
 540
 541        reg = readl(&ccm->chsccdr);
 542        reg |= (CHSCCDR_CLK_SEL_LDB_DI0
 543                << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
 544        reg &= ~MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK;
 545        reg |= (2 << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET);
 546        reg &= ~MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK;
 547        reg |= (2 << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
 548        writel(reg, &ccm->chsccdr);
 549
 550        reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
 551              | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
 552              | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_HIGH
 553              | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
 554              | IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT
 555              | IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED
 556              | IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
 557        writel(reg, &iomux->gpr[2]);
 558
 559        reg = readl(&iomux->gpr[3]);
 560        reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)
 561               | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
 562                  << IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
 563        writel(reg, &iomux->gpr[3]);
 564
 565        imx_iomux_v3_setup_multiple_pads(
 566                display_pads,
 567                 ARRAY_SIZE(display_pads));
 568
 569        return;
 570}
 571static void setup_display(void)
 572{
 573        enable_ipu_clock();
 574        enable_display_power();
 575}
 576
 577static void setup_iomux_gpio(void)
 578{
 579        imx_iomux_v3_setup_multiple_pads(gpio_pads, ARRAY_SIZE(gpio_pads));
 580}
 581
 582static void set_gpr_register(void)
 583{
 584        struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
 585
 586        writel(IOMUXC_GPR1_APP_CLK_REQ_N | IOMUXC_GPR1_PCIE_RDY_L23 |
 587               IOMUXC_GPR1_EXC_MON_SLVE |
 588               (2 << IOMUXC_GPR1_ADDRS0_OFFSET) |
 589               IOMUXC_GPR1_ACT_CS0,
 590               &iomuxc_regs->gpr[1]);
 591        writel(0x0, &iomuxc_regs->gpr[8]);
 592        writel(IOMUXC_GPR12_ARMP_IPG_CLK_EN | IOMUXC_GPR12_ARMP_AHB_CLK_EN |
 593               IOMUXC_GPR12_ARMP_ATB_CLK_EN | IOMUXC_GPR12_ARMP_APB_CLK_EN,
 594               &iomuxc_regs->gpr[12]);
 595}
 596
 597int board_early_init_f(void)
 598{
 599        setup_iomux_uart();
 600        setup_iomux_gpio();
 601
 602        gpio_direction_output(SOFT_RESET_GPIO, 1);
 603        gpio_direction_output(SD2_DRIVER_ENABLE, 1);
 604        setup_display();
 605        set_gpr_register();
 606        return 0;
 607}
 608
 609static void setup_i2c4(void)
 610{
 611        setup_i2c(3, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE,
 612                  &i2c_pad_info4);
 613}
 614
 615static void setup_board_gpio(void)
 616{
 617        /* enable all LEDs */
 618        gpio_request(IMX_GPIO_NR(2, 13), "LED ena"); /* 25 */
 619        gpio_direction_output(IMX_GPIO_NR(1, 25), 0);
 620
 621        /* switch off Status LEDs */
 622#if (CONFIG_SYS_BOARD_VERSION == 2)
 623        gpio_request(IMX_GPIO_NR(6, 16), "LED yellow"); /* 176 */
 624        gpio_direction_output(IMX_GPIO_NR(6, 16), 1);
 625        gpio_request(IMX_GPIO_NR(2, 28), "LED red"); /* 60 */
 626        gpio_direction_output(IMX_GPIO_NR(2, 28), 1);
 627        gpio_request(IMX_GPIO_NR(5, 4), "LED green"); /* 132 */
 628        gpio_direction_output(IMX_GPIO_NR(5, 4), 1);
 629        gpio_request(IMX_GPIO_NR(2, 29), "LED blue"); /* 61 */
 630        gpio_direction_output(IMX_GPIO_NR(2, 29), 1);
 631#elif (CONFIG_SYS_BOARD_VERSION == 3)
 632        gpio_request(IMX_GPIO_NR(6, 16), "LED yellow"); /* 176 */
 633        gpio_direction_output(IMX_GPIO_NR(6, 16), 0);
 634        gpio_request(IMX_GPIO_NR(5, 0), "LED red"); /* 128 */
 635        gpio_direction_output(IMX_GPIO_NR(5, 0), 0);
 636        gpio_request(IMX_GPIO_NR(5, 4), "LED green"); /* 132 */
 637        gpio_direction_output(IMX_GPIO_NR(5, 4), 0);
 638        gpio_request(IMX_GPIO_NR(2, 29), "LED blue"); /* 61 */
 639        gpio_direction_output(IMX_GPIO_NR(2, 29), 0);
 640#endif
 641}
 642
 643static void setup_board_spi(void)
 644{
 645        /* enable spi bus #2 SS drivers (and spi bus #4 SS1 for rev2b) */
 646        gpio_direction_output(IMX_GPIO_NR(6, 6), 1);
 647}
 648
 649int board_late_init(void)
 650{
 651        char *my_bootdelay;
 652        char bootmode = 0;
 653        char const *panel = env_get("panel");
 654
 655        /*
 656         * Check the boot-source. If booting from NOR Flash,
 657         * disable bootdelay
 658         */
 659        gpio_request(IMX_GPIO_NR(7, 6), "bootsel0");
 660        gpio_direction_input(IMX_GPIO_NR(7, 6));
 661        gpio_request(IMX_GPIO_NR(7, 7), "bootsel1");
 662        gpio_direction_input(IMX_GPIO_NR(7, 7));
 663        gpio_request(IMX_GPIO_NR(7, 1), "bootsel2");
 664        gpio_direction_input(IMX_GPIO_NR(7, 1));
 665        bootmode |= (gpio_get_value(IMX_GPIO_NR(7, 6)) ? 1 : 0) << 0;
 666        bootmode |= (gpio_get_value(IMX_GPIO_NR(7, 7)) ? 1 : 0) << 1;
 667        bootmode |= (gpio_get_value(IMX_GPIO_NR(7, 1)) ? 1 : 0) << 2;
 668
 669        if (bootmode == 7) {
 670                my_bootdelay = env_get("nor_bootdelay");
 671                if (my_bootdelay != NULL)
 672                        env_set("bootdelay", my_bootdelay);
 673                else
 674                        env_set("bootdelay", "-2");
 675        }
 676
 677        /* if we have the lg panel, we can initialze it now */
 678        if (panel)
 679                if (!strcmp(panel, displays[1].mode.name))
 680                        lg4573_spi_startup(CONFIG_LG4573_BUS,
 681                                           CONFIG_LG4573_CS,
 682                                           10000000, SPI_MODE_0);
 683
 684        return 0;
 685}
 686