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