Преглед на файлове

Merge tag 'u-boot-imx-20190719' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx

u-boot-imx-20190719

- CCF for i.MX6
- nandbcb command to write SPL into NAND
- Switch to DM (i.MX28)
- Boards: Toradex, engicam, DH
- Fixes for i.MX8
- Fixes for i.MX7ULP

Travis: https://travis-ci.org/sbabic/u-boot-imx/builds/561147504
Tom Rini преди 4 години
родител
ревизия
df9a7a195b
променени са 100 файла, в които са добавени 4738 реда и са изтрити 506 реда
  1. 12 0
      MAINTAINERS
  2. 0 4
      README
  3. 3 2
      arch/arm/dts/Makefile
  4. 64 0
      arch/arm/dts/fsl-imx8dx.dtsi
  5. 506 0
      arch/arm/dts/imx28-pinfunc.h
  6. 28 0
      arch/arm/dts/imx28-u-boot.dtsi
  7. 1330 0
      arch/arm/dts/imx28.dtsi
  8. 5 0
      arch/arm/dts/imx53-m53menlo-u-boot.dtsi
  9. 14 0
      arch/arm/dts/imx6dl-dhcom-pdk2.dts
  10. 5 136
      arch/arm/dts/imx6q-dhcom-pdk2.dts
  11. 44 0
      arch/arm/dts/imx6q-display5-u-boot.dtsi
  12. 352 0
      arch/arm/dts/imx6q-display5.dts
  13. 142 0
      arch/arm/dts/imx6qdl-dhcom-pdk2.dtsi
  14. 1 2
      arch/arm/dts/imx6qdl-dhcom.dtsi
  15. 2 0
      arch/arm/dts/imx7d-pico.dtsi
  16. 31 0
      arch/arm/dts/mxs-pinfunc.h
  17. 2 0
      arch/arm/include/asm/arch-imx8/sci/sci.h
  18. 1 0
      arch/arm/include/asm/arch-imx8/sci/svc/misc/api.h
  19. 3 0
      arch/arm/include/asm/arch-imx8/sys_proto.h
  20. 111 0
      arch/arm/include/asm/mach-imx/imx-nandbcb.h
  21. 11 0
      arch/arm/mach-imx/Kconfig
  22. 1 0
      arch/arm/mach-imx/Makefile
  23. 369 0
      arch/arm/mach-imx/cmd_nandbcb.c
  24. 4 2
      arch/arm/mach-imx/cpu.c
  25. 1 1
      arch/arm/mach-imx/imx8/Makefile
  26. 39 0
      arch/arm/mach-imx/imx8/misc.c
  27. 5 0
      arch/arm/mach-imx/mx6/soc.c
  28. 5 3
      arch/arm/mach-imx/spl.c
  29. 10 0
      arch/sandbox/dts/test.dts
  30. 0 21
      board/armadeus/opos6uldev/board.c
  31. 27 120
      board/dhelectronics/dh_imx6/dh_imx6.c
  32. 7 2
      board/dhelectronics/dh_imx6/dh_imx6_spl.c
  33. 0 2
      board/engicam/common/board.c
  34. 3 26
      board/freescale/imx8qm_mek/imx8qm_mek.c
  35. 3 26
      board/freescale/imx8qxp_mek/imx8qxp_mek.c
  36. 7 0
      board/freescale/mx6sxsabresd/imximage.cfg
  37. 6 11
      board/freescale/mx7ulp_evk/imximage.cfg
  38. 8 15
      board/freescale/mx7ulp_evk/plugin.S
  39. 1 1
      board/liebherr/display5/common.c
  40. 0 9
      board/liebherr/display5/display5.c
  41. 1 11
      board/logicpd/imx6/imx6logic.c
  42. 0 13
      board/technexion/pico-imx7d/pico-imx7d.c
  43. 3 27
      board/toradex/apalis-imx8/apalis-imx8.c
  44. 3 26
      board/toradex/colibri-imx8x/colibri-imx8x.c
  45. 46 20
      board/toradex/common/tdx-cfg-block.c
  46. 10 2
      cmd/Kconfig
  47. 1 1
      cmd/eeprom.c
  48. 1 1
      common/board_r.c
  49. 1 0
      common/spl/Kconfig
  50. 1 1
      common/spl/spl.c
  51. 0 2
      configs/apalis_imx6_defconfig
  52. 1 0
      configs/aristainetos2_defconfig
  53. 1 0
      configs/aristainetos2b_defconfig
  54. 1 0
      configs/aristainetos_defconfig
  55. 0 1
      configs/colibri-imx6ull_defconfig
  56. 0 2
      configs/colibri_imx6_defconfig
  57. 2 3
      configs/colibri_imx7_emmc_defconfig
  58. 9 1
      configs/dh_imx6_defconfig
  59. 3 0
      configs/display5_defconfig
  60. 1 0
      configs/dms-ba16-1g_defconfig
  61. 1 0
      configs/dms-ba16_defconfig
  62. 1 0
      configs/ge_bx50v3_defconfig
  63. 6 0
      configs/imx6q_logic_defconfig
  64. 1 0
      configs/imx6qdl_icore_mmc_defconfig
  65. 1 0
      configs/imx6qdl_icore_nand_defconfig
  66. 2 0
      configs/imx8qxp_mek_defconfig
  67. 2 0
      configs/kp_imx53_defconfig
  68. 2 0
      configs/m53menlo_defconfig
  69. 0 2
      configs/mccmon6_nor_defconfig
  70. 0 2
      configs/mccmon6_sd_defconfig
  71. 1 0
      configs/mx53ppd_defconfig
  72. 1 0
      configs/pico-hobbit-imx7d_defconfig
  73. 1 0
      configs/pico-imx7d_bl33_defconfig
  74. 1 0
      configs/pico-imx7d_defconfig
  75. 1 0
      configs/pico-pi-imx7d_defconfig
  76. 1 0
      configs/sandbox_defconfig
  77. 1 0
      configs/sandbox_flattree_defconfig
  78. 1 0
      configs/vining_2000_defconfig
  79. 8 1
      configs/warp7_bl33_defconfig
  80. 2 0
      doc/README.falcon
  81. 101 0
      doc/imx/clk/ccf.txt
  82. 74 0
      doc/imx/common/imx6.txt
  83. 22 0
      drivers/clk/Kconfig
  84. 3 0
      drivers/clk/Makefile
  85. 155 0
      drivers/clk/clk-divider.c
  86. 80 0
      drivers/clk/clk-fixed-factor.c
  87. 172 0
      drivers/clk/clk-mux.c
  88. 60 0
      drivers/clk/clk-uclass.c
  89. 57 0
      drivers/clk/clk.c
  90. 0 3
      drivers/clk/clk_fixed_factor.c
  91. 5 3
      drivers/clk/clk_fixed_rate.c
  92. 185 0
      drivers/clk/clk_sandbox_ccf.c
  93. 16 0
      drivers/clk/imx/Kconfig
  94. 2 0
      drivers/clk/imx/Makefile
  95. 103 0
      drivers/clk/imx/clk-gate2.c
  96. 179 0
      drivers/clk/imx/clk-imx6q.c
  97. 90 0
      drivers/clk/imx/clk-pfd.c
  98. 82 0
      drivers/clk/imx/clk-pllv3.c
  99. 69 0
      drivers/clk/imx/clk.h
  100. 1 1
      drivers/gpio/mxc_gpio.c

+ 12 - 0
MAINTAINERS

@@ -445,6 +445,13 @@ T:	git https://gitlab.denx.de/u-boot/custodians/u-boot-cfi-flash.git
 F:	drivers/mtd/cfi_flash.c
 F:	drivers/mtd/jedec_flash.c
 
+CLOCK
+M:	Lukasz Majewski <lukma@denx.de>
+S:	Maintained
+T:	git git://git.denx.de/u-boot-dfu.git
+F:	drivers/clk/
+F:	drivers/clk/imx/
+
 COLDFIRE
 M:	Huan Wang <alison.wang@nxp.com>
 M:	Angelo Dureghello <angelo@sysam.it>
@@ -778,6 +785,11 @@ F:	drivers/tee/
 F:	include/tee.h
 F:	include/tee/
 
+TEE-lib
+M:	Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+S:	Maintained
+F:	lib/optee
+
 UBI
 M:	Kyungmin Park <kmpark@infradead.org>
 M:	Heiko Schocher <hs@denx.de>

+ 0 - 4
README

@@ -960,10 +960,6 @@ The following options need to be configured:
 			CONFIG_SH_ETHER_CACHE_WRITEBACK
 			If this option is set, the driver enables cache flush.
 
-- PWM Support:
-		CONFIG_PWM_IMX
-		Support for PWM module on the imx6.
-
 - TPM Support:
 		CONFIG_TPM
 		Support TPM devices.

+ 3 - 2
arch/arm/dts/Makefile

@@ -551,6 +551,7 @@ dtb-$(CONFIG_MX6Q) += \
 	imx6q-tbs2910.dtb
 
 dtb-$(CONFIG_MX6QDL) += \
+	imx6dl-dhcom-pdk2.dtb \
 	imx6dl-icore.dtb \
 	imx6dl-icore-mipi.dtb \
 	imx6dl-icore-rqs.dtb \
@@ -559,6 +560,7 @@ dtb-$(CONFIG_MX6QDL) += \
 	imx6dl-sabresd.dtb \
 	imx6dl-wandboard-revb1.dtb \
 	imx6q-cm-fx6.dtb \
+	imx6q-dhcom-pdk2.dtb \
 	imx6q-icore.dtb \
 	imx6q-icore-mipi.dtb \
 	imx6q-icore-rqs.dtb \
@@ -599,8 +601,7 @@ dtb-$(CONFIG_MX6ULL) += \
 
 dtb-$(CONFIG_ARCH_MX6) += \
 	imx6-apalis.dtb \
-	imx6-colibri.dtb \
-	imx6q-dhcom-pdk2.dtb
+	imx6-colibri.dtb
 
 dtb-$(CONFIG_MX7) += imx7d-sdb.dtb \
 	imx7d-sdb-qspi.dtb \

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

@@ -11,6 +11,7 @@
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/pinctrl/pads-imx8qxp.h>
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/thermal/thermal.h>
 
 / {
 	model = "Freescale i.MX8DX";
@@ -30,6 +31,14 @@
 		i2c1 = &i2c1;
 		i2c2 = &i2c2;
 		i2c3 = &i2c3;
+		gpio0 = &gpio0;
+		gpio1 = &gpio1;
+		gpio2 = &gpio2;
+		gpio3 = &gpio3;
+		gpio4 = &gpio4;
+		gpio5 = &gpio5;
+		gpio6 = &gpio6;
+		gpio7 = &gpio7;
 	};
 
 	memory@80000000 {
@@ -543,6 +552,61 @@
 		power-domains = <&pd_conn_enet1>;
 		status = "disabled";
 	};
+
+	tsens: thermal-sensor {
+		compatible = "nxp,imx8qxp-sc-tsens";
+		/* number of the temp sensor on the chip */
+		tsens-num = <2>;
+		#thermal-sensor-cells = <1>;
+	};
+
+	thermal_zones: thermal-zones {
+		/* cpu thermal */
+		cpu-thermal0 {
+			polling-delay-passive = <250>;
+			polling-delay = <2000>;
+			/*the slope and offset of the temp sensor */
+			thermal-sensors = <&tsens 0>;
+			trips {
+				cpu_alert0: trip0 {
+					temperature = <107000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+				cpu_crit0: trip1 {
+					temperature = <127000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+			cooling-maps {
+				map0 {
+					trip = <&cpu_alert0>;
+					cooling-device =
+					<&A35_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+		};
+
+		drc-thermal0 {
+			polling-delay-passive = <250>;
+			polling-delay = <2000>;
+			thermal-sensors = <&tsens 1>;
+			status = "disabled";
+			trips {
+				drc_alert0: trip0 {
+					temperature = <107000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+				drc_crit0: trip1 {
+					temperature = <127000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+	};
 };
 
 &A35_0 {

+ 506 - 0
arch/arm/dts/imx28-pinfunc.h

@@ -0,0 +1,506 @@
+/*
+ * Header providing constants for i.MX28 pinctrl bindings.
+ *
+ * Copyright (C) 2013 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __DT_BINDINGS_MX28_PINCTRL_H__
+#define __DT_BINDINGS_MX28_PINCTRL_H__
+
+#include "mxs-pinfunc.h"
+
+#define MX28_PAD_GPMI_D00__GPMI_D0			0x0000
+#define MX28_PAD_GPMI_D01__GPMI_D1			0x0010
+#define MX28_PAD_GPMI_D02__GPMI_D2			0x0020
+#define MX28_PAD_GPMI_D03__GPMI_D3			0x0030
+#define MX28_PAD_GPMI_D04__GPMI_D4			0x0040
+#define MX28_PAD_GPMI_D05__GPMI_D5			0x0050
+#define MX28_PAD_GPMI_D06__GPMI_D6			0x0060
+#define MX28_PAD_GPMI_D07__GPMI_D7			0x0070
+#define MX28_PAD_GPMI_CE0N__GPMI_CE0N			0x0100
+#define MX28_PAD_GPMI_CE1N__GPMI_CE1N			0x0110
+#define MX28_PAD_GPMI_CE2N__GPMI_CE2N			0x0120
+#define MX28_PAD_GPMI_CE3N__GPMI_CE3N			0x0130
+#define MX28_PAD_GPMI_RDY0__GPMI_READY0			0x0140
+#define MX28_PAD_GPMI_RDY1__GPMI_READY1			0x0150
+#define MX28_PAD_GPMI_RDY2__GPMI_READY2			0x0160
+#define MX28_PAD_GPMI_RDY3__GPMI_READY3			0x0170
+#define MX28_PAD_GPMI_RDN__GPMI_RDN			0x0180
+#define MX28_PAD_GPMI_WRN__GPMI_WRN			0x0190
+#define MX28_PAD_GPMI_ALE__GPMI_ALE			0x01a0
+#define MX28_PAD_GPMI_CLE__GPMI_CLE			0x01b0
+#define MX28_PAD_GPMI_RESETN__GPMI_RESETN		0x01c0
+#define MX28_PAD_LCD_D00__LCD_D0			0x1000
+#define MX28_PAD_LCD_D01__LCD_D1			0x1010
+#define MX28_PAD_LCD_D02__LCD_D2			0x1020
+#define MX28_PAD_LCD_D03__LCD_D3			0x1030
+#define MX28_PAD_LCD_D04__LCD_D4			0x1040
+#define MX28_PAD_LCD_D05__LCD_D5			0x1050
+#define MX28_PAD_LCD_D06__LCD_D6			0x1060
+#define MX28_PAD_LCD_D07__LCD_D7			0x1070
+#define MX28_PAD_LCD_D08__LCD_D8			0x1080
+#define MX28_PAD_LCD_D09__LCD_D9			0x1090
+#define MX28_PAD_LCD_D10__LCD_D10			0x10a0
+#define MX28_PAD_LCD_D11__LCD_D11			0x10b0
+#define MX28_PAD_LCD_D12__LCD_D12			0x10c0
+#define MX28_PAD_LCD_D13__LCD_D13			0x10d0
+#define MX28_PAD_LCD_D14__LCD_D14			0x10e0
+#define MX28_PAD_LCD_D15__LCD_D15			0x10f0
+#define MX28_PAD_LCD_D16__LCD_D16			0x1100
+#define MX28_PAD_LCD_D17__LCD_D17			0x1110
+#define MX28_PAD_LCD_D18__LCD_D18			0x1120
+#define MX28_PAD_LCD_D19__LCD_D19			0x1130
+#define MX28_PAD_LCD_D20__LCD_D20			0x1140
+#define MX28_PAD_LCD_D21__LCD_D21			0x1150
+#define MX28_PAD_LCD_D22__LCD_D22			0x1160
+#define MX28_PAD_LCD_D23__LCD_D23			0x1170
+#define MX28_PAD_LCD_RD_E__LCD_RD_E			0x1180
+#define MX28_PAD_LCD_WR_RWN__LCD_WR_RWN			0x1190
+#define MX28_PAD_LCD_RS__LCD_RS				0x11a0
+#define MX28_PAD_LCD_CS__LCD_CS				0x11b0
+#define MX28_PAD_LCD_VSYNC__LCD_VSYNC			0x11c0
+#define MX28_PAD_LCD_HSYNC__LCD_HSYNC			0x11d0
+#define MX28_PAD_LCD_DOTCLK__LCD_DOTCLK			0x11e0
+#define MX28_PAD_LCD_ENABLE__LCD_ENABLE			0x11f0
+#define MX28_PAD_SSP0_DATA0__SSP0_D0			0x2000
+#define MX28_PAD_SSP0_DATA1__SSP0_D1			0x2010
+#define MX28_PAD_SSP0_DATA2__SSP0_D2			0x2020
+#define MX28_PAD_SSP0_DATA3__SSP0_D3			0x2030
+#define MX28_PAD_SSP0_DATA4__SSP0_D4			0x2040
+#define MX28_PAD_SSP0_DATA5__SSP0_D5			0x2050
+#define MX28_PAD_SSP0_DATA6__SSP0_D6			0x2060
+#define MX28_PAD_SSP0_DATA7__SSP0_D7			0x2070
+#define MX28_PAD_SSP0_CMD__SSP0_CMD			0x2080
+#define MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT		0x2090
+#define MX28_PAD_SSP0_SCK__SSP0_SCK			0x20a0
+#define MX28_PAD_SSP1_SCK__SSP1_SCK			0x20c0
+#define MX28_PAD_SSP1_CMD__SSP1_CMD			0x20d0
+#define MX28_PAD_SSP1_DATA0__SSP1_D0			0x20e0
+#define MX28_PAD_SSP1_DATA3__SSP1_D3			0x20f0
+#define MX28_PAD_SSP2_SCK__SSP2_SCK			0x2100
+#define MX28_PAD_SSP2_MOSI__SSP2_CMD			0x2110
+#define MX28_PAD_SSP2_MISO__SSP2_D0			0x2120
+#define MX28_PAD_SSP2_SS0__SSP2_D3			0x2130
+#define MX28_PAD_SSP2_SS1__SSP2_D4			0x2140
+#define MX28_PAD_SSP2_SS2__SSP2_D5			0x2150
+#define MX28_PAD_SSP3_SCK__SSP3_SCK			0x2180
+#define MX28_PAD_SSP3_MOSI__SSP3_CMD			0x2190
+#define MX28_PAD_SSP3_MISO__SSP3_D0			0x21a0
+#define MX28_PAD_SSP3_SS0__SSP3_D3			0x21b0
+#define MX28_PAD_AUART0_RX__AUART0_RX			0x3000
+#define MX28_PAD_AUART0_TX__AUART0_TX			0x3010
+#define MX28_PAD_AUART0_CTS__AUART0_CTS			0x3020
+#define MX28_PAD_AUART0_RTS__AUART0_RTS			0x3030
+#define MX28_PAD_AUART1_RX__AUART1_RX			0x3040
+#define MX28_PAD_AUART1_TX__AUART1_TX			0x3050
+#define MX28_PAD_AUART1_CTS__AUART1_CTS			0x3060
+#define MX28_PAD_AUART1_RTS__AUART1_RTS			0x3070
+#define MX28_PAD_AUART2_RX__AUART2_RX			0x3080
+#define MX28_PAD_AUART2_TX__AUART2_TX			0x3090
+#define MX28_PAD_AUART2_CTS__AUART2_CTS			0x30a0
+#define MX28_PAD_AUART2_RTS__AUART2_RTS			0x30b0
+#define MX28_PAD_AUART3_RX__AUART3_RX			0x30c0
+#define MX28_PAD_AUART3_TX__AUART3_TX			0x30d0
+#define MX28_PAD_AUART3_CTS__AUART3_CTS			0x30e0
+#define MX28_PAD_AUART3_RTS__AUART3_RTS			0x30f0
+#define MX28_PAD_PWM0__PWM_0				0x3100
+#define MX28_PAD_PWM1__PWM_1				0x3110
+#define MX28_PAD_PWM2__PWM_2				0x3120
+#define MX28_PAD_SAIF0_MCLK__SAIF0_MCLK			0x3140
+#define MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK		0x3150
+#define MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK		0x3160
+#define MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0		0x3170
+#define MX28_PAD_I2C0_SCL__I2C0_SCL			0x3180
+#define MX28_PAD_I2C0_SDA__I2C0_SDA			0x3190
+#define MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0		0x31a0
+#define MX28_PAD_SPDIF__SPDIF_TX			0x31b0
+#define MX28_PAD_PWM3__PWM_3				0x31c0
+#define MX28_PAD_PWM4__PWM_4				0x31d0
+#define MX28_PAD_LCD_RESET__LCD_RESET			0x31e0
+#define MX28_PAD_ENET0_MDC__ENET0_MDC			0x4000
+#define MX28_PAD_ENET0_MDIO__ENET0_MDIO			0x4010
+#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN		0x4020
+#define MX28_PAD_ENET0_RXD0__ENET0_RXD0			0x4030
+#define MX28_PAD_ENET0_RXD1__ENET0_RXD1			0x4040
+#define MX28_PAD_ENET0_TX_CLK__ENET0_TX_CLK		0x4050
+#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN		0x4060
+#define MX28_PAD_ENET0_TXD0__ENET0_TXD0			0x4070
+#define MX28_PAD_ENET0_TXD1__ENET0_TXD1			0x4080
+#define MX28_PAD_ENET0_RXD2__ENET0_RXD2			0x4090
+#define MX28_PAD_ENET0_RXD3__ENET0_RXD3			0x40a0
+#define MX28_PAD_ENET0_TXD2__ENET0_TXD2			0x40b0
+#define MX28_PAD_ENET0_TXD3__ENET0_TXD3			0x40c0
+#define MX28_PAD_ENET0_RX_CLK__ENET0_RX_CLK		0x40d0
+#define MX28_PAD_ENET0_COL__ENET0_COL			0x40e0
+#define MX28_PAD_ENET0_CRS__ENET0_CRS			0x40f0
+#define MX28_PAD_ENET_CLK__CLKCTRL_ENET			0x4100
+#define MX28_PAD_JTAG_RTCK__JTAG_RTCK			0x4140
+#define MX28_PAD_EMI_D00__EMI_DATA0			0x5000
+#define MX28_PAD_EMI_D01__EMI_DATA1			0x5010
+#define MX28_PAD_EMI_D02__EMI_DATA2			0x5020
+#define MX28_PAD_EMI_D03__EMI_DATA3			0x5030
+#define MX28_PAD_EMI_D04__EMI_DATA4			0x5040
+#define MX28_PAD_EMI_D05__EMI_DATA5			0x5050
+#define MX28_PAD_EMI_D06__EMI_DATA6			0x5060
+#define MX28_PAD_EMI_D07__EMI_DATA7			0x5070
+#define MX28_PAD_EMI_D08__EMI_DATA8			0x5080
+#define MX28_PAD_EMI_D09__EMI_DATA9			0x5090
+#define MX28_PAD_EMI_D10__EMI_DATA10			0x50a0
+#define MX28_PAD_EMI_D11__EMI_DATA11			0x50b0
+#define MX28_PAD_EMI_D12__EMI_DATA12			0x50c0
+#define MX28_PAD_EMI_D13__EMI_DATA13			0x50d0
+#define MX28_PAD_EMI_D14__EMI_DATA14			0x50e0
+#define MX28_PAD_EMI_D15__EMI_DATA15			0x50f0
+#define MX28_PAD_EMI_ODT0__EMI_ODT0			0x5100
+#define MX28_PAD_EMI_DQM0__EMI_DQM0			0x5110
+#define MX28_PAD_EMI_ODT1__EMI_ODT1			0x5120
+#define MX28_PAD_EMI_DQM1__EMI_DQM1			0x5130
+#define MX28_PAD_EMI_DDR_OPEN_FB__EMI_DDR_OPEN_FEEDBACK	0x5140
+#define MX28_PAD_EMI_CLK__EMI_CLK			0x5150
+#define MX28_PAD_EMI_DQS0__EMI_DQS0			0x5160
+#define MX28_PAD_EMI_DQS1__EMI_DQS1			0x5170
+#define MX28_PAD_EMI_DDR_OPEN__EMI_DDR_OPEN		0x51a0
+#define MX28_PAD_EMI_A00__EMI_ADDR0			0x6000
+#define MX28_PAD_EMI_A01__EMI_ADDR1			0x6010
+#define MX28_PAD_EMI_A02__EMI_ADDR2			0x6020
+#define MX28_PAD_EMI_A03__EMI_ADDR3			0x6030
+#define MX28_PAD_EMI_A04__EMI_ADDR4			0x6040
+#define MX28_PAD_EMI_A05__EMI_ADDR5			0x6050
+#define MX28_PAD_EMI_A06__EMI_ADDR6			0x6060
+#define MX28_PAD_EMI_A07__EMI_ADDR7			0x6070
+#define MX28_PAD_EMI_A08__EMI_ADDR8			0x6080
+#define MX28_PAD_EMI_A09__EMI_ADDR9			0x6090
+#define MX28_PAD_EMI_A10__EMI_ADDR10			0x60a0
+#define MX28_PAD_EMI_A11__EMI_ADDR11			0x60b0
+#define MX28_PAD_EMI_A12__EMI_ADDR12			0x60c0
+#define MX28_PAD_EMI_A13__EMI_ADDR13			0x60d0
+#define MX28_PAD_EMI_A14__EMI_ADDR14			0x60e0
+#define MX28_PAD_EMI_BA0__EMI_BA0			0x6100
+#define MX28_PAD_EMI_BA1__EMI_BA1			0x6110
+#define MX28_PAD_EMI_BA2__EMI_BA2			0x6120
+#define MX28_PAD_EMI_CASN__EMI_CASN			0x6130
+#define MX28_PAD_EMI_RASN__EMI_RASN			0x6140
+#define MX28_PAD_EMI_WEN__EMI_WEN			0x6150
+#define MX28_PAD_EMI_CE0N__EMI_CE0N			0x6160
+#define MX28_PAD_EMI_CE1N__EMI_CE1N			0x6170
+#define MX28_PAD_EMI_CKE__EMI_CKE			0x6180
+#define MX28_PAD_GPMI_D00__SSP1_D0			0x0001
+#define MX28_PAD_GPMI_D01__SSP1_D1			0x0011
+#define MX28_PAD_GPMI_D02__SSP1_D2			0x0021
+#define MX28_PAD_GPMI_D03__SSP1_D3			0x0031
+#define MX28_PAD_GPMI_D04__SSP1_D4			0x0041
+#define MX28_PAD_GPMI_D05__SSP1_D5			0x0051
+#define MX28_PAD_GPMI_D06__SSP1_D6			0x0061
+#define MX28_PAD_GPMI_D07__SSP1_D7			0x0071
+#define MX28_PAD_GPMI_CE0N__SSP3_D0			0x0101
+#define MX28_PAD_GPMI_CE1N__SSP3_D3			0x0111
+#define MX28_PAD_GPMI_CE2N__CAN1_TX			0x0121
+#define MX28_PAD_GPMI_CE3N__CAN1_RX			0x0131
+#define MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT		0x0141
+#define MX28_PAD_GPMI_RDY1__SSP1_CMD			0x0151
+#define MX28_PAD_GPMI_RDY2__CAN0_TX			0x0161
+#define MX28_PAD_GPMI_RDY3__CAN0_RX			0x0171
+#define MX28_PAD_GPMI_RDN__SSP3_SCK			0x0181
+#define MX28_PAD_GPMI_WRN__SSP1_SCK			0x0191
+#define MX28_PAD_GPMI_ALE__SSP3_D1			0x01a1
+#define MX28_PAD_GPMI_CLE__SSP3_D2			0x01b1
+#define MX28_PAD_GPMI_RESETN__SSP3_CMD			0x01c1
+#define MX28_PAD_LCD_D03__ETM_DA8			0x1031
+#define MX28_PAD_LCD_D04__ETM_DA9			0x1041
+#define MX28_PAD_LCD_D08__ETM_DA3			0x1081
+#define MX28_PAD_LCD_D09__ETM_DA4			0x1091
+#define MX28_PAD_LCD_D20__ENET1_1588_EVENT2_OUT		0x1141
+#define MX28_PAD_LCD_D21__ENET1_1588_EVENT2_IN		0x1151
+#define MX28_PAD_LCD_D22__ENET1_1588_EVENT3_OUT		0x1161
+#define MX28_PAD_LCD_D23__ENET1_1588_EVENT3_IN		0x1171
+#define MX28_PAD_LCD_RD_E__LCD_VSYNC			0x1181
+#define MX28_PAD_LCD_WR_RWN__LCD_HSYNC			0x1191
+#define MX28_PAD_LCD_RS__LCD_DOTCLK			0x11a1
+#define MX28_PAD_LCD_CS__LCD_ENABLE			0x11b1
+#define MX28_PAD_LCD_VSYNC__SAIF1_SDATA0		0x11c1
+#define MX28_PAD_LCD_HSYNC__SAIF1_SDATA1		0x11d1
+#define MX28_PAD_LCD_DOTCLK__SAIF1_MCLK			0x11e1
+#define MX28_PAD_SSP0_DATA4__SSP2_D0			0x2041
+#define MX28_PAD_SSP0_DATA5__SSP2_D3			0x2051
+#define MX28_PAD_SSP0_DATA6__SSP2_CMD			0x2061
+#define MX28_PAD_SSP0_DATA7__SSP2_SCK			0x2071
+#define MX28_PAD_SSP1_SCK__SSP2_D1			0x20c1
+#define MX28_PAD_SSP1_CMD__SSP2_D2			0x20d1
+#define MX28_PAD_SSP1_DATA0__SSP2_D6			0x20e1
+#define MX28_PAD_SSP1_DATA3__SSP2_D7			0x20f1
+#define MX28_PAD_SSP2_SCK__AUART2_RX			0x2101
+#define MX28_PAD_SSP2_MOSI__AUART2_TX			0x2111
+#define MX28_PAD_SSP2_MISO__AUART3_RX			0x2121
+#define MX28_PAD_SSP2_SS0__AUART3_TX			0x2131
+#define MX28_PAD_SSP2_SS1__SSP2_D1			0x2141
+#define MX28_PAD_SSP2_SS2__SSP2_D2			0x2151
+#define MX28_PAD_SSP3_SCK__AUART4_TX			0x2181
+#define MX28_PAD_SSP3_MOSI__AUART4_RX			0x2191
+#define MX28_PAD_SSP3_MISO__AUART4_RTS			0x21a1
+#define MX28_PAD_SSP3_SS0__AUART4_CTS			0x21b1
+#define MX28_PAD_AUART0_RX__I2C0_SCL			0x3001
+#define MX28_PAD_AUART0_TX__I2C0_SDA			0x3011
+#define MX28_PAD_AUART0_CTS__AUART4_RX			0x3021
+#define MX28_PAD_AUART0_RTS__AUART4_TX			0x3031
+#define MX28_PAD_AUART1_RX__SSP2_CARD_DETECT		0x3041
+#define MX28_PAD_AUART1_TX__SSP3_CARD_DETECT		0x3051
+#define MX28_PAD_AUART1_CTS__USB0_OVERCURRENT		0x3061
+#define MX28_PAD_AUART1_RTS__USB0_ID			0x3071
+#define MX28_PAD_AUART2_RX__SSP3_D1			0x3081
+#define MX28_PAD_AUART2_TX__SSP3_D2			0x3091
+#define MX28_PAD_AUART2_CTS__I2C1_SCL			0x30a1
+#define MX28_PAD_AUART2_RTS__I2C1_SDA			0x30b1
+#define MX28_PAD_AUART3_RX__CAN0_TX			0x30c1
+#define MX28_PAD_AUART3_TX__CAN0_RX			0x30d1
+#define MX28_PAD_AUART3_CTS__CAN1_TX			0x30e1
+#define MX28_PAD_AUART3_RTS__CAN1_RX			0x30f1
+#define MX28_PAD_PWM0__I2C1_SCL				0x3101
+#define MX28_PAD_PWM1__I2C1_SDA				0x3111
+#define MX28_PAD_PWM2__USB0_ID				0x3121
+#define MX28_PAD_SAIF0_MCLK__PWM_3			0x3141
+#define MX28_PAD_SAIF0_LRCLK__PWM_4			0x3151
+#define MX28_PAD_SAIF0_BITCLK__PWM_5			0x3161
+#define MX28_PAD_SAIF0_SDATA0__PWM_6			0x3171
+#define MX28_PAD_I2C0_SCL__TIMROT_ROTARYA		0x3181
+#define MX28_PAD_I2C0_SDA__TIMROT_ROTARYB		0x3191
+#define MX28_PAD_SAIF1_SDATA0__PWM_7			0x31a1
+#define MX28_PAD_LCD_RESET__LCD_VSYNC			0x31e1
+#define MX28_PAD_ENET0_MDC__GPMI_CE4N			0x4001
+#define MX28_PAD_ENET0_MDIO__GPMI_CE5N			0x4011
+#define MX28_PAD_ENET0_RX_EN__GPMI_CE6N			0x4021
+#define MX28_PAD_ENET0_RXD0__GPMI_CE7N			0x4031
+#define MX28_PAD_ENET0_RXD1__GPMI_READY4		0x4041
+#define MX28_PAD_ENET0_TX_CLK__HSADC_TRIGGER		0x4051
+#define MX28_PAD_ENET0_TX_EN__GPMI_READY5		0x4061
+#define MX28_PAD_ENET0_TXD0__GPMI_READY6		0x4071
+#define MX28_PAD_ENET0_TXD1__GPMI_READY7		0x4081
+#define MX28_PAD_ENET0_RXD2__ENET1_RXD0			0x4091
+#define MX28_PAD_ENET0_RXD3__ENET1_RXD1			0x40a1
+#define MX28_PAD_ENET0_TXD2__ENET1_TXD0			0x40b1
+#define MX28_PAD_ENET0_TXD3__ENET1_TXD1			0x40c1
+#define MX28_PAD_ENET0_RX_CLK__ENET0_RX_ER		0x40d1
+#define MX28_PAD_ENET0_COL__ENET1_TX_EN			0x40e1
+#define MX28_PAD_ENET0_CRS__ENET1_RX_EN			0x40f1
+#define MX28_PAD_GPMI_CE2N__ENET0_RX_ER			0x0122
+#define MX28_PAD_GPMI_CE3N__SAIF1_MCLK			0x0132
+#define MX28_PAD_GPMI_RDY0__USB0_ID			0x0142
+#define MX28_PAD_GPMI_RDY2__ENET0_TX_ER			0x0162
+#define MX28_PAD_GPMI_RDY3__HSADC_TRIGGER		0x0172
+#define MX28_PAD_GPMI_ALE__SSP3_D4			0x01a2
+#define MX28_PAD_GPMI_CLE__SSP3_D5			0x01b2
+#define MX28_PAD_LCD_D00__ETM_DA0			0x1002
+#define MX28_PAD_LCD_D01__ETM_DA1			0x1012
+#define MX28_PAD_LCD_D02__ETM_DA2			0x1022
+#define MX28_PAD_LCD_D03__ETM_DA3			0x1032
+#define MX28_PAD_LCD_D04__ETM_DA4			0x1042
+#define MX28_PAD_LCD_D05__ETM_DA5			0x1052
+#define MX28_PAD_LCD_D06__ETM_DA6			0x1062
+#define MX28_PAD_LCD_D07__ETM_DA7			0x1072
+#define MX28_PAD_LCD_D08__ETM_DA8			0x1082
+#define MX28_PAD_LCD_D09__ETM_DA9			0x1092
+#define MX28_PAD_LCD_D10__ETM_DA10			0x10a2
+#define MX28_PAD_LCD_D11__ETM_DA11			0x10b2
+#define MX28_PAD_LCD_D12__ETM_DA12			0x10c2
+#define MX28_PAD_LCD_D13__ETM_DA13			0x10d2
+#define MX28_PAD_LCD_D14__ETM_DA14			0x10e2
+#define MX28_PAD_LCD_D15__ETM_DA15			0x10f2
+#define MX28_PAD_LCD_D16__ETM_DA7			0x1102
+#define MX28_PAD_LCD_D17__ETM_DA6			0x1112
+#define MX28_PAD_LCD_D18__ETM_DA5			0x1122
+#define MX28_PAD_LCD_D19__ETM_DA4			0x1132
+#define MX28_PAD_LCD_D20__ETM_DA3			0x1142
+#define MX28_PAD_LCD_D21__ETM_DA2			0x1152
+#define MX28_PAD_LCD_D22__ETM_DA1			0x1162
+#define MX28_PAD_LCD_D23__ETM_DA0			0x1172
+#define MX28_PAD_LCD_RD_E__ETM_TCTL			0x1182
+#define MX28_PAD_LCD_WR_RWN__ETM_TCLK			0x1192
+#define MX28_PAD_LCD_HSYNC__ETM_TCTL			0x11d2
+#define MX28_PAD_LCD_DOTCLK__ETM_TCLK			0x11e2
+#define MX28_PAD_SSP1_SCK__ENET0_1588_EVENT2_OUT	0x20c2
+#define MX28_PAD_SSP1_CMD__ENET0_1588_EVENT2_IN		0x20d2
+#define MX28_PAD_SSP1_DATA0__ENET0_1588_EVENT3_OUT	0x20e2
+#define MX28_PAD_SSP1_DATA3__ENET0_1588_EVENT3_IN	0x20f2
+#define MX28_PAD_SSP2_SCK__SAIF0_SDATA1			0x2102
+#define MX28_PAD_SSP2_MOSI__SAIF0_SDATA2		0x2112
+#define MX28_PAD_SSP2_MISO__SAIF1_SDATA1		0x2122
+#define MX28_PAD_SSP2_SS0__SAIF1_SDATA2			0x2132
+#define MX28_PAD_SSP2_SS1__USB1_OVERCURRENT		0x2142
+#define MX28_PAD_SSP2_SS2__USB0_OVERCURRENT		0x2152
+#define MX28_PAD_SSP3_SCK__ENET1_1588_EVENT0_OUT	0x2182
+#define MX28_PAD_SSP3_MOSI__ENET1_1588_EVENT0_IN	0x2192
+#define MX28_PAD_SSP3_MISO__ENET1_1588_EVENT1_OUT	0x21a2
+#define MX28_PAD_SSP3_SS0__ENET1_1588_EVENT1_IN		0x21b2
+#define MX28_PAD_AUART0_RX__DUART_CTS			0x3002
+#define MX28_PAD_AUART0_TX__DUART_RTS			0x3012
+#define MX28_PAD_AUART0_CTS__DUART_RX			0x3022
+#define MX28_PAD_AUART0_RTS__DUART_TX			0x3032
+#define MX28_PAD_AUART1_RX__PWM_0			0x3042
+#define MX28_PAD_AUART1_TX__PWM_1			0x3052
+#define MX28_PAD_AUART1_CTS__TIMROT_ROTARYA		0x3062
+#define MX28_PAD_AUART1_RTS__TIMROT_ROTARYB		0x3072
+#define MX28_PAD_AUART2_RX__SSP3_D4			0x3082
+#define MX28_PAD_AUART2_TX__SSP3_D5			0x3092
+#define MX28_PAD_AUART2_CTS__SAIF1_BITCLK		0x30a2
+#define MX28_PAD_AUART2_RTS__SAIF1_LRCLK		0x30b2
+#define MX28_PAD_AUART3_RX__ENET0_1588_EVENT0_OUT	0x30c2
+#define MX28_PAD_AUART3_TX__ENET0_1588_EVENT0_IN	0x30d2
+#define MX28_PAD_AUART3_CTS__ENET0_1588_EVENT1_OUT	0x30e2
+#define MX28_PAD_AUART3_RTS__ENET0_1588_EVENT1_IN	0x30f2
+#define MX28_PAD_PWM0__DUART_RX				0x3102
+#define MX28_PAD_PWM1__DUART_TX				0x3112
+#define MX28_PAD_PWM2__USB1_OVERCURRENT			0x3122
+#define MX28_PAD_SAIF0_MCLK__AUART4_CTS			0x3142
+#define MX28_PAD_SAIF0_LRCLK__AUART4_RTS		0x3152
+#define MX28_PAD_SAIF0_BITCLK__AUART4_RX		0x3162
+#define MX28_PAD_SAIF0_SDATA0__AUART4_TX		0x3172
+#define MX28_PAD_I2C0_SCL__DUART_RX			0x3182
+#define MX28_PAD_I2C0_SDA__DUART_TX			0x3192
+#define MX28_PAD_SAIF1_SDATA0__SAIF0_SDATA1		0x31a2
+#define MX28_PAD_SPDIF__ENET1_RX_ER			0x31b2
+#define MX28_PAD_ENET0_MDC__SAIF0_SDATA1		0x4002
+#define MX28_PAD_ENET0_MDIO__SAIF0_SDATA2		0x4012
+#define MX28_PAD_ENET0_RX_EN__SAIF1_SDATA1		0x4022
+#define MX28_PAD_ENET0_RXD0__SAIF1_SDATA2		0x4032
+#define MX28_PAD_ENET0_TX_CLK__ENET0_1588_EVENT2_OUT	0x4052
+#define MX28_PAD_ENET0_RXD2__ENET0_1588_EVENT0_OUT	0x4092
+#define MX28_PAD_ENET0_RXD3__ENET0_1588_EVENT0_IN	0x40a2
+#define MX28_PAD_ENET0_TXD2__ENET0_1588_EVENT1_OUT	0x40b2
+#define MX28_PAD_ENET0_TXD3__ENET0_1588_EVENT1_IN	0x40c2
+#define MX28_PAD_ENET0_RX_CLK__ENET0_1588_EVENT2_IN	0x40d2
+#define MX28_PAD_ENET0_COL__ENET0_1588_EVENT3_OUT	0x40e2
+#define MX28_PAD_ENET0_CRS__ENET0_1588_EVENT3_IN	0x40f2
+#define MX28_PAD_GPMI_D00__GPIO_0_0			0x0003
+#define MX28_PAD_GPMI_D01__GPIO_0_1			0x0013
+#define MX28_PAD_GPMI_D02__GPIO_0_2			0x0023
+#define MX28_PAD_GPMI_D03__GPIO_0_3			0x0033
+#define MX28_PAD_GPMI_D04__GPIO_0_4			0x0043
+#define MX28_PAD_GPMI_D05__GPIO_0_5			0x0053
+#define MX28_PAD_GPMI_D06__GPIO_0_6			0x0063
+#define MX28_PAD_GPMI_D07__GPIO_0_7			0x0073
+#define MX28_PAD_GPMI_CE0N__GPIO_0_16			0x0103
+#define MX28_PAD_GPMI_CE1N__GPIO_0_17			0x0113
+#define MX28_PAD_GPMI_CE2N__GPIO_0_18			0x0123
+#define MX28_PAD_GPMI_CE3N__GPIO_0_19			0x0133
+#define MX28_PAD_GPMI_RDY0__GPIO_0_20			0x0143
+#define MX28_PAD_GPMI_RDY1__GPIO_0_21			0x0153
+#define MX28_PAD_GPMI_RDY2__GPIO_0_22			0x0163
+#define MX28_PAD_GPMI_RDY3__GPIO_0_23			0x0173
+#define MX28_PAD_GPMI_RDN__GPIO_0_24			0x0183
+#define MX28_PAD_GPMI_WRN__GPIO_0_25			0x0193
+#define MX28_PAD_GPMI_ALE__GPIO_0_26			0x01a3
+#define MX28_PAD_GPMI_CLE__GPIO_0_27			0x01b3
+#define MX28_PAD_GPMI_RESETN__GPIO_0_28			0x01c3
+#define MX28_PAD_LCD_D00__GPIO_1_0			0x1003
+#define MX28_PAD_LCD_D01__GPIO_1_1			0x1013
+#define MX28_PAD_LCD_D02__GPIO_1_2			0x1023
+#define MX28_PAD_LCD_D03__GPIO_1_3			0x1033
+#define MX28_PAD_LCD_D04__GPIO_1_4			0x1043
+#define MX28_PAD_LCD_D05__GPIO_1_5			0x1053
+#define MX28_PAD_LCD_D06__GPIO_1_6			0x1063
+#define MX28_PAD_LCD_D07__GPIO_1_7			0x1073
+#define MX28_PAD_LCD_D08__GPIO_1_8			0x1083
+#define MX28_PAD_LCD_D09__GPIO_1_9			0x1093
+#define MX28_PAD_LCD_D10__GPIO_1_10			0x10a3
+#define MX28_PAD_LCD_D11__GPIO_1_11			0x10b3
+#define MX28_PAD_LCD_D12__GPIO_1_12			0x10c3
+#define MX28_PAD_LCD_D13__GPIO_1_13			0x10d3
+#define MX28_PAD_LCD_D14__GPIO_1_14			0x10e3
+#define MX28_PAD_LCD_D15__GPIO_1_15			0x10f3
+#define MX28_PAD_LCD_D16__GPIO_1_16			0x1103
+#define MX28_PAD_LCD_D17__GPIO_1_17			0x1113
+#define MX28_PAD_LCD_D18__GPIO_1_18			0x1123
+#define MX28_PAD_LCD_D19__GPIO_1_19			0x1133
+#define MX28_PAD_LCD_D20__GPIO_1_20			0x1143
+#define MX28_PAD_LCD_D21__GPIO_1_21			0x1153
+#define MX28_PAD_LCD_D22__GPIO_1_22			0x1163
+#define MX28_PAD_LCD_D23__GPIO_1_23			0x1173
+#define MX28_PAD_LCD_RD_E__GPIO_1_24			0x1183
+#define MX28_PAD_LCD_WR_RWN__GPIO_1_25			0x1193
+#define MX28_PAD_LCD_RS__GPIO_1_26			0x11a3
+#define MX28_PAD_LCD_CS__GPIO_1_27			0x11b3
+#define MX28_PAD_LCD_VSYNC__GPIO_1_28			0x11c3
+#define MX28_PAD_LCD_HSYNC__GPIO_1_29			0x11d3
+#define MX28_PAD_LCD_DOTCLK__GPIO_1_30			0x11e3
+#define MX28_PAD_LCD_ENABLE__GPIO_1_31			0x11f3
+#define MX28_PAD_SSP0_DATA0__GPIO_2_0			0x2003
+#define MX28_PAD_SSP0_DATA1__GPIO_2_1			0x2013
+#define MX28_PAD_SSP0_DATA2__GPIO_2_2			0x2023
+#define MX28_PAD_SSP0_DATA3__GPIO_2_3			0x2033
+#define MX28_PAD_SSP0_DATA4__GPIO_2_4			0x2043
+#define MX28_PAD_SSP0_DATA5__GPIO_2_5			0x2053
+#define MX28_PAD_SSP0_DATA6__GPIO_2_6			0x2063
+#define MX28_PAD_SSP0_DATA7__GPIO_2_7			0x2073
+#define MX28_PAD_SSP0_CMD__GPIO_2_8			0x2083
+#define MX28_PAD_SSP0_DETECT__GPIO_2_9			0x2093
+#define MX28_PAD_SSP0_SCK__GPIO_2_10			0x20a3
+#define MX28_PAD_SSP1_SCK__GPIO_2_12			0x20c3
+#define MX28_PAD_SSP1_CMD__GPIO_2_13			0x20d3
+#define MX28_PAD_SSP1_DATA0__GPIO_2_14			0x20e3
+#define MX28_PAD_SSP1_DATA3__GPIO_2_15			0x20f3
+#define MX28_PAD_SSP2_SCK__GPIO_2_16			0x2103
+#define MX28_PAD_SSP2_MOSI__GPIO_2_17			0x2113
+#define MX28_PAD_SSP2_MISO__GPIO_2_18			0x2123
+#define MX28_PAD_SSP2_SS0__GPIO_2_19			0x2133
+#define MX28_PAD_SSP2_SS1__GPIO_2_20			0x2143
+#define MX28_PAD_SSP2_SS2__GPIO_2_21			0x2153
+#define MX28_PAD_SSP3_SCK__GPIO_2_24			0x2183
+#define MX28_PAD_SSP3_MOSI__GPIO_2_25			0x2193
+#define MX28_PAD_SSP3_MISO__GPIO_2_26			0x21a3
+#define MX28_PAD_SSP3_SS0__GPIO_2_27			0x21b3
+#define MX28_PAD_AUART0_RX__GPIO_3_0			0x3003
+#define MX28_PAD_AUART0_TX__GPIO_3_1			0x3013
+#define MX28_PAD_AUART0_CTS__GPIO_3_2			0x3023
+#define MX28_PAD_AUART0_RTS__GPIO_3_3			0x3033
+#define MX28_PAD_AUART1_RX__GPIO_3_4			0x3043
+#define MX28_PAD_AUART1_TX__GPIO_3_5			0x3053
+#define MX28_PAD_AUART1_CTS__GPIO_3_6			0x3063
+#define MX28_PAD_AUART1_RTS__GPIO_3_7			0x3073
+#define MX28_PAD_AUART2_RX__GPIO_3_8			0x3083
+#define MX28_PAD_AUART2_TX__GPIO_3_9			0x3093
+#define MX28_PAD_AUART2_CTS__GPIO_3_10			0x30a3
+#define MX28_PAD_AUART2_RTS__GPIO_3_11			0x30b3
+#define MX28_PAD_AUART3_RX__GPIO_3_12			0x30c3
+#define MX28_PAD_AUART3_TX__GPIO_3_13			0x30d3
+#define MX28_PAD_AUART3_CTS__GPIO_3_14			0x30e3
+#define MX28_PAD_AUART3_RTS__GPIO_3_15			0x30f3
+#define MX28_PAD_PWM0__GPIO_3_16			0x3103
+#define MX28_PAD_PWM1__GPIO_3_17			0x3113
+#define MX28_PAD_PWM2__GPIO_3_18			0x3123
+#define MX28_PAD_SAIF0_MCLK__GPIO_3_20			0x3143
+#define MX28_PAD_SAIF0_LRCLK__GPIO_3_21			0x3153
+#define MX28_PAD_SAIF0_BITCLK__GPIO_3_22		0x3163
+#define MX28_PAD_SAIF0_SDATA0__GPIO_3_23		0x3173
+#define MX28_PAD_I2C0_SCL__GPIO_3_24			0x3183
+#define MX28_PAD_I2C0_SDA__GPIO_3_25			0x3193
+#define MX28_PAD_SAIF1_SDATA0__GPIO_3_26		0x31a3
+#define MX28_PAD_SPDIF__GPIO_3_27			0x31b3
+#define MX28_PAD_PWM3__GPIO_3_28			0x31c3
+#define MX28_PAD_PWM4__GPIO_3_29			0x31d3
+#define MX28_PAD_LCD_RESET__GPIO_3_30			0x31e3
+#define MX28_PAD_ENET0_MDC__GPIO_4_0			0x4003
+#define MX28_PAD_ENET0_MDIO__GPIO_4_1			0x4013
+#define MX28_PAD_ENET0_RX_EN__GPIO_4_2			0x4023
+#define MX28_PAD_ENET0_RXD0__GPIO_4_3			0x4033
+#define MX28_PAD_ENET0_RXD1__GPIO_4_4			0x4043
+#define MX28_PAD_ENET0_TX_CLK__GPIO_4_5			0x4053
+#define MX28_PAD_ENET0_TX_EN__GPIO_4_6			0x4063
+#define MX28_PAD_ENET0_TXD0__GPIO_4_7			0x4073
+#define MX28_PAD_ENET0_TXD1__GPIO_4_8			0x4083
+#define MX28_PAD_ENET0_RXD2__GPIO_4_9			0x4093
+#define MX28_PAD_ENET0_RXD3__GPIO_4_10			0x40a3
+#define MX28_PAD_ENET0_TXD2__GPIO_4_11			0x40b3
+#define MX28_PAD_ENET0_TXD3__GPIO_4_12			0x40c3
+#define MX28_PAD_ENET0_RX_CLK__GPIO_4_13		0x40d3
+#define MX28_PAD_ENET0_COL__GPIO_4_14			0x40e3
+#define MX28_PAD_ENET0_CRS__GPIO_4_15			0x40f3
+#define MX28_PAD_ENET_CLK__GPIO_4_16			0x4103
+#define MX28_PAD_JTAG_RTCK__GPIO_4_20			0x4143
+
+#endif /* __DT_BINDINGS_MX28_PINCTRL_H__ */

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

@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ *
+ * SPDX-License-Identifier:     GPL-2.0+ or X11
+ */
+#include "imx28.dtsi"
+
+&gpio0 {
+	gpio-ranges = <&pinctrl 0 0 29>;
+};
+
+&gpio1 {
+	gpio-ranges = <&pinctrl 0 29 32>;
+};
+
+&gpio2 {
+	gpio-ranges = <&pinctrl 0 61 28>;
+};
+
+&gpio3 {
+	gpio-ranges = <&pinctrl 0 89 31>;
+};
+
+&gpio4 {
+	gpio-ranges = <&pinctrl 0 120 21>;
+};

+ 1330 - 0
arch/arm/dts/imx28.dtsi

@@ -0,0 +1,1330 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright 2012 Freescale Semiconductor, Inc.
+
+#include <dt-bindings/gpio/gpio.h>
+#include "imx28-pinfunc.h"
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	interrupt-parent = <&icoll>;
+	/*
+	 * The decompressor and also some bootloaders rely on a
+	 * pre-existing /chosen node to be available to insert the
+	 * command line and merge other ATAGS info.
+	 */
+	chosen {};
+
+	aliases {
+		ethernet0 = &mac0;
+		ethernet1 = &mac1;
+		gpio0 = &gpio0;
+		gpio1 = &gpio1;
+		gpio2 = &gpio2;
+		gpio3 = &gpio3;
+		gpio4 = &gpio4;
+		saif0 = &saif0;
+		saif1 = &saif1;
+		serial0 = &auart0;
+		serial1 = &auart1;
+		serial2 = &auart2;
+		serial3 = &auart3;
+		serial4 = &auart4;
+		spi0 = &ssp1;
+		spi1 = &ssp2;
+		usbphy0 = &usbphy0;
+		usbphy1 = &usbphy1;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			compatible = "arm,arm926ej-s";
+			device_type = "cpu";
+			reg = <0>;
+		};
+	};
+
+	apb@80000000 {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x80000000 0x80000>;
+		ranges;
+
+		apbh@80000000 {
+			compatible = "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x80000000 0x3c900>;
+			ranges;
+
+			icoll: interrupt-controller@80000000 {
+				compatible = "fsl,imx28-icoll", "fsl,icoll";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+				reg = <0x80000000 0x2000>;
+			};
+
+			hsadc: hsadc@80002000 {
+				reg = <0x80002000 0x2000>;
+				interrupts = <13>;
+				dmas = <&dma_apbh 12>;
+				dma-names = "rx";
+				status = "disabled";
+			};
+
+			dma_apbh: dma-apbh@80004000 {
+				compatible = "fsl,imx28-dma-apbh";
+				reg = <0x80004000 0x2000>;
+				interrupts = <82 83 84 85
+					      88 88 88 88
+					      88 88 88 88
+					      87 86 0 0>;
+				interrupt-names = "ssp0", "ssp1", "ssp2", "ssp3",
+						  "gpmi0", "gmpi1", "gpmi2", "gmpi3",
+						  "gpmi4", "gmpi5", "gpmi6", "gmpi7",
+						  "hsadc", "lcdif", "empty", "empty";
+				#dma-cells = <1>;
+				dma-channels = <16>;
+				clocks = <&clks 25>;
+			};
+
+			perfmon: perfmon@80006000 {
+				reg = <0x80006000 0x800>;
+				interrupts = <27>;
+				status = "disabled";
+			};
+
+			gpmi: gpmi-nand@8000c000 {
+				compatible = "fsl,imx28-gpmi-nand";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				reg = <0x8000c000 0x2000>, <0x8000a000 0x2000>;
+				reg-names = "gpmi-nand", "bch";
+				interrupts = <41>;
+				interrupt-names = "bch";
+				clocks = <&clks 50>;
+				clock-names = "gpmi_io";
+				dmas = <&dma_apbh 4>;
+				dma-names = "rx-tx";
+				status = "disabled";
+			};
+
+			ssp0: spi@80010000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x80010000 0x2000>;
+				interrupts = <96>;
+				clocks = <&clks 46>;
+				dmas = <&dma_apbh 0>;
+				dma-names = "rx-tx";
+				status = "disabled";
+			};
+
+			ssp1: spi@80012000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x80012000 0x2000>;
+				interrupts = <97>;
+				clocks = <&clks 47>;
+				dmas = <&dma_apbh 1>;
+				dma-names = "rx-tx";
+				status = "disabled";
+			};
+
+			ssp2: spi@80014000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x80014000 0x2000>;
+				interrupts = <98>;
+				clocks = <&clks 48>;
+				dmas = <&dma_apbh 2>;
+				dma-names = "rx-tx";
+				status = "disabled";
+			};
+
+			ssp3: spi@80016000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x80016000 0x2000>;
+				interrupts = <99>;
+				clocks = <&clks 49>;
+				dmas = <&dma_apbh 3>;
+				dma-names = "rx-tx";
+				status = "disabled";
+			};
+
+			pinctrl: pinctrl@80018000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx28-pinctrl", "simple-bus";
+				reg = <0x80018000 0x2000>;
+
+				gpio0: gpio@0 {
+					compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+					reg = <0>;
+					interrupts = <127>;
+					gpio-controller;
+					#gpio-cells = <2>;
+					interrupt-controller;
+					#interrupt-cells = <2>;
+				};
+
+				gpio1: gpio@1 {
+					compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+					reg = <1>;
+					interrupts = <126>;
+					gpio-controller;
+					#gpio-cells = <2>;
+					interrupt-controller;
+					#interrupt-cells = <2>;
+				};
+
+				gpio2: gpio@2 {
+					compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+					reg = <2>;
+					interrupts = <125>;
+					gpio-controller;
+					#gpio-cells = <2>;
+					interrupt-controller;
+					#interrupt-cells = <2>;
+				};
+
+				gpio3: gpio@3 {
+					compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+					reg = <3>;
+					interrupts = <124>;
+					gpio-controller;
+					#gpio-cells = <2>;
+					interrupt-controller;
+					#interrupt-cells = <2>;
+				};
+
+				gpio4: gpio@4 {
+					compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+					reg = <4>;
+					interrupts = <123>;
+					gpio-controller;
+					#gpio-cells = <2>;
+					interrupt-controller;
+					#interrupt-cells = <2>;
+				};
+
+				duart_pins_a: duart@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_PWM0__DUART_RX
+						MX28_PAD_PWM1__DUART_TX
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				duart_pins_b: duart@1 {
+					reg = <1>;
+					fsl,pinmux-ids = <
+						MX28_PAD_AUART0_CTS__DUART_RX
+						MX28_PAD_AUART0_RTS__DUART_TX
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				duart_4pins_a: duart-4pins@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_AUART0_CTS__DUART_RX
+						MX28_PAD_AUART0_RTS__DUART_TX
+						MX28_PAD_AUART0_RX__DUART_CTS
+						MX28_PAD_AUART0_TX__DUART_RTS
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				gpmi_pins_a: gpmi-nand@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_GPMI_D00__GPMI_D0
+						MX28_PAD_GPMI_D01__GPMI_D1
+						MX28_PAD_GPMI_D02__GPMI_D2
+						MX28_PAD_GPMI_D03__GPMI_D3
+						MX28_PAD_GPMI_D04__GPMI_D4
+						MX28_PAD_GPMI_D05__GPMI_D5
+						MX28_PAD_GPMI_D06__GPMI_D6
+						MX28_PAD_GPMI_D07__GPMI_D7
+						MX28_PAD_GPMI_CE0N__GPMI_CE0N
+						MX28_PAD_GPMI_RDY0__GPMI_READY0
+						MX28_PAD_GPMI_RDN__GPMI_RDN
+						MX28_PAD_GPMI_WRN__GPMI_WRN
+						MX28_PAD_GPMI_ALE__GPMI_ALE
+						MX28_PAD_GPMI_CLE__GPMI_CLE
+						MX28_PAD_GPMI_RESETN__GPMI_RESETN
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				gpmi_status_cfg: gpmi-status-cfg@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_GPMI_RDN__GPMI_RDN
+						MX28_PAD_GPMI_WRN__GPMI_WRN
+						MX28_PAD_GPMI_RESETN__GPMI_RESETN
+					>;
+					fsl,drive-strength = <MXS_DRIVE_12mA>;
+				};
+
+				auart0_pins_a: auart0@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_AUART0_RX__AUART0_RX
+						MX28_PAD_AUART0_TX__AUART0_TX
+						MX28_PAD_AUART0_CTS__AUART0_CTS
+						MX28_PAD_AUART0_RTS__AUART0_RTS
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				auart0_2pins_a: auart0-2pins@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_AUART0_RX__AUART0_RX
+						MX28_PAD_AUART0_TX__AUART0_TX
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				auart1_pins_a: auart1@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_AUART1_RX__AUART1_RX
+						MX28_PAD_AUART1_TX__AUART1_TX
+						MX28_PAD_AUART1_CTS__AUART1_CTS
+						MX28_PAD_AUART1_RTS__AUART1_RTS
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				auart1_2pins_a: auart1-2pins@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_AUART1_RX__AUART1_RX
+						MX28_PAD_AUART1_TX__AUART1_TX
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				auart2_2pins_a: auart2-2pins@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SSP2_SCK__AUART2_RX
+						MX28_PAD_SSP2_MOSI__AUART2_TX
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				auart2_2pins_b: auart2-2pins@1 {
+					reg = <1>;
+					fsl,pinmux-ids = <
+						MX28_PAD_AUART2_RX__AUART2_RX
+						MX28_PAD_AUART2_TX__AUART2_TX
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				auart2_pins_a: auart2-pins@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_AUART2_RX__AUART2_RX
+						MX28_PAD_AUART2_TX__AUART2_TX
+						MX28_PAD_AUART2_CTS__AUART2_CTS
+						MX28_PAD_AUART2_RTS__AUART2_RTS
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				auart3_pins_a: auart3@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_AUART3_RX__AUART3_RX
+						MX28_PAD_AUART3_TX__AUART3_TX
+						MX28_PAD_AUART3_CTS__AUART3_CTS
+						MX28_PAD_AUART3_RTS__AUART3_RTS
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				auart3_2pins_a: auart3-2pins@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SSP2_MISO__AUART3_RX
+						MX28_PAD_SSP2_SS0__AUART3_TX
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				auart3_2pins_b: auart3-2pins@1 {
+					reg = <1>;
+					fsl,pinmux-ids = <
+						MX28_PAD_AUART3_RX__AUART3_RX
+						MX28_PAD_AUART3_TX__AUART3_TX
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				auart4_2pins_a: auart4@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SSP3_SCK__AUART4_TX
+						MX28_PAD_SSP3_MOSI__AUART4_RX
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				auart4_2pins_b: auart4@1 {
+					reg = <1>;
+					fsl,pinmux-ids = <
+						MX28_PAD_AUART0_CTS__AUART4_RX
+						MX28_PAD_AUART0_RTS__AUART4_TX
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				mac0_pins_a: mac0@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_ENET0_MDC__ENET0_MDC
+						MX28_PAD_ENET0_MDIO__ENET0_MDIO
+						MX28_PAD_ENET0_RX_EN__ENET0_RX_EN
+						MX28_PAD_ENET0_RXD0__ENET0_RXD0
+						MX28_PAD_ENET0_RXD1__ENET0_RXD1
+						MX28_PAD_ENET0_TX_EN__ENET0_TX_EN
+						MX28_PAD_ENET0_TXD0__ENET0_TXD0
+						MX28_PAD_ENET0_TXD1__ENET0_TXD1
+						MX28_PAD_ENET_CLK__CLKCTRL_ENET
+					>;
+					fsl,drive-strength = <MXS_DRIVE_8mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_ENABLE>;
+				};
+
+				mac0_pins_b: mac0@1 {
+					reg = <1>;
+					fsl,pinmux-ids = <
+						MX28_PAD_ENET0_MDC__ENET0_MDC
+						MX28_PAD_ENET0_MDIO__ENET0_MDIO
+						MX28_PAD_ENET0_RX_EN__ENET0_RX_EN
+						MX28_PAD_ENET0_RXD0__ENET0_RXD0
+						MX28_PAD_ENET0_RXD1__ENET0_RXD1
+						MX28_PAD_ENET0_RXD2__ENET0_RXD2
+						MX28_PAD_ENET0_RXD3__ENET0_RXD3
+						MX28_PAD_ENET0_TX_EN__ENET0_TX_EN
+						MX28_PAD_ENET0_TXD0__ENET0_TXD0
+						MX28_PAD_ENET0_TXD1__ENET0_TXD1
+						MX28_PAD_ENET0_TXD2__ENET0_TXD2
+						MX28_PAD_ENET0_TXD3__ENET0_TXD3
+						MX28_PAD_ENET_CLK__CLKCTRL_ENET
+						MX28_PAD_ENET0_COL__ENET0_COL
+						MX28_PAD_ENET0_CRS__ENET0_CRS
+						MX28_PAD_ENET0_TX_CLK__ENET0_TX_CLK
+						MX28_PAD_ENET0_RX_CLK__ENET0_RX_CLK
+						>;
+					fsl,drive-strength = <MXS_DRIVE_8mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_ENABLE>;
+				};
+
+				mac1_pins_a: mac1@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_ENET0_CRS__ENET1_RX_EN
+						MX28_PAD_ENET0_RXD2__ENET1_RXD0
+						MX28_PAD_ENET0_RXD3__ENET1_RXD1
+						MX28_PAD_ENET0_COL__ENET1_TX_EN
+						MX28_PAD_ENET0_TXD2__ENET1_TXD0
+						MX28_PAD_ENET0_TXD3__ENET1_TXD1
+					>;
+					fsl,drive-strength = <MXS_DRIVE_8mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_ENABLE>;
+				};
+
+				mmc0_8bit_pins_a: mmc0-8bit@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SSP0_DATA0__SSP0_D0
+						MX28_PAD_SSP0_DATA1__SSP0_D1
+						MX28_PAD_SSP0_DATA2__SSP0_D2
+						MX28_PAD_SSP0_DATA3__SSP0_D3
+						MX28_PAD_SSP0_DATA4__SSP0_D4
+						MX28_PAD_SSP0_DATA5__SSP0_D5
+						MX28_PAD_SSP0_DATA6__SSP0_D6
+						MX28_PAD_SSP0_DATA7__SSP0_D7
+						MX28_PAD_SSP0_CMD__SSP0_CMD
+						MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT
+						MX28_PAD_SSP0_SCK__SSP0_SCK
+					>;
+					fsl,drive-strength = <MXS_DRIVE_8mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_ENABLE>;
+				};
+
+				mmc0_4bit_pins_a: mmc0-4bit@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SSP0_DATA0__SSP0_D0
+						MX28_PAD_SSP0_DATA1__SSP0_D1
+						MX28_PAD_SSP0_DATA2__SSP0_D2
+						MX28_PAD_SSP0_DATA3__SSP0_D3
+						MX28_PAD_SSP0_CMD__SSP0_CMD
+						MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT
+						MX28_PAD_SSP0_SCK__SSP0_SCK
+					>;
+					fsl,drive-strength = <MXS_DRIVE_8mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_ENABLE>;
+				};
+
+				mmc0_cd_cfg: mmc0-cd-cfg@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT
+					>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				mmc0_sck_cfg: mmc0-sck-cfg@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SSP0_SCK__SSP0_SCK
+					>;
+					fsl,drive-strength = <MXS_DRIVE_12mA>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				mmc1_4bit_pins_a: mmc1-4bit@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_GPMI_D00__SSP1_D0
+						MX28_PAD_GPMI_D01__SSP1_D1
+						MX28_PAD_GPMI_D02__SSP1_D2
+						MX28_PAD_GPMI_D03__SSP1_D3
+						MX28_PAD_GPMI_RDY1__SSP1_CMD
+						MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT
+						MX28_PAD_GPMI_WRN__SSP1_SCK
+					>;
+					fsl,drive-strength = <MXS_DRIVE_8mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_ENABLE>;
+				};
+
+				mmc1_cd_cfg: mmc1-cd-cfg@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT
+					>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				mmc1_sck_cfg: mmc1-sck-cfg@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_GPMI_WRN__SSP1_SCK
+					>;
+					fsl,drive-strength = <MXS_DRIVE_12mA>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+
+				mmc2_4bit_pins_a: mmc2-4bit@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SSP0_DATA4__SSP2_D0
+						MX28_PAD_SSP1_SCK__SSP2_D1
+						MX28_PAD_SSP1_CMD__SSP2_D2
+						MX28_PAD_SSP0_DATA5__SSP2_D3
+						MX28_PAD_SSP0_DATA6__SSP2_CMD
+						MX28_PAD_AUART1_RX__SSP2_CARD_DETECT
+						MX28_PAD_SSP0_DATA7__SSP2_SCK
+					>;
+					fsl,drive-strength = <MXS_DRIVE_8mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_ENABLE>;
+				};
+
+				mmc2_4bit_pins_b: mmc2-4bit@1 {
+					reg = <1>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SSP2_SCK__SSP2_SCK
+						MX28_PAD_SSP2_MOSI__SSP2_CMD
+						MX28_PAD_SSP2_MISO__SSP2_D0
+						MX28_PAD_SSP2_SS0__SSP2_D3
+						MX28_PAD_SSP2_SS1__SSP2_D1
+						MX28_PAD_SSP2_SS2__SSP2_D2
+						MX28_PAD_AUART1_RX__SSP2_CARD_DETECT
+					>;
+					fsl,drive-strength = <MXS_DRIVE_8mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_ENABLE>;
+				};
+
+				mmc2_cd_cfg: mmc2-cd-cfg@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_AUART1_RX__SSP2_CARD_DETECT
+					>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				mmc2_sck_cfg_a: mmc2-sck-cfg@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SSP0_DATA7__SSP2_SCK
+					>;
+					fsl,drive-strength = <MXS_DRIVE_12mA>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				mmc2_sck_cfg_b: mmc2-sck-cfg@1 {
+					reg = <1>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SSP2_SCK__SSP2_SCK
+					>;
+					fsl,drive-strength = <MXS_DRIVE_12mA>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				i2c0_pins_a: i2c0@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_I2C0_SCL__I2C0_SCL
+						MX28_PAD_I2C0_SDA__I2C0_SDA
+					>;
+					fsl,drive-strength = <MXS_DRIVE_8mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_ENABLE>;
+				};
+
+				i2c0_pins_b: i2c0@1 {
+					reg = <1>;
+					fsl,pinmux-ids = <
+						MX28_PAD_AUART0_RX__I2C0_SCL
+						MX28_PAD_AUART0_TX__I2C0_SDA
+					>;
+					fsl,drive-strength = <MXS_DRIVE_8mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_ENABLE>;
+				};
+
+				i2c1_pins_a: i2c1@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_PWM0__I2C1_SCL
+						MX28_PAD_PWM1__I2C1_SDA
+					>;
+					fsl,drive-strength = <MXS_DRIVE_8mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_ENABLE>;
+				};
+
+				i2c1_pins_b: i2c1@1 {
+					reg = <1>;
+					fsl,pinmux-ids = <
+						MX28_PAD_AUART2_CTS__I2C1_SCL
+						MX28_PAD_AUART2_RTS__I2C1_SDA
+					>;
+					fsl,drive-strength = <MXS_DRIVE_8mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_ENABLE>;
+				};
+
+				saif0_pins_a: saif0@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SAIF0_MCLK__SAIF0_MCLK
+						MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK
+						MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK
+						MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0
+					>;
+					fsl,drive-strength = <MXS_DRIVE_12mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_ENABLE>;
+				};
+
+				saif0_pins_b: saif0@1 {
+					reg = <1>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK
+						MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK
+						MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0
+					>;
+					fsl,drive-strength = <MXS_DRIVE_12mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_ENABLE>;
+				};
+
+				saif1_pins_a: saif1@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0
+					>;
+					fsl,drive-strength = <MXS_DRIVE_12mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_ENABLE>;
+				};
+
+				pwm0_pins_a: pwm0@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_PWM0__PWM_0
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				pwm2_pins_a: pwm2@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_PWM2__PWM_2
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				pwm3_pins_a: pwm3@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_PWM3__PWM_3
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				pwm3_pins_b: pwm3@1 {
+					reg = <1>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SAIF0_MCLK__PWM_3
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				pwm4_pins_a: pwm4@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_PWM4__PWM_4
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				lcdif_24bit_pins_a: lcdif-24bit@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_LCD_D00__LCD_D0
+						MX28_PAD_LCD_D01__LCD_D1
+						MX28_PAD_LCD_D02__LCD_D2
+						MX28_PAD_LCD_D03__LCD_D3
+						MX28_PAD_LCD_D04__LCD_D4
+						MX28_PAD_LCD_D05__LCD_D5
+						MX28_PAD_LCD_D06__LCD_D6
+						MX28_PAD_LCD_D07__LCD_D7
+						MX28_PAD_LCD_D08__LCD_D8
+						MX28_PAD_LCD_D09__LCD_D9
+						MX28_PAD_LCD_D10__LCD_D10
+						MX28_PAD_LCD_D11__LCD_D11
+						MX28_PAD_LCD_D12__LCD_D12
+						MX28_PAD_LCD_D13__LCD_D13
+						MX28_PAD_LCD_D14__LCD_D14
+						MX28_PAD_LCD_D15__LCD_D15
+						MX28_PAD_LCD_D16__LCD_D16
+						MX28_PAD_LCD_D17__LCD_D17
+						MX28_PAD_LCD_D18__LCD_D18
+						MX28_PAD_LCD_D19__LCD_D19
+						MX28_PAD_LCD_D20__LCD_D20
+						MX28_PAD_LCD_D21__LCD_D21
+						MX28_PAD_LCD_D22__LCD_D22
+						MX28_PAD_LCD_D23__LCD_D23
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				lcdif_18bit_pins_a: lcdif-18bit@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_LCD_D00__LCD_D0
+						MX28_PAD_LCD_D01__LCD_D1
+						MX28_PAD_LCD_D02__LCD_D2
+						MX28_PAD_LCD_D03__LCD_D3
+						MX28_PAD_LCD_D04__LCD_D4
+						MX28_PAD_LCD_D05__LCD_D5
+						MX28_PAD_LCD_D06__LCD_D6
+						MX28_PAD_LCD_D07__LCD_D7
+						MX28_PAD_LCD_D08__LCD_D8
+						MX28_PAD_LCD_D09__LCD_D9
+						MX28_PAD_LCD_D10__LCD_D10
+						MX28_PAD_LCD_D11__LCD_D11
+						MX28_PAD_LCD_D12__LCD_D12
+						MX28_PAD_LCD_D13__LCD_D13
+						MX28_PAD_LCD_D14__LCD_D14
+						MX28_PAD_LCD_D15__LCD_D15
+						MX28_PAD_LCD_D16__LCD_D16
+						MX28_PAD_LCD_D17__LCD_D17
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				lcdif_16bit_pins_a: lcdif-16bit@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_LCD_D00__LCD_D0
+						MX28_PAD_LCD_D01__LCD_D1
+						MX28_PAD_LCD_D02__LCD_D2
+						MX28_PAD_LCD_D03__LCD_D3
+						MX28_PAD_LCD_D04__LCD_D4
+						MX28_PAD_LCD_D05__LCD_D5
+						MX28_PAD_LCD_D06__LCD_D6
+						MX28_PAD_LCD_D07__LCD_D7
+						MX28_PAD_LCD_D08__LCD_D8
+						MX28_PAD_LCD_D09__LCD_D9
+						MX28_PAD_LCD_D10__LCD_D10
+						MX28_PAD_LCD_D11__LCD_D11
+						MX28_PAD_LCD_D12__LCD_D12
+						MX28_PAD_LCD_D13__LCD_D13
+						MX28_PAD_LCD_D14__LCD_D14
+						MX28_PAD_LCD_D15__LCD_D15
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				lcdif_sync_pins_a: lcdif-sync@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_LCD_RS__LCD_DOTCLK
+						MX28_PAD_LCD_CS__LCD_ENABLE
+						MX28_PAD_LCD_RD_E__LCD_VSYNC
+						MX28_PAD_LCD_WR_RWN__LCD_HSYNC
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				can0_pins_a: can0@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_GPMI_RDY2__CAN0_TX
+						MX28_PAD_GPMI_RDY3__CAN0_RX
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				can1_pins_a: can1@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_GPMI_CE2N__CAN1_TX
+						MX28_PAD_GPMI_CE3N__CAN1_RX
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				spi2_pins_a: spi2@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SSP2_SCK__SSP2_SCK
+						MX28_PAD_SSP2_MOSI__SSP2_CMD
+						MX28_PAD_SSP2_MISO__SSP2_D0
+						MX28_PAD_SSP2_SS0__SSP2_D3
+					>;
+					fsl,drive-strength = <MXS_DRIVE_8mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_ENABLE>;
+				};
+
+				spi3_pins_a: spi3@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_AUART2_RX__SSP3_D4
+						MX28_PAD_AUART2_TX__SSP3_D5
+						MX28_PAD_SSP3_SCK__SSP3_SCK
+						MX28_PAD_SSP3_MOSI__SSP3_CMD
+						MX28_PAD_SSP3_MISO__SSP3_D0
+						MX28_PAD_SSP3_SS0__SSP3_D3
+					>;
+					fsl,drive-strength = <MXS_DRIVE_8mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				spi3_pins_b: spi3@1 {
+					reg = <1>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SSP3_SCK__SSP3_SCK
+						MX28_PAD_SSP3_MOSI__SSP3_CMD
+						MX28_PAD_SSP3_MISO__SSP3_D0
+						MX28_PAD_SSP3_SS0__SSP3_D3
+					>;
+					fsl,drive-strength = <MXS_DRIVE_8mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_ENABLE>;
+				};
+
+				usb0_pins_a: usb0@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SSP2_SS2__USB0_OVERCURRENT
+					>;
+					fsl,drive-strength = <MXS_DRIVE_12mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				usb0_pins_b: usb0@1 {
+					reg = <1>;
+					fsl,pinmux-ids = <
+						MX28_PAD_AUART1_CTS__USB0_OVERCURRENT
+					>;
+					fsl,drive-strength = <MXS_DRIVE_12mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				usb1_pins_a: usb1@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SSP2_SS1__USB1_OVERCURRENT
+					>;
+					fsl,drive-strength = <MXS_DRIVE_12mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				usb0_id_pins_a: usb0id@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_AUART1_RTS__USB0_ID
+					>;
+					fsl,drive-strength = <MXS_DRIVE_12mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_ENABLE>;
+				};
+
+				usb0_id_pins_b: usb0id1@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_PWM2__USB0_ID
+					>;
+					fsl,drive-strength = <MXS_DRIVE_12mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_ENABLE>;
+				};
+
+			};
+
+			digctl: digctl@8001c000 {
+				compatible = "fsl,imx28-digctl", "fsl,imx23-digctl";
+				reg = <0x8001c000 0x2000>;
+				interrupts = <89>;
+				status = "disabled";
+			};
+
+			etm: etm@80022000 {
+				reg = <0x80022000 0x2000>;
+				status = "disabled";
+			};
+
+			dma_apbx: dma-apbx@80024000 {
+				compatible = "fsl,imx28-dma-apbx";
+				reg = <0x80024000 0x2000>;
+				interrupts = <78 79 66 0
+					      80 81 68 69
+					      70 71 72 73
+					      74 75 76 77>;
+				interrupt-names = "auart4-rx", "auart4-tx", "spdif-tx", "empty",
+						  "saif0", "saif1", "i2c0", "i2c1",
+						  "auart0-rx", "auart0-tx", "auart1-rx", "auart1-tx",
+						  "auart2-rx", "auart2-tx", "auart3-rx", "auart3-tx";
+				#dma-cells = <1>;
+				dma-channels = <16>;
+				clocks = <&clks 26>;
+			};
+
+			dcp: dcp@80028000 {
+				compatible = "fsl,imx28-dcp", "fsl,imx23-dcp";
+				reg = <0x80028000 0x2000>;
+				interrupts = <52 53 54>;
+				status = "okay";
+			};
+
+			pxp: pxp@8002a000 {
+				reg = <0x8002a000 0x2000>;
+				interrupts = <39>;
+				status = "disabled";
+			};
+
+			ocotp: ocotp@8002c000 {
+				compatible = "fsl,imx28-ocotp", "fsl,ocotp";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				reg = <0x8002c000 0x2000>;
+				clocks = <&clks 25>;
+			};
+
+			axi-ahb@8002e000 {
+				reg = <0x8002e000 0x2000>;
+				status = "disabled";
+			};
+
+			lcdif: lcdif@80030000 {
+				compatible = "fsl,imx28-lcdif";
+				reg = <0x80030000 0x2000>;
+				interrupts = <38>;
+				clocks = <&clks 55>;
+				dmas = <&dma_apbh 13>;
+				dma-names = "rx";
+				status = "disabled";
+			};
+
+			can0: can@80032000 {
+				compatible = "fsl,imx28-flexcan";
+				reg = <0x80032000 0x2000>;
+				interrupts = <8>;
+				clocks = <&clks 58>, <&clks 58>;
+				clock-names = "ipg", "per";
+				status = "disabled";
+			};
+
+			can1: can@80034000 {
+				compatible = "fsl,imx28-flexcan";
+				reg = <0x80034000 0x2000>;
+				interrupts = <9>;
+				clocks = <&clks 59>, <&clks 59>;
+				clock-names = "ipg", "per";
+				status = "disabled";
+			};
+
+			simdbg: simdbg@8003c000 {
+				reg = <0x8003c000 0x200>;
+				status = "disabled";
+			};
+
+			simgpmisel: simgpmisel@8003c200 {
+				reg = <0x8003c200 0x100>;
+				status = "disabled";
+			};
+
+			simsspsel: simsspsel@8003c300 {
+				reg = <0x8003c300 0x100>;
+				status = "disabled";
+			};
+
+			simmemsel: simmemsel@8003c400 {
+				reg = <0x8003c400 0x100>;
+				status = "disabled";
+			};
+
+			gpiomon: gpiomon@8003c500 {
+				reg = <0x8003c500 0x100>;
+				status = "disabled";
+			};
+
+			simenet: simenet@8003c700 {
+				reg = <0x8003c700 0x100>;
+				status = "disabled";
+			};
+
+			armjtag: armjtag@8003c800 {
+				reg = <0x8003c800 0x100>;
+				status = "disabled";
+			};
+		};
+
+		apbx@80040000 {
+			compatible = "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x80040000 0x40000>;
+			ranges;
+
+			clks: clkctrl@80040000 {
+				compatible = "fsl,imx28-clkctrl", "fsl,clkctrl";
+				reg = <0x80040000 0x2000>;
+				#clock-cells = <1>;
+			};
+
+			saif0: saif@80042000 {
+				#sound-dai-cells = <0>;
+				compatible = "fsl,imx28-saif";
+				reg = <0x80042000 0x2000>;
+				interrupts = <59>;
+				#clock-cells = <0>;
+				clocks = <&clks 53>;
+				dmas = <&dma_apbx 4>;
+				dma-names = "rx-tx";
+				status = "disabled";
+			};
+
+			power: power@80044000 {
+				reg = <0x80044000 0x2000>;
+				status = "disabled";
+			};
+
+			saif1: saif@80046000 {
+				#sound-dai-cells = <0>;
+				compatible = "fsl,imx28-saif";
+				reg = <0x80046000 0x2000>;
+				interrupts = <58>;
+				clocks = <&clks 54>;
+				dmas = <&dma_apbx 5>;
+				dma-names = "rx-tx";
+				status = "disabled";
+			};
+
+			lradc: lradc@80050000 {
+				compatible = "fsl,imx28-lradc";
+				reg = <0x80050000 0x2000>;
+				interrupts = <10 14 15 16 17 18 19
+						20 21 22 23 24 25>;
+				status = "disabled";
+				clocks = <&clks 41>;
+				#io-channel-cells = <1>;
+			};
+
+			spdif: spdif@80054000 {
+				reg = <0x80054000 0x2000>;
+				interrupts = <45>;
+				dmas = <&dma_apbx 2>;
+				dma-names = "tx";
+				status = "disabled";
+			};
+
+			mxs_rtc: rtc@80056000 {
+				compatible = "fsl,imx28-rtc", "fsl,stmp3xxx-rtc";
+				reg = <0x80056000 0x2000>;
+				interrupts = <29>;
+			};
+
+			i2c0: i2c@80058000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx28-i2c";
+				reg = <0x80058000 0x2000>;
+				interrupts = <111>;
+				clock-frequency = <100000>;
+				dmas = <&dma_apbx 6>;
+				dma-names = "rx-tx";
+				status = "disabled";
+			};
+
+			i2c1: i2c@8005a000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx28-i2c";
+				reg = <0x8005a000 0x2000>;
+				interrupts = <110>;
+				clock-frequency = <100000>;
+				dmas = <&dma_apbx 7>;
+				dma-names = "rx-tx";
+				status = "disabled";
+			};
+
+			pwm: pwm@80064000 {
+				compatible = "fsl,imx28-pwm", "fsl,imx23-pwm";
+				reg = <0x80064000 0x2000>;
+				clocks = <&clks 44>;
+				#pwm-cells = <2>;
+				fsl,pwm-number = <8>;
+				status = "disabled";
+			};
+
+			timer: timrot@80068000 {
+				compatible = "fsl,imx28-timrot", "fsl,timrot";
+				reg = <0x80068000 0x2000>;
+				interrupts = <48 49 50 51>;
+				clocks = <&clks 26>;
+			};
+
+			auart0: serial@8006a000 {
+				compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+				reg = <0x8006a000 0x2000>;
+				interrupts = <112>;
+				dmas = <&dma_apbx 8>, <&dma_apbx 9>;
+				dma-names = "rx", "tx";
+				clocks = <&clks 45>;
+				status = "disabled";
+			};
+
+			auart1: serial@8006c000 {
+				compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+				reg = <0x8006c000 0x2000>;
+				interrupts = <113>;
+				dmas = <&dma_apbx 10>, <&dma_apbx 11>;
+				dma-names = "rx", "tx";
+				clocks = <&clks 45>;
+				status = "disabled";
+			};
+
+			auart2: serial@8006e000 {
+				compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+				reg = <0x8006e000 0x2000>;
+				interrupts = <114>;
+				dmas = <&dma_apbx 12>, <&dma_apbx 13>;
+				dma-names = "rx", "tx";
+				clocks = <&clks 45>;
+				status = "disabled";
+			};
+
+			auart3: serial@80070000 {
+				compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+				reg = <0x80070000 0x2000>;
+				interrupts = <115>;
+				dmas = <&dma_apbx 14>, <&dma_apbx 15>;
+				dma-names = "rx", "tx";
+				clocks = <&clks 45>;
+				status = "disabled";
+			};
+
+			auart4: serial@80072000 {
+				compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+				reg = <0x80072000 0x2000>;
+				interrupts = <116>;
+				dmas = <&dma_apbx 0>, <&dma_apbx 1>;
+				dma-names = "rx", "tx";
+				clocks = <&clks 45>;
+				status = "disabled";
+			};
+
+			duart: serial@80074000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x80074000 0x1000>;
+				interrupts = <47>;
+				clocks = <&clks 45>, <&clks 26>;
+				clock-names = "uart", "apb_pclk";
+				status = "disabled";
+			};
+
+			usbphy0: usbphy@8007c000 {
+				compatible = "fsl,imx28-usbphy", "fsl,imx23-usbphy";
+				reg = <0x8007c000 0x2000>;
+				clocks = <&clks 62>;
+				status = "disabled";
+			};
+
+			usbphy1: usbphy@8007e000 {
+				compatible = "fsl,imx28-usbphy", "fsl,imx23-usbphy";
+				reg = <0x8007e000 0x2000>;
+				clocks = <&clks 63>;
+				status = "disabled";
+			};
+		};
+	};
+
+	ahb@80080000 {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x80080000 0x80000>;
+		ranges;
+
+		usb0: usb@80080000 {
+			compatible = "fsl,imx28-usb", "fsl,imx27-usb";
+			reg = <0x80080000 0x10000>;
+			interrupts = <93>;
+			clocks = <&clks 60>;
+			fsl,usbphy = <&usbphy0>;
+			status = "disabled";
+		};
+
+		usb1: usb@80090000 {
+			compatible = "fsl,imx28-usb", "fsl,imx27-usb";
+			reg = <0x80090000 0x10000>;
+			interrupts = <92>;
+			clocks = <&clks 61>;
+			fsl,usbphy = <&usbphy1>;
+			dr_mode = "host";
+			status = "disabled";
+		};
+
+		dflpt: dflpt@800c0000 {
+			reg = <0x800c0000 0x10000>;
+			status = "disabled";
+		};
+
+		mac0: ethernet@800f0000 {
+			compatible = "fsl,imx28-fec";
+			reg = <0x800f0000 0x4000>;
+			interrupts = <101>;
+			clocks = <&clks 57>, <&clks 57>, <&clks 64>;
+			clock-names = "ipg", "ahb", "enet_out";
+			status = "disabled";
+		};
+
+		mac1: ethernet@800f4000 {
+			compatible = "fsl,imx28-fec";
+			reg = <0x800f4000 0x4000>;
+			interrupts = <102>;
+			clocks = <&clks 57>, <&clks 57>;
+			clock-names = "ipg", "ahb";
+			status = "disabled";
+		};
+
+		etn_switch: switch@800f8000 {
+			reg = <0x800f8000 0x8000>;
+			status = "disabled";
+		};
+	};
+
+	iio-hwmon {
+		compatible = "iio-hwmon";
+		io-channels = <&lradc 8>;
+	};
+};

+ 5 - 0
arch/arm/dts/imx53-m53menlo-u-boot.dtsi

@@ -11,6 +11,11 @@
 			u-boot,dm-pre-reloc;
 		};
 	};
+
+	wdt-reboot {
+		compatible = "wdt-reboot";
+		wdt = <&wdog1>;
+	};
 };
 
 &gpio1 {

+ 14 - 0
arch/arm/dts/imx6dl-dhcom-pdk2.dts

@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0+)
+/*
+ * Copyright (C) 2019 DH electronics GmbH
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-dhcom-pdk2.dtsi"
+
+/ {
+	model = "Freescale i.MX6 Duallite/Solo DHCOM Premium Developer Kit (2)";
+	compatible = "dh,imx6dl-dhcom-pdk2", "dh,imx6dl-dhcom", "fsl,imx6dl";
+};

+ 5 - 136
arch/arm/dts/imx6q-dhcom-pdk2.dts

@@ -1,151 +1,20 @@
 // SPDX-License-Identifier: (GPL-2.0+)
 /*
- * Copyright (C) 2015 DH electronics GmbH
+ * Copyright (C) 2015-2019 DH electronics GmbH
  * Copyright (C) 2018 Marek Vasut <marex@denx.de>
  */
 
 /dts-v1/;
 
-#include "imx6q-dhcom-som.dtsi"
+#include "imx6q.dtsi"
+#include "imx6qdl-dhcom-pdk2.dtsi"
 
 / {
-	model = "Freescale i.MX6 Quad DHCOM Premium Developer Kit (2)";
-	compatible = "dh,imx6q-dhcom-pdk2", "dh,imx6q-dhcom-som", "fsl,imx6q";
-
-	chosen {
-		stdout-path = &uart1;
-	};
-
-	clk_ext_audio_codec: clock-codec {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <24000000>;
-	};
-
-	sound {
-		compatible = "fsl,imx-audio-sgtl5000";
-		model = "imx-sgtl5000";
-		ssi-controller = <&ssi1>;
-		audio-codec = <&sgtl5000>;
-		audio-routing =
-			"MIC_IN", "Mic Jack",
-			"Mic Jack", "Mic Bias",
-			"LINE_IN", "Line In Jack",
-			"Headphone Jack", "HP_OUT";
-		mux-int-port = <1>;
-		mux-ext-port = <3>;
-	};
-};
-
-&audmux {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_audmux_ext>;
-	status = "okay";
-};
-
-&hdmi {
-	ddc-i2c-bus = <&i2c2>;
-	status = "okay";
-};
-
-&i2c2 {
-	sgtl5000: codec@a {
-		compatible = "fsl,sgtl5000";
-		reg = <0x0a>;
-		#sound-dai-cells = <0>;
-		clocks = <&clk_ext_audio_codec>;
-		VDDA-supply = <&reg_3p3v>;
-		VDDIO-supply = <&reg_3p3v>;
-	};
-};
-
-&iomuxc {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_hog_base &pinctrl_hog>;
-
-	pinctrl_hog: hog-grp {
-		fsl,pins = <
-			MX6QDL_PAD_GPIO_2__GPIO1_IO02		0x400120b0
-			MX6QDL_PAD_GPIO_4__GPIO1_IO04		0x400120b0
-			MX6QDL_PAD_GPIO_5__GPIO1_IO05		0x400120b0
-			MX6QDL_PAD_CSI0_DAT17__GPIO6_IO03	0x400120b0
-			MX6QDL_PAD_GPIO_19__GPIO4_IO05		0x120b0
-			MX6QDL_PAD_DI0_PIN4__GPIO4_IO20		0x400120b0
-			MX6QDL_PAD_EIM_D27__GPIO3_IO27		0x120b0
-			MX6QDL_PAD_KEY_ROW0__GPIO4_IO07		0x120b0
-			MX6QDL_PAD_KEY_COL1__GPIO4_IO08		0x400120b0
-			MX6QDL_PAD_NANDF_CS1__GPIO6_IO14	0x400120b0
-			MX6QDL_PAD_NANDF_CS2__GPIO6_IO15	0x400120b0
-			MX6QDL_PAD_KEY_ROW1__GPIO4_IO09		0x400120b0
-			MX6QDL_PAD_SD3_DAT5__GPIO7_IO00		0x400120b0
-			MX6QDL_PAD_SD3_DAT4__GPIO7_IO01		0x400120b0
-			MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21	0x400120b0
-			MX6QDL_PAD_GPIO_18__GPIO7_IO13		0x400120b0
-			MX6QDL_PAD_SD1_CMD__GPIO1_IO18		0x400120b0
-			MX6QDL_PAD_SD1_DAT0__GPIO1_IO16		0x400120b0
-			MX6QDL_PAD_SD1_DAT1__GPIO1_IO17		0x400120b0
-			MX6QDL_PAD_SD1_DAT2__GPIO1_IO19		0x400120b0
-			MX6QDL_PAD_SD1_CLK__GPIO1_IO20		0x400120b0
-			MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18	0x400120b0
-			MX6QDL_PAD_CSI0_MCLK__GPIO5_IO19	0x400120b0
-			MX6QDL_PAD_KEY_COL0__GPIO4_IO06		0x400120b0
-		>;
-	};
-
-	pinctrl_audmux_ext: audmux-ext-grp {
-		fsl,pins = <
-			MX6QDL_PAD_CSI0_DAT7__AUD3_RXD		0x130b0
-			MX6QDL_PAD_CSI0_DAT4__AUD3_TXC		0x130b0
-			MX6QDL_PAD_CSI0_DAT5__AUD3_TXD		0x110b0
-			MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS		0x130b0
-		>;
-	};
-
-	pinctrl_enet_1G: enet-1G-grp {
-		fsl,pins = <
-			MX6QDL_PAD_ENET_MDIO__ENET_MDIO		0x100b0
-			MX6QDL_PAD_ENET_MDC__ENET_MDC		0x100b0
-			MX6QDL_PAD_RGMII_TXC__RGMII_TXC		0x100b0
-			MX6QDL_PAD_RGMII_TD0__RGMII_TD0		0x100b0
-			MX6QDL_PAD_RGMII_TD1__RGMII_TD1		0x100b0
-			MX6QDL_PAD_RGMII_TD2__RGMII_TD2		0x100b0
-			MX6QDL_PAD_RGMII_TD3__RGMII_TD3		0x100b0
-			MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL	0x100b0
-			MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK	0x100b0
-			MX6QDL_PAD_RGMII_RXC__RGMII_RXC		0x1b0b0
-			MX6QDL_PAD_RGMII_RD0__RGMII_RD0		0x1b0b0
-			MX6QDL_PAD_RGMII_RD1__RGMII_RD1		0x1b0b0
-			MX6QDL_PAD_RGMII_RD2__RGMII_RD2		0x1b0b0
-			MX6QDL_PAD_RGMII_RD3__RGMII_RD3		0x1b0b0
-			MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL	0x1b0b0
-			MX6QDL_PAD_EIM_D29__GPIO3_IO29		0x000b0
-			MX6QDL_PAD_GPIO_0__GPIO1_IO00		0x000b1
-			MX6QDL_PAD_EIM_D26__GPIO3_IO26		0x000b1
-		>;
-	};
-
-	pinctrl_pcie: pcie-grp {
-		fsl,pins = <
-			MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20	0x1b0b1
-		>;
-	};
-};
-
-&pcie {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_pcie>;
-	reset-gpio = <&gpio6 14 GPIO_ACTIVE_LOW>;
-	status = "okay";
-};
-
-&ssi1 {
-	status = "okay";
+	model = "Freescale i.MX6 Quad/Dual DHCOM Premium Developer Kit (2)";
+	compatible = "dh,imx6q-dhcom-pdk2", "dh,imx6q-dhcom", "fsl,imx6q";
 };
 
 &sata {
 	status = "okay";
 };
 
-&usdhc3 {
-	status = "okay";
-};

+ 44 - 0
arch/arm/dts/imx6q-display5-u-boot.dtsi

@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ *
+ * SPDX-License-Identifier:     GPL-2.0+ or X11
+ */
+
+/*
+ * The minimal augmentation DTS U-Boot file to allow UART5
+ * configuration in the pre-relocation stage of U-Boot
+ * proper.
+ *
+ * As the same UART is already configured in SPL, we don't need
+ * setup pinmux for it again.
+ */
+
+/ {
+	aliases {
+		mmc0 = &usdhc4;
+	};
+
+	soc {
+		u-boot,dm-pre-reloc;
+
+		aips-bus@2100000 {
+			u-boot,dm-pre-reloc;
+		};
+	};
+
+	chosen {
+		stdout-path = &uart5;
+	};
+};
+
+&i2c3 {
+	at24@50 {
+		u-boot,i2c-offset-len = <2>;
+	};
+};
+
+&uart5 {
+	u-boot,dm-pre-reloc;
+};

+ 352 - 0
arch/arm/dts/imx6q-display5.dts

@@ -10,9 +10,361 @@
 
 /dts-v1/;
 
+#include <dt-bindings/gpio/gpio.h>
 #include "imx6q.dtsi"
 
 / {
 	model = "Liebherr (LWN) display5 i.MX6 Quad Board";
 	compatible = "lwn,display5", "fsl,imx6q";
+
+	memory@10000000 {
+		device_type = "memory";
+		reg = <0x10000000 0x40000000>;
+	};
+};
+
+&ecspi2 {
+	cs-gpios = <&gpio5 29 GPIO_ACTIVE_LOW>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi2 &pinctrl_ecspi2_cs &pinctrl_ecspi2_flwp>;
+	status = "okay";
+
+	s25fl256s: flash@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "jedec,spi-nor";
+		spi-max-frequency = <40000000>;
+		reg = <0>;
+
+		partition@0 {
+			label = "SPL (spi)";
+			reg = <0x0 0x20000>;
+			read-only;
+		};
+		partition@1 {
+			label = "u-boot (spi)";
+			reg = <0x20000 0x100000>;
+			read-only;
+		};
+		partition@2 {
+			label = "uboot-env (spi)";
+			reg = <0x120000 0x10000>;
+		};
+		partition@3 {
+			label = "uboot-envr (spi)";
+			reg = <0x130000 0x10000>;
+		};
+		partition@4 {
+			label = "linux-recovery (spi)";
+			reg = <0x140000 0x800000>;
+		};
+		partition@5 {
+			label = "swupdate-fitImg (spi)";
+			reg = <0x940000 0x400000>;
+		};
+		partition@6 {
+			label = "swupdate-initramfs (spi)";
+			reg = <0xD40000 0x800000>;
+		};
+	};
+};
+
+&ecspi3 {
+	cs-gpios = <&gpio4 24 GPIO_ACTIVE_LOW>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi3 &pinctrl_ecspi3_cs &pinctrl_ecspi3_flwp>;
+	status = "okay";
+};
+
+&fec {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet>;
+	phy-handle = <&ethernet_phy0>;
+	phy-mode = "rgmii-id";
+	status = "okay";
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		ethernet_phy0: ethernet-phy@0 {
+			compatible = "marvell,88E1510";
+			device_type = "ethernet-phy";
+			/* Set LED0 control: */
+			/* On - Link, Blink - Activity, Off - No Link */
+			marvell,reg-init = <3 0x10 0 0x1011>;
+			max-speed = <100>;
+			reg = <0>;
+		};
+	};
+};
+
+&i2c1 {
+	clock-frequency = <400000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	status = "okay";
+
+	codec: tfa9879@6c {
+		#sound-dai-cells = <0>;
+		compatible = "nxp,tfa9879";
+		reg = <0x6C>;
+	};
+};
+
+&i2c2 {
+	clock-frequency = <400000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	status = "okay";
+};
+
+&i2c3 {
+	clock-frequency = <400000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c3>;
+	status = "okay";
+
+	at24@50 {
+		compatible = "atmel,24c256";
+		pagesize = <64>;
+		reg = <0x50>;
+	};
+
+	pfuze100: pmic@8 {
+		compatible = "fsl,pfuze100";
+		reg = <0x08>;
+
+		regulators {
+			sw1a_reg: sw1ab {
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1875000>;
+				regulator-boot-on;
+				regulator-always-on;
+				regulator-ramp-delay = <6250>;
+			};
+
+			sw1c_reg: sw1c {
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1875000>;
+				regulator-boot-on;
+				regulator-always-on;
+				regulator-ramp-delay = <6250>;
+			};
+
+			sw2_reg: sw2 {
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <3950000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			sw3a_reg: sw3a {
+				regulator-min-microvolt = <400000>;
+				regulator-max-microvolt = <1975000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			sw3b_reg: sw3b {
+				regulator-min-microvolt = <400000>;
+				regulator-max-microvolt = <1975000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			sw4_reg: sw4 {
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			swbst_reg: swbst {
+				regulator-min-microvolt = <5000000>;
+				regulator-max-microvolt = <5150000>;
+			};
+
+			snvs_reg: vsnvs {
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			vref_reg: vrefddr {
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			vgen1_reg: vgen1 {
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1550000>;
+			};
+
+			vgen2_reg: vgen2 {
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1550000>;
+			};
+
+			vgen3_reg: vgen3 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			vgen4_reg: vgen4 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+
+			vgen5_reg: vgen5 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+
+			vgen6_reg: vgen6 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart4>;
+	uart-has-rtscts;
+	status = "okay";
+};
+
+&uart5 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart5>;
+	status = "okay";
+};
+
+&usdhc4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc4>;
+	bus-width = <8>;
+	non-removable;
+	status = "okay";
+};
+
+&iomuxc {
+	pinctrl_ecspi2: ecspi2grp {
+		fsl,pins = <
+			MX6QDL_PAD_CSI0_DAT10__ECSPI2_MISO	0x100b1
+			MX6QDL_PAD_CSI0_DAT9__ECSPI2_MOSI	0x100b1
+			MX6QDL_PAD_CSI0_DAT8__ECSPI2_SCLK	0x100b1
+		>;
+	};
+
+	pinctrl_ecspi2_cs: ecspi2csgrp {
+		fsl,pins = <
+			MX6QDL_PAD_CSI0_DAT11__GPIO5_IO29 0x100b1
+		>;
+	};
+
+	pinctrl_ecspi2_flwp: ecspi2flwpgrp {
+		fsl,pins = <
+			MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0
+		>;
+	};
+
+	pinctrl_ecspi3: ecspi3grp {
+		fsl,pins = <
+			MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO	0x100b1
+			MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI	0x100b1
+			MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK	0x100b1
+		>;
+	};
+
+	pinctrl_ecspi3_cs: ecspi3csgrp {
+		fsl,pins = <
+			MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x1b0b0
+		>;
+	};
+
+	pinctrl_ecspi3_flwp: ecspi3flwpgrp {
+		fsl,pins = <
+			MX6QDL_PAD_DISP0_DAT6__GPIO4_IO27 0x1b0b0
+		>;
+	};
+
+	pinctrl_enet: enetgrp {
+		fsl,pins = <
+			MX6QDL_PAD_ENET_MDIO__ENET_MDIO		0x1b0b0
+			MX6QDL_PAD_ENET_MDC__ENET_MDC		0x1b0b0
+			MX6QDL_PAD_RGMII_TXC__RGMII_TXC		0x1b0b0
+			MX6QDL_PAD_RGMII_TD0__RGMII_TD0		0x1b0b0
+			MX6QDL_PAD_RGMII_TD1__RGMII_TD1		0x1b0b0
+			MX6QDL_PAD_RGMII_TD2__RGMII_TD2		0x1b0b0
+			MX6QDL_PAD_RGMII_TD3__RGMII_TD3		0x1b0b0
+			MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL	0x1b0b0
+			MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK	0x1b0b0
+			MX6QDL_PAD_RGMII_RXC__RGMII_RXC		0x1b0b0
+			MX6QDL_PAD_RGMII_RD0__RGMII_RD0		0x1b0b0
+			MX6QDL_PAD_RGMII_RD1__RGMII_RD1		0x1b0b0
+			MX6QDL_PAD_RGMII_RD2__RGMII_RD2		0x1b0b0
+			MX6QDL_PAD_RGMII_RD3__RGMII_RD3		0x1b0b0
+			MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL	0x1b0b0
+			MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+			MX6QDL_PAD_GPIO_6__ENET_IRQ		0x000b1
+			MX6QDL_PAD_ENET_RXD0__GPIO1_IO27        0x1b0b0
+		>;
+	};
+
+	pinctrl_i2c1: i2c1grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D21__I2C1_SCL	0x4001b8b1
+			MX6QDL_PAD_EIM_D28__I2C1_SDA	0x4001b8b1
+		>;
+	};
+
+	pinctrl_i2c2: i2c2grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_EB2__I2C2_SCL	0x4001b8b1
+			MX6QDL_PAD_EIM_D16__I2C2_SDA	0x4001b8b1
+		>;
+	};
+
+	pinctrl_i2c3: i2c3grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D17__I2C3_SCL	0x4001b8b1
+			MX6QDL_PAD_EIM_D18__I2C3_SDA	0x4001b8b1
+		>;
+	};
+
+	pinctrl_uart4: uart4grp {
+		fsl,pins = <
+			MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA	0x1b0b1
+			MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA	0x1b0b1
+			MX6QDL_PAD_CSI0_DAT16__UART4_RTS_B	0x1b0b1
+			MX6QDL_PAD_CSI0_DAT17__UART4_CTS_B	0x1b0b1
+		>;
+	};
+
+	pinctrl_uart5: uart5grp {
+		fsl,pins = <
+			MX6QDL_PAD_CSI0_DAT14__UART5_TX_DATA	0x1b0b1
+			MX6QDL_PAD_CSI0_DAT15__UART5_RX_DATA    0x1b0b1
+		>;
+	};
+
+	pinctrl_usdhc4: usdhc4grp {
+		fsl,pins = <
+			MX6QDL_PAD_SD4_CMD__SD4_CMD		0x17059
+			MX6QDL_PAD_SD4_CLK__SD4_CLK		0x10059
+			MX6QDL_PAD_SD4_DAT0__SD4_DATA0		0x17059
+			MX6QDL_PAD_SD4_DAT1__SD4_DATA1		0x17059
+			MX6QDL_PAD_SD4_DAT2__SD4_DATA2		0x17059
+			MX6QDL_PAD_SD4_DAT3__SD4_DATA3		0x17059
+			MX6QDL_PAD_SD4_DAT4__SD4_DATA4		0x17059
+			MX6QDL_PAD_SD4_DAT5__SD4_DATA5		0x17059
+			MX6QDL_PAD_SD4_DAT6__SD4_DATA6		0x17059
+			MX6QDL_PAD_SD4_DAT7__SD4_DATA7		0x17059
+			MX6QDL_PAD_NANDF_ALE__SD4_RESET	0x17059
+		>;
+	};
 };

+ 142 - 0
arch/arm/dts/imx6qdl-dhcom-pdk2.dtsi

@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: (GPL-2.0+)
+/*
+ * Copyright (C) 2015-2019 DH electronics GmbH
+ * Copyright (C) 2018 Marek Vasut <marex@denx.de>
+ */
+
+#include "imx6qdl-dhcom.dtsi"
+
+/ {
+	chosen {
+		stdout-path = &uart1;
+	};
+
+	clk_ext_audio_codec: clock-codec {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+
+	sound {
+		compatible = "fsl,imx-audio-sgtl5000";
+		model = "imx-sgtl5000";
+		ssi-controller = <&ssi1>;
+		audio-codec = <&sgtl5000>;
+		audio-routing =
+			"MIC_IN", "Mic Jack",
+			"Mic Jack", "Mic Bias",
+			"LINE_IN", "Line In Jack",
+			"Headphone Jack", "HP_OUT";
+		mux-int-port = <1>;
+		mux-ext-port = <3>;
+	};
+};
+
+&audmux {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_audmux_ext>;
+	status = "okay";
+};
+
+&hdmi {
+	ddc-i2c-bus = <&i2c2>;
+	status = "okay";
+};
+
+&i2c2 {
+	sgtl5000: codec@a {
+		compatible = "fsl,sgtl5000";
+		reg = <0x0a>;
+		#sound-dai-cells = <0>;
+		clocks = <&clk_ext_audio_codec>;
+		VDDA-supply = <&reg_3p3v>;
+		VDDIO-supply = <&reg_3p3v>;
+	};
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_hog_base &pinctrl_hog>;
+
+	pinctrl_hog: hog-grp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_2__GPIO1_IO02		0x400120b0
+			MX6QDL_PAD_GPIO_4__GPIO1_IO04		0x400120b0
+			MX6QDL_PAD_GPIO_5__GPIO1_IO05		0x400120b0
+			MX6QDL_PAD_CSI0_DAT17__GPIO6_IO03	0x400120b0
+			MX6QDL_PAD_GPIO_19__GPIO4_IO05		0x120b0
+			MX6QDL_PAD_DI0_PIN4__GPIO4_IO20		0x400120b0
+			MX6QDL_PAD_EIM_D27__GPIO3_IO27		0x120b0
+			MX6QDL_PAD_KEY_ROW0__GPIO4_IO07		0x120b0
+			MX6QDL_PAD_KEY_COL1__GPIO4_IO08		0x400120b0
+			MX6QDL_PAD_NANDF_CS1__GPIO6_IO14	0x400120b0
+			MX6QDL_PAD_NANDF_CS2__GPIO6_IO15	0x400120b0
+			MX6QDL_PAD_KEY_ROW1__GPIO4_IO09		0x400120b0
+			MX6QDL_PAD_SD3_DAT5__GPIO7_IO00		0x400120b0
+			MX6QDL_PAD_SD3_DAT4__GPIO7_IO01		0x400120b0
+			MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21	0x400120b0
+			MX6QDL_PAD_GPIO_18__GPIO7_IO13		0x400120b0
+			MX6QDL_PAD_SD1_CMD__GPIO1_IO18		0x400120b0
+			MX6QDL_PAD_SD1_DAT0__GPIO1_IO16		0x400120b0
+			MX6QDL_PAD_SD1_DAT1__GPIO1_IO17		0x400120b0
+			MX6QDL_PAD_SD1_DAT2__GPIO1_IO19		0x400120b0
+			MX6QDL_PAD_SD1_CLK__GPIO1_IO20		0x400120b0
+			MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18	0x400120b0
+			MX6QDL_PAD_CSI0_MCLK__GPIO5_IO19	0x400120b0
+			MX6QDL_PAD_KEY_COL0__GPIO4_IO06		0x400120b0
+		>;
+	};
+
+	pinctrl_audmux_ext: audmux-ext-grp {
+		fsl,pins = <
+			MX6QDL_PAD_CSI0_DAT7__AUD3_RXD		0x130b0
+			MX6QDL_PAD_CSI0_DAT4__AUD3_TXC		0x130b0
+			MX6QDL_PAD_CSI0_DAT5__AUD3_TXD		0x110b0
+			MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS		0x130b0
+		>;
+	};
+
+	pinctrl_enet_1G: enet-1G-grp {
+		fsl,pins = <
+			MX6QDL_PAD_ENET_MDIO__ENET_MDIO		0x100b0
+			MX6QDL_PAD_ENET_MDC__ENET_MDC		0x100b0
+			MX6QDL_PAD_RGMII_TXC__RGMII_TXC		0x100b0
+			MX6QDL_PAD_RGMII_TD0__RGMII_TD0		0x100b0
+			MX6QDL_PAD_RGMII_TD1__RGMII_TD1		0x100b0
+			MX6QDL_PAD_RGMII_TD2__RGMII_TD2		0x100b0
+			MX6QDL_PAD_RGMII_TD3__RGMII_TD3		0x100b0
+			MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL	0x100b0
+			MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK	0x100b0
+			MX6QDL_PAD_RGMII_RXC__RGMII_RXC		0x1b0b0
+			MX6QDL_PAD_RGMII_RD0__RGMII_RD0		0x1b0b0
+			MX6QDL_PAD_RGMII_RD1__RGMII_RD1		0x1b0b0
+			MX6QDL_PAD_RGMII_RD2__RGMII_RD2		0x1b0b0
+			MX6QDL_PAD_RGMII_RD3__RGMII_RD3		0x1b0b0
+			MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL	0x1b0b0
+			MX6QDL_PAD_EIM_D29__GPIO3_IO29		0x000b0
+			MX6QDL_PAD_GPIO_0__GPIO1_IO00		0x000b1
+			MX6QDL_PAD_EIM_D26__GPIO3_IO26		0x000b1
+		>;
+	};
+
+	pinctrl_pcie: pcie-grp {
+		fsl,pins = <
+			MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20	0x1b0b1
+		>;
+	};
+};
+
+&pcie {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pcie>;
+	reset-gpio = <&gpio6 14 GPIO_ACTIVE_LOW>;
+	status = "okay";
+};
+
+&ssi1 {
+	status = "okay";
+};
+
+&usdhc3 {
+	status = "okay";
+};

+ 1 - 2
arch/arm/dts/imx6q-dhcom-som.dtsi → arch/arm/dts/imx6qdl-dhcom.dtsi

@@ -1,10 +1,9 @@
 // SPDX-License-Identifier: (GPL-2.0+)
 /*
- * Copyright (C) 2015 DH electronics GmbH
+ * Copyright (C) 2015-2019 DH electronics GmbH
  * Copyright (C) 2018 Marek Vasut <marex@denx.de>
  */
 
-#include "imx6q.dtsi"
 #include <dt-bindings/pwm/pwm.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/clock/imx6qdl-clock.h>

+ 2 - 0
arch/arm/dts/imx7d-pico.dtsi

@@ -10,6 +10,7 @@
 / {
 	aliases {
 		mmc0 = &usdhc3;
+		usb0 = &usbotg1;
 	};
 
 	/* Will be filled by the bootloader */
@@ -296,6 +297,7 @@
 
 &usbotg1 {
 	vbus-supply = <&reg_usb_otg1_vbus>;
+	dr_mode = "peripheral";
 	status = "okay";
 };
 

+ 31 - 0
arch/arm/dts/mxs-pinfunc.h

@@ -0,0 +1,31 @@
+/*
+ * Header providing constants for i.MX28 pinctrl bindings.
+ *
+ * Copyright (C) 2013 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __DT_BINDINGS_MXS_PINCTRL_H__
+#define __DT_BINDINGS_MXS_PINCTRL_H__
+
+/* fsl,drive-strength property */
+#define MXS_DRIVE_4mA		0
+#define MXS_DRIVE_8mA		1
+#define MXS_DRIVE_12mA		2
+#define MXS_DRIVE_16mA		3
+
+/* fsl,voltage property */
+#define MXS_VOLTAGE_LOW		0
+#define MXS_VOLTAGE_HIGH	1
+
+/* fsl,pull-up property */
+#define MXS_PULL_DISABLE	0
+#define MXS_PULL_ENABLE		1
+
+#endif /* __DT_BINDINGS_MXS_PINCTRL_H__ */

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

@@ -72,6 +72,8 @@ 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);
+int sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource, sc_misc_temp_t temp,
+		     s16 *celsius, s8 *tenths);
 
 /* RM API */
 sc_bool_t sc_rm_is_memreg_owned(sc_ipc_t ipc, sc_rm_mr_t mr);

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

@@ -26,5 +26,6 @@
 #define SC_MISC_REL_CONTAINER	2U	/* Release container */
 
 typedef u8 sc_misc_boot_status_t;
+typedef u8 sc_misc_temp_t;
 
 #endif /* SC_MISC_API_H */

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

@@ -3,6 +3,7 @@
  * Copyright 2018 NXP
  */
 
+#include <asm/arch/sci/sci.h>
 #include <asm/mach-imx/sys_proto.h>
 #include <linux/types.h>
 
@@ -15,5 +16,7 @@ struct pass_over_info_t {
 	u32 g_ap_mu;
 };
 
+void build_info(void);
 enum boot_device get_boot_device(void);
 int print_bootinfo(void);
+int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate);

+ 111 - 0
arch/arm/include/asm/mach-imx/imx-nandbcb.h

@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2017 Jagan Teki <jagan@amarulasolutions.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _IMX_NAND_BCB_H_
+#define _IMX_NAND_BCB_H_
+
+#define FCB_FINGERPRINT		0x20424346      /* 'FCB' */
+#define FCB_VERSION_1		0x01000000
+
+#define DBBT_FINGERPRINT2	0x54424244	/* 'DBBT' */
+#define DBBT_VERSION_1		0x01000000
+
+struct dbbt_block {
+	u32 checksum;	/* reserved on i.MX6 */
+	u32 fingerprint;
+	u32 version;
+	u32 numberbb;	/* reserved on i.MX6 */
+	u32 dbbtpages;
+};
+
+struct fcb_block {
+	u32 checksum;		/* First fingerprint in first byte */
+	u32 fingerprint;	/* 2nd fingerprint at byte 4 */
+	u32 version;		/* 3rd fingerprint at byte 8 */
+	u8 datasetup;
+	u8 datahold;
+	u8 addr_setup;
+	u8 dsample_time;
+
+	/* These are for application use only and not for ROM. */
+	u8 nandtiming;
+	u8 rea;
+	u8 rloh;
+	u8 rhoh;
+	u32 pagesize;		/* 2048 for 2K pages, 4096 for 4K pages */
+	u32 oob_pagesize;	/* 2112 for 2K pages, 4314 for 4K pages */
+	u32 sectors;		/* Number of 2K sections per block */
+	u32 nr_nand;		/* Total Number of NANDs - not used by ROM */
+	u32 nr_die;		/* Number of separate chips in this NAND */
+	u32 celltype;		/* MLC or SLC */
+	u32 ecc_type;		/* Type of ECC, can be one of BCH-0-20 */
+	u32 ecc_nr;		/* Number of bytes for Block0 - BCH */
+
+	/* Block size in bytes for all blocks other than Block0 - BCH */
+	u32 ecc_size;
+	u32 ecc_level;		/* Ecc level for Block 0 - BCH */
+	u32 meta_size;		/* Metadata size - BCH */
+	/* Number of blocks per page for ROM use - BCH */
+	u32 nr_blocks;
+	u32 ecc_type_sdk;	/* Type of ECC, can be one of BCH-0-20 */
+	u32 ecc_nr_sdk;		/* Number of bytes for Block0 - BCH */
+	/* Block size in bytes for all blocks other than Block0 - BCH */
+	u32 ecc_size_sdk;
+	u32 ecc_level_sdk;	/* Ecc level for Block 0 - BCH */
+	/* Number of blocks per page for SDK use - BCH */
+	u32 nr_blocks_sdk;
+	u32 meta_size_sdk;	/* Metadata size - BCH */
+	u32 erase_th;		/* To set into BCH_MODE register */
+
+	/*
+	 * 0: normal boot
+	 * 1: to load patch starting next to FCB
+	 */
+	u32 bootpatch;
+	u32 patch_size;	/* Size of patch in sectors */
+	u32 fw1_start;	/* Firmware image starts on this sector */
+	u32 fw2_start;	/* Secondary FW Image starting Sector */
+	u32 fw1_pages;	/* Number of sectors in firmware image */
+	u32 fw2_pages;	/* Number of sector in secondary FW image */
+	u32 dbbt_start; /* Page address where dbbt search area begins */
+
+	/*
+	 * Byte in page data that have manufacturer marked bad block marker,
+	 * this will be swapped with metadata[0] to complete page data.
+	 */
+	u32 bb_byte;
+
+	/*
+	 * For BCH ECC sizes other than 8 and 16 the bad block marker does not
+	 * start at 0th bit of bb_byte. This field is used to get to
+	 * the start bit of bad block marker byte with in bb_byte
+	 */
+	u32 bb_start_bit;
+
+	/*
+	 * FCB value that gives byte offset for
+	 * bad block marker on physical NAND page
+	 */
+	u32 phy_offset;
+	u32 bchtype;
+
+	u32 readlatency;
+	u32 predelay;
+	u32 cedelay;
+	u32 postdelay;
+	u32 cmdaddpause;
+	u32 datapause;
+	u32 tmspeed;
+	u32 busytimeout;
+
+	/* the flag to enable (1)/disable(0) bi swap */
+	u32 disbbm;
+
+	/* The swap position of main area in spare area */
+	u32 spare_offset;
+};
+
+#endif	/* _IMX_NAND_BCB_H_ */

+ 11 - 0
arch/arm/mach-imx/Kconfig

@@ -71,6 +71,17 @@ config CMD_HDMIDETECT
 	  This enables the 'hdmidet' command which detects if an HDMI monitor
 	  is connected.
 
+config CMD_NANDBCB
+	bool "i.MX6 NAND Boot Control Block(BCB) command"
+	depends on NAND && CMD_MTDPARTS
+	default y if ARCH_MX6 && NAND_MXS
+	help
+	  Unlike normal 'nand write/erase' commands, this command update
+	  Boot Control Block(BCB) for i.MX6 platform NAND IP's.
+
+	  This is similar to kobs-ng, which is used in Linux as separate
+	  rootfs package.
+
 config NXP_BOARD_REVISION
 	bool "Read NXP board revision from fuses"
 	depends on ARCH_MX6 || ARCH_MX7

+ 1 - 0
arch/arm/mach-imx/Makefile

@@ -59,6 +59,7 @@ ifneq ($(CONFIG_SPL_BUILD),y)
 obj-$(CONFIG_CMD_BMODE) += cmd_bmode.o
 obj-$(CONFIG_CMD_HDMIDETECT) += cmd_hdmidet.o
 obj-$(CONFIG_CMD_DEKBLOB) += cmd_dek.o
+obj-$(CONFIG_CMD_NANDBCB) += cmd_nandbcb.o
 endif
 
 PLUGIN = board/$(BOARDDIR)/plugin

+ 369 - 0
arch/arm/mach-imx/cmd_nandbcb.c

@@ -0,0 +1,369 @@
+/*
+ * i.MX6 nand boot control block(bcb).
+ *
+ * Based on the common/imx-bbu-nand-fcb.c from barebox and imx kobs-ng
+ *
+ * Copyright (C) 2017 Jagan Teki <jagan@amarulasolutions.com>
+ * Copyright (C) 2016 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <nand.h>
+
+#include <asm/io.h>
+#include <jffs2/jffs2.h>
+#include <linux/mtd/mtd.h>
+
+#include <asm/mach-imx/imx-nandbcb.h>
+#include <asm/mach-imx/imximage.cfg>
+#include <mxs_nand.h>
+#include <linux/mtd/mtd.h>
+#include <nand.h>
+
+#define BF_VAL(v, bf)		(((v) & bf##_MASK) >> bf##_OFFSET)
+#define GETBIT(v, n)		(((v) >> (n)) & 0x1)
+
+static u8 calculate_parity_13_8(u8 d)
+{
+	u8 p = 0;
+
+	p |= (GETBIT(d, 6) ^ GETBIT(d, 5) ^ GETBIT(d, 3) ^ GETBIT(d, 2)) << 0;
+	p |= (GETBIT(d, 7) ^ GETBIT(d, 5) ^ GETBIT(d, 4) ^ GETBIT(d, 2) ^
+	      GETBIT(d, 1)) << 1;
+	p |= (GETBIT(d, 7) ^ GETBIT(d, 6) ^ GETBIT(d, 5) ^ GETBIT(d, 1) ^
+	      GETBIT(d, 0)) << 2;
+	p |= (GETBIT(d, 7) ^ GETBIT(d, 4) ^ GETBIT(d, 3) ^ GETBIT(d, 0)) << 3;
+	p |= (GETBIT(d, 6) ^ GETBIT(d, 4) ^ GETBIT(d, 3) ^ GETBIT(d, 2) ^
+	      GETBIT(d, 1) ^ GETBIT(d, 0)) << 4;
+
+	return p;
+}
+
+static void encode_hamming_13_8(void *_src, void *_ecc, size_t size)
+{
+	int i;
+	u8 *src = _src;
+	u8 *ecc = _ecc;
+
+	for (i = 0; i < size; i++)
+		ecc[i] = calculate_parity_13_8(src[i]);
+}
+
+static u32 calc_chksum(void *buf, size_t size)
+{
+	u32 chksum = 0;
+	u8 *bp = buf;
+	size_t i;
+
+	for (i = 0; i < size; i++)
+		chksum += bp[i];
+
+	return ~chksum;
+}
+
+static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd)
+{
+	struct nand_chip *chip = mtd_to_nand(mtd);
+	struct mxs_nand_info *nand_info = nand_get_controller_data(chip);
+
+	fcb->fingerprint = FCB_FINGERPRINT;
+	fcb->version = FCB_VERSION_1;
+	fcb->pagesize = mtd->writesize;
+	fcb->oob_pagesize = mtd->writesize + mtd->oobsize;
+	fcb->sectors = mtd->erasesize / mtd->writesize;
+
+	/* Divide ECC strength by two and save the value into FCB structure. */
+	fcb->ecc_level = nand_info->bch_geometry.ecc_strength >> 1;
+
+	fcb->ecc_type = fcb->ecc_level;
+
+	/* Also hardcoded in kobs-ng */
+	fcb->ecc_nr = 0x00000200;
+	fcb->ecc_size = 0x00000200;
+	fcb->datasetup = 80;
+	fcb->datahold = 60;
+	fcb->addr_setup = 25;
+	fcb->dsample_time = 6;
+	fcb->meta_size = 10;
+
+	/* DBBT search area starts at second page on first block */
+	fcb->dbbt_start = 1;
+
+	fcb->bb_byte = nand_info->bch_geometry.block_mark_byte_offset;
+	fcb->bb_start_bit = nand_info->bch_geometry.block_mark_bit_offset;
+
+	fcb->phy_offset = mtd->writesize;
+
+	fcb->nr_blocks = mtd->writesize / fcb->ecc_nr - 1;
+
+	fcb->checksum = calc_chksum((void *)fcb + 4, sizeof(*fcb) - 4);
+}
+
+static int dbbt_fill_data(struct mtd_info *mtd, void *buf, int num_blocks)
+{
+	int n, n_bad_blocks = 0;
+	u32 *bb = buf + 0x8;
+	u32 *n_bad_blocksp = buf + 0x4;
+
+	for (n = 0; n < num_blocks; n++) {
+		loff_t offset = n * mtd->erasesize;
+			if (mtd_block_isbad(mtd, offset)) {
+				n_bad_blocks++;
+				*bb = n;
+				bb++;
+		}
+	}
+
+	*n_bad_blocksp = n_bad_blocks;
+
+	return n_bad_blocks;
+}
+
+static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size,
+			  size_t maxsize, const u_char *buf)
+{
+	nand_erase_options_t opts;
+	struct fcb_block *fcb;
+	struct dbbt_block *dbbt;
+	loff_t fw1_off;
+	void *fwbuf, *fcb_raw_page, *dbbt_page, *dbbt_data_page;
+	int nr_blks, nr_blks_fcb, fw1_blk;
+	size_t fwsize, dummy;
+	int i, ret;
+
+	/* erase */
+	memset(&opts, 0, sizeof(opts));
+	opts.offset = off;
+	opts.length = maxsize - 1;
+	ret = nand_erase_opts(mtd, &opts);
+	if (ret) {
+		printf("%s: erase failed (ret = %d)\n", __func__, ret);
+		return ret;
+	}
+
+	/*
+	 * Reference documentation from i.MX6DQRM section 8.5.2.2
+	 *
+	 * Nand Boot Control Block(BCB) contains two data structures,
+	 * - Firmware Configuration Block(FCB)
+	 * - Discovered Bad Block Table(DBBT)
+	 *
+	 * FCB contains,
+	 * - nand timings
+	 * - DBBT search page address,
+	 * - start page address of primary firmware
+	 * - start page address of secondary firmware
+	 *
+	 * setup fcb:
+	 * - number of blocks = mtd partition size / mtd erasesize
+	 * - two firmware blocks, primary and secondary
+	 * - first 4 block for FCB/DBBT
+	 * - rest split in half for primary and secondary firmware
+	 * - same firmware will write two times
+	 */
+	nr_blks_fcb = 2;
+	nr_blks = maxsize / mtd->erasesize;
+	fw1_blk = nr_blks_fcb;
+
+	/* write fw */
+	fwsize = ALIGN(size + FLASH_OFFSET_STANDARD + mtd->writesize,
+		       mtd->writesize);
+	fwbuf = kzalloc(fwsize, GFP_KERNEL);
+	if (!fwbuf) {
+		debug("failed to allocate fwbuf\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	memcpy(fwbuf + FLASH_OFFSET_STANDARD, buf, size);
+	fw1_off = fw1_blk * mtd->erasesize;
+	ret = nand_write_skip_bad(mtd, fw1_off, &fwsize, NULL, maxsize,
+				  (u_char *)fwbuf, WITH_WR_VERIFY);
+	printf("NAND fw write: 0x%llx offset, 0x%x bytes written: %s\n",
+	       fw1_off, fwsize, ret ? "ERROR" : "OK");
+	if (ret)
+		goto fwbuf_err;
+
+	/* fill fcb */
+	fcb = kzalloc(sizeof(*fcb), GFP_KERNEL);
+	if (!fcb) {
+		debug("failed to allocate fcb\n");
+		ret = -ENOMEM;
+		goto fwbuf_err;
+	}
+
+	fcb->fw1_start = (fw1_blk * mtd->erasesize) / mtd->writesize;
+	fcb->fw1_pages = size / mtd->writesize + 1;
+	fill_fcb(fcb, mtd);
+
+	/* fill dbbt */
+	dbbt_page = kzalloc(mtd->writesize, GFP_KERNEL);
+	if (!dbbt_page) {
+		debug("failed to allocate dbbt_page\n");
+		ret = -ENOMEM;
+		goto fcb_err;
+	}
+
+	dbbt_data_page = kzalloc(mtd->writesize, GFP_KERNEL);
+	if (!dbbt_data_page) {
+		debug("failed to allocate dbbt_data_page\n");
+		ret = -ENOMEM;
+		goto dbbt_page_err;
+	}
+
+	dbbt = dbbt_page;
+	dbbt->checksum = 0;
+	dbbt->fingerprint = DBBT_FINGERPRINT2;
+	dbbt->version = DBBT_VERSION_1;
+	ret = dbbt_fill_data(mtd, dbbt_data_page, nr_blks);
+	if (ret < 0)
+		goto dbbt_data_page_err;
+	else if (ret > 0)
+		dbbt->dbbtpages = 1;
+
+	/* write fcb/dbbt */
+	fcb_raw_page = kzalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
+	if (!fcb_raw_page) {
+		debug("failed to allocate fcb_raw_page\n");
+		ret = -ENOMEM;
+		goto dbbt_data_page_err;
+	}
+
+	memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block));
+	encode_hamming_13_8(fcb_raw_page + 12, fcb_raw_page + 12 + 512, 512);
+	/*
+	 * Set the first and second byte of OOB data to 0xFF, not 0x00. These
+	 * bytes are used as the Manufacturers Bad Block Marker (MBBM). Since
+	 * the FCB is mostly written to the first page in a block, a scan for
+	 * factory bad blocks will detect these blocks as bad, e.g. when
+	 * function nand_scan_bbt() is executed to build a new bad block table.
+	 */
+	memset(fcb_raw_page + mtd->writesize, 0xFF, 2);
+
+	for (i = 0; i < nr_blks_fcb; i++) {
+		if (mtd_block_isbad(mtd, off)) {
+			printf("Block %d is bad, skipped\n", i);
+			continue;
+		}
+
+		/* raw write */
+		mtd_oob_ops_t ops = {
+			.datbuf = (u8 *)fcb_raw_page,
+			.oobbuf = ((u8 *)fcb_raw_page) + mtd->writesize,
+			.len = mtd->writesize,
+			.ooblen = mtd->oobsize,
+			.mode = MTD_OPS_RAW
+		};
+
+		ret = mtd_write_oob(mtd, mtd->erasesize * i, &ops);
+		if (ret)
+			goto fcb_raw_page_err;
+		debug("NAND fcb write: 0x%x offset, 0x%x bytes written: %s\n",
+		      mtd->erasesize * i, ops.len, ret ? "ERROR" : "OK");
+
+		ret = mtd_write(mtd, mtd->erasesize * i + mtd->writesize,
+				mtd->writesize, &dummy, dbbt_page);
+		if (ret)
+			goto fcb_raw_page_err;
+		debug("NAND dbbt write: 0x%x offset, 0x%x bytes written: %s\n",
+		      mtd->erasesize * i + mtd->writesize, dummy,
+		      ret ? "ERROR" : "OK");
+
+		/* dbbtpages == 0 if no bad blocks */
+		if (dbbt->dbbtpages > 0) {
+			loff_t to = (mtd->erasesize * i + mtd->writesize * 5);
+
+			ret = mtd_write(mtd, to, mtd->writesize, &dummy,
+					dbbt_data_page);
+			if (ret)
+				goto fcb_raw_page_err;
+		}
+	}
+
+fcb_raw_page_err:
+	kfree(fcb_raw_page);
+dbbt_data_page_err:
+	kfree(dbbt_data_page);
+dbbt_page_err:
+	kfree(dbbt_page);
+fcb_err:
+	kfree(fcb);
+fwbuf_err:
+	kfree(fwbuf);
+err:
+	return ret;
+}
+
+static int do_nandbcb_update(int argc, char * const argv[])
+{
+	struct mtd_info *mtd;
+	loff_t addr, offset, size, maxsize;
+	char *endp;
+	u_char *buf;
+	int dev;
+	int ret;
+
+	if (argc != 4)
+		return CMD_RET_USAGE;
+
+	dev = nand_curr_device;
+	if (dev < 0) {
+		printf("failed to get nand_curr_device, run nand device");
+		return CMD_RET_FAILURE;
+	}
+
+	addr = simple_strtoul(argv[1], &endp, 16);
+	if (*argv[1] == 0 || *endp != 0)
+		return CMD_RET_FAILURE;
+
+	mtd = get_nand_dev_by_index(dev);
+	if (mtd_arg_off_size(argc - 2, argv + 2, &dev, &offset, &size,
+			     &maxsize, MTD_DEV_TYPE_NAND, mtd->size))
+		return CMD_RET_FAILURE;
+
+	buf = map_physmem(addr, size, MAP_WRBACK);
+	if (!buf) {
+		puts("failed to map physical memory\n");
+		return CMD_RET_FAILURE;
+	}
+
+	ret = nandbcb_update(mtd, offset, size, maxsize, buf);
+
+	return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
+}
+
+static int do_nandbcb(cmd_tbl_t *cmdtp, int flag, int argc,
+		      char * const argv[])
+{
+	const char *cmd;
+	int ret = 0;
+
+	if (argc < 5)
+		goto usage;
+
+	cmd = argv[1];
+	--argc;
+	++argv;
+
+	if (strcmp(cmd, "update") == 0) {
+		ret = do_nandbcb_update(argc, argv);
+		goto done;
+	}
+
+done:
+	if (ret != -1)
+		return ret;
+usage:
+	return CMD_RET_USAGE;
+}
+
+static char nandbcb_help_text[] =
+	"update addr off|partition len	- update 'len' bytes starting at\n"
+	"	'off|part' to memory address 'addr', skipping  bad blocks";
+
+U_BOOT_CMD(nandbcb, 5, 1, do_nandbcb,
+	   "i.MX6 Nand BCB",
+	   nandbcb_help_text
+);

+ 4 - 2
arch/arm/mach-imx/cpu.c

@@ -289,10 +289,12 @@ void arch_preboot_os(void)
 	imx_pcie_remove();
 #endif
 #if defined(CONFIG_SATA)
-	sata_remove(0);
+	if (!is_mx6sdl()) {
+		sata_remove(0);
 #if defined(CONFIG_MX6)
-	disable_sata_clock();
+		disable_sata_clock();
 #endif
+	}
 #endif
 #if defined(CONFIG_VIDEO_IPUV3)
 	/* disable video before launching O/S */

+ 1 - 1
arch/arm/mach-imx/imx8/Makefile

@@ -4,4 +4,4 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-obj-y += cpu.o iomux.o
+obj-y += cpu.o iomux.o misc.o

+ 39 - 0
arch/arm/mach-imx/imx8/misc.c

@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0+
+#include <common.h>
+#include <asm/arch/sci/sci.h>
+
+int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate)
+{
+	sc_pm_clock_rate_t rate = clk_rate;
+	int ret;
+
+	/* Power up UARTn */
+	ret = sc_pm_set_resource_power_mode(-1, uart_rsrc, SC_PM_PW_MODE_ON);
+	if (ret)
+		return ret;
+
+	/* Set UARTn clock root to 'rate' MHz */
+	ret = sc_pm_set_clock_rate(-1, uart_rsrc, SC_PM_CLK_PER, &rate);
+	if (ret)
+		return ret;
+
+	/* Enable UARTn clock root */
+	ret = sc_pm_clock_enable(-1, uart_rsrc, SC_PM_CLK_PER, true, false);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+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 if build info not supported */
+	}
+	printf("Build: SCFW %x\n", sc_commit);
+}

+ 5 - 0
arch/arm/mach-imx/mx6/soc.c

@@ -95,6 +95,11 @@ u32 get_cpu_rev(void)
 			type = MXC_CPU_MX6DP;
 	}
 	reg &= 0xff;		/* mx6 silicon revision */
+
+	/* For 6DQ, the value 0x00630005 is Silicon revision 1.3*/
+	if (((type == MXC_CPU_MX6Q) || (type == MXC_CPU_MX6D)) && (reg == 0x5))
+		reg = 0x3;
+
 	return (type << 12) | (reg + (0x10 * (major + 1)));
 }
 

+ 5 - 3
arch/arm/mach-imx/spl.c

@@ -24,6 +24,7 @@ u32 spl_boot_device(void)
 {
 	unsigned int bmode = readl(&src_base->sbmr2);
 	u32 reg = imx6_src_get_boot_mode();
+	u32 mmc_index = ((reg >> 11) & 0x03);
 
 	/*
 	 * Check for BMODE if serial downloader is enabled
@@ -84,11 +85,12 @@ u32 spl_boot_device(void)
 	/* SD/eSD: 8.5.3, Table 8-15  */
 	case IMX6_BMODE_SD:
 	case IMX6_BMODE_ESD:
-		return BOOT_DEVICE_MMC1;
-	/* MMC/eMMC: 8.5.3 */
 	case IMX6_BMODE_MMC:
 	case IMX6_BMODE_EMMC:
-		return BOOT_DEVICE_MMC1;
+		if (mmc_index == 1)
+			return BOOT_DEVICE_MMC2;
+		else
+			return BOOT_DEVICE_MMC1;
 	/* NAND Flash: 8.5.2, Table 8-10 */
 	case IMX6_BMODE_NAND_MIN ... IMX6_BMODE_NAND_MAX:
 		return BOOT_DEVICE_NAND;

+ 10 - 0
arch/sandbox/dts/test.dts

@@ -211,6 +211,12 @@
 			clock-mult = <2>;
 			clocks = <&clk_fixed>;
 		};
+
+		osc {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <20000000>;
+		};
 	};
 
 	clk_sandbox: clk-sbox {
@@ -226,6 +232,10 @@
 		clock-names = "fixed", "i2c", "spi";
 	};
 
+	ccf: clk-ccf {
+		compatible = "sandbox,clk-ccf";
+	};
+
 	eth@10002000 {
 		compatible = "sandbox,eth";
 		reg = <0x10002000 0x1000>;

+ 0 - 21
board/armadeus/opos6uldev/board.c

@@ -70,27 +70,6 @@ int setup_lcd(void)
 }
 #endif
 
-#ifdef CONFIG_USB_EHCI_MX6
-#define USB_OTHERREGS_OFFSET	0x800
-#define UCTRL_PWR_POL		(1 << 9)
-
-int board_ehci_hcd_init(int port)
-{
-	u32 *usbnc_usb_ctrl;
-
-	if (port > 1)
-		return -EINVAL;
-
-	usbnc_usb_ctrl = (u32 *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET +
-				 port * 4);
-
-	/* Set Power polarity */
-	setbits_le32(usbnc_usb_ctrl, UCTRL_PWR_POL);
-
-	return 0;
-}
-#endif
-
 int opos6ul_board_late_init(void)
 {
 #ifdef CONFIG_VIDEO_MXS

+ 27 - 120
board/dhelectronics/dh_imx6/dh_imx6.c

@@ -18,7 +18,6 @@
 #include <asm/io.h>
 #include <asm/mach-imx/boot_mode.h>
 #include <asm/mach-imx/iomux-v3.h>
-#include <asm/mach-imx/mxc_i2c.h>
 #include <asm/mach-imx/sata.h>
 #include <ahci.h>
 #include <dwc_ahsata.h>
@@ -26,7 +25,7 @@
 #include <errno.h>
 #include <fsl_esdhc_imx.h>
 #include <fuse.h>
-#include <i2c.h>
+#include <i2c_eeprom.h>
 #include <miiphy.h>
 #include <mmc.h>
 #include <net.h>
@@ -36,92 +35,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#define I2C_PAD_CTRL							\
-	(PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |	\
-	PAD_CTL_HYS | PAD_CTL_ODE | PAD_CTL_SRE_FAST)
-
-#define EEPROM_I2C_ADDRESS	0x50
-
-#define PC			MUX_PAD_CTRL(I2C_PAD_CTRL)
-
-static struct i2c_pads_info dh6sdl_i2c_pad_info0 = {
-	.scl = {
-		.i2c_mode  = MX6DL_PAD_EIM_D21__I2C1_SCL | PC,
-		.gpio_mode = MX6DL_PAD_EIM_D21__GPIO3_IO21 | PC,
-		.gp = IMX_GPIO_NR(3, 21)
-	},
-	.sda = {
-		 .i2c_mode = MX6DL_PAD_EIM_D28__I2C1_SDA | PC,
-		 .gpio_mode = MX6DL_PAD_EIM_D28__GPIO3_IO28 | PC,
-		 .gp = IMX_GPIO_NR(3, 28)
-	 }
-};
-
-static struct i2c_pads_info dh6sdl_i2c_pad_info1 = {
-	.scl = {
-		.i2c_mode  = MX6DL_PAD_KEY_COL3__I2C2_SCL | PC,
-		.gpio_mode = MX6DL_PAD_KEY_COL3__GPIO4_IO12 | PC,
-		.gp = IMX_GPIO_NR(4, 12)
-	},
-	.sda = {
-		 .i2c_mode = MX6DL_PAD_KEY_ROW3__I2C2_SDA | PC,
-		 .gpio_mode = MX6DL_PAD_KEY_ROW3__GPIO4_IO13 | PC,
-		 .gp = IMX_GPIO_NR(4, 13)
-	 }
-};
-
-static struct i2c_pads_info dh6sdl_i2c_pad_info2 = {
-	.scl = {
-		.i2c_mode  = MX6DL_PAD_GPIO_3__I2C3_SCL | PC,
-		.gpio_mode = MX6DL_PAD_GPIO_3__GPIO1_IO03 | PC,
-		.gp = IMX_GPIO_NR(1, 3)
-	},
-	.sda = {
-		 .i2c_mode = MX6DL_PAD_GPIO_6__I2C3_SDA | PC,
-		 .gpio_mode = MX6DL_PAD_GPIO_6__GPIO1_IO06 | PC,
-		 .gp = IMX_GPIO_NR(1, 6)
-	 }
-};
-
-static struct i2c_pads_info dh6dq_i2c_pad_info0 = {
-	.scl = {
-		.i2c_mode  = MX6Q_PAD_EIM_D21__I2C1_SCL | PC,
-		.gpio_mode = MX6Q_PAD_EIM_D21__GPIO3_IO21 | PC,
-		.gp = IMX_GPIO_NR(3, 21)
-	},
-	.sda = {
-		 .i2c_mode = MX6Q_PAD_EIM_D28__I2C1_SDA | PC,
-		 .gpio_mode = MX6Q_PAD_EIM_D28__GPIO3_IO28 | PC,
-		 .gp = IMX_GPIO_NR(3, 28)
-	 }
-};
-
-static struct i2c_pads_info dh6dq_i2c_pad_info1 = {
-	.scl = {
-		.i2c_mode  = MX6Q_PAD_KEY_COL3__I2C2_SCL | PC,
-		.gpio_mode = MX6Q_PAD_KEY_COL3__GPIO4_IO12 | PC,
-		.gp = IMX_GPIO_NR(4, 12)
-	},
-	.sda = {
-		 .i2c_mode = MX6Q_PAD_KEY_ROW3__I2C2_SDA | PC,
-		 .gpio_mode = MX6Q_PAD_KEY_ROW3__GPIO4_IO13 | PC,
-		 .gp = IMX_GPIO_NR(4, 13)
-	 }
-};
-
-static struct i2c_pads_info dh6dq_i2c_pad_info2 = {
-	.scl = {
-		.i2c_mode  = MX6Q_PAD_GPIO_3__I2C3_SCL | PC,
-		.gpio_mode = MX6Q_PAD_GPIO_3__GPIO1_IO03 | PC,
-		.gp = IMX_GPIO_NR(1, 3)
-	},
-	.sda = {
-		 .i2c_mode = MX6Q_PAD_GPIO_6__I2C3_SDA | PC,
-		 .gpio_mode = MX6Q_PAD_GPIO_6__GPIO1_IO06 | PC,
-		 .gp = IMX_GPIO_NR(1, 6)
-	 }
-};
-
 int dram_init(void)
 {
 	gd->ram_size = imx_ddr_size();
@@ -196,7 +109,6 @@ int board_eth_init(bd_t *bis)
 #ifdef CONFIG_USB_EHCI_MX6
 static void setup_usb(void)
 {
-	gpio_request(IMX_GPIO_NR(3, 31), "USB-VBUS");
 	/*
 	 * Set daisy chain for otg_pin_id on MX6Q.
 	 * For MX6DL, this bit is reserved.
@@ -211,26 +123,12 @@ int board_usb_phy_mode(int port)
 	else
 		return USB_INIT_DEVICE;
 }
-
-int board_ehci_power(int port, int on)
-{
-	switch (port) {
-	case 0:
-		break;
-	case 1:
-		gpio_direction_output(IMX_GPIO_NR(3, 31), !!on);
-		break;
-	default:
-		printf("MXC USB port %d not yet supported\n", port);
-		return -EINVAL;
-	}
-
-	return 0;
-}
 #endif
 
 static int setup_dhcom_mac_from_fuse(void)
 {
+	struct udevice *dev;
+	ofnode eeprom;
 	unsigned char enetaddr[6];
 	int ret;
 
@@ -245,13 +143,19 @@ static int setup_dhcom_mac_from_fuse(void)
 		return 0;
 	}
 
-	ret = i2c_set_bus_num(2);
+	eeprom = ofnode_path("/soc/aips-bus@2100000/i2c@21a8000/eeprom@50");
+	if (!ofnode_valid(eeprom)) {
+		printf("Invalid hardware path to EEPROM!\n");
+		return -ENODEV;
+	}
+
+	ret = uclass_get_device_by_ofnode(UCLASS_I2C_EEPROM, eeprom, &dev);
 	if (ret) {
-		printf("Error switching I2C bus!\n");
+		printf("Cannot find EEPROM!\n");
 		return ret;
 	}
 
-	ret = i2c_read(EEPROM_I2C_ADDRESS, 0xfa, 0x1, enetaddr, 0x6);
+	ret = i2c_eeprom_read(dev, 0xfa, enetaddr, 0x6);
 	if (ret) {
 		printf("Error reading configuration EEPROM!\n");
 		return ret;
@@ -282,18 +186,6 @@ int board_init(void)
 	/* Enable eim_slow clocks */
 	setbits_le32(&mxc_ccm->CCGR6, 0x1 << MXC_CCM_CCGR6_EMI_SLOW_OFFSET);
 
-#ifdef CONFIG_SYS_I2C_MXC
-	if (is_mx6dq()) {
-		setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &dh6dq_i2c_pad_info0);
-		setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &dh6dq_i2c_pad_info1);
-		setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &dh6dq_i2c_pad_info2);
-	} else {
-		setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &dh6sdl_i2c_pad_info0);
-		setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &dh6sdl_i2c_pad_info1);
-		setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &dh6sdl_i2c_pad_info2);
-	}
-#endif
-
 	setup_dhcom_mac_from_fuse();
 
 	return 0;
@@ -372,3 +264,18 @@ int checkboard(void)
 	puts("Board: DHCOM i.MX6\n");
 	return 0;
 }
+
+#ifdef CONFIG_MULTI_DTB_FIT
+int board_fit_config_name_match(const char *name)
+{
+	if (is_mx6dq()) {
+		if (!strcmp(name, "imx6q-dhcom-pdk2"))
+			return 0;
+	} else if (is_mx6sdl()) {
+		if (!strcmp(name, "imx6dl-dhcom-pdk2"))
+			return 0;
+	}
+
+	return -1;
+}
+#endif

+ 7 - 2
board/dhelectronics/dh_imx6/dh_imx6_spl.c

@@ -440,8 +440,13 @@ static void setup_iomux_sd(void)
 
 /* SPI */
 static iomux_v3_cfg_t const ecspi1_pads[] = {
-	/* SS0 */
-	IOMUX_PADS(PAD_EIM_EB2__GPIO2_IO30	| MUX_PAD_CTRL(SPI_PAD_CTRL)),
+	/* SS0 - SS of boot flash */
+	IOMUX_PADS(PAD_EIM_EB2__GPIO2_IO30	|
+		MUX_PAD_CTRL(SPI_PAD_CTRL | PAD_CTL_PUS_100K_UP)),
+	/* SS2 - SS of DHCOM SPI1 */
+	IOMUX_PADS(PAD_KEY_ROW2__GPIO4_IO11	|
+		MUX_PAD_CTRL(SPI_PAD_CTRL | PAD_CTL_PUS_100K_UP)),
+
 	IOMUX_PADS(PAD_EIM_D17__ECSPI1_MISO	| MUX_PAD_CTRL(SPI_PAD_CTRL)),
 	IOMUX_PADS(PAD_EIM_D18__ECSPI1_MOSI	| MUX_PAD_CTRL(SPI_PAD_CTRL)),
 	IOMUX_PADS(PAD_EIM_D16__ECSPI1_SCLK	| MUX_PAD_CTRL(SPI_PAD_CTRL)),

+ 0 - 2
board/engicam/common/board.c

@@ -53,8 +53,6 @@ static void setenv_fdt_file(void)
 			env_set("fdt_file", "imx6dl-icore-rqs.dtb");
 	} else if (!strcmp(cmp_dtb, "imx6ul-geam"))
 		env_set("fdt_file", "imx6ul-geam.dtb");
-	else if (!strcmp(cmp_dtb, "imx6ul-isiot-mmc"))
-		env_set("fdt_file", "imx6ul-isiot-emmc.dtb");
 	else if (!strcmp(cmp_dtb, "imx6ul-isiot-emmc"))
 		env_set("fdt_file", "imx6ul-isiot-emmc.dtb");
 	else if (!strcmp(cmp_dtb, "imx6ul-isiot-nand"))

+ 3 - 26
board/freescale/imx8qm_mek/imx8qm_mek.c

@@ -34,21 +34,11 @@ static void setup_iomux_uart(void)
 
 int board_early_init_f(void)
 {
+	sc_pm_clock_rate_t rate = SC_80MHZ;
 	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);
+	/* Set UART0 clock root to 80 MHz */
+	ret = sc_pm_setup_uart(SC_R_UART_0, rate);
 	if (ret)
 		return ret;
 
@@ -88,19 +78,6 @@ int board_phy_config(struct phy_device *phydev)
 }
 #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: iMX8QM MEK\n");

+ 3 - 26
board/freescale/imx8qxp_mek/imx8qxp_mek.c

@@ -40,21 +40,11 @@ static void setup_iomux_uart(void)
 
 int board_early_init_f(void)
 {
+	sc_pm_clock_rate_t rate = SC_80MHZ;
 	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);
+	/* Set UART0 clock root to 80 MHz */
+	ret = sc_pm_setup_uart(SC_R_UART_0, rate);
 	if (ret)
 		return ret;
 
@@ -104,19 +94,6 @@ int board_phy_config(struct phy_device *phydev)
 }
 #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");

+ 7 - 0
board/freescale/mx6sxsabresd/imximage.cfg

@@ -17,6 +17,13 @@ IMAGE_VERSION 2
 
 BOOT_FROM	sd
 
+/*
+ * Secure boot support
+ */
+#ifdef CONFIG_SECURE_BOOT
+CSF CONFIG_CSF_SIZE
+#endif
+
 /*
  * Device Configuration Data (DCD)
  *

+ 6 - 11
board/freescale/mx7ulp_evk/imximage.cfg

@@ -45,12 +45,12 @@ DATA 4   0x403f00dc 0x00000000
 DATA 4   0x403e0040 0x01000020
 DATA 4   0x403e0500 0x01000000
 DATA 4   0x403e050c 0x80808080
-DATA 4   0x403e0508 0x00140000
-DATA 4   0x403E0510 0x00000004
-DATA 4   0x403E0514 0x00000002
+DATA 4   0x403e0508 0x00160002
+DATA 4   0x403E0510 0x00000001
+DATA 4   0x403E0514 0x00000014
 DATA 4   0x403e0500 0x00000001
 CHECK_BITS_SET 4 0x403e0500 0x01000000
-DATA 4   0x403e050c 0x8080801E
+DATA 4   0x403e050c 0x8080801B
 CHECK_BITS_SET 4 0x403e050c 0x00000040
 DATA 4   0x403E0030 0x00000001
 DATA 4   0x403e0040 0x11000020
@@ -94,11 +94,6 @@ DATA 4   0x40AB0820 0x33333333
 DATA 4   0x40AB0824 0x33333333
 DATA 4   0x40AB0828 0x33333333
 
-DATA 4   0x40AB082C 0xf3333333
-DATA 4   0x40AB0830 0xf3333333
-DATA 4   0x40AB0834 0xf3333333
-DATA 4   0x40AB0838 0xf3333333
-
 DATA 4   0x40AB08C0 0x24922492
 DATA 4   0x40AB08B8 0x00000800
 
@@ -113,8 +108,8 @@ DATA 4   0x40AB0030 0x009F0E10
 DATA 4   0x40AB0040 0x0000003F
 DATA 4   0x40AB0000 0xC3190000
 
-DATA 4   0x40AB001C 0x00008050
-DATA 4   0x40AB001C 0x00008058
+DATA 4   0x40AB001C 0x00008010
+DATA 4   0x40AB001C 0x00008018
 DATA 4   0x40AB001C 0x003F8030
 DATA 4   0x40AB001C 0x003F8038
 DATA 4   0x40AB001C 0xFF0A8030

+ 8 - 15
board/freescale/mx7ulp_evk/plugin.S

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2019 NXP
  */
 
 #include <config.h>
@@ -15,13 +16,14 @@
 	str r3, [r2, #0x40]
 	ldr r3, =0x01000000
 	str r3, [r2, #0x500]
+
 	ldr r3, =0x80808080
 	str r3, [r2, #0x50c]
-	ldr r3, =0x00140000
+	ldr r3, =0x00160002
 	str r3, [r2, #0x508]
-	ldr r3, =0x00000004
+	ldr r3, =0x00000001
 	str r3, [r2, #0x510]
-	ldr r3, =0x00000002
+	ldr r3, =0x00000014
 	str r3, [r2, #0x514]
 	ldr r3, =0x00000001
 	str r3, [r2, #0x500]
@@ -33,7 +35,7 @@ wait1:
 	cmp r4, r3
 	bne wait1
 
-	ldr r3, =0x8080801E
+	ldr r3, =0x8080801B
 	str r3, [r2, #0x50c]
 
 	ldr r3, =0x00000040
@@ -132,15 +134,6 @@ wait2:
 	ldr r1, =0x33333333
 	str r1, [r0, #0x828]
 
-	ldr r1, =0xf3333333
-	str r1, [r0, #0x82c]
-	ldr r1, =0xf3333333
-	str r1, [r0, #0x830]
-	ldr r1, =0xf3333333
-	str r1, [r0, #0x834]
-	ldr r1, =0xf3333333
-	str r1, [r0, #0x838]
-
 	ldr r1, =0x24922492
 	str r1, [r0, #0x8c0]
 	ldr r1, =0x00000800
@@ -168,9 +161,9 @@ wait2:
 	ldr r1, =0xC3190000
 	str r1, [r0, #0x0]
 
-	ldr r1, =0x00008050
+	ldr r1, =0x00008010
 	str r1, [r0, #0x1c]
-	ldr r1, =0x00008058
+	ldr r1, =0x00008018
 	str r1, [r0, #0x1c]
 	ldr r1, =0x003F8030
 	str r1, [r0, #0x1c]

+ 1 - 1
board/liebherr/display5/common.c

@@ -68,7 +68,7 @@ iomux_v3_cfg_t const ecspi2_pads[] = {
 
 int board_spi_cs_gpio(unsigned int bus, unsigned int cs)
 {
-	if (bus != 1 || cs != (IMX_GPIO_NR(5, 29) << 8))
+	if (bus != 1 || cs != 0)
 		return -EINVAL;
 
 	return IMX_GPIO_NR(5, 29);

+ 0 - 9
board/liebherr/display5/display5.c

@@ -413,12 +413,3 @@ int misc_init_r(void)
 
 	return 0;
 }
-
-static struct mxc_serial_platdata mxc_serial_plat = {
-	.reg = (struct mxc_uart *)UART5_BASE,
-};
-
-U_BOOT_DEVICE(mxc_serial) = {
-	.name = "serial_mxc",
-	.platdata = &mxc_serial_plat,
-};

+ 1 - 11
board/logicpd/imx6/imx6logic.c

@@ -223,25 +223,15 @@ int board_mmc_init(bd_t *bis)
 	switch (reg) {
 	case 0:
 		SETUP_IOMUX_PADS(usdhc1_pads);
-		usdhc_cfg[0].esdhc_base = USDHC1_BASE_ADDR;
-		usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
-		gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
 		break;
 	case 1:
 		SETUP_IOMUX_PADS(usdhc2_pads);
-		usdhc_cfg[1].esdhc_base = USDHC2_BASE_ADDR;
-		usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
-		gd->arch.sdhc_clk = usdhc_cfg[1].sdhc_clk;
 		break;
 	}
 
-	return fsl_esdhc_initialize(bis, &usdhc_cfg[reg]);
+	return 0;
 }
 
-int board_mmc_getcd(struct mmc *mmc)
-{
-	return 1;
-}
 #endif
 
 static void ccgr_init(void)

+ 0 - 13
board/technexion/pico-imx7d/pico-imx7d.c

@@ -16,7 +16,6 @@
 #include <i2c.h>
 #include <miiphy.h>
 #include <netdev.h>
-#include <usb.h>
 #include <power/pmic.h>
 #include <power/pfuze3000_pmic.h>
 #include "../../freescale/common/pfuze.h"
@@ -328,15 +327,3 @@ int board_ehci_hcd_init(int port)
 	return 0;
 }
 
-int board_usb_phy_mode(int port)
-{
-	switch (port) {
-	case 0:
-		return USB_INIT_DEVICE;
-	case 1:
-		return USB_INIT_HOST;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}

+ 3 - 27
board/toradex/apalis-imx8/apalis-imx8.c

@@ -37,22 +37,11 @@ static void setup_iomux_uart(void)
 
 int board_early_init_f(void)
 {
-	sc_pm_clock_rate_t rate;
+	sc_pm_clock_rate_t rate = SC_80MHZ;
 	sc_err_t err = 0;
 
-	/* Power up UART1 */
-	err = sc_pm_set_resource_power_mode(-1, SC_R_UART_1, SC_PM_PW_MODE_ON);
-	if (err != SC_ERR_NONE)
-		return 0;
-
-	/* Set UART3 clock root to 80 MHz */
-	rate = 80000000;
-	err = sc_pm_set_clock_rate(-1, SC_R_UART_1, SC_PM_CLK_PER, &rate);
-	if (err != SC_ERR_NONE)
-		return 0;
-
-	/* Enable UART1 clock root */
-	err = sc_pm_clock_enable(-1, SC_R_UART_1, SC_PM_CLK_PER, true, false);
+	/* Set UART1 clock root to 80 MHz and enable it */
+	err = sc_pm_setup_uart(SC_R_UART_1, rate);
 	if (err != SC_ERR_NONE)
 		return 0;
 
@@ -82,19 +71,6 @@ int board_phy_config(struct phy_device *phydev)
 }
 #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 if build info not supported */
-	}
-	printf("Build: SCFW %x\n", sc_commit);
-}
-
 int checkboard(void)
 {
 	puts("Model: Toradex Apalis iMX8\n");

+ 3 - 26
board/toradex/colibri-imx8x/colibri-imx8x.c

@@ -51,19 +51,9 @@ int board_early_init_f(void)
 	if (err != SC_ERR_NONE)
 		return 0;
 
-	/* Power up UART3 */
-	err = sc_pm_set_resource_power_mode(-1, SC_R_UART_3, SC_PM_PW_MODE_ON);
-	if (err != SC_ERR_NONE)
-		return 0;
-
-	/* Set UART3 clock root to 80 MHz */
-	rate = 80000000;
-	err = sc_pm_set_clock_rate(-1, SC_R_UART_3, SC_PM_CLK_PER, &rate);
-	if (err != SC_ERR_NONE)
-		return 0;
-
-	/* Enable UART3 clock root */
-	err = sc_pm_clock_enable(-1, SC_R_UART_3, SC_PM_CLK_PER, true, false);
+	/* Set UART3 clock root to 80 MHz and enable it */
+	rate = SC_80MHZ;
+	err = sc_pm_setup_uart(SC_R_UART_3, rate);
 	if (err != SC_ERR_NONE)
 		return 0;
 
@@ -93,19 +83,6 @@ int board_phy_config(struct phy_device *phydev)
 }
 #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 if build info not supported */
-	}
-	printf("Build: SCFW %x\n", sc_commit);
-}
-
 int checkboard(void)
 {
 	puts("Model: Toradex Colibri iMX8X\n");

+ 46 - 20
board/toradex/common/tdx-cfg-block.c

@@ -7,8 +7,9 @@
 #include "tdx-cfg-block.h"
 
 #if defined(CONFIG_TARGET_APALIS_IMX6) || \
+	defined(CONFIG_TARGET_APALIS_IMX8) || \
 	defined(CONFIG_TARGET_COLIBRI_IMX6) || \
-	defined(CONFIG_TARGET_COLIBRI_IMX8QXP)
+	defined(CONFIG_TARGET_COLIBRI_IMX8X)
 #include <asm/arch/sys_proto.h>
 #else
 #define is_cpu_type(cpu) (0)
@@ -129,6 +130,10 @@ static int tdx_cfg_block_mmc_storage(u8 *config_block, int write)
 		ret = -ENODEV;
 		goto out;
 	}
+	if (mmc_init(mmc)) {
+		puts("MMC init failed\n");
+		return -EINVAL;
+	}
 	if (part != mmc_get_blk_desc(mmc)->hwpart) {
 		if (blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part)) {
 			puts("MMC partition switch failed\n");
@@ -287,6 +292,7 @@ static int get_cfgblock_interactive(void)
 	char message[CONFIG_SYS_CBSIZE];
 	char *soc;
 	char it = 'n';
+	char wb = 'n';
 	int len;
 
 	/* Unknown module by default */
@@ -296,10 +302,17 @@ static int get_cfgblock_interactive(void)
 		sprintf(message, "Is the module the 312 MHz version? [y/N] ");
 	else
 		sprintf(message, "Is the module an IT version? [y/N] ");
-
 	len = cli_readline(message);
 	it = console_buffer[0];
 
+#if defined(CONFIG_TARGET_APALIS_IMX8) || \
+		defined(CONFIG_TARGET_COLIBRI_IMX6ULL) || \
+		defined(CONFIG_TARGET_COLIBRI_IMX8X)
+	sprintf(message, "Does the module have Wi-Fi / Bluetooth? [y/N] ");
+	len = cli_readline(message);
+	wb = console_buffer[0];
+#endif
+
 	soc = env_get("soc");
 	if (!strcmp("mx6", soc)) {
 #ifdef CONFIG_TARGET_APALIS_IMX6
@@ -327,12 +340,6 @@ static int get_cfgblock_interactive(void)
 				tdx_hw_tag.prodid = COLIBRI_IMX6S;
 		}
 #elif CONFIG_TARGET_COLIBRI_IMX6ULL
-		char wb = 'n';
-
-		sprintf(message, "Does the module have Wi-Fi / Bluetooth? " \
-				 "[y/N] ");
-		len = cli_readline(message);
-		wb = console_buffer[0];
 		if (it == 'y' || it == 'Y') {
 			if (wb == 'y' || wb == 'Y')
 				tdx_hw_tag.prodid = COLIBRI_IMX6ULL_WIFI_BT_IT;
@@ -349,9 +356,31 @@ static int get_cfgblock_interactive(void)
 		tdx_hw_tag.prodid = COLIBRI_IMX7D;
 	else if (!strcmp("imx7s", soc))
 		tdx_hw_tag.prodid = COLIBRI_IMX7S;
-	else if (is_cpu_type(MXC_CPU_IMX8QXP))
-		tdx_hw_tag.prodid = COLIBRI_IMX8QXP_WIFI_BT_IT;
-	else if (!strcmp("tegra20", soc)) {
+	else if (is_cpu_type(MXC_CPU_IMX8QM)) {
+		if (it == 'y' || it == 'Y') {
+			if (wb == 'y' || wb == 'Y')
+				tdx_hw_tag.prodid = APALIS_IMX8QM_WIFI_BT_IT;
+			else
+				tdx_hw_tag.prodid = APALIS_IMX8QM_IT;
+		} else {
+			if (wb == 'y' || wb == 'Y')
+				tdx_hw_tag.prodid = APALIS_IMX8QP_WIFI_BT;
+			else
+				tdx_hw_tag.prodid = APALIS_IMX8QP;
+		}
+	} else if (is_cpu_type(MXC_CPU_IMX8QXP)) {
+		if (it == 'y' || it == 'Y') {
+			if (wb == 'y' || wb == 'Y')
+				tdx_hw_tag.prodid = COLIBRI_IMX8QXP_WIFI_BT_IT;
+			else
+				tdx_hw_tag.prodid = COLIBRI_IMX8QXP_IT;
+		} else {
+			if (wb == 'y' || wb == 'Y')
+				tdx_hw_tag.prodid = COLIBRI_IMX8DX_WIFI_BT;
+			else
+				tdx_hw_tag.prodid = COLIBRI_IMX8DX;
+		}
+	} else if (!strcmp("tegra20", soc)) {
 		if (it == 'y' || it == 'Y')
 			if (gd->ram_size == 0x10000000)
 				tdx_hw_tag.prodid = COLIBRI_T20_256MB_IT;
@@ -482,8 +511,7 @@ static int do_cfgblock_create(cmd_tbl_t *cmdtp, int flag, int argc,
 		 * On NAND devices, recreation is only allowed if the page is
 		 * empty (config block invalid...)
 		 */
-		printf("NAND erase block %d need to be erased before creating" \
-		       " a Toradex config block\n",
+		printf("NAND erase block %d need to be erased before creating a Toradex config block\n",
 		       CONFIG_TDX_CFG_BLOCK_OFFSET /
 		       get_nand_dev_by_index(0)->erasesize);
 		goto out;
@@ -492,8 +520,7 @@ static int do_cfgblock_create(cmd_tbl_t *cmdtp, int flag, int argc,
 		 * On NOR devices, recreation is only allowed if the sector is
 		 * empty and write protection is off (config block invalid...)
 		 */
-		printf("NOR sector at offset 0x%02x need to be erased and " \
-		       "unprotected before creating a Toradex config block\n",
+		printf("NOR sector at offset 0x%02x need to be erased and unprotected before creating a Toradex config block\n",
 		       CONFIG_TDX_CFG_BLOCK_OFFSET);
 		goto out;
 #else
@@ -604,9 +631,8 @@ static int do_cfgblock(cmd_tbl_t *cmdtp, int flag, int argc,
 	return CMD_RET_USAGE;
 }
 
-U_BOOT_CMD(
-	cfgblock, 4, 0, do_cfgblock,
-	"Toradex config block handling commands",
-	"create [-y] [barcode] - (Re-)create Toradex config block\n"
-	"cfgblock reload - Reload Toradex config block from flash"
+U_BOOT_CMD(cfgblock, 4, 0, do_cfgblock,
+	   "Toradex config block handling commands",
+	   "create [-y] [barcode] - (Re-)create Toradex config block\n"
+	   "cfgblock reload - Reload Toradex config block from flash"
 );

+ 10 - 2
cmd/Kconfig

@@ -325,8 +325,8 @@ config CMD_SPL
 	  command.
 
 config CMD_SPL_NAND_OFS
-	hex "Offset of OS command line args for Falcon-mode NAND boot"
-	depends on CMD_SPL
+	hex "Offset of OS args or dtb for Falcon-mode NAND boot"
+	depends on CMD_SPL && (TPL_NAND_SUPPORT || SPL_NAND_SUPPORT)
 	default 0
 	help
 	  This provides the offset of the command line arguments for Linux
@@ -334,6 +334,14 @@ config CMD_SPL_NAND_OFS
 	  for full information about how to use this option (and also see
 	  board/gateworks/gw_ventana/README for an example).
 
+config CMD_SPL_NOR_OFS
+	hex "Offset of OS args or dtb for Falcon-mode NOR boot"
+	depends on CMD_SPL && SPL_NOR_SUPPORT
+	default 0
+	help
+	  This provides the offset of the command line arguments or dtb for
+	  Linux when booting from NOR in Falcon mode.
+
 config CMD_SPL_WRITE_SIZE
 	hex "Size of argument area"
 	depends on CMD_SPL

+ 1 - 1
cmd/eeprom.c

@@ -108,7 +108,7 @@ static int eeprom_len(unsigned offset, unsigned end)
 
 	/*
 	 * For a FRAM device there is no limit on the number of the
-	 * bytes that can be ccessed with the single read or write
+	 * bytes that can be accessed with the single read or write
 	 * operation.
 	 */
 #if !defined(CONFIG_SYS_I2C_FRAM)

+ 1 - 1
common/board_r.c

@@ -700,7 +700,7 @@ static init_fnc_t init_sequence_r[] = {
 	stdio_init_tables,
 	initr_serial,
 	initr_announce,
-#if defined(CONFIG_WDT)
+#if CONFIG_IS_ENABLED(WDT)
 	initr_watchdog,
 #endif
 	INIT_FUNC_WATCHDOG_RESET

+ 1 - 0
common/spl/Kconfig

@@ -1075,6 +1075,7 @@ endif
 
 config SPL_WATCHDOG_SUPPORT
 	bool "Support watchdog drivers"
+	imply SPL_WDT if !HW_WATCHDOG
 	help
 	  Enable support for watchdog drivers in SPL. A watchdog is
 	  typically a hardware peripheral which can reset the system when it

+ 1 - 1
common/spl/spl.c

@@ -603,7 +603,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
 	spl_board_init();
 #endif
 
-#if defined(CONFIG_SPL_WATCHDOG_SUPPORT) && defined(CONFIG_WDT)
+#if defined(CONFIG_SPL_WATCHDOG_SUPPORT) && CONFIG_IS_ENABLED(WDT)
 	initr_watchdog();
 #endif
 

+ 0 - 2
configs/apalis_imx6_defconfig

@@ -37,7 +37,6 @@ CONFIG_CMD_ASKENV=y
 CONFIG_CRC32_VERIFY=y
 CONFIG_CMD_MEMTEST=y
 CONFIG_SYS_ALT_MEMTEST=y
-CONFIG_CMD_DFU=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
@@ -56,7 +55,6 @@ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_IP_DEFRAG=y
 CONFIG_TFTP_BLOCKSIZE=4096
 CONFIG_DWC_AHSATA=y
-CONFIG_DFU_MMC=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y

+ 1 - 0
configs/aristainetos2_defconfig

@@ -50,6 +50,7 @@ CONFIG_PHYLIB=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
 CONFIG_MII=y
+CONFIG_PWM_IMX=y
 CONFIG_SPI=y
 CONFIG_MXC_SPI=y
 CONFIG_USB=y

+ 1 - 0
configs/aristainetos2b_defconfig

@@ -48,6 +48,7 @@ CONFIG_PHYLIB=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
 CONFIG_MII=y
+CONFIG_PWM_IMX=y
 CONFIG_SPI=y
 CONFIG_MXC_SPI=y
 CONFIG_USB=y

+ 1 - 0
configs/aristainetos_defconfig

@@ -49,6 +49,7 @@ CONFIG_PHYLIB=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ8XXX=y
 CONFIG_MII=y
+CONFIG_PWM_IMX=y
 CONFIG_SPI=y
 CONFIG_MXC_SPI=y
 CONFIG_USB=y

+ 0 - 1
configs/colibri-imx6ull_defconfig

@@ -47,7 +47,6 @@ CONFIG_ENV_IS_IN_NAND=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_IP_DEFRAG=y
 CONFIG_TFTP_BLOCKSIZE=16352
-CONFIG_DFU_MMC=y
 CONFIG_DFU_NAND=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y

+ 0 - 2
configs/colibri_imx6_defconfig

@@ -36,7 +36,6 @@ CONFIG_CMD_ASKENV=y
 CONFIG_CRC32_VERIFY=y
 CONFIG_CMD_MEMTEST=y
 CONFIG_SYS_ALT_MEMTEST=y
-CONFIG_CMD_DFU=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
@@ -55,7 +54,6 @@ CONFIG_ENV_IS_IN_MMC=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_IP_DEFRAG=y
 CONFIG_TFTP_BLOCKSIZE=16352
-CONFIG_DFU_MMC=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y

+ 2 - 3
configs/colibri_imx7_emmc_defconfig

@@ -24,10 +24,9 @@ CONFIG_SYS_PROMPT="Colibri iMX7 # "
 CONFIG_CMD_ASKENV=y
 CONFIG_CRC32_VERIFY=y
 CONFIG_CMD_MEMTEST=y
-CONFIG_CMD_DFU=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
-# CONFIG_RANDOM_UUID is not set
+CONFIG_RANDOM_UUID=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_USB=y
@@ -43,13 +42,13 @@ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_IP_DEFRAG=y
 CONFIG_TFTP_BLOCKSIZE=16352
 CONFIG_FSL_CAAM=y
-CONFIG_DFU_MMC=y
 CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x82000000
 CONFIG_FASTBOOT_BUF_SIZE=0x10000000
 CONFIG_FASTBOOT_FLASH=y
 CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
+CONFIG_ARMV7_BOOT_SEC_DEFAULT=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y

+ 9 - 1
configs/dh_imx6_defconfig

@@ -16,13 +16,13 @@ CONFIG_AHCI=y
 CONFIG_DISTRO_DEFAULTS=y
 # CONFIG_SYS_MALLOC_F is not set
 CONFIG_FIT=y
+CONFIG_SPL_FIT=y
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg"
 CONFIG_BOOTDELAY=3
 # CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y
 CONFIG_BOUNCE_BUFFER=y
 CONFIG_SPL_TEXT_BASE=0x00908000
-CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SPL_WATCHDOG_SUPPORT=y
 CONFIG_CMD_MEMTEST=y
@@ -41,10 +41,16 @@ CONFIG_CMD_TIME=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="imx6q-dhcom-pdk2"
+CONFIG_OF_LIST="imx6q-dhcom-pdk2 imx6dl-dhcom-pdk2"
+CONFIG_MULTI_DTB_FIT=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_DWC_AHSATA=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DM_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_MXC=y
+CONFIG_MISC=y
+CONFIG_I2C_EEPROM=y
 CONFIG_DM_MMC=y
 CONFIG_FSL_ESDHC_IMX=y
 CONFIG_DM_SPI_FLASH=y
@@ -64,6 +70,8 @@ CONFIG_FEC_MXC=y
 CONFIG_MII=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_IMX6=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_DM_SCSI=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y

+ 3 - 0
configs/display5_defconfig

@@ -4,16 +4,19 @@ CONFIG_SYS_TEXT_BASE=0x17800000
 CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SYS_MALLOC_F_LEN=0x1000
 CONFIG_MX6_DDRCAL=y
 CONFIG_TARGET_DISPLAY5=y
 CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x400
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_SPL=y
 CONFIG_SYS_BOOTCOUNT_SINGLEWORD=y
 CONFIG_SYS_BOOTCOUNT_ADDR=0x020CC068
 CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
+CONFIG_TPL_SYS_MALLOC_F_LEN=0x400
 CONFIG_FIT=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_OF_BOARD_SETUP=y

+ 1 - 0
configs/dms-ba16-1g_defconfig

@@ -41,6 +41,7 @@ CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_PHYLIB=y
 CONFIG_MII=y
+CONFIG_PWM_IMX=y
 CONFIG_SPI=y
 CONFIG_MXC_SPI=y
 CONFIG_USB=y

+ 1 - 0
configs/dms-ba16_defconfig

@@ -40,6 +40,7 @@ CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_PHYLIB=y
 CONFIG_MII=y
+CONFIG_PWM_IMX=y
 CONFIG_SPI=y
 CONFIG_MXC_SPI=y
 CONFIG_USB=y

+ 1 - 0
configs/ge_bx50v3_defconfig

@@ -55,6 +55,7 @@ CONFIG_CMD_E1000=y
 CONFIG_MII=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_IMX6=y
+CONFIG_PWM_IMX=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
 CONFIG_MXC_SPI=y

+ 6 - 0
configs/imx6q_logic_defconfig

@@ -4,6 +4,7 @@ CONFIG_SYS_TEXT_BASE=0x17800000
 CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_TARGET_MX6LOGICPD=y
 CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
@@ -54,12 +55,16 @@ CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nand0=gpmi-nand"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=gpmi-nand:2m(spl),2m(uboot),1m(env),16m(kernel),1m(dtb),-(fs)"
 CONFIG_CMD_UBI=y
+CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="imx6q-logicpd"
 CONFIG_ENV_IS_IN_FAT=y
 CONFIG_ENV_IS_IN_NAND=y
 CONFIG_ENV_FAT_INTERFACE="mmc"
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SPL_OF_TRANSLATE=y
 CONFIG_PCF8575_GPIO=y
 CONFIG_LED=y
 CONFIG_LED_GPIO=y
@@ -82,6 +87,7 @@ CONFIG_DM_REGULATOR_GPIO=y
 CONFIG_MXC_UART=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+# CONFIG_SPL_DM_USB is not set
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_MANUFACTURER="FSL"
 CONFIG_USB_GADGET_VENDOR_NUM=0x0525

+ 1 - 0
configs/imx6qdl_icore_mmc_defconfig

@@ -14,6 +14,7 @@ CONFIG_DEBUG_UART_BASE=0x021f0000
 CONFIG_DEBUG_UART_CLOCK=24000000
 CONFIG_SPL_LIBDISK_SUPPORT=y
 # CONFIG_CMD_BMODE is not set
+CONFIG_CMD_NANDBCB=y
 CONFIG_DEBUG_UART=y
 CONFIG_FIT=y
 CONFIG_FIT_SIGNATURE=y

+ 1 - 0
configs/imx6qdl_icore_nand_defconfig

@@ -8,6 +8,7 @@ CONFIG_TARGET_MX6Q_ENGICAM=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_SPL=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
 # CONFIG_CMD_BMODE is not set
 CONFIG_FIT=y
 CONFIG_FIT_SIGNATURE=y

+ 2 - 0
configs/imx8qxp_mek_defconfig

@@ -78,5 +78,7 @@ CONFIG_DM_REGULATOR_GPIO=y
 CONFIG_SPL_DM_REGULATOR_GPIO=y
 CONFIG_DM_SERIAL=y
 CONFIG_FSL_LPUART=y
+CONFIG_DM_THERMAL=y
+CONFIG_IMX_SCU_THERMAL=y
 CONFIG_SPL_TINY_MEMSET=y
 # CONFIG_EFI_LOADER is not set

+ 2 - 0
configs/kp_imx53_defconfig

@@ -47,3 +47,5 @@ CONFIG_MXC_UART=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_MX5=y
 CONFIG_USB_STORAGE=y
+CONFIG_HEXDUMP=y
+# CONFIG_EFI_LOADER is not set

+ 2 - 0
configs/m53menlo_defconfig

@@ -72,6 +72,8 @@ CONFIG_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_DM_REGULATOR_GPIO=y
 CONFIG_RTC_M41T62=y
+CONFIG_SYSRESET=y
+CONFIG_SYSRESET_WATCHDOG=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_EHCI_MX5=y

+ 0 - 2
configs/mccmon6_nor_defconfig

@@ -20,7 +20,6 @@ CONFIG_CMD_GPIO=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_SF=y
-CONFIG_CMD_USB=y
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_MTDPARTS=y
@@ -50,5 +49,4 @@ CONFIG_MII=y
 CONFIG_SPI=y
 CONFIG_MXC_SPI=y
 CONFIG_DM_THERMAL=y
-CONFIG_USB=y
 CONFIG_OF_LIBFDT=y

+ 0 - 2
configs/mccmon6_sd_defconfig

@@ -21,7 +21,6 @@ CONFIG_CMD_GPIO=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_SF=y
-CONFIG_CMD_USB=y
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_MTDPARTS=y
@@ -51,5 +50,4 @@ CONFIG_MII=y
 CONFIG_SPI=y
 CONFIG_MXC_SPI=y
 CONFIG_DM_THERMAL=y
-CONFIG_USB=y
 CONFIG_OF_LIBFDT=y

+ 1 - 0
configs/mx53ppd_defconfig

@@ -43,6 +43,7 @@ CONFIG_FSL_ESDHC_IMX=y
 CONFIG_MII=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_IMX5=y
+CONFIG_PWM_IMX=y
 CONFIG_RTC_S35392A=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_MX5=y

+ 1 - 0
configs/pico-hobbit-imx7d_defconfig

@@ -51,6 +51,7 @@ CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_MMC=y
+CONFIG_DM_USB=y
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_FSL_ESDHC_IMX=y
 CONFIG_PHYLIB=y

+ 1 - 0
configs/pico-imx7d_bl33_defconfig

@@ -43,6 +43,7 @@ CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DFU_MMC=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_MMC=y
+CONFIG_DM_USB=y
 CONFIG_FSL_ESDHC_IMX=y
 CONFIG_PHYLIB=y
 CONFIG_MII=y

+ 1 - 0
configs/pico-imx7d_defconfig

@@ -51,6 +51,7 @@ CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_MMC=y
+CONFIG_DM_USB=y
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_FSL_ESDHC_IMX=y
 CONFIG_PHYLIB=y

+ 1 - 0
configs/pico-pi-imx7d_defconfig

@@ -51,6 +51,7 @@ CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_MMC=y
+CONFIG_DM_USB=y
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_FSL_ESDHC_IMX=y
 CONFIG_PHYLIB=y

+ 1 - 0
configs/sandbox_defconfig

@@ -93,6 +93,7 @@ CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DM_BOOTCOUNT=y
 CONFIG_DM_BOOTCOUNT_RTC=y
 CONFIG_CLK=y
+CONFIG_SANDBOX_CLK_CCF=y
 CONFIG_CPU=y
 CONFIG_DM_DEMO=y
 CONFIG_DM_DEMO_SIMPLE=y

+ 1 - 0
configs/sandbox_flattree_defconfig

@@ -66,6 +66,7 @@ CONFIG_DEBUG_DEVRES=y
 CONFIG_ADC=y
 CONFIG_ADC_SANDBOX=y
 CONFIG_CLK=y
+CONFIG_SANDBOX_CLK_CCF=y
 CONFIG_CPU=y
 CONFIG_DM_DEMO=y
 CONFIG_DM_DEMO_SIMPLE=y

+ 1 - 0
configs/vining_2000_defconfig

@@ -45,6 +45,7 @@ CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_FSL_ESDHC_IMX=y
 CONFIG_PHYLIB=y
 CONFIG_MII=y
+CONFIG_PWM_IMX=y
 CONFIG_PCI=y
 CONFIG_DM_PCI=y
 CONFIG_PINCTRL=y

+ 8 - 1
configs/warp7_bl33_defconfig

@@ -54,4 +54,11 @@ 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_OPTEE_TZDRAM_SIZE=0x2000000
+CONFIG_OPTEE=y
+CONFIG_OPTEE_TZDRAM_BASE=0x9e000000
+CONFIG_OPTEE_TZDRAM_SIZE=0x02000000
+CONFIG_FIT=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_OF_LIBFDT=y
+CONFIG_OF_LIBFDT_OVERLAY=y

+ 2 - 0
doc/README.falcon

@@ -67,6 +67,8 @@ CONFIG_SYS_NAND_SPL_KERNEL_OFFS	Offset in NAND where the kernel is stored
 
 CONFIG_CMD_SPL_NAND_OFS	Offset in NAND where the parameters area was saved.
 
+CONFIG_CMD_SPL_NOR_OFS	Offset in NOR where the parameters area was saved.
+
 CONFIG_CMD_SPL_WRITE_SIZE 	Size of the parameters area to be copied
 
 CONFIG_SPL_OS_BOOT	Activate Falcon Mode.

+ 101 - 0
doc/imx/clk/ccf.txt

@@ -0,0 +1,101 @@
+Introduction:
+=============
+
+This documentation entry describes the Common Clock Framework [CCF]
+port from Linux kernel (v5.1.12) to U-Boot.
+
+This code is supposed to bring CCF to IMX based devices (imx6q, imx7
+imx8). Moreover, it also provides some common clock code, which would
+allow easy porting of CCF Linux code to other platforms.
+
+Design decisions:
+=================
+
+* U-Boot's driver model [DM] for clk differs from Linux CCF. The most
+  notably difference is the lack of support for hierarchical clocks and
+  "clock as a manager driver" (single clock DTS node acts as a starting
+  point for all other clocks).
+
+* The clk_get_rate() caches the previously read data if CLK_GET_RATE_NOCACHE
+  is not set (no need for recursive access).
+
+* On purpose the "manager" clk driver (clk-imx6q.c) is not using large
+  table to store pointers to clocks - e.g. clk[IMX6QDL_CLK_USDHC2_SEL] = ....
+  Instead we use udevice's linked list for the same class (UCLASS_CLK).
+
+  Rationale:
+  ----------
+    When porting the code as is from Linux, one would need ~1KiB of RAM to
+    store it. This is way too much if we do plan to use this driver in SPL.
+
+* The "central" structure of this patch series is struct udevice and its
+  uclass_priv field contains the struct clk pointer (to the originally created
+  one).
+
+* Up till now U-Boot's driver model (DM) CLK operates on udevice (main
+  access to clock is by udevice ops)
+  In the CCF the access to struct clk (embodying pointer to *dev) is
+  possible via dev_get_clk_ptr() (it is a wrapper on dev_get_uclass_priv()).
+
+* To keep things simple the struct udevice's uclass_priv pointer is used to
+  store back pointer to corresponding struct clk. However, it is possible to
+  modify clk-uclass.c file and add there struct uc_clk_priv, which would have
+  clock related members (like pointer to clk). As of this writing there is no
+  such need, so to avoid extra allocations (as it can be auto allocated by
+  setting .per_device_auto_alloc_size = sizeof(struct uc_clk_priv)) the
+  uclass_priv stores the pointer to struct clk.
+
+* It is advised to add common clock code (like already added rate and flags) to
+  the struct clk, which is a top level description of the clock.
+
+* U-Boot's driver model already provides the facility to automatically allocate
+  (via private_alloc_size) device private data (accessible via dev->priv).
+  It may look appealing to use this feature to allocate private structures for
+  CCF clk devices e.g. divider (struct clk_divider *divider) for IMX6Q clock.
+
+  The above feature had not been used for following reasons:
+  - The original CCF Linux kernel driver is the "manager" for clocks - it
+    decides when clock is instantiated (and when memory for it is allocated).
+
+  - Using it would change the original structure of the CCF code.
+
+  - To bind (via clk_register()) the clock device with U-Boot driver model we
+    first need udevice for it (the "chicken and egg problem").
+
+* I've added the clk_get_parent(), which reads parent's dev->uclass_priv to
+  provide parent's struct clk pointer. This seems the easiest way to get
+  child/parent relationship for struct clk in U-Boot's udevice based clocks.
+
+* Linux's CCF 'struct clk_core' corresponds to U-Boot's udevice in 'struct clk'.
+  Clock IP block agnostic flags from 'struct clk_core' (e.g. NOCACHE) have been
+  moved from this struct one level up to 'struct clk'.
+
+* For tests the new ./test/dm/clk_ccf.c and ./drivers/clk/clk_sandbox_ccf.c
+  files have been introduced. The latter setups the CCF clock structure for
+  sandbox by reusing, if possible, generic clock primitives - like divier
+  and mux. The former file provides code to tests this setup.
+
+  For sandbox new CONFIG_SANDBOX_CLK_CCF Kconfig define has been introduced.
+  All new primitives added for new architectures must have corresponding test
+  in the two aforementioned files.
+
+
+Testing (sandbox):
+==================
+
+make mrproper; make sandbox_defconfig; make -j4
+./u-boot -i -d arch/sandbox/dts/test.dtb
+=> ut dm clk
+
+or in a more "scriptable" way (with -v to print debug output):
+./u-boot --fdt arch/sandbox/dts/test.dtb --command "ut dm clk_ccf" -v
+
+To do:
+------
+
+* Use of OF_PLATDATA in the SPL setup for CCF - as it is now - the SPL grows
+  considerably and using CCF in boards with tiny resources (OCRAM) is
+  problematic.
+
+* On demand port other parts of CCF to U-Boot - as now only features _really_
+  needed by DM/DTS converted drivers are used.

+ 74 - 0
doc/imx/common/imx6.txt

@@ -88,3 +88,77 @@ Reading bank 4:
 
 Word 0x00000002: 9f027772 00000004
 
+NAND Boot on i.MX6 with SPL support
+--------------------------------------
+
+Writing/updating boot image in nand device is not straight forward in
+i.MX6 platform and it requires boot control block(BCB) to be configured.
+
+BCB contains two data structures, Firmware Configuration Block(FCB) and
+Discovered Bad Block Table(DBBT). FCB has nand timings, DBBT search area,
+and firmware. See IMX6DQRM Section 8.5.2.2
+for more information.
+
+We can't use 'nand write' command to write SPL/firmware image directly
+like other platforms does. So we need special setup to write BCB block
+as per IMX6QDL reference manual 'nandbcb update' command do that job.
+
+for nand boot, up on reset bootrom look for FCB structure in
+first block's if FCB found the nand timings are loaded for
+further reads. once FCB read done, DTTB will be loaded and
+finally firmware will be loaded which is boot image.
+
+cmd_nandbcb will create FCB these structures
+by taking mtd partition as an example.
+- initial code will erase entire partition
+- followed by FCB setup, like first 2 blocks for FCB/DBBT write,
+  and next block for FW1/SPL
+- write firmware at FW1 block and
+- finally write fcb/dttb in first 2 block.
+
+Typical NAND BCB layout:
+=======================
+
+   no.of blocks = partition size / erasesize
+   no.of fcb/dbbt blocks = 2
+   FW1 offset = no.of fcb/dbbt
+
+block  0          1          2
+        -------------------------------
+       |FCB/DBBT 0|FCB/DBBT 1|  FW 1  |
+       --------------------------------
+
+On summary, nandbcb update will
+- erase the entire partition
+- create BCB by creating 2 FCB/BDDT block followed by
+  1 FW blocks based on partition size and erasesize.
+- fill FCB/DBBT structures
+- write FW/SPL in FW1
+- write FCB/DBBT in first 2 blocks
+
+step-1: write SPL
+
+icorem6qdl> ext4load mmc 0:1 $loadaddr SPL
+39936 bytes read in 10 ms (3.8 MiB/s)
+
+icorem6qdl> nandbcb update $loadaddr spl $filesize
+device 0 offset 0x0, size 0x9c00
+Erasing at 0x1c0000 -- 100% complete.
+NAND fw write: 0x80000 offset, 0xb000 bytes written: OK
+
+step-2: write u-boot-dtb.img
+
+icorem6qdl> nand erase.part uboot
+
+NAND erase.part: device 0 offset 0x200000, size 0x200000
+Erasing at 0x3c0000 -- 100% complete.
+OK
+
+icorem6qdl> ext4load mmc 0:1 $loadaddr u-boot-dtb.img
+589094 bytes read in 37 ms (15.2 MiB/s)
+
+icorem6qdl> nand write ${loadaddr} uboot ${filesize}
+
+NAND write: device 0 offset 0x200000, size 0x8fd26
+ 589094 bytes written: OK
+icorem6qdl>

+ 22 - 0
drivers/clk/Kconfig

@@ -46,6 +46,20 @@ config CLK_BOSTON
 	help
 	  Enable this to support the clocks
 
+config SPL_CLK_CCF
+	bool "SPL Common Clock Framework [CCF] support "
+	depends on SPL_CLK_IMX6Q
+	help
+	  Enable this option if you want to (re-)use the Linux kernel's Common
+	  Clock Framework [CCF] code in U-Boot's SPL.
+
+config CLK_CCF
+	bool "Common Clock Framework [CCF] support "
+	depends on CLK_IMX6Q || SANDBOX_CLK_CCF
+	help
+	  Enable this option if you want to (re-)use the Linux kernel's Common
+	  Clock Framework [CCF] code in U-Boot's clock driver.
+
 config CLK_STM32F
 	bool "Enable clock driver support for STM32F family"
 	depends on CLK && (STM32F7 || STM32F4)
@@ -125,4 +139,12 @@ config CLK_MPC83XX
 	help
 	  Support for the clock driver of the MPC83xx series of SoCs.
 
+config SANDBOX_CLK_CCF
+	bool "Sandbox Common Clock Framework [CCF] support "
+	depends on SANDBOX
+	select CLK_CCF
+	help
+	  Enable this option if you want to test the Linux kernel's Common
+	  Clock Framework [CCF] code in U-Boot's Sandbox clock driver.
+
 endmenu

+ 3 - 0
drivers/clk/Makefile

@@ -7,6 +7,8 @@
 obj-$(CONFIG_$(SPL_TPL_)CLK) += clk-uclass.o
 obj-$(CONFIG_$(SPL_TPL_)CLK) += clk_fixed_rate.o
 obj-$(CONFIG_$(SPL_TPL_)CLK) += clk_fixed_factor.o
+obj-$(CONFIG_$(SPL_TPL_)CLK_CCF) += clk.o clk-divider.o clk-mux.o
+obj-$(CONFIG_$(SPL_TPL_)CLK_CCF) += clk-fixed-factor.o
 
 obj-y += analogbits/
 obj-y += imx/
@@ -37,5 +39,6 @@ obj-$(CONFIG_ICS8N3QV01) += ics8n3qv01.o
 obj-$(CONFIG_MACH_PIC32) += clk_pic32.o
 obj-$(CONFIG_SANDBOX) += clk_sandbox.o
 obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o
+obj-$(CONFIG_SANDBOX_CLK_CCF) += clk_sandbox_ccf.o
 obj-$(CONFIG_STM32H7) += clk_stm32h7.o
 obj-$(CONFIG_CLK_TI_SCI) += clk-ti-sci.o

+ 155 - 0
drivers/clk/clk-divider.c

@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ *
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ * Copyright (C) 2011 Richard Zhao, Linaro <richard.zhao@linaro.org>
+ * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <clk-uclass.h>
+#include <dm/device.h>
+#include <dm/uclass.h>
+#include <dm/lists.h>
+#include <dm/device-internal.h>
+#include <linux/clk-provider.h>
+#include <div64.h>
+#include <clk.h>
+#include "clk.h"
+
+#define UBOOT_DM_CLK_CCF_DIVIDER "ccf_clk_divider"
+
+static unsigned int _get_table_div(const struct clk_div_table *table,
+				   unsigned int val)
+{
+	const struct clk_div_table *clkt;
+
+	for (clkt = table; clkt->div; clkt++)
+		if (clkt->val == val)
+			return clkt->div;
+	return 0;
+}
+
+static unsigned int _get_div(const struct clk_div_table *table,
+			     unsigned int val, unsigned long flags, u8 width)
+{
+	if (flags & CLK_DIVIDER_ONE_BASED)
+		return val;
+	if (flags & CLK_DIVIDER_POWER_OF_TWO)
+		return 1 << val;
+	if (flags & CLK_DIVIDER_MAX_AT_ZERO)
+		return val ? val : clk_div_mask(width) + 1;
+	if (table)
+		return _get_table_div(table, val);
+	return val + 1;
+}
+
+unsigned long divider_recalc_rate(struct clk *hw, unsigned long parent_rate,
+				  unsigned int val,
+				  const struct clk_div_table *table,
+				  unsigned long flags, unsigned long width)
+{
+	unsigned int div;
+
+	div = _get_div(table, val, flags, width);
+	if (!div) {
+		WARN(!(flags & CLK_DIVIDER_ALLOW_ZERO),
+		     "%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n",
+		     clk_hw_get_name(hw));
+		return parent_rate;
+	}
+
+	return DIV_ROUND_UP_ULL((u64)parent_rate, div);
+}
+
+static ulong clk_divider_recalc_rate(struct clk *clk)
+{
+	struct clk_divider *divider =
+		to_clk_divider(dev_get_clk_ptr(clk->dev));
+	unsigned long parent_rate = clk_get_parent_rate(clk);
+	unsigned int val;
+
+#if CONFIG_IS_ENABLED(SANDBOX_CLK_CCF)
+	val = divider->io_divider_val;
+#else
+	val = readl(divider->reg);
+#endif
+	val >>= divider->shift;
+	val &= clk_div_mask(divider->width);
+
+	return divider_recalc_rate(clk, parent_rate, val, divider->table,
+				   divider->flags, divider->width);
+}
+
+const struct clk_ops clk_divider_ops = {
+	.get_rate = clk_divider_recalc_rate,
+};
+
+static struct clk *_register_divider(struct device *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 shift, u8 width,
+		u8 clk_divider_flags, const struct clk_div_table *table)
+{
+	struct clk_divider *div;
+	struct clk *clk;
+	int ret;
+
+	if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) {
+		if (width + shift > 16) {
+			pr_warn("divider value exceeds LOWORD field\n");
+			return ERR_PTR(-EINVAL);
+		}
+	}
+
+	/* allocate the divider */
+	div = kzalloc(sizeof(*div), GFP_KERNEL);
+	if (!div)
+		return ERR_PTR(-ENOMEM);
+
+	/* struct clk_divider assignments */
+	div->reg = reg;
+	div->shift = shift;
+	div->width = width;
+	div->flags = clk_divider_flags;
+	div->table = table;
+#if CONFIG_IS_ENABLED(SANDBOX_CLK_CCF)
+	div->io_divider_val = *(u32 *)reg;
+#endif
+
+	/* register the clock */
+	clk = &div->clk;
+
+	ret = clk_register(clk, UBOOT_DM_CLK_CCF_DIVIDER, name, parent_name);
+	if (ret) {
+		kfree(div);
+		return ERR_PTR(ret);
+	}
+
+	return clk;
+}
+
+struct clk *clk_register_divider(struct device *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 shift, u8 width,
+		u8 clk_divider_flags)
+{
+	struct clk *clk;
+
+	clk =  _register_divider(dev, name, parent_name, flags, reg, shift,
+				 width, clk_divider_flags, NULL);
+	if (IS_ERR(clk))
+		return ERR_CAST(clk);
+	return clk;
+}
+
+U_BOOT_DRIVER(ccf_clk_divider) = {
+	.name	= UBOOT_DM_CLK_CCF_DIVIDER,
+	.id	= UCLASS_CLK,
+	.ops	= &clk_divider_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};

+ 80 - 0
drivers/clk/clk-fixed-factor.c

@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ *
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ */
+#include <common.h>
+#include <malloc.h>
+#include <clk-uclass.h>
+#include <dm/device.h>
+#include <linux/clk-provider.h>
+#include <div64.h>
+#include <clk.h>
+#include "clk.h"
+
+#define UBOOT_DM_CLK_IMX_FIXED_FACTOR "ccf_clk_fixed_factor"
+
+static ulong clk_factor_recalc_rate(struct clk *clk)
+{
+	struct clk_fixed_factor *fix =
+		to_clk_fixed_factor(dev_get_clk_ptr(clk->dev));
+	unsigned long parent_rate = clk_get_parent_rate(clk);
+	unsigned long long int rate;
+
+	rate = (unsigned long long int)parent_rate * fix->mult;
+	do_div(rate, fix->div);
+	return (ulong)rate;
+}
+
+const struct clk_ops ccf_clk_fixed_factor_ops = {
+	.get_rate = clk_factor_recalc_rate,
+};
+
+struct clk *clk_hw_register_fixed_factor(struct device *dev,
+		const char *name, const char *parent_name, unsigned long flags,
+		unsigned int mult, unsigned int div)
+{
+	struct clk_fixed_factor *fix;
+	struct clk *clk;
+	int ret;
+
+	fix = kzalloc(sizeof(*fix), GFP_KERNEL);
+	if (!fix)
+		return ERR_PTR(-ENOMEM);
+
+	/* struct clk_fixed_factor assignments */
+	fix->mult = mult;
+	fix->div = div;
+	clk = &fix->clk;
+
+	ret = clk_register(clk, UBOOT_DM_CLK_IMX_FIXED_FACTOR, name,
+			   parent_name);
+	if (ret) {
+		kfree(fix);
+		return ERR_PTR(ret);
+	}
+
+	return clk;
+}
+
+struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		unsigned int mult, unsigned int div)
+{
+	struct clk *clk;
+
+	clk = clk_hw_register_fixed_factor(dev, name, parent_name, flags, mult,
+					  div);
+	if (IS_ERR(clk))
+		return ERR_CAST(clk);
+	return clk;
+}
+
+U_BOOT_DRIVER(imx_clk_fixed_factor) = {
+	.name	= UBOOT_DM_CLK_IMX_FIXED_FACTOR,
+	.id	= UCLASS_CLK,
+	.ops	= &ccf_clk_fixed_factor_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};

+ 172 - 0
drivers/clk/clk-mux.c

@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ *
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ * Copyright (C) 2011 Richard Zhao, Linaro <richard.zhao@linaro.org>
+ * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
+ *
+ * Simple multiplexer clock implementation
+ */
+
+/*
+ * U-Boot CCF porting node:
+ *
+ * The Linux kernel - as of tag: 5.0-rc3 is using also the imx_clk_fixup_mux()
+ * version of CCF mux. It is used on e.g. imx6q to provide fixes (like
+ * imx_cscmr1_fixup) for broken HW.
+ *
+ * At least for IMX6Q (but NOT IMX6QP) it is important when we set the parent
+ * clock.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <clk-uclass.h>
+#include <dm/device.h>
+#include <linux/clk-provider.h>
+#include <clk.h>
+#include "clk.h"
+
+#define UBOOT_DM_CLK_CCF_MUX "ccf_clk_mux"
+
+int clk_mux_val_to_index(struct clk *clk, u32 *table, unsigned int flags,
+			 unsigned int val)
+{
+	struct clk_mux *mux = to_clk_mux(clk);
+	int num_parents = mux->num_parents;
+
+	if (table) {
+		int i;
+
+		for (i = 0; i < num_parents; i++)
+			if (table[i] == val)
+				return i;
+		return -EINVAL;
+	}
+
+	if (val && (flags & CLK_MUX_INDEX_BIT))
+		val = ffs(val) - 1;
+
+	if (val && (flags & CLK_MUX_INDEX_ONE))
+		val--;
+
+	if (val >= num_parents)
+		return -EINVAL;
+
+	return val;
+}
+
+static u8 clk_mux_get_parent(struct clk *clk)
+{
+	struct clk_mux *mux = to_clk_mux(clk);
+	u32 val;
+
+#if CONFIG_IS_ENABLED(SANDBOX_CLK_CCF)
+	val = mux->io_mux_val;
+#else
+	val = readl(mux->reg);
+#endif
+	val >>= mux->shift;
+	val &= mux->mask;
+
+	return clk_mux_val_to_index(clk, mux->table, mux->flags, val);
+}
+
+const struct clk_ops clk_mux_ops = {
+		.get_rate = clk_generic_get_rate,
+};
+
+struct clk *clk_hw_register_mux_table(struct device *dev, const char *name,
+		const char * const *parent_names, u8 num_parents,
+		unsigned long flags,
+		void __iomem *reg, u8 shift, u32 mask,
+		u8 clk_mux_flags, u32 *table)
+{
+	struct clk_mux *mux;
+	struct clk *clk;
+	u8 width = 0;
+	int ret;
+
+	if (clk_mux_flags & CLK_MUX_HIWORD_MASK) {
+		width = fls(mask) - ffs(mask) + 1;
+		if (width + shift > 16) {
+			pr_err("mux value exceeds LOWORD field\n");
+			return ERR_PTR(-EINVAL);
+		}
+	}
+
+	/* allocate the mux */
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	if (!mux)
+		return ERR_PTR(-ENOMEM);
+
+	/* U-boot specific assignments */
+	mux->parent_names = parent_names;
+	mux->num_parents = num_parents;
+
+	/* struct clk_mux assignments */
+	mux->reg = reg;
+	mux->shift = shift;
+	mux->mask = mask;
+	mux->flags = clk_mux_flags;
+	mux->table = table;
+#if CONFIG_IS_ENABLED(SANDBOX_CLK_CCF)
+	mux->io_mux_val = *(u32 *)reg;
+#endif
+
+	clk = &mux->clk;
+
+	/*
+	 * Read the current mux setup - so we assign correct parent.
+	 *
+	 * Changing parent would require changing internals of udevice struct
+	 * for the corresponding clock (to do that define .set_parent() method.
+	 */
+	ret = clk_register(clk, UBOOT_DM_CLK_CCF_MUX, name,
+			   parent_names[clk_mux_get_parent(clk)]);
+	if (ret) {
+		kfree(mux);
+		return ERR_PTR(ret);
+	}
+
+	return clk;
+}
+
+struct clk *clk_register_mux_table(struct device *dev, const char *name,
+		const char * const *parent_names, u8 num_parents,
+		unsigned long flags,
+		void __iomem *reg, u8 shift, u32 mask,
+		u8 clk_mux_flags, u32 *table)
+{
+	struct clk *clk;
+
+	clk = clk_hw_register_mux_table(dev, name, parent_names, num_parents,
+				       flags, reg, shift, mask, clk_mux_flags,
+				       table);
+	if (IS_ERR(clk))
+		return ERR_CAST(clk);
+	return clk;
+}
+
+struct clk *clk_register_mux(struct device *dev, const char *name,
+		const char * const *parent_names, u8 num_parents,
+		unsigned long flags,
+		void __iomem *reg, u8 shift, u8 width,
+		u8 clk_mux_flags)
+{
+	u32 mask = BIT(width) - 1;
+
+	return clk_register_mux_table(dev, name, parent_names, num_parents,
+				      flags, reg, shift, mask, clk_mux_flags,
+				      NULL);
+}
+
+U_BOOT_DRIVER(ccf_clk_mux) = {
+	.name	= UBOOT_DM_CLK_CCF_MUX,
+	.id	= UCLASS_CLK,
+	.ops	= &clk_mux_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};

+ 60 - 0
drivers/clk/clk-uclass.c

@@ -13,6 +13,7 @@
 #include <dm/read.h>
 #include <dt-structs.h>
 #include <errno.h>
+#include <linux/clk-provider.h>
 
 static inline const struct clk_ops *clk_dev_ops(struct udevice *dev)
 {
@@ -381,6 +382,43 @@ ulong clk_get_rate(struct clk *clk)
 	return ops->get_rate(clk);
 }
 
+struct clk *clk_get_parent(struct clk *clk)
+{
+	struct udevice *pdev;
+	struct clk *pclk;
+
+	debug("%s(clk=%p)\n", __func__, clk);
+
+	pdev = dev_get_parent(clk->dev);
+	pclk = dev_get_clk_ptr(pdev);
+	if (!pclk)
+		return ERR_PTR(-ENODEV);
+
+	return pclk;
+}
+
+long long clk_get_parent_rate(struct clk *clk)
+{
+	const struct clk_ops *ops;
+	struct clk *pclk;
+
+	debug("%s(clk=%p)\n", __func__, clk);
+
+	pclk = clk_get_parent(clk);
+	if (IS_ERR(pclk))
+		return -ENODEV;
+
+	ops = clk_dev_ops(pclk->dev);
+	if (!ops->get_rate)
+		return -ENOSYS;
+
+	/* Read the 'rate' if not already set or if proper flag set*/
+	if (!pclk->rate || pclk->flags & CLK_GET_RATE_NOCACHE)
+		pclk->rate = clk_get_rate(pclk);
+
+	return pclk->rate;
+}
+
 ulong clk_set_rate(struct clk *clk, ulong rate)
 {
 	const struct clk_ops *ops = clk_dev_ops(clk->dev);
@@ -455,6 +493,28 @@ int clk_disable_bulk(struct clk_bulk *bulk)
 	return 0;
 }
 
+int clk_get_by_id(ulong id, struct clk **clkp)
+{
+	struct udevice *dev;
+	struct uclass *uc;
+	int ret;
+
+	ret = uclass_get(UCLASS_CLK, &uc);
+	if (ret)
+		return ret;
+
+	uclass_foreach_dev(dev, uc) {
+		struct clk *clk = dev_get_clk_ptr(dev);
+
+		if (clk && clk->id == id) {
+			*clkp = clk;
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
 UCLASS_DRIVER(clk) = {
 	.id		= UCLASS_CLK,
 	.name		= "clk",

+ 57 - 0
drivers/clk/clk.c

@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm/device.h>
+#include <dm/uclass.h>
+#include <dm/lists.h>
+#include <dm/device-internal.h>
+#include <clk.h>
+
+int clk_register(struct clk *clk, const char *drv_name,
+		 const char *name, const char *parent_name)
+{
+	struct udevice *parent;
+	struct driver *drv;
+	int ret;
+
+	ret = uclass_get_device_by_name(UCLASS_CLK, parent_name, &parent);
+	if (ret)
+		printf("%s: UCLASS parent: 0x%p\n", __func__, parent);
+
+	debug("%s: name: %s parent: %s [0x%p]\n", __func__, name, parent->name,
+	      parent);
+
+	drv = lists_driver_lookup_name(drv_name);
+	if (!drv) {
+		printf("%s: %s is not a valid driver name\n",
+		       __func__, drv_name);
+		return -ENOENT;
+	}
+
+	ret = device_bind(parent, drv, name, NULL, -1, &clk->dev);
+	if (ret) {
+		printf("%s: CLK: %s driver bind error [%d]!\n", __func__, name,
+		       ret);
+		return ret;
+	}
+
+	/* Store back pointer to clk from udevice */
+	clk->dev->uclass_priv = clk;
+
+	return 0;
+}
+
+ulong clk_generic_get_rate(struct clk *clk)
+{
+	return clk_get_parent_rate(clk);
+}
+
+const char *clk_hw_get_name(const struct clk *hw)
+{
+	return hw->dev->name;
+}

+ 0 - 3
drivers/clk/clk_fixed_factor.c

@@ -24,9 +24,6 @@ static ulong clk_fixed_factor_get_rate(struct clk *clk)
 	uint64_t rate;
 	struct clk_fixed_factor *ff = to_clk_fixed_factor(clk->dev);
 
-	if (clk->id != 0)
-		return -EINVAL;
-
 	rate = clk_get_rate(&ff->parent);
 	if (IS_ERR_VALUE(rate))
 		return rate;

+ 5 - 3
drivers/clk/clk_fixed_rate.c

@@ -8,6 +8,7 @@
 #include <dm.h>
 
 struct clk_fixed_rate {
+	struct clk clk;
 	unsigned long fixed_rate;
 };
 
@@ -15,9 +16,6 @@ struct clk_fixed_rate {
 
 static ulong clk_fixed_rate_get_rate(struct clk *clk)
 {
-	if (clk->id != 0)
-		return -EINVAL;
-
 	return to_clk_fixed_rate(clk->dev)->fixed_rate;
 }
 
@@ -27,10 +25,14 @@ const struct clk_ops clk_fixed_rate_ops = {
 
 static int clk_fixed_rate_ofdata_to_platdata(struct udevice *dev)
 {
+	struct clk *clk = &to_clk_fixed_rate(dev)->clk;
 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
 	to_clk_fixed_rate(dev)->fixed_rate =
 		dev_read_u32_default(dev, "clock-frequency", 0);
 #endif
+	/* Make fixed rate clock accessible from higher level struct clk */
+	dev->uclass_priv = clk;
+	clk->dev = dev;
 
 	return 0;
 }

+ 185 - 0
drivers/clk/clk_sandbox_ccf.c

@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ *
+ * Common Clock Framework [CCF] driver for Sandbox
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <clk.h>
+#include <asm/clk.h>
+#include <clk-uclass.h>
+#include <linux/clk-provider.h>
+#include <sandbox-clk.h>
+
+/*
+ * Sandbox implementation of CCF primitives necessary for clk-uclass testing
+ *
+ * --- Sandbox PLLv3 ---
+ */
+struct clk_pllv3 {
+	struct clk	clk;
+	u32		div_mask;
+	u32		div_shift;
+};
+
+static ulong clk_pllv3_get_rate(struct clk *clk)
+{
+	unsigned long parent_rate = clk_get_parent_rate(clk);
+
+	return parent_rate * 24;
+}
+
+static const struct clk_ops clk_pllv3_generic_ops = {
+	.get_rate       = clk_pllv3_get_rate,
+};
+
+struct clk *sandbox_clk_pllv3(enum sandbox_pllv3_type type, const char *name,
+			      const char *parent_name, void __iomem *base,
+			      u32 div_mask)
+{
+	struct clk_pllv3 *pll;
+	struct clk *clk;
+	char *drv_name = "sandbox_clk_pllv3";
+	int ret;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	pll->div_mask = div_mask;
+	clk = &pll->clk;
+
+	ret = clk_register(clk, drv_name, name, parent_name);
+	if (ret) {
+		kfree(pll);
+		return ERR_PTR(ret);
+	}
+
+	return clk;
+}
+
+U_BOOT_DRIVER(sandbox_clk_pll_generic) = {
+	.name	= "sandbox_clk_pllv3",
+	.id	= UCLASS_CLK,
+	.ops	= &clk_pllv3_generic_ops,
+};
+
+/* --- Sandbox PLLv3 --- */
+/* --- Sandbox Gate  --- */
+struct clk_gate2 {
+	struct clk clk;
+	bool	state;
+};
+
+#define to_clk_gate2(_clk) container_of(_clk, struct clk_gate2, clk)
+
+static int clk_gate2_enable(struct clk *clk)
+{
+	struct clk_gate2 *gate = to_clk_gate2(dev_get_clk_ptr(clk->dev));
+
+	gate->state = 1;
+	return 0;
+}
+
+static int clk_gate2_disable(struct clk *clk)
+{
+	struct clk_gate2 *gate = to_clk_gate2(dev_get_clk_ptr(clk->dev));
+
+	gate->state = 0;
+	return 0;
+}
+
+static const struct clk_ops clk_gate2_ops = {
+	.enable = clk_gate2_enable,
+	.disable = clk_gate2_disable,
+	.get_rate = clk_generic_get_rate,
+};
+
+struct clk *sandbox_clk_register_gate2(struct device *dev, const char *name,
+				       const char *parent_name,
+				       unsigned long flags, void __iomem *reg,
+				       u8 bit_idx, u8 cgr_val,
+				       u8 clk_gate2_flags)
+{
+	struct clk_gate2 *gate;
+	struct clk *clk;
+	int ret;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		return ERR_PTR(-ENOMEM);
+
+	gate->state = 0;
+	clk = &gate->clk;
+
+	ret = clk_register(clk, "sandbox_clk_gate2", name, parent_name);
+	if (ret) {
+		kfree(gate);
+		return ERR_PTR(ret);
+	}
+
+	return clk;
+}
+
+U_BOOT_DRIVER(sandbox_clk_gate2) = {
+	.name	= "sandbox_clk_gate2",
+	.id	= UCLASS_CLK,
+	.ops	= &clk_gate2_ops,
+};
+
+/* --- Sandbox Gate --- */
+/* The CCF core driver itself */
+static const struct udevice_id sandbox_clk_ccf_test_ids[] = {
+	{ .compatible = "sandbox,clk-ccf" },
+	{ }
+};
+
+static const char *const usdhc_sels[] = { "pll3_60m", "pll3_80m", };
+
+static int sandbox_clk_ccf_probe(struct udevice *dev)
+{
+	void *base = NULL;
+	u32 reg;
+
+	clk_dm(SANDBOX_CLK_PLL3,
+	       sandbox_clk_pllv3(SANDBOX_PLLV3_USB, "pll3_usb_otg", "osc",
+				 base + 0x10, 0x3));
+
+	clk_dm(SANDBOX_CLK_PLL3_60M,
+	       sandbox_clk_fixed_factor("pll3_60m",  "pll3_usb_otg",   1, 8));
+
+	clk_dm(SANDBOX_CLK_PLL3_80M,
+	       sandbox_clk_fixed_factor("pll3_80m",  "pll3_usb_otg",   1, 6));
+
+	/* The HW adds +1 to the divider value (2+1) is the divider */
+	reg = (2 << 19);
+	clk_dm(SANDBOX_CLK_ECSPI_ROOT,
+	       sandbox_clk_divider("ecspi_root", "pll3_60m", &reg, 19, 6));
+
+	clk_dm(SANDBOX_CLK_ECSPI1,
+	       sandbox_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0));
+
+	/* Select 'pll3_60m' */
+	reg = 0;
+	clk_dm(SANDBOX_CLK_USDHC1_SEL,
+	       sandbox_clk_mux("usdhc1_sel", &reg, 16, 1, usdhc_sels,
+			       ARRAY_SIZE(usdhc_sels)));
+
+	/* Select 'pll3_80m' */
+	reg = BIT(17);
+	clk_dm(SANDBOX_CLK_USDHC2_SEL,
+	       sandbox_clk_mux("usdhc2_sel", &reg, 17, 1, usdhc_sels,
+			       ARRAY_SIZE(usdhc_sels)));
+
+	return 0;
+}
+
+U_BOOT_DRIVER(sandbox_clk_ccf) = {
+	.name = "sandbox_clk_ccf",
+	.id = UCLASS_CLK,
+	.probe = sandbox_clk_ccf_probe,
+	.of_match = sandbox_clk_ccf_test_ids,
+};

+ 16 - 0
drivers/clk/imx/Kconfig

@@ -1,3 +1,19 @@
+config SPL_CLK_IMX6Q
+	bool "SPL clock support for i.MX6Q"
+	depends on ARCH_MX6 && SPL
+	select SPL_CLK
+	select SPL_CLK_CCF
+	help
+	  This enables SPL DM/DTS support for clock driver in i.MX6Q platforms.
+
+config CLK_IMX6Q
+	bool "Clock support for i.MX6Q"
+	depends on ARCH_MX6
+	select CLK
+	select CLK_CCF
+	help
+	  This enables DM/DTS support for clock driver in i.MX6Q platforms.
+
 config CLK_IMX8
 	bool "Clock support for i.MX8"
 	depends on ARCH_IMX8

+ 2 - 0
drivers/clk/imx/Makefile

@@ -2,6 +2,8 @@
 #
 # SPDX-License-Identifier: GPL-2.0
 
+obj-$(CONFIG_$(SPL_TPL_)CLK_CCF) += clk-gate2.o clk-pllv3.o clk-pfd.o
+obj-$(CONFIG_$(SPL_TPL_)CLK_IMX6Q) += clk-imx6q.o
 obj-$(CONFIG_CLK_IMX8) += clk-imx8.o
 
 ifdef CONFIG_CLK_IMX8

+ 103 - 0
drivers/clk/imx/clk-gate2.c

@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ *
+ * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com>
+ * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Gated clock implementation
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <clk-uclass.h>
+#include <dm/device.h>
+#include <linux/clk-provider.h>
+#include <clk.h>
+#include "clk.h"
+
+#define UBOOT_DM_CLK_IMX_GATE2 "imx_clk_gate2"
+
+struct clk_gate2 {
+	struct clk clk;
+	void __iomem	*reg;
+	u8		bit_idx;
+	u8		cgr_val;
+	u8		flags;
+};
+
+#define to_clk_gate2(_clk) container_of(_clk, struct clk_gate2, clk)
+
+static int clk_gate2_enable(struct clk *clk)
+{
+	struct clk_gate2 *gate = to_clk_gate2(dev_get_clk_ptr(clk->dev));
+	u32 reg;
+
+	reg = readl(gate->reg);
+	reg &= ~(3 << gate->bit_idx);
+	reg |= gate->cgr_val << gate->bit_idx;
+	writel(reg, gate->reg);
+
+	return 0;
+}
+
+static int clk_gate2_disable(struct clk *clk)
+{
+	struct clk_gate2 *gate = to_clk_gate2(dev_get_clk_ptr(clk->dev));
+	u32 reg;
+
+	reg = readl(gate->reg);
+	reg &= ~(3 << gate->bit_idx);
+	writel(reg, gate->reg);
+
+	return 0;
+}
+
+static const struct clk_ops clk_gate2_ops = {
+	.enable = clk_gate2_enable,
+	.disable = clk_gate2_disable,
+	.get_rate = clk_generic_get_rate,
+};
+
+struct clk *clk_register_gate2(struct device *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 bit_idx, u8 cgr_val,
+		u8 clk_gate2_flags)
+{
+	struct clk_gate2 *gate;
+	struct clk *clk;
+	int ret;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		return ERR_PTR(-ENOMEM);
+
+	gate->reg = reg;
+	gate->bit_idx = bit_idx;
+	gate->cgr_val = cgr_val;
+	gate->flags = clk_gate2_flags;
+
+	clk = &gate->clk;
+
+	ret = clk_register(clk, UBOOT_DM_CLK_IMX_GATE2, name, parent_name);
+	if (ret) {
+		kfree(gate);
+		return ERR_PTR(ret);
+	}
+
+	return clk;
+}
+
+U_BOOT_DRIVER(clk_gate2) = {
+	.name	= UBOOT_DM_CLK_IMX_GATE2,
+	.id	= UCLASS_CLK,
+	.ops	= &clk_gate2_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};

+ 179 - 0
drivers/clk/imx/clk-imx6q.c

@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+#include <dt-bindings/clock/imx6qdl-clock.h>
+
+#include "clk.h"
+
+static int imx6q_check_id(ulong id)
+{
+	if (id < IMX6QDL_CLK_DUMMY || id >= IMX6QDL_CLK_END) {
+		printf("%s: Invalid clk ID #%lu\n", __func__, id);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static ulong imx6q_clk_get_rate(struct clk *clk)
+{
+	struct clk *c;
+	int ret;
+
+	debug("%s(#%lu)\n", __func__, clk->id);
+
+	ret = imx6q_check_id(clk->id);
+	if (ret)
+		return ret;
+
+	ret = clk_get_by_id(clk->id, &c);
+	if (ret)
+		return ret;
+
+	return clk_get_rate(c);
+}
+
+static ulong imx6q_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
+
+	return rate;
+}
+
+static int __imx6q_clk_enable(struct clk *clk, bool enable)
+{
+	struct clk *c;
+	int ret = 0;
+
+	debug("%s(#%lu) en: %d\n", __func__, clk->id, enable);
+
+	ret = imx6q_check_id(clk->id);
+	if (ret)
+		return ret;
+
+	ret = clk_get_by_id(clk->id, &c);
+	if (ret)
+		return ret;
+
+	if (enable)
+		ret = clk_enable(c);
+	else
+		ret = clk_disable(c);
+
+	return ret;
+}
+
+static int imx6q_clk_disable(struct clk *clk)
+{
+	return __imx6q_clk_enable(clk, 0);
+}
+
+static int imx6q_clk_enable(struct clk *clk)
+{
+	return __imx6q_clk_enable(clk, 1);
+}
+
+static struct clk_ops imx6q_clk_ops = {
+	.set_rate = imx6q_clk_set_rate,
+	.get_rate = imx6q_clk_get_rate,
+	.enable = imx6q_clk_enable,
+	.disable = imx6q_clk_disable,
+};
+
+static const char *const usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+
+static int imx6q_clk_probe(struct udevice *dev)
+{
+	void *base;
+
+	/* Anatop clocks */
+	base = (void *)ANATOP_BASE_ADDR;
+
+	clk_dm(IMX6QDL_CLK_PLL2,
+	       imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc",
+			     base + 0x30, 0x1));
+	clk_dm(IMX6QDL_CLK_PLL3_USB_OTG,
+	       imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc",
+			     base + 0x10, 0x3));
+	clk_dm(IMX6QDL_CLK_PLL3_60M,
+	       imx_clk_fixed_factor("pll3_60m",  "pll3_usb_otg",   1, 8));
+	clk_dm(IMX6QDL_CLK_PLL2_PFD0_352M,
+	       imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0));
+	clk_dm(IMX6QDL_CLK_PLL2_PFD2_396M,
+	       imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2));
+
+	/* CCM clocks */
+	base = dev_read_addr_ptr(dev);
+	if (base == (void *)FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	clk_dm(IMX6QDL_CLK_USDHC1_SEL,
+	       imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1,
+			   usdhc_sels, ARRAY_SIZE(usdhc_sels)));
+	clk_dm(IMX6QDL_CLK_USDHC2_SEL,
+	       imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1,
+			   usdhc_sels, ARRAY_SIZE(usdhc_sels)));
+	clk_dm(IMX6QDL_CLK_USDHC3_SEL,
+	       imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1,
+			   usdhc_sels, ARRAY_SIZE(usdhc_sels)));
+	clk_dm(IMX6QDL_CLK_USDHC4_SEL,
+	       imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1,
+			   usdhc_sels, ARRAY_SIZE(usdhc_sels)));
+
+	clk_dm(IMX6QDL_CLK_USDHC1_PODF,
+	       imx_clk_divider("usdhc1_podf", "usdhc1_sel",
+			       base + 0x24, 11, 3));
+	clk_dm(IMX6QDL_CLK_USDHC2_PODF,
+	       imx_clk_divider("usdhc2_podf", "usdhc2_sel",
+			       base + 0x24, 16, 3));
+	clk_dm(IMX6QDL_CLK_USDHC3_PODF,
+	       imx_clk_divider("usdhc3_podf", "usdhc3_sel",
+			       base + 0x24, 19, 3));
+	clk_dm(IMX6QDL_CLK_USDHC4_PODF,
+	       imx_clk_divider("usdhc4_podf", "usdhc4_sel",
+			       base + 0x24, 22, 3));
+
+	clk_dm(IMX6QDL_CLK_ECSPI_ROOT,
+	       imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6));
+
+	clk_dm(IMX6QDL_CLK_ECSPI1,
+	       imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0));
+	clk_dm(IMX6QDL_CLK_ECSPI2,
+	       imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2));
+	clk_dm(IMX6QDL_CLK_ECSPI3,
+	       imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4));
+	clk_dm(IMX6QDL_CLK_ECSPI4,
+	       imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6));
+	clk_dm(IMX6QDL_CLK_USDHC1,
+	       imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2));
+	clk_dm(IMX6QDL_CLK_USDHC2,
+	       imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4));
+	clk_dm(IMX6QDL_CLK_USDHC3,
+	       imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6));
+	clk_dm(IMX6QDL_CLK_USDHC4,
+	       imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8));
+
+	return 0;
+}
+
+static const struct udevice_id imx6q_clk_ids[] = {
+	{ .compatible = "fsl,imx6q-ccm" },
+	{ },
+};
+
+U_BOOT_DRIVER(imx6q_clk) = {
+	.name = "clk_imx6q",
+	.id = UCLASS_CLK,
+	.of_match = imx6q_clk_ids,
+	.ops = &imx6q_clk_ops,
+	.probe = imx6q_clk_probe,
+	.flags = DM_FLAG_PRE_RELOC,
+};

+ 90 - 0
drivers/clk/imx/clk-pfd.c

@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ *
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <clk-uclass.h>
+#include <dm/device.h>
+#include <linux/clk-provider.h>
+#include <div64.h>
+#include <clk.h>
+#include "clk.h"
+
+#define UBOOT_DM_CLK_IMX_PFD "imx_clk_pfd"
+
+struct clk_pfd {
+	struct clk	clk;
+	void __iomem	*reg;
+	u8		idx;
+};
+
+#define to_clk_pfd(_clk) container_of(_clk, struct clk_pfd, clk)
+
+#define SET	0x4
+#define CLR	0x8
+#define OTG	0xc
+
+static unsigned long clk_pfd_recalc_rate(struct clk *clk)
+{
+	struct clk_pfd *pfd =
+		to_clk_pfd(dev_get_clk_ptr(clk->dev));
+	unsigned long parent_rate = clk_get_parent_rate(clk);
+	u64 tmp = parent_rate;
+	u8 frac = (readl(pfd->reg) >> (pfd->idx * 8)) & 0x3f;
+
+	tmp *= 18;
+	do_div(tmp, frac);
+
+	return tmp;
+}
+
+static const struct clk_ops clk_pfd_ops = {
+	.get_rate	= clk_pfd_recalc_rate,
+};
+
+struct clk *imx_clk_pfd(const char *name, const char *parent_name,
+			void __iomem *reg, u8 idx)
+{
+	struct clk_pfd *pfd;
+	struct clk *clk;
+	int ret;
+
+	pfd = kzalloc(sizeof(*pfd), GFP_KERNEL);
+	if (!pfd)
+		return ERR_PTR(-ENOMEM);
+
+	pfd->reg = reg;
+	pfd->idx = idx;
+
+	/* register the clock */
+	clk = &pfd->clk;
+
+	ret = clk_register(clk, UBOOT_DM_CLK_IMX_PFD, name, parent_name);
+	if (ret) {
+		kfree(pfd);
+		return ERR_PTR(ret);
+	}
+
+	return clk;
+}
+
+U_BOOT_DRIVER(clk_pfd) = {
+	.name	= UBOOT_DM_CLK_IMX_PFD,
+	.id	= UCLASS_CLK,
+	.ops	= &clk_pfd_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};

+ 82 - 0
drivers/clk/imx/clk-pllv3.c

@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <clk-uclass.h>
+#include <dm/device.h>
+#include <dm/uclass.h>
+#include <clk.h>
+#include "clk.h"
+
+#define UBOOT_DM_CLK_IMX_PLLV3 "imx_clk_pllv3"
+
+struct clk_pllv3 {
+	struct clk	clk;
+	void __iomem	*base;
+	u32		div_mask;
+	u32		div_shift;
+};
+
+#define to_clk_pllv3(_clk) container_of(_clk, struct clk_pllv3, clk)
+
+static ulong clk_pllv3_get_rate(struct clk *clk)
+{
+	struct clk_pllv3 *pll = to_clk_pllv3(dev_get_clk_ptr(clk->dev));
+	unsigned long parent_rate = clk_get_parent_rate(clk);
+
+	u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask;
+
+	return (div == 1) ? parent_rate * 22 : parent_rate * 20;
+}
+
+static const struct clk_ops clk_pllv3_generic_ops = {
+	.get_rate       = clk_pllv3_get_rate,
+};
+
+struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
+			  const char *parent_name, void __iomem *base,
+			  u32 div_mask)
+{
+	struct clk_pllv3 *pll;
+	struct clk *clk;
+	char *drv_name;
+	int ret;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	switch (type) {
+	case IMX_PLLV3_GENERIC:
+	case IMX_PLLV3_USB:
+		drv_name = UBOOT_DM_CLK_IMX_PLLV3;
+		break;
+	default:
+		kfree(pll);
+		return ERR_PTR(-ENOTSUPP);
+	}
+
+	pll->base = base;
+	pll->div_mask = div_mask;
+	clk = &pll->clk;
+
+	ret = clk_register(clk, drv_name, name, parent_name);
+	if (ret) {
+		kfree(pll);
+		return ERR_PTR(ret);
+	}
+
+	return clk;
+}
+
+U_BOOT_DRIVER(clk_pllv3_generic) = {
+	.name	= UBOOT_DM_CLK_IMX_PLLV3,
+	.id	= UCLASS_CLK,
+	.ops	= &clk_pllv3_generic_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};

+ 69 - 0
drivers/clk/imx/clk.h

@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 DENX Software Engineering
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ */
+#ifndef __MACH_IMX_CLK_H
+#define __MACH_IMX_CLK_H
+
+#include <linux/clk-provider.h>
+
+enum imx_pllv3_type {
+	IMX_PLLV3_GENERIC,
+	IMX_PLLV3_SYS,
+	IMX_PLLV3_USB,
+	IMX_PLLV3_USB_VF610,
+	IMX_PLLV3_AV,
+	IMX_PLLV3_ENET,
+	IMX_PLLV3_ENET_IMX7,
+	IMX_PLLV3_SYS_VF610,
+	IMX_PLLV3_DDR_IMX7,
+};
+
+struct clk *clk_register_gate2(struct device *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 bit_idx, u8 cgr_val,
+		u8 clk_gate_flags);
+
+struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
+			  const char *parent_name, void __iomem *base,
+			  u32 div_mask);
+
+static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
+					void __iomem *reg, u8 shift)
+{
+	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
+			shift, 0x3, 0);
+}
+
+static inline struct clk *imx_clk_fixed_factor(const char *name,
+		const char *parent, unsigned int mult, unsigned int div)
+{
+	return clk_register_fixed_factor(NULL, name, parent,
+			CLK_SET_RATE_PARENT, mult, div);
+}
+
+static inline struct clk *imx_clk_divider(const char *name, const char *parent,
+		void __iomem *reg, u8 shift, u8 width)
+{
+	return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
+			reg, shift, width, 0);
+}
+
+struct clk *imx_clk_pfd(const char *name, const char *parent_name,
+			void __iomem *reg, u8 idx);
+
+struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg,
+			      u8 shift, u8 width, const char * const *parents,
+			      int num_parents, void (*fixup)(u32 *val));
+
+static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
+			u8 shift, u8 width, const char * const *parents,
+			int num_parents)
+{
+	return clk_register_mux(NULL, name, parents, num_parents,
+			CLK_SET_RATE_NO_REPARENT, reg, shift,
+			width, 0);
+}
+
+#endif /* __MACH_IMX_CLK_H */

+ 1 - 1
drivers/gpio/mxc_gpio.c

@@ -31,7 +31,7 @@ struct mxc_bank_info {
 };
 
 #ifndef CONFIG_DM_GPIO
-#define GPIO_TO_PORT(n)		(n / 32)
+#define GPIO_TO_PORT(n)		((n) / 32)
 
 /* GPIO port description */
 static unsigned long gpio_ports[] = {

Някои файлове не бяха показани, защото твърде много файлове са промени