summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/dts/Makefile3
-rw-r--r--arch/arm/dts/fsl-imx8mm-verdin.dts877
-rw-r--r--arch/arm/mach-imx/imx8m/Kconfig7
-rw-r--r--board/toradex/verdin-imx8mm/Kconfig30
-rw-r--r--board/toradex/verdin-imx8mm/MAINTAINERS8
-rw-r--r--board/toradex/verdin-imx8mm/Makefile12
-rw-r--r--board/toradex/verdin-imx8mm/spl.c231
-rw-r--r--board/toradex/verdin-imx8mm/verdin-imx8mm.c494
-rw-r--r--configs/verdin-imx8mm_defconfig71
-rw-r--r--include/configs/verdin-imx8mm.h230
10 files changed, 1962 insertions, 1 deletions
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 119d33e55e..69950d46b8 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -468,7 +468,8 @@ dtb-$(CONFIG_ARCH_IMX8M) += fsl-imx8mq-evk.dtb \
fsl-imx8mm-ddr3l-val.dtb \
fsl-imx8mm-ddr4-evk.dtb \
fsl-imx8mm-ddr4-val.dtb \
- fsl-imx8mm-evk.dtb
+ fsl-imx8mm-evk.dtb \
+ fsl-imx8mm-verdin.dtb
dtb-$(CONFIG_ARCH_IMX8) += fsl-imx8dx-ddr3-arm2.dtb \
fsl-imx8qm-ddr4-arm2.dtb \
diff --git a/arch/arm/dts/fsl-imx8mm-verdin.dts b/arch/arm/dts/fsl-imx8mm-verdin.dts
new file mode 100644
index 0000000000..f3cfd3e61a
--- /dev/null
+++ b/arch/arm/dts/fsl-imx8mm-verdin.dts
@@ -0,0 +1,877 @@
+// SPDX-License-Identifier: GPL-2.0+ OR X11
+/*
+ * Copyright 2019 Toradex
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8mm.dtsi"
+
+/ {
+ model = "Toradex Verdin iMX8MM";
+ compatible = "toradex,verdin-imx8mm", "fsl,imx8mm";
+
+ chosen {
+ bootargs = "console=ttymxc0,115200 earlycon=ec_imx6q,0x30860000,115200";
+ stdout-path = &uart1;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_ethphy: regulator-ethphy {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_eth>;
+ regulator-name = "V3.3_ETH";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 20 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_usdhc2_vmmc: regulator-usdhc2 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2_pwr_en>;
+ regulator-name = "V3.3_SD";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 5 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <2000>;
+ enable-active-high;
+ };
+
+ reg_usb_otg1_vbus: regulator-usb-otg1 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_usb1_en>;
+ regulator-name = "usb_otg1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ /* Verdin USB1_EN */
+ gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_usb_otg2_vbus: regulator-usb-otg2 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_usb2_en>;
+ regulator-name = "usb_otg2_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ /* Verdin USB2_EN */
+ gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "imx8mm-wm8904";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,bitclock-master = <&dailink_master>;
+ simple-audio-card,frame-master = <&dailink_master>;
+ /*simple-audio-card,mclk-fs = <1>;*/
+
+ simple-audio-card,cpu {
+ sound-dai = <&sai2>;
+ };
+
+ dailink_master: simple-audio-card,codec {
+ sound-dai = <&wm8904_1a>;
+// clocks = <&clk IMX8QXP_AUD_MCLKOUT0>;
+ };
+ };
+
+};
+
+&A53_0 {
+ arm-supply = <&buck2_reg>;
+};
+
+&clk {
+ assigned-clocks = <&clk IMX8MM_AUDIO_PLL1>, <&clk IMX8MM_AUDIO_PLL2>;
+ assigned-clock-rates = <786432000>, <722534400>;
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ phy-handle = <&ethphy0>;
+ phy-mode = "rgmii";
+ phy-supply = <&reg_ethphy>;
+ fsl,magic-packet;
+ fsl,rgmii_rxc_dly;
+ fsl,rgmii_txc_dly;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@7 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ interrupt-parent = <&gpio1>;
+ interrupts = <10 IRQ_TYPE_LEVEL_LOW>;
+ reg = <7>;
+ micrel,led-mode = <0>;
+ };
+ };
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic: bd71837@4b {
+ reg = <0x4b>;
+ compatible = "rohm,bd71840", "rohm,bd71837";
+ /* PMIC BD71837 PMIC_nINT GPIO1_IO3 */
+ pinctrl-0 = <&pinctrl_pmic>;
+ gpio_intr = <&gpio1 3 GPIO_ACTIVE_LOW>;
+
+ gpo {
+ rohm,drv = <0x0C>; /* 0b0000_1100 all gpos with cmos output mode */
+ };
+
+ regulators {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bd71837,pmic-buck2-uses-i2c-dvs;
+ bd71837,pmic-buck2-dvs-voltage = <1000000>, <900000>, <0>; /* VDD_ARM: Run-Idle */
+
+ buck1_reg: regulator@0 {
+ reg = <0>;
+ regulator-compatible = "buck1";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <1250>;
+ };
+
+ buck2_reg: regulator@1 {
+ reg = <1>;
+ regulator-compatible = "buck2";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <1250>;
+ };
+
+ buck5_reg: regulator@4 {
+ reg = <4>;
+ regulator-compatible = "buck5";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck6_reg: regulator@5 {
+ reg = <5>;
+ regulator-compatible = "buck6";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck7_reg: regulator@6 {
+ reg = <6>;
+ regulator-compatible = "buck7";
+ regulator-min-microvolt = <1605000>;
+ regulator-max-microvolt = <1995000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck8_reg: regulator@7 {
+ reg = <7>;
+ regulator-compatible = "buck8";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1_reg: regulator@8 {
+ reg = <8>;
+ regulator-compatible = "ldo1";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo2_reg: regulator@9 {
+ reg = <9>;
+ regulator-compatible = "ldo2";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo3_reg: regulator@10 {
+ reg = <10>;
+ regulator-compatible = "ldo3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo4_reg: regulator@11 {
+ reg = <11>;
+ regulator-compatible = "ldo4";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo5_reg: regulator@12 {
+ reg = <12>;
+ regulator-compatible = "ldo5";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo6_reg: regulator@13 {
+ reg = <13>;
+ regulator-compatible = "ldo6";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
+
+ /* Epson RX8130 real time clock on carrier board */
+ rtc: rx8130@32 {
+ compatible = "epson,rx8130";
+ reg = <0x32>;
+ };
+
+ adc: max11607@34 {
+ compatible = "maxim,max11607";
+ reg = <0x34>;
+ vcc-supply = <&ldo5_reg>;
+ };
+
+ eeprom@50 {
+ compatible = "st,24c02";
+ pagesize = <16>;
+ reg = <0x50>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <10000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+};
+
+&i2c4 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ status = "okay";
+
+ /* Audio Codec */
+ wm8904_1a: wm8904@1a {
+ compatible = "wlf,wm8904";
+ #sound-dai-cells = <0>;
+ reg = <0x1a>;
+ clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+ clock-names = "mclk";
+ };
+
+ gpio_expander_21: gpio-expander@21 {
+ compatible = "nxp,pcal6416";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x21>;
+ };
+
+ /* Current measurement into module VCC */
+ ina219@40 {
+ compatible = "ti,ina219";
+ reg = <0x40>;
+ shunt-resistor = <10000>;
+ status = "okay";
+ };
+
+ /* MIPI-DSI to HDMI adapter */
+ lt8912@48 {
+ compatible = "lontium,lt8912";
+ ddc-i2c-bus = <&i2c2>;
+ hpd-gpios = <&gpio3 15 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpio5 5 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_hpd>, <&pinctrl_gpio1>,
+ <&pinctrl_gpio2>;
+ reg = <0x48>;
+
+ port {
+ lt8912_1_in: endpoint {
+ remote-endpoint = <&mipi_dsi_bridge1_out>;
+ };
+ };
+ };
+
+ /* EEPROM on MIPI-DSI to HDMI adapter */
+ eeprom_50: eeprom@50 {
+ compatible = "st,24c02";
+ pagesize = <16>;
+ reg = <0x50>;
+ };
+
+ /* EEPROM on Verdin Development board */
+ eeprom_57: eeprom@57 {
+ compatible = "st,24c02";
+ pagesize = <16>;
+ reg = <0x57>;
+ };
+};
+
+&lcdif {
+ status = "okay";
+};
+
+&mipi_dsi {
+ status = "okay";
+
+ port@1 {
+ mipi_dsi_bridge1_out: endpoint {
+ remote-endpoint = <&lt8912_1_in>;
+ };
+ };
+};
+
+/* VERDIN I2S_1 */
+&sai2 {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai2>;
+ assigned-clocks = <&clk IMX8MM_CLK_SAI2_SRC>,
+ <&clk IMX8MM_CLK_SAI2_DIV>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <0>, <24576000>;
+ status = "okay";
+};
+
+/* Verdin UART3 */
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+/* Verdin UART1 */
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+/* Verdin UART2 */
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+/* On-module eMMC */
+&usdhc1 {
+ bus-width = <8>;
+ keep-power-in-suspend;
+ non-removable;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ pm-ignore-notify;
+ status = "okay";
+ /* TODO Strobe */
+};
+
+/* Verdin SDIO 1 */
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_cd>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_cd>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_cd>;
+ cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+ bus-width = <4>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ status = "okay";
+};
+
+&usbotg1 {
+ dr_mode = "otg";
+ picophy,pre-emp-curr-control = <3>;
+ picophy,dc-vol-level-adjust = <7>;
+ vbus-supply = <&reg_usb_otg1_vbus>;
+ status = "okay";
+};
+
+&usbotg2 {
+ dr_mode = "host";
+ picophy,pre-emp-curr-control = <3>;
+ picophy,dc-vol-level-adjust = <7>;
+ vbus-supply = <&reg_usb_otg2_vbus>;
+ status = "okay";
+};
+
+&vpu_g1 {
+ status = "okay";
+};
+
+&vpu_g2 {
+ status = "okay";
+};
+
+&vpu_h1 {
+ status = "okay";
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio1>, <&pinctrl_gpio2>, <&pinctrl_gpio3>,
+ <&pinctrl_gpio4>, <&pinctrl_gpio5>, <&pinctrl_gpio6>,
+ <&pinctrl_gpio7>, <&pinctrl_gpio8>, <&pinctrl_se050_ena>;
+
+ imx8mm-verdin {
+ pinctrl_ctrl_force_off_moci: forceoffgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_RXC_GPIO3_IO20 0x1c4 /* SODIMM 250 */
+ >;
+ };
+
+ pinctrl_can1_int: can1intgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO06_GPIO1_IO6 0x1c4
+ >;
+ };
+
+ pinctrl_can2_int: can2intgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO07_GPIO1_IO7 0x1c4
+ >;
+ };
+
+ pinctrl_ecspi2: ecspi2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x4 /* SODIMM 196 */
+ MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x4 /* SODIMM 200 */
+ MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x1c4 /* SODIMM 198 */
+ MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x1c4 /* SODIMM 202 */
+ >;
+ };
+
+ pinctrl_ecspi3: ecspi3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART1_RXD_ECSPI3_SCLK 0x4
+ MX8MM_IOMUXC_UART1_TXD_ECSPI3_MOSI 0x4
+ MX8MM_IOMUXC_UART2_RXD_ECSPI3_MISO 0x1c4
+ MX8MM_IOMUXC_UART2_TXD_GPIO5_IO25 0x1c4
+ MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5 0x1c4
+ >;
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x3
+ MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x3
+ MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f
+ MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f
+ MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f
+ MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f
+ MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91
+ MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91
+ MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91
+ MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91
+ MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f
+ MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91
+ MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91
+ MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f
+ MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x1c4
+ >;
+ };
+
+ pinctrl_flexspi0: flexspi0grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_ALE_QSPI_A_SCLK 0x1c2 /* SODIMM 52 */
+ MX8MM_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B 0x82 /* SODIMM 54 */
+ MX8MM_IOMUXC_NAND_CE1_B_QSPI_A_SS1_B 0x82 /* SODIMM 64 */
+ MX8MM_IOMUXC_NAND_DQS_QSPI_A_DQS 0x82 /* SODIMM 66 */
+ MX8MM_IOMUXC_NAND_DATA00_QSPI_A_DATA0 0x82 /* SODIMM 56 */
+ MX8MM_IOMUXC_NAND_DATA01_QSPI_A_DATA1 0x82 /* SODIMM 58 */
+ MX8MM_IOMUXC_NAND_DATA02_QSPI_A_DATA2 0x82 /* SODIMM 60 */
+ MX8MM_IOMUXC_NAND_DATA03_QSPI_A_DATA3 0x82 /* SODIMM 62 */
+ >;
+ };
+
+ /* (MEZ_)DSI_1_INT# shared with (MEZ_)GPIO_1 on Verdin Development Board */
+ pinctrl_gpio_hpd: gpiohpdgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_RE_B_GPIO3_IO15 0x184 /* SODIMM 17 */
+ >;
+ };
+
+ /* (MEZ_)GPIO_1 shared with (MEZ_)DSI_1_INT# on Verdin Development Board */
+ pinctrl_gpio1: gpio1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_CE3_B_GPIO3_IO4 0x184 /* SODIMM 206 */
+ >;
+ };
+
+ pinctrl_gpio2: gpio2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SPDIF_EXT_CLK_GPIO5_IO5 0x184 /* SODIMM 208 */
+ >;
+ };
+
+ pinctrl_gpio3: gpio3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART3_RXD_GPIO5_IO26 0x184 /* SODIMM 210 */
+ >;
+ };
+
+ pinctrl_gpio4: gpio4grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART3_TXD_GPIO5_IO27 0x184 /* SODIMM 212 */
+ >;
+ };
+
+ pinctrl_gpio5: gpio5grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO00_GPIO1_IO0 0x184 /* SODIMM 216 */
+ >;
+ };
+
+ pinctrl_gpio6: gpio6grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO11_GPIO1_IO11 0x184 /* SODIMM 218 */
+ >;
+ };
+
+ pinctrl_gpio7: gpio7grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x184 /* SODIMM 220 */
+ >;
+ };
+
+ pinctrl_gpio8: gpio8grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x184 /* SODIMM 222 */
+ >;
+ };
+
+ /* On Module I2C */
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c6
+ MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c6
+ >;
+ };
+
+ /* Verdin I2C_4_CSI */
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x400001c6 /* SODIMM 55 */
+ MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x400001c6 /* SODIMM 53 */
+ >;
+ };
+
+ /* Verdin I2C_2_DSI */
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c6 /* SODIMM 95 */
+ MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c6 /* SODIMM 93 */
+ >;
+ };
+
+ /* Verdin I2C_1 */
+ pinctrl_i2c4: i2c4grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x400001c6 /* SODIMM 14 */
+ MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x400001c6 /* SODIMM 12 */
+ >;
+ };
+
+ pinctrl_pcie0: pcie0grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_RXFS_GPIO3_IO19 0x6 /* SODIMM 244 */
+ MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x6
+ >;
+ };
+
+ pinctrl_pmic: pmicirq {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x41
+ >;
+ };
+
+ pinctrl_reg_eth: regethgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_WP_GPIO2_IO20 0x184
+ >;
+ };
+
+ pinctrl_sai2: sai2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0xd6 /* SODIMM 32 */
+ MX8MM_IOMUXC_SAI2_TXC_SAI2_TX_BCLK 0xd6 /* SODIMM 30 */
+ MX8MM_IOMUXC_SAI2_MCLK_SAI2_MCLK 0xd6 /* SODIMM 38 */
+ MX8MM_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0 0xd6 /* SODIMM 36 */
+ MX8MM_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0 0xd6 /* SODIMM 34 */
+ >;
+ };
+
+ pinctrl_sai5: sai5grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_RXD0_SAI5_RX_DATA0 0xd6 /* SODIMM 48 */
+ MX8MM_IOMUXC_SAI5_RXD1_SAI5_TX_SYNC 0xd6 /* SODIMM 44 */
+ MX8MM_IOMUXC_SAI5_RXD2_SAI5_TX_BCLK 0xd6 /* SODIMM 42 */
+ MX8MM_IOMUXC_SAI5_RXD3_SAI5_TX_DATA0 0xd6 /* SODIMM 46 */
+ >;
+ };
+
+ pinctrl_se050_ena: se050enagrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI1_TXD7_GPIO4_IO19 0x184
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI2_RXFS_UART1_TX 0x1c4 /* SODIMM 149 */
+ MX8MM_IOMUXC_SAI2_RXC_UART1_RX 0x1c4 /* SODIMM 147 */
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x1c4 /* SODIMM 129 */
+ MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x1c4 /* SODIMM 131 */
+ MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x1c4 /* SODIMM 133 */
+ MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x1c4 /* SODIMM 135 */
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI1_SCLK_UART3_DCE_RX 0x1c4 /* SODIMM 137 */
+ MX8MM_IOMUXC_ECSPI1_MOSI_UART3_DCE_TX 0x1c4 /* SODIMM 139 */
+ MX8MM_IOMUXC_ECSPI1_MISO_UART3_DCE_CTS_B 0x1c4 /* SODIMM 141 */
+ MX8MM_IOMUXC_ECSPI1_SS0_UART3_DCE_RTS_B 0x1c4 /* SODIMM 143 */
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART4_RXD_UART4_DCE_RX 0x1c4 /* SODIMM 151 */
+ MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX 0x1c4 /* SODIMM 153 */
+ >;
+ };
+
+ pinctrl_reg_usb1_en: regusb1en {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x184 /* SODIMM 155 */
+ >;
+ };
+
+ pinctrl_reg_usb2_en: regusb2en {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO14_GPIO1_IO14 0x184 /* SODIMM 185 */
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190
+ MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0
+ MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0
+ MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0
+ MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0
+ MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0
+ MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4 0x1d0
+ MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5 0x1d0
+ MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6 0x1d0
+ MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7 0x1d0
+ MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x190
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x194
+ MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d4
+ MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d4
+ MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d4
+ MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d4
+ MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d4
+ MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4 0x1d4
+ MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5 0x1d4
+ MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6 0x1d4
+ MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7 0x1d4
+ MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x194
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x196
+ MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d6
+ MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d6
+ MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d6
+ MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d6
+ MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d6
+ MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4 0x1d6
+ MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5 0x1d6
+ MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6 0x1d6
+ MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7 0x1d6
+ MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x196
+ >;
+ };
+
+ pinctrl_usdhc2_cd: usdhc2cdgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x1c4 /* SODIMM 84 */
+ >;
+ };
+
+ pinctrl_usdhc2_pwr_en: usdhc2pwrengrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_CLE_GPIO3_IO5 0x184 /* SODIMM 76 */
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190 /* SODIMM 78 */
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0 /* SODIMM 74 */
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0 /* SODIMM 80 */
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0 /* SODIMM 82 */
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0 /* SODIMM 70 */
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0 /* SODIMM 72 */
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x190
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d0
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d0
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d0
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d0
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x194
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d4
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d4
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d4
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d4
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d4
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x196
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d6
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d6
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d6
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d6
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d6
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6
+ >;
+ };
+
+ pinctrl_wifi_ctrl: wifictrlgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_READY_B_GPIO3_IO16 0x1c4 /* WIFI_WKUP_BT */
+ MX8MM_IOMUXC_SD1_RESET_B_GPIO2_IO10 0x1c4 /* WIFI_WKUP_WLAN */
+ MX8MM_IOMUXC_SAI1_RXD7_GPIO4_IO9 0x1c4 /* WIFI_W_WKUP_HOST */
+ >;
+ };
+
+ pinctrl_wifi_pwr_en: wifipwrengrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_MCLK_GPIO3_IO25 0x184 /* PMIC_EN_WIFI */
+ >;
+ };
+
+ pinctrl_wifi_i2s: wifii2sgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI1_RXD4_SAI6_TX_BCLK 0xd6
+ MX8MM_IOMUXC_SAI1_RXD5_SAI6_TX_DATA0 0xd6
+ MX8MM_IOMUXC_SAI1_RXD6_SAI6_TX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI1_TXD5_SAI6_RX_DATA0 0xd6
+ >;
+ };
+ };
+};
diff --git a/arch/arm/mach-imx/imx8m/Kconfig b/arch/arm/mach-imx/imx8m/Kconfig
index 249436c33e..512cd135e3 100644
--- a/arch/arm/mach-imx/imx8m/Kconfig
+++ b/arch/arm/mach-imx/imx8m/Kconfig
@@ -60,6 +60,12 @@ config TARGET_IMX8MM_DDR4_EVK
select SUPPORT_SPL
select IMX8M_DDR4
+config TARGET_VERDIN_IMX8MM
+ bool "Support Toradex Verdin iMX8M Mini module"
+ select IMX8MM
+ select SUPPORT_SPL
+ select IMX8M_LPDDR4
+
endchoice
config SYS_SOC
@@ -70,5 +76,6 @@ source "board/freescale/imx8mq_arm2/Kconfig"
source "board/freescale/imx8mq_phanbell/Kconfig"
source "board/freescale/imx8mm_evk/Kconfig"
source "board/freescale/imx8mm_val/Kconfig"
+source "board/toradex/verdin-imx8mm/Kconfig"
endif
diff --git a/board/toradex/verdin-imx8mm/Kconfig b/board/toradex/verdin-imx8mm/Kconfig
new file mode 100644
index 0000000000..8a2fe98682
--- /dev/null
+++ b/board/toradex/verdin-imx8mm/Kconfig
@@ -0,0 +1,30 @@
+if TARGET_VERDIN_IMX8MM
+
+config SYS_BOARD
+ default "verdin-imx8mm"
+
+config SYS_VENDOR
+ default "toradex"
+
+config SYS_CONFIG_NAME
+ default "verdin-imx8mm"
+
+config TDX_CFG_BLOCK
+ default y
+
+config TDX_HAVE_MMC
+ default y
+
+config TDX_CFG_BLOCK_DEV
+ default "0"
+
+config TDX_CFG_BLOCK_PART
+ default "1"
+
+# Toradex config block in eMMC, at the end of 1st "boot sector"
+config TDX_CFG_BLOCK_OFFSET
+ default "-512"
+
+source "board/toradex/common/Kconfig"
+
+endif
diff --git a/board/toradex/verdin-imx8mm/MAINTAINERS b/board/toradex/verdin-imx8mm/MAINTAINERS
new file mode 100644
index 0000000000..339266d72e
--- /dev/null
+++ b/board/toradex/verdin-imx8mm/MAINTAINERS
@@ -0,0 +1,8 @@
+Verdin iMX8MM
+M: Igor Opaniuk <igor.opaniuk@toradex.com>
+W: http://developer.toradex.com/software/linux/linux-software
+S: Maintained
+F: arch/arm/dts/fsl-imx8mm-verdin.dts
+F: board/toradex/verdin-imx8mm/
+F: configs/verdin-imx8mm_defconfig
+F: include/configs/verdin-imx8mm.h
diff --git a/board/toradex/verdin-imx8mm/Makefile b/board/toradex/verdin-imx8mm/Makefile
new file mode 100644
index 0000000000..7161b19d0f
--- /dev/null
+++ b/board/toradex/verdin-imx8mm/Makefile
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2018-2019 Toradex
+#
+
+obj-y += verdin-imx8mm.o
+
+ifdef CONFIG_SPL_BUILD
+obj-y += spl.o
+obj-$(CONFIG_IMX8M_LPDDR4) += lpddr4_timing.o
+obj-$(CONFIG_IMX8M_DDR4) += ddr4_timing.o
+endif
diff --git a/board/toradex/verdin-imx8mm/spl.c b/board/toradex/verdin-imx8mm/spl.c
new file mode 100644
index 0000000000..5f1bfbbc17
--- /dev/null
+++ b/board/toradex/verdin-imx8mm/spl.c
@@ -0,0 +1,231 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 Toradex
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx8m_ddr.h>
+#include <asm/arch/imx8mm_pins.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/mach-imx/gpio.h>
+#include <asm/mach-imx/iomux-v3.h>
+#include <asm/mach-imx/mxc_i2c.h>
+#include <errno.h>
+#include <fsl_esdhc.h>
+#include <mmc.h>
+#include <power/pmic.h>
+#include <power/bd71837.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void spl_dram_init(void)
+{
+ ddr_init(&dram_timing);
+}
+
+#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 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),
+};
+
+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 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_mmc_init(bd_t *bis)
+{
+ 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;
+ }
+
+ return 0;
+}
+
+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 1;
+}
+
+#ifdef CONFIG_POWER
+#define I2C_PMIC 0
+int power_init_board(void)
+{
+ struct pmic *p;
+ int 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(p, BD71837_PWRONCONFIG1, 0x0);
+
+ /* unlock the PMIC regs */
+ pmic_reg_write(p, BD71837_REGLOCK, 0x1);
+
+ /* increase VDD_DRAM to 0.9v for 3Ghz DDR */
+ pmic_reg_write(p, BD71837_BUCK5_VOLT, 0x2);
+
+#ifndef CONFIG_IMX8M_LPDDR4
+ /* increase NVCC_DRAM_1V2 to 1.2v for DDR4 */
+ pmic_reg_write(p, BD71837_BUCK8_VOLT, 0x28);
+#endif
+
+ /* lock the PMIC regs */
+ 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)
+{
+ int ret;
+
+ /* Clear global data */
+ memset((void *)gd, 0, sizeof(gd_t));
+
+ arch_cpu_init();
+
+ board_early_init_f();
+
+ timer_init();
+
+ preloader_console_init();
+
+ /* Clear the BSS. */
+ memset(__bss_start, 0, __bss_end - __bss_start);
+
+ ret = spl_init();
+ if (ret) {
+ 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 */
+ spl_dram_init();
+
+ board_init_r(NULL, 0);
+}
diff --git a/board/toradex/verdin-imx8mm/verdin-imx8mm.c b/board/toradex/verdin-imx8mm/verdin-imx8mm.c
new file mode 100644
index 0000000000..e3c5774410
--- /dev/null
+++ b/board/toradex/verdin-imx8mm/verdin-imx8mm.c
@@ -0,0 +1,494 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 Toradex
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx8mm_pins.h>
+#include <asm/arch/sys_proto.h>
+#include <asm-generic/gpio.h>
+#include <asm/mach-imx/dma.h>
+#include <asm/mach-imx/iomux-v3.h>
+#include <asm/mach-imx/gpio.h>
+#include <asm/mach-imx/mxc_i2c.h>
+#include <asm/mach-imx/video.h>
+#include <dm.h>
+#include <errno.h>
+#include <fsl_esdhc.h>
+#include <imx_mipi_dsi_bridge.h>
+#include <malloc.h>
+#include <miiphy.h>
+#include <mipi_dsi_panel.h>
+#include <mmc.h>
+#include <netdev.h>
+#include <power/pmic.h>
+#include <power/bd71837.h>
+#include <sec_mipi_dsim.h>
+#include <spl.h>
+#include <usb.h>
+
+#include "../common/tdx-cfg-block.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#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)
+
+/* 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 wdog_pads[] = {
+ IMX8MM_PAD_GPIO1_IO02_WDOG1_WDOG_B | MUX_PAD_CTRL(WDOG_PAD_CTRL),
+};
+
+int board_early_init_f(void)
+{
+ struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR;
+
+ imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads));
+
+ set_wdog_reset(wdog);
+
+ imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads));
+
+ return 0;
+}
+
+#ifdef CONFIG_BOARD_POSTCLK_INIT
+int board_postclk_init(void)
+{
+ /* TODO */
+ return 0;
+}
+#endif
+
+int dram_init(void)
+{
+ /* rom_pointer[1] contains the size of TEE occupies */
+ if (rom_pointer[1])
+ gd->ram_size = PHYS_SDRAM_SIZE - rom_pointer[1];
+ else
+ gd->ram_size = PHYS_SDRAM_SIZE;
+
+ return 0;
+}
+
+#ifdef CONFIG_OF_BOARD_SETUP
+int ft_board_setup(void *blob, bd_t *bd)
+{
+ return ft_common_board_setup(blob, bd);
+}
+#endif
+
+#ifdef CONFIG_FEC_MXC
+static int setup_fec(void)
+{
+ struct iomuxc_gpr_base_regs *const iomuxc_gpr_regs
+ = (struct iomuxc_gpr_base_regs *) IOMUXC_GPR_BASE_ADDR;
+
+ /* Use 125M anatop REF_CLK1 for ENET1, not from external */
+ clrsetbits_le32(&iomuxc_gpr_regs->gpr[1],
+ IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL_SHIFT, 0);
+ return set_clk_enet(ENET_125MHZ);
+}
+
+int board_phy_config(struct phy_device *phydev)
+{
+ /* TODO: check settings for KSZ9030/31 */
+
+ /* enable rgmii rxc skew and phy mode select to RGMII copper */
+ phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f);
+ phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8);
+
+ phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x00);
+ phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee);
+ phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
+ phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100);
+
+ if (phydev->drv->config)
+ phydev->drv->config(phydev);
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_USB_TCPC
+struct tcpc_port port1;
+struct tcpc_port port2;
+
+static int setup_pd_switch(uint8_t i2c_bus, uint8_t addr)
+{
+ struct udevice *bus;
+ struct udevice *i2c_dev = NULL;
+ int ret;
+ uint8_t valb;
+
+ ret = uclass_get_device_by_seq(UCLASS_I2C, i2c_bus, &bus);
+ if (ret) {
+ printf("%s: Can't find bus\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = dm_i2c_probe(bus, addr, 0, &i2c_dev);
+ if (ret) {
+ printf("%s: Can't find device id=0x%x\n",
+ __func__, addr);
+ return -ENODEV;
+ }
+
+ ret = dm_i2c_read(i2c_dev, 0xB, &valb, 1);
+ if (ret) {
+ printf("%s dm_i2c_read failed, err %d\n", __func__, ret);
+ return -EIO;
+ }
+ valb |= 0x4; /* Set DB_EXIT to exit dead battery mode */
+ ret = dm_i2c_write(i2c_dev, 0xB, (const uint8_t *)&valb, 1);
+ if (ret) {
+ printf("%s dm_i2c_write failed, err %d\n", __func__, ret);
+ return -EIO;
+ }
+
+ /* Set OVP threshold to 23V */
+ valb = 0x6;
+ ret = dm_i2c_write(i2c_dev, 0x8, (const uint8_t *)&valb, 1);
+ if (ret) {
+ printf("%s dm_i2c_write failed, err %d\n", __func__, ret);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int pd_switch_snk_enable(struct tcpc_port *port)
+{
+ if (port == &port1) {
+ debug("Setup pd switch on port 1\n");
+ return setup_pd_switch(1, 0x72);
+ } else if (port == &port2) {
+ debug("Setup pd switch on port 2\n");
+ return setup_pd_switch(1, 0x73);
+ } else
+ return -EINVAL;
+}
+
+struct tcpc_port_config port1_config = {
+ .i2c_bus = 1, /*i2c2*/
+ .addr = 0x50,
+ .port_type = TYPEC_PORT_UFP,
+ .max_snk_mv = 5000,
+ .max_snk_ma = 3000,
+ .max_snk_mw = 40000,
+ .op_snk_mv = 9000,
+ .switch_setup_func = &pd_switch_snk_enable,
+};
+
+struct tcpc_port_config port2_config = {
+ .i2c_bus = 1, /*i2c2*/
+ .addr = 0x52,
+ .port_type = TYPEC_PORT_UFP,
+ .max_snk_mv = 5000,
+ .max_snk_ma = 3000,
+ .max_snk_mw = 40000,
+ .op_snk_mv = 9000,
+ .switch_setup_func = &pd_switch_snk_enable,
+};
+
+static int setup_typec(void)
+{
+ int ret;
+
+ debug("tcpc_init port 2\n");
+ ret = tcpc_init(&port2, port2_config, NULL);
+ if (ret) {
+ printf("%s: tcpc port2 init failed, err=%d\n",
+ __func__, ret);
+ } else if (tcpc_pd_sink_check_charging(&port2)) {
+ /* Disable PD for USB1, since USB2 has priority */
+ port1_config.disable_pd = true;
+ printf("Power supply on USB2\n");
+ }
+
+ debug("tcpc_init port 1\n");
+ ret = tcpc_init(&port1, port1_config, NULL);
+ if (ret) {
+ printf("%s: tcpc port1 init failed, err=%d\n",
+ __func__, ret);
+ } else {
+ if (!port1_config.disable_pd)
+ printf("Power supply on USB1\n");
+ return ret;
+ }
+
+ return ret;
+}
+#endif /* CONFIG_USB_TCPC */
+
+#ifdef CONFIG_USB_EHCI_HCD
+int board_usb_init(int index, enum usb_init_type init)
+{
+ int ret = 0;
+#ifdef CONFIG_USB_TCPC
+ struct tcpc_port *port_ptr;
+#endif
+
+ debug("board_usb_init %d, type %d\n", index, init);
+
+ imx8m_usb_power(index, true);
+
+#ifdef CONFIG_USB_TCPC
+ if (index == 0)
+ port_ptr = &port1;
+ else
+ port_ptr = &port2;
+
+ if (init == USB_INIT_HOST)
+ tcpc_setup_dfp_mode(port_ptr);
+ else
+ tcpc_setup_ufp_mode(port_ptr);
+#endif
+
+ return ret;
+}
+
+int board_usb_cleanup(int index, enum usb_init_type init)
+{
+ int ret = 0;
+
+ debug("board_usb_cleanup %d, type %d\n", index, init);
+
+#ifdef CONFIG_USB_TCPC
+ if (init == USB_INIT_HOST) {
+ if (index == 0)
+ ret = tcpc_disable_src_vbus(&port1);
+ else
+ ret = tcpc_disable_src_vbus(&port2);
+ }
+#endif
+
+ imx8m_usb_power(index, false);
+ return ret;
+}
+
+#ifdef CONFIG_SPL_BUILD
+int board_usb_phy_mode(struct udevice *dev)
+#else
+int board_ehci_usb_phy_mode(struct udevice *dev)
+#endif
+{
+#ifdef CONFIG_USB_TCPC
+ int ret = 0;
+ enum typec_cc_polarity pol;
+ enum typec_cc_state state;
+ struct tcpc_port *port_ptr;
+
+ if (dev->seq == 0)
+ port_ptr = &port1;
+ else
+ port_ptr = &port2;
+
+ tcpc_setup_ufp_mode(port_ptr);
+
+ ret = tcpc_get_cc_status(port_ptr, &pol, &state);
+ if (!ret) {
+ if (state == TYPEC_STATE_SRC_RD_RA || state == TYPEC_STATE_SRC_RD)
+ return USB_INIT_HOST;
+ }
+#endif /* CONFIG_USB_TCPC */
+
+ return USB_INIT_DEVICE;
+}
+#endif
+
+int board_init(void)
+{
+#ifdef CONFIG_USB_TCPC
+ setup_typec();
+#endif
+
+#ifdef CONFIG_FEC_MXC
+ setup_fec();
+#endif
+
+ return 0;
+}
+
+#ifdef CONFIG_VIDEO_MXS
+
+/* TODO: video integration */
+#define ADV7535_MAIN 0x3d
+#define ADV7535_DSI_CEC 0x3c
+
+static const struct sec_mipi_dsim_plat_data imx8mm_mipi_dsim_plat_data = {
+ .version = 0x1060200,
+ .max_data_lanes = 4,
+ .max_data_rate = 1500000000ULL,
+ .reg_base = MIPI_DSI_BASE_ADDR,
+ .gpr_base = CSI_BASE_ADDR + 0x8000,
+};
+
+#define DISPLAY_MIX_SFT_RSTN_CSR 0x00
+#define DISPLAY_MIX_CLK_EN_CSR 0x04
+
+ /* 'DISP_MIX_SFT_RSTN_CSR' bit fields */
+#define BUS_RSTN_BLK_SYNC_SFT_EN BIT(6)
+
+ /* 'DISP_MIX_CLK_EN_CSR' bit fields */
+#define LCDIF_PIXEL_CLK_SFT_EN BIT(7)
+#define LCDIF_APB_CLK_SFT_EN BIT(6)
+
+void disp_mix_bus_rstn_reset(ulong gpr_base, bool reset)
+{
+ if (!reset)
+ /* release reset */
+ setbits_le32(gpr_base + DISPLAY_MIX_SFT_RSTN_CSR, BUS_RSTN_BLK_SYNC_SFT_EN);
+ else
+ /* hold reset */
+ clrbits_le32(gpr_base + DISPLAY_MIX_SFT_RSTN_CSR, BUS_RSTN_BLK_SYNC_SFT_EN);
+}
+
+void disp_mix_lcdif_clks_enable(ulong gpr_base, bool enable)
+{
+ if (enable)
+ /* enable lcdif clks */
+ setbits_le32(gpr_base + DISPLAY_MIX_CLK_EN_CSR, LCDIF_PIXEL_CLK_SFT_EN | LCDIF_APB_CLK_SFT_EN);
+ else
+ /* disable lcdif clks */
+ clrbits_le32(gpr_base + DISPLAY_MIX_CLK_EN_CSR, LCDIF_PIXEL_CLK_SFT_EN | LCDIF_APB_CLK_SFT_EN);
+}
+
+struct mipi_dsi_client_dev adv7535_dev = {
+ .channel = 0,
+ .lanes = 4,
+ .format = MIPI_DSI_FMT_RGB888,
+ .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
+ MIPI_DSI_MODE_EOT_PACKET | MIPI_DSI_MODE_VIDEO_HSE,
+ .name = "ADV7535",
+};
+
+struct mipi_dsi_client_dev rm67191_dev = {
+ .channel = 0,
+ .lanes = 4,
+ .format = MIPI_DSI_FMT_RGB888,
+ .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
+ MIPI_DSI_MODE_EOT_PACKET | MIPI_DSI_MODE_VIDEO_HSE,
+};
+
+#define FSL_SIP_GPC 0xC2000000
+#define FSL_SIP_CONFIG_GPC_PM_DOMAIN 0x3
+#define DISPMIX 9
+#define MIPI 10
+
+void do_enable_mipi2hdmi(struct display_info_t const *dev)
+{
+ gpio_request(IMX_GPIO_NR(1, 8), "DSI EN");
+ gpio_direction_output(IMX_GPIO_NR(1, 8), 1);
+
+ /* ADV7353 initialization */
+/* TODO: disable for now
+ adv7535_init(); */
+
+ /* enable the dispmix & mipi phy power domain */
+ call_imx_sip(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_PM_DOMAIN, DISPMIX, true, 0);
+ call_imx_sip(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_PM_DOMAIN, MIPI, true, 0);
+
+ /* Put lcdif out of reset */
+ disp_mix_bus_rstn_reset(imx8mm_mipi_dsim_plat_data.gpr_base, false);
+ disp_mix_lcdif_clks_enable(imx8mm_mipi_dsim_plat_data.gpr_base, true);
+
+ /* Setup mipi dsim */
+ sec_mipi_dsim_setup(&imx8mm_mipi_dsim_plat_data);
+ imx_mipi_dsi_bridge_attach(&adv7535_dev); /* attach adv7535 device */
+}
+
+void do_enable_mipi_led(struct display_info_t const *dev)
+{
+ gpio_request(IMX_GPIO_NR(1, 8), "DSI EN");
+ gpio_direction_output(IMX_GPIO_NR(1, 8), 0);
+ mdelay(100);
+ gpio_direction_output(IMX_GPIO_NR(1, 8), 1);
+
+ /* enable the dispmix & mipi phy power domain */
+ call_imx_sip(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_PM_DOMAIN, DISPMIX, true, 0);
+ call_imx_sip(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_PM_DOMAIN, MIPI, true, 0);
+
+ /* Put lcdif out of reset */
+ disp_mix_bus_rstn_reset(imx8mm_mipi_dsim_plat_data.gpr_base, false);
+ disp_mix_lcdif_clks_enable(imx8mm_mipi_dsim_plat_data.gpr_base, true);
+
+ /* Setup mipi dsim */
+ sec_mipi_dsim_setup(&imx8mm_mipi_dsim_plat_data);
+
+ rm67191_init();
+ rm67191_dev.name = displays[1].mode.name;
+ imx_mipi_dsi_bridge_attach(&rm67191_dev); /* attach rm67191 device */
+}
+
+void board_quiesce_devices(void)
+{
+ gpio_request(IMX_GPIO_NR(1, 8), "DSI EN");
+ gpio_direction_output(IMX_GPIO_NR(1, 8), 0);
+}
+
+struct display_info_t const displays[] = {{
+ .bus = LCDIF_BASE_ADDR,
+ .addr = 0,
+ .pixfmt = 24,
+ .detect = NULL,
+ .enable = do_enable_mipi2hdmi,
+ .mode = {
+ .name = "MIPI2HDMI",
+ .refresh = 60,
+ .xres = 1920,
+ .yres = 1080,
+ .pixclock = 6734, /* 148500000 */
+ .left_margin = 148,
+ .right_margin = 88,
+ .upper_margin = 36,
+ .lower_margin = 4,
+ .hsync_len = 44,
+ .vsync_len = 5,
+ .sync = FB_SYNC_EXT,
+ .vmode = FB_VMODE_NONINTERLACED
+
+} }, {
+ .bus = LCDIF_BASE_ADDR,
+ .addr = 0,
+ .pixfmt = 24,
+ .detect = NULL,
+ .enable = do_enable_mipi_led,
+ .mode = {
+ .name = "RM67191_OLED",
+ .refresh = 60,
+ .xres = 1080,
+ .yres = 1920,
+ .pixclock = 7575, /* 132000000 */
+ .left_margin = 34,
+ .right_margin = 20,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .sync = FB_SYNC_EXT,
+ .vmode = FB_VMODE_NONINTERLACED
+
+} } };
+size_t display_count = ARRAY_SIZE(displays);
+#endif /* CONFIG_VIDEO_MXS */
+
+int board_late_init(void)
+{
+ return 0;
+}
+
+#ifdef CONFIG_FSL_FASTBOOT
+#ifdef CONFIG_ANDROID_RECOVERY
+int is_recovery_key_pressing(void)
+{
+ return 0; /* TODO */
+}
+#endif /*CONFIG_ANDROID_RECOVERY*/
+#endif /*CONFIG_FSL_FASTBOOT*/
diff --git a/configs/verdin-imx8mm_defconfig b/configs/verdin-imx8mm_defconfig
new file mode 100644
index 0000000000..406c202ba5
--- /dev/null
+++ b/configs/verdin-imx8mm_defconfig
@@ -0,0 +1,71 @@
+CONFIG_ARM=y
+CONFIG_ARCH_IMX8M=y
+CONFIG_SYS_TEXT_BASE=0x40200000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_TARGET_VERDIN_IMX8MM=y
+CONFIG_SPL_MMC_SUPPORT=y
+CONFIG_DEFAULT_DEVICE_TREE="fsl-imx8mm-verdin"
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_FIT=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg,SPL_TEXT_BASE=0x7E1000"
+CONFIG_BOOTDELAY=1
+CONFIG_LOG=y
+CONFIG_DEFAULT_FDT_FILE="fsl-imx8mm-verdin-dev.dtb"
+CONFIG_VERSION_VARIABLE=y
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_ARCH_MISC_INIT=y
+CONFIG_SPL=y
+CONFIG_SPL_BOARD_INIT=y
+CONFIG_SPL_USB_HOST_SUPPORT=y
+CONFIG_SPL_USB_GADGET_SUPPORT=y
+CONFIG_SPL_USB_SDP_SUPPORT=y
+CONFIG_SYS_PROMPT="Verdin iMX8MM # "
+CONFIG_FASTBOOT=y
+CONFIG_FSL_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x42800000
+CONFIG_FASTBOOT_BUF_SIZE=0x40000000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_CLK=y
+CONFIG_CMD_FUSE=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_READ=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_OF_CONTROL=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_CPU=y
+CONFIG_DM_GPIO=y
+CONFIG_MXC_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_MXC=y
+CONFIG_DM_MMC=y
+CONFIG_PHYLIB=y
+CONFIG_PHY_MICREL=y
+CONFIG_PHY_MICREL_KSZ90X1=y
+CONFIG_DM_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_IMX8M=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_DM_THERMAL=y
+CONFIG_NXP_TMU=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="FSL"
+CONFIG_USB_GADGET_VENDOR_NUM=0x0525
+CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
+CONFIG_CI_UDC=y
+CONFIG_SDP_LOADADDR=0x40400000
+CONFIG_VIDEO=y
+CONFIG_IMX_SEC_MIPI_DSI=y
diff --git a/include/configs/verdin-imx8mm.h b/include/configs/verdin-imx8mm.h
new file mode 100644
index 0000000000..bd1198126f
--- /dev/null
+++ b/include/configs/verdin-imx8mm.h
@@ -0,0 +1,230 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2019 Toradex
+ */
+
+#ifndef __VERDIN_IMX8MM_H
+#define __VERDIN_IMX8MM_H
+
+#include <linux/sizes.h>
+#include <asm/arch/imx-regs.h>
+
+#include "imx_env.h"
+
+#define CONFIG_DISPLAY_BOARDINFO_LATE
+
+#ifdef CONFIG_SECURE_BOOT
+#define CONFIG_CSF_SIZE 0x2000 /* 8K region */
+#endif
+
+#define CONFIG_SPL_MAX_SIZE (148 * 1024)
+#define CONFIG_SYS_MONITOR_LEN (512 * 1024)
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x300
+#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1
+#define CONFIG_SYS_UBOOT_BASE (QSPI0_AMBA_BASE + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512)
+
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SPL_WATCHDOG_SUPPORT
+#define CONFIG_SPL_POWER_SUPPORT
+#define CONFIG_SPL_DRIVERS_MISC_SUPPORT
+#define CONFIG_SPL_I2C_SUPPORT
+#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv8/u-boot-spl.lds"
+#define CONFIG_SPL_STACK 0x91fff0
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_GPIO_SUPPORT
+#define CONFIG_SPL_BSS_START_ADDR 0x00910000
+#define CONFIG_SPL_BSS_MAX_SIZE 0x2000 /* 8 KB */
+#define CONFIG_SYS_SPL_MALLOC_START 0x42200000
+#define CONFIG_SYS_SPL_MALLOC_SIZE 0x80000 /* 512 KB */
+#define CONFIG_SYS_ICACHE_OFF
+#define CONFIG_SYS_DCACHE_OFF
+
+#define CONFIG_MALLOC_F_ADDR 0x912000 /* malloc f used before GD_FLG_FULL_MALLOC_INIT set */
+
+#define CONFIG_SPL_ABORT_ON_RAW_IMAGE /* For RAW image gives a error info not panic */
+
+#undef CONFIG_DM_MMC
+#undef CONFIG_DM_PMIC
+#undef CONFIG_DM_PMIC_PFUZE100
+
+#define CONFIG_POWER
+#define CONFIG_POWER_I2C
+#define CONFIG_POWER_BD71837
+
+#define CONFIG_SYS_I2C
+#define CONFIG_SYS_I2C_MXC_I2C1 /* enable I2C bus 1 */
+#define CONFIG_SYS_I2C_MXC_I2C2 /* enable I2C bus 2 */
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
+
+#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+
+#endif /* CONFIG_SPL_BUILD */
+
+#define CONFIG_FASTBOOT_USB_DEV 0
+
+#define CONFIG_REMAKE_ELF
+
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_BOARD_POSTCLK_INIT
+#define CONFIG_BOARD_LATE_INIT
+
+#undef CONFIG_CMD_EXPORTENV
+#undef CONFIG_CMD_IMPORTENV
+#undef CONFIG_CMD_IMLS
+
+#undef CONFIG_CMD_CRC32
+#undef CONFIG_BOOTM_NETBSD
+
+/* ENET Config */
+/* ENET1 */
+#if defined(CONFIG_CMD_NET)
+#define CONFIG_MII
+#define CONFIG_ETHPRIME "FEC"
+
+#define CONFIG_FEC_MXC
+#define CONFIG_FEC_XCV_TYPE RGMII
+#define CONFIG_FEC_MXC_PHYADDR 7
+#define FEC_QUIRK_ENET_MAC
+
+#define IMX_FEC_BASE 0x30BE0000
+
+#define CONFIG_IP_DEFRAG
+#define CONFIG_TFTP_BLOCKSIZE 4096
+#define CONFIG_TFTP_TSIZE
+
+#define CONFIG_IPADDR 192.168.10.2
+#define CONFIG_NETMASK 255.255.255.0
+#define CONFIG_SERVERIP 192.168.10.1
+#endif /* CONFIG_CMD_NET */
+
+#define MEM_LAYOUT_ENV_SETTINGS \
+ "fdt_addr_r=0x44000000\0" \
+ "kernel_addr_r=0x42000000\0" \
+ "ramdisk_addr_r=0x46400000\0" \
+ "scriptaddr=0x46000000\0"
+
+#define CONFIG_LOADADDR 0x40480000
+#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
+
+/* Enable Distro Boot */
+#ifndef CONFIG_SPL_BUILD
+#define BOOT_TARGET_DEVICES(func) \
+ func(MMC, mmc, 1) \
+ func(MMC, mmc, 0) \
+ func(USB, usb, 0) \
+ func(DHCP, dhcp, na)
+#include <config_distro_bootcmd.h>
+#undef CONFIG_ISO_PARTITION
+#else
+#define BOOTENV
+#endif
+
+/* Initial environment variables */
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ BOOTENV \
+ MEM_LAYOUT_ENV_SETTINGS \
+ "bootcmd_mfg=fastboot 0\0" \
+ "console=ttymxc0\0" \
+ "fdt_addr=0x43000000\0" \
+ "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \
+ "initrd_addr=0x43800000\0" \
+ "initrd_high=0xffffffffffffffff\0" \
+ "kernel_image=Image\0" \
+ "setup=setenv setupargs console=${console},${baudrate} console=tty1 consoleblank=0 earlycon\0"
+
+#define CONFIG_SYS_INIT_RAM_ADDR 0x40000000
+#define CONFIG_SYS_INIT_RAM_SIZE 0x80000
+#define CONFIG_SYS_INIT_SP_OFFSET \
+ (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR \
+ (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
+
+#define CONFIG_ENV_OVERWRITE
+#if defined(CONFIG_ENV_IS_IN_MMC)
+/* Environment in eMMC, before config block at the end of 1st "boot sector" */
+#define CONFIG_ENV_SIZE 0x2000
+#define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE + \
+ CONFIG_TDX_CFG_BLOCK_OFFSET)
+#define CONFIG_SYS_MMC_ENV_DEV 0
+#define CONFIG_SYS_MMC_ENV_PART 1
+#endif
+
+#define CONFIG_SYS_BOOTM_LEN (64 << 20) /* Increase max gunzip size */
+
+/* Size of malloc() pool */
+#define CONFIG_SYS_MALLOC_LEN ((CONFIG_ENV_SIZE + (32*1024)) * 1024)
+
+#define CONFIG_SYS_SDRAM_BASE 0x40000000
+#define PHYS_SDRAM 0x40000000
+#define PHYS_SDRAM_SIZE 0x80000000 /* 2GB DDR */
+#define CONFIG_NR_DRAM_BANKS 1
+
+#define CONFIG_SYS_MEMTEST_START PHYS_SDRAM
+#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + (PHYS_SDRAM_SIZE >> 1))
+
+#define CONFIG_BAUDRATE 115200
+
+#define CONFIG_MXC_UART
+#define CONFIG_MXC_UART_BASE UART1_BASE_ADDR
+
+/* Monitor Command Prompt */
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
+#define CONFIG_SYS_CBSIZE 2048
+#define CONFIG_SYS_MAXARGS 64
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
+ sizeof(CONFIG_SYS_PROMPT) + 16)
+
+#define CONFIG_IMX_BOOTAUX
+
+/* USDHC */
+#define CONFIG_FSL_ESDHC
+#define CONFIG_FSL_USDHC
+
+#define CONFIG_SYS_FSL_USDHC_NUM 2
+#define CONFIG_SYS_FSL_ESDHC_ADDR 0
+
+#define CONFIG_SUPPORT_EMMC_BOOT /* eMMC specific */
+#define CONFIG_SYS_MMC_IMG_LOAD_PART 1
+
+#define CONFIG_MXC_OCOTP
+
+#ifndef CONFIG_DM_I2C
+#define CONFIG_SYS_I2C
+#endif
+#define CONFIG_SYS_I2C_MXC_I2C1 /* enable I2C bus 1 */
+#define CONFIG_SYS_I2C_MXC_I2C2 /* enable I2C bus 2 */
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
+#define CONFIG_SYS_I2C_SPEED 100000
+
+/* USB configs */
+#ifndef CONFIG_SPL_BUILD
+/* TODO moving USB_STORAGE to .config makes the SPL build fail */
+#define CONFIG_USB_STORAGE
+#define CONFIG_USBD_HS
+
+#define CONFIG_USB_GADGET_MASS_STORAGE
+#endif /* !CONFIG_SPL_BUILD */
+
+#define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW)
+#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
+
+#ifdef CONFIG_VIDEO
+#define CONFIG_VIDEO_MXS
+#define CONFIG_VIDEO_LOGO
+#define CONFIG_SPLASH_SCREEN
+#define CONFIG_SPLASH_SCREEN_ALIGN
+#define CONFIG_CMD_BMP
+#define CONFIG_BMP_16BPP
+#define CONFIG_VIDEO_BMP_RLE8
+#define CONFIG_VIDEO_BMP_LOGO
+#define CONFIG_IMX_VIDEO_SKIP
+#define CONFIG_RM67191
+#endif /* CONFIG_VIDEO */
+
+#define CONFIG_OF_SYSTEM_SETUP
+
+#endif /* __VERDIN_IMX8MM_H */