summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.mailmap4
-rw-r--r--MAINTAINERS7
-rw-r--r--Makefile11
-rw-r--r--arch/arm/config.mk10
-rw-r--r--arch/arm/dts/Makefile7
-rw-r--r--arch/arm/dts/imx8ulp-evk-u-boot.dtsi12
-rw-r--r--arch/arm/dts/imx8ulp-evk.dts4
-rw-r--r--arch/arm/dts/imx91-11x11-evk.dts2
-rw-r--r--arch/arm/dts/imx91-pinfunc.h4
-rw-r--r--arch/arm/dts/r8a779g0-white-hawk-u-boot.dtsi2
-rw-r--r--arch/arm/dts/r8a78000-ironhide-u-boot.dtsi8
-rw-r--r--arch/arm/dts/r8a78000-ironhide.dts257
-rw-r--r--arch/arm/dts/r8a78000-u-boot.dtsi139
-rw-r--r--arch/arm/dts/r8a78000.dtsi1164
-rw-r--r--arch/arm/dts/socfpga-common-u-boot.dtsi8
-rw-r--r--arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi26
-rw-r--r--arch/arm/include/asm/arch-imx9/imx91_pins.h4
-rw-r--r--arch/arm/mach-bcm283x/include/mach/gpio.h10
-rw-r--r--arch/arm/mach-exynos/Kconfig11
-rw-r--r--arch/arm/mach-k3/r5/j722s/clk-data.c12
-rw-r--r--arch/arm/mach-k3/r5/j722s/dev-data.c50
-rw-r--r--arch/arm/mach-renesas/Kconfig5
-rw-r--r--arch/arm/mach-renesas/Kconfig.641
-rw-r--r--arch/arm/mach-renesas/Kconfig.rcar526
-rw-r--r--arch/arm/mach-renesas/Makefile1
-rw-r--r--arch/arm/mach-renesas/cpu_info-rcar.c8
-rw-r--r--arch/arm/mach-renesas/cpu_info.c1
-rw-r--r--arch/arm/mach-renesas/include/mach/rcar-gen5-base.h44
-rw-r--r--arch/arm/mach-renesas/include/mach/renesas.h3
-rw-r--r--arch/arm/mach-renesas/psci-rcar64.c5
-rw-r--r--arch/arm/mach-socfpga/config.mk48
-rw-r--r--arch/arm/mach-socfpga/misc.c13
-rw-r--r--arch/arm/mach-socfpga/misc_gen5.c34
-rw-r--r--arch/sh/cpu/u-boot.lds3
-rw-r--r--board/BuR/brppt1/MAINTAINERS5
-rw-r--r--board/BuR/brppt2/MAINTAINERS3
-rw-r--r--board/BuR/brsmarc1/MAINTAINERS3
-rw-r--r--board/BuR/brxre1/MAINTAINERS2
-rw-r--r--board/BuR/zynq/MAINTAINERS2
-rw-r--r--board/armltd/integrator/MAINTAINERS2
-rw-r--r--board/armltd/vexpress64/MAINTAINERS6
-rw-r--r--board/broadcom/bcmns/MAINTAINERS2
-rw-r--r--board/raspberrypi/rpi/lowlevel_init.S3
-rw-r--r--board/raspberrypi/rpi/rpi.c33
-rw-r--r--board/renesas/MAINTAINERS2
-rw-r--r--board/renesas/common/Makefile4
-rw-r--r--board/renesas/common/gen5-common.c75
-rw-r--r--board/renesas/ironhide/Kconfig15
-rw-r--r--board/samsung/e850-96/Makefile2
-rw-r--r--board/samsung/e850-96/bootdev.c99
-rw-r--r--board/samsung/e850-96/bootdev.h23
-rw-r--r--board/samsung/e850-96/e850-96.c71
-rw-r--r--board/samsung/e850-96/fw.c76
-rw-r--r--board/samsung/e850-96/fw.h10
-rw-r--r--board/samsung/exynos-mobile/Kconfig18
-rw-r--r--board/samsung/exynos-mobile/MAINTAINERS6
-rw-r--r--board/samsung/exynos-mobile/Makefile5
-rw-r--r--board/samsung/exynos-mobile/debug-exynos7870.config7
-rw-r--r--board/samsung/exynos-mobile/exynos-mobile.c403
-rw-r--r--board/samsung/exynos-mobile/exynos-mobile.env18
-rw-r--r--board/softing/vining_fpga/socfpga.c12
-rw-r--r--board/ti/am335x/board.c2
-rw-r--r--board/ti/am62x/evm.c9
-rw-r--r--board/ti/am64x/evm.c9
-rw-r--r--board/ti/am65x/evm.c9
-rw-r--r--board/ti/common/board_detect.c2
-rw-r--r--board/ti/omap3evm/MAINTAINERS2
-rw-r--r--boot/bootmeth_rauc.c15
-rw-r--r--boot/fdt_support.c19
-rw-r--r--cmd/extension_board.c4
-rw-r--r--common/spl/Kconfig4
-rw-r--r--configs/apalis-tk1_defconfig2
-rw-r--r--configs/apalis_t30_defconfig2
-rw-r--r--configs/brcp150_defconfig2
-rw-r--r--configs/brcp170_defconfig2
-rw-r--r--configs/brcp1_1r_defconfig2
-rw-r--r--configs/brcp1_1r_switch_defconfig2
-rw-r--r--configs/brcp1_2r_defconfig2
-rw-r--r--configs/brsmarc2_defconfig2
-rw-r--r--configs/cardhu_defconfig2
-rw-r--r--configs/chagall_defconfig2
-rw-r--r--configs/colibri_imx7_defconfig2
-rw-r--r--configs/colibri_imx7_emmc_defconfig2
-rw-r--r--configs/colibri_t20_defconfig2
-rw-r--r--configs/colibri_t30_defconfig2
-rw-r--r--configs/endeavoru_defconfig2
-rw-r--r--configs/exynos-mobile_defconfig70
-rw-r--r--configs/grouper_defconfig2
-rw-r--r--configs/ideapad-yoga-11_defconfig2
-rw-r--r--configs/imx6dl_sielaff_defconfig2
-rw-r--r--configs/imx8mn_beacon_2g_defconfig2
-rw-r--r--configs/imx8mn_beacon_defconfig2
-rw-r--r--configs/imx8mn_beacon_fspi_defconfig2
-rw-r--r--configs/imx943_evk_defconfig2
-rw-r--r--configs/imx95_15x15_evk_defconfig2
-rw-r--r--configs/imxrt1050-evk_fspi_defconfig2
-rw-r--r--configs/mocha_defconfig2
-rw-r--r--configs/mot_defconfig2
-rw-r--r--configs/n1_defconfig2
-rw-r--r--configs/ouya_defconfig2
-rw-r--r--configs/p2771-0000-000_defconfig2
-rw-r--r--configs/p3450-0000_defconfig2
-rw-r--r--configs/pg_wcom_expu1_defconfig2
-rw-r--r--configs/pg_wcom_expu1_update_defconfig2
-rw-r--r--configs/pg_wcom_seli8_defconfig2
-rw-r--r--configs/pg_wcom_seli8_update_defconfig2
-rw-r--r--configs/phycore_am64x_a53_defconfig4
-rw-r--r--configs/picasso_defconfig2
-rw-r--r--configs/qc750_defconfig2
-rw-r--r--configs/r8a779g3_sparrowhawk_defconfig1
-rw-r--r--configs/r8a78000_ironhide_defconfig43
-rw-r--r--configs/renesas_rcar.config1
-rw-r--r--configs/renesas_rcar5.config23
-rw-r--r--configs/socfpga_agilex5_defconfig2
-rw-r--r--configs/socfpga_cyclone5_defconfig8
-rw-r--r--configs/socfpga_vining_fpga_defconfig13
-rw-r--r--configs/star_defconfig2
-rw-r--r--configs/surface-2_defconfig2
-rw-r--r--configs/surface-rt_defconfig2
-rw-r--r--configs/tegratab_defconfig2
-rw-r--r--configs/tf701t_defconfig2
-rw-r--r--configs/toradex-smarc-imx95_defconfig2
-rw-r--r--configs/transformer_t20_defconfig2
-rw-r--r--configs/transformer_t30_defconfig2
-rw-r--r--configs/xilinx_versal_mini_ospi_defconfig4
-rw-r--r--configs/xilinx_versal_mini_qspi_defconfig4
-rw-r--r--doc/board/samsung/exynos-mobile.rst45
-rw-r--r--doc/board/samsung/exynos-mobile/exynos7870.rst85
-rw-r--r--doc/board/samsung/index.rst1
-rw-r--r--doc/board/toradex/verdin-am62p.rst135
-rw-r--r--doc/develop/pytest/usage.rst16
-rw-r--r--doc/develop/release_cycle.rst2
-rw-r--r--doc/learn/index.rst1
-rw-r--r--doc/learn/logo.rst20
-rw-r--r--doc/sphinx/requirements.txt2
-rw-r--r--drivers/clk/clk-uclass.c6
-rw-r--r--drivers/clk/exynos/Kconfig7
-rw-r--r--drivers/clk/exynos/Makefile1
-rw-r--r--drivers/clk/exynos/clk-exynos7870.c929
-rw-r--r--drivers/clk/exynos/clk-pll.c4
-rw-r--r--drivers/clk/exynos/clk-pll.h4
-rw-r--r--drivers/clk/exynos/clk.c99
-rw-r--r--drivers/clk/exynos/clk.h53
-rw-r--r--drivers/clk/renesas/Makefile4
-rw-r--r--drivers/clk/renesas/compound-clock.c92
-rw-r--r--drivers/gpio/Kconfig8
-rw-r--r--drivers/gpio/Makefile2
-rw-r--r--drivers/gpio/s5p_gpio.c5
-rw-r--r--drivers/mailbox/Kconfig10
-rw-r--r--drivers/mailbox/Makefile1
-rw-r--r--drivers/mailbox/renesas-mfis.c59
-rw-r--r--drivers/mmc/socfpga_dw_mmc.c46
-rw-r--r--drivers/mtd/nand/raw/Kconfig1
-rw-r--r--drivers/mtd/nand/raw/atmel/pmecc.c11
-rw-r--r--drivers/mtd/nand/raw/atmel/pmecc.h1
-rw-r--r--drivers/net/dwc_eth_xgmac.c60
-rw-r--r--drivers/net/dwc_eth_xgmac.h1
-rw-r--r--drivers/net/phy/broadcom.c4
-rw-r--r--drivers/net/phy/dp83869.c5
-rw-r--r--drivers/net/ti/am65-cpsw-nuss.c4
-rw-r--r--drivers/pinctrl/broadcom/pinctrl-bcm283x.c105
-rw-r--r--drivers/pinctrl/exynos/pinctrl-exynos.c11
-rw-r--r--drivers/pinctrl/exynos/pinctrl-exynos.h1
-rw-r--r--drivers/pinctrl/exynos/pinctrl-exynos7420.c1
-rw-r--r--drivers/pinctrl/exynos/pinctrl-exynos78x0.c60
-rw-r--r--drivers/pinctrl/exynos/pinctrl-exynos850.c1
-rw-r--r--drivers/power/domain/ti-power-domain.c2
-rw-r--r--drivers/serial/serial_s5p.c1
-rw-r--r--drivers/soc/samsung/exynos-pmu.c3
-rw-r--r--drivers/spi/Kconfig15
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/cadence_xspi.c449
-rw-r--r--drivers/spi/cadence_xspi.h226
-rw-r--r--drivers/usb/host/Kconfig1
-rw-r--r--drivers/usb/host/xhci.c2
-rw-r--r--include/configs/exynos-mobile.h14
-rw-r--r--include/configs/ironhide.h11
-rw-r--r--include/configs/rcar-gen5-common.h24
-rw-r--r--include/configs/s5p4418_nanopi2.h1
-rw-r--r--include/configs/socfpga_vining_fpga.h1
-rw-r--r--include/dt-bindings/clock/r8a78000-clock-scmi.h46
-rw-r--r--include/dt-bindings/power/r8a78000-power-scmi.h25
-rw-r--r--include/dt-bindings/reset/r8a78000-reset-scmi.h33
-rw-r--r--include/env/adi/adi_boot.env2
-rw-r--r--lib/efi_loader/efi_capsule.c34
-rw-r--r--test/cmd/fdt.c9
-rw-r--r--test/dm/fdtdec.c48
-rw-r--r--test/lib/strlcat.c2
-rw-r--r--tools/binman/control.py5
-rwxr-xr-xtools/cv_bsp_generator/cv_bsp_generator.py100
-rwxr-xr-xtools/cv_bsp_generator/doc.py243
-rwxr-xr-xtools/cv_bsp_generator/emif.py424
-rwxr-xr-xtools/cv_bsp_generator/hps.py571
-rwxr-xr-xtools/cv_bsp_generator/iocsr.py203
-rwxr-xr-xtools/cv_bsp_generator/model.py114
-rwxr-xr-xtools/cv_bsp_generator/renderer.py196
-rw-r--r--tools/cv_bsp_generator/requirements.txt5
-rwxr-xr-xtools/cv_bsp_generator/streamer.py102
-rwxr-xr-xtools/cv_bsp_generator/xmlgrok.py32
-rw-r--r--tools/docker/Dockerfile1
-rw-r--r--tools/logos/u-boot_logo_with_text.svg280
201 files changed, 7933 insertions, 383 deletions
diff --git a/.mailmap b/.mailmap
index 145e9ea26e4..7b0d730b618 100644
--- a/.mailmap
+++ b/.mailmap
@@ -28,6 +28,7 @@ Anurag Kumar Vulisha <[email protected]> <anurag.kumar.vulisha@xilinx.
Appana Durga Kedareswara rao <[email protected]> <[email protected]>
+Bernhard Messerklinger <[email protected]> <[email protected]>
Bharat Kumar Gogada <[email protected]> <[email protected]>
Bharat Kumar Gogada <[email protected]> <[email protected]>
Bhargava Sreekantappa Gayathri <[email protected]> <[email protected]>
@@ -74,6 +75,7 @@ Jyotheeswar Reddy Mutthareddyvari <[email protected]> <j
Lukasz Majewski <[email protected]>
@@ -156,6 +158,8 @@ Wolfgang Denk <[email protected]> <wd@pollux.(none)>
Wolfgang Denk <[email protected]> <wdenk>
York Sun <[email protected]>
York Sun <[email protected]>
Łukasz Majewski <[email protected]>
diff --git a/MAINTAINERS b/MAINTAINERS
index 63140f4e1ac..c9853f40992 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -820,7 +820,7 @@ F: include/linux/soc/ti/
ARM U8500
M: Stephan Gerhold <[email protected]>
-R: Linus Walleij <[email protected]>
+R: Linus Walleij <[email protected]>
S: Maintained
F: arch/arm/dts/ste-*
F: arch/arm/mach-u8500/
@@ -1039,7 +1039,6 @@ F: drivers/mtd/jedec_flash.c
CLOCK
M: Lukasz Majewski <[email protected]>
-M: Sean Anderson <[email protected]>
S: Maintained
T: git https://source.denx.de/u-boot/custodians/u-boot-clk.git
F: drivers/clk/
@@ -1617,7 +1616,7 @@ F: drivers/pinctrl/pinctrl-k210.c
F: include/k210/
RISC-V T-HEAD TH1520
-M: Yao Zi <[email protected]>
+M: Yao Zi <[email protected]>
S: Maintained
F: arch/riscv/cpu/th1520/
F: drivers/clk/thead/clk-th1520-ap.c
@@ -1660,7 +1659,7 @@ F: include/scmi*
N: scmi
SEAMA
-M: Linus Walleij <[email protected]>
+M: Linus Walleij <[email protected]>
S: Maintained
F: cmd/seama.c
F: doc/usage/cmd/seama.rst
diff --git a/Makefile b/Makefile
index 375af33e5e7..571c07e0e9c 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
VERSION = 2026
PATCHLEVEL = 01
SUBLEVEL =
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc4
NAME =
# *DOCUMENTATION*
@@ -1499,6 +1499,15 @@ ifeq ($(CONFIG_POSITION_INDEPENDENT)$(CONFIG_RCAR_GEN3),yy)
OBJCOPYFLAGS_u-boot-elf.srec += --change-addresses=0x50000000
endif
+ifeq ($(CONFIG_POSITION_INDEPENDENT)$(CONFIG_RCAR_GEN5),yy)
+# The flash_writer tool and previous recovery tools
+# require the SREC load address to be 0x8e30_0000 .
+# The PIE U-Boot build sets the address to 0x0, so
+# override the address back to make u-boot-elf.srec
+# compatible with the recovery tools.
+OBJCOPYFLAGS_u-boot-elf.srec += --change-addresses=0x8e300000
+endif
+
u-boot-elf.srec: u-boot.elf FORCE
$(call if_changed,zobjcopy)
diff --git a/arch/arm/config.mk b/arch/arm/config.mk
index 73fddd50bd7..a7eff84a267 100644
--- a/arch/arm/config.mk
+++ b/arch/arm/config.mk
@@ -58,7 +58,7 @@ endif
# Only test once
ifeq ($(CONFIG_$(PHASE_)SYS_THUMB_BUILD),y)
-archprepare: checkthumb checkgcc6
+archprepare: checkthumb checkgcc10
checkthumb:
@if test "$(call cc-name)" = "gcc" -a \
@@ -69,13 +69,13 @@ checkthumb:
false; \
fi
else
-archprepare: checkgcc6
+archprepare: checkgcc10
endif
-checkgcc6:
+checkgcc10:
@if test "$(call cc-name)" = "gcc" -a \
- "$(call cc-version)" -lt "0600"; then \
- echo '*** Your GCC is older than 6.0 and is not supported'; \
+ "$(call cc-version)" -lt "1000"; then \
+ echo '*** Your GCC is older than 10.0 and is not supported'; \
false; \
fi
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 865ceb65f9a..fcad6fb2fc7 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -918,6 +918,13 @@ dtb-$(CONFIG_RZA1) += \
r7s72100-genmai.dtb \
r7s72100-gr-peach.dtb
+dtb-$(CONFIG_RCAR_GEN5) += \
+ r8a78000-ironhide.dtb
+
+ifdef CONFIG_RCAR_GEN5
+DTC_FLAGS += -R 4 -p 0x1000
+endif
+
dtb-$(CONFIG_TARGET_AT91SAM9261EK) += at91sam9261ek.dtb
dtb-$(CONFIG_TARGET_PM9261) += at91sam9261ek.dtb
diff --git a/arch/arm/dts/imx8ulp-evk-u-boot.dtsi b/arch/arm/dts/imx8ulp-evk-u-boot.dtsi
index 845fe205925..2782dc7dd75 100644
--- a/arch/arm/dts/imx8ulp-evk-u-boot.dtsi
+++ b/arch/arm/dts/imx8ulp-evk-u-boot.dtsi
@@ -10,16 +10,16 @@
compatible = "fsl,imx8ulp-mu";
reg = <0 0x27020000 0 0x10000>;
status = "okay";
- bootph-pre-ram;
+ bootph-all;
};
};
&soc {
- bootph-pre-ram;
+ bootph-all;
};
&per_bridge3 {
- bootph-pre-ram;
+ bootph-all;
};
&per_bridge4 {
@@ -27,15 +27,15 @@
};
&iomuxc1 {
- bootph-pre-ram;
+ bootph-all;
};
&pinctrl_lpuart5 {
- bootph-pre-ram;
+ bootph-all;
};
&lpuart5 {
- bootph-pre-ram;
+ bootph-all;
};
&usdhc0 {
diff --git a/arch/arm/dts/imx8ulp-evk.dts b/arch/arm/dts/imx8ulp-evk.dts
index f1c6d933a17..7aec1706382 100644
--- a/arch/arm/dts/imx8ulp-evk.dts
+++ b/arch/arm/dts/imx8ulp-evk.dts
@@ -119,3 +119,7 @@
>;
};
};
+
+&wdog3 {
+ status = "disabled";
+};
diff --git a/arch/arm/dts/imx91-11x11-evk.dts b/arch/arm/dts/imx91-11x11-evk.dts
index 65571fc223b..ca9070a4c76 100644
--- a/arch/arm/dts/imx91-11x11-evk.dts
+++ b/arch/arm/dts/imx91-11x11-evk.dts
@@ -503,7 +503,7 @@
MX91_PAD_ENET1_TD0__GPIO4_IO5 0x31e
MX91_PAD_ENET1_TD1__GPIO4_IO4 0x31e
MX91_PAD_ENET1_TD2__GPIO4_IO3 0x31e
- MX91_PAD_ENET1_TD3__GPIO4_IO3 0x31e
+ MX91_PAD_ENET1_TD3__GPIO4_IO2 0x31e
MX91_PAD_ENET1_TXC__GPIO4_IO7 0x31e
MX91_PAD_ENET1_TX_CTL__GPIO4_IO6 0x31e
>;
diff --git a/arch/arm/dts/imx91-pinfunc.h b/arch/arm/dts/imx91-pinfunc.h
index b0066df173b..5677928ab7c 100644
--- a/arch/arm/dts/imx91-pinfunc.h
+++ b/arch/arm/dts/imx91-pinfunc.h
@@ -330,7 +330,7 @@
#define MX91_PAD_ENET1_TD3__CAN2_TX 0x00a0 0x0250 0x0000 0x02 0x00
#define MX91_PAD_ENET1_TD3__HSIOMIX_OTG_ID2 0x00a0 0x0250 0x0000 0x03 0x00
#define MX91_PAD_ENET1_TD3__FLEXIO2_FLEXIO2 0x00a0 0x0250 0x0000 0x04 0x00
-#define MX91_PAD_ENET1_TD3__GPIO4_IO3 0x00a0 0x0250 0x0000 0x05 0x00
+#define MX91_PAD_ENET1_TD3__GPIO4_IO2 0x00a0 0x0250 0x0000 0x05 0x00
#define MX91_PAD_ENET1_TD3__LPI2C2_SCL 0x00a0 0x0250 0x03e8 0x06 0x00
#define MX91_PAD_ENET1_TD2__ENET_QOS_RGMII_TD2 0x00a4 0x0254 0x0000 0x00 0x00
@@ -680,7 +680,7 @@
#define MX91_PAD_I2C2_SCL__LPUART2_DCB_B 0x0178 0x0328 0x0000 0x02 0x00
#define MX91_PAD_I2C2_SCL__TPM2_CH2 0x0178 0x0328 0x0000 0x03 0x00
#define MX91_PAD_I2C2_SCL__SAI1_RX_SYNC 0x0178 0x0328 0x0000 0x04 0x00
-#define MX91_PAD_I2C2_SCL__GPIO1_IO3 0x0178 0x0328 0x0000 0x05 0x00
+#define MX91_PAD_I2C2_SCL__GPIO1_IO2 0x0178 0x0328 0x0000 0x05 0x00
#define MX91_PAD_I2C2_SCL__I3C1_PUR_B 0x0178 0x0328 0x0000 0x06 0x00
#define MX91_PAD_I2C2_SDA__LPI2C2_SDA 0x017c 0x032c 0x03ec 0x00 0x01
diff --git a/arch/arm/dts/r8a779g0-white-hawk-u-boot.dtsi b/arch/arm/dts/r8a779g0-white-hawk-u-boot.dtsi
index 8e4307ff87d..85e32208b29 100644
--- a/arch/arm/dts/r8a779g0-white-hawk-u-boot.dtsi
+++ b/arch/arm/dts/r8a779g0-white-hawk-u-boot.dtsi
@@ -23,8 +23,6 @@
&rpc {
bootph-all;
- status = "disabled";
-
flash@0 {
bootph-all;
spi-tx-bus-width = <1>;
diff --git a/arch/arm/dts/r8a78000-ironhide-u-boot.dtsi b/arch/arm/dts/r8a78000-ironhide-u-boot.dtsi
new file mode 100644
index 00000000000..9c72f3e55f4
--- /dev/null
+++ b/arch/arm/dts/r8a78000-ironhide-u-boot.dtsi
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source extras for U-Boot for the Ironhide board
+ *
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ */
+
+#include "r8a78000-u-boot.dtsi"
diff --git a/arch/arm/dts/r8a78000-ironhide.dts b/arch/arm/dts/r8a78000-ironhide.dts
new file mode 100644
index 00000000000..601f2740b54
--- /dev/null
+++ b/arch/arm/dts/r8a78000-ironhide.dts
@@ -0,0 +1,257 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the Ironhide board
+ *
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r8a78000.dtsi"
+#include <dt-bindings/net/ti-dp83869.h>
+
+/ {
+ model = "Renesas Ironhide board based on r8a78000";
+ compatible = "renesas,ironhide", "renesas,r8a78000";
+
+ aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ i2c4 = &i2c4;
+ i2c5 = &i2c5;
+ i2c6 = &i2c6;
+ i2c7 = &i2c7;
+ i2c8 = &i2c8;
+ mmc0 = &mmc0;
+ serial0 = &hscif0;
+ };
+
+ chosen {
+ stdout-path = "serial0:1843200n8";
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0x0 0x40000000 0x0 0x80000000>;
+ };
+
+ memory@1080000000 {
+ device_type = "memory";
+ reg = <0x10 0x80000000 0x0 0x80000000>;
+ };
+
+ memory@1200000000 {
+ device_type = "memory";
+ reg = <0x12 0x00000000 0x1 0x00000000>;
+ };
+
+ memory@1400000000 {
+ device_type = "memory";
+ reg = <0x14 0x00000000 0x1 0x00000000>;
+ };
+
+ memory@1600000000 {
+ device_type = "memory";
+ reg = <0x16 0x00000000 0x1 0x00000000>;
+ };
+
+ memory@1800000000 {
+ device_type = "memory";
+ reg = <0x18 0x00000000 0x1 0x00000000>;
+ };
+
+ memory@1a00000000 {
+ device_type = "memory";
+ reg = <0x1a 0x00000000 0x1 0x00000000>;
+ };
+
+ memory@1c00000000 {
+ device_type = "memory";
+ reg = <0x1c 0x00000000 0x1 0x00000000>;
+ };
+
+ memory@1e00000000 {
+ device_type = "memory";
+ reg = <0x1e 0x00000000 0x1 0x00000000>;
+ };
+
+ 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;
+ };
+};
+
+&extal_clk {
+ clock-frequency = <16666600>;
+};
+
+&extalr_clk {
+ clock-frequency = <32768>;
+};
+
+&hscif0 {
+ pinctrl-0 = <&hscif0_pins>;
+ pinctrl-names = "default";
+ uart-has-rtscts;
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+ clock-frequency = <400000>;
+ status = "okay";
+
+ eeprom@50 {
+ compatible = "rohm,br24g01", "atmel,24c01";
+ reg = <0x50>;
+ pagesize = <8>;
+ };
+};
+
+&i2c1 {
+ pinctrl-0 = <&i2c1_pins>;
+ pinctrl-names = "default";
+ clock-frequency = <400000>;
+ status = "okay";
+};
+
+&eth_pcs {
+ phys = <&mp_phy 2 1>;
+ status = "okay";
+};
+
+&mmc0 {
+ pinctrl-0 = <&mmc0_pins>;
+ pinctrl-1 = <&mmc0_pins>;
+ pinctrl-names = "default", "state_uhs";
+
+ bus-width = <8>;
+ full-pwr-cycle-in-suspend;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ no-sd;
+ no-sdio;
+ non-removable;
+
+ vmmc-supply = <&reg_3p3v>;
+ vqmmc-supply = <&reg_1p8v>;
+
+ status = "okay";
+};
+
+&ufs0 {
+ status = "okay";
+};
+
+&ufs1 {
+ status = "okay";
+};
+
+&mp_phy {
+ status = "okay";
+};
+
+&pfc {
+ pinctrl-0 = <&scif_clk_pins>;
+ pinctrl-names = "default";
+
+ eth25g2_pins: eth25g2 {
+ groups = "eth25g2_mdio", "eth25g2_link", "eth25g2_phyint";
+ function = "eth25g2";
+ drive-strength = <24>;
+ };
+
+ ethes0_pins: ethes0 {
+ groups = "ethes0_match", "ethes0_capture", "ethes0_pps";
+ function = "ethes0";
+ drive-strength = <24>;
+ };
+
+ hscif0_pins: hscif0 {
+ groups = "hscif0_data", "hscif0_ctrl";
+ function = "hscif0";
+ };
+
+ i2c0_pins: i2c0 {
+ groups = "i2c0";
+ function = "i2c0";
+ };
+
+ i2c1_pins: i2c1 {
+ groups = "i2c1";
+ function = "i2c1";
+ };
+
+ mmc0_pins: mmc0 {
+ groups = "mmc0_data8", "mmc0_ctrl", "mmc0_ds";
+ function = "mmc0";
+ drive-strength = <24>;
+ };
+
+ rsw3_pins: rsw3 {
+ groups = "rsw3_match", "rsw3_capture", "rsw3_pps";
+ function = "rsw3";
+ drive-strength = <24>;
+ };
+
+ scif_clk_pins: scif-clk {
+ groups = "scif_clk";
+ function = "scif_clk";
+ };
+};
+
+&rswitch3 {
+ pinctrl-0 = <&rsw3_pins>, <&eth25g2_pins>, <&ethes0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ ethernet-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /*
+ * NOTE: Only port@4 is configured for R-Car X5H board.
+ * Other ports (0-3, 5-12) are currently unused or not
+ * connected.
+ */
+ port@4 {
+ reg = <4>;
+ renesas,connect_to_xpcs;
+ phy-handle = <&dp83869_phy>;
+ phy-mode = "sgmii";
+ phys = <&eth_pcs 5>;
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dp83869_phy: ethernet-phy@2 {
+ reg = <2>;
+ ti,sgmii-interface;
+ ti,max-output-impedance;
+ ti,refclk-output-enable;
+ ti,clk-output-sel = <DP83869_CLK_O_SEL_REF_CLK>;
+ };
+ };
+ };
+ };
+};
+
+&scif_clk {
+ clock-frequency = <26000000>;
+};
diff --git a/arch/arm/dts/r8a78000-u-boot.dtsi b/arch/arm/dts/r8a78000-u-boot.dtsi
new file mode 100644
index 00000000000..1bc73252430
--- /dev/null
+++ b/arch/arm/dts/r8a78000-u-boot.dtsi
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source extras for U-Boot on R-Car R8A78000 SoC
+ *
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ */
+
+/ {
+ soc {
+ bootph-all;
+ };
+
+ /* Placeholder clock until the clock provider is in place */
+ clk_stub_gpio: clk-stub-gpio {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <1000000>;
+ };
+
+ clk_stub_i2c0: clk-stub-i2c0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <150000000>;
+ };
+
+ clk_stub_i2c1: clk-stub-i2c1 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <133333333>;
+ };
+
+ clk_stub_mmc: clk-stub-mmc {
+ compatible = "renesas,compound-clock";
+ #clock-cells = <0>;
+ clocks = <&scmi_clk SCP_CLOCK_ID_MDLC_SDHI0>,
+ <&scmi_clk 1691>;
+ clock-names = "mdlc", "per";
+ };
+};
+
+&cpg {
+ bootph-all;
+};
+
+&extal_clk {
+ bootph-all;
+};
+
+&extalr_clk {
+ bootph-all;
+};
+
+&gpio0 {
+ clocks = <&clk_stub_gpio>;
+};
+
+&gpio1 {
+ clocks = <&clk_stub_gpio>;
+};
+
+&gpio2 {
+ clocks = <&clk_stub_gpio>;
+};
+
+&gpio3 {
+ clocks = <&clk_stub_gpio>;
+};
+
+&gpio4 {
+ clocks = <&clk_stub_gpio>;
+};
+
+&gpio5 {
+ clocks = <&clk_stub_gpio>;
+};
+
+&gpio6 {
+ clocks = <&clk_stub_gpio>;
+};
+
+&gpio7 {
+ clocks = <&clk_stub_gpio>;
+};
+
+&gpio8 {
+ clocks = <&clk_stub_gpio>;
+};
+
+&gpio9 {
+ clocks = <&clk_stub_gpio>;
+};
+
+&gpio10 {
+ clocks = <&clk_stub_gpio>;
+};
+
+&i2c0 {
+ clocks = <&clk_stub_i2c0>;
+};
+
+&i2c1 {
+ clocks = <&clk_stub_i2c1>;
+};
+
+&i2c2 {
+ clocks = <&clk_stub_i2c1>;
+};
+
+&i2c3 {
+ clocks = <&clk_stub_i2c1>;
+};
+
+&i2c4 {
+ clocks = <&clk_stub_i2c1>;
+};
+
+&i2c5 {
+ clocks = <&clk_stub_i2c1>;
+};
+
+&i2c6 {
+ clocks = <&clk_stub_i2c1>;
+};
+
+&i2c7 {
+ clocks = <&clk_stub_i2c1>;
+};
+
+&i2c8 {
+ clocks = <&clk_stub_i2c1>;
+};
+
+&mmc0 {
+ clocks = <&clk_stub_mmc>;
+};
+
+&prr {
+ bootph-all;
+};
diff --git a/arch/arm/dts/r8a78000.dtsi b/arch/arm/dts/r8a78000.dtsi
new file mode 100644
index 00000000000..0d0c24503e2
--- /dev/null
+++ b/arch/arm/dts/r8a78000.dtsi
@@ -0,0 +1,1164 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the R-Car X5H (R8A78000) SoC
+ *
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/clock/r8a78000-clock-scmi.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/r8a78000-power-scmi.h>
+#include <dt-bindings/reset/r8a78000-reset-scmi.h>
+
+/ {
+ compatible = "renesas,r8a78000";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&gic>;
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&a720_0>;
+ };
+ core1 {
+ cpu = <&a720_1>;
+ };
+ core2 {
+ cpu = <&a720_2>;
+ };
+ core3 {
+ cpu = <&a720_3>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&a720_4>;
+ };
+ core1 {
+ cpu = <&a720_5>;
+ };
+ core2 {
+ cpu = <&a720_6>;
+ };
+ core3 {
+ cpu = <&a720_7>;
+ };
+ };
+
+ cluster2 {
+ core0 {
+ cpu = <&a720_8>;
+ };
+ core1 {
+ cpu = <&a720_9>;
+ };
+ core2 {
+ cpu = <&a720_10>;
+ };
+ core3 {
+ cpu = <&a720_11>;
+ };
+ };
+
+ cluster3 {
+ core0 {
+ cpu = <&a720_12>;
+ };
+ core1 {
+ cpu = <&a720_13>;
+ };
+ core2 {
+ cpu = <&a720_14>;
+ };
+ core3 {
+ cpu = <&a720_15>;
+ };
+ };
+
+ cluster4 {
+ core0 {
+ cpu = <&a720_16>;
+ };
+ core1 {
+ cpu = <&a720_17>;
+ };
+ core2 {
+ cpu = <&a720_18>;
+ };
+ core3 {
+ cpu = <&a720_19>;
+ };
+ };
+
+ cluster5 {
+ core0 {
+ cpu = <&a720_20>;
+ };
+ core1 {
+ cpu = <&a720_21>;
+ };
+ core2 {
+ cpu = <&a720_22>;
+ };
+ core3 {
+ cpu = <&a720_23>;
+ };
+ };
+
+ cluster6 {
+ core0 {
+ cpu = <&a720_24>;
+ };
+ core1 {
+ cpu = <&a720_25>;
+ };
+ core2 {
+ cpu = <&a720_26>;
+ };
+ core3 {
+ cpu = <&a720_27>;
+ };
+ };
+
+ cluster7 {
+ core0 {
+ cpu = <&a720_28>;
+ };
+ core1 {
+ cpu = <&a720_29>;
+ };
+ core2 {
+ cpu = <&a720_30>;
+ };
+ core3 {
+ cpu = <&a720_31>;
+ };
+ };
+ };
+
+ a720_0: cpu@0 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x0>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_0>;
+ };
+
+ a720_1: cpu@100 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x100>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_1>;
+ };
+
+ a720_2: cpu@200 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x200>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_2>;
+ };
+
+ a720_3: cpu@300 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x300>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_3>;
+ };
+
+ a720_4: cpu@10000 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x10000>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_4>;
+ };
+
+ a720_5: cpu@10100 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x10100>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_5>;
+ };
+
+ a720_6: cpu@10200 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x10200>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_6>;
+ };
+
+ a720_7: cpu@10300 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x10300>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_7>;
+ };
+
+ a720_8: cpu@20000 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x20000>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_8>;
+ };
+
+ a720_9: cpu@20100 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x20100>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_9>;
+ };
+
+ a720_10: cpu@20200 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x20200>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_10>;
+ };
+
+ a720_11: cpu@20300 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x20300>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_11>;
+ };
+
+ a720_12: cpu@30000 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x30000>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_12>;
+ };
+
+ a720_13: cpu@30100 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x30100>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_13>;
+ };
+
+ a720_14: cpu@30200 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x30200>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_14>;
+ };
+
+ a720_15: cpu@30300 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x30300>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_15>;
+ };
+
+ a720_16: cpu@40000 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x40000>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_16>;
+ };
+
+ a720_17: cpu@40100 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x40100>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_17>;
+ };
+
+ a720_18: cpu@40200 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x40200>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_18>;
+ };
+
+ a720_19: cpu@40300 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x40300>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_19>;
+ };
+
+ a720_20: cpu@50000 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x50000>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_20>;
+ };
+
+ a720_21: cpu@50100 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x50100>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_21>;
+ };
+
+ a720_22: cpu@50200 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x50200>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_22>;
+ };
+
+ a720_23: cpu@50300 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x50300>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_23>;
+ };
+
+ a720_24: cpu@60000 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x60000>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_24>;
+ };
+
+ a720_25: cpu@60100 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x60100>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_25>;
+ };
+
+ a720_26: cpu@60200 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x60200>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_26>;
+ };
+
+ a720_27: cpu@60300 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x60300>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_27>;
+ };
+
+ a720_28: cpu@70000 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x70000>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_28>;
+ };
+
+ a720_29: cpu@70100 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x70100>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_29>;
+ };
+
+ a720_30: cpu@70200 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x70200>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_30>;
+ };
+
+ a720_31: cpu@70300 {
+ compatible = "arm,cortex-a720ae";
+ reg = <0x0 0x70300>;
+ device_type = "cpu";
+ next-level-cache = <&L2_CA720_31>;
+ };
+
+ L2_CA720_0: cache-controller-200 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_0>;
+ };
+
+ L2_CA720_1: cache-controller-201 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_0>;
+ };
+
+ L2_CA720_2: cache-controller-202 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_0>;
+ };
+
+ L2_CA720_3: cache-controller-203 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_0>;
+ };
+
+ L2_CA720_4: cache-controller-204 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_1>;
+ };
+
+ L2_CA720_5: cache-controller-205 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_1>;
+ };
+
+ L2_CA720_6: cache-controller-206 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_1>;
+ };
+
+ L2_CA720_7: cache-controller-207 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_1>;
+ };
+
+ L2_CA720_8: cache-controller-208 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_2>;
+ };
+
+ L2_CA720_9: cache-controller-209 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_2>;
+ };
+
+ L2_CA720_10: cache-controller-210 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_2>;
+ };
+
+ L2_CA720_11: cache-controller-211 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_2>;
+ };
+
+ L2_CA720_12: cache-controller-212 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_3>;
+ };
+
+ L2_CA720_13: cache-controller-213 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_3>;
+ };
+
+ L2_CA720_14: cache-controller-214 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_3>;
+ };
+
+ L2_CA720_15: cache-controller-215 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_3>;
+ };
+
+ L2_CA720_16: cache-controller-216 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_4>;
+ };
+
+ L2_CA720_17: cache-controller-217 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_4>;
+ };
+
+ L2_CA720_18: cache-controller-218 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_4>;
+ };
+
+ L2_CA720_19: cache-controller-219 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_4>;
+ };
+
+ L2_CA720_20: cache-controller-220 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_5>;
+ };
+
+ L2_CA720_21: cache-controller-221 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_5>;
+ };
+
+ L2_CA720_22: cache-controller-222 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_5>;
+ };
+
+ L2_CA720_23: cache-controller-223 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_5>;
+ };
+
+ L2_CA720_24: cache-controller-224 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_6>;
+ };
+
+ L2_CA720_25: cache-controller-225 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_6>;
+ };
+
+ L2_CA720_26: cache-controller-226 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_6>;
+ };
+
+ L2_CA720_27: cache-controller-227 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_6>;
+ };
+
+ L2_CA720_28: cache-controller-228 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_7>;
+ };
+
+ L2_CA720_29: cache-controller-229 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_7>;
+ };
+
+ L2_CA720_30: cache-controller-230 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_7>;
+ };
+
+ L2_CA720_31: cache-controller-231 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <2>;
+ next-level-cache = <&L3_CA720_7>;
+ };
+
+ L3_CA720_0: cache-controller-30 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <3>;
+ };
+
+ L3_CA720_1: cache-controller-31 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <3>;
+ };
+
+ L3_CA720_2: cache-controller-32 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <3>;
+ };
+
+ L3_CA720_3: cache-controller-33 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <3>;
+ };
+
+ L3_CA720_4: cache-controller-34 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <3>;
+ };
+
+ L3_CA720_5: cache-controller-35 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <3>;
+ };
+
+ L3_CA720_6: cache-controller-36 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <3>;
+ };
+
+ L3_CA720_7: cache-controller-37 {
+ compatible = "cache";
+ cache-unified;
+ cache-level = <3>;
+ };
+ };
+
+ /*
+ * In the early phase, there is no clock control support,
+ * so assume that the clocks are enabled by default.
+ * Therefore, dummy clocks are used.
+ */
+ dummy_clk_sgasyncd16: dummy-clk-sgasyncd16 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <66666000>;
+ };
+
+ dummy_clk_sgasyncd4: dummy-clk-sgasyncd4 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <266660000>;
+ };
+
+ extal_clk: extal-clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* clock-frequency must be set on board */
+ };
+
+ extalr_clk: extalr-clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* clock-frequency must be set on board */
+ };
+
+ firmware {
+ scmi {
+ compatible = "arm,scmi";
+ arm,poll-transport;
+ mbox-names = "tx", "rx";
+ mboxes = <&mailbox 0>, <&mailbox 1>;
+ shmem = <&cpu_scp_lpri0>, <&cpu_scp_hpri0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ scmi_devpd: protocol@11 {
+ reg = <0x11>;
+ #power-domain-cells = <1>;
+ };
+
+ scmi_clk: protocol@14 {
+ reg = <0x14>;
+ #clock-cells = <1>;
+ };
+
+ scmi_reset: protocol@16 {
+ reg = <0x16>;
+ #reset-cells = <1>;
+ };
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-1.0", "arm,psci-0.2";
+ method = "smc";
+ };
+
+ /* External SCIF clock - to be overridden by boards that provide it */
+ scif_clk: scif-clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>; /* optional */
+ };
+
+ soc: soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ mailbox: mfis_mbox@18842000 {
+ compatible = "renesas,mfis-mbox";
+ #mbox-cells = <1>;
+ reg = <0 0x18842004 0 0x8>;
+ interrupts = <GIC_SPI 4362 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ prr: chipid@189e0044 {
+ compatible = "renesas,prr";
+ reg = <0 0x189e0044 0 4>;
+ };
+
+ /* Application Processors manage View-1 of a GIC-720AE */
+ gic: interrupt-controller@39000000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0 0x39000000 0 0x10000>,
+ <0 0x39080000 0 0x800000>;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pfc: pinctrl@c0400000 {
+ compatible = "renesas,pfc-r8a78000";
+ reg = <0 0xc1080000 0 0x104>, <0 0xc1080800 0 0x104>,
+ <0 0xc1081000 0 0x104>, <0 0xc0800000 0 0x104>,
+ <0 0xc0800800 0 0x104>, <0 0xc0400000 0 0x104>,
+ <0 0xc0400800 0 0x104>, <0 0xc0401000 0 0x104>,
+ <0 0xc0401800 0 0x104>, <0 0xc9b00000 0 0x104>,
+ <0 0xc9b00800 0 0x104>;
+ };
+
+ scif0: serial@c0700000 {
+ compatible = "renesas,scif-r8a78000",
+ "renesas,rcar-gen5-scif", "renesas,scif";
+ reg = <0 0xc0700000 0 0x40>;
+ interrupts = <GIC_SPI 4074 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd16>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ status = "disabled";
+ };
+
+ scif1: serial@c0704000 {
+ compatible = "renesas,scif-r8a78000",
+ "renesas,rcar-gen5-scif", "renesas,scif";
+ reg = <0 0xc0704000 0 0x40>;
+ interrupts = <GIC_SPI 4075 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd16>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ status = "okay";
+ };
+
+ scif3: serial@c0708000 {
+ compatible = "renesas,scif-r8a78000",
+ "renesas,rcar-gen5-scif", "renesas,scif";
+ reg = <0 0xc0708000 0 0x40>;
+ interrupts = <GIC_SPI 4076 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd16>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ status = "disabled";
+ };
+
+ scif4: serial@c070c000 {
+ compatible = "renesas,scif-r8a78000",
+ "renesas,rcar-gen5-scif", "renesas,scif";
+ reg = <0 0xc070c000 0 0x40>;
+ interrupts = <GIC_SPI 4077 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd16>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ status = "disabled";
+ };
+
+ mmc0: mmc@c0880000 {
+ compatible = "renesas,rcar-gen5-sdhi";
+ reg = <0 0xc0880000 0 0x2000>;
+ clock-names = "core";
+ max-frequency = <200000000>;
+ status = "disabled";
+ };
+
+ ufs0: ufs@c0a80000 {
+ compatible = "renesas,r8a78000-ufs";
+ reg = <0 0xc0a80000 0 0x1100>, <0 0xc0a00000 0 0x40000>;
+ reg-names = "hcr", "phy";
+ interrupts = <GIC_SPI 4284 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&scmi_devpd X5H_POWER_DOMAIN_ID_UFS0>;
+ clocks = <&scmi_clk SCP_CLOCK_ID_MDLC_UFS0>;
+ resets = <&scmi_reset SCP_RESET_DOMAIN_ID_UFS0>;
+ freq-table-hz = <38400000 38400000>;
+ status = "disabled";
+ };
+
+ ufs1: ufs@c0a90000 {
+ compatible = "renesas,r8a78000-ufs";
+ reg = <0 0xc0a90000 0 0x1100>, <0 0xc0a40000 0 0x40000>;
+ reg-names = "hcr", "phy";
+ interrupts = <GIC_SPI 4285 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&scmi_devpd X5H_POWER_DOMAIN_ID_UFS1>;
+ clocks = <&scmi_clk SCP_CLOCK_ID_MDLC_UFS1>;
+ resets = <&scmi_reset SCP_RESET_DOMAIN_ID_UFS1>;
+ freq-table-hz = <38400000 38400000>;
+ status = "disabled";
+ };
+
+ scp: sram@c1000000 {
+ compatible = "arm,rcar-sram-ns", "mmio-sram";
+ reg = <0x0 0xc1000000 0x0 0x80000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x0 0xc1000000 0x80000>;
+
+ cpu_scp_lpri0: scp-shmem@60000 {
+ compatible = "arm,rcar-scp-shmem", "arm,scmi-shmem";
+ reg = <0x61200 0x0100>;
+ };
+
+ cpu_scp_hpri0: scp-shmem@60300 {
+ compatible = "arm,rcar-scp-shmem", "arm,scmi-shmem";
+ reg = <0x61300 0x100>;
+ };
+ };
+
+ cpg: clock-controller@c64f0000 {
+ compatible = "renesas,r8a78000-cpg-mssr";
+ reg = <0 0xc64f0000 0 0x4000>;
+ clocks = <&extal_clk>, <&extalr_clk>;
+ clock-names = "extal", "extalr";
+ #clock-cells = <2>;
+ #power-domain-cells = <0>;
+ #reset-cells = <1>;
+ };
+
+ hscif0: serial@c0710000 {
+ compatible = "renesas,hscif-r8a78000",
+ "renesas,rcar-gen5-hscif", "renesas,hscif";
+ reg = <0 0xc0710000 0 0x60>;
+ interrupts = <GIC_SPI 4078 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&dummy_clk_sgasyncd4>, <&dummy_clk_sgasyncd4>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ status = "disabled";
+ };
+
+ hscif1: serial@c0714000 {
+ compatible = "renesas,hscif-r8a78000",
+ "renesas,rcar-gen5-hscif", "renesas,hscif";
+ reg = <0 0xc0714000 0 0x60>;
+ interrupts = <GIC_SPI 4079 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&dummy_clk_sgasyncd4>, <&dummy_clk_sgasyncd4>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ status = "disabled";
+ };
+
+ hscif2: serial@c0718000 {
+ compatible = "renesas,hscif-r8a78000",
+ "renesas,rcar-gen5-hscif", "renesas,hscif";
+ reg = <0 0xc0718000 0 0x60>;
+ interrupts = <GIC_SPI 4080 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&dummy_clk_sgasyncd4>, <&dummy_clk_sgasyncd4>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ status = "disabled";
+ };
+
+ hscif3: serial@c071c000 {
+ compatible = "renesas,hscif-r8a78000",
+ "renesas,rcar-gen5-hscif", "renesas,hscif";
+ reg = <0 0xc071c000 0 0x60>;
+ interrupts = <GIC_SPI 4081 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&dummy_clk_sgasyncd4>, <&dummy_clk_sgasyncd4>, <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ status = "disabled";
+ };
+
+ i2c0: i2c@c11d0000 {
+ compatible = "renesas,i2c-r8a78000",
+ "renesas,rcar-gen5-i2c";
+ reg = <0 0xc11d0000 0 0x40>;
+ i2c-scl-internal-delay-ns = <110>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@c06c0000 {
+ compatible = "renesas,i2c-r8a78000",
+ "renesas,rcar-gen5-i2c";
+ reg = <0 0xc06c0000 0 0x40>;
+ i2c-scl-internal-delay-ns = <110>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@c06c8000 {
+ compatible = "renesas,i2c-r8a78000",
+ "renesas,rcar-gen5-i2c";
+ reg = <0 0xc06c8000 0 0x40>;
+ i2c-scl-internal-delay-ns = <110>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@c06d0000 {
+ compatible = "renesas,i2c-r8a78000",
+ "renesas,rcar-gen5-i2c";
+ reg = <0 0xc06d0000 0 0x40>;
+ i2c-scl-internal-delay-ns = <110>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@c06d8000 {
+ compatible = "renesas,i2c-r8a78000",
+ "renesas,rcar-gen5-i2c";
+ reg = <0 0xc06d8000 0 0x40>;
+ i2c-scl-internal-delay-ns = <110>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c5: i2c@c06e0000 {
+ compatible = "renesas,i2c-r8a78000",
+ "renesas,rcar-gen5-i2c";
+ reg = <0 0xc06e0000 0 0x40>;
+ i2c-scl-internal-delay-ns = <110>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c6: i2c@c06e8000 {
+ compatible = "renesas,i2c-r8a78000",
+ "renesas,rcar-gen5-i2c";
+ reg = <0 0xc06e8000 0 0x40>;
+ i2c-scl-internal-delay-ns = <110>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c7: i2c@c06f0000 {
+ compatible = "renesas,i2c-r8a78000",
+ "renesas,rcar-gen5-i2c";
+ reg = <0 0xc06f0000 0 0x40>;
+ i2c-scl-internal-delay-ns = <110>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c8: i2c@c06f8000 {
+ compatible = "renesas,i2c-r8a78000",
+ "renesas,rcar-gen5-i2c";
+ reg = <0 0xc06f8000 0 0x40>;
+ i2c-scl-internal-delay-ns = <110>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ gpio0: gpio@c1080110 {
+ compatible = "renesas,gpio-r8a78000",
+ "renesas,rcar-gen5-gpio";
+ reg = <0 0xc1080110 0 0xc0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 0 28>;
+ };
+
+ gpio1: gpio@c1080910 {
+ compatible = "renesas,gpio-r8a78000",
+ "renesas,rcar-gen5-gpio";
+ reg = <0 0xc1080910 0 0xc0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 32 22>;
+ };
+
+ gpio2: gpio@c1081110 {
+ compatible = "renesas,gpio-r8a78000",
+ "renesas,rcar-gen5-gpio";
+ reg = <0 0xc1081110 0 0xc0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 64 29>;
+ };
+
+ gpio3: gpio@c0800110 {
+ compatible = "renesas,gpio-r8a78000",
+ "renesas,rcar-gen5-gpio";
+ reg = <0 0xc0800110 0 0xc0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 96 17>;
+ };
+
+ gpio4: gpio@c0800910 {
+ compatible = "renesas,gpio-r8a78000",
+ "renesas,rcar-gen5-gpio";
+ reg = <0 0xc0800910 0 0xc0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 128 16>;
+ };
+
+ gpio5: gpio@c0400110 {
+ compatible = "renesas,gpio-r8a78000",
+ "renesas,rcar-gen5-gpio";
+ reg = <0 0xc0400110 0 0xc0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 160 23>;
+ };
+
+ gpio6: gpio@c0400910 {
+ compatible = "renesas,gpio-r8a78000",
+ "renesas,rcar-gen5-gpio";
+ reg = <0 0xc0400910 0 0xc0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 192 31>;
+ };
+
+ gpio7: gpio@c0401110 {
+ compatible = "renesas,gpio-r8a78000",
+ "renesas,rcar-gen5-gpio";
+ reg = <0 0xc0401110 0 0xc0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 224 31>;
+ };
+
+ gpio8: gpio@c0401910 {
+ compatible = "renesas,gpio-r8a78000",
+ "renesas,rcar-gen5-gpio";
+ reg = <0 0xc0401910 0 0xc0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 256 32>;
+ gpio-reserved-ranges = <16 10>;
+ };
+
+ gpio9: gpio@c9b00110 {
+ compatible = "renesas,gpio-r8a78000",
+ "renesas,rcar-gen5-gpio";
+ reg = <0 0xc9b00110 0 0xc0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 288 17>;
+ };
+
+ gpio10: gpio@c9b00910 {
+ compatible = "renesas,gpio-r8a78000",
+ "renesas,rcar-gen5-gpio";
+ reg = <0 0xc9b00910 0 0xc0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 320 14>;
+ };
+
+ mp_phy: mp_phy@c9a00000 {
+ compatible = "renesas,r8a78000-multi-protocol-phy";
+ reg = <0 0xc9a00000 0 0x100000>;
+ #phy-cells = <2>;
+ clocks = <&scmi_clk SCP_CLOCK_ID_MDLC_MPPHY01>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_MPPHY11>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_MPPHY21>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_MPPHY31>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_MPPHY02>;
+ clock-names = "mpphy01", "mpphy11", "mpphy21",
+ "mpphy31", "mpphy02";
+ power-domains = <&scmi_devpd X5H_POWER_DOMAIN_ID_MPP0>,
+ <&scmi_devpd X5H_POWER_DOMAIN_ID_MPP1>,
+ <&scmi_devpd X5H_POWER_DOMAIN_ID_MPP2>,
+ <&scmi_devpd X5H_POWER_DOMAIN_ID_MPP3>;
+ resets = <&scmi_reset SCP_RESET_DOMAIN_ID_MPPHY01>,
+ <&scmi_reset SCP_RESET_DOMAIN_ID_MPPHY11>,
+ <&scmi_reset SCP_RESET_DOMAIN_ID_MPPHY21>,
+ <&scmi_reset SCP_RESET_DOMAIN_ID_MPPHY31>,
+ <&scmi_reset SCP_RESET_DOMAIN_ID_MPPHY02>;
+ status = "disabled";
+ };
+
+ rswitch3: ethernet@c9bc0000 {
+ compatible = "renesas,r8a78000-ether-switch3",
+ "renesas,etherswitch";
+ reg = <0 0xc9bc0000 0 0x40000>, <0 0xc9b80000 0 0x240000>;
+ reg-names = "base", "secure_base";
+ power-domains = <&scmi_devpd X5H_POWER_DOMAIN_ID_RSW>;
+ clocks = <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3TSN>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3AES>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3TSNTES0>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3TSNTES1>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3TSNTES2>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3TSNTES3>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3TSNTES4>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3TSNTES5>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3TSNTES6>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3TSNTES7>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_RSW3MFWD>;
+ clock-names = "rsw3", "rsw3tsn", "rsw3aes",
+ "rsw3tsntes0", "rsw3tsntes1", "rsw3tsntes2",
+ "rsw3tsntes3", "rsw3tsntes4", "rsw3tsntes5",
+ "rsw3tsntes6", "rsw3tsntes7", "rsw3mfwd";
+ status = "disabled";
+ };
+
+ eth_pcs: phy@c9c50000 {
+ compatible = "renesas,r8a78000-ether-pcs";
+ reg = <0 0xc9c50000 0 0x4000>;
+ #phy-cells = <1>;
+ clocks = <&scmi_clk SCP_CLOCK_ID_MDLC_XPCS0>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_XPCS1>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_XPCS2>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_XPCS3>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_XPCS4>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_XPCS5>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_XPCS6>,
+ <&scmi_clk SCP_CLOCK_ID_MDLC_XPCS7>;
+ clock-names = "xpcs0", "xpcs1", "xpcs2", "xpcs3",
+ "xpcs4", "xpcs5", "xpcs6", "xpcs7";
+ resets = <&scmi_reset SCP_RESET_DOMAIN_ID_XPCS0>,
+ <&scmi_reset SCP_RESET_DOMAIN_ID_XPCS1>,
+ <&scmi_reset SCP_RESET_DOMAIN_ID_XPCS2>,
+ <&scmi_reset SCP_RESET_DOMAIN_ID_XPCS3>,
+ <&scmi_reset SCP_RESET_DOMAIN_ID_XPCS4>,
+ <&scmi_reset SCP_RESET_DOMAIN_ID_XPCS5>,
+ <&scmi_reset SCP_RESET_DOMAIN_ID_XPCS6>,
+ <&scmi_reset SCP_RESET_DOMAIN_ID_XPCS7>;
+ reset-names = "xpcs0", "xpcs1", "xpcs2", "xpcs3",
+ "xpcs4", "xpcs5", "xpcs6", "xpcs7";
+ status = "disabled";
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt";
+ };
+};
diff --git a/arch/arm/dts/socfpga-common-u-boot.dtsi b/arch/arm/dts/socfpga-common-u-boot.dtsi
index eb3d1039314..695242bec21 100644
--- a/arch/arm/dts/socfpga-common-u-boot.dtsi
+++ b/arch/arm/dts/socfpga-common-u-boot.dtsi
@@ -5,6 +5,10 @@
* Copyright (c) 2019 Simon Goldschmidt
*/
/{
+ memory {
+ bootph-all;
+ };
+
soc {
bootph-all;
};
@@ -14,6 +18,10 @@
bootph-all;
};
+&L2 {
+ bootph-all;
+};
+
&rst {
bootph-all;
};
diff --git a/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi b/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi
index 330949c0184..bf5e12ec90c 100644
--- a/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi
+++ b/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi
@@ -13,6 +13,32 @@
spi0 = "/soc/spi@ff705000";
udc0 = &usb1;
};
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ default-state = "off";
+ gpios = <&portb 20 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-1 {
+ default-state = "off";
+ gpios = <&portb 25 GPIO_ACTIVE_HIGH>;
+ label = "status_1";
+ };
+
+ led-2 {
+ default-state = "off";
+ gpios = <&portb 26 GPIO_ACTIVE_HIGH>;
+ label = "status_2";
+ };
+
+ led-3 {
+ default-state = "off";
+ gpios = <&portc 7 GPIO_ACTIVE_HIGH>;
+ };
+ };
};
&mmc {
diff --git a/arch/arm/include/asm/arch-imx9/imx91_pins.h b/arch/arm/include/asm/arch-imx9/imx91_pins.h
index 26246702a96..838a8142257 100644
--- a/arch/arm/include/asm/arch-imx9/imx91_pins.h
+++ b/arch/arm/include/asm/arch-imx9/imx91_pins.h
@@ -329,7 +329,7 @@ enum {
MX91_PAD_ENET1_TD3__CAN2_TX = IOMUX_PAD(0x0250, 0x00A0, 0x02, 0x0000, 0x00, 0x00),
MX91_PAD_ENET1_TD3__HSIOMIX_OTG_ID2 = IOMUX_PAD(0x0250, 0x00A0, 0x03, 0x0000, 0x00, 0x00),
MX91_PAD_ENET1_TD3__FLEXIO2_FLEXIO2 = IOMUX_PAD(0x0250, 0x00A0, 0x04, 0x0000, 0x00, 0x00),
- MX91_PAD_ENET1_TD3__GPIO4_IO3 = IOMUX_PAD(0x0250, 0x00A0, 0x05, 0x0000, 0x00, 0x00),
+ MX91_PAD_ENET1_TD3__GPIO4_IO2 = IOMUX_PAD(0x0250, 0x00A0, 0x05, 0x0000, 0x00, 0x00),
MX91_PAD_ENET1_TD3__LPI2C2_SCL = IOMUX_PAD(0x0250, 0x00A0, 0x06, 0x03E8, 0x00, 0x00),
MX91_PAD_ENET1_TD2__ENET_QOS_RGMII_TD2 = IOMUX_PAD(0x0254, 0x00A4, 0x00, 0x0000, 0x00, 0x00),
@@ -679,7 +679,7 @@ enum {
MX91_PAD_I2C2_SCL__LPUART2_DCB_B = IOMUX_PAD(0x0328, 0x0178, 0x02, 0x0000, 0x00, 0x00),
MX91_PAD_I2C2_SCL__TPM2_CH2 = IOMUX_PAD(0x0328, 0x0178, 0x03, 0x0000, 0x00, 0x00),
MX91_PAD_I2C2_SCL__SAI1_RX_SYNC = IOMUX_PAD(0x0328, 0x0178, 0x04, 0x0000, 0x00, 0x00),
- MX91_PAD_I2C2_SCL__GPIO1_IO3 = IOMUX_PAD(0x0328, 0x0178, 0x05, 0x0000, 0x00, 0x00),
+ MX91_PAD_I2C2_SCL__GPIO1_IO2 = IOMUX_PAD(0x0328, 0x0178, 0x05, 0x0000, 0x00, 0x00),
MX91_PAD_I2C2_SCL__I3C1_PUR_B = IOMUX_PAD(0x0328, 0x0178, 0x06, 0x0000, 0x00, 0x00),
MX91_PAD_I2C2_SDA__LPI2C2_SDA = IOMUX_PAD(0x032C, 0x017C, 0x00, 0x03EC, 0x01, 0x00),
diff --git a/arch/arm/mach-bcm283x/include/mach/gpio.h b/arch/arm/mach-bcm283x/include/mach/gpio.h
index 4aeb48eeb20..c54414a012c 100644
--- a/arch/arm/mach-bcm283x/include/mach/gpio.h
+++ b/arch/arm/mach-bcm283x/include/mach/gpio.h
@@ -26,6 +26,16 @@
#define BCM2835_GPIO_FSEL_BANK(gpio) (gpio / 10)
#define BCM2835_GPIO_FSEL_SHIFT(gpio) ((gpio % 10) * 3)
+/* BCM2835 GPIO Pull-up/down register offsets */
+#define BCM2835_GPPUD 37
+#define BCM2835_GPPUDCLK0 38
+
+/* BCM2711 GPIO Pull-up/down control */
+#define BCM2711_GPPUD_CNTRL_REG0 57
+#define BCM2711_PUD_REG_OFFSET(gpio) ((gpio) / 16)
+#define BCM2711_PUD_REG_SHIFT(gpio) (((gpio) % 16) * 2)
+#define BCM2711_PUD_2711_MASK 0x3
+
struct bcm2835_gpio_regs {
u32 gpfsel[6];
u32 reserved1;
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 2cd67d02386..b084b7284aa 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -2,7 +2,7 @@ if ARCH_EXYNOS
config BOARD_COMMON
def_bool y
- depends on !TARGET_SMDKV310 && !TARGET_ARNDALE && !TARGET_E850_96
+ depends on !TARGET_SMDKV310 && !TARGET_ARNDALE && !TARGET_EXYNOS_MOBILE && !TARGET_E850_96
config SPI_BOOTING
bool
@@ -252,6 +252,14 @@ config TARGET_E850_96
endchoice
endif
+config TARGET_EXYNOS_MOBILE
+ bool "Samsung Exynos Generic Boards (for mobile devices)"
+ select ARM64
+ select BOARD_EARLY_INIT_F
+ select CLK_EXYNOS
+ select LINUX_KERNEL_IMAGE_HEADER
+ select OF_CONTROL
+
config SYS_SOC
default "exynos"
@@ -277,5 +285,6 @@ source "board/samsung/smdk5420/Kconfig"
source "board/samsung/espresso7420/Kconfig"
source "board/samsung/axy17lte/Kconfig"
source "board/samsung/e850-96/Kconfig"
+source "board/samsung/exynos-mobile/Kconfig"
endif
diff --git a/arch/arm/mach-k3/r5/j722s/clk-data.c b/arch/arm/mach-k3/r5/j722s/clk-data.c
index 238d57d0aa0..cb3d864c5a3 100644
--- a/arch/arm/mach-k3/r5/j722s/clk-data.c
+++ b/arch/arm/mach-k3/r5/j722s/clk-data.c
@@ -68,6 +68,11 @@ static const char * const main_cp_gemac_cpts_clk_sel_out0_parents[] = {
"sam62_pll_ctrl_wrap_main_0_chip_div1_clk_clk",
};
+static const char * const main_emmcsd0_refclk_sel_out0_parents[] = {
+ "postdiv4_16ff_main_0_hsdivout5_clk",
+ "hsdiv4_16fft_main_2_hsdivout2_clk",
+};
+
static const char * const main_emmcsd1_refclk_sel_out0_parents[] = {
"postdiv4_16ff_main_0_hsdivout5_clk",
"hsdiv4_16fft_main_2_hsdivout2_clk",
@@ -106,6 +111,8 @@ static const char * const main_timerclkn_sel_out0_parents[] = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
};
static const char * const wkup_clkout_sel_out0_parents[] = {
@@ -205,6 +212,7 @@ static const struct clk_data clk_list[] = {
CLK_MUX_PLLCTRL("sam62_pll_ctrl_wrap_mcu_0_sysclkout_clk", sam62_pll_ctrl_wrap_mcu_0_sysclkout_clk_parents, 2, 0x4020000, 0),
CLK_DIV("sam62_pll_ctrl_wrap_mcu_0_chip_div1_clk_clk", "sam62_pll_ctrl_wrap_mcu_0_sysclkout_clk", 0x4020118, 0, 5, 0, 0),
CLK_MUX("clkout0_ctrl_out0", clkout0_ctrl_out0_parents, 2, 0x108010, 0, 1, 0),
+ CLK_MUX("main_emmcsd0_refclk_sel_out0", main_emmcsd0_refclk_sel_out0_parents, 2, 0x108160, 0, 1, 0),
CLK_MUX("main_cp_gemac_cpts_clk_sel_out0", main_cp_gemac_cpts_clk_sel_out0_parents, 8, 0x108140, 0, 3, 0),
CLK_MUX("main_emmcsd1_refclk_sel_out0", main_emmcsd1_refclk_sel_out0_parents, 2, 0x108168, 0, 1, 0),
CLK_MUX("main_gtcclk_sel_out0", main_gtcclk_sel_out0_parents, 8, 0x43008030, 0, 3, 0),
@@ -262,6 +270,10 @@ static const struct dev_clk soc_dev_clk_data[] = {
DEV_CLK(36, 10, "board_0_cp_gemac_cpts0_rft_clk_out"),
DEV_CLK(36, 11, "hsdiv4_16fft_main_1_hsdivout3_clk"),
DEV_CLK(36, 12, "postdiv4_16ff_main_2_hsdivout6_clk"),
+ DEV_CLK(57, 1, "sam62_pll_ctrl_wrap_main_0_chip_div1_clk_clk"),
+ DEV_CLK(57, 2, "main_emmcsd0_refclk_sel_out0"),
+ DEV_CLK(57, 3, "postdiv4_16ff_main_0_hsdivout5_clk"),
+ DEV_CLK(57, 4, "hsdiv4_16fft_main_2_hsdivout2_clk"),
DEV_CLK(36, 13, "cpsw_3guss_am67_main_0_cpts_genf0"),
DEV_CLK(36, 14, "cpsw_3guss_am67_main_0_cpts_genf1"),
DEV_CLK(58, 0, "main_emmcsd1_io_clklb_sel_out0"),
diff --git a/arch/arm/mach-k3/r5/j722s/dev-data.c b/arch/arm/mach-k3/r5/j722s/dev-data.c
index d6832266884..5f7e2a44fed 100644
--- a/arch/arm/mach-k3/r5/j722s/dev-data.c
+++ b/arch/arm/mach-k3/r5/j722s/dev-data.c
@@ -23,18 +23,19 @@ static struct ti_pd soc_pd_list[] = {
static struct ti_lpsc soc_lpsc_list[] = {
[0] = PSC_LPSC(0, &soc_psc_list[0], &soc_pd_list[0], NULL),
- [1] = PSC_LPSC(12, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[4]),
- [2] = PSC_LPSC(13, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[4]),
- [3] = PSC_LPSC(21, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[6]),
- [4] = PSC_LPSC(23, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[6]),
- [5] = PSC_LPSC(28, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[6]),
- [6] = PSC_LPSC(34, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[6]),
- [7] = PSC_LPSC(42, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[6]),
- [8] = PSC_LPSC(53, &soc_psc_list[0], &soc_pd_list[1], &soc_lpsc_list[6]),
- [9] = PSC_LPSC(56, &soc_psc_list[0], &soc_pd_list[2], &soc_lpsc_list[8]),
- [10] = PSC_LPSC(72, &soc_psc_list[0], &soc_pd_list[3], &soc_lpsc_list[6]),
- [11] = PSC_LPSC(73, &soc_psc_list[0], &soc_pd_list[3], &soc_lpsc_list[10]),
- [12] = PSC_LPSC(74, &soc_psc_list[0], &soc_pd_list[3], &soc_lpsc_list[11]),
+ [1] = PSC_LPSC(12, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[5]),
+ [2] = PSC_LPSC(13, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[5]),
+ [3] = PSC_LPSC(20, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[7]),
+ [4] = PSC_LPSC(21, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[7]),
+ [5] = PSC_LPSC(23, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[7]),
+ [6] = PSC_LPSC(28, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[7]),
+ [7] = PSC_LPSC(34, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[7]),
+ [8] = PSC_LPSC(42, &soc_psc_list[0], &soc_pd_list[0], &soc_lpsc_list[7]),
+ [9] = PSC_LPSC(53, &soc_psc_list[0], &soc_pd_list[1], &soc_lpsc_list[7]),
+ [10] = PSC_LPSC(56, &soc_psc_list[0], &soc_pd_list[2], &soc_lpsc_list[9]),
+ [11] = PSC_LPSC(72, &soc_psc_list[0], &soc_pd_list[3], &soc_lpsc_list[7]),
+ [12] = PSC_LPSC(73, &soc_psc_list[0], &soc_pd_list[3], &soc_lpsc_list[11]),
+ [13] = PSC_LPSC(74, &soc_psc_list[0], &soc_pd_list[3], &soc_lpsc_list[12]),
};
static struct ti_dev soc_dev_list[] = {
@@ -43,18 +44,19 @@ static struct ti_dev soc_dev_list[] = {
PSC_DEV(61, &soc_lpsc_list[0]),
PSC_DEV(178, &soc_lpsc_list[1]),
PSC_DEV(179, &soc_lpsc_list[2]),
- PSC_DEV(58, &soc_lpsc_list[3]),
- PSC_DEV(161, &soc_lpsc_list[4]),
- PSC_DEV(75, &soc_lpsc_list[5]),
- PSC_DEV(36, &soc_lpsc_list[6]),
- PSC_DEV(102, &soc_lpsc_list[6]),
- PSC_DEV(146, &soc_lpsc_list[6]),
- PSC_DEV(13, &soc_lpsc_list[7]),
- PSC_DEV(166, &soc_lpsc_list[8]),
- PSC_DEV(135, &soc_lpsc_list[9]),
- PSC_DEV(170, &soc_lpsc_list[10]),
- PSC_DEV(177, &soc_lpsc_list[11]),
- PSC_DEV(55, &soc_lpsc_list[12]),
+ PSC_DEV(57, &soc_lpsc_list[3]),
+ PSC_DEV(58, &soc_lpsc_list[4]),
+ PSC_DEV(161, &soc_lpsc_list[5]),
+ PSC_DEV(75, &soc_lpsc_list[6]),
+ PSC_DEV(36, &soc_lpsc_list[7]),
+ PSC_DEV(102, &soc_lpsc_list[7]),
+ PSC_DEV(146, &soc_lpsc_list[7]),
+ PSC_DEV(13, &soc_lpsc_list[8]),
+ PSC_DEV(166, &soc_lpsc_list[9]),
+ PSC_DEV(135, &soc_lpsc_list[10]),
+ PSC_DEV(170, &soc_lpsc_list[11]),
+ PSC_DEV(177, &soc_lpsc_list[12]),
+ PSC_DEV(55, &soc_lpsc_list[13]),
};
const struct ti_k3_pd_platdata j722s_pd_platdata = {
diff --git a/arch/arm/mach-renesas/Kconfig b/arch/arm/mach-renesas/Kconfig
index 8f4fba4615c..fa4e312a4dd 100644
--- a/arch/arm/mach-renesas/Kconfig
+++ b/arch/arm/mach-renesas/Kconfig
@@ -46,6 +46,11 @@ config RCAR_GEN4
select RCAR_64
select PINCTRL_PFC
+config RCAR_GEN5
+ bool "Renesas ARM SoCs R-Car Gen5 (64bit)"
+ select RCAR_64
+ select PINCTRL_PFC
+
config RZA1
prompt "Renesas ARM SoCs RZ/A1 (32bit)"
select CPU_V7A
diff --git a/arch/arm/mach-renesas/Kconfig.64 b/arch/arm/mach-renesas/Kconfig.64
index b5067d0a8f0..1b1ed88339b 100644
--- a/arch/arm/mach-renesas/Kconfig.64
+++ b/arch/arm/mach-renesas/Kconfig.64
@@ -8,5 +8,6 @@ config OF_LIBFDT_OVERLAY
source "arch/arm/mach-renesas/Kconfig.rcar3"
source "arch/arm/mach-renesas/Kconfig.rcar4"
+source "arch/arm/mach-renesas/Kconfig.rcar5"
endif
diff --git a/arch/arm/mach-renesas/Kconfig.rcar5 b/arch/arm/mach-renesas/Kconfig.rcar5
new file mode 100644
index 00000000000..528fc5aecc9
--- /dev/null
+++ b/arch/arm/mach-renesas/Kconfig.rcar5
@@ -0,0 +1,26 @@
+if RCAR_GEN5
+
+menu "Select Target SoC"
+
+config R8A78000
+ bool "Renesas SoC R8A78000"
+ select GICV3
+ imply PINCTRL_PFC_R8A78000
+
+endmenu
+
+choice
+ prompt "Renesas ARM64 SoCs board select"
+ optional
+
+config TARGET_IRONHIDE
+ bool "Ironhide board"
+ imply R8A78000
+ help
+ Support for Renesas R-Car Gen5 Ironhide platform
+
+endchoice
+
+source "board/renesas/ironhide/Kconfig"
+
+endif
diff --git a/arch/arm/mach-renesas/Makefile b/arch/arm/mach-renesas/Makefile
index 9165ceab4a3..c0454fffa48 100644
--- a/arch/arm/mach-renesas/Makefile
+++ b/arch/arm/mach-renesas/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_RCAR_GEN2) += lowlevel_init_ca15.o cpu_info-rcar.o
obj-$(CONFIG_RCAR_64) += lowlevel_init_gen3.o
obj-$(CONFIG_RCAR_GEN3) += cpu_info-rcar.o memmap-gen3.o
obj-$(CONFIG_RCAR_GEN4) += cpu_info-rcar.o memmap-gen3.o
+obj-$(CONFIG_RCAR_GEN5) += cpu_info-rcar.o memmap-gen3.o
obj-$(CONFIG_RZ_G2) += cpu_info-rzg.o
obj-$(CONFIG_RZG2L) += cpu_info-rzg2l.o memmap-rzg2l.o
diff --git a/arch/arm/mach-renesas/cpu_info-rcar.c b/arch/arm/mach-renesas/cpu_info-rcar.c
index 74140fd38ab..a6e0b739e55 100644
--- a/arch/arm/mach-renesas/cpu_info-rcar.c
+++ b/arch/arm/mach-renesas/cpu_info-rcar.c
@@ -15,8 +15,12 @@
static u32 renesas_get_prr(void)
{
- if (IS_ENABLED(CONFIG_RCAR_64))
- return readl(0xFFF00044);
+ if (IS_ENABLED(CONFIG_RCAR_64)) {
+ if (IS_ENABLED(CONFIG_RCAR_GEN5))
+ return readl(0x189E0044);
+ else
+ return readl(0xFFF00044);
+ }
return readl(0xFF000044);
}
diff --git a/arch/arm/mach-renesas/cpu_info.c b/arch/arm/mach-renesas/cpu_info.c
index 2f9a4374a96..f040d732a51 100644
--- a/arch/arm/mach-renesas/cpu_info.c
+++ b/arch/arm/mach-renesas/cpu_info.c
@@ -72,6 +72,7 @@ static const struct {
{ RENESAS_CPU_TYPE_R8A779F0, "R8A779F0" },
{ RENESAS_CPU_TYPE_R8A779G0, "R8A779G0" },
{ RENESAS_CPU_TYPE_R8A779H0, "R8A779H0" },
+ { RMOBILE_CPU_TYPE_R8A78000, "R8A78000" },
{ 0x0, "CPU" },
};
diff --git a/arch/arm/mach-renesas/include/mach/rcar-gen5-base.h b/arch/arm/mach-renesas/include/mach/rcar-gen5-base.h
new file mode 100644
index 00000000000..f9af3ef885a
--- /dev/null
+++ b/arch/arm/mach-renesas/include/mach/rcar-gen5-base.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ */
+
+#ifndef __ASM_ARCH_RCAR_GEN5_BASE_H
+#define __ASM_ARCH_RCAR_GEN5_BASE_H
+
+/*
+ * R-Car (R8A78000) I/O Addresses
+ */
+#define TMU_BASE 0x1C030000
+
+/* Arm Generic Timer */
+#define CNTCR_BASE 0x1C000FFF /* Region 0 */
+#define CNTFID0 (CNTCR_BASE + 0x020)
+#define CNTCR_EN BIT(0)
+
+/* Reset */
+#define RST_BASE 0xC1320000 /* Domain0 */
+#define RST_SWSRES1A (RST_BASE + 0x410)
+#define RST_WDTRSTCR (RST_BASE + 0x420)
+#define RST_RWDT_RSTMSK BIT(0)
+#define RST_WWDT_RSTMSK BIT(2)
+#define RST_RESKCPROT0 (RST_BASE + 0x4F0)
+#define RST_KCPROT_DIS 0xA5A5A501
+
+/* GICv4 */
+/* Distributor Registers */
+#define GICD_BASE 0x38000000
+#define GICR_BASE (GICR_LPI_BASE)
+
+/* ReDistributor Registers for Control and Physical LPIs */
+#define GICR_LPI_BASE 0x38080000
+#define GICR_WAKER 0x0014
+#define GICR_PWRR 0x0024
+#define GICR_LPI_WAKER (GICR_LPI_BASE + GICR_WAKER)
+#define GICR_LPI_PWRR (GICR_LPI_BASE + GICR_PWRR)
+
+/* ReDistributor Registers for SGIs and PPIs */
+#define GICR_SGI_BASE 0x38090000
+#define GICR_IGROUPR0 0x0080
+
+#endif /* __ASM_ARCH_RCAR_GEN5_BASE_H */
diff --git a/arch/arm/mach-renesas/include/mach/renesas.h b/arch/arm/mach-renesas/include/mach/renesas.h
index c69c764adb8..deaeffedef9 100644
--- a/arch/arm/mach-renesas/include/mach/renesas.h
+++ b/arch/arm/mach-renesas/include/mach/renesas.h
@@ -16,6 +16,8 @@
#include <asm/arch/rcar-gen3-base.h>
#elif defined(CONFIG_RCAR_GEN4)
#include <asm/arch/rcar-gen4-base.h>
+#elif defined(CONFIG_RCAR_GEN5)
+#include <asm/arch/rcar-gen5-base.h>
#elif defined(CONFIG_R7S72100)
#elif defined(CONFIG_RZG2L)
#include <asm/arch/rzg2l.h>
@@ -42,6 +44,7 @@
#define RENESAS_CPU_TYPE_R8A779F0 0x5A
#define RENESAS_CPU_TYPE_R8A779G0 0x5C
#define RENESAS_CPU_TYPE_R8A779H0 0x5D
+#define RMOBILE_CPU_TYPE_R8A78000 0x60
#define RENESAS_CPU_TYPE_R9A07G044L 0x9A070440
#ifndef __ASSEMBLY__
diff --git a/arch/arm/mach-renesas/psci-rcar64.c b/arch/arm/mach-renesas/psci-rcar64.c
index 459dd55ff45..22c2ee045cc 100644
--- a/arch/arm/mach-renesas/psci-rcar64.c
+++ b/arch/arm/mach-renesas/psci-rcar64.c
@@ -32,7 +32,12 @@ u32 __secure psci_version(void)
void __secure __noreturn psci_system_reset(void)
{
+#if defined(CONFIG_RCAR_GEN5)
+ writel(RST_KCPROT_DIS, RST_RESKCPROT0);
+ writel(0x1, RST_SWSRES1A);
+#else
writel(RST_SPRES, RST_SRESCR0);
+#endif
while (1)
;
diff --git a/arch/arm/mach-socfpga/config.mk b/arch/arm/mach-socfpga/config.mk
new file mode 100644
index 00000000000..2290118f747
--- /dev/null
+++ b/arch/arm/mach-socfpga/config.mk
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Brian Sune <[email protected]>
+
+ifeq ($(CONFIG_TARGET_SOCFPGA_CYCLONE5),y)
+archprepare: socfpga_g5_handoff_prepare
+else ifeq ($(CONFIG_TARGET_SOCFPGA_ARRIA5),y)
+archprepare: socfpga_g5_handoff_prepare
+endif
+
+socfpga_g5_handoff_prepare:
+ @SOCFAMILY="$(SOCFAMILY)"; \
+ if [ -z "$$SOCFAMILY" ]; then \
+ exit 0; \
+ fi; \
+ echo "[INFO] SOC family detected: $$SOCFAMILY";
+ @set -- $$(awk -F'"' ' \
+ /^CONFIG_SYS_VENDOR=/ {v=$$2} \
+ /^CONFIG_SYS_BOARD=/ {b=$$2} \
+ END {print v, b}' .config); \
+ VENDOR=$$1; \
+ BOARD=$$2; \
+ if [ -z "$$VENDOR" ] || [ -z "$$BOARD" ]; then \
+ exit 0; \
+ fi; \
+ BOARD_DIR=$(src)/board/$$VENDOR/$$BOARD; \
+ if [ "$$HANDOFF_PATH" ]; then \
+ echo "[INFO] Using manually specified handoff folder: $$HANDOFF_PATH"; \
+ else \
+ HANDOFF_BASE=$$BOARD_DIR/hps_isw_handoff; \
+ if [ ! -d "$$HANDOFF_BASE" ]; then \
+ exit 0; \
+ fi; \
+ HANDOFF_PATH=$$(ls -d "$$HANDOFF_BASE"/*/ 2>/dev/null | head -n1); \
+ if [ -z "$$HANDOFF_PATH" ]; then \
+ exit 0; \
+ fi; \
+ echo "[INFO] Auto-detected handoff folder: $$HANDOFF_PATH"; \
+ fi; \
+ HIOF_FILE=$$HANDOFF_PATH/$$(basename $$HANDOFF_PATH).hiof; \
+ if [ ! -f "$$HIOF_FILE" ]; then \
+ echo "[WARN] No .hiof file found in $$HANDOFF_PATH, skipping BSP generation."; \
+ exit 0; \
+ fi; \
+ echo "[INFO] Found hiof file: $$HIOF_FILE"; \
+ echo "[INFO] Running BSP generator..."; \
+ python3 $(src)/tools/cv_bsp_generator/cv_bsp_generator.py -i "$$HANDOFF_PATH" -o "$$BOARD_DIR/qts" || echo "[WARN] BSP generator failed, continuing..."; \
+ echo "[DONE] SoCFPGA QTS handoff conversion complete."
diff --git a/arch/arm/mach-socfpga/misc.c b/arch/arm/mach-socfpga/misc.c
index 76747c2196a..07694107c8a 100644
--- a/arch/arm/mach-socfpga/misc.c
+++ b/arch/arm/mach-socfpga/misc.c
@@ -222,7 +222,7 @@ static int do_bridge(struct cmd_tbl *cmdtp, int flag, int argc,
}
U_BOOT_CMD(bridge, 3, 1, do_bridge,
- "SoCFPGA HPS FPGA bridge control",
+ "GEN5 SoCFPGA HPS FPGA bridge control",
"enable [mask] - Enable HPS-to-FPGA (Bit 0), LWHPS-to-FPGA (Bit 1), FPGA-to-HPS (Bit 2) bridges\n"
"bridge disable [mask] - Disable HPS-to-FPGA (Bit 0), LWHPS-to-FPGA (Bit 1), FPGA-to-HPS (Bit 2) bridges\n"
""
@@ -261,7 +261,16 @@ void socfpga_get_managers_addr(void)
if (ret)
hang();
- else if (IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X))
+ if (!IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX) &&
+ !IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX7M) &&
+ !IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5)) {
+ ret = socfpga_get_base_addr("altr,sys-mgr",
+ &socfpga_sysmgr_base);
+ if (ret)
+ hang();
+ }
+
+ if (IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X))
ret = socfpga_get_base_addr("intel,n5x-clkmgr",
&socfpga_clkmgr_base);
else if (!IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX) &&
diff --git a/arch/arm/mach-socfpga/misc_gen5.c b/arch/arm/mach-socfpga/misc_gen5.c
index b136691c685..5259ef54d73 100644
--- a/arch/arm/mach-socfpga/misc_gen5.c
+++ b/arch/arm/mach-socfpga/misc_gen5.c
@@ -217,6 +217,34 @@ int arch_early_init_r(void)
static struct socfpga_sdr_ctrl *sdr_ctrl =
(struct socfpga_sdr_ctrl *)SDR_CTRLGRP_ADDRESS;
+void socfpga_sdram_apply_static_cfg(void)
+{
+ const u32 applymask = 0x8;
+ u32 val = readl(&sdr_ctrl->static_cfg) | applymask;
+
+ /*
+ * SDRAM staticcfg register specific:
+ * When applying the register setting, the CPU must not access
+ * SDRAM. Luckily for us, we can use i-cache here to help us
+ * circumvent the SDRAM access issue. The idea is to make sure
+ * that the code is in one full i-cache line by branching past
+ * it and back. Once it is in the i-cache, we execute the core
+ * of the code and apply the register settings.
+ *
+ * The code below uses 7 instructions, while the Cortex-A9 has
+ * 32-byte cachelines, thus the limit is 8 instructions total.
+ */
+ asm volatile(".align 5 \n"
+ " b 2f \n"
+ "1: str %0, [%1] \n"
+ " dsb \n"
+ " isb \n"
+ " b 3f \n"
+ "2: b 1b \n"
+ "3: nop \n"
+ : : "r"(val), "r"(&sdr_ctrl->static_cfg) : "memory", "cc");
+}
+
void do_bridge_reset(int enable, unsigned int mask)
{
int i;
@@ -234,7 +262,10 @@ void do_bridge_reset(int enable, unsigned int mask)
writel(iswgrp_handoff[2],
socfpga_get_sysmgr_addr() +
SYSMGR_GEN5_FPGAINFGRP_MODULE);
- writel(iswgrp_handoff[3], &sdr_ctrl->fpgaport_rst);
+ if (iswgrp_handoff[3]) {
+ writel(iswgrp_handoff[3], &sdr_ctrl->fpgaport_rst);
+ socfpga_sdram_apply_static_cfg();
+ }
writel(iswgrp_handoff[0],
socfpga_get_rstmgr_addr() + RSTMGR_GEN5_BRGMODRST);
writel(iswgrp_handoff[1], &nic301_regs->remap);
@@ -246,6 +277,7 @@ void do_bridge_reset(int enable, unsigned int mask)
writel(0, socfpga_get_sysmgr_addr() +
SYSMGR_GEN5_FPGAINFGRP_MODULE);
writel(0, &sdr_ctrl->fpgaport_rst);
+ socfpga_sdram_apply_static_cfg();
writel(0x7, socfpga_get_rstmgr_addr() + RSTMGR_GEN5_BRGMODRST);
writel(1, &nic301_regs->remap);
}
diff --git a/arch/sh/cpu/u-boot.lds b/arch/sh/cpu/u-boot.lds
index c31deecec65..81526f5bd23 100644
--- a/arch/sh/cpu/u-boot.lds
+++ b/arch/sh/cpu/u-boot.lds
@@ -72,6 +72,7 @@ SECTIONS
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
+ . = ALIGN(8);
} >ram
PROVIDE (__init_end = .);
@@ -83,7 +84,7 @@ SECTIONS
.bss :
{
*(.bss)
- . = ALIGN(4);
+ . = ALIGN(8);
} >ram
PROVIDE (bss_end = .);
PROVIDE (__bss_end = .);
diff --git a/board/BuR/brppt1/MAINTAINERS b/board/BuR/brppt1/MAINTAINERS
index a974a97c157..fc2ee146668 100644
--- a/board/BuR/brppt1/MAINTAINERS
+++ b/board/BuR/brppt1/MAINTAINERS
@@ -1,9 +1,8 @@
BRPPT1 BOARD
-M: Wolfgang Wallner <[email protected]>
+M: Wolfgang Wallner <[email protected]>
S: Maintained
F: board/BuR/brppt1/
F: board/BuR/common/
F: include/configs/brppt1.h
F: configs/brppt1_mmc_defconfig
-F: configs/brppt1_nand_defconfig
-F: configs/brppt1_spi_defconfig
+F: arch/arm/dts/am335x-brppt1-mmc*
diff --git a/board/BuR/brppt2/MAINTAINERS b/board/BuR/brppt2/MAINTAINERS
index bfeaa571a82..84cb6573463 100644
--- a/board/BuR/brppt2/MAINTAINERS
+++ b/board/BuR/brppt2/MAINTAINERS
@@ -1,7 +1,8 @@
BUR_PPT2 BOARD
-M: Wolfgang Wallner <[email protected]>
+M: Wolfgang Wallner <[email protected]>
S: Maintained
F: board/BuR/brppt2/
F: board/BuR/common/
F: include/configs/brppt2.h
F: configs/brppt2_defconfig
+F: arch/arm/dts/imx6dl-brppt2.dts
diff --git a/board/BuR/brsmarc1/MAINTAINERS b/board/BuR/brsmarc1/MAINTAINERS
index 7421f61fc43..8716002c172 100644
--- a/board/BuR/brsmarc1/MAINTAINERS
+++ b/board/BuR/brsmarc1/MAINTAINERS
@@ -1,7 +1,8 @@
BRSMARC1 BOARD
-M: Wolfgang Wallner <[email protected]>
+M: Wolfgang Wallner <[email protected]>
S: Maintained
F: board/BuR/brsmarc1/
F: board/BuR/common/
F: include/configs/brsmarc1.h
F: configs/brsmarc1_defconfig
+F: arch/arm/dts/am335x-brsmarc1.dts
diff --git a/board/BuR/brxre1/MAINTAINERS b/board/BuR/brxre1/MAINTAINERS
index f826a44b6ac..b424ddca6ca 100644
--- a/board/BuR/brxre1/MAINTAINERS
+++ b/board/BuR/brxre1/MAINTAINERS
@@ -1,5 +1,5 @@
BRXRE1 BOARD
-M: Wolfgang Wallner <[email protected]>
+M: Wolfgang Wallner <[email protected]>
S: Maintained
F: board/BuR/brxre1/
F: board/BuR/common/
diff --git a/board/BuR/zynq/MAINTAINERS b/board/BuR/zynq/MAINTAINERS
index d655cae58d4..e2b04980403 100644
--- a/board/BuR/zynq/MAINTAINERS
+++ b/board/BuR/zynq/MAINTAINERS
@@ -1,5 +1,5 @@
ZYNQ BOARD
-M: Wolfgang Wallner <[email protected]>
+M: Wolfgang Wallner <[email protected]>
S: Maintained
F: board/BuR/zynq/
F: board/BuR/common/
diff --git a/board/armltd/integrator/MAINTAINERS b/board/armltd/integrator/MAINTAINERS
index 8af765eaebc..a228fc3daec 100644
--- a/board/armltd/integrator/MAINTAINERS
+++ b/board/armltd/integrator/MAINTAINERS
@@ -1,5 +1,5 @@
INTEGRATOR BOARD
-M: Linus Walleij <[email protected]>
+M: Linus Walleij <[email protected]>
S: Maintained
F: board/armltd/integrator/
F: include/configs/integratorcp.h
diff --git a/board/armltd/vexpress64/MAINTAINERS b/board/armltd/vexpress64/MAINTAINERS
index c38ab520c52..58ab5db7e4a 100644
--- a/board/armltd/vexpress64/MAINTAINERS
+++ b/board/armltd/vexpress64/MAINTAINERS
@@ -1,18 +1,18 @@
VEXPRESS64 PLATFORM
M: David Feng <[email protected]>
-M: Linus Walleij <[email protected]>
+M: Linus Walleij <[email protected]>
M: Peter Hoyes <[email protected]>
S: Maintained
F: board/armltd/vexpress64/
F: include/configs/vexpress_aemv8.h
VEXPRESS_AEMV8A_SEMI BOARD
-M: Linus Walleij <[email protected]>
+M: Linus Walleij <[email protected]>
S: Maintained
F: configs/vexpress_aemv8a_semi_defconfig
JUNO DEVELOPMENT PLATFORM BOARD
-M: Linus Walleij <[email protected]>
+M: Linus Walleij <[email protected]>
S: Maintained
F: configs/vexpress_aemv8a_juno_defconfig
diff --git a/board/broadcom/bcmns/MAINTAINERS b/board/broadcom/bcmns/MAINTAINERS
index 63c6d8bb4ac..4972d6cc934 100644
--- a/board/broadcom/bcmns/MAINTAINERS
+++ b/board/broadcom/bcmns/MAINTAINERS
@@ -1,5 +1,5 @@
BCMNS BOARD
-M: Linus Walleij <[email protected]>
+M: Linus Walleij <[email protected]>
S: Maintained
F: board/broadcom/bcmns/
F: configs/bcmns_defconfig
diff --git a/board/raspberrypi/rpi/lowlevel_init.S b/board/raspberrypi/rpi/lowlevel_init.S
index 8c39b3e12e8..30c0b0c27a8 100644
--- a/board/raspberrypi/rpi/lowlevel_init.S
+++ b/board/raspberrypi/rpi/lowlevel_init.S
@@ -16,7 +16,8 @@ save_boot_params:
/* The firmware provided ATAG/FDT address can be found in r2/x0 */
#ifdef CONFIG_ARM64
- adr x8, fw_dtb_pointer
+ adrp x8, fw_dtb_pointer
+ add x8, x8, #:lo12:fw_dtb_pointer
str x0, [x8]
#else
ldr r8, =fw_dtb_pointer
diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
index 1b0b664fa2b..f9b643555dd 100644
--- a/board/raspberrypi/rpi/rpi.c
+++ b/board/raspberrypi/rpi/rpi.c
@@ -3,6 +3,8 @@
* (C) Copyright 2012-2016 Stephen Warren
*/
+#define LOG_CATEGORY LOGC_BOARD
+
#include <config.h>
#include <dm.h>
#include <env.h>
@@ -332,13 +334,27 @@ int dram_init(void)
#ifdef CONFIG_OF_BOARD
int dram_init_banksize(void)
{
+ phys_addr_t total_size = 0;
+ int i;
int ret;
ret = fdtdec_setup_memory_banksize();
if (ret)
return ret;
- return fdtdec_setup_mem_size_base();
+ ret = fdtdec_setup_mem_size_base();
+ if (ret)
+ return ret;
+
+ /* Update gd->ram_size to reflect total RAM across all banks */
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+ if (gd->bd->bi_dram[i].size == 0)
+ break;
+ total_size += gd->bd->bi_dram[i].size;
+ }
+ gd->ram_size = total_size;
+
+ return 0;
}
#endif
@@ -354,15 +370,13 @@ static void set_fdtfile(void)
}
/*
- * If the firmware provided a valid FDT at boot time, let's expose it in
- * ${fdt_addr} so it may be passed unmodified to the kernel.
+ * Allow U-Boot to use its control FDT with extlinux if one is not provided.
+ * This will then go through the usual fixups that U-Boot does, before being
+ * handed off to Linux
*/
static void set_fdt_addr(void)
{
- if (fdt_magic(fw_dtb_pointer) != FDT_MAGIC)
- return;
-
- env_set_hex("fdt_addr", fw_dtb_pointer);
+ env_set_hex("fdt_addr", (ulong)gd->fdt_blob);
}
/*
@@ -608,7 +622,10 @@ int ft_board_setup(void *blob, struct bd_info *bd)
{
int node;
- update_fdt_from_fw(blob, (void *)fw_dtb_pointer);
+ if (blob == gd->fdt_blob)
+ log_debug("Same FDT: nothing to do\n");
+ else
+ update_fdt_from_fw(blob, (void *)gd->fdt_blob);
if (CONFIG_IS_ENABLED(FDT_SIMPLEFB)) {
node = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer");
diff --git a/board/renesas/MAINTAINERS b/board/renesas/MAINTAINERS
index 13551cdd2b4..8571bb02576 100644
--- a/board/renesas/MAINTAINERS
+++ b/board/renesas/MAINTAINERS
@@ -6,7 +6,7 @@ N: grpeach
N: r2dplus
N: r7s72100
N: r8a66597
-N: r8a77
+N: r8a7[78]
N: r9a0[0-9]g
N: rcar
N: renesas
diff --git a/board/renesas/common/Makefile b/board/renesas/common/Makefile
index 1849c995aee..889de8ea9ac 100644
--- a/board/renesas/common/Makefile
+++ b/board/renesas/common/Makefile
@@ -43,6 +43,10 @@ else
obj-y += gen4-common.o
endif
endif
+
+ifdef CONFIG_RCAR_GEN5
+obj-y += gen5-common.o
+endif
endif
endif
diff --git a/board/renesas/common/gen5-common.c b/board/renesas/common/gen5-common.c
new file mode 100644
index 00000000000..a05a3e8abef
--- /dev/null
+++ b/board/renesas/common/gen5-common.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ */
+
+#include <asm/arch/renesas.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <linux/errno.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void init_generic_timer(void)
+{
+ const u32 freq = CONFIG_SYS_CLK_FREQ;
+
+ /* Update memory mapped and register based freqency */
+ asm volatile ("msr cntfrq_el0, %0" :: "r" (freq));
+ writel(freq, CNTFID0);
+
+ /* Enable counter */
+ setbits_le32(CNTCR_BASE, CNTCR_EN);
+}
+
+static void init_gic_v3(void)
+{
+ /* GIC v3 power on */
+ writel(BIT(1), GICR_LPI_PWRR);
+
+ /* Wait till the WAKER_CA_BIT changes to 0 */
+ clrbits_le32(GICR_LPI_WAKER, BIT(1));
+ while (readl(GICR_LPI_WAKER) & BIT(2))
+ ;
+
+ writel(0xffffffff, GICR_SGI_BASE + GICR_IGROUPR0);
+}
+
+void s_init(void)
+{
+ if (current_el() == 3)
+ init_generic_timer();
+}
+
+int board_early_init_f(void)
+{
+ return 0;
+}
+
+int board_init(void)
+{
+ /* Allow WDT reset */
+ writel(RST_KCPROT_DIS, RST_RESKCPROT0);
+ clrbits_le32(RST_WDTRSTCR, RST_WWDT_RSTMSK | RST_RWDT_RSTMSK);
+
+ if (current_el() != 3)
+ return 0;
+ init_gic_v3();
+
+ return 0;
+}
+
+void __weak reset_cpu(void)
+{
+ writel(RST_KCPROT_DIS, RST_RESKCPROT0);
+ writel(0x1, RST_SWSRES1A);
+}
+
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+ return 0;
+}
diff --git a/board/renesas/ironhide/Kconfig b/board/renesas/ironhide/Kconfig
new file mode 100644
index 00000000000..34b596714f3
--- /dev/null
+++ b/board/renesas/ironhide/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_IRONHIDE
+
+config SYS_SOC
+ default "renesas"
+
+config SYS_BOARD
+ default "ironhide"
+
+config SYS_VENDOR
+ default "renesas"
+
+config SYS_CONFIG_NAME
+ default "ironhide"
+
+endif
diff --git a/board/samsung/e850-96/Makefile b/board/samsung/e850-96/Makefile
index 76b8d47994e..e9c62d3181f 100644
--- a/board/samsung/e850-96/Makefile
+++ b/board/samsung/e850-96/Makefile
@@ -3,4 +3,4 @@
# Copyright (C) 2024, Linaro Limited
# Sam Protsenko <[email protected]>
-obj-y := e850-96.o fw.o acpm.o pmic.o
+obj-y := e850-96.o fw.o acpm.o pmic.o bootdev.o
diff --git a/board/samsung/e850-96/bootdev.c b/board/samsung/e850-96/bootdev.c
new file mode 100644
index 00000000000..7d5ae7128f4
--- /dev/null
+++ b/board/samsung/e850-96/bootdev.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2025 Linaro Ltd.
+ * Author: Sam Protsenko <[email protected]>
+ *
+ * Routines for checking current boot device.
+ */
+
+#include <linux/arm-smccc.h>
+#include <vsprintf.h>
+#include "bootdev.h"
+
+/* Flag from BL2 bootloader in RAM */
+#define BL2_TAG_ADDR 0x80000000 /* DRAM base */
+#define BL2_TAG 0xabcdef
+
+/* Boot device info location in iRAM (only accessible from EL3) */
+#define IRAM_BASE 0x02020000
+#define BOOTDEVICE_INFO_ADDR (IRAM_BASE + 0x64)
+
+/* SMC call for getting boot device information from EL3 monitor */
+#define SMC_CMD_CHECK_SECOND_BOOT -233
+
+/* Boot device constants for the encoded boot device info value */
+#define BD_NO_DEVICE 0x0
+#define BD_UFS 0x1
+#define BD_EMMC 0x2
+#define BD_ERROR 0x3
+#define BD_USB 0x4
+#define BD_SDMMC 0x5
+#define BD_UFS_CARD 0x6
+#define BD_SPI 0x7
+
+/* If BL2 bootloader wasn't executed, it means U-Boot is running via JTAG */
+static bool bootdev_is_jtag_session(void)
+{
+ u32 bl2_tag_val = *(u32 *)BL2_TAG_ADDR;
+
+ return bl2_tag_val != BL2_TAG;
+}
+
+/* Obtain boot device information encoded in 32-bit value */
+static u32 bootdev_get_info(void)
+{
+ u32 info;
+
+ /*
+ * On regular boot U-Boot is executed by BL2 bootloader, and is running
+ * in EL1 mode, so the boot device information has to be obtained via
+ * SMC call from EL3 software (EL3 monitor), which can read that info
+ * from the protected iRAM memory. If U-Boot is running via TRACE32 JTAG
+ * (in EL3 mode), read the boot device info directly from iRAM, as EL3
+ * software might not be available.
+ */
+ if (bootdev_is_jtag_session()) {
+ info = *(u32 *)BOOTDEVICE_INFO_ADDR;
+ } else {
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(SMC_CMD_CHECK_SECOND_BOOT, 0, 0, 0, 0, 0, 0, 0,
+ &res);
+ info = (u32)res.a2;
+ }
+
+ return info;
+}
+
+enum bootdev bootdev_get_current(void)
+{
+ u32 info, magic, order, dev;
+
+ info = bootdev_get_info();
+ magic = info >> 24;
+ order = info & 0xf;
+ dev = (info >> (4 * order)) & 0xf;
+
+ if (magic != 0xcb)
+ panic("Abnormal boot");
+
+ switch (dev) {
+ case BD_UFS:
+ return BOOTDEV_UFS;
+ case BD_EMMC:
+ return BOOTDEV_EMMC;
+ case BD_USB:
+ return BOOTDEV_USB;
+ case BD_SDMMC:
+ return BOOTDEV_SD;
+ default:
+ return BOOTDEV_ERROR;
+ }
+
+ return BOOTDEV_ERROR;
+}
+
+bool bootdev_is_usb(void)
+{
+ return bootdev_get_current() == BOOTDEV_USB;
+}
diff --git a/board/samsung/e850-96/bootdev.h b/board/samsung/e850-96/bootdev.h
new file mode 100644
index 00000000000..5f454bf0090
--- /dev/null
+++ b/board/samsung/e850-96/bootdev.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2025 Linaro Ltd.
+ * Sam Protsenko <[email protected]>
+ */
+
+#ifndef __E850_96_BOOTDEV_H
+#define __E850_96_BOOTDEV_H
+
+#include <stdbool.h>
+
+enum bootdev {
+ BOOTDEV_ERROR,
+ BOOTDEV_SD,
+ BOOTDEV_EMMC,
+ BOOTDEV_USB,
+ BOOTDEV_UFS,
+};
+
+enum bootdev bootdev_get_current(void);
+bool bootdev_is_usb(void);
+
+#endif /* __E850_96_BOOTDEV_H */
diff --git a/board/samsung/e850-96/e850-96.c b/board/samsung/e850-96/e850-96.c
index 3df241edde2..415505f2561 100644
--- a/board/samsung/e850-96/e850-96.c
+++ b/board/samsung/e850-96/e850-96.c
@@ -11,6 +11,7 @@
#include <net.h>
#include <usb.h>
#include <asm/io.h>
+#include "bootdev.h"
#include "fw.h"
#include "pmic.h"
@@ -31,6 +32,10 @@
#define EMMC_DEV_NUM 0
#define EMMC_ESP_PART 1
+/* Firmware size */
+#define LDFW_MAX_SIZE SZ_4M
+#define SP_MAX_SIZE SZ_1M
+
struct efi_fw_image fw_images[] = {
{
.image_type_id = E850_96_FWBL1_IMAGE_GUID,
@@ -77,16 +82,6 @@ static struct acpm acpm = {
.ipc_ch = EXYNOS850_IPC_AP_I3C,
};
-int dram_init(void)
-{
- return fdtdec_setup_mem_size_base();
-}
-
-int dram_init_banksize(void)
-{
- return fdtdec_setup_memory_banksize();
-}
-
/* Read the unique SoC ID from OTP registers */
static u64 get_chip_id(void)
{
@@ -137,11 +132,34 @@ static void setup_ethaddr(void)
eth_env_set_enetaddr("ethaddr", mac_addr);
}
+static void load_firmware_usb(void)
+{
+ int err;
+
+ printf("Loading LDFW firmware (over USB)...\n");
+ err = load_image_usb(USB_DN_IMAGE_LDFW, LDFW_NWD_ADDR, LDFW_MAX_SIZE);
+ if (err) {
+ printf("ERROR: LDFW loading failed (%d)\n", err);
+ return;
+ }
+
+ err = init_ldfw(LDFW_NWD_ADDR);
+ if (err) {
+ printf("ERROR: LDFW init failed (%d)\n", err);
+ /* Do not return, still need to download SP */
+ }
+
+ printf("Loading SP firmware (over USB)...\n");
+ err = load_image_usb(USB_DN_IMAGE_SP, LDFW_NWD_ADDR, SP_MAX_SIZE);
+ if (err)
+ printf("ERROR: SP loading failed (%d)\n", err);
+}
+
/*
* Call this in board_late_init() to avoid probing block devices before
* efi_init_early().
*/
-void load_firmware(void)
+static void load_firmware_blk(void)
{
const char *ifname;
ulong dev, part;
@@ -161,16 +179,41 @@ void load_firmware(void)
}
printf("Loading LDFW firmware (from %s %ld)...\n", ifname, dev);
- err = load_ldfw(ifname, dev, part, LDFW_NWD_ADDR);
- if (err)
+ err = load_ldfw_from_blk(ifname, dev, part, LDFW_NWD_ADDR);
+ if (err) {
printf("ERROR: LDFW loading failed (%d)\n", err);
+ return;
+ }
+ err = init_ldfw(LDFW_NWD_ADDR);
+ if (err)
+ printf("ERROR: LDFW init failed (%d)\n", err);
+}
+
+int dram_init(void)
+{
+ return fdtdec_setup_mem_size_base();
+}
+
+int dram_init_banksize(void)
+{
+ return fdtdec_setup_memory_banksize();
}
int board_late_init(void)
{
setup_serial();
setup_ethaddr();
- load_firmware();
+
+ if (bootdev_is_usb())
+ load_firmware_usb();
+ else
+ load_firmware_blk();
+
+ if (bootdev_is_usb()) {
+ env_set("bootcmd", "echo \"Entering DFU mode...\"; "
+ "dfu 0 mmc 0");
+ env_set("bootdelay", "0");
+ }
return 0;
}
diff --git a/board/samsung/e850-96/fw.c b/board/samsung/e850-96/fw.c
index 64235c01a25..576167122ec 100644
--- a/board/samsung/e850-96/fw.c
+++ b/board/samsung/e850-96/fw.c
@@ -11,14 +11,19 @@
#include <linux/arm-smccc.h>
#include "fw.h"
-#define LDFW_RAW_PART "ldfw"
-#define LDFW_FAT_PATH "/EFI/firmware/ldfw.bin"
+#define LDFW_RAW_PART "ldfw"
+#define LDFW_FAT_PATH "/EFI/firmware/ldfw.bin"
+#define LDFW_MAGIC 0x10adab1e
-#define LDFW_MAGIC 0x10adab1e
-#define SMC_CMD_LOAD_LDFW -0x500
-#define SDM_HW_RESET_STATUS 0x1230
-#define SDM_SW_RESET_STATUS 0x1231
-#define SB_ERROR_PREFIX 0xfdaa0000
+/* SMC command for providing LDFW to EL3 monitor */
+#define SMC_CMD_LOAD_LDFW -0x500
+/* SMC command for loading some binary over USB */
+#define SMC_CMD_LOAD_IMAGE_BY_USB -0x512
+
+/* Error codes for SMC_CMD_LOAD_LDFW */
+#define SDM_HW_RESET_STATUS 0x1230
+#define SDM_SW_RESET_STATUS 0x1231
+#define SB_ERROR_PREFIX 0xfdaa0000
struct ldfw_header {
u32 magic;
@@ -94,7 +99,27 @@ static int read_fw_from_raw(const char *ifname, int dev, const char *part_name,
}
/**
- * load_ldfw - Load the loadable firmware (LDFW)
+ * load_image_usb - Load some binary over USB during USB boot
+ * @type: Image type
+ * @addr: Memory address where the image should be downloaded to
+ * @size: Image size
+ *
+ * Return: 0 on success or a negative value on error.
+ */
+int load_image_usb(enum usb_dn_image type, phys_addr_t addr, phys_size_t size)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(SMC_CMD_LOAD_IMAGE_BY_USB, (u64)type, addr, size,
+ 0, 0, 0, 0, &res);
+ if (res.a0)
+ return -EIO;
+
+ return 0;
+}
+
+/**
+ * load_ldfw_from_blk - Load the loadable firmware (LDFW) from block device
* @ifname: Interface name of the block device to load the firmware from
* @dev: Device number
* @part: Partition number
@@ -102,24 +127,37 @@ static int read_fw_from_raw(const char *ifname, int dev, const char *part_name,
*
* Return: 0 on success or a negative value on error.
*/
-int load_ldfw(const char *ifname, int dev, int part, phys_addr_t addr)
+int load_ldfw_from_blk(const char *ifname, int dev, int part, phys_addr_t addr)
{
- struct ldfw_header *hdr;
- struct arm_smccc_res res;
void *buf = (void *)addr;
- u64 size = 0;
- int err, i;
+ int err;
/* First try to read LDFW from EFI partition, then from the raw one */
err = read_fw_from_fat(ifname, dev, part, LDFW_FAT_PATH, buf);
- if (err) {
- err = read_fw_from_raw(ifname, dev, LDFW_RAW_PART, buf);
- if (err)
- return err;
- }
+ if (err)
+ return read_fw_from_raw(ifname, dev, LDFW_RAW_PART, buf);
+
+ return 0;
+}
+
+/**
+ * init_ldfw - Provide the LDFW (loaded to RAM) to EL3 monitor to make use of it
+ * @addr: Memory address where LDFW resides
+ *
+ * EL3 monitor will copy the LDFW from the provided Normal World memory @addr to
+ * Secure World location, and start using it.
+ *
+ * Return: 0 on success or a negative value on error.
+ */
+int init_ldfw(phys_addr_t addr)
+{
+ struct ldfw_header *hdr;
+ struct arm_smccc_res res;
+ u64 size = 0;
+ int err, i;
/* Validate LDFW by magic number in its header */
- hdr = buf;
+ hdr = (struct ldfw_header *)addr;
if (hdr->magic != LDFW_MAGIC) {
debug("%s: Wrong LDFW magic; is LDFW flashed?\n", __func__);
return -EINVAL;
diff --git a/board/samsung/e850-96/fw.h b/board/samsung/e850-96/fw.h
index 73d9615d4a9..68f943e8bbc 100644
--- a/board/samsung/e850-96/fw.h
+++ b/board/samsung/e850-96/fw.h
@@ -9,6 +9,14 @@
#include <asm/types.h>
-int load_ldfw(const char *ifname, int dev, int part, phys_addr_t addr);
+/* Image types for downloading over USB */
+enum usb_dn_image {
+ USB_DN_IMAGE_LDFW = 1, /* Loadable Firmware */
+ USB_DN_IMAGE_SP = 2, /* Secure Payload (tzsw.img) */
+};
+
+int load_image_usb(enum usb_dn_image type, phys_addr_t addr, phys_size_t size);
+int load_ldfw_from_blk(const char *ifname, int dev, int part, phys_addr_t addr);
+int init_ldfw(phys_addr_t addr);
#endif /* __E850_96_FW_H */
diff --git a/board/samsung/exynos-mobile/Kconfig b/board/samsung/exynos-mobile/Kconfig
new file mode 100644
index 00000000000..ed7d16b8c6b
--- /dev/null
+++ b/board/samsung/exynos-mobile/Kconfig
@@ -0,0 +1,18 @@
+if TARGET_EXYNOS_MOBILE
+
+config ENV_SOURCE_FILE
+ default "exynos-mobile"
+
+config LNX_KRNL_IMG_TEXT_OFFSET_BASE
+ default TEXT_BASE
+
+config SYS_BOARD
+ default "exynos-mobile"
+
+config SYS_CONFIG_NAME
+ default "exynos-mobile"
+
+config SYS_VENDOR
+ default "samsung"
+
+endif # TARGET_EXYNOS_MOBILE
diff --git a/board/samsung/exynos-mobile/MAINTAINERS b/board/samsung/exynos-mobile/MAINTAINERS
new file mode 100644
index 00000000000..11fea212fb1
--- /dev/null
+++ b/board/samsung/exynos-mobile/MAINTAINERS
@@ -0,0 +1,6 @@
+Exynos Generic Boards (for mobile devices)
+M: Kaustabh Chakraborty <[email protected]>
+S: Maintained
+F: board/samsung/exynos-mobile/
+F: configs/exynos-mobile_defconfig
+F: include/configs/exynos-mobile.h
diff --git a/board/samsung/exynos-mobile/Makefile b/board/samsung/exynos-mobile/Makefile
new file mode 100644
index 00000000000..e049ed217c1
--- /dev/null
+++ b/board/samsung/exynos-mobile/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2025 Kaustabh Chakraborty <[email protected]>
+
+obj-y := exynos-mobile.o
diff --git a/board/samsung/exynos-mobile/debug-exynos7870.config b/board/samsung/exynos-mobile/debug-exynos7870.config
new file mode 100644
index 00000000000..1aa506a675d
--- /dev/null
+++ b/board/samsung/exynos-mobile/debug-exynos7870.config
@@ -0,0 +1,7 @@
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_BASE=0x13820000
+CONFIG_DEBUG_UART_CLOCK=133250000
+CONFIG_DEBUG_UART_S5P=y
+CONFIG_LOG=y
+CONFIG_LOG_CONSOLE=y
+CONFIG_LOG_MAX_LEVEL=8
diff --git a/board/samsung/exynos-mobile/exynos-mobile.c b/board/samsung/exynos-mobile/exynos-mobile.c
new file mode 100644
index 00000000000..8ef38816abf
--- /dev/null
+++ b/board/samsung/exynos-mobile/exynos-mobile.c
@@ -0,0 +1,403 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung Exynos Generic Board Source (for mobile devices)
+ *
+ * Copyright (c) 2025 Kaustabh Chakraborty <[email protected]>
+ */
+
+#include <asm/armv8/mmu.h>
+#include <blk.h>
+#include <bootflow.h>
+#include <ctype.h>
+#include <dm/ofnode.h>
+#include <env.h>
+#include <errno.h>
+#include <init.h>
+#include <limits.h>
+#include <linux/sizes.h>
+#include <lmb.h>
+#include <part.h>
+#include <stdbool.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define lmb_alloc(size, addr) \
+ lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, addr, size, LMB_NONE)
+
+struct exynos_board_info {
+ const char *name;
+ const char *chip;
+ const u64 *const dram_bank_bases;
+
+ char serial[64];
+
+ int (*const match)(struct exynos_board_info *);
+ const char *match_model;
+ const u8 match_max_rev;
+};
+
+/*
+ * The memory mapping includes all DRAM banks, along with the
+ * peripheral block, and a sentinel at the end. This is filled in
+ * dynamically.
+ */
+static struct mm_region exynos_mem_map[CONFIG_NR_DRAM_BANKS + 2] = {
+ {
+ /* Peripheral MMIO block */
+ .virt = 0x10000000UL,
+ .phys = 0x10000000UL,
+ .size = 0x10000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN,
+ },
+};
+
+struct mm_region *mem_map = exynos_mem_map;
+
+static const u64 exynos7870_common_dram_bank_bases[CONFIG_NR_DRAM_BANKS] = {
+ 0x40000000, 0x80000000, 0x100000000,
+};
+
+static const char *exynos_prev_bl_get_bootargs(void)
+{
+ void *prev_bl_fdt_base = (void *)get_prev_bl_fdt_addr();
+ int chosen_node_offset, ret;
+ const struct fdt_property *bootargs_prop;
+
+ ret = fdt_check_header(prev_bl_fdt_base);
+ if (ret < 0) {
+ log_err("%s: FDT is invalid (FDT_ERR %d)\n", __func__, ret);
+ return NULL;
+ }
+
+ ret = fdt_path_offset(prev_bl_fdt_base, "/chosen");
+ chosen_node_offset = ret;
+ if (ret < 0) {
+ log_err("%s: /chosen node not found (FDT_ERR %d)\n", __func__,
+ ret);
+ return NULL;
+ }
+
+ bootargs_prop = fdt_get_property(prev_bl_fdt_base, chosen_node_offset,
+ "bootargs", &ret);
+ if (!bootargs_prop) {
+ log_err("%s: /chosen/bootargs property not found (FDT_ERR %d)\n",
+ __func__, ret);
+ return NULL;
+ }
+
+ return bootargs_prop->data;
+}
+
+static int exynos7870_fdt_match(struct exynos_board_info *board_info)
+{
+ const char *prev_bl_bootargs;
+ int val, ret;
+
+ prev_bl_bootargs = exynos_prev_bl_get_bootargs();
+ if (!prev_bl_bootargs)
+ return -1;
+
+ /*
+ * Read the cmdline property which stores the
+ * bootloader/firmware version. An example value of the option
+ * can be: "J600GDXU3ARH5". This can be used to verify the model
+ * of the device.
+ */
+ ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.bootloader", &val);
+ if (ret < 0) {
+ log_err("%s: unable to find property for bootloader version (%d)\n",
+ __func__, ret);
+ return -1;
+ }
+
+ if (strncmp(prev_bl_bootargs + val, board_info->match_model,
+ strlen(board_info->match_model)))
+ return -1;
+
+ /*
+ * Read the cmdline property which stores the hardware revision.
+ * This is required to allow selecting one of multiple dtbs
+ * available of a single device, varying in hardware changes in
+ * different revisions.
+ */
+ ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.revision", &val);
+ if (ret < 0)
+ ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.hw_rev", &val);
+ if (ret < 0) {
+ log_err("%s: unable to find property for bootloader revision (%d)\n",
+ __func__, ret);
+ return -1;
+ }
+
+ if (strtoul(prev_bl_bootargs + val, NULL, 10) > board_info->match_max_rev)
+ return -1;
+
+ /*
+ * Read the cmdline property which stores the serial number.
+ * Store this in the board info struct.
+ */
+ ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.serialno", &val);
+ if (ret > 0)
+ strlcpy(board_info->serial, prev_bl_bootargs + val, ret);
+
+ return 0;
+}
+
+/*
+ * This array is used for matching the models and revisions with the
+ * devicetree used by U-Boot. This allows a single U-Boot to work on
+ * multiple devices.
+ *
+ * Entries are kept in lexicographical order of board SoCs, followed by
+ * board names.
+ */
+static struct exynos_board_info exynos_board_info_match[] = {
+ {
+ /* Samsung Galaxy A2 Core */
+ .name = "a2corelte",
+ .chip = "exynos7870",
+ .dram_bank_bases = exynos7870_common_dram_bank_bases,
+ .match = exynos7870_fdt_match,
+ .match_model = "A260",
+ .match_max_rev = U8_MAX,
+ }, {
+ /* Samsung Galaxy J6 */
+ .name = "j6lte",
+ .chip = "exynos7870",
+ .dram_bank_bases = exynos7870_common_dram_bank_bases,
+ .match = exynos7870_fdt_match,
+ .match_model = "J600",
+ .match_max_rev = U8_MAX,
+ }, {
+ /* Samsung Galaxy J7 Prime */
+ .name = "on7xelte",
+ .chip = "exynos7870",
+ .dram_bank_bases = exynos7870_common_dram_bank_bases,
+ .match = exynos7870_fdt_match,
+ .match_model = "G610",
+ .match_max_rev = U8_MAX,
+ },
+};
+
+static void exynos_parse_dram_banks(const struct exynos_board_info *board_info,
+ const void *fdt_base)
+{
+ u64 mem_addr, mem_size = 0;
+ u32 na, ns, i, j;
+ int offset;
+
+ if (fdt_check_header(fdt_base) < 0)
+ return;
+
+ /* #address-cells and #size-cells as defined in the fdt root. */
+ na = fdt_address_cells(fdt_base, 0);
+ ns = fdt_size_cells(fdt_base, 0);
+
+ fdt_for_each_subnode(offset, fdt_base, 0) {
+ if (strncmp(fdt_get_name(fdt_base, offset, NULL), "memory", 6))
+ continue;
+
+ for (i = 0; ; i++) {
+ mem_addr = fdtdec_get_addr_size_fixed(fdt_base, offset,
+ "reg", i, na, ns,
+ &mem_size, false);
+ if (mem_addr == FDT_ADDR_T_NONE)
+ break;
+
+ if (!mem_size)
+ continue;
+
+ for (j = 0; j < CONFIG_NR_DRAM_BANKS; j++) {
+ if (board_info->dram_bank_bases[j] != mem_addr)
+ continue;
+
+ mem_map[j + 1].phys = mem_addr;
+ mem_map[j + 1].virt = mem_addr;
+ mem_map[j + 1].size = mem_size;
+ mem_map[j + 1].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE;
+ break;
+ }
+ }
+ }
+}
+
+static int exynos_fastboot_setup(void)
+{
+ struct blk_desc *blk_dev;
+ struct disk_partition info = {0};
+ char buf[128];
+ phys_addr_t addr;
+ int offset, i, j;
+
+ /* Allocate and define buffer address for fastboot interface. */
+ if (lmb_alloc(CONFIG_FASTBOOT_BUF_SIZE, &addr)) {
+ log_err("%s: failed to allocate fastboot buffer\n", __func__);
+ return -ENOMEM;
+ }
+ env_set_hex("fastboot_addr_r", addr);
+
+ blk_dev = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
+ if (!blk_dev) {
+ log_err("%s: required mmc device not available\n", __func__);
+ return -ENODEV;
+ }
+
+ strcpy(buf, "fastboot_partition_alias_");
+ offset = strlen(buf);
+
+ for (i = 1; i < CONFIG_EFI_PARTITION_ENTRIES_NUMBERS; i++) {
+ if (part_get_info(blk_dev, i, &info))
+ continue;
+
+ /*
+ * The partition name must be lowercase (stored in buf[]),
+ * as is expected in all fastboot partitions ...
+ */
+ strlcpy(buf + offset, info.name, sizeof(buf) - offset);
+ for (j = offset; buf[j]; j++)
+ buf[j] = tolower(buf[j]);
+ if (!strcmp(buf + offset, info.name))
+ continue;
+ /*
+ * ... However, if that isn't the case, a fastboot
+ * partition alias must be defined to establish it.
+ */
+ env_set(buf, info.name);
+ }
+
+ return 0;
+}
+
+int board_fit_config_name_match(const char *name)
+{
+ struct exynos_board_info *board_info;
+ char buf[128];
+ unsigned int i;
+ int ret;
+
+ /*
+ * Iterate over exynos_board_info_match[] to select the
+ * appropriate board info struct. If not found, exit.
+ */
+ for (i = 0; i < ARRAY_SIZE(exynos_board_info_match); i++) {
+ board_info = exynos_board_info_match + i;
+ snprintf(buf, sizeof(buf), "%s-%s", board_info->chip,
+ board_info->name);
+
+ if (!strcmp(name, buf))
+ break;
+ }
+ if (i == ARRAY_SIZE(exynos_board_info_match))
+ return -1;
+
+ /*
+ * Execute match logic for the target board. This is separated
+ * as the process may be different for multiple boards.
+ */
+ ret = board_info->match(board_info);
+ if (ret)
+ return ret;
+
+ /*
+ * Store the correct board info struct in gd->board_type to
+ * allow other functions to access it.
+ */
+ gd->board_type = (ulong)board_info;
+ log_debug("%s: device detected: %s\n", __func__, name);
+
+ return 0;
+}
+
+int timer_init(void)
+{
+ ofnode timer_node;
+
+ /*
+ * In a lot of Exynos devices, the previous bootloader does not
+ * set CNTFRQ_EL0 properly. However, the timer node in
+ * devicetree has the correct frequency, use that instead.
+ */
+ timer_node = ofnode_by_compatible(ofnode_null(), "arm,armv8-timer");
+ gd->arch.timer_rate_hz = ofnode_read_u32_default(timer_node,
+ "clock-frequency", 0);
+
+ return 0;
+}
+
+int board_early_init_f(void)
+{
+ const struct exynos_board_info *board_info;
+
+ if (!gd->board_type)
+ return -ENODATA;
+ board_info = (const struct exynos_board_info *)gd->board_type;
+
+ exynos_parse_dram_banks(board_info, gd->fdt_blob);
+ /*
+ * Some devices have multiple variants based on the amount of
+ * memory and internal storage. The lowest bank base has been
+ * observed to have the same memory range in all board variants.
+ * For variants with more memory, the previous bootloader should
+ * overlay the devicetree with the required extra memory ranges.
+ */
+ exynos_parse_dram_banks(board_info, (const void *)get_prev_bl_fdt_addr());
+
+ return 0;
+}
+
+int dram_init(void)
+{
+ unsigned int i;
+
+ /* Select the largest RAM bank for U-Boot. */
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+ if (gd->ram_size < mem_map[i + 1].size) {
+ gd->ram_base = mem_map[i + 1].phys;
+ gd->ram_size = mem_map[i + 1].size;
+ }
+ }
+
+ return 0;
+}
+
+int dram_init_banksize(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+ gd->bd->bi_dram[i].start = mem_map[i + 1].phys;
+ gd->bd->bi_dram[i].size = mem_map[i + 1].size;
+ }
+
+ return 0;
+}
+
+int board_init(void)
+{
+ return 0;
+}
+
+int misc_init_r(void)
+{
+ const struct exynos_board_info *board_info;
+ char buf[128];
+
+ if (!gd->board_type)
+ return -ENODATA;
+ board_info = (const struct exynos_board_info *)gd->board_type;
+
+ env_set("platform", board_info->chip);
+ env_set("board", board_info->name);
+
+ if (strlen(board_info->serial))
+ env_set("serial#", board_info->serial);
+
+ /* EFI booting requires the path to correct dtb, specify it here. */
+ snprintf(buf, sizeof(buf), "exynos/%s-%s.dtb", board_info->chip,
+ board_info->name);
+ env_set("fdtfile", buf);
+
+ return exynos_fastboot_setup();
+}
diff --git a/board/samsung/exynos-mobile/exynos-mobile.env b/board/samsung/exynos-mobile/exynos-mobile.env
new file mode 100644
index 00000000000..aa2e89afbac
--- /dev/null
+++ b/board/samsung/exynos-mobile/exynos-mobile.env
@@ -0,0 +1,18 @@
+stdin=serial,button-kbd
+stdout=serial,vidconsole
+stderr=serial,vidconsole
+
+bootdelay=0
+bootcmd=bootefi bootmgr; pause; bootmenu
+
+fastbootcmd=echo "Fastboot Mode";
+ fastboot -l $fastboot_addr_r usb 0
+
+bootmenu_0=Continue Boot=boot
+bootmenu_1=Enter Fastboot Mode=run fastbootcmd
+bootmenu_2=UEFI Maintenance Menu=eficonfig
+bootmenu_3=Reboot=reset
+bootmenu_4=Power Off=poweroff
+
+button_cmd_0_name=Volume Down Key
+button_cmd_0=bootmenu
diff --git a/board/softing/vining_fpga/socfpga.c b/board/softing/vining_fpga/socfpga.c
index ec2c7ea3631..475c19f2781 100644
--- a/board/softing/vining_fpga/socfpga.c
+++ b/board/softing/vining_fpga/socfpga.c
@@ -8,7 +8,7 @@
#include <env.h>
#include <init.h>
#include <net.h>
-#include <status_led.h>
+#include <led.h>
#include <asm/arch/reset_manager.h>
#include <asm/global_data.h>
#include <asm/io.h>
@@ -24,10 +24,16 @@ DECLARE_GLOBAL_DATA_PTR;
int board_late_init(void)
{
const unsigned int usb_nrst_gpio = 35;
+ struct udevice *dev;
int ret;
- status_led_set(1, CONFIG_LED_STATUS_ON);
- status_led_set(2, CONFIG_LED_STATUS_ON);
+ ret = led_get_by_label("status_1", &dev);
+ if (!ret)
+ led_set_state(dev, LEDST_ON);
+
+ ret = led_get_by_label("status_2", &dev);
+ if (!ret)
+ led_set_state(dev, LEDST_ON);
/* Address of boot parameters for ATAG (if ATAG is used) */
gd->bd->bi_boot_params = CFG_SYS_SDRAM_BASE + 0x100;
diff --git a/board/ti/am335x/board.c b/board/ti/am335x/board.c
index 712818ec235..90e37a8d913 100644
--- a/board/ti/am335x/board.c
+++ b/board/ti/am335x/board.c
@@ -429,7 +429,7 @@ void scale_vcores_generic(int freq)
{
int sil_rev, mpu_vdd;
- if (!IS_ENABLED(CONFIG_DM_PMIC_TPS65910))
+ if (!IS_ENABLED(CONFIG_SPL_POWER_TPS65910))
return;
/*
diff --git a/board/ti/am62x/evm.c b/board/ti/am62x/evm.c
index 6bb243ee597..e9eba57eba7 100644
--- a/board/ti/am62x/evm.c
+++ b/board/ti/am62x/evm.c
@@ -82,11 +82,16 @@ struct efi_capsule_update_info update_info = {
};
#if CONFIG_IS_ENABLED(TI_I2C_BOARD_DETECT)
+int do_board_detect(void)
+{
+ return do_board_detect_am6();
+}
+
int checkboard(void)
{
struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
- if (!do_board_detect_am6())
+ if (!do_board_detect())
printf("Board: %s rev %s\n", ep->name, ep->version);
return 0;
@@ -97,7 +102,7 @@ static void setup_board_eeprom_env(void)
{
char *name = "am62x_skevm";
- if (do_board_detect_am6())
+ if (do_board_detect())
goto invalid_eeprom;
if (board_is_am62x_skevm())
diff --git a/board/ti/am64x/evm.c b/board/ti/am64x/evm.c
index 3688cf2ca25..25076a8a588 100644
--- a/board/ti/am64x/evm.c
+++ b/board/ti/am64x/evm.c
@@ -114,11 +114,16 @@ void spl_perform_board_fixups(struct spl_image_info *spl_image)
#endif
#ifdef CONFIG_TI_I2C_BOARD_DETECT
+int do_board_detect(void)
+{
+ return do_board_detect_am6();
+}
+
int checkboard(void)
{
struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
- if (!do_board_detect_am6())
+ if (!do_board_detect())
printf("Board: %s rev %s\n", ep->name, ep->version);
return 0;
@@ -135,7 +140,7 @@ static void setup_board_eeprom_env(void)
{
char *name = "am64x_gpevm";
- if (do_board_detect_am6())
+ if (do_board_detect())
goto invalid_eeprom;
if (board_is_am64x_gpevm())
diff --git a/board/ti/am65x/evm.c b/board/ti/am65x/evm.c
index 68606746d5f..b35a9229033 100644
--- a/board/ti/am65x/evm.c
+++ b/board/ti/am65x/evm.c
@@ -72,11 +72,16 @@ int board_fit_config_name_match(const char *name)
#endif
#ifdef CONFIG_TI_I2C_BOARD_DETECT
+int do_board_detect(void)
+{
+ return do_board_detect_am6();
+}
+
int checkboard(void)
{
struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
- if (do_board_detect_am6())
+ if (do_board_detect())
/* EEPROM not populated */
printf("Board: %s rev %s\n", "AM6-COMPROCEVM", "E3");
else
@@ -89,7 +94,7 @@ static void setup_board_eeprom_env(void)
{
char *name = "am65x";
- if (do_board_detect_am6())
+ if (do_board_detect())
goto invalid_eeprom;
if (board_is_am65x_base_board())
diff --git a/board/ti/common/board_detect.c b/board/ti/common/board_detect.c
index d49e26fa453..a235ea9ef21 100644
--- a/board/ti/common/board_detect.c
+++ b/board/ti/common/board_detect.c
@@ -825,7 +825,7 @@ bool __maybe_unused board_ti_was_eeprom_read(void)
return false;
}
-#if CONFIG_IS_ENABLED(TI_I2C_BOARD_DETECT)
+#if IS_ENABLED(CONFIG_TI_I2C_BOARD_DETECT)
int do_board_detect_am6(void)
{
int ret;
diff --git a/board/ti/omap3evm/MAINTAINERS b/board/ti/omap3evm/MAINTAINERS
index fb4268b312f..491ab4fbed7 100644
--- a/board/ti/omap3evm/MAINTAINERS
+++ b/board/ti/omap3evm/MAINTAINERS
@@ -1,5 +1,5 @@
EVM BOARD
-M: Derald D. Woods <[email protected]>
+M: Tom Rini <[email protected]>
S: Maintained
F: board/ti/omap3evm/
F: include/configs/omap3_evm.h
diff --git a/boot/bootmeth_rauc.c b/boot/bootmeth_rauc.c
index f5d5a971e87..833715e1395 100644
--- a/boot/bootmeth_rauc.c
+++ b/boot/bootmeth_rauc.c
@@ -17,6 +17,7 @@
#include <fs.h>
#include <malloc.h>
#include <mapmem.h>
+#include <part.h>
#include <string.h>
#include <linux/stringify.h>
#include <asm/cache.h>
@@ -98,6 +99,7 @@ static int distro_rauc_scan_parts(struct bootflow *bflow)
struct distro_rauc_priv *priv;
char *boot_order;
const char **boot_order_list;
+ bool slot_found = false;
int ret;
int i;
@@ -119,17 +121,20 @@ static int distro_rauc_scan_parts(struct bootflow *bflow)
if (desc) {
ret = fs_set_blk_dev_with_part(desc, slot->boot_part);
if (ret)
- return log_msg_ret("part", ret);
+ continue;
fs_close();
- ret = fs_set_blk_dev_with_part(desc, slot->root_part);
+ ret = part_get_info(desc, slot->root_part, NULL);
if (ret)
- return log_msg_ret("part", ret);
- fs_close();
+ continue;
+ slot_found = true;
}
}
str_free_list(boot_order_list);
- return 0;
+ if (slot_found)
+ return 0;
+
+ return -1;
}
static int distro_rauc_read_bootflow(struct udevice *dev, struct bootflow *bflow)
diff --git a/boot/fdt_support.c b/boot/fdt_support.c
index 92f2f534ee0..1c215e548db 100644
--- a/boot/fdt_support.c
+++ b/boot/fdt_support.c
@@ -27,6 +27,7 @@
#include <fdtdec.h>
#include <version.h>
#include <video.h>
+#include <smbios.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -333,6 +334,7 @@ int fdt_chosen(void *fdt)
int nodeoffset;
int err;
const char *str; /* used to set string properties */
+ ulong smbiosaddr; /* SMBIOS table address */
err = fdt_check_header(fdt);
if (err < 0) {
@@ -387,6 +389,23 @@ int fdt_chosen(void *fdt)
return err;
}
+ if (CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)) {
+ /* Inject SMBIOS address when we have a valid address.
+ * This is useful for systems using booti/bootm instead of bootefi.
+ * Failure to set this property is non-fatal, we only generate a
+ * warning.
+ */
+ smbiosaddr = gd_smbios_start();
+ if (smbiosaddr) {
+ err = fdt_setprop_u64(fdt, nodeoffset, "smbios3-entrypoint",
+ smbiosaddr);
+ if (err < 0) {
+ printf("WARNING: could not set smbios3-entrypoint %s.\n",
+ fdt_strerror(err));
+ }
+ }
+ }
+
return fdt_fixup_stdout(fdt, nodeoffset);
}
diff --git a/cmd/extension_board.c b/cmd/extension_board.c
index 86e4795ba8a..75358abf666 100644
--- a/cmd/extension_board.c
+++ b/cmd/extension_board.c
@@ -99,6 +99,10 @@ static int do_extension_list(struct cmd_tbl *cmdtp, int flag,
int i = 0;
extension_list = extension_get_list();
+ if (!extension_list) {
+ printf("No extension device\n");
+ return CMD_RET_FAILURE;
+ }
if (!alist_get_ptr(extension_list, 0)) {
printf("No extension registered - Please run \"extension scan\"\n");
return CMD_RET_SUCCESS;
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 8dade2b501e..3b7b6cafef8 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -545,7 +545,7 @@ config SPL_SYS_MMCSD_RAW_MODE
depends on SPL_DM_MMC || SPL_MMC
default y if ARCH_SUNXI || ARCH_DAVINCI || ARCH_UNIPHIER || \
ARCH_MX6 || ARCH_MX7 || \
- ARCH_ROCKCHIP || ARCH_MVEBU || ARCH_SOCFPGA || \
+ ARCH_ROCKCHIP || ARCH_MVEBU || TARGET_SOCFPGA_GEN5 || \
ARCH_AT91 || ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || \
OMAP54XX || AM33XX || AM43XX || \
TARGET_SIFIVE_UNLEASHED || TARGET_SIFIVE_UNMATCHED
@@ -589,7 +589,7 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
default 0x8a if ARCH_MX6 || ARCH_MX7
default 0x100 if ARCH_UNIPHIER
default 0x0 if ARCH_MVEBU
- default 0x200 if ARCH_SOCFPGA || ARCH_AT91
+ default 0x200 if TARGET_SOCFPGA_GEN5 || ARCH_AT91
default 0x300 if ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || \
OMAP54XX || AM33XX || AM43XX || ARCH_K3
default 0x4000 if ARCH_ROCKCHIP
diff --git a/configs/apalis-tk1_defconfig b/configs/apalis-tk1_defconfig
index 846c7bde234..14d98041980 100644
--- a/configs/apalis-tk1_defconfig
+++ b/configs/apalis-tk1_defconfig
@@ -3,8 +3,8 @@ CONFIG_SYS_L2CACHE_OFF=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x80110000
CONFIG_SYS_MALLOC_F_LEN=0x2000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="apalis-tk1"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0xFFFFDE00
CONFIG_DEFAULT_DEVICE_TREE="tegra124-apalis"
diff --git a/configs/apalis_t30_defconfig b/configs/apalis_t30_defconfig
index 57e1eb733a8..f98582fca16 100644
--- a/configs/apalis_t30_defconfig
+++ b/configs/apalis_t30_defconfig
@@ -3,8 +3,8 @@ CONFIG_SYS_L2CACHE_OFF=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x80110000
CONFIG_SYS_MALLOC_F_LEN=0x2000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="apalis_t30"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0xFFFFDE00
CONFIG_DEFAULT_DEVICE_TREE="tegra30-apalis"
diff --git a/configs/brcp150_defconfig b/configs/brcp150_defconfig
index bae185e8126..84cf7c8067e 100644
--- a/configs/brcp150_defconfig
+++ b/configs/brcp150_defconfig
@@ -6,8 +6,8 @@ CONFIG_ARCH_ZYNQ=y
CONFIG_TEXT_BASE=0x4000000
CONFIG_SYS_MALLOC_F_LEN=0x1000
CONFIG_SPL_GPIO=y
-CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SOURCE_FILE="env/brcp150"
+CONFIG_NR_DRAM_BANKS=1
CONFIG_SF_DEFAULT_SPEED=100000000
CONFIG_SF_DEFAULT_MODE=0x3
CONFIG_ENV_SIZE=0x10000
diff --git a/configs/brcp170_defconfig b/configs/brcp170_defconfig
index f8e17ece276..ea7c239ac94 100644
--- a/configs/brcp170_defconfig
+++ b/configs/brcp170_defconfig
@@ -6,8 +6,8 @@ CONFIG_ARCH_ZYNQ=y
CONFIG_TEXT_BASE=0x4000000
CONFIG_SYS_MALLOC_F_LEN=0x1000
CONFIG_SPL_GPIO=y
-CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SOURCE_FILE="env/brcp1"
+CONFIG_NR_DRAM_BANKS=1
CONFIG_SF_DEFAULT_SPEED=100000000
CONFIG_SF_DEFAULT_MODE=0x3
CONFIG_ENV_SIZE=0x10000
diff --git a/configs/brcp1_1r_defconfig b/configs/brcp1_1r_defconfig
index 568313d4860..af87780a68a 100644
--- a/configs/brcp1_1r_defconfig
+++ b/configs/brcp1_1r_defconfig
@@ -6,8 +6,8 @@ CONFIG_ARCH_ZYNQ=y
CONFIG_TEXT_BASE=0x4000000
CONFIG_SYS_MALLOC_F_LEN=0x1000
CONFIG_SPL_GPIO=y
-CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SOURCE_FILE="env/brcp1"
+CONFIG_NR_DRAM_BANKS=1
CONFIG_SF_DEFAULT_SPEED=100000000
CONFIG_SF_DEFAULT_MODE=0x3
CONFIG_ENV_SIZE=0x10000
diff --git a/configs/brcp1_1r_switch_defconfig b/configs/brcp1_1r_switch_defconfig
index 805de796df6..6162ca6b5bb 100644
--- a/configs/brcp1_1r_switch_defconfig
+++ b/configs/brcp1_1r_switch_defconfig
@@ -6,8 +6,8 @@ CONFIG_ARCH_ZYNQ=y
CONFIG_TEXT_BASE=0x4000000
CONFIG_SYS_MALLOC_F_LEN=0x1000
CONFIG_SPL_GPIO=y
-CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SOURCE_FILE="env/brcp1"
+CONFIG_NR_DRAM_BANKS=1
CONFIG_SF_DEFAULT_SPEED=100000000
CONFIG_SF_DEFAULT_MODE=0x3
CONFIG_ENV_SIZE=0x10000
diff --git a/configs/brcp1_2r_defconfig b/configs/brcp1_2r_defconfig
index e92d8381bbb..95e185f6ac6 100644
--- a/configs/brcp1_2r_defconfig
+++ b/configs/brcp1_2r_defconfig
@@ -6,8 +6,8 @@ CONFIG_ARCH_ZYNQ=y
CONFIG_TEXT_BASE=0x4000000
CONFIG_SYS_MALLOC_F_LEN=0x1000
CONFIG_SPL_GPIO=y
-CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SOURCE_FILE="env/brcp1"
+CONFIG_NR_DRAM_BANKS=1
CONFIG_SF_DEFAULT_SPEED=100000000
CONFIG_SF_DEFAULT_MODE=0x3
CONFIG_ENV_SIZE=0x10000
diff --git a/configs/brsmarc2_defconfig b/configs/brsmarc2_defconfig
index 2ed54817af4..0e85ea594d7 100644
--- a/configs/brsmarc2_defconfig
+++ b/configs/brsmarc2_defconfig
@@ -8,8 +8,8 @@ CONFIG_INITRD_TAG=y
CONFIG_TEXT_BASE=0x4000000
CONFIG_SYS_MALLOC_F_LEN=0x1000
CONFIG_SPL_GPIO=y
-CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SOURCE_FILE="env/brcp1"
+CONFIG_NR_DRAM_BANKS=1
CONFIG_SF_DEFAULT_SPEED=100000000
CONFIG_SF_DEFAULT_MODE=0x3
CONFIG_ENV_SIZE=0x10000
diff --git a/configs/cardhu_defconfig b/configs/cardhu_defconfig
index 318fbaa529b..9deed0a1e93 100644
--- a/configs/cardhu_defconfig
+++ b/configs/cardhu_defconfig
@@ -3,8 +3,8 @@ CONFIG_SYS_HAS_NONCACHED_MEMORY=y
CONFIG_SYS_L2CACHE_OFF=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x80110000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="cardhu"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_SF_DEFAULT_SPEED=24000000
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0xFFFFE000
diff --git a/configs/chagall_defconfig b/configs/chagall_defconfig
index 1688b4c4d07..f51c4f18d63 100644
--- a/configs/chagall_defconfig
+++ b/configs/chagall_defconfig
@@ -1,8 +1,8 @@
CONFIG_ARM=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x80110000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="chagall"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x3000
CONFIG_ENV_OFFSET=0xFFFFD000
CONFIG_DEFAULT_DEVICE_TREE="tegra30-pegatron-chagall"
diff --git a/configs/colibri_imx7_defconfig b/configs/colibri_imx7_defconfig
index 5a415120bea..2a3cb84c3b6 100644
--- a/configs/colibri_imx7_defconfig
+++ b/configs/colibri_imx7_defconfig
@@ -22,7 +22,7 @@ CONFIG_BOOTDELAY=1
CONFIG_OF_ENV_SETUP=y
CONFIG_BOOTCOMMAND="run ubiboot ; echo ; echo ubiboot failed ; run distro_bootcmd;"
CONFIG_USE_PREBOOT=y
-CONFIG_PREBOOT="test -n ${fdtfile} || setenv fdtfile ${soc}-colibri-${fdt_board}.dtb "
+CONFIG_PREBOOT="test -n ${fdtfile} || setenv fdtfile ${soc}-colibri${variant}-${fdt_board}.dtb "
CONFIG_SYS_PBSIZE=544
CONFIG_SYS_CONSOLE_IS_IN_ENV=y
# CONFIG_DISPLAY_BOARDINFO is not set
diff --git a/configs/colibri_imx7_emmc_defconfig b/configs/colibri_imx7_emmc_defconfig
index bae43fe45aa..a95a3214d0c 100644
--- a/configs/colibri_imx7_emmc_defconfig
+++ b/configs/colibri_imx7_emmc_defconfig
@@ -19,7 +19,7 @@ CONFIG_FIT_VERBOSE=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_BOOTDELAY=1
CONFIG_USE_PREBOOT=y
-CONFIG_PREBOOT="test -n ${fdtfile} || setenv fdtfile ${soc}-colibri-emmc-${fdt_board}.dtb"
+CONFIG_PREBOOT="test -n ${fdtfile} || setenv fdtfile ${soc}-colibri${variant}-${fdt_board}.dtb"
CONFIG_SYS_PBSIZE=544
CONFIG_SYS_CONSOLE_IS_IN_ENV=y
# CONFIG_DISPLAY_BOARDINFO is not set
diff --git a/configs/colibri_t20_defconfig b/configs/colibri_t20_defconfig
index 02e33ba5e3c..036717160aa 100644
--- a/configs/colibri_t20_defconfig
+++ b/configs/colibri_t20_defconfig
@@ -3,8 +3,8 @@ CONFIG_SYS_L2CACHE_OFF=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x00110000
CONFIG_SYS_MALLOC_F_LEN=0x2000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="colibri_t20"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x10000
CONFIG_ENV_OFFSET=0x200000
CONFIG_DEFAULT_DEVICE_TREE="tegra20-colibri"
diff --git a/configs/colibri_t30_defconfig b/configs/colibri_t30_defconfig
index 63b695c1e54..cd98d75ba19 100644
--- a/configs/colibri_t30_defconfig
+++ b/configs/colibri_t30_defconfig
@@ -3,8 +3,8 @@ CONFIG_SYS_L2CACHE_OFF=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x80110000
CONFIG_SYS_MALLOC_F_LEN=0x2000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="colibri_t30"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0xFFFFDE00
CONFIG_DEFAULT_DEVICE_TREE="tegra30-colibri"
diff --git a/configs/endeavoru_defconfig b/configs/endeavoru_defconfig
index 165c0996038..220b8616ae9 100644
--- a/configs/endeavoru_defconfig
+++ b/configs/endeavoru_defconfig
@@ -1,8 +1,8 @@
CONFIG_ARM=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x80110000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="endeavoru"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x3000
CONFIG_ENV_OFFSET=0xFFFFD000
CONFIG_DEFAULT_DEVICE_TREE="tegra30-htc-endeavoru"
diff --git a/configs/exynos-mobile_defconfig b/configs/exynos-mobile_defconfig
new file mode 100644
index 00000000000..3a0b455b169
--- /dev/null
+++ b/configs/exynos-mobile_defconfig
@@ -0,0 +1,70 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_COUNTER_FREQUENCY=26000000
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_EXYNOS=y
+CONFIG_SYS_MALLOC_LEN=0x2000000
+CONFIG_SYS_MALLOC_F_LEN=0x16000
+CONFIG_TARGET_EXYNOS_MOBILE=y
+CONFIG_NR_DRAM_BANKS=3
+CONFIG_DEFAULT_DEVICE_TREE="exynos/exynos7870-a2corelte"
+CONFIG_SYS_BOOTM_LEN=0x2000000
+CONFIG_SYS_LOAD_ADDR=0x80000000
+CONFIG_ARMV8_CNTFRQ_BROKEN=y
+# CONFIG_PSCI_RESET is not set
+CONFIG_BUTTON_CMD=y
+CONFIG_SAVE_PREV_BL_FDT_ADDR=y
+CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR=y
+CONFIG_SYS_PBSIZE=1024
+CONFIG_BOARD_TYPES=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_MISC_INIT_R=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_BOOTMENU=y
+CONFIG_CMD_POWEROFF=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_EFI_PARTITION=y
+CONFIG_OF_UPSTREAM=y
+CONFIG_OF_LIST="exynos/exynos7870-a2corelte exynos/exynos7870-j6lte exynos/exynos7870-on7xelte"
+CONFIG_MULTI_DTB_FIT=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_REMAP_PHONE_KEYS=y
+CONFIG_CLK_EXYNOS7870=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0xdead0000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_SYS_I2C_S3C24X0=y
+CONFIG_BUTTON_KEYBOARD=y
+CONFIG_MISC=y
+CONFIG_MMC_BROKEN_CD=y
+CONFIG_MMC_IO_VOLTAGE=y
+CONFIG_MMC_UHS_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
+CONFIG_MMC_DW=y
+CONFIG_PHY=y
+CONFIG_PHY_EXYNOS_USBDRD=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_EXYNOS78x0=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_S2MPS11=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_S2MPS11=y
+CONFIG_SOC_SAMSUNG=y
+CONFIG_EXYNOS_PMU=y
+CONFIG_SYSRESET=y
+CONFIG_SYSRESET_CMD_POWEROFF=y
+CONFIG_SYSRESET_SYSCON=y
+CONFIG_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_GENERIC=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="Samsung"
+CONFIG_USB_GADGET_VENDOR_NUM=0x04e8
+CONFIG_USB_GADGET_PRODUCT_NUM=0x6602
+CONFIG_VIDEO=y
+CONFIG_VIDEO_SIMPLE=y
+CONFIG_FS_EXT4=y
+CONFIG_FS_FAT=y
diff --git a/configs/grouper_defconfig b/configs/grouper_defconfig
index b6c9550bbbc..91ba341c941 100644
--- a/configs/grouper_defconfig
+++ b/configs/grouper_defconfig
@@ -1,8 +1,8 @@
CONFIG_ARM=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x80110000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="grouper"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x3000
CONFIG_ENV_OFFSET=0xFFFFD000
CONFIG_DEFAULT_DEVICE_TREE="tegra30-asus-nexus7-grouper-E1565"
diff --git a/configs/ideapad-yoga-11_defconfig b/configs/ideapad-yoga-11_defconfig
index 68ca8333019..20eecb716fc 100644
--- a/configs/ideapad-yoga-11_defconfig
+++ b/configs/ideapad-yoga-11_defconfig
@@ -1,8 +1,8 @@
CONFIG_ARM=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x80110000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="ideapad-yoga-11"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x3000
CONFIG_ENV_OFFSET=0xFFFFD000
CONFIG_DEFAULT_DEVICE_TREE="tegra30-lenovo-ideapad-yoga-11"
diff --git a/configs/imx6dl_sielaff_defconfig b/configs/imx6dl_sielaff_defconfig
index a4271ea071a..917b8250e8f 100644
--- a/configs/imx6dl_sielaff_defconfig
+++ b/configs/imx6dl_sielaff_defconfig
@@ -5,8 +5,8 @@ CONFIG_SYS_MALLOC_F_LEN=0x4000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
-CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SOURCE_FILE="imx6dl-sielaff"
+CONFIG_NR_DRAM_BANKS=1
CONFIG_SF_DEFAULT_SPEED=20000000
CONFIG_ENV_SIZE=0x10000
CONFIG_ENV_OFFSET=0xF0000
diff --git a/configs/imx8mn_beacon_2g_defconfig b/configs/imx8mn_beacon_2g_defconfig
index c757a2180c0..32319823a43 100644
--- a/configs/imx8mn_beacon_2g_defconfig
+++ b/configs/imx8mn_beacon_2g_defconfig
@@ -5,8 +5,8 @@ CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
-CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SOURCE_FILE="imx8mn_beacon"
+CONFIG_NR_DRAM_BANKS=1
CONFIG_SF_DEFAULT_SPEED=40000000
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0xFFFFDE00
diff --git a/configs/imx8mn_beacon_defconfig b/configs/imx8mn_beacon_defconfig
index ddaea0c68bd..4f77d51ab4b 100644
--- a/configs/imx8mn_beacon_defconfig
+++ b/configs/imx8mn_beacon_defconfig
@@ -5,8 +5,8 @@ CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
-CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SOURCE_FILE="imx8mn_beacon"
+CONFIG_NR_DRAM_BANKS=1
CONFIG_SF_DEFAULT_SPEED=40000000
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0xFFFFDE00
diff --git a/configs/imx8mn_beacon_fspi_defconfig b/configs/imx8mn_beacon_fspi_defconfig
index 4a49355195a..96c2ed3da71 100644
--- a/configs/imx8mn_beacon_fspi_defconfig
+++ b/configs/imx8mn_beacon_fspi_defconfig
@@ -5,8 +5,8 @@ CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
-CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SOURCE_FILE="imx8mn_beacon"
+CONFIG_NR_DRAM_BANKS=1
CONFIG_SF_DEFAULT_SPEED=40000000
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0xFFFFDE00
diff --git a/configs/imx943_evk_defconfig b/configs/imx943_evk_defconfig
index 39b616e266e..0371dbe28a9 100644
--- a/configs/imx943_evk_defconfig
+++ b/configs/imx943_evk_defconfig
@@ -6,8 +6,8 @@ CONFIG_SYS_MALLOC_F_LEN=0x10000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="imx94_evk"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x4000
CONFIG_ENV_OFFSET=0x700000
CONFIG_DM_GPIO=y
diff --git a/configs/imx95_15x15_evk_defconfig b/configs/imx95_15x15_evk_defconfig
index 96b1d2a64af..f3099f14401 100644
--- a/configs/imx95_15x15_evk_defconfig
+++ b/configs/imx95_15x15_evk_defconfig
@@ -6,8 +6,8 @@ CONFIG_SYS_MALLOC_F_LEN=0x10000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
-CONFIG_NR_DRAM_BANKS=3
CONFIG_ENV_SOURCE_FILE="imx95_evk"
+CONFIG_NR_DRAM_BANKS=3
CONFIG_SF_DEFAULT_SPEED=40000000
CONFIG_ENV_SIZE=0x4000
CONFIG_ENV_OFFSET=0x700000
diff --git a/configs/imxrt1050-evk_fspi_defconfig b/configs/imxrt1050-evk_fspi_defconfig
index cc7e8a3e10b..f213135eb20 100644
--- a/configs/imxrt1050-evk_fspi_defconfig
+++ b/configs/imxrt1050-evk_fspi_defconfig
@@ -8,8 +8,8 @@ CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
-CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SOURCE_FILE="imxrt1050-evk-nor"
+CONFIG_NR_DRAM_BANKS=1
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x20020000
CONFIG_ENV_OFFSET=0x80000
diff --git a/configs/mocha_defconfig b/configs/mocha_defconfig
index ded43ccea58..19c3693a8c5 100644
--- a/configs/mocha_defconfig
+++ b/configs/mocha_defconfig
@@ -2,8 +2,8 @@ CONFIG_ARM=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x80110000
CONFIG_SYS_MALLOC_LEN=0x2500000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="mocha"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x3000
CONFIG_ENV_OFFSET=0xFFFFD000
CONFIG_DEFAULT_DEVICE_TREE="tegra124-xiaomi-mocha"
diff --git a/configs/mot_defconfig b/configs/mot_defconfig
index f6066b9e149..fec44ac8f79 100644
--- a/configs/mot_defconfig
+++ b/configs/mot_defconfig
@@ -1,8 +1,8 @@
CONFIG_ARM=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x00110000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="mot"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x3000
CONFIG_ENV_OFFSET=0xFFFFD000
CONFIG_DEFAULT_DEVICE_TREE="tegra20-motorola-olympus"
diff --git a/configs/n1_defconfig b/configs/n1_defconfig
index 1940a2208a9..15acd675afb 100644
--- a/configs/n1_defconfig
+++ b/configs/n1_defconfig
@@ -1,8 +1,8 @@
CONFIG_ARM=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x00110000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="n1"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x3000
CONFIG_ENV_OFFSET=0xFFFFD000
CONFIG_DEFAULT_DEVICE_TREE="tegra20-samsung-n1"
diff --git a/configs/ouya_defconfig b/configs/ouya_defconfig
index e82f65a9a86..ed1d1b64395 100644
--- a/configs/ouya_defconfig
+++ b/configs/ouya_defconfig
@@ -1,8 +1,8 @@
CONFIG_ARM=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x80110000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="ouya"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x3000
CONFIG_ENV_OFFSET=0xFFFFD000
CONFIG_DEFAULT_DEVICE_TREE="tegra30-ouya"
diff --git a/configs/p2771-0000-000_defconfig b/configs/p2771-0000-000_defconfig
index 462bec3bae2..24655774374 100644
--- a/configs/p2771-0000-000_defconfig
+++ b/configs/p2771-0000-000_defconfig
@@ -4,8 +4,8 @@ CONFIG_COUNTER_FREQUENCY=19200000
CONFIG_SYS_L2CACHE_OFF=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x80080000
-CONFIG_NR_DRAM_BANKS=1026
CONFIG_ENV_SOURCE_FILE="p2771-0000"
+CONFIG_NR_DRAM_BANKS=1026
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0xFFFFE000
CONFIG_DEFAULT_DEVICE_TREE="tegra186-p2771-0000-000"
diff --git a/configs/p3450-0000_defconfig b/configs/p3450-0000_defconfig
index 2ebcf8b83fc..f6e09ba1fee 100644
--- a/configs/p3450-0000_defconfig
+++ b/configs/p3450-0000_defconfig
@@ -5,8 +5,8 @@ CONFIG_SYS_L2CACHE_OFF=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x80080000
CONFIG_SYS_MALLOC_LEN=0x2500000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="p3450-0000"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_SF_DEFAULT_SPEED=24000000
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0xFFFFE000
diff --git a/configs/pg_wcom_expu1_defconfig b/configs/pg_wcom_expu1_defconfig
index 321e46e8c52..27e40c87c73 100644
--- a/configs/pg_wcom_expu1_defconfig
+++ b/configs/pg_wcom_expu1_defconfig
@@ -4,8 +4,8 @@ CONFIG_COUNTER_FREQUENCY=8333333
CONFIG_TARGET_PG_WCOM_EXPU1=y
CONFIG_TEXT_BASE=0x60100000
CONFIG_SYS_MALLOC_LEN=0x1004000
-CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SOURCE_FILE="pg-wcom-expu1"
+CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SIZE=0x4000
CONFIG_ENV_SECT_SIZE=0x20000
CONFIG_DM_GPIO=y
diff --git a/configs/pg_wcom_expu1_update_defconfig b/configs/pg_wcom_expu1_update_defconfig
index b53af5be52c..6e4925562c3 100644
--- a/configs/pg_wcom_expu1_update_defconfig
+++ b/configs/pg_wcom_expu1_update_defconfig
@@ -4,8 +4,8 @@ CONFIG_COUNTER_FREQUENCY=8333333
CONFIG_TARGET_PG_WCOM_EXPU1=y
CONFIG_TEXT_BASE=0x60240000
CONFIG_SYS_MALLOC_LEN=0x1004000
-CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SOURCE_FILE="pg-wcom-expu1"
+CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SIZE=0x4000
CONFIG_ENV_SECT_SIZE=0x20000
CONFIG_DM_GPIO=y
diff --git a/configs/pg_wcom_seli8_defconfig b/configs/pg_wcom_seli8_defconfig
index 561df3ee009..915483fb72a 100644
--- a/configs/pg_wcom_seli8_defconfig
+++ b/configs/pg_wcom_seli8_defconfig
@@ -4,8 +4,8 @@ CONFIG_COUNTER_FREQUENCY=8333333
CONFIG_TARGET_PG_WCOM_SELI8=y
CONFIG_TEXT_BASE=0x60100000
CONFIG_SYS_MALLOC_LEN=0x1004000
-CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SOURCE_FILE="pg-wcom-seli8"
+CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SIZE=0x4000
CONFIG_ENV_SECT_SIZE=0x20000
CONFIG_DM_GPIO=y
diff --git a/configs/pg_wcom_seli8_update_defconfig b/configs/pg_wcom_seli8_update_defconfig
index 2a631176095..81ca109facb 100644
--- a/configs/pg_wcom_seli8_update_defconfig
+++ b/configs/pg_wcom_seli8_update_defconfig
@@ -4,8 +4,8 @@ CONFIG_COUNTER_FREQUENCY=8333333
CONFIG_TARGET_PG_WCOM_SELI8=y
CONFIG_TEXT_BASE=0x60240000
CONFIG_SYS_MALLOC_LEN=0x1004000
-CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SOURCE_FILE="pg-wcom-seli8"
+CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SIZE=0x4000
CONFIG_ENV_SECT_SIZE=0x20000
CONFIG_DM_GPIO=y
diff --git a/configs/phycore_am64x_a53_defconfig b/configs/phycore_am64x_a53_defconfig
index 9d6aa9c308c..2e096415743 100644
--- a/configs/phycore_am64x_a53_defconfig
+++ b/configs/phycore_am64x_a53_defconfig
@@ -122,8 +122,8 @@ CONFIG_SYS_I2C_OMAP24XX=y
CONFIG_DM_MAILBOX=y
CONFIG_K3_SEC_PROXY=y
CONFIG_SUPPORT_EMMC_BOOT=y
-CONFIG_MMC_HS400_SUPPORT=y
-CONFIG_SPL_MMC_HS400_SUPPORT=y
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_SPL_MMC_HS200_SUPPORT=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ADMA=y
CONFIG_SPL_MMC_SDHCI_ADMA=y
diff --git a/configs/picasso_defconfig b/configs/picasso_defconfig
index 9d153694245..ddc51c5b55c 100644
--- a/configs/picasso_defconfig
+++ b/configs/picasso_defconfig
@@ -1,8 +1,8 @@
CONFIG_ARM=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x00110000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="picasso"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x3000
CONFIG_ENV_OFFSET=0xFFFFD000
CONFIG_DEFAULT_DEVICE_TREE="tegra20-acer-a500-picasso"
diff --git a/configs/qc750_defconfig b/configs/qc750_defconfig
index 2be3838ae60..3db8550266b 100644
--- a/configs/qc750_defconfig
+++ b/configs/qc750_defconfig
@@ -1,8 +1,8 @@
CONFIG_ARM=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x80110000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="qc750"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x3000
CONFIG_ENV_OFFSET=0xFFFFD000
CONFIG_DEFAULT_DEVICE_TREE="tegra30-wexler-qc750"
diff --git a/configs/r8a779g3_sparrowhawk_defconfig b/configs/r8a779g3_sparrowhawk_defconfig
index 2d1abf6f26d..ee8f2711985 100644
--- a/configs/r8a779g3_sparrowhawk_defconfig
+++ b/configs/r8a779g3_sparrowhawk_defconfig
@@ -6,6 +6,7 @@ CONFIG_RCAR_GEN4=y
CONFIG_ARM_SMCCC=y
CONFIG_ARMV8_PSCI=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_ENV_REDUNDANT=y
CONFIG_ENV_OFFSET=0x3f80000
CONFIG_ENV_OFFSET_REDUND=0x3fc0000
CONFIG_ENV_SECT_SIZE=0x40000
diff --git a/configs/r8a78000_ironhide_defconfig b/configs/r8a78000_ironhide_defconfig
new file mode 100644
index 00000000000..180704e75af
--- /dev/null
+++ b/configs/r8a78000_ironhide_defconfig
@@ -0,0 +1,43 @@
+#include <configs/renesas_rcar5.config>
+
+CONFIG_ARM=y
+CONFIG_ARCH_RENESAS=y
+CONFIG_RCAR_GEN5=y
+CONFIG_TARGET_IRONHIDE=y
+
+# CONFIG_OF_UPSTREAM is not set
+CONFIG_ARMV8_PSCI=y
+CONFIG_ARM_SMCCC=y
+CONFIG_BAUDRATE=1843200
+CONFIG_BOOTCOMMAND="setexpr dloadaddr ${loadaddr} + 0x200000 && setexpr dloadaddr ${dloadaddr} \\\\& 0xffc00000 && setexpr kloadaddr ${dloadaddr} + 0x200000 && tftp ${dloadaddr} r8a78000-ironhide.dtb && tftp ${kloadaddr} Image && booti ${kloadaddr} - ${dloadaddr}"
+CONFIG_DEFAULT_DEVICE_TREE="r8a78000-ironhide"
+CONFIG_CLK_CCF=y
+CONFIG_CLK_COMPOSITE_CCF=y
+CONFIG_CLK_SCMI=y
+CONFIG_CMD_CLK=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_SCMI=y
+CONFIG_CMD_UFS=y
+CONFIG_DM_MAILBOX=y
+CONFIG_DM_RESET=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_MMC_DEVICE_INDEX=0
+CONFIG_ENV_MMC_EMMC_HW_PARTITION=2
+CONFIG_ENV_OFFSET=0xFFFE0000
+CONFIG_ENV_SIZE=0x20000
+CONFIG_FIRMWARE=y
+CONFIG_NR_DRAM_BANKS=16
+CONFIG_POWER_DOMAIN=y
+CONFIG_RCAR_MFIS_MBOX=y
+CONFIG_RESET_SCMI=y
+CONFIG_SCMI_AGENT_MAILBOX=y
+CONFIG_SCMI_FIRMWARE=y
+CONFIG_SCMI_POWER_DOMAIN=y
+CONFIG_SCSI=y
+CONFIG_SYS_ALT_MEMTEST=y
+CONFIG_SYS_BARGSIZE=2048
+CONFIG_SYS_BOOT_GET_CMDLINE=y
+CONFIG_SYS_CBSIZE=2048
+CONFIG_SYS_CLK_FREQ=1066666667
+CONFIG_UFS=y
+CONFIG_UFS_RENESAS_GEN5=y
diff --git a/configs/renesas_rcar.config b/configs/renesas_rcar.config
index 45776be62ea..d9a99e1f428 100644
--- a/configs/renesas_rcar.config
+++ b/configs/renesas_rcar.config
@@ -17,7 +17,6 @@ CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
CONFIG_DM_SPI=y
CONFIG_DM_SPI_FLASH=y
-CONFIG_ENV_OVERWRITE=y
CONFIG_ENV_VARS_UBOOT_CONFIG=y
CONFIG_FIT=y
CONFIG_HUSH_PARSER=y
diff --git a/configs/renesas_rcar5.config b/configs/renesas_rcar5.config
new file mode 100644
index 00000000000..fbf158dfdb3
--- /dev/null
+++ b/configs/renesas_rcar5.config
@@ -0,0 +1,23 @@
+#include <configs/renesas_rcar64.config>
+
+CONFIG_ARCH_CPU_INIT=y
+CONFIG_SYS_LOAD_ADDR=0x9E600000
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_USE_BOOTARGS=y
+CONFIG_USE_BOOTCOMMAND=y
+
+CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=192.168.0.1:/export/rfs ip=192.168.0.20"
+CONFIG_CMD_MMC=y
+CONFIG_DM_ETH_PHY=y
+# CONFIG_MMC_HS200_SUPPORT is not set
+# CONFIG_MMC_IO_VOLTAGE is not set
+# CONFIG_MMC_UHS_SUPPORT is not set
+CONFIG_PHY_R8A78000_ETHERNET_PCS=y
+CONFIG_PHY_R8A78000_MP_PHY=y
+CONFIG_PHY_TI_DP83869=y
+# CONFIG_PSCI_RESET is not set
+CONFIG_RENESAS_ETHER_SWITCH=y
+CONFIG_RENESAS_SDHI=y
+CONFIG_SPI_FLASH_SPANSION=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+CONFIG_SYS_I2C_RCAR_I2C=y
diff --git a/configs/socfpga_agilex5_defconfig b/configs/socfpga_agilex5_defconfig
index bbe712f8452..64f2f1bf115 100644
--- a/configs/socfpga_agilex5_defconfig
+++ b/configs/socfpga_agilex5_defconfig
@@ -70,7 +70,9 @@ CONFIG_CMD_UBI=y
# CONFIG_ISO_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
CONFIG_OF_LIST=""
+CONFIG_ENV_IS_IN_FAT=y
CONFIG_ENV_IS_IN_UBI=y
+CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
CONFIG_ENV_UBI_PART="root"
CONFIG_ENV_UBI_VOLUME="env"
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
diff --git a/configs/socfpga_cyclone5_defconfig b/configs/socfpga_cyclone5_defconfig
index fef4cb90516..992abdbfdc4 100644
--- a/configs/socfpga_cyclone5_defconfig
+++ b/configs/socfpga_cyclone5_defconfig
@@ -12,10 +12,12 @@ CONFIG_DM_RESET=y
CONFIG_SPL_STACK=0x0
CONFIG_SPL_TEXT_BASE=0xFFFF0000
CONFIG_TARGET_SOCFPGA_CYCLONE5_SOCDK=y
+CONFIG_SPL_FS_FAT=y
+# CONFIG_SPL_SPI is not set
CONFIG_TIMESTAMP=y
CONFIG_FIT=y
CONFIG_DISTRO_DEFAULTS=y
-# CONFIG_USE_BOOTCOMMAND is not set
+CONFIG_BOOTCOMMAND="run fatscript;bridge enable; run distro_bootcmd"
CONFIG_DEFAULT_FDT_FILE="socfpga_cyclone5_socdk.dtb"
CONFIG_SYS_CONSOLE_IS_IN_ENV=y
CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y
@@ -27,8 +29,7 @@ CONFIG_SPL_PAD_TO=0x10000
CONFIG_SPL_NO_BSS_LIMIT=y
# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
CONFIG_SPL_HAVE_INIT_STACK=y
-CONFIG_SPL_SPI_LOAD=y
-CONFIG_SYS_SPI_U_BOOT_OFFS=0x40000
+# CONFIG_SPL_SYS_MMCSD_RAW_MODE is not set
CONFIG_SYS_MAXARGS=32
CONFIG_CMD_ASKENV=y
CONFIG_CMD_GREPENV=y
@@ -79,3 +80,4 @@ CONFIG_USB_GADGET_DWC2_OTG=y
CONFIG_USB_GADGET_DOWNLOAD=y
# CONFIG_SPL_WDT is not set
CONFIG_SYS_TIMER_COUNTS_DOWN=y
+# CONFIG_TOOLS_MKEFICAPSULE is not set
diff --git a/configs/socfpga_vining_fpga_defconfig b/configs/socfpga_vining_fpga_defconfig
index f3b6cb717b3..396b7a9715d 100644
--- a/configs/socfpga_vining_fpga_defconfig
+++ b/configs/socfpga_vining_fpga_defconfig
@@ -78,17 +78,8 @@ CONFIG_SYS_DFU_DATA_BUF_SIZE=0x1000000
CONFIG_DWAPB_GPIO=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_DW=y
-CONFIG_LED_STATUS=y
-CONFIG_LED_STATUS_GPIO=y
-CONFIG_LED_STATUS0=y
-CONFIG_LED_STATUS_BIT=48
-CONFIG_LED_STATUS1=y
-CONFIG_LED_STATUS_BIT1=53
-CONFIG_LED_STATUS2=y
-CONFIG_LED_STATUS_BIT2=54
-CONFIG_LED_STATUS3=y
-CONFIG_LED_STATUS_BIT3=65
-CONFIG_LED_STATUS_CMD=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
CONFIG_MISC=y
CONFIG_I2C_EEPROM=y
CONFIG_SYS_I2C_EEPROM_ADDR=0x50
diff --git a/configs/star_defconfig b/configs/star_defconfig
index 59eabdcb2b4..f2cdcf066c0 100644
--- a/configs/star_defconfig
+++ b/configs/star_defconfig
@@ -1,8 +1,8 @@
CONFIG_ARM=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x00110000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="star"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x3000
CONFIG_ENV_OFFSET=0xFFFFD000
CONFIG_DEFAULT_DEVICE_TREE="tegra20-lg-star"
diff --git a/configs/surface-2_defconfig b/configs/surface-2_defconfig
index d3e6166cf89..5ec0d234fe3 100644
--- a/configs/surface-2_defconfig
+++ b/configs/surface-2_defconfig
@@ -2,8 +2,8 @@ CONFIG_ARM=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x80110000
CONFIG_SYS_MALLOC_LEN=0x2500000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="surface-2"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x3000
CONFIG_ENV_OFFSET=0xFFFFD000
CONFIG_DEFAULT_DEVICE_TREE="tegra114-microsoft-surface-2-0b"
diff --git a/configs/surface-rt_defconfig b/configs/surface-rt_defconfig
index 88b67749095..6e3752c72a3 100644
--- a/configs/surface-rt_defconfig
+++ b/configs/surface-rt_defconfig
@@ -1,8 +1,8 @@
CONFIG_ARM=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x80110000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="surface-rt"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x3000
CONFIG_ENV_OFFSET=0xFFFFD000
CONFIG_DEFAULT_DEVICE_TREE="tegra30-microsoft-surface-rt"
diff --git a/configs/tegratab_defconfig b/configs/tegratab_defconfig
index 27cb75c92b5..d2596453d8d 100644
--- a/configs/tegratab_defconfig
+++ b/configs/tegratab_defconfig
@@ -2,8 +2,8 @@ CONFIG_ARM=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x80110000
CONFIG_SYS_MALLOC_LEN=0x2500000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="tegratab"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x3000
CONFIG_ENV_OFFSET=0xFFFFD000
CONFIG_DEFAULT_DEVICE_TREE="tegra114-nvidia-tegratab"
diff --git a/configs/tf701t_defconfig b/configs/tf701t_defconfig
index e8f920587c3..abed3d65baf 100644
--- a/configs/tf701t_defconfig
+++ b/configs/tf701t_defconfig
@@ -2,8 +2,8 @@ CONFIG_ARM=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x80110000
CONFIG_SYS_MALLOC_LEN=0x2500000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="transformer-t114"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x3000
CONFIG_ENV_OFFSET=0xFFFFD000
CONFIG_DEFAULT_DEVICE_TREE="tegra114-asus-tf701t"
diff --git a/configs/toradex-smarc-imx95_defconfig b/configs/toradex-smarc-imx95_defconfig
index c5cea6e4e5f..5ab420ae519 100644
--- a/configs/toradex-smarc-imx95_defconfig
+++ b/configs/toradex-smarc-imx95_defconfig
@@ -17,6 +17,7 @@ CONFIG_SYS_MONITOR_LEN=524288
CONFIG_SPL_MMC=y
CONFIG_SPL_SERIAL=y
CONFIG_SPL_DRIVERS_MISC=y
+CONFIG_SPL_STACK=0x204d6000
CONFIG_SPL_TEXT_BASE=0x20480000
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
CONFIG_SPL_BSS_START_ADDR=0x204d6000
@@ -49,6 +50,7 @@ CONFIG_SPL_BOARD_INIT=y
CONFIG_SPL_LOAD_IMX_CONTAINER=y
CONFIG_IMX_CONTAINER_CFG="arch/arm/mach-imx/imx9/scmi/container.cfg"
# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_HAVE_INIT_STACK=y
CONFIG_SPL_SYS_MALLOC=y
CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y
CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0x93200000
diff --git a/configs/transformer_t20_defconfig b/configs/transformer_t20_defconfig
index 61eab59fa3b..251bc955beb 100644
--- a/configs/transformer_t20_defconfig
+++ b/configs/transformer_t20_defconfig
@@ -1,8 +1,8 @@
CONFIG_ARM=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x00110000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="transformer-t20"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x3000
CONFIG_ENV_OFFSET=0xFFFFD000
CONFIG_DEFAULT_DEVICE_TREE="tegra20-asus-tf101"
diff --git a/configs/transformer_t30_defconfig b/configs/transformer_t30_defconfig
index 6f8953aa103..fb1900299b1 100644
--- a/configs/transformer_t30_defconfig
+++ b/configs/transformer_t30_defconfig
@@ -1,8 +1,8 @@
CONFIG_ARM=y
CONFIG_ARCH_TEGRA=y
CONFIG_TEXT_BASE=0x80110000
-CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SOURCE_FILE="transformer-t30"
+CONFIG_NR_DRAM_BANKS=2
CONFIG_ENV_SIZE=0x3000
CONFIG_ENV_OFFSET=0xFFFFD000
CONFIG_DEFAULT_DEVICE_TREE="tegra30-asus-tf201"
diff --git a/configs/xilinx_versal_mini_ospi_defconfig b/configs/xilinx_versal_mini_ospi_defconfig
index 11811f3c0fd..eb101d03973 100644
--- a/configs/xilinx_versal_mini_ospi_defconfig
+++ b/configs/xilinx_versal_mini_ospi_defconfig
@@ -3,11 +3,11 @@ CONFIG_SYS_CONFIG_NAME="xilinx_versal_mini"
CONFIG_COUNTER_FREQUENCY=100000000
CONFIG_ARCH_VERSAL=y
CONFIG_TEXT_BASE=0xFFFC0000
-CONFIG_SYS_MALLOC_LEN=0x2000
+CONFIG_SYS_MALLOC_LEN=0x3000
CONFIG_SYS_MALLOC_F_LEN=0x500
CONFIG_NR_DRAM_BANKS=1
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
-CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xFFFE1000
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xFFFE2000
CONFIG_SF_DEFAULT_SPEED=30000000
CONFIG_ENV_SIZE=0x80
# CONFIG_DM_GPIO is not set
diff --git a/configs/xilinx_versal_mini_qspi_defconfig b/configs/xilinx_versal_mini_qspi_defconfig
index 47737ce0f8f..20fab6931c3 100644
--- a/configs/xilinx_versal_mini_qspi_defconfig
+++ b/configs/xilinx_versal_mini_qspi_defconfig
@@ -3,10 +3,10 @@ CONFIG_SYS_CONFIG_NAME="xilinx_versal_mini"
CONFIG_COUNTER_FREQUENCY=100000000
CONFIG_ARCH_VERSAL=y
CONFIG_TEXT_BASE=0xFFFC0000
-CONFIG_SYS_MALLOC_LEN=0x2000
+CONFIG_SYS_MALLOC_LEN=0x3000
CONFIG_NR_DRAM_BANKS=1
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
-CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xFFFE0000
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xFFFE2000
CONFIG_SF_DEFAULT_SPEED=30000000
CONFIG_ENV_SIZE=0x80
CONFIG_DEFAULT_DEVICE_TREE="versal-mini-qspi-single"
diff --git a/doc/board/samsung/exynos-mobile.rst b/doc/board/samsung/exynos-mobile.rst
new file mode 100644
index 00000000000..37718af1fea
--- /dev/null
+++ b/doc/board/samsung/exynos-mobile.rst
@@ -0,0 +1,45 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. sectionauthor:: Kaustabh Chakraborty <[email protected]>
+
+Samsung Exynos Generic ARMv8 Boards (for mobile devices)
+========================================================
+
+Overview
+--------
+This document describes how to build and run U-Boot for Samsung Exynos generic
+boards. Boards are expected to boot with a primary bootloader, such as S-BOOT or
+S-LK, which hands off control to U-Boot. Presently, only ARMv8 devices are
+supported.
+
+The U-Boot image is built with all device tree blobs packed in a single FIT
+image. During boot, it uses simple heuristics to detect the target board, and
+subsequently the appropriate FDT is selected.
+
+Installation
+------------
+Building
+^^^^^^^^
+If a cross-compiler is required, install it and set it up like so:
+
+.. prompt:: bash $
+
+ export CROSS_COMPILE=aarch64-linux-gnu-
+
+Then, run the following commands to build U-Boot:
+
+.. prompt:: bash $
+
+ make O=.output exynos-mobile_defconfig
+ make O=.output -j$(nproc)
+
+If successful, the U-Boot binary will be present in ``.output/u-boot.bin``.
+
+Preparation and Flashing
+^^^^^^^^^^^^^^^^^^^^^^^^
+Since U-Boot supports multiple boards, and devices have different requirements,
+this step will vary depending on your target.
+
+.. toctree::
+ :maxdepth: 1
+
+ exynos-mobile/exynos7870
diff --git a/doc/board/samsung/exynos-mobile/exynos7870.rst b/doc/board/samsung/exynos-mobile/exynos7870.rst
new file mode 100644
index 00000000000..bbd857580b8
--- /dev/null
+++ b/doc/board/samsung/exynos-mobile/exynos7870.rst
@@ -0,0 +1,85 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. sectionauthor:: Kaustabh Chakraborty <[email protected]>
+
+Samsung Exynos 7870 Boards
+==========================
+
+Preparation
+-----------
+Create the following device tree (named ``stub.dts``)
+
+.. code-block:: devicetree
+
+ /dts-v1/;
+
+ / {
+ compatible = "samsung,exynos7870";
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ model_info-chip = <7870>;
+ model_info-hw_rev = <0>;
+ model_info-hw_rev_end = <255>;
+
+ chosen {
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x0>;
+ };
+
+ memory@100000000 {
+ device_type = "memory";
+ reg = <0x1 0x00000000 0x0>;
+ };
+ };
+
+The chosen node and memory ranges are populated by S-BOOT. A certain device
+model may have multiple variants, with differing amounts of RAM and storage. The
+RAM capacity information is graciously provided by S-BOOT's device tree
+overlays.
+
+Compile it to a device tree blob, then pack it in the QCDT format [1]_ using
+``dtbTool-exynos`` [2]_ by issuing the following commands:
+
+.. prompt:: bash $
+
+ dtc -I dts -O dtb -o stub.dtb stub.dts
+ dtbTool-exynos -o stub-dt.img stub.dtb
+
+Finally, use ``mkbootimg`` by osm0sis [3]_ to generate the boot image:
+
+.. prompt:: bash $
+
+ mkbootimg -o u-boot.img \
+ --kernel .output/u-boot.bin \
+ --dt stub-dt.img
+
+Offsets are not provided to ``mkbootimg`` as S-BOOT ignores them.
+
+Flashing
+--------
+If flashing for the first time, it must be done via Samsung's Download (Odin)
+mode. Heimdall [4]_ can be used for flashing, like so:
+
+.. prompt:: bash $
+
+ heimdall flash --BOOT u-boot.img
+
+However, if U-Boot is already installed, you may also use its fastboot interface
+for flashing. Boot into the boot menu by holding the volume down key. Enable
+fastboot mode from there, connect the device to your host, then run:
+
+.. prompt:: bash $
+
+ fastboot flash boot u-boot.img
+
+To flash an OS image in internal storage, fastboot is a reliable option.
+
+References
+----------
+.. [1] https://wiki.postmarketos.org/wiki/QCDT
+.. [2] https://github.com/dsankouski/dtbtool-exynos
+.. [3] https://github.com/osm0sis/mkbootimg
+.. [4] https://git.sr.ht/~grimler/Heimdall
diff --git a/doc/board/samsung/index.rst b/doc/board/samsung/index.rst
index 1b92c9518a5..1fbe88130c0 100644
--- a/doc/board/samsung/index.rst
+++ b/doc/board/samsung/index.rst
@@ -8,4 +8,5 @@ Samsung
axy17lte
e850-96
+ exynos-mobile
n1
diff --git a/doc/board/toradex/verdin-am62p.rst b/doc/board/toradex/verdin-am62p.rst
index 2f3262b8d1e..cc60505a40c 100644
--- a/doc/board/toradex/verdin-am62p.rst
+++ b/doc/board/toradex/verdin-am62p.rst
@@ -125,72 +125,69 @@ one may also use the update U-Boot wrappers:
Boot
----
-Output:
-
-.. code-block:: console
-
-U-Boot SPL 2025.04-00006-g51dc98d36470 (May 12 2025 - 15:46:57 +0100)
-SYSFW ABI: 4.0 (firmware rev 0x000b '11.0.7--v11.00.07 (Fancy Rat)')
-Changed A53 CPU frequency to 1250000000Hz (U grade) in DT
-SPL initial stack usage: 17080 bytes
-Trying to boot from MMC1
-Authentication passed
-Authentication passed
-Authentication passed
-Loading Environment from nowhere... OK
-init_env from device 9 not supported!
-Authentication passed
-Authentication passed
-Starting ATF on ARM64 core...
-
-NOTICE: BL31: v2.12.0(release):v2.12.0-1106-g4301798db096
-NOTICE: BL31: Built : 10:57:58, May 9 2025
-I/TC:
-I/TC: OP-TEE version: 4.6.0-18-g76d920d354df (gcc version 12.3.1 20230626 (Arm GNU Toolchain 12.3.Rel1 (Build arm-12.35))) #4 Tue May 6 19:48:13 UTC 2025 aarch64
-I/TC: WARNING: This OP-TEE configuration might be insecure!
-I/TC: WARNING: Please check https://optee.readthedocs.io/en/latest/architecture/porting_guidelines.html
-I/TC: Primary CPU initializing
-I/TC: GIC redistributor base address not provided
-I/TC: Assuming default GIC group status and modifier
-I/TC: SYSFW ABI: 4.0 (firmware rev 0x000b '11.0.7--v11.00.07 (Fancy Rat)')
-I/TC: Activated SA2UL device
-I/TC: Enabled firewalls for SA2UL TRNG device
-I/TC: SA2UL TRNG initialized
-I/TC: SA2UL Drivers initialized
-I/TC: HUK Initialized
-I/TC: Primary CPU switching to normal world boot
-
-U-Boot SPL 2025.04-00006-g51dc98d36470 (May 12 2025 - 15:47:54 +0100)
-SYSFW ABI: 4.0 (firmware rev 0x000b '11.0.7--v11.00.07 (Fancy Rat)')
-SPL initial stack usage: 1760 bytes
-HW CFG: 0x00
-Trying to boot from MMC1
-Authentication passed
-Authentication passed
-
-
-U-Boot 2025.04-00006-g51dc98d36470 (May 12 2025 - 15:47:54 +0100)
-
-SoC: AM62PX SR1.0 HS-FS
-DRAM: 2 GiB
-Core: 147 devices, 31 uclasses, devicetree: separate
-MMC: mmc@fa10000: 0, mmc@fa00000: 1
-Loading Environment from MMC... Reading from MMC(0)... OK
-In: serial@2800000
-Out: serial@2800000
-Err: serial@2800000
-Model: Toradex 0099 Verdin AM62P Quad 2GB WB IT V1.0A
-Serial#: 15664919
-Carrier: Toradex Dahlia V1.1D, Serial# 11287149
-am65_cpsw_nuss ethernet@8000000: K3 CPSW: nuss_ver: 0x6BA01903 cpsw_ver: 0x6BA81903 ale_ver: 0x00290105 Ports:2
-Setting variant to wifi
-Net:
-Warning: ethernet@8000000port@1 MAC addresses don't match:
-Address in ROM is 58:a1:5f:b8:93:f9
-Address in environment is 00:14:2d:ef:07:17
-eth0: ethernet@8000000port@1 [PRIME]Could not get PHY for mdio@f00: addr 7
-am65_cpsw_nuss_port ethernet@8000000port@2: phy_connect() failed
-
-Hit any key to stop autoboot: 0
-Verdin AM62P #
-
+Output::
+
+ U-Boot SPL 2025.04-00006-g51dc98d36470 (May 12 2025 - 15:46:57 +0100)
+ SYSFW ABI: 4.0 (firmware rev 0x000b '11.0.7--v11.00.07 (Fancy Rat)')
+ Changed A53 CPU frequency to 1250000000Hz (U grade) in DT
+ SPL initial stack usage: 17080 bytes
+ Trying to boot from MMC1
+ Authentication passed
+ Authentication passed
+ Authentication passed
+ Loading Environment from nowhere... OK
+ init_env from device 9 not supported!
+ Authentication passed
+ Authentication passed
+ Starting ATF on ARM64 core...
+
+ NOTICE: BL31: v2.12.0(release):v2.12.0-1106-g4301798db096
+ NOTICE: BL31: Built : 10:57:58, May 9 2025
+ I/TC:
+ I/TC: OP-TEE version: 4.6.0-18-g76d920d354df (gcc version 12.3.1 20230626 (Arm GNU Toolchain 12.3.Rel1 (Build arm-12.35))) #4 Tue May 6 19:48:13 UTC 2025 aarch64
+ I/TC: WARNING: This OP-TEE configuration might be insecure!
+ I/TC: WARNING: Please check https://optee.readthedocs.io/en/latest/architecture/porting_guidelines.html
+ I/TC: Primary CPU initializing
+ I/TC: GIC redistributor base address not provided
+ I/TC: Assuming default GIC group status and modifier
+ I/TC: SYSFW ABI: 4.0 (firmware rev 0x000b '11.0.7--v11.00.07 (Fancy Rat)')
+ I/TC: Activated SA2UL device
+ I/TC: Enabled firewalls for SA2UL TRNG device
+ I/TC: SA2UL TRNG initialized
+ I/TC: SA2UL Drivers initialized
+ I/TC: HUK Initialized
+ I/TC: Primary CPU switching to normal world boot
+
+ U-Boot SPL 2025.04-00006-g51dc98d36470 (May 12 2025 - 15:47:54 +0100)
+ SYSFW ABI: 4.0 (firmware rev 0x000b '11.0.7--v11.00.07 (Fancy Rat)')
+ SPL initial stack usage: 1760 bytes
+ HW CFG: 0x00
+ Trying to boot from MMC1
+ Authentication passed
+ Authentication passed
+
+
+ U-Boot 2025.04-00006-g51dc98d36470 (May 12 2025 - 15:47:54 +0100)
+
+ SoC: AM62PX SR1.0 HS-FS
+ DRAM: 2 GiB
+ Core: 147 devices, 31 uclasses, devicetree: separate
+ MMC: mmc@fa10000: 0, mmc@fa00000: 1
+ Loading Environment from MMC... Reading from MMC(0)... OK
+ In: serial@2800000
+ Out: serial@2800000
+ Err: serial@2800000
+ Model: Toradex 0099 Verdin AM62P Quad 2GB WB IT V1.0A
+ Serial#: 15664919
+ Carrier: Toradex Dahlia V1.1D, Serial# 11287149
+ am65_cpsw_nuss ethernet@8000000: K3 CPSW: nuss_ver: 0x6BA01903 cpsw_ver: 0x6BA81903 ale_ver: 0x00290105 Ports:2
+ Setting variant to wifi
+ Net:
+ Warning: ethernet@8000000port@1 MAC addresses don't match:
+ Address in ROM is 58:a1:5f:b8:93:f9
+ Address in environment is 00:14:2d:ef:07:17
+ eth0: ethernet@8000000port@1 [PRIME]Could not get PHY for mdio@f00: addr 7
+ am65_cpsw_nuss_port ethernet@8000000port@2: phy_connect() failed
+
+ Hit any key to stop autoboot: 0
+ Verdin AM62P #
diff --git a/doc/develop/pytest/usage.rst b/doc/develop/pytest/usage.rst
index 7335a39b963..df3821da20d 100644
--- a/doc/develop/pytest/usage.rst
+++ b/doc/develop/pytest/usage.rst
@@ -315,14 +315,16 @@ Environment variables
The following environment variables are set when running hook scripts:
-- ``UBOOT_BOARD_TYPE`` the board type being tested.
-- ``UBOOT_BOARD_IDENTITY`` the board identity being tested, or ``na`` if none
+- ``U_BOOT_BOARD_TYPE`` the board type being tested.
+- ``U_BOOT_BOARD_TYPE_EXTRA`` the 2nd board type being tested, if applicable.
+- ``U_BOOT_BOARD_IDENTITY`` the board identity being tested, or ``na`` if none
was specified.
-- ``UBOOT_SOURCE_DIR`` the U-Boot source directory.
-- ``UBOOT_TEST_PY_DIR`` the full path to ``test/py/`` in the source directory.
-- ``UBOOT_BUILD_DIR`` the U-Boot build directory.
-- ``UBOOT_RESULT_DIR`` the test result directory.
-- ``UBOOT_PERSISTENT_DATA_DIR`` the test persistent data directory.
+- ``U_BOOT_SOURCE_DIR`` the U-Boot source directory.
+- ``U_BOOT_TEST_PY_DIR`` the full path to ``test/py/`` in the source directory.
+- ``U_BOOT_BUILD_DIR`` the U-Boot build directory.
+- ``U_BOOT_BUILD_DIR_EXTRA`` the 2nd U-Boot build directory, if applicable.
+- ``U_BOOT_RESULT_DIR`` the test result directory.
+- ``U_BOOT_PERSISTENT_DATA_DIR`` the test persistent data directory.
u-boot-test-console
'''''''''''''''''''
diff --git a/doc/develop/release_cycle.rst b/doc/develop/release_cycle.rst
index 56cbfcb4b65..be6b09b250e 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 24 November 2025.
-.. * U-Boot |next_ver|-rc4 was released on Mon 08 December 2025.
+* U-Boot |next_ver|-rc4 was released on Mon 08 December 2025.
.. * U-Boot |next_ver|-rc5 was released on Tue 22 December 2025.
diff --git a/doc/learn/index.rst b/doc/learn/index.rst
index 8075c01d1df..5b139e3c9fd 100644
--- a/doc/learn/index.rst
+++ b/doc/learn/index.rst
@@ -6,4 +6,5 @@ Learn about U-Boot
.. toctree::
:maxdepth: 1
+ logo
talks
diff --git a/doc/learn/logo.rst b/doc/learn/logo.rst
new file mode 100644
index 00000000000..66d403e4cff
--- /dev/null
+++ b/doc/learn/logo.rst
@@ -0,0 +1,20 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+U-Boot logo
+===========
+
+The project uses the logos below.
+
+Logo with text
+--------------
+
+.. image:: ../../tools/logos/u-boot_logo_with_text.svg
+ :width: 10em
+ :alt: U-Boot logo with text
+
+Logo without text
+-----------------
+
+.. image:: ../../tools/logos/u-boot_logo.svg
+ :width: 10em
+ :alt: U-Boot logo without text
diff --git a/doc/sphinx/requirements.txt b/doc/sphinx/requirements.txt
index 8572c15ef68..dd433e2bb15 100644
--- a/doc/sphinx/requirements.txt
+++ b/doc/sphinx/requirements.txt
@@ -24,4 +24,4 @@ sphinxcontrib-jquery==4.1
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==2.0.0
sphinxcontrib-serializinghtml==2.0.0
-urllib3==2.5.0
+urllib3==2.6.0
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 4a438181ba9..4420651f765 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -594,12 +594,13 @@ ulong clk_set_rate(struct clk *clk, ulong rate)
if (!clk_valid(clk))
return 0;
ops = clk_dev_ops(clk->dev);
+ clk_get_priv(clk, &clkp);
/* Try to find parents which can set rate */
while (!ops->set_rate) {
struct clk *parent;
- if (!(clk->flags & CLK_SET_RATE_PARENT))
+ if (!(clkp->flags & CLK_SET_RATE_PARENT))
return -ENOSYS;
parent = clk_get_parent(clk);
@@ -608,10 +609,9 @@ ulong clk_set_rate(struct clk *clk, ulong rate)
clk = parent;
ops = clk_dev_ops(clk->dev);
+ clk_get_priv(clk, &clkp);
}
- /* get private clock struct used for cache */
- clk_get_priv(clk, &clkp);
/* Clean up cached rates for us and all child clocks */
clk_clean_rate_cache(clkp);
diff --git a/drivers/clk/exynos/Kconfig b/drivers/clk/exynos/Kconfig
index 85ce9d6e241..dcecbd51b5b 100644
--- a/drivers/clk/exynos/Kconfig
+++ b/drivers/clk/exynos/Kconfig
@@ -15,6 +15,13 @@ config CLK_EXYNOS7420
This enables common clock driver support for platforms based
on Samsung Exynos7420 SoC.
+config CLK_EXYNOS7870
+ bool "Clock driver for Samsung's Exynos7870 SoC"
+ select CLK_CCF
+ help
+ This enables common clock driver support for platforms based
+ on Samsung Exynos7870 SoC.
+
config CLK_EXYNOS850
bool "Clock driver for Samsung's Exynos850 SoC"
select CLK_CCF
diff --git a/drivers/clk/exynos/Makefile b/drivers/clk/exynos/Makefile
index 77385864fef..f5d27d87bd2 100644
--- a/drivers/clk/exynos/Makefile
+++ b/drivers/clk/exynos/Makefile
@@ -9,4 +9,5 @@
obj-$(CONFIG_$(PHASE_)CLK_CCF) += clk.o clk-pll.o
obj-$(CONFIG_CLK_EXYNOS7420) += clk-exynos7420.o
+obj-$(CONFIG_CLK_EXYNOS7870) += clk-exynos7870.o
obj-$(CONFIG_CLK_EXYNOS850) += clk-exynos850.o
diff --git a/drivers/clk/exynos/clk-exynos7870.c b/drivers/clk/exynos/clk-exynos7870.c
new file mode 100644
index 00000000000..d01b1c75350
--- /dev/null
+++ b/drivers/clk/exynos/clk-exynos7870.c
@@ -0,0 +1,929 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Samsung Exynos7870 clock driver.
+ * Copyright (C) 2015 Samsung Electronics Co., Ltd.
+ * Author: Kaustabh Chakraborty <[email protected]>
+ */
+
+#include "linux/clk-provider.h"
+#include <dm.h>
+#include <asm/io.h>
+#include <dt-bindings/clock/samsung,exynos7870-cmu.h>
+#include "clk.h"
+
+enum exynos7870_cmu_id {
+ CMU_MIF,
+ CMU_FSYS,
+ CMU_PERI,
+};
+
+/*
+ * Register offsets for CMU_MIF (0x10460000)
+ */
+#define PLL_LOCKTIME_MIF_MEM_PLL 0x0000
+#define PLL_LOCKTIME_MIF_MEDIA_PLL 0x0020
+#define PLL_LOCKTIME_MIF_BUS_PLL 0x0040
+#define PLL_CON0_MIF_MEM_PLL 0x0100
+#define PLL_CON0_MIF_MEDIA_PLL 0x0120
+#define PLL_CON0_MIF_BUS_PLL 0x0140
+#define CLK_CON_GAT_MIF_MUX_MEM_PLL 0x0200
+#define CLK_CON_GAT_MIF_MUX_MEM_PLL_CON 0x0200
+#define CLK_CON_GAT_MIF_MUX_MEDIA_PLL 0x0204
+#define CLK_CON_GAT_MIF_MUX_MEDIA_PLL_CON 0x0204
+#define CLK_CON_GAT_MIF_MUX_BUS_PLL 0x0208
+#define CLK_CON_GAT_MIF_MUX_BUS_PLL_CON 0x0208
+#define CLK_CON_GAT_MIF_MUX_BUSD 0x0220
+#define CLK_CON_MUX_MIF_BUSD 0x0220
+#define CLK_CON_GAT_MIF_MUX_CMU_ISP_VRA 0x0264
+#define CLK_CON_MUX_MIF_CMU_ISP_VRA 0x0264
+#define CLK_CON_GAT_MIF_MUX_CMU_ISP_CAM 0x0268
+#define CLK_CON_MUX_MIF_CMU_ISP_CAM 0x0268
+#define CLK_CON_GAT_MIF_MUX_CMU_ISP_ISP 0x026c
+#define CLK_CON_MUX_MIF_CMU_ISP_ISP 0x026c
+#define CLK_CON_GAT_MIF_MUX_CMU_DISPAUD_BUS 0x0270
+#define CLK_CON_MUX_MIF_CMU_DISPAUD_BUS 0x0270
+#define CLK_CON_GAT_MIF_MUX_CMU_DISPAUD_DECON_VCLK 0x0274
+#define CLK_CON_MUX_MIF_CMU_DISPAUD_DECON_VCLK 0x0274
+#define CLK_CON_GAT_MIF_MUX_CMU_DISPAUD_DECON_ECLK 0x0278
+#define CLK_CON_MUX_MIF_CMU_DISPAUD_DECON_ECLK 0x0278
+#define CLK_CON_GAT_MIF_MUX_CMU_MFCMSCL_MSCL 0x027c
+#define CLK_CON_MUX_MIF_CMU_MFCMSCL_MSCL 0x027c
+#define CLK_CON_GAT_MIF_MUX_CMU_MFCMSCL_MFC 0x0280
+#define CLK_CON_MUX_MIF_CMU_MFCMSCL_MFC 0x0280
+#define CLK_CON_GAT_MIF_MUX_CMU_FSYS_BUS 0x0284
+#define CLK_CON_MUX_MIF_CMU_FSYS_BUS 0x0284
+#define CLK_CON_GAT_MIF_MUX_CMU_FSYS_MMC0 0x0288
+#define CLK_CON_MUX_MIF_CMU_FSYS_MMC0 0x0288
+#define CLK_CON_GAT_MIF_MUX_CMU_FSYS_MMC1 0x028c
+#define CLK_CON_MUX_MIF_CMU_FSYS_MMC1 0x028c
+#define CLK_CON_GAT_MIF_MUX_CMU_FSYS_MMC2 0x0290
+#define CLK_CON_MUX_MIF_CMU_FSYS_MMC2 0x0290
+#define CLK_CON_GAT_MIF_MUX_CMU_FSYS_USB20DRD_REFCLK 0x029c
+#define CLK_CON_MUX_MIF_CMU_FSYS_USB20DRD_REFCLK 0x029c
+#define CLK_CON_GAT_MIF_MUX_CMU_PERI_BUS 0x02a0
+#define CLK_CON_MUX_MIF_CMU_PERI_BUS 0x02a0
+#define CLK_CON_GAT_MIF_MUX_CMU_PERI_UART1 0x02a4
+#define CLK_CON_MUX_MIF_CMU_PERI_UART1 0x02a4
+#define CLK_CON_GAT_MIF_MUX_CMU_PERI_UART2 0x02a8
+#define CLK_CON_MUX_MIF_CMU_PERI_UART2 0x02a8
+#define CLK_CON_GAT_MIF_MUX_CMU_PERI_UART0 0x02ac
+#define CLK_CON_MUX_MIF_CMU_PERI_UART0 0x02ac
+#define CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI2 0x02b0
+#define CLK_CON_MUX_MIF_CMU_PERI_SPI2 0x02b0
+#define CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI1 0x02b4
+#define CLK_CON_MUX_MIF_CMU_PERI_SPI1 0x02b4
+#define CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI0 0x02b8
+#define CLK_CON_MUX_MIF_CMU_PERI_SPI0 0x02b8
+#define CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI3 0x02bc
+#define CLK_CON_MUX_MIF_CMU_PERI_SPI3 0x02bc
+#define CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI4 0x02c0
+#define CLK_CON_MUX_MIF_CMU_PERI_SPI4 0x02c0
+#define CLK_CON_GAT_MIF_MUX_CMU_ISP_SENSOR0 0x02c4
+#define CLK_CON_MUX_MIF_CMU_ISP_SENSOR0 0x02c4
+#define CLK_CON_GAT_MIF_MUX_CMU_ISP_SENSOR1 0x02c8
+#define CLK_CON_MUX_MIF_CMU_ISP_SENSOR1 0x02c8
+#define CLK_CON_GAT_MIF_MUX_CMU_ISP_SENSOR2 0x02cc
+#define CLK_CON_MUX_MIF_CMU_ISP_SENSOR2 0x02cc
+#define CLK_CON_DIV_MIF_BUSD 0x0420
+#define CLK_CON_DIV_MIF_APB 0x0424
+#define CLK_CON_DIV_MIF_HSI2C 0x0430
+#define CLK_CON_DIV_MIF_CMU_G3D_SWITCH 0x0460
+#define CLK_CON_DIV_MIF_CMU_ISP_VRA 0x0464
+#define CLK_CON_DIV_MIF_CMU_ISP_CAM 0x0468
+#define CLK_CON_DIV_MIF_CMU_ISP_ISP 0x046c
+#define CLK_CON_DIV_MIF_CMU_DISPAUD_BUS 0x0470
+#define CLK_CON_DIV_MIF_CMU_DISPAUD_DECON_VCLK 0x0474
+#define CLK_CON_DIV_MIF_CMU_DISPAUD_DECON_ECLK 0x0478
+#define CLK_CON_DIV_MIF_CMU_MFCMSCL_MSCL 0x047c
+#define CLK_CON_DIV_MIF_CMU_MFCMSCL_MFC 0x0480
+#define CLK_CON_DIV_MIF_CMU_FSYS_BUS 0x0484
+#define CLK_CON_DIV_MIF_CMU_FSYS_MMC0 0x0488
+#define CLK_CON_DIV_MIF_CMU_FSYS_MMC1 0x048c
+#define CLK_CON_DIV_MIF_CMU_FSYS_MMC2 0x0490
+#define CLK_CON_DIV_MIF_CMU_FSYS_USB20DRD_REFCLK 0x049c
+#define CLK_CON_DIV_MIF_CMU_PERI_BUS 0x04a0
+#define CLK_CON_DIV_MIF_CMU_PERI_UART1 0x04a4
+#define CLK_CON_DIV_MIF_CMU_PERI_UART2 0x04a8
+#define CLK_CON_DIV_MIF_CMU_PERI_UART0 0x04ac
+#define CLK_CON_DIV_MIF_CMU_PERI_SPI2 0x04b0
+#define CLK_CON_DIV_MIF_CMU_PERI_SPI1 0x04b4
+#define CLK_CON_DIV_MIF_CMU_PERI_SPI0 0x04b8
+#define CLK_CON_DIV_MIF_CMU_PERI_SPI3 0x04bc
+#define CLK_CON_DIV_MIF_CMU_PERI_SPI4 0x04c0
+#define CLK_CON_DIV_MIF_CMU_ISP_SENSOR0 0x04c4
+#define CLK_CON_DIV_MIF_CMU_ISP_SENSOR1 0x04c8
+#define CLK_CON_DIV_MIF_CMU_ISP_SENSOR2 0x04cc
+#define CLK_CON_GAT_MIF_WRAP_ADC_IF_OSC_SYS 0x080c
+#define CLK_CON_GAT_MIF_HSI2C_AP_PCLKS 0x0828
+#define CLK_CON_GAT_MIF_HSI2C_CP_PCLKS 0x0828
+#define CLK_CON_GAT_MIF_WRAP_ADC_IF_PCLK_S0 0x0828
+#define CLK_CON_GAT_MIF_WRAP_ADC_IF_PCLK_S1 0x0828
+#define CLK_CON_GAT_MIF_CP_PCLK_HSI2C 0x0840
+#define CLK_CON_GAT_MIF_CP_PCLK_HSI2C_BAT_0 0x0840
+#define CLK_CON_GAT_MIF_CP_PCLK_HSI2C_BAT_1 0x0840
+#define CLK_CON_GAT_MIF_HSI2C_AP_PCLKM 0x0840
+#define CLK_CON_GAT_MIF_HSI2C_CP_PCLKM 0x0840
+#define CLK_CON_GAT_MIF_HSI2C_IPCLK 0x0840
+#define CLK_CON_GAT_MIF_HSI2C_ITCLK 0x0840
+#define CLK_CON_GAT_MIF_CMU_G3D_SWITCH 0x0860
+#define CLK_CON_GAT_MIF_CMU_ISP_VRA 0x0864
+#define CLK_CON_GAT_MIF_CMU_ISP_CAM 0x0868
+#define CLK_CON_GAT_MIF_CMU_ISP_ISP 0x086c
+#define CLK_CON_GAT_MIF_CMU_DISPAUD_BUS 0x0870
+#define CLK_CON_GAT_MIF_CMU_DISPAUD_DECON_VCLK 0x0874
+#define CLK_CON_GAT_MIF_CMU_DISPAUD_DECON_ECLK 0x0878
+#define CLK_CON_GAT_MIF_CMU_MFCMSCL_MSCL 0x087c
+#define CLK_CON_GAT_MIF_CMU_MFCMSCL_MFC 0x0880
+#define CLK_CON_GAT_MIF_CMU_FSYS_BUS 0x0884
+#define CLK_CON_GAT_MIF_CMU_FSYS_MMC0 0x0888
+#define CLK_CON_GAT_MIF_CMU_FSYS_MMC1 0x088c
+#define CLK_CON_GAT_MIF_CMU_FSYS_MMC2 0x0890
+#define CLK_CON_GAT_MIF_CMU_FSYS_USB20DRD_REFCLK 0x089c
+#define CLK_CON_GAT_MIF_CMU_PERI_BUS 0x08a0
+#define CLK_CON_GAT_MIF_CMU_PERI_UART1 0x08a4
+#define CLK_CON_GAT_MIF_CMU_PERI_UART2 0x08a8
+#define CLK_CON_GAT_MIF_CMU_PERI_UART0 0x08ac
+#define CLK_CON_GAT_MIF_CMU_PERI_SPI2 0x08b0
+#define CLK_CON_GAT_MIF_CMU_PERI_SPI1 0x08b4
+#define CLK_CON_GAT_MIF_CMU_PERI_SPI0 0x08b8
+#define CLK_CON_GAT_MIF_CMU_PERI_SPI3 0x08bc
+#define CLK_CON_GAT_MIF_CMU_PERI_SPI4 0x08c0
+#define CLK_CON_GAT_MIF_CMU_ISP_SENSOR0 0x08c4
+#define CLK_CON_GAT_MIF_CMU_ISP_SENSOR1 0x08c8
+#define CLK_CON_GAT_MIF_CMU_ISP_SENSOR2 0x08cc
+
+static const struct samsung_pll_clock mif_pll_clks[] = {
+ PLL(pll_1417x, CLK_FOUT_MIF_BUS_PLL, "fout_mif_bus_pll", "oscclk",
+ PLL_CON0_MIF_BUS_PLL),
+ PLL(pll_1417x, CLK_FOUT_MIF_MEDIA_PLL, "fout_mif_media_pll", "oscclk",
+ PLL_CON0_MIF_MEDIA_PLL),
+ PLL(pll_1417x, CLK_FOUT_MIF_MEM_PLL, "fout_mif_mem_pll", "oscclk",
+ PLL_CON0_MIF_MEM_PLL),
+};
+
+static const struct samsung_gate_clock mif_pll_gate_clks[] = {
+ GATE(CLK_GOUT_MIF_MUX_BUS_PLL_CON,
+ "gout_mif_mux_bus_pll_con", "fout_mif_bus_pll",
+ CLK_CON_GAT_MIF_MUX_BUS_PLL_CON, 12,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_MUX_MEDIA_PLL_CON,
+ "gout_mif_mux_media_pll_con", "fout_mif_media_pll",
+ CLK_CON_GAT_MIF_MUX_MEDIA_PLL_CON, 12,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_MUX_MEM_PLL_CON,
+ "gout_mif_mux_mem_pll_con", "fout_mif_mem_pll",
+ CLK_CON_GAT_MIF_MUX_MEM_PLL_CON, 12,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_MUX_BUS_PLL,
+ "gout_mif_mux_bus_pll", "gout_mif_mux_bus_pll_con",
+ CLK_CON_GAT_MIF_MUX_BUS_PLL, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_MUX_MEM_PLL,
+ "gout_mif_mux_mem_pll", "gout_mif_mux_mem_pll_con",
+ CLK_CON_GAT_MIF_MUX_MEM_PLL, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_MUX_MEDIA_PLL,
+ "gout_mif_mux_media_pll", "gout_mif_mux_media_pll_con",
+ CLK_CON_GAT_MIF_MUX_MEDIA_PLL, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+};
+
+static const struct samsung_fixed_factor_clock mif_fixed_factor_clks[] = {
+ FFACTOR(0, "ffac_mif_mux_bus_pll_div2", "gout_mif_mux_bus_pll_con",
+ 1, 2, 0),
+ FFACTOR(0, "ffac_mif_mux_media_pll_div2", "gout_mif_mux_media_pll_con",
+ 1, 2, 0),
+ FFACTOR(0, "ffac_mif_mux_mem_pll_div2", "gout_mif_mux_mem_pll_con",
+ 1, 2, 0),
+};
+
+/* List of parent clocks for muxes in CMU_MIF */
+PNAME(mout_mif_busd_p) = { "ffac_mif_mux_bus_pll_div2",
+ "ffac_mif_mux_media_pll_div2",
+ "ffac_mif_mux_mem_pll_div2" };
+PNAME(mout_mif_cmu_fsys_bus_p) = { "ffac_mif_mux_bus_pll_div2",
+ "ffac_mif_mux_media_pll_div2" };
+PNAME(mout_mif_cmu_fsys_mmc0_p) = { "ffac_mif_mux_bus_pll_div2",
+ "ffac_mif_mux_media_pll_div2" };
+PNAME(mout_mif_cmu_fsys_mmc1_p) = { "ffac_mif_mux_bus_pll_div2",
+ "ffac_mif_mux_media_pll_div2" };
+PNAME(mout_mif_cmu_fsys_mmc2_p) = { "ffac_mif_mux_bus_pll_div2",
+ "ffac_mif_mux_media_pll_div2" };
+PNAME(mout_mif_cmu_fsys_usb20drd_refclk_p) = { "ffac_mif_mux_bus_pll_div2",
+ "ffac_mif_mux_media_pll_div2" };
+PNAME(mout_mif_cmu_peri_bus_p) = { "ffac_mif_mux_bus_pll_div2",
+ "ffac_mif_mux_media_pll_div2" };
+PNAME(mout_mif_cmu_peri_spi0_p) = { "ffac_mif_mux_bus_pll_div2",
+ "oscclk" };
+PNAME(mout_mif_cmu_peri_spi1_p) = { "ffac_mif_mux_bus_pll_div2",
+ "oscclk" };
+PNAME(mout_mif_cmu_peri_spi2_p) = { "ffac_mif_mux_bus_pll_div2",
+ "oscclk" };
+PNAME(mout_mif_cmu_peri_spi3_p) = { "ffac_mif_mux_bus_pll_div2",
+ "oscclk" };
+PNAME(mout_mif_cmu_peri_spi4_p) = { "ffac_mif_mux_bus_pll_div2",
+ "oscclk" };
+PNAME(mout_mif_cmu_peri_uart2_p) = { "ffac_mif_mux_bus_pll_div2",
+ "ffac_mif_mux_media_pll_div2" };
+PNAME(mout_mif_cmu_peri_uart0_p) = { "ffac_mif_mux_bus_pll_div2",
+ "ffac_mif_mux_media_pll_div2" };
+PNAME(mout_mif_cmu_peri_uart1_p) = { "ffac_mif_mux_bus_pll_div2",
+ "ffac_mif_mux_media_pll_div2" };
+
+static const struct samsung_mux_clock mif_mux_clks[] = {
+ MUX(CLK_MOUT_MIF_BUSD,
+ "mout_mif_busd", mout_mif_busd_p,
+ CLK_CON_MUX_MIF_BUSD, 12, 2),
+ MUX(CLK_MOUT_MIF_CMU_FSYS_BUS,
+ "mout_mif_cmu_fsys_bus", mout_mif_cmu_fsys_bus_p,
+ CLK_CON_MUX_MIF_CMU_FSYS_BUS, 12, 1),
+ MUX(CLK_MOUT_MIF_CMU_FSYS_MMC0,
+ "mout_mif_cmu_fsys_mmc0", mout_mif_cmu_fsys_mmc0_p,
+ CLK_CON_MUX_MIF_CMU_FSYS_MMC0, 12, 1),
+ MUX(CLK_MOUT_MIF_CMU_FSYS_MMC1,
+ "mout_mif_cmu_fsys_mmc1", mout_mif_cmu_fsys_mmc1_p,
+ CLK_CON_MUX_MIF_CMU_FSYS_MMC1, 12, 1),
+ MUX(CLK_MOUT_MIF_CMU_FSYS_MMC2,
+ "mout_mif_cmu_fsys_mmc2", mout_mif_cmu_fsys_mmc2_p,
+ CLK_CON_MUX_MIF_CMU_FSYS_MMC2, 12, 1),
+ MUX(CLK_MOUT_MIF_CMU_FSYS_USB20DRD_REFCLK,
+ "mout_mif_cmu_fsys_usb20drd_refclk", mout_mif_cmu_fsys_usb20drd_refclk_p,
+ CLK_CON_MUX_MIF_CMU_FSYS_USB20DRD_REFCLK, 12, 1),
+ MUX(CLK_MOUT_MIF_CMU_PERI_BUS,
+ "mout_mif_cmu_peri_bus", mout_mif_cmu_peri_bus_p,
+ CLK_CON_MUX_MIF_CMU_PERI_BUS, 12, 1),
+ MUX(CLK_MOUT_MIF_CMU_PERI_SPI0,
+ "mout_mif_cmu_peri_spi0", mout_mif_cmu_peri_spi0_p,
+ CLK_CON_MUX_MIF_CMU_PERI_SPI0, 12, 1),
+ MUX(CLK_MOUT_MIF_CMU_PERI_SPI1,
+ "mout_mif_cmu_peri_spi1", mout_mif_cmu_peri_spi1_p,
+ CLK_CON_MUX_MIF_CMU_PERI_SPI1, 12, 1),
+ MUX(CLK_MOUT_MIF_CMU_PERI_SPI2,
+ "mout_mif_cmu_peri_spi2", mout_mif_cmu_peri_spi2_p,
+ CLK_CON_MUX_MIF_CMU_PERI_SPI2, 12, 1),
+ MUX(CLK_MOUT_MIF_CMU_PERI_SPI3,
+ "mout_mif_cmu_peri_spi3", mout_mif_cmu_peri_spi3_p,
+ CLK_CON_MUX_MIF_CMU_PERI_SPI3, 12, 1),
+ MUX(CLK_MOUT_MIF_CMU_PERI_SPI4,
+ "mout_mif_cmu_peri_spi4", mout_mif_cmu_peri_spi4_p,
+ CLK_CON_MUX_MIF_CMU_PERI_SPI4, 12, 1),
+ MUX(CLK_MOUT_MIF_CMU_PERI_UART0,
+ "mout_mif_cmu_peri_uart0", mout_mif_cmu_peri_uart0_p,
+ CLK_CON_MUX_MIF_CMU_PERI_UART0, 12, 1),
+ MUX(CLK_MOUT_MIF_CMU_PERI_UART1,
+ "mout_mif_cmu_peri_uart1", mout_mif_cmu_peri_uart1_p,
+ CLK_CON_MUX_MIF_CMU_PERI_UART1, 12, 1),
+ MUX(CLK_MOUT_MIF_CMU_PERI_UART2,
+ "mout_mif_cmu_peri_uart2", mout_mif_cmu_peri_uart2_p,
+ CLK_CON_MUX_MIF_CMU_PERI_UART2, 12, 1),
+};
+
+static const struct samsung_gate_clock mif_mux_gate_clks[] = {
+ GATE(CLK_GOUT_MIF_MUX_BUSD,
+ "gout_mif_mux_busd", "mout_mif_busd",
+ CLK_CON_GAT_MIF_MUX_BUSD, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_MUX_CMU_FSYS_BUS,
+ "gout_mif_mux_cmu_fsys_bus", "mout_mif_cmu_fsys_bus",
+ CLK_CON_GAT_MIF_MUX_CMU_FSYS_BUS, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_MUX_CMU_FSYS_MMC0,
+ "gout_mif_mux_cmu_fsys_mmc0", "mout_mif_cmu_fsys_mmc0",
+ CLK_CON_GAT_MIF_MUX_CMU_FSYS_MMC0, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_MUX_CMU_FSYS_MMC1,
+ "gout_mif_mux_cmu_fsys_mmc1", "mout_mif_cmu_fsys_mmc1",
+ CLK_CON_GAT_MIF_MUX_CMU_FSYS_MMC1, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_MUX_CMU_FSYS_MMC2,
+ "gout_mif_mux_cmu_fsys_mmc2", "mout_mif_cmu_fsys_mmc2",
+ CLK_CON_GAT_MIF_MUX_CMU_FSYS_MMC2, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_MUX_CMU_FSYS_USB20DRD_REFCLK,
+ "gout_mif_mux_cmu_fsys_usb20drd_refclk", "mout_mif_cmu_fsys_usb20drd_refclk",
+ CLK_CON_GAT_MIF_MUX_CMU_FSYS_USB20DRD_REFCLK, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_MUX_CMU_PERI_BUS,
+ "gout_mif_mux_cmu_peri_bus", "mout_mif_cmu_peri_bus",
+ CLK_CON_GAT_MIF_MUX_CMU_PERI_BUS, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_MUX_CMU_PERI_SPI0,
+ "gout_mif_mux_cmu_peri_spi0", "mout_mif_cmu_peri_spi0",
+ CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI0, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_MUX_CMU_PERI_SPI1,
+ "gout_mif_mux_cmu_peri_spi1", "mout_mif_cmu_peri_spi1",
+ CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI1, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_MUX_CMU_PERI_SPI2,
+ "gout_mif_mux_cmu_peri_spi2", "mout_mif_cmu_peri_spi2",
+ CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI2, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_MUX_CMU_PERI_SPI3,
+ "gout_mif_mux_cmu_peri_spi3", "mout_mif_cmu_peri_spi3",
+ CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI3, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_MUX_CMU_PERI_SPI4,
+ "gout_mif_mux_cmu_peri_spi4", "mout_mif_cmu_peri_spi4",
+ CLK_CON_GAT_MIF_MUX_CMU_PERI_SPI4, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_MUX_CMU_PERI_UART0,
+ "gout_mif_mux_cmu_peri_uart0", "mout_mif_cmu_peri_uart0",
+ CLK_CON_GAT_MIF_MUX_CMU_PERI_UART0, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_MUX_CMU_PERI_UART1,
+ "gout_mif_mux_cmu_peri_uart1", "mout_mif_cmu_peri_uart1",
+ CLK_CON_GAT_MIF_MUX_CMU_PERI_UART1, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_MUX_CMU_PERI_UART2,
+ "gout_mif_mux_cmu_peri_uart2", "mout_mif_cmu_peri_uart2",
+ CLK_CON_GAT_MIF_MUX_CMU_PERI_UART2, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+};
+
+static const struct samsung_div_clock mif_div_clks[] = {
+ DIV(CLK_DOUT_MIF_HSI2C,
+ "dout_mif_hsi2c", "ffac_mif_mux_media_pll_div2",
+ CLK_CON_DIV_MIF_HSI2C, 0, 4),
+ DIV(CLK_DOUT_MIF_BUSD,
+ "dout_mif_busd", "gout_mif_mux_busd",
+ CLK_CON_DIV_MIF_BUSD, 0, 4),
+ DIV(CLK_DOUT_MIF_CMU_FSYS_BUS,
+ "dout_mif_cmu_fsys_bus", "gout_mif_mux_cmu_fsys_bus",
+ CLK_CON_DIV_MIF_CMU_FSYS_BUS, 0, 4),
+ DIV(CLK_DOUT_MIF_CMU_FSYS_MMC0,
+ "dout_mif_cmu_fsys_mmc0", "gout_mif_mux_cmu_fsys_mmc0",
+ CLK_CON_DIV_MIF_CMU_FSYS_MMC0, 0, 10),
+ DIV(CLK_DOUT_MIF_CMU_FSYS_MMC1,
+ "dout_mif_cmu_fsys_mmc1", "gout_mif_mux_cmu_fsys_mmc1",
+ CLK_CON_DIV_MIF_CMU_FSYS_MMC1, 0, 10),
+ DIV(CLK_DOUT_MIF_CMU_FSYS_MMC2,
+ "dout_mif_cmu_fsys_mmc2", "gout_mif_mux_cmu_fsys_mmc2",
+ CLK_CON_DIV_MIF_CMU_FSYS_MMC2, 0, 10),
+ DIV(CLK_DOUT_MIF_CMU_FSYS_USB20DRD_REFCLK,
+ "dout_mif_cmu_fsys_usb20drd_refclk", "gout_mif_mux_cmu_fsys_usb20drd_refclk",
+ CLK_CON_DIV_MIF_CMU_FSYS_USB20DRD_REFCLK, 0, 4),
+ DIV(CLK_DOUT_MIF_CMU_PERI_BUS,
+ "dout_mif_cmu_peri_bus", "gout_mif_mux_cmu_peri_bus",
+ CLK_CON_DIV_MIF_CMU_PERI_BUS, 0, 4),
+ DIV(CLK_DOUT_MIF_CMU_PERI_SPI0,
+ "dout_mif_cmu_peri_spi0", "gout_mif_mux_cmu_peri_spi0",
+ CLK_CON_DIV_MIF_CMU_PERI_SPI0, 0, 6),
+ DIV(CLK_DOUT_MIF_CMU_PERI_SPI1,
+ "dout_mif_cmu_peri_spi1", "gout_mif_mux_cmu_peri_spi1",
+ CLK_CON_DIV_MIF_CMU_PERI_SPI1, 0, 6),
+ DIV(CLK_DOUT_MIF_CMU_PERI_SPI2,
+ "dout_mif_cmu_peri_spi2", "gout_mif_mux_cmu_peri_spi2",
+ CLK_CON_DIV_MIF_CMU_PERI_SPI2, 0, 6),
+ DIV(CLK_DOUT_MIF_CMU_PERI_SPI3,
+ "dout_mif_cmu_peri_spi3", "gout_mif_mux_cmu_peri_spi3",
+ CLK_CON_DIV_MIF_CMU_PERI_SPI3, 0, 6),
+ DIV(CLK_DOUT_MIF_CMU_PERI_SPI4,
+ "dout_mif_cmu_peri_spi4", "gout_mif_mux_cmu_peri_spi4",
+ CLK_CON_DIV_MIF_CMU_PERI_SPI4, 0, 6),
+ DIV(CLK_DOUT_MIF_CMU_PERI_UART0,
+ "dout_mif_cmu_peri_uart0", "gout_mif_mux_cmu_peri_uart0",
+ CLK_CON_DIV_MIF_CMU_PERI_UART0, 0, 4),
+ DIV(CLK_DOUT_MIF_CMU_PERI_UART1,
+ "dout_mif_cmu_peri_uart1", "gout_mif_mux_cmu_peri_uart1",
+ CLK_CON_DIV_MIF_CMU_PERI_UART1, 0, 4),
+ DIV(CLK_DOUT_MIF_CMU_PERI_UART2,
+ "dout_mif_cmu_peri_uart2", "gout_mif_mux_cmu_peri_uart2",
+ CLK_CON_DIV_MIF_CMU_PERI_UART2, 0, 4),
+ DIV(CLK_DOUT_MIF_APB,
+ "dout_mif_apb", "dout_mif_busd",
+ CLK_CON_DIV_MIF_APB, 0, 2),
+};
+
+static const struct samsung_gate_clock mif_gate_clks[] = {
+ GATE(CLK_GOUT_MIF_WRAP_ADC_IF_OSC_SYS,
+ "gout_mif_wrap_adc_if_osc_sys", "oscclk",
+ CLK_CON_GAT_MIF_WRAP_ADC_IF_OSC_SYS, 3,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_HSI2C_AP_PCLKS,
+ "gout_mif_hsi2c_ap_pclks", "dout_mif_apb",
+ CLK_CON_GAT_MIF_HSI2C_AP_PCLKS, 14,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_HSI2C_CP_PCLKS,
+ "gout_mif_hsi2c_cp_pclks", "dout_mif_apb",
+ CLK_CON_GAT_MIF_HSI2C_CP_PCLKS, 15,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_WRAP_ADC_IF_PCLK_S0,
+ "gout_mif_wrap_adc_if_pclk_s0", "dout_mif_apb",
+ CLK_CON_GAT_MIF_WRAP_ADC_IF_PCLK_S0, 20,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_WRAP_ADC_IF_PCLK_S1,
+ "gout_mif_wrap_adc_if_pclk_s1", "dout_mif_apb",
+ CLK_CON_GAT_MIF_WRAP_ADC_IF_PCLK_S1, 21,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_CMU_FSYS_BUS,
+ "gout_mif_cmu_fsys_bus", "dout_mif_cmu_fsys_bus",
+ CLK_CON_GAT_MIF_CMU_FSYS_BUS, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_CMU_FSYS_MMC0,
+ "gout_mif_cmu_fsys_mmc0", "dout_mif_cmu_fsys_mmc0",
+ CLK_CON_GAT_MIF_CMU_FSYS_MMC0, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_CMU_FSYS_MMC1,
+ "gout_mif_cmu_fsys_mmc1", "dout_mif_cmu_fsys_mmc1",
+ CLK_CON_GAT_MIF_CMU_FSYS_MMC1, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_CMU_FSYS_MMC2,
+ "gout_mif_cmu_fsys_mmc2", "dout_mif_cmu_fsys_mmc2",
+ CLK_CON_GAT_MIF_CMU_FSYS_MMC2, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_CMU_FSYS_USB20DRD_REFCLK,
+ "gout_mif_cmu_fsys_usb20drd_refclk", "dout_mif_cmu_fsys_usb20drd_refclk",
+ CLK_CON_GAT_MIF_CMU_FSYS_USB20DRD_REFCLK, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_CMU_PERI_BUS,
+ "gout_mif_cmu_peri_bus", "dout_mif_cmu_peri_bus",
+ CLK_CON_GAT_MIF_CMU_PERI_BUS, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_CMU_PERI_SPI0,
+ "gout_mif_cmu_peri_spi0", "dout_mif_cmu_peri_spi0",
+ CLK_CON_GAT_MIF_CMU_PERI_SPI0, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_CMU_PERI_SPI1,
+ "gout_mif_cmu_peri_spi1", "dout_mif_cmu_peri_spi1",
+ CLK_CON_GAT_MIF_CMU_PERI_SPI1, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_CMU_PERI_SPI2,
+ "gout_mif_cmu_peri_spi2", "dout_mif_cmu_peri_spi2",
+ CLK_CON_GAT_MIF_CMU_PERI_SPI2, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_CMU_PERI_SPI3,
+ "gout_mif_cmu_peri_spi3", "dout_mif_cmu_peri_spi3",
+ CLK_CON_GAT_MIF_CMU_PERI_SPI3, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_CMU_PERI_SPI4,
+ "gout_mif_cmu_peri_spi4", "dout_mif_cmu_peri_spi4",
+ CLK_CON_GAT_MIF_CMU_PERI_SPI4, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_CMU_PERI_UART0,
+ "gout_mif_cmu_peri_uart0", "dout_mif_cmu_peri_uart0",
+ CLK_CON_GAT_MIF_CMU_PERI_UART0, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_CMU_PERI_UART1,
+ "gout_mif_cmu_peri_uart1", "dout_mif_cmu_peri_uart1",
+ CLK_CON_GAT_MIF_CMU_PERI_UART1, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_CMU_PERI_UART2,
+ "gout_mif_cmu_peri_uart2", "dout_mif_cmu_peri_uart2",
+ CLK_CON_GAT_MIF_CMU_PERI_UART2, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_CP_PCLK_HSI2C,
+ "gout_mif_cp_pclk_hsi2c", "dout_mif_hsi2c",
+ CLK_CON_GAT_MIF_CP_PCLK_HSI2C, 6,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_CP_PCLK_HSI2C_BAT_0,
+ "gout_mif_cp_pclk_hsi2c_bat_0", "dout_mif_hsi2c",
+ CLK_CON_GAT_MIF_CP_PCLK_HSI2C_BAT_0, 4,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_CP_PCLK_HSI2C_BAT_1,
+ "gout_mif_cp_pclk_hsi2c_bat_1", "dout_mif_hsi2c",
+ CLK_CON_GAT_MIF_CP_PCLK_HSI2C_BAT_1, 5,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_HSI2C_AP_PCLKM,
+ "gout_mif_hsi2c_ap_pclkm", "dout_mif_hsi2c",
+ CLK_CON_GAT_MIF_HSI2C_AP_PCLKM, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_HSI2C_CP_PCLKM,
+ "gout_mif_hsi2c_cp_pclkm", "dout_mif_hsi2c",
+ CLK_CON_GAT_MIF_HSI2C_CP_PCLKM, 1,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_HSI2C_IPCLK,
+ "gout_mif_hsi2c_ipclk", "dout_mif_hsi2c",
+ CLK_CON_GAT_MIF_HSI2C_IPCLK, 2,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_MIF_HSI2C_ITCLK,
+ "gout_mif_hsi2c_itclk", "dout_mif_hsi2c",
+ CLK_CON_GAT_MIF_HSI2C_ITCLK, 3,
+ CLK_SET_RATE_PARENT, 0),
+};
+
+static const struct samsung_clk_group mif_cmu_clks[] = {
+ { S_CLK_PLL, mif_pll_clks, ARRAY_SIZE(mif_pll_clks) },
+ { S_CLK_GATE, mif_pll_gate_clks, ARRAY_SIZE(mif_pll_gate_clks) },
+ { S_CLK_FFACTOR, mif_fixed_factor_clks, ARRAY_SIZE(mif_fixed_factor_clks) },
+ { S_CLK_MUX, mif_mux_clks, ARRAY_SIZE(mif_mux_clks) },
+ { S_CLK_GATE, mif_mux_gate_clks, ARRAY_SIZE(mif_mux_gate_clks) },
+ { S_CLK_DIV, mif_div_clks, ARRAY_SIZE(mif_div_clks) },
+ { S_CLK_GATE, mif_gate_clks, ARRAY_SIZE(mif_gate_clks) },
+};
+
+static int exynos7870_cmu_mif_probe(struct udevice *dev)
+{
+ return samsung_register_cmu(dev, CMU_MIF, mif_cmu_clks,
+ exynos7870_cmu_mif);
+}
+
+static const struct udevice_id exynos7870_cmu_mif_ids[] = {
+ { .compatible = "samsung,exynos7870-cmu-mif" },
+ { }
+};
+
+SAMSUNG_CLK_OPS(exynos7870_cmu_mif, CMU_MIF);
+
+U_BOOT_DRIVER(exynos7870_cmu_mif) = {
+ .name = "exynos7870-cmu-mif",
+ .id = UCLASS_CLK,
+ .of_match = exynos7870_cmu_mif_ids,
+ .ops = &exynos7870_cmu_mif_clk_ops,
+ .probe = exynos7870_cmu_mif_probe,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+/*
+ * Register offsets for CMU_FSYS (0x13730000)
+ */
+#define PLL_LOCKTIME_FSYS_USB_PLL 0x0000
+#define PLL_CON0_FSYS_USB_PLL 0x0100
+#define CLK_CON_GAT_FSYS_MUX_USB_PLL 0x0200
+#define CLK_CON_GAT_FSYS_MUX_USB_PLL_CON 0x0200
+#define CLK_CON_GAT_FSYS_MUX_USB20DRD_PHYCLOCK_USER 0x0230
+#define CLK_CON_GAT_FSYS_MUX_USB20DRD_PHYCLOCK_USER_CON 0x0230
+#define CLK_CON_GAT_FSYS_BUSP3_HCLK 0x0804
+#define CLK_CON_GAT_FSYS_MMC0_ACLK 0x0804
+#define CLK_CON_GAT_FSYS_MMC1_ACLK 0x0804
+#define CLK_CON_GAT_FSYS_MMC2_ACLK 0x0804
+#define CLK_CON_GAT_FSYS_PDMA0_ACLK_PDMA0 0x0804
+#define CLK_CON_GAT_FSYS_PPMU_ACLK 0x0804
+#define CLK_CON_GAT_FSYS_PPMU_PCLK 0x0804
+#define CLK_CON_GAT_FSYS_SROMC_HCLK 0x0804
+#define CLK_CON_GAT_FSYS_UPSIZER_BUS1_ACLK 0x0804
+#define CLK_CON_GAT_FSYS_USB20DRD_ACLK_HSDRD 0x0804
+#define CLK_CON_GAT_FSYS_USB20DRD_HCLK_USB20_CTRL 0x0804
+#define CLK_CON_GAT_FSYS_USB20DRD_HSDRD_REF_CLK 0x0828
+
+static const struct samsung_fixed_rate_clock fsys_fixed_rate_clks[] = {
+ FRATE(0, "frat_fsys_usb20drd_phyclock", 60000000),
+};
+
+static const struct samsung_pll_clock fsys_pll_clks[] = {
+ PLL(pll_1417x, CLK_FOUT_FSYS_USB_PLL, "fout_fsys_usb_pll", "oscclk",
+ PLL_CON0_FSYS_USB_PLL),
+};
+
+static const struct samsung_gate_clock fsys_gate_clks[] = {
+ GATE(CLK_GOUT_FSYS_BUSP3_HCLK,
+ "gout_fsys_busp3_hclk", "bus",
+ CLK_CON_GAT_FSYS_BUSP3_HCLK, 2,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_FSYS_UPSIZER_BUS1_ACLK,
+ "gout_fsys_upsizer_bus1_aclk", "bus",
+ CLK_CON_GAT_FSYS_UPSIZER_BUS1_ACLK, 12,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_FSYS_PPMU_ACLK,
+ "gout_fsys_ppmu_aclk", "bus",
+ CLK_CON_GAT_FSYS_PPMU_ACLK, 17,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_FSYS_PPMU_PCLK,
+ "gout_fsys_ppmu_pclk", "bus",
+ CLK_CON_GAT_FSYS_PPMU_PCLK, 18,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_FSYS_USB20DRD_HSDRD_REF_CLK,
+ "gout_fsys_usb20drd_hsdrd_ref_clk", "usb20drd",
+ CLK_CON_GAT_FSYS_USB20DRD_HSDRD_REF_CLK, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_FSYS_MUX_USB20DRD_PHYCLOCK_USER_CON,
+ "gout_fsys_mux_usb20drd_phyclock_user_con", "frat_fsys_usb20drd_phyclock",
+ CLK_CON_GAT_FSYS_MUX_USB20DRD_PHYCLOCK_USER_CON, 12,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_FSYS_MUX_USB_PLL_CON,
+ "gout_fsys_mux_usb_pll_con", "fout_fsys_usb_pll",
+ CLK_CON_GAT_FSYS_MUX_USB_PLL_CON, 12,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_FSYS_MMC0_ACLK,
+ "gout_fsys_mmc0_aclk", "gout_fsys_busp3_hclk",
+ CLK_CON_GAT_FSYS_MMC0_ACLK, 8,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_FSYS_MMC1_ACLK,
+ "gout_fsys_mmc1_aclk", "gout_fsys_busp3_hclk",
+ CLK_CON_GAT_FSYS_MMC1_ACLK, 9,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_FSYS_MMC2_ACLK,
+ "gout_fsys_mmc2_aclk", "gout_fsys_busp3_hclk",
+ CLK_CON_GAT_FSYS_MMC2_ACLK, 10,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_FSYS_USB20DRD_ACLK_HSDRD,
+ "gout_fsys_usb20drd_aclk_hsdrd", "gout_fsys_busp3_hclk",
+ CLK_CON_GAT_FSYS_USB20DRD_ACLK_HSDRD, 20,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_FSYS_SROMC_HCLK,
+ "gout_fsys_sromc_hclk", "gout_fsys_busp3_hclk",
+ CLK_CON_GAT_FSYS_SROMC_HCLK, 6,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_FSYS_USB20DRD_HCLK_USB20_CTRL,
+ "gout_fsys_usb20drd_hclk_usb20_ctrl", "gout_fsys_busp3_hclk",
+ CLK_CON_GAT_FSYS_USB20DRD_HCLK_USB20_CTRL, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_FSYS_MUX_USB_PLL,
+ "gout_fsys_mux_usb_pll", "gout_fsys_mux_usb_pll_con",
+ CLK_CON_GAT_FSYS_MUX_USB_PLL, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_FSYS_MUX_USB20DRD_PHYCLOCK_USER,
+ "gout_fsys_mux_usb20drd_phyclock_user", "gout_fsys_mux_usb20drd_phyclock_user_con",
+ CLK_CON_GAT_FSYS_MUX_USB20DRD_PHYCLOCK_USER, 21,
+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_FSYS_PDMA0_ACLK_PDMA0,
+ "gout_fsys_pdma0_aclk_pdma0", "gout_fsys_upsizer_bus1_aclk",
+ CLK_CON_GAT_FSYS_PDMA0_ACLK_PDMA0, 7,
+ CLK_SET_RATE_PARENT, 0),
+};
+
+static const struct samsung_clk_group fsys_cmu_clks[] = {
+ { S_CLK_FRATE, fsys_fixed_rate_clks, ARRAY_SIZE(fsys_fixed_rate_clks) },
+ { S_CLK_PLL, fsys_pll_clks, ARRAY_SIZE(fsys_pll_clks) },
+ { S_CLK_GATE, fsys_gate_clks, ARRAY_SIZE(fsys_gate_clks) },
+};
+
+static int exynos7870_cmu_fsys_probe(struct udevice *dev)
+{
+ return samsung_register_cmu(dev, CMU_FSYS, fsys_cmu_clks,
+ exynos7870_cmu_fsys);
+}
+
+static const struct udevice_id exynos7870_cmu_fsys_ids[] = {
+ { .compatible = "samsung,exynos7870-cmu-fsys" },
+ { }
+};
+
+SAMSUNG_CLK_OPS(exynos7870_cmu_fsys, CMU_FSYS);
+
+U_BOOT_DRIVER(exynos7870_cmu_fsys) = {
+ .name = "exynos7870-cmu-fsys",
+ .id = UCLASS_CLK,
+ .of_match = exynos7870_cmu_fsys_ids,
+ .ops = &exynos7870_cmu_fsys_clk_ops,
+ .probe = exynos7870_cmu_fsys_probe,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+/*
+ * Register offsets for CMU_PERI (0x101f0000)
+ */
+#define CLK_CON_GAT_PERI_PWM_MOTOR_OSCCLK 0x0800
+#define CLK_CON_GAT_PERI_TMU_CLK 0x0800
+#define CLK_CON_GAT_PERI_TMU_CPUCL0_CLK 0x0800
+#define CLK_CON_GAT_PERI_TMU_CPUCL1_CLK 0x0800
+#define CLK_CON_GAT_PERI_BUSP1_PERIC0_HCLK 0x0810
+#define CLK_CON_GAT_PERI_GPIO2_PCLK 0x0810
+#define CLK_CON_GAT_PERI_GPIO5_PCLK 0x0810
+#define CLK_CON_GAT_PERI_GPIO6_PCLK 0x0810
+#define CLK_CON_GAT_PERI_GPIO7_PCLK 0x0810
+#define CLK_CON_GAT_PERI_HSI2C1_IPCLK 0x0810
+#define CLK_CON_GAT_PERI_HSI2C2_IPCLK 0x0810
+#define CLK_CON_GAT_PERI_HSI2C3_IPCLK 0x0810
+#define CLK_CON_GAT_PERI_HSI2C4_IPCLK 0x0810
+#define CLK_CON_GAT_PERI_HSI2C5_IPCLK 0x0810
+#define CLK_CON_GAT_PERI_HSI2C6_IPCLK 0x0810
+#define CLK_CON_GAT_PERI_I2C0_PCLK 0x0810
+#define CLK_CON_GAT_PERI_I2C1_PCLK 0x0810
+#define CLK_CON_GAT_PERI_I2C2_PCLK 0x0810
+#define CLK_CON_GAT_PERI_I2C3_PCLK 0x0810
+#define CLK_CON_GAT_PERI_I2C4_PCLK 0x0810
+#define CLK_CON_GAT_PERI_I2C5_PCLK 0x0810
+#define CLK_CON_GAT_PERI_I2C6_PCLK 0x0810
+#define CLK_CON_GAT_PERI_I2C7_PCLK 0x0810
+#define CLK_CON_GAT_PERI_I2C8_PCLK 0x0810
+#define CLK_CON_GAT_PERI_MCT_PCLK 0x0810
+#define CLK_CON_GAT_PERI_PWM_MOTOR_PCLK_S0 0x0810
+#define CLK_CON_GAT_PERI_SFRIF_TMU_CPUCL0_PCLK 0x0814
+#define CLK_CON_GAT_PERI_SFRIF_TMU_CPUCL1_PCLK 0x0814
+#define CLK_CON_GAT_PERI_SFRIF_TMU_PCLK 0x0814
+#define CLK_CON_GAT_PERI_SPI0_PCLK 0x0814
+#define CLK_CON_GAT_PERI_SPI1_PCLK 0x0814
+#define CLK_CON_GAT_PERI_SPI2_PCLK 0x0814
+#define CLK_CON_GAT_PERI_SPI3_PCLK 0x0814
+#define CLK_CON_GAT_PERI_SPI4_PCLK 0x0814
+#define CLK_CON_GAT_PERI_UART0_PCLK 0x0814
+#define CLK_CON_GAT_PERI_UART1_PCLK 0x0814
+#define CLK_CON_GAT_PERI_UART2_PCLK 0x0814
+#define CLK_CON_GAT_PERI_WDT_CPUCL0_PCLK 0x0814
+#define CLK_CON_GAT_PERI_WDT_CPUCL1_PCLK 0x0814
+#define CLK_CON_GAT_PERI_UART1_EXT_UCLK 0x0830
+#define CLK_CON_GAT_PERI_UART2_EXT_UCLK 0x0834
+#define CLK_CON_GAT_PERI_UART0_EXT_UCLK 0x0838
+#define CLK_CON_GAT_PERI_SPI2_SPI_EXT_CLK 0x083c
+#define CLK_CON_GAT_PERI_SPI1_SPI_EXT_CLK 0x0840
+#define CLK_CON_GAT_PERI_SPI0_SPI_EXT_CLK 0x0844
+#define CLK_CON_GAT_PERI_SPI3_SPI_EXT_CLK 0x0848
+#define CLK_CON_GAT_PERI_SPI4_SPI_EXT_CLK 0x084c
+
+static const struct samsung_gate_clock peri_gate_clks[] = {
+ GATE(CLK_GOUT_PERI_PWM_MOTOR_OSCCLK,
+ "gout_peri_pwm_motor_oscclk", "oscclk",
+ CLK_CON_GAT_PERI_PWM_MOTOR_OSCCLK, 2,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_TMU_CLK,
+ "gout_peri_tmu_clk", "oscclk",
+ CLK_CON_GAT_PERI_TMU_CLK, 6,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_TMU_CPUCL0_CLK,
+ "gout_peri_tmu_cpucl0_clk", "oscclk",
+ CLK_CON_GAT_PERI_TMU_CPUCL0_CLK, 4,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_TMU_CPUCL1_CLK,
+ "gout_peri_tmu_cpucl1_clk", "oscclk",
+ CLK_CON_GAT_PERI_TMU_CPUCL1_CLK, 5,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_BUSP1_PERIC0_HCLK,
+ "gout_peri_busp1_peric0_hclk", "bus",
+ CLK_CON_GAT_PERI_BUSP1_PERIC0_HCLK, 3,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_GPIO2_PCLK,
+ "gout_peri_gpio2_pclk", "bus",
+ CLK_CON_GAT_PERI_GPIO2_PCLK, 7,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_GPIO5_PCLK,
+ "gout_peri_gpio5_pclk", "bus",
+ CLK_CON_GAT_PERI_GPIO5_PCLK, 8,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_GPIO6_PCLK,
+ "gout_peri_gpio6_pclk", "bus",
+ CLK_CON_GAT_PERI_GPIO6_PCLK, 9,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_GPIO7_PCLK,
+ "gout_peri_gpio7_pclk", "bus",
+ CLK_CON_GAT_PERI_GPIO7_PCLK, 10,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_HSI2C5_IPCLK,
+ "gout_peri_hsi2c5_ipclk", "bus",
+ CLK_CON_GAT_PERI_HSI2C5_IPCLK, 15,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_HSI2C6_IPCLK,
+ "gout_peri_hsi2c6_ipclk", "bus",
+ CLK_CON_GAT_PERI_HSI2C6_IPCLK, 16,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_MCT_PCLK,
+ "gout_peri_mct_pclk", "bus",
+ CLK_CON_GAT_PERI_MCT_PCLK, 26,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_PWM_MOTOR_PCLK_S0,
+ "gout_peri_pwm_motor_pclk_s0", "bus",
+ CLK_CON_GAT_PERI_PWM_MOTOR_PCLK_S0, 29,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_SFRIF_TMU_CPUCL0_PCLK,
+ "gout_peri_sfrif_tmu_cpucl0_pclk", "bus",
+ CLK_CON_GAT_PERI_SFRIF_TMU_CPUCL0_PCLK, 1,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_SFRIF_TMU_CPUCL1_PCLK,
+ "gout_peri_sfrif_tmu_cpucl1_pclk", "bus",
+ CLK_CON_GAT_PERI_SFRIF_TMU_CPUCL1_PCLK, 2,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_SFRIF_TMU_PCLK,
+ "gout_peri_sfrif_tmu_pclk", "bus",
+ CLK_CON_GAT_PERI_SFRIF_TMU_PCLK, 3,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_SPI0_PCLK,
+ "gout_peri_spi0_pclk", "bus",
+ CLK_CON_GAT_PERI_SPI0_PCLK, 6,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_SPI1_PCLK,
+ "gout_peri_spi1_pclk", "bus",
+ CLK_CON_GAT_PERI_SPI1_PCLK, 5,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_SPI2_PCLK,
+ "gout_peri_spi2_pclk", "bus",
+ CLK_CON_GAT_PERI_SPI2_PCLK, 4,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_SPI3_PCLK,
+ "gout_peri_spi3_pclk", "bus",
+ CLK_CON_GAT_PERI_SPI3_PCLK, 7,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_SPI4_PCLK,
+ "gout_peri_spi4_pclk", "bus",
+ CLK_CON_GAT_PERI_SPI4_PCLK, 8,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_WDT_CPUCL0_PCLK,
+ "gout_peri_wdt_cpucl0_pclk", "bus",
+ CLK_CON_GAT_PERI_WDT_CPUCL0_PCLK, 13,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_WDT_CPUCL1_PCLK,
+ "gout_peri_wdt_cpucl1_pclk", "bus",
+ CLK_CON_GAT_PERI_WDT_CPUCL1_PCLK, 14,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_SPI0_SPI_EXT_CLK,
+ "gout_peri_spi0_spi_ext_clk", "spi0",
+ CLK_CON_GAT_PERI_SPI0_SPI_EXT_CLK, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_SPI1_SPI_EXT_CLK,
+ "gout_peri_spi1_spi_ext_clk", "spi1",
+ CLK_CON_GAT_PERI_SPI1_SPI_EXT_CLK, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_SPI2_SPI_EXT_CLK,
+ "gout_peri_spi2_spi_ext_clk", "spi2",
+ CLK_CON_GAT_PERI_SPI2_SPI_EXT_CLK, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_SPI3_SPI_EXT_CLK,
+ "gout_peri_spi3_spi_ext_clk", "spi3",
+ CLK_CON_GAT_PERI_SPI3_SPI_EXT_CLK, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_SPI4_SPI_EXT_CLK,
+ "gout_peri_spi4_spi_ext_clk", "spi4",
+ CLK_CON_GAT_PERI_SPI4_SPI_EXT_CLK, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_UART0_EXT_UCLK,
+ "gout_peri_uart0_ext_uclk", "uart0",
+ CLK_CON_GAT_PERI_UART0_EXT_UCLK, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_UART1_EXT_UCLK,
+ "gout_peri_uart1_ext_uclk", "uart1",
+ CLK_CON_GAT_PERI_UART1_EXT_UCLK, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_UART2_EXT_UCLK,
+ "gout_peri_uart2_ext_uclk", "uart2",
+ CLK_CON_GAT_PERI_UART2_EXT_UCLK, 0,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_HSI2C1_IPCLK,
+ "gout_peri_hsi2c1_ipclk", "gout_peri_busp1_peric0_hclk",
+ CLK_CON_GAT_PERI_HSI2C1_IPCLK, 11,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_HSI2C2_IPCLK,
+ "gout_peri_hsi2c2_ipclk", "gout_peri_busp1_peric0_hclk",
+ CLK_CON_GAT_PERI_HSI2C2_IPCLK, 12,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_HSI2C3_IPCLK,
+ "gout_peri_hsi2c3_ipclk", "gout_peri_busp1_peric0_hclk",
+ CLK_CON_GAT_PERI_HSI2C3_IPCLK, 13,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_HSI2C4_IPCLK,
+ "gout_peri_hsi2c4_ipclk", "gout_peri_busp1_peric0_hclk",
+ CLK_CON_GAT_PERI_HSI2C4_IPCLK, 14,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_I2C0_PCLK,
+ "gout_peri_i2c0_pclk", "gout_peri_busp1_peric0_hclk",
+ CLK_CON_GAT_PERI_I2C0_PCLK, 21,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_I2C1_PCLK,
+ "gout_peri_i2c1_pclk", "gout_peri_busp1_peric0_hclk",
+ CLK_CON_GAT_PERI_I2C1_PCLK, 23,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_I2C2_PCLK,
+ "gout_peri_i2c2_pclk", "gout_peri_busp1_peric0_hclk",
+ CLK_CON_GAT_PERI_I2C2_PCLK, 22,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_I2C3_PCLK,
+ "gout_peri_i2c3_pclk", "gout_peri_busp1_peric0_hclk",
+ CLK_CON_GAT_PERI_I2C3_PCLK, 20,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_I2C4_PCLK,
+ "gout_peri_i2c4_pclk", "gout_peri_busp1_peric0_hclk",
+ CLK_CON_GAT_PERI_I2C4_PCLK, 17,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_I2C5_PCLK,
+ "gout_peri_i2c5_pclk", "gout_peri_busp1_peric0_hclk",
+ CLK_CON_GAT_PERI_I2C5_PCLK, 18,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_I2C6_PCLK,
+ "gout_peri_i2c6_pclk", "gout_peri_busp1_peric0_hclk",
+ CLK_CON_GAT_PERI_I2C6_PCLK, 19,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_I2C7_PCLK,
+ "gout_peri_i2c7_pclk", "gout_peri_busp1_peric0_hclk",
+ CLK_CON_GAT_PERI_I2C7_PCLK, 24,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_I2C8_PCLK,
+ "gout_peri_i2c8_pclk", "gout_peri_busp1_peric0_hclk",
+ CLK_CON_GAT_PERI_I2C8_PCLK, 25,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_UART0_PCLK,
+ "gout_peri_uart0_pclk", "gout_peri_busp1_peric0_hclk",
+ CLK_CON_GAT_PERI_UART0_PCLK, 10,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_UART1_PCLK,
+ "gout_peri_uart1_pclk", "gout_peri_busp1_peric0_hclk",
+ CLK_CON_GAT_PERI_UART1_PCLK, 11,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_PERI_UART2_PCLK,
+ "gout_peri_uart2_pclk", "gout_peri_busp1_peric0_hclk",
+ CLK_CON_GAT_PERI_UART2_PCLK, 12,
+ CLK_SET_RATE_PARENT, 0),
+};
+
+static const struct samsung_clk_group peri_cmu_clks[] = {
+ { S_CLK_GATE, peri_gate_clks, ARRAY_SIZE(peri_gate_clks) },
+};
+
+static int exynos7870_cmu_peri_probe(struct udevice *dev)
+{
+ return samsung_register_cmu(dev, CMU_PERI, peri_cmu_clks,
+ exynos7870_cmu_peri);
+}
+
+static const struct udevice_id exynos7870_cmu_peri_ids[] = {
+ { .compatible = "samsung,exynos7870-cmu-peri" },
+ { }
+};
+
+SAMSUNG_CLK_OPS(exynos7870_cmu_peri, CMU_PERI);
+
+U_BOOT_DRIVER(exynos7870_cmu_peri) = {
+ .name = "exynos7870-cmu-peri",
+ .id = UCLASS_CLK,
+ .of_match = exynos7870_cmu_peri_ids,
+ .ops = &exynos7870_cmu_peri_clk_ops,
+ .probe = exynos7870_cmu_peri_probe,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/exynos/clk-pll.c b/drivers/clk/exynos/clk-pll.c
index 542d577eaa6..4b67591af10 100644
--- a/drivers/clk/exynos/clk-pll.c
+++ b/drivers/clk/exynos/clk-pll.c
@@ -117,6 +117,7 @@ static struct clk *_samsung_clk_register_pll(void __iomem *base,
switch (pll_clk->type) {
case pll_0822x:
+ case pll_1417x:
drv_name = UBOOT_DM_CLK_SAMSUNG_PLL0822X;
break;
case pll_0831x:
@@ -136,7 +137,8 @@ static struct clk *_samsung_clk_register_pll(void __iomem *base,
return clk;
}
-void samsung_clk_register_pll(void __iomem *base, unsigned int cmu_id,
+void samsung_clk_register_pll(struct udevice *dev, void __iomem *base,
+ unsigned int cmu_id,
const struct samsung_pll_clock *clk_list,
unsigned int nr_clk)
{
diff --git a/drivers/clk/exynos/clk-pll.h b/drivers/clk/exynos/clk-pll.h
index bdc94e7624d..d5dfc8934ba 100644
--- a/drivers/clk/exynos/clk-pll.h
+++ b/drivers/clk/exynos/clk-pll.h
@@ -20,9 +20,11 @@ struct samsung_pll_clock;
enum samsung_pll_type {
pll_0822x,
pll_0831x,
+ pll_1417x,
};
-void samsung_clk_register_pll(void __iomem *base, unsigned int cmu_id,
+void samsung_clk_register_pll(struct udevice *dev, void __iomem *base,
+ unsigned int cmu_id,
const struct samsung_pll_clock *clk_list,
unsigned int nr_clk);
diff --git a/drivers/clk/exynos/clk.c b/drivers/clk/exynos/clk.c
index 943e8bd0189..a2c9f4851da 100644
--- a/drivers/clk/exynos/clk.c
+++ b/drivers/clk/exynos/clk.c
@@ -10,7 +10,62 @@
#include <dm.h>
#include "clk.h"
-static void samsung_clk_register_mux(void __iomem *base, unsigned int cmu_id,
+int samsung_clk_request(struct clk *clk)
+{
+ struct clk *c;
+ int ret;
+
+ ret = clk_get_by_id(clk->id, &c);
+ if (ret)
+ return ret;
+
+ clk->dev = c->dev;
+ return 0;
+}
+
+static void
+samsung_clk_register_fixed_rate(struct udevice *dev, void __iomem *base,
+ unsigned int cmu_id,
+ const struct samsung_fixed_rate_clock *clk_list,
+ unsigned int nr_clk)
+{
+ unsigned int cnt;
+
+ for (cnt = 0; cnt < nr_clk; cnt++) {
+ struct clk *clk;
+ const struct samsung_fixed_rate_clock *m;
+ unsigned long clk_id;
+
+ m = &clk_list[cnt];
+ clk = clk_register_fixed_rate(NULL, m->name, m->fixed_rate);
+ clk_id = SAMSUNG_TO_CLK_ID(cmu_id, m->id);
+ clk_dm(clk_id, clk);
+ }
+}
+
+static void
+samsung_clk_register_fixed_factor(struct udevice *dev, void __iomem *base,
+ unsigned int cmu_id,
+ const struct samsung_fixed_factor_clock *clk_list,
+ unsigned int nr_clk)
+{
+ unsigned int cnt;
+
+ for (cnt = 0; cnt < nr_clk; cnt++) {
+ struct clk *clk;
+ const struct samsung_fixed_factor_clock *m;
+ unsigned long clk_id;
+
+ m = &clk_list[cnt];
+ clk = clk_register_fixed_factor(dev, m->name, m->parent_name,
+ m->flags, m->mult, m->div);
+ clk_id = SAMSUNG_TO_CLK_ID(cmu_id, m->id);
+ clk_dm(clk_id, clk);
+ }
+}
+
+static void samsung_clk_register_mux(struct udevice *dev, void __iomem *base,
+ unsigned int cmu_id,
const struct samsung_mux_clock *clk_list,
unsigned int nr_clk)
{
@@ -22,15 +77,17 @@ static void samsung_clk_register_mux(void __iomem *base, unsigned int cmu_id,
unsigned long clk_id;
m = &clk_list[cnt];
- clk = clk_register_mux(NULL, m->name, m->parent_names,
- m->num_parents, m->flags, base + m->offset, m->shift,
- m->width, m->mux_flags);
+ clk = clk_register_mux(dev, m->name, m->parent_names,
+ m->num_parents, m->flags,
+ base + m->offset, m->shift, m->width,
+ m->mux_flags);
clk_id = SAMSUNG_TO_CLK_ID(cmu_id, m->id);
clk_dm(clk_id, clk);
}
}
-static void samsung_clk_register_div(void __iomem *base, unsigned int cmu_id,
+static void samsung_clk_register_div(struct udevice *dev, void __iomem *base,
+ unsigned int cmu_id,
const struct samsung_div_clock *clk_list,
unsigned int nr_clk)
{
@@ -42,15 +99,16 @@ static void samsung_clk_register_div(void __iomem *base, unsigned int cmu_id,
unsigned long clk_id;
d = &clk_list[cnt];
- clk = clk_register_divider(NULL, d->name, d->parent_name,
- d->flags, base + d->offset, d->shift,
- d->width, d->div_flags);
+ clk = clk_register_divider(dev, d->name, d->parent_name,
+ d->flags, base + d->offset, d->shift,
+ d->width, d->div_flags);
clk_id = SAMSUNG_TO_CLK_ID(cmu_id, d->id);
clk_dm(clk_id, clk);
}
}
-static void samsung_clk_register_gate(void __iomem *base, unsigned int cmu_id,
+static void samsung_clk_register_gate(struct udevice *dev, void __iomem *base,
+ unsigned int cmu_id,
const struct samsung_gate_clock *clk_list,
unsigned int nr_clk)
{
@@ -62,19 +120,21 @@ static void samsung_clk_register_gate(void __iomem *base, unsigned int cmu_id,
unsigned long clk_id;
g = &clk_list[cnt];
- clk = clk_register_gate(NULL, g->name, g->parent_name,
- g->flags, base + g->offset, g->bit_idx,
- g->gate_flags, NULL);
+ clk = clk_register_gate(dev, g->name, g->parent_name,
+ g->flags, base + g->offset, g->bit_idx,
+ g->gate_flags, NULL);
clk_id = SAMSUNG_TO_CLK_ID(cmu_id, g->id);
clk_dm(clk_id, clk);
}
}
-typedef void (*samsung_clk_register_fn)(void __iomem *base, unsigned int cmu_id,
- const void *clk_list,
+typedef void (*samsung_clk_register_fn)(struct udevice *dev, void __iomem *base,
+ unsigned int cmu_id, const void *clk_list,
unsigned int nr_clk);
static const samsung_clk_register_fn samsung_clk_register_fns[] = {
+ [S_CLK_FRATE] = (samsung_clk_register_fn)samsung_clk_register_fixed_rate,
+ [S_CLK_FFACTOR] = (samsung_clk_register_fn)samsung_clk_register_fixed_factor,
[S_CLK_MUX] = (samsung_clk_register_fn)samsung_clk_register_mux,
[S_CLK_DIV] = (samsung_clk_register_fn)samsung_clk_register_div,
[S_CLK_GATE] = (samsung_clk_register_fn)samsung_clk_register_gate,
@@ -91,16 +151,17 @@ static const samsung_clk_register_fn samsung_clk_register_fns[] = {
* Having the array of clock groups @clk_groups makes it possible to keep a
* correct clocks registration order.
*/
-static void samsung_cmu_register_clocks(void __iomem *base, unsigned int cmu_id,
- const struct samsung_clk_group *clk_groups,
- unsigned int nr_groups)
+static void samsung_cmu_register_clocks(struct udevice *dev, void __iomem *base,
+ unsigned int cmu_id,
+ const struct samsung_clk_group *clk_groups,
+ unsigned int nr_groups)
{
unsigned int i;
for (i = 0; i < nr_groups; i++) {
const struct samsung_clk_group *g = &clk_groups[i];
- samsung_clk_register_fns[g->type](base, cmu_id,
+ samsung_clk_register_fns[g->type](dev, base, cmu_id,
g->clk_list, g->nr_clk);
}
}
@@ -124,7 +185,7 @@ int samsung_cmu_register_one(struct udevice *dev, unsigned int cmu_id,
if (!base)
return -EINVAL;
- samsung_cmu_register_clocks(base, cmu_id, clk_groups, nr_groups);
+ samsung_cmu_register_clocks(dev, base, cmu_id, clk_groups, nr_groups);
return 0;
}
diff --git a/drivers/clk/exynos/clk.h b/drivers/clk/exynos/clk.h
index ed0a395f0f6..c25b7cb59d4 100644
--- a/drivers/clk/exynos/clk.h
+++ b/drivers/clk/exynos/clk.h
@@ -9,10 +9,13 @@
#ifndef __EXYNOS_CLK_H
#define __EXYNOS_CLK_H
+#include <clk.h>
#include <errno.h>
#include <linux/clk-provider.h>
#include "clk-pll.h"
+int samsung_clk_request(struct clk *clk);
+
#define _SAMSUNG_CLK_OPS(_name, _cmu) \
static int _name##_of_xlate(struct clk *clk, \
struct ofnode_phandle_args *args) \
@@ -37,6 +40,7 @@ static const struct clk_ops _name##_clk_ops = { \
.enable = ccf_clk_enable, \
.disable = ccf_clk_disable, \
.of_xlate = _name##_of_xlate, \
+ .request = samsung_clk_request, \
}
/**
@@ -59,6 +63,53 @@ static const struct clk_ops _name##_clk_ops = { \
#define SAMSUNG_TO_CLK_ID(_cmu, _id) (((_cmu) << 8) | ((_id) & 0xff))
/**
+ * struct samsung_fixed_rate_clock - information about fixed-rate clock
+ * @id: platform specific id of the clock
+ * @name: name of this fixed-rate clock
+ * @fixed_rate: fixed clock rate of this clock
+ */
+struct samsung_fixed_rate_clock {
+ unsigned int id;
+ const char *name;
+ unsigned long fixed_rate;
+};
+
+#define FRATE(_id, cname, frate) \
+ { \
+ .id = _id, \
+ .name = cname, \
+ .fixed_rate = frate, \
+ }
+
+/**
+ * struct samsung_fixed_factor_clock - information about fixed-factor clock
+ * @id: platform specific id of the clock
+ * @name: name of this fixed-factor clock
+ * @parent_name: parent clock name
+ * @mult: fixed multiplication factor
+ * @div: fixed division factor
+ * @flags: optional fixed-factor clock flags
+ */
+struct samsung_fixed_factor_clock {
+ unsigned int id;
+ const char *name;
+ const char *parent_name;
+ unsigned long mult;
+ unsigned long div;
+ unsigned long flags;
+};
+
+#define FFACTOR(_id, cname, pname, m, d, f) \
+ { \
+ .id = _id, \
+ .name = cname, \
+ .parent_name = pname, \
+ .mult = m, \
+ .div = d, \
+ .flags = f, \
+ }
+
+/**
* struct samsung_mux_clock - information about mux clock
* @id: platform specific id of the clock
* @name: name of this mux clock
@@ -206,6 +257,8 @@ struct samsung_pll_clock {
}
enum samsung_clock_type {
+ S_CLK_FRATE,
+ S_CLK_FFACTOR,
S_CLK_MUX,
S_CLK_DIV,
S_CLK_GATE,
diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile
index 6c742553091..354035baf2d 100644
--- a/drivers/clk/renesas/Makefile
+++ b/drivers/clk/renesas/Makefile
@@ -26,3 +26,7 @@ obj-$(CONFIG_CLK_R8A779H0) += r8a779h0-cpg-mssr.o
obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o
obj-$(CONFIG_CLK_RZG2L) += rzg2l-cpg.o
obj-$(CONFIG_CLK_R9A07G044) += r9a07g044-cpg.o
+
+# Temporary stub clock used for SCP compatibility.
+# This is going to be removed once SCP solidifies.
+obj-$(CONFIG_R8A78000) += compound-clock.o
diff --git a/drivers/clk/renesas/compound-clock.c b/drivers/clk/renesas/compound-clock.c
new file mode 100644
index 00000000000..499a2598833
--- /dev/null
+++ b/drivers/clk/renesas/compound-clock.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2025 Marek Vasut <[email protected]>
+ */
+
+#define LOG_CATEGORY UCLASS_CLK
+
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <linux/clk-provider.h>
+#include <log.h>
+
+struct clk_compound_rate {
+ struct clk clk; /* This clock */
+ struct clk mdlc; /* MDLC parent module clock */
+ struct clk per; /* Peripheral parent clock */
+};
+
+static struct clk_compound_rate *to_clk_compound_rate(struct clk *clk)
+{
+ return (struct clk_compound_rate *)dev_get_plat(clk->dev);
+}
+
+static int clk_compound_rate_enable(struct clk *clk)
+{
+ struct clk_compound_rate *cc = to_clk_compound_rate(clk);
+
+ return clk_enable(&cc->mdlc);
+}
+
+static int clk_compound_rate_disable(struct clk *clk)
+{
+ struct clk_compound_rate *cc = to_clk_compound_rate(clk);
+
+ return clk_disable(&cc->mdlc);
+}
+
+static ulong clk_compound_rate_get_rate(struct clk *clk)
+{
+ struct clk_compound_rate *cc = to_clk_compound_rate(clk);
+
+ return clk_get_rate(&cc->per);
+}
+
+static ulong clk_compound_rate_set_rate(struct clk *clk, ulong rate)
+{
+ return 0; /* Set rate is not forwarded to SCP */
+}
+
+const struct clk_ops clk_compound_rate_ops = {
+ .enable = clk_compound_rate_enable,
+ .disable = clk_compound_rate_disable,
+ .get_rate = clk_compound_rate_get_rate,
+ .set_rate = clk_compound_rate_set_rate,
+};
+
+static int clk_compound_rate_of_to_plat(struct udevice *dev)
+{
+ struct clk_compound_rate *cc = (struct clk_compound_rate *)dev_get_plat(dev);
+ struct clk *clk = &cc->clk;
+ int ret;
+
+ clk->dev = dev;
+ clk->id = CLK_ID(dev, 0);
+ clk->enable_count = 0;
+
+ ret = clk_get_by_index(dev, 0, &cc->mdlc);
+ if (ret)
+ return ret;
+
+ ret = clk_get_by_index(dev, 1, &cc->per);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static const struct udevice_id clk_compound_rate_match[] = {
+ { .compatible = "renesas,compound-clock", },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(renesas_compound_clock) = {
+ .name = "compound-clock",
+ .id = UCLASS_CLK,
+ .of_match = clk_compound_rate_match,
+ .of_to_plat = clk_compound_rate_of_to_plat,
+ .plat_auto = sizeof(struct clk_compound_rate),
+ .ops = &clk_compound_rate_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 142db9e47b8..18ca8ad4cac 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -154,6 +154,14 @@ config DWAPB_GPIO
help
Support for the Designware APB GPIO driver.
+config SPL_DWAPB_GPIO
+ bool "DWAPB GPIO driver in SPL"
+ depends on SPL_DM_GPIO
+ help
+ Support for the Designware APB GPIO driver in SPL.
+
+ If unsure, say N.
+
config AT91_GPIO
bool "AT91 PIO GPIO driver"
depends on ARCH_AT91
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 73c94329e36..910478c0c7a 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -4,12 +4,12 @@
# Wolfgang Denk, DENX Software Engineering, [email protected].
ifndef CONFIG_XPL_BUILD
-obj-$(CONFIG_DWAPB_GPIO) += dwapb_gpio.o
obj-$(CONFIG_AXP_GPIO) += axp_gpio.o
obj-$(CONFIG_DM_74X164) += 74x164_gpio.o
endif
obj-$(CONFIG_$(PHASE_)DM_GPIO) += gpio-uclass.o
+obj-$(CONFIG_$(PHASE_)DWAPB_GPIO) += dwapb_gpio.o
obj-$(CONFIG_$(PHASE_)DM_PCA953X) += pca953x_gpio.o
obj-$(CONFIG_ADI_GPIO) += gpio-adi-adsp.o
diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c
index 53dbbe97b5a..c072f146514 100644
--- a/drivers/gpio/s5p_gpio.c
+++ b/drivers/gpio/s5p_gpio.c
@@ -319,7 +319,7 @@ static int gpio_exynos_bind(struct udevice *parent)
base = dev_read_addr_ptr(parent);
for (node = fdt_first_subnode(blob, dev_of_offset(parent)), bank = base;
node > 0;
- node = fdt_next_subnode(blob, node), bank++) {
+ node = fdt_next_subnode(blob, node)) {
struct exynos_gpio_plat *plat;
struct udevice *dev;
fdt_addr_t reg;
@@ -341,9 +341,8 @@ static int gpio_exynos_bind(struct udevice *parent)
if (reg != FDT_ADDR_T_NONE)
bank = (struct s5p_gpio_bank *)((ulong)base + reg);
- plat->bank = bank;
-
debug("dev at %p: %s\n", bank, plat->bank_name);
+ plat->bank = bank++;
}
return 0;
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index f9531c1627c..cfd2a3be3fd 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -66,6 +66,16 @@ config K3_SEC_PROXY
Select this driver if your platform has support for this hardware
block.
+config RCAR_MFIS_MBOX
+ bool "Renesas MFIS Multifunctional Interface mailbox driver"
+ depends on DM_MAILBOX && ARCH_RENESAS
+ help
+ This enables support for the Renesas MFIS mailbox module, which
+ provides an interface between the different CPU Cores, such as AP
+ System Core domain and the Realtime Core domain, SCP Core domain
+ and AP System Core domain or Realtime Core domain and AP System
+ Core domain or Realtime Core domain.
+
config ZYNQMP_IPI
bool "Xilinx ZynqMP IPI controller support"
depends on DM_MAILBOX && (ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET || ARCH_VERSAL2)
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index b54fbdfff15..b3a36691497 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -12,4 +12,5 @@ obj-$(CONFIG_SANDBOX_MBOX) += sandbox-mbox-test.o
obj-$(CONFIG_STM32_IPCC) += stm32-ipcc.o
obj-$(CONFIG_TEGRA_HSP) += tegra-hsp.o
obj-$(CONFIG_K3_SEC_PROXY) += k3-sec-proxy.o
+obj-$(CONFIG_RCAR_MFIS_MBOX) += renesas-mfis.o
obj-$(CONFIG_ZYNQMP_IPI) += zynqmp-ipi.o
diff --git a/drivers/mailbox/renesas-mfis.c b/drivers/mailbox/renesas-mfis.c
new file mode 100644
index 00000000000..1e9e8285974
--- /dev/null
+++ b/drivers/mailbox/renesas-mfis.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020-2025, Renesas Electronics Corporation.
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <linux/delay.h>
+#include <mailbox-uclass.h>
+
+#define COM 0x0
+#define IIR BIT(0)
+
+struct mfis_priv {
+ void __iomem *tx_base;
+};
+
+static int mfis_send(struct mbox_chan *chan, const void *data)
+{
+ struct mfis_priv *mfis = dev_get_priv(chan->dev);
+
+ writel(IIR, mfis->tx_base + COM);
+
+ /* Give the remote side some time. */
+ mdelay(1);
+
+ writel(0, mfis->tx_base + COM);
+
+ return 0;
+}
+
+struct mbox_ops mfis_mbox_ops = {
+ .send = mfis_send,
+};
+
+static int mfis_mbox_probe(struct udevice *dev)
+{
+ struct mfis_priv *mbox = dev_get_priv(dev);
+
+ mbox->tx_base = dev_read_addr_index_ptr(dev, 0);
+ if (!mbox->tx_base)
+ return -ENODEV;
+
+ return 0;
+}
+
+static const struct udevice_id mfis_mbox_of_match[] = {
+ { .compatible = "renesas,mfis-mbox", },
+ {},
+};
+
+U_BOOT_DRIVER(renesas_mfis) = {
+ .name = "renesas-mfis",
+ .id = UCLASS_MAILBOX,
+ .of_match = mfis_mbox_of_match,
+ .probe = mfis_mbox_probe,
+ .priv_auto = sizeof(struct mfis_priv),
+ .ops = &mfis_mbox_ops,
+};
diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c
index db4e0129c2e..6219284df3e 100644
--- a/drivers/mmc/socfpga_dw_mmc.c
+++ b/drivers/mmc/socfpga_dw_mmc.c
@@ -58,17 +58,24 @@ static int socfpga_dwmci_clksel(struct dwmci_host *host)
u32 sdmmc_mask = ((priv->smplsel & 0x7) << SYSMGR_SDMMC_SMPLSEL_SHIFT) |
((priv->drvsel & 0x7) << SYSMGR_SDMMC_DRVSEL_SHIFT);
- ret = clk_get_by_name(priv->dev, "ciu", &priv->mmc_clk_ciu);
- if (ret) {
- debug("%s: Failed to get SDMMC clock from dts\n", __func__);
- return ret;
- }
-
- /* Disable SDMMC clock. */
- ret = clk_disable(&priv->mmc_clk_ciu);
- if (ret) {
- printf("%s: Failed to disable SDMMC clock\n", __func__);
- return ret;
+ if (!IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX) &&
+ !IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX7M)) {
+ /* Disable SDMMC clock. */
+ clrbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_PERPLL_EN,
+ CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK);
+ } else {
+ ret = clk_get_by_name(priv->dev, "ciu", &priv->mmc_clk_ciu);
+ if (ret) {
+ debug("%s: Failed to get SDMMC clock from dts\n", __func__);
+ return ret;
+ }
+
+ /* Disable SDMMC clock. */
+ ret = clk_disable(&priv->mmc_clk_ciu);
+ if (ret) {
+ printf("%s: Failed to disable SDMMC clock\n", __func__);
+ return ret;
+ }
}
debug("%s: drvsel %d smplsel %d\n", __func__,
@@ -88,11 +95,18 @@ static int socfpga_dwmci_clksel(struct dwmci_host *host)
readl(socfpga_get_sysmgr_addr() + SYSMGR_SDMMC));
#endif
- /* Enable SDMMC clock */
- ret = clk_enable(&priv->mmc_clk_ciu);
- if (ret) {
- printf("%s: Failed to enable SDMMC clock\n", __func__);
- return ret;
+ if (!IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX) &&
+ !IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX7M)) {
+ /* Enable SDMMC clock */
+ setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_PERPLL_EN,
+ CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK);
+ } else {
+ /* Enable SDMMC clock */
+ ret = clk_enable(&priv->mmc_clk_ciu);
+ if (ret) {
+ printf("%s: Failed to enable SDMMC clock\n", __func__);
+ return ret;
+ }
}
return 0;
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 1bd33a200c1..5e4d1c0a937 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -212,6 +212,7 @@ config NAND_CADENCE
config NAND_DENALI
bool
select SYS_NAND_SELF_INIT
+ select SYS_NAND_ONFI_DETECTION if TARGET_SOCFPGA_SOC64
imply CMD_NAND
config NAND_DENALI_DT
diff --git a/drivers/mtd/nand/raw/atmel/pmecc.c b/drivers/mtd/nand/raw/atmel/pmecc.c
index e500a0fe3f8..1acaa5d0e07 100644
--- a/drivers/mtd/nand/raw/atmel/pmecc.c
+++ b/drivers/mtd/nand/raw/atmel/pmecc.c
@@ -142,6 +142,7 @@ struct atmel_pmecc_caps {
int nstrengths;
int el_offset;
bool correct_erased_chunks;
+ bool clk_ctrl;
};
struct atmel_pmecc_user_conf_cache {
@@ -819,8 +820,7 @@ EXPORT_SYMBOL_GPL(atmel_pmecc_wait_rdy);
static struct atmel_pmecc *
atmel_pmecc_create(struct udevice *dev,
const struct atmel_pmecc_caps *caps,
- int pmecc_res_idx, int errloc_res_idx,
- int timing_res_idx)
+ int pmecc_res_idx, int errloc_res_idx)
{
struct atmel_pmecc *pmecc;
struct resource res;
@@ -838,7 +838,9 @@ atmel_pmecc_create(struct udevice *dev,
ofnode_read_resource(dev->node_, 1, &res);
pmecc->regs.errloc = (void *)res.start;
- pmecc->regs.timing = 0;
+ /* pmecc data setup time */
+ if (caps->clk_ctrl)
+ writel(PMECC_CLK_133MHZ, pmecc->regs.base + ATMEL_PMECC_CLK);
/* Disable all interrupts before registering the PMECC handler. */
writel(0xffffffff, pmecc->regs.base + ATMEL_PMECC_IDR);
@@ -884,6 +886,7 @@ static struct atmel_pmecc_caps at91sam9g45_caps = {
.strengths = atmel_pmecc_strengths,
.nstrengths = 5,
.el_offset = 0x8c,
+ .clk_ctrl = true,
};
static struct atmel_pmecc_caps sama5d4_caps = {
@@ -946,7 +949,7 @@ static int atmel_pmecc_probe(struct udevice *dev)
return -EINVAL;
}
- pmecc = atmel_pmecc_create(dev, caps, 0, 1, 2);
+ pmecc = atmel_pmecc_create(dev, caps, 0, 1);
if (IS_ERR(pmecc))
return PTR_ERR(pmecc);
diff --git a/drivers/mtd/nand/raw/atmel/pmecc.h b/drivers/mtd/nand/raw/atmel/pmecc.h
index 43f96b2f168..88b0d18040e 100644
--- a/drivers/mtd/nand/raw/atmel/pmecc.h
+++ b/drivers/mtd/nand/raw/atmel/pmecc.h
@@ -65,7 +65,6 @@ struct atmel_pmecc {
struct {
void __iomem *base;
void __iomem *errloc;
- void __iomem *timing;
} regs;
/* Mutex used for pmecc enable/disable */
diff --git a/drivers/net/dwc_eth_xgmac.c b/drivers/net/dwc_eth_xgmac.c
index d29d871ea8c..458b87af7a2 100644
--- a/drivers/net/dwc_eth_xgmac.c
+++ b/drivers/net/dwc_eth_xgmac.c
@@ -140,9 +140,34 @@ static int xgmac_mdio_wait_idle(struct xgmac_priv *xgmac)
XGMAC_TIMEOUT_100MS, true);
}
+static u32 xgmac_set_clause(struct xgmac_priv *xgmac, int mdio_addr, int mdio_devad,
+ int mdio_reg, bool is_c45)
+{
+ u32 hw_addr;
+ u32 val;
+
+ if (is_c45) {
+ val = readl(&xgmac->mac_regs->mdio_clause_22_port);
+ val &= ~BIT(mdio_addr);
+ writel(val, &xgmac->mac_regs->mdio_clause_22_port);
+ hw_addr = (mdio_addr << XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) |
+ (mdio_reg & XGMAC_MAC_MDIO_REG_ADDR_C45P_MASK);
+ hw_addr |= mdio_devad << XGMAC_MAC_MDIO_ADDRESS_DA_SHIFT;
+ } else {
+ /* Set clause 22 format */
+ val = BIT(mdio_addr);
+ writel(val, &xgmac->mac_regs->mdio_clause_22_port);
+ hw_addr = (mdio_addr << XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) |
+ (mdio_reg & XGMAC_MAC_MDIO_REG_ADDR_C22P_MASK);
+ }
+
+ return hw_addr;
+}
+
static int xgmac_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad,
int mdio_reg)
{
+ bool is_c45 = (mdio_devad != MDIO_DEVAD_NONE);
struct xgmac_priv *xgmac = bus->priv;
u32 val;
u32 hw_addr;
@@ -159,19 +184,16 @@ static int xgmac_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad,
return ret;
}
- /* Set clause 22 format */
- val = BIT(mdio_addr);
- writel(val, &xgmac->mac_regs->mdio_clause_22_port);
-
- hw_addr = (mdio_addr << XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) |
- (mdio_reg & XGMAC_MAC_MDIO_REG_ADDR_C22P_MASK);
+ hw_addr = xgmac_set_clause(xgmac, mdio_addr, mdio_devad, mdio_reg, is_c45);
val = xgmac->config->config_mac_mdio <<
XGMAC_MAC_MDIO_ADDRESS_CR_SHIFT;
- val |= XGMAC_MAC_MDIO_ADDRESS_SADDR |
- XGMAC_MDIO_SINGLE_CMD_ADDR_CMD_READ |
- XGMAC_MAC_MDIO_ADDRESS_SBUSY;
+ if (!is_c45)
+ val |= XGMAC_MAC_MDIO_ADDRESS_SADDR;
+
+ val |= XGMAC_MDIO_SINGLE_CMD_ADDR_CMD_READ |
+ XGMAC_MAC_MDIO_ADDRESS_SBUSY;
ret = xgmac_mdio_wait_idle(xgmac);
if (ret) {
@@ -203,6 +225,7 @@ static int xgmac_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad,
static int xgmac_mdio_write(struct mii_dev *bus, int mdio_addr, int mdio_devad,
int mdio_reg, u16 mdio_val)
{
+ bool is_c45 = (mdio_devad != MDIO_DEVAD_NONE);
struct xgmac_priv *xgmac = bus->priv;
u32 val;
u32 hw_addr;
@@ -219,21 +242,18 @@ static int xgmac_mdio_write(struct mii_dev *bus, int mdio_addr, int mdio_devad,
return ret;
}
- /* Set clause 22 format */
- val = BIT(mdio_addr);
- writel(val, &xgmac->mac_regs->mdio_clause_22_port);
-
- hw_addr = (mdio_addr << XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) |
- (mdio_reg & XGMAC_MAC_MDIO_REG_ADDR_C22P_MASK);
-
- hw_addr |= (mdio_reg >> XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) <<
- XGMAC_MAC_MDIO_ADDRESS_DA_SHIFT;
+ hw_addr = xgmac_set_clause(xgmac, mdio_addr, mdio_devad, mdio_reg, is_c45);
val = (xgmac->config->config_mac_mdio <<
XGMAC_MAC_MDIO_ADDRESS_CR_SHIFT);
- val |= XGMAC_MAC_MDIO_ADDRESS_SADDR |
- mdio_val | XGMAC_MDIO_SINGLE_CMD_ADDR_CMD_WRITE |
+ if (!is_c45) {
+ hw_addr |= (mdio_reg >> XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) <<
+ XGMAC_MAC_MDIO_ADDRESS_DA_SHIFT;
+ val |= XGMAC_MAC_MDIO_ADDRESS_SADDR;
+ }
+
+ val |= mdio_val | XGMAC_MDIO_SINGLE_CMD_ADDR_CMD_WRITE |
XGMAC_MAC_MDIO_ADDRESS_SBUSY;
ret = xgmac_mdio_wait_idle(xgmac);
diff --git a/drivers/net/dwc_eth_xgmac.h b/drivers/net/dwc_eth_xgmac.h
index 259f815f3f2..90c2e22997c 100644
--- a/drivers/net/dwc_eth_xgmac.h
+++ b/drivers/net/dwc_eth_xgmac.h
@@ -109,6 +109,7 @@ struct xgmac_mac_regs {
#define XGMAC_MAC_MDIO_ADDRESS_SBUSY BIT(22)
#define XGMAC_MAC_MDIO_REG_ADDR_C22P_MASK GENMASK(4, 0)
#define XGMAC_MAC_MDIO_DATA_GD_MASK GENMASK(15, 0)
+#define XGMAC_MAC_MDIO_REG_ADDR_C45P_MASK GENMASK(15, 0)
/* MTL Registers */
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 1c02e3efedc..2d93ce0c966 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -176,11 +176,11 @@ static int bcm54210e_config(struct phy_device *phydev)
{
int ret;
- ret = bcm54xx_config_clock_delay(phydev);
+ ret = bcm5461_config(phydev);
if (ret < 0)
return ret;
- ret = bcm5461_config(phydev);
+ ret = bcm54xx_config_clock_delay(phydev);
if (ret < 0)
return ret;
diff --git a/drivers/net/phy/dp83869.c b/drivers/net/phy/dp83869.c
index b6fb5adae1f..c60fbf26a03 100644
--- a/drivers/net/phy/dp83869.c
+++ b/drivers/net/phy/dp83869.c
@@ -5,6 +5,7 @@
*/
#include <phy.h>
+#include <linux/bitfield.h>
#include <linux/compat.h>
#include <malloc.h>
@@ -64,7 +65,7 @@
#define DP83869_RGMII_RX_CLK_DELAY_EN BIT(0)
/* STRAP_STS1 bits */
-#define DP83869_STRAP_OP_MODE_MASK GENMASK(2, 0)
+#define DP83869_STRAP_OP_MODE_MASK GENMASK(11, 9)
#define DP83869_STRAP_STS1_RESERVED BIT(11)
#define DP83869_STRAP_MIRROR_ENABLED BIT(12)
@@ -168,7 +169,7 @@ static int dp83869_set_strapped_mode(struct phy_device *phydev)
if (val < 0)
return val;
- dp83869->mode = val & DP83869_STRAP_OP_MODE_MASK;
+ dp83869->mode = FIELD_GET(DP83869_STRAP_OP_MODE_MASK, val);
return 0;
}
diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c
index 7a88f76fd09..84a3e44ecbc 100644
--- a/drivers/net/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ti/am65-cpsw-nuss.c
@@ -819,6 +819,10 @@ static int am65_cpsw_nuss_bind(struct udevice *dev)
ofnode_for_each_subnode(node, ports_np) {
const char *node_name;
+ /* Ignore disabled ports */
+ if (!ofnode_is_enabled(node))
+ continue;
+
node_name = ofnode_get_name(node);
ret = device_bind_driver_to_node(dev, "am65_cpsw_nuss_port", node_name, node,
diff --git a/drivers/pinctrl/broadcom/pinctrl-bcm283x.c b/drivers/pinctrl/broadcom/pinctrl-bcm283x.c
index cf9350c151e..4ecc8bac645 100644
--- a/drivers/pinctrl/broadcom/pinctrl-bcm283x.c
+++ b/drivers/pinctrl/broadcom/pinctrl-bcm283x.c
@@ -21,6 +21,8 @@
#include <asm/system.h>
#include <asm/io.h>
#include <asm/gpio.h>
+#include <dt-bindings/pinctrl/bcm2835.h>
+#include <linux/delay.h>
struct bcm283x_pinctrl_priv {
u32 *base_reg;
@@ -54,7 +56,66 @@ static int bcm2835_gpio_get_func_id(struct udevice *dev, unsigned int gpio)
}
/*
- * bcm283x_pinctrl_set_state: configure pin functions.
+ * bcm2835_gpio_set_pull: Set GPIO pull-up/down resistor for BCM2835
+ * @dev: the pinctrl device
+ * @gpio: the GPIO pin number
+ * @pull: pull setting (BCM2835_PUD_OFF, BCM2835_PUD_DOWN, BCM2835_PUD_UP)
+ */
+static void bcm2835_gpio_set_pull(struct udevice *dev, unsigned int gpio, int pull)
+{
+ struct bcm283x_pinctrl_priv *priv = dev_get_priv(dev);
+ u32 bank = BCM2835_GPPUDCLK0 + BCM2835_GPIO_COMMON_BANK(gpio);
+ u32 bit = BCM2835_GPIO_COMMON_SHIFT(gpio);
+
+ /* Set required control signal */
+ writel(pull & 0x3, &priv->base_reg[BCM2835_GPPUD]);
+ udelay(1);
+
+ /* Clock the control signal into the GPIO pads */
+ writel(1 << bit, &priv->base_reg[bank]);
+ udelay(1);
+
+ /* Remove the control signal and clock */
+ writel(0, &priv->base_reg[BCM2835_GPPUD]);
+ writel(0, &priv->base_reg[bank]);
+}
+
+/*
+ * bcm2711_gpio_set_pull: Set GPIO pull-up/down resistor for BCM2711
+ * @dev: the pinctrl device
+ * @gpio: the GPIO pin number
+ * @pull: pull setting (BCM2835_PUD_OFF, BCM2835_PUD_DOWN, BCM2835_PUD_UP)
+ */
+static void bcm2711_gpio_set_pull(struct udevice *dev, unsigned int gpio, int pull)
+{
+ struct bcm283x_pinctrl_priv *priv = dev_get_priv(dev);
+ u32 reg_offset;
+ u32 bit_shift;
+ u32 pull_bits;
+
+ /* Findout which GPIO_PUP_PDN_CNTRL register to use */
+ reg_offset = BCM2711_GPPUD_CNTRL_REG0 + BCM2711_PUD_REG_OFFSET(gpio);
+
+ /* Findout the bit position */
+ bit_shift = BCM2711_PUD_REG_SHIFT(gpio);
+
+ /* Update the 2-bit field for this GPIO */
+ pull_bits = pull & BCM2711_PUD_2711_MASK;
+ clrsetbits_le32(&priv->base_reg[reg_offset],
+ BCM2711_PUD_2711_MASK << bit_shift,
+ pull_bits << bit_shift);
+}
+
+static void bcm283x_gpio_set_pull(struct udevice *dev, unsigned int gpio, int pull)
+{
+ if (device_is_compatible(dev, "brcm,bcm2835-gpio"))
+ bcm2835_gpio_set_pull(dev, gpio, pull);
+ else
+ bcm2711_gpio_set_pull(dev, gpio, pull);
+}
+
+/*
+ * bcm283x_pinctrl_set_state: configure pin functions and pull states.
* @dev: the pinctrl device to be configured.
* @config: the state to be configured.
* @return: 0 in success
@@ -62,8 +123,10 @@ static int bcm2835_gpio_get_func_id(struct udevice *dev, unsigned int gpio)
int bcm283x_pinctrl_set_state(struct udevice *dev, struct udevice *config)
{
u32 pin_arr[MAX_PINS_PER_BANK];
+ u32 pull_arr[MAX_PINS_PER_BANK];
int function;
- int i, len, pin_count = 0;
+ int i, len, pin_count = 0, pull_len = 0, pull_count = 0;
+ int pull_value;
if (!dev_read_prop(config, "brcm,pins", &len) || !len ||
len & 0x3 || dev_read_u32_array(config, "brcm,pins", pin_arr,
@@ -82,8 +145,44 @@ int bcm283x_pinctrl_set_state(struct udevice *dev, struct udevice *config)
return -EINVAL;
}
- for (i = 0; i < pin_count; i++)
+ /* Check if brcm,pull property exists */
+ if (dev_read_prop(config, "brcm,pull", &pull_len) && pull_len > 0) {
+ if (pull_len & 0x3) {
+ debug("Invalid pull array length for pinconfig %s (%d)\n",
+ config->name, pull_len);
+ return -EINVAL;
+ }
+
+ pull_count = pull_len / sizeof(u32);
+
+ if (pull_count != 1 && pull_count != pin_count) {
+ debug("Pull array count (%d) must be 1 or match pin count (%d) for pinconfig %s\n",
+ pull_count, pin_count, config->name);
+ return -EINVAL;
+ }
+
+ if (dev_read_u32_array(config, "brcm,pull", pull_arr, pull_count)) {
+ debug("Failed reading pull array for pinconfig %s\n", config->name);
+ return -EINVAL;
+ }
+
+ /* Validate pull values */
+ for (i = 0; i < pull_count; i++) {
+ if (pull_arr[i] > 2) {
+ debug("Invalid pull value %d for pin %d in pinconfig %s\n",
+ pull_arr[i], pin_arr[i], config->name);
+ return -EINVAL;
+ }
+ }
+ }
+
+ for (i = 0; i < pin_count; i++) {
bcm2835_gpio_set_func_id(dev, pin_arr[i], function);
+ if (pull_count > 0) {
+ pull_value = (pull_count == 1) ? pull_arr[0] : pull_arr[i];
+ bcm283x_gpio_set_pull(dev, pin_arr[i], pull_value);
+ }
+ }
return 0;
}
diff --git a/drivers/pinctrl/exynos/pinctrl-exynos.c b/drivers/pinctrl/exynos/pinctrl-exynos.c
index b37282fa9d6..4c06b41c7aa 100644
--- a/drivers/pinctrl/exynos/pinctrl-exynos.c
+++ b/drivers/pinctrl/exynos/pinctrl-exynos.c
@@ -7,6 +7,7 @@
#include <log.h>
#include <dm.h>
+#include <dm/lists.h>
#include <errno.h>
#include <asm/io.h>
#include "pinctrl-exynos.h"
@@ -178,3 +179,13 @@ int exynos_pinctrl_probe(struct udevice *dev)
return 0;
}
+
+int exynos_pinctrl_bind(struct udevice *dev)
+{
+ /*
+ * Attempt to bind the Exynos GPIO driver. The GPIOs and
+ * pin controller descriptors are found in the same OF node.
+ */
+ return device_bind_driver_to_node(dev, "gpio_exynos", "gpio-banks",
+ dev_ofnode(dev), NULL);
+}
diff --git a/drivers/pinctrl/exynos/pinctrl-exynos.h b/drivers/pinctrl/exynos/pinctrl-exynos.h
index da666777581..73cc2ce4117 100644
--- a/drivers/pinctrl/exynos/pinctrl-exynos.h
+++ b/drivers/pinctrl/exynos/pinctrl-exynos.h
@@ -97,5 +97,6 @@ void exynos_pinctrl_setup_peri(struct exynos_pinctrl_config_data *conf,
int exynos_pinctrl_set_state(struct udevice *dev,
struct udevice *config);
int exynos_pinctrl_probe(struct udevice *dev);
+int exynos_pinctrl_bind(struct udevice *dev);
#endif /* __PINCTRL_EXYNOS_H_ */
diff --git a/drivers/pinctrl/exynos/pinctrl-exynos7420.c b/drivers/pinctrl/exynos/pinctrl-exynos7420.c
index 8fdf60715a5..b1d983fd383 100644
--- a/drivers/pinctrl/exynos/pinctrl-exynos7420.c
+++ b/drivers/pinctrl/exynos/pinctrl-exynos7420.c
@@ -114,4 +114,5 @@ U_BOOT_DRIVER(pinctrl_exynos7420) = {
.priv_auto = sizeof(struct exynos_pinctrl_priv),
.ops = &exynos7420_pinctrl_ops,
.probe = exynos_pinctrl_probe,
+ .bind = exynos_pinctrl_bind,
};
diff --git a/drivers/pinctrl/exynos/pinctrl-exynos78x0.c b/drivers/pinctrl/exynos/pinctrl-exynos78x0.c
index 61b98443daf..04e72173802 100644
--- a/drivers/pinctrl/exynos/pinctrl-exynos78x0.c
+++ b/drivers/pinctrl/exynos/pinctrl-exynos78x0.c
@@ -45,6 +45,11 @@ static const struct samsung_pin_bank_data exynos78x0_pin_banks2[] = {
EXYNOS_PIN_BANK(4, 0x040, "gpz2"),
};
+/* pin banks of exynos78x0 pin-controller 3 (ESE) */
+static const struct samsung_pin_bank_data exynos78x0_pin_banks3[] = {
+ EXYNOS_PIN_BANK(5, 0x000, "gpc7"),
+};
+
/* pin banks of exynos78x0 pin-controller 4 (FSYS) */
static const struct samsung_pin_bank_data exynos78x0_pin_banks4[] = {
EXYNOS_PIN_BANK(3, 0x000, "gpr0"),
@@ -54,6 +59,11 @@ static const struct samsung_pin_bank_data exynos78x0_pin_banks4[] = {
EXYNOS_PIN_BANK(6, 0x080, "gpr4"),
};
+/* pin banks of exynos78x0 pin-controller 5 (NFC) */
+static const struct samsung_pin_bank_data exynos78x0_pin_banks5[] = {
+ EXYNOS_PIN_BANK(4, 0x000, "gpc2"),
+};
+
/* pin banks of exynos78x0 pin-controller 6 (TOP) */
static const struct samsung_pin_bank_data exynos78x0_pin_banks6[] = {
EXYNOS_PIN_BANK(4, 0x000, "gpb0"),
@@ -77,6 +87,11 @@ static const struct samsung_pin_bank_data exynos78x0_pin_banks6[] = {
EXYNOS_PIN_BANK(5, 0x240, "gpf4"),
};
+/* pin banks of exynos7870 pin-controller 7 (TOUCH) */
+static const struct samsung_pin_bank_data exynos78x0_pin_banks7[] = {
+ EXYNOS_PIN_BANK(3, 0x000, "gpc3"),
+};
+
const struct samsung_pin_ctrl exynos78x0_pin_ctrl[] = {
{
/* pin-controller instance 0 Alive data */
@@ -102,9 +117,53 @@ const struct samsung_pin_ctrl exynos78x0_pin_ctrl[] = {
{/* list terminator */}
};
+/*
+ * In Exynos7870, the CCORE block is named as MIF instead. As the
+ * pinctrl blocks are sorted in lexical order of their names, the
+ * order isn't the same as Exynos7880.
+ */
+const struct samsung_pin_ctrl exynos7870_pin_ctrl[] = {
+ {
+ /* pin-controller instance 0 Alive data */
+ .pin_banks = exynos78x0_pin_banks0,
+ .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks0),
+ }, {
+ /* pin-controller instance 1 DISPAUD data */
+ .pin_banks = exynos78x0_pin_banks2,
+ .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks2),
+ }, {
+ /* pin-controller instance 2 ESE data */
+ .pin_banks = exynos78x0_pin_banks3,
+ .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks3),
+ }, {
+ /* pin-controller instance 3 FSYS data */
+ .pin_banks = exynos78x0_pin_banks4,
+ .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks4),
+ }, {
+ /* pin-controller instance 4 MIF data */
+ .pin_banks = exynos78x0_pin_banks1,
+ .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks1),
+ }, {
+ /* pin-controller instance 5 NFC data */
+ .pin_banks = exynos78x0_pin_banks5,
+ .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks5),
+ }, {
+ /* pin-controller instance 6 TOP data */
+ .pin_banks = exynos78x0_pin_banks6,
+ .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks6),
+ }, {
+ /* pin-controller instance 7 TOUCH data */
+ .pin_banks = exynos78x0_pin_banks7,
+ .nr_banks = ARRAY_SIZE(exynos78x0_pin_banks7),
+ },
+ {/* list terminator */}
+};
+
static const struct udevice_id exynos78x0_pinctrl_ids[] = {
{ .compatible = "samsung,exynos78x0-pinctrl",
.data = (ulong)exynos78x0_pin_ctrl },
+ { .compatible = "samsung,exynos7870-pinctrl",
+ .data = (ulong)exynos7870_pin_ctrl },
{ }
};
@@ -115,4 +174,5 @@ U_BOOT_DRIVER(pinctrl_exynos78x0) = {
.priv_auto = sizeof(struct exynos_pinctrl_priv),
.ops = &exynos78x0_pinctrl_ops,
.probe = exynos_pinctrl_probe,
+ .bind = exynos_pinctrl_bind,
};
diff --git a/drivers/pinctrl/exynos/pinctrl-exynos850.c b/drivers/pinctrl/exynos/pinctrl-exynos850.c
index 3ec2636e0d8..5bf09ae20ee 100644
--- a/drivers/pinctrl/exynos/pinctrl-exynos850.c
+++ b/drivers/pinctrl/exynos/pinctrl-exynos850.c
@@ -122,4 +122,5 @@ U_BOOT_DRIVER(pinctrl_exynos850) = {
.priv_auto = sizeof(struct exynos_pinctrl_priv),
.ops = &exynos850_pinctrl_ops,
.probe = exynos_pinctrl_probe,
+ .bind = exynos_pinctrl_bind,
};
diff --git a/drivers/power/domain/ti-power-domain.c b/drivers/power/domain/ti-power-domain.c
index c3519307340..a554e659392 100644
--- a/drivers/power/domain/ti-power-domain.c
+++ b/drivers/power/domain/ti-power-domain.c
@@ -227,7 +227,7 @@ static int ti_pd_get(struct ti_pd *pd)
pd_write(pdctl, pd, PSC_PDCTL);
- return 0;
+ return ti_pd_wait(pd);
}
static int ti_pd_put(struct ti_pd *pd)
diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c
index 734780a124a..d46a88610ab 100644
--- a/drivers/serial/serial_s5p.c
+++ b/drivers/serial/serial_s5p.c
@@ -258,6 +258,7 @@ static const struct dm_serial_ops s5p_serial_ops = {
static const struct udevice_id s5p_serial_ids[] = {
{ .compatible = "samsung,exynos4210-uart", .data = PORT_S5P },
{ .compatible = "samsung,exynos850-uart", .data = PORT_S5P },
+ { .compatible = "samsung,exynos8895-uart", .data = PORT_S5P },
{ .compatible = "apple,s5l-uart", .data = PORT_S5L },
{ }
};
diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
index 233ad4a908f..0f533bcdae5 100644
--- a/drivers/soc/samsung/exynos-pmu.c
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -86,6 +86,9 @@ static int exynos_pmu_probe(struct udevice *dev)
static const struct udevice_id exynos_pmu_ids[] = {
{
+ .compatible = "samsung,exynos7-pmu",
+ },
+ {
.compatible = "samsung,exynos850-pmu",
.data = (ulong)&exynos850_pmu_data
},
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index c88918606d2..2afb15fff1e 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -180,6 +180,21 @@ config CADENCE_OSPI_VERSAL
This option is used to enable Versal OSPI DMA operations which
are used for ospi flash read using cadence qspi controller.
+config CADENCE_XSPI
+ bool "Cadence XSPI driver (Experimental feature)"
+ help
+ Important: this feature is experimental so far and tested only
+ on simulated environment.
+
+ Enable the Cadence eXpanded Serial Periheral Interface (xSPI) flash
+ driver. This driver can be used to access the SPI NOR flash on
+ platforms embedding this Cadence IP core up to 8 bit wide bus.
+ xSPI flash controller IP offers three work mode, Auto Command (ACMD)
+ work mode, Software Triggered Instruction Generator (STIG) work mode
+ and Direct work mode. This flash controller able to coomunicate
+ with Flash Memory Devices supporting JESD216 and JESD251 stadards
+ by using the Auto Command work mode.
+
config CF_SPI
bool "ColdFire SPI driver"
depends on M68K
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 5129d649f84..d5d1e543588 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -8,6 +8,7 @@ ifdef CONFIG_$(PHASE_)DM_SPI
obj-y += spi-uclass.o
obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o cadence_qspi_apb.o
obj-$(CONFIG_CADENCE_OSPI_VERSAL) += cadence_ospi_versal.o
+obj-$(CONFIG_CADENCE_XSPI) += cadence_xspi.o
obj-$(CONFIG_SANDBOX) += spi-emul-uclass.o
obj-$(CONFIG_SOFT_SPI) += soft_spi.o
obj-$(CONFIG_SPI_ASPEED_SMC) += spi-aspeed-smc.o
diff --git a/drivers/spi/cadence_xspi.c b/drivers/spi/cadence_xspi.c
new file mode 100644
index 00000000000..717f226b709
--- /dev/null
+++ b/drivers/spi/cadence_xspi.c
@@ -0,0 +1,449 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2025
+ * Altera Corporation <www.altera.com>
+ */
+
+#include <clk.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <log.h>
+#include <malloc.h>
+#include <reset.h>
+#include <spi.h>
+#include <spi-mem.h>
+#include <dm/device_compat.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/ioport.h>
+#include <linux/sizes.h>
+#include <linux/time.h>
+#include "cadence_xspi.h"
+
+static int cdns_xspi_wait_for_controller_idle(struct cdns_xspi_plat *cdns_xspi)
+{
+ u32 ctrl_stat;
+
+ return readl_relaxed_poll_timeout(cdns_xspi->iobase +
+ CDNS_XSPI_CTRL_STATUS_REG,
+ ctrl_stat,
+ !(ctrl_stat &
+ CDNS_XSPI_CTRL_BUSY),
+ 1000);
+}
+
+static int cdns_xspi_wait_for_sdma_complete(struct cdns_xspi_plat *cdns_xspi)
+{
+ u32 irq_status;
+ int ret = 0;
+
+ ret = readl_relaxed_poll_timeout(cdns_xspi->iobase +
+ CDNS_XSPI_INTR_STATUS_REG,
+ irq_status,
+ (irq_status &
+ CDNS_XSPI_SDMA_TRIGGER),
+ 1000);
+
+ if (!ret) {
+ /*
+ * SDMA return an interrupt, need to clear
+ * the interrupt after read, wrtting 1 to clear the bit.
+ */
+ setbits_le32(cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG,
+ CDNS_XSPI_SDMA_TRIGGER);
+ }
+
+ /* Check if SDMA ERROR happened */
+ if (irq_status & CDNS_XSPI_SDMA_ERROR) {
+ /*
+ * Need to clear the SDMA_ERROR interrupt
+ * after read, wrtting 1 to clear the bit.
+ */
+ dev_err(cdns_xspi->dev,
+ "Slave DMA transaction error\n");
+
+ cdns_xspi->sdma_error = true;
+ setbits_le32(cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG,
+ CDNS_XSPI_SDMA_ERROR);
+
+ ret = -EIO;
+ }
+
+ return ret;
+}
+
+static int cdns_xspi_wait_for_cmd_complete(struct cdns_xspi_plat *cdns_xspi)
+{
+ u32 irq_status;
+ int ret = 0;
+
+ ret = readl_relaxed_poll_timeout(cdns_xspi->iobase +
+ CDNS_XSPI_INTR_STATUS_REG,
+ irq_status,
+ (irq_status &
+ CDNS_XSPI_STIG_DONE),
+ 100000);
+
+ irq_status = readl(cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG);
+
+ if (!ret) {
+ /*
+ * Need to clear the interrupt after read,
+ * wrtting 1 to the clear the bit.
+ */
+ writel(irq_status & CDNS_XSPI_STIG_DONE,
+ cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG);
+ }
+
+ return ret;
+}
+
+static void cdns_xspi_trigger_command(struct cdns_xspi_plat *cdns_xspi,
+ u32 cmd_regs[6])
+{
+ writel(cmd_regs[5], cdns_xspi->iobase + CDNS_XSPI_CMD_REG_5);
+ writel(cmd_regs[4], cdns_xspi->iobase + CDNS_XSPI_CMD_REG_4);
+ writel(cmd_regs[3], cdns_xspi->iobase + CDNS_XSPI_CMD_REG_3);
+ writel(cmd_regs[2], cdns_xspi->iobase + CDNS_XSPI_CMD_REG_2);
+ writel(cmd_regs[1], cdns_xspi->iobase + CDNS_XSPI_CMD_REG_1);
+ writel(cmd_regs[0], cdns_xspi->iobase + CDNS_XSPI_CMD_REG_0);
+}
+
+static int cdns_xspi_check_command_status(struct cdns_xspi_plat *cdns_xspi)
+{
+ int ret = 0;
+ u32 cmd_status = readl(cdns_xspi->iobase + CDNS_XSPI_CMD_STATUS_REG);
+
+ /* Check if the command has completed */
+ if (cmd_status & CDNS_XSPI_CMD_STATUS_COMPLETED) {
+ /*Check for failure status and report each type of error */
+ if ((cmd_status & CDNS_XSPI_CMD_STATUS_FAILED) != 0) {
+ if (cmd_status & CDNS_XSPI_CMD_STATUS_DQS_ERROR)
+ dev_err(cdns_xspi->dev,
+ "Incorrect DQS pulses detected\n");
+
+ if (cmd_status & CDNS_XSPI_CMD_STATUS_CRC_ERROR)
+ dev_err(cdns_xspi->dev,
+ "CRC error received\n");
+
+ if (cmd_status & CDNS_XSPI_CMD_STATUS_BUS_ERROR)
+ dev_err(cdns_xspi->dev,
+ "Error resp on system DMA interface\n");
+
+ if (cmd_status & CDNS_XSPI_CMD_STATUS_INV_SEQ_ERROR)
+ dev_err(cdns_xspi->dev,
+ "Invalid command sequence detected\n");
+
+ ret = -EPROTO;
+ }
+ } else {
+ /* Command did not complete at all -- fatal error */
+ dev_err(cdns_xspi->dev, "Fatal err - command not completed\n");
+ ret = -EPROTO;
+ }
+
+ return ret;
+}
+
+static void cdns_xspi_set_interrupts(struct cdns_xspi_plat *cdns_xspi,
+ bool enabled)
+{
+ u32 intr_enable;
+
+ intr_enable = readl(cdns_xspi->iobase + CDNS_XSPI_INTR_ENABLE_REG);
+ if (enabled)
+ intr_enable |= CDNS_XSPI_INTR_MASK;
+ else
+ intr_enable &= ~CDNS_XSPI_INTR_MASK;
+ writel(intr_enable, cdns_xspi->iobase + CDNS_XSPI_INTR_ENABLE_REG);
+}
+
+static int cdns_xspi_controller_init(struct cdns_xspi_plat *cdns_xspi)
+{
+ u32 ctrl_ver;
+ u32 ctrl_features;
+ u16 hw_magic_num;
+
+ ctrl_ver = readl(cdns_xspi->iobase + CDNS_XSPI_CTRL_VERSION_REG);
+ hw_magic_num = FIELD_GET(CDNS_XSPI_MAGIC_NUM, ctrl_ver);
+ if (hw_magic_num != CDNS_XSPI_MAGIC_NUM_VALUE) {
+ dev_err(cdns_xspi->dev,
+ "Incorrect XSPI magic number: %x, expected: %x\n",
+ hw_magic_num, CDNS_XSPI_MAGIC_NUM_VALUE);
+ return -ENXIO;
+ }
+
+ ctrl_features = readl(cdns_xspi->iobase + CDNS_XSPI_CTRL_FEATURES_REG);
+ cdns_xspi->hw_num_banks = FIELD_GET(CDNS_XSPI_NUM_BANKS, ctrl_features);
+ cdns_xspi->set_interrupts_handler(cdns_xspi, false);
+
+ return 0;
+}
+
+static void cdns_xspi_sdma_handle(struct cdns_xspi_plat *cdns_xspi)
+{
+ u32 sdma_size, sdma_trd_info;
+ u8 sdma_dir;
+ u8 *in_buf;
+ u8 *out_buf;
+
+ sdma_size = readl(cdns_xspi->iobase + CDNS_XSPI_SDMA_SIZE_REG);
+ sdma_trd_info = readl(cdns_xspi->iobase + CDNS_XSPI_SDMA_TRD_INFO_REG);
+ sdma_dir = FIELD_GET(CDNS_XSPI_SDMA_DIR, sdma_trd_info);
+
+ in_buf = (u8 *)cdns_xspi->in_buffer;
+ out_buf = (u8 *)cdns_xspi->out_buffer;
+
+ switch (sdma_dir) {
+ case CDNS_XSPI_SDMA_DIR_READ:
+ if (in_buf)
+ memcpy_fromio(in_buf, cdns_xspi->sdmabase, sdma_size);
+ break;
+
+ case CDNS_XSPI_SDMA_DIR_WRITE:
+ if (in_buf)
+ memcpy_toio(cdns_xspi->sdmabase, out_buf, sdma_size);
+ break;
+
+ default:
+ /* Handle unexpected direction */
+ dev_warn(cdns_xspi->dev,
+ "Unknown SDMA direction: %u\n", sdma_dir);
+ break;
+ }
+}
+
+static int cdns_xspi_send_stig_command(struct cdns_xspi_plat *cdns_xspi,
+ const struct spi_mem_op *op,
+ bool data_phase)
+{
+ u32 cmd_regs[6] = {0};
+ int ret = 0;
+ int dummybytes = op->dummy.nbytes;
+
+ ret = cdns_xspi_wait_for_controller_idle(cdns_xspi);
+ if (ret < 0)
+ return ret;
+
+ writel(FIELD_PREP(CDNS_XSPI_CTRL_WORK_MODE, CDNS_XSPI_WORK_MODE_STIG),
+ cdns_xspi->iobase + CDNS_XSPI_CTRL_CONFIG_REG);
+
+ cdns_xspi->set_interrupts_handler(cdns_xspi, true);
+ cdns_xspi->sdma_error = false;
+
+ cmd_regs[1] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_1(op, data_phase);
+ cmd_regs[2] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_2(op);
+ if (dummybytes != 0) {
+ cmd_regs[3] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3(op, 1);
+ dummybytes--;
+ } else {
+ cmd_regs[3] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3(op, 0);
+ }
+ cmd_regs[4] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_4(op,
+ cdns_xspi->cur_cs);
+
+ cdns_xspi_trigger_command(cdns_xspi, cmd_regs);
+
+ if (data_phase) {
+ cmd_regs[0] = CDNS_XSPI_STIG_DONE_FLAG;
+ cmd_regs[1] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_1;
+ cmd_regs[2] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_2(op);
+ cmd_regs[3] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_3(op, dummybytes);
+ cmd_regs[4] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_4(op,
+ cdns_xspi->cur_cs);
+
+ cdns_xspi->in_buffer = op->data.buf.in;
+ cdns_xspi->out_buffer = op->data.buf.out;
+
+ cdns_xspi_trigger_command(cdns_xspi, cmd_regs);
+
+ cdns_xspi_wait_for_sdma_complete(cdns_xspi);
+
+ if (cdns_xspi->sdma_error) {
+ cdns_xspi->set_interrupts_handler(cdns_xspi, false);
+ return -EIO;
+ }
+ cdns_xspi_sdma_handle(cdns_xspi);
+ }
+
+ cdns_xspi_wait_for_cmd_complete(cdns_xspi);
+ ret = cdns_xspi_check_command_status(cdns_xspi);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int cdns_xspi_mem_op(struct udevice *bus,
+ const struct spi_mem_op *op,
+ unsigned int cs)
+{
+ struct cdns_xspi_plat *plat = dev_get_plat(bus);
+ enum spi_mem_data_dir dir = op->data.dir;
+
+ if (plat->cur_cs != cs)
+ plat->cur_cs = cs;
+
+ return cdns_xspi_send_stig_command(plat, op,
+ (dir != SPI_MEM_NO_DATA));
+}
+
+static int cdns_xspi_mem_op_execute(struct spi_slave *spi,
+ const struct spi_mem_op *op)
+{
+ struct udevice *bus = spi->dev->parent;
+ unsigned int cs = 0;
+ int ret = 0;
+
+ cs = spi_chip_select(spi->dev);
+
+ if (cs < 0) {
+ /*
+ * spi_chip_select will return error number when not
+ * able to get chip select.
+ */
+ pr_err("%s: Unable to get chip select, ret=%d",
+ spi->dev->name, cs);
+ return cs;
+ }
+
+ ret = cdns_xspi_mem_op(bus, op, cs);
+
+ return ret;
+}
+
+static int cdns_xspi_adjust_mem_op_size(struct spi_slave *spi,
+ struct spi_mem_op *op)
+{
+ struct udevice *bus = spi->dev->parent;
+ struct cdns_xspi_plat *plat = dev_get_plat(bus);
+
+ op->data.nbytes = clamp_val(op->data.nbytes, 0, plat->sdmasize);
+
+ return 0;
+}
+
+static const struct spi_controller_mem_ops cadence_xspi_mem_ops = {
+ .exec_op = cdns_xspi_mem_op_execute,
+ .adjust_op_size = cdns_xspi_adjust_mem_op_size,
+};
+
+static void cdns_xspi_print_phy_config(struct cdns_xspi_plat *cdns_xspi)
+{
+ struct device *dev = cdns_xspi->dev;
+
+ dev_info(dev, "PHY configuration\n");
+ dev_info(dev, " * xspi_dll_phy_ctrl: %08x\n",
+ readl(cdns_xspi->iobase + CDNS_XSPI_DLL_PHY_CTRL));
+ dev_info(dev, " * phy_dq_timing: %08x\n",
+ readl(cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_DQ_TIMING));
+ dev_info(dev, " * phy_dqs_timing: %08x\n",
+ readl(cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_DQS_TIMING));
+ dev_info(dev, " * phy_gate_loopback_ctrl: %08x\n",
+ readl(cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_GATE_LPBCK_CTRL));
+ dev_info(dev, " * phy_dll_slave_ctrl: %08x\n",
+ readl(cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_DLL_SLAVE_CTRL));
+}
+
+static int cdns_xspi_probe(struct udevice *bus)
+{
+ struct cdns_xspi_plat *cdns_xspi = dev_get_plat(bus);
+ struct resource res;
+ int ret = 0;
+
+ cdns_xspi->sdma_handler = &cdns_xspi_sdma_handle;
+ cdns_xspi->set_interrupts_handler = &cdns_xspi_set_interrupts;
+ cdns_xspi->cur_cs = 0;
+
+ ret = dev_read_resource_byname(bus, "io", &res);
+ if (ret)
+ return ret;
+
+ cdns_xspi->iobase = devm_ioremap(bus, res.start, resource_size(&res));
+
+ if (IS_ERR(cdns_xspi->iobase)) {
+ dev_err(bus, "Failed to remap controller base address\n");
+ return PTR_ERR(cdns_xspi->iobase);
+ }
+
+ ret = dev_read_resource_byname(bus, "sdma", &res);
+ if (ret)
+ return ret;
+
+ cdns_xspi->sdmabase = devm_ioremap(bus, res.start, resource_size(&res));
+
+ if (IS_ERR(cdns_xspi->sdmabase)) {
+ dev_err(bus, "Failed to remap SDMA address\n");
+ return PTR_ERR(cdns_xspi->sdmabase);
+ }
+ cdns_xspi->sdmasize = resource_size(&res);
+
+ ret = dev_read_resource_byname(bus, "aux", &res);
+ if (ret)
+ return ret;
+
+ cdns_xspi->auxbase = devm_ioremap(bus, res.start, resource_size(&res));
+
+ if (IS_ERR(cdns_xspi->auxbase)) {
+ dev_err(bus, "Failed to remap AUX address\n");
+ return PTR_ERR(cdns_xspi->auxbase);
+ }
+
+ cdns_xspi_print_phy_config(cdns_xspi);
+
+ ret = cdns_xspi_controller_init(cdns_xspi);
+
+ if (ret) {
+ dev_err(bus, "Failed to initialize controller\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int cdns_xspi_remove(struct udevice *dev)
+{
+ struct cdns_xspi_plat *plat = dev_get_plat(dev);
+ int ret = 0;
+
+ if (plat->resets)
+ ret = reset_release_bulk(plat->resets);
+
+ return ret;
+}
+
+static int cadence_spi_set_speed(struct udevice *bus, uint hz)
+{
+ return 0;
+}
+
+static int cadence_spi_set_mode(struct udevice *bus, uint mode)
+{
+ return 0;
+}
+
+static const struct dm_spi_ops cdns_xspi_ops = {
+ .set_speed = cadence_spi_set_speed,
+ .set_mode = cadence_spi_set_mode,
+ .mem_ops = &cadence_xspi_mem_ops,
+};
+
+static const struct udevice_id cdns_xspi_of_match[] = {
+ {
+ .compatible = "cdns,xspi-nor",
+ },
+ {/* end of table */}
+};
+
+U_BOOT_DRIVER(cadence_xspi) = {
+ .name = CDNS_XSPI_NAME,
+ .id = UCLASS_SPI,
+ .of_match = cdns_xspi_of_match,
+ .ops = &cdns_xspi_ops,
+ .probe = cdns_xspi_probe,
+ .remove = cdns_xspi_remove,
+ .flags = DM_FLAG_OS_PREPARE,
+};
diff --git a/drivers/spi/cadence_xspi.h b/drivers/spi/cadence_xspi.h
new file mode 100644
index 00000000000..e408d27303f
--- /dev/null
+++ b/drivers/spi/cadence_xspi.h
@@ -0,0 +1,226 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2025
+ * Altera Corporation <www.altera.com>
+ */
+
+#ifndef __CADENCE_XSPI_H__
+#define __CADENCE_XSPI_H__
+
+#include <spi-mem.h>
+#include <reset.h>
+#include <linux/mtd/spi-nor.h>
+#include <linux/bitfield.h>
+#include <linux/log2.h>
+
+#define CDNS_XSPI_MAGIC_NUM_VALUE 0x6522
+#define CDNS_XSPI_MAX_BANKS 8
+#define CDNS_XSPI_NAME "cadence_xspi"
+
+/*
+ * Note: below are additional auxiliary registers to
+ * configure XSPI controller pin-strap settings
+ */
+
+/* PHY DQ timing register */
+#define CDNS_XSPI_CCP_PHY_DQ_TIMING 0x0000
+
+/* PHY DQS timing register */
+#define CDNS_XSPI_CCP_PHY_DQS_TIMING 0x0004
+
+/* PHY gate loopback control register */
+#define CDNS_XSPI_CCP_PHY_GATE_LPBCK_CTRL 0x0008
+
+/* PHY DLL slave control register */
+#define CDNS_XSPI_CCP_PHY_DLL_SLAVE_CTRL 0x0010
+
+/* DLL PHY control register */
+#define CDNS_XSPI_DLL_PHY_CTRL 0x1034
+
+/* Command registers */
+#define CDNS_XSPI_CMD_REG_0 0x0000
+#define CDNS_XSPI_CMD_REG_1 0x0004
+#define CDNS_XSPI_CMD_REG_2 0x0008
+#define CDNS_XSPI_CMD_REG_3 0x000C
+#define CDNS_XSPI_CMD_REG_4 0x0010
+#define CDNS_XSPI_CMD_REG_5 0x0014
+
+/* Command status registers */
+#define CDNS_XSPI_CMD_STATUS_REG 0x0044
+
+/* Controller status register */
+#define CDNS_XSPI_CTRL_STATUS_REG 0x0100
+#define CDNS_XSPI_INIT_COMPLETED BIT(16)
+#define CDNS_XSPI_INIT_LEGACY BIT(9)
+#define CDNS_XSPI_INIT_FAIL BIT(8)
+#define CDNS_XSPI_CTRL_BUSY BIT(7)
+
+/* Controller interrupt status register */
+#define CDNS_XSPI_INTR_STATUS_REG 0x0110
+#define CDNS_XSPI_STIG_DONE BIT(23)
+#define CDNS_XSPI_SDMA_ERROR BIT(22)
+#define CDNS_XSPI_SDMA_TRIGGER BIT(21)
+#define CDNS_XSPI_CMD_IGNRD_EN BIT(20)
+#define CDNS_XSPI_DDMA_TERR_EN BIT(18)
+#define CDNS_XSPI_CDMA_TREE_EN BIT(17)
+#define CDNS_XSPI_CTRL_IDLE_EN BIT(16)
+
+#define CDNS_XSPI_TRD_COMP_INTR_STATUS 0x0120
+#define CDNS_XSPI_TRD_ERR_INTR_STATUS 0x0130
+#define CDNS_XSPI_TRD_ERR_INTR_EN 0x0134
+
+/* Controller interrupt enable register */
+#define CDNS_XSPI_INTR_ENABLE_REG 0x0114
+#define CDNS_XSPI_INTR_EN BIT(31)
+#define CDNS_XSPI_STIG_DONE_EN BIT(23)
+#define CDNS_XSPI_SDMA_ERROR_EN BIT(22)
+#define CDNS_XSPI_SDMA_TRIGGER_EN BIT(21)
+
+#define CDNS_XSPI_INTR_MASK (CDNS_XSPI_INTR_EN | \
+ CDNS_XSPI_STIG_DONE_EN | \
+ CDNS_XSPI_SDMA_ERROR_EN | \
+ CDNS_XSPI_SDMA_TRIGGER_EN)
+
+/* Controller config register */
+#define CDNS_XSPI_CTRL_CONFIG_REG 0x0230
+#define CDNS_XSPI_CTRL_WORK_MODE GENMASK(6, 5)
+
+#define CDNS_XSPI_WORK_MODE_DIRECT 0
+#define CDNS_XSPI_WORK_MODE_STIG 1
+#define CDNS_XSPI_WORK_MODE_ACMD 3
+
+/* SDMA trigger transaction registers */
+#define CDNS_XSPI_SDMA_SIZE_REG 0x0240
+#define CDNS_XSPI_SDMA_TRD_INFO_REG 0x0244
+#define CDNS_XSPI_SDMA_DIR BIT(8)
+
+/* Controller features register */
+#define CDNS_XSPI_CTRL_FEATURES_REG 0x0F04
+#define CDNS_XSPI_NUM_BANKS GENMASK(25, 24)
+#define CDNS_XSPI_DMA_DATA_WIDTH BIT(21)
+#define CDNS_XSPI_NUM_THREADS GENMASK(3, 0)
+
+/* Controller version register */
+#define CDNS_XSPI_CTRL_VERSION_REG 0x0F00
+#define CDNS_XSPI_MAGIC_NUM GENMASK(31, 16)
+#define CDNS_XSPI_CTRL_REV GENMASK(7, 0)
+
+/* STIG Profile 1.0 instruction fields (split into registers) */
+#define CDNS_XSPI_CMD_INSTR_TYPE GENMASK(6, 0)
+#define CDNS_XSPI_CMD_P1_R1_ADDR0 GENMASK(31, 24)
+#define CDNS_XSPI_CMD_P1_R2_ADDR1 GENMASK(7, 0)
+#define CDNS_XSPI_CMD_P1_R2_ADDR2 GENMASK(15, 8)
+#define CDNS_XSPI_CMD_P1_R2_ADDR3 GENMASK(23, 16)
+#define CDNS_XSPI_CMD_P1_R2_ADDR4 GENMASK(31, 24)
+#define CDNS_XSPI_CMD_P1_R3_ADDR5 GENMASK(7, 0)
+#define CDNS_XSPI_CMD_P1_R3_CMD GENMASK(23, 16)
+#define CDNS_XSPI_CMD_P1_R3_NUM_ADDR_BYTES GENMASK(30, 28)
+#define CDNS_XSPI_CMD_P1_R4_ADDR_IOS GENMASK(1, 0)
+#define CDNS_XSPI_CMD_P1_R4_CMD_IOS GENMASK(9, 8)
+#define CDNS_XSPI_CMD_P1_R4_BANK GENMASK(14, 12)
+
+/* STIG data sequence instruction fields (split into registers) */
+#define CDNS_XSPI_CMD_DSEQ_R2_DCNT_L GENMASK(31, 16)
+#define CDNS_XSPI_CMD_DSEQ_R3_DCNT_H GENMASK(15, 0)
+#define CDNS_XSPI_CMD_DSEQ_R3_NUM_OF_DUMMY GENMASK(25, 20)
+#define CDNS_XSPI_CMD_DSEQ_R4_BANK GENMASK(14, 12)
+#define CDNS_XSPI_CMD_DSEQ_R4_DATA_IOS GENMASK(9, 8)
+#define CDNS_XSPI_CMD_DSEQ_R4_DIR BIT(4)
+
+/* STIG command status fields */
+#define CDNS_XSPI_CMD_STATUS_COMPLETED BIT(15)
+#define CDNS_XSPI_CMD_STATUS_FAILED BIT(14)
+#define CDNS_XSPI_CMD_STATUS_DQS_ERROR BIT(3)
+#define CDNS_XSPI_CMD_STATUS_CRC_ERROR BIT(2)
+#define CDNS_XSPI_CMD_STATUS_BUS_ERROR BIT(1)
+#define CDNS_XSPI_CMD_STATUS_INV_SEQ_ERROR BIT(0)
+
+#define CDNS_XSPI_STIG_DONE_FLAG BIT(0)
+#define CDNS_XSPI_TRD_STATUS 0x0104
+
+#define MODE_NO_OF_BYTES GENMASK(25, 24)
+#define MODEBYTES_COUNT 1
+
+/* Helper macros for filling command registers */
+#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_1(op, data_phase) ( \
+ FIELD_PREP(CDNS_XSPI_CMD_INSTR_TYPE, (data_phase) ? \
+ CDNS_XSPI_STIG_INSTR_TYPE_1 : CDNS_XSPI_STIG_INSTR_TYPE_0) | \
+ FIELD_PREP(CDNS_XSPI_CMD_P1_R1_ADDR0, (op)->addr.val & 0xff))
+
+#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_2(op) ( \
+ FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR1, ((op)->addr.val >> 8) & 0xFF) | \
+ FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR2, ((op)->addr.val >> 16) & 0xFF) | \
+ FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR3, ((op)->addr.val >> 24) & 0xFF) | \
+ FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR4, ((op)->addr.val >> 32) & 0xFF))
+
+#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3(op, modebytes) ( \
+ FIELD_PREP(CDNS_XSPI_CMD_P1_R3_ADDR5, ((op)->addr.val >> 40) & 0xFF) | \
+ FIELD_PREP(CDNS_XSPI_CMD_P1_R3_CMD, (op)->cmd.opcode) | \
+ FIELD_PREP(MODE_NO_OF_BYTES, modebytes) | \
+ FIELD_PREP(CDNS_XSPI_CMD_P1_R3_NUM_ADDR_BYTES, (op)->addr.nbytes))
+
+#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_4(op, chipsel) ( \
+ FIELD_PREP(CDNS_XSPI_CMD_P1_R4_ADDR_IOS, ilog2((op)->addr.buswidth)) | \
+ FIELD_PREP(CDNS_XSPI_CMD_P1_R4_CMD_IOS, ilog2((op)->cmd.buswidth)) | \
+ FIELD_PREP(CDNS_XSPI_CMD_P1_R4_BANK, chipsel))
+
+#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_1 \
+ FIELD_PREP(CDNS_XSPI_CMD_INSTR_TYPE, CDNS_XSPI_STIG_INSTR_TYPE_DATA_SEQ)
+
+#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_2(op) \
+ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R2_DCNT_L, (op)->data.nbytes & 0xFFFF)
+
+#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_3(op, dummybytes) ( \
+ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R3_DCNT_H, \
+ ((op)->data.nbytes >> 16) & 0xffff) | \
+ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R3_NUM_OF_DUMMY, \
+ (op)->dummy.buswidth != 0 ? \
+ (((dummybytes) * 8) / (op)->dummy.buswidth) : \
+ 0))
+
+#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_4(op, chipsel) ( \
+ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R4_BANK, chipsel) | \
+ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R4_DATA_IOS, \
+ ilog2((op)->data.buswidth)) | \
+ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R4_DIR, \
+ ((op)->data.dir == SPI_MEM_DATA_IN) ? \
+ CDNS_XSPI_STIG_CMD_DIR_READ : CDNS_XSPI_STIG_CMD_DIR_WRITE))
+
+enum cdns_xspi_stig_instr_type {
+ CDNS_XSPI_STIG_INSTR_TYPE_0,
+ CDNS_XSPI_STIG_INSTR_TYPE_1,
+ CDNS_XSPI_STIG_INSTR_TYPE_DATA_SEQ = 127,
+};
+
+enum cdns_xspi_sdma_dir {
+ CDNS_XSPI_SDMA_DIR_READ,
+ CDNS_XSPI_SDMA_DIR_WRITE,
+};
+
+enum cdns_xspi_stig_cmd_dir {
+ CDNS_XSPI_STIG_CMD_DIR_READ,
+ CDNS_XSPI_STIG_CMD_DIR_WRITE,
+};
+
+struct cdns_xspi_plat {
+ struct device *dev;
+ struct reset_ctl_bulk *resets;
+
+ void __iomem *iobase;
+ void __iomem *auxbase;
+ void __iomem *sdmabase;
+
+ int cur_cs;
+ unsigned int sdmasize;
+ bool sdma_error;
+
+ void *in_buffer;
+ const void *out_buffer;
+
+ u8 hw_num_banks;
+
+ void (*sdma_handler)(struct cdns_xspi_plat *cdns_xspi);
+ void (*set_interrupts_handler)(struct cdns_xspi_plat *cdns_xspi, bool enabled);
+};
+
+#endif /* __CADENCE_XSPI_H__ */
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 427b62e934b..99f381db9f9 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -271,6 +271,7 @@ config USB_EHCI_MSM
config USB_EHCI_PCI
bool "Support for PCI-based EHCI USB controller"
+ depends on PCI
default y if X86
help
Enables support for the PCI-based EHCI controller.
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 3ee1f67190f..d59804580f1 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1249,7 +1249,7 @@ static int xhci_lowlevel_init(struct xhci_ctrl *ctrl)
reg = xhci_readl(&hccr->cr_hcsparams1);
ctrl->hub_desc.bNbrPorts = HCS_MAX_PORTS(reg);
- printf("Register %x NbrPorts %d\n", reg, ctrl->hub_desc.bNbrPorts);
+ debug("Register %x NbrPorts %d\n", reg, ctrl->hub_desc.bNbrPorts);
/* Port Indicators */
reg = xhci_readl(&hccr->cr_hccparams);
diff --git a/include/configs/exynos-mobile.h b/include/configs/exynos-mobile.h
new file mode 100644
index 00000000000..862db5779ef
--- /dev/null
+++ b/include/configs/exynos-mobile.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Samsung Exynos Generic Board Configuration (for mobile devices)
+ *
+ * Copyright (C) 2025 Kaustabh Chakraborty <[email protected]>
+ */
+
+#ifndef __CONFIG_EXYNOS_MOBILE_H
+#define __CONFIG_EXYNOS_MOBILE_H
+
+#define CPU_RELEASE_ADDR secondary_boot_addr
+#define CFG_SYS_BAUDRATE_TABLE {9600, 115200}
+
+#endif /* __CONFIG_EXYNOS_MOBILE_H */
diff --git a/include/configs/ironhide.h b/include/configs/ironhide.h
new file mode 100644
index 00000000000..703c1714052
--- /dev/null
+++ b/include/configs/ironhide.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ */
+
+#ifndef __IRONHIDE_H
+#define __IRONHIDE_H
+
+#include "rcar-gen5-common.h"
+
+#endif /* __IRONHIDE_H */
diff --git a/include/configs/rcar-gen5-common.h b/include/configs/rcar-gen5-common.h
new file mode 100644
index 00000000000..dc28d07c7f9
--- /dev/null
+++ b/include/configs/rcar-gen5-common.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2025 Renesas Electronics Corporation
+ */
+
+#ifndef __RCAR_GEN5_COMMON_H
+#define __RCAR_GEN5_COMMON_H
+
+#include <asm/arch/renesas.h>
+
+/* Console */
+#define CFG_SYS_BAUDRATE_TABLE { 38400, 115200, 921600, 1843200, 3250000 }
+
+/* Memory */
+#define DRAM_RSV_SIZE 0x08000000
+#define CFG_SYS_SDRAM_BASE (0x40000000 + DRAM_RSV_SIZE)
+#define CFG_SYS_SDRAM_SIZE (0x80000000u - DRAM_RSV_SIZE)
+#define CFG_MAX_MEM_MAPPED (0x80000000u - DRAM_RSV_SIZE)
+
+/* Environment setting */
+#define CFG_EXTRA_ENV_SETTINGS \
+ "bootm_size=0x10000000\0"
+
+#endif /* __RCAR_GEN5_COMMON_H */
diff --git a/include/configs/s5p4418_nanopi2.h b/include/configs/s5p4418_nanopi2.h
index fec1bfd50eb..8a8d54daf7b 100644
--- a/include/configs/s5p4418_nanopi2.h
+++ b/include/configs/s5p4418_nanopi2.h
@@ -139,7 +139,6 @@
#endif
#define CFG_EXTRA_ENV_SETTINGS \
- "fdt_high=0xffffffff\0" \
"initrd_high=0xffffffff\0" \
"rootdev=" __stringify(CONFIG_ROOT_DEV) "\0" \
"rootpart=" __stringify(CONFIG_ROOT_PART) "\0" \
diff --git a/include/configs/socfpga_vining_fpga.h b/include/configs/socfpga_vining_fpga.h
index 4bb15cf4629..ad13f1345b0 100644
--- a/include/configs/socfpga_vining_fpga.h
+++ b/include/configs/socfpga_vining_fpga.h
@@ -40,7 +40,6 @@
"hostname=vining_fpga\0" \
"kernel_addr_r=0x10000000\0" \
"fdt_addr_r=0x20000000\0" \
- "fdt_high=0xffffffff\0" \
"initrd_high=0xffffffff\0" \
"dfu_alt_info=qspi0 sf 0:0;qspi1 sf 0:1\0" \
"mtdparts_0_16m=ff705000.spi.0:" /* 16MiB+128MiB SF config */ \
diff --git a/include/dt-bindings/clock/r8a78000-clock-scmi.h b/include/dt-bindings/clock/r8a78000-clock-scmi.h
new file mode 100644
index 00000000000..455402ee8cc
--- /dev/null
+++ b/include/dt-bindings/clock/r8a78000-clock-scmi.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ *
+ * IDs match SCP 4.27
+ */
+
+#ifndef __DT_BINDINGS_R8A78000_SCMI_CLOCK_H__
+#define __DT_BINDINGS_R8A78000_SCMI_CLOCK_H__
+
+/*
+ * These definition indices match the Clock ID defined by SCP FW 4.27.
+ */
+
+#define SCP_CLOCK_ID_MDLC_UFS0 202
+#define SCP_CLOCK_ID_MDLC_UFS1 203
+#define SCP_CLOCK_ID_MDLC_SDHI0 204
+
+#define SCP_CLOCK_ID_MDLC_XPCS0 316
+#define SCP_CLOCK_ID_MDLC_XPCS1 317
+#define SCP_CLOCK_ID_MDLC_XPCS2 318
+#define SCP_CLOCK_ID_MDLC_XPCS3 319
+#define SCP_CLOCK_ID_MDLC_XPCS4 320
+#define SCP_CLOCK_ID_MDLC_XPCS5 321
+#define SCP_CLOCK_ID_MDLC_XPCS6 322
+#define SCP_CLOCK_ID_MDLC_XPCS7 323
+#define SCP_CLOCK_ID_MDLC_RSW3 324
+#define SCP_CLOCK_ID_MDLC_RSW3TSN 325
+#define SCP_CLOCK_ID_MDLC_RSW3AES 326
+#define SCP_CLOCK_ID_MDLC_RSW3TSNTES0 327
+#define SCP_CLOCK_ID_MDLC_RSW3TSNTES1 328
+#define SCP_CLOCK_ID_MDLC_RSW3TSNTES2 329
+#define SCP_CLOCK_ID_MDLC_RSW3TSNTES3 330
+#define SCP_CLOCK_ID_MDLC_RSW3TSNTES4 331
+#define SCP_CLOCK_ID_MDLC_RSW3TSNTES5 332
+#define SCP_CLOCK_ID_MDLC_RSW3TSNTES6 333
+#define SCP_CLOCK_ID_MDLC_RSW3TSNTES7 334
+#define SCP_CLOCK_ID_MDLC_RSW3MFWD 335
+
+#define SCP_CLOCK_ID_MDLC_MPPHY01 344
+#define SCP_CLOCK_ID_MDLC_MPPHY11 345
+#define SCP_CLOCK_ID_MDLC_MPPHY21 346
+#define SCP_CLOCK_ID_MDLC_MPPHY31 347
+#define SCP_CLOCK_ID_MDLC_MPPHY02 348
+
+#endif /* __DT_BINDINGS_R8A78000_SCMI_CLOCK_H__ */
diff --git a/include/dt-bindings/power/r8a78000-power-scmi.h b/include/dt-bindings/power/r8a78000-power-scmi.h
new file mode 100644
index 00000000000..2f1cb8e909c
--- /dev/null
+++ b/include/dt-bindings/power/r8a78000-power-scmi.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ *
+ * IDs match SCP 4.27
+ */
+
+#ifndef __DT_BINDINGS_R8A78000_SCMI_POWER_H__
+#define __DT_BINDINGS_R8A78000_SCMI_POWER_H__
+
+/*
+ * These power domain indices match the Power Domain ID defined by SCP FW 4.27.
+ */
+
+#define X5H_POWER_DOMAIN_ID_UFS0 12
+#define X5H_POWER_DOMAIN_ID_UFS1 13
+
+#define X5H_POWER_DOMAIN_ID_RSW 15
+
+#define X5H_POWER_DOMAIN_ID_MPP0 17
+#define X5H_POWER_DOMAIN_ID_MPP1 18
+#define X5H_POWER_DOMAIN_ID_MPP2 19
+#define X5H_POWER_DOMAIN_ID_MPP3 20
+
+#endif /* __DT_BINDINGS_R8A78000_SCMI_POWER_H__ */
diff --git a/include/dt-bindings/reset/r8a78000-reset-scmi.h b/include/dt-bindings/reset/r8a78000-reset-scmi.h
new file mode 100644
index 00000000000..e0d10caa589
--- /dev/null
+++ b/include/dt-bindings/reset/r8a78000-reset-scmi.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ *
+ * IDs match SCP 4.27
+ */
+
+#ifndef __DT_BINDINGS_R8A78000_SCMI_RESET_H__
+#define __DT_BINDINGS_R8A78000_SCMI_RESET_H__
+
+/*
+ * These definition indices match the Reset ID defined by SCP FW 4.27.
+ */
+
+#define SCP_RESET_DOMAIN_ID_UFS0 202
+#define SCP_RESET_DOMAIN_ID_UFS1 203
+
+#define SCP_RESET_DOMAIN_ID_XPCS0 316
+#define SCP_RESET_DOMAIN_ID_XPCS1 317
+#define SCP_RESET_DOMAIN_ID_XPCS2 318
+#define SCP_RESET_DOMAIN_ID_XPCS3 319
+#define SCP_RESET_DOMAIN_ID_XPCS4 320
+#define SCP_RESET_DOMAIN_ID_XPCS5 321
+#define SCP_RESET_DOMAIN_ID_XPCS6 322
+#define SCP_RESET_DOMAIN_ID_XPCS7 323
+
+#define SCP_RESET_DOMAIN_ID_MPPHY01 344
+#define SCP_RESET_DOMAIN_ID_MPPHY11 345
+#define SCP_RESET_DOMAIN_ID_MPPHY21 346
+#define SCP_RESET_DOMAIN_ID_MPPHY31 347
+#define SCP_RESET_DOMAIN_ID_MPPHY02 348
+
+#endif /* __DT_BINDINGS_R8A78000_SCMI_RESET_H__ */
diff --git a/include/env/adi/adi_boot.env b/include/env/adi/adi_boot.env
index e266c89b110..db4148b1af9 100644
--- a/include/env/adi/adi_boot.env
+++ b/include/env/adi/adi_boot.env
@@ -39,7 +39,7 @@ addip=setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmas
/* Boot modes are selectable and should be defined in the board env before including */
#if defined(USE_NFS)
// rootpath is set by CONFIG_ROOTPATH
-nfsargs=setenv bootargs root=/dev/nfs rw nfsroot=${serverip}${rootpath},tcp,nfsvers=3 ${adi_bootargs}
+nfsargs=setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath},tcp,nfsvers=3 ${adi_bootargs}
nfsboot=run init_ethernet;
tftp ${loadaddr} ${tftp_dir_prefix}${imagefile};
run nfsargs;
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
index 31b47a20186..eafc647f558 100644
--- a/lib/efi_loader/efi_capsule.c
+++ b/lib/efi_loader/efi_capsule.c
@@ -857,18 +857,9 @@ static efi_status_t get_dp_device(u16 *boot_var,
struct efi_device_path *file_dp;
efi_status_t ret;
- size = 0;
- ret = efi_get_variable_int(boot_var, &efi_global_variable_guid,
- NULL, &size, NULL, NULL);
- if (ret == EFI_BUFFER_TOO_SMALL) {
- buf = malloc(size);
- if (!buf)
- return EFI_OUT_OF_RESOURCES;
- ret = efi_get_variable_int(boot_var, &efi_global_variable_guid,
- NULL, &size, buf, NULL);
- }
- if (ret != EFI_SUCCESS)
- return ret;
+ buf = efi_get_var(boot_var, &efi_global_variable_guid, &size);
+ if (!buf)
+ return EFI_NOT_FOUND;
efi_deserialize_load_option(&lo, buf, &size);
@@ -960,22 +951,11 @@ static efi_status_t find_boot_device(void)
skip:
/* find active boot device in BootOrder */
- size = 0;
- ret = efi_get_variable_int(u"BootOrder", &efi_global_variable_guid,
- NULL, &size, NULL, NULL);
- if (ret == EFI_BUFFER_TOO_SMALL) {
- boot_order = malloc(size);
- if (!boot_order) {
- ret = EFI_OUT_OF_RESOURCES;
- goto out;
- }
-
- ret = efi_get_variable_int(u"BootOrder",
- &efi_global_variable_guid,
- NULL, &size, boot_order, NULL);
- }
- if (ret != EFI_SUCCESS)
+ boot_order = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size);
+ if (!boot_order) {
+ ret = EFI_NOT_FOUND;
goto out;
+ }
/* check in higher order */
num = size / sizeof(u16);
diff --git a/test/cmd/fdt.c b/test/cmd/fdt.c
index 8ce888770ac..f0b35cc3bb7 100644
--- a/test/cmd/fdt.c
+++ b/test/cmd/fdt.c
@@ -1274,6 +1274,7 @@ static int fdt_test_chosen(struct unit_test_state *uts)
char fdt[8192];
struct udevice *dev;
ulong addr;
+ ulong smbiosaddr = gd_smbios_start();
ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt), &addr));
fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */
@@ -1292,6 +1293,10 @@ static int fdt_test_chosen(struct unit_test_state *uts)
ut_assert(0 < console_record_readline(uts->actual_str,
sizeof(uts->actual_str)));
ut_asserteq_str("chosen {", uts->actual_str);
+ if (CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE))
+ ut_assert_nextline("\tsmbios3-entrypoint = <0x%08x 0x%08x>;",
+ upper_32_bits(smbiosaddr),
+ lower_32_bits(smbiosaddr));
ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */
if (env_bootargs)
ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs);
@@ -1316,6 +1321,10 @@ static int fdt_test_chosen(struct unit_test_state *uts)
lower_32_bits(0x1234 + 0x5678 - 1));
ut_assert_nextline("\tlinux,initrd-start = <0x%08x 0x%08x>;",
upper_32_bits(0x1234), lower_32_bits(0x1234));
+ if (CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE))
+ ut_assert_nextline("\tsmbios3-entrypoint = <0x%08x 0x%08x>;",
+ upper_32_bits(smbiosaddr),
+ lower_32_bits(smbiosaddr));
ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */
if (env_bootargs)
ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs);
diff --git a/test/dm/fdtdec.c b/test/dm/fdtdec.c
index 1f24f1d5dff..ea5a494612c 100644
--- a/test/dm/fdtdec.c
+++ b/test/dm/fdtdec.c
@@ -7,6 +7,9 @@
#include <asm/global_data.h>
#include <dm/of_extra.h>
#include <dm/test.h>
+#include <fdt_support.h>
+#include <mapmem.h>
+#include <smbios.h>
#include <test/ut.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -129,3 +132,48 @@ static int dm_test_fdtdec_add_reserved_memory(struct unit_test_state *uts)
}
DM_TEST(dm_test_fdtdec_add_reserved_memory,
UTF_SCAN_PDATA | UTF_SCAN_FDT | UTF_FLAT_TREE);
+
+static int dm_test_fdt_chosen_smbios(struct unit_test_state *uts)
+{
+ void *blob;
+ ulong val;
+ struct smbios3_entry *entry;
+ int chosen, blob_sz;
+ const fdt64_t *prop;
+
+ if (!CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)) {
+ return -EAGAIN;
+ }
+
+ blob_sz = fdt_totalsize(gd->fdt_blob) + 4096;
+ blob = memalign(8, blob_sz);
+ ut_assertnonnull(blob);
+
+ /* Make a writable copy of the fdt blob */
+ ut_assertok(fdt_open_into(gd->fdt_blob, blob, blob_sz));
+
+ /* Mock SMBIOS table */
+ entry = map_sysmem(gd->arch.smbios_start, sizeof(struct smbios3_entry));
+ memcpy(entry->anchor, "_SM3_", 5);
+ entry->length = sizeof(struct smbios3_entry);
+ unmap_sysmem(entry);
+
+ /* Force fdt_chosen to run */
+ ut_assertok(fdt_chosen(blob));
+
+ chosen = fdt_path_offset(blob, "/chosen");
+ ut_assert(chosen >= 0);
+
+ /* Verify the property exists */
+ prop = fdt_getprop(blob, chosen, "smbios3-entrypoint", NULL);
+ ut_assertnonnull(prop);
+
+ /* Verify the property matches smbios_start */
+ val = fdt64_to_cpu(*prop);
+ ut_asserteq_64(gd->arch.smbios_start, val);
+
+ free(blob);
+
+ return 0;
+}
+DM_TEST(dm_test_fdt_chosen_smbios, UTF_SCAN_PDATA | UTF_SCAN_FDT);
diff --git a/test/lib/strlcat.c b/test/lib/strlcat.c
index d1a0293271b..a3d4eee4795 100644
--- a/test/lib/strlcat.c
+++ b/test/lib/strlcat.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.1+
+// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2021 Sean Anderson <[email protected]>
* Copyright (C) 2011-2021 Free Software Foundation, Inc.
diff --git a/tools/binman/control.py b/tools/binman/control.py
index 1307222591d..816f7c1eba2 100644
--- a/tools/binman/control.py
+++ b/tools/binman/control.py
@@ -9,8 +9,9 @@ from collections import OrderedDict
import glob
try:
import importlib.resources as importlib_resources
-except ImportError: # pragma: no cover
- # for Python 3.6
+ # for Python 3.6, 3.7 and 3.8
+ importlib_resources.files
+except (ImportError, AttributeError): # pragma: no cover
import importlib_resources
import os
import re
diff --git a/tools/cv_bsp_generator/cv_bsp_generator.py b/tools/cv_bsp_generator/cv_bsp_generator.py
new file mode 100755
index 00000000000..aff597d3978
--- /dev/null
+++ b/tools/cv_bsp_generator/cv_bsp_generator.py
@@ -0,0 +1,100 @@
+#! /usr/bin/env python
+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+"""
+Bsp preloader header file generator
+
+Process the handoff files from Quartus and convert them to headers
+usable by U-Boot. Includes the qts filter.sh capability to generate
+correct format for headers to be used for mainline Uboot on FPGA,
+namely Cyclone V & Arria V.
+
+Copyright (C) 2022 Intel Corporation <www.intel.com>
+
+Author: Lee, Kah Jing <[email protected]>
+"""
+import glob
+import optparse
+import os
+import shutil
+import emif
+import hps
+import iocsr
+import renderer
+import model
+import collections
+import sys
+
+def printUsage():
+ """ usage string """
+ print ("Usage:\n\t%s\n" % ("sys.argv[0], --input_dir=<path to iswinfo directory> --output_dir=<path store output files>"))
+ exit(1)
+
+def verifyInputDir(dir):
+ """ check if the input directory exists """
+ if not os.path.isdir(dir):
+ print ("There is no such directory '%s'!\n" % (dir))
+ exit(1)
+
+def verifyOutputDir(dir):
+ """ check if the output directory exists """
+ if not os.path.isdir(dir):
+ os.makedirs(dir)
+
+if __name__ == '__main__':
+ # Do some rudimentary command line processing until it is proven we need something
+ # heavier, such as argparse (preferred, but 2.7+ only) or optparse
+
+ inputDir = '.'
+ outputDir = '.'
+
+ progVersion = '%prog 1.0'
+ progDesc = 'Generate board-specific files for the preloader'
+ optParser = optparse.OptionParser(version=progVersion, description=progDesc)
+ optParser.add_option('-i', '--input-dir', action='store', type='string', dest='inputDir', default='.',
+ help='input-dir is usually the iswinfo directory')
+ optParser.add_option('-o', '--output-dir', action='store', type='string', dest='outputDir', default='.',
+ help='output-dir is usually the directory containing the preloader source')
+
+ (options, args) = optParser.parse_args()
+
+ for arg in args:
+ print ("***WARNING: I don't understand '%s', so I am ignoring it\n" % (arg))
+
+ inputDir = options.inputDir
+ verifyInputDir(inputDir)
+ outputDir = options.outputDir
+
+ verifyOutputDir(outputDir)
+
+ emif = emif.EMIFGrokker(inputDir, outputDir, 'emif.xml')
+ hps = hps.HPSGrokker(inputDir, outputDir)
+
+ pllConfigH = outputDir + "/" + "pll_config.h"
+ print ("Generating file: " + pllConfigH)
+ hpsModel = model.hps.create(inputDir + "/" + "hps.xml")
+ emifModel = model.emif.create(inputDir +"/" + "emif.xml")
+
+ content=str(renderer.pll_config_h(hpsModel, emifModel))
+ f = open(pllConfigH, "w")
+ f.write(content)
+ f.close()
+
+ # For all the .hiof files, make a iocsr_config.[h|c]
+ # Only support single hiof file currently
+ hiof_list = glob.glob(inputDir + os.sep + "*.hiof")
+ if len(hiof_list) < 1:
+ print ("***Error: No .hiof files found in input!")
+
+ elif len(hiof_list) > 1:
+ print ("***Error: We don't handle more than one .hiof file yet")
+ print (" Only the last .hiof file in the list will be converted")
+ print (" hiof files found:")
+ for f in hiof_list:
+ print (" " + f)
+
+ for hiof_file_path in hiof_list:
+ hiof_file = os.path.basename(hiof_file_path)
+ # Avoid IOCSRGrokker having to parse hps.xml to determine
+ # device family for output file name, instead we'll just
+ # get it from HPSGrokker
+ iocsr = iocsr.IOCSRGrokker(hps.getDeviceFamily(), inputDir, outputDir, hiof_file)
diff --git a/tools/cv_bsp_generator/doc.py b/tools/cv_bsp_generator/doc.py
new file mode 100755
index 00000000000..86c5726c5f1
--- /dev/null
+++ b/tools/cv_bsp_generator/doc.py
@@ -0,0 +1,243 @@
+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+"""
+Generic document construction classes.
+
+These classes are templates for creating documents that are not bound
+to a specific usage or data model.
+
+Copyright (C) 2022 Intel Corporation <www.intel.com>
+
+Author: Lee, Kah Jing <[email protected]>
+"""
+
+class document(object):
+ """
+ An abstract document class which does not dictate
+ how a document should be constructed or manipulated.
+
+ It's sole purpose is to describe the entire document
+ in smaller units
+ """
+
+ class entry(object):
+ """
+ An entry is the smallest unit
+ """
+
+ def __init__(self, parent):
+ """ entry initialization """
+ if parent != None:
+ parent.add(self)
+
+ class block(entry):
+ """
+ A block is the smallest collection unit
+ consists of entries and blocks.
+ """
+
+ def __init__(self, parent):
+ """ block initialization """
+ super(document.block, self).__init__(parent)
+ self.entries = []
+
+ def add(self, entry):
+ """ add entry to block """
+ self.entries.append(entry)
+
+
+ def __init__(self):
+ """ document initialization """
+ self.entries = []
+
+ def add(self, entry):
+ """ add entry to entry list """
+ self.entries.append(entry)
+
+
+class text(document):
+ """
+ A simple text document implementation
+ """
+
+ class string(document.entry):
+ """
+ The smallest unit of a text file is a string
+ """
+
+ def __init__(self, parent, stringString=None):
+ """ string initialization """
+ super(text.string, self).__init__(parent)
+ self.stringString = stringString
+
+ def __str__(self):
+ """ convert None to empty string """
+ if (self.stringString != None):
+ return self.stringString
+ else:
+ return ""
+
+
+ class line(string):
+ """
+ A line is a string with EOL character
+ """
+
+ def __str__(self):
+ """ convert string with newline """
+ return super(text.line, self).__str__() + "\n"
+
+ class block(document.block):
+ """
+ A block of text which can be made up of
+ strings or lines
+ """
+
+ def __str__(self):
+ """ concatenate strings or lines """
+ blockString = ""
+
+ for entry in self.entries:
+ blockString += str(entry)
+
+ return blockString
+
+
+ def __str__(self):
+ """ concatenate strings or lines """
+ textString = ""
+
+ for entry in self.entries:
+ textString += str(entry)
+
+ return textString
+
+
+class c_source(text):
+ """
+ A simple C header document implementation
+ """
+
+ class define(text.string):
+ """
+ C header define
+ """
+
+ def __init__(self, parent, id, token=None):
+ """ c header constructor initialization """
+ super(c_source.define, self).__init__(parent, id)
+ self.token = token
+
+ def __str__(self):
+ """ c header to strings """
+ defineString = "#define" + " " + super(c_source.define, self).__str__()
+
+ if self.token != None:
+ defineString += " " + self.token
+
+ defineString += "\n"
+
+ return defineString
+
+ class comment_string(text.string):
+ """
+ C header comment
+ """
+
+ def __str__(self):
+ """ c comment """
+ return "/*" + " " + super(c_source.comment_string, self).__str__() + " " + "*/"
+
+ class comment_line(comment_string):
+ """
+ C header comment with newline
+ """
+
+ def __str__(self):
+ """ c comment with newline """
+ return super(c_source.comment_line, self).__str__() + "\n"
+
+ class block(text.block):
+ """
+ A simple C block string implementation
+ """
+
+ def __init__(self, parent, prologue=None, epilogue=None):
+ """ ifdef block string implementation """
+ super(c_source.block, self).__init__(parent)
+
+ self.prologue = None
+ self.epilogue = None
+
+ if prologue != None:
+ self.prologue = prologue
+
+ if epilogue != None:
+ self.epilogue = epilogue
+
+ def __str__(self):
+ """ convert ifdef to string """
+ blockString = ""
+
+ if self.prologue != None:
+ blockString += str(self.prologue)
+
+ blockString += super(c_source.block, self).__str__()
+
+ if self.epilogue != None:
+ blockString += str(self.epilogue)
+
+ return blockString
+
+ class comment_block(block):
+ """
+ A simple C header block comment implementation
+ """
+
+ def __init__(self, parent, comments):
+ """ block comment initialization """
+ super(c_source.comment_block, self).__init__(parent, "/*\n", " */\n")
+ for comment in comments.split("\n"):
+ self.add(comment)
+
+ def add(self, entry):
+ """ add line to block comment """
+ super(c_source.block, self).add(" * " + entry + "\n")
+
+ class ifndef_block(block):
+ """
+ A simple C header ifndef implementation
+ """
+
+ def __init__(self, parent, id):
+ """ ifndef block initialization """
+ prologue = text.line(None, "#ifndef" + " " + id)
+ epilogue = text.block(None)
+ text.string(epilogue, "#endif")
+ text.string(epilogue, " ")
+ c_source.comment_line(epilogue, id)
+ super(c_source.ifndef_block, self).__init__(parent, prologue, epilogue)
+
+
+class generated_c_source(c_source):
+ """
+ Caller to generate c format files using the helper classes
+ """
+
+ def __init__(self, filename):
+ """ Generate c header file with license, copyright, comment,
+ ifdef block
+ """
+ super(generated_c_source, self).__init__()
+
+ self.entries.append(c_source.comment_line(None, "SPDX-License-Identifier: BSD-3-Clause"))
+ self.entries.append(c_source.comment_block(None, "Copyright (C) 2022 Intel Corporation <www.intel.com>"))
+ self.entries.append(c_source.comment_block(None, "Altera SoCFPGA Clock and PLL configuration"))
+ self.entries.append(text.line(None))
+
+ self.body = c_source.ifndef_block(None, filename)
+ self.body.add(c_source.define(None, filename))
+ self.entries.append(self.body)
+
+ def add(self, entry):
+ """ add content to be written into c header file """
+ self.body.add(entry)
diff --git a/tools/cv_bsp_generator/emif.py b/tools/cv_bsp_generator/emif.py
new file mode 100755
index 00000000000..143bd2da550
--- /dev/null
+++ b/tools/cv_bsp_generator/emif.py
@@ -0,0 +1,424 @@
+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+"""
+SDRAM header file generator
+
+Process the handoff files from Quartus and convert them to headers
+usable by U-Boot.
+
+Copyright (C) 2022 Intel Corporation <www.intel.com>
+
+Author: Lee, Kah Jing <[email protected]>
+"""
+
+import os
+import re
+import xml.dom.minidom
+import streamer
+import xmlgrok
+
+class EMIFGrokker(object):
+ """ parse an emif.xml input and translate to various
+ outputs
+ """
+ SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
+ TEMPLATE_DIR = os.path.dirname(SCRIPT_DIR) + '/src'
+ SDRAM_FILE_HEADER = '/*\n' + ' * Altera SoCFPGA SDRAM configuration\n' + ' *\n' + ' */\n\n'
+ SDRAM_SENTINEL = '__SOCFPGA_SDRAM_CONFIG_H__'
+ SDRAM_MATCH = r'#define (CFG_HPS_SDR_CTRLCFG_CTRLCFG_MEMTYPE|CFG_HPS_SDR_CTRLCFG_CTRLCFG_MEMBL|CFG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER|CFG_HPS_SDR_CTRLCFG_CTRLCFG_ECCEN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_ECCCORREN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_REORDEREN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_STARVELIMIT|CFG_HPS_SDR_CTRLCFG_CTRLCFG_DQSTRKEN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_NODMPINS|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCWL|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_AL|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCL|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRRD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TFAW|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRFC|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TREFI|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRCD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRP|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWR|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWTR|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRTP|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRAS|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRC|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TMRD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TCCD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING4_SELFRFSHEXIT|CFG_HPS_SDR_CTRLCFG_DRAMTIMING4_PWRDOWNEXIT|CFG_HPS_SDR_CTRLCFG_LOWPWRTIMING_AUTOPDCYCLES|CFG_HPS_SDR_CTRLCFG_LOWPWRTIMING_CLKDISABLECYCLES|CFG_HPS_SDR_CTRLCFG_DRAMODT_READ|CFG_HPS_SDR_CTRLCFG_DRAMODT_WRITE|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS|CFG_HPS_SDR_CTRLCFG_DRAMIFWIDTH_IFWIDTH|CFG_HPS_SDR_CTRLCFG_DRAMDEVWIDTH_DEVWIDTH|CFG_HPS_SDR_CTRLCFG_DRAMINTR_INTREN|CFG_HPS_SDR_CTRLCFG_LOWPWREQ_SELFRFSHMASK|CFG_HPS_SDR_CTRLCFG_STATICCFG_MEMBL|CFG_HPS_SDR_CTRLCFG_STATICCFG_USEECCASDATA|CFG_HPS_SDR_CTRLCFG_CTRLWIDTH_CTRLWIDTH|CFG_HPS_SDR_CTRLCFG_CPORTWIDTH_CPORTWIDTH|CFG_HPS_SDR_CTRLCFG_CPORTWMAP_CPORTWMAP|CFG_HPS_SDR_CTRLCFG_CPORTRMAP_CPORTRMAP|CFG_HPS_SDR_CTRLCFG_RFIFOCMAP_RFIFOCMAP|CFG_HPS_SDR_CTRLCFG_WFIFOCMAP_WFIFOCMAP|CFG_HPS_SDR_CTRLCFG_CPORTRDWR_CPORTRDWR|CFG_HPS_SDR_CTRLCFG_PORTCFG_AUTOPCHEN|CFG_HPS_SDR_CTRLCFG_FPGAPORTRST|CFG_HPS_SDR_CTRLCFG_FIFOCFG_SYNCMODE|CFG_HPS_SDR_CTRLCFG_FIFOCFG_INCSYNC|CFG_HPS_SDR_CTRLCFG_MPPRIORITY_USERPRIORITY|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_0_STATICWEIGHT_31_0|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_STATICWEIGHT_49_32|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_SUMOFWEIGHT_13_0|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_2_SUMOFWEIGHT_45_14|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_3_SUMOFWEIGHT_63_46|CFG_HPS_SDR_CTRLCFG_PHYCTRL_PHYCTRL_0|CFG_HPS_SDR_CTRLCFG_MPPACING_0_THRESHOLD1_31_0|CFG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD1_59_32|CFG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD2_3_0|CFG_HPS_SDR_CTRLCFG_MPPACING_2_THRESHOLD2_35_4|CFG_HPS_SDR_CTRLCFG_MPPACING_3_THRESHOLD2_59_36|CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_0_THRESHOLDRSTCYCLES_31_0|CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_1_THRESHOLDRSTCYCLES_63_32|CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64|RW_MGR_ACTIVATE_0_AND_1|RW_MGR_ACTIVATE_0_AND_1_WAIT1|RW_MGR_ACTIVATE_0_AND_1_WAIT2|RW_MGR_ACTIVATE_1|RW_MGR_CLEAR_DQS_ENABLE|RW_MGR_EMR_OCD_ENABLE|RW_MGR_EMR|RW_MGR_EMR2|RW_MGR_EMR3|RW_MGR_GUARANTEED_READ|RW_MGR_GUARANTEED_READ_CONT|RW_MGR_GUARANTEED_WRITE|RW_MGR_GUARANTEED_WRITE_WAIT0|RW_MGR_GUARANTEED_WRITE_WAIT1|RW_MGR_GUARANTEED_WRITE_WAIT2|RW_MGR_GUARANTEED_WRITE_WAIT3|RW_MGR_IDLE|RW_MGR_IDLE_LOOP1|RW_MGR_IDLE_LOOP2|RW_MGR_INIT_RESET_0_CKE_0|RW_MGR_INIT_RESET_1_CKE_0|RW_MGR_INIT_CKE_0|RW_MGR_LFSR_WR_RD_BANK_0|RW_MGR_LFSR_WR_RD_BANK_0_DATA|RW_MGR_LFSR_WR_RD_BANK_0_DQS|RW_MGR_LFSR_WR_RD_BANK_0_NOP|RW_MGR_LFSR_WR_RD_BANK_0_WAIT|RW_MGR_LFSR_WR_RD_BANK_0_WL_1|RW_MGR_LFSR_WR_RD_DM_BANK_0|RW_MGR_LFSR_WR_RD_DM_BANK_0_DATA|RW_MGR_LFSR_WR_RD_DM_BANK_0_DQS|RW_MGR_LFSR_WR_RD_DM_BANK_0_NOP|RW_MGR_LFSR_WR_RD_DM_BANK_0_WAIT|RW_MGR_LFSR_WR_RD_DM_BANK_0_WL_1|RW_MGR_MR_CALIB|RW_MGR_MR_USER|RW_MGR_MR_DLL_RESET|RW_MGR_MRS0_DLL_RESET|RW_MGR_MRS0_DLL_RESET_MIRR|RW_MGR_MRS0_USER|RW_MGR_MRS0_USER_MIRR|RW_MGR_MRS1|RW_MGR_MRS1_MIRR|RW_MGR_MRS2|RW_MGR_MRS2_MIRR|RW_MGR_MRS3|RW_MGR_MRS3_MIRR|RW_MGR_NOP|RW_MGR_PRECHARGE_ALL|RW_MGR_READ_B2B|RW_MGR_READ_B2B_WAIT1|RW_MGR_READ_B2B_WAIT2|RW_MGR_REFRESH|RW_MGR_REFRESH_ALL|RW_MGR_RETURN|RW_MGR_SGLE_READ|RW_MGR_ZQCL|RW_MGR_TRUE_MEM_DATA_MASK_WIDTH|RW_MGR_MEM_ADDRESS_MIRRORING|RW_MGR_MEM_DATA_MASK_WIDTH|RW_MGR_MEM_DATA_WIDTH|RW_MGR_MEM_DQ_PER_READ_DQS|RW_MGR_MEM_DQ_PER_WRITE_DQS|RW_MGR_MEM_IF_READ_DQS_WIDTH|RW_MGR_MEM_IF_WRITE_DQS_WIDTH|RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM|RW_MGR_MEM_NUMBER_OF_RANKS|RW_MGR_MEM_VIRTUAL_GROUPS_PER_READ_DQS|RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS|IO_DELAY_PER_DCHAIN_TAP|IO_DELAY_PER_DQS_EN_DCHAIN_TAP|IO_DELAY_PER_OPA_TAP|IO_DLL_CHAIN_LENGTH|IO_DQDQS_OUT_PHASE_MAX|IO_DQS_EN_DELAY_MAX|IO_DQS_EN_DELAY_OFFSET|IO_DQS_EN_PHASE_MAX|IO_DQS_IN_DELAY_MAX|IO_DQS_IN_RESERVE|IO_DQS_OUT_RESERVE|IO_IO_IN_DELAY_MAX|IO_IO_OUT1_DELAY_MAX|IO_IO_OUT2_DELAY_MAX|IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS|AFI_RATE_RATIO|AFI_CLK_FREQ|CALIB_LFIFO_OFFSET|CALIB_VFIFO_OFFSET|ENABLE_SUPER_QUICK_CALIBRATION|MAX_LATENCY_COUNT_WIDTH|READ_VALID_FIFO_SIZE|REG_FILE_INIT_SEQ_SIGNATURE|TINIT_CNTR0_VAL|TINIT_CNTR1_VAL|TINIT_CNTR2_VAL|TRESET_CNTR0_VAL|TRESET_CNTR1_VAL|TRESET_CNTR2_VAL|CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR|CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_BC|CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_DIFF_CHIP)\s+'
+
+ SDRAM_CONFIG_H_FILENAME = "sdram_config.h"
+
+ sdramHTemplate = ""
+ seqAutoTemplate = ""
+ seqDefinesTemplate = ""
+ seqAutoAcTemplate = ""
+ seqAutoInstTemplate = ""
+ seqAutoTemplateList = []
+ seqDefinesTemplateList = []
+ seqAutoAcTemplateList = []
+ seqAutoInstTemplateList = []
+
+ def __init__(self, inputDir, outputDir, emifFileName='emif.xml', hpsFileName='hps.xml'):
+ """ EMIFGrokker initialization """
+ self.inputDir = inputDir
+ self.outputDir = outputDir
+
+ sdramDir = self.outputDir
+ if not os.path.isdir(sdramDir):
+ os.makedirs(sdramDir)
+
+ self.emifFileName = inputDir + os.sep + emifFileName
+ self.hpsFileName = inputDir + os.sep + hpsFileName
+ self.emifDom = xml.dom.minidom.parse(self.emifFileName)
+ self.hpsDom = xml.dom.minidom.parse(self.hpsFileName)
+ self.sequencerDefinesStream = None
+ self.seqAutoFileName = inputDir + os.sep + "sequencer_auto.h"
+ self.seqDefinesFileName = inputDir + os.sep + "sequencer_defines.h"
+ self.seqAutoACFileName = inputDir + os.sep + "sequencer_auto_ac_init.c"
+ self.seqAutoInstFileName = inputDir + os.sep + "sequencer_auto_inst_init.c"
+
+ self.createFilesFromEMIF()
+
+ def openSeqFiles(self):
+ """ files to retrieve values to written to sdram_config.h """
+ self.seq_auto_fd = open(self.seqAutoFileName, "r")
+ self.seq_defines_fd = open(self.seqDefinesFileName, "r")
+ self.seq_auto_ac_fd = open(self.seqAutoACFileName, "r")
+ self.seq_auto_inst_fd = open(self.seqAutoInstFileName, "r")
+
+ def closeSeqFiles(self):
+ """ close files """
+ self.seq_auto_fd.close()
+ self.seq_defines_fd.close()
+ self.seq_auto_ac_fd.close()
+ self.seq_auto_inst_fd.close()
+
+ def processSeqAuto(self):
+ """ process sequencer files to retrieve variable. Regex match is from
+ qts-filter.sh
+ """
+ # replace underscore & bracket in sequencer_auto.h define
+ for line in self.seq_auto_fd.readlines():
+ if re.match(".*__RW_MGR_", line) and not re.match(".*ac_", line) and not re.match(".*CONTENT_", line):
+ line = re.sub("__RW_MGR", "RW_MGR", line)
+ if re.match(self.SDRAM_MATCH, line):
+ self.seqAutoTemplateList.append(re.sub(r' (\w+)(\s+)(\d+)', r' \1\t\3', line))
+ self.seqAutoTemplateList.sort()
+ self.seqAutoTemplate = ''.join([item for item in self.seqAutoTemplateList])
+
+ # replace underscore & bracket in sequencer_defines.h define
+ for line in self.seq_defines_fd.readlines():
+ if re.match("^#define (\w+_)", line):
+ line = re.sub("__", "", line)
+ if re.match(self.SDRAM_MATCH, line):
+ self.seqDefinesTemplateList.append(re.sub(r' (\w+)(\s+)(\d+)', r' \1\t\3', line))
+ self.seqDefinesTemplateList.sort()
+ self.seqDefinesTemplate = ''.join([item for item in self.seqDefinesTemplateList])
+
+ arrayMatchStart = 0
+ # replace const variable declaration in sequencer_auto_ac_init.c
+ for line in self.seq_auto_ac_fd.readlines():
+ if re.match("^const.*\[", line) or arrayMatchStart:
+ if arrayMatchStart == 0:
+ line = line.strip() + " "
+ arrayMatchStart = 1
+ if re.match("};", line):
+ arrayMatchStart = 0
+ self.seqAutoAcTemplateList.append("};")
+ continue
+ line = re.sub("alt_u32", "u32", line)
+ self.seqAutoAcTemplateList.append(re.sub("\[.*\]", "[]", line))
+ self.seqAutoAcTemplate = ''.join([item for item in self.seqAutoAcTemplateList])
+
+ arrayMatchStart = 0
+ # replace const variable declaration in sequencer_auto_inst_init.c
+ for line in self.seq_auto_inst_fd.readlines():
+ if re.match("^const.*\[", line) or arrayMatchStart:
+ if arrayMatchStart == 0:
+ line = line.strip() + " "
+ arrayMatchStart = 1
+ if re.match("};", line):
+ arrayMatchStart = 0
+ self.seqAutoInstTemplateList.append("};")
+ continue
+ line = re.sub("alt_u32", "u32", line)
+ self.seqAutoInstTemplateList.append(re.sub("\[.*\]", "[]", line))
+ self.seqAutoInstTemplate = ''.join([item for item in self.seqAutoInstTemplateList])
+
+ def handleSettingNode(self, settingNode):
+ """ create define string from variable name and value """
+ if settingNode.hasAttribute('name') and settingNode.hasAttribute('value'):
+ name = settingNode.getAttribute('name')
+ value = settingNode.getAttribute('value')
+ self.sequencerDefinesStream.write("#define " + name + ' ' + '(' + value + ')' + '\n')
+
+ def updateTemplate(self, name, value):
+ """ update sdram template """
+ pattern = "${" + name + "}"
+ self.sdramHTemplate = self.sdramHTemplate.replace(pattern, value)
+
+ def handleEMIFControllerNode(self, node):
+ """ retrieve values from emif.xml for controller node """
+ derivedNoDmPins = 0
+ derivedCtrlWidth = 0
+ derivedEccEn = 0
+ derivedEccCorrEn = 0
+
+ self.mem_if_rd_to_wr_turnaround_oct = 0
+
+ node = xmlgrok.firstElementChild(node)
+ while node != None:
+ name = node.getAttribute('name')
+ value = node.getAttribute('value')
+
+ if value == "true":
+ value = "1"
+ elif value == "false":
+ value = "0"
+
+ self.updateTemplate(name, value)
+
+ if name == "MEM_IF_DM_PINS_EN":
+ if value == "1":
+ derivedNoDmPins = 0
+ else:
+ derivedNoDmPins = 1
+
+ if name == "MEM_DQ_WIDTH":
+ if value == "8":
+ derivedCtrlWidth = 0
+ derivedEccEn = 0
+ derivedEccCorrEn = 0
+ elif value == "16":
+ derivedCtrlWidth = 1
+ derivedEccEn = 0
+ derivedEccCorrEn = 0
+ elif value == "24":
+ derivedCtrlWidth = 1
+ derivedEccEn = 1
+ derivedEccCorrEn = 1
+ elif value == "32":
+ derivedCtrlWidth = 2
+ derivedEccEn = 0
+ derivedEccCorrEn = 0
+ elif value == "40":
+ derivedCtrlWidth = 2
+ derivedEccEn = 1
+ derivedEccCorrEn = 1
+
+ if name == "MEM_IF_RD_TO_WR_TURNAROUND_OCT":
+ self.mem_if_rd_to_wr_turnaround_oct = int(value)
+
+ node = xmlgrok.nextElementSibling(node)
+
+ self.updateTemplate("DERIVED_NODMPINS", str(derivedNoDmPins))
+ self.updateTemplate("DERIVED_CTRLWIDTH", str(derivedCtrlWidth))
+ self.updateTemplate("DERIVED_ECCEN", str(derivedEccEn))
+ self.updateTemplate("DERIVED_ECCCORREN", str(derivedEccCorrEn))
+
+ def handleEMIFPllNode(self, node):
+ """ retrieve values for pll node """
+ node = xmlgrok.firstElementChild(node)
+ while node != None:
+ name = node.getAttribute('name')
+ value = node.getAttribute('value')
+
+ self.updateTemplate(name, value)
+
+ node = xmlgrok.nextElementSibling(node)
+
+ def handleEMIFSequencerNode(self, node):
+ """ retrieve values for sequencer node """
+ derivedMemtype = 0
+ derivedSelfrfshexit = 0
+
+ self.afi_rate_ratio = 0
+
+ node = xmlgrok.firstElementChild(node)
+ while node != None:
+ name = node.getAttribute('name')
+ value = node.getAttribute('value')
+
+ self.updateTemplate(name, value)
+
+ if value.isdigit():
+ intValue = int(value)
+ else:
+ intValue = 0
+
+ if name == "DDR2" and intValue != 0:
+ derivedMemtype = 1
+ derivedSelfrfshexit = 200
+ elif name == "DDR3" and intValue != 0:
+ derivedMemtype = 2
+ derivedSelfrfshexit = 512
+ elif name == "LPDDR1" and intValue != 0:
+ derivedMemtype = 3
+ derivedSelfrfshexit = 200
+ elif name == "LPDDR2" and intValue != 0:
+ derivedMemtype = 4
+ derivedSelfrfshexit = 200
+ elif name == "AFI_RATE_RATIO" and intValue != 0:
+ self.afi_rate_ratio = intValue
+
+ node = xmlgrok.nextElementSibling(node)
+
+ self.updateTemplate("DERIVED_MEMTYPE", str(derivedMemtype))
+ self.updateTemplate("DERIVED_SELFRFSHEXIT", str(derivedSelfrfshexit))
+
+
+ def handleHpsFpgaInterfaces(self, node):
+ """ retrieve values for fpga interface """
+ node = xmlgrok.firstElementChild(node)
+
+ while node != None:
+ name = node.getAttribute('name')
+ value = node.getAttribute('value')
+
+ self.updateTemplate(name, value)
+
+ node = xmlgrok.nextElementSibling(node)
+
+
+ def createFilesFromEMIF(self):
+ """ create sdram_config.h with the template and value read from xml.
+ Different sequencer files are written to individual section, with
+ comment at the start.
+ """
+ self.sdramHTemplate ="""\
+#define CFG_HPS_SDR_CTRLCFG_CPORTRDWR_CPORTRDWR 0x5A56A
+#define CFG_HPS_SDR_CTRLCFG_CPORTRMAP_CPORTRMAP 0xB00088
+#define CFG_HPS_SDR_CTRLCFG_CPORTWIDTH_CPORTWIDTH 0x44555
+#define CFG_HPS_SDR_CTRLCFG_CPORTWMAP_CPORTWMAP 0x2C011000
+#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER ${ADDR_ORDER}
+#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_DQSTRKEN ${USE_HPS_DQS_TRACKING}
+#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_ECCCORREN ${DERIVED_ECCCORREN}
+#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_ECCEN ${DERIVED_ECCEN}
+#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_MEMBL ${MEM_BURST_LENGTH}
+#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_MEMTYPE ${DERIVED_MEMTYPE}
+#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_NODMPINS ${DERIVED_NODMPINS}
+#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_REORDEREN 1
+#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_STARVELIMIT 10
+#define CFG_HPS_SDR_CTRLCFG_CTRLWIDTH_CTRLWIDTH ${DERIVED_CTRLWIDTH}
+#define CFG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS ${MEM_IF_BANKADDR_WIDTH}
+#define CFG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS ${MEM_IF_COL_ADDR_WIDTH}
+#define CFG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS ${DEVICE_DEPTH}
+#define CFG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS ${MEM_IF_ROW_ADDR_WIDTH}
+#define CFG_HPS_SDR_CTRLCFG_DRAMDEVWIDTH_DEVWIDTH 8
+#define CFG_HPS_SDR_CTRLCFG_DRAMIFWIDTH_IFWIDTH ${MEM_DQ_WIDTH}
+#define CFG_HPS_SDR_CTRLCFG_DRAMINTR_INTREN 0
+#define CFG_HPS_SDR_CTRLCFG_DRAMODT_READ ${CFG_READ_ODT_CHIP}
+#define CFG_HPS_SDR_CTRLCFG_DRAMODT_WRITE ${CFG_WRITE_ODT_CHIP}
+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_AL 0
+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCL ${MEM_TCL}
+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCWL ${MEM_WTCL_INT}
+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TFAW ${MEM_TFAW}
+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRFC ${MEM_TRFC}
+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRRD ${MEM_TRRD}
+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRCD ${MEM_TRCD}
+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TREFI ${MEM_TREFI}
+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRP ${MEM_TRP}
+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWR ${MEM_TWR}
+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWTR ${MEM_TWTR}
+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TCCD 4
+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TMRD ${MEM_TMRD_CK}
+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRAS ${MEM_TRAS}
+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRC ${MEM_TRC}
+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRTP ${MEM_TRTP}
+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING4_PWRDOWNEXIT 3
+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING4_SELFRFSHEXIT ${DERIVED_SELFRFSHEXIT}
+#define CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR ${DERIVED_CLK_RD_TO_WR}
+#define CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_BC ${DERIVED_CLK_RD_TO_WR}
+#define CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_DIFF_CHIP ${DERIVED_CLK_RD_TO_WR}
+#define CFG_HPS_SDR_CTRLCFG_FIFOCFG_INCSYNC 0
+#define CFG_HPS_SDR_CTRLCFG_FIFOCFG_SYNCMODE 0
+#define CFG_HPS_SDR_CTRLCFG_FPGAPORTRST ${F2SDRAM_RESET_PORT_USED}
+#define CFG_HPS_SDR_CTRLCFG_LOWPWREQ_SELFRFSHMASK 3
+#define CFG_HPS_SDR_CTRLCFG_LOWPWRTIMING_AUTOPDCYCLES 0
+#define CFG_HPS_SDR_CTRLCFG_LOWPWRTIMING_CLKDISABLECYCLES 8
+#define CFG_HPS_SDR_CTRLCFG_MPPACING_0_THRESHOLD1_31_0 0x20820820
+#define CFG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD1_59_32 0x8208208
+#define CFG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD2_3_0 0
+#define CFG_HPS_SDR_CTRLCFG_MPPACING_2_THRESHOLD2_35_4 0x41041041
+#define CFG_HPS_SDR_CTRLCFG_MPPACING_3_THRESHOLD2_59_36 0x410410
+#define CFG_HPS_SDR_CTRLCFG_MPPRIORITY_USERPRIORITY 0x0
+#define CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_0_THRESHOLDRSTCYCLES_31_0 0x01010101
+#define CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_1_THRESHOLDRSTCYCLES_63_32 0x01010101
+#define CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64 0x0101
+#define CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_0_STATICWEIGHT_31_0 0x21084210
+#define CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_STATICWEIGHT_49_32 0x10441
+#define CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_SUMOFWEIGHT_13_0 0x78
+#define CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_2_SUMOFWEIGHT_45_14 0x0
+#define CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_3_SUMOFWEIGHT_63_46 0x0
+#define CFG_HPS_SDR_CTRLCFG_PHYCTRL_PHYCTRL_0 0x200
+#define CFG_HPS_SDR_CTRLCFG_PORTCFG_AUTOPCHEN 0
+#define CFG_HPS_SDR_CTRLCFG_RFIFOCMAP_RFIFOCMAP 0x760210
+#define CFG_HPS_SDR_CTRLCFG_STATICCFG_MEMBL 2
+#define CFG_HPS_SDR_CTRLCFG_STATICCFG_USEECCASDATA 0
+#define CFG_HPS_SDR_CTRLCFG_WFIFOCMAP_WFIFOCMAP 0x980543
+"""
+
+ # Get a list of all nodes with the emif element name
+ emifNodeList = self.emifDom.getElementsByTagName('emif')
+ if len(emifNodeList) > 1:
+ print ("*** WARNING:" + "Multiple emif Elements found in %s!" % self.emifFileName)
+ # For each of the emif element nodes, go through the child list
+ # Note that currently there is only one emif Element
+ # but this code will handle more than one emif node
+ # In the future, multiple emif nodes may need additional code
+ # to combine settings from the multiple emif Elements
+ for emifNode in emifNodeList:
+ # Currently, there are only 3 children of the emif Element:
+ # sequencer, controller, and pll
+ # but this is left open-ended for future additions to the
+ # specification for the emif.xml
+ childNode = xmlgrok.firstElementChild(emifNode)
+ while childNode != None:
+
+ if childNode.nodeName == 'controller':
+ self.handleEMIFControllerNode(childNode)
+ elif childNode.nodeName == 'sequencer':
+ self.handleEMIFSequencerNode(childNode)
+ elif childNode.nodeName == 'pll':
+ self.handleEMIFPllNode(childNode)
+
+ childNode = xmlgrok.nextElementSibling(childNode)
+
+ data_rate_ratio = 2
+ dwidth_ratio = self.afi_rate_ratio * data_rate_ratio
+ if dwidth_ratio == 0:
+ derivedClkRdToWr = 0
+ else:
+ derivedClkRdToWr = (self.mem_if_rd_to_wr_turnaround_oct / (dwidth_ratio / 2))
+
+ if (self.mem_if_rd_to_wr_turnaround_oct % (dwidth_ratio / 2)) > 0:
+ derivedClkRdToWr += 1
+
+ self.updateTemplate("DERIVED_CLK_RD_TO_WR", str(int(derivedClkRdToWr)))
+
+ # MPFE information are stored in hps.xml despite we generate
+ # them into sdram_config, so let's load hps.xml
+ hpsNodeList = self.hpsDom.getElementsByTagName('hps')
+
+ for hpsNode in hpsNodeList:
+
+ childNode = xmlgrok.firstElementChild(hpsNode)
+
+ while childNode != None:
+ # MPFE info is part of fpga_interfaces
+ if childNode.nodeName == 'fpga_interfaces':
+ self.handleHpsFpgaInterfaces(childNode)
+
+ childNode = xmlgrok.nextElementSibling(childNode)
+
+ self.sequencerDefinesStream = streamer.Streamer(self.outputDir + os.sep + EMIFGrokker.SDRAM_CONFIG_H_FILENAME, 'w')
+ self.sequencerDefinesStream.open()
+ self.sequencerDefinesStream.writeLicenseHeader()
+ self.sequencerDefinesStream.write(EMIFGrokker.SDRAM_FILE_HEADER)
+ ret = self.sequencerDefinesStream.writeSentinelStart(EMIFGrokker.SDRAM_SENTINEL)
+ if ret == -1:
+ print("Empty header written. Exiting.")
+ self.sequencerDefinesStream.write("/* SDRAM configuration */\n")
+ self.sequencerDefinesStream.write(self.sdramHTemplate)
+ self.openSeqFiles()
+ self.processSeqAuto()
+
+ self.sequencerDefinesStream.write("\n")
+ self.sequencerDefinesStream.write("/* Sequencer auto configuration */\n")
+ self.sequencerDefinesStream.write(self.seqAutoTemplate)
+ self.sequencerDefinesStream.write("\n")
+ self.sequencerDefinesStream.write("/* Sequencer defines configuration */\n")
+ self.sequencerDefinesStream.write(self.seqDefinesTemplate)
+ self.sequencerDefinesStream.write("\n")
+ self.sequencerDefinesStream.write("/* Sequencer ac_rom_init configuration */\n")
+ self.sequencerDefinesStream.write(self.seqAutoAcTemplate)
+ self.sequencerDefinesStream.write("\n\n")
+ self.sequencerDefinesStream.write("/* Sequencer inst_rom_init configuration */\n")
+ self.sequencerDefinesStream.write(self.seqAutoInstTemplate)
+ self.sequencerDefinesStream.write("\n")
+
+ ret = self.sequencerDefinesStream.writeSentinelEnd(EMIFGrokker.SDRAM_SENTINEL)
+ if ret == -1:
+ print("Empty header written. Exiting.")
+ self.sequencerDefinesStream.close()
+ self.closeSeqFiles()
diff --git a/tools/cv_bsp_generator/hps.py b/tools/cv_bsp_generator/hps.py
new file mode 100755
index 00000000000..d702c5b4891
--- /dev/null
+++ b/tools/cv_bsp_generator/hps.py
@@ -0,0 +1,571 @@
+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+"""
+Pinmux header file generator
+
+Process the hps.xml from Quartus and convert them to headers
+usable by U-Boot.
+
+Copyright (C) 2022 Intel Corporation <www.intel.com>
+
+Author: Lee, Kah Jing <[email protected]>
+"""
+import os
+import re
+import streamer
+import xmlgrok
+import xml.dom.minidom
+import collections
+import io
+from io import StringIO
+
+class CompatStringIO(io.StringIO):
+ def write(self, s):
+ if hasattr(s, 'decode'):
+ # Use unicode for python2 to keep compatible
+ return int(super(CompatStringIO, self).write(s.decode('utf-8')))
+ else:
+ return super(CompatStringIO, self).write(s)
+ def getvalue(self):
+ return str(super(CompatStringIO, self).getvalue())
+
+class HPSGrokker(object):
+
+ SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
+ TEMPLATE_DIR = os.path.dirname(SCRIPT_DIR) + '/src'
+
+ MAKEFILE_FILENAME = "Makefile"
+ makefileTemplate = ""
+ RESET_CONFIG_H_FILENAME = "reset_config.h"
+ resetConfigHTemplate = ""
+
+ # If no device family is specified, assume Cyclone V.
+ derivedDeviceFamily = "cyclone5"
+
+ # Assume FPGA DMA 0-7 are not in use by default
+ # Note: there appears to be a weird mismatch between sopcinfo
+ # value vs hps.xml value of DMA_Enable of string_list hw.tcl
+ # type, where sopcinfo uses comma as separator e.g.
+ # "No,No,No,..." while hps.xml uses space as separator.
+ dmaEnable = "No No No No No No No No"
+
+ def __init__(self, inputDir, outputDir, hpsFileName='hps.xml'):
+ """ HPSGrokker initialization """
+ self.inputDir = inputDir
+ self.outputDir = outputDir
+ self.hpsInFileName = inputDir + os.sep + hpsFileName
+ self.dom = xml.dom.minidom.parse(self.hpsInFileName)
+ self.peripheralStream = None
+ self.pinmuxConfigBuffer = None
+ self.pinmuxHeaderBuffer = None
+ self.pinmuxHeaderFile = None
+ self.pinmuxArraySize = 0
+ self.config_hps_ = "CFG_HPS_"
+ self.clockStream = None
+ self.pinmux_regs = self.get_default_pinmux_regs()
+ self.pinmux_configs = self.get_default_pinmux_configs()
+ self.pinmux_config_h = None
+
+ self.createFilesFromHPS()
+
+ def get_default_pinmux_regs(self):
+ """ Set default pinmux values """
+ p = collections.OrderedDict()
+
+ p['EMACIO0'] = 0
+ p['EMACIO1'] = 0
+ p['EMACIO2'] = 0
+ p['EMACIO3'] = 0
+ p['EMACIO4'] = 0
+ p['EMACIO5'] = 0
+ p['EMACIO6'] = 0
+ p['EMACIO7'] = 0
+ p['EMACIO8'] = 0
+ p['EMACIO9'] = 0
+ p['EMACIO10'] = 0
+ p['EMACIO11'] = 0
+ p['EMACIO12'] = 0
+ p['EMACIO13'] = 0
+ p['EMACIO14'] = 0
+ p['EMACIO15'] = 0
+ p['EMACIO16'] = 0
+ p['EMACIO17'] = 0
+ p['EMACIO18'] = 0
+ p['EMACIO19'] = 0
+ p['FLASHIO0'] = 0
+ p['FLASHIO1'] = 0
+ p['FLASHIO2'] = 0
+ p['FLASHIO3'] = 0
+ p['FLASHIO4'] = 0
+ p['FLASHIO5'] = 0
+ p['FLASHIO6'] = 0
+ p['FLASHIO7'] = 0
+ p['FLASHIO8'] = 0
+ p['FLASHIO9'] = 0
+ p['FLASHIO10'] = 0
+ p['FLASHIO11'] = 0
+ p['GENERALIO0'] = 0
+ p['GENERALIO1'] = 0
+ p['GENERALIO2'] = 0
+ p['GENERALIO3'] = 0
+ p['GENERALIO4'] = 0
+ p['GENERALIO5'] = 0
+ p['GENERALIO6'] = 0
+ p['GENERALIO7'] = 0
+ p['GENERALIO8'] = 0
+ p['GENERALIO9'] = 0
+ p['GENERALIO10'] = 0
+ p['GENERALIO11'] = 0
+ p['GENERALIO12'] = 0
+ p['GENERALIO13'] = 0
+ p['GENERALIO14'] = 0
+ p['GENERALIO15'] = 0
+ p['GENERALIO16'] = 0
+ p['GENERALIO17'] = 0
+ p['GENERALIO18'] = 0
+ p['GENERALIO19'] = 0
+ p['GENERALIO20'] = 0
+ p['GENERALIO21'] = 0
+ p['GENERALIO22'] = 0
+ p['GENERALIO23'] = 0
+ p['GENERALIO24'] = 0
+ p['GENERALIO25'] = 0
+ p['GENERALIO26'] = 0
+ p['GENERALIO27'] = 0
+ p['GENERALIO28'] = 0
+ p['GENERALIO29'] = 0
+ p['GENERALIO30'] = 0
+ p['GENERALIO31'] = 0
+ p['MIXED1IO0'] = 0
+ p['MIXED1IO1'] = 0
+ p['MIXED1IO2'] = 0
+ p['MIXED1IO3'] = 0
+ p['MIXED1IO4'] = 0
+ p['MIXED1IO5'] = 0
+ p['MIXED1IO6'] = 0
+ p['MIXED1IO7'] = 0
+ p['MIXED1IO8'] = 0
+ p['MIXED1IO9'] = 0
+ p['MIXED1IO10'] = 0
+ p['MIXED1IO11'] = 0
+ p['MIXED1IO12'] = 0
+ p['MIXED1IO13'] = 0
+ p['MIXED1IO14'] = 0
+ p['MIXED1IO15'] = 0
+ p['MIXED1IO16'] = 0
+ p['MIXED1IO17'] = 0
+ p['MIXED1IO18'] = 0
+ p['MIXED1IO19'] = 0
+ p['MIXED1IO20'] = 0
+ p['MIXED1IO21'] = 0
+ p['MIXED2IO0'] = 0
+ p['MIXED2IO1'] = 0
+ p['MIXED2IO2'] = 0
+ p['MIXED2IO3'] = 0
+ p['MIXED2IO4'] = 0
+ p['MIXED2IO5'] = 0
+ p['MIXED2IO6'] = 0
+ p['MIXED2IO7'] = 0
+ p['GPLINMUX48'] = 0
+ p['GPLINMUX49'] = 0
+ p['GPLINMUX50'] = 0
+ p['GPLINMUX51'] = 0
+ p['GPLINMUX52'] = 0
+ p['GPLINMUX53'] = 0
+ p['GPLINMUX54'] = 0
+ p['GPLINMUX55'] = 0
+ p['GPLINMUX56'] = 0
+ p['GPLINMUX57'] = 0
+ p['GPLINMUX58'] = 0
+ p['GPLINMUX59'] = 0
+ p['GPLINMUX60'] = 0
+ p['GPLINMUX61'] = 0
+ p['GPLINMUX62'] = 0
+ p['GPLINMUX63'] = 0
+ p['GPLINMUX64'] = 0
+ p['GPLINMUX65'] = 0
+ p['GPLINMUX66'] = 0
+ p['GPLINMUX67'] = 0
+ p['GPLINMUX68'] = 0
+ p['GPLINMUX69'] = 0
+ p['GPLINMUX70'] = 0
+ p['GPLMUX0'] = 1
+ p['GPLMUX1'] = 1
+ p['GPLMUX2'] = 1
+ p['GPLMUX3'] = 1
+ p['GPLMUX4'] = 1
+ p['GPLMUX5'] = 1
+ p['GPLMUX6'] = 1
+ p['GPLMUX7'] = 1
+ p['GPLMUX8'] = 1
+ p['GPLMUX9'] = 1
+ p['GPLMUX10'] = 1
+ p['GPLMUX11'] = 1
+ p['GPLMUX12'] = 1
+ p['GPLMUX13'] = 1
+ p['GPLMUX14'] = 1
+ p['GPLMUX15'] = 1
+ p['GPLMUX16'] = 1
+ p['GPLMUX17'] = 1
+ p['GPLMUX18'] = 1
+ p['GPLMUX19'] = 1
+ p['GPLMUX20'] = 1
+ p['GPLMUX21'] = 1
+ p['GPLMUX22'] = 1
+ p['GPLMUX23'] = 1
+ p['GPLMUX24'] = 1
+ p['GPLMUX25'] = 1
+ p['GPLMUX26'] = 1
+ p['GPLMUX27'] = 1
+ p['GPLMUX28'] = 1
+ p['GPLMUX29'] = 1
+ p['GPLMUX30'] = 1
+ p['GPLMUX31'] = 1
+ p['GPLMUX32'] = 1
+ p['GPLMUX33'] = 1
+ p['GPLMUX34'] = 1
+ p['GPLMUX35'] = 1
+ p['GPLMUX36'] = 1
+ p['GPLMUX37'] = 1
+ p['GPLMUX38'] = 1
+ p['GPLMUX39'] = 1
+ p['GPLMUX40'] = 1
+ p['GPLMUX41'] = 1
+ p['GPLMUX42'] = 1
+ p['GPLMUX43'] = 1
+ p['GPLMUX44'] = 1
+ p['GPLMUX45'] = 1
+ p['GPLMUX46'] = 1
+ p['GPLMUX47'] = 1
+ p['GPLMUX48'] = 1
+ p['GPLMUX49'] = 1
+ p['GPLMUX50'] = 1
+ p['GPLMUX51'] = 1
+ p['GPLMUX52'] = 1
+ p['GPLMUX53'] = 1
+ p['GPLMUX54'] = 1
+ p['GPLMUX55'] = 1
+ p['GPLMUX56'] = 1
+ p['GPLMUX57'] = 1
+ p['GPLMUX58'] = 1
+ p['GPLMUX59'] = 1
+ p['GPLMUX60'] = 1
+ p['GPLMUX61'] = 1
+ p['GPLMUX62'] = 1
+ p['GPLMUX63'] = 1
+ p['GPLMUX64'] = 1
+ p['GPLMUX65'] = 1
+ p['GPLMUX66'] = 1
+ p['GPLMUX67'] = 1
+ p['GPLMUX68'] = 1
+ p['GPLMUX69'] = 1
+ p['GPLMUX70'] = 1
+ p['NANDUSEFPGA'] = 0
+ p['UART0USEFPGA'] = 0
+ p['RGMII1USEFPGA'] = 0
+ p['SPIS0USEFPGA'] = 0
+ p['CAN0USEFPGA'] = 0
+ p['I2C0USEFPGA'] = 0
+ p['SDMMCUSEFPGA'] = 0
+ p['QSPIUSEFPGA'] = 0
+ p['SPIS1USEFPGA'] = 0
+ p['RGMII0USEFPGA'] = 0
+ p['UART1USEFPGA'] = 0
+ p['CAN1USEFPGA'] = 0
+ p['USB1USEFPGA'] = 0
+ p['I2C3USEFPGA'] = 0
+ p['I2C2USEFPGA'] = 0
+ p['I2C1USEFPGA'] = 0
+ p['SPIM1USEFPGA'] = 0
+ p['USB0USEFPGA'] = 0
+ p['SPIM0USEFPGA'] = 0
+
+ return p
+
+
+ def get_default_pinmux_configs(self):
+ """ Get default pinmux values """
+ p = collections.OrderedDict()
+
+ p['rgmii0'] = { 'name': 'CFG_HPS_EMAC0', 'used': 0 }
+ p['rgmii1'] = { 'name': 'CFG_HPS_EMAC1', 'used': 0 }
+ p['usb0'] = { 'name': 'CFG_HPS_USB0', 'used': 0 }
+ p['usb1'] = { 'name': 'CFG_HPS_USB1', 'used': 0 }
+ p['nand'] = { 'name': 'CFG_HPS_NAND', 'used': 0 }
+ p['sdmmc'] = { 'name': 'CFG_HPS_SDMMC', 'used': 0 }
+ p['CFG_HPS_SDMMC_BUSWIDTH'] = { 'name': 'CFG_HPS_SDMMC_BUSWIDTH', 'used': 0 }
+ p['qspi'] = { 'name': 'CFG_HPS_QSPI', 'used': 0 }
+ p['CFG_HPS_QSPI_CS3'] = { 'name': 'CFG_HPS_QSPI_CS3', 'used': 0 }
+ p['CFG_HPS_QSPI_CS2'] = { 'name': 'CFG_HPS_QSPI_CS2', 'used': 0 }
+ p['CFG_HPS_QSPI_CS1'] = { 'name': 'CFG_HPS_QSPI_CS1', 'used': 0 }
+ p['CFG_HPS_QSPI_CS0'] = { 'name': 'CFG_HPS_QSPI_CS0', 'used': 0 }
+ p['uart0'] = { 'name': 'CFG_HPS_UART0', 'used': 0 }
+ p['CFG_HPS_UART0_TX'] = { 'name': 'CFG_HPS_UART0_TX', 'used': 0 }
+ p['CFG_HPS_UART0_CTS'] = { 'name': 'CFG_HPS_UART0_CTS', 'used': 0 }
+ p['CFG_HPS_UART0_RTS'] = { 'name': 'CFG_HPS_UART0_RTS', 'used': 0 }
+ p['CFG_HPS_UART0_RX'] = { 'name': 'CFG_HPS_UART0_RX', 'used': 0 }
+ p['uart1'] = { 'name': 'CFG_HPS_UART1', 'used': 0 }
+ p['CFG_HPS_UART1_TX'] = { 'name': 'CFG_HPS_UART1_TX', 'used': 0 }
+ p['CFG_HPS_UART1_CTS'] = { 'name': 'CFG_HPS_UART1_CTS', 'used': 0 }
+ p['CFG_HPS_UART1_RTS'] = { 'name': 'CFG_HPS_UART1_RTS', 'used': 0 }
+ p['CFG_HPS_UART1_RX'] = { 'name': 'CFG_HPS_UART1_RX', 'used': 0 }
+ p['trace'] = { 'name': 'CFG_HPS_TRACE', 'used': 0 }
+ p['i2c0'] = { 'name': 'CFG_HPS_I2C0', 'used': 0 }
+ p['i2c1'] = { 'name': 'CFG_HPS_I2C1', 'used': 0 }
+ p['i2c2'] = { 'name': 'CFG_HPS_I2C2', 'used': 0 }
+ p['i2c3'] = { 'name': 'CFG_HPS_I2C3', 'used': 0 }
+ p['spim0'] = { 'name': 'CFG_HPS_SPIM0', 'used': 0 }
+ p['spim1'] = { 'name': 'CFG_HPS_SPIM1', 'used': 0 }
+ p['spis0'] = { 'name': 'CFG_HPS_SPIS0', 'used': 0 }
+ p['spis1'] = { 'name': 'CFG_HPS_SPIS1', 'used': 0 }
+ p['can0'] = { 'name': 'CFG_HPS_CAN0', 'used': 0 }
+ p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 }
+
+ p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 }
+ p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 }
+ p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 }
+ p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 }
+
+ return p
+
+ def updateTemplate(self, name, value):
+ """ Update Makefile & reset_config.h """
+ pattern = "${" + name + "}"
+ self.makefileTemplate = self.makefileTemplate.replace(pattern, value)
+ self.resetConfigHTemplate = self.resetConfigHTemplate.replace(pattern, value)
+
+ def romanToInteger(self, roman):
+ """
+ Convert roman numerals to integer
+ Since we only support I,V,X, the
+ supported range is 1-39
+ """
+ table = { 'I':1 , 'V':5, 'X':10 }
+
+ literals = list(roman)
+
+ value = 0
+ i = 0
+
+ while(i < (len(literals) - 1)):
+ current = table[literals[i]]
+ next = table[literals[i + 1]]
+ if (current < next):
+ value += (next - current)
+ i += 2
+ else:
+ value += current
+ i += 1
+
+ if (i < (len(literals))):
+ value += table[literals[i]]
+
+ return value
+
+ def getDeviceFamily(self):
+ """ Get device family """
+ return self.derivedDeviceFamily
+
+ def getDeviceFamilyName(self, deviceFamily):
+ """ Get device family name """
+ p = re.compile('^(\w+)\s+(\w+)$')
+ m = p.match(deviceFamily)
+ return m.group(1).lower() + str(self.romanToInteger(m.group(2)))
+
+ def handleHPSSystemNode(self, systemNode):
+ """ handleHPSPeripheralsNode(peripheralsNode)
+ peripheralsNode is a peripherals element node in hps.xml
+ peripheralsNode is a list of peripheralNodes
+ """
+ configNode = xmlgrok.firstElementChild(systemNode)
+ while configNode != None:
+
+ name = configNode.getAttribute('name')
+ value = configNode.getAttribute('value')
+
+ self.updateTemplate(name, value)
+
+ if name == "DEVICE_FAMILY":
+ self.derivedDeviceFamily = self.getDeviceFamilyName(value)
+
+ if name == "DMA_Enable":
+ self.dmaEnable = value
+
+ configNode = xmlgrok.nextElementSibling(configNode)
+
+ def handleHPSPeripheralNode(self, peripheralNode):
+ """ This node of the hps.xml may contain a name, value pair
+ We need to:
+ emit a #define for the peripheral for is 'used' state
+ emit a #define for that pair, if it is marked 'used'
+ """
+ peripheralNode = xmlgrok.firstElementChild(peripheralNode)
+
+ while peripheralNode != None:
+ if peripheralNode.hasAttribute('name') and peripheralNode.hasAttribute('used'):
+ newLine = "\n"
+ name = peripheralNode.getAttribute('name')
+ used = peripheralNode.getAttribute('used')
+
+ if used == 'true' or used == True:
+ used = 1
+ elif used == 'false' or used == False:
+ used = 0
+
+ configs = collections.OrderedDict()
+
+ configNode = xmlgrok.firstElementChild(peripheralNode)
+ while configNode != None:
+ config_define_name = configNode.getAttribute('name')
+ config_define_value = configNode.getAttribute('value')
+ configs[config_define_name] = config_define_value
+ configNode = xmlgrok.nextElementSibling(configNode)
+ if configNode == None:
+ newLine += newLine
+ self.pinmuxConfigBuffer.write("#define " + str(config_define_name) + ' ' + '(' + str(config_define_value) + ')' + newLine)
+
+ entry = self.pinmux_configs[name]
+ define_name = entry['name']
+
+ if (len(configs) > 0):
+ self.pinmux_configs[name] = { 'name': define_name, 'used': used, 'configs': configs }
+ else:
+ self.pinmux_configs[name] = { 'name': define_name, 'used': used }
+
+ # skip the parent peripheral node
+ # since only need to define child config node(s)
+ peripheralNode = xmlgrok.nextElementSibling(peripheralNode)
+
+ def handleHPSPinmuxNode(self, pinmuxNode):
+ """ For a pinmuxNode, we may emit a #define for the name, value pair
+ """
+ if pinmuxNode.hasAttribute('name') and pinmuxNode.hasAttribute('value'):
+ self.pinmuxArraySize += 1
+ name = pinmuxNode.getAttribute('name')
+ value = pinmuxNode.getAttribute('value')
+
+ def handleHPSPinmuxesNode(self, pinmuxesNode):
+ """ PinmuxesNode is a list of pinmuxNodes
+ """
+ self.pinmuxHeaderBuffer.write(str("const u8 sys_mgr_init_table[] = {\n"))
+
+ pinmuxNode = xmlgrok.firstElementChild(pinmuxesNode)
+ while pinmuxNode != None:
+ if pinmuxNode.hasAttribute('name') and pinmuxNode.hasAttribute('value'):
+ self.pinmuxArraySize += 1
+ name = pinmuxNode.getAttribute('name')
+ value = pinmuxNode.getAttribute('value')
+ self.pinmux_regs[name] = value
+ pinmuxNode = xmlgrok.nextElementSibling(pinmuxNode)
+
+ reg_count = 0
+ pinmux_regs_count = len(self.pinmux_regs)
+ for reg, value in self.pinmux_regs.items():
+ reg_count += 1
+ if reg_count < pinmux_regs_count:
+ self.pinmuxHeaderBuffer.write(str("\t" + str(value) + ', /* ' + reg + ' */\n' ))
+ else:
+ self.pinmuxHeaderBuffer.write(str("\t" + str(value) + ' /* ' + reg + ' */\n' ))
+
+ # Write the close of the pin MUX array in the header
+ self.pinmuxHeaderBuffer.write(str("};" ))
+
+ def handleHPSClockNode(self, clockNode):
+ """ A clockNode may emit a #define for the name, frequency pair
+ """
+ if clockNode.hasAttribute('name') and clockNode.hasAttribute('frequency'):
+ name = clockNode.getAttribute('name')
+ frequency = clockNode.getAttribute('frequency')
+ self.clockStream.write("#define " + name + ' ' + '(' + frequency + ')' + '\n')
+
+ def handleHPSClocksNode(self, clocksNode):
+ """ A list of clockNodes is call clocksNode
+ """
+ self.clockStream = streamer.Streamer(self.outputDir + os.sep + clocksNode.nodeName + '.h', 'w')
+ self.clockStream.open()
+ clockNode = xmlgrok.firstElementChild(clocksNode)
+ while clockNode != None:
+ self.handleHPSClockNode(clockNode)
+ clockNode = xmlgrok.nextElementSibling(clockNode)
+
+ self.clockStream.close()
+
+ def handleHpsFpgaInterfaces(self, node):
+ """ Update FPGA Interface registers """
+ node = xmlgrok.firstElementChild(node)
+
+ while node != None:
+ name = node.getAttribute('name')
+ used = node.getAttribute('used')
+
+ if used == 'true':
+ reset = 0
+ else:
+ reset = 1
+
+ if name == 'F2H_AXI_SLAVE':
+ self.updateTemplate("DERIVED_RESET_ASSERT_FPGA2HPS", str(reset))
+ elif name == 'H2F_AXI_MASTER':
+ self.updateTemplate("DERIVED_RESET_ASSERT_HPS2FPGA", str(reset))
+ elif name == 'LWH2F_AXI_MASTER':
+ self.updateTemplate("DERIVED_RESET_ASSERT_LWHPS2FPGA", str(reset))
+
+ node = xmlgrok.nextElementSibling(node)
+
+ def createFilesFromHPS(self):
+ """ Parse xml and create pinmux_config.h """
+ # Unfortunately we can't determine the file name before
+ # parsing the XML, so let's build up the source file
+ # content in string buffer
+ self.pinmuxHeaderBuffer = CompatStringIO()
+ self.pinmuxConfigBuffer = CompatStringIO()
+
+ # Get a list of all nodes with the hps element name
+ hpsNodeList = self.dom.getElementsByTagName('hps')
+ if len(hpsNodeList) > 1:
+ print ("*** WARNING:" + "Multiple hps Elements found in %s!" % self.hpsInFileName)
+ # For each of the hps element nodes, go through the child list
+ # Note that currently there is only one hps Element
+ # but this code will handle more than one hps node
+ # In the future, multiple hps nodes may need additional code
+ # to combine settings from the multiple hps Elements
+ for hpsNode in hpsNodeList:
+ # Currently, there are only 3 children of the hps Element:
+ # peripherals, pin_muxes, and clocks
+ # but this is left open-ended for future additions to the
+ # specification for the hps.xml
+ childNode = xmlgrok.firstElementChild(hpsNode)
+ while childNode != None:
+ if childNode.nodeName == 'pin_muxes':
+ self.handleHPSPinmuxesNode(childNode)
+ elif childNode.nodeName == 'system':
+ self.handleHPSSystemNode(childNode)
+ elif childNode.nodeName == 'fpga_interfaces':
+ self.handleHpsFpgaInterfaces(childNode)
+ elif childNode.nodeName == 'peripherals':
+ self.handleHPSPeripheralNode(childNode)
+ else:
+ print ("***Error:Found unexpected HPS child node:%s" % childNode.nodeName)
+ childNode = xmlgrok.nextElementSibling(childNode)
+
+ self.updateTemplate("DERIVED_DEVICE_FAMILY", self.derivedDeviceFamily)
+
+ # Now we write string buffers into files once we know the device family
+ self.pinmux_config_h = 'pinmux_config.h'
+ self.pinmux_config_src = 'pinmux_config_' + self.derivedDeviceFamily + '.c'
+
+ # Create pinmux_config .h
+ headerDefine = "__SOCFPGA_PINMUX_CONFIG_H__"
+ self.pinmuxHeaderFile = streamer.Streamer(self.outputDir + os.sep + self.pinmux_config_h, 'w')
+ self.pinmuxHeaderFile.open()
+ self.pinmuxHeaderFile.writeLicenseHeader()
+ self.pinmuxHeaderFile.write('/*\n * Altera SoCFPGA PinMux configuration\n */\n\n')
+
+ self.pinmuxHeaderFile.write("#ifndef " + headerDefine + "\n")
+ self.pinmuxHeaderFile.write("#define " + headerDefine + "\n\n")
+ self.pinmuxHeaderFile.write(self.pinmuxHeaderBuffer.getvalue())
+ self.pinmuxHeaderFile.write("\n#endif /* " + headerDefine + " */\n")
+ self.pinmuxHeaderFile.close()
+
+ # Free up string buffers
+ self.pinmuxHeaderBuffer.close()
+ self.pinmuxConfigBuffer.close()
diff --git a/tools/cv_bsp_generator/iocsr.py b/tools/cv_bsp_generator/iocsr.py
new file mode 100755
index 00000000000..a6ff5dfd829
--- /dev/null
+++ b/tools/cv_bsp_generator/iocsr.py
@@ -0,0 +1,203 @@
+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+"""
+IOCSR header file generator
+
+Process the hiof file from Quartus and generate iocsr header
+usable by U-Boot.
+
+Copyright (C) 2022 Intel Corporation <www.intel.com>
+
+Author: Lee, Kah Jing <[email protected]>
+"""
+import os
+import struct
+import streamer
+
+class IOCSRGrokker(object):
+ """ Decode the .hiof file and produce some C source code
+ """
+ IOCSR_ROOT_FILENAME = 'iocsr_config'
+ IOCSR_SENTINEL = '__SOCFPGA_IOCSR_CONFIG_H__'
+ IOCSR_FILE_EXTENSION_MAX_LEN = 6
+ PTAG_HPS_IOCSR_INFO = 39
+ PTAG_HPS_IOCSR = 40
+ PTAG_DEVICE_NAME = 2
+ PTAG_TERMINATION = 8
+
+ def __init__(self, deviceFamily, inputDir, outputDir, hiofSrcFileName):
+ """ IOCSRGrokker Initialization """
+ self.deviceFamily = deviceFamily
+ self.inputDir = inputDir
+ self.outputDir = outputDir
+ self.hiofInFileName = hiofSrcFileName
+ self.iocsrFileName = self.IOCSR_ROOT_FILENAME
+ self.headerOut = None
+ self.sourceOut = None
+ self.createFilesFromHIOF()
+
+ @staticmethod
+ def byteArrayToStr(bytes):
+ """ Convert a list of bytes into a string
+ """
+ # We don't like nulls
+ bytes = bytes.replace('\x00', '')
+ s = ''
+ for b in bytes:
+ s += b
+ return s
+
+ @staticmethod
+ def getLengthData(bytes):
+ """
+ @param: bytes is a chunk of bytes that we need to decode
+ There will be a ptag that we may care about.
+ If we care about it, we will get the length of the chunk
+ that the ptag cares about.
+ @rtype: a pair, length of chunk and the chunk itself
+ @return: length of the ptag chunk we care about
+ @return: data chunk that ptag indicates we need to decode
+ """
+ blockSize = len(bytes)
+ i = 0
+ bitlength = 0
+ length = 0
+ data = []
+
+ while i < blockSize:
+ byte = struct.unpack('B', bytes[i:i+1])[0]
+ i += 1
+
+ if byte == 1:
+ bitlength = struct.unpack('I', bytes[i:i+4])[0]
+ i += 4
+ elif byte == 2:
+ length = struct.unpack('I', bytes[i:i+4])[0]
+ i += 4
+
+ elif byte == 5:
+ j = 0
+ while i < blockSize:
+ data.append(struct.unpack('I', bytes[i:i+4])[0])
+ i += 4
+ j += 1
+
+ else:
+ i += 4
+
+ return (bitlength, data)
+
+
+ def verifyRead(self, tagWeRead, tagWeExpected):
+ """ verify the hiof value with tag expected """
+ if tagWeRead != tagWeExpected:
+ print ("***Error: Expected ptag of %02d, but got %02d" % (tagWeExpected, tagWeRead))
+
+ def createFilesFromHIOF(self):
+ """ read the hiof file to create iocsr_config.h """
+ self.hiofStream = streamer.Streamer(self.inputDir + os.sep + self.hiofInFileName, 'rb')
+ self.iocsrHeaderStream = streamer.Streamer(self.outputDir + os.sep + self.iocsrFileName + '.h', 'w')
+ self.hiofStream.open()
+ self.iocsrHeaderStream.open()
+ self.iocsrHeaderStream.writeLicenseHeader()
+ self.iocsrHeaderStream.write('/*\n * Altera SoCFPGA IOCSR configuration\n */\n\n')
+ ret = self.iocsrHeaderStream.writeSentinelStart(IOCSRGrokker.IOCSR_SENTINEL)
+ if ret == -1:
+ print("Empty header written. Exiting.")
+
+ # Read the file extension (typically .hiof)
+ # and the file version
+ self.fileExtension = self.hiofStream.readBytesAsString(IOCSRGrokker.IOCSR_FILE_EXTENSION_MAX_LEN)
+ self.fileVersion = self.hiofStream.readUnsignedInt()
+
+ # Now read the ptags
+ # Device name is first
+ self.programmerTag = self.hiofStream.readUnsignedShort()
+ self.verifyRead(self.programmerTag, self.PTAG_DEVICE_NAME)
+ self.deviceNameLength = self.hiofStream.readUnsignedInt()
+ self.deviceName = self.hiofStream.readBytesAsString(self.deviceNameLength)
+
+ # Basic information of the HIOF files
+ # This is not used by the preloader generator, but we read it and ignore the
+ # contents.
+ programmerTag = self.hiofStream.readUnsignedShort()
+ self.verifyRead(programmerTag, self.PTAG_HPS_IOCSR_INFO)
+ basicHPSIOCSRInfoLength = self.hiofStream.readUnsignedInt()
+ self.hiofStream.read(basicHPSIOCSRInfoLength)
+
+ # Actual content of IOCSR information
+ self.programmerTag1 = self.hiofStream.readUnsignedShort()
+ self.verifyRead(self.programmerTag1, self.PTAG_HPS_IOCSR)
+ self.HPSIOCSRLength1 = self.hiofStream.readUnsignedInt()
+ self.HPSIOCSRBytes1 = self.hiofStream.read(self.HPSIOCSRLength1)
+ self.HPSIOCSRDataLength1, self.HPSIOCSRData1 = IOCSRGrokker.getLengthData(self.HPSIOCSRBytes1)
+
+ # Actual content of IOCSR information
+ self.programmerTag2 = self.hiofStream.readUnsignedShort()
+ self.verifyRead(self.programmerTag2, self.PTAG_HPS_IOCSR)
+ self.HPSIOCSRLength2 = self.hiofStream.readUnsignedInt()
+ self.HPSIOCSRBytes2 = self.hiofStream.read(self.HPSIOCSRLength2)
+ self.HPSIOCSRDataLength2, self.HPSIOCSRData2 = IOCSRGrokker.getLengthData(self.HPSIOCSRBytes2)
+
+ # Actual content of IOCSR information
+ self.programmerTag3 = self.hiofStream.readUnsignedShort()
+ self.verifyRead(self.programmerTag3, self.PTAG_HPS_IOCSR)
+ self.HPSIOCSRLength3 = self.hiofStream.readUnsignedInt()
+ self.HPSIOCSRBytes3 = self.hiofStream.read(self.HPSIOCSRLength3)
+ self.HPSIOCSRDataLength3, self.HPSIOCSRData3 = IOCSRGrokker.getLengthData(self.HPSIOCSRBytes3)
+
+ # Actual content of IOCSR information
+ self.programmerTag4 = self.hiofStream.readUnsignedShort()
+ self.verifyRead(self.programmerTag4, self.PTAG_HPS_IOCSR)
+ self.HPSIOCSRLength4 = self.hiofStream.readUnsignedInt()
+ self.HPSIOCSRBytes4 = self.hiofStream.read(self.HPSIOCSRLength4)
+ self.HPSIOCSRDataLength4, self.HPSIOCSRData4 = IOCSRGrokker.getLengthData(self.HPSIOCSRBytes4)
+
+ # Now we should see the end of the hiof input
+ programmerTag = self.hiofStream.readUnsignedShort()
+ if 8 != programmerTag:
+ print ("I didn't find the end of the .hiof file when I expected to!")
+
+ self.iocsrHeaderStream.write('#define CFG_HPS_IOCSR_SCANCHAIN0_LENGTH\t' +\
+ str(self.HPSIOCSRDataLength1) + '\n')
+ self.iocsrHeaderStream.write('#define CFG_HPS_IOCSR_SCANCHAIN1_LENGTH\t' +\
+ str(self.HPSIOCSRDataLength2) + '\n')
+ self.iocsrHeaderStream.write('#define CFG_HPS_IOCSR_SCANCHAIN2_LENGTH\t' +\
+ str(self.HPSIOCSRDataLength3) + '\n')
+ self.iocsrHeaderStream.write('#define CFG_HPS_IOCSR_SCANCHAIN3_LENGTH\t' +\
+ str(self.HPSIOCSRDataLength4) + '\n')
+
+ self.iocsrHeaderStream.write("\n")
+
+ self.iocsrHeaderStream.write('const unsigned long iocsr_scan_chain0_table[] = {\n')
+ for value in self.HPSIOCSRData1:
+ hv = '0x%08X' % (value)
+ self.iocsrHeaderStream.write('\t' + hv + ',\n')
+ self.iocsrHeaderStream.write('};\n')
+ self.iocsrHeaderStream.write('\n')
+
+ self.iocsrHeaderStream.write('const unsigned long iocsr_scan_chain1_table[] = {\n')
+ for value in self.HPSIOCSRData2:
+ hv = '0x%08X' % (value)
+ self.iocsrHeaderStream.write('\t' + hv + ',\n')
+ self.iocsrHeaderStream.write('};\n')
+ self.iocsrHeaderStream.write('\n')
+
+ self.iocsrHeaderStream.write('const unsigned long iocsr_scan_chain2_table[] = {\n')
+ for value in self.HPSIOCSRData3:
+ hv = '0x%08X' % (value)
+ self.iocsrHeaderStream.write('\t' + hv + ',\n')
+ self.iocsrHeaderStream.write('};\n')
+ self.iocsrHeaderStream.write('\n')
+
+ self.iocsrHeaderStream.write('const unsigned long iocsr_scan_chain3_table[] = {\n')
+ for value in self.HPSIOCSRData4:
+ hv = '0x%08X' % (value)
+ self.iocsrHeaderStream.write('\t' + hv + ',\n')
+ self.iocsrHeaderStream.write('};\n')
+ self.iocsrHeaderStream.write('\n\n')
+
+ ret = self.iocsrHeaderStream.writeSentinelEnd(IOCSRGrokker.IOCSR_SENTINEL)
+ if ret == -1:
+ print("Empty header written. Exiting.")
+
+ self.iocsrHeaderStream.close()
diff --git a/tools/cv_bsp_generator/model.py b/tools/cv_bsp_generator/model.py
new file mode 100755
index 00000000000..c30d6246cc4
--- /dev/null
+++ b/tools/cv_bsp_generator/model.py
@@ -0,0 +1,114 @@
+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+"""
+Data models for XML files required for generating a preloader.
+
+These classes encapsulate the complexities of XML DOM in order to
+make retrieving data from XML files easier and more reliable.
+By shielding data model deserialization from data consumers,
+it'd be easier to switch to other formats such as JSON if required.
+
+There are some assumptions about how these XML files are structured
+such as the hierarchy of elements and ordering of attributes, these
+are relatively safe assumptions for as long as the XML files are
+always generated by HPS megawizard (isw.tcl) and are not hand-edited.
+
+Copyright (C) 2022 Intel Corporation <www.intel.com>
+
+Author: Lee, Kah Jing <[email protected]>
+"""
+import xml.dom.minidom
+
+def getSingletonElementByTagName(parent, tagName):
+ """
+ Find tag by name and ensure that there is exactly one match
+ """
+ nodes = parent.getElementsByTagName(tagName)
+
+ if len(nodes) == 0:
+ raise Exception("Can't find element: " + tagName)
+ elif len(nodes) > 1:
+ raise Exception("Unexpected multiple matches for singleton element: " + tagName)
+ else:
+ return nodes[0]
+
+class hps(object):
+ """
+ Data model for hps.xml
+ """
+ @staticmethod
+ def create(file):
+ """ hps model """
+ return hps(file)
+
+ def __init__(self, file):
+ """ hps model initialization """
+ self.dom = xml.dom.minidom.parse(file)
+
+ try:
+ # Look for <hps> node
+ self.hpsNode = getSingletonElementByTagName(self.dom, "hps")
+ # Look for <hps><system> node
+ self.hpsSystemNode = getSingletonElementByTagName(self.hpsNode, "system")
+ except Exception:
+ raise Exception("Can't initialize from file: " + file)
+
+ def getSystemConfig(self, param):
+ """ parse system configuration tag """
+ hpsSystemConfigNode = None
+
+ # Look for <hps><system><config ...> nodes
+ for node in self.hpsSystemNode.getElementsByTagName("config"):
+ # assume name is the first attribute as in <config name="..." ...>
+ nameAttrNode = node.attributes.item(0)
+ if nameAttrNode.nodeName == "name" and nameAttrNode.nodeValue == param:
+ # assume value is the second attribute as in <config name="..." value="...">
+ valueAttrNode = node.attributes.item(1)
+ if valueAttrNode.nodeName == "value":
+ hpsSystemConfigNode = valueAttrNode
+ break
+
+ if hpsSystemConfigNode == None:
+ raise ValueError("Can't find <hps><system><config> node: " + param)
+
+ return hpsSystemConfigNode.nodeValue
+
+class emif(object):
+ """
+ Data model for emif.xml.
+ """
+ @staticmethod
+ def create(file):
+ """ emif model """
+ return emif(file)
+
+ def __init__(self, file):
+ """ emif model initialization """
+ self.dom = xml.dom.minidom.parse(file)
+
+ try:
+ # Look for <emif> node
+ self.emifNode = getSingletonElementByTagName(self.dom, "emif")
+ # Look for <emif><pll> node
+ self.emifPllNode = getSingletonElementByTagName(self.emifNode, "pll")
+ except Exception:
+ raise Exception("Can't initialize from file: " + file)
+
+ def getPllDefine(self, param):
+ """ parse pll define tag """
+ emifPllDefineNode = None
+
+ # Look for <emif><pll><define ...> nodes
+ for node in self.emifPllNode.getElementsByTagName("define"):
+ nameAttrNode = node.attributes.item(0)
+ # assume name is the first attribute as in <define name="..." ...>
+ if nameAttrNode.nodeName == "name" and nameAttrNode.nodeValue == param:
+ # assume value is the second attribute as in <config name="..." value="...">
+ valueAttrNode = node.attributes.item(1)
+ if valueAttrNode.nodeName == "value":
+ emifPllDefineNode = valueAttrNode
+ break
+
+ if emifPllDefineNode == None:
+ raise Exception("Can't find EMIF PLL define node: " + param)
+
+ return emifPllDefineNode.nodeValue
diff --git a/tools/cv_bsp_generator/renderer.py b/tools/cv_bsp_generator/renderer.py
new file mode 100755
index 00000000000..0ab1e2f2df2
--- /dev/null
+++ b/tools/cv_bsp_generator/renderer.py
@@ -0,0 +1,196 @@
+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+"""
+Document renderer class for preloader source files
+
+Each document renderer takes care of a full construction of
+a specific file format using the required data model.
+
+Copyright (C) 2022 Intel Corporation <www.intel.com>
+
+Author: Lee, Kah Jing <[email protected]>
+"""
+import collections
+import doc
+
+class pll_config_h:
+ """
+ pll_config.h renderer.
+ """
+
+ def __init__(self, hpsModel, emifModel):
+ """ renderer initialization """
+ self.hpsModel = hpsModel
+ self.emifModel = emifModel
+ self.doc = doc.generated_c_source("__SOCFPGA_PLL_CONFIG_H__")
+
+ def createContent(self):
+ """ add the content based on settings parsed. eventually it will be
+ written to pll_config.h file
+ """
+ doc.c_source.line(self.doc)
+ id = "CFG_HPS_DBCTRL_STAYOSC1"
+ valueString = self.hpsModel.getSystemConfig("dbctrl_stayosc1")
+ # Unfortunately hps.xml never tells us the data type of values
+ # attributes. Here we workaround this type of problem, often
+ # this is case-by-case, i.e. having to know which parameter that
+ # we're dealing with, hence this ugly parameter-specific
+ # if-statement needs here to workaround the data type inconsistency
+ if valueString.lower() == "true":
+ value = "1"
+ else:
+ value = "0"
+ doc.c_source.define(self.doc, id, value )
+ doc.c_source.line(self.doc)
+ self.addMainPllSettings()
+ doc.c_source.line(self.doc)
+ self.addPeriphPllSettings()
+ doc.c_source.line(self.doc)
+ self.addSdramPllSettings()
+ doc.c_source.line(self.doc)
+ self.addClockFreq()
+ doc.c_source.line(self.doc)
+ self.addAlteraSettings()
+ doc.c_source.line(self.doc)
+
+ def addMainPllSettings(self):
+ """ add pll settings to the file """
+ paramMap = collections.OrderedDict()
+ paramMap["VCO_DENOM"] = "main_pll_n"
+ paramMap["VCO_NUMER"] = "main_pll_m"
+
+ for key in paramMap.keys():
+ id = "CFG_HPS_MAINPLLGRP_" + key
+ value = self.hpsModel.getSystemConfig(paramMap[key])
+ doc.c_source.define(self.doc, id, value )
+
+ # main_pll_c0, main_pll_c1, main_pll_c2 are fixed counters,
+ doc.c_source.define(self.doc, "CFG_HPS_MAINPLLGRP_MPUCLK_CNT", "0")
+ doc.c_source.define(self.doc, "CFG_HPS_MAINPLLGRP_MAINCLK_CNT", "0")
+ doc.c_source.define(self.doc, "CFG_HPS_MAINPLLGRP_DBGATCLK_CNT", "0")
+
+ paramMap = collections.OrderedDict()
+
+ paramMap["MAINQSPICLK_CNT"] = "main_pll_c3"
+ paramMap["MAINNANDSDMMCCLK_CNT"] = "main_pll_c4"
+ paramMap["CFGS2FUSER0CLK_CNT"] = "main_pll_c5"
+ paramMap["MAINDIV_L3MPCLK"] = "l3_mp_clk_div"
+ paramMap["MAINDIV_L3SPCLK"] = "l3_sp_clk_div"
+ paramMap["MAINDIV_L4MPCLK"] = "l4_mp_clk_div"
+ paramMap["MAINDIV_L4SPCLK"] = "l4_sp_clk_div"
+ paramMap["DBGDIV_DBGATCLK"] = "dbg_at_clk_div"
+ paramMap["DBGDIV_DBGCLK"] = "dbg_clk_div"
+ paramMap["TRACEDIV_TRACECLK"] = "dbg_trace_clk_div"
+ paramMap["L4SRC_L4MP"] = "l4_mp_clk_source"
+ paramMap["L4SRC_L4SP"] = "l4_sp_clk_source"
+
+ for key in paramMap.keys():
+ id = "CFG_HPS_MAINPLLGRP_" + key
+ value = self.hpsModel.getSystemConfig(paramMap[key])
+ doc.c_source.define(self.doc, id, value )
+
+ def addPeriphPllSettings(self):
+ """ add peripheral pll settings to the file """
+ paramMap = collections.OrderedDict()
+ paramMap["VCO_DENOM"] = "periph_pll_n"
+ paramMap["VCO_NUMER"] = "periph_pll_m"
+ paramMap["VCO_PSRC"] = "periph_pll_source"
+ paramMap["EMAC0CLK_CNT"] = "periph_pll_c0"
+ paramMap["EMAC1CLK_CNT"] = "periph_pll_c1"
+ paramMap["PERQSPICLK_CNT"] = "periph_pll_c2"
+ paramMap["PERNANDSDMMCCLK_CNT"] = "periph_pll_c3"
+ paramMap["PERBASECLK_CNT"] = "periph_pll_c4"
+ paramMap["S2FUSER1CLK_CNT"] = "periph_pll_c5"
+ paramMap["DIV_USBCLK"] = "usb_mp_clk_div"
+ paramMap["DIV_SPIMCLK"] = "spi_m_clk_div"
+ paramMap["DIV_CAN0CLK"] = "can0_clk_div"
+ paramMap["DIV_CAN1CLK"] = "can1_clk_div"
+ paramMap["GPIODIV_GPIODBCLK"] = "gpio_db_clk_div"
+ paramMap["SRC_SDMMC"] = "sdmmc_clk_source"
+ paramMap["SRC_NAND"] = "nand_clk_source"
+ paramMap["SRC_QSPI"] = "qspi_clk_source"
+
+ for key in paramMap.keys():
+ id = "CFG_HPS_PERPLLGRP_" + key
+ value = self.hpsModel.getSystemConfig(paramMap[key])
+ doc.c_source.define(self.doc, id, value )
+
+ def addSdramPllSettings(self):
+ """ add sdram pll settings to the file """
+ value = self.emifModel.getPllDefine("PLL_MEM_CLK_DIV")
+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_VCO_DENOM", value )
+ value = self.emifModel.getPllDefine("PLL_MEM_CLK_MULT")
+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_VCO_NUMER", value )
+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_VCO_SSRC", "0")
+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_DDRDQSCLK_CNT", "1")
+ value = self.emifModel.getPllDefine("PLL_MEM_CLK_PHASE_DEG")
+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_DDRDQSCLK_PHASE", value )
+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_DDR2XDQSCLK_CNT", "0")
+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_DDR2XDQSCLK_PHASE", "0")
+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_DDRDQCLK_CNT", "1")
+ value = self.emifModel.getPllDefine("PLL_WRITE_CLK_PHASE_DEG")
+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_DDRDQCLK_PHASE", value )
+
+ try:
+ value = self.hpsModel.getSystemConfig("sdram_pll_c5")
+ except ValueError:
+ value = "5"
+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_S2FUSER2CLK_CNT", value )
+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_S2FUSER2CLK_PHASE", "0")
+
+ def addClockFreq(self):
+ """ add clock frequency settings to the file """
+ paramMap = collections.OrderedDict()
+ paramMap["OSC1"] = "eosc1_clk_hz"
+ paramMap["OSC2"] = "eosc2_clk_hz"
+ paramMap["F2S_SDR_REF"] = "F2SCLK_SDRAMCLK_FREQ"
+ paramMap["F2S_PER_REF"] = "F2SCLK_PERIPHCLK_FREQ"
+ paramMap["MAINVCO"] = "main_pll_vco_hz"
+ paramMap["PERVCO"] = "periph_pll_vco_hz"
+
+ for key in paramMap.keys():
+ id = "CFG_HPS_CLK_" + key + "_HZ"
+ value = self.hpsModel.getSystemConfig(paramMap[key])
+ doc.c_source.define(self.doc, id, value )
+
+ eosc1 = int(self.hpsModel.getSystemConfig("eosc1_clk_hz"))
+ eosc2 = int(self.hpsModel.getSystemConfig("eosc2_clk_hz"))
+ m = int(self.emifModel.getPllDefine("PLL_MEM_CLK_MULT"))
+ n = int(self.emifModel.getPllDefine("PLL_MEM_CLK_DIV"))
+ vco = int(round(eosc1 * (m + 1) / (n + 1)))
+ doc.c_source.define(self.doc, "CFG_HPS_CLK_SDRVCO_HZ", str(vco) )
+
+ paramMap = collections.OrderedDict()
+ paramMap["EMAC0"] = "emac0_clk_hz"
+ paramMap["EMAC1"] = "emac1_clk_hz"
+ paramMap["USBCLK"] = "usb_mp_clk_hz"
+ paramMap["NAND"] = "nand_clk_hz"
+ paramMap["SDMMC"] = "sdmmc_clk_hz"
+ paramMap["QSPI"] = "qspi_clk_hz"
+ paramMap["SPIM"] = "spi_m_clk_hz"
+ paramMap["CAN0"] = "can0_clk_hz"
+ paramMap["CAN1"] = "can1_clk_hz"
+ paramMap["GPIODB"] = "gpio_db_clk_hz"
+ paramMap["L4_MP"] = "l4_mp_clk_hz"
+ paramMap["L4_SP"] = "l4_sp_clk_hz"
+
+ for key in paramMap.keys():
+ id = "CFG_HPS_CLK_" + key + "_HZ"
+ value = self.hpsModel.getSystemConfig(paramMap[key])
+ doc.c_source.define(self.doc, id, value )
+
+ def addAlteraSettings(self):
+ """ add Altera-related settings to the file """
+ paramMap = collections.OrderedDict()
+ paramMap["MPUCLK"] = "main_pll_c0_internal"
+ paramMap["MAINCLK"] = "main_pll_c1_internal"
+ paramMap["DBGATCLK"] = "main_pll_c2_internal"
+
+ for key in paramMap.keys():
+ id = "CFG_HPS_ALTERAGRP_" + key
+ value = self.hpsModel.getSystemConfig(paramMap[key])
+ doc.c_source.define(self.doc, id, value )
+
+ def __str__(self):
+ """ convert to string """
+ self.createContent()
+ return str(self.doc)
diff --git a/tools/cv_bsp_generator/requirements.txt b/tools/cv_bsp_generator/requirements.txt
new file mode 100644
index 00000000000..2ad65d1c331
--- /dev/null
+++ b/tools/cv_bsp_generator/requirements.txt
@@ -0,0 +1,5 @@
+# requirements.txt for cv_bsp_generator.py
+# All dependencies are either standard library modules
+# or local Python files included in this BSP tool.
+# No external pip packages are required.
+
diff --git a/tools/cv_bsp_generator/streamer.py b/tools/cv_bsp_generator/streamer.py
new file mode 100755
index 00000000000..19c30aced6a
--- /dev/null
+++ b/tools/cv_bsp_generator/streamer.py
@@ -0,0 +1,102 @@
+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+"""
+Generate license, file header and close tag.
+
+Copyright (C) 2022 Intel Corporation <www.intel.com>
+
+Author: Lee, Kah Jing <[email protected]>
+"""
+import os
+import struct
+import doc
+
+class Streamer(object):
+ """ Streamer class to generate license, header, and close tag.
+ """
+ def __init__(self, fileName, mode='r'):
+ """ Streamer initialization """
+ self.fileName = fileName
+ self.mode = mode
+ self.file = None
+ self.sentinel = None
+ if '+' in mode or 'w' in mode or 'a' in mode:
+ self.fileMode = 'write'
+ else:
+ self.fileMode = 'read'
+
+ def close(self):
+ """ file close """
+ if self.file != None:
+ self.file.close()
+ self.file = None
+
+ def open(self):
+ """ file open """
+ if self.fileName != None:
+ if self.file == None:
+ if self.fileMode == 'write':
+ print ("Generating file: %s..." % self.fileName)
+ else:
+ print ("Reading file: %s..." % self.fileName)
+ self.file = open(self.fileName, self.mode)
+
+ def read(self, numBytes):
+ """ file read number of bytes """
+ if self.file == None:
+ print ("***Error: Attempted to read from unopened file %s" \
+ % (self.fileName))
+ exit(-1)
+
+ else:
+ return self.file.read(numBytes)
+
+ def readUnsignedInt(self):
+ """ read unsigned integer """
+ return struct.unpack('I', self.read(4))[0]
+
+ def readUnsignedShort(self):
+ """ read unsigned short """
+ return struct.unpack('H', self.read(2))[0]
+
+ def readBytesAsString(self, numBytes):
+ """ Read some bytes from a binary file
+ and interpret the data values as a String
+ """
+ bytes = self.read(numBytes)
+ s = bytes.decode('utf-8')
+
+ return s
+
+ def write(self, str):
+ """ file write """
+ if self.file == None:
+ print ("***Error: Attempted to write to unopened file %s" \
+ % (self.fileName))
+ exit(-1)
+
+ else:
+ self.file.write("%s" % str)
+
+ def writeLicenseHeader(self):
+ """ write license & copyright """
+ # format the license header
+ licenseHeader = "/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */\n"
+ self.file.write("%s" % licenseHeader)
+ copyrightHeader = "/*\n * Copyright (C) 2022 Intel Corporation <www.intel.com>\n *\n */\n"
+ self.file.write("%s" % copyrightHeader)
+
+ def writeSentinelStart(self, sentinel):
+ """ start header """
+ if sentinel == None:
+ return -1
+ self.sentinel = sentinel
+ self.file.write("%s\n%s\n\n" % (\
+ "#ifndef " + self.sentinel,
+ "#define " + self.sentinel))
+
+ def writeSentinelEnd(self, sentinel):
+ """ end header """
+ if sentinel == None:
+ return -1
+ self.sentinel = sentinel
+ self.file.write("\n%s\n" % ("#endif /* " + self.sentinel + " */"))
diff --git a/tools/cv_bsp_generator/xmlgrok.py b/tools/cv_bsp_generator/xmlgrok.py
new file mode 100755
index 00000000000..fae1d745bfd
--- /dev/null
+++ b/tools/cv_bsp_generator/xmlgrok.py
@@ -0,0 +1,32 @@
+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+"""
+XML node parser
+
+Copyright (C) 2022 Intel Corporation <www.intel.com>
+
+Author: Lee, Kah Jing <[email protected]>
+"""
+import xml.dom
+
+def isElementNode(XMLNode):
+ """ check if the node is element node """
+ return XMLNode.nodeType == xml.dom.Node.ELEMENT_NODE
+
+def firstElementChild(XMLNode):
+ """ Calling firstChild on an Node of type Element often (always?)
+ returns a Node of Text type. How annoying! Return the first Element
+ child
+ """
+ child = XMLNode.firstChild
+ while child != None and not isElementNode(child):
+ child = nextElementSibling(child)
+ return child
+
+def nextElementSibling(XMLNode):
+ """ nextElementSibling will return the next sibling of XMLNode that is
+ an Element Node Type
+ """
+ sib = XMLNode.nextSibling
+ while sib != None and not isElementNode(sib):
+ sib = sib.nextSibling
+ return sib
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
index 6eaa1780097..06666339d60 100644
--- a/tools/docker/Dockerfile
+++ b/tools/docker/Dockerfile
@@ -129,6 +129,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
python3-pip \
python3-pyelftools \
python3-sphinx \
+ python3-tk \
python3-tomli \
python3-venv \
rpm2cpio \
diff --git a/tools/logos/u-boot_logo_with_text.svg b/tools/logos/u-boot_logo_with_text.svg
new file mode 100644
index 00000000000..1527e79a3a9
--- /dev/null
+++ b/tools/logos/u-boot_logo_with_text.svg
@@ -0,0 +1,280 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- SPDX-License-Identifier: CC-BY-SA-4.0 -->
+
+<!-- Copyright (c) 2018, Heinrich Schuchardt <[email protected]> -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="186"
+ height="244"
+ viewBox="0 0 186 244"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+ sodipodi:docname="u-boot_logo.svg"
+ inkscape:export-filename="tools/logos/u-boot_logo.png"
+ inkscape:export-xdpi="41.290001"
+ inkscape:export-ydpi="41.290001">
+ <title
+ id="title30">U-Boot Logo</title>
+ <metadata
+ id="metadata31">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>U-Boot Logo</dc:title>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Heinrich Schuchardt &lt;[email protected]&gt;</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:date>May 21st, 2018</dc:date>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs29" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="1051"
+ id="namedview27"
+ showgrid="false"
+ inkscape:zoom="2.1213203"
+ inkscape:cx="40"
+ inkscape:cy="66.333333"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="flowRoot840" />
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,58)">
+ <circle
+ style="fill:#004466;fill-opacity:1;stroke:none;stroke-width:0"
+ id="path835"
+ cx="93"
+ cy="35"
+ r="93" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffcc88;fill-opacity:1;stroke:none;stroke-width:0"
+ d="M 116,18 A 20,20 0 0 1 96,-2 20,20 0 0 1 116,-22 v 11 a 9,9 0 0 0 -9,9 9,9 0 0 0 9,9 z"
+ id="path4136-6-6-1-6-3-5" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffcc88;fill-opacity:1;stroke:none;stroke-width:0"
+ d="m 116,8 a 10,10 0 0 1 -10,-10 10,10 0 0 1 10,-10 v 1 a 9,9 0 0 0 -9,9 9,9 0 0 0 9,9 z"
+ id="path4136-6-6-1-6-3-5-1-9" />
+ <ellipse
+ style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+ id="path4136-6-6-1-6-3-5-1-2"
+ cx="116"
+ cy="-16.5"
+ rx="4"
+ ry="5.5" />
+ <circle
+ style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+ id="path4352"
+ cx="86"
+ cy="8"
+ r="10" />
+ <circle
+ style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+ id="path4352-1"
+ cx="126"
+ cy="8"
+ r="10" />
+ <rect
+ style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+ id="rect4399"
+ width="39"
+ height="20"
+ x="86.5"
+ y="-2" />
+ <rect
+ style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+ id="rect4660"
+ width="60"
+ height="9.5"
+ x="76"
+ y="8.5" />
+ <circle
+ style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+ id="path4549-5"
+ cx="36"
+ cy="23"
+ r="15" />
+ <circle
+ style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+ id="path4549-5-5"
+ cx="36"
+ cy="63"
+ r="15" />
+ <ellipse
+ style="fill:#ffcc88;fill-opacity:1;stroke:#000000;stroke-width:0"
+ id="path4136-6-6"
+ cx="15"
+ cy="33"
+ rx="4"
+ ry="10" />
+ <ellipse
+ style="fill:#ffcc88;fill-opacity:1;stroke:#000000;stroke-width:0"
+ id="path4136-6-6-1"
+ cx="15"
+ cy="53"
+ rx="4"
+ ry="10" />
+ <rect
+ style="fill:#dd9955;fill-opacity:1;stroke:#000000;stroke-width:0"
+ id="rect4213"
+ width="65"
+ height="4"
+ x="11"
+ y="41" />
+ <ellipse
+ style="fill:#ffcc88;fill-opacity:1;stroke:#000000;stroke-width:0"
+ id="path4136"
+ cx="100.5"
+ cy="42.5"
+ rx="74.5"
+ ry="34.5" />
+ <ellipse
+ style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+ id="path4416"
+ cx="70"
+ cy="37.5"
+ rx="15"
+ ry="12.5" />
+ <ellipse
+ style="fill:#ffcc88;fill-opacity:1;stroke:none;stroke-width:0"
+ id="path4416-9"
+ cx="70"
+ cy="37.5"
+ rx="14"
+ ry="11.5" />
+ <ellipse
+ style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+ id="path4416-0"
+ cx="70"
+ cy="37.5"
+ rx="11"
+ ry="8.5" />
+ <ellipse
+ style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+ id="path4416-94"
+ cx="110"
+ cy="37.5"
+ rx="15"
+ ry="12.5" />
+ <ellipse
+ style="fill:#ffcc88;fill-opacity:1;stroke:none;stroke-width:0"
+ id="path4416-9-1"
+ cx="110"
+ cy="37.5"
+ rx="14"
+ ry="11.5" />
+ <ellipse
+ style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+ id="path4416-0-1"
+ cx="110"
+ cy="37.5"
+ rx="11"
+ ry="8.5" />
+ <ellipse
+ style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+ id="path4416-94-2"
+ cx="150"
+ cy="37.5"
+ rx="15"
+ ry="12.5" />
+ <ellipse
+ style="fill:#ffcc88;fill-opacity:1;stroke:none;stroke-width:0"
+ id="path4416-9-1-2"
+ cx="150"
+ cy="37.5"
+ rx="14"
+ ry="11.5" />
+ <ellipse
+ style="fill:#dd9955;fill-opacity:1;stroke:none;stroke-width:0"
+ id="path4416-0-1-9"
+ cx="150"
+ cy="37.5"
+ rx="11"
+ ry="8.5" />
+ <g
+ aria-label="U-Boot"
+ transform="matrix(1.4316296,0,0,1.4316493,154.42725,-33.934324)"
+ style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#004466;fill-opacity:1;stroke:none"
+ id="flowRoot840">
+ <g
+ id="g3123">
+ <path
+ style="stroke-width:0.99455768"
+ id="path1717"
+ d="m -107.86816,123.89647 h 3.9218 v 17.71485 q 0,4.6875 1.68078,6.75781 1.68077,2.05078 5.44802,2.05078 3.747933,0 5.428707,-2.05078 1.680773,-2.07031 1.680773,-6.75781 v -17.71485 h 3.921806 v 18.20313 q 0,5.70312 -2.80129,8.61328 -2.78197,2.91016 -8.229996,2.91016 -5.46734,0 -8.26863,-2.91016 -2.78197,-2.91016 -2.78197,-8.61328 z"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path1719"
+ style="fill:#dd9955;fill-opacity:1;stroke-width:0.99455768"
+ d="m -80.415526,140.49804 h 10.413069 v 3.20312 h -10.413069 z"
+ inkscape:connector-curvature="0" />
+ <path
+ style="stroke-width:0.99455768"
+ id="path1721"
+ d="m -60.28488,139.13085 v 10.68359 h 6.259433 q 3.149036,0 4.655936,-1.30859 1.526221,-1.32813 1.526221,-4.04297 0,-2.73437 -1.526221,-4.02344 -1.5069,-1.30859 -4.655936,-1.30859 z m 0,-11.99219 v 8.78906 h 5.776453 q 2.859247,0 4.250232,-1.07421 1.410304,-1.09375 1.410304,-3.32032 0,-2.20703 -1.410304,-3.30078 -1.390985,-1.09375 -4.250232,-1.09375 z m -3.902486,-3.24219 h 9.968727 q 4.462744,0 6.877649,1.875 2.414905,1.875 2.414905,5.33204 0,2.67578 -1.236432,4.25781 -1.236431,1.58203 -3.632016,1.97265 2.878566,0.625 4.462744,2.61719 1.603496,1.97266 1.603496,4.94141 0,3.90625 -2.627416,6.03515 -2.627417,2.12891 -7.476545,2.12891 h -10.355112 z"
+ inkscape:connector-curvature="0" />
+ <path
+ style="stroke-width:0.99455768"
+ id="path1723"
+ d="m -28.813841,133.70116 q -2.859247,0 -4.520701,2.26563 -1.661455,2.24609 -1.661455,6.17187 0,3.92578 1.642136,6.19141 1.661454,2.24609 4.54002,2.24609 2.839928,0 4.501383,-2.26562 1.661454,-2.26563 1.661454,-6.17188 0,-3.88672 -1.661454,-6.15234 -1.661455,-2.28516 -4.501383,-2.28516 z m 0,-3.04687 q 4.636617,0 7.283354,3.04687 2.646735,3.04688 2.646735,8.4375 0,5.3711 -2.646735,8.4375 -2.646737,3.04688 -7.283354,3.04688 -4.655936,0 -7.302672,-3.04688 -2.627416,-3.0664 -2.627416,-8.4375 0,-5.39062 2.627416,-8.4375 2.646736,-3.04687 7.302672,-3.04687 z"
+ inkscape:connector-curvature="0" />
+ <path
+ style="stroke-width:0.99455768"
+ id="path1725"
+ d="m -4.6068351,133.70116 q -2.8592473,0 -4.5207018,2.26563 -1.6614541,2.24609 -1.6614541,6.17187 0,3.92578 1.6421348,6.19141 1.6614545,2.24609 4.5400211,2.24609 2.839928,0 4.50138246,-2.26562 1.66145444,-2.26563 1.66145444,-6.17188 0,-3.88672 -1.66145444,-6.15234 -1.66145446,-2.28516 -4.50138246,-2.28516 z m 0,-3.04687 q 4.63661713,0 7.2833528,3.04687 2.6467357,3.04688 2.6467357,8.4375 0,5.3711 -2.6467357,8.4375 -2.64673567,3.04688 -7.2833528,3.04688 -4.6559365,0 -7.3026719,-3.04688 -2.627417,-3.0664 -2.627417,-8.4375 0,-5.39062 2.627417,-8.4375 2.6467354,-3.04687 7.3026719,-3.04687 z"
+ inkscape:connector-curvature="0" />
+ <path
+ style="stroke-width:0.99455768"
+ id="path1727"
+ d="m 14.731723,124.97069 v 6.21094 h 7.321991 v 2.79297 h -7.321991 v 11.875 q 0,2.67578 0.714811,3.4375 0.734132,0.76172 2.955843,0.76172 h 3.651337 v 3.00781 h -3.651337 q -4.114997,0 -5.679855,-1.54297 -1.564858,-1.5625 -1.564858,-5.66406 v -11.875 H 8.5495661 v -2.79297 h 2.6080979 v -6.21094 z"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+</svg>