diff options
| author | Tom Rini <[email protected]> | 2026-06-08 15:28:18 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2026-06-08 15:28:18 -0600 |
| commit | e91911169bc737ee4a79963a1cba8db2aab7c1c0 (patch) | |
| tree | 77bdc64834398b00a211c1ceedfb87e39a1631b0 | |
| parent | 5d4d6e331d3f056ecc7ab11b72098a3cf4fdb099 (diff) | |
| parent | 1296a428c67cf103eca482d4a63349661c1b799f (diff) | |
Merge tag 'v2026.07-rc4' into next
Prepare v2026.07-rc4
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" @@ -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 = <®_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 = <®_3p3v>; + vqmmc-supply = <®_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, ®ion, 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, ®ion, 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, ®ion, 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", }, |
