MLK-14938-26 imx8qm_arm2: Add i.MX8QM ARM2 board support
authorYe Li <ye.li@nxp.com>
Thu, 18 May 2017 12:51:34 +0000 (07:51 -0500)
committerJason Liu <jason.hui.liu@nxp.com>
Thu, 2 Nov 2017 18:36:51 +0000 (02:36 +0800)
Add board level codes and DTS for i.MX8QM LPDDR4 ARM2 board.

Copy the DTS from imx_4.9.y kernel on commit:
"f4b0affd5477301f732efc8ee21185b11495cfcf"
With modifications to support FlexSPI flash and PCA953x

- Enabled DM driver:
  FEC, LPUART, LPI2C, GPIO, SD/MMC, FSPI, PCA953X

- Enabled Non-DM driver:
  SATA, PCIE, iomux, fuse

- Disabled driver:
  mailbox, pinctrl (will try to use later)

- Board defconfigs:
  imx8qm_lpddr4_arm2_defconfig

Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Signed-off-by: Han Xu <han.xu@nxp.com>
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Ye Li <ye.li@nxp.com>
arch/arm/cpu/armv8/imx8/Kconfig
arch/arm/dts/Makefile
arch/arm/dts/fsl-imx8qm-lpddr4-arm2.dts [new file with mode: 0644]
board/freescale/imx8qm_arm2/Kconfig [new file with mode: 0644]
board/freescale/imx8qm_arm2/Makefile [new file with mode: 0644]
board/freescale/imx8qm_arm2/imx8qm_arm2.c [new file with mode: 0644]
configs/imx8qm_lpddr4_arm2_defconfig [new file with mode: 0644]
include/configs/imx8qm_arm2.h [new file with mode: 0644]

index 3acddf3..2e56f24 100644 (file)
@@ -25,4 +25,20 @@ config IMX8QXP
 config SYS_SOC
        default "imx8"
 
+choice
+       prompt "MX8 board select"
+       optional
+
+config TARGET_IMX8QM_LPDDR4_ARM2
+       bool "Support i.MX8QM lpddr4 validation board"
+       select IMX8QM
+
+config TARGET_IMX8QM_DDR4_ARM2
+       bool "Support i.MX8QM ddr4 validation board"
+       select IMX8QM
+
+endchoice
+
+source "board/freescale/imx8qm_arm2/Kconfig"
+
 endif
index da89c23..4ea3218 100644 (file)
@@ -386,6 +386,8 @@ dtb-$(CONFIG_ARCH_MX7ULP) += imx7ulp-evk.dtb \
                imx7ulp-10x10-arm2.dtb \
                imx7ulp-14x14-arm2.dtb
 
+dtb-$(CONFIG_ARCH_IMX8) += fsl-imx8qm-lpddr4-arm2.dtb
+
 dtb-$(CONFIG_SOC_KEYSTONE) += keystone-k2hk-evm.dtb \
        keystone-k2l-evm.dtb \
        keystone-k2e-evm.dtb \
diff --git a/arch/arm/dts/fsl-imx8qm-lpddr4-arm2.dts b/arch/arm/dts/fsl-imx8qm-lpddr4-arm2.dts
new file mode 100644 (file)
index 0000000..27030c0
--- /dev/null
@@ -0,0 +1,415 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/* First 128KB is for PSCI ATF. */
+/memreserve/ 0x80000000 0x00020000;
+
+#include "fsl-imx8qm.dtsi"
+
+/ {
+       model = "Freescale i.MX8QM ARM2";
+       compatible = "fsl,imx8qm-arm2", "fsl,imx8qm";
+
+       chosen {
+               bootargs = "console=ttyLP0,115200 earlycon=lpuart32,0x5a060000,115200";
+               stdout-path = &lpuart0;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_leds>;
+               user {
+                       label = "heartbeat";
+                       gpios = <&gpio2 15 0>;
+                       default-state = "on";
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+};
+
+&iomuxc {
+       imx8qm-arm2 {
+               pinctrl_fec1: fec1grp {
+                       fsl,pins = <
+                               SC_P_ENET0_MDC_CONN_ENET0_MDC                   0x06000048
+                               SC_P_ENET0_MDIO_CONN_ENET0_MDIO                 0x06000048
+                               SC_P_ENET0_RGMII_TX_CTL_CONN_ENET0_RGMII_TX_CTL 0x06000048
+                               SC_P_ENET0_RGMII_TXC_CONN_ENET0_RGMII_TXC       0x06000048
+                               SC_P_ENET0_RGMII_TXD0_CONN_ENET0_RGMII_TXD0     0x06000048
+                               SC_P_ENET0_RGMII_TXD1_CONN_ENET0_RGMII_TXD1     0x06000048
+                               SC_P_ENET0_RGMII_TXD2_CONN_ENET0_RGMII_TXD2     0x06000048
+                               SC_P_ENET0_RGMII_TXD3_CONN_ENET0_RGMII_TXD3     0x06000048
+                               SC_P_ENET0_RGMII_RXC_CONN_ENET0_RGMII_RXC       0x06000048
+                               SC_P_ENET0_RGMII_RX_CTL_CONN_ENET0_RGMII_RX_CTL 0x06000048
+                               SC_P_ENET0_RGMII_RXD0_CONN_ENET0_RGMII_RXD0     0x06000048
+                               SC_P_ENET0_RGMII_RXD1_CONN_ENET0_RGMII_RXD1     0x06000048
+                               SC_P_ENET0_RGMII_RXD2_CONN_ENET0_RGMII_RXD2     0x06000048
+                               SC_P_ENET0_RGMII_RXD3_CONN_ENET0_RGMII_RXD3     0x06000048
+                       >;
+               };
+
+               pinctrl_fec2: fec2grp {
+                       fsl,pins = <
+                               SC_P_ENET1_MDC_CONN_ENET1_MDC                   0x06000048
+                               SC_P_ENET1_MDIO_CONN_ENET1_MDIO                 0x06000048
+                               SC_P_ENET1_RGMII_TX_CTL_CONN_ENET1_RGMII_TX_CTL 0x06000048
+                               SC_P_ENET1_RGMII_TXC_CONN_ENET1_RGMII_TXC       0x06000048
+                               SC_P_ENET1_RGMII_TXD0_CONN_ENET1_RGMII_TXD0     0x06000048
+                               SC_P_ENET1_RGMII_TXD1_CONN_ENET1_RGMII_TXD1     0x06000048
+                               SC_P_ENET1_RGMII_TXD2_CONN_ENET1_RGMII_TXD2     0x06000048
+                               SC_P_ENET1_RGMII_TXD3_CONN_ENET1_RGMII_TXD3     0x06000048
+                               SC_P_ENET1_RGMII_RXC_CONN_ENET1_RGMII_RXC       0x06000048
+                               SC_P_ENET1_RGMII_RX_CTL_CONN_ENET1_RGMII_RX_CTL 0x06000048
+                               SC_P_ENET1_RGMII_RXD0_CONN_ENET1_RGMII_RXD0     0x06000048
+                               SC_P_ENET1_RGMII_RXD1_CONN_ENET1_RGMII_RXD1     0x06000048
+                               SC_P_ENET1_RGMII_RXD2_CONN_ENET1_RGMII_RXD2     0x06000048
+                               SC_P_ENET1_RGMII_RXD3_CONN_ENET1_RGMII_RXD3     0x06000048
+                       >;
+               };
+
+               pinctrl_lpuart0: lpuart0grp {
+                       fsl,pins = <
+                               SC_P_UART0_RX_DMA_UART0_RX              0x0600004c
+                               SC_P_UART0_TX_DMA_UART0_TX              0x0600004c
+                               SC_P_UART0_RTS_B_DMA_UART0_RTS_B        0x0600004c
+                               SC_P_UART0_CTS_B_DMA_UART0_CTS_B        0x0600004c
+                       >;
+               };
+
+               pinctrl_usdhc1: usdhc1grp {
+                       fsl,pins = <
+                               SC_P_EMMC0_CLK_CONN_EMMC0_CLK           0x06000021
+                               SC_P_EMMC0_CMD_CONN_EMMC0_CMD           0x00000021
+                               SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0       0x00000021
+                               SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1       0x00000021
+                               SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2       0x00000021
+                               SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3       0x00000021
+                               SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4       0x00000021
+                               SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5       0x00000021
+                               SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6       0x00000021
+                               SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7       0x00000021
+                               SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B   0x00000021
+                       >;
+               };
+
+               pinctrl_usdhc2: usdhc2grp {
+                       fsl,pins = <
+                               SC_P_USDHC1_CLK_CONN_USDHC1_CLK         0x06000021
+                               SC_P_USDHC1_CMD_CONN_USDHC1_CMD         0x00000021
+                               SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0     0x00000021
+                               SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1     0x00000021
+                               SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2     0x00000021
+                               SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3     0x00000021
+                               SC_P_USDHC1_DATA6_LSIO_GPIO5_IO21       0x00000021
+                               SC_P_USDHC1_DATA7_LSIO_GPIO5_IO22       0x00000021
+                       >;
+               };
+
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <
+                               SC_P_USDHC2_CLK_CONN_USDHC2_CLK         0x06000021
+                               SC_P_USDHC2_CMD_CONN_USDHC2_CMD         0x00000021
+                               SC_P_USDHC2_DATA0_CONN_USDHC2_DATA0     0x00000021
+                               SC_P_USDHC2_DATA1_CONN_USDHC2_DATA1     0x00000021
+                               SC_P_USDHC2_DATA2_CONN_USDHC2_DATA2     0x00000021
+                               SC_P_USDHC2_DATA3_CONN_USDHC2_DATA3     0x00000021
+                               /* WP */
+                               SC_P_USDHC2_WP_LSIO_GPIO4_IO11          0x00000021
+                               /* CD */
+                               SC_P_USDHC2_CD_B_LSIO_GPIO4_IO12        0x00000021
+                       >;
+               };
+
+               pinctrl_lpi2c1: lpi2c1grp {
+                       fsl,pins = <
+                               SC_P_GPT0_CLK_DMA_I2C1_SCL              0x06000020
+                               SC_P_GPT0_CAPTURE_DMA_I2C1_SDA          0x06000020
+                               /*
+                                * Change the default alt function from SCL/SDA to others,
+                                * to avoid select input conflict with GPT0
+                                */
+                               SC_P_USB_SS3_TC0_LSIO_GPIO4_IO03        0x0700004c
+                               SC_P_USB_SS3_TC1_LSIO_GPIO4_IO04        0x0700004c
+                               SC_P_USB_SS3_TC2_LSIO_GPIO4_IO05        0x0700004c
+                               SC_P_USB_SS3_TC3_LSIO_GPIO4_IO06        0x0700004c
+                       >;
+               };
+
+               pinctrl_lpspi0: lpspi0grp {
+                       fsl,pins = <
+                               SC_P_SPI0_SCK_DMA_SPI0_SCK              0x0600004c
+                               SC_P_SPI0_SDO_DMA_SPI0_SDO              0x0600004c
+                               SC_P_SPI0_SDI_DMA_SPI0_SDI              0x0600004c
+                               SC_P_SPI0_CS0_DMA_SPI0_CS0              0x0600004c
+                               SC_P_SPI0_CS1_DMA_SPI0_CS1              0x0600004c
+                       >;
+               };
+
+               pinctrl_flexspi0: flexspi0grp {
+                       fsl,pins = <
+                               SC_P_QSPI0A_DATA0_LSIO_QSPI0A_DATA0     0x0600004c
+                               SC_P_QSPI0A_DATA1_LSIO_QSPI0A_DATA1     0x0600004c
+                               SC_P_QSPI0A_DATA2_LSIO_QSPI0A_DATA2     0x0600004c
+                               SC_P_QSPI0A_DATA3_LSIO_QSPI0A_DATA3     0x0600004c
+                               SC_P_QSPI0A_DQS_LSIO_QSPI0A_DQS         0x0600004c
+                               SC_P_QSPI0A_SS0_B_LSIO_QSPI0A_SS0_B     0x0600004c
+                               SC_P_QSPI0A_SS1_B_LSIO_QSPI0A_SS1_B     0x0600004c
+                               SC_P_QSPI0A_SCLK_LSIO_QSPI0A_SCLK       0x0600004c
+                               SC_P_QSPI0B_SCLK_LSIO_QSPI0B_SCLK       0x0600004c
+                               SC_P_QSPI0B_DATA0_LSIO_QSPI0B_DATA0     0x0600004c
+                               SC_P_QSPI0B_DATA1_LSIO_QSPI0B_DATA1     0x0600004c
+                               SC_P_QSPI0B_DATA2_LSIO_QSPI0B_DATA2     0x0600004c
+                               SC_P_QSPI0B_DATA3_LSIO_QSPI0B_DATA3     0x0600004c
+                               SC_P_QSPI0B_DQS_LSIO_QSPI0B_DQS         0x0600004c
+                               SC_P_QSPI0B_SS0_B_LSIO_QSPI0B_SS0_B     0x0600004c
+                               SC_P_QSPI0B_SS1_B_LSIO_QSPI0B_SS1_B     0x0600004c
+                       >;
+               };
+
+               pinctrl_gpio_leds: gpioledsgrp {
+                       fsl,pins = <
+                               SC_P_SPDIF0_TX_LSIO_GPIO2_IO15          0x00000021
+                       >;
+               };
+       };
+};
+
+&gpio2 {
+       status = "okay";
+};
+
+&gpio4 {
+       status = "okay";
+};
+
+&gpio5 {
+       status = "okay";
+};
+
+&framebuffer1 {
+       status = "okay";
+};
+
+&framebuffer3 {
+       status = "okay";
+};
+
+&imxdpu0 {
+       status = "okay";
+};
+
+&imxdpu1 {
+       status = "okay";
+};
+
+&lvds0 {
+       status = "okay";
+};
+
+&lvds1 {
+       status = "okay";
+};
+
+&usdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       bus-width = <8>;
+       non-removable;
+       status = "okay";
+};
+
+&usdhc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       bus-width = <4>;
+       cd-gpios = <&gpio5 22 GPIO_ACTIVE_LOW>;
+       wp-gpios = <&gpio5 21 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       bus-width = <4>;
+       cd-gpios = <&gpio4 12 GPIO_ACTIVE_LOW>;
+       wp-gpios = <&gpio4 11 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+
+};
+
+&usbotg1 {
+       srp-disable;
+       hnp-disable;
+       adp-disable;
+       disable-over-current;
+       status = "okay";
+};
+
+&fec1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec1>;
+       phy-mode = "rgmii";
+       phy-handle = <&ethphy0>;
+       fsl,ar8031-phy-fixup;
+       fsl,magic-packet;
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy0: ethernet-phy@0 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       reg = <0>;
+               };
+
+               ethphy1: ethernet-phy@1 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       reg = <1>;
+               };
+       };
+};
+
+&fec2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec2>;
+       phy-mode = "rgmii";
+       phy-handle = <&ethphy1>;
+       fsl,ar8031-phy-fixup;
+       fsl,magic-packet;
+       status = "disabled";
+};
+
+&flexspi0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexspi0>;
+       status = "okay";
+
+       flash0: mt35xu512aba@0 {
+               reg = <0>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "spi-flash";
+               spi-max-frequency = <29000000>;
+               spi-nor,ddr-quad-read-dummy = <8>;
+       };
+};
+
+&i2c1 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lpi2c1>;
+       status = "okay";
+
+       pca9557_a: gpio@18 {
+               compatible = "nxp,pca9557";
+               reg = <0x18>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       pca9557_b: gpio@19 {
+               compatible = "nxp,pca9557";
+               reg = <0x19>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       pca9557_c: gpio@1b {
+               compatible = "nxp,pca9557";
+               reg = <0x1b>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       pca9557_d: gpio@1f {
+               compatible = "nxp,pca9557";
+               reg = <0x1f>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+};
+
+&i2c1_lvds0 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       pinctrl-names = "default";
+       clock-frequency = <100000>;
+       status = "okay";
+
+       it6263-0@4c {
+               compatible = "ITE,it6263";
+               reg = <0x4c>;
+       };
+};
+
+&i2c1_lvds1 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       pinctrl-names = "default";
+       clock-frequency = <100000>;
+       status = "okay";
+
+       it6263-1@4c {
+               compatible = "ITE,it6263";
+               reg = <0x4c>;
+       };
+};
+
+&lpspi0 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lpspi0>;
+       status = "okay";
+
+       spidev0: spi@0 {
+               reg = <0>;
+               compatible = "rohm,dh2228fv";
+               spi-max-frequency = <4000000>;
+       };
+};
+
+&lpuart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lpuart0>;
+       status = "okay";
+};
+
+&lpuart1 {
+       status = "okay";
+};
+
+&A53_0 {
+       operating-points = <
+               /* kHz    uV */
+               1296000 1150000
+       >;
+       clocks = <&clk IMX8QM_A53_DIV>;
+};
+
+&A72_0 {
+       operating-points = <
+               /* kHz    uV */
+               1800000 1150000
+       >;
+       clocks = <&clk IMX8QM_A72_DIV>;
+};
diff --git a/board/freescale/imx8qm_arm2/Kconfig b/board/freescale/imx8qm_arm2/Kconfig
new file mode 100644 (file)
index 0000000..3e2ca25
--- /dev/null
@@ -0,0 +1,12 @@
+if TARGET_IMX8QM_LPDDR4_ARM2 || TARGET_IMX8QM_DDR4_ARM2
+
+config SYS_BOARD
+       default "imx8qm_arm2"
+
+config SYS_VENDOR
+       default "freescale"
+
+config SYS_CONFIG_NAME
+       default "imx8qm_arm2"
+
+endif
diff --git a/board/freescale/imx8qm_arm2/Makefile b/board/freescale/imx8qm_arm2/Makefile
new file mode 100644 (file)
index 0000000..b8bf8e4
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Copyright 2017 NXP
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y += imx8qm_arm2.o
diff --git a/board/freescale/imx8qm_arm2/imx8qm_arm2.c b/board/freescale/imx8qm_arm2/imx8qm_arm2.c
new file mode 100644 (file)
index 0000000..e0a65b5
--- /dev/null
@@ -0,0 +1,712 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#include <common.h>
+#include <malloc.h>
+#include <errno.h>
+#include <netdev.h>
+#include <fsl_ifc.h>
+#include <fdt_support.h>
+#include <libfdt.h>
+#include <environment.h>
+#include <fsl_esdhc.h>
+#include <i2c.h>
+#include "pca953x.h"
+
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/arch/clock.h>
+#include <asm/imx-common/sci/sci.h>
+#include <asm/arch/imx8-pins.h>
+#include <dm.h>
+#include <imx8_hsio.h>
+#include <usb.h>
+#include <asm/arch/iomux.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define ESDHC_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \
+                                               | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
+
+#define ESDHC_CLK_PAD_CTRL     ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \
+                                               | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
+
+
+#define ENET_INPUT_PAD_CTRL    ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \
+                                               | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
+
+#define ENET_NORMAL_PAD_CTRL   ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \
+                                               | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
+
+#define FSPI_PAD_CTRL  ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \
+                                               | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
+
+#define GPIO_PAD_CTRL  ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \
+                                               | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
+
+#define I2C_PAD_CTRL   ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \
+                                               | (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
+
+#define UART_PAD_CTRL  ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \
+                                               | (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT))
+
+static iomux_cfg_t uart0_pads[] = {
+       SC_P_UART0_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
+       SC_P_UART0_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
+};
+
+static void setup_iomux_uart(void)
+{
+       imx8_iomux_setup_multiple_pads(uart0_pads, ARRAY_SIZE(uart0_pads));
+}
+
+int board_early_init_f(void)
+{
+       sc_ipc_t ipcHndl = 0;
+       sc_err_t sciErr = 0;
+
+       ipcHndl = gd->arch.ipc_channel_handle;
+
+       /* Power up the GPT */
+       sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_GPT_0, SC_PM_PW_MODE_ON);
+       if (sciErr != SC_ERR_NONE)
+               return 0;
+
+       /* Set GPT clock root to 24 MHz */
+       sc_pm_clock_rate_t gpt_rate = 24000000;
+       sciErr = sc_pm_set_clock_rate(ipcHndl, SC_R_GPT_0, SC_PM_CLK_PER, &gpt_rate);
+       if (sciErr != SC_ERR_NONE)
+               return 0;
+
+       /* Enable GPT clock root */
+       sciErr = sc_pm_clock_enable(ipcHndl, SC_R_GPT_0, SC_PM_CLK_PER, true, false);
+       if (sciErr != SC_ERR_NONE)
+               return 0;
+
+       /* Power up UART0 */
+       sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_UART_0, SC_PM_PW_MODE_ON);
+       if (sciErr != SC_ERR_NONE)
+               return 0;
+
+       /* Set UART0 clock root to 80 MHz */
+       sc_pm_clock_rate_t rate = 80000000;
+       sciErr = sc_pm_set_clock_rate(ipcHndl, SC_R_UART_0, 2, &rate);
+       if (sciErr != SC_ERR_NONE)
+               return 0;
+
+       /* Enable UART0 clock root */
+       sciErr = sc_pm_clock_enable(ipcHndl, SC_R_UART_0, 2, true, false);
+       if (sciErr != SC_ERR_NONE)
+               return 0;
+
+       setup_iomux_uart();
+
+       return 0;
+}
+
+#ifdef CONFIG_SYS_I2C_IMX_LPI2C
+static iomux_cfg_t lpi2c1_pads[] = {
+       SC_P_GPT0_CLK | MUX_MODE_ALT(1) | MUX_PAD_CTRL(I2C_PAD_CTRL),
+       SC_P_GPT0_CAPTURE | MUX_MODE_ALT(1) | MUX_PAD_CTRL(I2C_PAD_CTRL),
+
+       /* Change the default alt function from SCL/SDA to others, to avoid select input conflict with GPT0 */
+       SC_P_USB_SS3_TC0 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPIO_PAD_CTRL), /* Set ALT to OTG1 PWR*/
+       SC_P_USB_SS3_TC1 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), /* Set ALT to GPIO */
+       SC_P_USB_SS3_TC2 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPIO_PAD_CTRL), /* Set ALT to OTG1 OC */
+       SC_P_USB_SS3_TC3 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), /* Set ALT to GPIO */
+};
+
+static iomux_cfg_t lpi2c2_pads[] = {
+       SC_P_GPT1_CLK | MUX_MODE_ALT(1) | MUX_PAD_CTRL(I2C_PAD_CTRL),
+       SC_P_GPT1_CAPTURE | MUX_MODE_ALT(1) | MUX_PAD_CTRL(I2C_PAD_CTRL),
+};
+
+static iomux_cfg_t lpi2c4_pads[] = {
+       SC_P_ENET1_MDC  | MUX_MODE_ALT(1) | MUX_PAD_CTRL(I2C_PAD_CTRL),
+       SC_P_ENET1_MDIO | MUX_MODE_ALT(1) | MUX_PAD_CTRL(I2C_PAD_CTRL),
+};
+
+static iomux_cfg_t lvds0_lipi2c1_pads[] = {
+       SC_P_LVDS0_I2C1_SCL | MUX_MODE_ALT(0) | MUX_PAD_CTRL(I2C_PAD_CTRL),
+       SC_P_LVDS0_I2C1_SDA | MUX_MODE_ALT(0) | MUX_PAD_CTRL(I2C_PAD_CTRL),
+};
+
+static iomux_cfg_t lvds1_lipi2c1_pads[] = {
+       SC_P_LVDS1_I2C1_SCL | MUX_MODE_ALT(0) | MUX_PAD_CTRL(I2C_PAD_CTRL),
+       SC_P_LVDS1_I2C1_SDA | MUX_MODE_ALT(0) | MUX_PAD_CTRL(I2C_PAD_CTRL),
+};
+
+void i2c_init_board(void)
+{
+       imx8_iomux_setup_multiple_pads(lpi2c1_pads, ARRAY_SIZE(lpi2c1_pads));
+       imx8_iomux_setup_multiple_pads(lpi2c2_pads, ARRAY_SIZE(lpi2c2_pads));
+       imx8_iomux_setup_multiple_pads(lpi2c4_pads, ARRAY_SIZE(lpi2c4_pads));
+       imx8_iomux_setup_multiple_pads(lvds0_lipi2c1_pads, ARRAY_SIZE(lvds0_lipi2c1_pads));
+       imx8_iomux_setup_multiple_pads(lvds1_lipi2c1_pads, ARRAY_SIZE(lvds1_lipi2c1_pads));
+}
+#endif
+
+#ifdef CONFIG_FSL_ESDHC
+
+#define USDHC1_CD_GPIO IMX_GPIO_NR(5, 22)
+#define USDHC2_CD_GPIO IMX_GPIO_NR(4, 12)
+
+static struct fsl_esdhc_cfg usdhc_cfg[CONFIG_SYS_FSL_USDHC_NUM] = {
+#ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2
+       {USDHC1_BASE_ADDR, 0, 8},
+#endif
+       {USDHC2_BASE_ADDR, 0, 4},
+       {USDHC3_BASE_ADDR, 0, 4},
+};
+
+#ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2
+static iomux_cfg_t emmc0[] = {
+       SC_P_EMMC0_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL),
+       SC_P_EMMC0_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_EMMC0_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_EMMC0_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_EMMC0_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_EMMC0_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_EMMC0_DATA4 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_EMMC0_DATA5 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_EMMC0_DATA6 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_EMMC0_DATA7 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_EMMC0_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_EMMC0_STROBE | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+};
+#endif
+
+static iomux_cfg_t usdhc1_sd[] = {
+       SC_P_USDHC1_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL),
+       SC_P_USDHC1_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_USDHC1_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_USDHC1_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_USDHC1_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_USDHC1_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_USDHC1_DATA6 | MUX_MODE_ALT(2) | MUX_PAD_CTRL(ESDHC_PAD_CTRL), /* Mux for WP */
+       SC_P_USDHC1_DATA7 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ESDHC_PAD_CTRL), /* Mux for CD,  GPIO5 IO22 */
+       SC_P_USDHC1_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_USDHC1_VSELECT | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+};
+
+static iomux_cfg_t usdhc2_sd[] = {
+       SC_P_USDHC2_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL),
+       SC_P_USDHC2_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_USDHC2_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_USDHC2_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_USDHC2_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_USDHC2_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_USDHC2_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_USDHC2_WP | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
+       SC_P_USDHC2_CD_B | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ESDHC_PAD_CTRL),      /* Mux to GPIO4 IO12 */
+};
+
+#ifdef CONFIG_DM_MMC
+void setup_mmc(void)
+{
+#ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2
+       imx8_iomux_setup_multiple_pads(emmc0, ARRAY_SIZE(emmc0));
+#endif
+       imx8_iomux_setup_multiple_pads(usdhc1_sd, ARRAY_SIZE(usdhc1_sd));
+       imx8_iomux_setup_multiple_pads(usdhc2_sd, ARRAY_SIZE(usdhc2_sd));
+}
+#endif
+
+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
+        * mmc1                    USDHC2
+        * mmc2                    USDHC3
+        */
+       for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
+               switch (i) {
+#ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2
+               case 0:
+                       imx8_iomux_setup_multiple_pads(emmc0, ARRAY_SIZE(emmc0));
+                       init_clk_usdhc(0);
+                       usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+                       break;
+               case 1:
+#else
+               case 0:
+#endif
+                       imx8_iomux_setup_multiple_pads(usdhc1_sd, ARRAY_SIZE(usdhc1_sd));
+                       init_clk_usdhc(1);
+                       usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
+                       gpio_request(USDHC1_CD_GPIO, "sd1_cd");
+                       gpio_direction_input(USDHC1_CD_GPIO);
+                       break;
+#ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2
+               case 2:
+#else
+               case 1:
+#endif
+                       imx8_iomux_setup_multiple_pads(usdhc2_sd, ARRAY_SIZE(usdhc2_sd));
+                       init_clk_usdhc(2);
+                       usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+                       gpio_request(USDHC2_CD_GPIO, "sd2_cd");
+                       gpio_direction_input(USDHC2_CD_GPIO);
+                       break;
+               default:
+                       printf("Warning: you configured more USDHC controllers"
+                               "(%d) than supported by the board\n", i + 1);
+                       return 0;
+               }
+               ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
+               if (ret) {
+                       printf("Warning: failed to initialize mmc dev %d\n", i);
+                       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:
+               ret = !gpio_get_value(USDHC1_CD_GPIO);
+               break;
+       case USDHC3_BASE_ADDR:
+               ret = !gpio_get_value(USDHC2_CD_GPIO);
+               break;
+       }
+
+       return ret;
+}
+
+#endif /* CONFIG_FSL_ESDHC */
+
+
+#ifdef CONFIG_FEC_MXC
+#include <miiphy.h>
+
+static iomux_cfg_t pad_enet1[] = {
+       SC_P_ENET1_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL),
+       SC_P_ENET1_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL),
+       SC_P_ENET1_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL),
+       SC_P_ENET1_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL),
+       SC_P_ENET1_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL),
+       SC_P_ENET1_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL),
+       SC_P_ENET1_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
+       SC_P_ENET1_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
+       SC_P_ENET1_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
+       SC_P_ENET1_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
+       SC_P_ENET1_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
+       SC_P_ENET1_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
+
+       /* Shared MDIO */
+       SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
+       SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
+};
+
+static iomux_cfg_t pad_enet0[] = {
+       SC_P_ENET0_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL),
+       SC_P_ENET0_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL),
+       SC_P_ENET0_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL),
+       SC_P_ENET0_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL),
+       SC_P_ENET0_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL),
+       SC_P_ENET0_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL),
+       SC_P_ENET0_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
+       SC_P_ENET0_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
+       SC_P_ENET0_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
+       SC_P_ENET0_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
+       SC_P_ENET0_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
+       SC_P_ENET0_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
+
+       /* Shared MDIO */
+       SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
+       SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
+};
+
+static void setup_iomux_fec(void)
+{
+       if (0 == CONFIG_FEC_ENET_DEV)
+               imx8_iomux_setup_multiple_pads(pad_enet0, ARRAY_SIZE(pad_enet0));
+       else
+               imx8_iomux_setup_multiple_pads(pad_enet1, ARRAY_SIZE(pad_enet1));
+}
+
+static void enet_device_phy_reset(void)
+{
+       struct gpio_desc desc;
+       int ret;
+
+       if (0 == CONFIG_FEC_ENET_DEV) {
+               ret = dm_gpio_lookup_name("gpio@18_1", &desc);
+               if (ret)
+                       return;
+
+               ret = dm_gpio_request(&desc, "enet0_reset");
+               if (ret)
+                       return;
+       } else {
+               ret = dm_gpio_lookup_name("gpio@18_4", &desc);
+               if (ret)
+                       return;
+
+               ret = dm_gpio_request(&desc, "enet1_reset");
+               if (ret)
+                       return;
+       }
+
+       dm_gpio_set_dir_flags(&desc, GPIOD_IS_OUT);
+       dm_gpio_set_value(&desc, 0);
+       udelay(50);
+       dm_gpio_set_value(&desc, 1);
+
+       /* The board has a long delay for this reset to become stable */
+       mdelay(200);
+}
+
+int board_eth_init(bd_t *bis)
+{
+       int ret;
+
+       printf("[%s] %d\n", __func__, __LINE__);
+
+       setup_iomux_fec();
+
+       ret = fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV,
+               CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
+       if (ret)
+               printf("FEC1 MXC: %s:failed\n", __func__);
+
+       return ret;
+}
+
+int board_phy_config(struct phy_device *phydev)
+{
+#ifdef CONFIG_FEC_ENABLE_MAX7322
+       uint8_t value;
+
+       /* This is needed to drive the pads to 1.8V instead of 1.5V */
+       i2c_set_bus_num(CONFIG_MAX7322_I2C_BUS);
+
+       if (!i2c_probe(CONFIG_MAX7322_I2C_ADDR)) {
+               /* Write 0x1 to enable O0 output, this device has no addr */
+               /* hence addr length is 0 */
+               value = 0x1;
+               if (i2c_write(CONFIG_MAX7322_I2C_ADDR, 0, 0, &value, 1))
+                       printf("MAX7322 write failed\n");
+       } else {
+               printf("MAX7322 Not found\n");
+       }
+       mdelay(1);
+#endif
+
+       phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f);
+       phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8);
+
+       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;
+}
+
+static int setup_fec(int ind)
+{
+       sc_err_t err;
+       sc_ipc_t ipc;
+       sc_pm_clock_rate_t rate = 24000000;
+       sc_rsrc_t enet[2] = {SC_R_ENET_0, SC_R_ENET_1};
+
+       if (ind > 1)
+               return -EINVAL;
+
+       ipc = gd->arch.ipc_channel_handle;
+       /* Power on ENET, notify if SCI error occurred */
+       err = sc_pm_set_resource_power_mode(ipc, enet[ind], SC_PM_PW_MODE_ON);
+       if (err != SC_ERR_NONE) {
+               printf("\nSC_R_ENET_0 Power up failed! (error = %d)\n", err);
+               return -EIO;
+       }
+
+       /* Disable SC_R_ENET_0 clock root */
+       err = sc_pm_clock_enable(ipc, enet[ind], 0, false, false);
+       err |= sc_pm_clock_enable(ipc, enet[ind], 2, false, false);
+       err |= sc_pm_clock_enable(ipc, enet[ind], 4, false, false);
+       if (err != SC_ERR_NONE) {
+               printf("\nSC_R_ENET_0 set clock disable failed! (error = %d)\n", err);
+               return -EIO;
+       }
+
+       /* Set SC_R_ENET_0 clock root to 125 MHz */
+       rate = 125000000;
+
+       /* div = 8 clk_source = PLL_1 ss_slice #7 in verfication codes */
+       err = sc_pm_set_clock_rate(ipc, enet[ind], 2, &rate);
+       if (err != SC_ERR_NONE) {
+               printf("\nSC_R_ENET_0 set clock ref clock 125M failed! (error = %d)\n", err);
+               return -EIO;
+       }
+
+       /* Enable SC_R_ENET_0 clock root */
+       err = sc_pm_clock_enable(ipc, enet[ind], 0, true, true);
+       err |= sc_pm_clock_enable(ipc, enet[ind], 2, true, true);
+       err |= sc_pm_clock_enable(ipc, enet[ind], 4, true, true);
+       if (err != SC_ERR_NONE) {
+               printf("\nSC_R_ENET_0 set clock enable failed! (error = %d)\n", err);
+               return -EIO;
+       }
+
+       /* Reset ENET PHY */
+       enet_device_phy_reset();
+
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_FSL_FSPI
+static iomux_cfg_t pad_fspi[] = {
+       SC_P_QSPI0A_DATA0 | MUX_PAD_CTRL(FSPI_PAD_CTRL),
+    SC_P_QSPI0A_DATA1 | MUX_PAD_CTRL(FSPI_PAD_CTRL),
+    SC_P_QSPI0A_DATA2 | MUX_PAD_CTRL(FSPI_PAD_CTRL),
+    SC_P_QSPI0A_DATA3 | MUX_PAD_CTRL(FSPI_PAD_CTRL),
+    SC_P_QSPI0A_DQS | MUX_PAD_CTRL(FSPI_PAD_CTRL),
+    SC_P_QSPI0A_SS0_B | MUX_PAD_CTRL(FSPI_PAD_CTRL),
+    SC_P_QSPI0A_SCLK | MUX_PAD_CTRL(FSPI_PAD_CTRL),
+    SC_P_QSPI0B_DATA0 | MUX_PAD_CTRL(FSPI_PAD_CTRL),
+    SC_P_QSPI0B_DATA1 | MUX_PAD_CTRL(FSPI_PAD_CTRL),
+    SC_P_QSPI0B_DATA2 | MUX_PAD_CTRL(FSPI_PAD_CTRL),
+    SC_P_QSPI0B_DATA3 | MUX_PAD_CTRL(FSPI_PAD_CTRL),
+};
+
+void board_fspi_init(void)
+{
+       sc_err_t sciErr = 0;
+       sc_pm_clock_rate_t rate;
+       sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle;
+
+       /* Power up the FSPI0*/
+       sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_FSPI_0, SC_PM_PW_MODE_ON);
+       if (sciErr != SC_ERR_NONE) {
+               puts("FSPI0 power up failed\n");
+               return;
+       }
+
+       /* Set FSPI0 clock root to 29 MHz */
+       rate = 29000000;
+       sciErr = sc_pm_set_clock_rate(ipcHndl, SC_R_FSPI_0, SC_PM_CLK_PER, &rate);
+       if (sciErr != SC_ERR_NONE) {
+               puts("FSPI0 setrate failed\n");
+               return;
+       }
+
+       /* Enable FSPI0 clock root */
+       sciErr = sc_pm_clock_enable(ipcHndl, SC_R_FSPI_0, SC_PM_CLK_PER, true, false);
+       if (sciErr != SC_ERR_NONE) {
+               puts("FSPI0 enable clock failed\n");
+               return;
+       }
+
+       imx8_iomux_setup_multiple_pads(pad_fspi, ARRAY_SIZE(pad_fspi));
+
+}
+#endif
+
+#ifdef CONFIG_MXC_GPIO
+
+#define DEBUG_LED   IMX_GPIO_NR(2, 15)
+#define IOEXP_RESET IMX_GPIO_NR(1, 12)
+
+static iomux_cfg_t board_gpios[] = {
+       SC_P_LVDS1_I2C0_SCL | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL),
+       SC_P_SPDIF0_TX | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL),
+};
+
+static void setup_gpio(void)
+{
+       sc_err_t err;
+       sc_ipc_t ipc;
+       u32 i;
+
+       ipc = gd->arch.ipc_channel_handle;
+
+       /* Power up all GPIOs */
+       for (i = 0; i < 8; i++) {
+               err = sc_pm_set_resource_power_mode(ipc, SC_R_GPIO_0 + i, SC_PM_PW_MODE_ON);
+               if (err != SC_ERR_NONE)
+                       printf("gpio_%u powerup error\n", i);
+       }
+}
+
+static void board_gpio_init(void)
+{
+       setup_gpio();
+
+       imx8_iomux_setup_multiple_pads(board_gpios, ARRAY_SIZE(board_gpios));
+
+       gpio_request(DEBUG_LED, "debug_led");
+       gpio_direction_output(DEBUG_LED, 1);
+
+       /* enable i2c port expander assert reset line */
+       gpio_request(IOEXP_RESET, "ioexp_rst");
+       gpio_direction_output(IOEXP_RESET, 1);
+}
+#endif
+
+int checkboard(void)
+{
+#ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2
+       puts("Board: iMX8QM LPDDR4 ARM2\n");
+#else
+       puts("Board: iMX8QM DDR4 ARM2\n");
+#endif
+
+       /* Note:  After reloc, ipcHndl will no longer be valid.  If handle
+        *        returned by sc_ipc_open matches SC_IPC_CH, use this
+        *        macro (valid after reloc) for subsequent SCI calls.
+        */
+       if (gd->arch.ipc_channel_handle != SC_IPC_CH) {
+               printf("\nSCI error! Invalid handle\n");
+       }
+
+#ifdef SCI_FORCE_ABORT
+       sc_rpc_msg_t abort_msg;
+
+       puts("Send abort request\n");
+       RPC_SIZE(&abort_msg) = 1;
+       RPC_SVC(&abort_msg) = SC_RPC_SVC_ABORT;
+       sc_ipc_write(SC_IPC_CH, &abort_msg);
+
+       /* Close IPC channel */
+       sc_ipc_close(SC_IPC_CH);
+#endif /* SCI_FORCE_ABORT */
+
+       return 0;
+}
+
+#ifdef CONFIG_FSL_HSIO
+
+#define PCIE_PAD_CTRL  ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT))
+static iomux_cfg_t board_pcie_pins[] = {
+       SC_P_PCIE_CTRL0_CLKREQ_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL),
+       SC_P_PCIE_CTRL0_WAKE_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL),
+       SC_P_PCIE_CTRL0_PERST_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL),
+};
+
+static void imx8qm_hsio_initialize(void)
+{
+       sc_err_t err;
+       sc_ipc_t ipc;
+
+       ipc = gd->arch.ipc_channel_handle;
+
+       err = sc_pm_set_resource_power_mode(ipc, SC_R_SERDES_0, SC_PM_PW_MODE_ON);
+       err |= sc_pm_set_resource_power_mode(ipc, SC_R_SERDES_1, SC_PM_PW_MODE_ON);
+       if (err != SC_ERR_NONE)
+               printf("\nSC_R_SERDES_0 Power up failed! (error = %d)\n", err);
+
+       err = sc_pm_set_resource_power_mode(ipc, SC_R_SATA_0, SC_PM_PW_MODE_ON);
+       if (err != SC_ERR_NONE)
+               printf("\nSC_R_SATA_0 Power up failed! (error = %d)\n", err);
+
+       err = sc_pm_set_resource_power_mode(ipc, SC_R_PCIE_A, SC_PM_PW_MODE_ON);
+       err |= sc_pm_set_resource_power_mode(ipc, SC_R_PCIE_B, SC_PM_PW_MODE_ON);
+       if (err != SC_ERR_NONE)
+               printf("\nSC_R_PCIE_A/B Power up failed! (error = %d)\n", err);
+
+       imx8_iomux_setup_multiple_pads(board_pcie_pins, ARRAY_SIZE(board_pcie_pins));
+
+}
+
+void pci_init_board(void)
+{
+       /* test the 1 lane mode of the PCIe A controller */
+       mx8qm_pcie_init();
+}
+#endif
+
+int board_init(void)
+{
+#ifdef CONFIG_MXC_GPIO
+       board_gpio_init();
+#endif
+
+#ifdef CONFIG_SYS_I2C_IMX_LPI2C
+       i2c_init_board();
+#endif
+
+#ifdef CONFIG_FEC_MXC
+       setup_fec(CONFIG_FEC_ENET_DEV);
+       setup_iomux_fec();
+#endif
+
+#ifdef CONFIG_FSL_FSPI
+       board_fspi_init();
+#endif
+
+#ifdef CONFIG_FSL_HSIO
+       imx8qm_hsio_initialize();
+#ifdef CONFIG_SCSI_AHCI_PLAT
+       sata_init();
+#endif
+#endif
+
+#ifdef CONFIG_DM_MMC
+       setup_mmc();
+#endif
+
+       return 0;
+}
+
+void detail_board_ddr_info(void)
+{
+       puts("\nDDR    ");
+}
+
+phys_size_t get_effective_memsize(void)
+{
+       return PHYS_SDRAM_1_SIZE;
+}
+
+int dram_init(void)
+{
+       gd->ram_size = PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE;
+
+       return 0;
+}
+
+void dram_init_banksize(void)
+{
+       gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+       gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+       gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+       gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
+}
+
+/*
+ * Board specific reset that is system reset.
+ */
+void reset_cpu(ulong addr)
+{
+       puts("SCI reboot request");
+       sc_pm_reboot(SC_IPC_CH, SC_PM_RESET_TYPE_COLD);
+       while (1)
+               putc('.');
+}
+
+#ifdef CONFIG_OF_BOARD_SETUP
+int ft_board_setup(void *blob, bd_t *bd)
+{
+       return 0;
+}
+#endif
diff --git a/configs/imx8qm_lpddr4_arm2_defconfig b/configs/imx8qm_lpddr4_arm2_defconfig
new file mode 100644 (file)
index 0000000..93722d4
--- /dev/null
@@ -0,0 +1,40 @@
+CONFIG_ARM=y
+CONFIG_ARCH_IMX8=y
+CONFIG_DEFAULT_DEVICE_TREE="fsl-imx8qm-lpddr4-arm2"
+CONFIG_TARGET_IMX8QM_LPDDR4_ARM2=y
+CONFIG_CMD_IMPORTENV=n
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_DM=y
+
+CONFIG_DM_SERIAL=y
+CONFIG_FSL_LPUART=y
+CONFIG_OF_CONTROL=y
+CONFIG_DM_I2C=y
+# CONFIG_DM_I2C_COMPAT is not set
+CONFIG_SYS_I2C_IMX_LPI2C=y
+CONFIG_CMD_I2C=y
+# CONFIG_CMD_USB is not set
+# CONFIG_USB is not set
+CONFIG_CMD_GPIO=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_PCA953X=y
+CONFIG_BOOTDELAY=3
+CONFIG_IMX_BOOTAUX=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_MMC=y
+CONFIG_DM_MMC=y
+# CONFIG_BLK is not set
+# CONFIG_DM_MMC_OPS is not set
+CONFIG_FSL_FSPI=y
+CONFIG_DM_SPI=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_CMD_SF=y
+
+CONFIG_CMD_PING=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_DM_ETH=y
+# CONFIG_EFI_LOADER is not set
diff --git a/include/configs/imx8qm_arm2.h b/include/configs/imx8qm_arm2.h
new file mode 100644 (file)
index 0000000..d70cb96
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __IMX8QM_ARM2_H
+#define __IMX8QM_ARM2_H
+
+#include <linux/sizes.h>
+#include <asm/arch/imx-regs.h>
+
+#define CONFIG_REMAKE_ELF
+
+#define CONFIG_BOARD_EARLY_INIT_F
+
+/* Flat Device Tree Definitions */
+#define CONFIG_OF_BOARD_SETUP
+
+#undef CONFIG_CMD_EXPORTENV
+#undef CONFIG_CMD_IMPORTENV
+#undef CONFIG_CMD_IMLS
+
+#undef CONFIG_CMD_CRC32
+#undef CONFIG_BOOTM_NETBSD
+
+#define CONFIG_FSL_ESDHC
+#define CONFIG_FSL_USDHC
+#define CONFIG_SYS_FSL_ESDHC_ADDR       0
+#define USDHC1_BASE_ADDR                0x5B010000
+#define USDHC2_BASE_ADDR                0x5B020000
+#define USDHC3_BASE_ADDR                0x5B030000
+#define CONFIG_SUPPORT_EMMC_BOOT       /* eMMC specific */
+
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_SCSI
+#define CONFIG_SCSI_AHCI
+#define CONFIG_SCSI_AHCI_PLAT
+#define CONFIG_SYS_SCSI_MAX_SCSI_ID 1
+#define CONFIG_CMD_SCSI
+#define CONFIG_LIBATA
+#define CONFIG_SYS_SCSI_MAX_LUN 1
+#define CONFIG_SYS_SCSI_MAX_DEVICE      (CONFIG_SYS_SCSI_MAX_SCSI_ID * CONFIG_SYS_SCSI_MAX_LUN)
+#define CONFIG_SYS_SCSI_MAXDEVICE       CONFIG_SYS_SCSI_MAX_DEVICE
+#define CONFIG_SYS_SATA_MAX_DEVICE     1
+#define CONFIG_SATA_IMX
+
+#define CONFIG_FSL_HSIO
+#define CONFIG_PCIE_IMX8X
+#define CONFIG_CMD_PCI
+#define CONFIG_PCI
+#define CONFIG_PCI_PNP
+#define CONFIG_PCI_SCAN_SHOW
+
+/* FUSE command */
+#define CONFIG_CMD_FUSE
+
+/* GPIO configs */
+#define CONFIG_MXC_GPIO
+
+/* ENET Config */
+#define CONFIG_MII
+
+#define CONFIG_FEC_MXC
+#define CONFIG_FEC_XCV_TYPE             RGMII
+#define FEC_QUIRK_ENET_MAC
+
+#define CONFIG_PHY_GIGE /* Support for 1000BASE-X */
+#define CONFIG_PHYLIB
+#define CONFIG_PHY_ATHEROS
+
+/* ENET0 connects AR8031 on CPU board, ENET1 connects to base board */
+#define CONFIG_FEC_ENET_DEV 0
+
+#if (CONFIG_FEC_ENET_DEV == 0)
+#define IMX_FEC_BASE                   0x5B040000
+#define CONFIG_FEC_MXC_PHYADDR          0x0
+#define CONFIG_ETHPRIME                 "eth0"
+#elif (CONFIG_FEC_ENET_DEV == 1)
+#define IMX_FEC_BASE                   0x5B050000
+#define CONFIG_FEC_MXC_PHYADDR          0x1
+#define CONFIG_FEC_ENABLE_MAX7322
+#define CONFIG_ETHPRIME                 "eth1"
+#endif
+
+/* ENET0 MDIO are shared */
+#define CONFIG_FEC_MXC_MDIO_BASE       0x5B040000
+
+/* MAX7322 */
+#ifdef CONFIG_FEC_ENABLE_MAX7322
+#define CONFIG_MAX7322_I2C_ADDR                0x68
+#define CONFIG_MAX7322_I2C_BUS         2 /* I2C2 */
+#endif
+
+/* Boot M4 */
+#define M4_BOOT_ENV \
+       "m4_0_image=m4_0.bin\0" \
+       "m4_1_image=m4_1.bin\0" \
+       "loadm4image_0=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${m4_0_image}\0" \
+       "loadm4image_1=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${m4_1_image}\0" \
+       "m4boot_0=run loadm4image_0; bootaux ${loadaddr} 0\0" \
+       "m4boot_1=run loadm4image_1; bootaux ${loadaddr} 1\0" \
+
+/* Initial environment variables */
+#define CONFIG_EXTRA_ENV_SETTINGS              \
+       M4_BOOT_ENV \
+       "script=boot.scr\0" \
+       "image=Image\0" \
+       "mmcdev=1\0"\
+       "console=ttyLP0,115200 earlycon=lpuart32,0x5a060000,115200\0" \
+       "fdtaddr=0x83000000\0"                  \
+       "fdt_high=0xffffffffffffffff\0"         \
+       "boot_fdt=try\0" \
+       "fdt_file=fsl-imx8qm-lpddr4-arm2.dtb\0" \
+       "initrd_addr=0x83800000\0"              \
+       "initrd_high=0xffffffffffffffff\0" \
+       "mmcdev="__stringify(CONFIG_SYS_MMC_ENV_DEV)"\0" \
+       "mmcpart=" __stringify(CONFIG_SYS_MMC_IMG_LOAD_PART) "\0" \
+       "mmcroot=" CONFIG_MMCROOT " rootwait rw\0" \
+       "mmcautodetect=yes\0" \
+       "mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot} " \
+       "video=imxdpufb5:off video=imxdpufb6:off video=imxdpufb7:off\0" \
+       "loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
+       "bootscript=echo Running bootscript from mmc ...; " \
+               "source\0" \
+       "loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \
+       "loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdtaddr} ${fdt_file}\0" \
+       "mmcboot=echo Booting from mmc ...; " \
+               "run mmcargs; " \
+               "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
+                       "if run loadfdt; then " \
+                               "booti ${loadaddr} - ${fdtaddr}; " \
+                       "else " \
+                               "echo WARN: Cannot load the DT; " \
+                       "fi; " \
+               "else " \
+                       "echo wait for boot; " \
+               "fi;\0" \
+       "netargs=setenv bootargs console=${console} " \
+               "root=/dev/nfs " \
+               "ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp " \
+               "video=imxdpufb5:off video=imxdpufb6:off video=imxdpufb7:off\0" \
+       "netboot=echo Booting from net ...; " \
+               "run netargs;  " \
+               "if test ${ip_dyn} = yes; then " \
+                       "setenv get_cmd dhcp; " \
+               "else " \
+                       "setenv get_cmd tftp; " \
+               "fi; " \
+               "${get_cmd} ${loadaddr} ${image}; " \
+               "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
+                       "if ${get_cmd} ${fdtaddr} ${fdt_file}; then " \
+                               "booti ${loadaddr} - ${fdtaddr}; " \
+                       "else " \
+                               "echo WARN: Cannot load the DT; " \
+                       "fi; " \
+               "else " \
+                       "booti; " \
+               "fi;\0"
+
+#define CONFIG_BOOTCOMMAND \
+          "mmc dev ${mmcdev}; if mmc rescan; then " \
+                  "if run loadbootscript; then " \
+                          "run bootscript; " \
+                  "else " \
+                          "if run loadimage; then " \
+                                  "run mmcboot; " \
+                          "else booti ${loadaddr} - ${fdtaddr}; " \
+                          "fi; " \
+                  "fi; " \
+          "else booti ${loadaddr} - ${fdtaddr}; fi"
+
+/* Link Definitions */
+#define CONFIG_LOADADDR                        0x80080000
+#define CONFIG_SYS_TEXT_BASE           0x80020000
+
+#define CONFIG_SYS_LOAD_ADDR           CONFIG_LOADADDR
+
+#define CONFIG_SYS_INIT_SP_ADDR         0x90000000
+
+
+/* Default environment is in SD */
+#define CONFIG_ENV_OFFSET       (14 * SZ_64K)
+#define CONFIG_ENV_SIZE                        0x1000
+#define CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_IMG_LOAD_PART   1
+#define CONFIG_SYS_MMC_ENV_PART                0       /* user area */
+
+/* On LPDDR4 board, USDHC1 is for eMMC, USDHC2 is for SD on CPU board, USDHC3 is for SD on base board
+  * On DDR4 board, USDHC1 is mux for NAND, USDHC2 is for SD, USDHC3 is for SD on base board
+  */
+#ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2
+#define CONFIG_SYS_MMC_ENV_DEV         1   /* USDHC2 */
+#define CONFIG_MMCROOT                 "/dev/mmcblk1p2"  /* USDHC2 */
+#define CONFIG_SYS_FSL_USDHC_NUM       3
+#else
+#define CONFIG_SYS_MMC_ENV_DEV         0   /* USDHC2 */
+#define CONFIG_MMCROOT                 "/dev/mmcblk1p2"  /* USDHC2 */
+#define CONFIG_SYS_FSL_USDHC_NUM       2
+#endif
+
+/* Size of malloc() pool */
+#define CONFIG_SYS_MALLOC_LEN          ((CONFIG_ENV_SIZE + (16*1024)) * 1024)
+
+#define CONFIG_SYS_SDRAM_BASE          0x80000000
+#define CONFIG_NR_DRAM_BANKS           2
+#define PHYS_SDRAM_1                   0x80000000
+#define PHYS_SDRAM_2                   0x880000000
+#define PHYS_SDRAM_1_SIZE              0x80000000      /* 2 GB */
+/* LPDDR4 board total DDR is 6GB, DDR4 board total DDR is 4GB */
+#ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2
+#define PHYS_SDRAM_2_SIZE              0x100000000     /* 4 GB */
+#else
+#define PHYS_SDRAM_2_SIZE              0x80000000      /* 2 GB */
+#endif
+
+/* Serial */
+#define CONFIG_BAUDRATE                        115200
+
+/* Monitor Command Prompt */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2     "> "
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_SYS_CBSIZE              1024
+#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_CMDLINE_EDITING
+
+/* Generic Timer Definitions */
+#define COUNTER_FREQUENCY              8000000 /* 8MHz */
+
+#ifndef CONFIG_DM_PCA953X
+#define CONFIG_PCA953X
+#define CONFIG_CMD_PCA953X
+#define CONFIG_CMD_PCA953X_INFO
+#endif
+
+#define CONFIG_IMX_SMMU
+
+/* MT35XU512ABA1G12 has only one Die, so QSPI0 B won't work */
+#ifdef CONFIG_FSL_FSPI
+#define CONFIG_SF_DEFAULT_BUS          0
+#define CONFIG_SF_DEFAULT_CS           0
+#define CONFIG_SF_DEFAULT_SPEED        40000000
+#define CONFIG_SF_DEFAULT_MODE         SPI_MODE_0
+#define FSL_FSPI_FLASH_SIZE            SZ_64M
+#define FSL_FSPI_FLASH_NUM             1
+#define FSPI0_BASE_ADDR                        0x5d120000
+#define FSPI0_AMBA_BASE                        0
+#define CONFIG_SYS_FSL_FSPI_AHB
+#endif
+
+#endif /* __IMX8QM_ARM2_H */