uboot/board/denx/m28evk/m28evk.c
<<
>>
Prefs
   1/*
   2 * DENX M28 module
   3 *
   4 * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
   5 * on behalf of DENX Software Engineering GmbH
   6 *
   7 * SPDX-License-Identifier:     GPL-2.0+
   8 */
   9
  10#include <common.h>
  11#include <asm/gpio.h>
  12#include <asm/io.h>
  13#include <asm/arch/imx-regs.h>
  14#include <asm/arch/iomux-mx28.h>
  15#include <asm/arch/clock.h>
  16#include <asm/arch/sys_proto.h>
  17#include <linux/mii.h>
  18#include <miiphy.h>
  19#include <netdev.h>
  20#include <errno.h>
  21
  22DECLARE_GLOBAL_DATA_PTR;
  23
  24/*
  25 * Functions
  26 */
  27int board_early_init_f(void)
  28{
  29        /* IO0 clock at 480MHz */
  30        mxs_set_ioclk(MXC_IOCLK0, 480000);
  31        /* IO1 clock at 480MHz */
  32        mxs_set_ioclk(MXC_IOCLK1, 480000);
  33
  34        /* SSP0 clock at 96MHz */
  35        mxs_set_sspclk(MXC_SSPCLK0, 96000, 0);
  36        /* SSP2 clock at 160MHz */
  37        mxs_set_sspclk(MXC_SSPCLK2, 160000, 0);
  38
  39#ifdef  CONFIG_CMD_USB
  40        mxs_iomux_setup_pad(MX28_PAD_SSP2_SS1__USB1_OVERCURRENT);
  41        mxs_iomux_setup_pad(MX28_PAD_AUART3_TX__GPIO_3_13 |
  42                        MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP);
  43        gpio_direction_output(MX28_PAD_AUART3_TX__GPIO_3_13, 0);
  44
  45        mxs_iomux_setup_pad(MX28_PAD_AUART3_RX__GPIO_3_12 |
  46                        MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP);
  47        gpio_direction_output(MX28_PAD_AUART3_RX__GPIO_3_12, 0);
  48#endif
  49
  50        return 0;
  51}
  52
  53int board_init(void)
  54{
  55        /* Adress of boot parameters */
  56        gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
  57
  58        return 0;
  59}
  60
  61int dram_init(void)
  62{
  63        return mxs_dram_init();
  64}
  65
  66#ifdef  CONFIG_CMD_MMC
  67static int m28_mmc_wp(int id)
  68{
  69        if (id != 0) {
  70                printf("MXS MMC: Invalid card selected (card id = %d)\n", id);
  71                return 1;
  72        }
  73
  74        return gpio_get_value(MX28_PAD_AUART2_CTS__GPIO_3_10);
  75}
  76
  77int board_mmc_init(bd_t *bis)
  78{
  79        /* Configure WP as input. */
  80        gpio_direction_input(MX28_PAD_AUART2_CTS__GPIO_3_10);
  81        /* Turn on the power to the card. */
  82        gpio_direction_output(MX28_PAD_PWM3__GPIO_3_28, 0);
  83
  84        return mxsmmc_initialize(bis, 0, m28_mmc_wp, NULL);
  85}
  86#endif
  87
  88#ifdef  CONFIG_CMD_NET
  89
  90#define MII_OPMODE_STRAP_OVERRIDE       0x16
  91#define MII_PHY_CTRL1                   0x1e
  92#define MII_PHY_CTRL2                   0x1f
  93
  94int fecmxc_mii_postcall(int phy)
  95{
  96#if     defined(CONFIG_DENX_M28_V11) || defined(CONFIG_DENX_M28_V10)
  97        /* KZ8031 PHY on old boards. */
  98        const uint32_t freq = 0x0080;
  99#else
 100        /* KZ8021 PHY on new boards. */
 101        const uint32_t freq = 0x0000;
 102#endif
 103
 104        miiphy_write("FEC1", phy, MII_BMCR, 0x9000);
 105        miiphy_write("FEC1", phy, MII_OPMODE_STRAP_OVERRIDE, 0x0202);
 106        if (phy == 3)
 107                miiphy_write("FEC1", 3, MII_PHY_CTRL2, 0x8100 | freq);
 108        return 0;
 109}
 110
 111int board_eth_init(bd_t *bis)
 112{
 113        struct mxs_clkctrl_regs *clkctrl_regs =
 114                (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
 115        struct eth_device *dev;
 116        int ret;
 117
 118        ret = cpu_eth_init(bis);
 119        if (ret)
 120                return ret;
 121
 122        clrsetbits_le32(&clkctrl_regs->hw_clkctrl_enet,
 123                CLKCTRL_ENET_TIME_SEL_MASK | CLKCTRL_ENET_CLK_OUT_EN,
 124                CLKCTRL_ENET_TIME_SEL_RMII_CLK);
 125
 126#if !defined(CONFIG_DENX_M28_V11) && !defined(CONFIG_DENX_M28_V10)
 127        /* Reset the new PHY */
 128        gpio_direction_output(MX28_PAD_AUART2_RTS__GPIO_3_11, 0);
 129        udelay(10000);
 130        gpio_set_value(MX28_PAD_AUART2_RTS__GPIO_3_11, 1);
 131        udelay(10000);
 132#endif
 133
 134        ret = fecmxc_initialize_multi(bis, 0, 0, MXS_ENET0_BASE);
 135        if (ret) {
 136                printf("FEC MXS: Unable to init FEC0\n");
 137                return ret;
 138        }
 139
 140        ret = fecmxc_initialize_multi(bis, 1, 3, MXS_ENET1_BASE);
 141        if (ret) {
 142                printf("FEC MXS: Unable to init FEC1\n");
 143                return ret;
 144        }
 145
 146        dev = eth_get_dev_by_name("FEC0");
 147        if (!dev) {
 148                printf("FEC MXS: Unable to get FEC0 device entry\n");
 149                return -EINVAL;
 150        }
 151
 152        ret = fecmxc_register_mii_postcall(dev, fecmxc_mii_postcall);
 153        if (ret) {
 154                printf("FEC MXS: Unable to register FEC0 mii postcall\n");
 155                return ret;
 156        }
 157
 158        dev = eth_get_dev_by_name("FEC1");
 159        if (!dev) {
 160                printf("FEC MXS: Unable to get FEC1 device entry\n");
 161                return -EINVAL;
 162        }
 163
 164        ret = fecmxc_register_mii_postcall(dev, fecmxc_mii_postcall);
 165        if (ret) {
 166                printf("FEC MXS: Unable to register FEC1 mii postcall\n");
 167                return ret;
 168        }
 169
 170        return ret;
 171}
 172
 173#endif
 174