diff options
author | Igor Opaniuk <igor.opaniuk@toradex.com> | 2020-07-21 15:35:29 +0300 |
---|---|---|
committer | Igor Opaniuk <igor.opaniuk@toradex.com> | 2020-07-21 16:02:32 +0300 |
commit | 315a779930375e9f6e3da87cf04835b436bb0938 (patch) | |
tree | 96aa1311de1460078a1c6cf42b622c178a49a542 /board/toradex/verdin-imx8mm/spl.c | |
parent | b5a14619a41595f963d2242755335b09ab89ed33 (diff) |
board: toradex: up-port verdin imx8mm module support
This patch introduces changes on top of existing Verdin iMX8MM support in
the mainline U-Boot v2020.04.
Some patches were already upstreamed, some were squashed and included
into this commit:
78e80d3f ("board: toradex: add verdin imx8mm 2gb wb it v1.0a module support")
a6c18891 ("verdin-imx8mm: lpddr4_timing.c: intial lpddr4 calibration data")
b16da3d6 ("verdin-imx8mm: fix usb_1 device aka peripheral operation")
6451e680 ("verdin-imx8: do not undef configs configured using Kconfig")
d5382436 ("fsl-imx8mm-verdin.dts: remove fsl,rgmii_rxc_dly et. al.")
c24fe844 ("fsl-imx8mm-verdin.dts: fix eth phy power up")
b07ae5f3 ("verdin-imx8mm.c: set eth phy skew")
4eb91e6e ("tdx-cfg-block: adjust verdin naming")
569703d4 ("verdin-imx8mm: sync with EVK board")
8c8b56a5 ("tdx-cfg-block: add proper defines for other Verdin SKUs")
Relates-to: ELB-2771
Signed-off-by: Igor Opaniuk <igor.opaniuk@toradex.com>
Diffstat (limited to 'board/toradex/verdin-imx8mm/spl.c')
-rw-r--r-- | board/toradex/verdin-imx8mm/spl.c | 231 |
1 files changed, 157 insertions, 74 deletions
diff --git a/board/toradex/verdin-imx8mm/spl.c b/board/toradex/verdin-imx8mm/spl.c index 55cde73e19..463378b610 100644 --- a/board/toradex/verdin-imx8mm/spl.c +++ b/board/toradex/verdin-imx8mm/spl.c @@ -4,22 +4,23 @@ */ #include <common.h> +#include <cpu_func.h> +#include <hang.h> +#include <spl.h> +#include <asm/io.h> +#include <asm/mach-imx/iomux-v3.h> #include <asm/arch/clock.h> -#include <asm/arch/ddr.h> #include <asm/arch/imx8mm_pins.h> #include <asm/arch/sys_proto.h> -#include <asm/io.h> #include <asm/mach-imx/boot_mode.h> -#include <asm/mach-imx/iomux-v3.h> -#include <cpu_func.h> -#include <dm/device.h> -#include <dm/device-internal.h> -#include <dm/uclass.h> -#include <dm/uclass-internal.h> -#include <hang.h> -#include <power/bd71837.h> +#include <asm/arch/ddr.h> + #include <power/pmic.h> -#include <spl.h> +#include <power/bd71837.h> +#include <asm/mach-imx/gpio.h> +#include <asm/mach-imx/mxc_i2c.h> +#include <fsl_esdhc_imx.h> +#include <mmc.h> DECLARE_GLOBAL_DATA_PTR; @@ -46,93 +47,183 @@ void spl_dram_init(void) ddr_init(&dram_timing); } -void spl_board_init(void) -{ - /* Serial download mode */ - if (is_usb_boot()) { - puts("Back to ROM, SDP\n"); - restore_boot_params(); - } - puts("Normal Boot\n"); -} - -#ifdef CONFIG_SPL_LOAD_FIT -int board_fit_config_name_match(const char *name) -{ - /* Just empty function now - can't decide what to choose */ - debug("%s: %s\n", __func__, name); - - return 0; -} -#endif +#define I2C_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE | PAD_CTL_PE) +#define PC MUX_PAD_CTRL(I2C_PAD_CTRL) +struct i2c_pads_info i2c_pad_info1 = { + .scl = { + .i2c_mode = IMX8MM_PAD_I2C1_SCL_I2C1_SCL | PC, + .gpio_mode = IMX8MM_PAD_I2C1_SCL_GPIO5_IO14 | PC, + .gp = IMX_GPIO_NR(5, 14), + }, + .sda = { + .i2c_mode = IMX8MM_PAD_I2C1_SDA_I2C1_SDA | PC, + .gpio_mode = IMX8MM_PAD_I2C1_SDA_GPIO5_IO15 | PC, + .gp = IMX_GPIO_NR(5, 15), + }, +}; -#define UART_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_PE | PAD_CTL_DSE4) -#define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_ODE | PAD_CTL_PUE | PAD_CTL_PE) +#define USDHC2_CD_GPIO IMX_GPIO_NR(2, 12) +#define USDHC2_PWR_GPIO IMX_GPIO_NR(3, 5) + +#define USDHC_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE | PAD_CTL_PE | \ + PAD_CTL_FSEL2) +#define USDHC_GPIO_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_DSE1) + +static iomux_v3_cfg_t const usdhc1_pads[] = { + IMX8MM_PAD_SD1_CLK_USDHC1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MM_PAD_SD1_CMD_USDHC1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MM_PAD_SD1_DATA0_USDHC1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MM_PAD_SD1_DATA1_USDHC1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MM_PAD_SD1_DATA2_USDHC1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MM_PAD_SD1_DATA3_USDHC1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MM_PAD_SD1_DATA4_USDHC1_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MM_PAD_SD1_DATA5_USDHC1_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MM_PAD_SD1_DATA6_USDHC1_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MM_PAD_SD1_DATA7_USDHC1_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MM_PAD_SD1_STROBE_USDHC1_STROBE | MUX_PAD_CTRL(USDHC_PAD_CTRL), +}; -/* Verdin UART_3, Console/Debug UART */ -static iomux_v3_cfg_t const uart_pads[] = { - IMX8MM_PAD_SAI2_RXFS_UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL), - IMX8MM_PAD_SAI2_RXC_UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL), +static iomux_v3_cfg_t const usdhc2_pads[] = { + IMX8MM_PAD_SD2_CLK_USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MM_PAD_SD2_CMD_USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MM_PAD_SD2_DATA0_USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MM_PAD_SD2_DATA1_USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MM_PAD_SD2_DATA2_USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MM_PAD_SD2_DATA3_USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MM_PAD_SD2_RESET_B_GPIO2_IO19 | MUX_PAD_CTRL(USDHC_GPIO_PAD_CTRL), + IMX8MM_PAD_SD2_CD_B_GPIO2_IO12 | MUX_PAD_CTRL(USDHC_GPIO_PAD_CTRL), + IMX8MM_PAD_NAND_CLE_GPIO3_IO5 | MUX_PAD_CTRL(USDHC_GPIO_PAD_CTRL), }; -static iomux_v3_cfg_t const wdog_pads[] = { - IMX8MM_PAD_GPIO1_IO02_WDOG1_WDOG_B | MUX_PAD_CTRL(WDOG_PAD_CTRL), +static struct fsl_esdhc_cfg usdhc_cfg[2] = { + /* esdhc_base, sdhc_clk, max_bus_width */ + {USDHC1_BASE_ADDR, 0, 8}, + {USDHC2_BASE_ADDR, 0, 4}, }; -int board_early_init_f(void) +int board_mmc_init(bd_t *bis) { - struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; - - imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads)); + int i, ret; + /* + * According to the board_mmc_init() the following map is done: + * (U-Boot device node) (Physical Port) + * mmc0 USDHC1 (eMMC) + * mmc1 USDHC2 (SD card) + */ + for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { + switch (i) { + case 0: + usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + imx_iomux_v3_setup_multiple_pads( + usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); + break; + case 1: + usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); + imx_iomux_v3_setup_multiple_pads( + usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); + gpio_request(USDHC2_PWR_GPIO, "SD_1_PWR_EN"); + gpio_direction_output(USDHC2_PWR_GPIO, 1); + break; + default: + printf("Warning: you configured more USDHC controllers" + "(%d) than supported by the board\n", i + 1); + return -EINVAL; + } + + ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); + if (ret) + return ret; + } - set_wdog_reset(wdog); + return 0; +} - imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads)); +int board_mmc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = 0; + + switch (cfg->esdhc_base) { + case USDHC1_BASE_ADDR: + ret = 1; /* eMMC */ + break; + case USDHC2_BASE_ADDR: + gpio_request(USDHC2_CD_GPIO, "SD_1_CD#"); + gpio_direction_input(USDHC2_CD_GPIO); + ret = !gpio_get_value(USDHC2_CD_GPIO); + return ret; + } - return 0; + return 1; } +#ifdef CONFIG_POWER +#define I2C_PMIC 0 int power_init_board(void) { - struct udevice *dev; + struct pmic *p; int ret; - ret = pmic_get("pmic@4b", &dev); - if (ret == -ENODEV) { - puts("No pmic\n"); - return 0; - } - if (ret != 0) - return ret; + ret = power_bd71837_init(I2C_PMIC); + if (ret) + printf("power init failed"); + + p = pmic_get("BD71837"); + pmic_probe(p); /* decrease RESET key long push time from the default 10s to 10ms */ - pmic_reg_write(dev, BD71837_PWRONCONFIG1, 0x0); + pmic_reg_write(p, BD71837_PWRONCONFIG1, 0x0); /* unlock the PMIC regs */ - pmic_reg_write(dev, BD71837_REGLOCK, 0x1); + pmic_reg_write(p, BD71837_REGLOCK, 0x1); /* increase VDD_SOC to typical value 0.85v before first DRAM access */ - pmic_reg_write(dev, BD71837_BUCK1_VOLT_RUN, 0x0f); + pmic_reg_write(p, BD71837_BUCK1_VOLT_RUN, 0x0f); /* increase VDD_DRAM to 0.975v for 3Ghz DDR */ - pmic_reg_write(dev, BD71837_BUCK5_VOLT, 0x83); + pmic_reg_write(p, BD71837_BUCK5_VOLT, 0x83); #ifndef CONFIG_IMX8M_LPDDR4 /* increase NVCC_DRAM_1V2 to 1.2v for DDR4 */ - pmic_reg_write(dev, BD71837_BUCK8_VOLT, 0x28); + pmic_reg_write(p, BD71837_BUCK8_VOLT, 0x28); #endif /* lock the PMIC regs */ - pmic_reg_write(dev, BD71837_REGLOCK, 0x11); + pmic_reg_write(p, BD71837_REGLOCK, 0x11); return 0; } +#endif + +void spl_board_init(void) +{ +#ifndef CONFIG_SPL_USB_SDP_SUPPORT + /* Serial download mode */ + if (is_usb_boot()) { + puts("Back to ROM, SDP\n"); + restore_boot_params(); + } +#endif + puts("Normal Boot\n"); +} + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + /* Just empty function now - can't decide what to choose */ + debug("%s: %s\n", __func__, name); + + return 0; +} +#endif void board_init_f(ulong dummy) { - struct udevice *dev; int ret; + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + arch_cpu_init(); init_uart_clk(0); @@ -143,25 +234,17 @@ void board_init_f(ulong dummy) preloader_console_init(); - /* Clear the BSS. */ - memset(__bss_start, 0, __bss_end - __bss_start); - - ret = spl_early_init(); + ret = spl_init(); if (ret) { - debug("spl_early_init() failed: %d\n", ret); - hang(); - } - - ret = uclass_get_device_by_name(UCLASS_CLK, - "clock-controller@30380000", - &dev); - if (ret < 0) { - printf("Failed to find clock node. Check device tree\n"); + debug("spl_init() failed: %d\n", ret); hang(); } enable_tzc380(); + /* Adjust pmic voltage to 1.0V for 800M */ + setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1); + power_init_board(); /* DDR initialization */ @@ -172,7 +255,7 @@ void board_init_f(ulong dummy) int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - puts("resetting ...\n"); + puts ("resetting ...\n"); reset_cpu(WDOG1_BASE_ADDR); |