uboot/board/google/imx8mq_phanbell/spl.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2020 NXP
   4 *
   5 */
   6
   7#include <common.h>
   8#include <hang.h>
   9#include <asm/global_data.h>
  10#include <asm/io.h>
  11#include <errno.h>
  12#include <init.h>
  13#include <log.h>
  14#include <asm/io.h>
  15#include <asm/arch/ddr.h>
  16#include <asm/arch/imx8mq_pins.h>
  17#include <asm/arch/sys_proto.h>
  18#include <asm/arch/clock.h>
  19#include <asm/mach-imx/iomux-v3.h>
  20#include <asm/mach-imx/gpio.h>
  21#include <asm/mach-imx/mxc_i2c.h>
  22#include <asm/sections.h>
  23#include <linux/delay.h>
  24#include <fsl_esdhc_imx.h>
  25#include <mmc.h>
  26#include <spl.h>
  27
  28DECLARE_GLOBAL_DATA_PTR;
  29
  30static void spl_dram_init(void)
  31{
  32        /* ddr init */
  33        ddr_init(&dram_timing);
  34}
  35
  36#define USDHC2_CD_GPIO  IMX_GPIO_NR(2, 12)
  37#define USDHC1_PWR_GPIO IMX_GPIO_NR(2, 10)
  38#define USDHC2_PWR_GPIO IMX_GPIO_NR(2, 19)
  39
  40int board_mmc_getcd(struct mmc *mmc)
  41{
  42        struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
  43        int ret = 0;
  44
  45        switch (cfg->esdhc_base) {
  46        case USDHC1_BASE_ADDR:
  47                ret = 1;
  48                break;
  49        case USDHC2_BASE_ADDR:
  50                ret = !gpio_get_value(USDHC2_CD_GPIO);
  51                return ret;
  52        }
  53
  54        return 1;
  55}
  56
  57#define USDHC_PAD_CTRL  (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE | \
  58                         PAD_CTL_FSEL2)
  59#define USDHC_GPIO_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_DSE1)
  60
  61static iomux_v3_cfg_t const usdhc1_pads[] = {
  62        IMX8MQ_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  63        IMX8MQ_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  64        IMX8MQ_PAD_SD1_DATA0__USDHC1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  65        IMX8MQ_PAD_SD1_DATA1__USDHC1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  66        IMX8MQ_PAD_SD1_DATA2__USDHC1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  67        IMX8MQ_PAD_SD1_DATA3__USDHC1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  68        IMX8MQ_PAD_SD1_DATA4__USDHC1_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  69        IMX8MQ_PAD_SD1_DATA5__USDHC1_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  70        IMX8MQ_PAD_SD1_DATA6__USDHC1_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  71        IMX8MQ_PAD_SD1_DATA7__USDHC1_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  72        IMX8MQ_PAD_SD1_RESET_B__GPIO2_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
  73};
  74
  75static iomux_v3_cfg_t const usdhc2_pads[] = {
  76        IMX8MQ_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
  77        IMX8MQ_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
  78        IMX8MQ_PAD_SD2_DATA0__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
  79        IMX8MQ_PAD_SD2_DATA1__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
  80        IMX8MQ_PAD_SD2_DATA2__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0x16 */
  81        IMX8MQ_PAD_SD2_DATA3__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
  82        IMX8MQ_PAD_SD2_CD_B__GPIO2_IO12 | MUX_PAD_CTRL(USDHC_GPIO_PAD_CTRL),
  83        IMX8MQ_PAD_SD2_RESET_B__GPIO2_IO19 | MUX_PAD_CTRL(USDHC_GPIO_PAD_CTRL),
  84};
  85
  86static struct fsl_esdhc_cfg usdhc_cfg[2] = {
  87        {USDHC1_BASE_ADDR},
  88        {USDHC2_BASE_ADDR},
  89};
  90
  91int board_mmc_init(struct bd_info *bis)
  92{
  93        int i, ret;
  94        /*
  95         * According to the board_mmc_init() the following map is done:
  96         * (U-Boot device node)    (Physical Port)
  97         * mmc0                    USDHC1
  98         * mmc1                    USDHC2
  99         */
 100        for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
 101                switch (i) {
 102                case 0:
 103                        init_clk_usdhc(0);
 104                        usdhc_cfg[0].sdhc_clk = mxc_get_clock(USDHC1_CLK_ROOT);
 105                        usdhc_cfg[0].max_bus_width = 8;
 106                        imx_iomux_v3_setup_multiple_pads(usdhc1_pads,
 107                                                         ARRAY_SIZE(usdhc1_pads));
 108                        gpio_request(USDHC1_PWR_GPIO, "usdhc1_reset");
 109                        gpio_direction_output(USDHC1_PWR_GPIO, 0);
 110                        udelay(500);
 111                        gpio_direction_output(USDHC1_PWR_GPIO, 1);
 112                        break;
 113                case 1:
 114                        init_clk_usdhc(1);
 115                        usdhc_cfg[1].sdhc_clk = mxc_get_clock(USDHC2_CLK_ROOT);
 116                        usdhc_cfg[1].max_bus_width = 4;
 117                        imx_iomux_v3_setup_multiple_pads(usdhc2_pads,
 118                                                         ARRAY_SIZE(usdhc2_pads));
 119                        gpio_request(USDHC2_PWR_GPIO, "usdhc2_reset");
 120                        gpio_direction_output(USDHC2_PWR_GPIO, 0);
 121                        udelay(500);
 122                        gpio_direction_output(USDHC2_PWR_GPIO, 1);
 123                        break;
 124                default:
 125                        printf("Warning: you configured more USDHC controllers(%d) than supported by the board\n", i + 1);
 126                        return -EINVAL;
 127                }
 128
 129                ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
 130                if (ret)
 131                        return ret;
 132        }
 133
 134        return 0;
 135}
 136
 137void spl_board_init(void)
 138{
 139        puts("Normal Boot\n");
 140}
 141
 142#ifdef CONFIG_SPL_LOAD_FIT
 143int board_fit_config_name_match(const char *name)
 144{
 145        /* Just empty function now - can't decide what to choose */
 146        debug("%s: %s\n", __func__, name);
 147
 148        return 0;
 149}
 150#endif
 151
 152void board_init_f(ulong dummy)
 153{
 154        int ret;
 155
 156        /* Clear global data */
 157        memset((void *)gd, 0, sizeof(gd_t));
 158
 159        arch_cpu_init();
 160
 161        init_uart_clk(0);
 162
 163        board_early_init_f();
 164
 165        timer_init();
 166
 167        preloader_console_init();
 168
 169        /* Clear the BSS. */
 170        memset(__bss_start, 0, __bss_end - __bss_start);
 171
 172        ret = spl_init();
 173        if (ret) {
 174                debug("spl_init() failed: %d\n", ret);
 175                hang();
 176        }
 177
 178        enable_tzc380();
 179
 180        /* DDR initialization */
 181        spl_dram_init();
 182
 183        board_init_r(NULL, 0);
 184}
 185