summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2026-06-08 15:28:18 -0600
committerTom Rini <[email protected]>2026-06-08 15:28:18 -0600
commite91911169bc737ee4a79963a1cba8db2aab7c1c0 (patch)
tree77bdc64834398b00a211c1ceedfb87e39a1631b0
parent5d4d6e331d3f056ecc7ab11b72098a3cf4fdb099 (diff)
parent1296a428c67cf103eca482d4a63349661c1b799f (diff)
Merge tag 'v2026.07-rc4' into next
Prepare v2026.07-rc4
-rw-r--r--.gitignore2
-rw-r--r--.gitlab-ci-sage-lab.yml30
-rw-r--r--Makefile6
-rw-r--r--arch/arm/config.mk8
-rw-r--r--arch/arm/dts/Makefile3
-rw-r--r--arch/arm/dts/imx8mm-u-boot.dtsi13
-rw-r--r--arch/arm/dts/imx8mn-u-boot.dtsi13
-rw-r--r--arch/arm/dts/r8a779md-geist-u-boot.dtsi59
-rw-r--r--arch/arm/dts/r8a779md-geist.dts717
-rw-r--r--arch/arm/dts/r8a779md.dtsi59
-rw-r--r--arch/arm/dts/stm32mp15-scmi-u-boot.dtsi9
-rw-r--r--arch/arm/mach-bcm283x/include/mach/acpi/bcm2711.h6
-rw-r--r--arch/arm/mach-bcm283x/init.c10
-rw-r--r--arch/arm/mach-renesas/Kconfig.rcar38
-rw-r--r--arch/arm/mach-renesas/cpu_info.c13
-rw-r--r--arch/arm/mach-stm32mp/include/mach/sys_proto.h16
-rw-r--r--board/renesas/geist/Kconfig15
-rw-r--r--board/renesas/geist/Makefile9
-rw-r--r--board/renesas/geist/geist.c36
-rw-r--r--board/st/common/Makefile1
-rw-r--r--board/st/common/stm32mp_fwu.c55
-rw-r--r--board/st/stm32mp1/stm32mp1.c21
-rw-r--r--board/st/stm32mp2/stm32mp2.c53
-rw-r--r--board/toradex/verdin-imx95/verdin-imx95.c8
-rw-r--r--boot/pxe_utils.c2
-rw-r--r--configs/kontron-sl-mx6ul_defconfig1
-rw-r--r--configs/r8a779md_geist_defconfig75
-rw-r--r--configs/rpi_arm64_defconfig8
-rw-r--r--configs/stm32mp13_defconfig2
-rw-r--r--configs/stm32mp15_defconfig3
-rw-r--r--doc/develop/release_cycle.rst2
-rw-r--r--drivers/cpu/imx8_cpu.c7
-rw-r--r--drivers/mmc/bcm2835_sdhci.c4
-rw-r--r--drivers/mmc/bcmstb_sdhci.c6
-rw-r--r--drivers/net/ti/icssg_prueth.c5
-rw-r--r--drivers/nvme/nvme.c50
-rw-r--r--drivers/pci/pcie_brcmstb.c387
-rw-r--r--drivers/reset/Kconfig16
-rw-r--r--drivers/reset/Makefile2
-rw-r--r--drivers/reset/reset-brcmstb-rescal.c103
-rw-r--r--drivers/reset/reset-brcmstb.c97
-rw-r--r--drivers/usb/host/xhci-mvebu.c1
-rw-r--r--drivers/video/bcm2835.c1
-rw-r--r--include/configs/geist.h18
-rw-r--r--include/configs/stm32mp15_st_common.h15
-rw-r--r--lib/Kconfig9
-rw-r--r--lib/lmb.c20
-rw-r--r--lib/smbios.c2
-rw-r--r--net/bootp.c8
-rw-r--r--net/dhcpv6.c32
-rw-r--r--net/sntp.c3
-rw-r--r--test/py/tests/fs_helper.py2
-rw-r--r--tools/binman/etype/nxp_imx8mimage.py14
-rw-r--r--tools/binman/ftest.py14
-rw-r--r--tools/binman/test/vendor/nxp_imx8m_fspi.dts18
-rw-r--r--tools/binman/test/vendor/nxp_imx8m_fspi_fail.dts18
-rw-r--r--tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts18
-rw-r--r--tools/imx8image.c2
58 files changed, 1934 insertions, 201 deletions
diff --git a/.gitignore b/.gitignore
index e5d22dbe8e9..d57d3be0291 100644
--- a/.gitignore
+++ b/.gitignore
@@ -80,7 +80,7 @@ fit-dtb.blob*
/*imx8mimage*
/*imx8mcst*
/*rcar4-sa0*
-/drivers/video/u_boot_logo.S
+/drivers/video/u_boot_logo.bmp.S
/test/fdt_overlay/test-fdt-overlay-stacked.dtbo.S
/test/fdt_overlay/test-fdt-overlay.dtbo.S
capsule_esl_file
diff --git a/.gitlab-ci-sage-lab.yml b/.gitlab-ci-sage-lab.yml
index e9fa3e5f6f3..176d281868b 100644
--- a/.gitlab-ci-sage-lab.yml
+++ b/.gitlab-ci-sage-lab.yml
@@ -153,20 +153,13 @@ Raspberry Pi 4 (rpi_arm64):
LABGRID_EXPORTER: "sage-exporter-rpi4-1"
LG_PLACE: "rpi4-1"
TEST_PY_BD: "rpi_arm64"
- OVERRIDE: "-a UNIT_TEST -a ~CMD_EFIDEBUG -a CMD_BOOTMENU -a CMD_LOG -a ~CMD_BOOTEFI_SELFTEST -a CMD_TFTPPUT -a FIT -a FIT_SIGNATURE -a FIT_BEST_MATCH -a SYS_BOOTM_LEN=0x4000000 -a BOOTSTAGE -a BOOTSTAGE_STASH -a CMD_BOOTSTAGE -a BOOTSTAGE_STASH_ADDR=0x02400000"
-
-Raspberry Pi 4 (rpi_arm64, lwIP):
- <<: *sage_lab_dfn
- needs: [ "Raspberry Pi 4 (rpi_arm64)" ]
- variables:
- LABGRID_EXPORTER: "sage-exporter-rpi4-1"
- LG_PLACE: "rpi4-1"
- TEST_PY_BD: "rpi_arm64"
- OVERRIDE: "-a UNIT_TEST -a ~CMD_EFIDEBUG -a CMD_BOOTMENU -a CMD_LOG -a ~CMD_BOOTEFI_SELFTEST -a FIT -a FIT_SIGNATURE -a FIT_BEST_MATCH -a SYS_BOOTM_LEN=0x4000000 -a BOOTSTAGE -a BOOTSTAGE_STASH -a CMD_BOOTSTAGE -a BOOTSTAGE_STASH_ADDR=0x02400000 -a NET_LWIP"
+ # DHCP is not being run first, needs to be investigated.
+ TEST_PY_TEST_SPEC: "not test_efi_helloworld_net_http"
+ OVERRIDE: "-a UNIT_TEST -a ~CMD_EFIDEBUG -a CMD_BOOTMENU -a CMD_LOG -a ~CMD_BOOTEFI_SELFTEST -a FIT -a FIT_SIGNATURE -a FIT_BEST_MATCH -a SYS_BOOTM_LEN=0x4000000 -a BOOTSTAGE -a BOOTSTAGE_STASH -a CMD_BOOTSTAGE -a BOOTSTAGE_STASH_ADDR=0x02400000"
Raspberry Pi 4 (rpi_4_32b):
<<: *sage_lab_dfn
- needs: [ "Raspberry Pi 4 (rpi_arm64, lwIP)" ]
+ needs: [ "Raspberry Pi 4 (rpi_arm64)" ]
variables:
LABGRID_EXPORTER: "sage-exporter-rpi4-1"
LG_PLACE: "rpi4-1"
@@ -197,20 +190,13 @@ Raspberry Pi 3 (rpi_arm64):
LABGRID_EXPORTER: "sage-exporter-rpi3-1"
LG_PLACE: "rpi3-1"
TEST_PY_BD: "rpi_arm64"
- OVERRIDE: "-a UNIT_TEST -a ~CMD_EFIDEBUG -a CMD_BOOTMENU -a CMD_LOG -a ~CMD_BOOTEFI_SELFTEST -a CMD_TFTPPUT -a FIT -a FIT_SIGNATURE -a FIT_BEST_MATCH -a SYS_BOOTM_LEN=0x4000000 -a BOOTSTAGE -a BOOTSTAGE_STASH -a CMD_BOOTSTAGE -a BOOTSTAGE_STASH_ADDR=0x02400000"
-
-Raspberry Pi 3 (rpi_arm64, lwIP):
- <<: *sage_lab_dfn
- needs: [ "Raspberry Pi 3 (rpi_arm64)" ]
- variables:
- LABGRID_EXPORTER: "sage-exporter-rpi3-1"
- LG_PLACE: "rpi3-1"
- TEST_PY_BD: "rpi_arm64"
- OVERRIDE: "-a UNIT_TEST -a ~CMD_EFIDEBUG -a CMD_BOOTMENU -a CMD_LOG -a ~CMD_BOOTEFI_SELFTEST -a FIT -a FIT_SIGNATURE -a FIT_BEST_MATCH -a SYS_BOOTM_LEN=0x4000000 -a BOOTSTAGE -a BOOTSTAGE_STASH -a CMD_BOOTSTAGE -a BOOTSTAGE_STASH_ADDR=0x02400000 -a NET_LWIP"
+ # DHCP is not being run first, needs to be investigated.
+ TEST_PY_TEST_SPEC: "not test_efi_helloworld_net_http"
+ OVERRIDE: "-a UNIT_TEST -a ~CMD_EFIDEBUG -a CMD_BOOTMENU -a CMD_LOG -a ~CMD_BOOTEFI_SELFTEST -a FIT -a FIT_SIGNATURE -a FIT_BEST_MATCH -a SYS_BOOTM_LEN=0x4000000 -a BOOTSTAGE -a BOOTSTAGE_STASH -a CMD_BOOTSTAGE -a BOOTSTAGE_STASH_ADDR=0x02400000"
Raspberry Pi 3 (rpi_3_32b):
<<: *sage_lab_dfn
- needs: [ "Raspberry Pi 3 (rpi_arm64, lwIP)" ]
+ needs: [ "Raspberry Pi 3 (rpi_arm64)" ]
variables:
LABGRID_EXPORTER: "sage-exporter-rpi3-1"
LG_PLACE: "rpi3-1"
diff --git a/Makefile b/Makefile
index f07faada3d5..4e5c1dd6a1c 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
VERSION = 2026
PATCHLEVEL = 07
SUBLEVEL =
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc4
NAME =
# *DOCUMENTATION*
@@ -920,7 +920,7 @@ endif
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
KBUILD_CFLAGS += -Os
else ifdef CONFIG_CC_OPTIMIZE_FOR_DEBUG
--KBUILD_CFLAGS += -Og
+KBUILD_CFLAGS += -Og
# Avoid false positives -Wmaybe-uninitialized
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78394
KBUILD_CFLAGS += -Wno-maybe-uninitialized
@@ -2544,7 +2544,7 @@ CLEAN_FILES += $(MODVERDIR) \
$(filter-out include, $(shell ls -1 $d 2>/dev/null))))
CLEAN_FILES += include/autoconf.mk* include/bmp_logo.h include/bmp_logo_data.h \
- include/config.h include/generated/env.* drivers/video/u_boot_logo.S \
+ include/config.h include/generated/env.* drivers/video/u_boot_logo.bmp.S \
tools/version.h u-boot* MLO* SPL System.map fit-dtb.blob* \
u-boot-ivt.img.log u-boot-dtb.imx.log SPL.log u-boot.imx.log \
lpc32xx-* bl31.c bl31.elf bl31_*.bin image.map tispl.bin* \
diff --git a/arch/arm/config.mk b/arch/arm/config.mk
index a7eff84a267..bce9a31e966 100644
--- a/arch/arm/config.mk
+++ b/arch/arm/config.mk
@@ -112,6 +112,14 @@ endif
# needed for relocation
LDFLAGS_u-boot += -pie
+ifeq ($(CONFIG_ARM64),y)
+# U-Boot uses fixed 4K granules, so we force the linker to match.
+# Otherwise, we're subject to toolchain preferences, (e.g Fedora's
+# aarch64-linux-none toolchain selects 64K granules) and we end up wasting
+# a lot of space in ELFs with MMU_PGPROT enabled.
+LDFLAGS_u-boot += -z common-page-size=0x1000 -z max-page-size=0x1000
+endif
+
#
# FIXME: binutils versions < 2.22 have a bug in the assembler where
# branches to weak symbols can be incorrectly optimized in thumb mode
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index c14069447a1..b75f3ee4386 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -885,6 +885,9 @@ dtb-$(CONFIG_RZA1) += \
r7s72100-genmai.dtb \
r7s72100-gr-peach.dtb
+dtb-$(CONFIG_RCAR_GEN3) += \
+ r8a779md-geist.dtb
+
dtb-$(CONFIG_RCAR_GEN5) += \
r8a78000-ironhide-cm33.dtb
diff --git a/arch/arm/dts/imx8mm-u-boot.dtsi b/arch/arm/dts/imx8mm-u-boot.dtsi
index d891e8062fe..ab135fc8a47 100644
--- a/arch/arm/dts/imx8mm-u-boot.dtsi
+++ b/arch/arm/dts/imx8mm-u-boot.dtsi
@@ -50,14 +50,6 @@
section {
pad-byte = <0x00>;
-#ifdef CONFIG_FSPI_CONF_HEADER
- fspi_conf_block {
- filename = CONFIG_FSPI_CONF_FILE;
- type = "blob-ext";
- size = <0x1000>;
- };
-#endif
-
#ifdef CONFIG_IMX_HAB
nxp-imx8mcst@0 {
filename = "u-boot-spl-mkimage.signed.bin";
@@ -68,7 +60,12 @@
binman_imx_spl: nxp-imx8mimage {
filename = "u-boot-spl-mkimage.bin";
+#ifdef CONFIG_FSPI_CONF_HEADER
+ nxp,boot-from = "fspi";
+ nxp,fspi-header-filename = CONFIG_FSPI_CONF_FILE;
+#else
nxp,boot-from = "sd";
+#endif
nxp,rom-version = <1>;
nxp,loader-address = <CONFIG_SPL_TEXT_BASE>;
args; /* Needed by mkimage etype superclass */
diff --git a/arch/arm/dts/imx8mn-u-boot.dtsi b/arch/arm/dts/imx8mn-u-boot.dtsi
index 29eecd6d70d..8993605af3c 100644
--- a/arch/arm/dts/imx8mn-u-boot.dtsi
+++ b/arch/arm/dts/imx8mn-u-boot.dtsi
@@ -104,14 +104,6 @@
section {
pad-byte = <0x00>;
-#ifdef CONFIG_FSPI_CONF_HEADER
- fspi_conf_block {
- filename = CONFIG_FSPI_CONF_FILE;
- type = "blob-ext";
- offset = <0x400>;
- };
-#endif
-
#ifdef CONFIG_IMX_HAB
nxp-imx8mcst@0 {
filename = "u-boot-spl-mkimage.signed.bin";
@@ -122,7 +114,12 @@
binman_imx_spl: nxp-imx8mimage {
filename = "u-boot-spl-mkimage.bin";
+#ifdef CONFIG_FSPI_CONF_HEADER
+ nxp,boot-from = "fspi";
+ nxp,fspi-header-filename = CONFIG_FSPI_CONF_FILE;
+#else
nxp,boot-from = "sd";
+#endif
nxp,rom-version = <2>;
nxp,loader-address = <CONFIG_SPL_TEXT_BASE>;
args; /* Needed by mkimage etype superclass */
diff --git a/arch/arm/dts/r8a779md-geist-u-boot.dtsi b/arch/arm/dts/r8a779md-geist-u-boot.dtsi
new file mode 100644
index 00000000000..fbda218002a
--- /dev/null
+++ b/arch/arm/dts/r8a779md-geist-u-boot.dtsi
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source extras for U-Boot for the Geist board with r8a779md
+ *
+ * Copyright (C) 2025-2026 Renesas Electronics Corp.
+ */
+
+/ {
+ aliases {
+ spi0 = &rpc;
+ };
+};
+
+&pfc {
+ qspi0_pins: qspi0 {
+ groups = "qspi0_ctrl", "qspi0_data4";
+ function = "qspi0";
+ };
+};
+
+/*
+ * SPI access works only if TFA is built with RCAR_RPC_HYPERFLASH_LOCKED=0
+ * and SPD=none , otherwise the RPC access is blocked either by TFA in case
+ * the former is set to 1, or by OPTEE-OS in case SPD=opteed .
+ */
+&rpc {
+ pinctrl-0 = <&qspi0_pins>;
+ pinctrl-names = "default";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ spi-max-frequency = <40000000>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <1>;
+ };
+};
+
+&sdhi0 {
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr104;
+ max-frequency = <208000000>;
+};
+
+&sdhi2 {
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ max-frequency = <200000000>;
+};
+
+&vcc_sdhi0 {
+ u-boot,off-on-delay-us = <20000>;
+};
diff --git a/arch/arm/dts/r8a779md-geist.dts b/arch/arm/dts/r8a779md-geist.dts
new file mode 100644
index 00000000000..2921aba92a5
--- /dev/null
+++ b/arch/arm/dts/r8a779md-geist.dts
@@ -0,0 +1,717 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the Geist board with R-Car M3Le
+ *
+ * Copyright (C) 2025-2026 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "r8a779md.dtsi"
+
+/ {
+ model = "Renesas Geist board based on r8a779md";
+ compatible = "renesas,geist", "renesas,r8a779md", "renesas,r8a77965";
+
+ aliases {
+ serial0 = &scif2;
+ serial1 = &hscif1;
+ ethernet0 = &avb;
+ mmc0 = &sdhi2;
+ mmc1 = &sdhi0;
+ };
+
+ chosen {
+ bootargs = "ignore_loglevel rw root=/dev/nfs ip=on";
+ stdout-path = "serial0:115200n8";
+ };
+
+ audio_clkout: audio-clkout {
+ /*
+ * This is same as <&rcar_sound 0>
+ * but needed to avoid cs2500/rcar_sound probe dead-lock
+ */
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <12288000>;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm1 0 50000>;
+
+ brightness-levels = <256 128 64 16 8 4 0>;
+ default-brightness-level = <6>;
+
+ power-supply = <&reg_12v>;
+ enable-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>;
+ };
+
+ cvbs-in {
+ compatible = "composite-video-connector";
+ label = "CVBS IN";
+
+ port {
+ cvbs_con: endpoint {
+ remote-endpoint = <&adv7482_ain7>;
+ };
+ };
+ };
+
+ hdmi-in {
+ compatible = "hdmi-connector";
+ label = "HDMI IN";
+ type = "a";
+
+ port {
+ hdmi_in_con: endpoint {
+ remote-endpoint = <&adv7482_hdmi>;
+ };
+ };
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ pinctrl-0 = <&keys_pins>;
+ pinctrl-names = "default";
+
+ key-1 {
+ gpios = <&gpio5 17 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_1>;
+ label = "SW4-1";
+ wakeup-source;
+ debounce-interval = <20>;
+ };
+
+ key-2 {
+ gpios = <&gpio5 20 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_2>;
+ label = "SW4-2";
+ wakeup-source;
+ debounce-interval = <20>;
+ };
+
+ key-3 {
+ gpios = <&gpio5 22 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_3>;
+ label = "SW4-3";
+ wakeup-source;
+ debounce-interval = <20>;
+ };
+
+ key-4 {
+ gpios = <&gpio5 23 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_4>;
+ label = "SW4-4";
+ wakeup-source;
+ debounce-interval = <20>;
+ };
+
+ key-a {
+ gpios = <&gpio6 11 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_A>;
+ label = "TSW0";
+ wakeup-source;
+ debounce-interval = <20>;
+ };
+
+ key-b {
+ gpios = <&gpio6 12 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_B>;
+ label = "TSW1";
+ wakeup-source;
+ debounce-interval = <20>;
+ };
+
+ key-c {
+ gpios = <&gpio6 13 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_C>;
+ label = "TSW2";
+ wakeup-source;
+ debounce-interval = <20>;
+ };
+ };
+
+ memory@48000000 {
+ device_type = "memory";
+ /* first 128MB is reserved for secure area. */
+ reg = <0x0 0x48000000 0x0 0x78000000>;
+ };
+
+ memory@480000000 {
+ device_type = "memory";
+ reg = <0x4 0x80000000 0x0 0x80000000>;
+ };
+
+ reg_1p8v: regulator-1p8v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_12v: regulator-12v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-12V";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vbus0_usb2: regulator-vbus0-usb2 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "USB20_VBUS0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+
+ gpio = <&gpio6 16 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vcc_sdhi0: regulator-vcc-sdhi0 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "SDHI0 Vcc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&gpio5 2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vccq_sdhi0: regulator-vccq-sdhi0 {
+ compatible = "regulator-gpio";
+
+ regulator-name = "SDHI0 VccQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+ gpios-states = <1>;
+ states = <3300000 1>, <1800000 0>;
+ };
+
+ sound_card: sound {
+ compatible = "audio-graph-card";
+
+ label = "rcar-sound";
+ dais = <&rsnd_port0>; /* AK4619 Audio Codec */
+ };
+
+ x12_clk: x12-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24576000>;
+ };
+
+ /* External DU dot clocks */
+ x21_clk: x21-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <33000000>;
+ };
+
+ x22_clk: x22-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <33000000>;
+ };
+
+ x23_clk: x23-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+
+ x3013_clk: x3013-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+};
+
+&audio_clk_a {
+ clock-frequency = <22579200>;
+};
+
+&avb {
+ pinctrl-0 = <&avb_pins>;
+ pinctrl-names = "default";
+ phy-handle = <&phy0>;
+ tx-internal-delay-ps = <2000>;
+ status = "okay";
+
+ phy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-id0022.1622";
+ rxc-skew-ps = <1500>;
+ reg = <0>;
+ interrupts-extended = <&gpio2 11 IRQ_TYPE_LEVEL_LOW>;
+ reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <10000>;
+ reset-deassert-us = <300>;
+ };
+};
+
+&csi40 {
+ status = "okay";
+
+ ports {
+ port@0 {
+ csi40_in: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&adv7482_txa>;
+ };
+ };
+ };
+};
+
+&ehci0 {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&extalr_clk {
+ clock-frequency = <32768>;
+};
+
+&extal_clk {
+ clock-frequency = <16666666>;
+};
+
+&hscif1 {
+ pinctrl-0 = <&hscif1_pins>;
+ pinctrl-names = "default";
+
+ uart-has-rtscts;
+ /* Please only enable hscif1 or scif1 */
+ status = "okay";
+};
+
+&hsusb {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-0 = <&i2c2_pins>;
+ pinctrl-names = "default";
+ clock-frequency = <100000>;
+ status = "okay";
+
+ ak4619: codec@10 {
+ compatible = "asahi-kasei,ak4619";
+ reg = <0x10>;
+ clocks = <&rcar_sound 3>;
+ clock-names = "mclk";
+ #sound-dai-cells = <0>;
+
+ port {
+ ak4619_endpoint: endpoint {
+ remote-endpoint = <&rsnd_endpoint0>;
+ };
+ };
+ };
+
+ /* Pin-to-pin, register map, and control compatible with CS2000 and CS2200 */
+ cs2500: clock-controller@4f {
+ #clock-cells = <0>;
+ compatible = "cirrus,cs2500", "cirrus,cs2000-cp";
+ reg = <0x4f>;
+ clocks = <&audio_clkout>, <&x12_clk>;
+ clock-names = "clk_in", "ref_clk";
+
+ assigned-clocks = <&cs2500>;
+ assigned-clock-rates = <24576000>; /* 1/1 divide */
+ };
+};
+
+&i2c4 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ versaclock3: clock-controller@68 {
+ compatible = "renesas,5p35023";
+ reg = <0x68>;
+ #clock-cells = <1>;
+ clocks = <&x3013_clk>;
+ assigned-clocks = <&versaclock3 4>, <&versaclock3 5>;
+ assigned-clock-rates = <100000000>, <100000000>;
+ };
+
+ versaclock5: clock-controller@6a {
+ compatible = "idt,5p49v5923";
+ reg = <0x6a>;
+ #clock-cells = <1>;
+ clocks = <&x23_clk>;
+ clock-names = "xin";
+ };
+
+ video-receiver@70 {
+ compatible = "adi,adv7482";
+ reg = <0x70 0x71 0x72 0x73 0x74 0x75
+ 0x60 0x61 0x62 0x63 0x64 0x65>;
+ reg-names = "main", "dpll", "cp", "hdmi", "edid", "repeater",
+ "infoframe", "cbus", "cec", "sdp", "txa", "txb" ;
+
+ interrupts-extended = <&gpio6 30 IRQ_TYPE_LEVEL_LOW>,
+ <&gpio6 31 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "intrq1", "intrq2";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@7 {
+ reg = <7>;
+
+ adv7482_ain7: endpoint {
+ remote-endpoint = <&cvbs_con>;
+ };
+ };
+
+ port@8 {
+ reg = <8>;
+
+ adv7482_hdmi: endpoint {
+ remote-endpoint = <&hdmi_in_con>;
+ };
+ };
+
+ port@a {
+ reg = <10>;
+
+ adv7482_txa: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&csi40_in>;
+ };
+ };
+ };
+ };
+
+ csa_vdd: adc@7c {
+ compatible = "maxim,max9611";
+ reg = <0x7c>;
+
+ shunt-resistor-micro-ohms = <5000>;
+ };
+
+ csa_dvfs: adc@7f {
+ compatible = "maxim,max9611";
+ reg = <0x7f>;
+
+ shunt-resistor-micro-ohms = <5000>;
+ };
+};
+
+&i2c_dvfs {
+ status = "okay";
+
+ clock-frequency = <400000>;
+
+ eeprom@50 {
+ compatible = "rohm,br24t01", "atmel,24c01";
+ reg = <0x50>;
+ pagesize = <8>;
+ };
+};
+
+&ohci0 {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&pcie_bus_clk {
+ clock-frequency = <100000000>;
+ status = "disabled";
+};
+
+&pciec0 {
+ clocks = <&cpg CPG_MOD 319>, <&versaclock3 4>;
+ status = "okay";
+};
+
+&pfc {
+ pinctrl-0 = <&scif_clk_pins>;
+ pinctrl-names = "default";
+
+ avb_pins: avb {
+ mux {
+ groups = "avb_link", "avb_mdio", "avb_mii";
+ function = "avb";
+ };
+
+ pins_mdio {
+ groups = "avb_mdio";
+ drive-strength = <24>;
+ };
+
+ pins_mii_tx {
+ pins = "PIN_AVB_TX_CTL", "PIN_AVB_TXC", "PIN_AVB_TD0",
+ "PIN_AVB_TD1", "PIN_AVB_TD2", "PIN_AVB_TD3";
+ drive-strength = <12>;
+ };
+ };
+
+ hscif1_pins: hscif1 {
+ groups = "hscif1_data_a", "hscif1_ctrl_a";
+ function = "hscif1";
+ };
+
+ i2c2_pins: i2c2 {
+ groups = "i2c2_a";
+ function = "i2c2";
+ };
+
+ irq0_pins: irq0 {
+ groups = "intc_ex_irq0";
+ function = "intc_ex";
+ };
+
+ keys_pins: keys {
+ pins = "GP_5_17", "GP_5_20", "GP_5_22";
+ bias-pull-up;
+ };
+
+ pwm1_pins: pwm1 {
+ groups = "pwm1_a";
+ function = "pwm1";
+ };
+
+ scif1_pins: scif1 {
+ groups = "scif1_data_a", "scif1_ctrl";
+ function = "scif1";
+ };
+
+ scif2_pins: scif2 {
+ groups = "scif2_data_a";
+ function = "scif2";
+ };
+
+ scif_clk_pins: scif_clk {
+ groups = "scif_clk_a";
+ function = "scif_clk";
+ };
+
+ sdhi0_pins: sd0 {
+ groups = "sdhi0_data4", "sdhi0_ctrl";
+ function = "sdhi0";
+ power-source = <3300>;
+ };
+
+ sdhi0_pins_uhs: sd0_uhs {
+ groups = "sdhi0_data4", "sdhi0_ctrl";
+ function = "sdhi0";
+ power-source = <1800>;
+ };
+
+ sdhi2_pins: sd2 {
+ groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
+ function = "sdhi2";
+ power-source = <1800>;
+ };
+
+ sound_pins: sound {
+ groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a";
+ function = "ssi";
+ };
+
+ sound_clk_pins: sound_clk {
+ groups = "audio_clk_a_a", "audio_clk_b_a", "audio_clk_c_a",
+ "audio_clkout_a", "audio_clkout3_a";
+ function = "audio_clk";
+ };
+
+ usb0_pins: usb0 {
+ groups = "usb0";
+ function = "usb0";
+ };
+};
+
+&pwm1 {
+ pinctrl-0 = <&pwm1_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&rcar_sound {
+ pinctrl-0 = <&sound_pins>, <&sound_clk_pins>;
+ pinctrl-names = "default";
+
+ /* Single DAI */
+ #sound-dai-cells = <0>;
+
+ /* audio_clkout0/1/2/3 */
+ #clock-cells = <1>;
+ clock-frequency = <12288000 11289600>;
+
+ status = "okay";
+
+ /* update <audio_clk_b> to <cs2500> */
+ clocks = <&cpg CPG_MOD 1005>,
+ <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
+ <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
+ <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
+ <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
+ <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
+ <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>,
+ <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>,
+ <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>,
+ <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>,
+ <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>,
+ <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>,
+ <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>,
+ <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
+ <&audio_clk_a>, <&cs2500>,
+ <&audio_clk_c>,
+ <&cpg CPG_MOD 922>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rsnd_port0: port@0 {
+ reg = <0>;
+
+ rsnd_endpoint0: endpoint {
+ remote-endpoint = <&ak4619_endpoint>;
+ dai-format = "left_j";
+ bitclock-master = <&rsnd_endpoint0>;
+ frame-master = <&rsnd_endpoint0>;
+ playback = <&ssi0>, <&src0>, <&dvc0>;
+ capture = <&ssi1>, <&src1>, <&dvc1>;
+ };
+ };
+ };
+};
+
+&rwdt {
+ timeout-sec = <60>;
+ status = "okay";
+};
+
+&scif1 {
+ pinctrl-0 = <&scif1_pins>;
+ pinctrl-names = "default";
+
+ uart-has-rtscts;
+ /* Please only enable hscif1 or scif1 */
+ /* status = "okay"; */
+};
+
+&scif2 {
+ pinctrl-0 = <&scif2_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&scif_clk {
+ clock-frequency = <14745600>;
+};
+
+&sdhi0 {
+ pinctrl-0 = <&sdhi0_pins>;
+ pinctrl-1 = <&sdhi0_pins_uhs>;
+ pinctrl-names = "default", "state_uhs";
+
+ vmmc-supply = <&vcc_sdhi0>;
+ vqmmc-supply = <&vccq_sdhi0>;
+ cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ status = "okay";
+};
+
+&sdhi2 {
+ /* used for on-board 8bit eMMC */
+ pinctrl-0 = <&sdhi2_pins>;
+ pinctrl-1 = <&sdhi2_pins>;
+ pinctrl-names = "default", "state_uhs";
+
+ vmmc-supply = <&reg_3p3v>;
+ vqmmc-supply = <&reg_1p8v>;
+ bus-width = <8>;
+ mmc-hs200-1_8v;
+ no-sd;
+ no-sdio;
+ non-removable;
+ fixed-emmc-driver-type = <1>;
+ full-pwr-cycle-in-suspend;
+ status = "okay";
+};
+
+&ssi1 {
+ shared-pin;
+};
+
+&usb_extal_clk {
+ clock-frequency = <50000000>;
+};
+
+&usb2_phy0 {
+ pinctrl-0 = <&usb0_pins>;
+ pinctrl-names = "default";
+
+ vbus-supply = <&vbus0_usb2>;
+ status = "okay";
+};
+
+&vin0 {
+ status = "okay";
+};
+
+&vin1 {
+ status = "okay";
+};
+
+&vin2 {
+ status = "okay";
+};
+
+&vin3 {
+ status = "okay";
+};
+
+&vin4 {
+ status = "okay";
+};
+
+&vin5 {
+ status = "okay";
+};
+
+&vin6 {
+ status = "okay";
+};
+
+&vin7 {
+ status = "okay";
+};
+
+&vspb {
+ status = "okay";
+};
+
+&vspi0 {
+ status = "okay";
+};
diff --git a/arch/arm/dts/r8a779md.dtsi b/arch/arm/dts/r8a779md.dtsi
new file mode 100644
index 00000000000..f3065414134
--- /dev/null
+++ b/arch/arm/dts/r8a779md.dtsi
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the R-Car M3Le (R8A779MD) SoC
+ *
+ * Copyright (C) 2025-2026 Renesas Electronics Corp.
+ */
+
+#include "r8a77965.dtsi"
+
+/ {
+ compatible = "renesas,r8a779md", "renesas,r8a77965";
+};
+
+/delete-node/ &csi20;
+/delete-node/ &drif00;
+/delete-node/ &drif01;
+/delete-node/ &drif10;
+/delete-node/ &drif11;
+/delete-node/ &drif20;
+/delete-node/ &drif21;
+/delete-node/ &drif30;
+/delete-node/ &drif31;
+/delete-node/ &du;
+/delete-node/ &ehci1;
+/delete-node/ &hdmi0;
+/delete-node/ &lvds0;
+/delete-node/ &mlp;
+/delete-node/ &ohci1;
+/delete-node/ &pciec1;
+/delete-node/ &sata;
+/delete-node/ &usb2_phy1;
+/delete-node/ &usb3_peri0;
+/delete-node/ &usb3_phy0;
+/delete-node/ &vin0csi20;
+/delete-node/ &vin1csi20;
+/delete-node/ &vin2csi20;
+/delete-node/ &vin3csi20;
+/delete-node/ &vin4csi20;
+/delete-node/ &vin5csi20;
+/delete-node/ &vin6csi20;
+/delete-node/ &vin7csi20;
+/delete-node/ &xhci0;
+
+&sdhi0 {
+ compatible = "renesas,sdhi-r8a779md", "renesas,rcar-gen3-sdhi";
+};
+
+&sdhi1 {
+ compatible = "renesas,sdhi-r8a779md", "renesas,rcar-gen3-sdhi";
+};
+
+&sdhi2 {
+ compatible = "renesas,sdhi-r8a779md", "renesas,rcar-gen3-sdhi";
+};
+
+&sdhi3 {
+ compatible = "renesas,sdhi-r8a779md", "renesas,rcar-gen3-sdhi";
+ no-mmc;
+};
diff --git a/arch/arm/dts/stm32mp15-scmi-u-boot.dtsi b/arch/arm/dts/stm32mp15-scmi-u-boot.dtsi
index 79494ecad90..600316205fc 100644
--- a/arch/arm/dts/stm32mp15-scmi-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp15-scmi-u-boot.dtsi
@@ -21,6 +21,13 @@
pinctrl1 = &pinctrl_z;
};
+ arm_wdt: watchdog {
+ compatible = "arm,smc-wdt";
+ arm,smc-id = <0xbc000000>;
+ timeout-sec = <32>;
+ status = "okay";
+ };
+
binman: binman {
multiple-images;
};
@@ -103,7 +110,7 @@
};
&iwdg2 {
- bootph-all;
+ status = "disabled";
};
/* pre-reloc probe = reserve video frame buffer in video_reserve() */
diff --git a/arch/arm/mach-bcm283x/include/mach/acpi/bcm2711.h b/arch/arm/mach-bcm283x/include/mach/acpi/bcm2711.h
index a86875b1833..c72b47e1b10 100644
--- a/arch/arm/mach-bcm283x/include/mach/acpi/bcm2711.h
+++ b/arch/arm/mach-bcm283x/include/mach/acpi/bcm2711.h
@@ -54,6 +54,7 @@
#define MISC_CTRL_CFG_READ_UR_MODE_MASK 0x2000
#define MISC_CTRL_MAX_BURST_SIZE_MASK 0x300000
#define MISC_CTRL_MAX_BURST_SIZE_128 0x0
+#define MISC_CTRL_MAX_BURST_SIZE_128_2712 0x100000
#define MISC_CTRL_SCB0_SIZE_MASK 0xf8000000
#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO 0x400c
@@ -70,6 +71,7 @@
#define PCIE_MISC_RC_BAR2_CONFIG_HI 0x4038
#define PCIE_MISC_RC_BAR3_CONFIG_LO 0x403c
#define RC_BAR3_CONFIG_LO_SIZE_MASK 0x1f
+#define PCIE_MISC_PCIE_CTRL 0x4064
#define PCIE_MISC_PCIE_STATUS 0x4068
#define STATUS_PCIE_PORT_MASK 0x80
#define STATUS_PCIE_PORT_SHIFT 7
@@ -108,6 +110,10 @@
#define PCIE_RGR1_SW_INIT_1 0x9210
#define PCIE_EXT_CFG_INDEX 0x9000
+#define RGR1_SW_INIT_1_PERST_MASK 0x1
+#define RGR1_SW_INIT_1_PERSTB_MASK 0x4
+#define RGR1_SW_INIT_1_INIT_MASK 0x2
+
/* A small window pointing at the ECAM of the device selected by CFG_INDEX */
#define PCIE_EXT_CFG_DATA 0x8000
diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c
index 7a1de22e0ae..7a2faaa4de6 100644
--- a/arch/arm/mach-bcm283x/init.c
+++ b/arch/arm/mach-bcm283x/init.c
@@ -18,7 +18,7 @@
#ifdef CONFIG_ARM64
#include <asm/armv8/mmu.h>
-#define MEM_MAP_MAX_ENTRIES (4)
+#define MEM_MAP_MAX_ENTRIES (5)
static struct mm_region bcm283x_mem_map[MEM_MAP_MAX_ENTRIES] = {
{
@@ -84,6 +84,14 @@ static struct mm_region bcm2712_mem_map[MEM_MAP_MAX_ENTRIES] = {
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
+ /* Whole PCIe section */
+ .virt = 0x1800000000UL,
+ .phys = 0x1800000000UL,
+ .size = 0x0800000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
/* SoC bus */
.virt = 0x107c000000UL,
.phys = 0x107c000000UL,
diff --git a/arch/arm/mach-renesas/Kconfig.rcar3 b/arch/arm/mach-renesas/Kconfig.rcar3
index 8479875178d..6bed7684fb8 100644
--- a/arch/arm/mach-renesas/Kconfig.rcar3
+++ b/arch/arm/mach-renesas/Kconfig.rcar3
@@ -164,12 +164,20 @@ config TARGET_ULCB
help
Support for Renesas R-Car Gen3 ULCB platform
+config TARGET_GEIST
+ bool "Geist board"
+ imply R8A77965
+ imply SYS_MALLOC_F
+ help
+ Support for Renesas R-Car Gen3 Geist platform
+
endchoice
source "board/renesas/condor/Kconfig"
source "board/renesas/draak/Kconfig"
source "board/renesas/eagle/Kconfig"
source "board/renesas/ebisu/Kconfig"
+source "board/renesas/geist/Kconfig"
source "board/renesas/salvator-x/Kconfig"
source "board/renesas/ulcb/Kconfig"
source "board/renesas/v3hsk/Kconfig"
diff --git a/arch/arm/mach-renesas/cpu_info.c b/arch/arm/mach-renesas/cpu_info.c
index f040d732a51..42183e2daa5 100644
--- a/arch/arm/mach-renesas/cpu_info.c
+++ b/arch/arm/mach-renesas/cpu_info.c
@@ -114,6 +114,8 @@ int arch_misc_init(void)
int print_cpuinfo(void)
{
+ const uintptr_t pfc_base = 0xe6060000;
+ void __iomem *rcar_m3nm3l_ident = (void __iomem *)pfc_base + 0x800;
int i = renesas_cpuinfo_idx();
if (renesas_cpuinfo[i].cpu_type == RENESAS_CPU_TYPE_R8A7796 &&
@@ -123,6 +125,17 @@ int print_cpuinfo(void)
return 0;
}
+ /*
+ * M3Le PRR ID is the same as M3N , but PFC register 0x800 reads 0
+ * on M3N and 1 on M3Le. Use this to discern M3Le from M3N .
+ */
+ if (renesas_cpuinfo[i].cpu_type == RENESAS_CPU_TYPE_R8A77965 &&
+ readl(rcar_m3nm3l_ident) == 1) {
+ printf("CPU: Renesas Electronics R8A779MD rev %d.%d\n",
+ renesas_get_cpu_rev_integer(), renesas_get_cpu_rev_fraction());
+ return 0;
+ }
+
printf("CPU: Renesas Electronics %s rev %d.%d\n",
get_cpu_name(i), renesas_get_cpu_rev_integer(),
renesas_get_cpu_rev_fraction());
diff --git a/arch/arm/mach-stm32mp/include/mach/sys_proto.h b/arch/arm/mach-stm32mp/include/mach/sys_proto.h
index a875907ac3e..05ce869c428 100644
--- a/arch/arm/mach-stm32mp/include/mach/sys_proto.h
+++ b/arch/arm/mach-stm32mp/include/mach/sys_proto.h
@@ -61,20 +61,20 @@
/* ID for STM32MP25x = Device Part Number (RPN) (bit31:0) */
#define CPU_STM32MP257Cxx 0x00002000
#define CPU_STM32MP255Cxx 0x00082000
-#define CPU_STM32MP253Cxx 0x000B2004
-#define CPU_STM32MP251Cxx 0x000B3065
+#define CPU_STM32MP253Cxx 0x000B300C
+#define CPU_STM32MP251Cxx 0x000B306D
#define CPU_STM32MP257Axx 0x40002E00
#define CPU_STM32MP255Axx 0x40082E00
-#define CPU_STM32MP253Axx 0x400B2E04
-#define CPU_STM32MP251Axx 0x400B3E65
+#define CPU_STM32MP253Axx 0x400B3E0C
+#define CPU_STM32MP251Axx 0x400B3E6D
#define CPU_STM32MP257Fxx 0x80002000
#define CPU_STM32MP255Fxx 0x80082000
-#define CPU_STM32MP253Fxx 0x800B2004
-#define CPU_STM32MP251Fxx 0x800B3065
+#define CPU_STM32MP253Fxx 0x800B300C
+#define CPU_STM32MP251Fxx 0x800B306D
#define CPU_STM32MP257Dxx 0xC0002E00
#define CPU_STM32MP255Dxx 0xC0082E00
-#define CPU_STM32MP253Dxx 0xC00B2E04
-#define CPU_STM32MP251Dxx 0xC00B3E65
+#define CPU_STM32MP253Dxx 0xC00B3E0C
+#define CPU_STM32MP251Dxx 0xC00B3E6D
/* return CPU_STMP32MP...Xxx constants */
u32 get_cpu_type(void);
diff --git a/board/renesas/geist/Kconfig b/board/renesas/geist/Kconfig
new file mode 100644
index 00000000000..da36be0942f
--- /dev/null
+++ b/board/renesas/geist/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_GEIST
+
+config SYS_SOC
+ default "renesas"
+
+config SYS_BOARD
+ default "geist"
+
+config SYS_VENDOR
+ default "renesas"
+
+config SYS_CONFIG_NAME
+ default "geist"
+
+endif
diff --git a/board/renesas/geist/Makefile b/board/renesas/geist/Makefile
new file mode 100644
index 00000000000..3e33c91e9e7
--- /dev/null
+++ b/board/renesas/geist/Makefile
@@ -0,0 +1,9 @@
+#
+# Copyright (C) 2025-2026 Renesas Electronics Corporation
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+
+ifndef CONFIG_XPL_BUILD
+obj-y += geist.o
+endif
diff --git a/board/renesas/geist/geist.c b/board/renesas/geist/geist.c
new file mode 100644
index 00000000000..09241aed14c
--- /dev/null
+++ b/board/renesas/geist/geist.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This file is Geist board support.
+ *
+ * Copyright (C) 2025-2026 Renesas Electronics Corporation
+ */
+
+#include <asm/io.h>
+#include <asm/arch/rcar-mstp.h>
+#include <asm/arch/renesas.h>
+#include <init.h>
+
+#define HSUSB_MSTP704 BIT(4) /* HSUSB */
+
+/* HSUSB block registers */
+#define HSUSB_REG_LPSTS 0xE6590102
+#define HSUSB_REG_LPSTS_SUSPM_NORMAL BIT(14)
+#define HSUSB_REG_UGCTRL2 0xE6590184
+#define HSUSB_REG_UGCTRL2_USB0SEL 0x30
+#define HSUSB_REG_UGCTRL2_USB0SEL_EHCI 0x10
+
+int board_init(void)
+{
+ /* USB1 pull-up */
+ setbits_le32(PFC_PUEN6, PUEN_USB1_OVC | PUEN_USB1_PWEN);
+
+ /* Configure the HSUSB block */
+ mstp_clrbits_le32(SMSTPCR7, SMSTPCR7, HSUSB_MSTP704);
+ /* Choice USB0SEL */
+ clrsetbits_le32(HSUSB_REG_UGCTRL2, HSUSB_REG_UGCTRL2_USB0SEL,
+ HSUSB_REG_UGCTRL2_USB0SEL_EHCI);
+ /* low power status */
+ setbits_le16(HSUSB_REG_LPSTS, HSUSB_REG_LPSTS_SUSPM_NORMAL);
+
+ return 0;
+}
diff --git a/board/st/common/Makefile b/board/st/common/Makefile
index 122b13c3aa8..36dfaddfa0e 100644
--- a/board/st/common/Makefile
+++ b/board/st/common/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_PMIC_STPMIC1) += stpmic1.o
ifeq ($(CONFIG_ARCH_STM32MP),y)
obj-$(CONFIG_SET_DFU_ALT_INFO) += stm32mp_dfu.o
obj-$(CONFIG_$(PHASE_)DFU_VIRT) += stm32mp_dfu_virt.o
+obj-$(CONFIG_FWU_MULTI_BANK_UPDATE) += stm32mp_fwu.o
endif
obj-$(CONFIG_TYPEC_STUSB160X) += stusb160x.o
diff --git a/board/st/common/stm32mp_fwu.c b/board/st/common/stm32mp_fwu.c
new file mode 100644
index 00000000000..ac7ca6bdca2
--- /dev/null
+++ b/board/st/common/stm32mp_fwu.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2026 Amarula Solutions, Dario Binacchi <[email protected]>
+ */
+
+#include <fwu.h>
+#include <part_efi.h>
+#include <asm/io.h>
+/**
+ * fwu_plat_get_bootidx() - Get the value of the boot index
+ * @boot_idx: Boot index value
+ *
+ * Get the value of the bank(partition) from which the platform
+ * has booted. This value is passed to U-Boot from the earlier
+ * stage bootloader which loads and boots all the relevant
+ * firmware images
+ *
+ */
+void fwu_plat_get_bootidx(uint *boot_idx)
+{
+ *boot_idx = (readl(TAMP_FWU_BOOT_INFO_REG) >>
+ TAMP_FWU_BOOT_IDX_OFFSET) & TAMP_FWU_BOOT_IDX_MASK;
+}
+
+int fwu_platform_hook(struct udevice *dev, struct fwu_data *data)
+{
+ uint boot_idx;
+ efi_guid_t boot_uuid, root_uuid;
+ const efi_guid_t boot_type_guid = PARTITION_XBOOTLDR;
+ const efi_guid_t root_type_guid =
+ PARTITION_LINUX_FILE_SYSTEM_DATA_GUID;
+ char uuidbuf[UUID_STR_LEN + 1];
+ int retb, retr;
+
+ fwu_plat_get_bootidx(&boot_idx);
+
+ retb = fwu_mdata_get_image_guid(&boot_uuid, &boot_type_guid, boot_idx);
+ retr = fwu_mdata_get_image_guid(&root_uuid, &root_type_guid, boot_idx);
+
+ if (!retb && !retr) {
+ uuid_bin_to_str(boot_uuid.b, uuidbuf, UUID_STR_FORMAT_GUID);
+ env_set("boot_partuuid", uuidbuf);
+
+ uuid_bin_to_str(root_uuid.b, uuidbuf, UUID_STR_FORMAT_GUID);
+ env_set("root_partuuid", uuidbuf);
+ } else if (!retb && retr) {
+ log_warning("%s: found boot GUID but missing root GUID (%d)\n",
+ __func__, retr);
+ } else if (!retr && retb) {
+ log_warning("%s: found root GUID but missing boot GUID (%d)\n",
+ __func__, retb);
+ }
+
+ return 0;
+}
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index 88ede4e3910..9b933a2ba0b 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -837,24 +837,3 @@ static void board_copro_image_process(ulong fw_image, size_t fw_size)
}
U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_COPRO, board_copro_image_process);
-
-#if defined(CONFIG_FWU_MULTI_BANK_UPDATE)
-
-#include <fwu.h>
-
-/**
- * fwu_plat_get_bootidx() - Get the value of the boot index
- * @boot_idx: Boot index value
- *
- * Get the value of the bank(partition) from which the platform
- * has booted. This value is passed to U-Boot from the earlier
- * stage bootloader which loads and boots all the relevant
- * firmware images
- *
- */
-void fwu_plat_get_bootidx(uint *boot_idx)
-{
- *boot_idx = (readl(TAMP_FWU_BOOT_INFO_REG) >>
- TAMP_FWU_BOOT_IDX_OFFSET) & TAMP_FWU_BOOT_IDX_MASK;
-}
-#endif /* CONFIG_FWU_MULTI_BANK_UPDATE */
diff --git a/board/st/stm32mp2/stm32mp2.c b/board/st/stm32mp2/stm32mp2.c
index 5cbbbc322a3..7bc7d2a608f 100644
--- a/board/st/stm32mp2/stm32mp2.c
+++ b/board/st/stm32mp2/stm32mp2.c
@@ -188,56 +188,3 @@ void board_quiesce_devices(void)
{
led_boot_off();
}
-
-#if defined(CONFIG_FWU_MULTI_BANK_UPDATE)
-
-#include <fwu.h>
-
-/**
- * fwu_plat_get_bootidx() - Get the value of the boot index
- * @boot_idx: Boot index value
- *
- * Get the value of the bank(partition) from which the platform
- * has booted. This value is passed to U-Boot from the earlier
- * stage bootloader which loads and boots all the relevant
- * firmware images
- *
- */
-void fwu_plat_get_bootidx(uint *boot_idx)
-{
- *boot_idx = (readl(TAMP_FWU_BOOT_INFO_REG) >>
- TAMP_FWU_BOOT_IDX_OFFSET) & TAMP_FWU_BOOT_IDX_MASK;
-}
-
-int fwu_platform_hook(struct udevice *dev, struct fwu_data *data)
-{
- uint boot_idx;
- efi_guid_t boot_uuid, root_uuid;
- const efi_guid_t boot_type_guid = PARTITION_XBOOTLDR;
- const efi_guid_t root_type_guid =
- PARTITION_LINUX_FILE_SYSTEM_DATA_GUID;
- char uuidbuf[UUID_STR_LEN + 1];
- int retb, retr;
-
- fwu_plat_get_bootidx(&boot_idx);
-
- retb = fwu_mdata_get_image_guid(&boot_uuid, &boot_type_guid, boot_idx);
- retr = fwu_mdata_get_image_guid(&root_uuid, &root_type_guid, boot_idx);
-
- if (!retb && !retr) {
- uuid_bin_to_str(boot_uuid.b, uuidbuf, UUID_STR_FORMAT_GUID);
- env_set("boot_partuuid", uuidbuf);
-
- uuid_bin_to_str(root_uuid.b, uuidbuf, UUID_STR_FORMAT_GUID);
- env_set("root_partuuid", uuidbuf);
- } else if (!retb && retr) {
- log_warning("%s: found boot GUID but missing root GUID (%d)\n",
- __func__, retr);
- } else if (!retr && retb) {
- log_warning("%s: found root GUID but missing boot GUID (%d)\n",
- __func__, retb);
- }
-
- return 0;
-}
-#endif /* CONFIG_FWU_MULTI_BANK_UPDATE */
diff --git a/board/toradex/verdin-imx95/verdin-imx95.c b/board/toradex/verdin-imx95/verdin-imx95.c
index 60c1dbb5e29..7c0804c1d1c 100644
--- a/board/toradex/verdin-imx95/verdin-imx95.c
+++ b/board/toradex/verdin-imx95/verdin-imx95.c
@@ -50,10 +50,10 @@ int board_late_init(void)
}
static const struct ram_alias_check ram_alias_checks[] = {
- { (void *)(PHYS_SDRAM + SZ_8G), (void *)(PHYS_SDRAM), SZ_16G },
- { (void *)(PHYS_SDRAM + SZ_4G), (void *)(PHYS_SDRAM), SZ_8G },
- { (void *)(PHYS_SDRAM + SZ_2G), (void *)(PHYS_SDRAM), SZ_4G },
- { (void *)(PHYS_SDRAM + SZ_1G), (void *)(PHYS_SDRAM), SZ_2G },
+ { (void *)((uintptr_t)PHYS_SDRAM + SZ_8G), (void *)(PHYS_SDRAM), SZ_16G },
+ { (void *)((uintptr_t)PHYS_SDRAM + SZ_4G), (void *)(PHYS_SDRAM), SZ_8G },
+ { (void *)((uintptr_t)PHYS_SDRAM + SZ_2G), (void *)(PHYS_SDRAM), SZ_4G },
+ { (void *)((uintptr_t)PHYS_SDRAM + SZ_1G), (void *)(PHYS_SDRAM), SZ_2G },
{ NULL }
};
diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c
index 419ab1f1b0e..8c1310dabeb 100644
--- a/boot/pxe_utils.c
+++ b/boot/pxe_utils.c
@@ -546,7 +546,7 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
char *zboot_argv[] = { "zboot", NULL, "0", NULL, NULL };
char *kernel_addr = NULL;
char *initrd_addr_str = NULL;
- char initrd_filesize[10];
+ char initrd_filesize[17];
char initrd_str[28];
char mac_str[29] = "";
char ip_str[68] = "";
diff --git a/configs/kontron-sl-mx6ul_defconfig b/configs/kontron-sl-mx6ul_defconfig
index 8d540a381fc..0804eb02c37 100644
--- a/configs/kontron-sl-mx6ul_defconfig
+++ b/configs/kontron-sl-mx6ul_defconfig
@@ -93,6 +93,7 @@ CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_MDIO=y
CONFIG_DM_ETH_PHY=y
CONFIG_FEC_MXC=y
CONFIG_MII=y
diff --git a/configs/r8a779md_geist_defconfig b/configs/r8a779md_geist_defconfig
new file mode 100644
index 00000000000..2d25690354b
--- /dev/null
+++ b/configs/r8a779md_geist_defconfig
@@ -0,0 +1,75 @@
+#include <configs/renesas_rcar3.config>
+
+# CONFIG_OF_UPSTREAM is not set
+
+CONFIG_ARM=y
+CONFIG_ARCH_RENESAS=y
+CONFIG_RCAR_GEN3=y
+CONFIG_COUNTER_FREQUENCY=16666666
+CONFIG_ARCH_CPU_INIT=y
+CONFIG_ENV_SIZE=0x20000
+CONFIG_ENV_OFFSET=0xFFFE0000
+CONFIG_DEFAULT_DEVICE_TREE="r8a779md-geist"
+CONFIG_SPL_TEXT_BASE=0xe6338000
+CONFIG_TARGET_GEIST=y
+CONFIG_SPL_HAVE_INIT_STACK=y
+CONFIG_SPL_STACK=0xe6304000
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0xe633f000
+CONFIG_SPL_BSS_MAX_SIZE=0x1000
+CONFIG_PCI=y
+CONFIG_SYS_MONITOR_BASE=0x00000000
+# CONFIG_EFI_UNICODE_CAPITALIZATION is not set
+# CONFIG_BOOTSTD is not set
+CONFIG_USE_BOOTARGS=y
+CONFIG_USE_BOOTCOMMAND=y
+CONFIG_BOOTCOMMAND="setexpr dloadaddr ${loadaddr} + 0x200000 && setexpr dloadaddr ${dloadaddr} \\\\& 0xffc00000 && setexpr kloadaddr ${dloadaddr} + 0x200000 && tftp ${dloadaddr} Image-r8a779md-geist.dtb && tftp ${kloadaddr} Image && booti ${kloadaddr} - ${dloadaddr}"
+CONFIG_DEFAULT_FDT_FILE="r8a779md-geist.dtb"
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=10
+CONFIG_CMD_DFU=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_MULTI_DTB_FIT_LZO=y
+CONFIG_MULTI_DTB_FIT_USER_DEFINED_AREA=y
+CONFIG_OF_DTB_PROPS_REMOVE=y
+CONFIG_OF_REMOVE_PROPS="dmas dma-names interrupt-parent interrupts interrupts-extended interrupt-names interrupt-map interrupt-map-mask iommus"
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_RELOC_GD_ENV_ADDR=y
+CONFIG_ENV_MMC_EMMC_HW_PARTITION=2
+CONFIG_DFU_TFTP=y
+CONFIG_DFU_RAM=y
+CONFIG_DFU_SF=y
+CONFIG_SYS_I2C_RCAR_IIC=y
+CONFIG_MISC=y
+CONFIG_I2C_EEPROM=y
+CONFIG_SYS_I2C_EEPROM_ADDR=0x70
+CONFIG_MMC_IO_VOLTAGE=y
+CONFIG_MMC_UHS_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
+CONFIG_RENESAS_SDHI=y
+CONFIG_DM_MTD=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_PHY_MICREL=y
+CONFIG_PHY_MICREL_KSZ90X1=y
+CONFIG_DM_ETH_PHY=y
+CONFIG_RENESAS_RAVB=y
+CONFIG_NVME_PCI=y
+CONFIG_PCI_REGION_MULTI_ENTRY=y
+CONFIG_PCI_RCAR_GEN3=y
+CONFIG_SYSINFO=y
+CONFIG_TEE=y
+CONFIG_OPTEE=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="Renesas"
+CONFIG_USB_GADGET_VENDOR_NUM=0x045b
+CONFIG_USB_GADGET_PRODUCT_NUM=0x023c
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_USB_RENESAS_USBHS=y
+CONFIG_USB_STORAGE=y
diff --git a/configs/rpi_arm64_defconfig b/configs/rpi_arm64_defconfig
index 69e8e72c5d7..cdcf05ea6db 100644
--- a/configs/rpi_arm64_defconfig
+++ b/configs/rpi_arm64_defconfig
@@ -11,6 +11,7 @@ CONFIG_SYS_LOAD_ADDR=0x1000000
CONFIG_PCI=y
CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
+CONFIG_EFI_HTTP_BOOT=y
CONFIG_BOOTSTD_DEFAULTS=y
CONFIG_OF_BOARD_SETUP=y
CONFIG_FDT_SIMPLEFB=y
@@ -26,11 +27,13 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_MMC=y
CONFIG_CMD_PCI=y
CONFIG_CMD_USB=y
+CONFIG_CMD_SNTP=y
+CONFIG_WGET_HTTPS=y
CONFIG_CMD_EFIDEBUG=y
CONFIG_CMD_FS_UUID=y
CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
-CONFIG_TFTP_TSIZE=y
+CONFIG_NET_LWIP=y
CONFIG_DM_DMA=y
CONFIG_DFU_MMC=y
CONFIG_SYS_DFU_DATA_BUF_SIZE=0x100000
@@ -44,6 +47,8 @@ CONFIG_BCMGENET=y
CONFIG_PCI_BRCMSTB=y
CONFIG_PINCTRL=y
# CONFIG_PINCTRL_GENERIC is not set
+CONFIG_RESET_BRCMSTB=y
+CONFIG_RESET_BRCMSTB_RESCAL=y
CONFIG_DM_RNG=y
CONFIG_RNG_IPROC200=y
# CONFIG_REQUIRE_SERIAL_CONSOLE is not set
@@ -64,4 +69,5 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_BCM2835=y
CONFIG_CONSOLE_SCROLL_LINES=10
CONFIG_PHYS_TO_BUS=y
+CONFIG_MBEDTLS_LIB=y
# CONFIG_HEXDUMP is not set
diff --git a/configs/stm32mp13_defconfig b/configs/stm32mp13_defconfig
index 620a6da2efe..2ad57e23e44 100644
--- a/configs/stm32mp13_defconfig
+++ b/configs/stm32mp13_defconfig
@@ -113,4 +113,6 @@ CONFIG_USB_GADGET_MANUFACTURER="STMicroelectronics"
CONFIG_USB_GADGET_VENDOR_NUM=0x0483
CONFIG_USB_GADGET_PRODUCT_NUM=0x5720
CONFIG_USB_GADGET_DWC2_OTG=y
+CONFIG_WDT=y
+CONFIG_WDT_ARM_SMC=y
CONFIG_ERRNO_STR=y
diff --git a/configs/stm32mp15_defconfig b/configs/stm32mp15_defconfig
index b9e44254087..53903376524 100644
--- a/configs/stm32mp15_defconfig
+++ b/configs/stm32mp15_defconfig
@@ -1,7 +1,7 @@
CONFIG_ARM=y
CONFIG_ARCH_STM32MP=y
CONFIG_TFABOOT=y
-CONFIG_SYS_MALLOC_F_LEN=0x80000
+CONFIG_SYS_MALLOC_F_LEN=0x90000
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc0100000
CONFIG_ENV_OFFSET=0x900000
CONFIG_ENV_SECT_SIZE=0x40000
@@ -169,5 +169,6 @@ CONFIG_BMP_24BPP=y
CONFIG_BMP_32BPP=y
CONFIG_WDT=y
CONFIG_WDT_STM32MP=y
+CONFIG_WDT_ARM_SMC=y
# CONFIG_BINMAN_FDT is not set
CONFIG_ERRNO_STR=y
diff --git a/doc/develop/release_cycle.rst b/doc/develop/release_cycle.rst
index b53eac45504..1e3e179d77f 100644
--- a/doc/develop/release_cycle.rst
+++ b/doc/develop/release_cycle.rst
@@ -77,7 +77,7 @@ For the next scheduled release, release candidates were made on:
* U-Boot |next_ver|-rc3 was released on Mon 25 May 2026.
-.. * U-Boot |next_ver|-rc4 was released on Mon 08 June 2026.
+* U-Boot |next_ver|-rc4 was released on Mon 08 June 2026.
.. * U-Boot |next_ver|-rc5 was released on Mon 22 June 2026.
diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c
index d94a24ea30a..2bd76ffa739 100644
--- a/drivers/cpu/imx8_cpu.c
+++ b/drivers/cpu/imx8_cpu.c
@@ -228,7 +228,7 @@ static int cpu_imx_get_desc(const struct udevice *dev, char *buf, int size)
ret = snprintf(buf, size, "NXP i.MX%s Rev%s %s at %u MHz",
plat->type, plat->rev, plat->name, plat->freq_mhz);
- if (IS_ENABLED(CONFIG_IMX_TMU)) {
+ if (!IS_ENABLED(CONFIG_IMX8)) { /* imx8 does not have segment fuse */
switch (get_cpu_temp_grade(&minc, &maxc)) {
case TEMP_AUTOMOTIVE:
grade = "Automotive temperature grade";
@@ -237,7 +237,10 @@ static int cpu_imx_get_desc(const struct udevice *dev, char *buf, int size)
grade = "Industrial temperature grade";
break;
case TEMP_EXTCOMMERCIAL:
- grade = "Extended Consumer temperature grade";
+ if (IS_ENABLED(CONFIG_ARCH_IMX9))
+ grade = "Extended Industrial temperature grade";
+ else
+ grade = "Extended Consumer temperature grade";
break;
default:
grade = "Consumer temperature grade";
diff --git a/drivers/mmc/bcm2835_sdhci.c b/drivers/mmc/bcm2835_sdhci.c
index 655d9902dfa..efa4d14f5da 100644
--- a/drivers/mmc/bcm2835_sdhci.c
+++ b/drivers/mmc/bcm2835_sdhci.c
@@ -219,6 +219,10 @@ static int bcm2835_sdhci_probe(struct udevice *dev)
host->mmc = &plat->mmc;
host->mmc->dev = dev;
+ ret = mmc_of_parse(dev, &plat->cfg);
+ if (ret)
+ return ret;
+
ret = sdhci_setup_cfg(&plat->cfg, host, emmc_freq, MIN_FREQ);
if (ret) {
debug("%s: Failed to setup SDHCI (err=%d)\n", __func__, ret);
diff --git a/drivers/mmc/bcmstb_sdhci.c b/drivers/mmc/bcmstb_sdhci.c
index 7bddbebb162..f27b84a6ee4 100644
--- a/drivers/mmc/bcmstb_sdhci.c
+++ b/drivers/mmc/bcmstb_sdhci.c
@@ -56,7 +56,7 @@ struct sdhci_brcmstb_dev_priv {
static int sdhci_brcmstb_init_2712(struct udevice *dev)
{
- struct sdhci_host *host = dev_get_priv(dev);
+ struct sdhci_bcmstb_plat *plat = dev_get_plat(dev);
void *cfg_regs;
u32 reg;
@@ -65,8 +65,8 @@ static int sdhci_brcmstb_init_2712(struct udevice *dev)
if (!cfg_regs)
return -ENOENT;
- if ((host->mmc->host_caps & MMC_CAP_NONREMOVABLE) ||
- (host->mmc->host_caps & MMC_CAP_NEEDS_POLL)) {
+ if ((plat->cfg.host_caps & MMC_CAP_NONREMOVABLE) ||
+ (plat->cfg.host_caps & MMC_CAP_NEEDS_POLL)) {
/* Force presence */
reg = readl(cfg_regs + SDIO_CFG_CTRL);
reg &= ~SDIO_CFG_CTRL_SDCD_N_TEST_LEV;
diff --git a/drivers/net/ti/icssg_prueth.c b/drivers/net/ti/icssg_prueth.c
index 12a162b9d68..4796d0d67cd 100644
--- a/drivers/net/ti/icssg_prueth.c
+++ b/drivers/net/ti/icssg_prueth.c
@@ -496,14 +496,15 @@ static int prueth_port_probe(struct udevice *dev)
{
struct prueth_priv *priv = dev_get_priv(dev);
struct prueth *prueth;
- char portname[15];
+ char portname[64];
int ret;
priv->dev = dev;
prueth = dev_get_priv(dev->parent);
priv->prueth = prueth;
- sprintf(portname, "%s-%s", dev->parent->name, dev->name);
+ snprintf(portname, sizeof(portname), "%s-%s", dev->parent->name, dev->name);
+ portname[sizeof(portname) - 1] = '\0';
device_set_name(dev, portname);
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
index 0631b190b97..147a104149e 100644
--- a/drivers/nvme/nvme.c
+++ b/drivers/nvme/nvme.c
@@ -27,6 +27,23 @@
#define IO_TIMEOUT 30
#define MAX_PRP_POOL 512
+/**
+ * nvme_invalidate_cache_aligned() - invalidate cache with proper alignment
+ *
+ * Aligns cache invalidation to cacheline boundaries to ensure correct
+ * behavior even when the DMA buffer is not aligned to page boundaries.
+ *
+ * @addr: The start address of the buffer
+ * @length: The length of the buffer in bytes
+ */
+static inline void nvme_invalidate_cache_aligned(uintptr_t addr, int length)
+{
+ uintptr_t start_addr = addr & ~(ARCH_DMA_MINALIGN - 1);
+ uintptr_t end_addr = ALIGN(addr + length, ARCH_DMA_MINALIGN);
+
+ invalidate_dcache_range(start_addr, end_addr);
+}
+
static int nvme_wait_csts(struct nvme_dev *dev, u32 mask, u32 val)
{
int timeout;
@@ -182,8 +199,10 @@ static int nvme_submit_sync_cmd(struct nvme_queue *nvmeq,
if ((status & 0x01) == phase)
break;
if (timeout_us > 0 && (timer_get_us() - start_time)
- >= timeout_us)
+ >= timeout_us) {
+ pr_warn("nvme: cmd %#x timed out\n", cmd->common.command_id);
return -ETIMEDOUT;
+ }
}
ops = (struct nvme_ops *)nvmeq->dev->udev->driver->ops;
@@ -281,11 +300,6 @@ static int nvme_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id)
return nvme_submit_admin_cmd(dev, &c, NULL);
}
-static int nvme_delete_sq(struct nvme_dev *dev, u16 sqid)
-{
- return nvme_delete_queue(dev, nvme_admin_delete_sq, sqid);
-}
-
static int nvme_delete_cq(struct nvme_dev *dev, u16 cqid)
{
return nvme_delete_queue(dev, nvme_admin_delete_cq, cqid);
@@ -456,6 +470,7 @@ int nvme_identify(struct nvme_dev *dev, unsigned nsid,
u32 page_size = dev->page_size;
int offset = dma_addr & (page_size - 1);
int length = sizeof(struct nvme_id_ctrl);
+ dma_addr_t orig_dma_addr = dma_addr;
int ret;
memset(&c, 0, sizeof(c));
@@ -473,13 +488,13 @@ int nvme_identify(struct nvme_dev *dev, unsigned nsid,
c.identify.cns = cpu_to_le32(cns);
- invalidate_dcache_range(dma_addr,
- dma_addr + sizeof(struct nvme_id_ctrl));
+ nvme_invalidate_cache_aligned((uintptr_t)orig_dma_addr,
+ sizeof(struct nvme_id_ctrl));
ret = nvme_submit_admin_cmd(dev, &c, NULL);
if (!ret)
- invalidate_dcache_range(dma_addr,
- dma_addr + sizeof(struct nvme_id_ctrl));
+ nvme_invalidate_cache_aligned((uintptr_t)orig_dma_addr,
+ sizeof(struct nvme_id_ctrl));
return ret;
}
@@ -545,20 +560,19 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid)
nvmeq->cq_vector = qid - 1;
result = nvme_alloc_cq(dev, qid, nvmeq);
if (result < 0)
- goto release_cq;
+ goto release_ret;
result = nvme_alloc_sq(dev, qid, nvmeq);
if (result < 0)
- goto release_sq;
+ goto release_cq;
nvme_init_queue(nvmeq, qid);
return result;
- release_sq:
- nvme_delete_sq(dev, qid);
release_cq:
nvme_delete_cq(dev, qid);
+ release_ret:
return result;
}
@@ -868,14 +882,14 @@ int nvme_init(struct udevice *udev)
if (!ndev->prp_pool) {
ret = -ENOMEM;
printf("Error: %s: Out of memory!\n", udev->name);
- goto free_nvme;
+ goto free_queue;
}
ndev->prp_entry_num = MAX_PRP_POOL >> 3;
ret = nvme_setup_io_queues(ndev);
if (ret) {
log_debug("Unable to setup I/O queues(err=%dE)\n", ret);
- goto free_queue;
+ goto free_prp_pool;
}
nvme_get_info_from_identify(ndev);
@@ -885,7 +899,7 @@ int nvme_init(struct udevice *udev)
id = memalign(ndev->page_size, sizeof(struct nvme_id_ns));
if (!id) {
ret = -ENOMEM;
- goto free_queue;
+ goto free_prp_pool;
}
for (int i = 1; i <= ndev->nn; i++) {
@@ -930,6 +944,8 @@ int nvme_init(struct udevice *udev)
free_id:
free(id);
+free_prp_pool:
+ free((void *)ndev->prp_pool);
free_queue:
free((void *)ndev->queues);
free_nvme:
diff --git a/drivers/pci/pcie_brcmstb.c b/drivers/pci/pcie_brcmstb.c
index f089c48f028..1b03b0a7b05 100644
--- a/drivers/pci/pcie_brcmstb.c
+++ b/drivers/pci/pcie_brcmstb.c
@@ -21,6 +21,7 @@
#include <linux/bitfield.h>
#include <linux/log2.h>
#include <linux/iopoll.h>
+#include <reset.h>
/* PCIe parameters */
#define BRCM_NUM_PCIE_OUT_WINS 4
@@ -49,6 +50,47 @@
#define SSC_STATUS_PLL_LOCK_MASK 0x800
#define SSC_STATUS_PLL_LOCK_SHIFT 11
+#define PCIE_RC_PL_PHY_CTL_15 0x184c
+#define PCIE_RC_PL_PHY_CTL_15_DIS_PLL_PD_MASK 0x400000
+#define PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD_MASK 0xff
+
+#define PCIE_MISC_UBUS_CTRL 0x40a4
+#define PCIE_MISC_UBUS_CTRL_UBUS_PCIE_REPLY_ERR_DIS_MASK BIT(13)
+#define PCIE_MISC_UBUS_CTRL_UBUS_PCIE_REPLY_DECERR_DIS_MASK BIT(19)
+#define PCIE_MISC_AXI_READ_ERROR_DATA 0x4170
+#define PCIE_MISC_UBUS_TIMEOUT 0x40A8
+#define PCIE_MISC_RC_CONFIG_RETRY_TIMEOUT 0x405c
+#define PCIE_MISC_RC_BAR4_CONFIG_LO 0x40d4
+#define PCIE_MISC_RC_BAR4_CONFIG_HI 0x40d8
+#define PCIE_MISC_UBUS_BAR_CONFIG_REMAP_HI_MASK 0xff
+#define PCIE_MISC_UBUS_BAR4_CONFIG_REMAP_HI 0x4110
+#define PCIE_MISC_UBUS_BAR_CONFIG_REMAP_ENABLE 0x1
+#define PCIE_MISC_UBUS_BAR_CONFIG_REMAP_LO_MASK 0xfffff000
+#define PCIE_MISC_UBUS_BAR4_CONFIG_REMAP_LO 0x410c
+
+#define PCIE_MISC_UBUS_BAR1_CONFIG_REMAP 0x40ac
+#define PCIE_MISC_UBUS_BAR2_CONFIG_REMAP 0x40b4
+#define PCIE_MISC_UBUS_BAR2_CONFIG_REMAP_ACCESS_ENABLE_MASK BIT(0)
+#define MISC_CTRL_PCIE_RCB_MPS_MODE_MASK 0x400
+
+enum {
+ RGR1_SW_INIT_1,
+ PCIE_HARD_DEBUG,
+};
+
+enum brcm_pcie_type {
+ BCM2711,
+ BCM2712
+};
+
+struct brcm_pcie;
+
+struct brcm_pcie_cfg_data {
+ const int *offsets;
+ const enum brcm_pcie_type type;
+ void (*perst_set)(struct brcm_pcie *pcie, u32 val);
+};
+
/**
* struct brcm_pcie - the PCIe controller state
* @base: Base address of memory mapped IO registers of the controller
@@ -61,6 +103,9 @@ struct brcm_pcie {
int gen;
bool ssc;
+ struct reset_ctl rescal;
+ struct reset_ctl bridge_reset;
+ const struct brcm_pcie_cfg_data *pcie_cfg;
};
/**
@@ -79,8 +124,8 @@ static int brcm_pcie_encode_ibar_size(u64 size)
if (log2_in >= 12 && log2_in <= 15)
/* Covers 4KB to 32KB (inclusive) */
return (log2_in - 12) + 0x1c;
- else if (log2_in >= 16 && log2_in <= 37)
- /* Covers 64KB to 32GB, (inclusive) */
+ else if (log2_in >= 16 && log2_in <= 36)
+ /* Covers 64KB to 64GB, (inclusive) */
return log2_in - 15;
/* Something is awry so disable */
@@ -104,6 +149,80 @@ static bool brcm_pcie_rc_mode(struct brcm_pcie *pcie)
return (val & STATUS_PCIE_PORT_MASK) >> STATUS_PCIE_PORT_SHIFT;
}
+static void brcm_pcie_perst_set_generic(struct brcm_pcie *pcie, u32 val)
+{
+ if (val)
+ setbits_le32(pcie->base + pcie->pcie_cfg->offsets[RGR1_SW_INIT_1],
+ RGR1_SW_INIT_1_PERST_MASK);
+ else
+ clrbits_le32(pcie->base + pcie->pcie_cfg->offsets[RGR1_SW_INIT_1],
+ RGR1_SW_INIT_1_PERST_MASK);
+}
+
+static void brcm_pcie_perst_set_2712(struct brcm_pcie *pcie, u32 val)
+{
+ u32 tmp;
+
+ /* Perst bit has moved and assert value is 0 */
+ tmp = readl(pcie->base + PCIE_MISC_PCIE_CTRL);
+ u32p_replace_bits(&tmp, !val, RGR1_SW_INIT_1_PERSTB_MASK);
+ writel(tmp, pcie->base + PCIE_MISC_PCIE_CTRL);
+}
+
+static int brcm_pcie_get_resets_dt(struct udevice *dev)
+{
+ struct brcm_pcie *pcie = dev_get_priv(dev);
+ int ret;
+
+ ret = reset_get_by_name(dev, "rescal", &pcie->rescal);
+ if (ret) {
+ printf("Unable to get rescal reset\n");
+ return ret;
+ }
+
+ ret = reset_get_by_name(dev, "bridge", &pcie->bridge_reset);
+ if (ret)
+ printf("Unable to get bridge reset\n");
+
+ return ret;
+}
+
+static int brcm_pcie_do_reset(struct udevice *dev)
+{
+ struct brcm_pcie *pcie = dev_get_priv(dev);
+ int ret;
+
+ ret = reset_deassert(&pcie->rescal);
+ if (ret)
+ printf("failed to deassert 'rescal'\n");
+ return ret;
+}
+
+static int brcm_pcie_bridge_sw_init_set(struct brcm_pcie *pcie, u32 val)
+{
+ int ret = 0;
+
+ if (reset_valid(&pcie->bridge_reset))
+ {
+ if (val)
+ ret = reset_assert(&pcie->bridge_reset);
+ else
+ ret = reset_deassert(&pcie->bridge_reset);
+ if (ret)
+ log_err("failed to %sassert bridge reset, err=%d\n",
+ val ? "" : "de", ret);
+ return ret;
+ }
+
+ if (val)
+ setbits_le32(pcie->base + pcie->pcie_cfg->offsets[RGR1_SW_INIT_1],
+ RGR1_SW_INIT_1_INIT_MASK);
+ else
+ clrbits_le32(pcie->base + pcie->pcie_cfg->offsets[RGR1_SW_INIT_1],
+ RGR1_SW_INIT_1_INIT_MASK);
+ return 0;
+}
+
/**
* brcm_pcie_link_up() - Check whether the PCIe link is up
* @pcie: Pointer to the PCIe controller state
@@ -125,7 +244,7 @@ static int brcm_pcie_config_address(const struct udevice *dev, pci_dev_t bdf,
uint offset, void **paddress)
{
struct brcm_pcie *pcie = dev_get_priv(dev);
- unsigned int pci_bus = PCI_BUS(bdf);
+ unsigned int pci_bus = PCI_BUS(bdf) - dev_seq(dev);
unsigned int pci_dev = PCI_DEV(bdf);
unsigned int pci_func = PCI_FUNC(bdf);
int idx;
@@ -345,28 +464,150 @@ static void brcm_pcie_set_outbound_win(struct brcm_pcie *pcie,
writel(tmp, base + PCIE_MEM_WIN0_LIMIT_HI(win));
}
+static u32 brcm_bar_reg_offset(int bar)
+{
+ if (bar <= 3)
+ return PCIE_MISC_RC_BAR1_CONFIG_LO + 8 * (bar - 1);
+ else
+ return PCIE_MISC_RC_BAR4_CONFIG_LO + 8 * (bar - 4);
+}
+
+static u32 brcm_ubus_reg_offset(int bar)
+{
+ if (bar <= 3)
+ return PCIE_MISC_UBUS_BAR1_CONFIG_REMAP + 8 * (bar - 1);
+ else
+ return PCIE_MISC_UBUS_BAR4_CONFIG_REMAP_LO + 8 * (bar - 4);
+}
+
+/*
+ * Round size up to the next power of two, as required by
+ * brcm_pcie_encode_ibar_size(). If size is already a power of two
+ * fls64(size - 1) still gives the correct result because the hardware
+ * encodes the exponent, not the raw value.
+ */
+static u64 brcm_ibar_round_size(u64 size)
+{
+ return 1ULL << fls64(size - 1);
+}
+
+static void brcm_pcie_set_inbound_windows(struct udevice *dev)
+{
+ struct brcm_pcie *pcie = dev_get_priv(dev);
+ void __iomem *base = pcie->base;
+ bool is_2712 = (pcie->pcie_cfg->type == BCM2712);
+ int i, ibar_no, ret;
+ u32 tmp;
+
+ ibar_no = 0;
+ /* pre-2712 chips leave the first entry empty */
+ if (pcie->pcie_cfg->type != BCM2712)
+ ibar_no++;
+
+ /* program inbound windows from OF property "dma-regions" */
+ for (i = 0; i < 7; i++, ibar_no++) {
+ u64 bar_cpu, bar_size, bar_pci;
+ struct pci_region region;
+ int ubus_bar_offset, rc_bar_offset;
+
+ ret = pci_get_dma_regions(dev, &region, i);
+ if (ret) /* no region #i? Then we're done. */
+ break;
+ ubus_bar_offset = brcm_ubus_reg_offset(ibar_no + 1);
+ rc_bar_offset = brcm_bar_reg_offset(ibar_no + 1);
+
+ bar_pci = region.bus_start;
+ bar_cpu = region.phys_start;
+ bar_size = region.size;
+
+ if (is_2712) {
+ /* BCM2712: BAR holds raw PCI address; UBUS remap
+ * registers supply the CPU-side translation. */
+ tmp = lower_32_bits(bar_pci);
+ u32p_replace_bits(&tmp, brcm_pcie_encode_ibar_size(bar_size),
+ RC_BAR2_CONFIG_LO_SIZE_MASK);
+ writel(tmp, base + rc_bar_offset);
+ writel(upper_32_bits(bar_pci), base + rc_bar_offset + 4);
+
+ tmp = lower_32_bits(bar_cpu) &
+ PCIE_MISC_UBUS_BAR_CONFIG_REMAP_LO_MASK;
+ tmp |= PCIE_MISC_UBUS_BAR_CONFIG_REMAP_ENABLE;
+ writel(tmp, base + ubus_bar_offset);
+
+ tmp = upper_32_bits(bar_cpu) &
+ PCIE_MISC_UBUS_BAR_CONFIG_REMAP_HI_MASK;
+ writel(tmp, base + ubus_bar_offset + 4);
+ } else {
+ /* Pre-BCM2712 (e.g. BCM2711 / RPi4): the BAR config
+ * register holds the offset (bus_start - phys_start),
+ * not the raw PCI address. The size must be rounded
+ * up to the next power of two before encoding. */
+ u64 bar_offset = bar_pci - bar_cpu;
+ u64 bar_size_po2 = brcm_ibar_round_size(bar_size);
+
+ tmp = lower_32_bits(bar_offset);
+ u32p_replace_bits(&tmp, brcm_pcie_encode_ibar_size(bar_size_po2),
+ RC_BAR2_CONFIG_LO_SIZE_MASK);
+ writel(tmp, base + rc_bar_offset);
+ writel(upper_32_bits(bar_offset), base + rc_bar_offset + 4);
+ /* UBUS remap registers are not used on pre-2712 hardware. */
+ }
+ }
+}
+
+static void brcm_pcie_munge_pll(struct brcm_pcie *pcie)
+{
+ u32 tmp;
+ int ret, i;
+ u8 regs[] = { 0x16, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1e };
+ u16 data[] = { 0x50b9, 0xbda1, 0x0094, 0x97b4, 0x5030, 0x5030, 0x0007 };
+
+ ret = brcm_pcie_mdio_write(pcie->base, MDIO_PORT0, SET_ADDR_OFFSET,
+ 0x1600);
+ for (i = 0; i < ARRAY_SIZE(regs); i++) {
+ brcm_pcie_mdio_read(pcie->base, MDIO_PORT0, regs[i], &tmp);
+ debug("PCIE MDIO pre_refclk 0x%02x = 0x%04x\n",
+ regs[i], tmp);
+ }
+ for (i = 0; i < ARRAY_SIZE(regs); i++) {
+ brcm_pcie_mdio_write(pcie->base, MDIO_PORT0, regs[i], data[i]);
+ brcm_pcie_mdio_read(pcie->base, MDIO_PORT0, regs[i], &tmp);
+ debug("PCIE MDIO post_refclk 0x%02x = 0x%04x\n",
+ regs[i], tmp);
+ }
+
+ udelay(200);
+}
+
static int brcm_pcie_probe(struct udevice *dev)
{
struct udevice *ctlr = pci_get_controller(dev);
struct pci_controller *hose = dev_get_uclass_priv(ctlr);
struct brcm_pcie *pcie = dev_get_priv(dev);
void __iomem *base = pcie->base;
- struct pci_region region;
bool ssc_good = false;
int num_out_wins = 0;
- u64 rc_bar2_offset, rc_bar2_size;
- unsigned int scb_size_val;
- int i, ret;
+ int i, ret = 0;
u16 nlw, cls, lnksta;
u32 tmp;
/*
+ * Ensure rescal reset for BCM2712 is really disabled.
+ */
+ if (pcie->pcie_cfg->type == BCM2712)
+ ret = brcm_pcie_do_reset(dev);
+ if (ret)
+ return ret;
+ /*
* Reset the bridge, assert the fundamental reset. Note for some SoCs,
* e.g. BCM7278, the fundamental reset should not be asserted here.
* This will need to be changed when support for other SoCs is added.
*/
- setbits_le32(base + PCIE_RGR1_SW_INIT_1,
- PCIE_RGR1_SW_INIT_1_INIT_MASK | PCIE_RGR1_SW_INIT_1_PERST_MASK);
+ ret = brcm_pcie_bridge_sw_init_set(pcie, 1);
+ if (ret)
+ return ret;
+ if (pcie->pcie_cfg->type != BCM2712)
+ pcie->pcie_cfg->perst_set(pcie, 1);
/*
* The delay is a safety precaution to preclude the reset signal
* from looking like a glitch.
@@ -374,39 +615,77 @@ static int brcm_pcie_probe(struct udevice *dev)
udelay(100);
/* Take the bridge out of reset */
- clrbits_le32(base + PCIE_RGR1_SW_INIT_1, PCIE_RGR1_SW_INIT_1_INIT_MASK);
-
- clrbits_le32(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG,
+ ret = brcm_pcie_bridge_sw_init_set(pcie, 0);
+ if (ret)
+ return ret;
+ clrbits_le32(base + pcie->pcie_cfg->offsets[PCIE_HARD_DEBUG],
PCIE_HARD_DEBUG_SERDES_IDDQ_MASK);
/* Wait for SerDes to be stable */
udelay(100);
+ if (pcie->pcie_cfg->type == BCM2712) {
+ /* Allow a 54MHz (xosc) refclk source */
+ brcm_pcie_munge_pll(pcie);
+ /* Fix for L1SS errata */
+ tmp = readl(base + PCIE_RC_PL_PHY_CTL_15);
+ tmp &= ~PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD_MASK;
+ /* PM clock period is 18.52ns (round down) */
+ tmp |= 0x12;
+ writel(tmp, base + PCIE_RC_PL_PHY_CTL_15);
+ }
+
+ tmp = (pcie->pcie_cfg->type == BCM2712) ?
+ MISC_CTRL_MAX_BURST_SIZE_128_2712 :
+ MISC_CTRL_MAX_BURST_SIZE_128;
/* Set SCB_MAX_BURST_SIZE, CFG_READ_UR_MODE, SCB_ACCESS_EN */
clrsetbits_le32(base + PCIE_MISC_MISC_CTRL,
MISC_CTRL_MAX_BURST_SIZE_MASK,
MISC_CTRL_SCB_ACCESS_EN_MASK |
MISC_CTRL_CFG_READ_UR_MODE_MASK |
- MISC_CTRL_MAX_BURST_SIZE_128);
+ MISC_CTRL_PCIE_RCB_MPS_MODE_MASK |
+ tmp);
- pci_get_dma_regions(dev, &region, 0);
- rc_bar2_offset = region.bus_start - region.phys_start;
- rc_bar2_size = 1ULL << fls64(region.size - 1);
+ tmp = readl(base + PCIE_MISC_MISC_CTRL);
+ if (pcie->pcie_cfg->type == BCM2712) {
+ /* BCM2712: fixed 32GB SCB0 window */
+ u32p_replace_bits(&tmp, 20, MISC_CTRL_SCB0_SIZE_MASK);
+ } else {
+ /* Pre-BCM2712: size SCB0 to match the actual DMA region.
+ * rc_bar2_size must be a power of two; ilog2(size) - 15
+ * gives the hardware encoding (e.g. 1GB -> 15). */
+ struct pci_region region;
+ u64 rc_bar2_size;
- tmp = lower_32_bits(rc_bar2_offset);
- u32p_replace_bits(&tmp, brcm_pcie_encode_ibar_size(rc_bar2_size),
- RC_BAR2_CONFIG_LO_SIZE_MASK);
- writel(tmp, base + PCIE_MISC_RC_BAR2_CONFIG_LO);
- writel(upper_32_bits(rc_bar2_offset),
- base + PCIE_MISC_RC_BAR2_CONFIG_HI);
+ pci_get_dma_regions(dev, &region, 0);
+ rc_bar2_size = brcm_ibar_round_size(region.size);
+ u32p_replace_bits(&tmp, rc_bar2_size ? ilog2(rc_bar2_size) - 15 : 0xf,
+ MISC_CTRL_SCB0_SIZE_MASK);
+ }
+ writel(tmp, base + PCIE_MISC_MISC_CTRL);
- scb_size_val = rc_bar2_size ?
- ilog2(rc_bar2_size) - 15 : 0xf; /* 0xf is 1GB */
+ if (pcie->pcie_cfg->type == BCM2712) {
+ /* Suppress AXI error responses and return 1s for read failures */
+ tmp = readl(base + PCIE_MISC_UBUS_CTRL);
+ u32p_replace_bits(&tmp, 1, PCIE_MISC_UBUS_CTRL_UBUS_PCIE_REPLY_ERR_DIS_MASK);
+ u32p_replace_bits(&tmp, 1, PCIE_MISC_UBUS_CTRL_UBUS_PCIE_REPLY_DECERR_DIS_MASK);
+ writel(tmp, base + PCIE_MISC_UBUS_CTRL);
+ writel(0xffffffff, base + PCIE_MISC_AXI_READ_ERROR_DATA);
- tmp = readl(base + PCIE_MISC_MISC_CTRL);
- u32p_replace_bits(&tmp, scb_size_val,
- MISC_CTRL_SCB0_SIZE_MASK);
- writel(tmp, base + PCIE_MISC_MISC_CTRL);
+ /*
+ * Adjust timeouts. The UBUS timeout also affects CRS
+ * completion retries, as the request will get terminated if
+ * either timeout expires, so both have to be a large value
+ * (in clocks of 750MHz).
+ * Set UBUS timeout to 250ms, then set RC config retry timeout
+ * to be ~240ms.
+ *
+ * Setting CRSVis=1 will stop the core from blocking on a CRS
+ * response, but does require the device to be well-behaved...
+ */
+ writel(0xB2D0000, base + PCIE_MISC_UBUS_TIMEOUT);
+ writel(0xABA0000, base + PCIE_MISC_RC_CONFIG_RETRY_TIMEOUT);
+ }
/* Disable the PCIe->GISB memory window (RC_BAR1) */
clrbits_le32(base + PCIE_MISC_RC_BAR1_CONFIG_LO,
@@ -422,12 +701,13 @@ static int brcm_pcie_probe(struct udevice *dev)
/* Clear any interrupts we find on boot */
writel(0xffffffff, base + PCIE_MSI_INTR2_CLR);
+ brcm_pcie_set_inbound_windows(dev);
+
if (pcie->gen)
brcm_pcie_set_gen(pcie, pcie->gen);
/* Unassert the fundamental reset */
- clrbits_le32(pcie->base + PCIE_RGR1_SW_INIT_1,
- PCIE_RGR1_SW_INIT_1_PERST_MASK);
+ pcie->pcie_cfg->perst_set(pcie, 0);
/*
* Wait for 100ms after PERST# deassertion; see PCIe CEM specification
@@ -514,14 +794,25 @@ static int brcm_pcie_remove(struct udevice *dev)
void __iomem *base = pcie->base;
/* Assert fundamental reset */
- setbits_le32(base + PCIE_RGR1_SW_INIT_1, PCIE_RGR1_SW_INIT_1_PERST_MASK);
+ setbits_le32(base + pcie->pcie_cfg->offsets[RGR1_SW_INIT_1],
+ PCIE_RGR1_SW_INIT_1_PERST_MASK);
/* Turn off SerDes */
- setbits_le32(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG,
+ setbits_le32(base + pcie->pcie_cfg->offsets[PCIE_HARD_DEBUG],
PCIE_HARD_DEBUG_SERDES_IDDQ_MASK);
/* Shutdown bridge */
- setbits_le32(base + PCIE_RGR1_SW_INIT_1, PCIE_RGR1_SW_INIT_1_INIT_MASK);
+ brcm_pcie_bridge_sw_init_set(pcie, 1);
+
+ /*
+ * For the controllers that are utilizing reset for bridge Sw init,
+ * such as BCM2712, reset should be deasserted after assertion.
+ * Leaving it in asserted state may lead to unexpected hangs in
+ * the Linux Kernel driver because it do not perform reset initialization
+ * and start accessing device memory.
+ */
+ if (pcie->pcie_cfg->type == BCM2712)
+ brcm_pcie_bridge_sw_init_set(pcie, 0);
return 0;
}
@@ -546,6 +837,11 @@ static int brcm_pcie_of_to_plat(struct udevice *dev)
else
pcie->gen = max_link_speed;
+ pcie->pcie_cfg = (const struct brcm_pcie_cfg_data *)dev_get_driver_data(dev);
+
+ if (pcie->pcie_cfg->type == BCM2712)
+ return brcm_pcie_get_resets_dt(dev);
+
return 0;
}
@@ -554,8 +850,31 @@ static const struct dm_pci_ops brcm_pcie_ops = {
.write_config = brcm_pcie_write_config,
};
+static const int pcie_offsets[] = {
+ [RGR1_SW_INIT_1] = 0x9210,
+ [PCIE_HARD_DEBUG] = 0x4204,
+};
+
+static const struct brcm_pcie_cfg_data bcm2711_cfg = {
+ .offsets = pcie_offsets,
+ .type = BCM2711,
+ .perst_set = brcm_pcie_perst_set_generic,
+};
+
+static const int pcie_offsets_bcm2712[] = {
+ [RGR1_SW_INIT_1] = 0x0,
+ [PCIE_HARD_DEBUG] = 0x4304,
+};
+
+static const struct brcm_pcie_cfg_data bcm2712_cfg = {
+ .offsets = pcie_offsets_bcm2712,
+ .type = BCM2712,
+ .perst_set = brcm_pcie_perst_set_2712,
+};
+
static const struct udevice_id brcm_pcie_ids[] = {
- { .compatible = "brcm,bcm2711-pcie" },
+ { .compatible = "brcm,bcm2711-pcie", .data = (ulong)&bcm2711_cfg },
+ { .compatible = "brcm,bcm2712-pcie", .data = (ulong)&bcm2712_cfg },
{ }
};
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index ebf484d9df4..485f907b041 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -64,6 +64,22 @@ config RESET_BCM6345
help
Support reset controller on BCM6345.
+config RESET_BRCMSTB
+ depends on ARCH_BCM283X
+ bool "Generic Reset controller driver for Broadcom"
+ help
+ This enables reset controller for Broadcom devices.
+ If you wish to use reset resources managed by the Broadcom
+ Reset Controller, say Y here. Otherwise, say N.
+
+config RESET_BRCMSTB_RESCAL
+ depends on ARCH_BCM283X
+ bool "Generic Rescal Reset controller driver for Broadcom"
+ help
+ Support rescal reset controller on Broadcom.
+ If you wish to use reset resources managed by the Broadcom
+ Reset Controller, say Y here. Otherwise, say N.
+
config RESET_UNIPHIER
bool "Reset controller driver for UniPhier SoCs"
depends on ARCH_UNIPHIER
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 088545c6473..c369bdb3d6c 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -13,6 +13,8 @@ obj-$(CONFIG_RESET_AIROHA) += reset-airoha.o
obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o
obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o
+obj-$(CONFIG_RESET_BRCMSTB) += reset-brcmstb.o
+obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o
obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
obj-$(CONFIG_RESET_AST2500) += reset-ast2500.o
obj-$(CONFIG_RESET_AST2600) += reset-ast2600.o
diff --git a/drivers/reset/reset-brcmstb-rescal.c b/drivers/reset/reset-brcmstb-rescal.c
new file mode 100644
index 00000000000..fc8fcfa8b3f
--- /dev/null
+++ b/drivers/reset/reset-brcmstb-rescal.c
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Broadcom STB generic reset controller
+ *
+ * Copyright (C) 2024 EPAM Systems
+ * Moved from linux kernel:
+ * Copyright (C) 2018-2020 Broadcom
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <errno.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/iopoll.h>
+#include <log.h>
+#include <malloc.h>
+#include <reset-uclass.h>
+
+#define BRCM_RESCAL_START 0x0
+#define BRCM_RESCAL_START_BIT BIT(0)
+#define BRCM_RESCAL_CTRL 0x4
+#define BRCM_RESCAL_STATUS 0x8
+#define BRCM_RESCAL_STATUS_BIT BIT(0)
+
+struct brcm_rescal_reset {
+ void __iomem *base;
+};
+
+/* Also doubles a deassert */
+static int brcm_rescal_reset_set(struct reset_ctl *rst)
+{
+ struct brcm_rescal_reset *data = dev_get_priv(rst->dev);
+ void __iomem *base = data->base;
+ u32 reg;
+ int ret;
+
+ reg = readl(base + BRCM_RESCAL_START);
+ writel(reg | BRCM_RESCAL_START_BIT, base + BRCM_RESCAL_START);
+ reg = readl(base + BRCM_RESCAL_START);
+ if (!(reg & BRCM_RESCAL_START_BIT)) {
+ dev_err(rst->dev, "failed to start SATA/PCIe rescal\n");
+ return -EIO;
+ }
+
+ ret = readl_poll_timeout(base + BRCM_RESCAL_STATUS, reg,
+ (reg & BRCM_RESCAL_STATUS_BIT), 100);
+ if (ret) {
+ dev_err(rst->dev, "time out on SATA/PCIe rescal\n");
+ return ret;
+ }
+
+ reg = readl(base + BRCM_RESCAL_START);
+ writel(reg & ~BRCM_RESCAL_START_BIT, base + BRCM_RESCAL_START);
+
+ dev_dbg(rst->dev, "SATA/PCIe rescal success\n");
+ return 0;
+}
+
+/* A dummy function - deassert/reset does all the work */
+static int brcm_rescal_reset_assert(struct reset_ctl *rst)
+{
+ return 0;
+}
+
+static int brcm_rescal_reset_xlate(struct reset_ctl *reset_ctl,
+ struct ofnode_phandle_args *args)
+{
+ /* This is needed if #reset-cells == 0. */
+ return 0;
+}
+
+static const struct reset_ops brcm_rescal_reset_ops = {
+ .rst_deassert = brcm_rescal_reset_set,
+ .rst_assert = brcm_rescal_reset_assert,
+ .of_xlate = brcm_rescal_reset_xlate,
+};
+
+static int brcm_rescal_reset_probe(struct udevice *dev)
+{
+ struct brcm_rescal_reset *data = dev_get_priv(dev);
+
+ data->base = dev_remap_addr(dev);
+ if (!data->base)
+ return -EINVAL;
+
+ return 0;
+}
+
+static const struct udevice_id brcm_rescal_reset_of_match[] = {
+ {.compatible = "brcm,bcm7216-pcie-sata-rescal"},
+ {},
+};
+
+U_BOOT_DRIVER(brcmstb_reset_rescal) = {
+ .name = "brcmstb-reset-rescal",
+ .id = UCLASS_RESET,
+ .of_match = brcm_rescal_reset_of_match,
+ .ops = &brcm_rescal_reset_ops,
+ .probe = brcm_rescal_reset_probe,
+ .priv_auto = sizeof(struct brcm_rescal_reset),
+};
diff --git a/drivers/reset/reset-brcmstb.c b/drivers/reset/reset-brcmstb.c
new file mode 100644
index 00000000000..7861f7c9baf
--- /dev/null
+++ b/drivers/reset/reset-brcmstb.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Broadcom STB generic reset controller
+ *
+ * Copyright (C) 2024 EPAM Systems
+ *
+ * Moved from linux kernel:
+ * Author: Florian Fainelli <[email protected]>
+ * Copyright (C) 2018 Broadcom
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <errno.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <log.h>
+#include <malloc.h>
+#include <reset-uclass.h>
+
+struct brcmstb_reset {
+ void __iomem *base;
+};
+
+#define SW_INIT_SET 0x00
+#define SW_INIT_CLEAR 0x04
+#define SW_INIT_STATUS 0x08
+
+#define SW_INIT_BIT(id) BIT((id) & 0x1f)
+#define SW_INIT_BANK(id) ((id) >> 5)
+
+#define usleep_range(a, b) udelay((b))
+
+/* A full bank contains extra registers that we are not utilizing but still
+ * qualify as a single bank.
+ */
+#define SW_INIT_BANK_SIZE 0x18
+
+static int brcmstb_reset_assert(struct reset_ctl *rst)
+{
+ unsigned int off = SW_INIT_BANK(rst->id) * SW_INIT_BANK_SIZE;
+ struct brcmstb_reset *priv = dev_get_priv(rst->dev);
+
+ writel_relaxed(SW_INIT_BIT(rst->id), priv->base + off + SW_INIT_SET);
+ return 0;
+}
+
+static int brcmstb_reset_deassert(struct reset_ctl *rst)
+{
+ unsigned int off = SW_INIT_BANK(rst->id) * SW_INIT_BANK_SIZE;
+ struct brcmstb_reset *priv = dev_get_priv(rst->dev);
+
+ writel_relaxed(SW_INIT_BIT(rst->id), priv->base + off + SW_INIT_CLEAR);
+ /* Maximum reset delay after de-asserting a line and seeing block
+ * operation is typically 14us for the worst case, build some slack
+ * here.
+ */
+ usleep_range(100, 200);
+ return 0;
+}
+
+static int brcmstb_reset_status(struct reset_ctl *rst)
+{
+ unsigned int off = SW_INIT_BANK(rst->id) * SW_INIT_BANK_SIZE;
+ struct brcmstb_reset *priv = dev_get_priv(rst->dev);
+
+ return readl_relaxed(priv->base + off + SW_INIT_STATUS) &
+ SW_INIT_BIT(rst->id);
+}
+
+struct reset_ops brcmstb_reset_reset_ops = {
+ .rst_assert = brcmstb_reset_assert,
+ .rst_deassert = brcmstb_reset_deassert,
+ .rst_status = brcmstb_reset_status};
+
+static int brcmstb_reset_probe(struct udevice *dev)
+{
+ struct brcmstb_reset *priv = dev_get_priv(dev);
+
+ priv->base = dev_remap_addr(dev);
+ if (!priv->base)
+ return -EINVAL;
+
+ return 0;
+}
+
+static const struct udevice_id brcmstb_reset_ids[] = {
+ {.compatible = "brcm,brcmstb-reset"}, {/* sentinel */}};
+
+U_BOOT_DRIVER(brcmstb_reset) = {
+ .name = "brcmstb-reset",
+ .id = UCLASS_RESET,
+ .of_match = brcmstb_reset_ids,
+ .ops = &brcmstb_reset_reset_ops,
+ .probe = brcmstb_reset_probe,
+ .priv_auto = sizeof(struct brcmstb_reset),
+};
diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c
index 12dc61aee9d..c294a56b3c9 100644
--- a/drivers/usb/host/xhci-mvebu.c
+++ b/drivers/usb/host/xhci-mvebu.c
@@ -82,6 +82,7 @@ static int xhci_usb_of_to_plat(struct udevice *dev)
static const struct udevice_id xhci_usb_ids[] = {
{ .compatible = "marvell,armada3700-xhci" },
+ { .compatible = "marvell,armada-375-xhci" },
{ .compatible = "marvell,armada-380-xhci" },
{ .compatible = "marvell,armada-8k-xhci" },
{ }
diff --git a/drivers/video/bcm2835.c b/drivers/video/bcm2835.c
index 0c81e606622..0e0cc1979eb 100644
--- a/drivers/video/bcm2835.c
+++ b/drivers/video/bcm2835.c
@@ -66,6 +66,7 @@ static int bcm2835_video_probe(struct udevice *dev)
static const struct udevice_id bcm2835_video_ids[] = {
{ .compatible = "brcm,bcm2835-hdmi" },
{ .compatible = "brcm,bcm2711-hdmi0" },
+ { .compatible = "brcm,bcm2712-hdmi0" },
{ .compatible = "brcm,bcm2708-fb" },
#if !IS_ENABLED(CONFIG_VIDEO_DT_SIMPLEFB)
{ .compatible = "simple-framebuffer" },
diff --git a/include/configs/geist.h b/include/configs/geist.h
new file mode 100644
index 00000000000..3f7e2e913ed
--- /dev/null
+++ b/include/configs/geist.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * This file is Geist board configuration.
+ *
+ * Copyright (C) 2025-2026 Renesas Electronics Corporation
+ */
+
+#ifndef __GEIST_H
+#define __GEIST_H
+
+#include "rcar-gen3-common.h"
+
+/* Environment in eMMC, at the end of 2nd "boot sector" */
+
+#define CFG_SYS_FLASH_BANKS_LIST { 0x08000000 }
+#define CFG_SYS_WRITE_SWAPPED_DATA
+
+#endif /* __GEIST_H */
diff --git a/include/configs/stm32mp15_st_common.h b/include/configs/stm32mp15_st_common.h
index 60838cb0e3f..7727e583fc7 100644
--- a/include/configs/stm32mp15_st_common.h
+++ b/include/configs/stm32mp15_st_common.h
@@ -8,7 +8,22 @@
#ifndef __CONFIG_STM32MP15_ST_COMMON_H__
#define __CONFIG_STM32MP15_ST_COMMON_H__
+#ifdef CONFIG_FWU_MULTI_BANK_UPDATE
+#define SCAN_DEV_FOR_BOOT_PARTS \
+ "setenv devplist; " \
+ "env exists boot_partuuid && " \
+ "part number ${devtype} ${devnum} ${boot_partuuid} devplist; " \
+ "env exists devplist || " \
+ "part list ${devtype} ${devnum} -bootable devplist; "
+
+#define ST_STM32MP15_FWU_ENV \
+ "altbootcmd=${bootcmd}\0"
+#else
+#define ST_STM32MP15_FWU_ENV
+#endif
+
#define STM32MP_BOARD_EXTRA_ENV \
+ ST_STM32MP15_FWU_ENV \
"usb_pgood_delay=2000\0" \
"console=ttySTM0\0" \
"splashimage=" __stringify(CONFIG_SYS_LOAD_ADDR) "\0" \
diff --git a/lib/Kconfig b/lib/Kconfig
index 77ebc79e1db..cf13ac1bdad 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -1295,6 +1295,15 @@ config SPL_LMB_ARCH_MEM_MAP
memory map. Enable this config in such scenarios which allow
architectures and boards to define their own memory map.
+config LMB_LIMIT_DMA_BELOW_RAM_TOP
+ bool
+ depends on LMB
+ default y if ARCH_BCM283X
+ help
+ Some architectures can not DMA above ram_top boundary,
+ which is after 4 GiB or 32-bit boundary too. Limit the
+ available memory to memory below ram_top boundary.
+
config PHANDLE_CHECK_SEQ
bool "Enable phandle check while getting sequence number"
help
diff --git a/lib/lmb.c b/lib/lmb.c
index 8f12c6ad8e5..275d105c5aa 100644
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -611,6 +611,7 @@ static __maybe_unused void lmb_reserve_common_spl(void)
static void lmb_add_memory(void)
{
int i;
+ phys_addr_t bank_end;
phys_size_t size;
u64 ram_top = gd->ram_top;
struct bd_info *bd = gd->bd;
@@ -625,8 +626,25 @@ static void lmb_add_memory(void)
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
size = bd->bi_dram[i].size;
- if (size)
+ if (size) {
lmb_add(bd->bi_dram[i].start, size);
+ if (!IS_ENABLED(CONFIG_LMB_LIMIT_DMA_BELOW_RAM_TOP))
+ continue;
+
+ bank_end = bd->bi_dram[i].start + size;
+
+ /*
+ * Reserve memory above ram_top as
+ * no-overwrite so that it cannot be
+ * allocated
+ */
+ if (bd->bi_dram[i].start >= ram_top)
+ lmb_reserve(bd->bi_dram[i].start, size,
+ LMB_NOOVERWRITE);
+ else if (bank_end > ram_top)
+ lmb_reserve(ram_top, bank_end - ram_top,
+ LMB_NOOVERWRITE);
+ }
}
}
diff --git a/lib/smbios.c b/lib/smbios.c
index 906d2753517..afde6401ae5 100644
--- a/lib/smbios.c
+++ b/lib/smbios.c
@@ -679,7 +679,7 @@ static int smbios_write_type3(ulong *current, int *handle,
t->serial_number = smbios_add_prop_si(ctx, "serial",
SYSID_SM_ENCLOSURE_SERIAL, NULL);
t->asset_tag_number = smbios_add_prop_si(ctx, "asset-tag",
- SYSID_SM_BASEBOARD_ASSET_TAG,
+ SYSID_SM_ENCLOSURE_ASSET_TAG,
NULL);
t->oem_defined = smbios_get_val_si(ctx, "oem-defined",
SYSID_SM_ENCLOSURE_OEM, 0);
diff --git a/net/bootp.c b/net/bootp.c
index 8976936b184..f0dc329d6e4 100644
--- a/net/bootp.c
+++ b/net/bootp.c
@@ -997,13 +997,13 @@ static void dhcp_packet_process_options(struct bootp_hdr *bp)
}
}
-static int dhcp_message_type(unsigned char *popt)
+static int dhcp_message_type(unsigned char *popt, unsigned char *end)
{
if (net_read_u32((u32 *)popt) != htonl(BOOTP_VENDOR_MAGIC))
return -1;
popt += 4;
- while (*popt != 0xff) {
+ while (popt < end && *popt != 0xff) {
if (*popt == 53) /* DHCP Message Type */
return *(popt + 2);
if (*popt == 0) {
@@ -1120,7 +1120,7 @@ static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
strlen(CONFIG_SYS_BOOTFILE_PREFIX)) == 0) {
#endif /* CONFIG_SYS_BOOTFILE_PREFIX */
if (CONFIG_IS_ENABLED(UNIT_TEST) &&
- dhcp_message_type((u8 *)bp->bp_vend) == -1) {
+ dhcp_message_type((u8 *)bp->bp_vend, (u8 *)pkt + len) == -1) {
debug("got BOOTP response; transitioning to BOUND\n");
goto dhcp_got_bootp;
}
@@ -1149,7 +1149,7 @@ static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
case REQUESTING:
debug("DHCP State: REQUESTING\n");
- if (dhcp_message_type((u8 *)bp->bp_vend) == DHCP_ACK) {
+ if (dhcp_message_type((u8 *)bp->bp_vend, (u8 *)pkt + len) == DHCP_ACK) {
dhcp_got_bootp:
dhcp_packet_process_options(bp);
/* Store net params from reply */
diff --git a/net/dhcpv6.c b/net/dhcpv6.c
index 5bf935cb6a3..640f089a2e1 100644
--- a/net/dhcpv6.c
+++ b/net/dhcpv6.c
@@ -339,6 +339,11 @@ static void dhcp6_parse_options(uchar *rx_pkt, unsigned int len)
break;
case DHCP6_OPTION_IA_TA:
case DHCP6_OPTION_IA_NA:
+ if (option_len < sizeof(u32)) {
+ debug("Invalid IA_NA/IA_TA option length\n");
+ break;
+ }
+
/* check the IA_ID */
if (*((u32 *)option_ptr) != htonl(sm_params.ia_id)) {
debug("IA_ID mismatch 0x%08x 0x%08x\n",
@@ -347,6 +352,10 @@ static void dhcp6_parse_options(uchar *rx_pkt, unsigned int len)
}
if (ntohs(option_hdr->option_id) == DHCP6_OPTION_IA_NA) {
+ if (option_len < 3 * sizeof(u32)) {
+ debug("Invalid IA_NA option length\n");
+ break;
+ }
/* skip past IA_ID/T1/T2 */
option_ptr += 3 * sizeof(u32);
} else if (ntohs(option_hdr->option_id) == DHCP6_OPTION_IA_TA) {
@@ -358,12 +367,20 @@ static void dhcp6_parse_options(uchar *rx_pkt, unsigned int len)
break;
case DHCP6_OPTION_STATUS_CODE:
debug("DHCP6_OPTION_STATUS_CODE FOUND\n");
+ if (option_len < sizeof(u16)) {
+ debug("Invalid status code option length\n");
+ break;
+ }
sm_params.rx_status.status_code = ntohs(*((u16 *)option_ptr));
debug("DHCP6 top-level status code %d\n", sm_params.rx_status.status_code);
debug("DHCP6 status message: %.*s\n", len, option_ptr + 2);
break;
case DHCP6_OPTION_SOL_MAX_RT:
debug("DHCP6_OPTION_SOL_MAX_RT FOUND\n");
+ if (option_len != sizeof(u32)) {
+ debug("Invalid SOL_MAX_RT option length\n");
+ break;
+ }
sol_max_rt_sec = ntohl(*((u32 *)option_ptr));
/* A DHCP client MUST ignore any SOL_MAX_RT option values that are less
@@ -377,6 +394,11 @@ static void dhcp6_parse_options(uchar *rx_pkt, unsigned int len)
break;
case DHCP6_OPTION_OPT_BOOTFILE_URL:
debug("DHCP6_OPTION_OPT_BOOTFILE_URL FOUND\n");
+ if (option_len >= sizeof(net_boot_file_name)) {
+ debug("Option length for BOOTFILE_URL is greater or equal than %zu. Skipping\n",
+ sizeof(net_boot_file_name));
+ break;
+ }
copy_filename(net_boot_file_name, option_ptr, option_len + 1);
debug("net_boot_file_name: %s\n", net_boot_file_name);
@@ -389,6 +411,12 @@ static void dhcp6_parse_options(uchar *rx_pkt, unsigned int len)
case DHCP6_OPTION_OPT_BOOTFILE_PARAM:
if (IS_ENABLED(CONFIG_DHCP6_PXE_DHCP_OPTION)) {
debug("DHCP6_OPTION_OPT_BOOTFILE_PARAM FOUND\n");
+
+ if (option_len < sizeof(u16)) {
+ debug("Invalid BOOTFILE_PARAM option length\n");
+ break;
+ }
+
/* if CONFIG_DHCP6_PXE_DHCP_OPTION is set the PXE config file path
* is contained in the first OPT_BOOTFILE_PARAM argument
*/
@@ -414,6 +442,10 @@ static void dhcp6_parse_options(uchar *rx_pkt, unsigned int len)
break;
case DHCP6_OPTION_PREFERENCE:
debug("DHCP6_OPTION_PREFERENCE FOUND\n");
+ if (option_len != 1) {
+ debug("Invalid preference option length\n");
+ break;
+ }
sm_params.rx_status.preference = *option_ptr;
break;
default:
diff --git a/net/sntp.c b/net/sntp.c
index 77cee0046bd..4b3dc675bab 100644
--- a/net/sntp.c
+++ b/net/sntp.c
@@ -64,6 +64,9 @@ static void sntp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
if (dest != sntp_our_port)
return;
+ if (len < SNTP_PACKET_LEN)
+ return;
+
/*
* As the RTC's used in U-Boot support second resolution only
* we simply ignore the sub-second field.
diff --git a/test/py/tests/fs_helper.py b/test/py/tests/fs_helper.py
index ee779474ce6..e3824b2c1fd 100644
--- a/test/py/tests/fs_helper.py
+++ b/test/py/tests/fs_helper.py
@@ -87,7 +87,7 @@ class FsHelper:
"""Remove created image"""
if self.tmpdir:
self.tmpdir.cleanup()
- if self._do_cleanup:
+ if self._do_cleanup and self.fs_img:
os.remove(self.fs_img)
def __enter__(self):
diff --git a/tools/binman/etype/nxp_imx8mimage.py b/tools/binman/etype/nxp_imx8mimage.py
index 8ad177b3b65..25c43438a87 100644
--- a/tools/binman/etype/nxp_imx8mimage.py
+++ b/tools/binman/etype/nxp_imx8mimage.py
@@ -7,6 +7,8 @@
# configuration file and input data.
#
+import os
+
from collections import OrderedDict
from binman.entry import Entry
@@ -23,6 +25,8 @@ class Entry_nxp_imx8mimage(Entry_mkimage):
- nxp,boot-from - device to boot from (e.g. 'sd')
- nxp,loader-address - loader address (SPL text base)
- nxp,rom-version - BootROM version ('2' for i.MX8M Nano and Plus)
+ - nxp,fspi-header-filename - FSPI header file name (CONFIG_FSPI_CONF_FILE).
+ Used only if 'nxp,boot-from == "fspi"' .
"""
def __init__(self, section, etype, node):
@@ -33,6 +37,7 @@ class Entry_nxp_imx8mimage(Entry_mkimage):
def ReadNode(self):
super().ReadNode()
self.boot_from = fdt_util.GetString(self._node, 'nxp,boot-from')
+ self.fspi_header = fdt_util.GetString(self._node, 'nxp,fspi-header-filename', 'fspi_header.bin')
self.loader_address = fdt_util.GetInt(self._node, 'nxp,loader-address')
self.rom_version = fdt_util.GetInt(self._node, 'nxp,rom-version')
self.ReadEntries()
@@ -52,7 +57,14 @@ class Entry_nxp_imx8mimage(Entry_mkimage):
args = ['-d', input_fname, '-n', cfg_fname, '-T', 'imx8mimage',
output_fname]
if self.mkimage.run_cmd(*args) is not None:
- return tools.read_file(output_fname)
+ outdata = tools.read_file(output_fname)
+ if self.boot_from == 'fspi':
+ spidata = tools.read_file(os.path.join(tools.get_output_dir(), self.fspi_header))
+ if len(spidata) != 448:
+ raise ValueError("FSPI header is not 448 Bytes long")
+ spidata += tools.get_bytes(0, 0x1000 - len(spidata))
+ outdata = spidata + outdata
+ return outdata
else:
# Bintool is missing; just use the input data as the output
self.record_missing_bintool(self.mkimage)
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 9a3811c1732..bf98b268ac1 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -8099,6 +8099,20 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
result = cst.fetch(bintool.FETCH_BUILD)
self.assertEqual(('cst', None), result)
+ def testNxpImx8MFSPI(self):
+ """Test that binman can produce an iMX8m FSPI image"""
+ testdir = tempfile.mkdtemp(prefix='binman.')
+
+ tools.write_file(os.path.join(testdir, 'fspi_header.bin'), tools.get_bytes(0, 448))
+ with terminal.capture():
+ self._DoTestFile('vendor/nxp_imx8m_fspi.dts', output_dir=testdir)
+ self._DoTestFile('vendor/nxp_imx8m_fspi_pass.dts', output_dir=testdir)
+
+ tools.write_file(os.path.join(testdir, 'fspi_header_fail.bin'), tools.get_bytes(0, 4097))
+ with terminal.capture():
+ with self.assertRaises(ValueError) as e:
+ self._DoTestFile('vendor/nxp_imx8m_fspi_fail.dts', output_dir=testdir)
+
def testNxpHeaderDdrfw(self):
"""Test that binman can add a header to DDR PHY firmware images"""
data = self._DoReadFile('vendor/nxp_ddrfw_imx95.dts')
diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi.dts b/tools/binman/test/vendor/nxp_imx8m_fspi.dts
new file mode 100644
index 00000000000..ae6cc5981e6
--- /dev/null
+++ b/tools/binman/test/vendor/nxp_imx8m_fspi.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ nxp-imx8mimage {
+ args; /* TODO: Needed by mkimage etype superclass */
+ nxp,boot-from = "fspi";
+ nxp,fspi-header-filename = "fspi_header.bin";
+ nxp,rom-version = <1>;
+ nxp,loader-address = <0x10>;
+ };
+ };
+};
diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail.dts
new file mode 100644
index 00000000000..5a0d758e5a3
--- /dev/null
+++ b/tools/binman/test/vendor/nxp_imx8m_fspi_fail.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ nxp-imx8mimage {
+ args; /* TODO: Needed by mkimage etype superclass */
+ nxp,boot-from = "fspi";
+ nxp,fspi-header-filename = "fspi_header_fail.bin";
+ nxp,rom-version = <2>;
+ nxp,loader-address = <0x10>;
+ };
+ };
+};
diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts
new file mode 100644
index 00000000000..448d93d277a
--- /dev/null
+++ b/tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ nxp-imx8mimage {
+ args; /* TODO: Needed by mkimage etype superclass */
+ nxp,boot-from = "fspi";
+ /* Default nxp,fspi-header-filename = "fspi_header.bin"; */
+ nxp,rom-version = <2>;
+ nxp,loader-address = <0x10>;
+ };
+ };
+};
diff --git a/tools/imx8image.c b/tools/imx8image.c
index 84f46bcaf37..bb1b8667971 100644
--- a/tools/imx8image.c
+++ b/tools/imx8image.c
@@ -80,7 +80,7 @@ static table_entry_t imx8image_core_entries[] = {
static table_entry_t imx8image_sector_size[] = {
{0x400, "sd", "sd/emmc",},
{0x400, "emmc_fastboot", "emmc fastboot",},
- {0x400, "fspi", "flexspi", },
+ {0x1000, "fspi", "flexspi", },
{0x1000, "nand_4k", "nand 4K", },
{0x2000, "nand_8k", "nand 8K", },
{0x4000, "nand_16k", "nand 16K", },