Merge tag 'xilinx-for-v2020.07' of https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze into next

Xilinx changes for v2020.07

common:
- Align ENV_FAT_INTERFACE
- Fix MAC address source print log
- Improve based autodetection code

xilinx:
- Enable netconsole

Microblaze:
- Setup default ENV_OFFSET/ENV_SECT_SIZE

Zynq:
- Multiple DT updates/fixes
- Use DEVICE_TREE environment variable for DTB selection
- Switch to single zynq configuration
- Enable NOR flash via DM
- Minor SPL print removal
- Enable i2c mux driver

ZynqMP:
- Print multiboot register
- Enable cache commands in mini mtest
- Multiple DT updates/fixes
- Fix firmware probing when driver is not enabled
- Specify 3rd backup RAM boot mode in SPL
- Add SPL support for zcu102 v1.1 and zcu111 revA
- Redesign debug uart enabling and psu_init delay
- Enable full u-boot run from EL3
- Enable u-boot.itb generation without ATF with U-Boot in EL3

Versal:
- Enable distro default
- Enable others SPI flashes
- Enable systems without DDR

Drivers:
- Gem:
  - Flush memory after freeing
  - Handle mdio bus separately
- Watchdog:
  - Get rid of unused global data pointer
  - Enable window watchdog timer
- Serial:
  - Change reinitialization logic in zynq serial driver

Signed-off-by: Tom Rini <trini@konsulko.com>
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml
index 7d2ffe3..192c7ef 100644
--- a/.azure-pipelines.yml
+++ b/.azure-pipelines.yml
@@ -120,7 +120,7 @@
           make tools-only_config envtools -j$(nproc)
 
   - job: utils
-    displayName: 'Run binman, buildman, dtoc and patman testsuites'
+    displayName: 'Run binman, buildman, dtoc, Kconfig and patman testsuites'
     pool:
       vmImage: $(ubuntu_vm)
     steps:
@@ -135,7 +135,7 @@
           export USER=azure
           virtualenv -p /usr/bin/python3 /tmp/venv
           . /tmp/venv/bin/activate
-          pip install pyelftools
+          pip install pyelftools pytest
           export UBOOT_TRAVIS_BUILD_DIR=/tmp/.bm-work/sandbox_spl
           export PYTHONPATH=${UBOOT_TRAVIS_BUILD_DIR}/scripts/dtc/pylibfdt
           export PATH=${UBOOT_TRAVIS_BUILD_DIR}/scripts/dtc:${PATH}
@@ -144,6 +144,7 @@
           ./tools/buildman/buildman -t
           ./tools/dtoc/dtoc -t
           ./tools/patman/patman --test
+          make O=${UBOOT_TRAVIS_BUILD_DIR} testconfig
           EOF
           cat build.sh
           # We cannot use "container" like other jobs above, as buildman
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 8903358..ae158aa 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -157,7 +157,7 @@
   script:
     - make tools-only_config envtools -j$(nproc)
 
-Run binman, buildman, dtoc and patman testsuites:
+Run binman, buildman, dtoc, Kconfig and patman testsuites:
   tags: [ 'all' ]
   stage: testsuites
   script:
@@ -166,7 +166,7 @@
       export USER=gitlab;
       virtualenv -p /usr/bin/python3 /tmp/venv;
       . /tmp/venv/bin/activate;
-      pip install pyelftools;
+      pip install pyelftools pytest;
       export UBOOT_TRAVIS_BUILD_DIR=/tmp/.bm-work/sandbox_spl;
       export PYTHONPATH="${UBOOT_TRAVIS_BUILD_DIR}/scripts/dtc/pylibfdt";
       export PATH="${UBOOT_TRAVIS_BUILD_DIR}/scripts/dtc:${PATH}";
@@ -174,7 +174,8 @@
       ./tools/binman/binman --toolpath ${UBOOT_TRAVIS_BUILD_DIR}/tools test;
       ./tools/buildman/buildman -t;
       ./tools/dtoc/dtoc -t;
-      ./tools/patman/patman --test
+      ./tools/patman/patman --test;
+      make testconfig
 
 # Test sandbox with test.py
 sandbox test.py:
diff --git a/.travis.yml b/.travis.yml
index 60cc62e..8a4a45c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -152,7 +152,8 @@
        ./tools/binman/binman --toolpath ${UBOOT_TRAVIS_BUILD_DIR}/tools test &&
        ./tools/patman/patman --test &&
        ./tools/buildman/buildman -t &&
-       ./tools/dtoc/dtoc -t;
+       ./tools/dtoc/dtoc -t &&
+       make testconfig;
      fi;
    fi
 
diff --git a/Kconfig b/Kconfig
index f698e0a..1b0b699 100644
--- a/Kconfig
+++ b/Kconfig
@@ -3,11 +3,7 @@
 # see the file Documentation/kbuild/kconfig-language.txt in the
 # Linux kernel source tree.
 #
-mainmenu "U-Boot $UBOOTVERSION Configuration"
-
-config UBOOTVERSION
-	string
-	option env="UBOOTVERSION"
+mainmenu "U-Boot $(UBOOTVERSION) Configuration"
 
 # Allow defaults in arch-specific code to override any given here
 source "arch/Kconfig"
@@ -360,6 +356,8 @@
 	depends on DM
 	select HASH
 	select RSA
+	select RSA_VERIFY
+	select IMAGE_SIGN_INFO
 	help
 	  This option enables signature verification of FIT uImages,
 	  using a hash signed and verified using RSA. If
@@ -448,6 +446,8 @@
 	depends on SPL_DM
 	select SPL_FIT
 	select SPL_RSA
+	select SPL_RSA_VERIFY
+	select IMAGE_SIGN_INFO
 
 config SPL_LOAD_FIT
 	bool "Enable SPL loading U-Boot as a FIT (basic fitImage features)"
diff --git a/Makefile b/Makefile
index c9ae31c..9076979 100644
--- a/Makefile
+++ b/Makefile
@@ -436,6 +436,8 @@
 export KBUILD_CPPFLAGS NOSTDINC_FLAGS UBOOTINCLUDE OBJCOPYFLAGS LDFLAGS
 export KBUILD_CFLAGS KBUILD_AFLAGS
 
+export CC_VERSION_TEXT := $(shell $(CC) --version | head -n 1)
+
 # When compiling out-of-tree modules, put MODVERDIR in the module
 # tree rather than in the kernel tree. The kernel tree might
 # even be read-only.
@@ -711,7 +713,6 @@
 		-include $(srctree)/include/linux/kconfig.h
 
 NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
-CHECKFLAGS     += $(NOSTDINC_FLAGS)
 
 # FIX ME
 cpp_flags := $(KBUILD_CPPFLAGS) $(PLATFORM_CPPFLAGS) $(UBOOTINCLUDE) \
@@ -925,6 +926,12 @@
 LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE)
 endif
 
+# insure the checker run with the right endianness
+CHECKFLAGS += $(if $(CONFIG_CPU_BIG_ENDIAN),-mbig-endian,-mlittle-endian)
+
+# the checker needs the correct machine size
+CHECKFLAGS += $(if $(CONFIG_64BIT),-m64,-m32)
+
 # Normally we fill empty space with 0xff
 quiet_cmd_objcopy = OBJCOPY $@
 cmd_objcopy = $(OBJCOPY) --gap-fill=0xff $(OBJCOPYFLAGS) \
@@ -2207,6 +2214,6 @@
 PHONY += FORCE
 FORCE:
 
-# Declare the contents of the .PHONY variable as phony.  We keep that
+# Declare the contents of the PHONY variable as phony.  We keep that
 # information in a variable so we can use it in if_changed and friends.
 .PHONY: $(PHONY)
diff --git a/arch/arm/dts/am335x-brppt1-mmc.dts b/arch/arm/dts/am335x-brppt1-mmc.dts
index 9be34d9..6f91971 100644
--- a/arch/arm/dts/am335x-brppt1-mmc.dts
+++ b/arch/arm/dts/am335x-brppt1-mmc.dts
@@ -53,6 +53,8 @@
 		bkl-pwm = <&pwmbacklight>;
 		bkl-tps = <&tps_bl>;
 
+		u-boot,dm-pre-reloc;
+
 		panel-info {
 			ac-bias		= <255>;
 			ac-bias-intrpt	= <0>;
diff --git a/arch/arm/dts/am335x-brppt1-nand.dts b/arch/arm/dts/am335x-brppt1-nand.dts
index 11bd5c5..9d4340f 100644
--- a/arch/arm/dts/am335x-brppt1-nand.dts
+++ b/arch/arm/dts/am335x-brppt1-nand.dts
@@ -53,6 +53,8 @@
 		bkl-pwm = <&pwmbacklight>;
 		bkl-tps = <&tps_bl>;
 
+		u-boot,dm-pre-reloc;
+
 		panel-info {
 			ac-bias		= <255>;
 			ac-bias-intrpt	= <0>;
diff --git a/arch/arm/dts/am335x-brppt1-spi.dts b/arch/arm/dts/am335x-brppt1-spi.dts
index 01ab74b..c078af8 100644
--- a/arch/arm/dts/am335x-brppt1-spi.dts
+++ b/arch/arm/dts/am335x-brppt1-spi.dts
@@ -54,6 +54,8 @@
 		bkl-pwm = <&pwmbacklight>;
 		bkl-tps = <&tps_bl>;
 
+		u-boot,dm-pre-reloc;
+
 		panel-info {
 			ac-bias		= <255>;
 			ac-bias-intrpt	= <0>;
diff --git a/arch/arm/dts/am335x-brsmarc1.dts b/arch/arm/dts/am335x-brsmarc1.dts
index a63fc2d..7e9516e 100644
--- a/arch/arm/dts/am335x-brsmarc1.dts
+++ b/arch/arm/dts/am335x-brsmarc1.dts
@@ -59,6 +59,7 @@
 		/*backlight = <&tps_bl>; */
 		compatible = "ti,tilcdc,panel";
 		status = "okay";
+		u-boot,dm-pre-reloc;
 
 		panel-info {
 			ac-bias		= <255>;
diff --git a/arch/arm/dts/am335x-brxre1.dts b/arch/arm/dts/am335x-brxre1.dts
index 33d8ab7..6091a12 100644
--- a/arch/arm/dts/am335x-brxre1.dts
+++ b/arch/arm/dts/am335x-brxre1.dts
@@ -79,6 +79,8 @@
 
 		backlight = <&tps_bl>;
 
+		u-boot,dm-pre-reloc;
+
 		panel-info {
 			ac-bias		= <255>;
 			ac-bias-intrpt	= <0>;
diff --git a/arch/arm/dts/am335x-evm-u-boot.dtsi b/arch/arm/dts/am335x-evm-u-boot.dtsi
index b6b97ed..d7b049e 100644
--- a/arch/arm/dts/am335x-evm-u-boot.dtsi
+++ b/arch/arm/dts/am335x-evm-u-boot.dtsi
@@ -3,6 +3,12 @@
  * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
  */
 
+/ {
+	panel {
+		u-boot,dm-pre-reloc;
+	};
+};
+
 
 &mmc3 {
 	status = "disabled";
diff --git a/arch/arm/dts/am335x-evmsk-u-boot.dtsi b/arch/arm/dts/am335x-evmsk-u-boot.dtsi
new file mode 100644
index 0000000..599fb37
--- /dev/null
+++ b/arch/arm/dts/am335x-evmsk-u-boot.dtsi
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * am335x-evmsk U-Boot Additions
+ *
+ * Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
+ */
+
+/ {
+	panel {
+		u-boot,dm-pre-reloc;
+	};
+};
diff --git a/arch/arm/dts/am335x-guardian-u-boot.dtsi b/arch/arm/dts/am335x-guardian-u-boot.dtsi
index 156b9b0..705ef33 100644
--- a/arch/arm/dts/am335x-guardian-u-boot.dtsi
+++ b/arch/arm/dts/am335x-guardian-u-boot.dtsi
@@ -8,6 +8,10 @@
 	ocp {
 		u-boot,dm-pre-reloc;
 	};
+
+	panel {
+		u-boot,dm-pre-reloc;
+	};
 };
 
 &l4_wkup {
diff --git a/arch/arm/dts/am335x-pdu001-u-boot.dtsi b/arch/arm/dts/am335x-pdu001-u-boot.dtsi
index 84a07bd..a799fe9 100644
--- a/arch/arm/dts/am335x-pdu001-u-boot.dtsi
+++ b/arch/arm/dts/am335x-pdu001-u-boot.dtsi
@@ -7,6 +7,10 @@
 	ocp {
 		u-boot,dm-pre-reloc;
 	};
+
+	panel {
+		u-boot,dm-pre-reloc;
+	};
 };
 
 &l4_wkup {
diff --git a/arch/arm/dts/am335x-pxm50-u-boot.dtsi b/arch/arm/dts/am335x-pxm50-u-boot.dtsi
new file mode 100644
index 0000000..77dfe6e
--- /dev/null
+++ b/arch/arm/dts/am335x-pxm50-u-boot.dtsi
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * am335x-pxm50 U-Boot Additions
+ *
+ * Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
+ */
+
+/ {
+	panel {
+		u-boot,dm-pre-reloc;
+	};
+};
diff --git a/arch/arm/dts/am335x-rut-u-boot.dtsi b/arch/arm/dts/am335x-rut-u-boot.dtsi
new file mode 100644
index 0000000..b2b4aa5
--- /dev/null
+++ b/arch/arm/dts/am335x-rut-u-boot.dtsi
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * am335x-rut U-Boot Additions
+ *
+ * Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
+ */
+
+/ {
+	panel {
+		u-boot,dm-pre-reloc;
+	};
+};
diff --git a/arch/arm/dts/da850-evm-u-boot.dtsi b/arch/arm/dts/da850-evm-u-boot.dtsi
index aa42d30..d9afc5e 100644
--- a/arch/arm/dts/da850-evm-u-boot.dtsi
+++ b/arch/arm/dts/da850-evm-u-boot.dtsi
@@ -14,6 +14,10 @@
 	nand {
 		compatible = "ti,davinci-nand";
 	};
+
+	panel {
+		u-boot,dm-pre-reloc;
+	};
 };
 
 &eth0 {
diff --git a/arch/arm/dts/k3-am65-mcu.dtsi b/arch/arm/dts/k3-am65-mcu.dtsi
index c42e755..bc9a872 100644
--- a/arch/arm/dts/k3-am65-mcu.dtsi
+++ b/arch/arm/dts/k3-am65-mcu.dtsi
@@ -64,4 +64,42 @@
 			loczrama = <1>;
 		};
 	};
+
+	fss: fss@47000000 {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		ospi0: spi@47040000 {
+			compatible = "ti,am654-ospi", "cdns,qspi-nor";
+			reg = <0x0 0x47040000 0x0 0x100>,
+				<0x5 0x00000000 0x1 0x0000000>;
+			interrupts = <GIC_SPI 552 IRQ_TYPE_LEVEL_HIGH>;
+			cdns,fifo-depth = <256>;
+			cdns,fifo-width = <4>;
+			cdns,trigger-address = <0x0>;
+			clocks = <&k3_clks 248 0>;
+			assigned-clocks = <&k3_clks 248 0>;
+			assigned-clock-parents = <&k3_clks 248 2>;
+			assigned-clock-rates = <166666666>;
+			power-domains = <&k3_pds 248 TI_SCI_PD_EXCLUSIVE>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		ospi1: spi@47050000 {
+			compatible = "ti,am654-ospi", "cdns,qspi-nor";
+			reg = <0x0 0x47050000 0x0 0x100>,
+				<0x7 0x00000000 0x1 0x00000000>;
+			interrupts = <GIC_SPI 553 IRQ_TYPE_LEVEL_HIGH>;
+			cdns,fifo-depth = <256>;
+			cdns,fifo-width = <4>;
+			cdns,trigger-address = <0x0>;
+			clocks = <&k3_clks 249 6>;
+			power-domains = <&k3_pds 249 TI_SCI_PD_EXCLUSIVE>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
 };
diff --git a/arch/arm/dts/k3-am65.dtsi b/arch/arm/dts/k3-am65.dtsi
index 3ead944..3d89bf3 100644
--- a/arch/arm/dts/k3-am65.dtsi
+++ b/arch/arm/dts/k3-am65.dtsi
@@ -30,6 +30,8 @@
 		i2c3 = &main_i2c1;
 		i2c4 = &main_i2c2;
 		i2c5 = &main_i2c3;
+		spi0 = &ospi0;
+		spi1 = &ospi1;
 	};
 
 	chosen { };
@@ -79,7 +81,11 @@
 			 <0x00 0x42040000 0x00 0x42040000 0x00 0x03ac2400>,
 			 <0x00 0x45100000 0x00 0x45100000 0x00 0x00c24000>,
 			 <0x00 0x46000000 0x00 0x46000000 0x00 0x00200000>,
-			 <0x00 0x47000000 0x00 0x47000000 0x00 0x00068400>;
+			 <0x00 0x47000000 0x00 0x47000000 0x00 0x00068400>,
+			 <0x00 0x50000000 0x00 0x50000000 0x00 0x8000000>,
+			 <0x00 0x70000000 0x00 0x70000000 0x00 0x200000>,
+			 <0x05 0x00000000 0x05 0x00000000 0x01 0x0000000>,
+			 <0x07 0x00000000 0x07 0x00000000 0x01 0x0000000>;
 
 		cbass_mcu: interconnect@28380000 {
 			compatible = "simple-bus";
@@ -93,7 +99,10 @@
 				 <0x00 0x42040000 0x00 0x42040000 0x00 0x03ac2400>, /* WKUP */
 				 <0x00 0x45100000 0x00 0x45100000 0x00 0x00c24000>, /* MMRs, remaining NAVSS */
 				 <0x00 0x46000000 0x00 0x46000000 0x00 0x00200000>, /* CPSW */
-				 <0x00 0x47000000 0x00 0x47000000 0x00 0x00068400>; /* OSPI space 1 */
+				 <0x00 0x47000000 0x00 0x47000000 0x00 0x00068400>, /* OSPI space 1 */
+				 <0x00 0x50000000 0x00 0x50000000 0x00 0x8000000>, /*  FSS OSPI0 data region 1 */
+				 <0x05 0x00000000 0x05 0x00000000 0x01 0x0000000>, /* FSS OSPI0 data region 3*/
+				 <0x07 0x00000000 0x07 0x00000000 0x01 0x0000000>; /* FSS OSPI1 data region 3*/
 
 			cbass_wakeup: interconnect@42040000 {
 				compatible = "simple-bus";
diff --git a/arch/arm/dts/k3-am654-base-board-u-boot.dtsi b/arch/arm/dts/k3-am654-base-board-u-boot.dtsi
index 54ecb3d..a7e5eb0 100644
--- a/arch/arm/dts/k3-am654-base-board-u-boot.dtsi
+++ b/arch/arm/dts/k3-am654-base-board-u-boot.dtsi
@@ -52,6 +52,7 @@
 		#address-cells = <2>;
 		#size-cells = <2>;
 		ranges;
+		u-boot,dm-spl;
 
 		ti,sci-dev-id = <119>;
 
@@ -68,6 +69,7 @@
 			ti,dma-ring-reset-quirk;
 			ti,sci = <&dmsc>;
 			ti,sci-dev-id = <195>;
+			u-boot,dm-spl;
 		};
 
 		mcu_udmap: udmap@285c0000 {
@@ -90,6 +92,7 @@
 						<0x4>; /* RX_CHAN */
 			ti,sci-rm-range-rflow = <0x5>; /* GP RFLOW */
 			dma-coherent;
+			u-boot,dm-spl;
 		};
 	};
 
@@ -314,6 +317,10 @@
 			AM65X_WKUP_IOPAD(0x0088, PIN_INPUT, 0) /* (L4) MCU_MDIO0_MDIO */
 		>;
 	};
+
+	mcu-fss0-ospi0-pins-default {
+		u-boot,dm-spl;
+	};
 };
 
 &main_uart0 {
@@ -374,3 +381,15 @@
 &usb1 {
 	dr_mode = "peripheral";
 };
+
+&fss {
+	u-boot,dm-spl;
+};
+
+&ospi0 {
+	u-boot,dm-spl;
+
+	 flash@0{
+		u-boot,dm-spl;
+	};
+};
diff --git a/arch/arm/dts/k3-am654-base-board.dts b/arch/arm/dts/k3-am654-base-board.dts
index 7ebbf17..5058b6c 100644
--- a/arch/arm/dts/k3-am654-base-board.dts
+++ b/arch/arm/dts/k3-am654-base-board.dts
@@ -64,6 +64,29 @@
 			AM65X_IOPAD(0x02c0, PIN_OUTPUT, 0) /* (AC8) USB1_DRVVBUS */
 		>;
 	};
+
+	main_i2c2_pins_default: main-i2c2-pins-default {
+		pinctrl-single,pins = <
+			AM65X_IOPAD(0x0074, PIN_INPUT, 5) /* (T27) GPMC0_CSn3.I2C2_SCL */
+			AM65X_IOPAD(0x0070, PIN_INPUT, 5) /* (R25) GPMC0_CSn2.I2C2_SDA */
+		>;
+	};
+};
+
+&main_pmx1 {
+	main_i2c0_pins_default: main-i2c0-pins-default {
+		pinctrl-single,pins = <
+			AM65X_IOPAD(0x0000, PIN_INPUT, 0) /* (D20) I2C0_SCL */
+			AM65X_IOPAD(0x0004, PIN_INPUT, 0) /* (C21) I2C0_SDA */
+		>;
+	};
+
+	main_i2c1_pins_default: main-i2c1-pins-default {
+		pinctrl-single,pins = <
+			AM65X_IOPAD(0x0008, PIN_INPUT, 0) /* (B21) I2C1_SCL */
+			AM65X_IOPAD(0x000c, PIN_INPUT, 0) /* (E21) I2C1_SDA */
+		>;
+	};
 };
 
 &wkup_pmx0 {
@@ -73,6 +96,22 @@
 			AM65X_WKUP_IOPAD(0x00e4, PIN_INPUT, 0) /* (AD6) WKUP_I2C0_SDA */
 		>;
 	};
+
+	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins_default {
+		pinctrl-single,pins = <
+			AM65X_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* (V1) MCU_OSPI0_CLK */
+			AM65X_WKUP_IOPAD(0x0008, PIN_INPUT, 0)	 /* (U2) MCU_OSPI0_DQS */
+			AM65X_WKUP_IOPAD(0x000c, PIN_INPUT, 0)  /* (U4) MCU_OSPI0_D0 */
+			AM65X_WKUP_IOPAD(0x0010, PIN_INPUT, 0)  /* (U5) MCU_OSPI0_D1 */
+			AM65X_WKUP_IOPAD(0x0014, PIN_INPUT, 0)  /* (T2) MCU_OSPI0_D2 */
+			AM65X_WKUP_IOPAD(0x0018, PIN_INPUT, 0)  /* (T3) MCU_OSPI0_D3 */
+			AM65X_WKUP_IOPAD(0x001c, PIN_INPUT, 0)  /* (T4) MCU_OSPI0_D4 */
+			AM65X_WKUP_IOPAD(0x0020, PIN_INPUT, 0)  /* (T5) MCU_OSPI0_D5 */
+			AM65X_WKUP_IOPAD(0x0024, PIN_INPUT, 0)  /* (R2) MCU_OSPI0_D6 */
+			AM65X_WKUP_IOPAD(0x0028, PIN_INPUT, 0)  /* (R3) MCU_OSPI0_D7 */
+			AM65X_WKUP_IOPAD(0x002c, PIN_OUTPUT, 0) /* (R4) MCU_OSPI0_CSn0 */
+		>;
+	};
 };
 
 &sdhci0 {
@@ -96,6 +135,31 @@
 	};
 };
 
+&main_i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_pins_default>;
+	clock-frequency = <400000>;
+
+	pca9555: gpio@21 {
+		compatible = "nxp,pca9555";
+		reg = <0x21>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+};
+
+&main_i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c1_pins_default>;
+	clock-frequency = <400000>;
+};
+
+&main_i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c2_pins_default>;
+	clock-frequency = <400000>;
+};
+
 &dwc3_1 {
 	status = "okay";
 };
@@ -117,3 +181,23 @@
 &usb0_phy {
 	status = "disabled";
 };
+
+&ospi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
+
+	flash@0{
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <40000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+	};
+};
diff --git a/arch/arm/dts/k3-am654-r5-base-board.dts b/arch/arm/dts/k3-am654-r5-base-board.dts
index 5d5689d..257b56a 100644
--- a/arch/arm/dts/k3-am654-r5-base-board.dts
+++ b/arch/arm/dts/k3-am654-r5-base-board.dts
@@ -179,6 +179,22 @@
 			AM65X_WKUP_IOPAD(0x00e4, PIN_INPUT, 0) /* (AD6) WKUP_I2C0_SDA */
 		>;
 	};
+
+	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins_default {
+		pinctrl-single,pins = <
+			AM65X_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* (V1) MCU_OSPI0_CLK */
+			AM65X_WKUP_IOPAD(0x0008, PIN_INPUT, 0)	 /* (U2) MCU_OSPI0_DQS */
+			AM65X_WKUP_IOPAD(0x000c, PIN_INPUT, 0)  /* (U4) MCU_OSPI0_D0 */
+			AM65X_WKUP_IOPAD(0x0010, PIN_INPUT, 0)  /* (U5) MCU_OSPI0_D1 */
+			AM65X_WKUP_IOPAD(0x0014, PIN_INPUT, 0)  /* (T2) MCU_OSPI0_D2 */
+			AM65X_WKUP_IOPAD(0x0018, PIN_INPUT, 0)  /* (T3) MCU_OSPI0_D3 */
+			AM65X_WKUP_IOPAD(0x001c, PIN_INPUT, 0)  /* (T4) MCU_OSPI0_D4 */
+			AM65X_WKUP_IOPAD(0x0020, PIN_INPUT, 0)  /* (T5) MCU_OSPI0_D5 */
+			AM65X_WKUP_IOPAD(0x0024, PIN_INPUT, 0)  /* (R2) MCU_OSPI0_D6 */
+			AM65X_WKUP_IOPAD(0x0028, PIN_INPUT, 0)  /* (R3) MCU_OSPI0_D7 */
+			AM65X_WKUP_IOPAD(0x002c, PIN_OUTPUT, 0) /* (R4) MCU_OSPI0_CSn0 */
+		>;
+	};
 };
 
 &main_pmx0 {
@@ -239,3 +255,26 @@
 		u-boot,dm-spl;
 	};
 };
+
+&ospi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
+
+	reg = <0x0 0x47040000 0x0 0x100>,
+	      <0x0 0x50000000 0x0 0x8000000>;
+
+	flash@0{
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <40000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+	};
+};
diff --git a/arch/arm/dts/k3-j721e-common-proc-board-u-boot.dtsi b/arch/arm/dts/k3-j721e-common-proc-board-u-boot.dtsi
index a3a8193..7b01e42 100644
--- a/arch/arm/dts/k3-j721e-common-proc-board-u-boot.dtsi
+++ b/arch/arm/dts/k3-j721e-common-proc-board-u-boot.dtsi
@@ -349,3 +349,31 @@
 &exp2 {
 	u-boot,dm-spl;
 };
+
+&mcu_fss0_ospi0_pins_default {
+	u-boot,dm-spl;
+};
+
+&fss {
+	u-boot,dm-spl;
+};
+
+&ospi0 {
+	u-boot,dm-spl;
+
+	flash@0 {
+		u-boot,dm-spl;
+	};
+};
+
+&ospi1 {
+	u-boot,dm-spl;
+
+	flash@0 {
+		u-boot,dm-spl;
+	};
+};
+
+&mcu_fss0_ospi1_pins_default {
+	u-boot,dm-spl;
+};
diff --git a/arch/arm/dts/k3-j721e-common-proc-board.dts b/arch/arm/dts/k3-j721e-common-proc-board.dts
index d216b70..496a15e 100644
--- a/arch/arm/dts/k3-j721e-common-proc-board.dts
+++ b/arch/arm/dts/k3-j721e-common-proc-board.dts
@@ -123,6 +123,19 @@
 			J721E_WKUP_IOPAD(0xfc, PIN_INPUT_PULLUP, 0) /* (H24) WKUP_I2C0_SDA */
 		>;
 	};
+
+	mcu_fss0_ospi1_pins_default: mcu-fss0-ospi1-pins-default {
+		pinctrl-single,pins = <
+			J721E_WKUP_IOPAD(0x34, PIN_OUTPUT, 0) /* (F22) MCU_OSPI1_CLK */
+			J721E_WKUP_IOPAD(0x50, PIN_OUTPUT, 0) /* (C22) MCU_OSPI1_CSn0 */
+			J721E_WKUP_IOPAD(0x40, PIN_INPUT, 0) /* (D22) MCU_OSPI1_D0 */
+			J721E_WKUP_IOPAD(0x44, PIN_INPUT, 0) /* (G22) MCU_OSPI1_D1 */
+			J721E_WKUP_IOPAD(0x48, PIN_INPUT, 0) /* (D23) MCU_OSPI1_D2 */
+			J721E_WKUP_IOPAD(0x4c, PIN_INPUT, 0) /* (C23) MCU_OSPI1_D3 */
+			J721E_WKUP_IOPAD(0x3c, PIN_INPUT, 0) /* (B23) MCU_OSPI1_DQS */
+			J721E_WKUP_IOPAD(0x38, PIN_INPUT, 0) /* (A23) MCU_OSPI1_LBCLKO */
+		>;
+	};
 };
 
 &usbss0 {
@@ -172,3 +185,23 @@
 		#gpio-cells = <2>;
 	};
 };
+
+&ospi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_fss0_ospi1_pins_default>;
+
+	flash@0{
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <40000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <2>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+	};
+};
diff --git a/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi b/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi
index fe52fd1..2eed50a 100644
--- a/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi
+++ b/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi
@@ -143,6 +143,39 @@
 			assigned-clocks = <&k3_clks 102 0>;
 			assigned-clock-rates = <250000000>;
 		};
+
+		ospi0: spi@47040000 {
+			compatible = "ti,am654-ospi";
+			reg = <0x0 0x47040000 0x0 0x100>,
+				<0x5 0x00000000 0x1 0x0000000>;
+			interrupts = <GIC_SPI 840 IRQ_TYPE_LEVEL_HIGH>;
+			cdns,fifo-depth = <256>;
+			cdns,fifo-width = <4>;
+			cdns,trigger-address = <0x0>;
+			clocks = <&k3_clks 103 0>;
+			assigned-clocks = <&k3_clks 103 0>;
+			assigned-clock-parents = <&k3_clks 103 2>;
+			assigned-clock-rates = <166666666>;
+			power-domains = <&k3_pds 103 TI_SCI_PD_EXCLUSIVE>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		ospi1: spi@47050000 {
+			compatible = "ti,am654-ospi";
+			reg = <0x0 0x47050000 0x0 0x100>,
+				<0x7 0x00000000 0x1 0x00000000>;
+			interrupts = <GIC_SPI 841 IRQ_TYPE_LEVEL_HIGH>;
+			cdns,fifo-depth = <256>;
+			cdns,fifo-width = <4>;
+			cdns,trigger-address = <0x0>;
+			clocks = <&k3_clks 104 0>;
+			assigned-clocks = <&k3_clks 104 0>;
+			assigned-clock-rates = <133333333>;
+			power-domains = <&k3_pds 104 TI_SCI_PD_EXCLUSIVE>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
 	};
 
 	mcu_i2c0: i2c@40b00000 {
diff --git a/arch/arm/dts/k3-j721e-r5-common-proc-board-u-boot.dtsi b/arch/arm/dts/k3-j721e-r5-common-proc-board-u-boot.dtsi
new file mode 100644
index 0000000..824b301
--- /dev/null
+++ b/arch/arm/dts/k3-j721e-r5-common-proc-board-u-boot.dtsi
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/ {
+	chosen {
+		firmware-loader = &fs_loader0;
+	};
+
+	fs_loader0: fs_loader@0 {
+		u-boot,dm-pre-reloc;
+		compatible = "u-boot,fs-loader";
+	};
+};
+
+&main_r5fss0 {
+	u-boot,dm-spl;
+};
+
+&main_r5fss0_core0 {
+	u-boot,dm-spl;
+};
+
+&main_r5fss0_core1 {
+	u-boot,dm-spl;
+};
+
+&tps659413a {
+	esm: esm {
+		compatible = "ti,tps659413-esm";
+		u-boot,dm-spl;
+	};
+};
diff --git a/arch/arm/dts/k3-j721e-r5-common-proc-board.dts b/arch/arm/dts/k3-j721e-r5-common-proc-board.dts
index 5973e21..403b158 100644
--- a/arch/arm/dts/k3-j721e-r5-common-proc-board.dts
+++ b/arch/arm/dts/k3-j721e-r5-common-proc-board.dts
@@ -13,6 +13,8 @@
 	aliases {
 		remoteproc0 = &sysctrler;
 		remoteproc1 = &a72_0;
+		remoteproc2 = &main_r5fss0_core0;
+		remoteproc3 = &main_r5fss0_core1;
 	};
 
 	chosen {
@@ -75,6 +77,15 @@
 	};
 };
 
+&cbass_main {
+	main_esm: esm@700000 {
+		compatible = "ti,j721e-esm";
+		reg = <0x0 0x700000 0x0 0x1000>;
+		ti,esm-pins = <344>, <345>;
+		u-boot,dm-spl;
+	};
+};
+
 &dmsc {
 	mboxes= <&mcu_secproxy 8>, <&mcu_secproxy 6>, <&mcu_secproxy 5>;
 	mbox-names = "tx", "rx", "notify";
@@ -107,6 +118,36 @@
 			J721E_WKUP_IOPAD(0xfc, PIN_INPUT_PULLUP, 0) /* (H24) WKUP_I2C0_SDA */
 		>;
 	};
+
+	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins-default {
+		pinctrl-single,pins = <
+			J721E_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* MCU_OSPI0_CLK */
+			J721E_WKUP_IOPAD(0x0008, PIN_INPUT, 0)  /* MCU_OSPI0_DQS */
+			J721E_WKUP_IOPAD(0x000c, PIN_INPUT, 0)  /* MCU_OSPI0_D0 */
+			J721E_WKUP_IOPAD(0x0010, PIN_INPUT, 0)  /* MCU_OSPI0_D1 */
+			J721E_WKUP_IOPAD(0x0014, PIN_INPUT, 0)  /* MCU_OSPI0_D2 */
+			J721E_WKUP_IOPAD(0x0018, PIN_INPUT, 0)  /* MCU_OSPI0_D3 */
+			J721E_WKUP_IOPAD(0x001c, PIN_INPUT, 0)  /* MCU_OSPI0_D4 */
+			J721E_WKUP_IOPAD(0x0020, PIN_INPUT, 0)  /* MCU_OSPI0_D5 */
+			J721E_WKUP_IOPAD(0x0024, PIN_INPUT, 0)  /* MCU_OSPI0_D6 */
+			J721E_WKUP_IOPAD(0x0028, PIN_INPUT, 0)  /* MCU_OSPI0_D7 */
+			J721E_WKUP_IOPAD(0x002c, PIN_OUTPUT, 0) /* MCU_OSPI0_CSn0 */
+		>;
+	};
+
+	mcu_fss0_ospi1_pins_default: mcu-fss0-ospi1-pins-default {
+		u-boot,dm-spl;
+		pinctrl-single,pins = <
+			J721E_WKUP_IOPAD(0x34, PIN_OUTPUT, 0) /* (F22) MCU_OSPI1_CLK */
+			J721E_WKUP_IOPAD(0x50, PIN_OUTPUT, 0) /* (C22) MCU_OSPI1_CSn0 */
+			J721E_WKUP_IOPAD(0x40, PIN_INPUT, 0) /* (D22) MCU_OSPI1_D0 */
+			J721E_WKUP_IOPAD(0x44, PIN_INPUT, 0) /* (G22) MCU_OSPI1_D1 */
+			J721E_WKUP_IOPAD(0x48, PIN_INPUT, 0) /* (D23) MCU_OSPI1_D2 */
+			J721E_WKUP_IOPAD(0x4c, PIN_INPUT, 0) /* (C23) MCU_OSPI1_D3 */
+			J721E_WKUP_IOPAD(0x3c, PIN_INPUT, 0) /* (B23) MCU_OSPI1_DQS */
+			J721E_WKUP_IOPAD(0x38, PIN_INPUT, 0) /* (A23) MCU_OSPI1_LBCLKO */
+		>;
+	};
 };
 
 &main_pmx0 {
@@ -256,4 +297,52 @@
 	};
 };
 
+&ospi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
+
+	reg = <0x0 0x47040000 0x0 0x100>,
+	      <0x0 0x50000000 0x0 0x8000000>;
+
+	flash@0{
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <40000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+	};
+};
+
+&ospi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_fss0_ospi1_pins_default>;
+	u-boot,dm-spl;
+
+	reg = <0x0 0x47050000 0x0 0x100>,
+	      <0x0 0x58000000 0x0 0x8000000>;
+
+	flash@0{
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <40000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <2>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		u-boot,dm-spl;
+	};
+};
+
 #include "k3-j721e-common-proc-board-u-boot.dtsi"
diff --git a/arch/arm/dts/k3-j721e-som-p0.dtsi b/arch/arm/dts/k3-j721e-som-p0.dtsi
index 1e1519f..8497ff3 100644
--- a/arch/arm/dts/k3-j721e-som-p0.dtsi
+++ b/arch/arm/dts/k3-j721e-som-p0.dtsi
@@ -47,6 +47,22 @@
 			J721E_WKUP_IOPAD(0x28, PIN_INPUT, 1) /* (G21) MCU_OSPI0_D7.MCU_HYPERBUS0_DQ7 */
 		>;
 	};
+
+	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins-default {
+		pinctrl-single,pins = <
+			J721E_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* MCU_OSPI0_CLK */
+			J721E_WKUP_IOPAD(0x0008, PIN_INPUT, 0)  /* MCU_OSPI0_DQS */
+			J721E_WKUP_IOPAD(0x000c, PIN_INPUT, 0)  /* MCU_OSPI0_D0 */
+			J721E_WKUP_IOPAD(0x0010, PIN_INPUT, 0)  /* MCU_OSPI0_D1 */
+			J721E_WKUP_IOPAD(0x0014, PIN_INPUT, 0)  /* MCU_OSPI0_D2 */
+			J721E_WKUP_IOPAD(0x0018, PIN_INPUT, 0)  /* MCU_OSPI0_D3 */
+			J721E_WKUP_IOPAD(0x001c, PIN_INPUT, 0)  /* MCU_OSPI0_D4 */
+			J721E_WKUP_IOPAD(0x0020, PIN_INPUT, 0)  /* MCU_OSPI0_D5 */
+			J721E_WKUP_IOPAD(0x0024, PIN_INPUT, 0)  /* MCU_OSPI0_D6 */
+			J721E_WKUP_IOPAD(0x0028, PIN_INPUT, 0)  /* MCU_OSPI0_D7 */
+			J721E_WKUP_IOPAD(0x002c, PIN_OUTPUT, 0) /* MCU_OSPI0_CSn0 */
+		>;
+	};
 };
 
 &hbmc {
@@ -61,3 +77,23 @@
 		reg = <0x0 0x0 0x4000000>;
 	};
 };
+
+&ospi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
+
+	flash@0{
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <40000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+	};
+};
diff --git a/arch/arm/dts/k3-j721e.dtsi b/arch/arm/dts/k3-j721e.dtsi
index 68ba517..6bd5aab 100644
--- a/arch/arm/dts/k3-j721e.dtsi
+++ b/arch/arm/dts/k3-j721e.dtsi
@@ -40,6 +40,8 @@
 		i2c7 = &main_i2c4;
 		i2c8 = &main_i2c5;
 		i2c9 = &main_i2c6;
+		spi0 = &ospi0;
+		spi1 = &ospi1;
 	};
 
 	chosen { };
@@ -135,6 +137,7 @@
 		#size-cells = <2>;
 		ranges = <0x00 0x00100000 0x00 0x00100000 0x00 0x00020000>, /* ctrl mmr */
 			 <0x00 0x00600000 0x00 0x00600000 0x00 0x00031100>, /* GPIO */
+			 <0x00 0x00700000 0x00 0x00700000 0x00 0x00001000>, /* ESM */
 			 <0x00 0x00900000 0x00 0x00900000 0x00 0x00012000>, /* serdes */
 			 <0x00 0x00A40000 0x00 0x00A40000 0x00 0x00000800>, /* timesync router */
 			 <0x00 0x01000000 0x00 0x01000000 0x00 0x0af02400>, /* Most peripherals */
diff --git a/arch/arm/dts/stm32mp15-ddr.dtsi b/arch/arm/dts/stm32mp15-ddr.dtsi
index 38f29bb..8b20b5e 100644
--- a/arch/arm/dts/stm32mp15-ddr.dtsi
+++ b/arch/arm/dts/stm32mp15-ddr.dtsi
@@ -133,6 +133,7 @@
 				DDR_MR3
 			>;
 
+#ifdef DDR_PHY_CAL_SKIP
 			st,phy-cal = <
 				DDR_DX0DLLCR
 				DDR_DX0DQTR
@@ -148,6 +149,8 @@
 				DDR_DX3DQSTR
 			>;
 
+#endif
+
 			status = "okay";
 		};
 	};
diff --git a/arch/arm/dts/stm32mp15-pinctrl.dtsi b/arch/arm/dts/stm32mp15-pinctrl.dtsi
new file mode 100644
index 0000000..53df840
--- /dev/null
+++ b/arch/arm/dts/stm32mp15-pinctrl.dtsi
@@ -0,0 +1,1114 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
+ */
+#include <dt-bindings/pinctrl/stm32-pinfunc.h>
+
+&pinctrl {
+	adc1_in6_pins_a: adc1-in6 {
+		pins {
+			pinmux = <STM32_PINMUX('F', 12, ANALOG)>;
+		};
+	};
+
+	adc12_ain_pins_a: adc12-ain-0 {
+		pins {
+			pinmux = <STM32_PINMUX('C', 3, ANALOG)>, /* ADC1 in13 */
+				 <STM32_PINMUX('F', 12, ANALOG)>, /* ADC1 in6 */
+				 <STM32_PINMUX('F', 13, ANALOG)>, /* ADC2 in2 */
+				 <STM32_PINMUX('F', 14, ANALOG)>; /* ADC2 in6 */
+		};
+	};
+
+	adc12_usb_cc_pins_a: adc12-usb-cc-pins-0 {
+		pins {
+			pinmux = <STM32_PINMUX('A', 4, ANALOG)>, /* ADC12 in18 */
+				 <STM32_PINMUX('A', 5, ANALOG)>; /* ADC12 in19 */
+		};
+	};
+
+	cec_pins_a: cec-0 {
+		pins {
+			pinmux = <STM32_PINMUX('A', 15, AF4)>;
+			bias-disable;
+			drive-open-drain;
+			slew-rate = <0>;
+		};
+	};
+
+	cec_pins_sleep_a: cec-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('A', 15, ANALOG)>; /* HDMI_CEC */
+		};
+	};
+
+	cec_pins_b: cec-1 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 6, AF5)>;
+			bias-disable;
+			drive-open-drain;
+			slew-rate = <0>;
+		};
+	};
+
+	cec_pins_sleep_b: cec-sleep-1 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 6, ANALOG)>; /* HDMI_CEC */
+		};
+	};
+
+	dac_ch1_pins_a: dac-ch1 {
+		pins {
+			pinmux = <STM32_PINMUX('A', 4, ANALOG)>;
+		};
+	};
+
+	dac_ch2_pins_a: dac-ch2 {
+		pins {
+			pinmux = <STM32_PINMUX('A', 5, ANALOG)>;
+		};
+	};
+
+	dcmi_pins_a: dcmi-0 {
+		pins {
+			pinmux = <STM32_PINMUX('H', 8,  AF13)>,/* DCMI_HSYNC */
+				 <STM32_PINMUX('B', 7,  AF13)>,/* DCMI_VSYNC */
+				 <STM32_PINMUX('A', 6,  AF13)>,/* DCMI_PIXCLK */
+				 <STM32_PINMUX('H', 9,  AF13)>,/* DCMI_D0 */
+				 <STM32_PINMUX('H', 10, AF13)>,/* DCMI_D1 */
+				 <STM32_PINMUX('H', 11, AF13)>,/* DCMI_D2 */
+				 <STM32_PINMUX('H', 12, AF13)>,/* DCMI_D3 */
+				 <STM32_PINMUX('H', 14, AF13)>,/* DCMI_D4 */
+				 <STM32_PINMUX('I', 4,  AF13)>,/* DCMI_D5 */
+				 <STM32_PINMUX('B', 8,  AF13)>,/* DCMI_D6 */
+				 <STM32_PINMUX('E', 6,  AF13)>,/* DCMI_D7 */
+				 <STM32_PINMUX('I', 1,  AF13)>,/* DCMI_D8 */
+				 <STM32_PINMUX('H', 7,  AF13)>,/* DCMI_D9 */
+				 <STM32_PINMUX('I', 3,  AF13)>,/* DCMI_D10 */
+				 <STM32_PINMUX('H', 15, AF13)>;/* DCMI_D11 */
+			bias-disable;
+		};
+	};
+
+	dcmi_sleep_pins_a: dcmi-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('H', 8,  ANALOG)>,/* DCMI_HSYNC */
+				 <STM32_PINMUX('B', 7,  ANALOG)>,/* DCMI_VSYNC */
+				 <STM32_PINMUX('A', 6,  ANALOG)>,/* DCMI_PIXCLK */
+				 <STM32_PINMUX('H', 9,  ANALOG)>,/* DCMI_D0 */
+				 <STM32_PINMUX('H', 10, ANALOG)>,/* DCMI_D1 */
+				 <STM32_PINMUX('H', 11, ANALOG)>,/* DCMI_D2 */
+				 <STM32_PINMUX('H', 12, ANALOG)>,/* DCMI_D3 */
+				 <STM32_PINMUX('H', 14, ANALOG)>,/* DCMI_D4 */
+				 <STM32_PINMUX('I', 4,  ANALOG)>,/* DCMI_D5 */
+				 <STM32_PINMUX('B', 8,  ANALOG)>,/* DCMI_D6 */
+				 <STM32_PINMUX('E', 6,  ANALOG)>,/* DCMI_D7 */
+				 <STM32_PINMUX('I', 1,  ANALOG)>,/* DCMI_D8 */
+				 <STM32_PINMUX('H', 7,  ANALOG)>,/* DCMI_D9 */
+				 <STM32_PINMUX('I', 3,  ANALOG)>,/* DCMI_D10 */
+				 <STM32_PINMUX('H', 15, ANALOG)>;/* DCMI_D11 */
+		};
+	};
+
+	ethernet0_rgmii_pins_a: rgmii-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('G', 5, AF11)>, /* ETH_RGMII_CLK125 */
+				 <STM32_PINMUX('G', 4, AF11)>, /* ETH_RGMII_GTX_CLK */
+				 <STM32_PINMUX('G', 13, AF11)>, /* ETH_RGMII_TXD0 */
+				 <STM32_PINMUX('G', 14, AF11)>, /* ETH_RGMII_TXD1 */
+				 <STM32_PINMUX('C', 2, AF11)>, /* ETH_RGMII_TXD2 */
+				 <STM32_PINMUX('E', 2, AF11)>, /* ETH_RGMII_TXD3 */
+				 <STM32_PINMUX('B', 11, AF11)>, /* ETH_RGMII_TX_CTL */
+				 <STM32_PINMUX('C', 1, AF11)>; /* ETH_MDC */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <2>;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('A', 2, AF11)>; /* ETH_MDIO */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+		pins3 {
+			pinmux = <STM32_PINMUX('C', 4, AF11)>, /* ETH_RGMII_RXD0 */
+				 <STM32_PINMUX('C', 5, AF11)>, /* ETH_RGMII_RXD1 */
+				 <STM32_PINMUX('B', 0, AF11)>, /* ETH_RGMII_RXD2 */
+				 <STM32_PINMUX('B', 1, AF11)>, /* ETH_RGMII_RXD3 */
+				 <STM32_PINMUX('A', 1, AF11)>, /* ETH_RGMII_RX_CLK */
+				 <STM32_PINMUX('A', 7, AF11)>; /* ETH_RGMII_RX_CTL */
+			bias-disable;
+		};
+	};
+
+	ethernet0_rgmii_pins_sleep_a: rgmii-sleep-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('G', 5, ANALOG)>, /* ETH_RGMII_CLK125 */
+				 <STM32_PINMUX('G', 4, ANALOG)>, /* ETH_RGMII_GTX_CLK */
+				 <STM32_PINMUX('G', 13, ANALOG)>, /* ETH_RGMII_TXD0 */
+				 <STM32_PINMUX('G', 14, ANALOG)>, /* ETH_RGMII_TXD1 */
+				 <STM32_PINMUX('C', 2, ANALOG)>, /* ETH_RGMII_TXD2 */
+				 <STM32_PINMUX('E', 2, ANALOG)>, /* ETH_RGMII_TXD3 */
+				 <STM32_PINMUX('B', 11, ANALOG)>, /* ETH_RGMII_TX_CTL */
+				 <STM32_PINMUX('A', 2, ANALOG)>, /* ETH_MDIO */
+				 <STM32_PINMUX('C', 1, ANALOG)>, /* ETH_MDC */
+				 <STM32_PINMUX('C', 4, ANALOG)>, /* ETH_RGMII_RXD0 */
+				 <STM32_PINMUX('C', 5, ANALOG)>, /* ETH_RGMII_RXD1 */
+				 <STM32_PINMUX('B', 0, ANALOG)>, /* ETH_RGMII_RXD2 */
+				 <STM32_PINMUX('B', 1, ANALOG)>, /* ETH_RGMII_RXD3 */
+				 <STM32_PINMUX('A', 1, ANALOG)>, /* ETH_RGMII_RX_CLK */
+				 <STM32_PINMUX('A', 7, ANALOG)>; /* ETH_RGMII_RX_CTL */
+		};
+	};
+
+	fmc_pins_a: fmc-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('D', 4, AF12)>, /* FMC_NOE */
+				 <STM32_PINMUX('D', 5, AF12)>, /* FMC_NWE */
+				 <STM32_PINMUX('D', 11, AF12)>, /* FMC_A16_FMC_CLE */
+				 <STM32_PINMUX('D', 12, AF12)>, /* FMC_A17_FMC_ALE */
+				 <STM32_PINMUX('D', 14, AF12)>, /* FMC_D0 */
+				 <STM32_PINMUX('D', 15, AF12)>, /* FMC_D1 */
+				 <STM32_PINMUX('D', 0, AF12)>, /* FMC_D2 */
+				 <STM32_PINMUX('D', 1, AF12)>, /* FMC_D3 */
+				 <STM32_PINMUX('E', 7, AF12)>, /* FMC_D4 */
+				 <STM32_PINMUX('E', 8, AF12)>, /* FMC_D5 */
+				 <STM32_PINMUX('E', 9, AF12)>, /* FMC_D6 */
+				 <STM32_PINMUX('E', 10, AF12)>, /* FMC_D7 */
+				 <STM32_PINMUX('G', 9, AF12)>; /* FMC_NE2_FMC_NCE */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <1>;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('D', 6, AF12)>; /* FMC_NWAIT */
+			bias-pull-up;
+		};
+	};
+
+	fmc_sleep_pins_a: fmc-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('D', 4, ANALOG)>, /* FMC_NOE */
+				 <STM32_PINMUX('D', 5, ANALOG)>, /* FMC_NWE */
+				 <STM32_PINMUX('D', 11, ANALOG)>, /* FMC_A16_FMC_CLE */
+				 <STM32_PINMUX('D', 12, ANALOG)>, /* FMC_A17_FMC_ALE */
+				 <STM32_PINMUX('D', 14, ANALOG)>, /* FMC_D0 */
+				 <STM32_PINMUX('D', 15, ANALOG)>, /* FMC_D1 */
+				 <STM32_PINMUX('D', 0, ANALOG)>, /* FMC_D2 */
+				 <STM32_PINMUX('D', 1, ANALOG)>, /* FMC_D3 */
+				 <STM32_PINMUX('E', 7, ANALOG)>, /* FMC_D4 */
+				 <STM32_PINMUX('E', 8, ANALOG)>, /* FMC_D5 */
+				 <STM32_PINMUX('E', 9, ANALOG)>, /* FMC_D6 */
+				 <STM32_PINMUX('E', 10, ANALOG)>, /* FMC_D7 */
+				 <STM32_PINMUX('D', 6, ANALOG)>, /* FMC_NWAIT */
+				 <STM32_PINMUX('G', 9, ANALOG)>; /* FMC_NE2_FMC_NCE */
+		};
+	};
+
+	i2c1_pins_a: i2c1-0 {
+		pins {
+			pinmux = <STM32_PINMUX('D', 12, AF5)>, /* I2C1_SCL */
+				 <STM32_PINMUX('F', 15, AF5)>; /* I2C1_SDA */
+			bias-disable;
+			drive-open-drain;
+			slew-rate = <0>;
+		};
+	};
+
+	i2c1_pins_sleep_a: i2c1-1 {
+		pins {
+			pinmux = <STM32_PINMUX('D', 12, ANALOG)>, /* I2C1_SCL */
+				 <STM32_PINMUX('F', 15, ANALOG)>; /* I2C1_SDA */
+		};
+	};
+
+	i2c1_pins_b: i2c1-2 {
+		pins {
+			pinmux = <STM32_PINMUX('F', 14, AF5)>, /* I2C1_SCL */
+				 <STM32_PINMUX('F', 15, AF5)>; /* I2C1_SDA */
+			bias-disable;
+			drive-open-drain;
+			slew-rate = <0>;
+		};
+	};
+
+	i2c1_pins_sleep_b: i2c1-3 {
+		pins {
+			pinmux = <STM32_PINMUX('F', 14, ANALOG)>, /* I2C1_SCL */
+				 <STM32_PINMUX('F', 15, ANALOG)>; /* I2C1_SDA */
+		};
+	};
+
+	i2c2_pins_a: i2c2-0 {
+		pins {
+			pinmux = <STM32_PINMUX('H', 4, AF4)>, /* I2C2_SCL */
+				 <STM32_PINMUX('H', 5, AF4)>; /* I2C2_SDA */
+			bias-disable;
+			drive-open-drain;
+			slew-rate = <0>;
+		};
+	};
+
+	i2c2_pins_sleep_a: i2c2-1 {
+		pins {
+			pinmux = <STM32_PINMUX('H', 4, ANALOG)>, /* I2C2_SCL */
+				 <STM32_PINMUX('H', 5, ANALOG)>; /* I2C2_SDA */
+		};
+	};
+
+	i2c2_pins_b1: i2c2-2 {
+		pins {
+			pinmux = <STM32_PINMUX('H', 5, AF4)>; /* I2C2_SDA */
+			bias-disable;
+			drive-open-drain;
+			slew-rate = <0>;
+		};
+	};
+
+	i2c2_pins_sleep_b1: i2c2-3 {
+		pins {
+			pinmux = <STM32_PINMUX('H', 5, ANALOG)>; /* I2C2_SDA */
+		};
+	};
+
+	i2c5_pins_a: i2c5-0 {
+		pins {
+			pinmux = <STM32_PINMUX('A', 11, AF4)>, /* I2C5_SCL */
+				 <STM32_PINMUX('A', 12, AF4)>; /* I2C5_SDA */
+			bias-disable;
+			drive-open-drain;
+			slew-rate = <0>;
+		};
+	};
+
+	i2c5_pins_sleep_a: i2c5-1 {
+		pins {
+			pinmux = <STM32_PINMUX('A', 11, ANALOG)>, /* I2C5_SCL */
+				 <STM32_PINMUX('A', 12, ANALOG)>; /* I2C5_SDA */
+
+		};
+	};
+
+	i2s2_pins_a: i2s2-0 {
+		pins {
+			pinmux = <STM32_PINMUX('I', 3, AF5)>, /* I2S2_SDO */
+				 <STM32_PINMUX('B', 9, AF5)>, /* I2S2_WS */
+				 <STM32_PINMUX('A', 9, AF5)>; /* I2S2_CK */
+			slew-rate = <1>;
+			drive-push-pull;
+			bias-disable;
+		};
+	};
+
+	i2s2_pins_sleep_a: i2s2-1 {
+		pins {
+			pinmux = <STM32_PINMUX('I', 3, ANALOG)>, /* I2S2_SDO */
+				 <STM32_PINMUX('B', 9, ANALOG)>, /* I2S2_WS */
+				 <STM32_PINMUX('A', 9, ANALOG)>; /* I2S2_CK */
+		};
+	};
+
+	ltdc_pins_a: ltdc-a-0 {
+		pins {
+			pinmux = <STM32_PINMUX('G',  7, AF14)>, /* LCD_CLK */
+				 <STM32_PINMUX('I', 10, AF14)>, /* LCD_HSYNC */
+				 <STM32_PINMUX('I',  9, AF14)>, /* LCD_VSYNC */
+				 <STM32_PINMUX('F', 10, AF14)>, /* LCD_DE */
+				 <STM32_PINMUX('H',  2, AF14)>, /* LCD_R0 */
+				 <STM32_PINMUX('H',  3, AF14)>, /* LCD_R1 */
+				 <STM32_PINMUX('H',  8, AF14)>, /* LCD_R2 */
+				 <STM32_PINMUX('H',  9, AF14)>, /* LCD_R3 */
+				 <STM32_PINMUX('H', 10, AF14)>, /* LCD_R4 */
+				 <STM32_PINMUX('C',  0, AF14)>, /* LCD_R5 */
+				 <STM32_PINMUX('H', 12, AF14)>, /* LCD_R6 */
+				 <STM32_PINMUX('E', 15, AF14)>, /* LCD_R7 */
+				 <STM32_PINMUX('E',  5, AF14)>, /* LCD_G0 */
+				 <STM32_PINMUX('E',  6, AF14)>, /* LCD_G1 */
+				 <STM32_PINMUX('H', 13, AF14)>, /* LCD_G2 */
+				 <STM32_PINMUX('H', 14, AF14)>, /* LCD_G3 */
+				 <STM32_PINMUX('H', 15, AF14)>, /* LCD_G4 */
+				 <STM32_PINMUX('I',  0, AF14)>, /* LCD_G5 */
+				 <STM32_PINMUX('I',  1, AF14)>, /* LCD_G6 */
+				 <STM32_PINMUX('I',  2, AF14)>, /* LCD_G7 */
+				 <STM32_PINMUX('D',  9, AF14)>, /* LCD_B0 */
+				 <STM32_PINMUX('G', 12, AF14)>, /* LCD_B1 */
+				 <STM32_PINMUX('G', 10, AF14)>, /* LCD_B2 */
+				 <STM32_PINMUX('D', 10, AF14)>, /* LCD_B3 */
+				 <STM32_PINMUX('I',  4, AF14)>, /* LCD_B4 */
+				 <STM32_PINMUX('A',  3, AF14)>, /* LCD_B5 */
+				 <STM32_PINMUX('B',  8, AF14)>, /* LCD_B6 */
+				 <STM32_PINMUX('D',  8, AF14)>; /* LCD_B7 */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <1>;
+		};
+	};
+
+	ltdc_pins_sleep_a: ltdc-a-1 {
+		pins {
+			pinmux = <STM32_PINMUX('G',  7, ANALOG)>, /* LCD_CLK */
+				 <STM32_PINMUX('I', 10, ANALOG)>, /* LCD_HSYNC */
+				 <STM32_PINMUX('I',  9, ANALOG)>, /* LCD_VSYNC */
+				 <STM32_PINMUX('F', 10, ANALOG)>, /* LCD_DE */
+				 <STM32_PINMUX('H',  2, ANALOG)>, /* LCD_R0 */
+				 <STM32_PINMUX('H',  3, ANALOG)>, /* LCD_R1 */
+				 <STM32_PINMUX('H',  8, ANALOG)>, /* LCD_R2 */
+				 <STM32_PINMUX('H',  9, ANALOG)>, /* LCD_R3 */
+				 <STM32_PINMUX('H', 10, ANALOG)>, /* LCD_R4 */
+				 <STM32_PINMUX('C',  0, ANALOG)>, /* LCD_R5 */
+				 <STM32_PINMUX('H', 12, ANALOG)>, /* LCD_R6 */
+				 <STM32_PINMUX('E', 15, ANALOG)>, /* LCD_R7 */
+				 <STM32_PINMUX('E',  5, ANALOG)>, /* LCD_G0 */
+				 <STM32_PINMUX('E',  6, ANALOG)>, /* LCD_G1 */
+				 <STM32_PINMUX('H', 13, ANALOG)>, /* LCD_G2 */
+				 <STM32_PINMUX('H', 14, ANALOG)>, /* LCD_G3 */
+				 <STM32_PINMUX('H', 15, ANALOG)>, /* LCD_G4 */
+				 <STM32_PINMUX('I',  0, ANALOG)>, /* LCD_G5 */
+				 <STM32_PINMUX('I',  1, ANALOG)>, /* LCD_G6 */
+				 <STM32_PINMUX('I',  2, ANALOG)>, /* LCD_G7 */
+				 <STM32_PINMUX('D',  9, ANALOG)>, /* LCD_B0 */
+				 <STM32_PINMUX('G', 12, ANALOG)>, /* LCD_B1 */
+				 <STM32_PINMUX('G', 10, ANALOG)>, /* LCD_B2 */
+				 <STM32_PINMUX('D', 10, ANALOG)>, /* LCD_B3 */
+				 <STM32_PINMUX('I',  4, ANALOG)>, /* LCD_B4 */
+				 <STM32_PINMUX('A',  3, ANALOG)>, /* LCD_B5 */
+				 <STM32_PINMUX('B',  8, ANALOG)>, /* LCD_B6 */
+				 <STM32_PINMUX('D',  8, ANALOG)>; /* LCD_B7 */
+		};
+	};
+
+	ltdc_pins_b: ltdc-b-0 {
+		pins {
+			pinmux = <STM32_PINMUX('I', 14, AF14)>, /* LCD_CLK */
+				 <STM32_PINMUX('I', 12, AF14)>, /* LCD_HSYNC */
+				 <STM32_PINMUX('I', 13, AF14)>, /* LCD_VSYNC */
+				 <STM32_PINMUX('K',  7, AF14)>, /* LCD_DE */
+				 <STM32_PINMUX('I', 15, AF14)>, /* LCD_R0 */
+				 <STM32_PINMUX('J',  0, AF14)>, /* LCD_R1 */
+				 <STM32_PINMUX('J',  1, AF14)>, /* LCD_R2 */
+				 <STM32_PINMUX('J',  2, AF14)>, /* LCD_R3 */
+				 <STM32_PINMUX('J',  3, AF14)>, /* LCD_R4 */
+				 <STM32_PINMUX('J',  4, AF14)>, /* LCD_R5 */
+				 <STM32_PINMUX('J',  5, AF14)>, /* LCD_R6 */
+				 <STM32_PINMUX('J',  6, AF14)>, /* LCD_R7 */
+				 <STM32_PINMUX('J',  7, AF14)>, /* LCD_G0 */
+				 <STM32_PINMUX('J',  8, AF14)>, /* LCD_G1 */
+				 <STM32_PINMUX('J',  9, AF14)>, /* LCD_G2 */
+				 <STM32_PINMUX('J', 10, AF14)>, /* LCD_G3 */
+				 <STM32_PINMUX('J', 11, AF14)>, /* LCD_G4 */
+				 <STM32_PINMUX('K',  0, AF14)>, /* LCD_G5 */
+				 <STM32_PINMUX('K',  1, AF14)>, /* LCD_G6 */
+				 <STM32_PINMUX('K',  2, AF14)>, /* LCD_G7 */
+				 <STM32_PINMUX('J', 12, AF14)>, /* LCD_B0 */
+				 <STM32_PINMUX('J', 13, AF14)>, /* LCD_B1 */
+				 <STM32_PINMUX('J', 14, AF14)>, /* LCD_B2 */
+				 <STM32_PINMUX('J', 15, AF14)>, /* LCD_B3 */
+				 <STM32_PINMUX('K',  3, AF14)>, /* LCD_B4 */
+				 <STM32_PINMUX('K',  4, AF14)>, /* LCD_B5 */
+				 <STM32_PINMUX('K',  5, AF14)>, /* LCD_B6 */
+				 <STM32_PINMUX('K',  6, AF14)>; /* LCD_B7 */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <1>;
+		};
+	};
+
+	ltdc_pins_sleep_b: ltdc-b-1 {
+		pins {
+			pinmux = <STM32_PINMUX('I', 14, ANALOG)>, /* LCD_CLK */
+				 <STM32_PINMUX('I', 12, ANALOG)>, /* LCD_HSYNC */
+				 <STM32_PINMUX('I', 13, ANALOG)>, /* LCD_VSYNC */
+				 <STM32_PINMUX('K',  7, ANALOG)>, /* LCD_DE */
+				 <STM32_PINMUX('I', 15, ANALOG)>, /* LCD_R0 */
+				 <STM32_PINMUX('J',  0, ANALOG)>, /* LCD_R1 */
+				 <STM32_PINMUX('J',  1, ANALOG)>, /* LCD_R2 */
+				 <STM32_PINMUX('J',  2, ANALOG)>, /* LCD_R3 */
+				 <STM32_PINMUX('J',  3, ANALOG)>, /* LCD_R4 */
+				 <STM32_PINMUX('J',  4, ANALOG)>, /* LCD_R5 */
+				 <STM32_PINMUX('J',  5, ANALOG)>, /* LCD_R6 */
+				 <STM32_PINMUX('J',  6, ANALOG)>, /* LCD_R7 */
+				 <STM32_PINMUX('J',  7, ANALOG)>, /* LCD_G0 */
+				 <STM32_PINMUX('J',  8, ANALOG)>, /* LCD_G1 */
+				 <STM32_PINMUX('J',  9, ANALOG)>, /* LCD_G2 */
+				 <STM32_PINMUX('J', 10, ANALOG)>, /* LCD_G3 */
+				 <STM32_PINMUX('J', 11, ANALOG)>, /* LCD_G4 */
+				 <STM32_PINMUX('K',  0, ANALOG)>, /* LCD_G5 */
+				 <STM32_PINMUX('K',  1, ANALOG)>, /* LCD_G6 */
+				 <STM32_PINMUX('K',  2, ANALOG)>, /* LCD_G7 */
+				 <STM32_PINMUX('J', 12, ANALOG)>, /* LCD_B0 */
+				 <STM32_PINMUX('J', 13, ANALOG)>, /* LCD_B1 */
+				 <STM32_PINMUX('J', 14, ANALOG)>, /* LCD_B2 */
+				 <STM32_PINMUX('J', 15, ANALOG)>, /* LCD_B3 */
+				 <STM32_PINMUX('K',  3, ANALOG)>, /* LCD_B4 */
+				 <STM32_PINMUX('K',  4, ANALOG)>, /* LCD_B5 */
+				 <STM32_PINMUX('K',  5, ANALOG)>, /* LCD_B6 */
+				 <STM32_PINMUX('K',  6, ANALOG)>; /* LCD_B7 */
+		};
+	};
+
+	m_can1_pins_a: m-can1-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('H', 13, AF9)>; /* CAN1_TX */
+			slew-rate = <1>;
+			drive-push-pull;
+			bias-disable;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('I', 9, AF9)>; /* CAN1_RX */
+			bias-disable;
+		};
+	};
+
+	m_can1_sleep_pins_a: m_can1-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('H', 13, ANALOG)>, /* CAN1_TX */
+				 <STM32_PINMUX('I', 9, ANALOG)>; /* CAN1_RX */
+		};
+	};
+
+	pwm1_pins_a: pwm1-0 {
+		pins {
+			pinmux = <STM32_PINMUX('E', 9, AF1)>, /* TIM1_CH1 */
+				 <STM32_PINMUX('E', 11, AF1)>, /* TIM1_CH2 */
+				 <STM32_PINMUX('E', 14, AF1)>; /* TIM1_CH4 */
+			bias-pull-down;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+	};
+
+	pwm1_sleep_pins_a: pwm1-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('E', 9, ANALOG)>, /* TIM1_CH1 */
+				 <STM32_PINMUX('E', 11, ANALOG)>, /* TIM1_CH2 */
+				 <STM32_PINMUX('E', 14, ANALOG)>; /* TIM1_CH4 */
+		};
+	};
+
+	pwm2_pins_a: pwm2-0 {
+		pins {
+			pinmux = <STM32_PINMUX('A', 3, AF1)>; /* TIM2_CH4 */
+			bias-pull-down;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+	};
+
+	pwm2_sleep_pins_a: pwm2-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('A', 3, ANALOG)>; /* TIM2_CH4 */
+		};
+	};
+
+	pwm3_pins_a: pwm3-0 {
+		pins {
+			pinmux = <STM32_PINMUX('C', 7, AF2)>; /* TIM3_CH2 */
+			bias-pull-down;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+	};
+
+	pwm3_sleep_pins_a: pwm3-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('C', 7, ANALOG)>; /* TIM3_CH2 */
+		};
+	};
+
+	pwm4_pins_a: pwm4-0 {
+		pins {
+			pinmux = <STM32_PINMUX('D', 14, AF2)>, /* TIM4_CH3 */
+				 <STM32_PINMUX('D', 15, AF2)>; /* TIM4_CH4 */
+			bias-pull-down;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+	};
+
+	pwm4_sleep_pins_a: pwm4-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('D', 14, ANALOG)>, /* TIM4_CH3 */
+				 <STM32_PINMUX('D', 15, ANALOG)>; /* TIM4_CH4 */
+		};
+	};
+
+	pwm4_pins_b: pwm4-1 {
+		pins {
+			pinmux = <STM32_PINMUX('D', 13, AF2)>; /* TIM4_CH2 */
+			bias-pull-down;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+	};
+
+	pwm4_sleep_pins_b: pwm4-sleep-1 {
+		pins {
+			pinmux = <STM32_PINMUX('D', 13, ANALOG)>; /* TIM4_CH2 */
+		};
+	};
+
+	pwm5_pins_a: pwm5-0 {
+		pins {
+			pinmux = <STM32_PINMUX('H', 11, AF2)>; /* TIM5_CH2 */
+			bias-pull-down;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+	};
+
+	pwm5_sleep_pins_a: pwm5-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('H', 11, ANALOG)>; /* TIM5_CH2 */
+		};
+	};
+
+	pwm8_pins_a: pwm8-0 {
+		pins {
+			pinmux = <STM32_PINMUX('I', 2, AF3)>; /* TIM8_CH4 */
+			bias-pull-down;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+	};
+
+	pwm8_sleep_pins_a: pwm8-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('I', 2, ANALOG)>; /* TIM8_CH4 */
+		};
+	};
+
+	pwm12_pins_a: pwm12-0 {
+		pins {
+			pinmux = <STM32_PINMUX('H', 6, AF2)>; /* TIM12_CH1 */
+			bias-pull-down;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+	};
+
+	pwm12_sleep_pins_a: pwm12-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('H', 6, ANALOG)>; /* TIM12_CH1 */
+		};
+	};
+
+	qspi_clk_pins_a: qspi-clk-0 {
+		pins {
+			pinmux = <STM32_PINMUX('F', 10, AF9)>; /* QSPI_CLK */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <3>;
+		};
+	};
+
+	qspi_clk_sleep_pins_a: qspi-clk-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('F', 10, ANALOG)>; /* QSPI_CLK */
+		};
+	};
+
+	qspi_bk1_pins_a: qspi-bk1-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('F', 8, AF10)>, /* QSPI_BK1_IO0 */
+				 <STM32_PINMUX('F', 9, AF10)>, /* QSPI_BK1_IO1 */
+				 <STM32_PINMUX('F', 7, AF9)>, /* QSPI_BK1_IO2 */
+				 <STM32_PINMUX('F', 6, AF9)>; /* QSPI_BK1_IO3 */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <1>;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('B', 6, AF10)>; /* QSPI_BK1_NCS */
+			bias-pull-up;
+			drive-push-pull;
+			slew-rate = <1>;
+		};
+	};
+
+	qspi_bk1_sleep_pins_a: qspi-bk1-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('F', 8, ANALOG)>, /* QSPI_BK1_IO0 */
+				 <STM32_PINMUX('F', 9, ANALOG)>, /* QSPI_BK1_IO1 */
+				 <STM32_PINMUX('F', 7, ANALOG)>, /* QSPI_BK1_IO2 */
+				 <STM32_PINMUX('F', 6, ANALOG)>, /* QSPI_BK1_IO3 */
+				 <STM32_PINMUX('B', 6, ANALOG)>; /* QSPI_BK1_NCS */
+		};
+	};
+
+	qspi_bk2_pins_a: qspi-bk2-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('H', 2, AF9)>, /* QSPI_BK2_IO0 */
+				 <STM32_PINMUX('H', 3, AF9)>, /* QSPI_BK2_IO1 */
+				 <STM32_PINMUX('G', 10, AF11)>, /* QSPI_BK2_IO2 */
+				 <STM32_PINMUX('G', 7, AF11)>; /* QSPI_BK2_IO3 */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <1>;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('C', 0, AF10)>; /* QSPI_BK2_NCS */
+			bias-pull-up;
+			drive-push-pull;
+			slew-rate = <1>;
+		};
+	};
+
+	qspi_bk2_sleep_pins_a: qspi-bk2-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('H', 2, ANALOG)>, /* QSPI_BK2_IO0 */
+				 <STM32_PINMUX('H', 3, ANALOG)>, /* QSPI_BK2_IO1 */
+				 <STM32_PINMUX('G', 10, ANALOG)>, /* QSPI_BK2_IO2 */
+				 <STM32_PINMUX('G', 7, ANALOG)>, /* QSPI_BK2_IO3 */
+				 <STM32_PINMUX('C', 0, ANALOG)>; /* QSPI_BK2_NCS */
+		};
+	};
+
+	sai2a_pins_a: sai2a-0 {
+		pins {
+			pinmux = <STM32_PINMUX('I', 5, AF10)>, /* SAI2_SCK_A */
+				 <STM32_PINMUX('I', 6, AF10)>, /* SAI2_SD_A */
+				 <STM32_PINMUX('I', 7, AF10)>, /* SAI2_FS_A */
+				 <STM32_PINMUX('E', 0, AF10)>; /* SAI2_MCLK_A */
+			slew-rate = <0>;
+			drive-push-pull;
+			bias-disable;
+		};
+	};
+
+	sai2a_sleep_pins_a: sai2a-1 {
+		pins {
+			pinmux = <STM32_PINMUX('I', 5, ANALOG)>, /* SAI2_SCK_A */
+				 <STM32_PINMUX('I', 6, ANALOG)>, /* SAI2_SD_A */
+				 <STM32_PINMUX('I', 7, ANALOG)>, /* SAI2_FS_A */
+				 <STM32_PINMUX('E', 0, ANALOG)>; /* SAI2_MCLK_A */
+		};
+	};
+
+	sai2b_pins_a: sai2b-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('E', 12, AF10)>, /* SAI2_SCK_B */
+				 <STM32_PINMUX('E', 13, AF10)>, /* SAI2_FS_B */
+				 <STM32_PINMUX('E', 14, AF10)>; /* SAI2_MCLK_B */
+			slew-rate = <0>;
+			drive-push-pull;
+			bias-disable;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('F', 11, AF10)>; /* SAI2_SD_B */
+			bias-disable;
+		};
+	};
+
+	sai2b_sleep_pins_a: sai2b-1 {
+		pins {
+			pinmux = <STM32_PINMUX('F', 11, ANALOG)>, /* SAI2_SD_B */
+				 <STM32_PINMUX('E', 12, ANALOG)>, /* SAI2_SCK_B */
+				 <STM32_PINMUX('E', 13, ANALOG)>, /* SAI2_FS_B */
+				 <STM32_PINMUX('E', 14, ANALOG)>; /* SAI2_MCLK_B */
+		};
+	};
+
+	sai2b_pins_b: sai2b-2 {
+		pins {
+			pinmux = <STM32_PINMUX('F', 11, AF10)>; /* SAI2_SD_B */
+			bias-disable;
+		};
+	};
+
+	sai2b_sleep_pins_b: sai2b-3 {
+		pins {
+			pinmux = <STM32_PINMUX('F', 11, ANALOG)>; /* SAI2_SD_B */
+		};
+	};
+
+	sai4a_pins_a: sai4a-0 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 5, AF10)>; /* SAI4_SD_A */
+			slew-rate = <0>;
+			drive-push-pull;
+			bias-disable;
+		};
+	};
+
+	sai4a_sleep_pins_a: sai4a-1 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 5, ANALOG)>; /* SAI4_SD_A */
+		};
+	};
+
+	sdmmc1_b4_pins_a: sdmmc1-b4-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
+				 <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
+				 <STM32_PINMUX('C', 10, AF12)>, /* SDMMC1_D2 */
+				 <STM32_PINMUX('C', 11, AF12)>, /* SDMMC1_D3 */
+				 <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */
+			slew-rate = <1>;
+			drive-push-pull;
+			bias-disable;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
+			slew-rate = <2>;
+			drive-push-pull;
+			bias-disable;
+		};
+	};
+
+	sdmmc1_b4_od_pins_a: sdmmc1-b4-od-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
+				 <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
+				 <STM32_PINMUX('C', 10, AF12)>, /* SDMMC1_D2 */
+				 <STM32_PINMUX('C', 11, AF12)>; /* SDMMC1_D3 */
+			slew-rate = <1>;
+			drive-push-pull;
+			bias-disable;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
+			slew-rate = <2>;
+			drive-push-pull;
+			bias-disable;
+		};
+		pins3 {
+			pinmux = <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */
+			slew-rate = <1>;
+			drive-open-drain;
+			bias-disable;
+		};
+	};
+
+	sdmmc1_b4_sleep_pins_a: sdmmc1-b4-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('C', 8, ANALOG)>, /* SDMMC1_D0 */
+				 <STM32_PINMUX('C', 9, ANALOG)>, /* SDMMC1_D1 */
+				 <STM32_PINMUX('C', 10, ANALOG)>, /* SDMMC1_D2 */
+				 <STM32_PINMUX('C', 11, ANALOG)>, /* SDMMC1_D3 */
+				 <STM32_PINMUX('C', 12, ANALOG)>, /* SDMMC1_CK */
+				 <STM32_PINMUX('D', 2, ANALOG)>; /* SDMMC1_CMD */
+		};
+	};
+
+	sdmmc1_dir_pins_a: sdmmc1-dir-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('F', 2, AF11)>, /* SDMMC1_D0DIR */
+				 <STM32_PINMUX('C', 7, AF8)>, /* SDMMC1_D123DIR */
+				 <STM32_PINMUX('B', 9, AF11)>; /* SDMMC1_CDIR */
+			slew-rate = <1>;
+			drive-push-pull;
+			bias-pull-up;
+		};
+		pins2{
+			pinmux = <STM32_PINMUX('E', 4, AF8)>; /* SDMMC1_CKIN */
+			bias-pull-up;
+		};
+	};
+
+	sdmmc1_dir_sleep_pins_a: sdmmc1-dir-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('F', 2, ANALOG)>, /* SDMMC1_D0DIR */
+				 <STM32_PINMUX('C', 7, ANALOG)>, /* SDMMC1_D123DIR */
+				 <STM32_PINMUX('B', 9, ANALOG)>, /* SDMMC1_CDIR */
+				 <STM32_PINMUX('E', 4, ANALOG)>; /* SDMMC1_CKIN */
+		};
+	};
+
+	sdmmc2_b4_pins_a: sdmmc2-b4-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
+				 <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
+				 <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
+				 <STM32_PINMUX('B', 4, AF9)>, /* SDMMC2_D3 */
+				 <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
+			slew-rate = <1>;
+			drive-push-pull;
+			bias-pull-up;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
+			slew-rate = <2>;
+			drive-push-pull;
+			bias-pull-up;
+		};
+	};
+
+	sdmmc2_b4_od_pins_a: sdmmc2-b4-od-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
+				 <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
+				 <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
+				 <STM32_PINMUX('B', 4, AF9)>; /* SDMMC2_D3 */
+			slew-rate = <1>;
+			drive-push-pull;
+			bias-pull-up;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
+			slew-rate = <2>;
+			drive-push-pull;
+			bias-pull-up;
+		};
+		pins3 {
+			pinmux = <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
+			slew-rate = <1>;
+			drive-open-drain;
+			bias-pull-up;
+		};
+	};
+
+	sdmmc2_b4_sleep_pins_a: sdmmc2-b4-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 14, ANALOG)>, /* SDMMC2_D0 */
+				 <STM32_PINMUX('B', 15, ANALOG)>, /* SDMMC2_D1 */
+				 <STM32_PINMUX('B', 3, ANALOG)>, /* SDMMC2_D2 */
+				 <STM32_PINMUX('B', 4, ANALOG)>, /* SDMMC2_D3 */
+				 <STM32_PINMUX('E', 3, ANALOG)>, /* SDMMC2_CK */
+				 <STM32_PINMUX('G', 6, ANALOG)>; /* SDMMC2_CMD */
+		};
+	};
+
+	sdmmc2_b4_pins_b: sdmmc2-b4-1 {
+		pins1 {
+			pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
+				 <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
+				 <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
+				 <STM32_PINMUX('B', 4, AF9)>, /* SDMMC2_D3 */
+				 <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
+			slew-rate = <1>;
+			drive-push-pull;
+			bias-disable;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
+			slew-rate = <2>;
+			drive-push-pull;
+			bias-disable;
+		};
+	};
+
+	sdmmc2_b4_od_pins_b: sdmmc2-b4-od-1 {
+		pins1 {
+			pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
+				 <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
+				 <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
+				 <STM32_PINMUX('B', 4, AF9)>; /* SDMMC2_D3 */
+			slew-rate = <1>;
+			drive-push-pull;
+			bias-disable;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
+			slew-rate = <2>;
+			drive-push-pull;
+			bias-disable;
+		};
+		pins3 {
+			pinmux = <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
+			slew-rate = <1>;
+			drive-open-drain;
+			bias-disable;
+		};
+	};
+
+	sdmmc2_d47_pins_a: sdmmc2-d47-0 {
+		pins {
+			pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
+				 <STM32_PINMUX('A', 9, AF10)>, /* SDMMC2_D5 */
+				 <STM32_PINMUX('E', 5, AF9)>, /* SDMMC2_D6 */
+				 <STM32_PINMUX('D', 3, AF9)>; /* SDMMC2_D7 */
+			slew-rate = <1>;
+			drive-push-pull;
+			bias-pull-up;
+		};
+	};
+
+	sdmmc2_d47_sleep_pins_a: sdmmc2-d47-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('A', 8, ANALOG)>, /* SDMMC2_D4 */
+				 <STM32_PINMUX('A', 9, ANALOG)>, /* SDMMC2_D5 */
+				 <STM32_PINMUX('E', 5, ANALOG)>, /* SDMMC2_D6 */
+				 <STM32_PINMUX('D', 3, ANALOG)>; /* SDMMC2_D7 */
+		};
+	};
+
+	sdmmc3_b4_pins_a: sdmmc3-b4-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('F', 0, AF9)>, /* SDMMC3_D0 */
+				 <STM32_PINMUX('F', 4, AF9)>, /* SDMMC3_D1 */
+				 <STM32_PINMUX('F', 5, AF9)>, /* SDMMC3_D2 */
+				 <STM32_PINMUX('D', 7, AF10)>, /* SDMMC3_D3 */
+				 <STM32_PINMUX('F', 1, AF9)>; /* SDMMC3_CMD */
+			slew-rate = <1>;
+			drive-push-pull;
+			bias-pull-up;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('G', 15, AF10)>; /* SDMMC3_CK */
+			slew-rate = <2>;
+			drive-push-pull;
+			bias-pull-up;
+		};
+	};
+
+	sdmmc3_b4_od_pins_a: sdmmc3-b4-od-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('F', 0, AF9)>, /* SDMMC3_D0 */
+				 <STM32_PINMUX('F', 4, AF9)>, /* SDMMC3_D1 */
+				 <STM32_PINMUX('F', 5, AF9)>, /* SDMMC3_D2 */
+				 <STM32_PINMUX('D', 7, AF10)>; /* SDMMC3_D3 */
+			slew-rate = <1>;
+			drive-push-pull;
+			bias-pull-up;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('G', 15, AF10)>; /* SDMMC3_CK */
+			slew-rate = <2>;
+			drive-push-pull;
+			bias-pull-up;
+		};
+		pins3 {
+			pinmux = <STM32_PINMUX('F', 1, AF9)>; /* SDMMC2_CMD */
+			slew-rate = <1>;
+			drive-open-drain;
+			bias-pull-up;
+		};
+	};
+
+	sdmmc3_b4_sleep_pins_a: sdmmc3-b4-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('F', 0, ANALOG)>, /* SDMMC3_D0 */
+				 <STM32_PINMUX('F', 4, ANALOG)>, /* SDMMC3_D1 */
+				 <STM32_PINMUX('F', 5, ANALOG)>, /* SDMMC3_D2 */
+				 <STM32_PINMUX('D', 7, ANALOG)>, /* SDMMC3_D3 */
+				 <STM32_PINMUX('G', 15, ANALOG)>, /* SDMMC3_CK */
+				 <STM32_PINMUX('F', 1, ANALOG)>; /* SDMMC3_CMD */
+		};
+	};
+
+	spdifrx_pins_a: spdifrx-0 {
+		pins {
+			pinmux = <STM32_PINMUX('G', 12, AF8)>; /* SPDIF_IN1 */
+			bias-disable;
+		};
+	};
+
+	spdifrx_sleep_pins_a: spdifrx-1 {
+		pins {
+			pinmux = <STM32_PINMUX('G', 12, ANALOG)>; /* SPDIF_IN1 */
+		};
+	};
+
+	spi2_pins_a: spi2-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('B', 10, AF5)>, /* SPI2_SCK */
+				 <STM32_PINMUX('I', 0, AF5)>, /* SPI2_NSS */
+				 <STM32_PINMUX('I', 3, AF5)>; /* SPI2_MOSI */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <3>;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('I', 2, AF5)>; /* SPI2_MISO */
+			bias-disable;
+		};
+	};
+
+	stusb1600_pins_a: stusb1600-0 {
+			pins {
+				pinmux = <STM32_PINMUX('I', 11, ANALOG)>;
+				bias-pull-up;
+		};
+	};
+
+	uart4_pins_a: uart4-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
+			bias-disable;
+		};
+	};
+
+	uart4_pins_b: uart4-1 {
+		pins1 {
+			pinmux = <STM32_PINMUX('D', 1, AF8)>; /* UART4_TX */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
+			bias-disable;
+		};
+	};
+
+	uart7_pins_a: uart7-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('E', 8, AF7)>; /* UART4_TX */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('E', 7, AF7)>, /* UART4_RX */
+				 <STM32_PINMUX('E', 10, AF7)>, /* UART4_CTS */
+				 <STM32_PINMUX('E', 9, AF7)>; /* UART4_RTS */
+			bias-disable;
+		};
+	};
+};
+
+&pinctrl_z {
+	i2c2_pins_b2: i2c2-0 {
+		pins {
+			pinmux = <STM32_PINMUX('Z', 0, AF3)>; /* I2C2_SCL */
+			bias-disable;
+			drive-open-drain;
+			slew-rate = <0>;
+		};
+	};
+
+	i2c2_pins_sleep_b2: i2c2-1 {
+		pins {
+			pinmux = <STM32_PINMUX('Z', 0, ANALOG)>; /* I2C2_SCL */
+		};
+	};
+
+	i2c4_pins_a: i2c4-0 {
+		pins {
+			pinmux = <STM32_PINMUX('Z', 4, AF6)>, /* I2C4_SCL */
+				 <STM32_PINMUX('Z', 5, AF6)>; /* I2C4_SDA */
+			bias-disable;
+			drive-open-drain;
+			slew-rate = <0>;
+		};
+	};
+
+	i2c4_pins_sleep_a: i2c4-1 {
+		pins {
+			pinmux = <STM32_PINMUX('Z', 4, ANALOG)>, /* I2C4_SCL */
+				 <STM32_PINMUX('Z', 5, ANALOG)>; /* I2C4_SDA */
+		};
+	};
+
+	spi1_pins_a: spi1-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('Z', 0, AF5)>, /* SPI1_SCK */
+				 <STM32_PINMUX('Z', 2, AF5)>; /* SPI1_MOSI */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <1>;
+		};
+
+		pins2 {
+			pinmux = <STM32_PINMUX('Z', 1, AF5)>; /* SPI1_MISO */
+			bias-disable;
+		};
+	};
+};
diff --git a/arch/arm/dts/stm32mp157-u-boot.dtsi b/arch/arm/dts/stm32mp15-u-boot.dtsi
similarity index 100%
rename from arch/arm/dts/stm32mp157-u-boot.dtsi
rename to arch/arm/dts/stm32mp15-u-boot.dtsi
diff --git a/arch/arm/dts/stm32mp157c.dtsi b/arch/arm/dts/stm32mp151.dtsi
similarity index 88%
rename from arch/arm/dts/stm32mp157c.dtsi
rename to arch/arm/dts/stm32mp151.dtsi
index 22a9386..f185639 100644
--- a/arch/arm/dts/stm32mp157c.dtsi
+++ b/arch/arm/dts/stm32mp151.dtsi
@@ -20,12 +20,6 @@
 			device_type = "cpu";
 			reg = <0>;
 		};
-
-		cpu1: cpu@1 {
-			compatible = "arm,cortex-a7";
-			device_type = "cpu";
-			reg = <1>;
-		};
 	};
 
 	psci {
@@ -155,6 +149,11 @@
 				reg = <1>;
 				status = "disabled";
 			};
+
+			counter {
+				compatible = "st,stm32-timer-counter";
+				status = "disabled";
+			};
 		};
 
 		timers3: timer@40001000 {
@@ -184,6 +183,11 @@
 				reg = <2>;
 				status = "disabled";
 			};
+
+			counter {
+				compatible = "st,stm32-timer-counter";
+				status = "disabled";
+			};
 		};
 
 		timers4: timer@40002000 {
@@ -211,6 +215,11 @@
 				reg = <3>;
 				status = "disabled";
 			};
+
+			counter {
+				compatible = "st,stm32-timer-counter";
+				status = "disabled";
+			};
 		};
 
 		timers5: timer@40003000 {
@@ -240,6 +249,11 @@
 				reg = <4>;
 				status = "disabled";
 			};
+
+			counter {
+				compatible = "st,stm32-timer-counter";
+				status = "disabled";
+			};
 		};
 
 		timers6: timer@40004000 {
@@ -596,6 +610,11 @@
 				reg = <0>;
 				status = "disabled";
 			};
+
+			counter {
+				compatible = "st,stm32-timer-counter";
+				status = "disabled";
+			};
 		};
 
 		timers8: timer@44001000 {
@@ -627,6 +646,11 @@
 				reg = <7>;
 				status = "disabled";
 			};
+
+			counter {
+				compatible = "st,stm32-timer-counter";
+				status = "disabled";
+			};
 		};
 
 		usart6: serial@44003000 {
@@ -930,33 +954,7 @@
 			};
 		};
 
-		m_can1: can@4400e000 {
-			compatible = "bosch,m_can";
-			reg = <0x4400e000 0x400>, <0x44011000 0x1400>;
-			reg-names = "m_can", "message_ram";
-			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "int0", "int1";
-			clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
-			clock-names = "hclk", "cclk";
-			bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>;
-			status = "disabled";
-		};
-
-		m_can2: can@4400f000 {
-			compatible = "bosch,m_can";
-			reg = <0x4400f000 0x400>, <0x44011000 0x2800>;
-			reg-names = "m_can", "message_ram";
-			interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "int0", "int1";
-			clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
-			clock-names = "hclk", "cclk";
-			bosch,mram-cfg = <0x1400 0 0 32 0 0 2 2>;
-			status = "disabled";
-		};
-
-		dma1: dma@48000000 {
+		dma1: dma-controller@48000000 {
 			compatible = "st,stm32-dma";
 			reg = <0x48000000 0x400>;
 			interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
@@ -973,7 +971,7 @@
 			dma-requests = <8>;
 		};
 
-		dma2: dma@48001000 {
+		dma2: dma-controller@48001000 {
 			compatible = "st,stm32-dma";
 			reg = <0x48001000 0x400>;
 			interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
@@ -1041,8 +1039,8 @@
 			compatible = "arm,pl18x", "arm,primecell";
 			arm,primecell-periphid = <0x10153180>;
 			reg = <0x48004000 0x400>;
-			reg-names = "sdmmc";
-			interrupts = <GIC_SPI 137 IRQ_TYPE_NONE>;
+			interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "cmd_irq";
 			clocks = <&rcc SDMMC3_K>;
 			clock-names = "apb_pclk";
 			resets = <&rcc SDMMC3_R>;
@@ -1273,15 +1271,6 @@
 			status = "disabled";
 		};
 
-		cryp1: cryp@54001000 {
-			compatible = "st,stm32mp1-cryp";
-			reg = <0x54001000 0x400>;
-			interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&rcc CRYP1>;
-			resets = <&rcc CRYP1_R>;
-			status = "disabled";
-		};
-
 		hash1: hash@54002000 {
 			compatible = "st,stm32f756-hash";
 			reg = <0x54002000 0x400>;
@@ -1302,7 +1291,7 @@
 			status = "disabled";
 		};
 
-		mdma1: dma@58000000 {
+		mdma1: dma-controller@58000000 {
 			compatible = "st,stm32h7-mdma";
 			reg = <0x58000000 0x1000>;
 			interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
@@ -1349,20 +1338,22 @@
 			arm,primecell-periphid = <0x10153180>;
 			reg = <0x58005000 0x1000>;
 			interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names	= "cmd_irq";
+			interrupt-names = "cmd_irq";
 			clocks = <&rcc SDMMC1_K>;
 			clock-names = "apb_pclk";
 			resets = <&rcc SDMMC1_R>;
 			cap-sd-highspeed;
 			cap-mmc-highspeed;
 			max-frequency = <120000000>;
+			status = "disabled";
 		};
 
 		sdmmc2: sdmmc@58007000 {
 			compatible = "arm,pl18x", "arm,primecell";
 			arm,primecell-periphid = <0x10153180>;
 			reg = <0x58007000 0x1000>;
-			interrupts = <GIC_SPI 124 IRQ_TYPE_NONE>;
+			interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "cmd_irq";
 			clocks = <&rcc SDMMC2_K>;
 			clock-names = "apb_pclk";
 			resets = <&rcc SDMMC2_R>;
@@ -1406,6 +1397,7 @@
 			st,syscon = <&syscfg 0x4>;
 			snps,mixed-burst;
 			snps,pbl = <2>;
+			snps,en-tx-lpi-clockgating;
 			snps,axi-config = <&stmmac_axi_config_0>;
 			snps,tso;
 			status = "disabled";
@@ -1430,26 +1422,6 @@
 			status = "disabled";
 		};
 
-		gpu: gpu@59000000 {
-			compatible = "vivante,gc";
-			reg = <0x59000000 0x800>;
-			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&rcc GPU>, <&rcc GPU_K>;
-			clock-names = "bus" ,"core";
-			resets = <&rcc GPU_R>;
-			status = "disabled";
-		};
-
-		dsi: dsi@5a000000 {
-			compatible = "st,stm32-dsi";
-			reg = <0x5a000000 0x800>;
-			clocks = <&rcc DSI_K>, <&clk_hse>, <&rcc DSI_PX>;
-			clock-names = "pclk", "ref", "px_clk";
-			resets = <&rcc DSI_R>;
-			reset-names = "apb";
-			status = "disabled";
-		};
-
 		ltdc: display-controller@5a001000 {
 			compatible = "st,stm32-ltdc";
 			reg = <0x5a001000 0x400>;
@@ -1535,7 +1507,7 @@
 			status = "disabled";
 		};
 
-		bsec: nvmem@5c005000 {
+		bsec: efuse@5c005000 {
 			compatible = "st,stm32mp15-bsec";
 			reg = <0x5c005000 0x400>;
 			#address-cells = <1>;
@@ -1560,12 +1532,172 @@
 			#size-cells = <0>;
 			status = "disabled";
 		};
+
+		/*
+		 * Break node order to solve dependency probe issue between
+		 * pinctrl and exti.
+		 */
+		pinctrl: pin-controller@50002000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "st,stm32mp157-pinctrl";
+			ranges = <0 0x50002000 0xa400>;
+			interrupt-parent = <&exti>;
+			st,syscfg = <&exti 0x60 0xff>;
+			hwlocks = <&hwspinlock 0>;
+			pins-are-numbered;
+
+			gpioa: gpio@50002000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x0 0x400>;
+				clocks = <&rcc GPIOA>;
+				st,bank-name = "GPIOA";
+				status = "disabled";
+			};
+
+			gpiob: gpio@50003000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x1000 0x400>;
+				clocks = <&rcc GPIOB>;
+				st,bank-name = "GPIOB";
+				status = "disabled";
+			};
+
+			gpioc: gpio@50004000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x2000 0x400>;
+				clocks = <&rcc GPIOC>;
+				st,bank-name = "GPIOC";
+				status = "disabled";
+			};
+
+			gpiod: gpio@50005000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x3000 0x400>;
+				clocks = <&rcc GPIOD>;
+				st,bank-name = "GPIOD";
+				status = "disabled";
+			};
+
+			gpioe: gpio@50006000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x4000 0x400>;
+				clocks = <&rcc GPIOE>;
+				st,bank-name = "GPIOE";
+				status = "disabled";
+			};
+
+			gpiof: gpio@50007000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x5000 0x400>;
+				clocks = <&rcc GPIOF>;
+				st,bank-name = "GPIOF";
+				status = "disabled";
+			};
+
+			gpiog: gpio@50008000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x6000 0x400>;
+				clocks = <&rcc GPIOG>;
+				st,bank-name = "GPIOG";
+				status = "disabled";
+			};
+
+			gpioh: gpio@50009000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x7000 0x400>;
+				clocks = <&rcc GPIOH>;
+				st,bank-name = "GPIOH";
+				status = "disabled";
+			};
+
+			gpioi: gpio@5000a000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x8000 0x400>;
+				clocks = <&rcc GPIOI>;
+				st,bank-name = "GPIOI";
+				status = "disabled";
+			};
+
+			gpioj: gpio@5000b000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x9000 0x400>;
+				clocks = <&rcc GPIOJ>;
+				st,bank-name = "GPIOJ";
+				status = "disabled";
+			};
+
+			gpiok: gpio@5000c000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0xa000 0x400>;
+				clocks = <&rcc GPIOK>;
+				st,bank-name = "GPIOK";
+				status = "disabled";
+			};
+		};
+
+		pinctrl_z: pin-controller-z@54004000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "st,stm32mp157-z-pinctrl";
+			ranges = <0 0x54004000 0x400>;
+			pins-are-numbered;
+			interrupt-parent = <&exti>;
+			st,syscfg = <&exti 0x60 0xff>;
+			hwlocks = <&hwspinlock 0>;
+
+			gpioz: gpio@54004000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0 0x400>;
+				clocks = <&rcc GPIOZ>;
+				st,bank-name = "GPIOZ";
+				st,bank-ioport = <11>;
+				status = "disabled";
+			};
+		};
 	};
 
-	mlahb {
-		compatible = "simple-bus";
+	mlahb: ahb {
+		compatible = "st,mlahb", "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
+		ranges;
 		dma-ranges = <0x00000000 0x38000000 0x10000>,
 			     <0x10000000 0x10000000 0x60000>,
 			     <0x30000000 0x30000000 0x60000>;
diff --git a/arch/arm/dts/stm32mp153.dtsi b/arch/arm/dts/stm32mp153.dtsi
new file mode 100644
index 0000000..2d759fc
--- /dev/null
+++ b/arch/arm/dts/stm32mp153.dtsi
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+#include "stm32mp151.dtsi"
+
+/ {
+	cpus {
+		cpu1: cpu@1 {
+			compatible = "arm,cortex-a7";
+			device_type = "cpu";
+			reg = <1>;
+		};
+	};
+
+	soc {
+		m_can1: can@4400e000 {
+			compatible = "bosch,m_can";
+			reg = <0x4400e000 0x400>, <0x44011000 0x1400>;
+			reg-names = "m_can", "message_ram";
+			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "int0", "int1";
+			clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
+			clock-names = "hclk", "cclk";
+			bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>;
+			status = "disabled";
+		};
+
+		m_can2: can@4400f000 {
+			compatible = "bosch,m_can";
+			reg = <0x4400f000 0x400>, <0x44011000 0x2800>;
+			reg-names = "m_can", "message_ram";
+			interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "int0", "int1";
+			clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
+			clock-names = "hclk", "cclk";
+			bosch,mram-cfg = <0x1400 0 0 32 0 0 2 2>;
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm/dts/stm32mp157.dtsi b/arch/arm/dts/stm32mp157.dtsi
new file mode 100644
index 0000000..3f0a4a9
--- /dev/null
+++ b/arch/arm/dts/stm32mp157.dtsi
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+#include "stm32mp153.dtsi"
+
+/ {
+	soc {
+		gpu: gpu@59000000 {
+			compatible = "vivante,gc";
+			reg = <0x59000000 0x800>;
+			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&rcc GPU>, <&rcc GPU_K>;
+			clock-names = "bus" ,"core";
+			resets = <&rcc GPU_R>;
+			status = "disabled";
+		};
+
+		dsi: dsi@5a000000 {
+			compatible = "st,stm32-dsi";
+			reg = <0x5a000000 0x800>;
+			clocks = <&rcc DSI_K>, <&clk_hse>, <&rcc DSI_PX>;
+			clock-names = "pclk", "ref", "px_clk";
+			resets = <&rcc DSI_R>;
+			reset-names = "apb";
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm/dts/stm32mp157a-avenger96-u-boot.dtsi b/arch/arm/dts/stm32mp157a-avenger96-u-boot.dtsi
index 2c7dc50..f2ff7a2 100644
--- a/arch/arm/dts/stm32mp157a-avenger96-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp157a-avenger96-u-boot.dtsi
@@ -7,7 +7,7 @@
  */
 
 #include <dt-bindings/clock/stm32mp1-clksrc.h>
-#include "stm32mp157-u-boot.dtsi"
+#include "stm32mp15-u-boot.dtsi"
 #include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi"
 
 / {
@@ -145,7 +145,10 @@
 
 &sdmmc1_b4_pins_a {
 	u-boot,dm-spl;
-	pins {
+	pins1 {
+		u-boot,dm-spl;
+	};
+	pins2 {
 		u-boot,dm-spl;
 	};
 };
@@ -199,7 +202,3 @@
 	u-boot,force-b-session-valid;
 	hnp-srp-disable;
 };
-
-&v3v3 {
-	regulator-always-on;
-};
diff --git a/arch/arm/dts/stm32mp157a-avenger96.dts b/arch/arm/dts/stm32mp157a-avenger96.dts
index 1f32395..80ee9c0 100644
--- a/arch/arm/dts/stm32mp157a-avenger96.dts
+++ b/arch/arm/dts/stm32mp157a-avenger96.dts
@@ -6,8 +6,10 @@
 
 /dts-v1/;
 
-#include "stm32mp157c.dtsi"
-#include "stm32mp157xac-pinctrl.dtsi"
+#include "stm32mp157.dtsi"
+#include "stm32mp15-pinctrl.dtsi"
+#include "stm32mp157-pinctrl.dtsi"
+#include "stm32mp15xxac-pinctrl.dtsi"
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/mfd/st,stpmic1.h>
 
diff --git a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi
index a5cc01d..5844d41 100644
--- a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi
@@ -4,7 +4,7 @@
  */
 
 #include <dt-bindings/clock/stm32mp1-clksrc.h>
-#include "stm32mp157-u-boot.dtsi"
+#include "stm32mp15-u-boot.dtsi"
 #include "stm32mp15-ddr3-1x4Gb-1066-binG.dtsi"
 
 / {
@@ -164,7 +164,10 @@
 
 &sdmmc1_b4_pins_a {
 	u-boot,dm-spl;
-	pins {
+	pins1 {
+		u-boot,dm-spl;
+	};
+	pins2 {
 		u-boot,dm-spl;
 	};
 };
diff --git a/arch/arm/dts/stm32mp157a-dk1.dts b/arch/arm/dts/stm32mp157a-dk1.dts
index 624bf69..d03d4cd 100644
--- a/arch/arm/dts/stm32mp157a-dk1.dts
+++ b/arch/arm/dts/stm32mp157a-dk1.dts
@@ -6,10 +6,10 @@
 
 /dts-v1/;
 
-#include "stm32mp157c.dtsi"
-#include "stm32mp157xac-pinctrl.dtsi"
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/mfd/st,stpmic1.h>
+#include "stm32mp157.dtsi"
+#include "stm32mp15-pinctrl.dtsi"
+#include "stm32mp15xxac-pinctrl.dtsi"
+#include "stm32mp15xx-dkx.dtsi"
 
 / {
 	model = "STMicroelectronics STM32MP157A-DK1 Discovery Board";
@@ -23,537 +23,4 @@
 	chosen {
 		stdout-path = "serial0:115200n8";
 	};
-
-	memory@c0000000 {
-		device_type = "memory";
-		reg = <0xc0000000 0x20000000>;
-	};
-
-	reserved-memory {
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges;
-
-		mcuram2: mcuram2@10000000 {
-			compatible = "shared-dma-pool";
-			reg = <0x10000000 0x40000>;
-			no-map;
-		};
-
-		vdev0vring0: vdev0vring0@10040000 {
-			compatible = "shared-dma-pool";
-			reg = <0x10040000 0x1000>;
-			no-map;
-		};
-
-		vdev0vring1: vdev0vring1@10041000 {
-			compatible = "shared-dma-pool";
-			reg = <0x10041000 0x1000>;
-			no-map;
-		};
-
-		vdev0buffer: vdev0buffer@10042000 {
-			compatible = "shared-dma-pool";
-			reg = <0x10042000 0x4000>;
-			no-map;
-		};
-
-		mcuram: mcuram@30000000 {
-			compatible = "shared-dma-pool";
-			reg = <0x30000000 0x40000>;
-			no-map;
-		};
-
-		retram: retram@38000000 {
-			compatible = "shared-dma-pool";
-			reg = <0x38000000 0x10000>;
-			no-map;
-		};
-
-		gpu_reserved: gpu@d4000000 {
-			reg = <0xd4000000 0x4000000>;
-			no-map;
-		};
-	};
-
-	led {
-		compatible = "gpio-leds";
-		blue {
-			label = "heartbeat";
-			gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>;
-			linux,default-trigger = "heartbeat";
-			default-state = "off";
-		};
-	};
-
-	sound {
-		compatible = "audio-graph-card";
-		label = "STM32MP1-DK";
-		routing =
-			"Playback" , "MCLK",
-			"Capture" , "MCLK",
-			"MICL" , "Mic Bias";
-		dais = <&sai2a_port &sai2b_port &i2s2_port>;
-		status = "okay";
-	};
-};
-
-&adc {
-	pinctrl-names = "default";
-	pinctrl-0 = <&adc12_ain_pins_a>, <&adc12_usb_cc_pins_a>;
-	vdd-supply = <&vdd>;
-	vdda-supply = <&vdd>;
-	vref-supply = <&vrefbuf>;
-	status = "disabled";
-	adc1: adc@0 {
-		/*
-		 * Type-C USB_PWR_CC1 & USB_PWR_CC2 on in18 & in19.
-		 * Use at least 5 * RC time, e.g. 5 * (Rp + Rd) * C:
-		 * 5 * (56 + 47kOhms) * 5pF => 2.5us.
-		 * Use arbitrary margin here (e.g. 5us).
-		 */
-		st,min-sample-time-nsecs = <5000>;
-		/* AIN connector, USB Type-C CC1 & CC2 */
-		st,adc-channels = <0 1 6 13 18 19>;
-		status = "okay";
-	};
-	adc2: adc@100 {
-		/* AIN connector, USB Type-C CC1 & CC2 */
-		st,adc-channels = <0 1 2 6 18 19>;
-		st,min-sample-time-nsecs = <5000>;
-		status = "okay";
-	};
-};
-
-&cec {
-	pinctrl-names = "default", "sleep";
-	pinctrl-0 = <&cec_pins_b>;
-	pinctrl-1 = <&cec_pins_sleep_b>;
-	status = "okay";
-};
-
-&ethernet0 {
-	status = "okay";
-	pinctrl-0 = <&ethernet0_rgmii_pins_a>;
-	pinctrl-1 = <&ethernet0_rgmii_pins_sleep_a>;
-	pinctrl-names = "default", "sleep";
-	phy-mode = "rgmii-id";
-	max-speed = <1000>;
-	phy-handle = <&phy0>;
-
-	mdio0 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "snps,dwmac-mdio";
-		phy0: ethernet-phy@0 {
-			reg = <0>;
-		};
-	};
-};
-
-&gpu {
-	contiguous-area = <&gpu_reserved>;
-	status = "okay";
-};
-
-&i2c1 {
-	pinctrl-names = "default", "sleep";
-	pinctrl-0 = <&i2c1_pins_a>;
-	pinctrl-1 = <&i2c1_pins_sleep_a>;
-	i2c-scl-rising-time-ns = <100>;
-	i2c-scl-falling-time-ns = <7>;
-	status = "okay";
-	/delete-property/dmas;
-	/delete-property/dma-names;
-
-	hdmi-transmitter@39 {
-		compatible = "sil,sii9022";
-		reg = <0x39>;
-		iovcc-supply = <&v3v3_hdmi>;
-		cvcc12-supply = <&v1v2_hdmi>;
-		reset-gpios = <&gpioa 10 GPIO_ACTIVE_LOW>;
-		interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
-		interrupt-parent = <&gpiog>;
-		#sound-dai-cells = <0>;
-		status = "okay";
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port@0 {
-				reg = <0>;
-				sii9022_in: endpoint {
-					remote-endpoint = <&ltdc_ep0_out>;
-				};
-			};
-
-			port@3 {
-				reg = <3>;
-				sii9022_tx_endpoint: endpoint {
-					remote-endpoint = <&i2s2_endpoint>;
-				};
-			};
-		};
-	};
-
-	cs42l51: cs42l51@4a {
-		compatible = "cirrus,cs42l51";
-		reg = <0x4a>;
-		#sound-dai-cells = <0>;
-		VL-supply = <&v3v3>;
-		VD-supply = <&v1v8_audio>;
-		VA-supply = <&v1v8_audio>;
-		VAHP-supply = <&v1v8_audio>;
-		reset-gpios = <&gpiog 9 GPIO_ACTIVE_LOW>;
-		clocks = <&sai2a>;
-		clock-names = "MCLK";
-		status = "okay";
-
-		cs42l51_port: port {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			cs42l51_tx_endpoint: endpoint@0 {
-				reg = <0>;
-				remote-endpoint = <&sai2a_endpoint>;
-				frame-master;
-				bitclock-master;
-			};
-
-			cs42l51_rx_endpoint: endpoint@1 {
-				reg = <1>;
-				remote-endpoint = <&sai2b_endpoint>;
-				frame-master;
-				bitclock-master;
-			};
-		};
-	};
-};
-
-&i2c4 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&i2c4_pins_a>;
-	i2c-scl-rising-time-ns = <185>;
-	i2c-scl-falling-time-ns = <20>;
-	status = "okay";
-	/* spare dmas for other usage */
-	/delete-property/dmas;
-	/delete-property/dma-names;
-
-	typec: stusb1600@28 {
-		compatible = "st,stusb1600";
-		reg = <0x28>;
-		interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
-		interrupt-parent = <&gpioi>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&stusb1600_pins_a>;
-
-		status = "okay";
-
-		typec_con: connector {
-			compatible = "usb-c-connector";
-			label = "USB-C";
-			power-role = "sink";
-			power-opmode = "default";
-		};
-	};
-
-	pmic: stpmic@33 {
-		compatible = "st,stpmic1";
-		reg = <0x33>;
-		interrupts-extended = <&gpioa 0 IRQ_TYPE_EDGE_FALLING>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
-		status = "okay";
-
-		regulators {
-			compatible = "st,stpmic1-regulators";
-			ldo1-supply = <&v3v3>;
-			ldo3-supply = <&vdd_ddr>;
-			ldo6-supply = <&v3v3>;
-			pwr_sw1-supply = <&bst_out>;
-			pwr_sw2-supply = <&bst_out>;
-
-			vddcore: buck1 {
-				regulator-name = "vddcore";
-				regulator-min-microvolt = <1200000>;
-				regulator-max-microvolt = <1350000>;
-				regulator-always-on;
-				regulator-initial-mode = <0>;
-				regulator-over-current-protection;
-			};
-
-			vdd_ddr: buck2 {
-				regulator-name = "vdd_ddr";
-				regulator-min-microvolt = <1350000>;
-				regulator-max-microvolt = <1350000>;
-				regulator-always-on;
-				regulator-initial-mode = <0>;
-				regulator-over-current-protection;
-			};
-
-			vdd: buck3 {
-				regulator-name = "vdd";
-				regulator-min-microvolt = <3300000>;
-				regulator-max-microvolt = <3300000>;
-				regulator-always-on;
-				st,mask-reset;
-				regulator-initial-mode = <0>;
-				regulator-over-current-protection;
-			};
-
-			v3v3: buck4 {
-				regulator-name = "v3v3";
-				regulator-min-microvolt = <3300000>;
-				regulator-max-microvolt = <3300000>;
-				regulator-always-on;
-				regulator-over-current-protection;
-				regulator-initial-mode = <0>;
-			};
-
-			v1v8_audio: ldo1 {
-				regulator-name = "v1v8_audio";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-				regulator-always-on;
-				interrupts = <IT_CURLIM_LDO1 0>;
-			};
-
-			v3v3_hdmi: ldo2 {
-				regulator-name = "v3v3_hdmi";
-				regulator-min-microvolt = <3300000>;
-				regulator-max-microvolt = <3300000>;
-				regulator-always-on;
-				interrupts = <IT_CURLIM_LDO2 0>;
-			};
-
-			vtt_ddr: ldo3 {
-				regulator-name = "vtt_ddr";
-				regulator-min-microvolt = <500000>;
-				regulator-max-microvolt = <750000>;
-				regulator-always-on;
-				regulator-over-current-protection;
-			};
-
-			vdd_usb: ldo4 {
-				regulator-name = "vdd_usb";
-				regulator-min-microvolt = <3300000>;
-				regulator-max-microvolt = <3300000>;
-				interrupts = <IT_CURLIM_LDO4 0>;
-			};
-
-			vdda: ldo5 {
-				regulator-name = "vdda";
-				regulator-min-microvolt = <2900000>;
-				regulator-max-microvolt = <2900000>;
-				interrupts = <IT_CURLIM_LDO5 0>;
-				regulator-boot-on;
-			};
-
-			v1v2_hdmi: ldo6 {
-				regulator-name = "v1v2_hdmi";
-				regulator-min-microvolt = <1200000>;
-				regulator-max-microvolt = <1200000>;
-				regulator-always-on;
-				interrupts = <IT_CURLIM_LDO6 0>;
-			};
-
-			vref_ddr: vref_ddr {
-				regulator-name = "vref_ddr";
-				regulator-always-on;
-				regulator-over-current-protection;
-			};
-
-			 bst_out: boost {
-				regulator-name = "bst_out";
-				interrupts = <IT_OCP_BOOST 0>;
-			 };
-
-			vbus_otg: pwr_sw1 {
-				regulator-name = "vbus_otg";
-				interrupts = <IT_OCP_OTG 0>;
-			 };
-
-			 vbus_sw: pwr_sw2 {
-				regulator-name = "vbus_sw";
-				interrupts = <IT_OCP_SWOUT 0>;
-				regulator-active-discharge = <1>;
-			 };
-		};
-
-		onkey {
-			compatible = "st,stpmic1-onkey";
-			interrupts = <IT_PONKEY_F 0>, <IT_PONKEY_R 0>;
-			interrupt-names = "onkey-falling", "onkey-rising";
-			power-off-time-sec = <10>;
-			status = "okay";
-		};
-
-		watchdog {
-			compatible = "st,stpmic1-wdt";
-			status = "disabled";
-		};
-	};
-};
-
-&i2s2 {
-	clocks = <&rcc SPI2>, <&rcc SPI2_K>, <&rcc PLL3_Q>, <&rcc PLL3_R>;
-	clock-names = "pclk", "i2sclk", "x8k", "x11k";
-	pinctrl-names = "default", "sleep";
-	pinctrl-0 = <&i2s2_pins_a>;
-	pinctrl-1 = <&i2s2_pins_sleep_a>;
-	status = "okay";
-
-	i2s2_port: port {
-		i2s2_endpoint: endpoint {
-			remote-endpoint = <&sii9022_tx_endpoint>;
-			format = "i2s";
-			mclk-fs = <256>;
-		};
-	};
-};
-
-&ipcc {
-	status = "okay";
-};
-
-&iwdg2 {
-	timeout-sec = <32>;
-	status = "okay";
-};
-
-&ltdc {
-	pinctrl-names = "default", "sleep";
-	pinctrl-0 = <&ltdc_pins_a>;
-	pinctrl-1 = <&ltdc_pins_sleep_a>;
-	status = "okay";
-
-	port {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		ltdc_ep0_out: endpoint@0 {
-			reg = <0>;
-			remote-endpoint = <&sii9022_in>;
-		};
-	};
-};
-
-&m4_rproc {
-	memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>,
-			<&vdev0vring1>, <&vdev0buffer>;
-	mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>;
-	mbox-names = "vq0", "vq1", "shutdown";
-	interrupt-parent = <&exti>;
-	interrupts = <68 1>;
-	status = "okay";
-};
-
-&pwr_regulators {
-	vdd-supply = <&vdd>;
-	vdd_3v3_usbfs-supply = <&vdd_usb>;
-};
-
-&rng1 {
-	status = "okay";
-};
-
-&rtc {
-	status = "okay";
-};
-
-&sai2 {
-	clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>;
-	clock-names = "pclk", "x8k", "x11k";
-	pinctrl-names = "default", "sleep";
-	pinctrl-0 = <&sai2a_pins_a>, <&sai2b_pins_b>;
-	pinctrl-1 = <&sai2a_sleep_pins_a>, <&sai2b_sleep_pins_b>;
-	status = "okay";
-
-	sai2a: audio-controller@4400b004 {
-		#clock-cells = <0>;
-		dma-names = "tx";
-		clocks = <&rcc SAI2_K>;
-		clock-names = "sai_ck";
-		status = "okay";
-
-		sai2a_port: port {
-			sai2a_endpoint: endpoint {
-				remote-endpoint = <&cs42l51_tx_endpoint>;
-				format = "i2s";
-				mclk-fs = <256>;
-				dai-tdm-slot-num = <2>;
-				dai-tdm-slot-width = <32>;
-			};
-		};
-	};
-
-	sai2b: audio-controller@4400b024 {
-		dma-names = "rx";
-		st,sync = <&sai2a 2>;
-		clocks = <&rcc SAI2_K>, <&sai2a>;
-		clock-names = "sai_ck", "MCLK";
-		status = "okay";
-
-		sai2b_port: port {
-			sai2b_endpoint: endpoint {
-				remote-endpoint = <&cs42l51_rx_endpoint>;
-				format = "i2s";
-				mclk-fs = <256>;
-				dai-tdm-slot-num = <2>;
-				dai-tdm-slot-width = <32>;
-			};
-		};
-	};
-};
-
-&sdmmc1 {
-	pinctrl-names = "default", "opendrain", "sleep";
-	pinctrl-0 = <&sdmmc1_b4_pins_a>;
-	pinctrl-1 = <&sdmmc1_b4_od_pins_a>;
-	pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>;
-	broken-cd;
-	st,neg-edge;
-	bus-width = <4>;
-	vmmc-supply = <&v3v3>;
-	status = "okay";
-};
-
-&uart4 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&uart4_pins_a>;
-	status = "okay";
-};
-
-&usbh_ehci {
-	phys = <&usbphyc_port0>;
-	phy-names = "usb";
-	status = "okay";
-};
-
-&usbotg_hs {
-	dr_mode = "peripheral";
-	phys = <&usbphyc_port1 0>;
-	phy-names = "usb2-phy";
-	status = "okay";
-};
-
-&usbphyc {
-	status = "okay";
-};
-
-&usbphyc_port0 {
-	phy-supply = <&vdd_usb>;
-};
-
-&usbphyc_port1 {
-	phy-supply = <&vdd_usb>;
-};
-
-&vrefbuf {
-	regulator-min-microvolt = <2500000>;
-	regulator-max-microvolt = <2500000>;
-	vdda-supply = <&vdd>;
-	status = "okay";
 };
diff --git a/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi b/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi
index 18ac1e3..06ef3a4 100644
--- a/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi
@@ -4,9 +4,3 @@
  */
 
 #include "stm32mp157a-dk1-u-boot.dtsi"
-
-&i2c1 {
-	hdmi-transmitter@39 {
-		reset-gpios = <&gpioa 10 GPIO_ACTIVE_LOW>;
-	};
-};
diff --git a/arch/arm/dts/stm32mp157c-dk2.dts b/arch/arm/dts/stm32mp157c-dk2.dts
index d26adcb..7985b80 100644
--- a/arch/arm/dts/stm32mp157c-dk2.dts
+++ b/arch/arm/dts/stm32mp157c-dk2.dts
@@ -6,11 +6,24 @@
 
 /dts-v1/;
 
-#include "stm32mp157a-dk1.dts"
+#include "stm32mp157.dtsi"
+#include "stm32mp15xc.dtsi"
+#include "stm32mp15-pinctrl.dtsi"
+#include "stm32mp15xxac-pinctrl.dtsi"
+#include "stm32mp15xx-dkx.dtsi"
 
 / {
 	model = "STMicroelectronics STM32MP157C-DK2 Discovery Board";
 	compatible = "st,stm32mp157c-dk2", "st,stm32mp157";
+
+	aliases {
+		ethernet0 = &ethernet0;
+		serial0 = &uart4;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
 };
 
 &dsi {
diff --git a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi
index 347edf7..ed2f024 100644
--- a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi
@@ -4,7 +4,7 @@
  */
 
 #include <dt-bindings/clock/stm32mp1-clksrc.h>
-#include "stm32mp157-u-boot.dtsi"
+#include "stm32mp15-u-boot.dtsi"
 #include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi"
 
 / {
@@ -161,7 +161,10 @@
 
 &sdmmc1_b4_pins_a {
 	u-boot,dm-spl;
-	pins {
+	pins1 {
+		u-boot,dm-spl;
+	};
+	pins2 {
 		u-boot,dm-spl;
 	};
 };
diff --git a/arch/arm/dts/stm32mp157c-ed1.dts b/arch/arm/dts/stm32mp157c-ed1.dts
index ae4da39..54af7c9 100644
--- a/arch/arm/dts/stm32mp157c-ed1.dts
+++ b/arch/arm/dts/stm32mp157c-ed1.dts
@@ -5,8 +5,10 @@
  */
 /dts-v1/;
 
-#include "stm32mp157c.dtsi"
-#include "stm32mp157xaa-pinctrl.dtsi"
+#include "stm32mp157.dtsi"
+#include "stm32mp15xc.dtsi"
+#include "stm32mp15-pinctrl.dtsi"
+#include "stm32mp15xxaa-pinctrl.dtsi"
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/mfd/st,stpmic1.h>
 
@@ -89,6 +91,22 @@
 	};
 };
 
+&adc {
+	/* ANA0, ANA1 are dedicated pins and don't need pinctrl: only in6. */
+	pinctrl-0 = <&adc1_in6_pins_a>;
+	pinctrl-names = "default";
+	vdd-supply = <&vdd>;
+	vdda-supply = <&vdda>;
+	vref-supply = <&vdda>;
+	status = "disabled";
+	adc1: adc@0 {
+		st,adc-channels = <0 1 6>;
+		/* 16.5 ck_cycles sampling time */
+		st,min-sample-time-nsecs = <400>;
+		status = "okay";
+	};
+};
+
 &dac {
 	pinctrl-names = "default";
 	pinctrl-0 = <&dac_ch1_pins_a &dac_ch2_pins_a>;
diff --git a/arch/arm/dts/stm32mp157c-ev1.dts b/arch/arm/dts/stm32mp157c-ev1.dts
index bd8ffc1..228e35e 100644
--- a/arch/arm/dts/stm32mp157c-ev1.dts
+++ b/arch/arm/dts/stm32mp157c-ev1.dts
@@ -182,8 +182,6 @@
 
 	ov5640: camera@3c {
 		compatible = "ovti,ov5640";
-		pinctrl-names = "default";
-		pinctrl-0 = <&ov5640_pins>;
 		reg = <0x3c>;
 		clocks = <&clk_ext_camera>;
 		clock-names = "xclk";
@@ -224,12 +222,6 @@
 				pins = "gpio0", "gpio1", "gpio2", "gpio3", "gpio4";
 				bias-pull-down;
 			};
-
-			ov5640_pins: camera {
-				pins = "agpio2", "agpio3"; /* stmfx pins 18 & 19 */
-				drive-push-pull;
-				output-low;
-			};
 		};
 	};
 };
@@ -291,6 +283,18 @@
 	};
 };
 
+&sdmmc3 {
+	pinctrl-names = "default", "opendrain", "sleep";
+	pinctrl-0 = <&sdmmc3_b4_pins_a>;
+	pinctrl-1 = <&sdmmc3_b4_od_pins_a>;
+	pinctrl-2 = <&sdmmc3_b4_sleep_pins_a>;
+	broken-cd;
+	st,neg-edge;
+	bus-width = <4>;
+	vmmc-supply = <&v3v3>;
+	status = "disabled";
+};
+
 &spi1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&spi1_pins_a>;
@@ -304,7 +308,8 @@
 	status = "disabled";
 	pwm {
 		pinctrl-0 = <&pwm2_pins_a>;
-		pinctrl-names = "default";
+		pinctrl-1 = <&pwm2_sleep_pins_a>;
+		pinctrl-names = "default", "sleep";
 		status = "okay";
 	};
 	timer@1 {
@@ -318,7 +323,8 @@
 	status = "disabled";
 	pwm {
 		pinctrl-0 = <&pwm8_pins_a>;
-		pinctrl-names = "default";
+		pinctrl-1 = <&pwm8_sleep_pins_a>;
+		pinctrl-names = "default", "sleep";
 		status = "okay";
 	};
 	timer@7 {
@@ -332,7 +338,8 @@
 	status = "disabled";
 	pwm {
 		pinctrl-0 = <&pwm12_pins_a>;
-		pinctrl-names = "default";
+		pinctrl-1 = <&pwm12_sleep_pins_a>;
+		pinctrl-names = "default", "sleep";
 		status = "okay";
 	};
 	timer@11 {
@@ -348,6 +355,7 @@
 &usbotg_hs {
 	dr_mode = "peripheral";
 	phys = <&usbphyc_port1 0>;
+	phy-names = "usb2-phy";
 	status = "okay";
 };
 
diff --git a/arch/arm/dts/stm32mp157xaa-pinctrl.dtsi b/arch/arm/dts/stm32mp157xaa-pinctrl.dtsi
deleted file mode 100644
index 875adf5e..0000000
--- a/arch/arm/dts/stm32mp157xaa-pinctrl.dtsi
+++ /dev/null
@@ -1,90 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
-/*
- * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
- * Author: Alexandre Torgue <alexandre.torgue@st.com>
- */
-
-#include "stm32mp157-pinctrl.dtsi"
-/ {
-	soc {
-		pinctrl: pin-controller@50002000 {
-			st,package = <STM32MP_PKG_AA>;
-
-			gpioa: gpio@50002000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 0 16>;
-			};
-
-			gpiob: gpio@50003000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 16 16>;
-			};
-
-			gpioc: gpio@50004000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 32 16>;
-			};
-
-			gpiod: gpio@50005000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 48 16>;
-			};
-
-			gpioe: gpio@50006000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 64 16>;
-			};
-
-			gpiof: gpio@50007000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 80 16>;
-			};
-
-			gpiog: gpio@50008000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 96 16>;
-			};
-
-			gpioh: gpio@50009000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 112 16>;
-			};
-
-			gpioi: gpio@5000a000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 128 16>;
-			};
-
-			gpioj: gpio@5000b000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 144 16>;
-			};
-
-			gpiok: gpio@5000c000 {
-				status = "okay";
-				ngpios = <8>;
-				gpio-ranges = <&pinctrl 0 160 8>;
-			};
-		};
-
-		pinctrl_z: pin-controller-z@54004000 {
-			st,package = <STM32MP_PKG_AA>;
-
-			gpioz: gpio@54004000 {
-				status = "okay";
-				ngpios = <8>;
-				gpio-ranges = <&pinctrl_z 0 400 8>;
-			};
-		};
-	};
-};
diff --git a/arch/arm/dts/stm32mp157xab-pinctrl.dtsi b/arch/arm/dts/stm32mp157xab-pinctrl.dtsi
deleted file mode 100644
index 961fa12..0000000
--- a/arch/arm/dts/stm32mp157xab-pinctrl.dtsi
+++ /dev/null
@@ -1,62 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
-/*
- * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
- * Author: Alexandre Torgue <alexandre.torgue@st.com>
- */
-
-#include "stm32mp157-pinctrl.dtsi"
-/ {
-	soc {
-		pinctrl: pin-controller@50002000 {
-			st,package = <STM32MP_PKG_AB>;
-
-			gpioa: gpio@50002000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 0 16>;
-			};
-
-			gpiob: gpio@50003000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 16 16>;
-			};
-
-			gpioc: gpio@50004000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 32 16>;
-			};
-
-			gpiod: gpio@50005000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 48 16>;
-			};
-
-			gpioe: gpio@50006000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 64 16>;
-			};
-
-			gpiof: gpio@50007000 {
-				status = "okay";
-				ngpios = <6>;
-				gpio-ranges = <&pinctrl 6 86 6>;
-			};
-
-			gpiog: gpio@50008000 {
-				status = "okay";
-				ngpios = <10>;
-				gpio-ranges = <&pinctrl 6 102 10>;
-			};
-
-			gpioh: gpio@50009000 {
-				status = "okay";
-				ngpios = <2>;
-				gpio-ranges = <&pinctrl 0 112 2>;
-			};
-		};
-	};
-};
diff --git a/arch/arm/dts/stm32mp157xac-pinctrl.dtsi b/arch/arm/dts/stm32mp157xac-pinctrl.dtsi
deleted file mode 100644
index 26600f1..0000000
--- a/arch/arm/dts/stm32mp157xac-pinctrl.dtsi
+++ /dev/null
@@ -1,78 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
-/*
- * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
- * Author: Alexandre Torgue <alexandre.torgue@st.com>
- */
-
-#include "stm32mp157-pinctrl.dtsi"
-/ {
-	soc {
-		pinctrl: pin-controller@50002000 {
-			st,package = <STM32MP_PKG_AC>;
-
-			gpioa: gpio@50002000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 0 16>;
-			};
-
-			gpiob: gpio@50003000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 16 16>;
-			};
-
-			gpioc: gpio@50004000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 32 16>;
-			};
-
-			gpiod: gpio@50005000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 48 16>;
-			};
-
-			gpioe: gpio@50006000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 64 16>;
-			};
-
-			gpiof: gpio@50007000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 80 16>;
-			};
-
-			gpiog: gpio@50008000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 96 16>;
-			};
-
-			gpioh: gpio@50009000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 112 16>;
-			};
-
-			gpioi: gpio@5000a000 {
-				status = "okay";
-				ngpios = <12>;
-				gpio-ranges = <&pinctrl 0 128 12>;
-			};
-		};
-
-		pinctrl_z: pin-controller-z@54004000 {
-			st,package = <STM32MP_PKG_AC>;
-
-			gpioz: gpio@54004000 {
-				status = "okay";
-				ngpios = <8>;
-				gpio-ranges = <&pinctrl_z 0 400 8>;
-			};
-		};
-	};
-};
diff --git a/arch/arm/dts/stm32mp157xad-pinctrl.dtsi b/arch/arm/dts/stm32mp157xad-pinctrl.dtsi
deleted file mode 100644
index 910113f..0000000
--- a/arch/arm/dts/stm32mp157xad-pinctrl.dtsi
+++ /dev/null
@@ -1,62 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
-/*
- * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
- * Author: Alexandre Torgue <alexandre.torgue@st.com>
- */
-
-#include "stm32mp157-pinctrl.dtsi"
-/ {
-	soc {
-		pinctrl: pin-controller@50002000 {
-			st,package = <STM32MP_PKG_AD>;
-
-			gpioa: gpio@50002000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 0 16>;
-			};
-
-			gpiob: gpio@50003000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 16 16>;
-			};
-
-			gpioc: gpio@50004000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 32 16>;
-			};
-
-			gpiod: gpio@50005000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 48 16>;
-			};
-
-			gpioe: gpio@50006000 {
-				status = "okay";
-				ngpios = <16>;
-				gpio-ranges = <&pinctrl 0 64 16>;
-			};
-
-			gpiof: gpio@50007000 {
-				status = "okay";
-				ngpios = <6>;
-				gpio-ranges = <&pinctrl 6 86 6>;
-			};
-
-			gpiog: gpio@50008000 {
-				status = "okay";
-				ngpios = <10>;
-				gpio-ranges = <&pinctrl 6 102 10>;
-			};
-
-			gpioh: gpio@50009000 {
-				status = "okay";
-				ngpios = <2>;
-				gpio-ranges = <&pinctrl 0 112 2>;
-			};
-		};
-	};
-};
diff --git a/arch/arm/dts/stm32mp15xc.dtsi b/arch/arm/dts/stm32mp15xc.dtsi
new file mode 100644
index 0000000..b06a55a
--- /dev/null
+++ b/arch/arm/dts/stm32mp15xc.dtsi
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+/ {
+	soc {
+		cryp1: cryp@54001000 {
+			compatible = "st,stm32mp1-cryp";
+			reg = <0x54001000 0x400>;
+			interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&rcc CRYP1>;
+			resets = <&rcc CRYP1_R>;
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi b/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi
index 6c952a5..62c45de 100644
--- a/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi
@@ -4,7 +4,7 @@
  */
 
 #include <dt-bindings/clock/stm32mp1-clksrc.h>
-#include "stm32mp157-u-boot.dtsi"
+#include "stm32mp15-u-boot.dtsi"
 #include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi"
 
 / {
@@ -196,7 +196,10 @@
 
 &sdmmc1_b4_pins_a {
 	u-boot,dm-spl;
-	pins {
+	pins1 {
+		u-boot,dm-spl;
+	};
+	pins2 {
 		u-boot,dm-spl;
 	};
 };
diff --git a/arch/arm/dts/stm32mp15xx-dhcom.dtsi b/arch/arm/dts/stm32mp15xx-dhcom.dtsi
index e5be0a7..d8a255b 100644
--- a/arch/arm/dts/stm32mp15xx-dhcom.dtsi
+++ b/arch/arm/dts/stm32mp15xx-dhcom.dtsi
@@ -4,8 +4,10 @@
  */
 /dts-v1/;
 
-#include "stm32mp157c.dtsi"
-#include "stm32mp157xaa-pinctrl.dtsi"
+#include "stm32mp157.dtsi"
+#include "stm32mp15xc.dtsi"
+#include "stm32mp15-pinctrl.dtsi"
+#include "stm32mp15xxaa-pinctrl.dtsi"
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/mfd/st,stpmic1.h>
 
diff --git a/arch/arm/dts/stm32mp15xx-dkx.dtsi b/arch/arm/dts/stm32mp15xx-dkx.dtsi
new file mode 100644
index 0000000..42d3f0c
--- /dev/null
+++ b/arch/arm/dts/stm32mp15xx-dkx.dtsi
@@ -0,0 +1,639 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/mfd/st,stpmic1.h>
+
+/ {
+	memory@c0000000 {
+		device_type = "memory";
+		reg = <0xc0000000 0x20000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		mcuram2: mcuram2@10000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x10000000 0x40000>;
+			no-map;
+		};
+
+		vdev0vring0: vdev0vring0@10040000 {
+			compatible = "shared-dma-pool";
+			reg = <0x10040000 0x1000>;
+			no-map;
+		};
+
+		vdev0vring1: vdev0vring1@10041000 {
+			compatible = "shared-dma-pool";
+			reg = <0x10041000 0x1000>;
+			no-map;
+		};
+
+		vdev0buffer: vdev0buffer@10042000 {
+			compatible = "shared-dma-pool";
+			reg = <0x10042000 0x4000>;
+			no-map;
+		};
+
+		mcuram: mcuram@30000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x30000000 0x40000>;
+			no-map;
+		};
+
+		retram: retram@38000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x38000000 0x10000>;
+			no-map;
+		};
+
+		gpu_reserved: gpu@d4000000 {
+			reg = <0xd4000000 0x4000000>;
+			no-map;
+		};
+	};
+
+	led {
+		compatible = "gpio-leds";
+		blue {
+			label = "heartbeat";
+			gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+			default-state = "off";
+		};
+	};
+
+	sound {
+		compatible = "audio-graph-card";
+		label = "STM32MP1-DK";
+		routing =
+			"Playback" , "MCLK",
+			"Capture" , "MCLK",
+			"MICL" , "Mic Bias";
+		dais = <&sai2a_port &sai2b_port &i2s2_port>;
+		status = "okay";
+	};
+};
+
+&adc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&adc12_ain_pins_a>, <&adc12_usb_cc_pins_a>;
+	vdd-supply = <&vdd>;
+	vdda-supply = <&vdd>;
+	vref-supply = <&vrefbuf>;
+	status = "disabled";
+	adc1: adc@0 {
+		/*
+		 * Type-C USB_PWR_CC1 & USB_PWR_CC2 on in18 & in19.
+		 * Use at least 5 * RC time, e.g. 5 * (Rp + Rd) * C:
+		 * 5 * (56 + 47kOhms) * 5pF => 2.5us.
+		 * Use arbitrary margin here (e.g. 5us).
+		 */
+		st,min-sample-time-nsecs = <5000>;
+		/* AIN connector, USB Type-C CC1 & CC2 */
+		st,adc-channels = <0 1 6 13 18 19>;
+		status = "okay";
+	};
+	adc2: adc@100 {
+		/* AIN connector, USB Type-C CC1 & CC2 */
+		st,adc-channels = <0 1 2 6 18 19>;
+		st,min-sample-time-nsecs = <5000>;
+		status = "okay";
+	};
+};
+
+&cec {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&cec_pins_b>;
+	pinctrl-1 = <&cec_pins_sleep_b>;
+	status = "okay";
+};
+
+&ethernet0 {
+	status = "okay";
+	pinctrl-0 = <&ethernet0_rgmii_pins_a>;
+	pinctrl-1 = <&ethernet0_rgmii_pins_sleep_a>;
+	pinctrl-names = "default", "sleep";
+	phy-mode = "rgmii-id";
+	max-speed = <1000>;
+	phy-handle = <&phy0>;
+
+	mdio0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "snps,dwmac-mdio";
+		phy0: ethernet-phy@0 {
+			reg = <0>;
+		};
+	};
+};
+
+&gpu {
+	contiguous-area = <&gpu_reserved>;
+	status = "okay";
+};
+
+&i2c1 {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&i2c1_pins_a>;
+	pinctrl-1 = <&i2c1_pins_sleep_a>;
+	i2c-scl-rising-time-ns = <100>;
+	i2c-scl-falling-time-ns = <7>;
+	status = "okay";
+	/delete-property/dmas;
+	/delete-property/dma-names;
+
+	hdmi-transmitter@39 {
+		compatible = "sil,sii9022";
+		reg = <0x39>;
+		iovcc-supply = <&v3v3_hdmi>;
+		cvcc12-supply = <&v1v2_hdmi>;
+		reset-gpios = <&gpioa 10 GPIO_ACTIVE_LOW>;
+		interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+		interrupt-parent = <&gpiog>;
+		#sound-dai-cells = <0>;
+		status = "okay";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				sii9022_in: endpoint {
+					remote-endpoint = <&ltdc_ep0_out>;
+				};
+			};
+
+			port@3 {
+				reg = <3>;
+				sii9022_tx_endpoint: endpoint {
+					remote-endpoint = <&i2s2_endpoint>;
+				};
+			};
+		};
+	};
+
+	cs42l51: cs42l51@4a {
+		compatible = "cirrus,cs42l51";
+		reg = <0x4a>;
+		#sound-dai-cells = <0>;
+		VL-supply = <&v3v3>;
+		VD-supply = <&v1v8_audio>;
+		VA-supply = <&v1v8_audio>;
+		VAHP-supply = <&v1v8_audio>;
+		reset-gpios = <&gpiog 9 GPIO_ACTIVE_LOW>;
+		clocks = <&sai2a>;
+		clock-names = "MCLK";
+		status = "okay";
+
+		cs42l51_port: port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			cs42l51_tx_endpoint: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&sai2a_endpoint>;
+				frame-master;
+				bitclock-master;
+			};
+
+			cs42l51_rx_endpoint: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&sai2b_endpoint>;
+				frame-master;
+				bitclock-master;
+			};
+		};
+	};
+};
+
+&i2c4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c4_pins_a>;
+	i2c-scl-rising-time-ns = <185>;
+	i2c-scl-falling-time-ns = <20>;
+	status = "okay";
+	/* spare dmas for other usage */
+	/delete-property/dmas;
+	/delete-property/dma-names;
+
+	typec: stusb1600@28 {
+		compatible = "st,stusb1600";
+		reg = <0x28>;
+		interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+		interrupt-parent = <&gpioi>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&stusb1600_pins_a>;
+
+		status = "okay";
+
+		typec_con: connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			power-role = "sink";
+			power-opmode = "default";
+		};
+	};
+
+	pmic: stpmic@33 {
+		compatible = "st,stpmic1";
+		reg = <0x33>;
+		interrupts-extended = <&gpioa 0 IRQ_TYPE_EDGE_FALLING>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		status = "okay";
+
+		regulators {
+			compatible = "st,stpmic1-regulators";
+			ldo1-supply = <&v3v3>;
+			ldo3-supply = <&vdd_ddr>;
+			ldo6-supply = <&v3v3>;
+			pwr_sw1-supply = <&bst_out>;
+			pwr_sw2-supply = <&bst_out>;
+
+			vddcore: buck1 {
+				regulator-name = "vddcore";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-always-on;
+				regulator-initial-mode = <0>;
+				regulator-over-current-protection;
+			};
+
+			vdd_ddr: buck2 {
+				regulator-name = "vdd_ddr";
+				regulator-min-microvolt = <1350000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-always-on;
+				regulator-initial-mode = <0>;
+				regulator-over-current-protection;
+			};
+
+			vdd: buck3 {
+				regulator-name = "vdd";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+				st,mask-reset;
+				regulator-initial-mode = <0>;
+				regulator-over-current-protection;
+			};
+
+			v3v3: buck4 {
+				regulator-name = "v3v3";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+				regulator-over-current-protection;
+				regulator-initial-mode = <0>;
+			};
+
+			v1v8_audio: ldo1 {
+				regulator-name = "v1v8_audio";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				interrupts = <IT_CURLIM_LDO1 0>;
+			};
+
+			v3v3_hdmi: ldo2 {
+				regulator-name = "v3v3_hdmi";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+				interrupts = <IT_CURLIM_LDO2 0>;
+			};
+
+			vtt_ddr: ldo3 {
+				regulator-name = "vtt_ddr";
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <750000>;
+				regulator-always-on;
+				regulator-over-current-protection;
+			};
+
+			vdd_usb: ldo4 {
+				regulator-name = "vdd_usb";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				interrupts = <IT_CURLIM_LDO4 0>;
+			};
+
+			vdda: ldo5 {
+				regulator-name = "vdda";
+				regulator-min-microvolt = <2900000>;
+				regulator-max-microvolt = <2900000>;
+				interrupts = <IT_CURLIM_LDO5 0>;
+				regulator-boot-on;
+			};
+
+			v1v2_hdmi: ldo6 {
+				regulator-name = "v1v2_hdmi";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-always-on;
+				interrupts = <IT_CURLIM_LDO6 0>;
+			};
+
+			vref_ddr: vref_ddr {
+				regulator-name = "vref_ddr";
+				regulator-always-on;
+				regulator-over-current-protection;
+			};
+
+			 bst_out: boost {
+				regulator-name = "bst_out";
+				interrupts = <IT_OCP_BOOST 0>;
+			 };
+
+			vbus_otg: pwr_sw1 {
+				regulator-name = "vbus_otg";
+				interrupts = <IT_OCP_OTG 0>;
+			 };
+
+			 vbus_sw: pwr_sw2 {
+				regulator-name = "vbus_sw";
+				interrupts = <IT_OCP_SWOUT 0>;
+				regulator-active-discharge = <1>;
+			 };
+		};
+
+		onkey {
+			compatible = "st,stpmic1-onkey";
+			interrupts = <IT_PONKEY_F 0>, <IT_PONKEY_R 0>;
+			interrupt-names = "onkey-falling", "onkey-rising";
+			power-off-time-sec = <10>;
+			status = "okay";
+		};
+
+		watchdog {
+			compatible = "st,stpmic1-wdt";
+			status = "disabled";
+		};
+	};
+};
+
+&i2s2 {
+	clocks = <&rcc SPI2>, <&rcc SPI2_K>, <&rcc PLL3_Q>, <&rcc PLL3_R>;
+	clock-names = "pclk", "i2sclk", "x8k", "x11k";
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&i2s2_pins_a>;
+	pinctrl-1 = <&i2s2_pins_sleep_a>;
+	status = "okay";
+
+	i2s2_port: port {
+		i2s2_endpoint: endpoint {
+			remote-endpoint = <&sii9022_tx_endpoint>;
+			format = "i2s";
+			mclk-fs = <256>;
+		};
+	};
+};
+
+&ipcc {
+	status = "okay";
+};
+
+&iwdg2 {
+	timeout-sec = <32>;
+	status = "okay";
+};
+
+&ltdc {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&ltdc_pins_a>;
+	pinctrl-1 = <&ltdc_pins_sleep_a>;
+	status = "okay";
+
+	port {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ltdc_ep0_out: endpoint@0 {
+			reg = <0>;
+			remote-endpoint = <&sii9022_in>;
+		};
+	};
+};
+
+&m4_rproc {
+	memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>,
+			<&vdev0vring1>, <&vdev0buffer>;
+	mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>;
+	mbox-names = "vq0", "vq1", "shutdown";
+	interrupt-parent = <&exti>;
+	interrupts = <68 1>;
+	status = "okay";
+};
+
+&pwr_regulators {
+	vdd-supply = <&vdd>;
+	vdd_3v3_usbfs-supply = <&vdd_usb>;
+};
+
+&rng1 {
+	status = "okay";
+};
+
+&rtc {
+	status = "okay";
+};
+
+&sai2 {
+	clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>;
+	clock-names = "pclk", "x8k", "x11k";
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&sai2a_pins_a>, <&sai2b_pins_b>;
+	pinctrl-1 = <&sai2a_sleep_pins_a>, <&sai2b_sleep_pins_b>;
+	status = "okay";
+
+	sai2a: audio-controller@4400b004 {
+		#clock-cells = <0>;
+		dma-names = "tx";
+		clocks = <&rcc SAI2_K>;
+		clock-names = "sai_ck";
+		status = "okay";
+
+		sai2a_port: port {
+			sai2a_endpoint: endpoint {
+				remote-endpoint = <&cs42l51_tx_endpoint>;
+				format = "i2s";
+				mclk-fs = <256>;
+				dai-tdm-slot-num = <2>;
+				dai-tdm-slot-width = <32>;
+			};
+		};
+	};
+
+	sai2b: audio-controller@4400b024 {
+		dma-names = "rx";
+		st,sync = <&sai2a 2>;
+		clocks = <&rcc SAI2_K>, <&sai2a>;
+		clock-names = "sai_ck", "MCLK";
+		status = "okay";
+
+		sai2b_port: port {
+			sai2b_endpoint: endpoint {
+				remote-endpoint = <&cs42l51_rx_endpoint>;
+				format = "i2s";
+				mclk-fs = <256>;
+				dai-tdm-slot-num = <2>;
+				dai-tdm-slot-width = <32>;
+			};
+		};
+	};
+};
+
+&sdmmc1 {
+	pinctrl-names = "default", "opendrain", "sleep";
+	pinctrl-0 = <&sdmmc1_b4_pins_a>;
+	pinctrl-1 = <&sdmmc1_b4_od_pins_a>;
+	pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>;
+	broken-cd;
+	st,neg-edge;
+	bus-width = <4>;
+	vmmc-supply = <&v3v3>;
+	status = "okay";
+};
+
+&sdmmc3 {
+	pinctrl-names = "default", "opendrain", "sleep";
+	pinctrl-0 = <&sdmmc3_b4_pins_a>;
+	pinctrl-1 = <&sdmmc3_b4_od_pins_a>;
+	pinctrl-2 = <&sdmmc3_b4_sleep_pins_a>;
+	broken-cd;
+	st,neg-edge;
+	bus-width = <4>;
+	vmmc-supply = <&v3v3>;
+	status = "disabled";
+};
+
+&timers1 {
+	/* spare dmas for other usage */
+	/delete-property/dmas;
+	/delete-property/dma-names;
+	status = "disabled";
+	pwm {
+		pinctrl-0 = <&pwm1_pins_a>;
+		pinctrl-1 = <&pwm1_sleep_pins_a>;
+		pinctrl-names = "default", "sleep";
+		status = "okay";
+	};
+	timer@0 {
+		status = "okay";
+	};
+};
+
+&timers3 {
+	/delete-property/dmas;
+	/delete-property/dma-names;
+	status = "disabled";
+	pwm {
+		pinctrl-0 = <&pwm3_pins_a>;
+		pinctrl-1 = <&pwm3_sleep_pins_a>;
+		pinctrl-names = "default", "sleep";
+		status = "okay";
+	};
+	timer@2 {
+		status = "okay";
+	};
+};
+
+&timers4 {
+	/delete-property/dmas;
+	/delete-property/dma-names;
+	status = "disabled";
+	pwm {
+		pinctrl-0 = <&pwm4_pins_a &pwm4_pins_b>;
+		pinctrl-1 = <&pwm4_sleep_pins_a &pwm4_sleep_pins_b>;
+		pinctrl-names = "default", "sleep";
+		status = "okay";
+	};
+	timer@3 {
+		status = "okay";
+	};
+};
+
+&timers5 {
+	/delete-property/dmas;
+	/delete-property/dma-names;
+	status = "disabled";
+	pwm {
+		pinctrl-0 = <&pwm5_pins_a>;
+		pinctrl-1 = <&pwm5_sleep_pins_a>;
+		pinctrl-names = "default", "sleep";
+		status = "okay";
+	};
+	timer@4 {
+		status = "okay";
+	};
+};
+
+&timers6 {
+	/delete-property/dmas;
+	/delete-property/dma-names;
+	status = "disabled";
+	timer@5 {
+		status = "okay";
+	};
+};
+
+&timers12 {
+	/delete-property/dmas;
+	/delete-property/dma-names;
+	status = "disabled";
+	pwm {
+		pinctrl-0 = <&pwm12_pins_a>;
+		pinctrl-1 = <&pwm12_sleep_pins_a>;
+		pinctrl-names = "default", "sleep";
+		status = "okay";
+	};
+	timer@11 {
+		status = "okay";
+	};
+};
+
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart4_pins_a>;
+	status = "okay";
+};
+
+&usbh_ehci {
+	phys = <&usbphyc_port0>;
+	status = "okay";
+};
+
+&usbotg_hs {
+	dr_mode = "peripheral";
+	phys = <&usbphyc_port1 0>;
+	phy-names = "usb2-phy";
+	status = "okay";
+};
+
+&usbphyc {
+	status = "okay";
+};
+
+&usbphyc_port0 {
+	phy-supply = <&vdd_usb>;
+};
+
+&usbphyc_port1 {
+	phy-supply = <&vdd_usb>;
+};
+
+&vrefbuf {
+	regulator-min-microvolt = <2500000>;
+	regulator-max-microvolt = <2500000>;
+	vdda-supply = <&vdd>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/stm32mp15xxaa-pinctrl.dtsi b/arch/arm/dts/stm32mp15xxaa-pinctrl.dtsi
new file mode 100644
index 0000000..04f7a43
--- /dev/null
+++ b/arch/arm/dts/stm32mp15xxaa-pinctrl.dtsi
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+&pinctrl {
+	st,package = <STM32MP_PKG_AA>;
+
+	gpioa: gpio@50002000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 0 16>;
+	};
+
+	gpiob: gpio@50003000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 16 16>;
+	};
+
+	gpioc: gpio@50004000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 32 16>;
+	};
+
+	gpiod: gpio@50005000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 48 16>;
+	};
+
+	gpioe: gpio@50006000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 64 16>;
+	};
+
+	gpiof: gpio@50007000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 80 16>;
+	};
+
+	gpiog: gpio@50008000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 96 16>;
+	};
+
+	gpioh: gpio@50009000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 112 16>;
+	};
+
+	gpioi: gpio@5000a000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 128 16>;
+	};
+
+	gpioj: gpio@5000b000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 144 16>;
+	};
+
+	gpiok: gpio@5000c000 {
+		status = "okay";
+		ngpios = <8>;
+		gpio-ranges = <&pinctrl 0 160 8>;
+	};
+};
+
+&pinctrl_z {
+	st,package = <STM32MP_PKG_AA>;
+
+	gpioz: gpio@54004000 {
+		status = "okay";
+		ngpios = <8>;
+		gpio-ranges = <&pinctrl_z 0 400 8>;
+	};
+};
diff --git a/arch/arm/dts/stm32mp15xxab-pinctrl.dtsi b/arch/arm/dts/stm32mp15xxab-pinctrl.dtsi
new file mode 100644
index 0000000..328dad1
--- /dev/null
+++ b/arch/arm/dts/stm32mp15xxab-pinctrl.dtsi
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+&pinctrl {
+	st,package = <STM32MP_PKG_AB>;
+
+	gpioa: gpio@50002000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 0 16>;
+	};
+
+	gpiob: gpio@50003000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 16 16>;
+	};
+
+	gpioc: gpio@50004000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 32 16>;
+	};
+
+	gpiod: gpio@50005000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 48 16>;
+	};
+
+	gpioe: gpio@50006000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 64 16>;
+	};
+
+	gpiof: gpio@50007000 {
+		status = "okay";
+		ngpios = <6>;
+		gpio-ranges = <&pinctrl 6 86 6>;
+	};
+
+	gpiog: gpio@50008000 {
+		status = "okay";
+		ngpios = <10>;
+		gpio-ranges = <&pinctrl 6 102 10>;
+	};
+
+	gpioh: gpio@50009000 {
+		status = "okay";
+		ngpios = <2>;
+		gpio-ranges = <&pinctrl 0 112 2>;
+	};
+};
diff --git a/arch/arm/dts/stm32mp15xxac-pinctrl.dtsi b/arch/arm/dts/stm32mp15xxac-pinctrl.dtsi
new file mode 100644
index 0000000..7eaa245
--- /dev/null
+++ b/arch/arm/dts/stm32mp15xxac-pinctrl.dtsi
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+&pinctrl {
+	st,package = <STM32MP_PKG_AC>;
+
+	gpioa: gpio@50002000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 0 16>;
+	};
+
+	gpiob: gpio@50003000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 16 16>;
+	};
+
+	gpioc: gpio@50004000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 32 16>;
+	};
+
+	gpiod: gpio@50005000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 48 16>;
+	};
+
+	gpioe: gpio@50006000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 64 16>;
+	};
+
+	gpiof: gpio@50007000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 80 16>;
+	};
+
+	gpiog: gpio@50008000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 96 16>;
+	};
+
+	gpioh: gpio@50009000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 112 16>;
+	};
+
+	gpioi: gpio@5000a000 {
+		status = "okay";
+		ngpios = <12>;
+		gpio-ranges = <&pinctrl 0 128 12>;
+	};
+};
+
+&pinctrl_z {
+	st,package = <STM32MP_PKG_AC>;
+
+	gpioz: gpio@54004000 {
+		status = "okay";
+		ngpios = <8>;
+		gpio-ranges = <&pinctrl_z 0 400 8>;
+	};
+};
diff --git a/arch/arm/dts/stm32mp15xxad-pinctrl.dtsi b/arch/arm/dts/stm32mp15xxad-pinctrl.dtsi
new file mode 100644
index 0000000..b63e207
--- /dev/null
+++ b/arch/arm/dts/stm32mp15xxad-pinctrl.dtsi
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+&pinctrl {
+	st,package = <STM32MP_PKG_AD>;
+
+	gpioa: gpio@50002000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 0 16>;
+	};
+
+	gpiob: gpio@50003000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 16 16>;
+	};
+
+	gpioc: gpio@50004000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 32 16>;
+	};
+
+	gpiod: gpio@50005000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 48 16>;
+	};
+
+	gpioe: gpio@50006000 {
+		status = "okay";
+		ngpios = <16>;
+		gpio-ranges = <&pinctrl 0 64 16>;
+	};
+
+	gpiof: gpio@50007000 {
+		status = "okay";
+		ngpios = <6>;
+		gpio-ranges = <&pinctrl 6 86 6>;
+	};
+
+	gpiog: gpio@50008000 {
+		status = "okay";
+		ngpios = <10>;
+		gpio-ranges = <&pinctrl 6 102 10>;
+	};
+
+	gpioh: gpio@50009000 {
+		status = "okay";
+		ngpios = <2>;
+		gpio-ranges = <&pinctrl 0 112 2>;
+	};
+};
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index 8a81c07..6eca8db 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -135,6 +135,6 @@
 source "board/lego/ev3/Kconfig"
 
 config SPL_LDSCRIPT
-	default "board/$(BOARDDIR)/u-boot-spl-da850evm.lds"
+	default "board/davinci/da8xxevm/u-boot-spl-da850evm.lds"
 
 endif
diff --git a/arch/arm/mach-imx/imx_bootaux.c b/arch/arm/mach-imx/imx_bootaux.c
index 21e96f8..ec0da11 100644
--- a/arch/arm/mach-imx/imx_bootaux.c
+++ b/arch/arm/mach-imx/imx_bootaux.c
@@ -12,70 +12,6 @@
 #include <linux/compiler.h>
 #include <cpu_func.h>
 
-#ifndef CONFIG_IMX8M
-const __weak struct rproc_att hostmap[] = { };
-
-static const struct rproc_att *get_host_mapping(unsigned long auxcore)
-{
-	const struct rproc_att *mmap = hostmap;
-
-	while (mmap && mmap->size) {
-		if (mmap->da <= auxcore &&
-		    mmap->da + mmap->size > auxcore)
-			return mmap;
-		mmap++;
-	}
-
-	return NULL;
-}
-
-/*
- * A very simple elf loader, assumes the image is valid, returns the
- * entry point address.
- */
-static unsigned long load_elf_image_phdr(unsigned long addr)
-{
-	Elf32_Ehdr *ehdr; /* ELF header structure pointer */
-	Elf32_Phdr *phdr; /* Program header structure pointer */
-	int i;
-
-	ehdr = (Elf32_Ehdr *)addr;
-	phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
-
-	/* Load each program header */
-	for (i = 0; i < ehdr->e_phnum; ++i, ++phdr) {
-		const struct rproc_att *mmap = get_host_mapping(phdr->p_paddr);
-		void *dst, *src;
-
-		if (phdr->p_type != PT_LOAD)
-			continue;
-
-		if (!mmap) {
-			printf("Invalid aux core address: %08x",
-			       phdr->p_paddr);
-			return 0;
-		}
-
-		dst = (void *)(phdr->p_paddr - mmap->da) + mmap->sa;
-		src = (void *)addr + phdr->p_offset;
-
-		debug("Loading phdr %i to 0x%p (%i bytes)\n",
-		      i, dst, phdr->p_filesz);
-
-		if (phdr->p_filesz)
-			memcpy(dst, src, phdr->p_filesz);
-		if (phdr->p_filesz != phdr->p_memsz)
-			memset(dst + phdr->p_filesz, 0x00,
-			       phdr->p_memsz - phdr->p_filesz);
-		flush_cache((unsigned long)dst &
-			    ~(CONFIG_SYS_CACHELINE_SIZE - 1),
-			    ALIGN(phdr->p_filesz, CONFIG_SYS_CACHELINE_SIZE));
-	}
-
-	return ehdr->e_entry;
-}
-#endif
-
 int arch_auxiliary_core_up(u32 core_id, ulong addr)
 {
 	ulong stack, pc;
diff --git a/arch/arm/mach-k3/Kconfig b/arch/arm/mach-k3/Kconfig
index 8f42722..a13cbef 100644
--- a/arch/arm/mach-k3/Kconfig
+++ b/arch/arm/mach-k3/Kconfig
@@ -126,6 +126,14 @@
 	  tree blob. Keep it as tight as possible, as this directly affects the
 	  overall SPL memory footprint.
 
+config K3_SYSFW_IMAGE_SPI_OFFS
+	hex "SPI offset of SYSFW firmware and configuration blob"
+	depends on K3_LOAD_SYSFW
+	default	0x6C0000
+	help
+	  Offset of the combined System Firmware and configuration image tree
+	  blob to be loaded when booting from a SPI flash memory.
+
 config SYS_K3_SPL_ATF
 	bool "Start Cortex-A from SPL"
 	depends on SPL && CPU_V7R
diff --git a/arch/arm/mach-k3/am6_init.c b/arch/arm/mach-k3/am6_init.c
index d0b10e5..3768bcc 100644
--- a/arch/arm/mach-k3/am6_init.c
+++ b/arch/arm/mach-k3/am6_init.c
@@ -161,10 +161,8 @@
 		pinctrl_select_state(dev, "default");
 
 	/*
-	 * Load, start up, and configure system controller firmware. Provide
-	 * the U-Boot console init function to the SYSFW post-PM configuration
-	 * callback hook, effectively switching on (or over) the console
-	 * output.
+	 * Load, start up, and configure system controller firmware while
+	 * also populating the SYSFW post-PM configuration callback hook.
 	 */
 	k3_sysfw_loader(k3_mmc_stop_clock, k3_mmc_restart_clock);
 
@@ -181,6 +179,9 @@
 	preloader_console_init();
 #endif
 
+	/* Output System Firmware version info */
+	k3_sysfw_print_ver();
+
 	/* Perform EEPROM-based board detection */
 	do_board_detect();
 
diff --git a/arch/arm/mach-k3/arm64-mmu.c b/arch/arm/mach-k3/arm64-mmu.c
index 7f908ee..95f830b 100644
--- a/arch/arm/mach-k3/arm64-mmu.c
+++ b/arch/arm/mach-k3/arm64-mmu.c
@@ -50,6 +50,13 @@
 		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
 			 PTE_BLOCK_INNER_SHARE
 	}, {
+		.virt = 0x500000000UL,
+		.phys = 0x500000000UL,
+		.size = 0x400000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
 		/* List terminator */
 		0,
 	}
@@ -60,7 +67,7 @@
 
 #ifdef CONFIG_SOC_K3_J721E
 /* NR_DRAM_BANKS + 32bit IO + 64bit IO + terminator */
-#define NR_MMU_REGIONS	(CONFIG_NR_DRAM_BANKS + 5)
+#define NR_MMU_REGIONS	(CONFIG_NR_DRAM_BANKS + 6)
 
 /* ToDo: Add 64bit IO */
 struct mm_region j721e_mem_map[NR_MMU_REGIONS] = {
@@ -103,6 +110,12 @@
 			 PTE_BLOCK_NON_SHARE |
 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
 	}, {
+		.virt = 0x4d80000000UL,
+		.phys = 0x4d80000000UL,
+		.size = 0x0002000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
+			 PTE_BLOCK_INNER_SHARE
+	}, {
 		/* List terminator */
 		0,
 	}
diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c
index 7af60a7..efd84ec 100644
--- a/arch/arm/mach-k3/common.c
+++ b/arch/arm/mach-k3/common.c
@@ -17,6 +17,10 @@
 #include <asm/arch/sys_proto.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
+#include <fs_loader.h>
+#include <fs.h>
+#include <env.h>
+#include <elf.h>
 
 struct ti_sci_handle *get_ti_sci_handle(void)
 {
@@ -31,6 +35,28 @@
 	return (struct ti_sci_handle *)ti_sci_get_handle_from_sysfw(dev);
 }
 
+void k3_sysfw_print_ver(void)
+{
+	struct ti_sci_handle *ti_sci = get_ti_sci_handle();
+	char fw_desc[sizeof(ti_sci->version.firmware_description) + 1];
+
+	/*
+	 * Output System Firmware version info. Note that since the
+	 * 'firmware_description' field is not guaranteed to be zero-
+	 * terminated we manually add a \0 terminator if needed. Further
+	 * note that we intentionally no longer rely on the extended
+	 * printf() formatter '%.*s' to not having to require a more
+	 * full-featured printf() implementation.
+	 */
+	strncpy(fw_desc, ti_sci->version.firmware_description,
+		sizeof(ti_sci->version.firmware_description));
+	fw_desc[sizeof(fw_desc) - 1] = '\0';
+
+	printf("SYSFW ABI: %d.%d (firmware rev 0x%04x '%s')\n",
+	       ti_sci->version.abi_major, ti_sci->version.abi_minor,
+	       ti_sci->version.firmware_revision, fw_desc);
+}
+
 DECLARE_GLOBAL_DATA_PTR;
 
 #ifdef CONFIG_K3_EARLY_CONS
@@ -58,23 +84,98 @@
 #endif
 
 #ifdef CONFIG_SYS_K3_SPL_ATF
+
+void init_env(void)
+{
+#ifdef CONFIG_SPL_ENV_SUPPORT
+	char *part;
+
+	env_init();
+	env_relocate();
+	switch (spl_boot_device()) {
+	case BOOT_DEVICE_MMC2:
+		part = env_get("bootpart");
+		env_set("storage_interface", "mmc");
+		env_set("fw_dev_part", part);
+		break;
+	case BOOT_DEVICE_SPI:
+		env_set("storage_interface", "ubi");
+		env_set("fw_ubi_mtdpart", "UBI");
+		env_set("fw_ubi_volume", "UBI0");
+		break;
+	default:
+		printf("%s from device %u not supported!\n",
+		       __func__, spl_boot_device());
+		return;
+	}
+#endif
+}
+
+#ifdef CONFIG_FS_LOADER
+int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr)
+{
+	struct udevice *fsdev;
+	char *name = NULL;
+	int size = 0;
+
+	*loadaddr = 0;
+#ifdef CONFIG_SPL_ENV_SUPPORT
+	switch (spl_boot_device()) {
+	case BOOT_DEVICE_MMC2:
+		name = env_get(name_fw);
+		*loadaddr = env_get_hex(name_loadaddr, *loadaddr);
+		break;
+	default:
+		printf("Loading rproc fw image from device %u not supported!\n",
+		       spl_boot_device());
+		return 0;
+	}
+#endif
+	if (!*loadaddr)
+		return 0;
+
+	if (!uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0, &fsdev)) {
+		size = request_firmware_into_buf(fsdev, name, (void *)*loadaddr,
+						 0, 0);
+	}
+
+	return size;
+}
+#else
+int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr)
+{
+	return 0;
+}
+#endif
+
+__weak void start_non_linux_remote_cores(void)
+{
+}
+
 void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
 {
+	typedef void __noreturn (*image_entry_noargs_t)(void);
 	struct ti_sci_handle *ti_sci = get_ti_sci_handle();
-	int ret;
+	u32 loadaddr = 0;
+	int ret, size;
 
 	/* Release all the exclusive devices held by SPL before starting ATF */
 	ti_sci->ops.dev_ops.release_exclusive_devices(ti_sci);
 
+	ret = rproc_init();
+	if (ret)
+		panic("rproc failed to be initialized (%d)\n", ret);
+
+	init_env();
+	start_non_linux_remote_cores();
+	size = load_firmware("name_mcur5f0_0fw", "addr_mcur5f0_0load",
+			     &loadaddr);
+
+
 	/*
 	 * It is assumed that remoteproc device 1 is the corresponding
 	 * Cortex-A core which runs ATF. Make sure DT reflects the same.
 	 */
-	ret = rproc_dev_init(1);
-	if (ret)
-		panic("%s: ATF failed to initialize on rproc (%d)\n", __func__,
-		      ret);
-
 	ret = rproc_load(1, spl_image->entry_point, 0x200);
 	if (ret)
 		panic("%s: ATF failed to load on rproc (%d)\n", __func__, ret);
@@ -85,13 +186,18 @@
 	ret = rproc_start(1);
 	if (ret)
 		panic("%s: ATF failed to start on rproc (%d)\n", __func__, ret);
+	if (!(size > 0 && valid_elf_image(loadaddr))) {
+		debug("Shutting down...\n");
+		release_resources_for_core_shutdown();
 
-	debug("Releasing resources...\n");
-	release_resources_for_core_shutdown();
+		while (1)
+			asm volatile("wfe");
+	}
 
-	debug("Finalizing core shutdown...\n");
-	while (1)
-		asm volatile("wfe");
+	image_entry_noargs_t image_entry =
+		(image_entry_noargs_t)load_elf_image_phdr(loadaddr);
+
+	image_entry();
 }
 #endif
 
diff --git a/arch/arm/mach-k3/common.h b/arch/arm/mach-k3/common.h
index d8b34fe..b1cbe11 100644
--- a/arch/arm/mach-k3/common.h
+++ b/arch/arm/mach-k3/common.h
@@ -24,3 +24,6 @@
 int early_console_init(void);
 void disable_linefill_optimization(void);
 void remove_fwl_configs(struct fwl_data *fwl_data, size_t fwl_data_size);
+void start_non_linux_remote_cores(void);
+int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr);
+void k3_sysfw_print_ver(void);
diff --git a/arch/arm/mach-k3/j721e_init.c b/arch/arm/mach-k3/j721e_init.c
index 0994522..f34090f 100644
--- a/arch/arm/mach-k3/j721e_init.c
+++ b/arch/arm/mach-k3/j721e_init.c
@@ -19,6 +19,7 @@
 #include <dm/uclass-internal.h>
 #include <dm/pinctrl.h>
 #include <mmc.h>
+#include <remoteproc.h>
 
 #ifdef CONFIG_SPL_BUILD
 #ifdef CONFIG_K3_LOAD_SYSFW
@@ -202,6 +203,9 @@
 	preloader_console_init();
 #endif
 
+	/* Output System Firmware version info */
+	k3_sysfw_print_ver();
+
 	/* Perform EEPROM-based board detection */
 	do_board_detect();
 
@@ -326,3 +330,36 @@
 	}
 }
 #endif
+
+#ifdef CONFIG_SYS_K3_SPL_ATF
+void start_non_linux_remote_cores(void)
+{
+	int size = 0, ret;
+	u32 loadaddr = 0;
+
+	size = load_firmware("name_mainr5f0_0fw", "addr_mainr5f0_0load",
+			     &loadaddr);
+	if (size <= 0)
+		goto err_load;
+
+	/* assuming remoteproc 2 is aliased for the needed remotecore */
+	ret = rproc_load(2, loadaddr, size);
+	if (ret) {
+		printf("Firmware failed to start on rproc (%d)\n", ret);
+		goto err_load;
+	}
+
+	ret = rproc_start(2);
+	if (ret) {
+		printf("Firmware init failed on rproc (%d)\n", ret);
+		goto err_load;
+	}
+
+	printf("Remoteproc 2 started successfully\n");
+
+	return;
+
+err_load:
+	rproc_reset(2);
+}
+#endif
diff --git a/arch/arm/mach-k3/r5_mpu.c b/arch/arm/mach-k3/r5_mpu.c
index ee076ed..3d2ff67 100644
--- a/arch/arm/mach-k3/r5_mpu.c
+++ b/arch/arm/mach-k3/r5_mpu.c
@@ -26,7 +26,9 @@
 	/* U-Boot's code area marking it as WB and Write allocate */
 	{CONFIG_SYS_SDRAM_BASE, REGION_2, XN_DIS, PRIV_RW_USR_RW,
 	 O_I_WB_RD_WR_ALLOC, REGION_2GB},
-	{0x0, 3, 0x0, 0x0, 0x0, 0x0},
+	/* mcu_r5fss0_core0 BTCM area marking it as WB and Write allocate. */
+	{0x41010000, 3, XN_DIS, PRIV_RW_USR_RW, O_I_WB_RD_WR_ALLOC,
+	 REGION_8MB},
 	{0x0, 4, 0x0, 0x0, 0x0, 0x0},
 	{0x0, 5, 0x0, 0x0, 0x0, 0x0},
 	{0x0, 6, 0x0, 0x0, 0x0, 0x0},
diff --git a/arch/arm/mach-k3/sysfw-loader.c b/arch/arm/mach-k3/sysfw-loader.c
index db02607..4f5c848 100644
--- a/arch/arm/mach-k3/sysfw-loader.c
+++ b/arch/arm/mach-k3/sysfw-loader.c
@@ -14,6 +14,8 @@
 #include <g_dnl.h>
 #include <usb.h>
 #include <dfu.h>
+#include <dm/uclass-internal.h>
+#include <spi_flash.h>
 
 #include <asm/arch/sys_proto.h>
 #include "common.h"
@@ -197,13 +199,33 @@
 }
 #endif
 
+#if CONFIG_IS_ENABLED(SPI_LOAD)
+static void *k3_sysfw_get_spi_addr(void)
+{
+	struct udevice *dev;
+	fdt_addr_t addr;
+	int ret;
+
+	ret = uclass_find_device_by_seq(UCLASS_SPI, CONFIG_SF_DEFAULT_BUS,
+					true, &dev);
+	if (ret)
+		return NULL;
+
+	addr = dev_read_addr_index(dev, 1);
+	if (addr == FDT_ADDR_T_NONE)
+		return NULL;
+
+	return (void *)(addr + CONFIG_K3_SYSFW_IMAGE_SPI_OFFS);
+}
+#endif
+
 void k3_sysfw_loader(void (*config_pm_pre_callback) (void),
 		     void (*config_pm_done_callback)(void))
 {
 	struct spl_image_info spl_image = { 0 };
 	struct spl_boot_device bootdev = { 0 };
 	struct ti_sci_handle *ti_sci;
-	int ret;
+	int ret = 0;
 
 	/* Reserve a block of aligned memory for loading the SYSFW image */
 	sysfw_load_address = memalign(ARCH_DMA_MINALIGN,
@@ -244,6 +266,13 @@
 #endif
 		break;
 #endif
+#if CONFIG_IS_ENABLED(SPI_LOAD)
+	case BOOT_DEVICE_SPI:
+		sysfw_load_address = k3_sysfw_get_spi_addr();
+		if (!sysfw_load_address)
+			ret = -ENODEV;
+		break;
+#endif
 #if CONFIG_IS_ENABLED(YMODEM_SUPPORT)
 	case BOOT_DEVICE_UART:
 #ifdef CONFIG_K3_EARLY_CONS
@@ -305,22 +334,4 @@
 	 */
 	if (config_pm_done_callback)
 		config_pm_done_callback();
-
-	/*
-	 * Output System Firmware version info. Note that since the
-	 * 'firmware_description' field is not guaranteed to be zero-
-	 * terminated we manually add a \0 terminator if needed. Further
-	 * note that we intentionally no longer rely on the extended
-	 * printf() formatter '%.*s' to not having to require a more
-	 * full-featured printf() implementation.
-	 */
-	char fw_desc[sizeof(ti_sci->version.firmware_description) + 1];
-
-	strncpy(fw_desc, ti_sci->version.firmware_description,
-		sizeof(ti_sci->version.firmware_description));
-	fw_desc[sizeof(fw_desc) - 1] = '\0';
-
-	printf("SYSFW ABI: %d.%d (firmware rev 0x%04x '%s')\n",
-	       ti_sci->version.abi_major, ti_sci->version.abi_minor,
-	       ti_sci->version.firmware_revision, fw_desc);
 }
diff --git a/arch/arm/mach-omap2/am33xx/clock_am33xx.c b/arch/arm/mach-omap2/am33xx/clock_am33xx.c
index f2cd496..2427933 100644
--- a/arch/arm/mach-omap2/am33xx/clock_am33xx.c
+++ b/arch/arm/mach-omap2/am33xx/clock_am33xx.c
@@ -226,6 +226,10 @@
 		&cmper->usb0clkctrl,
 		&cmper->emiffwclkctrl,
 		&cmper->emifclkctrl,
+#if CONFIG_IS_ENABLED(AM335X_LCD)
+		&cmper->lcdclkctrl,
+		&cmper->lcdcclkstctrl,
+#endif
 		0
 	};
 
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig
index 2984a3e..7644b8d 100644
--- a/arch/arm/mach-orion5x/Kconfig
+++ b/arch/arm/mach-orion5x/Kconfig
@@ -15,7 +15,4 @@
 
 source "board/LaCie/edminiv2/Kconfig"
 
-config SPL_LDSCRIPT
-	default "$(CPUDIR)/orion5x/u-boot-spl.lds" if ORION5X
-
 endif
diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c
index a77c706..3b923f0 100644
--- a/arch/arm/mach-stm32mp/bsec.c
+++ b/arch/arm/mach-stm32mp/bsec.c
@@ -12,8 +12,6 @@
 #include <linux/iopoll.h>
 
 #define BSEC_OTP_MAX_VALUE		95
-
-#ifndef CONFIG_STM32MP1_TRUSTED
 #define BSEC_TIMEOUT_US			10000
 
 /* BSEC REGISTER OFFSET (base relative) */
@@ -24,9 +22,10 @@
 #define BSEC_OTP_LOCK_OFF		0x010
 #define BSEC_DISTURBED_OFF		0x01C
 #define BSEC_ERROR_OFF			0x034
-#define BSEC_SPLOCK_OFF			0x064 /* Program safmem sticky lock */
-#define BSEC_SWLOCK_OFF			0x07C /* write in OTP sticky lock */
-#define BSEC_SRLOCK_OFF			0x094 /* shadowing sticky lock */
+#define BSEC_WRLOCK_OFF			0x04C /* OTP write permananet lock */
+#define BSEC_SPLOCK_OFF			0x064 /* OTP write sticky lock */
+#define BSEC_SWLOCK_OFF			0x07C /* shadow write sticky lock */
+#define BSEC_SRLOCK_OFF			0x094 /* shadow read sticky lock */
 #define BSEC_OTP_DATA_OFF		0x200
 
 /* BSEC_CONFIGURATION Register MASK */
@@ -53,6 +52,24 @@
 #define BSEC_LOCK_PROGRAM		0x04
 
 /**
+ * bsec_lock() - manage lock for each type SR/SP/SW
+ * @address: address of bsec IP register
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * Return: true if locked else false
+ */
+static bool bsec_read_lock(u32 address, u32 otp)
+{
+	u32 bit;
+	u32 bank;
+
+	bit = 1 << (otp & OTP_LOCK_MASK);
+	bank = ((otp >> OTP_LOCK_BANK_SHIFT) & OTP_LOCK_MASK) * sizeof(u32);
+
+	return !!(readl(address + bank) & bit);
+}
+
+#ifndef CONFIG_STM32MP1_TRUSTED
+/**
  * bsec_check_error() - Check status of one otp
  * @base: base address of bsec IP
  * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
@@ -75,23 +92,6 @@
 }
 
 /**
- * bsec_lock() - manage lock for each type SR/SP/SW
- * @address: address of bsec IP register
- * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
- * Return: true if locked else false
- */
-static bool bsec_read_lock(u32 address, u32 otp)
-{
-	u32 bit;
-	u32 bank;
-
-	bit = 1 << (otp & OTP_LOCK_MASK);
-	bank = ((otp >> OTP_LOCK_BANK_SHIFT) & OTP_LOCK_MASK) * sizeof(u32);
-
-	return !!(readl(address + bank) & bit);
-}
-
-/**
  * bsec_read_SR_lock() - read SR lock (Shadowing)
  * @base: base address of bsec IP
  * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
@@ -324,6 +324,16 @@
 #endif
 }
 
+static int stm32mp_bsec_read_lock(struct udevice *dev, u32 *val, u32 otp)
+{
+	struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
+
+	/* return OTP permanent write lock status */
+	*val = bsec_read_lock(plat->base + BSEC_WRLOCK_OFF, otp);
+
+	return 0;
+}
+
 static int stm32mp_bsec_write_otp(struct udevice *dev, u32 val, u32 otp)
 {
 #ifdef CONFIG_STM32MP1_TRUSTED
@@ -350,22 +360,41 @@
 #endif
 }
 
+static int stm32mp_bsec_write_lock(struct udevice *dev, u32 val, u32 otp)
+{
+#ifdef CONFIG_STM32MP1_TRUSTED
+	if (val == 1)
+		return stm32_smc_exec(STM32_SMC_BSEC,
+				      STM32_SMC_WRLOCK_OTP,
+				      otp, 0);
+	if (val == 0)
+		return 0; /* nothing to do */
+
+	return -EINVAL;
+#else
+	return -ENOTSUPP;
+#endif
+}
+
 static int stm32mp_bsec_read(struct udevice *dev, int offset,
 			     void *buf, int size)
 {
 	int ret;
 	int i;
-	bool shadow = true;
+	bool shadow = true, lock = false;
 	int nb_otp = size / sizeof(u32);
 	int otp;
 	unsigned int offs = offset;
 
-	if (offs >= STM32_BSEC_OTP_OFFSET) {
+	if (offs >= STM32_BSEC_LOCK_OFFSET) {
+		offs -= STM32_BSEC_LOCK_OFFSET;
+		lock = true;
+	} else if (offs >= STM32_BSEC_OTP_OFFSET) {
 		offs -= STM32_BSEC_OTP_OFFSET;
 		shadow = false;
 	}
 
-	if (offs < 0 || (offs % 4) || (size % 4))
+	if ((offs % 4) || (size % 4))
 		return -EINVAL;
 
 	otp = offs / sizeof(u32);
@@ -373,7 +402,9 @@
 	for (i = otp; i < (otp + nb_otp) && i <= BSEC_OTP_MAX_VALUE; i++) {
 		u32 *addr = &((u32 *)buf)[i - otp];
 
-		if (shadow)
+		if (lock)
+			ret = stm32mp_bsec_read_lock(dev, addr, i);
+		else if (shadow)
 			ret = stm32mp_bsec_read_shadow(dev, addr, i);
 		else
 			ret = stm32mp_bsec_read_otp(dev, addr, i);
@@ -392,17 +423,20 @@
 {
 	int ret = 0;
 	int i;
-	bool shadow = true;
+	bool shadow = true, lock = false;
 	int nb_otp = size / sizeof(u32);
 	int otp;
 	unsigned int offs = offset;
 
-	if (offs >= STM32_BSEC_OTP_OFFSET) {
+	if (offs >= STM32_BSEC_LOCK_OFFSET) {
+		offs -= STM32_BSEC_LOCK_OFFSET;
+		lock = true;
+	} else if (offs >= STM32_BSEC_OTP_OFFSET) {
 		offs -= STM32_BSEC_OTP_OFFSET;
 		shadow = false;
 	}
 
-	if (offs < 0 || (offs % 4) || (size % 4))
+	if ((offs % 4) || (size % 4))
 		return -EINVAL;
 
 	otp = offs / sizeof(u32);
@@ -410,7 +444,9 @@
 	for (i = otp; i < otp + nb_otp && i <= BSEC_OTP_MAX_VALUE; i++) {
 		u32 *val = &((u32 *)buf)[i - otp];
 
-		if (shadow)
+		if (lock)
+			ret = stm32mp_bsec_write_lock(dev, *val, i);
+		else if (shadow)
 			ret = stm32mp_bsec_write_shadow(dev, *val, i);
 		else
 			ret = stm32mp_bsec_write_otp(dev, *val, i);
diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c
index ea0bd94..9aa5794 100644
--- a/arch/arm/mach-stm32mp/cpu.c
+++ b/arch/arm/mach-stm32mp/cpu.c
@@ -61,12 +61,6 @@
 #define BOOTROM_INSTANCE_MASK	 GENMASK(31, 16)
 #define BOOTROM_INSTANCE_SHIFT	16
 
-/* BSEC OTP index */
-#define BSEC_OTP_RPN	1
-#define BSEC_OTP_SERIAL	13
-#define BSEC_OTP_PKG	16
-#define BSEC_OTP_MAC	57
-
 /* Device Part Number (RPN) = OTP_DATA1 lower 8 bits */
 #define RPN_SHIFT	0
 #define RPN_MASK	GENMASK(7, 0)
@@ -285,25 +279,42 @@
 	return get_otp(BSEC_OTP_PKG, PKG_SHIFT, PKG_MASK);
 }
 
-#if defined(CONFIG_DISPLAY_CPUINFO)
-int print_cpuinfo(void)
+void get_soc_name(char name[SOC_NAME_SIZE])
 {
 	char *cpu_s, *cpu_r, *pkg;
 
 	/* MPUs Part Numbers */
 	switch (get_cpu_type()) {
+	case CPU_STM32MP157Fxx:
+		cpu_s = "157F";
+		break;
+	case CPU_STM32MP157Dxx:
+		cpu_s = "157D";
+		break;
 	case CPU_STM32MP157Cxx:
 		cpu_s = "157C";
 		break;
 	case CPU_STM32MP157Axx:
 		cpu_s = "157A";
 		break;
+	case CPU_STM32MP153Fxx:
+		cpu_s = "153F";
+		break;
+	case CPU_STM32MP153Dxx:
+		cpu_s = "153D";
+		break;
 	case CPU_STM32MP153Cxx:
 		cpu_s = "153C";
 		break;
 	case CPU_STM32MP153Axx:
 		cpu_s = "153A";
 		break;
+	case CPU_STM32MP151Fxx:
+		cpu_s = "151F";
+		break;
+	case CPU_STM32MP151Dxx:
+		cpu_s = "151D";
+		break;
 	case CPU_STM32MP151Cxx:
 		cpu_s = "151C";
 		break;
@@ -350,7 +361,16 @@
 		break;
 	}
 
-	printf("CPU: STM32MP%s%s Rev.%s\n", cpu_s, pkg, cpu_r);
+	snprintf(name, SOC_NAME_SIZE, "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r);
+}
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
+{
+	char name[SOC_NAME_SIZE];
+
+	get_soc_name(name);
+	printf("CPU: %s\n", name);
 
 	return 0;
 }
diff --git a/arch/arm/mach-stm32mp/fdt.c b/arch/arm/mach-stm32mp/fdt.c
index 82c430b..3ee7d6a 100644
--- a/arch/arm/mach-stm32mp/fdt.c
+++ b/arch/arm/mach-stm32mp/fdt.c
@@ -23,6 +23,12 @@
 
 #define ETZPC_RESERVED		0xffffffff
 
+#define STM32_FDCAN_BASE	0x4400e000
+#define STM32_CRYP2_BASE	0x4c005000
+#define STM32_CRYP1_BASE	0x54001000
+#define STM32_GPU_BASE		0x59000000
+#define STM32_DSI_BASE		0x5a000000
+
 static const u32 stm32mp1_ip_addr[] = {
 	0x5c008000,	/* 00 stgenc */
 	0x54000000,	/* 01 bkpsram */
@@ -33,7 +39,7 @@
 	ETZPC_RESERVED,	/* 06 reserved */
 	0x54003000,	/* 07 rng1 */
 	0x54002000,	/* 08 hash1 */
-	0x54001000,	/* 09 cryp1 */
+	STM32_CRYP1_BASE,	/* 09 cryp1 */
 	0x5a003000,	/* 0A ddrctrl */
 	0x5a004000,	/* 0B ddrphyc */
 	0x5c009000,	/* 0C i2c6 */
@@ -86,7 +92,7 @@
 	0x4400b000,	/* 3B sai2 */
 	0x4400c000,	/* 3C sai3 */
 	0x4400d000,	/* 3D dfsdm */
-	0x4400e000,	/* 3E tt_fdcan */
+	STM32_FDCAN_BASE,	/* 3E tt_fdcan */
 	ETZPC_RESERVED,	/* 3F reserved */
 	0x50021000,	/* 40 lptim2 */
 	0x50022000,	/* 41 lptim3 */
@@ -99,7 +105,7 @@
 	0x48003000,	/* 48 adc */
 	0x4c002000,	/* 49 hash2 */
 	0x4c003000,	/* 4A rng2 */
-	0x4c005000,	/* 4B cryp2 */
+	STM32_CRYP2_BASE,	/* 4B cryp2 */
 	ETZPC_RESERVED,	/* 4C reserved */
 	ETZPC_RESERVED,	/* 4D reserved */
 	ETZPC_RESERVED,	/* 4E reserved */
@@ -126,11 +132,13 @@
 static bool fdt_disable_subnode_by_address(void *fdt, int offset, u32 addr)
 {
 	int node;
+	fdt_addr_t regs;
 
 	for (node = fdt_first_subnode(fdt, offset);
 	     node >= 0;
 	     node = fdt_next_subnode(fdt, node)) {
-		if (addr == (u32)fdt_getprop(fdt, node, "reg", 0)) {
+		regs = fdtdec_get_addr(fdt, node, "reg");
+		if (addr == regs) {
 			if (fdtdec_get_is_enabled(fdt, node)) {
 				fdt_status_disabled(fdt, node);
 
@@ -143,11 +151,11 @@
 	return false;
 }
 
-static int stm32_fdt_fixup_etzpc(void *fdt)
+static int stm32_fdt_fixup_etzpc(void *fdt, int soc_node)
 {
 	const u32 *array;
 	int array_size, i;
-	int soc_node, offset, shift;
+	int offset, shift;
 	u32 addr, status, decprot[ETZPC_DECPROT_NB];
 
 	array = stm32mp1_ip_addr;
@@ -156,10 +164,6 @@
 	for (i = 0; i < ETZPC_DECPROT_NB; i++)
 		decprot[i] = readl(ETZPC_DECPROT(i));
 
-	soc_node = fdt_path_offset(fdt, "/soc");
-	if (soc_node < 0)
-		return soc_node;
-
 	for (i = 0; i < array_size; i++) {
 		offset = i / NB_PROT_PER_REG;
 		shift = (i % NB_PROT_PER_REG) * DECPROT_NB_BITS;
@@ -180,6 +184,40 @@
 	return 0;
 }
 
+/* deactivate all the cpu except core 0 */
+static void stm32_fdt_fixup_cpu(void *blob, char *name)
+{
+	int off;
+	u32 reg;
+
+	off = fdt_path_offset(blob, "/cpus");
+	if (off < 0) {
+		printf("%s: couldn't find /cpus node\n", __func__);
+		return;
+	}
+
+	off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);
+	while (off != -FDT_ERR_NOTFOUND) {
+		reg = fdtdec_get_addr(blob, off, "reg");
+		if (reg != 0) {
+			fdt_del_node(blob, off);
+			printf("FDT: cpu %d node remove for %s\n", reg, name);
+			/* after delete we can't trust the offsets anymore */
+			off = -1;
+		}
+		off = fdt_node_offset_by_prop_value(blob, off,
+						    "device_type", "cpu", 4);
+	}
+}
+
+static void stm32_fdt_disable(void *fdt, int offset, u32 addr,
+			      const char *string, const char *name)
+{
+	if (fdt_disable_subnode_by_address(fdt, offset, addr))
+		printf("FDT: %s@%08x node disabled for %s\n",
+		       string, addr, name);
+}
+
 /*
  * This function is called right before the kernel is booted. "blob" is the
  * device tree that will be passed to the kernel.
@@ -187,14 +225,59 @@
 int ft_system_setup(void *blob, bd_t *bd)
 {
 	int ret = 0;
-	u32 pkg;
+	int soc;
+	u32 pkg, cpu;
+	char name[SOC_NAME_SIZE];
+
+	soc = fdt_path_offset(blob, "/soc");
+	if (soc < 0)
+		return soc;
 
 	if (CONFIG_IS_ENABLED(STM32_ETZPC)) {
-		ret = stm32_fdt_fixup_etzpc(blob);
+		ret = stm32_fdt_fixup_etzpc(blob, soc);
 		if (ret)
 			return ret;
 	}
 
+	/* MPUs Part Numbers and name*/
+	cpu = get_cpu_type();
+	get_soc_name(name);
+
+	switch (cpu) {
+	case CPU_STM32MP151Fxx:
+	case CPU_STM32MP151Dxx:
+	case CPU_STM32MP151Cxx:
+	case CPU_STM32MP151Axx:
+		stm32_fdt_fixup_cpu(blob, name);
+		/* after cpu delete we can't trust the soc offsets anymore */
+		soc = fdt_path_offset(blob, "/soc");
+		stm32_fdt_disable(blob, soc, STM32_FDCAN_BASE, "can", name);
+		/* fall through */
+	case CPU_STM32MP153Fxx:
+	case CPU_STM32MP153Dxx:
+	case CPU_STM32MP153Cxx:
+	case CPU_STM32MP153Axx:
+		stm32_fdt_disable(blob, soc, STM32_GPU_BASE, "gpu", name);
+		stm32_fdt_disable(blob, soc, STM32_DSI_BASE, "dsi", name);
+		break;
+	default:
+		break;
+	}
+
+	switch (cpu) {
+	case CPU_STM32MP157Dxx:
+	case CPU_STM32MP157Axx:
+	case CPU_STM32MP153Dxx:
+	case CPU_STM32MP153Axx:
+	case CPU_STM32MP151Dxx:
+	case CPU_STM32MP151Axx:
+		stm32_fdt_disable(blob, soc, STM32_CRYP1_BASE, "cryp", name);
+		stm32_fdt_disable(blob, soc, STM32_CRYP2_BASE, "cryp", name);
+		break;
+	default:
+		break;
+	}
+
 	switch (get_cpu_package()) {
 	case PKG_AA_LBGA448:
 		pkg = STM32MP_PKG_AA;
diff --git a/arch/arm/mach-stm32mp/include/mach/ddr.h b/arch/arm/mach-stm32mp/include/mach/ddr.h
index b8a17cf..bfc42a7 100644
--- a/arch/arm/mach-stm32mp/include/mach/ddr.h
+++ b/arch/arm/mach-stm32mp/include/mach/ddr.h
@@ -9,8 +9,10 @@
 /* DDR power initializations */
 enum ddr_type {
 	STM32MP_DDR3,
-	STM32MP_LPDDR2,
-	STM32MP_LPDDR3,
+	STM32MP_LPDDR2_16,
+	STM32MP_LPDDR2_32,
+	STM32MP_LPDDR3_16,
+	STM32MP_LPDDR3_32,
 };
 
 int board_ddr_power_init(enum ddr_type ddr_type);
diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h
index f063600..6daf9f7 100644
--- a/arch/arm/mach-stm32mp/include/mach/stm32.h
+++ b/arch/arm/mach-stm32mp/include/mach/stm32.h
@@ -119,7 +119,14 @@
 #define STM32_BSEC_SHADOW(id)		(STM32_BSEC_SHADOW_OFFSET + (id) * 4)
 #define STM32_BSEC_OTP_OFFSET		0x80000000
 #define STM32_BSEC_OTP(id)		(STM32_BSEC_OTP_OFFSET + (id) * 4)
+#define STM32_BSEC_LOCK_OFFSET		0xC0000000
+#define STM32_BSEC_LOCK(id)		(STM32_BSEC_LOCK_OFFSET + (id) * 4)
 
+/* BSEC OTP index */
+#define BSEC_OTP_RPN	1
+#define BSEC_OTP_SERIAL	13
+#define BSEC_OTP_PKG	16
+#define BSEC_OTP_MAC	57
 #define BSEC_OTP_BOARD	59
 
 #endif /* __ASSEMBLY__*/
diff --git a/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h b/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h
index 8130546..4ad14f9 100644
--- a/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h
+++ b/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h
@@ -27,6 +27,7 @@
 #define STM32_SMC_READ_OTP		0x04
 #define STM32_SMC_READ_ALL		0x05
 #define STM32_SMC_WRITE_ALL		0x06
+#define STM32_SMC_WRLOCK_OTP		0x07
 
 /* SMC error codes */
 #define STM32_SMC_OK			0x0
@@ -45,8 +46,8 @@
 	arm_smccc_smc(svc, op, data1, data2, 0, 0, 0, 0, &res);
 
 	if (res.a0) {
-		pr_err("%s: Failed to exec in secure mode (err = %ld)\n",
-		       __func__, res.a0);
+		pr_err("%s: Failed to exec svc=%x op=%x in secure mode (err = %ld)\n",
+		       __func__, svc, op, res.a0);
 		return -EINVAL;
 	}
 	if (result)
diff --git a/arch/arm/mach-stm32mp/include/mach/sys_proto.h b/arch/arm/mach-stm32mp/include/mach/sys_proto.h
index da46c11..1617126 100644
--- a/arch/arm/mach-stm32mp/include/mach/sys_proto.h
+++ b/arch/arm/mach-stm32mp/include/mach/sys_proto.h
@@ -3,13 +3,19 @@
  * Copyright (C) 2015-2017, STMicroelectronics - All Rights Reserved
  */
 
-/* ID = Device Version (bit31:16) + Device Part Number (RPN) (bit15:0)*/
+/* ID = Device Version (bit31:16) + Device Part Number (RPN) (bit7:0) */
 #define CPU_STM32MP157Cxx	0x05000000
 #define CPU_STM32MP157Axx	0x05000001
 #define CPU_STM32MP153Cxx	0x05000024
 #define CPU_STM32MP153Axx	0x05000025
 #define CPU_STM32MP151Cxx	0x0500002E
 #define CPU_STM32MP151Axx	0x0500002F
+#define CPU_STM32MP157Fxx	0x05000080
+#define CPU_STM32MP157Dxx	0x05000081
+#define CPU_STM32MP153Fxx	0x050000A4
+#define CPU_STM32MP153Dxx	0x050000A5
+#define CPU_STM32MP151Fxx	0x050000AE
+#define CPU_STM32MP151Dxx	0x050000AF
 
 /* return CPU_STMP32MP...Xxx constants */
 u32 get_cpu_type(void);
@@ -29,6 +35,10 @@
 #define PKG_AC_TFBGA361	2
 #define PKG_AD_TFBGA257	1
 
+/* Get SOC name */
+#define SOC_NAME_SIZE 20
+void get_soc_name(char name[SOC_NAME_SIZE]);
+
 /* return boot mode */
 u32 get_bootmode(void);
 
diff --git a/arch/arm/mach-stm32mp/psci.c b/arch/arm/mach-stm32mp/psci.c
index 1d91b2d..3fb038d 100644
--- a/arch/arm/mach-stm32mp/psci.c
+++ b/arch/arm/mach-stm32mp/psci.c
@@ -30,6 +30,22 @@
 	 PSCI_AFFINITY_LEVEL_ON,
 	 PSCI_AFFINITY_LEVEL_OFF};
 
+static u32 __secure_data cntfrq;
+
+static u32 __secure cp15_read_cntfrq(void)
+{
+	u32 frq;
+
+	asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (frq));
+
+	return frq;
+}
+
+static void __secure cp15_write_cntfrq(u32 frq)
+{
+	asm volatile ("mcr p15, 0, %0, c14, c0, 0" : : "r" (frq));
+}
+
 static inline void psci_set_state(int cpu, u8 state)
 {
 	psci_state[cpu] = state;
@@ -63,6 +79,9 @@
 
 	psci_set_state(cpu, PSCI_AFFINITY_LEVEL_ON);
 
+	/* write the saved cntfrq */
+	cp15_write_cntfrq(cntfrq);
+
 	/* reset magic in TAMP register */
 	writel(0xFFFFFFFF, TAMP_BACKUP_MAGIC_NUMBER);
 }
@@ -130,6 +149,9 @@
 	if (psci_state[cpu] == PSCI_AFFINITY_LEVEL_ON)
 		return ARM_PSCI_RET_ALREADY_ON;
 
+	/* read and save cntfrq of current cpu to write on target cpu  */
+	cntfrq = cp15_read_cntfrq();
+
 	/* reset magic in TAMP register */
 	if (readl(TAMP_BACKUP_MAGIC_NUMBER))
 		writel(0xFFFFFFFF, TAMP_BACKUP_MAGIC_NUMBER);
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 5ce8261..2bd260e 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -30,7 +30,4 @@
 
 source "board/xilinx/microblaze-generic/Kconfig"
 
-config SPL_LDSCRIPT
-	default "arch/microblaze/cpu/u-boot-spl.lds"
-
 endmenu
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index cc87da7..3061bf8 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -242,7 +242,4 @@
 	int
 	default 14
 
-config SPL_LDSCRIPT
-	default "arch/riscv/cpu/u-boot-spl.lds"
-
 endmenu
diff --git a/board/BuR/common/br_resetc.c b/board/BuR/common/br_resetc.c
index c0e7fb6..70ad832 100644
--- a/board/BuR/common/br_resetc.c
+++ b/board/BuR/common/br_resetc.c
@@ -22,7 +22,7 @@
 #define BMODE_PME		12
 #define BMODE_DIAG		15
 
-#ifdef CONFIG_LCD
+#if CONFIG_IS_ENABLED(LCD) && !CONFIG_IS_ENABLED(DM_VIDEO)
 #include <lcd.h>
 #define LCD_SETCURSOR(x, y)	lcd_position_cursor(x, y)
 #define LCD_PUTS(x)		lcd_puts(x)
diff --git a/board/BuR/common/bur_common.h b/board/BuR/common/bur_common.h
index 2591bf4..618cebc 100644
--- a/board/BuR/common/bur_common.h
+++ b/board/BuR/common/bur_common.h
@@ -11,9 +11,12 @@
 #ifndef _BUR_COMMON_H_
 #define _BUR_COMMON_H_
 
+#if !CONFIG_IS_ENABLED(DM_VIDEO)
 #include <../../../drivers/video/am335x-fb.h>
 
 int load_lcdtiming(struct am335x_lcdpanel *panel);
+#endif
+
 void br_summaryscreen(void);
 void pmicsetup(u32 mpupll, unsigned int bus);
 void enable_uart0_pin_mux(void);
diff --git a/board/BuR/common/common.c b/board/BuR/common/common.c
index 148fc90..de8d455 100644
--- a/board/BuR/common/common.c
+++ b/board/BuR/common/common.c
@@ -20,7 +20,7 @@
 
 /* --------------------------------------------------------------------------*/
 #if defined(CONFIG_LCD) && defined(CONFIG_AM335X_LCD) && \
-	!defined(CONFIG_SPL_BUILD)
+	!defined(CONFIG_DM_VIDEO) && !defined(CONFIG_SPL_BUILD)
 #include <asm/arch/hardware.h>
 #include <asm/arch/cpu.h>
 #include <asm/gpio.h>
diff --git a/board/armadeus/apf27/Kconfig b/board/armadeus/apf27/Kconfig
index a342d2e..65544a8 100644
--- a/board/armadeus/apf27/Kconfig
+++ b/board/armadeus/apf27/Kconfig
@@ -1,8 +1,5 @@
 if TARGET_APF27
 
-config SPL_LDSCRIPT
-	default "arch/$(ARCH)/cpu/u-boot-spl.lds"
-
 config SYS_BOARD
 	default "apf27"
 
diff --git a/board/freescale/mx31pdk/Kconfig b/board/freescale/mx31pdk/Kconfig
index b9fc2d5..055545c 100644
--- a/board/freescale/mx31pdk/Kconfig
+++ b/board/freescale/mx31pdk/Kconfig
@@ -1,8 +1,5 @@
 if TARGET_MX31PDK
 
-config SPL_LDSCRIPT
-	default "arch/$(ARCH)/cpu/u-boot-spl.lds"
-
 config SYS_BOARD
 	default "mx31pdk"
 
diff --git a/board/st/common/cmd_stboard.c b/board/st/common/cmd_stboard.c
index e994a88..915164a 100644
--- a/board/st/common/cmd_stboard.c
+++ b/board/st/common/cmd_stboard.c
@@ -1,6 +1,32 @@
 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
 /*
  * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * the st command stboard supports the STMicroelectronics board identification
+ * saved in OTP 59.
+ *
+ * The ST product codification have several element
+ * - "Commercial Product Name" (CPN): type of product board (DKX, EVX)
+ *   associated to the board ID "MBxxxx"
+ * - "Finished Good" or "Finish Good" (FG):
+ *   effective content of the product without chip STM32MP1xx (LCD, Wifi,…)
+ * - BOM: cost variant for same FG (for example, several provider of the same
+ *   component)
+ *
+ * For example
+ * - commercial product = STM32MP157C-EV1 for board MB1263
+ * - Finished Good = EVA32MP157A1$AU1
+ *
+ * Both information are written on board and these information are also saved
+ * in OTP59, with:
+ * bit [31:16] (hex) => Board id, MBxxxx
+ * bit [15:12] (dec) => Variant CPN (1....15)
+ * bit [11:8]  (dec) => Revision board (index with A = 1, Z = 26)
+ * bit [7:4]   (dec) => Variant FG : finished good index
+ * bit [3:0]   (dec) => BOM (01, .... 255)
+ *
+ * and displayed with the format:
+ *   Board: MB<Board> Var<VarCPN>.<VarFG> Rev.<Revision>-<BOM>
  */
 
 #ifndef CONFIG_SPL_BUILD
@@ -13,6 +39,7 @@
 static bool check_stboard(u16 board)
 {
 	unsigned int i;
+	/* list of supported ST boards */
 	const u16 st_board_id[] = {
 		0x1272,
 		0x1263,
@@ -31,9 +58,11 @@
 
 static void display_stboard(u32 otp)
 {
-	printf("Board: MB%04x Var%d Rev.%c-%02d\n",
+	/* display board indentification with OPT coding */
+	printf("Board: MB%04x Var%d.%d Rev.%c-%02d\n",
 	       otp >> 16,
 	       (otp >> 12) & 0xF,
+	       (otp >> 4) & 0xF,
 	       ((otp >> 8) & 0xF) - 1 + 'A',
 	       otp & 0xF);
 }
@@ -42,23 +71,23 @@
 		      char * const argv[])
 {
 	int ret;
-	u32 otp;
+	u32 otp, lock;
 	u8 revision;
-	unsigned long board, variant, bom;
+	unsigned long board, var_cpn, var_fg, bom;
 	struct udevice *dev;
-	int confirmed = argc == 6 && !strcmp(argv[1], "-y");
+	int confirmed = argc == 7 && !strcmp(argv[1], "-y");
 
 	argc -= 1 + confirmed;
 	argv += 1 + confirmed;
 
-	if (argc != 0 && argc != 4)
+	if (argc != 0 && argc != 5)
 		return CMD_RET_USAGE;
 
 	ret = uclass_get_device_by_driver(UCLASS_MISC,
 					  DM_GET_DRIVER(stm32mp_bsec),
 					  &dev);
 
-	ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD),
+	ret = misc_read(dev, STM32_BSEC_OTP(BSEC_OTP_BOARD),
 			&otp, sizeof(otp));
 
 	if (ret < 0) {
@@ -66,11 +95,20 @@
 		return CMD_RET_FAILURE;
 	}
 
+	ret = misc_read(dev, STM32_BSEC_LOCK(BSEC_OTP_BOARD),
+			&lock, sizeof(lock));
+	if (ret < 0) {
+		puts("LOCK read error");
+		return CMD_RET_FAILURE;
+	}
+
 	if (argc == 0) {
 		if (!otp)
 			puts("Board : OTP board FREE\n");
 		else
 			display_stboard(otp);
+		printf("      OTP %d %s locked !\n", BSEC_OTP_BOARD,
+		       lock == 1 ? "" : "NOT");
 		return CMD_RET_SUCCESS;
 	}
 
@@ -86,8 +124,8 @@
 		return CMD_RET_USAGE;
 	}
 
-	if (strict_strtoul(argv[1], 10, &variant) < 0 ||
-	    variant == 0 || variant > 15) {
+	if (strict_strtoul(argv[1], 10, &var_cpn) < 0 ||
+	    var_cpn == 0 || var_cpn > 15) {
 		printf("argument %d invalid: %s\n", 2, argv[1]);
 		return CMD_RET_USAGE;
 	}
@@ -98,13 +136,21 @@
 		return CMD_RET_USAGE;
 	}
 
-	if (strict_strtoul(argv[3], 10, &bom) < 0 ||
+	if (strict_strtoul(argv[3], 10, &var_fg) < 0 ||
+	    var_fg > 15) {
+		printf("argument %d invalid: %s\n", 4, argv[3]);
+		return CMD_RET_USAGE;
+	}
+
+	if (strict_strtoul(argv[4], 10, &bom) < 0 ||
 	    bom == 0 || bom > 15) {
 		printf("argument %d invalid: %s\n", 4, argv[3]);
 		return CMD_RET_USAGE;
 	}
 
-	otp = (board << 16) | (variant << 12) | (revision << 8) | bom;
+	/* st board indentification value */
+	otp = (board << 16) | (var_cpn << 12) | (revision << 8) |
+	      (var_fg << 4) | bom;
 	display_stboard(otp);
 	printf("=> OTP[%d] = %08X\n", BSEC_OTP_BOARD, otp);
 
@@ -125,24 +171,35 @@
 	ret = misc_write(dev, STM32_BSEC_OTP(BSEC_OTP_BOARD),
 			 &otp, sizeof(otp));
 
-	if (ret) {
+	if (ret < 0) {
 		puts("BOARD programming error\n");
 		return CMD_RET_FAILURE;
 	}
+
+	/* write persistent lock */
+	otp = 1;
+	ret = misc_write(dev, STM32_BSEC_LOCK(BSEC_OTP_BOARD),
+			 &otp, sizeof(otp));
+	if (ret < 0) {
+		puts("BOARD lock error\n");
+		return CMD_RET_FAILURE;
+	}
+
 	puts("BOARD programming done\n");
 
 	return CMD_RET_SUCCESS;
 }
 
-U_BOOT_CMD(stboard, 6, 0, do_stboard,
+U_BOOT_CMD(stboard, 7, 0, do_stboard,
 	   "read/write board reference in OTP",
 	   "\n"
 	   "  Print current board information\n"
-	   "stboard [-y] <Board> <Variant> <Revision> <BOM>\n"
+	   "stboard [-y] <Board> <VarCPN> <Revision> <VarFG> <BOM>\n"
 	   "  Write board information\n"
 	   "  - Board: xxxx, example 1264 for MB1264\n"
-	   "  - Variant: 1 ... 15\n"
+	   "  - VarCPN: 1...15\n"
 	   "  - Revision: A...O\n"
+	   "  - VarFG: 0...15\n"
 	   "  - BOM: 1...15\n");
 
 #endif
diff --git a/board/st/stm32mp1/board.c b/board/st/stm32mp1/board.c
index c3d832f..4e35d36 100644
--- a/board/st/stm32mp1/board.c
+++ b/board/st/stm32mp1/board.c
@@ -43,6 +43,7 @@
 	struct udevice *dev;
 	bool buck3_at_1800000v = false;
 	int ret;
+	u32 buck2;
 
 	ret = uclass_get_device_by_driver(UCLASS_PMIC,
 					  DM_GET_DRIVER(pmic_stpmic1), &dev);
@@ -102,8 +103,10 @@
 
 		break;
 
-	case STM32MP_LPDDR2:
-	case STM32MP_LPDDR3:
+	case STM32MP_LPDDR2_16:
+	case STM32MP_LPDDR2_32:
+	case STM32MP_LPDDR3_16:
+	case STM32MP_LPDDR3_32:
 		/*
 		 * configure VDD_DDR1 = LDO3
 		 * Set LDO3 to 1.8V
@@ -133,11 +136,23 @@
 		if (ret < 0)
 			return ret;
 
-		/* VDD_DDR2 : Set BUCK2 to 1.2V */
+		/* VDD_DDR2 : Set BUCK2 to 1.2V (16bits) or 1.25V (32 bits)*/
+		switch (ddr_type) {
+		case STM32MP_LPDDR2_32:
+		case STM32MP_LPDDR3_32:
+			buck2 = STPMIC1_BUCK2_1250000V;
+			break;
+		default:
+		case STM32MP_LPDDR2_16:
+		case STM32MP_LPDDR3_16:
+			buck2 = STPMIC1_BUCK2_1200000V;
+			break;
+		}
+
 		ret = pmic_clrsetbits(dev,
 				      STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
 				      STPMIC1_BUCK_VOUT_MASK,
-				      STPMIC1_BUCK2_1200000V);
+				      buck2);
 		if (ret < 0)
 			return ret;
 
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index c36e765..07f5344 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -104,19 +104,21 @@
 		printf(" (%s)", fdt_compat);
 	puts("\n");
 
-	ret = uclass_get_device_by_driver(UCLASS_MISC,
-					  DM_GET_DRIVER(stm32mp_bsec),
-					  &dev);
-
-	if (!ret)
-		ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD),
-				&otp, sizeof(otp));
-	if (ret > 0 && otp) {
-		printf("Board: MB%04x Var%d Rev.%c-%02d\n",
-		       otp >> 16,
-		       (otp >> 12) & 0xF,
-		       ((otp >> 8) & 0xF) - 1 + 'A',
-		       otp & 0xF);
+	/* display the STMicroelectronics board identification */
+	if (CONFIG_IS_ENABLED(CMD_STBOARD)) {
+		ret = uclass_get_device_by_driver(UCLASS_MISC,
+						  DM_GET_DRIVER(stm32mp_bsec),
+						  &dev);
+		if (!ret)
+			ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD),
+					&otp, sizeof(otp));
+		if (ret > 0 && otp)
+			printf("Board: MB%04x Var%d.%d Rev.%c-%02d\n",
+			       otp >> 16,
+			       (otp >> 12) & 0xF,
+			       (otp >> 4) & 0xF,
+			       ((otp >> 8) & 0xF) - 1 + 'A',
+			       otp & 0xF);
 	}
 
 	return 0;
diff --git a/board/ti/am65x/README b/board/ti/am65x/README
index 2e3fd9c..00be1ff 100644
--- a/board/ti/am65x/README
+++ b/board/ti/am65x/README
@@ -104,7 +104,7 @@
 Sources:
 --------
 1. SYSFW:
-	Tree: git://git.ti.com/processor-firmware/system-firmware-image-gen.git
+	Tree: git://git.ti.com/k3-image-gen/k3-image-gen.git
 	Branch: master
 
 2. ATF:
@@ -138,7 +138,7 @@
 
 4.2. A53:
 $ make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- am65x_evm_a53_defconfig O=/tmp/a53
-$ make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- ATF=<path to ATF dir>/build/k3/generic/release/bl31.bin TEE=<path to OPTEE OS dir>/out/arm-plat-k3/core/tee-pager.bin O=/tmp/a53
+$ make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- ATF=<path to ATF dir>/build/k3/generic/release/bl31.bin TEE=<path to OPTEE OS dir>/out/arm-plat-k3/core/tee-pager_v2.bin O=/tmp/a53
 
 Target Images
 --------------
@@ -262,6 +262,61 @@
 => setenv bootpart 0
 => boot
 
+OSPI:
+-----
+ROM supports booting from OSPI from offset 0x0.
+
+Flashing images to OSPI:
+
+Below commands can be used to download tiboot3.bin, tispl.bin, u-boot.img,
+and sysfw.itb over tftp and then flash those to OSPI at their respective
+addresses.
+
+=> sf probe
+=> tftp ${loadaddr} tiboot3.bin
+=> sf update $loadaddr 0x0 $filesize
+=> tftp ${loadaddr} tispl.bin
+=> sf update $loadaddr 0x80000 $filesize
+=> tftp ${loadaddr} u-boot.img
+=> sf update $loadaddr 0x280000 $filesize
+=> tftp ${loadaddr} sysfw.itb
+=> sf update $loadaddr 0x6C0000 $filesize
+
+Flash layout for OSPI:
+
+         0x0 +----------------------------+
+             |     ospi.tiboot3(512K)     |
+             |                            |
+     0x80000 +----------------------------+
+             |     ospi.tispl(2M)         |
+             |                            |
+    0x280000 +----------------------------+
+             |     ospi.u-boot(4M)        |
+             |                            |
+    0x680000 +----------------------------+
+             |     ospi.env(128K)         |
+             |                            |
+    0x6A0000 +----------------------------+
+	     |	 ospi.env.backup (128K)   |
+	     |                            |
+    0x6C0000 +----------------------------+
+             |      ospi.sysfw(1M)        |
+             |                            |
+    0x7C0000 +----------------------------+
+	     |      padding (256k)        |
+    0x800000 +----------------------------+
+             |     ospi.rootfs(UBIFS)     |
+             |                            |
+             +----------------------------+
+
+Kernel Image and DT are expected to be present in the /boot folder of UBIFS
+ospi.rootfs just like in SD card case. U-Boot looks for UBI volume named
+"rootfs" for rootfs.
+
+To boot kernel from OSPI, at the U-Boot prompt:
+=> setenv boot ubi
+=> boot
+
 UART:
 -----
 ROM supports booting from MCU_UART0 via X-Modem protocol. The entire UART-based
diff --git a/board/ti/j721e/README b/board/ti/j721e/README
index 5be7d09..7dcf336 100644
--- a/board/ti/j721e/README
+++ b/board/ti/j721e/README
@@ -120,7 +120,7 @@
 Sources:
 --------
 1. SYSFW:
-	Tree: git://git.ti.com/processor-firmware/system-firmware-image-gen.git
+	Tree: git://git.ti.com/k3-image-gen/k3-image-gen.git
 	Branch: master
 
 2. ATF:
@@ -154,7 +154,7 @@
 
 4.2. A72:
 $ make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- j721e_evm_a72_defconfig O=/tmp/a72
-$ make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- ATF=<path to ATF dir>/build/k3/generic/release/bl31.bin TEE=<path to OPTEE OS dir>/out/arm-plat-k3/core/tee-pager.bin O=/tmp/a72
+$ make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- ATF=<path to ATF dir>/build/k3/generic/release/bl31.bin TEE=<path to OPTEE OS dir>/out/arm-plat-k3/core/tee-pager_v2.bin O=/tmp/a72
 
 Target Images
 --------------
@@ -225,3 +225,50 @@
                 | |    Secure config  | |
                 | +-------------------+ |
                 +-----------------------+
+
+OSPI:
+-----
+ROM supports booting from OSPI from offset 0x0.
+
+Flashing images to OSPI:
+
+Below commands can be used to download tiboot3.bin, tispl.bin, u-boot.img,
+and sysfw.itb over tftp and then flash those to OSPI at their respective
+addresses.
+
+=> sf probe
+=> tftp ${loadaddr} tiboot3.bin
+=> sf update $loadaddr 0x0 $filesize
+=> tftp ${loadaddr} tispl.bin
+=> sf update $loadaddr 0x80000 $filesize
+=> tftp ${loadaddr} u-boot.img
+=> sf update $loadaddr 0x280000 $filesize
+=> tftp ${loadaddr} sysfw.itb
+=> sf update $loadaddr 0x6C0000 $filesize
+
+Flash layout for OSPI:
+
+         0x0 +----------------------------+
+             |     ospi.tiboot3(512K)     |
+             |                            |
+     0x80000 +----------------------------+
+             |     ospi.tispl(2M)         |
+             |                            |
+    0x280000 +----------------------------+
+             |     ospi.u-boot(4M)        |
+             |                            |
+    0x680000 +----------------------------+
+             |     ospi.env(128K)         |
+             |                            |
+    0x6A0000 +----------------------------+
+	     |	 ospi.env.backup (128K)   |
+	     |                            |
+    0x6C0000 +----------------------------+
+             |      ospi.sysfw(1M)        |
+             |                            |
+    0x7C0000 +----------------------------+
+	     |      padding (256k)        |
+    0x800000 +----------------------------+
+             |     ospi.rootfs(UBIFS)     |
+             |                            |
+             +----------------------------+
diff --git a/board/ti/j721e/evm.c b/board/ti/j721e/evm.c
index aa2240b..c068bb8 100644
--- a/board/ti/j721e/evm.c
+++ b/board/ti/j721e/evm.c
@@ -15,6 +15,8 @@
 #include <asm/io.h>
 #include <spl.h>
 #include <asm/arch/sys_proto.h>
+#include <dm.h>
+#include <dm/uclass-internal.h>
 
 #include "../common/board_detect.h"
 
@@ -343,5 +345,29 @@
 
 void spl_board_init(void)
 {
+#if defined(CONFIG_ESM_K3) || defined(CONFIG_ESM_PMIC)
+	struct udevice *dev;
+	int ret;
+#endif
+
 	probe_daughtercards();
+
+#ifdef CONFIG_ESM_K3
+	if (board_ti_k3_is("J721EX-PM2-SOM")) {
+		ret = uclass_get_device_by_driver(UCLASS_MISC,
+						  DM_GET_DRIVER(k3_esm), &dev);
+		if (ret)
+			printf("ESM init failed: %d\n", ret);
+	}
+#endif
+
+#ifdef CONFIG_ESM_PMIC
+	if (board_ti_k3_is("J721EX-PM2-SOM")) {
+		ret = uclass_get_device_by_driver(UCLASS_MISC,
+						  DM_GET_DRIVER(pmic_esm),
+						  &dev);
+		if (ret)
+			printf("ESM PMIC init failed: %d\n", ret);
+	}
+#endif
 }
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 6403bc4..faa133d 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -399,6 +399,7 @@
 config CMD_ELF
 	bool "bootelf, bootvx"
 	default y
+	select LIB_ELF
 	help
 	  Boot an ELF/vxWorks image from the memory.
 
diff --git a/cmd/elf.c b/cmd/elf.c
index 036be5f..10e8264 100644
--- a/cmd/elf.c
+++ b/cmd/elf.c
@@ -18,211 +18,6 @@
 #include <linux/linkage.h>
 #endif
 
-/*
- * A very simple ELF64 loader, assumes the image is valid, returns the
- * entry point address.
- *
- * Note if U-Boot is 32-bit, the loader assumes the to segment's
- * physical address and size is within the lower 32-bit address space.
- */
-static unsigned long load_elf64_image_phdr(unsigned long addr)
-{
-	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
-	Elf64_Phdr *phdr; /* Program header structure pointer */
-	int i;
-
-	ehdr = (Elf64_Ehdr *)addr;
-	phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
-
-	/* Load each program header */
-	for (i = 0; i < ehdr->e_phnum; ++i) {
-		void *dst = (void *)(ulong)phdr->p_paddr;
-		void *src = (void *)addr + phdr->p_offset;
-
-		debug("Loading phdr %i to 0x%p (%lu bytes)\n",
-		      i, dst, (ulong)phdr->p_filesz);
-		if (phdr->p_filesz)
-			memcpy(dst, src, phdr->p_filesz);
-		if (phdr->p_filesz != phdr->p_memsz)
-			memset(dst + phdr->p_filesz, 0x00,
-			       phdr->p_memsz - phdr->p_filesz);
-		flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
-			    roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
-		++phdr;
-	}
-
-	if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
-					    EF_PPC64_ELFV1_ABI)) {
-		/*
-		 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
-		 * descriptor pointer with the first double word being the
-		 * address of the entry point of the function.
-		 */
-		uintptr_t addr = ehdr->e_entry;
-
-		return *(Elf64_Addr *)addr;
-	}
-
-	return ehdr->e_entry;
-}
-
-static unsigned long load_elf64_image_shdr(unsigned long addr)
-{
-	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
-	Elf64_Shdr *shdr; /* Section header structure pointer */
-	unsigned char *strtab = 0; /* String table pointer */
-	unsigned char *image; /* Binary image pointer */
-	int i; /* Loop counter */
-
-	ehdr = (Elf64_Ehdr *)addr;
-
-	/* Find the section header string table for output info */
-	shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
-			     (ehdr->e_shstrndx * sizeof(Elf64_Shdr)));
-
-	if (shdr->sh_type == SHT_STRTAB)
-		strtab = (unsigned char *)(addr + (ulong)shdr->sh_offset);
-
-	/* Load each appropriate section */
-	for (i = 0; i < ehdr->e_shnum; ++i) {
-		shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
-				     (i * sizeof(Elf64_Shdr)));
-
-		if (!(shdr->sh_flags & SHF_ALLOC) ||
-		    shdr->sh_addr == 0 || shdr->sh_size == 0) {
-			continue;
-		}
-
-		if (strtab) {
-			debug("%sing %s @ 0x%08lx (%ld bytes)\n",
-			      (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
-			       &strtab[shdr->sh_name],
-			       (unsigned long)shdr->sh_addr,
-			       (long)shdr->sh_size);
-		}
-
-		if (shdr->sh_type == SHT_NOBITS) {
-			memset((void *)(uintptr_t)shdr->sh_addr, 0,
-			       shdr->sh_size);
-		} else {
-			image = (unsigned char *)addr + (ulong)shdr->sh_offset;
-			memcpy((void *)(uintptr_t)shdr->sh_addr,
-			       (const void *)image, shdr->sh_size);
-		}
-		flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
-			    roundup((shdr->sh_addr + shdr->sh_size),
-				     ARCH_DMA_MINALIGN) -
-			            rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
-	}
-
-	if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
-					    EF_PPC64_ELFV1_ABI)) {
-		/*
-		 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
-		 * descriptor pointer with the first double word being the
-		 * address of the entry point of the function.
-		 */
-		uintptr_t addr = ehdr->e_entry;
-
-		return *(Elf64_Addr *)addr;
-	}
-
-	return ehdr->e_entry;
-}
-
-/*
- * A very simple ELF loader, assumes the image is valid, returns the
- * entry point address.
- *
- * The loader firstly reads the EFI class to see if it's a 64-bit image.
- * If yes, call the ELF64 loader. Otherwise continue with the ELF32 loader.
- */
-static unsigned long load_elf_image_phdr(unsigned long addr)
-{
-	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
-	Elf32_Phdr *phdr; /* Program header structure pointer */
-	int i;
-
-	ehdr = (Elf32_Ehdr *)addr;
-	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
-		return load_elf64_image_phdr(addr);
-
-	phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
-
-	/* Load each program header */
-	for (i = 0; i < ehdr->e_phnum; ++i) {
-		void *dst = (void *)(uintptr_t)phdr->p_paddr;
-		void *src = (void *)addr + phdr->p_offset;
-
-		debug("Loading phdr %i to 0x%p (%i bytes)\n",
-		      i, dst, phdr->p_filesz);
-		if (phdr->p_filesz)
-			memcpy(dst, src, phdr->p_filesz);
-		if (phdr->p_filesz != phdr->p_memsz)
-			memset(dst + phdr->p_filesz, 0x00,
-			       phdr->p_memsz - phdr->p_filesz);
-		flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
-			    roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
-		++phdr;
-	}
-
-	return ehdr->e_entry;
-}
-
-static unsigned long load_elf_image_shdr(unsigned long addr)
-{
-	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
-	Elf32_Shdr *shdr; /* Section header structure pointer */
-	unsigned char *strtab = 0; /* String table pointer */
-	unsigned char *image; /* Binary image pointer */
-	int i; /* Loop counter */
-
-	ehdr = (Elf32_Ehdr *)addr;
-	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
-		return load_elf64_image_shdr(addr);
-
-	/* Find the section header string table for output info */
-	shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
-			     (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
-
-	if (shdr->sh_type == SHT_STRTAB)
-		strtab = (unsigned char *)(addr + shdr->sh_offset);
-
-	/* Load each appropriate section */
-	for (i = 0; i < ehdr->e_shnum; ++i) {
-		shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
-				     (i * sizeof(Elf32_Shdr)));
-
-		if (!(shdr->sh_flags & SHF_ALLOC) ||
-		    shdr->sh_addr == 0 || shdr->sh_size == 0) {
-			continue;
-		}
-
-		if (strtab) {
-			debug("%sing %s @ 0x%08lx (%ld bytes)\n",
-			      (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
-			       &strtab[shdr->sh_name],
-			       (unsigned long)shdr->sh_addr,
-			       (long)shdr->sh_size);
-		}
-
-		if (shdr->sh_type == SHT_NOBITS) {
-			memset((void *)(uintptr_t)shdr->sh_addr, 0,
-			       shdr->sh_size);
-		} else {
-			image = (unsigned char *)addr + shdr->sh_offset;
-			memcpy((void *)(uintptr_t)shdr->sh_addr,
-			       (const void *)image, shdr->sh_size);
-		}
-		flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
-			    roundup((shdr->sh_addr + shdr->sh_size),
-				    ARCH_DMA_MINALIGN) -
-			    rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
-	}
-
-	return ehdr->e_entry;
-}
-
 /* Allow ports to override the default behavior */
 static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
 				     int argc, char * const argv[])
@@ -238,30 +33,6 @@
 	return ret;
 }
 
-/*
- * Determine if a valid ELF image exists at the given memory location.
- * First look at the ELF header magic field, then make sure that it is
- * executable.
- */
-int valid_elf_image(unsigned long addr)
-{
-	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
-
-	ehdr = (Elf32_Ehdr *)addr;
-
-	if (!IS_ELF(*ehdr)) {
-		printf("## No elf image at address 0x%08lx\n", addr);
-		return 0;
-	}
-
-	if (ehdr->e_type != ET_EXEC) {
-		printf("## Not a 32-bit elf image at address 0x%08lx\n", addr);
-		return 0;
-	}
-
-	return 1;
-}
-
 /* Interpreter command to boot an arbitrary ELF image from memory */
 int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
diff --git a/common/Kconfig b/common/Kconfig
index bd35de3..3072651 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -1046,3 +1046,10 @@
 endmenu
 
 source "common/spl/Kconfig"
+
+config IMAGE_SIGN_INFO
+	bool
+	select SHA1
+	select SHA256
+	help
+	  Enable image_sign_info helper functions.
diff --git a/common/Makefile b/common/Makefile
index 896e4af..702f239 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -112,7 +112,8 @@
 obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o
 obj-$(CONFIG_$(SPL_TPL_)FIT) += image-fit.o
 obj-$(CONFIG_$(SPL_)MULTI_DTB_FIT) += boot_fit.o common_fit.o
-obj-$(CONFIG_$(SPL_TPL_)FIT_SIGNATURE) += image-sig.o
+obj-$(CONFIG_IMAGE_SIGN_INFO) += image-sig.o
+obj-$(CONFIG_$(SPL_TPL_)FIT_SIGNATURE) += image-fit-sig.o
 obj-$(CONFIG_$(SPL_TPL_)FIT_CIPHER) += image-cipher.o
 obj-$(CONFIG_IO_TRACE) += iotrace.o
 obj-y += memsize.o
diff --git a/common/image-fit-sig.c b/common/image-fit-sig.c
new file mode 100644
index 0000000..490566c
--- /dev/null
+++ b/common/image-fit-sig.c
@@ -0,0 +1,450 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2013, Google Inc.
+ */
+
+#ifdef USE_HOSTCC
+#include "mkimage.h"
+#include <time.h>
+#else
+#include <common.h>
+#include <malloc.h>
+DECLARE_GLOBAL_DATA_PTR;
+#endif /* !USE_HOSTCC*/
+#include <image.h>
+#include <u-boot/rsa.h>
+#include <u-boot/rsa-checksum.h>
+
+#define IMAGE_MAX_HASHED_NODES		100
+
+#ifdef USE_HOSTCC
+void *host_blob;
+
+void image_set_host_blob(void *blob)
+{
+	host_blob = blob;
+}
+
+void *image_get_host_blob(void)
+{
+	return host_blob;
+}
+#endif
+
+/**
+ * fit_region_make_list() - Make a list of image regions
+ *
+ * Given a list of fdt_regions, create a list of image_regions. This is a
+ * simple conversion routine since the FDT and image code use different
+ * structures.
+ *
+ * @fit: FIT image
+ * @fdt_regions: Pointer to FDT regions
+ * @count: Number of FDT regions
+ * @region: Pointer to image regions, which must hold @count records. If
+ * region is NULL, then (except for an SPL build) the array will be
+ * allocated.
+ * @return: Pointer to image regions
+ */
+struct image_region *fit_region_make_list(const void *fit,
+					  struct fdt_region *fdt_regions,
+					  int count,
+					  struct image_region *region)
+{
+	int i;
+
+	debug("Hash regions:\n");
+	debug("%10s %10s\n", "Offset", "Size");
+
+	/*
+	 * Use malloc() except in SPL (to save code size). In SPL the caller
+	 * must allocate the array.
+	 */
+#ifndef CONFIG_SPL_BUILD
+	if (!region)
+		region = calloc(sizeof(*region), count);
+#endif
+	if (!region)
+		return NULL;
+	for (i = 0; i < count; i++) {
+		debug("%10x %10x\n", fdt_regions[i].offset,
+		      fdt_regions[i].size);
+		region[i].data = fit + fdt_regions[i].offset;
+		region[i].size = fdt_regions[i].size;
+	}
+
+	return region;
+}
+
+static int fit_image_setup_verify(struct image_sign_info *info,
+				  const void *fit, int noffset,
+				  int required_keynode, char **err_msgp)
+{
+	char *algo_name;
+	const char *padding_name;
+
+	if (fdt_totalsize(fit) > CONFIG_FIT_SIGNATURE_MAX_SIZE) {
+		*err_msgp = "Total size too large";
+		return 1;
+	}
+
+	if (fit_image_hash_get_algo(fit, noffset, &algo_name)) {
+		*err_msgp = "Can't get hash algo property";
+		return -1;
+	}
+
+	padding_name = fdt_getprop(fit, noffset, "padding", NULL);
+	if (!padding_name)
+		padding_name = RSA_DEFAULT_PADDING_NAME;
+
+	memset(info, '\0', sizeof(*info));
+	info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
+	info->fit = (void *)fit;
+	info->node_offset = noffset;
+	info->name = algo_name;
+	info->checksum = image_get_checksum_algo(algo_name);
+	info->crypto = image_get_crypto_algo(algo_name);
+	info->padding = image_get_padding_algo(padding_name);
+	info->fdt_blob = gd_fdt_blob();
+	info->required_keynode = required_keynode;
+	printf("%s:%s", algo_name, info->keyname);
+
+	if (!info->checksum || !info->crypto || !info->padding) {
+		*err_msgp = "Unknown signature algorithm";
+		return -1;
+	}
+
+	return 0;
+}
+
+int fit_image_check_sig(const void *fit, int noffset, const void *data,
+			size_t size, int required_keynode, char **err_msgp)
+{
+	struct image_sign_info info;
+	struct image_region region;
+	uint8_t *fit_value;
+	int fit_value_len;
+
+	*err_msgp = NULL;
+	if (fit_image_setup_verify(&info, fit, noffset, required_keynode,
+				   err_msgp))
+		return -1;
+
+	if (fit_image_hash_get_value(fit, noffset, &fit_value,
+				     &fit_value_len)) {
+		*err_msgp = "Can't get hash value property";
+		return -1;
+	}
+
+	region.data = data;
+	region.size = size;
+
+	if (info.crypto->verify(&info, &region, 1, fit_value, fit_value_len)) {
+		*err_msgp = "Verification failed";
+		return -1;
+	}
+
+	return 0;
+}
+
+static int fit_image_verify_sig(const void *fit, int image_noffset,
+				const char *data, size_t size,
+				const void *sig_blob, int sig_offset)
+{
+	int noffset;
+	char *err_msg = "";
+	int verified = 0;
+	int ret;
+
+	/* Process all hash subnodes of the component image node */
+	fdt_for_each_subnode(noffset, fit, image_noffset) {
+		const char *name = fit_get_name(fit, noffset, NULL);
+
+		if (!strncmp(name, FIT_SIG_NODENAME,
+			     strlen(FIT_SIG_NODENAME))) {
+			ret = fit_image_check_sig(fit, noffset, data,
+						  size, -1, &err_msg);
+			if (ret) {
+				puts("- ");
+			} else {
+				puts("+ ");
+				verified = 1;
+				break;
+			}
+		}
+	}
+
+	if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
+		err_msg = "Corrupted or truncated tree";
+		goto error;
+	}
+
+	return verified ? 0 : -EPERM;
+
+error:
+	printf(" error!\n%s for '%s' hash node in '%s' image node\n",
+	       err_msg, fit_get_name(fit, noffset, NULL),
+	       fit_get_name(fit, image_noffset, NULL));
+	return -1;
+}
+
+int fit_image_verify_required_sigs(const void *fit, int image_noffset,
+				   const char *data, size_t size,
+				   const void *sig_blob, int *no_sigsp)
+{
+	int verify_count = 0;
+	int noffset;
+	int sig_node;
+
+	/* Work out what we need to verify */
+	*no_sigsp = 1;
+	sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME);
+	if (sig_node < 0) {
+		debug("%s: No signature node found: %s\n", __func__,
+		      fdt_strerror(sig_node));
+		return 0;
+	}
+
+	fdt_for_each_subnode(noffset, sig_blob, sig_node) {
+		const char *required;
+		int ret;
+
+		required = fdt_getprop(sig_blob, noffset, FIT_KEY_REQUIRED,
+				       NULL);
+		if (!required || strcmp(required, "image"))
+			continue;
+		ret = fit_image_verify_sig(fit, image_noffset, data, size,
+					   sig_blob, noffset);
+		if (ret) {
+			printf("Failed to verify required signature '%s'\n",
+			       fit_get_name(sig_blob, noffset, NULL));
+			return ret;
+		}
+		verify_count++;
+	}
+
+	if (verify_count)
+		*no_sigsp = 0;
+
+	return 0;
+}
+
+/**
+ * fit_config_check_sig() - Check the signature of a config
+ *
+ * @fit: FIT to check
+ * @noffset: Offset of configuration node (e.g. /configurations/conf-1)
+ * @required_keynode:	Offset in the control FDT of the required key node,
+ *			if any. If this is given, then the configuration wil not
+ *			pass verification unless that key is used. If this is
+ *			-1 then any signature will do.
+ * @conf_noffset: Offset of the configuration subnode being checked (e.g.
+ *	 /configurations/conf-1/kernel)
+ * @err_msgp:		In the event of an error, this will be pointed to a
+ *			help error string to display to the user.
+ * @return 0 if all verified ok, <0 on error
+ */
+static int fit_config_check_sig(const void *fit, int noffset,
+				int required_keynode, int conf_noffset,
+				char **err_msgp)
+{
+	char * const exc_prop[] = {"data"};
+	const char *prop, *end, *name;
+	struct image_sign_info info;
+	const uint32_t *strings;
+	const char *config_name;
+	uint8_t *fit_value;
+	int fit_value_len;
+	bool found_config;
+	int max_regions;
+	int i, prop_len;
+	char path[200];
+	int count;
+
+	config_name = fit_get_name(fit, conf_noffset, NULL);
+	debug("%s: fdt=%p, conf='%s', sig='%s'\n", __func__, gd_fdt_blob(),
+	      fit_get_name(fit, noffset, NULL),
+	      fit_get_name(gd_fdt_blob(), required_keynode, NULL));
+	*err_msgp = NULL;
+	if (fit_image_setup_verify(&info, fit, noffset, required_keynode,
+				   err_msgp))
+		return -1;
+
+	if (fit_image_hash_get_value(fit, noffset, &fit_value,
+				     &fit_value_len)) {
+		*err_msgp = "Can't get hash value property";
+		return -1;
+	}
+
+	/* Count the number of strings in the property */
+	prop = fdt_getprop(fit, noffset, "hashed-nodes", &prop_len);
+	end = prop ? prop + prop_len : prop;
+	for (name = prop, count = 0; name < end; name++)
+		if (!*name)
+			count++;
+	if (!count) {
+		*err_msgp = "Can't get hashed-nodes property";
+		return -1;
+	}
+
+	if (prop && prop_len > 0 && prop[prop_len - 1] != '\0') {
+		*err_msgp = "hashed-nodes property must be null-terminated";
+		return -1;
+	}
+
+	/* Add a sanity check here since we are using the stack */
+	if (count > IMAGE_MAX_HASHED_NODES) {
+		*err_msgp = "Number of hashed nodes exceeds maximum";
+		return -1;
+	}
+
+	/* Create a list of node names from those strings */
+	char *node_inc[count];
+
+	debug("Hash nodes (%d):\n", count);
+	found_config = false;
+	for (name = prop, i = 0; name < end; name += strlen(name) + 1, i++) {
+		debug("   '%s'\n", name);
+		node_inc[i] = (char *)name;
+		if (!strncmp(FIT_CONFS_PATH, name, strlen(FIT_CONFS_PATH)) &&
+		    name[sizeof(FIT_CONFS_PATH) - 1] == '/' &&
+		    !strcmp(name + sizeof(FIT_CONFS_PATH), config_name)) {
+			debug("      (found config node %s)", config_name);
+			found_config = true;
+		}
+	}
+	if (!found_config) {
+		*err_msgp = "Selected config not in hashed nodes";
+		return -1;
+	}
+
+	/*
+	 * Each node can generate one region for each sub-node. Allow for
+	 * 7 sub-nodes (hash-1, signature-1, etc.) and some extra.
+	 */
+	max_regions = 20 + count * 7;
+	struct fdt_region fdt_regions[max_regions];
+
+	/* Get a list of regions to hash */
+	count = fdt_find_regions(fit, node_inc, count,
+				 exc_prop, ARRAY_SIZE(exc_prop),
+				 fdt_regions, max_regions - 1,
+				 path, sizeof(path), 0);
+	if (count < 0) {
+		*err_msgp = "Failed to hash configuration";
+		return -1;
+	}
+	if (count == 0) {
+		*err_msgp = "No data to hash";
+		return -1;
+	}
+	if (count >= max_regions - 1) {
+		*err_msgp = "Too many hash regions";
+		return -1;
+	}
+
+	/* Add the strings */
+	strings = fdt_getprop(fit, noffset, "hashed-strings", NULL);
+	if (strings) {
+		/*
+		 * The strings region offset must be a static 0x0.
+		 * This is set in tool/image-host.c
+		 */
+		fdt_regions[count].offset = fdt_off_dt_strings(fit);
+		fdt_regions[count].size = fdt32_to_cpu(strings[1]);
+		count++;
+	}
+
+	/* Allocate the region list on the stack */
+	struct image_region region[count];
+
+	fit_region_make_list(fit, fdt_regions, count, region);
+	if (info.crypto->verify(&info, region, count, fit_value,
+				fit_value_len)) {
+		*err_msgp = "Verification failed";
+		return -1;
+	}
+
+	return 0;
+}
+
+static int fit_config_verify_sig(const void *fit, int conf_noffset,
+				 const void *sig_blob, int sig_offset)
+{
+	int noffset;
+	char *err_msg = "";
+	int verified = 0;
+	int ret;
+
+	/* Process all hash subnodes of the component conf node */
+	fdt_for_each_subnode(noffset, fit, conf_noffset) {
+		const char *name = fit_get_name(fit, noffset, NULL);
+
+		if (!strncmp(name, FIT_SIG_NODENAME,
+			     strlen(FIT_SIG_NODENAME))) {
+			ret = fit_config_check_sig(fit, noffset, sig_offset,
+						   conf_noffset, &err_msg);
+			if (ret) {
+				puts("- ");
+			} else {
+				puts("+ ");
+				verified = 1;
+				break;
+			}
+		}
+	}
+
+	if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
+		err_msg = "Corrupted or truncated tree";
+		goto error;
+	}
+
+	if (verified)
+		return 0;
+
+error:
+	printf(" error!\n%s for '%s' hash node in '%s' config node\n",
+	       err_msg, fit_get_name(fit, noffset, NULL),
+	       fit_get_name(fit, conf_noffset, NULL));
+	return -EPERM;
+}
+
+int fit_config_verify_required_sigs(const void *fit, int conf_noffset,
+				    const void *sig_blob)
+{
+	int noffset;
+	int sig_node;
+
+	/* Work out what we need to verify */
+	sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME);
+	if (sig_node < 0) {
+		debug("%s: No signature node found: %s\n", __func__,
+		      fdt_strerror(sig_node));
+		return 0;
+	}
+
+	fdt_for_each_subnode(noffset, sig_blob, sig_node) {
+		const char *required;
+		int ret;
+
+		required = fdt_getprop(sig_blob, noffset, FIT_KEY_REQUIRED,
+				       NULL);
+		if (!required || strcmp(required, "conf"))
+			continue;
+		ret = fit_config_verify_sig(fit, conf_noffset, sig_blob,
+					    noffset);
+		if (ret) {
+			printf("Failed to verify required signature '%s'\n",
+			       fit_get_name(sig_blob, noffset, NULL));
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+int fit_config_verify(const void *fit, int conf_noffset)
+{
+	return fit_config_verify_required_sigs(fit, conf_noffset,
+					       gd_fdt_blob());
+}
diff --git a/common/image-fit.c b/common/image-fit.c
index 0fef0a9..368b730 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -1271,7 +1271,7 @@
 	int ret;
 
 	/* Verify all required signatures */
-	if (IMAGE_ENABLE_VERIFY &&
+	if (FIT_IMAGE_ENABLE_VERIFY &&
 	    fit_image_verify_required_sigs(fit, image_noffset, data, size,
 					   gd_fdt_blob(), &verify_all)) {
 		err_msg = "Unable to verify required signature";
@@ -1293,7 +1293,7 @@
 						 &err_msg))
 				goto error;
 			puts("+ ");
-		} else if (IMAGE_ENABLE_VERIFY && verify_all &&
+		} else if (FIT_IMAGE_ENABLE_VERIFY && verify_all &&
 				!strncmp(name, FIT_SIG_NODENAME,
 					strlen(FIT_SIG_NODENAME))) {
 			ret = fit_image_check_sig(fit, noffset, data,
@@ -1933,7 +1933,7 @@
 		if (image_type == IH_TYPE_KERNEL)
 			images->fit_uname_cfg = fit_base_uname_config;
 
-		if (IMAGE_ENABLE_VERIFY && images->verify) {
+		if (FIT_IMAGE_ENABLE_VERIFY && images->verify) {
 			puts("   Verifying Hash Integrity ... ");
 			if (fit_config_verify(fit, cfg_noffset)) {
 				puts("Bad Data Hash\n");
diff --git a/common/image-sig.c b/common/image-sig.c
index 6563eff..84b2c04 100644
--- a/common/image-sig.c
+++ b/common/image-sig.c
@@ -17,18 +17,6 @@
 
 #define IMAGE_MAX_HASHED_NODES		100
 
-#ifdef USE_HOSTCC
-void *host_blob;
-void image_set_host_blob(void *blob)
-{
-	host_blob = blob;
-}
-void *image_get_host_blob(void)
-{
-	return host_blob;
-}
-#endif
-
 struct checksum_algo checksum_algos[] = {
 	{
 		.name = "sha1",
@@ -162,420 +150,3 @@
 
 	return NULL;
 }
-
-/**
- * fit_region_make_list() - Make a list of image regions
- *
- * Given a list of fdt_regions, create a list of image_regions. This is a
- * simple conversion routine since the FDT and image code use different
- * structures.
- *
- * @fit: FIT image
- * @fdt_regions: Pointer to FDT regions
- * @count: Number of FDT regions
- * @region: Pointer to image regions, which must hold @count records. If
- * region is NULL, then (except for an SPL build) the array will be
- * allocated.
- * @return: Pointer to image regions
- */
-struct image_region *fit_region_make_list(const void *fit,
-		struct fdt_region *fdt_regions, int count,
-		struct image_region *region)
-{
-	int i;
-
-	debug("Hash regions:\n");
-	debug("%10s %10s\n", "Offset", "Size");
-
-	/*
-	 * Use malloc() except in SPL (to save code size). In SPL the caller
-	 * must allocate the array.
-	 */
-#ifndef CONFIG_SPL_BUILD
-	if (!region)
-		region = calloc(sizeof(*region), count);
-#endif
-	if (!region)
-		return NULL;
-	for (i = 0; i < count; i++) {
-		debug("%10x %10x\n", fdt_regions[i].offset,
-		      fdt_regions[i].size);
-		region[i].data = fit + fdt_regions[i].offset;
-		region[i].size = fdt_regions[i].size;
-	}
-
-	return region;
-}
-
-static int fit_image_setup_verify(struct image_sign_info *info,
-		const void *fit, int noffset, int required_keynode,
-		char **err_msgp)
-{
-	char *algo_name;
-	const char *padding_name;
-
-	if (fdt_totalsize(fit) > CONFIG_FIT_SIGNATURE_MAX_SIZE) {
-		*err_msgp = "Total size too large";
-		return 1;
-	}
-
-	if (fit_image_hash_get_algo(fit, noffset, &algo_name)) {
-		*err_msgp = "Can't get hash algo property";
-		return -1;
-	}
-
-	padding_name = fdt_getprop(fit, noffset, "padding", NULL);
-	if (!padding_name)
-		padding_name = RSA_DEFAULT_PADDING_NAME;
-
-	memset(info, '\0', sizeof(*info));
-	info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
-	info->fit = (void *)fit;
-	info->node_offset = noffset;
-	info->name = algo_name;
-	info->checksum = image_get_checksum_algo(algo_name);
-	info->crypto = image_get_crypto_algo(algo_name);
-	info->padding = image_get_padding_algo(padding_name);
-	info->fdt_blob = gd_fdt_blob();
-	info->required_keynode = required_keynode;
-	printf("%s:%s", algo_name, info->keyname);
-
-	if (!info->checksum || !info->crypto || !info->padding) {
-		*err_msgp = "Unknown signature algorithm";
-		return -1;
-	}
-
-	return 0;
-}
-
-int fit_image_check_sig(const void *fit, int noffset, const void *data,
-		size_t size, int required_keynode, char **err_msgp)
-{
-	struct image_sign_info info;
-	struct image_region region;
-	uint8_t *fit_value;
-	int fit_value_len;
-
-	*err_msgp = NULL;
-	if (fit_image_setup_verify(&info, fit, noffset, required_keynode,
-				   err_msgp))
-		return -1;
-
-	if (fit_image_hash_get_value(fit, noffset, &fit_value,
-				     &fit_value_len)) {
-		*err_msgp = "Can't get hash value property";
-		return -1;
-	}
-
-	region.data = data;
-	region.size = size;
-
-	if (info.crypto->verify(&info, &region, 1, fit_value, fit_value_len)) {
-		*err_msgp = "Verification failed";
-		return -1;
-	}
-
-	return 0;
-}
-
-static int fit_image_verify_sig(const void *fit, int image_noffset,
-		const char *data, size_t size, const void *sig_blob,
-		int sig_offset)
-{
-	int noffset;
-	char *err_msg = "";
-	int verified = 0;
-	int ret;
-
-	/* Process all hash subnodes of the component image node */
-	fdt_for_each_subnode(noffset, fit, image_noffset) {
-		const char *name = fit_get_name(fit, noffset, NULL);
-
-		if (!strncmp(name, FIT_SIG_NODENAME,
-			     strlen(FIT_SIG_NODENAME))) {
-			ret = fit_image_check_sig(fit, noffset, data,
-							size, -1, &err_msg);
-			if (ret) {
-				puts("- ");
-			} else {
-				puts("+ ");
-				verified = 1;
-				break;
-			}
-		}
-	}
-
-	if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
-		err_msg = "Corrupted or truncated tree";
-		goto error;
-	}
-
-	return verified ? 0 : -EPERM;
-
-error:
-	printf(" error!\n%s for '%s' hash node in '%s' image node\n",
-	       err_msg, fit_get_name(fit, noffset, NULL),
-	       fit_get_name(fit, image_noffset, NULL));
-	return -1;
-}
-
-int fit_image_verify_required_sigs(const void *fit, int image_noffset,
-		const char *data, size_t size, const void *sig_blob,
-		int *no_sigsp)
-{
-	int verify_count = 0;
-	int noffset;
-	int sig_node;
-
-	/* Work out what we need to verify */
-	*no_sigsp = 1;
-	sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME);
-	if (sig_node < 0) {
-		debug("%s: No signature node found: %s\n", __func__,
-		      fdt_strerror(sig_node));
-		return 0;
-	}
-
-	fdt_for_each_subnode(noffset, sig_blob, sig_node) {
-		const char *required;
-		int ret;
-
-		required = fdt_getprop(sig_blob, noffset, FIT_KEY_REQUIRED,
-				       NULL);
-		if (!required || strcmp(required, "image"))
-			continue;
-		ret = fit_image_verify_sig(fit, image_noffset, data, size,
-					sig_blob, noffset);
-		if (ret) {
-			printf("Failed to verify required signature '%s'\n",
-			       fit_get_name(sig_blob, noffset, NULL));
-			return ret;
-		}
-		verify_count++;
-	}
-
-	if (verify_count)
-		*no_sigsp = 0;
-
-	return 0;
-}
-
-/**
- * fit_config_check_sig() - Check the signature of a config
- *
- * @fit: FIT to check
- * @noffset: Offset of configuration node (e.g. /configurations/conf-1)
- * @required_keynode:	Offset in the control FDT of the required key node,
- *			if any. If this is given, then the configuration wil not
- *			pass verification unless that key is used. If this is
- *			-1 then any signature will do.
- * @conf_noffset: Offset of the configuration subnode being checked (e.g.
- *	 /configurations/conf-1/kernel)
- * @err_msgp:		In the event of an error, this will be pointed to a
- *			help error string to display to the user.
- * @return 0 if all verified ok, <0 on error
- */
-static int fit_config_check_sig(const void *fit, int noffset,
-				int required_keynode, int conf_noffset,
-				char **err_msgp)
-{
-	char * const exc_prop[] = {"data"};
-	const char *prop, *end, *name;
-	struct image_sign_info info;
-	const uint32_t *strings;
-	const char *config_name;
-	uint8_t *fit_value;
-	int fit_value_len;
-	bool found_config;
-	int max_regions;
-	int i, prop_len;
-	char path[200];
-	int count;
-
-	config_name = fit_get_name(fit, conf_noffset, NULL);
-	debug("%s: fdt=%p, conf='%s', sig='%s'\n", __func__, gd_fdt_blob(),
-	      fit_get_name(fit, noffset, NULL),
-	      fit_get_name(gd_fdt_blob(), required_keynode, NULL));
-	*err_msgp = NULL;
-	if (fit_image_setup_verify(&info, fit, noffset, required_keynode,
-				   err_msgp))
-		return -1;
-
-	if (fit_image_hash_get_value(fit, noffset, &fit_value,
-				     &fit_value_len)) {
-		*err_msgp = "Can't get hash value property";
-		return -1;
-	}
-
-	/* Count the number of strings in the property */
-	prop = fdt_getprop(fit, noffset, "hashed-nodes", &prop_len);
-	end = prop ? prop + prop_len : prop;
-	for (name = prop, count = 0; name < end; name++)
-		if (!*name)
-			count++;
-	if (!count) {
-		*err_msgp = "Can't get hashed-nodes property";
-		return -1;
-	}
-
-	if (prop && prop_len > 0 && prop[prop_len - 1] != '\0') {
-		*err_msgp = "hashed-nodes property must be null-terminated";
-		return -1;
-	}
-
-	/* Add a sanity check here since we are using the stack */
-	if (count > IMAGE_MAX_HASHED_NODES) {
-		*err_msgp = "Number of hashed nodes exceeds maximum";
-		return -1;
-	}
-
-	/* Create a list of node names from those strings */
-	char *node_inc[count];
-
-	debug("Hash nodes (%d):\n", count);
-	found_config = false;
-	for (name = prop, i = 0; name < end; name += strlen(name) + 1, i++) {
-		debug("   '%s'\n", name);
-		node_inc[i] = (char *)name;
-		if (!strncmp(FIT_CONFS_PATH, name, strlen(FIT_CONFS_PATH)) &&
-		    name[sizeof(FIT_CONFS_PATH) - 1] == '/' &&
-		    !strcmp(name + sizeof(FIT_CONFS_PATH), config_name)) {
-			debug("      (found config node %s)", config_name);
-			found_config = true;
-		}
-	}
-	if (!found_config) {
-		*err_msgp = "Selected config not in hashed nodes";
-		return -1;
-	}
-
-	/*
-	 * Each node can generate one region for each sub-node. Allow for
-	 * 7 sub-nodes (hash-1, signature-1, etc.) and some extra.
-	 */
-	max_regions = 20 + count * 7;
-	struct fdt_region fdt_regions[max_regions];
-
-	/* Get a list of regions to hash */
-	count = fdt_find_regions(fit, node_inc, count,
-			exc_prop, ARRAY_SIZE(exc_prop),
-			fdt_regions, max_regions - 1,
-			path, sizeof(path), 0);
-	if (count < 0) {
-		*err_msgp = "Failed to hash configuration";
-		return -1;
-	}
-	if (count == 0) {
-		*err_msgp = "No data to hash";
-		return -1;
-	}
-	if (count >= max_regions - 1) {
-		*err_msgp = "Too many hash regions";
-		return -1;
-	}
-
-	/* Add the strings */
-	strings = fdt_getprop(fit, noffset, "hashed-strings", NULL);
-	if (strings) {
-		/*
-		 * The strings region offset must be a static 0x0.
-		 * This is set in tool/image-host.c
-		 */
-		fdt_regions[count].offset = fdt_off_dt_strings(fit);
-		fdt_regions[count].size = fdt32_to_cpu(strings[1]);
-		count++;
-	}
-
-	/* Allocate the region list on the stack */
-	struct image_region region[count];
-
-	fit_region_make_list(fit, fdt_regions, count, region);
-	if (info.crypto->verify(&info, region, count, fit_value,
-				fit_value_len)) {
-		*err_msgp = "Verification failed";
-		return -1;
-	}
-
-	return 0;
-}
-
-static int fit_config_verify_sig(const void *fit, int conf_noffset,
-		const void *sig_blob, int sig_offset)
-{
-	int noffset;
-	char *err_msg = "";
-	int verified = 0;
-	int ret;
-
-	/* Process all hash subnodes of the component conf node */
-	fdt_for_each_subnode(noffset, fit, conf_noffset) {
-		const char *name = fit_get_name(fit, noffset, NULL);
-
-		if (!strncmp(name, FIT_SIG_NODENAME,
-			     strlen(FIT_SIG_NODENAME))) {
-			ret = fit_config_check_sig(fit, noffset, sig_offset,
-						   conf_noffset, &err_msg);
-			if (ret) {
-				puts("- ");
-			} else {
-				puts("+ ");
-				verified = 1;
-				break;
-			}
-		}
-	}
-
-	if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
-		err_msg = "Corrupted or truncated tree";
-		goto error;
-	}
-
-	if (verified)
-		return 0;
-
-error:
-	printf(" error!\n%s for '%s' hash node in '%s' config node\n",
-	       err_msg, fit_get_name(fit, noffset, NULL),
-	       fit_get_name(fit, conf_noffset, NULL));
-	return -EPERM;
-}
-
-int fit_config_verify_required_sigs(const void *fit, int conf_noffset,
-		const void *sig_blob)
-{
-	int noffset;
-	int sig_node;
-
-	/* Work out what we need to verify */
-	sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME);
-	if (sig_node < 0) {
-		debug("%s: No signature node found: %s\n", __func__,
-		      fdt_strerror(sig_node));
-		return 0;
-	}
-
-	fdt_for_each_subnode(noffset, sig_blob, sig_node) {
-		const char *required;
-		int ret;
-
-		required = fdt_getprop(sig_blob, noffset, FIT_KEY_REQUIRED,
-				       NULL);
-		if (!required || strcmp(required, "conf"))
-			continue;
-		ret = fit_config_verify_sig(fit, conf_noffset, sig_blob,
-					    noffset);
-		if (ret) {
-			printf("Failed to verify required signature '%s'\n",
-			       fit_get_name(sig_blob, noffset, NULL));
-			return ret;
-		}
-	}
-
-	return 0;
-}
-
-int fit_config_verify(const void *fit, int conf_noffset)
-{
-	return fit_config_verify_required_sigs(fit, conf_noffset,
-					       gd_fdt_blob());
-}
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index b03a476..9d52b75 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -139,7 +139,7 @@
 
 config SPL_LDSCRIPT
 	string "Linker script for the SPL stage"
-	default "arch/$(ARCH)/cpu/u-boot-spl.lds"
+	default "arch/\$(ARCH)/cpu/u-boot-spl.lds"
 	help
 	  The SPL stage will usually require a different linker-script
 	  (as it runs from a different memory region) than the regular
@@ -1306,7 +1306,7 @@
         string "Linker script for the TPL stage"
 	depends on TPL
 	default "arch/arm/cpu/armv8/u-boot-spl.lds" if ARM64
-	default "arch/$(ARCH)/cpu/u-boot-spl.lds"
+	default "arch/\$(ARCH)/cpu/u-boot-spl.lds"
 	help
 	  The TPL stage will usually require a different linker-script
 	  (as it runs from a different memory region) than the regular
diff --git a/configs/am335x_baltos_defconfig b/configs/am335x_baltos_defconfig
index 63f0da9..2781d49 100644
--- a/configs/am335x_baltos_defconfig
+++ b/configs/am335x_baltos_defconfig
@@ -55,6 +55,8 @@
 CONFIG_PHY_ADDR_ENABLE=y
 CONFIG_PHY_ATHEROS=y
 CONFIG_PHY_SMSC=y
+CONFIG_DM_ETH=y
+CONFIG_DM_MDIO=y
 CONFIG_MII=y
 CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SPI=y
diff --git a/configs/am335x_evm_defconfig b/configs/am335x_evm_defconfig
index 335aa8c..66899c2 100644
--- a/configs/am335x_evm_defconfig
+++ b/configs/am335x_evm_defconfig
@@ -40,10 +40,14 @@
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_CLK=y
 CONFIG_CLK_CDCE9XX=y
+CONFIG_DFU_TFTP=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_NAND=y
 CONFIG_DFU_RAM=y
 CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=1
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_DM_I2C=y
 CONFIG_MISC=y
 CONFIG_DM_MMC=y
diff --git a/configs/am65x_evm_a53_defconfig b/configs/am65x_evm_a53_defconfig
index df7723b..542bbd9 100644
--- a/configs/am65x_evm_a53_defconfig
+++ b/configs/am65x_evm_a53_defconfig
@@ -16,6 +16,8 @@
 CONFIG_ENV_OFFSET_REDUND=0x6A0000
 CONFIG_SPL_FS_FAT=y
 CONFIG_SPL_LIBDISK_SUPPORT=y
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI_SUPPORT=y
 # CONFIG_PSCI_RESET is not set
 CONFIG_SPL_TEXT_BASE=0x80080000
 CONFIG_DISTRO_DEFAULTS=y
@@ -29,10 +31,17 @@
 CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1400
+CONFIG_SPL_DMA=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
+CONFIG_SPL_MTD_SUPPORT=y
 CONFIG_SPL_DM_RESET=y
 CONFIG_SPL_POWER_DOMAIN=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x280000
 CONFIG_SPL_YMODEM_SUPPORT=y
 CONFIG_CMD_ASKENV=y
 CONFIG_CMD_DFU=y
@@ -41,9 +50,13 @@
 CONFIG_CMD_MMC=y
 CONFIG_CMD_PCI=y
 CONFIG_CMD_REMOTEPROC=y
+CONFIG_CMD_SF=y
 CONFIG_CMD_USB=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_TIME=y
+CONFIG_MTDIDS_DEFAULT="nor0=47040000.spi.0"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=47040000.spi.0:512k(ospi.tiboot3),2m(ospi.tispl),4m(ospi.u-boot),128k(ospi.env),128k(ospi.env.backup),1m(ospi.sysfw),-@8m(ospi.rootfs)"
+CONFIG_CMD_UBI=y
 # CONFIG_ISO_PARTITION is not set
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
@@ -58,11 +71,13 @@
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_SPL_REGMAP=y
+CONFIG_SPL_OF_TRANSLATE=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_CLK_TI_SCI=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
+CONFIG_DFU_SF=y
 CONFIG_DMA_CHANNELS=y
 CONFIG_TI_K3_NAVSS_UDMA=y
 CONFIG_TI_SCI_PROTOCOL=y
@@ -79,6 +94,13 @@
 CONFIG_MMC_SDHCI_ADMA=y
 CONFIG_SPL_MMC_SDHCI_ADMA=y
 CONFIG_MMC_SDHCI_AM654=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT
+CONFIG_SPI_FLASH_STMICRO=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_TI=y
 CONFIG_PHY_FIXED=y
 CONFIG_DM_ETH=y
@@ -103,6 +125,9 @@
 CONFIG_RESET_TI_SCI=y
 CONFIG_DM_SERIAL=y
 CONFIG_SOC_TI=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_CADENCE_QSPI=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
 CONFIG_SYSRESET_TI_SCI=y
diff --git a/configs/am65x_evm_r5_defconfig b/configs/am65x_evm_r5_defconfig
index b475ace..b795526 100644
--- a/configs/am65x_evm_r5_defconfig
+++ b/configs/am65x_evm_r5_defconfig
@@ -16,6 +16,8 @@
 CONFIG_NR_DRAM_BANKS=2
 CONFIG_SPL_FS_FAT=y
 CONFIG_SPL_LIBDISK_SUPPORT=y
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI_SUPPORT=y
 CONFIG_SPL_TEXT_BASE=0x41c00000
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SPL_LOAD_FIT=y
@@ -26,6 +28,7 @@
 CONFIG_SPL_EARLY_BSS=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x400
+CONFIG_SPL_DMA=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
 CONFIG_SPL_DM_RESET=y
@@ -34,6 +37,10 @@
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_REMOTEPROC=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000
 CONFIG_SPL_YMODEM_SUPPORT=y
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_BOOTZ=y
@@ -63,6 +70,8 @@
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_CLK_TI_SCI=y
+CONFIG_DMA_CHANNELS=y
+CONFIG_TI_K3_NAVSS_UDMA=y
 CONFIG_TI_SCI_PROTOCOL=y
 CONFIG_DA8XX_GPIO=y
 CONFIG_DM_I2C=y
@@ -77,6 +86,10 @@
 CONFIG_MMC_SDHCI=y
 CONFIG_SPL_MMC_SDHCI_ADMA=y
 CONFIG_MMC_SDHCI_AM654=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_STMICRO=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
 CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_GENERIC is not set
 CONFIG_SPL_PINCTRL=y
@@ -96,6 +109,10 @@
 CONFIG_DM_RESET=y
 CONFIG_RESET_TI_SCI=y
 CONFIG_DM_SERIAL=y
+CONFIG_SOC_TI=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_CADENCE_QSPI=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
 CONFIG_SYSRESET_TI_SCI=y
diff --git a/configs/am65x_hs_evm_a53_defconfig b/configs/am65x_hs_evm_a53_defconfig
index 6097a02..9f43cee 100644
--- a/configs/am65x_hs_evm_a53_defconfig
+++ b/configs/am65x_hs_evm_a53_defconfig
@@ -7,6 +7,7 @@
 CONFIG_SOC_K3_AM6=y
 CONFIG_TARGET_AM654_A53_EVM=y
 CONFIG_ENV_SIZE=0x20000
+CONFIG_ENV_OFFSET=0x680000
 CONFIG_DM_GPIO=y
 CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
@@ -15,6 +16,9 @@
 CONFIG_NR_DRAM_BANKS=2
 CONFIG_SPL_FS_FAT=y
 CONFIG_SPL_LIBDISK_SUPPORT=y
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI_SUPPORT=y
+# CONFIG_PSCI_RESET is not set
 CONFIG_SPL_TEXT_BASE=0x80080000
 CONFIG_DISTRO_DEFAULTS=y
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
@@ -23,38 +27,60 @@
 CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y
 CONFIG_OF_BOARD_SETUP=y
 CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run get_fit_${boot}; run get_overlaystring; run run_fit"
+CONFIG_CONSOLE_MUX=y
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1400
+CONFIG_SPL_DMA=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
+CONFIG_SPL_MTD_SUPPORT=y
 CONFIG_SPL_DM_RESET=y
 CONFIG_SPL_POWER_DOMAIN=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x280000
 CONFIG_SPL_YMODEM_SUPPORT=y
 CONFIG_CMD_ASKENV=y
+CONFIG_CMD_DFU=y
+CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_REMOTEPROC=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_USB=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_TIME=y
+CONFIG_MTDIDS_DEFAULT="nor0=47040000.spi.0"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=47040000.spi.0:512k(ospi.tiboot3),2m(ospi.tispl),4m(ospi.u-boot),128k(ospi.env),128k(ospi.env.backup),1m(ospi.sysfw),-@8m(ospi.rootfs)"
+CONFIG_CMD_UBI=y
 # CONFIG_ISO_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="k3-am654-base-board"
 CONFIG_SPL_MULTI_DTB_FIT=y
 CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y
-CONFIG_ENV_IS_IN_FAT=y
-CONFIG_ENV_FAT_INTERFACE="mmc"
-CONFIG_ENV_FAT_DEVICE_AND_PART="1:1"
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
+CONFIG_ENV_OFFSET_REDUND=0x6A0000
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SPL_OF_TRANSLATE=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_CLK_TI_SCI=y
+CONFIG_DFU_MMC=y
+CONFIG_DFU_RAM=y
+CONFIG_DFU_SF=y
 CONFIG_DMA_CHANNELS=y
 CONFIG_TI_K3_NAVSS_UDMA=y
 CONFIG_TI_SCI_PROTOCOL=y
@@ -62,10 +88,33 @@
 CONFIG_DM_I2C=y
 CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
 CONFIG_SYS_I2C_OMAP24XX=y
+CONFIG_DM_KEYBOARD=y
 CONFIG_DM_MAILBOX=y
 CONFIG_K3_SEC_PROXY=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ADMA=y
+CONFIG_SPL_MMC_SDHCI_ADMA=y
+CONFIG_MMC_SDHCI_AM654=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT
+CONFIG_SPI_FLASH_STMICRO=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_PHY_TI=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_E1000=y
+CONFIG_CMD_E1000=y
+CONFIG_TI_AM65_CPSW_NUSS=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_PCI_KEYSTONE=y
+CONFIG_PHY=y
+CONFIG_AM654_PHY=y
+CONFIG_OMAP_USB2_PHY=y
 CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_GENERIC is not set
 CONFIG_SPL_PINCTRL=y
@@ -73,11 +122,29 @@
 CONFIG_PINCTRL_SINGLE=y
 CONFIG_POWER_DOMAIN=y
 CONFIG_TI_SCI_POWER_DOMAIN=y
+CONFIG_REMOTEPROC_TI_K3_R5F=y
 CONFIG_DM_RESET=y
 CONFIG_RESET_TI_SCI=y
 CONFIG_DM_SERIAL=y
 CONFIG_SOC_TI=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_CADENCE_QSPI=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
 CONFIG_SYSRESET_TI_SCI=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_GENERIC=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
+CONFIG_USB_GADGET_VENDOR_NUM=0x0451
+CONFIG_USB_GADGET_PRODUCT_NUM=0x6162
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_FAT_WRITE=y
 CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/am65x_hs_evm_r5_defconfig b/configs/am65x_hs_evm_r5_defconfig
index 0cdfc73..bbf50bf 100644
--- a/configs/am65x_hs_evm_r5_defconfig
+++ b/configs/am65x_hs_evm_r5_defconfig
@@ -6,6 +6,7 @@
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_SYS_MALLOC_F_LEN=0x55000
 CONFIG_SOC_K3_AM6=y
+CONFIG_K3_EARLY_CONS=y
 CONFIG_TARGET_AM654_R5_EVM=y
 CONFIG_ENV_SIZE=0x20000
 CONFIG_DM_GPIO=y
@@ -16,6 +17,8 @@
 CONFIG_NR_DRAM_BANKS=2
 CONFIG_SPL_FS_FAT=y
 CONFIG_SPL_LIBDISK_SUPPORT=y
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI_SUPPORT=y
 CONFIG_SPL_TEXT_BASE=0x41c00000
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SPL_LOAD_FIT=y
@@ -27,6 +30,7 @@
 CONFIG_SPL_EARLY_BSS=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x400
+CONFIG_SPL_DMA=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
 CONFIG_SPL_DM_RESET=y
@@ -35,6 +39,10 @@
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_REMOTEPROC=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000
 CONFIG_SPL_YMODEM_SUPPORT=y
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_BOOTZ=y
@@ -58,10 +66,14 @@
 CONFIG_DM=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
 CONFIG_SPL_OF_TRANSLATE=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_CLK_TI_SCI=y
+CONFIG_DMA_CHANNELS=y
+CONFIG_TI_K3_NAVSS_UDMA=y
 CONFIG_TI_SCI_PROTOCOL=y
 CONFIG_DA8XX_GPIO=y
 CONFIG_DM_I2C=y
@@ -70,8 +82,15 @@
 CONFIG_DM_MAILBOX=y
 CONFIG_K3_SEC_PROXY=y
 CONFIG_MISC=y
+CONFIG_K3_AVS0=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
+CONFIG_SPL_MMC_SDHCI_ADMA=y
+CONFIG_MMC_SDHCI_AM654=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_STMICRO=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
 CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_GENERIC is not set
 CONFIG_SPL_PINCTRL=y
@@ -83,6 +102,7 @@
 CONFIG_SPL_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_GPIO=y
 CONFIG_SPL_DM_REGULATOR_GPIO=y
+CONFIG_DM_REGULATOR_TPS62360=y
 CONFIG_RAM=y
 CONFIG_SPL_RAM=y
 CONFIG_K3_SYSTEM_CONTROLLER=y
@@ -90,6 +110,10 @@
 CONFIG_DM_RESET=y
 CONFIG_RESET_TI_SCI=y
 CONFIG_DM_SERIAL=y
+CONFIG_SOC_TI=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_CADENCE_QSPI=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
 CONFIG_SYSRESET_TI_SCI=y
diff --git a/configs/axm_defconfig b/configs/axm_defconfig
index 57683b1..1ae7846 100644
--- a/configs/axm_defconfig
+++ b/configs/axm_defconfig
@@ -5,7 +5,7 @@
 # CONFIG_SPL_USE_ARCH_MEMCPY is not set
 # CONFIG_SPL_USE_ARCH_MEMSET is not set
 CONFIG_ARCH_AT91=y
-CONFIG_SPL_LDSCRIPT="arch/$(ARCH)/cpu/u-boot-spl.lds"
+CONFIG_SPL_LDSCRIPT="arch/arm/cpu/u-boot-spl.lds"
 CONFIG_SYS_TEXT_BASE=0x21000000
 CONFIG_TARGET_TAURUS=y
 CONFIG_SPL_GPIO_SUPPORT=y
diff --git a/configs/brppt2_defconfig b/configs/brppt2_defconfig
index f94ea28..4fde3b9 100644
--- a/configs/brppt2_defconfig
+++ b/configs/brppt2_defconfig
@@ -2,7 +2,7 @@
 # CONFIG_SPL_SYS_THUMB_BUILD is not set
 CONFIG_SYS_L2CACHE_OFF=y
 CONFIG_ARCH_MX6=y
-CONFIG_SPL_LDSCRIPT="arch/$(ARCH)/cpu/u-boot-spl.lds"
+CONFIG_SPL_LDSCRIPT="arch/arm/cpu/u-boot-spl.lds"
 CONFIG_SYS_TEXT_BASE=0x17800000
 CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
diff --git a/configs/edminiv2_defconfig b/configs/edminiv2_defconfig
index 2bbd6a7..b9a68a9 100644
--- a/configs/edminiv2_defconfig
+++ b/configs/edminiv2_defconfig
@@ -1,6 +1,7 @@
 CONFIG_ARM=y
 CONFIG_ARCH_CPU_INIT=y
 CONFIG_ORION5X=y
+CONFIG_SPL_LDSCRIPT="arch/arm/cpu/arm926ejs/orion5x/u-boot-spl.lds"
 CONFIG_SYS_TEXT_BASE=0x00800000
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
diff --git a/configs/j721e_evm_a72_defconfig b/configs/j721e_evm_a72_defconfig
index b27f9ba..e9e82bb 100644
--- a/configs/j721e_evm_a72_defconfig
+++ b/configs/j721e_evm_a72_defconfig
@@ -31,6 +31,7 @@
 CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1400
+CONFIG_SPL_DMA=y
 CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
@@ -39,6 +40,8 @@
 CONFIG_SPL_POWER_DOMAIN=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SYS_SPI_U_BOOT_OFFS=0x280000
 CONFIG_SPL_USB_GADGET=y
@@ -60,7 +63,8 @@
 CONFIG_CMD_TIME=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_MTDIDS_DEFAULT="nor0=47040000.spi.0,nor0=47034000.hyperbus"
-CONFIG_MTDPARTS_DEFAULT="mtdparts=47034000.hyperbus:512k(hbmc.tiboot3),2m(hbmc.tispl),4m(hbmc.u-boot),256k(hbmc.env),1m(hbmc.sysfw),-@8m(hbmc.rootfs)"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=47040000.spi.0:512k(ospi.tiboot3),2m(ospi.tispl),4m(ospi.u-boot),128k(ospi.env),128k(ospi.env.backup),1m(ospi.sysfw),-@8m(ospi.rootfs);47034000.hyperbus:512k(hbmc.tiboot3),2m(hbmc.tispl),4m(hbmc.u-boot),256k(hbmc.env),1m(hbmc.sysfw),-@8m(hbmc.rootfs)"
+CONFIG_CMD_UBI=y
 # CONFIG_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_OF_CONTROL=y
@@ -116,7 +120,10 @@
 CONFIG_SYS_FLASH_CFI=y
 CONFIG_HBMC_AM654=y
 CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT
 CONFIG_SPI_FLASH_STMICRO=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_TI=y
 CONFIG_PHY_FIXED=y
 CONFIG_DM_ETH=y
diff --git a/configs/j721e_evm_r5_defconfig b/configs/j721e_evm_r5_defconfig
index ea70c34..917f82d 100644
--- a/configs/j721e_evm_r5_defconfig
+++ b/configs/j721e_evm_r5_defconfig
@@ -8,7 +8,6 @@
 CONFIG_K3_EARLY_CONS=y
 CONFIG_TARGET_J721E_R5_EVM=y
 CONFIG_ENV_SIZE=0x20000
-CONFIG_ENV_OFFSET=0x680000
 CONFIG_DM_GPIO=y
 CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
@@ -29,7 +28,9 @@
 CONFIG_SPL_EARLY_BSS=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x400
+CONFIG_SPL_DMA=y
 CONFIG_SPL_ENV_SUPPORT=y
+CONFIG_SPL_FS_EXT4=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
 CONFIG_SPL_DM_RESET=y
@@ -38,6 +39,8 @@
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_REMOTEPROC=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000
 CONFIG_SPL_USB_GADGET=y
@@ -55,8 +58,6 @@
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="k3-j721e-r5-common-proc-board"
-CONFIG_ENV_IS_IN_MMC=y
-CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
@@ -67,6 +68,8 @@
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_CLK_TI_SCI=y
+CONFIG_DMA_CHANNELS=y
+CONFIG_TI_K3_NAVSS_UDMA=y
 CONFIG_TI_SCI_PROTOCOL=y
 CONFIG_DA8XX_GPIO=y
 CONFIG_DM_PCA953X=y
@@ -85,6 +88,7 @@
 CONFIG_MMC_SDHCI_AM654=y
 CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_GENERIC is not set
@@ -100,9 +104,11 @@
 CONFIG_DM_REGULATOR_TPS65941=y
 CONFIG_K3_SYSTEM_CONTROLLER=y
 CONFIG_REMOTEPROC_TI_K3_ARM64=y
+CONFIG_REMOTEPROC_TI_K3_R5F=y
 CONFIG_DM_RESET=y
 CONFIG_RESET_TI_SCI=y
 CONFIG_DM_SERIAL=y
+CONFIG_SOC_TI=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
 CONFIG_CADENCE_QSPI=y
@@ -126,3 +132,6 @@
 CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_FS_EXT4=y
 CONFIG_FS_FAT_MAX_CLUSTSIZE=16384
+CONFIG_ESM_K3=y
+CONFIG_ESM_PMIC=y
+CONFIG_SPL_BOARD_INIT=y
diff --git a/configs/j721e_hs_evm_a72_defconfig b/configs/j721e_hs_evm_a72_defconfig
index f791877..a723e27 100644
--- a/configs/j721e_hs_evm_a72_defconfig
+++ b/configs/j721e_hs_evm_a72_defconfig
@@ -36,6 +36,8 @@
 CONFIG_SPL_DM_RESET=y
 CONFIG_SPL_POWER_SUPPORT=y
 CONFIG_SPL_POWER_DOMAIN=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SYS_SPI_U_BOOT_OFFS=0x280000
 CONFIG_SPL_YMODEM_SUPPORT=y
@@ -54,7 +56,8 @@
 CONFIG_CMD_TIME=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_MTDIDS_DEFAULT="nor0=47040000.spi.0,nor0=47034000.hyperbus"
-CONFIG_MTDPARTS_DEFAULT="mtdparts=47034000.hyperbus:512k(hbmc.tiboot3),2m(hbmc.tispl),4m(hbmc.u-boot),256k(hbmc.env),1m(hbmc.sysfw),-@8m(hbmc.rootfs)"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=47040000.spi.0:512k(ospi.tiboot3),2m(ospi.tispl),4m(ospi.u-boot),128k(ospi.env),128k(ospi.env.backup),1m(ospi.sysfw),-@8m(ospi.rootfs);47034000.hyperbus:512k(hbmc.tiboot3),2m(hbmc.tispl),4m(hbmc.u-boot),256k(hbmc.env),1m(hbmc.sysfw),-@8m(hbmc.rootfs)"
+CONFIG_CMD_UBI=y
 # CONFIG_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_OF_CONTROL=y
@@ -107,7 +110,10 @@
 CONFIG_SYS_FLASH_CFI=y
 CONFIG_HBMC_AM654=y
 CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT
 CONFIG_SPI_FLASH_STMICRO=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_TI=y
 CONFIG_PHY_FIXED=y
 CONFIG_DM_ETH=y
diff --git a/configs/j721e_hs_evm_r5_defconfig b/configs/j721e_hs_evm_r5_defconfig
index 91d1cc8..196625d 100644
--- a/configs/j721e_hs_evm_r5_defconfig
+++ b/configs/j721e_hs_evm_r5_defconfig
@@ -28,6 +28,7 @@
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SPL_EARLY_BSS=y
+CONFIG_SPL_DMA=y
 CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
@@ -37,6 +38,8 @@
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_REMOTEPROC=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000
 CONFIG_SPL_YMODEM_SUPPORT=y
@@ -63,6 +66,8 @@
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_CLK_TI_SCI=y
+CONFIG_DMA_CHANNELS=y
+CONFIG_TI_K3_NAVSS_UDMA=y
 CONFIG_TI_SCI_PROTOCOL=y
 CONFIG_DA8XX_GPIO=y
 CONFIG_DM_I2C=y
@@ -79,6 +84,7 @@
 CONFIG_MMC_SDHCI_AM654=y
 CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_GENERIC is not set
@@ -97,6 +103,7 @@
 CONFIG_DM_RESET=y
 CONFIG_RESET_TI_SCI=y
 CONFIG_DM_SERIAL=y
+CONFIG_SOC_TI=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
 CONFIG_CADENCE_QSPI=y
diff --git a/configs/mx31pdk_defconfig b/configs/mx31pdk_defconfig
index ac1dac0..595a1be 100644
--- a/configs/mx31pdk_defconfig
+++ b/configs/mx31pdk_defconfig
@@ -2,6 +2,7 @@
 # CONFIG_SPL_USE_ARCH_MEMCPY is not set
 # CONFIG_SPL_USE_ARCH_MEMSET is not set
 CONFIG_ARCH_MX31=y
+CONFIG_SPL_LDSCRIPT="arch/arm/cpu/u-boot-spl.lds"
 CONFIG_SYS_TEXT_BASE=0x87e00000
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_TARGET_MX31PDK=y
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index 71a4d7f..8ca17d6 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -199,6 +199,7 @@
 CONFIG_FS_CBFS=y
 CONFIG_FS_CRAMFS=y
 CONFIG_CMD_DHRYSTONE=y
+CONFIG_RSA_VERIFY_WITH_PKEY=y
 CONFIG_TPM=y
 CONFIG_LZ4=y
 CONFIG_ERRNO_STR=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index f96891e..cc90f00 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -225,6 +225,7 @@
 CONFIG_FS_CBFS=y
 CONFIG_FS_CRAMFS=y
 CONFIG_CMD_DHRYSTONE=y
+CONFIG_RSA_VERIFY_WITH_PKEY=y
 CONFIG_TPM=y
 CONFIG_LZ4=y
 CONFIG_ERRNO_STR=y
diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig
index 43efefd..59d34cb 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -175,6 +175,7 @@
 CONFIG_OSD=y
 CONFIG_SANDBOX_OSD=y
 CONFIG_CMD_DHRYSTONE=y
+CONFIG_RSA_VERIFY_WITH_PKEY=y
 CONFIG_TPM=y
 CONFIG_LZ4=y
 CONFIG_ERRNO_STR=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index cb387e7..53c5bd8 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -198,6 +198,7 @@
 CONFIG_FS_CRAMFS=y
 # CONFIG_SPL_USE_TINY_PRINTF is not set
 CONFIG_CMD_DHRYSTONE=y
+CONFIG_RSA_VERIFY_WITH_PKEY=y
 CONFIG_TPM=y
 CONFIG_LZ4=y
 CONFIG_ERRNO_STR=y
diff --git a/configs/taurus_defconfig b/configs/taurus_defconfig
index 0399132..19d85f9 100644
--- a/configs/taurus_defconfig
+++ b/configs/taurus_defconfig
@@ -6,7 +6,7 @@
 # CONFIG_SPL_USE_ARCH_MEMCPY is not set
 # CONFIG_SPL_USE_ARCH_MEMSET is not set
 CONFIG_ARCH_AT91=y
-CONFIG_SPL_LDSCRIPT="arch/$(ARCH)/cpu/u-boot-spl.lds"
+CONFIG_SPL_LDSCRIPT="arch/arm/cpu/u-boot-spl.lds"
 CONFIG_SYS_TEXT_BASE=0x21000000
 CONFIG_TARGET_TAURUS=y
 CONFIG_BOARD_TAURUS=y
diff --git a/doc/board/st/stm32mp1.rst b/doc/board/st/stm32mp1.rst
index 1640bf9..b7a0fbf 100644
--- a/doc/board/st/stm32mp1.rst
+++ b/doc/board/st/stm32mp1.rst
@@ -25,6 +25,14 @@
  - Standard connectivity, widely inherited from the STM32 MCU family
  - Comprehensive security support
 
+Each line comes with a security option (cryptography & secure boot) and
+a Cortex-A frequency option:
+
+ - A : Cortex-A7 @ 650 MHz
+ - C : Secure Boot + HW Crypto + Cortex-A7 @ 650 MHz
+ - D : Cortex-A7 @ 800 MHz
+ - F : Secure Boot + HW Crypto + Cortex-A7 @ 800 MHz
+
 Everything is supported in Linux but U-Boot is limited to:
 
  1. UART
@@ -416,20 +424,26 @@
  - OTP_58[15:0] = MAC_ADDR[47:32]
 
 To program a MAC address on virgin OTP words above, you can use the fuse command
-on bank 0 to access to internal OTP:
+on bank 0 to access to internal OTP and lock them:
 
 Prerequisite: check if a MAC address isn't yet programmed in OTP
 
-1) check OTP: their value must be equal to 0
+1) check OTP: their value must be equal to 0::
 
-   STM32MP> fuse sense 0 57 2
-   Sensing bank 0:
-   Word 0x00000039: 00000000 00000000
+    STM32MP> fuse sense 0 57 2
+    Sensing bank 0:
+    Word 0x00000039: 00000000 00000000
 
-2) check environment variable
+2) check environment variable::
 
-   STM32MP> env print ethaddr
-   ## Error: "ethaddr" not defined
+    STM32MP> env print ethaddr
+    ## Error: "ethaddr" not defined
+
+3) check lock status of fuse 57 & 58 (at 0x39, 0=unlocked, 1=locked)::
+
+    STM32MP> fuse sense 0 0x10000039 2
+    Sensing bank 0:
+       Word 0x10000039: 00000000 00000000
 
 Example to set mac address "12:34:56:78:9a:bc"
 
@@ -443,11 +457,19 @@
     Sensing bank 0:
     Word 0x00000039: 78563412 0000bc9a
 
-3) next REBOOT, in the trace::
+3) Lock OTP::
+
+    STM32MP> fuse prog 0 0x10000039 1 1
+
+    STM32MP> fuse sense 0 0x10000039 2
+    Sensing bank 0:
+       Word 0x10000039: 00000001 00000001
+
+4) next REBOOT, in the trace::
 
     ### Setting environment from OTP MAC address = "12:34:56:78:9a:bc"
 
-4) check env update::
+5) check env update::
 
     STM32MP> env print ethaddr
     ethaddr=12:34:56:78:9a:bc
diff --git a/doc/device-tree-bindings/i2c/i2c-gpio.txt b/doc/device-tree-bindings/i2c/i2c-gpio.txt
index ba56ed5..b06b829 100644
--- a/doc/device-tree-bindings/i2c/i2c-gpio.txt
+++ b/doc/device-tree-bindings/i2c/i2c-gpio.txt
@@ -16,6 +16,10 @@
    The resulting transfer speed can be adjusted by setting the delay[us]
    between gpio-toggle operations. Speed [Hz] = 1000000 / 4 * udelay[us],
    It not defined, then default is 5us (~50KHz).
+* i2c-gpio,deblock
+   Run deblocking sequence when the driver gets probed.
+* i2c-gpio,scl-output-only;
+   Set if SCL is an output only
 
 Example:
 
diff --git a/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt b/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt
index ee708ce..ac6a7df 100644
--- a/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt
+++ b/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt
@@ -129,6 +129,8 @@
 		MR3
 
 - st,phy-cal	: phy cal depending of calibration or tuning of DDR
+	This parameter is optional; when it is absent the built-in PHY
+	calibration is done.
 	for STM32MP15x: 12 values are requested in this order
 		DX0DLLCR
 		DX0DQTR
diff --git a/doc/device-tree-bindings/misc/bootcounter.txt b/doc/device-tree-bindings/misc/bootcounter.txt
new file mode 100644
index 0000000..d32fbc3
--- /dev/null
+++ b/doc/device-tree-bindings/misc/bootcounter.txt
@@ -0,0 +1,21 @@
+U-Boot bootcounter Devicetree Binding
+=====================================
+
+The device tree node describes the U-Boot bootcounter
+memory based device binding.
+
+Required properties :
+
+- compatible : "u-boot,bootcount";
+- single-word : set this, if you have only one word space
+    for storing the bootcounter.
+
+Example
+-------
+
+MPC83xx based board:
+
+bootcount@0x13ff8 {
+	compatible = "u-boot,bootcount";
+	reg = <0x13ff8 0x08>;
+};
diff --git a/doc/device-tree-bindings/misc/esm-k3.txt b/doc/device-tree-bindings/misc/esm-k3.txt
new file mode 100644
index 0000000..01c8b6b
--- /dev/null
+++ b/doc/device-tree-bindings/misc/esm-k3.txt
@@ -0,0 +1,25 @@
+Texas Instruments K3 ESM Binding
+======================
+
+ESM (Error Signaling Module) is an IP block on TI K3 devices that allows
+handling of safety events somewhat similar to what interrupt controller
+would do. The safety signals have their separate paths within the SoC,
+and they are handled by the ESM, which routes them to the proper
+destination, which can be system reset, interrupt controller, etc. In
+the simplest configuration the signals are just routed to reset the
+SoC.
+
+Required properties :
+- compatible	: "ti,j721e-esm"
+- ti,esm-pins	: integer array of esm events IDs to route to external event
+		  pin which can be used to reset the SoC. The array can
+		  have arbitrary amount of event IDs listed on it.
+
+Example
+=======
+
+	main_esm: esm@700000 {
+		compatible = "ti,j721e-esm";
+		reg = <0x0 0x700000 0x0 0x1000>;
+		ti,esm-pins = <344>, <345>;
+	};
diff --git a/doc/device-tree-bindings/misc/esm-pmic.txt b/doc/device-tree-bindings/misc/esm-pmic.txt
new file mode 100644
index 0000000..a60ad74
--- /dev/null
+++ b/doc/device-tree-bindings/misc/esm-pmic.txt
@@ -0,0 +1,19 @@
+PMIC ESM Binding
+======================
+
+Certain Power Management ICs contain safety handling logic within them,
+allowing automatic reset of the board in case a safety error is signaled.
+For this purpose, ESM (Error Signal Monitor) is implemented within
+the PMIC running its own state machine.
+
+Required properties :
+- compatible	: "ti,tps659413-esm"
+
+Example
+=======
+
+&tps659413a {
+	esm: esm {
+		compatible = "ti,tps659413-esm";
+	};
+};
diff --git a/doc/device-tree-bindings/video/tilcdc/panel.txt b/doc/device-tree-bindings/video/tilcdc/panel.txt
new file mode 100644
index 0000000..8082163
--- /dev/null
+++ b/doc/device-tree-bindings/video/tilcdc/panel.txt
@@ -0,0 +1,66 @@
+Device-Tree bindings for tilcdc DRM generic panel output driver
+
+Required properties:
+ - compatible: value should be "ti,tilcdc,panel".
+ - panel-info: configuration info to configure LCDC correctly for the panel
+   - ac-bias: AC Bias Pin Frequency
+   - ac-bias-intrpt: AC Bias Pin Transitions per Interrupt
+   - dma-burst-sz: DMA burst size
+   - bpp: Bits per pixel
+   - fdd: FIFO DMA Request Delay
+   - sync-edge: Horizontal and Vertical Sync Edge: 0=rising 1=falling
+   - sync-ctrl: Horizontal and Vertical Sync: Control: 0=ignore
+   - raster-order: Raster Data Order Select: 1=Most-to-least 0=Least-to-most
+   - fifo-th: DMA FIFO threshold
+ - display-timings: typical videomode of lcd panel.  Multiple video modes
+   can be listed if the panel supports multiple timings, but the 'native-mode'
+   should be the preferred/default resolution.  Refer to
+   Documentation/devicetree/bindings/display/panel/display-timing.txt for display
+   timing binding details.
+
+Optional properties:
+- backlight: phandle of the backlight device attached to the panel
+- enable-gpios: GPIO pin to enable or disable the panel
+
+Recommended properties:
+ - pinctrl-names, pinctrl-0: the pincontrol settings to configure
+   muxing properly for pins that connect to TFP410 device
+
+Example:
+
+	/* Settings for CDTech_S035Q01 / LCD3 cape: */
+	lcd3 {
+		compatible = "ti,tilcdc,panel";
+		pinctrl-names = "default";
+		pinctrl-0 = <&bone_lcd3_cape_lcd_pins>;
+		backlight = <&backlight>;
+		enable-gpios = <&gpio3 19 0>;
+
+		panel-info {
+			ac-bias           = <255>;
+			ac-bias-intrpt    = <0>;
+			dma-burst-sz      = <16>;
+			bpp               = <16>;
+			fdd               = <0x80>;
+			sync-edge         = <0>;
+			sync-ctrl         = <1>;
+			raster-order      = <0>;
+			fifo-th           = <0>;
+		};
+		display-timings {
+			native-mode = <&timing0>;
+			timing0: 320x240 {
+				hactive         = <320>;
+				vactive         = <240>;
+				hback-porch     = <21>;
+				hfront-porch    = <58>;
+				hsync-len       = <47>;
+				vback-porch     = <11>;
+				vfront-porch    = <23>;
+				vsync-len       = <2>;
+				clock-frequency = <8000000>;
+				hsync-active    = <0>;
+				vsync-active    = <0>;
+			};
+		};
+	};
diff --git a/doc/device-tree-bindings/video/tilcdc/tilcdc.txt b/doc/device-tree-bindings/video/tilcdc/tilcdc.txt
new file mode 100644
index 0000000..7bf1bb4
--- /dev/null
+++ b/doc/device-tree-bindings/video/tilcdc/tilcdc.txt
@@ -0,0 +1,82 @@
+Device-Tree bindings for tilcdc DRM driver
+
+Required properties:
+ - compatible: value should be one of the following:
+    - "ti,am33xx-tilcdc" for AM335x based boards
+    - "ti,da850-tilcdc" for DA850/AM18x/OMAP-L138 based boards
+ - interrupts: the interrupt number
+ - reg: base address and size of the LCDC device
+
+Recommended properties:
+ - ti,hwmods: Name of the hwmod associated to the LCDC
+
+Optional properties:
+ - max-bandwidth: The maximum pixels per second that the memory
+   interface / lcd controller combination can sustain
+ - max-width: The maximum horizontal pixel width supported by
+   the lcd controller.
+ - max-pixelclock: The maximum pixel clock that can be supported
+   by the lcd controller in KHz.
+ - blue-and-red-wiring: Recognized values "straight" or "crossed".
+   This property deals with the LCDC revision 2 (found on AM335x)
+   color errata [1].
+    - "straight" indicates normal wiring that supports RGB565,
+      BGR888, and XBGR8888 color formats.
+    - "crossed" indicates wiring that has blue and red wires
+      crossed. This setup supports BGR565, RGB888 and XRGB8888
+      formats.
+    - If the property is not present or its value is not recognized
+      the legacy mode is assumed. This configuration supports RGB565,
+      RGB888 and XRGB8888 formats. However, depending on wiring, the red
+      and blue colors are swapped in either 16 or 24-bit color modes.
+
+Optional nodes:
+
+ - port/ports: to describe a connection to an external encoder. The
+   binding follows Documentation/devicetree/bindings/graph.txt and
+   supports a single port with a single endpoint.
+
+ - See also Documentation/devicetree/bindings/display/tilcdc/panel.txt and
+   Documentation/devicetree/bindings/display/tilcdc/tfp410.txt for connecting
+   tfp410 DVI encoder or lcd panel to lcdc
+
+[1] There is an errata about AM335x color wiring. For 16-bit color mode
+    the wires work as they should (LCD_DATA[0:4] is for Blue[3:7]),
+    but for 24 bit color modes the wiring of blue and red components is
+    crossed and LCD_DATA[0:4] is for Red[3:7] and LCD_DATA[11:15] is
+    for Blue[3-7]. For more details see section 3.1.1 in AM335x
+    Silicon Errata:
+    http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=sprz360
+
+Example:
+
+	fb: fb@4830e000 {
+		compatible = "ti,am33xx-tilcdc", "ti,da850-tilcdc";
+		reg = <0x4830e000 0x1000>;
+		interrupt-parent = <&intc>;
+		interrupts = <36>;
+		ti,hwmods = "lcdc";
+
+		blue-and-red-wiring = "crossed";
+
+		port {
+			lcdc_0: endpoint@0 {
+				remote-endpoint = <&hdmi_0>;
+			};
+		};
+	};
+
+	tda19988: tda19988 {
+		compatible = "nxp,tda998x";
+		reg = <0x70>;
+
+		pinctrl-names = "default", "off";
+		pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
+		pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
+
+		port {
+			hdmi_0: endpoint@0 {
+				remote-endpoint = <&lcdc_0>;
+			};
+		};
+	};
diff --git a/drivers/Makefile b/drivers/Makefile
index 23501fd..4208750 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -107,7 +107,6 @@
 obj-y += input/
 # SOC specific infrastructure drivers.
 obj-y += smem/
-obj-y += soc/
 obj-y += thermal/
 obj-$(CONFIG_TEE) += tee/
 obj-y += axi/
@@ -119,3 +118,5 @@
 obj-$(CONFIG_DM_HWSPINLOCK) += hwspinlock/
 obj-$(CONFIG_DM_RNG) += rng/
 endif
+
+obj-y += soc/
diff --git a/drivers/bootcount/Kconfig b/drivers/bootcount/Kconfig
index 0e506c9..0356f8b 100644
--- a/drivers/bootcount/Kconfig
+++ b/drivers/bootcount/Kconfig
@@ -106,6 +106,13 @@
 	  pointing to the underlying i2c eeprom device) and an optional 'offset'
 	  property are supported.
 
+config BOOTCOUNT_MEM
+	bool "Support memory based bootcounter"
+	help
+	  Enabling Memory based bootcount, typically in a SoC register which
+	  is not cleared on softreset.
+	  compatible = "u-boot,bootcount";
+
 endmenu
 
 endif
diff --git a/drivers/bootcount/Makefile b/drivers/bootcount/Makefile
index 73ccfb5..059d40d 100644
--- a/drivers/bootcount/Makefile
+++ b/drivers/bootcount/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0+
 
 obj-$(CONFIG_BOOTCOUNT_GENERIC)	+= bootcount.o
+obj-$(CONFIG_BOOTCOUNT_MEM)	+= bootcount.o
 obj-$(CONFIG_BOOTCOUNT_AT91)	+= bootcount_at91.o
 obj-$(CONFIG_BOOTCOUNT_AM33XX)	+= bootcount_davinci.o
 obj-$(CONFIG_BOOTCOUNT_RAM)	+= bootcount_ram.o
diff --git a/drivers/bootcount/bootcount.c b/drivers/bootcount/bootcount.c
index 7a6d03d..655dfaf 100644
--- a/drivers/bootcount/bootcount.c
+++ b/drivers/bootcount/bootcount.c
@@ -8,6 +8,7 @@
 #include <cpu_func.h>
 #include <linux/compiler.h>
 
+#if !defined(CONFIG_DM_BOOTCOUNT)
 /* Now implement the generic default functions */
 __weak void bootcount_store(ulong a)
 {
@@ -49,3 +50,94 @@
 		return raw_bootcount_load(reg);
 #endif /* defined(CONFIG_SYS_BOOTCOUNT_SINGLEWORD) */
 }
+#else
+#include <dm.h>
+
+/*
+ * struct bootcount_mem_priv - private bootcount mem driver data
+ *
+ * @base: base address used for bootcounter
+ * @singleword: if true use only one 32 bit word for bootcounter
+ */
+struct bootcount_mem_priv {
+	phys_addr_t base;
+	bool singleword;
+};
+
+static int bootcount_mem_get(struct udevice *dev, u32 *a)
+{
+	struct bootcount_mem_priv *priv = dev_get_priv(dev);
+	void *reg = (void *)priv->base;
+	u32 magic = CONFIG_SYS_BOOTCOUNT_MAGIC;
+
+	if (priv->singleword) {
+		u32 tmp = raw_bootcount_load(reg);
+
+		if ((tmp & 0xffff0000) != (magic & 0xffff0000))
+			return -ENODEV;
+
+		*a = (tmp & 0x0000ffff);
+	} else {
+		if (raw_bootcount_load(reg + 4) != magic)
+			return -ENODEV;
+
+		*a = raw_bootcount_load(reg);
+	}
+
+	return 0;
+};
+
+static int bootcount_mem_set(struct udevice *dev, const u32 a)
+{
+	struct bootcount_mem_priv *priv = dev_get_priv(dev);
+	void *reg = (void *)priv->base;
+	u32 magic = CONFIG_SYS_BOOTCOUNT_MAGIC;
+	uintptr_t flush_start = rounddown(priv->base,
+					  CONFIG_SYS_CACHELINE_SIZE);
+	uintptr_t flush_end;
+
+	if (priv->singleword) {
+		raw_bootcount_store(reg, (magic & 0xffff0000) | a);
+		flush_end = roundup(priv->base + 4,
+				    CONFIG_SYS_CACHELINE_SIZE);
+	} else {
+		raw_bootcount_store(reg, a);
+		raw_bootcount_store(reg + 4, magic);
+		flush_end = roundup(priv->base + 8,
+				    CONFIG_SYS_CACHELINE_SIZE);
+	}
+	flush_dcache_range(flush_start, flush_end);
+
+	return 0;
+};
+
+static const struct bootcount_ops bootcount_mem_ops = {
+	.get = bootcount_mem_get,
+	.set = bootcount_mem_set,
+};
+
+static int bootcount_mem_probe(struct udevice *dev)
+{
+	struct bootcount_mem_priv *priv = dev_get_priv(dev);
+
+	priv->base = (phys_addr_t)dev_read_addr(dev);
+	if (dev_read_bool(dev, "single-word"))
+		priv->singleword = true;
+
+	return 0;
+}
+
+static const struct udevice_id bootcount_mem_ids[] = {
+	{ .compatible = "u-boot,bootcount" },
+	{ }
+};
+
+U_BOOT_DRIVER(bootcount_mem) = {
+	.name	= "bootcount-mem",
+	.id	= UCLASS_BOOTCOUNT,
+	.priv_auto_alloc_size = sizeof(struct bootcount_mem_priv),
+	.probe	= bootcount_mem_probe,
+	.of_match = bootcount_mem_ids,
+	.ops	= &bootcount_mem_ops,
+};
+#endif
diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c
index fd8c821..52bd8e9 100644
--- a/drivers/clk/clk_stm32mp1.c
+++ b/drivers/clk/clk_stm32mp1.c
@@ -95,6 +95,7 @@
 #define RCC_I2C12CKSELR		0x8C0
 #define RCC_I2C35CKSELR		0x8C4
 #define RCC_SPI2S1CKSELR	0x8D8
+#define RCC_SPI45CKSELR		0x8E0
 #define RCC_UART6CKSELR		0x8E4
 #define RCC_UART24CKSELR	0x8E8
 #define RCC_UART35CKSELR	0x8EC
@@ -304,6 +305,7 @@
 	_DSI_SEL,
 	_ADC12_SEL,
 	_SPI1_SEL,
+	_SPI45_SEL,
 	_RTC_SEL,
 	_PARENT_SEL_NB,
 	_UNKNOWN_SEL = 0xff,
@@ -527,6 +529,7 @@
 	STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 24, I2C5_K, _I2C35_SEL),
 
 	STM32MP1_CLK_SET_CLR(RCC_MP_APB2ENSETR, 8, SPI1_K, _SPI1_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_APB2ENSETR, 10, SPI5_K, _SPI45_SEL),
 	STM32MP1_CLK_SET_CLR(RCC_MP_APB2ENSETR, 13, USART6_K, _UART6_SEL),
 
 	STM32MP1_CLK_SET_CLR_F(RCC_MP_APB3ENSETR, 13, VREF, _PCLK3),
@@ -603,6 +606,8 @@
 static const u8 adc_parents[] = {_PLL4_R, _CK_PER, _PLL3_Q};
 static const u8 spi_parents[] = {_PLL4_P, _PLL3_Q, _I2S_CKIN, _CK_PER,
 				 _PLL3_R};
+static const u8 spi45_parents[] = {_PCLK2, _PLL4_Q, _HSI_KER, _CSI_KER,
+				   _HSE_KER};
 static const u8 rtc_parents[] = {_UNKNOWN_ID, _LSE, _LSI, _HSE};
 
 static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = {
@@ -621,14 +626,15 @@
 	STM32MP1_CLK_PARENT(_SDMMC3_SEL, RCC_SDMMC3CKSELR, 0, 0x7,
 			    sdmmc3_parents),
 	STM32MP1_CLK_PARENT(_ETH_SEL, RCC_ETHCKSELR, 0, 0x3, eth_parents),
-	STM32MP1_CLK_PARENT(_QSPI_SEL, RCC_QSPICKSELR, 0, 0xf, qspi_parents),
-	STM32MP1_CLK_PARENT(_FMC_SEL, RCC_FMCCKSELR, 0, 0xf, fmc_parents),
+	STM32MP1_CLK_PARENT(_QSPI_SEL, RCC_QSPICKSELR, 0, 0x3, qspi_parents),
+	STM32MP1_CLK_PARENT(_FMC_SEL, RCC_FMCCKSELR, 0, 0x3, fmc_parents),
 	STM32MP1_CLK_PARENT(_USBPHY_SEL, RCC_USBCKSELR, 0, 0x3, usbphy_parents),
 	STM32MP1_CLK_PARENT(_USBO_SEL, RCC_USBCKSELR, 4, 0x1, usbo_parents),
 	STM32MP1_CLK_PARENT(_STGEN_SEL, RCC_STGENCKSELR, 0, 0x3, stgen_parents),
 	STM32MP1_CLK_PARENT(_DSI_SEL, RCC_DSICKSELR, 0, 0x1, dsi_parents),
-	STM32MP1_CLK_PARENT(_ADC12_SEL, RCC_ADCCKSELR, 0, 0x1, adc_parents),
+	STM32MP1_CLK_PARENT(_ADC12_SEL, RCC_ADCCKSELR, 0, 0x3, adc_parents),
 	STM32MP1_CLK_PARENT(_SPI1_SEL, RCC_SPI2S1CKSELR, 0, 0x7, spi_parents),
+	STM32MP1_CLK_PARENT(_SPI45_SEL, RCC_SPI45CKSELR, 0, 0x7, spi45_parents),
 	STM32MP1_CLK_PARENT(_RTC_SEL, RCC_BDCR, RCC_BDCR_RTCSRC_SHIFT,
 			    (RCC_BDCR_RTCSRC_MASK >> RCC_BDCR_RTCSRC_SHIFT),
 			    rtc_parents),
@@ -747,6 +753,7 @@
 	[_DSI_SEL] = "DSI",
 	[_ADC12_SEL] = "ADC12",
 	[_SPI1_SEL] = "SPI1",
+	[_SPI45_SEL] = "SPI45",
 	[_RTC_SEL] = "RTC",
 };
 
diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
index e587f1f..a0e536a 100644
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -938,7 +938,9 @@
 
 	req.valid_params = TI_SCI_MSG_VALUE_RM_UDMAP_CH_FETCH_SIZE_VALID |
 			TI_SCI_MSG_VALUE_RM_UDMAP_CH_CQ_QNUM_VALID |
-			TI_SCI_MSG_VALUE_RM_UDMAP_CH_CHAN_TYPE_VALID;
+			TI_SCI_MSG_VALUE_RM_UDMAP_CH_CHAN_TYPE_VALID |
+			TI_SCI_MSG_VALUE_RM_UDMAP_CH_RX_FLOWID_START_VALID |
+			TI_SCI_MSG_VALUE_RM_UDMAP_CH_RX_FLOWID_CNT_VALID;
 	req.nav_id = tisci_rm->tisci_dev_id;
 	req.index = uc->rchan->id;
 	req.rx_chan_type = mode;
@@ -954,9 +956,6 @@
 	if (uc->rflow->id != uc->rchan->id && uc->dir != DMA_MEM_TO_MEM) {
 		req.flowid_start = uc->rflow->id;
 		req.flowid_cnt = 1;
-		req.valid_params |=
-			TI_SCI_MSG_VALUE_RM_UDMAP_CH_RX_FLOWID_START_VALID |
-			TI_SCI_MSG_VALUE_RM_UDMAP_CH_RX_FLOWID_CNT_VALID;
 	}
 
 	ret = tisci_rm->tisci_udmap_ops->rx_ch_cfg(tisci_rm->tisci, &req);
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index 99b2e5d..c3f95b2 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -2364,82 +2364,6 @@
 	return ret;
 }
 
-/**
- * ti_sci_cmd_ring_get_config() - get RA ring configuration
- * @handle:	pointer to TI SCI handle
- * @nav_id: Device ID of Navigator Subsystem from which the ring is allocated
- * @index: Ring index.
- * @addr_lo: returns ring's base address lo 32 bits
- * @addr_hi: returns ring's base address hi 32 bits
- * @count: returns number of ring elements.
- * @mode: returns mode of the ring
- * @size: returns ring element size.
- * @order_id: returns ring's bus order ID.
- *
- * Return: 0 if all went well, else returns appropriate error value.
- *
- * See @ti_sci_msg_rm_ring_get_cfg_req for more info.
- */
-static int ti_sci_cmd_ring_get_config(const struct ti_sci_handle *handle,
-				      u32 nav_id, u32 index, u8 *mode,
-				      u32 *addr_lo, u32 *addr_hi,
-				      u32 *count, u8 *size, u8 *order_id)
-{
-	struct ti_sci_msg_rm_ring_get_cfg_resp *resp;
-	struct ti_sci_msg_rm_ring_get_cfg_req req;
-	struct ti_sci_xfer *xfer;
-	struct ti_sci_info *info;
-	int ret = 0;
-
-	if (IS_ERR(handle))
-		return PTR_ERR(handle);
-	if (!handle)
-		return -EINVAL;
-
-	info = handle_to_ti_sci_info(handle);
-
-	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_RM_RING_GET_CFG,
-				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
-				     (u32 *)&req, sizeof(req), sizeof(*resp));
-	if (IS_ERR(xfer)) {
-		ret = PTR_ERR(xfer);
-		dev_err(info->dev,
-			"RM_RA:Message get config failed(%d)\n", ret);
-		return ret;
-	}
-	req.nav_id = nav_id;
-	req.index = index;
-
-	ret = ti_sci_do_xfer(info, xfer);
-	if (ret) {
-		dev_err(info->dev, "RM_RA:Mbox get config send fail %d\n", ret);
-		goto fail;
-	}
-
-	resp = (struct ti_sci_msg_rm_ring_get_cfg_resp *)xfer->tx_message.buf;
-
-	if (!ti_sci_is_response_ack(resp)) {
-		ret = -ENODEV;
-	} else {
-		if (mode)
-			*mode = resp->mode;
-		if (addr_lo)
-			*addr_lo = resp->addr_lo;
-		if (addr_hi)
-			*addr_hi = resp->addr_hi;
-		if (count)
-			*count = resp->count;
-		if (size)
-			*size = resp->size;
-		if (order_id)
-			*order_id = resp->order_id;
-	};
-
-fail:
-	dev_dbg(info->dev, "RM_RA:get config ring %u ret:%d\n", index, ret);
-	return ret;
-}
-
 static int ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle *handle,
 				   u32 nav_id, u32 src_thread, u32 dst_thread)
 {
@@ -2948,7 +2872,6 @@
 	pops->proc_shutdown_no_wait = ti_sci_cmd_proc_shutdown_no_wait;
 
 	rops->config = ti_sci_cmd_ring_config;
-	rops->get_config = ti_sci_cmd_ring_get_config;
 
 	psilops->pair = ti_sci_cmd_rm_psil_pair;
 	psilops->unpair = ti_sci_cmd_rm_psil_unpair;
diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h
index 69ff74d..24b4d1c 100644
--- a/drivers/firmware/ti_sci.h
+++ b/drivers/firmware/ti_sci.h
@@ -58,7 +58,6 @@
 /* NAVSS resource management */
 /* Ringacc requests */
 #define TI_SCI_MSG_RM_RING_CFG			0x1110
-#define TI_SCI_MSG_RM_RING_GET_CFG		0x1111
 
 /* PSI-L requests */
 #define TI_SCI_MSG_RM_PSIL_PAIR			0x1280
@@ -72,13 +71,9 @@
 #define TI_SCI_MSG_RM_UDMAP_OPT_FLOW_CFG	0x1221
 
 #define TISCI_MSG_RM_UDMAP_TX_CH_CFG		0x1205
-#define TISCI_MSG_RM_UDMAP_TX_CH_GET_CFG	0x1206
 #define TISCI_MSG_RM_UDMAP_RX_CH_CFG		0x1215
-#define TISCI_MSG_RM_UDMAP_RX_CH_GET_CFG	0x1216
 #define TISCI_MSG_RM_UDMAP_FLOW_CFG		0x1230
 #define TISCI_MSG_RM_UDMAP_FLOW_SIZE_THRESH_CFG	0x1231
-#define TISCI_MSG_RM_UDMAP_FLOW_GET_CFG		0x1232
-#define TISCI_MSG_RM_UDMAP_FLOW_SIZE_THRESH_GET_CFG	0x1233
 
 #define TISCI_MSG_FWL_SET		0x9000
 #define TISCI_MSG_FWL_GET		0x9001
diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c
index 0b5e70a..088a6f3 100644
--- a/drivers/i2c/designware_i2c.c
+++ b/drivers/i2c/designware_i2c.c
@@ -203,14 +203,16 @@
 	const struct dw_scl_sda_cfg *scl_sda_cfg = NULL;
 	struct i2c_regs *regs = priv->regs;
 	enum i2c_speed_mode i2c_spd;
+	u32 comp_param1;
 	int spk_cnt;
 	int ret;
 
+	comp_param1 = readl(&regs->comp_param1);
+
 	if (priv)
 		scl_sda_cfg = priv->scl_sda_cfg;
 	/* Allow high speed if there is no config, or the config allows it */
-	if (speed >= I2C_SPEED_HIGH_RATE &&
-	    (!scl_sda_cfg || scl_sda_cfg->has_high_speed))
+	if (speed >= I2C_SPEED_HIGH_RATE)
 		i2c_spd = IC_SPEED_MODE_HIGH;
 	else if (speed >= I2C_SPEED_FAST_PLUS_RATE)
 		i2c_spd = IC_SPEED_MODE_FAST_PLUS;
@@ -219,6 +221,13 @@
 	else
 		i2c_spd = IC_SPEED_MODE_STANDARD;
 
+	/* Check is high speed possible and fall back to fast mode if not */
+	if (i2c_spd == IC_SPEED_MODE_HIGH) {
+		if ((comp_param1 & DW_IC_COMP_PARAM_1_SPEED_MODE_MASK)
+				!= DW_IC_COMP_PARAM_1_SPEED_MODE_HIGH)
+			i2c_spd = IC_SPEED_MODE_FAST;
+	}
+
 	/* Get the proper spike-suppression count based on target speed */
 	if (!priv || !priv->has_spk_cnt)
 		spk_cnt = 0;
@@ -231,6 +240,9 @@
 		if (i2c_spd == IC_SPEED_MODE_STANDARD) {
 			config->scl_hcnt = scl_sda_cfg->ss_hcnt;
 			config->scl_lcnt = scl_sda_cfg->ss_lcnt;
+		} else if (i2c_spd == IC_SPEED_MODE_HIGH) {
+			config->scl_hcnt = scl_sda_cfg->hs_hcnt;
+			config->scl_lcnt = scl_sda_cfg->hs_lcnt;
 		} else {
 			config->scl_hcnt = scl_sda_cfg->fs_hcnt;
 			config->scl_lcnt = scl_sda_cfg->fs_lcnt;
@@ -274,7 +286,7 @@
 
 	switch (config.speed_mode) {
 	case IC_SPEED_MODE_HIGH:
-		cntl |= IC_CON_SPD_SS;
+		cntl |= IC_CON_SPD_HS;
 		writel(config.scl_hcnt, &i2c_base->ic_hs_scl_hcnt);
 		writel(config.scl_lcnt, &i2c_base->ic_hs_scl_lcnt);
 		break;
diff --git a/drivers/i2c/designware_i2c.h b/drivers/i2c/designware_i2c.h
index 61a882c..7ee2361 100644
--- a/drivers/i2c/designware_i2c.h
+++ b/drivers/i2c/designware_i2c.h
@@ -138,22 +138,27 @@
 #define IC_STATUS_TFNF		0x0002
 #define IC_STATUS_ACT		0x0001
 
+#define DW_IC_COMP_PARAM_1_SPEED_MODE_HIGH      (BIT(2) | BIT(3))
+#define DW_IC_COMP_PARAM_1_SPEED_MODE_MASK      (BIT(2) | BIT(3))
+
 /**
  * struct dw_scl_sda_cfg - I2C timing configuration
  *
- * @has_high_speed: Support high speed (3.4Mbps)
  * @ss_hcnt: Standard speed high time in ns
  * @fs_hcnt: Fast speed high time in ns
+ * @hs_hcnt: High speed high time in ns
  * @ss_lcnt: Standard speed low time in ns
  * @fs_lcnt: Fast speed low time in ns
+ * @hs_lcnt: High speed low time in ns
  * @sda_hold: SDA hold time
  */
 struct dw_scl_sda_cfg {
-	bool has_high_speed;
 	u32 ss_hcnt;
 	u32 fs_hcnt;
+	u32 hs_hcnt;
 	u32 ss_lcnt;
 	u32 fs_lcnt;
+	u32 hs_lcnt;
 	u32 sda_hold;
 };
 
diff --git a/drivers/i2c/i2c-gpio.c b/drivers/i2c/i2c-gpio.c
index 4e8fa21..07fdd34 100644
--- a/drivers/i2c/i2c-gpio.c
+++ b/drivers/i2c/i2c-gpio.c
@@ -32,23 +32,50 @@
 	int udelay;
 	 /* sda, scl */
 	struct gpio_desc gpios[PIN_COUNT];
+
+	int (*get_sda)(struct i2c_gpio_bus *bus);
+	void (*set_sda)(struct i2c_gpio_bus *bus, int bit);
+	void (*set_scl)(struct i2c_gpio_bus *bus, int bit);
 };
 
-static int i2c_gpio_sda_get(struct gpio_desc *sda)
+static int i2c_gpio_sda_get(struct i2c_gpio_bus *bus)
 {
+	struct gpio_desc *sda = &bus->gpios[PIN_SDA];
+
 	return dm_gpio_get_value(sda);
 }
 
-static void i2c_gpio_sda_set(struct gpio_desc *sda, int bit)
+static void i2c_gpio_sda_set(struct i2c_gpio_bus *bus, int bit)
 {
+	struct gpio_desc *sda = &bus->gpios[PIN_SDA];
+
 	if (bit)
 		dm_gpio_set_dir_flags(sda, GPIOD_IS_IN);
 	else
 		dm_gpio_set_dir_flags(sda, GPIOD_IS_OUT);
 }
 
-static void i2c_gpio_scl_set(struct gpio_desc *scl, int bit)
+static void i2c_gpio_scl_set(struct i2c_gpio_bus *bus, int bit)
 {
+	struct gpio_desc *scl = &bus->gpios[PIN_SCL];
+	int count = 0;
+
+	if (bit) {
+		dm_gpio_set_dir_flags(scl, GPIOD_IS_IN);
+		while (!dm_gpio_get_value(scl) && count++ < 100000)
+			udelay(1);
+
+		if (!dm_gpio_get_value(scl))
+			pr_err("timeout waiting on slave to release scl\n");
+	} else {
+		dm_gpio_set_dir_flags(scl, GPIOD_IS_OUT);
+	}
+}
+
+/* variant for output only gpios which cannot support clock stretching */
+static void i2c_gpio_scl_set_output_only(struct i2c_gpio_bus *bus, int bit)
+{
+	struct gpio_desc *scl = &bus->gpios[PIN_SCL];
 	ulong flags = GPIOD_IS_OUT;
 
 	if (bit)
@@ -56,65 +83,60 @@
 	dm_gpio_set_dir_flags(scl, flags);
 }
 
-static void i2c_gpio_write_bit(struct gpio_desc *scl, struct gpio_desc *sda,
-			       int delay, uchar bit)
+static void i2c_gpio_write_bit(struct i2c_gpio_bus *bus, int delay, uchar bit)
 {
-	i2c_gpio_scl_set(scl, 0);
+	bus->set_scl(bus, 0);
 	udelay(delay);
-	i2c_gpio_sda_set(sda, bit);
+	bus->set_sda(bus, bit);
 	udelay(delay);
-	i2c_gpio_scl_set(scl, 1);
+	bus->set_scl(bus, 1);
 	udelay(2 * delay);
 }
 
-static int i2c_gpio_read_bit(struct gpio_desc *scl, struct gpio_desc *sda,
-			     int delay)
+static int i2c_gpio_read_bit(struct i2c_gpio_bus *bus, int delay)
 {
 	int value;
 
-	i2c_gpio_scl_set(scl, 1);
+	bus->set_scl(bus, 1);
 	udelay(delay);
-	value = i2c_gpio_sda_get(sda);
+	value = bus->get_sda(bus);
 	udelay(delay);
-	i2c_gpio_scl_set(scl, 0);
+	bus->set_scl(bus, 0);
 	udelay(2 * delay);
 
 	return value;
 }
 
 /* START: High -> Low on SDA while SCL is High */
-static void i2c_gpio_send_start(struct gpio_desc *scl, struct gpio_desc *sda,
-				int delay)
+static void i2c_gpio_send_start(struct i2c_gpio_bus *bus, int delay)
 {
 	udelay(delay);
-	i2c_gpio_sda_set(sda, 1);
+	bus->set_sda(bus, 1);
 	udelay(delay);
-	i2c_gpio_scl_set(scl, 1);
+	bus->set_scl(bus, 1);
 	udelay(delay);
-	i2c_gpio_sda_set(sda, 0);
+	bus->set_sda(bus, 0);
 	udelay(delay);
 }
 
 /* STOP: Low -> High on SDA while SCL is High */
-static void i2c_gpio_send_stop(struct gpio_desc *scl, struct gpio_desc *sda,
-			       int delay)
+static void i2c_gpio_send_stop(struct i2c_gpio_bus *bus, int delay)
 {
-	i2c_gpio_scl_set(scl, 0);
+	bus->set_scl(bus, 0);
 	udelay(delay);
-	i2c_gpio_sda_set(sda, 0);
+	bus->set_sda(bus, 0);
 	udelay(delay);
-	i2c_gpio_scl_set(scl, 1);
+	bus->set_scl(bus, 1);
 	udelay(delay);
-	i2c_gpio_sda_set(sda, 1);
+	bus->set_sda(bus, 1);
 	udelay(delay);
 }
 
 /* ack should be I2C_ACK or I2C_NOACK */
-static void i2c_gpio_send_ack(struct gpio_desc *scl, struct gpio_desc *sda,
-			      int delay, int ack)
+static void i2c_gpio_send_ack(struct i2c_gpio_bus *bus, int delay, int ack)
 {
-	i2c_gpio_write_bit(scl, sda, delay, ack);
-	i2c_gpio_scl_set(scl, 0);
+	i2c_gpio_write_bit(bus, delay, ack);
+	bus->set_scl(bus, 0);
 	udelay(delay);
 }
 
@@ -123,44 +145,41 @@
  * to clock any confused device back into an idle state.  Also send a
  * <stop> at the end of the sequence for belts & suspenders.
  */
-static void i2c_gpio_send_reset(struct gpio_desc *scl, struct gpio_desc *sda,
-				int delay)
+static void i2c_gpio_send_reset(struct i2c_gpio_bus *bus, int delay)
 {
 	int j;
 
 	for (j = 0; j < 9; j++)
-		i2c_gpio_write_bit(scl, sda, delay, 1);
+		i2c_gpio_write_bit(bus, delay, 1);
 
-	i2c_gpio_send_stop(scl, sda, delay);
+	i2c_gpio_send_stop(bus, delay);
 }
 
 /* Set sda high with low clock, before reading slave data */
-static void i2c_gpio_sda_high(struct gpio_desc *scl, struct gpio_desc *sda,
-			      int delay)
+static void i2c_gpio_sda_high(struct i2c_gpio_bus *bus, int delay)
 {
-	i2c_gpio_scl_set(scl, 0);
+	bus->set_scl(bus, 0);
 	udelay(delay);
-	i2c_gpio_sda_set(sda, 1);
+	bus->set_sda(bus, 1);
 	udelay(delay);
 }
 
 /* Send 8 bits and look for an acknowledgement */
-static int i2c_gpio_write_byte(struct gpio_desc *scl, struct gpio_desc *sda,
-			       int delay, uchar data)
+static int i2c_gpio_write_byte(struct i2c_gpio_bus *bus, int delay, uchar data)
 {
 	int j;
 	int nack;
 
 	for (j = 0; j < 8; j++) {
-		i2c_gpio_write_bit(scl, sda, delay, data & 0x80);
+		i2c_gpio_write_bit(bus, delay, data & 0x80);
 		data <<= 1;
 	}
 
 	udelay(delay);
 
 	/* Look for an <ACK>(negative logic) and return it */
-	i2c_gpio_sda_high(scl, sda, delay);
-	nack = i2c_gpio_read_bit(scl, sda, delay);
+	i2c_gpio_sda_high(bus, delay);
+	nack = i2c_gpio_read_bit(bus, delay);
 
 	return nack;	/* not a nack is an ack */
 }
@@ -169,31 +188,29 @@
  * if ack == I2C_ACK, ACK the byte so can continue reading, else
  * send I2C_NOACK to end the read.
  */
-static uchar i2c_gpio_read_byte(struct gpio_desc *scl, struct gpio_desc *sda,
-				int delay, int ack)
+static uchar i2c_gpio_read_byte(struct i2c_gpio_bus *bus, int delay, int ack)
 {
 	int  data;
 	int  j;
 
-	i2c_gpio_sda_high(scl, sda, delay);
+	i2c_gpio_sda_high(bus, delay);
 	data = 0;
 	for (j = 0; j < 8; j++) {
 		data <<= 1;
-		data |= i2c_gpio_read_bit(scl, sda, delay);
+		data |= i2c_gpio_read_bit(bus, delay);
 	}
-	i2c_gpio_send_ack(scl, sda, delay, ack);
+	i2c_gpio_send_ack(bus, delay, ack);
 
 	return data;
 }
 
 /* send start and the slave chip address */
-int i2c_send_slave_addr(struct gpio_desc *scl, struct gpio_desc *sda, int delay,
-			uchar chip)
+int i2c_send_slave_addr(struct i2c_gpio_bus *bus, int delay, uchar chip)
 {
-	i2c_gpio_send_start(scl, sda, delay);
+	i2c_gpio_send_start(bus, delay);
 
-	if (i2c_gpio_write_byte(scl, sda, delay, chip)) {
-		i2c_gpio_send_stop(scl, sda, delay);
+	if (i2c_gpio_write_byte(bus, delay, chip)) {
+		i2c_gpio_send_stop(bus, delay);
 		return -EIO;
 	}
 
@@ -204,29 +221,27 @@
 			       uchar *buffer, int len,
 			       bool end_with_repeated_start)
 {
-	struct gpio_desc *scl = &bus->gpios[PIN_SCL];
-	struct gpio_desc *sda = &bus->gpios[PIN_SDA];
 	unsigned int delay = bus->udelay;
 	int failures = 0;
 
 	debug("%s: chip %x buffer %p len %d\n", __func__, chip, buffer, len);
 
-	if (i2c_send_slave_addr(scl, sda, delay, chip << 1)) {
+	if (i2c_send_slave_addr(bus, delay, chip << 1)) {
 		debug("i2c_write, no chip responded %02X\n", chip);
 		return -EIO;
 	}
 
 	while (len-- > 0) {
-		if (i2c_gpio_write_byte(scl, sda, delay, *buffer++))
+		if (i2c_gpio_write_byte(bus, delay, *buffer++))
 			failures++;
 	}
 
 	if (!end_with_repeated_start) {
-		i2c_gpio_send_stop(scl, sda, delay);
+		i2c_gpio_send_stop(bus, delay);
 		return failures;
 	}
 
-	if (i2c_send_slave_addr(scl, sda, delay, (chip << 1) | 0x1)) {
+	if (i2c_send_slave_addr(bus, delay, (chip << 1) | 0x1)) {
 		debug("i2c_write, no chip responded %02X\n", chip);
 		return -EIO;
 	}
@@ -237,16 +252,14 @@
 static int i2c_gpio_read_data(struct i2c_gpio_bus *bus, uchar chip,
 			      uchar *buffer, int len)
 {
-	struct gpio_desc *scl = &bus->gpios[PIN_SCL];
-	struct gpio_desc *sda = &bus->gpios[PIN_SDA];
 	unsigned int delay = bus->udelay;
 
 	debug("%s: chip %x buffer: %p len %d\n", __func__, chip, buffer, len);
 
 	while (len-- > 0)
-		*buffer++ = i2c_gpio_read_byte(scl, sda, delay, len == 0);
+		*buffer++ = i2c_gpio_read_byte(bus, delay, len == 0);
 
-	i2c_gpio_send_stop(scl, sda, delay);
+	i2c_gpio_send_stop(bus, delay);
 
 	return 0;
 }
@@ -277,14 +290,12 @@
 static int i2c_gpio_probe(struct udevice *dev, uint chip, uint chip_flags)
 {
 	struct i2c_gpio_bus *bus = dev_get_priv(dev);
-	struct gpio_desc *scl = &bus->gpios[PIN_SCL];
-	struct gpio_desc *sda = &bus->gpios[PIN_SDA];
 	unsigned int delay = bus->udelay;
 	int ret;
 
-	i2c_gpio_send_start(scl, sda, delay);
-	ret = i2c_gpio_write_byte(scl, sda, delay, (chip << 1) | 0);
-	i2c_gpio_send_stop(scl, sda, delay);
+	i2c_gpio_send_start(bus, delay);
+	ret = i2c_gpio_write_byte(bus, delay, (chip << 1) | 0);
+	i2c_gpio_send_stop(bus, delay);
 
 	debug("%s: bus: %d (%s) chip: %x flags: %x ret: %d\n",
 	      __func__, dev->seq, dev->name, chip, chip_flags, ret);
@@ -295,12 +306,25 @@
 static int i2c_gpio_set_bus_speed(struct udevice *dev, unsigned int speed_hz)
 {
 	struct i2c_gpio_bus *bus = dev_get_priv(dev);
-	struct gpio_desc *scl = &bus->gpios[PIN_SCL];
-	struct gpio_desc *sda = &bus->gpios[PIN_SDA];
 
 	bus->udelay = 1000000 / (speed_hz << 2);
 
-	i2c_gpio_send_reset(scl, sda, bus->udelay);
+	i2c_gpio_send_reset(bus, bus->udelay);
+
+	return 0;
+}
+
+static int i2c_gpio_drv_probe(struct udevice *dev)
+{
+	if (dev_read_bool(dev, "i2c-gpio,deblock")) {
+		/* @200kHz 9 clocks = 44us, 62us is ok */
+		const unsigned int DELAY_ABORT_SEQ = 62;
+		struct i2c_gpio_bus *bus = dev_get_priv(dev);
+
+		return i2c_deblock_gpio_loop(&bus->gpios[PIN_SDA],
+					     &bus->gpios[PIN_SCL],
+					     16, 5, DELAY_ABORT_SEQ);
+	}
 
 	return 0;
 }
@@ -320,6 +344,13 @@
 	bus->udelay = fdtdec_get_int(blob, node, "i2c-gpio,delay-us",
 				     DEFAULT_UDELAY);
 
+	bus->get_sda = i2c_gpio_sda_get;
+	bus->set_sda = i2c_gpio_sda_set;
+	if (fdtdec_get_bool(blob, node, "i2c-gpio,scl-output-only"))
+		bus->set_scl = i2c_gpio_scl_set_output_only;
+	else
+		bus->set_scl = i2c_gpio_scl_set;
+
 	return 0;
 error:
 	pr_err("Can't get %s gpios! Error: %d", dev->name, ret);
@@ -341,6 +372,7 @@
 	.name	= "i2c-gpio",
 	.id	= UCLASS_I2C,
 	.of_match = i2c_gpio_ids,
+	.probe	= i2c_gpio_drv_probe,
 	.ofdata_to_platdata = i2c_gpio_ofdata_to_platdata,
 	.priv_auto_alloc_size = sizeof(struct i2c_gpio_bus),
 	.ops	= &i2c_gpio_ops,
diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c
index 2aa3efe..e9ec388 100644
--- a/drivers/i2c/i2c-uclass.c
+++ b/drivers/i2c/i2c-uclass.c
@@ -501,35 +501,53 @@
 	return dm_gpio_get_value(pin);
 }
 
-static int i2c_deblock_gpio_loop(struct gpio_desc *sda_pin,
-				 struct gpio_desc *scl_pin)
+int i2c_deblock_gpio_loop(struct gpio_desc *sda_pin,
+			  struct gpio_desc *scl_pin,
+			  unsigned int scl_count,
+			  unsigned int start_count,
+			  unsigned int delay)
 {
-	int counter = 9;
-	int ret = 0;
+	int i, ret = -EREMOTEIO;
 
 	i2c_gpio_set_pin(sda_pin, 1);
 	i2c_gpio_set_pin(scl_pin, 1);
-	udelay(5);
+	udelay(delay);
 
 	/*  Toggle SCL until slave release SDA */
-	while (counter-- >= 0) {
+	while (scl_count-- >= 0) {
 		i2c_gpio_set_pin(scl_pin, 1);
-		udelay(5);
+		udelay(delay);
 		i2c_gpio_set_pin(scl_pin, 0);
-		udelay(5);
-		if (i2c_gpio_get_pin(sda_pin))
+		udelay(delay);
+		if (i2c_gpio_get_pin(sda_pin)) {
+			ret = 0;
 			break;
+		}
+	}
+
+	if (!ret && start_count) {
+		for (i = 0; i < start_count; i++) {
+			/* Send start condition */
+			udelay(delay);
+			i2c_gpio_set_pin(sda_pin, 1);
+			udelay(delay);
+			i2c_gpio_set_pin(scl_pin, 1);
+			udelay(delay);
+			i2c_gpio_set_pin(sda_pin, 0);
+			udelay(delay);
+			i2c_gpio_set_pin(scl_pin, 0);
+		}
 	}
 
 	/* Then, send I2C stop */
 	i2c_gpio_set_pin(sda_pin, 0);
-	udelay(5);
+	udelay(delay);
 
 	i2c_gpio_set_pin(scl_pin, 1);
-	udelay(5);
+	udelay(delay);
 
 	i2c_gpio_set_pin(sda_pin, 1);
-	udelay(5);
+	udelay(delay);
 
 	if (!i2c_gpio_get_pin(sda_pin) || !i2c_gpio_get_pin(scl_pin))
 		ret = -EREMOTEIO;
@@ -561,7 +579,7 @@
 		goto out_no_pinctrl;
 	}
 
-	ret0 = i2c_deblock_gpio_loop(&gpios[PIN_SDA], &gpios[PIN_SCL]);
+	ret0 = i2c_deblock_gpio_loop(&gpios[PIN_SDA], &gpios[PIN_SCL], 9, 0, 5);
 
 	ret = pinctrl_select_state(bus, "default");
 	if (ret) {
diff --git a/drivers/i2c/stm32f7_i2c.c b/drivers/i2c/stm32f7_i2c.c
index 7d046c1..fc5c122 100644
--- a/drivers/i2c/stm32f7_i2c.c
+++ b/drivers/i2c/stm32f7_i2c.c
@@ -7,10 +7,10 @@
 #include <clk.h>
 #include <dm.h>
 #include <i2c.h>
-#include <malloc.h>
 #include <reset.h>
 
 #include <dm/device.h>
+#include <linux/err.h>
 #include <linux/io.h>
 
 /* STM32 I2C registers */
@@ -145,7 +145,6 @@
 
 /**
  * struct stm32_i2c_setup - private I2C timing setup parameters
- * @speed: I2C speed mode (standard, Fast Plus)
  * @speed_freq: I2C speed frequency  (Hz)
  * @clock_src: I2C clock source frequency (Hz)
  * @rise_time: Rise time (ns)
@@ -154,7 +153,6 @@
  * @analog_filter: Analog filter delay (On/Off)
  */
 struct stm32_i2c_setup {
-	enum i2c_speed_mode speed;
 	u32 speed_freq;
 	u32 clock_src;
 	u32 rise_time;
@@ -184,10 +182,11 @@
 	struct stm32_i2c_regs *regs;
 	struct clk clk;
 	struct stm32_i2c_setup *setup;
-	int speed;
+	u32 speed;
 };
 
 static const struct stm32_i2c_spec i2c_specs[] = {
+	/* Standard speed - 100 KHz */
 	[IC_SPEED_MODE_STANDARD] = {
 		.rate = I2C_SPEED_STANDARD_RATE,
 		.rate_min = 8000,
@@ -200,6 +199,7 @@
 		.l_min = 4700,
 		.h_min = 4000,
 	},
+	/* Fast speed - 400 KHz */
 	[IC_SPEED_MODE_FAST] = {
 		.rate = I2C_SPEED_FAST_RATE,
 		.rate_min = 320000,
@@ -212,6 +212,7 @@
 		.l_min = 1300,
 		.h_min = 600,
 	},
+	/* Fast Plus Speed - 1 MHz */
 	[IC_SPEED_MODE_FAST_PLUS] = {
 		.rate = I2C_SPEED_FAST_PLUS_RATE,
 		.rate_min = 800000,
@@ -474,6 +475,7 @@
 }
 
 static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup,
+				       const struct stm32_i2c_spec *specs,
 				       struct list_head *solutions)
 {
 	struct stm32_i2c_timings *v;
@@ -490,13 +492,13 @@
 	af_delay_max = setup->analog_filter ?
 		       STM32_I2C_ANALOG_FILTER_DELAY_MAX : 0;
 
-	sdadel_min = i2c_specs[setup->speed].hddat_min + setup->fall_time -
+	sdadel_min = specs->hddat_min + setup->fall_time -
 		     af_delay_min - (setup->dnf + 3) * i2cclk;
 
-	sdadel_max = i2c_specs[setup->speed].vddat_max - setup->rise_time -
+	sdadel_max = specs->vddat_max - setup->rise_time -
 		     af_delay_max - (setup->dnf + 4) * i2cclk;
 
-	scldel_min = setup->rise_time + i2c_specs[setup->speed].sudat_min;
+	scldel_min = setup->rise_time + specs->sudat_min;
 
 	if (sdadel_min < 0)
 		sdadel_min = 0;
@@ -548,6 +550,7 @@
 }
 
 static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup,
+				     const struct stm32_i2c_spec *specs,
 				     struct list_head *solutions,
 				     struct stm32_i2c_timings *s)
 {
@@ -570,8 +573,8 @@
 	dnf_delay = setup->dnf * i2cclk;
 
 	tsync = af_delay_min + dnf_delay + (2 * i2cclk);
-	clk_max = STM32_NSEC_PER_SEC / i2c_specs[setup->speed].rate_min;
-	clk_min = STM32_NSEC_PER_SEC / i2c_specs[setup->speed].rate_max;
+	clk_max = STM32_NSEC_PER_SEC / specs->rate_min;
+	clk_min = STM32_NSEC_PER_SEC / specs->rate_max;
 
 	/*
 	 * Among Prescaler possibilities discovered above figures out SCL Low
@@ -589,7 +592,7 @@
 		for (l = 0; l < STM32_SCLL_MAX; l++) {
 			u32 tscl_l = (l + 1) * prescaler + tsync;
 
-			if ((tscl_l < i2c_specs[setup->speed].l_min) ||
+			if (tscl_l < specs->l_min ||
 			    (i2cclk >=
 			     ((tscl_l - af_delay_min - dnf_delay) / 4))) {
 				continue;
@@ -601,7 +604,7 @@
 					   setup->rise_time + setup->fall_time;
 
 				if ((tscl >= clk_min) && (tscl <= clk_max) &&
-				    (tscl_h >= i2c_specs[setup->speed].h_min) &&
+				    (tscl_h >= specs->h_min) &&
 				    (i2cclk < tscl_h)) {
 					u32 clk_error;
 
@@ -630,26 +633,40 @@
 	return ret;
 }
 
+static const struct stm32_i2c_spec *get_specs(u32 rate)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(i2c_specs); i++)
+		if (rate <= i2c_specs[i].rate)
+			return &i2c_specs[i];
+
+	/* NOT REACHED */
+	return ERR_PTR(-EINVAL);
+}
+
 static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv,
 				    struct stm32_i2c_setup *setup,
 				    struct stm32_i2c_timings *output)
 {
+	const struct stm32_i2c_spec *specs;
 	struct stm32_i2c_timings *v, *_v;
 	struct list_head solutions;
 	int ret;
 
-	if (setup->speed >= ARRAY_SIZE(i2c_specs)) {
-		pr_err("%s: speed out of bound {%d/%d}\n", __func__,
-		       setup->speed, ARRAY_SIZE(i2c_specs) - 1);
+	specs = get_specs(setup->speed_freq);
+	if (specs == ERR_PTR(-EINVAL)) {
+		pr_err("%s: speed out of bound {%d}\n", __func__,
+		       setup->speed_freq);
 		return -EINVAL;
 	}
 
-	if ((setup->rise_time > i2c_specs[setup->speed].rise_max) ||
-	    (setup->fall_time > i2c_specs[setup->speed].fall_max)) {
+	if (setup->rise_time > specs->rise_max ||
+	    setup->fall_time > specs->fall_max) {
 		pr_err("%s :timings out of bound Rise{%d>%d}/Fall{%d>%d}\n",
 		       __func__,
-		       setup->rise_time, i2c_specs[setup->speed].rise_max,
-		       setup->fall_time, i2c_specs[setup->speed].fall_max);
+		       setup->rise_time, specs->rise_max,
+		       setup->fall_time, specs->fall_max);
 		return -EINVAL;
 	}
 
@@ -659,18 +676,12 @@
 		return -EINVAL;
 	}
 
-	if (setup->speed_freq > i2c_specs[setup->speed].rate) {
-		pr_err("%s: Freq {%d/%d}\n", __func__,
-		       setup->speed_freq, i2c_specs[setup->speed].rate);
-		return -EINVAL;
-	}
-
 	INIT_LIST_HEAD(&solutions);
-	ret = stm32_i2c_compute_solutions(setup, &solutions);
+	ret = stm32_i2c_compute_solutions(setup, specs, &solutions);
 	if (ret)
 		goto exit;
 
-	ret = stm32_i2c_choose_solution(setup, &solutions, output);
+	ret = stm32_i2c_choose_solution(setup, specs, &solutions, output);
 	if (ret)
 		goto exit;
 
@@ -689,14 +700,24 @@
 	return ret;
 }
 
+static u32 get_lower_rate(u32 rate)
+{
+	int i;
+
+	for (i = ARRAY_SIZE(i2c_specs) - 1; i >= 0; i--)
+		if (rate > i2c_specs[i].rate)
+			return i2c_specs[i].rate;
+
+	return i2c_specs[0].rate;
+}
+
 static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv,
 				  struct stm32_i2c_timings *timing)
 {
 	struct stm32_i2c_setup *setup = i2c_priv->setup;
 	int ret = 0;
 
-	setup->speed = i2c_priv->speed;
-	setup->speed_freq = i2c_specs[setup->speed].rate;
+	setup->speed_freq = i2c_priv->speed;
 	setup->clock_src = clk_get_rate(&i2c_priv->clk);
 
 	if (!setup->clock_src) {
@@ -709,13 +730,11 @@
 		if (ret) {
 			debug("%s: failed to compute I2C timings.\n",
 			      __func__);
-			if (i2c_priv->speed > IC_SPEED_MODE_STANDARD) {
-				i2c_priv->speed--;
-				setup->speed = i2c_priv->speed;
+			if (setup->speed_freq > I2C_SPEED_STANDARD_RATE) {
 				setup->speed_freq =
-					i2c_specs[setup->speed].rate;
+					get_lower_rate(setup->speed_freq);
 				debug("%s: downgrade I2C Speed Freq to (%i)\n",
-				      __func__, i2c_specs[setup->speed].rate);
+				      __func__, setup->speed_freq);
 			} else {
 				break;
 			}
@@ -727,13 +746,15 @@
 		return ret;
 	}
 
-	debug("%s: I2C Speed(%i), Freq(%i), Clk Source(%i)\n", __func__,
-	      setup->speed, setup->speed_freq, setup->clock_src);
+	debug("%s: I2C Freq(%i), Clk Source(%i)\n", __func__,
+	      setup->speed_freq, setup->clock_src);
 	debug("%s: I2C Rise(%i) and Fall(%i) Time\n", __func__,
 	      setup->rise_time, setup->fall_time);
 	debug("%s: I2C Analog Filter(%s), DNF(%i)\n", __func__,
 	      setup->analog_filter ? "On" : "Off", setup->dnf);
 
+	i2c_priv->speed = setup->speed_freq;
+
 	return 0;
 }
 
@@ -773,21 +794,13 @@
 {
 	struct stm32_i2c_priv *i2c_priv = dev_get_priv(bus);
 
-	switch (speed) {
-	case I2C_SPEED_STANDARD_RATE:
-		i2c_priv->speed = IC_SPEED_MODE_STANDARD;
-		break;
-	case I2C_SPEED_FAST_RATE:
-		i2c_priv->speed = IC_SPEED_MODE_FAST;
-		break;
-	case I2C_SPEED_FAST_PLUS_RATE:
-		i2c_priv->speed = IC_SPEED_MODE_FAST_PLUS;
-		break;
-	default:
+	if (speed > I2C_SPEED_FAST_PLUS_RATE) {
 		debug("%s: Speed %d not supported\n", __func__, speed);
 		return -EINVAL;
 	}
 
+	i2c_priv->speed = speed;
+
 	return stm32_i2c_hw_config(i2c_priv);
 }
 
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index f18aa8f..7664027 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -462,6 +462,11 @@
 	  gdsys devices, which supply the majority of the functionality offered
 	  by the devices. This driver supports both CON and CPU variants of the
 	  devices, depending on the device tree entry.
+config ESM_K3
+	bool "Enable K3 ESM driver"
+	depends on ARCH_K3
+	help
+	  Support ESM (Error Signaling Module) on TI K3 SoCs.
 
 config MICROCHIP_FLEXCOM
 	bool "Enable Microchip Flexcom driver"
@@ -481,4 +486,11 @@
 	  optimized voltage from the efuse, so that it can be programmed
 	  to the PMIC on board.
 
+config ESM_PMIC
+	bool "Enable PMIC ESM driver"
+	depends on DM_PMIC
+	help
+	  Support ESM (Error Signal Monitor) on PMIC devices. ESM is used
+	  typically to reboot the board in error condition.
+
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 2b843de..68e0e7a 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -72,3 +72,5 @@
 obj-$(CONFIG_JZ4780_EFUSE) += jz4780_efuse.o
 obj-$(CONFIG_MICROCHIP_FLEXCOM) += microchip_flexcom.o
 obj-$(CONFIG_K3_AVS0) += k3_avs.o
+obj-$(CONFIG_ESM_K3) += k3_esm.o
+obj-$(CONFIG_ESM_PMIC) += esm_pmic.o
diff --git a/drivers/misc/esm_pmic.c b/drivers/misc/esm_pmic.c
new file mode 100644
index 0000000..92c8d68
--- /dev/null
+++ b/drivers/misc/esm_pmic.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * PMIC Error Signal Monitor driver
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ *      Tero Kristo <t-kristo@ti.com>
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <power/pmic.h>
+#include <dm/device_compat.h>
+
+#define INT_ESM_REG		0x6c
+#define INT_ESM_MASK		0x3f
+
+#define ESM_MCU_START_REG	0x8f
+
+#define ESM_MCU_START		BIT(0)
+
+#define ESM_MCU_MODE_CFG_REG	0x92
+
+#define ESM_MCU_EN		BIT(6)
+#define ESM_MCU_ENDRV		BIT(5)
+
+/**
+ * pmic_esm_probe: configures and enables PMIC ESM functionality
+ *
+ * Configures ESM PMIC support and enables it.
+ */
+static int pmic_esm_probe(struct udevice *dev)
+{
+	int ret;
+
+	ret = pmic_reg_write(dev->parent, INT_ESM_REG, INT_ESM_MASK);
+	if (ret) {
+		dev_err(dev, "clearing ESM irqs failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = pmic_reg_write(dev->parent, ESM_MCU_MODE_CFG_REG,
+			     ESM_MCU_EN | ESM_MCU_ENDRV);
+	if (ret) {
+		dev_err(dev, "setting ESM mode failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = pmic_reg_write(dev->parent, ESM_MCU_START_REG, ESM_MCU_START);
+	if (ret) {
+		dev_err(dev, "starting ESM failed: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct udevice_id pmic_esm_ids[] = {
+	{ .compatible = "ti,tps659413-esm" },
+	{}
+};
+
+U_BOOT_DRIVER(pmic_esm) = {
+	.name = "esm_pmic",
+	.of_match = pmic_esm_ids,
+	.id = UCLASS_MISC,
+	.probe = pmic_esm_probe,
+};
diff --git a/drivers/misc/i2c_eeprom.c b/drivers/misc/i2c_eeprom.c
index 6c0459d..ef5f103 100644
--- a/drivers/misc/i2c_eeprom.c
+++ b/drivers/misc/i2c_eeprom.c
@@ -14,7 +14,7 @@
 
 struct i2c_eeprom_drv_data {
 	u32 size; /* size in bytes */
-	u32 pagewidth; /* pagesize = 2^pagewidth */
+	u32 pagesize; /* page size in bytes */
 	u32 addr_offset_mask; /* bits in addr used for offset overflow */
 	u32 offset_len; /* size in bytes of offset */
 };
@@ -99,13 +99,11 @@
 	u32 pagesize;
 	u32 size;
 
-	if (dev_read_u32(dev, "pagesize", &pagesize) == 0) {
+	if (dev_read_u32(dev, "pagesize", &pagesize) == 0)
 		priv->pagesize = pagesize;
-	} else {
+	else
 		/* 6 bit -> page size of up to 2^63 (should be sufficient) */
-		priv->pagewidth = data->pagewidth;
-		priv->pagesize = (1 << priv->pagewidth);
-	}
+		priv->pagesize = data->pagesize;
 
 	if (dev_read_u32(dev, "size", &size) == 0)
 		priv->size = size;
@@ -158,98 +156,98 @@
 
 static const struct i2c_eeprom_drv_data eeprom_data = {
 	.size = 0,
-	.pagewidth = 0,
+	.pagesize = 1,
 	.addr_offset_mask = 0,
 	.offset_len = 1,
 };
 
 static const struct i2c_eeprom_drv_data mc24aa02e48_data = {
 	.size = 256,
-	.pagewidth = 3,
+	.pagesize = 8,
 	.addr_offset_mask = 0,
 	.offset_len = 1,
 };
 
 static const struct i2c_eeprom_drv_data atmel24c01a_data = {
 	.size = 128,
-	.pagewidth = 3,
+	.pagesize = 8,
 	.addr_offset_mask = 0,
 	.offset_len = 1,
 };
 
 static const struct i2c_eeprom_drv_data atmel24c02_data = {
 	.size = 256,
-	.pagewidth = 3,
+	.pagesize = 8,
 	.addr_offset_mask = 0,
 	.offset_len = 1,
 };
 
 static const struct i2c_eeprom_drv_data atmel24c04_data = {
 	.size = 512,
-	.pagewidth = 4,
+	.pagesize = 16,
 	.addr_offset_mask = 0x1,
 	.offset_len = 1,
 };
 
 static const struct i2c_eeprom_drv_data atmel24c08_data = {
 	.size = 1024,
-	.pagewidth = 4,
+	.pagesize = 16,
 	.addr_offset_mask = 0x3,
 	.offset_len = 1,
 };
 
 static const struct i2c_eeprom_drv_data atmel24c08a_data = {
 	.size = 1024,
-	.pagewidth = 4,
+	.pagesize = 16,
 	.addr_offset_mask = 0x3,
 	.offset_len = 1,
 };
 
 static const struct i2c_eeprom_drv_data atmel24c16a_data = {
 	.size = 2048,
-	.pagewidth = 4,
+	.pagesize = 16,
 	.addr_offset_mask = 0x7,
 	.offset_len = 1,
 };
 
 static const struct i2c_eeprom_drv_data atmel24mac402_data = {
 	.size = 256,
-	.pagewidth = 4,
+	.pagesize = 16,
 	.addr_offset_mask = 0,
 	.offset_len = 1,
 };
 
 static const struct i2c_eeprom_drv_data atmel24c32_data = {
 	.size = 4096,
-	.pagewidth = 5,
+	.pagesize = 32,
 	.addr_offset_mask = 0,
 	.offset_len = 2,
 };
 
 static const struct i2c_eeprom_drv_data atmel24c64_data = {
 	.size = 8192,
-	.pagewidth = 5,
+	.pagesize = 32,
 	.addr_offset_mask = 0,
 	.offset_len = 2,
 };
 
 static const struct i2c_eeprom_drv_data atmel24c128_data = {
 	.size = 16384,
-	.pagewidth = 6,
+	.pagesize = 64,
 	.addr_offset_mask = 0,
 	.offset_len = 2,
 };
 
 static const struct i2c_eeprom_drv_data atmel24c256_data = {
 	.size = 32768,
-	.pagewidth = 6,
+	.pagesize = 64,
 	.addr_offset_mask = 0,
 	.offset_len = 2,
 };
 
 static const struct i2c_eeprom_drv_data atmel24c512_data = {
 	.size = 65536,
-	.pagewidth = 6,
+	.pagesize = 64,
 	.addr_offset_mask = 0,
 	.offset_len = 2,
 };
diff --git a/drivers/misc/k3_avs.c b/drivers/misc/k3_avs.c
index 90df377..d8048e1 100644
--- a/drivers/misc/k3_avs.c
+++ b/drivers/misc/k3_avs.c
@@ -316,15 +316,15 @@
 		.opp = AM6_OPP_NOM,
 		.opps = {
 			[AM6_OPP_NOM] = {
-				.volt = 1000000,
+				.volt = 1100000,
 				.freq = 800000000,
 			},
 			[AM6_OPP_OD] = {
-				.volt = 1100000,
+				.volt = 1200000,
 				.freq = 1000000000,
 			},
 			[AM6_OPP_TURBO] = {
-				.volt = 1220000,
+				.volt = 1240000,
 				.freq = 1100000000,
 			},
 		},
@@ -336,15 +336,15 @@
 		.clk_id = 0, /* ARM clock */
 		.opps = {
 			[AM6_OPP_NOM] = {
-				.volt = 1000000,
+				.volt = 1100000,
 				.freq = 800000000,
 			},
 			[AM6_OPP_OD] = {
-				.volt = 1100000,
+				.volt = 1200000,
 				.freq = 1000000000,
 			},
 			[AM6_OPP_TURBO] = {
-				.volt = 1220000,
+				.volt = 1240000,
 				.freq = 1100000000,
 			},
 		},
diff --git a/drivers/misc/k3_esm.c b/drivers/misc/k3_esm.c
new file mode 100644
index 0000000..8f270f3
--- /dev/null
+++ b/drivers/misc/k3_esm.c
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Texas Instruments' K3 Error Signalling Module driver
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ *      Tero Kristo <t-kristo@ti.com>
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <dm/device_compat.h>
+
+#define ESM_SFT_RST			0x0c
+#define ESM_SFT_RST_KEY			0x0f
+
+#define ESM_STS(i)			(0x404 + (i) / 32 * 0x20)
+#define ESM_PIN_EN_SET_OFFSET(i)	(0x414 + (i) / 32 * 0x20)
+#define ESM_PIN_MASK(i)			BIT((i) & 0x1f)
+
+static void esm_pin_enable(void __iomem *base, int pin)
+{
+	/* Enable event */
+	writel(ESM_PIN_MASK(pin), base + ESM_PIN_EN_SET_OFFSET(pin));
+}
+
+/**
+ * k3_esm_probe: configures ESM based on DT data
+ *
+ * Parses ESM info from device tree, and configures the module accordingly.
+ */
+static int k3_esm_probe(struct udevice *dev)
+{
+	int ret;
+	void __iomem *base;
+	int num_pins;
+	u32 *pins;
+	int i;
+
+	base = dev_remap_addr_index(dev, 0);
+	if (!base)
+		return -ENODEV;
+
+	num_pins = dev_read_size(dev, "ti,esm-pins");
+	if (num_pins < 0) {
+		dev_err(dev, "ti,esm-pins property missing or invalid: %d\n",
+			num_pins);
+		return num_pins;
+	}
+
+	num_pins /= sizeof(u32);
+
+	pins = kmalloc(num_pins * sizeof(u32), __GFP_ZERO);
+	if (!pins)
+		return -ENOMEM;
+
+	ret = dev_read_u32_array(dev, "ti,esm-pins", pins, num_pins);
+	if (ret < 0) {
+		dev_err(dev, "failed to read ti,esm-pins property: %d\n",
+			ret);
+		goto free_pins;
+	}
+
+	/* Clear any pending events */
+	writel(ESM_SFT_RST_KEY, base + ESM_SFT_RST);
+
+	for (i = 0; i < num_pins; i++)
+		esm_pin_enable(base, pins[i]);
+
+free_pins:
+	kfree(pins);
+	return ret;
+}
+
+static const struct udevice_id k3_esm_ids[] = {
+	{ .compatible = "ti,j721e-esm" },
+	{}
+};
+
+U_BOOT_DRIVER(k3_esm) = {
+	.name = "k3_esm",
+	.of_match = k3_esm_ids,
+	.id = UCLASS_MISC,
+	.probe = k3_esm_probe,
+};
diff --git a/drivers/power/pmic/tps65941.c b/drivers/power/pmic/tps65941.c
index e8f3c95..7b3416a 100644
--- a/drivers/power/pmic/tps65941.c
+++ b/drivers/power/pmic/tps65941.c
@@ -59,8 +59,8 @@
 	if (!children)
 		printf("%s: %s - no child found\n", __func__, dev->name);
 
-	/* Always return success for this device */
-	return 0;
+	/* Probe all the child devices */
+	return dm_scan_fdt_dev(dev);
 }
 
 static struct dm_pmic_ops tps65941_ops = {
diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.c b/drivers/ram/stm32mp1/stm32mp1_ddr.c
index d765a46..11b14ae 100644
--- a/drivers/ram/stm32mp1/stm32mp1_ddr.c
+++ b/drivers/ram/stm32mp1/stm32mp1_ddr.c
@@ -639,7 +639,8 @@
 	start_sw_done(ctl);
 	/* quasi-dynamic register update*/
 	setbits_le32(&ctl->rfshctl3, DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
-	clrbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN);
+	clrbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN |
+				   DDRCTRL_PWRCTL_SELFREF_EN);
 	clrbits_le32(&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
 	wait_sw_done_ack(ctl);
 }
@@ -652,6 +653,8 @@
 		clrbits_le32(&ctl->rfshctl3, DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
 	if (pwrctl & DDRCTRL_PWRCTL_POWERDOWN_EN)
 		setbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN);
+	if ((pwrctl & DDRCTRL_PWRCTL_SELFREF_EN))
+		setbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_SELFREF_EN);
 	setbits_le32(&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
 	wait_sw_done_ack(ctl);
 }
@@ -668,14 +671,34 @@
 {
 	u32 pir;
 	int ret = -EINVAL;
+	char bus_width;
+
+	switch (config->c_reg.mstr & DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK) {
+	case DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER:
+		bus_width = 8;
+		break;
+	case DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF:
+		bus_width = 16;
+		break;
+	default:
+		bus_width = 32;
+		break;
+	}
+
 
 	if (config->c_reg.mstr & DDRCTRL_MSTR_DDR3)
 		ret = board_ddr_power_init(STM32MP_DDR3);
-	else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR2)
-		ret = board_ddr_power_init(STM32MP_LPDDR2);
-	else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR3)
-		ret = board_ddr_power_init(STM32MP_LPDDR3);
-
+	else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR2) {
+		if (bus_width == 32)
+			ret = board_ddr_power_init(STM32MP_LPDDR2_32);
+		else
+			ret = board_ddr_power_init(STM32MP_LPDDR2_16);
+	} else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR3) {
+		if (bus_width == 32)
+			ret = board_ddr_power_init(STM32MP_LPDDR3_32);
+		else
+			ret = board_ddr_power_init(STM32MP_LPDDR3_16);
+	}
 	if (ret)
 		panic("ddr power init failed\n");
 
@@ -746,7 +769,8 @@
  */
 	set_reg(priv, REGPHY_REG, &config->p_reg);
 	set_reg(priv, REGPHY_TIMING, &config->p_timing);
-	set_reg(priv, REGPHY_CAL, &config->p_cal);
+	if (config->p_cal_present)
+		set_reg(priv, REGPHY_CAL, &config->p_cal);
 
 	if (INTERACTIVE(STEP_PHY_INIT))
 		goto start;
@@ -781,13 +805,16 @@
 
 	wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL);
 
-	debug("DDR DQS training : ");
+	if (config->p_cal_present) {
+		debug("DDR DQS training skipped.\n");
+	} else {
+		debug("DDR DQS training : ");
 /*  8. Disable Auto refresh and power down by setting
  *    - RFSHCTL3.dis_au_refresh = 1
  *    - PWRCTL.powerdown_en = 0
  *    - DFIMISC.dfiinit_complete_en = 0
  */
-	stm32mp1_refresh_disable(priv->ctl);
+		stm32mp1_refresh_disable(priv->ctl);
 
 /*  9. Program PUBL PGCR to enable refresh during training and rank to train
  *     not done => keep the programed value in PGCR
@@ -795,14 +822,15 @@
 
 /* 10. configure PUBL PIR register to specify which training step to run */
 	/* warning : RVTRN  is not supported by this PUBL */
-	stm32mp1_ddrphy_init(priv->phy, DDRPHYC_PIR_QSTRN);
+		stm32mp1_ddrphy_init(priv->phy, DDRPHYC_PIR_QSTRN);
 
 /* 11. monitor PUB PGSR.IDONE to poll cpmpletion of training sequence */
-	ddrphy_idone_wait(priv->phy);
+		ddrphy_idone_wait(priv->phy);
 
 /* 12. set back registers in step 8 to the orginal values if desidered */
-	stm32mp1_refresh_restore(priv->ctl, config->c_reg.rfshctl3,
-				 config->c_reg.pwrctl);
+		stm32mp1_refresh_restore(priv->ctl, config->c_reg.rfshctl3,
+					 config->c_reg.pwrctl);
+	} /* if (config->p_cal_present) */
 
 	/* enable uMCTL2 AXI port 0 and 1 */
 	setbits_le32(&priv->ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN);
diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.h b/drivers/ram/stm32mp1/stm32mp1_ddr.h
index 52b748f..4998f04 100644
--- a/drivers/ram/stm32mp1/stm32mp1_ddr.h
+++ b/drivers/ram/stm32mp1/stm32mp1_ddr.h
@@ -170,6 +170,7 @@
 	struct stm32mp1_ddrphy_reg p_reg;
 	struct stm32mp1_ddrphy_timing p_timing;
 	struct stm32mp1_ddrphy_cal p_cal;
+	bool p_cal_present;
 };
 
 int stm32mp1_ddr_clk_enable(struct ddr_info *priv, u32 mem_speed);
diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h b/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h
index 9d33186..afd93c5 100644
--- a/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h
+++ b/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h
@@ -260,6 +260,7 @@
 
 #define DDRCTRL_MRSTAT_MR_WR_BUSY		BIT(0)
 
+#define DDRCTRL_PWRCTL_SELFREF_EN		BIT(0)
 #define DDRCTRL_PWRCTL_POWERDOWN_EN		BIT(1)
 #define DDRCTRL_PWRCTL_SELFREF_SW		BIT(5)
 
diff --git a/drivers/ram/stm32mp1/stm32mp1_interactive.c b/drivers/ram/stm32mp1/stm32mp1_interactive.c
index cc9b2e7..805c9dd 100644
--- a/drivers/ram/stm32mp1/stm32mp1_interactive.c
+++ b/drivers/ram/stm32mp1/stm32mp1_interactive.c
@@ -106,7 +106,7 @@
 		"help                       displays help\n"
 		"info                       displays DDR information\n"
 		"info  <param> <val>        changes DDR information\n"
-		"      with <param> = step, name, size or speed\n"
+		"      with <param> = step, name, size, speed or cal\n"
 		"freq                       displays the DDR PHY frequency in kHz\n"
 		"freq  <freq>               changes the DDR PHY frequency\n"
 		"param [type|reg]           prints input parameters\n"
@@ -160,6 +160,7 @@
 		printf("name = %s\n", config->info.name);
 		printf("size = 0x%x\n", config->info.size);
 		printf("speed = %d kHz\n", config->info.speed);
+		printf("cal = %d\n", config->p_cal_present);
 		return;
 	}
 
@@ -208,6 +209,16 @@
 		}
 		return;
 	}
+	if (!strcmp(argv[1], "cal")) {
+		if (strict_strtoul(argv[2], 10, &value) < 0 ||
+		    (value != 0 && value != 1)) {
+			printf("invalid value %s\n", argv[2]);
+		} else {
+			config->p_cal_present = value;
+			printf("cal = %d\n", config->p_cal_present);
+		}
+		return;
+	}
 	printf("argument %s invalid\n", argv[1]);
 }
 
@@ -367,7 +378,6 @@
 			      enum stm32mp1_ddr_interact_step step,
 			      const struct stm32mp1_ddr_config *config)
 {
-	const char *prompt = "DDR>";
 	char buffer[CONFIG_SYS_CBSIZE];
 	char *argv[CONFIG_SYS_MAXARGS + 1];	/* NULL terminated */
 	int argc;
@@ -403,13 +413,12 @@
 	}
 
 	printf("%d:%s\n", step, step_str[step]);
-	printf("%s\n", prompt);
 
 	if (next_step > step)
 		return false;
 
 	while (next_step == step) {
-		cli_readline_into_buffer(prompt, buffer, 0);
+		cli_readline_into_buffer("DDR>", buffer, 0);
 		argc = cli_simple_parse_line(buffer, argv);
 		if (!argc)
 			continue;
diff --git a/drivers/ram/stm32mp1/stm32mp1_ram.c b/drivers/ram/stm32mp1/stm32mp1_ram.c
index eb78f11..b1e593f 100644
--- a/drivers/ram/stm32mp1/stm32mp1_ram.c
+++ b/drivers/ram/stm32mp1/stm32mp1_ram.c
@@ -65,18 +65,22 @@
 	struct clk axidcg;
 	struct stm32mp1_ddr_config config;
 
-#define PARAM(x, y) \
-	{ x,\
-	  offsetof(struct stm32mp1_ddr_config, y),\
-	  sizeof(config.y) / sizeof(u32)}
+#define PARAM(x, y, z)							\
+	{	.name = x,						\
+		.offset = offsetof(struct stm32mp1_ddr_config, y),	\
+		.size = sizeof(config.y) / sizeof(u32),			\
+		.present = z,						\
+	}
 
-#define CTL_PARAM(x) PARAM("st,ctl-"#x, c_##x)
-#define PHY_PARAM(x) PARAM("st,phy-"#x, p_##x)
+#define CTL_PARAM(x) PARAM("st,ctl-"#x, c_##x, NULL)
+#define PHY_PARAM(x) PARAM("st,phy-"#x, p_##x, NULL)
+#define PHY_PARAM_OPT(x) PARAM("st,phy-"#x, p_##x, &config.p_##x##_present)
 
 	const struct {
 		const char *name; /* name in DT */
 		const u32 offset; /* offset in config struct */
 		const u32 size;   /* size of parameters */
+		bool * const present;  /* presence indication for opt */
 	} param[] = {
 		CTL_PARAM(reg),
 		CTL_PARAM(timing),
@@ -84,7 +88,7 @@
 		CTL_PARAM(perf),
 		PHY_PARAM(reg),
 		PHY_PARAM(timing),
-		PHY_PARAM(cal)
+		PHY_PARAM_OPT(cal)
 	};
 
 	config.info.speed = dev_read_u32_default(dev, "st,mem-speed", 0);
@@ -103,11 +107,25 @@
 					 param[idx].size);
 		debug("%s: %s[0x%x] = %d\n", __func__,
 		      param[idx].name, param[idx].size, ret);
-		if (ret) {
+		if (ret &&
+		    (ret != -FDT_ERR_NOTFOUND || !param[idx].present)) {
 			pr_err("%s: Cannot read %s, error=%d\n",
 			       __func__, param[idx].name, ret);
 			return -EINVAL;
 		}
+		if (param[idx].present) {
+			/* save presence of optional parameters */
+			*param[idx].present = true;
+			if (ret == -FDT_ERR_NOTFOUND) {
+				*param[idx].present = false;
+#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE
+				/* reset values if used later */
+				memset((void *)((u32)&config +
+						param[idx].offset),
+					0, param[idx].size * sizeof(u32));
+#endif
+			}
+		}
 	}
 
 	ret = clk_get_by_name(dev, "axidcg", &axidcg);
diff --git a/drivers/ram/stm32mp1/stm32mp1_tuning.c b/drivers/ram/stm32mp1/stm32mp1_tuning.c
index 4e1c1fa..3013b7b 100644
--- a/drivers/ram/stm32mp1/stm32mp1_tuning.c
+++ b/drivers/ram/stm32mp1/stm32mp1_tuning.c
@@ -8,6 +8,8 @@
 #include <ram.h>
 #include <reset.h>
 #include <asm/io.h>
+#include <linux/bitops.h>
+#include <linux/iopoll.h>
 
 #include "stm32mp1_ddr_regs.h"
 #include "stm32mp1_ddr.h"
@@ -75,6 +77,133 @@
 	return nb_bytes;
 }
 
+static u8 get_nb_bank(struct stm32mp1_ddrctl *ctl)
+{
+	/* Count bank address bits */
+	u8 bits = 0;
+	u32 reg, val;
+
+	reg = readl(&ctl->addrmap1);
+	/* addrmap1.addrmap_bank_b1 */
+	val = (reg & GENMASK(5, 0)) >> 0;
+	if (val <= 31)
+		bits++;
+	/* addrmap1.addrmap_bank_b2 */
+	val = (reg & GENMASK(13, 8)) >> 8;
+	if (val <= 31)
+		bits++;
+	/* addrmap1.addrmap_bank_b3 */
+	val = (reg & GENMASK(21, 16)) >> 16;
+	if (val <= 31)
+		bits++;
+
+	return bits;
+}
+
+static u8 get_nb_col(struct stm32mp1_ddrctl *ctl)
+{
+	u8 bits;
+	u32 reg, val;
+
+	/* Count column address bits, start at 2 for b0 and b1 (fixed) */
+	bits = 2;
+
+	reg = readl(&ctl->addrmap2);
+	/* addrmap2.addrmap_col_b2 */
+	val = (reg & GENMASK(3, 0)) >> 0;
+	if (val <= 7)
+		bits++;
+	/* addrmap2.addrmap_col_b3 */
+	val = (reg & GENMASK(11, 8)) >> 8;
+	if (val <= 7)
+		bits++;
+	/* addrmap2.addrmap_col_b4 */
+	val = (reg & GENMASK(19, 16)) >> 16;
+	if (val <= 7)
+		bits++;
+	/* addrmap2.addrmap_col_b5 */
+	val = (reg & GENMASK(27, 24)) >> 24;
+	if (val <= 7)
+		bits++;
+
+	reg = readl(&ctl->addrmap3);
+	/* addrmap3.addrmap_col_b6 */
+	val = (reg & GENMASK(3, 0)) >> 0;
+	if (val <= 7)
+		bits++;
+	/* addrmap3.addrmap_col_b7 */
+	val = (reg & GENMASK(11, 8)) >> 8;
+	if (val <= 7)
+		bits++;
+	/* addrmap3.addrmap_col_b8 */
+	val = (reg & GENMASK(19, 16)) >> 16;
+	if (val <= 7)
+		bits++;
+	/* addrmap3.addrmap_col_b9 */
+	val = (reg & GENMASK(27, 24)) >> 24;
+	if (val <= 7)
+		bits++;
+
+	reg = readl(&ctl->addrmap4);
+	/* addrmap4.addrmap_col_b10 */
+	val = (reg & GENMASK(3, 0)) >> 0;
+	if (val <= 7)
+		bits++;
+	/* addrmap4.addrmap_col_b11 */
+	val = (reg & GENMASK(11, 8)) >> 8;
+	if (val <= 7)
+		bits++;
+
+	return bits;
+}
+
+static u8 get_nb_row(struct stm32mp1_ddrctl *ctl)
+{
+	/* Count row address bits */
+	u8 bits = 0;
+	u32 reg, val;
+
+	reg = readl(&ctl->addrmap5);
+	/* addrmap5.addrmap_row_b0 */
+	val = (reg & GENMASK(3, 0)) >> 0;
+	if (val <= 11)
+		bits++;
+	/* addrmap5.addrmap_row_b1 */
+	val = (reg & GENMASK(11, 8)) >> 8;
+	if (val <= 11)
+		bits++;
+	/* addrmap5.addrmap_row_b2_10 */
+	val = (reg & GENMASK(19, 16)) >> 16;
+	if (val <= 11)
+		bits += 9;
+	else
+		printf("warning: addrmap5.addrmap_row_b2_10 not supported\n");
+	/* addrmap5.addrmap_row_b11 */
+	val = (reg & GENMASK(27, 24)) >> 24;
+	if (val <= 11)
+		bits++;
+
+	reg = readl(&ctl->addrmap6);
+	/* addrmap6.addrmap_row_b12 */
+	val = (reg & GENMASK(3, 0)) >> 0;
+	if (val <= 7)
+		bits++;
+	/* addrmap6.addrmap_row_b13 */
+	val = (reg & GENMASK(11, 8)) >> 8;
+	if (val <= 7)
+		bits++;
+	/* addrmap6.addrmap_row_b14 */
+	val = (reg & GENMASK(19, 16)) >> 16;
+	if (val <= 7)
+		bits++;
+	/* addrmap6.addrmap_row_b15 */
+	val = (reg & GENMASK(27, 24)) >> 24;
+	if (val <= 7)
+		bits++;
+
+	return bits;
+}
+
 static void itm_soft_reset(struct stm32mp1_ddrphy *phy)
 {
 	stm32mp1_ddrphy_init(phy, DDRPHYC_PIR_ITMSRST);
@@ -169,8 +298,13 @@
 }
 
 /* Basic BIST configuration for data lane tests. */
-static void config_BIST(struct stm32mp1_ddrphy *phy)
+static void config_BIST(struct stm32mp1_ddrctl *ctl,
+			struct stm32mp1_ddrphy *phy)
 {
+	u8 nb_bank = get_nb_bank(ctl);
+	u8 nb_row = get_nb_row(ctl);
+	u8 nb_col = get_nb_col(ctl);
+
 	/* Selects the SDRAM bank address to be used during BIST. */
 	u32 bbank = 0;
 	/* Selects the SDRAM row address to be used during BIST. */
@@ -190,18 +324,20 @@
 	 * must be 0 with single rank
 	 */
 	u32 brank = 0;
+
 	/* Specifies the maximum SDRAM bank address to be used during
 	 * BIST before the address & increments to the next rank.
 	 */
-	u32 bmbank = 1;
+	u32 bmbank = (1 << nb_bank) - 1;
 	/* Specifies the maximum SDRAM row address to be used during
 	 * BIST before the address & increments to the next bank.
 	 */
-	u32 bmrow = 0x7FFF; /* To check */
+	u32 bmrow = (1 << nb_row) - 1;
 	/* Specifies the maximum SDRAM column address to be used during
 	 * BIST before the address & increments to the next row.
 	 */
-	u32 bmcol = 0x3FF;  /* To check */
+	u32 bmcol = (1 << nb_col) - 1;
+
 	u32 bmode_conf = 0x00000001;  /* DRam mode */
 	u32 bdxen_conf = 0x00000001;  /* BIST on Data byte */
 	u32 bdpat_conf = 0x00000002;  /* Select LFSR pattern */
@@ -223,8 +359,6 @@
 
 	writel(bcol | (brow << 12) | (bbank << 28), &phy->bistar0);
 	writel(brank | (bmrank << 2) | (bainc << 4), &phy->bistar1);
-
-	/* To check this line : */
 	writel(bmcol | (bmrow << 12) | (bmbank << 28), &phy->bistar2);
 }
 
@@ -246,6 +380,8 @@
 	bool result = true; /* BIST_SUCCESS */
 	u32 cnt = 0;
 	u32 error = 0;
+	u32 val;
+	int ret;
 
 	bist->test_result = true;
 
@@ -266,7 +402,7 @@
 		writel(rand(), &phy->bistlsr);
 
 	/* some delay to reset BIST */
-	mdelay(1);
+	udelay(10);
 
 	/*Perform BIST Run*/
 	clrsetbits_le32(&phy->bistrr,
@@ -274,27 +410,29 @@
 			0x00000001);
 	/* Write BISTRR.BINST = 3?b001; */
 
-	/* Wait for a number of CTL clocks before reading BIST register*/
-	/* Wait 300 ctl_clk cycles;  ... IS it really needed?? */
-	/* Perform BIST Instruction Stop*/
-	/* Write BISTRR.BINST = 3?b010;*/
+	/* poll on BISTGSR.BDONE and wait max 1000 us */
+	ret = readl_poll_timeout(&phy->bistgsr, val,
+				 val & DDRPHYC_BISTGSR_BDDONE, 1000);
 
-	/* poll on BISTGSR.BDONE. If 0, wait.  ++TODO Add timeout */
-	while (!(readl(&phy->bistgsr) & DDRPHYC_BISTGSR_BDDONE))
-		;
-
-	/*Check if received correct number of words*/
-	/* if (Read BISTWCSR.DXWCNT = Read BISTWCR.BWCNT) */
-	if (((readl(&phy->bistwcsr)) >> DDRPHYC_BISTWCSR_DXWCNT_SHIFT) ==
-	    readl(&phy->bistwcr)) {
-		/*Determine if there is a data comparison error*/
-		/* if (Read BISTGSR.BDXERR = 1?b0) */
-		if (readl(&phy->bistgsr) & DDRPHYC_BISTGSR_BDXERR)
-			result = false; /* BIST_FAIL; */
-		else
-			result = true; /* BIST_SUCCESS; */
-	} else {
+	if (ret < 0) {
+		printf("warning: BIST timeout\n");
 		result = false; /* BIST_FAIL; */
+		/*Perform BIST Stop */
+		clrsetbits_le32(&phy->bistrr, 0x00000007, 0x00000002);
+	} else {
+		/*Check if received correct number of words*/
+		/* if (Read BISTWCSR.DXWCNT = Read BISTWCR.BWCNT) */
+		if (((readl(&phy->bistwcsr)) >> DDRPHYC_BISTWCSR_DXWCNT_SHIFT)
+		    == readl(&phy->bistwcr)) {
+			/*Determine if there is a data comparison error*/
+			/* if (Read BISTGSR.BDXERR = 1?b0) */
+			if (readl(&phy->bistgsr) & DDRPHYC_BISTGSR_BDXERR)
+				result = false; /* BIST_FAIL; */
+			else
+				result = true; /* BIST_SUCCESS; */
+		} else {
+			result = false; /* BIST_FAIL; */
+		}
 	}
 
 	/* loop while success */
@@ -394,7 +532,7 @@
 	clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN);
 
 	/* Config the BIST block */
-	config_BIST(phy);
+	config_BIST(ctl, phy);
 	pr_debug("BIST Config done.\n");
 
 	/* Train each byte */
@@ -807,7 +945,7 @@
 	clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN);
 
 	/* Config the BIST block */
-	config_BIST(phy);
+	config_BIST(ctl, phy);
 
 	for (byte = 0; byte < nb_bytes; byte++) {
 		if (ctrlc()) {
@@ -1182,15 +1320,17 @@
 				 dqs_gate_values[byte][0],
 				 dqs_gate_values[byte][1]);
 			pr_debug("*******the nominal values were system latency: 0  phase: 2*******\n");
-			set_r0dgsl_delay(phy, byte, dqs_gate_values[byte][0]);
-			set_r0dgps_delay(phy, byte, dqs_gate_values[byte][1]);
 		}
 	} else {
 		/* if intermitant, restore defaut values */
 		pr_debug("dqs gating:no regular fail/pass/fail found. defaults values restored.\n");
-		set_r0dgsl_delay(phy, byte, 0);
-		set_r0dgps_delay(phy, byte, 2);
+		dqs_gate_values[byte][0] = 0;
+		dqs_gate_values[byte][1] = 2;
 	}
+	set_r0dgsl_delay(phy, byte, dqs_gate_values[byte][0]);
+	set_r0dgps_delay(phy, byte, dqs_gate_values[byte][1]);
+	printf("Byte %d, R0DGSL = %d, R0DGPS = %d\n",
+	       byte, dqs_gate_values[byte][0], dqs_gate_values[byte][1]);
 
 	/* return 0 if intermittent or if both left_bound
 	 * and right_bound are not found
@@ -1227,7 +1367,7 @@
 	clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN);
 
 	/* config the bist block */
-	config_BIST(phy);
+	config_BIST(ctl, phy);
 
 	for (byte = 0; byte < nb_bytes; byte++) {
 		if (ctrlc()) {
@@ -1281,11 +1421,16 @@
 {
 	u32 rfshctl3 = readl(&ctl->rfshctl3);
 	u32 pwrctl = readl(&ctl->pwrctl);
+	u32 derateen = readl(&ctl->derateen);
 	enum test_result res;
 
+	writel(0x0, &ctl->derateen);
 	stm32mp1_refresh_disable(ctl);
+
 	res = read_dqs_gating(ctl, phy, string);
+
 	stm32mp1_refresh_restore(ctl, rfshctl3, pwrctl);
+	writel(derateen, &ctl->derateen);
 
 	return res;
 }
@@ -1296,11 +1441,16 @@
 {
 	u32 rfshctl3 = readl(&ctl->rfshctl3);
 	u32 pwrctl = readl(&ctl->pwrctl);
+	u32 derateen = readl(&ctl->derateen);
 	enum test_result res;
 
+	writel(0x0, &ctl->derateen);
 	stm32mp1_refresh_disable(ctl);
+
 	res = bit_deskew(ctl, phy, string);
+
 	stm32mp1_refresh_restore(ctl, rfshctl3, pwrctl);
+	writel(derateen, &ctl->derateen);
 
 	return res;
 }
@@ -1311,11 +1461,16 @@
 {
 	u32 rfshctl3 = readl(&ctl->rfshctl3);
 	u32 pwrctl = readl(&ctl->pwrctl);
+	u32 derateen = readl(&ctl->derateen);
 	enum test_result res;
 
+	writel(0x0, &ctl->derateen);
 	stm32mp1_refresh_disable(ctl);
+
 	res = eye_training(ctl, phy, string);
+
 	stm32mp1_refresh_restore(ctl, rfshctl3, pwrctl);
+	writel(derateen, &ctl->derateen);
 
 	return res;
 }
diff --git a/drivers/remoteproc/ti_k3_dsp_rproc.c b/drivers/remoteproc/ti_k3_dsp_rproc.c
index 09e050f..1fc8193 100644
--- a/drivers/remoteproc/ti_k3_dsp_rproc.c
+++ b/drivers/remoteproc/ti_k3_dsp_rproc.c
@@ -2,9 +2,9 @@
 /*
  * Texas Instruments' K3 DSP Remoteproc driver
  *
- * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2018-2020 Texas Instruments Incorporated - http://www.ti.com/
  *	Lokesh Vutla <lokeshvutla@ti.com>
- *
+ *	Suman Anna <s-anna@ti.com>
  */
 
 #include <common.h>
@@ -18,6 +18,7 @@
 #include <power-domain.h>
 #include <dm/device_compat.h>
 #include <linux/err.h>
+#include <linux/sizes.h>
 #include <linux/soc/ti/ti_sci_protocol.h>
 #include "ti_sci_proc.h"
 
@@ -38,19 +39,79 @@
 };
 
 /**
+ * struct k3_dsp_boot_data - internal data structure used for boot
+ * @boot_align_addr: Boot vector address alignment granularity
+ * @uses_lreset: Flag to denote the need for local reset management
+ */
+struct k3_dsp_boot_data {
+	u32 boot_align_addr;
+	bool uses_lreset;
+};
+
+/**
  * struct k3_dsp_privdata - Structure representing Remote processor data.
  * @rproc_rst:		rproc reset control data
  * @tsp:		Pointer to TISCI proc contrl handle
+ * @data:		Pointer to DSP specific boot data structure
  * @mem:		Array of available memories
  * @num_mem:		Number of available memories
  */
 struct k3_dsp_privdata {
 	struct reset_ctl dsp_rst;
 	struct ti_sci_proc tsp;
+	struct k3_dsp_boot_data *data;
 	struct k3_dsp_mem *mem;
 	int num_mems;
 };
 
+/*
+ * The C66x DSP cores have a local reset that affects only the CPU, and a
+ * generic module reset that powers on the device and allows the DSP internal
+ * memories to be accessed while the local reset is asserted. This function is
+ * used to release the global reset on C66x DSPs to allow loading into the DSP
+ * internal RAMs. This helper function is invoked in k3_dsp_load() before any
+ * actual firmware loading and is undone only in k3_dsp_stop(). The local reset
+ * on C71x cores is a no-op and the global reset cannot be released on C71x
+ * cores until after the firmware images are loaded, so this function does
+ * nothing for C71x cores.
+ */
+static int k3_dsp_prepare(struct udevice *dev)
+{
+	struct k3_dsp_privdata *dsp = dev_get_priv(dev);
+	struct k3_dsp_boot_data *data = dsp->data;
+	int ret;
+
+	/* local reset is no-op on C71x processors */
+	if (!data->uses_lreset)
+		return 0;
+
+	ret = ti_sci_proc_power_domain_on(&dsp->tsp);
+	if (ret)
+		dev_err(dev, "cannot enable internal RAM loading, ret = %d\n",
+			ret);
+
+	return ret;
+}
+
+/*
+ * This function is the counterpart to k3_dsp_prepare() and is used to assert
+ * the global reset on C66x DSP cores (no-op for C71x DSP cores). This completes
+ * the second step of powering down the C66x DSP cores. The cores themselves
+ * are halted through the local reset in first step. This function is invoked
+ * in k3_dsp_stop() after the local reset is asserted.
+ */
+static int k3_dsp_unprepare(struct udevice *dev)
+{
+	struct k3_dsp_privdata *dsp = dev_get_priv(dev);
+	struct k3_dsp_boot_data *data = dsp->data;
+
+	/* local reset is no-op on C71x processors */
+	if (!data->uses_lreset)
+		return 0;
+
+	return ti_sci_proc_power_domain_off(&dsp->tsp);
+}
+
 /**
  * k3_dsp_load() - Load up the Remote processor image
  * @dev:	rproc device pointer
@@ -62,6 +123,7 @@
 static int k3_dsp_load(struct udevice *dev, ulong addr, ulong size)
 {
 	struct k3_dsp_privdata *dsp = dev_get_priv(dev);
+	struct k3_dsp_boot_data *data = dsp->data;
 	u32 boot_vector;
 	int ret;
 
@@ -70,17 +132,33 @@
 	if (ret)
 		return ret;
 
-	ret = rproc_elf_load_image(dev, addr, size);
-	if (ret < 0) {
-		dev_err(dev, "Loading elf failed %d\n", ret);
+	ret = k3_dsp_prepare(dev);
+	if (ret) {
+		dev_err(dev, "DSP prepare failed for core %d\n",
+			dsp->tsp.proc_id);
 		goto proc_release;
 	}
 
+	ret = rproc_elf_load_image(dev, addr, size);
+	if (ret < 0) {
+		dev_err(dev, "Loading elf failed %d\n", ret);
+		goto unprepare;
+	}
+
 	boot_vector = rproc_elf_get_boot_addr(dev, addr);
+	if (boot_vector & (data->boot_align_addr - 1)) {
+		ret = -EINVAL;
+		dev_err(dev, "Boot vector 0x%x not aligned on 0x%x boundary\n",
+			boot_vector, data->boot_align_addr);
+		goto proc_release;
+	}
 
 	dev_dbg(dev, "%s: Boot vector = 0x%x\n", __func__, boot_vector);
 
 	ret = ti_sci_proc_set_config(&dsp->tsp, boot_vector, 0, 0);
+unprepare:
+	if (ret)
+		k3_dsp_unprepare(dev);
 proc_release:
 	ti_sci_proc_release(&dsp->tsp);
 	return ret;
@@ -95,6 +173,7 @@
 static int k3_dsp_start(struct udevice *dev)
 {
 	struct k3_dsp_privdata *dsp = dev_get_priv(dev);
+	struct k3_dsp_boot_data *data = dsp->data;
 	int ret;
 
 	dev_dbg(dev, "%s\n", __func__);
@@ -102,16 +181,18 @@
 	ret = ti_sci_proc_request(&dsp->tsp);
 	if (ret)
 		return ret;
-	/*
-	 * Setting the right clock frequency would have taken care by
-	 * assigned-clock-rates during the device probe. So no need to
-	 * set the frequency again here.
-	 */
-	ret = ti_sci_proc_power_domain_on(&dsp->tsp);
-	if (ret)
-		goto proc_release;
+
+	if (!data->uses_lreset) {
+		ret = ti_sci_proc_power_domain_on(&dsp->tsp);
+		if (ret)
+			goto proc_release;
+	}
 
 	ret = reset_deassert(&dsp->dsp_rst);
+	if (ret) {
+		if (!data->uses_lreset)
+			ti_sci_proc_power_domain_off(&dsp->tsp);
+	}
 
 proc_release:
 	ti_sci_proc_release(&dsp->tsp);
@@ -302,6 +383,8 @@
 	if (ret)
 		return ret;
 
+	dsp->data = (struct k3_dsp_boot_data *)dev_get_driver_data(dev);
+
 	return 0;
 }
 
@@ -326,6 +409,15 @@
 		return ret;
 	}
 
+	/*
+	 * The DSP local resets are deasserted by default on Power-On-Reset.
+	 * Assert the local resets to ensure the DSPs don't execute bogus code
+	 * in .load() callback when the module reset is released to support
+	 * internal memory loading. This is needed for C66x DSPs, and is a
+	 * no-op on C71x DSPs.
+	 */
+	reset_assert(&dsp->dsp_rst);
+
 	dev_dbg(dev, "Remoteproc successfully probed\n");
 
 	return 0;
@@ -340,9 +432,19 @@
 	return 0;
 }
 
+static const struct k3_dsp_boot_data c66_data = {
+	.boot_align_addr = SZ_1K,
+	.uses_lreset = true,
+};
+
+static const struct k3_dsp_boot_data c71_data = {
+	.boot_align_addr = SZ_2M,
+	.uses_lreset = false,
+};
+
 static const struct udevice_id k3_dsp_ids[] = {
-	{ .compatible = "ti,j721e-c66-dsp"},
-	{ .compatible = "ti,j721e-c71-dsp"},
+	{ .compatible = "ti,j721e-c66-dsp", .data = (ulong)&c66_data, },
+	{ .compatible = "ti,j721e-c71-dsp", .data = (ulong)&c71_data, },
 	{}
 };
 
diff --git a/drivers/remoteproc/ti_k3_r5f_rproc.c b/drivers/remoteproc/ti_k3_r5f_rproc.c
index ea56689..c01b29d 100644
--- a/drivers/remoteproc/ti_k3_r5f_rproc.c
+++ b/drivers/remoteproc/ti_k3_r5f_rproc.c
@@ -543,6 +543,7 @@
 {
 	struct k3_r5f_cluster *cluster = core->cluster;
 	u32 set_cfg = 0, clr_cfg = 0, cfg, ctrl, sts;
+	bool lockstep_permitted;
 	u64 boot_vec = 0;
 	int ret;
 
@@ -560,8 +561,9 @@
 		goto out;
 
 	/* Sanity check for Lockstep mode */
-	if (cluster->mode && is_primary_core(core) &&
-	    !(sts & PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED)) {
+	lockstep_permitted = !!(sts &
+				PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED);
+	if (cluster->mode && is_primary_core(core) && !lockstep_permitted) {
 		dev_err(core->dev, "LockStep mode not permitted on this device\n");
 		ret = -EINVAL;
 		goto out;
@@ -573,7 +575,7 @@
 		clr_cfg |= PROC_BOOT_CFG_FLAG_R5_TEINIT;
 		if (cluster->mode == CLUSTER_MODE_LOCKSTEP)
 			set_cfg |= PROC_BOOT_CFG_FLAG_R5_LOCKSTEP;
-		else
+		else if (lockstep_permitted)
 			clr_cfg |= PROC_BOOT_CFG_FLAG_R5_LOCKSTEP;
 	}
 
@@ -816,4 +818,5 @@
 	.id = UCLASS_MISC,
 	.probe = k3_r5f_cluster_probe,
 	.priv_auto_alloc_size = sizeof(struct k3_r5f_cluster),
+	.flags = DM_FLAG_DEFAULT_PD_CTRL_OFF,
 };
diff --git a/drivers/timer/sti-timer.c b/drivers/timer/sti-timer.c
index 9def7e0..ff42056 100644
--- a/drivers/timer/sti-timer.c
+++ b/drivers/timer/sti-timer.c
@@ -6,14 +6,13 @@
 
 #include <common.h>
 #include <dm.h>
-#include <fdtdec.h>
+#include <clk.h>
 #include <timer.h>
+#include <linux/err.h>
 
 #include <asm/io.h>
 #include <asm/arch-armv7/globaltimer.h>
 
-DECLARE_GLOBAL_DATA_PTR;
-
 struct sti_timer_priv {
 	struct globaltimer *global_timer;
 };
@@ -44,13 +43,24 @@
 {
 	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 	struct sti_timer_priv *priv = dev_get_priv(dev);
-	fdt_addr_t addr;
-
-	uc_priv->clock_rate = CONFIG_SYS_HZ_CLOCK;
+	struct clk clk;
+	int err;
+	ulong ret;
 
 	/* get arm global timer base address */
-	addr = fdtdec_get_addr(gd->fdt_blob, dev_of_offset(dev), "reg");
-	priv->global_timer = (struct globaltimer *)addr;
+	priv->global_timer = (struct globaltimer *)dev_read_addr_ptr(dev);
+	if (!priv->global_timer)
+		return -ENOENT;
+
+	err = clk_get_by_index(dev, 0, &clk);
+	if (!err) {
+		ret = clk_get_rate(&clk);
+		if (IS_ERR_VALUE(ret))
+			return ret;
+		uc_priv->clock_rate = ret;
+	} else {
+		uc_priv->clock_rate = CONFIG_SYS_HZ_CLOCK;
+	}
 
 	/* init timer */
 	writel(0x01, &priv->global_timer->ctl);
diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c
index f947e69..ce84648 100644
--- a/drivers/usb/cdns3/core.c
+++ b/drivers/usb/cdns3/core.c
@@ -108,7 +108,7 @@
 	enum usb_dr_mode dr_mode;
 	int ret = 0;
 
-	dr_mode = usb_get_dr_mode(dev_of_offset(dev));
+	dr_mode = usb_get_dr_mode(dev->node);
 	cdns->role = USB_ROLE_NONE;
 
 	/*
@@ -384,22 +384,20 @@
 
 int cdns3_bind(struct udevice *parent)
 {
-	int from = dev_of_offset(parent);
-	const void *fdt = gd->fdt_blob;
 	enum usb_dr_mode dr_mode;
 	struct udevice *dev;
 	const char *driver;
 	const char *name;
-	int node;
+	ofnode node;
 	int ret;
 
-	node = fdt_node_offset_by_compatible(fdt, from, "cdns,usb3");
-	if (node < 0) {
+	node = ofnode_by_compatible(parent->node, "cdns,usb3");
+	if (!ofnode_valid(node)) {
 		ret = -ENODEV;
 		goto fail;
 	}
 
-	name = fdt_get_name(fdt, node, NULL);
+	name = ofnode_get_name(node);
 	dr_mode = usb_get_dr_mode(node);
 
 	switch (dr_mode) {
@@ -422,8 +420,7 @@
 		goto fail;
 	};
 
-	ret = device_bind_driver_to_node(parent, driver, name,
-					 offset_to_ofnode(node), &dev);
+	ret = device_bind_driver_to_node(parent, driver, name, node, &dev);
 	if (ret) {
 		printf("%s: not able to bind usb device mode\n",
 		       __func__);
diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c
index 8377eb4..caed27c 100644
--- a/drivers/usb/cdns3/gadget.c
+++ b/drivers/usb/cdns3/gadget.c
@@ -2579,7 +2579,7 @@
 	if (!priv_dev->onchip_buffers)
 		priv_dev->onchip_buffers = 256;
 
-	max_speed = usb_get_maximum_speed(dev_of_offset(cdns->dev));
+	max_speed = usb_get_maximum_speed(dev_ofnode(cdns->dev));
 
 	/* Check the maximum_speed parameter */
 	switch (max_speed) {
diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c
index a55def5..0db281b 100644
--- a/drivers/usb/common/common.c
+++ b/drivers/usb/common/common.c
@@ -7,7 +7,7 @@
  */
 
 #include <common.h>
-#include <linux/libfdt.h>
+#include <dm.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/ch9.h>
 
@@ -20,13 +20,12 @@
 	[USB_DR_MODE_OTG]		= "otg",
 };
 
-enum usb_dr_mode usb_get_dr_mode(int node)
+enum usb_dr_mode usb_get_dr_mode(ofnode node)
 {
-	const void *fdt = gd->fdt_blob;
 	const char *dr_mode;
 	int i;
 
-	dr_mode = fdt_getprop(fdt, node, "dr_mode", NULL);
+	dr_mode = ofnode_read_string(node, "dr_mode");
 	if (!dr_mode) {
 		pr_err("usb dr_mode not found\n");
 		return USB_DR_MODE_UNKNOWN;
@@ -48,13 +47,12 @@
 	[USB_SPEED_SUPER] = "super-speed",
 };
 
-enum usb_device_speed usb_get_maximum_speed(int node)
+enum usb_device_speed usb_get_maximum_speed(ofnode node)
 {
-	const void *fdt = gd->fdt_blob;
 	const char *max_speed;
 	int i;
 
-	max_speed = fdt_getprop(fdt, node, "maximum-speed", NULL);
+	max_speed = ofnode_read_string(node, "maximum-speed");
 	if (!max_speed) {
 		pr_err("usb maximum-speed not found\n");
 		return USB_SPEED_UNKNOWN;
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 3e116b2..febcfc0 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -88,9 +88,9 @@
 static int dwc3_generic_ofdata_to_platdata(struct udevice *dev)
 {
 	struct dwc3_generic_plat *plat = dev_get_platdata(dev);
-	int node = dev_of_offset(dev);
+	ofnode node = dev->node;
 
-	plat->base = devfdt_get_addr(dev);
+	plat->base = dev_read_addr(dev);
 
 	plat->maximum_speed = usb_get_maximum_speed(node);
 	if (plat->maximum_speed == USB_SPEED_UNKNOWN) {
@@ -284,13 +284,11 @@
 
 static int dwc3_glue_bind(struct udevice *parent)
 {
-	const void *fdt = gd->fdt_blob;
-	int node;
+	ofnode node;
 	int ret;
 
-	for (node = fdt_first_subnode(fdt, dev_of_offset(parent)); node > 0;
-	     node = fdt_next_subnode(fdt, node)) {
-		const char *name = fdt_get_name(fdt, node, NULL);
+	ofnode_for_each_subnode(node, parent->node) {
+		const char *name = ofnode_get_name(node);
 		enum usb_dr_mode dr_mode;
 		struct udevice *dev;
 		const char *driver = NULL;
@@ -322,7 +320,7 @@
 			continue;
 
 		ret = device_bind_driver_to_node(parent, driver, name,
-						 offset_to_ofnode(node), &dev);
+						 node, &dev);
 		if (ret) {
 			debug("%s: not able to bind usb device mode\n",
 			      __func__);
@@ -400,7 +398,7 @@
 	while (child) {
 		enum usb_dr_mode dr_mode;
 
-		dr_mode = usb_get_dr_mode(dev_of_offset(child));
+		dr_mode = usb_get_dr_mode(child->node);
 		device_find_next_child(&child);
 		if (ops && ops->select_dr_mode)
 			ops->select_dr_mode(dev, index, dr_mode);
diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c
index 832bcd7..d4453f8 100644
--- a/drivers/usb/dwc3/dwc3-meson-g12a.c
+++ b/drivers/usb/dwc3/dwc3-meson-g12a.c
@@ -393,7 +393,7 @@
 	}
 #endif
 
-	priv->otg_mode = usb_get_dr_mode(dev_of_offset(dev));
+	priv->otg_mode = usb_get_dr_mode(dev->node);
 
 	ret = dwc3_meson_g12a_usb_init(priv);
 	if (ret)
diff --git a/drivers/usb/gadget/dwc2_udc_otg.c b/drivers/usb/gadget/dwc2_udc_otg.c
index 496abf3..b9c814c 100644
--- a/drivers/usb/gadget/dwc2_udc_otg.c
+++ b/drivers/usb/gadget/dwc2_udc_otg.c
@@ -1039,13 +1039,12 @@
 static int dwc2_udc_otg_ofdata_to_platdata(struct udevice *dev)
 {
 	struct dwc2_plat_otg_data *platdata = dev_get_platdata(dev);
-	int node = dev_of_offset(dev);
 	ulong drvdata;
 	void (*set_params)(struct dwc2_plat_otg_data *data);
 	int ret;
 
-	if (usb_get_dr_mode(node) != USB_DR_MODE_PERIPHERAL &&
-	    usb_get_dr_mode(node) != USB_DR_MODE_OTG) {
+	if (usb_get_dr_mode(dev->node) != USB_DR_MODE_PERIPHERAL &&
+	    usb_get_dr_mode(dev->node) != USB_DR_MODE_OTG) {
 		dev_dbg(dev, "Invalid mode\n");
 		return -ENODEV;
 	}
diff --git a/drivers/usb/host/dwc3-of-simple.c b/drivers/usb/host/dwc3-of-simple.c
index 45df614..e4abc6f 100644
--- a/drivers/usb/host/dwc3-of-simple.c
+++ b/drivers/usb/host/dwc3-of-simple.c
@@ -12,7 +12,6 @@
 
 #include <common.h>
 #include <dm.h>
-#include <fdtdec.h>
 #include <reset.h>
 #include <clk.h>
 
diff --git a/drivers/usb/host/dwc3-sti-glue.c b/drivers/usb/host/dwc3-sti-glue.c
index ad7cf6e..c99a198 100644
--- a/drivers/usb/host/dwc3-sti-glue.c
+++ b/drivers/usb/host/dwc3-sti-glue.c
@@ -10,8 +10,6 @@
 #include <asm/io.h>
 #include <dm.h>
 #include <errno.h>
-#include <fdtdec.h>
-#include <linux/libfdt.h>
 #include <dm/lists.h>
 #include <regmap.h>
 #include <reset-uclass.h>
@@ -109,8 +107,7 @@
 	int ret;
 	u32 reg[4];
 
-	ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
-				   "reg", reg, ARRAY_SIZE(reg));
+	ret = ofnode_read_u32_array(dev->node, "reg", reg, ARRAY_SIZE(reg));
 	if (ret) {
 		pr_err("unable to find st,stih407-dwc3 reg property(%d)\n", ret);
 		return ret;
@@ -153,18 +150,15 @@
 static int sti_dwc3_glue_bind(struct udevice *dev)
 {
 	struct sti_dwc3_glue_platdata *plat = dev_get_platdata(dev);
-	int dwc3_node;
+	ofnode node, dwc3_node;
 
-	/* check if one subnode is present */
-	dwc3_node = fdt_first_subnode(gd->fdt_blob, dev_of_offset(dev));
-	if (dwc3_node <= 0) {
-		pr_err("Can't find subnode for %s\n", dev->name);
-		return -ENODEV;
+	/* Find snps,dwc3 node from subnode */
+	ofnode_for_each_subnode(node, dev->node) {
+		if (ofnode_device_is_compatible(node, "snps,dwc3"))
+			dwc3_node = node;
 	}
 
-	/* check if the subnode compatible string is the dwc3 one*/
-	if (fdt_node_check_compatible(gd->fdt_blob, dwc3_node,
-				      "snps,dwc3") != 0) {
+	if (!ofnode_valid(node)) {
 		pr_err("Can't find dwc3 subnode for %s\n", dev->name);
 		return -ENODEV;
 	}
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c
index 5c257cc..dd92808 100644
--- a/drivers/usb/host/ehci-msm.c
+++ b/drivers/usb/host/ehci-msm.c
@@ -10,8 +10,6 @@
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
-#include <fdtdec.h>
-#include <linux/libfdt.h>
 #include <usb.h>
 #include <usb/ehci-ci.h>
 #include <usb/ulpi.h>
@@ -108,7 +106,7 @@
 	struct msm_ehci_priv *priv = dev_get_priv(dev);
 
 	priv->ulpi_vp.port_num = 0;
-	priv->ehci = (void *)devfdt_get_addr(dev);
+	priv->ehci = dev_read_addr_ptr(dev);
 
 	if (priv->ehci == (void *)FDT_ADDR_T_NONE)
 		return -EINVAL;
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
index 1993ad6..f2ceb51 100644
--- a/drivers/usb/host/ehci-mx6.c
+++ b/drivers/usb/host/ehci-mx6.c
@@ -513,7 +513,7 @@
 	struct usb_platdata *plat = dev_get_platdata(dev);
 	enum usb_dr_mode dr_mode;
 
-	dr_mode = usb_get_dr_mode(dev_of_offset(dev));
+	dr_mode = usb_get_dr_mode(dev->node);
 
 	switch (dr_mode) {
 	case USB_DR_MODE_HOST:
diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c
index c1c681c..9fcfa39 100644
--- a/drivers/usb/host/xhci-dwc3.c
+++ b/drivers/usb/host/xhci-dwc3.c
@@ -9,7 +9,6 @@
 
 #include <common.h>
 #include <dm.h>
-#include <fdtdec.h>
 #include <generic-phy.h>
 #include <usb.h>
 #include <dwc3-uboot.h>
@@ -155,7 +154,7 @@
 
 	writel(reg, &dwc3_reg->g_usb2phycfg[0]);
 
-	dr_mode = usb_get_dr_mode(dev_of_offset(dev));
+	dr_mode = usb_get_dr_mode(dev->node);
 	if (dr_mode == USB_DR_MODE_UNKNOWN)
 		/* by default set dual role mode to HOST */
 		dr_mode = USB_DR_MODE_HOST;
diff --git a/drivers/usb/musb-new/ti-musb.c b/drivers/usb/musb-new/ti-musb.c
index 00759f3..608face 100644
--- a/drivers/usb/musb-new/ti-musb.c
+++ b/drivers/usb/musb-new/ti-musb.c
@@ -285,14 +285,12 @@
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 static int ti_musb_wrapper_bind(struct udevice *parent)
 {
-	const void *fdt = gd->fdt_blob;
-	int node;
+	ofnode node;
 	int ret;
 
-	for (node = fdt_first_subnode(fdt, dev_of_offset(parent)); node > 0;
-	     node = fdt_next_subnode(fdt, node)) {
+	ofnode_for_each_subnode(node, parent->node) {
 		struct udevice *dev;
-		const char *name = fdt_get_name(fdt, node, NULL);
+		const char *name = ofnode_get_name(node);
 		enum usb_dr_mode dr_mode;
 		struct driver *drv;
 
@@ -306,7 +304,7 @@
 			ret = device_bind_driver_to_node(parent,
 							 "ti-musb-peripheral",
 							 name,
-							 offset_to_ofnode(node),
+							 node,
 							 &dev);
 			if (ret)
 				pr_err("musb - not able to bind usb peripheral node\n");
@@ -316,7 +314,7 @@
 			ret = device_bind_driver_to_node(parent,
 							 "ti-musb-host",
 							 name,
-							 offset_to_ofnode(node),
+							 node,
 							 &dev);
 			if (ret)
 				pr_err("musb - not able to bind usb host node\n");
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 4c93369..7c5012a6 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -473,6 +473,12 @@
 	help
 	   HLCDC supports video output to an attached LCD panel.
 
+config AM335X_LCD
+	bool "Enable AM335x video support"
+	depends on DM_VIDEO
+	help
+	   Supports video output to an attached LCD panel.
+
 config LOGICORE_DP_TX
 	bool "Enable Logicore DP TX driver"
 	depends on DISPLAY
diff --git a/drivers/video/am335x-fb.c b/drivers/video/am335x-fb.c
index 51c1af5..eb5add2 100644
--- a/drivers/video/am335x-fb.c
+++ b/drivers/video/am335x-fb.c
@@ -2,6 +2,7 @@
 /*
  * Copyright (C) 2013-2018 Hannes Schmelzer <oe5hpm@oevsv.at>
  * B&R Industrial Automation GmbH - http://www.br-automation.com
+ * Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
  *
  * minimal framebuffer driver for TI's AM335x SoC to be compatible with
  * Wolfgang Denk's LCD-Framework (CONFIG_LCD, common/lcd.c)
@@ -11,61 +12,69 @@
  * - starts output DMA from gd->fb_base buffer
  */
 #include <common.h>
+#include <dm.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/omap.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/sys_proto.h>
+#include <asm/utils.h>
+#include <linux/err.h>
 #include <lcd.h>
+#include <video.h>
 #include "am335x-fb.h"
 
-#if !defined(LCD_CNTL_BASE)
-#error "hw-base address of LCD-Controller (LCD_CNTL_BASE) not defined!"
-#endif
-
 #define LCDC_FMAX				200000000
 
 /* LCD Control Register */
-#define LCD_CLK_DIVISOR(x)			((x) << 8)
-#define LCD_RASTER_MODE				0x01
+#define LCDC_CTRL_CLK_DIVISOR_MASK		GENMASK(15, 8)
+#define LCDC_CTRL_RASTER_MODE			BIT(0)
+#define LCDC_CTRL_CLK_DIVISOR(x)		(((x) & GENMASK(7, 0)) << 8)
 /* LCD Clock Enable Register */
-#define LCD_CORECLKEN				(0x01 << 0)
-#define LCD_LIDDCLKEN				(0x01 << 1)
-#define LCD_DMACLKEN				(0x01 << 2)
+#define LCDC_CLKC_ENABLE_CORECLKEN		BIT(0)
+#define LCDC_CLKC_ENABLE_LIDDCLKEN		BIT(1)
+#define LCDC_CLKC_ENABLE_DMACLKEN		BIT(2)
 /* LCD DMA Control Register */
-#define LCD_DMA_BURST_SIZE(x)			((x) << 4)
-#define LCD_DMA_BURST_1				0x0
-#define LCD_DMA_BURST_2				0x1
-#define LCD_DMA_BURST_4				0x2
-#define LCD_DMA_BURST_8				0x3
-#define LCD_DMA_BURST_16			0x4
+#define LCDC_DMA_CTRL_BURST_SIZE(x)		(((x) & GENMASK(2, 0)) << 4)
+#define LCDC_DMA_CTRL_BURST_1			0x0
+#define LCDC_DMA_CTRL_BURST_2			0x1
+#define LCDC_DMA_CTRL_BURST_4			0x2
+#define LCDC_DMA_CTRL_BURST_8			0x3
+#define LCDC_DMA_CTRL_BURST_16			0x4
+#define LCDC_DMA_CTRL_FIFO_TH(x)		(((x) & GENMASK(2, 0)) << 8)
 /* LCD Timing_0 Register */
-#define LCD_HBPLSB(x)				((((x)-1) & 0xFF) << 24)
-#define LCD_HFPLSB(x)				((((x)-1) & 0xFF) << 16)
-#define LCD_HSWLSB(x)				((((x)-1) & 0x3F) << 10)
-#define LCD_HORLSB(x)				(((((x) >> 4)-1) & 0x3F) << 4)
-#define LCD_HORMSB(x)				(((((x) >> 4)-1) & 0x40) >> 4)
+#define LCDC_RASTER_TIMING_0_HORMSB(x)	((((x) - 1) & BIT(10)) >> 7)
+#define LCDC_RASTER_TIMING_0_HORLSB(x) (((((x) >> 4) - 1) & GENMASK(5, 0)) << 4)
+#define LCDC_RASTER_TIMING_0_HSWLSB(x)	((((x) - 1) & GENMASK(5, 0)) << 10)
+#define LCDC_RASTER_TIMING_0_HFPLSB(x)	((((x) - 1) & GENMASK(7, 0)) << 16)
+#define LCDC_RASTER_TIMING_0_HBPLSB(x)	((((x) - 1) & GENMASK(7, 0)) << 24)
 /* LCD Timing_1 Register */
-#define LCD_VBP(x)				((x) << 24)
-#define LCD_VFP(x)				((x) << 16)
-#define LCD_VSW(x)				(((x)-1) << 10)
-#define LCD_VERLSB(x)				(((x)-1) & 0x3FF)
+#define LCDC_RASTER_TIMING_1_VERLSB(x)		(((x) - 1) & GENMASK(9, 0))
+#define LCDC_RASTER_TIMING_1_VSW(x)	((((x) - 1) & GENMASK(5, 0)) << 10)
+#define LCDC_RASTER_TIMING_1_VFP(x)		(((x) & GENMASK(7, 0)) << 16)
+#define LCDC_RASTER_TIMING_1_VBP(x)		(((x) & GENMASK(7, 0)) << 24)
 /* LCD Timing_2 Register */
-#define LCD_HSWMSB(x)				((((x)-1) & 0x3C0) << 21)
-#define LCD_VERMSB(x)				((((x)-1) & 0x400) << 16)
-#define LCD_HBPMSB(x)				((((x)-1) & 0x300) >> 4)
-#define LCD_HFPMSB(x)				((((x)-1) & 0x300) >> 8)
-#define LCD_INVMASK(x)				((x) & 0x3F00000)
+#define LCDC_RASTER_TIMING_2_HFPMSB(x)	((((x) - 1) & GENMASK(9, 8)) >> 8)
+#define LCDC_RASTER_TIMING_2_HBPMSB(x)	((((x) - 1) & GENMASK(9, 8)) >> 4)
+#define LCDC_RASTER_TIMING_2_ACB(x)		(((x) & GENMASK(7, 0)) << 8)
+#define LCDC_RASTER_TIMING_2_ACBI(x)		(((x) & GENMASK(3, 0)) << 16)
+#define LCDC_RASTER_TIMING_2_VSYNC_INVERT	BIT(20)
+#define LCDC_RASTER_TIMING_2_HSYNC_INVERT	BIT(21)
+#define LCDC_RASTER_TIMING_2_PXCLK_INVERT	BIT(22)
+#define LCDC_RASTER_TIMING_2_DE_INVERT		BIT(23)
+#define LCDC_RASTER_TIMING_2_HSVS_RISEFALL	BIT(24)
+#define LCDC_RASTER_TIMING_2_HSVS_CONTROL	BIT(25)
+#define LCDC_RASTER_TIMING_2_VERMSB(x)		((((x) - 1) & BIT(10)) << 16)
+#define LCDC_RASTER_TIMING_2_HSWMSB(x)	((((x) - 1) & GENMASK(9, 6)) << 21)
 /* LCD Raster Ctrl Register */
-#define LCD_TFT_24BPP_MODE			(1 << 25)
-#define LCD_TFT_24BPP_UNPACK			(1 << 26)
-#define LCD_PALMODE_RAWDATA			(0x02 << 20)
-#define LCD_TFT_MODE				(0x01 << 7)
-#define LCD_RASTER_ENABLE			(0x01 << 0)
-
-
-/* Macro definitions */
-#define FBSIZE(x)	((x->hactive * x->vactive * x->bpp) >> 3)
+#define LCDC_RASTER_CTRL_ENABLE			BIT(0)
+#define LCDC_RASTER_CTRL_TFT_MODE		BIT(7)
+#define LCDC_RASTER_CTRL_DATA_ORDER		BIT(8)
+#define LCDC_RASTER_CTRL_REQDLY(x)		(((x) & GENMASK(7, 0)) << 12)
+#define LCDC_RASTER_CTRL_PALMODE_RAWDATA	(0x02 << 20)
+#define LCDC_RASTER_CTRL_TFT_ALT_ENABLE		BIT(23)
+#define LCDC_RASTER_CTRL_TFT_24BPP_MODE		BIT(25)
+#define LCDC_RASTER_CTRL_TFT_24BPP_UNPACK	BIT(26)
 
 struct am335x_lcdhw {
 	unsigned int		pid;			/* 0x00 */
@@ -99,10 +108,106 @@
 	unsigned int		clkc_reset;		/* 0x70 */
 };
 
-static struct am335x_lcdhw *lcdhw = (void *)LCD_CNTL_BASE;
+struct dpll_data {
+	unsigned long rounded_rate;
+	u16 rounded_m;
+	u8 rounded_n;
+	u8 rounded_div;
+};
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/**
+ * am335x_dpll_round_rate() - Round a target rate for an OMAP DPLL
+ *
+ * @dpll_data: struct dpll_data pointer for the DPLL
+ * @rate:      New DPLL clock rate
+ * @return rounded rate and the computed m, n and div values in the dpll_data
+ *         structure, or -ve error code.
+ */
+static ulong am335x_dpll_round_rate(struct dpll_data *dd, ulong rate)
+{
+	unsigned int m, n, d;
+	unsigned long rounded_rate;
+	int err, err_r;
+
+	dd->rounded_rate = -EFAULT;
+	err = rate;
+	err_r = err;
+
+	for (d = 2; err && d < 255; d++) {
+		for (m = 2; m < 2047; m++) {
+			if ((V_OSCK * m) < (rate * d))
+				continue;
+
+			n = (V_OSCK * m) / (rate * d);
+			if (n > 127)
+				break;
+
+			if (((V_OSCK * m) / n) > LCDC_FMAX)
+				break;
+
+			rounded_rate = (V_OSCK * m) / n / d;
+			err = abs(rounded_rate - rate);
+			if (err < err_r) {
+				err_r = err;
+				dd->rounded_rate = rounded_rate;
+				dd->rounded_m = m;
+				dd->rounded_n = n;
+				dd->rounded_div = d;
+				if (err == 0)
+					break;
+			}
+		}
+	}
+
+	debug("DPLL display: best error %d Hz (M %d, N %d, DIV %d)\n",
+	      err_r, dd->rounded_m, dd->rounded_n, dd->rounded_div);
+
+	return dd->rounded_rate;
+}
+
+/**
+ * am335x_fb_set_pixel_clk_rate() - Set pixel clock rate.
+ *
+ * @am335x_lcdhw: Base address of the LCD controller registers.
+ * @rate:         New clock rate in Hz.
+ * @return new rate, or -ve error code.
+ */
+static ulong am335x_fb_set_pixel_clk_rate(struct am335x_lcdhw *regs, ulong rate)
+{
+	struct dpll_params dpll_disp = { 1, 0, 1, -1, -1, -1, -1 };
+	struct dpll_data dd;
+	ulong round_rate;
+	u32 reg;
+
+	round_rate = am335x_dpll_round_rate(&dd, rate);
+	if (IS_ERR_VALUE(round_rate))
+		return round_rate;
+
+	dpll_disp.m = dd.rounded_m;
+	dpll_disp.n = dd.rounded_n;
+	do_setup_dpll(&dpll_disp_regs, &dpll_disp);
+
+	reg = readl(&regs->ctrl) & ~LCDC_CTRL_CLK_DIVISOR_MASK;
+	reg |= LCDC_CTRL_CLK_DIVISOR(dd.rounded_div);
+	writel(reg, &regs->ctrl);
+	return round_rate;
+}
+
+#if !CONFIG_IS_ENABLED(DM_VIDEO)
+
+#if !defined(LCD_CNTL_BASE)
+#error "hw-base address of LCD-Controller (LCD_CNTL_BASE) not defined!"
+#endif
+
+/* Macro definitions */
+#define FBSIZE(x)	(((x)->hactive * (x)->vactive * (x)->bpp) >> 3)
+
+#define LCDC_RASTER_TIMING_2_INVMASK(x)		((x) & GENMASK(25, 20))
+
+static struct am335x_lcdhw *lcdhw = (void *)LCD_CNTL_BASE;
+
 int lcd_get_size(int *line_length)
 {
 	*line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
@@ -112,11 +217,9 @@
 int am335xfb_init(struct am335x_lcdpanel *panel)
 {
 	u32 raster_ctrl = 0;
-
 	struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL;
-	struct dpll_params dpll_disp = { 1, 0, 1, -1, -1, -1, -1 };
-	unsigned int m, n, d, best_d = 2;
-	int err = 0, err_r = 0;
+	ulong rate;
+	u32 reg;
 
 	if (gd->fb_base == 0) {
 		printf("ERROR: no valid fb_base stored in GLOBAL_DATA_PTR!\n");
@@ -132,10 +235,10 @@
 	case 16:
 		break;
 	case 32:
-		raster_ctrl |= LCD_TFT_24BPP_UNPACK;
+		raster_ctrl |= LCDC_RASTER_CTRL_TFT_24BPP_UNPACK;
 		/* fallthrough */
 	case 24:
-		raster_ctrl |= LCD_TFT_24BPP_MODE;
+		raster_ctrl |= LCDC_RASTER_CTRL_TFT_24BPP_MODE;
 		break;
 	default:
 		pr_err("am335x-fb: invalid bpp value: %d\n", panel->bpp);
@@ -157,32 +260,9 @@
 	debug("using frambuffer at 0x%08x with size %d.\n",
 	      (unsigned int)gd->fb_base, FBSIZE(panel));
 
-	/* setup display pll for requested clock frequency */
-	err = panel->pxl_clk;
-	err_r = err;
-
-	for (d = 2; d < 255; d++) {
-		for (m = 2; m < 2047; m++) {
-			if ((V_OSCK * m) < (panel->pxl_clk * d))
-				continue;
-			n = (V_OSCK * m) / (panel->pxl_clk * d);
-			if (n > 127)
-				break;
-			if (((V_OSCK * m) / n) > LCDC_FMAX)
-				break;
-
-			err = abs((V_OSCK * m) / n / d - panel->pxl_clk);
-			if (err < err_r) {
-				err_r = err;
-				dpll_disp.m = m;
-				dpll_disp.n = n;
-				best_d = d;
-			}
-		}
-	}
-	debug("%s: PLL: best error %d Hz (M %d, N %d, DISP %d)\n",
-	      __func__, err_r, dpll_disp.m, dpll_disp.n, best_d);
-	do_setup_dpll(&dpll_disp_regs, &dpll_disp);
+	rate = am335x_fb_set_pixel_clk_rate(lcdhw, panel->pxl_clk);
+	if (IS_ERR_VALUE(rate))
+		return rate;
 
 	/* clock source for LCDC from dispPLL M2 */
 	writel(0x0, &cmdpll->clklcdcpixelclk);
@@ -199,37 +279,340 @@
 
 	debug("am335x-fb: wait for stable power ...\n");
 	mdelay(panel->pup_delay);
-	lcdhw->clkc_enable = LCD_CORECLKEN | LCD_LIDDCLKEN | LCD_DMACLKEN;
+	lcdhw->clkc_enable = LCDC_CLKC_ENABLE_CORECLKEN |
+		LCDC_CLKC_ENABLE_LIDDCLKEN | LCDC_CLKC_ENABLE_DMACLKEN;
 	lcdhw->raster_ctrl = 0;
-	lcdhw->ctrl = LCD_CLK_DIVISOR(best_d) | LCD_RASTER_MODE;
+
+	reg = lcdhw->ctrl & LCDC_CTRL_CLK_DIVISOR_MASK;
+	reg |= LCDC_CTRL_RASTER_MODE;
+	lcdhw->ctrl = reg;
+
 	lcdhw->lcddma_fb0_base = gd->fb_base;
 	lcdhw->lcddma_fb0_ceiling = gd->fb_base + FBSIZE(panel);
 	lcdhw->lcddma_fb1_base = gd->fb_base;
 	lcdhw->lcddma_fb1_ceiling = gd->fb_base + FBSIZE(panel);
-	lcdhw->lcddma_ctrl = LCD_DMA_BURST_SIZE(LCD_DMA_BURST_16);
+	lcdhw->lcddma_ctrl = LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_16);
 
-	lcdhw->raster_timing0 = LCD_HORLSB(panel->hactive) |
-				LCD_HORMSB(panel->hactive) |
-				LCD_HFPLSB(panel->hfp) |
-				LCD_HBPLSB(panel->hbp) |
-				LCD_HSWLSB(panel->hsw);
-	lcdhw->raster_timing1 = LCD_VBP(panel->vbp) |
-				LCD_VFP(panel->vfp) |
-				LCD_VSW(panel->vsw) |
-				LCD_VERLSB(panel->vactive);
-	lcdhw->raster_timing2 = LCD_HSWMSB(panel->hsw) |
-				LCD_VERMSB(panel->vactive) |
-				LCD_INVMASK(panel->pol) |
-				LCD_HBPMSB(panel->hbp) |
-				LCD_HFPMSB(panel->hfp) |
+	lcdhw->raster_timing0 = LCDC_RASTER_TIMING_0_HORLSB(panel->hactive) |
+				LCDC_RASTER_TIMING_0_HORMSB(panel->hactive) |
+				LCDC_RASTER_TIMING_0_HFPLSB(panel->hfp) |
+				LCDC_RASTER_TIMING_0_HBPLSB(panel->hbp) |
+				LCDC_RASTER_TIMING_0_HSWLSB(panel->hsw);
+	lcdhw->raster_timing1 = LCDC_RASTER_TIMING_1_VBP(panel->vbp) |
+				LCDC_RASTER_TIMING_1_VFP(panel->vfp) |
+				LCDC_RASTER_TIMING_1_VSW(panel->vsw) |
+				LCDC_RASTER_TIMING_1_VERLSB(panel->vactive);
+	lcdhw->raster_timing2 = LCDC_RASTER_TIMING_2_HSWMSB(panel->hsw) |
+				LCDC_RASTER_TIMING_2_VERMSB(panel->vactive) |
+				LCDC_RASTER_TIMING_2_INVMASK(panel->pol) |
+				LCDC_RASTER_TIMING_2_HBPMSB(panel->hbp) |
+				LCDC_RASTER_TIMING_2_HFPMSB(panel->hfp) |
 				0x0000FF00;	/* clk cycles for ac-bias */
 	lcdhw->raster_ctrl =	raster_ctrl |
-				LCD_PALMODE_RAWDATA |
-				LCD_TFT_MODE |
-				LCD_RASTER_ENABLE;
+				LCDC_RASTER_CTRL_PALMODE_RAWDATA |
+				LCDC_RASTER_CTRL_TFT_MODE |
+				LCDC_RASTER_CTRL_ENABLE;
 
 	debug("am335x-fb: waiting picture to be stable.\n.");
 	mdelay(panel->pon_delay);
 
 	return 0;
 }
+
+#else /* CONFIG_DM_VIDEO */
+
+#define FBSIZE(t, p)	(((t)->hactive.typ * (t)->vactive.typ * (p)->bpp) >> 3)
+
+enum {
+	LCD_MAX_WIDTH		= 2048,
+	LCD_MAX_HEIGHT		= 2048,
+	LCD_MAX_LOG2_BPP	= VIDEO_BPP32,
+};
+
+/**
+ * tilcdc_panel_info: Panel parameters
+ *
+ * @ac_bias: AC Bias Pin Frequency
+ * @ac_bias_intrpt: AC Bias Pin Transitions per Interrupt
+ * @dma_burst_sz: DMA burst size
+ * @bpp: Bits per pixel
+ * @fdd: FIFO DMA Request Delay
+ * @tft_alt_mode: TFT Alternative Signal Mapping (Only for active)
+ * @invert_pxl_clk: Invert pixel clock
+ * @sync_edge: Horizontal and Vertical Sync Edge: 0=rising 1=falling
+ * @sync_ctrl: Horizontal and Vertical Sync: Control: 0=ignore
+ * @raster_order: Raster Data Order Select: 1=Most-to-least 0=Least-to-most
+ * @fifo_th: DMA FIFO threshold
+ */
+struct tilcdc_panel_info {
+	u32 ac_bias;
+	u32 ac_bias_intrpt;
+	u32 dma_burst_sz;
+	u32 bpp;
+	u32 fdd;
+	bool tft_alt_mode;
+	bool invert_pxl_clk;
+	u32 sync_edge;
+	u32 sync_ctrl;
+	u32 raster_order;
+	u32 fifo_th;
+};
+
+struct am335x_fb_priv {
+	struct am335x_lcdhw *regs;
+	struct tilcdc_panel_info panel;
+	struct display_timing timing;
+};
+
+static int am335x_fb_remove(struct udevice *dev)
+{
+	struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
+
+	uc_plat->base -= 0x20;
+	uc_plat->size += 0x20;
+	return 0;
+}
+
+static int am335x_fb_probe(struct udevice *dev)
+{
+	struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
+	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct am335x_fb_priv *priv = dev_get_priv(dev);
+	struct am335x_lcdhw *regs = priv->regs;
+	struct tilcdc_panel_info *panel = &priv->panel;
+	struct display_timing *timing = &priv->timing;
+	struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL;
+	u32 reg;
+
+	/* Before relocation we don't need to do anything */
+	if (!(gd->flags & GD_FLG_RELOC))
+		return 0;
+
+	am335x_fb_set_pixel_clk_rate(regs, timing->pixelclock.typ);
+
+	/* clock source for LCDC from dispPLL M2 */
+	writel(0, &cmdpll->clklcdcpixelclk);
+
+	/* palette default entry */
+	memset((void *)uc_plat->base, 0, 0x20);
+	*(unsigned int *)uc_plat->base = 0x4000;
+	/* point fb behind palette */
+	uc_plat->base += 0x20;
+	uc_plat->size -= 0x20;
+
+	writel(LCDC_CLKC_ENABLE_CORECLKEN | LCDC_CLKC_ENABLE_LIDDCLKEN |
+	       LCDC_CLKC_ENABLE_DMACLKEN, &regs->clkc_enable);
+	writel(0, &regs->raster_ctrl);
+
+	reg = readl(&regs->ctrl) & LCDC_CTRL_CLK_DIVISOR_MASK;
+	reg |= LCDC_CTRL_RASTER_MODE;
+	writel(reg, &regs->ctrl);
+
+	writel(uc_plat->base, &regs->lcddma_fb0_base);
+	writel(uc_plat->base + FBSIZE(timing, panel),
+	       &regs->lcddma_fb0_ceiling);
+	writel(uc_plat->base, &regs->lcddma_fb1_base);
+	writel(uc_plat->base + FBSIZE(timing, panel),
+	       &regs->lcddma_fb1_ceiling);
+
+	reg = LCDC_DMA_CTRL_FIFO_TH(panel->fifo_th);
+	switch (panel->dma_burst_sz) {
+	case 1:
+		reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_1);
+		break;
+	case 2:
+		reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_2);
+		break;
+	case 4:
+		reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_4);
+		break;
+	case 8:
+		reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_8);
+		break;
+	case 16:
+		reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_16);
+		break;
+	}
+
+	writel(reg, &regs->lcddma_ctrl);
+
+	writel(LCDC_RASTER_TIMING_0_HORLSB(timing->hactive.typ) |
+	       LCDC_RASTER_TIMING_0_HORMSB(timing->hactive.typ) |
+	       LCDC_RASTER_TIMING_0_HFPLSB(timing->hfront_porch.typ) |
+	       LCDC_RASTER_TIMING_0_HBPLSB(timing->hback_porch.typ) |
+	       LCDC_RASTER_TIMING_0_HSWLSB(timing->hsync_len.typ),
+	       &regs->raster_timing0);
+
+	writel(LCDC_RASTER_TIMING_1_VBP(timing->vback_porch.typ) |
+	       LCDC_RASTER_TIMING_1_VFP(timing->vfront_porch.typ) |
+	       LCDC_RASTER_TIMING_1_VSW(timing->vsync_len.typ) |
+	       LCDC_RASTER_TIMING_1_VERLSB(timing->vactive.typ),
+	       &regs->raster_timing1);
+
+	reg = LCDC_RASTER_TIMING_2_ACB(panel->ac_bias) |
+		LCDC_RASTER_TIMING_2_ACBI(panel->ac_bias_intrpt) |
+		LCDC_RASTER_TIMING_2_HSWMSB(timing->hsync_len.typ) |
+		LCDC_RASTER_TIMING_2_VERMSB(timing->vactive.typ) |
+		LCDC_RASTER_TIMING_2_HBPMSB(timing->hback_porch.typ) |
+		LCDC_RASTER_TIMING_2_HFPMSB(timing->hfront_porch.typ);
+
+	if (timing->flags & DISPLAY_FLAGS_VSYNC_LOW)
+		reg |= LCDC_RASTER_TIMING_2_VSYNC_INVERT;
+
+	if (timing->flags & DISPLAY_FLAGS_HSYNC_LOW)
+		reg |= LCDC_RASTER_TIMING_2_HSYNC_INVERT;
+
+	if (panel->invert_pxl_clk)
+		reg |= LCDC_RASTER_TIMING_2_PXCLK_INVERT;
+
+	if (panel->sync_edge)
+		reg |= LCDC_RASTER_TIMING_2_HSVS_RISEFALL;
+
+	if (panel->sync_ctrl)
+		reg |= LCDC_RASTER_TIMING_2_HSVS_CONTROL;
+
+	writel(reg, &regs->raster_timing2);
+
+	reg = LCDC_RASTER_CTRL_PALMODE_RAWDATA | LCDC_RASTER_CTRL_TFT_MODE |
+		LCDC_RASTER_CTRL_ENABLE | LCDC_RASTER_CTRL_REQDLY(panel->fdd);
+
+	if (panel->tft_alt_mode)
+		reg |= LCDC_RASTER_CTRL_TFT_ALT_ENABLE;
+
+	if (panel->bpp == 24)
+		reg |= LCDC_RASTER_CTRL_TFT_24BPP_MODE;
+	else if (panel->bpp == 32)
+		reg |= LCDC_RASTER_CTRL_TFT_24BPP_MODE |
+			LCDC_RASTER_CTRL_TFT_24BPP_UNPACK;
+
+	if (panel->raster_order)
+		reg |= LCDC_RASTER_CTRL_DATA_ORDER;
+
+	writel(reg, &regs->raster_ctrl);
+
+	uc_priv->xsize = timing->hactive.typ;
+	uc_priv->ysize = timing->vactive.typ;
+	uc_priv->bpix = log_2_n_round_up(panel->bpp);
+	return 0;
+}
+
+static int am335x_fb_ofdata_to_platdata(struct udevice *dev)
+{
+	struct am335x_fb_priv *priv = dev_get_priv(dev);
+	struct tilcdc_panel_info *panel = &priv->panel;
+	struct display_timing *timing = &priv->timing;
+	ofnode node;
+	int err;
+
+	node = ofnode_by_compatible(ofnode_null(), "ti,am33xx-tilcdc");
+	if (!ofnode_valid(node)) {
+		dev_err(dev, "missing 'ti,am33xx-tilcdc' node\n");
+		return -ENXIO;
+	}
+
+	priv->regs = (struct am335x_lcdhw *)ofnode_get_addr(node);
+	dev_dbg(dev, "LCD: base address=0x%x\n", (unsigned int)priv->regs);
+
+	err = ofnode_decode_display_timing(dev_ofnode(dev), 0, timing);
+	if (err) {
+		dev_err(dev, "failed to get display timing\n");
+		return err;
+	}
+
+	if (timing->pixelclock.typ > (LCDC_FMAX / 2)) {
+		dev_err(dev, "invalid display clock-frequency: %d Hz\n",
+			timing->pixelclock.typ);
+		return -EINVAL;
+	}
+
+	if (timing->hactive.typ > LCD_MAX_WIDTH)
+		timing->hactive.typ = LCD_MAX_WIDTH;
+
+	if (timing->vactive.typ > LCD_MAX_HEIGHT)
+		timing->vactive.typ = LCD_MAX_HEIGHT;
+
+	node = ofnode_find_subnode(dev_ofnode(dev), "panel-info");
+	if (!ofnode_valid(node)) {
+		dev_err(dev, "missing 'panel-info' node\n");
+		return -ENXIO;
+	}
+
+	err |= ofnode_read_u32(node, "ac-bias", &panel->ac_bias);
+	err |= ofnode_read_u32(node, "ac-bias-intrpt", &panel->ac_bias_intrpt);
+	err |= ofnode_read_u32(node, "dma-burst-sz", &panel->dma_burst_sz);
+	err |= ofnode_read_u32(node, "bpp", &panel->bpp);
+	err |= ofnode_read_u32(node, "fdd", &panel->fdd);
+	err |= ofnode_read_u32(node, "sync-edge", &panel->sync_edge);
+	err |= ofnode_read_u32(node, "sync-ctrl", &panel->sync_ctrl);
+	err |= ofnode_read_u32(node, "raster-order", &panel->raster_order);
+	err |= ofnode_read_u32(node, "fifo-th", &panel->fifo_th);
+	if (err) {
+		dev_err(dev, "failed to get panel info\n");
+		return err;
+	}
+
+	switch (panel->bpp) {
+	case 16:
+	case 24:
+	case 32:
+		break;
+	default:
+		dev_err(dev, "invalid seting, bpp: %d\n", panel->bpp);
+		return -EINVAL;
+	}
+
+	switch (panel->dma_burst_sz) {
+	case 1:
+	case 2:
+	case 4:
+	case 8:
+	case 16:
+		break;
+	default:
+		dev_err(dev, "invalid setting, dma-burst-sz: %d\n",
+			panel->dma_burst_sz);
+		return -EINVAL;
+	}
+
+	/* optional */
+	panel->tft_alt_mode = ofnode_read_bool(node, "tft-alt-mode");
+	panel->invert_pxl_clk = ofnode_read_bool(node, "invert-pxl-clk");
+
+	dev_dbg(dev, "LCD: %dx%d, bpp=%d, clk=%d Hz\n", timing->hactive.typ,
+		timing->vactive.typ, panel->bpp, timing->pixelclock.typ);
+	dev_dbg(dev, "     hbp=%d, hfp=%d, hsw=%d\n", timing->hback_porch.typ,
+		timing->hfront_porch.typ, timing->hsync_len.typ);
+	dev_dbg(dev, "     vbp=%d, vfp=%d, vsw=%d\n", timing->vback_porch.typ,
+		timing->vfront_porch.typ, timing->vsync_len.typ);
+
+	return 0;
+}
+
+static int am335x_fb_bind(struct udevice *dev)
+{
+	struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
+
+	uc_plat->size = ((LCD_MAX_WIDTH * LCD_MAX_HEIGHT *
+			  (1 << LCD_MAX_LOG2_BPP)) >> 3) + 0x20;
+
+	dev_dbg(dev, "frame buffer size 0x%x\n", uc_plat->size);
+	return 0;
+}
+
+static const struct udevice_id am335x_fb_ids[] = {
+	{ .compatible = "ti,tilcdc,panel" },
+	{ }
+};
+
+U_BOOT_DRIVER(am335x_fb) = {
+	.name = "am335x_fb",
+	.id = UCLASS_VIDEO,
+	.of_match = am335x_fb_ids,
+	.bind = am335x_fb_bind,
+	.ofdata_to_platdata = am335x_fb_ofdata_to_platdata,
+	.probe = am335x_fb_probe,
+	.remove = am335x_fb_remove,
+	.priv_auto_alloc_size = sizeof(struct am335x_fb_priv),
+};
+
+#endif /* CONFIG_DM_VIDEO */
diff --git a/drivers/video/am335x-fb.h b/drivers/video/am335x-fb.h
index f5883c0..c9f92bc 100644
--- a/drivers/video/am335x-fb.h
+++ b/drivers/video/am335x-fb.h
@@ -7,7 +7,9 @@
 #ifndef AM335X_FB_H
 #define AM335X_FB_H
 
-#define HSVS_CONTROL	(0x01 << 25)	/*
+#if !CONFIG_IS_ENABLED(DM_VIDEO)
+
+#define HSVS_CONTROL		BIT(25)	/*
 					 * 0 = lcd_lp and lcd_fp are driven on
 					 * opposite edges of pixel clock than
 					 * the lcd_pixel_o
@@ -17,7 +19,7 @@
 					 * Matrix displays the edge timing is
 					 * fixed
 					 */
-#define HSVS_RISEFALL	(0x01 << 24)	/*
+#define HSVS_RISEFALL		BIT(24)	/*
 					 * 0 = lcd_lp and lcd_fp are driven on
 					 * the rising edge of pixel clock (bit
 					 * 25 must be set to 1)
@@ -25,19 +27,19 @@
 					 * the falling edge of pixel clock (bit
 					 * 25 must be set to 1)
 					 */
-#define DE_INVERT	(0x01 << 23)	/*
+#define DE_INVERT		BIT(23)	/*
 					 * 0 = DE is low-active
 					 * 1 = DE is high-active
 					 */
-#define PXCLK_INVERT	(0x01 << 22)	/*
+#define PXCLK_INVERT		BIT(22)	/*
 					 * 0 = pix-clk is high-active
 					 * 1 = pic-clk is low-active
 					 */
-#define HSYNC_INVERT	(0x01 << 21)	/*
+#define HSYNC_INVERT		BIT(21)	/*
 					 * 0 = HSYNC is active high
 					 * 1 = HSYNC is avtive low
 					 */
-#define VSYNC_INVERT	(0x01 << 20)	/*
+#define VSYNC_INVERT		BIT(20)	/*
 					 * 0 = VSYNC is active high
 					 * 1 = VSYNC is active low
 					 */
@@ -68,4 +70,6 @@
 
 int am335xfb_init(struct am335x_lcdpanel *panel);
 
+#endif  /* CONFIG_DM_VIDEO */
+
 #endif  /* AM335X_FB_H */
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 5d02732..d9e220c 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -25,7 +25,7 @@
 #include <linux/list.h>
 
 typedef struct global_data {
-	bd_t *bd;
+	struct bd_info *bd;
 	unsigned long flags;
 	unsigned int baudrate;
 	unsigned long cpu_clk;		/* CPU clock in Hz!		*/
diff --git a/include/asm-generic/u-boot.h b/include/asm-generic/u-boot.h
index eee84f4..cc94d39 100644
--- a/include/asm-generic/u-boot.h
+++ b/include/asm-generic/u-boot.h
@@ -23,6 +23,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <linux/types.h>
+
 typedef struct bd_info {
 	unsigned long	bi_memstart;	/* start of DRAM memory */
 	phys_size_t	bi_memsize;	/* size	 of DRAM memory in bytes */
diff --git a/include/configs/am65x_evm.h b/include/configs/am65x_evm.h
index 23ee225..19d861d 100644
--- a/include/configs/am65x_evm.h
+++ b/include/configs/am65x_evm.h
@@ -73,7 +73,8 @@
 	"name_kern=Image\0"						\
 	"console=ttyS2,115200n8\0"					\
 	"stdin=serial,usbkbd\0"						\
-	"args_all=setenv optargs earlycon=ns16550a,mmio32,0x02800000\0" \
+	"args_all=setenv optargs earlycon=ns16550a,mmio32,0x02800000 "  \
+		"${mtdparts}\0"						\
 	"run_kern=booti ${loadaddr} ${rd_spec} ${fdtaddr}\0"		\
 
 /* U-Boot MMC-specific configuration */
@@ -106,6 +107,22 @@
 		"0 /lib/firmware/am65x-mcu-r5f0_0-fw "			\
 		"1 /lib/firmware/am65x-mcu-r5f0_1-fw "
 
+#ifdef CONFIG_TARGET_AM654_A53_EVM
+#define EXTRA_ENV_AM65X_BOARD_SETTINGS_MTD				\
+	"mtdids=" CONFIG_MTDIDS_DEFAULT "\0"				\
+	"mtdparts=" CONFIG_MTDPARTS_DEFAULT "\0"
+#else
+#define EXTRA_ENV_AM65X_BOARD_SETTINGS_MTD
+#endif
+
+#define EXTRA_ENV_AM65X_BOARD_SETTINGS_UBI				\
+	"init_ubi=run args_all args_ubi; sf probe; "			\
+		"ubi part ospi.rootfs; ubifsmount ubi:rootfs;\0"	\
+	"get_kern_ubi=ubifsload ${loadaddr} ${bootdir}/${name_kern}\0"	\
+	"get_fdt_ubi=ubifsload ${fdtaddr} ${bootdir}/${name_fdt}\0"	\
+	"args_ubi=setenv bootargs console=${console} ${optargs} "	\
+		"rootfstype=ubifs root=ubi0:rootfs rw ubi.mtd=ospi.rootfs\0"
+
 #define EXTRA_ENV_DFUARGS						\
 	"dfu_bufsiz=0x20000\0"						\
 	DFU_ALT_INFO_MMC						\
@@ -118,6 +135,8 @@
 	DEFAULT_FIT_TI_ARGS						\
 	EXTRA_ENV_AM65X_BOARD_SETTINGS					\
 	EXTRA_ENV_AM65X_BOARD_SETTINGS_MMC				\
+	EXTRA_ENV_AM65X_BOARD_SETTINGS_MTD				\
+	EXTRA_ENV_AM65X_BOARD_SETTINGS_UBI				\
 	EXTRA_ENV_RPROC_SETTINGS					\
 	EXTRA_ENV_DFUARGS
 
diff --git a/include/configs/brxre1.h b/include/configs/brxre1.h
index ea15912..0066633 100644
--- a/include/configs/brxre1.h
+++ b/include/configs/brxre1.h
@@ -14,7 +14,9 @@
 #include <configs/bur_cfg_common.h>
 #include <configs/bur_am335x_common.h>
 /* ------------------------------------------------------------------------- */
+#if !defined(CONFIG_AM335X_LCD)
 #define CONFIG_AM335X_LCD
+#endif
 #define LCD_BPP				LCD_COLOR32
 
 /* memory */
diff --git a/include/configs/j721e_evm.h b/include/configs/j721e_evm.h
index 4371c47..7488b66 100644
--- a/include/configs/j721e_evm.h
+++ b/include/configs/j721e_evm.h
@@ -74,7 +74,8 @@
 	"overlayaddr=0x83000000\0"					\
 	"name_kern=Image\0"						\
 	"console=ttyS2,115200n8\0"					\
-	"args_all=setenv optargs earlycon=ns16550a,mmio32,0x02800000\0" \
+	"args_all=setenv optargs earlycon=ns16550a,mmio32,0x02800000 "	\
+		"${mtdparts}\0"						\
 	"run_kern=booti ${loadaddr} ${rd_spec} ${fdtaddr}\0"
 
 #define PARTS_DEFAULT \
@@ -88,6 +89,10 @@
 	"mmcdev=1\0"							\
 	"bootpart=1:2\0"						\
 	"bootdir=/boot\0"						\
+	"addr_mainr5f0_0load=88000000\0"					\
+	"name_mainr5f0_0fw=/lib/firmware/j7-main-r5f0_0-fw\0"		\
+	"addr_mcur5f0_0load=89000000\0"					\
+	"name_mcur5f0_0fw=/lib/firmware/j7-mcu-r5f0_0-fw\0"		\
 	"rd_spec=-\0"							\
 	"init_mmc=run args_all args_mmc\0"				\
 	"get_fdt_mmc=load mmc ${bootpart} ${fdtaddr} ${bootdir}/${name_fdt}\0" \
@@ -124,6 +129,14 @@
 	DFU_ALT_INFO_RAM \
 	DFU_ALT_INFO_OSPI
 
+#ifdef CONFIG_TARGET_J721E_A72_EVM
+#define EXTRA_ENV_J721E_BOARD_SETTINGS_MTD				\
+	"mtdids=" CONFIG_MTDIDS_DEFAULT "\0"				\
+	"mtdparts=" CONFIG_MTDPARTS_DEFAULT "\0"
+#else
+#define EXTRA_ENV_J721E_BOARD_SETTINGS_MTD
+#endif
+
 /* Incorporate settings into the U-Boot environment */
 #define CONFIG_EXTRA_ENV_SETTINGS					\
 	DEFAULT_MMC_TI_ARGS						\
@@ -132,7 +145,8 @@
 	EXTRA_ENV_J721E_BOARD_SETTINGS_MMC				\
 	EXTRA_ENV_RPROC_SETTINGS					\
 	EXTRA_ENV_DFUARGS						\
-	DEFAULT_UFS_TI_ARGS
+	DEFAULT_UFS_TI_ARGS						\
+	EXTRA_ENV_J721E_BOARD_SETTINGS_MTD
 
 /* Now for the remaining common defines */
 #include <configs/ti_armv7_common.h>
diff --git a/include/debug_uart.h b/include/debug_uart.h
index cd70ae1..4d1c580 100644
--- a/include/debug_uart.h
+++ b/include/debug_uart.h
@@ -88,28 +88,28 @@
  *
  * @value:	Value to output
  */
-void printhex2(uint value);
+void printhex2(unsigned int value);
 
 /**
  * printhex4() - Output a 4-digit hex value
  *
  * @value:	Value to output
  */
-void printhex4(uint value);
+void printhex4(unsigned int value);
 
 /**
  * printhex8() - Output a 8-digit hex value
  *
  * @value:	Value to output
  */
-void printhex8(uint value);
+void printhex8(unsigned int value);
 
 /**
  * printdec() - Output a decimalism value
  *
  * @value:	Value to output
  */
-void printdec(uint value);
+void printdec(unsigned int value);
 
 #ifdef CONFIG_DEBUG_UART_ANNOUNCE
 #define _DEBUG_UART_ANNOUNCE	printascii("<debug_uart> ");
@@ -151,34 +151,34 @@
 			_printch(*str++); \
 	} \
 \
-	static inline void printhex1(uint digit) \
+	static inline void printhex1(unsigned int digit) \
 	{ \
 		digit &= 0xf; \
 		_debug_uart_putc(digit > 9 ? digit - 10 + 'a' : digit + '0'); \
 	} \
 \
-	static inline void printhex(uint value, int digits) \
+	static inline void printhex(unsigned int value, int digits) \
 	{ \
 		while (digits-- > 0) \
 			printhex1(value >> (4 * digits)); \
 	} \
 \
-	void printhex2(uint value) \
+	void printhex2(unsigned int value) \
 	{ \
 		printhex(value, 2); \
 	} \
 \
-	void printhex4(uint value) \
+	void printhex4(unsigned int value) \
 	{ \
 		printhex(value, 4); \
 	} \
 \
-	void printhex8(uint value) \
+	void printhex8(unsigned int value) \
 	{ \
 		printhex(value, 8); \
 	} \
 \
-	void printdec(uint value) \
+	void printdec(unsigned int value) \
 	{ \
 		if (value > 10) { \
 			printdec(value / 10); \
diff --git a/include/elf.h b/include/elf.h
index 81f4019..e7c5198 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -692,6 +692,10 @@
 
 #ifndef __ASSEMBLER__
 int valid_elf_image(unsigned long addr);
+unsigned long load_elf64_image_phdr(unsigned long addr);
+unsigned long load_elf64_image_shdr(unsigned long addr);
+unsigned long load_elf_image_phdr(unsigned long addr);
+unsigned long load_elf_image_shdr(unsigned long addr);
 #endif
 
 #endif /* _ELF_H */
diff --git a/include/environment/ti/boot.h b/include/environment/ti/boot.h
index 523c8fc..11a57af 100644
--- a/include/environment/ti/boot.h
+++ b/include/environment/ti/boot.h
@@ -103,18 +103,18 @@
 		"echo \"  Reading DTB for AM57x EVM RevA3...\"; " \
 		"abootimg get dtb --index=0 dtb_start dtb_size; " \
 		"cp.b $dtb_start $fdtaddr $dtb_size; " \
-		"fdt addr $fdtaddr; " \
+		"fdt addr $fdtaddr 0x80000; " \
 		"echo \"  Applying DTBOs for AM57x EVM RevA3...\"; " \
 		"adtimg addr $dtboaddr; " \
-		"adtimg get dt --index=0 dtbo0_addr; " \
+		"adtimg get dt --index=0 dtbo0_addr dtbo0_size; " \
 		"fdt apply $dtbo0_addr; " \
-		"adtimg get dt --index=1 dtbo1_addr; " \
+		"adtimg get dt --index=1 dtbo1_addr dtbo1_size; " \
 		"fdt apply $dtbo1_addr; " \
 	"elif test $board_name = beagle_x15_revc; then " \
 		"echo \"  Reading DTB for Beagle X15 RevC...\"; " \
 		"abootimg get dtb --index=0 dtb_start dtb_size; " \
 		"cp.b $dtb_start $fdtaddr $dtb_size; " \
-		"fdt addr $fdtaddr; " \
+		"fdt addr $fdtaddr 0x80000; " \
 	"else " \
 		"echo Error: Android boot is not supported for $board_name; " \
 		"exit; " \
diff --git a/include/i2c.h b/include/i2c.h
index 0faf854..0592001 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -331,6 +331,24 @@
 int i2c_deblock(struct udevice *bus);
 
 /**
+ * i2c_deblock_gpio_loop() - recover a bus from an unknown state by toggling SDA/SCL
+ *
+ * This is the inner logic used for toggling I2C SDA/SCL lines as GPIOs
+ * for deblocking the I2C bus.
+ *
+ * @sda_pin:	SDA GPIO
+ * @scl_pin:	SCL GPIO
+ * @scl_count:	Number of SCL clock cycles generated to deblock SDA
+ * @start_count:Number of I2C start conditions sent after deblocking SDA
+ * @delay:	Delay between SCL clock line changes
+ * @return 0 if OK, -ve on error
+ */
+struct gpio_desc;
+int i2c_deblock_gpio_loop(struct gpio_desc *sda_pin, struct gpio_desc *scl_pin,
+			  unsigned int scl_count, unsigned int start_count,
+			  unsigned int delay);
+
+/**
  * struct dm_i2c_ops - driver operations for I2C uclass
  *
  * Drivers should support these operations unless otherwise noted. These
diff --git a/include/i2c_eeprom.h b/include/i2c_eeprom.h
index b96254a..cd620d5 100644
--- a/include/i2c_eeprom.h
+++ b/include/i2c_eeprom.h
@@ -16,8 +16,6 @@
 struct i2c_eeprom {
 	/* The EEPROM's page size in byte */
 	unsigned long pagesize;
-	/* The EEPROM's page width in bits (pagesize = 2^pagewidth) */
-	unsigned pagewidth;
 	/* The EEPROM's capacity in bytes */
 	unsigned long size;
 };
diff --git a/include/image.h b/include/image.h
index 3ffc0fd..2388c1f 100644
--- a/include/image.h
+++ b/include/image.h
@@ -1136,6 +1136,7 @@
 
 int fit_check_ramdisk(const void *fit, int os_noffset,
 		uint8_t arch, int verify);
+#endif /* IMAGE_ENABLE_FIT */
 
 int calculate_hash(const void *data, int data_len, const char *algo,
 			uint8_t *value, int *value_len);
@@ -1148,16 +1149,20 @@
 # if defined(CONFIG_FIT_SIGNATURE)
 #  define IMAGE_ENABLE_SIGN	1
 #  define IMAGE_ENABLE_VERIFY	1
+#  define FIT_IMAGE_ENABLE_VERIFY	1
 #  include <openssl/evp.h>
 # else
 #  define IMAGE_ENABLE_SIGN	0
 #  define IMAGE_ENABLE_VERIFY	0
+#  define FIT_IMAGE_ENABLE_VERIFY	0
 # endif
 #else
 # define IMAGE_ENABLE_SIGN	0
-# define IMAGE_ENABLE_VERIFY	CONFIG_IS_ENABLED(FIT_SIGNATURE)
+# define IMAGE_ENABLE_VERIFY		CONFIG_IS_ENABLED(RSA_VERIFY)
+# define FIT_IMAGE_ENABLE_VERIFY	CONFIG_IS_ENABLED(FIT_SIGNATURE)
 #endif
 
+#if IMAGE_ENABLE_FIT
 #ifdef USE_HOSTCC
 void *image_get_host_blob(void);
 void image_set_host_blob(void *host_blob);
@@ -1171,6 +1176,7 @@
 #else
 #define IMAGE_ENABLE_BEST_MATCH	0
 #endif
+#endif /* IMAGE_ENABLE_FIT */
 
 /* Information passed to the signing routines */
 struct image_sign_info {
@@ -1186,18 +1192,21 @@
 	int required_keynode;		/* Node offset of key to use: -1=any */
 	const char *require_keys;	/* Value for 'required' property */
 	const char *engine_id;		/* Engine to use for signing */
+	/*
+	 * Note: the following two fields are always valid even w/o
+	 * RSA_VERIFY_WITH_PKEY in order to make sure this structure is
+	 * the same on target and host. Otherwise, vboot test may fail.
+	 */
+	const void *key;		/* Pointer to public key in DER */
+	int keylen;			/* Length of public key */
 };
 
-#endif /* Allow struct image_region to always be defined for rsa.h */
-
 /* A part of an image, used for hashing */
 struct image_region {
 	const void *data;
 	int size;
 };
 
-#if IMAGE_ENABLE_FIT
-
 #if IMAGE_ENABLE_VERIFY
 # include <u-boot/rsa-checksum.h>
 #endif
@@ -1298,6 +1307,8 @@
  */
 struct padding_algo *image_get_padding_algo(const char *name);
 
+#if IMAGE_ENABLE_FIT
+
 /**
  * fit_image_verify_required_sigs() - Verify signatures marked as 'required'
  *
@@ -1438,6 +1449,7 @@
 #endif /* CONFIG_FIT_VERBOSE */
 #endif /* CONFIG_FIT */
 
+#if !defined(USE_HOSTCC)
 #if defined(CONFIG_ANDROID_BOOT_IMAGE)
 struct andr_img_hdr;
 int android_image_check_header(const struct andr_img_hdr *hdr);
@@ -1459,6 +1471,7 @@
 #endif
 
 #endif /* CONFIG_ANDROID_BOOT_IMAGE */
+#endif /* !USE_HOSTCC */
 
 /**
  * board_fit_config_name_match() - Check for a matching board name
diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h
index 1cba8d9..8c4863e 100644
--- a/include/linux/soc/ti/ti_sci_protocol.h
+++ b/include/linux/soc/ti/ti_sci_protocol.h
@@ -327,8 +327,6 @@
 /**
  * struct ti_sci_rm_ringacc_ops - Ring Accelerator Management operations
  * @config: configure the SoC Navigator Subsystem Ring Accelerator ring
- * @get_config: get the SoC Navigator Subsystem Ring Accelerator ring
- *		configuration
  */
 struct ti_sci_rm_ringacc_ops {
 	int (*config)(const struct ti_sci_handle *handle,
@@ -336,10 +334,6 @@
 		      u32 addr_lo, u32 addr_hi, u32 count, u8 mode,
 		      u8 size, u8 order_id
 	);
-	int (*get_config)(const struct ti_sci_handle *handle,
-			  u32 nav_id, u32 index, u8 *mode,
-			  u32 *addr_lo, u32 *addr_hi, u32 *count,
-			  u8 *size, u8 *order_id);
 };
 
 /**
diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h
index d2604c5..c19b916 100644
--- a/include/linux/usb/otg.h
+++ b/include/linux/usb/otg.h
@@ -9,6 +9,8 @@
 #ifndef __LINUX_USB_OTG_H
 #define __LINUX_USB_OTG_H
 
+#include <dm/ofnode.h>
+
 enum usb_dr_mode {
 	USB_DR_MODE_UNKNOWN,
 	USB_DR_MODE_HOST,
@@ -18,20 +20,20 @@
 
 /**
  * usb_get_dr_mode() - Get dual role mode for given device
- * @node: Node offset to the given device
+ * @node: ofnode of the given device
  *
  * The function gets phy interface string from property 'dr_mode',
  * and returns the correspondig enum usb_dr_mode
  */
-enum usb_dr_mode usb_get_dr_mode(int node);
+enum usb_dr_mode usb_get_dr_mode(ofnode node);
 
 /**
  * usb_get_maximum_speed() - Get maximum speed for given device
- * @node: Node offset to the given device
+ * @node: ofnode of the given device
  *
  * The function gets phy interface string from property 'maximum-speed',
  * and returns the correspondig enum usb_device_speed
  */
-enum usb_device_speed usb_get_maximum_speed(int node);
+enum usb_device_speed usb_get_maximum_speed(ofnode node);
 
 #endif /* __LINUX_USB_OTG_H */
diff --git a/include/power/stpmic1.h b/include/power/stpmic1.h
index dc8b5a7..1493a67 100644
--- a/include/power/stpmic1.h
+++ b/include/power/stpmic1.h
@@ -37,6 +37,7 @@
 #define STPMIC1_BUCK_VOUT(sel)		(sel << STPMIC1_BUCK_VOUT_SHIFT)
 
 #define STPMIC1_BUCK2_1200000V		STPMIC1_BUCK_VOUT(24)
+#define STPMIC1_BUCK2_1250000V		STPMIC1_BUCK_VOUT(26)
 #define STPMIC1_BUCK2_1350000V		STPMIC1_BUCK_VOUT(30)
 
 #define STPMIC1_BUCK3_1800000V		STPMIC1_BUCK_VOUT(39)
diff --git a/include/spl.h b/include/spl.h
index 6087cd7..5d8d14d 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -10,9 +10,13 @@
 
 /* Platform-specific defines */
 #include <linux/compiler.h>
+#include <asm/global_data.h>
 #include <asm/spl.h>
 #include <handoff.h>
 
+struct blk_desc;
+struct image_header;
+
 /* Value in r0 indicates we booted from U-Boot */
 #define UBOOT_NOT_LOADED_FROM_SPL	0x13578642
 
diff --git a/include/u-boot/rsa-mod-exp.h b/include/u-boot/rsa-mod-exp.h
index 8a428c4..1da8af1 100644
--- a/include/u-boot/rsa-mod-exp.h
+++ b/include/u-boot/rsa-mod-exp.h
@@ -27,6 +27,29 @@
 };
 
 /**
+ * rsa_gen_key_prop() - Generate key properties of RSA public key
+ * @key:	Specifies key data in DER format
+ * @keylen:	Length of @key
+ * @prop:	Generated key property
+ *
+ * This function takes a blob of encoded RSA public key data in DER
+ * format, parse it and generate all the relevant properties
+ * in key_prop structure.
+ * Return a pointer to struct key_prop in @prop on success.
+ *
+ * Return:	0 on success, negative on error
+ */
+int rsa_gen_key_prop(const void *key, uint32_t keylen, struct key_prop **proc);
+
+/**
+ * rsa_free_key_prop() - Free key properties
+ * @prop:	Pointer to struct key_prop
+ *
+ * This function frees all the memories allocated by rsa_gen_key_prop().
+ */
+void rsa_free_key_prop(struct key_prop *prop);
+
+/**
  * rsa_mod_exp_sw() - Perform RSA Modular Exponentiation in sw
  *
  * Operation: out[] = sig ^ exponent % modulus
diff --git a/lib/Kconfig b/lib/Kconfig
index ab6aff7..452f390 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -602,4 +602,10 @@
 config LIB_DATE
 	bool
 
+config LIB_ELF
+	bool
+	help
+	  Supoort basic elf loading/validating functions.
+	  This supports fir 32 bit and 64 bit versions.
+
 endmenu
diff --git a/lib/Makefile b/lib/Makefile
index 15259d0..32bf3f3 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -122,6 +122,7 @@
 endif
 
 obj-y += date.o
+obj-$(CONFIG_LIB_ELF) += elf.o
 
 #
 # Build a fast OID lookup registry from include/linux/oid_registry.h
diff --git a/lib/elf.c b/lib/elf.c
new file mode 100644
index 0000000..d074e4e
--- /dev/null
+++ b/lib/elf.c
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+   Copyright (c) 2001 William L. Pitts
+*/
+
+#include <common.h>
+#include <command.h>
+#include <cpu_func.h>
+#include <elf.h>
+#include <env.h>
+#include <net.h>
+#include <vxworks.h>
+#ifdef CONFIG_X86
+#include <vbe.h>
+#include <asm/e820.h>
+#include <linux/linkage.h>
+#endif
+
+/*
+ * A very simple ELF64 loader, assumes the image is valid, returns the
+ * entry point address.
+ *
+ * Note if U-Boot is 32-bit, the loader assumes the to segment's
+ * physical address and size is within the lower 32-bit address space.
+ */
+unsigned long load_elf64_image_phdr(unsigned long addr)
+{
+	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
+	Elf64_Phdr *phdr; /* Program header structure pointer */
+	int i;
+
+	ehdr = (Elf64_Ehdr *)addr;
+	phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
+
+	/* Load each program header */
+	for (i = 0; i < ehdr->e_phnum; ++i) {
+		void *dst = (void *)(ulong)phdr->p_paddr;
+		void *src = (void *)addr + phdr->p_offset;
+
+		debug("Loading phdr %i to 0x%p (%lu bytes)\n",
+		      i, dst, (ulong)phdr->p_filesz);
+		if (phdr->p_filesz)
+			memcpy(dst, src, phdr->p_filesz);
+		if (phdr->p_filesz != phdr->p_memsz)
+			memset(dst + phdr->p_filesz, 0x00,
+			       phdr->p_memsz - phdr->p_filesz);
+		flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
+			    roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
+		++phdr;
+	}
+
+	if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
+					    EF_PPC64_ELFV1_ABI)) {
+		/*
+		 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
+		 * descriptor pointer with the first double word being the
+		 * address of the entry point of the function.
+		 */
+		uintptr_t addr = ehdr->e_entry;
+
+		return *(Elf64_Addr *)addr;
+	}
+
+	return ehdr->e_entry;
+}
+
+unsigned long load_elf64_image_shdr(unsigned long addr)
+{
+	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
+	Elf64_Shdr *shdr; /* Section header structure pointer */
+	unsigned char *strtab = 0; /* String table pointer */
+	unsigned char *image; /* Binary image pointer */
+	int i; /* Loop counter */
+
+	ehdr = (Elf64_Ehdr *)addr;
+
+	/* Find the section header string table for output info */
+	shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
+			     (ehdr->e_shstrndx * sizeof(Elf64_Shdr)));
+
+	if (shdr->sh_type == SHT_STRTAB)
+		strtab = (unsigned char *)(addr + (ulong)shdr->sh_offset);
+
+	/* Load each appropriate section */
+	for (i = 0; i < ehdr->e_shnum; ++i) {
+		shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
+				     (i * sizeof(Elf64_Shdr)));
+
+		if (!(shdr->sh_flags & SHF_ALLOC) ||
+		    shdr->sh_addr == 0 || shdr->sh_size == 0) {
+			continue;
+		}
+
+		if (strtab) {
+			debug("%sing %s @ 0x%08lx (%ld bytes)\n",
+			      (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
+			       &strtab[shdr->sh_name],
+			       (unsigned long)shdr->sh_addr,
+			       (long)shdr->sh_size);
+		}
+
+		if (shdr->sh_type == SHT_NOBITS) {
+			memset((void *)(uintptr_t)shdr->sh_addr, 0,
+			       shdr->sh_size);
+		} else {
+			image = (unsigned char *)addr + (ulong)shdr->sh_offset;
+			memcpy((void *)(uintptr_t)shdr->sh_addr,
+			       (const void *)image, shdr->sh_size);
+		}
+		flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
+			    roundup((shdr->sh_addr + shdr->sh_size),
+				     ARCH_DMA_MINALIGN) -
+				rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
+	}
+
+	if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
+					    EF_PPC64_ELFV1_ABI)) {
+		/*
+		 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
+		 * descriptor pointer with the first double word being the
+		 * address of the entry point of the function.
+		 */
+		uintptr_t addr = ehdr->e_entry;
+
+		return *(Elf64_Addr *)addr;
+	}
+
+	return ehdr->e_entry;
+}
+
+/*
+ * A very simple ELF loader, assumes the image is valid, returns the
+ * entry point address.
+ *
+ * The loader firstly reads the EFI class to see if it's a 64-bit image.
+ * If yes, call the ELF64 loader. Otherwise continue with the ELF32 loader.
+ */
+unsigned long load_elf_image_phdr(unsigned long addr)
+{
+	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
+	Elf32_Phdr *phdr; /* Program header structure pointer */
+	int i;
+
+	ehdr = (Elf32_Ehdr *)addr;
+	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
+		return load_elf64_image_phdr(addr);
+
+	phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
+
+	/* Load each program header */
+	for (i = 0; i < ehdr->e_phnum; ++i) {
+		void *dst = (void *)(uintptr_t)phdr->p_paddr;
+		void *src = (void *)addr + phdr->p_offset;
+
+		debug("Loading phdr %i to 0x%p (%i bytes)\n",
+		      i, dst, phdr->p_filesz);
+		if (phdr->p_filesz)
+			memcpy(dst, src, phdr->p_filesz);
+		if (phdr->p_filesz != phdr->p_memsz)
+			memset(dst + phdr->p_filesz, 0x00,
+			       phdr->p_memsz - phdr->p_filesz);
+		flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
+			    roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
+		++phdr;
+	}
+
+	return ehdr->e_entry;
+}
+
+unsigned long load_elf_image_shdr(unsigned long addr)
+{
+	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
+	Elf32_Shdr *shdr; /* Section header structure pointer */
+	unsigned char *strtab = 0; /* String table pointer */
+	unsigned char *image; /* Binary image pointer */
+	int i; /* Loop counter */
+
+	ehdr = (Elf32_Ehdr *)addr;
+	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
+		return load_elf64_image_shdr(addr);
+
+	/* Find the section header string table for output info */
+	shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
+			     (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
+
+	if (shdr->sh_type == SHT_STRTAB)
+		strtab = (unsigned char *)(addr + shdr->sh_offset);
+
+	/* Load each appropriate section */
+	for (i = 0; i < ehdr->e_shnum; ++i) {
+		shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
+				     (i * sizeof(Elf32_Shdr)));
+
+		if (!(shdr->sh_flags & SHF_ALLOC) ||
+		    shdr->sh_addr == 0 || shdr->sh_size == 0) {
+			continue;
+		}
+
+		if (strtab) {
+			debug("%sing %s @ 0x%08lx (%ld bytes)\n",
+			      (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
+			       &strtab[shdr->sh_name],
+			       (unsigned long)shdr->sh_addr,
+			       (long)shdr->sh_size);
+		}
+
+		if (shdr->sh_type == SHT_NOBITS) {
+			memset((void *)(uintptr_t)shdr->sh_addr, 0,
+			       shdr->sh_size);
+		} else {
+			image = (unsigned char *)addr + shdr->sh_offset;
+			memcpy((void *)(uintptr_t)shdr->sh_addr,
+			       (const void *)image, shdr->sh_size);
+		}
+		flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
+			    roundup((shdr->sh_addr + shdr->sh_size),
+				    ARCH_DMA_MINALIGN) -
+			    rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
+	}
+
+	return ehdr->e_entry;
+}
+
+/*
+ * Determine if a valid ELF image exists at the given memory location.
+ * First look at the ELF header magic field, then make sure that it is
+ * executable.
+ */
+int valid_elf_image(unsigned long addr)
+{
+	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
+
+	ehdr = (Elf32_Ehdr *)addr;
+
+	if (!IS_ELF(*ehdr)) {
+		printf("## No elf image at address 0x%08lx\n", addr);
+		return 0;
+	}
+
+	if (ehdr->e_type != ET_EXEC) {
+		printf("## Not a 32-bit elf image at address 0x%08lx\n", addr);
+		return 0;
+	}
+
+	return 1;
+}
diff --git a/lib/rsa/Kconfig b/lib/rsa/Kconfig
index 2b33f32..a90d67e 100644
--- a/lib/rsa/Kconfig
+++ b/lib/rsa/Kconfig
@@ -18,6 +18,33 @@
 config SPL_RSA
 	bool "Use RSA Library within SPL"
 
+config SPL_RSA_VERIFY
+	bool
+	help
+	  Add RSA signature verification support in SPL.
+
+config RSA_VERIFY
+	bool
+	help
+	  Add RSA signature verification support.
+
+config RSA_VERIFY_WITH_PKEY
+	bool "Execute RSA verification without key parameters from FDT"
+	select RSA_VERIFY
+	select ASYMMETRIC_KEY_TYPE
+	select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+	select RSA_PUBLIC_KEY_PARSER
+	help
+	  The standard RSA-signature verification code (FIT_SIGNATURE) uses
+	  pre-calculated key properties, that are stored in fdt blob, in
+	  decrypting a signature.
+	  This does not suit the use case where there is no way defined to
+	  provide such additional key properties in standardized form,
+	  particularly UEFI secure boot.
+	  This options enables RSA signature verification with a public key
+	  directly specified in image_sign_info, where all the necessary
+	  key properties will be calculated on the fly in verification code.
+
 config RSA_SOFTWARE_EXP
 	bool "Enable driver for RSA Modular Exponentiation in software"
 	depends on DM
diff --git a/lib/rsa/Makefile b/lib/rsa/Makefile
index a51c6e1..14ed3cb 100644
--- a/lib/rsa/Makefile
+++ b/lib/rsa/Makefile
@@ -5,5 +5,6 @@
 # (C) Copyright 2000-2007
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
-obj-$(CONFIG_$(SPL_)FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o
+obj-$(CONFIG_$(SPL_)RSA_VERIFY) += rsa-verify.o rsa-checksum.o
+obj-$(CONFIG_RSA_VERIFY_WITH_PKEY) += rsa-keyprop.o
 obj-$(CONFIG_RSA_SOFTWARE_EXP) += rsa-mod-exp.o
diff --git a/lib/rsa/rsa-keyprop.c b/lib/rsa/rsa-keyprop.c
new file mode 100644
index 0000000..9464df0
--- /dev/null
+++ b/lib/rsa/rsa-keyprop.c
@@ -0,0 +1,725 @@
+// SPDX-License-Identifier: GPL-2.0+ and MIT
+/*
+ * RSA library - generate parameters for a public key
+ *
+ * Copyright (c) 2019 Linaro Limited
+ * Author: AKASHI Takahiro
+ *
+ * Big number routines in this file come from BearSSL:
+ * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
+ */
+
+#include <common.h>
+#include <image.h>
+#include <malloc.h>
+#include <asm/byteorder.h>
+#include <crypto/internal/rsa.h>
+#include <u-boot/rsa-mod-exp.h>
+
+/**
+ * br_dec16be() - Convert 16-bit big-endian integer to native
+ * @src:	Pointer to data
+ * Return:	Native-endian integer
+ */
+static unsigned br_dec16be(const void *src)
+{
+	return be16_to_cpup(src);
+}
+
+/**
+ * br_dec32be() - Convert 32-bit big-endian integer to native
+ * @src:	Pointer to data
+ * Return:	Native-endian integer
+ */
+static uint32_t br_dec32be(const void *src)
+{
+	return be32_to_cpup(src);
+}
+
+/**
+ * br_enc32be() - Convert native 32-bit integer to big-endian
+ * @dst:	Pointer to buffer to store big-endian integer in
+ * @x:		Native 32-bit integer
+ */
+static void br_enc32be(void *dst, uint32_t x)
+{
+	__be32 tmp;
+
+	tmp = cpu_to_be32(x);
+	memcpy(dst, &tmp, sizeof(tmp));
+}
+
+/* from BearSSL's src/inner.h */
+
+/*
+ * Negate a boolean.
+ */
+static uint32_t NOT(uint32_t ctl)
+{
+	return ctl ^ 1;
+}
+
+/*
+ * Multiplexer: returns x if ctl == 1, y if ctl == 0.
+ */
+static uint32_t MUX(uint32_t ctl, uint32_t x, uint32_t y)
+{
+	return y ^ (-ctl & (x ^ y));
+}
+
+/*
+ * Equality check: returns 1 if x == y, 0 otherwise.
+ */
+static uint32_t EQ(uint32_t x, uint32_t y)
+{
+	uint32_t q;
+
+	q = x ^ y;
+	return NOT((q | -q) >> 31);
+}
+
+/*
+ * Inequality check: returns 1 if x != y, 0 otherwise.
+ */
+static uint32_t NEQ(uint32_t x, uint32_t y)
+{
+	uint32_t q;
+
+	q = x ^ y;
+	return (q | -q) >> 31;
+}
+
+/*
+ * Comparison: returns 1 if x > y, 0 otherwise.
+ */
+static uint32_t GT(uint32_t x, uint32_t y)
+{
+	/*
+	 * If both x < 2^31 and y < 2^31, then y-x will have its high
+	 * bit set if x > y, cleared otherwise.
+	 *
+	 * If either x >= 2^31 or y >= 2^31 (but not both), then the
+	 * result is the high bit of x.
+	 *
+	 * If both x >= 2^31 and y >= 2^31, then we can virtually
+	 * subtract 2^31 from both, and we are back to the first case.
+	 * Since (y-2^31)-(x-2^31) = y-x, the subtraction is already
+	 * fine.
+	 */
+	uint32_t z;
+
+	z = y - x;
+	return (z ^ ((x ^ y) & (x ^ z))) >> 31;
+}
+
+/*
+ * Compute the bit length of a 32-bit integer. Returned value is between 0
+ * and 32 (inclusive).
+ */
+static uint32_t BIT_LENGTH(uint32_t x)
+{
+	uint32_t k, c;
+
+	k = NEQ(x, 0);
+	c = GT(x, 0xFFFF); x = MUX(c, x >> 16, x); k += c << 4;
+	c = GT(x, 0x00FF); x = MUX(c, x >>  8, x); k += c << 3;
+	c = GT(x, 0x000F); x = MUX(c, x >>  4, x); k += c << 2;
+	c = GT(x, 0x0003); x = MUX(c, x >>  2, x); k += c << 1;
+	k += GT(x, 0x0001);
+	return k;
+}
+
+#define GE(x, y)   NOT(GT(y, x))
+#define LT(x, y)   GT(y, x)
+#define MUL(x, y)   ((uint64_t)(x) * (uint64_t)(y))
+
+/*
+ * Integers 'i32'
+ * --------------
+ *
+ * The 'i32' functions implement computations on big integers using
+ * an internal representation as an array of 32-bit integers. For
+ * an array x[]:
+ *  -- x[0] contains the "announced bit length" of the integer
+ *  -- x[1], x[2]... contain the value in little-endian order (x[1]
+ *     contains the least significant 32 bits)
+ *
+ * Multiplications rely on the elementary 32x32->64 multiplication.
+ *
+ * The announced bit length specifies the number of bits that are
+ * significant in the subsequent 32-bit words. Unused bits in the
+ * last (most significant) word are set to 0; subsequent words are
+ * uninitialized and need not exist at all.
+ *
+ * The execution time and memory access patterns of all computations
+ * depend on the announced bit length, but not on the actual word
+ * values. For modular integers, the announced bit length of any integer
+ * modulo n is equal to the actual bit length of n; thus, computations
+ * on modular integers are "constant-time" (only the modulus length may
+ * leak).
+ */
+
+/*
+ * Extract one word from an integer. The offset is counted in bits.
+ * The word MUST entirely fit within the word elements corresponding
+ * to the announced bit length of a[].
+ */
+static uint32_t br_i32_word(const uint32_t *a, uint32_t off)
+{
+	size_t u;
+	unsigned j;
+
+	u = (size_t)(off >> 5) + 1;
+	j = (unsigned)off & 31;
+	if (j == 0) {
+		return a[u];
+	} else {
+		return (a[u] >> j) | (a[u + 1] << (32 - j));
+	}
+}
+
+/* from BearSSL's src/int/i32_bitlen.c */
+
+/*
+ * Compute the actual bit length of an integer. The argument x should
+ * point to the first (least significant) value word of the integer.
+ * The len 'xlen' contains the number of 32-bit words to access.
+ *
+ * CT: value or length of x does not leak.
+ */
+static uint32_t br_i32_bit_length(uint32_t *x, size_t xlen)
+{
+	uint32_t tw, twk;
+
+	tw = 0;
+	twk = 0;
+	while (xlen -- > 0) {
+		uint32_t w, c;
+
+		c = EQ(tw, 0);
+		w = x[xlen];
+		tw = MUX(c, w, tw);
+		twk = MUX(c, (uint32_t)xlen, twk);
+	}
+	return (twk << 5) + BIT_LENGTH(tw);
+}
+
+/* from BearSSL's src/int/i32_decode.c */
+
+/*
+ * Decode an integer from its big-endian unsigned representation. The
+ * "true" bit length of the integer is computed, but all words of x[]
+ * corresponding to the full 'len' bytes of the source are set.
+ *
+ * CT: value or length of x does not leak.
+ */
+static void br_i32_decode(uint32_t *x, const void *src, size_t len)
+{
+	const unsigned char *buf;
+	size_t u, v;
+
+	buf = src;
+	u = len;
+	v = 1;
+	for (;;) {
+		if (u < 4) {
+			uint32_t w;
+
+			if (u < 2) {
+				if (u == 0) {
+					break;
+				} else {
+					w = buf[0];
+				}
+			} else {
+				if (u == 2) {
+					w = br_dec16be(buf);
+				} else {
+					w = ((uint32_t)buf[0] << 16)
+						| br_dec16be(buf + 1);
+				}
+			}
+			x[v ++] = w;
+			break;
+		} else {
+			u -= 4;
+			x[v ++] = br_dec32be(buf + u);
+		}
+	}
+	x[0] = br_i32_bit_length(x + 1, v - 1);
+}
+
+/* from BearSSL's src/int/i32_encode.c */
+
+/*
+ * Encode an integer into its big-endian unsigned representation. The
+ * output length in bytes is provided (parameter 'len'); if the length
+ * is too short then the integer is appropriately truncated; if it is
+ * too long then the extra bytes are set to 0.
+ */
+static void br_i32_encode(void *dst, size_t len, const uint32_t *x)
+{
+	unsigned char *buf;
+	size_t k;
+
+	buf = dst;
+
+	/*
+	 * Compute the announced size of x in bytes; extra bytes are
+	 * filled with zeros.
+	 */
+	k = (x[0] + 7) >> 3;
+	while (len > k) {
+		*buf ++ = 0;
+		len --;
+	}
+
+	/*
+	 * Now we use k as index within x[]. That index starts at 1;
+	 * we initialize it to the topmost complete word, and process
+	 * any remaining incomplete word.
+	 */
+	k = (len + 3) >> 2;
+	switch (len & 3) {
+	case 3:
+		*buf ++ = x[k] >> 16;
+		/* fall through */
+	case 2:
+		*buf ++ = x[k] >> 8;
+		/* fall through */
+	case 1:
+		*buf ++ = x[k];
+		k --;
+	}
+
+	/*
+	 * Encode all complete words.
+	 */
+	while (k > 0) {
+		br_enc32be(buf, x[k]);
+		k --;
+		buf += 4;
+	}
+}
+
+/* from BearSSL's src/int/i32_ninv32.c */
+
+/*
+ * Compute -(1/x) mod 2^32. If x is even, then this function returns 0.
+ */
+static uint32_t br_i32_ninv32(uint32_t x)
+{
+	uint32_t y;
+
+	y = 2 - x;
+	y *= 2 - y * x;
+	y *= 2 - y * x;
+	y *= 2 - y * x;
+	y *= 2 - y * x;
+	return MUX(x & 1, -y, 0);
+}
+
+/* from BearSSL's src/int/i32_add.c */
+
+/*
+ * Add b[] to a[] and return the carry (0 or 1). If ctl is 0, then a[]
+ * is unmodified, but the carry is still computed and returned. The
+ * arrays a[] and b[] MUST have the same announced bit length.
+ *
+ * a[] and b[] MAY be the same array, but partial overlap is not allowed.
+ */
+static uint32_t br_i32_add(uint32_t *a, const uint32_t *b, uint32_t ctl)
+{
+	uint32_t cc;
+	size_t u, m;
+
+	cc = 0;
+	m = (a[0] + 63) >> 5;
+	for (u = 1; u < m; u ++) {
+		uint32_t aw, bw, naw;
+
+		aw = a[u];
+		bw = b[u];
+		naw = aw + bw + cc;
+
+		/*
+		 * Carry is 1 if naw < aw. Carry is also 1 if naw == aw
+		 * AND the carry was already 1.
+		 */
+		cc = (cc & EQ(naw, aw)) | LT(naw, aw);
+		a[u] = MUX(ctl, naw, aw);
+	}
+	return cc;
+}
+
+/* from BearSSL's src/int/i32_sub.c */
+
+/*
+ * Subtract b[] from a[] and return the carry (0 or 1). If ctl is 0,
+ * then a[] is unmodified, but the carry is still computed and returned.
+ * The arrays a[] and b[] MUST have the same announced bit length.
+ *
+ * a[] and b[] MAY be the same array, but partial overlap is not allowed.
+ */
+static uint32_t br_i32_sub(uint32_t *a, const uint32_t *b, uint32_t ctl)
+{
+	uint32_t cc;
+	size_t u, m;
+
+	cc = 0;
+	m = (a[0] + 63) >> 5;
+	for (u = 1; u < m; u ++) {
+		uint32_t aw, bw, naw;
+
+		aw = a[u];
+		bw = b[u];
+		naw = aw - bw - cc;
+
+		/*
+		 * Carry is 1 if naw > aw. Carry is 1 also if naw == aw
+		 * AND the carry was already 1.
+		 */
+		cc = (cc & EQ(naw, aw)) | GT(naw, aw);
+		a[u] = MUX(ctl, naw, aw);
+	}
+	return cc;
+}
+
+/* from BearSSL's src/int/i32_div32.c */
+
+/*
+ * Constant-time division. The dividend hi:lo is divided by the
+ * divisor d; the quotient is returned and the remainder is written
+ * in *r. If hi == d, then the quotient does not fit on 32 bits;
+ * returned value is thus truncated. If hi > d, returned values are
+ * indeterminate.
+ */
+static uint32_t br_divrem(uint32_t hi, uint32_t lo, uint32_t d, uint32_t *r)
+{
+	/* TODO: optimize this */
+	uint32_t q;
+	uint32_t ch, cf;
+	int k;
+
+	q = 0;
+	ch = EQ(hi, d);
+	hi = MUX(ch, 0, hi);
+	for (k = 31; k > 0; k --) {
+		int j;
+		uint32_t w, ctl, hi2, lo2;
+
+		j = 32 - k;
+		w = (hi << j) | (lo >> k);
+		ctl = GE(w, d) | (hi >> k);
+		hi2 = (w - d) >> j;
+		lo2 = lo - (d << k);
+		hi = MUX(ctl, hi2, hi);
+		lo = MUX(ctl, lo2, lo);
+		q |= ctl << k;
+	}
+	cf = GE(lo, d) | hi;
+	q |= cf;
+	*r = MUX(cf, lo - d, lo);
+	return q;
+}
+
+/*
+ * Wrapper for br_divrem(); the remainder is returned, and the quotient
+ * is discarded.
+ */
+static uint32_t br_rem(uint32_t hi, uint32_t lo, uint32_t d)
+{
+	uint32_t r;
+
+	br_divrem(hi, lo, d, &r);
+	return r;
+}
+
+/*
+ * Wrapper for br_divrem(); the quotient is returned, and the remainder
+ * is discarded.
+ */
+static uint32_t br_div(uint32_t hi, uint32_t lo, uint32_t d)
+{
+	uint32_t r;
+
+	return br_divrem(hi, lo, d, &r);
+}
+
+/* from BearSSL's src/int/i32_muladd.c */
+
+/*
+ * Multiply x[] by 2^32 and then add integer z, modulo m[]. This
+ * function assumes that x[] and m[] have the same announced bit
+ * length, and the announced bit length of m[] matches its true
+ * bit length.
+ *
+ * x[] and m[] MUST be distinct arrays.
+ *
+ * CT: only the common announced bit length of x and m leaks, not
+ * the values of x, z or m.
+ */
+static void br_i32_muladd_small(uint32_t *x, uint32_t z, const uint32_t *m)
+{
+	uint32_t m_bitlen;
+	size_t u, mlen;
+	uint32_t a0, a1, b0, hi, g, q, tb;
+	uint32_t chf, clow, under, over;
+	uint64_t cc;
+
+	/*
+	 * We can test on the modulus bit length since we accept to
+	 * leak that length.
+	 */
+	m_bitlen = m[0];
+	if (m_bitlen == 0) {
+		return;
+	}
+	if (m_bitlen <= 32) {
+		x[1] = br_rem(x[1], z, m[1]);
+		return;
+	}
+	mlen = (m_bitlen + 31) >> 5;
+
+	/*
+	 * Principle: we estimate the quotient (x*2^32+z)/m by
+	 * doing a 64/32 division with the high words.
+	 *
+	 * Let:
+	 *   w = 2^32
+	 *   a = (w*a0 + a1) * w^N + a2
+	 *   b = b0 * w^N + b2
+	 * such that:
+	 *   0 <= a0 < w
+	 *   0 <= a1 < w
+	 *   0 <= a2 < w^N
+	 *   w/2 <= b0 < w
+	 *   0 <= b2 < w^N
+	 *   a < w*b
+	 * I.e. the two top words of a are a0:a1, the top word of b is
+	 * b0, we ensured that b0 is "full" (high bit set), and a is
+	 * such that the quotient q = a/b fits on one word (0 <= q < w).
+	 *
+	 * If a = b*q + r (with 0 <= r < q), we can estimate q by
+	 * doing an Euclidean division on the top words:
+	 *   a0*w+a1 = b0*u + v  (with 0 <= v < w)
+	 * Then the following holds:
+	 *   0 <= u <= w
+	 *   u-2 <= q <= u
+	 */
+	a0 = br_i32_word(x, m_bitlen - 32);
+	hi = x[mlen];
+	memmove(x + 2, x + 1, (mlen - 1) * sizeof *x);
+	x[1] = z;
+	a1 = br_i32_word(x, m_bitlen - 32);
+	b0 = br_i32_word(m, m_bitlen - 32);
+
+	/*
+	 * We estimate a divisor q. If the quotient returned by br_div()
+	 * is g:
+	 * -- If a0 == b0 then g == 0; we want q = 0xFFFFFFFF.
+	 * -- Otherwise:
+	 *    -- if g == 0 then we set q = 0;
+	 *    -- otherwise, we set q = g - 1.
+	 * The properties described above then ensure that the true
+	 * quotient is q-1, q or q+1.
+	 */
+	g = br_div(a0, a1, b0);
+	q = MUX(EQ(a0, b0), 0xFFFFFFFF, MUX(EQ(g, 0), 0, g - 1));
+
+	/*
+	 * We subtract q*m from x (with the extra high word of value 'hi').
+	 * Since q may be off by 1 (in either direction), we may have to
+	 * add or subtract m afterwards.
+	 *
+	 * The 'tb' flag will be true (1) at the end of the loop if the
+	 * result is greater than or equal to the modulus (not counting
+	 * 'hi' or the carry).
+	 */
+	cc = 0;
+	tb = 1;
+	for (u = 1; u <= mlen; u ++) {
+		uint32_t mw, zw, xw, nxw;
+		uint64_t zl;
+
+		mw = m[u];
+		zl = MUL(mw, q) + cc;
+		cc = (uint32_t)(zl >> 32);
+		zw = (uint32_t)zl;
+		xw = x[u];
+		nxw = xw - zw;
+		cc += (uint64_t)GT(nxw, xw);
+		x[u] = nxw;
+		tb = MUX(EQ(nxw, mw), tb, GT(nxw, mw));
+	}
+
+	/*
+	 * If we underestimated q, then either cc < hi (one extra bit
+	 * beyond the top array word), or cc == hi and tb is true (no
+	 * extra bit, but the result is not lower than the modulus). In
+	 * these cases we must subtract m once.
+	 *
+	 * Otherwise, we may have overestimated, which will show as
+	 * cc > hi (thus a negative result). Correction is adding m once.
+	 */
+	chf = (uint32_t)(cc >> 32);
+	clow = (uint32_t)cc;
+	over = chf | GT(clow, hi);
+	under = ~over & (tb | (~chf & LT(clow, hi)));
+	br_i32_add(x, m, over);
+	br_i32_sub(x, m, under);
+}
+
+/* from BearSSL's src/int/i32_reduce.c */
+
+/*
+ * Reduce an integer (a[]) modulo another (m[]). The result is written
+ * in x[] and its announced bit length is set to be equal to that of m[].
+ *
+ * x[] MUST be distinct from a[] and m[].
+ *
+ * CT: only announced bit lengths leak, not values of x, a or m.
+ */
+static void br_i32_reduce(uint32_t *x, const uint32_t *a, const uint32_t *m)
+{
+	uint32_t m_bitlen, a_bitlen;
+	size_t mlen, alen, u;
+
+	m_bitlen = m[0];
+	mlen = (m_bitlen + 31) >> 5;
+
+	x[0] = m_bitlen;
+	if (m_bitlen == 0) {
+		return;
+	}
+
+	/*
+	 * If the source is shorter, then simply copy all words from a[]
+	 * and zero out the upper words.
+	 */
+	a_bitlen = a[0];
+	alen = (a_bitlen + 31) >> 5;
+	if (a_bitlen < m_bitlen) {
+		memcpy(x + 1, a + 1, alen * sizeof *a);
+		for (u = alen; u < mlen; u ++) {
+			x[u + 1] = 0;
+		}
+		return;
+	}
+
+	/*
+	 * The source length is at least equal to that of the modulus.
+	 * We must thus copy N-1 words, and input the remaining words
+	 * one by one.
+	 */
+	memcpy(x + 1, a + 2 + (alen - mlen), (mlen - 1) * sizeof *a);
+	x[mlen] = 0;
+	for (u = 1 + alen - mlen; u > 0; u --) {
+		br_i32_muladd_small(x, a[u], m);
+	}
+}
+
+/**
+ * rsa_free_key_prop() - Free key properties
+ * @prop:	Pointer to struct key_prop
+ *
+ * This function frees all the memories allocated by rsa_gen_key_prop().
+ */
+void rsa_free_key_prop(struct key_prop *prop)
+{
+	if (!prop)
+		return;
+
+	free((void *)prop->modulus);
+	free((void *)prop->public_exponent);
+	free((void *)prop->rr);
+
+	free(prop);
+}
+
+/**
+ * rsa_gen_key_prop() - Generate key properties of RSA public key
+ * @key:	Specifies key data in DER format
+ * @keylen:	Length of @key
+ * @prop:	Generated key property
+ *
+ * This function takes a blob of encoded RSA public key data in DER
+ * format, parse it and generate all the relevant properties
+ * in key_prop structure.
+ * Return a pointer to struct key_prop in @prop on success.
+ *
+ * Return:	0 on success, negative on error
+ */
+int rsa_gen_key_prop(const void *key, uint32_t keylen, struct key_prop **prop)
+{
+	struct rsa_key rsa_key;
+	uint32_t *n = NULL, *rr = NULL, *rrtmp = NULL;
+	const int max_rsa_size = 4096;
+	int rlen, i, ret;
+
+	*prop = calloc(sizeof(**prop), 1);
+	n = calloc(sizeof(uint32_t), 1 + (max_rsa_size >> 5));
+	rr = calloc(sizeof(uint32_t), 1 + (max_rsa_size >> 5));
+	rrtmp = calloc(sizeof(uint32_t), 1 + (max_rsa_size >> 5));
+	if (!(*prop) || !n || !rr || !rrtmp) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	ret = rsa_parse_pub_key(&rsa_key, key, keylen);
+	if (ret)
+		goto err;
+
+	/* modulus */
+	/* removing leading 0's */
+	for (i = 0; i < rsa_key.n_sz && !rsa_key.n[i]; i++)
+		;
+	(*prop)->num_bits = (rsa_key.n_sz - i) * 8;
+	(*prop)->modulus = malloc(rsa_key.n_sz - i);
+	if (!(*prop)->modulus) {
+		ret = -ENOMEM;
+		goto err;
+	}
+	memcpy((void *)(*prop)->modulus, &rsa_key.n[i], rsa_key.n_sz - i);
+
+	/* exponent */
+	(*prop)->public_exponent = calloc(1, sizeof(uint64_t));
+	if (!(*prop)->public_exponent) {
+		ret = -ENOMEM;
+		goto err;
+	}
+	memcpy((void *)(*prop)->public_exponent + sizeof(uint64_t)
+						- rsa_key.e_sz,
+	       rsa_key.e, rsa_key.e_sz);
+	(*prop)->exp_len = rsa_key.e_sz;
+
+	/* n0 inverse */
+	br_i32_decode(n, &rsa_key.n[i], rsa_key.n_sz - i);
+	(*prop)->n0inv = br_i32_ninv32(n[1]);
+
+	/* R^2 mod n; R = 2^(num_bits) */
+	rlen = (*prop)->num_bits * 2; /* #bits of R^2 = (2^num_bits)^2 */
+	rr[0] = 0;
+	*(uint8_t *)&rr[0] = (1 << (rlen % 8));
+	for (i = 1; i < (((rlen + 31) >> 5) + 1); i++)
+		rr[i] = 0;
+	br_i32_decode(rrtmp, rr, ((rlen + 7) >> 3) + 1);
+	br_i32_reduce(rr, rrtmp, n);
+
+	rlen = ((*prop)->num_bits + 7) >> 3; /* #bytes of R^2 mod n */
+	(*prop)->rr = malloc(rlen);
+	if (!(*prop)->rr) {
+		ret = -ENOMEM;
+		goto err;
+	}
+	br_i32_encode((void *)(*prop)->rr, rlen, rr);
+
+	return 0;
+
+err:
+	free(n);
+	free(rr);
+	free(rrtmp);
+	rsa_free_key_prop(*prop);
+	return ret;
+}
diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
index 326a5e4..80e8173 100644
--- a/lib/rsa/rsa-verify.c
+++ b/lib/rsa/rsa-verify.c
@@ -18,9 +18,22 @@
 #include "mkimage.h"
 #include <fdt_support.h>
 #endif
+#include <linux/kconfig.h>
 #include <u-boot/rsa-mod-exp.h>
 #include <u-boot/rsa.h>
 
+#ifndef __UBOOT__
+/*
+ * NOTE:
+ * Since host tools, like mkimage, make use of openssl library for
+ * RSA encryption, rsa_verify_with_pkey()/rsa_gen_key_prop() are
+ * of no use and should not be compiled in.
+ * So just turn off CONFIG_RSA_VERIFY_WITH_PKEY.
+ */
+
+#undef CONFIG_RSA_VERIFY_WITH_PKEY
+#endif
+
 /* Default public exponent for backward compatibility */
 #define RSA_DEFAULT_PUBEXP	65537
 
@@ -271,6 +284,7 @@
 }
 #endif
 
+#if CONFIG_IS_ENABLED(FIT_SIGNATURE) || IS_ENABLED(CONFIG_RSA_VERIFY_WITH_PKEY)
 /**
  * rsa_verify_key() - Verify a signature against some data using RSA Key
  *
@@ -342,7 +356,52 @@
 
 	return 0;
 }
+#endif
 
+#ifdef CONFIG_RSA_VERIFY_WITH_PKEY
+/**
+ * rsa_verify_with_pkey() - Verify a signature against some data using
+ * only modulus and exponent as RSA key properties.
+ * @info:	Specifies key information
+ * @hash:	Pointer to the expected hash
+ * @sig:	Signature
+ * @sig_len:	Number of bytes in signature
+ *
+ * Parse a RSA public key blob in DER format pointed to in @info and fill
+ * a key_prop structure with properties of the key. Then verify a RSA PKCS1.5
+ * signature against an expected hash using the calculated properties.
+ *
+ * Return	0 if verified, -ve on error
+ */
+static int rsa_verify_with_pkey(struct image_sign_info *info,
+				const void *hash, uint8_t *sig, uint sig_len)
+{
+	struct key_prop *prop;
+	int ret;
+
+	/* Public key is self-described to fill key_prop */
+	ret = rsa_gen_key_prop(info->key, info->keylen, &prop);
+	if (ret) {
+		debug("Generating necessary parameter for decoding failed\n");
+		return ret;
+	}
+
+	ret = rsa_verify_key(info, prop, sig, sig_len, hash,
+			     info->crypto->key_len);
+
+	rsa_free_key_prop(prop);
+
+	return ret;
+}
+#else
+static int rsa_verify_with_pkey(struct image_sign_info *info,
+				const void *hash, uint8_t *sig, uint sig_len)
+{
+	return -EACCES;
+}
+#endif
+
+#if CONFIG_IS_ENABLED(FIT_SIGNATURE)
 /**
  * rsa_verify_with_keynode() - Verify a signature against some data using
  * information in node with prperties of RSA Key like modulus, exponent etc.
@@ -396,18 +455,22 @@
 
 	return ret;
 }
+#else
+static int rsa_verify_with_keynode(struct image_sign_info *info,
+				   const void *hash, uint8_t *sig,
+				   uint sig_len, int node)
+{
+	return -EACCES;
+}
+#endif
 
 int rsa_verify(struct image_sign_info *info,
 	       const struct image_region region[], int region_count,
 	       uint8_t *sig, uint sig_len)
 {
-	const void *blob = info->fdt_blob;
 	/* Reserve memory for maximum checksum-length */
 	uint8_t hash[info->crypto->key_len];
-	int ndepth, noffset;
-	int sig_node, node;
-	char name[100];
-	int ret;
+	int ret = -EACCES;
 
 	/*
 	 * Verify that the checksum-length does not exceed the
@@ -420,12 +483,6 @@
 		return -EINVAL;
 	}
 
-	sig_node = fdt_subnode_offset(blob, 0, FIT_SIG_NODENAME);
-	if (sig_node < 0) {
-		debug("%s: No signature node found\n", __func__);
-		return -ENOENT;
-	}
-
 	/* Calculate checksum with checksum-algorithm */
 	ret = info->checksum->calculate(info->checksum->name,
 					region, region_count, hash);
@@ -434,29 +491,51 @@
 		return -EINVAL;
 	}
 
-	/* See if we must use a particular key */
-	if (info->required_keynode != -1) {
-		ret = rsa_verify_with_keynode(info, hash, sig, sig_len,
-			info->required_keynode);
+	if (IS_ENABLED(CONFIG_RSA_VERIFY_WITH_PKEY) && !info->fdt_blob) {
+		/* don't rely on fdt properties */
+		ret = rsa_verify_with_pkey(info, hash, sig, sig_len);
+
 		return ret;
 	}
 
-	/* Look for a key that matches our hint */
-	snprintf(name, sizeof(name), "key-%s", info->keyname);
-	node = fdt_subnode_offset(blob, sig_node, name);
-	ret = rsa_verify_with_keynode(info, hash, sig, sig_len, node);
-	if (!ret)
-		return ret;
+	if (CONFIG_IS_ENABLED(FIT_SIGNATURE)) {
+		const void *blob = info->fdt_blob;
+		int ndepth, noffset;
+		int sig_node, node;
+		char name[100];
 
-	/* No luck, so try each of the keys in turn */
-	for (ndepth = 0, noffset = fdt_next_node(info->fit, sig_node, &ndepth);
-			(noffset >= 0) && (ndepth > 0);
-			noffset = fdt_next_node(info->fit, noffset, &ndepth)) {
-		if (ndepth == 1 && noffset != node) {
+		sig_node = fdt_subnode_offset(blob, 0, FIT_SIG_NODENAME);
+		if (sig_node < 0) {
+			debug("%s: No signature node found\n", __func__);
+			return -ENOENT;
+		}
+
+		/* See if we must use a particular key */
+		if (info->required_keynode != -1) {
 			ret = rsa_verify_with_keynode(info, hash, sig, sig_len,
-						      noffset);
-			if (!ret)
-				break;
+						      info->required_keynode);
+			return ret;
+		}
+
+		/* Look for a key that matches our hint */
+		snprintf(name, sizeof(name), "key-%s", info->keyname);
+		node = fdt_subnode_offset(blob, sig_node, name);
+		ret = rsa_verify_with_keynode(info, hash, sig, sig_len, node);
+		if (!ret)
+			return ret;
+
+		/* No luck, so try each of the keys in turn */
+		for (ndepth = 0, noffset = fdt_next_node(info->fit, sig_node,
+							 &ndepth);
+		     (noffset >= 0) && (ndepth > 0);
+		     noffset = fdt_next_node(info->fit, noffset, &ndepth)) {
+			if (ndepth == 1 && noffset != node) {
+				ret = rsa_verify_with_keynode(info, hash,
+							      sig, sig_len,
+							      noffset);
+				if (!ret)
+					break;
+			}
 		}
 	}
 
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index b8969e2..c7ad187 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -54,7 +54,6 @@
 #   to specify a valid file as first prerequisite (often the kbuild file)
 define filechk
 	$(Q)set -e;				\
-	$(kecho) '  CHK     $@';		\
 	mkdir -p $(dir $@);			\
 	$(filechk_$(1)) < $< > $@.tmp;		\
 	if [ -r $@ ] && cmp -s $@ $@.tmp; then	\
@@ -121,11 +120,6 @@
 cc-option-yn = $(call try-run,\
 	$(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n)
 
-# cc-option-align
-# Prefix align with either -falign or -malign
-cc-option-align = $(subst -functions=0,,\
-	$(call cc-option,-falign-functions=0,-malign-functions=0))
-
 # cc-disable-warning
 # Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable)
 cc-disable-warning = $(call try-run,\
@@ -148,7 +142,6 @@
 
 # added for U-Boot
 binutils-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/binutils-version.sh $(AS))
-dtc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/dtc-version.sh $(DTC))
 
 # cc-ldoption
 # Usage: ldflags += $(call cc-ldoption, -Wl$(comma)--hash-style=both)
@@ -208,7 +201,7 @@
 # Prefix -I with $(srctree) if it is not an absolute path.
 # skip if -I has no parameter
 addtree = $(if $(patsubst -I%,%,$(1)), \
-$(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1))
+$(if $(filter-out -I/% -I./% -I../%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1)),$(1)),$(1))
 
 # Find all -I options and call addtree
 flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o)))
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 26eb701..f8362fb 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -181,7 +181,6 @@
 cmd_gensymtypes =                                                           \
     $(CPP) -D__GENKSYMS__ $(c_flags) $< |                                   \
     $(GENKSYMS) $(if $(1), -T $(2))                                         \
-     $(patsubst y,-s _,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX))             \
      $(if $(KBUILD_PRESERVE),-p)                                            \
      -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
 
@@ -231,6 +230,11 @@
 endif
 
 ifdef CONFIG_FTRACE_MCOUNT_RECORD
+# gcc 5 supports generating the mcount tables directly
+ifneq ($(call cc-option,-mrecord-mcount,y),y)
+KBUILD_CFLAGS += -mrecord-mcount
+else
+# else do it all manually
 ifdef BUILD_C_RECORDMCOUNT
 ifeq ("$(origin RECORDMCOUNT_WARN)", "command line")
   RECORDMCOUNT_FLAGS = -w
@@ -259,6 +263,7 @@
 	     "$(CC_FLAGS_FTRACE)" ]; then			\
 		$(sub_cmd_record_mcount)			\
 	fi;
+endif # -record-mcount
 endif
 
 define rule_cc_o_c
@@ -450,7 +455,4 @@
   include $(cmd_files)
 endif
 
-# Declare the contents of the .PHONY variable as phony.  We keep that
-# information in a variable se we can use it in if_changed and friends.
-
 .PHONY: $(PHONY)
diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean
index 4cc468d..8fe9e05 100644
--- a/scripts/Makefile.clean
+++ b/scripts/Makefile.clean
@@ -91,7 +91,4 @@
 $(subdir-ymn):
 	$(Q)$(MAKE) $(clean)=$@
 
-# Declare the contents of the .PHONY variable as phony.  We keep that
-# information in a variable se we can use it in if_changed and friends.
-
 .PHONY: $(PHONY)
diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
index 1105c76..80231fb 100644
--- a/scripts/Makefile.extrawarn
+++ b/scripts/Makefile.extrawarn
@@ -56,25 +56,4 @@
 
 KBUILD_CFLAGS += $(warning)
 
-dtc-warning-2 += -Wnode_name_chars_strict
-dtc-warning-2 += -Wproperty_name_chars_strict
-
-dtc-warning := $(dtc-warning-$(findstring 1, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)))
-dtc-warning += $(dtc-warning-$(findstring 2, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)))
-dtc-warning += $(dtc-warning-$(findstring 3, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)))
-
-DTC_FLAGS += $(dtc-warning)
-
-else
-
-# Disable noisy checks by default
-DTC_FLAGS += -Wno-unit_address_vs_reg
-DTC_FLAGS += -Wno-simple_bus_reg
-DTC_FLAGS += -Wno-unit_address_format
-DTC_FLAGS += -Wno-pci_bridge
-DTC_FLAGS += -Wno-pci_device_bus_num
-DTC_FLAGS += -Wno-pci_device_reg
-DTC_FLAGS += -Wno-avoid_unnecessary_addr_size
-DTC_FLAGS += -Wno-alias_paths
-
 endif
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 30f392f..8c77eaa 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -144,9 +144,10 @@
 # $(call addtree,-I$(obj)) locates .h files in srctree, from generated .c files
 #   and locates generated .h files
 # FIXME: Replace both with specific CFLAGS* statements in the makefiles
-__c_flags	= $(call addtree,-I$(obj)) $(call flags,_c_flags)
-__a_flags	=                          $(call flags,_a_flags)
-__cpp_flags     =                          $(call flags,_cpp_flags)
+__c_flags	= $(if $(obj),$(call addtree,-I$(src)) -I$(obj)) \
+		  $(call flags,_c_flags)
+__a_flags	= $(call flags,_a_flags)
+__cpp_flags     = $(call flags,_cpp_flags)
 endif
 
 # Modified for U-Boot: LINUXINCLUDE -> UBOOTINCLUDE
@@ -274,6 +275,30 @@
 # DTC
 # ---------------------------------------------------------------------------
 
+# Disable noisy checks by default
+ifeq ($(findstring 1,$(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),)
+DTC_FLAGS += -Wno-unit_address_vs_reg \
+	-Wno-unit_address_format \
+	-Wno-avoid_unnecessary_addr_size \
+	-Wno-alias_paths \
+	-Wno-graph_child_address \
+	-Wno-graph_port \
+	-Wno-unique_unit_address \
+	-Wno-simple_bus_reg \
+	-Wno-pci_device_reg
+
+# U-Boot specific disables
+DTC_FLAGS += -Wno-pci_bridge \
+        -Wno-pci_device_bus_num
+endif
+
+ifneq ($(findstring 2,$(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),)
+DTC_FLAGS += -Wnode_name_chars_strict \
+	-Wproperty_name_chars_strict
+endif
+
+DTC_FLAGS += $(DTC_FLAGS_$(basetarget))
+
 # Generate an assembly file to wrap the output of the device tree compiler
 quiet_cmd_dt_S_dtb= DTB     $@
 # Modified for U-Boot
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
index da7fb2c..c9277d7 100644
--- a/scripts/basic/fixdep.c
+++ b/scripts/basic/fixdep.c
@@ -25,7 +25,7 @@
  *
  * So we play the same trick that "mkdep" played before. We replace
  * the dependency on autoconf.h by a dependency on every config
- * option which is mentioned in any of the listed prequisites.
+ * option which is mentioned in any of the listed prerequisites.
  *
  * kconfig populates a tree in include/config/ with an empty file
  * for each config symbol and when the configuration is updated
@@ -34,7 +34,7 @@
  * the config symbols are rebuilt.
  *
  * So if the user changes his CONFIG_HIS_DRIVER option, only the objects
- * which depend on "include/linux/config/his/driver.h" will be rebuilt,
+ * which depend on "include/config/his/driver.h" will be rebuilt,
  * so most likely only his driver ;-)
  *
  * The idea above dates, by the way, back to Michael E Chastain, AFAIK.
@@ -75,15 +75,14 @@
  * and then basically copies the .<target>.d file to stdout, in the
  * process filtering out the dependency on autoconf.h and adding
  * dependencies on include/config/my/option.h for every
- * CONFIG_MY_OPTION encountered in any of the prequisites.
+ * CONFIG_MY_OPTION encountered in any of the prerequisites.
  *
  * It will also filter out all the dependencies on *.ver. We need
  * to make sure that the generated version checksum are globally up
  * to date before even starting the recursive build, so it's too late
  * at this point anyway.
  *
- * The algorithm to grep for "CONFIG_..." is bit unusual, but should
- * be fast ;-) We don't even try to really parse the header files, but
+ * We don't even try to really parse the header files, but
  * merely grep, i.e. if CONFIG_FOO is mentioned in a comment, it will
  * be picked up as well. It's not a problem with respect to
  * correctness, since that can only give too many dependencies, thus
@@ -94,49 +93,59 @@
  * (Note: it'd be easy to port over the complete mkdep state machine,
  *  but I don't think the added complexity is worth it)
  */
-/*
- * Note 2: if somebody writes HELLO_CONFIG_BOOM in a file, it will depend onto
- * CONFIG_BOOM. This could seem a bug (not too hard to fix), but please do not
- * fix it! Some UserModeLinux files (look at arch/um/) call CONFIG_BOOM as
- * UML_CONFIG_BOOM, to avoid conflicts with /usr/include/linux/autoconf.h,
- * through arch/um/include/uml-config.h; this fixdep "bug" makes sure that
- * those files will have correct dependencies.
- */
 
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/mman.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
-#include <limits.h>
 #include <ctype.h>
-#include <arpa/inet.h>
 
-#define INT_CONF ntohl(0x434f4e46)
-#define INT_ONFI ntohl(0x4f4e4649)
-#define INT_NFIG ntohl(0x4e464947)
-#define INT_FIG_ ntohl(0x4649475f)
-
-char *target;
-char *depfile;
-char *cmdline;
 int is_spl_build = 0; /* hack for U-Boot */
 
 static void usage(void)
 {
-	fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n");
+	fprintf(stderr, "Usage: fixdep [-e] <depfile> <target> <cmdline>\n");
+	fprintf(stderr, " -e  insert extra dependencies given on stdin\n");
 	exit(1);
 }
 
 /*
- * Print out the commandline prefixed with cmd_<target filename> :=
+ * Print out a dependency path from a symbol name
  */
-static void print_cmdline(void)
+static void print_dep(const char *m, int slen, const char *dir)
 {
-	printf("cmd_%s := %s\n\n", target, cmdline);
+	int c, prev_c = '/', i;
+
+	printf("    $(wildcard %s/", dir);
+	for (i = 0; i < slen; i++) {
+		c = m[i];
+		if (c == '_')
+			c = '/';
+		else
+			c = tolower(c);
+		if (c != '/' || prev_c != '/')
+			putchar(c);
+		prev_c = c;
+	}
+	printf(".h) \\\n");
+}
+
+static void do_extra_deps(void)
+{
+	char buf[80];
+
+	while (fgets(buf, sizeof(buf), stdin)) {
+		int len = strlen(buf);
+
+		if (len < 2 || buf[len - 1] != '\n') {
+			fprintf(stderr, "fixdep: bad data on stdin\n");
+			exit(1);
+		}
+		print_dep(buf, len - 1, "include/ksym");
+	}
 }
 
 struct item {
@@ -198,57 +207,44 @@
 static void use_config(const char *m, int slen)
 {
 	unsigned int hash = strhash(m, slen);
-	int c, i;
 
 	if (is_defined_config(m, slen, hash))
 	    return;
 
 	define_config(m, slen, hash);
-
-	printf("    $(wildcard include/config/");
-	for (i = 0; i < slen; i++) {
-		c = m[i];
-		if (c == '_')
-			c = '/';
-		else
-			c = tolower(c);
-		putchar(c);
-	}
-	printf(".h) \\\n");
+	print_dep(m, slen, "include/config");
 }
 
-static void parse_config_file(const char *map, size_t len)
+/* test if s ends in sub */
+static int str_ends_with(const char *s, int slen, const char *sub)
 {
-	const int *end = (const int *) (map + len);
-	/* start at +1, so that p can never be < map */
-	const int *m   = (const int *) map + 1;
-	const char *p, *q;
+	int sublen = strlen(sub);
+
+	if (sublen > slen)
+		return 0;
+
+	return !memcmp(s + slen - sublen, sub, sublen);
+}
+
+static void parse_config_file(const char *p)
+{
+	const char *q, *r;
+	const char *start = p;
 	char tmp_buf[256] = "SPL_"; /* hack for U-Boot */
 
-	for (; m < end; m++) {
-		if (*m == INT_CONF) { p = (char *) m  ; goto conf; }
-		if (*m == INT_ONFI) { p = (char *) m-1; goto conf; }
-		if (*m == INT_NFIG) { p = (char *) m-2; goto conf; }
-		if (*m == INT_FIG_) { p = (char *) m-3; goto conf; }
-		continue;
-	conf:
-		if (p > map + len - 7)
+	while ((p = strstr(p, "CONFIG_"))) {
+		if (p > start && (isalnum(p[-1]) || p[-1] == '_')) {
+			p += 7;
 			continue;
-		if (memcmp(p, "CONFIG_", 7))
-			continue;
-		p += 7;
-		for (q = p; q < map + len; q++) {
-			if (!(isalnum(*q) || *q == '_'))
-				goto found;
 		}
-		continue;
-
-	found:
-		if (!memcmp(q - 7, "_MODULE", 7))
-			q -= 7;
-		if (q - p < 0)
-			continue;
-
+		p += 7;
+		q = p;
+		while (*q && (isalnum(*q) || *q == '_'))
+			q++;
+		if (str_ends_with(p, q - p, "_MODULE"))
+			r = q - 7;
+		else
+			r = q;
 		/*
 		 * U-Boot also handles
 		 *   CONFIG_IS_ENABLED(...)
@@ -261,69 +257,61 @@
 		    (q - p == 9 && !memcmp(p, "IS_MODULE(", 10)) ||
 		    (q - p == 3 && !memcmp(p, "VAL(", 4))) {
 			p = q + 1;
-			for (q = p; q < map + len; q++)
-				if (*q == ')')
-					goto found2;
-			continue;
-
-		found2:
-			if (is_spl_build) {
-				memcpy(tmp_buf + 4, p, q - p);
-				q = tmp_buf + 4 + (q - p);
+			while (isalnum(*q) || *q == '_')
+				q++;
+			r = q;
+			if (r > p && is_spl_build) {
+				memcpy(tmp_buf + 4, p, r - p);
+				r = tmp_buf + 4 + (r - p);
 				p = tmp_buf;
 			}
 		}
 		/* end U-Boot hack */
 
-		use_config(p, q - p);
+		if (r > p)
+			use_config(p, r - p);
+		p = q;
 	}
 }
 
-/* test is s ends in sub */
-static int strrcmp(char *s, char *sub)
-{
-	int slen = strlen(s);
-	int sublen = strlen(sub);
-
-	if (sublen > slen)
-		return 1;
-
-	return memcmp(s + slen - sublen, sub, sublen);
-}
-
-static void do_config_file(const char *filename)
+static void *read_file(const char *filename)
 {
 	struct stat st;
 	int fd;
-	void *map;
+	char *buf;
 
 	fd = open(filename, O_RDONLY);
 	if (fd < 0) {
-		fprintf(stderr, "fixdep: error opening config file: ");
+		fprintf(stderr, "fixdep: error opening file: ");
 		perror(filename);
 		exit(2);
 	}
 	if (fstat(fd, &st) < 0) {
-		fprintf(stderr, "fixdep: error fstat'ing config file: ");
+		fprintf(stderr, "fixdep: error fstat'ing file: ");
 		perror(filename);
 		exit(2);
 	}
-	if (st.st_size == 0) {
-		close(fd);
-		return;
+	buf = malloc(st.st_size + 1);
+	if (!buf) {
+		perror("fixdep: malloc");
+		exit(2);
 	}
-	map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
-	if ((long) map == -1) {
-		perror("fixdep: mmap");
-		close(fd);
-		return;
+	if (read(fd, buf, st.st_size) != st.st_size) {
+		perror("fixdep: read");
+		exit(2);
 	}
-
-	parse_config_file(map, st.st_size);
-
-	munmap(map, st.st_size);
-
+	buf[st.st_size] = '\0';
 	close(fd);
+
+	return buf;
+}
+
+/* Ignore certain dependencies */
+static int is_ignored_file(const char *s, int len)
+{
+	return str_ends_with(s, len, "include/generated/autoconf.h") ||
+	       str_ends_with(s, len, "include/generated/autoksyms.h") ||
+	       str_ends_with(s, len, ".ver");
 }
 
 /*
@@ -331,70 +319,70 @@
  * assignments are parsed not only by make, but also by the rather simple
  * parser in scripts/mod/sumversion.c.
  */
-static void parse_dep_file(void *map, size_t len)
+static void parse_dep_file(char *m, const char *target, int insert_extra_deps)
 {
-	char *m = map;
-	char *end = m + len;
 	char *p;
-	char s[PATH_MAX];
-	int is_target;
+	int is_last, is_target;
 	int saw_any_target = 0;
 	int is_first_dep = 0;
+	void *buf;
 
-	while (m < end) {
+	while (1) {
 		/* Skip any "white space" */
-		while (m < end && (*m == ' ' || *m == '\\' || *m == '\n'))
+		while (*m == ' ' || *m == '\\' || *m == '\n')
 			m++;
+
+		if (!*m)
+			break;
+
 		/* Find next "white space" */
 		p = m;
-		while (p < end && *p != ' ' && *p != '\\' && *p != '\n')
+		while (*p && *p != ' ' && *p != '\\' && *p != '\n')
 			p++;
+		is_last = (*p == '\0');
 		/* Is the token we found a target name? */
 		is_target = (*(p-1) == ':');
 		/* Don't write any target names into the dependency file */
 		if (is_target) {
 			/* The /next/ file is the first dependency */
 			is_first_dep = 1;
-		} else {
-			/* Save this token/filename */
-			memcpy(s, m, p-m);
-			s[p - m] = 0;
+		} else if (!is_ignored_file(m, p - m)) {
+			*p = '\0';
 
-			/* Ignore certain dependencies */
-			if (strrcmp(s, "include/generated/autoconf.h") &&
-			    strrcmp(s, "arch/um/include/uml-config.h") &&
-			    strrcmp(s, "include/linux/kconfig.h") &&
-			    strrcmp(s, ".ver")) {
+			/*
+			 * Do not list the source file as dependency, so that
+			 * kbuild is not confused if a .c file is rewritten
+			 * into .S or vice versa. Storing it in source_* is
+			 * needed for modpost to compute srcversions.
+			 */
+			if (is_first_dep) {
 				/*
-				 * Do not list the source file as dependency,
-				 * so that kbuild is not confused if a .c file
-				 * is rewritten into .S or vice versa. Storing
-				 * it in source_* is needed for modpost to
-				 * compute srcversions.
+				 * If processing the concatenation of multiple
+				 * dependency files, only process the first
+				 * target name, which will be the original
+				 * source name, and ignore any other target
+				 * names, which will be intermediate temporary
+				 * files.
 				 */
-				if (is_first_dep) {
-					/*
-					 * If processing the concatenation of
-					 * multiple dependency files, only
-					 * process the first target name, which
-					 * will be the original source name,
-					 * and ignore any other target names,
-					 * which will be intermediate temporary
-					 * files.
-					 */
-					if (!saw_any_target) {
-						saw_any_target = 1;
-						printf("source_%s := %s\n\n",
-							target, s);
-						printf("deps_%s := \\\n",
-							target);
-					}
-					is_first_dep = 0;
-				} else
-					printf("  %s \\\n", s);
-				do_config_file(s);
+				if (!saw_any_target) {
+					saw_any_target = 1;
+					printf("source_%s := %s\n\n",
+					       target, m);
+					printf("deps_%s := \\\n", target);
+				}
+				is_first_dep = 0;
+			} else {
+				printf("  %s \\\n", m);
 			}
+
+			buf = read_file(m);
+			parse_config_file(buf);
+			free(buf);
 		}
+
+		if (is_last)
+			break;
+
 		/*
 		 * Start searching for next token immediately after the first
 		 * "whitespace" character that follows this token.
@@ -407,63 +395,23 @@
 		exit(1);
 	}
 
+	if (insert_extra_deps)
+		do_extra_deps();
+
 	printf("\n%s: $(deps_%s)\n\n", target, target);
 	printf("$(deps_%s):\n", target);
 }
 
-static void print_deps(void)
-{
-	struct stat st;
-	int fd;
-	void *map;
-
-	fd = open(depfile, O_RDONLY);
-	if (fd < 0) {
-		fprintf(stderr, "fixdep: error opening depfile: ");
-		perror(depfile);
-		exit(2);
-	}
-	if (fstat(fd, &st) < 0) {
-		fprintf(stderr, "fixdep: error fstat'ing depfile: ");
-		perror(depfile);
-		exit(2);
-	}
-	if (st.st_size == 0) {
-		fprintf(stderr,"fixdep: %s is empty\n",depfile);
-		close(fd);
-		return;
-	}
-	map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
-	if ((long) map == -1) {
-		perror("fixdep: mmap");
-		close(fd);
-		return;
-	}
-
-	parse_dep_file(map, st.st_size);
-
-	munmap(map, st.st_size);
-
-	close(fd);
-}
-
-static void traps(void)
-{
-	static char test[] __attribute__((aligned(sizeof(int)))) = "CONF";
-	int *p = (int *)test;
-
-	if (*p != INT_CONF) {
-		fprintf(stderr, "fixdep: sizeof(int) != 4 or wrong endianness? %#x\n",
-			*p);
-		exit(2);
-	}
-}
-
 int main(int argc, char *argv[])
 {
-	traps();
+	const char *depfile, *target, *cmdline;
+	int insert_extra_deps = 0;
+	void *buf;
 
-	if (argc != 4)
+	if (argc == 5 && !strcmp(argv[1], "-e")) {
+		insert_extra_deps = 1;
+		argv++;
+	} else if (argc != 4)
 		usage();
 
 	depfile = argv[1];
@@ -474,8 +422,11 @@
 	if (!strncmp(target, "spl/", 4) || !strncmp(target, "tpl/", 4))
 		is_spl_build = 1;
 
-	print_cmdline();
-	print_deps();
+	printf("cmd_%s := %s\n\n", target, cmdline);
+
+	buf = read_file(depfile);
+	parse_dep_file(buf, target, insert_extra_deps);
+	free(buf);
 
 	return 0;
 }
diff --git a/scripts/dtc-version.sh b/scripts/dtc-version.sh
deleted file mode 100755
index 0744c39..0000000
--- a/scripts/dtc-version.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/sh
-#
-# dtc-version dtc-command
-#
-# Prints the dtc version of `dtc-command' in a canonical 6-digit form
-# such as `010404'  for dtc 1.4.4
-#
-
-dtc="$*"
-
-if [ ${#dtc} -eq 0 ]; then
-	echo "Error: No dtc command specified."
-	printf "Usage:\n\t$0 <dtc-command>\n"
-	exit 1
-fi
-
-MAJOR=$($dtc -v | head -1 | awk '{print $NF}' | cut -d . -f 1)
-MINOR=$($dtc -v | head -1 | awk '{print $NF}' | cut -d . -f 2)
-PATCH=$($dtc -v | head -1 | awk '{print $NF}' | cut -d . -f 3 | cut -d - -f 1)
-
-printf "%02d%02d%02d\\n" $MAJOR $MINOR $PATCH
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
index 4087967..c35aa6f 100644
--- a/scripts/dtc/checks.c
+++ b/scripts/dtc/checks.c
@@ -255,7 +255,7 @@
 		     child2;
 		     child2 = child2->next_sibling)
 			if (streq(child->name, child2->name))
-				FAIL(c, dti, node, "Duplicate node name");
+				FAIL(c, dti, child2, "Duplicate node name");
 }
 ERROR(duplicate_node_names, check_duplicate_node_names, NULL);
 
@@ -317,6 +317,11 @@
 	const char *unitname = get_unitname(node);
 	struct property *prop = get_property(node, "reg");
 
+	if (get_subnode(node, "__overlay__")) {
+		/* HACK: Overlay fragments are a special case */
+		return;
+	}
+
 	if (!prop) {
 		prop = get_property(node, "ranges");
 		if (prop && !prop->val.len)
@@ -1030,6 +1035,36 @@
 }
 WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size);
 
+static void check_unique_unit_address(struct check *c, struct dt_info *dti,
+					      struct node *node)
+{
+	struct node *childa;
+
+	if (node->addr_cells < 0 || node->size_cells < 0)
+		return;
+
+	if (!node->children)
+		return;
+
+	for_each_child(node, childa) {
+		struct node *childb;
+		const char *addr_a = get_unitname(childa);
+
+		if (!strlen(addr_a))
+			continue;
+
+		for_each_child(node, childb) {
+			const char *addr_b = get_unitname(childb);
+			if (childa == childb)
+				break;
+
+			if (streq(addr_a, addr_b))
+				FAIL(c, dti, childb, "duplicate unit-address (also used in node %s)", childa->fullpath);
+		}
+	}
+}
+WARNING(unique_unit_address, check_unique_unit_address, NULL, &avoid_default_addr_size);
+
 static void check_obsolete_chosen_interrupt_controller(struct check *c,
 						       struct dt_info *dti,
 						       struct node *node)
@@ -1370,6 +1405,152 @@
 }
 WARNING(interrupts_property, check_interrupts_property, &phandle_references);
 
+static const struct bus_type graph_port_bus = {
+	.name = "graph-port",
+};
+
+static const struct bus_type graph_ports_bus = {
+	.name = "graph-ports",
+};
+
+static void check_graph_nodes(struct check *c, struct dt_info *dti,
+			      struct node *node)
+{
+	struct node *child;
+
+	for_each_child(node, child) {
+		if (!(strprefixeq(child->name, child->basenamelen, "endpoint") ||
+		      get_property(child, "remote-endpoint")))
+			continue;
+
+		node->bus = &graph_port_bus;
+
+		/* The parent of 'port' nodes can be either 'ports' or a device */
+		if (!node->parent->bus &&
+		    (streq(node->parent->name, "ports") || get_property(node, "reg")))
+			node->parent->bus = &graph_ports_bus;
+
+		break;
+	}
+
+}
+WARNING(graph_nodes, check_graph_nodes, NULL);
+
+static void check_graph_child_address(struct check *c, struct dt_info *dti,
+				      struct node *node)
+{
+	int cnt = 0;
+	struct node *child;
+
+	if (node->bus != &graph_ports_bus && node->bus != &graph_port_bus)
+		return;
+
+	for_each_child(node, child) {
+		struct property *prop = get_property(child, "reg");
+
+		/* No error if we have any non-zero unit address */
+		if (prop && propval_cell(prop) != 0)
+			return;
+
+		cnt++;
+	}
+
+	if (cnt == 1 && node->addr_cells != -1)
+		FAIL(c, dti, node, "graph node has single child node '%s', #address-cells/#size-cells are not necessary",
+		     node->children->name);
+}
+WARNING(graph_child_address, check_graph_child_address, NULL, &graph_nodes);
+
+static void check_graph_reg(struct check *c, struct dt_info *dti,
+			    struct node *node)
+{
+	char unit_addr[9];
+	const char *unitname = get_unitname(node);
+	struct property *prop;
+
+	prop = get_property(node, "reg");
+	if (!prop || !unitname)
+		return;
+
+	if (!(prop->val.val && prop->val.len == sizeof(cell_t))) {
+		FAIL(c, dti, node, "graph node malformed 'reg' property");
+		return;
+	}
+
+	snprintf(unit_addr, sizeof(unit_addr), "%x", propval_cell(prop));
+	if (!streq(unitname, unit_addr))
+		FAIL(c, dti, node, "graph node unit address error, expected \"%s\"",
+		     unit_addr);
+
+	if (node->parent->addr_cells != 1)
+		FAIL_PROP(c, dti, node, get_property(node, "#address-cells"),
+			  "graph node '#address-cells' is %d, must be 1",
+			  node->parent->addr_cells);
+	if (node->parent->size_cells != 0)
+		FAIL_PROP(c, dti, node, get_property(node, "#size-cells"),
+			  "graph node '#size-cells' is %d, must be 0",
+			  node->parent->size_cells);
+}
+
+static void check_graph_port(struct check *c, struct dt_info *dti,
+			     struct node *node)
+{
+	if (node->bus != &graph_port_bus)
+		return;
+
+	if (!strprefixeq(node->name, node->basenamelen, "port"))
+		FAIL(c, dti, node, "graph port node name should be 'port'");
+
+	check_graph_reg(c, dti, node);
+}
+WARNING(graph_port, check_graph_port, NULL, &graph_nodes);
+
+static struct node *get_remote_endpoint(struct check *c, struct dt_info *dti,
+					struct node *endpoint)
+{
+	int phandle;
+	struct node *node;
+	struct property *prop;
+
+	prop = get_property(endpoint, "remote-endpoint");
+	if (!prop)
+		return NULL;
+
+	phandle = propval_cell(prop);
+	/* Give up if this is an overlay with external references */
+	if (phandle == 0 || phandle == -1)
+		return NULL;
+
+	node = get_node_by_phandle(dti->dt, phandle);
+	if (!node)
+		FAIL_PROP(c, dti, endpoint, prop, "graph phandle is not valid");
+
+	return node;
+}
+
+static void check_graph_endpoint(struct check *c, struct dt_info *dti,
+				 struct node *node)
+{
+	struct node *remote_node;
+
+	if (!node->parent || node->parent->bus != &graph_port_bus)
+		return;
+
+	if (!strprefixeq(node->name, node->basenamelen, "endpoint"))
+		FAIL(c, dti, node, "graph endpont node name should be 'endpoint'");
+
+	check_graph_reg(c, dti, node);
+
+	remote_node = get_remote_endpoint(c, dti, node);
+	if (!remote_node)
+		return;
+
+	if (get_remote_endpoint(c, dti, remote_node) != node)
+		FAIL(c, dti, node, "graph connection to node '%s' is not bidirectional",
+		     remote_node->fullpath);
+}
+WARNING(graph_endpoint, check_graph_endpoint, NULL, &graph_nodes);
+
 static struct check *check_table[] = {
 	&duplicate_node_names, &duplicate_property_names,
 	&node_name_chars, &node_name_format, &property_name_chars,
@@ -1404,6 +1585,7 @@
 
 	&avoid_default_addr_size,
 	&avoid_unnecessary_addr_size,
+	&unique_unit_address,
 	&obsolete_chosen_interrupt_controller,
 	&chosen_node_is_root, &chosen_node_bootargs, &chosen_node_stdout_path,
 
@@ -1430,6 +1612,8 @@
 
 	&alias_paths,
 
+	&graph_nodes, &graph_child_address, &graph_port, &graph_endpoint,
+
 	&always_fail,
 };
 
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
index 66ff7f7..011a5b2 100644
--- a/scripts/dtc/dtc-parser.y
+++ b/scripts/dtc/dtc-parser.y
@@ -191,18 +191,18 @@
 		}
 	| devicetree DT_REF nodedef
 		{
-			struct node *target = get_node_by_ref($1, $2);
-
-			if (target) {
-				merge_nodes(target, $3);
+			/*
+			 * We rely on the rule being always:
+			 *   versioninfo plugindecl memreserves devicetree
+			 * so $-1 is what we want (plugindecl)
+			 */
+			if ($<flags>-1 & DTSF_PLUGIN) {
+				add_orphan_node($1, $3, $2);
 			} else {
-				/*
-				 * We rely on the rule being always:
-				 *   versioninfo plugindecl memreserves devicetree
-				 * so $-1 is what we want (plugindecl)
-				 */
-				if ($<flags>-1 & DTSF_PLUGIN)
-					add_orphan_node($1, $3, $2);
+				struct node *target = get_node_by_ref($1, $2);
+
+				if (target)
+					merge_nodes(target, $3);
 				else
 					ERROR(&@2, "Label or path %s not found", $2);
 			}
diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c
index 81b6c48..6e4c367 100644
--- a/scripts/dtc/livetree.c
+++ b/scripts/dtc/livetree.c
@@ -238,10 +238,16 @@
 	struct data d = empty_data;
 	char *name;
 
-	d = data_add_marker(d, REF_PHANDLE, ref);
-	d = data_append_integer(d, 0xffffffff, 32);
+	if (ref[0] == '/') {
+		d = data_append_data(d, ref, strlen(ref) + 1);
 
-	p = build_property("target", d);
+		p = build_property("target-path", d);
+	} else {
+		d = data_add_marker(d, REF_PHANDLE, ref);
+		d = data_append_integer(d, 0xffffffff, 32);
+
+		p = build_property("target", d);
+	}
 
 	xasprintf(&name, "fragment@%u",
 			next_orphan_fragment++);
diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h
index ad87849..b00f14f 100644
--- a/scripts/dtc/version_gen.h
+++ b/scripts/dtc/version_gen.h
@@ -1 +1 @@
-#define DTC_VERSION "DTC 1.4.6-gaadd0b65"
+#define DTC_VERSION "DTC 1.4.6-g84e414b0"
diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore
index 2da579e..0aabc1d 100644
--- a/scripts/kconfig/.gitignore
+++ b/scripts/kconfig/.gitignore
@@ -2,9 +2,6 @@
 # Generated files
 #
 *.moc
-gconf.glade.h
-*.pot
-*.mo
 
 #
 # configuration programs
@@ -14,4 +11,3 @@
 nconf
 qconf
 gconf
-kxgettext
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 8b7b349..30b90cf 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -3,7 +3,7 @@
 # Kernel configuration targets
 # These targets are used from top-level makefile
 
-PHONY += xconfig gconfig menuconfig config syncconfig update-po-config \
+PHONY += xconfig gconfig menuconfig config syncconfig \
 	localmodconfig localyesconfig
 
 # Added for U-Boot
@@ -61,29 +61,6 @@
 	fi
 	$(Q)rm -f .tmp.config
 
-# Create new linux.pot file
-# Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files
-update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h
-	$(Q)$(kecho) "  GEN     config.pot"
-	$(Q)xgettext --default-domain=linux                         \
-	    --add-comments --keyword=_ --keyword=N_                 \
-	    --from-code=UTF-8                                       \
-	    --files-from=$(srctree)/scripts/kconfig/POTFILES.in     \
-	    --directory=$(srctree) --directory=$(objtree)           \
-	    --output $(obj)/config.pot
-	$(Q)sed -i s/CHARSET/UTF-8/ $(obj)/config.pot
-	$(Q)(for i in `ls $(srctree)/arch/*/Kconfig      \
-	    $(srctree)/arch/*/um/Kconfig`;               \
-	    do                                           \
-		$(kecho) "  GEN     $$i";                    \
-		$(obj)/kxgettext $$i                     \
-		     >> $(obj)/config.pot;               \
-	    done )
-	$(Q)$(kecho) "  GEN     linux.pot"
-	$(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \
-	    --output $(obj)/linux.pot
-	$(Q)rm -f $(obj)/config.pot
-
 # These targets map 1:1 to the commandline options of 'conf'
 simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \
 	alldefconfig randconfig listnewconfig olddefconfig
@@ -161,8 +138,7 @@
 # Help text used by make help
 help:
 	@echo  '  config	  - Update current config utilising a line-oriented program'
-	@echo  '  nconfig         - Update current config utilising a ncurses menu based'
-	@echo  '                    program'
+	@echo  '  nconfig         - Update current config utilising a ncurses menu based program'
 	@echo  '  menuconfig	  - Update current config utilising a menu based program'
 	@echo  '  xconfig	  - Update current config utilising a Qt based front-end'
 	@echo  '  gconfig	  - Update current config utilising a GTK+ based front-end'
@@ -182,141 +158,77 @@
 #	@echo  '  kvmconfig	  - Enable additional options for kvm guest kernel support'
 #	@echo  '  xenconfig       - Enable additional options for xen dom0 and guest kernel support'
 #	@echo  '  tinyconfig	  - Configure the tiniest possible kernel'
-
-# lxdialog stuff
-check-lxdialog  := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
-
-# Use recursively expanded variables so we do not call gcc unless
-# we really need to do so. (Do not call gcc as part of make mrproper)
-HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) \
-                    -DLOCALE
+	@echo  '  testconfig	  - Run Kconfig unit tests (requires python3 and pytest)'
 
 # ===========================================================================
 # Shared Makefile for the various kconfig executables:
 # conf:	  Used for defconfig, oldconfig and related targets
-# nconf:  Used for the nconfig target.
-#         Utilizes ncurses
-# mconf:  Used for the menuconfig target
-#         Utilizes the lxdialog package
-# qconf:  Used for the xconfig target
-#         Based on Qt which needs to be installed to compile it
-# gconf:  Used for the gconfig target
-#         Based on GTK+ which needs to be installed to compile it
 # object files used by all kconfig flavours
 
-lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o
-lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o
-
 conf-objs	:= conf.o  zconf.tab.o
-mconf-objs     := mconf.o zconf.tab.o $(lxdialog)
-nconf-objs     := nconf.o zconf.tab.o nconf.gui.o
-kxgettext-objs	:= kxgettext.o zconf.tab.o
-qconf-cxxobjs	:= qconf.o
-qconf-objs	:= zconf.tab.o
-gconf-objs	:= gconf.o zconf.tab.o
 
-hostprogs-y := conf nconf mconf kxgettext qconf gconf
+hostprogs-y := conf
 
 targets		+= zconf.lex.c
-clean-files	:= qconf.moc .tmp_qtcheck .tmp_gtkcheck
-clean-files	+= gconf.glade.h
-clean-files     += config.pot linux.pot
-
-# Check that we have the required ncurses stuff installed for lxdialog (menuconfig)
-PHONY += $(obj)/dochecklxdialog
-$(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/dochecklxdialog
-$(obj)/dochecklxdialog:
-	$(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTLOADLIBES_mconf)
-
-always := dochecklxdialog
-
-# Add environment specific flags
-HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCC) $(HOSTCFLAGS))
-HOST_EXTRACXXFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCXX) $(HOSTCXXFLAGS))
 
 # generated files seem to need this to find local include files
 HOSTCFLAGS_zconf.lex.o	:= -I$(src)
 HOSTCFLAGS_zconf.tab.o	:= -I$(src)
 
-HOSTLOADLIBES_qconf	= $(KC_QT_LIBS)
-HOSTCXXFLAGS_qconf.o	= $(KC_QT_CFLAGS)
+# nconf: Used for the nconfig target based on ncurses
+hostprogs-y	+= nconf
+nconf-objs	:= nconf.o zconf.tab.o nconf.gui.o
 
-HOSTLOADLIBES_gconf	= `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0`
-HOSTCFLAGS_gconf.o	= `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \
-                          -Wno-missing-prototypes
+HOSTLOADLIBES_nconf	= $(shell . $(obj)/.nconf-cfg && echo $$libs)
+HOSTCFLAGS_nconf.o	= $(shell . $(obj)/.nconf-cfg && echo $$cflags)
+HOSTCFLAGS_nconf.gui.o	= $(shell . $(obj)/.nconf-cfg && echo $$cflags)
 
-HOSTLOADLIBES_mconf   = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
+$(obj)/nconf.o: $(obj)/.nconf-cfg
 
-HOSTLOADLIBES_nconf	= $(shell \
-				pkg-config --libs menuw panelw ncursesw 2>/dev/null \
-				|| pkg-config --libs menu panel ncurses 2>/dev/null \
-				|| echo "-lmenu -lpanel -lncurses"  )
-$(obj)/qconf.o: $(obj)/.tmp_qtcheck
+# mconf: Used for the menuconfig target based on lxdialog
+hostprogs-y	+= mconf
+lxdialog	:= checklist.o inputbox.o menubox.o textbox.o util.o yesno.o
+mconf-objs	:= mconf.o zconf.tab.o $(addprefix lxdialog/, $(lxdialog))
 
-ifeq ($(MAKECMDGOALS),xconfig)
-$(obj)/.tmp_qtcheck: $(src)/Makefile
--include $(obj)/.tmp_qtcheck
+HOSTLOADLIBES_mconf = $(shell . $(obj)/.mconf-cfg && echo $$libs)
+$(foreach f, mconf.o $(lxdialog), \
+  $(eval HOSTCFLAGS_$f = $$(shell . $(obj)/.mconf-cfg && echo $$$$cflags)))
 
-# Qt needs some extra effort...
-$(obj)/.tmp_qtcheck:
-	@set -e; $(kecho) "  CHECK   qt"; \
-	if pkg-config --exists Qt5Core; then \
-	    cflags="-std=c++11 -fPIC `pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets`"; \
-	    libs=`pkg-config --libs Qt5Core Qt5Gui Qt5Widgets`; \
-	    moc=`pkg-config --variable=host_bins Qt5Core`/moc; \
-	elif pkg-config --exists QtCore; then \
-	    cflags=`pkg-config --cflags QtCore QtGui`; \
-	    libs=`pkg-config --libs QtCore QtGui`; \
-	    moc=`pkg-config --variable=moc_location QtCore`; \
-	else \
-	    echo >&2 "*"; \
-	    echo >&2 "* Could not find Qt via pkg-config."; \
-	    echo >&2 "* Please install either Qt 4.8 or 5.x. and make sure it's in PKG_CONFIG_PATH"; \
-	    echo >&2 "*"; \
-	    exit 1; \
-	fi; \
-	echo "KC_QT_CFLAGS=$$cflags" > $@; \
-	echo "KC_QT_LIBS=$$libs" >> $@; \
-	echo "KC_QT_MOC=$$moc" >> $@
-endif
+$(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/.mconf-cfg
 
-$(obj)/gconf.o: $(obj)/.tmp_gtkcheck
+# qconf: Used for the xconfig target based on Qt
+hostprogs-y	+= qconf
+qconf-cxxobjs	:= qconf.o
+qconf-objs	:= zconf.tab.o
 
-ifeq ($(MAKECMDGOALS),gconfig)
--include $(obj)/.tmp_gtkcheck
+HOSTLOADLIBES_qconf	= $(shell . $(obj)/.qconf-cfg && echo $$libs)
+HOSTCXXFLAGS_qconf.o	= $(shell . $(obj)/.qconf-cfg && echo $$cflags)
 
-# GTK+ needs some extra effort, too...
-$(obj)/.tmp_gtkcheck:
-	@if `pkg-config --exists gtk+-2.0 gmodule-2.0 libglade-2.0`; then		\
-		if `pkg-config --atleast-version=2.0.0 gtk+-2.0`; then			\
-			touch $@;								\
-		else									\
-			echo >&2 "*"; 							\
-			echo >&2 "* GTK+ is present but version >= 2.0.0 is required.";	\
-			echo >&2 "*";							\
-			false;								\
-		fi									\
-	else										\
-		echo >&2 "*"; 								\
-		echo >&2 "* Unable to find the GTK+ installation. Please make sure that"; 	\
-		echo >&2 "* the GTK+ 2.0 development package is correctly installed..."; 	\
-		echo >&2 "* You need gtk+-2.0, glib-2.0 and libglade-2.0."; 		\
-		echo >&2 "*"; 								\
-		false;									\
-	fi
-endif
+$(obj)/qconf.o: $(obj)/.qconf-cfg $(obj)/qconf.moc
+
+quiet_cmd_moc = MOC     $@
+      cmd_moc = $(shell . $(obj)/.qconf-cfg && echo $$moc) -i $< -o $@
+
+$(obj)/%.moc: $(src)/%.h $(obj)/.qconf-cfg
+	$(call cmd,moc)
+
+# gconf: Used for the gconfig target based on GTK+
+hostprogs-y	+= gconf
+gconf-objs	:= gconf.o zconf.tab.o
+
+HOSTLOADLIBES_gconf = $(shell . $(obj)/.gconf-cfg && echo $$libs)
+HOSTCFLAGS_gconf.o  = $(shell . $(obj)/.gconf-cfg && echo $$cflags)
+
+$(obj)/gconf.o: $(obj)/.gconf-cfg
 
 $(obj)/zconf.tab.o: $(obj)/zconf.lex.c
 
-$(obj)/qconf.o: $(obj)/qconf.moc
+# check if necessary packages are available, and configure build flags
+define filechk_conf_cfg
+	$(CONFIG_SHELL) $<
+endef
 
-quiet_cmd_moc = MOC     $@
-      cmd_moc = $(KC_QT_MOC) -i $< -o $@
+$(obj)/.%conf-cfg: $(src)/%conf-cfg.sh FORCE
+	$(call filechk,conf_cfg)
 
-$(obj)/%.moc: $(src)/%.h $(obj)/.tmp_qtcheck
-	$(call cmd,moc)
-
-# Extract gconf menu items for i18n support
-$(obj)/gconf.glade.h: $(obj)/gconf.glade
-	$(Q)intltool-extract --type=gettext/glade --srcdir=$(srctree) \
-	$(obj)/gconf.glade
+clean-files += .*conf-cfg
diff --git a/scripts/kconfig/POTFILES.in b/scripts/kconfig/POTFILES.in
deleted file mode 100644
index 9674573..0000000
--- a/scripts/kconfig/POTFILES.in
+++ /dev/null
@@ -1,12 +0,0 @@
-scripts/kconfig/lxdialog/checklist.c
-scripts/kconfig/lxdialog/inputbox.c
-scripts/kconfig/lxdialog/menubox.c
-scripts/kconfig/lxdialog/textbox.c
-scripts/kconfig/lxdialog/util.c
-scripts/kconfig/lxdialog/yesno.c
-scripts/kconfig/mconf.c
-scripts/kconfig/conf.c
-scripts/kconfig/confdata.c
-scripts/kconfig/gconf.c
-scripts/kconfig/gconf.glade.h
-scripts/kconfig/qconf.cc
diff --git a/scripts/kconfig/check.sh b/scripts/kconfig/check.sh
deleted file mode 100755
index 97f0fee..0000000
--- a/scripts/kconfig/check.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-# Needed for systems without gettext
-$* -x c -o /dev/null - > /dev/null 2>&1 << EOF
-#include <libintl.h>
-int main()
-{
-	gettext("");
-	return 0;
-}
-EOF
-if [ ! "$?" -eq "0"  ]; then
-	echo -DKBUILD_NO_NLS;
-fi
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 283eeed..671ff53 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -3,7 +3,6 @@
  * Released under the terms of the GNU GPL v2.0.
  */
 
-#include <locale.h>
 #include <ctype.h>
 #include <limits.h>
 #include <stdio.h>
@@ -86,7 +85,7 @@
 	enum symbol_type type = sym_get_type(sym);
 
 	if (!sym_has_value(sym))
-		printf(_("(NEW) "));
+		printf("(NEW) ");
 
 	line[0] = '\n';
 	line[1] = 0;
@@ -133,7 +132,7 @@
 	const char *def;
 
 	while (1) {
-		printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
+		printf("%*s%s ", indent - 1, "", menu->prompt->text);
 		printf("(%s) ", sym->name);
 		def = sym_get_string_value(sym);
 		if (sym_get_string_value(sym))
@@ -166,7 +165,7 @@
 	tristate oldval, newval;
 
 	while (1) {
-		printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
+		printf("%*s%s ", indent - 1, "", menu->prompt->text);
 		if (sym->name)
 			printf("(%s) ", sym->name);
 		putchar('[');
@@ -251,7 +250,7 @@
 		case no:
 			return 1;
 		case mod:
-			printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
+			printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
 			return 0;
 		case yes:
 			break;
@@ -261,7 +260,7 @@
 	while (1) {
 		int cnt, def;
 
-		printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
+		printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
 		def_sym = sym_get_choice_value(sym);
 		cnt = def = 0;
 		line[0] = 0;
@@ -269,7 +268,7 @@
 			if (!menu_is_visible(child))
 				continue;
 			if (!child->sym) {
-				printf("%*c %s\n", indent, '*', _(menu_get_prompt(child)));
+				printf("%*c %s\n", indent, '*', menu_get_prompt(child));
 				continue;
 			}
 			cnt++;
@@ -278,14 +277,14 @@
 				printf("%*c", indent, '>');
 			} else
 				printf("%*c", indent, ' ');
-			printf(" %d. %s", cnt, _(menu_get_prompt(child)));
+			printf(" %d. %s", cnt, menu_get_prompt(child));
 			if (child->sym->name)
 				printf(" (%s)", child->sym->name);
 			if (!sym_has_value(child->sym))
-				printf(_(" (NEW)"));
+				printf(" (NEW)");
 			printf("\n");
 		}
-		printf(_("%*schoice"), indent - 1, "");
+		printf("%*schoice", indent - 1, "");
 		if (cnt == 1) {
 			printf("[1]: 1\n");
 			goto conf_childs;
@@ -372,7 +371,7 @@
 			if (prompt)
 				printf("%*c\n%*c %s\n%*c\n",
 					indent, '*',
-					indent, '*', _(prompt),
+					indent, '*', prompt,
 					indent, '*');
 		default:
 			;
@@ -437,7 +436,7 @@
 				}
 			} else {
 				if (!conf_cnt++)
-					printf(_("*\n* Restart config...\n*\n"));
+					printf("*\n* Restart config...\n*\n");
 				rootEntry = menu_get_parent_menu(menu);
 				conf(rootEntry);
 			}
@@ -498,10 +497,6 @@
 	const char *name, *defconfig_file = NULL /* gcc uninit */;
 	struct stat tmpstat;
 
-	setlocale(LC_ALL, "");
-	bindtextdomain(PACKAGE, LOCALEDIR);
-	textdomain(PACKAGE);
-
 	tty_stdio = isatty(0) && isatty(1);
 
 	while ((opt = getopt_long(ac, av, "s", long_opts, NULL)) != -1) {
@@ -559,7 +554,7 @@
 		}
 	}
 	if (ac == optind) {
-		fprintf(stderr, _("%s: Kconfig file missing\n"), av[0]);
+		fprintf(stderr, "%s: Kconfig file missing\n", av[0]);
 		conf_usage(progname);
 		exit(1);
 	}
@@ -569,12 +564,12 @@
 	if (sync_kconfig) {
 		name = conf_get_configname();
 		if (stat(name, &tmpstat)) {
-			fprintf(stderr, _("***\n"
+			fprintf(stderr, "***\n"
 				"*** Configuration file \"%s\" not found!\n"
 				"***\n"
 				"*** Please run some configurator (e.g. \"make oldconfig\" or\n"
 				"*** \"make menuconfig\" or \"make xconfig\").\n"
-				"***\n"), name);
+				"***\n", name);
 			exit(1);
 		}
 	}
@@ -585,9 +580,9 @@
 			defconfig_file = conf_get_default_confname();
 		if (conf_read(defconfig_file)) {
 			fprintf(stderr,
-				_("***\n"
+				"***\n"
 				  "*** Can't find default configuration \"%s\"!\n"
-				  "***\n"),
+				  "***\n",
 				defconfig_file);
 			exit(1);
 		}
@@ -611,7 +606,7 @@
 		if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) {
 			if (conf_read_simple(name, S_DEF_USER)) {
 				fprintf(stderr,
-					_("*** Can't read seed configuration \"%s\"!\n"),
+					"*** Can't read seed configuration \"%s\"!\n",
 					name);
 				exit(1);
 			}
@@ -628,7 +623,7 @@
 		if (conf_read_simple(name, S_DEF_USER) &&
 		    conf_read_simple("all.config", S_DEF_USER)) {
 			fprintf(stderr,
-				_("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"),
+				"*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n",
 				name);
 			exit(1);
 		}
@@ -642,7 +637,7 @@
 			name = getenv("KCONFIG_NOSILENTUPDATE");
 			if (name && *name) {
 				fprintf(stderr,
-					_("\n*** The configuration requires explicit update.\n\n"));
+					"\n*** The configuration requires explicit update.\n\n");
 				return 1;
 			}
 		}
@@ -694,22 +689,22 @@
 		 * All other commands are only used to generate a config.
 		 */
 		if (conf_get_changed() && conf_write(NULL)) {
-			fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
+			fprintf(stderr, "\n*** Error during writing of the configuration.\n\n");
 			exit(1);
 		}
 		if (conf_write_autoconf()) {
-			fprintf(stderr, _("\n*** Error during update of the configuration.\n\n"));
+			fprintf(stderr, "\n*** Error during update of the configuration.\n\n");
 			return 1;
 		}
 	} else if (input_mode == savedefconfig) {
 		if (conf_write_defconfig(defconfig_file)) {
-			fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"),
+			fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n",
 				defconfig_file);
 			return 1;
 		}
 	} else if (input_mode != listnewconfig) {
 		if (conf_write(NULL)) {
-			fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
+			fprintf(stderr, "\n*** Error during writing of the configuration.\n\n");
 			exit(1);
 		}
 	}
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index a04bb26..1abf849 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -30,7 +30,7 @@
 static const char *conf_filename;
 static int conf_lineno, conf_warnings;
 
-const char conf_defname[] = "arch/$ARCH/defconfig";
+const char conf_defname[] = "arch/$(ARCH)/defconfig";
 
 static void conf_warning(const char *fmt, ...)
 {
@@ -81,39 +81,13 @@
 	return name ? name : "include/config/auto.conf";
 }
 
-static char *conf_expand_value(const char *in)
-{
-	struct symbol *sym;
-	const char *src;
-	static char res_value[SYMBOL_MAXLENGTH];
-	char *dst, name[SYMBOL_MAXLENGTH];
-
-	res_value[0] = 0;
-	dst = name;
-	while ((src = strchr(in, '$'))) {
-		strncat(res_value, in, src - in);
-		src++;
-		dst = name;
-		while (isalnum(*src) || *src == '_')
-			*dst++ = *src++;
-		*dst = 0;
-		sym = sym_lookup(name, 0);
-		sym_calc_value(sym);
-		strcat(res_value, sym_get_string_value(sym));
-		in = src;
-	}
-	strcat(res_value, in);
-
-	return res_value;
-}
-
 char *conf_get_default_confname(void)
 {
 	struct stat buf;
 	static char fullname[PATH_MAX+1];
 	char *env, *name;
 
-	name = conf_expand_value(conf_defname);
+	name = expand_string(conf_defname);
 	env = getenv(SRCTREE);
 	if (env) {
 		sprintf(fullname, "%s/%s", env, name);
@@ -270,10 +244,11 @@
 			if (expr_calc_value(prop->visible.expr) == no ||
 			    prop->expr->type != E_SYMBOL)
 				continue;
-			name = conf_expand_value(prop->expr->left.sym->name);
+			sym_calc_value(prop->expr->left.sym);
+			name = sym_get_string_value(prop->expr->left.sym);
 			in = zconf_fopen(name);
 			if (in) {
-				conf_message(_("using defaults found in %s"),
+				conf_message("using defaults found in %s",
 					 name);
 				goto load;
 			}
@@ -829,7 +804,7 @@
 			return 1;
 	}
 
-	conf_message(_("configuration written to %s"), newname);
+	conf_message("configuration written to %s", newname);
 
 	sym_set_change_count(0);
 
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 94a383b..f63b41b 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -171,6 +171,9 @@
  * config BAZ
  *         int "BAZ Value"
  *         range 1..255
+ *
+ * Please, also check zconf.y:print_symbol() when modifying the
+ * list of property types!
  */
 enum prop_type {
 	P_UNKNOWN,
diff --git a/scripts/kconfig/gconf-cfg.sh b/scripts/kconfig/gconf-cfg.sh
new file mode 100755
index 0000000..533b3d8
--- /dev/null
+++ b/scripts/kconfig/gconf-cfg.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+PKG="gtk+-2.0 gmodule-2.0 libglade-2.0"
+
+if ! pkg-config --exists $PKG; then
+	echo >&2 "*"
+	echo >&2 "* Unable to find the GTK+ installation. Please make sure that"
+	echo >&2 "* the GTK+ 2.0 development package is correctly installed."
+	echo >&2 "* You need $PKG"
+	echo >&2 "*"
+	exit 1
+fi
+
+if ! pkg-config --atleast-version=2.0.0 gtk+-2.0; then
+	echo >&2 "*"
+	echo >&2 "* GTK+ is present but version >= 2.0.0 is required."
+	echo >&2 "*"
+	exit 1
+fi
+
+echo cflags=\"$(pkg-config --cflags $PKG)\"
+echo libs=\"$(pkg-config --libs $PKG)\"
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
index cfddddb..610c4ab 100644
--- a/scripts/kconfig/gconf.c
+++ b/scripts/kconfig/gconf.c
@@ -137,7 +137,7 @@
 
 	xml = glade_xml_new(glade_file, "window1", NULL);
 	if (!xml)
-		g_error(_("GUI loading failed !\n"));
+		g_error("GUI loading failed !\n");
 	glade_xml_signal_autoconnect(xml);
 
 	main_wnd = glade_xml_get_widget(xml, "window1");
@@ -233,7 +233,7 @@
 
 	column = gtk_tree_view_column_new();
 	gtk_tree_view_append_column(view, column);
-	gtk_tree_view_column_set_title(column, _("Options"));
+	gtk_tree_view_column_set_title(column, "Options");
 
 	renderer = gtk_cell_renderer_toggle_new();
 	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
@@ -276,7 +276,7 @@
 
 	column = gtk_tree_view_column_new();
 	gtk_tree_view_append_column(view, column);
-	gtk_tree_view_column_set_title(column, _("Options"));
+	gtk_tree_view_column_set_title(column, "Options");
 
 	renderer = gtk_cell_renderer_pixbuf_new();
 	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
@@ -305,7 +305,7 @@
 
 	renderer = gtk_cell_renderer_text_new();
 	gtk_tree_view_insert_column_with_attributes(view, -1,
-						    _("Name"), renderer,
+						    "Name", renderer,
 						    "text", COL_NAME,
 						    "foreground-gdk",
 						    COL_COLOR, NULL);
@@ -329,7 +329,7 @@
 						    COL_COLOR, NULL);
 	renderer = gtk_cell_renderer_text_new();
 	gtk_tree_view_insert_column_with_attributes(view, -1,
-						    _("Value"), renderer,
+						    "Value", renderer,
 						    "text", COL_VALUE,
 						    "editable",
 						    COL_EDIT,
@@ -368,7 +368,7 @@
 {
 	GtkTextBuffer *buffer;
 	GtkTextIter start, end;
-	const char *prompt = _(menu_get_prompt(menu));
+	const char *prompt = menu_get_prompt(menu);
 	struct gstr help = str_new();
 
 	menu_get_ext_help(menu, &help);
@@ -422,7 +422,7 @@
 	if (!conf_get_changed())
 		return FALSE;
 
-	dialog = gtk_dialog_new_with_buttons(_("Warning !"),
+	dialog = gtk_dialog_new_with_buttons("Warning !",
 					     GTK_WINDOW(main_wnd),
 					     (GtkDialogFlags)
 					     (GTK_DIALOG_MODAL |
@@ -436,7 +436,7 @@
 	gtk_dialog_set_default_response(GTK_DIALOG(dialog),
 					GTK_RESPONSE_CANCEL);
 
-	label = gtk_label_new(_("\nSave configuration ?\n"));
+	label = gtk_label_new("\nSave configuration ?\n");
 	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
 	gtk_widget_show(label);
 
@@ -496,7 +496,7 @@
 					     (user_data));
 
 	if (conf_read(fn))
-		text_insert_msg(_("Error"), _("Unable to load configuration !"));
+		text_insert_msg("Error", "Unable to load configuration !");
 	else
 		display_tree(&rootmenu);
 }
@@ -505,7 +505,7 @@
 {
 	GtkWidget *fs;
 
-	fs = gtk_file_selection_new(_("Load file..."));
+	fs = gtk_file_selection_new("Load file...");
 	g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
 			 "clicked",
 			 G_CALLBACK(load_filename), (gpointer) fs);
@@ -524,7 +524,7 @@
 void on_save_activate(GtkMenuItem * menuitem, gpointer user_data)
 {
 	if (conf_write(NULL))
-		text_insert_msg(_("Error"), _("Unable to save configuration !"));
+		text_insert_msg("Error", "Unable to save configuration !");
 }
 
 
@@ -537,7 +537,7 @@
 					     (user_data));
 
 	if (conf_write(fn))
-		text_insert_msg(_("Error"), _("Unable to save configuration !"));
+		text_insert_msg("Error", "Unable to save configuration !");
 
 	gtk_widget_destroy(GTK_WIDGET(user_data));
 }
@@ -546,7 +546,7 @@
 {
 	GtkWidget *fs;
 
-	fs = gtk_file_selection_new(_("Save file as..."));
+	fs = gtk_file_selection_new("Save file as...");
 	g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
 			 "clicked",
 			 G_CALLBACK(store_filename), (gpointer) fs);
@@ -639,7 +639,7 @@
 void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
 {
 	GtkWidget *dialog;
-	const gchar *intro_text = _(
+	const gchar *intro_text = 
 	    "Welcome to gkc, the GTK+ graphical configuration tool\n"
 	    "For each option, a blank box indicates the feature is disabled, a\n"
 	    "check indicates it is enabled, and a dot indicates that it is to\n"
@@ -654,7 +654,7 @@
 	    "option.\n"
 	    "\n"
 	    "Toggling Show Debug Info under the Options menu will show \n"
-	    "the dependencies, which you can then match by examining other options.");
+	    "the dependencies, which you can then match by examining other options.";
 
 	dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
 					GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -671,8 +671,8 @@
 {
 	GtkWidget *dialog;
 	const gchar *about_text =
-	    _("gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n"
-	      "Based on the source code from Roman Zippel.\n");
+	    "gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n"
+	      "Based on the source code from Roman Zippel.\n";
 
 	dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
 					GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -689,9 +689,9 @@
 {
 	GtkWidget *dialog;
 	const gchar *license_text =
-	    _("gkc is released under the terms of the GNU GPL v2.\n"
+	    "gkc is released under the terms of the GNU GPL v2.\n"
 	      "For more information, please see the source code or\n"
-	      "visit http://www.fsf.org/licenses/licenses.html\n");
+	      "visit http://www.fsf.org/licenses/licenses.html\n";
 
 	dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
 					GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -1049,7 +1049,7 @@
 	bzero(row, sizeof(row));
 
 	row[COL_OPTION] =
-	    g_strdup_printf("%s %s", _(menu_get_prompt(menu)),
+	    g_strdup_printf("%s %s", menu_get_prompt(menu),
 			    sym && !sym_has_value(sym) ? "(NEW)" : "");
 
 	if (opt_mode == OPT_ALL && !menu_is_visible(menu))
@@ -1102,7 +1102,7 @@
 
 		if (def_menu)
 			row[COL_VALUE] =
-			    g_strdup(_(menu_get_prompt(def_menu)));
+			    g_strdup(menu_get_prompt(def_menu));
 	}
 	if (sym->flags & SYMBOL_CHOICEVAL)
 		row[COL_BTNRAD] = GINT_TO_POINTER(TRUE);
@@ -1447,10 +1447,6 @@
 	char *env;
 	gchar *glade_file;
 
-	bindtextdomain(PACKAGE, LOCALEDIR);
-	bind_textdomain_codeset(PACKAGE, "UTF-8");
-	textdomain(PACKAGE);
-
 	/* GTK stuffs */
 	gtk_set_locale();
 	gtk_init(&ac, &av);
diff --git a/scripts/kconfig/kconf_id.c b/scripts/kconfig/kconf_id.c
index 3ea9c5f..b3e0ea0 100644
--- a/scripts/kconfig/kconf_id.c
+++ b/scripts/kconfig/kconf_id.c
@@ -32,7 +32,6 @@
 	{ "on",			T_ON,			TF_PARAM },
 	{ "modules",		T_OPT_MODULES,		TF_OPTION },
 	{ "defconfig_list",	T_OPT_DEFCONFIG_LIST,	TF_OPTION },
-	{ "env",		T_OPT_ENV,		TF_OPTION },
 	{ "allnoconfig_y",	T_OPT_ALLNOCONFIG_Y,	TF_OPTION },
 };
 
diff --git a/scripts/kconfig/kxgettext.c b/scripts/kconfig/kxgettext.c
deleted file mode 100644
index 240880a..0000000
--- a/scripts/kconfig/kxgettext.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2005
- *
- * Released under the terms of the GNU GPL v2.0
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "lkc.h"
-
-static char *escape(const char* text, char *bf, int len)
-{
-	char *bfp = bf;
-	int multiline = strchr(text, '\n') != NULL;
-	int eol = 0;
-	int textlen = strlen(text);
-
-	if ((textlen > 0) && (text[textlen-1] == '\n'))
-		eol = 1;
-
-	*bfp++ = '"';
-	--len;
-
-	if (multiline) {
-		*bfp++ = '"';
-		*bfp++ = '\n';
-		*bfp++ = '"';
-		len -= 3;
-	}
-
-	while (*text != '\0' && len > 1) {
-		if (*text == '"')
-			*bfp++ = '\\';
-		else if (*text == '\n') {
-			*bfp++ = '\\';
-			*bfp++ = 'n';
-			*bfp++ = '"';
-			*bfp++ = '\n';
-			*bfp++ = '"';
-			len -= 5;
-			++text;
-			goto next;
-		}
-		else if (*text == '\\') {
-			*bfp++ = '\\';
-			len--;
-		}
-		*bfp++ = *text++;
-next:
-		--len;
-	}
-
-	if (multiline && eol)
-		bfp -= 3;
-
-	*bfp++ = '"';
-	*bfp = '\0';
-
-	return bf;
-}
-
-struct file_line {
-	struct file_line *next;
-	const char *file;
-	int lineno;
-};
-
-static struct file_line *file_line__new(const char *file, int lineno)
-{
-	struct file_line *self = malloc(sizeof(*self));
-
-	if (self == NULL)
-		goto out;
-
-	self->file   = file;
-	self->lineno = lineno;
-	self->next   = NULL;
-out:
-	return self;
-}
-
-struct message {
-	const char	 *msg;
-	const char	 *option;
-	struct message	 *next;
-	struct file_line *files;
-};
-
-static struct message *message__list;
-
-static struct message *message__new(const char *msg, char *option,
-				    const char *file, int lineno)
-{
-	struct message *self = malloc(sizeof(*self));
-
-	if (self == NULL)
-		goto out;
-
-	self->files = file_line__new(file, lineno);
-	if (self->files == NULL)
-		goto out_fail;
-
-	self->msg = xstrdup(msg);
-	if (self->msg == NULL)
-		goto out_fail_msg;
-
-	self->option = option;
-	self->next = NULL;
-out:
-	return self;
-out_fail_msg:
-	free(self->files);
-out_fail:
-	free(self);
-	self = NULL;
-	goto out;
-}
-
-static struct message *mesage__find(const char *msg)
-{
-	struct message *m = message__list;
-
-	while (m != NULL) {
-		if (strcmp(m->msg, msg) == 0)
-			break;
-		m = m->next;
-	}
-
-	return m;
-}
-
-static int message__add_file_line(struct message *self, const char *file,
-				  int lineno)
-{
-	int rc = -1;
-	struct file_line *fl = file_line__new(file, lineno);
-
-	if (fl == NULL)
-		goto out;
-
-	fl->next    = self->files;
-	self->files = fl;
-	rc = 0;
-out:
-	return rc;
-}
-
-static int message__add(const char *msg, char *option, const char *file,
-			int lineno)
-{
-	int rc = 0;
-	char bf[16384];
-	char *escaped = escape(msg, bf, sizeof(bf));
-	struct message *m = mesage__find(escaped);
-
-	if (m != NULL)
-		rc = message__add_file_line(m, file, lineno);
-	else {
-		m = message__new(escaped, option, file, lineno);
-
-		if (m != NULL) {
-			m->next	      = message__list;
-			message__list = m;
-		} else
-			rc = -1;
-	}
-	return rc;
-}
-
-static void menu_build_message_list(struct menu *menu)
-{
-	struct menu *child;
-
-	message__add(menu_get_prompt(menu), NULL,
-		     menu->file == NULL ? "Root Menu" : menu->file->name,
-		     menu->lineno);
-
-	if (menu->sym != NULL && menu_has_help(menu))
-		message__add(menu_get_help(menu), menu->sym->name,
-			     menu->file == NULL ? "Root Menu" : menu->file->name,
-			     menu->lineno);
-
-	for (child = menu->list; child != NULL; child = child->next)
-		if (child->prompt != NULL)
-			menu_build_message_list(child);
-}
-
-static void message__print_file_lineno(struct message *self)
-{
-	struct file_line *fl = self->files;
-
-	putchar('\n');
-	if (self->option != NULL)
-		printf("# %s:00000\n", self->option);
-
-	printf("#: %s:%d", fl->file, fl->lineno);
-	fl = fl->next;
-
-	while (fl != NULL) {
-		printf(", %s:%d", fl->file, fl->lineno);
-		fl = fl->next;
-	}
-
-	putchar('\n');
-}
-
-static void message__print_gettext_msgid_msgstr(struct message *self)
-{
-	message__print_file_lineno(self);
-
-	printf("msgid %s\n"
-	       "msgstr \"\"\n", self->msg);
-}
-
-static void menu__xgettext(void)
-{
-	struct message *m = message__list;
-
-	while (m != NULL) {
-		/* skip empty lines ("") */
-		if (strlen(m->msg) > sizeof("\"\""))
-			message__print_gettext_msgid_msgstr(m);
-		m = m->next;
-	}
-}
-
-int main(int ac, char **av)
-{
-	conf_parse(av[1]);
-
-	menu_build_message_list(menu_get_root_menu(NULL));
-	menu__xgettext();
-	return 0;
-}
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index f4394af..ed3ff88 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -8,15 +8,6 @@
 
 #include "expr.h"
 
-#ifndef KBUILD_NO_NLS
-# include <libintl.h>
-#else
-static inline const char *gettext(const char *txt) { return txt; }
-static inline void textdomain(const char *domainname) {}
-static inline void bindtextdomain(const char *name, const char *dir) {}
-static inline char *bind_textdomain_codeset(const char *dn, char *c) { return c; }
-#endif
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -29,11 +20,6 @@
 #define PACKAGE "linux"
 #endif
 
-#define LOCALEDIR "/usr/share/locale"
-
-#define _(text) gettext(text)
-#define N_(text) (text)
-
 #ifndef CONFIG_
 #define CONFIG_ "CONFIG_"
 #endif
@@ -58,7 +44,6 @@
 
 #define T_OPT_MODULES		1
 #define T_OPT_DEFCONFIG_LIST	2
-#define T_OPT_ENV		3
 #define T_OPT_ALLNOCONFIG_Y	4
 
 struct kconf_id {
@@ -117,6 +102,7 @@
 void *xcalloc(size_t nmemb, size_t size);
 void *xrealloc(void *p, size_t size);
 char *xstrdup(const char *s);
+char *xstrndup(const char *s, size_t n);
 
 struct gstr {
 	size_t len;
@@ -134,9 +120,6 @@
 const char *str_get(struct gstr *gs);
 
 /* symbol.c */
-extern struct expr *sym_env_list;
-
-void sym_init(void);
 void sym_clear_all_valid(void);
 struct symbol *sym_choice_default(struct symbol *sym);
 const char *sym_get_string_default(struct symbol *sym);
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 9dc8abf..a8b7a33 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -31,7 +31,6 @@
 
 struct symbol * sym_lookup(const char *name, int flags);
 struct symbol * sym_find(const char *name);
-char *sym_expand_string_value(const char *in);
 const char * sym_escape_string_value(const char *in);
 struct symbol ** sym_re_search(const char *pattern);
 const char * sym_type_name(enum symbol_type type);
@@ -49,5 +48,19 @@
 
 const char * prop_get_type_name(enum prop_type type);
 
+/* preprocess.c */
+enum variable_flavor {
+	VAR_SIMPLE,
+	VAR_RECURSIVE,
+	VAR_APPEND,
+};
+void env_write_dep(FILE *f, const char *auto_conf_name);
+void variable_add(const char *name, const char *value,
+		  enum variable_flavor flavor);
+void variable_all_del(void);
+char *expand_string(const char *in);
+char *expand_dollar(const char **str);
+char *expand_one_token(const char **str);
+
 /* expr.c */
 void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken);
diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh
deleted file mode 100755
index 6c0bcd9..0000000
--- a/scripts/kconfig/lxdialog/check-lxdialog.sh
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-# Check ncurses compatibility
-
-# What library to link
-ldflags()
-{
-	pkg-config --libs ncursesw 2>/dev/null && exit
-	pkg-config --libs ncurses 2>/dev/null && exit
-	for ext in so a dll.a dylib ; do
-		for lib in ncursesw ncurses curses ; do
-			$cc -print-file-name=lib${lib}.${ext} | grep -q /
-			if [ $? -eq 0 ]; then
-				echo "-l${lib}"
-				exit
-			fi
-		done
-	done
-	exit 1
-}
-
-# Where is ncurses.h?
-ccflags()
-{
-	if pkg-config --cflags ncursesw 2>/dev/null; then
-		echo '-DCURSES_LOC="<ncurses.h>" -DNCURSES_WIDECHAR=1'
-	elif pkg-config --cflags ncurses 2>/dev/null; then
-		echo '-DCURSES_LOC="<ncurses.h>"'
-	elif [ -f /usr/include/ncursesw/curses.h ]; then
-		echo '-I/usr/include/ncursesw -DCURSES_LOC="<curses.h>"'
-		echo ' -DNCURSES_WIDECHAR=1'
-	elif [ -f /usr/include/ncurses/ncurses.h ]; then
-		echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"'
-	elif [ -f /usr/include/ncurses/curses.h ]; then
-		echo '-I/usr/include/ncurses -DCURSES_LOC="<curses.h>"'
-	elif [ -f /usr/include/ncurses.h ]; then
-		echo '-DCURSES_LOC="<ncurses.h>"'
-	else
-		echo '-DCURSES_LOC="<curses.h>"'
-	fi
-}
-
-# Temp file, try to clean up after us
-tmp=.lxdialog.tmp
-trap "rm -f $tmp" 0 1 2 3 15
-
-# Check if we can link to ncurses
-check() {
-        $cc -x c - -o $tmp 2>/dev/null <<'EOF'
-#include CURSES_LOC
-main() {}
-EOF
-	if [ $? != 0 ]; then
-	    echo " *** Unable to find the ncurses libraries or the"       1>&2
-	    echo " *** required header files."                            1>&2
-	    echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2
-	    echo " *** "                                                  1>&2
-	    echo " *** Install ncurses (ncurses-devel or libncurses-dev " 1>&2
-	    echo " *** depending on your distribution) and try again."    1>&2
-	    echo " *** "                                                  1>&2
-	    exit 1
-	fi
-}
-
-usage() {
-	printf "Usage: $0 [-check compiler options|-ccflags|-ldflags compiler options]\n"
-}
-
-if [ $# -eq 0 ]; then
-	usage
-	exit 1
-fi
-
-cc=""
-case "$1" in
-	"-check")
-		shift
-		cc="$@"
-		check
-		;;
-	"-ccflags")
-		ccflags
-		;;
-	"-ldflags")
-		shift
-		cc="$@"
-		ldflags
-		;;
-	"*")
-		usage
-		exit 1
-		;;
-esac
diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c
index fc0b12b..fd161cf 100644
--- a/scripts/kconfig/lxdialog/checklist.c
+++ b/scripts/kconfig/lxdialog/checklist.c
@@ -90,8 +90,8 @@
 	int x = width / 2 - 11;
 	int y = height - 2;
 
-	print_button(dialog, gettext("Select"), y, x, selected == 0);
-	print_button(dialog, gettext(" Help "), y, x + 14, selected == 1);
+	print_button(dialog, "Select", y, x, selected == 0);
+	print_button(dialog, " Help ", y, x + 14, selected == 1);
 
 	wmove(dialog, y, x + 1 + 14 * selected);
 	wrefresh(dialog);
diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h
index b1617ffb..68b565e 100644
--- a/scripts/kconfig/lxdialog/dialog.h
+++ b/scripts/kconfig/lxdialog/dialog.h
@@ -13,16 +13,10 @@
 #include <string.h>
 #include <stdbool.h>
 
-#ifndef KBUILD_NO_NLS
-# include <libintl.h>
-#else
-# define gettext(Msgid) ((const char *) (Msgid))
-#endif
-
 #ifdef __sun__
 #define CURS_MACROS
 #endif
-#include CURSES_LOC
+#include <ncurses.h>
 
 /*
  * Colors in ncurses 1.9.9e do not work properly since foreground and
diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c
index edeb094..6119456 100644
--- a/scripts/kconfig/lxdialog/inputbox.c
+++ b/scripts/kconfig/lxdialog/inputbox.c
@@ -18,8 +18,8 @@
 	int x = width / 2 - 11;
 	int y = height - 2;
 
-	print_button(dialog, gettext("  Ok  "), y, x, selected == 0);
-	print_button(dialog, gettext(" Help "), y, x + 14, selected == 1);
+	print_button(dialog, "  Ok  ", y, x, selected == 0);
+	print_button(dialog, " Help ", y, x + 14, selected == 1);
 
 	wmove(dialog, y, x + 1 + 14 * selected);
 	wrefresh(dialog);
diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c
index 0ef2319..58c2f8a 100644
--- a/scripts/kconfig/lxdialog/menubox.c
+++ b/scripts/kconfig/lxdialog/menubox.c
@@ -144,11 +144,11 @@
 	int x = width / 2 - 28;
 	int y = height - 2;
 
-	print_button(win, gettext("Select"), y, x, selected == 0);
-	print_button(win, gettext(" Exit "), y, x + 12, selected == 1);
-	print_button(win, gettext(" Help "), y, x + 24, selected == 2);
-	print_button(win, gettext(" Save "), y, x + 36, selected == 3);
-	print_button(win, gettext(" Load "), y, x + 48, selected == 4);
+	print_button(win, "Select", y, x, selected == 0);
+	print_button(win, " Exit ", y, x + 12, selected == 1);
+	print_button(win, " Help ", y, x + 24, selected == 2);
+	print_button(win, " Save ", y, x + 36, selected == 3);
+	print_button(win, " Load ", y, x + 48, selected == 4);
 
 	wmove(win, y, x + 1 + 12 * selected);
 	wrefresh(win);
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c
index ab34000..4e339b1 100644
--- a/scripts/kconfig/lxdialog/textbox.c
+++ b/scripts/kconfig/lxdialog/textbox.c
@@ -116,7 +116,7 @@
 
 	print_title(dialog, title, width);
 
-	print_button(dialog, gettext(" Exit "), height - 2, width / 2 - 4, TRUE);
+	print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
 	wnoutrefresh(dialog);
 	getyx(dialog, cur_y, cur_x);	/* Save cursor position */
 
diff --git a/scripts/kconfig/lxdialog/yesno.c b/scripts/kconfig/lxdialog/yesno.c
index 274341d..bcaac9b 100644
--- a/scripts/kconfig/lxdialog/yesno.c
+++ b/scripts/kconfig/lxdialog/yesno.c
@@ -16,8 +16,8 @@
 	int x = width / 2 - 10;
 	int y = height - 2;
 
-	print_button(dialog, gettext(" Yes "), y, x, selected == 0);
-	print_button(dialog, gettext("  No  "), y, x + 13, selected == 1);
+	print_button(dialog, " Yes ", y, x, selected == 0);
+	print_button(dialog, "  No  ", y, x + 13, selected == 1);
 
 	wmove(dialog, y, x + 1 + 13 * selected);
 	wrefresh(dialog);
diff --git a/scripts/kconfig/mconf-cfg.sh b/scripts/kconfig/mconf-cfg.sh
new file mode 100755
index 0000000..e6f9fac
--- /dev/null
+++ b/scripts/kconfig/mconf-cfg.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+PKG="ncursesw"
+PKG2="ncurses"
+
+if pkg-config --exists $PKG; then
+	echo cflags=\"$(pkg-config --cflags $PKG)\"
+	echo libs=\"$(pkg-config --libs $PKG)\"
+	exit 0
+fi
+
+if pkg-config --exists $PKG2; then
+	echo cflags=\"$(pkg-config --cflags $PKG2)\"
+	echo libs=\"$(pkg-config --libs $PKG2)\"
+	exit 0
+fi
+
+# Unfortunately, some distributions (e.g. openSUSE) cannot find ncurses
+# by pkg-config.
+if [ -f /usr/include/ncursesw/ncurses.h ]; then
+	echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncursesw\"
+	echo libs=\"-lncursesw\"
+	exit 0
+fi
+
+if [ -f /usr/include/ncurses/ncurses.h ]; then
+	echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncurses\"
+	echo libs=\"-lncurses\"
+	exit 0
+fi
+
+if [ -f /usr/include/ncurses.h ]; then
+	echo cflags=\"-D_GNU_SOURCE\"
+	echo libs=\"-lncurses\"
+	exit 0
+fi
+
+echo >&2 "*"
+echo >&2 "* Unable to find the ncurses package."
+echo >&2 "* Install ncurses (ncurses-devel or libncurses-dev"
+echo >&2 "* depending on your distribution)."
+echo >&2 "*"
+exit 1
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index c829be8..5294ed1 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -17,12 +17,11 @@
 #include <string.h>
 #include <signal.h>
 #include <unistd.h>
-#include <locale.h>
 
 #include "lkc.h"
 #include "lxdialog/dialog.h"
 
-static const char mconf_readme[] = N_(
+static const char mconf_readme[] =
 "Overview\n"
 "--------\n"
 "This interface lets you select features and parameters for the build.\n"
@@ -171,37 +170,37 @@
 " blackbg    => selects a color scheme with black background\n"
 " classic    => theme with blue background. The classic look\n"
 " bluetitle  => an LCD friendly version of classic. (default)\n"
-"\n"),
-menu_instructions[] = N_(
+"\n",
+menu_instructions[] =
 	"Arrow keys navigate the menu.  "
 	"<Enter> selects submenus ---> (or empty submenus ----).  "
 	"Highlighted letters are hotkeys.  "
 	"Pressing <Y> includes, <N> excludes, <M> modularizes features.  "
 	"Press <Esc><Esc> to exit, <?> for Help, </> for Search.  "
-	"Legend: [*] built-in  [ ] excluded  <M> module  < > module capable"),
-radiolist_instructions[] = N_(
+	"Legend: [*] built-in  [ ] excluded  <M> module  < > module capable",
+radiolist_instructions[] =
 	"Use the arrow keys to navigate this window or "
 	"press the hotkey of the item you wish to select "
 	"followed by the <SPACE BAR>. "
-	"Press <?> for additional information about this option."),
-inputbox_instructions_int[] = N_(
+	"Press <?> for additional information about this option.",
+inputbox_instructions_int[] =
 	"Please enter a decimal value. "
 	"Fractions will not be accepted.  "
-	"Use the <TAB> key to move from the input field to the buttons below it."),
-inputbox_instructions_hex[] = N_(
+	"Use the <TAB> key to move from the input field to the buttons below it.",
+inputbox_instructions_hex[] =
 	"Please enter a hexadecimal value. "
-	"Use the <TAB> key to move from the input field to the buttons below it."),
-inputbox_instructions_string[] = N_(
+	"Use the <TAB> key to move from the input field to the buttons below it.",
+inputbox_instructions_string[] =
 	"Please enter a string value. "
-	"Use the <TAB> key to move from the input field to the buttons below it."),
-setmod_text[] = N_(
+	"Use the <TAB> key to move from the input field to the buttons below it.",
+setmod_text[] =
 	"This feature depends on another which has been configured as a module.\n"
-	"As a result, this feature will be built as a module."),
-load_config_text[] = N_(
+	"As a result, this feature will be built as a module.",
+load_config_text[] =
 	"Enter the name of the configuration file you wish to load.  "
 	"Accept the name shown to restore the configuration you "
-	"last retrieved.  Leave blank to abort."),
-load_config_help[] = N_(
+	"last retrieved.  Leave blank to abort.",
+load_config_help[] =
 	"\n"
 	"For various reasons, one may wish to keep several different\n"
 	"configurations available on a single machine.\n"
@@ -211,11 +210,11 @@
 	"configuration.\n"
 	"\n"
 	"If you are uncertain, then you have probably never used alternate\n"
-	"configuration files. You should therefore leave this blank to abort.\n"),
-save_config_text[] = N_(
+	"configuration files. You should therefore leave this blank to abort.\n",
+save_config_text[] =
 	"Enter a filename to which this configuration should be saved "
-	"as an alternate.  Leave blank to abort."),
-save_config_help[] = N_(
+	"as an alternate.  Leave blank to abort.",
+save_config_help[] =
 	"\n"
 	"For various reasons, one may wish to keep different configurations\n"
 	"available on a single machine.\n"
@@ -225,8 +224,8 @@
 	"configuration options you have selected at that time.\n"
 	"\n"
 	"If you are uncertain what all this means then you should probably\n"
-	"leave this blank.\n"),
-search_help[] = N_(
+	"leave this blank.\n",
+search_help[] =
 	"\n"
 	"Search for symbols and display their relations.\n"
 	"Regular expressions are allowed.\n"
@@ -271,7 +270,7 @@
 	"Examples: USB	=> find all symbols containing USB\n"
 	"          ^USB => find all symbols starting with USB\n"
 	"          USB$ => find all symbols ending with USB\n"
-	"\n");
+	"\n";
 
 static int indent;
 static struct menu *current_menu;
@@ -400,19 +399,19 @@
 	struct subtitle_part stpart;
 
 	title = str_new();
-	str_printf( &title, _("Enter (sub)string or regexp to search for "
-			      "(with or without \"%s\")"), CONFIG_);
+	str_printf( &title, "Enter (sub)string or regexp to search for "
+			      "(with or without \"%s\")", CONFIG_);
 
 again:
 	dialog_clear();
-	dres = dialog_inputbox(_("Search Configuration Parameter"),
+	dres = dialog_inputbox("Search Configuration Parameter",
 			      str_get(&title),
 			      10, 75, "");
 	switch (dres) {
 	case 0:
 		break;
 	case 1:
-		show_helptext(_("Search Configuration"), search_help);
+		show_helptext("Search Configuration", search_help);
 		goto again;
 	default:
 		str_free(&title);
@@ -443,7 +442,7 @@
 
 		res = get_relations_str(sym_arr, &head);
 		set_subtitle();
-		dres = show_textbox_ext(_("Search Results"), (char *)
+		dres = show_textbox_ext("Search Results", (char *)
 					str_get(&res), 0, 0, keys, &vscroll,
 					&hscroll, &update_text, (void *)
 					&data);
@@ -491,7 +490,7 @@
 			switch (prop->type) {
 			case P_MENU:
 				child_count++;
-				prompt = _(prompt);
+				prompt = prompt;
 				if (single_menu_mode) {
 					item_make("%s%*c%s",
 						  menu->data ? "-->" : "++>",
@@ -508,7 +507,7 @@
 			case P_COMMENT:
 				if (prompt) {
 					child_count++;
-					item_make("   %*c*** %s ***", indent + 1, ' ', _(prompt));
+					item_make("   %*c*** %s ***", indent + 1, ' ', prompt);
 					item_set_tag(':');
 					item_set_data(menu);
 				}
@@ -516,7 +515,7 @@
 			default:
 				if (prompt) {
 					child_count++;
-					item_make("---%*c%s", indent + 1, ' ', _(prompt));
+					item_make("---%*c%s", indent + 1, ' ', prompt);
 					item_set_tag(':');
 					item_set_data(menu);
 				}
@@ -560,10 +559,10 @@
 			item_set_data(menu);
 		}
 
-		item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
+		item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
 		if (val == yes) {
 			if (def_menu) {
-				item_add_str(" (%s)", _(menu_get_prompt(def_menu)));
+				item_add_str(" (%s)", menu_get_prompt(def_menu));
 				item_add_str("  --->");
 				if (def_menu->list) {
 					indent += 2;
@@ -575,7 +574,7 @@
 		}
 	} else {
 		if (menu == current_menu) {
-			item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
+			item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
 			item_set_tag(':');
 			item_set_data(menu);
 			goto conf_childs;
@@ -618,17 +617,17 @@
 				tmp = indent - tmp + 4;
 				if (tmp < 0)
 					tmp = 0;
-				item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)),
+				item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
 					     (sym_has_value(sym) || !sym_is_changable(sym)) ?
-					     "" : _(" (NEW)"));
+					     "" : " (NEW)");
 				item_set_tag('s');
 				item_set_data(menu);
 				goto conf_childs;
 			}
 		}
-		item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)),
+		item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
 			  (sym_has_value(sym) || !sym_is_changable(sym)) ?
-			  "" : _(" (NEW)"));
+			  "" : " (NEW)");
 		if (menu->prompt->type == P_MENU) {
 			item_add_str("  %s", menu_is_empty(menu) ? "----" : "--->");
 			return;
@@ -665,8 +664,8 @@
 			break;
 		set_subtitle();
 		dialog_clear();
-		res = dialog_menu(prompt ? _(prompt) : _("Main Menu"),
-				  _(menu_instructions),
+		res = dialog_menu(prompt ? prompt : "Main Menu",
+				  menu_instructions,
 				  active_menu, &s_scroll);
 		if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
 			break;
@@ -708,7 +707,7 @@
 				show_help(submenu);
 			else {
 				reset_subtitle();
-				show_helptext(_("README"), _(mconf_readme));
+				show_helptext("README", mconf_readme);
 			}
 			break;
 		case 3:
@@ -793,13 +792,13 @@
 	help.max_width = getmaxx(stdscr) - 10;
 	menu_get_ext_help(menu, &help);
 
-	show_helptext(_(menu_get_prompt(menu)), str_get(&help));
+	show_helptext(menu_get_prompt(menu), str_get(&help));
 	str_free(&help);
 }
 
 static void conf_choice(struct menu *menu)
 {
-	const char *prompt = _(menu_get_prompt(menu));
+	const char *prompt = menu_get_prompt(menu);
 	struct menu *child;
 	struct symbol *active;
 
@@ -814,9 +813,9 @@
 			if (!menu_is_visible(child))
 				continue;
 			if (child->sym)
-				item_make("%s", _(menu_get_prompt(child)));
+				item_make("%s", menu_get_prompt(child));
 			else {
-				item_make("*** %s ***", _(menu_get_prompt(child)));
+				item_make("*** %s ***", menu_get_prompt(child));
 				item_set_tag(':');
 			}
 			item_set_data(child);
@@ -826,8 +825,8 @@
 				item_set_tag('X');
 		}
 		dialog_clear();
-		res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"),
-					_(radiolist_instructions),
+		res = dialog_checklist(prompt ? prompt : "Main Menu",
+					radiolist_instructions,
 					MENUBOX_HEIGTH_MIN,
 					MENUBOX_WIDTH_MIN,
 					CHECKLIST_HEIGTH_MIN);
@@ -868,26 +867,26 @@
 
 		switch (sym_get_type(menu->sym)) {
 		case S_INT:
-			heading = _(inputbox_instructions_int);
+			heading = inputbox_instructions_int;
 			break;
 		case S_HEX:
-			heading = _(inputbox_instructions_hex);
+			heading = inputbox_instructions_hex;
 			break;
 		case S_STRING:
-			heading = _(inputbox_instructions_string);
+			heading = inputbox_instructions_string;
 			break;
 		default:
-			heading = _("Internal mconf error!");
+			heading = "Internal mconf error!";
 		}
 		dialog_clear();
-		res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"),
+		res = dialog_inputbox(prompt ? prompt : "Main Menu",
 				      heading, 10, 75,
 				      sym_get_string_value(menu->sym));
 		switch (res) {
 		case 0:
 			if (sym_set_string_value(menu->sym, dialog_input_result))
 				return;
-			show_textbox(NULL, _("You have made an invalid entry."), 5, 43);
+			show_textbox(NULL, "You have made an invalid entry.", 5, 43);
 			break;
 		case 1:
 			show_help(menu);
@@ -915,10 +914,10 @@
 				sym_set_change_count(1);
 				return;
 			}
-			show_textbox(NULL, _("File does not exist!"), 5, 38);
+			show_textbox(NULL, "File does not exist!", 5, 38);
 			break;
 		case 1:
-			show_helptext(_("Load Alternate Configuration"), load_config_help);
+			show_helptext("Load Alternate Configuration", load_config_help);
 			break;
 		case KEY_ESC:
 			return;
@@ -941,10 +940,10 @@
 				set_config_filename(dialog_input_result);
 				return;
 			}
-			show_textbox(NULL, _("Can't create file!  Probably a nonexistent directory."), 5, 60);
+			show_textbox(NULL, "Can't create file!  Probably a nonexistent directory.", 5, 60);
 			break;
 		case 1:
-			show_helptext(_("Save Alternate Configuration"), save_config_help);
+			show_helptext("Save Alternate Configuration", save_config_help);
 			break;
 		case KEY_ESC:
 			return;
@@ -961,8 +960,8 @@
 	dialog_clear();
 	if (conf_get_changed())
 		res = dialog_yesno(NULL,
-				   _("Do you wish to save your new configuration?\n"
-				     "(Press <ESC><ESC> to continue kernel configuration.)"),
+				   "Do you wish to save your new configuration?\n"
+				     "(Press <ESC><ESC> to continue kernel configuration.)",
 				   6, 60);
 	else
 		res = -1;
@@ -972,26 +971,26 @@
 	switch (res) {
 	case 0:
 		if (conf_write(filename)) {
-			fprintf(stderr, _("\n\n"
+			fprintf(stderr, "\n\n"
 					  "Error while writing of the configuration.\n"
 					  "Your configuration changes were NOT saved."
-					  "\n\n"));
+					  "\n\n");
 			return 1;
 		}
 		/* fall through */
 	case -1:
 		if (!silent)
-			printf(_("\n\n"
+			printf("\n\n"
 				 "*** End of the configuration.\n"
 				 "*** Execute 'make' to start the build or try 'make help'."
-				 "\n\n"));
+				 "\n\n");
 		res = 0;
 		break;
 	default:
 		if (!silent)
-			fprintf(stderr, _("\n\n"
+			fprintf(stderr, "\n\n"
 					  "Your configuration changes were NOT saved."
-					  "\n\n"));
+					  "\n\n");
 		if (res != KEY_ESC)
 			res = 0;
 	}
@@ -1009,10 +1008,6 @@
 	char *mode;
 	int res;
 
-	setlocale(LC_ALL, "");
-	bindtextdomain(PACKAGE, LOCALEDIR);
-	textdomain(PACKAGE);
-
 	signal(SIGINT, sig_handler);
 
 	if (ac > 1 && strcmp(av[1], "-s") == 0) {
@@ -1031,8 +1026,8 @@
 	}
 
 	if (init_dialog(NULL)) {
-		fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
-		fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
+		fprintf(stderr, "Your display is too small to run Menuconfig!\n");
+		fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
 		return 1;
 	}
 
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 5c5c137..379a119 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -214,9 +214,6 @@
 			zconf_error("trying to redefine defconfig symbol");
 		sym_defconfig_list->flags |= SYMBOL_AUTO;
 		break;
-	case T_OPT_ENV:
-		prop_add_env(arg);
-		break;
 	case T_OPT_ALLNOCONFIG_Y:
 		current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y;
 		break;
@@ -711,7 +708,7 @@
 	struct menu *submenu[8], *menu, *location = NULL;
 	struct jump_key *jump = NULL;
 
-	str_printf(r, _("Prompt: %s\n"), _(prop->text));
+	str_printf(r, "Prompt: %s\n", prop->text);
 	menu = prop->menu->parent;
 	for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) {
 		bool accessible = menu_is_visible(menu);
@@ -744,16 +741,16 @@
 	}
 
 	if (i > 0) {
-		str_printf(r, _("  Location:\n"));
+		str_printf(r, "  Location:\n");
 		for (j = 4; --i >= 0; j += 2) {
 			menu = submenu[i];
 			if (jump && menu == location)
 				jump->offset = strlen(r->s);
 			str_printf(r, "%*c-> %s", j, ' ',
-				   _(menu_get_prompt(menu)));
+				   menu_get_prompt(menu));
 			if (menu->sym) {
 				str_printf(r, " (%s [=%s])", menu->sym->name ?
-					menu->sym->name : _("<choice>"),
+					menu->sym->name : "<choice>",
 					sym_get_string_value(menu->sym));
 			}
 			str_append(r, "\n");
@@ -817,23 +814,23 @@
 
 	prop = get_symbol_prop(sym);
 	if (prop) {
-		str_printf(r, _("  Defined at %s:%d\n"), prop->menu->file->name,
+		str_printf(r, "  Defined at %s:%d\n", prop->menu->file->name,
 			prop->menu->lineno);
 		if (!expr_is_yes(prop->visible.expr)) {
-			str_append(r, _("  Depends on: "));
+			str_append(r, "  Depends on: ");
 			expr_gstr_print(prop->visible.expr, r);
 			str_append(r, "\n");
 		}
 	}
 
-	get_symbol_props_str(r, sym, P_SELECT, _("  Selects: "));
+	get_symbol_props_str(r, sym, P_SELECT, "  Selects: ");
 	if (sym->rev_dep.expr) {
 		expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, "  Selected by [y]:\n");
 		expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, "  Selected by [m]:\n");
 		expr_gstr_print_revdep(sym->rev_dep.expr, r, no, "  Selected by [n]:\n");
 	}
 
-	get_symbol_props_str(r, sym, P_IMPLY, _("  Implies: "));
+	get_symbol_props_str(r, sym, P_IMPLY, "  Implies: ");
 	if (sym->implied.expr) {
 		expr_gstr_print_revdep(sym->implied.expr, r, yes, "  Implied by [y]:\n");
 		expr_gstr_print_revdep(sym->implied.expr, r, mod, "  Implied by [m]:\n");
@@ -852,7 +849,7 @@
 	for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
 		get_symbol_str(&res, sym, head);
 	if (!i)
-		str_append(&res, _("No matches found.\n"));
+		str_append(&res, "No matches found.\n");
 	return res;
 }
 
@@ -867,7 +864,7 @@
 			str_printf(help, "%s%s:\n\n", CONFIG_, sym->name);
 		help_text = menu_get_help(menu);
 	}
-	str_printf(help, "%s\n", _(help_text));
+	str_printf(help, "%s\n", help_text);
 	if (sym)
 		get_symbol_str(help, sym, NULL);
 }
diff --git a/scripts/kconfig/nconf-cfg.sh b/scripts/kconfig/nconf-cfg.sh
new file mode 100644
index 0000000..42f5ac7
--- /dev/null
+++ b/scripts/kconfig/nconf-cfg.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+PKG="ncursesw menuw panelw"
+PKG2="ncurses menu panel"
+
+if pkg-config --exists $PKG; then
+	echo cflags=\"$(pkg-config --cflags $PKG)\"
+	echo libs=\"$(pkg-config --libs $PKG)\"
+	exit 0
+fi
+
+if pkg-config --exists $PKG2; then
+	echo cflags=\"$(pkg-config --cflags $PKG2)\"
+	echo libs=\"$(pkg-config --libs $PKG2)\"
+	exit 0
+fi
+
+# Unfortunately, some distributions (e.g. openSUSE) cannot find ncurses
+# by pkg-config.
+if [ -f /usr/include/ncursesw/ncurses.h ]; then
+	echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncursesw\"
+	echo libs=\"-lncursesw -lmenuw -lpanelw\"
+	exit 0
+fi
+
+if [ -f /usr/include/ncurses/ncurses.h ]; then
+	echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncurses\"
+	echo libs=\"-lncurses -lmenu -lpanel\"
+	exit 0
+fi
+
+if [ -f /usr/include/ncurses.h ]; then
+	echo cflags=\"-D_GNU_SOURCE\"
+	echo libs=\"-lncurses -lmenu -lpanel\"
+	exit 0
+fi
+
+echo >&2 "*"
+echo >&2 "* Unable to find the ncurses package."
+echo >&2 "* Install ncurses (ncurses-devel or libncurses-dev"
+echo >&2 "* depending on your distribution)."
+echo >&2 "*"
+exit 1
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
index 0031147..97b7844 100644
--- a/scripts/kconfig/nconf.c
+++ b/scripts/kconfig/nconf.c
@@ -15,7 +15,7 @@
 #include "nconf.h"
 #include <ctype.h>
 
-static const char nconf_global_help[] = N_(
+static const char nconf_global_help[] =
 "Help windows\n"
 "------------\n"
 "o  Global help:  Unless in a data entry window, pressing <F1> will give \n"
@@ -130,8 +130,8 @@
 "\n"
 "Note that this mode can eventually be a little more CPU expensive than\n"
 "the default mode, especially with a larger number of unfolded submenus.\n"
-"\n"),
-menu_no_f_instructions[] = N_(
+"\n",
+menu_no_f_instructions[] =
 "Legend:  [*] built-in  [ ] excluded  <M> module  < > module capable.\n"
 "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"
 "\n"
@@ -147,8 +147,8 @@
 "You do not have function keys support.\n"
 "Press <1> instead of <F1>, <2> instead of <F2>, etc.\n"
 "For verbose global help use key <1>.\n"
-"For help related to the current menu entry press <?> or <h>.\n"),
-menu_instructions[] = N_(
+"For help related to the current menu entry press <?> or <h>.\n",
+menu_instructions[] =
 "Legend:  [*] built-in  [ ] excluded  <M> module  < > module capable.\n"
 "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"
 "\n"
@@ -163,30 +163,30 @@
 "\n"
 "Pressing <1> may be used instead of <F1>, <2> instead of <F2>, etc.\n"
 "For verbose global help press <F1>.\n"
-"For help related to the current menu entry press <?> or <h>.\n"),
-radiolist_instructions[] = N_(
+"For help related to the current menu entry press <?> or <h>.\n",
+radiolist_instructions[] =
 "Press <Up>, <Down>, <Home> or <End> to navigate a radiolist, select\n"
 "with <Space>.\n"
 "For help related to the current entry press <?> or <h>.\n"
-"For global help press <F1>.\n"),
-inputbox_instructions_int[] = N_(
+"For global help press <F1>.\n",
+inputbox_instructions_int[] =
 "Please enter a decimal value.\n"
 "Fractions will not be accepted.\n"
-"Press <Enter> to apply, <Esc> to cancel."),
-inputbox_instructions_hex[] = N_(
+"Press <Enter> to apply, <Esc> to cancel.",
+inputbox_instructions_hex[] =
 "Please enter a hexadecimal value.\n"
-"Press <Enter> to apply, <Esc> to cancel."),
-inputbox_instructions_string[] = N_(
+"Press <Enter> to apply, <Esc> to cancel.",
+inputbox_instructions_string[] =
 "Please enter a string value.\n"
-"Press <Enter> to apply, <Esc> to cancel."),
-setmod_text[] = N_(
+"Press <Enter> to apply, <Esc> to cancel.",
+setmod_text[] =
 "This feature depends on another feature which has been configured as a\n"
-"module.  As a result, the current feature will be built as a module too."),
-load_config_text[] = N_(
+"module.  As a result, the current feature will be built as a module too.",
+load_config_text[] =
 "Enter the name of the configuration file you wish to load.\n"
 "Accept the name shown to restore the configuration you last\n"
-"retrieved.  Leave empty to abort."),
-load_config_help[] = N_(
+"retrieved.  Leave empty to abort.",
+load_config_help[] =
 "For various reasons, one may wish to keep several different\n"
 "configurations available on a single machine.\n"
 "\n"
@@ -194,11 +194,11 @@
 "default one, entering its name here will allow you to load and modify\n"
 "that configuration.\n"
 "\n"
-"Leave empty to abort.\n"),
-save_config_text[] = N_(
+"Leave empty to abort.\n",
+save_config_text[] =
 "Enter a filename to which this configuration should be saved\n"
-"as an alternate.  Leave empty to abort."),
-save_config_help[] = N_(
+"as an alternate.  Leave empty to abort.",
+save_config_help[] =
 "For various reasons, one may wish to keep several different\n"
 "configurations available on a single machine.\n"
 "\n"
@@ -206,8 +206,8 @@
 "and use the current configuration as an alternate to whatever\n"
 "configuration options you have selected at that time.\n"
 "\n"
-"Leave empty to abort.\n"),
-search_help[] = N_(
+"Leave empty to abort.\n",
+search_help[] =
 "Search for symbols (configuration variable names CONFIG_*) and display\n"
 "their relations.  Regular expressions are supported.\n"
 "Example:  Search for \"^FOO\".\n"
@@ -244,7 +244,7 @@
 "USB  => find all symbols containing USB\n"
 "^USB => find all symbols starting with USB\n"
 "USB$ => find all symbols ending with USB\n"
-"\n");
+"\n";
 
 struct mitem {
 	char str[256];
@@ -388,7 +388,7 @@
 static void handle_f1(int *key, struct menu *current_item)
 {
 	show_scroll_win(main_window,
-			_("Global help"), _(nconf_global_help));
+			"Global help", nconf_global_help);
 	return;
 }
 
@@ -403,8 +403,8 @@
 static void handle_f3(int *key, struct menu *current_item)
 {
 	show_scroll_win(main_window,
-			_("Short help"),
-			_(current_instructions));
+			"Short help",
+			current_instructions);
 	return;
 }
 
@@ -412,7 +412,7 @@
 static void handle_f4(int *key, struct menu *current_item)
 {
 	int res = btn_dialog(main_window,
-			_("Show all symbols?"),
+			"Show all symbols?",
 			2,
 			"   <Show All>   ",
 			"<Don't show all>");
@@ -653,8 +653,8 @@
 		return 0;
 	}
 	res = btn_dialog(main_window,
-			_("Do you wish to save your new configuration?\n"
-				"<ESC> to cancel and resume nconfig."),
+			"Do you wish to save your new configuration?\n"
+				"<ESC> to cancel and resume nconfig.",
 			2,
 			"   <save>   ",
 			"<don't save>");
@@ -670,15 +670,15 @@
 		if (res)
 			btn_dialog(
 				main_window,
-				_("Error during writing of configuration.\n"
-				  "Your configuration changes were NOT saved."),
+				"Error during writing of configuration.\n"
+				  "Your configuration changes were NOT saved.",
 				  1,
 				  "<OK>");
 		break;
 	default:
 		btn_dialog(
 			main_window,
-			_("Your configuration changes were NOT saved."),
+			"Your configuration changes were NOT saved.",
 			1,
 			"<OK>");
 		break;
@@ -697,12 +697,12 @@
 	int dres;
 
 	title = str_new();
-	str_printf( &title, _("Enter (sub)string or regexp to search for "
-			      "(with or without \"%s\")"), CONFIG_);
+	str_printf( &title, "Enter (sub)string or regexp to search for "
+			      "(with or without \"%s\")", CONFIG_);
 
 again:
 	dres = dialog_inputbox(main_window,
-			_("Search Configuration Parameter"),
+			"Search Configuration Parameter",
 			str_get(&title),
 			"", &dialog_input_result, &dialog_input_result_len);
 	switch (dres) {
@@ -710,7 +710,7 @@
 		break;
 	case 1:
 		show_scroll_win(main_window,
-				_("Search Configuration"), search_help);
+				"Search Configuration", search_help);
 		goto again;
 	default:
 		str_free(&title);
@@ -726,7 +726,7 @@
 	res = get_relations_str(sym_arr, NULL);
 	free(sym_arr);
 	show_scroll_win(main_window,
-			_("Search Results"), str_get(&res));
+			"Search Results", str_get(&res));
 	str_free(&res);
 	str_free(&title);
 }
@@ -754,7 +754,7 @@
 			switch (ptype) {
 			case P_MENU:
 				child_count++;
-				prompt = _(prompt);
+				prompt = prompt;
 				if (single_menu_mode) {
 					item_make(menu, 'm',
 						"%s%*c%s",
@@ -775,7 +775,7 @@
 					item_make(menu, ':',
 						"   %*c*** %s ***",
 						indent + 1, ' ',
-						_(prompt));
+						prompt);
 				}
 				break;
 			default:
@@ -783,7 +783,7 @@
 					child_count++;
 					item_make(menu, ':', "---%*c%s",
 						indent + 1, ' ',
-						_(prompt));
+						prompt);
 				}
 			}
 		} else
@@ -829,11 +829,11 @@
 		}
 
 		item_add_str("%*c%s", indent + 1,
-				' ', _(menu_get_prompt(menu)));
+				' ', menu_get_prompt(menu));
 		if (val == yes) {
 			if (def_menu) {
 				item_add_str(" (%s)",
-					_(menu_get_prompt(def_menu)));
+					menu_get_prompt(def_menu));
 				item_add_str("  --->");
 				if (def_menu->list) {
 					indent += 2;
@@ -847,7 +847,7 @@
 		if (menu == current_menu) {
 			item_make(menu, ':',
 				"---%*c%s", indent + 1,
-				' ', _(menu_get_prompt(menu)));
+				' ', menu_get_prompt(menu));
 			goto conf_childs;
 		}
 		child_count++;
@@ -894,17 +894,17 @@
 				if (tmp < 0)
 					tmp = 0;
 				item_add_str("%*c%s%s", tmp, ' ',
-						_(menu_get_prompt(menu)),
+						menu_get_prompt(menu),
 						(sym_has_value(sym) ||
 						 !sym_is_changable(sym)) ? "" :
-						_(" (NEW)"));
+						" (NEW)");
 				goto conf_childs;
 			}
 		}
 		item_add_str("%*c%s%s", indent + 1, ' ',
-				_(menu_get_prompt(menu)),
+				menu_get_prompt(menu),
 				(sym_has_value(sym) || !sym_is_changable(sym)) ?
-				"" : _(" (NEW)"));
+				"" : " (NEW)");
 		if (menu->prompt && menu->prompt->type == P_MENU) {
 			item_add_str("  %s", menu_is_empty(menu) ? "----" : "--->");
 			return;
@@ -1086,8 +1086,8 @@
 		if (!child_count)
 			break;
 
-		show_menu(prompt ? _(prompt) : _("Main Menu"),
-				_(menu_instructions),
+		show_menu(prompt ? prompt : "Main Menu",
+				menu_instructions,
 				current_index, &last_top_row);
 		keypad((menu_win(curses_menu)), TRUE);
 		while (!global_exit) {
@@ -1227,13 +1227,13 @@
 
 	help = str_new();
 	menu_get_ext_help(menu, &help);
-	show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help));
+	show_scroll_win(main_window, menu_get_prompt(menu), str_get(&help));
 	str_free(&help);
 }
 
 static void conf_choice(struct menu *menu)
 {
-	const char *prompt = _(menu_get_prompt(menu));
+	const char *prompt = menu_get_prompt(menu);
 	struct menu *child = NULL;
 	struct symbol *active;
 	int selected_index = 0;
@@ -1256,13 +1256,13 @@
 
 			if (child->sym == sym_get_choice_value(menu->sym))
 				item_make(child, ':', "<X> %s",
-						_(menu_get_prompt(child)));
+						menu_get_prompt(child));
 			else if (child->sym)
 				item_make(child, ':', "    %s",
-						_(menu_get_prompt(child)));
+						menu_get_prompt(child));
 			else
 				item_make(child, ':', "*** %s ***",
-						_(menu_get_prompt(child)));
+						menu_get_prompt(child));
 
 			if (child->sym == active){
 				last_top_row = top_row(curses_menu);
@@ -1270,8 +1270,8 @@
 			}
 			i++;
 		}
-		show_menu(prompt ? _(prompt) : _("Choice Menu"),
-				_(radiolist_instructions),
+		show_menu(prompt ? prompt : "Choice Menu",
+				radiolist_instructions,
 				selected_index,
 				&last_top_row);
 		while (!global_exit) {
@@ -1358,19 +1358,19 @@
 
 		switch (sym_get_type(menu->sym)) {
 		case S_INT:
-			heading = _(inputbox_instructions_int);
+			heading = inputbox_instructions_int;
 			break;
 		case S_HEX:
-			heading = _(inputbox_instructions_hex);
+			heading = inputbox_instructions_hex;
 			break;
 		case S_STRING:
-			heading = _(inputbox_instructions_string);
+			heading = inputbox_instructions_string;
 			break;
 		default:
-			heading = _("Internal nconf error!");
+			heading = "Internal nconf error!";
 		}
 		res = dialog_inputbox(main_window,
-				prompt ? _(prompt) : _("Main Menu"),
+				prompt ? prompt : "Main Menu",
 				heading,
 				sym_get_string_value(menu->sym),
 				&dialog_input_result,
@@ -1381,7 +1381,7 @@
 						dialog_input_result))
 				return;
 			btn_dialog(main_window,
-				_("You have made an invalid entry."), 0);
+				"You have made an invalid entry.", 0);
 			break;
 		case 1:
 			show_help(menu);
@@ -1410,11 +1410,11 @@
 				sym_set_change_count(1);
 				return;
 			}
-			btn_dialog(main_window, _("File does not exist!"), 0);
+			btn_dialog(main_window, "File does not exist!", 0);
 			break;
 		case 1:
 			show_scroll_win(main_window,
-					_("Load Alternate Configuration"),
+					"Load Alternate Configuration",
 					load_config_help);
 			break;
 		case KEY_EXIT:
@@ -1441,13 +1441,13 @@
 				set_config_filename(dialog_input_result);
 				return;
 			}
-			btn_dialog(main_window, _("Can't create file! "
-				"Probably a nonexistent directory."),
+			btn_dialog(main_window, "Can't create file! "
+				"Probably a nonexistent directory.",
 				1, "<OK>");
 			break;
 		case 1:
 			show_scroll_win(main_window,
-				_("Save Alternate Configuration"),
+				"Save Alternate Configuration",
 				save_config_help);
 			break;
 		case KEY_EXIT:
@@ -1480,10 +1480,6 @@
 	int lines, columns;
 	char *mode;
 
-	setlocale(LC_ALL, "");
-	bindtextdomain(PACKAGE, LOCALEDIR);
-	textdomain(PACKAGE);
-
 	if (ac > 1 && strcmp(av[1], "-s") == 0) {
 		/* Silence conf_read() until the real callback is set up */
 		conf_set_message_callback(NULL);
@@ -1541,8 +1537,8 @@
 	/* check for KEY_FUNC(1) */
 	if (has_key(KEY_F(1)) == FALSE) {
 		show_scroll_win(main_window,
-				_("Instructions"),
-				_(menu_no_f_instructions));
+				"Instructions",
+				menu_no_f_instructions);
 	}
 
 	conf_set_message_callback(conf_message_callback);
diff --git a/scripts/kconfig/nconf.h b/scripts/kconfig/nconf.h
index 9f6f21d..2b9e19f 100644
--- a/scripts/kconfig/nconf.h
+++ b/scripts/kconfig/nconf.h
@@ -14,7 +14,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <locale.h>
 #include <ncurses.h>
 #include <menu.h>
 #include <panel.h>
diff --git a/scripts/kconfig/preprocess.c b/scripts/kconfig/preprocess.c
new file mode 100644
index 0000000..5ca2df7
--- /dev/null
+++ b/scripts/kconfig/preprocess.c
@@ -0,0 +1,572 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2018 Masahiro Yamada <yamada.masahiro@socionext.com>
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "list.h"
+
+#define ARRAY_SIZE(arr)		(sizeof(arr) / sizeof((arr)[0]))
+
+static char *expand_string_with_args(const char *in, int argc, char *argv[]);
+
+static void __attribute__((noreturn)) pperror(const char *format, ...)
+{
+	va_list ap;
+
+	fprintf(stderr, "%s:%d: ", current_file->name, yylineno);
+	va_start(ap, format);
+	vfprintf(stderr, format, ap);
+	va_end(ap);
+	fprintf(stderr, "\n");
+
+	exit(1);
+}
+
+/*
+ * Environment variables
+ */
+static LIST_HEAD(env_list);
+
+struct env {
+	char *name;
+	char *value;
+	struct list_head node;
+};
+
+static void env_add(const char *name, const char *value)
+{
+	struct env *e;
+
+	e = xmalloc(sizeof(*e));
+	e->name = xstrdup(name);
+	e->value = xstrdup(value);
+
+	list_add_tail(&e->node, &env_list);
+}
+
+static void env_del(struct env *e)
+{
+	list_del(&e->node);
+	free(e->name);
+	free(e->value);
+	free(e);
+}
+
+/* The returned pointer must be freed when done */
+static char *env_expand(const char *name)
+{
+	struct env *e;
+	const char *value;
+
+	if (!*name)
+		return NULL;
+
+	list_for_each_entry(e, &env_list, node) {
+		if (!strcmp(name, e->name))
+			return xstrdup(e->value);
+	}
+
+	value = getenv(name);
+	if (!value)
+		return NULL;
+
+	/*
+	 * We need to remember all referenced environment variables.
+	 * They will be written out to include/config/auto.conf.cmd
+	 */
+	env_add(name, value);
+
+	return xstrdup(value);
+}
+
+void env_write_dep(FILE *f, const char *autoconfig_name)
+{
+	struct env *e, *tmp;
+
+	list_for_each_entry_safe(e, tmp, &env_list, node) {
+		fprintf(f, "ifneq \"$(%s)\" \"%s\"\n", e->name, e->value);
+		fprintf(f, "%s: FORCE\n", autoconfig_name);
+		fprintf(f, "endif\n");
+		env_del(e);
+	}
+}
+
+/*
+ * Built-in functions
+ */
+struct function {
+	const char *name;
+	unsigned int min_args;
+	unsigned int max_args;
+	char *(*func)(int argc, char *argv[]);
+};
+
+static char *do_error_if(int argc, char *argv[])
+{
+	if (!strcmp(argv[0], "y"))
+		pperror("%s", argv[1]);
+
+	return NULL;
+}
+
+static char *do_filename(int argc, char *argv[])
+{
+	return xstrdup(current_file->name);
+}
+
+static char *do_info(int argc, char *argv[])
+{
+	printf("%s\n", argv[0]);
+
+	return xstrdup("");
+}
+
+static char *do_lineno(int argc, char *argv[])
+{
+	char buf[16];
+
+	sprintf(buf, "%d", yylineno);
+
+	return xstrdup(buf);
+}
+
+static char *do_shell(int argc, char *argv[])
+{
+	FILE *p;
+	char buf[256];
+	char *cmd;
+	size_t nread;
+	int i;
+
+	cmd = argv[0];
+
+	p = popen(cmd, "r");
+	if (!p) {
+		perror(cmd);
+		exit(1);
+	}
+
+	nread = fread(buf, 1, sizeof(buf), p);
+	if (nread == sizeof(buf))
+		nread--;
+
+	/* remove trailing new lines */
+	while (nread > 0 && buf[nread - 1] == '\n')
+		nread--;
+
+	buf[nread] = 0;
+
+	/* replace a new line with a space */
+	for (i = 0; i < nread; i++) {
+		if (buf[i] == '\n')
+			buf[i] = ' ';
+	}
+
+	if (pclose(p) == -1) {
+		perror(cmd);
+		exit(1);
+	}
+
+	return xstrdup(buf);
+}
+
+static char *do_warning_if(int argc, char *argv[])
+{
+	if (!strcmp(argv[0], "y"))
+		fprintf(stderr, "%s:%d: %s\n",
+			current_file->name, yylineno, argv[1]);
+
+	return xstrdup("");
+}
+
+static const struct function function_table[] = {
+	/* Name		MIN	MAX	Function */
+	{ "error-if",	2,	2,	do_error_if },
+	{ "filename",	0,	0,	do_filename },
+	{ "info",	1,	1,	do_info },
+	{ "lineno",	0,	0,	do_lineno },
+	{ "shell",	1,	1,	do_shell },
+	{ "warning-if",	2,	2,	do_warning_if },
+};
+
+#define FUNCTION_MAX_ARGS		16
+
+static char *function_expand(const char *name, int argc, char *argv[])
+{
+	const struct function *f;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(function_table); i++) {
+		f = &function_table[i];
+		if (strcmp(f->name, name))
+			continue;
+
+		if (argc < f->min_args)
+			pperror("too few function arguments passed to '%s'",
+				name);
+
+		if (argc > f->max_args)
+			pperror("too many function arguments passed to '%s'",
+				name);
+
+		return f->func(argc, argv);
+	}
+
+	return NULL;
+}
+
+/*
+ * Variables (and user-defined functions)
+ */
+static LIST_HEAD(variable_list);
+
+struct variable {
+	char *name;
+	char *value;
+	enum variable_flavor flavor;
+	int exp_count;
+	struct list_head node;
+};
+
+static struct variable *variable_lookup(const char *name)
+{
+	struct variable *v;
+
+	list_for_each_entry(v, &variable_list, node) {
+		if (!strcmp(name, v->name))
+			return v;
+	}
+
+	return NULL;
+}
+
+static char *variable_expand(const char *name, int argc, char *argv[])
+{
+	struct variable *v;
+	char *res;
+
+	v = variable_lookup(name);
+	if (!v)
+		return NULL;
+
+	if (argc == 0 && v->exp_count)
+		pperror("Recursive variable '%s' references itself (eventually)",
+			name);
+
+	if (v->exp_count > 1000)
+		pperror("Too deep recursive expansion");
+
+	v->exp_count++;
+
+	if (v->flavor == VAR_RECURSIVE)
+		res = expand_string_with_args(v->value, argc, argv);
+	else
+		res = xstrdup(v->value);
+
+	v->exp_count--;
+
+	return res;
+}
+
+void variable_add(const char *name, const char *value,
+		  enum variable_flavor flavor)
+{
+	struct variable *v;
+	char *new_value;
+	bool append = false;
+
+	v = variable_lookup(name);
+	if (v) {
+		/* For defined variables, += inherits the existing flavor */
+		if (flavor == VAR_APPEND) {
+			flavor = v->flavor;
+			append = true;
+		} else {
+			free(v->value);
+		}
+	} else {
+		/* For undefined variables, += assumes the recursive flavor */
+		if (flavor == VAR_APPEND)
+			flavor = VAR_RECURSIVE;
+
+		v = xmalloc(sizeof(*v));
+		v->name = xstrdup(name);
+		v->exp_count = 0;
+		list_add_tail(&v->node, &variable_list);
+	}
+
+	v->flavor = flavor;
+
+	if (flavor == VAR_SIMPLE)
+		new_value = expand_string(value);
+	else
+		new_value = xstrdup(value);
+
+	if (append) {
+		v->value = xrealloc(v->value,
+				    strlen(v->value) + strlen(new_value) + 2);
+		strcat(v->value, " ");
+		strcat(v->value, new_value);
+		free(new_value);
+	} else {
+		v->value = new_value;
+	}
+}
+
+static void variable_del(struct variable *v)
+{
+	list_del(&v->node);
+	free(v->name);
+	free(v->value);
+	free(v);
+}
+
+void variable_all_del(void)
+{
+	struct variable *v, *tmp;
+
+	list_for_each_entry_safe(v, tmp, &variable_list, node)
+		variable_del(v);
+}
+
+/*
+ * Evaluate a clause with arguments.  argc/argv are arguments from the upper
+ * function call.
+ *
+ * Returned string must be freed when done
+ */
+static char *eval_clause(const char *str, size_t len, int argc, char *argv[])
+{
+	char *tmp, *name, *res, *endptr, *prev, *p;
+	int new_argc = 0;
+	char *new_argv[FUNCTION_MAX_ARGS];
+	int nest = 0;
+	int i;
+	unsigned long n;
+
+	tmp = xstrndup(str, len);
+
+	/*
+	 * If variable name is '1', '2', etc.  It is generally an argument
+	 * from a user-function call (i.e. local-scope variable).  If not
+	 * available, then look-up global-scope variables.
+	 */
+	n = strtoul(tmp, &endptr, 10);
+	if (!*endptr && n > 0 && n <= argc) {
+		res = xstrdup(argv[n - 1]);
+		goto free_tmp;
+	}
+
+	prev = p = tmp;
+
+	/*
+	 * Split into tokens
+	 * The function name and arguments are separated by a comma.
+	 * For example, if the function call is like this:
+	 *   $(foo,$(x),$(y))
+	 *
+	 * The input string for this helper should be:
+	 *   foo,$(x),$(y)
+	 *
+	 * and split into:
+	 *   new_argv[0] = 'foo'
+	 *   new_argv[1] = '$(x)'
+	 *   new_argv[2] = '$(y)'
+	 */
+	while (*p) {
+		if (nest == 0 && *p == ',') {
+			*p = 0;
+			if (new_argc >= FUNCTION_MAX_ARGS)
+				pperror("too many function arguments");
+			new_argv[new_argc++] = prev;
+			prev = p + 1;
+		} else if (*p == '(') {
+			nest++;
+		} else if (*p == ')') {
+			nest--;
+		}
+
+		p++;
+	}
+	new_argv[new_argc++] = prev;
+
+	/*
+	 * Shift arguments
+	 * new_argv[0] represents a function name or a variable name.  Put it
+	 * into 'name', then shift the rest of the arguments.  This simplifies
+	 * 'const' handling.
+	 */
+	name = expand_string_with_args(new_argv[0], argc, argv);
+	new_argc--;
+	for (i = 0; i < new_argc; i++)
+		new_argv[i] = expand_string_with_args(new_argv[i + 1],
+						      argc, argv);
+
+	/* Search for variables */
+	res = variable_expand(name, new_argc, new_argv);
+	if (res)
+		goto free;
+
+	/* Look for built-in functions */
+	res = function_expand(name, new_argc, new_argv);
+	if (res)
+		goto free;
+
+	/* Last, try environment variable */
+	if (new_argc == 0) {
+		res = env_expand(name);
+		if (res)
+			goto free;
+	}
+
+	res = xstrdup("");
+free:
+	for (i = 0; i < new_argc; i++)
+		free(new_argv[i]);
+	free(name);
+free_tmp:
+	free(tmp);
+
+	return res;
+}
+
+/*
+ * Expand a string that follows '$'
+ *
+ * For example, if the input string is
+ *     ($(FOO)$($(BAR)))$(BAZ)
+ * this helper evaluates
+ *     $($(FOO)$($(BAR)))
+ * and returns a new string containing the expansion (note that the string is
+ * recursively expanded), also advancing 'str' to point to the next character
+ * after the corresponding closing parenthesis, in this case, *str will be
+ *     $(BAR)
+ */
+static char *expand_dollar_with_args(const char **str, int argc, char *argv[])
+{
+	const char *p = *str;
+	const char *q;
+	int nest = 0;
+
+	/*
+	 * In Kconfig, variable/function references always start with "$(".
+	 * Neither single-letter variables as in $A nor curly braces as in ${CC}
+	 * are supported.  '$' not followed by '(' loses its special meaning.
+	 */
+	if (*p != '(') {
+		*str = p;
+		return xstrdup("$");
+	}
+
+	p++;
+	q = p;
+	while (*q) {
+		if (*q == '(') {
+			nest++;
+		} else if (*q == ')') {
+			if (nest-- == 0)
+				break;
+		}
+		q++;
+	}
+
+	if (!*q)
+		pperror("unterminated reference to '%s': missing ')'", p);
+
+	/* Advance 'str' to after the expanded initial portion of the string */
+	*str = q + 1;
+
+	return eval_clause(p, q - p, argc, argv);
+}
+
+char *expand_dollar(const char **str)
+{
+	return expand_dollar_with_args(str, 0, NULL);
+}
+
+static char *__expand_string(const char **str, bool (*is_end)(char c),
+			     int argc, char *argv[])
+{
+	const char *in, *p;
+	char *expansion, *out;
+	size_t in_len, out_len;
+
+	out = xmalloc(1);
+	*out = 0;
+	out_len = 1;
+
+	p = in = *str;
+
+	while (1) {
+		if (*p == '$') {
+			in_len = p - in;
+			p++;
+			expansion = expand_dollar_with_args(&p, argc, argv);
+			out_len += in_len + strlen(expansion);
+			out = xrealloc(out, out_len);
+			strncat(out, in, in_len);
+			strcat(out, expansion);
+			free(expansion);
+			in = p;
+			continue;
+		}
+
+		if (is_end(*p))
+			break;
+
+		p++;
+	}
+
+	in_len = p - in;
+	out_len += in_len;
+	out = xrealloc(out, out_len);
+	strncat(out, in, in_len);
+
+	/* Advance 'str' to the end character */
+	*str = p;
+
+	return out;
+}
+
+static bool is_end_of_str(char c)
+{
+	return !c;
+}
+
+/*
+ * Expand variables and functions in the given string.  Undefined variables
+ * expand to an empty string.
+ * The returned string must be freed when done.
+ */
+static char *expand_string_with_args(const char *in, int argc, char *argv[])
+{
+	return __expand_string(&in, is_end_of_str, argc, argv);
+}
+
+char *expand_string(const char *in)
+{
+	return expand_string_with_args(in, 0, NULL);
+}
+
+static bool is_end_of_token(char c)
+{
+	/* Why are '.' and '/' valid characters for symbols? */
+	return !(isalnum(c) || c == '_' || c == '-' || c == '.' || c == '/');
+}
+
+/*
+ * Expand variables in a token.  The parsing stops when a token separater
+ * (in most cases, it is a whitespace) is encountered.  'str' is updated to
+ * point to the next character.
+ *
+ * The returned string must be freed when done.
+ */
+char *expand_one_token(const char **str)
+{
+	return __expand_string(str, is_end_of_token, 0, NULL);
+}
diff --git a/scripts/kconfig/qconf-cfg.sh b/scripts/kconfig/qconf-cfg.sh
new file mode 100755
index 0000000..0862e15
--- /dev/null
+++ b/scripts/kconfig/qconf-cfg.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+PKG="Qt5Core Qt5Gui Qt5Widgets"
+PKG2="QtCore QtGui"
+
+if pkg-config --exists $PKG; then
+	echo cflags=\"-std=c++11 -fPIC $(pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets)\"
+	echo libs=\"$(pkg-config --libs $PKG)\"
+	echo moc=\"$(pkg-config --variable=host_bins Qt5Core)/moc\"
+	exit 0
+fi
+
+if pkg-config --exists $PKG2; then
+	echo cflags=\"$(pkg-config --cflags $PKG2)\"
+	echo libs=\"$(pkg-config --libs $PKG2)\"
+	echo moc=\"$(pkg-config --variable=moc_location QtCore)\"
+	exit 0
+fi
+
+echo >&2 "*"
+echo >&2 "* Could not find Qt via pkg-config."
+echo >&2 "* Please install either Qt 4.8 or 5.x. and make sure it's in PKG_CONFIG_PATH"
+echo >&2 "*"
+exit 1
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index ae6c725..ad9c22d 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -34,10 +34,6 @@
 #include "qconf.moc"
 #include "images.c"
 
-#ifdef _
-# undef _
-# define _ qgettext
-#endif
 
 static QApplication *configApp;
 static ConfigSettings *configSettings;
@@ -46,12 +42,7 @@
 
 static inline QString qgettext(const char* str)
 {
-	return QString::fromLocal8Bit(gettext(str));
-}
-
-static inline QString qgettext(const QString& str)
-{
-	return QString::fromLocal8Bit(gettext(str.toLatin1()));
+	return QString::fromLocal8Bit(str);
 }
 
 ConfigSettings::ConfigSettings()
@@ -127,7 +118,7 @@
 
 	sym = menu->sym;
 	prop = menu->prompt;
-	prompt = _(menu_get_prompt(menu));
+	prompt = qgettext(menu_get_prompt(menu));
 
 	if (prop) switch (prop->type) {
 	case P_MENU:
@@ -216,7 +207,7 @@
 		break;
 	}
 	if (!sym_has_value(sym) && visible)
-		prompt += _(" (NEW)");
+		prompt += " (NEW)";
 set_prompt:
 	setText(promptColIdx, prompt);
 }
@@ -327,7 +318,7 @@
 	setVerticalScrollMode(ScrollPerPixel);
 	setHorizontalScrollMode(ScrollPerPixel);
 
-	setHeaderLabels(QStringList() << _("Option") << _("Name") << "N" << "M" << "Y" << _("Value"));
+	setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value");
 
 	connect(this, SIGNAL(itemSelectionChanged(void)),
 		SLOT(updateSelection(void)));
@@ -883,7 +874,7 @@
 			QAction *action;
 
 			headerPopup = new QMenu(this);
-			action = new QAction(_("Show Name"), this);
+			action = new QAction("Show Name", this);
 			  action->setCheckable(true);
 			  connect(action, SIGNAL(toggled(bool)),
 				  parent(), SLOT(setShowName(bool)));
@@ -891,7 +882,7 @@
 				  action, SLOT(setOn(bool)));
 			  action->setChecked(showName);
 			  headerPopup->addAction(action);
-			action = new QAction(_("Show Range"), this);
+			action = new QAction("Show Range", this);
 			  action->setCheckable(true);
 			  connect(action, SIGNAL(toggled(bool)),
 				  parent(), SLOT(setShowRange(bool)));
@@ -899,7 +890,7 @@
 				  action, SLOT(setOn(bool)));
 			  action->setChecked(showRange);
 			  headerPopup->addAction(action);
-			action = new QAction(_("Show Data"), this);
+			action = new QAction("Show Data", this);
 			  action->setCheckable(true);
 			  connect(action, SIGNAL(toggled(bool)),
 				  parent(), SLOT(setShowData(bool)));
@@ -1086,7 +1077,7 @@
 	if (sym) {
 		if (_menu->prompt) {
 			head += "<big><b>";
-			head += print_filter(_(_menu->prompt->text));
+			head += print_filter(_menu->prompt->text);
 			head += "</b></big>";
 			if (sym->name) {
 				head += " (";
@@ -1117,7 +1108,7 @@
 		str_free(&help_gstr);
 	} else if (_menu->prompt) {
 		head += "<big><b>";
-		head += print_filter(_(_menu->prompt->text));
+		head += print_filter(_menu->prompt->text);
 		head += "</b></big><br><br>";
 		if (showDebug()) {
 			if (_menu->prompt->visible.expr) {
@@ -1152,7 +1143,7 @@
 		case P_PROMPT:
 		case P_MENU:
 			debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
-			debug += print_filter(_(prop->text));
+			debug += print_filter(prop->text);
 			debug += "</a><br>";
 			break;
 		case P_DEFAULT:
@@ -1234,7 +1225,7 @@
 QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
 {
 	QMenu* popup = Parent::createStandardContextMenu(pos);
-	QAction* action = new QAction(_("Show Debug Info"), popup);
+	QAction* action = new QAction("Show Debug Info", popup);
 	  action->setCheckable(true);
 	  connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
 	  connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
@@ -1261,11 +1252,11 @@
 	QHBoxLayout* layout2 = new QHBoxLayout(0);
 	layout2->setContentsMargins(0, 0, 0, 0);
 	layout2->setSpacing(6);
-	layout2->addWidget(new QLabel(_("Find:"), this));
+	layout2->addWidget(new QLabel("Find:", this));
 	editField = new QLineEdit(this);
 	connect(editField, SIGNAL(returnPressed()), SLOT(search()));
 	layout2->addWidget(editField);
-	searchButton = new QPushButton(_("Search"), this);
+	searchButton = new QPushButton("Search", this);
 	searchButton->setAutoDefault(false);
 	connect(searchButton, SIGNAL(clicked()), SLOT(search()));
 	layout2->addWidget(searchButton);
@@ -1387,44 +1378,44 @@
 	toolBar = new QToolBar("Tools", this);
 	addToolBar(toolBar);
 
-	backAction = new QAction(QPixmap(xpm_back), _("Back"), this);
+	backAction = new QAction(QPixmap(xpm_back), "Back", this);
 	  connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
 	  backAction->setEnabled(false);
-	QAction *quitAction = new QAction(_("&Quit"), this);
+	QAction *quitAction = new QAction("&Quit", this);
 	quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
 	  connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
-	QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this);
+	QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
 	loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
 	  connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
-	saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this);
+	saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
 	saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
 	  connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
 	conf_set_changed_callback(conf_changed);
 	// Set saveAction's initial state
 	conf_changed();
-	QAction *saveAsAction = new QAction(_("Save &As..."), this);
+	QAction *saveAsAction = new QAction("Save &As...", this);
 	  connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
-	QAction *searchAction = new QAction(_("&Find"), this);
+	QAction *searchAction = new QAction("&Find", this);
 	searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
 	  connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
-	singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this);
+	singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
 	singleViewAction->setCheckable(true);
 	  connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
-	splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this);
+	splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);
 	splitViewAction->setCheckable(true);
 	  connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
-	fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this);
+	fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);
 	fullViewAction->setCheckable(true);
 	  connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
 
-	QAction *showNameAction = new QAction(_("Show Name"), this);
+	QAction *showNameAction = new QAction("Show Name", this);
 	  showNameAction->setCheckable(true);
 	  connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
 	  showNameAction->setChecked(configView->showName());
-	QAction *showRangeAction = new QAction(_("Show Range"), this);
+	QAction *showRangeAction = new QAction("Show Range", this);
 	  showRangeAction->setCheckable(true);
 	  connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
-	QAction *showDataAction = new QAction(_("Show Data"), this);
+	QAction *showDataAction = new QAction("Show Data", this);
 	  showDataAction->setCheckable(true);
 	  connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
 
@@ -1435,21 +1426,21 @@
 	connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
 		SLOT(setOptionMode(QAction *)));
 
-	configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
-	configView->showAllAction = new QAction(_("Show All Options"), optGroup);
-	configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
+	configView->showNormalAction = new QAction("Show Normal Options", optGroup);
+	configView->showAllAction = new QAction("Show All Options", optGroup);
+	configView->showPromptAction = new QAction("Show Prompt Options", optGroup);
 	configView->showNormalAction->setCheckable(true);
 	configView->showAllAction->setCheckable(true);
 	configView->showPromptAction->setCheckable(true);
 
-	QAction *showDebugAction = new QAction( _("Show Debug Info"), this);
+	QAction *showDebugAction = new QAction("Show Debug Info", this);
 	  showDebugAction->setCheckable(true);
 	  connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
 	  showDebugAction->setChecked(helpText->showDebug());
 
-	QAction *showIntroAction = new QAction( _("Introduction"), this);
+	QAction *showIntroAction = new QAction("Introduction", this);
 	  connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
-	QAction *showAboutAction = new QAction( _("About"), this);
+	QAction *showAboutAction = new QAction("About", this);
 	  connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
 
 	// init tool bar
@@ -1463,7 +1454,7 @@
 	toolBar->addAction(fullViewAction);
 
 	// create config menu
-	QMenu* config = menu->addMenu(_("&File"));
+	QMenu* config = menu->addMenu("&File");
 	config->addAction(loadAction);
 	config->addAction(saveAction);
 	config->addAction(saveAsAction);
@@ -1471,11 +1462,11 @@
 	config->addAction(quitAction);
 
 	// create edit menu
-	QMenu* editMenu = menu->addMenu(_("&Edit"));
+	QMenu* editMenu = menu->addMenu("&Edit");
 	editMenu->addAction(searchAction);
 
 	// create options menu
-	QMenu* optionMenu = menu->addMenu(_("&Option"));
+	QMenu* optionMenu = menu->addMenu("&Option");
 	optionMenu->addAction(showNameAction);
 	optionMenu->addAction(showRangeAction);
 	optionMenu->addAction(showDataAction);
@@ -1486,7 +1477,7 @@
 
 	// create help menu
 	menu->addSeparator();
-	QMenu* helpMenu = menu->addMenu(_("&Help"));
+	QMenu* helpMenu = menu->addMenu("&Help");
 	helpMenu->addAction(showIntroAction);
 	helpMenu->addAction(showAboutAction);
 
@@ -1534,14 +1525,14 @@
 	if (s.isNull())
 		return;
 	if (conf_read(QFile::encodeName(s)))
-		QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
+		QMessageBox::information(this, "qconf", "Unable to load configuration!");
 	ConfigView::updateListAll();
 }
 
 bool ConfigMainWindow::saveConfig(void)
 {
 	if (conf_write(NULL)) {
-		QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
+		QMessageBox::information(this, "qconf", "Unable to save configuration!");
 		return false;
 	}
 	return true;
@@ -1723,11 +1714,11 @@
 		e->accept();
 		return;
 	}
-	QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
+	QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
 			QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
-	mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
-	mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
-	mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
+	mb.setButtonText(QMessageBox::Yes, "&Save Changes");
+	mb.setButtonText(QMessageBox::No, "&Discard Changes");
+	mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
 	switch (mb.exec()) {
 	case QMessageBox::Yes:
 		if (saveConfig())
@@ -1746,7 +1737,7 @@
 
 void ConfigMainWindow::showIntro(void)
 {
-	static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
+	static const QString str = "Welcome to the qconf graphical configuration tool.\n\n"
 		"For each option, a blank box indicates the feature is disabled, a check\n"
 		"indicates it is enabled, and a dot indicates that it is to be compiled\n"
 		"as a module.  Clicking on the box will cycle through the three states.\n\n"
@@ -1756,16 +1747,16 @@
 		"options must be enabled to support the option you are interested in, you can\n"
 		"still view the help of a grayed-out option.\n\n"
 		"Toggling Show Debug Info under the Options menu will show the dependencies,\n"
-		"which you can then match by examining other options.\n\n");
+		"which you can then match by examining other options.\n\n";
 
 	QMessageBox::information(this, "qconf", str);
 }
 
 void ConfigMainWindow::showAbout(void)
 {
-	static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
+	static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
 		"Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
-		"Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
+		"Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
 
 	QMessageBox::information(this, "qconf", str);
 }
@@ -1826,7 +1817,7 @@
 
 static void usage(void)
 {
-	printf(_("%s [-s] <config>\n").toLatin1().constData(), progname);
+	printf("%s [-s] <config>\n", progname);
 	exit(0);
 }
 
@@ -1835,9 +1826,6 @@
 	ConfigMainWindow* v;
 	const char *name;
 
-	bindtextdomain(PACKAGE, LOCALEDIR);
-	textdomain(PACKAGE);
-
 	progname = av[0];
 	configApp = new QApplication(ac, av);
 	if (ac > 1 && av[1][0] == '-') {
diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl
index a2e83ab..4686531 100755
--- a/scripts/kconfig/streamline_config.pl
+++ b/scripts/kconfig/streamline_config.pl
@@ -165,10 +165,10 @@
     my $last_source = "";
 
     # Check for any environment variables used
-    while ($source =~ /\$(\w+)/ && $last_source ne $source) {
+    while ($source =~ /\$\((\w+)\)/ && $last_source ne $source) {
 	my $env = $1;
 	$last_source = $source;
-	$source =~ s/\$$env/$ENV{$env}/;
+	$source =~ s/\$\($env\)/$ENV{$env}/;
     }
 
     open(my $kinfile, '<', $source) || die "Can't open $kconfig";
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index f0b2e3b..7c9a88e 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -33,33 +33,6 @@
 struct symbol *modules_sym;
 tristate modules_val;
 
-struct expr *sym_env_list;
-
-static void sym_add_default(struct symbol *sym, const char *def)
-{
-	struct property *prop = prop_alloc(P_DEFAULT, sym);
-
-	prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST));
-}
-
-void sym_init(void)
-{
-	struct symbol *sym;
-	struct utsname uts;
-	static bool inited = false;
-
-	if (inited)
-		return;
-	inited = true;
-
-	uname(&uts);
-
-	sym = sym_lookup("UNAME_RELEASE", 0);
-	sym->type = S_STRING;
-	sym->flags |= SYMBOL_AUTO;
-	sym_add_default(sym, uts.release);
-}
-
 enum symbol_type sym_get_type(struct symbol *sym)
 {
 	enum symbol_type type = sym->type;
@@ -906,59 +879,6 @@
 	return symbol;
 }
 
-/*
- * Expand symbol's names embedded in the string given in argument. Symbols'
- * name to be expanded shall be prefixed by a '$'. Unknown symbol expands to
- * the empty string.
- */
-char *sym_expand_string_value(const char *in)
-{
-	const char *src;
-	char *res;
-	size_t reslen;
-
-	/*
-	 * Note: 'in' might come from a token that's about to be
-	 * freed, so make sure to always allocate a new string
-	 */
-	reslen = strlen(in) + 1;
-	res = xmalloc(reslen);
-	res[0] = '\0';
-
-	while ((src = strchr(in, '$'))) {
-		char *p, name[SYMBOL_MAXLENGTH];
-		const char *symval = "";
-		struct symbol *sym;
-		size_t newlen;
-
-		strncat(res, in, src - in);
-		src++;
-
-		p = name;
-		while (isalnum(*src) || *src == '_')
-			*p++ = *src++;
-		*p = '\0';
-
-		sym = sym_find(name);
-		if (sym != NULL) {
-			sym_calc_value(sym);
-			symval = sym_get_string_value(sym);
-		}
-
-		newlen = strlen(res) + strlen(symval) + strlen(src) + 1;
-		if (newlen > reslen) {
-			reslen = newlen;
-			res = xrealloc(res, reslen);
-		}
-
-		strcat(res, symval);
-		in = src;
-	}
-	strcat(res, in);
-
-	return res;
-}
-
 const char *sym_escape_string_value(const char *in)
 {
 	const char *p;
@@ -1401,32 +1321,3 @@
 	}
 	return "unknown";
 }
-
-static void prop_add_env(const char *env)
-{
-	struct symbol *sym, *sym2;
-	struct property *prop;
-	char *p;
-
-	sym = current_entry->sym;
-	sym->flags |= SYMBOL_AUTO;
-	for_all_properties(sym, prop, P_ENV) {
-		sym2 = prop_get_symbol(prop);
-		if (strcmp(sym2->name, env))
-			menu_warn(current_entry, "redefining environment symbol from %s",
-				  sym2->name);
-		return;
-	}
-
-	prop = prop_alloc(P_ENV, sym);
-	prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST));
-
-	sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
-	sym_env_list->right.sym = sym;
-
-	p = getenv(env);
-	if (p)
-		sym_add_default(sym, p);
-	else
-		menu_warn(current_entry, "environment variable %s undefined", env);
-}
diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config b/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config
index 0d15e41..4732288 100644
--- a/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config
+++ b/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config
@@ -1,5 +1,5 @@
 #
 # Automatically generated file; DO NOT EDIT.
-# Linux Kernel Configuration
+# Main menu
 #
 # CONFIG_A is not set
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
index c6f6e21..a365594 100644
--- a/scripts/kconfig/util.c
+++ b/scripts/kconfig/util.c
@@ -14,18 +14,16 @@
 struct file *file_lookup(const char *name)
 {
 	struct file *file;
-	char *file_name = sym_expand_string_value(name);
 
 	for (file = file_list; file; file = file->next) {
 		if (!strcmp(name, file->name)) {
-			free(file_name);
 			return file;
 		}
 	}
 
 	file = xmalloc(sizeof(*file));
 	memset(file, 0, sizeof(*file));
-	file->name = file_name;
+	file->name = xstrdup(name);
 	file->next = file_list;
 	file_list = file;
 	return file;
@@ -34,8 +32,6 @@
 /* write a dependency file as used by kbuild to track dependencies */
 int file_write_dep(const char *name)
 {
-	struct symbol *sym, *env_sym;
-	struct expr *e;
 	struct file *file;
 	FILE *out;
 
@@ -54,21 +50,7 @@
 	fprintf(out, "\n%s: \\\n"
 		     "\t$(deps_config)\n\n", conf_get_autoconfig_name());
 
-	expr_list_for_each_sym(sym_env_list, e, sym) {
-		struct property *prop;
-		const char *value;
-
-		prop = sym_get_env_prop(sym);
-		env_sym = prop_get_symbol(prop);
-		if (!env_sym)
-			continue;
-		value = getenv(env_sym->name);
-		if (!value)
-			value = "";
-		fprintf(out, "ifneq \"$(%s)\" \"%s\"\n", env_sym->name, value);
-		fprintf(out, "%s: FORCE\n", conf_get_autoconfig_name());
-		fprintf(out, "endif\n");
-	}
+	env_write_dep(out, conf_get_autoconfig_name());
 
 	fprintf(out, "\n$(deps_config): ;\n");
 	fclose(out);
@@ -165,3 +147,14 @@
 	fprintf(stderr, "Out of memory.\n");
 	exit(1);
 }
+
+char *xstrndup(const char *s, size_t n)
+{
+	char *p;
+
+	p = strndup(s, n);
+	if (p)
+		return p;
+	fprintf(stderr, "Out of memory.\n");
+	exit(1);
+}
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l
index 045093d..25bd2b8 100644
--- a/scripts/kconfig/zconf.l
+++ b/scripts/kconfig/zconf.l
@@ -1,13 +1,13 @@
 %option nostdinit noyywrap never-interactive full ecs
 %option 8bit nodefault yylineno
-%option noinput
-%x COMMAND HELP STRING PARAM
+%x COMMAND HELP STRING PARAM ASSIGN_VAL
 %{
 /*
  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
  * Released under the terms of the GNU GPL v2.0.
  */
 
+#include <assert.h>
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -35,6 +35,8 @@
 
 static int last_ts, first_ts;
 
+static char *expand_token(const char *in, size_t n);
+static void append_expanded_string(const char *in);
 static void zconf_endhelp(void);
 static void zconf_endfile(void);
 
@@ -101,17 +103,28 @@
 <COMMAND>{
 	{n}+	{
 		const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
-		BEGIN(PARAM);
 		current_pos.file = current_file;
 		current_pos.lineno = yylineno;
 		if (id && id->flags & TF_COMMAND) {
+			BEGIN(PARAM);
 			yylval.id = id;
 			return id->token;
 		}
 		alloc_string(yytext, yyleng);
 		yylval.string = text;
-		return T_WORD;
+		return T_VARIABLE;
 	}
+	({n}|$)+	{
+		/* this token includes at least one '$' */
+		yylval.string = expand_token(yytext, yyleng);
+		if (strlen(yylval.string))
+			return T_VARIABLE;
+		free(yylval.string);
+	}
+	"="	{ BEGIN(ASSIGN_VAL); yylval.flavor = VAR_RECURSIVE; return T_ASSIGN; }
+	":="	{ BEGIN(ASSIGN_VAL); yylval.flavor = VAR_SIMPLE; return T_ASSIGN; }
+	"+="	{ BEGIN(ASSIGN_VAL); yylval.flavor = VAR_APPEND; return T_ASSIGN; }
+	[[:blank:]]+
 	.	warn_ignored_character(*yytext);
 	\n	{
 		BEGIN(INITIAL);
@@ -119,6 +132,16 @@
 	}
 }
 
+<ASSIGN_VAL>{
+	[^[:blank:]\n]+.*	{
+		alloc_string(yytext, yyleng);
+		yylval.string = text;
+		return T_ASSIGN_VAL;
+	}
+	\n	{ BEGIN(INITIAL); return T_EOL; }
+	.
+}
+
 <PARAM>{
 	"&&"	return T_AND;
 	"||"	return T_OR;
@@ -147,6 +170,13 @@
 		yylval.string = text;
 		return T_WORD;
 	}
+	({n}|[/.$])+	{
+		/* this token includes at least one '$' */
+		yylval.string = expand_token(yytext, yyleng);
+		if (strlen(yylval.string))
+			return T_WORD;
+		free(yylval.string);
+	}
 	#.*	/* comment */
 	\\\n	;
 	[[:blank:]]+
@@ -157,12 +187,13 @@
 }
 
 <STRING>{
-	[^'"\\\n]+/\n	{
+	"$".*	append_expanded_string(yytext);
+	[^$'"\\\n]+/\n	{
 		append_string(yytext, yyleng);
 		yylval.string = text;
 		return T_WORD_QUOTE;
 	}
-	[^'"\\\n]+	{
+	[^$'"\\\n]+	{
 		append_string(yytext, yyleng);
 	}
 	\\.?/\n	{
@@ -249,6 +280,58 @@
 }
 
 %%
+static char *expand_token(const char *in, size_t n)
+{
+	char *out;
+	int c;
+	char c2;
+	const char *rest, *end;
+
+	new_string();
+	append_string(in, n);
+
+	/* get the whole line because we do not know the end of token. */
+	while ((c = input()) != EOF) {
+		if (c == '\n') {
+			unput(c);
+			break;
+		}
+		c2 = c;
+		append_string(&c2, 1);
+	}
+
+	rest = text;
+	out = expand_one_token(&rest);
+
+	/* push back unused characters to the input stream */
+	end = rest + strlen(rest);
+	while (end > rest)
+		unput(*--end);
+
+	free(text);
+
+	return out;
+}
+
+static void append_expanded_string(const char *str)
+{
+	const char *end;
+	char *res;
+
+	str++;
+
+	res = expand_dollar(&str);
+
+	/* push back unused characters to the input stream */
+	end = str + strlen(str);
+	while (end > str)
+		unput(*--end);
+
+	append_string(res, strlen(res));
+
+	free(res);
+}
+
 void zconf_starthelp(void)
 {
 	new_string();
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index ad6305b..4b68272 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -31,7 +31,7 @@
 static struct menu *current_menu, *current_entry;
 
 %}
-%expect 32
+%expect 31
 
 %union
 {
@@ -41,6 +41,7 @@
 	struct expr *expr;
 	struct menu *menu;
 	const struct kconf_id *id;
+	enum variable_flavor flavor;
 }
 
 %token <id>T_MAINMENU
@@ -77,6 +78,9 @@
 %token T_CLOSE_PAREN
 %token T_OPEN_PAREN
 %token T_EOL
+%token <string> T_VARIABLE
+%token <flavor> T_ASSIGN
+%token <string> T_ASSIGN_VAL
 
 %left T_OR
 %left T_AND
@@ -92,7 +96,7 @@
 %type <id> end
 %type <id> option_name
 %type <menu> if_entry menu_entry choice_entry
-%type <string> symbol_option_arg word_opt
+%type <string> symbol_option_arg word_opt assign_val
 
 %destructor {
 	fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -109,7 +113,7 @@
 %%
 input: nl start | start;
 
-start: mainmenu_stmt stmt_list | no_mainmenu_stmt stmt_list;
+start: mainmenu_stmt stmt_list | stmt_list;
 
 /* mainmenu entry */
 
@@ -118,19 +122,6 @@
 	menu_add_prompt(P_MENU, $2, NULL);
 };
 
-/* Default main menu, if there's no mainmenu entry */
-
-no_mainmenu_stmt: /* empty */
-{
-	/*
-	 * Hack: Keep the main menu title on the heap so we can safely free it
-	 * later regardless of whether it comes from the 'prompt' in
-	 * mainmenu_stmt or here
-	 */
-	menu_add_prompt(P_MENU, xstrdup("Linux Kernel Configuration"), NULL);
-};
-
-
 stmt_list:
 	  /* empty */
 	| stmt_list common_stmt
@@ -156,6 +147,7 @@
 	| config_stmt
 	| menuconfig_stmt
 	| source_stmt
+	| assignment_stmt
 ;
 
 option_error:
@@ -345,7 +337,7 @@
 
 /* if entry */
 
-if_entry: T_IF expr nl
+if_entry: T_IF expr T_EOL
 {
 	printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
 	menu_add_entry(NULL);
@@ -524,31 +516,42 @@
 word_opt: /* empty */			{ $$ = NULL; }
 	| T_WORD
 
+/* assignment statement */
+
+assignment_stmt:  T_VARIABLE T_ASSIGN assign_val T_EOL	{ variable_add($1, $3, $2); free($1); free($3); }
+
+assign_val:
+	/* empty */		{ $$ = xstrdup(""); };
+	| T_ASSIGN_VAL
+;
+
 %%
 
 void conf_parse(const char *name)
 {
-	const char *tmp;
 	struct symbol *sym;
 	int i;
 
 	zconf_initscan(name);
 
-	sym_init();
 	_menu_init();
 
 	if (getenv("ZCONF_DEBUG"))
 		yydebug = 1;
 	yyparse();
+
+	/* Variables are expanded in the parse phase. We can free them here. */
+	variable_all_del();
+
 	if (yynerrs)
 		exit(1);
 	if (!modules_sym)
 		modules_sym = sym_find( "n" );
 
-	tmp = rootmenu.prompt->text;
-	rootmenu.prompt->text = _(rootmenu.prompt->text);
-	rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text);
-	free((char*)tmp);
+	if (!menu_has_prompt(&rootmenu)) {
+		current_entry = &rootmenu;
+		menu_add_prompt(P_MENU, "Main menu", NULL);
+	}
 
 	menu_finalize(&rootmenu);
 	for_all_symbols(i, sym) {
@@ -714,6 +717,10 @@
 			print_quoted_string(out, prop->text);
 			fputc('\n', out);
 			break;
+		case P_SYMBOL:
+			fputs( "  symbol ", out);
+			fprintf(out, "%s\n", prop->sym->name);
+			break;
 		default:
 			fprintf(out, "  unknown prop %d!\n", prop->type);
 			break;
@@ -780,3 +787,4 @@
 #include "expr.c"
 #include "symbol.c"
 #include "menu.c"
+#include "preprocess.c"
diff --git a/test/Kconfig b/test/Kconfig
index cb51b46..0157e0b 100644
--- a/test/Kconfig
+++ b/test/Kconfig
@@ -28,6 +28,16 @@
 	  Enables a test which exercises asn1 compiler and decoder function
 	  via various parsers.
 
+config UT_LIB_RSA
+	bool "Unit test for rsa_verify() function"
+	depends on RSA
+	depends on RSA_VERIFY_WITH_PKEY
+	select IMAGE_SIGN_INFO
+	default y
+	help
+	  Enables rsa_verify() test, currently rsa_verify_with_pkey only()
+	  only, at the 'ut lib' command.
+
 endif
 
 config UT_TIME
diff --git a/test/lib/Makefile b/test/lib/Makefile
index 230068d..ce9ae4a 100644
--- a/test/lib/Makefile
+++ b/test/lib/Makefile
@@ -8,4 +8,5 @@
 obj-y += string.o
 obj-$(CONFIG_ERRNO_STR) += test_errno_str.o
 obj-$(CONFIG_UT_LIB_ASN1) += asn1.o
+obj-$(CONFIG_UT_LIB_RSA) += rsa.o
 obj-$(CONFIG_AES) += test_aes.o
diff --git a/test/lib/rsa.c b/test/lib/rsa.c
new file mode 100644
index 0000000..44f8ade
--- /dev/null
+++ b/test/lib/rsa.c
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019 Linaro Limited
+ * Author: AKASHI Takahiro
+ *
+ * Unit test for rsa_verify() function
+ */
+
+#include <common.h>
+#include <command.h>
+#include <image.h>
+#include <test/lib.h>
+#include <test/test.h>
+#include <test/ut.h>
+#include <u-boot/rsa.h>
+
+#ifdef CONFIG_RSA_VERIFY_WITH_PKEY
+/*
+ * openssl genrsa 2048 -out private.pem
+ * openssl rsa -in private.pem -pubout -outform der -out public.der
+ * dd if=public.der of=public.raw bs=24 skip=1
+ */
+static unsigned char public_key[] = {
+	0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xca, 0x25, 0x23,
+	0xe0, 0x0a, 0x4d, 0x8f, 0x56, 0xfc, 0xc9, 0x06, 0x4c, 0xcc, 0x94, 0x43,
+	0xe0, 0x56, 0x44, 0x6e, 0x37, 0x54, 0x87, 0x12, 0x84, 0xf9, 0x07, 0x4f,
+	0xe4, 0x23, 0x40, 0xc3, 0x43, 0x84, 0x37, 0x86, 0xd3, 0x9d, 0x95, 0x1c,
+	0xe4, 0x8a, 0x66, 0x02, 0x09, 0xe2, 0x3d, 0xce, 0x2c, 0xc6, 0x02, 0x6a,
+	0xd4, 0x65, 0x61, 0xff, 0x85, 0x6f, 0x88, 0x63, 0xba, 0x31, 0x62, 0x1e,
+	0xb7, 0x95, 0xe9, 0x08, 0x3c, 0xe9, 0x35, 0xde, 0xfd, 0x65, 0x92, 0xb8,
+	0x9e, 0x71, 0xa4, 0xcd, 0x47, 0xfd, 0x04, 0x26, 0xb9, 0x78, 0xbf, 0x05,
+	0x0d, 0xfc, 0x00, 0x84, 0x08, 0xfc, 0xc4, 0x4b, 0xea, 0xf5, 0x97, 0x68,
+	0x0d, 0x97, 0xd7, 0xff, 0x4f, 0x92, 0x82, 0xd7, 0xbb, 0xef, 0xb7, 0x67,
+	0x8e, 0x72, 0x54, 0xe8, 0xc5, 0x9e, 0xfd, 0xd8, 0x38, 0xe9, 0xbe, 0x19,
+	0x37, 0x5b, 0x36, 0x8b, 0xbf, 0x49, 0xa1, 0x59, 0x3a, 0x9d, 0xad, 0x92,
+	0x08, 0x0b, 0xe3, 0xa4, 0xa4, 0x7d, 0xd3, 0x70, 0xc0, 0xb8, 0xfb, 0xc7,
+	0xda, 0xd3, 0x19, 0x86, 0x37, 0x9a, 0xcd, 0xab, 0x30, 0x96, 0xab, 0xa4,
+	0xa2, 0x31, 0xa0, 0x38, 0xfb, 0xbf, 0x85, 0xd3, 0x24, 0x39, 0xed, 0xbf,
+	0xe1, 0x31, 0xed, 0x6c, 0x39, 0xc1, 0xe5, 0x05, 0x2e, 0x12, 0x30, 0x36,
+	0x73, 0x5d, 0x62, 0xf3, 0x82, 0xaf, 0x38, 0xc8, 0xca, 0xfa, 0xa1, 0x99,
+	0x57, 0x3c, 0xe1, 0xc1, 0x7b, 0x05, 0x0b, 0xcc, 0x2e, 0xa9, 0x10, 0xc8,
+	0x68, 0xbd, 0x27, 0xb6, 0x19, 0x9c, 0xd2, 0xad, 0xb3, 0x1f, 0xca, 0x35,
+	0x6e, 0x84, 0x23, 0xa1, 0xe9, 0xa4, 0x4c, 0xab, 0x19, 0x09, 0x79, 0x6e,
+	0x3c, 0x7b, 0x74, 0xfc, 0x33, 0x05, 0xcf, 0xa4, 0x2e, 0xeb, 0x55, 0x60,
+	0x05, 0xc7, 0xcf, 0x3f, 0x92, 0xac, 0x2d, 0x69, 0x0b, 0x19, 0x16, 0x79,
+	0x75, 0x02, 0x03, 0x01, 0x00, 0x01
+};
+
+static unsigned int public_key_len = 270;
+
+/*
+ * dd if=/dev/urandom of=data.raw bs=512 count=1
+ */
+static unsigned char data_raw[] = {
+	0x3e, 0x48, 0x6e, 0xef, 0x83, 0xd1, 0x4c, 0xfd, 0x92, 0x47, 0x92, 0xd7,
+	0xf6, 0x16, 0x25, 0x0a, 0xdf, 0xe2, 0xb6, 0x6c, 0xe7, 0xe0, 0x55, 0xb2,
+	0x70, 0x66, 0xf0, 0xe5, 0xdc, 0xaf, 0xd3, 0x2e, 0xc1, 0x3e, 0x5c, 0x4b,
+	0xb5, 0xa7, 0x23, 0x1f, 0x2c, 0xce, 0xf8, 0x83, 0x00, 0x6d, 0xeb, 0xdd,
+	0x19, 0x71, 0x13, 0xb4, 0xae, 0x5c, 0xa8, 0xae, 0x52, 0xc8, 0xe1, 0x77,
+	0x9e, 0x98, 0x75, 0xbc, 0xef, 0x36, 0x9f, 0x0c, 0x14, 0xed, 0x1a, 0x0a,
+	0x4f, 0x6c, 0xa4, 0xb1, 0xbb, 0x0e, 0x43, 0x93, 0x12, 0xfc, 0x2e, 0x82,
+	0x93, 0x4e, 0xcb, 0xa2, 0xcd, 0x59, 0x3f, 0xc5, 0x11, 0x38, 0x3a, 0x88,
+	0xc3, 0xcf, 0xf9, 0x61, 0xa8, 0x9e, 0x96, 0xb6, 0xbf, 0xa6, 0x5b, 0x0d,
+	0xd9, 0xbd, 0x05, 0x4c, 0xbe, 0xed, 0x86, 0xca, 0x10, 0x63, 0x72, 0x75,
+	0x4b, 0xbd, 0x86, 0x42, 0x30, 0x9d, 0x54, 0x4e, 0x12, 0xda, 0xf4, 0xb4,
+	0xfd, 0xd9, 0x54, 0x95, 0x8f, 0x83, 0xc2, 0x63, 0x44, 0xdd, 0x96, 0x1a,
+	0xd0, 0x7c, 0xcf, 0xcb, 0x16, 0xd6, 0xff, 0xa3, 0xbb, 0xeb, 0x24, 0x06,
+	0xbf, 0x81, 0xd0, 0x29, 0x76, 0x19, 0x66, 0x84, 0xfc, 0x49, 0xde, 0x7b,
+	0x5d, 0xd2, 0x27, 0x58, 0x21, 0x7b, 0xff, 0x4d, 0x64, 0xf3, 0x89, 0xe3,
+	0xea, 0xb6, 0x54, 0x4e, 0xb1, 0x62, 0x52, 0x89, 0xe3, 0x22, 0xf2, 0x26,
+	0x3e, 0x4f, 0x43, 0x58, 0x78, 0x91, 0x55, 0xbc, 0x1e, 0xd6, 0x97, 0xfc,
+	0x0b, 0x85, 0x4c, 0x92, 0x9c, 0xbf, 0xc4, 0xb1, 0x62, 0x93, 0x27, 0xa9,
+	0xb2, 0xf4, 0xb4, 0x7a, 0xfb, 0x56, 0xe5, 0x8f, 0xe1, 0x94, 0x4d, 0xfd,
+	0xe4, 0x72, 0x8d, 0xa9, 0x71, 0x65, 0xcb, 0x2e, 0x6d, 0x39, 0xd5, 0x95,
+	0xe7, 0x3f, 0xab, 0xaa, 0x7a, 0x74, 0x84, 0x25, 0x4b, 0x42, 0x1e, 0xd3,
+	0x86, 0xca, 0x47, 0x4a, 0xf0, 0x24, 0x81, 0x24, 0xb0, 0xe1, 0xbb, 0x6c,
+	0x3f, 0x2a, 0xa0, 0xb8, 0xeb, 0xd6, 0x01, 0xce, 0x63, 0x51, 0xe1, 0x81,
+	0xd2, 0x32, 0x43, 0x56, 0x44, 0x4a, 0x6b, 0x51, 0x24, 0xa2, 0xc7, 0x39,
+	0x7c, 0x54, 0xda, 0xf8, 0xd4, 0x93, 0x7c, 0x8e, 0x4e, 0x9d, 0x15, 0x08,
+	0xce, 0x27, 0xd8, 0x28, 0xb0, 0x5b, 0x75, 0x32, 0x43, 0xe8, 0xd6, 0xbf,
+	0x12, 0xd5, 0xc5, 0x12, 0x8e, 0xeb, 0x77, 0x8f, 0x00, 0xde, 0x45, 0x1e,
+	0xdd, 0xf3, 0xef, 0x43, 0x99, 0x79, 0x86, 0xea, 0x01, 0xce, 0xf2, 0x4d,
+	0xa0, 0xfe, 0x5a, 0x55, 0xc0, 0x1f, 0xce, 0xe8, 0xbe, 0xc2, 0x66, 0xdb,
+	0xcb, 0x3f, 0xa5, 0x48, 0xa1, 0xe2, 0x49, 0xa1, 0x29, 0x65, 0x5b, 0x62,
+	0x39, 0xcc, 0xef, 0xbe, 0x86, 0xb7, 0xe3, 0x44, 0x67, 0x04, 0x04, 0xb1,
+	0xec, 0xd8, 0xb2, 0xb2, 0x38, 0xbc, 0x10, 0xea, 0x7a, 0x0e, 0xa4, 0xa4,
+	0xcb, 0x21, 0xd9, 0xc7, 0xb4, 0x0b, 0xb8, 0x39, 0xb4, 0x07, 0x53, 0x3f,
+	0xb9, 0x55, 0x55, 0xa1, 0x6f, 0x11, 0x49, 0xc0, 0x94, 0x77, 0xaf, 0x76,
+	0x97, 0x7f, 0x31, 0x08, 0xdd, 0x72, 0x48, 0x72, 0xf8, 0x11, 0x4f, 0x69,
+	0x10, 0xef, 0x23, 0x06, 0xf3, 0x34, 0xac, 0xee, 0x97, 0x89, 0x41, 0x1c,
+	0x36, 0x38, 0xb1, 0x80, 0x96, 0x7a, 0x9e, 0x72, 0xab, 0x25, 0xeb, 0xce,
+	0x7b, 0xb8, 0x5d, 0xc8, 0xef, 0xa4, 0x73, 0xa1, 0xa6, 0x8f, 0x01, 0x54,
+	0xce, 0x58, 0x19, 0xe5, 0x7e, 0xfa, 0x77, 0x08, 0x9d, 0x53, 0xc1, 0xcc,
+	0x08, 0xe8, 0x1d, 0xe0, 0x82, 0x5e, 0xe1, 0xe6, 0xbd, 0xbb, 0x59, 0x7e,
+	0x12, 0x9c, 0x39, 0x60, 0x23, 0xf7, 0xbe, 0x0a, 0x7c, 0x48, 0x12, 0xa0,
+	0x84, 0x04, 0x3f, 0xa1, 0x6e, 0x92, 0xcd, 0xa0, 0xac, 0xee, 0x0b, 0xbc,
+	0x18, 0x30, 0x28, 0xbd, 0xf5, 0xfa, 0x3a, 0x35
+};
+
+static unsigned int data_raw_len = 512;
+
+/*
+ * openssl dgst -sha256 -sign private.key -out data.enc data.raw
+ */
+unsigned char data_enc[] = {
+	0xa7, 0x4a, 0x12, 0x8f, 0xee, 0x65, 0x4b, 0xcd, 0x88, 0xca, 0x4d, 0xed,
+	0xe3, 0x04, 0xe7, 0x7c, 0x59, 0xbf, 0x2f, 0xad, 0x95, 0x73, 0x5b, 0x2c,
+	0x4e, 0xb5, 0xda, 0x5e, 0x3a, 0x6d, 0xb4, 0xc5, 0x84, 0x0c, 0xd2, 0x4a,
+	0x62, 0x0d, 0x5f, 0xba, 0x10, 0xee, 0xb1, 0x2a, 0xe1, 0xfe, 0x50, 0x18,
+	0x97, 0xcc, 0xea, 0x26, 0x62, 0x33, 0x5a, 0x1d, 0x51, 0x38, 0x52, 0x89,
+	0x4d, 0xa7, 0x18, 0xff, 0xa6, 0xc8, 0xd4, 0x7a, 0xc0, 0xa6, 0x22, 0xdf,
+	0x41, 0x89, 0x93, 0x9b, 0xe7, 0x9e, 0xc1, 0xc8, 0x80, 0xda, 0x1a, 0x3f,
+	0xa4, 0x7a, 0xd0, 0x07, 0xcb, 0x5c, 0xa4, 0x75, 0x12, 0x54, 0x78, 0x67,
+	0xbf, 0xe6, 0xae, 0x1e, 0x56, 0x33, 0x9e, 0xe0, 0x6e, 0x33, 0xa7, 0x58,
+	0xb0, 0x47, 0x49, 0xa8, 0x37, 0xdb, 0x82, 0x4b, 0xbd, 0x32, 0x9c, 0xdc,
+	0xf4, 0x67, 0x17, 0x24, 0x55, 0xfd, 0x83, 0x1e, 0xc8, 0xb4, 0x5c, 0xf9,
+	0x15, 0x6c, 0x5e, 0xaa, 0x72, 0x03, 0x9e, 0x7c, 0x17, 0xf5, 0x7c, 0x37,
+	0x96, 0x00, 0xb0, 0xd8, 0xaa, 0x05, 0xfa, 0xaa, 0xa1, 0x78, 0x77, 0xd5,
+	0x09, 0xdd, 0x05, 0xc7, 0xe2, 0x9f, 0x68, 0xc7, 0xf8, 0xfb, 0x0b, 0x6f,
+	0x18, 0x1e, 0xcc, 0x93, 0xd3, 0x3f, 0xc9, 0x26, 0x29, 0x64, 0xe7, 0x15,
+	0xdc, 0xb8, 0x19, 0x10, 0x24, 0x55, 0x55, 0x3b, 0x79, 0xa1, 0x65, 0x12,
+	0xe0, 0x0b, 0x88, 0x44, 0x4c, 0xea, 0x85, 0x5a, 0x6b, 0x2d, 0x45, 0x6e,
+	0xe7, 0x83, 0x6f, 0x3a, 0xaa, 0x1e, 0xf1, 0x9c, 0x8f, 0xdc, 0xb9, 0x37,
+	0xa2, 0x15, 0x61, 0x93, 0x06, 0x23, 0xf5, 0xfe, 0xf0, 0xf8, 0x2b, 0xf7,
+	0xc0, 0x68, 0x67, 0xf6, 0x4e, 0x08, 0x0d, 0x0d, 0x08, 0xbe, 0xfb, 0x2c,
+	0x4c, 0xe7, 0xd7, 0x1a, 0xad, 0xd9, 0x98, 0xa1, 0x8d, 0x94, 0x1c, 0xd1,
+	0x89, 0x06, 0xc9, 0x3a
+};
+
+static unsigned int data_enc_len = 256;
+
+/**
+ * lib_rsa_verify_valid() - unit test for rsa_verify()
+ *
+ * Test rsa_verify() with valid hash
+ *
+ * @uts:	unit test state
+ * Return:	0 = success, 1 = failure
+ */
+static int lib_rsa_verify_valid(struct unit_test_state *uts)
+{
+	struct image_sign_info info;
+	struct image_region reg;
+	int ret;
+
+	memset(&info, '\0', sizeof(info));
+	info.name = "sha256,rsa2048";
+	info.padding = image_get_padding_algo("pkcs-1.5");
+	info.checksum = image_get_checksum_algo("sha256,rsa2048");
+	info.crypto = image_get_crypto_algo(info.name);
+
+	info.key = public_key;
+	info.keylen = public_key_len;
+
+	reg.data = data_raw;
+	reg.size = data_raw_len;
+	ret = rsa_verify(&info, &reg, 1, data_enc, data_enc_len);
+	ut_assertf(ret == 0, "verification unexpectedly failed (%d)\n", ret);
+
+	return CMD_RET_SUCCESS;
+}
+
+LIB_TEST(lib_rsa_verify_valid, 0);
+
+/**
+ * lib_rsa_verify_invalid() - unit test for rsa_verify()
+ *
+ * Test rsa_verify() with invalid hash
+ *
+ * @uts:	unit test state
+ * Return:	0 = success, 1 = failure
+ */
+static int lib_rsa_verify_invalid(struct unit_test_state *uts)
+{
+	struct image_sign_info info;
+	struct image_region reg;
+	unsigned char ctmp;
+	int ret;
+
+	memset(&info, '\0', sizeof(info));
+	info.name = "sha256,rsa2048";
+	info.padding = image_get_padding_algo("pkcs-1.5");
+	info.checksum = image_get_checksum_algo("sha256,rsa2048");
+	info.crypto = image_get_crypto_algo(info.name);
+
+	info.key = public_key;
+	info.keylen = public_key_len;
+
+	/* randomly corrupt enc'ed data */
+	ctmp = data_enc[data_enc_len - 10];
+	data_enc[data_enc_len - 10] = 0x12;
+
+	reg.data = data_raw;
+	reg.size = data_raw_len;
+	ret = rsa_verify(&info, &reg, 1, data_enc, data_enc_len);
+
+	/* revert a change */
+	data_enc[data_enc_len - 10] = ctmp;
+
+	ut_assertf(ret != 0, "verification unexpectedly succeeded\n");
+
+	return CMD_RET_SUCCESS;
+}
+
+LIB_TEST(lib_rsa_verify_invalid, 0);
+#endif /* RSA_VERIFY_WITH_PKEY */
diff --git a/tools/Makefile b/tools/Makefile
index 99be724..3b9ae90 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -58,7 +58,7 @@
 hostprogs-$(CONFIG_CMD_BOOTEFI_SELFTEST) += file2include
 
 FIT_OBJS-$(CONFIG_FIT) := fit_common.o fit_image.o image-host.o common/image-fit.o
-FIT_SIG_OBJS-$(CONFIG_FIT_SIGNATURE) := common/image-sig.o
+FIT_SIG_OBJS-$(CONFIG_FIT_SIGNATURE) := common/image-sig.o common/image-fit-sig.o
 FIT_CIPHER_OBJS-$(CONFIG_FIT_CIPHER) := common/image-cipher.o
 
 # The following files are synced with upstream DTC.