Przeglądaj źródła

Merge tag 'u-boot-imx-20181025' of git://git.denx.de/u-boot-imx

Merged imx8 architecture, fix build for imx8 + warnings
Tom Rini 5 lat temu
rodzic
commit
cf033e04da
100 zmienionych plików z 4974 dodań i 116 usunięć
  1. 8 0
      arch/arm/Kconfig
  2. 1 1
      arch/arm/Makefile
  3. 2 0
      arch/arm/dts/Makefile
  4. 66 0
      arch/arm/dts/fsl-imx8-ca35.dtsi
  5. 499 0
      arch/arm/dts/fsl-imx8dx.dtsi
  6. 11 0
      arch/arm/dts/fsl-imx8dxp.dtsi
  7. 244 0
      arch/arm/dts/fsl-imx8qxp-mek.dts
  8. 51 0
      arch/arm/dts/fsl-imx8qxp.dtsi
  9. 28 0
      arch/arm/dts/imx6ul-opos6ul-u-boot.dtsi
  10. 0 2
      arch/arm/dts/imx6ul-opos6ul.dtsi
  11. 24 0
      arch/arm/dts/imx6ul-opos6uldev-u-boot.dtsi
  12. 0 2
      arch/arm/dts/imx6ul-opos6uldev.dts
  13. 6 0
      arch/arm/include/asm/arch-imx/cpu.h
  14. 27 0
      arch/arm/include/asm/arch-imx8/clock.h
  15. 21 0
      arch/arm/include/asm/arch-imx8/gpio.h
  16. 46 0
      arch/arm/include/asm/arch-imx8/imx-regs.h
  17. 15 0
      arch/arm/include/asm/arch-imx8/imx8-pins.h
  18. 40 0
      arch/arm/include/asm/arch-imx8/iomux.h
  19. 15 0
      arch/arm/include/asm/arch-imx8/power-domain.h
  20. 158 0
      arch/arm/include/asm/arch-imx8/sci/rpc.h
  21. 88 0
      arch/arm/include/asm/arch-imx8/sci/sci.h
  22. 30 0
      arch/arm/include/asm/arch-imx8/sci/svc/misc/api.h
  23. 57 0
      arch/arm/include/asm/arch-imx8/sci/svc/pad/api.h
  24. 44 0
      arch/arm/include/asm/arch-imx8/sci/svc/pm/api.h
  25. 69 0
      arch/arm/include/asm/arch-imx8/sci/svc/rm/api.h
  26. 220 0
      arch/arm/include/asm/arch-imx8/sci/types.h
  27. 19 0
      arch/arm/include/asm/arch-imx8/sys_proto.h
  28. 1 0
      arch/arm/include/asm/arch-mx5/clock.h
  29. 26 0
      arch/arm/include/asm/armv8/cpu.h
  30. 4 0
      arch/arm/include/asm/global_data.h
  31. 1 0
      arch/arm/include/asm/mach-imx/boot_mode.h
  32. 3 0
      arch/arm/include/asm/mach-imx/sys_proto.h
  33. 21 7
      arch/arm/mach-imx/Makefile
  34. 26 0
      arch/arm/mach-imx/imx8/Kconfig
  35. 7 0
      arch/arm/mach-imx/imx8/Makefile
  36. 21 0
      arch/arm/mach-imx/imx8/clock.c
  37. 646 0
      arch/arm/mach-imx/imx8/cpu.c
  38. 43 0
      arch/arm/mach-imx/imx8/iomux.c
  39. 6 0
      arch/arm/mach-imx/mx5/Kconfig
  40. 29 0
      arch/arm/mach-imx/mx5/clock.c
  41. 4 0
      arch/arm/mach-imx/mx7/ddr.c
  42. 2 0
      arch/arm/mach-imx/mx7/soc.c
  43. 2 0
      arch/arm/mach-imx/syscounter.c
  44. 14 0
      board/freescale/imx8qxp_mek/Kconfig
  45. 6 0
      board/freescale/imx8qxp_mek/MAINTAINERS
  46. 7 0
      board/freescale/imx8qxp_mek/Makefile
  47. 55 0
      board/freescale/imx8qxp_mek/README
  48. 170 0
      board/freescale/imx8qxp_mek/imx8qxp_mek.c
  49. 25 0
      board/freescale/imx8qxp_mek/imximage.cfg
  50. 81 0
      board/freescale/mx8mq_evk/README
  51. 1 1
      board/ge/bx50v3/MAINTAINERS
  52. 22 16
      board/ge/bx50v3/bx50v3.c
  53. 15 0
      board/menlo/m53menlo/Kconfig
  54. 7 0
      board/menlo/m53menlo/MAINTAINERS
  55. 9 0
      board/menlo/m53menlo/Makefile
  56. 91 0
      board/menlo/m53menlo/imximage.cfg
  57. 513 0
      board/menlo/m53menlo/m53menlo.c
  58. 28 1
      board/technexion/pico-imx7d/pico-imx7d.c
  59. 1 1
      board/toradex/colibri_imx7/colibri_imx7.c
  60. 1 0
      board/warp7/MAINTAINERS
  61. 1 0
      common/image.c
  62. 1 0
      configs/aristainetos2_defconfig
  63. 1 0
      configs/aristainetos2b_defconfig
  64. 1 0
      configs/aristainetos_defconfig
  65. 1 0
      configs/dh_imx6_defconfig
  66. 1 0
      configs/display5_defconfig
  67. 1 0
      configs/display5_factory_defconfig
  68. 1 0
      configs/ge_bx50v3_defconfig
  69. 52 0
      configs/imx8qxp_mek_defconfig
  70. 1 0
      configs/kp_imx6q_tpc_defconfig
  71. 60 0
      configs/m53menlo_defconfig
  72. 1 0
      configs/mx53ppd_defconfig
  73. 0 1
      configs/pico-hobbit-imx7d_defconfig
  74. 0 1
      configs/pico-imx7d_defconfig
  75. 0 1
      configs/pico-pi-imx7d_defconfig
  76. 1 0
      configs/tqma6s_wru4_mmc_defconfig
  77. 42 0
      configs/warp7_bl33_defconfig
  78. 2 0
      configs/warp7_defconfig
  79. 1 0
      configs/warp_defconfig
  80. 0 0
      doc/imx/common/imx25.txt
  81. 0 0
      doc/imx/common/imx27.txt
  82. 0 0
      doc/imx/common/imx5.txt
  83. 0 25
      doc/imx/common/imx6.txt
  84. 0 0
      doc/imx/common/mxs.txt
  85. 43 0
      doc/imx/hab/habv4/encrypted_boot.txt
  86. 0 44
      doc/imx/hab/habv4/secure_boot.txt
  87. 20 2
      doc/imx/misc/sdp.txt
  88. 0 0
      doc/imx/mkimage/imximage.txt
  89. 0 0
      doc/imx/mkimage/mxsimage.txt
  90. 1 0
      drivers/clk/Kconfig
  91. 1 0
      drivers/clk/Makefile
  92. 6 0
      drivers/clk/imx/Kconfig
  93. 5 0
      drivers/clk/imx/Makefile
  94. 393 0
      drivers/clk/imx/clk-imx8.c
  95. 21 9
      drivers/gpio/mxc_gpio.c
  96. 2 2
      drivers/i2c/imx_lpi2c.c
  97. 1 0
      drivers/misc/Makefile
  98. 3 0
      drivers/misc/imx8/Makefile
  99. 266 0
      drivers/misc/imx8/scu.c
  100. 367 0
      drivers/misc/imx8/scu_api.c

+ 8 - 0
arch/arm/Kconfig

@@ -668,6 +668,12 @@ config ARCH_LPC32XX
 	select SUPPORT_SPL
 	imply CMD_DM
 
+config ARCH_IMX8
+	bool "NXP i.MX8 platform"
+	select ARM64
+	select DM
+	select OF_CONTROL
+
 config ARCH_MX8M
 	bool "NXP i.MX8M platform"
 	select ARM64
@@ -1418,6 +1424,8 @@ source "arch/arm/mach-imx/mx7/Kconfig"
 
 source "arch/arm/mach-imx/mx7ulp/Kconfig"
 
+source "arch/arm/mach-imx/imx8/Kconfig"
+
 source "arch/arm/mach-imx/mx8m/Kconfig"
 
 source "arch/arm/mach-imx/mxs/Kconfig"

+ 1 - 1
arch/arm/Makefile

@@ -106,7 +106,7 @@ ifneq (,$(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_MX35)$(filter $(SOC), mx25 mx5 mx6
 libs-y += arch/arm/mach-imx/
 endif
 else
-ifneq (,$(filter $(SOC), mx25 mx27 mx5 mx6 mx7 mx7ulp mx31 mx35 mxs mx8m vf610))
+ifneq (,$(filter $(SOC), mx25 mx27 mx5 mx6 mx7 mx7ulp mx31 mx35 mxs mx8m imx8 vf610))
 libs-y += arch/arm/mach-imx/
 endif
 endif

+ 2 - 0
arch/arm/dts/Makefile

@@ -454,6 +454,8 @@ dtb-$(CONFIG_MX7) += imx7-colibri.dtb \
 
 dtb-$(CONFIG_ARCH_MX7ULP) += imx7ulp-evk.dtb
 
+dtb-$(CONFIG_ARCH_IMX8) += fsl-imx8qxp-mek.dtb
+
 dtb-$(CONFIG_RCAR_GEN3) += \
 	r8a7795-h3ulcb-u-boot.dtb \
 	r8a7795-salvator-x-u-boot.dtb \

+ 66 - 0
arch/arm/dts/fsl-imx8-ca35.dtsi

@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ */
+
+#include <dt-bindings/clock/imx8qxp-clock.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/{
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		/* We have 1 clusters having 4 Cortex-A35 cores */
+		A35_0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			next-level-cache = <&A35_L2>;
+		};
+
+		A35_1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			next-level-cache = <&A35_L2>;
+		};
+
+		A35_2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+			next-level-cache = <&A35_L2>;
+		};
+
+		A35_3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			reg = <0x0 0x3>;
+			enable-method = "psci";
+			next-level-cache = <&A35_L2>;
+		};
+
+		A35_L2: l2-cache0 {
+			compatible = "cache";
+		};
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <GIC_PPI 7
+			(GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
+		interrupt-affinity = <&A35_0>, <&A35_1>, <&A35_2>, <&A35_3>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+		cpu_suspend   = <0xc4000001>;
+		cpu_off	      = <0xc4000002>;
+		cpu_on	      = <0xc4000003>;
+	};
+};

+ 499 - 0
arch/arm/dts/fsl-imx8dx.dtsi

@@ -0,0 +1,499 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "fsl-imx8-ca35.dtsi"
+#include <dt-bindings/soc/imx_rsrc.h>
+#include <dt-bindings/soc/imx8_pd.h>
+#include <dt-bindings/clock/imx8qxp-clock.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/pads-imx8qxp.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	model = "Freescale i.MX8DX";
+	compatible = "fsl,imx8dx", "fsl,imx8qxp";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		ethernet0 = &fec1;
+		ethernet1 = &fec2;
+		serial0 = &lpuart0;
+		mmc0 = &usdhc1;
+		mmc1 = &usdhc2;
+		mmc2 = &usdhc3;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x00000000 0x80000000 0 0x40000000>;
+		      /* DRAM space - 1, size : 1 GB DRAM */
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/*
+		 * reserved-memory layout
+		 * 0x8800_0000 ~ 0x8FFF_FFFF is reserved for M4
+		 * Shouldn't be used at A core and Linux side.
+		 *
+		 */
+		decoder_boot: decoder_boot@0x84000000 {
+			no-map;
+			reg = <0 0x84000000 0 0x2000000>;
+		};
+		encoder_boot: encoder_boot@0x86000000 {
+			no-map;
+			reg = <0 0x86000000 0 0x2000000>;
+		};
+		rpmsg_reserved: rpmsg@0x90000000 {
+			no-map;
+			reg = <0 0x90000000 0 0x400000>;
+		};
+		decoder_rpc: decoder_rpc@0x90400000 {
+			no-map;
+			reg = <0 0x90400000 0 0x1000000>;
+		};
+		encoder_rpc: encoder_rpc@0x91400000 {
+			no-map;
+			reg = <0 0x91400000 0 0x1000000>;
+		};
+		dsp_reserved: dsp@0x92400000 {
+			no-map;
+			reg = <0 0x92400000 0 0x2000000>;
+		};
+		decoder_str: str@0x94400000 {
+			no-map;
+			reg = <0 0x94400000 0 0x1800000>;
+		};
+		/* global autoconfigured region for contiguous allocations */
+		linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0 0x28000000>;
+			alloc-ranges = <0 0x96000000 0 0x28000000>;
+			linux,cma-default;
+		};
+	};
+
+	gic: interrupt-controller@51a00000 {
+		compatible = "arm,gic-v3";
+		reg = <0x0 0x51a00000 0 0x10000>, /* GIC Dist */
+		      <0x0 0x51b00000 0 0xC0000>; /* GICR (RD_base + SGI_base) */
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		interrupts = <GIC_PPI 9
+			(GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
+		interrupt-parent = <&gic>;
+	};
+
+	mu: mu@5d1c0000 {
+		compatible = "fsl,imx8-mu";
+		reg = <0x0 0x5d1c0000 0x0 0x10000>;
+		interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-parent = <&gic>;
+		status = "okay";
+
+		clk: clk {
+			compatible = "fsl,imx8qxp-clk";
+			#clock-cells = <1>;
+		};
+
+		iomuxc: iomuxc {
+			compatible = "fsl,imx8qxp-iomuxc";
+		};
+	};
+
+	imx8qx-pm {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pd_lsio: PD_LSIO {
+			compatible = "nxp,imx8-pd";
+			reg = <SC_R_LAST>;
+			#power-domain-cells = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			pd_lsio_gpio0: PD_LSIO_GPIO_0 {
+				reg = <SC_R_GPIO_0>;
+				#power-domain-cells = <0>;
+				power-domains = <&pd_lsio>;
+			};
+			pd_lsio_gpio1: PD_LSIO_GPIO_1 {
+				reg = <SC_R_GPIO_1>;
+				#power-domain-cells = <0>;
+				power-domains = <&pd_lsio>;
+			};
+			pd_lsio_gpio2: PD_LSIO_GPIO_2 {
+				reg = <SC_R_GPIO_2>;
+				#power-domain-cells = <0>;
+				power-domains = <&pd_lsio>;
+			};
+			pd_lsio_gpio3: PD_LSIO_GPIO_3 {
+				reg = <SC_R_GPIO_3>;
+				#power-domain-cells = <0>;
+				power-domains = <&pd_lsio>;
+			};
+			pd_lsio_gpio4: PD_LSIO_GPIO_4 {
+				reg = <SC_R_GPIO_4>;
+				#power-domain-cells = <0>;
+				power-domains = <&pd_lsio>;
+			};
+			pd_lsio_gpio5: PD_LSIO_GPIO_5{
+				reg = <SC_R_GPIO_5>;
+				#power-domain-cells = <0>;
+				power-domains = <&pd_lsio>;
+			};
+			pd_lsio_gpio6: PD_LSIO_GPIO_6 {
+				reg = <SC_R_GPIO_6>;
+				#power-domain-cells = <0>;
+				power-domains = <&pd_lsio>;
+			};
+			pd_lsio_gpio7: PD_LSIO_GPIO_7 {
+				reg = <SC_R_GPIO_7>;
+				#power-domain-cells = <0>;
+				power-domains = <&pd_lsio>;
+			};
+		};
+
+		pd_conn: PD_CONN {
+			compatible = "nxp,imx8-pd";
+			reg = <SC_R_LAST>;
+			#power-domain-cells = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			pd_conn_sdch0: PD_CONN_SDHC_0 {
+				reg = <SC_R_SDHC_0>;
+				#power-domain-cells = <0>;
+				power-domains = <&pd_conn>;
+			};
+			pd_conn_sdch1: PD_CONN_SDHC_1 {
+				reg = <SC_R_SDHC_1>;
+				#power-domain-cells = <0>;
+				power-domains = <&pd_conn>;
+			};
+			pd_conn_sdch2: PD_CONN_SDHC_2 {
+				reg = <SC_R_SDHC_2>;
+				#power-domain-cells = <0>;
+				power-domains = <&pd_conn>;
+			};
+			pd_conn_enet0: PD_CONN_ENET_0 {
+				reg = <SC_R_ENET_0>;
+				#power-domain-cells = <0>;
+				power-domains = <&pd_conn>;
+			};
+			pd_conn_enet1: PD_CONN_ENET_1 {
+				reg = <SC_R_ENET_1>;
+				#power-domain-cells = <0>;
+				power-domains = <&pd_conn>;
+			};
+		};
+
+		pd_dma: PD_DMA {
+			compatible = "nxp,imx8-pd";
+			reg = <SC_R_LAST>;
+			#power-domain-cells = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			pd_dma_lpi2c0: PD_DMA_I2C_0 {
+				reg = <SC_R_I2C_0>;
+				#power-domain-cells = <0>;
+				power-domains = <&pd_dma>;
+			};
+			pd_dma_lpi2c1: PD_DMA_I2C_1 {
+				reg = <SC_R_I2C_1>;
+				#power-domain-cells = <0>;
+				power-domains = <&pd_dma>;
+			};
+			pd_dma_lpi2c2:PD_DMA_I2C_2 {
+				reg = <SC_R_I2C_2>;
+				#power-domain-cells = <0>;
+				power-domains = <&pd_dma>;
+			};
+			pd_dma_lpi2c3: PD_DMA_I2C_3 {
+				reg = <SC_R_I2C_3>;
+				#power-domain-cells = <0>;
+				power-domains = <&pd_dma>;
+			};
+			pd_dma_lpuart0: PD_DMA_UART0 {
+				reg = <SC_R_UART_0>;
+				#power-domain-cells = <0>;
+				power-domains = <&pd_dma>;
+				wakeup-irq = <225>;
+			};
+		};
+	};
+
+	i2c0: i2c@5a800000 {
+		compatible = "fsl,imx8qm-lpi2c", "fsl,imx7ulp-lpi2c";
+		reg = <0x0 0x5a800000 0x0 0x4000>;
+		interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-parent = <&gic>;
+		clocks = <&clk IMX8QXP_I2C0_CLK>;
+		clock-names = "per";
+		assigned-clocks = <&clk IMX8QXP_I2C0_CLK>;
+		assigned-clock-rates = <24000000>;
+		power-domains = <&pd_dma_lpi2c0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c1: i2c@5a810000 {
+		compatible = "fsl,imx8qm-lpi2c", "fsl,imx7ulp-lpi2c";
+		reg = <0x0 0x5a810000 0x0 0x4000>;
+		interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-parent = <&gic>;
+		clocks = <&clk IMX8QXP_I2C1_CLK>,
+			<&clk IMX8QXP_I2C1_IPG_CLK>;
+		clock-names = "per", "ipg";
+		assigned-clocks = <&clk IMX8QXP_I2C1_CLK>;
+		assigned-clock-rates = <24000000>;
+		power-domains = <&pd_dma_lpi2c1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c2: i2c@5a820000 {
+		compatible = "fsl,imx8qm-lpi2c", "fsl,imx7ulp-lpi2c";
+		reg = <0x0 0x5a820000 0x0 0x4000>;
+		interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-parent = <&gic>;
+		clocks = <&clk IMX8QXP_I2C2_CLK>;
+		clock-names = "per";
+		assigned-clocks = <&clk IMX8QXP_I2C2_CLK>;
+		assigned-clock-rates = <24000000>;
+		power-domains = <&pd_dma_lpi2c2>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c3: i2c@5a830000 {
+		compatible = "fsl,imx8qm-lpi2c", "fsl,imx7ulp-lpi2c";
+		reg = <0x0 0x5a830000 0x0 0x4000>;
+		interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-parent = <&gic>;
+		clocks = <&clk IMX8QXP_I2C3_CLK>,
+			<&clk IMX8QXP_I2C3_IPG_CLK>;
+		clock-names = "per", "ipg";
+		assigned-clocks = <&clk IMX8QXP_I2C3_CLK>;
+		assigned-clock-rates = <24000000>;
+		power-domains = <&pd_dma_lpi2c3>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	gpio0: gpio@5d080000 {
+		compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+		reg = <0x0 0x5d080000 0x0 0x10000>;
+		interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		power-domains = <&pd_lsio_gpio0>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpio1: gpio@5d090000 {
+		compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+		reg = <0x0 0x5d090000 0x0 0x10000>;
+		interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		power-domains = <&pd_lsio_gpio1>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpio2: gpio@5d0a0000 {
+		compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+		reg = <0x0 0x5d0a0000 0x0 0x10000>;
+		interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		power-domains = <&pd_lsio_gpio2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpio3: gpio@5d0b0000 {
+		compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+		reg = <0x0 0x5d0b0000 0x0 0x10000>;
+		interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		power-domains = <&pd_lsio_gpio3>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpio4: gpio@5d0c0000 {
+		compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+		reg = <0x0 0x5d0c0000 0x0 0x10000>;
+		interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		power-domains = <&pd_lsio_gpio4>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpio5: gpio@5d0d0000 {
+		compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+		reg = <0x0 0x5d0d0000 0x0 0x10000>;
+		interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		power-domains = <&pd_lsio_gpio5>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpio6: gpio@5d0e0000 {
+		compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+		reg = <0x0 0x5d0e0000 0x0 0x10000>;
+		interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		power-domains = <&pd_lsio_gpio6>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpio7: gpio@5d0f0000 {
+		compatible = "fsl,imx8qm-gpio", "fsl,imx35-gpio";
+		reg = <0x0 0x5d0f0000 0x0 0x10000>;
+		interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		power-domains = <&pd_lsio_gpio7>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	lpuart0: serial@5a060000 {
+		compatible = "fsl,imx8qm-lpuart";
+		reg = <0x0 0x5a060000 0x0 0x1000>;
+		interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clk IMX8QXP_UART0_CLK>,
+			 <&clk IMX8QXP_UART0_IPG_CLK>;
+		clock-names = "per", "ipg";
+		assigned-clocks = <&clk IMX8QXP_UART0_CLK>;
+		assigned-clock-rates = <80000000>;
+		power-domains = <&pd_dma_lpuart0>;
+		status = "disabled";
+	};
+
+	usdhc1: usdhc@5b010000 {
+		compatible = "fsl,imx8qm-usdhc", "fsl,imx6sl-usdhc";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>;
+		reg = <0x0 0x5b010000 0x0 0x10000>;
+		clocks = <&clk IMX8QXP_SDHC0_IPG_CLK>,
+			<&clk IMX8QXP_SDHC0_CLK>,
+			<&clk IMX8QXP_CLK_DUMMY>;
+		clock-names = "ipg", "per", "ahb";
+		assigned-clocks = <&clk IMX8QXP_SDHC0_SEL>, <&clk IMX8QXP_SDHC0_DIV>;
+		assigned-clock-parents = <&clk IMX8QXP_CONN_PLL0_CLK>;
+		assigned-clock-rates = <0>, <400000000>;
+		power-domains = <&pd_conn_sdch0>;
+		fsl,tuning-start-tap = <20>;
+		fsl,tuning-step= <2>;
+		status = "disabled";
+	};
+
+	usdhc2: usdhc@5b020000 {
+		compatible = "fsl,imx8qm-usdhc", "fsl,imx6sl-usdhc";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>;
+		reg = <0x0 0x5b020000 0x0 0x10000>;
+		clocks = <&clk IMX8QXP_SDHC1_IPG_CLK>,
+			<&clk IMX8QXP_SDHC1_CLK>,
+			<&clk IMX8QXP_CLK_DUMMY>;
+		clock-names = "ipg", "per", "ahb";
+		assigned-clocks = <&clk IMX8QXP_SDHC1_SEL>, <&clk IMX8QXP_SDHC1_DIV>;
+		assigned-clock-parents = <&clk IMX8QXP_CONN_PLL0_CLK>;
+		assigned-clock-rates = <0>, <200000000>;
+		power-domains = <&pd_conn_sdch1>;
+		fsl,tuning-start-tap = <20>;
+		fsl,tuning-step= <2>;
+		status = "disabled";
+	};
+
+	usdhc3: usdhc@5b030000 {
+		compatible = "fsl,imx8qm-usdhc", "fsl,imx6sl-usdhc";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
+		reg = <0x0 0x5b030000 0x0 0x10000>;
+		clocks = <&clk IMX8QXP_SDHC2_IPG_CLK>,
+			<&clk IMX8QXP_SDHC2_CLK>,
+			<&clk IMX8QXP_CLK_DUMMY>;
+		clock-names = "ipg", "per", "ahb";
+		assigned-clocks = <&clk IMX8QXP_SDHC2_SEL>, <&clk IMX8QXP_SDHC2_DIV>;
+		assigned-clock-parents = <&clk IMX8QXP_CONN_PLL0_CLK>;
+		assigned-clock-rates = <0>, <200000000>;
+		power-domains = <&pd_conn_sdch2>;
+		status = "disabled";
+	};
+
+	fec1: ethernet@5b040000 {
+		compatible = "fsl,imx7d-fec", "fsl,imx8qm-fec";
+		reg = <0x0 0x5b040000 0x0 0x10000>;
+		interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clk IMX8QXP_ENET0_IPG_CLK>, <&clk IMX8QXP_ENET0_AHB_CLK>,
+			<&clk IMX8QXP_ENET0_RGMII_TX_CLK>, <&clk IMX8QXP_ENET0_PTP_CLK>;
+		clock-names = "ipg", "ahb", "enet_clk_ref", "ptp";
+		assigned-clocks = <&clk IMX8QXP_ENET0_REF_DIV>, <&clk IMX8QXP_ENET0_PTP_CLK>;
+		assigned-clock-rates = <125000000>, <125000000>;
+		fsl,num-tx-queues=<3>;
+		fsl,num-rx-queues=<3>;
+		power-domains = <&pd_conn_enet0>;
+		status = "disabled";
+	};
+
+	fec2: ethernet@5b050000 {
+		compatible = "fsl,imx7d-fec", "fsl,imx8qm-fec";
+		reg = <0x0 0x5b050000 0x0 0x10000>;
+		interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clk IMX8QXP_ENET1_IPG_CLK>, <&clk IMX8QXP_ENET1_AHB_CLK>,
+			<&clk IMX8QXP_ENET1_RGMII_TX_CLK>, <&clk IMX8QXP_ENET1_PTP_CLK>;
+		clock-names = "ipg", "ahb", "enet_clk_ref", "ptp";
+		assigned-clocks = <&clk IMX8QXP_ENET1_REF_DIV>, <&clk IMX8QXP_ENET1_PTP_CLK>;
+		assigned-clock-rates = <125000000>, <125000000>;
+		fsl,num-tx-queues=<3>;
+		fsl,num-rx-queues=<3>;
+		power-domains = <&pd_conn_enet1>;
+		status = "disabled";
+	};
+};
+
+&A35_0 {
+	clocks = <&clk IMX8QXP_A35_DIV>;
+};
+
+/delete-node/ &A35_2;
+/delete-node/ &A35_3;

+ 11 - 0
arch/arm/dts/fsl-imx8dxp.dtsi

@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ */
+
+#include "fsl-imx8dx.dtsi"
+
+/ {
+	model = "Freescale i.MX8DXP";
+	compatible = "fsl,imx8dxp", "fsl,imx8qxp";
+};

+ 244 - 0
arch/arm/dts/fsl-imx8qxp-mek.dts

@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2017-2018 NXP
+ */
+
+/dts-v1/;
+
+#include "fsl-imx8qxp.dtsi"
+
+/ {
+	model = "Freescale i.MX8QXP MEK";
+	compatible = "fsl,imx8qxp-mek", "fsl,imx8qxp";
+
+	chosen {
+		bootargs = "console=ttyLP0,115200 earlycon=lpuart32,0x5a060000,115200";
+		stdout-path = &lpuart0;
+	};
+
+	regulators {
+		compatible = "simple-bus";
+
+		reg_usdhc2_vmmc: usdhc2-vmmc {
+			compatible = "regulator-fixed";
+			regulator-name = "SD1_SPWR";
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3000000>;
+			gpio = <&gpio4 19 GPIO_ACTIVE_HIGH>;
+			off-on-delay = <3480>;
+			enable-active-high;
+		};
+	};
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_hog>;
+
+	imx8qxp-mek {
+		pinctrl_hog: hoggrp {
+			fsl,pins = <
+				SC_P_MCLK_OUT0_ADMA_ACM_MCLK_OUT0	0x0600004c
+				SC_P_COMP_CTL_GPIO_1V8_3V3_GPIORHB_PAD	0x000514a0
+			>;
+		};
+
+		pinctrl_ioexp_rst: ioexp-rst-grp {
+			fsl,pins = <
+				SC_P_SPI2_SDO_LSIO_GPIO1_IO01	0x06000021
+			>;
+		};
+
+		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_ESAI0_SCKR_CONN_ENET1_RGMII_TX_CTL		0x06000048
+				SC_P_ESAI0_FSR_CONN_ENET1_RGMII_TXC		0x06000048
+				SC_P_ESAI0_TX4_RX1_CONN_ENET1_RGMII_TXD0	0x06000048
+				SC_P_ESAI0_TX5_RX0_CONN_ENET1_RGMII_TXD1	0x06000048
+				SC_P_ESAI0_FST_CONN_ENET1_RGMII_TXD2		0x06000048
+				SC_P_ESAI0_SCKT_CONN_ENET1_RGMII_TXD3		0x06000048
+				SC_P_ESAI0_TX0_CONN_ENET1_RGMII_RXC		0x06000048
+				SC_P_SPDIF0_TX_CONN_ENET1_RGMII_RX_CTL		0x06000048
+				SC_P_SPDIF0_RX_CONN_ENET1_RGMII_RXD0		0x06000048
+				SC_P_ESAI0_TX3_RX2_CONN_ENET1_RGMII_RXD1	0x06000048
+				SC_P_ESAI0_TX2_RX3_CONN_ENET1_RGMII_RXD2	0x06000048
+				SC_P_ESAI0_TX1_CONN_ENET1_RGMII_RXD3		0x06000048
+			>;
+		};
+
+		pinctrl_lpi2c1: lpi2c1grp {
+			fsl,pins = <
+				SC_P_USB_SS3_TC1_ADMA_I2C1_SCL	0x06000021
+				SC_P_USB_SS3_TC3_ADMA_I2C1_SDA	0x06000021
+			>;
+		};
+
+		pinctrl_lpuart0: lpuart0grp {
+			fsl,pins = <
+				SC_P_UART0_RX_ADMA_UART0_RX	0x06000020
+				SC_P_UART0_TX_ADMA_UART0_TX	0x06000020
+			>;
+		};
+
+		pinctrl_usdhc1: usdhc1grp {
+			fsl,pins = <
+				SC_P_EMMC0_CLK_CONN_EMMC0_CLK		0x06000041
+				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_STROBE_CONN_EMMC0_STROBE	0x00000041
+			>;
+		};
+
+		pinctrl_usdhc2_gpio: usdhc2gpiogrp {
+			fsl,pins = <
+				SC_P_USDHC1_RESET_B_LSIO_GPIO4_IO19	0x00000021
+				SC_P_USDHC1_WP_LSIO_GPIO4_IO21		0x00000021
+				SC_P_USDHC1_CD_B_LSIO_GPIO4_IO22	0x00000021
+			>;
+		};
+
+		pinctrl_usdhc2: usdhc2grp {
+			fsl,pins = <
+				SC_P_USDHC1_CLK_CONN_USDHC1_CLK		0x06000041
+				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_VSELECT_CONN_USDHC1_VSELECT	0x00000021
+			>;
+		};
+	};
+};
+
+&A35_0 {
+	u-boot,dm-pre-reloc;
+};
+
+&lpuart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_lpuart0>;
+	status = "okay";
+};
+
+&i2c1 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_lpi2c1 &pinctrl_ioexp_rst>;
+	status = "okay";
+
+	i2cswitch@71 {
+		compatible = "nxp,pca9646";
+		reg = <0x71>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reset-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+
+		bb_i2c1: i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x0>;
+		};
+
+		mfi_i2c1: i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x1>;
+		};
+
+		i2cexp1_i2c1: i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x2>;
+		};
+
+		i2cexp2_i2c1: i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x3>;
+
+			pca9557_a: gpio@1a {
+				compatible = "nxp,pca9557";
+				reg = <0x1a>;
+				gpio-controller;
+				#gpio-cells = <2>;
+			};
+			pca9557_b: gpio@1d {
+				compatible = "nxp,pca9557";
+				reg = <0x1d>;
+				gpio-controller;
+				#gpio-cells = <2>;
+			};
+		};
+	};
+};
+
+&usdhc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc1>;
+	bus-width = <8>;
+	non-removable;
+	status = "okay";
+};
+
+&usdhc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+	bus-width = <4>;
+	cd-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>;
+	wp-gpios = <&gpio4 21 GPIO_ACTIVE_HIGH>;
+	vmmc-supply = <&reg_usdhc2_vmmc>;
+	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";
+	phy-reset-gpios = <&pca9557_a 4 GPIO_ACTIVE_LOW>;
+	phy-reset-duration = <10>;
+
+	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>;
+		};
+	};
+};

+ 51 - 0
arch/arm/dts/fsl-imx8qxp.dtsi

@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 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.
+ */
+
+#include "fsl-imx8dxp.dtsi"
+
+/ {
+	model = "Freescale i.MX8QXP";
+	compatible = "fsl,imx8qxp";
+
+	cpus {
+		A35_2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+			next-level-cache = <&A35_L2>;
+		};
+
+		A35_3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			reg = <0x0 0x3>;
+			enable-method = "psci";
+			next-level-cache = <&A35_L2>;
+		};
+	};
+
+	pmu {
+		interrupt-affinity = <&A35_0>, <&A35_1>, <&A35_2>, <&A35_3>;
+	};
+};
+
+&A35_2 {
+	device_type = "cpu";
+};
+
+&A35_3 {
+	device_type = "cpu";
+};

+ 28 - 0
arch/arm/dts/imx6ul-opos6ul-u-boot.dtsi

@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source extras for U-Boot for the OPOS6UL SoM
+ *
+ * Copyright (C) 2018 Armadeus Systems <support@armadeus.com>
+ */
+
+/ {
+	soc {
+		u-boot,dm-spl;
+	};
+};
+
+&aips2 {
+	u-boot,dm-spl;
+};
+
+&iomuxc {
+	u-boot,dm-spl;
+};
+
+&pinctrl_usdhc1 {
+	u-boot,dm-spl;
+};
+
+&usdhc1 {
+	u-boot,dm-spl;
+};

+ 0 - 2
arch/arm/dts/imx6ul-opos6ul.dtsi

@@ -99,7 +99,6 @@
 
 /* eMMC */
 &usdhc1 {
-	u-boot,dm-spl;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_usdhc1>;
 	bus-width = <8>;
@@ -162,7 +161,6 @@
 	};
 
 	pinctrl_usdhc1: usdhc1grp {
-		u-boot,dm-spl;
 		fsl,pins = <
 			MX6UL_PAD_SD1_CMD__USDHC1_CMD		0x17059
 			MX6UL_PAD_SD1_CLK__USDHC1_CLK		0x10059

+ 24 - 0
arch/arm/dts/imx6ul-opos6uldev-u-boot.dtsi

@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source extras for U-Boot for the OPOS6ULDev board
+ *
+ * Copyright (C) 2018 Armadeus Systems <support@armadeus.com>
+ */
+
+#include "imx6ul-opos6ul-u-boot.dtsi"
+
+&aips1 {
+	u-boot,dm-spl;
+
+	spba-bus@02000000 {
+		u-boot,dm-spl;
+	};
+};
+
+&pinctrl_uart1 {
+	u-boot,dm-spl;
+};
+
+&uart1 {
+	u-boot,dm-spl;
+};

+ 0 - 2
arch/arm/dts/imx6ul-opos6uldev.dts

@@ -228,7 +228,6 @@
 };
 
 &uart1 {
-	u-boot,dm-spl;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_uart1>;
 	status = "okay";
@@ -374,7 +373,6 @@
 	};
 
 	pinctrl_uart1: uart1grp {
-		u-boot,dm-spl;
 		fsl,pins = <
 			MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX	0x1b0b1
 			MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX	0x1b0b1

+ 6 - 0
arch/arm/include/asm/arch-imx/cpu.h

@@ -25,12 +25,15 @@
 #define MXC_CPU_MX7S		0x71 /* dummy ID */
 #define MXC_CPU_MX7D		0x72
 #define MXC_CPU_MX8MQ		0x82
+#define MXC_CPU_IMX8QXP_A0	0x90 /* dummy ID */
+#define MXC_CPU_IMX8QXP		0x92 /* dummy ID */
 #define MXC_CPU_MX7ULP		0xE1 /* Temporally hard code */
 #define MXC_CPU_VF610		0xF6 /* dummy ID */
 
 #define MXC_SOC_MX6		0x60
 #define MXC_SOC_MX7		0x70
 #define MXC_SOC_MX8M		0x80
+#define MXC_SOC_IMX8		0x90 /* dummy */
 #define MXC_SOC_MX7ULP		0xE0 /* dummy */
 
 #define CHIP_REV_1_0            0x10
@@ -41,6 +44,9 @@
 #define CHIP_REV_2_5            0x25
 #define CHIP_REV_3_0            0x30
 
+#define CHIP_REV_A		0x0
+#define CHIP_REV_B		0x1
+
 #define BOARD_REV_1_0           0x0
 #define BOARD_REV_2_0           0x1
 #define BOARD_VER_OFFSET        0x8

+ 27 - 0
arch/arm/include/asm/arch-imx8/clock.h

@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ */
+
+#ifndef __ASM_ARCH_IMX8_CLOCK_H__
+#define __ASM_ARCH_IMX8_CLOCK_H__
+
+/* Mainly for compatible to imx common code. */
+enum mxc_clock {
+	MXC_ARM_CLK = 0,
+	MXC_AHB_CLK,
+	MXC_IPG_CLK,
+	MXC_UART_CLK,
+	MXC_CSPI_CLK,
+	MXC_AXI_CLK,
+	MXC_DDR_CLK,
+	MXC_ESDHC_CLK,
+	MXC_ESDHC2_CLK,
+	MXC_ESDHC3_CLK,
+	MXC_I2C_CLK,
+	MXC_FEC_CLK,
+};
+
+u32 mxc_get_clock(enum mxc_clock clk);
+
+#endif /* __ASM_ARCH_IMX8_CLOCK_H__ */

+ 21 - 0
arch/arm/include/asm/arch-imx8/gpio.h

@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ */
+
+#ifndef __ASM_ARCH_IMX8_GPIO_H
+#define __ASM_ARCH_IMX8_GPIO_H
+
+#if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
+/* GPIO registers */
+struct gpio_regs {
+	u32 gpio_dr;	/* data */
+	u32 gpio_dir;	/* direction */
+	u32 gpio_psr;	/* pad satus */
+};
+#endif
+
+/* IMX8 the GPIO index is from 0 not 1 */
+#define IMX_GPIO_NR(port, index)		(((port) * 32) + ((index) & 31))
+
+#endif /* __ASM_ARCH_IMX8_GPIO_H */

+ 46 - 0
arch/arm/include/asm/arch-imx8/imx-regs.h

@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ */
+
+#ifndef __ASM_ARCH_IMX8_REGS_H__
+#define __ASM_ARCH_IMX8_REGS_H__
+
+#define LPUART_BASE		0x5A060000
+
+#define GPT1_BASE_ADDR		0x5D140000
+#define SCU_LPUART_BASE		0x33220000
+#define GPIO1_BASE_ADDR		0x5D080000
+#define GPIO2_BASE_ADDR		0x5D090000
+#define GPIO3_BASE_ADDR		0x5D0A0000
+#define GPIO4_BASE_ADDR		0x5D0B0000
+#define GPIO5_BASE_ADDR		0x5D0C0000
+#define GPIO6_BASE_ADDR		0x5D0D0000
+#define GPIO7_BASE_ADDR		0x5D0E0000
+#define GPIO8_BASE_ADDR		0x5D0F0000
+#define LPI2C1_BASE_ADDR	0x5A800000
+#define LPI2C2_BASE_ADDR	0x5A810000
+#define LPI2C3_BASE_ADDR	0x5A820000
+#define LPI2C4_BASE_ADDR	0x5A830000
+#define LPI2C5_BASE_ADDR	0x5A840000
+
+#ifdef CONFIG_IMX8QXP
+#define LVDS0_PHYCTRL_BASE	0x56221000
+#define LVDS1_PHYCTRL_BASE	0x56241000
+#define MIPI0_SS_BASE		0x56220000
+#define MIPI1_SS_BASE		0x56240000
+#endif
+
+#define APBH_DMA_ARB_BASE_ADDR	0x5B810000
+#define APBH_DMA_ARB_END_ADDR	0x5B81FFFF
+#define MXS_APBH_BASE		APBH_DMA_ARB_BASE_ADDR
+
+#define MXS_GPMI_BASE		(APBH_DMA_ARB_BASE_ADDR + 0x02000)
+#define MXS_BCH_BASE		(APBH_DMA_ARB_BASE_ADDR + 0x04000)
+
+#define PASS_OVER_INFO_ADDR	0x0010fe00
+
+#define USB_BASE_ADDR		0x5b0d0000
+#define USB_PHY0_BASE_ADDR	0x5b100000
+
+#endif /* __ASM_ARCH_IMX8_REGS_H__ */

+ 15 - 0
arch/arm/include/asm/arch-imx8/imx8-pins.h

@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ */
+
+#ifndef __ASM_ARCH_IMX8_PINS_H__
+#define __ASM_ARCH_IMX8_PINS_H__
+
+#if defined(CONFIG_IMX8QXP)
+#include <dt-bindings/pinctrl/pads-imx8qxp.h>
+#else
+#error "No pin header"
+#endif
+
+#endif	/* __ASM_ARCH_IMX8_PINS_H__ */

+ 40 - 0
arch/arm/include/asm/arch-imx8/iomux.h

@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ */
+
+#ifndef __ASM_ARCH_IMX8_IOMUX_H__
+#define __ASM_ARCH_IMX8_IOMUX_H__
+
+/*
+ * We use 64bits value for iomux settings.
+ * High 32bits are used for padring register value,
+ * low 16bits are used for pin index.
+ */
+typedef u64 iomux_cfg_t;
+
+#define PADRING_IFMUX_EN_SHIFT		31
+#define PADRING_IFMUX_EN_MASK		BIT(31)
+#define PADRING_GP_EN_SHIFT		30
+#define PADRING_GP_EN_MASK		BIT(30)
+#define PADRING_IFMUX_SHIFT		27
+#define PADRING_IFMUX_MASK		GENMASK(29, 27)
+#define PADRING_CONFIG_SHIFT		25
+#define PADRING_LPCONFIG_SHIFT		23
+#define PADRING_PULL_SHIFT		5
+#define PADRING_DSE_SHIFT		0
+
+#define MUX_PAD_CTRL_SHIFT	32
+#define MUX_PAD_CTRL_MASK	((iomux_cfg_t)0xFFFFFFFF << MUX_PAD_CTRL_SHIFT)
+#define MUX_PAD_CTRL(x)		((iomux_cfg_t)(x) << MUX_PAD_CTRL_SHIFT)
+#define MUX_MODE_SHIFT		(PADRING_IFMUX_SHIFT + MUX_PAD_CTRL_SHIFT)
+#define MUX_MODE_MASK		((iomux_cfg_t)0x7 << MUX_MODE_SHIFT)
+#define PIN_ID_MASK		((iomux_cfg_t)0xFFFF)
+
+/* Valid mux alt0 to alt7 */
+#define MUX_MODE_ALT(x)		(((iomux_cfg_t)(x) << MUX_MODE_SHIFT) & \
+				 MUX_MODE_MASK)
+
+void imx8_iomux_setup_pad(iomux_cfg_t pad);
+void imx8_iomux_setup_multiple_pads(iomux_cfg_t const *pad_list, u32 count);
+#endif	/* __ASM_ARCH_IMX8_IOMUX_H__ */

+ 15 - 0
arch/arm/include/asm/arch-imx8/power-domain.h

@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2017 NXP
+ */
+
+#ifndef _ASM_ARCH_IMX8_POWER_DOMAIN_H
+#define _ASM_ARCH_IMX8_POWER_DOMAIN_H
+
+#include <asm/arch/sci/types.h>
+
+struct imx8_power_domain_platdata {
+	sc_rsrc_t resource_id;
+};
+
+#endif

+ 158 - 0
arch/arm/include/asm/arch-imx8/sci/rpc.h

@@ -0,0 +1,158 @@
+/* SPDX-License-Identifier:     GPL-2.0+ */
+/*
+ * Copyright 2017-2018 NXP
+ *
+ */
+
+#ifndef SC_RPC_H
+#define SC_RPC_H
+
+/* Note: Check SCFW API Released DOC before you want to modify something */
+#define SC_RPC_VERSION          1U
+
+#define SC_RPC_MAX_MSG          8U
+
+#define RPC_VER(MSG)            ((MSG)->version)
+#define RPC_SIZE(MSG)           ((MSG)->size)
+#define RPC_SVC(MSG)            ((MSG)->svc)
+#define RPC_FUNC(MSG)           ((MSG)->func)
+#define RPC_R8(MSG)             ((MSG)->func)
+#define RPC_I32(MSG, IDX)       ((MSG)->DATA.i32[(IDX) / 4U])
+#define RPC_I16(MSG, IDX)       ((MSG)->DATA.i16[(IDX) / 2U])
+#define RPC_I8(MSG, IDX)        ((MSG)->DATA.i8[(IDX)])
+#define RPC_U32(MSG, IDX)       ((MSG)->DATA.u32[(IDX) / 4U])
+#define RPC_U16(MSG, IDX)       ((MSG)->DATA.u16[(IDX) / 2U])
+#define RPC_U8(MSG, IDX)        ((MSG)->DATA.u8[(IDX)])
+
+#define SC_RPC_SVC_UNKNOWN      0U
+#define SC_RPC_SVC_RETURN       1U
+#define SC_RPC_SVC_PM           2U
+#define SC_RPC_SVC_RM           3U
+#define SC_RPC_SVC_TIMER        5U
+#define SC_RPC_SVC_PAD          6U
+#define SC_RPC_SVC_MISC         7U
+#define SC_RPC_SVC_IRQ          8U
+#define SC_RPC_SVC_ABORT        9U
+
+/* Types */
+
+struct sc_rpc_msg_s {
+	u8 version;
+	u8 size;
+	u8 svc;
+	u8 func;
+	union {
+		s32 i32[(SC_RPC_MAX_MSG - 1U)];
+		s16 i16[(SC_RPC_MAX_MSG - 1U) * 2U];
+		s8 i8[(SC_RPC_MAX_MSG - 1U) * 4U];
+		u32 u32[(SC_RPC_MAX_MSG - 1U)];
+		u16 u16[(SC_RPC_MAX_MSG - 1U) * 2U];
+		u8 u8[(SC_RPC_MAX_MSG - 1U) * 4U];
+	} DATA;
+};
+
+/* PM RPC */
+#define PM_FUNC_UNKNOWN				0
+#define PM_FUNC_SET_SYS_POWER_MODE		19U
+#define PM_FUNC_SET_PARTITION_POWER_MODE	1U
+#define PM_FUNC_GET_SYS_POWER_MODE		2U
+#define PM_FUNC_SET_RESOURCE_POWER_MODE		3U
+#define PM_FUNC_GET_RESOURCE_POWER_MODE		4U
+#define PM_FUNC_REQ_LOW_POWER_MODE		16U
+#define PM_FUNC_REQ_CPU_LOW_POWER_MODE		20U
+#define PM_FUNC_SET_CPU_RESUME_ADDR		17U
+#define PM_FUNC_SET_CPU_RESUME			21U
+#define PM_FUNC_REQ_SYS_IF_POWER_MODE		18U
+#define PM_FUNC_SET_CLOCK_RATE			5U
+#define PM_FUNC_GET_CLOCK_RATE			6U
+#define PM_FUNC_CLOCK_ENABLE			7U
+#define PM_FUNC_SET_CLOCK_PARENT		14U
+#define PM_FUNC_GET_CLOCK_PARENT		15U
+#define PM_FUNC_RESET				13U
+#define PM_FUNC_RESET_REASON			10U
+#define PM_FUNC_BOOT				8U
+#define PM_FUNC_REBOOT				9U
+#define PM_FUNC_REBOOT_PARTITION		12U
+#define PM_FUNC_CPU_START			11U
+
+/* MISC RPC */
+#define MISC_FUNC_UNKNOWN			0
+#define MISC_FUNC_SET_CONTROL			1U
+#define MISC_FUNC_GET_CONTROL			2U
+#define MISC_FUNC_SET_MAX_DMA_GROUP		4U
+#define MISC_FUNC_SET_DMA_GROUP			5U
+#define MISC_FUNC_SECO_IMAGE_LOAD		8U
+#define MISC_FUNC_SECO_AUTHENTICATE		9U
+#define MISC_FUNC_SECO_FUSE_WRITE		20U
+#define MISC_FUNC_SECO_ENABLE_DEBUG		21U
+#define MISC_FUNC_SECO_FORWARD_LIFECYCLE	22U
+#define MISC_FUNC_SECO_RETURN_LIFECYCLE		23U
+#define MISC_FUNC_SECO_BUILD_INFO		24U
+#define MISC_FUNC_DEBUG_OUT			10U
+#define MISC_FUNC_WAVEFORM_CAPTURE		6U
+#define MISC_FUNC_BUILD_INFO			15U
+#define MISC_FUNC_UNIQUE_ID			19U
+#define MISC_FUNC_SET_ARI			3U
+#define MISC_FUNC_BOOT_STATUS			7U
+#define MISC_FUNC_BOOT_DONE			14U
+#define MISC_FUNC_OTP_FUSE_READ			11U
+#define MISC_FUNC_OTP_FUSE_WRITE		17U
+#define MISC_FUNC_SET_TEMP			12U
+#define MISC_FUNC_GET_TEMP			13U
+#define MISC_FUNC_GET_BOOT_DEV			16U
+#define MISC_FUNC_GET_BUTTON_STATUS		18U
+
+/* PAD RPC */
+#define PAD_FUNC_UNKNOWN			0
+#define PAD_FUNC_SET_MUX			1U
+#define PAD_FUNC_GET_MUX			6U
+#define PAD_FUNC_SET_GP				2U
+#define PAD_FUNC_GET_GP				7U
+#define PAD_FUNC_SET_WAKEUP			4U
+#define PAD_FUNC_GET_WAKEUP			9U
+#define PAD_FUNC_SET_ALL			5U
+#define PAD_FUNC_GET_ALL			10U
+#define PAD_FUNC_SET				15U
+#define PAD_FUNC_GET				16U
+#define PAD_FUNC_SET_GP_28FDSOI			11U
+#define PAD_FUNC_GET_GP_28FDSOI			12U
+#define PAD_FUNC_SET_GP_28FDSOI_HSIC		3U
+#define PAD_FUNC_GET_GP_28FDSOI_HSIC		8U
+#define PAD_FUNC_SET_GP_28FDSOI_COMP		13U
+#define PAD_FUNC_GET_GP_28FDSOI_COMP		14U
+
+/* RM RPC */
+#define RM_FUNC_UNKNOWN				0
+#define RM_FUNC_PARTITION_ALLOC			1U
+#define RM_FUNC_SET_CONFIDENTIAL		31U
+#define RM_FUNC_PARTITION_FREE			2U
+#define RM_FUNC_GET_DID				26U
+#define RM_FUNC_PARTITION_STATIC		3U
+#define RM_FUNC_PARTITION_LOCK			4U
+#define RM_FUNC_GET_PARTITION			5U
+#define RM_FUNC_SET_PARENT			6U
+#define RM_FUNC_MOVE_ALL			7U
+#define RM_FUNC_ASSIGN_RESOURCE			8U
+#define RM_FUNC_SET_RESOURCE_MOVABLE		9U
+#define RM_FUNC_SET_SUBSYS_RSRC_MOVABLE		28U
+#define RM_FUNC_SET_MASTER_ATTRIBUTES		10U
+#define RM_FUNC_SET_MASTER_SID			11U
+#define RM_FUNC_SET_PERIPHERAL_PERMISSIONS	12U
+#define RM_FUNC_IS_RESOURCE_OWNED		13U
+#define RM_FUNC_IS_RESOURCE_MASTER		14U
+#define RM_FUNC_IS_RESOURCE_PERIPHERAL		15U
+#define RM_FUNC_GET_RESOURCE_INFO		16U
+#define RM_FUNC_MEMREG_ALLOC			17U
+#define RM_FUNC_MEMREG_SPLIT			29U
+#define RM_FUNC_MEMREG_FREE			18U
+#define RM_FUNC_FIND_MEMREG			30U
+#define RM_FUNC_ASSIGN_MEMREG			19U
+#define RM_FUNC_SET_MEMREG_PERMISSIONS		20U
+#define RM_FUNC_IS_MEMREG_OWNED			21U
+#define RM_FUNC_GET_MEMREG_INFO			22U
+#define RM_FUNC_ASSIGN_PAD			23U
+#define RM_FUNC_SET_PAD_MOVABLE			24U
+#define RM_FUNC_IS_PAD_OWNED			25U
+#define RM_FUNC_DUMP				27U
+
+#endif /* SC_RPC_H */

+ 88 - 0
arch/arm/include/asm/arch-imx8/sci/sci.h

@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ */
+
+#ifndef _SC_SCI_H
+#define _SC_SCI_H
+
+#include <asm/arch/sci/types.h>
+#include <asm/arch/sci/svc/misc/api.h>
+#include <asm/arch/sci/svc/pad/api.h>
+#include <asm/arch/sci/svc/pm/api.h>
+#include <asm/arch/sci/svc/rm/api.h>
+#include <asm/arch/sci/rpc.h>
+#include <dt-bindings/soc/imx_rsrc.h>
+#include <linux/errno.h>
+
+static inline int sc_err_to_linux(sc_err_t err)
+{
+	int ret;
+
+	switch (err) {
+	case SC_ERR_NONE:
+		return 0;
+	case SC_ERR_VERSION:
+	case SC_ERR_CONFIG:
+	case SC_ERR_PARM:
+		ret = -EINVAL;
+		break;
+	case SC_ERR_NOACCESS:
+	case SC_ERR_LOCKED:
+	case SC_ERR_UNAVAILABLE:
+		ret = -EACCES;
+		break;
+	case SC_ERR_NOTFOUND:
+	case SC_ERR_NOPOWER:
+		ret = -ENODEV;
+		break;
+	case SC_ERR_IPC:
+		ret = -EIO;
+		break;
+	case SC_ERR_BUSY:
+		ret = -EBUSY;
+		break;
+	case SC_ERR_FAIL:
+		ret = -EIO;
+		break;
+	default:
+		ret = 0;
+		break;
+	}
+
+	debug("%s %d %d\n", __func__, err, ret);
+
+	return ret;
+}
+
+/* PM API*/
+int sc_pm_set_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
+				  sc_pm_power_mode_t mode);
+int sc_pm_set_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
+			 sc_pm_clock_rate_t *rate);
+int sc_pm_get_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
+			 sc_pm_clock_rate_t *rate);
+int sc_pm_set_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
+			 sc_pm_clock_rate_t *rate);
+int sc_pm_get_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
+			 sc_pm_clock_rate_t *rate);
+int sc_pm_clock_enable(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
+		       sc_bool_t enable, sc_bool_t autog);
+
+/* MISC API */
+int sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource, sc_ctrl_t ctrl,
+			u32 *val);
+void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *boot_dev);
+void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status);
+void sc_misc_build_info(sc_ipc_t ipc, u32 *build, u32 *commit);
+int sc_misc_otp_fuse_read(sc_ipc_t ipc, u32 word, u32 *val);
+
+/* RM API */
+sc_bool_t sc_rm_is_memreg_owned(sc_ipc_t ipc, sc_rm_mr_t mr);
+int sc_rm_get_memreg_info(sc_ipc_t ipc, sc_rm_mr_t mr, sc_faddr_t *addr_start,
+			  sc_faddr_t *addr_end);
+sc_bool_t sc_rm_is_resource_owned(sc_ipc_t ipc, sc_rsrc_t resource);
+
+/* PAD API */
+int sc_pad_set(sc_ipc_t ipc, sc_pad_t pad, u32 val);
+#endif

+ 30 - 0
arch/arm/include/asm/arch-imx8/sci/svc/misc/api.h

@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier:     GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ */
+
+#ifndef SC_MISC_API_H
+#define SC_MISC_API_H
+
+/* Defines for sc_misc_boot_status_t */
+#define SC_MISC_BOOT_STATUS_SUCCESS	0U	/* Success */
+#define SC_MISC_BOOT_STATUS_SECURITY	1U	/* Security violation */
+
+/* Defines for sc_misc_seco_auth_cmd_t */
+#define SC_MISC_SECO_AUTH_SECO_FW	0U   /* SECO Firmware */
+#define SC_MISC_SECO_AUTH_HDMI_TX_FW	1U   /* HDMI TX Firmware */
+#define SC_MISC_SECO_AUTH_HDMI_RX_FW	2U   /* HDMI RX Firmware */
+
+/* Defines for sc_misc_temp_t */
+#define SC_MISC_TEMP			0U	/* Temp sensor */
+#define SC_MISC_TEMP_HIGH		1U	/* Temp high alarm */
+#define SC_MISC_TEMP_LOW		2U	/* Temp low alarm */
+
+/* Defines for sc_misc_seco_auth_cmd_t */
+#define SC_MISC_AUTH_CONTAINER	0U	/* Authenticate container */
+#define SC_MISC_VERIFY_IMAGE	1U	/* Verify image */
+#define SC_MISC_REL_CONTAINER	2U	/* Release container */
+
+typedef u8 sc_misc_boot_status_t;
+
+#endif /* SC_MISC_API_H */

+ 57 - 0
arch/arm/include/asm/arch-imx8/sci/svc/pad/api.h

@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier:     GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ */
+
+#ifndef SC_PAD_API_H
+#define SC_PAD_API_H
+
+/* Defines for sc_pad_config_t */
+#define SC_PAD_CONFIG_NORMAL	0U	/* Normal */
+#define SC_PAD_CONFIG_OD	1U	/* Open Drain */
+#define SC_PAD_CONFIG_OD_IN	2U	/* Open Drain and input */
+#define SC_PAD_CONFIG_OUT_IN	3U	/* Output and input */
+
+/* Defines for sc_pad_iso_t */
+#define SC_PAD_ISO_OFF		0U	/* ISO latch is transparent */
+#define SC_PAD_ISO_EARLY	1U	/* Follow EARLY_ISO */
+#define SC_PAD_ISO_LATE		2U	/* Follow LATE_ISO */
+#define SC_PAD_ISO_ON		3U	/* ISO latched data is held */
+
+/* Defines for sc_pad_28fdsoi_dse_t */
+#define SC_PAD_28FDSOI_DSE_18V_1MA	0U /* Drive strength of 1mA for 1.8v */
+#define SC_PAD_28FDSOI_DSE_18V_2MA	1U /* Drive strength of 2mA for 1.8v */
+#define SC_PAD_28FDSOI_DSE_18V_4MA	2U /* Drive strength of 4mA for 1.8v */
+#define SC_PAD_28FDSOI_DSE_18V_6MA	3U /* Drive strength of 6mA for 1.8v */
+#define SC_PAD_28FDSOI_DSE_18V_8MA	4U /* Drive strength of 8mA for 1.8v */
+#define SC_PAD_28FDSOI_DSE_18V_10MA	5U /* Drive strength of 10mA for 1.8v */
+#define SC_PAD_28FDSOI_DSE_18V_12MA	6U /* Drive strength of 12mA for 1.8v */
+#define SC_PAD_28FDSOI_DSE_18V_HS	7U /* High-speed for 1.8v */
+#define SC_PAD_28FDSOI_DSE_33V_2MA	0U /* Drive strength of 2mA for 3.3v */
+#define SC_PAD_28FDSOI_DSE_33V_4MA	1U /* Drive strength of 4mA for 3.3v */
+#define SC_PAD_28FDSOI_DSE_33V_8MA	2U /* Drive strength of 8mA for 3.3v */
+#define SC_PAD_28FDSOI_DSE_33V_12MA	3U /* Drive strength of 12mA for 3.3v */
+#define SC_PAD_28FDSOI_DSE_DV_HIGH	0U /* High drive strength dual volt */
+#define SC_PAD_28FDSOI_DSE_DV_LOW	1U /* Low drive strength  dual volt */
+
+/* Defines for sc_pad_28fdsoi_ps_t */
+#define SC_PAD_28FDSOI_PS_KEEPER 0U /* Bus-keeper (only valid for 1.8v) */
+#define SC_PAD_28FDSOI_PS_PU	1U /* Pull-up */
+#define SC_PAD_28FDSOI_PS_PD	2U /* Pull-down */
+#define SC_PAD_28FDSOI_PS_NONE	3U /* No pull (disabled) */
+
+/* Defines for sc_pad_28fdsoi_pus_t */
+#define SC_PAD_28FDSOI_PUS_30K_PD	0U /* 30K pull-down */
+#define SC_PAD_28FDSOI_PUS_100K_PU	1U /* 100K pull-up */
+#define SC_PAD_28FDSOI_PUS_3K_PU	2U /* 3K pull-up */
+#define SC_PAD_28FDSOI_PUS_30K_PU	3U /* 30K pull-up */
+
+/* Defines for sc_pad_wakeup_t */
+#define SC_PAD_WAKEUP_OFF	0U /* Off */
+#define SC_PAD_WAKEUP_CLEAR	1U /* Clears pending flag */
+#define SC_PAD_WAKEUP_LOW_LVL	4U /* Low level */
+#define SC_PAD_WAKEUP_FALL_EDGE	5U /* Falling edge */
+#define SC_PAD_WAKEUP_RISE_EDGE	6U /* Rising edge */
+#define SC_PAD_WAKEUP_HIGH_LVL	7U /* High-level */
+
+#endif /* SC_PAD_API_H */

+ 44 - 0
arch/arm/include/asm/arch-imx8/sci/svc/pm/api.h

@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier:     GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ */
+
+#ifndef SC_PM_API_H
+#define SC_PM_API_H
+
+/* Defines for sc_pm_power_mode_t */
+#define SC_PM_PW_MODE_OFF	0U /* Power off */
+#define SC_PM_PW_MODE_STBY	1U /* Power in standby */
+#define SC_PM_PW_MODE_LP	2U /* Power in low-power */
+#define SC_PM_PW_MODE_ON	3U /* Power on */
+
+/* Defines for sc_pm_clk_t */
+#define SC_PM_CLK_SLV_BUS	0U /* Slave bus clock */
+#define SC_PM_CLK_MST_BUS	1U /* Master bus clock */
+#define SC_PM_CLK_PER		2U /* Peripheral clock */
+#define SC_PM_CLK_PHY		3U /* Phy clock */
+#define SC_PM_CLK_MISC		4U /* Misc clock */
+#define SC_PM_CLK_MISC0		0U /* Misc 0 clock */
+#define SC_PM_CLK_MISC1		1U /* Misc 1 clock */
+#define SC_PM_CLK_MISC2		2U /* Misc 2 clock */
+#define SC_PM_CLK_MISC3		3U /* Misc 3 clock */
+#define SC_PM_CLK_MISC4		4U /* Misc 4 clock */
+#define SC_PM_CLK_CPU		2U /* CPU clock */
+#define SC_PM_CLK_PLL		4U /* PLL */
+#define SC_PM_CLK_BYPASS	4U /* Bypass clock */
+
+/* Defines for sc_pm_clk_mode_t */
+#define SC_PM_CLK_MODE_ROM_INIT		0U /* Clock is initialized by ROM. */
+#define SC_PM_CLK_MODE_OFF		1U /* Clock is disabled */
+#define SC_PM_CLK_MODE_ON		2U /* Clock is enabled. */
+#define SC_PM_CLK_MODE_AUTOGATE_SW	3U /* Clock is in SW autogate mode */
+#define SC_PM_CLK_MODE_AUTOGATE_HW	4U /* Clock is in HW autogate mode */
+#define SC_PM_CLK_MODE_AUTOGATE_SW_HW	5U /* Clock is in SW-HW autogate mode */
+
+typedef u8 sc_pm_power_mode_t;
+typedef u8 sc_pm_clk_t;
+typedef u8 sc_pm_clk_mode_t;
+typedef u8 sc_pm_clk_parent_t;
+typedef u32 sc_pm_clock_rate_t;
+
+#endif /* SC_PM_API_H */

+ 69 - 0
arch/arm/include/asm/arch-imx8/sci/svc/rm/api.h

@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier:     GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ */
+
+#ifndef SC_RM_API_H
+#define SC_RM_API_H
+
+#include <asm/arch/sci/types.h>
+
+/* Defines for type widths */
+#define SC_RM_PARTITION_W   5U      /* Width of sc_rm_pt_t */
+#define SC_RM_MEMREG_W      6U      /* Width of sc_rm_mr_t */
+#define SC_RM_DID_W         4U      /* Width of sc_rm_did_t */
+#define SC_RM_SID_W         6U      /* Width of sc_rm_sid_t */
+#define SC_RM_SPA_W         2U      /* Width of sc_rm_spa_t */
+#define SC_RM_PERM_W        3U      /* Width of sc_rm_perm_t */
+
+/* Defines for ALL parameters */
+#define SC_RM_PT_ALL        ((sc_rm_pt_t)UINT8_MAX)   /* All partitions */
+#define SC_RM_MR_ALL        ((sc_rm_mr_t)UINT8_MAX)   /* All memory regions */
+
+/* Defines for sc_rm_spa_t */
+#define SC_RM_SPA_PASSTHRU  0U   /* Pass through (attribute driven by master) */
+#define SC_RM_SPA_PASSSID   1U   /* Pass through and output on SID */
+#define SC_RM_SPA_ASSERT    2U   /* Assert (force to be secure/privileged) */
+#define SC_RM_SPA_NEGATE    3U   /* Negate (force to be non-secure/user) */
+
+/* Defines for sc_rm_perm_t */
+#define SC_RM_PERM_NONE         0U /* No access */
+#define SC_RM_PERM_SEC_R        1U /* Secure RO */
+#define SC_RM_PERM_SECPRIV_RW   2U /* Secure privilege R/W */
+#define SC_RM_PERM_SEC_RW       3U /* Secure R/W */
+#define SC_RM_PERM_NSPRIV_R     4U /* Secure R/W, non-secure privilege RO */
+#define SC_RM_PERM_NS_R         5U /* Secure R/W, non-secure RO */
+#define SC_RM_PERM_NSPRIV_RW    6U /* Secure R/W, non-secure privilege R/W */
+#define SC_RM_PERM_FULL         7U /* Full access */
+
+/* Types */
+
+/*!
+ * This type is used to declare a resource partition.
+ */
+typedef u8 sc_rm_pt_t;
+
+/*!
+ * This type is used to declare a memory region.
+ */
+typedef u8 sc_rm_mr_t;
+
+/*!
+ * This type is used to declare a resource domain ID used by the
+ * isolation HW.
+ */
+typedef u8 sc_rm_did_t;
+
+/*!
+ * This type is used to declare an SMMU StreamID.
+ */
+typedef u16 sc_rm_sid_t;
+
+/*!
+ * This type is a used to declare master transaction attributes.
+ */
+typedef u8 sc_rm_spa_t;
+
+typedef u8 sc_rm_perm_t;
+
+#endif /* SC_RM_API_H */

+ 220 - 0
arch/arm/include/asm/arch-imx8/sci/types.h

@@ -0,0 +1,220 @@
+/* SPDX-License-Identifier:     GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ */
+
+#ifndef SC_TYPES_H
+#define SC_TYPES_H
+
+/* Includes */
+#include <linux/types.h>
+
+/* Defines */
+/*
+ * This type is used to declare a handle for an IPC communication
+ * channel. Its meaning is specific to the IPC implementation.
+ */
+typedef u64 sc_ipc_t;
+
+/* Defines for common frequencies */
+#define SC_32KHZ            32768U   /* 32KHz */
+#define SC_10MHZ         10000000U   /* 10MHz */
+#define SC_20MHZ         20000000U   /* 20MHz */
+#define SC_25MHZ         25000000U   /* 25MHz */
+#define SC_27MHZ         27000000U   /* 27MHz */
+#define SC_40MHZ         40000000U   /* 40MHz */
+#define SC_45MHZ         45000000U   /* 45MHz */
+#define SC_50MHZ         50000000U   /* 50MHz */
+#define SC_60MHZ         60000000U   /* 60MHz */
+#define SC_66MHZ         66666666U   /* 66MHz */
+#define SC_74MHZ         74250000U   /* 74.25MHz */
+#define SC_80MHZ         80000000U   /* 80MHz */
+#define SC_83MHZ         83333333U   /* 83MHz */
+#define SC_84MHZ         84375000U   /* 84.37MHz */
+#define SC_100MHZ       100000000U   /* 100MHz */
+#define SC_125MHZ       125000000U   /* 125MHz */
+#define SC_133MHZ       133333333U   /* 133MHz */
+#define SC_135MHZ       135000000U   /* 135MHz */
+#define SC_150MHZ       150000000U   /* 150MHz */
+#define SC_160MHZ       160000000U   /* 160MHz */
+#define SC_166MHZ       166666666U   /* 166MHz */
+#define SC_175MHZ       175000000U   /* 175MHz */
+#define SC_180MHZ       180000000U   /* 180MHz */
+#define SC_200MHZ       200000000U   /* 200MHz */
+#define SC_250MHZ       250000000U   /* 250MHz */
+#define SC_266MHZ       266666666U   /* 266MHz */
+#define SC_300MHZ       300000000U   /* 300MHz */
+#define SC_312MHZ       312500000U   /* 312.5MHZ */
+#define SC_320MHZ       320000000U   /* 320MHz */
+#define SC_325MHZ       325000000U   /* 325MHz */
+#define SC_333MHZ       333333333U   /* 333MHz */
+#define SC_350MHZ       350000000U   /* 350MHz */
+#define SC_372MHZ       372000000U   /* 372MHz */
+#define SC_375MHZ       375000000U   /* 375MHz */
+#define SC_400MHZ       400000000U   /* 400MHz */
+#define SC_500MHZ       500000000U   /* 500MHz */
+#define SC_594MHZ       594000000U   /* 594MHz */
+#define SC_625MHZ       625000000U   /* 625MHz */
+#define SC_640MHZ       640000000U   /* 640MHz */
+#define SC_650MHZ       650000000U   /* 650MHz */
+#define SC_667MHZ       666666667U   /* 667MHz */
+#define SC_675MHZ       675000000U   /* 675MHz */
+#define SC_700MHZ       700000000U   /* 700MHz */
+#define SC_720MHZ       720000000U   /* 720MHz */
+#define SC_750MHZ       750000000U   /* 750MHz */
+#define SC_800MHZ       800000000U   /* 800MHz */
+#define SC_850MHZ       850000000U   /* 850MHz */
+#define SC_900MHZ       900000000U   /* 900MHz */
+#define SC_1000MHZ     1000000000U   /* 1GHz */
+#define SC_1060MHZ     1060000000U   /* 1.06GHz */
+#define SC_1188MHZ     1188000000U   /* 1.188GHz */
+#define SC_1260MHZ     1260000000U   /* 1.26GHz */
+#define SC_1280MHZ     1280000000U   /* 1.28GHz */
+#define SC_1300MHZ     1300000000U   /* 1.3GHz */
+#define SC_1400MHZ     1400000000U   /* 1.4GHz */
+#define SC_1500MHZ     1500000000U   /* 1.5GHz */
+#define SC_1600MHZ     1600000000U   /* 1.6GHz */
+#define SC_1800MHZ     1800000000U   /* 1.8GHz */
+#define SC_2000MHZ     2000000000U   /* 2.0GHz */
+#define SC_2112MHZ     2112000000U   /* 2.12GHz */
+
+/* Defines for 24M related frequencies */
+#define SC_8MHZ           8000000U   /* 8MHz */
+#define SC_12MHZ         12000000U   /* 12MHz */
+#define SC_19MHZ         19800000U   /* 19.8MHz */
+#define SC_24MHZ         24000000U   /* 24MHz */
+#define SC_48MHZ         48000000U   /* 48MHz */
+#define SC_120MHZ       120000000U   /* 120MHz */
+#define SC_132MHZ       132000000U   /* 132MHz */
+#define SC_144MHZ       144000000U   /* 144MHz */
+#define SC_192MHZ       192000000U   /* 192MHz */
+#define SC_211MHZ       211200000U   /* 211.2MHz */
+#define SC_240MHZ       240000000U   /* 240MHz */
+#define SC_264MHZ       264000000U   /* 264MHz */
+#define SC_352MHZ       352000000U   /* 352MHz */
+#define SC_360MHZ       360000000U   /* 360MHz */
+#define SC_384MHZ       384000000U   /* 384MHz */
+#define SC_396MHZ       396000000U   /* 396MHz */
+#define SC_432MHZ       432000000U   /* 432MHz */
+#define SC_480MHZ       480000000U   /* 480MHz */
+#define SC_600MHZ       600000000U   /* 600MHz */
+#define SC_744MHZ       744000000U   /* 744MHz */
+#define SC_792MHZ       792000000U   /* 792MHz */
+#define SC_864MHZ       864000000U   /* 864MHz */
+#define SC_960MHZ       960000000U   /* 960MHz */
+#define SC_1056MHZ     1056000000U   /* 1056MHz */
+#define SC_1104MHZ     1104000000U   /* 1104MHz */
+#define SC_1200MHZ     1200000000U   /* 1.2GHz */
+#define SC_1464MHZ     1464000000U   /* 1.464GHz */
+#define SC_2400MHZ     2400000000U   /* 2.4GHz */
+
+/* Defines for A/V related frequencies */
+#define SC_62MHZ         62937500U   /* 62.9375MHz */
+#define SC_755MHZ       755250000U   /* 755.25MHz */
+
+/* Defines for type widths */
+#define SC_FADDR_W      36U          /* Width of sc_faddr_t */
+#define SC_BOOL_W       1U           /* Width of sc_bool_t */
+#define SC_ERR_W        4U           /* Width of sc_err_t */
+#define SC_RSRC_W       10U          /* Width of sc_rsrc_t */
+#define SC_CTRL_W       6U           /* Width of sc_ctrl_t */
+
+/* Defines for sc_bool_t */
+#define SC_FALSE        ((sc_bool_t)0U)
+#define SC_TRUE         ((sc_bool_t)1U)
+
+/* Defines for sc_err_t */
+#define SC_ERR_NONE         0U      /* Success */
+#define SC_ERR_VERSION      1U      /* Incompatible API version */
+#define SC_ERR_CONFIG       2U      /* Configuration error */
+#define SC_ERR_PARM         3U      /* Bad parameter */
+#define SC_ERR_NOACCESS     4U      /* Permission error (no access) */
+#define SC_ERR_LOCKED       5U      /* Permission error (locked) */
+#define SC_ERR_UNAVAILABLE  6U      /* Unavailable (out of resources) */
+#define SC_ERR_NOTFOUND     7U      /* Not found */
+#define SC_ERR_NOPOWER      8U      /* No power */
+#define SC_ERR_IPC          9U      /* Generic IPC error */
+#define SC_ERR_BUSY         10U     /* Resource is currently busy/active */
+#define SC_ERR_FAIL         11U     /* General I/O failure */
+#define SC_ERR_LAST         12U
+
+/* Defines for sc_ctrl_t. */
+#define SC_C_TEMP                       0U
+#define SC_C_TEMP_HI                    1U
+#define SC_C_TEMP_LOW                   2U
+#define SC_C_PXL_LINK_MST1_ADDR         3U
+#define SC_C_PXL_LINK_MST2_ADDR         4U
+#define SC_C_PXL_LINK_MST_ENB           5U
+#define SC_C_PXL_LINK_MST1_ENB          6U
+#define SC_C_PXL_LINK_MST2_ENB          7U
+#define SC_C_PXL_LINK_SLV1_ADDR         8U
+#define SC_C_PXL_LINK_SLV2_ADDR         9U
+#define SC_C_PXL_LINK_MST_VLD           10U
+#define SC_C_PXL_LINK_MST1_VLD          11U
+#define SC_C_PXL_LINK_MST2_VLD          12U
+#define SC_C_SINGLE_MODE                13U
+#define SC_C_ID                         14U
+#define SC_C_PXL_CLK_POLARITY           15U
+#define SC_C_LINESTATE                  16U
+#define SC_C_PCIE_G_RST                 17U
+#define SC_C_PCIE_BUTTON_RST            18U
+#define SC_C_PCIE_PERST                 19U
+#define SC_C_PHY_RESET                  20U
+#define SC_C_PXL_LINK_RATE_CORRECTION   21U
+#define SC_C_PANIC                      22U
+#define SC_C_PRIORITY_GROUP             23U
+#define SC_C_TXCLK                      24U
+#define SC_C_CLKDIV                     25U
+#define SC_C_DISABLE_50                 26U
+#define SC_C_DISABLE_125                27U
+#define SC_C_SEL_125                    28U
+#define SC_C_MODE                       29U
+#define SC_C_SYNC_CTRL0                 30U
+#define SC_C_KACHUNK_CNT                31U
+#define SC_C_KACHUNK_SEL                32U
+#define SC_C_SYNC_CTRL1                 33U
+#define SC_C_DPI_RESET                  34U
+#define SC_C_MIPI_RESET                 35U
+#define SC_C_DUAL_MODE                  36U
+#define SC_C_VOLTAGE                    37U
+#define SC_C_PXL_LINK_SEL               38U
+#define SC_C_OFS_SEL                    39U
+#define SC_C_OFS_AUDIO                  40U
+#define SC_C_OFS_PERIPH                 41U
+#define SC_C_OFS_IRQ                    42U
+#define SC_C_RST0                       43U
+#define SC_C_RST1                       44U
+#define SC_C_SEL0                       45U
+#define SC_C_LAST                       46U
+
+#define SC_P_ALL        ((sc_pad_t)UINT16_MAX)   /* All pads */
+
+/* Types */
+
+/* This type is used to store a boolean */
+typedef u8 sc_bool_t;
+
+/* This type is used to store a system (full-size) address.  */
+typedef u64 sc_faddr_t;
+
+/* This type is used to indicate error response for most functions.  */
+typedef u8 sc_err_t;
+
+/*
+ * This type is used to indicate a resource. Resources include peripherals
+ * and bus masters (but not memory regions). Note items from list should
+ * never be changed or removed (only added to at the end of the list).
+ */
+typedef u16 sc_rsrc_t;
+
+/* This type is used to indicate a control.  */
+typedef u8 sc_ctrl_t;
+
+/*
+ * This type is used to indicate a pad. Valid values are SoC specific.
+ *
+ * Refer to the SoC [Pad List](@ref PADS) for valid pad values.
+ */
+typedef u16 sc_pad_t;
+
+#endif /* SC_TYPES_H */

+ 19 - 0
arch/arm/include/asm/arch-imx8/sys_proto.h

@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ */
+
+#include <asm/mach-imx/sys_proto.h>
+#include <linux/types.h>
+
+struct pass_over_info_t {
+	u16 barker;
+	u16 len;
+	u32 g_bt_cfg_shadow;
+	u32 card_address_mode;
+	u32 bad_block_count_met;
+	u32 g_ap_mu;
+};
+
+enum boot_device get_boot_device(void);
+int print_bootinfo(void);

+ 1 - 0
arch/arm/include/asm/arch-mx5/clock.h

@@ -38,6 +38,7 @@ enum mxc_clock {
 	MXC_NFC_CLK,
 	MXC_PERIPH_CLK,
 	MXC_I2C_CLK,
+	MXC_LDB_CLK,
 };
 
 u32 imx_get_uartclk(void);

+ 26 - 0
arch/arm/include/asm/armv8/cpu.h

@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ */
+
+#define MIDR_PARTNUM_CORTEX_A35	0xD04
+#define MIDR_PARTNUM_CORTEX_A53	0xD03
+#define MIDR_PARTNUM_CORTEX_A72	0xD08
+#define MIDR_PARTNUM_SHIFT	0x4
+#define MIDR_PARTNUM_MASK	(0xFFF << 0x4)
+
+static inline unsigned int read_midr(void)
+{
+	unsigned long val;
+
+	asm volatile("mrs %0, midr_el1" : "=r" (val));
+
+	return val;
+}
+
+#define is_cortex_a35() (((read_midr() & MIDR_PARTNUM_MASK) >> \
+			 MIDR_PARTNUM_SHIFT) == MIDR_PARTNUM_CORTEX_A35)
+#define is_cortex_a53() (((read_midr() & MIDR_PARTNUM_MASK) >> \
+			 MIDR_PARTNUM_SHIFT) == MIDR_PARTNUM_CORTEX_A53)
+#define is_cortex_a72() (((read_midr() & MIDR_PARTNUM_MASK) >>\
+			 MIDR_PARTNUM_SHIFT) == MIDR_PARTNUM_CORTEX_A72)

+ 4 - 0
arch/arm/include/asm/global_data.h

@@ -74,6 +74,10 @@ struct arch_global_data {
 #if defined(CONFIG_FSL_LSCH3) && defined(CONFIG_SYS_FSL_HAS_DP_DDR)
 	unsigned long mem2_clk;
 #endif
+
+#ifdef CONFIG_ARCH_IMX8
+	struct udevice *scu_dev;
+#endif
 };
 
 #include <asm-generic/global_data.h>

+ 1 - 0
arch/arm/include/asm/mach-imx/boot_mode.h

@@ -25,6 +25,7 @@ enum boot_device {
 	MMC4_BOOT,
 	NAND_BOOT,
 	QSPI_BOOT,
+	FLEXSPI_BOOT,
 	USB_BOOT,
 	UNKNOWN_BOOT,
 	BOOT_DEV_NUM = UNKNOWN_BOOT,

+ 3 - 0
arch/arm/include/asm/mach-imx/sys_proto.h

@@ -27,6 +27,7 @@
 #define is_mx6() (is_soc_type(MXC_SOC_MX6))
 #define is_mx7() (is_soc_type(MXC_SOC_MX7))
 #define is_mx8m() (is_soc_type(MXC_SOC_MX8M))
+#define is_imx8() (is_soc_type(MXC_SOC_IMX8))
 
 #define is_mx6dqp() (is_cpu_type(MXC_CPU_MX6QP) || is_cpu_type(MXC_CPU_MX6DP))
 #define is_mx6dq() (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D))
@@ -41,6 +42,8 @@
 
 #define is_mx7ulp() (is_cpu_type(MXC_CPU_MX7ULP))
 
+#define is_imx8qxp() (is_cpu_type(MXC_CPU_IMX8QXP))
+
 #ifdef CONFIG_MX6
 #define IMX6_SRC_GPR10_BMODE		BIT(28)
 

+ 21 - 7
arch/arm/mach-imx/Makefile

@@ -31,10 +31,12 @@ obj-y 	+= cpu.o
 obj-$(CONFIG_SYS_I2C_MXC) += i2c-mxv7.o
 obj-$(CONFIG_ENV_IS_IN_MMC) += mmc_env.o
 endif
+ifeq ($(SOC),$(filter $(SOC),mx5 mx6 mx7))
+obj-$(CONFIG_IMX_VIDEO_SKIP) += video.o
+endif
 ifeq ($(SOC),$(filter $(SOC),mx6 mx7))
 obj-y 	+= cache.o init.o
 obj-$(CONFIG_FEC_MXC) += mac.o
-obj-$(CONFIG_IMX_VIDEO_SKIP) += video.o
 obj-$(CONFIG_IMX_RDC) += rdc-sema.o
 ifneq ($(CONFIG_SPL_BUILD),y)
 obj-$(CONFIG_IMX_BOOTAUX) += imx_bootaux.o
@@ -84,24 +86,35 @@ IMX_CONFIG = $(CONFIG_IMX_CONFIG:"%"=%)
 	$(Q)mkdir -p $(dir $@)
 	$(call if_changed_dep,cpp_cfg)
 
-MKIMAGEFLAGS_u-boot.imx = -n $(filter-out $(PLUGIN).bin $< $(PHONY),$^) -T imximage \
-	-e $(CONFIG_SYS_TEXT_BASE)
+ifeq ($(CONFIG_ARCH_IMX8), y)
+CNTR_DEPFILES := $(srctree)/tools/imx_cntr_image.sh
+IMAGE_TYPE := imx8image
+DEPFILE_EXISTS := $(shell if [ -f u-boot-dtb.cfgout ]; then $(CNTR_DEPFILES) u-boot-dtb.cfgout; echo $$?; fi)
+else
+IMAGE_TYPE := imximage
+DEPFILE_EXISTS := 0
+endif
+
+MKIMAGEFLAGS_u-boot.imx = -n $(filter-out $(PLUGIN).bin $< $(PHONY),$^) \
+	-T $(IMAGE_TYPE) -e $(CONFIG_SYS_TEXT_BASE)
 u-boot.imx: MKIMAGEOUTPUT = u-boot.imx.log
 
 u-boot.imx: u-boot.bin u-boot.cfgout $(PLUGIN).bin FORCE
 	$(call if_changed,mkimage)
 
 ifeq ($(CONFIG_OF_SEPARATE),y)
-MKIMAGEFLAGS_u-boot-dtb.imx = -n $(filter-out $(PLUGIN).bin $< $(PHONY),$^) -T imximage \
-	-e $(CONFIG_SYS_TEXT_BASE)
+MKIMAGEFLAGS_u-boot-dtb.imx = -n $(filter-out $(PLUGIN).bin $< $(PHONY),$^) \
+	-T $(IMAGE_TYPE) -e $(CONFIG_SYS_TEXT_BASE)
 u-boot-dtb.imx: MKIMAGEOUTPUT = u-boot-dtb.imx.log
 
 u-boot-dtb.imx: u-boot-dtb.bin u-boot-dtb.cfgout $(PLUGIN).bin FORCE
+ifeq ($(DEPFILE_EXISTS),0)
 	$(call if_changed,mkimage)
 endif
+endif
 
-MKIMAGEFLAGS_SPL = -n $(filter-out $(PLUGIN).bin $< $(PHONY),$^) -T imximage \
-	-e $(CONFIG_SPL_TEXT_BASE)
+MKIMAGEFLAGS_SPL = -n $(filter-out $(PLUGIN).bin $< $(PHONY),$^) \
+		   -T $(IMAGE_TYPE) -e $(CONFIG_SPL_TEXT_BASE)
 SPL: MKIMAGEOUTPUT = SPL.log
 
 SPL: spl/u-boot-spl.bin spl/u-boot-spl.cfgout $(PLUGIN).bin FORCE
@@ -141,3 +154,4 @@ obj-$(CONFIG_MX6) += mx6/
 obj-$(CONFIG_MX7) += mx7/
 obj-$(CONFIG_ARCH_MX7ULP) += mx7ulp/
 obj-$(CONFIG_MX8M) += mx8m/
+obj-$(CONFIG_ARCH_IMX8) += imx8/

+ 26 - 0
arch/arm/mach-imx/imx8/Kconfig

@@ -0,0 +1,26 @@
+if ARCH_IMX8
+
+config IMX8
+	bool
+
+config IMX8QXP
+	select IMX8
+	bool
+
+config SYS_SOC
+	default "imx8"
+
+choice
+	prompt "i.MX8 board select"
+	optional
+
+config TARGET_IMX8QXP_MEK
+	bool "Support i.MX8QXP MEK board"
+	select BOARD_LATE_INIT
+	select IMX8QXP
+
+endchoice
+
+source "board/freescale/imx8qxp_mek/Kconfig"
+
+endif

+ 7 - 0
arch/arm/mach-imx/imx8/Makefile

@@ -0,0 +1,7 @@
+#
+# Copyright 2018 NXP
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y += cpu.o iomux.o

+ 21 - 0
arch/arm/mach-imx/imx8/clock.c

@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ */
+
+#include <common.h>
+#include <linux/errno.h>
+#include <asm/arch/clock.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+u32 mxc_get_clock(enum mxc_clock clk)
+{
+	switch (clk) {
+	default:
+		printf("Unsupported mxc_clock %d\n", clk);
+		break;
+	}
+
+	return 0;
+}

+ 646 - 0
arch/arm/mach-imx/imx8/cpu.c

@@ -0,0 +1,646 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <cpu.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/uclass.h>
+#include <errno.h>
+#include <asm/arch/sci/sci.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch-imx/cpu.h>
+#include <asm/armv8/cpu.h>
+#include <asm/armv8/mmu.h>
+#include <asm/mach-imx/boot_mode.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define BT_PASSOVER_TAG	0x504F
+struct pass_over_info_t *get_pass_over_info(void)
+{
+	struct pass_over_info_t *p =
+		(struct pass_over_info_t *)PASS_OVER_INFO_ADDR;
+
+	if (p->barker != BT_PASSOVER_TAG ||
+	    p->len != sizeof(struct pass_over_info_t))
+		return NULL;
+
+	return p;
+}
+
+int arch_cpu_init(void)
+{
+	struct pass_over_info_t *pass_over = get_pass_over_info();
+
+	if (pass_over && pass_over->g_ap_mu == 0) {
+		/*
+		 * When ap_mu is 0, means the U-Boot booted
+		 * from first container
+		 */
+		sc_misc_boot_status(-1, SC_MISC_BOOT_STATUS_SUCCESS);
+	}
+
+	return 0;
+}
+
+int arch_cpu_init_dm(void)
+{
+	struct udevice *devp;
+	int node, ret;
+
+	node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "fsl,imx8-mu");
+	ret = device_bind_driver_to_node(gd->dm_root, "imx8_scu", "imx8_scu",
+					 offset_to_ofnode(node), &devp);
+
+	if (ret) {
+		printf("could not find scu %d\n", ret);
+		return ret;
+	}
+
+	ret = device_probe(devp);
+	if (ret) {
+		printf("scu probe failed %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+int print_bootinfo(void)
+{
+	enum boot_device bt_dev = get_boot_device();
+
+	puts("Boot:  ");
+	switch (bt_dev) {
+	case SD1_BOOT:
+		puts("SD0\n");
+		break;
+	case SD2_BOOT:
+		puts("SD1\n");
+		break;
+	case SD3_BOOT:
+		puts("SD2\n");
+		break;
+	case MMC1_BOOT:
+		puts("MMC0\n");
+		break;
+	case MMC2_BOOT:
+		puts("MMC1\n");
+		break;
+	case MMC3_BOOT:
+		puts("MMC2\n");
+		break;
+	case FLEXSPI_BOOT:
+		puts("FLEXSPI\n");
+		break;
+	case SATA_BOOT:
+		puts("SATA\n");
+		break;
+	case NAND_BOOT:
+		puts("NAND\n");
+		break;
+	case USB_BOOT:
+		puts("USB\n");
+		break;
+	default:
+		printf("Unknown device %u\n", bt_dev);
+		break;
+	}
+
+	return 0;
+}
+
+enum boot_device get_boot_device(void)
+{
+	enum boot_device boot_dev = SD1_BOOT;
+
+	sc_rsrc_t dev_rsrc;
+
+	sc_misc_get_boot_dev(-1, &dev_rsrc);
+
+	switch (dev_rsrc) {
+	case SC_R_SDHC_0:
+		boot_dev = MMC1_BOOT;
+		break;
+	case SC_R_SDHC_1:
+		boot_dev = SD2_BOOT;
+		break;
+	case SC_R_SDHC_2:
+		boot_dev = SD3_BOOT;
+		break;
+	case SC_R_NAND:
+		boot_dev = NAND_BOOT;
+		break;
+	case SC_R_FSPI_0:
+		boot_dev = FLEXSPI_BOOT;
+		break;
+	case SC_R_SATA_0:
+		boot_dev = SATA_BOOT;
+		break;
+	case SC_R_USB_0:
+	case SC_R_USB_1:
+	case SC_R_USB_2:
+		boot_dev = USB_BOOT;
+		break;
+	default:
+		break;
+	}
+
+	return boot_dev;
+}
+
+#ifdef CONFIG_ENV_IS_IN_MMC
+__weak int board_mmc_get_env_dev(int devno)
+{
+	return CONFIG_SYS_MMC_ENV_DEV;
+}
+
+int mmc_get_env_dev(void)
+{
+	sc_rsrc_t dev_rsrc;
+	int devno;
+
+	sc_misc_get_boot_dev(-1, &dev_rsrc);
+
+	switch (dev_rsrc) {
+	case SC_R_SDHC_0:
+		devno = 0;
+		break;
+	case SC_R_SDHC_1:
+		devno = 1;
+		break;
+	case SC_R_SDHC_2:
+		devno = 2;
+		break;
+	default:
+		/* If not boot from sd/mmc, use default value */
+		return CONFIG_SYS_MMC_ENV_DEV;
+	}
+
+	return board_mmc_get_env_dev(devno);
+}
+#endif
+
+#define MEMSTART_ALIGNMENT  SZ_2M /* Align the memory start with 2MB */
+
+static int get_owned_memreg(sc_rm_mr_t mr, sc_faddr_t *addr_start,
+			    sc_faddr_t *addr_end)
+{
+	sc_faddr_t start, end;
+	int ret;
+	bool owned;
+
+	owned = sc_rm_is_memreg_owned(-1, mr);
+	if (owned) {
+		ret = sc_rm_get_memreg_info(-1, mr, &start, &end);
+		if (ret) {
+			printf("Memreg get info failed, %d\n", ret);
+			return -EINVAL;
+		}
+		debug("0x%llx -- 0x%llx\n", start, end);
+		*addr_start = start;
+		*addr_end = end;
+
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+phys_size_t get_effective_memsize(void)
+{
+	sc_rm_mr_t mr;
+	sc_faddr_t start, end, end1;
+	int err;
+
+	end1 = (sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE;
+
+	for (mr = 0; mr < 64; mr++) {
+		err = get_owned_memreg(mr, &start, &end);
+		if (!err) {
+			start = roundup(start, MEMSTART_ALIGNMENT);
+			/* Too small memory region, not use it */
+			if (start > end)
+				continue;
+
+			/* Find the memory region runs the U-Boot */
+			if (start >= PHYS_SDRAM_1 && start <= end1 &&
+			    (start <= CONFIG_SYS_TEXT_BASE &&
+			    end >= CONFIG_SYS_TEXT_BASE)) {
+				if ((end + 1) <= ((sc_faddr_t)PHYS_SDRAM_1 +
+				    PHYS_SDRAM_1_SIZE))
+					return (end - PHYS_SDRAM_1 + 1);
+				else
+					return PHYS_SDRAM_1_SIZE;
+			}
+		}
+	}
+
+	return PHYS_SDRAM_1_SIZE;
+}
+
+int dram_init(void)
+{
+	sc_rm_mr_t mr;
+	sc_faddr_t start, end, end1, end2;
+	int err;
+
+	end1 = (sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE;
+	end2 = (sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE;
+	for (mr = 0; mr < 64; mr++) {
+		err = get_owned_memreg(mr, &start, &end);
+		if (!err) {
+			start = roundup(start, MEMSTART_ALIGNMENT);
+			/* Too small memory region, not use it */
+			if (start > end)
+				continue;
+
+			if (start >= PHYS_SDRAM_1 && start <= end1) {
+				if ((end + 1) <= end1)
+					gd->ram_size += end - start + 1;
+				else
+					gd->ram_size += end1 - start;
+			} else if (start >= PHYS_SDRAM_2 && start <= end2) {
+				if ((end + 1) <= end2)
+					gd->ram_size += end - start + 1;
+				else
+					gd->ram_size += end2 - start;
+			}
+		}
+	}
+
+	/* If error, set to the default value */
+	if (!gd->ram_size) {
+		gd->ram_size = PHYS_SDRAM_1_SIZE;
+		gd->ram_size += PHYS_SDRAM_2_SIZE;
+	}
+	return 0;
+}
+
+static void dram_bank_sort(int current_bank)
+{
+	phys_addr_t start;
+	phys_size_t size;
+
+	while (current_bank > 0) {
+		if (gd->bd->bi_dram[current_bank - 1].start >
+		    gd->bd->bi_dram[current_bank].start) {
+			start = gd->bd->bi_dram[current_bank - 1].start;
+			size = gd->bd->bi_dram[current_bank - 1].size;
+
+			gd->bd->bi_dram[current_bank - 1].start =
+				gd->bd->bi_dram[current_bank].start;
+			gd->bd->bi_dram[current_bank - 1].size =
+				gd->bd->bi_dram[current_bank].size;
+
+			gd->bd->bi_dram[current_bank].start = start;
+			gd->bd->bi_dram[current_bank].size = size;
+		}
+		current_bank--;
+	}
+}
+
+int dram_init_banksize(void)
+{
+	sc_rm_mr_t mr;
+	sc_faddr_t start, end, end1, end2;
+	int i = 0;
+	int err;
+
+	end1 = (sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE;
+	end2 = (sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE;
+
+	for (mr = 0; mr < 64 && i < CONFIG_NR_DRAM_BANKS; mr++) {
+		err = get_owned_memreg(mr, &start, &end);
+		if (!err) {
+			start = roundup(start, MEMSTART_ALIGNMENT);
+			if (start > end) /* Small memory region, no use it */
+				continue;
+
+			if (start >= PHYS_SDRAM_1 && start <= end1) {
+				gd->bd->bi_dram[i].start = start;
+
+				if ((end + 1) <= end1)
+					gd->bd->bi_dram[i].size =
+						end - start + 1;
+				else
+					gd->bd->bi_dram[i].size = end1 - start;
+
+				dram_bank_sort(i);
+				i++;
+			} else if (start >= PHYS_SDRAM_2 && start <= end2) {
+				gd->bd->bi_dram[i].start = start;
+
+				if ((end + 1) <= end2)
+					gd->bd->bi_dram[i].size =
+						end - start + 1;
+				else
+					gd->bd->bi_dram[i].size = end2 - start;
+
+				dram_bank_sort(i);
+				i++;
+			}
+		}
+	}
+
+	/* If error, set to the default value */
+	if (!i) {
+		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;
+	}
+
+	return 0;
+}
+
+static u64 get_block_attrs(sc_faddr_t addr_start)
+{
+	u64 attr = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE |
+		PTE_BLOCK_PXN | PTE_BLOCK_UXN;
+
+	if ((addr_start >= PHYS_SDRAM_1 &&
+	     addr_start <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) ||
+	    (addr_start >= PHYS_SDRAM_2 &&
+	     addr_start <= ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE)))
+		return (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE);
+
+	return attr;
+}
+
+static u64 get_block_size(sc_faddr_t addr_start, sc_faddr_t addr_end)
+{
+	sc_faddr_t end1, end2;
+
+	end1 = (sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE;
+	end2 = (sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE;
+
+	if (addr_start >= PHYS_SDRAM_1 && addr_start <= end1) {
+		if ((addr_end + 1) > end1)
+			return end1 - addr_start;
+	} else if (addr_start >= PHYS_SDRAM_2 && addr_start <= end2) {
+		if ((addr_end + 1) > end2)
+			return end2 - addr_start;
+	}
+
+	return (addr_end - addr_start + 1);
+}
+
+#define MAX_PTE_ENTRIES 512
+#define MAX_MEM_MAP_REGIONS 16
+
+static struct mm_region imx8_mem_map[MAX_MEM_MAP_REGIONS];
+struct mm_region *mem_map = imx8_mem_map;
+
+void enable_caches(void)
+{
+	sc_rm_mr_t mr;
+	sc_faddr_t start, end;
+	int err, i;
+
+	/* Create map for registers access from 0x1c000000 to 0x80000000*/
+	imx8_mem_map[0].virt = 0x1c000000UL;
+	imx8_mem_map[0].phys = 0x1c000000UL;
+	imx8_mem_map[0].size = 0x64000000UL;
+	imx8_mem_map[0].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN;
+
+	i = 1;
+	for (mr = 0; mr < 64 && i < MAX_MEM_MAP_REGIONS; mr++) {
+		err = get_owned_memreg(mr, &start, &end);
+		if (!err) {
+			imx8_mem_map[i].virt = start;
+			imx8_mem_map[i].phys = start;
+			imx8_mem_map[i].size = get_block_size(start, end);
+			imx8_mem_map[i].attrs = get_block_attrs(start);
+			i++;
+		}
+	}
+
+	if (i < MAX_MEM_MAP_REGIONS) {
+		imx8_mem_map[i].size = 0;
+		imx8_mem_map[i].attrs = 0;
+	} else {
+		puts("Error, need more MEM MAP REGIONS reserved\n");
+		icache_enable();
+		return;
+	}
+
+	for (i = 0; i < MAX_MEM_MAP_REGIONS; i++) {
+		debug("[%d] vir = 0x%llx phys = 0x%llx size = 0x%llx attrs = 0x%llx\n",
+		      i, imx8_mem_map[i].virt, imx8_mem_map[i].phys,
+		      imx8_mem_map[i].size, imx8_mem_map[i].attrs);
+	}
+
+	icache_enable();
+	dcache_enable();
+}
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+u64 get_page_table_size(void)
+{
+	u64 one_pt = MAX_PTE_ENTRIES * sizeof(u64);
+	u64 size = 0;
+
+	/*
+	 * For each memory region, the max table size:
+	 * 2 level 3 tables + 2 level 2 tables + 1 level 1 table
+	 */
+	size = (2 + 2 + 1) * one_pt * MAX_MEM_MAP_REGIONS + one_pt;
+
+	/*
+	 * We need to duplicate our page table once to have an emergency pt to
+	 * resort to when splitting page tables later on
+	 */
+	size *= 2;
+
+	/*
+	 * We may need to split page tables later on if dcache settings change,
+	 * so reserve up to 4 (random pick) page tables for that.
+	 */
+	size += one_pt * 4;
+
+	return size;
+}
+#endif
+
+#define FUSE_MAC0_WORD0 708
+#define FUSE_MAC0_WORD1 709
+#define FUSE_MAC1_WORD0 710
+#define FUSE_MAC1_WORD1 711
+
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+{
+	u32 word[2], val[2] = {};
+	int i, ret;
+
+	if (dev_id == 0) {
+		word[0] = FUSE_MAC0_WORD0;
+		word[1] = FUSE_MAC0_WORD1;
+	} else {
+		word[0] = FUSE_MAC1_WORD0;
+		word[1] = FUSE_MAC1_WORD1;
+	}
+
+	for (i = 0; i < 2; i++) {
+		ret = sc_misc_otp_fuse_read(-1, word[i], &val[i]);
+		if (ret < 0)
+			goto err;
+	}
+
+	mac[0] = val[0];
+	mac[1] = val[0] >> 8;
+	mac[2] = val[0] >> 16;
+	mac[3] = val[0] >> 24;
+	mac[4] = val[1];
+	mac[5] = val[1] >> 8;
+
+	debug("%s: MAC%d: %02x.%02x.%02x.%02x.%02x.%02x\n",
+	      __func__, dev_id, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+	return;
+err:
+	printf("%s: fuse %d, err: %d\n", __func__, word[i], ret);
+}
+
+#if CONFIG_IS_ENABLED(CPU)
+struct cpu_imx_platdata {
+	const char *name;
+	const char *rev;
+	const char *type;
+	u32 cpurev;
+	u32 freq_mhz;
+};
+
+u32 get_cpu_rev(void)
+{
+	u32 id = 0, rev = 0;
+	int ret;
+
+	ret = sc_misc_get_control(-1, SC_R_SYSTEM, SC_C_ID, &id);
+	if (ret)
+		return 0;
+
+	rev = (id >> 5)  & 0xf;
+	id = (id & 0x1f) + MXC_SOC_IMX8;  /* Dummy ID for chip */
+
+	return (id << 12) | rev;
+}
+
+const char *get_imx8_type(u32 imxtype)
+{
+	switch (imxtype) {
+	case MXC_CPU_IMX8QXP:
+	case MXC_CPU_IMX8QXP_A0:
+		return "QXP";
+	default:
+		return "??";
+	}
+}
+
+const char *get_imx8_rev(u32 rev)
+{
+	switch (rev) {
+	case CHIP_REV_A:
+		return "A";
+	case CHIP_REV_B:
+		return "B";
+	default:
+		return "?";
+	}
+}
+
+const char *get_core_name(void)
+{
+	if (is_cortex_a35())
+		return "A35";
+	else if (is_cortex_a53())
+		return "A53";
+	else if (is_cortex_a72())
+		return "A72";
+	else
+		return "?";
+}
+
+int cpu_imx_get_desc(struct udevice *dev, char *buf, int size)
+{
+	struct cpu_imx_platdata *plat = dev_get_platdata(dev);
+
+	if (size < 100)
+		return -ENOSPC;
+
+	snprintf(buf, size, "CPU:   Freescale i.MX8%s Rev%s %s at %u MHz\n",
+		 plat->type, plat->rev, plat->name, plat->freq_mhz);
+
+	return 0;
+}
+
+static int cpu_imx_get_info(struct udevice *dev, struct cpu_info *info)
+{
+	struct cpu_imx_platdata *plat = dev_get_platdata(dev);
+
+	info->cpu_freq = plat->freq_mhz * 1000;
+	info->features = BIT(CPU_FEAT_L1_CACHE) | BIT(CPU_FEAT_MMU);
+	return 0;
+}
+
+static int cpu_imx_get_count(struct udevice *dev)
+{
+	return 4;
+}
+
+static int cpu_imx_get_vendor(struct udevice *dev,  char *buf, int size)
+{
+	snprintf(buf, size, "NXP");
+	return 0;
+}
+
+static const struct cpu_ops cpu_imx8_ops = {
+	.get_desc	= cpu_imx_get_desc,
+	.get_info	= cpu_imx_get_info,
+	.get_count	= cpu_imx_get_count,
+	.get_vendor	= cpu_imx_get_vendor,
+};
+
+static const struct udevice_id cpu_imx8_ids[] = {
+	{ .compatible = "arm,cortex-a35" },
+	{ }
+};
+
+static int imx8_cpu_probe(struct udevice *dev)
+{
+	struct cpu_imx_platdata *plat = dev_get_platdata(dev);
+	struct clk cpu_clk;
+	u32 cpurev;
+	int ret;
+
+	cpurev = get_cpu_rev();
+	plat->cpurev = cpurev;
+	plat->name = get_core_name();
+	plat->rev = get_imx8_rev(cpurev & 0xFFF);
+	plat->type = get_imx8_type((cpurev & 0xFF000) >> 12);
+
+	ret = clk_get_by_index(dev, 0, &cpu_clk);
+	if (ret) {
+		debug("%s: Failed to get CPU clk: %d\n", __func__, ret);
+		return 0;
+	}
+
+	plat->freq_mhz = clk_get_rate(&cpu_clk) / 1000000;
+	return 0;
+}
+
+U_BOOT_DRIVER(cpu_imx8_drv) = {
+	.name		= "imx8x_cpu",
+	.id		= UCLASS_CPU,
+	.of_match	= cpu_imx8_ids,
+	.ops		= &cpu_imx8_ops,
+	.probe		= imx8_cpu_probe,
+	.platdata_auto_alloc_size = sizeof(struct cpu_imx_platdata),
+	.flags		= DM_FLAG_PRE_RELOC,
+};
+#endif

+ 43 - 0
arch/arm/mach-imx/imx8/iomux.c

@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/iomux.h>
+#include <asm/arch/sci/sci.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * configures a single pad in the iomuxer
+ */
+void imx8_iomux_setup_pad(iomux_cfg_t pad)
+{
+	sc_pad_t pin_id = pad & PIN_ID_MASK;
+	int ret;
+
+	u32 val = (u32)((pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT);
+
+	val |= PADRING_IFMUX_EN_MASK;
+	val |= PADRING_GP_EN_MASK;
+
+	ret = sc_pad_set(-1, pin_id, val);
+	if (ret)
+		printf("sc_pad_set failed!, pin: %u, val: 0x%x\n", pin_id, val);
+
+	debug("iomux: pin %d, val = 0x%x\n", pin_id, val);
+}
+
+/* configures a list of pads within declared with IOMUX_PADS macro */
+void imx8_iomux_setup_multiple_pads(iomux_cfg_t const *pad_list, u32 count)
+{
+	iomux_cfg_t const *p = pad_list;
+	int i;
+
+	for (i = 0; i < count; i++) {
+		imx8_iomux_setup_pad(*p);
+		p++;
+	}
+}

+ 6 - 0
arch/arm/mach-imx/mx5/Kconfig

@@ -30,6 +30,11 @@ config TARGET_KP_IMX53
 	select MX53
 	imply CMD_DM
 
+config TARGET_M53MENLO
+	bool "Support m53menlo"
+	select MX53
+	select SUPPORT_SPL
+
 config TARGET_MX51EVK
 	bool "Support mx51evk"
 	select BOARD_LATE_INIT
@@ -89,6 +94,7 @@ source "board/freescale/mx53smd/Kconfig"
 source "board/ge/mx53ppd/Kconfig"
 source "board/inversepath/usbarmory/Kconfig"
 source "board/k+p/kp_imx53/Kconfig"
+source "board/menlo/m53menlo/Kconfig"
 source "board/technologic/ts4800/Kconfig"
 
 endif

+ 29 - 0
arch/arm/mach-imx/mx5/clock.c

@@ -838,6 +838,31 @@ static int config_ddr_clk(u32 emi_clk)
 	return 0;
 }
 
+#ifdef CONFIG_MX53
+static int config_ldb_clk(u32 ref, u32 freq)
+{
+	int ret = 0;
+	struct pll_param pll_param;
+
+	memset(&pll_param, 0, sizeof(struct pll_param));
+
+	ret = calc_pll_params(ref, freq, &pll_param);
+	if (ret != 0) {
+		printf("Error:Can't find pll parameters: %d\n",
+			ret);
+		return ret;
+	}
+
+	return config_pll_clk(PLL4_CLOCK, &pll_param);
+}
+#else
+static int config_ldb_clk(u32 ref, u32 freq)
+{
+	/* Platform not supported */
+	return -EINVAL;
+}
+#endif
+
 /*
  * This function assumes the expected core clock has to be changed by
  * modifying the PLL. This is NOT true always but for most of the times,
@@ -879,6 +904,10 @@ int mxc_set_clock(u32 ref, u32 freq, enum mxc_clock clk)
 		if (config_nfc_clk(freq))
 			return -EINVAL;
 		break;
+	case MXC_LDB_CLK:
+		if (config_ldb_clk(ref, freq))
+			return -EINVAL;
+		break;
 	default:
 		printf("Warning:Unsupported or invalid clock type\n");
 	}

+ 4 - 0
arch/arm/mach-imx/mx7/ddr.c

@@ -196,5 +196,9 @@ unsigned int imx_ddr_size(void)
 	if (field_val <= 29)
 		bits++;
 
+	/* cap to max 2 GB */
+	if (bits > 31)
+		bits = 31;
+
 	return 1 << bits;
 }

+ 2 - 0
arch/arm/mach-imx/mx7/soc.c

@@ -164,6 +164,7 @@ u32 __weak get_board_rev(void)
 }
 #endif
 
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
 /* enable all periherial can be accessed in nosec mode */
 static void init_csu(void)
 {
@@ -285,6 +286,7 @@ int arch_cpu_init(void)
 
 	return 0;
 }
+#endif
 
 #ifdef CONFIG_ARCH_MISC_INIT
 int arch_misc_init(void)

+ 2 - 0
arch/arm/mach-imx/syscounter.c

@@ -55,6 +55,7 @@ static inline unsigned long long us_to_tick(unsigned long long usec)
 	return usec;
 }
 
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
 int timer_init(void)
 {
 	struct sctr_regs *sctr = (struct sctr_regs *)SCTR_BASE_ADDR;
@@ -76,6 +77,7 @@ int timer_init(void)
 
 	return 0;
 }
+#endif
 
 unsigned long long get_ticks(void)
 {

+ 14 - 0
board/freescale/imx8qxp_mek/Kconfig

@@ -0,0 +1,14 @@
+if TARGET_IMX8QXP_MEK
+
+config SYS_BOARD
+	default "imx8qxp_mek"
+
+config SYS_VENDOR
+	default "freescale"
+
+config SYS_CONFIG_NAME
+	default "imx8qxp_mek"
+
+source "board/freescale/common/Kconfig"
+
+endif

+ 6 - 0
board/freescale/imx8qxp_mek/MAINTAINERS

@@ -0,0 +1,6 @@
+i.MX8QXP MEK BOARD
+M:	Peng Fan <peng.fan@nxp.com>
+S:	Maintained
+F:	board/freescale/imx8qxp_mek/
+F:	include/configs/imx8qxp_mek.h
+F:	configs/imx8qxp_mek_defconfig

+ 7 - 0
board/freescale/imx8qxp_mek/Makefile

@@ -0,0 +1,7 @@
+#
+# Copyright 2017 NXP
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y += imx8qxp_mek.o

+ 55 - 0
board/freescale/imx8qxp_mek/README

@@ -0,0 +1,55 @@
+U-Boot for the NXP i.MX8QXP EVK board
+
+Quick Start
+===========
+
+- Build the ARM Trusted firmware binary
+- Get scfw_tcm.bin and ahab-container.img
+- Build U-Boot
+- Flash the binary into the SD card
+- Boot
+
+Get and Build the ARM Trusted firmware
+======================================
+
+$ git clone https://source.codeaurora.org/external/imx/imx-atf
+$ cd imx-atf/
+$ git checkout origin/imx_4.9.88_imx8qxp_beta2 -b imx_4.9.88_imx8qxp_beta2
+$ make PLAT=imx8qxp bl31
+
+Get scfw_tcm.bin and ahab-container.img
+==============================
+
+$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/imx-sc-firmware-0.7.bin
+$ chmod +x imx-sc-firmware-0.7.bin
+$ ./imx-sc-firmware-0.7.bin
+$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-7.6.bin
+$ chmod +x firmware-imx-7.6.bin
+$ ./firmware-imx-7.6.bin
+
+Copy the following binaries to U-Boot folder:
+
+$ cp imx-atf/build/imx8qxp/release/bl31.bin .
+$ cp u-boot/u-boot.bin .
+
+Copy the following firmwares U-Boot folder :
+
+$ cp firmware-imx-7.6/firmware/seco/ahab-container.img .
+$ cp imx-sc-firmware-0.7/mx8qx-mek-scfw-tcm.bin	.
+
+Build U-Boot
+============
+
+$ make imx8qxp_mek_defconfig
+$ make
+
+Flash the binary into the SD card
+=================================
+
+Burn the flash.bin binary to SD card offset 32KB:
+
+$ sudo dd if=u-boot-dtb.imx of=/dev/sd[x] bs=1024 seek=32
+
+Boot
+====
+Set Boot switch SW2: 1100.

+ 170 - 0
board/freescale/imx8qxp_mek/imx8qxp_mek.c

@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <linux/libfdt.h>
+#include <environment.h>
+#include <fsl_esdhc.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sci/sci.h>
+#include <asm/arch/imx8-pins.h>
+#include <asm/arch/iomux.h>
+#include <asm/arch/sys_proto.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#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 UART_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))
+
+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)
+{
+	int ret;
+	/* Set UART0 clock root to 80 MHz */
+	sc_pm_clock_rate_t rate = 80000000;
+
+	/* Power up UART0 */
+	ret = sc_pm_set_resource_power_mode(-1, SC_R_UART_0, SC_PM_PW_MODE_ON);
+	if (ret)
+		return ret;
+
+	ret = sc_pm_set_clock_rate(-1, SC_R_UART_0, 2, &rate);
+	if (ret)
+		return ret;
+
+	/* Enable UART0 clock root */
+	ret = sc_pm_clock_enable(-1, SC_R_UART_0, 2, true, false);
+	if (ret)
+		return ret;
+
+	setup_iomux_uart();
+
+	return 0;
+}
+
+#if IS_ENABLED(CONFIG_DM_GPIO)
+static void board_gpio_init(void)
+{
+	struct gpio_desc desc;
+	int ret;
+
+	ret = dm_gpio_lookup_name("gpio@1a_3", &desc);
+	if (ret)
+		return;
+
+	ret = dm_gpio_request(&desc, "bb_per_rst_b");
+	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);
+}
+#else
+static inline void board_gpio_init(void) {}
+#endif
+
+#if IS_ENABLED(CONFIG_FEC_MXC)
+#include <miiphy.h>
+
+int board_phy_config(struct phy_device *phydev)
+{
+	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;
+}
+#endif
+
+void build_info(void)
+{
+	u32 sc_build = 0, sc_commit = 0;
+
+	/* Get SCFW build and commit id */
+	sc_misc_build_info(-1, &sc_build, &sc_commit);
+	if (!sc_build) {
+		printf("SCFW does not support build info\n");
+		sc_commit = 0; /* Display 0 when the build info is not supported*/
+	}
+	printf("Build: SCFW %x\n", sc_commit);
+}
+
+int checkboard(void)
+{
+	puts("Board: iMX8QXP MEK\n");
+
+	build_info();
+	print_bootinfo();
+
+	return 0;
+}
+
+int board_init(void)
+{
+	board_gpio_init();
+
+	return 0;
+}
+
+void detail_board_ddr_info(void)
+{
+	puts("\nDDR    ");
+}
+
+/*
+ * Board specific reset that is system reset.
+ */
+void reset_cpu(ulong addr)
+{
+	/* TODO */
+}
+
+#ifdef CONFIG_OF_BOARD_SETUP
+int ft_board_setup(void *blob, bd_t *bd)
+{
+	return 0;
+}
+#endif
+
+int board_mmc_get_env_dev(int devno)
+{
+	return devno;
+}
+
+int board_late_init(void)
+{
+#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+	env_set("board_name", "MEK");
+	env_set("board_rev", "iMX8QXP");
+#endif
+
+	return 0;
+}

+ 25 - 0
board/freescale/imx8qxp_mek/imximage.cfg

@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ *
+ * Refer doc/README.imx8image for more details about how-to configure
+ * and create imx8image boot image
+ */
+
+#define __ASSEMBLY__
+#include <config.h>
+
+/* Boot from SD, sector size 0x400 */
+BOOT_FROM SD 0x400
+/* SoC type IMX8QX */
+SOC_TYPE IMX8QX
+/* Append seco container image */
+APPEND ahab-container.img
+/* Create the 2nd container */
+CONTAINER
+/* Add scfw image with exec attribute */
+IMAGE SCU mx8qx-mek-scfw-tcm.bin
+/* Add ATF image with exec attribute */
+IMAGE A35 bl31.bin 0x80000000
+/* Add U-Boot image with load attribute */
+DATA A35 u-boot-dtb.bin 0x80020000

+ 81 - 0
board/freescale/mx8mq_evk/README

@@ -0,0 +1,81 @@
+U-Boot for the NXP i.MX8MQ EVK board
+
+Quick Start
+===========
+
+- Build U-Boot
+- Build the ARM Trusted firmware binary
+- Get DDR firmware and mkimage tool
+- Generate flash.bin using imx-mkimage
+- Flash the binary into the SD card
+- Boot
+
+Build U-Boot
+============
+
+$ make mx8mq_evk_defconfig
+$ make
+
+Get and Build the ARM Trusted firmware
+======================================
+
+$ git clone https://source.codeaurora.org/external/imx/imx-atf
+$ cd imx-atf/
+$ git checkout origin/imx_4.9.51_imx8m_beta
+$ make PLAT=imx8mq bl31
+
+Get the DDR firmware and mkimage tool
+==============================
+
+$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-7.2.bin
+$ chmod +x firmware-imx-7.2.bin
+$ ./firmware-imx-7.2.bin
+
+Download the imx-mkimage tool:
+
+$ git clone https://source.codeaurora.org/external/imx/imx-mkimage/
+$ cd imx-mkimage/
+$ git checkout origin/imx_4.9.51_imx8m_beta
+
+
+Generate flash.bin using imx-mkimage
+====================================
+
+Copy the following binaries to imx-mkimage/iMX8M folder:
+
+$ cp imx-atf/build/imx8mq/release/bl31.bin imx-mkimage/iMX8M/
+$ cp u-boot/u-boot-nodtb.bin imx-mkimage/iMX8M/
+$ cp u-boot/spl/u-boot-spl.bin imx-mkimage/iMX8M/
+$ cp u-boot/arch/arm/dts/fsl-imx8mq-evk.dtb imx-mkimage/iMX8M/
+
+Copy the following firmwares to imx-mkimage/iMX8 folder :
+
+$ cp firmware-imx-7.2/firmware/ddr/synopsys/lpddr4_pmu_train_1d_dmem.bin imx-mkimage/iMX8M/
+$ cp firmware-imx-7.2/firmware/ddr/synopsys/lpddr4_pmu_train_1d_imem.bin imx-mkimage/iMX8M/
+$ cp firmware-imx-7.2/firmware/ddr/synopsys/lpddr4_pmu_train_2d_dmem.bin imx-mkimage/iMX8M/
+$ cp firmware-imx-7.2/firmware/ddr/synopsys/lpddr4_pmu_train_2d_imem.bin imx-mkimage/iMX8M/
+
+If you want to run with HDMI, copy signed_hdmi_imx8m.bin to imx-mkimage/iMX8M.
+
+Before generating the flash.bin, transfer the mkimage generated by U-Boot to iMX8M folder:
+
+$ cp u-boot/tools/mkimage imx-mkimage/iMX8M/
+$ mv imx-mkimage/iMX8M/mkimage imx-mkimage/iMX8M/mkimage_uboot
+
+$ cd imx-mkimage/
+$ make SOC=iMX8M flash_spl_uboot
+
+Or for using HDMI:
+
+$ make SOC=iMX8M flash_hdmi_spl_uboot
+
+Flash the binary into the SD card
+=================================
+
+Burn the flash.bin binary to SD card offset 33KB:
+
+$ sudo dd if=iMX8M/flash.bin of=/dev/sd[x] bs=1024 seek=33
+
+Boot
+====
+Set Boot switch SW801: 1100 and Bmode: 10 to boot from Micro SD.

+ 1 - 1
board/ge/bx50v3/MAINTAINERS

@@ -1,5 +1,5 @@
 GE_BX50V3 BOARD
-M:	Martin Donnelly <martin.donnelly@ge.com>
+M:	Ian Ray <ian.ray@ge.com>
 S:	Maintained
 F:	board/ge/bx50v3/
 F:	include/configs/ge_bx50v3.h

+ 22 - 16
board/ge/bx50v3/bx50v3.c

@@ -426,14 +426,22 @@ static void enable_videopll(void)
 
 	setbits_le32(&ccm->analog_pll_video, BM_ANADIG_PLL_VIDEO_POWERDOWN);
 
-	/* set video pll to 910MHz (24MHz * (37+11/12))
-	* video pll post div to 910/4 = 227.5MHz
-	*/
+	/* PLL_VIDEO  455MHz (24MHz * (37+11/12) / 2)
+	 *   |
+	 * PLL5
+	 *   |
+	 * CS2CDR[LDB_DI0_CLK_SEL]
+	 *   |
+	 *   +----> LDB_DI0_SERIAL_CLK_ROOT
+	 *   |
+	 *   +--> CSCMR2[LDB_DI0_IPU_DIV] --> LDB_DI0_IPU  455 / 7 = 65 MHz
+	 */
+
 	clrsetbits_le32(&ccm->analog_pll_video,
 			BM_ANADIG_PLL_VIDEO_DIV_SELECT |
 			BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT,
 			BF_ANADIG_PLL_VIDEO_DIV_SELECT(37) |
-			BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(0));
+			BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(1));
 
 	writel(BF_ANADIG_PLL_VIDEO_NUM_A(11), &ccm->analog_pll_video_num);
 	writel(BF_ANADIG_PLL_VIDEO_DENOM_B(12), &ccm->analog_pll_video_denom);
@@ -459,8 +467,8 @@ static void setup_display_b850v3(void)
 
 	enable_videopll();
 
-	/* IPU1 D0 clock is 227.5 / 3.5 = 65MHz */
-	clrbits_le32(&mxc_ccm->cscmr2, MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV);
+	/* IPU1 DI0 clock is 455MHz / 7 = 65MHz */
+	setbits_le32(&mxc_ccm->cscmr2, MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV);
 
 	imx_setup_hdmi();
 
@@ -507,7 +515,7 @@ static void setup_display_bx50v3(void)
 	 */
 	mdelay(200);
 
-	/* IPU1 DI0 clock is 480/7 = 68.5 MHz */
+	/* IPU1 DI0 clock is 455MHz / 7 = 65MHz */
 	setbits_le32(&mxc_ccm->cscmr2, MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV);
 
 	/* Set LDB_DI0 as clock source for IPU_DI0 */
@@ -683,12 +691,8 @@ int board_early_init_f(void)
 	setup_iomux_uart();
 
 #if defined(CONFIG_VIDEO_IPUV3)
-	if (is_b850v3())
-		/* Set LDB clock to Video PLL */
-		select_ldb_di_clock_source(MXC_PLL5_CLK);
-	else
-		/* Set LDB clock to USB PLL */
-		select_ldb_di_clock_source(MXC_PLL3_SW_CLK);
+	/* Set LDB clock to Video PLL */
+	select_ldb_di_clock_source(MXC_PLL5_CLK);
 #endif
 	return 0;
 }
@@ -710,9 +714,9 @@ static void set_confidx(const struct vpd_cache* vpd)
 
 int board_init(void)
 {
-	setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
-	setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
-	setup_i2c(3, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info3);
+	setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
+	setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
+	setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info3);
 
 	read_vpd(CONFIG_SYS_I2C_EEPROM_BUS);
 
@@ -805,6 +809,8 @@ int board_late_init(void)
 
 	if (is_b850v3())
 		env_set("videoargs", "video=DP-1:1024x768@60 video=HDMI-A-1:1024x768@60");
+	else
+		env_set("videoargs", "video=LVDS-1:1024x768@65");
 
 	/* board specific pmic init */
 	pmic_init();

+ 15 - 0
board/menlo/m53menlo/Kconfig

@@ -0,0 +1,15 @@
+if TARGET_M53MENLO
+
+config SYS_BOARD
+	default "m53menlo"
+
+config SYS_VENDOR
+	default "menlo"
+
+config SYS_SOC
+	default "mx5"
+
+config SYS_CONFIG_NAME
+	default "m53menlo"
+
+endif

+ 7 - 0
board/menlo/m53menlo/MAINTAINERS

@@ -0,0 +1,7 @@
+M53MENLO BOARD
+M:	Marek Vasut <marex@denx.de>
+M:	Olaf Mandel <o.mandel@menlosystems.com>
+S:	Maintained
+F:	board/menlo/m53menlo/
+F:	include/configs/m53menlo.h
+F:	configs/m53menlo_defconfig

+ 9 - 0
board/menlo/m53menlo/Makefile

@@ -0,0 +1,9 @@
+#
+# Menlosystems M53Menlo
+# Copyright (C) 2012-2017 Marek Vasut <marex@denx.de>
+# Copyright (C) 2014-2017 Olaf Mandel <o.mandel@menlosystems.com>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y	:= m53menlo.o

+ 91 - 0
board/menlo/m53menlo/imximage.cfg

@@ -0,0 +1,91 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * M53 DRAM init values
+ * Copyright (C) 2012-2013 Marek Vasut <marex@denx.de>
+ *
+ * Refer doc/README.imximage for more details about how-to configure
+ * and create imximage boot image
+ *
+ * The syntax is taken as close as possible with the kwbimage
+ */
+#include <asm/mach-imx/imximage.cfg>
+
+/* image version */
+IMAGE_VERSION	2
+
+
+/* Boot Offset 0x400, valid for both SD and NAND boot. */
+BOOT_OFFSET	FLASH_OFFSET_STANDARD
+
+/*
+ * Device Configuration Data (DCD)
+ *
+ * Each entry must have the format:
+ * Addr-type           Address        Value
+ *
+ * where:
+ *	Addr-type register length (1,2 or 4 bytes)
+ *	Address	  absolute address of the register
+ *	value	  value to be stored in the register
+ */
+DATA 4 0x53fa86f4 0x00000000	 /* GRP_DDRMODE_CTL */
+DATA 4 0x53fa8714 0x00000000	 /* GRP_DDRMODE */
+DATA 4 0x53fa86fc 0x00000000	 /* GRP_DDRPKE */
+DATA 4 0x53fa8724 0x04000000	 /* GRP_DDR_TYPE */
+
+DATA 4 0x53fa872c 0x00300000	 /* GRP_B3DS */
+DATA 4 0x53fa8554 0x00300000	 /* DRAM_DQM3 */
+DATA 4 0x53fa8558 0x00300040	 /* DRAM_SDQS3 */
+
+DATA 4 0x53fa8728 0x00300000	 /* GRP_B2DS */
+DATA 4 0x53fa8560 0x00300000	 /* DRAM_DQM2 */
+DATA 4 0x53fa8568 0x00300040	 /* DRAM_SDQS2 */
+
+DATA 4 0x53fa871c 0x00300000	 /* GRP_B1DS */
+DATA 4 0x53fa8594 0x00300000	 /* DRAM_DQM1 */
+DATA 4 0x53fa8590 0x00300040	 /* DRAM_SDQS1 */
+
+DATA 4 0x53fa8718 0x00300000	 /* GRP_B0DS */
+DATA 4 0x53fa8584 0x00300000	 /* DRAM_DQM0 */
+DATA 4 0x53fa857c 0x00300040	 /* DRAM_SDQS0 */
+
+DATA 4 0x53fa8578 0x00300000	 /* DRAM_SDCLK_0 */
+DATA 4 0x53fa8570 0x00300000	 /* DRAM_SDCLK_1 */
+
+DATA 4 0x53fa8574 0x00300000	 /* DRAM_CAS */
+DATA 4 0x53fa8588 0x00300000	 /* DRAM_RAS */
+DATA 4 0x53fa86f0 0x00300000	 /* GRP_ADDDS */
+DATA 4 0x53fa8720 0x00300000	 /* GRP_CTLDS */
+
+DATA 4 0x53fa8564 0x00300040	 /* DRAM_SDODT1 */
+DATA 4 0x53fa8580 0x00300040	 /* DRAM_SDODT0 */
+
+/* ESDCTL */
+DATA 4 0x63fd9088 0x32383535
+DATA 4 0x63fd9090 0x40383538
+DATA 4 0x63fd907c 0x0136014d
+DATA 4 0x63fd9080 0x01510141
+
+DATA 4 0x63fd9018 0x00011740
+DATA 4 0x63fd9000 0xc3190000
+DATA 4 0x63fd900c 0x555952e3
+DATA 4 0x63fd9010 0xb68e8b63
+DATA 4 0x63fd9014 0x01ff00db
+DATA 4 0x63fd902c 0x000026d2
+DATA 4 0x63fd9030 0x009f0e21
+DATA 4 0x63fd9008 0x12273030
+DATA 4 0x63fd9004 0x0002002d
+DATA 4 0x63fd901c 0x00008032
+DATA 4 0x63fd901c 0x00008033
+DATA 4 0x63fd901c 0x00028031
+DATA 4 0x63fd901c 0x092080b0
+DATA 4 0x63fd901c 0x04008040
+DATA 4 0x63fd901c 0x0000803a
+DATA 4 0x63fd901c 0x0000803b
+DATA 4 0x63fd901c 0x00028039
+DATA 4 0x63fd901c 0x09208138
+DATA 4 0x63fd901c 0x04008048
+DATA 4 0x63fd9020 0x00001800
+DATA 4 0x63fd9040 0x04b80003
+DATA 4 0x63fd9058 0x00022227
+DATA 4 0x63fd901c 0x00000000

+ 513 - 0
board/menlo/m53menlo/m53menlo.c

@@ -0,0 +1,513 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Menlosystems M53Menlo board
+ *
+ * Copyright (C) 2012-2017 Marek Vasut <marex@denx.de>
+ * Copyright (C) 2014-2017 Olaf Mandel <o.mandel@menlosystems.com>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/iomux-mx53.h>
+#include <asm/mach-imx/mx5_video.h>
+#include <asm/mach-imx/video.h>
+#include <asm/gpio.h>
+#include <asm/spl.h>
+#include <fdt_support.h>
+#include <fsl_esdhc.h>
+#include <i2c.h>
+#include <ipu_pixfmt.h>
+#include <linux/errno.h>
+#include <linux/fb.h>
+#include <mmc.h>
+#include <netdev.h>
+#include <spl.h>
+#include <splash.h>
+#include <usb/ehci-ci.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static u32 mx53_dram_size[2];
+
+ulong board_get_usable_ram_top(ulong total_size)
+{
+	/*
+	 * WARNING: We must override get_effective_memsize() function here
+	 * to report only the size of the first DRAM bank. This is to make
+	 * U-Boot relocator place U-Boot into valid memory, that is, at the
+	 * end of the first DRAM bank. If we did not override this function
+	 * like so, U-Boot would be placed at the address of the first DRAM
+	 * bank + total DRAM size - sizeof(uboot), which in the setup where
+	 * each DRAM bank contains 512MiB of DRAM would result in placing
+	 * U-Boot into invalid memory area close to the end of the first
+	 * DRAM bank.
+	 */
+	return PHYS_SDRAM_2 + mx53_dram_size[1];
+}
+
+int dram_init(void)
+{
+	mx53_dram_size[0] = get_ram_size((void *)PHYS_SDRAM_1, 1 << 30);
+	mx53_dram_size[1] = get_ram_size((void *)PHYS_SDRAM_2, 1 << 30);
+
+	gd->ram_size = mx53_dram_size[0] + mx53_dram_size[1];
+
+	return 0;
+}
+
+int dram_init_banksize(void)
+{
+	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+	gd->bd->bi_dram[0].size = mx53_dram_size[0];
+
+	gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+	gd->bd->bi_dram[1].size = mx53_dram_size[1];
+
+	return 0;
+}
+
+static void setup_iomux_uart(void)
+{
+	static const iomux_v3_cfg_t uart_pads[] = {
+		MX53_PAD_PATA_DMACK__UART1_RXD_MUX,
+		MX53_PAD_PATA_DIOW__UART1_TXD_MUX,
+	};
+
+	imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads));
+}
+
+#ifdef CONFIG_USB_EHCI_MX5
+int board_ehci_hcd_init(int port)
+{
+	if (port == 0) {
+		/* USB OTG PWRON */
+		imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX53_PAD_GPIO_4__GPIO1_4,
+						    PAD_CTL_PKE |
+						    PAD_CTL_DSE_HIGH));
+		gpio_direction_output(IMX_GPIO_NR(1, 4), 0);
+
+		/* USB OTG Over Current */
+		imx_iomux_v3_setup_pad(MX53_PAD_GPIO_18__GPIO7_13);
+	} else if (port == 1) {
+		/* USB Host PWRON */
+		imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX53_PAD_GPIO_2__GPIO1_2,
+						    PAD_CTL_PKE |
+						    PAD_CTL_DSE_HIGH));
+		gpio_direction_output(IMX_GPIO_NR(1, 2), 0);
+
+		/* USB Host Over Current */
+		imx_iomux_v3_setup_pad(MX53_PAD_GPIO_3__USBOH3_USBH1_OC);
+	}
+
+	return 0;
+}
+#endif
+
+static void setup_iomux_fec(void)
+{
+	static const iomux_v3_cfg_t fec_pads[] = {
+		/* MDIO pads */
+		NEW_PAD_CTRL(MX53_PAD_FEC_MDIO__FEC_MDIO, PAD_CTL_HYS |
+			PAD_CTL_DSE_HIGH | PAD_CTL_PUS_22K_UP | PAD_CTL_ODE),
+		NEW_PAD_CTRL(MX53_PAD_FEC_MDC__FEC_MDC, PAD_CTL_DSE_HIGH),
+
+		/* FEC 0 pads */
+		NEW_PAD_CTRL(MX53_PAD_FEC_CRS_DV__FEC_RX_DV,
+			     PAD_CTL_HYS | PAD_CTL_PKE),
+		NEW_PAD_CTRL(MX53_PAD_FEC_REF_CLK__FEC_TX_CLK,
+			     PAD_CTL_HYS | PAD_CTL_PKE),
+		NEW_PAD_CTRL(MX53_PAD_FEC_RX_ER__FEC_RX_ER,
+			     PAD_CTL_HYS | PAD_CTL_PKE),
+		NEW_PAD_CTRL(MX53_PAD_FEC_TX_EN__FEC_TX_EN, PAD_CTL_DSE_HIGH),
+		NEW_PAD_CTRL(MX53_PAD_FEC_RXD0__FEC_RDATA_0,
+			     PAD_CTL_HYS | PAD_CTL_PKE),
+		NEW_PAD_CTRL(MX53_PAD_FEC_RXD1__FEC_RDATA_1,
+			     PAD_CTL_HYS | PAD_CTL_PKE),
+		NEW_PAD_CTRL(MX53_PAD_FEC_TXD0__FEC_TDATA_0, PAD_CTL_DSE_HIGH),
+		NEW_PAD_CTRL(MX53_PAD_FEC_TXD1__FEC_TDATA_1, PAD_CTL_DSE_HIGH),
+
+		/* FEC 1 pads */
+		NEW_PAD_CTRL(MX53_PAD_KEY_COL0__FEC_RDATA_3,
+			     PAD_CTL_HYS | PAD_CTL_PKE),
+		NEW_PAD_CTRL(MX53_PAD_KEY_ROW0__FEC_TX_ER,
+			     PAD_CTL_HYS | PAD_CTL_PKE),
+		NEW_PAD_CTRL(MX53_PAD_KEY_COL1__FEC_RX_CLK,
+			     PAD_CTL_HYS | PAD_CTL_PKE),
+		NEW_PAD_CTRL(MX53_PAD_KEY_ROW1__FEC_COL,
+			     PAD_CTL_HYS | PAD_CTL_PKE),
+		NEW_PAD_CTRL(MX53_PAD_KEY_COL2__FEC_RDATA_2,
+			     PAD_CTL_HYS | PAD_CTL_PKE),
+		NEW_PAD_CTRL(MX53_PAD_KEY_ROW2__FEC_TDATA_2, PAD_CTL_DSE_HIGH),
+		NEW_PAD_CTRL(MX53_PAD_KEY_COL3__FEC_CRS,
+			     PAD_CTL_HYS | PAD_CTL_PKE),
+		NEW_PAD_CTRL(MX53_PAD_GPIO_19__FEC_TDATA_3, PAD_CTL_DSE_HIGH),
+	};
+
+	imx_iomux_v3_setup_multiple_pads(fec_pads, ARRAY_SIZE(fec_pads));
+}
+
+#ifdef CONFIG_FSL_ESDHC
+struct fsl_esdhc_cfg esdhc_cfg = {
+	MMC_SDHC1_BASE_ADDR,
+};
+
+int board_mmc_getcd(struct mmc *mmc)
+{
+	imx_iomux_v3_setup_pad(MX53_PAD_GPIO_1__GPIO1_1);
+	gpio_direction_input(IMX_GPIO_NR(1, 1));
+
+	return !gpio_get_value(IMX_GPIO_NR(1, 1));
+}
+
+#define SD_CMD_PAD_CTRL		(PAD_CTL_HYS | PAD_CTL_DSE_HIGH | \
+				 PAD_CTL_PUS_100K_UP)
+#define SD_PAD_CTRL		(PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | \
+				 PAD_CTL_DSE_HIGH)
+
+int board_mmc_init(bd_t *bis)
+{
+	static const iomux_v3_cfg_t sd1_pads[] = {
+		NEW_PAD_CTRL(MX53_PAD_SD1_CMD__ESDHC1_CMD, SD_CMD_PAD_CTRL),
+		NEW_PAD_CTRL(MX53_PAD_SD1_CLK__ESDHC1_CLK, SD_PAD_CTRL),
+		NEW_PAD_CTRL(MX53_PAD_SD1_DATA0__ESDHC1_DAT0, SD_PAD_CTRL),
+		NEW_PAD_CTRL(MX53_PAD_SD1_DATA1__ESDHC1_DAT1, SD_PAD_CTRL),
+		NEW_PAD_CTRL(MX53_PAD_SD1_DATA2__ESDHC1_DAT2, SD_PAD_CTRL),
+		NEW_PAD_CTRL(MX53_PAD_SD1_DATA3__ESDHC1_DAT3, SD_PAD_CTRL),
+	};
+
+	esdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+
+	imx_iomux_v3_setup_multiple_pads(sd1_pads, ARRAY_SIZE(sd1_pads));
+
+	return fsl_esdhc_initialize(bis, &esdhc_cfg);
+}
+#endif
+
+#ifdef CONFIG_VIDEO
+static void enable_lvds_clock(struct display_info_t const *dev, const u8 hclk)
+{
+	static struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE;
+	int ret;
+
+	/* For ETM0430G0DH6 model, this must be enabled before the clock. */
+	gpio_direction_output(IMX_GPIO_NR(6, 0), 1);
+
+	/*
+	 * Set LVDS clock to 33.28 MHz for the display. The PLL4 is set to
+	 * 233 MHz, divided by 7 by setting CCM_CSCMR2 LDB_DI0_IPU_DIV=1 .
+	 */
+	ret = mxc_set_clock(MXC_HCLK, hclk, MXC_LDB_CLK);
+	if (ret)
+		puts("IPU:   Failed to configure LDB clock\n");
+
+	/* Configure CCM_CSCMR2 */
+	clrsetbits_le32(&mxc_ccm->cscmr2,
+			(0x7 << 26) | BIT(10) | BIT(8),
+			(0x5 << 26) | BIT(10) | BIT(8));
+
+	/* Configure LDB_CTRL */
+	writel(0x201, 0x53fa8008);
+}
+
+static void enable_lvds_etm0430g0dh6(struct display_info_t const *dev)
+{
+	/* For ETM0430G0DH6 model, this must be enabled before the clock. */
+	gpio_direction_output(IMX_GPIO_NR(6, 0), 1);
+
+	/*
+	 * Set LVDS clock to 9 MHz for the display. The PLL4 is set to
+	 * 63 MHz, divided by 7 by setting CCM_CSCMR2 LDB_DI0_IPU_DIV=1 .
+	 */
+	enable_lvds_clock(dev, 63);
+}
+
+static void enable_lvds_etm0700g0dh6(struct display_info_t const *dev)
+{
+	/*
+	 * Set LVDS clock to 33.28 MHz for the display. The PLL4 is set to
+	 * 233 MHz, divided by 7 by setting CCM_CSCMR2 LDB_DI0_IPU_DIV=1 .
+	 */
+	enable_lvds_clock(dev, 233);
+
+	/* For ETM0700G0DH6 model, this may be enabled after the clock. */
+	gpio_direction_output(IMX_GPIO_NR(6, 0), 1);
+}
+
+static const char *lvds_compat_string;
+
+static int detect_lvds(struct display_info_t const *dev)
+{
+	u8 touchid[23];
+	u8 *touchptr = &touchid[0];
+	int ret;
+
+	ret = i2c_set_bus_num(0);
+	if (ret)
+		return 0;
+
+	/* Touchscreen is at address 0x38, ID register is 0xbb. */
+	ret = i2c_read(0x38, 0xbb, 1, touchid, sizeof(touchid));
+	if (ret)
+		return 0;
+
+	/* EP0430 prefixes the response with 0xbb, skip it. */
+	if (*touchptr == 0xbb)
+		touchptr++;
+
+	/* Skip the 'EP' prefix. */
+	touchptr += 2;
+
+	ret = !memcmp(touchptr, &dev->mode.name[7], 4);
+	if (ret)
+		lvds_compat_string = dev->mode.name;
+
+	return ret;
+}
+
+void board_preboot_os(void)
+{
+	/* Power off the LCD to prevent awful color flicker */
+	gpio_direction_output(IMX_GPIO_NR(6, 0), 0);
+}
+
+int ft_board_setup(void *blob, bd_t *bd)
+{
+	if (lvds_compat_string)
+		do_fixup_by_path_string(blob, "/panel", "compatible",
+					lvds_compat_string);
+
+	return 0;
+}
+
+struct display_info_t const displays[] = {
+	{
+		.bus	= 0,
+		.addr	= 0,
+		.detect	= detect_lvds,
+		.enable	= enable_lvds_etm0430g0dh6,
+		.pixfmt	= IPU_PIX_FMT_RGB666,
+		.mode	= {
+			.name		= "edt,etm0430g0dh6",
+			.refresh	= 60,
+			.xres		= 480,
+			.yres		= 272,
+			.pixclock	= 111111, /* picosecond (9 MHz) */
+			.left_margin	= 2,
+			.right_margin	= 2,
+			.upper_margin	= 2,
+			.lower_margin	= 2,
+			.hsync_len	= 41,
+			.vsync_len	= 10,
+			.sync		= 0x40000000,
+			.vmode          = FB_VMODE_NONINTERLACED
+		}
+	}, {
+		.bus	= 0,
+		.addr	= 0,
+		.detect	= detect_lvds,
+		.enable	= enable_lvds_etm0700g0dh6,
+		.pixfmt	= IPU_PIX_FMT_RGB666,
+		.mode	= {
+			.name		= "edt,etm0700g0dh6",
+			.refresh	= 60,
+			.xres		= 800,
+			.yres		= 480,
+			.pixclock	= 30048, /* picosecond (33.28 MHz) */
+			.left_margin	= 40,
+			.right_margin	= 88,
+			.upper_margin	= 10,
+			.lower_margin	= 33,
+			.hsync_len	= 128,
+			.vsync_len	= 2,
+			.sync		= FB_SYNC_EXT,
+			.vmode          = FB_VMODE_NONINTERLACED
+		}
+	}
+};
+
+size_t display_count = ARRAY_SIZE(displays);
+#endif
+
+#ifdef CONFIG_SPLASH_SCREEN
+static struct splash_location default_splash_locations[] = {
+	{
+		.name		= "mmc_fs",
+		.storage	= SPLASH_STORAGE_MMC,
+		.flags		= SPLASH_STORAGE_FS,
+		.devpart	= "0:1",
+	},
+};
+
+int splash_screen_prepare(void)
+{
+	return splash_source_load(default_splash_locations,
+				  ARRAY_SIZE(default_splash_locations));
+}
+#endif
+
+#define I2C_PAD_CTRL	(PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \
+			 PAD_CTL_PUS_100K_UP | PAD_CTL_ODE)
+
+static void setup_iomux_i2c(void)
+{
+	static const iomux_v3_cfg_t i2c_pads[] = {
+		/* I2C1 */
+		NEW_PAD_CTRL(MX53_PAD_EIM_D28__I2C1_SDA, I2C_PAD_CTRL),
+		NEW_PAD_CTRL(MX53_PAD_EIM_D21__I2C1_SCL, I2C_PAD_CTRL),
+		/* I2C2 */
+		NEW_PAD_CTRL(MX53_PAD_EIM_D16__I2C2_SDA, I2C_PAD_CTRL),
+		NEW_PAD_CTRL(MX53_PAD_EIM_EB2__I2C2_SCL, I2C_PAD_CTRL),
+	};
+
+	imx_iomux_v3_setup_multiple_pads(i2c_pads, ARRAY_SIZE(i2c_pads));
+}
+
+static void setup_iomux_video(void)
+{
+	static const iomux_v3_cfg_t lcd_pads[] = {
+		MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3,
+		MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK,
+		MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2,
+		MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1,
+		MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0,
+	};
+
+	imx_iomux_v3_setup_multiple_pads(lcd_pads, ARRAY_SIZE(lcd_pads));
+}
+
+static void setup_iomux_nand(void)
+{
+	static const iomux_v3_cfg_t nand_pads[] = {
+		NEW_PAD_CTRL(MX53_PAD_NANDF_WE_B__EMI_NANDF_WE_B,
+			     PAD_CTL_DSE_HIGH),
+		NEW_PAD_CTRL(MX53_PAD_NANDF_RE_B__EMI_NANDF_RE_B,
+			     PAD_CTL_DSE_HIGH),
+		NEW_PAD_CTRL(MX53_PAD_NANDF_CLE__EMI_NANDF_CLE,
+			     PAD_CTL_DSE_HIGH),
+		NEW_PAD_CTRL(MX53_PAD_NANDF_ALE__EMI_NANDF_ALE,
+			     PAD_CTL_DSE_HIGH),
+		NEW_PAD_CTRL(MX53_PAD_NANDF_WP_B__EMI_NANDF_WP_B,
+			     PAD_CTL_PUS_100K_UP),
+		NEW_PAD_CTRL(MX53_PAD_NANDF_RB0__EMI_NANDF_RB_0,
+			     PAD_CTL_PUS_100K_UP),
+		NEW_PAD_CTRL(MX53_PAD_NANDF_CS0__EMI_NANDF_CS_0,
+			     PAD_CTL_DSE_HIGH),
+		NEW_PAD_CTRL(MX53_PAD_PATA_DATA0__EMI_NANDF_D_0,
+			     PAD_CTL_DSE_HIGH | PAD_CTL_PKE),
+		NEW_PAD_CTRL(MX53_PAD_PATA_DATA1__EMI_NANDF_D_1,
+			     PAD_CTL_DSE_HIGH | PAD_CTL_PKE),
+		NEW_PAD_CTRL(MX53_PAD_PATA_DATA2__EMI_NANDF_D_2,
+			     PAD_CTL_DSE_HIGH | PAD_CTL_PKE),
+		NEW_PAD_CTRL(MX53_PAD_PATA_DATA3__EMI_NANDF_D_3,
+			     PAD_CTL_DSE_HIGH | PAD_CTL_PKE),
+		NEW_PAD_CTRL(MX53_PAD_PATA_DATA4__EMI_NANDF_D_4,
+			     PAD_CTL_DSE_HIGH | PAD_CTL_PKE),
+		NEW_PAD_CTRL(MX53_PAD_PATA_DATA5__EMI_NANDF_D_5,
+			     PAD_CTL_DSE_HIGH | PAD_CTL_PKE),
+		NEW_PAD_CTRL(MX53_PAD_PATA_DATA6__EMI_NANDF_D_6,
+			     PAD_CTL_DSE_HIGH | PAD_CTL_PKE),
+		NEW_PAD_CTRL(MX53_PAD_PATA_DATA7__EMI_NANDF_D_7,
+			     PAD_CTL_DSE_HIGH | PAD_CTL_PKE),
+	};
+
+	imx_iomux_v3_setup_multiple_pads(nand_pads, ARRAY_SIZE(nand_pads));
+}
+
+static void m53_set_clock(void)
+{
+	int ret;
+	const u32 ref_clk = MXC_HCLK;
+	const u32 dramclk = 400;
+	u32 cpuclk;
+
+	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX53_PAD_GPIO_10__GPIO4_0,
+					    PAD_CTL_DSE_HIGH | PAD_CTL_PKE));
+	gpio_direction_input(IMX_GPIO_NR(4, 0));
+
+	/* GPIO10 selects modules' CPU speed, 1 = 1200MHz ; 0 = 800MHz */
+	cpuclk = gpio_get_value(IMX_GPIO_NR(4, 0)) ? 1200 : 800;
+
+	ret = mxc_set_clock(ref_clk, cpuclk, MXC_ARM_CLK);
+	if (ret)
+		printf("CPU:   Switch CPU clock to %dMHz failed\n", cpuclk);
+
+	ret = mxc_set_clock(ref_clk, dramclk, MXC_PERIPH_CLK);
+	if (ret) {
+		printf("CPU:   Switch peripheral clock to %dMHz failed\n",
+		       dramclk);
+	}
+
+	ret = mxc_set_clock(ref_clk, dramclk, MXC_DDR_CLK);
+	if (ret)
+		printf("CPU:   Switch DDR clock to %dMHz failed\n", dramclk);
+}
+
+static void m53_set_nand(void)
+{
+	u32 i;
+
+	/* NAND flash is muxed on ATA pins */
+	setbits_le32(M4IF_BASE_ADDR + 0xc, M4IF_GENP_WEIM_MM_MASK);
+
+	/* Wait for Grant/Ack sequence (see EIM_CSnGCR2:MUX16_BYP_GRANT) */
+	for (i = 0x4; i < 0x94; i += 0x18) {
+		clrbits_le32(WEIM_BASE_ADDR + i,
+			     WEIM_GCR2_MUX16_BYP_GRANT_MASK);
+	}
+
+	mxc_set_clock(0, 33, MXC_NFC_CLK);
+	enable_nfc_clk(1);
+}
+
+int board_early_init_f(void)
+{
+	setup_iomux_uart();
+	setup_iomux_fec();
+	setup_iomux_i2c();
+	setup_iomux_nand();
+	setup_iomux_video();
+
+	m53_set_clock();
+
+	mxc_set_sata_internal_clock();
+
+	/* NAND clock @ 33MHz */
+	m53_set_nand();
+
+	return 0;
+}
+
+int board_init(void)
+{
+	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
+
+	return 0;
+}
+
+int checkboard(void)
+{
+	puts("Board: Menlosystems M53Menlo\n");
+
+	return 0;
+}
+
+/*
+ * NAND SPL
+ */
+#ifdef CONFIG_SPL_BUILD
+void spl_board_init(void)
+{
+	setup_iomux_nand();
+	m53_set_clock();
+	m53_set_nand();
+}
+
+u32 spl_boot_device(void)
+{
+	return BOOT_DEVICE_NAND;
+}
+#endif

+ 28 - 1
board/technexion/pico-imx7d/pico-imx7d.c

@@ -282,7 +282,34 @@ int checkboard(void)
 	return 0;
 }
 
+static iomux_v3_cfg_t const usb_otg2_pads[] = {
+	MX7D_PAD_UART3_CTS_B__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+int board_ehci_hcd_init(int port)
+{
+	switch (port) {
+	case 0:
+		break;
+	case 1:
+		imx_iomux_v3_setup_multiple_pads(usb_otg2_pads,
+						 ARRAY_SIZE(usb_otg2_pads));
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
 int board_usb_phy_mode(int port)
 {
-	return USB_INIT_DEVICE;
+	switch (port) {
+	case 0:
+		return USB_INIT_DEVICE;
+	case 1:
+		return USB_INIT_HOST;
+	default:
+		return -EINVAL;
+	}
+	return 0;
 }

+ 1 - 1
board/toradex/colibri_imx7/colibri_imx7.c

@@ -52,7 +52,7 @@ DECLARE_GLOBAL_DATA_PTR;
 
 int dram_init(void)
 {
-	gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
+	gd->ram_size = get_ram_size((void *)PHYS_SDRAM, imx_ddr_size());
 
 	return 0;
 }

+ 1 - 0
board/warp7/MAINTAINERS

@@ -4,3 +4,4 @@ S:	Maintained
 F:	board/warp7/
 F:	include/configs/warp7.h
 F:	configs/warp7_defconfig
+F:	configs/warp7_bl33_defconfig

+ 1 - 0
common/image.c

@@ -139,6 +139,7 @@ static const table_entry_t uimage_type[] = {
 	{	IH_TYPE_KERNEL_NOLOAD, "kernel_noload",  "Kernel Image (no loading done)", },
 	{	IH_TYPE_KWBIMAGE,   "kwbimage",   "Kirkwood Boot Image",},
 	{	IH_TYPE_IMXIMAGE,   "imximage",   "Freescale i.MX Boot Image",},
+	{	IH_TYPE_IMX8IMAGE,  "imx8image",  "NXP i.MX8 Boot Image",},
 	{	IH_TYPE_INVALID,    "invalid",	  "Invalid Image",	},
 	{	IH_TYPE_MULTI,	    "multi",	  "Multi-File Image",	},
 	{	IH_TYPE_OMAPIMAGE,  "omapimage",  "TI OMAP SPL With GP CH",},

+ 1 - 0
configs/aristainetos2_defconfig

@@ -50,4 +50,5 @@ CONFIG_USB=y
 CONFIG_USB_STORAGE=y
 CONFIG_VIDEO=y
 # CONFIG_VIDEO_SW_CURSOR is not set
+CONFIG_IMX_WATCHDOG=y
 CONFIG_OF_LIBFDT=y

+ 1 - 0
configs/aristainetos2b_defconfig

@@ -50,4 +50,5 @@ CONFIG_USB=y
 CONFIG_USB_STORAGE=y
 CONFIG_VIDEO=y
 # CONFIG_VIDEO_SW_CURSOR is not set
+CONFIG_IMX_WATCHDOG=y
 CONFIG_OF_LIBFDT=y

+ 1 - 0
configs/aristainetos_defconfig

@@ -49,4 +49,5 @@ CONFIG_USB=y
 CONFIG_USB_STORAGE=y
 CONFIG_VIDEO=y
 # CONFIG_VIDEO_SW_CURSOR is not set
+CONFIG_IMX_WATCHDOG=y
 CONFIG_OF_LIBFDT=y

+ 1 - 0
configs/dh_imx6_defconfig

@@ -59,4 +59,5 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x0525
 CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
 CONFIG_CI_UDC=y
 CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_IMX_WATCHDOG=y
 CONFIG_OF_LIBFDT=y

+ 1 - 0
configs/display5_defconfig

@@ -75,3 +75,4 @@ CONFIG_MII=y
 CONFIG_MXC_UART=y
 CONFIG_SPI=y
 CONFIG_MXC_SPI=y
+CONFIG_IMX_WATCHDOG=y

+ 1 - 0
configs/display5_factory_defconfig

@@ -82,4 +82,5 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x1b67
 CONFIG_USB_GADGET_PRODUCT_NUM=0x4000
 CONFIG_CI_UDC=y
 CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_IMX_WATCHDOG=y
 CONFIG_OF_LIBFDT=y

+ 1 - 0
configs/ge_bx50v3_defconfig

@@ -41,5 +41,6 @@ CONFIG_CMD_E1000=y
 CONFIG_MII=y
 CONFIG_SPI=y
 CONFIG_MXC_SPI=y
+CONFIG_IMX_WATCHDOG=y
 CONFIG_OF_LIBFDT=y
 # CONFIG_EFI_LOADER is not set

+ 52 - 0
configs/imx8qxp_mek_defconfig

@@ -0,0 +1,52 @@
+CONFIG_ARM=y
+CONFIG_ARCH_IMX8=y
+CONFIG_SYS_TEXT_BASE=0x80020000
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/imx8qxp_mek/imximage.cfg"
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_TARGET_IMX8QXP_MEK=y
+CONFIG_NR_DRAM_BANKS=3
+CONFIG_BOOTDELAY=3
+CONFIG_CMD_CPU=y
+# CONFIG_CMD_IMPORTENV is not set
+CONFIG_CMD_CLK=y
+CONFIG_CMD_DM=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_FAT=y
+CONFIG_DEFAULT_DEVICE_TREE="fsl-imx8qxp-mek"
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_CLK_IMX8=y
+CONFIG_CPU=y
+CONFIG_DM_GPIO=y
+CONFIG_MXC_GPIO=y
+CONFIG_DM_PCA953X=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_IMX_LPI2C=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_MISC=y
+CONFIG_DM_MMC=y
+CONFIG_PHYLIB=y
+CONFIG_PHY_ADDR_ENABLE=y
+CONFIG_PHY_ATHEROS=y
+CONFIG_DM_ETH=y
+CONFIG_PHY_GIGE=y
+CONFIG_FEC_MXC_SHARE_MDIO=y
+CONFIG_FEC_MXC_MDIO_BASE=0x5B040000
+CONFIG_FEC_MXC=y
+CONFIG_MII=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_IMX8=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_IMX8_POWER_DOMAIN=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_DM_SERIAL=y
+CONFIG_FSL_LPUART=y
+# CONFIG_EFI_LOADER is not set

+ 1 - 0
configs/kp_imx6q_tpc_defconfig

@@ -40,4 +40,5 @@ CONFIG_MII=y
 CONFIG_IMX_THERMAL=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
+CONFIG_IMX_WATCHDOG=y
 CONFIG_OF_LIBFDT=y

+ 60 - 0
configs/m53menlo_defconfig

@@ -0,0 +1,60 @@
+CONFIG_ARM=y
+CONFIG_ARCH_MX5=y
+CONFIG_SYS_TEXT_BASE=0x71000000
+CONFIG_SPL_GPIO_SUPPORT=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_TARGET_M53MENLO=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL=y
+# CONFIG_CMD_BMODE is not set
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_FIT=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/menlo/m53menlo/imximage.cfg"
+CONFIG_BOOTDELAY=1
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttymxc0,115200"
+# CONFIG_CONSOLE_MUX is not set
+CONFIG_SYS_CONSOLE_IS_IN_ENV=y
+CONFIG_VERSION_VARIABLE=y
+CONFIG_SPL_BOARD_INIT=y
+CONFIG_SPL_NAND_SUPPORT=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_ASKENV=y
+CONFIG_CMD_GREPENV=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_FUSE=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_NAND_TRIMFFS=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_BMP=y
+CONFIG_CMD_DATE=y
+CONFIG_CMD_BTRFS=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_MTDIDS_DEFAULT="nand0=mxc_nand"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=mxc_nand:1m(u-boot),512k(env1),512k(env2),-(ubi)"
+CONFIG_CMD_UBI=y
+CONFIG_ENV_IS_IN_NAND=y
+CONFIG_FSL_ESDHC=y
+CONFIG_NAND=y
+CONFIG_NAND_MXC=y
+CONFIG_PHYLIB=y
+CONFIG_PHY_MICREL=y
+CONFIG_USB=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_HOST_ETHER=y
+CONFIG_USB_ETHER_ASIX=y
+CONFIG_USB_ETHER_MCS7830=y
+CONFIG_USB_ETHER_SMSC95XX=y
+CONFIG_VIDEO=y
+# CONFIG_VIDEO_SW_CURSOR is not set
+CONFIG_FAT_WRITE=y
+CONFIG_OF_LIBFDT=y

+ 1 - 0
configs/mx53ppd_defconfig

@@ -37,4 +37,5 @@ CONFIG_USB=y
 CONFIG_USB_STORAGE=y
 CONFIG_VIDEO=y
 # CONFIG_VIDEO_SW_CURSOR is not set
+CONFIG_IMX_WATCHDOG=y
 CONFIG_OF_LIBFDT=y

+ 0 - 1
configs/pico-hobbit-imx7d_defconfig

@@ -8,7 +8,6 @@ CONFIG_TARGET_PICO_IMX7D=y
 CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL=y
-CONFIG_SPL_LIBDISK_SUPPORT=y
 CONFIG_ARMV7_BOOT_SEC_DEFAULT=y
 CONFIG_IMX_RDC=y
 CONFIG_IMX_BOOTAUX=y

+ 0 - 1
configs/pico-imx7d_defconfig

@@ -8,7 +8,6 @@ CONFIG_TARGET_PICO_IMX7D=y
 CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL=y
-CONFIG_SPL_LIBDISK_SUPPORT=y
 CONFIG_ARMV7_BOOT_SEC_DEFAULT=y
 CONFIG_IMX_RDC=y
 CONFIG_IMX_BOOTAUX=y

+ 0 - 1
configs/pico-pi-imx7d_defconfig

@@ -8,7 +8,6 @@ CONFIG_TARGET_PICO_IMX7D=y
 CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL=y
-CONFIG_SPL_LIBDISK_SUPPORT=y
 CONFIG_ARMV7_BOOT_SEC_DEFAULT=y
 CONFIG_IMX_RDC=y
 CONFIG_IMX_BOOTAUX=y

+ 1 - 0
configs/tqma6s_wru4_mmc_defconfig

@@ -65,4 +65,5 @@ CONFIG_USB=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_SMSC95XX=y
+CONFIG_IMX_WATCHDOG=y
 CONFIG_OF_LIBFDT=y

+ 42 - 0
configs/warp7_bl33_defconfig

@@ -0,0 +1,42 @@
+CONFIG_ARM=y
+CONFIG_ARCH_MX7=y
+CONFIG_SECURE_BOOT=y
+CONFIG_SYS_TEXT_BASE=0x87800000
+CONFIG_TARGET_WARP7=y
+CONFIG_ARMV7_BOOT_SEC_DEFAULT=y
+CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/warp7/imximage.cfg"
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_DFU=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+CONFIG_CMD_SETEXPR=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_DFU_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_MXC_USB_OTG_HACTIVE=y
+CONFIG_USB_STORAGE=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_USB_GADGET_DOWNLOAD=y
+CONFIG_USB_ETHER=y
+CONFIG_USB_ETH_CDC=y
+CONFIG_USBNET_HOST_ADDR="de:ad:be:af:00:00"
+CONFIG_OF_LIBFDT=y
+CONFIG_OPTEE_TZDRAM_SIZE=0x2000000

+ 2 - 0
configs/warp7_defconfig

@@ -46,5 +46,7 @@ CONFIG_USB_ETH_CDC=y
 CONFIG_USBNET_HOST_ADDR="de:ad:be:af:00:00"
 CONFIG_OF_LIBFDT=y
 CONFIG_OPTEE=y
+CONFIG_OPTEE_TZDRAM_SIZE=0x3000000
+CONFIG_OPTEE_TZDRAM_BASE=0x9d000000
 CONFIG_OPTEE_LOAD_ADDR=0x84000000
 CONFIG_BOOTM_OPTEE=y

+ 1 - 0
configs/warp_defconfig

@@ -37,4 +37,5 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x0525
 CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
 CONFIG_CI_UDC=y
 CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_IMX_WATCHDOG=y
 CONFIG_OF_LIBFDT=y

+ 0 - 0
doc/README.imx25 → doc/imx/common/imx25.txt


+ 0 - 0
doc/README.imx27 → doc/imx/common/imx27.txt


+ 0 - 0
doc/README.imx5 → doc/imx/common/imx5.txt


+ 0 - 25
doc/README.imx6 → doc/imx/common/imx6.txt

@@ -88,28 +88,3 @@ Reading bank 4:
 
 Word 0x00000002: 9f027772 00000004
 
-2. Using imx_usb_loader for first install with SPL
---------------------------------------------------
-
-imx_usb_loader is a very nice tool by Boundary Devices that
-allow to install U-Boot without a JTAG debugger, using
-the USB boot mode as described in the manual. It is
-a replacement for Freescale's MFGTOOLS.
-
-The sources can be found here:
-
-	https://github.com/boundarydevices/imx_usb_loader.git
-
-Booting in USB mode, the i.MX6 announces itself to the Linux Host as:
-
-Bus 001 Device 111: ID 15a2:0061 Freescale Semiconductor, Inc.
-
-imx_usb_loader is able to download a single file (u-boot.imx)
-to the board. For boards without SPL support, it is enough to
-issue the command:
-
-	sudo ../imx_usb_loader/imx_usb -v u-boot.imx
-
-In order to load SPL and u-boot.img via imx_usb_loader tool,
-please refer to doc/README.sdp.
-

+ 0 - 0
doc/README.mxs → doc/imx/common/mxs.txt


+ 43 - 0
doc/imx/hab/habv4/encrypted_boot.txt

@@ -0,0 +1,43 @@
+1. Setup U-Boot Image for Encrypted Boot
+----------------------------------------
+An authenticated U-Boot image is used as starting point for
+Encrypted Boot. The image is encrypted by i.MX Code Signing
+Tool (CST). The CST replaces only the image data of
+u-boot-dtb.imx with the encrypted data. The Initial Vector Table,
+DCD, and Boot data, remains in plaintext.
+
+The image data is encrypted with a Encryption Key (DEK).
+Therefore, this key is needed to decrypt the data during the
+booting process. The DEK is protected by wrapping it in a Blob,
+which needs to be appended to the U-Boot image and specified in
+the CSF file.
+
+The DEK blob is generated by an authenticated U-Boot image with
+the dek_blob cmd enabled. The image used for DEK blob generation
+needs to have the following configurations enabled in Kconfig:
+
+CONFIG_SECURE_BOOT=y
+CONFIG_CMD_DEKBLOB=y
+
+Note: The encrypted boot feature is only supported by HABv4 or
+greater.
+
+The dek_blob command then can be used to generate the DEK blob of
+a DEK previously loaded in memory. The command is used as follows:
+
+dek_blob <DEK address> <Output Address> <Key Size in Bits>
+example: dek_blob 0x10800000 0x10801000 192
+
+The resulting DEK blob then is used to construct the encrypted
+U-Boot image. Note that the blob needs to be transferred back
+to the host.Then the following commands are used to construct
+the final image.
+
+cat u-boot-dtb.imx csf-u-boot.bin > u-boot-signed.imx
+objcopy -I binary -O binary --pad-to <blob_dst> --gap-fill=0x00 \
+    u-boot-signed.imx u-boot-signed-pad.bin
+cat u-boot-signed-pad.imx DEK_blob.bin > u-boot-encrypted.imx
+
+    NOTE: u-boot-signed.bin needs to be padded to the value
+    equivalent to the address in which the DEK blob is specified
+    in the CSF.

+ 0 - 44
doc/README.mxc_hab → doc/imx/hab/habv4/secure_boot.txt

@@ -98,47 +98,3 @@ cat u-boot-ivt.img csf-u-boot.bin > u-boot-signed.img
 
 These two signed binaries can be used on an i.MX in closed
 configuration when the according SRK Table Hash has been flashed.
-
-4. Setup U-Boot Image for Encrypted Boot
-----------------------------------------
-An authenticated U-Boot image is used as starting point for
-Encrypted Boot. The image is encrypted by i.MX Code Signing
-Tool (CST). The CST replaces only the image data of
-u-boot-dtb.imx with the encrypted data. The Initial Vector Table,
-DCD, and Boot data, remains in plaintext.
-
-The image data is encrypted with a Encryption Key (DEK).
-Therefore, this key is needed to decrypt the data during the
-booting process. The DEK is protected by wrapping it in a Blob,
-which needs to be appended to the U-Boot image and specified in
-the CSF file.
-
-The DEK blob is generated by an authenticated U-Boot image with
-the dek_blob cmd enabled. The image used for DEK blob generation
-needs to have the following configurations enabled in Kconfig:
-
-CONFIG_SECURE_BOOT=y
-CONFIG_CMD_DEKBLOB=y
-
-Note: The encrypted boot feature is only supported by HABv4 or
-greater.
-
-The dek_blob command then can be used to generate the DEK blob of
-a DEK previously loaded in memory. The command is used as follows:
-
-dek_blob <DEK address> <Output Address> <Key Size in Bits>
-example: dek_blob 0x10800000 0x10801000 192
-
-The resulting DEK blob then is used to construct the encrypted
-U-Boot image. Note that the blob needs to be transferred back
-to the host.Then the following commands are used to construct
-the final image.
-
-cat u-boot-dtb.imx csf-u-boot.bin > u-boot-signed.imx
-objcopy -I binary -O binary --pad-to <blob_dst> --gap-fill=0x00 \
-    u-boot-signed.imx u-boot-signed-pad.bin
-cat u-boot-signed-pad.imx DEK_blob.bin > u-boot-encrypted.imx
-
-    NOTE: u-boot-signed.bin needs to be padded to the value
-    equivalent to the address in which the DEK blob is specified
-    in the CSF.

+ 20 - 2
doc/README.sdp → doc/imx/misc/sdp.txt

@@ -16,14 +16,19 @@ protocols allow to access a USB device without OS specific drivers. The
 U-Boot implementation has primarly been tested using the open source
 imx_loader utility (https://github.com/boundarydevices/imx_usb_loader).
 
+imx_usb_loader is a very nice tool by Boundary Devices that allow to
+install U-Boot without a JTAG debugger, using the USB boot mode as
+described in the manual. It is a replacement for Freescale's
+MFGTOOLS.
+
 The host side utilities are typically capable to interpret the i.MX
 specific image header (see doc/README.imximage). There are extensions
 for imx_loader's imx_usb utility which allow to interpret the U-Boot
 specific legacy image format (see mkimage(1)). Also the U-Boot side
 support beside the i.MX specific header the U-Boot legacy header.
 
-Usage
------
+1. Using imx_usb_loader for first install with SPL
+--------------------------------------------------
 
 This implementation can be started in U-Boot using the sdp command
 (CONFIG_CMD_USB_SDP) or in SPL if Serial Downloader boot mode has been
@@ -98,3 +103,16 @@ With that SPL and U-Boot can be downloaded with a single invocation
 of imx_usb without arguments:
 
   # imx_usb
+
+2. Using imx_usb_loader non-SPL images
+---------------------------------------
+
+Booting in USB mode, the i.MX6 announces itself to the Linux Host as:
+
+Bus 001 Device 111: ID 15a2:0061 Freescale Semiconductor, Inc.
+
+imx_usb_loader is able to download a single file (u-boot.imx)
+to the board. For boards without SPL support, it is enough to
+issue the command:
+
+	sudo ../imx_usb_loader/imx_usb -v u-boot.imx

+ 0 - 0
doc/README.imximage → doc/imx/mkimage/imximage.txt


+ 0 - 0
doc/README.mxsimage → doc/imx/mkimage/mxsimage.txt


+ 1 - 0
drivers/clk/Kconfig

@@ -100,6 +100,7 @@ config CLK_STM32MP1
 
 source "drivers/clk/at91/Kconfig"
 source "drivers/clk/exynos/Kconfig"
+source "drivers/clk/imx/Kconfig"
 source "drivers/clk/mvebu/Kconfig"
 source "drivers/clk/owl/Kconfig"
 source "drivers/clk/renesas/Kconfig"

+ 1 - 0
drivers/clk/Makefile

@@ -7,6 +7,7 @@
 
 obj-$(CONFIG_$(SPL_TPL_)CLK) += clk-uclass.o clk_fixed_rate.o
 
+obj-y += imx/
 obj-y += tegra/
 obj-$(CONFIG_ARCH_ASPEED) += aspeed/
 obj-$(CONFIG_ARCH_MESON) += clk_meson.o

+ 6 - 0
drivers/clk/imx/Kconfig

@@ -0,0 +1,6 @@
+config CLK_IMX8
+	bool "Clock support for i.MX8"
+	depends on ARCH_IMX8
+	select CLK
+	help
+	  This enables support clock driver for i.MX8 platforms.

+ 5 - 0
drivers/clk/imx/Makefile

@@ -0,0 +1,5 @@
+# Copyright 2018 NXP
+#
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_CLK_IMX8) += clk-imx8.o

+ 393 - 0
drivers/clk/imx/clk-imx8.c

@@ -0,0 +1,393 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2018 NXP
+ * Peng Fan <peng.fan@nxp.com>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <asm/arch/sci/sci.h>
+#include <asm/arch/clock.h>
+#include <dt-bindings/clock/imx8qxp-clock.h>
+#include <dt-bindings/soc/imx_rsrc.h>
+#include <misc.h>
+
+struct imx8_clks {
+	ulong id;
+	const char *name;
+};
+
+static struct imx8_clks imx8_clk_names[] = {
+	{ IMX8QXP_A35_DIV, "A35_DIV" },
+	{ IMX8QXP_I2C0_CLK, "I2C0" },
+	{ IMX8QXP_I2C1_CLK, "I2C1" },
+	{ IMX8QXP_I2C2_CLK, "I2C2" },
+	{ IMX8QXP_I2C3_CLK, "I2C3" },
+	{ IMX8QXP_UART0_CLK, "UART0" },
+	{ IMX8QXP_UART1_CLK, "UART1" },
+	{ IMX8QXP_UART2_CLK, "UART2" },
+	{ IMX8QXP_UART3_CLK, "UART3" },
+	{ IMX8QXP_SDHC0_CLK, "SDHC0" },
+	{ IMX8QXP_SDHC1_CLK, "SDHC1" },
+	{ IMX8QXP_ENET0_AHB_CLK, "ENET0_AHB" },
+	{ IMX8QXP_ENET0_IPG_CLK, "ENET0_IPG" },
+	{ IMX8QXP_ENET0_REF_DIV, "ENET0_REF" },
+	{ IMX8QXP_ENET0_PTP_CLK, "ENET0_PTP" },
+	{ IMX8QXP_ENET1_AHB_CLK, "ENET1_AHB" },
+	{ IMX8QXP_ENET1_IPG_CLK, "ENET1_IPG" },
+	{ IMX8QXP_ENET1_REF_DIV, "ENET1_REF" },
+	{ IMX8QXP_ENET1_PTP_CLK, "ENET1_PTP" },
+};
+
+static ulong imx8_clk_get_rate(struct clk *clk)
+{
+	sc_pm_clk_t pm_clk;
+	ulong rate;
+	u16 resource;
+	int ret;
+
+	debug("%s(#%lu)\n", __func__, clk->id);
+
+	switch (clk->id) {
+	case IMX8QXP_A35_DIV:
+		resource = SC_R_A35;
+		pm_clk = SC_PM_CLK_CPU;
+		break;
+	case IMX8QXP_I2C0_CLK:
+		resource = SC_R_I2C_0;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_I2C1_CLK:
+		resource = SC_R_I2C_1;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_I2C2_CLK:
+		resource = SC_R_I2C_2;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_I2C3_CLK:
+		resource = SC_R_I2C_3;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_SDHC0_IPG_CLK:
+	case IMX8QXP_SDHC0_CLK:
+	case IMX8QXP_SDHC0_DIV:
+		resource = SC_R_SDHC_0;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_SDHC1_IPG_CLK:
+	case IMX8QXP_SDHC1_CLK:
+	case IMX8QXP_SDHC1_DIV:
+		resource = SC_R_SDHC_1;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_UART0_IPG_CLK:
+	case IMX8QXP_UART0_CLK:
+		resource = SC_R_UART_0;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_UART1_CLK:
+		resource = SC_R_UART_1;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_UART2_CLK:
+		resource = SC_R_UART_2;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_UART3_CLK:
+		resource = SC_R_UART_3;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_ENET0_IPG_CLK:
+	case IMX8QXP_ENET0_AHB_CLK:
+	case IMX8QXP_ENET0_REF_DIV:
+	case IMX8QXP_ENET0_PTP_CLK:
+		resource = SC_R_ENET_0;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_ENET1_IPG_CLK:
+	case IMX8QXP_ENET1_AHB_CLK:
+	case IMX8QXP_ENET1_REF_DIV:
+	case IMX8QXP_ENET1_PTP_CLK:
+		resource = SC_R_ENET_1;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	default:
+		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
+		    clk->id >= IMX8QXP_CLK_END) {
+			printf("%s(Invalid clk ID #%lu)\n",
+			       __func__, clk->id);
+			return -EINVAL;
+		}
+		return -ENOTSUPP;
+	};
+
+	ret = sc_pm_get_clock_rate(-1, resource, pm_clk,
+				   (sc_pm_clock_rate_t *)&rate);
+	if (ret) {
+		printf("%s err %d\n", __func__, ret);
+		return ret;
+	}
+
+	return rate;
+}
+
+static ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	sc_pm_clk_t pm_clk;
+	u32 new_rate = rate;
+	u16 resource;
+	int ret;
+
+	debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
+
+	switch (clk->id) {
+	case IMX8QXP_I2C0_CLK:
+		resource = SC_R_I2C_0;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_I2C1_CLK:
+		resource = SC_R_I2C_1;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_I2C2_CLK:
+		resource = SC_R_I2C_2;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_I2C3_CLK:
+		resource = SC_R_I2C_3;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_UART0_CLK:
+		resource = SC_R_UART_0;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_UART1_CLK:
+		resource = SC_R_UART_1;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_UART2_CLK:
+		resource = SC_R_UART_2;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_UART3_CLK:
+		resource = SC_R_UART_3;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_SDHC0_IPG_CLK:
+	case IMX8QXP_SDHC0_CLK:
+	case IMX8QXP_SDHC0_DIV:
+		resource = SC_R_SDHC_0;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_SDHC1_SEL:
+	case IMX8QXP_SDHC0_SEL:
+		return 0;
+	case IMX8QXP_SDHC1_IPG_CLK:
+	case IMX8QXP_SDHC1_CLK:
+	case IMX8QXP_SDHC1_DIV:
+		resource = SC_R_SDHC_1;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_ENET0_IPG_CLK:
+	case IMX8QXP_ENET0_AHB_CLK:
+	case IMX8QXP_ENET0_REF_DIV:
+	case IMX8QXP_ENET0_PTP_CLK:
+		resource = SC_R_ENET_0;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_ENET1_IPG_CLK:
+	case IMX8QXP_ENET1_AHB_CLK:
+	case IMX8QXP_ENET1_REF_DIV:
+	case IMX8QXP_ENET1_PTP_CLK:
+		resource = SC_R_ENET_1;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	default:
+		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
+		    clk->id >= IMX8QXP_CLK_END) {
+			printf("%s(Invalid clk ID #%lu)\n",
+			       __func__, clk->id);
+			return -EINVAL;
+		}
+		return -ENOTSUPP;
+	};
+
+	ret = sc_pm_set_clock_rate(-1, resource, pm_clk, &new_rate);
+	if (ret) {
+		printf("%s err %d\n", __func__, ret);
+		return ret;
+	}
+
+	return new_rate;
+}
+
+static int __imx8_clk_enable(struct clk *clk, bool enable)
+{
+	sc_pm_clk_t pm_clk;
+	u16 resource;
+	int ret;
+
+	debug("%s(#%lu)\n", __func__, clk->id);
+
+	switch (clk->id) {
+	case IMX8QXP_I2C0_CLK:
+		resource = SC_R_I2C_0;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_I2C1_CLK:
+		resource = SC_R_I2C_1;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_I2C2_CLK:
+		resource = SC_R_I2C_2;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_I2C3_CLK:
+		resource = SC_R_I2C_3;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_UART0_CLK:
+		resource = SC_R_UART_0;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_UART1_CLK:
+		resource = SC_R_UART_1;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_UART2_CLK:
+		resource = SC_R_UART_2;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_UART3_CLK:
+		resource = SC_R_UART_3;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_SDHC0_IPG_CLK:
+	case IMX8QXP_SDHC0_CLK:
+	case IMX8QXP_SDHC0_DIV:
+		resource = SC_R_SDHC_0;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_SDHC1_IPG_CLK:
+	case IMX8QXP_SDHC1_CLK:
+	case IMX8QXP_SDHC1_DIV:
+		resource = SC_R_SDHC_1;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_ENET0_IPG_CLK:
+	case IMX8QXP_ENET0_AHB_CLK:
+	case IMX8QXP_ENET0_REF_DIV:
+	case IMX8QXP_ENET0_PTP_CLK:
+		resource = SC_R_ENET_0;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	case IMX8QXP_ENET1_IPG_CLK:
+	case IMX8QXP_ENET1_AHB_CLK:
+	case IMX8QXP_ENET1_REF_DIV:
+	case IMX8QXP_ENET1_PTP_CLK:
+		resource = SC_R_ENET_1;
+		pm_clk = SC_PM_CLK_PER;
+		break;
+	default:
+		if (clk->id < IMX8QXP_UART0_IPG_CLK ||
+		    clk->id >= IMX8QXP_CLK_END) {
+			printf("%s(Invalid clk ID #%lu)\n",
+			       __func__, clk->id);
+			return -EINVAL;
+		}
+		return -ENOTSUPP;
+	}
+
+	ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0);
+	if (ret) {
+		printf("%s err %d\n", __func__, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int imx8_clk_disable(struct clk *clk)
+{
+	return __imx8_clk_enable(clk, 0);
+}
+
+static int imx8_clk_enable(struct clk *clk)
+{
+	return __imx8_clk_enable(clk, 1);
+}
+
+#if CONFIG_IS_ENABLED(CMD_CLK)
+int soc_clk_dump(void)
+{
+	struct udevice *dev;
+	struct clk clk;
+	unsigned long rate;
+	int i, ret;
+
+	ret = uclass_get_device_by_driver(UCLASS_CLK,
+					  DM_GET_DRIVER(imx8_clk), &dev);
+	if (ret)
+		return ret;
+
+	printf("Clk\t\tHz\n");
+
+	for (i = 0; i < ARRAY_SIZE(imx8_clk_names); i++) {
+		clk.id = imx8_clk_names[i].id;
+		ret = clk_request(dev, &clk);
+		if (ret < 0) {
+			debug("%s clk_request() failed: %d\n", __func__, ret);
+			continue;
+		}
+
+		ret = clk_get_rate(&clk);
+		rate = ret;
+
+		clk_free(&clk);
+
+		if (ret == -ENOTSUPP) {
+			printf("clk ID %lu not supported yet\n",
+			       imx8_clk_names[i].id);
+			continue;
+		}
+		if (ret < 0) {
+			printf("%s %lu: get_rate err: %d\n",
+			       __func__, imx8_clk_names[i].id, ret);
+			continue;
+		}
+
+		printf("%s(%3lu):\t%lu\n",
+		       imx8_clk_names[i].name, imx8_clk_names[i].id, rate);
+	}
+
+	return 0;
+}
+#endif
+
+static struct clk_ops imx8_clk_ops = {
+	.set_rate = imx8_clk_set_rate,
+	.get_rate = imx8_clk_get_rate,
+	.enable = imx8_clk_enable,
+	.disable = imx8_clk_disable,
+};
+
+static int imx8_clk_probe(struct udevice *dev)
+{
+	return 0;
+}
+
+static const struct udevice_id imx8_clk_ids[] = {
+	{ .compatible = "fsl,imx8qxp-clk" },
+	{ },
+};
+
+U_BOOT_DRIVER(imx8_clk) = {
+	.name = "clk_imx8",
+	.id = UCLASS_CLK,
+	.of_match = imx8_clk_ids,
+	.ops = &imx8_clk_ops,
+	.probe = imx8_clk_probe,
+	.flags = DM_FLAG_PRE_RELOC,
+};

+ 21 - 9
drivers/gpio/mxc_gpio.c

@@ -40,21 +40,27 @@ static unsigned long gpio_ports[] = {
 	[2] = GPIO3_BASE_ADDR,
 #if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX51) || \
 		defined(CONFIG_MX53) || defined(CONFIG_MX6) || \
-		defined(CONFIG_MX7) || defined(CONFIG_MX8M)
+		defined(CONFIG_MX7) || defined(CONFIG_MX8M) || \
+		defined(CONFIG_ARCH_IMX8)
 	[3] = GPIO4_BASE_ADDR,
 #endif
 #if defined(CONFIG_MX27) || defined(CONFIG_MX53) || defined(CONFIG_MX6) || \
-		defined(CONFIG_MX7) || defined(CONFIG_MX8M)
+		defined(CONFIG_MX7) || defined(CONFIG_MX8M) || \
+		defined(CONFIG_ARCH_IMX8)
 	[4] = GPIO5_BASE_ADDR,
 #if !(defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL) || defined(CONFIG_MX8M))
 	[5] = GPIO6_BASE_ADDR,
 #endif
 #endif
-#if defined(CONFIG_MX53) || defined(CONFIG_MX6) || defined(CONFIG_MX7)
+#if defined(CONFIG_MX53) || defined(CONFIG_MX6) || defined(CONFIG_MX7) || \
+		defined(CONFIG_ARCH_IMX8)
 #if !(defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL))
 	[6] = GPIO7_BASE_ADDR,
 #endif
 #endif
+#if defined(CONFIG_ARCH_IMX8)
+	[7] = GPIO8_BASE_ADDR,
+#endif
 };
 
 static int mxc_gpio_direction(unsigned int gpio,
@@ -347,19 +353,22 @@ static const struct mxc_gpio_plat mxc_plat[] = {
 	{ 2, (struct gpio_regs *)GPIO3_BASE_ADDR },
 #if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX51) || \
 		defined(CONFIG_MX53) || defined(CONFIG_MX6) || \
-		defined(CONFIG_MX8M)
+		defined(CONFIG_MX8M) || defined(CONFIG_ARCH_IMX8)
 	{ 3, (struct gpio_regs *)GPIO4_BASE_ADDR },
 #endif
 #if defined(CONFIG_MX27) || defined(CONFIG_MX53) || defined(CONFIG_MX6) || \
-		defined(CONFIG_MX8M)
+		defined(CONFIG_MX8M) || defined(CONFIG_ARCH_IMX8)
 	{ 4, (struct gpio_regs *)GPIO5_BASE_ADDR },
 #ifndef CONFIG_MX8M
 	{ 5, (struct gpio_regs *)GPIO6_BASE_ADDR },
 #endif
 #endif
-#if defined(CONFIG_MX53) || defined(CONFIG_MX6)
+#if defined(CONFIG_MX53) || defined(CONFIG_MX6) || defined(CONFIG_ARCH_IMX8)
 	{ 6, (struct gpio_regs *)GPIO7_BASE_ADDR },
 #endif
+#if defined(CONFIG_ARCH_IMX8)
+	{ 7, (struct gpio_regs *)GPIO8_BASE_ADDR },
+#endif
 };
 
 U_BOOT_DEVICES(mxc_gpios) = {
@@ -368,19 +377,22 @@ U_BOOT_DEVICES(mxc_gpios) = {
 	{ "gpio_mxc", &mxc_plat[2] },
 #if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX51) || \
 		defined(CONFIG_MX53) || defined(CONFIG_MX6) || \
-		defined(CONFIG_MX8M)
+		defined(CONFIG_MX8M) || defined(CONFIG_ARCH_IMX8)
 	{ "gpio_mxc", &mxc_plat[3] },
 #endif
 #if defined(CONFIG_MX27) || defined(CONFIG_MX53) || defined(CONFIG_MX6) || \
-		defined(CONFIG_MX8M)
+		defined(CONFIG_MX8M) || defined(CONFIG_ARCH_IMX8)
 	{ "gpio_mxc", &mxc_plat[4] },
 #ifndef CONFIG_MX8M
 	{ "gpio_mxc", &mxc_plat[5] },
 #endif
 #endif
-#if defined(CONFIG_MX53) || defined(CONFIG_MX6)
+#if defined(CONFIG_MX53) || defined(CONFIG_MX6) || defined(CONFIG_ARCH_IMX8)
 	{ "gpio_mxc", &mxc_plat[6] },
 #endif
+#if defined(CONFIG_ARCH_IMX8)
+	{ "gpio_mxc", &mxc_plat[7] },
+#endif
 };
 #endif
 #endif

+ 2 - 2
drivers/i2c/imx_lpi2c.c

@@ -105,7 +105,7 @@ static int bus_i2c_send(struct udevice *bus, u8 *txbuf, int len)
 	while (len--) {
 		result = bus_i2c_wait_for_tx_ready(regs);
 		if (result) {
-			debug("i2c: send wait fot tx ready: %d\n", result);
+			debug("i2c: send wait for tx ready: %d\n", result);
 			return result;
 		}
 		writel(*txbuf++, &regs->mtdr);
@@ -482,7 +482,7 @@ static int imx_lpi2c_probe(struct udevice *bus)
 	if (ret < 0)
 		return ret;
 
-	debug("i2c : controller bus %d at %lu , speed %d: ",
+	debug("i2c : controller bus %d at 0x%lx , speed %d: ",
 	      bus->seq, i2c_bus->base,
 	      i2c_bus->speed);
 

+ 1 - 0
drivers/misc/Makefile

@@ -20,6 +20,7 @@ obj-$(CONFIG_FSL_IIM) += fsl_iim.o
 obj-$(CONFIG_LED_STATUS_GPIO) += gpio_led.o
 obj-$(CONFIG_$(SPL_)I2C_EEPROM) += i2c_eeprom.o
 obj-$(CONFIG_FSL_MC9SDZ60) += mc9sdz60.o
+obj-$(CONFIG_IMX8) += imx8/
 obj-$(CONFIG_MXC_OCOTP) += mxc_ocotp.o
 obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o
 obj-$(CONFIG_NUVOTON_NCT6102D) += nuvoton_nct6102d.o

+ 3 - 0
drivers/misc/imx8/Makefile

@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y += scu_api.o scu.o

+ 266 - 0
drivers/misc/imx8/scu.c

@@ -0,0 +1,266 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2018 NXP
+ *
+ * Peng Fan <peng.fan@nxp.com>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+#include <dm/device-internal.h>
+#include <asm/arch/sci/sci.h>
+#include <linux/iopoll.h>
+#include <misc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct mu_type {
+	u32 tr[4];
+	u32 rr[4];
+	u32 sr;
+	u32 cr;
+};
+
+struct imx8_scu {
+	struct mu_type *base;
+	struct udevice *clk;
+	struct udevice *pinclk;
+};
+
+#define MU_CR_GIE_MASK		0xF0000000u
+#define MU_CR_RIE_MASK		0xF000000u
+#define MU_CR_GIR_MASK		0xF0000u
+#define MU_CR_TIE_MASK		0xF00000u
+#define MU_CR_F_MASK		0x7u
+#define MU_SR_TE0_MASK		BIT(23)
+#define MU_SR_RF0_MASK		BIT(27)
+#define MU_TR_COUNT		4
+#define MU_RR_COUNT		4
+
+static inline void mu_hal_init(struct mu_type *base)
+{
+	/* Clear GIEn, RIEn, TIEn, GIRn and ABFn. */
+	clrbits_le32(&base->cr, MU_CR_GIE_MASK | MU_CR_RIE_MASK |
+		     MU_CR_TIE_MASK | MU_CR_GIR_MASK | MU_CR_F_MASK);
+}
+
+static int mu_hal_sendmsg(struct mu_type *base, u32 reg_index, u32 msg)
+{
+	u32 mask = MU_SR_TE0_MASK >> reg_index;
+	u32 val;
+	int ret;
+
+	assert(reg_index < MU_TR_COUNT);
+
+	/* Wait TX register to be empty. */
+	ret = readl_poll_timeout(&base->sr, val, val & mask, 10000);
+	if (ret < 0) {
+		printf("%s timeout\n", __func__);
+		return -ETIMEDOUT;
+	}
+
+	writel(msg, &base->tr[reg_index]);
+
+	return 0;
+}
+
+static int mu_hal_receivemsg(struct mu_type *base, u32 reg_index, u32 *msg)
+{
+	u32 mask = MU_SR_RF0_MASK >> reg_index;
+	u32 val;
+	int ret;
+
+	assert(reg_index < MU_TR_COUNT);
+
+	/* Wait RX register to be full. */
+	ret = readl_poll_timeout(&base->sr, val, val & mask, 10000);
+	if (ret < 0) {
+		printf("%s timeout\n", __func__);
+		return -ETIMEDOUT;
+	}
+
+	*msg = readl(&base->rr[reg_index]);
+
+	return 0;
+}
+
+static int sc_ipc_read(struct mu_type *base, void *data)
+{
+	struct sc_rpc_msg_s *msg = (struct sc_rpc_msg_s *)data;
+	int ret;
+	u8 count = 0;
+
+	if (!msg)
+		return -EINVAL;
+
+	/* Read first word */
+	ret = mu_hal_receivemsg(base, 0, (u32 *)msg);
+	if (ret)
+		return ret;
+	count++;
+
+	/* Check size */
+	if (msg->size > SC_RPC_MAX_MSG) {
+		*((u32 *)msg) = 0;
+		return -EINVAL;
+	}
+
+	/* Read remaining words */
+	while (count < msg->size) {
+		ret = mu_hal_receivemsg(base, count % MU_RR_COUNT,
+					&msg->DATA.u32[count - 1]);
+		if (ret)
+			return ret;
+		count++;
+	}
+
+	return 0;
+}
+
+static int sc_ipc_write(struct mu_type *base, void *data)
+{
+	struct sc_rpc_msg_s *msg = (struct sc_rpc_msg_s *)data;
+	int ret;
+	u8 count = 0;
+
+	if (!msg)
+		return -EINVAL;
+
+	/* Check size */
+	if (msg->size > SC_RPC_MAX_MSG)
+		return -EINVAL;
+
+	/* Write first word */
+	ret = mu_hal_sendmsg(base, 0, *((u32 *)msg));
+	if (ret)
+		return ret;
+	count++;
+
+	/* Write remaining words */
+	while (count < msg->size) {
+		ret = mu_hal_sendmsg(base, count % MU_TR_COUNT,
+				     msg->DATA.u32[count - 1]);
+		if (ret)
+			return ret;
+		count++;
+	}
+
+	return 0;
+}
+
+/*
+ * Note the function prototype use msgid as the 2nd parameter, here
+ * we take it as no_resp.
+ */
+static int imx8_scu_call(struct udevice *dev, int no_resp, void *tx_msg,
+			 int tx_size, void *rx_msg, int rx_size)
+{
+	struct imx8_scu *priv = dev_get_priv(dev);
+	sc_err_t result;
+	int ret;
+
+	/* Expect tx_msg, rx_msg are the same value */
+	if (rx_msg && tx_msg != rx_msg)
+		printf("tx_msg %p, rx_msg %p\n", tx_msg, rx_msg);
+
+	ret = sc_ipc_write(priv->base, tx_msg);
+	if (ret)
+		return ret;
+	if (!no_resp) {
+		ret = sc_ipc_read(priv->base, rx_msg);
+		if (ret)
+			return ret;
+	}
+
+	result = RPC_R8((struct sc_rpc_msg_s *)tx_msg);
+
+	return sc_err_to_linux(result);
+}
+
+static int imx8_scu_probe(struct udevice *dev)
+{
+	struct imx8_scu *priv = dev_get_priv(dev);
+	fdt_addr_t addr;
+
+	debug("%s(dev=%p) (priv=%p)\n", __func__, dev, priv);
+
+	addr = devfdt_get_addr(dev);
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->base = (struct mu_type *)addr;
+
+	/* U-Boot not enable interrupts, so need to enable RX interrupts */
+	mu_hal_init(priv->base);
+
+	gd->arch.scu_dev = dev;
+
+	device_probe(priv->clk);
+	device_probe(priv->pinclk);
+
+	return 0;
+}
+
+static int imx8_scu_remove(struct udevice *dev)
+{
+	return 0;
+}
+
+static int imx8_scu_bind(struct udevice *dev)
+{
+	struct imx8_scu *priv = dev_get_priv(dev);
+	int ret;
+	struct udevice *child;
+	int node;
+
+	debug("%s(dev=%p)\n", __func__, dev);
+
+	node = fdt_node_offset_by_compatible(gd->fdt_blob, -1,
+					     "fsl,imx8qxp-clk");
+	if (node < 0)
+		panic("No clk node found\n");
+
+	ret = lists_bind_fdt(dev, offset_to_ofnode(node), &child);
+	if (ret)
+		return ret;
+
+	priv->clk = child;
+
+	node = fdt_node_offset_by_compatible(gd->fdt_blob, -1,
+					     "fsl,imx8qxp-iomuxc");
+	if (node < 0)
+		panic("No iomuxc node found\n");
+
+	ret = lists_bind_fdt(dev, offset_to_ofnode(node), &child);
+	if (ret)
+		return ret;
+
+	priv->pinclk = child;
+
+	return 0;
+}
+
+static struct misc_ops imx8_scu_ops = {
+	.call = imx8_scu_call,
+};
+
+static const struct udevice_id imx8_scu_ids[] = {
+	{ .compatible = "fsl,imx8qxp-mu" },
+	{ .compatible = "fsl,imx8-mu" },
+	{ }
+};
+
+U_BOOT_DRIVER(imx8_scu) = {
+	.name		= "imx8_scu",
+	.id		= UCLASS_MISC,
+	.of_match	= imx8_scu_ids,
+	.probe		= imx8_scu_probe,
+	.bind		= imx8_scu_bind,
+	.remove		= imx8_scu_remove,
+	.ops		= &imx8_scu_ops,
+	.priv_auto_alloc_size = sizeof(struct imx8_scu),
+	.flags		= DM_FLAG_PRE_RELOC,
+};

+ 367 - 0
drivers/misc/imx8/scu_api.c

@@ -0,0 +1,367 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2018 NXP
+ *
+ * Peng Fan <peng.fan@nxp.com>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <dm.h>
+#include <asm/arch/sci/sci.h>
+#include <misc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* CLK and PM */
+int sc_pm_set_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
+			 sc_pm_clock_rate_t *rate)
+{
+	struct udevice *dev = gd->arch.scu_dev;
+	int size = sizeof(struct sc_rpc_msg_s);
+	struct sc_rpc_msg_s msg;
+	int ret;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
+	RPC_FUNC(&msg) = (u8)PM_FUNC_SET_CLOCK_RATE;
+	RPC_U32(&msg, 0U) = *(u32 *)rate;
+	RPC_U16(&msg, 4U) = (u16)resource;
+	RPC_U8(&msg, 6U) = (u8)clk;
+	RPC_SIZE(&msg) = 3U;
+
+	ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+	if (ret)
+		printf("%s: rate:%u resource:%u: clk:%u res:%d\n",
+		       __func__, *rate, resource, clk, RPC_R8(&msg));
+
+	*rate = RPC_U32(&msg, 0U);
+
+	return ret;
+}
+
+int sc_pm_get_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
+			 sc_pm_clock_rate_t *rate)
+{
+	struct udevice *dev = gd->arch.scu_dev;
+	int size = sizeof(struct sc_rpc_msg_s);
+	struct sc_rpc_msg_s msg;
+	int ret;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
+	RPC_FUNC(&msg) = (u8)PM_FUNC_GET_CLOCK_RATE;
+	RPC_U16(&msg, 0U) = (u16)resource;
+	RPC_U8(&msg, 2U) = (u8)clk;
+	RPC_SIZE(&msg) = 2U;
+
+	ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+	if (ret) {
+		printf("%s: resource:%d clk:%d: res:%d\n",
+		       __func__, resource, clk, RPC_R8(&msg));
+		return ret;
+	}
+
+	if (rate)
+		*rate = RPC_U32(&msg, 0U);
+
+	return 0;
+}
+
+int sc_pm_clock_enable(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
+		       sc_bool_t enable, sc_bool_t autog)
+{
+	struct udevice *dev = gd->arch.scu_dev;
+	int size = sizeof(struct sc_rpc_msg_s);
+	struct sc_rpc_msg_s msg;
+	int ret;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
+	RPC_FUNC(&msg) = (u8)PM_FUNC_CLOCK_ENABLE;
+	RPC_U16(&msg, 0U) = (u16)resource;
+	RPC_U8(&msg, 2U) = (u8)clk;
+	RPC_U8(&msg, 3U) = (u8)enable;
+	RPC_U8(&msg, 4U) = (u8)autog;
+	RPC_SIZE(&msg) = 3U;
+
+	ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+	if (ret)
+		printf("%s: resource:%d clk:%d: enable:%d autog: %d, res:%d\n",
+		       __func__, resource, clk, enable, autog, RPC_R8(&msg));
+
+	return ret;
+}
+
+int sc_pm_set_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
+				  sc_pm_power_mode_t mode)
+{
+	struct udevice *dev = gd->arch.scu_dev;
+	int size = sizeof(struct sc_rpc_msg_s);
+	struct sc_rpc_msg_s msg;
+	int ret;
+
+	if (!dev)
+		hang();
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
+	RPC_FUNC(&msg) = (u8)PM_FUNC_SET_RESOURCE_POWER_MODE;
+	RPC_U16(&msg, 0U) = (u16)resource;
+	RPC_U8(&msg, 2U) = (u8)mode;
+	RPC_SIZE(&msg) = 2U;
+
+	ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+	if (ret)
+		printf("%s: resource:%d mode:%d: res:%d\n",
+		       __func__, resource, mode, RPC_R8(&msg));
+
+	return ret;
+}
+
+/* PAD */
+int sc_pad_set(sc_ipc_t ipc, sc_pad_t pad, u32 val)
+{
+	struct udevice *dev = gd->arch.scu_dev;
+	int size = sizeof(struct sc_rpc_msg_s);
+	struct sc_rpc_msg_s msg;
+	int ret;
+
+	if (!dev)
+		hang();
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (u8)SC_RPC_SVC_PAD;
+	RPC_FUNC(&msg) = (u8)PAD_FUNC_SET;
+	RPC_U32(&msg, 0U) = (u32)val;
+	RPC_U16(&msg, 4U) = (u16)pad;
+	RPC_SIZE(&msg) = 3U;
+
+	ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+	if (ret)
+		printf("%s: val:%d pad:%d: res:%d\n",
+		       __func__, val, pad, RPC_R8(&msg));
+
+	return ret;
+}
+
+/* MISC */
+int sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource, sc_ctrl_t ctrl,
+			u32 *val)
+{
+	struct udevice *dev = gd->arch.scu_dev;
+	int size = sizeof(struct sc_rpc_msg_s);
+	struct sc_rpc_msg_s msg;
+	int ret;
+
+	if (!dev)
+		hang();
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_CONTROL;
+	RPC_U32(&msg, 0U) = (u32)ctrl;
+	RPC_U16(&msg, 4U) = (u16)resource;
+	RPC_SIZE(&msg) = 3U;
+
+	ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+	if (ret)
+		printf("%s: ctrl:%d resource:%d: res:%d\n",
+		       __func__, ctrl, resource, RPC_R8(&msg));
+
+	if (!val)
+		*val = RPC_U32(&msg, 0U);
+
+	return ret;
+}
+
+void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *boot_dev)
+{
+	struct udevice *dev = gd->arch.scu_dev;
+	int size = sizeof(struct sc_rpc_msg_s);
+	struct sc_rpc_msg_s msg;
+	int ret;
+
+	if (!dev)
+		hang();
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_BOOT_DEV;
+	RPC_SIZE(&msg) = 1U;
+
+	ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+	if (ret)
+		printf("%s: res:%d\n", __func__, RPC_R8(&msg));
+
+	if (!boot_dev)
+		*boot_dev = RPC_U16(&msg, 0U);
+}
+
+void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status)
+{
+	struct udevice *dev = gd->arch.scu_dev;
+	int size = sizeof(struct sc_rpc_msg_s);
+	struct sc_rpc_msg_s msg;
+	int ret;
+
+	if (!dev)
+		hang();
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (u8)MISC_FUNC_BOOT_STATUS;
+	RPC_U8(&msg, 0U) = (u8)status;
+	RPC_SIZE(&msg) = 2U;
+
+	ret = misc_call(dev, SC_TRUE, &msg, size, &msg, size);
+	if (ret)
+		printf("%s: status:%d res:%d\n",
+		       __func__, status, RPC_R8(&msg));
+}
+
+void sc_misc_build_info(sc_ipc_t ipc, u32 *build, u32 *commit)
+{
+	struct udevice *dev = gd->arch.scu_dev;
+	int size = sizeof(struct sc_rpc_msg_s);
+	struct sc_rpc_msg_s msg;
+	int ret;
+
+	if (!dev)
+		hang();
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = MISC_FUNC_BUILD_INFO;
+	RPC_SIZE(&msg) = 1;
+
+	ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+	if (ret < 0) {
+		printf("%s: err: %d\n", __func__, ret);
+		return;
+	}
+
+	if (build)
+		*build = RPC_U32(&msg, 0);
+	if (commit)
+		*commit = RPC_U32(&msg, 4);
+}
+
+int sc_misc_otp_fuse_read(sc_ipc_t ipc, u32 word, u32 *val)
+{
+	struct udevice *dev = gd->arch.scu_dev;
+	int size = sizeof(struct sc_rpc_msg_s);
+	struct sc_rpc_msg_s msg;
+	int ret;
+
+	if (!dev)
+		hang();
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = MISC_FUNC_OTP_FUSE_READ;
+	RPC_U32(&msg, 0) = word;
+	RPC_SIZE(&msg) = 2;
+
+	ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+	if (ret < 0)
+		return ret;
+
+	if (val)
+		*val = RPC_U32(&msg, 0U);
+
+	return 0;
+}
+
+/* RM */
+sc_bool_t sc_rm_is_memreg_owned(sc_ipc_t ipc, sc_rm_mr_t mr)
+{
+	struct udevice *dev = gd->arch.scu_dev;
+	int size = sizeof(struct sc_rpc_msg_s);
+	struct sc_rpc_msg_s msg;
+	int ret;
+	sc_err_t result;
+
+	if (!dev)
+		hang();
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
+	RPC_FUNC(&msg) = (u8)RM_FUNC_IS_MEMREG_OWNED;
+	RPC_U8(&msg, 0U) = (u8)mr;
+	RPC_SIZE(&msg) = 2U;
+
+	ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+	result = RPC_R8(&msg);
+
+	if (result != 0 && result != 1) {
+		printf("%s: mr:%d res:%d\n", __func__, mr, RPC_R8(&msg));
+		if (ret)
+			printf("%s: mr:%d res:%d\n", __func__, mr,
+			       RPC_R8(&msg));
+	}
+
+	return (sc_bool_t)result;
+}
+
+int sc_rm_get_memreg_info(sc_ipc_t ipc, sc_rm_mr_t mr, sc_faddr_t *addr_start,
+			  sc_faddr_t *addr_end)
+{
+	struct udevice *dev = gd->arch.scu_dev;
+	int size = sizeof(struct sc_rpc_msg_s);
+	struct sc_rpc_msg_s msg;
+	int ret;
+
+	if (!dev)
+		hang();
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
+	RPC_FUNC(&msg) = (u8)RM_FUNC_GET_MEMREG_INFO;
+	RPC_U8(&msg, 0U) = (u8)mr;
+	RPC_SIZE(&msg) = 2U;
+
+	ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+	if (ret)
+		printf("%s: mr:%d res:%d\n", __func__, mr, RPC_R8(&msg));
+
+	if (addr_start)
+		*addr_start = ((u64)RPC_U32(&msg, 0U) << 32U) |
+			RPC_U32(&msg, 4U);
+
+	if (addr_end)
+		*addr_end = ((u64)RPC_U32(&msg, 8U) << 32U) |
+			RPC_U32(&msg, 12U);
+
+	return ret;
+}
+
+sc_bool_t sc_rm_is_resource_owned(sc_ipc_t ipc, sc_rsrc_t resource)
+{
+	struct udevice *dev = gd->arch.scu_dev;
+	int size = sizeof(struct sc_rpc_msg_s);
+	struct sc_rpc_msg_s msg;
+	int ret;
+	u8 result;
+
+	if (!dev)
+		hang();
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
+	RPC_FUNC(&msg) = (u8)RM_FUNC_IS_RESOURCE_OWNED;
+	RPC_U16(&msg, 0U) = (u16)resource;
+	RPC_SIZE(&msg) = 2U;
+
+	ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+	result = RPC_R8(&msg);
+	if (result != 0 && result != 1) {
+		printf("%s: resource:%d res:%d\n",
+		       __func__, resource, RPC_R8(&msg));
+		if (ret)
+			printf("%s: res:%d res:%d\n", __func__, resource,
+			       RPC_R8(&msg));
+	}
+
+	return !!result;
+}

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików