Merge branch 'master' of https://source.denx.de/u-boot/custodians/u-boot-sunxi

Beside some rather unexciting sync of the DTs from the kernel tree, and
some Kconfig cleanup, there are some improvements for the ARMv5 Allwinner
family, to support boards with the F1C200s (64MB DRAM) better. We will
get actual board support as soon as the DTs have passed the Linux review
process.
There is also support for the X96 Mate TV Box, featuring the H616 SoC and
a full 4GB of DRAM.
Also we found the secret to enable SPI booting on the H616 (pin PC5 must
be pulled to GND), so the SPI boot support patch is now good to go.

Passed the gitlab CI, plus briefly tested on Pine64-LTS, LicheePi Nano,
X96 Mate and OrangePi Zero.
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml
index f200b40..bda7624 100644
--- a/.azure-pipelines.yml
+++ b/.azure-pipelines.yml
@@ -2,7 +2,7 @@
   windows_vm: windows-2019
   ubuntu_vm: ubuntu-22.04
   macos_vm: macOS-12
-  ci_runner_image: trini/u-boot-gitlab-ci-runner:jammy-20221003-07Oct2022
+  ci_runner_image: trini/u-boot-gitlab-ci-runner:jammy-20221003-17Oct2022
   # Add '-u 0' options for Azure pipelines, otherwise we get "permission
   # denied" error when it tries to "useradd -m -u 1001 vsts_azpcontainer",
   # since our $(ci_runner_image) user is not root.
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 7052a60..6f4c34f 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -2,7 +2,7 @@
 
 # Grab our configured image.  The source for this is found
 # in the u-boot tree at tools/docker/Dockerfile
-image: trini/u-boot-gitlab-ci-runner:jammy-20221003-07Oct2022
+image: trini/u-boot-gitlab-ci-runner:jammy-20221003-17Oct2022
 
 # We run some tests in different order, to catch some failures quicker.
 stages:
@@ -92,7 +92,6 @@
   script:
     - virtualenv -p /usr/bin/python3 /tmp/venv
     - . /tmp/venv/bin/activate
-    - pip install pyelftools
     - ret=0;
       ./tools/buildman/buildman -o /tmp -P -E -W aarch64 || ret=$?;
       if [[ $ret -ne 0 ]]; then
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index e5b3f4c..162d108 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1206,7 +1206,8 @@
 	stm32mp15xx-dhcom-pdk2.dtb \
 	stm32mp15xx-dhcom-picoitx.dtb \
 	stm32mp15xx-dhcor-avenger96.dtb \
-	stm32mp15xx-dhcor-drc-compact.dtb
+	stm32mp15xx-dhcor-drc-compact.dtb \
+	stm32mp15xx-dhcor-testbench.dtb
 
 dtb-$(CONFIG_SOC_K3_AM654) += \
 	k3-am654-base-board.dtb \
diff --git a/arch/arm/dts/k3-am64-evm-ddr4-1600MTs.dtsi b/arch/arm/dts/k3-am64-evm-ddr4-1600MTs.dtsi
index 9a008df..4914121 100644
--- a/arch/arm/dts/k3-am64-evm-ddr4-1600MTs.dtsi
+++ b/arch/arm/dts/k3-am64-evm-ddr4-1600MTs.dtsi
@@ -1,8 +1,10 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * This file was generated by the AM64x_DDR4_RegConfig_Tool, Revision: 0.6.0
- * This file was generated on Oct 26 2020
- * DDR4 Frequency = 800MHz (1600MTs)
+ * This file was generated with the
+ * AM64x SysConfig DDR Subsystem Register Configuration Tool v0.08.40
+ * Wed Feb 02 2022 16:24:50 GMT-0600 (Central Standard Time)
+ * DDR Type: DDR4
+ * Frequency = 800MHz (1600MTs)
  * Density: 16Gb
  * Number of Ranks: 1
  */
@@ -49,11 +51,11 @@
 #define DDRSS_CTL_35_DATA 0x00000000
 #define DDRSS_CTL_36_DATA 0x00000000
 #define DDRSS_CTL_37_DATA 0x00000000
-#define DDRSS_CTL_38_DATA 0x04000918
+#define DDRSS_CTL_38_DATA 0x0400091C
 #define DDRSS_CTL_39_DATA 0x1C1C1C1C
-#define DDRSS_CTL_40_DATA 0x04000918
+#define DDRSS_CTL_40_DATA 0x0400091C
 #define DDRSS_CTL_41_DATA 0x1C1C1C1C
-#define DDRSS_CTL_42_DATA 0x04000918
+#define DDRSS_CTL_42_DATA 0x0400091C
 #define DDRSS_CTL_43_DATA 0x1C1C1C1C
 #define DDRSS_CTL_44_DATA 0x05050404
 #define DDRSS_CTL_45_DATA 0x00002706
@@ -215,22 +217,22 @@
 #define DDRSS_CTL_201_DATA 0x00000000
 #define DDRSS_CTL_202_DATA 0x00000000
 #define DDRSS_CTL_203_DATA 0x00000000
-#define DDRSS_CTL_204_DATA 0x00041400
+#define DDRSS_CTL_204_DATA 0x00042400
 #define DDRSS_CTL_205_DATA 0x00000301
 #define DDRSS_CTL_206_DATA 0x00000000
-#define DDRSS_CTL_207_DATA 0x00000414
+#define DDRSS_CTL_207_DATA 0x00000424
 #define DDRSS_CTL_208_DATA 0x00000301
 #define DDRSS_CTL_209_DATA 0x00000000
-#define DDRSS_CTL_210_DATA 0x00000414
+#define DDRSS_CTL_210_DATA 0x00000424
 #define DDRSS_CTL_211_DATA 0x00000301
 #define DDRSS_CTL_212_DATA 0x00000000
-#define DDRSS_CTL_213_DATA 0x00000414
+#define DDRSS_CTL_213_DATA 0x00000424
 #define DDRSS_CTL_214_DATA 0x00000301
 #define DDRSS_CTL_215_DATA 0x00000000
-#define DDRSS_CTL_216_DATA 0x00000414
+#define DDRSS_CTL_216_DATA 0x00000424
 #define DDRSS_CTL_217_DATA 0x00000301
 #define DDRSS_CTL_218_DATA 0x00000000
-#define DDRSS_CTL_219_DATA 0x00000414
+#define DDRSS_CTL_219_DATA 0x00000424
 #define DDRSS_CTL_220_DATA 0x00000301
 #define DDRSS_CTL_221_DATA 0x00000000
 #define DDRSS_CTL_222_DATA 0x00000000
@@ -247,12 +249,12 @@
 #define DDRSS_CTL_233_DATA 0x00000000
 #define DDRSS_CTL_234_DATA 0x00000000
 #define DDRSS_CTL_235_DATA 0x00000000
-#define DDRSS_CTL_236_DATA 0x00000401
-#define DDRSS_CTL_237_DATA 0x00000401
-#define DDRSS_CTL_238_DATA 0x00000401
-#define DDRSS_CTL_239_DATA 0x00000401
-#define DDRSS_CTL_240_DATA 0x00000401
-#define DDRSS_CTL_241_DATA 0x00000401
+#define DDRSS_CTL_236_DATA 0x00001401
+#define DDRSS_CTL_237_DATA 0x00001401
+#define DDRSS_CTL_238_DATA 0x00001401
+#define DDRSS_CTL_239_DATA 0x00001401
+#define DDRSS_CTL_240_DATA 0x00001401
+#define DDRSS_CTL_241_DATA 0x00001401
 #define DDRSS_CTL_242_DATA 0x00000493
 #define DDRSS_CTL_243_DATA 0x00000493
 #define DDRSS_CTL_244_DATA 0x00000493
@@ -341,9 +343,9 @@
 #define DDRSS_CTL_327_DATA 0x00000C01
 #define DDRSS_CTL_328_DATA 0x00000000
 #define DDRSS_CTL_329_DATA 0x00000000
-#define DDRSS_CTL_330_DATA 0x01000000
+#define DDRSS_CTL_330_DATA 0x00000000
 #define DDRSS_CTL_331_DATA 0x01000000
-#define DDRSS_CTL_332_DATA 0x00000000
+#define DDRSS_CTL_332_DATA 0x00000100
 #define DDRSS_CTL_333_DATA 0x00010000
 #define DDRSS_CTL_334_DATA 0x00000000
 #define DDRSS_CTL_335_DATA 0x00000000
@@ -386,8 +388,8 @@
 #define DDRSS_CTL_372_DATA 0x06060C06
 #define DDRSS_CTL_373_DATA 0x00010101
 #define DDRSS_CTL_374_DATA 0x02000000
-#define DDRSS_CTL_375_DATA 0x03020101
-#define DDRSS_CTL_376_DATA 0x00000303
+#define DDRSS_CTL_375_DATA 0x05020101
+#define DDRSS_CTL_376_DATA 0x00000505
 #define DDRSS_CTL_377_DATA 0x02020200
 #define DDRSS_CTL_378_DATA 0x02020202
 #define DDRSS_CTL_379_DATA 0x02020202
@@ -403,7 +405,7 @@
 #define DDRSS_CTL_389_DATA 0x00000200
 #define DDRSS_CTL_390_DATA 0x0000DB60
 #define DDRSS_CTL_391_DATA 0x0001E780
-#define DDRSS_CTL_392_DATA 0x0A0B0302
+#define DDRSS_CTL_392_DATA 0x0C0D0302
 #define DDRSS_CTL_393_DATA 0x001E090A
 #define DDRSS_CTL_394_DATA 0x000030C0
 #define DDRSS_CTL_395_DATA 0x00000200
@@ -412,7 +414,7 @@
 #define DDRSS_CTL_398_DATA 0x00000200
 #define DDRSS_CTL_399_DATA 0x0000DB60
 #define DDRSS_CTL_400_DATA 0x0001E780
-#define DDRSS_CTL_401_DATA 0x0A0B0302
+#define DDRSS_CTL_401_DATA 0x0C0D0302
 #define DDRSS_CTL_402_DATA 0x001E090A
 #define DDRSS_CTL_403_DATA 0x000030C0
 #define DDRSS_CTL_404_DATA 0x00000200
@@ -421,7 +423,7 @@
 #define DDRSS_CTL_407_DATA 0x00000200
 #define DDRSS_CTL_408_DATA 0x0000DB60
 #define DDRSS_CTL_409_DATA 0x0001E780
-#define DDRSS_CTL_410_DATA 0x0A0B0302
+#define DDRSS_CTL_410_DATA 0x0C0D0302
 #define DDRSS_CTL_411_DATA 0x0000090A
 #define DDRSS_CTL_412_DATA 0x00000000
 #define DDRSS_CTL_413_DATA 0x0302000A
@@ -601,14 +603,14 @@
 #define DDRSS_PI_164_DATA 0x00007800
 #define DDRSS_PI_165_DATA 0x00780078
 #define DDRSS_PI_166_DATA 0x00141414
-#define DDRSS_PI_167_DATA 0x00000038
-#define DDRSS_PI_168_DATA 0x00000038
-#define DDRSS_PI_169_DATA 0x00040038
+#define DDRSS_PI_167_DATA 0x0000003A
+#define DDRSS_PI_168_DATA 0x0000003A
+#define DDRSS_PI_169_DATA 0x0004003A
 #define DDRSS_PI_170_DATA 0x04000400
 #define DDRSS_PI_171_DATA 0xC8040009
-#define DDRSS_PI_172_DATA 0x04000918
-#define DDRSS_PI_173_DATA 0x000918C8
-#define DDRSS_PI_174_DATA 0x0018C804
+#define DDRSS_PI_172_DATA 0x0400091C
+#define DDRSS_PI_173_DATA 0x00091CC8
+#define DDRSS_PI_174_DATA 0x001CC804
 #define DDRSS_PI_175_DATA 0x00000118
 #define DDRSS_PI_176_DATA 0x00001860
 #define DDRSS_PI_177_DATA 0x00000118
@@ -621,14 +623,14 @@
 #define DDRSS_PI_184_DATA 0x010C010C
 #define DDRSS_PI_185_DATA 0x0000010C
 #define DDRSS_PI_186_DATA 0x00000000
-#define DDRSS_PI_187_DATA 0x03000000
-#define DDRSS_PI_188_DATA 0x01010303
+#define DDRSS_PI_187_DATA 0x05000000
+#define DDRSS_PI_188_DATA 0x01010505
 #define DDRSS_PI_189_DATA 0x01010101
 #define DDRSS_PI_190_DATA 0x00181818
 #define DDRSS_PI_191_DATA 0x00000000
 #define DDRSS_PI_192_DATA 0x00000000
-#define DDRSS_PI_193_DATA 0x0B000000
-#define DDRSS_PI_194_DATA 0x0A0A0B0B
+#define DDRSS_PI_193_DATA 0x0D000000
+#define DDRSS_PI_194_DATA 0x0A0A0D0D
 #define DDRSS_PI_195_DATA 0x0303030A
 #define DDRSS_PI_196_DATA 0x00000000
 #define DDRSS_PI_197_DATA 0x00000000
@@ -656,15 +658,15 @@
 #define DDRSS_PI_219_DATA 0x001600C8
 #define DDRSS_PI_220_DATA 0x010100C8
 #define DDRSS_PI_221_DATA 0x00001B01
-#define DDRSS_PI_222_DATA 0x1F0F0051
-#define DDRSS_PI_223_DATA 0x03000001
-#define DDRSS_PI_224_DATA 0x001B0A0B
-#define DDRSS_PI_225_DATA 0x1F0F0051
-#define DDRSS_PI_226_DATA 0x03000001
-#define DDRSS_PI_227_DATA 0x001B0A0B
-#define DDRSS_PI_228_DATA 0x1F0F0051
-#define DDRSS_PI_229_DATA 0x03000001
-#define DDRSS_PI_230_DATA 0x00000A0B
+#define DDRSS_PI_222_DATA 0x1F0F0053
+#define DDRSS_PI_223_DATA 0x05000001
+#define DDRSS_PI_224_DATA 0x001B0A0D
+#define DDRSS_PI_225_DATA 0x1F0F0053
+#define DDRSS_PI_226_DATA 0x05000001
+#define DDRSS_PI_227_DATA 0x001B0A0D
+#define DDRSS_PI_228_DATA 0x1F0F0053
+#define DDRSS_PI_229_DATA 0x05000001
+#define DDRSS_PI_230_DATA 0x00010A0D
 #define DDRSS_PI_231_DATA 0x0C0B0700
 #define DDRSS_PI_232_DATA 0x000D0605
 #define DDRSS_PI_233_DATA 0x0000C570
@@ -731,52 +733,52 @@
 #define DDRSS_PI_294_DATA 0x01000000
 #define DDRSS_PI_295_DATA 0x00020201
 #define DDRSS_PI_296_DATA 0x00000000
-#define DDRSS_PI_297_DATA 0x00000414
+#define DDRSS_PI_297_DATA 0x00000424
 #define DDRSS_PI_298_DATA 0x00000301
 #define DDRSS_PI_299_DATA 0x00000000
 #define DDRSS_PI_300_DATA 0x00000000
 #define DDRSS_PI_301_DATA 0x00000000
-#define DDRSS_PI_302_DATA 0x00000401
+#define DDRSS_PI_302_DATA 0x00001401
 #define DDRSS_PI_303_DATA 0x00000493
 #define DDRSS_PI_304_DATA 0x00000000
-#define DDRSS_PI_305_DATA 0x00000414
+#define DDRSS_PI_305_DATA 0x00000424
 #define DDRSS_PI_306_DATA 0x00000301
 #define DDRSS_PI_307_DATA 0x00000000
 #define DDRSS_PI_308_DATA 0x00000000
 #define DDRSS_PI_309_DATA 0x00000000
-#define DDRSS_PI_310_DATA 0x00000401
+#define DDRSS_PI_310_DATA 0x00001401
 #define DDRSS_PI_311_DATA 0x00000493
 #define DDRSS_PI_312_DATA 0x00000000
-#define DDRSS_PI_313_DATA 0x00000414
+#define DDRSS_PI_313_DATA 0x00000424
 #define DDRSS_PI_314_DATA 0x00000301
 #define DDRSS_PI_315_DATA 0x00000000
 #define DDRSS_PI_316_DATA 0x00000000
 #define DDRSS_PI_317_DATA 0x00000000
-#define DDRSS_PI_318_DATA 0x00000401
+#define DDRSS_PI_318_DATA 0x00001401
 #define DDRSS_PI_319_DATA 0x00000493
 #define DDRSS_PI_320_DATA 0x00000000
-#define DDRSS_PI_321_DATA 0x00000414
+#define DDRSS_PI_321_DATA 0x00000424
 #define DDRSS_PI_322_DATA 0x00000301
 #define DDRSS_PI_323_DATA 0x00000000
 #define DDRSS_PI_324_DATA 0x00000000
 #define DDRSS_PI_325_DATA 0x00000000
-#define DDRSS_PI_326_DATA 0x00000401
+#define DDRSS_PI_326_DATA 0x00001401
 #define DDRSS_PI_327_DATA 0x00000493
 #define DDRSS_PI_328_DATA 0x00000000
-#define DDRSS_PI_329_DATA 0x00000414
+#define DDRSS_PI_329_DATA 0x00000424
 #define DDRSS_PI_330_DATA 0x00000301
 #define DDRSS_PI_331_DATA 0x00000000
 #define DDRSS_PI_332_DATA 0x00000000
 #define DDRSS_PI_333_DATA 0x00000000
-#define DDRSS_PI_334_DATA 0x00000401
+#define DDRSS_PI_334_DATA 0x00001401
 #define DDRSS_PI_335_DATA 0x00000493
 #define DDRSS_PI_336_DATA 0x00000000
-#define DDRSS_PI_337_DATA 0x00000414
+#define DDRSS_PI_337_DATA 0x00000424
 #define DDRSS_PI_338_DATA 0x00000301
 #define DDRSS_PI_339_DATA 0x00000000
 #define DDRSS_PI_340_DATA 0x00000000
 #define DDRSS_PI_341_DATA 0x00000000
-#define DDRSS_PI_342_DATA 0x00000401
+#define DDRSS_PI_342_DATA 0x00001401
 #define DDRSS_PI_343_DATA 0x00000493
 #define DDRSS_PI_344_DATA 0x00000000
 #define DDRSS_PHY_0_DATA 0x04C00000
@@ -871,7 +873,7 @@
 #define DDRSS_PHY_89_DATA 0x31804000
 #define DDRSS_PHY_90_DATA 0x04BF0340
 #define DDRSS_PHY_91_DATA 0x01008080
-#define DDRSS_PHY_92_DATA 0x04050000
+#define DDRSS_PHY_92_DATA 0x04050001
 #define DDRSS_PHY_93_DATA 0x00000504
 #define DDRSS_PHY_94_DATA 0x42100010
 #define DDRSS_PHY_95_DATA 0x010C053E
@@ -1127,7 +1129,7 @@
 #define DDRSS_PHY_345_DATA 0x31804000
 #define DDRSS_PHY_346_DATA 0x04BF0340
 #define DDRSS_PHY_347_DATA 0x01008080
-#define DDRSS_PHY_348_DATA 0x04050000
+#define DDRSS_PHY_348_DATA 0x04050001
 #define DDRSS_PHY_349_DATA 0x00000504
 #define DDRSS_PHY_350_DATA 0x42100010
 #define DDRSS_PHY_351_DATA 0x010C053E
@@ -2113,7 +2115,7 @@
 #define DDRSS_PHY_1331_DATA 0x00004410
 #define DDRSS_PHY_1332_DATA 0x00000000
 #define DDRSS_PHY_1333_DATA 0x00000046
-#define DDRSS_PHY_1334_DATA 0x00010000
+#define DDRSS_PHY_1334_DATA 0x00000400
 #define DDRSS_PHY_1335_DATA 0x00000008
 #define DDRSS_PHY_1336_DATA 0x00000000
 #define DDRSS_PHY_1337_DATA 0x00000000
@@ -2184,4 +2186,4 @@
 #define DDRSS_PHY_1402_DATA 0x01990000
 #define DDRSS_PHY_1403_DATA 0x300D3F11
 #define DDRSS_PHY_1404_DATA 0x01990000
-#define DDRSS_PHY_1405_DATA 0x20040001
+#define DDRSS_PHY_1405_DATA 0x20040004
diff --git a/arch/arm/dts/k3-am64-sk-lp4-1333MTs.dtsi b/arch/arm/dts/k3-am64-sk-lp4-1600MTs.dtsi
similarity index 91%
rename from arch/arm/dts/k3-am64-sk-lp4-1333MTs.dtsi
rename to arch/arm/dts/k3-am64-sk-lp4-1600MTs.dtsi
index dde5ab1..f225c1f 100644
--- a/arch/arm/dts/k3-am64-sk-lp4-1333MTs.dtsi
+++ b/arch/arm/dts/k3-am64-sk-lp4-1600MTs.dtsi
@@ -1,18 +1,17 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/
  * This file was generated with the
- * AM64x SysConfig DDR Subsystem Register Configuration Tool v0.08.00
- * Wed Oct 13 2021 10:08:29 GMT-0500 (Central Daylight Time)
+ * AM64x SysConfig DDR Subsystem Register Configuration Tool v0.08.40
+ * Wed Feb 02 2022 16:59:34 GMT-0600 (Central Standard Time)
  * DDR Type: LPDDR4
- * F0 = 50MHz    F1 = 666.7MHz    F2 = 666.7MHz
+ * F0 = 50MHz    F1 = 800MHz    F2 = 800MHz
  * Density (per channel): 16Gb
  * Number of Ranks: 1
-*/
+ */
 
 #define DDRSS_PLL_FHS_CNT 6
-#define DDRSS_PLL_FREQUENCY_1 333350000
-#define DDRSS_PLL_FREQUENCY_2 333350000
+#define DDRSS_PLL_FREQUENCY_1 400000000
+#define DDRSS_PLL_FREQUENCY_2 400000000
 
 #define DDRSS_CTL_0_DATA 0x00000B00
 #define DDRSS_CTL_1_DATA 0x00000000
@@ -25,14 +24,14 @@
 #define DDRSS_CTL_8_DATA 0x000186A0
 #define DDRSS_CTL_9_DATA 0x00000005
 #define DDRSS_CTL_10_DATA 0x00000064
-#define DDRSS_CTL_11_DATA 0x000208D6
-#define DDRSS_CTL_12_DATA 0x00145856
+#define DDRSS_CTL_11_DATA 0x00027100
+#define DDRSS_CTL_12_DATA 0x00186A00
 #define DDRSS_CTL_13_DATA 0x00000005
-#define DDRSS_CTL_14_DATA 0x00000536
-#define DDRSS_CTL_15_DATA 0x000208D6
-#define DDRSS_CTL_16_DATA 0x00145856
+#define DDRSS_CTL_14_DATA 0x00000640
+#define DDRSS_CTL_15_DATA 0x00027100
+#define DDRSS_CTL_16_DATA 0x00186A00
 #define DDRSS_CTL_17_DATA 0x00000005
-#define DDRSS_CTL_18_DATA 0x00000536
+#define DDRSS_CTL_18_DATA 0x00000640
 #define DDRSS_CTL_19_DATA 0x01010100
 #define DDRSS_CTL_20_DATA 0x01010100
 #define DDRSS_CTL_21_DATA 0x01000110
@@ -48,8 +47,8 @@
 #define DDRSS_CTL_31_DATA 0x00000000
 #define DDRSS_CTL_32_DATA 0x00000000
 #define DDRSS_CTL_33_DATA 0x00000000
-#define DDRSS_CTL_34_DATA 0x02000010
-#define DDRSS_CTL_35_DATA 0x00001B1B
+#define DDRSS_CTL_34_DATA 0x08000010
+#define DDRSS_CTL_35_DATA 0x00002020
 #define DDRSS_CTL_36_DATA 0x00000000
 #define DDRSS_CTL_37_DATA 0x00000000
 #define DDRSS_CTL_38_DATA 0x0000040C
@@ -62,64 +61,64 @@
 #define DDRSS_CTL_45_DATA 0x00000700
 #define DDRSS_CTL_46_DATA 0x09090004
 #define DDRSS_CTL_47_DATA 0x00000203
-#define DDRSS_CTL_48_DATA 0x00290006
-#define DDRSS_CTL_49_DATA 0x0909001D
-#define DDRSS_CTL_50_DATA 0x0000150C
-#define DDRSS_CTL_51_DATA 0x00290006
-#define DDRSS_CTL_52_DATA 0x0909001D
-#define DDRSS_CTL_53_DATA 0x0900150C
+#define DDRSS_CTL_48_DATA 0x00320007
+#define DDRSS_CTL_49_DATA 0x09090023
+#define DDRSS_CTL_50_DATA 0x0000190F
+#define DDRSS_CTL_51_DATA 0x00320007
+#define DDRSS_CTL_52_DATA 0x09090023
+#define DDRSS_CTL_53_DATA 0x0900190F
 #define DDRSS_CTL_54_DATA 0x000A0A09
 #define DDRSS_CTL_55_DATA 0x040006DB
 #define DDRSS_CTL_56_DATA 0x09092004
-#define DDRSS_CTL_57_DATA 0x00000A0A
-#define DDRSS_CTL_58_DATA 0x05005B68
-#define DDRSS_CTL_59_DATA 0x09092005
-#define DDRSS_CTL_60_DATA 0x00000A0A
-#define DDRSS_CTL_61_DATA 0x05005B68
-#define DDRSS_CTL_62_DATA 0x03042005
+#define DDRSS_CTL_57_DATA 0x00000C0A
+#define DDRSS_CTL_58_DATA 0x06006DB0
+#define DDRSS_CTL_59_DATA 0x09092006
+#define DDRSS_CTL_60_DATA 0x00000C0A
+#define DDRSS_CTL_61_DATA 0x06006DB0
+#define DDRSS_CTL_62_DATA 0x03042006
 #define DDRSS_CTL_63_DATA 0x04050002
-#define DDRSS_CTL_64_DATA 0x0E0D0E0D
+#define DDRSS_CTL_64_DATA 0x100F100F
 #define DDRSS_CTL_65_DATA 0x01010008
-#define DDRSS_CTL_66_DATA 0x041A1A07
-#define DDRSS_CTL_67_DATA 0x030E0E03
-#define DDRSS_CTL_68_DATA 0x00000E0E
+#define DDRSS_CTL_66_DATA 0x041F1F07
+#define DDRSS_CTL_67_DATA 0x03111103
+#define DDRSS_CTL_68_DATA 0x00001111
 #define DDRSS_CTL_69_DATA 0x00000101
 #define DDRSS_CTL_70_DATA 0x00000000
 #define DDRSS_CTL_71_DATA 0x01000000
 #define DDRSS_CTL_72_DATA 0x00130803
 #define DDRSS_CTL_73_DATA 0x000000BB
-#define DDRSS_CTL_74_DATA 0x000000FE
-#define DDRSS_CTL_75_DATA 0x00000A20
-#define DDRSS_CTL_76_DATA 0x000000FE
-#define DDRSS_CTL_77_DATA 0x00000A20
+#define DDRSS_CTL_74_DATA 0x00000130
+#define DDRSS_CTL_75_DATA 0x00000C28
+#define DDRSS_CTL_76_DATA 0x00000130
+#define DDRSS_CTL_77_DATA 0x00000C28
 #define DDRSS_CTL_78_DATA 0x00000005
 #define DDRSS_CTL_79_DATA 0x0000000A
 #define DDRSS_CTL_80_DATA 0x00000010
-#define DDRSS_CTL_81_DATA 0x0000007F
-#define DDRSS_CTL_82_DATA 0x0000013D
-#define DDRSS_CTL_83_DATA 0x0000007F
-#define DDRSS_CTL_84_DATA 0x0000013D
+#define DDRSS_CTL_81_DATA 0x00000098
+#define DDRSS_CTL_82_DATA 0x0000017E
+#define DDRSS_CTL_83_DATA 0x00000098
+#define DDRSS_CTL_84_DATA 0x0000017E
 #define DDRSS_CTL_85_DATA 0x03004000
 #define DDRSS_CTL_86_DATA 0x00001201
-#define DDRSS_CTL_87_DATA 0x00050005
-#define DDRSS_CTL_88_DATA 0x00000005
+#define DDRSS_CTL_87_DATA 0x00060005
+#define DDRSS_CTL_88_DATA 0x00000006
 #define DDRSS_CTL_89_DATA 0x00000000
-#define DDRSS_CTL_90_DATA 0x05101008
+#define DDRSS_CTL_90_DATA 0x05121208
 #define DDRSS_CTL_91_DATA 0x05030A05
-#define DDRSS_CTL_92_DATA 0x05030A05
-#define DDRSS_CTL_93_DATA 0x01030A05
+#define DDRSS_CTL_92_DATA 0x05030C06
+#define DDRSS_CTL_93_DATA 0x01030C06
 #define DDRSS_CTL_94_DATA 0x02010201
 #define DDRSS_CTL_95_DATA 0x00001401
-#define DDRSS_CTL_96_DATA 0x01030014
-#define DDRSS_CTL_97_DATA 0x01030103
-#define DDRSS_CTL_98_DATA 0x00000103
+#define DDRSS_CTL_96_DATA 0x01360014
+#define DDRSS_CTL_97_DATA 0x01360136
+#define DDRSS_CTL_98_DATA 0x00000136
 #define DDRSS_CTL_99_DATA 0x00000000
 #define DDRSS_CTL_100_DATA 0x05010303
-#define DDRSS_CTL_101_DATA 0x0A040505
-#define DDRSS_CTL_102_DATA 0x05050203
-#define DDRSS_CTL_103_DATA 0x030A0505
-#define DDRSS_CTL_104_DATA 0x05050502
-#define DDRSS_CTL_105_DATA 0x03030305
+#define DDRSS_CTL_101_DATA 0x0C040505
+#define DDRSS_CTL_102_DATA 0x06050203
+#define DDRSS_CTL_103_DATA 0x030C0605
+#define DDRSS_CTL_104_DATA 0x05060502
+#define DDRSS_CTL_105_DATA 0x03030306
 #define DDRSS_CTL_106_DATA 0x03010000
 #define DDRSS_CTL_107_DATA 0x00010000
 #define DDRSS_CTL_108_DATA 0x00000000
@@ -140,20 +139,20 @@
 #define DDRSS_CTL_123_DATA 0x00002EC0
 #define DDRSS_CTL_124_DATA 0x00000000
 #define DDRSS_CTL_125_DATA 0x0000051D
-#define DDRSS_CTL_126_DATA 0x00028800
-#define DDRSS_CTL_127_DATA 0x00028800
-#define DDRSS_CTL_128_DATA 0x00028800
-#define DDRSS_CTL_129_DATA 0x00028800
-#define DDRSS_CTL_130_DATA 0x00028800
+#define DDRSS_CTL_126_DATA 0x00030A00
+#define DDRSS_CTL_127_DATA 0x00030A00
+#define DDRSS_CTL_128_DATA 0x00030A00
+#define DDRSS_CTL_129_DATA 0x00030A00
+#define DDRSS_CTL_130_DATA 0x00030A00
 #define DDRSS_CTL_131_DATA 0x00000000
-#define DDRSS_CTL_132_DATA 0x000046E0
-#define DDRSS_CTL_133_DATA 0x00028800
-#define DDRSS_CTL_134_DATA 0x00028800
-#define DDRSS_CTL_135_DATA 0x00028800
-#define DDRSS_CTL_136_DATA 0x00028800
-#define DDRSS_CTL_137_DATA 0x00028800
+#define DDRSS_CTL_132_DATA 0x00005518
+#define DDRSS_CTL_133_DATA 0x00030A00
+#define DDRSS_CTL_134_DATA 0x00030A00
+#define DDRSS_CTL_135_DATA 0x00030A00
+#define DDRSS_CTL_136_DATA 0x00030A00
+#define DDRSS_CTL_137_DATA 0x00030A00
 #define DDRSS_CTL_138_DATA 0x00000000
-#define DDRSS_CTL_139_DATA 0x000046E0
+#define DDRSS_CTL_139_DATA 0x00005518
 #define DDRSS_CTL_140_DATA 0x00000000
 #define DDRSS_CTL_141_DATA 0x00000000
 #define DDRSS_CTL_142_DATA 0x00000000
@@ -209,12 +208,12 @@
 #define DDRSS_CTL_192_DATA 0x0005000A
 #define DDRSS_CTL_193_DATA 0x0404000D
 #define DDRSS_CTL_194_DATA 0x0000000D
-#define DDRSS_CTL_195_DATA 0x00430086
-#define DDRSS_CTL_196_DATA 0x050500A7
-#define DDRSS_CTL_197_DATA 0x000000A7
-#define DDRSS_CTL_198_DATA 0x00430086
-#define DDRSS_CTL_199_DATA 0x050500A7
-#define DDRSS_CTL_200_DATA 0x000000A7
+#define DDRSS_CTL_195_DATA 0x005000A0
+#define DDRSS_CTL_196_DATA 0x060600C8
+#define DDRSS_CTL_197_DATA 0x000000C8
+#define DDRSS_CTL_198_DATA 0x005000A0
+#define DDRSS_CTL_199_DATA 0x060600C8
+#define DDRSS_CTL_200_DATA 0x000000C8
 #define DDRSS_CTL_201_DATA 0x00000000
 #define DDRSS_CTL_202_DATA 0x00000000
 #define DDRSS_CTL_203_DATA 0x00000000
@@ -239,11 +238,11 @@
 #define DDRSS_CTL_222_DATA 0x00000000
 #define DDRSS_CTL_223_DATA 0x00000000
 #define DDRSS_CTL_224_DATA 0x00000031
-#define DDRSS_CTL_225_DATA 0x00000031
-#define DDRSS_CTL_226_DATA 0x00000031
+#define DDRSS_CTL_225_DATA 0x000000B1
+#define DDRSS_CTL_226_DATA 0x000000B1
 #define DDRSS_CTL_227_DATA 0x00000031
-#define DDRSS_CTL_228_DATA 0x00000031
-#define DDRSS_CTL_229_DATA 0x00000031
+#define DDRSS_CTL_228_DATA 0x000000B1
+#define DDRSS_CTL_229_DATA 0x000000B1
 #define DDRSS_CTL_230_DATA 0x00000000
 #define DDRSS_CTL_231_DATA 0x00000000
 #define DDRSS_CTL_232_DATA 0x00000000
@@ -323,12 +322,12 @@
 #define DDRSS_CTL_306_DATA 0x00400100
 #define DDRSS_CTL_307_DATA 0x00080032
 #define DDRSS_CTL_308_DATA 0x01000200
-#define DDRSS_CTL_309_DATA 0x029B0040
-#define DDRSS_CTL_310_DATA 0x00020014
+#define DDRSS_CTL_309_DATA 0x03200040
+#define DDRSS_CTL_310_DATA 0x00020018
 #define DDRSS_CTL_311_DATA 0x00400100
-#define DDRSS_CTL_312_DATA 0x0014029B
+#define DDRSS_CTL_312_DATA 0x00180320
 #define DDRSS_CTL_313_DATA 0x00030000
-#define DDRSS_CTL_314_DATA 0x00220022
+#define DDRSS_CTL_314_DATA 0x00280028
 #define DDRSS_CTL_315_DATA 0x00000100
 #define DDRSS_CTL_316_DATA 0x01010000
 #define DDRSS_CTL_317_DATA 0x00000000
@@ -344,9 +343,9 @@
 #define DDRSS_CTL_327_DATA 0x00000C01
 #define DDRSS_CTL_328_DATA 0x01000100
 #define DDRSS_CTL_329_DATA 0x00000000
-#define DDRSS_CTL_330_DATA 0x01000000
+#define DDRSS_CTL_330_DATA 0x00000000
 #define DDRSS_CTL_331_DATA 0x01030303
-#define DDRSS_CTL_332_DATA 0x00000000
+#define DDRSS_CTL_332_DATA 0x00000001
 #define DDRSS_CTL_333_DATA 0x00000000
 #define DDRSS_CTL_334_DATA 0x00000000
 #define DDRSS_CTL_335_DATA 0x00000000
@@ -390,14 +389,14 @@
 #define DDRSS_CTL_373_DATA 0x00010101
 #define DDRSS_CTL_374_DATA 0x01050503
 #define DDRSS_CTL_375_DATA 0x05020201
-#define DDRSS_CTL_376_DATA 0x08080B0B
+#define DDRSS_CTL_376_DATA 0x08080C0C
 #define DDRSS_CTL_377_DATA 0x00080308
-#define DDRSS_CTL_378_DATA 0x000C030E
-#define DDRSS_CTL_379_DATA 0x000C0310
-#define DDRSS_CTL_380_DATA 0x0C0C0810
+#define DDRSS_CTL_378_DATA 0x000B030E
+#define DDRSS_CTL_379_DATA 0x000B0310
+#define DDRSS_CTL_380_DATA 0x0B0B0810
 #define DDRSS_CTL_381_DATA 0x01000000
-#define DDRSS_CTL_382_DATA 0x03010301
-#define DDRSS_CTL_383_DATA 0x04000101
+#define DDRSS_CTL_382_DATA 0x03020301
+#define DDRSS_CTL_383_DATA 0x04000102
 #define DDRSS_CTL_384_DATA 0x1B000004
 #define DDRSS_CTL_385_DATA 0x00000176
 #define DDRSS_CTL_386_DATA 0x00000200
@@ -407,24 +406,24 @@
 #define DDRSS_CTL_390_DATA 0x00000693
 #define DDRSS_CTL_391_DATA 0x00000E9C
 #define DDRSS_CTL_392_DATA 0x03050202
-#define DDRSS_CTL_393_DATA 0x00240201
-#define DDRSS_CTL_394_DATA 0x00001440
+#define DDRSS_CTL_393_DATA 0x00250201
+#define DDRSS_CTL_394_DATA 0x00001850
 #define DDRSS_CTL_395_DATA 0x00000200
 #define DDRSS_CTL_396_DATA 0x00000200
 #define DDRSS_CTL_397_DATA 0x00000200
 #define DDRSS_CTL_398_DATA 0x00000200
-#define DDRSS_CTL_399_DATA 0x00005B20
-#define DDRSS_CTL_400_DATA 0x0000CA80
-#define DDRSS_CTL_401_DATA 0x080D0402
-#define DDRSS_CTL_402_DATA 0x00240405
-#define DDRSS_CTL_403_DATA 0x00001440
+#define DDRSS_CTL_399_DATA 0x00006D68
+#define DDRSS_CTL_400_DATA 0x0000F320
+#define DDRSS_CTL_401_DATA 0x070D0402
+#define DDRSS_CTL_402_DATA 0x00250405
+#define DDRSS_CTL_403_DATA 0x00001850
 #define DDRSS_CTL_404_DATA 0x00000200
 #define DDRSS_CTL_405_DATA 0x00000200
 #define DDRSS_CTL_406_DATA 0x00000200
 #define DDRSS_CTL_407_DATA 0x00000200
-#define DDRSS_CTL_408_DATA 0x00005B20
-#define DDRSS_CTL_409_DATA 0x0000CA80
-#define DDRSS_CTL_410_DATA 0x080D0402
+#define DDRSS_CTL_408_DATA 0x00006D68
+#define DDRSS_CTL_409_DATA 0x0000F320
+#define DDRSS_CTL_410_DATA 0x070D0402
 #define DDRSS_CTL_411_DATA 0x00000405
 #define DDRSS_CTL_412_DATA 0x00000000
 #define DDRSS_CTL_413_DATA 0x0302000A
@@ -483,7 +482,7 @@
 #define DDRSS_PI_43_DATA 0x00000000
 #define DDRSS_PI_44_DATA 0x00000000
 #define DDRSS_PI_45_DATA 0x00010100
-#define DDRSS_PI_46_DATA 0x00000014
+#define DDRSS_PI_46_DATA 0x00000015
 #define DDRSS_PI_47_DATA 0x000007D0
 #define DDRSS_PI_48_DATA 0x00000300
 #define DDRSS_PI_49_DATA 0x00000000
@@ -602,8 +601,8 @@
 #define DDRSS_PI_162_DATA 0x00000000
 #define DDRSS_PI_163_DATA 0x00000000
 #define DDRSS_PI_164_DATA 0x00000800
-#define DDRSS_PI_165_DATA 0x00640064
-#define DDRSS_PI_166_DATA 0x000E0E01
+#define DDRSS_PI_165_DATA 0x00780078
+#define DDRSS_PI_166_DATA 0x00101001
 #define DDRSS_PI_167_DATA 0x00000034
 #define DDRSS_PI_168_DATA 0x00000042
 #define DDRSS_PI_169_DATA 0x00020042
@@ -614,84 +613,84 @@
 #define DDRSS_PI_174_DATA 0x001C0000
 #define DDRSS_PI_175_DATA 0x00000013
 #define DDRSS_PI_176_DATA 0x000000BB
-#define DDRSS_PI_177_DATA 0x000000FE
-#define DDRSS_PI_178_DATA 0x00000A20
-#define DDRSS_PI_179_DATA 0x000000FE
-#define DDRSS_PI_180_DATA 0x04000A20
+#define DDRSS_PI_177_DATA 0x00000130
+#define DDRSS_PI_178_DATA 0x00000C28
+#define DDRSS_PI_179_DATA 0x00000130
+#define DDRSS_PI_180_DATA 0x04000C28
 #define DDRSS_PI_181_DATA 0x01010404
 #define DDRSS_PI_182_DATA 0x00001501
-#define DDRSS_PI_183_DATA 0x001B001B
+#define DDRSS_PI_183_DATA 0x001D001D
 #define DDRSS_PI_184_DATA 0x01000100
 #define DDRSS_PI_185_DATA 0x00000100
 #define DDRSS_PI_186_DATA 0x00000000
 #define DDRSS_PI_187_DATA 0x05050503
-#define DDRSS_PI_188_DATA 0x01010B0B
+#define DDRSS_PI_188_DATA 0x01010C0C
 #define DDRSS_PI_189_DATA 0x01010101
 #define DDRSS_PI_190_DATA 0x000C0C0A
 #define DDRSS_PI_191_DATA 0x00000000
 #define DDRSS_PI_192_DATA 0x00000000
 #define DDRSS_PI_193_DATA 0x04000000
-#define DDRSS_PI_194_DATA 0x04020909
+#define DDRSS_PI_194_DATA 0x04020808
 #define DDRSS_PI_195_DATA 0x04040204
 #define DDRSS_PI_196_DATA 0x00090031
-#define DDRSS_PI_197_DATA 0x000F0037
-#define DDRSS_PI_198_DATA 0x000F0037
+#define DDRSS_PI_197_DATA 0x00110039
+#define DDRSS_PI_198_DATA 0x00110039
 #define DDRSS_PI_199_DATA 0x01010101
-#define DDRSS_PI_200_DATA 0x0001000D
-#define DDRSS_PI_201_DATA 0x000100A7
-#define DDRSS_PI_202_DATA 0x010000A7
+#define DDRSS_PI_200_DATA 0x0002000D
+#define DDRSS_PI_201_DATA 0x000200C8
+#define DDRSS_PI_202_DATA 0x010000C8
 #define DDRSS_PI_203_DATA 0x000E000E
-#define DDRSS_PI_204_DATA 0x00A80100
-#define DDRSS_PI_205_DATA 0x010000A8
-#define DDRSS_PI_206_DATA 0x00A800A8
+#define DDRSS_PI_204_DATA 0x00C90100
+#define DDRSS_PI_205_DATA 0x010000C9
+#define DDRSS_PI_206_DATA 0x00C900C9
 #define DDRSS_PI_207_DATA 0x32103200
 #define DDRSS_PI_208_DATA 0x01013210
 #define DDRSS_PI_209_DATA 0x0A070601
-#define DDRSS_PI_210_DATA 0x0B08070D
-#define DDRSS_PI_211_DATA 0x0B08070D
+#define DDRSS_PI_210_DATA 0x0D09070D
+#define DDRSS_PI_211_DATA 0x0D09070D
 #define DDRSS_PI_212_DATA 0x000C000D
 #define DDRSS_PI_213_DATA 0x00001000
 #define DDRSS_PI_214_DATA 0x00000C00
 #define DDRSS_PI_215_DATA 0x00001000
 #define DDRSS_PI_216_DATA 0x00000C00
 #define DDRSS_PI_217_DATA 0x02001000
-#define DDRSS_PI_218_DATA 0x0015000D
-#define DDRSS_PI_219_DATA 0x001500A7
-#define DDRSS_PI_220_DATA 0x000000A7
+#define DDRSS_PI_218_DATA 0x0016000D
+#define DDRSS_PI_219_DATA 0x001600C8
+#define DDRSS_PI_220_DATA 0x000000C8
 #define DDRSS_PI_221_DATA 0x00001900
 #define DDRSS_PI_222_DATA 0x32000056
 #define DDRSS_PI_223_DATA 0x06000101
 #define DDRSS_PI_224_DATA 0x001D0204
-#define DDRSS_PI_225_DATA 0x32120059
+#define DDRSS_PI_225_DATA 0x32120058
 #define DDRSS_PI_226_DATA 0x05000101
-#define DDRSS_PI_227_DATA 0x001D0409
-#define DDRSS_PI_228_DATA 0x32120059
+#define DDRSS_PI_227_DATA 0x001D0408
+#define DDRSS_PI_228_DATA 0x32120058
 #define DDRSS_PI_229_DATA 0x05000101
-#define DDRSS_PI_230_DATA 0x00000409
+#define DDRSS_PI_230_DATA 0x00000408
 #define DDRSS_PI_231_DATA 0x05030900
 #define DDRSS_PI_232_DATA 0x00040900
 #define DDRSS_PI_233_DATA 0x0000062B
 #define DDRSS_PI_234_DATA 0x20010004
 #define DDRSS_PI_235_DATA 0x0A0A0A03
-#define DDRSS_PI_236_DATA 0x0E090000
-#define DDRSS_PI_237_DATA 0x0E09000D
-#define DDRSS_PI_238_DATA 0x00005244
-#define DDRSS_PI_239_DATA 0x2003001D
-#define DDRSS_PI_240_DATA 0x0A0A0A0A
-#define DDRSS_PI_241_DATA 0x0E090000
-#define DDRSS_PI_242_DATA 0x0E09000D
-#define DDRSS_PI_243_DATA 0x00005244
-#define DDRSS_PI_244_DATA 0x2003001D
-#define DDRSS_PI_245_DATA 0x0A0A0A0A
+#define DDRSS_PI_236_DATA 0x11090000
+#define DDRSS_PI_237_DATA 0x1009000F
+#define DDRSS_PI_238_DATA 0x000062B8
+#define DDRSS_PI_239_DATA 0x20030023
+#define DDRSS_PI_240_DATA 0x0C0A0C0C
+#define DDRSS_PI_241_DATA 0x11090000
+#define DDRSS_PI_242_DATA 0x1009000F
+#define DDRSS_PI_243_DATA 0x000062B8
+#define DDRSS_PI_244_DATA 0x20030023
+#define DDRSS_PI_245_DATA 0x0C0A0C0C
 #define DDRSS_PI_246_DATA 0x00000000
 #define DDRSS_PI_247_DATA 0x00000176
 #define DDRSS_PI_248_DATA 0x00000E9C
-#define DDRSS_PI_249_DATA 0x00001440
-#define DDRSS_PI_250_DATA 0x0000CA80
-#define DDRSS_PI_251_DATA 0x00001440
-#define DDRSS_PI_252_DATA 0x0000CA80
-#define DDRSS_PI_253_DATA 0x01030014
-#define DDRSS_PI_254_DATA 0x03030103
+#define DDRSS_PI_249_DATA 0x00001850
+#define DDRSS_PI_250_DATA 0x0000F320
+#define DDRSS_PI_251_DATA 0x00001850
+#define DDRSS_PI_252_DATA 0x0000F320
+#define DDRSS_PI_253_DATA 0x01360014
+#define DDRSS_PI_254_DATA 0x03030136
 #define DDRSS_PI_255_DATA 0x00000003
 #define DDRSS_PI_256_DATA 0x00000000
 #define DDRSS_PI_257_DATA 0x05030503
@@ -701,23 +700,23 @@
 #define DDRSS_PI_261_DATA 0x00000005
 #define DDRSS_PI_262_DATA 0x00000064
 #define DDRSS_PI_263_DATA 0x00000014
-#define DDRSS_PI_264_DATA 0x000208D6
+#define DDRSS_PI_264_DATA 0x00027100
 #define DDRSS_PI_265_DATA 0x000186A0
 #define DDRSS_PI_266_DATA 0x00000005
-#define DDRSS_PI_267_DATA 0x00000536
-#define DDRSS_PI_268_DATA 0x00000103
-#define DDRSS_PI_269_DATA 0x000208D6
+#define DDRSS_PI_267_DATA 0x00000640
+#define DDRSS_PI_268_DATA 0x00000136
+#define DDRSS_PI_269_DATA 0x00027100
 #define DDRSS_PI_270_DATA 0x000186A0
 #define DDRSS_PI_271_DATA 0x00000005
-#define DDRSS_PI_272_DATA 0x00000536
-#define DDRSS_PI_273_DATA 0x01000103
+#define DDRSS_PI_272_DATA 0x00000640
+#define DDRSS_PI_273_DATA 0x01000136
 #define DDRSS_PI_274_DATA 0x00320040
 #define DDRSS_PI_275_DATA 0x00010008
-#define DDRSS_PI_276_DATA 0x029B0040
-#define DDRSS_PI_277_DATA 0x00010014
-#define DDRSS_PI_278_DATA 0x029B0040
-#define DDRSS_PI_279_DATA 0x00000314
-#define DDRSS_PI_280_DATA 0x00280021
+#define DDRSS_PI_276_DATA 0x03200040
+#define DDRSS_PI_277_DATA 0x00010018
+#define DDRSS_PI_278_DATA 0x03200040
+#define DDRSS_PI_279_DATA 0x00000318
+#define DDRSS_PI_280_DATA 0x00280028
 #define DDRSS_PI_281_DATA 0x03040404
 #define DDRSS_PI_282_DATA 0x00000303
 #define DDRSS_PI_283_DATA 0x02020101
@@ -745,7 +744,7 @@
 #define DDRSS_PI_305_DATA 0x00000000
 #define DDRSS_PI_306_DATA 0x00000024
 #define DDRSS_PI_307_DATA 0x00000012
-#define DDRSS_PI_308_DATA 0x00000031
+#define DDRSS_PI_308_DATA 0x000000B1
 #define DDRSS_PI_309_DATA 0x00000000
 #define DDRSS_PI_310_DATA 0x00000000
 #define DDRSS_PI_311_DATA 0x46000000
@@ -753,7 +752,7 @@
 #define DDRSS_PI_313_DATA 0x00000000
 #define DDRSS_PI_314_DATA 0x00000024
 #define DDRSS_PI_315_DATA 0x00000012
-#define DDRSS_PI_316_DATA 0x00000031
+#define DDRSS_PI_316_DATA 0x000000B1
 #define DDRSS_PI_317_DATA 0x00000000
 #define DDRSS_PI_318_DATA 0x00000000
 #define DDRSS_PI_319_DATA 0x46000000
@@ -769,7 +768,7 @@
 #define DDRSS_PI_329_DATA 0x00000000
 #define DDRSS_PI_330_DATA 0x00000024
 #define DDRSS_PI_331_DATA 0x00000012
-#define DDRSS_PI_332_DATA 0x00000031
+#define DDRSS_PI_332_DATA 0x000000B1
 #define DDRSS_PI_333_DATA 0x00000000
 #define DDRSS_PI_334_DATA 0x00000000
 #define DDRSS_PI_335_DATA 0x46000000
@@ -777,7 +776,7 @@
 #define DDRSS_PI_337_DATA 0x00000000
 #define DDRSS_PI_338_DATA 0x00000024
 #define DDRSS_PI_339_DATA 0x00000012
-#define DDRSS_PI_340_DATA 0x00000031
+#define DDRSS_PI_340_DATA 0x000000B1
 #define DDRSS_PI_341_DATA 0x00000000
 #define DDRSS_PI_342_DATA 0x00000000
 #define DDRSS_PI_343_DATA 0x46000000
@@ -869,29 +868,29 @@
 #define DDRSS_PHY_84_DATA 0x00100010
 #define DDRSS_PHY_85_DATA 0x00100010
 #define DDRSS_PHY_86_DATA 0x00100010
-#define DDRSS_PHY_87_DATA 0x02000010
+#define DDRSS_PHY_87_DATA 0x02020010
 #define DDRSS_PHY_88_DATA 0x51516041
 #define DDRSS_PHY_89_DATA 0x31C06000
 #define DDRSS_PHY_90_DATA 0x07AB0340
 #define DDRSS_PHY_91_DATA 0x0000C0C0
-#define DDRSS_PHY_92_DATA 0x03040000
-#define DDRSS_PHY_93_DATA 0x00000403
+#define DDRSS_PHY_92_DATA 0x04050000
+#define DDRSS_PHY_93_DATA 0x00000504
 #define DDRSS_PHY_94_DATA 0x42100010
 #define DDRSS_PHY_95_DATA 0x010C053E
-#define DDRSS_PHY_96_DATA 0x000F0C1A
+#define DDRSS_PHY_96_DATA 0x000F0C1D
 #define DDRSS_PHY_97_DATA 0x01000140
-#define DDRSS_PHY_98_DATA 0x00660120
+#define DDRSS_PHY_98_DATA 0x007A0120
 #define DDRSS_PHY_99_DATA 0x00000C00
-#define DDRSS_PHY_100_DATA 0x000001AA
+#define DDRSS_PHY_100_DATA 0x000001CC
 #define DDRSS_PHY_101_DATA 0x20100200
-#define DDRSS_PHY_102_DATA 0x00000004
+#define DDRSS_PHY_102_DATA 0x00000005
 #define DDRSS_PHY_103_DATA 0x76543210
 #define DDRSS_PHY_104_DATA 0x00000008
-#define DDRSS_PHY_105_DATA 0x032A032A
-#define DDRSS_PHY_106_DATA 0x032A032A
-#define DDRSS_PHY_107_DATA 0x032A032A
-#define DDRSS_PHY_108_DATA 0x032A032A
-#define DDRSS_PHY_109_DATA 0x0000032A
+#define DDRSS_PHY_105_DATA 0x034C034C
+#define DDRSS_PHY_106_DATA 0x034C034C
+#define DDRSS_PHY_107_DATA 0x034C034C
+#define DDRSS_PHY_108_DATA 0x034C034C
+#define DDRSS_PHY_109_DATA 0x0000034C
 #define DDRSS_PHY_110_DATA 0x00008000
 #define DDRSS_PHY_111_DATA 0x00800080
 #define DDRSS_PHY_112_DATA 0x00800080
@@ -901,7 +900,7 @@
 #define DDRSS_PHY_116_DATA 0x00800080
 #define DDRSS_PHY_117_DATA 0x00800080
 #define DDRSS_PHY_118_DATA 0x00800080
-#define DDRSS_PHY_119_DATA 0x01190080
+#define DDRSS_PHY_119_DATA 0x01800080
 #define DDRSS_PHY_120_DATA 0x01A00001
 #define DDRSS_PHY_121_DATA 0x00000000
 #define DDRSS_PHY_122_DATA 0x00000000
@@ -1125,29 +1124,29 @@
 #define DDRSS_PHY_340_DATA 0x00100010
 #define DDRSS_PHY_341_DATA 0x00100010
 #define DDRSS_PHY_342_DATA 0x00100010
-#define DDRSS_PHY_343_DATA 0x02000010
+#define DDRSS_PHY_343_DATA 0x02020010
 #define DDRSS_PHY_344_DATA 0x51516041
 #define DDRSS_PHY_345_DATA 0x31C06000
 #define DDRSS_PHY_346_DATA 0x07AB0340
 #define DDRSS_PHY_347_DATA 0x0000C0C0
-#define DDRSS_PHY_348_DATA 0x03040000
-#define DDRSS_PHY_349_DATA 0x00000403
+#define DDRSS_PHY_348_DATA 0x04050000
+#define DDRSS_PHY_349_DATA 0x00000504
 #define DDRSS_PHY_350_DATA 0x42100010
 #define DDRSS_PHY_351_DATA 0x010C053E
-#define DDRSS_PHY_352_DATA 0x000F0C1A
+#define DDRSS_PHY_352_DATA 0x000F0C1D
 #define DDRSS_PHY_353_DATA 0x01000140
-#define DDRSS_PHY_354_DATA 0x00660120
+#define DDRSS_PHY_354_DATA 0x007A0120
 #define DDRSS_PHY_355_DATA 0x00000C00
-#define DDRSS_PHY_356_DATA 0x000001AA
+#define DDRSS_PHY_356_DATA 0x000001CC
 #define DDRSS_PHY_357_DATA 0x20100200
-#define DDRSS_PHY_358_DATA 0x00000004
+#define DDRSS_PHY_358_DATA 0x00000005
 #define DDRSS_PHY_359_DATA 0x76543210
 #define DDRSS_PHY_360_DATA 0x00000008
-#define DDRSS_PHY_361_DATA 0x032A032A
-#define DDRSS_PHY_362_DATA 0x032A032A
-#define DDRSS_PHY_363_DATA 0x032A032A
-#define DDRSS_PHY_364_DATA 0x032A032A
-#define DDRSS_PHY_365_DATA 0x0000032A
+#define DDRSS_PHY_361_DATA 0x034C034C
+#define DDRSS_PHY_362_DATA 0x034C034C
+#define DDRSS_PHY_363_DATA 0x034C034C
+#define DDRSS_PHY_364_DATA 0x034C034C
+#define DDRSS_PHY_365_DATA 0x0000034C
 #define DDRSS_PHY_366_DATA 0x00008000
 #define DDRSS_PHY_367_DATA 0x00800080
 #define DDRSS_PHY_368_DATA 0x00800080
@@ -1157,7 +1156,7 @@
 #define DDRSS_PHY_372_DATA 0x00800080
 #define DDRSS_PHY_373_DATA 0x00800080
 #define DDRSS_PHY_374_DATA 0x00800080
-#define DDRSS_PHY_375_DATA 0x01190080
+#define DDRSS_PHY_375_DATA 0x01800080
 #define DDRSS_PHY_376_DATA 0x01A00001
 #define DDRSS_PHY_377_DATA 0x00000000
 #define DDRSS_PHY_378_DATA 0x00000000
@@ -1326,7 +1325,7 @@
 #define DDRSS_PHY_541_DATA 0x003F0000
 #define DDRSS_PHY_542_DATA 0x000F013F
 #define DDRSS_PHY_543_DATA 0x0000000F
-#define DDRSS_PHY_544_DATA 0x000002CC
+#define DDRSS_PHY_544_DATA 0x020002CC
 #define DDRSS_PHY_545_DATA 0x00030000
 #define DDRSS_PHY_546_DATA 0x00000300
 #define DDRSS_PHY_547_DATA 0x00000300
@@ -1582,7 +1581,7 @@
 #define DDRSS_PHY_797_DATA 0x00000000
 #define DDRSS_PHY_798_DATA 0x000F0000
 #define DDRSS_PHY_799_DATA 0x0000000F
-#define DDRSS_PHY_800_DATA 0x000002CC
+#define DDRSS_PHY_800_DATA 0x020002CC
 #define DDRSS_PHY_801_DATA 0x00030000
 #define DDRSS_PHY_802_DATA 0x00000300
 #define DDRSS_PHY_803_DATA 0x00000300
@@ -1838,7 +1837,7 @@
 #define DDRSS_PHY_1053_DATA 0x10000000
 #define DDRSS_PHY_1054_DATA 0x000F0000
 #define DDRSS_PHY_1055_DATA 0x0000000F
-#define DDRSS_PHY_1056_DATA 0x000002CC
+#define DDRSS_PHY_1056_DATA 0x020002CC
 #define DDRSS_PHY_1057_DATA 0x00030000
 #define DDRSS_PHY_1058_DATA 0x00000300
 #define DDRSS_PHY_1059_DATA 0x00000300
@@ -2116,7 +2115,7 @@
 #define DDRSS_PHY_1331_DATA 0x00004410
 #define DDRSS_PHY_1332_DATA 0x00000000
 #define DDRSS_PHY_1333_DATA 0x00000076
-#define DDRSS_PHY_1334_DATA 0x00010000
+#define DDRSS_PHY_1334_DATA 0x00000400
 #define DDRSS_PHY_1335_DATA 0x00000008
 #define DDRSS_PHY_1336_DATA 0x00000000
 #define DDRSS_PHY_1337_DATA 0x00000000
@@ -2154,7 +2153,7 @@
 #define DDRSS_PHY_1369_DATA 0x00000000
 #define DDRSS_PHY_1370_DATA 0x00000000
 #define DDRSS_PHY_1371_DATA 0x0001F7C0
-#define DDRSS_PHY_1372_DATA 0x00000002
+#define DDRSS_PHY_1372_DATA 0x00020002
 #define DDRSS_PHY_1373_DATA 0x00000000
 #define DDRSS_PHY_1374_DATA 0x00001142
 #define DDRSS_PHY_1375_DATA 0x03020000
@@ -2187,4 +2186,4 @@
 #define DDRSS_PHY_1402_DATA 0x019900E0
 #define DDRSS_PHY_1403_DATA 0x00018011
 #define DDRSS_PHY_1404_DATA 0x0089FF00
-#define DDRSS_PHY_1405_DATA 0x20040001
+#define DDRSS_PHY_1405_DATA 0x20040004
diff --git a/arch/arm/dts/k3-am642-r5-sk.dts b/arch/arm/dts/k3-am642-r5-sk.dts
index cf3ba0e..97f44e2 100644
--- a/arch/arm/dts/k3-am642-r5-sk.dts
+++ b/arch/arm/dts/k3-am642-r5-sk.dts
@@ -9,7 +9,7 @@
 #include <dt-bindings/phy/phy.h>
 #include <dt-bindings/net/ti-dp83867.h>
 #include "k3-am642.dtsi"
-#include "k3-am64-sk-lp4-1333MTs.dtsi"
+#include "k3-am64-sk-lp4-1600MTs.dtsi"
 #include "k3-am64-ddr.dtsi"
 
 / {
diff --git a/arch/arm/dts/stm32mp15-scmi.dtsi b/arch/arm/dts/stm32mp15-scmi.dtsi
index 37d4547..543f24c 100644
--- a/arch/arm/dts/stm32mp15-scmi.dtsi
+++ b/arch/arm/dts/stm32mp15-scmi.dtsi
@@ -103,7 +103,3 @@
 /delete-node/ &clk_lse;
 /delete-node/ &clk_lsi;
 /delete-node/ &clk_csi;
-/delete-node/ &reg11;
-/delete-node/ &reg18;
-/delete-node/ &usb33;
-/delete-node/ &pwr_regulators;
diff --git a/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi b/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi
index 8a7156c..b72a2f6 100644
--- a/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp15xx-dhcom-u-boot.dtsi
@@ -190,6 +190,21 @@
 		CLK_LPTIM45_LSE
 	>;
 
+	/*
+	 * cfg = < DIVM1 DIVN P Q R PQR(p,q,r) >;
+	 * frac = < f >;
+	 *
+	 * PRQ(p,q,r) ... for p,q,r: 0-output disabled / 1-output enabled
+	 * DIVN ... actually multiplier, but RCC_PLL1CFGR1 calls the field DIVN
+	 * m ... for PLL1,2: m=2 ; for PLL3,4: m=1
+	 * XTAL = 24 MHz
+	 *
+	 * VCO = ( XTAL / (DIVM1 + 1) ) * m * ( DIVN + 1 + ( f / 8192 ) )
+	 *   P = VCO / (P + 1)
+	 *   Q = VCO / (Q + 1)
+	 *   R = VCO / (R + 1)
+	 */
+
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
@@ -208,7 +223,7 @@
 		u-boot,dm-pre-reloc;
 	};
 
-	/* VCO = 600.0 MHz => P = 50, Q = 50, R = 50 */
+	/* VCO = 600.0 MHz => P = 100, Q = 50, R = 50 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
diff --git a/arch/arm/dts/stm32mp15xx-dhcor-avenger96-u-boot.dtsi b/arch/arm/dts/stm32mp15xx-dhcor-avenger96-u-boot.dtsi
index 5bed53e..6dee51d 100644
--- a/arch/arm/dts/stm32mp15xx-dhcor-avenger96-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp15xx-dhcor-avenger96-u-boot.dtsi
@@ -19,7 +19,6 @@
 	};
 };
 
-
 &ethernet0 {
 	phy-reset-gpios = <&gpioz 2 GPIO_ACTIVE_LOW>;
 
@@ -102,6 +101,10 @@
 	hnp-srp-disable;
 };
 
+&vdd {
+	/delete-property/ regulator-always-on;
+};
+
 &vdd_io {
 	u-boot,dm-spl;
 };
diff --git a/arch/arm/dts/stm32mp15xx-dhcor-testbench-u-boot.dtsi b/arch/arm/dts/stm32mp15xx-dhcor-testbench-u-boot.dtsi
new file mode 100644
index 0000000..5b051b8
--- /dev/null
+++ b/arch/arm/dts/stm32mp15xx-dhcor-testbench-u-boot.dtsi
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2022 Marek Vasut <marex@denx.de>
+ */
+
+#include "stm32mp15xx-dhcor-u-boot.dtsi"
+
+/ {
+	aliases {
+		mmc0 = &sdmmc1;
+		mmc1 = &sdmmc2;
+		usb0 = &usbotg_hs;
+	};
+
+	config {
+		dh,board-coding-gpios = <&gpiog 13 0>, <&gpiod 9 0>;
+	};
+};
+
+&ethernet0 {
+	phy-reset-gpios = <&gpioz 2 GPIO_ACTIVE_LOW>;
+
+	mdio0 {
+		ethernet-phy@7 {
+			reset-gpios = <&gpioz 2 GPIO_ACTIVE_LOW>;
+			reset-assert-us = <11000>;
+			reset-deassert-us = <1000>;
+		};
+	};
+};
+
+&sdmmc1 {
+	u-boot,dm-spl;
+	st,use-ckin;
+	st,cmd-gpios = <&gpiod 2 0>;
+	st,ck-gpios = <&gpioc 12 0>;
+	st,ckin-gpios = <&gpioe 4 0>;
+};
+
+&sdmmc1_b4_pins_a {
+	u-boot,dm-spl;
+	pins1 {
+		u-boot,dm-spl;
+	};
+	pins2 {
+		u-boot,dm-spl;
+	};
+};
+
+&sdmmc1_dir_pins_b {
+	u-boot,dm-spl;
+	pins1 {
+		u-boot,dm-spl;
+	};
+	pins2 {
+		u-boot,dm-spl;
+	};
+};
+
+&sdmmc2 {
+	u-boot,dm-spl;
+};
+
+&sdmmc2_b4_pins_a {
+	u-boot,dm-spl;
+	pins1 {
+		u-boot,dm-spl;
+	};
+	pins2 {
+		u-boot,dm-spl;
+	};
+};
+
+&sdmmc2_d47_pins_c {
+	u-boot,dm-spl;
+	pins {
+		u-boot,dm-spl;
+	};
+};
+
+&uart4 {
+	u-boot,dm-pre-reloc;
+};
+
+&uart4_pins_b {
+	u-boot,dm-pre-reloc;
+	pins1 {
+		u-boot,dm-pre-reloc;
+	};
+	pins2 {
+		u-boot,dm-pre-reloc;
+		/delete-property/ bias-disable;
+		bias-pull-up;
+	};
+};
+
+&usbotg_hs {
+	u-boot,force-b-session-valid;
+	hnp-srp-disable;
+};
diff --git a/arch/arm/dts/stm32mp15xx-dhcor-testbench.dts b/arch/arm/dts/stm32mp15xx-dhcor-testbench.dts
new file mode 100644
index 0000000..c9163e1
--- /dev/null
+++ b/arch/arm/dts/stm32mp15xx-dhcor-testbench.dts
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+/*
+ * Copyright (C) 2022 Marek Vasut <marex@denx.de>
+ */
+/dts-v1/;
+
+#include "stm32mp151.dtsi"
+#include "stm32mp15xx-dhcor-som.dtsi"
+
+/ {
+	model = "DH electronics STM32MP15xx DHCOR Testbench";
+	compatible = "dh,stm32mp15xx-dhcor-testbench", "st,stm32mp1xx";
+
+	aliases {
+		ethernet0 = &ethernet0;
+		mmc0 = &sdmmc1;
+		mmc1 = &sdmmc2;
+		serial0 = &uart4;
+		serial1 = &uart7;
+		spi0 = &qspi;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	sd_switch: regulator-sd_switch {
+		compatible = "regulator-gpio";
+		regulator-name = "sd_switch";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <2900000>;
+		regulator-type = "voltage";
+		regulator-always-on;
+
+		gpios = <&gpioi 5 GPIO_ACTIVE_HIGH>;
+		gpios-states = <0>;
+		states = <1800000 0x1>,
+			 <2900000 0x0>;
+	};
+};
+
+&adc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&adc12_ain_pins_b>;
+	vdd-supply = <&vdd>;
+	vdda-supply = <&vdda>;
+	vref-supply = <&vdda>;
+	status = "okay";
+
+	adc1: adc@0 {
+		st,adc-channels = <0 1 6>;
+		st,min-sample-time-nsecs = <5000>;
+		status = "okay";
+	};
+
+	adc2: adc@100 {
+		st,adc-channels = <0 1 2>;
+		st,min-sample-time-nsecs = <5000>;
+		status = "okay";
+	};
+};
+
+&ethernet0 {
+	status = "okay";
+	pinctrl-0 = <&ethernet0_rgmii_pins_c>;
+	pinctrl-1 = <&ethernet0_rgmii_sleep_pins_c>;
+	pinctrl-names = "default", "sleep";
+	phy-mode = "rgmii";
+	max-speed = <1000>;
+	phy-handle = <&phy0>;
+
+	mdio0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "snps,dwmac-mdio";
+		reset-gpios = <&gpioz 2 GPIO_ACTIVE_LOW>;
+		reset-delay-us = <1000>;
+
+		phy0: ethernet-phy@7 {
+			reg = <7>;
+
+			rxc-skew-ps = <1500>;
+			rxdv-skew-ps = <540>;
+			rxd0-skew-ps = <420>;
+			rxd1-skew-ps = <420>;
+			rxd2-skew-ps = <420>;
+			rxd3-skew-ps = <420>;
+
+			txc-skew-ps = <1440>;
+			txen-skew-ps = <540>;
+			txd0-skew-ps = <420>;
+			txd1-skew-ps = <420>;
+			txd2-skew-ps = <420>;
+			txd3-skew-ps = <420>;
+		};
+	};
+};
+
+&sdmmc1 {
+	pinctrl-names = "default", "opendrain", "sleep";
+	pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_b>;
+	pinctrl-1 = <&sdmmc1_b4_od_pins_a &sdmmc1_dir_pins_b>;
+	pinctrl-2 = <&sdmmc1_b4_sleep_pins_a &sdmmc1_dir_sleep_pins_b>;
+	cd-gpios = <&gpioi 8 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+	disable-wp;
+	st,sig-dir;
+	st,neg-edge;
+	st,use-ckin;
+	bus-width = <4>;
+	vmmc-supply = <&vdd_sd>;
+	vqmmc-supply = <&sd_switch>;
+	status = "okay";
+};
+
+&sdmmc2 {
+	pinctrl-names = "default", "opendrain", "sleep";
+	pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_c>;
+	pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_c>;
+	pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_c>;
+	bus-width = <8>;
+	mmc-ddr-1_8v;
+	no-sd;
+	no-sdio;
+	non-removable;
+	st,neg-edge;
+	vmmc-supply = <&v3v3>;
+	vqmmc-supply = <&v3v3>;
+	status = "okay";
+};
+
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart4_pins_b>;
+	/delete-property/dmas;
+	/delete-property/dma-names;
+	status = "okay";
+};
+
+&uart7 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart7_pins_a>;
+	uart-has-rtscts;
+	/delete-property/dmas;
+	/delete-property/dma-names;
+	status = "okay";
+};
+
+&usbh_ehci {
+	phys = <&usbphyc_port0>;
+	phy-names = "usb";
+	status = "okay";
+};
+
+&usbotg_hs {
+	pinctrl-0 = <&usbotg_hs_pins_a>;
+	pinctrl-names = "default";
+	phy-names = "usb2-phy";
+	phys = <&usbphyc_port1 0>;
+	status = "okay";
+	vbus-supply = <&vbus_otg>;
+};
+
+&usbphyc {
+	status = "okay";
+};
+
+&usbphyc_port0 {
+	phy-supply = <&vdd_usb>;
+};
+
+&usbphyc_port1 {
+	phy-supply = <&vdd_usb>;
+};
+
+&vdd {
+	/delete-property/ regulator-always-on;
+	regulator-min-microvolt = <1200000>;
+};
diff --git a/arch/arm/dts/stm32mp15xx-dhcor-u-boot.dtsi b/arch/arm/dts/stm32mp15xx-dhcor-u-boot.dtsi
index 19f4221..25a288b 100644
--- a/arch/arm/dts/stm32mp15xx-dhcor-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp15xx-dhcor-u-boot.dtsi
@@ -144,6 +144,21 @@
 		CLK_LPTIM45_LSE
 	>;
 
+	/*
+	 * cfg = < DIVM1 DIVN P Q R PQR(p,q,r) >;
+	 * frac = < f >;
+	 *
+	 * PRQ(p,q,r) ... for p,q,r: 0-output disabled / 1-output enabled
+	 * DIVN ... actually multiplier, but RCC_PLL1CFGR1 calls the field DIVN
+	 * m ... for PLL1,2: m=2 ; for PLL3,4: m=1
+	 * XTAL = 24 MHz
+	 *
+	 * VCO = ( XTAL / (DIVM1 + 1) ) * m * ( DIVN + 1 + ( f / 8192 ) )
+	 *   P = VCO / (P + 1)
+	 *   Q = VCO / (Q + 1)
+	 *   R = VCO / (R + 1)
+	 */
+
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
@@ -162,7 +177,7 @@
 		u-boot,dm-pre-reloc;
 	};
 
-	/* VCO = 600.0 MHz => P = 99, Q = 74, R = 99 */
+	/* VCO = 594.0 MHz => P = 99, Q = 74, R = 99 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
diff --git a/arch/arm/mach-k3/am642_init.c b/arch/arm/mach-k3/am642_init.c
index 8428322..0e30cc4 100644
--- a/arch/arm/mach-k3/am642_init.c
+++ b/arch/arm/mach-k3/am642_init.c
@@ -23,7 +23,6 @@
 #include <mmc.h>
 #include <dm/root.h>
 
-#define MCU_CTRL_MMR0_BASE			0x04500000
 #define CTRLMMR_MCU_RST_CTRL			0x04518170
 
 static void ctrl_mmr_unlock(void)
diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c
index 14c37ac..227706e 100644
--- a/arch/arm/mach-k3/common.c
+++ b/arch/arm/mach-k3/common.c
@@ -606,5 +606,9 @@
 			printf("Failed to probe am65_cpsw_nuss driver\n");
 	}
 
+	/* Default FIT boot on non-GP devices */
+	if (get_device_type() != K3_DEVICE_TYPE_GP)
+		env_set("boot_fit", "1");
+
 	return 0;
 }
diff --git a/arch/arm/mach-k3/include/mach/am62_hardware.h b/arch/arm/mach-k3/include/mach/am62_hardware.h
index 9118d05..278beb5 100644
--- a/arch/arm/mach-k3/include/mach/am62_hardware.h
+++ b/arch/arm/mach-k3/include/mach/am62_hardware.h
@@ -44,23 +44,6 @@
 /* Backup Bootmode USB Config macros */
 #define MAIN_DEVSTAT_BACKUP_USB_MODE_MASK	0x01
 
-/*
- * The CTRL_MMR0 memory space is divided into several equally-spaced
- * partitions, so defining the partition size allows us to determine
- * register addresses common to those partitions.
- */
-#define CTRL_MMR0_PARTITION_SIZE		0x4000
-
-/*
- * CTRL_MMR0, WKUP_CTRL_MMR0, and MCU_CTRL_MMR0 lock/kick-mechanism
- * shared register definitions. The same registers are also used for
- * PADCFG_MMR lock/kick-mechanism.
- */
-#define CTRLMMR_LOCK_KICK0			0x1008
-#define CTRLMMR_LOCK_KICK0_UNLOCK_VAL		0x68ef3490
-#define CTRLMMR_LOCK_KICK1			0x100c
-#define CTRLMMR_LOCK_KICK1_UNLOCK_VAL		0xd172bc5a
-
 #define MCU_CTRL_LFXOSC_CTRL			(MCU_CTRL_MMR0_BASE + 0x8038)
 #define MCU_CTRL_LFXOSC_TRIM			(MCU_CTRL_MMR0_BASE + 0x803c)
 #define MCU_CTRL_LFXOSC_32K_DISABLE_VAL		BIT(7)
diff --git a/arch/arm/mach-k3/include/mach/am64_hardware.h b/arch/arm/mach-k3/include/mach/am64_hardware.h
index e06e1f9..6c9332e 100644
--- a/arch/arm/mach-k3/include/mach/am64_hardware.h
+++ b/arch/arm/mach-k3/include/mach/am64_hardware.h
@@ -7,12 +7,13 @@
 #ifndef __ASM_ARCH_AM64_HARDWARE_H
 #define __ASM_ARCH_AM64_HARDWARE_H
 
-#define CTRL_MMR0_BASE					0x43000000
-#define CTRLMMR_MAIN_DEVSTAT				(CTRL_MMR0_BASE + 0x30)
-
-#define PADCFG_MMR1_BASE				0xf0000
-
+#define PADCFG_MMR1_BASE				0x000f0000
 #define MCU_PADCFG_MMR1_BASE				0x04080000
+#define WKUP_CTRL_MMR0_BASE				0x43000000
+#define MCU_CTRL_MMR0_BASE				0x04500000
+#define CTRL_MMR0_BASE					0x43000000
+
+#define CTRLMMR_MAIN_DEVSTAT				(CTRL_MMR0_BASE + 0x30)
 
 #define MAIN_DEVSTAT_PRIMARY_BOOTMODE_MASK		0x00000078
 #define MAIN_DEVSTAT_PRIMARY_BOOTMODE_SHIFT		3
@@ -35,23 +36,6 @@
 
 #define MAIN_DEVSTAT_BACKUP_USB_MODE_MASK		0x01
 
-/*
- * The CTRL_MMR and PADCFG_MMR memory space is divided into several
- * equally-spaced partitions, so defining the partition size allows us to
- * determine register addresses common to those partitions.
- */
-#define CTRL_MMR0_PARTITION_SIZE			0x4000
-
-/*
- * CTRL_MMR and PADCFG_MMR lock/kick-mechanism shared register definitions.
- */
-#define CTRLMMR_LOCK_KICK0				0x01008
-#define CTRLMMR_LOCK_KICK0_UNLOCK_VAL			0x68ef3490
-#define CTRLMMR_LOCK_KICK0_UNLOCKED_MASK		BIT(0)
-#define CTRLMMR_LOCK_KICK0_UNLOCKED_SHIFT		0
-#define CTRLMMR_LOCK_KICK1				0x0100c
-#define CTRLMMR_LOCK_KICK1_UNLOCK_VAL			0xd172bc5a
-
 #define ROM_ENTENDED_BOOT_DATA_INFO			0x701beb00
 
 /* Use Last 2K as Scratch pad */
diff --git a/arch/arm/mach-k3/include/mach/am6_hardware.h b/arch/arm/mach-k3/include/mach/am6_hardware.h
index f533e22..f9f3291 100644
--- a/arch/arm/mach-k3/include/mach/am6_hardware.h
+++ b/arch/arm/mach-k3/include/mach/am6_hardware.h
@@ -13,8 +13,10 @@
 #endif
 
 #define CTRL_MMR0_BASE					0x00100000
-#define CTRLMMR_MAIN_DEVSTAT				(CTRL_MMR0_BASE + 0x30)
+#define WKUP_CTRL_MMR0_BASE				0x43000000
+#define MCU_CTRL_MMR0_BASE				0x40f00000
 
+#define CTRLMMR_MAIN_DEVSTAT				(CTRL_MMR0_BASE + 0x30)
 #define CTRLMMR_MAIN_DEVSTAT_BOOTMODE_MASK		GENMASK(3, 0)
 #define CTRLMMR_MAIN_DEVSTAT_BOOTMODE_SHIFT		0
 #define CTRLMMR_MAIN_DEVSTAT_BKUP_BOOTMODE_MASK		GENMASK(6, 4)
@@ -28,27 +30,6 @@
 #define CTRLMMR_MAIN_DEVSTAT_USB_MODE_SHIFT		9
 #define CTRLMMR_MAIN_DEVSTAT_USB_MODE_MASK		GENMASK(10, 9)
 
-#define WKUP_CTRL_MMR0_BASE				0x43000000
-#define MCU_CTRL_MMR0_BASE				0x40f00000
-
-/*
- * The CTRL_MMR0 memory space is divided into several equally-spaced
- * partitions, so defining the partition size allows us to determine
- * register addresses common to those partitions.
- */
-#define CTRL_MMR0_PARTITION_SIZE			0x4000
-
-/*
- * CTRL_MMR0, WKUP_CTRL_MMR0, and MCU_CTR_MMR0 lock/kick-mechanism
- * shared register definitions.
- */
-#define CTRLMMR_LOCK_KICK0				0x01008
-#define CTRLMMR_LOCK_KICK0_UNLOCK_VAL			0x68ef3490
-#define CTRLMMR_LOCK_KICK0_UNLOCKED_MASK		BIT(0)
-#define CTRLMMR_LOCK_KICK0_UNLOCKED_SHIFT		0
-#define CTRLMMR_LOCK_KICK1				0x0100c
-#define CTRLMMR_LOCK_KICK1_UNLOCK_VAL			0xd172bc5a
-
 /* MCU SCRATCHPAD usage */
 #define TI_SRAM_SCRATCH_BOARD_EEPROM_START CONFIG_SYS_K3_MCU_SCRATCHPAD_BASE
 
diff --git a/arch/arm/mach-k3/include/mach/hardware.h b/arch/arm/mach-k3/include/mach/hardware.h
index 028482b..d6d2cf6 100644
--- a/arch/arm/mach-k3/include/mach/hardware.h
+++ b/arch/arm/mach-k3/include/mach/hardware.h
@@ -27,7 +27,7 @@
 #endif
 
 /* Assuming these addresses and definitions stay common across K3 devices */
-#define CTRLMMR_WKUP_JTAG_ID	0x43000014
+#define CTRLMMR_WKUP_JTAG_ID	(WKUP_CTRL_MMR0_BASE + 0x14)
 #define JTAG_ID_VARIANT_SHIFT	28
 #define JTAG_ID_VARIANT_MASK	(0xf << 28)
 #define JTAG_ID_PARTNO_SHIFT	12
@@ -43,6 +43,23 @@
 #define SYS_STATUS_SUB_TYPE_MASK	(0xf << 8)
 #define SYS_STATUS_SUB_TYPE_VAL_FS	0xa
 
+/*
+ * The CTRL_MMR0 memory space is divided into several equally-spaced
+ * partitions, so defining the partition size allows us to determine
+ * register addresses common to those partitions.
+ */
+#define CTRL_MMR0_PARTITION_SIZE		0x4000
+
+/*
+ * CTRL_MMR0, WKUP_CTRL_MMR0, and MCU_CTRL_MMR0 lock/kick-mechanism
+ * shared register definitions. The same registers are also used for
+ * PADCFG_MMR lock/kick-mechanism.
+ */
+#define CTRLMMR_LOCK_KICK0			0x1008
+#define CTRLMMR_LOCK_KICK0_UNLOCK_VAL		0x68ef3490
+#define CTRLMMR_LOCK_KICK1			0x100c
+#define CTRLMMR_LOCK_KICK1_UNLOCK_VAL		0xd172bc5a
+
 #define K3_ROM_BOOT_HEADER_MAGIC	"EXTBOOT"
 
 struct rom_extended_boot_data {
diff --git a/arch/arm/mach-k3/include/mach/j721e_hardware.h b/arch/arm/mach-k3/include/mach/j721e_hardware.h
index b98f0a8..032cb26 100644
--- a/arch/arm/mach-k3/include/mach/j721e_hardware.h
+++ b/arch/arm/mach-k3/include/mach/j721e_hardware.h
@@ -12,9 +12,11 @@
 #include <linux/bitops.h>
 #endif
 
+#define WKUP_CTRL_MMR0_BASE				0x43000000
+#define MCU_CTRL_MMR0_BASE				0x40f00000
 #define CTRL_MMR0_BASE					0x00100000
-#define CTRLMMR_MAIN_DEVSTAT				(CTRL_MMR0_BASE + 0x30)
 
+#define CTRLMMR_MAIN_DEVSTAT				(CTRL_MMR0_BASE + 0x30)
 #define MAIN_DEVSTAT_BOOT_MODE_B_MASK		BIT(0)
 #define MAIN_DEVSTAT_BOOT_MODE_B_SHIFT		0
 #define MAIN_DEVSTAT_BKUP_BOOTMODE_MASK		GENMASK(3, 1)
@@ -24,33 +26,12 @@
 #define MAIN_DEVSTAT_BKUP_MMC_PORT_MASK			BIT(7)
 #define MAIN_DEVSTAT_BKUP_MMC_PORT_SHIFT		7
 
-#define WKUP_CTRL_MMR0_BASE				0x43000000
-#define MCU_CTRL_MMR0_BASE				0x40f00000
-
 #define CTRLMMR_WKUP_DEVSTAT			(WKUP_CTRL_MMR0_BASE + 0x30)
 #define WKUP_DEVSTAT_PRIMARY_BOOTMODE_MASK	GENMASK(5, 3)
 #define WKUP_DEVSTAT_PRIMARY_BOOTMODE_SHIFT	3
 #define WKUP_DEVSTAT_MCU_OMLY_MASK		BIT(6)
 #define WKUP_DEVSTAT_MCU_ONLY_SHIFT		6
 
-/*
- * The CTRL_MMR0 memory space is divided into several equally-spaced
- * partitions, so defining the partition size allows us to determine
- * register addresses common to those partitions.
- */
-#define CTRL_MMR0_PARTITION_SIZE			0x4000
-
-/*
- * CTRL_MMR0, WKUP_CTRL_MMR0, and MCU_CTR_MMR0 lock/kick-mechanism
- * shared register definitions.
- */
-#define CTRLMMR_LOCK_KICK0				0x01008
-#define CTRLMMR_LOCK_KICK0_UNLOCK_VAL			0x68ef3490
-#define CTRLMMR_LOCK_KICK0_UNLOCKED_MASK		BIT(0)
-#define CTRLMMR_LOCK_KICK0_UNLOCKED_SHIFT		0
-#define CTRLMMR_LOCK_KICK1				0x0100c
-#define CTRLMMR_LOCK_KICK1_UNLOCK_VAL			0xd172bc5a
-
 /* ROM HANDOFF Structure location */
 #define ROM_ENTENDED_BOOT_DATA_INFO			0x41cffb00
 
diff --git a/arch/arm/mach-k3/include/mach/j721s2_hardware.h b/arch/arm/mach-k3/include/mach/j721s2_hardware.h
index 23dfe2e..e47f40e 100644
--- a/arch/arm/mach-k3/include/mach/j721s2_hardware.h
+++ b/arch/arm/mach-k3/include/mach/j721s2_hardware.h
@@ -12,9 +12,11 @@
 #include <linux/bitops.h>
 #endif
 
+#define WKUP_CTRL_MMR0_BASE				0x43000000
+#define MCU_CTRL_MMR0_BASE				0x40f00000
 #define CTRL_MMR0_BASE					0x00100000
-#define CTRLMMR_MAIN_DEVSTAT				(CTRL_MMR0_BASE + 0x30)
 
+#define CTRLMMR_MAIN_DEVSTAT				(CTRL_MMR0_BASE + 0x30)
 #define MAIN_DEVSTAT_BOOT_MODE_B_MASK			BIT(0)
 #define MAIN_DEVSTAT_BOOT_MODE_B_SHIFT			0
 #define MAIN_DEVSTAT_BKUP_BOOTMODE_MASK			GENMASK(3, 1)
@@ -24,33 +26,12 @@
 #define MAIN_DEVSTAT_BKUP_MMC_PORT_MASK			BIT(7)
 #define MAIN_DEVSTAT_BKUP_MMC_PORT_SHIFT		7
 
-#define WKUP_CTRL_MMR0_BASE				0x43000000
-#define MCU_CTRL_MMR0_BASE				0x40f00000
-
 #define CTRLMMR_WKUP_DEVSTAT				(WKUP_CTRL_MMR0_BASE + 0x30)
 #define WKUP_DEVSTAT_PRIMARY_BOOTMODE_MASK		GENMASK(5, 3)
 #define WKUP_DEVSTAT_PRIMARY_BOOTMODE_SHIFT		3
 #define WKUP_DEVSTAT_MCU_OMLY_MASK			BIT(6)
 #define WKUP_DEVSTAT_MCU_ONLY_SHIFT			6
 
-/*
- * The CTRL_MMR0 memory space is divided into several equally-spaced
- * partitions, so defining the partition size allows us to determine
- * register addresses common to those partitions.
- */
-#define CTRL_MMR0_PARTITION_SIZE			0x4000
-
-/*
- * CTRL_MMR0, WKUP_CTRL_MMR0, and MCU_CTR_MMR0 lock/kick-mechanism
- * shared register definitions.
- */
-#define CTRLMMR_LOCK_KICK0				0x01008
-#define CTRLMMR_LOCK_KICK0_UNLOCK_VAL			0x68ef3490
-#define CTRLMMR_LOCK_KICK0_UNLOCKED_MASK		BIT(0)
-#define CTRLMMR_LOCK_KICK0_UNLOCKED_SHIFT		0
-#define CTRLMMR_LOCK_KICK1				0x0100c
-#define CTRLMMR_LOCK_KICK1_UNLOCK_VAL			0xd172bc5a
-
 /* ROM HANDOFF Structure location */
 #define ROM_ENTENDED_BOOT_DATA_INFO			0x41cfdb00
 
diff --git a/arch/arm/mach-k3/j721s2_init.c b/arch/arm/mach-k3/j721s2_init.c
index 12da813..dd0c7ba 100644
--- a/arch/arm/mach-k3/j721s2_init.c
+++ b/arch/arm/mach-k3/j721s2_init.c
@@ -164,7 +164,7 @@
 		if (ret)
 			panic("DRAM 0 init failed: %d\n", ret);
 
-		ret = uclass_next_device(&dev);
+		ret = uclass_next_device_err(&dev);
 		if (ret)
 			panic("DRAM 1 init failed: %d\n", ret);
 	}
diff --git a/arch/arm/mach-k3/security.c b/arch/arm/mach-k3/security.c
index d8d41ec..092588f 100644
--- a/arch/arm/mach-k3/security.c
+++ b/arch/arm/mach-k3/security.c
@@ -18,6 +18,7 @@
 #include <mach/spl.h>
 #include <spl.h>
 #include <asm/arch/sys_proto.h>
+#include <linux/dma-mapping.h>
 
 #include "common.h"
 
@@ -47,7 +48,6 @@
 	u32 image_size;
 	int ret;
 
-	image_addr = (uintptr_t)*p_image;
 	image_size = *p_size;
 
 	if (!image_size)
@@ -80,13 +80,12 @@
 		return;
 	}
 
+	/* Clean out image so it can be seen by system firmware */
+	image_addr = dma_map_single(*p_image, *p_size, DMA_BIDIRECTIONAL);
+
 	debug("Authenticating image at address 0x%016llx\n", image_addr);
 	debug("Authenticating image of size %d bytes\n", image_size);
 
-	flush_dcache_range((unsigned long)image_addr,
-			   ALIGN((unsigned long)image_addr + image_size,
-				 ARCH_DMA_MINALIGN));
-
 	/* Authenticate image */
 	ret = proc_ops->proc_auth_boot_image(ti_sci, &image_addr, &image_size);
 	if (ret) {
@@ -94,10 +93,9 @@
 		hang();
 	}
 
+	/* Invalidate any stale lines over data written by system firmware */
 	if (image_size)
-		invalidate_dcache_range((unsigned long)image_addr,
-					ALIGN((unsigned long)image_addr +
-					      image_size, ARCH_DMA_MINALIGN));
+		dma_unmap_single(image_addr, image_size, DMA_BIDIRECTIONAL);
 
 	/*
 	 * The image_size returned may be 0 when the authentication process has
diff --git a/arch/arm/mach-omap2/am33xx/board.c b/arch/arm/mach-omap2/am33xx/board.c
index 7f1b84e..f393ff9 100644
--- a/arch/arm/mach-omap2/am33xx/board.c
+++ b/arch/arm/mach-omap2/am33xx/board.c
@@ -265,8 +265,8 @@
 	struct udevice *dev;
 	int ret;
 
-	ret = uclass_first_device(UCLASS_MISC, &dev);
-	if (ret || !dev)
+	ret = uclass_first_device_err(UCLASS_MISC, &dev);
+	if (ret)
 		return ret;
 
 #if defined(CONFIG_DM_ETH) && defined(CONFIG_USB_ETHER)
diff --git a/arch/arm/mach-stm32mp/Kconfig.15x b/arch/arm/mach-stm32mp/Kconfig.15x
index d516270..5bd9b53 100644
--- a/arch/arm/mach-stm32mp/Kconfig.15x
+++ b/arch/arm/mach-stm32mp/Kconfig.15x
@@ -117,7 +117,7 @@
 if DEBUG_UART
 
 config DEBUG_UART_BOARD_INIT
-	default y
+	default y if SPL
 
 # debug on UART4 by default
 config DEBUG_UART_BASE
diff --git a/arch/sandbox/lib/bootm.c b/arch/sandbox/lib/bootm.c
index c1742f9..28f4a74 100644
--- a/arch/sandbox/lib/bootm.c
+++ b/arch/sandbox/lib/bootm.c
@@ -50,8 +50,25 @@
 	return ret;
 }
 
+/* Subcommand: PREP */
+static int boot_prep_linux(struct bootm_headers *images)
+{
+	int ret;
+
+	if (CONFIG_IS_ENABLED(LMB)) {
+		ret = image_setup_linux(images);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 int do_bootm_linux(int flag, int argc, char *argv[], struct bootm_headers *images)
 {
+	if (flag & BOOTM_STATE_OS_PREP)
+		return boot_prep_linux(images);
+
 	if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) {
 		bootstage_mark(BOOTSTAGE_ID_RUN_OS);
 		printf("## Transferring control to Linux (at address %08lx)...\n",
diff --git a/arch/x86/cpu/broadwell/cpu.c b/arch/x86/cpu/broadwell/cpu.c
index 2adcf4b..7877961 100644
--- a/arch/x86/cpu/broadwell/cpu.c
+++ b/arch/x86/cpu/broadwell/cpu.c
@@ -31,11 +31,9 @@
 	int ret;
 
 	/* Start up the LPC so we have serial */
-	ret = uclass_first_device(UCLASS_LPC, &dev);
+	ret = uclass_first_device_err(UCLASS_LPC, &dev);
 	if (ret)
 		return ret;
-	if (!dev)
-		return -ENODEV;
 	ret = cpu_set_flex_ratio_to_tdp_nominal();
 	if (ret)
 		return ret;
diff --git a/arch/x86/cpu/intel_common/cpu.c b/arch/x86/cpu/intel_common/cpu.c
index 96d05e2..8f489e6 100644
--- a/arch/x86/cpu/intel_common/cpu.c
+++ b/arch/x86/cpu/intel_common/cpu.c
@@ -61,11 +61,9 @@
 	/* Early chipset init required before RAM init can work */
 	uclass_first_device(UCLASS_NORTHBRIDGE, &dev);
 
-	ret = uclass_first_device(UCLASS_LPC, &lpc);
+	ret = uclass_first_device_err(UCLASS_LPC, &lpc);
 	if (ret)
 		return ret;
-	if (!lpc)
-		return -ENODEV;
 
 	/* Cause the SATA device to do its early init */
 	uclass_first_device(UCLASS_AHCI, &dev);
diff --git a/arch/x86/lib/pinctrl_ich6.c b/arch/x86/lib/pinctrl_ich6.c
index fd5e311..c93f245 100644
--- a/arch/x86/lib/pinctrl_ich6.c
+++ b/arch/x86/lib/pinctrl_ich6.c
@@ -160,11 +160,9 @@
 	u32 iobase = -1;
 
 	debug("%s: start\n", __func__);
-	ret = uclass_first_device(UCLASS_PCH, &pch);
+	ret = uclass_first_device_err(UCLASS_PCH, &pch);
 	if (ret)
 		return ret;
-	if (!pch)
-		return -ENODEV;
 
 	/*
 	 * Get the memory/io base address to configure every pins.
diff --git a/board/atmel/common/mac_eeprom.c b/board/atmel/common/mac_eeprom.c
index a723ba7..4606008 100644
--- a/board/atmel/common/mac_eeprom.c
+++ b/board/atmel/common/mac_eeprom.c
@@ -56,7 +56,7 @@
 		return ret;
 
 	/* attempt to obtain a second eeprom device */
-	ret = uclass_next_device(&dev);
+	ret = uclass_next_device_err(&dev);
 	if (ret)
 		return ret;
 
diff --git a/board/dhelectronics/dh_stm32mp1/board.c b/board/dhelectronics/dh_stm32mp1/board.c
index 2bc0d7b..8d8104a 100644
--- a/board/dhelectronics/dh_stm32mp1/board.c
+++ b/board/dhelectronics/dh_stm32mp1/board.c
@@ -547,7 +547,7 @@
 	if (!prop || !len)
 		return -ENODEV;
 
-	if (!strstr(prop, "avenger96"))
+	if (!strstr(prop, "avenger96") && !strstr(prop, "dhcor-testbench"))
 		return -EINVAL;
 
 	/* Read out STPMIC1 NVM and determine default Buck3 voltage. */
@@ -564,18 +564,32 @@
 	bucks_vout >>= STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_OFFSET(3);
 	bucks_vout &= STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_MASK;
 
-	/*
-	 * Avenger96 board comes in multiple regulator configurations:
-	 * - rev.100 or rev.200 have Buck3 preconfigured to 3V3 operation on
-	 *   boot and contains extra Enpirion EP53A8LQI DCDC converter which
-	 *   supplies the IO. Reduce Buck3 voltage to 2V9 to not waste power.
-	 * - rev.200L have Buck3 preconfigured to 1V8 operation and have no
-	 *   Enpirion EP53A8LQI DCDC anymore, the IO is supplied from Buck3.
-	 */
-	if (bucks_vout == STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_3V3)
-		*uv = 2900000;
-	else
-		*uv = 1800000;
+	if (strstr(prop, "avenger96")) {
+		/*
+		 * Avenger96 board comes in multiple regulator configurations:
+		 * - rev.100 or rev.200 have Buck3 preconfigured to
+		 *   3V3 operation on boot and contains extra Enpirion
+		 *   EP53A8LQI DCDC converter which supplies the IO.
+		 *   Reduce Buck3 voltage to 2V9 to not waste power.
+		 * - rev.200L have Buck3 preconfigured to 1V8 operation
+		 *   and have no Enpirion EP53A8LQI DCDC anymore, the
+		 *   IO is supplied from Buck3.
+		 */
+		if (bucks_vout == STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_3V3)
+			*uv = 2900000;
+		else
+			*uv = 1800000;
+	} else {
+		/* Testbench always respects Buck3 NVM settings */
+		if (bucks_vout == STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_3V3)
+			*uv = 3300000;
+		else if (bucks_vout == STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_3V0)
+			*uv = 3000000;
+		else if (bucks_vout == STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_1V8)
+			*uv = 1800000;
+		else	/* STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_1V2 */
+			*uv = 1200000;
+	}
 
 	return 0;
 }
@@ -595,6 +609,7 @@
 
 	/* Adjust Buck3 per preconfigured PMIC voltage from NVM. */
 	regulator_set_value(rdev, uv);
+	regulator_set_enable(rdev, true);
 }
 
 static void board_init_regulator(void)
diff --git a/board/dhelectronics/dh_stm32mp1/u-boot-dhcor.its b/board/dhelectronics/dh_stm32mp1/u-boot-dhcor.its
index de7dcb3..f9c1075 100644
--- a/board/dhelectronics/dh_stm32mp1/u-boot-dhcor.its
+++ b/board/dhelectronics/dh_stm32mp1/u-boot-dhcor.its
@@ -18,7 +18,7 @@
 
 		fdt-1 {
 			description = ".dtb";
-			data = /incbin/("arch/arm/dts/stm32mp15xx-dhcor-avenger96.dtb");
+			data = /incbin/("arch/arm/dts/stm32mp15xx-dhcor-testbench.dtb");
 			type = "flat_dt";
 			arch = "arm";
 			compression = "none";
@@ -26,6 +26,14 @@
 
 		fdt-2 {
 			description = ".dtb";
+			data = /incbin/("arch/arm/dts/stm32mp15xx-dhcor-avenger96.dtb");
+			type = "flat_dt";
+			arch = "arm";
+			compression = "none";
+		};
+
+		fdt-3 {
+			description = ".dtb";
 			data = /incbin/("arch/arm/dts/stm32mp15xx-dhcor-drc-compact.dtb");
 			type = "flat_dt";
 			arch = "arm";
@@ -38,18 +46,25 @@
 
 		config-1 {
 			/* DT+SoM+board model */
-			description = "arrow,stm32mp15xx-avenger96_somrev0_boardrev1";
+			description = "dh,stm32mp15xx-dhcor-testbench_somrev0_boardrev1";
 			firmware = "uboot";
 			fdt = "fdt-1";
 		};
 
 		config-2 {
 			/* DT+SoM+board model */
-			description = "dh,stm32mp15xx-dhcor-drc-compact_somrev0_boardrev0";
+			description = "arrow,stm32mp15xx-avenger96_somrev0_boardrev1";
 			firmware = "uboot";
 			fdt = "fdt-2";
 		};
 
+		config-3 {
+			/* DT+SoM+board model */
+			description = "dh,stm32mp15xx-dhcor-drc-compact_somrev0_boardrev0";
+			firmware = "uboot";
+			fdt = "fdt-3";
+		};
+
 		/* Add 586-200..586-400 with fdt-2..fdt-4 here */
 	};
 };
diff --git a/board/engicam/stm32mp1/Makefile b/board/engicam/stm32mp1/Makefile
index 65560df..155d33f 100644
--- a/board/engicam/stm32mp1/Makefile
+++ b/board/engicam/stm32mp1/Makefile
@@ -8,3 +8,5 @@
 else
 obj-y += stm32mp1.o
 endif
+
+obj-$(CONFIG_DEBUG_UART_BOARD_INIT) += ../../st/stm32mp1/debug_uart.o
diff --git a/board/engicam/stm32mp1/spl.c b/board/engicam/stm32mp1/spl.c
index 3aa738b..2b7779c 100644
--- a/board/engicam/stm32mp1/spl.c
+++ b/board/engicam/stm32mp1/spl.c
@@ -6,7 +6,6 @@
  */
 
 #include <common.h>
-#include <asm/io.h>
 
 /* board early initialisation in board_f: need to use global variable */
 static u32 opp_voltage_mv __section(".data");
@@ -22,27 +21,3 @@
 	return 0;
 }
 
-#ifdef CONFIG_DEBUG_UART_BOARD_INIT
-void board_debug_uart_init(void)
-{
-#if (CONFIG_DEBUG_UART_BASE == STM32_UART4_BASE)
-
-#define RCC_MP_APB1ENSETR (STM32_RCC_BASE + 0x0A00)
-#define RCC_MP_AHB4ENSETR (STM32_RCC_BASE + 0x0A28)
-
-	/* UART4 clock enable */
-	setbits_le32(RCC_MP_APB1ENSETR, BIT(16));
-
-#define GPIOG_BASE 0x50008000
-	/* GPIOG clock enable */
-	writel(BIT(6), RCC_MP_AHB4ENSETR);
-	/* GPIO configuration for ST boards: Uart4 TX = G11 */
-	writel(0xffbfffff, GPIOG_BASE + 0x00);
-	writel(0x00006000, GPIOG_BASE + 0x24);
-#else
-
-#error("CONFIG_DEBUG_UART_BASE: not supported value")
-
-#endif
-}
-#endif
diff --git a/board/gdsys/mpc8308/gazerbeam.c b/board/gdsys/mpc8308/gazerbeam.c
index 3d4a7e5..ba88401 100644
--- a/board/gdsys/mpc8308/gazerbeam.c
+++ b/board/gdsys/mpc8308/gazerbeam.c
@@ -49,8 +49,10 @@
 	int mc = 0;
 	int con = 0;
 
-	if (sysinfo_get(&sysinfo))
+	if (sysinfo_get(&sysinfo)) {
 		puts("Could not find sysinfo information device.\n");
+		sysinfo = NULL;
+	}
 
 	/* Initialize serdes */
 	uclass_get_device_by_phandle(UCLASS_MISC, sysinfo, "serdes", &serdes);
@@ -92,8 +94,10 @@
 	int mc = 0;
 	int con = 0;
 
-	if (sysinfo_get(&sysinfo))
+	if (sysinfo_get(&sysinfo)) {
 		puts("Could not find sysinfo information device.\n");
+		sysinfo = NULL;
+	}
 
 	sysinfo_get_int(sysinfo, BOARD_MULTICHANNEL, &mc);
 	sysinfo_get_int(sysinfo, BOARD_VARIANT, &con);
@@ -130,8 +134,10 @@
 	struct udevice *tpm;
 	int ret;
 
-	if (sysinfo_get(&sysinfo))
+	if (sysinfo_get(&sysinfo)) {
 		puts("Could not find sysinfo information device.\n");
+		sysinfo = NULL;
+	}
 
 	if (sysinfo) {
 		int res = sysinfo_get_int(sysinfo, BOARD_HWVERSION,
diff --git a/board/intel/cougarcanyon2/cougarcanyon2.c b/board/intel/cougarcanyon2/cougarcanyon2.c
index ce11eae..7f61ef8 100644
--- a/board/intel/cougarcanyon2/cougarcanyon2.c
+++ b/board/intel/cougarcanyon2/cougarcanyon2.c
@@ -21,11 +21,9 @@
 	struct udevice *pch;
 	int ret;
 
-	ret = uclass_first_device(UCLASS_PCH, &pch);
+	ret = uclass_first_device_err(UCLASS_PCH, &pch);
 	if (ret)
 		return ret;
-	if (!pch)
-		return -ENODEV;
 
 	/* Initialize LPC interface to turn on superio chipset decode range */
 	dm_pci_write_config16(pch, LPC_IO_DEC, COMA_DEC_RANGE | COMB_DEC_RANGE);
diff --git a/board/nokia/rx51/lowlevel_init.S b/board/nokia/rx51/lowlevel_init.S
index 1cf8f8d..4b66e0a 100644
--- a/board/nokia/rx51/lowlevel_init.S
+++ b/board/nokia/rx51/lowlevel_init.S
@@ -7,7 +7,7 @@
 #include <config.h>
 
 kernoffs:		/* offset of kernel image from this address */
-	.word KERNEL_OFFSET - (. - CONFIG_SYS_TEXT_BASE)
+	.word . - CONFIG_SYS_TEXT_BASE - KERNEL_OFFSET
 
 kernaddr:		/* address of kernel after copying */
 	.word KERNEL_ADDRESS
@@ -49,7 +49,7 @@
 	/* r0 - start of kernel before */
 	adr	r0, kernoffs	/* r0 - current address of kernoffs section */
 	ldr	r1, kernoffs	/* r1 - offset of kernel image from kernoffs section */
-	add	r0, r0, r1
+	sub	r0, r0, r1
 
 	/* r3 - start of kernel after */
 	ldr	r3, kernaddr
diff --git a/board/st/stm32mp1/Makefile b/board/st/stm32mp1/Makefile
index 65560df..f2d720b 100644
--- a/board/st/stm32mp1/Makefile
+++ b/board/st/stm32mp1/Makefile
@@ -8,3 +8,5 @@
 else
 obj-y += stm32mp1.o
 endif
+
+obj-$(CONFIG_DEBUG_UART_BOARD_INIT) += debug_uart.o
diff --git a/board/st/stm32mp1/debug_uart.c b/board/st/stm32mp1/debug_uart.c
new file mode 100644
index 0000000..24e3f9f
--- /dev/null
+++ b/board/st/stm32mp1/debug_uart.c
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
+/*
+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ */
+
+#include <config.h>
+#include <debug_uart.h>
+#include <asm/io.h>
+#include <asm/arch/stm32.h>
+#include <linux/bitops.h>
+
+#define RCC_MP_APB1ENSETR (STM32_RCC_BASE + 0x0A00)
+#define RCC_MP_AHB4ENSETR (STM32_RCC_BASE + 0x0A28)
+
+#define GPIOG_BASE 0x50008000
+
+void board_debug_uart_init(void)
+{
+	if (CONFIG_DEBUG_UART_BASE == STM32_UART4_BASE) {
+		/* UART4 clock enable */
+		setbits_le32(RCC_MP_APB1ENSETR, BIT(16));
+
+		/* GPIOG clock enable */
+		writel(BIT(6), RCC_MP_AHB4ENSETR);
+		/* GPIO configuration for ST boards: Uart4 TX = G11 */
+		writel(0xffbfffff, GPIOG_BASE + 0x00);
+		writel(0x00006000, GPIOG_BASE + 0x24);
+	}
+}
diff --git a/board/st/stm32mp1/spl.c b/board/st/stm32mp1/spl.c
index 8e4549a..747ec7e 100644
--- a/board/st/stm32mp1/spl.c
+++ b/board/st/stm32mp1/spl.c
@@ -5,11 +5,7 @@
 
 #include <config.h>
 #include <common.h>
-#include <init.h>
-#include <asm/io.h>
 #include <asm/arch/sys_proto.h>
-#include <linux/bitops.h>
-#include <linux/delay.h>
 #include "../common/stpmic1.h"
 
 /* board early initialisation in board_f: need to use global variable */
@@ -29,27 +25,3 @@
 	return 0;
 }
 
-#ifdef CONFIG_DEBUG_UART_BOARD_INIT
-void board_debug_uart_init(void)
-{
-#if (CONFIG_DEBUG_UART_BASE == STM32_UART4_BASE)
-
-#define RCC_MP_APB1ENSETR (STM32_RCC_BASE + 0x0A00)
-#define RCC_MP_AHB4ENSETR (STM32_RCC_BASE + 0x0A28)
-
-	/* UART4 clock enable */
-	setbits_le32(RCC_MP_APB1ENSETR, BIT(16));
-
-#define GPIOG_BASE 0x50008000
-	/* GPIOG clock enable */
-	writel(BIT(6), RCC_MP_AHB4ENSETR);
-	/* GPIO configuration for ST boards: Uart4 TX = G11 */
-	writel(0xffbfffff, GPIOG_BASE + 0x00);
-	writel(0x00006000, GPIOG_BASE + 0x24);
-#else
-
-#error("CONFIG_DEBUG_UART_BASE: not supported value")
-
-#endif
-}
-#endif
diff --git a/boot/Makefile b/boot/Makefile
index 67e3352..dd45d78 100644
--- a/boot/Makefile
+++ b/boot/Makefile
@@ -47,5 +47,5 @@
 obj-$(CONFIG_SPL_LOAD_FIT) += common_fit.o
 endif
 
-obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_VBE) += vbe.o
+obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_VBE) += vbe.o vbe_fixup.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_VBE_SIMPLE) += vbe_simple.o
diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 13ac69e..9d98bee 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -195,7 +195,7 @@
 	printf("Seq  Probed  Status  Uclass    Name\n");
 	printf("---  ------  ------  --------  ------------------\n");
 	if (probe)
-		ret = uclass_first_device_err(UCLASS_BOOTDEV, &dev);
+		ret = uclass_first_device_check(UCLASS_BOOTDEV, &dev);
 	else
 		ret = uclass_find_first_device(UCLASS_BOOTDEV, &dev);
 	for (i = 0; dev; i++) {
@@ -204,7 +204,7 @@
 		       ret ? simple_itoa(ret) : "OK",
 		       dev_get_uclass_name(dev_get_parent(dev)), dev->name);
 		if (probe)
-			ret = uclass_next_device_err(&dev);
+			ret = uclass_next_device_check(&dev);
 		else
 			ret = uclass_find_next_device(&dev);
 	}
diff --git a/boot/bootm.c b/boot/bootm.c
index 5b20b41..a4c0870 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -790,7 +790,7 @@
 
 	/* Check for unsupported subcommand. */
 	if (ret) {
-		puts("subcommand not supported\n");
+		printf("subcommand failed (err=%d)\n", ret);
 		return ret;
 	}
 
diff --git a/boot/image-fdt.c b/boot/image-fdt.c
index 884e089..b830a0a 100644
--- a/boot/image-fdt.c
+++ b/boot/image-fdt.c
@@ -186,24 +186,25 @@
 	/* If fdt_high is set use it to select the relocation address */
 	fdt_high = env_get("fdt_high");
 	if (fdt_high) {
-		void *desired_addr = (void *)hextoul(fdt_high, NULL);
+		ulong desired_addr = hextoul(fdt_high, NULL);
+		ulong addr;
 
-		if (((ulong) desired_addr) == ~0UL) {
+		if (desired_addr == ~0UL) {
 			/* All ones means use fdt in place */
 			of_start = fdt_blob;
-			lmb_reserve(lmb, (ulong)of_start, of_len);
+			lmb_reserve(lmb, map_to_sysmem(of_start), of_len);
 			disable_relocation = 1;
 		} else if (desired_addr) {
-			of_start =
-			    (void *)(ulong) lmb_alloc_base(lmb, of_len, 0x1000,
-							   (ulong)desired_addr);
+			addr = lmb_alloc_base(lmb, of_len, 0x1000,
+					      desired_addr);
+			of_start = map_sysmem(addr, of_len);
 			if (of_start == NULL) {
 				puts("Failed using fdt_high value for Device Tree");
 				goto error;
 			}
 		} else {
-			of_start =
-			    (void *)(ulong) lmb_alloc(lmb, of_len, 0x1000);
+			addr = lmb_alloc(lmb, of_len, 0x1000);
+			of_start = map_sysmem(addr, of_len);
 		}
 	} else {
 		mapsize = env_get_bootm_mapsize();
@@ -224,9 +225,8 @@
 			 * At least part of this DRAM bank is usable, try
 			 * using it for LMB allocation.
 			 */
-			of_start =
-			    (void *)(ulong) lmb_alloc_base(lmb, of_len, 0x1000,
-							   start + usable);
+			of_start = map_sysmem((ulong)lmb_alloc_base(lmb,
+				    of_len, 0x1000, start + usable), of_len);
 			/* Allocation succeeded, use this block. */
 			if (of_start != NULL)
 				break;
@@ -665,15 +665,18 @@
 			goto err;
 		}
 	}
-	if (CONFIG_IS_ENABLED(EVENT)) {
+	if (!of_live_active() && CONFIG_IS_ENABLED(EVENT)) {
 		struct event_ft_fixup fixup;
 
-		fixup.tree = oftree_default();
+		fixup.tree = oftree_from_fdt(blob);
 		fixup.images = images;
-		ret = event_notify(EVT_FT_FIXUP, &fixup, sizeof(fixup));
-		if (ret) {
-			printf("ERROR: fdt fixup event failed: %d\n", ret);
-			goto err;
+		if (oftree_valid(fixup.tree)) {
+			ret = event_notify(EVT_FT_FIXUP, &fixup, sizeof(fixup));
+			if (ret) {
+				printf("ERROR: fdt fixup event failed: %d\n",
+				       ret);
+				goto err;
+			}
 		}
 	}
 
diff --git a/boot/vbe_fixup.c b/boot/vbe_fixup.c
new file mode 100644
index 0000000..53d8867
--- /dev/null
+++ b/boot/vbe_fixup.c
@@ -0,0 +1,233 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Verified Boot for Embedded (VBE) device tree fixup functions
+ *
+ * Copyright 2022 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#define LOG_CATEGORY LOGC_BOOT
+
+#include <common.h>
+#include <dm.h>
+#include <event.h>
+#include <image.h>
+#include <malloc.h>
+#include <rng.h>
+#include <dm/ofnode.h>
+
+#define VBE_PREFIX		"vbe,"
+#define VBE_PREFIX_LEN		(sizeof(VBE_PREFIX) - 1)
+#define VBE_ERR_STR_LEN		128
+#define VBE_MAX_RAND_SIZE	256
+
+struct vbe_result {
+	int errnum;
+	char err_str[VBE_ERR_STR_LEN];
+};
+
+typedef int (*vbe_req_func)(ofnode node, struct vbe_result *result);
+
+static int handle_random_req(ofnode node, int default_size,
+			     struct vbe_result *result)
+{
+	char buf[VBE_MAX_RAND_SIZE];
+	struct udevice *dev;
+	u32 size;
+	int ret;
+
+	if (!IS_ENABLED(CONFIG_DM_RNG))
+		return -ENOTSUPP;
+
+	if (ofnode_read_u32(node, "vbe,size", &size)) {
+		if (!default_size) {
+			snprintf(result->err_str, VBE_ERR_STR_LEN,
+				 "Missing vbe,size property");
+			return log_msg_ret("byt", -EINVAL);
+		}
+		size = default_size;
+	}
+	if (size > VBE_MAX_RAND_SIZE) {
+		snprintf(result->err_str, VBE_ERR_STR_LEN,
+			 "vbe,size %#x exceeds max size %#x", size,
+			 VBE_MAX_RAND_SIZE);
+		return log_msg_ret("siz", -E2BIG);
+	}
+	ret = uclass_first_device_err(UCLASS_RNG, &dev);
+	if (ret) {
+		snprintf(result->err_str, VBE_ERR_STR_LEN,
+			 "Cannot find random-number device (err=%d)", ret);
+		return log_msg_ret("wr", ret);
+	}
+	ret = dm_rng_read(dev, buf, size);
+	if (ret) {
+		snprintf(result->err_str, VBE_ERR_STR_LEN,
+			 "Failed to read random-number device (err=%d)", ret);
+		return log_msg_ret("rd", ret);
+	}
+	ret = ofnode_write_prop(node, "data", buf, size, true);
+	if (ret)
+		return log_msg_ret("wr", -EINVAL);
+
+	return 0;
+}
+
+static int vbe_req_random_seed(ofnode node, struct vbe_result *result)
+{
+	return handle_random_req(node, 0, result);
+}
+
+static int vbe_req_aslr_move(ofnode node, struct vbe_result *result)
+{
+	return -ENOTSUPP;
+}
+
+static int vbe_req_aslr_rand(ofnode node, struct vbe_result *result)
+{
+	return handle_random_req(node, 4, result);
+}
+
+static int vbe_req_efi_runtime_rand(ofnode node, struct vbe_result *result)
+{
+	return handle_random_req(node, 4, result);
+}
+
+static struct vbe_req {
+	const char *compat;
+	vbe_req_func func;
+} vbe_reqs[] = {
+	/* address space layout randomization - move the OS in memory */
+	{ "aslr-move", vbe_req_aslr_move },
+
+	/* provide random data for address space layout randomization */
+	{ "aslr-rand", vbe_req_aslr_rand },
+
+	/* provide random data for EFI-runtime-services address */
+	{ "efi-runtime-rand", vbe_req_efi_runtime_rand },
+
+	/* generate random data bytes to see the OS's rand generator */
+	{ "random-rand", vbe_req_random_seed },
+
+};
+
+static int vbe_process_request(ofnode node, struct vbe_result *result)
+{
+	const char *compat, *req_name;
+	int i;
+
+	compat = ofnode_read_string(node, "compatible");
+	if (!compat)
+		return 0;
+
+	if (strlen(compat) <= VBE_PREFIX_LEN ||
+	    strncmp(compat, VBE_PREFIX, VBE_PREFIX_LEN))
+		return -EINVAL;
+
+	req_name = compat + VBE_PREFIX_LEN; /* drop "vbe," prefix */
+	for (i = 0; i < ARRAY_SIZE(vbe_reqs); i++) {
+		if (!strcmp(vbe_reqs[i].compat, req_name)) {
+			int ret;
+
+			ret = vbe_reqs[i].func(node, result);
+			if (ret)
+				return log_msg_ret("req", ret);
+			return 0;
+		}
+	}
+	snprintf(result->err_str, VBE_ERR_STR_LEN, "Unknown request: %s",
+		 req_name);
+
+	return -ENOTSUPP;
+}
+
+/**
+ * bootmeth_vbe_ft_fixup() - Process VBE OS requests and do device tree fixups
+ *
+ * If there are no images provided, this does nothing and returns 0.
+ *
+ * @ctx: Context for event
+ * @event: Event to process
+ * @return 0 if OK, -ve on error
+ */
+static int bootmeth_vbe_ft_fixup(void *ctx, struct event *event)
+{
+	const struct event_ft_fixup *fixup = &event->data.ft_fixup;
+	const struct bootm_headers *images = fixup->images;
+	ofnode parent, dest_parent, root, node;
+	oftree fit;
+
+	if (!images || !images->fit_hdr_os)
+		return 0;
+
+	/* Get the image node with requests in it */
+	log_debug("fit=%p, noffset=%d\n", images->fit_hdr_os,
+		  images->fit_noffset_os);
+	fit = oftree_from_fdt(images->fit_hdr_os);
+	root = oftree_root(fit);
+	if (of_live_active()) {
+		log_warning("Cannot fix up live tree\n");
+		return 0;
+	}
+	if (!ofnode_valid(root))
+		return log_msg_ret("rt", -EINVAL);
+	parent = noffset_to_ofnode(root, images->fit_noffset_os);
+	if (!ofnode_valid(parent))
+		return log_msg_ret("img", -EINVAL);
+	dest_parent = oftree_path(fixup->tree, "/chosen");
+	if (!ofnode_valid(dest_parent))
+		return log_msg_ret("dst", -EINVAL);
+
+	ofnode_for_each_subnode(node, parent) {
+		const char *name = ofnode_get_name(node);
+		struct vbe_result result;
+		ofnode dest;
+		int ret;
+
+		log_debug("copy subnode: %s\n", name);
+		ret = ofnode_add_subnode(dest_parent, name, &dest);
+		if (ret && ret != -EEXIST)
+			return log_msg_ret("add", ret);
+		ret = ofnode_copy_props(node, dest);
+		if (ret)
+			return log_msg_ret("cp", ret);
+
+		*result.err_str = '\0';
+		ret = vbe_process_request(dest, &result);
+		if (ret) {
+			result.errnum = ret;
+			log_err("Failed to process VBE request %s (err=%d)\n",
+				ofnode_get_name(dest), ret);
+			if (*result.err_str) {
+				char *msg = strdup(result.err_str);
+
+				if (!msg)
+					return log_msg_ret("msg", -ENOMEM);
+				ret = ofnode_write_string(dest, "vbe,error",
+							  msg);
+				if (ret) {
+					free(msg);
+					return log_msg_ret("str", -ENOMEM);
+				}
+			}
+			if (result.errnum) {
+				ret = ofnode_write_u32(dest, "vbe,errnum",
+						       result.errnum);
+				if (ret)
+					return log_msg_ret("num", -ENOMEM);
+				if (result.errnum != -ENOTSUPP)
+					return log_msg_ret("pro",
+							   result.errnum);
+				if (result.errnum == -ENOTSUPP &&
+				    ofnode_read_bool(dest, "vbe,required")) {
+					log_err("Cannot handle required request: %s\n",
+						ofnode_get_name(dest));
+					return log_msg_ret("req",
+							   result.errnum);
+				}
+			}
+		}
+	}
+
+	return 0;
+}
+EVENT_SPY(EVT_FT_FIXUP, bootmeth_vbe_ft_fixup);
diff --git a/boot/vbe_simple.c b/boot/vbe_simple.c
index 61b6322..076b650 100644
--- a/boot/vbe_simple.c
+++ b/boot/vbe_simple.c
@@ -6,6 +6,8 @@
  * Written by Simon Glass <sjg@chromium.org>
  */
 
+#define LOG_CATEGORY LOGC_BOOT
+
 #include <common.h>
 #include <log.h>
 #include <memalign.h>
@@ -199,17 +201,17 @@
 
 	version = strdup(state->fw_version);
 	if (!version)
-		return log_msg_ret("ver", -ENOMEM);
+		return log_msg_ret("dup", -ENOMEM);
 
 	ret = ofnode_write_string(node, "cur-version", version);
 	if (ret)
 		return log_msg_ret("ver", ret);
 	ret = ofnode_write_u32(node, "cur-vernum", state->fw_vernum);
 	if (ret)
-		return log_msg_ret("ver", ret);
+		return log_msg_ret("num", ret);
 	ret = ofnode_write_string(node, "bootloader-version", version_string);
 	if (ret)
-		return log_msg_ret("fix", ret);
+		return log_msg_ret("bl", ret);
 
 	return 0;
 }
@@ -233,7 +235,7 @@
 	 */
 	for (vbe_find_first_device(&dev); dev; vbe_find_next_device(&dev)) {
 		struct simple_state state;
-		ofnode node;
+		ofnode node, subnode;
 		int ret;
 
 		if (strcmp("vbe_simple", dev->driver->name))
@@ -243,8 +245,8 @@
 		node = oftree_path(tree, "/chosen/fwupd");
 		if (!ofnode_valid(node))
 			continue;
-		node = ofnode_find_subnode(node, dev->name);
-		if (!ofnode_valid(node))
+		subnode = ofnode_find_subnode(node, dev->name);
+		if (!ofnode_valid(subnode))
 			continue;
 
 		log_debug("Fixing up: %s\n", dev->name);
@@ -255,7 +257,7 @@
 		if (ret)
 			return log_msg_ret("read", ret);
 
-		ret = vbe_simple_fixup_node(node, &state);
+		ret = vbe_simple_fixup_node(subnode, &state);
 		if (ret)
 			return log_msg_ret("fix", ret);
 	}
diff --git a/cmd/adc.c b/cmd/adc.c
index 1c5d3e1..a739d9e 100644
--- a/cmd/adc.c
+++ b/cmd/adc.c
@@ -12,23 +12,19 @@
 		       char *const argv[])
 {
 	struct udevice *dev;
-	int ret;
+	int ret, err;
 
-	ret = uclass_first_device_err(UCLASS_ADC, &dev);
-	if (ret) {
-		printf("No available ADC device\n");
-		return CMD_RET_FAILURE;
+	ret = err = uclass_first_device_check(UCLASS_ADC, &dev);
+
+	while (dev) {
+		printf("- %s status: %i\n", dev->name, ret);
+
+		ret = uclass_next_device_check(&dev);
+		if (ret)
+			err = ret;
 	}
 
-	do {
-		printf("- %s\n", dev->name);
-
-		ret = uclass_next_device(&dev);
-		if (ret)
-			return CMD_RET_FAILURE;
-	} while (dev);
-
-	return CMD_RET_SUCCESS;
+	return err ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
 }
 
 static int do_adc_info(struct cmd_tbl *cmdtp, int flag, int argc,
diff --git a/cmd/bootm.c b/cmd/bootm.c
index d764a27..37c2af9 100644
--- a/cmd/bootm.c
+++ b/cmd/bootm.c
@@ -111,7 +111,7 @@
 			    bootm_get_addr(argc, argv) + image_load_offset);
 #endif
 
-	return ret;
+	return ret ? CMD_RET_FAILURE : 0;
 }
 
 /*******************************************************************/
@@ -120,6 +120,9 @@
 
 int do_bootm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 {
+	int states;
+	int ret;
+
 #ifdef CONFIG_NEEDS_MANUAL_RELOC
 	static int relocated = 0;
 
@@ -152,17 +155,17 @@
 			return do_bootm_subcommand(cmdtp, flag, argc, argv);
 	}
 
-	return do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_START |
-		BOOTM_STATE_FINDOS | BOOTM_STATE_PRE_LOAD | BOOTM_STATE_FINDOTHER |
-		BOOTM_STATE_LOADOS |
-#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
-		BOOTM_STATE_RAMDISK |
-#endif
-#if defined(CONFIG_PPC) || defined(CONFIG_MIPS)
-		BOOTM_STATE_OS_CMDLINE |
-#endif
+	states = BOOTM_STATE_START | BOOTM_STATE_FINDOS | BOOTM_STATE_PRE_LOAD |
+		BOOTM_STATE_FINDOTHER | BOOTM_STATE_LOADOS |
 		BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO |
-		BOOTM_STATE_OS_GO, &images, 1);
+		BOOTM_STATE_OS_GO;
+	if (IS_ENABLED(CONFIG_SYS_BOOT_RAMDISK_HIGH))
+		states |= BOOTM_STATE_RAMDISK;
+	if (IS_ENABLED(CONFIG_PPC) || IS_ENABLED(CONFIG_MIPS))
+		states |= BOOTM_STATE_OS_CMDLINE;
+	ret = do_bootm_states(cmdtp, flag, argc, argv, states, &images, 1);
+
+	return ret ? CMD_RET_FAILURE : 0;
 }
 
 int bootm_maybe_autostart(struct cmd_tbl *cmdtp, const char *cmd)
diff --git a/cmd/demo.c b/cmd/demo.c
index 571f562..ebd5a24 100644
--- a/cmd/demo.c
+++ b/cmd/demo.c
@@ -64,20 +64,23 @@
 int do_demo_list(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 {
 	struct udevice *dev;
-	int i, ret;
+	int i, ret, err = 0;
 
 	puts("Demo uclass entries:\n");
 
-	for (i = 0, ret = uclass_first_device(UCLASS_DEMO, &dev);
+	for (i = 0, ret = uclass_first_device_check(UCLASS_DEMO, &dev);
 	     dev;
-	     ret = uclass_next_device(&dev)) {
-		printf("entry %d - instance %08x, ops %08x, plat %08x\n",
+	     ret = uclass_next_device_check(&dev)) {
+		printf("entry %d - instance %08x, ops %08x, plat %08x, status %i\n",
 		       i++, (uint)map_to_sysmem(dev),
 		       (uint)map_to_sysmem(dev->driver->ops),
-		       (uint)map_to_sysmem(dev_get_plat(dev)));
+		       (uint)map_to_sysmem(dev_get_plat(dev)),
+		       ret);
+		if (ret)
+			err = ret;
 	}
 
-	return cmd_process_error(cmdtp, ret);
+	return cmd_process_error(cmdtp, err);
 }
 
 static struct cmd_tbl demo_commands[] = {
diff --git a/cmd/fdt.c b/cmd/fdt.c
index 6fbd920..4b2dcfe 100644
--- a/cmd/fdt.c
+++ b/cmd/fdt.c
@@ -40,6 +40,7 @@
 {
 	void *buf;
 
+	printf("Working FDT set to %lx\n", addr);
 	buf = map_sysmem(addr, 0);
 	working_fdt = buf;
 	env_set_hex("fdtaddr", addr);
diff --git a/cmd/gpio.c b/cmd/gpio.c
index 53e9ce6..f456598 100644
--- a/cmd/gpio.c
+++ b/cmd/gpio.c
@@ -77,17 +77,24 @@
 	struct udevice *dev;
 	int banklen;
 	int flags;
-	int ret;
+	int ret, err = 0;
 
 	flags = 0;
 	if (gpio_name && !*gpio_name)
 		gpio_name = NULL;
-	for (ret = uclass_first_device(UCLASS_GPIO, &dev);
+	for (ret = uclass_first_device_check(UCLASS_GPIO, &dev);
 	     dev;
-	     ret = uclass_next_device(&dev)) {
+	     ret = uclass_next_device_check(&dev)) {
 		const char *bank_name;
 		int num_bits;
 
+		if (ret) {
+			printf("GPIO device %s probe error %i\n",
+			       dev->name, ret);
+			err = ret;
+			continue;
+		}
+
 		flags |= FLAG_SHOW_BANK;
 		if (all)
 			flags |= FLAG_SHOW_ALL;
@@ -120,7 +127,7 @@
 			flags |= FLAG_SHOW_NEWLINE;
 	}
 
-	return ret;
+	return err;
 }
 #endif
 
diff --git a/cmd/pmic.c b/cmd/pmic.c
index 0cb44d0..49a405f 100644
--- a/cmd/pmic.c
+++ b/cmd/pmic.c
@@ -51,25 +51,26 @@
 		   char *const argv[])
 {
 	struct udevice *dev;
-	int ret;
+	int ret, err = 0;
 
 	printf("| %-*.*s| %-*.*s| %s @ %s\n",
 	       LIMIT_DEV, LIMIT_DEV, "Name",
 	       LIMIT_PARENT, LIMIT_PARENT, "Parent name",
 	       "Parent uclass", "seq");
 
-	for (ret = uclass_first_device(UCLASS_PMIC, &dev); dev;
-	     ret = uclass_next_device(&dev)) {
+	for (ret = uclass_first_device_check(UCLASS_PMIC, &dev); dev;
+	     ret = uclass_next_device_check(&dev)) {
 		if (ret)
-			continue;
+			err = ret;
 
-		printf("| %-*.*s| %-*.*s| %s @ %d\n",
+		printf("| %-*.*s| %-*.*s| %s @ %d | status: %i\n",
 		       LIMIT_DEV, LIMIT_DEV, dev->name,
 		       LIMIT_PARENT, LIMIT_PARENT, dev->parent->name,
-		       dev_get_uclass_name(dev->parent), dev_seq(dev->parent));
+		       dev_get_uclass_name(dev->parent), dev_seq(dev->parent),
+		       ret);
 	}
 
-	if (ret)
+	if (err)
 		return CMD_RET_FAILURE;
 
 	return CMD_RET_SUCCESS;
diff --git a/cmd/regulator.c b/cmd/regulator.c
index 60a7003..ed4996d 100644
--- a/cmd/regulator.c
+++ b/cmd/regulator.c
@@ -205,7 +205,7 @@
 	constraint(" * mode id:", mode, mode_name);
 }
 
-static void do_status_line(struct udevice *dev)
+static void do_status_line(struct udevice *dev, int status)
 {
 	struct dm_regulator_uclass_plat *pdata;
 	int current, value, mode;
@@ -231,6 +231,7 @@
 		printf("%-10s", mode_name);
 	else
 		printf("%-10s", "-");
+	printf(" %i", status);
 	printf("\n");
 }
 
@@ -250,11 +251,11 @@
 	}
 
 	/* Show all of them in a list, probing them as needed */
-	printf("%-20s %-10s %10s %10s %-10s\n", "Name", "Enabled", "uV", "mA",
-	       "Mode");
-	for (ret = uclass_first_device(UCLASS_REGULATOR, &dev); dev;
-	     ret = uclass_next_device(&dev))
-		do_status_line(dev);
+	printf("%-20s %-10s %10s %10s %-10s %s\n", "Name", "Enabled", "uV", "mA",
+	       "Mode", "Status");
+	for (ret = uclass_first_device_check(UCLASS_REGULATOR, &dev); dev;
+	     ret = uclass_next_device_check(&dev))
+		do_status_line(dev, ret);
 
 	return CMD_RET_SUCCESS;
 }
diff --git a/common/stdio.c b/common/stdio.c
index 1308384..e316a35 100644
--- a/common/stdio.c
+++ b/common/stdio.c
@@ -314,7 +314,6 @@
 int stdio_add_devices(void)
 {
 	struct udevice *dev;
-	struct uclass *uc;
 	int ret;
 
 	if (IS_ENABLED(CONFIG_DM_KEYBOARD)) {
@@ -324,24 +323,18 @@
 		 * have a list of input devices to start up in the stdin
 		 * environment variable. That work probably makes more sense
 		 * when stdio itself is converted to driver model.
-		 *
-		 * TODO(sjg@chromium.org): Convert changing
-		 * uclass_first_device() etc. to return the device even on
-		 * error. Then we could use that here.
 		 */
-		ret = uclass_get(UCLASS_KEYBOARD, &uc);
-		if (ret)
-			return ret;
 
 		/*
 		 * Don't report errors to the caller - assume that they are
 		 * non-fatal
 		 */
-		uclass_foreach_dev(dev, uc) {
-			ret = device_probe(dev);
+		for (ret = uclass_first_device_check(UCLASS_KEYBOARD, &dev);
+				dev;
+				ret = uclass_next_device_check(&dev)) {
 			if (ret)
-				printf("Failed to probe keyboard '%s'\n",
-				       dev->name);
+				printf("%s: Failed to probe keyboard '%s' (ret=%d)\n",
+				       __func__, dev->name, ret);
 		}
 	}
 #if CONFIG_IS_ENABLED(SYS_I2C_LEGACY)
@@ -361,13 +354,14 @@
 		int ret;
 
 		if (!IS_ENABLED(CONFIG_SYS_CONSOLE_IS_IN_ENV)) {
-			for (ret = uclass_first_device(UCLASS_VIDEO, &vdev);
-			     vdev;
-			     ret = uclass_next_device(&vdev))
-				;
-			if (ret)
-				printf("%s: Video device failed (ret=%d)\n",
-				       __func__, ret);
+			for (ret = uclass_first_device_check(UCLASS_VIDEO,
+							     &vdev);
+					vdev;
+					ret = uclass_next_device_check(&vdev)) {
+				if (ret)
+					printf("%s: Failed to probe video device '%s' (ret=%d)\n",
+					       __func__, vdev->name, ret);
+			}
 		}
 		if (IS_ENABLED(CONFIG_SPLASH_SCREEN) &&
 		    IS_ENABLED(CONFIG_CMD_BMP))
diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig
index fdd7b35..9d8da25 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -11,7 +11,6 @@
 CONFIG_FIT=y
 CONFIG_FIT_SIGNATURE=y
 CONFIG_FIT_VERBOSE=y
-# CONFIG_BOOTMETH_VBE is not set
 CONFIG_BOOTSTAGE=y
 CONFIG_BOOTSTAGE_REPORT=y
 CONFIG_BOOTSTAGE_FDT=y
@@ -84,6 +83,7 @@
 CONFIG_SYSCON=y
 CONFIG_DEVRES=y
 CONFIG_DEBUG_DEVRES=y
+CONFIG_OFNODE_MULTI_TREE=y
 CONFIG_ADC=y
 CONFIG_ADC_SANDBOX=y
 CONFIG_AXI=y
diff --git a/configs/stm32mp15_dhcom_basic_defconfig b/configs/stm32mp15_dhcom_basic_defconfig
index f47e70b..67e238a 100644
--- a/configs/stm32mp15_dhcom_basic_defconfig
+++ b/configs/stm32mp15_dhcom_basic_defconfig
@@ -79,6 +79,7 @@
 CONFIG_CMD_TIMER=y
 CONFIG_CMD_PMIC=y
 CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_BTRFS=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nor0=nor0"
diff --git a/configs/stm32mp15_dhcor_basic_defconfig b/configs/stm32mp15_dhcor_basic_defconfig
index 02cce50..a630713 100644
--- a/configs/stm32mp15_dhcor_basic_defconfig
+++ b/configs/stm32mp15_dhcor_basic_defconfig
@@ -77,6 +77,7 @@
 CONFIG_CMD_TIMER=y
 CONFIG_CMD_PMIC=y
 CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_BTRFS=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nor0=nor0"
diff --git a/disk/part_efi.c b/disk/part_efi.c
index ad94504..26738a5 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -264,20 +264,19 @@
 
 	/* "part" argument must be at least 1 */
 	if (part < 1) {
-		printf("%s: Invalid Argument(s)\n", __func__);
-		return -1;
+		log_debug("Invalid Argument(s)\n");
+		return -EINVAL;
 	}
 
 	/* This function validates AND fills in the GPT header and PTE */
 	if (find_valid_gpt(dev_desc, gpt_head, &gpt_pte) != 1)
-		return -1;
+		return -EINVAL;
 
 	if (part > le32_to_cpu(gpt_head->num_partition_entries) ||
 	    !is_pte_valid(&gpt_pte[part - 1])) {
-		debug("%s: *** ERROR: Invalid partition number %d ***\n",
-			__func__, part);
+		log_debug("*** ERROR: Invalid partition number %d ***\n", part);
 		free(gpt_pte);
-		return -1;
+		return -EPERM;
 	}
 
 	/* The 'lbaint_t' casting may limit the maximum disk size to 2 TB */
@@ -300,8 +299,8 @@
 			info->type_guid, UUID_STR_FORMAT_GUID);
 #endif
 
-	debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s\n", __func__,
-	      info->start, info->size, info->name);
+	log_debug("start 0x" LBAF ", size 0x" LBAF ", name %s\n", info->start,
+		  info->size, info->name);
 
 	/* Remember to free pte */
 	free(gpt_pte);
diff --git a/doc/develop/driver-model/livetree.rst b/doc/develop/driver-model/livetree.rst
index 55aa3ea..579eef5 100644
--- a/doc/develop/driver-model/livetree.rst
+++ b/doc/develop/driver-model/livetree.rst
@@ -255,7 +255,7 @@
 interface. The OF_LIVE support required addition of the flattening step at the
 end.
 
-See dm_test_ofnode_root() for some examples. The ofnode_path_root() function
+See dm_test_ofnode_root() for some examples. The oftree_from_fdt() function
 causes a flat device tree to be 'registered' such that it can be used by the
 ofnode interface.
 
diff --git a/doc/develop/vbe.rst b/doc/develop/vbe.rst
index 8f147fd..cca193c 100644
--- a/doc/develop/vbe.rst
+++ b/doc/develop/vbe.rst
@@ -19,8 +19,9 @@
 
 For a detailed overview of VBE, see vbe-intro_. A fuller description of
 bootflows is at vbe-bootflows_ and the firmware-update mechanism is described at
-vbe-fwupdate_.
+vbe-fwupdate_. VBE OS requests are described at  vbe-osrequests_.
 
 .. _vbe-intro: https://docs.google.com/document/d/e/2PACX-1vQjXLPWMIyVktaTMf8edHZYDrEvMYD_iNzIj1FgPmKF37fpglAC47Tt5cvPBC5fvTdoK-GA5Zv1wifo/pub
 .. _vbe-bootflows: https://docs.google.com/document/d/e/2PACX-1vR0OzhuyRJQ8kdeOibS3xB1rVFy3J4M_QKTM5-3vPIBNcdvR0W8EXu9ymG-yWfqthzWoM4JUNhqwydN/pub
 .. _vbe-fwupdate: https://docs.google.com/document/d/e/2PACX-1vTnlIL17vVbl6TVoTHWYMED0bme7oHHNk-g5VGxblbPiKIdGDALE1HKId8Go5f0g1eziLsv4h9bocbk/pub
+.. _vbe-osrequests: https://docs.google.com/document/d/e/2PACX-1vTHhxX7WSZe68i9rAkW-DHdx6koU-jxYHhamLhZn9GQ9QT2_epSBosMV1_r7yPHOXZccx71rF_t0PXL/pub
diff --git a/doc/usage/cmd/fdt.rst b/doc/usage/cmd/fdt.rst
index 07fed73..36b8230 100644
--- a/doc/usage/cmd/fdt.rst
+++ b/doc/usage/cmd/fdt.rst
@@ -60,6 +60,7 @@
 address and expand it to 0xf000 in size::
 
     => fdt addr 10000 f000
+    Working FDT set to 10000
     => md 10000 4
     00010000: edfe0dd0 00f00000 78000000 7c270000  ...........x..'|
 
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index 7d12d54..bcc14a6 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -593,11 +593,9 @@
 
 int blk_first_device_err(enum blk_flag_t flags, struct udevice **devp)
 {
-	int ret;
-
-	for (ret = uclass_first_device_err(UCLASS_BLK, devp);
-	     !ret;
-	     ret = uclass_next_device_err(devp)) {
+	for (uclass_first_device(UCLASS_BLK, devp);
+	     *devp;
+	     uclass_next_device(devp)) {
 		if (!blk_flags_check(*devp, flags))
 			return 0;
 	}
@@ -607,11 +605,9 @@
 
 int blk_next_device_err(enum blk_flag_t flags, struct udevice **devp)
 {
-	int ret;
-
-	for (ret = uclass_next_device_err(devp);
-	     !ret;
-	     ret = uclass_next_device_err(devp)) {
+	for (uclass_next_device(devp);
+	     *devp;
+	     uclass_next_device(devp)) {
 		if (!blk_flags_check(*devp, flags))
 			return 0;
 	}
diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c
index 5ccbf9a..e33bb9d 100644
--- a/drivers/core/regmap.c
+++ b/drivers/core/regmap.c
@@ -4,6 +4,8 @@
  * Written by Simon Glass <sjg@chromium.org>
  */
 
+#define LOG_CATEGORY	LOGC_DM
+
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
@@ -37,6 +39,22 @@
 DECLARE_GLOBAL_DATA_PTR;
 
 /**
+ * do_range_check() - Control whether range checks are done
+ *
+ * Returns: true to do range checks, false to skip
+ *
+ * This is used to reduce code size on SPL where range checks are known not to
+ * be needed
+ *
+ * Add this to the top of the file to enable them: #define LOG_DEBUG
+ */
+static inline bool do_range_check(void)
+{
+	return _LOG_DEBUG || !IS_ENABLED(CONFIG_SPL);
+
+}
+
+/**
  * regmap_alloc() - Allocate a regmap with a given number of ranges.
  *
  * @count: Number of ranges to be allocated for the regmap.
@@ -391,7 +409,7 @@
 	struct regmap_range *range;
 	void *ptr;
 
-	if (range_num >= map->range_count) {
+	if (do_range_check() && range_num >= map->range_count) {
 		debug("%s: range index %d larger than range count\n",
 		      __func__, range_num);
 		return -ERANGE;
@@ -399,7 +417,8 @@
 	range = &map->ranges[range_num];
 
 	offset <<= map->reg_offset_shift;
-	if (offset + val_len > range->size || offset + val_len < offset) {
+	if (do_range_check() &&
+	    (offset + val_len > range->size || offset + val_len < offset)) {
 		debug("%s: offset/size combination invalid\n", __func__);
 		return -ERANGE;
 	}
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 08d9ed8..b7d11bd 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -586,19 +586,6 @@
 	return uclass_get_device_tail(dev, ret, devp);
 }
 
-int uclass_first_device_err(enum uclass_id id, struct udevice **devp)
-{
-	int ret;
-
-	ret = uclass_first_device(id, devp);
-	if (ret)
-		return ret;
-	else if (!*devp)
-		return -ENODEV;
-
-	return 0;
-}
-
 int uclass_next_device(struct udevice **devp)
 {
 	struct udevice *dev = *devp;
@@ -611,11 +598,24 @@
 	return uclass_get_device_tail(dev, ret, devp);
 }
 
+int uclass_first_device_err(enum uclass_id id, struct udevice **devp)
+{
+	int ret;
+
+	ret = uclass_first_device_check(id, devp);
+	if (ret)
+		return ret;
+	else if (!*devp)
+		return -ENODEV;
+
+	return 0;
+}
+
 int uclass_next_device_err(struct udevice **devp)
 {
 	int ret;
 
-	ret = uclass_next_device(devp);
+	ret = uclass_next_device_check(devp);
 	if (ret)
 		return ret;
 	else if (!*devp)
@@ -799,20 +799,18 @@
 int uclass_probe_all(enum uclass_id id)
 {
 	struct udevice *dev;
-	int ret;
+	int ret, err;
 
-	ret = uclass_first_device(id, &dev);
-	if (ret || !dev)
-		return ret;
+	err = uclass_first_device_check(id, &dev);
 
 	/* Scanning uclass to probe all devices */
 	while (dev) {
-		ret = uclass_next_device(&dev);
+		ret = uclass_next_device_check(&dev);
 		if (ret)
-			return ret;
+			err = ret;
 	}
 
-	return 0;
+	return err;
 }
 
 int uclass_id_count(enum uclass_id id)
diff --git a/drivers/cpu/cpu-uclass.c b/drivers/cpu/cpu-uclass.c
index 71e5900..a754832 100644
--- a/drivers/cpu/cpu-uclass.c
+++ b/drivers/cpu/cpu-uclass.c
@@ -20,25 +20,13 @@
 
 int cpu_probe_all(void)
 {
-	struct udevice *cpu;
-	int ret;
+	int ret = uclass_probe_all(UCLASS_CPU);
 
-	ret = uclass_first_device(UCLASS_CPU, &cpu);
 	if (ret) {
-		debug("%s: No CPU found (err = %d)\n", __func__, ret);
-		return ret;
+		debug("%s: Error while probing CPUs (err = %d %s)\n",
+		      __func__, ret, errno_str(ret));
 	}
-
-	while (cpu) {
-		ret = uclass_next_device(&cpu);
-		if (ret) {
-			debug("%s: Error while probing CPU (err = %d)\n",
-			      __func__, ret);
-			return ret;
-		}
-	}
-
-	return 0;
+	return ret;
 }
 
 int cpu_is_current(struct udevice *cpu)
diff --git a/drivers/dma/dma-uclass.c b/drivers/dma/dma-uclass.c
index 012609b..81dbb4d 100644
--- a/drivers/dma/dma-uclass.c
+++ b/drivers/dma/dma-uclass.c
@@ -19,6 +19,7 @@
 #include <asm/cache.h>
 #include <dm/read.h>
 #include <dma-uclass.h>
+#include <linux/dma-mapping.h>
 #include <dt-structs.h>
 #include <errno.h>
 
@@ -235,6 +236,8 @@
 {
 	struct udevice *dev;
 	const struct dma_ops *ops;
+	dma_addr_t destination;
+	dma_addr_t source;
 	int ret;
 
 	ret = dma_get_device(DMA_SUPPORTS_MEM_TO_MEM, &dev);
@@ -245,11 +248,17 @@
 	if (!ops->transfer)
 		return -ENOSYS;
 
-	/* Invalidate the area, so no writeback into the RAM races with DMA */
-	invalidate_dcache_range((unsigned long)dst, (unsigned long)dst +
-				roundup(len, ARCH_DMA_MINALIGN));
+	/* Clean the areas, so no writeback into the RAM races with DMA */
+	destination = dma_map_single(dst, len, DMA_FROM_DEVICE);
+	source = dma_map_single(src, len, DMA_TO_DEVICE);
 
-	return ops->transfer(dev, DMA_MEM_TO_MEM, dst, src, len);
+	ret = ops->transfer(dev, DMA_MEM_TO_MEM, destination, source, len);
+
+	/* Clean+Invalidate the areas after, so we can see DMA'd data */
+	dma_unmap_single(destination, len, DMA_FROM_DEVICE);
+	dma_unmap_single(source, len, DMA_TO_DEVICE);
+
+	return ret;
 }
 
 UCLASS_DRIVER(dma) = {
diff --git a/drivers/dma/sandbox-dma-test.c b/drivers/dma/sandbox-dma-test.c
index aebf3ee..2b8259a 100644
--- a/drivers/dma/sandbox-dma-test.c
+++ b/drivers/dma/sandbox-dma-test.c
@@ -39,9 +39,9 @@
 };
 
 static int sandbox_dma_transfer(struct udevice *dev, int direction,
-				void *dst, void *src, size_t len)
+				dma_addr_t dst, dma_addr_t src, size_t len)
 {
-	memcpy(dst, src, len);
+	memcpy((void *)dst, (void *)src, len);
 
 	return 0;
 }
diff --git a/drivers/dma/ti-edma3.c b/drivers/dma/ti-edma3.c
index ec3dc62..1ad3b92 100644
--- a/drivers/dma/ti-edma3.c
+++ b/drivers/dma/ti-edma3.c
@@ -13,6 +13,7 @@
 #include <common.h>
 #include <dm.h>
 #include <dma-uclass.h>
+#include <linux/dma-mapping.h>
 #include <asm/omap_common.h>
 #include <asm/ti-common/ti-edma3.h>
 
@@ -395,7 +396,7 @@
 }
 
 void __edma3_transfer(unsigned long edma3_base_addr, unsigned int edma_slot_num,
-		      void *dst, void *src, size_t len, size_t s_len)
+		      dma_addr_t dst, dma_addr_t src, size_t len, size_t s_len)
 {
 	struct edma3_slot_config        slot;
 	struct edma3_channel_config     edma_channel;
@@ -483,12 +484,14 @@
 }
 
 void __edma3_fill(unsigned long edma3_base_addr, unsigned int edma_slot_num,
-		  void *dst, u8 val, size_t len)
+		  dma_addr_t dst, u8 val, size_t len)
 {
 	int xfer_len;
 	int max_xfer = EDMA_FILL_BUFFER_SIZE * 65535;
+	dma_addr_t source;
 
 	memset((void *)edma_fill_buffer, val, sizeof(edma_fill_buffer));
+	source = dma_map_single(edma_fill_buffer, len, DMA_TO_DEVICE);
 
 	while (len) {
 		xfer_len = len;
@@ -496,11 +499,13 @@
 			xfer_len = max_xfer;
 
 		__edma3_transfer(edma3_base_addr, edma_slot_num, dst,
-				 edma_fill_buffer, xfer_len,
+				 source, xfer_len,
 				 EDMA_FILL_BUFFER_SIZE);
 		len -= xfer_len;
 		dst += xfer_len;
 	}
+
+	dma_unmap_single(source, len, DMA_FROM_DEVICE);
 }
 
 #ifndef CONFIG_DMA
@@ -508,19 +513,33 @@
 void edma3_transfer(unsigned long edma3_base_addr, unsigned int edma_slot_num,
 		    void *dst, void *src, size_t len)
 {
-	__edma3_transfer(edma3_base_addr, edma_slot_num, dst, src, len, len);
+	/* Clean the areas, so no writeback into the RAM races with DMA */
+	dma_addr_t destination = dma_map_single(dst, len, DMA_FROM_DEVICE);
+	dma_addr_t source = dma_map_single(src, len, DMA_TO_DEVICE);
+
+	__edma3_transfer(edma3_base_addr, edma_slot_num, destination, source, len, len);
+
+	/* Clean+Invalidate the areas after, so we can see DMA'd data */
+	dma_unmap_single(destination, len, DMA_FROM_DEVICE);
+	dma_unmap_single(source, len, DMA_TO_DEVICE);
 }
 
 void edma3_fill(unsigned long edma3_base_addr, unsigned int edma_slot_num,
 		void *dst, u8 val, size_t len)
 {
-	__edma3_fill(edma3_base_addr, edma_slot_num, dst, val, len);
+	/* Clean the area, so no writeback into the RAM races with DMA */
+	dma_addr_t destination = dma_map_single(dst, len, DMA_FROM_DEVICE);
+
+	__edma3_fill(edma3_base_addr, edma_slot_num, destination, val, len);
+
+	/* Clean+Invalidate the area after, so we can see DMA'd data */
+	dma_unmap_single(destination, len, DMA_FROM_DEVICE);
 }
 
 #else
 
-static int ti_edma3_transfer(struct udevice *dev, int direction, void *dst,
-			     void *src, size_t len)
+static int ti_edma3_transfer(struct udevice *dev, int direction,
+			     dma_addr_t dst, dma_addr_t src, size_t len)
 {
 	struct ti_edma3_priv *priv = dev_get_priv(dev);
 
diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
index 1a9197b..d92b964 100644
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -2305,7 +2305,7 @@
 }
 
 static int udma_transfer(struct udevice *dev, int direction,
-			 void *dst, void *src, size_t len)
+			 dma_addr_t dst, dma_addr_t src, size_t len)
 {
 	struct udma_dev *ud = dev_get_priv(dev);
 	/* Channel0 is reserved for memcpy */
@@ -2326,7 +2326,7 @@
 	if (ret)
 		return ret;
 
-	udma_prep_dma_memcpy(uc, (dma_addr_t)dst, (dma_addr_t)src, len);
+	udma_prep_dma_memcpy(uc, dst, src, len);
 	udma_start(uc);
 	udma_poll_completion(uc, &paddr);
 	udma_stop(uc);
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index b2f4a4e..a2595d1 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -644,7 +644,7 @@
 	      ((mmc->selected_mode == UHS_SDR50) && (val & CAPA2_TSDR50))))
 		return 0;
 
-	ret = uclass_first_device(UCLASS_THERMAL, &thermal_dev);
+	ret = uclass_first_device_err(UCLASS_THERMAL, &thermal_dev);
 	if (ret) {
 		printf("Couldn't get thermal device for tuning\n");
 		return ret;
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 058b2f6..5cff81a 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -1217,7 +1217,7 @@
 	 * Scan through all the PCI controllers. On x86 there will only be one
 	 * but that is not necessarily true on other hardware.
 	 */
-	do {
+	while (bus) {
 		device_find_first_child(bus, &dev);
 		if (dev) {
 			*devp = dev;
@@ -1226,7 +1226,7 @@
 		ret = uclass_next_device(&bus);
 		if (ret)
 			return ret;
-	} while (bus);
+	}
 
 	return 0;
 }
diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
index fb6b6cf..6646b15 100644
--- a/drivers/phy/ti/phy-j721e-wiz.c
+++ b/drivers/phy/ti/phy-j721e-wiz.c
@@ -69,14 +69,20 @@
 static const struct reg_field phy_reset_n = REG_FIELD(WIZ_SERDES_RST, 31, 31);
 static const struct reg_field pll1_refclk_mux_sel =
 					REG_FIELD(WIZ_SERDES_RST, 29, 29);
+static const struct reg_field pll1_refclk_mux_sel_2 =
+					REG_FIELD(WIZ_SERDES_RST, 22, 23);
 static const struct reg_field pll0_refclk_mux_sel =
 					REG_FIELD(WIZ_SERDES_RST, 28, 28);
+static const struct reg_field pll0_refclk_mux_sel_2 =
+					REG_FIELD(WIZ_SERDES_RST, 28, 29);
 static const struct reg_field refclk_dig_sel_16g =
 					REG_FIELD(WIZ_SERDES_RST, 24, 25);
 static const struct reg_field refclk_dig_sel_10g =
 					REG_FIELD(WIZ_SERDES_RST, 24, 24);
 static const struct reg_field pma_cmn_refclk_int_mode =
 					REG_FIELD(WIZ_SERDES_TOP_CTRL, 28, 29);
+static const struct reg_field pma_cmn_refclk1_int_mode =
+					REG_FIELD(WIZ_SERDES_TOP_CTRL, 20, 21);
 static const struct reg_field pma_cmn_refclk_mode =
 					REG_FIELD(WIZ_SERDES_TOP_CTRL, 30, 31);
 static const struct reg_field pma_cmn_refclk_dig_div =
@@ -204,6 +210,27 @@
 	},
 };
 
+static const struct wiz_clk_mux_sel clk_mux_sel_10g_2_refclk[] = {
+	{
+		.num_parents = 3,
+		.parents = { WIZ_CORE_REFCLK, WIZ_CORE_REFCLK1, WIZ_EXT_REFCLK },
+		.table = { 2, 3, 0 },
+		.node_name = "pll0-refclk",
+	},
+	{
+		.num_parents = 3,
+		.parents = { WIZ_CORE_REFCLK, WIZ_CORE_REFCLK1, WIZ_EXT_REFCLK },
+		.table = { 2, 3, 0 },
+		.node_name = "pll1-refclk",
+	},
+	{
+		.num_parents = 3,
+		.parents = { WIZ_CORE_REFCLK, WIZ_CORE_REFCLK1, WIZ_EXT_REFCLK },
+		.table = { 2, 3, 0 },
+		.node_name = "refclk-dig",
+	},
+};
+
 static struct wiz_clk_div_sel clk_div_sel[] = {
 	{
 		.div_sel = CMN_REFCLK,
@@ -219,6 +246,7 @@
 	J721E_WIZ_16G,
 	J721E_WIZ_10G,
 	AM64_WIZ_10G,
+	J784S4_WIZ_10G,
 };
 
 struct wiz_data {
@@ -227,6 +255,7 @@
 	const struct reg_field *pll1_refclk_mux_sel;
 	const struct reg_field *refclk_dig_sel;
 	const struct reg_field *pma_cmn_refclk1_dig_div;
+	const struct reg_field *pma_cmn_refclk1_int_mode;
 	const struct wiz_clk_mux_sel *clk_mux_sel;
 	unsigned int clk_div_sel_num;
 };
@@ -259,6 +288,16 @@
 	.clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_10G,
 };
 
+static struct wiz_data j784s4_wiz_10g = {
+	.type = J784S4_WIZ_10G,
+	.pll0_refclk_mux_sel = &pll0_refclk_mux_sel_2,
+	.pll1_refclk_mux_sel = &pll1_refclk_mux_sel_2,
+	.refclk_dig_sel = &refclk_dig_sel_16g,
+	.pma_cmn_refclk1_int_mode = &pma_cmn_refclk1_int_mode,
+	.clk_mux_sel = clk_mux_sel_10g_2_refclk,
+	.clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_10G,
+};
+
 #define WIZ_TYPEC_DIR_DEBOUNCE_MIN	100	/* ms */
 #define WIZ_TYPEC_DIR_DEBOUNCE_MAX	1000
 
@@ -279,6 +318,7 @@
 	struct regmap_field	*p_mac_div_sel1[WIZ_MAX_LANES];
 	struct regmap_field	*p0_fullrt_div[WIZ_MAX_LANES];
 	struct regmap_field	*pma_cmn_refclk_int_mode;
+	struct regmap_field	*pma_cmn_refclk1_int_mode;
 	struct regmap_field	*pma_cmn_refclk_mode;
 	struct regmap_field	*pma_cmn_refclk_dig_div;
 	struct regmap_field	*pma_cmn_refclk1_dig_div;
@@ -729,6 +769,15 @@
 		return PTR_ERR(wiz->pma_cmn_refclk_int_mode);
 	}
 
+	if (data->pma_cmn_refclk1_int_mode) {
+		wiz->pma_cmn_refclk1_int_mode =
+			devm_regmap_field_alloc(dev, regmap, *data->pma_cmn_refclk1_int_mode);
+		if (IS_ERR(wiz->pma_cmn_refclk1_int_mode)) {
+			dev_err(dev, "PMA_CMN_REFCLK1_INT_MODE reg field init failed\n");
+			return PTR_ERR(wiz->pma_cmn_refclk1_int_mode);
+		}
+	}
+
 	wiz->pma_cmn_refclk_mode =
 		devm_regmap_field_alloc(dev, regmap, pma_cmn_refclk_mode);
 	if (IS_ERR(wiz->pma_cmn_refclk_mode)) {
@@ -844,8 +893,6 @@
 		return ret;
 	}
 	wiz->input_clks[WIZ_CORE_REFCLK] = clk;
-	/* Initialize CORE_REFCLK1 to the same clock reference to maintain old DT compatibility */
-	wiz->input_clks[WIZ_CORE_REFCLK1] = clk;
 
 	rate = clk_get_rate(clk);
 	if (rate >= 100000000)
@@ -853,6 +900,25 @@
 	else
 		regmap_field_write(wiz->pma_cmn_refclk_int_mode, 0x3);
 
+	if (wiz->data->pma_cmn_refclk1_int_mode) {
+		clk = devm_clk_get(dev, "core_ref1_clk");
+		if (IS_ERR(clk)) {
+			dev_err(dev, "core_ref1_clk clock not found\n");
+			ret = PTR_ERR(clk);
+			return ret;
+		}
+		wiz->input_clks[WIZ_CORE_REFCLK1] = clk;
+
+		rate = clk_get_rate(clk);
+		if (rate >= 100000000)
+			regmap_field_write(wiz->pma_cmn_refclk1_int_mode, 0x1);
+		else
+			regmap_field_write(wiz->pma_cmn_refclk1_int_mode, 0x3);
+	} else {
+		/* Initialize CORE_REFCLK1 to the same clock reference to maintain old DT compatibility */
+		wiz->input_clks[WIZ_CORE_REFCLK1] = clk;
+	}
+
 	clk = devm_clk_get(dev, "ext_ref_clk");
 	if (IS_ERR(clk)) {
 		dev_err(dev, "ext_ref_clk clock not found\n");
@@ -933,7 +999,7 @@
 	ofnode node;
 	int i, rc;
 
-	if (type == AM64_WIZ_10G)
+	if (type == AM64_WIZ_10G || type == J784S4_WIZ_10G)
 		return j721e_wiz_bind_clocks(wiz);
 
 	div_clk_drv = lists_driver_lookup_name("wiz_div_clk");
@@ -1173,6 +1239,9 @@
 	{
 		.compatible = "ti,am64-wiz-10g", .data = (ulong)&am64_10g_data,
 	},
+	{
+		.compatible = "ti,j784s4-wiz-10g", .data = (ulong)&j784s4_wiz_10g,
+	},
 	{}
 };
 
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index da3e1eb..83cda1f 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -143,7 +143,7 @@
 #else
 		if (!uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) ||
 		    !uclass_get_device(UCLASS_SERIAL, INDEX, &dev) ||
-		    (!uclass_first_device(UCLASS_SERIAL, &dev) && dev)) {
+		    !uclass_first_device_err(UCLASS_SERIAL, &dev)) {
 			gd->cur_serial_dev = dev;
 			return;
 		}
diff --git a/drivers/serial/serial_bcm283x_mu.c b/drivers/serial/serial_bcm283x_mu.c
index 493a42b..12cbcb9 100644
--- a/drivers/serial/serial_bcm283x_mu.c
+++ b/drivers/serial/serial_bcm283x_mu.c
@@ -147,7 +147,7 @@
 	int serial_gpio = 15;
 	struct udevice *dev;
 
-	if (uclass_first_device(UCLASS_PINCTRL, &dev) || !dev)
+	if (uclass_first_device_err(UCLASS_PINCTRL, &dev))
 		return false;
 
 	if (pinctrl_get_gpio_mux(dev, 0, serial_gpio) != BCM2835_GPIO_ALT5)
diff --git a/drivers/serial/serial_bcm283x_pl011.c b/drivers/serial/serial_bcm283x_pl011.c
index fe74629..7d172cd 100644
--- a/drivers/serial/serial_bcm283x_pl011.c
+++ b/drivers/serial/serial_bcm283x_pl011.c
@@ -24,7 +24,7 @@
 	int serial_gpio = 15;
 	struct udevice *dev;
 
-	if (uclass_first_device(UCLASS_PINCTRL, &dev) || !dev)
+	if (uclass_first_device_err(UCLASS_PINCTRL, &dev))
 		return false;
 
 	if (pinctrl_get_gpio_mux(dev, 0, serial_gpio) != BCM2835_GPIO_ALT0)
diff --git a/drivers/sysreset/sysreset_ast.c b/drivers/sysreset/sysreset_ast.c
index d747ed0..92fad96 100644
--- a/drivers/sysreset/sysreset_ast.c
+++ b/drivers/sysreset/sysreset_ast.c
@@ -18,7 +18,7 @@
 {
 	struct udevice *wdt;
 	u32 reset_mode;
-	int ret = uclass_first_device(UCLASS_WDT, &wdt);
+	int ret = uclass_first_device_err(UCLASS_WDT, &wdt);
 
 	if (ret)
 		return ret;
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 6ce389d..43aec7f 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -2636,18 +2636,17 @@
 
 int usb_ether_init(void)
 {
-	struct udevice *dev;
 	struct udevice *usb_dev;
 	int ret;
 
-	ret = uclass_first_device(UCLASS_USB_GADGET_GENERIC, &usb_dev);
-	if (!usb_dev || ret) {
+	uclass_first_device(UCLASS_USB_GADGET_GENERIC, &usb_dev);
+	if (!usb_dev) {
 		pr_err("No USB device found\n");
-		return ret;
+		return -ENODEV;
 	}
 
-	ret = device_bind_driver(usb_dev, "usb_ether", "usb_ether", &dev);
-	if (!dev || ret) {
+	ret = device_bind_driver(usb_dev, "usb_ether", "usb_ether", NULL);
+	if (ret) {
 		pr_err("usb - not able to bind usb_ether device\n");
 		return ret;
 	}
diff --git a/drivers/video/exynos/exynos_fb.c b/drivers/video/exynos/exynos_fb.c
index 69992b3..86970a6 100644
--- a/drivers/video/exynos/exynos_fb.c
+++ b/drivers/video/exynos/exynos_fb.c
@@ -640,25 +640,17 @@
 #endif
 	exynos_fimd_lcd_init(dev);
 
-	ret = uclass_first_device(UCLASS_PANEL, &panel);
+	ret = uclass_first_device_err(UCLASS_PANEL, &panel);
 	if (ret) {
-		printf("LCD panel failed to probe\n");
+		printf("%s: LCD panel failed to probe %d\n", __func__, ret);
 		return ret;
 	}
-	if (!panel) {
-		printf("LCD panel not found\n");
-		return -ENODEV;
-	}
 
-	ret = uclass_first_device(UCLASS_DISPLAY, &dp);
+	ret = uclass_first_device_err(UCLASS_DISPLAY, &dp);
 	if (ret) {
 		debug("%s: Display device error %d\n", __func__, ret);
 		return ret;
 	}
-	if (!dev) {
-		debug("%s: Display device missing\n", __func__);
-		return -ENODEV;
-	}
 	ret = display_enable(dp, 18, NULL);
 	if (ret) {
 		debug("%s: Display enable error %d\n", __func__, ret);
diff --git a/drivers/video/imx/mxc_ipuv3_fb.c b/drivers/video/imx/mxc_ipuv3_fb.c
index 49bbeef..8b01a1b 100644
--- a/drivers/video/imx/mxc_ipuv3_fb.c
+++ b/drivers/video/imx/mxc_ipuv3_fb.c
@@ -609,12 +609,11 @@
 		return ret;
 
 #if defined(CONFIG_DISPLAY)
-	ret = uclass_first_device(UCLASS_DISPLAY, &disp_dev);
-	if (disp_dev) {
+	ret = uclass_first_device_err(UCLASS_DISPLAY, &disp_dev);
+	if (!ret)
 		ret = display_enable(disp_dev, 16, NULL);
-		if (ret < 0)
-			return ret;
-	}
+	if (ret < 0)
+		return ret;
 #endif
 	if (CONFIG_IS_ENABLED(PANEL)) {
 		struct udevice *panel_dev;
diff --git a/drivers/video/mali_dp.c b/drivers/video/mali_dp.c
index ba1ddd6..cbcdb99 100644
--- a/drivers/video/mali_dp.c
+++ b/drivers/video/mali_dp.c
@@ -244,7 +244,7 @@
 	struct udevice *disp_dev;
 	int err;
 
-	err = uclass_first_device(UCLASS_DISPLAY, &disp_dev);
+	err = uclass_first_device_err(UCLASS_DISPLAY, &disp_dev);
 	if (err)
 		return err;
 
diff --git a/drivers/video/stm32/stm32_dsi.c b/drivers/video/stm32/stm32_dsi.c
index 5871ac7..e6347bb 100644
--- a/drivers/video/stm32/stm32_dsi.c
+++ b/drivers/video/stm32/stm32_dsi.c
@@ -346,7 +346,7 @@
 	struct display_timing timings;
 	int ret;
 
-	ret = uclass_first_device(UCLASS_PANEL, &priv->panel);
+	ret = uclass_first_device_err(UCLASS_PANEL, &priv->panel);
 	if (ret) {
 		dev_err(dev, "panel device error %d\n", ret);
 		return ret;
diff --git a/drivers/video/tegra124/dp.c b/drivers/video/tegra124/dp.c
index ee4f09a..b27b163 100644
--- a/drivers/video/tegra124/dp.c
+++ b/drivers/video/tegra124/dp.c
@@ -1494,8 +1494,8 @@
 		return -ENOLINK;
 	}
 
-	ret = uclass_first_device(UCLASS_VIDEO_BRIDGE, &sor);
-	if (ret || !sor) {
+	ret = uclass_first_device_err(UCLASS_VIDEO_BRIDGE, &sor);
+	if (ret) {
 		debug("dp: failed to find SOR device: ret=%d\n", ret);
 		return ret;
 	}
diff --git a/drivers/virtio/virtio-uclass.c b/drivers/virtio/virtio-uclass.c
index 9e2d0e0..da4f2f26 100644
--- a/drivers/virtio/virtio-uclass.c
+++ b/drivers/virtio/virtio-uclass.c
@@ -183,21 +183,8 @@
 
 int virtio_init(void)
 {
-	struct udevice *bus;
-	int ret;
-
 	/* Enumerate all known virtio devices */
-	ret = uclass_first_device(UCLASS_VIRTIO, &bus);
-	if (ret)
-		return ret;
-
-	while (bus) {
-		ret = uclass_next_device(&bus);
-		if (ret)
-			break;
-	}
-
-	return ret;
+	return uclass_probe_all(UCLASS_VIRTIO);
 }
 
 static int virtio_uclass_pre_probe(struct udevice *udev)
diff --git a/drivers/w1/w1-uclass.c b/drivers/w1/w1-uclass.c
index 52b519c..de4f25b 100644
--- a/drivers/w1/w1-uclass.c
+++ b/drivers/w1/w1-uclass.c
@@ -16,6 +16,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <errno.h>
 #include <log.h>
 #include <w1.h>
 #include <w1-eeprom.h>
@@ -182,24 +183,25 @@
 int w1_get_bus(int busnum, struct udevice **busp)
 {
 	int ret, i = 0;
-
 	struct udevice *dev;
 
-	for (ret = uclass_first_device(UCLASS_W1, &dev);
-	     dev && !ret;
-	     ret = uclass_next_device(&dev), i++) {
+	for (ret = uclass_first_device_check(UCLASS_W1, &dev);
+			dev;
+			ret = uclass_next_device_check(&dev), i++) {
 		if (i == busnum) {
+			if (ret) {
+				debug("Cannot probe w1 bus %d: %d (%s)\n",
+				      busnum, ret, errno_str(ret));
+				return ret;
+			}
 			*busp = dev;
 			return 0;
 		}
 	}
 
-	if (!ret) {
-		debug("Cannot find w1 bus %d\n", busnum);
-		ret = -ENODEV;
-	}
+	debug("Cannot find w1 bus %d\n", busnum);
 
-	return ret;
+	return -ENODEV;
 }
 
 u8 w1_get_device_family(struct udevice *dev)
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index ca2bc7c..f0e57b4 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -39,7 +39,7 @@
 #include <common.h>
 #include <log.h>
 #include <watchdog.h>
-#include <asm/arch/hardware.h>
+#include <asm/ti-common/omap_wdt.h>
 #include <asm/io.h>
 #include <asm/processor.h>
 #include <asm/arch/cpu.h>
diff --git a/drivers/xen/pvblock.c b/drivers/xen/pvblock.c
index 970182c..95e298d 100644
--- a/drivers/xen/pvblock.c
+++ b/drivers/xen/pvblock.c
@@ -852,10 +852,7 @@
 	ret = uclass_get(UCLASS_BLK, &uc);
 	if (ret)
 		return ret;
-	uclass_foreach_dev_probe(UCLASS_BLK, udev) {
-		if (_ret)
-			return _ret;
-	};
+	uclass_foreach_dev_probe(UCLASS_BLK, udev);
 	return 0;
 }
 
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index c80f8e8..3f0d9f1 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 #include <common.h>
 #include <fs_internal.h>
+#include <log.h>
 #include <uuid.h>
 #include <memalign.h>
 #include "kernel-shared/btrfs_tree.h"
@@ -910,9 +911,9 @@
 
 	if (round_up(BTRFS_SUPER_INFO_SIZE + BTRFS_SUPER_INFO_OFFSET,
 		     desc->blksz) > (part->size << desc->log2blksz)) {
-		error("superblock end %u is larger than device size " LBAFU,
-				BTRFS_SUPER_INFO_SIZE + BTRFS_SUPER_INFO_OFFSET,
-				part->size << desc->log2blksz);
+		log_debug("superblock end %u is larger than device size " LBAFU,
+			  BTRFS_SUPER_INFO_SIZE + BTRFS_SUPER_INFO_OFFSET,
+			  part->size << desc->log2blksz);
 		return -EINVAL;
 	}
 
diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
index d49ba4a..1185cb2 100644
--- a/fs/ext4/ext4_common.c
+++ b/fs/ext4/ext4_common.c
@@ -2415,7 +2415,7 @@
 
 	return 1;
 fail:
-	printf("Failed to mount ext2 filesystem...\n");
+	log_debug("Failed to mount ext2 filesystem...\n");
 fail_noerr:
 	free(data);
 	ext4fs_root = NULL;
diff --git a/fs/fs_internal.c b/fs/fs_internal.c
index ae1cb85..111f91b 100644
--- a/fs/fs_internal.c
+++ b/fs/fs_internal.c
@@ -29,8 +29,7 @@
 	/* Check partition boundaries */
 	if ((sector + ((byte_offset + byte_len - 1) >> log2blksz))
 	    >= partition->size) {
-		log_err("%s read outside partition " LBAFU "\n", __func__,
-			sector);
+		log_debug("read outside partition " LBAFU "\n", sector);
 		return 0;
 	}
 
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index 7aae2c2..fa98656 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -59,6 +59,9 @@
 /**
  * oftree_from_fdt() - Returns an oftree from a flat device tree pointer
  *
+ * If @fdt is not already registered in the list of current device trees, it is
+ * added to the list.
+ *
  * @fdt: Device tree to use
  *
  * Returns: reference to the given node
diff --git a/include/dm/uclass.h b/include/dm/uclass.h
index f6c0110..823a165 100644
--- a/include/dm/uclass.h
+++ b/include/dm/uclass.h
@@ -333,17 +333,6 @@
 int uclass_first_device(enum uclass_id id, struct udevice **devp);
 
 /**
- * uclass_first_device_err() - Get the first device in a uclass
- *
- * The device returned is probed if necessary, and ready for use
- *
- * @id: Uclass ID to look up
- * @devp: Returns pointer to the first device in that uclass, or NULL if none
- * Return: 0 if found, -ENODEV if not found, other -ve on error
- */
-int uclass_first_device_err(enum uclass_id id, struct udevice **devp);
-
-/**
  * uclass_next_device() - Get the next device in a uclass
  *
  * The device returned is probed if necessary, and ready for use
@@ -359,6 +348,17 @@
 int uclass_next_device(struct udevice **devp);
 
 /**
+ * uclass_first_device_err() - Get the first device in a uclass
+ *
+ * The device returned is probed if necessary, and ready for use
+ *
+ * @id: Uclass ID to look up
+ * @devp: Returns pointer to the first device in that uclass, or NULL if none
+ * Return: 0 if found, -ENODEV if not found, other -ve on error
+ */
+int uclass_first_device_err(enum uclass_id id, struct udevice **devp);
+
+/**
  * uclass_next_device_err() - Get the next device in a uclass
  *
  * The device returned is probed if necessary, and ready for use
@@ -491,7 +491,7 @@
  * are no more devices.
  */
 #define uclass_foreach_dev_probe(id, dev)	\
-	for (int _ret = uclass_first_device_err(id, &dev); !_ret && dev; \
-	     _ret = uclass_next_device_err(&dev))
+	for (uclass_first_device(id, &dev); dev; \
+	     uclass_next_device(&dev))
 
 #endif
diff --git a/include/dma-uclass.h b/include/dma-uclass.h
index 340437a..ea721ba 100644
--- a/include/dma-uclass.h
+++ b/include/dma-uclass.h
@@ -132,8 +132,8 @@
 	 * @len: Length of the data to be copied (number of bytes).
 	 * @return zero on success, or -ve error code.
 	 */
-	int (*transfer)(struct udevice *dev, int direction, void *dst,
-			void *src, size_t len);
+	int (*transfer)(struct udevice *dev, int direction, dma_addr_t dst,
+			dma_addr_t src, size_t len);
 };
 
 #endif /* _DMA_UCLASS_H */
diff --git a/lib/acpi/acpi_table.c b/lib/acpi/acpi_table.c
index f8642f9..7c4189e 100644
--- a/lib/acpi/acpi_table.c
+++ b/lib/acpi/acpi_table.c
@@ -40,7 +40,7 @@
 	struct udevice *cpu;
 	int ret;
 
-	ret = uclass_first_device(UCLASS_CPU, &cpu);
+	ret = uclass_first_device_err(UCLASS_CPU, &cpu);
 	if (ret)
 		return log_msg_ret("cpu", ret);
 	ret = cpu_get_info(cpu, &info);
diff --git a/lib/efi_loader/efi_gop.c b/lib/efi_loader/efi_gop.c
index 5908b5c..20bd7ff 100644
--- a/lib/efi_loader/efi_gop.c
+++ b/lib/efi_loader/efi_gop.c
@@ -482,7 +482,7 @@
 	struct video_priv *priv;
 
 	/* We only support a single video output device for now */
-	if (uclass_first_device(UCLASS_VIDEO, &vdev) || !vdev) {
+	if (uclass_first_device_err(UCLASS_VIDEO, &vdev)) {
 		debug("WARNING: No video device\n");
 		return EFI_SUCCESS;
 	}
diff --git a/net/eth-uclass.c b/net/eth-uclass.c
index 0f6b45b..f41da4b 100644
--- a/net/eth-uclass.c
+++ b/net/eth-uclass.c
@@ -91,8 +91,10 @@
 		eth_errno = uclass_get_device_by_seq(UCLASS_ETH, 0,
 						     &uc_priv->current);
 		if (eth_errno)
-			eth_errno = uclass_first_device(UCLASS_ETH,
-							&uc_priv->current);
+			eth_errno = uclass_first_device_err(UCLASS_ETH,
+							    &uc_priv->current);
+		if (eth_errno)
+			uc_priv->current = NULL;
 	}
 	return uc_priv->current;
 }
diff --git a/test/boot/Makefile b/test/boot/Makefile
index 9e9d5ae..5bb3f88 100644
--- a/test/boot/Makefile
+++ b/test/boot/Makefile
@@ -7,3 +7,4 @@
 ifdef CONFIG_OF_LIVE
 obj-$(CONFIG_BOOTMETH_VBE_SIMPLE) += vbe_simple.o
 endif
+obj-$(CONFIG_BOOTMETH_VBE) += vbe_fixup.o
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index 8530523..1e8ea75 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -329,6 +329,8 @@
 {
 	struct udevice *dev;
 
+	if (!IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR))
+		return 0;
 	ut_assertok(uclass_get_device_by_name(UCLASS_BOOTMETH, "efi_mgr",
 					      &dev));
 	sandbox_set_fake_efi_mgr_dev(dev, true);
diff --git a/test/boot/bootmeth.c b/test/boot/bootmeth.c
index fb62731..f0b5ab9 100644
--- a/test/boot/bootmeth.c
+++ b/test/boot/bootmeth.c
@@ -156,7 +156,7 @@
 	struct udevice *dev;
 	char buf[50];
 
-	ut_assertok(uclass_first_device(UCLASS_BOOTMETH, &dev));
+	ut_assertok(uclass_first_device_err(UCLASS_BOOTMETH, &dev));
 	ut_assertnonnull(dev);
 
 	ut_assertok(bootmeth_get_state_desc(dev, buf, sizeof(buf)));
diff --git a/test/boot/bootstd_common.c b/test/boot/bootstd_common.c
index 05347d8..7a40836 100644
--- a/test/boot/bootstd_common.c
+++ b/test/boot/bootstd_common.c
@@ -9,10 +9,52 @@
 #include <common.h>
 #include <bootstd.h>
 #include <dm.h>
+#include <memalign.h>
+#include <mmc.h>
+#include <linux/log2.h>
 #include <test/suites.h>
 #include <test/ut.h>
+#include <u-boot/crc.h>
 #include "bootstd_common.h"
 
+/* tracks whether bootstd_setup_for_tests() has been run yet */
+bool vbe_setup_done;
+
+/* set up MMC for VBE tests */
+int bootstd_setup_for_tests(void)
+{
+	ALLOC_CACHE_ALIGN_BUFFER(u8, buf, MMC_MAX_BLOCK_LEN);
+	struct udevice *mmc;
+	struct blk_desc *desc;
+	int ret;
+
+	if (vbe_setup_done)
+		return 0;
+
+	/* Set up the version string */
+	ret = uclass_get_device(UCLASS_MMC, 1, &mmc);
+	if (ret)
+		return log_msg_ret("mmc", -EIO);
+	desc = blk_get_by_device(mmc);
+
+	memset(buf, '\0', MMC_MAX_BLOCK_LEN);
+	strcpy(buf, TEST_VERSION);
+	if (blk_dwrite(desc, VERSION_START_BLK, 1, buf) != 1)
+		return log_msg_ret("wr1", -EIO);
+
+	/* Set up the nvdata */
+	memset(buf, '\0', MMC_MAX_BLOCK_LEN);
+	buf[1] = ilog2(0x40) << 4 | 1;
+	*(u32 *)(buf + 4) = TEST_VERNUM;
+	buf[0] = crc8(0, buf + 1, 0x3f);
+	if (blk_dwrite(desc, NVDATA_START_BLK, 1, buf) != 1)
+		return log_msg_ret("wr2", -EIO);
+
+	vbe_setup_done = true;
+
+	return 0;
+}
+
 int bootstd_test_drop_bootdev_order(struct unit_test_state *uts)
 {
 	struct bootstd_priv *priv;
@@ -29,6 +71,13 @@
 {
 	struct unit_test *tests = UNIT_TEST_SUITE_START(bootstd_test);
 	const int n_ents = UNIT_TEST_SUITE_COUNT(bootstd_test);
+	int ret;
+
+	ret = bootstd_setup_for_tests();
+	if (ret) {
+		printf("Failed to set up for bootstd tests (err=%d)\n", ret);
+		return CMD_RET_FAILURE;
+	}
 
 	return cmd_ut_category("bootstd", "bootstd_test_",
 			       tests, n_ents, argc, argv);
diff --git a/test/boot/bootstd_common.h b/test/boot/bootstd_common.h
index 676ef0a..c5e0fd1 100644
--- a/test/boot/bootstd_common.h
+++ b/test/boot/bootstd_common.h
@@ -9,10 +9,17 @@
 #ifndef __bootstd_common_h
 #define __bootstd_common_h
 
+#include <version_string.h>
+
 /* Declare a new bootdev test */
 #define BOOTSTD_TEST(_name, _flags) \
 		UNIT_TEST(_name, _flags, bootstd_test)
 
+#define NVDATA_START_BLK	((0x400 + 0x400) / MMC_MAX_BLOCK_LEN)
+#define VERSION_START_BLK	((0x400 + 0x800) / MMC_MAX_BLOCK_LEN)
+#define TEST_VERSION		"U-Boot v2022.04-local2"
+#define TEST_VERNUM		0x00010002
+
 struct unit_test_state;
 
 /**
@@ -24,4 +31,13 @@
  */
 int bootstd_test_drop_bootdev_order(struct unit_test_state *uts);
 
+/**
+ * bootstd_setup_for_tests() - Set up MMC data for VBE tests
+ *
+ * Some data is needed for VBE tests to work. This function sets that up.
+ *
+ * @return 0 if OK, -ve on error
+ */
+int bootstd_setup_for_tests(void);
+
 #endif
diff --git a/test/boot/vbe_fixup.c b/test/boot/vbe_fixup.c
new file mode 100644
index 0000000..1b488e2
--- /dev/null
+++ b/test/boot/vbe_fixup.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test for VBE device tree fix-ups
+ *
+ * Copyright 2022 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <dm/ofnode.h>
+#include <linux/libfdt.h>
+#include <test/test.h>
+#include <test/ut.h>
+#include "bootstd_common.h"
+
+/* Basic test of reading nvdata and updating a fwupd node in the device tree */
+static int vbe_test_fixup(struct unit_test_state *uts)
+{
+	ofnode chosen, node;
+	const char *data;
+	oftree tree;
+	int size;
+
+	/*
+	 * This test works when called from test_vbe.py and it must use the
+	 * flat tree, since device tree fix-ups do not yet support live tree.
+	 */
+	if (!working_fdt)
+		return 0;
+
+	tree = oftree_from_fdt(working_fdt);
+	ut_assert(oftree_valid(tree));
+
+	chosen = oftree_path(tree, "/chosen");
+	ut_assert(ofnode_valid(chosen));
+
+	/* check the things set up for the FIT in test_vbe.py */
+	node = ofnode_find_subnode(chosen, "random");
+
+	/* ignore if this test is run on its own */
+	if (!ofnode_valid(node))
+		return 0;
+	data = ofnode_read_prop(node, "data", &size);
+	ut_asserteq(0x40, size);
+
+	node = ofnode_find_subnode(chosen, "aslr2");
+	ut_assert(ofnode_valid(node));
+	data = ofnode_read_prop(node, "data", &size);
+	ut_asserteq(4, size);
+
+	node = ofnode_find_subnode(chosen, "efi-runtime");
+	ut_assert(ofnode_valid(node));
+	data = ofnode_read_prop(node, "data", &size);
+	ut_asserteq(4, size);
+
+	return 0;
+}
+BOOTSTD_TEST(vbe_test_fixup,
+	     UT_TESTF_DM | UT_TESTF_SCAN_FDT | UT_TESTF_FLAT_TREE);
diff --git a/test/boot/vbe_simple.c b/test/boot/vbe_simple.c
index 8acd777..faba9e8 100644
--- a/test/boot/vbe_simple.c
+++ b/test/boot/vbe_simple.c
@@ -10,54 +10,27 @@
 #include <bootmeth.h>
 #include <dm.h>
 #include <image.h>
-#include <memalign.h>
-#include <mmc.h>
 #include <of_live.h>
 #include <vbe.h>
-#include <version_string.h>
-#include <linux/log2.h>
 #include <test/suites.h>
 #include <test/ut.h>
-#include <u-boot/crc.h>
 #include "bootstd_common.h"
 
-#define NVDATA_START_BLK	((0x400 + 0x400) / MMC_MAX_BLOCK_LEN)
-#define VERSION_START_BLK	((0x400 + 0x800) / MMC_MAX_BLOCK_LEN)
-#define TEST_VERSION		"U-Boot v2022.04-local2"
-#define TEST_VERNUM		0x00010002
-
 /* Basic test of reading nvdata and updating a fwupd node in the device tree */
 static int vbe_simple_test_base(struct unit_test_state *uts)
 {
-	ALLOC_CACHE_ALIGN_BUFFER(u8, buf, MMC_MAX_BLOCK_LEN);
 	const char *version, *bl_version;
 	struct event_ft_fixup fixup;
-	struct udevice *dev, *mmc;
+	struct udevice *dev;
 	struct device_node *np;
-	struct blk_desc *desc;
 	char fdt_buf[0x400];
 	char info[100];
 	int node_ofs;
 	ofnode node;
 	u32 vernum;
 
-	/* Set up the version string */
-	ut_assertok(uclass_get_device(UCLASS_MMC, 1, &mmc));
-	desc = blk_get_by_device(mmc);
-	ut_assertnonnull(desc);
-
-	memset(buf, '\0', MMC_MAX_BLOCK_LEN);
-	strcpy(buf, TEST_VERSION);
-	if (blk_dwrite(desc, VERSION_START_BLK, 1, buf) != 1)
-		return log_msg_ret("write", -EIO);
-
-	/* Set up the nvdata */
-	memset(buf, '\0', MMC_MAX_BLOCK_LEN);
-	buf[1] = ilog2(0x40) << 4 | 1;
-	*(u32 *)(buf + 4) = TEST_VERNUM;
-	buf[0] = crc8(0, buf + 1, 0x3f);
-	if (blk_dwrite(desc, NVDATA_START_BLK, 1, buf) != 1)
-		return log_msg_ret("write", -EIO);
+	/* Set up the VBE info */
+	ut_assertok(bootstd_setup_for_tests());
 
 	/* Read the version back */
 	ut_assertok(vbe_find_by_any("firmware0", &dev));
@@ -90,6 +63,7 @@
 	 *
 	 * Two fix this we need image_setup_libfdt() is updated to use ofnode
 	 */
+	fixup.images = NULL;
 	ut_assertok(event_notify(EVT_FT_FIXUP, &fixup, sizeof(fixup)));
 
 	node = oftree_path(fixup.tree, "/chosen/fwupd/firmware0");
diff --git a/test/cmd/fdt.c b/test/cmd/fdt.c
index 100a7ef..ba9eaa4 100644
--- a/test/cmd/fdt.c
+++ b/test/cmd/fdt.c
@@ -55,6 +55,7 @@
 
 	/* The working fdt is not set, so this should fail */
 	set_working_fdt_addr(0);
+	ut_assert_nextline("Working FDT set to 0");
 	ut_asserteq(CMD_RET_FAILURE, run_command("fdt addr", 0));
 	ut_assert_nextline("libfdt fdt_check_header(): FDT_ERR_BADMAGIC");
 	ut_assertok(ut_check_console_end(uts));
@@ -63,18 +64,22 @@
 	ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt)));
 	addr = map_to_sysmem(fdt);
 	set_working_fdt_addr(addr);
+	ut_assert_nextline("Working FDT set to %lx", addr);
 	ut_assertok(run_command("fdt addr", 0));
 	ut_assert_nextline("Working fdt: %08lx", (ulong)map_to_sysmem(fdt));
 	ut_assertok(ut_check_console_end(uts));
 
 	/* Set the working FDT */
 	set_working_fdt_addr(0);
+	ut_assert_nextline("Working FDT set to 0");
 	ut_assertok(run_commandf("fdt addr %08x", addr));
+	ut_assert_nextline("Working FDT set to %lx", addr);
 	ut_asserteq(addr, map_to_sysmem(working_fdt));
 	ut_assertok(ut_check_console_end(uts));
 	set_working_fdt_addr(0);
+	ut_assert_nextline("Working FDT set to 0");
 
-	/* Set the working FDT */
+	/* Set the control FDT */
 	fdt_blob = gd->fdt_blob;
 	gd->fdt_blob = NULL;
 	ret = run_commandf("fdt addr -c %08x", addr);
@@ -93,6 +98,7 @@
 	/* Test detecting an invalid FDT */
 	fdt[0] = 123;
 	set_working_fdt_addr(addr);
+	ut_assert_nextline("Working FDT set to %lx", addr);
 	ut_asserteq(1, run_commandf("fdt addr"));
 	ut_assert_nextline("libfdt fdt_check_header(): FDT_ERR_BADMAGIC");
 	ut_assertok(ut_check_console_end(uts));
@@ -115,16 +121,19 @@
 	/* Test setting and resizing the working FDT to a larger size */
 	ut_assertok(console_record_reset_enable());
 	ut_assertok(run_commandf("fdt addr %08x %x", addr, newsize));
+	ut_assert_nextline("Working FDT set to %lx", addr);
 	ut_assertok(ut_check_console_end(uts));
 
 	/* Try shrinking it */
 	ut_assertok(run_commandf("fdt addr %08x %x", addr, sizeof(fdt) / 4));
+	ut_assert_nextline("Working FDT set to %lx", addr);
 	ut_assert_nextline("New length %d < existing length %d, ignoring",
 			   (int)sizeof(fdt) / 4, newsize);
 	ut_assertok(ut_check_console_end(uts));
 
 	/* ...quietly */
 	ut_assertok(run_commandf("fdt addr -q %08x %x", addr, sizeof(fdt) / 4));
+	ut_assert_nextline("Working FDT set to %lx", addr);
 	ut_assertok(ut_check_console_end(uts));
 
 	/* We cannot easily provoke errors in fdt_open_into(), so ignore that */
diff --git a/test/dm/acpi.c b/test/dm/acpi.c
index edad913..9634fc2 100644
--- a/test/dm/acpi.c
+++ b/test/dm/acpi.c
@@ -169,28 +169,28 @@
 	ut_asserteq_str("GHIJ", name);
 
 	/* Test getting the name from acpi_device_get_name() */
-	ut_assertok(uclass_first_device(UCLASS_I2C, &i2c));
+	ut_assertok(uclass_first_device_err(UCLASS_I2C, &i2c));
 	ut_assertok(acpi_get_name(i2c, name));
 	ut_asserteq_str("I2C0", name);
 
-	ut_assertok(uclass_first_device(UCLASS_SPI, &spi));
+	ut_assertok(uclass_first_device_err(UCLASS_SPI, &spi));
 	ut_assertok(acpi_get_name(spi, name));
 	ut_asserteq_str("SPI0", name);
 
 	/* ACPI doesn't know about the timer */
-	ut_assertok(uclass_first_device(UCLASS_TIMER, &timer));
+	ut_assertok(uclass_first_device_err(UCLASS_TIMER, &timer));
 	ut_asserteq(-ENOENT, acpi_get_name(timer, name));
 
 	/* May as well test the rest of the cases */
-	ut_assertok(uclass_first_device(UCLASS_SOUND, &sound));
+	ut_assertok(uclass_first_device_err(UCLASS_SOUND, &sound));
 	ut_assertok(acpi_get_name(sound, name));
 	ut_asserteq_str("HDAS", name);
 
-	ut_assertok(uclass_first_device(UCLASS_PCI, &pci));
+	ut_assertok(uclass_first_device_err(UCLASS_PCI, &pci));
 	ut_assertok(acpi_get_name(pci, name));
 	ut_asserteq_str("PCI0", name);
 
-	ut_assertok(uclass_first_device(UCLASS_ROOT, &root));
+	ut_assertok(uclass_first_device_err(UCLASS_ROOT, &root));
 	ut_assertok(acpi_get_name(root, name));
 	ut_asserteq_str("\\_SB", name);
 
@@ -219,7 +219,7 @@
 	struct acpi_dmar dmar;
 	struct udevice *cpu;
 
-	ut_assertok(uclass_first_device(UCLASS_CPU, &cpu));
+	ut_assertok(uclass_first_device_err(UCLASS_CPU, &cpu));
 	ut_assertnonnull(cpu);
 	ut_assertok(acpi_create_dmar(&dmar, DMAR_INTR_REMAP));
 	ut_asserteq(DMAR_INTR_REMAP, dmar.flags);
diff --git a/test/dm/core.c b/test/dm/core.c
index fd4d756..84eb76e 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -512,23 +512,15 @@
 	int i;
 
 	for (i = 0; i < 2; i++) {
-		struct udevice *dev;
 		int ret;
-		int id;
 
 		dm_leak_check_start(uts);
 
 		ut_assertok(dm_scan_plat(false));
 		ut_assertok(dm_scan_fdt(false));
 
-		/* Scanning the uclass is enough to probe all the devices */
-		for (id = UCLASS_ROOT; id < UCLASS_COUNT; id++) {
-			for (ret = uclass_first_device(UCLASS_TEST, &dev);
-			     dev;
-			     ret = uclass_next_device(&dev))
-				;
-			ut_assertok(ret);
-		}
+		ret = uclass_probe_all(UCLASS_TEST);
+		ut_assertok(ret);
 
 		ut_assertok(dm_leak_check_end(uts));
 	}
@@ -653,10 +645,7 @@
 	ut_asserteq(2 + NODE_COUNT, dm_testdrv_op_count[DM_TEST_OP_PROBE]);
 
 	/* Probe everything */
-	for (ret = uclass_first_device(UCLASS_TEST, &dev);
-	     dev;
-	     ret = uclass_next_device(&dev))
-		;
+	ret = uclass_probe_all(UCLASS_TEST);
 	ut_assertok(ret);
 
 	ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_PROBE]);
diff --git a/test/dm/devres.c b/test/dm/devres.c
index 524114c..3df0f64 100644
--- a/test/dm/devres.c
+++ b/test/dm/devres.c
@@ -165,8 +165,8 @@
 	ut_asserteq(TEST_DEVRES_SIZE + TEST_DEVRES_SIZE3, stats.total_size);
 
 	/* Probing the device should add one allocation */
-	ut_assertok(uclass_first_device(UCLASS_TEST_DEVRES, &dev));
-	ut_assert(dev != NULL);
+	ut_assertok(uclass_first_device_err(UCLASS_TEST_DEVRES, &dev));
+	ut_assertnonnull(dev);
 	devres_get_stats(dev, &stats);
 	ut_asserteq(3, stats.allocs);
 	ut_asserteq(TEST_DEVRES_SIZE + TEST_DEVRES_SIZE2 + TEST_DEVRES_SIZE3,
diff --git a/test/dm/i2c.c b/test/dm/i2c.c
index 74b2097..b46a22e 100644
--- a/test/dm/i2c.c
+++ b/test/dm/i2c.c
@@ -124,7 +124,7 @@
 	ut_asserteq_mem(buf, "\0\0\0\0\0", sizeof(buf));
 
 	/* Tell the EEPROM to only read/write one register at a time */
-	ut_assertok(uclass_first_device(UCLASS_I2C_EMUL, &eeprom));
+	ut_assertok(uclass_first_device_err(UCLASS_I2C_EMUL, &eeprom));
 	ut_assertnonnull(eeprom);
 	sandbox_i2c_eeprom_set_test_mode(eeprom, SIE_TEST_MODE_SINGLE_BYTE);
 
@@ -177,7 +177,7 @@
 
 	/* Do a transfer so we can find the emulator */
 	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
-	ut_assertok(uclass_first_device(UCLASS_I2C_EMUL, &eeprom));
+	ut_assertok(uclass_first_device_err(UCLASS_I2C_EMUL, &eeprom));
 
 	/* Offset length 0 */
 	sandbox_i2c_eeprom_set_offset_len(eeprom, 0);
@@ -250,7 +250,7 @@
 
 	/* Do a transfer so we can find the emulator */
 	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
-	ut_assertok(uclass_first_device(UCLASS_I2C_EMUL, &eeprom));
+	ut_assertok(uclass_first_device_err(UCLASS_I2C_EMUL, &eeprom));
 
 	/* Offset length 0 */
 	sandbox_i2c_eeprom_set_offset_len(eeprom, 0);
@@ -315,7 +315,7 @@
 
 	/* Do a transfer so we can find the emulator */
 	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
-	ut_assertok(uclass_first_device(UCLASS_I2C_EMUL, &eeprom));
+	ut_assertok(uclass_first_device_err(UCLASS_I2C_EMUL, &eeprom));
 
 	/* Dummy data for the test */
 	ut_assertok(dm_i2c_write(dev, 0, "\xff\x00\xff\x00\x10", 5));
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index 012f2f4..1f14513 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -392,10 +392,10 @@
 	UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_FLAT_TREE);
 
 /**
- * Test various error conditions with uclass_first_device() and
- * uclass_next_device()
+ * Test various error conditions with uclass_first_device(),
+ * uclass_next_device(), and uclass_probe_all()
  */
-static int dm_test_first_next_device(struct unit_test_state *uts)
+static int dm_test_first_next_device_probeall(struct unit_test_state *uts)
 {
 	struct dm_testprobe_pdata *pdata;
 	struct udevice *dev, *parent = NULL;
@@ -428,9 +428,20 @@
 	device_remove(parent, DM_REMOVE_NORMAL);
 	ut_asserteq(-ENOENT, uclass_first_device(UCLASS_TEST_PROBE, &dev));
 
+	/* Now that broken devices are set up test probe_all */
+	device_remove(parent, DM_REMOVE_NORMAL);
+	/* There are broken devices so an error should be returned */
+	ut_assert(uclass_probe_all(UCLASS_TEST_PROBE) < 0);
+	/* but non-error device should be probed nonetheless */
+	ut_assertok(uclass_get_device(UCLASS_TEST_PROBE, 2, &dev));
+	ut_assert(dev_get_flags(dev) & DM_FLAG_ACTIVATED);
+	ut_assertok(uclass_get_device(UCLASS_TEST_PROBE, 3, &dev));
+	ut_assert(dev_get_flags(dev) & DM_FLAG_ACTIVATED);
+
 	return 0;
 }
-DM_TEST(dm_test_first_next_device, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+DM_TEST(dm_test_first_next_device_probeall,
+	UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
 
 /* Test iteration through devices in a uclass */
 static int dm_test_uclass_foreach(struct unit_test_state *uts)
diff --git a/test/dm/virtio_device.c b/test/dm/virtio_device.c
index d0195e6..b5c4523 100644
--- a/test/dm/virtio_device.c
+++ b/test/dm/virtio_device.c
@@ -22,7 +22,7 @@
 	u8 status;
 
 	/* check probe success */
-	ut_assertok(uclass_first_device(UCLASS_VIRTIO, &bus));
+	ut_assertok(uclass_first_device_err(UCLASS_VIRTIO, &bus));
 	ut_assertnonnull(bus);
 
 	/* check the child virtio-rng device is bound */
@@ -60,7 +60,7 @@
 	struct virtqueue *vqs[2];
 
 	/* check probe success */
-	ut_assertok(uclass_first_device(UCLASS_VIRTIO, &bus));
+	ut_assertok(uclass_first_device_err(UCLASS_VIRTIO, &bus));
 	ut_assertnonnull(bus);
 
 	/* check the child virtio-rng device is bound */
@@ -102,7 +102,7 @@
 	struct udevice *bus, *dev;
 
 	/* check probe success */
-	ut_assertok(uclass_first_device(UCLASS_VIRTIO, &bus));
+	ut_assertok(uclass_first_device_err(UCLASS_VIRTIO, &bus));
 	ut_assertnonnull(bus);
 
 	/* check the child virtio-rng device is bound */
@@ -134,7 +134,7 @@
 	u8 buffer[2][32];
 
 	/* check probe success */
-	ut_assertok(uclass_first_device(UCLASS_VIRTIO, &bus));
+	ut_assertok(uclass_first_device_err(UCLASS_VIRTIO, &bus));
 	ut_assertnonnull(bus);
 
 	/* check the child virtio-blk device is bound */
diff --git a/test/dm/virtio_rng.c b/test/dm/virtio_rng.c
index ff5646b..8b9a04b 100644
--- a/test/dm/virtio_rng.c
+++ b/test/dm/virtio_rng.c
@@ -28,7 +28,7 @@
 	u8 buffer[16];
 
 	/* check probe success */
-	ut_assertok(uclass_first_device(UCLASS_VIRTIO, &bus));
+	ut_assertok(uclass_first_device_err(UCLASS_VIRTIO, &bus));
 	ut_assertnonnull(bus);
 
 	/* check the child virtio-rng device is bound */
diff --git a/test/fuzz/cmd_fuzz.c b/test/fuzz/cmd_fuzz.c
index 0cc01dc..e2f44f3 100644
--- a/test/fuzz/cmd_fuzz.c
+++ b/test/fuzz/cmd_fuzz.c
@@ -29,7 +29,7 @@
 {
 	struct udevice *dev;
 
-	if (uclass_first_device(UCLASS_FUZZING_ENGINE, &dev))
+	if (uclass_first_device_err(UCLASS_FUZZING_ENGINE, &dev))
 		return NULL;
 
 	return dev;
diff --git a/test/fuzz/virtio.c b/test/fuzz/virtio.c
index e5363d5..8a47667 100644
--- a/test/fuzz/virtio.c
+++ b/test/fuzz/virtio.c
@@ -30,7 +30,7 @@
 		return 0;
 
 	/* check probe success */
-	if (uclass_first_device(UCLASS_VIRTIO, &bus) || !bus)
+	if (uclass_first_device_err(UCLASS_VIRTIO, &bus))
 		panic("Could not find virtio bus\n");
 
 	/* check the child virtio-rng device is bound */
diff --git a/test/py/tests/fit_util.py b/test/py/tests/fit_util.py
new file mode 100644
index 0000000..79718d4
--- /dev/null
+++ b/test/py/tests/fit_util.py
@@ -0,0 +1,93 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2022 Google LLC
+
+"""Common utility functions for FIT tests"""
+
+import os
+
+import u_boot_utils as util
+
+def make_fname(cons, basename):
+    """Make a temporary filename
+
+    Args:
+        cons (ConsoleBase): u_boot_console to use
+        basename (str): Base name of file to create (within temporary directory)
+    Return:
+        Temporary filename
+    """
+
+    return os.path.join(cons.config.build_dir, basename)
+
+def make_its(cons, base_its, params, basename='test.its'):
+    """Make a sample .its file with parameters embedded
+
+    Args:
+        cons (ConsoleBase): u_boot_console to use
+        base_its (str): Template text for the .its file, typically containing
+            %() references
+        params (dict of str): Parameters to embed in the %() strings
+        basename (str): base name to write to (will be placed in the temp dir)
+    Returns:
+        str: Filename of .its file created
+    """
+    its = make_fname(cons, basename)
+    with open(its, 'w', encoding='utf-8') as outf:
+        print(base_its % params, file=outf)
+    return its
+
+def make_fit(cons, mkimage, base_its, params, basename='test.fit', base_fdt=None):
+    """Make a sample .fit file ready for loading
+
+    This creates a .its script with the selected parameters and uses mkimage to
+    turn this into a .fit image.
+
+    Args:
+        cons (ConsoleBase): u_boot_console to use
+        mkimage (str): Filename of 'mkimage' utility
+        base_its (str): Template text for the .its file, typically containing
+            %() references
+        params (dict of str): Parameters to embed in the %() strings
+        basename (str): base name to write to (will be placed in the temp dir)
+    Return:
+        Filename of .fit file created
+    """
+    fit = make_fname(cons, basename)
+    its = make_its(cons, base_its, params)
+    util.run_and_log(cons, [mkimage, '-f', its, fit])
+    if base_fdt:
+        with open(make_fname(cons, 'u-boot.dts'), 'w') as fd:
+            fd.write(base_fdt)
+    return fit
+
+def make_kernel(cons, basename, text):
+    """Make a sample kernel with test data
+
+    Args:
+        cons (ConsoleBase): u_boot_console to use
+        basename (str): base name to write to (will be placed in the temp dir)
+        text (str): Contents of the kernel file (will be repeated 100 times)
+    Returns:
+        str: Full path and filename of the kernel it created
+    """
+    fname = make_fname(cons, basename)
+    data = ''
+    for i in range(100):
+        data += f'this {text} {i} is unlikely to boot\n'
+    with open(fname, 'w', encoding='utf-8') as outf:
+        print(data, file=outf)
+    return fname
+
+def make_dtb(cons, base_fdt, basename):
+    """Make a sample .dts file and compile it to a .dtb
+
+    Returns:
+        cons (ConsoleBase): u_boot_console to use
+        Filename of .dtb file created
+    """
+    src = make_fname(cons, f'{basename}.dts')
+    dtb = make_fname(cons, f'{basename}.dtb')
+    with open(src, 'w', encoding='utf-8') as outf:
+        outf.write(base_fdt)
+    util.run_and_log(cons, ['dtc', src, '-O', 'dtb', '-o', dtb])
+    return dtb
diff --git a/test/py/tests/test_event_dump.py b/test/py/tests/test_event_dump.py
index bc54149..e63c25d 100644
--- a/test/py/tests/test_event_dump.py
+++ b/test/py/tests/test_event_dump.py
@@ -16,6 +16,7 @@
     out = util.run_and_log(cons, ['scripts/event_dump.py', sandbox])
     expect = '''.*Event type            Id                              Source location
 --------------------  ------------------------------  ------------------------------
+EVT_FT_FIXUP          bootmeth_vbe_ft_fixup           .*boot/vbe_fixup.c:.*
 EVT_FT_FIXUP          bootmeth_vbe_simple_ft_fixup    .*boot/vbe_simple.c:.*
 EVT_MISC_INIT_F       sandbox_misc_init_f             .*arch/sandbox/cpu/start.c:'''
     assert re.match(expect, out, re.MULTILINE) is not None
diff --git a/test/py/tests/test_fit.py b/test/py/tests/test_fit.py
index 5856960..f458484 100755
--- a/test/py/tests/test_fit.py
+++ b/test/py/tests/test_fit.py
@@ -7,6 +7,7 @@
 import pytest
 import struct
 import u_boot_utils as util
+import fit_util
 
 # Define a base ITS which we can adjust using % and a dictionary
 base_its = '''
@@ -126,7 +127,6 @@
         Return:
             Temporary filename
         """
-
         return os.path.join(cons.config.build_dir, leaf)
 
     def filesize(fname):
@@ -150,67 +150,6 @@
         with open(fname, 'rb') as fd:
             return fd.read()
 
-    def make_dtb():
-        """Make a sample .dts file and compile it to a .dtb
-
-        Returns:
-            Filename of .dtb file created
-        """
-        src = make_fname('u-boot.dts')
-        dtb = make_fname('u-boot.dtb')
-        with open(src, 'w') as fd:
-            fd.write(base_fdt)
-        util.run_and_log(cons, ['dtc', src, '-O', 'dtb', '-o', dtb])
-        return dtb
-
-    def make_its(params):
-        """Make a sample .its file with parameters embedded
-
-        Args:
-            params: Dictionary containing parameters to embed in the %() strings
-        Returns:
-            Filename of .its file created
-        """
-        its = make_fname('test.its')
-        with open(its, 'w') as fd:
-            print(base_its % params, file=fd)
-        return its
-
-    def make_fit(mkimage, params):
-        """Make a sample .fit file ready for loading
-
-        This creates a .its script with the selected parameters and uses mkimage to
-        turn this into a .fit image.
-
-        Args:
-            mkimage: Filename of 'mkimage' utility
-            params: Dictionary containing parameters to embed in the %() strings
-        Return:
-            Filename of .fit file created
-        """
-        fit = make_fname('test.fit')
-        its = make_its(params)
-        util.run_and_log(cons, [mkimage, '-f', its, fit])
-        with open(make_fname('u-boot.dts'), 'w') as fd:
-            fd.write(base_fdt)
-        return fit
-
-    def make_kernel(filename, text):
-        """Make a sample kernel with test data
-
-        Args:
-            filename: the name of the file you want to create
-        Returns:
-            Full path and filename of the kernel it created
-        """
-        fname = make_fname(filename)
-        data = ''
-        for i in range(100):
-            data += 'this %s %d is unlikely to boot\n' % (text, i)
-        with open(fname, 'w') as fd:
-            print(data, file=fd)
-        return fname
-
     def make_ramdisk(filename, text):
         """Make a sample ramdisk with test data
 
@@ -321,10 +260,10 @@
           - run code coverage to make sure we are testing all the code
         """
         # Set up invariant files
-        control_dtb = make_dtb()
-        kernel = make_kernel('test-kernel.bin', 'kernel')
+        control_dtb = fit_util.make_dtb(cons, base_fdt, 'u-boot')
+        kernel = fit_util.make_kernel(cons, 'test-kernel.bin', 'kernel')
         ramdisk = make_ramdisk('test-ramdisk.bin', 'ramdisk')
-        loadables1 = make_kernel('test-loadables1.bin', 'lenrek')
+        loadables1 = fit_util.make_kernel(cons, 'test-loadables1.bin', 'lenrek')
         loadables2 = make_ramdisk('test-loadables2.bin', 'ksidmar')
         kernel_out = make_fname('kernel-out.bin')
         fdt = make_fname('u-boot.dtb')
@@ -372,7 +311,7 @@
         }
 
         # Make a basic FIT and a script to load it
-        fit = make_fit(mkimage, params)
+        fit = fit_util.make_fit(cons, mkimage, base_its, params)
         params['fit'] = fit
         cmd = base_script % params
 
@@ -403,7 +342,7 @@
         # Now a kernel and an FDT
         with cons.log.section('Kernel + FDT load'):
             params['fdt_load'] = 'load = <%#x>;' % params['fdt_addr']
-            fit = make_fit(mkimage, params)
+            fit = fit_util.make_fit(cons, mkimage, base_its, params)
             cons.restart_uboot()
             output = cons.run_command_list(cmd.splitlines())
             check_equal(kernel, kernel_out, 'Kernel not loaded')
@@ -415,7 +354,7 @@
         with cons.log.section('Kernel + FDT + Ramdisk load'):
             params['ramdisk_config'] = 'ramdisk = "ramdisk-1";'
             params['ramdisk_load'] = 'load = <%#x>;' % params['ramdisk_addr']
-            fit = make_fit(mkimage, params)
+            fit = fit_util.make_fit(cons, mkimage, base_its, params)
             cons.restart_uboot()
             output = cons.run_command_list(cmd.splitlines())
             check_equal(ramdisk, ramdisk_out, 'Ramdisk not loaded')
@@ -427,7 +366,7 @@
                                          params['loadables1_addr'])
             params['loadables2_load'] = ('load = <%#x>;' %
                                          params['loadables2_addr'])
-            fit = make_fit(mkimage, params)
+            fit = fit_util.make_fit(cons, mkimage, base_its, params)
             cons.restart_uboot()
             output = cons.run_command_list(cmd.splitlines())
             check_equal(loadables1, loadables1_out,
@@ -441,7 +380,7 @@
             params['kernel'] = make_compressed(kernel)
             params['fdt'] = make_compressed(fdt)
             params['ramdisk'] = make_compressed(ramdisk)
-            fit = make_fit(mkimage, params)
+            fit = fit_util.make_fit(cons, mkimage, base_its, params)
             cons.restart_uboot()
             output = cons.run_command_list(cmd.splitlines())
             check_equal(kernel, kernel_out, 'Kernel not loaded')
diff --git a/test/py/tests/test_vbe.py b/test/py/tests/test_vbe.py
new file mode 100644
index 0000000..559c291
--- /dev/null
+++ b/test/py/tests/test_vbe.py
@@ -0,0 +1,123 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2022 Google LLC
+#
+# Test addition of VBE
+
+import pytest
+
+import fit_util
+
+# Define a base ITS which we can adjust using % and a dictionary
+base_its = '''
+/dts-v1/;
+
+/ {
+        description = "Example kernel";
+
+        images {
+            kernel-1 {
+                data = /incbin/("%(kernel)s");
+                type = "kernel";
+                arch = "sandbox";
+                os = "linux";
+                load = <0x40000>;
+                entry = <0x8>;
+                compression = "%(compression)s";
+
+                random {
+                    compatible = "vbe,random-rand";
+                    vbe,size = <0x40>;
+                    vbe,required;
+                };
+                aslr1 {
+                    compatible = "vbe,aslr-move";
+                    vbe,align = <0x100000>;
+                };
+                aslr2 {
+                    compatible = "vbe,aslr-rand";
+                };
+                efi-runtime {
+                    compatible = "vbe,efi-runtime-rand";
+                };
+                wibble {
+                    compatible = "vbe,wibble";
+                };
+            };
+
+            fdt-1 {
+                description = "snow";
+                data = /incbin/("%(fdt)s");
+                type = "flat_dt";
+                arch = "sandbox";
+                load = <%(fdt_addr)#x>;
+                compression = "%(compression)s";
+            };
+        };
+        configurations {
+            default = "conf-1";
+            conf-1 {
+                kernel = "kernel-1";
+                fdt = "fdt-1";
+            };
+        };
+};
+'''
+
+# Define a base FDT - currently we don't use anything in this
+base_fdt = '''
+/dts-v1/;
+
+/ {
+    chosen {
+    };
+};
+'''
+
+# This is the U-Boot script that is run for each test. First load the FIT,
+# then run the 'bootm' command, then run the unit test which checks that the
+# working tree has the required things filled in according to the OS requests
+# above (random, aslr2, etc.)
+base_script = '''
+host load hostfs 0 %(fit_addr)x %(fit)s
+fdt addr %(fit_addr)x
+bootm start %(fit_addr)x
+bootm loados
+bootm prep
+fdt addr
+fdt print
+ut bootstd vbe_test_fixup
+'''
+
+@pytest.mark.boardspec('sandbox_flattree')
+@pytest.mark.requiredtool('dtc')
+def test_vbe(u_boot_console):
+    cons = u_boot_console
+    kernel = fit_util.make_kernel(cons, 'vbe-kernel.bin', 'kernel')
+    fdt = fit_util.make_dtb(cons, base_fdt, 'vbe-fdt')
+    fdt_out = fit_util.make_fname(cons, 'fdt-out.dtb')
+
+    params = {
+        'fit_addr' : 0x1000,
+
+        'kernel' : kernel,
+
+        'fdt' : fdt,
+        'fdt_out' : fdt_out,
+        'fdt_addr' : 0x80000,
+        'fdt_size' : 0x1000,
+
+        'compression' : 'none',
+    }
+    mkimage = cons.config.build_dir + '/tools/mkimage'
+    fit = fit_util.make_fit(cons, mkimage, base_its, params, 'test-vbe.fit',
+                            base_fdt)
+    params['fit'] = fit
+    cmd = base_script % params
+
+    with cons.log.section('Kernel load'):
+        output = cons.run_command_list(cmd.splitlines())
+
+    # This is a little wonky since there are two tests running in CI. The final
+    # one is the 'ut bootstd' command above
+    failures = [line for line in output if 'Failures' in line]
+    assert len(failures) >= 1 and 'Failures: 0' in failures[-1]
diff --git a/test/test-main.c b/test/test-main.c
index d74df29..a98a77d 100644
--- a/test/test-main.c
+++ b/test/test-main.c
@@ -165,16 +165,7 @@
 /* Ensure all the test devices are probed */
 static int do_autoprobe(struct unit_test_state *uts)
 {
-	struct udevice *dev;
-	int ret;
-
-	/* Scanning the uclass is enough to probe all the devices */
-	for (ret = uclass_first_device(UCLASS_TEST, &dev);
-	     dev;
-	     ret = uclass_next_device(&dev))
-		;
-
-	return ret;
+	return uclass_probe_all(UCLASS_TEST);
 }
 
 /*
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
index 84b7777..42ab812 100644
--- a/tools/docker/Dockerfile
+++ b/tools/docker/Dockerfile
@@ -97,6 +97,7 @@
 	python3 \
 	python3-dev \
 	python3-pip \
+	python3-pyelftools \
 	python3-sphinx \
 	python3-virtualenv \
 	rpm2cpio \