summaryrefslogtreecommitdiff
path: root/board/toradex/verdin-imx8mm/spl.c
diff options
context:
space:
mode:
authorIgor Opaniuk <igor.opaniuk@toradex.com>2020-07-21 15:35:29 +0300
committerIgor Opaniuk <igor.opaniuk@toradex.com>2020-07-21 16:02:32 +0300
commit315a779930375e9f6e3da87cf04835b436bb0938 (patch)
tree96aa1311de1460078a1c6cf42b622c178a49a542 /board/toradex/verdin-imx8mm/spl.c
parentb5a14619a41595f963d2242755335b09ab89ed33 (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.c231
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);