uboot/board/technexion/pico-imx6/pico-imx6.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2013 Freescale Semiconductor, Inc.
   4 * Copyright (C) 2014 O.S. Systems Software LTDA.
   5 *
   6 * Author: Fabio Estevam <festevam@gmail.com>
   7 */
   8
   9#include <env.h>
  10#include <init.h>
  11#include <net.h>
  12#include <asm/arch/clock.h>
  13#include <asm/arch/crm_regs.h>
  14#include <asm/arch/iomux.h>
  15#include <asm/arch/imx-regs.h>
  16#include <asm/arch/mx6-pins.h>
  17#include <asm/arch/sys_proto.h>
  18#include <asm/gpio.h>
  19#include <asm/arch/mxc_hdmi.h>
  20#include <asm/mach-imx/video.h>
  21#include <asm/mach-imx/iomux-v3.h>
  22#include <asm/io.h>
  23#include <linux/delay.h>
  24#include <linux/sizes.h>
  25#include <common.h>
  26#include <miiphy.h>
  27#include <netdev.h>
  28#include <phy.h>
  29
  30DECLARE_GLOBAL_DATA_PTR;
  31
  32#define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                   \
  33        PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |                 \
  34        PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
  35
  36#define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                   \
  37        PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
  38
  39#define ETH_PHY_RESET           IMX_GPIO_NR(1, 26)
  40#define LVDS0_EN                IMX_GPIO_NR(2, 8)
  41#define LVDS0_BL_EN             IMX_GPIO_NR(2, 9)
  42
  43int dram_init(void)
  44{
  45        gd->ram_size = imx_ddr_size();
  46
  47        return 0;
  48}
  49
  50static iomux_v3_cfg_t const uart1_pads[] = {
  51        IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
  52        IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
  53};
  54
  55static void setup_iomux_uart(void)
  56{
  57        SETUP_IOMUX_PADS(uart1_pads);
  58}
  59
  60static iomux_v3_cfg_t const lvds_pads[] = {
  61        /* lvds */
  62        IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL)),
  63        IOMUX_PADS(PAD_SD4_DAT1__GPIO2_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL)),
  64        IOMUX_PADS(PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK | MUX_PAD_CTRL(NO_PAD_CTRL)),
  65        IOMUX_PADS(PAD_DI0_PIN2__IPU1_DI0_PIN02 | MUX_PAD_CTRL(NO_PAD_CTRL)),
  66        IOMUX_PADS(PAD_DI0_PIN3__IPU1_DI0_PIN03 | MUX_PAD_CTRL(NO_PAD_CTRL)),
  67};
  68
  69static iomux_v3_cfg_t const enet_pads[] = {
  70        IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  71        IOMUX_PADS(PAD_ENET_MDC__ENET_MDC    | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  72        IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  73        IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  74        IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  75        IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  76        IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  77        IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL |
  78                   MUX_PAD_CTRL(ENET_PAD_CTRL)),
  79        IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK |
  80                   MUX_PAD_CTRL(ENET_PAD_CTRL)),
  81        IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  82        IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  83        IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  84        IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  85        IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3  | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  86        IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
  87        /* AR8035 PHY Reset */
  88        IOMUX_PADS(PAD_ENET_RXD1__GPIO1_IO26 | MUX_PAD_CTRL(NO_PAD_CTRL)),
  89};
  90
  91static void setup_iomux_enet(void)
  92{
  93        SETUP_IOMUX_PADS(enet_pads);
  94
  95        /* Reset AR8031 PHY */
  96        gpio_request(ETH_PHY_RESET, "enet_phy_reset");
  97        gpio_direction_output(ETH_PHY_RESET, 0);
  98        udelay(500);
  99        gpio_set_value(ETH_PHY_RESET, 1);
 100}
 101
 102#if defined(CONFIG_VIDEO_IPUV3)
 103static iomux_v3_cfg_t const ft5x06_wvga_pads[] = {
 104        IOMUX_PADS(PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK),
 105        IOMUX_PADS(PAD_DI0_PIN2__IPU1_DI0_PIN02), /* HSync */
 106        IOMUX_PADS(PAD_DI0_PIN3__IPU1_DI0_PIN03), /* VSync */
 107        IOMUX_PADS(PAD_DI0_PIN4__IPU1_DI0_PIN04 | MUX_PAD_CTRL(PAD_CTL_DSE_120ohm)), /* Contrast */
 108        IOMUX_PADS(PAD_DI0_PIN15__IPU1_DI0_PIN15), /* DISP0_DRDY */
 109        IOMUX_PADS(PAD_DISP0_DAT0__IPU1_DISP0_DATA00),
 110        IOMUX_PADS(PAD_DISP0_DAT1__IPU1_DISP0_DATA01),
 111        IOMUX_PADS(PAD_DISP0_DAT2__IPU1_DISP0_DATA02),
 112        IOMUX_PADS(PAD_DISP0_DAT3__IPU1_DISP0_DATA03),
 113        IOMUX_PADS(PAD_DISP0_DAT4__IPU1_DISP0_DATA04),
 114        IOMUX_PADS(PAD_DISP0_DAT5__IPU1_DISP0_DATA05),
 115        IOMUX_PADS(PAD_DISP0_DAT6__IPU1_DISP0_DATA06),
 116        IOMUX_PADS(PAD_DISP0_DAT7__IPU1_DISP0_DATA07),
 117        IOMUX_PADS(PAD_DISP0_DAT8__IPU1_DISP0_DATA08),
 118        IOMUX_PADS(PAD_DISP0_DAT9__IPU1_DISP0_DATA09),
 119        IOMUX_PADS(PAD_DISP0_DAT10__IPU1_DISP0_DATA10),
 120        IOMUX_PADS(PAD_DISP0_DAT11__IPU1_DISP0_DATA11),
 121        IOMUX_PADS(PAD_DISP0_DAT12__IPU1_DISP0_DATA12),
 122        IOMUX_PADS(PAD_DISP0_DAT13__IPU1_DISP0_DATA13),
 123        IOMUX_PADS(PAD_DISP0_DAT14__IPU1_DISP0_DATA14),
 124        IOMUX_PADS(PAD_DISP0_DAT15__IPU1_DISP0_DATA15),
 125        IOMUX_PADS(PAD_DISP0_DAT16__IPU1_DISP0_DATA16),
 126        IOMUX_PADS(PAD_DISP0_DAT17__IPU1_DISP0_DATA17),
 127        IOMUX_PADS(PAD_DISP0_DAT18__IPU1_DISP0_DATA18),
 128        IOMUX_PADS(PAD_DISP0_DAT19__IPU1_DISP0_DATA19),
 129        IOMUX_PADS(PAD_DISP0_DAT20__IPU1_DISP0_DATA20),
 130        IOMUX_PADS(PAD_DISP0_DAT21__IPU1_DISP0_DATA21),
 131        IOMUX_PADS(PAD_DISP0_DAT22__IPU1_DISP0_DATA22),
 132        IOMUX_PADS(PAD_DISP0_DAT23__IPU1_DISP0_DATA23),
 133        IOMUX_PADS(PAD_SD4_DAT2__GPIO2_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL)), /* DISP0_BKLEN */
 134        IOMUX_PADS(PAD_SD4_DAT3__GPIO2_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL)), /* DISP0_VDDEN */
 135};
 136
 137static void do_enable_hdmi(struct display_info_t const *dev)
 138{
 139        imx_enable_hdmi_phy();
 140}
 141
 142static void enable_lvds(struct display_info_t const *dev)
 143{
 144        struct iomuxc *iomux = (struct iomuxc *)
 145                                IOMUXC_BASE_ADDR;
 146
 147        /* set CH0 data width to 24bit (IOMUXC_GPR2:5 0=18bit, 1=24bit) */
 148        u32 reg = readl(&iomux->gpr[2]);
 149        reg |= IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT;
 150        writel(reg, &iomux->gpr[2]);
 151
 152        /* Enable Backlight - use GPIO for Brightness adjustment */
 153        SETUP_IOMUX_PAD(PAD_SD4_DAT1__GPIO2_IO09);
 154        gpio_request(IMX_GPIO_NR(2, 9), "backlight_enable");
 155        gpio_direction_output(IMX_GPIO_NR(2, 9), 1);
 156
 157        gpio_request(IMX_GPIO_NR(2, 8), "brightness");
 158        SETUP_IOMUX_PAD(PAD_SD4_DAT0__GPIO2_IO08);
 159        gpio_direction_output(IMX_GPIO_NR(2, 8), 1);
 160}
 161
 162static void enable_ft5x06_wvga(struct display_info_t const *dev)
 163{
 164        SETUP_IOMUX_PADS(ft5x06_wvga_pads);
 165
 166        gpio_request(IMX_GPIO_NR(2, 10), "parallel_enable");
 167        gpio_request(IMX_GPIO_NR(2, 11), "parallel_brightness");
 168        gpio_direction_output(IMX_GPIO_NR(2, 10), 1);
 169        gpio_direction_output(IMX_GPIO_NR(2, 11), 1);
 170}
 171
 172struct display_info_t const displays[] = {{
 173        .bus    = 1,
 174        .addr   = 0x38,
 175        .pixfmt = IPU_PIX_FMT_RGB24,
 176        .detect = NULL,
 177        .enable = enable_ft5x06_wvga,
 178        .mode   = {
 179                .name           = "FT5x06-WVGA",
 180                .refresh        = 60,
 181                .xres           = 800,
 182                .yres           = 480,
 183                .pixclock       = 30303,
 184                .left_margin    = 45,
 185                .right_margin   = 210,
 186                .upper_margin   = 22,
 187                .lower_margin   = 22,
 188                .hsync_len      = 1,
 189                .vsync_len      = 1,
 190                .sync           = 0,
 191                .vmode          = FB_VMODE_NONINTERLACED
 192} }, {
 193        .bus    = -1,
 194        .addr   = 0,
 195        .pixfmt = IPU_PIX_FMT_RGB24,
 196        .detect = NULL,
 197        .enable = enable_lvds,
 198        .mode   = {
 199                .name           = "hj070na",
 200                .refresh        = 60,
 201                .xres           = 1024,
 202                .yres           = 600,
 203                .pixclock       = 15385,
 204                .left_margin    = 220,
 205                .right_margin   = 40,
 206                .upper_margin   = 21,
 207                .lower_margin   = 7,
 208                .hsync_len      = 60,
 209                .vsync_len      = 10,
 210                .sync           = FB_SYNC_EXT,
 211                .vmode          = FB_VMODE_NONINTERLACED
 212} }, {
 213        .bus    = -1,
 214        .addr   = 0,
 215        .pixfmt = IPU_PIX_FMT_RGB24,
 216        .detect = detect_hdmi,
 217        .enable = do_enable_hdmi,
 218        .mode   = {
 219                .name           = "HDMI",
 220                .refresh        = 60,
 221                .xres           = 1024,
 222                .yres           = 768,
 223                .pixclock       = 15385,
 224                .left_margin    = 220,
 225                .right_margin   = 40,
 226                .upper_margin   = 21,
 227                .lower_margin   = 7,
 228                .hsync_len      = 60,
 229                .vsync_len      = 10,
 230                .sync           = FB_SYNC_EXT,
 231                .vmode          = FB_VMODE_NONINTERLACED
 232} } };
 233size_t display_count = ARRAY_SIZE(displays);
 234
 235static void setup_display(void)
 236{
 237        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 238        struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
 239        int reg;
 240
 241        /* Setup HSYNC, VSYNC, DISP_CLK for debugging purposes */
 242        SETUP_IOMUX_PADS(lvds_pads);
 243        gpio_request(LVDS0_EN, "lvds0_enable");
 244        gpio_request(LVDS0_BL_EN, "lvds0_bl_enable");
 245        gpio_direction_output(LVDS0_EN, 1);
 246        gpio_direction_output(LVDS0_BL_EN, 1);
 247
 248        enable_ipu_clock();
 249        imx_setup_hdmi();
 250
 251        reg = __raw_readl(&mxc_ccm->CCGR3);
 252        reg |=  MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
 253        writel(reg, &mxc_ccm->CCGR3);
 254
 255        /* set LDB0, LDB1 clk select to 011/011 */
 256        reg = readl(&mxc_ccm->cs2cdr);
 257        reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
 258                | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
 259        reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
 260                 | (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
 261        writel(reg, &mxc_ccm->cs2cdr);
 262
 263        reg = readl(&mxc_ccm->cscmr2);
 264        reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
 265        writel(reg, &mxc_ccm->cscmr2);
 266
 267        reg = readl(&mxc_ccm->chsccdr);
 268        reg |= (CHSCCDR_CLK_SEL_LDB_DI0
 269                << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
 270        reg |= (CHSCCDR_CLK_SEL_LDB_DI0
 271                << MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
 272        writel(reg, &mxc_ccm->chsccdr);
 273
 274         reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
 275                | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW
 276                | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
 277                | IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
 278                | IOMUXC_GPR2_DATA_WIDTH_CH1_24BIT
 279                | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
 280                | IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT
 281                | IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0
 282                | IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
 283        writel(reg, &iomux->gpr[2]);
 284        reg = readl(&iomux->gpr[3]);
 285
 286        reg = (reg & ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK
 287                | IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
 288                | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
 289                << IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
 290
 291        writel(reg, &iomux->gpr[3]);
 292}
 293#endif /* CONFIG_VIDEO_IPUV3 */
 294
 295int board_early_init_f(void)
 296{
 297        setup_iomux_uart();
 298
 299#if defined(CONFIG_VIDEO_IPUV3)
 300        setup_display();
 301#endif
 302
 303        return 0;
 304}
 305
 306int board_eth_init(struct bd_info *bis)
 307{
 308        setup_iomux_enet();
 309
 310        return cpu_eth_init(bis);
 311}
 312
 313int board_phy_config(struct phy_device *phydev)
 314{
 315        unsigned short val;
 316
 317        /* To enable AR8035 ouput a 125MHz clk from CLK_25M */
 318        phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
 319        phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
 320        phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
 321
 322        val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
 323        val &= 0xffe7;
 324        val |= 0x18;
 325        phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
 326
 327        /* introduce tx clock delay */
 328        phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
 329        val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
 330        val |= 0x0100;
 331        phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
 332
 333        if (phydev->drv->config)
 334                phydev->drv->config(phydev);
 335
 336        return 0;
 337}
 338
 339int overwrite_console(void)
 340{
 341        return 1;
 342}
 343
 344int board_late_init(void)
 345{
 346        if (is_mx6dq())
 347                env_set("board_rev", "MX6Q");
 348        else
 349                env_set("board_rev", "MX6DL");
 350
 351        return 0;
 352}
 353
 354int board_init(void)
 355{
 356        gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
 357
 358        return 0;
 359}
 360
 361int checkboard(void)
 362{
 363        puts("Board: PICO-IMX6\n");
 364
 365        return 0;
 366}
 367