uboot/board/grinn/liteboard/board.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
   4 * Copyright (C) 2016 Grinn
   5 */
   6
   7#include <command.h>
   8#include <init.h>
   9#include <asm/arch/clock.h>
  10#include <asm/arch/iomux.h>
  11#include <asm/arch/imx-regs.h>
  12#include <asm/arch/crm_regs.h>
  13#include <asm/arch/litesom.h>
  14#include <asm/arch/mx6ul_pins.h>
  15#include <asm/arch/mx6-pins.h>
  16#include <asm/arch/sys_proto.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/io.h>
  21#include <common.h>
  22#include <env.h>
  23#include <fsl_esdhc_imx.h>
  24#include <linux/sizes.h>
  25#include <linux/fb.h>
  26#include <miiphy.h>
  27#include <mmc.h>
  28#include <netdev.h>
  29#include <spl.h>
  30
  31DECLARE_GLOBAL_DATA_PTR;
  32
  33#define UART_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |             \
  34        PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |               \
  35        PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
  36
  37#define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |             \
  38        PAD_CTL_PUS_22K_UP  | PAD_CTL_SPEED_LOW |               \
  39        PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
  40
  41#define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE |     \
  42        PAD_CTL_SPEED_HIGH   |                                   \
  43        PAD_CTL_DSE_48ohm   | PAD_CTL_SRE_FAST)
  44
  45#define MDIO_PAD_CTRL  (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE |     \
  46        PAD_CTL_DSE_48ohm   | PAD_CTL_SRE_FAST | PAD_CTL_ODE)
  47
  48#define ENET_CLK_PAD_CTRL  (PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST)
  49
  50static iomux_v3_cfg_t const uart1_pads[] = {
  51        MX6_PAD_UART1_TX_DATA__UART1_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
  52        MX6_PAD_UART1_RX_DATA__UART1_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
  53};
  54
  55static iomux_v3_cfg_t const sd_pads[] = {
  56        MX6_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  57        MX6_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  58        MX6_PAD_SD1_DATA0__USDHC1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  59        MX6_PAD_SD1_DATA1__USDHC1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  60        MX6_PAD_SD1_DATA2__USDHC1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  61        MX6_PAD_SD1_DATA3__USDHC1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  62
  63        /* CD */
  64        MX6_PAD_UART1_RTS_B__GPIO1_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
  65};
  66
  67static void setup_iomux_uart(void)
  68{
  69        imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
  70}
  71
  72#ifdef CONFIG_FSL_ESDHC_IMX
  73static struct fsl_esdhc_cfg sd_cfg = {USDHC1_BASE_ADDR, 0, 4};
  74
  75#define SD_CD_GPIO      IMX_GPIO_NR(1, 19)
  76
  77static int mmc_get_env_devno(void)
  78{
  79        u32 soc_sbmr = readl(SRC_BASE_ADDR + 0x4);
  80        int dev_no;
  81        u32 bootsel;
  82
  83        bootsel = (soc_sbmr & 0x000000FF) >> 6;
  84
  85        /* If not boot from sd/mmc, use default value */
  86        if (bootsel != 1)
  87                return CONFIG_SYS_MMC_ENV_DEV;
  88
  89        /* BOOT_CFG2[3] and BOOT_CFG2[4] */
  90        dev_no = (soc_sbmr & 0x00001800) >> 11;
  91
  92        return dev_no;
  93}
  94
  95int board_mmc_getcd(struct mmc *mmc)
  96{
  97        struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
  98        int ret = 0;
  99
 100        switch (cfg->esdhc_base) {
 101        case USDHC1_BASE_ADDR:
 102                ret = !gpio_get_value(SD_CD_GPIO);
 103                break;
 104        case USDHC2_BASE_ADDR:
 105                ret = 1;
 106                break;
 107        }
 108
 109        return ret;
 110}
 111
 112int board_mmc_init(bd_t *bis)
 113{
 114        int ret;
 115
 116        /* SD */
 117        imx_iomux_v3_setup_multiple_pads(sd_pads, ARRAY_SIZE(sd_pads));
 118        gpio_direction_input(SD_CD_GPIO);
 119        sd_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
 120
 121        ret = fsl_esdhc_initialize(bis, &sd_cfg);
 122        if (ret) {
 123                printf("Warning: failed to initialize mmc dev 0 (SD)\n");
 124                return ret;
 125        }
 126
 127        return litesom_mmc_init(bis);
 128}
 129
 130static int check_mmc_autodetect(void)
 131{
 132        char *autodetect_str = env_get("mmcautodetect");
 133
 134        if ((autodetect_str != NULL) &&
 135            (strcmp(autodetect_str, "yes") == 0)) {
 136                return 1;
 137        }
 138
 139        return 0;
 140}
 141
 142void board_late_mmc_init(void)
 143{
 144        char cmd[32];
 145        char mmcblk[32];
 146        u32 dev_no = mmc_get_env_devno();
 147
 148        if (!check_mmc_autodetect())
 149                return;
 150
 151        env_set_ulong("mmcdev", dev_no);
 152
 153        /* Set mmcblk env */
 154        sprintf(mmcblk, "/dev/mmcblk%dp2 rootwait rw",
 155                dev_no);
 156        env_set("mmcroot", mmcblk);
 157
 158        sprintf(cmd, "mmc dev %d", dev_no);
 159        run_command(cmd, 0);
 160}
 161#endif
 162
 163#ifdef CONFIG_FEC_MXC
 164static int setup_fec(void)
 165{
 166        struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
 167        int ret;
 168
 169        /* Use 50M anatop loopback REF_CLK1 for ENET1, clear gpr1[13],
 170           set gpr1[17]*/
 171        clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC1_MASK,
 172                        IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK);
 173
 174        ret = enable_fec_anatop_clock(0, ENET_50MHZ);
 175        if (ret)
 176                return ret;
 177
 178        enable_enet_clk(1);
 179
 180        return 0;
 181}
 182#endif
 183
 184int board_early_init_f(void)
 185{
 186        setup_iomux_uart();
 187
 188        return 0;
 189}
 190
 191int board_init(void)
 192{
 193        /* Address of boot parameters */
 194        gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
 195
 196#ifdef  CONFIG_FEC_MXC
 197        setup_fec();
 198#endif
 199
 200        return 0;
 201}
 202
 203#ifdef CONFIG_CMD_BMODE
 204static const struct boot_mode board_boot_modes[] = {
 205        /* 4 bit bus width */
 206        {"sd",   MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)},
 207        {"emmc", MAKE_CFGVAL(0x60, 0x48, 0x00, 0x00)},
 208        {NULL,   0},
 209};
 210#endif
 211
 212int board_late_init(void)
 213{
 214#ifdef CONFIG_CMD_BMODE
 215        add_board_boot_modes(board_boot_modes);
 216#endif
 217
 218#ifdef CONFIG_ENV_IS_IN_MMC
 219        board_late_mmc_init();
 220#endif
 221
 222        return 0;
 223}
 224
 225int checkboard(void)
 226{
 227        puts("Board: Grinn liteBoard\n");
 228
 229        return 0;
 230}
 231
 232#ifdef CONFIG_SPL_BUILD
 233void board_boot_order(u32 *spl_boot_list)
 234{
 235        struct src *psrc = (struct src *)SRC_BASE_ADDR;
 236        unsigned gpr10_boot = readl(&psrc->gpr10) & (1 << 28);
 237        unsigned reg = gpr10_boot ? readl(&psrc->gpr9) : readl(&psrc->sbmr1);
 238        unsigned port = (reg >> 11) & 0x1;
 239
 240        if (port == 0) {
 241                spl_boot_list[0] = BOOT_DEVICE_MMC1;
 242                spl_boot_list[1] = BOOT_DEVICE_MMC2;
 243        } else {
 244                spl_boot_list[0] = BOOT_DEVICE_MMC2;
 245                spl_boot_list[1] = BOOT_DEVICE_MMC1;
 246        }
 247}
 248
 249void board_init_f(ulong dummy)
 250{
 251        litesom_init_f();
 252}
 253#endif
 254