uboot/board/freescale/mx6qarm2/mx6qarm2.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
   4 */
   5
   6#include <common.h>
   7#include <init.h>
   8#include <net.h>
   9#include <asm/io.h>
  10#include <asm/arch/imx-regs.h>
  11#include <asm/arch/mx6-pins.h>
  12#include <asm/arch/clock.h>
  13#include <linux/errno.h>
  14#include <asm/gpio.h>
  15#include <asm/mach-imx/iomux-v3.h>
  16#include <mmc.h>
  17#include <fsl_esdhc_imx.h>
  18#include <miiphy.h>
  19#include <netdev.h>
  20#include <usb.h>
  21
  22DECLARE_GLOBAL_DATA_PTR;
  23
  24#define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                   \
  25        PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |                 \
  26        PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
  27
  28#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP |                    \
  29        PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm |                 \
  30        PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
  31
  32#define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                   \
  33        PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
  34
  35int dram_init(void)
  36{
  37#if defined(CONFIG_MX6DL) && !defined(CONFIG_MX6DL_LPDDR2) && \
  38        defined(CONFIG_DDR_32BIT)
  39        gd->ram_size = ((phys_size_t)CONFIG_DDR_MB * 1024 * 1024) / 2;
  40#else
  41        gd->ram_size = (phys_size_t)CONFIG_DDR_MB * 1024 * 1024;
  42#endif
  43
  44        return 0;
  45}
  46
  47iomux_v3_cfg_t const uart4_pads[] = {
  48        MX6_PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  49        MX6_PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  50};
  51
  52iomux_v3_cfg_t const usdhc3_pads[] = {
  53        MX6_PAD_SD3_CLK__SD3_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  54        MX6_PAD_SD3_CMD__SD3_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  55        MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  56        MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  57        MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  58        MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  59        MX6_PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  60        MX6_PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  61        MX6_PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  62        MX6_PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  63        MX6_PAD_NANDF_CS0__GPIO6_IO11  | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
  64};
  65
  66iomux_v3_cfg_t const usdhc4_pads[] = {
  67        MX6_PAD_SD4_CLK__SD4_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  68        MX6_PAD_SD4_CMD__SD4_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  69        MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  70        MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  71        MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  72        MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  73        MX6_PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  74        MX6_PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  75        MX6_PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  76        MX6_PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  77};
  78
  79iomux_v3_cfg_t const enet_pads[] = {
  80        MX6_PAD_KEY_COL1__ENET_MDIO        | MUX_PAD_CTRL(ENET_PAD_CTRL),
  81        MX6_PAD_KEY_COL2__ENET_MDC         | MUX_PAD_CTRL(ENET_PAD_CTRL),
  82        MX6_PAD_RGMII_TXC__RGMII_TXC  | MUX_PAD_CTRL(ENET_PAD_CTRL),
  83        MX6_PAD_RGMII_TD0__RGMII_TD0  | MUX_PAD_CTRL(ENET_PAD_CTRL),
  84        MX6_PAD_RGMII_TD1__RGMII_TD1  | MUX_PAD_CTRL(ENET_PAD_CTRL),
  85        MX6_PAD_RGMII_TD2__RGMII_TD2  | MUX_PAD_CTRL(ENET_PAD_CTRL),
  86        MX6_PAD_RGMII_TD3__RGMII_TD3  | MUX_PAD_CTRL(ENET_PAD_CTRL),
  87        MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
  88        MX6_PAD_ENET_REF_CLK__ENET_TX_CLK  | MUX_PAD_CTRL(ENET_PAD_CTRL),
  89        MX6_PAD_RGMII_RXC__RGMII_RXC  | MUX_PAD_CTRL(ENET_PAD_CTRL),
  90        MX6_PAD_RGMII_RD0__RGMII_RD0  | MUX_PAD_CTRL(ENET_PAD_CTRL),
  91        MX6_PAD_RGMII_RD1__RGMII_RD1  | MUX_PAD_CTRL(ENET_PAD_CTRL),
  92        MX6_PAD_RGMII_RD2__RGMII_RD2  | MUX_PAD_CTRL(ENET_PAD_CTRL),
  93        MX6_PAD_RGMII_RD3__RGMII_RD3  | MUX_PAD_CTRL(ENET_PAD_CTRL),
  94        MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
  95};
  96
  97
  98static void setup_iomux_uart(void)
  99{
 100        imx_iomux_v3_setup_multiple_pads(uart4_pads, ARRAY_SIZE(uart4_pads));
 101}
 102
 103static void setup_iomux_enet(void)
 104{
 105        imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
 106}
 107
 108#ifdef CONFIG_FSL_ESDHC_IMX
 109struct fsl_esdhc_cfg usdhc_cfg[2] = {
 110        {USDHC3_BASE_ADDR},
 111        {USDHC4_BASE_ADDR},
 112};
 113
 114int board_mmc_get_env_dev(int devno)
 115{
 116        return devno - 2;
 117}
 118
 119int board_mmc_getcd(struct mmc *mmc)
 120{
 121        struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
 122        int ret;
 123
 124        if (cfg->esdhc_base == USDHC3_BASE_ADDR) {
 125                gpio_direction_input(IMX_GPIO_NR(6, 11));
 126                ret = !gpio_get_value(IMX_GPIO_NR(6, 11));
 127        } else /* Don't have the CD GPIO pin on board */
 128                ret = 1;
 129
 130        return ret;
 131}
 132
 133int board_mmc_init(bd_t *bis)
 134{
 135        int ret;
 136        u32 index = 0;
 137
 138        usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
 139        usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
 140
 141        for (index = 0; index < CONFIG_SYS_FSL_USDHC_NUM; ++index) {
 142                switch (index) {
 143                case 0:
 144                        imx_iomux_v3_setup_multiple_pads(
 145                                usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
 146                        break;
 147                case 1:
 148                        imx_iomux_v3_setup_multiple_pads(
 149                                usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
 150                        break;
 151                default:
 152                        printf("Warning: you configured more USDHC controllers"
 153                                "(%d) then supported by the board (%d)\n",
 154                                index + 1, CONFIG_SYS_FSL_USDHC_NUM);
 155                        return -EINVAL;
 156                }
 157
 158                ret = fsl_esdhc_initialize(bis, &usdhc_cfg[index]);
 159                if (ret)
 160                        return ret;
 161        }
 162
 163        return 0;
 164}
 165#endif
 166
 167#define MII_MMD_ACCESS_CTRL_REG         0xd
 168#define MII_MMD_ACCESS_ADDR_DATA_REG    0xe
 169#define MII_DBG_PORT_REG                0x1d
 170#define MII_DBG_PORT2_REG               0x1e
 171
 172int fecmxc_mii_postcall(int phy)
 173{
 174        unsigned short val;
 175
 176        /*
 177         * Due to the i.MX6Q Armadillo2 board HW design,there is
 178         * no 125Mhz clock input from SOC. In order to use RGMII,
 179         * We need enable AR8031 ouput a 125MHz clk from CLK_25M
 180         */
 181        miiphy_write("FEC", phy, MII_MMD_ACCESS_CTRL_REG, 0x7);
 182        miiphy_write("FEC", phy, MII_MMD_ACCESS_ADDR_DATA_REG, 0x8016);
 183        miiphy_write("FEC", phy, MII_MMD_ACCESS_CTRL_REG, 0x4007);
 184        miiphy_read("FEC", phy, MII_MMD_ACCESS_ADDR_DATA_REG, &val);
 185        val &= 0xffe3;
 186        val |= 0x18;
 187        miiphy_write("FEC", phy, MII_MMD_ACCESS_ADDR_DATA_REG, val);
 188
 189        /* For the RGMII phy, we need enable tx clock delay */
 190        miiphy_write("FEC", phy, MII_DBG_PORT_REG, 0x5);
 191        miiphy_read("FEC", phy, MII_DBG_PORT2_REG, &val);
 192        val |= 0x0100;
 193        miiphy_write("FEC", phy, MII_DBG_PORT2_REG, val);
 194
 195        miiphy_write("FEC", phy, MII_BMCR, 0xa100);
 196
 197        return 0;
 198}
 199
 200int board_eth_init(bd_t *bis)
 201{
 202        struct eth_device *dev;
 203        int ret = cpu_eth_init(bis);
 204
 205        if (ret)
 206                return ret;
 207
 208        dev = eth_get_dev_by_name("FEC");
 209        if (!dev) {
 210                printf("FEC MXC: Unable to get FEC device entry\n");
 211                return -EINVAL;
 212        }
 213
 214        ret = fecmxc_register_mii_postcall(dev, fecmxc_mii_postcall);
 215        if (ret) {
 216                printf("FEC MXC: Unable to register FEC mii postcall\n");
 217                return ret;
 218        }
 219
 220        return 0;
 221}
 222
 223#ifdef CONFIG_USB_EHCI_MX6
 224#define USB_OTHERREGS_OFFSET    0x800
 225#define UCTRL_PWR_POL           (1 << 9)
 226
 227static iomux_v3_cfg_t const usb_otg_pads[] = {
 228        MX6_PAD_EIM_D22__USB_OTG_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
 229        MX6_PAD_GPIO_1__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
 230};
 231
 232static void setup_usb(void)
 233{
 234        imx_iomux_v3_setup_multiple_pads(usb_otg_pads,
 235                                         ARRAY_SIZE(usb_otg_pads));
 236
 237        /*
 238         * set daisy chain for otg_pin_id on 6q.
 239         * for 6dl, this bit is reserved
 240         */
 241        imx_iomux_set_gpr_register(1, 13, 1, 1);
 242}
 243
 244int board_ehci_hcd_init(int port)
 245{
 246        u32 *usbnc_usb_ctrl;
 247
 248        if (port > 0)
 249                return -EINVAL;
 250
 251        usbnc_usb_ctrl = (u32 *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET +
 252                                 port * 4);
 253
 254        setbits_le32(usbnc_usb_ctrl, UCTRL_PWR_POL);
 255
 256        return 0;
 257}
 258#endif
 259
 260int board_early_init_f(void)
 261{
 262        setup_iomux_uart();
 263        setup_iomux_enet();
 264
 265        return 0;
 266}
 267
 268int board_init(void)
 269{
 270        /* address of boot parameters */
 271        gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
 272
 273#ifdef CONFIG_USB_EHCI_MX6
 274        setup_usb();
 275#endif
 276
 277        return 0;
 278}
 279
 280int checkboard(void)
 281{
 282#ifdef CONFIG_MX6DL
 283        puts("Board: MX6DL-Armadillo2\n");
 284#else
 285        puts("Board: MX6Q-Armadillo2\n");
 286#endif
 287
 288        return 0;
 289}
 290