summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml20
-rw-r--r--.mailmap1
-rw-r--r--Kconfig2
-rw-r--r--MAINTAINERS5
-rw-r--r--Makefile872
-rw-r--r--arch/Kconfig1
-rw-r--r--arch/arm/Kconfig14
-rw-r--r--arch/arm/cpu/armv8/fel_utils.S2
-rw-r--r--arch/arm/dts/imx8ulp-evk-u-boot.dtsi1
-rw-r--r--arch/arm/dts/imxrt1020.dtsi1
-rw-r--r--arch/arm/dts/imxrt1170.dtsi1
-rw-r--r--arch/arm/dts/ipq5424-rdp466-u-boot.dtsi37
-rw-r--r--arch/arm/dts/k3-am625-phycore-som-binman.dtsi94
-rw-r--r--arch/arm/dts/qcs615-ride-u-boot.dtsi14
-rw-r--r--arch/arm/dts/qcs8300-ride-u-boot.dtsi19
-rw-r--r--arch/arm/dts/versal-mini-emmc0.dts36
-rw-r--r--arch/arm/dts/versal-mini-emmc1.dts36
-rw-r--r--arch/arm/dts/versal-mini-ospi.dtsi52
-rw-r--r--arch/arm/dts/versal-mini-qspi.dtsi40
-rw-r--r--arch/arm/dts/versal-net-mini-emmc.dts36
-rw-r--r--arch/arm/dts/versal-net-mini-ospi.dtsi56
-rw-r--r--arch/arm/dts/versal-net-mini-qspi.dtsi42
-rw-r--r--arch/arm/dts/versal-net-mini.dts26
-rw-r--r--arch/arm/dts/vf610-pcm052.dtsi4
-rw-r--r--arch/arm/dts/zynqmp-clk-ccf.dtsi2
-rw-r--r--arch/arm/dts/zynqmp-mini-emmc0.dts31
-rw-r--r--arch/arm/dts/zynqmp-mini-emmc1.dts31
-rw-r--r--arch/arm/dts/zynqmp-mini-nand.dts35
-rw-r--r--arch/arm/dts/zynqmp-mini-qspi.dts25
-rw-r--r--arch/arm/include/asm/arch-imxrt/gpio.h9
-rw-r--r--arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h7
-rw-r--r--arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h4
-rw-r--r--arch/arm/include/asm/arch-sunxi/dram.h2
-rw-r--r--arch/arm/include/asm/arch-sunxi/dram_sun50i_a133.h230
-rw-r--r--arch/arm/include/asm/io.h152
-rw-r--r--arch/arm/mach-airoha/an7581/init.c3
-rw-r--r--arch/arm/mach-apple/board.c27
-rw-r--r--arch/arm/mach-k3/am62ax/am62a7_init.c1
-rw-r--r--arch/arm/mach-k3/j722s/j722s_init.c2
-rw-r--r--arch/arm/mach-mediatek/tzcfg.c8
-rw-r--r--arch/arm/mach-rockchip/rk3399/rk3399.c1
-rw-r--r--arch/arm/mach-snapdragon/board.c75
-rw-r--r--arch/arm/mach-snapdragon/capsule_update.c274
-rw-r--r--arch/arm/mach-snapdragon/of_fixup.c13
-rw-r--r--arch/arm/mach-snapdragon/qcom-priv.h14
-rw-r--r--arch/arm/mach-sunxi/Kconfig114
-rw-r--r--arch/arm/mach-sunxi/Makefile2
-rw-r--r--arch/arm/mach-sunxi/board.c4
-rw-r--r--arch/arm/mach-sunxi/clock_sun50i_h6.c3
-rw-r--r--arch/arm/mach-sunxi/cpu_info.c2
-rw-r--r--arch/arm/mach-sunxi/dram_sun50i_a133.c1204
-rw-r--r--arch/arm/mach-sunxi/dram_timings/Makefile2
-rw-r--r--arch/arm/mach-sunxi/dram_timings/a133_ddr4.c80
-rw-r--r--arch/arm/mach-sunxi/dram_timings/a133_lpddr4.c102
-rw-r--r--arch/m68k/Kconfig5
-rw-r--r--arch/m68k/dts/Makefile1
-rw-r--r--arch/m68k/dts/astro_mcf5373l.dts27
-rw-r--r--arch/powerpc/cpu/mpc85xx/mp.c4
-rw-r--r--arch/powerpc/lib/misc.c5
-rw-r--r--arch/riscv/config.mk18
-rw-r--r--arch/riscv/cpu/th1520/Kconfig1
-rw-r--r--arch/riscv/cpu/th1520/cpu.c29
-rw-r--r--arch/riscv/cpu/th1520/spl.c83
-rw-r--r--arch/riscv/dts/th1520.dtsi29
-rw-r--r--arch/riscv/include/asm/arch-th1520/cpu.h1
-rw-r--r--arch/riscv/include/asm/byteorder.h2
-rw-r--r--arch/riscv/lib/aclint_ipi.c5
-rw-r--r--arch/sandbox/cpu/state.c6
-rw-r--r--arch/sandbox/include/asm/state.h1
-rw-r--r--board/amd/versal2/board.c2
-rw-r--r--board/astro/mcf5373l/Kconfig15
-rw-r--r--board/astro/mcf5373l/MAINTAINERS6
-rw-r--r--board/astro/mcf5373l/Makefile6
-rw-r--r--board/astro/mcf5373l/astro.h44
-rw-r--r--board/astro/mcf5373l/fpga.c407
-rw-r--r--board/astro/mcf5373l/mcf5373l.c201
-rw-r--r--board/congatec/common/Makefile4
-rw-r--r--board/cssi/cmpc885/u-boot.lds4
-rw-r--r--board/cssi/mcr3000/u-boot.lds4
-rw-r--r--board/freescale/common/Makefile4
-rw-r--r--board/freescale/imx8mm_evk/imx8mm_evk.c22
-rw-r--r--board/freescale/imx8mn_evk/imx8mn_evk.c22
-rw-r--r--board/freescale/imx8mp_evk/imx8mp_evk.c23
-rw-r--r--board/freescale/imx8mq_evk/imx8mq_evk.c21
-rw-r--r--board/freescale/imx93_evk/imx93_evk.c21
-rw-r--r--board/lg/star/star.c1
-rw-r--r--board/menlo/mx8menlo/Makefile4
-rw-r--r--board/microchip/mpfs_icicle/mpfs_icicle.c63
-rw-r--r--board/phytec/common/Makefile4
-rw-r--r--board/phytec/phycore_am62x/rm-cfg.yaml26
-rw-r--r--board/qualcomm/MAINTAINERS24
-rw-r--r--board/raidsonic/ib62x0/MAINTAINERS2
-rw-r--r--board/samsung/coreprimevelte/MAINTAINERS2
-rw-r--r--board/samsung/e850-96/e850-96.c9
-rw-r--r--board/samsung/origen/Makefile4
-rw-r--r--board/samsung/smdkv310/Makefile4
-rw-r--r--board/sandbox/sandbox.c1
-rw-r--r--board/sunxi/MAINTAINERS10
-rw-r--r--board/sunxi/board.c4
-rw-r--r--board/thead/th1520_lpi4a/spl.c3
-rw-r--r--board/toradex/common/Makefile4
-rw-r--r--board/xilinx/common/board.c33
-rw-r--r--boot/Kconfig11
-rw-r--r--boot/bootm.c27
-rw-r--r--boot/bootm_os.c11
-rw-r--r--boot/image-android.c11
-rw-r--r--boot/image-board.c56
-rw-r--r--boot/image-fdt.c69
-rw-r--r--boot/pxe_utils.c4
-rw-r--r--boot/scene_menu.c5
-rw-r--r--cmd/Kconfig65
-rw-r--r--cmd/Makefile5
-rw-r--r--cmd/abootimg.c2
-rw-r--r--cmd/booti.c10
-rw-r--r--cmd/bootz.c10
-rw-r--r--cmd/eficonfig.c146
-rw-r--r--cmd/help.c6
-rw-r--r--cmd/load.c9
-rw-r--r--cmd/lwip/Makefile6
-rw-r--r--cmd/lwip/dhcp.c9
-rw-r--r--cmd/lwip/dns.c (renamed from net/lwip/dns.c)33
-rw-r--r--cmd/lwip/ping.c (renamed from net/lwip/ping.c)6
-rw-r--r--cmd/lwip/sntp.c134
-rw-r--r--cmd/lwip/tftp.c9
-rw-r--r--cmd/lwip/wget.c222
-rw-r--r--cmd/net-lwip.c50
-rw-r--r--cmd/smbios.c2
-rw-r--r--cmd/tpm-v2.c6
-rw-r--r--common/Makefile6
-rw-r--r--common/cli_readline.c4
-rw-r--r--common/spl/Kconfig4
-rw-r--r--common/spl/spl_fit.c58
-rw-r--r--configs/am62x_a53_usbdfu.config1
-rw-r--r--configs/am64x_evm_a53_defconfig3
-rw-r--r--configs/am64x_evm_r5_defconfig1
-rw-r--r--configs/am65x_evm_a53_defconfig1
-rw-r--r--configs/am65x_evm_r5_defconfig1
-rw-r--r--configs/am65x_evm_r5_usbdfu_defconfig1
-rw-r--r--configs/am65x_evm_r5_usbmsc_defconfig1
-rw-r--r--configs/amd_versal2_mini_defconfig2
-rw-r--r--configs/amd_versal2_mini_emmc_defconfig2
-rw-r--r--configs/amd_versal2_mini_ospi_defconfig5
-rw-r--r--configs/amd_versal2_mini_qspi_defconfig2
-rw-r--r--configs/amd_versal2_virt_defconfig6
-rw-r--r--configs/arbel_evb_defconfig1
-rw-r--r--configs/astro_mcf5373l_defconfig51
-rw-r--r--configs/bk4r1_defconfig1
-rw-r--r--configs/e850-96_defconfig1
-rw-r--r--configs/imx8mm_evk_defconfig19
-rw-r--r--configs/imx8mn_evk_defconfig22
-rw-r--r--configs/imx8mp_evk_defconfig14
-rw-r--r--configs/imx8mq_evk_defconfig13
-rw-r--r--configs/imx93_11x11_evk_defconfig14
-rw-r--r--configs/iot2050_defconfig1
-rw-r--r--configs/j7200_evm_a72_defconfig1
-rw-r--r--configs/j7200_evm_r5_defconfig1
-rw-r--r--configs/j721e_beagleboneai64_a72_defconfig1
-rw-r--r--configs/j721e_beagleboneai64_r5_defconfig1
-rw-r--r--configs/j721e_evm_a72_defconfig1
-rw-r--r--configs/j721e_evm_r5_defconfig1
-rw-r--r--configs/j721s2_evm_a72_defconfig1
-rw-r--r--configs/j721s2_evm_r5_defconfig1
-rw-r--r--configs/j784s4_evm_a72_defconfig1
-rw-r--r--configs/j784s4_evm_r5_defconfig1
-rw-r--r--configs/legoev3_defconfig6
-rw-r--r--configs/liontron-h-a133l_defconfig36
-rw-r--r--configs/ls1021aqds_nor_SECURE_BOOT_defconfig1
-rw-r--r--configs/ls1021atwr_nor_SECURE_BOOT_defconfig1
-rw-r--r--configs/mangopi_mq_r_defconfig2
-rw-r--r--configs/mx6sabresd_defconfig3
-rw-r--r--configs/pcm052_defconfig1
-rw-r--r--configs/phycore_am62ax_a53_defconfig1
-rw-r--r--configs/phycore_am62x_a53_defconfig1
-rw-r--r--configs/phycore_am64x_a53_defconfig1
-rw-r--r--configs/phycore_am64x_r5_defconfig1
-rw-r--r--configs/qcm6490_defconfig6
-rw-r--r--configs/qcom_defconfig7
-rw-r--r--configs/qcom_ipq5424_mmc_defconfig56
-rw-r--r--configs/qcom_ipq9574_mmc_defconfig2
-rw-r--r--configs/qcom_qcs615_defconfig22
-rw-r--r--configs/qcom_qcs8300_defconfig21
-rw-r--r--configs/qemu_arm64_defconfig1
-rw-r--r--configs/qemu_arm64_lwip_defconfig1
-rw-r--r--configs/qemu_arm_defconfig1
-rw-r--r--configs/r8a779g0_whitehawk_defconfig4
-rw-r--r--configs/r8a779g3_sparrowhawk_defconfig9
-rw-r--r--configs/sandbox64_defconfig1
-rw-r--r--configs/sandbox_defconfig1
-rw-r--r--configs/sandbox_flattree_defconfig1
-rw-r--r--configs/sandbox_noinst_defconfig1
-rw-r--r--configs/sandbox_spl_defconfig1
-rw-r--r--configs/sandbox_vpl_defconfig1
-rw-r--r--configs/th1520_lpi4a_defconfig1
-rw-r--r--configs/verdin-am62_a53_defconfig1
-rw-r--r--configs/verdin-am62p_a53_defconfig4
-rw-r--r--configs/verdin-am62p_r5_defconfig3
-rw-r--r--configs/vf610twr_defconfig1
-rw-r--r--configs/vf610twr_nand_defconfig1
-rw-r--r--configs/xilinx_versal_mini_defconfig2
-rw-r--r--configs/xilinx_versal_mini_emmc0_defconfig2
-rw-r--r--configs/xilinx_versal_mini_emmc1_defconfig2
-rw-r--r--configs/xilinx_versal_mini_ospi_defconfig2
-rw-r--r--configs/xilinx_versal_mini_qspi_defconfig2
-rw-r--r--configs/xilinx_versal_net_mini_defconfig2
-rw-r--r--configs/xilinx_versal_net_mini_emmc_defconfig2
-rw-r--r--configs/xilinx_versal_net_mini_ospi_defconfig2
-rw-r--r--configs/xilinx_versal_net_mini_qspi_defconfig2
-rw-r--r--configs/xilinx_versal_net_virt_defconfig1
-rw-r--r--configs/xilinx_versal_virt_defconfig1
-rw-r--r--configs/xilinx_zynqmp_kria_defconfig1
-rw-r--r--configs/xilinx_zynqmp_mini_defconfig2
-rw-r--r--configs/xilinx_zynqmp_mini_emmc0_defconfig2
-rw-r--r--configs/xilinx_zynqmp_mini_emmc1_defconfig2
-rw-r--r--configs/xilinx_zynqmp_mini_nand_defconfig2
-rw-r--r--configs/xilinx_zynqmp_mini_nand_single_defconfig2
-rw-r--r--configs/xilinx_zynqmp_mini_qspi_defconfig2
-rw-r--r--configs/xilinx_zynqmp_virt_defconfig2
-rw-r--r--configs/yuzukihd-chameleon_defconfig29
-rw-r--r--disk/part_efi.c67
-rw-r--r--doc/README.SNTP17
-rw-r--r--doc/README.pxe3
-rw-r--r--doc/api/index.rst1
-rw-r--r--doc/api/linker_lists.rst8
-rw-r--r--doc/api/lmb.rst7
-rw-r--r--doc/board/qualcomm/board.rst21
-rw-r--r--doc/board/qualcomm/dragonwing.rst49
-rw-r--r--doc/board/qualcomm/index.rst1
-rw-r--r--doc/board/qualcomm/rdp.rst15
-rw-r--r--doc/develop/crash_dumps.rst8
-rw-r--r--doc/develop/distro.rst7
-rw-r--r--doc/develop/index.rst1
-rw-r--r--doc/develop/lmb.rst166
-rw-r--r--doc/develop/release_cycle.rst32
-rw-r--r--doc/develop/statistics/u-boot-stats-v2025.07.rst990
-rw-r--r--doc/usage/cmd/gpt.rst93
-rw-r--r--doc/usage/cmd/sntp.rst72
-rw-r--r--doc/usage/cmd/wget.rst7
-rw-r--r--doc/usage/index.rst1
-rw-r--r--drivers/cache/Kconfig1
-rw-r--r--drivers/clk/Kconfig2
-rw-r--r--drivers/clk/clk_zynqmp.c20
-rw-r--r--drivers/clk/qcom/Kconfig24
-rw-r--r--drivers/clk/qcom/Makefile3
-rw-r--r--drivers/clk/qcom/clock-ipq5424.c96
-rw-r--r--drivers/clk/qcom/clock-qcom.h1
-rw-r--r--drivers/clk/qcom/clock-qcs615.c163
-rw-r--r--drivers/clk/qcom/clock-qcs8300.c146
-rw-r--r--drivers/clk/qcom/clock-sc7280.c4
-rw-r--r--drivers/clk/qcom/clock-sm8250.c4
-rw-r--r--drivers/dfu/dfu_scsi.c5
-rw-r--r--drivers/firmware/Kconfig1
-rw-r--r--drivers/firmware/firmware-zynqmp.c60
-rw-r--r--drivers/fpga/intel_sdm_mb.c3
-rw-r--r--drivers/gpio/msm_gpio.c2
-rw-r--r--drivers/i2c/muxes/i2c-mux-uclass.c5
-rw-r--r--drivers/mmc/rpmb.c6
-rw-r--r--drivers/mmc/socfpga_dw_mmc.c22
-rw-r--r--drivers/mmc/zynq_sdhci.c22
-rw-r--r--drivers/mtd/nand/spi/gigadevice.c188
-rw-r--r--drivers/net/designware.c2
-rw-r--r--drivers/pci/Kconfig10
-rw-r--r--drivers/pci/Makefile1
-rw-r--r--drivers/pci/pci-rcar-gen4.c565
-rw-r--r--drivers/pci/pcie_dw_common.c45
-rw-r--r--drivers/pci/pcie_dw_common.h9
-rw-r--r--drivers/pci/pcie_dw_meson.c6
-rw-r--r--drivers/pci/pcie_dw_qcom.c19
-rw-r--r--drivers/pci/pcie_dw_rockchip.c39
-rw-r--r--drivers/pci_endpoint/Kconfig6
-rw-r--r--drivers/pci_endpoint/Makefile1
-rw-r--r--drivers/pci_endpoint/pcie_cdns_ti_ep.c396
-rw-r--r--drivers/phy/cadence/phy-cadence-torrent.c225
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-ufs.c128
-rw-r--r--drivers/pinctrl/Kconfig8
-rw-r--r--drivers/pinctrl/Makefile1
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx-mmio.c1
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx8ulp.c2
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imxrt.c1
-rw-r--r--drivers/pinctrl/nxp/pinctrl-vf610.c1
-rw-r--r--drivers/pinctrl/pinctrl-th1520.c700
-rw-r--r--drivers/pinctrl/qcom/Kconfig7
-rw-r--r--drivers/pinctrl/qcom/Makefile1
-rw-r--r--drivers/pinctrl/qcom/pinctrl-ipq5424.c322
-rw-r--r--drivers/rtc/Kconfig7
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/ds1672.c117
-rw-r--r--drivers/spi/cadence_ospi_versal.c12
-rw-r--r--drivers/spi/cadence_qspi.h4
-rw-r--r--drivers/spi/cadence_qspi_apb.c13
-rw-r--r--drivers/spi/fsl_dspi.c6
-rw-r--r--drivers/watchdog/Kconfig9
-rw-r--r--drivers/watchdog/Makefile1
-rw-r--r--drivers/watchdog/qcom-wdt.c137
-rw-r--r--dts/upstream/src/arm64/allwinner/sun50i-a100.dtsi3
-rw-r--r--dts/upstream/src/arm64/allwinner/sun50i-a133-liontron-h-a133l.dts211
-rw-r--r--dts/upstream/src/arm64/allwinner/sun50i-h618-yuzukihd-chameleon.dts222
-rw-r--r--env/Kconfig42
-rw-r--r--env/common.c4
-rw-r--r--env/mmc.c8
-rw-r--r--fs/ext4/ext4_journal.c7
-rw-r--r--fs/fs.c5
-rw-r--r--include/configs/astro_mcf5373l.h187
-rw-r--r--include/configs/sandbox.h2
-rw-r--r--include/dt-bindings/clock/xlnx-zynqmp-clk.h126
-rw-r--r--include/efi_api.h71
-rw-r--r--include/efi_config.h2
-rw-r--r--include/efi_loader.h19
-rw-r--r--include/fsl_ifc.h24
-rw-r--r--include/image.h2
-rw-r--r--include/lmb.h105
-rw-r--r--include/log.h2
-rw-r--r--include/ndisc.h2
-rw-r--r--include/net-common.h13
-rw-r--r--include/net-lwip.h16
-rw-r--r--include/part.h15
-rw-r--r--include/part_efi.h20
-rw-r--r--include/sata.h3
-rw-r--r--include/spl_gpio.h2
-rw-r--r--include/tpm-v2.h2
-rw-r--r--include/vsc9953.h2
-rw-r--r--include/zynqmp_firmware.h9
-rw-r--r--lib/ecdsa/ecdsa-libcrypto.c176
-rw-r--r--lib/efi_loader/Kconfig9
-rw-r--r--lib/efi_loader/Makefile2
-rw-r--r--lib/efi_loader/dbginfodump.c356
-rw-r--r--lib/efi_loader/efi_bootmgr.c2
-rw-r--r--lib/efi_loader/efi_boottime.c7
-rw-r--r--lib/efi_loader/efi_debug_support.c183
-rw-r--r--lib/efi_loader/efi_disk.c39
-rw-r--r--lib/efi_loader/efi_file.c2
-rw-r--r--lib/efi_loader/efi_http.c9
-rw-r--r--lib/efi_loader/efi_memory.c80
-rw-r--r--lib/efi_loader/efi_net.c2
-rw-r--r--lib/efi_loader/efi_setup.c18
-rw-r--r--lib/efi_selftest/Makefile2
-rw-r--r--lib/efi_selftest/efi_selftest_block_device.c30
-rw-r--r--lib/efi_selftest/efi_selftest_debug_support.c40
-rw-r--r--lib/lmb.c183
-rw-r--r--lib/lwip/Makefile1
-rw-r--r--lib/lwip/u-boot/arch/cc.h4
-rw-r--r--lib/lwip/u-boot/lwipopts.h8
-rw-r--r--lib/rsa/rsa-sign.c4
-rw-r--r--lib/rsa/rsa-verify.c2
-rw-r--r--lib/tpm-v2.c2
-rw-r--r--lib/uuid.c162
-rw-r--r--net/bootp.c6
-rw-r--r--net/dhcpv6.c6
-rw-r--r--net/lwip/Makefile2
-rw-r--r--net/lwip/dhcp.c1
-rw-r--r--net/lwip/eth_internal.h35
-rw-r--r--net/lwip/net-lwip.c81
-rw-r--r--net/lwip/tftp.c8
-rw-r--r--net/lwip/wget.c207
-rw-r--r--net/net-common.c23
-rw-r--r--net/sntp.c23
-rw-r--r--scripts/Makefile.build284
-rw-r--r--scripts/Makefile.extrawarn9
-rw-r--r--scripts/Makefile.gcc-plugins59
-rw-r--r--scripts/Makefile.kcov9
-rw-r--r--scripts/Makefile.lib114
-rw-r--r--scripts/Makefile.xpl2
-rwxr-xr-xscripts/dtc/pylibfdt/setup.py2
-rw-r--r--test/cmd/wget.c20
-rw-r--r--test/common/print.c3
-rw-r--r--test/lib/Makefile2
-rw-r--r--test/lib/efi_memory.c63
-rw-r--r--test/lib/lmb.c102
-rw-r--r--test/py/tests/test_efi_selftest.py1
-rw-r--r--test/py/tests/test_fit_mkimage_validate.py58
-rw-r--r--test/py/tests/test_gpt.py27
-rw-r--r--test/py/tests/test_help.py1
-rw-r--r--test/py/tests/test_mmc.py30
-rw-r--r--tools/Makefile3
-rw-r--r--tools/binman/binman.rst7
-rw-r--r--tools/binman/btool/openssl.py16
-rw-r--r--tools/binman/control.py86
-rw-r--r--tools/binman/entry.py17
-rw-r--r--tools/binman/etype/blob.py9
-rw-r--r--tools/binman/etype/blob_ext_list.py4
-rw-r--r--tools/binman/etype/cbfs.py3
-rw-r--r--tools/binman/etype/fit.py3
-rw-r--r--tools/binman/etype/mkimage.py2
-rw-r--r--tools/binman/etype/section.py16
-rw-r--r--tools/binman/etype/ti_secure.py1
-rw-r--r--tools/binman/etype/ti_secure_rom.py1
-rw-r--r--tools/binman/etype/u_boot_spl_pubkey_dtb.py2
-rw-r--r--tools/binman/etype/x509_cert.py7
-rw-r--r--tools/binman/ftest.py111
-rw-r--r--tools/binman/image.py2
-rw-r--r--tools/binman/missing-blob-help59
-rw-r--r--tools/binman/test/170_fit_fdt.dts14
-rw-r--r--tools/binman/test/220_fit_subentry_bintool.dts2
-rw-r--r--tools/binman/test/223_fit_fdt_oper.dts14
-rw-r--r--tools/binman/test/284_fit_fdt_list.dts14
-rw-r--r--tools/binman/test/333_fit_fdt_dir.dts14
-rw-r--r--tools/binman/test/334_fit_fdt_compat.dts14
-rw-r--r--tools/binman/test/335_fit_fdt_phase.dts14
-rw-r--r--tools/binman/test/345_fit_fdt_name.dts14
-rw-r--r--tools/binman/test/347_bootph_prop.dts21
-rw-r--r--tools/binman/test/347_key_name_hint_dir_fit_signature.dts98
-rw-r--r--tools/binman/test/348_key_name_hint_dir_spl_pubkey_dtb.dts16
-rw-r--r--tools/buildman/builder.py7
-rw-r--r--tools/buildman/builderthread.py56
-rw-r--r--tools/buildman/buildman.rst8
-rw-r--r--tools/buildman/control.py17
-rw-r--r--tools/fit_image.c122
-rw-r--r--tools/image-host.c4
-rw-r--r--tools/imx8image.c2
-rw-r--r--tools/mkimage.c7
-rwxr-xr-xtools/rmboard.py6
-rw-r--r--tools/termios_linux.h6
411 files changed, 12803 insertions, 3316 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 18afc03b460..2dfeda9985d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -264,8 +264,8 @@ Check packing of Python tools:
sandbox test.py:
parallel:
matrix:
- - HOST: "fast arm64"
- - HOST: "fast amd64"
+ - HOST: "arm64"
+ - HOST: "amd64"
tags:
- ${HOST}
variables:
@@ -276,8 +276,8 @@ sandbox test.py:
sandbox with clang test.py:
parallel:
matrix:
- - HOST: "fast arm64"
- - HOST: "fast amd64"
+ - HOST: "arm64"
+ - HOST: "amd64"
tags:
- ${HOST}
variables:
@@ -288,8 +288,8 @@ sandbox with clang test.py:
sandbox64 test.py:
parallel:
matrix:
- - HOST: "fast arm64"
- - HOST: "fast amd64"
+ - HOST: "arm64"
+ - HOST: "amd64"
tags:
- ${HOST}
variables:
@@ -299,8 +299,8 @@ sandbox64 test.py:
sandbox64 with clang test.py:
parallel:
matrix:
- - HOST: "fast arm64"
- - HOST: "fast amd64"
+ - HOST: "arm64"
+ - HOST: "amd64"
tags:
- ${HOST}
variables:
@@ -311,8 +311,8 @@ sandbox64 with clang test.py:
sandbox64_lwip test.py:
parallel:
matrix:
- - HOST: "fast arm64"
- - HOST: "fast amd64"
+ - HOST: "arm64"
+ - HOST: "amd64"
tags:
- ${HOST}
variables:
diff --git a/.mailmap b/.mailmap
index 830a263b983..629d0ca95a8 100644
--- a/.mailmap
+++ b/.mailmap
@@ -39,6 +39,7 @@ Casey Connolly <casey.connolly@linaro.org> <caleb.connolly@linaro.org>
Christian Kohn <chris.kohn@amd.com> <christian.kohn@xilinx.com>
Christopher Obbard <christopher.obbard@linaro.org> <chris.obbard@collabora.com>
Dirk Behme <dirk.behme@googlemail.com>
+<duje@dujemihanovic.xyz> <duje.mihanovic@skole.hr>
Durga Challa <durga.challa@amd.com> <vnsl.durga.challa@xilinx.com>
Eugen Hristev <eugen.hristev@linaro.org> <eugen.hristev@microchip.com>
Eugen Hristev <eugen.hristev@linaro.org> <eugen.hristev@collabora.com>
diff --git a/Kconfig b/Kconfig
index 51358633762..05b7f410fa5 100644
--- a/Kconfig
+++ b/Kconfig
@@ -309,7 +309,7 @@ config SYS_MALLOC_F_LEN
config SYS_MALLOC_LEN
hex "Define memory for Dynamic allocation"
default 0x4000000 if SANDBOX
- default 0x2000000 if ARCH_ROCKCHIP || ARCH_OMAP2PLUS || ARCH_MESON
+ default 0x2000000 if ARCH_ROCKCHIP || ARCH_OMAP2PLUS || ARCH_MESON || ARCH_K3
default 0x200000 if ARCH_BMIPS || X86
default 0x4020000 if SUNXI_MINIMUM_DRAM_MB >= 256
default 0x220000 if SUNXI_MINIMUM_DRAM_MB >= 64
diff --git a/MAINTAINERS b/MAINTAINERS
index 92119667618..d5264c8f5df 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -391,7 +391,7 @@ F: drivers/pci/pci-aardvark.c
F: drivers/pci/pci_mvebu.c
ARM MARVELL PXA1908
-M: Duje Mihanović <duje.mihanovic@skole.hr>
+M: Duje Mihanović <duje@dujemihanovic.xyz>
S: Maintained
T: git git://git.dujemihanovic.xyz/u-boot.git
F: arch/arm/dts/pxa1908*
@@ -1073,6 +1073,7 @@ T: git https://source.denx.de/u-boot/custodians/u-boot-dfu.git
F: cmd/dfu.c
F: cmd/usb_*.c
F: common/dfu.c
+F: common/spl/spl_dfu.c
F: common/update.c
F: doc/api/dfu.rst
F: doc/usage/dfu.rst
@@ -1409,6 +1410,7 @@ F: net/
NETWORK (LWIP)
M: Jerome Forissier <jerome.forissier@linaro.org>
S: Maintained
+F: cmd/lwip/
F: cmd/net-lwip.c
F: configs/qemu_arm64_lwip_defconfig
F: drivers/net/sandbox-lwip.c
@@ -1574,6 +1576,7 @@ M: Yao Zi <ziyao@disroot.org>
S: Maintained
F: arch/riscv/cpu/th1520/
F: drivers/clk/thead/clk-th1520-ap.c
+F: drivers/pinctrl/pinctrl-th1520.c
F: drivers/ram/thead/th1520_ddr.c
RNG
diff --git a/Makefile b/Makefile
index 03290bbbbd4..93e9f401842 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
VERSION = 2025
PATCHLEVEL = 07
SUBLEVEL =
-EXTRAVERSION = -rc4
+EXTRAVERSION =
NAME =
# *DOCUMENTATION*
@@ -12,6 +12,10 @@ NAME =
# Comments in this file are targeted only to the developer, do not
# expect to learn how to build the kernel reading this file.
+# That's our default target when none is given on the command line
+PHONY := _all
+_all:
+
# Determine target architecture for the sandbox
include include/host_arch.h
ifeq ("", "$(CROSS_COMPILE)")
@@ -41,7 +45,7 @@ undefine MK_ARCH
# Most importantly: sub-Makefiles should only ever modify files in
# their own directory. If in some directory we have a dependency on
# a file in another dir (which doesn't happen often, but it's often
-# unavoidable when linking the built-in.o targets which finally
+# unavoidable when linking the built-in.a targets which finally
# turn into vmlinux), we will call a sub make in that other dir, and
# after that we are sure that everything which is in that other dir
# is now up to date.
@@ -109,7 +113,6 @@ endif
# If the user is running make -s (silent mode), suppress echoing of
# commands
-
ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4
ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)
quiet=silent_
@@ -137,8 +140,8 @@ export quiet Q KBUILD_VERBOSE
# The O= assignment takes precedence over the KBUILD_OUTPUT environment
# variable.
-# KBUILD_SRC is set on invocation of make in OBJ directory
-# KBUILD_SRC is not intended to be used by the regular user (for now)
+# KBUILD_SRC is not intended to be used by the regular user (for now),
+# it is set on invocation of make with KBUILD_OUTPUT or O= specified.
# OK, Make called in directory where kernel src resides
# Do we want to locate output files in a separate directory?
@@ -146,19 +149,15 @@ ifeq ("$(origin O)", "command line")
KBUILD_OUTPUT := $(O)
endif
-# That's our default target when none is given on the command line
-PHONY := _all
-_all:
-
-# Cancel implicit rules on top Makefile
-$(CURDIR)/Makefile Makefile: ;
+ifneq ($(words $(subst :, ,$(CURDIR))), 1)
+ $(error main directory cannot contain spaces nor colons)
+endif
ifneq ($(KBUILD_OUTPUT),)
-# Invoke a second make in the output directory, passing relevant variables
# check that the output directory actually exists
saved-output := $(KBUILD_OUTPUT)
KBUILD_OUTPUT := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) \
- && /bin/pwd)
+ && pwd)
$(if $(KBUILD_OUTPUT),, \
$(error failed to create output directory "$(saved-output)"))
@@ -169,6 +168,7 @@ $(if $(KBUILD_OUTPUT),, \
# 'sub-make' below.
MAKEFLAGS += --include-dir=$(CURDIR)
+need-sub-make := 1
else
# Do not print "Entering directory ..." at all for in-tree build.
@@ -176,19 +176,34 @@ MAKEFLAGS += --no-print-directory
endif # ifneq ($(KBUILD_OUTPUT),)
+ifneq ($(filter 3.%,$(MAKE_VERSION)),)
+# 'MAKEFLAGS += -rR' does not immediately become effective for GNU Make 3.x
+# We need to invoke sub-make to avoid implicit rules in the top Makefile.
+need-sub-make := 1
+# Cancel implicit rules for this Makefile.
+$(lastword $(MAKEFILE_LIST)): ;
+endif
+
export sub_make_done := 1
+
+ifeq ($(need-sub-make),1)
+
PHONY += $(MAKECMDGOALS) sub-make
$(filter-out _all sub-make $(CURDIR)/Makefile, $(MAKECMDGOALS)) _all: sub-make
@:
-sub-make: FORCE
+# Invoke a second make in the output directory, passing relevant variables
+sub-make:
$(Q)$(MAKE) \
$(if $(KBUILD_OUTPUT),-C $(KBUILD_OUTPUT) KBUILD_SRC=$(CURDIR)) \
-f $(CURDIR)/Makefile $(filter-out _all sub-make,$(MAKECMDGOALS))
-else # sub_make_done
+endif # need-sub-make
+endif # sub_make_done
+
# We process the rest of the Makefile if this is the final invocation of make
+ifeq ($(need-sub-make),)
# Do not print "Entering directory ...",
# but we want to display it when entering to the output directory
@@ -202,8 +217,8 @@ MAKEFLAGS += --no-print-directory
# Use 'make C=2' to enable checking of *all* source files, regardless
# of whether they are re-compiled or not.
#
-# See the file "doc/sparse.txt" for more details, including
-# where to get the "sparse" utility.
+# See the file "Documentation/dev-tools/sparse.rst" for more details,
+# including where to get the "sparse" utility.
ifeq ("$(origin C)", "command line")
KBUILD_CHECKSRC = $(C)
@@ -216,6 +231,10 @@ endif
# Old syntax make ... SUBDIRS=$PWD is still supported
# Setting the environment variable KBUILD_EXTMOD take precedence
ifdef SUBDIRS
+ $(warning ================= WARNING ================)
+ $(warning 'SUBDIRS' will be removed after Linux 5.3)
+ $(warning Please use 'M=' or 'KBUILD_EXTMOD' instead)
+ $(warning ==========================================)
KBUILD_EXTMOD ?= $(SUBDIRS)
endif
@@ -223,18 +242,6 @@ ifeq ("$(origin M)", "command line")
KBUILD_EXTMOD := $(M)
endif
-# If building an external module we do not care about the all: rule
-# but instead _all depend on modules
-PHONY += all
-ifeq ($(KBUILD_EXTMOD),)
-_all: all
-else
-_all: modules
-PHONY += prepare
-prepare:
- $(cmd_crmodverdir)
-endif
-
ifeq ($(KBUILD_SRC),)
# building in the source tree
srctree := .
@@ -246,132 +253,177 @@ else
srctree := $(KBUILD_SRC)
endif
endif
+
+export KBUILD_CHECKSRC KBUILD_EXTMOD KBUILD_SRC
+
objtree := .
src := $(srctree)
obj := $(objtree)
-VPATH := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD))
+VPATH := $(srctree)
export srctree objtree VPATH
-# Make sure CDPATH settings don't interfere
-unexport CDPATH
+# To make sure we do not include .config for any of the *config targets
+# catch them early, and hand them over to scripts/kconfig/Makefile
+# It is allowed to specify more targets when calling make, including
+# mixing *config targets and build targets.
+# For example 'make oldconfig all'.
+# Detect when mixed targets is specified, and make a second invocation
+# of make so .config is not included in this case either (for *config).
-#########################################################################
+version_h := include/generated/version_autogenerated.h
+timestamp_h := include/generated/timestamp_autogenerated.h
+defaultenv_h := include/generated/defaultenv_autogenerated.h
+dt_h := include/generated/dt.h
+env_h := include/generated/environment.h
-HOSTARCH := $(shell uname -m | \
- sed -e s/i.86/x86/ \
- -e s/sun4u/sparc64/ \
- -e s/arm.*/arm/ \
- -e s/sa110/arm/ \
- -e s/ppc64/powerpc/ \
- -e s/ppc/powerpc/ \
- -e s/macppc/powerpc/\
- -e s/sh.*/sh/)
+clean-targets := %clean mrproper cleandocs
+no-dot-config-targets := $(clean-targets) \
+ clobber distclean \
+ help %docs check% coccicheck \
+ ubootversion backup tests check pcheck qcheck tcheck \
+ pylint pylint_err _pip pip pip_test pip_release
+no-sync-config-targets := $(no-dot-config-targets) install %install \
+ kernelrelease
-HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
- sed -e 's/\(cygwin\).*/cygwin/')
+config-targets := 0
+mixed-targets := 0
+dot-config := 1
+may-sync-config := 1
-export HOSTARCH HOSTOS
+ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)
+ ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)
+ dot-config := 0
+ endif
+endif
-#########################################################################
+ifneq ($(filter $(no-sync-config-targets), $(MAKECMDGOALS)),)
+ ifeq ($(filter-out $(no-sync-config-targets), $(MAKECMDGOALS)),)
+ may-sync-config := 0
+ endif
+endif
-# set default to nothing for native builds
-ifeq ($(HOSTARCH),$(ARCH))
-CROSS_COMPILE ?=
+ifneq ($(KBUILD_EXTMOD),)
+ may-sync-config := 0
endif
-KCONFIG_CONFIG ?= .config
-export KCONFIG_CONFIG
+ifeq ($(KBUILD_EXTMOD),)
+ ifneq ($(filter config %config,$(MAKECMDGOALS)),)
+ config-targets := 1
+ ifneq ($(words $(MAKECMDGOALS)),1)
+ mixed-targets := 1
+ endif
+ endif
+endif
-# SHELL used by kbuild
-CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
- else if [ -x /bin/bash ]; then echo /bin/bash; \
- else echo sh; fi ; fi)
+# For "make -j clean all", "make -j mrproper defconfig all", etc.
+ifneq ($(filter $(clean-targets),$(MAKECMDGOALS)),)
+ ifneq ($(filter-out $(clean-targets),$(MAKECMDGOALS)),)
+ mixed-targets := 1
+ endif
+endif
-HOST_LFS_CFLAGS := $(shell getconf LFS_CFLAGS 2>/dev/null)
-HOST_LFS_LDFLAGS := $(shell getconf LFS_LDFLAGS 2>/dev/null)
-HOST_LFS_LIBS := $(shell getconf LFS_LIBS 2>/dev/null)
+# install and modules_install need also be processed one by one
+ifneq ($(filter install,$(MAKECMDGOALS)),)
+ ifneq ($(filter modules_install,$(MAKECMDGOALS)),)
+ mixed-targets := 1
+ endif
+endif
-HOSTCC = cc
-HOSTCXX = c++
-KBUILD_HOSTCFLAGS := -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer \
- $(HOST_LFS_CFLAGS) $(HOSTCFLAGS)
-KBUILD_HOSTCXXFLAGS := -O2 $(HOST_LFS_CFLAGS) $(HOSTCXXFLAGS)
-KBUILD_HOSTLDFLAGS := $(HOST_LFS_LDFLAGS) $(HOSTLDFLAGS)
-KBUILD_HOSTLDLIBS := $(HOST_LFS_LIBS) $(HOSTLDLIBS)
+ifeq ($(mixed-targets),1)
+# ===========================================================================
+# We're called with mixed targets (*config and build targets).
+# Handle them one by one.
-# With the move to GCC 6, we have implicitly upgraded our language
-# standard to GNU11 (see https://gcc.gnu.org/gcc-5/porting_to.html).
-# Some Linux distributions (including RHEL7, SLES13, Debian 8) still
-# have older compilers as their default, so we make it explicit for
-# these that our host tools are GNU11 (i.e. C11 w/ GNU extensions).
-CSTD_FLAG := -std=gnu11
-KBUILD_HOSTCFLAGS += $(CSTD_FLAG)
+PHONY += $(MAKECMDGOALS) __build_one_by_one
-ifeq ($(HOSTOS),cygwin)
-KBUILD_HOSTCFLAGS += -ansi
-endif
+$(filter-out __build_one_by_one, $(MAKECMDGOALS)): __build_one_by_one
+ @:
-# Mac OS X / Darwin's C preprocessor is Apple specific. It
-# generates numerous errors and warnings. We want to bypass it
-# and use GNU C's cpp. To do this we pass the -traditional-cpp
-# option to the compiler. Note that the -traditional-cpp flag
-# DOES NOT have the same semantics as GNU C's flag, all it does
-# is invoke the GNU preprocessor in stock ANSI/ISO C fashion.
-#
-# Apple's linker is similar, thanks to the new 2 stage linking
-# multiple symbol definitions are treated as errors, hence the
-# -multiply_defined suppress option to turn off this error.
-#
-ifeq ($(HOSTOS),darwin)
-# get major and minor product version (e.g. '10' and '6' for Snow Leopard)
-DARWIN_MAJOR_VERSION := $(shell sw_vers -productVersion | cut -f 1 -d '.')
-DARWIN_MINOR_VERSION := $(shell sw_vers -productVersion | cut -f 2 -d '.')
+__build_one_by_one:
+ $(Q)set -e; \
+ for i in $(MAKECMDGOALS); do \
+ $(MAKE) -f $(srctree)/Makefile $$i; \
+ done
-os_x_before = $(shell if [ $(DARWIN_MAJOR_VERSION) -le $(1) -a \
- $(DARWIN_MINOR_VERSION) -le $(2) ] ; then echo "$(3)"; else echo "$(4)"; fi ;)
+else
-os_x_after = $(shell if [ $(DARWIN_MAJOR_VERSION) -ge $(1) -a \
- $(DARWIN_MINOR_VERSION) -ge $(2) ] ; then echo "$(3)"; else echo "$(4)"; fi ;)
+include scripts/Kbuild.include
-# Snow Leopards build environment has no longer restrictions as described above
-HOSTCC = $(call os_x_before, 10, 5, "cc", "gcc")
-KBUILD_HOSTCFLAGS += $(call os_x_before, 10, 4, "-traditional-cpp")
-KBUILD_HOSTLDFLAGS += $(call os_x_before, 10, 5, "-multiply_defined suppress")
+# Read UBOOTRELEASE from include/config/uboot.release (if it exists)
+UBOOTRELEASE = $(shell cat include/config/uboot.release 2> /dev/null)
+UBOOTVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)
+export VERSION PATCHLEVEL SUBLEVEL UBOOTRELEASE UBOOTVERSION
-# macOS Mojave (10.14.X)
-# Undefined symbols for architecture x86_64: "_PyArg_ParseTuple"
-KBUILD_HOSTLDFLAGS += $(call os_x_after, 10, 14, "-lpython -dynamclib", "")
-endif
+# Modified for U-Boot
+-include scripts/subarch.include
-# Decide whether to build built-in, modular, or both.
-# Normally, just do built-in.
+# Cross compiling and selecting different set of gcc/bin-utils
+# ---------------------------------------------------------------------------
+#
+# When performing cross compilation for other architectures ARCH shall be set
+# to the target architecture. (See arch/* for the possibilities).
+# ARCH can be set during invocation of make:
+# make ARCH=ia64
+# Another way is to have ARCH set in the environment.
+# The default ARCH is the host where make is executed.
-KBUILD_MODULES :=
-KBUILD_BUILTIN := 1
+# CROSS_COMPILE specify the prefix used for all executables used
+# during compilation. Only gcc and related bin-utils executables
+# are prefixed with $(CROSS_COMPILE).
+# CROSS_COMPILE can be set on the command line
+# make CROSS_COMPILE=ia64-linux-
+# Alternatively CROSS_COMPILE can be set in the environment.
+# Default value for CROSS_COMPILE is not to prefix executables
+# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
+ARCH ?= $(SUBARCH)
-# If we have only "make modules", don't compile built-in objects.
-# When we're building modules with modversions, we need to consider
-# the built-in objects during the descend as well, in order to
-# make sure the checksums are up to date before we record them.
+# Architecture as present in compile.h
+UTS_MACHINE := $(ARCH)
+SRCARCH := $(ARCH)
-ifeq ($(MAKECMDGOALS),modules)
- KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1)
+# Additional ARCH settings for x86
+ifeq ($(ARCH),i386)
+ SRCARCH := x86
+endif
+ifeq ($(ARCH),x86_64)
+ SRCARCH := x86
endif
-# If we have "make <whatever> modules", compile modules
-# in addition to whatever we do anyway.
-# Just "make" or "make all" shall build modules as well
+# Additional ARCH settings for sparc
+ifeq ($(ARCH),sparc32)
+ SRCARCH := sparc
+endif
+ifeq ($(ARCH),sparc64)
+ SRCARCH := sparc
+endif
-# U-Boot does not need modules
-#ifneq ($(filter all _all modules,$(MAKECMDGOALS)),)
-# KBUILD_MODULES := 1
-#endif
+# Additional ARCH settings for sh
+ifeq ($(ARCH),sh64)
+ SRCARCH := sh
+endif
-#ifeq ($(MAKECMDGOALS),)
-# KBUILD_MODULES := 1
-#endif
+KCONFIG_CONFIG ?= .config
+export KCONFIG_CONFIG
+
+# SHELL used by kbuild
+CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
+ else if [ -x /bin/bash ]; then echo /bin/bash; \
+ else echo sh; fi ; fi)
+
+HOST_LFS_CFLAGS := $(shell getconf LFS_CFLAGS 2>/dev/null)
+HOST_LFS_LDFLAGS := $(shell getconf LFS_LDFLAGS 2>/dev/null)
+HOST_LFS_LIBS := $(shell getconf LFS_LIBS 2>/dev/null)
+
+HOSTCC = gcc
+HOSTCXX = g++
+KBUILD_HOSTCFLAGS := -Wall -Wstrict-prototypes -O2 \
+ -fomit-frame-pointer -std=gnu11 $(HOST_LFS_CFLAGS) \
+ $(HOSTCFLAGS) #-Wmissing-prototypes Enable it and fix warnings
+KBUILD_HOSTCXXFLAGS := -O2 $(HOST_LFS_CFLAGS) $(HOSTCXXFLAGS)
+KBUILD_HOSTLDFLAGS := $(HOST_LFS_LDFLAGS) $(HOSTLDFLAGS)
+KBUILD_HOSTLDLIBS := $(HOST_LFS_LIBS) $(HOSTLDLIBS)
# Check ths size of a binary:
# Args:
@@ -393,19 +445,9 @@ export size_check
export KBUILD_MODULES KBUILD_BUILTIN
export KBUILD_CHECKSRC KBUILD_SRC KBUILD_EXTMOD
-# We need some generic definitions (do not try to remake the file).
-scripts/Kbuild.include: ;
-include scripts/Kbuild.include
-
# Make variables (CC, etc...)
-
AS = $(CROSS_COMPILE)as
-# Always use GNU ld
-ifneq ($(shell $(CROSS_COMPILE)ld.bfd -v 2> /dev/null),)
-LD = $(CROSS_COMPILE)ld.bfd
-else
LD = $(CROSS_COMPILE)ld
-endif
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
@@ -418,10 +460,12 @@ READELF = $(CROSS_COMPILE)readelf
LEX = flex
YACC = bison
AWK = awk
+INSTALLKERNEL := installkernel
+DEPMOD = /sbin/depmod
PERL = perl
-PYTHON ?= python
+PYTHON = python
PYTHON2 = python2
-PYTHON3 ?= python3
+PYTHON3 = python3
# The devicetree compiler and pylibfdt are automatically built unless DTC is
# provided. If DTC is provided, it is assumed the pylibfdt is available too.
@@ -432,51 +476,79 @@ DTC_MIN_VERSION := 010406
CHECK = sparse
CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
- -Wbitwise -Wno-return-void -Wno-unknown-attribute \
- -D__CHECK_ENDIAN__ $(CF)
-
-KBUILD_CPPFLAGS := -D__KERNEL__ -D__UBOOT__
-
-KBUILD_CFLAGS := -Wall -Werror=strict-prototypes -Wno-trigraphs \
- -Wno-format-security \
- -fno-builtin -ffreestanding $(CSTD_FLAG) \
- -fno-PIE \
- -Werror=implicit-function-declaration -Werror=implicit-int
-KBUILD_CFLAGS += -fshort-wchar -fno-strict-aliasing
-KBUILD_AFLAGS := -D__ASSEMBLY__ -fno-PIE
-KBUILD_LDFLAGS :=
+ -Wbitwise -Wno-return-void -Wno-unknown-attribute -D__CHECK_ENDIAN__ $(CF)
+NOSTDINC_FLAGS :=
+CFLAGS_MODULE =
+AFLAGS_MODULE =
+LDFLAGS_MODULE =
+CFLAGS_KERNEL =
+AFLAGS_KERNEL =
+LDFLAGS_vmlinux =
+
+# Use USERINCLUDE when you must reference the UAPI directories only.
+USERINCLUDE := \
+ -I$(srctree)/arch/$(SRCARCH)/include/uapi \
+ -I$(objtree)/arch/$(SRCARCH)/include/generated/uapi \
+ -I$(srctree)/include/uapi \
+ -I$(objtree)/include/generated/uapi \
+ -include $(srctree)/include/linux/kconfig.h
-ifeq ($(cc-name),clang)
-ifneq ($(CROSS_COMPILE),)
-CLANG_TARGET := --target=$(notdir $(CROSS_COMPILE:%-=%))
-LDPPFLAGS += $(CLANG_TARGET)
-GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit))
-CLANG_PREFIX := --prefix=$(GCC_TOOLCHAIN_DIR)
-GCC_TOOLCHAIN := $(realpath $(GCC_TOOLCHAIN_DIR)/..)
-endif
-ifneq ($(GCC_TOOLCHAIN),)
-CLANG_GCC_TC := --gcc-toolchain=$(GCC_TOOLCHAIN)
-endif
-KBUILD_CFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC) $(CLANG_PREFIX)
-KBUILD_AFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC) $(CLANG_PREFIX)
-KBUILD_CFLAGS += $(call cc-option, -no-integrated-as)
-KBUILD_AFLAGS += $(call cc-option, -no-integrated-as)
-endif
-
-# Read UBOOTRELEASE from include/config/uboot.release (if it exists)
-UBOOTRELEASE = $(shell cat include/config/uboot.release 2> /dev/null)
-UBOOTVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)
+# Use UBOOTINCLUDE when you must reference the include/ directory.
+# Needed to be compatible with the O= option
+UBOOTINCLUDE := \
+ -Iinclude \
+ $(if $(KBUILD_SRC), -I$(srctree)/include) \
+ $(if $(CONFIG_$(XPL_)MBEDTLS_LIB), \
+ "-DMBEDTLS_CONFIG_FILE=\"mbedtls_def_config.h\"" \
+ -I$(srctree)/lib/mbedtls \
+ -I$(srctree)/lib/mbedtls/port \
+ -I$(srctree)/lib/mbedtls/external/mbedtls \
+ -I$(srctree)/lib/mbedtls/external/mbedtls/include) \
+ $(if $(CONFIG_$(PHASE_)SYS_THUMB_BUILD), \
+ $(if $(CONFIG_HAS_THUMB2), \
+ $(if $(CONFIG_CPU_V7M), \
+ -I$(srctree)/arch/arm/thumb1/include), \
+ -I$(srctree)/arch/arm/thumb1/include)) \
+ -I$(srctree)/arch/$(ARCH)/include \
+ -include $(srctree)/include/linux/kconfig.h \
+ -I$(srctree)/dts/upstream/include \
+ $(if $(CONFIG_NET_LWIP), -I$(srctree)/lib/lwip/lwip/src/include \
+ -I$(srctree)/lib/lwip/u-boot)
-export VERSION PATCHLEVEL SUBLEVEL UBOOTRELEASE UBOOTVERSION
-export ARCH CPU BOARD VENDOR SOC CPUDIR BOARDDIR
-export CONFIG_SHELL HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD CC
-export CPP AR NM LDR STRIP OBJCOPY OBJDUMP KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS
-export MAKE LEX YACC AWK PERL PYTHON PYTHON2 PYTHON3
-export HOSTCXX KBUILD_HOSTCXXFLAGS CHECK CHECKFLAGS DTC DTC_FLAGS
-export KBUILD_CPPFLAGS NOSTDINC_FLAGS UBOOTINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS
-export KBUILD_CFLAGS KBUILD_AFLAGS
+KBUILD_AFLAGS := -D__ASSEMBLY__ -fno-PIE
+KBUILD_CFLAGS := -Wall -Werror=strict-prototypes -Wno-trigraphs \
+ -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE \
+ -Werror=implicit-function-declaration -Werror=implicit-int \
+ -Wno-format-security -std=gnu11 #-Wundef Enable it and fix warnings
+UBOOT_CFLAGS := -ffreestanding -fno-builtin
+KBUILD_CFLAGS += $(UBOOT_CFLAGS)
+KBUILD_CPPFLAGS := -D__KERNEL__ -D__UBOOT__
+KBUILD_AFLAGS_KERNEL :=
+KBUILD_CFLAGS_KERNEL :=
+KBUILD_AFLAGS_MODULE := -DMODULE
+KBUILD_CFLAGS_MODULE := -DMODULE
+KBUILD_LDFLAGS_MODULE := -T $(srctree)/scripts/module-common.lds
+KBUILD_LDFLAGS :=
+GCC_PLUGINS_CFLAGS :=
+
+export ARCH SRCARCH CONFIG_SHELL HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD CC
+export CPP AR NM STRIP OBJCOPY OBJDUMP KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS
+export MAKE LEX YACC AWK INSTALLKERNEL PERL PYTHON PYTHON2 PYTHON3 UTS_MACHINE
+export HOSTCXX KBUILD_HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
+
+export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS
+export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
+export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE CFLAGS_UBSAN
+export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
+export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
+export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
+export KBUILD_ARFLAGS
+
+export LDR
+export CPU BOARD VENDOR SOC CPUDIR BOARDDIR
+export UBOOTINCLUDE
export CC_VERSION_TEXT := $(shell $(CC) --version | head -n 1)
# When compiling out-of-tree modules, put MODVERDIR in the module
@@ -504,15 +576,12 @@ endif
# ===========================================================================
# Rules shared between *config targets and build targets
-# Basic helpers built in scripts/
+# Basic helpers built in scripts/basic/
PHONY += scripts_basic
scripts_basic:
$(Q)$(MAKE) $(build)=scripts/basic
$(Q)rm -f .tmp_quiet_recordmcount
-# To avoid any implicit rule to kick in, define an empty command.
-scripts/basic/%: scripts_basic ;
-
PHONY += outputmakefile
# outputmakefile generates a Makefile in the output directory, if using a
# separate output directory. This allows convenient use of make in the
@@ -524,71 +593,51 @@ ifneq ($(KBUILD_SRC),)
$(Q)ln -fsn $(srctree) source
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile $(srctree)
$(Q)test -e .gitignore || \
- { echo "# this is build directory, ignore it"; echo "*"; } > .gitignore
+ { echo "# this is build directory, ignore it"; echo "*"; } > .gitignore
endif
-# To make sure we do not include .config for any of the *config targets
-# catch them early, and hand them over to scripts/kconfig/Makefile
-# It is allowed to specify more targets when calling make, including
-# mixing *config targets and build targets.
-# For example 'make oldconfig all'.
-# Detect when mixed targets is specified, and make a second invocation
-# of make so .config is not included in this case either (for *config).
-
-version_h := include/generated/version_autogenerated.h
-timestamp_h := include/generated/timestamp_autogenerated.h
-defaultenv_h := include/generated/defaultenv_autogenerated.h
-dt_h := include/generated/dt.h
-env_h := include/generated/environment.h
-
-no-dot-config-targets := clean clobber mrproper distclean \
- help %docs check% coccicheck \
- ubootversion backup tests check pcheck qcheck tcheck \
- pylint pylint_err _pip pip pip_test pip_release
-
-config-targets := 0
-mixed-targets := 0
-dot-config := 1
-
-ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)
- ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)
- dot-config := 0
- endif
+ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),)
+ifneq ($(CROSS_COMPILE),)
+CLANG_FLAGS := --target=$(notdir $(CROSS_COMPILE:%-=%))
+GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit))
+CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR)
+GCC_TOOLCHAIN := $(realpath $(GCC_TOOLCHAIN_DIR)/..)
endif
-
-ifeq ($(KBUILD_EXTMOD),)
- ifneq ($(filter config %config,$(MAKECMDGOALS)),)
- config-targets := 1
- ifneq ($(words $(MAKECMDGOALS)),1)
- mixed-targets := 1
- endif
- endif
+ifneq ($(GCC_TOOLCHAIN),)
+CLANG_FLAGS += --gcc-toolchain=$(GCC_TOOLCHAIN)
+endif
+CLANG_FLAGS += -no-integrated-as
+KBUILD_CFLAGS += $(CLANG_FLAGS)
+KBUILD_AFLAGS += $(CLANG_FLAGS)
+export CLANG_FLAGS
endif
-ifeq ($(mixed-targets),1)
-# ===========================================================================
-# We're called with mixed targets (*config and build targets).
-# Handle them one by one.
-
-PHONY += $(MAKECMDGOALS) __build_one_by_one
+RETPOLINE_CFLAGS_GCC := -mindirect-branch=thunk-extern -mindirect-branch-register
+RETPOLINE_VDSO_CFLAGS_GCC := -mindirect-branch=thunk-inline -mindirect-branch-register
+RETPOLINE_CFLAGS_CLANG := -mretpoline-external-thunk
+RETPOLINE_VDSO_CFLAGS_CLANG := -mretpoline
+RETPOLINE_CFLAGS := $(call cc-option,$(RETPOLINE_CFLAGS_GCC),$(call cc-option,$(RETPOLINE_CFLAGS_CLANG)))
+RETPOLINE_VDSO_CFLAGS := $(call cc-option,$(RETPOLINE_VDSO_CFLAGS_GCC),$(call cc-option,$(RETPOLINE_VDSO_CFLAGS_CLANG)))
+export RETPOLINE_CFLAGS
+export RETPOLINE_VDSO_CFLAGS
-$(filter-out __build_one_by_one, $(MAKECMDGOALS)): __build_one_by_one
- @:
-
-__build_one_by_one:
- $(Q)set -e; \
- for i in $(MAKECMDGOALS); do \
- $(MAKE) -f $(srctree)/Makefile $$i; \
- done
+# The expansion should be delayed until arch/$(SRCARCH)/Makefile is included.
+# Some architectures define CROSS_COMPILE in arch/$(SRCARCH)/Makefile.
+# CC_VERSION_TEXT is referenced from Kconfig (so it needs export),
+# and from include/config/auto.conf.cmd to detect the compiler upgrade.
+CC_VERSION_TEXT = $(shell $(CC) --version | head -n 1)
-else
ifeq ($(config-targets),1)
# ===========================================================================
# *config targets only - make sure prerequisites are updated, and descend
# in scripts/kconfig to make the *config target
-KBUILD_DEFCONFIG := sandbox_defconfig
-export KBUILD_DEFCONFIG KBUILD_KCONFIG
+# Read arch specific Makefile to set KBUILD_DEFCONFIG as needed.
+# KBUILD_DEFCONFIG may point out an alternative default configuration
+# used for 'make defconfig'
+# Modified for U-Boot
+-include arch/$(SRCARCH)/Makefile
+export KBUILD_DEFCONFIG KBUILD_KCONFIG CC_VERSION_TEXT
config: scripts_basic outputmakefile FORCE
$(Q)$(MAKE) $(build)=scripts/kconfig $@
@@ -601,29 +650,104 @@ else
# Build targets only - this includes vmlinux, arch specific targets, clean
# targets and others. In general all targets except *config targets.
-# Additional helpers built in scripts/
-# Carefully list dependencies so we do not try to build scripts twice
-# in parallel
-PHONY += scripts
-scripts: scripts_basic scripts_dtc include/config/auto.conf
- $(Q)$(MAKE) $(build)=$(@)
+# If building an external module we do not care about the all: rule
+# but instead _all depend on modules
+PHONY += all
+ifeq ($(KBUILD_EXTMOD),)
+_all: all
+else
+_all: modules
+endif
+
+# Decide whether to build built-in, modular, or both.
+# Normally, just do built-in.
+
+KBUILD_MODULES :=
+KBUILD_BUILTIN := 1
+
+# If we have only "make modules", don't compile built-in objects.
+# When we're building modules with modversions, we need to consider
+# the built-in objects during the descend as well, in order to
+# make sure the checksums are up to date before we record them.
+
+ifeq ($(MAKECMDGOALS),modules)
+ KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1)
+endif
+
+# If we have "make <whatever> modules", compile modules
+# in addition to whatever we do anyway.
+# Just "make" or "make all" shall build modules as well
+
+ifneq ($(filter all _all modules,$(MAKECMDGOALS)),)
+ KBUILD_MODULES := 1
+endif
+
+ifeq ($(MAKECMDGOALS),)
+ KBUILD_MODULES := 1
+endif
+
+export KBUILD_MODULES KBUILD_BUILTIN
+
+ifeq ($(KBUILD_EXTMOD),)
+# Objects we will link into vmlinux / subdirs we need to visit
+init-y := init/
+drivers-y := drivers/ sound/
+net-y := net/
+libs-y := lib/
+core-y := usr/
+virt-y := virt/
+endif # KBUILD_EXTMOD
ifeq ($(dot-config),1)
-# Read in config
+# Modified for U-Boot
-include include/config/auto.conf
+endif
+
+# The all: target is the default when no target is given on the
+# command line.
+# This allow a user to issue only 'make' to build a kernel including modules
+# Defaults to vmlinux, but the arch makefile usually adds further targets
+all: u-boot
+
+CFLAGS_GCOV := -fprofile-arcs -ftest-coverage \
+ $(call cc-option,-fno-tree-loop-im) \
+ $(call cc-disable-warning,maybe-uninitialized,)
+export CFLAGS_GCOV
+
+# The arch Makefiles can override CC_FLAGS_FTRACE. We may also append it later.
+ifdef CONFIG_FUNCTION_TRACER
+ CC_FLAGS_FTRACE := -pg
+endif
+
+# The arch Makefile can set ARCH_{CPP,A,C}FLAGS to override the default
+# values of the respective KBUILD_* variables
+ARCH_CPPFLAGS :=
+ARCH_AFLAGS :=
+ARCH_CFLAGS :=
+# Modified for U-Boot
+-include arch/$(SRCARCH)/Makefile
-# Read in dependencies to all Kconfig* files, make sure to run
-# oldconfig if changes are detected.
+ifeq ($(dot-config),1)
+ifeq ($(may-sync-config),1)
+# Read in dependencies to all Kconfig* files, make sure to run syncconfig if
+# changes are detected. This should be included after arch/$(SRCARCH)/Makefile
+# because some architectures define CROSS_COMPILE there.
-include include/config/auto.conf.cmd
-# To avoid any implicit rule to kick in, define an empty command
-$(KCONFIG_CONFIG) include/config/auto.conf.cmd: ;
+$(KCONFIG_CONFIG):
+ @echo >&2 '***'
+ @echo >&2 '*** Configuration file "$@" not found!'
+ @echo >&2 '***'
+ @echo >&2 '*** Please run some configurator (e.g. "make oldconfig" or'
+ @echo >&2 '*** "make menuconfig" or "make xconfig").'
+ @echo >&2 '***'
+ @/bin/false
# If .config is newer than include/config/auto.conf, someone tinkered
# with it and forgot to run make oldconfig.
# if auto.conf.cmd is missing then we are probably in a cleaned tree so
# we execute the config step to be sure to catch updated Kconfig files
-include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
+include/config/%.conf: $(KCONFIG_CONFIG) #include/config/auto.conf.cmd
$(Q)$(MAKE) -f $(srctree)/Makefile syncconfig
@# If the following part fails, include/config/auto.conf should be
@# deleted so "make silentoldconfig" will be re-run on the next build.
@@ -698,10 +822,30 @@ ifndef LDSCRIPT
endif
else
-# Dummy target needed, because used as prerequisite
-include/config/auto.conf: ;
+# External modules and some install targets need include/generated/autoconf.h
+# and include/config/auto.conf but do not care if they are up-to-date.
+# Use auto.conf to trigger the test
+PHONY += include/config/auto.conf
+
+include/config/auto.conf:
+ $(Q)test -e include/generated/autoconf.h -a -e $@ || ( \
+ echo >&2; \
+ echo >&2 " ERROR: Kernel configuration is invalid."; \
+ echo >&2 " include/generated/autoconf.h or $@ are missing.";\
+ echo >&2 " Run 'make oldconfig && make prepare' on kernel src to fix it."; \
+ echo >&2 ; \
+ /bin/false)
+
+endif # may-sync-config
endif # $(dot-config)
+KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks,)
+KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,)
+KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation)
+KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow)
+KBUILD_CFLAGS += $(call cc-disable-warning, int-in-bool-context)
+KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member)
+
ifdef CONFIG_CC_OPTIMIZE_FOR_DEBUG
KBUILD_HOSTCFLAGS := -Wall -Wstrict-prototypes -Og -g -fomit-frame-pointer \
$(HOST_LFS_CFLAGS) $(HOSTCFLAGS)
@@ -721,19 +865,19 @@ endif
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
KBUILD_CFLAGS += -Os
+else
+KBUILD_CFLAGS += -O2
endif
-ifdef CONFIG_CC_OPTIMIZE_FOR_SPEED
-KBUILD_CFLAGS += -O2
+ifdef CONFIG_CC_DISABLE_WARN_MAYBE_UNINITIALIZED
+KBUILD_CFLAGS += -Wno-maybe-uninitialized
endif
-ifdef CONFIG_CC_OPTIMIZE_FOR_DEBUG
-KBUILD_CFLAGS += -Og
-# Avoid false positives -Wmaybe-uninitialized
-# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78394
-KBUILD_CFLAGS += -Wno-maybe-uninitialized
-endif
+# Tell gcc to never replace conditional load with a non-conditional one
+KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0)
+include scripts/Makefile.kcov
+include scripts/Makefile.gcc-plugins
LTO_CFLAGS :=
LTO_FINAL_LDFLAGS :=
export LTO_CFLAGS LTO_FINAL_LDFLAGS
@@ -768,12 +912,6 @@ KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector)
endif
KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks)
-# disable pointer signed / unsigned warnings in gcc 4.0
-KBUILD_CFLAGS += -Wno-pointer-sign
-
-# disable stringop warnings in gcc 8+
-KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation)
-
KBUILD_CFLAGS += $(call cc-disable-warning, zero-length-bounds)
KBUILD_CFLAGS += $(call cc-disable-warning, array-bounds)
KBUILD_CFLAGS += $(call cc-disable-warning, stringop-overflow)
@@ -813,6 +951,11 @@ KBUILD_CFLAGS += $(call cc-disable-warning, tautological-compare)
KBUILD_CFLAGS += $(call cc-option, -mno-global-merge,)
KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior)
KBUILD_CFLAGS += $(call cc-disable-warning, deprecated-non-prototype)
+else
+
+# These warnings generated too much noise in a regular build.
+# Use make W=1 to enable them (see scripts/Makefile.extrawarn)
+KBUILD_CFLAGS += -Wno-unused-but-set-variable
endif
# These warnings generated too much noise in a regular build.
@@ -864,6 +1007,7 @@ cpp_flags := $(KBUILD_CPPFLAGS) $(PLATFORM_CPPFLAGS) $(UBOOTINCLUDE) \
$(NOSTDINC_FLAGS)
c_flags := $(KBUILD_CFLAGS) $(cpp_flags)
+
#########################################################################
# U-Boot objects....order is important (i.e. start must be first)
@@ -912,7 +1056,15 @@ u-boot-dirs := $(patsubst %/,%,$(filter %/, $(libs-y))) tools examples
u-boot-alldirs := $(sort $(u-boot-dirs) $(patsubst %/,%,$(filter %/, $(libs-))))
-libs-y := $(patsubst %/, %/built-in.o, $(libs-y))
+libs-y := $(patsubst %/, %/built-in.a, $(libs-y))
+# Not needed in U-Boot
+#init-y := $(patsubst %/, %/built-in.a, $(init-y))
+#core-y := $(patsubst %/, %/built-in.a, $(core-y))
+drivers-y := $(patsubst %/, %/built-in.a, $(drivers-y))
+#net-y := $(patsubst %/, %/built-in.a, $(net-y))
+libs-y1 := $(patsubst %/, %/lib.a, $(libs-y))
+libs-y2 := $(patsubst %/, %/built-in.a, $(filter-out %.a, $(libs-y)))
+#virt-y := $(patsubst %/, %/built-in.a, $(virt-y))
u-boot-init := $(head-y)
u-boot-main := $(libs-y)
@@ -1031,6 +1183,37 @@ INPUTS-$(CONFIG_ARCH_MEDIATEK) += u-boot-mtk.bin
endif
endif
+ifdef CONFIG_FUNCTION_TRACER
+ifdef CONFIG_FTRACE_MCOUNT_RECORD
+ # gcc 5 supports generating the mcount tables directly
+ ifeq ($(call cc-option-yn,-mrecord-mcount),y)
+ CC_FLAGS_FTRACE += -mrecord-mcount
+ export CC_USING_RECORD_MCOUNT := 1
+ endif
+ ifdef CONFIG_HAVE_NOP_MCOUNT
+ ifeq ($(call cc-option-yn, -mnop-mcount),y)
+ CC_FLAGS_FTRACE += -mnop-mcount
+ CC_FLAGS_USING += -DCC_USING_NOP_MCOUNT
+ endif
+ endif
+endif
+ifdef CONFIG_HAVE_FENTRY
+ ifeq ($(call cc-option-yn, -mfentry),y)
+ CC_FLAGS_FTRACE += -mfentry
+ CC_FLAGS_USING += -DCC_USING_FENTRY
+ endif
+endif
+export CC_FLAGS_FTRACE
+KBUILD_CFLAGS += $(CC_FLAGS_FTRACE) $(CC_FLAGS_USING)
+KBUILD_AFLAGS += $(CC_FLAGS_USING)
+ifdef CONFIG_DYNAMIC_FTRACE
+ ifdef CONFIG_HAVE_C_RECORDMCOUNT
+ BUILD_C_RECORDMCOUNT := y
+ export BUILD_C_RECORDMCOUNT
+ endif
+endif
+endif
+
# Add optional build target if defined in board/cpu/soc headers
ifneq ($(CONFIG_BUILD_TARGET),)
INPUTS-y += $(CONFIG_BUILD_TARGET:"%"=%)
@@ -1076,6 +1259,15 @@ quiet_cmd_objcopy = OBJCOPY $@
cmd_objcopy = $(OBJCOPY) --gap-fill=0xff $(OBJCOPYFLAGS) \
$(OBJCOPYFLAGS_$(@F)) $< $@
+# disable pointer signed / unsigned warnings in gcc 4.0
+KBUILD_CFLAGS += -Wno-pointer-sign
+
+# disable stringop warnings in gcc 8+
+KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation)
+
+# disable invalid "can't wrap" optimizations for signed / pointers
+KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow)
+
# Provide a version which does not do this, for use by EFI and hex/srec
quiet_cmd_zobjcopy = OBJCOPY $@
cmd_zobjcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
@@ -1216,7 +1408,7 @@ FINAL_DTB_CONTAINER = fit-dtb.blob
endif
fit-dtb.blob.gz: fit-dtb.blob
- @gzip -kf9 $< > $@
+ @gzip -nkf9 $< > $@
fit-dtb.blob.lzo: fit-dtb.blob
@lzop -f9 $< > $@
@@ -1392,17 +1584,17 @@ ifneq ($(EXT_DTB),)
ext_dtb_list := $(basename $(notdir $(EXT_DTB)))
default_dt := $(firstword $(ext_dtb_list))
of_list := "$(ext_dtb_list)"
-of_list_dirs := $(dir $(EXT_DTB))
+of_list_dirs := $(dir $(EXT_DTB)) $(dt_dir)
else
of_list := $(CONFIG_OF_LIST)
-ifneq ($(CONFIG_OF_UPSTREAM_INCLUDE_LOCAL_FALLBACK_DTBOS),)
-of_list_dirs := $(dt_dir) arch/$(ARCH)/dts
-else
of_list_dirs := $(dt_dir)
-endif
default_dt := $(if $(DEVICE_TREE),$(DEVICE_TREE),$(CONFIG_DEFAULT_DEVICE_TREE))
endif
+ifneq ($(CONFIG_OF_UPSTREAM_INCLUDE_LOCAL_FALLBACK_DTBOS),)
+of_list_dirs += arch/$(ARCH)/dts
+endif
+
binman_dtb := $(shell echo $(CONFIG_BINMAN_DTB))
ifeq ($(strip $(binman_dtb)),)
ifeq ($(CONFIG_OF_EMBED),y)
@@ -1927,7 +2119,7 @@ $(sort $(u-boot-init) $(u-boot-main)): $(u-boot-dirs) ;
PHONY += $(u-boot-dirs)
$(u-boot-dirs): prepare
- $(Q)$(MAKE) $(build)=$@
+ $(Q)$(MAKE) $(build)=$@ need-builtin=1
tools: prepare
# The "tools" are needed early
@@ -1946,7 +2138,12 @@ endef
# Store (new) UBOOTRELEASE string in include/config/uboot.release
include/config/uboot.release: include/config/auto.conf FORCE
$(call filechk,uboot.release)
-
+# Additional helpers built in scripts/
+# Carefully list dependencies so we do not try to build scripts twice
+# in parallel
+PHONY += scripts
+scripts: scripts_basic scripts_dtc
+ $(Q)$(MAKE) $(build)=$(@)
# Things we need to do before we recursively start building the kernel
# or the modules are listed in "prepare".
@@ -1954,7 +2151,6 @@ include/config/uboot.release: include/config/auto.conf FORCE
# archprepare is used in arch Makefiles and when processed asm symlink,
# version.h and scripts_basic is processed / created.
-# Listed in dependency order
PHONY += prepare archprepare prepare1 prepare3
# prepare3 is used to check if we are building in a separate output directory,
@@ -1982,14 +2178,35 @@ prepare1: $(defaultenv_h)
envtools: $(defaultenv_h)
endif
-
archprepare: prepare1 scripts
-prepare0: archprepare FORCE
+prepare0: archprepare
$(Q)$(MAKE) $(build)=.
# All the preparing..
-prepare: prepare0
+prepare: prepare0 prepare-objtool
+
+# Support for using generic headers in asm-generic
+asm-generic := -f $(srctree)/scripts/Makefile.asm-generic obj
+
+PHONY += asm-generic uapi-asm-generic
+asm-generic: uapi-asm-generic
+ $(Q)$(MAKE) $(asm-generic)=arch/$(SRCARCH)/include/generated/asm \
+ generic=include/asm-generic
+uapi-asm-generic:
+ $(Q)$(MAKE) $(asm-generic)=arch/$(SRCARCH)/include/generated/uapi/asm \
+ generic=include/uapi/asm-generic
+
+PHONY += prepare-objtool
+prepare-objtool: $(objtool_target)
+ifeq ($(SKIP_STACK_VALIDATION),1)
+ifdef CONFIG_UNWINDER_ORC
+ @echo "error: Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
+ @false
+else
+ @echo "warning: Cannot use CONFIG_STACK_VALIDATION=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
+endif
+endif
# Generate some files
# ---------------------------------------------------------------------------
@@ -2072,13 +2289,20 @@ ifneq ($(dtstree),)
%.dtb: prepare3 scripts_dtc
$(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@
-PHONY += dtbs dtbs_install
-dtbs: prepare3 scripts_dtc
+PHONY += dtbs dtbs_install dt_binding_check
+dtbs dtbs_check: prepare3 scripts_dtc
$(Q)$(MAKE) $(build)=$(dtstree)
+dtbs_check: export CHECK_DTBS=1
+dtbs_check: dt_binding_check
+
dtbs_install:
$(Q)$(MAKE) $(dtbinst)=$(dtstree)
+ifdef CONFIG_OF_EARLY_FLATTREE
+all: dtbs
+endif
+
endif
# Check dtc and pylibfdt, if DTC is provided, else build them
@@ -2180,8 +2404,6 @@ SYSTEM_MAP = \
System.map: u-boot
@$(call SYSTEM_MAP,$<) > $@
-#########################################################################
-
# ARM relocations should all be R_ARM_RELATIVE (32-bit) or
# R_AARCH64_RELATIVE (64-bit).
checkarmreloc: u-boot
@@ -2255,9 +2477,7 @@ MRPROPER_FILES += .config .config.old include/autoconf.mk* include/config.h \
#
clean: rm-dirs := $(CLEAN_DIRS)
clean: rm-files := $(CLEAN_FILES)
-
clean-dirs := $(foreach f,$(u-boot-alldirs),$(if $(wildcard $(srctree)/$f/Makefile),$f))
-
clean-dirs := $(addprefix _clean_, $(clean-dirs))
PHONY += $(clean-dirs) clean archclean
@@ -2465,11 +2685,25 @@ checkstack:
$(OBJDUMP) -d u-boot $$(find . -name u-boot-spl) | \
$(PERL) $(src)/scripts/checkstack.pl $(ARCH)
+ubootversion:
+ @echo $(UBOOTVERSION)
+
ubootrelease:
@$(filechk_uboot.release)
-ubootversion:
- @echo $(UBOOTVERSION)
+# Clear a bunch of variables before executing the submake
+
+ifeq ($(quiet),silent_)
+tools_silent=s
+endif
+
+tools/: FORCE
+ $(Q)mkdir -p $(objtree)/tools
+ $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(abspath $(objtree)) subdir=tools -C $(src)/tools/
+
+tools/%: FORCE
+ $(Q)mkdir -p $(objtree)/tools
+ $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(abspath $(objtree)) subdir=tools -C $(src)/tools/ $*
# Single targets
# ---------------------------------------------------------------------------
@@ -2481,41 +2715,32 @@ ubootversion:
# target-dir => where to store outputfile
# build-dir => directory in kernel source tree to use
-ifeq ($(KBUILD_EXTMOD),)
- build-dir = $(patsubst %/,%,$(dir $@))
- target-dir = $(dir $@)
-else
- zap-slash=$(filter-out .,$(patsubst %/,%,$(dir $@)))
- build-dir = $(KBUILD_EXTMOD)$(if $(zap-slash),/$(zap-slash))
- target-dir = $(if $(KBUILD_EXTMOD),$(dir $<),$(dir $@))
-endif
-
-%.s: %.c prepare FORCE
- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
-%.i: %.c prepare FORCE
- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
-%.o: %.c prepare FORCE
- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
-%.lst: %.c prepare FORCE
- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
-%.s: %.S prepare FORCE
- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
-%.o: %.S prepare FORCE
- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
-%.symtypes: %.c prepare FORCE
- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+build-target = $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD)/)$@
+build-dir = $(patsubst %/,%,$(dir $(build-target)))
+
+%.i: prepare FORCE
+ $(Q)$(MAKE) $(build)=$(build-dir) $(build-target)
+%.ll: prepare FORCE
+ $(Q)$(MAKE) $(build)=$(build-dir) $(build-target)
+%.lst: prepare FORCE
+ $(Q)$(MAKE) $(build)=$(build-dir) $(build-target)
+%.o: prepare FORCE
+ $(Q)$(MAKE) $(build)=$(build-dir) $(build-target)
+%.s: prepare FORCE
+ $(Q)$(MAKE) $(build)=$(build-dir) $(build-target)
+%.symtypes: prepare FORCE
+ $(Q)$(MAKE) $(build)=$(build-dir) $(build-target)
+%.ko: %.o
+ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
# Modules
-/: prepare FORCE
- $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
- $(build)=$(build-dir)
+PHONY += /
+/: ./
+
+# Make sure the latest headers are built for Documentation
+Documentation/ samples/: headers_install
%/: prepare FORCE
- $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
- $(build)=$(build-dir)
-%.ko: prepare FORCE
- $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
- $(build)=$(build-dir) $(@:.ko=.o)
- $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
+ $(Q)$(MAKE) KBUILD_MODULES=1 $(build)=$(build-dir)
quiet_cmd_genenv = GENENV $@
cmd_genenv = \
@@ -2544,15 +2769,24 @@ quiet_cmd_rmdirs = $(if $(wildcard $(rm-dirs)),CLEAN $(wildcard $(rm-dirs)))
quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN $(wildcard $(rm-files)))
cmd_rmfiles = rm -f $(rm-files)
+# Run depmod only if we have System.map and depmod is executable
+quiet_cmd_depmod = DEPMOD $(KERNELRELEASE)
+ cmd_depmod = $(CONFIG_SHELL) $(srctree)/scripts/depmod.sh $(DEPMOD) \
+ $(KERNELRELEASE)
+
+# Create temporary dir for module support files
+# clean it up only when building all modules
+cmd_crmodverdir = $(Q)mkdir -p $(MODVERDIR) \
+ $(if $(KBUILD_MODULES),; rm -f $(MODVERDIR)/*)
+
# read saved command lines for existing targets
existing-targets := $(wildcard $(sort $(targets)))
-cmd_files := $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd)
-$(cmd_files): ; # Do not try to update included dependency files
--include $(cmd_files)
-endif #ifeq ($(config-targets),1)
-endif #ifeq ($(mixed-targets),1)
-endif # sub_make_done
+-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd)
+
+endif # ifeq ($(config-targets),1)
+endif # ifeq ($(mixed-targets),1)
+endif # need-sub-make
PHONY += FORCE
FORCE:
diff --git a/arch/Kconfig b/arch/Kconfig
index 597b40ffd60..7e05e0c2263 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -220,6 +220,7 @@ config SANDBOX
imply BITREVERSE
select BLOBLIST
imply LTO
+ imply CMD_BOOTEFI_SELFTEST
imply CMD_DM
imply CMD_EXCEPTION
imply CMD_GETTIME
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index da67f20675a..9ed55e6cfac 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -108,6 +108,18 @@ config LNX_KRNL_IMG_TEXT_OFFSET_BASE
The value subtracted from CONFIG_TEXT_BASE to calculate the
TEXT_OFFSET value written to the Linux kernel image header.
+config KVM_VIRT_INS
+ bool "Emit virtualizable instructions"
+ help
+ Instructions in the ARM ISA that have multiple output registers,
+ can't be used if the instruction leads to an exception to the hypervisor.
+ These instructions cannot be emulated by KVM because they do not produce
+ syndrome information data that KVM can use to infer the destination
+ register, the faulting address, whether it was a load or store,
+ if it's a 32 or 64 bit general-purpose register amongst other things.
+ Use this to produce virtualizable instructions if you plan to run U-Boot
+ with KVM.
+
config NVIC
bool
@@ -821,6 +833,7 @@ config ARCH_K3
select FIT
select REGEX
select FIT_SIGNATURE if ARM64
+ select LTO
imply TI_SECURE_DEVICE
config ARCH_OMAP2PLUS
@@ -1126,6 +1139,7 @@ config ARCH_SNAPDRAGON
select LINUX_KERNEL_IMAGE_HEADER if !ENABLE_ARM_SOC_BOOT0_HOOK
select SYSRESET
select SYSRESET_PSCI
+ select ANDROID_BOOT_IMAGE_IGNORE_BLOB_ADDR
imply OF_UPSTREAM
imply CMD_DM
imply DM_USB_GADGET
diff --git a/arch/arm/cpu/armv8/fel_utils.S b/arch/arm/cpu/armv8/fel_utils.S
index 044a7c16cc5..6a7ec9a7ec1 100644
--- a/arch/arm/cpu/armv8/fel_utils.S
+++ b/arch/arm/cpu/armv8/fel_utils.S
@@ -41,7 +41,7 @@ ENTRY(return_to_fel)
str w2, [x1]
ldr w0, =0xfa50392f // CPU hotplug magic
-#ifdef CONFIG_MACH_SUN50I_H616
+#if defined(CONFIG_MACH_SUN50I_H616) || defined(CONFIG_MACH_SUN50I_A133)
ldr w2, =(SUNXI_R_CPUCFG_BASE + 0x1c0)
str w0, [x2], #0x4
#elif CONFIG_MACH_SUN50I_H6
diff --git a/arch/arm/dts/imx8ulp-evk-u-boot.dtsi b/arch/arm/dts/imx8ulp-evk-u-boot.dtsi
index f67fe166d31..845fe205925 100644
--- a/arch/arm/dts/imx8ulp-evk-u-boot.dtsi
+++ b/arch/arm/dts/imx8ulp-evk-u-boot.dtsi
@@ -28,7 +28,6 @@
&iomuxc1 {
bootph-pre-ram;
- fsl,mux_mask = <0xf00>;
};
&pinctrl_lpuart5 {
diff --git a/arch/arm/dts/imxrt1020.dtsi b/arch/arm/dts/imxrt1020.dtsi
index 13511ebb18e..336aeedb2ce 100644
--- a/arch/arm/dts/imxrt1020.dtsi
+++ b/arch/arm/dts/imxrt1020.dtsi
@@ -64,7 +64,6 @@
iomuxc: iomuxc@401f8000 {
compatible = "fsl,imxrt-iomuxc";
reg = <0x401f8000 0x4000>;
- fsl,mux_mask = <0x7>;
};
anatop: anatop@400d8000 {
diff --git a/arch/arm/dts/imxrt1170.dtsi b/arch/arm/dts/imxrt1170.dtsi
index 08665eaf06a..7566402353a 100644
--- a/arch/arm/dts/imxrt1170.dtsi
+++ b/arch/arm/dts/imxrt1170.dtsi
@@ -77,7 +77,6 @@
iomuxc: iomuxc@400e8000 {
compatible = "fsl,imxrt-iomuxc";
reg = <0x400e8000 0x4000>;
- fsl,mux_mask = <0x7>;
};
anatop: anatop@40c84000 {
diff --git a/arch/arm/dts/ipq5424-rdp466-u-boot.dtsi b/arch/arm/dts/ipq5424-rdp466-u-boot.dtsi
new file mode 100644
index 00000000000..9e4af4d9f72
--- /dev/null
+++ b/arch/arm/dts/ipq5424-rdp466-u-boot.dtsi
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IPQ5424 RDP466 board device tree source
+ *
+ * Copyright (c) 2025 The Linux Foundation. All rights reserved.
+ */
+
+/ {
+ /* Will be removed when SMEM parsing is updated */
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x0 0x20000000>;
+ };
+
+};
+
+ &sdhc {
+ sdhci-caps-mask = <0x0 0x04000000>;
+ sdhci-caps = <0x0 0x04000000>; /* SDHCI_CAN_VDD_180 */
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ max-frequency = <192000000>;
+ bus-width = <4>;
+ pinctrl-0 = <&sdc_default_state>;
+ pinctrl-names = "default";
+ non-removable;
+
+ /*
+ * This reset is needed to clear out the settings done by
+ * previous boot loader. Without this the SDHCI_RESET_ALL
+ * reset done sdhci_init() times out.
+ */
+ resets = <&gcc GCC_SDCC_BCR>;
+
+ status = "okay";
+ };
+
diff --git a/arch/arm/dts/k3-am625-phycore-som-binman.dtsi b/arch/arm/dts/k3-am625-phycore-som-binman.dtsi
index 32d8804a395..6deebdadf09 100644
--- a/arch/arm/dts/k3-am625-phycore-som-binman.dtsi
+++ b/arch/arm/dts/k3-am625-phycore-som-binman.dtsi
@@ -400,11 +400,105 @@
};
&binman {
+ tifsstub-hs {
+ filename = "tifsstub.bin_hs";
+ ti-secure-rom {
+ content = <&tifsstub_hs_cert>;
+ core = "secure";
+ load = <0x40000>;
+ sw-rev = <CONFIG_K3_X509_SWRV>;
+ keyfile = "custMpk.pem";
+ countersign;
+ tifsstub;
+ };
+ tifsstub_hs_cert: tifsstub-hs-cert.bin {
+ filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-cert.bin";
+ type = "blob-ext";
+ optional;
+ };
+ tifsstub_hs_enc: tifsstub-hs-enc.bin {
+ filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-enc.bin";
+ type = "blob-ext";
+ optional;
+ };
+ };
+
+ tifsstub-fs {
+ filename = "tifsstub.bin_fs";
+ tifsstub_fs_cert: tifsstub-fs-cert.bin {
+ filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-cert.bin";
+ type = "blob-ext";
+ optional;
+ };
+ tifsstub_fs_enc: tifsstub-fs-enc.bin {
+ filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-enc.bin";
+ type = "blob-ext";
+ optional;
+ };
+
+ };
+
+ tifsstub-gp {
+ filename = "tifsstub.bin_gp";
+ ti-secure-rom {
+ content = <&tifsstub_gp>;
+ core = "secure";
+ load = <0x60000>;
+ sw-rev = <CONFIG_K3_X509_SWRV>;
+ keyfile = "ti-degenerate-key.pem";
+ tifsstub;
+ };
+ tifsstub_gp: tifsstub-gp.bin {
+ filename = "ti-sysfw/ti-fs-stub-firmware-am62x-gp.bin";
+ type = "blob-ext";
+ optional;
+ };
+ };
+
ti-spl_unsigned {
insert-template = <&ti_spl_unsigned_template>;
fit {
images {
+ tifsstub-hs {
+ description = "TIFSSTUB";
+ type = "firmware";
+ arch = "arm32";
+ compression = "none";
+ os = "tifsstub-hs";
+ load = <0x9dc00000>;
+ entry = <0x9dc00000>;
+ blob-ext {
+ filename = "tifsstub.bin_hs";
+ };
+ };
+
+ tifsstub-fs {
+ description = "TIFSSTUB";
+ type = "firmware";
+ arch = "arm32";
+ compression = "none";
+ os = "tifsstub-fs";
+ load = <0x9dc00000>;
+ entry = <0x9dc00000>;
+ blob-ext {
+ filename = "tifsstub.bin_fs";
+ };
+ };
+
+ tifsstub-gp {
+ description = "TIFSSTUB";
+ type = "firmware";
+ arch = "arm32";
+ compression = "none";
+ os = "tifsstub-gp";
+ load = <0x9dc00000>;
+ entry = <0x9dc00000>;
+ blob-ext {
+ filename = "tifsstub.bin_gp";
+ };
+ };
+
dm {
ti-dm {
filename = "ti-dm/am62xx/ipc_echo_testb_mcu1_0_release_strip.xer5f";
diff --git a/arch/arm/dts/qcs615-ride-u-boot.dtsi b/arch/arm/dts/qcs615-ride-u-boot.dtsi
new file mode 100644
index 00000000000..68fffc70fcb
--- /dev/null
+++ b/arch/arm/dts/qcs615-ride-u-boot.dtsi
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/ {
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x0 0x7a00000>,
+ <0x0 0x89600000 0x0 0x30100000>,
+ <0x0 0xc0000000 0x0 0xc0000000>,
+ <0x1 0x80000000 0x1 0x00000000>;
+ };
+};
diff --git a/arch/arm/dts/qcs8300-ride-u-boot.dtsi b/arch/arm/dts/qcs8300-ride-u-boot.dtsi
new file mode 100644
index 00000000000..8c353ace71e
--- /dev/null
+++ b/arch/arm/dts/qcs8300-ride-u-boot.dtsi
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/ {
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x0 0x11a80000>,
+ <0x0 0xc0000000 0x0 0x10000000>,
+ <0x0 0xd3100000 0x0 0x26b00000>,
+ <0xe 0x80000000 0x1 0x00000000>,
+ <0xa 0x80000000 0x1 0x80000000>,
+ <0x0 0xb0800000 0x0 0x0f200000>,
+ <0x0 0xd0100000 0x0 0x01800000>,
+ <0x0 0x91b00000 0x0 0x1e500000>;
+ };
+};
+
diff --git a/arch/arm/dts/versal-mini-emmc0.dts b/arch/arm/dts/versal-mini-emmc0.dts
index 179060c56ee..9044ef1889b 100644
--- a/arch/arm/dts/versal-mini-emmc0.dts
+++ b/arch/arm/dts/versal-mini-emmc0.dts
@@ -28,28 +28,20 @@
bootph-all;
};
- amba: axi {
- bootph-all;
- compatible = "simple-bus";
- #address-cells = <0x2>;
- #size-cells = <0x2>;
- ranges;
-
- sdhci0: sdhci@f1040000 {
- compatible = "xlnx,versal-8.9a", "arasan,sdhci-8.9a";
- status = "okay";
- non-removable;
- disable-wp;
- no-sd;
- no-sdio;
- cap-mmc-hw-reset;
- bus-width = <8>;
- reg = <0x0 0xf1040000 0x0 0x10000>;
- clock-names = "clk_xin", "clk_ahb";
- clocks = <&clk200 &clk200>;
- no-1-8-v;
- xlnx,mio-bank = <0>;
- };
+ sdhci0: sdhci@f1040000 {
+ compatible = "xlnx,versal-8.9a", "arasan,sdhci-8.9a";
+ status = "okay";
+ non-removable;
+ disable-wp;
+ no-sd;
+ no-sdio;
+ cap-mmc-hw-reset;
+ bus-width = <8>;
+ reg = <0x0 0xf1040000 0x0 0x10000>;
+ clock-names = "clk_xin", "clk_ahb";
+ clocks = <&clk200 &clk200>;
+ no-1-8-v;
+ xlnx,mio-bank = <0>;
};
aliases {
diff --git a/arch/arm/dts/versal-mini-emmc1.dts b/arch/arm/dts/versal-mini-emmc1.dts
index ffcc3334529..47f3b74c065 100644
--- a/arch/arm/dts/versal-mini-emmc1.dts
+++ b/arch/arm/dts/versal-mini-emmc1.dts
@@ -28,28 +28,20 @@
bootph-all;
};
- amba: axi {
- bootph-all;
- compatible = "simple-bus";
- #address-cells = <0x2>;
- #size-cells = <0x2>;
- ranges;
-
- sdhci1: sdhci@f1050000 {
- compatible = "xlnx,versal-8.9a", "arasan,sdhci-8.9a";
- status = "okay";
- non-removable;
- disable-wp;
- no-sd;
- no-sdio;
- cap-mmc-hw-reset;
- bus-width = <8>;
- reg = <0x0 0xf1050000 0x0 0x10000>;
- clock-names = "clk_xin", "clk_ahb";
- clocks = <&clk200 &clk200>;
- no-1-8-v;
- xlnx,mio-bank = <0>;
- };
+ sdhci1: sdhci@f1050000 {
+ compatible = "xlnx,versal-8.9a", "arasan,sdhci-8.9a";
+ status = "okay";
+ non-removable;
+ disable-wp;
+ no-sd;
+ no-sdio;
+ cap-mmc-hw-reset;
+ bus-width = <8>;
+ reg = <0x0 0xf1050000 0x0 0x10000>;
+ clock-names = "clk_xin", "clk_ahb";
+ clocks = <&clk200 &clk200>;
+ no-1-8-v;
+ xlnx,mio-bank = <0>;
};
aliases {
diff --git a/arch/arm/dts/versal-mini-ospi.dtsi b/arch/arm/dts/versal-mini-ospi.dtsi
index 9ca0cf3c027..eec2a08e7c7 100644
--- a/arch/arm/dts/versal-mini-ospi.dtsi
+++ b/arch/arm/dts/versal-mini-ospi.dtsi
@@ -28,37 +28,29 @@
bootph-all;
};
- amba: axi {
- bootph-all;
- compatible = "simple-bus";
- #address-cells = <0x2>;
- #size-cells = <0x2>;
- ranges;
-
- ospi: spi@f1010000 {
- compatible = "cdns,qspi-nor";
- status = "okay";
- reg = <0 0xf1010000 0 0x10000 0 0xc0000000 0 0x20000000>;
- clock-names = "ref_clk", "pclk";
- clocks = <&clk125 &clk125>;
- bus-num = <2>;
- num-cs = <1>;
- cdns,fifo-depth = <256>;
- cdns,fifo-width = <4>;
- cdns,is-dma = <1>;
- cdns,trigger-address = <0xc0000000>;
- #address-cells = <1>;
- #size-cells = <0>;
+ ospi: spi@f1010000 {
+ compatible = "cdns,qspi-nor";
+ status = "okay";
+ reg = <0 0xf1010000 0 0x10000 0 0xc0000000 0 0x20000000>;
+ clock-names = "ref_clk", "pclk";
+ clocks = <&clk125 &clk125>;
+ bus-num = <2>;
+ num-cs = <1>;
+ cdns,fifo-depth = <256>;
+ cdns,fifo-width = <4>;
+ cdns,is-dma = <1>;
+ cdns,trigger-address = <0xc0000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- flash0: flash@0 {
- compatible = "n25q512a", "micron,m25p80",
- "jedec,spi-nor";
- reg = <0x0>;
- spi-tx-bus-width = <8>;
- spi-rx-bus-width = <8>;
- spi-max-frequency = <20000000>;
- no-wp;
- };
+ flash0: flash@0 {
+ compatible = "n25q512a", "micron,m25p80",
+ "jedec,spi-nor";
+ reg = <0x0>;
+ spi-tx-bus-width = <8>;
+ spi-rx-bus-width = <8>;
+ spi-max-frequency = <20000000>;
+ no-wp;
};
};
diff --git a/arch/arm/dts/versal-mini-qspi.dtsi b/arch/arm/dts/versal-mini-qspi.dtsi
index 57427e099f9..ec4eef74020 100644
--- a/arch/arm/dts/versal-mini-qspi.dtsi
+++ b/arch/arm/dts/versal-mini-qspi.dtsi
@@ -28,31 +28,23 @@
bootph-all;
};
- amba: axi {
- bootph-all;
- compatible = "simple-bus";
- #address-cells = <0x2>;
- #size-cells = <0x2>;
- ranges;
-
- qspi: spi@f1030000 {
- compatible = "xlnx,versal-qspi-1.0";
- status = "okay";
- clock-names = "ref_clk", "pclk";
- num-cs = <0x1>;
- reg = <0x0 0xf1030000 0x0 0x1000>;
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&clk150 &clk150>;
+ qspi: spi@f1030000 {
+ compatible = "xlnx,versal-qspi-1.0";
+ status = "okay";
+ clock-names = "ref_clk", "pclk";
+ num-cs = <0x1>;
+ reg = <0x0 0xf1030000 0x0 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clk150 &clk150>;
- flash0: flash@0 {
- compatible = "n25q512a", "micron,m25p80",
- "jedec,spi-nor";
- reg = <0x0>;
- spi-tx-bus-width = <4>;
- spi-rx-bus-width = <4>;
- spi-max-frequency = <20000000>;
- };
+ flash0: flash@0 {
+ compatible = "n25q512a", "micron,m25p80",
+ "jedec,spi-nor";
+ reg = <0x0>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ spi-max-frequency = <20000000>;
};
};
diff --git a/arch/arm/dts/versal-net-mini-emmc.dts b/arch/arm/dts/versal-net-mini-emmc.dts
index 20e4e299404..567ceeb36a0 100644
--- a/arch/arm/dts/versal-net-mini-emmc.dts
+++ b/arch/arm/dts/versal-net-mini-emmc.dts
@@ -2,7 +2,7 @@
/*
* dts file for Xilinx Versal NET Mini eMMC Configuration
*
- * (C) Copyright 2023, Advanced Micro Devices, Inc.
+ * (C) Copyright 2023-2025, Advanced Micro Devices, Inc.
*
* Michal Simek <michal.simek@amd.com>
* Ashok Reddy Soma <ashok.reddy.soma@amd.com>
@@ -42,26 +42,18 @@
bootph-all;
};
- amba: axi {
- bootph-all;
- compatible = "simple-bus";
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- sdhci1: mmc@f1050000 {
- compatible = "xlnx,versal-net-emmc";
- status = "okay";
- non-removable;
- disable-wp;
- no-sd;
- no-sdio;
- cap-mmc-hw-reset;
- bus-width = <8>;
- reg = <0 0xf1050000 0 0x10000>;
- clock-names = "clk_xin", "clk_ahb";
- clocks = <&clk200>, <&clk200>;
- xlnx,mio-bank = <0>;
- };
+ sdhci1: mmc@f1050000 {
+ compatible = "xlnx,versal-net-emmc";
+ status = "okay";
+ non-removable;
+ disable-wp;
+ no-sd;
+ no-sdio;
+ cap-mmc-hw-reset;
+ bus-width = <8>;
+ reg = <0 0xf1050000 0 0x10000>;
+ clock-names = "clk_xin", "clk_ahb";
+ clocks = <&clk200>, <&clk200>;
+ xlnx,mio-bank = <0>;
};
};
diff --git a/arch/arm/dts/versal-net-mini-ospi.dtsi b/arch/arm/dts/versal-net-mini-ospi.dtsi
index a9bf7cc4248..1c94b352dc9 100644
--- a/arch/arm/dts/versal-net-mini-ospi.dtsi
+++ b/arch/arm/dts/versal-net-mini-ospi.dtsi
@@ -2,7 +2,7 @@
/*
* dts file for Xilinx Versal NET Mini OSPI Configuration
*
- * (C) Copyright 2023, Advanced Micro Devices, Inc.
+ * (C) Copyright 2023-2025, Advanced Micro Devices, Inc.
*
* Michal Simek <michal.simek@amd.com>
* Ashok Reddy Soma <ashok.reddy.soma@amd.com>
@@ -42,38 +42,30 @@
bootph-all;
};
- amba: axi {
- bootph-all;
- compatible = "simple-bus";
- #address-cells = <0x2>;
- #size-cells = <0x2>;
- ranges;
-
- ospi: spi@f1010000 {
- compatible = "cdns,qspi-nor";
- status = "okay";
- reg = <0 0xf1010000 0 0x10000>, <0 0xc0000000 0 0x20000000>;
- clock-names = "ref_clk", "pclk";
- clocks = <&clk125>, <&clk125>;
- bus-num = <2>;
- num-cs = <1>;
- cdns,fifo-depth = <256>;
- cdns,fifo-width = <4>;
- cdns,is-dma = <1>;
- cdns,is-stig-pgm = <1>;
- cdns,trigger-address = <0xc0000000>;
- #address-cells = <1>;
- #size-cells = <0>;
+ ospi: spi@f1010000 {
+ compatible = "cdns,qspi-nor";
+ status = "okay";
+ reg = <0 0xf1010000 0 0x10000>, <0 0xc0000000 0 0x20000000>;
+ clock-names = "ref_clk", "pclk";
+ clocks = <&clk125>, <&clk125>;
+ bus-num = <2>;
+ num-cs = <1>;
+ cdns,fifo-depth = <256>;
+ cdns,fifo-width = <4>;
+ cdns,is-dma = <1>;
+ cdns,is-stig-pgm = <1>;
+ cdns,trigger-address = <0xc0000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- flash0: flash@0 {
- compatible = "mt35xu02g", "micron,m25p80",
- "jedec,spi-nor";
- reg = <0>;
- spi-tx-bus-width = <8>;
- spi-rx-bus-width = <8>;
- spi-max-frequency = <20000000>;
- no-wp;
- };
+ flash0: flash@0 {
+ compatible = "mt35xu02g", "micron,m25p80",
+ "jedec,spi-nor";
+ reg = <0>;
+ spi-tx-bus-width = <8>;
+ spi-rx-bus-width = <8>;
+ spi-max-frequency = <20000000>;
+ no-wp;
};
};
};
diff --git a/arch/arm/dts/versal-net-mini-qspi.dtsi b/arch/arm/dts/versal-net-mini-qspi.dtsi
index e29a3f36d6e..97cc39c73e0 100644
--- a/arch/arm/dts/versal-net-mini-qspi.dtsi
+++ b/arch/arm/dts/versal-net-mini-qspi.dtsi
@@ -2,7 +2,7 @@
/*
* dts file for Xilinx Versal NET Mini QSPI Configuration
*
- * (C) Copyright 2023, Advanced Micro Devices, Inc.
+ * (C) Copyright 2023-2025, Advanced Micro Devices, Inc.
*
* Michal Simek <michal.simek@amd.com>
* Ashok Reddy Soma <ashok.reddy.soma@amd.com>
@@ -42,31 +42,23 @@
bootph-all;
};
- amba: axi {
- bootph-all;
- compatible = "simple-bus";
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- qspi: spi@f1030000 {
- compatible = "xlnx,versal-qspi-1.0";
- status = "okay";
- clock-names = "ref_clk", "pclk";
- num-cs = <1>;
- reg = <0 0xf1030000 0 0x1000>;
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&clk150>, <&clk150>;
+ qspi: spi@f1030000 {
+ compatible = "xlnx,versal-qspi-1.0";
+ status = "okay";
+ clock-names = "ref_clk", "pclk";
+ num-cs = <1>;
+ reg = <0 0xf1030000 0 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clk150>, <&clk150>;
- flash0: flash@0 {
- compatible = "n25q512a", "micron,m25p80",
- "jedec,spi-nor";
- reg = <0>;
- spi-tx-bus-width = <4>;
- spi-rx-bus-width = <4>;
- spi-max-frequency = <20000000>;
- };
+ flash0: flash@0 {
+ compatible = "n25q512a", "micron,m25p80",
+ "jedec,spi-nor";
+ reg = <0>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ spi-max-frequency = <20000000>;
};
};
};
diff --git a/arch/arm/dts/versal-net-mini.dts b/arch/arm/dts/versal-net-mini.dts
index f98f95a5c2f..0f0a82e3aa3 100644
--- a/arch/arm/dts/versal-net-mini.dts
+++ b/arch/arm/dts/versal-net-mini.dts
@@ -3,7 +3,7 @@
* dts file for Xilinx Versal NET
*
* Copyright (C) 2021 - 2022, Xilinx, Inc.
- * Copyright (C) 2022, Advanced Micro Devices, Inc.
+ * Copyright (C) 2022-2025, Advanced Micro Devices, Inc.
*
* Michal Simek <michal.simek@amd.com>
*/
@@ -45,22 +45,14 @@
bootph-all;
};
- amba: axi {
- compatible = "simple-bus";
+ serial0: serial@f1920000 {
bootph-all;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- serial0: serial@f1920000 {
- bootph-all;
- compatible = "arm,pl011", "arm,primecell";
- reg = <0 0xf1920000 0 0x1000>;
- reg-io-width = <4>;
- clock-names = "uartclk", "apb_pclk";
- clocks = <&clk1>, <&clk1>;
- clock = <1000000>;
- skip-init;
- };
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0 0xf1920000 0 0x1000>;
+ reg-io-width = <4>;
+ clock-names = "uartclk", "apb_pclk";
+ clocks = <&clk1>, <&clk1>;
+ clock = <1000000>;
+ skip-init;
};
};
diff --git a/arch/arm/dts/vf610-pcm052.dtsi b/arch/arm/dts/vf610-pcm052.dtsi
index ccdc0f57e2b..2b82b7313dd 100644
--- a/arch/arm/dts/vf610-pcm052.dtsi
+++ b/arch/arm/dts/vf610-pcm052.dtsi
@@ -244,7 +244,7 @@
qflash0: spi_flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <108000000>;
reg = <0>;
};
@@ -252,7 +252,7 @@
qflash1: spi_flash@1 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <66000000>;
reg = <1>;
};
diff --git a/arch/arm/dts/zynqmp-clk-ccf.dtsi b/arch/arm/dts/zynqmp-clk-ccf.dtsi
index 385fed8a852..52e122fc7c9 100644
--- a/arch/arm/dts/zynqmp-clk-ccf.dtsi
+++ b/arch/arm/dts/zynqmp-clk-ccf.dtsi
@@ -8,7 +8,7 @@
* Michal Simek <michal.simek@amd.com>
*/
-#include <dt-bindings/clock/xlnx-zynqmp-clk.h>
+#include "xlnx-zynqmp-clk.h"
/ {
pss_ref_clk: pss-ref-clk {
bootph-all;
diff --git a/arch/arm/dts/zynqmp-mini-emmc0.dts b/arch/arm/dts/zynqmp-mini-emmc0.dts
index ad4b3c5f8b1..05f61d6bb35 100644
--- a/arch/arm/dts/zynqmp-mini-emmc0.dts
+++ b/arch/arm/dts/zynqmp-mini-emmc0.dts
@@ -41,25 +41,18 @@
clock-frequency = <200000000>;
};
- amba: axi {
- compatible = "simple-bus";
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- sdhci0: mmc@ff160000 {
- bootph-all;
- compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a";
- status = "disabled";
- non-removable;
- no-sd;
- no-sdio;
- cap-mmc-hw-reset;
- bus-width = <8>;
- reg = <0x0 0xff160000 0x0 0x1000>;
- clock-names = "clk_xin", "clk_ahb";
- clocks = <&clk_xin &clk_xin>;
- };
+ sdhci0: mmc@ff160000 {
+ bootph-all;
+ compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a";
+ status = "disabled";
+ non-removable;
+ no-sd;
+ no-sdio;
+ cap-mmc-hw-reset;
+ bus-width = <8>;
+ reg = <0x0 0xff160000 0x0 0x1000>;
+ clock-names = "clk_xin", "clk_ahb";
+ clocks = <&clk_xin &clk_xin>;
};
};
diff --git a/arch/arm/dts/zynqmp-mini-emmc1.dts b/arch/arm/dts/zynqmp-mini-emmc1.dts
index fd421b4fe7e..7857106260e 100644
--- a/arch/arm/dts/zynqmp-mini-emmc1.dts
+++ b/arch/arm/dts/zynqmp-mini-emmc1.dts
@@ -41,25 +41,18 @@
clock-frequency = <200000000>;
};
- amba: axi {
- compatible = "simple-bus";
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- sdhci1: mmc@ff170000 {
- bootph-all;
- compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a";
- status = "disabled";
- non-removable;
- no-sd;
- no-sdio;
- cap-mmc-hw-reset;
- bus-width = <8>;
- reg = <0x0 0xff170000 0x0 0x1000>;
- clock-names = "clk_xin", "clk_ahb";
- clocks = <&clk_xin &clk_xin>;
- };
+ sdhci1: mmc@ff170000 {
+ bootph-all;
+ compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a";
+ status = "disabled";
+ non-removable;
+ no-sd;
+ no-sdio;
+ cap-mmc-hw-reset;
+ bus-width = <8>;
+ reg = <0x0 0xff170000 0x0 0x1000>;
+ clock-names = "clk_xin", "clk_ahb";
+ clocks = <&clk_xin &clk_xin>;
};
};
diff --git a/arch/arm/dts/zynqmp-mini-nand.dts b/arch/arm/dts/zynqmp-mini-nand.dts
index 5e2135158cd..1ece3999791 100644
--- a/arch/arm/dts/zynqmp-mini-nand.dts
+++ b/arch/arm/dts/zynqmp-mini-nand.dts
@@ -35,27 +35,20 @@
bootph-all;
};
- amba: axi {
- compatible = "simple-bus";
- #address-cells = <2>;
- #size-cells = <1>;
- ranges;
-
- nand0: nand@ff100000 {
- compatible = "arasan,nfc-v3p10";
- status = "okay";
- reg = <0x0 0xff100000 0x1000>;
- clock-names = "clk_sys", "clk_flash";
- #address-cells = <1>;
- #size-cells = <0>;
- arasan,has-mdma;
- num-cs = <2>;
- nand@0 {
- reg = <0>;
- #address-cells = <2>;
- #size-cells = <1>;
- nand-ecc-mode = "hw";
- };
+ nand0: nand@ff100000 {
+ compatible = "arasan,nfc-v3p10";
+ status = "okay";
+ reg = <0x0 0xff100000 0x1000>;
+ clock-names = "clk_sys", "clk_flash";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ arasan,has-mdma;
+ num-cs = <2>;
+ nand@0 {
+ reg = <0>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ nand-ecc-mode = "hw";
};
};
};
diff --git a/arch/arm/dts/zynqmp-mini-qspi.dts b/arch/arm/dts/zynqmp-mini-qspi.dts
index 917603dec61..ddcc39b4e94 100644
--- a/arch/arm/dts/zynqmp-mini-qspi.dts
+++ b/arch/arm/dts/zynqmp-mini-qspi.dts
@@ -42,22 +42,15 @@
clock-frequency = <125000000>;
};
- amba: axi {
- compatible = "simple-bus";
- #address-cells = <2>;
- #size-cells = <1>;
- ranges;
-
- qspi: spi@ff0f0000 {
- compatible = "xlnx,zynqmp-qspi-1.0";
- status = "disabled";
- clock-names = "ref_clk", "pclk";
- clocks = <&misc_clk &misc_clk>;
- num-cs = <1>;
- reg = <0x0 0xff0f0000 0x1000 0x0 0xc0000000 0x8000000>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
+ qspi: spi@ff0f0000 {
+ compatible = "xlnx,zynqmp-qspi-1.0";
+ status = "disabled";
+ clock-names = "ref_clk", "pclk";
+ clocks = <&misc_clk &misc_clk>;
+ num-cs = <1>;
+ reg = <0x0 0xff0f0000 0x1000 0x0 0xc0000000 0x8000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
};
};
diff --git a/arch/arm/include/asm/arch-imxrt/gpio.h b/arch/arm/include/asm/arch-imxrt/gpio.h
index da31a7438aa..be130e00652 100644
--- a/arch/arm/include/asm/arch-imxrt/gpio.h
+++ b/arch/arm/include/asm/arch-imxrt/gpio.h
@@ -7,13 +7,6 @@
#ifndef __ASM_ARCH_GPIO_H__
#define __ASM_ARCH_GPIO_H__
-#if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
-/* GPIO registers */
-struct gpio_regs {
- u32 gpio_dr; /* data */
- u32 gpio_dir; /* direction */
- u32 gpio_psr; /* pad satus */
-};
-#endif
+#include <asm/mach-imx/gpio.h>
#endif /* __ASM_ARCH_GPIO_H__ */
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
index ccacc99d018..575dff68804 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
@@ -90,6 +90,13 @@
#define CCM_PLL6_DEFAULT 0xe8216300
#define CCM_PSI_AHB1_AHB2_DEFAULT 0x03000002
#define CCM_APB1_DEFAULT 0x03000102
+
+#elif CONFIG_MACH_SUN50I_A133 /* A133 */
+
+#define CCM_PLL6_DEFAULT 0xb8003100
+#define CCM_PSI_AHB1_AHB2_DEFAULT 0x03000002
+#define CCM_AHB3_DEFAULT 0x03000002
+#define CCM_APB1_DEFAULT 0x03000102
#endif
/* apb2 bit field */
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
index 8a3f465545a..2a9b086991c 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
@@ -29,6 +29,10 @@
#define SUNXI_DRAM_COM_BASE 0x047FA000
#define SUNXI_DRAM_CTL0_BASE 0x047FB000
#define SUNXI_DRAM_PHY0_BASE 0x04800000
+#elif CONFIG_MACH_SUN50I_A133
+#define SUNXI_DRAM_COM_BASE 0x04810000
+#define SUNXI_DRAM_CTL0_BASE 0x04820000
+#define SUNXI_DRAM_PHY0_BASE 0x04830000
#endif
#define SUNXI_TWI0_BASE 0x05002000
diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h
index 9d21b492418..0708ae3ee3b 100644
--- a/arch/arm/include/asm/arch-sunxi/dram.h
+++ b/arch/arm/include/asm/arch-sunxi/dram.h
@@ -31,6 +31,8 @@
#include <asm/arch/dram_sun50i_h6.h>
#elif defined(CONFIG_MACH_SUN50I_H616)
#include <asm/arch/dram_sun50i_h616.h>
+#elif defined(CONFIG_DRAM_SUN50I_A133)
+#include <asm/arch/dram_sun50i_a133.h>
#elif defined(CONFIG_MACH_SUNIV)
#include <asm/arch/dram_suniv.h>
#else
diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun50i_a133.h b/arch/arm/include/asm/arch-sunxi/dram_sun50i_a133.h
new file mode 100644
index 00000000000..a5fc6ad3656
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_a133.h
@@ -0,0 +1,230 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * A133 dram controller register and constant defines
+ *
+ * (C) Copyright 2024 MasterR3C0RD <masterr3c0rd@epochal.quest>
+ */
+
+#ifndef _SUNXI_DRAM_SUN50I_A133_H
+#define _SUNXI_DRAM_SUN50I_A133_H
+
+#include <linux/bitops.h>
+
+enum sunxi_dram_type {
+ SUNXI_DRAM_TYPE_DDR3 = 3,
+ SUNXI_DRAM_TYPE_DDR4,
+ SUNXI_DRAM_TYPE_LPDDR3 = 7,
+ SUNXI_DRAM_TYPE_LPDDR4
+};
+
+static inline int ns_to_t(int nanoseconds)
+{
+ const unsigned int ctrl_freq = CONFIG_DRAM_CLK / 2;
+
+ return DIV_ROUND_UP(ctrl_freq * nanoseconds, 1000);
+}
+
+/* MBUS part is largely the same as in H6, except for one special register */
+#define MCTL_COM_UNK_008 0x008
+/* NOTE: This register has the same importance as mctl_ctl->clken in H616 */
+#define MCTL_COM_MAER0 0x020
+
+/*
+ * Controller registers seems to be the same or at least very similar
+ * to those in H6.
+ */
+struct sunxi_mctl_ctl_reg {
+ u32 mstr; /* 0x000 */
+ u32 statr; /* 0x004 unused */
+ u32 mstr1; /* 0x008 unused */
+ u32 clken; /* 0x00c */
+ u32 mrctrl0; /* 0x010 unused */
+ u32 mrctrl1; /* 0x014 unused */
+ u32 mrstatr; /* 0x018 unused */
+ u32 mrctrl2; /* 0x01c unused */
+ u32 derateen; /* 0x020 unused */
+ u32 derateint; /* 0x024 unused */
+ u8 reserved_0x028[8]; /* 0x028 */
+ u32 pwrctl; /* 0x030 unused */
+ u32 pwrtmg; /* 0x034 unused */
+ u32 hwlpctl; /* 0x038 unused */
+ u8 reserved_0x03c[20]; /* 0x03c */
+ u32 rfshctl0; /* 0x050 unused */
+ u32 rfshctl1; /* 0x054 unused */
+ u8 reserved_0x058[8]; /* 0x05c */
+ u32 rfshctl3; /* 0x060 */
+ u32 rfshtmg; /* 0x064 */
+ u8 reserved_0x068[104]; /* 0x068 */
+ u32 init[8]; /* 0x0d0 */
+ u32 dimmctl; /* 0x0f0 unused */
+ u32 rankctl; /* 0x0f4 */
+ u8 reserved_0x0f8[8]; /* 0x0f8 */
+ u32 dramtmg[17]; /* 0x100 */
+ u8 reserved_0x144[60]; /* 0x144 */
+ u32 zqctl[3]; /* 0x180 */
+ u32 zqstat; /* 0x18c unused */
+ u32 dfitmg0; /* 0x190 */
+ u32 dfitmg1; /* 0x194 */
+ u32 dfilpcfg[2]; /* 0x198 unused */
+ u32 dfiupd[3]; /* 0x1a0 */
+ u32 reserved_0x1ac; /* 0x1ac */
+ u32 dfimisc; /* 0x1b0 */
+ u32 dfitmg2; /* 0x1b4 unused */
+ u32 dfitmg3; /* 0x1b8 unused */
+ u32 dfistat; /* 0x1bc */
+ u32 dbictl; /* 0x1c0 */
+ u8 reserved_0x1c4[60]; /* 0x1c4 */
+ u32 addrmap[12]; /* 0x200 */
+ u8 reserved_0x230[16]; /* 0x230 */
+ u32 odtcfg; /* 0x240 */
+ u32 odtmap; /* 0x244 */
+ u8 reserved_0x248[8]; /* 0x248 */
+ u32 sched[2]; /* 0x250 */
+ u8 reserved_0x258[180]; /* 0x258 */
+ u32 dbgcmd; /* 0x30c unused */
+ u32 dbgstat; /* 0x310 unused */
+ u8 reserved_0x314[12]; /* 0x314 */
+ u32 swctl; /* 0x320 */
+ u32 swstat; /* 0x324 */
+ u8 reserved_0x328[7768]; /* 0x328 */
+ u32 unk_0x2180; /* 0x2180 */
+ u8 reserved_0x2184[188]; /* 0x2184 */
+ u32 unk_0x2240; /* 0x2240 */
+ u8 reserved_0x2244[3900]; /* 0x2244 */
+ u32 unk_0x3180; /* 0x3180 */
+ u8 reserved_0x3184[188]; /* 0x3184 */
+ u32 unk_0x3240; /* 0x3240 */
+ u8 reserved_0x3244[3900]; /* 0x3244 */
+ u32 unk_0x4180; /* 0x4180 */
+ u8 reserved_0x4184[188]; /* 0x4184 */
+ u32 unk_0x4240; /* 0x4240 */
+};
+
+check_member(sunxi_mctl_ctl_reg, swstat, 0x324);
+check_member(sunxi_mctl_ctl_reg, unk_0x4240, 0x4240);
+
+#define MSTR_DEVICETYPE_DDR3 BIT(0)
+#define MSTR_DEVICETYPE_LPDDR2 BIT(2)
+#define MSTR_DEVICETYPE_LPDDR3 BIT(3)
+#define MSTR_DEVICETYPE_DDR4 BIT(4)
+#define MSTR_DEVICETYPE_LPDDR4 BIT(5)
+#define MSTR_DEVICETYPE_MASK GENMASK(5, 0)
+#define MSTR_GEARDOWNMODE BIT(0) /* Same as MSTR_DEVICETYPE_DDR3, only used for DDR4 */
+#define MSTR_2TMODE BIT(10)
+#define MSTR_BUSWIDTH_FULL (0 << 12)
+#define MSTR_BUSWIDTH_HALF (1 << 12)
+#define MSTR_ACTIVE_RANKS(x) (((x == 1) ? 3 : 1) << 24)
+#define MSTR_BURST_LENGTH(x) (((x) >> 1) << 16)
+#define MSTR_DEVICECONFIG_X32 (3 << 30)
+
+#define TPR10_CA_BIT_DELAY BIT(16)
+#define TPR10_DX_BIT_DELAY0 BIT(17)
+#define TPR10_DX_BIT_DELAY1 BIT(18)
+#define TPR10_WRITE_LEVELING BIT(20)
+#define TPR10_READ_CALIBRATION BIT(21)
+#define TPR10_READ_TRAINING BIT(22)
+#define TPR10_WRITE_TRAINING BIT(23)
+
+/* MRCTRL constants */
+#define MRCTRL0_MR_RANKS_ALL (3 << 4)
+#define MRCTRL0_MR_ADDR(x) (x << 12)
+#define MRCTRL0_MR_WR BIT(31)
+
+#define MRCTRL1_MR_ADDR(x) (x << 8)
+#define MRCTRL1_MR_DATA(x) (x)
+
+/* ADDRMAP constants */
+#define ADDRMAP_DISABLED_3F_B(b) (0x3f + b)
+#define ADDRMAP_DISABLED_1F_B(b) (0x1f + b)
+#define ADDRMAP_DISABLED_0F_B(b) (0x0f + b)
+
+#define _ADDRMAP_VALUE(a,x,b) (((a) - b) << (x * 8))
+
+/*
+ * Bx = internal base
+ * The selected HIF address bit for each address bit is determined
+ * by adding the internal base to the value of each field
+ * */
+
+#define ADDRMAP0_CS0_B6(v) _ADDRMAP_VALUE(v, 0, 6)
+
+#define ADDRMAP1_BANK0_B2(v) _ADDRMAP_VALUE(v, 0, 2)
+#define ADDRMAP1_BANK1_B3(v) _ADDRMAP_VALUE(v, 1, 3)
+#define ADDRMAP1_BANK2_B4(v) _ADDRMAP_VALUE(v, 2, 4)
+
+#define ADDRMAP2_COL2_B2(v) _ADDRMAP_VALUE(v, 0, 2)
+#define ADDRMAP2_COL3_B3(v) _ADDRMAP_VALUE(v, 1, 3)
+#define ADDRMAP2_COL4_B4(v) _ADDRMAP_VALUE(v, 2, 4)
+#define ADDRMAP2_COL5_B5(v) _ADDRMAP_VALUE(v, 3, 5)
+
+#define ADDRMAP3_COL6_B6(v) _ADDRMAP_VALUE(v, 0, 6)
+#define ADDRMAP3_COL7_B7(v) _ADDRMAP_VALUE(v, 1, 7)
+#define ADDRMAP3_COL8_B8(v) _ADDRMAP_VALUE(v, 2, 8)
+#define ADDRMAP3_COL9_B9(v) _ADDRMAP_VALUE(v, 3, 9)
+
+#define ADDRMAP4_COL10_B10(v) _ADDRMAP_VALUE(v, 0, 10)
+#define ADDRMAP4_COL11_B11(v) _ADDRMAP_VALUE(v, 1, 11)
+
+#define ADDRMAP5_ROW0_B6(v) _ADDRMAP_VALUE(v, 0, 6)
+#define ADDRMAP5_ROW1_B7(v) _ADDRMAP_VALUE(v, 1, 7)
+#define ADDRMAP5_ROW2_10_B8(v) _ADDRMAP_VALUE(v, 2, 8)
+#define ADDRMAP5_ROW11_B17(v) _ADDRMAP_VALUE(v, 3, 17)
+
+#define ADDRMAP6_ROW12_B18(v) _ADDRMAP_VALUE(v, 0, 18)
+#define ADDRMAP6_ROW13_B19(v) _ADDRMAP_VALUE(v, 1, 19)
+#define ADDRMAP6_ROW14_B20(v) _ADDRMAP_VALUE(v, 2, 20)
+#define ADDRMAP6_ROW15_B21(v) _ADDRMAP_VALUE(v, 3, 21)
+
+#define ADDRMAP7_ROW16_B22(v) _ADDRMAP_VALUE(v, 0, 22)
+#define ADDRMAP7_ROW17_B23(v) _ADDRMAP_VALUE(v, 1, 23)
+
+#define ADDRMAP8_BG0_B2(v) _ADDRMAP_VALUE(v, 0, 2)
+#define ADDRMAP8_BG1_B3(v) _ADDRMAP_VALUE(v, 1, 3)
+
+/* These are only used if ADDRMAP5_ROW_BITS_2_10 = ADDRMAP_DISABLED_0F */
+#define ADDRMAP9_ROW2_B8(v) _ADDRMAP_VALUE(v, 0, 8)
+#define ADDRMAP9_ROW3_B9(v) _ADDRMAP_VALUE(v, 1, 9)
+#define ADDRMAP9_ROW4_B10(v) _ADDRMAP_VALUE(v, 2, 10)
+#define ADDRMAP9_ROW5_B11(v) _ADDRMAP_VALUE(v, 3, 11)
+
+#define ADDRMAP10_ROW6_B12(v) _ADDRMAP_VALUE(v, 0, 12)
+#define ADDRMAP10_ROW7_B13(v) _ADDRMAP_VALUE(v, 1, 13)
+#define ADDRMAP10_ROW8_B14(v) _ADDRMAP_VALUE(v, 2, 14)
+#define ADDRMAP10_ROW9_B15(v) _ADDRMAP_VALUE(v, 3, 15)
+
+#define ADDRMAP11_ROW10_B16(v) _ADDRMAP_VALUE(v, 0, 16)
+
+struct dram_para {
+ uint32_t clk;
+ enum sunxi_dram_type type;
+ uint32_t dx_odt;
+ uint32_t dx_dri;
+ uint32_t ca_dri;
+ uint32_t para0;
+ uint32_t mr11;
+ uint32_t mr12;
+ uint32_t mr13;
+ uint32_t mr14;
+ uint32_t tpr1;
+ uint32_t tpr2;
+ uint32_t tpr3;
+ uint32_t tpr6;
+ uint32_t tpr10;
+ uint32_t tpr11;
+ uint32_t tpr12;
+ uint32_t tpr13;
+ uint32_t tpr14;
+};
+
+void mctl_set_timing_params(const struct dram_para *para);
+
+struct dram_config {
+ u8 cols; /* Column bits */
+ u8 rows; /* Row bits */
+ u8 ranks; /* Rank bits (different from H616!) */
+ u8 banks; /* Bank bits */
+ u8 bankgrps; /* Bank group bits */
+ u8 bus_full_width; /* 1 = x32, 0 = x16 */
+};
+
+#endif /* _SUNXI_DRAM_SUN50I_A133_H */
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 89b1015bc4d..85ec0e6937e 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -20,23 +20,108 @@ static inline void sync(void)
{
}
-/* Generic virtual read/write. */
-#define __arch_getb(a) (*(volatile unsigned char *)(a))
-#define __arch_getw(a) (*(volatile unsigned short *)(a))
-#define __arch_getl(a) (*(volatile unsigned int *)(a))
-#define __arch_getq(a) (*(volatile unsigned long long *)(a))
+#ifdef CONFIG_ARM64
+#define __W "w"
+#else
+#define __W
+#endif
+
+#if CONFIG_IS_ENABLED(SYS_THUMB_BUILD)
+#define __R "l"
+#define __RM "=l"
+#else
+#define __R "r"
+#define __RM "=r"
+#endif
-#define __arch_putb(v,a) (*(volatile unsigned char *)(a) = (v))
-#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
-#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v))
-#define __arch_putq(v,a) (*(volatile unsigned long long *)(a) = (v))
+#ifdef CONFIG_KVM_VIRT_INS
+/*
+ * The __raw_writeX/__raw_readX below should be converted to static inline
+ * functions. However doing so produces a lot of compilation warnings when
+ * called with a raw address. Convert these once the callers have been fixed.
+ */
+#define __raw_writeb(val, addr) \
+ do { \
+ asm volatile("strb %" __W "0, [%1]" \
+ : \
+ : __R ((u8)(val)), __R (addr)); \
+ } while (0)
+
+#define __raw_readb(addr) \
+ ({ \
+ u32 __val; \
+ asm volatile("ldrb %" __W "0, [%1]" \
+ : __RM (__val) \
+ : __R (addr)); \
+ __val; \
+ })
+
+#define __raw_writew(val, addr) \
+ do { \
+ asm volatile("strh %" __W "0, [%1]" \
+ : \
+ : __R ((u16)(val)), __R (addr)); \
+ } while (0)
+
+#define __raw_readw(addr) \
+ ({ \
+ u32 __val; \
+ asm volatile("ldrh %" __W "0, [%1]" \
+ : __RM (__val) \
+ : __R (addr)); \
+ __val; \
+ })
+
+#define __raw_writel(val, addr) \
+ do { \
+ asm volatile("str %" __W "0, [%1]" \
+ : \
+ : __R ((u32)(val)), __R (addr)); \
+ } while (0)
+
+#define __raw_readl(addr) \
+ ({ \
+ u32 __val; \
+ asm volatile("ldr %" __W "0, [%1]" \
+ : __RM (__val) \
+ : __R (addr)); \
+ __val; \
+ })
+
+#define __raw_writeq(val, addr) \
+ do { \
+ asm volatile("str %0, [%1]" \
+ : \
+ : __R ((u64)(val)), __R (addr)); \
+ } while (0)
+
+#define __raw_readq(addr) \
+ ({ \
+ u64 __val; \
+ asm volatile("ldr %0, [%1]" \
+ : __RM (__val) \
+ : __R (addr)); \
+ __val; \
+ })
+#else
+/* Generic virtual read/write. */
+#define __raw_readb(a) (*(volatile unsigned char *)(a))
+#define __raw_readw(a) (*(volatile unsigned short *)(a))
+#define __raw_readl(a) (*(volatile unsigned int *)(a))
+#define __raw_readq(a) (*(volatile unsigned long long *)(a))
+
+#define __raw_writeb(v, a) (*(volatile unsigned char *)(a) = (v))
+#define __raw_writew(v, a) (*(volatile unsigned short *)(a) = (v))
+#define __raw_writel(v, a) (*(volatile unsigned int *)(a) = (v))
+#define __raw_writeq(v, a) (*(volatile unsigned long long *)(a) = (v))
+#endif
static inline void __raw_writesb(unsigned long addr, const void *data,
int bytelen)
{
uint8_t *buf = (uint8_t *)data;
while(bytelen--)
- __arch_putb(*buf++, addr);
+ __raw_writeb(*buf++, addr);
}
static inline void __raw_writesw(unsigned long addr, const void *data,
@@ -44,7 +129,7 @@ static inline void __raw_writesw(unsigned long addr, const void *data,
{
uint16_t *buf = (uint16_t *)data;
while(wordlen--)
- __arch_putw(*buf++, addr);
+ __raw_writew(*buf++, addr);
}
static inline void __raw_writesl(unsigned long addr, const void *data,
@@ -52,40 +137,30 @@ static inline void __raw_writesl(unsigned long addr, const void *data,
{
uint32_t *buf = (uint32_t *)data;
while(longlen--)
- __arch_putl(*buf++, addr);
+ __raw_writel(*buf++, addr);
}
static inline void __raw_readsb(unsigned long addr, void *data, int bytelen)
{
uint8_t *buf = (uint8_t *)data;
while(bytelen--)
- *buf++ = __arch_getb(addr);
+ *buf++ = __raw_readb(addr);
}
static inline void __raw_readsw(unsigned long addr, void *data, int wordlen)
{
uint16_t *buf = (uint16_t *)data;
while(wordlen--)
- *buf++ = __arch_getw(addr);
+ *buf++ = __raw_readw(addr);
}
static inline void __raw_readsl(unsigned long addr, void *data, int longlen)
{
uint32_t *buf = (uint32_t *)data;
while(longlen--)
- *buf++ = __arch_getl(addr);
+ *buf++ = __raw_readl(addr);
}
-#define __raw_writeb(v,a) __arch_putb(v,a)
-#define __raw_writew(v,a) __arch_putw(v,a)
-#define __raw_writel(v,a) __arch_putl(v,a)
-#define __raw_writeq(v,a) __arch_putq(v,a)
-
-#define __raw_readb(a) __arch_getb(a)
-#define __raw_readw(a) __arch_getw(a)
-#define __raw_readl(a) __arch_getl(a)
-#define __raw_readq(a) __arch_getq(a)
-
/*
* TODO: The kernel offers some more advanced versions of barriers, it might
* have some advantages to use them instead of the simple one here.
@@ -98,15 +173,15 @@ static inline void __raw_readsl(unsigned long addr, void *data, int longlen)
#define smp_processor_id() 0
-#define writeb(v,c) ({ u8 __v = v; __iowmb(); __arch_putb(__v,c); __v; })
-#define writew(v,c) ({ u16 __v = v; __iowmb(); __arch_putw(__v,c); __v; })
-#define writel(v,c) ({ u32 __v = v; __iowmb(); __arch_putl(__v,c); __v; })
-#define writeq(v,c) ({ u64 __v = v; __iowmb(); __arch_putq(__v,c); __v; })
+#define writeb(v, c) ({ u8 __v = v; __iowmb(); writeb_relaxed(__v, c); __v; })
+#define writew(v, c) ({ u16 __v = v; __iowmb(); writew_relaxed(__v, c); __v; })
+#define writel(v, c) ({ u32 __v = v; __iowmb(); writel_relaxed(__v, c); __v; })
+#define writeq(v, c) ({ u64 __v = v; __iowmb(); writeq_relaxed(__v, c); __v; })
-#define readb(c) ({ u8 __v = __arch_getb(c); __iormb(); __v; })
-#define readw(c) ({ u16 __v = __arch_getw(c); __iormb(); __v; })
-#define readl(c) ({ u32 __v = __arch_getl(c); __iormb(); __v; })
-#define readq(c) ({ u64 __v = __arch_getq(c); __iormb(); __v; })
+#define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; })
+#define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; })
+#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; })
+#define readq(c) ({ u64 __v = readq_relaxed(c); __iormb(); __v; })
/*
* Relaxed I/O memory access primitives. These follow the Device memory
@@ -121,13 +196,10 @@ static inline void __raw_readsl(unsigned long addr, void *data, int longlen)
#define readq_relaxed(c) ({ u64 __r = le64_to_cpu((__force __le64) \
__raw_readq(c)); __r; })
-#define writeb_relaxed(v, c) ((void)__raw_writeb((v), (c)))
-#define writew_relaxed(v, c) ((void)__raw_writew((__force u16) \
- cpu_to_le16(v), (c)))
-#define writel_relaxed(v, c) ((void)__raw_writel((__force u32) \
- cpu_to_le32(v), (c)))
-#define writeq_relaxed(v, c) ((void)__raw_writeq((__force u64) \
- cpu_to_le64(v), (c)))
+#define writeb_relaxed(v, c) __raw_writeb((v), (c))
+#define writew_relaxed(v, c) __raw_writew((__force u16)cpu_to_le16(v), (c))
+#define writel_relaxed(v, c) __raw_writel((__force u32)cpu_to_le32(v), (c))
+#define writeq_relaxed(v, c) __raw_writeq((__force u64)cpu_to_le64(v), (c))
/*
* The compiler seems to be incapable of optimising constants
diff --git a/arch/arm/mach-airoha/an7581/init.c b/arch/arm/mach-airoha/an7581/init.c
index cefe9c6db9e..d149e0ee3c8 100644
--- a/arch/arm/mach-airoha/an7581/init.c
+++ b/arch/arm/mach-airoha/an7581/init.c
@@ -2,6 +2,7 @@
#include <fdtdec.h>
#include <init.h>
+#include <sysreset.h>
#include <asm/armv8/mmu.h>
#include <asm/system.h>
@@ -21,7 +22,7 @@ int dram_init_banksize(void)
return fdtdec_setup_memory_banksize();
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
psci_system_reset();
}
diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c
index 2604c5a710e..4cd8979bdc2 100644
--- a/arch/arm/mach-apple/board.c
+++ b/arch/arm/mach-apple/board.c
@@ -773,22 +773,31 @@ u64 get_page_table_size(void)
#define KERNEL_COMP_SIZE SZ_128M
+#define lmb_alloc(size, addr) lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, addr, size, LMB_NONE)
+
int board_late_init(void)
{
u32 status = 0;
+ phys_addr_t addr;
/* somewhat based on the Linux Kernel boot requirements:
* align by 2M and maximal FDT size 2M
*/
- status |= env_set_hex("loadaddr", lmb_alloc(SZ_1G, SZ_2M));
- status |= env_set_hex("fdt_addr_r", lmb_alloc(SZ_2M, SZ_2M));
- status |= env_set_hex("kernel_addr_r", lmb_alloc(SZ_128M, SZ_2M));
- status |= env_set_hex("ramdisk_addr_r", lmb_alloc(SZ_1G, SZ_2M));
- status |= env_set_hex("kernel_comp_addr_r",
- lmb_alloc(KERNEL_COMP_SIZE, SZ_2M));
- status |= env_set_hex("kernel_comp_size", KERNEL_COMP_SIZE);
- status |= env_set_hex("scriptaddr", lmb_alloc(SZ_4M, SZ_2M));
- status |= env_set_hex("pxefile_addr_r", lmb_alloc(SZ_4M, SZ_2M));
+ status |= !lmb_alloc(SZ_1G, &addr) ? env_set_hex("loadaddr", addr) : 1;
+ status |= !lmb_alloc(SZ_2M, &addr) ?
+ env_set_hex("fdt_addr_r", addr) : 1;
+ status |= !lmb_alloc(SZ_128M, &addr) ?
+ env_set_hex("kernel_addr_r", addr) : 1;
+ status |= !lmb_alloc(SZ_1G, &addr) ?
+ env_set_hex("ramdisk_addr_r", addr) : 1;
+ status |= !lmb_alloc(KERNEL_COMP_SIZE, &addr) ?
+ env_set_hex("kernel_comp_addr_r", addr) : 1;
+ status |= !lmb_alloc(KERNEL_COMP_SIZE, &addr) ?
+ env_set_hex("kernel_comp_size", addr) : 1;
+ status |= !lmb_alloc(SZ_4M, &addr) ?
+ env_set_hex("scriptaddr", addr) : 1;
+ status |= !lmb_alloc(SZ_4M, &addr) ?
+ env_set_hex("pxefile_addr_r", addr) : 1;
if (status)
log_warning("late_init: Failed to set run time variables\n");
diff --git a/arch/arm/mach-k3/am62ax/am62a7_init.c b/arch/arm/mach-k3/am62ax/am62a7_init.c
index ac4d30052f3..00173e6836b 100644
--- a/arch/arm/mach-k3/am62ax/am62a7_init.c
+++ b/arch/arm/mach-k3/am62ax/am62a7_init.c
@@ -57,7 +57,6 @@ static void ctrl_mmr_unlock(void)
mmr_unlock(CTRL_MMR0_BASE, 1);
mmr_unlock(CTRL_MMR0_BASE, 2);
mmr_unlock(CTRL_MMR0_BASE, 4);
- mmr_unlock(CTRL_MMR0_BASE, 5);
mmr_unlock(CTRL_MMR0_BASE, 6);
/* Unlock all MCU_CTRL_MMR0 module registers */
diff --git a/arch/arm/mach-k3/j722s/j722s_init.c b/arch/arm/mach-k3/j722s/j722s_init.c
index d8123f282ee..1180c75f551 100644
--- a/arch/arm/mach-k3/j722s/j722s_init.c
+++ b/arch/arm/mach-k3/j722s/j722s_init.c
@@ -166,6 +166,8 @@ static void k3_mem_init(void)
if (ret)
panic("DRAM init failed: %d\n", ret);
}
+
+ spl_enable_cache();
}
static __maybe_unused void enable_mcu_esm_reset(void)
diff --git a/arch/arm/mach-mediatek/tzcfg.c b/arch/arm/mach-mediatek/tzcfg.c
index 71982ba4d20..c8fe8ac0e9b 100644
--- a/arch/arm/mach-mediatek/tzcfg.c
+++ b/arch/arm/mach-mediatek/tzcfg.c
@@ -173,6 +173,7 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
int arch_misc_init(void)
{
+ phys_addr_t addr;
struct arm_smccc_res res;
/*
@@ -180,11 +181,14 @@ int arch_misc_init(void)
* there's no need to check the result
*/
arm_smccc_smc(MTK_SIP_GET_BL31_REGION, 0, 0, 0, 0, 0, 0, 0, &res);
- lmb_reserve(res.a1, res.a2, LMB_NOMAP);
+ addr = (phys_addr_t)res.a1;
+ lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &addr, res.a2, LMB_NOMAP);
arm_smccc_smc(MTK_SIP_GET_BL32_REGION, 0, 0, 0, 0, 0, 0, 0, &res);
+ addr = (phys_addr_t)res.a1;
if (!res.a0 && res.a1 && res.a2)
- lmb_reserve(res.a1, res.a2, LMB_NOMAP);
+ lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &addr, res.a2,
+ LMB_NOMAP);
#if IS_ENABLED(CONFIG_CMD_PSTORE)
char cmd[64];
diff --git a/arch/arm/mach-rockchip/rk3399/rk3399.c b/arch/arm/mach-rockchip/rk3399/rk3399.c
index 99597076d2c..43d151708e4 100644
--- a/arch/arm/mach-rockchip/rk3399/rk3399.c
+++ b/arch/arm/mach-rockchip/rk3399/rk3399.c
@@ -16,6 +16,7 @@
#include <asm/arch-rockchip/gpio.h>
#include <asm/arch-rockchip/grf_rk3399.h>
#include <asm/arch-rockchip/hardware.h>
+#include <asm/gpio.h>
#include <linux/bitops.h>
#include <linux/printk.h>
#include <power/regulator.h>
diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
index 5547d6d054f..ec51ebbbe7f 100644
--- a/arch/arm/mach-snapdragon/board.c
+++ b/arch/arm/mach-snapdragon/board.c
@@ -37,6 +37,8 @@
DECLARE_GLOBAL_DATA_PTR;
+enum qcom_boot_source qcom_boot_source __section(".data") = 0;
+
static struct mm_region rbx_mem_map[CONFIG_NR_DRAM_BANKS + 2] = { { 0 } };
struct mm_region *mem_map = rbx_mem_map;
@@ -238,6 +240,12 @@ int board_fdt_blob_setup(void **fdtp)
if (ret < 0)
panic("No valid memory ranges found!\n");
+ /* If we have an external FDT, it can only have come from the Android bootloader. */
+ if (external_valid)
+ qcom_boot_source = QCOM_BOOT_SOURCE_ANDROID;
+ else
+ qcom_boot_source = QCOM_BOOT_SOURCE_XBL;
+
debug("ram_base = %#011lx, ram_size = %#011llx\n",
gd->ram_base, gd->ram_size);
@@ -481,6 +489,23 @@ static void configure_env(void)
qcom_set_serialno();
}
+void qcom_show_boot_source(void)
+{
+ const char *name = "UNKNOWN";
+
+ switch (qcom_boot_source) {
+ case QCOM_BOOT_SOURCE_ANDROID:
+ name = "ABL";
+ break;
+ case QCOM_BOOT_SOURCE_XBL:
+ name = "XBL";
+ break;
+ }
+
+ log_info("U-Boot loaded from %s\n", name);
+ env_set("boot_source", name);
+}
+
void __weak qcom_late_init(void)
{
}
@@ -492,38 +517,56 @@ void __weak qcom_late_init(void)
#define FASTBOOT_BUF_SIZE 0
#endif
-#define addr_alloc(size) lmb_alloc(size, SZ_2M)
+#define lmb_alloc(size, addr) lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, addr, size, LMB_NONE)
/* Stolen from arch/arm/mach-apple/board.c */
int board_late_init(void)
{
- u32 status = 0;
+ u32 status = 0, fdt_status = 0;
phys_addr_t addr;
struct fdt_header *fdt_blob = (struct fdt_header *)gd->fdt_blob;
/* We need to be fairly conservative here as we support boards with just 1G of TOTAL RAM */
- addr = addr_alloc(SZ_128M);
+ status |= !lmb_alloc(SZ_128M, &addr) ?
+ env_set_hex("loadaddr", addr) : 1;
status |= env_set_hex("kernel_addr_r", addr);
- status |= env_set_hex("loadaddr", addr);
- status |= env_set_hex("ramdisk_addr_r", addr_alloc(SZ_128M));
- status |= env_set_hex("kernel_comp_addr_r", addr_alloc(KERNEL_COMP_SIZE));
- status |= env_set_hex("kernel_comp_size", KERNEL_COMP_SIZE);
- if (IS_ENABLED(CONFIG_FASTBOOT))
- status |= env_set_hex("fastboot_addr_r", addr_alloc(FASTBOOT_BUF_SIZE));
- status |= env_set_hex("scriptaddr", addr_alloc(SZ_4M));
- status |= env_set_hex("pxefile_addr_r", addr_alloc(SZ_4M));
- addr = addr_alloc(SZ_2M);
- status |= env_set_hex("fdt_addr_r", addr);
-
- if (status)
+ status |= !lmb_alloc(SZ_128M, &addr) ?
+ env_set_hex("ramdisk_addr_r", addr) : 1;
+ status |= !lmb_alloc(KERNEL_COMP_SIZE, &addr) ?
+ env_set_hex("kernel_comp_addr_r", addr) : 1;
+ status |= !lmb_alloc(KERNEL_COMP_SIZE, &addr) ?
+ env_set_hex("kernel_comp_size", addr) : 1;
+ status |= !lmb_alloc(SZ_4M, &addr) ?
+ env_set_hex("scriptaddr", addr) : 1;
+ status |= !lmb_alloc(SZ_4M, &addr) ?
+ env_set_hex("pxefile_addr_r", addr) : 1;
+
+ if (IS_ENABLED(CONFIG_FASTBOOT)) {
+ status |= !lmb_alloc(FASTBOOT_BUF_SIZE, &addr) ?
+ env_set_hex("fastboot_addr_r", addr) : 1;
+ /* override loadaddr for memory rich soc */
+ status |= !lmb_alloc(SZ_128M, &addr) ?
+ env_set_hex("loadaddr", addr) : 1;
+ }
+
+ fdt_status |= !lmb_alloc(SZ_2M, &addr) ?
+ env_set_hex("fdt_addr_r", addr) : 1;
+
+ if (status || fdt_status)
log_warning("%s: Failed to set run time variables\n", __func__);
/* By default copy U-Boots FDT, it will be used as a fallback */
- memcpy((void *)addr, (void *)gd->fdt_blob, fdt32_to_cpu(fdt_blob->totalsize));
+ if (fdt_status)
+ log_warning("%s: Failed to reserve memory for copying FDT\n",
+ __func__);
+ else
+ memcpy((void *)addr, (void *)gd->fdt_blob,
+ fdt32_to_cpu(fdt_blob->totalsize));
configure_env();
qcom_late_init();
+ qcom_show_boot_source();
/* Configure the dfu_string for capsule updates */
qcom_configure_capsule_updates();
diff --git a/arch/arm/mach-snapdragon/capsule_update.c b/arch/arm/mach-snapdragon/capsule_update.c
index bf75a9a1b24..4dced4961b6 100644
--- a/arch/arm/mach-snapdragon/capsule_update.c
+++ b/arch/arm/mach-snapdragon/capsule_update.c
@@ -20,22 +20,19 @@
#include "qcom-priv.h"
/*
- * NOTE: for now this implementation only supports the rb3gen2. Supporting other
- * boards that boot in different ways (e.g. chainloaded from ABL) will require
- * additional complexity to properly create the dfu string and fw_images array.
- */
-
-/*
- * To handle different variants like chainloaded U-Boot here we'll need to
- * build the fw_images array dynamically at runtime. It looks like
- * mach-rockchip is a good example for how to do this.
- * Detecting which image types a board uses is TBD, hence for now we only
- * support the one new board that runs U-Boot as its primary bootloader.
+ * To handle different variants like chainloaded U-Boot here we need to
+ * build the fw_images array dynamically at runtime. These are the possible
+ * implementations:
+ *
+ * - Devices with U-Boot on the uefi_a/b partition
+ * - Devices with U-Boot on the boot (a/b) partition
+ * - Devices with U-Boot on the xbl (a/b) partition
+ *
+ * Which partition actually has U-Boot on it is determined based on the
+ * qcom_boot_source variable and additional logic in find_target_partition().
*/
struct efi_fw_image fw_images[] = {
{
- /* U-Boot flashed to the uefi_X partition (e.g. rb3gen2) */
- .fw_name = u"UBOOT_UEFI_PARTITION",
.image_index = 1,
},
};
@@ -47,6 +44,12 @@ struct efi_capsule_update_info update_info = {
.images = fw_images,
};
+enum target_part_type {
+ TARGET_PART_UEFI = 1,
+ TARGET_PART_XBL,
+ TARGET_PART_BOOT,
+};
+
/* LSB first */
struct part_slot_status {
u16: 2;
@@ -57,35 +60,202 @@ struct part_slot_status {
u16 tries_remaining : 4;
};
-static int find_boot_partition(const char *partname, struct blk_desc *blk_dev, char *name)
+enum ab_slot {
+ SLOT_NONE,
+ SLOT_A,
+ SLOT_B,
+};
+
+static enum ab_slot get_part_slot(const char *partname)
+{
+ int len = strlen(partname);
+
+ if (partname[len - 2] != '_')
+ return SLOT_NONE;
+ if (partname[len - 1] == 'a')
+ return SLOT_A;
+ if (partname[len - 1] == 'b')
+ return SLOT_B;
+
+ return SLOT_NONE;
+}
+
+/*
+ * Determine which partition U-Boot is flashed to based on the boot source (ABL/XBL),
+ * the slot status, and prioritizing the uefi partition over xbl if found.
+ */
+static int find_target_partition(int *devnum, enum uclass_id *uclass,
+ enum target_part_type *target_part_type)
{
int ret;
- int partnum;
+ int partnum, uefi_partnum = -1, xbl_partnum = -1;
struct disk_partition info;
struct part_slot_status *slot_status;
+ struct udevice *dev = NULL;
+ struct blk_desc *desc = NULL, *xbl_desc = NULL;
+ uchar ptn_name[32] = { 0 };
+ bool have_ufs = false;
+
+ /*
+ * Check to see if we have UFS storage, if so U-Boot MUST be on it and we can skip
+ * all non-UFS block devices
+ */
+ uclass_foreach_dev_probe(UCLASS_UFS, dev) {
+ have_ufs = true;
+ break;
+ }
- for (partnum = 1;; partnum++) {
- ret = part_get_info(blk_dev, partnum, &info);
- if (ret)
- return ret;
+ uclass_foreach_dev_probe(UCLASS_BLK, dev) {
+ if (device_get_uclass_id(dev) != UCLASS_BLK)
+ continue;
- slot_status = (struct part_slot_status *)&info.type_flags;
- log_io("%16s: Active: %1d, Successful: %1d, Unbootable: %1d, Tries left: %1d\n",
- info.name, slot_status->active,
- slot_status->successful, slot_status->unbootable,
- slot_status->tries_remaining);
+ /* If we have a UFS then don't look at any other block devices */
+ if (have_ufs) {
+ if (device_get_uclass_id(dev->parent->parent) != UCLASS_UFS)
+ continue;
/*
- * FIXME: eventually we'll want to find the active/inactive variant of the partition
- * but on the rb3gen2 these values might all be 0
+ * If we don't have UFS, then U-Boot must be on the eMMC which is always the first
+ * MMC device.
*/
- if (!strncmp(info.name, partname, strlen(partname))) {
- log_debug("Found active %s partition: '%s'!\n", partname, info.name);
- strlcpy(name, info.name, sizeof(info.name));
- return partnum;
+ } else if (dev->parent->seq_ > 0) {
+ continue;
}
+
+ desc = dev_get_uclass_plat(dev);
+ if (!desc || desc->part_type == PART_TYPE_UNKNOWN)
+ continue;
+ for (partnum = 1;; partnum++) {
+ ret = part_get_info(desc, partnum, &info);
+ if (ret)
+ break;
+
+ slot_status = (struct part_slot_status *)&info.type_flags;
+
+ /*
+ * Qualcomm Linux devices have a "uefi" partition, it's A/B but the
+ * flags might not be set so we assume the A partition unless the B
+ * partition is active.
+ */
+ if (!strncmp(info.name, "uefi", strlen("uefi"))) {
+ /*
+ * If U-Boot was chainloaded somehow we can't be flashed to
+ * the uefi partition
+ */
+ if (qcom_boot_source != QCOM_BOOT_SOURCE_XBL)
+ continue;
+
+ *target_part_type = TARGET_PART_UEFI;
+ /*
+ * Found an active UEFI partition, this is where U-Boot is
+ * flashed.
+ */
+ if (slot_status->active)
+ goto found;
+
+ /* Prefer A slot if it's not marked active */
+ if (get_part_slot(info.name) == SLOT_A) {
+ /*
+ * If we found the A slot after the B slot (both
+ * inactive) then we assume U-Boot is on the A slot.
+ */
+ if (uefi_partnum >= 0)
+ goto found;
+
+ /* Didn't find the B slot yet */
+ uefi_partnum = partnum;
+ strlcpy(ptn_name, info.name, 32);
+ } else {
+ /*
+ * Found inactive B slot after inactive A slot, return
+ * the A slot
+ */
+ if (uefi_partnum >= 0) {
+ partnum = uefi_partnum;
+ goto found;
+ }
+
+ /*
+ * Didn't find the A slot yet. Record that we found the
+ * B slot
+ */
+ uefi_partnum = partnum;
+ strlcpy(ptn_name, info.name, 32);
+ }
+ /* xbl and aboot are effectively the same */
+ } else if ((!strncmp(info.name, "xbl", strlen("xbl")) &&
+ strlen(info.name) == 5) ||
+ !strncmp(info.name, "aboot", strlen("aboot"))) {
+ /*
+ * If U-Boot was booted via ABL, we can't be flashed to the
+ * XBL partition
+ */
+ if (qcom_boot_source != QCOM_BOOT_SOURCE_XBL)
+ continue;
+
+ /*
+ * ignore xbl partition if we have uefi partitions, U-Boot will
+ * always be on the UEFI partition in this case.
+ */
+ if (*target_part_type == TARGET_PART_UEFI)
+ continue;
+
+ /* Either non-A/B or find the active XBL partition */
+ if (slot_status->active || !get_part_slot(info.name)) {
+ /*
+ * No quick return since we might find a uefi partition
+ * later
+ */
+ xbl_partnum = partnum;
+ *target_part_type = TARGET_PART_XBL;
+ xbl_desc = desc;
+ strlcpy(ptn_name, info.name, 32);
+ }
+
+ /*
+ * No fast return since we might also have a uefi partition which
+ * will take priority.
+ */
+ } else if (!strncmp(info.name, "boot", strlen("boot"))) {
+ /* We can only be flashed to boot if we were chainloaded */
+ if (qcom_boot_source != QCOM_BOOT_SOURCE_ANDROID)
+ continue;
+
+ /*
+ * Either non-A/B or find the active partition. We can return
+ * immediately here since we've narrowed it down to a single option
+ */
+ if (slot_status->active || !get_part_slot(info.name)) {
+ *target_part_type = TARGET_PART_BOOT;
+ goto found;
+ }
+ }
+ }
+ }
+
+ /*
+ * Now we've exhausted all options, if we didn't find a uefi partition
+ * then we are indeed flashed to the xbl partition.
+ */
+ if (*target_part_type == TARGET_PART_XBL) {
+ partnum = xbl_partnum;
+ desc = xbl_desc;
+ goto found;
}
+ /* Found no candidate partitions */
return -1;
+
+found:
+ if (desc) {
+ *devnum = desc->devnum;
+ *uclass = desc->uclass_id;
+ }
+
+ /* info won't match for XBL hence the copy. */
+ log_info("Capsule update target: %s (disk %d:%d)\n",
+ *target_part_type == TARGET_PART_BOOT ? info.name : ptn_name,
+ *devnum, partnum);
+ return partnum;
}
/**
@@ -101,12 +271,10 @@ static int find_boot_partition(const char *partname, struct blk_desc *blk_dev, c
*/
void qcom_configure_capsule_updates(void)
{
- struct blk_desc *desc;
int ret = 0, partnum = -1, devnum;
static char dfu_string[32] = { 0 };
- char name[32]; /* GPT partition name */
- char *partname = "uefi_a";
- struct udevice *dev = NULL;
+ enum target_part_type target_part_type = 0;
+ enum uclass_id dev_uclass;
if (IS_ENABLED(CONFIG_SCSI)) {
/* Scan for SCSI devices */
@@ -117,26 +285,30 @@ void qcom_configure_capsule_updates(void)
}
}
- uclass_foreach_dev_probe(UCLASS_BLK, dev) {
- if (device_get_uclass_id(dev) != UCLASS_BLK)
- continue;
-
- desc = dev_get_uclass_plat(dev);
- if (!desc || desc->part_type == PART_TYPE_UNKNOWN)
- continue;
- devnum = desc->devnum;
- partnum = find_boot_partition(partname, desc,
- name);
- if (partnum >= 0)
- break;
- }
-
+ partnum = find_target_partition(&devnum, &dev_uclass, &target_part_type);
if (partnum < 0) {
log_err("Failed to find boot partition\n");
return;
}
- switch (desc->uclass_id) {
+ /*
+ * Set the fw_name based on the partition type. This causes the GUID to be different
+ * so we will never accidentally flash a U-Boot image intended for XBL to the boot
+ * partition.
+ */
+ switch (target_part_type) {
+ case TARGET_PART_UEFI:
+ fw_images[0].fw_name = u"UBOOT_UEFI_PARTITION";
+ break;
+ case TARGET_PART_XBL:
+ fw_images[0].fw_name = u"UBOOT_XBL_PARTITION";
+ break;
+ case TARGET_PART_BOOT:
+ fw_images[0].fw_name = u"UBOOT_BOOT_PARTITION";
+ break;
+ }
+
+ switch (dev_uclass) {
case UCLASS_SCSI:
snprintf(dfu_string, 32, "scsi %d=u-boot.bin part %d", devnum, partnum);
break;
@@ -144,10 +316,10 @@ void qcom_configure_capsule_updates(void)
snprintf(dfu_string, 32, "mmc 0=u-boot.bin part %d %d", devnum, partnum);
break;
default:
- debug("Unsupported storage uclass: %d\n", desc->uclass_id);
+ debug("Unsupported storage uclass: %d\n", dev_uclass);
return;
}
- log_debug("boot partition is %s, DFU string: '%s'\n", name, dfu_string);
+ log_debug("DFU string: '%s'\n", dfu_string);
update_info.dfu_string = dfu_string;
}
diff --git a/arch/arm/mach-snapdragon/of_fixup.c b/arch/arm/mach-snapdragon/of_fixup.c
index b398c6b7b9f..328c7812f30 100644
--- a/arch/arm/mach-snapdragon/of_fixup.c
+++ b/arch/arm/mach-snapdragon/of_fixup.c
@@ -99,19 +99,6 @@ static int fixup_qcom_dwc3(struct device_node *root, struct device_node *glue_np
return ret;
}
- /*
- * The RB1/2 boards only have a single USB controller and it's muxed between the type-C port
- * and a USB hub. Since we can't do OTG in U-Boot properly we prefer to put it into host mode.
- */
- if (of_device_is_compatible(root, "qcom,qrb4210-rb2", NULL, NULL) ||
- of_device_is_compatible(root, "qcom,qrb2210-rb1", NULL, NULL)) {
- ret = of_write_prop(dwc3, "dr_mode", sizeof("host"), "host");
- if (ret) {
- log_err("Failed to set 'dr_mode' property: %d\n", ret);
- return ret;
- }
- }
-
return 0;
}
diff --git a/arch/arm/mach-snapdragon/qcom-priv.h b/arch/arm/mach-snapdragon/qcom-priv.h
index 4f398e2ba37..b8bf574e8bb 100644
--- a/arch/arm/mach-snapdragon/qcom-priv.h
+++ b/arch/arm/mach-snapdragon/qcom-priv.h
@@ -3,6 +3,20 @@
#ifndef __QCOM_PRIV_H__
#define __QCOM_PRIV_H__
+/**
+ * enum qcom_boot_source - Track where we got loaded from.
+ * Used for capsule update logic.
+ *
+ * @QCOM_BOOT_SOURCE_ANDROID: chainloaded (typically from ABL)
+ * @QCOM_BOOT_SOURCE_XBL: flashed to the XBL or UEFI partition
+ */
+enum qcom_boot_source {
+ QCOM_BOOT_SOURCE_ANDROID = 1,
+ QCOM_BOOT_SOURCE_XBL,
+};
+
+extern enum qcom_boot_source qcom_boot_source;
+
#if IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)
void qcom_configure_capsule_updates(void);
#else
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 17179593913..0a7c029b15a 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -51,7 +51,13 @@ config DRAM_SUN50I_H616
Select this dram controller driver for some sun50i platforms,
like H616.
-if DRAM_SUN50I_H616
+config DRAM_SUN50I_A133
+ bool
+ help
+ Select this dram controller driver for some sun50i platforms,
+ like A133.
+
+if DRAM_SUN50I_H616 || DRAM_SUN50I_A133
config DRAM_SUNXI_DX_ODT
hex "DRAM DX ODT parameter"
help
@@ -73,18 +79,64 @@ config DRAM_SUNXI_ODT_EN
help
ODT EN value from vendor DRAM settings.
+config DRAM_SUNXI_PARA0
+ hex "DRAM PARA0 parameter"
+ depends on DRAM_SUN50I_A133
+ help
+ PARA0 value from vendor DRAM settings.
+
+config DRAM_SUNXI_MR11
+ hex "DRAM MR11 parameter"
+ depends on DRAM_SUN50I_A133
+ default 0x0
+ help
+ MR11 value from vendor DRAM settings.
+
+config DRAM_SUNXI_MR12
+ hex "DRAM MR12 parameter"
+ depends on DRAM_SUN50I_A133
+ default 0x0
+ help
+ MR12 value from vendor DRAM settings.
+
+config DRAM_SUNXI_MR13
+ hex "DRAM MR13 parameter"
+ depends on DRAM_SUN50I_A133
+ default 0x0
+ help
+ MR13 value from vendor DRAM settings.
+
+config DRAM_SUNXI_MR14
+ hex "DRAM MR14 parameter"
+ depends on DRAM_SUN50I_A133
+ default 0x0
+ help
+ MR14 value from vendor DRAM settings.
+
config DRAM_SUNXI_TPR0
hex "DRAM TPR0 parameter"
default 0x0
help
TPR0 value from vendor DRAM settings.
+config DRAM_SUNXI_TPR1
+ hex "DRAM TPR1 parameter"
+ default 0x0
+ help
+ TPR1 value from vendor DRAM settings.
+
config DRAM_SUNXI_TPR2
hex "DRAM TPR2 parameter"
default 0x0
help
TPR2 value from vendor DRAM settings.
+config DRAM_SUNXI_TPR3
+ hex "DRAM TPR3 parameter"
+ default 0x0
+ help
+ TPR3 value from vendor DRAM settings.
+
config DRAM_SUNXI_TPR6
hex "DRAM TPR6 parameter"
default 0x3300c080
@@ -109,6 +161,20 @@ config DRAM_SUNXI_TPR12
help
TPR12 value from vendor DRAM settings.
+config DRAM_SUNXI_TPR13
+ hex "DRAM TPR13 parameter"
+ depends on DRAM_SUN50I_A133
+ default 0x0
+ help
+ TPR13 value from vendor DRAM settings.
+
+config DRAM_SUNXI_TPR14
+ hex "DRAM TPR14 parameter"
+ depends on DRAM_SUN50I_A133
+ default 0x0
+ help
+ TPR14 value from vendor DRAM settings.
+
choice
prompt "DRAM PHY pin mapping selection"
default DRAM_SUNXI_PHY_ADDR_MAP_0
@@ -116,7 +182,8 @@ choice
config DRAM_SUNXI_PHY_ADDR_MAP_0
bool "DRAM PHY address map 0"
help
- This pin mapping selection should be used by the H313, H616, H618.
+ This pin mapping selection should be used by the H313, H616, H618,
+ and A133, R818 SoCs.
config DRAM_SUNXI_PHY_ADDR_MAP_1
bool "DRAM PHY address map 1"
@@ -153,6 +220,7 @@ config SUNXI_SRAM_ADDRESS
config SUNXI_RVBAR_ADDRESS
hex
depends on ARM64
+ default 0x08100040 if MACH_SUN50I_A133
default 0x09010040 if SUN50I_GEN_H6
default 0x017000a0
---help---
@@ -179,8 +247,8 @@ config SUNXI_RVBAR_ALTERNATIVE
config SUNXI_BL31_BASE
hex
default 0x00044000 if MACH_SUN50I || MACH_SUN50I_H5
- default 0x00104000 if MACH_SUN50I_H6
default 0x40000000 if MACH_SUN50I_H616
+ default 0x00104000 if SUN50I_GEN_H6
default 0x0
help
Address where BL31 (TF-A) is loaded, or zero if BL31 is not used.
@@ -262,7 +330,7 @@ config MACH_SUNXI_H3_H5
# TODO: try out A80's 8GiB DRAM space
config SUNXI_DRAM_MAX_SIZE
hex
- default 0x100000000 if MACH_SUN50I_H616
+ default 0x100000000 if MACH_SUN50I_H616 || MACH_SUN50I_A133
default 0xC0000000 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN50I_H6
default 0x80000000
@@ -459,6 +527,10 @@ config MACH_SUN50I_H616
config MACH_SUN50I_A133
bool "sun50i (Allwinner A133)"
+ select ARM64
+ select DRAM_SUN50I_A133
+ select SUN50I_GEN_H6
+ imply OF_UPSTREAM
endchoice
@@ -497,7 +569,7 @@ config ARM_BOOT_HOOK_RMR
This allows both the SPL and the U-Boot proper to be entered in
either mode and switch to AArch64 if needed.
-if SUNXI_DRAM_DW || DRAM_SUN50I_H6 || DRAM_SUN50I_H616
+if SUNXI_DRAM_DW || DRAM_SUN50I_H6 || DRAM_SUN50I_H616 || DRAM_SUN50I_A133
config SUNXI_DRAM_DDR3
bool
@@ -510,6 +582,9 @@ config SUNXI_DRAM_LPDDR3
config SUNXI_DRAM_LPDDR4
bool
+config SUNXI_DRAM_DDR4
+ bool
+
choice
prompt "DRAM Type and Timing"
default SUNXI_DRAM_DDR3_1333 if !MACH_SUN8I_V3S
@@ -518,6 +593,7 @@ choice
config SUNXI_DRAM_DDR3_1333
bool "DDR3 1333"
select SUNXI_DRAM_DDR3
+ depends on !DRAM_SUN50I_A133
---help---
This option is the original only supported memory type, which suits
many H3/H5/A64 boards available now.
@@ -525,6 +601,7 @@ config SUNXI_DRAM_DDR3_1333
config SUNXI_DRAM_LPDDR3_STOCK
bool "LPDDR3 with Allwinner stock configuration"
select SUNXI_DRAM_LPDDR3
+ depends on !DRAM_SUN50I_A133
---help---
This option is the LPDDR3 timing used by the stock boot0 by
Allwinner.
@@ -548,7 +625,7 @@ config SUNXI_DRAM_H6_DDR3_1333
config SUNXI_DRAM_H616_LPDDR3
bool "LPDDR3 DRAM chips on the H616 DRAM controller"
select SUNXI_DRAM_LPDDR3
- depends on DRAM_SUN50I_H616
+ depends on DRAM_SUN50I_H616 || DRAM_SUN50I_A133
help
This option is the LPDDR3 timing used by the stock boot0 by
Allwinner.
@@ -556,7 +633,7 @@ config SUNXI_DRAM_H616_LPDDR3
config SUNXI_DRAM_H616_LPDDR4
bool "LPDDR4 DRAM chips on the H616 DRAM controller"
select SUNXI_DRAM_LPDDR4
- depends on DRAM_SUN50I_H616
+ depends on DRAM_SUN50I_H616 || DRAM_SUN50I_A133
help
This option is the LPDDR4 timing used by the stock boot0 by
Allwinner.
@@ -564,11 +641,27 @@ config SUNXI_DRAM_H616_LPDDR4
config SUNXI_DRAM_H616_DDR3_1333
bool "DDR3-1333 boot0 timings on the H616 DRAM controller"
select SUNXI_DRAM_DDR3
- depends on DRAM_SUN50I_H616
+ depends on DRAM_SUN50I_H616 || DRAM_SUN50I_A133
help
This option is the DDR3 timing used by the boot0 on H616 TV boxes
which use a DDR3-1333 timing.
+config SUNXI_DRAM_A133_DDR4
+ bool "DDR4 boot0 timings on the A133 DRAM controller"
+ select SUNXI_DRAM_DDR4
+ depends on DRAM_SUN50I_A133
+ help
+ This option is the DDR4 timing used by the boot0 on A133 devices
+ which use a DDR4 timing.
+
+config SUNXI_DRAM_A133_LPDDR4
+ bool "LPDDR4 boot0 timings on the A133 DRAM controller"
+ select SUNXI_DRAM_LPDDR4
+ depends on DRAM_SUN50I_A133
+ help
+ This option is the LPDDR4 timing used by the boot0 on A133 devices
+ which use an LPDDR4 timing.
+
config SUNXI_DRAM_DDR2_V3S
bool "DDR2 found in V3s chip"
select SUNXI_DRAM_DDR2
@@ -596,7 +689,7 @@ config DRAM_CLK
MACH_SUN8I_V3S
default 672 if MACH_SUN50I
default 744 if MACH_SUN50I_H6
- default 720 if MACH_SUN50I_H616
+ default 720 if MACH_SUN50I_H616 || MACH_SUN50I_A133
---help---
Set the dram clock speed, valid range 240 - 480 (prior to sun9i),
must be a multiple of 24. For the sun9i (A80), the tested values
@@ -613,7 +706,7 @@ endif
config DRAM_ZQ
int "sunxi dram zq value"
- depends on !MACH_SUN50I_H616
+ depends on !MACH_SUN50I_H616 && !MACH_SUN50I_A133
default 123 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || \
MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_A83T
default 127 if MACH_SUN7I
@@ -733,6 +826,7 @@ config SYS_CONFIG_NAME
default "sun50i" if MACH_SUN50I
default "sun50i" if MACH_SUN50I_H6
default "sun50i" if MACH_SUN50I_H616
+ default "sun50i" if MACH_SUN50I_A133
config SYS_BOARD
default "sunxi"
diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
index a33cd5b0f07..8eff20b77bf 100644
--- a/arch/arm/mach-sunxi/Makefile
+++ b/arch/arm/mach-sunxi/Makefile
@@ -45,4 +45,6 @@ obj-$(CONFIG_DRAM_SUN50I_H6) += dram_sun50i_h6.o dram_dw_helpers.o
obj-$(CONFIG_DRAM_SUN50I_H6) += dram_timings/
obj-$(CONFIG_DRAM_SUN50I_H616) += dram_sun50i_h616.o dram_dw_helpers.o
obj-$(CONFIG_DRAM_SUN50I_H616) += dram_timings/
+obj-$(CONFIG_DRAM_SUN50I_A133) += dram_sun50i_a133.o
+obj-$(CONFIG_DRAM_SUN50I_A133) += dram_timings/
endif
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index b1bf51f40c5..08d55b3a0e3 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -137,6 +137,10 @@ static int gpio_init(void)
sunxi_gpio_set_cfgpin(SUNXI_GPH(0), SUN50I_H616_GPH_UART0);
sunxi_gpio_set_cfgpin(SUNXI_GPH(1), SUN50I_H616_GPH_UART0);
sunxi_gpio_set_pull(SUNXI_GPH(1), SUNXI_GPIO_PULL_UP);
+#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN50I_A133)
+ sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN50I_H616_GPH_UART0);
+ sunxi_gpio_set_cfgpin(SUNXI_GPB(10), SUN50I_H616_GPH_UART0);
+ sunxi_gpio_set_pull(SUNXI_GPB(10), SUNXI_GPIO_PULL_UP);
#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_A83T)
sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN8I_A83T_GPB_UART0);
sunxi_gpio_set_cfgpin(SUNXI_GPB(10), SUN8I_A83T_GPB_UART0);
diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c
index 4c522f60810..3f375a51965 100644
--- a/arch/arm/mach-sunxi/clock_sun50i_h6.c
+++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c
@@ -87,7 +87,8 @@ void clock_set_pll1(unsigned int clk)
/* clk = 24*n/p, p is ignored if clock is >288MHz */
val = CCM_PLL1_CTRL_EN | CCM_PLL1_LOCK_EN | CCM_PLL1_CLOCK_TIME_2;
val |= CCM_PLL1_CTRL_N(clk / 24000000);
- if (IS_ENABLED(CONFIG_MACH_SUN50I_H616))
+ if (IS_ENABLED(CONFIG_MACH_SUN50I_H616) ||
+ IS_ENABLED(CONFIG_MACH_SUN50I_A133))
val |= CCM_PLL1_OUT_EN;
if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
val |= CCM_PLL1_OUT_EN | CCM_PLL1_LDO_EN;
diff --git a/arch/arm/mach-sunxi/cpu_info.c b/arch/arm/mach-sunxi/cpu_info.c
index 310dca06e57..3f4735d4717 100644
--- a/arch/arm/mach-sunxi/cpu_info.c
+++ b/arch/arm/mach-sunxi/cpu_info.c
@@ -104,6 +104,8 @@ int print_cpuinfo(void)
puts("CPU: Allwinner H6 (SUN50I)\n");
#elif defined CONFIG_MACH_SUN50I_H616
puts("CPU: Allwinner H616 (SUN50I)\n");
+#elif defined CONFIG_MACH_SUN50I_A133
+ puts("CPU: Allwinner A133 (SUN50I)\n");
#else
#warning Please update cpu_info.c with correct CPU information
puts("CPU: SUNXI Family\n");
diff --git a/arch/arm/mach-sunxi/dram_sun50i_a133.c b/arch/arm/mach-sunxi/dram_sun50i_a133.c
new file mode 100644
index 00000000000..a0fca3738f4
--- /dev/null
+++ b/arch/arm/mach-sunxi/dram_sun50i_a133.c
@@ -0,0 +1,1204 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * sun50i A133 platform dram controller driver
+ *
+ * Controller and PHY appear to be quite similar to that of the H616;
+ * however certain offsets, timings, and other details are different enough that
+ * the original code does not work as expected. Some device flags and
+ * calibrations are not yet implemented, and configuration aside from DDR4
+ * have not been tested.
+ *
+ * (C) Copyright 2024 MasterR3C0RD <masterr3c0rd@epochal.quest>
+ *
+ * Uses code from H616 driver, which is
+ * (C) Copyright 2020 Jernej Skrabec <jernej.skrabec@siol.net>
+ *
+ */
+
+//#define DEBUG
+
+#include <asm/arch/clock.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/dram.h>
+#include <asm/arch/prcm.h>
+#include <asm/io.h>
+#include <init.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <log.h>
+
+#ifdef CONFIG_DRAM_SUNXI_PHY_ADDR_MAP_1
+static const u8 phy_init[] = {
+#ifdef CONFIG_SUNXI_DRAM_DDR3
+ 0x0c, 0x08, 0x19, 0x18, 0x10, 0x06, 0x0a, 0x03, 0x0e,
+ 0x00, 0x0b, 0x05, 0x09, 0x1a, 0x04, 0x13, 0x16, 0x11,
+ 0x01, 0x15, 0x0d, 0x07, 0x12, 0x17, 0x14, 0x02, 0x0f
+#elif CONFIG_SUNXI_DRAM_DDR4
+ 0x19, 0x1a, 0x04, 0x12, 0x09, 0x06, 0x08, 0x0a, 0x16,
+ 0x17, 0x18, 0x0f, 0x0c, 0x13, 0x02, 0x05, 0x01, 0x11,
+ 0x0e, 0x00, 0x0b, 0x07, 0x03, 0x14, 0x15, 0x0d, 0x10
+#elif CONFIG_SUNXI_DRAM_LPDDR3
+ 0x08, 0x03, 0x02, 0x00, 0x18, 0x19, 0x09, 0x01, 0x06,
+ 0x17, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
+ 0x12, 0x13, 0x14, 0x15, 0x16, 0x04, 0x05, 0x07, 0x1a
+#elif CONFIG_SUNXI_DRAM_LPDDR4
+ 0x01, 0x05, 0x02, 0x00, 0x19, 0x03, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
+ 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x04, 0x1a
+#endif
+};
+#else
+static const u8 phy_init[] = {
+#ifdef CONFIG_SUNXI_DRAM_DDR3
+ 0x03, 0x19, 0x18, 0x02, 0x10, 0x15, 0x16, 0x07, 0x06,
+ 0x0e, 0x05, 0x08, 0x0d, 0x04, 0x17, 0x1a, 0x13, 0x11,
+ 0x12, 0x14, 0x00, 0x01, 0x0c, 0x0a, 0x09, 0x0b, 0x0f
+#elif CONFIG_SUNXI_DRAM_DDR4
+ 0x13, 0x17, 0x0e, 0x01, 0x06, 0x12, 0x14, 0x07, 0x09,
+ 0x02, 0x0f, 0x00, 0x0d, 0x05, 0x16, 0x0c, 0x0a, 0x11,
+ 0x04, 0x03, 0x18, 0x15, 0x08, 0x10, 0x0b, 0x19, 0x1a
+#elif CONFIG_SUNXI_DRAM_LPDDR3
+ 0x05, 0x06, 0x17, 0x02, 0x19, 0x18, 0x04, 0x07, 0x03,
+ 0x01, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
+ 0x12, 0x13, 0x14, 0x15, 0x16, 0x08, 0x09, 0x00, 0x1a
+#elif CONFIG_SUNXI_DRAM_LPDDR4
+ 0x01, 0x03, 0x02, 0x19, 0x17, 0x00, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
+ 0x12, 0x13, 0x14, 0x15, 0x16, 0x04, 0x18, 0x05, 0x1a
+#endif
+};
+#endif
+
+static void mctl_clk_init(u32 clk)
+{
+ void * const ccm = (void *)SUNXI_CCM_BASE;
+
+ /* Place all DRAM blocks into reset */
+ clrbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_ENABLE);
+ clrbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_RESET);
+ clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(GATE_SHIFT));
+ clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(RESET_SHIFT));
+ clrbits_le32(ccm + CCU_H6_PLL5_CFG, CCM_PLL5_CTRL_EN);
+ clrbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, DRAM_MOD_RESET);
+ udelay(5);
+
+ /* Set up PLL5 clock, used for DRAM */
+ clrsetbits_le32(ccm + CCU_H6_PLL5_CFG, 0xff03,
+ CCM_PLL5_CTRL_N((clk * 2) / 24) | CCM_PLL5_CTRL_EN);
+ setbits_le32(ccm + CCU_H6_PLL5_CFG, BIT(24));
+ clrsetbits_le32(ccm + CCU_H6_PLL5_CFG, 0x3,
+ CCM_PLL5_LOCK_EN | CCM_PLL5_CTRL_EN | BIT(30));
+ clrbits_le32(ccm + CCU_H6_PLL5_CFG, 0x3 | BIT(30));
+ mctl_await_completion(ccm + CCU_H6_PLL5_CFG,
+ CCM_PLL5_LOCK, CCM_PLL5_LOCK);
+
+ /* Enable DRAM clock and gate*/
+ clrbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, BIT(24) | BIT(25));
+ clrsetbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, 0x1f, BIT(1) | BIT(0));
+ setbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, DRAM_CLK_UPDATE);
+ setbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(RESET_SHIFT));
+ setbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(GATE_SHIFT));
+
+ /* Re-enable MBUS and reset the DRAM module */
+ setbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_RESET);
+ setbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_ENABLE);
+ setbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, DRAM_MOD_RESET);
+ udelay(5);
+}
+
+static void mctl_set_odtmap(const struct dram_para *para,
+ const struct dram_config *config)
+{
+ struct sunxi_mctl_ctl_reg *mctl_ctl =
+ (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
+ u32 val, temp1, temp2;
+
+ /* Set ODT/rank mappings*/
+ if (config->bus_full_width)
+ writel_relaxed(0x0201, &mctl_ctl->odtmap);
+ else
+ writel_relaxed(0x0303, &mctl_ctl->odtmap);
+
+ switch (para->type) {
+ case SUNXI_DRAM_TYPE_DDR3:
+ val = 0x06000400;
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR3:
+ /* TODO: What's the purpose of these values? */
+ temp1 = para->clk * 7 / 2000;
+ if (para->clk < 400)
+ temp2 = 0x3;
+ else
+ temp2 = 0x4;
+
+ val = 0x400 | (temp2 - temp1) << 16 | temp1 << 24;
+ break;
+ case SUNXI_DRAM_TYPE_DDR4:
+ /* MR4: CS to CMD / ADDR Latency and write preamble */
+ val = 0x400 | (0x000 << 10 & 0x70000) |
+ (((0x0000 >> 12) & 1) + 6) << 24;
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR4:
+ val = 0x4000400;
+ break;
+ }
+
+ writel_relaxed(val, &mctl_ctl->odtcfg);
+ /* Documented as ODTCFG_SHADOW */
+ writel_relaxed(val, &mctl_ctl->unk_0x2240);
+ /* Offset's interesting; additional undocumented shadows? */
+ writel_relaxed(val, &mctl_ctl->unk_0x3240);
+ writel_relaxed(val, &mctl_ctl->unk_0x4240);
+}
+
+/*
+ * This function produces address mapping parameters, used internally by the
+ * controller to map address lines to HIF addresses. HIF addresses are word
+ * addresses, not byte addresses;
+ * In other words, DDR address 0x400 maps to HIF address 0x100.
+ *
+ * This implementation sets up a reasonable mapping where HIF address
+ * ordering (LSB->MSB) is as such:
+ * - Bank Groups
+ * - Columns
+ * - Banks
+ * - Rows
+ * - Ranks
+ *
+ * TODO: Handle 1.5GB + 3GB configurations. Info about these is stored in
+ * upper bits of TPR13 after autoscan in boot0, and then some extra logic
+ * happens in the address mapping
+ */
+#define INITIAL_HIF_OFFSET 3
+
+static void mctl_set_addrmap(const struct dram_config *config)
+{
+ struct sunxi_mctl_ctl_reg *mctl_ctl =
+ (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
+ u8 bankgrp_bits = config->bankgrps;
+ u8 col_bits = config->cols;
+ u8 bank_bits = config->banks;
+ u8 row_bits = config->rows;
+ u8 rank_bits = config->ranks;
+
+ unsigned int i, hif_offset, hif_bits[6];
+
+ /*
+ * When the bus is half width, we need to adjust address mapping,
+ * as COL[0] will be reallocated as part of the byte address,
+ * offsetting the column address mapping values by 1
+ */
+ if (!config->bus_full_width)
+ col_bits--;
+
+ /* Match boot0's DRAM requirements */
+ if (bankgrp_bits > 2)
+ panic("invalid dram configuration (bankgrps_bits = %d)",
+ bankgrp_bits);
+ if (col_bits < 8 || col_bits > 12)
+ panic("invalid dram configuration (col_bits = %d)", col_bits);
+
+ if (bank_bits < 2 || bank_bits > 3)
+ panic("invalid dram configuration (bank_bits = %d)", bank_bits);
+
+ if (row_bits < 14 || row_bits > 18)
+ panic("invalid dram configuration (row_bits = %d)", row_bits);
+
+ if (rank_bits > 1)
+ panic("invalid dram configuration (rank_bits = %d)", rank_bits);
+
+ /*
+ * Col[0:1] + HIF[0:1] (hardwired), Col[2] = HIF[2] (required)
+ * Thus, we start allocating from HIF[3] onwards
+ */
+ hif_offset = INITIAL_HIF_OFFSET;
+
+ /* BG[bankgrp_bits:0] = HIF[3 + bankgrp_bits:3]*/
+ switch (bankgrp_bits) {
+ case 0:
+ writel_relaxed(ADDRMAP8_BG0_B2(ADDRMAP_DISABLED_1F_B(2)) |
+ ADDRMAP8_BG1_B3(ADDRMAP_DISABLED_1F_B(3)),
+ &mctl_ctl->addrmap[8]);
+ break;
+ case 1:
+ writel_relaxed(ADDRMAP8_BG0_B2(hif_offset) |
+ ADDRMAP8_BG1_B3(ADDRMAP_DISABLED_1F_B(3)),
+ &mctl_ctl->addrmap[8]);
+ break;
+ case 2:
+ writel_relaxed(ADDRMAP8_BG0_B2(hif_offset) |
+ ADDRMAP8_BG1_B3(hif_offset + 1),
+ &mctl_ctl->addrmap[8]);
+ break;
+ default:
+ panic("invalid dram configuration (bankgrp_bits = %d)",
+ bankgrp_bits);
+ }
+
+ hif_offset += bankgrp_bits;
+
+ /* Col[2] = HIF[2], Col[5:3] = HIF[offset + 2:offset] */
+ writel_relaxed(ADDRMAP2_COL2_B2(2) | ADDRMAP2_COL3_B3(hif_offset) |
+ ADDRMAP2_COL4_B4(hif_offset + 1) |
+ ADDRMAP2_COL5_B5(hif_offset + 2),
+ &mctl_ctl->addrmap[2]);
+
+ /* Col[col_bits:6] = HIF[col_bits + offset - 3:offset - 3] */
+ for (i = 6; i < 12; i++) {
+ if (i < col_bits)
+ hif_bits[i - 6] = hif_offset + (i - INITIAL_HIF_OFFSET);
+ else
+ hif_bits[i - 6] = ADDRMAP_DISABLED_1F_B(i);
+ }
+
+ writel_relaxed(ADDRMAP3_COL6_B6(hif_bits[0]) |
+ ADDRMAP3_COL7_B7(hif_bits[1]) |
+ ADDRMAP3_COL8_B8(hif_bits[2]) |
+ ADDRMAP3_COL9_B9(hif_bits[3]),
+ &mctl_ctl->addrmap[3]);
+
+ writel_relaxed(ADDRMAP4_COL10_B10(hif_bits[4]) |
+ ADDRMAP4_COL11_B11(hif_bits[5]),
+ &mctl_ctl->addrmap[4]);
+
+ hif_offset = bankgrp_bits + col_bits;
+
+ /* Bank[bank_bits:0] = HIF[bank_bits + offset:offset] */
+ if (bank_bits == 3)
+ writel_relaxed(ADDRMAP1_BANK0_B2(hif_offset) |
+ ADDRMAP1_BANK1_B3(hif_offset + 1) |
+ ADDRMAP1_BANK2_B4(hif_offset + 2),
+ &mctl_ctl->addrmap[1]);
+ else
+ writel_relaxed(ADDRMAP1_BANK0_B2(hif_offset) |
+ ADDRMAP1_BANK1_B3(hif_offset + 1) |
+ ADDRMAP1_BANK2_B4(ADDRMAP_DISABLED_1F_B(4)),
+ &mctl_ctl->addrmap[1]);
+
+ hif_offset += bank_bits;
+
+ /* Row[11:0] = HIF[11 + offset:offset] */
+ writel_relaxed(ADDRMAP5_ROW0_B6(hif_offset) |
+ ADDRMAP5_ROW1_B7(hif_offset + 1) |
+ ADDRMAP5_ROW2_10_B8(hif_offset + 2) |
+ ADDRMAP5_ROW11_B17(hif_offset + 11),
+ &mctl_ctl->addrmap[5]);
+
+ /*
+ * There's some complexity here because of a special case
+ * in boot0 code that appears to work around a hardware bug.
+ * For (col_bits, row_bits, rank_bits) = (10, 16, 1), we have to
+ * place CS[0] in the position we would normally place ROW[14],
+ * and shift ROW[14] and ROW[15] over by one. Using the bit following
+ * ROW[15], as would be standard here, seems to cause nonsensical
+ * aliasing patterns.
+ *
+ * Aside from this case, mapping is simple:
+ * Row[row_bits:12] = HIF[offset + row_bits:offset + 12]
+ */
+ for (i = 12; i < 18; i++) {
+ if (i >= row_bits)
+ hif_bits[i - 12] = ADDRMAP_DISABLED_0F_B(6 + i);
+ else if (rank_bits != 1 || col_bits != 10 || row_bits != 16 ||
+ i < 14)
+ hif_bits[i - 12] = hif_offset + i;
+ else
+ hif_bits[i - 12] = hif_offset + i + 1;
+ }
+
+ writel_relaxed(ADDRMAP6_ROW12_B18(hif_bits[0]) |
+ ADDRMAP6_ROW13_B19(hif_bits[1]) |
+ ADDRMAP6_ROW14_B20(hif_bits[2]) |
+ ADDRMAP6_ROW15_B21(hif_bits[3]),
+ &mctl_ctl->addrmap[6]);
+
+ writel_relaxed(ADDRMAP7_ROW16_B22(hif_bits[4]) |
+ ADDRMAP7_ROW17_B23(hif_bits[5]),
+ &mctl_ctl->addrmap[7]);
+
+ hif_offset += row_bits;
+
+ /*
+ * Ranks
+ * Most cases: CS[0] = HIF[offset]
+ * Special case (see above): CS[0] = HIF[offset - 2]
+ */
+ if (rank_bits == 0)
+ writel_relaxed(ADDRMAP0_CS0_B6(ADDRMAP_DISABLED_1F_B(6)),
+ &mctl_ctl->addrmap[0]);
+ else if (col_bits == 10 && row_bits == 16)
+ writel_relaxed(ADDRMAP0_CS0_B6(hif_offset - 2),
+ &mctl_ctl->addrmap[0]);
+ else
+ writel_relaxed(ADDRMAP0_CS0_B6(hif_offset),
+ &mctl_ctl->addrmap[0]);
+}
+
+static void mctl_com_init(const struct dram_para *para,
+ const struct dram_config *config)
+{
+ void *const mctl_com = (void *)SUNXI_DRAM_COM_BASE;
+ struct sunxi_mctl_ctl_reg *mctl_ctl =
+ (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
+ /* Might control power/reset of DDR-related blocks */
+ clrsetbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(24), BIT(25) | BIT(9));
+
+ /* Unlock mctl_ctl registers */
+ setbits_le32(mctl_com + MCTL_COM_MAER0, BIT(15));
+
+ if (para->type == SUNXI_DRAM_TYPE_LPDDR4)
+ setbits_le32(0x03102ea8, BIT(0));
+
+ clrsetbits_le32(&mctl_ctl->sched[0], 0xff << 8, 0x30 << 8);
+ if (!(para->tpr13 & BIT(28)))
+ clrsetbits_le32(&mctl_ctl->sched[0], 0xf, BIT(0));
+
+ writel_relaxed(0, &mctl_ctl->hwlpctl);
+
+ /* Master settings */
+ u32 mstr_value = MSTR_DEVICECONFIG_X32 |
+ MSTR_ACTIVE_RANKS(config->ranks);
+
+ if (config->bus_full_width)
+ mstr_value |= MSTR_BUSWIDTH_FULL;
+ else
+ mstr_value |= MSTR_BUSWIDTH_HALF;
+
+ /*
+ * Geardown and 2T mode are always enabled here, but is controlled by a flag in boot0;
+ * it has not been a problem so far, but may be suspect if a particular board isn't booting.
+ */
+ switch (para->type) {
+ case SUNXI_DRAM_TYPE_DDR3:
+ mstr_value |= MSTR_DEVICETYPE_DDR3 | MSTR_BURST_LENGTH(8) |
+ MSTR_2TMODE;
+ break;
+ case SUNXI_DRAM_TYPE_DDR4:
+ mstr_value |= MSTR_DEVICETYPE_DDR4 | MSTR_BURST_LENGTH(8) |
+ MSTR_GEARDOWNMODE | MSTR_2TMODE;
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR3:
+ mstr_value |= MSTR_DEVICETYPE_LPDDR3 | MSTR_BURST_LENGTH(8);
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR4:
+ mstr_value |= MSTR_DEVICETYPE_LPDDR4 | MSTR_BURST_LENGTH(16);
+ break;
+ }
+
+ writel_relaxed(mstr_value, &mctl_ctl->mstr);
+
+ mctl_set_odtmap(para, config);
+ mctl_set_addrmap(config);
+ mctl_set_timing_params(para);
+
+ dsb();
+ writel(0, &mctl_ctl->pwrctl);
+
+ /* Disable automatic controller updates + automatic controller update requests */
+ setbits_le32(&mctl_ctl->dfiupd[0], BIT(31) | BIT(30));
+ setbits_le32(&mctl_ctl->zqctl[0], BIT(31) | BIT(30));
+ setbits_le32(&mctl_ctl->unk_0x2180, BIT(31) | BIT(30));
+ setbits_le32(&mctl_ctl->unk_0x3180, BIT(31) | BIT(30));
+ setbits_le32(&mctl_ctl->unk_0x4180, BIT(31) | BIT(30));
+
+ /*
+ * Data bus inversion
+ * Controlled by a flag in boot0, enabled by default here.
+ */
+ if (para->type == SUNXI_DRAM_TYPE_DDR4 ||
+ para->type == SUNXI_DRAM_TYPE_LPDDR4)
+ setbits_le32(&mctl_ctl->dbictl, BIT(2));
+}
+
+static void mctl_drive_odt_config(const struct dram_para *para)
+{
+ u32 val;
+ u64 base;
+ u32 i;
+
+ /* DX drive */
+ for (i = 0; i < 4; i++) {
+ base = SUNXI_DRAM_PHY0_BASE + 0x388 + 0x40 * i;
+ val = (para->dx_dri >> (i * 8)) & 0x1f;
+
+ writel_relaxed(val, base);
+ if (para->type == SUNXI_DRAM_TYPE_LPDDR4) {
+ if (para->tpr3 & 0x1f1f1f1f)
+ val = (para->tpr3 >> (i * 8)) & 0x1f;
+ else
+ val = 4;
+ }
+ writel_relaxed(val, base + 4);
+ }
+
+ /* CA drive */
+ for (i = 0; i < 2; i++) {
+ base = SUNXI_DRAM_PHY0_BASE + 0x340 + 0x8 * i;
+ val = (para->ca_dri >> (i * 8)) & 0x1f;
+
+ writel_relaxed(val, base);
+ writel_relaxed(val, base + 4);
+ }
+
+ /* DX ODT */
+ for (i = 0; i < 4; i++) {
+ base = SUNXI_DRAM_PHY0_BASE + 0x380 + 0x40 * i;
+ val = (para->dx_odt >> (i * 8)) & 0x1f;
+
+ if (para->type == SUNXI_DRAM_TYPE_DDR4 ||
+ para->type == SUNXI_DRAM_TYPE_LPDDR3)
+ writel_relaxed(0, base);
+ else
+ writel_relaxed(val, base);
+
+ if (para->type == SUNXI_DRAM_TYPE_LPDDR4)
+ writel_relaxed(0, base + 4);
+ else
+ writel_relaxed(val, base + 4);
+ }
+ dsb();
+}
+
+static void mctl_phy_ca_bit_delay_compensation(const struct dram_para *para)
+{
+ u32 val, i;
+ u32 *ptr;
+
+ if (para->tpr10 & BIT(31)) {
+ val = para->tpr2;
+ } else {
+ val = ((para->tpr10 << 1) & 0x1e) |
+ ((para->tpr10 << 5) & 0x1e00) |
+ ((para->tpr10 << 9) & 0x1e0000) |
+ ((para->tpr10 << 13) & 0x1e000000);
+
+ if (para->tpr10 >> 29 != 0)
+ val <<= 1;
+ }
+
+ ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x780);
+ for (i = 0; i < 32; i++)
+ writel_relaxed((val >> 8) & 0x3f, &ptr[i]);
+
+ writel_relaxed(val & 0x3f, SUNXI_DRAM_PHY0_BASE + 0x7dc);
+ writel_relaxed(val & 0x3f, SUNXI_DRAM_PHY0_BASE + 0x7e0);
+
+ switch (para->type) {
+ case SUNXI_DRAM_TYPE_DDR3:
+ writel_relaxed((val >> 16) & 0x3f,
+ SUNXI_DRAM_PHY0_BASE + 0x7b8);
+ writel_relaxed((val >> 24) & 0x3f,
+ SUNXI_DRAM_PHY0_BASE + 0x784);
+ break;
+ case SUNXI_DRAM_TYPE_DDR4:
+ writel_relaxed((val >> 16) & 0x3f,
+ SUNXI_DRAM_PHY0_BASE + 0x784);
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR3:
+ writel_relaxed((val >> 16) & 0x3f,
+ SUNXI_DRAM_PHY0_BASE + 0x788);
+ writel_relaxed((val >> 24) & 0x3f,
+ SUNXI_DRAM_PHY0_BASE + 0x790);
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR4:
+ writel_relaxed((val >> 16) & 0x3f,
+ SUNXI_DRAM_PHY0_BASE + 0x790);
+ writel_relaxed((val >> 24) & 0x3f,
+ SUNXI_DRAM_PHY0_BASE + 0x78c);
+ break;
+ }
+
+ dsb();
+}
+
+static void mctl_phy_init(const struct dram_para *para,
+ const struct dram_config *config)
+{
+ struct sunxi_mctl_ctl_reg *mctl_ctl =
+ (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+ void *const prcm = (void *)SUNXI_PRCM_BASE;
+ void *const mctl_com = (void *)SUNXI_DRAM_COM_BASE;
+
+ u32 val, val2, i;
+ u32 *ptr;
+
+ /* Disable auto refresh. */
+ setbits_le32(&mctl_ctl->rfshctl3, BIT(0));
+
+ /* Set "phy_dbi_mode" to mark the DFI as implementing DBI functionality */
+ writel_relaxed(0, &mctl_ctl->pwrctl);
+ clrbits_le32(&mctl_ctl->dfimisc, 1);
+ writel_relaxed(0x20, &mctl_ctl->pwrctl);
+
+ /* PHY cold reset */
+ clrsetbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(24), BIT(9));
+ udelay(1);
+ setbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(24));
+
+ /* Not sure what this gates the power of. */
+ clrbits_le32(prcm + CCU_PRCM_SYS_PWROFF_GATING, BIT(4));
+
+ if (para->type == SUNXI_DRAM_TYPE_LPDDR4)
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x4, BIT(7));
+
+ /* Note: Similar enumeration of values is used during read training */
+ if (config->bus_full_width)
+ val = 0xf;
+ else
+ val = 0x3;
+
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x3c, 0xf, val);
+
+ switch (para->type) {
+ case SUNXI_DRAM_TYPE_DDR3:
+ val = 13;
+ val2 = 9;
+ break;
+ case SUNXI_DRAM_TYPE_DDR4:
+ val = 13;
+ val2 = 10;
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR3:
+ val = 14;
+ val2 = 8;
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR4:
+ if (para->tpr13 & BIT(28))
+ val = 22;
+ else
+ val = 20;
+
+ val2 = 10;
+ break;
+ }
+
+ writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x14);
+ writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x35c);
+ writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x368);
+ writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x374);
+ writel_relaxed(0, SUNXI_DRAM_PHY0_BASE + 0x18);
+ writel_relaxed(0, SUNXI_DRAM_PHY0_BASE + 0x360);
+ writel_relaxed(0, SUNXI_DRAM_PHY0_BASE + 0x36c);
+ writel_relaxed(0, SUNXI_DRAM_PHY0_BASE + 0x378);
+ writel_relaxed(val2, SUNXI_DRAM_PHY0_BASE + 0x1c);
+ writel_relaxed(val2, SUNXI_DRAM_PHY0_BASE + 0x364);
+ writel_relaxed(val2, SUNXI_DRAM_PHY0_BASE + 0x370);
+ writel_relaxed(val2, SUNXI_DRAM_PHY0_BASE + 0x37c);
+
+ /* Set up SDQ swizzle */
+ ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xc0);
+ for (i = 0; i < ARRAY_SIZE(phy_init); i++)
+ writel_relaxed(phy_init[i], &ptr[i]);
+
+ /* Set VREF */
+ val = 0;
+ switch (para->type) {
+ case SUNXI_DRAM_TYPE_DDR3:
+ val = para->tpr6 & 0xff;
+ if (val == 0)
+ val = 0x80;
+ break;
+ case SUNXI_DRAM_TYPE_DDR4:
+ val = (para->tpr6 >> 8) & 0xff;
+ if (val == 0)
+ val = 0x80;
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR3:
+ val = (para->tpr6 >> 16) & 0xff;
+ if (val == 0)
+ val = 0x80;
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR4:
+ val = (para->tpr6 >> 24) & 0xff;
+ if (val == 0)
+ val = 0x33;
+ break;
+ }
+ writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x3dc);
+ writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x45c);
+
+ mctl_drive_odt_config(para);
+
+ if (para->tpr10 & TPR10_CA_BIT_DELAY)
+ mctl_phy_ca_bit_delay_compensation(para);
+
+ switch (para->type) {
+ case SUNXI_DRAM_TYPE_DDR3:
+ val = 2;
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR3:
+ val = 3;
+ break;
+ case SUNXI_DRAM_TYPE_DDR4:
+ val = 4;
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR4:
+ val = 5;
+ break;
+ }
+
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x4, 0x7, val | 8);
+
+ if (para->clk <= 672)
+ writel_relaxed(0xf, SUNXI_DRAM_PHY0_BASE + 0x20);
+
+ if (para->clk > 500) {
+ val = 0;
+ val2 = 0;
+ } else {
+ val = 0x80;
+ val2 = 0x20;
+ }
+
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x144, 0x80, val);
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x14c, 0xe0, val2);
+
+ dsb();
+ clrbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(9));
+ udelay(1);
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x14c, BIT(3));
+
+ mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x180), BIT(2),
+ BIT(2));
+
+ /*
+ * This delay is controlled by a tpr13 flag in boot0; doesn't hurt
+ * to always do it though.
+ */
+ udelay(1000);
+ writel(0x37, SUNXI_DRAM_PHY0_BASE + 0x58);
+
+ setbits_le32(prcm + CCU_PRCM_SYS_PWROFF_GATING, BIT(4));
+}
+
+/* Helpers for updating mode registers */
+static inline void mctl_mr_write(u32 mrctrl0, u32 mrctrl1)
+{
+ struct sunxi_mctl_ctl_reg *mctl_ctl =
+ (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
+ writel(mrctrl1, &mctl_ctl->mrctrl1);
+ writel(mrctrl0 | MRCTRL0_MR_WR | MRCTRL0_MR_RANKS_ALL,
+ &mctl_ctl->mrctrl0);
+ mctl_await_completion(&mctl_ctl->mrctrl0, MRCTRL0_MR_WR, 0);
+}
+
+static inline void mctl_mr_write_lpddr4(u8 addr, u8 value)
+{
+ mctl_mr_write(0, MRCTRL1_MR_ADDR(addr) | MRCTRL1_MR_DATA(value));
+}
+
+static inline void mctl_mr_write_lpddr3(u8 addr, u8 value)
+{
+ /* Bit [7:6] are set by boot0, but undocumented */
+ mctl_mr_write(BIT(6) | BIT(7),
+ MRCTRL1_MR_ADDR(addr) | MRCTRL1_MR_DATA(value));
+}
+
+static void mctl_dfi_init(const struct dram_para *para)
+{
+ void *const mctl_com = (void *)SUNXI_DRAM_COM_BASE;
+ struct sunxi_mctl_ctl_reg *mctl_ctl =
+ (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
+ /* Unlock DFI registers? */
+ setbits_le32(mctl_com + MCTL_COM_MAER0, BIT(8));
+
+ /* Enable dfi_init_complete signal and trigger PHY init start request */
+ writel_relaxed(0, &mctl_ctl->swctl);
+ setbits_le32(&mctl_ctl->dfimisc, BIT(0));
+ setbits_le32(&mctl_ctl->dfimisc, BIT(5));
+ writel_relaxed(1, &mctl_ctl->swctl);
+ mctl_await_completion(&mctl_ctl->swstat, BIT(0), BIT(0));
+
+ /* Stop sending init request and wait for DFI initialization to complete. */
+ writel_relaxed(0, &mctl_ctl->swctl);
+ clrbits_le32(&mctl_ctl->dfimisc, BIT(5));
+ writel_relaxed(1, &mctl_ctl->swctl);
+ mctl_await_completion(&mctl_ctl->swstat, BIT(0), BIT(0));
+ mctl_await_completion(&mctl_ctl->dfistat, BIT(0), BIT(0));
+
+ /* Enter Software Exit from Self Refresh */
+ writel_relaxed(0, &mctl_ctl->swctl);
+ clrbits_le32(&mctl_ctl->pwrctl, BIT(5));
+ writel_relaxed(1, &mctl_ctl->swctl);
+ mctl_await_completion(&mctl_ctl->swstat, BIT(0), BIT(0));
+ mctl_await_completion(&mctl_ctl->statr, 0x3, 1);
+
+ udelay(200);
+
+ /* Disable dfi_init_complete signal */
+ writel_relaxed(0, &mctl_ctl->swctl);
+ clrbits_le32(&mctl_ctl->dfimisc, BIT(0));
+ writel_relaxed(1, &mctl_ctl->swctl);
+ mctl_await_completion(&mctl_ctl->swstat, BIT(0), BIT(0));
+
+ /* Write mode registers, fixed in the JEDEC spec */
+ switch (para->type) {
+ case SUNXI_DRAM_TYPE_DDR3:
+ mctl_mr_write(MRCTRL0_MR_ADDR(0), 0x1c70); /* MR0 */
+ /*
+ * outbuf en, TDQs dis, write leveling dis, out drv 40 Ohms,
+ * DLL en, Rtt_nom 120 Ohms
+ */
+ mctl_mr_write(MRCTRL0_MR_ADDR(1), 0x40); /* MR1 */
+ /*
+ * full array self-ref, CAS: 8 cyc, SRT w/ norm temp range,
+ * dynamic ODT off
+ */
+ mctl_mr_write(MRCTRL0_MR_ADDR(2), 0x18); /* MR2 */
+ /* predef MPR pattern */
+ mctl_mr_write(MRCTRL0_MR_ADDR(3), 0); /* MR3 */
+ break;
+ case SUNXI_DRAM_TYPE_DDR4:
+ mctl_mr_write(MRCTRL0_MR_ADDR(0), 0x840);
+ mctl_mr_write(MRCTRL0_MR_ADDR(1), 0x601);
+ mctl_mr_write(MRCTRL0_MR_ADDR(2), 0x8);
+ mctl_mr_write(MRCTRL0_MR_ADDR(3), 0);
+ mctl_mr_write(MRCTRL0_MR_ADDR(4), 0);
+ mctl_mr_write(MRCTRL0_MR_ADDR(5), 0x400);
+
+ mctl_mr_write(MRCTRL0_MR_ADDR(6), 0x862 | BIT(7));
+ mctl_mr_write(MRCTRL0_MR_ADDR(6), 0x862 | BIT(7));
+ mctl_mr_write(MRCTRL0_MR_ADDR(6), 0x862 & (~BIT(7)));
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR3:
+ mctl_mr_write_lpddr3(1, 0xc3); /* MR1: nWR=8, BL8 */
+ mctl_mr_write_lpddr3(2, 0xa); /* MR2: RL=12, WL=6 */
+ mctl_mr_write_lpddr3(3, 0x2); /* MR3: 40 0hms PD/PU */
+ mctl_mr_write_lpddr3(11, para->mr11);
+ break;
+ case SUNXI_DRAM_TYPE_LPDDR4:
+ mctl_mr_write_lpddr4(0, 0); /* MR0 */
+ mctl_mr_write_lpddr4(1, 0x34); /* MR1 */
+ mctl_mr_write_lpddr4(2, 0x1b); /* MR2 */
+ mctl_mr_write_lpddr4(3, 0x33); /* MR3 */
+ mctl_mr_write_lpddr4(4, 0x3); /* MR4 */
+ mctl_mr_write_lpddr4(11, para->mr11);
+ mctl_mr_write_lpddr4(12, para->mr12);
+ mctl_mr_write_lpddr4(13, para->mr13);
+ mctl_mr_write_lpddr4(14, para->mr14);
+ mctl_mr_write_lpddr4(22, para->tpr1);
+ break;
+ }
+
+ writel(0, SUNXI_DRAM_PHY0_BASE + 0x54);
+
+ /* Re-enable controller refresh */
+ writel(0, &mctl_ctl->swctl);
+ clrbits_le32(&mctl_ctl->rfshctl3, BIT(0));
+ writel(1, &mctl_ctl->swctl);
+}
+
+/* Slightly modified from H616 driver */
+static bool mctl_phy_read_calibration(const struct dram_config *config)
+{
+ bool result = true;
+ u32 val, tmp;
+
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 0x30, 0x20);
+
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 1);
+
+ if (config->bus_full_width)
+ val = 0xf;
+ else
+ val = 3;
+
+ while ((readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x184) & val) != val) {
+ if (readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x184) & 0x20) {
+ result = false;
+ break;
+ }
+ }
+
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 1);
+
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 0x30);
+
+ if (config->ranks == 1) {
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 0x30, 0x10);
+
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 1);
+
+ while ((readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x184) & val) !=
+ val) {
+ if (readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x184) &
+ 0x20) {
+ result = false;
+ break;
+ }
+ }
+
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 1);
+ }
+
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 0x30);
+
+ val = readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x274) & 7;
+ tmp = readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x26c) & 7;
+ if (val < tmp)
+ val = tmp;
+ tmp = readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x32c) & 7;
+ if (val < tmp)
+ val = tmp;
+ tmp = readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x334) & 7;
+ if (val < tmp)
+ val = tmp;
+ clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x38, 0x7, (val + 2) & 7);
+
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 0x20);
+
+ return result;
+}
+
+static inline void mctl_phy_dx_delay1_inner(u32 *base, u32 val1, u32 val2)
+{
+ u32 *ptr = base;
+
+ for (int i = 0; i < 9; i++) {
+ writel_relaxed(val1, ptr);
+ writel_relaxed(val1, ptr + 0x30);
+ ptr += 2;
+ }
+
+ writel_relaxed(val2, ptr + 1);
+ writel_relaxed(val2, ptr + 49);
+ writel_relaxed(val2, ptr);
+ writel_relaxed(val2, ptr + 48);
+}
+
+static inline void mctl_phy_dx_delay0_inner(u32 *base1, u32 *base2, u32 val1,
+ u32 val2)
+{
+ u32 *ptr = base1;
+
+ for (int i = 0; i < 9; i++) {
+ writel_relaxed(val1, ptr);
+ writel_relaxed(val1, ptr + 0x30);
+ ptr += 2;
+ }
+
+ writel_relaxed(val2, base2);
+ writel_relaxed(val2, base2 + 48);
+ writel_relaxed(val2, ptr);
+ writel_relaxed(val2, base2 + 44);
+}
+
+/*
+ * This might be somewhat transferable to H616; whether or not people like
+ * the design is another question
+ */
+static void mctl_phy_dx_delay_compensation(const struct dram_para *para)
+{
+ if (para->tpr10 & TPR10_DX_BIT_DELAY1) {
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, BIT(3));
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, BIT(4));
+
+ if (para->type == SUNXI_DRAM_TYPE_DDR4)
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x4, BIT(7));
+
+ mctl_phy_dx_delay1_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x484),
+ para->tpr11 & 0x3f,
+ para->para0 & 0x3f);
+ mctl_phy_dx_delay1_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d8),
+ (para->tpr11 >> 8) & 0x3f,
+ (para->para0 >> 8) & 0x3f);
+ mctl_phy_dx_delay1_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x604),
+ (para->tpr11 >> 16) & 0x3f,
+ (para->para0 >> 16) & 0x3f);
+ mctl_phy_dx_delay1_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x658),
+ (para->tpr11 >> 24) & 0x3f,
+ (para->para0 >> 24) & 0x3f);
+
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
+ }
+
+ if (para->tpr10 & TPR10_DX_BIT_DELAY0) {
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, BIT(7));
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, BIT(2));
+
+ mctl_phy_dx_delay0_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480),
+ (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x528),
+ para->tpr12 & 0x3f,
+ para->tpr14 & 0x3f);
+
+ mctl_phy_dx_delay0_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4),
+ (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x52c),
+ (para->tpr12 >> 8) & 0x3f,
+ (para->tpr14 >> 8) & 0x3f);
+
+ mctl_phy_dx_delay0_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600),
+ (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x6a8),
+ (para->tpr12 >> 16) & 0x3f,
+ (para->tpr14 >> 16) & 0x3f);
+
+ mctl_phy_dx_delay0_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x6ac),
+ (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x528),
+ (para->tpr12 >> 24) & 0x3f,
+ (para->tpr14 >> 24) & 0x3f);
+
+ setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, BIT(7));
+ }
+}
+
+static bool mctl_calibrate_phy(const struct dram_para *para,
+ const struct dram_config *config)
+{
+ struct sunxi_mctl_ctl_reg *mctl_ctl =
+ (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
+ int i;
+
+ /* TODO: Implement write levelling */
+ if (para->tpr10 & TPR10_READ_CALIBRATION) {
+ for (i = 0; i < 5; i++)
+ if (mctl_phy_read_calibration(config))
+ break;
+ if (i == 5) {
+ debug("read calibration failed\n");
+ return false;
+ }
+ }
+
+ /* TODO: Implement read training */
+ /* TODO: Implement write training */
+
+ mctl_phy_dx_delay_compensation(para);
+ /* TODO: Implement DFS */
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, BIT(0));
+ clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 7);
+
+ /* Q: Does self-refresh get disabled by a calibration? */
+ writel_relaxed(0, &mctl_ctl->swctl);
+ clrbits_le32(&mctl_ctl->rfshctl3, BIT(1));
+ writel_relaxed(1, &mctl_ctl->swctl);
+ mctl_await_completion(&mctl_ctl->swstat, BIT(0), BIT(0));
+
+ return true;
+}
+
+static bool mctl_core_init(const struct dram_para *para,
+ const struct dram_config *config)
+{
+ mctl_clk_init(para->clk);
+ mctl_com_init(para, config);
+ mctl_phy_init(para, config);
+ mctl_dfi_init(para);
+
+ return mctl_calibrate_phy(para, config);
+}
+
+/* Heavily inspired from H616 driver. */
+static void auto_detect_ranks(const struct dram_para *para,
+ struct dram_config *config)
+{
+ int i;
+
+ config->cols = 9;
+ config->rows = 14;
+ config->banks = 2;
+ config->bankgrps = 0;
+
+ /* Test ranks */
+ for (i = 1; i >= 0; i--) {
+ config->ranks = i;
+ config->bus_full_width = true;
+ debug("Testing ranks = %d, 32-bit bus: ", i);
+ if (mctl_core_init(para, config)) {
+ debug("OK\n");
+ break;
+ }
+
+ config->bus_full_width = false;
+ debug("Testing ranks = %d, 16-bit bus: ", i);
+ if (mctl_core_init(para, config)) {
+ debug("OK\n");
+ break;
+ }
+ }
+
+ if (i < 0)
+ debug("rank testing failed\n");
+}
+
+static void mctl_write_pattern(void)
+{
+ unsigned int i;
+ u32 *ptr, val;
+
+ ptr = (u32 *)CFG_SYS_SDRAM_BASE;
+ for (i = 0; i < 16; ptr++, i++) {
+ if (i & 1)
+ val = ~(ulong)ptr;
+ else
+ val = (ulong)ptr;
+ writel(val, ptr);
+ }
+}
+
+static bool mctl_check_pattern(ulong offset)
+{
+ unsigned int i;
+ u32 *ptr, val;
+
+ ptr = (u32 *)CFG_SYS_SDRAM_BASE;
+ for (i = 0; i < 16; ptr++, i++) {
+ if (i & 1)
+ val = ~(ulong)ptr;
+ else
+ val = (ulong)ptr;
+ if (val != *(ptr + offset / 4))
+ return false;
+ }
+
+ return true;
+}
+
+static void mctl_auto_detect_dram_size(const struct dram_para *para,
+ struct dram_config *config)
+{
+ unsigned int shift;
+ u32 buffer[16];
+
+ /* max config for bankgrps on DDR4, minimum for everything else */
+ config->cols = 8;
+ config->banks = 2;
+ config->rows = 14;
+
+ shift = 1 + config->bus_full_width;
+ if (para->type == SUNXI_DRAM_TYPE_DDR4) {
+ config->bankgrps = 2;
+ mctl_core_init(para, config);
+
+ /* store content so it can be restored later. */
+ memcpy(buffer, (u32 *)CFG_SYS_SDRAM_BASE, sizeof(buffer));
+ mctl_write_pattern();
+
+ if (mctl_check_pattern(1ULL << (shift + 4)))
+ config->bankgrps = 1;
+
+ /* restore data */
+ memcpy((u32 *)CFG_SYS_SDRAM_BASE, buffer, sizeof(buffer));
+ } else {
+ /* No bank groups in (LP)DDR3/LPDDR4 */
+ config->bankgrps = 0;
+ }
+
+ /* reconfigure to make sure all active columns are accessible */
+ config->cols = 12;
+ mctl_core_init(para, config);
+
+ /* store data again as it might be moved */
+ memcpy(buffer, (u32 *)CFG_SYS_SDRAM_BASE, sizeof(buffer));
+ mctl_write_pattern();
+
+ /*
+ * Detect column address bits. The last number of columns checked
+ * is 11, if that doesn't match, is must be 12, no more checks needed.
+ */
+ shift = 1 + config->bus_full_width + config->bankgrps;
+ for (config->cols = 8; config->cols < 12; config->cols++) {
+ if (mctl_check_pattern(1ULL << (config->cols + shift)))
+ break;
+ }
+ memcpy((u32 *)CFG_SYS_SDRAM_BASE, buffer, sizeof(buffer));
+
+ /* reconfigure to make sure that all active banks are accessible */
+ config->banks = 3;
+ mctl_core_init(para, config);
+
+ memcpy(buffer, (u32 *)CFG_SYS_SDRAM_BASE, sizeof(buffer));
+ mctl_write_pattern();
+
+ /* detect bank bits */
+ shift += config->cols;
+ for (config->banks = 2; config->banks < 3; config->banks++) {
+ if (mctl_check_pattern(1ULL << (config->banks + shift)))
+ break;
+ }
+ memcpy((u32 *)CFG_SYS_SDRAM_BASE, buffer, sizeof(buffer));
+
+ /* reconfigure to make sure that all active rows are accessible */
+ config->rows = 18;
+ mctl_core_init(para, config);
+
+ memcpy(buffer, (u32 *)CFG_SYS_SDRAM_BASE, sizeof(buffer));
+ mctl_write_pattern();
+
+ /* detect row address bits */
+ shift += config->banks;
+ for (config->rows = 14; config->rows < 18; config->rows++) {
+ if (mctl_check_pattern(1ULL << (config->rows + shift)))
+ break;
+ }
+ memcpy((u32 *)CFG_SYS_SDRAM_BASE, buffer, sizeof(buffer));
+}
+
+/* Modified from H616 driver to add banks and bank groups */
+static unsigned long calculate_dram_size(const struct dram_config *config)
+{
+ /* Bootrom only uses x32 or x16 bus widths */
+ u8 width = config->bus_full_width ? 4 : 2;
+
+ return (1ULL << (config->cols + config->rows + config->banks +
+ config->bankgrps)) *
+ width * (1ULL << config->ranks);
+}
+
+static const struct dram_para para = {
+ .clk = CONFIG_DRAM_CLK,
+#ifdef CONFIG_SUNXI_DRAM_DDR3
+ .type = SUNXI_DRAM_TYPE_DDR3,
+#elif defined(CONFIG_SUNXI_DRAM_DDR4)
+ .type = SUNXI_DRAM_TYPE_DDR4,
+#elif defined(CONFIG_SUNXI_DRAM_LPDDR3)
+ .type = SUNXI_DRAM_TYPE_LPDDR3,
+#elif defined(CONFIG_SUNXI_DRAM_LPDDR4)
+ .type = SUNXI_DRAM_TYPE_LPDDR4,
+#endif
+ /* TODO: Populate from config */
+ .dx_odt = CONFIG_DRAM_SUNXI_DX_ODT,
+ .dx_dri = CONFIG_DRAM_SUNXI_DX_DRI,
+ .ca_dri = CONFIG_DRAM_SUNXI_CA_DRI,
+ .para0 = CONFIG_DRAM_SUNXI_PARA0,
+ .mr11 = CONFIG_DRAM_SUNXI_MR11,
+ .mr12 = CONFIG_DRAM_SUNXI_MR12,
+ .mr13 = CONFIG_DRAM_SUNXI_MR13,
+ .mr14 = CONFIG_DRAM_SUNXI_MR14,
+ .tpr1 = CONFIG_DRAM_SUNXI_TPR1,
+ .tpr2 = CONFIG_DRAM_SUNXI_TPR2,
+ .tpr3 = CONFIG_DRAM_SUNXI_TPR3,
+ .tpr6 = CONFIG_DRAM_SUNXI_TPR6,
+ .tpr10 = CONFIG_DRAM_SUNXI_TPR10,
+ .tpr11 = CONFIG_DRAM_SUNXI_TPR11,
+ .tpr12 = CONFIG_DRAM_SUNXI_TPR12,
+ .tpr13 = CONFIG_DRAM_SUNXI_TPR13,
+ .tpr14 = CONFIG_DRAM_SUNXI_TPR14,
+};
+
+unsigned long sunxi_dram_init(void)
+{
+ struct dram_config config;
+
+ /* Writing to undocumented SYS_CFG area, according to user manual. */
+ setbits_le32(0x03000160, BIT(8));
+ clrbits_le32(0x03000168, 0x3f);
+
+ auto_detect_ranks(&para, &config);
+ mctl_auto_detect_dram_size(&para, &config);
+
+ if (!mctl_core_init(&para, &config))
+ return 0;
+
+ debug("cols = 2^%d, rows = 2^%d, banks = %d, bank groups = %d, ranks = %d, width = %d\n",
+ config.cols, config.rows, 1U << config.banks,
+ 1U << config.bankgrps, 1U << config.ranks,
+ 16U << config.bus_full_width);
+
+ return calculate_dram_size(&config);
+}
diff --git a/arch/arm/mach-sunxi/dram_timings/Makefile b/arch/arm/mach-sunxi/dram_timings/Makefile
index 5f203419240..4dc1f29fc08 100644
--- a/arch/arm/mach-sunxi/dram_timings/Makefile
+++ b/arch/arm/mach-sunxi/dram_timings/Makefile
@@ -6,3 +6,5 @@ obj-$(CONFIG_SUNXI_DRAM_H6_DDR3_1333) += h6_ddr3_1333.o
obj-$(CONFIG_SUNXI_DRAM_H616_DDR3_1333) += h616_ddr3_1333.o
obj-$(CONFIG_SUNXI_DRAM_H616_LPDDR3) += h616_lpddr3.o
obj-$(CONFIG_SUNXI_DRAM_H616_LPDDR4) += h616_lpddr4_2133.o
+obj-$(CONFIG_SUNXI_DRAM_A133_DDR4) += a133_ddr4.o
+obj-$(CONFIG_SUNXI_DRAM_A133_LPDDR4) += a133_lpddr4.o
diff --git a/arch/arm/mach-sunxi/dram_timings/a133_ddr4.c b/arch/arm/mach-sunxi/dram_timings/a133_ddr4.c
new file mode 100644
index 00000000000..dec208e22df
--- /dev/null
+++ b/arch/arm/mach-sunxi/dram_timings/a133_ddr4.c
@@ -0,0 +1,80 @@
+#include <asm/arch/cpu.h>
+#include <asm/arch/dram.h>
+
+void mctl_set_timing_params(const struct dram_para *para)
+{
+ struct sunxi_mctl_ctl_reg *const mctl_ctl =
+ (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
+ u8 txsr = 4;
+ u8 tccd = 3;
+ u8 rd2wr = 5;
+ u8 tmrd = 4;
+ u8 tmrw = 0;
+ u8 wrlat = 5;
+ u8 rdlat = 7;
+ u8 wr2pre = 14;
+ u8 dfi_tphy_wrlat = 6;
+ u8 dfi_trddata_en = 10;
+
+ u8 tfaw = ns_to_t(35);
+ u8 trrd = max(ns_to_t(8), 2);
+ u8 txp = max(ns_to_t(6), 2);
+ u8 tmrd_pda = max(ns_to_t(10), 8);
+ u8 trp = ns_to_t(15);
+ u8 trc = ns_to_t(49);
+ u8 wr2rd_s = max(ns_to_t(3), 1) + 7;
+ u8 tras_min = ns_to_t(34);
+ u16 trefi_x32 = ns_to_t(7800) / 32;
+ u16 trfc_min = ns_to_t(350);
+ u16 txs_x32 = ns_to_t(360) / 32;
+ u16 tmod = max(ns_to_t(15), 12);
+ u8 tcke = max(ns_to_t(5), 2);
+ u8 tcksrx = max(ns_to_t(10), 3);
+ u8 txs_abort_x32 = ns_to_t(170) / 32;
+ u8 tras_max = ns_to_t(70200) / 1024;
+
+ u8 rd2pre = (trp < 5 ? 9 - trp : 4);
+ u8 wr2rd = trrd + 7;
+ u8 tckesr = tcke + 1;
+ u8 trcd = trp;
+ u8 trrd_s = txp;
+ u8 tcksre = tcksrx;
+
+ writel(tras_min | tras_max << 8 | tfaw << 16 | wr2pre << 24,
+ &mctl_ctl->dramtmg[0]);
+ writel(trc | rd2pre << 8 | txp << 16, &mctl_ctl->dramtmg[1]);
+ writel(wr2rd | rd2wr << 8 | rdlat << 16 | wrlat << 24,
+ &mctl_ctl->dramtmg[2]);
+ writel(tmod | tmrd << 12 | tmrw << 20, &mctl_ctl->dramtmg[3]);
+ writel(trp | trrd << 8 | tccd << 16 | trcd << 24,
+ &mctl_ctl->dramtmg[4]);
+ writel(tcke | tckesr << 8 | tcksre << 16 | tcksrx << 24,
+ &mctl_ctl->dramtmg[5]);
+ writel((txp + 2) | 0x20 << 16 | 0x20 << 24,
+ &mctl_ctl->dramtmg[6]);
+ writel(txs_x32 | 0x10 << 8 | txs_abort_x32 << 16 | txs_abort_x32 << 24,
+ &mctl_ctl->dramtmg[8]);
+ writel(wr2rd_s | trrd_s << 8 | 0x2 << 16, &mctl_ctl->dramtmg[9]);
+ writel(0xe0c05, &mctl_ctl->dramtmg[10]);
+ writel(0x440c021c, &mctl_ctl->dramtmg[11]);
+ writel(tmrd_pda, &mctl_ctl->dramtmg[12]);
+ writel(0xa100002, &mctl_ctl->dramtmg[13]);
+ writel(txsr, &mctl_ctl->dramtmg[14]);
+
+ clrsetbits_le32(&mctl_ctl->init[0], 0xc0000fff, 1008);
+ writel(0x1f20000, &mctl_ctl->init[1]);
+ clrsetbits_le32(&mctl_ctl->init[2], 0xff0f, 0xd05);
+ writel(0, &mctl_ctl->dfimisc);
+
+ writel(0x840 << 16 | 0x601, &mctl_ctl->init[3]); /* MR0 / MR1 */
+ writel(0x8 << 16 | 0x0, &mctl_ctl->init[4]); /* MR2 / MR3 */
+ writel(0x0 << 16 | 0x400, &mctl_ctl->init[6]); /* MR4 / MR5 */
+ writel(0x826, &mctl_ctl->init[7]); /* MR6 */
+
+ clrsetbits_le32(&mctl_ctl->rankctl, 0xff0, 0x660);
+ writel((dfi_tphy_wrlat - 1) | 0x2000000 | (dfi_trddata_en - 1) << 16 |
+ 0x808000, &mctl_ctl->dfitmg0);
+ writel(0x100202, &mctl_ctl->dfitmg1);
+ writel(trfc_min | trefi_x32 << 16, &mctl_ctl->rfshtmg);
+}
diff --git a/arch/arm/mach-sunxi/dram_timings/a133_lpddr4.c b/arch/arm/mach-sunxi/dram_timings/a133_lpddr4.c
new file mode 100644
index 00000000000..1e607381023
--- /dev/null
+++ b/arch/arm/mach-sunxi/dram_timings/a133_lpddr4.c
@@ -0,0 +1,102 @@
+#include <asm/arch/cpu.h>
+#include <asm/arch/dram.h>
+
+void mctl_set_timing_params(const struct dram_para *para)
+{
+ struct sunxi_mctl_ctl_reg *const mctl_ctl =
+ (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
+ bool tpr13_flag1 = para->tpr13 & BIT(28);
+ bool tpr13_flag2 = para->tpr13 & BIT(3);
+ bool tpr13_flag3 = para->tpr13 & BIT(5);
+
+ u8 tccd = 4;
+ u8 tfaw = ns_to_t(40);
+ u8 trrd = max(ns_to_t(10), 2);
+ u8 trcd = max(ns_to_t(18), 2);
+ u8 trc = ns_to_t(65);
+ u8 txp = max(ns_to_t(8), 2);
+
+ u8 trp = ns_to_t(21);
+ u8 tras_min = ns_to_t(42);
+ u16 trefi_x32 = ns_to_t(3904) / 32;
+ u16 trfc_min = ns_to_t(180);
+ u16 txsr = ns_to_t(190);
+
+ u8 tmrw = max(ns_to_t(14), 5);
+ u8 tmrd = max(ns_to_t(14), 5);
+ u8 tmod = 12;
+ u8 tcke = max(ns_to_t(15), 2);
+ u8 tcksrx = max(ns_to_t(2), 2);
+ u8 tcksre = max(ns_to_t(5), 2);
+ u8 tckesr = max(ns_to_t(15), 2);
+ u8 tras_max = (trefi_x32 * 9) / 32;
+ u8 txs_x32 = 4;
+ u8 txsabort_x32 = 4;
+
+ u8 wrlat = 5;
+ u8 wr2rd_s = 8;
+ u8 trrd_s = 2;
+ u8 tmrd_pda = 8;
+
+ u8 wr2pre = 24;
+ u8 rd2pre = 4;
+ u8 wr2rd = 14 + max(ns_to_t(tpr13_flag1 ? 10 : 12), 4);
+ u8 rd2wr = 17 + ns_to_t(4) - ns_to_t(1);
+ u8 tphy_wrlat = 5;
+
+ u8 rdlat = 10;
+ u8 trddata_en = 17;
+
+ if (tpr13_flag1) {
+ rdlat = 11;
+ trddata_en = 19;
+ }
+
+ writel(tras_min | tras_max << 8 | tfaw << 16 | wr2pre << 24,
+ &mctl_ctl->dramtmg[0]);
+ writel(trc | rd2pre << 8 | txp << 16, &mctl_ctl->dramtmg[1]);
+ writel(wr2rd | rd2wr << 8 | rdlat << 16 | wrlat << 24,
+ &mctl_ctl->dramtmg[2]);
+ writel(tmod | tmrd << 12 | tmrw << 20, &mctl_ctl->dramtmg[3]);
+ writel(trp | trrd << 8 | tccd << 16 | trcd << 24,
+ &mctl_ctl->dramtmg[4]);
+ writel(tcke | tckesr << 8 | tcksre << 16 | tcksrx << 24,
+ &mctl_ctl->dramtmg[5]);
+ writel((txp + 2) | 0x20 << 16 | 0x20 << 24, &mctl_ctl->dramtmg[6]);
+ writel(txs_x32 | 0x10 << 8 | txsabort_x32 << 16 | txsabort_x32 << 24,
+ &mctl_ctl->dramtmg[8]);
+ writel(wr2rd_s | trrd_s << 8 | 0x2 << 16, &mctl_ctl->dramtmg[9]);
+ writel(0xe0c05, &mctl_ctl->dramtmg[10]);
+ writel(0x440c021c, &mctl_ctl->dramtmg[11]);
+ writel(tmrd_pda, &mctl_ctl->dramtmg[12]);
+ writel(0xa100002, &mctl_ctl->dramtmg[13]);
+ writel(txsr, &mctl_ctl->dramtmg[14]);
+
+ clrsetbits_le32(&mctl_ctl->init[0], 0xc0000fff, 1008);
+
+ if (tpr13_flag2)
+ writel(0x420000, &mctl_ctl->init[1]);
+ else
+ writel(0x1f20000, &mctl_ctl->init[1]);
+
+ clrsetbits_le32(&mctl_ctl->init[2], 0xff0f, 0xd05);
+ writel(0, &mctl_ctl->dfimisc);
+
+ writel(0x34 << 16 | 0x1b, &mctl_ctl->init[3]); /* MR1/MR2 */
+ writel(0x33 << 16, &mctl_ctl->init[4]); /* MR3 */
+ writel(para->mr11 << 16 | para->mr12, &mctl_ctl->init[6]);
+ writel(para->tpr1 << 16 | para->mr14, &mctl_ctl->init[7]);
+
+ clrsetbits_le32(&mctl_ctl->rankctl, 0xff0, 0x660);
+ if (!tpr13_flag3) {
+ tphy_wrlat -= 1;
+ trddata_en -= 1;
+ }
+
+ writel(tphy_wrlat | trddata_en << 16 | 0x808000 | 0x2000000,
+ &mctl_ctl->dfitmg0);
+ writel(0x100202, &mctl_ctl->dfitmg1);
+
+ writel(trfc_min | trefi_x32 << 16, &mctl_ctl->rfshtmg);
+}
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index b288c65e7fd..8ade6f7b9d1 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -155,10 +155,6 @@ config TARGET_M5282EVB
bool "Support M5282EVB"
select M5282
-config TARGET_ASTRO_MCF5373L
- bool "Support astro_mcf5373l"
- select M5373
-
config TARGET_M53017EVB
bool "Support M53017EVB"
select M53015
@@ -183,7 +179,6 @@ config TARGET_STMARK2
endchoice
source "board/BuS/eb_cpu5282/Kconfig"
-source "board/astro/mcf5373l/Kconfig"
source "board/cobra5272/Kconfig"
source "board/freescale/m5208evbe/Kconfig"
source "board/freescale/m5235evb/Kconfig"
diff --git a/arch/m68k/dts/Makefile b/arch/m68k/dts/Makefile
index 0f06109aa06..c89559be309 100644
--- a/arch/m68k/dts/Makefile
+++ b/arch/m68k/dts/Makefile
@@ -11,7 +11,6 @@ dtb-$(CONFIG_TARGET_M5253DEMO) += M5253DEMO.dtb
dtb-$(CONFIG_TARGET_M5272C3) += M5272C3.dtb
dtb-$(CONFIG_TARGET_M5275EVB) += M5275EVB.dtb
dtb-$(CONFIG_TARGET_M5282EVB) += M5282EVB.dtb
-dtb-$(CONFIG_TARGET_ASTRO_MCF5373L) += astro_mcf5373l.dtb
dtb-$(CONFIG_TARGET_M53017EVB) += M53017EVB.dtb
dtb-$(CONFIG_TARGET_M5329EVB) += M5329AFEE.dtb M5329BFEE.dtb
dtb-$(CONFIG_TARGET_M5373EVB) += M5373EVB.dtb
diff --git a/arch/m68k/dts/astro_mcf5373l.dts b/arch/m68k/dts/astro_mcf5373l.dts
deleted file mode 100644
index 40f84dd64b6..00000000000
--- a/arch/m68k/dts/astro_mcf5373l.dts
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
- */
-
-/dts-v1/;
-/include/ "mcf537x.dtsi"
-
-/ {
- model = "Astro mcf5373l";
- compatible = "astro,mcf5373l";
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-};
-
-&uart0 {
- bootph-all;
- status = "okay";
-};
-
-&i2c0 {
- clock-frequency = <80000>;
- u-boot,i2c-slave-addr = <0x7f>;
- status = "okay";
-};
diff --git a/arch/powerpc/cpu/mpc85xx/mp.c b/arch/powerpc/cpu/mpc85xx/mp.c
index 8918a401fac..bee6758dc9a 100644
--- a/arch/powerpc/cpu/mpc85xx/mp.c
+++ b/arch/powerpc/cpu/mpc85xx/mp.c
@@ -410,9 +410,9 @@ static void plat_mp_up(unsigned long bootpg, unsigned int pagesize)
void cpu_mp_lmb_reserve(void)
{
- u32 bootpg = determine_mp_bootpg(NULL);
+ phys_addr_t bootpg = determine_mp_bootpg(NULL);
- lmb_reserve(bootpg, 4096, LMB_NONE);
+ lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &bootpg, 4096, LMB_NONE);
}
void setup_mp(void)
diff --git a/arch/powerpc/lib/misc.c b/arch/powerpc/lib/misc.c
index 7e303419624..fc10ae50cf8 100644
--- a/arch/powerpc/lib/misc.c
+++ b/arch/powerpc/lib/misc.c
@@ -36,11 +36,12 @@ int arch_misc_init(void)
size = min(size, (ulong)CFG_SYS_LINUX_LOWMEM_MAX_SIZE);
if (size < bootm_size) {
- ulong base = bootmap_base + size;
+ phys_addr_t base = bootmap_base + size;
printf("WARNING: adjusting available memory from 0x%lx to 0x%llx\n",
size, (unsigned long long)bootm_size);
- lmb_reserve(base, bootm_size - size, LMB_NONE);
+ lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &base,
+ bootm_size - size, LMB_NONE);
}
#ifdef CONFIG_MP
diff --git a/arch/riscv/config.mk b/arch/riscv/config.mk
index 9f16dda92a0..eddd6a3b9a2 100644
--- a/arch/riscv/config.mk
+++ b/arch/riscv/config.mk
@@ -10,19 +10,29 @@
# Rick Chen, Andes Technology Corporation <rick@andestech.com>
#
-32bit-emul := elf32lriscv
-64bit-emul := elf64lriscv
+ifdef CONFIG_SYS_BIG_ENDIAN
+small-endian := b
+large-endian := big
+PLATFORM_CPPFLAGS += -mbig-endian
+KBUILD_LDFLAGS += -mbig-endian
+else
+small-endian := l
+large-endian := little
+endif
+
+32bit-emul := elf32$(small-endian)riscv
+64bit-emul := elf64$(small-endian)riscv
ifdef CONFIG_32BIT
KBUILD_LDFLAGS += -m $(32bit-emul)
EFI_LDS := elf_riscv32_efi.lds
-PLATFORM_ELFFLAGS += -B riscv -O elf32-littleriscv
+PLATFORM_ELFFLAGS += -B riscv -O elf32-$(large-endian)riscv
endif
ifdef CONFIG_64BIT
KBUILD_LDFLAGS += -m $(64bit-emul)
EFI_LDS := elf_riscv64_efi.lds
-PLATFORM_ELFFLAGS += -B riscv -O elf64-littleriscv
+PLATFORM_ELFFLAGS += -B riscv -O elf64-$(large-endian)riscv
endif
PLATFORM_CPPFLAGS += -ffixed-x3 -fpic
diff --git a/arch/riscv/cpu/th1520/Kconfig b/arch/riscv/cpu/th1520/Kconfig
index 4d44191bd22..c73462c04b8 100644
--- a/arch/riscv/cpu/th1520/Kconfig
+++ b/arch/riscv/cpu/th1520/Kconfig
@@ -11,6 +11,7 @@ config THEAD_TH1520
select BINMAN if SPL
select SYS_CACHE_THEAD_CMO
select CLK_THEAD
+ select PINCTRL_TH1520
imply CPU
imply CPU_RISCV
imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE)
diff --git a/arch/riscv/cpu/th1520/cpu.c b/arch/riscv/cpu/th1520/cpu.c
index b83f1272c67..f60446fd772 100644
--- a/arch/riscv/cpu/th1520/cpu.c
+++ b/arch/riscv/cpu/th1520/cpu.c
@@ -9,8 +9,35 @@
#include <asm/io.h>
#include <cpu_func.h>
+#include <linux/bitops.h>
-#define TH1520_PMP_BASE (void *)0xffdc020000
+#define TH1520_C910_RST (void __iomem *)(0xffef014000 + 0x004)
+#define TH1520_C910_CORE_RST_N(n) BIT((n) + 1)
+#define TH1520_SYSCFG_AP_BASE (void __iomem *)(0xffef018000)
+#define TH1520_SYSCFG_CORE_START_L(n) (TH1520_SYSCFG_AP_BASE + 0x50 + 8 * (n))
+#define TH1520_SYSCFG_CORE_START_H(n) (TH1520_SYSCFG_AP_BASE + 0x54 + 8 * (n))
+#define TH1520_PMP_BASE (void *)0xffdc020000
+
+void th1520_kick_secondary_cores(void)
+{
+ int i;
+
+ /*
+ * On coldboot, only HART 0 is brought up by hardware, and resets for
+ * secondary cores are asserted. Set reset address of secondary cores
+ * to the entry of SPL, then deassert the resets to bring them up.
+ */
+ for (i = 1; i < 4; i++) {
+ writel(CONFIG_SPL_TEXT_BASE & 0xffffffff,
+ TH1520_SYSCFG_CORE_START_L(i));
+ writel(CONFIG_SPL_TEXT_BASE >> 32,
+ TH1520_SYSCFG_CORE_START_H(i));
+ }
+
+ setbits_le32(TH1520_C910_RST, TH1520_C910_CORE_RST_N(1) |
+ TH1520_C910_CORE_RST_N(2) |
+ TH1520_C910_CORE_RST_N(3));
+}
void th1520_invalidate_pmp(void)
{
diff --git a/arch/riscv/cpu/th1520/spl.c b/arch/riscv/cpu/th1520/spl.c
index 362fe895f86..b95470485f6 100644
--- a/arch/riscv/cpu/th1520/spl.c
+++ b/arch/riscv/cpu/th1520/spl.c
@@ -4,6 +4,7 @@
*/
#include <asm/arch/iopmp.h>
#include <asm/io.h>
+#include <cpu_func.h>
#include <dm.h>
#include <linux/sizes.h>
#include <log.h>
@@ -21,6 +22,52 @@ DECLARE_GLOBAL_DATA_PTR;
#define TH1520_SUBSYS_RST_VI_N BIT(1)
#define TH1520_SUBSYS_RST_DSP_N BIT(0)
+#define CSR_MXSTATUS 0x7c0
+#define CSR_MXSTATUS_THEADISAEE BIT(22)
+#define CSR_MXSTATUS_MAEE BIT(21)
+#define CSR_MXSTATUS_CLINTEE BIT(17)
+#define CSR_MXSTATUS_UCME BIT(16)
+#define CSR_MXSTATUS_MM BIT(15)
+#define CSR_MHCR 0x7c1
+#define CSR_MHCR_WBR BIT(8)
+#define CSR_MHCR_BTB BIT(6)
+#define CSR_MHCR_BPE BIT(5)
+#define CSR_MHCR_RS BIT(4)
+#define CSR_MHCR_WB BIT(3)
+#define CSR_MHCR_WA BIT(2)
+#define CSR_MHCR_DE BIT(1)
+#define CSR_MHCR_IE BIT(0)
+#define CSR_MCOR 0x7c2
+#define CSR_MCOR_IBP_INV BIT(18)
+#define CSR_MCOR_BTB_INV BIT(17)
+#define CSR_MCOR_BHT_INV BIT(16)
+#define CSR_MCOR_CACHE_INV BIT(4)
+#define CSR_MCCR2 0x7c3
+#define CSR_MCCR2_TPRF BIT(31)
+#define CSR_MCCR2_IPRF(n) ((n) << 29)
+#define CSR_MCCR2_TSETUP BIT(25)
+#define CSR_MCCR2_TLNTCY(n) ((n) << 22)
+#define CSR_MCCR2_DSETUP BIT(19)
+#define CSR_MCCR2_DLNTCY(n) ((n) << 16)
+#define CSR_MCCR2_L2EN BIT(3)
+#define CSR_MCCR2_RFE BIT(0)
+#define CSR_MHINT 0x7c5
+#define CSR_MHINT_FENCERW_BROAD_DIS BIT(22)
+#define CSR_MHINT_TLB_BRAOD_DIS BIT(21)
+#define CSR_MHINT_NSFE BIT(18)
+#define CSR_MHINT_L2_PREF_DIST(n) ((n) << 16)
+#define CSR_MHINT_L2PLD BIT(15)
+#define CSR_MHINT_DCACHE_PREF_DIST(n) ((n) << 13)
+#define CSR_MHINT_LPE BIT(9)
+#define CSR_MHINT_ICACHE_PREF BIT(8)
+#define CSR_MHINT_AMR BIT(3)
+#define CSR_MHINT_DCACHE_PREF BIT(2)
+#define CSR_MHINT2 0x7cc
+#define CSR_MHINT2_LOCAL_ICG_EN(n) BIT((n) + 14)
+#define CSR_MHINT4 0x7ce
+#define CSR_MSMPR 0x7f3
+#define CSR_MSMPR_SMPEN BIT(0)
+
int spl_dram_init(void)
{
int ret;
@@ -77,6 +124,42 @@ void harts_early_init(void)
{
int i;
+ /* Invalidate cache and buffer entries */
+ csr_write(CSR_MCOR, CSR_MCOR_IBP_INV | CSR_MCOR_BTB_INV |
+ CSR_MCOR_BHT_INV | CSR_MCOR_CACHE_INV | 0x3);
+
+ /* Enable cache snooping */
+ csr_write(CSR_MSMPR, CSR_MSMPR_SMPEN);
+
+ /*
+ * Configure and enable L2 cache,
+ * Enable tag/data RAM prefetch, both cost 2 cycles
+ * Prefetch 3 cache lines of instructions
+ * Enable read allocation
+ */
+ csr_write(CSR_MCCR2, CSR_MCCR2_TPRF | CSR_MCCR2_IPRF(3) |
+ CSR_MCCR2_TSETUP | CSR_MCCR2_TLNTCY(1) |
+ CSR_MCCR2_DSETUP | CSR_MCCR2_DLNTCY(1) |
+ CSR_MCCR2_L2EN | CSR_MCCR2_RFE);
+ csr_write(CSR_MXSTATUS, CSR_MXSTATUS_THEADISAEE | CSR_MXSTATUS_MAEE |
+ CSR_MXSTATUS_CLINTEE | CSR_MXSTATUS_UCME |
+ CSR_MXSTATUS_MM);
+ csr_write(CSR_MHINT, CSR_MHINT_FENCERW_BROAD_DIS |
+ CSR_MHINT_TLB_BRAOD_DIS |
+ CSR_MHINT_NSFE |
+ CSR_MHINT_L2_PREF_DIST(2) |
+ CSR_MHINT_L2PLD |
+ CSR_MHINT_DCACHE_PREF_DIST(3) |
+ CSR_MHINT_LPE |
+ CSR_MHINT_ICACHE_PREF |
+ CSR_MHINT_AMR |
+ CSR_MHINT_DCACHE_PREF);
+ csr_write(CSR_MHCR, CSR_MHCR_WBR | CSR_MHCR_BTB | CSR_MHCR_BPE |
+ CSR_MHCR_RS | CSR_MHCR_WB | CSR_MHCR_WA | 0x3);
+ csr_write(CSR_MHINT2, CSR_MHINT2_LOCAL_ICG_EN(8) |
+ CSR_MHINT2_LOCAL_ICG_EN(3));
+ csr_write(CSR_MHINT4, 0x410);
+
/*
* Set IOPMPs to the default attribute, allowing the application
* processor to access various peripherals. Subsystem clocks should be
diff --git a/arch/riscv/dts/th1520.dtsi b/arch/riscv/dts/th1520.dtsi
index 28107a9f354..8306eda5521 100644
--- a/arch/riscv/dts/th1520.dtsi
+++ b/arch/riscv/dts/th1520.dtsi
@@ -128,6 +128,13 @@
#clock-cells = <0>;
};
+ aonsys_clk: clock-73728000 {
+ compatible = "fixed-clock";
+ clock-frequency = <73728000>;
+ clock-output-names = "aonsys_clk";
+ #clock-cells = <0>;
+ };
+
soc {
compatible = "simple-bus";
interrupt-parent = <&plic>;
@@ -151,6 +158,7 @@
clint: timer@ffdc000000 {
compatible = "thead,th1520-clint", "thead,c900-clint";
reg = <0xff 0xdc000000 0x0 0x00010000>;
+ bootph-pre-ram;
interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>,
<&cpu1_intc 3>, <&cpu1_intc 7>,
<&cpu2_intc 3>, <&cpu2_intc 7>,
@@ -258,6 +266,13 @@
};
};
+ padctrl1_apsys: pinctrl@ffe7f3c000 {
+ compatible = "thead,th1520-pinctrl";
+ reg = <0xff 0xe7f3c000 0x0 0x1000>;
+ clocks = <&clk CLK_PADCTRL1>;
+ thead,pad-group = <2>;
+ };
+
gpio0: gpio@ffec005000 {
compatible = "snps,dw-apb-gpio";
reg = <0xff 0xec005000 0x0 0x1000>;
@@ -298,6 +313,13 @@
};
};
+ padctrl0_apsys: pinctrl@ffec007000 {
+ compatible = "thead,th1520-pinctrl";
+ reg = <0xff 0xec007000 0x0 0x1000>;
+ clocks = <&clk CLK_PADCTRL0>;
+ thead,pad-group = <3>;
+ };
+
uart2: serial@ffec010000 {
compatible = "snps,dw-apb-uart";
reg = <0xff 0xec010000 0x0 0x4000>;
@@ -438,6 +460,13 @@
};
};
+ padctrl_aosys: pinctrl@fffff4a000 {
+ compatible = "thead,th1520-pinctrl";
+ reg = <0xff 0xfff4a000 0x0 0x2000>;
+ clocks = <&aonsys_clk>;
+ thead,pad-group = <1>;
+ };
+
ao_gpio1: gpio@fffff52000 {
compatible = "snps,dw-apb-gpio";
reg = <0xff 0xfff52000 0x0 0x1000>;
diff --git a/arch/riscv/include/asm/arch-th1520/cpu.h b/arch/riscv/include/asm/arch-th1520/cpu.h
index 837f0b8d06b..e164e9ab979 100644
--- a/arch/riscv/include/asm/arch-th1520/cpu.h
+++ b/arch/riscv/include/asm/arch-th1520/cpu.h
@@ -5,5 +5,6 @@
#ifndef _ASM_TH1520_CPU_H_
#define _ASM_TH1520_CPU_H_
+void th1520_kick_secondary_cores(void);
void th1520_invalidate_pmp(void);
#endif /* _ASM_TH1520_CPU_H_ */
diff --git a/arch/riscv/include/asm/byteorder.h b/arch/riscv/include/asm/byteorder.h
index d26ac5688fa..3140c1f585e 100644
--- a/arch/riscv/include/asm/byteorder.h
+++ b/arch/riscv/include/asm/byteorder.h
@@ -26,7 +26,7 @@
# define __SWAB_64_THRU_32__
#endif
-#ifdef __RISCVEB__
+#if defined(__RISCVEB__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
#include <linux/byteorder/big_endian.h>
#else
#include <linux/byteorder/little_endian.h>
diff --git a/arch/riscv/lib/aclint_ipi.c b/arch/riscv/lib/aclint_ipi.c
index dcd7e5e6b34..1c9a2d70301 100644
--- a/arch/riscv/lib/aclint_ipi.c
+++ b/arch/riscv/lib/aclint_ipi.c
@@ -29,6 +29,10 @@ int riscv_init_ipi(void)
ret = uclass_get_device_by_driver(UCLASS_TIMER,
DM_DRIVER_GET(riscv_aclint_timer), &dev);
+ if (ret == -ENODEV)
+ ret = uclass_get_device_by_driver(UCLASS_SYSCON,
+ DM_DRIVER_GET(riscv_aclint_swi), &dev);
+
if (ret)
return ret;
@@ -66,6 +70,7 @@ int riscv_get_ipi(int hart, int *pending)
static const struct udevice_id riscv_aclint_swi_ids[] = {
{ .compatible = "riscv,aclint-mswi", .data = RISCV_SYSCON_ACLINT },
+ { .compatible = "thead,c900-clint", .data = RISCV_SYSCON_ACLINT },
{ }
};
diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c
index 49236db99c2..6a15c8b0a18 100644
--- a/arch/sandbox/cpu/state.c
+++ b/arch/sandbox/cpu/state.c
@@ -480,7 +480,9 @@ int state_init(void)
state = &main_state;
state->ram_size = CFG_SYS_SDRAM_SIZE;
- state->ram_buf = os_malloc(state->ram_size);
+ state->mmap_addr = os_malloc(state->ram_size + SB_SDRAM_ALIGN);
+ state->ram_buf = (uint8_t *)ALIGN((uintptr_t)state->mmap_addr,
+ SB_SDRAM_ALIGN);
if (!state->ram_buf) {
printf("Out of memory\n");
os_exit(1);
@@ -533,7 +535,7 @@ int state_uninit(void)
trace_set_enabled(0);
os_free(state->state_fdt);
- os_free(state->ram_buf);
+ os_free(state->mmap_addr);
memset(state, '\0', sizeof(*state));
return 0;
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index dc21a623106..9dea0980bfc 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -75,6 +75,7 @@ struct sandbox_state {
char **argv; /* Command line arguments */
const char *jumped_fname; /* Jumped from previous U-Boot */
const char *prog_fname; /* U-Boot executable filename */
+ uint8_t *mmap_addr; /* Memory allocated via mmap */
uint8_t *ram_buf; /* Emulated RAM buffer */
unsigned long ram_size; /* Size of RAM buffer */
const char *ram_buf_fname; /* Filename to use for RAM buffer */
diff --git a/board/amd/versal2/board.c b/board/amd/versal2/board.c
index 72967e69a84..7d91d288d2e 100644
--- a/board/amd/versal2/board.c
+++ b/board/amd/versal2/board.c
@@ -365,9 +365,11 @@ int dram_init(void)
return 0;
}
+#if !CONFIG_IS_ENABLED(SYSRESET)
void reset_cpu(void)
{
}
+#endif
#if defined(CONFIG_ENV_IS_NOWHERE)
enum env_location env_get_location(enum env_operation op, int prio)
diff --git a/board/astro/mcf5373l/Kconfig b/board/astro/mcf5373l/Kconfig
deleted file mode 100644
index a7c04cef83d..00000000000
--- a/board/astro/mcf5373l/Kconfig
+++ /dev/null
@@ -1,15 +0,0 @@
-if TARGET_ASTRO_MCF5373L
-
-config SYS_CPU
- default "mcf532x"
-
-config SYS_BOARD
- default "mcf5373l"
-
-config SYS_VENDOR
- default "astro"
-
-config SYS_CONFIG_NAME
- default "astro_mcf5373l"
-
-endif
diff --git a/board/astro/mcf5373l/MAINTAINERS b/board/astro/mcf5373l/MAINTAINERS
deleted file mode 100644
index 6c23da71968..00000000000
--- a/board/astro/mcf5373l/MAINTAINERS
+++ /dev/null
@@ -1,6 +0,0 @@
-MCF5373L BOARD
-M: Wolfgang Wegner <w.wegner@astro-kom.de>
-S: Maintained
-F: board/astro/mcf5373l/
-F: include/configs/astro_mcf5373l.h
-F: configs/astro_mcf5373l_defconfig
diff --git a/board/astro/mcf5373l/Makefile b/board/astro/mcf5373l/Makefile
deleted file mode 100644
index d3ea0d06a8d..00000000000
--- a/board/astro/mcf5373l/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-#
-# (C) Copyright 2000-2006
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-
-obj-y = mcf5373l.o fpga.o
diff --git a/board/astro/mcf5373l/astro.h b/board/astro/mcf5373l/astro.h
deleted file mode 100644
index b55a6f785ce..00000000000
--- a/board/astro/mcf5373l/astro.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef __ASTRO_H__
-#define __ASTRO_H__
-
-/* in mcf5373l.c */
-int rs_serial_init(int port, int baud);
-void astro_put_char(char ch);
-int astro_is_char(void);
-int astro_get_char(void);
-
-/* in fpga.c */
-int astro5373l_altera_load(void);
-int astro5373l_xilinx_load(void);
-
-/* data structures used for communication (update.c) */
-typedef struct card_id {
- char card_type;
- char hardware_version;
- char software_version;
- char software_subversion; /* " ","a".."z" */
- char fpga_version_altera;
- char fpga_version_xilinx;
-} card_id_t;
-
-typedef struct {
- unsigned char mode;
- unsigned char deviation;
- unsigned short freq;
-} __attribute__ ((packed)) output_params_t;
-
-typedef struct {
- unsigned short satfreq;
- unsigned char satdatallg;
- unsigned short symbolrate;
- unsigned char viterbirate;
- unsigned char symbolrate_l;
- output_params_t output_params;
- unsigned char reserve;
- unsigned char card_error;
- unsigned short dummy_ts_id;
- unsigned char dummy_pat_ver;
- unsigned char dummy_sdt_ver;
-} __attribute__ ((packed)) parameters_t;
-
-#endif /* __ASTRO_H__ */
diff --git a/board/astro/mcf5373l/fpga.c b/board/astro/mcf5373l/fpga.c
deleted file mode 100644
index 6e505c630d1..00000000000
--- a/board/astro/mcf5373l/fpga.c
+++ /dev/null
@@ -1,407 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2006
- * Wolfgang Wegner, ASTRO Strobel Kommunikationssysteme GmbH,
- * w.wegner@astro-kom.de
- *
- * based on the files by
- * Heiko Schocher, DENX Software Engineering, hs@denx.de
- * and
- * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
- * Keith Outwater, keith_outwater@mvis.com.
- */
-
-/* Altera/Xilinx FPGA configuration support for the ASTRO "URMEL" board */
-
-#include <console.h>
-#include <watchdog.h>
-#include <altera.h>
-#include <ACEX1K.h>
-#include <spartan3.h>
-#include <command.h>
-#include <asm/immap_5329.h>
-#include <asm/io.h>
-#include "fpga.h"
-
-int altera_pre_fn(int cookie)
-{
- gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
- unsigned char tmp_char;
- unsigned short tmp_short;
-
- /* first, set the required pins to GPIO function */
- /* PAR_T0IN -> GPIO */
- tmp_char = readb(&gpiop->par_timer);
- tmp_char &= 0xfc;
- writeb(tmp_char, &gpiop->par_timer);
- /* all QSPI pins -> GPIO */
- writew(0x0000, &gpiop->par_qspi);
- /* U0RTS, U0CTS -> GPIO */
- tmp_short = __raw_readw(&gpiop->par_uart);
- tmp_short &= 0xfff3;
- __raw_writew(tmp_short, &gpiop->par_uart);
- /* all PWM pins -> GPIO */
- writeb(0x00, &gpiop->par_pwm);
- /* next, set data direction registers */
- writeb(0x01, &gpiop->pddr_timer);
- writeb(0x25, &gpiop->pddr_qspi);
- writeb(0x0c, &gpiop->pddr_uart);
- writeb(0x04, &gpiop->pddr_pwm);
-
- /* ensure other SPI peripherals are deselected */
- writeb(0x08, &gpiop->ppd_uart);
- writeb(0x38, &gpiop->ppd_qspi);
-
- /* CONFIG = 0 STATUS = 0 -> FPGA in reset state */
- writeb(0xFB, &gpiop->pclrr_uart);
- /* enable Altera configuration by clearing QSPI_CS2 and DT0IN */
- writeb(0xFE, &gpiop->pclrr_timer);
- writeb(0xDF, &gpiop->pclrr_qspi);
- return FPGA_SUCCESS;
-}
-
-/* Set the state of CONFIG Pin */
-int altera_config_fn(int assert_config, int flush, int cookie)
-{
- gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
-
- if (assert_config)
- writeb(0x04, &gpiop->ppd_uart);
- else
- writeb(0xFB, &gpiop->pclrr_uart);
- return FPGA_SUCCESS;
-}
-
-/* Returns the state of STATUS Pin */
-int altera_status_fn(int cookie)
-{
- gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
-
- if (readb(&gpiop->ppd_pwm) & 0x08)
- return FPGA_FAIL;
- return FPGA_SUCCESS;
-}
-
-/* Returns the state of CONF_DONE Pin */
-int altera_done_fn(int cookie)
-{
- gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
-
- if (readb(&gpiop->ppd_pwm) & 0x20)
- return FPGA_FAIL;
- return FPGA_SUCCESS;
-}
-
-/*
- * writes the complete buffer to the FPGA
- * writing the complete buffer in one function is much faster,
- * then calling it for every bit
- */
-int altera_write_fn(const void *buf, size_t len, int flush, int cookie)
-{
- size_t bytecount = 0;
- gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
- unsigned char *data = (unsigned char *)buf;
- unsigned char val = 0;
- int i;
- int len_40 = len / 40;
-
- while (bytecount < len) {
- val = data[bytecount++];
- i = 8;
- do {
- writeb(0xFB, &gpiop->pclrr_qspi);
- if (val & 0x01)
- writeb(0x01, &gpiop->ppd_qspi);
- else
- writeb(0xFE, &gpiop->pclrr_qspi);
- writeb(0x04, &gpiop->ppd_qspi);
- val >>= 1;
- i--;
- } while (i > 0);
-
- if (bytecount % len_40 == 0) {
-#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
- schedule();
-#endif
-#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
- putc('.'); /* let them know we are alive */
-#endif
-#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
- if (ctrlc())
- return FPGA_FAIL;
-#endif
- }
- }
- return FPGA_SUCCESS;
-}
-
-/* called, when programming is aborted */
-int altera_abort_fn(int cookie)
-{
- gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
-
- writeb(0x20, &gpiop->ppd_qspi);
- writeb(0x08, &gpiop->ppd_uart);
- return FPGA_SUCCESS;
-}
-
-/* called, when programming was succesful */
-int altera_post_fn(int cookie)
-{
- return altera_abort_fn(cookie);
-}
-
-/*
- * Note that these are pointers to code that is in Flash. They will be
- * relocated at runtime.
- * FIXME: relocation not yet working for coldfire, see below!
- */
-Altera_CYC2_Passive_Serial_fns altera_fns = {
- altera_pre_fn,
- altera_config_fn,
- altera_status_fn,
- altera_done_fn,
- altera_write_fn,
- altera_abort_fn,
- altera_post_fn
-};
-
-#define FPGA_COUNT 1
-Altera_desc altera_fpga[FPGA_COUNT] = {
- {Altera_CYC2,
- passive_serial,
- 85903,
- (void *)&altera_fns,
- NULL,
- 0}
-};
-
-/* Initialize the fpga. Return 1 on success, 0 on failure. */
-int astro5373l_altera_load(void)
-{
- int i;
-
- for (i = 0; i < FPGA_COUNT; i++) {
- /*
- * I did not yet manage to get relocation work properly,
- * so set stuff here instead of static initialisation:
- */
- altera_fns.pre = altera_pre_fn;
- altera_fns.config = altera_config_fn;
- altera_fns.status = altera_status_fn;
- altera_fns.done = altera_done_fn;
- altera_fns.write = altera_write_fn;
- altera_fns.abort = altera_abort_fn;
- altera_fns.post = altera_post_fn;
- altera_fpga[i].iface_fns = (void *)&altera_fns;
- fpga_add(fpga_altera, &altera_fpga[i]);
- }
- return 1;
-}
-
-/* Set the FPGA's PROG_B line to the specified level */
-int xilinx_pgm_config_fn(int assert, int flush, int cookie)
-{
- gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
-
- if (assert)
- writeb(0xFB, &gpiop->pclrr_uart);
- else
- writeb(0x04, &gpiop->ppd_uart);
- return assert;
-}
-
-/*
- * Test the state of the active-low FPGA INIT line. Return 1 on INIT
- * asserted (low).
- */
-int xilinx_init_config_fn(int cookie)
-{
- gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
-
- return (readb(&gpiop->ppd_pwm) & 0x08) == 0;
-}
-
-/* Test the state of the active-high FPGA DONE pin */
-int xilinx_done_config_fn(int cookie)
-{
- gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
-
- return (readb(&gpiop->ppd_pwm) & 0x20) >> 5;
-}
-
-/* Abort an FPGA operation */
-int xilinx_abort_config_fn(int cookie)
-{
- gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
- /* ensure all SPI peripherals and FPGAs are deselected */
- writeb(0x08, &gpiop->ppd_uart);
- writeb(0x01, &gpiop->ppd_timer);
- writeb(0x38, &gpiop->ppd_qspi);
- return FPGA_FAIL;
-}
-
-/*
- * FPGA pre-configuration function. Just make sure that
- * FPGA reset is asserted to keep the FPGA from starting up after
- * configuration.
- */
-int xilinx_pre_config_fn(int cookie)
-{
- gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
- unsigned char tmp_char;
- unsigned short tmp_short;
-
- /* first, set the required pins to GPIO function */
- /* PAR_T0IN -> GPIO */
- tmp_char = readb(&gpiop->par_timer);
- tmp_char &= 0xfc;
- writeb(tmp_char, &gpiop->par_timer);
- /* all QSPI pins -> GPIO */
- writew(0x0000, &gpiop->par_qspi);
- /* U0RTS, U0CTS -> GPIO */
- tmp_short = __raw_readw(&gpiop->par_uart);
- tmp_short &= 0xfff3;
- __raw_writew(tmp_short, &gpiop->par_uart);
- /* all PWM pins -> GPIO */
- writeb(0x00, &gpiop->par_pwm);
- /* next, set data direction registers */
- writeb(0x01, &gpiop->pddr_timer);
- writeb(0x25, &gpiop->pddr_qspi);
- writeb(0x0c, &gpiop->pddr_uart);
- writeb(0x04, &gpiop->pddr_pwm);
-
- /* ensure other SPI peripherals are deselected */
- writeb(0x08, &gpiop->ppd_uart);
- writeb(0x38, &gpiop->ppd_qspi);
- writeb(0x01, &gpiop->ppd_timer);
-
- /* CONFIG = 0, STATUS = 0 -> FPGA in reset state */
- writeb(0xFB, &gpiop->pclrr_uart);
- /* enable Xilinx configuration by clearing QSPI_CS2 and U0CTS */
- writeb(0xF7, &gpiop->pclrr_uart);
- writeb(0xDF, &gpiop->pclrr_qspi);
- return 0;
-}
-
-/*
- * FPGA post configuration function. Should perform a test if FPGA is running.
- */
-int xilinx_post_config_fn(int cookie)
-{
- int rc = 0;
-
- /*
- * no test yet
- */
- return rc;
-}
-
-int xilinx_clk_config_fn(int assert_clk, int flush, int cookie)
-{
- gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
-
- if (assert_clk)
- writeb(0x04, &gpiop->ppd_qspi);
- else
- writeb(0xFB, &gpiop->pclrr_qspi);
- return assert_clk;
-}
-
-int xilinx_wr_config_fn(int assert_write, int flush, int cookie)
-{
- gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
-
- if (assert_write)
- writeb(0x01, &gpiop->ppd_qspi);
- else
- writeb(0xFE, &gpiop->pclrr_qspi);
- return assert_write;
-}
-
-int xilinx_fastwr_config_fn(void *buf, size_t len, int flush, int cookie)
-{
- size_t bytecount = 0;
- gpio_t *gpiop = (gpio_t *)MMAP_GPIO;
- unsigned char *data = (unsigned char *)buf;
- unsigned char val = 0;
- int i;
- int len_40 = len / 40;
-
- for (bytecount = 0; bytecount < len; bytecount++) {
- val = *(data++);
- for (i = 8; i > 0; i--) {
- writeb(0xFB, &gpiop->pclrr_qspi);
- if (val & 0x80)
- writeb(0x01, &gpiop->ppd_qspi);
- else
- writeb(0xFE, &gpiop->pclrr_qspi);
- writeb(0x04, &gpiop->ppd_qspi);
- val <<= 1;
- }
- if (bytecount % len_40 == 0) {
-#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
- schedule();
-#endif
-#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
- putc('.'); /* let them know we are alive */
-#endif
-#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
- if (ctrlc())
- return FPGA_FAIL;
-#endif
- }
- }
- return FPGA_SUCCESS;
-}
-
-/*
- * Note that these are pointers to code that is in Flash. They will be
- * relocated at runtime.
- * FIXME: relocation not yet working for coldfire, see below!
- */
-xilinx_spartan3_slave_serial_fns xilinx_fns = {
- xilinx_pre_config_fn,
- xilinx_pgm_config_fn,
- xilinx_clk_config_fn,
- xilinx_init_config_fn,
- xilinx_done_config_fn,
- xilinx_wr_config_fn,
- 0,
- xilinx_fastwr_config_fn
-};
-
-xilinx_desc xilinx_fpga[FPGA_COUNT] = {
- {xilinx_spartan3,
- slave_serial,
- XILINX_XC3S4000_SIZE,
- (void *)&xilinx_fns,
- 0,
- &spartan3_op}
-};
-
-/* Initialize the fpga. Return 1 on success, 0 on failure. */
-int astro5373l_xilinx_load(void)
-{
- int i;
-
- fpga_init();
-
- for (i = 0; i < FPGA_COUNT; i++) {
- /*
- * I did not yet manage to get relocation work properly,
- * so set stuff here instead of static initialisation:
- */
- xilinx_fns.pre = xilinx_pre_config_fn;
- xilinx_fns.pgm = xilinx_pgm_config_fn;
- xilinx_fns.clk = xilinx_clk_config_fn;
- xilinx_fns.init = xilinx_init_config_fn;
- xilinx_fns.done = xilinx_done_config_fn;
- xilinx_fns.wr = xilinx_wr_config_fn;
- xilinx_fns.bwr = xilinx_fastwr_config_fn;
- xilinx_fpga[i].iface_fns = (void *)&xilinx_fns;
- fpga_add(fpga_xilinx, &xilinx_fpga[i]);
- }
- return 1;
-}
diff --git a/board/astro/mcf5373l/mcf5373l.c b/board/astro/mcf5373l/mcf5373l.c
deleted file mode 100644
index 43fcbc65513..00000000000
--- a/board/astro/mcf5373l/mcf5373l.c
+++ /dev/null
@@ -1,201 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2000-2003
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- * modified by Wolfgang Wegner <w.wegner@astro-kom.de> for ASTRO 5373l
- */
-
-#include <config.h>
-#include <init.h>
-#include <serial.h>
-#include <time.h>
-#include <watchdog.h>
-#include <command.h>
-#include <asm/global_data.h>
-#include <asm/m5329.h>
-#include <asm/immap_5329.h>
-#include <asm/io.h>
-#include <linux/delay.h>
-
-/* needed for astro bus: */
-#include <asm/uart.h>
-#include "astro.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-extern void uart_port_conf(void);
-
-int checkboard(void)
-{
- puts("Board: ");
- puts("ASTRO MCF5373L (Urmel) Board\n");
- return 0;
-}
-
-int dram_init(void)
-{
-#if !defined(CONFIG_MONITOR_IS_IN_RAM)
- sdram_t *sdp = (sdram_t *)(MMAP_SDRAM);
-
- /*
- * GPIO configuration for bus should be set correctly from reset,
- * so we do not care! First, set up address space: at this point,
- * we should be running from internal SRAM;
- * so use CFG_SYS_SDRAM_BASE as the base address for SDRAM,
- * and do not care where it is
- */
- __raw_writel((CFG_SYS_SDRAM_BASE & 0xFFF00000) | 0x00000018,
- &sdp->cs0);
- __raw_writel((CFG_SYS_SDRAM_BASE & 0xFFF00000) | 0x00000000,
- &sdp->cs1);
- /*
- * I am not sure from the data sheet, but it seems burst length
- * has to be 8 for the 16 bit data bus we use;
- * so these values are for BL = 8
- */
- __raw_writel(0x33211530, &sdp->cfg1);
- __raw_writel(0x56570000, &sdp->cfg2);
- /* send PrechargeALL, REF and IREF remain cleared! */
- __raw_writel(0xE1462C02, &sdp->ctrl);
- udelay(1);
- /* refresh SDRAM twice */
- __raw_writel(0xE1462C04, &sdp->ctrl);
- udelay(1);
- __raw_writel(0xE1462C04, &sdp->ctrl);
- /* init MR */
- __raw_writel(0x008D0000, &sdp->mode);
- /* initialize EMR */
- __raw_writel(0x80010000, &sdp->mode);
- /* wait until DLL is locked */
- udelay(1);
- /*
- * enable automatic refresh, lock mode register,
- * clear iref and ipall
- */
- __raw_writel(0x71462C00, &sdp->ctrl);
- /* Dummy write to start SDRAM */
- writel(0, CFG_SYS_SDRAM_BASE);
-#endif
-
- /*
- * for get_ram_size() to work, both CS areas have to be
- * configured, i.e. CS1 has to be explicitely disabled, else
- * probing for memory will cause the SDRAM bus to hang!
- * (Do not rely on the SDCS register(s) being set to 0x00000000
- * during reset as stated in the data sheet.)
- */
- gd->ram_size = get_ram_size((long *)CFG_SYS_SDRAM_BASE,
- 0x80000000 - CFG_SYS_SDRAM_BASE);
-
- return 0;
-}
-
-#define UART_BASE MMAP_UART0
-int rs_serial_init(int port, int baud)
-{
- uart_t *uart;
- u32 counter;
-
- switch (port) {
- case 0:
- uart = (uart_t *)(MMAP_UART0);
- break;
- case 1:
- uart = (uart_t *)(MMAP_UART1);
- break;
- case 2:
- uart = (uart_t *)(MMAP_UART2);
- break;
- default:
- uart = (uart_t *)(MMAP_UART0);
- }
-
- uart_port_conf();
-
- /* write to SICR: SIM2 = uart mode,dcd does not affect rx */
- writeb(UART_UCR_RESET_RX, &uart->ucr);
- writeb(UART_UCR_RESET_TX, &uart->ucr);
- writeb(UART_UCR_RESET_ERROR, &uart->ucr);
- writeb(UART_UCR_RESET_MR, &uart->ucr);
- __asm__ ("nop");
-
- writeb(0, &uart->uimr);
-
- /* write to CSR: RX/TX baud rate from timers */
- writeb(UART_UCSR_RCS_SYS_CLK | UART_UCSR_TCS_SYS_CLK, &uart->ucsr);
-
- writeb(UART_UMR_BC_8 | UART_UMR_PM_NONE, &uart->umr);
- writeb(UART_UMR_SB_STOP_BITS_1, &uart->umr);
-
- /* Setting up BaudRate */
- counter = (u32) (gd->bus_clk / (baud));
- counter >>= 5;
-
- /* write to CTUR: divide counter upper byte */
- writeb((u8) ((counter & 0xff00) >> 8), &uart->ubg1);
- /* write to CTLR: divide counter lower byte */
- writeb((u8) (counter & 0x00ff), &uart->ubg2);
-
- writeb(UART_UCR_RX_ENABLED | UART_UCR_TX_ENABLED, &uart->ucr);
-
- return 0;
-}
-
-void astro_put_char(char ch)
-{
- uart_t *uart;
- unsigned long timer;
-
- uart = (uart_t *)(MMAP_UART0);
- /*
- * Wait for last character to go. Timeout of 6ms should
- * be enough for our lowest baud rate of 2400.
- */
- timer = get_timer(0);
- while (get_timer(timer) < 6) {
- if (readb(&uart->usr) & UART_USR_TXRDY)
- break;
- }
- writeb(ch, &uart->utb);
-
- return;
-}
-
-int astro_is_char(void)
-{
- uart_t *uart;
-
- uart = (uart_t *)(MMAP_UART0);
- return readb(&uart->usr) & UART_USR_RXRDY;
-}
-
-int astro_get_char(void)
-{
- uart_t *uart;
-
- uart = (uart_t *)(MMAP_UART0);
- while (!(readb(&uart->usr) & UART_USR_RXRDY)) ;
- return readb(&uart->urb);
-}
-
-int misc_init_r(void)
-{
- int retval = 0;
-
- puts("Configure Xilinx FPGA...");
- retval = astro5373l_xilinx_load();
- if (!retval) {
- puts("failed!\n");
- return retval;
- }
- puts("done\n");
-
- puts("Configure Altera FPGA...");
- retval = astro5373l_altera_load();
- if (!retval) {
- puts("failed!\n");
- return retval;
- }
- puts("done\n");
-
- return retval;
-}
diff --git a/board/congatec/common/Makefile b/board/congatec/common/Makefile
index f8170d9c653..7f1c8994d27 100644
--- a/board/congatec/common/Makefile
+++ b/board/congatec/common/Makefile
@@ -16,8 +16,8 @@ endif
endif
ifdef MINIMAL
-# necessary to create built-in.o
-obj- := __dummy__.o
+# necessary to create built-in.a
+obj- := __dummy__.a
else
obj-y += mmc.o
diff --git a/board/cssi/cmpc885/u-boot.lds b/board/cssi/cmpc885/u-boot.lds
index 53f616fcfe1..167606357e0 100644
--- a/board/cssi/cmpc885/u-boot.lds
+++ b/board/cssi/cmpc885/u-boot.lds
@@ -18,8 +18,8 @@ SECTIONS
{
arch/powerpc/cpu/mpc8xx/start.o (.text)
arch/powerpc/cpu/mpc8xx/traps.o (.text*)
- arch/powerpc/lib/built-in.o (.text*)
- drivers/net/built-in.o (.text*)
+ arch/powerpc/lib/built-in.a (.text*)
+ drivers/net/built-in.a (.text*)
. = DEFINED(env_offset) ? env_offset : .;
env/embedded.o (.text.environment)
diff --git a/board/cssi/mcr3000/u-boot.lds b/board/cssi/mcr3000/u-boot.lds
index 24b535e724a..66afdebc0f7 100644
--- a/board/cssi/mcr3000/u-boot.lds
+++ b/board/cssi/mcr3000/u-boot.lds
@@ -18,8 +18,8 @@ SECTIONS
{
arch/powerpc/cpu/mpc8xx/start.o (.text)
arch/powerpc/cpu/mpc8xx/traps.o (.text*)
- arch/powerpc/lib/built-in.o (.text*)
- drivers/net/built-in.o (.text*)
+ arch/powerpc/lib/built-in.a (.text*)
+ drivers/net/built-in.a (.text*)
. = DEFINED(env_offset) ? env_offset : .;
env/embedded.o (.text.environment)
diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile
index b04e19e9428..ed102ae7bf7 100644
--- a/board/freescale/common/Makefile
+++ b/board/freescale/common/Makefile
@@ -14,8 +14,8 @@ endif
endif
ifdef MINIMAL
-# necessary to create built-in.o
-obj- := __dummy__.o
+# necessary to create built-in.a
+obj- := __dummy__.a
else
# include i2c_common.o once if either VID or FSL_USE_PCA9547_MUX
I2C_COMMON=
diff --git a/board/freescale/imx8mm_evk/imx8mm_evk.c b/board/freescale/imx8mm_evk/imx8mm_evk.c
index d41db8d31d8..ecc20768cb5 100644
--- a/board/freescale/imx8mm_evk/imx8mm_evk.c
+++ b/board/freescale/imx8mm_evk/imx8mm_evk.c
@@ -3,6 +3,8 @@
* Copyright 2018 NXP
*/
+#include <config.h>
+#include <efi_loader.h>
#include <env.h>
#include <init.h>
#include <miiphy.h>
@@ -15,6 +17,26 @@
DECLARE_GLOBAL_DATA_PTR;
+#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT)
+#define IMX_BOOT_IMAGE_GUID \
+ EFI_GUID(0xead2005e, 0x7780, 0x400b, 0x93, 0x48, \
+ 0xa2, 0x82, 0xeb, 0x85, 0x8b, 0x6b)
+
+struct efi_fw_image fw_images[] = {
+ {
+ .image_type_id = IMX_BOOT_IMAGE_GUID,
+ .fw_name = u"IMX8MM-EVK-RAW",
+ .image_index = 1,
+ },
+};
+
+struct efi_capsule_update_info update_info = {
+ .dfu_string = "mmc 2=flash-bin raw 0x42 0x2000 mmcpart 1",
+ .num_images = ARRAY_SIZE(fw_images),
+ .images = fw_images,
+};
+#endif /* EFI_HAVE_CAPSULE_SUPPORT */
+
#if IS_ENABLED(CONFIG_FEC_MXC)
static int setup_fec(void)
{
diff --git a/board/freescale/imx8mn_evk/imx8mn_evk.c b/board/freescale/imx8mn_evk/imx8mn_evk.c
index c62d7a47e21..9d3f29f2253 100644
--- a/board/freescale/imx8mn_evk/imx8mn_evk.c
+++ b/board/freescale/imx8mn_evk/imx8mn_evk.c
@@ -5,9 +5,31 @@
#include <asm/arch/sys_proto.h>
#include <asm/io.h>
+#include <config.h>
+#include <efi_loader.h>
#include <env.h>
#include <init.h>
+#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT)
+#define IMX_BOOT_IMAGE_GUID \
+ EFI_GUID(0xcbabf44d, 0x12cc, 0x45dd, 0xb0, 0xc5, \
+ 0x29, 0xc5, 0xb7, 0x42, 0x2d, 0x34)
+
+struct efi_fw_image fw_images[] = {
+ {
+ .image_type_id = IMX_BOOT_IMAGE_GUID,
+ .fw_name = u"IMX8MN-EVK-RAW",
+ .image_index = 1,
+ },
+};
+
+struct efi_capsule_update_info update_info = {
+ .dfu_string = "mmc 2=flash-bin raw 0 0x2000 mmcpart 1",
+ .num_images = ARRAY_SIZE(fw_images),
+ .images = fw_images,
+};
+#endif /* EFI_HAVE_CAPSULE_SUPPORT */
+
int board_mmc_get_env_dev(int devno)
{
return devno;
diff --git a/board/freescale/imx8mp_evk/imx8mp_evk.c b/board/freescale/imx8mp_evk/imx8mp_evk.c
index 2ff067bc675..2a9ba7df2bb 100644
--- a/board/freescale/imx8mp_evk/imx8mp_evk.c
+++ b/board/freescale/imx8mp_evk/imx8mp_evk.c
@@ -4,8 +4,31 @@
*/
#include <asm/arch/sys_proto.h>
+#include <config.h>
+#include <efi_loader.h>
#include <env.h>
+#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT)
+#define IMX_BOOT_IMAGE_GUID \
+ EFI_GUID(0x928b33bc, 0xe58b, 0x4247, 0x9f, 0x1d, \
+ 0x3b, 0xf1, 0xee, 0x1c, 0xda, 0xff)
+
+struct efi_fw_image fw_images[] = {
+ {
+ .image_type_id = IMX_BOOT_IMAGE_GUID,
+ .fw_name = u"IMX8MP-EVK-RAW",
+ .image_index = 1,
+ },
+};
+
+struct efi_capsule_update_info update_info = {
+ .dfu_string = "mmc 2=flash-bin raw 0 0x2000 mmcpart 1",
+ .num_images = ARRAY_SIZE(fw_images),
+ .images = fw_images,
+};
+#endif /* EFI_HAVE_CAPSULE_SUPPORT */
+
+
int board_init(void)
{
return 0;
diff --git a/board/freescale/imx8mq_evk/imx8mq_evk.c b/board/freescale/imx8mq_evk/imx8mq_evk.c
index 18e83d90a08..e90c56c33ff 100644
--- a/board/freescale/imx8mq_evk/imx8mq_evk.c
+++ b/board/freescale/imx8mq_evk/imx8mq_evk.c
@@ -7,6 +7,7 @@
#include <asm/arch/imx8mq_pins.h>
#include <asm/arch/sys_proto.h>
#include <asm/mach-imx/iomux-v3.h>
+#include <efi_loader.h>
#include <env.h>
#define UART_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_FSEL1)
@@ -22,6 +23,26 @@ static iomux_v3_cfg_t const uart_pads[] = {
IMX8MQ_PAD_UART1_TXD__UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
};
+#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT)
+#define IMX_BOOT_IMAGE_GUID \
+ EFI_GUID(0x296119cf, 0xdd70, 0x43de, 0x8a, 0xc8, \
+ 0xa7, 0x05, 0x1f, 0x31, 0x25, 0x77)
+
+struct efi_fw_image fw_images[] = {
+ {
+ .image_type_id = IMX_BOOT_IMAGE_GUID,
+ .fw_name = u"IMX8MQ-EVK-RAW",
+ .image_index = 1,
+ },
+};
+
+struct efi_capsule_update_info update_info = {
+ .dfu_string = "mmc 0=flash-bin raw 0x42 0x2000 mmcpart 1",
+ .num_images = ARRAY_SIZE(fw_images),
+ .images = fw_images,
+};
+#endif /* EFI_HAVE_CAPSULE_SUPPORT */
+
int board_early_init_f(void)
{
struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR;
diff --git a/board/freescale/imx93_evk/imx93_evk.c b/board/freescale/imx93_evk/imx93_evk.c
index c9171df330e..d84d56be5e1 100644
--- a/board/freescale/imx93_evk/imx93_evk.c
+++ b/board/freescale/imx93_evk/imx93_evk.c
@@ -4,6 +4,7 @@
*/
#include <env.h>
+#include <efi_loader.h>
#include <init.h>
#include <miiphy.h>
#include <netdev.h>
@@ -28,6 +29,26 @@ static iomux_v3_cfg_t const uart_pads[] = {
MX93_PAD_UART1_TXD__LPUART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
};
+#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT)
+#define IMX_BOOT_IMAGE_GUID \
+ EFI_GUID(0xbc550d86, 0xda26, 0x4b70, 0xac, 0x05, \
+ 0x2a, 0x44, 0x8e, 0xda, 0x6f, 0x21)
+
+struct efi_fw_image fw_images[] = {
+ {
+ .image_type_id = IMX_BOOT_IMAGE_GUID,
+ .fw_name = u"IMX93-11X11-EVK-RAW",
+ .image_index = 1,
+ },
+};
+
+struct efi_capsule_update_info update_info = {
+ .dfu_string = "mmc 0=flash-bin raw 0 0x2000 mmcpart 1",
+ .num_images = ARRAY_SIZE(fw_images),
+ .images = fw_images,
+};
+#endif /* EFI_HAVE_CAPSULE_SUPPORT */
+
int board_early_init_f(void)
{
imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads));
diff --git a/board/lg/star/star.c b/board/lg/star/star.c
index dc593754101..0b4a433a5df 100644
--- a/board/lg/star/star.c
+++ b/board/lg/star/star.c
@@ -9,6 +9,7 @@
#include <fdt_support.h>
#include <log.h>
#include <spl_gpio.h>
+#include <asm/gpio.h>
static int star_fix_panel(void *fdt)
{
diff --git a/board/menlo/mx8menlo/Makefile b/board/menlo/mx8menlo/Makefile
index 62939395ba1..c71fa9edfd9 100644
--- a/board/menlo/mx8menlo/Makefile
+++ b/board/menlo/mx8menlo/Makefile
@@ -16,8 +16,8 @@ endif
# Common for all Toradex modules
ifeq ($(CONFIG_XPL_BUILD),y)
-# Necessary to create built-in.o
-obj- := __dummy__.o
+# Necessary to create built-in.a
+obj- := __dummy__.a
else
obj-$(CONFIG_TDX_CFG_BLOCK) += ../../toradex/common/tdx-cfg-block.o
obj-y += ../../toradex/common/tdx-common.o
diff --git a/board/microchip/mpfs_icicle/mpfs_icicle.c b/board/microchip/mpfs_icicle/mpfs_icicle.c
index 4d7d843dfa3..6b6984eae3f 100644
--- a/board/microchip/mpfs_icicle/mpfs_icicle.c
+++ b/board/microchip/mpfs_icicle/mpfs_icicle.c
@@ -9,6 +9,7 @@
#include <init.h>
#include <asm/global_data.h>
#include <asm/io.h>
+#include <asm/sections.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -50,6 +51,68 @@ static void read_device_serial_number(u8 *response, u8 response_size)
response_buf[idx] = readb(MPFS_SYS_SERVICE_MAILBOX + idx);
}
+#if defined(CONFIG_MULTI_DTB_FIT)
+int board_fit_config_name_match(const char *name)
+{
+ const void *fdt;
+ int list_len;
+
+ /*
+ * If there's not a HSS provided dtb, there's no point re-selecting
+ * since we'd just end up re-selecting the same dtb again.
+ */
+ if (!gd->arch.firmware_fdt_addr)
+ return -EINVAL;
+
+ fdt = (void *)gd->arch.firmware_fdt_addr;
+
+ list_len = fdt_stringlist_count(fdt, 0, "compatible");
+ if (list_len < 1)
+ return -EINVAL;
+
+ for (int i = 0; i < list_len; i++) {
+ int len, match;
+ const char *compat;
+ char *devendored;
+
+ compat = fdt_stringlist_get(fdt, 0, "compatible", i, &len);
+ if (!compat)
+ return -EINVAL;
+
+ strtok((char *)compat, ",");
+
+ devendored = strtok(NULL, ",");
+ if (!devendored)
+ return -EINVAL;
+
+ match = strcmp(devendored, name);
+ if (!match)
+ return 0;
+ }
+
+ return -EINVAL;
+}
+#endif
+
+int board_fdt_blob_setup(void **fdtp)
+{
+ fdtp = (void *)_end;
+
+ /*
+ * The devicetree provided by the previous stage is very minimal due to
+ * severe space constraints. The firmware performs no fixups etc.
+ * U-Boot, if providing a devicetree, almost certainly has a better
+ * more complete one than the firmware so that provided by the firmware
+ * is ignored for OF_SEPARATE.
+ */
+ if (IS_ENABLED(CONFIG_OF_BOARD) && !IS_ENABLED(CONFIG_MULTI_DTB_FIT)) {
+ if (gd->arch.firmware_fdt_addr)
+ fdtp = (void *)(uintptr_t)gd->arch.firmware_fdt_addr;
+ }
+
+ return 0;
+}
+
int board_init(void)
{
/* For now nothing to do here. */
diff --git a/board/phytec/common/Makefile b/board/phytec/common/Makefile
index 8126f7356e1..948f9dab626 100644
--- a/board/phytec/common/Makefile
+++ b/board/phytec/common/Makefile
@@ -3,8 +3,8 @@
# Author: Teresa Remmet <t.remmet@phytec.de>
ifdef CONFIG_XPL_BUILD
-# necessary to create built-in.o
-obj- := __dummy__.o
+# necessary to create built-in.a
+obj- := __dummy__.a
endif
obj-y += phytec_som_detection.o phytec_som_detection_blocks.o
diff --git a/board/phytec/phycore_am62x/rm-cfg.yaml b/board/phytec/phycore_am62x/rm-cfg.yaml
index e4221f82f92..26d99b03b80 100644
--- a/board/phytec/phycore_am62x/rm-cfg.yaml
+++ b/board/phytec/phycore_am62x/rm-cfg.yaml
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0+
-# Copyright (C) 2022-2023 Texas Instruments Incorporated - https://www.ti.com/
+# Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
#
-# Resource management configuration for AM62
+# Resource management configuration for AM62X
#
---
@@ -244,7 +244,7 @@ rm-cfg:
subhdr:
magic: 0x7B25
size: 8
- resasg_entries_size: 960
+ resasg_entries_size: 976
reserved: 0
resasg_entries:
-
@@ -285,11 +285,23 @@ rm-cfg:
reserved: 0
-
start_resource: 0
- num_resource: 4
+ num_resource: 2
type: 320
host_id: 12
reserved: 0
-
+ start_resource: 2
+ num_resource: 2
+ type: 320
+ host_id: 35
+ reserved: 0
+ -
+ start_resource: 2
+ num_resource: 2
+ type: 320
+ host_id: 36
+ reserved: 0
+ -
start_resource: 4
num_resource: 4
type: 320
@@ -501,13 +513,13 @@ rm-cfg:
reserved: 0
-
start_resource: 44
- num_resource: 36
+ num_resource: 35
type: 1802
host_id: 35
reserved: 0
-
start_resource: 44
- num_resource: 36
+ num_resource: 35
type: 1802
host_id: 36
reserved: 0
@@ -543,7 +555,7 @@ rm-cfg:
reserved: 0
-
start_resource: 909
- num_resource: 627
+ num_resource: 626
type: 1805
host_id: 128
reserved: 0
diff --git a/board/qualcomm/MAINTAINERS b/board/qualcomm/MAINTAINERS
new file mode 100644
index 00000000000..3767a2a7949
--- /dev/null
+++ b/board/qualcomm/MAINTAINERS
@@ -0,0 +1,24 @@
+# This MAINTAINERS file is for folks with an interest in a particular platform
+# or board under ARM SNAPDRAGON
+
+QUALCOMM DRAGONWING QCS615
+M: Aswin Murugan <aswin.murugan@oss.qualcomm.com>
+S: Maintained
+N: qcs615
+
+# RB3 Gen 2 and similar boards
+QUALCOMM DRAGONWING QCS6490
+M: Casey Connolly <casey.connolly@linaro.org>
+S: Maintained
+N: qcs6490
+N: sc7280
+
+QUALCOMM DRAGONWING QCS8300
+M: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
+S: Maintained
+N: qcs8300
+
+QUALCOMM DRAGONWING QCS9100
+M: Varadarajan Narayanan <quic_varada@quicinc.com>
+S: Maintained
+N: qcs9100
diff --git a/board/raidsonic/ib62x0/MAINTAINERS b/board/raidsonic/ib62x0/MAINTAINERS
index 423aa0cf253..2822eb0d29d 100644
--- a/board/raidsonic/ib62x0/MAINTAINERS
+++ b/board/raidsonic/ib62x0/MAINTAINERS
@@ -1,5 +1,5 @@
IB62X0 BOARD
-M: Luka Perkov <luka@openwrt.org>
+M: Tony Dinh <mibodhi@gmail.com>
S: Maintained
F: board/raidsonic/ib62x0/
F: include/configs/ib62x0.h
diff --git a/board/samsung/coreprimevelte/MAINTAINERS b/board/samsung/coreprimevelte/MAINTAINERS
index 0902117e8b3..9dccd041ffb 100644
--- a/board/samsung/coreprimevelte/MAINTAINERS
+++ b/board/samsung/coreprimevelte/MAINTAINERS
@@ -1,5 +1,5 @@
Samsung Galaxy Core Prime VE LTE support
-M: Duje Mihanović <duje.mihanovic@skole.hr>
+M: Duje Mihanović <duje@dujemihanovic.xyz>
S: Maintained
T: git git://git.dujemihanovic.xyz/u-boot.git
F: board/samsung/coreprimevelte/
diff --git a/board/samsung/e850-96/e850-96.c b/board/samsung/e850-96/e850-96.c
index 0bef68d2fb2..3bbd95201b5 100644
--- a/board/samsung/e850-96/e850-96.c
+++ b/board/samsung/e850-96/e850-96.c
@@ -19,8 +19,17 @@ int dram_init_banksize(void)
int board_init(void)
{
+ return 0;
+}
+
+int board_late_init(void)
+{
int err;
+ /*
+ * Do this in board_late_init() to make sure MMC is not probed before
+ * efi_init_early().
+ */
err = load_ldfw();
if (err)
printf("ERROR: LDFW loading failed (%d)\n", err);
diff --git a/board/samsung/origen/Makefile b/board/samsung/origen/Makefile
index 940f689a601..30c637e322a 100644
--- a/board/samsung/origen/Makefile
+++ b/board/samsung/origen/Makefile
@@ -3,8 +3,8 @@
# Copyright (C) 2011 Samsung Electronics
ifdef CONFIG_XPL_BUILD
-# necessary to create built-in.o
-obj- := __dummy__.o
+# necessary to create built-in.a
+obj- := __dummy__.a
hostprogs-y := tools/mkorigenspl
always := $(hostprogs-y)
diff --git a/board/samsung/smdkv310/Makefile b/board/samsung/smdkv310/Makefile
index b7f9d5a254c..360300a7851 100644
--- a/board/samsung/smdkv310/Makefile
+++ b/board/samsung/smdkv310/Makefile
@@ -3,8 +3,8 @@
# Copyright (C) 2011 Samsung Electronics
ifdef CONFIG_XPL_BUILD
-# necessary to create built-in.o
-obj- := __dummy__.o
+# necessary to create built-in.a
+obj- := __dummy__.a
hostprogs-y := tools/mksmdkv310spl
always := $(hostprogs-y)
diff --git a/board/sandbox/sandbox.c b/board/sandbox/sandbox.c
index d97945e58fc..43f4edc39e9 100644
--- a/board/sandbox/sandbox.c
+++ b/board/sandbox/sandbox.c
@@ -101,7 +101,6 @@ enum env_location env_get_location(enum env_operation op, int prio)
int dram_init(void)
{
- gd->ram_size = CFG_SYS_SDRAM_SIZE;
return 0;
}
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index 84799879e85..1b4b7d87163 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -296,6 +296,11 @@ M: Adam Sampson <ats@offog.org>
S: Maintained
F: configs/Linksprite_pcDuino3_Nano_defconfig
+LIONTRON H-A133L BOARD
+M: Andre Przywara <andre.przywara@arm.com>
+S: Maintained
+F: configs/liontron-h-a133l_defconfig
+
MARSBOARD-A10 BOARD
M: Aleksei Mamlin <mamlinav@gmail.com>
S: Maintained
@@ -596,6 +601,11 @@ M: Peter Korsgaard <peter@korsgaard.com>
S: Maintained
F: configs/Yones_Toptech_BS1078_V2_defconfig
+YUZUKIHD CHAMELEON BOARD
+M: Andre Przywara <andre.przywara@arm.com>
+S: Maintained
+F: configs/yuzukihd-chameleon_defconfig
+
ZEROPI BOARD
M: Yu-Tung Chang <mtwget@gmail.com>
S: Maintained
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index feec95658a2..943b6221b8a 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -114,7 +114,7 @@ void i2c_init_board(void)
clock_twi_onoff(5, 1);
sunxi_gpio_set_cfgpin(SUNXI_GPL(8), SUN50I_GPL_R_TWI);
sunxi_gpio_set_cfgpin(SUNXI_GPL(9), SUN50I_GPL_R_TWI);
-#elif CONFIG_MACH_SUN50I_H616
+#elif defined(CONFIG_MACH_SUN50I_H616)
clock_twi_onoff(5, 1);
sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN50I_H616_GPL_R_TWI);
sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN50I_H616_GPL_R_TWI);
@@ -435,7 +435,7 @@ static void mmc_pinmux_setup(int sdc)
sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
sunxi_gpio_set_drv(pin, 2);
}
-#elif defined(CONFIG_MACH_SUN50I_H616)
+#elif defined(CONFIG_MACH_SUN50I_H616) || defined(CONFIG_MACH_SUN50I_A133)
/* SDC2: PC0-PC1, PC5-PC6, PC8-PC11, PC13-PC16 */
for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(16); pin++) {
if (pin > SUNXI_GPC(1) && pin < SUNXI_GPC(5))
diff --git a/board/thead/th1520_lpi4a/spl.c b/board/thead/th1520_lpi4a/spl.c
index 25dfa387c36..d75fa6f3eff 100644
--- a/board/thead/th1520_lpi4a/spl.c
+++ b/board/thead/th1520_lpi4a/spl.c
@@ -39,6 +39,9 @@ void board_init_f(ulong dummy)
if (ret)
panic("failed to bind CPU: %d\n", ret);
+ riscv_cpu_setup();
+ th1520_kick_secondary_cores();
+
spl_dram_init();
icache_enable();
diff --git a/board/toradex/common/Makefile b/board/toradex/common/Makefile
index 7e3905445a5..24496a7c997 100644
--- a/board/toradex/common/Makefile
+++ b/board/toradex/common/Makefile
@@ -3,8 +3,8 @@
# Common for all Toradex modules
ifeq ($(CONFIG_XPL_BUILD),y)
-# Necessary to create built-in.o
-obj- := __dummy__.o
+# Necessary to create built-in.a
+obj- := __dummy__.a
else
obj-$(CONFIG_TDX_CFG_BLOCK) += tdx-cfg-block.o
obj-y += tdx-common.o
diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c
index 8ffe7429901..ceb58da6d3c 100644
--- a/board/xilinx/common/board.c
+++ b/board/xilinx/common/board.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2014 - 2022, Xilinx, Inc.
- * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc.
+ * (C) Copyright 2022 - 2025, Advanced Micro Devices, Inc.
*
* Michal Simek <michal.simek@amd.com>
*/
@@ -712,3 +712,34 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
}
#endif
+
+#if IS_ENABLED(CONFIG_BOARD_RNG_SEED)
+/* Use hardware rng to seed Linux random. */
+__weak int board_rng_seed(struct abuf *buf)
+{
+ struct udevice *dev;
+ ulong len = 64;
+ u64 *data;
+
+ if (uclass_get_device(UCLASS_RNG, 0, &dev) || !dev) {
+ printf("No RNG device\n");
+ return -ENODEV;
+ }
+
+ data = malloc(len);
+ if (!data) {
+ printf("Out of memory\n");
+ return -ENOMEM;
+ }
+
+ if (dm_rng_read(dev, data, len)) {
+ printf("Reading RNG failed\n");
+ free(data);
+ return -EIO;
+ }
+
+ abuf_init_set(buf, data, len);
+
+ return 0;
+}
+#endif
diff --git a/boot/Kconfig b/boot/Kconfig
index b0548358e8b..2ff6f003738 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -11,6 +11,17 @@ config ANDROID_BOOT_IMAGE
This enables support for booting images which use the Android
image format header.
+config ANDROID_BOOT_IMAGE_IGNORE_BLOB_ADDR
+ bool "Android Boot Image ignore addr"
+ default n
+ help
+ This ignore kernel/ramdisk load addr specified in androidboot header.
+
+ There is a concern on exposing the whole memory to image loading is
+ dangerous. Also, since it's not always possible to change the load
+ addr by repacking the boot.img (mainly due to AVB signature mismatch),
+ we need a way to use kernel_addr_r and ramdisk_addr_r.
+
config TIMESTAMP
bool "Show image date and time when displaying image information"
default y if CMD_DATE
diff --git a/boot/bootm.c b/boot/bootm.c
index 108ca7fb472..4bdca22ea8c 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -623,12 +623,16 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress)
*/
if (os.type == IH_TYPE_KERNEL_NOLOAD && os.comp != IH_COMP_NONE) {
ulong req_size = ALIGN(image_len * 4, SZ_1M);
+ phys_addr_t addr;
- load = lmb_alloc(req_size, SZ_2M);
- if (!load)
+ err = lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, &addr,
+ req_size, LMB_NONE);
+ if (err)
return 1;
- os.load = load;
- images->ep = load;
+
+ load = (ulong)addr;
+ os.load = (ulong)addr;
+ images->ep = (ulong)addr;
debug("Allocated %lx bytes at %lx for kernel (size %lx) decompression\n",
req_size, load, image_len);
}
@@ -698,9 +702,18 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress)
images->os.end = relocated_addr + image_size;
}
- if (CONFIG_IS_ENABLED(LMB))
- lmb_reserve(images->os.load, (load_end - images->os.load),
- LMB_NONE);
+ if (CONFIG_IS_ENABLED(LMB)) {
+ phys_addr_t load;
+
+ load = (phys_addr_t)images->os.load;
+ err = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &load,
+ (load_end - images->os.load), LMB_NONE);
+ if (err) {
+ log_err("Unable to allocate memory %#lx for loading OS\n",
+ images->os.load);
+ return 1;
+ }
+ }
return 0;
}
diff --git a/boot/bootm_os.c b/boot/bootm_os.c
index a3c7cb5332e..88f7c183867 100644
--- a/boot/bootm_os.c
+++ b/boot/bootm_os.c
@@ -402,6 +402,17 @@ static int do_bootm_elf(int flag, struct bootm_info *bmi)
if (flag != BOOTM_STATE_OS_GO)
return 0;
+ /*
+ * Required per RISC-V boot protocol:
+ * a0(argc) = hartid of the current core
+ * a1(argv) = address of the devicetree in memory
+ * https://www.kernel.org/doc/html/latest/arch/riscv/boot.html#register-state
+ */
+#if defined(CONFIG_RISCV)
+ bmi->argc = gd->arch.boot_hart;
+ bmi->argv = (char **)bmi->images->ft_addr;
+#endif
+
bootelf(bmi->images->ep, flags, bmi->argc, bmi->argv);
return 1;
diff --git a/boot/image-android.c b/boot/image-android.c
index 459cdb8456c..1cd2060bb3f 100644
--- a/boot/image-android.c
+++ b/boot/image-android.c
@@ -268,7 +268,8 @@ static ulong android_image_get_kernel_addr(struct andr_image_data *img_data,
*
* Otherwise, we will return the actual value set by the user.
*/
- if (img_data->kernel_addr == ANDROID_IMAGE_DEFAULT_KERNEL_ADDR) {
+ if (img_data->kernel_addr == ANDROID_IMAGE_DEFAULT_KERNEL_ADDR ||
+ IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE_IGNORE_BLOB_ADDR)) {
if (comp == IH_COMP_NONE)
return img_data->kernel_ptr;
return env_get_ulong("kernel_addr_r", 16, 0);
@@ -464,7 +465,8 @@ int android_image_get_ramdisk(const void *hdr, const void *vendor_boot_img,
*/
if (img_data.header_version > 2) {
/* Ramdisk can't be used in-place, copy it to ramdisk_addr_r */
- if (img_data.ramdisk_addr == ANDROID_IMAGE_DEFAULT_RAMDISK_ADDR) {
+ if (img_data.ramdisk_addr == ANDROID_IMAGE_DEFAULT_RAMDISK_ADDR ||
+ IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE_IGNORE_BLOB_ADDR)) {
ramdisk_ptr = env_get_ulong("ramdisk_addr_r", 16, 0);
if (!ramdisk_ptr) {
printf("Invalid ramdisk_addr_r to copy ramdisk into\n");
@@ -489,7 +491,8 @@ int android_image_get_ramdisk(const void *hdr, const void *vendor_boot_img,
/* Ramdisk can be used in-place, use current ptr */
if (img_data.ramdisk_addr == 0 ||
img_data.ramdisk_addr == ANDROID_IMAGE_DEFAULT_RAMDISK_ADDR ||
- img_data.ramdisk_addr == img_data.kernel_addr) {
+ img_data.ramdisk_addr == img_data.kernel_addr ||
+ IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE_IGNORE_BLOB_ADDR)) {
*rd_data = img_data.ramdisk_ptr;
} else {
ramdisk_ptr = img_data.ramdisk_addr;
@@ -677,7 +680,7 @@ bool android_image_get_dtb_by_index(ulong hdr_addr, ulong vendor_boot_img,
{
struct andr_image_data img_data;
const struct andr_boot_img_hdr_v0 *hdr;
- const struct andr_vnd_boot_img_hdr *vhdr;
+ const struct andr_vnd_boot_img_hdr *vhdr = NULL;
hdr = map_sysmem(hdr_addr, sizeof(*hdr));
if (vendor_boot_img != -1)
diff --git a/boot/image-board.c b/boot/image-board.c
index 514f8e63f9c..005d60caf5c 100644
--- a/boot/image-board.c
+++ b/boot/image-board.c
@@ -16,6 +16,7 @@
#include <fpga.h>
#include <image.h>
#include <init.h>
+#include <lmb.h>
#include <log.h>
#include <mapmem.h>
#include <rtc.h>
@@ -538,6 +539,7 @@ int boot_get_ramdisk(char const *select, struct bootm_headers *images,
int boot_ramdisk_high(ulong rd_data, ulong rd_len, ulong *initrd_start,
ulong *initrd_end)
{
+ int err;
char *s;
phys_addr_t initrd_high;
int initrd_copy_to_ram = 1;
@@ -559,25 +561,30 @@ int boot_ramdisk_high(ulong rd_data, ulong rd_len, ulong *initrd_start,
if (rd_data) {
if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */
+ phys_addr_t initrd_addr;
+
debug(" in-place initrd\n");
*initrd_start = rd_data;
*initrd_end = rd_data + rd_len;
- lmb_reserve(rd_data, rd_len, LMB_NONE);
+ initrd_addr = (phys_addr_t)rd_data;
+ err = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &initrd_addr,
+ rd_len, LMB_NONE);
+ if (err) {
+ puts("in-place initrd alloc failed\n");
+ goto error;
+ }
} else {
- if (initrd_high)
- *initrd_start =
- (ulong)lmb_alloc_base(rd_len,
- 0x1000,
- initrd_high,
- LMB_NONE);
- else
- *initrd_start = (ulong)lmb_alloc(rd_len,
- 0x1000);
+ enum lmb_mem_type type = initrd_high ?
+ LMB_MEM_ALLOC_MAX : LMB_MEM_ALLOC_ANY;
- if (*initrd_start == 0) {
+ err = lmb_alloc_mem(type, 0x1000, &initrd_high, rd_len,
+ LMB_NONE);
+ if (err) {
puts("ramdisk - allocation error\n");
goto error;
}
+
+ *initrd_start = (ulong)initrd_high;
bootstage_mark(BOOTSTAGE_ID_COPY_RAMDISK);
*initrd_end = *initrd_start + rd_len;
@@ -828,9 +835,10 @@ int boot_get_loadable(struct bootm_headers *images)
*/
int boot_get_cmdline(ulong *cmd_start, ulong *cmd_end)
{
- int barg;
+ int barg, err;
char *cmdline;
char *s;
+ phys_addr_t addr;
/*
* Help the compiler detect that this function is only called when
@@ -840,12 +848,14 @@ int boot_get_cmdline(ulong *cmd_start, ulong *cmd_end)
return 0;
barg = IF_ENABLED_INT(CONFIG_SYS_BOOT_GET_CMDLINE, CONFIG_SYS_BARGSIZE);
- cmdline = (char *)(ulong)lmb_alloc_base(barg, 0xf,
- env_get_bootm_mapsize() + env_get_bootm_low(),
- LMB_NONE);
- if (!cmdline)
+ addr = env_get_bootm_mapsize() + env_get_bootm_low();
+
+ err = lmb_alloc_mem(LMB_MEM_ALLOC_MAX, 0xf, &addr, barg, LMB_NONE);
+ if (err)
return -1;
+ cmdline = (char *)(uintptr_t)addr;
+
s = env_get("bootargs");
if (!s)
s = "";
@@ -874,14 +884,16 @@ int boot_get_cmdline(ulong *cmd_start, ulong *cmd_end)
*/
int boot_get_kbd(struct bd_info **kbd)
{
- *kbd = (struct bd_info *)(ulong)lmb_alloc_base(sizeof(struct bd_info),
- 0xf,
- env_get_bootm_mapsize() +
- env_get_bootm_low(),
- LMB_NONE);
- if (!*kbd)
+ int err;
+ phys_addr_t addr;
+
+ addr = env_get_bootm_mapsize() + env_get_bootm_low();
+ err = lmb_alloc_mem(LMB_MEM_ALLOC_MAX, 0xf, &addr,
+ sizeof(struct bd_info), LMB_NONE);
+ if (err)
return -1;
+ *kbd = (struct bd_info *)(uintptr_t)addr;
**kbd = *gd->bd;
debug("## kernel board info at 0x%08lx\n", (ulong)*kbd);
diff --git a/boot/image-fdt.c b/boot/image-fdt.c
index 1c5d9426b86..3f0ac54f76f 100644
--- a/boot/image-fdt.c
+++ b/boot/image-fdt.c
@@ -72,13 +72,15 @@ static const struct legacy_img_hdr *image_get_fdt(ulong fdt_addr)
static void boot_fdt_reserve_region(u64 addr, u64 size, u32 flags)
{
long ret;
+ phys_addr_t rsv_addr;
- ret = lmb_reserve(addr, size, flags);
+ rsv_addr = (phys_addr_t)addr;
+ ret = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &rsv_addr, size, flags);
if (!ret) {
debug(" reserving fdt memory region: addr=%llx size=%llx flags=%x\n",
(unsigned long long)addr,
(unsigned long long)size, flags);
- } else if (ret != -EEXIST) {
+ } else if (ret != -EEXIST && ret != -EINVAL) {
puts("ERROR: reserving fdt memory region failed ");
printf("(addr=%llx size=%llx flags=%x)\n",
(unsigned long long)addr,
@@ -155,7 +157,7 @@ void boot_fdt_add_mem_rsv_regions(void *fdt_blob)
*/
int boot_relocate_fdt(char **of_flat_tree, ulong *of_size)
{
- u64 start, size, usable, addr, low, mapsize;
+ u64 start, size, usable, low, mapsize;
void *fdt_blob = *of_flat_tree;
void *of_start = NULL;
char *fdt_high;
@@ -163,6 +165,7 @@ int boot_relocate_fdt(char **of_flat_tree, ulong *of_size)
int bank;
int err;
int disable_relocation = 0;
+ phys_addr_t addr;
/* nothing to do */
if (*of_size == 0)
@@ -180,23 +183,32 @@ int boot_relocate_fdt(char **of_flat_tree, ulong *of_size)
/* If fdt_high is set use it to select the relocation address */
fdt_high = env_get("fdt_high");
if (fdt_high) {
- ulong desired_addr = hextoul(fdt_high, NULL);
+ ulong high_addr = hextoul(fdt_high, NULL);
- if (desired_addr == ~0UL) {
+ if (high_addr == ~0UL) {
/* All ones means use fdt in place */
of_start = fdt_blob;
- lmb_reserve(map_to_sysmem(of_start), of_len, LMB_NONE);
- disable_relocation = 1;
- } else if (desired_addr) {
- addr = lmb_alloc_base(of_len, 0x1000, desired_addr,
- LMB_NONE);
- of_start = map_sysmem(addr, of_len);
- if (of_start == NULL) {
- puts("Failed using fdt_high value for Device Tree");
+ addr = map_to_sysmem(fdt_blob);
+ err = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &addr,
+ of_len, LMB_NONE);
+ if (err) {
+ printf("Failed to reserve memory for fdt at %#llx\n",
+ (u64)addr);
goto error;
}
+
+ disable_relocation = 1;
} else {
- addr = lmb_alloc(of_len, 0x1000);
+ enum lmb_mem_type type = high_addr ?
+ LMB_MEM_ALLOC_MAX : LMB_MEM_ALLOC_ANY;
+
+ addr = high_addr;
+ err = lmb_alloc_mem(type, 0x1000, &addr, of_len,
+ LMB_NONE);
+ if (err) {
+ puts("Failed to allocate memory for Device Tree relocation\n");
+ goto error;
+ }
of_start = map_sysmem(addr, of_len);
}
} else {
@@ -218,11 +230,15 @@ int boot_relocate_fdt(char **of_flat_tree, ulong *of_size)
* for LMB allocation.
*/
usable = min(start + size, low + mapsize);
- addr = lmb_alloc_base(of_len, 0x1000, usable, LMB_NONE);
- of_start = map_sysmem(addr, of_len);
- /* Allocation succeeded, use this block. */
- if (of_start != NULL)
- break;
+ addr = usable;
+ err = lmb_alloc_mem(LMB_MEM_ALLOC_MAX, 0x1000,
+ &addr, of_len, LMB_NONE);
+ if (!err) {
+ of_start = map_sysmem(addr, of_len);
+ /* Allocation succeeded, use this block. */
+ if (of_start)
+ break;
+ }
/*
* Reduce the mapping size in the next bank
@@ -675,7 +691,7 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob, bool lmb)
/* Delete the old LMB reservation */
if (CONFIG_IS_ENABLED(LMB) && lmb)
- lmb_free(map_to_sysmem(blob), fdt_totalsize(blob));
+ lmb_free(map_to_sysmem(blob), fdt_totalsize(blob), LMB_NONE);
ret = fdt_shrink_to_minimum(blob, 0);
if (ret < 0)
@@ -683,8 +699,17 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob, bool lmb)
of_size = ret;
/* Create a new LMB reservation */
- if (CONFIG_IS_ENABLED(LMB) && lmb)
- lmb_reserve(map_to_sysmem(blob), of_size, LMB_NONE);
+ if (CONFIG_IS_ENABLED(LMB) && lmb) {
+ phys_addr_t fdt_addr;
+
+ fdt_addr = map_to_sysmem(blob);
+ ret = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &fdt_addr,
+ of_size, LMB_NONE);
+ if (ret) {
+ printf("Failed to reserve memory for the fdt at %#llx\n",
+ (u64)fdt_addr);
+ }
+ }
if (IS_ENABLED(CONFIG_OF_BOARD_SETUP_EXTENDED) && !skip_board_fixup)
ft_board_setup_ex(blob, gd->bd);
diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c
index 82f217aaf86..eb4d7723481 100644
--- a/boot/pxe_utils.c
+++ b/boot/pxe_utils.c
@@ -1348,7 +1348,7 @@ static int parse_pxefile_top(struct pxe_context *ctx, char *p, unsigned long bas
case T_ONTIMEOUT:
err = parse_sliteral(&p, &label_name);
- if (label_name) {
+ if (err >= 0 && label_name) {
if (cfg->default_label)
free(cfg->default_label);
@@ -1360,7 +1360,7 @@ static int parse_pxefile_top(struct pxe_context *ctx, char *p, unsigned long bas
case T_FALLBACK:
err = parse_sliteral(&p, &label_name);
- if (label_name) {
+ if (err >= 0 && label_name) {
if (cfg->fallback_label)
free(cfg->fallback_label);
diff --git a/boot/scene_menu.c b/boot/scene_menu.c
index 8db6a2b2f4d..23404172093 100644
--- a/boot/scene_menu.c
+++ b/boot/scene_menu.c
@@ -571,14 +571,15 @@ int scene_menu_display(struct scene_obj_menu *menu)
return log_msg_ret("txt", -EINVAL);
str = expo_get_str(exp, txt->gen.str_id);
- printf("%s\n\n", str);
+ printf("%s\n\n", str ? str : "");
}
if (list_empty(&menu->item_head))
return 0;
pointer = scene_obj_find(scn, menu->pointer_id, SCENEOBJT_TEXT);
- pstr = expo_get_str(scn->expo, pointer->gen.str_id);
+ if (pointer)
+ pstr = expo_get_str(scn->expo, pointer->gen.str_id);
list_for_each_entry(item, &menu->item_head, sibling) {
struct scene_obj_txt *key = NULL, *label = NULL;
diff --git a/cmd/Kconfig b/cmd/Kconfig
index ed741d43cea..1e86773a143 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -153,6 +153,7 @@ config CMD_CONFIG
bool "config"
default SANDBOX
select BUILD_BIN2C
+ select GZIP
help
Print ".config" contents.
@@ -189,6 +190,12 @@ config CMD_FWU_METADATA
help
Command to read the metadata and dump it's contents
+config CMD_HELP
+ bool "help"
+ default y
+ help
+ Command to show help information about other commands.
+
config CMD_HISTORY
bool "history"
depends on CMDLINE_EDITING
@@ -1864,12 +1871,6 @@ config CMD_DHCP6
if CMD_DHCP6
-config DHCP6_PXE_CLIENTARCH
- hex
- default 0x16 if ARM64
- default 0x15 if ARM
- default 0xFF
-
config DHCP6_PXE_DHCP_OPTION
bool "Request & store 'pxe_configfile' from DHCP6 server"
@@ -1977,12 +1978,22 @@ config BOOTP_PXE
help
Supported for ARM, ARM64, and x86 for now.
-config BOOTP_PXE_CLIENTARCH
- hex
- depends on BOOTP_PXE
- default 0x16 if ARM64
- default 0x15 if ARM
- default 0x0 if X86
+config DHCP_PXE_CLIENTARCH
+ hex "DCHCP client system architecture type"
+ depends on BOOTP_PXE || CMD_DHCP6
+ default 0x16 if ARM64 # arm 64 uboot
+ default 0x15 if ARM # arm 32 uboot
+ default 0x0 if X86 # x86 BIOS
+ default 0xFF # DHCP option not sent
+ help
+ DHCP option 93 (defined in RFC4578) or DHCPv6 option 61 (defined in
+ RFC 5970) is used to transmit the client system architecture type
+ to the DHCP server. The DHCP server may use this information to
+ choose the boot file. For a complete list of assigned values see
+ https://www.iana.org/assignments/dhcpv6-parameters#processor-architecture.
+
+ If the value is set to the reserved value 0xFF, the DHCP option will
+ not be sent by U-Boot.
config BOOTP_PXE_DHCP_OPTION
bool "Request & store 'pxe_configfile' from BOOTP/DHCP server"
@@ -2004,23 +2015,6 @@ config BOOTP_RANDOM_XID
Selecting this will allow for a random transaction ID to get
selected for each BOOTP/DHCPv4 exchange.
-if CMD_DHCP6
-
-config DHCP6_PXE_CLIENTARCH
- hex
- default 0x16 if ARM64
- default 0x15 if ARM
- default 0xFF
-
-config DHCP6_PXE_DHCP_OPTION
- bool "Request & store 'pxe_configfile' from DHCP6 server"
-
-config DHCP6_ENTERPRISE_ID
- int "Enterprise ID to send in DHCPv6 Vendor Class Option"
- default 0
-
-endif
-
config CMD_TFTPPUT
bool "tftp put"
depends on CMD_TFTPBOOT
@@ -2086,12 +2080,6 @@ config CMD_CDP
and to retrieve configuration data including the VLAN id using the
proprietary Cisco Discovery Protocol (CDP).
-config CMD_SNTP
- bool "sntp"
- select PROT_UDP
- help
- Synchronize RTC via network
-
config CMD_LINK_LOCAL
bool "linklocal"
depends on (LIB_RAND || LIB_HW_RAND)
@@ -2169,6 +2157,13 @@ config CMD_PING
help
Send ICMP ECHO_REQUEST to network host
+config CMD_SNTP
+ bool "sntp"
+ select PROT_UDP if NET
+ select PROT_UDP_LWIP if NET_LWIP
+ help
+ Synchronize RTC via network
+
config CMD_TFTPBOOT
bool "tftp"
select PROT_UDP_LWIP if NET_LWIP
diff --git a/cmd/Makefile b/cmd/Makefile
index 80cf70b7fe8..40f6ac4a85e 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -7,7 +7,7 @@ ifndef CONFIG_XPL_BUILD
# core command
obj-y += boot.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o
-obj-y += help.o
+obj-$(CONFIG_CMD_HELP) += help.o
obj-y += panic.o
obj-y += version.o
@@ -133,7 +133,8 @@ obj-$(CONFIG_CMD_NAND) += nand.o
ifdef CONFIG_NET
obj-$(CONFIG_CMD_NET) += net.o net-common.o
else ifdef CONFIG_NET_LWIP
-obj-$(CONFIG_CMD_NET) += net-lwip.o net-common.o
+obj-$(CONFIG_CMD_NET) += net-common.o
+obj-y += lwip/
endif
obj-$(CONFIG_ENV_SUPPORT) += nvedit.o
obj-$(CONFIG_CMD_NVEDIT_EFI) += nvedit_efi.o
diff --git a/cmd/abootimg.c b/cmd/abootimg.c
index 44de00fb9c9..6fb52153786 100644
--- a/cmd/abootimg.c
+++ b/cmd/abootimg.c
@@ -96,7 +96,7 @@ static int abootimg_get_dtb_load_addr(int argc, char *const argv[])
return CMD_RET_USAGE;
struct andr_image_data img_data = {0};
const struct andr_boot_img_hdr_v0 *hdr;
- const struct andr_vnd_boot_img_hdr *vhdr;
+ const struct andr_vnd_boot_img_hdr *vhdr = NULL;
hdr = map_sysmem(abootimg_addr(), sizeof(*hdr));
if (get_avendor_bootimg_addr() != -1)
diff --git a/cmd/booti.c b/cmd/booti.c
index 7e6d9426299..e6f67d6e136 100644
--- a/cmd/booti.c
+++ b/cmd/booti.c
@@ -30,6 +30,7 @@ static int booti_start(struct bootm_info *bmi)
uint8_t *temp;
ulong dest;
ulong dest_end;
+ phys_addr_t ep_addr;
unsigned long comp_len;
unsigned long decomp_len;
int ctype;
@@ -88,7 +89,14 @@ static int booti_start(struct bootm_info *bmi)
images->os.start = relocated_addr;
images->os.end = relocated_addr + image_size;
- lmb_reserve(images->ep, le32_to_cpu(image_size), LMB_NONE);
+ ep_addr = (phys_addr_t)images->ep;
+ ret = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &ep_addr,
+ le32_to_cpu(image_size), LMB_NONE);
+ if (ret) {
+ printf("Failed to allocate memory for the image at %#llx\n",
+ (unsigned long long)images->ep);
+ return 1;
+ }
/*
* Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not
diff --git a/cmd/bootz.c b/cmd/bootz.c
index 99318ff213f..44af7d012aa 100644
--- a/cmd/bootz.c
+++ b/cmd/bootz.c
@@ -28,6 +28,7 @@ static int bootz_start(struct cmd_tbl *cmdtp, int flag, int argc,
{
ulong zi_start, zi_end;
struct bootm_info bmi;
+ phys_addr_t ep_addr;
int ret;
bootm_init(&bmi);
@@ -56,7 +57,14 @@ static int bootz_start(struct cmd_tbl *cmdtp, int flag, int argc,
if (ret != 0)
return 1;
- lmb_reserve(images->ep, zi_end - zi_start, LMB_NONE);
+ ep_addr = (phys_addr_t)images->ep;
+ ret = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &ep_addr, zi_end - zi_start,
+ LMB_NONE);
+ if (ret) {
+ printf("Failed to allocate memory for the image at %#llx\n",
+ (unsigned long long)images->ep);
+ return 1;
+ }
/*
* Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not
diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c
index 6e14d34a6bd..8ac0fb98e02 100644
--- a/cmd/eficonfig.c
+++ b/cmd/eficonfig.c
@@ -35,6 +35,7 @@ static int avail_row;
#define EFICONFIG_DESCRIPTION_MAX 32
#define EFICONFIG_OPTIONAL_DATA_MAX 64
+#define EFICONFIG_URI_MAX 512
#define EFICONFIG_MENU_HEADER_ROW_NUM 3
#define EFICONFIG_MENU_DESC_ROW_NUM 5
@@ -539,6 +540,40 @@ struct efi_device_path *eficonfig_create_device_path(struct efi_device_path *dp_
}
/**
+ * eficonfig_create_uri_device_path() - Create an URI based device path
+ * @uri_str: URI string to be added to the device path
+ *
+ * Take the u16 string, convert it to a u8 string, and create a URI
+ * device path. This will be used for the EFI HTTP boot.
+ *
+ * Return: pointer to the URI device path on success, NULL on failure
+ */
+static struct efi_device_path *eficonfig_create_uri_device_path(u16 *uri_str)
+{
+ char *pos, *p;
+ u32 len = 0;
+ efi_uintn_t uridp_len;
+ struct efi_device_path_uri *uridp;
+
+ len = utf16_utf8_strlen(uri_str);
+
+ uridp_len = sizeof(struct efi_device_path) + len + 1;
+ uridp = efi_alloc(uridp_len + sizeof(EFI_DP_END));
+ if (!uridp)
+ return NULL;
+
+ uridp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
+ uridp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_URI;
+ uridp->dp.length = uridp_len;
+ p = (char *)&uridp->uri;
+ utf16_utf8_strcpy(&p, uri_str);
+ pos = (char *)uridp + uridp_len;
+ memcpy(pos, &EFI_DP_END, sizeof(EFI_DP_END));
+
+ return &uridp->dp;
+}
+
+/**
* eficonfig_file_selected() - handler of file selection
*
* @data: pointer to the data of selected entry
@@ -984,6 +1019,22 @@ static efi_status_t eficonfig_boot_add_optional_data(void *data)
}
/**
+ * eficonfig_boot_add_uri() - handle user input for HTTP Boot URI
+ *
+ * @data: pointer to the internal boot option structure
+ * Return: status code
+ */
+static efi_status_t eficonfig_boot_add_uri(void *data)
+{
+ struct eficonfig_select_file_info *file_info = data;
+
+ return handle_user_input(file_info->uri, EFICONFIG_URI_MAX, 24,
+ "\n ** Edit URI **\n"
+ "\n"
+ " enter HTTP Boot URI:");
+}
+
+/**
* eficonfig_boot_edit_save() - handler to save the boot option
*
* @data: pointer to the internal boot option structure
@@ -998,7 +1049,8 @@ static efi_status_t eficonfig_boot_edit_save(void *data)
bo->edit_completed = false;
return EFI_NOT_READY;
}
- if (u16_strlen(bo->file_info.current_path) == 0) {
+ if (u16_strlen(bo->file_info.current_path) == 0 &&
+ u16_strlen(bo->file_info.uri) == 0) {
eficonfig_print_msg("File is not selected!");
bo->edit_completed = false;
return EFI_NOT_READY;
@@ -1024,9 +1076,19 @@ efi_status_t eficonfig_process_clear_file_selection(void *data)
file_info->current_path[0] = u'\0';
file_info->dp_volume = NULL;
+ if (file_info->uri)
+ file_info->uri[0] = u'\0';
+
return EFI_ABORTED;
}
+static struct eficonfig_item select_boot_file_menu_items[] = {
+ {"Select File", eficonfig_process_select_file},
+ {"Enter URI", eficonfig_boot_add_uri},
+ {"Clear", eficonfig_process_clear_file_selection},
+ {"Quit", eficonfig_process_quit},
+};
+
static struct eficonfig_item select_file_menu_items[] = {
{"Select File", eficonfig_process_select_file},
{"Clear", eficonfig_process_clear_file_selection},
@@ -1042,16 +1104,30 @@ static struct eficonfig_item select_file_menu_items[] = {
efi_status_t eficonfig_process_show_file_option(void *data)
{
efi_status_t ret;
+ unsigned int menu_count;
struct efimenu *efi_menu;
+ struct eficonfig_item *menu_items;
+ struct eficonfig_select_file_info *file_info = data;
+
+ menu_items = file_info->uri ? select_boot_file_menu_items :
+ select_file_menu_items;
+
+ menu_count = file_info->uri ?
+ ARRAY_SIZE(select_boot_file_menu_items) :
+ ARRAY_SIZE(select_file_menu_items);
+
+ menu_items[0].data = data;
+ menu_items[1].data = data;
+ menu_items[2].data = data;
- select_file_menu_items[0].data = data;
- select_file_menu_items[1].data = data;
- efi_menu = eficonfig_create_fixed_menu(select_file_menu_items,
- ARRAY_SIZE(select_file_menu_items));
+ efi_menu = eficonfig_create_fixed_menu(menu_items, menu_count);
if (!efi_menu)
return EFI_OUT_OF_RESOURCES;
- ret = eficonfig_process_common(efi_menu, " ** Update File **",
+ ret = eficonfig_process_common(efi_menu,
+ file_info->uri ?
+ " ** Update File/URI **" :
+ " ** Update File **",
eficonfig_menu_desc,
eficonfig_display_statusline,
eficonfig_print_entry,
@@ -1121,6 +1197,14 @@ out:
file_info->current_path[len] = u'\0';
file_info->current_volume = tmp->current_volume;
file_info->dp_volume = tmp->dp_volume;
+
+ /*
+ * File being selected, set the URI string to
+ * null so that the file gets picked as the
+ * boot image.
+ */
+ if (file_info->uri)
+ file_info->uri[0] = u'\0';
}
list_for_each_safe(pos, n, &tmp->filepath_list) {
@@ -1224,6 +1308,12 @@ static efi_status_t prepare_file_selection_entry(struct efimenu *efi_menu, char
efi_handle_t handle;
char *devname;
+ /* Check for URI based boot file */
+ if (file_info->uri && utf16_utf8_strlen(file_info->uri))
+ return create_boot_option_entry(efi_menu, title, file_info->uri,
+ eficonfig_process_show_file_option,
+ file_info);
+
devname = calloc(1, EFICONFIG_VOLUME_PATH_MAX + 1);
if (!devname)
return EFI_OUT_OF_RESOURCES;
@@ -1341,6 +1431,27 @@ out:
}
/**
+ * fill_dp_uri() - copy the URI string in the device path
+ * @dp: pointer to the URI device path
+ * @uri_str: URI string to be copied
+ *
+ * Copy the passed URI string to the URI device path. This
+ * requires utf8_utf16_strcpy() to copy the u16 string to
+ * the u8 array in the device path structure.
+ *
+ * Return: None
+ */
+static void fill_dp_uri(struct efi_device_path *dp, u16 **uri_str)
+{
+ u16 *p = *uri_str;
+ struct efi_device_path_uri *uridp;
+
+ uridp = (struct efi_device_path_uri *)dp;
+
+ utf8_utf16_strcpy(&p, uridp->uri);
+}
+
+/**
* fill_file_info() - fill the file info from efi_device_path structure
*
* @dp: pointer to the device path
@@ -1392,10 +1503,13 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo
size_t len;
efi_status_t ret;
char *tmp = NULL, *p;
+ u16 *current_path = NULL;
struct efi_load_option lo = {0};
efi_uintn_t dp_size;
struct efi_device_path *dp = NULL;
efi_uintn_t size = load_option_size;
+ struct efi_device_path *dp_volume = NULL;
+ struct efi_device_path *uri_dp = NULL;
struct efi_device_path *device_dp = NULL;
struct efi_device_path *initrd_dp = NULL;
struct efi_device_path *fdt_dp = NULL;
@@ -1464,6 +1578,12 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo
goto out;
}
+ bo->file_info.uri = calloc(1, EFICONFIG_URI_MAX * sizeof(u16));
+ if (!bo->file_info.uri) {
+ ret = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+
/* copy the preset value */
if (load_option) {
ret = efi_deserialize_load_option(&lo, load_option, &size);
@@ -1481,7 +1601,10 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo
u16_strcpy(bo->description, lo.label);
/* EFI image file path is a first instance */
- if (lo.file_path)
+ if (lo.file_path && EFI_DP_TYPE(lo.file_path, MESSAGING_DEVICE,
+ MSG_URI))
+ fill_dp_uri(lo.file_path, &bo->file_info.uri);
+ else if (lo.file_path)
fill_file_info(lo.file_path, &bo->file_info, device_dp);
/* Initrd file path (optional) is placed at second instance. */
@@ -1512,6 +1635,9 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo
goto out;
}
+ if (utf16_utf8_strlen(bo->file_info.uri))
+ uri_dp = eficonfig_create_uri_device_path(bo->file_info.uri);
+
if (bo->initrd_info.dp_volume) {
dp = eficonfig_create_device_path(bo->initrd_info.dp_volume,
bo->initrd_info.current_path);
@@ -1536,7 +1662,10 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo
efi_free_pool(dp);
}
- dp = eficonfig_create_device_path(bo->file_info.dp_volume, bo->file_info.current_path);
+ dp_volume = bo->file_info.dp_volume;
+ current_path = bo->file_info.current_path;
+ dp = uri_dp ?
+ uri_dp : eficonfig_create_device_path(dp_volume, current_path);
if (!dp) {
ret = EFI_OUT_OF_RESOURCES;
goto out;
@@ -1560,6 +1689,7 @@ out:
free(tmp);
free(bo->optional_data);
free(bo->description);
+ free(bo->file_info.uri);
free(bo->file_info.current_path);
free(bo->initrd_info.current_path);
free(bo->fdt_info.current_path);
diff --git a/cmd/help.c b/cmd/help.c
index 56579e28d31..1be83ba607d 100644
--- a/cmd/help.c
+++ b/cmd/help.c
@@ -9,13 +9,9 @@
static int do_help(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
-#ifdef CONFIG_CMDLINE
struct cmd_tbl *start = ll_entry_start(struct cmd_tbl, cmd);
const int len = ll_entry_count(struct cmd_tbl, cmd);
return _do_help(start, len, cmdtp, flag, argc, argv);
-#else
- return 0;
-#endif
}
U_BOOT_CMD(
@@ -27,7 +23,6 @@ U_BOOT_CMD(
" - print detailed usage of 'command'"
);
-#ifdef CONFIG_CMDLINE
/*
* This does not use the U_BOOT_CMD macro as ? can't be used in symbol names
* nor can we rely on the CONFIG_SYS_LONGHELP helper macro
@@ -39,4 +34,3 @@ ll_entry_declare(struct cmd_tbl, question_mark, cmd) = {
""
#endif /* CONFIG_SYS_LONGHELP */
};
-#endif
diff --git a/cmd/load.c b/cmd/load.c
index 899bb4f598e..159767aa7f7 100644
--- a/cmd/load.c
+++ b/cmd/load.c
@@ -178,17 +178,20 @@ static ulong load_serial(long offset)
#endif
{
void *dst;
+ phys_addr_t dst_addr;
- ret = lmb_reserve(store_addr, binlen, LMB_NONE);
+ dst_addr = (phys_addr_t)store_addr;
+ ret = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &dst_addr,
+ binlen, LMB_NONE);
if (ret) {
printf("\nCannot overwrite reserved area (%08lx..%08lx)\n",
store_addr, store_addr + binlen);
return ret;
}
- dst = map_sysmem(store_addr, binlen);
+ dst = map_sysmem(dst_addr, binlen);
memcpy(dst, binbuf, binlen);
unmap_sysmem(dst);
- lmb_free(store_addr, binlen);
+ lmb_free(dst_addr, binlen, LMB_NONE);
}
if ((store_addr) < start_addr)
start_addr = store_addr;
diff --git a/cmd/lwip/Makefile b/cmd/lwip/Makefile
new file mode 100644
index 00000000000..a7f8976af3f
--- /dev/null
+++ b/cmd/lwip/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_CMD_DHCP) += dhcp.o
+obj-$(CONFIG_CMD_DNS) += dns.o
+obj-$(CONFIG_CMD_PING) += ping.o
+obj-$(CONFIG_CMD_SNTP) += sntp.o
+obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o
+obj-$(CONFIG_CMD_WGET) += wget.o
diff --git a/cmd/lwip/dhcp.c b/cmd/lwip/dhcp.c
new file mode 100644
index 00000000000..3894d71f654
--- /dev/null
+++ b/cmd/lwip/dhcp.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Copyright (C) 2024-2025 Linaro Ltd. */
+
+#include <command.h>
+#include <net.h>
+
+U_BOOT_CMD(dhcp, 3, 1, do_dhcp,
+ "boot image via network using DHCP/TFTP protocol",
+ "[loadAddress] [[hostIPaddr:]bootfilename]");
diff --git a/net/lwip/dns.c b/cmd/lwip/dns.c
index 6862869d9e3..b5fccc7433e 100644
--- a/net/lwip/dns.c
+++ b/cmd/lwip/dns.c
@@ -9,6 +9,9 @@
#include <net.h>
#include <time.h>
+U_BOOT_CMD(dns, 3, 1, do_dns, "lookup the IP of a hostname",
+ "hostname [envvar]");
+
#define DNS_RESEND_MS 1000
#define DNS_TIMEOUT_MS 10000
@@ -36,21 +39,18 @@ static void dns_cb(const char *name, const ip_addr_t *ipaddr, void *arg)
return;
}
+ dns_cb_arg->host_ipaddr.addr = ipaddr->addr;
+
if (dns_cb_arg->var)
env_set(dns_cb_arg->var, ipstr);
-
- printf("%s\n", ipstr);
}
static int dns_loop(struct udevice *udev, const char *name, const char *var)
{
struct dns_cb_arg dns_cb_arg = { };
- bool has_server = false;
struct netif *netif;
ip_addr_t ipaddr;
- ip_addr_t ns;
ulong start;
- char *nsenv;
int ret;
dns_cb_arg.var = var;
@@ -59,22 +59,7 @@ static int dns_loop(struct udevice *udev, const char *name, const char *var)
if (!netif)
return CMD_RET_FAILURE;
- dns_init();
-
- nsenv = env_get("dnsip");
- if (nsenv && ipaddr_aton(nsenv, &ns)) {
- dns_setserver(0, &ns);
- has_server = true;
- }
-
- nsenv = env_get("dnsip2");
- if (nsenv && ipaddr_aton(nsenv, &ns)) {
- dns_setserver(1, &ns);
- has_server = true;
- }
-
- if (!has_server) {
- log_err("No valid name server (dnsip/dnsip2)\n");
+ if (net_lwip_dns_init()) {
net_lwip_remove_netif(netif);
return CMD_RET_FAILURE;
}
@@ -92,7 +77,6 @@ static int dns_loop(struct udevice *udev, const char *name, const char *var)
net_lwip_rx(udev, netif);
if (dns_cb_arg.done)
break;
- sys_check_timeouts();
if (ctrlc()) {
printf("\nAbort\n");
break;
@@ -103,8 +87,11 @@ static int dns_loop(struct udevice *udev, const char *name, const char *var)
net_lwip_remove_netif(netif);
- if (dns_cb_arg.done && dns_cb_arg.host_ipaddr.addr != 0)
+ if (dns_cb_arg.done && dns_cb_arg.host_ipaddr.addr != 0) {
+ if (!var)
+ printf("%s\n", ipaddr_ntoa(&ipaddr));
return CMD_RET_SUCCESS;
+ }
return CMD_RET_FAILURE;
}
diff --git a/net/lwip/ping.c b/cmd/lwip/ping.c
index d8042ceecf9..87f8e958e48 100644
--- a/net/lwip/ping.c
+++ b/cmd/lwip/ping.c
@@ -13,6 +13,9 @@
#include <net.h>
#include <time.h>
+U_BOOT_CMD(ping, 2, 1, do_ping, "send ICMP ECHO_REQUEST to network host",
+ "pingAddressOrHostName");
+
#define PING_DELAY_MS 1000
#define PING_COUNT 5
/* Ping identifier - must fit on a u16_t */
@@ -136,7 +139,6 @@ static int ping_loop(struct udevice *udev, const ip_addr_t *addr)
ping_send(&ctx);
do {
- sys_check_timeouts();
net_lwip_rx(udev, netif);
if (ctx.alive)
break;
@@ -165,7 +167,7 @@ int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
if (argc < 2)
return CMD_RET_USAGE;
- if (!ipaddr_aton(argv[1], &addr))
+ if (net_lwip_dns_resolve(argv[1], &addr))
return CMD_RET_USAGE;
restart:
diff --git a/cmd/lwip/sntp.c b/cmd/lwip/sntp.c
new file mode 100644
index 00000000000..ae02bb11040
--- /dev/null
+++ b/cmd/lwip/sntp.c
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Copyright (C) 2025 Linaro Ltd. */
+
+#include <command.h>
+#include <console.h>
+#include <dm/device.h>
+#include <env.h>
+#include <lwip/apps/sntp.h>
+#include <lwip/timeouts.h>
+#include <net.h>
+
+U_BOOT_CMD(sntp, 2, 1, do_sntp, "synchronize RTC via network",
+ "[NTPServerNameOrIp]");
+
+#define SNTP_TIMEOUT 10000
+
+static enum done_state {
+ NOT_DONE = 0,
+ SUCCESS,
+ ABORTED,
+ TIMED_OUT
+} sntp_state;
+
+static void no_response(void *arg)
+{
+ sntp_state = TIMED_OUT;
+}
+
+/* Called by lwIP via the SNTP_SET_SYSTEM_TIME() macro */
+void sntp_set_system_time(uint32_t seconds)
+{
+ char *toff;
+ int net_ntp_time_offset = 0;
+
+ toff = env_get("timeoffset");
+ if (toff)
+ net_ntp_time_offset = simple_strtol(toff, NULL, 10);
+
+ net_sntp_set_rtc(seconds + net_ntp_time_offset);
+ sntp_state = SUCCESS;
+}
+
+static bool ntp_server_known(void)
+{
+ int i;
+
+ for (i = 0; i < SNTP_MAX_SERVERS; i++) {
+ const ip_addr_t *ip = sntp_getserver(i);
+
+ if (ip && ip->addr)
+ return true;
+ }
+
+ return false;
+}
+
+static int sntp_loop(struct udevice *udev, ip_addr_t *srvip)
+{
+ struct netif *netif;
+
+ netif = net_lwip_new_netif(udev);
+ if (!netif)
+ return -1;
+
+ sntp_state = NOT_DONE;
+
+ sntp_setoperatingmode(SNTP_OPMODE_POLL);
+ sntp_servermode_dhcp(CONFIG_IS_ENABLED(CMD_DHCP));
+ if (srvip) {
+ sntp_setserver(0, srvip);
+ } else {
+ if (!ntp_server_known()) {
+ log_err("error: ntpserverip not set\n");
+ return -1;
+ }
+ }
+ sntp_init();
+
+ sys_timeout(SNTP_TIMEOUT, no_response, NULL);
+ while (sntp_state == NOT_DONE) {
+ net_lwip_rx(udev, netif);
+ sys_check_timeouts();
+ if (ctrlc()) {
+ printf("\nAbort\n");
+ sntp_state = ABORTED;
+ break;
+ }
+ }
+ sys_untimeout(no_response, NULL);
+
+ sntp_stop();
+ net_lwip_remove_netif(netif);
+
+ if (sntp_state == SUCCESS)
+ return 0;
+
+ return -1;
+}
+
+int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ ip_addr_t *srvip;
+ char *server;
+ ip_addr_t ipaddr;
+
+ switch (argc) {
+ case 1:
+ srvip = NULL;
+ server = env_get("ntpserverip");
+ if (server) {
+ if (!ipaddr_aton(server, &ipaddr)) {
+ printf("ntpserverip is invalid\n");
+ return CMD_RET_FAILURE;
+ }
+ srvip = &ipaddr;
+ }
+ break;
+ case 2:
+ if (net_lwip_dns_resolve(argv[1], &ipaddr))
+ return CMD_RET_FAILURE;
+ srvip = &ipaddr;
+ break;
+ default:
+ return CMD_RET_USAGE;
+ }
+
+ if (net_lwip_eth_start() < 0)
+ return CMD_RET_FAILURE;
+
+ if (sntp_loop(eth_get_dev(), srvip) < 0)
+ return CMD_RET_FAILURE;
+
+ return CMD_RET_SUCCESS;
+}
diff --git a/cmd/lwip/tftp.c b/cmd/lwip/tftp.c
new file mode 100644
index 00000000000..6bb7a3733a2
--- /dev/null
+++ b/cmd/lwip/tftp.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Copyright (C) 2024-2025 Linaro Ltd. */
+
+#include <command.h>
+#include <net.h>
+
+U_BOOT_CMD(tftpboot, 3, 0, do_tftpb,
+ "boot image via network using TFTP protocol",
+ "[loadAddress] [[hostIPaddr:]bootfilename]");
diff --git a/cmd/lwip/wget.c b/cmd/lwip/wget.c
new file mode 100644
index 00000000000..fc9bc11cd83
--- /dev/null
+++ b/cmd/lwip/wget.c
@@ -0,0 +1,222 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Copyright (C) 2024-2025 Linaro Ltd. */
+
+#include <command.h>
+#include <env.h>
+#include <image.h>
+#include <net.h>
+#include <lwip/altcp_tls.h>
+
+U_BOOT_CMD(wget, 4, 1, do_wget,
+ "boot image via network using HTTP/HTTPS protocol"
+#if defined(CONFIG_WGET_CACERT)
+ "\nwget cacert - configure wget root certificates"
+#endif
+ ,
+ "[loadAddress] url\n"
+ "wget [loadAddress] [host:]path\n"
+ " - load file"
+#if defined(CONFIG_WGET_CACERT)
+ "\nwget cacert <address> <length>\n"
+ " - provide CA certificates (0 0 to remove current)"
+ "\nwget cacert none|optional|required\n"
+ " - set server certificate verification mode (default: optional)"
+#if defined(CONFIG_WGET_BUILTIN_CACERT)
+ "\nwget cacert builtin\n"
+ " - use the builtin CA certificates"
+#endif
+#endif
+);
+
+#if CONFIG_IS_ENABLED(WGET_CACERT) || CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT)
+char *cacert;
+size_t cacert_size;
+enum auth_mode cacert_auth_mode = AUTH_OPTIONAL;
+
+#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT)
+extern const char builtin_cacert[];
+extern const size_t builtin_cacert_size;
+bool cacert_initialized;
+#endif
+
+static int _set_cacert(const void *addr, size_t sz)
+{
+ mbedtls_x509_crt crt;
+ void *p;
+ int ret;
+
+ if (cacert)
+ free(cacert);
+
+ if (!addr) {
+ cacert = NULL;
+ cacert_size = 0;
+ return CMD_RET_SUCCESS;
+ }
+
+ p = malloc(sz);
+ if (!p)
+ return CMD_RET_FAILURE;
+ cacert = p;
+ cacert_size = sz;
+
+ memcpy(cacert, (void *)addr, sz);
+
+ mbedtls_x509_crt_init(&crt);
+ ret = mbedtls_x509_crt_parse(&crt, cacert, cacert_size);
+ if (ret) {
+ if (!wget_info->silent)
+ printf("Could not parse certificates (%d)\n", ret);
+ free(cacert);
+ cacert = NULL;
+ cacert_size = 0;
+ return CMD_RET_FAILURE;
+ }
+
+#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT)
+ cacert_initialized = true;
+#endif
+ return CMD_RET_SUCCESS;
+}
+
+#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT)
+int set_cacert_builtin(void)
+{
+ cacert_auth_mode = AUTH_REQUIRED;
+ return _set_cacert(builtin_cacert, builtin_cacert_size);
+}
+#endif
+#endif /* CONFIG_WGET_CACERT || CONFIG_WGET_BUILTIN_CACERT */
+
+#if CONFIG_IS_ENABLED(WGET_CACERT)
+static int set_auth(enum auth_mode auth)
+{
+ cacert_auth_mode = auth;
+
+ return CMD_RET_SUCCESS;
+}
+
+static int set_cacert(char * const saddr, char * const ssz)
+{
+ ulong addr, sz;
+
+ addr = hextoul(saddr, NULL);
+ sz = hextoul(ssz, NULL);
+
+ return _set_cacert((void *)addr, sz);
+}
+#endif
+
+/*
+ * Legacy syntax support
+ * Convert [<server_name_or_ip>:]filename into a URL if needed
+ */
+static int parse_legacy_arg(char *arg, char *nurl, size_t rem)
+{
+ char *p = nurl;
+ size_t n;
+ char *col = strchr(arg, ':');
+ char *env;
+ char *server;
+ char *path;
+
+ if (strstr(arg, "http") == arg) {
+ n = snprintf(nurl, rem, "%s", arg);
+ if (n < 0 || n > rem)
+ return -1;
+ return 0;
+ }
+
+ n = snprintf(p, rem, "%s", "http://");
+ if (n < 0 || n > rem)
+ return -1;
+ p += n;
+ rem -= n;
+
+ if (col) {
+ n = col - arg;
+ server = arg;
+ path = col + 1;
+ } else {
+ env = env_get("httpserverip");
+ if (!env)
+ env = env_get("serverip");
+ if (!env) {
+ log_err("error: httpserver/serverip has to be set\n");
+ return -1;
+ }
+ n = strlen(env);
+ server = env;
+ path = arg;
+ }
+
+ if (rem < n)
+ return -1;
+ strncpy(p, server, n);
+ p += n;
+ rem -= n;
+ if (rem < 1)
+ return -1;
+ *p = '/';
+ p++;
+ rem--;
+ n = strlen(path);
+ if (rem < n)
+ return -1;
+ strncpy(p, path, n);
+ p += n;
+ rem -= n;
+ if (rem < 1)
+ return -1;
+ *p = '\0';
+
+ return 0;
+}
+
+int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
+{
+ char *end;
+ char *url;
+ ulong dst_addr;
+ char nurl[1024];
+
+#if CONFIG_IS_ENABLED(WGET_CACERT)
+ if (argc == 4 && !strncmp(argv[1], "cacert", strlen("cacert")))
+ return set_cacert(argv[2], argv[3]);
+ if (argc == 3 && !strncmp(argv[1], "cacert", strlen("cacert"))) {
+#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT)
+ if (!strncmp(argv[2], "builtin", strlen("builtin")))
+ return set_cacert_builtin();
+#endif
+ if (!strncmp(argv[2], "none", strlen("none")))
+ return set_auth(AUTH_NONE);
+ if (!strncmp(argv[2], "optional", strlen("optional")))
+ return set_auth(AUTH_OPTIONAL);
+ if (!strncmp(argv[2], "required", strlen("required")))
+ return set_auth(AUTH_REQUIRED);
+ return CMD_RET_USAGE;
+ }
+#endif
+
+ if (argc < 2 || argc > 3)
+ return CMD_RET_USAGE;
+
+ dst_addr = hextoul(argv[1], &end);
+ if (end == (argv[1] + strlen(argv[1]))) {
+ if (argc < 3)
+ return CMD_RET_USAGE;
+ url = argv[2];
+ } else {
+ dst_addr = image_load_addr;
+ url = argv[1];
+ }
+
+ if (parse_legacy_arg(url, nurl, sizeof(nurl)))
+ return CMD_RET_FAILURE;
+
+ wget_info = &default_wget_info;
+ if (wget_do_request(dst_addr, nurl))
+ return CMD_RET_FAILURE;
+
+ return CMD_RET_SUCCESS;
+}
diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c
deleted file mode 100644
index cecf8d02555..00000000000
--- a/cmd/net-lwip.c
+++ /dev/null
@@ -1,50 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* Copyright (C) 2024 Linaro Ltd. */
-
-#include <command.h>
-#include <net.h>
-
-#if defined(CONFIG_CMD_DHCP)
-U_BOOT_CMD(dhcp, 3, 1, do_dhcp,
- "boot image via network using DHCP/TFTP protocol",
- "[loadAddress] [[hostIPaddr:]bootfilename]");
-#endif
-
-#if defined(CONFIG_CMD_PING)
-U_BOOT_CMD(ping, 2, 1, do_ping, "send ICMP ECHO_REQUEST to network host",
- "pingAddress");
-#endif
-
-#if defined(CONFIG_CMD_TFTPBOOT)
-U_BOOT_CMD(tftpboot, 3, 0, do_tftpb,
- "boot image via network using TFTP protocol",
- "[loadAddress] [[hostIPaddr:]bootfilename]");
-#endif
-
-#if defined(CONFIG_CMD_DNS)
-U_BOOT_CMD(dns, 3, 1, do_dns, "lookup the IP of a hostname",
- "hostname [envvar]");
-#endif
-
-#if defined(CONFIG_CMD_WGET)
-U_BOOT_CMD(wget, 4, 1, do_wget,
- "boot image via network using HTTP/HTTPS protocol"
-#if defined(CONFIG_WGET_CACERT)
- "\nwget cacert - configure wget root certificates"
-#endif
- ,
- "[loadAddress] url\n"
- "wget [loadAddress] [host:]path\n"
- " - load file"
-#if defined(CONFIG_WGET_CACERT)
- "\nwget cacert <address> <length>\n"
- " - provide CA certificates (0 0 to remove current)"
- "\nwget cacert none|optional|required\n"
- " - set server certificate verification mode (default: optional)"
-#if defined(CONFIG_WGET_BUILTIN_CACERT)
- "\nwget cacert builtin\n"
- " - use the builtin CA certificates"
-#endif
-#endif
-);
-#endif
diff --git a/cmd/smbios.c b/cmd/smbios.c
index 562dd7959be..ed419f19028 100644
--- a/cmd/smbios.c
+++ b/cmd/smbios.c
@@ -280,7 +280,7 @@ static void smbios_print_type3(struct smbios_type3 *table)
int i;
u8 *addr = (u8 *)table + offsetof(struct smbios_type3, sku_number);
- printf("Baseboard Information\n");
+ printf("Chassis Information\n");
smbios_print_str("Manufacturer", table, table->manufacturer);
printf("\tType: 0x%02x\n", table->chassis_type);
smbios_print_str("Version", table, table->version);
diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c
index a62862e94f9..346e21d27bb 100644
--- a/cmd/tpm-v2.c
+++ b/cmd/tpm-v2.c
@@ -113,7 +113,7 @@ static int do_tpm2_pcr_extend(struct cmd_tbl *cmdtp, int flag, int argc,
return CMD_RET_USAGE;
if (argc == 4) {
algo = tpm2_name_to_algorithm(argv[3]);
- if (algo < 0)
+ if (algo == TPM2_ALG_INVAL)
return CMD_RET_FAILURE;
}
algo_len = tpm2_algorithm_to_len(algo);
@@ -157,7 +157,7 @@ static int do_tpm_pcr_read(struct cmd_tbl *cmdtp, int flag, int argc,
return CMD_RET_USAGE;
if (argc == 4) {
algo = tpm2_name_to_algorithm(argv[3]);
- if (algo < 0)
+ if (algo == TPM2_ALG_INVAL)
return CMD_RET_FAILURE;
}
algo_len = tpm2_algorithm_to_len(algo);
@@ -288,7 +288,7 @@ static int do_tpm2_pcrallocate(struct cmd_tbl *cmdtp, int flag, int argc,
return CMD_RET_USAGE;
algo = tpm2_name_to_algorithm(argv[1]);
- if (algo == -EINVAL)
+ if (algo == TPM2_ALG_INVAL)
return CMD_RET_USAGE;
ret = get_tpm(&dev);
diff --git a/common/Makefile b/common/Makefile
index 35991562a12..d62ea34599e 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -19,6 +19,12 @@ obj-y += version.o
# # boards
obj-y += board_f.o
obj-y += board_r.o
+ifdef CONFIG_$(PHASE_)SYS_THUMB_BUILD
+ifneq ($(CONFIG_SYS_ARM_ARCH),7)
+CFLAGS_REMOVE_board_f.o := $(LTO_CFLAGS)
+CFLAGS_REMOVE_board_r.o := $(LTO_CFLAGS)
+endif
+endif
obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o
obj-$(CONFIG_DISPLAY_BOARDINFO_LATE) += board_info.o
diff --git a/common/cli_readline.c b/common/cli_readline.c
index 4e6797a1944..0cb43e62000 100644
--- a/common/cli_readline.c
+++ b/common/cli_readline.c
@@ -332,8 +332,8 @@ int cread_line_process_ch(struct cli_line_state *cls, char ichar)
if (cls->num) {
uint base, wlen;
- for (base = cls->num - 1;
- base >= 0 && buf[base] == ' ';)
+ for (base = cls->num;
+ base > 0 && buf[base - 1] == ' ';)
base--;
for (; base > 0 && buf[base - 1] != ' ';)
base--;
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 880192043c4..9a17ccb2d3d 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -80,7 +80,7 @@ config SPL_MAX_SIZE
default 0x1b000 if AM33XX && !TI_SECURE_DEVICE
default 0xec00 if OMAP34XX
default 0x10000 if ARCH_MX6 && !MX6_OCRAM_256KB
- default 0xbfa0 if MACH_SUN50I_H616
+ default 0xbfa0 if MACH_SUN50I_H616 || MACH_SUN50I_A133
default 0x7000 if RCAR_GEN3
default 0x5fa0 if SUNXI_SRAM_ADDRESS = 0x0
default 0x7fa0 if ARCH_SUNXI
@@ -423,7 +423,7 @@ config SPL_STACK
default 0x91ffb8 if ARCH_MX6 && !MX6_OCRAM_256KB
default 0x118000 if MACH_SUN50I_H6
default 0x52a00 if MACH_SUN50I_H616
- default 0x40000 if MACH_SUN8I_R528
+ default 0x40000 if MACH_SUN8I_R528 || MACH_SUN50I_A133
default 0x54000 if MACH_SUN50I || MACH_SUN50I_H5
default 0x18000 if MACH_SUN9I
default 0x8000 if ARCH_SUNXI
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index 86506d6905c..25f3c822a49 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -73,7 +73,7 @@ static int spl_fit_get_image_name(const struct spl_fit_info *ctx,
const char **outname)
{
struct udevice *sysinfo;
- const char *name, *str;
+ const char *name, *str, *end;
__maybe_unused int node;
int len, i;
bool found = true;
@@ -83,11 +83,17 @@ static int spl_fit_get_image_name(const struct spl_fit_info *ctx,
debug("cannot find property '%s': %d\n", type, len);
return -EINVAL;
}
+ /* A string property should be NUL terminated */
+ end = name + len - 1;
+ if (!len || *end) {
+ debug("malformed property '%s'\n", type);
+ return -EINVAL;
+ }
str = name;
for (i = 0; i < index; i++) {
str = strchr(str, '\0') + 1;
- if (!str || (str - name >= len)) {
+ if (str > end) {
found = false;
break;
}
@@ -199,7 +205,7 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size,
* the image gets loaded to the address pointed to by the
* load_addr member in this struct, if load_addr is not 0
*
- * Return: 0 on success, -EPERM if this image is not the correct phase
+ * Return: 0 on success, -EBADSLT if this image is not the correct phase
* (for CONFIG_BOOTMETH_VBE_SIMPLE_FW), or another negative error number on
* other error.
*/
@@ -235,7 +241,7 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset,
return ret;
} else {
log_debug("- phase mismatch, skipping this image\n");
- return -EPERM;
+ return -EBADSLT;
}
}
@@ -474,7 +480,7 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image,
image_info.load_addr = (ulong)tmpbuffer;
ret = load_simple_fit(info, offset, ctx, node,
&image_info);
- if (ret == -EPERM)
+ if (ret == -EBADSLT)
continue;
else if (ret < 0)
break;
@@ -702,13 +708,51 @@ static int spl_simple_fit_read(struct spl_fit_info *ctx,
*/
size = get_aligned_image_size(info, size, 0);
buf = board_spl_fit_buffer_addr(size, size, 1);
+ if (!buf) {
+ /*
+ * We assume that none of the board will ever use 0x0 as a
+ * valid load address. Theoretically some board could use it,
+ * but this is extremely unlikely.
+ */
+ return -EIO;
+ }
count = info->read(info, offset, size, buf);
+ if (!count) {
+ /*
+ * FIT could not be read. This means we should free the
+ * memory allocated by board_spl_fit_buffer_addr().
+ * Unfortunately, we don't know what memory allocation
+ * mechanism was used:
+ * - For the SPL_SYS_MALLOC_SIMPLE case nothing could
+ * be done. The memory just could not be freed.
+ * - For statically allocated memory buffer we can try
+ * to reuse previously allocated memory (example:
+ * board_spl_fit_buffer_addr() function from the
+ * file test/image/spl_load.c).
+ * - For normall malloc() -- memory leak can't be easily
+ * avoided. To somehow reduce memory consumption the
+ * next calls of board_spl_fit_buffer_addr() could
+ * reallocate previously allocated buffer and use
+ * them again. This is somethat similar to the approach
+ * used for statically allocated buffer.
+ *
+ * Please note:
+ * - FIT images with data placed outside of the FIT
+ * structure will cause small memory leak (several
+ * kilobytes),
+ * - FIT images with data placed inside to the FIT
+ * structure may cause huge memory leak (up to
+ * several megabytes). Do NOT use such images!
+ */
+ return -EIO;
+ }
+
ctx->fit = buf;
debug("fit read offset %lx, size=%lu, dst=%p, count=%lu\n",
offset, size, buf, count);
- return (count == 0) ? -EIO : 0;
+ return 0;
}
static int spl_simple_fit_parse(struct spl_fit_info *ctx)
@@ -834,7 +878,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
image_info.load_addr = 0;
ret = load_simple_fit(info, offset, &ctx, node, &image_info);
- if (ret < 0 && ret != -EPERM) {
+ if (ret < 0 && ret != -EBADSLT) {
printf("%s: can't load image loadables index %d (ret = %d)\n",
__func__, index, ret);
return ret;
diff --git a/configs/am62x_a53_usbdfu.config b/configs/am62x_a53_usbdfu.config
index 16cd4c89f41..373b1d0ed64 100644
--- a/configs/am62x_a53_usbdfu.config
+++ b/configs/am62x_a53_usbdfu.config
@@ -1,4 +1,3 @@
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SPL_ENV_SUPPORT=y
CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
diff --git a/configs/am64x_evm_a53_defconfig b/configs/am64x_evm_a53_defconfig
index 8f7d098f770..fd2b28a1c6e 100644
--- a/configs/am64x_evm_a53_defconfig
+++ b/configs/am64x_evm_a53_defconfig
@@ -1,7 +1,6 @@
CONFIG_ARM=y
CONFIG_SKIP_LOWLEVEL_INIT=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_TI_COMMON_CMD_OPTIONS=y
CONFIG_SPL_GPIO=y
@@ -144,6 +143,8 @@ CONFIG_TI_ICSSG_PRUETH=y
CONFIG_NVME_PCI=y
CONFIG_PCI_CONFIG_HOST_BRIDGE=y
CONFIG_PCIE_CDNS_TI=y
+CONFIG_PCI_ENDPOINT=y
+CONFIG_PCIE_CDNS_TI_EP=y
CONFIG_PHY=y
CONFIG_SPL_PHY=y
CONFIG_PHY_CADENCE_TORRENT=y
diff --git a/configs/am64x_evm_r5_defconfig b/configs/am64x_evm_r5_defconfig
index 6f9ec2c21e8..fdf5d7803bb 100644
--- a/configs/am64x_evm_r5_defconfig
+++ b/configs/am64x_evm_r5_defconfig
@@ -1,6 +1,5 @@
CONFIG_ARM=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x80000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
diff --git a/configs/am65x_evm_a53_defconfig b/configs/am65x_evm_a53_defconfig
index 86fa5d30373..438ec8a1c56 100644
--- a/configs/am65x_evm_a53_defconfig
+++ b/configs/am65x_evm_a53_defconfig
@@ -1,7 +1,6 @@
CONFIG_ARM=y
CONFIG_SKIP_LOWLEVEL_INIT=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_TI_COMMON_CMD_OPTIONS=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
diff --git a/configs/am65x_evm_r5_defconfig b/configs/am65x_evm_r5_defconfig
index f783b6882dc..7d3eb6f8c93 100644
--- a/configs/am65x_evm_r5_defconfig
+++ b/configs/am65x_evm_r5_defconfig
@@ -1,6 +1,5 @@
CONFIG_ARM=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x55000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
diff --git a/configs/am65x_evm_r5_usbdfu_defconfig b/configs/am65x_evm_r5_usbdfu_defconfig
index b0d333d95c2..3ac494f0126 100644
--- a/configs/am65x_evm_r5_usbdfu_defconfig
+++ b/configs/am65x_evm_r5_usbdfu_defconfig
@@ -2,7 +2,6 @@
CONFIG_ARM=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x57000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
diff --git a/configs/am65x_evm_r5_usbmsc_defconfig b/configs/am65x_evm_r5_usbmsc_defconfig
index 5722e9efd17..63ba94ff90e 100644
--- a/configs/am65x_evm_r5_usbmsc_defconfig
+++ b/configs/am65x_evm_r5_usbmsc_defconfig
@@ -1,6 +1,5 @@
CONFIG_ARM=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x55000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
diff --git a/configs/amd_versal2_mini_defconfig b/configs/amd_versal2_mini_defconfig
index e1c5d9b7fb9..e0f43352236 100644
--- a/configs/amd_versal2_mini_defconfig
+++ b/configs/amd_versal2_mini_defconfig
@@ -32,6 +32,7 @@ CONFIG_BOARD_EARLY_INIT_R=y
# CONFIG_SYS_LONGHELP is not set
CONFIG_SYS_PROMPT="versal2> "
# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_HELP is not set
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
@@ -63,6 +64,7 @@ CONFIG_OF_EMBED=y
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_NO_NET=y
# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_SIMPLE_BUS is not set
# CONFIG_GPIO is not set
# CONFIG_I2C is not set
# CONFIG_INPUT is not set
diff --git a/configs/amd_versal2_mini_emmc_defconfig b/configs/amd_versal2_mini_emmc_defconfig
index 42bab43a72b..d95c4b3d199 100644
--- a/configs/amd_versal2_mini_emmc_defconfig
+++ b/configs/amd_versal2_mini_emmc_defconfig
@@ -26,6 +26,7 @@ CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_SYS_PROMPT="versal2> "
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_HELP is not set
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
@@ -54,6 +55,7 @@ CONFIG_OF_EMBED=y
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_NO_NET=y
# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_SIMPLE_BUS is not set
CONFIG_MMC_HS200_SUPPORT=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ZYNQ=y
diff --git a/configs/amd_versal2_mini_ospi_defconfig b/configs/amd_versal2_mini_ospi_defconfig
index c2934625f2e..3de6e292c08 100644
--- a/configs/amd_versal2_mini_ospi_defconfig
+++ b/configs/amd_versal2_mini_ospi_defconfig
@@ -9,7 +9,7 @@ CONFIG_SYS_MALLOC_LEN=0x20000
CONFIG_SYS_MALLOC_F_LEN=0x4000
CONFIG_NR_DRAM_BANKS=3
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
-CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xBBF20000
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xBBFF8000
CONFIG_ENV_SIZE=0x80
CONFIG_DEFAULT_DEVICE_TREE="amd-versal2-mini"
CONFIG_SYS_LOAD_ADDR=0xBBF80000
@@ -30,6 +30,7 @@ CONFIG_BOARD_EARLY_INIT_R=y
# CONFIG_SYS_LONGHELP is not set
CONFIG_SYS_PROMPT="versal2> "
# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_HELP is not set
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
@@ -57,6 +58,8 @@ CONFIG_OF_EMBED=y
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_NO_NET=y
# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_SIMPLE_BUS is not set
+# CONFIG_ZYNQMP_FIRMWARE is not set
# CONFIG_GPIO is not set
# CONFIG_I2C is not set
# CONFIG_INPUT is not set
diff --git a/configs/amd_versal2_mini_qspi_defconfig b/configs/amd_versal2_mini_qspi_defconfig
index 1c61ae821a9..03f3bd48806 100644
--- a/configs/amd_versal2_mini_qspi_defconfig
+++ b/configs/amd_versal2_mini_qspi_defconfig
@@ -30,6 +30,7 @@ CONFIG_BOARD_EARLY_INIT_R=y
# CONFIG_SYS_LONGHELP is not set
CONFIG_SYS_PROMPT="versal2> "
# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_HELP is not set
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
@@ -57,6 +58,7 @@ CONFIG_OF_EMBED=y
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_NO_NET=y
# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_SIMPLE_BUS is not set
# CONFIG_GPIO is not set
# CONFIG_I2C is not set
# CONFIG_INPUT is not set
diff --git a/configs/amd_versal2_virt_defconfig b/configs/amd_versal2_virt_defconfig
index 3ead9f058b3..062cae70eb0 100644
--- a/configs/amd_versal2_virt_defconfig
+++ b/configs/amd_versal2_virt_defconfig
@@ -1,5 +1,5 @@
CONFIG_ARM=y
-CONFIG_COUNTER_FREQUENCY=375000
+CONFIG_COUNTER_FREQUENCY=100000000
CONFIG_POSITION_INDEPENDENT=y
CONFIG_SYS_INIT_SP_BSS_OFFSET=1572864
CONFIG_ARCH_VERSAL2=y
@@ -43,6 +43,7 @@ CONFIG_CMD_MMC=y
CONFIG_MMC_SPEED_MODE_SET=y
CONFIG_CMD_OPTEE=y
CONFIG_CMD_MTD=y
+CONFIG_CMD_POWEROFF=y
CONFIG_CMD_SF_TEST=y
CONFIG_CMD_SPI=y
CONFIG_CMD_UFS=y
@@ -130,6 +131,9 @@ CONFIG_CADENCE_QSPI=y
CONFIG_CADENCE_OSPI_VERSAL=y
CONFIG_ZYNQ_SPI=y
CONFIG_ZYNQMP_GQSPI=y
+CONFIG_SPI_STACKED_PARALLEL=y
+CONFIG_SYSRESET=y
+CONFIG_SYSRESET_PSCI=y
CONFIG_TEE=y
CONFIG_OPTEE=y
CONFIG_TPM2_TIS_SPI=y
diff --git a/configs/arbel_evb_defconfig b/configs/arbel_evb_defconfig
index f5c05fd4616..34c4e9a3f74 100644
--- a/configs/arbel_evb_defconfig
+++ b/configs/arbel_evb_defconfig
@@ -41,7 +41,6 @@ CONFIG_CMD_USB_MASS_STORAGE=y
CONFIG_CMD_DHCP6=y
CONFIG_DHCP6_PXE_DHCP_OPTION=y
CONFIG_DHCP6_ENTERPRISE_ID=311
-CONFIG_BOOTP_PXE_DHCP_OPTION=y
CONFIG_IPV6_ROUTER_DISCOVERY=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_MII=y
diff --git a/configs/astro_mcf5373l_defconfig b/configs/astro_mcf5373l_defconfig
deleted file mode 100644
index 8dd369d68a1..00000000000
--- a/configs/astro_mcf5373l_defconfig
+++ /dev/null
@@ -1,51 +0,0 @@
-CONFIG_M68K=y
-CONFIG_TEXT_BASE=0x00000000
-CONFIG_SYS_MALLOC_LEN=0x20000
-CONFIG_ENV_SIZE=0x8000
-CONFIG_ENV_SECT_SIZE=0x8000
-CONFIG_DEFAULT_DEVICE_TREE="astro_mcf5373l"
-CONFIG_SYS_MONITOR_LEN=262144
-CONFIG_SYS_LOAD_ADDR=0x20000
-CONFIG_ENV_ADDR=0x1FF8000
-CONFIG_TARGET_ASTRO_MCF5373L=y
-CONFIG_SYS_MONITOR_BASE=0x00000400
-CONFIG_BOOTDELAY=1
-CONFIG_USE_BOOTARGS=y
-CONFIG_BOOTARGS=" console=ttyS2,115200 rootfstype=romfs loaderversion=$loaderversion"
-CONFIG_USE_BOOTCOMMAND=y
-CONFIG_BOOTCOMMAND="protect off 0x80000 0x1ffffff;run env_check;run xilinxload&&run alteraload&&bootm 0x80000;update;reset"
-CONFIG_SYS_PBSIZE=281
-# CONFIG_DISPLAY_BOARDINFO is not set
-CONFIG_MISC_INIT_R=y
-CONFIG_SYS_MALLOC_BOOTPARAMS=y
-CONFIG_HUSH_PARSER=y
-# CONFIG_AUTO_COMPLETE is not set
-CONFIG_SYS_PROMPT="URMEL > "
-CONFIG_CMD_IMLS=y
-CONFIG_CMD_FPGA_LOADMK=y
-CONFIG_CMD_I2C=y
-# CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_CACHE=y
-CONFIG_CMD_JFFS2=y
-CONFIG_NO_NET=y
-CONFIG_FPGA_ALTERA=y
-CONFIG_FPGA_CYCLON2=y
-CONFIG_FPGA_XILINX=y
-CONFIG_FPGA_SPARTAN3=y
-CONFIG_SYS_FPGA_PROG_FEEDBACK=y
-CONFIG_DM_I2C=y
-CONFIG_SYS_I2C_FSL=y
-CONFIG_MTD=y
-CONFIG_MTD_NOR_FLASH=y
-CONFIG_FLASH_CFI_DRIVER=y
-CONFIG_FLASH_SHOW_PROGRESS=0
-CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
-CONFIG_SYS_FLASH_PROTECTION=y
-CONFIG_SYS_FLASH_CFI=y
-CONFIG_SYS_MAX_FLASH_SECT=259
-CONFIG_DM_RTC=y
-CONFIG_MCFRTC=y
-CONFIG_SYS_MCFRTC_BASE=0xFC0A8000
-CONFIG_MCFUART=y
-CONFIG_WDT=y
-CONFIG_WDT_MCF=y
diff --git a/configs/bk4r1_defconfig b/configs/bk4r1_defconfig
index a4174d9219b..fd3b6188776 100644
--- a/configs/bk4r1_defconfig
+++ b/configs/bk4r1_defconfig
@@ -4,7 +4,6 @@ CONFIG_SYS_THUMB_BUILD=y
CONFIG_ARCH_VF610=y
CONFIG_TEXT_BASE=0x3f401000
CONFIG_SYS_MALLOC_LEN=0x402000
-CONFIG_SYS_MALLOC_F_LEN=0x800
CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0x200000
diff --git a/configs/e850-96_defconfig b/configs/e850-96_defconfig
index e07e4cffd0a..f0e9ff7c447 100644
--- a/configs/e850-96_defconfig
+++ b/configs/e850-96_defconfig
@@ -19,6 +19,7 @@ CONFIG_ANDROID_BOOT_IMAGE=y
CONFIG_BOOTSTD_FULL=y
CONFIG_DEFAULT_FDT_FILE="exynos850-e850-96.dtb"
# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_BOARD_LATE_INIT=y
CONFIG_CMD_BOOTEFI_SELFTEST=y
CONFIG_CMD_ABOOTIMG=y
CONFIG_CMD_NVEDIT_EFI=y
diff --git a/configs/imx8mm_evk_defconfig b/configs/imx8mm_evk_defconfig
index 0e0f764d2c7..c15372edc9c 100644
--- a/configs/imx8mm_evk_defconfig
+++ b/configs/imx8mm_evk_defconfig
@@ -21,6 +21,11 @@ CONFIG_SPL_BSS_START_ADDR=0x910000
CONFIG_SPL_BSS_MAX_SIZE=0x2000
CONFIG_SYS_LOAD_ADDR=0x40480000
CONFIG_SPL=y
+CONFIG_EFI_MM_COMM_TEE=y
+CONFIG_EFI_VAR_BUF_SIZE=139264
+CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
+CONFIG_EFI_CAPSULE_ON_DISK=y
+CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
CONFIG_FIT=y
CONFIG_FIT_EXTERNAL_OFFSET=0x3000
CONFIG_SPL_LOAD_FIT=y
@@ -46,16 +51,25 @@ CONFIG_SYS_PROMPT="u-boot=> "
CONFIG_CMD_CPU=y
# CONFIG_CMD_EXPORTENV is not set
# CONFIG_CMD_IMPORTENV is not set
+CONFIG_CMD_NVEDIT_EFI=y
# CONFIG_CMD_CRC32 is not set
CONFIG_CMD_CLK=y
+CONFIG_CMD_DFU=y
CONFIG_CMD_FUSE=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
+CONFIG_CMD_OPTEE_RPMB=y
+CONFIG_CMD_OPTEE=y
CONFIG_CMD_USB_SDP=y
CONFIG_CMD_USB_MASS_STORAGE=y
CONFIG_CMD_CACHE=y
+CONFIG_CMD_EFIDEBUG=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_GETTIME=y
+CONFIG_CMD_TIMER=y
CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_EXT4_WRITE=y
CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_ENV_OVERWRITE=y
@@ -70,8 +84,10 @@ CONFIG_SPL_CLK_COMPOSITE_CCF=y
CONFIG_CLK_COMPOSITE_CCF=y
CONFIG_SPL_CLK_IMX8MM=y
CONFIG_CLK_IMX8MM=y
+CONFIG_DFU_MMC=y
CONFIG_MXC_GPIO=y
CONFIG_DM_I2C=y
+CONFIG_SUPPORT_EMMC_RPMB=y
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_MMC_IO_VOLTAGE=y
CONFIG_MMC_UHS_SUPPORT=y
@@ -103,6 +119,8 @@ CONFIG_SYSRESET=y
CONFIG_SPL_SYSRESET=y
CONFIG_SYSRESET_PSCI=y
CONFIG_SYSRESET_WATCHDOG=y
+CONFIG_TEE=y
+CONFIG_OPTEE=y
CONFIG_DM_THERMAL=y
CONFIG_USB=y
CONFIG_SPL_USB_HOST=y
@@ -118,3 +136,4 @@ CONFIG_SDP_LOADADDR=0x40400000
CONFIG_USB_GADGET_DOWNLOAD=y
CONFIG_SPL_USB_SDP_SUPPORT=y
CONFIG_IMX_WATCHDOG=y
+CONFIG_SHA384=y
diff --git a/configs/imx8mn_evk_defconfig b/configs/imx8mn_evk_defconfig
index 6a0e46b14ab..127903045e5 100644
--- a/configs/imx8mn_evk_defconfig
+++ b/configs/imx8mn_evk_defconfig
@@ -23,6 +23,12 @@ CONFIG_SYS_BOOTM_LEN=0x2000000
CONFIG_SYS_LOAD_ADDR=0x42000000
CONFIG_SPL=y
CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000
+CONFIG_EFI_SET_TIME=y
+CONFIG_EFI_MM_COMM_TEE=y
+CONFIG_EFI_VAR_BUF_SIZE=139264
+CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
+CONFIG_EFI_CAPSULE_ON_DISK=y
+CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
CONFIG_FIT=y
CONFIG_FIT_EXTERNAL_OFFSET=0x3000
CONFIG_SPL_LOAD_FIT=y
@@ -55,13 +61,22 @@ CONFIG_CMD_CPU=y
# CONFIG_CMD_EXPORTENV is not set
# CONFIG_CMD_IMPORTENV is not set
CONFIG_CMD_ERASEENV=y
+CONFIG_CMD_NVEDIT_EFI=y
# CONFIG_CMD_CRC32 is not set
CONFIG_CMD_CLK=y
+CONFIG_CMD_DFU=y
CONFIG_CMD_FUSE=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
+CONFIG_CMD_OPTEE_RPMB=y
+CONFIG_CMD_OPTEE=y
CONFIG_CMD_CACHE=y
+CONFIG_CMD_EFIDEBUG=y
+CONFIG_CMD_RTC=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_GETTIME=y
+CONFIG_CMD_TIMER=y
CONFIG_CMD_REGULATOR=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_OF_CONTROL=y
@@ -73,8 +88,10 @@ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
CONFIG_SPL_DM=y
CONFIG_SPL_CLK_IMX8MN=y
CONFIG_CLK_IMX8MN=y
+CONFIG_DFU_MMC=y
CONFIG_MXC_GPIO=y
CONFIG_DM_I2C=y
+CONFIG_SUPPORT_EMMC_RPMB=y
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_MMC_IO_VOLTAGE=y
CONFIG_SPL_MMC_IO_VOLTAGE=y
@@ -99,11 +116,16 @@ CONFIG_DM_REGULATOR=y
CONFIG_SPL_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_DM_RTC=y
+CONFIG_RTC_EMULATION=y
CONFIG_DM_SERIAL=y
CONFIG_MXC_UART=y
CONFIG_SYSRESET=y
CONFIG_SPL_SYSRESET=y
CONFIG_SYSRESET_PSCI=y
CONFIG_SYSRESET_WATCHDOG=y
+CONFIG_TEE=y
+CONFIG_OPTEE=y
CONFIG_DM_THERMAL=y
CONFIG_IMX_WATCHDOG=y
+CONFIG_SHA384=y
diff --git a/configs/imx8mp_evk_defconfig b/configs/imx8mp_evk_defconfig
index d3b51134ee6..46039fd0c03 100644
--- a/configs/imx8mp_evk_defconfig
+++ b/configs/imx8mp_evk_defconfig
@@ -23,6 +23,11 @@ CONFIG_SYS_BOOTM_LEN=0x2000000
CONFIG_SYS_LOAD_ADDR=0x40480000
CONFIG_SPL=y
CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000
+CONFIG_EFI_MM_COMM_TEE=y
+CONFIG_EFI_VAR_BUF_SIZE=139264
+CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
+CONFIG_EFI_CAPSULE_ON_DISK=y
+CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
CONFIG_FIT=y
CONFIG_FIT_EXTERNAL_OFFSET=0x3000
CONFIG_SPL_LOAD_FIT=y
@@ -51,16 +56,20 @@ CONFIG_SYS_PROMPT="u-boot=> "
CONFIG_CMD_CPU=y
# CONFIG_CMD_EXPORTENV is not set
# CONFIG_CMD_IMPORTENV is not set
+CONFIG_CMD_NVEDIT_EFI=y
# CONFIG_CMD_CRC32 is not set
CONFIG_CMD_CLK=y
+CONFIG_CMD_DFU=y
CONFIG_CMD_FUSE=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
+CONFIG_CMD_OPTEE=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_SDP=y
CONFIG_CMD_USB_MASS_STORAGE=y
CONFIG_CMD_CACHE=y
+CONFIG_CMD_EFIDEBUG=y
CONFIG_CMD_REGULATOR=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_OF_CONTROL=y
@@ -76,6 +85,7 @@ CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM=y
CONFIG_CLK_COMPOSITE_CCF=y
CONFIG_CLK_IMX8MP=y
+CONFIG_DFU_MMC=y
CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x42800000
CONFIG_FASTBOOT_BUF_SIZE=0x20000000
@@ -89,6 +99,7 @@ CONFIG_DM_PCA953X=y
CONFIG_DM_I2C=y
CONFIG_LED=y
CONFIG_LED_GPIO=y
+CONFIG_SUPPORT_EMMC_RPMB=y
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_MMC_IO_VOLTAGE=y
CONFIG_MMC_UHS_SUPPORT=y
@@ -124,6 +135,8 @@ CONFIG_SYSRESET=y
CONFIG_SPL_SYSRESET=y
CONFIG_SYSRESET_PSCI=y
CONFIG_SYSRESET_WATCHDOG=y
+CONFIG_TEE=y
+CONFIG_OPTEE=y
CONFIG_USB=y
# CONFIG_SPL_DM_USB is not set
CONFIG_DM_USB_GADGET=y
@@ -139,3 +152,4 @@ CONFIG_USB_GADGET_MANUFACTURER="FSL"
CONFIG_USB_GADGET_VENDOR_NUM=0x0525
CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
CONFIG_IMX_WATCHDOG=y
+CONFIG_SHA384=y
diff --git a/configs/imx8mq_evk_defconfig b/configs/imx8mq_evk_defconfig
index a9262833486..21bb04d18a8 100644
--- a/configs/imx8mq_evk_defconfig
+++ b/configs/imx8mq_evk_defconfig
@@ -27,6 +27,10 @@ CONFIG_SYS_LOAD_ADDR=0x40480000
CONFIG_SPL=y
CONFIG_IMX_BOOTAUX=y
CONFIG_REMAKE_ELF=y
+CONFIG_EFI_MM_COMM_TEE=y
+CONFIG_EFI_VAR_BUF_SIZE=139264
+CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
+CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
CONFIG_FIT=y
CONFIG_FIT_EXTERNAL_OFFSET=0x3000
CONFIG_SPL_LOAD_FIT=y
@@ -53,15 +57,19 @@ CONFIG_SYS_PROMPT="u-boot=> "
# CONFIG_BOOTM_NETBSD is not set
# CONFIG_CMD_EXPORTENV is not set
# CONFIG_CMD_IMPORTENV is not set
+CONFIG_CMD_NVEDIT_EFI=y
# CONFIG_CMD_CRC32 is not set
CONFIG_CMD_CLK=y
+CONFIG_CMD_DFU=y
CONFIG_CMD_FUSE=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
+CONFIG_CMD_OPTEE_RPMB=y
CONFIG_CMD_USB=y
# CONFIG_CMD_MDIO is not set
CONFIG_CMD_CACHE=y
+CONFIG_CMD_EFIDEBUG=y
CONFIG_CMD_REGULATOR=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_OF_CONTROL=y
@@ -72,9 +80,11 @@ CONFIG_ENV_MMC_DEVICE_INDEX=1
CONFIG_USE_ETHPRIME=y
CONFIG_ETHPRIME="FEC"
CONFIG_SAVED_DRAM_TIMING_BASE=0x40000000
+CONFIG_DFU_MMC=y
CONFIG_MXC_GPIO=y
CONFIG_DM_I2C=y
CONFIG_SPL_SYS_I2C_LEGACY=y
+CONFIG_SUPPORT_EMMC_RPMB=y
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_FSL_USDHC=y
CONFIG_PHYLIB=y
@@ -96,8 +106,11 @@ CONFIG_DM_REGULATOR_GPIO=y
CONFIG_SPL_POWER_I2C=y
CONFIG_DM_SERIAL=y
CONFIG_MXC_UART=y
+CONFIG_TEE=y
+CONFIG_OPTEE=y
CONFIG_DM_THERMAL=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_DWC3=y
+CONFIG_SHA384=y
diff --git a/configs/imx93_11x11_evk_defconfig b/configs/imx93_11x11_evk_defconfig
index ba2da308705..cb4a542cbf1 100644
--- a/configs/imx93_11x11_evk_defconfig
+++ b/configs/imx93_11x11_evk_defconfig
@@ -26,6 +26,12 @@ CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x88000000
CONFIG_SYS_MEMTEST_START=0x80000000
CONFIG_SYS_MEMTEST_END=0x90000000
CONFIG_REMAKE_ELF=y
+CONFIG_EFI_SET_TIME=y
+CONFIG_EFI_MM_COMM_TEE=y
+CONFIG_EFI_VAR_BUF_SIZE=139264
+CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
+CONFIG_EFI_CAPSULE_ON_DISK=y
+CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
CONFIG_BOOTCOMMAND="bootflow scan -lb; run bsp_bootcmd"
CONFIG_DEFAULT_FDT_FILE="imx93-11x11-evk.dtb"
CONFIG_SYS_CBSIZE=2048
@@ -51,6 +57,7 @@ CONFIG_SPL_WATCHDOG=y
CONFIG_SYS_PROMPT="u-boot=> "
CONFIG_CMD_CPU=y
CONFIG_CMD_ERASEENV=y
+CONFIG_CMD_NVEDIT_EFI=y
# CONFIG_CMD_CRC32 is not set
CONFIG_CMD_MEMTEST=y
CONFIG_CMD_CLK=y
@@ -60,9 +67,11 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
+CONFIG_CMD_OPTEE_RPMB=y
CONFIG_CMD_POWEROFF=y
CONFIG_CMD_SNTP=y
CONFIG_CMD_CACHE=y
+CONFIG_CMD_EFIDEBUG=y
CONFIG_CMD_RTC=y
CONFIG_CMD_TIME=y
CONFIG_CMD_GETTIME=y
@@ -89,10 +98,12 @@ CONFIG_ADC=y
CONFIG_ADC_IMX93=y
CONFIG_SPL_CLK_IMX93=y
CONFIG_CLK_IMX93=y
+CONFIG_DFU_MMC=y
CONFIG_IMX_RGPIO2P=y
CONFIG_DM_PCA953X=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_IMX_LPI2C=y
+CONFIG_SUPPORT_EMMC_RPMB=y
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_MMC_IO_VOLTAGE=y
CONFIG_MMC_UHS_SUPPORT=y
@@ -122,9 +133,12 @@ CONFIG_FSL_LPUART=y
CONFIG_SYSRESET=y
CONFIG_SYSRESET_CMD_POWEROFF=y
CONFIG_SYSRESET_PSCI=y
+CONFIG_TEE=y
+CONFIG_OPTEE=y
CONFIG_DM_THERMAL=y
CONFIG_ULP_WATCHDOG=y
CONFIG_WDT=y
+CONFIG_SHA384=y
CONFIG_LZO=y
CONFIG_BZIP2=y
CONFIG_UTHREAD=y
diff --git a/configs/iot2050_defconfig b/configs/iot2050_defconfig
index 55477c85807..a88e697d9fa 100644
--- a/configs/iot2050_defconfig
+++ b/configs/iot2050_defconfig
@@ -2,7 +2,6 @@ CONFIG_ARM=y
CONFIG_SKIP_LOWLEVEL_INIT=y
CONFIG_ARCH_K3=y
# CONFIG_TI_SECURE_DEVICE is not set
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
diff --git a/configs/j7200_evm_a72_defconfig b/configs/j7200_evm_a72_defconfig
index c9b8e02812b..3987bab5679 100644
--- a/configs/j7200_evm_a72_defconfig
+++ b/configs/j7200_evm_a72_defconfig
@@ -1,6 +1,5 @@
CONFIG_ARM=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_TI_COMMON_CMD_OPTIONS=y
CONFIG_SPL_GPIO=y
diff --git a/configs/j7200_evm_r5_defconfig b/configs/j7200_evm_r5_defconfig
index f5480b16df8..dca757fe057 100644
--- a/configs/j7200_evm_r5_defconfig
+++ b/configs/j7200_evm_r5_defconfig
@@ -1,6 +1,5 @@
CONFIG_ARM=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x70000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
diff --git a/configs/j721e_beagleboneai64_a72_defconfig b/configs/j721e_beagleboneai64_a72_defconfig
index d3f118a9429..00ed3d91242 100644
--- a/configs/j721e_beagleboneai64_a72_defconfig
+++ b/configs/j721e_beagleboneai64_a72_defconfig
@@ -1,6 +1,5 @@
CONFIG_ARM=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
diff --git a/configs/j721e_beagleboneai64_r5_defconfig b/configs/j721e_beagleboneai64_r5_defconfig
index dad3173daa3..99e96c90ef9 100644
--- a/configs/j721e_beagleboneai64_r5_defconfig
+++ b/configs/j721e_beagleboneai64_r5_defconfig
@@ -1,6 +1,5 @@
CONFIG_ARM=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x70000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
diff --git a/configs/j721e_evm_a72_defconfig b/configs/j721e_evm_a72_defconfig
index a27b7c712b4..02e3ac343d9 100644
--- a/configs/j721e_evm_a72_defconfig
+++ b/configs/j721e_evm_a72_defconfig
@@ -1,6 +1,5 @@
CONFIG_ARM=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
diff --git a/configs/j721e_evm_r5_defconfig b/configs/j721e_evm_r5_defconfig
index 15aa0f2a3e4..3a54a4c97d1 100644
--- a/configs/j721e_evm_r5_defconfig
+++ b/configs/j721e_evm_r5_defconfig
@@ -1,6 +1,5 @@
CONFIG_ARM=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x70000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
diff --git a/configs/j721s2_evm_a72_defconfig b/configs/j721s2_evm_a72_defconfig
index 36b6c6ade0b..ac584f50b94 100644
--- a/configs/j721s2_evm_a72_defconfig
+++ b/configs/j721s2_evm_a72_defconfig
@@ -1,6 +1,5 @@
CONFIG_ARM=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_TI_COMMON_CMD_OPTIONS=y
CONFIG_SPL_GPIO=y
diff --git a/configs/j721s2_evm_r5_defconfig b/configs/j721s2_evm_r5_defconfig
index fe95f2c29bc..f4c0862d0a8 100644
--- a/configs/j721s2_evm_r5_defconfig
+++ b/configs/j721s2_evm_r5_defconfig
@@ -1,6 +1,5 @@
CONFIG_ARM=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x10000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
diff --git a/configs/j784s4_evm_a72_defconfig b/configs/j784s4_evm_a72_defconfig
index faa3e26afaa..6b1306cf7af 100644
--- a/configs/j784s4_evm_a72_defconfig
+++ b/configs/j784s4_evm_a72_defconfig
@@ -1,6 +1,5 @@
CONFIG_ARM=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_TI_COMMON_CMD_OPTIONS=y
CONFIG_SPL_GPIO=y
diff --git a/configs/j784s4_evm_r5_defconfig b/configs/j784s4_evm_r5_defconfig
index 78d89bebd19..9e4170028f4 100644
--- a/configs/j784s4_evm_r5_defconfig
+++ b/configs/j784s4_evm_r5_defconfig
@@ -1,6 +1,5 @@
CONFIG_ARM=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x10000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
diff --git a/configs/legoev3_defconfig b/configs/legoev3_defconfig
index ff4d78a6d47..dee19a95d55 100644
--- a/configs/legoev3_defconfig
+++ b/configs/legoev3_defconfig
@@ -1,5 +1,6 @@
CONFIG_ARM=y
CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_SYS_THUMB_BUILD=y
CONFIG_ARCH_DAVINCI=y
CONFIG_TEXT_BASE=0xc1080000
CONFIG_SYS_MALLOC_LEN=0x110000
@@ -12,6 +13,9 @@ CONFIG_SF_DEFAULT_SPEED=50000000
CONFIG_ENV_SIZE=0x4000
CONFIG_DEFAULT_DEVICE_TREE="da850-lego-ev3"
CONFIG_SYS_LOAD_ADDR=0xc0700000
+CONFIG_LTO=y
+CONFIG_HAS_BOARD_SIZE_LIMIT=y
+CONFIG_BOARD_SIZE_LIMIT=262144
CONFIG_DYNAMIC_SYS_CLK_FREQ=y
CONFIG_BOOTDELAY=0
CONFIG_AUTOBOOT_KEYED=y
@@ -31,7 +35,6 @@ CONFIG_HUSH_PARSER=y
# CONFIG_BOOTM_RTEMS is not set
# CONFIG_BOOTM_VXWORKS is not set
CONFIG_CMD_ASKENV=y
-CONFIG_CRC32_VERIFY=y
CONFIG_CMD_MX_CYCLIC=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SPI=y
@@ -56,4 +59,3 @@ CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_DAVINCI_SPI=y
-CONFIG_REGEX=y
diff --git a/configs/liontron-h-a133l_defconfig b/configs/liontron-h-a133l_defconfig
new file mode 100644
index 00000000000..65c4359593f
--- /dev/null
+++ b/configs/liontron-h-a133l_defconfig
@@ -0,0 +1,36 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_DEFAULT_DEVICE_TREE="allwinner/sun50i-a133-liontron-h-a133l"
+CONFIG_SPL=y
+CONFIG_DRAM_SUNXI_DX_ODT=0x7070707
+CONFIG_DRAM_SUNXI_DX_DRI=0xd0d0d0d
+CONFIG_DRAM_SUNXI_CA_DRI=0xe0e
+CONFIG_DRAM_SUNXI_PARA0=0xd0a050c
+CONFIG_DRAM_SUNXI_MR11=0x4
+CONFIG_DRAM_SUNXI_MR12=0x72
+CONFIG_DRAM_SUNXI_MR14=0x7
+CONFIG_DRAM_SUNXI_TPR1=0x26
+CONFIG_DRAM_SUNXI_TPR2=0x6060606
+CONFIG_DRAM_SUNXI_TPR3=0x84040404
+CONFIG_DRAM_SUNXI_TPR6=0x48000000
+CONFIG_DRAM_SUNXI_TPR10=0x273333
+CONFIG_DRAM_SUNXI_TPR11=0x231d151c
+CONFIG_DRAM_SUNXI_TPR12=0x1212110e
+CONFIG_DRAM_SUNXI_TPR13=0x7521
+CONFIG_DRAM_SUNXI_TPR14=0x2023211f
+CONFIG_MACH_SUN50I_A133=y
+CONFIG_SUNXI_DRAM_A133_LPDDR4=y
+CONFIG_DRAM_CLK=792
+CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+CONFIG_R_I2C_ENABLE=y
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL_I2C=y
+CONFIG_SPL_SYS_I2C_LEGACY=y
+CONFIG_SYS_I2C_MVTWSI=y
+CONFIG_SYS_I2C_SLAVE=0x7f
+CONFIG_SYS_I2C_SPEED=400000
+CONFIG_SUPPORT_EMMC_BOOT=y
+CONFIG_AXP803_POWER=y
+CONFIG_AXP_DCDC5_VOLT=1100
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
diff --git a/configs/ls1021aqds_nor_SECURE_BOOT_defconfig b/configs/ls1021aqds_nor_SECURE_BOOT_defconfig
index ad4b58e517b..3934d259887 100644
--- a/configs/ls1021aqds_nor_SECURE_BOOT_defconfig
+++ b/configs/ls1021aqds_nor_SECURE_BOOT_defconfig
@@ -24,7 +24,6 @@ CONFIG_FSL_QIXIS=y
# CONFIG_QIXIS_I2C_ACCESS is not set
CONFIG_SYS_MEMTEST_START=0x80000000
CONFIG_SYS_MEMTEST_END=0x9fffffff
-# CONFIG_SYS_MALLOC_F is not set
CONFIG_DYNAMIC_SYS_CLK_FREQ=y
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
diff --git a/configs/ls1021atwr_nor_SECURE_BOOT_defconfig b/configs/ls1021atwr_nor_SECURE_BOOT_defconfig
index 38bb415bb81..503afd1847b 100644
--- a/configs/ls1021atwr_nor_SECURE_BOOT_defconfig
+++ b/configs/ls1021atwr_nor_SECURE_BOOT_defconfig
@@ -21,7 +21,6 @@ CONFIG_PCIE1=y
CONFIG_PCIE2=y
CONFIG_SYS_MEMTEST_START=0x80000000
CONFIG_SYS_MEMTEST_END=0x9fffffff
-# CONFIG_SYS_MALLOC_F is not set
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_DISTRO_DEFAULTS=y
diff --git a/configs/mangopi_mq_r_defconfig b/configs/mangopi_mq_r_defconfig
index df3dec704f4..9017df040cf 100644
--- a/configs/mangopi_mq_r_defconfig
+++ b/configs/mangopi_mq_r_defconfig
@@ -6,10 +6,10 @@ CONFIG_DRAM_SUNXI_ODT_EN=0
CONFIG_DRAM_SUNXI_TPR0=0x004a2195
CONFIG_DRAM_SUNXI_TPR11=0x340000
CONFIG_DRAM_SUNXI_TPR12=0x46
+CONFIG_DRAM_SUNXI_TPR13=0x34000100
CONFIG_MACH_SUN8I_R528=y
CONFIG_DRAM_CLK=792
CONFIG_DRAM_ZQ=8092667
CONFIG_SUNXI_MINIMUM_DRAM_MB=128
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-CONFIG_DRAM_SUNXI_TPR13=0x34000100
CONFIG_CONS_INDEX=4
diff --git a/configs/mx6sabresd_defconfig b/configs/mx6sabresd_defconfig
index e8109fbe6c0..75a655a0e0d 100644
--- a/configs/mx6sabresd_defconfig
+++ b/configs/mx6sabresd_defconfig
@@ -40,6 +40,8 @@ CONFIG_SPL_WATCHDOG=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_MAXARGS=32
CONFIG_CMD_BOOTZ=y
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
CONFIG_CMD_SPL=y
CONFIG_CMD_SPL_WRITE_SIZE=0x20000
CONFIG_CMD_GPIO=y
@@ -65,7 +67,6 @@ CONFIG_EFI_PARTITION=y
# CONFIG_SPL_EFI_PARTITION is not set
CONFIG_OF_CONTROL=y
CONFIG_OF_LIST="imx6q-sabresd imx6qp-sabresd imx6dl-sabresd"
-CONFIG_MULTI_DTB_FIT=y
CONFIG_ENV_OVERWRITE=y
CONFIG_ENV_IS_IN_MMC=y
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
diff --git a/configs/pcm052_defconfig b/configs/pcm052_defconfig
index 7cfeee3cafe..64f5f777e5c 100644
--- a/configs/pcm052_defconfig
+++ b/configs/pcm052_defconfig
@@ -4,7 +4,6 @@ CONFIG_SYS_THUMB_BUILD=y
CONFIG_ARCH_VF610=y
CONFIG_TEXT_BASE=0x3f401000
CONFIG_SYS_MALLOC_LEN=0x202000
-CONFIG_SYS_MALLOC_F_LEN=0x400
CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0xA0000
diff --git a/configs/phycore_am62ax_a53_defconfig b/configs/phycore_am62ax_a53_defconfig
index 35d693a17ed..bdd7e288aa4 100644
--- a/configs/phycore_am62ax_a53_defconfig
+++ b/configs/phycore_am62ax_a53_defconfig
@@ -1,6 +1,5 @@
CONFIG_ARM=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
diff --git a/configs/phycore_am62x_a53_defconfig b/configs/phycore_am62x_a53_defconfig
index 5e89076774e..910a41fa052 100644
--- a/configs/phycore_am62x_a53_defconfig
+++ b/configs/phycore_am62x_a53_defconfig
@@ -1,7 +1,6 @@
CONFIG_ARM=y
CONFIG_ARM_SMCCC=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
diff --git a/configs/phycore_am64x_a53_defconfig b/configs/phycore_am64x_a53_defconfig
index a8bf7d7339b..9f98b3522dc 100644
--- a/configs/phycore_am64x_a53_defconfig
+++ b/configs/phycore_am64x_a53_defconfig
@@ -1,7 +1,6 @@
CONFIG_ARM=y
CONFIG_SKIP_LOWLEVEL_INIT=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
diff --git a/configs/phycore_am64x_r5_defconfig b/configs/phycore_am64x_r5_defconfig
index 8a8fe70e25c..189d0706ce5 100644
--- a/configs/phycore_am64x_r5_defconfig
+++ b/configs/phycore_am64x_r5_defconfig
@@ -1,6 +1,5 @@
CONFIG_ARM=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x80000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
diff --git a/configs/qcm6490_defconfig b/configs/qcm6490_defconfig
index ba26924da16..5ddc5ab3ef8 100644
--- a/configs/qcm6490_defconfig
+++ b/configs/qcm6490_defconfig
@@ -19,9 +19,3 @@ CONFIG_TEXT_BASE=0x9fc00000
CONFIG_REMAKE_ELF=y
CONFIG_DEFAULT_DEVICE_TREE="qcom/qcs6490-rb3gen2"
-
-# Enable capsule updates
-CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
-CONFIG_EFI_CAPSULE_ON_DISK=y
-CONFIG_EFI_IGNORE_OSINDICATIONS=y
-CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
diff --git a/configs/qcom_defconfig b/configs/qcom_defconfig
index 5eb027ba27b..84cc4cf82d8 100644
--- a/configs/qcom_defconfig
+++ b/configs/qcom_defconfig
@@ -6,6 +6,9 @@ CONFIG_ARCH_SNAPDRAGON=y
CONFIG_NR_DRAM_BANKS=24
CONFIG_DEFAULT_DEVICE_TREE="qcom/sdm845-db845c"
CONFIG_SYS_LOAD_ADDR=0xA0000000
+CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
+CONFIG_EFI_CAPSULE_ON_DISK=y
+CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
CONFIG_BUTTON_CMD=y
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
@@ -51,6 +54,8 @@ CONFIG_CLK_QCOM_APQ8016=y
CONFIG_CLK_QCOM_APQ8096=y
CONFIG_CLK_QCOM_QCM2290=y
CONFIG_CLK_QCOM_QCS404=y
+CONFIG_CLK_QCOM_QCS615=y
+CONFIG_CLK_QCOM_QCS8300=y
CONFIG_CLK_QCOM_SA8775P=y
CONFIG_CLK_QCOM_SDM845=y
CONFIG_CLK_QCOM_SM6115=y
@@ -143,3 +148,5 @@ CONFIG_VIDEO_FONT_16X32=y
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_NO_FB_CLEAR=y
CONFIG_VIDEO_SIMPLE=y
+CONFIG_WDT=y
+CONFIG_WDT_QCOM=y
diff --git a/configs/qcom_ipq5424_mmc_defconfig b/configs/qcom_ipq5424_mmc_defconfig
new file mode 100644
index 00000000000..e508c0cf508
--- /dev/null
+++ b/configs/qcom_ipq5424_mmc_defconfig
@@ -0,0 +1,56 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_SYS_INIT_SP_BSS_OFFSET=1572864
+CONFIG_ARCH_SNAPDRAGON=y
+CONFIG_TEXT_BASE=0x8a380000
+CONFIG_NR_DRAM_BANKS=24
+CONFIG_ENV_SIZE=0x40000
+CONFIG_ENV_OFFSET=0
+CONFIG_DEFAULT_DEVICE_TREE="qcom/ipq5424-rdp466"
+CONFIG_SYS_LOAD_ADDR=0x50000000
+CONFIG_DEBUG_UART_BASE=0x1a84000
+CONFIG_DEBUG_UART_CLOCK=14745600
+CONFIG_DEBUG_UART=y
+CONFIG_REMAKE_ELF=y
+# CONFIG_EFI_LOADER is not set
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+# CONFIG_BOOTSTD is not set
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_USE_PREBOOT=y
+CONFIG_SYS_PBSIZE=1024
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_EFI_PARTITION=y
+CONFIG_OF_LIVE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_CLK=y
+CONFIG_CLK_QCOM_IPQ5424=y
+CONFIG_MSM_GPIO=y
+# CONFIG_I2C is not set
+# CONFIG_INPUT is not set
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ADMA=y
+CONFIG_MMC_SDHCI_MSM=y
+CONFIG_MTD=y
+CONFIG_DM_MDIO=y
+CONFIG_DM_ETH_PHY=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_QCOM=y
+CONFIG_RGMII=y
+CONFIG_PHY=y
+CONFIG_PHY_QCOM_QMP_UFS=y
+CONFIG_PHY_QCOM_QUSB2=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_QCOM_IPQ5424=y
+CONFIG_DEBUG_UART_MSM_GENI=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_MSM_SERIAL=y
+CONFIG_MSM_GENI_SERIAL=y
+CONFIG_SOC_QCOM=y
diff --git a/configs/qcom_ipq9574_mmc_defconfig b/configs/qcom_ipq9574_mmc_defconfig
index c7ce4f5c237..720220dc98a 100644
--- a/configs/qcom_ipq9574_mmc_defconfig
+++ b/configs/qcom_ipq9574_mmc_defconfig
@@ -28,8 +28,6 @@ CONFIG_CMD_PART=y
CONFIG_EFI_PARTITION=y
CONFIG_OF_LIVE=y
CONFIG_ENV_IS_IN_MMC=y
-CONFIG_USE_ENV_DEFAULT_ENV_TEXT_FILE=y
-CONFIG_ENV_DEFAULT_ENV_TEXT_FILE="board/qualcomm/default.env"
CONFIG_CLK=y
CONFIG_CLK_QCOM_IPQ9574=y
CONFIG_MSM_GPIO=y
diff --git a/configs/qcom_qcs615_defconfig b/configs/qcom_qcs615_defconfig
new file mode 100644
index 00000000000..2468267b955
--- /dev/null
+++ b/configs/qcom_qcs615_defconfig
@@ -0,0 +1,22 @@
+# Configuration for building U-Boot to be flashed
+# to the uefi partition of QCS615 dev boards with
+# the "Linux Embedded" partition layout (which have
+# a dedicated "uefi" partition for edk2/U-Boot)
+
+#include "qcom_defconfig"
+
+# Otherwise buildman thinks this isn't an ARM platform
+CONFIG_ARM=y
+
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEBUG_UART_BASE=0x880000
+CONFIG_DEBUG_UART_MSM_GENI=y
+CONFIG_DEBUG_UART_CLOCK=14745600
+
+CONFIG_DEFAULT_DEVICE_TREE="qcom/qcs615-ride"
+
+CONFIG_REMAKE_ELF=y
+
+# Address where U-Boot will be loaded
+CONFIG_TEXT_BASE=0x9fc00000
diff --git a/configs/qcom_qcs8300_defconfig b/configs/qcom_qcs8300_defconfig
new file mode 100644
index 00000000000..5fffcddc16e
--- /dev/null
+++ b/configs/qcom_qcs8300_defconfig
@@ -0,0 +1,21 @@
+# Configuration for building U-Boot to be flashed
+# to the uefi partition of QCS8300 dev boards with
+# the "Linux Embedded" partition layout (which have
+# a dedicated "uefi_a" partition for edk2/U-Boot)
+
+#include "qcom_defconfig"
+
+# Otherwise buildman thinks this isn't an ARM platform
+CONFIG_ARM=y
+
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEBUG_UART_BASE=0x99C000
+CONFIG_DEBUG_UART_MSM_GENI=y
+CONFIG_DEBUG_UART_CLOCK=14745600
+
+# Address where U-Boot will be loaded
+CONFIG_TEXT_BASE=0xaf000000
+CONFIG_REMAKE_ELF=y
+
+CONFIG_DEFAULT_DEVICE_TREE="qcom/qcs8300-ride"
diff --git a/configs/qemu_arm64_defconfig b/configs/qemu_arm64_defconfig
index 72bd255eafa..39afb837e41 100644
--- a/configs/qemu_arm64_defconfig
+++ b/configs/qemu_arm64_defconfig
@@ -1,4 +1,5 @@
CONFIG_ARM=y
+CONFIG_KVM_VIRT_INS=y
CONFIG_ARCH_QEMU=y
CONFIG_SYS_MALLOC_LEN=0x1000000
CONFIG_BLOBLIST_SIZE_RELOC=0x2000
diff --git a/configs/qemu_arm64_lwip_defconfig b/configs/qemu_arm64_lwip_defconfig
index 814e98729a3..e8f976efaf7 100644
--- a/configs/qemu_arm64_lwip_defconfig
+++ b/configs/qemu_arm64_lwip_defconfig
@@ -5,6 +5,7 @@ CONFIG_ARCH_QEMU=y
CONFIG_NET_LWIP=y
CONFIG_CMD_DNS=y
+CONFIG_CMD_SNTP=y
CONFIG_CMD_WGET=y
CONFIG_EFI_HTTP_BOOT=y
CONFIG_WGET_HTTPS=y
diff --git a/configs/qemu_arm_defconfig b/configs/qemu_arm_defconfig
index f13001390d4..92ba48f6af9 100644
--- a/configs/qemu_arm_defconfig
+++ b/configs/qemu_arm_defconfig
@@ -1,4 +1,5 @@
CONFIG_ARM=y
+CONFIG_KVM_VIRT_INS=y
CONFIG_ARM_SMCCC=y
CONFIG_ARCH_QEMU=y
CONFIG_SYS_MALLOC_LEN=0x1000000
diff --git a/configs/r8a779g0_whitehawk_defconfig b/configs/r8a779g0_whitehawk_defconfig
index fefe356ed2b..41217fa5776 100644
--- a/configs/r8a779g0_whitehawk_defconfig
+++ b/configs/r8a779g0_whitehawk_defconfig
@@ -26,7 +26,9 @@ CONFIG_PHY_MICREL_KSZ90X1=y
CONFIG_RENESAS_RAVB=y
CONFIG_BAUDRATE=921600
-CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xeb300000
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_HAVE_INIT_STACK=y
+CONFIG_SPL_STACK=0xe6400000
CONFIG_SPL_DM_SPI=y
CONFIG_SPL_TEXT_BASE=0xeb210000
CONFIG_SPL_STACK_R_ADDR=0x44000000
diff --git a/configs/r8a779g3_sparrowhawk_defconfig b/configs/r8a779g3_sparrowhawk_defconfig
index 47fc536df81..9aa8dc83317 100644
--- a/configs/r8a779g3_sparrowhawk_defconfig
+++ b/configs/r8a779g3_sparrowhawk_defconfig
@@ -24,12 +24,19 @@ CONFIG_CMD_REMOTEPROC=y
CONFIG_GPIO_HOG=y
CONFIG_REMOTEPROC_RENESAS_APMU=y
CONFIG_BITBANGMII=y
+CONFIG_CMD_PCI=y
CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_NVME_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_RCAR_GEN4=y
+CONFIG_PCI_REGION_MULTI_ENTRY=y
CONFIG_PHY_MICREL=y
CONFIG_PHY_MICREL_KSZ90X1=y
CONFIG_RENESAS_RAVB=y
-CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xeb300000
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_HAVE_INIT_STACK=y
+CONFIG_SPL_STACK=0xe6400000
CONFIG_SPL_DM_SPI=y
CONFIG_SPL_TEXT_BASE=0xeb210000
CONFIG_SPL_STACK_R_ADDR=0x44000000
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index 34e89bf6b3e..1cefaa0a138 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -31,7 +31,6 @@ CONFIG_ANDROID_AB=y
CONFIG_CMD_CPU=y
CONFIG_CMD_LICENSE=y
CONFIG_CMD_BOOTZ=y
-CONFIG_CMD_BOOTEFI_HELLO=y
# CONFIG_CMD_ELF is not set
CONFIG_CMD_ASKENV=y
CONFIG_CMD_GREPENV=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 4f6943d1a4b..d6768e291d0 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -59,7 +59,6 @@ CONFIG_CMD_BOOTM_PRE_LOAD=y
CONFIG_CMD_BOOTZ=y
CONFIG_BOOTM_OPENRTOS=y
CONFIG_BOOTM_OSE=y
-CONFIG_CMD_BOOTEFI_HELLO=y
CONFIG_CMD_BOOTMENU=y
CONFIG_CMD_ABOOTIMG=y
CONFIG_CMD_ASKENV=y
diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig
index 67c0ed7353e..f0a69a414db 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -30,7 +30,6 @@ CONFIG_CMD_CPU=y
CONFIG_CMD_LICENSE=y
CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_BOOTEFI_BOOTMGR is not set
-CONFIG_CMD_BOOTEFI_HELLO=y
# CONFIG_CMD_ELF is not set
CONFIG_CMD_ASKENV=y
CONFIG_CMD_GREPENV=y
diff --git a/configs/sandbox_noinst_defconfig b/configs/sandbox_noinst_defconfig
index 2a8e79a95c7..a0702d6f6e1 100644
--- a/configs/sandbox_noinst_defconfig
+++ b/configs/sandbox_noinst_defconfig
@@ -66,7 +66,6 @@ CONFIG_SPL_SPI_LOAD=y
CONFIG_CMD_CPU=y
CONFIG_CMD_LICENSE=y
CONFIG_CMD_BOOTZ=y
-CONFIG_CMD_BOOTEFI_HELLO=y
# CONFIG_CMD_ELF is not set
CONFIG_CMD_ASKENV=y
CONFIG_CMD_GREPENV=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index 76b0ef1fcb6..f1c48c84b62 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -45,7 +45,6 @@ CONFIG_SPL_RTC=y
CONFIG_CMD_CPU=y
CONFIG_CMD_LICENSE=y
CONFIG_CMD_BOOTZ=y
-CONFIG_CMD_BOOTEFI_HELLO=y
# CONFIG_CMD_ELF is not set
CONFIG_CMD_ASKENV=y
CONFIG_CMD_GREPENV=y
diff --git a/configs/sandbox_vpl_defconfig b/configs/sandbox_vpl_defconfig
index e1a0555744c..9d75bb5f933 100644
--- a/configs/sandbox_vpl_defconfig
+++ b/configs/sandbox_vpl_defconfig
@@ -58,7 +58,6 @@ CONFIG_VPL_TEXT_BASE=0x100000
CONFIG_CMD_CPU=y
CONFIG_CMD_LICENSE=y
CONFIG_CMD_BOOTZ=y
-CONFIG_CMD_BOOTEFI_HELLO=y
# CONFIG_CMD_ELF is not set
CONFIG_CMD_ASKENV=y
CONFIG_CMD_GREPENV=y
diff --git a/configs/th1520_lpi4a_defconfig b/configs/th1520_lpi4a_defconfig
index 243b89f753d..78e3b25ab82 100644
--- a/configs/th1520_lpi4a_defconfig
+++ b/configs/th1520_lpi4a_defconfig
@@ -90,6 +90,7 @@ CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ADMA=y
CONFIG_MMC_SDHCI_SNPS=y
# CONFIG_MTD is not set
+CONFIG_PINCTRL=y
# CONFIG_POWER is not set
CONFIG_RAM=y
CONFIG_SPL_RAM=y
diff --git a/configs/verdin-am62_a53_defconfig b/configs/verdin-am62_a53_defconfig
index 4b8e7d9f490..584c416bd83 100644
--- a/configs/verdin-am62_a53_defconfig
+++ b/configs/verdin-am62_a53_defconfig
@@ -1,6 +1,5 @@
CONFIG_ARM=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
diff --git a/configs/verdin-am62p_a53_defconfig b/configs/verdin-am62p_a53_defconfig
index e4a28050079..28f48ba773e 100644
--- a/configs/verdin-am62p_a53_defconfig
+++ b/configs/verdin-am62p_a53_defconfig
@@ -1,6 +1,5 @@
CONFIG_ARM=y
CONFIG_ARCH_K3=y
-CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
@@ -19,7 +18,6 @@ CONFIG_SPL_MMC=y
CONFIG_SPL_SERIAL=y
CONFIG_SPL_DRIVERS_MISC=y
CONFIG_SPL_STACK_R_ADDR=0x82000000
-CONFIG_SPL_TEXT_BASE=0x80080000
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
CONFIG_SPL_BSS_START_ADDR=0x80c80000
CONFIG_SPL_BSS_MAX_SIZE=0x80000
@@ -73,7 +71,6 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_READ=y
-CONFIG_CMD_REMOTEPROC=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
CONFIG_CMD_BOOTCOUNT=y
@@ -171,7 +168,6 @@ CONFIG_DM_REGULATOR_TPS65219=y
CONFIG_K3_SYSTEM_CONTROLLER=y
CONFIG_REMOTEPROC_TI_K3_ARM64=y
CONFIG_REMOTEPROC_TI_K3_DSP=y
-CONFIG_REMOTEPROC_TI_K3_R5F=y
CONFIG_RESET_TI_SCI=y
CONFIG_DM_SERIAL=y
CONFIG_SOC_DEVICE=y
diff --git a/configs/verdin-am62p_r5_defconfig b/configs/verdin-am62p_r5_defconfig
index bbdc803eb3a..42361523ab3 100644
--- a/configs/verdin-am62p_r5_defconfig
+++ b/configs/verdin-am62p_r5_defconfig
@@ -18,7 +18,6 @@ CONFIG_SPL_SERIAL=y
CONFIG_SPL_DRIVERS_MISC=y
CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_SPL_SYS_MALLOC_F_LEN=0x8000
-CONFIG_SPL_TEXT_BASE=0x43c00000
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
CONFIG_SPL_BSS_START_ADDR=0x43c4b000
CONFIG_SPL_BSS_MAX_SIZE=0x3000
@@ -49,7 +48,6 @@ CONFIG_SPL_DM_MAILBOX=y
CONFIG_SPL_DM_RESET=y
CONFIG_SPL_POWER_DOMAIN=y
CONFIG_SPL_RAM_DEVICE=y
-CONFIG_SPL_REMOTEPROC=y
CONFIG_CMD_DFU=y
CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
@@ -89,7 +87,6 @@ CONFIG_PINCTRL_SINGLE=y
CONFIG_POWER_DOMAIN=y
CONFIG_TI_POWER_DOMAIN=y
CONFIG_K3_SYSTEM_CONTROLLER=y
-CONFIG_REMOTEPROC_TI_K3_ARM64=y
CONFIG_RESET_TI_SCI=y
CONFIG_SPECIFY_CONSOLE_INDEX=y
CONFIG_DM_SERIAL=y
diff --git a/configs/vf610twr_defconfig b/configs/vf610twr_defconfig
index 0bb21f58a7c..556190728e1 100644
--- a/configs/vf610twr_defconfig
+++ b/configs/vf610twr_defconfig
@@ -4,7 +4,6 @@ CONFIG_SYS_THUMB_BUILD=y
CONFIG_ARCH_VF610=y
CONFIG_TEXT_BASE=0x3f401000
CONFIG_SYS_MALLOC_LEN=0x202000
-CONFIG_SYS_MALLOC_F_LEN=0x400
CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0xC0000
diff --git a/configs/vf610twr_nand_defconfig b/configs/vf610twr_nand_defconfig
index a7e8cf2f7bb..7fe9d822110 100644
--- a/configs/vf610twr_nand_defconfig
+++ b/configs/vf610twr_nand_defconfig
@@ -4,7 +4,6 @@ CONFIG_SYS_THUMB_BUILD=y
CONFIG_ARCH_VF610=y
CONFIG_TEXT_BASE=0x3f401000
CONFIG_SYS_MALLOC_LEN=0x0220000
-CONFIG_SYS_MALLOC_F_LEN=0x400
CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SIZE=0x20000
CONFIG_ENV_OFFSET=0x180000
diff --git a/configs/xilinx_versal_mini_defconfig b/configs/xilinx_versal_mini_defconfig
index 605a30b9987..59f33f669cb 100644
--- a/configs/xilinx_versal_mini_defconfig
+++ b/configs/xilinx_versal_mini_defconfig
@@ -33,6 +33,7 @@ CONFIG_CLOCKS=y
# CONFIG_SYS_LONGHELP is not set
CONFIG_SYS_PROMPT="Versal> "
# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_HELP is not set
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
@@ -60,6 +61,7 @@ CONFIG_SYS_ALT_MEMTEST=y
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_NO_NET=y
# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_SIMPLE_BUS is not set
# CONFIG_MMC is not set
CONFIG_ARM_DCC=y
# CONFIG_GZIP is not set
diff --git a/configs/xilinx_versal_mini_emmc0_defconfig b/configs/xilinx_versal_mini_emmc0_defconfig
index 90d6abd490e..92d08120237 100644
--- a/configs/xilinx_versal_mini_emmc0_defconfig
+++ b/configs/xilinx_versal_mini_emmc0_defconfig
@@ -31,6 +31,7 @@ CONFIG_CLOCKS=y
CONFIG_SYS_PROMPT="Versal> "
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_HELP is not set
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
@@ -59,6 +60,7 @@ CONFIG_OF_EMBED=y
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_NO_NET=y
# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_SIMPLE_BUS is not set
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ZYNQ=y
CONFIG_ARM_DCC=y
diff --git a/configs/xilinx_versal_mini_emmc1_defconfig b/configs/xilinx_versal_mini_emmc1_defconfig
index df6a4165015..2c3775c3075 100644
--- a/configs/xilinx_versal_mini_emmc1_defconfig
+++ b/configs/xilinx_versal_mini_emmc1_defconfig
@@ -31,6 +31,7 @@ CONFIG_CLOCKS=y
CONFIG_SYS_PROMPT="Versal> "
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_HELP is not set
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
@@ -59,6 +60,7 @@ CONFIG_OF_EMBED=y
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_NO_NET=y
# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_SIMPLE_BUS is not set
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ZYNQ=y
CONFIG_ARM_DCC=y
diff --git a/configs/xilinx_versal_mini_ospi_defconfig b/configs/xilinx_versal_mini_ospi_defconfig
index af9ce499169..11811f3c0fd 100644
--- a/configs/xilinx_versal_mini_ospi_defconfig
+++ b/configs/xilinx_versal_mini_ospi_defconfig
@@ -31,6 +31,7 @@ CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_SYS_PROMPT="Versal> "
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_HELP is not set
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
@@ -54,6 +55,7 @@ CONFIG_SYS_PROMPT="Versal> "
# CONFIG_CMD_SETEXPR is not set
CONFIG_NO_NET=y
# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_SIMPLE_BUS is not set
# CONFIG_MMC is not set
CONFIG_MTD=y
CONFIG_DM_SPI_FLASH=y
diff --git a/configs/xilinx_versal_mini_qspi_defconfig b/configs/xilinx_versal_mini_qspi_defconfig
index ecb3b16033c..47737ce0f8f 100644
--- a/configs/xilinx_versal_mini_qspi_defconfig
+++ b/configs/xilinx_versal_mini_qspi_defconfig
@@ -32,6 +32,7 @@ CONFIG_SYS_PROMPT="Versal> "
# CONFIG_SYS_XTRACE is not set
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_HELP is not set
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
@@ -56,6 +57,7 @@ CONFIG_SYS_PROMPT="Versal> "
# CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG is not set
CONFIG_NO_NET=y
# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_SIMPLE_BUS is not set
# CONFIG_GPIO is not set
# CONFIG_I2C is not set
# CONFIG_INPUT is not set
diff --git a/configs/xilinx_versal_net_mini_defconfig b/configs/xilinx_versal_net_mini_defconfig
index 7cae88b0d9f..27a163a9ae5 100644
--- a/configs/xilinx_versal_net_mini_defconfig
+++ b/configs/xilinx_versal_net_mini_defconfig
@@ -33,6 +33,7 @@ CONFIG_BOARD_EARLY_INIT_R=y
# CONFIG_SYS_LONGHELP is not set
CONFIG_SYS_PROMPT="Versal NET> "
# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_HELP is not set
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
@@ -64,6 +65,7 @@ CONFIG_OF_EMBED=y
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_NO_NET=y
# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_SIMPLE_BUS is not set
# CONFIG_GPIO is not set
# CONFIG_I2C is not set
# CONFIG_INPUT is not set
diff --git a/configs/xilinx_versal_net_mini_emmc_defconfig b/configs/xilinx_versal_net_mini_emmc_defconfig
index 30f4885d149..8d3561fee6d 100644
--- a/configs/xilinx_versal_net_mini_emmc_defconfig
+++ b/configs/xilinx_versal_net_mini_emmc_defconfig
@@ -26,6 +26,7 @@ CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_SYS_PROMPT="Versal NET> "
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_HELP is not set
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
@@ -54,6 +55,7 @@ CONFIG_OF_EMBED=y
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_NO_NET=y
# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_SIMPLE_BUS is not set
CONFIG_MMC_HS200_SUPPORT=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ZYNQ=y
diff --git a/configs/xilinx_versal_net_mini_ospi_defconfig b/configs/xilinx_versal_net_mini_ospi_defconfig
index 18ec7372258..aadfcfcf9db 100644
--- a/configs/xilinx_versal_net_mini_ospi_defconfig
+++ b/configs/xilinx_versal_net_mini_ospi_defconfig
@@ -30,6 +30,7 @@ CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_SYS_PROMPT="Versal NET> "
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_HELP is not set
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
@@ -53,6 +54,7 @@ CONFIG_SYS_PROMPT="Versal NET> "
# CONFIG_CMD_SETEXPR is not set
CONFIG_NO_NET=y
# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_SIMPLE_BUS is not set
# CONFIG_MMC is not set
CONFIG_MTD=y
CONFIG_DM_SPI_FLASH=y
diff --git a/configs/xilinx_versal_net_mini_qspi_defconfig b/configs/xilinx_versal_net_mini_qspi_defconfig
index 5241da6c63b..ed4c3893315 100644
--- a/configs/xilinx_versal_net_mini_qspi_defconfig
+++ b/configs/xilinx_versal_net_mini_qspi_defconfig
@@ -31,6 +31,7 @@ CONFIG_SYS_PROMPT="Versal NET> "
# CONFIG_SYS_XTRACE is not set
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_HELP is not set
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
@@ -55,6 +56,7 @@ CONFIG_SYS_PROMPT="Versal NET> "
# CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG is not set
CONFIG_NO_NET=y
# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_SIMPLE_BUS is not set
# CONFIG_GPIO is not set
# CONFIG_I2C is not set
# CONFIG_INPUT is not set
diff --git a/configs/xilinx_versal_net_virt_defconfig b/configs/xilinx_versal_net_virt_defconfig
index c9866deeaeb..c13bdb2e545 100644
--- a/configs/xilinx_versal_net_virt_defconfig
+++ b/configs/xilinx_versal_net_virt_defconfig
@@ -73,6 +73,7 @@ CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SIMPLE_PM_BUS=y
CONFIG_CLK_VERSAL=y
CONFIG_DFU_RAM=y
+CONFIG_ZYNQMP_FIRMWARE=y
CONFIG_ARM_FFA_TRANSPORT=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_VERSALPL=y
diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig
index 5dc43ba00fd..d8f4b884e76 100644
--- a/configs/xilinx_versal_virt_defconfig
+++ b/configs/xilinx_versal_virt_defconfig
@@ -81,6 +81,7 @@ CONFIG_DFU_MMC=y
CONFIG_DFU_RAM=y
CONFIG_DFU_SF=y
CONFIG_SYS_DFU_DATA_BUF_SIZE=0x1800000
+CONFIG_ZYNQMP_FIRMWARE=y
CONFIG_ARM_FFA_TRANSPORT=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_VERSALPL=y
diff --git a/configs/xilinx_zynqmp_kria_defconfig b/configs/xilinx_zynqmp_kria_defconfig
index 22ba8a7cc15..3e2ac614405 100644
--- a/configs/xilinx_zynqmp_kria_defconfig
+++ b/configs/xilinx_zynqmp_kria_defconfig
@@ -46,6 +46,7 @@ CONFIG_USE_PREBOOT=y
CONFIG_SYS_PBSIZE=2073
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_CLOCKS=y
+CONFIG_BOARD_RNG_SEED=y
CONFIG_SPL_MAX_SIZE=0x40000
# CONFIG_SPL_BINMAN_SYMBOLS is not set
# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
diff --git a/configs/xilinx_zynqmp_mini_defconfig b/configs/xilinx_zynqmp_mini_defconfig
index 736d4bd4efc..f164580c501 100644
--- a/configs/xilinx_zynqmp_mini_defconfig
+++ b/configs/xilinx_zynqmp_mini_defconfig
@@ -26,6 +26,7 @@ CONFIG_CLOCKS=y
# CONFIG_SYS_LONGHELP is not set
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_HELP is not set
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
@@ -56,6 +57,7 @@ CONFIG_OF_EMBED=y
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_NO_NET=y
# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_SIMPLE_BUS is not set
# CONFIG_DM_MAILBOX is not set
# CONFIG_MMC is not set
CONFIG_ARM_DCC=y
diff --git a/configs/xilinx_zynqmp_mini_emmc0_defconfig b/configs/xilinx_zynqmp_mini_emmc0_defconfig
index 85a6af45c57..8a8a9b0b463 100644
--- a/configs/xilinx_zynqmp_mini_emmc0_defconfig
+++ b/configs/xilinx_zynqmp_mini_emmc0_defconfig
@@ -40,6 +40,7 @@ CONFIG_SPL_SYS_MALLOC_SIZE=0x1000000
# CONFIG_AUTO_COMPLETE is not set
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_HELP is not set
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
@@ -71,6 +72,7 @@ CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_NO_NET=y
# CONFIG_DM_DEVICE_REMOVE is not set
CONFIG_SPL_DM_SEQ_ALIAS=y
+# CONFIG_SIMPLE_BUS is not set
# CONFIG_DM_MAILBOX is not set
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_MMC_SDHCI=y
diff --git a/configs/xilinx_zynqmp_mini_emmc1_defconfig b/configs/xilinx_zynqmp_mini_emmc1_defconfig
index 4c01a43b6e4..3fc4f2f9b86 100644
--- a/configs/xilinx_zynqmp_mini_emmc1_defconfig
+++ b/configs/xilinx_zynqmp_mini_emmc1_defconfig
@@ -40,6 +40,7 @@ CONFIG_SPL_SYS_MALLOC_SIZE=0x1000000
# CONFIG_AUTO_COMPLETE is not set
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_HELP is not set
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
@@ -71,6 +72,7 @@ CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_NO_NET=y
# CONFIG_DM_DEVICE_REMOVE is not set
CONFIG_SPL_DM_SEQ_ALIAS=y
+# CONFIG_SIMPLE_BUS is not set
# CONFIG_DM_MAILBOX is not set
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_MMC_SDHCI=y
diff --git a/configs/xilinx_zynqmp_mini_nand_defconfig b/configs/xilinx_zynqmp_mini_nand_defconfig
index afb50a9ff43..cfcb4321b1f 100644
--- a/configs/xilinx_zynqmp_mini_nand_defconfig
+++ b/configs/xilinx_zynqmp_mini_nand_defconfig
@@ -27,6 +27,7 @@ CONFIG_CLOCKS=y
# CONFIG_SYS_LONGHELP is not set
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_HELP is not set
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
@@ -51,6 +52,7 @@ CONFIG_OF_EMBED=y
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_NO_NET=y
# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_SIMPLE_BUS is not set
# CONFIG_DM_MAILBOX is not set
# CONFIG_MMC is not set
CONFIG_DM_MTD=y
diff --git a/configs/xilinx_zynqmp_mini_nand_single_defconfig b/configs/xilinx_zynqmp_mini_nand_single_defconfig
index a40a4493d5d..9af0b717ba9 100644
--- a/configs/xilinx_zynqmp_mini_nand_single_defconfig
+++ b/configs/xilinx_zynqmp_mini_nand_single_defconfig
@@ -27,6 +27,7 @@ CONFIG_CLOCKS=y
# CONFIG_SYS_LONGHELP is not set
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_HELP is not set
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
@@ -51,6 +52,7 @@ CONFIG_OF_EMBED=y
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_NO_NET=y
# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_SIMPLE_BUS is not set
# CONFIG_DM_MAILBOX is not set
# CONFIG_MMC is not set
CONFIG_DM_MTD=y
diff --git a/configs/xilinx_zynqmp_mini_qspi_defconfig b/configs/xilinx_zynqmp_mini_qspi_defconfig
index 0367c043574..3f2d44d038e 100644
--- a/configs/xilinx_zynqmp_mini_qspi_defconfig
+++ b/configs/xilinx_zynqmp_mini_qspi_defconfig
@@ -43,6 +43,7 @@ CONFIG_SPL_SYS_MALLOC_SIZE=0x1000000
# CONFIG_SYS_LONGHELP is not set
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_HELP is not set
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
@@ -73,6 +74,7 @@ CONFIG_ENV_RELOC_GD_ENV_ADDR=y
CONFIG_NO_NET=y
# CONFIG_DM_DEVICE_REMOVE is not set
CONFIG_SPL_DM_SEQ_ALIAS=y
+# CONFIG_SIMPLE_BUS is not set
# CONFIG_FIRMWARE is not set
# CONFIG_GPIO is not set
# CONFIG_I2C is not set
diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig
index a0067793a41..65c8a4bbaad 100644
--- a/configs/xilinx_zynqmp_virt_defconfig
+++ b/configs/xilinx_zynqmp_virt_defconfig
@@ -163,7 +163,6 @@ CONFIG_MTD_RAW_NAND=y
CONFIG_NAND_ARASAN=y
CONFIG_SYS_NAND_ONFI_DETECTION=y
CONFIG_SYS_NAND_MAX_CHIPS=2
-CONFIG_SPI_FLASH_BAR=y
CONFIG_SPI_FLASH_GIGADEVICE=y
CONFIG_SPI_FLASH_ISSI=y
CONFIG_SPI_FLASH_MACRONIX=y
@@ -182,6 +181,7 @@ CONFIG_PHY_NATSEMI=y
CONFIG_PHY_REALTEK=y
CONFIG_PHY_TI_DP83867=y
CONFIG_PHY_VITESSE=y
+CONFIG_PHY_XILINX=y
CONFIG_PHY_XILINX_GMII2RGMII=y
CONFIG_PHY_FIXED=y
CONFIG_DM_ETH_PHY=y
diff --git a/configs/yuzukihd-chameleon_defconfig b/configs/yuzukihd-chameleon_defconfig
new file mode 100644
index 00000000000..6cefcb77a28
--- /dev/null
+++ b/configs/yuzukihd-chameleon_defconfig
@@ -0,0 +1,29 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_DEFAULT_DEVICE_TREE="allwinner/sun50i-h618-yuzukihd-chameleon"
+CONFIG_SPL=y
+CONFIG_DRAM_SUNXI_DX_ODT=0x03030303
+CONFIG_DRAM_SUNXI_DX_DRI=0x0e0e0e0e
+CONFIG_DRAM_SUNXI_CA_DRI=0x1c12
+CONFIG_DRAM_SUNXI_TPR6=0x33808080
+CONFIG_DRAM_SUNXI_TPR10=0x002f0006
+CONFIG_DRAM_SUNXI_TPR11=0xddddcccc
+CONFIG_DRAM_SUNXI_TPR12=0xeddc7564
+CONFIG_MACH_SUN50I_H616=y
+CONFIG_SUNXI_DRAM_H616_DDR3_1333=y
+CONFIG_DRAM_CLK=648
+CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+CONFIG_R_I2C_ENABLE=y
+CONFIG_SPL_SPI_SUNXI=y
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL_I2C=y
+CONFIG_SPL_SYS_I2C_LEGACY=y
+CONFIG_SYS_I2C_MVTWSI=y
+CONFIG_SYS_I2C_SLAVE=0x7f
+CONFIG_SYS_I2C_SPEED=400000
+CONFIG_SUPPORT_EMMC_BOOT=y
+CONFIG_AXP313_POWER=y
+CONFIG_AXP_DCDC3_VOLT=1500
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_MUSB_GADGET=y
diff --git a/disk/part_efi.c b/disk/part_efi.c
index 68ba1d11e7b..fb1ed534f86 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -215,6 +215,34 @@ int get_disk_guid(struct blk_desc *desc, char *guid)
return 0;
}
+int part_get_gpt_pte(struct blk_desc *desc, int part, gpt_entry *gpt_e)
+{
+ ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, desc->blksz);
+ gpt_entry *gpt_pte = NULL;
+
+ /* "part" argument must be at least 1 */
+ if (part < 1) {
+ log_debug("Invalid Argument(s)\n");
+ return -EINVAL;
+ }
+
+ /* This function validates AND fills in the GPT header and PTE */
+ if (find_valid_gpt(desc, gpt_head, &gpt_pte) != 1)
+ return -EINVAL;
+
+ if (part > le32_to_cpu(gpt_head->num_partition_entries) ||
+ !is_pte_valid(&gpt_pte[part - 1])) {
+ log_debug("Invalid partition number %d\n", part);
+ free(gpt_pte);
+ return -EPERM;
+ }
+
+ memcpy(gpt_e, &gpt_pte[part - 1], sizeof(*gpt_e));
+
+ free(gpt_pte);
+ return 0;
+}
+
static void __maybe_unused part_print_efi(struct blk_desc *desc)
{
ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, desc->blksz);
@@ -260,45 +288,32 @@ static void __maybe_unused part_print_efi(struct blk_desc *desc)
static int __maybe_unused part_get_info_efi(struct blk_desc *desc, int part,
struct disk_partition *info)
{
- ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, desc->blksz);
- gpt_entry *gpt_pte = NULL;
-
- /* "part" argument must be at least 1 */
- if (part < 1) {
- log_debug("Invalid Argument(s)\n");
- return -EINVAL;
- }
-
- /* This function validates AND fills in the GPT header and PTE */
- if (find_valid_gpt(desc, gpt_head, &gpt_pte) != 1)
- return -EINVAL;
+ gpt_entry gpt_pte = {};
+ int ret;
- if (part > le32_to_cpu(gpt_head->num_partition_entries) ||
- !is_pte_valid(&gpt_pte[part - 1])) {
- log_debug("Invalid partition number %d\n", part);
- free(gpt_pte);
- return -EPERM;
- }
+ ret = part_get_gpt_pte(desc, part, &gpt_pte);
+ if (ret)
+ return ret;
/* The 'lbaint_t' casting may limit the maximum disk size to 2 TB */
- info->start = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].starting_lba);
+ info->start = (lbaint_t)le64_to_cpu(gpt_pte.starting_lba);
/* The ending LBA is inclusive, to calculate size, add 1 to it */
- info->size = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1
+ info->size = (lbaint_t)le64_to_cpu(gpt_pte.ending_lba) + 1
- info->start;
info->blksz = desc->blksz;
snprintf((char *)info->name, sizeof(info->name), "%s",
- print_efiname(&gpt_pte[part - 1]));
+ print_efiname(&gpt_pte));
strcpy((char *)info->type, "U-Boot");
- info->bootable = get_bootable(&gpt_pte[part - 1]);
- info->type_flags = gpt_pte[part - 1].attributes.fields.type_guid_specific;
+ info->bootable = get_bootable(&gpt_pte);
+ info->type_flags = gpt_pte.attributes.fields.type_guid_specific;
if (CONFIG_IS_ENABLED(PARTITION_UUIDS)) {
- uuid_bin_to_str(gpt_pte[part - 1].unique_partition_guid.b,
+ uuid_bin_to_str(gpt_pte.unique_partition_guid.b,
(char *)disk_partition_uuid(info),
UUID_STR_FORMAT_GUID);
}
if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID)) {
- uuid_bin_to_str(gpt_pte[part - 1].partition_type_guid.b,
+ uuid_bin_to_str(gpt_pte.partition_type_guid.b,
(char *)disk_partition_type_guid(info),
UUID_STR_FORMAT_GUID);
}
@@ -306,8 +321,6 @@ static int __maybe_unused part_get_info_efi(struct blk_desc *desc, int part,
log_debug("start 0x" LBAF ", size 0x" LBAF ", name %s\n", info->start,
info->size, info->name);
- /* Remember to free pte */
- free(gpt_pte);
return 0;
}
diff --git a/doc/README.SNTP b/doc/README.SNTP
deleted file mode 100644
index da9ec459ad4..00000000000
--- a/doc/README.SNTP
+++ /dev/null
@@ -1,17 +0,0 @@
-To use SNTP support, add define CONFIG_CMD_SNTP to the
-configuration file of the board.
-
-The "sntp" command gets network time from NTP time server and
-syncronize RTC of the board. This command needs the command line
-parameter of server's IP address or environment variable
-"ntpserverip". The network time is sent as UTC. So if you want to
-set local time to RTC, set the offset in second from UTC to the
-environment variable "time offset".
-
-If the DHCP server provides time server's IP or time offset, you
-don't need to set the above environment variables yourself.
-
-Current limitations of SNTP support:
-1. The roundtrip time is ignored.
-2. Only the 1st NTP server IP, in the option ntp-servers of DHCP, will
- be used.
diff --git a/doc/README.pxe b/doc/README.pxe
index 9fff2cd5ae9..ba189080e8c 100644
--- a/doc/README.pxe
+++ b/doc/README.pxe
@@ -178,7 +178,8 @@ devicetree-overlay <path> [...] - if this label is chosen, use tftp to retrieve
kaslrseed - set this label to request random number from hwrng as kaslr seed.
append <string> - use <string> as the kernel command line when booting this
- label.
+ label. Environment variable references like ${var} are
+ substituted before boot.
initrd <path> - if this label is chosen, use tftp to retrieve the initrd
at <path>. it will be stored at the address indicated in
diff --git a/doc/api/index.rst b/doc/api/index.rst
index 506843ed74a..cf9d21e4c1c 100644
--- a/doc/api/index.rst
+++ b/doc/api/index.rst
@@ -17,7 +17,6 @@ U-Boot API documentation
interrupt
led
linker_lists
- lmb
logging
nvmem
part
diff --git a/doc/api/linker_lists.rst b/doc/api/linker_lists.rst
index 3cd447f187d..9e6849d5e75 100644
--- a/doc/api/linker_lists.rst
+++ b/doc/api/linker_lists.rst
@@ -130,17 +130,17 @@ the compiler cannot update the alignment of the linker_list item.
In the first case, an 8-byte 'fill' region is added::
__u_boot_list_2_driver_2_testbus_drv
- 0x0000000000270018 0x80 test/built-in.o
+ 0x0000000000270018 0x80 test/built-in.a
0x0000000000270018 _u_boot_list_2_driver_2_testbus_drv
__u_boot_list_2_driver_2_testfdt1_drv
- 0x0000000000270098 0x80 test/built-in.o
+ 0x0000000000270098 0x80 test/built-in.a
0x0000000000270098 _u_boot_list_2_driver_2_testfdt1_drv
*fill* 0x0000000000270118 0x8
__u_boot_list_2_driver_2_testfdt_drv
- 0x0000000000270120 0x80 test/built-in.o
+ 0x0000000000270120 0x80 test/built-in.a
0x0000000000270120 _u_boot_list_2_driver_2_testfdt_drv
__u_boot_list_2_driver_2_testprobe_drv
- 0x00000000002701a0 0x80 test/built-in.o
+ 0x00000000002701a0 0x80 test/built-in.a
0x00000000002701a0 _u_boot_list_2_driver_2_testprobe_drv
With this, the linker_list no-longer works since items after testfdt1_drv
diff --git a/doc/api/lmb.rst b/doc/api/lmb.rst
deleted file mode 100644
index 2095bfa1618..00000000000
--- a/doc/api/lmb.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0+
-
-Logical memory blocks
-=====================
-
-.. kernel-doc:: include/lmb.h
- :internal:
diff --git a/doc/board/qualcomm/board.rst b/doc/board/qualcomm/board.rst
index 003d59a18eb..642c5095261 100644
--- a/doc/board/qualcomm/board.rst
+++ b/doc/board/qualcomm/board.rst
@@ -23,10 +23,7 @@ Installation
------------
Build
^^^^^
-
- $ ./tools/buildman/buildman -o .output qcom
-
-This will build ``.output/u-boot-nodtb.bin`` using the ``qcom_defconfig``.
+We will build ``u-boot-nodtb.bin`` from the u-boot source tree.
Generate FIT image (optional)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -81,19 +78,20 @@ Steps:
- Build u-boot
-As above::
+Use the following commands::
- ./tools/buildman/buildman -o .output qcom
+ make CROSS_COMPILE=aarch64-linux-gnu- O=.output qcom_defconfig
+ make CROSS_COMPILE=aarch64-linux-gnu- O=.output -j$(nproc)
Or for db410c (and other boards not supported by the generic target)::
make CROSS_COMPILE=aarch64-linux-gnu- O=.output dragonboard410c_defconfig
- make O=.output -j$(nproc)
+ make CROSS_COMPILE=aarch64-linux-gnu- O=.output -j$(nproc)
Or for smartphones::
make CROSS_COMPILE=aarch64-linux-gnu- O=.output qcom_defconfig qcom-phone.config
- make O=.output -j$(nproc)
+ make CROSS_COMPILE=aarch64-linux-gnu- O=.output -j$(nproc)
- gzip u-boot::
@@ -119,6 +117,13 @@ Or with no FIT image::
mkbootimg --kernel u-boot-nodtb.bin.gz-dtb \
--output boot.img --pagesize 4096 --base 0x80000000
+Other devices with boot image version 2 can be built like this example::
+
+ mkbootimg --pagesize 4096 --header_version 2 \
+ --kernel_offset 0x00008000 --kernel u-boot-nodtb.bin.gz \
+ --dtb_offset 0x01f00000 --dtb dts/upstream/src/arm64/qcom/qcm6490-fairphone-fp5.dtb \
+ --output boot.img
+
- Flash boot.img using fastboot and erase dtbo to avoid conflicts with our DTB:
.. code-block:: bash
diff --git a/doc/board/qualcomm/dragonwing.rst b/doc/board/qualcomm/dragonwing.rst
new file mode 100644
index 00000000000..d4899415309
--- /dev/null
+++ b/doc/board/qualcomm/dragonwing.rst
@@ -0,0 +1,49 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. sectionauthor:: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
+
+Qualcomm DragonWing
+========================================
+
+Qualcomm DragonWing are industrial-grade boards that provides various series
+of processors such as IQ6 (QCS615), IQ8 (QCS8300) and IQ9 (QCS9100).
+These SoCs are used for factory/industry based applications.
+More information can be found on the `Qualcomm's IQ6 product page`_,
+`Qualcomm's IQ8 product page`_ and `Qualcomm's IQ9 product page`_.
+
+.. _Qualcomm's IQ6 product page: https://docs.qualcomm.com/bundle/publicresource/87-83838-1_REV_A_Qualcomm_IQ6_Series_Product_Brief.pdf
+.. _Qualcomm's IQ8 product page: https://docs.qualcomm.com/bundle/publicresource/87-83839-1_REV_A_Qualcomm_IQ8_Series_Product_Brief________.pdf
+.. _Qualcomm's IQ9 product page: https://docs.qualcomm.com/bundle/publicresource/87-83840-1_REV_A_Qualcomm_IQ9_Series_Product_Brief.pdf
+
+Installation
+------------
+First, setup ``CROSS_COMPILE`` for aarch64. Then, build U-Boot for ``QCS615``, ``QCS8300`` or ``QCS9100``::
+
+ $ export CROSS_COMPILE=<aarch64 toolchain prefix>
+ $ make qcom_qcs8300_defconfig
+ $ make -j8 u-boot.mbn
+
+Although the board does not have secure boot set up by default,
+the firmware still expects firmware ELF images to be "signed". The signature
+does not provide any security in this case, but it provides the firmware with
+some required metadata.
+
+To "sign" ``u-boot.elf`` you can use e.g. `qtestsign`_::
+
+ $ qtestsign -v6 aboot -o u-boot.mbn u-boot.elf
+
+Then flash the resulting ``u-boot.mbn`` to the ``uefi_a`` partition
+on your device with ``fastboot flash uefi_a u-boot.mbn``.
+
+U-Boot should be running after a reboot (``fastboot reboot``).
+
+Note that fastboot is not yet supported in U-Boot on Dragonwing boards, as a result, to flash
+back the original firmware, or new versoins of the U-Boot, EDL mode must be used.
+
+A tool like bkerler's `edl`_ can be used for flashing with the firehose loader (for example, for QCS9100
+the firehose loader can be obtained from `dragonwing IQ9 bootbinaries`.) ::
+
+$ edl.py --loader /path/to/prog_firehose_ddr.elf w uefi_a u-boot.mbn
+
+.. _qtestsign: https://github.com/msm8916-mainline/qtestsign
+.. _edl: https://github.com/bkerler/edl
+.. _dragonwing IQ9 bootbinaries: https://artifacts.codelinaro.org/ui/native/qli-ci/flashable-binaries/qimpsdk/qcs9075-rb8-core-kit
diff --git a/doc/board/qualcomm/index.rst b/doc/board/qualcomm/index.rst
index e2fcbfa19c2..ccf834208e9 100644
--- a/doc/board/qualcomm/index.rst
+++ b/doc/board/qualcomm/index.rst
@@ -8,6 +8,7 @@ Qualcomm
dragonboard410c
rb3gen2
+ dragonwing
board
phones
debugging
diff --git a/doc/board/qualcomm/rdp.rst b/doc/board/qualcomm/rdp.rst
index fd14f1d9829..99cf8eba57c 100644
--- a/doc/board/qualcomm/rdp.rst
+++ b/doc/board/qualcomm/rdp.rst
@@ -21,13 +21,16 @@ First, setup ``CROSS_COMPILE`` for aarch64. Then, build U-Boot for ``IPQ9574``::
This will build ``u-boot.elf`` in the configured output directory.
-Although the RDPs do not have secure boot set up by default, the firmware still
-expects firmware ELF images to be "signed". The signature does not provide any
-security in this case, but it provides the firmware with some required metadata.
+The firmware expects the ELF images to be in MBN format. The `elftombn.py` tool
+can be used to convert the ELF images to MBN format.
-To "sign" ``u-boot.elf`` you can use e.g. `qtestsign`_::
+ IPQ9574: (MBN version 6)
- $ qtestsign -v6 aboot -o u-boot.mbn u-boot.elf
+ $ python elftombn.py -f u-boot.elf -o u-boot.mbn -v6
+
+ IPQ5424: (MBN version 7)
+
+ $ python elftombn.py -f u-boot.elf -o u-boot.mbn -v7
Then install the resulting ``u-boot.mbn`` to the ``0:APPSBL`` partition
on your device with::
@@ -51,5 +54,5 @@ U-Boot should be running after a reboot (``reset``).
Note that the support added is very basic. Restoring the original U-Boot
on boards with older version of the software requires a debugger.
-.. _qtestsign: https://github.com/msm8916-mainline/qtestsign
+.. _elftombn.py: https://git.codelinaro.org/clo/qsdk/oss/system/tools/meta/-/tree/NHSS.QSDK.13.0.5.r2/scripts?ref_type=heads
.. _edl: https://github.com/bkerler/edl
diff --git a/doc/develop/crash_dumps.rst b/doc/develop/crash_dumps.rst
index 4237b073bc9..c84b85b3364 100644
--- a/doc/develop/crash_dumps.rst
+++ b/doc/develop/crash_dumps.rst
@@ -89,15 +89,15 @@ File u-boot.map contains the memory layout of the U-Boot binary. Here we find
these lines::
.text.do_undefined
- 0x00000000000101fc 0xc cmd/built-in.o
+ 0x00000000000101fc 0xc cmd/built-in.a
.text.exception_complete
- 0x0000000000010208 0x90 cmd/built-in.o
+ 0x0000000000010208 0x90 cmd/built-in.a
...
.text.cmd_process
- 0x00000000000213b8 0x164 common/built-in.o
+ 0x00000000000213b8 0x164 common/built-in.a
0x00000000000213b8 cmd_process
.text.cmd_process_error
- 0x000000000002151c 0x40 common/built-in.o
+ 0x000000000002151c 0x40 common/built-in.a
0x000000000002151c cmd_process_error
So the error occurred at the start of function do\_undefined() and this
diff --git a/doc/develop/distro.rst b/doc/develop/distro.rst
index 1d2f9c4c32b..01efce40a29 100644
--- a/doc/develop/distro.rst
+++ b/doc/develop/distro.rst
@@ -92,6 +92,13 @@ That said, we have some differences to these documents, namely:
* If ``-`` is passed as fdt argument and ``CONFIG_SUPPORT_PASSING_ATAGS`` is
enabled, then no device tree will be used (legacy booting / pre-dtb kernel).
+* The ``append`` string may use environment variables. For example, an
+ A/B boot setup could use ``append root=PARTLABEL=root_${bootslot}``
+ to set the root filesystem to the right one for the selected slot,
+ assuming the ``bootslot`` environment variable is set before the
+ extlinux.conf file is processed, and the partition is labeled to
+ match.
+
See also doc/README.pxe under 'pxe file format'.
One example extlinux.conf generated by the Fedora installer is::
diff --git a/doc/develop/index.rst b/doc/develop/index.rst
index 0c83ef109ab..3c044e67927 100644
--- a/doc/develop/index.rst
+++ b/doc/develop/index.rst
@@ -46,6 +46,7 @@ Implementation
cedit
event
global_data
+ lmb
logging
makefiles
menus
diff --git a/doc/develop/lmb.rst b/doc/develop/lmb.rst
new file mode 100644
index 00000000000..b9d0f09c2bb
--- /dev/null
+++ b/doc/develop/lmb.rst
@@ -0,0 +1,166 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Logical Memory Blocks (LMB)
+===========================
+
+U-Boot has support for reserving chunks of memory which is primarily
+used for loading images to the DRAM memory, before these are booted,
+or written to non-volatile storage medium. This functionality is
+provided through the Logical Memory Blocks (LMB) module.
+
+Introduction
+------------
+
+The LMB module manages allocation requests for memory region not
+occupied by the U-Boot image. Allocation requests that are made
+through malloc() and similar functions result in memory getting
+allocated from the heap region, which is part of the U-Boot
+image. Typically, the heap memory is a few MiB in size. Loading an
+image like the linux kernel might require lot more memory than what
+the heap can provide. Such allocations are usually handled through the
+LMB module.
+
+The U-Boot image typically gets relocated to the top of the usable
+DRAM memory region. A typical memory layout looks as follows::
+
+
+
+
+
+ | |
+ | |
+ | |
+ | |
+ | |
+ --- +--------------+ <--- U-Boot ram top
+ | | |
+ | | Text |
+ | +--------------+
+ | | |
+ | | Data |
+ | +--------------+
+ | | |
+ | | BSS |
+ U-Boot Image +--------------+
+ | | |
+ | | Heap |
+ | | |
+ | +--------------+
+ | | |
+ | | |
+ | | Stack |
+ | | |
+ | | |
+ --- +--------------+
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +--------------+ <--- ram start
+
+
+
+The region of memory below the U-Boot image is the one controlled by
+the LMB module.
+
+
+Types of LMB Allocations
+------------------------
+
+There are two classes of allocation requests that get made to the LMB
+module. One type of allocation requests are requesting memory of a
+particular number of bytes. This type of allocation is similar to that
+done using the malloc type of function calls. The other type of
+allocations, are requests made for a specific memory address. The
+second type of allocations are usually made for loading images to a
+particular memory address.
+
+
+LMB design Pre 2025.01
+----------------------
+
+The earlier versions of U-Boot (pre 2025.01 release)
+had a local memory map based LMB implementation whereby it was
+possible to declare the LMB map inside a function or a C file. This
+design resulted in temporary, non-global LMB maps, which also allowed
+for re-use of memory. This meant that it was possible to use a region
+of memory to load some image, and subsequently the same region of
+memory could be used for loading a different image. A typical example
+of this usage would be loading an image to a memory address, followed
+by writing that image to some non-volatile storage medium. Once this
+is done, the same address can be used for loading a different image
+and then writing it to it's non-volatile storage
+destination. Typically, environment variables like `loadaddr`,
+`kernel_addr_r`, `ramdisk_addr_r` are used for loading images to
+memory regions.
+
+
+Current LMB implementation
+--------------------------
+
+Changes were made in the 2025.01 release to make the LMB memory map
+global and persistent. With this, the LMB memory map is the same
+across all of U-Boot, and also persists as long as U-Boot is
+active. Even with this change, there has been consistency as far as
+re-use of memory is concerned to maintain backward compatibility. It
+is allowed for re-requesting the same region of memory if the memory
+region has a particular attribute (LMB_NONE).
+
+As part of the platform boot, DRAM memory available for use in U-Boot
+gets added to the LMB memory map. Any allocation requests made
+subsequently will be made from this memory added as part of the board
+init.
+
+
+Allocation API
+--------------
+
+Any request for non-heap memory can be made through the LMB allocation
+API.
+
+.. code-block:: c
+
+ int lmb_alloc_mem(enum lmb_mem_type type, u64 align,
+ phys_addr_t *addr, phys_size_t size,
+ u32 flags);
+
+Correspondingly, the allocated memory can be free'd
+
+.. code-block:: c
+
+ long lmb_free(phys_addr_t base, phys_size_t size, u32 flags);
+
+For a detailed API description, please refer to the header file.
+
+
+UEFI allocations with LMB as the backend
+----------------------------------------
+
+The UEFI specification describes boot-time API's for allocation of
+memory. These API's use the same memory that is being used by the LMB
+module. Pre 2025.01 release, there wasn't any synchronisation between
+the EFI sub-system and the LMB module about the memory that was
+getting allocated by each of these modules. This was the primary
+reason for making the LMB memory map global and persistent. With this
+change, the EFI memory allocation API's have also been changed to use
+the LMB module as the backend for the allocation requests. Any other
+sub-system which might wish to use the same memory region for it's use
+can then use the LMB as the backend for the memory allocations and
+it's associated book-keeping.
+
+
+API documentation
+-----------------
+
+.. kernel-doc:: include/lmb.h
+
diff --git a/doc/develop/release_cycle.rst b/doc/develop/release_cycle.rst
index fee7cca2628..f2ffcf3d331 100644
--- a/doc/develop/release_cycle.rst
+++ b/doc/develop/release_cycle.rst
@@ -1,4 +1,4 @@
-.. |next_ver| replace:: v2025.07
+.. |next_ver| replace:: v2025.10
Release Cycle
=============
@@ -53,15 +53,15 @@ Examples::
Current Status
--------------
-* U-Boot v2025.04 was released on Monday, 07 April 2025.
+* U-Boot v2025.07 was released on Monday, 07 July 2025.
-* The Merge Window for the next release (|next_ver|) was **closed** with the -rc1
- release on Monday, 28 April 2025.
+* The Merge Window for the next release (|next_ver|) is **open** until the -rc1
+ release on Monday, 28 July 2025.
-* The next branch is now **closed** until the -rc2 release on Monday, 12 May
+* The next branch is now **closed** until the -rc2 release on Monday, 11 August
2025.
-* Release "|next_ver|" is scheduled for Monday, 07 July 2025.
+* Release "|next_ver|" is scheduled for Monday, 06 October 2025.
Future Releases
---------------
@@ -69,28 +69,28 @@ Future Releases
.. The following commented out dates are for when release candidates are
planned to be tagged.
-For the next scheduled release, release candidates were made on::
+.. For the next scheduled release, release candidates were made on::
-* U-Boot |next_ver|-rc1 was released on Mon 28 April 2025.
+.. * U-Boot |next_ver|-rc1 was released on Mon 28 July 2025.
-* U-Boot |next_ver|-rc2 was released on Mon 12 May 2025.
+.. * U-Boot |next_ver|-rc2 was released on Mon 11 August 2025.
-* U-Boot |next_ver|-rc3 was released on Mon 26 May 2025.
+.. * U-Boot |next_ver|-rc3 was released on Mon 25 August 2025.
-* U-Boot |next_ver|-rc4 was released on Mon 09 June 2025.
+.. * U-Boot |next_ver|-rc4 was released on Mon 08 September 2025.
-.. * U-Boot |next_ver|-rc5 was released on Mon 23 June 2025.
+.. * U-Boot |next_ver|-rc5 was released on Mon 22 September 2025.
Please note that the following dates are planned only and may be deviated from
as needed.
-* "v2025.07": end of MW = Mon, Apr 28, 2025; release = Mon, Jul 07, 2025
-
* "v2025.10": end of MW = Mon, Jul 28, 2025; release = Mon, Oct 06, 2025
* "v2026.01": end of MW = Mon, Oct 27, 2025; release = Mon, Jan 05, 2026
-* "v2025.04": end of MW = Mon, Jan 26, 2026; release = Mon, Apr 06, 2026
+* "v2026.04": end of MW = Mon, Jan 26, 2026; release = Mon, Apr 06, 2026
+
+* "v2026.07": end of MW = Mon, Apr 27, 2026; release = Mon, Jul 06, 2026
Previous Releases
-----------------
@@ -99,6 +99,8 @@ Note: these statistics are generated by our fork of `gitdm
<https://source.denx.de/u-boot/gitdm>`_, which was originally created by
Jonathan Corbet.
+* :doc:`statistics/u-boot-stats-v2025.07` which was released on 07 July 2025.
+
* :doc:`statistics/u-boot-stats-v2025.04` which was released on 07 April 2025.
* :doc:`statistics/u-boot-stats-v2025.01` which was released on 06 January 2025.
diff --git a/doc/develop/statistics/u-boot-stats-v2025.07.rst b/doc/develop/statistics/u-boot-stats-v2025.07.rst
new file mode 100644
index 00000000000..32f7df393de
--- /dev/null
+++ b/doc/develop/statistics/u-boot-stats-v2025.07.rst
@@ -0,0 +1,990 @@
+:orphan:
+
+Release Statistics for U-Boot v2025.07
+======================================
+
+* Processed 1780 changesets from 225 developers
+
+* 24 employers found
+
+* A total of 200374 lines added, 64238 removed (delta 136136)
+
+.. table:: Developers with the most changesets
+ :widths: auto
+
+ ==================================== =====
+ Name Count
+ ==================================== =====
+ Simon Glass 172 (9.7%)
+ Svyatoslav Ryhel 117 (6.6%)
+ Marek Vasut 110 (6.2%)
+ Tom Rini 91 (5.1%)
+ Heinrich Schuchardt 68 (3.8%)
+ Jerome Forissier 52 (2.9%)
+ Jonas Karlman 49 (2.8%)
+ Andre Przywara 44 (2.5%)
+ Casey Connolly 37 (2.1%)
+ Patrice Chotard 32 (1.8%)
+ Yao Zi 29 (1.6%)
+ Stephan Gerhold 26 (1.5%)
+ Quentin Schulz 25 (1.4%)
+ Christian Marangi 22 (1.2%)
+ Adam Ford 22 (1.2%)
+ Alif Zakuan Yuslaimi 22 (1.2%)
+ Paul Barker 19 (1.1%)
+ Wadim Egorov 17 (1.0%)
+ Adriano Cordova 17 (1.0%)
+ Dinesh Maniyam 17 (1.0%)
+ Ilias Apalodimas 15 (0.8%)
+ Sam Edwards 15 (0.8%)
+ Venkatesh Yadav Abbarapu 14 (0.8%)
+ Varadarajan Narayanan 14 (0.8%)
+ Dario Binacchi 14 (0.8%)
+ Sughosh Ganu 14 (0.8%)
+ Daniel Schultz 14 (0.8%)
+ Miquel Raynal 14 (0.8%)
+ Alice Guo 13 (0.7%)
+ Michal Simek 13 (0.7%)
+ Siddharth Vadapalli 13 (0.7%)
+ Jiaxun Yang 13 (0.7%)
+ Patrick Delaunay 12 (0.7%)
+ Patrick Rudolph 12 (0.7%)
+ Neil Armstrong 12 (0.7%)
+ Paul HENRYS 12 (0.7%)
+ Judith Mendez 11 (0.6%)
+ Heiko Stuebner 11 (0.6%)
+ Tien Fong Chee 11 (0.6%)
+ Sam Day 11 (0.6%)
+ Vincent Stehlé 10 (0.6%)
+ Nishanth Menon 10 (0.6%)
+ Anshul Dalal 9 (0.5%)
+ Bryan Brattlof 9 (0.5%)
+ Alexander Graf 9 (0.5%)
+ Alexander Dahl 9 (0.5%)
+ Weijie Gao 8 (0.4%)
+ Minda Chen 8 (0.4%)
+ Santhosh Kumar K 8 (0.4%)
+ Peng Fan 7 (0.4%)
+ Raymond Mao 7 (0.4%)
+ Neha Malcom Francis 7 (0.4%)
+ Mayuresh Chitale 7 (0.4%)
+ Aristo Chen 7 (0.4%)
+ Jernej Skrabec 7 (0.4%)
+ Samuel Holland 7 (0.4%)
+ Tingting Meng 7 (0.4%)
+ Greg Malysa 7 (0.4%)
+ Nathan Barrett-Morrison 7 (0.4%)
+ Fabio Estevam 6 (0.3%)
+ E Shattow 6 (0.3%)
+ Tony Dinh 6 (0.3%)
+ Lukasz Czechowski 6 (0.3%)
+ Naresh Kumar Ravulapalli 6 (0.3%)
+ Michael Trimarchi 6 (0.3%)
+ Primoz Fiser 6 (0.3%)
+ Udit Kumar 6 (0.3%)
+ Prasad Kummari 6 (0.3%)
+ Harrison Mutai 6 (0.3%)
+ Hector Martin 6 (0.3%)
+ Huan Zhou 6 (0.3%)
+ Leonard Anderweit 6 (0.3%)
+ Manorit Chawdhry 6 (0.3%)
+ Gabriel Dalimonte 6 (0.3%)
+ Maks Mishin 6 (0.3%)
+ Manikandan Muralidharan 6 (0.3%)
+ Mattijs Korpershoek 5 (0.3%)
+ Justin Klaassen 5 (0.3%)
+ Andrew Davis 5 (0.3%)
+ Padmarao Begari 5 (0.3%)
+ Jonathan Currier 5 (0.3%)
+ Ye Li 5 (0.3%)
+ Bernhard Messerklinger 5 (0.3%)
+ Hrushikesh Salunke 5 (0.3%)
+ Jorge Ramirez-Ortiz 5 (0.3%)
+ Anurag Dutta 5 (0.3%)
+ Jeremy Compostella 5 (0.3%)
+ Harsha Vardhan V M 5 (0.3%)
+ Anton Moryakov 5 (0.3%)
+ Baocheng Su 5 (0.3%)
+ Hari Nagalla 5 (0.3%)
+ Mikhail Kshevetskiy 4 (0.2%)
+ Alper Nebi Yasak 4 (0.2%)
+ Aniket Limaye 4 (0.2%)
+ Cheick Traore 4 (0.2%)
+ Heiko Schocher 3 (0.2%)
+ Sumit Garg 3 (0.2%)
+ Alexey Minnekhanov 3 (0.2%)
+ Rui Miguel Silva 3 (0.2%)
+ Rasmus Villemoes 3 (0.2%)
+ Martin Schiller 3 (0.2%)
+ Keerthy 3 (0.2%)
+ Mike Looijmans 3 (0.2%)
+ Lionel Debieve 3 (0.2%)
+ Zixun LI 3 (0.2%)
+ Vitor Soares 3 (0.2%)
+ Liya Huang 3 (0.2%)
+ Evgeny Bachinin 3 (0.2%)
+ Sinthu Raja 3 (0.2%)
+ Marius Dinu 2 (0.1%)
+ Shiji Yang 2 (0.1%)
+ Kory Maincent 2 (0.1%)
+ Yang Xiwen 2 (0.1%)
+ Peter Robinson 2 (0.1%)
+ Benjamin ROBIN 2 (0.1%)
+ Michael Bode 2 (0.1%)
+ Alexander Sverdlin 2 (0.1%)
+ Benjamin Schneider 2 (0.1%)
+ Christoph Fritz 2 (0.1%)
+ Vaishnav Achath 2 (0.1%)
+ Pascal Zimmermann 2 (0.1%)
+ Andrew Halaney 2 (0.1%)
+ Takahiro Kuwano 2 (0.1%)
+ Walter Schweizer 2 (0.1%)
+ Pawel Kochanowski 2 (0.1%)
+ Emanuele Ghidoli 2 (0.1%)
+ Stefano Babic 2 (0.1%)
+ Elaine Zhang 2 (0.1%)
+ Steven Liu 2 (0.1%)
+ Xuhui Lin 2 (0.1%)
+ Chukun Pan 2 (0.1%)
+ Muhammad Hazim Izzat Zamri 2 (0.1%)
+ Josua Mayer 2 (0.1%)
+ Jesse Taube 2 (0.1%)
+ Artur Kowalski 2 (0.1%)
+ Jonathan Humphreys 2 (0.1%)
+ 牛 志宏 2 (0.1%)
+ Daniel Golle 2 (0.1%)
+ Nathan Morrisson 2 (0.1%)
+ Jim Liu 2 (0.1%)
+ Ernest Van Hoecke 2 (0.1%)
+ Jonas Schwöbel 2 (0.1%)
+ David Lechner 1 (0.1%)
+ Fiona Klute 1 (0.1%)
+ Duje Mihanović 1 (0.1%)
+ Akashdeep Kaur 1 (0.1%)
+ Baruch Siach 1 (0.1%)
+ Sam Protsenko 1 (0.1%)
+ Ivan Pang 1 (0.1%)
+ Jan Čermák 1 (0.1%)
+ Hiago De Franco 1 (0.1%)
+ Hugo Villeneuve 1 (0.1%)
+ Tim Harvey 1 (0.1%)
+ BehradElmi 1 (0.1%)
+ Wojciech Szamocki 1 (0.1%)
+ Martin Kaistra 1 (0.1%)
+ Frantisek Bohacek 1 (0.1%)
+ Eddie Kovsky 1 (0.1%)
+ Jayanth Dodderi Chidanand 1 (0.1%)
+ Olaf Baehring 1 (0.1%)
+ Simon Holesch 1 (0.1%)
+ Thomas Schaefer 1 (0.1%)
+ Michael Walle 1 (0.1%)
+ No generic patch CC mail please 1 (0.1%)
+ Nikunj Kela 1 (0.1%)
+ Naresh Solanki 1 (0.1%)
+ Andy Shevchenko 1 (0.1%)
+ Jiehui He 1 (0.1%)
+ Ilya Katsnelson 1 (0.1%)
+ Prasanth Babu Mantena 1 (0.1%)
+ Chen-Yu Tsai 1 (0.1%)
+ Ben Wolsieffer 1 (0.1%)
+ ZhiJie.zhang 1 (0.1%)
+ Christophe Roullier 1 (0.1%)
+ Alexander Vickberg 1 (0.1%)
+ Carlos López 1 (0.1%)
+ Christoph Niedermaier 1 (0.1%)
+ Boon Khai Ng 1 (0.1%)
+ Bhavya Kapoor 1 (0.1%)
+ Love Kumar 1 (0.1%)
+ Nicolas Frattaroli 1 (0.1%)
+ Lin Jinhan 1 (0.1%)
+ Joseph Chen 1 (0.1%)
+ Yifeng Zhao 1 (0.1%)
+ Sean Edmond 1 (0.1%)
+ Mathieu Othacehe 1 (0.1%)
+ Jean-Jacques Hiblot 1 (0.1%)
+ Ezra Buehler 1 (0.1%)
+ Parth Pancholi 1 (0.1%)
+ Lucien.Jheng 1 (0.1%)
+ Mauro Salvini 1 (0.1%)
+ Bruno Leite 1 (0.1%)
+ Chris Packham 1 (0.1%)
+ yan wang 1 (0.1%)
+ Parvathi Pudi 1 (0.1%)
+ Martin Schwan 1 (0.1%)
+ Viorel Suman 1 (0.1%)
+ Rafael Beims 1 (0.1%)
+ Christian Kohlschütter 1 (0.1%)
+ Luke Wang 1 (0.1%)
+ Xu Zhang 1 (0.1%)
+ Andreas Dannenberg 1 (0.1%)
+ Andrew Goodbody 1 (0.1%)
+ Gary Bisson 1 (0.1%)
+ Oskar Nilsson 1 (0.1%)
+ Sukrut Bellary 1 (0.1%)
+ Richard Genoud 1 (0.1%)
+ Gowtham Tammana 1 (0.1%)
+ Vishal Mahaveer 1 (0.1%)
+ Masahisa Kojima 1 (0.1%)
+ Jimmy Ho 1 (0.1%)
+ Junhui Liu 1 (0.1%)
+ Baltazár Radics 1 (0.1%)
+ Arseniy Krasnov 1 (0.1%)
+ Robert Nelson 1 (0.1%)
+ Dragan Simic 1 (0.1%)
+ Vignesh Raghavendra 1 (0.1%)
+ Linus Walleij 1 (0.1%)
+ J. Neuschäfer 1 (0.1%)
+ Alexander Stein 1 (0.1%)
+ Stefan Eichenberger 1 (0.1%)
+ Michael Chang 1 (0.1%)
+ Hironori KIKUCHI 1 (0.1%)
+ Tomas Peterka 1 (0.1%)
+ Balamanikandan Gunasundar 1 (0.1%)
+ ==================================== =====
+
+
+.. table:: Developers with the most changed lines
+ :widths: auto
+
+ ==================================== =====
+ Name Count
+ ==================================== =====
+ Tom Rini 78284 (33.7%)
+ Patrice Chotard 20809 (9.0%)
+ Manorit Chawdhry 17813 (7.7%)
+ Svyatoslav Ryhel 16864 (7.3%)
+ Simon Glass 8757 (3.8%)
+ Marek Vasut 8650 (3.7%)
+ Robert Nelson 5921 (2.6%)
+ Vitor Soares 4567 (2.0%)
+ Bernhard Messerklinger 3955 (1.7%)
+ Elaine Zhang 3663 (1.6%)
+ Yao Zi 3317 (1.4%)
+ Dinesh Maniyam 3269 (1.4%)
+ Jonas Karlman 3191 (1.4%)
+ Christian Marangi 3131 (1.3%)
+ Jerome Forissier 2676 (1.2%)
+ Joseph Chen 2480 (1.1%)
+ Nathan Barrett-Morrison 2115 (0.9%)
+ Tingting Meng 2075 (0.9%)
+ Peng Fan 1544 (0.7%)
+ Dario Binacchi 1387 (0.6%)
+ Varadarajan Narayanan 1338 (0.6%)
+ Miquel Raynal 1244 (0.5%)
+ Jesse Taube 1242 (0.5%)
+ Gabriel Dalimonte 1162 (0.5%)
+ Heiko Stuebner 1114 (0.5%)
+ Adriano Cordova 1013 (0.4%)
+ Tien Fong Chee 987 (0.4%)
+ Ye Li 982 (0.4%)
+ Heinrich Schuchardt 981 (0.4%)
+ Patrick Delaunay 944 (0.4%)
+ Andre Przywara 912 (0.4%)
+ Alice Guo 906 (0.4%)
+ Greg Malysa 875 (0.4%)
+ Paul HENRYS 823 (0.4%)
+ Lucien.Jheng 818 (0.4%)
+ Casey Connolly 780 (0.3%)
+ Neil Armstrong 745 (0.3%)
+ Manikandan Muralidharan 737 (0.3%)
+ Huan Zhou 722 (0.3%)
+ Paul Barker 686 (0.3%)
+ Minda Chen 667 (0.3%)
+ Fabio Estevam 598 (0.3%)
+ Nishanth Menon 574 (0.2%)
+ Steven Liu 556 (0.2%)
+ Alexander Graf 511 (0.2%)
+ Lionel Debieve 501 (0.2%)
+ Ilias Apalodimas 486 (0.2%)
+ Xuhui Lin 476 (0.2%)
+ Sughosh Ganu 473 (0.2%)
+ Andrew Davis 461 (0.2%)
+ Jiaxun Yang 449 (0.2%)
+ Neha Malcom Francis 437 (0.2%)
+ Jernej Skrabec 431 (0.2%)
+ Baocheng Su 424 (0.2%)
+ Wadim Egorov 421 (0.2%)
+ Alif Zakuan Yuslaimi 416 (0.2%)
+ Prasad Kummari 404 (0.2%)
+ Hari Nagalla 402 (0.2%)
+ Cheick Traore 391 (0.2%)
+ Simon Holesch 388 (0.2%)
+ Samuel Holland 337 (0.1%)
+ Hector Martin 334 (0.1%)
+ Harsha Vardhan V M 326 (0.1%)
+ Jonas Schwöbel 302 (0.1%)
+ Alexey Minnekhanov 290 (0.1%)
+ Primoz Fiser 266 (0.1%)
+ Alexander Dahl 256 (0.1%)
+ Siddharth Vadapalli 248 (0.1%)
+ Michael Trimarchi 217 (0.1%)
+ Alper Nebi Yasak 210 (0.1%)
+ Stephan Gerhold 204 (0.1%)
+ Chukun Pan 191 (0.1%)
+ Venkatesh Yadav Abbarapu 189 (0.1%)
+ Adam Ford 186 (0.1%)
+ Evgeny Bachinin 181 (0.1%)
+ Michael Bode 179 (0.1%)
+ Patrick Rudolph 175 (0.1%)
+ Judith Mendez 168 (0.1%)
+ Heiko Schocher 158 (0.1%)
+ Aniket Limaye 157 (0.1%)
+ Anshul Dalal 155 (0.1%)
+ Jonathan Humphreys 152 (0.1%)
+ Rui Miguel Silva 151 (0.1%)
+ Luke Wang 150 (0.1%)
+ Sam Day 127 (0.1%)
+ E Shattow 127 (0.1%)
+ Raymond Mao 121 (0.1%)
+ Quentin Schulz 116 (0.0%)
+ Ilya Katsnelson 116 (0.0%)
+ Harrison Mutai 108 (0.0%)
+ Hrushikesh Salunke 105 (0.0%)
+ Bryan Brattlof 104 (0.0%)
+ Michal Simek 103 (0.0%)
+ Jonathan Currier 103 (0.0%)
+ Mike Looijmans 99 (0.0%)
+ Jiehui He 96 (0.0%)
+ Tomas Peterka 78 (0.0%)
+ Justin Klaassen 77 (0.0%)
+ Jeremy Compostella 75 (0.0%)
+ Santhosh Kumar K 74 (0.0%)
+ Lin Jinhan 73 (0.0%)
+ Balamanikandan Gunasundar 73 (0.0%)
+ Andreas Dannenberg 65 (0.0%)
+ Ernest Van Hoecke 64 (0.0%)
+ Sam Edwards 62 (0.0%)
+ Christoph Fritz 61 (0.0%)
+ Weijie Gao 60 (0.0%)
+ Keerthy 59 (0.0%)
+ Vishal Mahaveer 59 (0.0%)
+ Mayuresh Chitale 57 (0.0%)
+ Leonard Anderweit 57 (0.0%)
+ Kory Maincent 55 (0.0%)
+ Jim Liu 54 (0.0%)
+ Walter Schweizer 53 (0.0%)
+ Masahisa Kojima 52 (0.0%)
+ Udit Kumar 50 (0.0%)
+ Mikhail Kshevetskiy 48 (0.0%)
+ Pascal Zimmermann 42 (0.0%)
+ Muhammad Hazim Izzat Zamri 42 (0.0%)
+ Nathan Morrisson 41 (0.0%)
+ Daniel Schultz 40 (0.0%)
+ Sumit Garg 39 (0.0%)
+ Dragan Simic 37 (0.0%)
+ Boon Khai Ng 35 (0.0%)
+ Jorge Ramirez-Ortiz 32 (0.0%)
+ Chen-Yu Tsai 32 (0.0%)
+ Tony Dinh 31 (0.0%)
+ Naresh Kumar Ravulapalli 31 (0.0%)
+ Anton Moryakov 31 (0.0%)
+ Rasmus Villemoes 30 (0.0%)
+ Vaishnav Achath 30 (0.0%)
+ Artur Kowalski 30 (0.0%)
+ Love Kumar 29 (0.0%)
+ Sinthu Raja 28 (0.0%)
+ Jean-Jacques Hiblot 28 (0.0%)
+ Lukasz Czechowski 26 (0.0%)
+ Nikunj Kela 23 (0.0%)
+ Sean Edmond 23 (0.0%)
+ Daniel Golle 22 (0.0%)
+ Mattijs Korpershoek 21 (0.0%)
+ Zixun LI 19 (0.0%)
+ Wojciech Szamocki 19 (0.0%)
+ Anurag Dutta 18 (0.0%)
+ Padmarao Begari 17 (0.0%)
+ Bhavya Kapoor 17 (0.0%)
+ Aristo Chen 16 (0.0%)
+ Christophe Roullier 16 (0.0%)
+ Hironori KIKUCHI 16 (0.0%)
+ Jayanth Dodderi Chidanand 15 (0.0%)
+ Olaf Baehring 15 (0.0%)
+ Vincent Stehlé 14 (0.0%)
+ Maks Mishin 13 (0.0%)
+ Andy Shevchenko 13 (0.0%)
+ Viorel Suman 13 (0.0%)
+ Michael Chang 13 (0.0%)
+ Andrew Halaney 12 (0.0%)
+ Prasanth Babu Mantena 12 (0.0%)
+ Rafael Beims 12 (0.0%)
+ Baltazár Radics 12 (0.0%)
+ Benjamin ROBIN 11 (0.0%)
+ Mathieu Othacehe 11 (0.0%)
+ Junhui Liu 11 (0.0%)
+ Stefan Eichenberger 11 (0.0%)
+ Alexander Sverdlin 10 (0.0%)
+ Sam Protsenko 10 (0.0%)
+ Pawel Kochanowski 9 (0.0%)
+ Josua Mayer 9 (0.0%)
+ Fiona Klute 9 (0.0%)
+ Martin Kaistra 8 (0.0%)
+ Michael Walle 8 (0.0%)
+ Nicolas Frattaroli 8 (0.0%)
+ Liya Huang 7 (0.0%)
+ Peter Robinson 7 (0.0%)
+ No generic patch CC mail please 7 (0.0%)
+ ZhiJie.zhang 7 (0.0%)
+ Gowtham Tammana 7 (0.0%)
+ Shiji Yang 6 (0.0%)
+ Parvathi Pudi 5 (0.0%)
+ Emanuele Ghidoli 4 (0.0%)
+ Stefano Babic 4 (0.0%)
+ David Lechner 4 (0.0%)
+ Frantisek Bohacek 4 (0.0%)
+ Martin Schwan 4 (0.0%)
+ Andrew Goodbody 4 (0.0%)
+ Gary Bisson 4 (0.0%)
+ J. Neuschäfer 4 (0.0%)
+ Martin Schiller 3 (0.0%)
+ Yang Xiwen 3 (0.0%)
+ Benjamin Schneider 3 (0.0%)
+ 牛 志宏 3 (0.0%)
+ Duje Mihanović 3 (0.0%)
+ Thomas Schaefer 3 (0.0%)
+ Parth Pancholi 3 (0.0%)
+ Mauro Salvini 3 (0.0%)
+ Bruno Leite 3 (0.0%)
+ Christian Kohlschütter 3 (0.0%)
+ Xu Zhang 3 (0.0%)
+ Arseniy Krasnov 3 (0.0%)
+ Alexander Stein 3 (0.0%)
+ Marius Dinu 2 (0.0%)
+ Takahiro Kuwano 2 (0.0%)
+ Ivan Pang 2 (0.0%)
+ Hiago De Franco 2 (0.0%)
+ Eddie Kovsky 2 (0.0%)
+ Chris Packham 2 (0.0%)
+ Sukrut Bellary 2 (0.0%)
+ Jimmy Ho 2 (0.0%)
+ Akashdeep Kaur 1 (0.0%)
+ Baruch Siach 1 (0.0%)
+ Jan Čermák 1 (0.0%)
+ Hugo Villeneuve 1 (0.0%)
+ Tim Harvey 1 (0.0%)
+ BehradElmi 1 (0.0%)
+ Naresh Solanki 1 (0.0%)
+ Ben Wolsieffer 1 (0.0%)
+ Alexander Vickberg 1 (0.0%)
+ Carlos López 1 (0.0%)
+ Christoph Niedermaier 1 (0.0%)
+ Yifeng Zhao 1 (0.0%)
+ Ezra Buehler 1 (0.0%)
+ yan wang 1 (0.0%)
+ Oskar Nilsson 1 (0.0%)
+ Richard Genoud 1 (0.0%)
+ Vignesh Raghavendra 1 (0.0%)
+ Linus Walleij 1 (0.0%)
+ ==================================== =====
+
+
+.. table:: Developers with the most lines removed
+ :widths: auto
+
+ ==================================== =====
+ Name Count
+ ==================================== =====
+ Patrice Chotard 19307 (30.1%)
+ Jesse Taube 1211 (1.9%)
+ Fabio Estevam 561 (0.9%)
+ Primoz Fiser 241 (0.4%)
+ Prasad Kummari 191 (0.3%)
+ Andrew Davis 129 (0.2%)
+ Samuel Holland 129 (0.2%)
+ Jiaxun Yang 74 (0.1%)
+ Quentin Schulz 67 (0.1%)
+ E Shattow 51 (0.1%)
+ Judith Mendez 45 (0.1%)
+ Jonathan Humphreys 44 (0.1%)
+ Hrushikesh Salunke 37 (0.1%)
+ Dragan Simic 37 (0.1%)
+ Lionel Debieve 31 (0.0%)
+ Tomas Peterka 29 (0.0%)
+ Chen-Yu Tsai 26 (0.0%)
+ Stephan Gerhold 15 (0.0%)
+ Tony Dinh 11 (0.0%)
+ Baltazár Radics 9 (0.0%)
+ Heiko Schocher 4 (0.0%)
+ Mauro Salvini 3 (0.0%)
+ Jorge Ramirez-Ortiz 2 (0.0%)
+ No generic patch CC mail please 2 (0.0%)
+ Arseniy Krasnov 2 (0.0%)
+ Jimmy Ho 2 (0.0%)
+ Olaf Baehring 1 (0.0%)
+ Benjamin ROBIN 1 (0.0%)
+ Pawel Kochanowski 1 (0.0%)
+ Liya Huang 1 (0.0%)
+ Parvathi Pudi 1 (0.0%)
+ Stefano Babic 1 (0.0%)
+ Alexander Stein 1 (0.0%)
+ Hugo Villeneuve 1 (0.0%)
+ ==================================== =====
+
+
+.. table:: Developers with the most signoffs (total 449)
+ :widths: auto
+
+ ==================================== =====
+ Name Count
+ ==================================== =====
+ Caleb Connolly 87 (19.4%)
+ Michal Simek 34 (7.6%)
+ Heiko Stuebner 19 (4.2%)
+ Jonas Karlman 15 (3.3%)
+ Patrice Chotard 14 (3.1%)
+ Mattijs Korpershoek 12 (2.7%)
+ Vasileios Bimpikas 12 (2.7%)
+ Utsav Agarwal 12 (2.7%)
+ Arturs Artamonovs 12 (2.7%)
+ Casey Connolly 12 (2.7%)
+ Ian Roberts 11 (2.4%)
+ Oliver Gaskell 11 (2.4%)
+ Alice Guo 11 (2.4%)
+ Peng Fan 11 (2.4%)
+ Tien Fong Chee 10 (2.2%)
+ Andre Przywara 7 (1.6%)
+ Alper Nebi Yasak 7 (1.6%)
+ Ilias Apalodimas 7 (1.6%)
+ Greg Malysa 7 (1.6%)
+ Patrick Delaunay 7 (1.6%)
+ Mark Kettenis 6 (1.3%)
+ Dario Binacchi 6 (1.3%)
+ Judith Mendez 5 (1.1%)
+ Michael Trimarchi 5 (1.1%)
+ Wadim Egorov 5 (1.1%)
+ Neil Armstrong 5 (1.1%)
+ Nathan Barrett-Morrison 4 (0.9%)
+ Svyatoslav Ryhel 4 (0.9%)
+ Gatien Chevallier 3 (0.7%)
+ Li Hua Qian 3 (0.7%)
+ Jan Kiszka 3 (0.7%)
+ Anurag Dutta 3 (0.7%)
+ Sughosh Ganu 3 (0.7%)
+ Neha Malcom Francis 3 (0.7%)
+ Simon Glass 3 (0.7%)
+ Tom Rini 3 (0.7%)
+ Fabio Estevam 2 (0.4%)
+ Primoz Fiser 2 (0.4%)
+ Heiko Schocher 2 (0.4%)
+ Ranjani Vaidyanathan 2 (0.4%)
+ Mahesh Rao 2 (0.4%)
+ Stephen Boyd 2 (0.4%)
+ Angelo Dureghello 2 (0.4%)
+ Piotr Wojtaszczyk 2 (0.4%)
+ Andrew Halaney 2 (0.4%)
+ Heinrich Schuchardt 2 (0.4%)
+ Ye Li 2 (0.4%)
+ Andrew Davis 1 (0.2%)
+ Lionel Debieve 1 (0.2%)
+ Arseniy Krasnov 1 (0.2%)
+ Heiko Thiery 1 (0.2%)
+ Wolfgang Birkner 1 (0.2%)
+ Haibo Chen 1 (0.2%)
+ Frank Li 1 (0.2%)
+ Mark Brown 1 (0.2%)
+ Ashok Reddy Soma 1 (0.2%)
+ ZHANG Yuntian 1 (0.2%)
+ Pan Bian 1 (0.2%)
+ Richard Weinberger 1 (0.2%)
+ Ji Luo 1 (0.2%)
+ Jindong Yue 1 (0.2%)
+ Francesco Dolcini 1 (0.2%)
+ Thomas Bourgoin 1 (0.2%)
+ Raphael Gallais-Pou 1 (0.2%)
+ Finley Xiao 1 (0.2%)
+ Basharath Hussain Khaja 1 (0.2%)
+ Gabriel Nesteruk 1 (0.2%)
+ AngeloGioacchino Del Regno 1 (0.2%)
+ Sparsh Kumar 1 (0.2%)
+ Sebin Francis 1 (0.2%)
+ Sam Shih 1 (0.2%)
+ Peter Geis 1 (0.2%)
+ Viacheslav Bocharov 1 (0.2%)
+ Beleswar Padhi 1 (0.2%)
+ Ryan Eatmon 1 (0.2%)
+ Charan Pedumuru 1 (0.2%)
+ Walter Schweizer 1 (0.2%)
+ Prasanth Babu Mantena 1 (0.2%)
+ Viorel Suman 1 (0.2%)
+ Nathan Morrisson 1 (0.2%)
+ Boon Khai Ng 1 (0.2%)
+ Udit Kumar 1 (0.2%)
+ Muhammad Hazim Izzat Zamri 1 (0.2%)
+ Keerthy 1 (0.2%)
+ Manikandan Muralidharan 1 (0.2%)
+ Aniket Limaye 1 (0.2%)
+ Patrick Rudolph 1 (0.2%)
+ Jonas Schwöbel 1 (0.2%)
+ Nishanth Menon 1 (0.2%)
+ Tingting Meng 1 (0.2%)
+ Marek Vasut 1 (0.2%)
+ Manorit Chawdhry 1 (0.2%)
+ ==================================== =====
+
+
+.. table:: Developers with the most reviews (total 1002)
+ :widths: auto
+
+ ==================================== =====
+ Name Count
+ ==================================== =====
+ Kever Yang 116 (11.6%)
+ Simon Glass 64 (6.4%)
+ Ilias Apalodimas 53 (5.3%)
+ Neil Armstrong 52 (5.2%)
+ Tom Rini 52 (5.2%)
+ Leo Yu-Chi Liang 45 (4.5%)
+ Mattijs Korpershoek 40 (4.0%)
+ Paul Barker 37 (3.7%)
+ Marek Vasut 33 (3.3%)
+ Quentin Schulz 32 (3.2%)
+ Heinrich Schuchardt 30 (3.0%)
+ Caleb Connolly 27 (2.7%)
+ Peng Fan 27 (2.7%)
+ Tien Fong Chee 26 (2.6%)
+ Sumit Garg 25 (2.5%)
+ Patrice Chotard 20 (2.0%)
+ Patrick Delaunay 20 (2.0%)
+ E Shattow 19 (1.9%)
+ Stefan Roese 18 (1.8%)
+ Bryan Brattlof 17 (1.7%)
+ Jonas Karlman 16 (1.6%)
+ Heiko Schocher 16 (1.6%)
+ Andrew Davis 16 (1.6%)
+ Matthias Brugger 14 (1.4%)
+ Jerome Forissier 13 (1.3%)
+ Daniel Schwierzeck 12 (1.2%)
+ Jernej Skrabec 12 (1.2%)
+ Fabio Estevam 9 (0.9%)
+ Udit Kumar 9 (0.9%)
+ Andre Przywara 8 (0.8%)
+ Neha Malcom Francis 8 (0.8%)
+ Hal Feng 8 (0.8%)
+ Christopher Obbard 8 (0.8%)
+ Casey Connolly 7 (0.7%)
+ Wadim Egorov 6 (0.6%)
+ Ye Li 6 (0.6%)
+ Eugen Hristev 6 (0.6%)
+ Michael Trimarchi 5 (0.5%)
+ Francesco Dolcini 4 (0.4%)
+ Roger Quadros 4 (0.4%)
+ Peter Robinson 4 (0.4%)
+ Svyatoslav Ryhel 3 (0.3%)
+ Dhruva Gole 3 (0.3%)
+ Jaehoon Chung 3 (0.3%)
+ Tobias Waldekranz 3 (0.3%)
+ Fabrice Gasnier 3 (0.3%)
+ Daniel Schultz 3 (0.3%)
+ Siddharth Vadapalli 3 (0.3%)
+ Alice Guo 2 (0.2%)
+ Nishanth Menon 2 (0.2%)
+ Tudor Ambarus 2 (0.2%)
+ Joao Marcos Costa 2 (0.2%)
+ Richard Henderson 2 (0.2%)
+ Judith Mendez 1 (0.1%)
+ Sughosh Ganu 1 (0.1%)
+ Frank Li 1 (0.1%)
+ AngeloGioacchino Del Regno 1 (0.1%)
+ Linus Walleij 1 (0.1%)
+ Ramon Fried 1 (0.1%)
+ Lukasz Majewski 1 (0.1%)
+ Maxim Moskalets 1 (0.1%)
+ Vladimir Oltean 1 (0.1%)
+ Paul Kocialkowski 1 (0.1%)
+ Anand Moon 1 (0.1%)
+ Boris Brezillon 1 (0.1%)
+ Krzysztof Kozlowski 1 (0.1%)
+ Sean Anderson 1 (0.1%)
+ Icenowy Zheng 1 (0.1%)
+ Yixun Lan 1 (0.1%)
+ Teresa Remmet 1 (0.1%)
+ Anshul Dalal 1 (0.1%)
+ Michael Walle 1 (0.1%)
+ Alexander Sverdlin 1 (0.1%)
+ Andy Shevchenko 1 (0.1%)
+ Love Kumar 1 (0.1%)
+ Leonard Anderweit 1 (0.1%)
+ Harrison Mutai 1 (0.1%)
+ Adam Ford 1 (0.1%)
+ Christian Marangi 1 (0.1%)
+ Yao Zi 1 (0.1%)
+ ==================================== =====
+
+
+.. table:: Developers with the most test credits (total 89)
+ :widths: auto
+
+ ==================================== =====
+ Name Count
+ ==================================== =====
+ E Shattow 7 (7.9%)
+ Love Kumar 7 (7.9%)
+ Ion Agorria 7 (7.9%)
+ Christopher Obbard 6 (6.7%)
+ Danila Tikhonov 6 (6.7%)
+ Jens Reidel 6 (6.7%)
+ Sumit Garg 4 (4.5%)
+ Zixun LI 4 (4.5%)
+ Simon Glass 3 (3.4%)
+ Neil Armstrong 3 (3.4%)
+ Sughosh Ganu 3 (3.4%)
+ Mattijs Korpershoek 2 (2.2%)
+ Quentin Schulz 2 (2.2%)
+ Heinrich Schuchardt 2 (2.2%)
+ Patrice Chotard 2 (2.2%)
+ Fabio Estevam 2 (2.2%)
+ Daniel Schultz 2 (2.2%)
+ Dang Huynh 2 (2.2%)
+ Peter Robinson 1 (1.1%)
+ Vladimir Oltean 1 (1.1%)
+ Adam Ford 1 (1.1%)
+ Yao Zi 1 (1.1%)
+ Michal Simek 1 (1.1%)
+ Prasanth Babu Mantena 1 (1.1%)
+ Jonathan Humphreys 1 (1.1%)
+ Tony Dinh 1 (1.1%)
+ Niklas Sombert 1 (1.1%)
+ Weizhao Ouyang 1 (1.1%)
+ Marcel Ziswiler 1 (1.1%)
+ Faqiang Zhu 1 (1.1%)
+ Ryan Walklin 1 (1.1%)
+ Tim Harvey 1 (1.1%)
+ Nicolas Frattaroli 1 (1.1%)
+ Raymond Mao 1 (1.1%)
+ Sam Day 1 (1.1%)
+ Alexey Minnekhanov 1 (1.1%)
+ Huan Zhou 1 (1.1%)
+ ==================================== =====
+
+
+.. table:: Developers who gave the most tested-by credits (total 89)
+ :widths: auto
+
+ ==================================== =====
+ Name Count
+ ==================================== =====
+ Casey Connolly 19 (21.3%)
+ Svyatoslav Ryhel 8 (9.0%)
+ Simon Glass 7 (7.9%)
+ Neil Armstrong 6 (6.7%)
+ Ilias Apalodimas 6 (6.7%)
+ Minda Chen 5 (5.6%)
+ Mattijs Korpershoek 4 (4.5%)
+ Heinrich Schuchardt 4 (4.5%)
+ Jerome Forissier 4 (4.5%)
+ Marek Vasut 3 (3.4%)
+ Quentin Schulz 2 (2.2%)
+ Thomas Schaefer 2 (2.2%)
+ Michal Simek 1 (1.1%)
+ Raymond Mao 1 (1.1%)
+ Tom Rini 1 (1.1%)
+ Paul Barker 1 (1.1%)
+ Peng Fan 1 (1.1%)
+ Patrick Delaunay 1 (1.1%)
+ Jonas Karlman 1 (1.1%)
+ Jernej Skrabec 1 (1.1%)
+ Wadim Egorov 1 (1.1%)
+ Michael Trimarchi 1 (1.1%)
+ Heiko Stuebner 1 (1.1%)
+ Jiaxun Yang 1 (1.1%)
+ Junhui Liu 1 (1.1%)
+ Eddie Kovsky 1 (1.1%)
+ Bruno Leite 1 (1.1%)
+ Weijie Gao 1 (1.1%)
+ Venkatesh Yadav Abbarapu 1 (1.1%)
+ Hari Nagalla 1 (1.1%)
+ Adriano Cordova 1 (1.1%)
+ ==================================== =====
+
+
+.. table:: Developers with the most report credits (total 41)
+ :widths: auto
+
+ ==================================== =====
+ Name Count
+ ==================================== =====
+ Da Xue 6 (14.6%)
+ Heinrich Schuchardt 4 (9.8%)
+ Tom Rini 4 (9.8%)
+ Zixun LI 3 (7.3%)
+ Francesco Dolcini 2 (4.9%)
+ Nathaniel Hourt 2 (4.9%)
+ Kuba Szczodrzyński 2 (4.9%)
+ Quentin Schulz 1 (2.4%)
+ Jernej Skrabec 1 (2.4%)
+ Yao Zi 1 (2.4%)
+ Tony Dinh 1 (2.4%)
+ Niklas Sombert 1 (2.4%)
+ Weizhao Ouyang 1 (2.4%)
+ Tim Harvey 1 (2.4%)
+ Sam Day 1 (2.4%)
+ Anshul Dalal 1 (2.4%)
+ Heiko Thiery 1 (2.4%)
+ Keerthy 1 (2.4%)
+ Enric Balletbo i Serra 1 (2.4%)
+ Chirag Shilwant 1 (2.4%)
+ Prashant Shivhare 1 (2.4%)
+ Chintan Vankar 1 (2.4%)
+ Parth Pancholi 1 (2.4%)
+ Christoph Niedermaier 1 (2.4%)
+ Mikhail Kshevetskiy 1 (2.4%)
+ ==================================== =====
+
+
+.. table:: Developers who gave the most report credits (total 41)
+ :widths: auto
+
+ ==================================== =====
+ Name Count
+ ==================================== =====
+ Alexander Graf 7 (17.1%)
+ Tom Rini 4 (9.8%)
+ Jerome Forissier 4 (9.8%)
+ Simon Glass 3 (7.3%)
+ Mattijs Korpershoek 3 (7.3%)
+ Andre Przywara 3 (7.3%)
+ Yao Zi 2 (4.9%)
+ Andrew Davis 2 (4.9%)
+ Heinrich Schuchardt 1 (2.4%)
+ Anshul Dalal 1 (2.4%)
+ Casey Connolly 1 (2.4%)
+ Ilias Apalodimas 1 (2.4%)
+ Marek Vasut 1 (2.4%)
+ Weijie Gao 1 (2.4%)
+ Adriano Cordova 1 (2.4%)
+ Fabio Estevam 1 (2.4%)
+ Adam Ford 1 (2.4%)
+ Bryan Brattlof 1 (2.4%)
+ Alice Guo 1 (2.4%)
+ Alexander Sverdlin 1 (2.4%)
+ Bhavya Kapoor 1 (2.4%)
+ ==================================== =====
+
+
+.. table:: Top changeset contributors by employer
+ :widths: auto
+
+ ==================================== =====
+ Name Count
+ ==================================== =====
+ (Unknown) 747 (42.0%)
+ Google LLC 172 (9.7%)
+ Linaro 169 (9.5%)
+ Texas Instruments 126 (7.1%)
+ Konsulko Group 91 (5.1%)
+ DENX Software Engineering 68 (3.8%)
+ Renesas Electronics 68 (3.8%)
+ ARM 61 (3.4%)
+ ST Microelectronics 52 (2.9%)
+ Intel 50 (2.8%)
+ AMD 39 (2.2%)
+ Phytec 38 (2.1%)
+ NXP 27 (1.5%)
+ Amarula Solutions 20 (1.1%)
+ Bootlin 17 (1.0%)
+ Toradex 10 (0.6%)
+ Rockchip 9 (0.5%)
+ Siemens 8 (0.4%)
+ Red Hat 3 (0.2%)
+ BayLibre SAS 1 (0.1%)
+ Collabora Ltd. 1 (0.1%)
+ linutronix 1 (0.1%)
+ Nokia 1 (0.1%)
+ Socionext Inc. 1 (0.1%)
+ ==================================== =====
+
+
+.. table:: Top lines changed by employer
+ :widths: auto
+
+ ==================================== =====
+ Name Count
+ ==================================== =====
+ Konsulko Group 78284 (33.7%)
+ (Unknown) 59242 (25.5%)
+ ST Microelectronics 22661 (9.8%)
+ Texas Instruments 21551 (9.3%)
+ Google LLC 8757 (3.8%)
+ Rockchip 7249 (3.1%)
+ DENX Software Engineering 7195 (3.1%)
+ Linaro 5651 (2.4%)
+ Toradex 4661 (2.0%)
+ Intel 4500 (1.9%)
+ NXP 3595 (1.5%)
+ Renesas Electronics 2880 (1.2%)
+ Amarula Solutions 1604 (0.7%)
+ Bootlin 1300 (0.6%)
+ ARM 1049 (0.5%)
+ AMD 742 (0.3%)
+ Phytec 522 (0.2%)
+ Siemens 483 (0.2%)
+ Socionext Inc. 52 (0.0%)
+ Nokia 19 (0.0%)
+ Red Hat 14 (0.0%)
+ Collabora Ltd. 8 (0.0%)
+ linutronix 8 (0.0%)
+ BayLibre SAS 2 (0.0%)
+ ==================================== =====
+
+
+.. table:: Employers with the most signoffs (total 449)
+ :widths: auto
+
+ ==================================== =====
+ Name Count
+ ==================================== =====
+ (Unknown) 125 (27.8%)
+ Linaro 114 (25.4%)
+ Analog Devices 47 (10.5%)
+ AMD 34 (7.6%)
+ NXP 31 (6.9%)
+ ST Microelectronics 27 (6.0%)
+ Texas Instruments 22 (4.9%)
+ Amarula Solutions 11 (2.4%)
+ ARM 7 (1.6%)
+ Siemens 7 (1.6%)
+ Phytec 5 (1.1%)
+ Konsulko Group 3 (0.7%)
+ Google LLC 3 (0.7%)
+ DENX Software Engineering 2 (0.4%)
+ Red Hat 2 (0.4%)
+ BayLibre SAS 2 (0.4%)
+ Canonical 2 (0.4%)
+ Rockchip 1 (0.2%)
+ Toradex 1 (0.2%)
+ Renesas Electronics 1 (0.2%)
+ Collabora Ltd. 1 (0.2%)
+ Xilinx 1 (0.2%)
+ ==================================== =====
+
+
+.. table:: Employers with the most hackers (total 230)
+ :widths: auto
+
+ ==================================== =====
+ Name Count
+ ==================================== =====
+ (Unknown) 129 (56.1%)
+ Texas Instruments 27 (11.7%)
+ Linaro 11 (4.8%)
+ Toradex 7 (3.0%)
+ Rockchip 6 (2.6%)
+ AMD 5 (2.2%)
+ NXP 5 (2.2%)
+ ST Microelectronics 5 (2.2%)
+ Intel 5 (2.2%)
+ ARM 4 (1.7%)
+ Phytec 4 (1.7%)
+ Siemens 3 (1.3%)
+ DENX Software Engineering 3 (1.3%)
+ Bootlin 3 (1.3%)
+ Amarula Solutions 2 (0.9%)
+ Red Hat 2 (0.9%)
+ Renesas Electronics 2 (0.9%)
+ Konsulko Group 1 (0.4%)
+ Google LLC 1 (0.4%)
+ BayLibre SAS 1 (0.4%)
+ Collabora Ltd. 1 (0.4%)
+ Socionext Inc. 1 (0.4%)
+ Nokia 1 (0.4%)
+ linutronix 1 (0.4%)
+ ==================================== =====
diff --git a/doc/usage/cmd/gpt.rst b/doc/usage/cmd/gpt.rst
index 8534f78cbac..13e8783be9b 100644
--- a/doc/usage/cmd/gpt.rst
+++ b/doc/usage/cmd/gpt.rst
@@ -54,7 +54,7 @@ partition string
* name=<NAME> - The partition name, required
* start=<BYTES> - The partition start offset in bytes, required
- * size=<BYTES> - The partition size in bytes or "-" to expand it to the whole free area
+ * size=<BYTES> - The partition size in bytes or "-" for the last partition to expand it to the whole free area
* bootable - Set the legacy bootable flag
* uuid=<UUID> - The partition UUID, optional if CONFIG_RANDOM_UUID=y is enabled
* type=<UUID> - The partition type GUID, requires CONFIG_PARTITION_TYPE_GUID=y
@@ -63,6 +63,23 @@ partition string
If 'uuid' is not specified, but CONFIG_RANDOM_UUID is enabled, a random UUID
will be generated for the partition
+ If 'type' is not specified or without CONFIG_PARTITION_TYPE_GUID=y,
+ the used partition type GUID is PARTITION_BASIC_DATA_GUID.
+
+ Some strings can be also used at the place of the known partition type GUID:
+ * "mbr" = LEGACY_MBR_PARTITION_GUID (024DEE41-33E7-11D3-9D69-0008C781F39F)
+ * "msft" = PARTITION_MSFT_RESERVED_GUID (E3C9E316-0B5C-4DB8-817D-F92DF00215AE)
+ * "data" = PARTITION_BASIC_DATA_GUID (EBD0A0A2-B9E5-4433-87C0-68B6B72699C7)
+ * "linux" = PARTITION_LINUX_FILE_SYSTEM_DATA_GUID (0FC63DAF-8483-4772-8E79-3D69D8477DE4)
+ * "raid" = PARTITION_LINUX_RAID_GUID (A19D880F-05FC-4D3B-A006-743F0F84911E)
+ * "swap" = PARTITION_LINUX_SWAP_GUID (0657FD6D-A4AB-43C4-84E5-0933C84B4F4F)
+ * "lvm" = PARTITION_LINUX_LVM_GUID (E6D6D379-F507-44C2-A23C-238F2A3DF928)
+ * "u-boot-env" = PARTITION_U_BOOT_ENVIRONMENT(3DE21764-95BD-54BD-A5C3-4ABE786F38A8)
+ * "system" = PARTITION_SYSTEM_GUID (C12A7328-F81F-11D2-BA4B-00A0C93EC93B)
+
+ The GPT partitions layout and associated 'type' are also printed with the
+ :doc:`part command <part>` command by typing "part list".
+
gpt enumerate
~~~~~~~~~~~~~
@@ -162,16 +179,17 @@ Examples
Create 6 partitions on a disk::
- => setenv gpt_parts 'uuid_disk=bec9fc2a-86c1-483d-8a0e-0109732277d7;
- name=boot,start=4M,size=128M,bootable,type=ebd0a0a2-b9e5-4433-87c0-68b6b72699c7,
- name=rootfs,size=3072M,type=0fc63daf-8483-4772-8e79-3d69d8477de4;
- name=system-data,size=512M,type=0fc63daf-8483-4772-8e79-3d69d8477de4;
- name=[ext],size=-,type=0fc63daf-8483-4772-8e79-3d69d8477de4;
- name=user,size=-,type=0fc63daf-8483-4772-8e79-3d69d8477de4;
- name=modules,size=100M,type=0fc63daf-8483-4772-8e79-3d69d8477de4;
- name=ramdisk,size=8M,type=0fc63daf-8483-4772-8e79-3d69d8477de4
+ => setenv gpt_parts 'uuid_disk=bec9fc2a-86c1-483d-8a0e-0109732277d7;\
+ name=boot,start=4M,size=128M,bootable,type=ebd0a0a2-b9e5-4433-87c0-68b6b72699c7;\
+ name=rootfs,size=3072M,type=0fc63daf-8483-4772-8e79-3d69d8477de4;\
+ name=system-data,size=512M,type=0fc63daf-8483-4772-8e79-3d69d8477de4;\
+ name=user,size=512M,type=0fc63daf-8483-4772-8e79-3d69d8477de4;\
+ name=modules,size=100M,type=0fc63daf-8483-4772-8e79-3d69d8477de4;\
+ name=ramdisk,size=8M,type=0fc63daf-8483-4772-8e79-3d69d8477de4;\
+ name=[ext],size=-,type=0fc63daf-8483-4772-8e79-3d69d8477de4'
=> gpt write mmc 0 $gpt_parts
+Last partition "[ext]" with '-' is extended up to the end of the disk
Verify that the device matches the partition layout described in the variable
$gpt_parts::
@@ -228,3 +246,60 @@ Swap the order of the 'boot' and 'rootfs' partition table entries::
=> gpt setenv mmc 0 boot
=> echo ${gpt_partition_entry}
2
+
+Other example: a disk with known partition types::
+
+ => setenv gpt_parts 'name=u-boot,size=32M,type=data;\
+ name=env,size=1M,type=u-boot-env;
+ name=ESP,size=128M,type=system;
+ name=rootfs,size=3072M,type=linux;
+ name=swap,size=100M,type=swap;
+ name=user,size=-,type=linux'
+ => gpt write mmc 0 $gpt_parts
+
+ => part list mmc 0
+ Partition Map for mmc device 0 -- Partition Type: EFI
+ Part Start LBA End LBA Name
+ Attributes
+ Type GUID
+ Partition GUID
+ 1 0x00000022 0x00010021 "u-boot"
+ attrs: 0x0000000000000000
+ type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
+ (data)
+ guid: 502d48f6-81c0-488f-bdc0-ad602498f3ce
+ 2 0x00010022 0x00010821 "env"
+ attrs: 0x0000000000000000
+ type: 3de21764-95bd-54bd-a5c3-4abe786f38a8
+ (u-boot-env)
+ guid: 9dc62338-459a-485e-bd8f-b3fbf728d9c0
+ 3 0x00010822 0x00050821 "ESP"
+ attrs: 0x0000000000000000
+ type: c12a7328-f81f-11d2-ba4b-00a0c93ec93b
+ (EFI System Partition)
+ guid: 8a3a1168-6af8-4ba7-a95d-9cd0d14e1b3d
+ 4 0x00050822 0x00650821 "rootfs"
+ attrs: 0x0000000000000000
+ type: 0fc63daf-8483-4772-8e79-3d69d8477de4
+ (linux)
+ guid: 411ffebc-8a19-469d-99a9-0982409a6851
+ 5 0x00650822 0x00682821 "swap"
+ attrs: 0x0000000000000000
+ type: 0657fd6d-a4ab-43c4-84e5-0933c84b4f4f
+ (swap)
+ guid: f8ec0410-95ec-4e3e-8b98-fb8cf271a201
+ 6 0x00682822 0x01dacbde "user"
+ attrs: 0x0000000000000000
+ type: 0fc63daf-8483-4772-8e79-3d69d8477de4
+ (linux)
+ guid: c5543e1c-566d-4502-99ad-20545007e673
+
+Modifying GPT partition layout from U-Boot::
+
+ => gpt read mmc 0 current_partitions
+ => env edit current_partitions
+ edit: uuid_disk=[...];name=part1,start=0x4000,size=0x4000,uuid=[...];
+ name=part2,start=0xc000,size=0xc000,uuid=[...];[ . . . ]
+
+ => gpt write mmc 0 $current_partitions
+ => gpt verify mmc 0 $current_partitions
diff --git a/doc/usage/cmd/sntp.rst b/doc/usage/cmd/sntp.rst
new file mode 100644
index 00000000000..d97f83053f7
--- /dev/null
+++ b/doc/usage/cmd/sntp.rst
@@ -0,0 +1,72 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+.. index::
+ single: sntp (command)
+
+sntp command
+============
+
+Synopsis
+--------
+
+::
+
+ sntp [serverip]
+ sntp [servername] # NET_LWIP=y && CMD_DNS=y only
+
+
+Description
+-----------
+
+The sntp command gets the current time from an NTP time server and
+syncronizes the Real Time Clock (RTC) of the board. This command needs
+the server's IP address to be given on the command line or via the
+`ntpserverip` environment variable.
+
+The address of the NTP server does not need to be given if the DHCP server
+provides one. The legacy network stack (`CONFIG_NET=y`) can only use the
+first NTP server provided in the `ntp-servers` DHCP option.
+
+When the network stack is lwIP (`CONFIG_NET_LWIP=y`) and the dns command
+is enabled (`CONFIG_CMD_DNS=y`), then the sntp command accepts a server
+name as an argument.
+
+The network time is sent as UTC. So, if you want to set the RTC to any local
+time different from UTC, you need to set the `timeoffset` environment variable.
+
+Round-trip delay compensation is not implemented/not enabled. In practice
+this should not matter much given that the RTC API does not have sub-second
+resolution, and round-trip times are typically 10 to 100 ms at most.
+
+Examples
+--------
+
+::
+
+ => setenv ntpserverip 109.190.177.205
+ => date
+ Date: 2025-06-16 (Monday) Time: 15:19:35
+ => date reset
+ Reset RTC...
+ Date: 2000-01-01 (Saturday) Time: 0:00:00
+ => date
+ Date: 2000-01-01 (Saturday) Time: 0:00:03
+ => sntp
+ Date: 2025-06-16 Time: 15:19:43
+ => date
+ Date: 2025-06-16 (Monday) Time: 15:19:47
+ => setenv timeoffset 7200
+ => sntp
+ Date: 2025-06-16 Time: 17:19:55
+ => date
+ Date: 2025-06-16 (Monday) Time: 17:19:57
+
+With `CONFIG_NET_LWIP=y` and `CONFIG_CMD_DNS=y`:
+
+::
+
+ => date reset
+ Reset RTC...
+ Date: 2000-01-01 (Saturday) Time: 0:00:00
+ => sntp 0.us.pool.ntp.org
+ Date: 2025-06-16 Time: 15:10:59
diff --git a/doc/usage/cmd/wget.rst b/doc/usage/cmd/wget.rst
index 44033aaff39..06df2842549 100644
--- a/doc/usage/cmd/wget.rst
+++ b/doc/usage/cmd/wget.rst
@@ -185,13 +185,6 @@ TCP Selective Acknowledgments in the legacy network stack can be enabled via
CONFIG_PROT_TCP_SACK=y. This will improve the download speed. Selective
Acknowledgments are enabled by default with lwIP.
-.. note::
-
- U-Boot currently has no way to verify certificates for HTTPS.
- A place to store the root CA certificates is needed, and then MBed TLS would
- need to walk the entire chain. Therefore, man-in-the middle attacks are
- possible and HTTPS should not be relied upon for payload authentication.
-
Return value
------------
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index c5b45fd9290..e9e0bd04e05 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -119,6 +119,7 @@ Shell commands
cmd/sleep
cmd/sm
cmd/smbios
+ cmd/sntp
cmd/sound
cmd/source
cmd/tcpm
diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig
index 4f358657444..f5bcd406a50 100644
--- a/drivers/cache/Kconfig
+++ b/drivers/cache/Kconfig
@@ -24,6 +24,7 @@ config L2X0_CACHE
config ANDES_L2_CACHE
bool "Andes L2 cache driver"
+ depends on RISCV
select CACHE
help
Support Andes L2 cache controller in AE350 platform.
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index ef1e5355be8..e6483ddc88b 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -225,7 +225,7 @@ config CLK_VERSACLOCK
config CLK_VERSAL
bool "Enable clock driver support for Versal"
depends on (ARCH_VERSAL || ARCH_VERSAL_NET)
- imply ZYNQMP_FIRMWARE
+ depends on ZYNQMP_FIRMWARE
help
This clock driver adds support for clock realted settings for
Versal platform.
diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c
index a8239e228cf..4f67c958d0f 100644
--- a/drivers/clk/clk_zynqmp.c
+++ b/drivers/clk/clk_zynqmp.c
@@ -108,6 +108,8 @@ static const resource_size_t zynqmp_crl_apb_clkc_base = 0xff5e0020;
#define PLLCTRL_POST_SRC_MASK (0x7 << PLLCTRL_POST_SRC_SHFT)
#define PLLCTRL_PRE_SRC_SHFT 20
#define PLLCTRL_PRE_SRC_MASK (0x7 << PLLCTRL_PRE_SRC_SHFT)
+#define PLL_TO_LPD_DIV_SHIFT 8
+#define PLL_TO_LPD_DIV_MASK (0x3f << PLL_TO_LPD_DIV_SHIFT)
#define NUM_MIO_PINS 77
@@ -334,6 +336,8 @@ static u32 zynqmp_clk_get_register(enum zynqmp_clk id)
return CRF_APB_TOPSW_LSBUS_CTRL;
case iopll_to_fpd:
return CRL_APB_IOPLL_TO_FPD_CTRL;
+ case dpll_to_lpd:
+ return CRF_APB_DPLL_TO_LPD_CTRL;
default:
debug("Invalid clk id%d\n", id);
}
@@ -397,6 +401,22 @@ static ulong zynqmp_clk_get_pll_rate(struct zynqmp_clk_priv *priv,
if (clk_ctrl & (1 << 16))
freq /= 2;
+ if (id == dpll) {
+ u32 dpll_lpd_reg, cross_div;
+
+ dpll_lpd_reg = zynqmp_clk_get_register(dpll_to_lpd);
+
+ ret = zynqmp_mmio_read(dpll_lpd_reg, &cross_div);
+ if (ret) {
+ printf("%s mio read fail\n", __func__);
+ return -EIO;
+ }
+
+ cross_div = (cross_div & PLL_TO_LPD_DIV_MASK) >>
+ PLL_TO_LPD_DIV_SHIFT;
+ freq /= cross_div;
+ }
+
return freq;
}
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 3ea01f3c969..34e41461e72 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -31,6 +31,14 @@ config CLK_QCOM_IPQ4019
on the Snapdragon IPQ4019 SoC. This driver supports the clocks
and resets exposed by the GCC hardware block.
+config CLK_QCOM_IPQ5424
+ bool "Qualcomm IPQ5424 GCC"
+ select CLK_QCOM
+ help
+ Say Y here to enable support for the Global Clock Controller
+ on the Qualcomm IPQ5424 SoC. This driver supports the clocks
+ and resets exposed by the GCC hardware block.
+
config CLK_QCOM_IPQ9574
bool "Qualcomm IPQ9574 GCC"
select CLK_QCOM
@@ -55,6 +63,22 @@ config CLK_QCOM_QCS404
on the Snapdragon QCS404 SoC. This driver supports the clocks
and resets exposed by the GCC hardware block.
+config CLK_QCOM_QCS615
+ bool "Qualcomm QCS615 GCC"
+ select CLK_QCOM
+ help
+ Say Y here to enable support for the Global Clock Controller
+ on the Snapdragon QCS615 SoC. This driver supports the clocks
+ and resets exposed by the GCC hardware block.
+
+config CLK_QCOM_QCS8300
+ bool "Qualcomm QCS8300 GCC"
+ select CLK_QCOM
+ help
+ Say Y here to enable support for the Global Clock Controller
+ on the Snapdragon QCS8300 SoC. This driver supports the clocks
+ and resets exposed by the GCC hardware block.
+
config CLK_QCOM_SA8775P
bool "Qualcomm SA8775 GCC"
select CLK_QCOM
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index e13fc8c1071..b3d95b0faa3 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -7,9 +7,12 @@ obj-$(CONFIG_CLK_QCOM_SDM845) += clock-sdm845.o
obj-$(CONFIG_CLK_QCOM_APQ8016) += clock-apq8016.o
obj-$(CONFIG_CLK_QCOM_APQ8096) += clock-apq8096.o
obj-$(CONFIG_CLK_QCOM_IPQ4019) += clock-ipq4019.o
+obj-$(CONFIG_CLK_QCOM_IPQ5424) += clock-ipq5424.o
obj-$(CONFIG_CLK_QCOM_IPQ9574) += clock-ipq9574.o
obj-$(CONFIG_CLK_QCOM_QCM2290) += clock-qcm2290.o
obj-$(CONFIG_CLK_QCOM_QCS404) += clock-qcs404.o
+obj-$(CONFIG_CLK_QCOM_QCS8300) += clock-qcs8300.o
+obj-$(CONFIG_CLK_QCOM_QCS615) += clock-qcs615.o
obj-$(CONFIG_CLK_QCOM_SA8775P) += clock-sa8775p.o
obj-$(CONFIG_CLK_QCOM_SC7280) += clock-sc7280.o
obj-$(CONFIG_CLK_QCOM_SM6115) += clock-sm6115.o
diff --git a/drivers/clk/qcom/clock-ipq5424.c b/drivers/clk/qcom/clock-ipq5424.c
new file mode 100644
index 00000000000..40823a30ead
--- /dev/null
+++ b/drivers/clk/qcom/clock-ipq5424.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock drivers for Qualcomm ipq5424
+ *
+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <linux/bug.h>
+#include <linux/bitops.h>
+#include <dt-bindings/clock/qcom,ipq5424-gcc.h>
+#include <dt-bindings/reset/qcom,ipq5424-gcc.h>
+
+#include "clock-qcom.h"
+
+#define GCC_IM_SLEEP_CBCR 0x1834020u
+
+static ulong ipq5424_set_rate(struct clk *clk, ulong rate)
+{
+ struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+ switch (clk->id) {
+ case GCC_QUPV3_UART1_CLK:
+ clk_rcg_set_rate_mnd(priv->base, priv->data->clks[clk->id].reg,
+ 0, 144, 15625, CFG_CLK_SRC_GPLL0, 16);
+ return rate;
+ case GCC_SDCC1_APPS_CLK:
+ clk_rcg_set_rate_mnd(priv->base, priv->data->clks[clk->id].reg,
+ 5, 0, 0, CFG_CLK_SRC_GPLL2_MAIN, 16);
+ return rate;
+ }
+ return 0;
+}
+
+static const struct gate_clk ipq5424_clks[] = {
+ GATE_CLK(GCC_QUPV3_UART1_CLK, 0x302c, BIT(0)),
+ GATE_CLK(GCC_SDCC1_AHB_CLK, 0x3303c, BIT(0)),
+ GATE_CLK(GCC_SDCC1_APPS_CLK, 0x33004, BIT(1)),
+ GATE_CLK(GCC_IM_SLEEP_CLK, 0x34020, BIT(0)),
+};
+
+static int ipq5424_enable(struct clk *clk)
+{
+ struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+ if (clk->id >= ARRAY_SIZE(ipq5424_clks) || !ipq5424_clks[clk->id].reg)
+ return -EINVAL;
+
+ qcom_gate_clk_en(priv, clk->id);
+
+ return 0;
+}
+
+static const struct qcom_reset_map ipq5424_gcc_resets[] = {
+ [GCC_SDCC_BCR] = { 0x33000 },
+};
+
+static struct msm_clk_data ipq5424_gcc_data = {
+ .resets = ipq5424_gcc_resets,
+ .num_resets = ARRAY_SIZE(ipq5424_gcc_resets),
+ .clks = ipq5424_clks,
+ .num_clks = ARRAY_SIZE(ipq5424_clks),
+
+ .enable = ipq5424_enable,
+ .set_rate = ipq5424_set_rate,
+};
+
+static const struct udevice_id gcc_ipq5424_of_match[] = {
+ {
+ .compatible = "qcom,ipq5424-gcc",
+ .data = (ulong)&ipq5424_gcc_data,
+ },
+ { }
+};
+
+static int ipq5424_clk_probe(struct udevice *dev)
+{
+ /* Enable the sleep clock needed for the MMC block reset */
+ writel(BIT(0), GCC_IM_SLEEP_CBCR);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(gcc_ipq5424) = {
+ .name = "gcc_ipq5424",
+ .id = UCLASS_NOP,
+ .of_match = gcc_ipq5424_of_match,
+ .probe = ipq5424_clk_probe,
+ .bind = qcom_cc_bind,
+ .flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
+};
diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h
index 1b60882dae4..3a4550d8536 100644
--- a/drivers/clk/qcom/clock-qcom.h
+++ b/drivers/clk/qcom/clock-qcom.h
@@ -13,6 +13,7 @@
#define CFG_CLK_SRC_GPLL0 (1 << 8)
#define CFG_CLK_SRC_GPLL0_AUX2 (2 << 8)
#define CFG_CLK_SRC_GPLL2 (2 << 8)
+#define CFG_CLK_SRC_GPLL2_MAIN (2 << 8)
#define CFG_CLK_SRC_GPLL9 (2 << 8)
#define CFG_CLK_SRC_GPLL0_ODD (3 << 8)
#define CFG_CLK_SRC_GPLL6 (4 << 8)
diff --git a/drivers/clk/qcom/clock-qcs615.c b/drivers/clk/qcom/clock-qcs615.c
new file mode 100644
index 00000000000..4700baba8c9
--- /dev/null
+++ b/drivers/clk/qcom/clock-qcs615.c
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock drivers for Qualcomm qcs615
+ *
+ * (C) Copyright 2024 Linaro Ltd.
+ */
+
+#include <linux/types.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <linux/bug.h>
+#include <linux/bitops.h>
+#include <dt-bindings/clock/qcom,qcs615-gcc.h>
+#include "clock-qcom.h"
+
+#define USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR 0xf034
+#define USB30_PRIM_MASTER_CLK_CMD_RCGR 0xf01c
+#define USB3_PRIM_PHY_AUX_CMD_RCGR 0xf060
+
+#define GCC_QUPV3_WRAP0_S0_CLK_ENA_BIT BIT(10)
+#define GCC_QUPV3_WRAP0_S1_CLK_ENA_BIT BIT(11)
+#define GCC_QUPV3_WRAP0_S2_CLK_ENA_BIT BIT(12)
+#define GCC_QUPV3_WRAP0_S3_CLK_ENA_BIT BIT(13)
+#define GCC_QUPV3_WRAP0_S4_CLK_ENA_BIT BIT(14)
+#define GCC_QUPV3_WRAP0_S5_CLK_ENA_BIT BIT(15)
+
+#define GCC_QUPV3_WRAP1_S0_CLK_ENA_BIT BIT(22)
+#define GCC_QUPV3_WRAP1_S1_CLK_ENA_BIT BIT(23)
+#define GCC_QUPV3_WRAP1_S2_CLK_ENA_BIT BIT(24)
+#define GCC_QUPV3_WRAP1_S3_CLK_ENA_BIT BIT(25)
+#define GCC_QUPV3_WRAP1_S4_CLK_ENA_BIT BIT(26)
+#define GCC_QUPV3_WRAP1_S5_CLK_ENA_BIT BIT(27)
+
+static ulong qcs615_set_rate(struct clk *clk, ulong rate)
+{
+ struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+ if (clk->id < priv->data->num_clks)
+ debug("%s: %s, requested rate=%ld\n", __func__,
+ priv->data->clks[clk->id].name, rate);
+
+ switch (clk->id) {
+ case GCC_USB30_PRIM_MOCK_UTMI_CLK:
+ WARN(rate != 19200000, "Unexpected rate for USB30_PRIM_MOCK_UTMI_CLK: %lu\n", rate);
+ clk_rcg_set_rate(priv->base, USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR, 0, CFG_CLK_SRC_CXO);
+ return rate;
+ case GCC_USB30_PRIM_MASTER_CLK:
+ WARN(rate != 200000000, "Unexpected rate for USB30_PRIM_MASTER_CLK: %lu\n", rate);
+ clk_rcg_set_rate_mnd(priv->base, USB30_PRIM_MASTER_CLK_CMD_RCGR,
+ 5, 0, 0, CFG_CLK_SRC_GPLL0, 8);
+ clk_rcg_set_rate(priv->base, USB3_PRIM_PHY_AUX_CMD_RCGR, 0, 0);
+ return rate;
+ default:
+ return 0;
+ }
+}
+
+static const struct gate_clk qcs615_clks[] = {
+ GATE_CLK(GCC_CFG_NOC_USB3_PRIM_AXI_CLK, 0xf078, BIT(0)),
+ GATE_CLK(GCC_USB30_PRIM_MASTER_CLK, 0xf010, BIT(0)),
+ GATE_CLK(GCC_AGGRE_USB3_PRIM_AXI_CLK, 0xf07c, BIT(0)),
+ GATE_CLK(GCC_USB30_PRIM_SLEEP_CLK, 0xf014, BIT(0)),
+ GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK, 0xf018, BIT(0)),
+ GATE_CLK(GCC_USB3_PRIM_PHY_AUX_CLK, 0xf050, BIT(0)),
+ GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK, 0xf054, BIT(0)),
+ GATE_CLK(GCC_USB3_PRIM_PHY_PIPE_CLK, 0xf058, BIT(0)),
+ GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x5200c, GCC_QUPV3_WRAP0_S0_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x5200c, GCC_QUPV3_WRAP0_S1_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP0_S2_CLK, 0x5200c, GCC_QUPV3_WRAP0_S2_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK, 0x5200c, GCC_QUPV3_WRAP0_S3_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP0_S4_CLK, 0x5200c, GCC_QUPV3_WRAP0_S4_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP0_S5_CLK, 0x5200c, GCC_QUPV3_WRAP0_S5_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP1_S0_CLK, 0x5200c, GCC_QUPV3_WRAP1_S0_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP1_S1_CLK, 0x5200c, GCC_QUPV3_WRAP1_S1_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP1_S2_CLK, 0x5200c, GCC_QUPV3_WRAP1_S2_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP1_S3_CLK, 0x5200c, GCC_QUPV3_WRAP1_S3_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP1_S4_CLK, 0x5200c, GCC_QUPV3_WRAP1_S4_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP1_S5_CLK, 0x5200c, GCC_QUPV3_WRAP1_S5_CLK_ENA_BIT),
+ GATE_CLK(GCC_DISP_HF_AXI_CLK, 0xb038, BIT(0)),
+ GATE_CLK(GCC_DISP_AHB_CLK, 0xb032, BIT(0))
+};
+
+static int qcs615_enable(struct clk *clk)
+{
+ struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+ if (priv->data->num_clks < clk->id) {
+ debug("%s: unknown clk id %lu\n", __func__, clk->id);
+ return 0;
+ }
+
+ debug("%s: clk %ld: %s\n", __func__, clk->id, qcs615_clks[clk->id].name);
+
+ switch (clk->id) {
+ case GCC_AGGRE_USB3_PRIM_AXI_CLK:
+ qcom_gate_clk_en(priv, GCC_USB30_PRIM_MASTER_CLK);
+ fallthrough;
+ case GCC_USB30_PRIM_MASTER_CLK:
+ qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_AUX_CLK);
+ qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_COM_AUX_CLK);
+ break;
+ }
+
+ qcom_gate_clk_en(priv, clk->id);
+
+ return 0;
+}
+
+static const struct qcom_reset_map qcs615_gcc_resets[] = {
+ [GCC_EMAC_BCR] = { 0x6000 },
+ [GCC_QUSB2PHY_PRIM_BCR] = { 0xd000 },
+ [GCC_QUSB2PHY_SEC_BCR] = { 0xd004 },
+ [GCC_USB30_PRIM_BCR] = { 0xf000 },
+ [GCC_USB2_PHY_SEC_BCR] = { 0x50018 },
+ [GCC_USB3_DP_PHY_SEC_BCR] = { 0x50020 },
+ [GCC_USB3PHY_PHY_SEC_BCR] = { 0x5001c },
+ [GCC_PCIE_0_BCR] = { 0x6b000 },
+ [GCC_PCIE_0_PHY_BCR] = { 0x6c01c },
+ [GCC_PCIE_PHY_BCR] = { 0x6f000 },
+ [GCC_PCIE_PHY_COM_BCR] = { 0x6f010 },
+ [GCC_UFS_PHY_BCR] = { 0x77000 },
+ [GCC_USB20_SEC_BCR] = { 0xa6000 },
+ [GCC_USB3PHY_PHY_PRIM_SP0_BCR] = { 0x50008 },
+ [GCC_USB3_PHY_PRIM_SP0_BCR] = { 0x50000 },
+ [GCC_SDCC1_BCR] = { 0x12000 },
+ [GCC_SDCC2_BCR] = { 0x14000 }
+};
+
+static const struct qcom_power_map qcs615_gdscs[] = {
+ [UFS_PHY_GDSC] = { 0x77004 },
+ [USB30_PRIM_GDSC] = { 0xf004 },
+};
+
+static struct msm_clk_data sa8775_gcc_data = {
+ .resets = qcs615_gcc_resets,
+ .num_resets = ARRAY_SIZE(qcs615_gcc_resets),
+ .clks = qcs615_clks,
+ .num_clks = ARRAY_SIZE(qcs615_clks),
+
+ .power_domains = qcs615_gdscs,
+ .num_power_domains = ARRAY_SIZE(qcs615_gdscs),
+
+ .enable = qcs615_enable,
+ .set_rate = qcs615_set_rate,
+};
+
+static const struct udevice_id gcc_qcs615_of_match[] = {
+ {
+ .compatible = "qcom,qcs615-gcc",
+ .data = (ulong)&sa8775_gcc_data,
+ },
+ { }
+};
+
+U_BOOT_DRIVER(gcc_qcs615) = {
+ .name = "gcc_qcs615",
+ .id = UCLASS_NOP,
+ .of_match = gcc_qcs615_of_match,
+ .bind = qcom_cc_bind,
+ .flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
+};
diff --git a/drivers/clk/qcom/clock-qcs8300.c b/drivers/clk/qcom/clock-qcs8300.c
new file mode 100644
index 00000000000..cd8aecdf788
--- /dev/null
+++ b/drivers/clk/qcom/clock-qcs8300.c
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024-2025, Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ */
+
+#include <linux/types.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <linux/bug.h>
+#include <linux/bitops.h>
+#include <dt-bindings/clock/qcom,qcs8300-gcc.h>
+#include "clock-qcom.h"
+
+#define USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR 0xf038
+#define USB30_PRIM_MASTER_CLK_CMD_RCGR 0xf020
+
+static ulong qcs8300_set_rate(struct clk *clk, ulong rate)
+{
+ struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+ if (clk->id < priv->data->num_clks)
+ debug("%s: %s, requested rate=%ld\n",
+ __func__, priv->data->clks[clk->id].name, rate);
+
+ switch (clk->id) {
+ case GCC_USB30_PRIM_MOCK_UTMI_CLK:
+ WARN(rate != 19200000, "Unexpected rate for USB30_PRIM_MOCK_UTMI_CLK: %lu\n", rate);
+ clk_rcg_set_rate(priv->base, USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR, 0, CFG_CLK_SRC_CXO);
+ return rate;
+ case GCC_USB30_PRIM_MASTER_CLK:
+ WARN(rate != 200000000, "Unexpected rate for USB30_PRIM_MASTER_CLK: %lu\n", rate);
+ clk_rcg_set_rate_mnd(priv->base, USB30_PRIM_MASTER_CLK_CMD_RCGR,
+ 1, 0, 0, CFG_CLK_SRC_GPLL0_ODD, 8);
+ clk_rcg_set_rate(priv->base, 0xf064, 0, 0);
+ return rate;
+ default:
+ return 0;
+ }
+}
+
+static const struct gate_clk qcs8300_clks[] = {
+ GATE_CLK(GCC_CFG_NOC_USB3_PRIM_AXI_CLK, 0x1b088, BIT(0)),
+ GATE_CLK(GCC_USB30_PRIM_MASTER_CLK, 0x1b018, BIT(0)),
+ GATE_CLK(GCC_AGGRE_USB3_PRIM_AXI_CLK, 0x1b084, BIT(0)),
+ GATE_CLK(GCC_USB30_PRIM_SLEEP_CLK, 0x1b020, BIT(0)),
+ GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK, 0x1b024, BIT(0)),
+ GATE_CLK(GCC_USB3_PRIM_PHY_AUX_CLK, 0x1b05c, BIT(0)),
+ GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK, 0x1b060, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x83020, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x83018, BIT(0)),
+ GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x830d4, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x83064, BIT(0)),
+};
+
+static int qcs8300_enable(struct clk *clk)
+{
+ struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+ if (priv->data->num_clks < clk->id) {
+ debug("%s: unknown clk id %lu\n", __func__, clk->id);
+ return 0;
+ }
+
+ debug("%s: clk %ld: %s\n", __func__, clk->id, qcs8300_clks[clk->id].name);
+
+ switch (clk->id) {
+ case GCC_AGGRE_USB3_PRIM_AXI_CLK:
+ qcom_gate_clk_en(priv, GCC_USB30_PRIM_MASTER_CLK);
+ fallthrough;
+ case GCC_USB30_PRIM_MASTER_CLK:
+ qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_AUX_CLK);
+ qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_COM_AUX_CLK);
+ break;
+ }
+
+ qcom_gate_clk_en(priv, clk->id);
+
+ return 0;
+}
+
+static const struct qcom_reset_map qcs8300_gcc_resets[] = {
+ [GCC_EMAC0_BCR] = { 0xb6000 },
+ [GCC_PCIE_0_BCR] = { 0xa9000 },
+ [GCC_PCIE_0_LINK_DOWN_BCR] = { 0xbf000 },
+ [GCC_PCIE_0_NOCSR_COM_PHY_BCR] = { 0xbf008 },
+ [GCC_PCIE_0_PHY_BCR] = { 0xa9144 },
+ [GCC_PCIE_0_PHY_NOCSR_COM_PHY_BCR] = { 0xbf00c },
+ [GCC_PCIE_1_BCR] = { 0x77000 },
+ [GCC_PCIE_1_LINK_DOWN_BCR] = { 0xae084 },
+ [GCC_PCIE_1_NOCSR_COM_PHY_BCR] = { 0xae090 },
+ [GCC_PCIE_1_PHY_BCR] = { 0xae08c },
+ [GCC_PCIE_1_PHY_NOCSR_COM_PHY_BCR] = { 0xae094 },
+ [GCC_SDCC1_BCR] = { 0x20000 },
+ [GCC_UFS_PHY_BCR] = { 0x83000 },
+ [GCC_USB20_PRIM_BCR] = { 0x1c000 },
+ [GCC_USB2_PHY_PRIM_BCR] = { 0x5c01c },
+ [GCC_USB2_PHY_SEC_BCR] = { 0x5c020 },
+ [GCC_USB30_PRIM_BCR] = { 0x1b000 },
+ [GCC_USB3_DP_PHY_PRIM_BCR] = { 0x5c008 },
+ [GCC_USB3_PHY_PRIM_BCR] = { 0x5c000 },
+ [GCC_USB3_PHY_TERT_BCR] = { 0x5c024 },
+ [GCC_USB3_UNIPHY_MP0_BCR] = { 0x5c00c },
+ [GCC_USB3_UNIPHY_MP1_BCR] = { 0x5c010 },
+ [GCC_USB3PHY_PHY_PRIM_BCR] = { 0x5c004 },
+ [GCC_USB3UNIPHY_PHY_MP0_BCR] = { 0x5c014 },
+ [GCC_USB3UNIPHY_PHY_MP1_BCR] = { 0x5c018 },
+ [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x76000 },
+ [GCC_VIDEO_BCR] = { 0x34000 },
+};
+
+static const struct qcom_power_map qcs8300_gdscs[] = {
+ [GCC_UFS_PHY_GDSC] = { 0x83004 },
+ [GCC_USB30_PRIM_GDSC] = { 0x1B004 },
+};
+
+static struct msm_clk_data qcs8300_gcc_data = {
+ .resets = qcs8300_gcc_resets,
+ .num_resets = ARRAY_SIZE(qcs8300_gcc_resets),
+ .clks = qcs8300_clks,
+ .num_clks = ARRAY_SIZE(qcs8300_clks),
+
+ .power_domains = qcs8300_gdscs,
+ .num_power_domains = ARRAY_SIZE(qcs8300_gdscs),
+
+ .enable = qcs8300_enable,
+ .set_rate = qcs8300_set_rate,
+};
+
+static const struct udevice_id gcc_qcs8300_of_match[] = {
+ {
+ .compatible = "qcom,qcs8300-gcc",
+ .data = (ulong)&qcs8300_gcc_data,
+ },
+ { }
+};
+
+U_BOOT_DRIVER(gcc_qcs8300) = {
+ .name = "gcc_qcs8300",
+ .id = UCLASS_NOP,
+ .of_match = gcc_qcs8300_of_match,
+ .bind = qcom_cc_bind,
+ .flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
+};
diff --git a/drivers/clk/qcom/clock-sc7280.c b/drivers/clk/qcom/clock-sc7280.c
index 9aff8a847ad..47e0ca5f0e5 100644
--- a/drivers/clk/qcom/clock-sc7280.c
+++ b/drivers/clk/qcom/clock-sc7280.c
@@ -205,7 +205,7 @@ static const char *const sc7280_rcg_names[] = {
"GCC_PCIE_1_AUX_CLK_SRC",
};
-static struct msm_clk_data qcs404_gcc_data = {
+static struct msm_clk_data sc7280_gcc_data = {
.resets = sc7280_gcc_resets,
.num_resets = ARRAY_SIZE(sc7280_gcc_resets),
.clks = sc7280_clks,
@@ -225,7 +225,7 @@ static struct msm_clk_data qcs404_gcc_data = {
static const struct udevice_id gcc_sc7280_of_match[] = {
{
.compatible = "qcom,gcc-sc7280",
- .data = (ulong)&qcs404_gcc_data,
+ .data = (ulong)&sc7280_gcc_data,
},
{ }
};
diff --git a/drivers/clk/qcom/clock-sm8250.c b/drivers/clk/qcom/clock-sm8250.c
index 26396847d85..cc481258d22 100644
--- a/drivers/clk/qcom/clock-sm8250.c
+++ b/drivers/clk/qcom/clock-sm8250.c
@@ -360,7 +360,7 @@ static const char *const sm8250_rcg_names[] = {
"GCC_PCIE_2_AUX_CMD_RCGR",
};
-static struct msm_clk_data qcs404_gcc_data = {
+static struct msm_clk_data sm8250_gcc_data = {
.resets = sm8250_gcc_resets,
.num_resets = ARRAY_SIZE(sm8250_gcc_resets),
.clks = sm8250_clks,
@@ -381,7 +381,7 @@ static struct msm_clk_data qcs404_gcc_data = {
static const struct udevice_id gcc_sm8250_of_match[] = {
{
.compatible = "qcom,gcc-sm8250",
- .data = (ulong)&qcs404_gcc_data,
+ .data = (ulong)&sm8250_gcc_data,
},
{}
};
diff --git a/drivers/dfu/dfu_scsi.c b/drivers/dfu/dfu_scsi.c
index 7ec34a8f7e3..d99b05d23ac 100644
--- a/drivers/dfu/dfu_scsi.c
+++ b/drivers/dfu/dfu_scsi.c
@@ -342,11 +342,6 @@ int dfu_fill_entity_scsi(struct dfu_entity *dfu, char *devstr, char **argv, int
return -EINVAL;
}
- if (scsi_scan(false)) {
- pr_err("Couldn't init scsi device.\n");
- return -ENODEV;
- }
-
ret = find_scsi_device(dfu->data.scsi.lun, &scsi);
if (ret < 0) {
pr_err("Couldn't find scsi device no. %d.\n", dfu->data.scsi.lun);
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 8789b1ea141..a094e6c3afe 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -29,6 +29,7 @@ config TI_SCI_PROTOCOL
config ZYNQMP_FIRMWARE
bool "ZynqMP Firmware interface"
+ depends on ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET || ARCH_VERSAL2
select FIRMWARE
help
Firmware interface driver is used by different
diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c
index 2940181e83e..d18ae523b6b 100644
--- a/drivers/firmware/firmware-zynqmp.c
+++ b/drivers/firmware/firmware-zynqmp.c
@@ -422,6 +422,30 @@ U_BOOT_DRIVER(zynqmp_power) = {
};
#endif
+smc_call_handler_t __data smc_call_handler;
+
+static int smc_call_legacy(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
+ u32 arg3, u32 *ret_payload)
+{
+ struct pt_regs regs;
+
+ regs.regs[0] = PM_SIP_SVC | api_id;
+ regs.regs[1] = ((u64)arg1 << 32) | arg0;
+ regs.regs[2] = ((u64)arg3 << 32) | arg2;
+
+ smc_call(&regs);
+
+ if (ret_payload) {
+ ret_payload[0] = (u32)regs.regs[0];
+ ret_payload[1] = upper_32_bits(regs.regs[0]);
+ ret_payload[2] = (u32)regs.regs[1];
+ ret_payload[3] = upper_32_bits(regs.regs[1]);
+ ret_payload[4] = (u32)regs.regs[2];
+ }
+
+ return (ret_payload) ? ret_payload[0] : 0;
+}
+
int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
u32 arg3, u32 *ret_payload)
{
@@ -450,38 +474,20 @@ int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
PAYLOAD_ARG_CNT);
if (ret)
return ret;
+
+ return (ret_payload) ? ret_payload[0] : 0;
#else
return -EPERM;
#endif
- } else {
- /*
- * Added SIP service call Function Identifier
- * Make sure to stay in x0 register
- */
- struct pt_regs regs;
-
- regs.regs[0] = PM_SIP_SVC | api_id;
- regs.regs[1] = ((u64)arg1 << 32) | arg0;
- regs.regs[2] = ((u64)arg3 << 32) | arg2;
-
- smc_call(&regs);
-
- if (ret_payload) {
- ret_payload[0] = (u32)regs.regs[0];
- ret_payload[1] = upper_32_bits(regs.regs[0]);
- ret_payload[2] = (u32)regs.regs[1];
- ret_payload[3] = upper_32_bits(regs.regs[1]);
- ret_payload[4] = (u32)regs.regs[2];
- }
-
}
- return (ret_payload) ? ret_payload[0] : 0;
+
+ return smc_call_handler(api_id, arg0, arg1, arg2, arg3, ret_payload);
}
static const struct udevice_id zynqmp_firmware_ids[] = {
- { .compatible = "xlnx,zynqmp-firmware" },
- { .compatible = "xlnx,versal-firmware"},
- { .compatible = "xlnx,versal-net-firmware"},
+ { .compatible = "xlnx,zynqmp-firmware", .data = (ulong)smc_call_legacy },
+ { .compatible = "xlnx,versal-firmware", .data = (ulong)smc_call_legacy},
+ { .compatible = "xlnx,versal-net-firmware", .data = (ulong)smc_call_legacy },
{ }
};
@@ -490,6 +496,10 @@ static int zynqmp_firmware_bind(struct udevice *dev)
int ret;
struct udevice *child;
+ smc_call_handler = (smc_call_handler_t)dev_get_driver_data(dev);
+ if (!smc_call_handler)
+ return -EINVAL;
+
if ((IS_ENABLED(CONFIG_XPL_BUILD) &&
IS_ENABLED(CONFIG_SPL_POWER_DOMAIN) &&
IS_ENABLED(CONFIG_ZYNQMP_POWER_DOMAIN)) ||
diff --git a/drivers/fpga/intel_sdm_mb.c b/drivers/fpga/intel_sdm_mb.c
index a2f3b160a73..5f4aae47d6d 100644
--- a/drivers/fpga/intel_sdm_mb.c
+++ b/drivers/fpga/intel_sdm_mb.c
@@ -687,7 +687,8 @@ static int send_bitstream(const void *rbf_data, size_t rbf_size)
debug("wr_ret = %d, rbf_data = %p, buf_size = %08lx\n",
wr_ret, rbf_data, buf_size);
- if (wr_ret)
+ if (wr_ret != INTEL_SIP_SMC_STATUS_OK &&
+ wr_ret != INTEL_SIP_SMC_STATUS_BUSY)
continue;
rbf_size -= buf_size;
diff --git a/drivers/gpio/msm_gpio.c b/drivers/gpio/msm_gpio.c
index 6783fc756f4..7de332c66ae 100644
--- a/drivers/gpio/msm_gpio.c
+++ b/drivers/gpio/msm_gpio.c
@@ -202,7 +202,7 @@ static int msm_gpio_get_value(struct udevice *dev, unsigned int gpio)
if (qcom_is_special_pin(priv->pin_data, gpio))
return msm_gpio_get_value_special(priv, gpio);
- return !!(readl(priv->base + GPIO_IN_OUT_REG(dev, gpio)) >> GPIO_IN);
+ return !!(readl(priv->base + GPIO_IN_OUT_REG(dev, gpio)) & BIT(GPIO_IN));
}
static int msm_gpio_get_function_special(struct msm_gpio_bank *priv,
diff --git a/drivers/i2c/muxes/i2c-mux-uclass.c b/drivers/i2c/muxes/i2c-mux-uclass.c
index d1999d21feb..012881de05b 100644
--- a/drivers/i2c/muxes/i2c-mux-uclass.c
+++ b/drivers/i2c/muxes/i2c-mux-uclass.c
@@ -40,6 +40,11 @@ static int i2c_mux_child_post_bind(struct udevice *dev)
struct i2c_mux_bus *plat = dev_get_parent_plat(dev);
int channel;
+ ofnode node = dev_ofnode(dev);
+
+ if (!ofnode_has_property(node, "reg"))
+ return 0;
+
channel = dev_read_u32_default(dev, "reg", -1);
if (channel < 0)
return -EINVAL;
diff --git a/drivers/mmc/rpmb.c b/drivers/mmc/rpmb.c
index fa3ac2d9e37..8bfdffd56f5 100644
--- a/drivers/mmc/rpmb.c
+++ b/drivers/mmc/rpmb.c
@@ -11,7 +11,7 @@
#include <log.h>
#include <memalign.h>
#include <mmc.h>
-#include <sdhci.h>
+#include <asm/byteorder.h>
#include <u-boot/sha256.h>
#include "mmc_private.h"
@@ -91,7 +91,6 @@ static int mmc_rpmb_request(struct mmc *mmc, const struct s_rpmb *s,
{
struct mmc_cmd cmd = {0};
struct mmc_data data;
- struct sdhci_host *host = mmc->priv;
int ret;
ret = mmc_set_blockcount(mmc, count, is_rel_write);
@@ -106,9 +105,6 @@ static int mmc_rpmb_request(struct mmc *mmc, const struct s_rpmb *s,
cmd.cmdarg = 0;
cmd.resp_type = MMC_RSP_R1;
- if (host->quirks & SDHCI_QUIRK_BROKEN_R1B)
- cmd.resp_type = MMC_RSP_R1;
-
data.src = (const char *)s;
data.blocks = 1;
data.blocksize = MMC_MAX_BLOCK_LEN;
diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c
index 9dc1ceaa09b..3b86bc9b18c 100644
--- a/drivers/mmc/socfpga_dw_mmc.c
+++ b/drivers/mmc/socfpga_dw_mmc.c
@@ -54,16 +54,30 @@ 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);
+ /* Get clock manager base address */
+ struct udevice *clkmgr_dev;
+ int ret = uclass_get_device_by_name(UCLASS_CLK, "clock-controller@ffd10000", &clkmgr_dev);
+
+ if (ret) {
+ printf("Failed to get clkmgr device: %d\n", ret);
+ return ret;
+ }
+
+ fdt_addr_t clkmgr_base = dev_read_addr(clkmgr_dev);
+
+ if (clkmgr_base == FDT_ADDR_T_NONE) {
+ printf("Failed to read base address from clkmgr DT node\n");
+ return -EINVAL;
+ }
+
/* Disable SDMMC clock. */
- clrbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_PERPLL_EN,
+ clrbits_le32(clkmgr_base + CLKMGR_PERPLL_EN,
CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK);
debug("%s: drvsel %d smplsel %d\n", __func__,
priv->drvsel, priv->smplsel);
#if !defined(CONFIG_XPL_BUILD) && defined(CONFIG_SPL_ATF)
- int ret;
-
ret = socfpga_secure_reg_write32(SOCFPGA_SECURE_REG_SYSMGR_SOC64_SDMMC,
sdmmc_mask);
if (ret) {
@@ -78,7 +92,7 @@ static int socfpga_dwmci_clksel(struct dwmci_host *host)
#endif
/* Enable SDMMC clock */
- setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_PERPLL_EN,
+ setbits_le32(clkmgr_base + CLKMGR_PERPLL_EN,
CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK);
return 0;
diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index 2375b15539b..3b682918b03 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -1127,6 +1127,28 @@ static int arasan_sdhci_probe(struct udevice *dev)
if (arasan_sdhci_is_compatible(dev, SDHCI_COMPATIBLE_VERSAL_NET_EMMC))
priv->internal_phy_reg = true;
+ ret = reset_get_bulk(dev, &priv->resets);
+ if (ret == -ENOTSUPP || ret == -ENOENT) {
+ dev_warn(dev, "Reset not found\n");
+ } else if (ret) {
+ dev_err(dev, "Reset failed\n");
+ return ret;
+ }
+
+ if (!ret) {
+ ret = reset_assert_bulk(&priv->resets);
+ if (ret) {
+ dev_err(dev, "Reset assert failed\n");
+ return ret;
+ }
+
+ ret = reset_deassert_bulk(&priv->resets);
+ if (ret) {
+ dev_err(dev, "Reset release failed\n");
+ return ret;
+ }
+ }
+
ret = clk_get_by_index(dev, 0, &clk);
if (ret < 0) {
dev_err(dev, "failed to get clock\n");
diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
index f2ecf47f8d4..fe8c76acac6 100644
--- a/drivers/mtd/nand/spi/gigadevice.c
+++ b/drivers/mtd/nand/spi/gigadevice.c
@@ -43,6 +43,22 @@ static SPINAND_OP_VARIANTS(read_cache_variants_f,
SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0),
SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0));
+static SPINAND_OP_VARIANTS(read_cache_variants_1gq5,
+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
+
+static SPINAND_OP_VARIANTS(read_cache_variants_2gq5,
+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 4, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 2, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
+
static SPINAND_OP_VARIANTS(write_cache_variants,
SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
SPINAND_PROG_LOAD(true, 0, NULL, 0));
@@ -329,6 +345,36 @@ static const struct spinand_info gigadevice_spinand_table[] = {
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
gd5fxgq4uexxg_ecc_get_status)),
+ SPINAND_INFO("GD5F1GQ4RExxG",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc1),
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+ gd5fxgq4uexxg_ecc_get_status)),
+ SPINAND_INFO("GD5F2GQ4UExxG",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd2),
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+ gd5fxgq4uexxg_ecc_get_status)),
+ SPINAND_INFO("GD5F2GQ4RExxG",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc2),
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+ gd5fxgq4uexxg_ecc_get_status)),
SPINAND_INFO("GD5F1GQ4UFxxG",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
@@ -343,12 +389,152 @@ static const struct spinand_info gigadevice_spinand_table[] = {
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(4, 512),
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+ gd5fxgq5xexxg_ecc_get_status)),
+ SPINAND_INFO("GD5F1GQ5RExxG",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x41),
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
+ NAND_ECCREQ(4, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+ gd5fxgq5xexxg_ecc_get_status)),
+ SPINAND_INFO("GD5F2GQ5UExxG",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x52),
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
+ NAND_ECCREQ(4, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+ gd5fxgq5xexxg_ecc_get_status)),
+ SPINAND_INFO("GD5F2GQ5RExxG",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x42),
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
+ NAND_ECCREQ(4, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+ gd5fxgq5xexxg_ecc_get_status)),
+ SPINAND_INFO("GD5F4GQ6UExxG",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x55),
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1),
+ NAND_ECCREQ(4, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+ gd5fxgq5xexxg_ecc_get_status)),
+ SPINAND_INFO("GD5F4GQ6RExxG",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x45),
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1),
+ NAND_ECCREQ(4, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
&write_cache_variants,
&update_cache_variants),
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
gd5fxgq5xexxg_ecc_get_status)),
+ SPINAND_INFO("GD5F1GM7UExxG",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x91),
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+ gd5fxgq4uexxg_ecc_get_status)),
+ SPINAND_INFO("GD5F1GM7RExxG",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x81),
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+ gd5fxgq4uexxg_ecc_get_status)),
+ SPINAND_INFO("GD5F2GM7UExxG",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92),
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+ gd5fxgq4uexxg_ecc_get_status)),
+ SPINAND_INFO("GD5F2GM7RExxG",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x82),
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+ gd5fxgq4uexxg_ecc_get_status)),
+ SPINAND_INFO("GD5F4GM8UExxG",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x95),
+ NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+ gd5fxgq4uexxg_ecc_get_status)),
+ SPINAND_INFO("GD5F4GM8RExxG",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x85),
+ NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+ gd5fxgq4uexxg_ecc_get_status)),
+ SPINAND_INFO("GD5F2GQ5xExxH",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22),
+ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
+ NAND_ECCREQ(4, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+ gd5fxgq4uexxg_ecc_get_status)),
+ SPINAND_INFO("GD5F1GQ5RExxH",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x21),
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
+ NAND_ECCREQ(4, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+ gd5fxgq4uexxg_ecc_get_status)),
+ SPINAND_INFO("GD5F1GQ4RExxH",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xc9),
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
+ NAND_ECCREQ(4, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+ gd5fxgq4uexxg_ecc_get_status)),
};
static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 0f93c25e3fe..fce3ef910cb 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -716,7 +716,7 @@ static int _dw_free_pkt(struct dw_eth_dev *priv)
ulong desc_start = (ulong)desc_p;
ulong desc_end = desc_start +
roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
- ulong data_start = desc_p->dmamac_addr;
+ ulong data_start = dev_bus_to_phys(priv->dev, desc_p->dmamac_addr);
ulong data_end = data_start + roundup(CFG_ETH_BUFSIZE, ARCH_DMA_MINALIGN);
/* Invalidate the descriptor buffer data */
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 409049137cc..8ffd88c722d 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -389,6 +389,16 @@ config PCIE_DW_QCOM
Say Y here if you want to enable DW PCIe controller support on
Qualcomm SoCs.
+config PCI_RCAR_GEN4
+ bool "Renesas R-Car Gen4 PCIe driver"
+ depends on RCAR_GEN4
+ select DM_RESET
+ select DM_GPIO
+ select PCIE_DW_COMMON
+ help
+ Say Y here if you want to enable PCIe controller support on
+ Renesas R-Car Gen4 SoCs.
+
config PCIE_ROCKCHIP
bool "Enable Rockchip PCIe driver"
depends on ARCH_ROCKCHIP
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index ba53f594963..a0420e733ed 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_PCIE_IMX) += pcie_imx.o
obj-$(CONFIG_PCI_MVEBU) += pci_mvebu.o
obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
obj-$(CONFIG_PCI_RCAR_GEN3) += pci-rcar-gen3.o
+obj-$(CONFIG_PCI_RCAR_GEN4) += pci-rcar-gen4.o
obj-$(CONFIG_SH7751_PCI) +=pci_sh7751.o
obj-$(CONFIG_PCI_TEGRA) += pci_tegra.o
obj-$(CONFIG_PCIE_IPROC) += pcie_iproc.o
diff --git a/drivers/pci/pci-rcar-gen4.c b/drivers/pci/pci-rcar-gen4.c
new file mode 100644
index 00000000000..87cd69f989d
--- /dev/null
+++ b/drivers/pci/pci-rcar-gen4.c
@@ -0,0 +1,565 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * PCIe controller driver for Renesas R-Car Gen4 Series SoCs
+ * Copyright (C) 2025 Marek Vasut <marek.vasut+renesas@mailbox.org>
+ * Based on Linux kernel driver
+ * Copyright (C) 2022-2023 Renesas Electronics Corporation
+ *
+ * The r8a779g0 (R-Car V4H) controller requires a specific firmware to be
+ * provided, to initialize the PHY. Otherwise, the PCIe controller will not
+ * work.
+ */
+
+#include <asm-generic/gpio.h>
+#include <asm/arch/gpio.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <clk.h>
+#include <command.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <env.h>
+#include <log.h>
+#include <reset.h>
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/iopoll.h>
+
+#include "pcie_dw_common.h"
+
+/* Renesas-specific */
+/* PCIe Mode Setting Register 0 */
+#define PCIEMSR0 0x0000
+#define APP_SRIS_MODE BIT(6)
+#define DEVICE_TYPE_EP 0
+#define DEVICE_TYPE_RC BIT(4)
+#define BIFUR_MOD_SET_ON BIT(0)
+
+/* PCIe Interrupt Status 0 */
+#define PCIEINTSTS0 0x0084
+
+/* PCIe Interrupt Status 0 Enable */
+#define PCIEINTSTS0EN 0x0310
+#define MSI_CTRL_INT BIT(26)
+#define SMLH_LINK_UP BIT(7)
+#define RDLH_LINK_UP BIT(6)
+
+/* PCIe DMA Interrupt Status Enable */
+#define PCIEDMAINTSTSEN 0x0314
+#define PCIEDMAINTSTSEN_INIT GENMASK(15, 0)
+
+/* Port Logic Registers 89 */
+#define PRTLGC89 0x0b70
+
+/* Port Logic Registers 90 */
+#define PRTLGC90 0x0b74
+
+/* PCIe Reset Control Register 1 */
+#define PCIERSTCTRL1 0x0014
+#define APP_HOLD_PHY_RST BIT(16)
+#define APP_LTSSM_ENABLE BIT(0)
+
+/* PCIe Power Management Control */
+#define PCIEPWRMNGCTRL 0x0070
+#define APP_CLK_REQ_N BIT(11)
+#define APP_CLK_PM_EN BIT(10)
+
+#define RCAR_NUM_SPEED_CHANGE_RETRIES 10
+#define RCAR_MAX_LINK_SPEED 4
+
+#define RCAR_GEN4_PCIE_EP_FUNC_DBI_OFFSET 0x1000
+#define RCAR_GEN4_PCIE_EP_FUNC_DBI2_OFFSET 0x800
+
+#define RCAR_GEN4_PCIE_FIRMWARE_NAME "rcar_gen4_pcie.bin"
+#define RCAR_GEN4_PCIE_FIRMWARE_BASE_ADDR 0xc000
+
+#define PCIE_T_PVPERL_MS 100
+
+/**
+ * struct rcar_gen4_pcie - Renesas R-Car Gen4 DW PCIe controller state
+ *
+ * @rcar: The common PCIe DW structure
+ * @pwr_rst: The PWR reset of the PCIe core
+ * @core_clk: The core clock of the PCIe core
+ * @ref_clk: The reference clock of the PCIe core and possibly bus
+ * @pe_rst: PERST GPIO
+ * @app_base: The base address of application register space
+ * @dbi2_base: The base address of DBI2 register space
+ * @phy_base: The base address of PHY register space
+ * @max_link_speed: Maximum PCIe link speed supported by the setup
+ * @num_lanes: Number of PCIe lanes used by the setup
+ * @firmware: PHY firmware
+ * @firmware_size: PHY firmware size in Bytes
+ */
+struct rcar_gen4_pcie {
+ /* Must be first member of the struct */
+ struct pcie_dw dw;
+ struct reset_ctl pwr_rst;
+ struct clk *core_clk;
+ struct clk *ref_clk;
+ struct gpio_desc pe_rst;
+ void *app_base;
+ void *dbi2_base;
+ void *phy_base;
+ u32 max_link_speed;
+ u32 num_lanes;
+ u16 *firmware;
+ u32 firmware_size;
+};
+
+/* Common */
+static bool rcar_gen4_pcie_link_up(struct rcar_gen4_pcie *rcar)
+{
+ u32 val, mask;
+
+ val = readl(rcar->app_base + PCIEINTSTS0);
+ mask = RDLH_LINK_UP | SMLH_LINK_UP;
+
+ return (val & mask) == mask;
+}
+
+/*
+ * Manually initiate the speed change. Return 0 if change succeeded; otherwise
+ * -ETIMEDOUT.
+ */
+static int rcar_gen4_pcie_speed_change(struct rcar_gen4_pcie *rcar)
+{
+ u32 val;
+ int i;
+
+ clrbits_le32(rcar->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL,
+ PORT_LOGIC_SPEED_CHANGE);
+
+ setbits_le32(rcar->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL,
+ PORT_LOGIC_SPEED_CHANGE);
+
+ for (i = 0; i < RCAR_NUM_SPEED_CHANGE_RETRIES; i++) {
+ val = readl(rcar->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
+ if (!(val & PORT_LOGIC_SPEED_CHANGE))
+ return 0;
+ mdelay(10);
+ }
+
+ return -ETIMEDOUT;
+}
+
+/*
+ * SoC datasheet suggests checking port logic register bits during firmware
+ * write. If read returns non-zero value, then this function returns -EAGAIN
+ * indicating that the write needs to be done again. If read returns zero,
+ * then return 0 to indicate success.
+ */
+static int rcar_gen4_pcie_reg_test_bit(struct rcar_gen4_pcie *rcar,
+ u32 offset, u32 mask)
+{
+ if (readl(rcar->dw.dbi_base + offset) & mask)
+ return -EAGAIN;
+
+ return 0;
+}
+
+static int rcar_gen4_pcie_download_phy_firmware(struct rcar_gen4_pcie *rcar)
+{
+ /* The check_addr values are magical numbers in the datasheet */
+ static const u32 check_addr[] = {
+ 0x00101018,
+ 0x00101118,
+ 0x00101021,
+ 0x00101121,
+ };
+ unsigned int i, timeout;
+ u32 data;
+ int ret;
+
+ for (i = 0; i < rcar->firmware_size / 2; i++) {
+ data = rcar->firmware[i];
+ timeout = 100;
+ do {
+ writel(RCAR_GEN4_PCIE_FIRMWARE_BASE_ADDR + i, rcar->dw.dbi_base + PRTLGC89);
+ writel(data, rcar->dw.dbi_base + PRTLGC90);
+ if (!rcar_gen4_pcie_reg_test_bit(rcar, PRTLGC89, BIT(30)))
+ break;
+ if (!(--timeout))
+ return -ETIMEDOUT;
+ udelay(100);
+ } while (1);
+ }
+
+ setbits_le32(rcar->phy_base + 0x0f8, BIT(17));
+
+ for (i = 0; i < ARRAY_SIZE(check_addr); i++) {
+ timeout = 100;
+ do {
+ writel(check_addr[i], rcar->dw.dbi_base + PRTLGC89);
+ ret = rcar_gen4_pcie_reg_test_bit(rcar, PRTLGC89, BIT(30));
+ ret |= rcar_gen4_pcie_reg_test_bit(rcar, PRTLGC90, BIT(0));
+ if (!ret)
+ break;
+ if (!(--timeout))
+ return -ETIMEDOUT;
+ udelay(100);
+ } while (1);
+ }
+
+ return ret;
+}
+
+static int rcar_gen4_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable)
+{
+ u32 val;
+ int ret;
+
+ if (!enable) {
+ clrbits_le32(rcar->app_base + PCIERSTCTRL1, APP_LTSSM_ENABLE);
+ return 0;
+ }
+
+ setbits_le32(rcar->dw.dbi_base + PCIE_PORT_FORCE,
+ PORT_FORCE_DO_DESKEW_FOR_SRIS);
+
+ setbits_le32(rcar->app_base + PCIEMSR0, APP_SRIS_MODE);
+
+ /*
+ * The R-Car Gen4 datasheet doesn't describe the PHY registers' name.
+ * But, the initialization procedure describes these offsets. So,
+ * this driver has magical offset numbers.
+ */
+ clrsetbits_le32(rcar->phy_base + 0x700, BIT(28), 0);
+ clrsetbits_le32(rcar->phy_base + 0x700, BIT(20), 0);
+ clrsetbits_le32(rcar->phy_base + 0x700, BIT(12), 0);
+ clrsetbits_le32(rcar->phy_base + 0x700, BIT(4), 0);
+
+ clrsetbits_le32(rcar->phy_base + 0x148, GENMASK(23, 22), BIT(22));
+ clrsetbits_le32(rcar->phy_base + 0x148, GENMASK(18, 16), GENMASK(17, 16));
+ clrsetbits_le32(rcar->phy_base + 0x148, GENMASK(7, 6), BIT(6));
+ clrsetbits_le32(rcar->phy_base + 0x148, GENMASK(2, 0), GENMASK(11, 0));
+ clrsetbits_le32(rcar->phy_base + 0x1d4, GENMASK(16, 15), GENMASK(16, 15));
+ clrsetbits_le32(rcar->phy_base + 0x514, BIT(26), BIT(26));
+ clrsetbits_le32(rcar->phy_base + 0x0f8, BIT(16), 0);
+ clrsetbits_le32(rcar->phy_base + 0x0f8, BIT(19), BIT(19));
+
+ clrbits_le32(rcar->app_base + PCIERSTCTRL1, APP_HOLD_PHY_RST);
+
+ ret = readl_poll_timeout(rcar->phy_base + 0x0f8, val, !(val & BIT(18)), 10000);
+ if (ret < 0)
+ return ret;
+
+ ret = rcar_gen4_pcie_download_phy_firmware(rcar);
+ if (ret)
+ return ret;
+
+ setbits_le32(rcar->app_base + PCIERSTCTRL1, APP_LTSSM_ENABLE);
+
+ return 0;
+}
+
+/*
+ * Enable LTSSM of this controller and manually initiate the speed change.
+ * Always return 0.
+ */
+static int rcar_gen4_pcie_start_link(struct rcar_gen4_pcie *rcar)
+{
+ int i, ret;
+
+ ret = rcar_gen4_pcie_ltssm_control(rcar, true);
+ if (ret)
+ return ret;
+
+ /*
+ * Require direct speed change with retrying here if the max_link_speed
+ * is PCIe Gen2 or higher.
+ */
+ if (rcar->max_link_speed == LINK_SPEED_GEN_1)
+ return 0;
+
+ for (i = 0; i < RCAR_MAX_LINK_SPEED; i++) {
+ /* It may not be connected in EP mode yet. So, break the loop */
+ if (rcar_gen4_pcie_speed_change(rcar))
+ break;
+ }
+
+ return 0;
+}
+
+static void rcar_gen4_pcie_additional_common_init(struct rcar_gen4_pcie *rcar)
+{
+ clrsetbits_le32(rcar->dw.dbi_base + PCIE_PORT_LANE_SKEW,
+ PORT_LANE_SKEW_INSERT_MASK,
+ (rcar->num_lanes < 4) ? BIT(6) : 0);
+
+ setbits_le32(rcar->app_base + PCIEPWRMNGCTRL,
+ APP_CLK_REQ_N | APP_CLK_PM_EN);
+}
+
+static int rcar_gen4_pcie_common_init(struct rcar_gen4_pcie *rcar)
+{
+ int ret;
+
+ ret = clk_prepare_enable(rcar->core_clk);
+ if (ret)
+ return ret;
+
+ ret = reset_assert(&rcar->pwr_rst);
+ if (ret)
+ goto err_unprepare;
+
+ setbits_le32(rcar->app_base + PCIEMSR0,
+ DEVICE_TYPE_RC |
+ ((rcar->num_lanes < 4) ? BIFUR_MOD_SET_ON : 0));
+
+ ret = reset_deassert(&rcar->pwr_rst);
+ if (ret)
+ goto err_unprepare;
+
+ rcar_gen4_pcie_additional_common_init(rcar);
+
+ return 0;
+
+err_unprepare:
+ clk_disable_unprepare(rcar->core_clk);
+
+ return ret;
+}
+
+/* Host mode */
+static int rcar_gen4_pcie_host_init(struct udevice *dev)
+{
+ struct rcar_gen4_pcie *rcar = dev_get_priv(dev);
+ int ret;
+
+ dm_gpio_set_value(&rcar->pe_rst, 1);
+
+ ret = rcar_gen4_pcie_common_init(rcar);
+ if (ret)
+ return ret;
+
+ /*
+ * According to the section 3.5.7.2 "RC Mode" in DWC PCIe Dual Mode
+ * Rev.5.20a and 3.5.6.1 "RC mode" in DWC PCIe RC databook v5.20a, we
+ * should disable two BARs to avoid unnecessary memory assignment
+ * during device enumeration.
+ */
+ writel(0x0, rcar->dbi2_base + PCI_BASE_ADDRESS_0);
+ writel(0x0, rcar->dbi2_base + PCI_BASE_ADDRESS_1);
+
+ /* Disable MSI interrupt signal */
+ clrbits_le32(rcar->app_base + PCIEINTSTS0EN, MSI_CTRL_INT);
+
+ mdelay(PCIE_T_PVPERL_MS); /* pe_rst requires 100msec delay */
+
+ dm_gpio_set_value(&rcar->pe_rst, 0);
+
+ return 0;
+}
+
+static int rcar_gen4_pcie_load_firmware(struct rcar_gen4_pcie *rcar)
+{
+ ulong addr, size;
+ int ret;
+
+ /*
+ * Run user specified firmware loading script, which loads the
+ * firmware from whichever location the user decides it should
+ * load the firmware from, by whatever means the user decides.
+ */
+ ret = run_command_list("run renesas_rcar_gen4_load_firmware", -1, 0);
+ if (ret) {
+ printf("Firmware loading script 'renesas_rcar_gen4_load_firmware' not defined or failed.\n");
+ goto fail;
+ }
+
+ /* Find out where the firmware got loaded and how long it is. */
+ addr = env_get_hex("renesas_rcar_gen4_load_firmware_addr", 0);
+ size = env_get_hex("renesas_rcar_gen4_load_firmware_size", 0);
+
+ /*
+ * Clear the variables set by the firmware loading script, as
+ * their content would become stale once this function exits.
+ */
+ env_set("renesas_rcar_gen4_load_firmware_addr", NULL);
+ env_set("renesas_rcar_gen4_load_firmware_size", NULL);
+
+ if (!addr || !size) {
+ printf("Firmware address (%lx) or size (%lx) are invalid.\n", addr, size);
+ goto fail;
+ }
+
+ /* Create local copy of the loaded firmware. */
+ rcar->firmware = (u16 *)memdup((void *)addr, size);
+ if (!rcar->firmware)
+ return -ENOMEM;
+
+ rcar->firmware_size = size;
+
+ return 0;
+
+fail:
+ printf("Define 'renesas_rcar_gen4_load_firmware' script which loads the R-Car\n"
+ "Gen4 PCIe controller firmware from storage into memory and sets these\n"
+ "two environment variables:\n"
+ " renesas_rcar_gen4_load_firmware_addr ... address of firmware in memory\n"
+ " renesas_rcar_gen4_load_firmware_size ... length of firmware in bytes\n"
+ "\n"
+ "Example:\n"
+ " => env set renesas_rcar_gen4_load_firmware 'env set renesas_rcar_gen4_load_firmware_addr 0x54000000 && load mmc 0:1 ${renesas_rcar_gen4_load_firmware_addr} lib/firmware/rcar_gen4_pcie.bin && env set renesas_rcar_gen4_load_firmware_size ${filesize}'\n"
+ );
+ return -EINVAL;
+}
+
+/**
+ * rcar_gen4_pcie_probe() - Probe the PCIe bus for active link
+ *
+ * @dev: A pointer to the device being operated on
+ *
+ * Probe for an active link on the PCIe bus and configure the controller
+ * to enable this port.
+ *
+ * Return: 0 on success, else -ENODEV
+ */
+static int rcar_gen4_pcie_probe(struct udevice *dev)
+{
+ struct rcar_gen4_pcie *rcar = dev_get_priv(dev);
+ struct udevice *ctlr = pci_get_controller(dev);
+ struct pci_controller *hose = dev_get_uclass_priv(ctlr);
+ int ret;
+
+ ret = rcar_gen4_pcie_load_firmware(rcar);
+ if (ret)
+ return ret;
+
+ rcar->dw.first_busno = dev_seq(dev);
+ rcar->dw.dev = dev;
+
+ ret = reset_get_by_name(dev, "pwr", &rcar->pwr_rst);
+ if (ret)
+ return ret;
+
+ rcar->core_clk = devm_clk_get(dev, "core");
+ if (IS_ERR(rcar->core_clk))
+ return PTR_ERR(rcar->core_clk);
+
+ rcar->ref_clk = devm_clk_get(dev, "ref");
+ if (IS_ERR(rcar->ref_clk))
+ return PTR_ERR(rcar->ref_clk);
+
+ ret = clk_prepare_enable(rcar->ref_clk);
+ if (ret)
+ return ret;
+
+ ret = gpio_request_by_name(dev, "reset-gpios", 0, &rcar->pe_rst,
+ GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+ if (ret)
+ return ret;
+
+ ret = rcar_gen4_pcie_host_init(dev);
+ if (ret)
+ return ret;
+
+ pcie_dw_setup_host(&rcar->dw);
+
+ dw_pcie_dbi_write_enable(&rcar->dw, true);
+
+ dw_pcie_link_set_max_link_width(&rcar->dw, rcar->num_lanes);
+
+ ret = rcar_gen4_pcie_start_link(rcar);
+ if (ret)
+ return ret;
+
+ dw_pcie_dbi_write_enable(&rcar->dw, false);
+
+ if (!rcar_gen4_pcie_link_up(rcar)) {
+ printf("PCIE-%d: Link down\n", dev_seq(dev));
+ return -ENODEV;
+ }
+
+ printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n", dev_seq(dev),
+ pcie_dw_get_link_speed(&rcar->dw),
+ pcie_dw_get_link_width(&rcar->dw),
+ hose->first_busno);
+
+ pcie_dw_prog_outbound_atu_unroll(&rcar->dw, PCIE_ATU_REGION_INDEX0,
+ PCIE_ATU_TYPE_MEM,
+ rcar->dw.mem.phys_start,
+ rcar->dw.mem.bus_start, rcar->dw.mem.size);
+
+ return 0;
+}
+
+/**
+ * rcar_gen4_pcie_of_to_plat() - Translate from DT to device state
+ *
+ * @dev: A pointer to the device being operated on
+ *
+ * Translate relevant data from the device tree pertaining to device @dev into
+ * state that the driver will later make use of. This state is stored in the
+ * device's private data structure.
+ *
+ * Return: 0 on success, else -EINVAL
+ */
+static int rcar_gen4_pcie_of_to_plat(struct udevice *dev)
+{
+ struct rcar_gen4_pcie *rcar = dev_get_priv(dev);
+
+ /* Get the controller base address */
+ rcar->dw.dbi_base = (void *)dev_read_addr_name(dev, "dbi");
+ if ((fdt_addr_t)rcar->dw.dbi_base == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ /* Get the config space base address and size */
+ rcar->dw.cfg_base = (void *)dev_read_addr_size_name(dev, "config",
+ &rcar->dw.cfg_size);
+ if ((fdt_addr_t)rcar->dw.cfg_base == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ /* Get the iATU base address and size */
+ rcar->dw.atu_base = (void *)dev_read_addr_name(dev, "atu");
+ if ((fdt_addr_t)rcar->dw.atu_base == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ /* Get the PHY base address and size */
+ rcar->phy_base = (void *)dev_read_addr_name(dev, "phy");
+ if ((fdt_addr_t)rcar->phy_base == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ /* Get the app base address and size */
+ rcar->app_base = (void *)dev_read_addr_name(dev, "app");
+ if ((fdt_addr_t)rcar->app_base == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ /* Get the dbi2 base address and size */
+ rcar->dbi2_base = (void *)dev_read_addr_name(dev, "dbi2");
+ if ((fdt_addr_t)rcar->dbi2_base == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ rcar->max_link_speed =
+ clamp(dev_read_u32_default(dev, "max-link-speed",
+ LINK_SPEED_GEN_4),
+ LINK_SPEED_GEN_1, RCAR_MAX_LINK_SPEED);
+
+ rcar->num_lanes = dev_read_u32_default(dev, "num-lanes", 4);
+
+ return 0;
+}
+
+static const struct dm_pci_ops rcar_gen4_pcie_ops = {
+ .read_config = pcie_dw_read_config,
+ .write_config = pcie_dw_write_config,
+};
+
+static const struct udevice_id rcar_gen4_pcie_ids[] = {
+ { .compatible = "renesas,rcar-gen4-pcie" },
+ { }
+};
+
+U_BOOT_DRIVER(rcar_gen4_pcie) = {
+ .name = "rcar_gen4_pcie",
+ .id = UCLASS_PCI,
+ .of_match = rcar_gen4_pcie_ids,
+ .ops = &rcar_gen4_pcie_ops,
+ .of_to_plat = rcar_gen4_pcie_of_to_plat,
+ .probe = rcar_gen4_pcie_probe,
+ .priv_auto = sizeof(struct rcar_gen4_pcie),
+};
diff --git a/drivers/pci/pcie_dw_common.c b/drivers/pci/pcie_dw_common.c
index 78961271a8e..c4cad019373 100644
--- a/drivers/pci/pcie_dw_common.c
+++ b/drivers/pci/pcie_dw_common.c
@@ -13,6 +13,7 @@
#include <pci.h>
#include <dm/device_compat.h>
#include <asm/io.h>
+#include <linux/bitfield.h>
#include <linux/delay.h>
#include "pcie_dw_common.h"
@@ -28,6 +29,50 @@ int pcie_dw_get_link_width(struct pcie_dw *pci)
PCIE_LINK_STATUS_WIDTH_MASK) >> PCIE_LINK_STATUS_WIDTH_OFF;
}
+void dw_pcie_link_set_max_link_width(struct pcie_dw *pci, u32 num_lanes)
+{
+ u32 lnkcap, lwsc, plc;
+ u8 cap;
+
+ if (!num_lanes)
+ return;
+
+ /* Set the number of lanes */
+ plc = readl(pci->dbi_base + PCIE_PORT_LINK_CONTROL);
+ plc &= ~PORT_LINK_FAST_LINK_MODE;
+ plc &= ~PORT_LINK_MODE_MASK;
+
+ /* Set link width speed control register */
+ lwsc = readl(pci->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
+ lwsc &= ~PORT_LOGIC_LINK_WIDTH_MASK;
+ lwsc |= PORT_LOGIC_LINK_WIDTH_1_LANES;
+ switch (num_lanes) {
+ case 1:
+ plc |= PORT_LINK_MODE_1_LANES;
+ break;
+ case 2:
+ plc |= PORT_LINK_MODE_2_LANES;
+ break;
+ case 4:
+ plc |= PORT_LINK_MODE_4_LANES;
+ break;
+ case 8:
+ plc |= PORT_LINK_MODE_8_LANES;
+ break;
+ default:
+ dev_err(pci->dev, "num-lanes %u: invalid value\n", num_lanes);
+ return;
+ }
+ writel(plc, pci->dbi_base + PCIE_PORT_LINK_CONTROL);
+ writel(lwsc, pci->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
+
+ cap = pcie_dw_find_capability(pci, PCI_CAP_ID_EXP);
+ lnkcap = readl(pci->dbi_base + cap + PCI_EXP_LNKCAP);
+ lnkcap &= ~PCI_EXP_LNKCAP_MLW;
+ lnkcap |= FIELD_PREP(PCI_EXP_LNKCAP_MLW, num_lanes);
+ writel(lnkcap, pci->dbi_base + cap + PCI_EXP_LNKCAP);
+}
+
static void dw_pcie_writel_ob_unroll(struct pcie_dw *pci, u32 index, u32 reg,
u32 val)
{
diff --git a/drivers/pci/pcie_dw_common.h b/drivers/pci/pcie_dw_common.h
index 8cb99a12ea1..5fa50f3dc3a 100644
--- a/drivers/pci/pcie_dw_common.h
+++ b/drivers/pci/pcie_dw_common.h
@@ -66,8 +66,12 @@
#define LINK_SPEED_GEN_1 0x1
#define LINK_SPEED_GEN_2 0x2
#define LINK_SPEED_GEN_3 0x3
+#define LINK_SPEED_GEN_4 0x4
/* Synopsys-specific PCIe configuration registers */
+#define PCIE_PORT_FORCE 0x708
+#define PORT_FORCE_DO_DESKEW_FOR_SRIS BIT(23)
+
#define PCIE_PORT_LINK_CONTROL 0x710
#define PORT_LINK_DLL_LINK_EN BIT(5)
#define PORT_LINK_FAST_LINK_MODE BIT(7)
@@ -78,6 +82,9 @@
#define PORT_LINK_MODE_4_LANES PORT_LINK_MODE(0x7)
#define PORT_LINK_MODE_8_LANES PORT_LINK_MODE(0xf)
+#define PCIE_PORT_LANE_SKEW 0x714
+#define PORT_LANE_SKEW_INSERT_MASK GENMASK(23, 0)
+
#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
#define PORT_LOGIC_N_FTS_MASK GENMASK(7, 0)
#define PORT_LOGIC_SPEED_CHANGE BIT(17)
@@ -130,6 +137,8 @@ int pcie_dw_get_link_speed(struct pcie_dw *pci);
int pcie_dw_get_link_width(struct pcie_dw *pci);
+void dw_pcie_link_set_max_link_width(struct pcie_dw *pci, u32 num_lanes);
+
int pcie_dw_prog_outbound_atu_unroll(struct pcie_dw *pci, int index, int type, u64 cpu_addr,
u64 pci_addr, u32 size);
diff --git a/drivers/pci/pcie_dw_meson.c b/drivers/pci/pcie_dw_meson.c
index bb78e7874b1..483b07ce078 100644
--- a/drivers/pci/pcie_dw_meson.c
+++ b/drivers/pci/pcie_dw_meson.c
@@ -115,13 +115,9 @@ static void meson_pcie_configure(struct meson_pcie *priv)
val &= ~PORT_LINK_FAST_LINK_MODE;
val |= PORT_LINK_DLL_LINK_EN;
val &= ~PORT_LINK_MODE_MASK;
- val |= PORT_LINK_MODE_1_LANES;
writel(val, priv->dw.dbi_base + PCIE_PORT_LINK_CONTROL);
- val = readl(priv->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
- val &= ~PORT_LOGIC_LINK_WIDTH_MASK;
- val |= PORT_LOGIC_LINK_WIDTH_1_LANES;
- writel(val, priv->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
+ dw_pcie_link_set_max_link_width(&priv->dw, 1);
dw_pcie_dbi_write_enable(&priv->dw, false);
}
diff --git a/drivers/pci/pcie_dw_qcom.c b/drivers/pci/pcie_dw_qcom.c
index 39b4cd4efe2..978754e8472 100644
--- a/drivers/pci/pcie_dw_qcom.c
+++ b/drivers/pci/pcie_dw_qcom.c
@@ -213,17 +213,6 @@ static void qcom_pcie_clear_hpc(struct qcom_pcie *priv)
dw_pcie_dbi_write_enable(&priv->dw, false);
}
-static void qcom_pcie_set_lanes(struct qcom_pcie *priv, unsigned int lanes)
-{
- u8 offset = pcie_dw_find_capability(&priv->dw, PCI_CAP_ID_EXP);
- u32 val;
-
- val = readl(priv->dw.dbi_base + offset + PCI_EXP_LNKCAP);
- val &= ~PCI_EXP_LNKCAP_MLW;
- val |= FIELD_PREP(PCI_EXP_LNKCAP_MLW, lanes);
- writel(val, priv->dw.dbi_base + offset + PCI_EXP_LNKCAP);
-}
-
static int qcom_pcie_config_sid_1_9_0(struct qcom_pcie *priv)
{
/* iommu map structure */
@@ -299,15 +288,9 @@ static void qcom_pcie_configure(struct qcom_pcie *priv)
val &= ~PORT_LINK_FAST_LINK_MODE;
val |= PORT_LINK_DLL_LINK_EN;
val &= ~PORT_LINK_MODE_MASK;
- val |= PORT_LINK_MODE_2_LANES;
writel(val, priv->dw.dbi_base + PCIE_PORT_LINK_CONTROL);
- val = readl(priv->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
- val &= ~PORT_LOGIC_LINK_WIDTH_MASK;
- val |= PORT_LOGIC_LINK_WIDTH_2_LANES;
- writel(val, priv->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
-
- qcom_pcie_set_lanes(priv, 2);
+ dw_pcie_link_set_max_link_width(&priv->dw, 2);
dw_pcie_dbi_write_enable(&priv->dw, false);
}
diff --git a/drivers/pci/pcie_dw_rockchip.c b/drivers/pci/pcie_dw_rockchip.c
index ac7faa4cc19..208aa30463a 100644
--- a/drivers/pci/pcie_dw_rockchip.c
+++ b/drivers/pci/pcie_dw_rockchip.c
@@ -158,8 +158,6 @@ static inline void rk_pcie_writel_apb(struct rk_pcie *rk_pcie, u32 reg,
*/
static void rk_pcie_configure(struct rk_pcie *pci)
{
- u32 val;
-
dw_pcie_dbi_write_enable(&pci->dw, true);
/* Disable BAR 0 and BAR 1 */
@@ -175,43 +173,8 @@ static void rk_pcie_configure(struct rk_pcie *pci)
TARGET_LINK_SPEED_MASK, pci->gen);
/* Set the number of lanes */
- val = readl(pci->dw.dbi_base + PCIE_PORT_LINK_CONTROL);
- val &= ~PORT_LINK_FAST_LINK_MODE;
- val |= PORT_LINK_DLL_LINK_EN;
- val &= ~PORT_LINK_MODE_MASK;
- switch (pci->num_lanes) {
- case 1:
- val |= PORT_LINK_MODE_1_LANES;
- break;
- case 2:
- val |= PORT_LINK_MODE_2_LANES;
- break;
- case 4:
- val |= PORT_LINK_MODE_4_LANES;
- break;
- default:
- dev_err(pci->dw.dev, "num-lanes %u: invalid value\n", pci->num_lanes);
- goto out;
- }
- writel(val, pci->dw.dbi_base + PCIE_PORT_LINK_CONTROL);
-
- /* Set link width speed control register */
- val = readl(pci->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
- val &= ~PORT_LOGIC_LINK_WIDTH_MASK;
- switch (pci->num_lanes) {
- case 1:
- val |= PORT_LOGIC_LINK_WIDTH_1_LANES;
- break;
- case 2:
- val |= PORT_LOGIC_LINK_WIDTH_2_LANES;
- break;
- case 4:
- val |= PORT_LOGIC_LINK_WIDTH_4_LANES;
- break;
- }
- writel(val, pci->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
+ dw_pcie_link_set_max_link_width(&pci->dw, pci->num_lanes);
-out:
dw_pcie_dbi_write_enable(&pci->dw, false);
}
diff --git a/drivers/pci_endpoint/Kconfig b/drivers/pci_endpoint/Kconfig
index 19cfa0aafb5..9900481daa6 100644
--- a/drivers/pci_endpoint/Kconfig
+++ b/drivers/pci_endpoint/Kconfig
@@ -22,6 +22,12 @@ config PCIE_CADENCE_EP
endpoint mode. This PCIe controller may be embedded into many
different vendors SoCs.
+config PCIE_CDNS_TI_EP
+ bool "TI K3 PCIe EP support"
+ help
+ Say Y here to enable support for the Canence PCIe Controller
+ in Endpoint Mode on TI's K3 Socs.
+
config PCI_SANDBOX_EP
bool "Sandbox PCIe endpoint controller"
depends on PCI_ENDPOINT
diff --git a/drivers/pci_endpoint/Makefile b/drivers/pci_endpoint/Makefile
index 3cd987259d3..62a865c4463 100644
--- a/drivers/pci_endpoint/Makefile
+++ b/drivers/pci_endpoint/Makefile
@@ -6,3 +6,4 @@
obj-y += pci_ep-uclass.o
obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o
obj-$(CONFIG_PCI_SANDBOX_EP) += sandbox-pci_ep.o
+obj-$(CONFIG_PCIE_CDNS_TI_EP) += pcie_cdns_ti_ep.o
diff --git a/drivers/pci_endpoint/pcie_cdns_ti_ep.c b/drivers/pci_endpoint/pcie_cdns_ti_ep.c
new file mode 100644
index 00000000000..661b6ba5b55
--- /dev/null
+++ b/drivers/pci_endpoint/pcie_cdns_ti_ep.c
@@ -0,0 +1,396 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com
+ *
+ * PCIe Endpoint controller driver for TI's K3 SoCs with Cadence PCIe controller
+ *
+ * Ported from the Linux driver - drivers/pci/controller/cadence/pci-j721e.c
+ *
+ * Author: Hrushikesh Salunke <h-salunke@ti.com>
+ *
+ */
+
+#include <clk.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <generic-phy.h>
+#include <linux/log2.h>
+#include <linux/sizes.h>
+#include <power-domain.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <pci_ep.h>
+
+#include "pcie-cadence.h"
+
+#define PCIE_USER_CMD_STATUS_REG_OFFSET 0x4
+#define LINK_TRAINING_ENABLE BIT(0)
+
+#define PCIE_MODE_SEL_MASK BIT(7)
+#define PCIE_GEN_SEL_MASK GENMASK(1, 0)
+#define PCIE_LINK_WIDTH_MASK GENMASK(9, 8)
+
+struct pcie_cdns_ti_ep_data {
+ unsigned int quirk_retrain_flag:1;
+ unsigned int quirk_detect_quiet_flag:1;
+ unsigned int quirk_disable_flr:1;
+ unsigned int byte_access_allowed:1;
+ unsigned int max_lanes;
+};
+
+struct pcie_cdns_ti_ep {
+ struct udevice *dev;
+ void __iomem *intd_cfg_base;
+ void __iomem *user_cfg_base;
+ void __iomem *reg_base;
+ void __iomem *mem_base;
+ fdt_size_t cfg_size;
+ struct regmap *syscon_base;
+ u32 max_link_speed;
+ u32 num_lanes;
+ u32 pcie_ctrl_offset;
+ unsigned int quirk_retrain_flag:1;
+ unsigned int quirk_detect_quiet_flag:1;
+ unsigned int quirk_disable_flr:1;
+ unsigned int byte_access_allowed:1;
+};
+
+static inline u32 pcie_cdns_ti_ep_user_readl(struct pcie_cdns_ti_ep *pcie, u32 offset)
+{
+ return readl(pcie->user_cfg_base + offset);
+}
+
+static inline void pcie_cdns_ti_ep_user_writel(struct pcie_cdns_ti_ep *pcie, u32 offset,
+ u32 val)
+{
+ writel(val, pcie->user_cfg_base + offset);
+}
+
+static void pcie_cdns_ti_start_link(struct pcie_cdns_ti_ep *pcie)
+{
+ u32 reg;
+
+ reg = pcie_cdns_ti_ep_user_readl(pcie, PCIE_USER_CMD_STATUS_REG_OFFSET);
+ reg |= LINK_TRAINING_ENABLE;
+ pcie_cdns_ti_ep_user_writel(pcie, PCIE_USER_CMD_STATUS_REG_OFFSET, reg);
+}
+
+static int pcie_cdns_reset(struct udevice *dev, struct power_domain *pci_pwrdmn)
+{
+ int ret;
+
+ ret = power_domain_off(pci_pwrdmn);
+ if (ret) {
+ dev_err(dev, "failed to power off\n");
+ return ret;
+ }
+
+ ret = power_domain_on(pci_pwrdmn);
+ if (ret) {
+ dev_err(dev, "failed to power on: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int pcie_cdns_config_serdes(struct udevice *dev)
+{
+ if (CONFIG_IS_ENABLED(PHY_CADENCE_TORRENT)) {
+ struct phy serdes;
+ int ret = 7;
+
+ ret = generic_phy_get_by_name(dev, "pcie-phy", &serdes);
+ if (ret != 0 && ret != -EBUSY) {
+ dev_err(dev, "unable to get serdes\n");
+ return ret;
+ }
+ generic_phy_reset(&serdes);
+ generic_phy_init(&serdes);
+ generic_phy_power_on(&serdes);
+ } else {
+ dev_info(dev, "Proceeding with the assumption that the SERDES is already configured\n");
+ }
+ return 0;
+}
+
+static int pcie_cdns_ti_ctrl_init(struct pcie_cdns_ti_ep *pcie)
+{
+ struct regmap *syscon = pcie->syscon_base;
+ u32 val = 0;
+
+ /* Set mode of operation */
+ regmap_update_bits(syscon, pcie->pcie_ctrl_offset, PCIE_MODE_SEL_MASK,
+ val);
+
+ /* Set link speed */
+ regmap_update_bits(syscon, pcie->pcie_ctrl_offset, PCIE_GEN_SEL_MASK,
+ pcie->max_link_speed - 1);
+
+ /* Set link width */
+ regmap_update_bits(syscon, pcie->pcie_ctrl_offset, PCIE_LINK_WIDTH_MASK,
+ (pcie->num_lanes - 1) << 8);
+ return 0;
+}
+
+static int pcie_cdns_ti_write_header(struct udevice *dev, uint fn,
+ struct pci_ep_header *hdr)
+{
+ struct pcie_cdns_ti_ep *pcie_ep = dev_get_priv(dev);
+ struct cdns_pcie pcie;
+
+ pcie.reg_base = pcie_ep->reg_base;
+
+ cdns_pcie_ep_fn_writew(&pcie, fn, PCI_DEVICE_ID, hdr->deviceid);
+ cdns_pcie_ep_fn_writeb(&pcie, fn, PCI_REVISION_ID, hdr->revid);
+ cdns_pcie_ep_fn_writeb(&pcie, fn, PCI_CLASS_PROG,
+ hdr->progif_code);
+ cdns_pcie_ep_fn_writew(&pcie, fn, PCI_CLASS_DEVICE,
+ hdr->subclass_code |
+ hdr->baseclass_code << 8);
+ cdns_pcie_ep_fn_writeb(&pcie, fn, PCI_CACHE_LINE_SIZE,
+ hdr->cache_line_size);
+ cdns_pcie_ep_fn_writew(&pcie, fn, PCI_SUBSYSTEM_ID,
+ hdr->subsys_id);
+ cdns_pcie_ep_fn_writeb(&pcie, fn, PCI_INTERRUPT_PIN,
+ hdr->interrupt_pin);
+
+ /*
+ * Vendor ID can only be modified from function 0, all other functions
+ * use the same vendor ID as function 0.
+ */
+ if (fn == 0) {
+ /* Update the vendor IDs. */
+ u32 id = CDNS_PCIE_LM_ID_VENDOR(hdr->vendorid) |
+ CDNS_PCIE_LM_ID_SUBSYS(hdr->subsys_vendor_id);
+
+ cdns_pcie_writel(&pcie, CDNS_PCIE_LM_ID, id);
+ }
+
+ return 0;
+}
+
+static int pcie_cdns_ti_set_bar(struct udevice *dev, uint fn,
+ struct pci_bar *ep_bar)
+{
+ struct pcie_cdns_ti_ep *pcie_ep = dev_get_priv(dev);
+ struct cdns_pcie pcie;
+ dma_addr_t bar_phys = ep_bar->phys_addr;
+ enum pci_barno bar = ep_bar->barno;
+ int flags = ep_bar->flags;
+ u32 addr0, addr1, reg, cfg, b, aperture, ctrl;
+ u64 sz;
+
+ pcie.reg_base = pcie_ep->reg_base;
+
+ /* BAR size is 2^(aperture + 7) */
+ sz = max_t(size_t, ep_bar->size, CDNS_PCIE_EP_MIN_APERTURE);
+ /*
+ * roundup_pow_of_two() returns an unsigned long, which is not suited
+ * for 64bit values.
+ */
+ sz = 1ULL << fls64(sz - 1);
+ aperture = ilog2(sz) - 7; /* 128B -> 0, 256B -> 1, 512B -> 2, ... */
+
+ if ((flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
+ ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_IO_32BITS;
+ } else {
+ bool is_prefetch = !!(flags & PCI_BASE_ADDRESS_MEM_PREFETCH);
+ bool is_64bits = (sz > SZ_2G) |
+ !!(ep_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64);
+
+ if (is_64bits && (bar & 1))
+ return -EINVAL;
+
+ if (is_64bits && !(flags & PCI_BASE_ADDRESS_MEM_TYPE_64))
+ ep_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
+
+ if (is_64bits && is_prefetch)
+ ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS;
+ else if (is_prefetch)
+ ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS;
+ else if (is_64bits)
+ ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_64BITS;
+ else
+ ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_32BITS;
+ }
+
+ addr0 = lower_32_bits(bar_phys);
+ addr1 = upper_32_bits(bar_phys);
+ cdns_pcie_writel(&pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar),
+ addr0);
+ cdns_pcie_writel(&pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar),
+ addr1);
+
+ /*
+ * Cadence PCIe controller provides a register interface to configure
+ * BAR of an Endpoint function. Per function there are two BAR configuration
+ * registers, out of which first is used to configure BAR_0 to BAR_4 and
+ * second is used to configure the remaining BARs.
+ */
+ if (bar < BAR_4) {
+ reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
+ b = bar;
+ } else {
+ reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
+ b = bar - BAR_4;
+ }
+
+ cfg = cdns_pcie_readl(&pcie, reg);
+
+ cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
+ CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
+ cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) |
+ CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl));
+ cdns_pcie_writel(&pcie, reg, cfg);
+
+ cfg = cdns_pcie_readl(&pcie, reg);
+
+ return 0;
+}
+
+static int pcie_cdns_ti_start(struct udevice *dev)
+{
+ struct pcie_cdns_ti_ep *pcie = dev_get_priv(dev);
+
+ pcie_cdns_ti_start_link(pcie);
+
+ return 0;
+}
+
+static int pcie_cdns_ti_ep_probe(struct udevice *dev)
+{
+ struct pcie_cdns_ti_ep *pcie = dev_get_priv(dev);
+ struct pcie_cdns_ti_ep_data *data;
+ struct power_domain pci_pwrdmn;
+ struct clk *clk;
+ int ret;
+
+ pcie->dev = dev;
+ data = (struct pcie_cdns_ti_ep_data *)dev_get_driver_data(dev);
+ if (!data)
+ return -EINVAL;
+
+ pcie->quirk_retrain_flag = data->quirk_retrain_flag;
+ pcie->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag;
+ pcie->quirk_disable_flr = data->quirk_disable_flr;
+
+ if (pcie->num_lanes > data->max_lanes) {
+ dev_warn(dev, "cannot support %d lanes, defaulting to %d\n",
+ pcie->num_lanes, data->max_lanes);
+ pcie->num_lanes = data->max_lanes;
+ }
+
+ ret = power_domain_get_by_index(dev, &pci_pwrdmn, 0);
+ if (ret) {
+ dev_err(dev, "failed to get power domain: %d\n", ret);
+ return ret;
+ }
+
+ /*
+ * Reset the PCIe controller so that newly configured BAR
+ * values are reflected.
+ */
+ ret = pcie_cdns_reset(dev, &pci_pwrdmn);
+ if (ret) {
+ dev_err(dev, "failed to reset controller: %d\n", ret);
+ return ret;
+ }
+
+ clk = devm_clk_get(dev, "fck");
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ dev_err(dev, "failed to get functional clock\n");
+ return ret;
+ }
+
+ ret = pcie_cdns_config_serdes(dev);
+ if (ret) {
+ dev_err(dev, "failed to configure serdes: %d\n", ret);
+ return ret;
+ }
+
+ ret = pcie_cdns_ti_ctrl_init(pcie);
+ if (ret) {
+ dev_err(dev, "failed to initialize controller: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int pcie_cdns_ti_ep_of_to_plat(struct udevice *dev)
+{
+ struct pcie_cdns_ti_ep *pcie = dev_get_priv(dev);
+ struct regmap *syscon;
+ u32 offset;
+ int ret;
+
+ pcie->intd_cfg_base = dev_remap_addr_name(dev, "intd_cfg");
+ if (!pcie->intd_cfg_base)
+ return -EINVAL;
+
+ pcie->user_cfg_base = dev_remap_addr_name(dev, "user_cfg");
+ if (!pcie->user_cfg_base)
+ return -EINVAL;
+
+ pcie->reg_base = dev_remap_addr_name(dev, "reg");
+ if (!pcie->reg_base)
+ return -EINVAL;
+
+ pcie->mem_base = dev_remap_addr_name(dev, "mem");
+ if (!pcie->mem_base)
+ return -EINVAL;
+
+ ret = dev_read_u32(dev, "num-lanes", &pcie->num_lanes);
+ if (ret)
+ return ret;
+
+ ret = dev_read_u32(dev, "max-link-speed", &pcie->max_link_speed);
+ if (ret)
+ return ret;
+
+ syscon = syscon_regmap_lookup_by_phandle(dev, "ti,syscon-pcie-ctrl");
+ if (IS_ERR(syscon)) {
+ if (PTR_ERR(syscon) == -ENODEV)
+ return 0;
+ return PTR_ERR(syscon);
+ }
+
+ ret = dev_read_u32_index(dev, "ti,syscon-pcie-ctrl", 1, &offset);
+ if (ret)
+ return ret;
+
+ pcie->syscon_base = syscon;
+ pcie->pcie_ctrl_offset = offset;
+
+ return 0;
+}
+
+static const struct pci_ep_ops pcie_cdns_ti_ep_ops = {
+ .write_header = pcie_cdns_ti_write_header,
+ .set_bar = pcie_cdns_ti_set_bar,
+ .start = pcie_cdns_ti_start,
+};
+
+static const struct pcie_cdns_ti_ep_data am64_pcie_ep_data = {
+ .max_lanes = 1,
+};
+
+static const struct udevice_id pcie_cdns_ti_ep_ids[] = {
+ {
+ .compatible = "ti,am64-pcie-ep",
+ .data = (ulong)&am64_pcie_ep_data,
+ },
+ {},
+};
+
+U_BOOT_DRIVER(pcie_cdns_ti_ep) = {
+ .name = "pcie_cdns_ti_ep",
+ .id = UCLASS_PCI_EP,
+ .of_match = pcie_cdns_ti_ep_ids,
+ .ops = &pcie_cdns_ti_ep_ops,
+ .of_to_plat = pcie_cdns_ti_ep_of_to_plat,
+ .probe = pcie_cdns_ti_ep_probe,
+ .priv_auto = sizeof(struct pcie_cdns_ti_ep),
+};
diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
index d4e8ece4935..1f566d082f9 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -240,6 +240,7 @@ struct cdns_torrent_inst {
struct cdns_torrent_phy {
void __iomem *sd_base; /* SD0801 register base */
+ u32 protocol_bitmask;
size_t size;
struct reset_control *phy_rst;
struct udevice *dev;
@@ -432,124 +433,155 @@ static int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_ph
struct cdns_reg_pairs *reg_pairs;
enum cdns_torrent_ssc_mode ssc;
struct regmap *regmap;
- u32 num_regs;
+ u32 num_regs, num_protocols, protocol;
+
+ num_protocols = hweight32(cdns_phy->protocol_bitmask);
- /* Maximum 2 links (subnodes) are supported */
- if (cdns_phy->nsubnodes != 2)
+ /* Maximum 2 protocols are supported */
+ if (num_protocols > 2) {
+ dev_err(cdns_phy->dev, "at most 2 protocols are supported\n");
return -EINVAL;
+ }
- phy_t1 = cdns_phy->phys[0].phy_type;
- phy_t2 = cdns_phy->phys[1].phy_type;
+ if (cdns_phy->nsubnodes == 2) {
+ phy_t1 = cdns_phy->phys[0].phy_type;
+ phy_t2 = cdns_phy->phys[1].phy_type;
+ } else {
+ if (num_protocols != 2) {
+ dev_err(cdns_phy->dev, "incorrect representation of link\n");
+ return -EINVAL;
+ }
+ phy_t1 = __ffs(cdns_phy->protocol_bitmask);
+ phy_t2 = __fls(cdns_phy->protocol_bitmask);
+ }
- /*
- * First configure the PHY for first link with phy_t1. Geth the array
- * values are [phy_t1][phy_t2][ssc].
+ /**
+ * Configure all links with the protocol phy_t1 first followed by
+ * configuring all links with the protocol phy_t2.
+ *
+ * When phy_t1 = phy_t2, it is a single protocol and configuration
+ * is performed with a single iteration of the protocol and multiple
+ * iterations over the sub-nodes (links).
+ *
+ * When phy_t1 != phy_t2, there are two protocols and configuration
+ * is performed by iterating over all sub-nodes matching the first
+ * protocol and configuring them first, followed by iterating over
+ * all sub-nodes matching the second protocol and configuring them
+ * next.
*/
- for (node = 0; node < cdns_phy->nsubnodes; node++) {
- if (node == 1) {
- /*
- * If fist link with phy_t1 is configured, then
- * configure the PHY for second link with phy_t2.
- * Get the array values as [phy_t2][phy_t1][ssc]
- */
+
+ for (protocol = 0; protocol < num_protocols; protocol++) {
+ /**
+ * For the case where num_protocols is 1,
+ * phy_t1 = phy_t2 and the swap is unnecessary.
+ *
+ * Swapping phy_t1 and phy_t2 is only required when the
+ * number of protocols is 2 and there are 2 or more links.
+ */
+ if (protocol == 1) {
tmp_phy_type = phy_t1;
phy_t1 = phy_t2;
phy_t2 = tmp_phy_type;
}
- mlane = cdns_phy->phys[node].mlane;
- ssc = cdns_phy->phys[node].ssc_mode;
- num_lanes = cdns_phy->phys[node].num_lanes;
+ for (node = 0; node < cdns_phy->nsubnodes; node++) {
+ if (cdns_phy->phys[node].phy_type != phy_t1)
+ continue;
- /**
- * PHY configuration specific registers:
- * link_cmn_vals depend on combination of PHY types being
- * configured and are common for both PHY types, so array
- * values should be same for [phy_t1][phy_t2][ssc] and
- * [phy_t2][phy_t1][ssc].
- * xcvr_diag_vals also depend on combination of PHY types
- * being configured, but these can be different for particular
- * PHY type and are per lane.
- */
- link_cmn_vals = init_data->link_cmn_vals[phy_t1][phy_t2][ssc];
- if (link_cmn_vals) {
- reg_pairs = link_cmn_vals->reg_pairs;
- num_regs = link_cmn_vals->num_regs;
- regmap = cdns_phy->regmap_common_cdb;
+ mlane = cdns_phy->phys[node].mlane;
+ ssc = cdns_phy->phys[node].ssc_mode;
+ num_lanes = cdns_phy->phys[node].num_lanes;
/**
- * First array value in link_cmn_vals must be of
- * PHY_PLL_CFG register
+ * PHY configuration specific registers:
+ * link_cmn_vals depend on combination of PHY types being
+ * configured and are common for both PHY types, so array
+ * values should be same for [phy_t1][phy_t2][ssc] and
+ * [phy_t2][phy_t1][ssc].
+ * xcvr_diag_vals also depend on combination of PHY types
+ * being configured, but these can be different for particular
+ * PHY type and are per lane.
*/
- regmap_field_write(cdns_phy->phy_pll_cfg,
- reg_pairs[0].val);
-
- for (i = 1; i < num_regs; i++)
- regmap_write(regmap, reg_pairs[i].off,
- reg_pairs[i].val);
- }
+ link_cmn_vals = init_data->link_cmn_vals[phy_t1][phy_t2][ssc];
+ if (link_cmn_vals) {
+ reg_pairs = link_cmn_vals->reg_pairs;
+ num_regs = link_cmn_vals->num_regs;
+ regmap = cdns_phy->regmap_common_cdb;
+
+ /**
+ * First array value in link_cmn_vals must be of
+ * PHY_PLL_CFG register
+ */
+ regmap_field_write(cdns_phy->phy_pll_cfg,
+ reg_pairs[0].val);
+
+ for (i = 1; i < num_regs; i++)
+ regmap_write(regmap, reg_pairs[i].off,
+ reg_pairs[i].val);
+ }
- xcvr_diag_vals = init_data->xcvr_diag_vals[phy_t1][phy_t2][ssc];
- if (xcvr_diag_vals) {
- reg_pairs = xcvr_diag_vals->reg_pairs;
- num_regs = xcvr_diag_vals->num_regs;
- for (i = 0; i < num_lanes; i++) {
- regmap = cdns_phy->regmap_tx_lane_cdb[i + mlane];
- for (j = 0; j < num_regs; j++)
- regmap_write(regmap, reg_pairs[j].off,
- reg_pairs[j].val);
+ xcvr_diag_vals = init_data->xcvr_diag_vals[phy_t1][phy_t2][ssc];
+ if (xcvr_diag_vals) {
+ reg_pairs = xcvr_diag_vals->reg_pairs;
+ num_regs = xcvr_diag_vals->num_regs;
+ for (i = 0; i < num_lanes; i++) {
+ regmap = cdns_phy->regmap_tx_lane_cdb[i + mlane];
+ for (j = 0; j < num_regs; j++)
+ regmap_write(regmap, reg_pairs[j].off,
+ reg_pairs[j].val);
+ }
}
- }
- /* PHY PCS common registers configurations */
- pcs_cmn_vals = init_data->pcs_cmn_vals[phy_t1][phy_t2][ssc];
- if (pcs_cmn_vals) {
- reg_pairs = pcs_cmn_vals->reg_pairs;
- num_regs = pcs_cmn_vals->num_regs;
- regmap = cdns_phy->regmap_phy_pcs_common_cdb;
- for (i = 0; i < num_regs; i++)
- regmap_write(regmap, reg_pairs[i].off,
- reg_pairs[i].val);
- }
+ /* PHY PCS common registers configurations */
+ pcs_cmn_vals = init_data->pcs_cmn_vals[phy_t1][phy_t2][ssc];
+ if (pcs_cmn_vals) {
+ reg_pairs = pcs_cmn_vals->reg_pairs;
+ num_regs = pcs_cmn_vals->num_regs;
+ regmap = cdns_phy->regmap_phy_pcs_common_cdb;
+ for (i = 0; i < num_regs; i++)
+ regmap_write(regmap, reg_pairs[i].off,
+ reg_pairs[i].val);
+ }
- /* PMA common registers configurations */
- cmn_vals = init_data->cmn_vals[phy_t1][phy_t2][ssc];
- if (cmn_vals) {
- reg_pairs = cmn_vals->reg_pairs;
- num_regs = cmn_vals->num_regs;
- regmap = cdns_phy->regmap_common_cdb;
- for (i = 0; i < num_regs; i++)
- regmap_write(regmap, reg_pairs[i].off,
- reg_pairs[i].val);
- }
+ /* PMA common registers configurations */
+ cmn_vals = init_data->cmn_vals[phy_t1][phy_t2][ssc];
+ if (cmn_vals) {
+ reg_pairs = cmn_vals->reg_pairs;
+ num_regs = cmn_vals->num_regs;
+ regmap = cdns_phy->regmap_common_cdb;
+ for (i = 0; i < num_regs; i++)
+ regmap_write(regmap, reg_pairs[i].off,
+ reg_pairs[i].val);
+ }
- /* PMA TX lane registers configurations */
- tx_ln_vals = init_data->tx_ln_vals[phy_t1][phy_t2][ssc];
- if (tx_ln_vals) {
- reg_pairs = tx_ln_vals->reg_pairs;
- num_regs = tx_ln_vals->num_regs;
- for (i = 0; i < num_lanes; i++) {
- regmap = cdns_phy->regmap_tx_lane_cdb[i + mlane];
- for (j = 0; j < num_regs; j++)
- regmap_write(regmap, reg_pairs[j].off,
- reg_pairs[j].val);
+ /* PMA TX lane registers configurations */
+ tx_ln_vals = init_data->tx_ln_vals[phy_t1][phy_t2][ssc];
+ if (tx_ln_vals) {
+ reg_pairs = tx_ln_vals->reg_pairs;
+ num_regs = tx_ln_vals->num_regs;
+ for (i = 0; i < num_lanes; i++) {
+ regmap = cdns_phy->regmap_tx_lane_cdb[i + mlane];
+ for (j = 0; j < num_regs; j++)
+ regmap_write(regmap, reg_pairs[j].off,
+ reg_pairs[j].val);
+ }
}
- }
- /* PMA RX lane registers configurations */
- rx_ln_vals = init_data->rx_ln_vals[phy_t1][phy_t2][ssc];
- if (rx_ln_vals) {
- reg_pairs = rx_ln_vals->reg_pairs;
- num_regs = rx_ln_vals->num_regs;
- for (i = 0; i < num_lanes; i++) {
- regmap = cdns_phy->regmap_rx_lane_cdb[i + mlane];
- for (j = 0; j < num_regs; j++)
- regmap_write(regmap, reg_pairs[j].off,
- reg_pairs[j].val);
+ /* PMA RX lane registers configurations */
+ rx_ln_vals = init_data->rx_ln_vals[phy_t1][phy_t2][ssc];
+ if (rx_ln_vals) {
+ reg_pairs = rx_ln_vals->reg_pairs;
+ num_regs = rx_ln_vals->num_regs;
+ for (i = 0; i < num_lanes; i++) {
+ regmap = cdns_phy->regmap_rx_lane_cdb[i + mlane];
+ for (j = 0; j < num_regs; j++)
+ regmap_write(regmap, reg_pairs[j].off,
+ reg_pairs[j].val);
+ }
}
- }
- reset_deassert_bulk(cdns_phy->phys[node].lnk_rst);
+ reset_deassert_bulk(cdns_phy->phys[node].lnk_rst);
+ }
}
/* Take the PHY out of reset */
@@ -575,6 +607,7 @@ static int cdns_torrent_phy_probe(struct udevice *dev)
/* Get init data for this phy */
data = (struct cdns_torrent_data *)dev_get_driver_data(dev);
cdns_phy->init_data = data;
+ cdns_phy->protocol_bitmask = 0;
cdns_phy->phy_rst = devm_reset_control_get_by_index(dev, 0);
if (IS_ERR(cdns_phy->phy_rst)) {
@@ -677,6 +710,8 @@ static int cdns_torrent_phy_probe(struct udevice *dev)
/* Get SSC mode */
ofnode_read_u32(child, "cdns,ssc-mode",
&cdns_phy->phys[node].ssc_mode);
+
+ cdns_phy->protocol_bitmask |= BIT(cdns_phy->phys[node].phy_type);
node++;
}
diff --git a/drivers/phy/qcom/phy-qcom-qmp-ufs.c b/drivers/phy/qcom/phy-qcom-qmp-ufs.c
index 449b9767778..f3c606847fb 100644
--- a/drivers/phy/qcom/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qcom/phy-qcom-qmp-ufs.c
@@ -86,6 +86,12 @@ enum qphy_reg_layout {
QPHY_LAYOUT_SIZE
};
+static const unsigned int ufsphy_v2_regs_layout[QPHY_LAYOUT_SIZE] = {
+ [QPHY_START_CTRL] = QPHY_V2_PCS_UFS_PHY_START,
+ [QPHY_PCS_READY_STATUS] = QPHY_V2_PCS_UFS_READY_STATUS,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V2_PCS_UFS_POWER_DOWN_CONTROL,
+};
+
static const unsigned int ufsphy_v3_regs_layout[QPHY_LAYOUT_SIZE] = {
[QPHY_START_CTRL] = QPHY_V3_PCS_UFS_PHY_START,
[QPHY_PCS_READY_STATUS] = QPHY_V3_PCS_UFS_READY_STATUS,
@@ -715,6 +721,98 @@ static const struct qmp_ufs_init_tbl sc7280_ufsphy_hs_g4_rx[] = {
QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x0f),
};
+static const struct qmp_ufs_init_tbl sm6115_ufsphy_serdes[] = {
+ QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
+ QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
+ QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
+ QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
+ QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
+ QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
+ QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
+ QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
+ QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
+ QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
+ QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
+ QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL1, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL2, 0x00),
+};
+
+static const struct qmp_ufs_init_tbl sm6115_ufsphy_hs_b_serdes[] = {
+ QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x44),
+};
+
+static const struct qmp_ufs_init_tbl sm6115_ufsphy_tx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
+ QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
+};
+
+static const struct qmp_ufs_init_tbl sm6115_ufsphy_rx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
+ QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x40),
+ QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
+ QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
+ QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5b),
+ QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0d),
+ QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5b),
+};
+
+static const struct qmp_ufs_init_tbl sm6115_ufsphy_pcs[] = {
+ QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_PWM_GEAR_BAND, 0x15),
+ QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
+ QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
+ QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
+ QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28),
+ QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_SYM_RESYNC_CTRL, 0x03),
+ QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_LARGE_AMP_POST_EMP_LVL, 0x12),
+ QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_SMALL_AMP_POST_EMP_LVL, 0x0f),
+ QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */
+};
+
struct qmp_ufs_offsets {
u16 serdes;
u16 pcs;
@@ -1079,6 +1177,34 @@ static const struct qmp_ufs_cfg sa8775p_ufsphy_cfg = {
.regs = ufsphy_v5_regs_layout,
};
+static const struct qmp_ufs_cfg sm6115_ufsphy_cfg = {
+ .lanes = 1,
+
+ .offsets = &qmp_ufs_offsets,
+
+ .tbls = {
+ .serdes = sm6115_ufsphy_serdes,
+ .serdes_num = ARRAY_SIZE(sm6115_ufsphy_serdes),
+ .tx = sm6115_ufsphy_tx,
+ .tx_num = ARRAY_SIZE(sm6115_ufsphy_tx),
+ .rx = sm6115_ufsphy_rx,
+ .rx_num = ARRAY_SIZE(sm6115_ufsphy_rx),
+ .pcs = sm6115_ufsphy_pcs,
+ .pcs_num = ARRAY_SIZE(sm6115_ufsphy_pcs),
+ },
+ .tbls_hs_b = {
+ .serdes = sm6115_ufsphy_hs_b_serdes,
+ .serdes_num = ARRAY_SIZE(sm6115_ufsphy_hs_b_serdes),
+ },
+ .clk_list = sdm845_ufs_phy_clk_l,
+ .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
+ .vreg_list = qmp_ufs_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_ufs_vreg_l),
+ .regs = ufsphy_v2_regs_layout,
+
+ .no_pcs_sw_reset = true,
+};
+
static void qmp_ufs_configure_lane(void __iomem *base,
const struct qmp_ufs_init_tbl tbl[],
int num,
@@ -1469,9 +1595,11 @@ static const struct udevice_id qmp_ufs_ids[] = {
{ .compatible = "qcom,sdm845-qmp-ufs-phy", .data = (ulong)&sdm845_ufsphy_cfg },
{ .compatible = "qcom,sm8150-qmp-ufs-phy", .data = (ulong)&sm8150_ufsphy_cfg },
{ .compatible = "qcom,sm8250-qmp-ufs-phy", .data = (ulong)&sm8250_ufsphy_cfg },
+ { .compatible = "qcom,qcs8300-qmp-ufs-phy", .data = (ulong)&sa8775p_ufsphy_cfg },
{ .compatible = "qcom,sm8550-qmp-ufs-phy", .data = (ulong)&sm8550_ufsphy_cfg },
{ .compatible = "qcom,sm8650-qmp-ufs-phy", .data = (ulong)&sm8650_ufsphy_cfg },
{ .compatible = "qcom,sc7280-qmp-ufs-phy", .data = (ulong)&sc7280_ufsphy_cfg, },
+ { .compatible = "qcom,qcs615-qmp-ufs-phy", .data = (ulong)&sm6115_ufsphy_cfg, },
{ }
};
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 8d47fa0cfd5..5e2808abc8a 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -341,6 +341,14 @@ config SPL_PINCTRL_STMFX
This option is an SPL-variant of the SPL_PINCTRL_STMFX option.
See the help of PINCTRL_STMFX for details.
+config PINCTRL_TH1520
+ bool "T-Head TH1520 pinctrl driver"
+ depends on DM && PINCTRL_FULL
+ select PINCONF
+ help
+ Support pin multiplexing and configuration control blocks on the
+ T-Head TH1520 SoC.
+
config ASPEED_AST2500_PINCTRL
bool "Aspeed AST2500 pin control driver"
depends on DM && PINCTRL_GENERIC && ASPEED_AST2500
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index fc9c604c485..33ff7b95ef2 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_PINCTRL_STI) += pinctrl-sti.o
obj-$(CONFIG_PINCTRL_STM32) += pinctrl_stm32.o
obj-$(CONFIG_$(PHASE_)PINCTRL_SX150X) += pinctrl-sx150x.o
obj-$(CONFIG_$(PHASE_)PINCTRL_STMFX) += pinctrl-stmfx.o
+obj-$(CONFIG_PINCTRL_TH1520) += pinctrl-th1520.o
obj-y += broadcom/
obj-$(CONFIG_PINCTRL_ZYNQMP) += pinctrl-zynqmp.o
obj-$(CONFIG_PINCTRL_STARFIVE) += starfive/
diff --git a/drivers/pinctrl/nxp/pinctrl-imx-mmio.c b/drivers/pinctrl/nxp/pinctrl-imx-mmio.c
index 6ee108a0120..2f4228a9fc5 100644
--- a/drivers/pinctrl/nxp/pinctrl-imx-mmio.c
+++ b/drivers/pinctrl/nxp/pinctrl-imx-mmio.c
@@ -187,7 +187,6 @@ int imx_pinctrl_probe_mmio(struct udevice *dev)
return -ENOMEM;
priv->info = info;
- info->mux_mask = ofnode_read_u32_default(node, "fsl,mux_mask", 0);
/*
* Refer to linux documentation for details:
* Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt
diff --git a/drivers/pinctrl/nxp/pinctrl-imx8ulp.c b/drivers/pinctrl/nxp/pinctrl-imx8ulp.c
index 2df63625191..3e8c080d3fd 100644
--- a/drivers/pinctrl/nxp/pinctrl-imx8ulp.c
+++ b/drivers/pinctrl/nxp/pinctrl-imx8ulp.c
@@ -11,10 +11,12 @@
static struct imx_pinctrl_soc_info imx8ulp_pinctrl_soc_info0 = {
.flags = ZERO_OFFSET_VALID | SHARE_MUX_CONF_REG | CFG_IBE_OBE,
+ .mux_mask = 0xf00,
};
static struct imx_pinctrl_soc_info imx8ulp_pinctrl_soc_info1 = {
.flags = ZERO_OFFSET_VALID | SHARE_MUX_CONF_REG | CFG_IBE_OBE,
+ .mux_mask = 0xf00,
};
static const struct udevice_id imx8ulp_pinctrl_match[] = {
diff --git a/drivers/pinctrl/nxp/pinctrl-imxrt.c b/drivers/pinctrl/nxp/pinctrl-imxrt.c
index 39000ceb923..7e55d596248 100644
--- a/drivers/pinctrl/nxp/pinctrl-imxrt.c
+++ b/drivers/pinctrl/nxp/pinctrl-imxrt.c
@@ -11,6 +11,7 @@
static struct imx_pinctrl_soc_info imxrt_pinctrl_soc_info = {
.flags = ZERO_OFFSET_VALID,
+ .mux_mask = 0x7,
};
static const struct udevice_id imxrt_pinctrl_match[] = {
diff --git a/drivers/pinctrl/nxp/pinctrl-vf610.c b/drivers/pinctrl/nxp/pinctrl-vf610.c
index cbff8dcefd8..7d1b95eaa05 100644
--- a/drivers/pinctrl/nxp/pinctrl-vf610.c
+++ b/drivers/pinctrl/nxp/pinctrl-vf610.c
@@ -11,6 +11,7 @@
static struct imx_pinctrl_soc_info vf610_pinctrl_soc_info = {
.flags = SHARE_MUX_CONF_REG | ZERO_OFFSET_VALID,
+ .mux_mask = 0x700000,
};
static const struct udevice_id vf610_pinctrl_match[] = {
diff --git a/drivers/pinctrl/pinctrl-th1520.c b/drivers/pinctrl/pinctrl-th1520.c
new file mode 100644
index 00000000000..be7e508f8a4
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-th1520.c
@@ -0,0 +1,700 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Pinctrl driver for the T-Head TH1520 SoC
+ *
+ * Copyright (C) 2023 Emil Renner Berthing <emil.renner.berthing@canonical.com>
+ * Copyright (C) 2025 Yao Zi <ziyao@disroot.org>
+ */
+
+#include <asm/io.h>
+#include <clk.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <linux/bitops.h>
+#include <linux/string.h>
+#include <malloc.h>
+
+#define TH1520_PADCFG_IE BIT(9)
+#define TH1520_PADCFG_SL BIT(8)
+#define TH1520_PADCFG_ST BIT(7)
+#define TH1520_PADCFG_SPU BIT(6)
+#define TH1520_PADCFG_PS BIT(5)
+#define TH1520_PADCFG_PE BIT(4)
+#define TH1520_PADCFG_BIAS (TH1520_PADCFG_SPU | TH1520_PADCFG_PS | TH1520_PADCFG_PE)
+#define TH1520_PADCFG_DS GENMASK(3, 0)
+
+#define TH1520_PULL_DOWN_OHM 44000 /* typ. 44kOhm */
+#define TH1520_PULL_UP_OHM 48000 /* typ. 48kOhm */
+#define TH1520_PULL_STRONG_OHM 2100 /* typ. 2.1kOhm */
+
+#define TH1520_PAD_NO_PADCFG BIT(0)
+
+enum th1520_muxtype {
+ TH1520_MUX_____,
+ TH1520_MUX_GPIO,
+ TH1520_MUX_PWM,
+ TH1520_MUX_UART,
+ TH1520_MUX_IR,
+ TH1520_MUX_I2C,
+ TH1520_MUX_SPI,
+ TH1520_MUX_QSPI,
+ TH1520_MUX_SDIO,
+ TH1520_MUX_AUD,
+ TH1520_MUX_I2S,
+ TH1520_MUX_MAC0,
+ TH1520_MUX_MAC1,
+ TH1520_MUX_DPU0,
+ TH1520_MUX_DPU1,
+ TH1520_MUX_ISP,
+ TH1520_MUX_HDMI,
+ TH1520_MUX_BSEL,
+ TH1520_MUX_DBG,
+ TH1520_MUX_CLK,
+ TH1520_MUX_JTAG,
+ TH1520_MUX_ISO,
+ TH1520_MUX_FUSE,
+ TH1520_MUX_RST,
+};
+
+static const char *const th1520_muxtype_string[] = {
+ [TH1520_MUX_GPIO] = "gpio",
+ [TH1520_MUX_PWM] = "pwm",
+ [TH1520_MUX_UART] = "uart",
+ [TH1520_MUX_IR] = "ir",
+ [TH1520_MUX_I2C] = "i2c",
+ [TH1520_MUX_SPI] = "spi",
+ [TH1520_MUX_QSPI] = "qspi",
+ [TH1520_MUX_SDIO] = "sdio",
+ [TH1520_MUX_AUD] = "audio",
+ [TH1520_MUX_I2S] = "i2s",
+ [TH1520_MUX_MAC0] = "gmac0",
+ [TH1520_MUX_MAC1] = "gmac1",
+ [TH1520_MUX_DPU0] = "dpu0",
+ [TH1520_MUX_DPU1] = "dpu1",
+ [TH1520_MUX_ISP] = "isp",
+ [TH1520_MUX_HDMI] = "hdmi",
+ [TH1520_MUX_BSEL] = "bootsel",
+ [TH1520_MUX_DBG] = "debug",
+ [TH1520_MUX_CLK] = "clock",
+ [TH1520_MUX_JTAG] = "jtag",
+ [TH1520_MUX_ISO] = "iso7816",
+ [TH1520_MUX_FUSE] = "efuse",
+ [TH1520_MUX_RST] = "reset",
+};
+
+struct th1520_pin_desc {
+ unsigned int number;
+ const char *name;
+ enum th1520_muxtype muxes[6];
+ u8 flags;
+};
+
+struct th1520_pad_group {
+ unsigned int npins;
+ const struct th1520_pin_desc *pins;
+ const char *name;
+};
+
+struct th1520_pinctrl {
+ const struct th1520_pad_group *group;
+ void __iomem *base;
+ struct pinctrl_dev *pctl;
+};
+
+static enum th1520_muxtype th1520_muxtype_get(const char *str)
+{
+ enum th1520_muxtype mt;
+
+ for (mt = TH1520_MUX_GPIO; mt < ARRAY_SIZE(th1520_muxtype_string); mt++) {
+ if (!strcmp(str, th1520_muxtype_string[mt]))
+ return mt;
+ }
+ return TH1520_MUX_____;
+}
+
+#define TH1520_PAD(_nr, _name, m0, m1, m2, m3, m4, m5, _flags) \
+ { \
+ .number = _nr, \
+ .name = #_name, \
+ .muxes = { \
+ TH1520_MUX_##m0, TH1520_MUX_##m1, \
+ TH1520_MUX_##m2, TH1520_MUX_##m3, \
+ TH1520_MUX_##m4, TH1520_MUX_##m5 \
+ }, \
+ .flags = _flags, \
+ }
+
+static bool th1520_pad_no_padcfg(const struct th1520_pin_desc *pin)
+{
+ return pin->flags & TH1520_PAD_NO_PADCFG;
+}
+
+static const struct th1520_pin_desc th1520_group1_pins[] = {
+ TH1520_PAD(0, OSC_CLK_IN, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG),
+ TH1520_PAD(1, OSC_CLK_OUT, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG),
+ TH1520_PAD(2, SYS_RST_N, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG),
+ TH1520_PAD(3, RTC_CLK_IN, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG),
+ TH1520_PAD(4, RTC_CLK_OUT, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG),
+ /* skip number 5 so we can calculate register offsets and shifts from the pin number */
+ TH1520_PAD(6, TEST_MODE, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG),
+ TH1520_PAD(7, DEBUG_MODE, DBG, ____, ____, GPIO, ____, ____, TH1520_PAD_NO_PADCFG),
+ TH1520_PAD(8, POR_SEL, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG),
+ TH1520_PAD(9, I2C_AON_SCL, I2C, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(10, I2C_AON_SDA, I2C, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(11, CPU_JTG_TCLK, JTAG, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(12, CPU_JTG_TMS, JTAG, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(13, CPU_JTG_TDI, JTAG, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(14, CPU_JTG_TDO, JTAG, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(15, CPU_JTG_TRST, JTAG, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(16, AOGPIO_7, CLK, AUD, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(17, AOGPIO_8, UART, AUD, IR, GPIO, ____, ____, 0),
+ TH1520_PAD(18, AOGPIO_9, UART, AUD, IR, GPIO, ____, ____, 0),
+ TH1520_PAD(19, AOGPIO_10, CLK, AUD, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(20, AOGPIO_11, GPIO, AUD, ____, ____, ____, ____, 0),
+ TH1520_PAD(21, AOGPIO_12, GPIO, AUD, ____, ____, ____, ____, 0),
+ TH1520_PAD(22, AOGPIO_13, GPIO, AUD, ____, ____, ____, ____, 0),
+ TH1520_PAD(23, AOGPIO_14, GPIO, AUD, ____, ____, ____, ____, 0),
+ TH1520_PAD(24, AOGPIO_15, GPIO, AUD, ____, ____, ____, ____, 0),
+ TH1520_PAD(25, AUDIO_PA0, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(26, AUDIO_PA1, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(27, AUDIO_PA2, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(28, AUDIO_PA3, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(29, AUDIO_PA4, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(30, AUDIO_PA5, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(31, AUDIO_PA6, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(32, AUDIO_PA7, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(33, AUDIO_PA8, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(34, AUDIO_PA9, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(35, AUDIO_PA10, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(36, AUDIO_PA11, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(37, AUDIO_PA12, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(38, AUDIO_PA13, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(39, AUDIO_PA14, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(40, AUDIO_PA15, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(41, AUDIO_PA16, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(42, AUDIO_PA17, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(43, AUDIO_PA27, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(44, AUDIO_PA28, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(45, AUDIO_PA29, AUD, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(46, AUDIO_PA30, AUD, RST, ____, GPIO, ____, ____, 0),
+};
+
+static const struct th1520_pin_desc th1520_group2_pins[] = {
+ TH1520_PAD(0, QSPI1_SCLK, QSPI, ISO, ____, GPIO, FUSE, ____, 0),
+ TH1520_PAD(1, QSPI1_CSN0, QSPI, ____, I2C, GPIO, FUSE, ____, 0),
+ TH1520_PAD(2, QSPI1_D0_MOSI, QSPI, ISO, I2C, GPIO, FUSE, ____, 0),
+ TH1520_PAD(3, QSPI1_D1_MISO, QSPI, ISO, ____, GPIO, FUSE, ____, 0),
+ TH1520_PAD(4, QSPI1_D2_WP, QSPI, ISO, UART, GPIO, FUSE, ____, 0),
+ TH1520_PAD(5, QSPI1_D3_HOLD, QSPI, ISO, UART, GPIO, ____, ____, 0),
+ TH1520_PAD(6, I2C0_SCL, I2C, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(7, I2C0_SDA, I2C, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(8, I2C1_SCL, I2C, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(9, I2C1_SDA, I2C, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(10, UART1_TXD, UART, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(11, UART1_RXD, UART, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(12, UART4_TXD, UART, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(13, UART4_RXD, UART, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(14, UART4_CTSN, UART, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(15, UART4_RTSN, UART, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(16, UART3_TXD, DBG, UART, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(17, UART3_RXD, DBG, UART, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(18, GPIO0_18, GPIO, I2C, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(19, GPIO0_19, GPIO, I2C, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(20, GPIO0_20, GPIO, UART, IR, ____, DPU0, DPU1, 0),
+ TH1520_PAD(21, GPIO0_21, GPIO, UART, IR, ____, DPU0, DPU1, 0),
+ TH1520_PAD(22, GPIO0_22, GPIO, JTAG, I2C, ____, DPU0, DPU1, 0),
+ TH1520_PAD(23, GPIO0_23, GPIO, JTAG, I2C, ____, DPU0, DPU1, 0),
+ TH1520_PAD(24, GPIO0_24, GPIO, JTAG, QSPI, ____, DPU0, DPU1, 0),
+ TH1520_PAD(25, GPIO0_25, GPIO, JTAG, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(26, GPIO0_26, GPIO, JTAG, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(27, GPIO0_27, GPIO, ____, I2C, ____, DPU0, DPU1, 0),
+ TH1520_PAD(28, GPIO0_28, GPIO, ____, I2C, ____, DPU0, DPU1, 0),
+ TH1520_PAD(29, GPIO0_29, GPIO, ____, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(30, GPIO0_30, GPIO, ____, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(31, GPIO0_31, GPIO, ____, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(32, GPIO1_0, GPIO, JTAG, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(33, GPIO1_1, GPIO, JTAG, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(34, GPIO1_2, GPIO, JTAG, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(35, GPIO1_3, GPIO, JTAG, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(36, GPIO1_4, GPIO, JTAG, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(37, GPIO1_5, GPIO, ____, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(38, GPIO1_6, GPIO, QSPI, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(39, GPIO1_7, GPIO, QSPI, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(40, GPIO1_8, GPIO, QSPI, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(41, GPIO1_9, GPIO, QSPI, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(42, GPIO1_10, GPIO, QSPI, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(43, GPIO1_11, GPIO, QSPI, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(44, GPIO1_12, GPIO, QSPI, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(45, GPIO1_13, GPIO, UART, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(46, GPIO1_14, GPIO, UART, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(47, GPIO1_15, GPIO, UART, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(48, GPIO1_16, GPIO, UART, ____, ____, DPU0, DPU1, 0),
+ TH1520_PAD(49, CLK_OUT_0, BSEL, CLK, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(50, CLK_OUT_1, BSEL, CLK, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(51, CLK_OUT_2, BSEL, CLK, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(52, CLK_OUT_3, BSEL, CLK, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(53, GPIO1_21, JTAG, ____, ISP, GPIO, ____, ____, 0),
+ TH1520_PAD(54, GPIO1_22, JTAG, ____, ISP, GPIO, ____, ____, 0),
+ TH1520_PAD(55, GPIO1_23, JTAG, ____, ISP, GPIO, ____, ____, 0),
+ TH1520_PAD(56, GPIO1_24, JTAG, ____, ISP, GPIO, ____, ____, 0),
+ TH1520_PAD(57, GPIO1_25, JTAG, ____, ISP, GPIO, ____, ____, 0),
+ TH1520_PAD(58, GPIO1_26, GPIO, ____, ISP, ____, ____, ____, 0),
+ TH1520_PAD(59, GPIO1_27, GPIO, ____, ISP, ____, ____, ____, 0),
+ TH1520_PAD(60, GPIO1_28, GPIO, ____, ISP, ____, ____, ____, 0),
+ TH1520_PAD(61, GPIO1_29, GPIO, ____, ISP, ____, ____, ____, 0),
+ TH1520_PAD(62, GPIO1_30, GPIO, ____, ISP, ____, ____, ____, 0),
+};
+
+static const struct th1520_pin_desc th1520_group3_pins[] = {
+ TH1520_PAD(0, UART0_TXD, UART, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(1, UART0_RXD, UART, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(2, QSPI0_SCLK, QSPI, PWM, I2S, GPIO, ____, ____, 0),
+ TH1520_PAD(3, QSPI0_CSN0, QSPI, PWM, I2S, GPIO, ____, ____, 0),
+ TH1520_PAD(4, QSPI0_CSN1, QSPI, PWM, I2S, GPIO, ____, ____, 0),
+ TH1520_PAD(5, QSPI0_D0_MOSI, QSPI, PWM, I2S, GPIO, ____, ____, 0),
+ TH1520_PAD(6, QSPI0_D1_MISO, QSPI, PWM, I2S, GPIO, ____, ____, 0),
+ TH1520_PAD(7, QSPI0_D2_WP, QSPI, PWM, I2S, GPIO, ____, ____, 0),
+ TH1520_PAD(8, QSPI1_D3_HOLD, QSPI, ____, I2S, GPIO, ____, ____, 0),
+ TH1520_PAD(9, I2C2_SCL, I2C, UART, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(10, I2C2_SDA, I2C, UART, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(11, I2C3_SCL, I2C, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(12, I2C3_SDA, I2C, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(13, GPIO2_13, GPIO, SPI, ____, ____, ____, ____, 0),
+ TH1520_PAD(14, SPI_SCLK, SPI, UART, IR, GPIO, ____, ____, 0),
+ TH1520_PAD(15, SPI_CSN, SPI, UART, IR, GPIO, ____, ____, 0),
+ TH1520_PAD(16, SPI_MOSI, SPI, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(17, SPI_MISO, SPI, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(18, GPIO2_18, GPIO, MAC1, ____, ____, ____, ____, 0),
+ TH1520_PAD(19, GPIO2_19, GPIO, MAC1, ____, ____, ____, ____, 0),
+ TH1520_PAD(20, GPIO2_20, GPIO, MAC1, ____, ____, ____, ____, 0),
+ TH1520_PAD(21, GPIO2_21, GPIO, MAC1, ____, ____, ____, ____, 0),
+ TH1520_PAD(22, GPIO2_22, GPIO, MAC1, ____, ____, ____, ____, 0),
+ TH1520_PAD(23, GPIO2_23, GPIO, MAC1, ____, ____, ____, ____, 0),
+ TH1520_PAD(24, GPIO2_24, GPIO, MAC1, ____, ____, ____, ____, 0),
+ TH1520_PAD(25, GPIO2_25, GPIO, MAC1, ____, ____, ____, ____, 0),
+ TH1520_PAD(26, SDIO0_WPRTN, SDIO, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(27, SDIO0_DETN, SDIO, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(28, SDIO1_WPRTN, SDIO, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(29, SDIO1_DETN, SDIO, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(30, GPIO2_30, GPIO, MAC1, ____, ____, ____, ____, 0),
+ TH1520_PAD(31, GPIO2_31, GPIO, MAC1, ____, ____, ____, ____, 0),
+ TH1520_PAD(32, GPIO3_0, GPIO, MAC1, ____, ____, ____, ____, 0),
+ TH1520_PAD(33, GPIO3_1, GPIO, MAC1, ____, ____, ____, ____, 0),
+ TH1520_PAD(34, GPIO3_2, GPIO, PWM, ____, ____, ____, ____, 0),
+ TH1520_PAD(35, GPIO3_3, GPIO, PWM, ____, ____, ____, ____, 0),
+ TH1520_PAD(36, HDMI_SCL, HDMI, PWM, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(37, HDMI_SDA, HDMI, PWM, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(38, HDMI_CEC, HDMI, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(39, GMAC0_TX_CLK, MAC0, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(40, GMAC0_RX_CLK, MAC0, ____, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(41, GMAC0_TXEN, MAC0, UART, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(42, GMAC0_TXD0, MAC0, UART, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(43, GMAC0_TXD1, MAC0, UART, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(44, GMAC0_TXD2, MAC0, UART, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(45, GMAC0_TXD3, MAC0, I2C, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(46, GMAC0_RXDV, MAC0, I2C, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(47, GMAC0_RXD0, MAC0, I2C, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(48, GMAC0_RXD1, MAC0, I2C, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(49, GMAC0_RXD2, MAC0, SPI, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(50, GMAC0_RXD3, MAC0, SPI, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(51, GMAC0_MDC, MAC0, SPI, MAC1, GPIO, ____, ____, 0),
+ TH1520_PAD(52, GMAC0_MDIO, MAC0, SPI, MAC1, GPIO, ____, ____, 0),
+ TH1520_PAD(53, GMAC0_COL, MAC0, PWM, ____, GPIO, ____, ____, 0),
+ TH1520_PAD(54, GMAC0_CRS, MAC0, PWM, ____, GPIO, ____, ____, 0),
+};
+
+static const struct th1520_pad_group th1520_group1 = {
+ .name = "th1520-group1",
+ .pins = th1520_group1_pins,
+ .npins = ARRAY_SIZE(th1520_group1_pins),
+};
+
+static const struct th1520_pad_group th1520_group2 = {
+ .name = "th1520-group2",
+ .pins = th1520_group2_pins,
+ .npins = ARRAY_SIZE(th1520_group2_pins),
+};
+
+static const struct th1520_pad_group th1520_group3 = {
+ .name = "th1520-group3",
+ .pins = th1520_group3_pins,
+ .npins = ARRAY_SIZE(th1520_group3_pins),
+};
+
+static void __iomem *th1520_padcfg(struct th1520_pinctrl *thp,
+ unsigned int pin)
+{
+ return thp->base + 4 * (pin / 2);
+}
+
+static unsigned int th1520_padcfg_shift(unsigned int pin)
+{
+ return 16 * (pin & BIT(0));
+}
+
+static void __iomem *th1520_muxcfg(struct th1520_pinctrl *thp,
+ unsigned int pin)
+{
+ return thp->base + 0x400 + 4 * (pin / 8);
+}
+
+static unsigned int th1520_muxcfg_shift(unsigned int pin)
+{
+ return 4 * (pin & GENMASK(2, 0));
+}
+
+static const u8 th1520_drive_strength_in_ma[16] = {
+ 1, 2, 3, 5, 7, 8, 10, 12, 13, 15, 16, 18, 20, 21, 23, 25,
+};
+
+static u16 th1520_drive_strength_from_ma(u32 arg)
+{
+ u16 ds;
+
+ for (ds = 0; ds < TH1520_PADCFG_DS; ds++) {
+ if (arg <= th1520_drive_strength_in_ma[ds])
+ return ds;
+ }
+ return TH1520_PADCFG_DS;
+}
+
+static int th1520_padcfg_rmw(struct th1520_pinctrl *thp, unsigned int pin,
+ u32 mask, u32 value)
+{
+ void __iomem *padcfg = th1520_padcfg(thp, pin);
+ unsigned int shift = th1520_padcfg_shift(pin);
+ u32 tmp;
+
+ mask <<= shift;
+ value <<= shift;
+
+ tmp = readl_relaxed(padcfg);
+ tmp = (tmp & ~mask) | value;
+ writel_relaxed(tmp, padcfg);
+
+ return 0;
+}
+
+static int th1520_pinconf_apply_one(struct th1520_pinctrl *thp,
+ const struct th1520_pin_desc *desc,
+ enum pin_config_param param, u32 arg)
+
+{
+ u16 mask = 0, value = 0;
+
+ if (th1520_pad_no_padcfg(desc))
+ return -EOPNOTSUPP;
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ mask |= TH1520_PADCFG_BIAS;
+ value &= ~TH1520_PADCFG_BIAS;
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ if (arg == 0)
+ return -EOPNOTSUPP;
+ mask |= TH1520_PADCFG_BIAS;
+ value &= ~TH1520_PADCFG_BIAS;
+ value |= TH1520_PADCFG_PE;
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ if (arg == 0)
+ return -EOPNOTSUPP;
+ mask |= TH1520_PADCFG_BIAS;
+ value &= ~TH1520_PADCFG_BIAS;
+ if (arg == TH1520_PULL_STRONG_OHM)
+ value |= TH1520_PADCFG_SPU;
+ else
+ value |= TH1520_PADCFG_PE | TH1520_PADCFG_PS;
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ mask |= TH1520_PADCFG_DS;
+ value &= ~TH1520_PADCFG_DS;
+ value |= th1520_drive_strength_from_ma(arg);
+ break;
+ case PIN_CONFIG_INPUT_ENABLE:
+ mask |= TH1520_PADCFG_IE;
+ if (arg)
+ value |= TH1520_PADCFG_IE;
+ else
+ value &= ~TH1520_PADCFG_IE;
+ break;
+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+ mask |= TH1520_PADCFG_ST;
+ if (arg)
+ value |= TH1520_PADCFG_ST;
+ else
+ value &= ~TH1520_PADCFG_ST;
+ break;
+ case PIN_CONFIG_SLEW_RATE:
+ mask |= TH1520_PADCFG_SL;
+ if (arg)
+ value |= TH1520_PADCFG_SL;
+ else
+ value &= ~TH1520_PADCFG_SL;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return th1520_padcfg_rmw(thp, desc->number, mask, value);
+}
+
+static int th1520_pinmux_apply_one(struct th1520_pinctrl *thp,
+ const struct th1520_pin_desc *desc,
+ enum th1520_muxtype muxtype)
+{
+ void __iomem *muxcfg = th1520_muxcfg(thp, desc->number);
+ unsigned int shift = th1520_muxcfg_shift(desc->number);
+ u32 mask, value, tmp;
+
+ for (value = 0; value < ARRAY_SIZE(desc->muxes); value++) {
+ if (desc->muxes[value] == muxtype)
+ break;
+ }
+ if (value == ARRAY_SIZE(desc->muxes)) {
+ pr_err("invalid mux %s for pin \"%s\"\n",
+ th1520_muxtype_string[muxtype], desc->name);
+ return -EINVAL;
+ }
+
+ mask = GENMASK(3, 0) << shift;
+ value = value << shift;
+
+ tmp = readl_relaxed(muxcfg);
+ tmp = (tmp & ~mask) | value;
+ writel_relaxed(tmp, muxcfg);
+
+ return 0;
+}
+
+const struct pinconf_param th1520_pinconf_params[] = {
+ { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
+ { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
+ { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
+ { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
+ { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
+ { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
+ { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
+ { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
+ { "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
+};
+
+static const struct th1520_pin_desc *
+th1520_pinctrl_search_pin(struct th1520_pinctrl *thp,
+ const char *name)
+{
+ const struct th1520_pad_group *pg = thp->group;
+ int i;
+
+ for (i = 0; i < pg->npins; i++) {
+ if (!strcmp(pg->pins[i].name, name))
+ return &pg->pins[i];
+ }
+
+ return NULL;
+}
+
+static int th1520_pinctrl_apply_group(struct th1520_pinctrl *thp, ofnode group)
+{
+ struct th1520_pin_desc const **pins;
+ enum th1520_muxtype muxtype;
+ int pin_count, ret, i, j;
+ const char *muxname;
+
+ pin_count = ofnode_read_string_count(group, "pins");
+ if (pin_count < 0) {
+ pr_err("missing property pins");
+ return -EINVAL;
+ }
+
+ pins = calloc(pin_count, sizeof(pins[0]));
+ if (!pins)
+ return -ENOMEM;
+
+ for (i = 0; i < pin_count; i++) {
+ const char *pinname;
+
+ ret = ofnode_read_string_index(group, "pins", i, &pinname);
+ if (ret)
+ goto out;
+
+ pins[i] = th1520_pinctrl_search_pin(thp, pinname);
+ if (!pins[i]) {
+ pr_err("unknown pin name \"%s\"\n", pinname);
+ goto out;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(th1520_pinconf_params); i++) {
+ const struct pinconf_param *param = &th1520_pinconf_params[i];
+ u32 val;
+
+ ret = ofnode_read_u32(group, param->property, &val);
+ if (ret == -EINVAL)
+ continue;
+ else if (ret)
+ val = param->default_value;
+
+ for (j = 0; j < pin_count; j++) {
+ ret = th1520_pinconf_apply_one(thp, pins[j],
+ param->param, val);
+ if (ret) {
+ pr_err("failed to apply pinconf for \"%s\": %d\n",
+ pins[j]->name, ret);
+ goto out;
+ }
+ }
+ }
+
+ muxname = ofnode_read_string(group, "function");
+ if (!muxname)
+ goto out;
+
+ muxtype = th1520_muxtype_get(muxname);
+ if (!muxtype) {
+ pr_err("invalid mux type \"%s\"", muxname);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ for (i = 0; i < pin_count; i++) {
+ ret = th1520_pinmux_apply_one(thp, pins[i], muxtype);
+ if (ret) {
+ pr_err("failed to set pinmux function: %d\n", ret);
+ break;
+ }
+ }
+
+out:
+ free(pins);
+
+ return ret;
+}
+
+static int th1520_pinctrl_set_state(struct udevice *dev, struct udevice *pcfg)
+{
+ struct th1520_pinctrl *thp = dev_get_priv(dev);
+ ofnode group;
+ int ret = 0;
+
+ dev_for_each_subnode(group, pcfg) {
+ ret = th1520_pinctrl_apply_group(thp, group);
+ if (ret) {
+ pr_err("failed to apply pin group \"%s\": %d\n",
+ ofnode_get_name(group), ret);
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static int th1520_pinctrl_get_pins_count(struct udevice *dev)
+{
+ struct th1520_pinctrl *thp = dev_get_priv(dev);
+
+ return thp->group->npins;
+}
+
+static const char *th1520_pinctrl_get_pin_name(struct udevice *dev,
+ unsigned int selector)
+{
+ struct th1520_pinctrl *p = dev_get_priv(dev);
+
+ if (selector >= p->group->npins)
+ return ERR_PTR(-EINVAL);
+
+ return p->group->pins[selector].name;
+}
+
+static int th1520_pinctrl_get_pin_muxing(struct udevice *dev,
+ unsigned int selector,
+ char *buf, int size)
+{
+ struct th1520_pinctrl *thp = dev_get_priv(dev);
+ const struct th1520_pad_group *group = thp->group;
+ const struct th1520_pin_desc *desc;
+ void __iomem *muxcfg;
+ unsigned int shift;
+ u32 val;
+
+ if (selector >= group->npins)
+ return -EINVAL;
+
+ desc = &group->pins[selector];
+ if (th1520_pad_no_padcfg(desc)) {
+ strlcpy(buf, "unsupported", size - 1);
+ return 0;
+ }
+
+ muxcfg = th1520_muxcfg(thp, desc->number);
+ shift = th1520_muxcfg_shift(desc->number);
+
+ val = (readl_relaxed(muxcfg) >> shift) & GENMASK(3, 0);
+ strlcpy(buf, th1520_muxtype_string[desc->muxes[val]], size);
+
+ return 0;
+}
+
+static const struct pinctrl_ops th1520_pinctrl_ops = {
+ .get_pins_count = th1520_pinctrl_get_pins_count,
+ .get_pin_name = th1520_pinctrl_get_pin_name,
+ .get_pin_muxing = th1520_pinctrl_get_pin_muxing,
+ .set_state = th1520_pinctrl_set_state,
+};
+
+static int th1520_pinctrl_probe(struct udevice *dev)
+{
+ struct th1520_pinctrl *thp = dev_get_priv(dev);
+ struct clk clk;
+ u32 pin_group;
+ int ret;
+
+ thp->base = dev_read_addr_ptr(dev);
+ if (!thp->base)
+ return -EINVAL;
+
+ ret = clk_get_by_index(dev, 0, &clk);
+ if (ret) {
+ pr_err("failed to enable pinctrl clock: %d\n", ret);
+ return ret;
+ }
+
+ ret = dev_read_u32(dev, "thead,pad-group", &pin_group);
+ if (ret) {
+ pr_err("failed to read thead,pad-group property: %d\n", ret);
+ return ret;
+ }
+
+ switch (pin_group) {
+ case 1:
+ thp->group = &th1520_group1;
+ break;
+ case 2:
+ thp->group = &th1520_group2;
+ break;
+ case 3:
+ thp->group = &th1520_group3;
+ break;
+ default:
+ pr_err("invalid thead,pad-group property: %u\n", pin_group);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct udevice_id th1520_pinctrl_ids[] = {
+ { .compatible = "thead,th1520-pinctrl"},
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(th1520_pinctrl) = {
+ .name = "th1520-pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = th1520_pinctrl_ids,
+ .probe = th1520_pinctrl_probe,
+ .priv_auto = sizeof(struct th1520_pinctrl),
+ .ops = &th1520_pinctrl_ops,
+};
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
index e567cb113a3..21f81b66099 100644
--- a/drivers/pinctrl/qcom/Kconfig
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -27,6 +27,13 @@ config PINCTRL_QCOM_IPQ4019
Say Y here to enable support for pinctrl on the IPQ4019 SoC,
as well as the associated GPIO driver.
+config PINCTRL_QCOM_IPQ5424
+ bool "Qualcomm IPQ5424 Pinctrl"
+ select PINCTRL_QCOM
+ help
+ Say Y here to enable support for pinctrl on the IPQ5424 SoC,
+ as well as the associated GPIO driver.
+
config PINCTRL_QCOM_IPQ9574
bool "Qualcomm IPQ9574 Pinctrl"
select PINCTRL_QCOM
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
index 6ffc6d48c15..6cb53838e71 100644
--- a/drivers/pinctrl/qcom/Makefile
+++ b/drivers/pinctrl/qcom/Makefile
@@ -5,6 +5,7 @@
obj-$(CONFIG_PINCTRL_QCOM) += pinctrl-qcom.o
obj-$(CONFIG_PINCTRL_QCOM_APQ8016) += pinctrl-apq8016.o
obj-$(CONFIG_PINCTRL_QCOM_IPQ4019) += pinctrl-ipq4019.o
+obj-$(CONFIG_PINCTRL_QCOM_IPQ5424) += pinctrl-ipq5424.o
obj-$(CONFIG_PINCTRL_QCOM_IPQ9574) += pinctrl-ipq9574.o
obj-$(CONFIG_PINCTRL_QCOM_APQ8096) += pinctrl-apq8096.o
obj-$(CONFIG_PINCTRL_QCOM_QCM2290) += pinctrl-qcm2290.o
diff --git a/drivers/pinctrl/qcom/pinctrl-ipq5424.c b/drivers/pinctrl/qcom/pinctrl-ipq5424.c
new file mode 100644
index 00000000000..cde990a32ef
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-ipq5424.c
@@ -0,0 +1,322 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2016-2018,2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dm.h>
+
+#include "pinctrl-qcom.h"
+
+#define MAX_PIN_NAME_LEN 32
+static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
+
+enum ipq5424_functions {
+ msm_mux_atest_char,
+ msm_mux_atest_char0,
+ msm_mux_atest_char1,
+ msm_mux_atest_char2,
+ msm_mux_atest_char3,
+ msm_mux_atest_tic,
+ msm_mux_audio_pri,
+ msm_mux_audio_pri0,
+ msm_mux_audio_pri1,
+ msm_mux_audio_sec,
+ msm_mux_audio_sec0,
+ msm_mux_audio_sec1,
+ msm_mux_core_voltage,
+ msm_mux_cri_trng0,
+ msm_mux_cri_trng1,
+ msm_mux_cri_trng2,
+ msm_mux_cri_trng3,
+ msm_mux_cxc_clk,
+ msm_mux_cxc_data,
+ msm_mux_dbg_out,
+ msm_mux_gcc_plltest,
+ msm_mux_gcc_tlmm,
+ msm_mux_gpio,
+ msm_mux_i2c0_scl,
+ msm_mux_i2c0_sda,
+ msm_mux_i2c1_scl,
+ msm_mux_i2c1_sda,
+ msm_mux_i2c11,
+ msm_mux_mac0,
+ msm_mux_mac1,
+ msm_mux_mdc_mst,
+ msm_mux_mdc_slv,
+ msm_mux_mdio_mst,
+ msm_mux_mdio_slv,
+ msm_mux_pcie0_clk,
+ msm_mux_pcie0_wake,
+ msm_mux_pcie1_clk,
+ msm_mux_pcie1_wake,
+ msm_mux_pcie2_clk,
+ msm_mux_pcie2_wake,
+ msm_mux_pcie3_clk,
+ msm_mux_pcie3_wake,
+ msm_mux_pll_test,
+ msm_mux_prng_rosc0,
+ msm_mux_prng_rosc1,
+ msm_mux_prng_rosc2,
+ msm_mux_prng_rosc3,
+ msm_mux_PTA0_0,
+ msm_mux_PTA0_1,
+ msm_mux_PTA0_2,
+ msm_mux_PTA10,
+ msm_mux_PTA11,
+ msm_mux_pwm0,
+ msm_mux_pwm1,
+ msm_mux_pwm2,
+ msm_mux_qdss_cti_trig_in_a0,
+ msm_mux_qdss_cti_trig_out_a0,
+ msm_mux_qdss_cti_trig_in_a1,
+ msm_mux_qdss_cti_trig_out_a1,
+ msm_mux_qdss_cti_trig_in_b0,
+ msm_mux_qdss_cti_trig_out_b0,
+ msm_mux_qdss_cti_trig_in_b1,
+ msm_mux_qdss_cti_trig_out_b1,
+ msm_mux_qdss_traceclk_a,
+ msm_mux_qdss_tracectl_a,
+ msm_mux_qdss_tracedata_a,
+ msm_mux_qspi_clk,
+ msm_mux_qspi_cs,
+ msm_mux_qspi_data,
+ msm_mux_resout,
+ msm_mux_rx0,
+ msm_mux_rx1,
+ msm_mux_rx2,
+ msm_mux_sdc_clk,
+ msm_mux_sdc_cmd,
+ msm_mux_sdc_data,
+ msm_mux_spi0_clk,
+ msm_mux_spi0_cs,
+ msm_mux_spi0_miso,
+ msm_mux_spi0_mosi,
+ msm_mux_spi1,
+ msm_mux_spi10,
+ msm_mux_spi11,
+ msm_mux_tsens_max,
+ msm_mux_uart0,
+ msm_mux_uart1,
+ msm_mux_wci_txd,
+ msm_mux_wci_rxd,
+ msm_mux_wsi_clk,
+ msm_mux_wsi_data,
+ msm_mux__,
+};
+
+#define MSM_PIN_FUNCTION(fname) \
+ [msm_mux_##fname] = {#fname, msm_mux_##fname}
+
+static const struct pinctrl_function ipq5424_functions[] = {
+ MSM_PIN_FUNCTION(atest_char),
+ MSM_PIN_FUNCTION(atest_char0),
+ MSM_PIN_FUNCTION(atest_char1),
+ MSM_PIN_FUNCTION(atest_char2),
+ MSM_PIN_FUNCTION(atest_char3),
+ MSM_PIN_FUNCTION(atest_tic),
+ MSM_PIN_FUNCTION(audio_pri),
+ MSM_PIN_FUNCTION(audio_pri0),
+ MSM_PIN_FUNCTION(audio_pri1),
+ MSM_PIN_FUNCTION(audio_sec),
+ MSM_PIN_FUNCTION(audio_sec0),
+ MSM_PIN_FUNCTION(audio_sec1),
+ MSM_PIN_FUNCTION(core_voltage),
+ MSM_PIN_FUNCTION(cri_trng0),
+ MSM_PIN_FUNCTION(cri_trng1),
+ MSM_PIN_FUNCTION(cri_trng2),
+ MSM_PIN_FUNCTION(cri_trng3),
+ MSM_PIN_FUNCTION(cxc_clk),
+ MSM_PIN_FUNCTION(cxc_data),
+ MSM_PIN_FUNCTION(dbg_out),
+ MSM_PIN_FUNCTION(gcc_plltest),
+ MSM_PIN_FUNCTION(gcc_tlmm),
+ MSM_PIN_FUNCTION(gpio),
+ MSM_PIN_FUNCTION(i2c0_scl),
+ MSM_PIN_FUNCTION(i2c0_sda),
+ MSM_PIN_FUNCTION(i2c1_scl),
+ MSM_PIN_FUNCTION(i2c1_sda),
+ MSM_PIN_FUNCTION(i2c11),
+ MSM_PIN_FUNCTION(mac0),
+ MSM_PIN_FUNCTION(mac1),
+ MSM_PIN_FUNCTION(mdc_mst),
+ MSM_PIN_FUNCTION(mdc_slv),
+ MSM_PIN_FUNCTION(mdio_mst),
+ MSM_PIN_FUNCTION(mdio_slv),
+ MSM_PIN_FUNCTION(pcie0_clk),
+ MSM_PIN_FUNCTION(pcie0_wake),
+ MSM_PIN_FUNCTION(pcie1_clk),
+ MSM_PIN_FUNCTION(pcie1_wake),
+ MSM_PIN_FUNCTION(pcie2_clk),
+ MSM_PIN_FUNCTION(pcie2_wake),
+ MSM_PIN_FUNCTION(pcie3_clk),
+ MSM_PIN_FUNCTION(pcie3_wake),
+ MSM_PIN_FUNCTION(pll_test),
+ MSM_PIN_FUNCTION(prng_rosc0),
+ MSM_PIN_FUNCTION(prng_rosc1),
+ MSM_PIN_FUNCTION(prng_rosc2),
+ MSM_PIN_FUNCTION(prng_rosc3),
+ MSM_PIN_FUNCTION(PTA0_0),
+ MSM_PIN_FUNCTION(PTA0_1),
+ MSM_PIN_FUNCTION(PTA0_2),
+ MSM_PIN_FUNCTION(PTA10),
+ MSM_PIN_FUNCTION(PTA11),
+ MSM_PIN_FUNCTION(pwm0),
+ MSM_PIN_FUNCTION(pwm1),
+ MSM_PIN_FUNCTION(pwm2),
+ MSM_PIN_FUNCTION(qdss_cti_trig_in_a0),
+ MSM_PIN_FUNCTION(qdss_cti_trig_out_a0),
+ MSM_PIN_FUNCTION(qdss_cti_trig_in_a1),
+ MSM_PIN_FUNCTION(qdss_cti_trig_out_a1),
+ MSM_PIN_FUNCTION(qdss_cti_trig_in_b0),
+ MSM_PIN_FUNCTION(qdss_cti_trig_out_b0),
+ MSM_PIN_FUNCTION(qdss_cti_trig_in_b1),
+ MSM_PIN_FUNCTION(qdss_cti_trig_out_b1),
+ MSM_PIN_FUNCTION(qdss_traceclk_a),
+ MSM_PIN_FUNCTION(qdss_tracectl_a),
+ MSM_PIN_FUNCTION(qdss_tracedata_a),
+ MSM_PIN_FUNCTION(qspi_clk),
+ MSM_PIN_FUNCTION(qspi_cs),
+ MSM_PIN_FUNCTION(qspi_data),
+ MSM_PIN_FUNCTION(resout),
+ MSM_PIN_FUNCTION(rx0),
+ MSM_PIN_FUNCTION(rx1),
+ MSM_PIN_FUNCTION(rx2),
+ MSM_PIN_FUNCTION(sdc_clk),
+ MSM_PIN_FUNCTION(sdc_cmd),
+ MSM_PIN_FUNCTION(sdc_data),
+ MSM_PIN_FUNCTION(spi0_clk),
+ MSM_PIN_FUNCTION(spi0_cs),
+ MSM_PIN_FUNCTION(spi0_miso),
+ MSM_PIN_FUNCTION(spi0_mosi),
+ MSM_PIN_FUNCTION(spi1),
+ MSM_PIN_FUNCTION(spi10),
+ MSM_PIN_FUNCTION(spi11),
+ MSM_PIN_FUNCTION(tsens_max),
+ MSM_PIN_FUNCTION(uart0),
+ MSM_PIN_FUNCTION(uart1),
+ MSM_PIN_FUNCTION(wci_txd),
+ MSM_PIN_FUNCTION(wci_rxd),
+ MSM_PIN_FUNCTION(wsi_clk),
+ MSM_PIN_FUNCTION(wsi_data),
+};
+
+typedef unsigned int msm_pin_function[10];
+
+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9)\
+ [id] = { msm_mux_gpio, /* gpio mode */ \
+ msm_mux_##f1, \
+ msm_mux_##f2, \
+ msm_mux_##f3, \
+ msm_mux_##f4, \
+ msm_mux_##f5, \
+ msm_mux_##f6, \
+ msm_mux_##f7, \
+ msm_mux_##f8, \
+ msm_mux_##f9, \
+ }
+
+static const msm_pin_function ipq5424_pin_functions[] = {
+ PINGROUP(0, sdc_data, qspi_data, pwm2, wci_txd, wci_rxd, _, _, _, _),
+ PINGROUP(1, sdc_data, qspi_data, pwm2, wci_txd, wci_rxd, _, _, _, _),
+ PINGROUP(2, sdc_data, qspi_data, pwm2, _, _, _, _, _, _),
+ PINGROUP(3, sdc_data, qspi_data, pwm2, _, _, _, _, _, _),
+ PINGROUP(4, sdc_cmd, qspi_cs, _, _, _, _, _, _, _),
+ PINGROUP(5, sdc_clk, qspi_clk, _, _, _, _, _, _, _),
+ PINGROUP(6, spi0_clk, pwm1, _, cri_trng0, qdss_tracedata_a, _, _, _, _),
+ PINGROUP(7, spi0_cs, pwm1, _, cri_trng1, qdss_tracedata_a, _, _, _, _),
+ PINGROUP(8, spi0_miso, pwm1, wci_txd, wci_rxd, _, cri_trng2, qdss_tracedata_a, _, _),
+ PINGROUP(9, spi0_mosi, pwm1, _, cri_trng3, qdss_tracedata_a, _, _, _, _),
+ PINGROUP(10, uart0, pwm0, spi11, _, wci_txd, wci_rxd, _, qdss_tracedata_a, _),
+ PINGROUP(11, uart0, pwm0, spi1, _, wci_txd, wci_rxd, _, qdss_tracedata_a, _),
+ PINGROUP(12, uart0, pwm0, spi11, _, prng_rosc0, qdss_tracedata_a, _, _, _),
+ PINGROUP(13, uart0, pwm0, spi11, _, prng_rosc1, qdss_tracedata_a, _, _, _),
+ PINGROUP(14, i2c0_scl, tsens_max, _, prng_rosc2, qdss_tracedata_a, _, _, _, _),
+ PINGROUP(15, i2c0_sda, _, prng_rosc3, qdss_tracedata_a, _, _, _, _, _),
+ PINGROUP(16, core_voltage, i2c1_scl, _, _, _, _, _, _, _),
+ PINGROUP(17, core_voltage, i2c1_sda, _, _, _, _, _, _, _),
+ PINGROUP(18, _, _, _, _, _, _, _, _, _),
+ PINGROUP(19, _, _, _, _, _, _, _, _, _),
+ PINGROUP(20, mdc_slv, atest_char0, _, qdss_tracedata_a, _, _, _, _, _),
+ PINGROUP(21, mdio_slv, atest_char1, _, qdss_tracedata_a, _, _, _, _, _),
+ PINGROUP(22, mdc_mst, atest_char2, _, _, _, _, _, _, _),
+ PINGROUP(23, mdio_mst, atest_char3, _, _, _, _, _, _, _),
+ PINGROUP(24, pcie0_clk, PTA10, mac0, _, wsi_clk, _, atest_char, qdss_cti_trig_out_a0, _),
+ PINGROUP(25, _, _, _, _, _, _, _, _, _),
+ PINGROUP(26, pcie0_wake, PTA10, mac0, _, wsi_data, _, qdss_cti_trig_in_a0, _, _),
+ PINGROUP(27, pcie1_clk, i2c11, PTA10, wsi_clk, qdss_cti_trig_out_a1, _, _, _, _),
+ PINGROUP(28, _, _, _, _, _, _, _, _, _),
+ PINGROUP(29, pcie1_wake, i2c11, wsi_data, qdss_cti_trig_in_a1, _, _, _, _, _),
+ PINGROUP(30, pcie2_clk, PTA11, mac1, qdss_cti_trig_out_b0, _, _, _, _, _),
+ PINGROUP(31, _, _, _, _, _, _, _, _, _),
+ PINGROUP(32, pcie2_wake, PTA11, mac1, audio_pri0, audio_pri0, qdss_cti_trig_in_b0, _, _, _),
+ PINGROUP(33, pcie3_clk, PTA11, audio_pri1, audio_pri1, qdss_cti_trig_out_b1, _, _, _, _),
+ PINGROUP(34, _, _, _, _, _, _, _, _, _),
+ PINGROUP(35, pcie3_wake, audio_sec1, audio_sec1, qdss_cti_trig_in_b1, _, _, _, _, _),
+ PINGROUP(36, audio_pri, spi1, audio_sec0, audio_sec0, qdss_tracedata_a, _, _, _, _),
+ PINGROUP(37, audio_pri, spi1, rx2, qdss_tracedata_a, _, _, _, _, _),
+ PINGROUP(38, audio_pri, spi1, pll_test, rx1, qdss_tracedata_a, _, _, _, _),
+ PINGROUP(39, audio_pri, rx0, _, qdss_tracedata_a, _, _, _, _, _),
+ PINGROUP(40, PTA0_0, wci_txd, wci_rxd, _, atest_tic, _, _, _, _),
+ PINGROUP(41, PTA0_1, wci_txd, wci_rxd, cxc_data, _, _, _, _, _),
+ PINGROUP(42, PTA0_2, cxc_clk, _, _, _, _, _, _, _),
+ PINGROUP(43, uart1, gcc_plltest, _, _, _, _, _, _, _),
+ PINGROUP(44, uart1, gcc_tlmm, _, _, _, _, _, _, _),
+ PINGROUP(45, spi10, rx2, audio_sec, gcc_plltest, _, qdss_traceclk_a, _, _, _),
+ PINGROUP(46, spi1, rx1, audio_sec, dbg_out, qdss_tracectl_a, _, _, _, _),
+ PINGROUP(47, spi10, rx0, audio_sec, _, _, _, _, _, _),
+ PINGROUP(48, spi10, audio_sec, _, _, _, _, _, _, _),
+ PINGROUP(49, resout, _, _, _, _, _, _, _, _),
+};
+
+static const char *ipq5424_get_function_name(struct udevice *dev,
+ unsigned int selector)
+{
+ return ipq5424_functions[selector].name;
+}
+
+static const char *ipq5424_get_pin_name(struct udevice *dev,
+ unsigned int selector)
+{
+ snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
+ return pin_name;
+}
+
+static int ipq5424_get_function_mux(unsigned int pin, unsigned int selector)
+{
+ unsigned int i;
+ const msm_pin_function *func = ipq5424_pin_functions + pin;
+
+ for (i = 0; i < 10; i++)
+ if ((*func)[i] == selector)
+ return i;
+
+ debug("Can't find requested function for pin:selector %u:%u\n",
+ pin, selector);
+
+ return -EINVAL;
+}
+
+static const struct msm_pinctrl_data ipq5424_data = {
+ .pin_data = {
+ .pin_count = 49,
+ },
+ .functions_count = ARRAY_SIZE(ipq5424_functions),
+ .get_function_name = ipq5424_get_function_name,
+ .get_function_mux = ipq5424_get_function_mux,
+ .get_pin_name = ipq5424_get_pin_name,
+};
+
+static const struct udevice_id msm_pinctrl_ids[] = {
+ { .compatible = "qcom,ipq5424-tlmm", .data = (ulong)&ipq5424_data },
+ { /* Sentinal */ }
+};
+
+U_BOOT_DRIVER(pinctrl_ipq5424) = {
+ .name = "pinctrl_ipq5424",
+ .id = UCLASS_NOP,
+ .of_match = msm_pinctrl_ids,
+ .ops = &msm_pinctrl_ops,
+ .bind = msm_pinctrl_bind,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 6467f20422b..79b879d68d1 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -94,6 +94,13 @@ config RTC_DS1374
Support for Dallas Semiconductor (now Maxim) DS1374 and compatible
Real Time Clock devices.
+config RTC_DS1672
+ bool "Enable DS1672 driver"
+ depends on DM_RTC
+ help
+ Support for Dallas Semiconductor (now Maxim) DS1672 compatible
+ Real Time Clock devices.
+
config RTC_DS3231
bool "Enable DS3231 driver"
help
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 99b5a2a346a..a4ede413cd1 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_RTC_DS1307) += ds1307.o
obj-$(CONFIG_RTC_DS1338) += ds1307.o
obj-$(CONFIG_RTC_DS1337) += ds1337.o
obj-$(CONFIG_RTC_DS1374) += ds1374.o
+obj-$(CONFIG_RTC_DS1672) += ds1672.o
obj-$(CONFIG_RTC_DS3231) += ds3231.o
obj-$(CONFIG_RTC_DS3232) += ds3232.o
obj-$(CONFIG_RTC_EMULATION) += emul_rtc.o
diff --git a/drivers/rtc/ds1672.c b/drivers/rtc/ds1672.c
new file mode 100644
index 00000000000..4705e5abc93
--- /dev/null
+++ b/drivers/rtc/ds1672.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Analog Devices DS1672 I2C RTC driver
+ *
+ * Copyright 2025 Gateworks Corporation.
+ */
+#include <dm.h>
+#include <i2c.h>
+#include <rtc.h>
+#include <dm/device_compat.h>
+
+/* Registers */
+#define DS1672_REG_CNT_BASE 0
+#define DS1672_REG_CONTROL 4
+#define DS1672_REG_TRICKLE 5
+
+#define DS1672_REG_CONTROL_EOSC 0x80
+
+static int ds1672_read_time(struct udevice *dev, struct rtc_time *tm)
+{
+ time64_t secs;
+ u8 regs[4];
+ int ret;
+
+ ret = dm_i2c_read(dev, DS1672_REG_CONTROL, regs, 1);
+ if (ret)
+ return ret;
+
+ if (regs[0] & DS1672_REG_CONTROL_EOSC) {
+ dev_err(dev, "Oscillator not enabled. Set time to enable.\n");
+ return -EINVAL;
+ }
+
+ ret = dm_i2c_read(dev, DS1672_REG_CNT_BASE, regs, 4);
+ if (ret)
+ return ret;
+ dev_dbg(dev, "raw read: 0x%02x 0x%02x 0x%02x 0x%02x\n",
+ regs[0], regs[1], regs[2], regs[3]);
+ secs = ((unsigned long)regs[3] << 24) | (regs[2] << 16) | (regs[1] << 8) | regs[0];
+ rtc_to_tm(secs, tm);
+
+ dev_dbg(dev, "read %lld %4d-%02d-%02d (wday=%d) %2d:%02d:%02d\n", secs,
+ tm->tm_year, tm->tm_mon, tm->tm_mday,
+ tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+ return 0;
+}
+
+static int ds1672_set_time(struct udevice *dev, const struct rtc_time *tm)
+{
+ time64_t secs = rtc_mktime(tm);
+ u8 regs[5];
+
+ dev_dbg(dev, "set %4d-%02d-%02d (wday=%d) %2d:%02d:%02d %lld\n",
+ tm->tm_year, tm->tm_mon, tm->tm_mday,
+ tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec,
+ secs);
+
+ if (tm->tm_year < 2000) {
+ dev_err(dev, "year %d (before 2000) not supported\n",
+ tm->tm_year);
+ return -EINVAL;
+ }
+
+ regs[0] = secs & 0x000000ff;
+ regs[1] = (secs & 0x0000ff00) >> 8;
+ regs[2] = (secs & 0x00ff0000) >> 16;
+ regs[3] = (secs & 0xff000000) >> 24;
+ regs[4] = 0; /* set control reg to enable counting */
+
+ return dm_i2c_write(dev, DS1672_REG_CNT_BASE, regs, 5);
+}
+
+static int ds1672_reset(struct udevice *dev)
+{
+ u8 regs[5] = { 0 };
+
+ return dm_i2c_write(dev, DS1672_REG_CNT_BASE, regs, 5);
+}
+
+static int ds1672_read8(struct udevice *dev, unsigned int reg)
+{
+ return dm_i2c_reg_read(dev, reg);
+}
+
+static int ds1672_write8(struct udevice *dev, unsigned int reg, int val)
+{
+ return dm_i2c_reg_write(dev, reg, val);
+}
+
+static const struct rtc_ops ds1672_rtc_ops = {
+ .get = ds1672_read_time,
+ .set = ds1672_set_time,
+ .reset = ds1672_reset,
+ .read8 = ds1672_read8,
+ .write8 = ds1672_write8,
+};
+
+static int ds1672_probe(struct udevice *dev)
+{
+ i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS | DM_I2C_CHIP_WR_ADDRESS);
+
+ return 0;
+}
+
+static const struct udevice_id ds1672_of_id[] = {
+ { .compatible = "dallas,ds1672" },
+ { }
+};
+
+U_BOOT_DRIVER(rtc_max313xx) = {
+ .name = "rtc-ds1672",
+ .id = UCLASS_RTC,
+ .probe = ds1672_probe,
+ .of_match = ds1672_of_id,
+ .ops = &ds1672_rtc_ops,
+};
diff --git a/drivers/spi/cadence_ospi_versal.c b/drivers/spi/cadence_ospi_versal.c
index fbeb0c6a85c..6dc6fbe5a5b 100644
--- a/drivers/spi/cadence_ospi_versal.c
+++ b/drivers/spi/cadence_ospi_versal.c
@@ -20,7 +20,7 @@
int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv,
const struct spi_mem_op *op)
{
- u32 reg, ret, rx_rem, n_rx, bytes_to_dma, data;
+ u32 reg, ret, rx_rem, n_rx, bytes_to_dma, data, status;
u8 opcode, addr_bytes, *rxbuf, dummy_cycles;
n_rx = op->data.nbytes;
@@ -87,6 +87,16 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv,
CQSPI_REG_SIZE_ADDRESS_MASK;
opcode = CMD_4BYTE_FAST_READ;
+
+ /* Set up command opcode extension. */
+ status = readl(priv->regbase + CQSPI_REG_CONFIG);
+ if (status & CQSPI_REG_CONFIG_DTR_PROTO) {
+ ret = cadence_qspi_setup_opcode_ext(priv, op,
+ CQSPI_REG_OP_EXT_STIG_LSB);
+ if (ret)
+ return ret;
+ }
+
dummy_cycles = 8;
writel((dummy_cycles << CQSPI_REG_RD_INSTR_DUMMY_LSB) | opcode,
priv->regbase + CQSPI_REG_RD_INSTR);
diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h
index 80510f2542b..879e7f8dbfb 100644
--- a/drivers/spi/cadence_qspi.h
+++ b/drivers/spi/cadence_qspi.h
@@ -320,5 +320,7 @@ int cadence_qspi_flash_reset(struct udevice *dev);
ofnode cadence_qspi_get_subnode(struct udevice *dev);
void cadence_qspi_apb_enable_linear_mode(bool enable);
int cadence_device_reset(struct udevice *dev);
-
+int cadence_qspi_setup_opcode_ext(struct cadence_spi_priv *priv,
+ const struct spi_mem_op *op,
+ unsigned int shift);
#endif /* __CADENCE_QSPI_H__ */
diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c
index b579699d2eb..6f89d3add5d 100644
--- a/drivers/spi/cadence_qspi_apb.c
+++ b/drivers/spi/cadence_qspi_apb.c
@@ -303,6 +303,10 @@ void cadence_qspi_apb_delay(void *reg_base,
tshsl_ns -= sclk_ns + ref_clk_ns;
if (tchsh_ns >= sclk_ns + 3 * ref_clk_ns)
tchsh_ns -= sclk_ns + 3 * ref_clk_ns;
+
+ if (tshsl_ns < sclk_ns)
+ tshsl_ns = sclk_ns;
+
tshsl = DIV_ROUND_UP(tshsl_ns, ref_clk_ns);
tchsh = DIV_ROUND_UP(tchsh_ns, ref_clk_ns);
tslch = DIV_ROUND_UP(tslch_ns, ref_clk_ns);
@@ -380,9 +384,9 @@ int cadence_qspi_apb_exec_flash_cmd(void *reg_base, unsigned int reg)
return 0;
}
-static int cadence_qspi_setup_opcode_ext(struct cadence_spi_priv *priv,
- const struct spi_mem_op *op,
- unsigned int shift)
+int cadence_qspi_setup_opcode_ext(struct cadence_spi_priv *priv,
+ const struct spi_mem_op *op,
+ unsigned int shift)
{
unsigned int reg;
u8 ext;
@@ -555,6 +559,9 @@ int cadence_qspi_apb_command_write(struct cadence_spi_priv *priv,
u8 opcode;
if (priv->dtr)
+ txlen += txlen & 1;
+
+ if (priv->dtr)
opcode = op->cmd.opcode >> 8;
else
opcode = op->cmd.opcode;
diff --git a/drivers/spi/fsl_dspi.c b/drivers/spi/fsl_dspi.c
index f2393c041f4..545561ad116 100644
--- a/drivers/spi/fsl_dspi.c
+++ b/drivers/spi/fsl_dspi.c
@@ -123,8 +123,10 @@ static uint dspi_read32(uint flags, uint *addr)
static void dspi_write32(uint flags, uint *addr, uint val)
{
- flags & DSPI_FLAG_REGMAP_ENDIAN_BIG ?
- out_be32(addr, val) : out_le32(addr, val);
+ if (flags & DSPI_FLAG_REGMAP_ENDIAN_BIG)
+ out_be32(addr, val);
+ else
+ out_le32(addr, val);
}
static void dspi_halt(struct fsl_dspi_priv *priv, u8 halt)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index a0f2948335f..45eb9b4d3f9 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -29,6 +29,7 @@ config WATCHDOG_TIMEOUT_MSECS
int "Watchdog timeout in msec"
default 128000 if ARCH_MX31 || ARCH_MX5 || ARCH_MX6
default 128000 if ARCH_MX7 || ARCH_VF610
+ default 30000 if ARCH_SNAPDRAGON
default 30000 if ARCH_SOCFPGA
default 16000 if ARCH_SUNXI
default 5376 if ULP_WATCHDOG
@@ -335,6 +336,14 @@ config WDT_K3_RTI_FW_FILE
endif
+config WDT_QCOM
+ bool "Qualcomm watchdog timer support"
+ depends on WDT && ARCH_SNAPDRAGON
+ imply WATCHDOG
+ help
+ Select this to enable Qualcomm watchdog timer, which can be found on
+ some Qualcomm chips.
+
config WDT_RENESAS
bool "Renesas watchdog timer support"
depends on WDT && R8A779F0
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index c4467d6e126..d52d17e1c90 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -55,3 +55,4 @@ obj-$(CONFIG_WDT_SUNXI) += sunxi_wdt.o
obj-$(CONFIG_WDT_TANGIER) += tangier_wdt.o
obj-$(CONFIG_WDT_XILINX) += xilinx_wwdt.o
obj-$(CONFIG_WDT_ADI) += adi_wdt.o
+obj-$(CONFIG_WDT_QCOM) += qcom-wdt.o
diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
new file mode 100644
index 00000000000..adbb5aacdc3
--- /dev/null
+++ b/drivers/watchdog/qcom-wdt.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) Linaro Ltd. 2024
+ *
+ * Authors:
+ * Casey Connolly <casey.connolly@linaro.org>
+ * Paul Sajna <hello@paulsajna.com>
+ *
+ * Derived from linux/drivers/watchdog/qcom-wdt.c
+ */
+
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <wdt.h>
+#include <clk.h>
+
+#include <asm/io.h>
+
+enum wdt_reg {
+ WDT_RST,
+ WDT_EN,
+ WDT_STS,
+ WDT_BARK_TIME,
+ WDT_BITE_TIME,
+};
+
+struct qcom_wdt_match_data {
+ const u32 *offset;
+};
+
+struct qcom_wdt {
+ void __iomem *base;
+ ulong clk_rate;
+ const u32 *layout;
+};
+
+static const u32 reg_offset_data_kpss[] = {
+ [WDT_RST] = 0x4,
+ [WDT_EN] = 0x8,
+ [WDT_STS] = 0xC,
+ [WDT_BARK_TIME] = 0x10,
+ [WDT_BITE_TIME] = 0x14,
+};
+
+static const struct qcom_wdt_match_data match_data_kpss = {
+ .offset = reg_offset_data_kpss,
+};
+
+static void __iomem *wdt_addr(struct qcom_wdt *wdt, enum wdt_reg reg)
+{
+ return wdt->base + wdt->layout[reg];
+}
+
+int qcom_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
+{
+ struct qcom_wdt *wdt = dev_get_priv(dev);
+ ulong bark_timeout_s = ((timeout_ms - 1) * wdt->clk_rate) / 1000;
+ ulong bite_timeout_s = (timeout_ms * wdt->clk_rate) / 1000;
+
+ writel(0, wdt_addr(wdt, WDT_EN));
+ writel(BIT(0), wdt_addr(wdt, WDT_RST));
+ writel(bark_timeout_s, wdt_addr(wdt, WDT_BARK_TIME));
+ writel(bite_timeout_s, wdt_addr(wdt, WDT_BITE_TIME));
+ writel(BIT(0), wdt_addr(wdt, WDT_EN));
+ if (readl(wdt_addr(wdt, WDT_EN)) != 1) {
+ dev_err(dev, "Failed to enable Qualcomm watchdog!\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+int qcom_wdt_stop(struct udevice *dev)
+{
+ struct qcom_wdt *wdt = dev_get_priv(dev);
+
+ writel(0, wdt_addr(wdt, WDT_EN));
+ if (readl(wdt_addr(wdt, WDT_EN))) {
+ dev_err(dev, "Failed to disable Qualcomm watchdog!\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int qcom_wdt_reset(struct udevice *dev)
+{
+ struct qcom_wdt *wdt = dev_get_priv(dev);
+
+ writel(1, wdt_addr(wdt, WDT_RST));
+ return 0;
+}
+
+static int qcom_wdt_probe(struct udevice *dev)
+{
+ struct clk clk;
+ long rate;
+ int ret;
+
+ struct qcom_wdt *wdt = dev_get_priv(dev);
+ struct qcom_wdt_match_data *data = (void *)dev_get_driver_data(dev);
+
+ wdt->base = dev_read_addr_ptr(dev);
+ wdt->layout = data->offset;
+
+ ret = clk_get_by_index(dev, 0, &clk);
+ if (ret)
+ return ret;
+
+ rate = clk_get_rate(&clk);
+ if (rate <= 0)
+ return rate < 0 ? (int)rate : -EINVAL;
+
+ wdt->clk_rate = (ulong)rate;
+
+ return 0;
+}
+
+static const struct wdt_ops qcom_wdt_ops = {
+ .start = qcom_wdt_start,
+ .stop = qcom_wdt_stop,
+ .reset = qcom_wdt_reset,
+};
+
+static const struct udevice_id qcom_wdt_ids[] = {
+ { .compatible = "qcom,kpss-wdt", .data = (ulong)&match_data_kpss },
+ {}
+};
+
+U_BOOT_DRIVER(qcom_wdt) = {
+ .name = "qcom_wdt",
+ .id = UCLASS_WDT,
+ .of_match = qcom_wdt_ids,
+ .ops = &qcom_wdt_ops,
+ .probe = qcom_wdt_probe,
+ .priv_auto = sizeof(struct qcom_wdt),
+};
diff --git a/dts/upstream/src/arm64/allwinner/sun50i-a100.dtsi b/dts/upstream/src/arm64/allwinner/sun50i-a100.dtsi
index f9f6fea03b7..bd366389b23 100644
--- a/dts/upstream/src/arm64/allwinner/sun50i-a100.dtsi
+++ b/dts/upstream/src/arm64/allwinner/sun50i-a100.dtsi
@@ -252,6 +252,7 @@
interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&mmc0_pins>;
+ max-frequency = <150000000>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
@@ -267,6 +268,7 @@
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&mmc1_pins>;
+ max-frequency = <150000000>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
@@ -282,6 +284,7 @@
interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&mmc2_pins>;
+ max-frequency = <150000000>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
diff --git a/dts/upstream/src/arm64/allwinner/sun50i-a133-liontron-h-a133l.dts b/dts/upstream/src/arm64/allwinner/sun50i-a133-liontron-h-a133l.dts
new file mode 100644
index 00000000000..fe77178d3e3
--- /dev/null
+++ b/dts/upstream/src/arm64/allwinner/sun50i-a133-liontron-h-a133l.dts
@@ -0,0 +1,211 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2025 Arm Ltd.
+ */
+
+/dts-v1/;
+
+#include "sun50i-a100.dtsi"
+#include "sun50i-a100-cpu-opp.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+
+/{
+ model = "Liontron H-A133L";
+ compatible = "liontron,h-a133l", "allwinner,sun50i-a100";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&pio 7 16 GPIO_ACTIVE_LOW>; /* PH16 */
+ };
+ };
+
+ reg_vcc5v: vcc5v {
+ /* board wide 5V supply from a 12V->5V regulator */
+ compatible = "regulator-fixed";
+ regulator-name = "vcc-5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ reg_usb1_vbus: regulator-usb1-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb1-vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&reg_vcc5v>;
+ enable-active-high;
+ gpio = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&mmc0 {
+ vmmc-supply = <&reg_dcdc1>;
+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+ bus-width = <4>;
+ status = "okay";
+};
+
+&mmc2 {
+ vmmc-supply = <&reg_dcdc1>;
+ vqmmc-supply = <&reg_eldo1>;
+ cap-mmc-hw-reset;
+ non-removable;
+ bus-width = <8>;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&pio {
+ vcc-pb-supply = <&reg_dcdc1>;
+ vcc-pc-supply = <&reg_eldo1>;
+ vcc-pf-supply = <&reg_dcdc1>;
+ vcc-ph-supply = <&reg_dcdc1>;
+};
+
+&r_i2c0 {
+ status = "okay";
+
+ axp803: pmic@34 {
+ compatible = "x-powers,axp803";
+ reg = <0x34>;
+ interrupt-parent = <&r_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+#include "axp803.dtsi"
+
+&ac_power_supply {
+ status = "okay";
+};
+
+&reg_aldo1 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-codec-avcc";
+};
+
+&reg_aldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-dram-1";
+};
+
+&reg_aldo3 {
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-usb-pl";
+};
+
+&reg_dcdc1 {
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-io-usb-pd-emmc";
+};
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <810000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-name = "vdd-cpux";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ regulator-name = "vdd-usb-cpus";
+};
+
+&reg_dcdc4 {
+ regulator-always-on;
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <950000>;
+ regulator-name = "vdd-sys";
+};
+
+&reg_dcdc5 {
+ regulator-always-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-name = "vcc-dram";
+};
+
+/* DCDC6 unused */
+/* DLDO3 unused */
+/* DLDO4 unused */
+
+&reg_eldo1 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-pc-emmc";
+};
+
+/* ELDO2 unused */
+/* ELDO3 unused */
+
+&reg_fldo1 {
+ regulator-always-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ regulator-name = "vdd-cpus-usb";
+};
+
+/* reg_drivevbus unused */
+/* dc1sw unused */
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pb_pins>;
+ status = "okay";
+};
+
+&usb_otg {
+ dr_mode = "host"; /* USB A type receptacle, always powered */
+ status = "okay";
+};
+
+&usbphy {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+};
diff --git a/dts/upstream/src/arm64/allwinner/sun50i-h618-yuzukihd-chameleon.dts b/dts/upstream/src/arm64/allwinner/sun50i-h618-yuzukihd-chameleon.dts
new file mode 100644
index 00000000000..eae56908b9b
--- /dev/null
+++ b/dts/upstream/src/arm64/allwinner/sun50i-h618-yuzukihd-chameleon.dts
@@ -0,0 +1,222 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2024 Arm Ltd.
+ */
+
+/dts-v1/;
+
+#include "sun50i-h616.dtsi"
+#include "sun50i-h616-cpu-opp.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ model = "Yuzuki Chameleon";
+ compatible = "yuzukihd,chameleon", "allwinner,sun50i-h618";
+
+ aliases {
+ ethernet1 = &sdio_wifi;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ reg_vcc5v: vcc5v {
+ /* board wide 5V supply directly from the USB-C socket */
+ compatible = "regulator-fixed";
+ regulator-name = "vcc-5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ wifi_pwrseq: pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rtc CLK_OSC32K_FANOUT>;
+ clock-names = "ext_clock";
+ pinctrl-0 = <&x32clk_fanout_pin>;
+ pinctrl-names = "default";
+ reset-gpios = <&pio 6 11 GPIO_ACTIVE_LOW>; /* PG11 */
+ };
+};
+
+&codec {
+ allwinner,audio-routing = "Line Out", "LINEOUT";
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&ehci2 {
+ status = "okay";
+};
+
+&ehci3 {
+ status = "okay";
+};
+
+&mmc0 {
+ bus-width = <4>;
+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+ disable-wp;
+ vmmc-supply = <&reg_dldo1>;
+ status = "okay";
+};
+
+&mmc1 {
+ bus-width = <4>;
+ mmc-pwrseq = <&wifi_pwrseq>;
+ non-removable;
+ vmmc-supply = <&reg_dldo1>;
+ vqmmc-supply = <&reg_dldo1>;
+ status = "okay";
+
+ sdio_wifi: wifi@1 {
+ reg = <1>;
+ interrupt-parent = <&pio>;
+ interrupts = <6 12 IRQ_TYPE_LEVEL_LOW>; /* PG12 */
+ interrupt-names = "host-wake";
+ };
+};
+
+&mmc2 {
+ bus-width = <8>;
+ cap-mmc-hw-reset;
+ mmc-ddr-3_3v;
+ non-removable;
+ vmmc-supply = <&reg_dldo1>;
+ vqmmc-supply = <&reg_dldo1>;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&ohci2 {
+ status = "okay";
+};
+
+&ohci3 {
+ status = "okay";
+};
+
+&pio {
+ vcc-pc-supply = <&reg_dldo1>;
+ vcc-pf-supply = <&reg_dldo1>; /* via VCC_IO */
+ vcc-pg-supply = <&reg_dldo1>;
+ vcc-ph-supply = <&reg_dldo1>; /* via VCC_IO */
+ vcc-pi-supply = <&reg_dldo1>;
+};
+
+&r_i2c {
+ status = "okay";
+
+ axp313: pmic@36 {
+ compatible = "x-powers,axp313a";
+ reg = <0x36>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ interrupt-parent = <&pio>;
+ interrupts = <2 2 IRQ_TYPE_LEVEL_LOW>; /* PC2 */
+
+ vin1-supply = <&reg_vcc5v>;
+ vin2-supply = <&reg_vcc5v>;
+ vin3-supply = <&reg_vcc5v>;
+
+ regulators {
+ /* Supplies VCC-PLL, so needs to be always on. */
+ reg_aldo1: aldo1 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc1v8";
+ };
+
+ /* Supplies VCC-IO, so needs to be always on. */
+ reg_dldo1: dldo1 {
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc3v3";
+ };
+
+ reg_dcdc1: dcdc1 {
+ regulator-always-on;
+ regulator-min-microvolt = <810000>;
+ regulator-max-microvolt = <990000>;
+ regulator-name = "vdd-gpu-sys";
+ };
+
+ reg_dcdc2: dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <810000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-name = "vdd-cpu";
+ };
+
+ reg_dcdc3: dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-name = "vdd-dram";
+ };
+ };
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_ph_pins>;
+ status = "okay";
+};
+
+/* Connected to the Bluetooth UART pins of the XR829 Wifi/BT chip. */
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
+ uart-has-rtscts;
+ status = "okay";
+};
+
+&usbotg {
+ /*
+ * PHY0 pins are connected to a USB-C socket, but a role switch
+ * is not implemented: both CC pins are pulled to GND.
+ * The VBUS pins power the device, so a fixed peripheral mode
+ * is the best choice.
+ * The board can be powered via GPIOs, in this case port0 *can*
+ * act as a host (with a cable/adapter ignoring CC), as VBUS is
+ * then provided by the GPIOs. Any user of this setup would
+ * need to adjust the DT accordingly: dr_mode set to "host",
+ * enabling OHCI0 and EHCI0.
+ */
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&usbphy {
+ usb0_id_det-gpios = <&pio 6 18 GPIO_ACTIVE_HIGH>; /* PG18 */
+ usb0_vbus-supply = <&reg_vcc5v>;
+ usb1_vbus-supply = <&reg_vcc5v>;
+ usb2_vbus-supply = <&reg_vcc5v>;
+ usb3_vbus-supply = <&reg_vcc5v>;
+ status = "okay";
+};
diff --git a/env/Kconfig b/env/Kconfig
index 58a0666cd49..c30785de48b 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -231,14 +231,6 @@ config ENV_IS_IN_MMC
These two #defines specify the offset and size of the environment
area within the specified MMC device.
- If offset is positive (the usual case), it is treated as relative to
- the start of the MMC partition. If offset is negative, it is treated
- as relative to the end of the MMC partition. This can be useful if
- your board may be fitted with different MMC devices, which have
- different sizes for the MMC partitions, and you always want the
- environment placed at the very end of the partition, to leave the
- maximum possible space before it, to store other data.
-
These two values are in units of bytes, but must be aligned to an
MMC sector boundary.
@@ -249,9 +241,6 @@ config ENV_IS_IN_MMC
valid backup copy in case the other copy is corrupted, e.g. due
to a power failure during a "saveenv" operation.
- This value may also be positive or negative; this is handled in the
- same way as CONFIG_ENV_OFFSET.
-
In case CONFIG_ENV_MMC_EMMC_HW_PARTITION is 1 (i.e. environment in eMMC boot
partition) then setting CONFIG_ENV_OFFSET_REDUND to the same value
as CONFIG_ENV_OFFSET makes use of the second eMMC boot partition for
@@ -618,9 +607,18 @@ config ENV_OFFSET
Offset from the start of the device (or partition).
This offset may be interpreted differently depending on the chosen
- ENV_IS_IN_* options. For example, for ENV_IS_IN_MMC=y, this offset may
- be negative to indicate an offset backwards from the end of the
- partition. See the relevant help messages for more details.
+ ENV_IS_IN_* options. See the relevant help messages for more details.
+
+config ENV_OFFSET_RELATIVE_END
+ bool "Offset is relative to the end of the partition"
+ depends on ENV_IS_IN_MMC
+ help
+ Treat the environment offset as relative to the end of the MMC
+ hardware partition. This can be useful if your board may be fitted
+ with different MMC devices, which have different sizes for the MMC
+ hardware partitions, and you always want the environment placed at the
+ very end of the partition, to leave the maximum possible space before
+ it, to store other data.
config ENV_OFFSET_REDUND
hex "Redundant environment offset"
@@ -633,9 +631,19 @@ config ENV_OFFSET_REDUND
environment location.
This offset may be interpreted differently depending on the chosen
- ENV_IS_IN_* options. For example, for ENV_IS_IN_MMC=y, this offset may
- be negative to indicate an offset backwards from the end of the
- partition. See the relevant help messages for more details.
+ ENV_IS_IN_* options. See the relevant help messages for more details.
+
+config ENV_OFFSET_REDUND_RELATIVE_END
+ bool "Offset is relative to the end of the partition"
+ depends on SYS_REDUNDAND_ENVIRONMENT
+ depends on ENV_IS_IN_MMC
+ help
+ Treat the redundant environment offset as relative to the end of the
+ MMC hardware partition. This can be useful if your board may be
+ fitted with different MMC devices, which have different sizes for the
+ MMC hardware partitions, and you always want the environment placed at
+ the very end of the partition, to leave the maximum possible space
+ before it, to store other data.
config ENV_SIZE
hex "Environment Size"
diff --git a/env/common.c b/env/common.c
index 1e23c5de436..05e78d63874 100644
--- a/env/common.c
+++ b/env/common.c
@@ -82,6 +82,10 @@ int env_do_env_set(int flag, int argc, char *const argv[], int env_flag)
}
}
debug("Final value for argc=%d\n", argc);
+ /* Exit early if we don't have an env to apply */
+ if (argc < 2)
+ return 0;
+
name = argv[1];
if (strchr(name, '=')) {
diff --git a/env/mmc.c b/env/mmc.c
index 11375bd4464..46ffa6386d6 100644
--- a/env/mmc.c
+++ b/env/mmc.c
@@ -29,11 +29,19 @@
#else
/* Default ENV offset when not defined in Device Tree */
+#if !defined(CONFIG_ENV_OFFSET_RELATIVE_END)
#define ENV_MMC_OFFSET CONFIG_ENV_OFFSET
+#else
+#define ENV_MMC_OFFSET (-(CONFIG_ENV_OFFSET))
+#endif
#if defined(CONFIG_ENV_OFFSET_REDUND)
+#if !defined(CONFIG_ENV_OFFSET_REDUND_RELATIVE_END)
#define ENV_MMC_OFFSET_REDUND CONFIG_ENV_OFFSET_REDUND
#else
+#define ENV_MMC_OFFSET_REDUND (-(CONFIG_ENV_OFFSET_REDUND))
+#endif
+#else
#define ENV_MMC_OFFSET_REDUND ENV_MMC_INVALID_OFFSET
#endif
#endif
diff --git a/fs/ext4/ext4_journal.c b/fs/ext4/ext4_journal.c
index 02c4ac2cb93..868a2c1804a 100644
--- a/fs/ext4/ext4_journal.c
+++ b/fs/ext4/ext4_journal.c
@@ -131,6 +131,13 @@ int ext4fs_log_gdt(char *gd_table)
struct ext_filesystem *fs = get_fs();
short i;
long int var = fs->gdtable_blkno;
+
+ /* Make sure there is enough journal entries */
+ if (fs->no_blk_pergdt > MAX_JOURNAL_ENTRIES) {
+ log_err("*** Not enough journal entries allocated\n");
+ return -ENOMEM;
+ }
+
for (i = 0; i < fs->no_blk_pergdt; i++) {
journal_ptr[gindex]->buf = zalloc(fs->blksz);
if (!journal_ptr[gindex]->buf)
diff --git a/fs/fs.c b/fs/fs.c
index 1f36872fb9a..2650328b358 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -580,6 +580,7 @@ static int fs_read_lmb_check(const char *filename, ulong addr, loff_t offset,
int ret;
loff_t size;
loff_t read_len;
+ phys_addr_t read_addr;
/* get the actual size of the file */
ret = info->size(filename, &size);
@@ -597,7 +598,9 @@ static int fs_read_lmb_check(const char *filename, ulong addr, loff_t offset,
lmb_dump_all();
- if (!lmb_alloc_addr(addr, read_len, LMB_NONE))
+ read_addr = (phys_addr_t)addr;
+ if (!lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &read_addr, read_len,
+ LMB_NONE))
return 0;
log_err("** Reading file would overwrite reserved memory **\n");
diff --git a/include/configs/astro_mcf5373l.h b/include/configs/astro_mcf5373l.h
deleted file mode 100644
index 65224324fbc..00000000000
--- a/include/configs/astro_mcf5373l.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Configuration settings for the Sentec Cobra Board.
- *
- * (C) Copyright 2003 Josef Baumgartner <josef.baumgartner@telex.de>
- */
-
-/*
- * configuration for ASTRO "Urmel" board.
- * Originating from Cobra5272 configuration, messed up by
- * Wolfgang Wegner <w.wegner@astro-kom.de>
- * Please do not bother the original author with bug reports
- * concerning this file.
- */
-
-#ifndef _CONFIG_ASTRO_MCF5373L_H
-#define _CONFIG_ASTRO_MCF5373L_H
-
-#include <linux/stringify.h>
-
-/*
- * set the card type to actually compile for; either of
- * the possibilities listed below has to be used!
- */
-#define ASTRO_V532 1
-
-#if ASTRO_V532
-#define ASTRO_ID 0xF8
-#elif ASTRO_V512
-#define ASTRO_ID 0xFA
-#elif ASTRO_TWIN7S2
-#define ASTRO_ID 0xF9
-#elif ASTRO_V912
-#define ASTRO_ID 0xFC
-#elif ASTRO_COFDMDUOS2
-#define ASTRO_ID 0xFB
-#else
-#error No card type defined!
-#endif
-
-/* I2C */
-
-/*
- * Defines processor clock - important for correct timings concerning serial
- * interface etc.
- */
-
-#define CFG_SYS_CLK 80000000
-#define CFG_SYS_CPU_CLK (CFG_SYS_CLK * 3)
-#define CFG_SYS_SDRAM_SIZE 32 /* SDRAM size in MB */
-
-/*
- * Define baudrate for UART1 (console output, tftp, ...)
- * default value of CONFIG_BAUDRATE for Sentec board: 19200 baud
- * CFG_SYS_BAUDRATE_TABLE defines values that can be selected
- * in u-boot command interface
- */
-
-#define CFG_SYS_UART_PORT (2)
-#define CFG_SYS_UART2_ALT3_GPIO
-
-/* here we put our FPGA configuration... */
-
-/* Define user parameters that have to be customized most likely */
-
-/* AUTOBOOT settings - booting images automatically by u-boot after power on */
-
-/*
- * The following settings will be contained in the environment block ; if you
- * want to use a neutral environment all those settings can be manually set in
- * u-boot: 'set' command
- */
-
-#define CFG_EXTRA_ENV_SETTINGS \
- "loaderversion=11\0" \
- "card_id="__stringify(ASTRO_ID)"\0" \
- "alterafile=0\0" \
- "xilinxfile=0\0" \
- "xilinxload=imxtract 0x540000 $xilinxfile 0x41000000&&"\
- "fpga load 0 0x41000000 $filesize\0" \
- "alteraload=imxtract 0x6c0000 $alterafile 0x41000000&&"\
- "fpga load 1 0x41000000 $filesize\0" \
- "env_default=1\0" \
- "env_check=if test $env_default -eq 1;"\
- " then setenv env_default 0;saveenv;fi\0"
-
-/*
- * "update" is a non-standard command that has to be supplied
- * by external update.c; This is not included in mainline because
- * it needs non-blocking CFI routines.
- */
-
-#define CFG_SYS_FPGA_WAIT 1000
-
-/* End of user parameters to be customized */
-
-/* Defines memory range for test */
-
-/*
- * Low Level Configuration Settings
- * (address mappings, register initial values, etc.)
- * You should know what you are doing if you make changes here.
- */
-
-/* Base register address */
-
-#define CFG_SYS_MBAR 0xFC000000 /* Register Base Addrs */
-
-/* System Conf. Reg. & System Protection Reg. */
-
-#define CFG_SYS_SCR 0x0003;
-#define CFG_SYS_SPR 0xffff;
-
-/*
- * Definitions for initial stack pointer and data area (in internal SRAM)
- */
-#define CFG_SYS_INIT_RAM_ADDR 0x80000000
-#define CFG_SYS_INIT_RAM_SIZE 0x8000
-#define CFG_SYS_INIT_RAM_CTRL 0x221
-
-/*
- * Start addresses for the final memory configuration
- * (Set up by the startup code)
- * for MCF5373, the allowable range is 0x40000000 to 0x7FF00000
- */
-#define CFG_SYS_SDRAM_BASE 0x40000000
-
-/*
- * Chipselect bank definitions
- *
- * CS0 - Flash 32MB (first 16MB)
- * CS1 - Flash 32MB (second half)
- * CS2 - FPGA
- * CS3 - FPGA
- * CS4 - unused
- * CS5 - unused
- */
-#define CFG_SYS_CS0_BASE 0
-#define CFG_SYS_CS0_MASK 0x00ff0001
-#define CFG_SYS_CS0_CTRL 0x00001fc0
-
-#define CFG_SYS_CS1_BASE 0x01000000
-#define CFG_SYS_CS1_MASK 0x00ff0001
-#define CFG_SYS_CS1_CTRL 0x00001fc0
-
-#define CFG_SYS_CS2_BASE 0x20000000
-#define CFG_SYS_CS2_MASK 0x00ff0001
-#define CFG_SYS_CS2_CTRL 0x0000fec0
-
-#define CFG_SYS_CS3_BASE 0x21000000
-#define CFG_SYS_CS3_MASK 0x00ff0001
-#define CFG_SYS_CS3_CTRL 0x0000fec0
-
-#define CFG_SYS_FLASH_BASE 0x00000000
-
-/* Reserve 256 kB for Monitor */
-
-/*
- * For booting Linux, the board info and command line data
- * have to be in the first 8 MB of memory, since this is
- * the maximum mapped by the Linux kernel during initialization ??
- */
-#define CFG_SYS_BOOTMAPSZ (CFG_SYS_SDRAM_BASE + \
- (CFG_SYS_SDRAM_SIZE << 20))
-
-/* FLASH organization */
-
-#define CFG_SYS_FLASH_SIZE 0x2000000
-
-#define LDS_BOARD_TEXT \
- . = DEFINED(env_offset) ? env_offset : .; \
- env/embedded.o(.text*)
-
-/* Cache Configuration */
-
-#define ICACHE_STATUS (CFG_SYS_INIT_RAM_ADDR + \
- CFG_SYS_INIT_RAM_SIZE - 8)
-#define DCACHE_STATUS (CFG_SYS_INIT_RAM_ADDR + \
- CFG_SYS_INIT_RAM_SIZE - 4)
-#define CFG_SYS_ICACHE_INV (CF_CACR_CINVA)
-#define CFG_SYS_CACHE_ACR0 (CFG_SYS_SDRAM_BASE | \
- CF_ADDRMASK(CFG_SYS_SDRAM_SIZE) | \
- CF_ACR_EN | CF_ACR_SM_ALL)
-#define CFG_SYS_CACHE_ICACR (CF_CACR_EC | CF_CACR_CINVA | \
- CF_CACR_DCM_P)
-
-#endif /* _CONFIG_ASTRO_MCF5373L_H */
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index db2ac7f83bb..44d4960d487 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -14,6 +14,8 @@
#define CFG_SYS_SDRAM_BASE 0
#define CFG_SYS_SDRAM_SIZE \
(SB_TO_UL(CONFIG_SANDBOX_RAM_SIZE_MB) << 20)
+/** define SB_SDRAM_ALIGN - Alignment of emulated RAM */
+#define SB_SDRAM_ALIGN 0x400000
#define CFG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\
115200}
diff --git a/include/dt-bindings/clock/xlnx-zynqmp-clk.h b/include/dt-bindings/clock/xlnx-zynqmp-clk.h
deleted file mode 100644
index cdc4c0b9a37..00000000000
--- a/include/dt-bindings/clock/xlnx-zynqmp-clk.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Xilinx Zynq MPSoC Firmware layer
- *
- * Copyright (C) 2014-2018 Xilinx, Inc.
- *
- */
-
-#ifndef _DT_BINDINGS_CLK_ZYNQMP_H
-#define _DT_BINDINGS_CLK_ZYNQMP_H
-
-#define IOPLL 0
-#define RPLL 1
-#define APLL 2
-#define DPLL 3
-#define VPLL 4
-#define IOPLL_TO_FPD 5
-#define RPLL_TO_FPD 6
-#define APLL_TO_LPD 7
-#define DPLL_TO_LPD 8
-#define VPLL_TO_LPD 9
-#define ACPU 10
-#define ACPU_HALF 11
-#define DBF_FPD 12
-#define DBF_LPD 13
-#define DBG_TRACE 14
-#define DBG_TSTMP 15
-#define DP_VIDEO_REF 16
-#define DP_AUDIO_REF 17
-#define DP_STC_REF 18
-#define GDMA_REF 19
-#define DPDMA_REF 20
-#define DDR_REF 21
-#define SATA_REF 22
-#define PCIE_REF 23
-#define GPU_REF 24
-#define GPU_PP0_REF 25
-#define GPU_PP1_REF 26
-#define TOPSW_MAIN 27
-#define TOPSW_LSBUS 28
-#define GTGREF0_REF 29
-#define LPD_SWITCH 30
-#define LPD_LSBUS 31
-#define USB0_BUS_REF 32
-#define USB1_BUS_REF 33
-#define USB3_DUAL_REF 34
-#define USB0 35
-#define USB1 36
-#define CPU_R5 37
-#define CPU_R5_CORE 38
-#define CSU_SPB 39
-#define CSU_PLL 40
-#define PCAP 41
-#define IOU_SWITCH 42
-#define GEM_TSU_REF 43
-#define GEM_TSU 44
-#define GEM0_TX 45
-#define GEM1_TX 46
-#define GEM2_TX 47
-#define GEM3_TX 48
-#define GEM0_RX 49
-#define GEM1_RX 50
-#define GEM2_RX 51
-#define GEM3_RX 52
-#define QSPI_REF 53
-#define SDIO0_REF 54
-#define SDIO1_REF 55
-#define UART0_REF 56
-#define UART1_REF 57
-#define SPI0_REF 58
-#define SPI1_REF 59
-#define NAND_REF 60
-#define I2C0_REF 61
-#define I2C1_REF 62
-#define CAN0_REF 63
-#define CAN1_REF 64
-#define CAN0 65
-#define CAN1 66
-#define DLL_REF 67
-#define ADMA_REF 68
-#define TIMESTAMP_REF 69
-#define AMS_REF 70
-#define PL0_REF 71
-#define PL1_REF 72
-#define PL2_REF 73
-#define PL3_REF 74
-#define WDT 75
-#define IOPLL_INT 76
-#define IOPLL_PRE_SRC 77
-#define IOPLL_HALF 78
-#define IOPLL_INT_MUX 79
-#define IOPLL_POST_SRC 80
-#define RPLL_INT 81
-#define RPLL_PRE_SRC 82
-#define RPLL_HALF 83
-#define RPLL_INT_MUX 84
-#define RPLL_POST_SRC 85
-#define APLL_INT 86
-#define APLL_PRE_SRC 87
-#define APLL_HALF 88
-#define APLL_INT_MUX 89
-#define APLL_POST_SRC 90
-#define DPLL_INT 91
-#define DPLL_PRE_SRC 92
-#define DPLL_HALF 93
-#define DPLL_INT_MUX 94
-#define DPLL_POST_SRC 95
-#define VPLL_INT 96
-#define VPLL_PRE_SRC 97
-#define VPLL_HALF 98
-#define VPLL_INT_MUX 99
-#define VPLL_POST_SRC 100
-#define CAN0_MIO 101
-#define CAN1_MIO 102
-#define ACPU_FULL 103
-#define GEM0_REF 104
-#define GEM1_REF 105
-#define GEM2_REF 106
-#define GEM3_REF 107
-#define GEM0_REF_UNG 108
-#define GEM1_REF_UNG 109
-#define GEM2_REF_UNG 110
-#define GEM3_REF_UNG 111
-#define LPD_WDT 112
-
-#endif
diff --git a/include/efi_api.h b/include/efi_api.h
index eb61eafa028..77a05f752e5 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -238,6 +238,10 @@ enum efi_reset_type {
EFI_GUID(0xcce33c35, 0x74ac, 0x4087, 0xbc, 0xe7, \
0x8b, 0x29, 0xb0, 0x2e, 0xeb, 0x27)
+#define EFI_DEBUG_IMAGE_INFO_TABLE_GUID \
+ EFI_GUID(0x49152e77, 0x1ada, 0x4764, 0xb7, 0xa2, \
+ 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b)
+
struct efi_conformance_profiles_table {
u16 version;
u16 number_of_profiles;
@@ -259,6 +263,22 @@ struct efi_capsule_result_variable_header {
efi_status_t capsule_status;
} __packed;
+/**
+ * struct efi_system_table_pointer - struct to store the pointer of system
+ * table.
+ * @signature: The signature of this struct.
+ * @efi_system_table_base: The physical address of System Table.
+ * @crc32: CRC32 checksum
+ *
+ * This struct is design for hardware debugger to search through memory to
+ * get the address of EFI System Table.
+ */
+struct efi_system_table_pointer {
+ u64 signature;
+ efi_physical_addr_t efi_system_table_base;
+ u32 crc32;
+};
+
struct efi_memory_range {
efi_physical_addr_t address;
u64 length;
@@ -558,6 +578,57 @@ struct efi_loaded_image {
efi_status_t (EFIAPI *unload)(efi_handle_t image_handle);
};
+#define EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS 0x01
+#define EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED 0x02
+
+#define EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL 0x01
+
+/**
+ * struct efi_debug_image_info_normal - Store Debug Information for normal
+ * image.
+ * @image_info_type: the type of image info.
+ * @loaded_image_protocol_instance: the pointer to struct efi_loaded_image.
+ * @image_handle: the EFI handle of the image.
+ *
+ * This struct is created by efi_load_image() and store the information
+ * for debugging an normal image.
+ */
+struct efi_debug_image_info_normal {
+ u32 image_info_type;
+ struct efi_loaded_image *loaded_image_protocol_instance;
+ efi_handle_t image_handle;
+};
+
+/**
+ * union efi_debug_image_info - The union to store a pointer for EFI
+ * DEBUG IMAGE INFO.
+ * @image_info_type: the type of the image_info if it is not a normal image.
+ * @normal_image: The pointer to a normal image.
+ *
+ * This union is for a pointer that can point to the struct of normal_image.
+ * Or it points to an image_info_type.
+ */
+union efi_debug_image_info {
+ u32 *image_info_type;
+ struct efi_debug_image_info_normal *normal_image;
+};
+
+/**
+ * struct efi_debug_image_info_table_header - store the array of
+ * struct efi_debug_image_info.
+ * @update_status: Status to notify this struct is ready to use or not.
+ * @table_size: The number of elements of efi_debug_image_info_table.
+ * @efi_debug_image_info_table: The array of efi_debug_image_info.
+ *
+ * This struct stores the array of efi_debug_image_info. The
+ * number of elements is table_size.
+ */
+struct efi_debug_image_info_table_header {
+ volatile u32 update_status;
+ u32 table_size;
+ union efi_debug_image_info *efi_debug_image_info_table;
+};
+
#define EFI_DEVICE_PATH_PROTOCOL_GUID \
EFI_GUID(0x09576e91, 0x6d3f, 0x11d2, \
0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
diff --git a/include/efi_config.h b/include/efi_config.h
index d7c1601137e..23211e799fc 100644
--- a/include/efi_config.h
+++ b/include/efi_config.h
@@ -82,6 +82,7 @@ struct eficonfig_item {
* @current_volume: pointer to the efi_simple_file_system_protocol
* @dp_volume: pointer to device path of the selected device
* @current_path: pointer to the selected file path string
+ * @uri: URI for HTTP Boot
* @filepath_list: list_head structure for file path list
* @file_selectred: flag indicates file selecting status
*/
@@ -89,6 +90,7 @@ struct eficonfig_select_file_info {
struct efi_simple_file_system_protocol *current_volume;
struct efi_device_path *dp_volume;
u16 *current_path;
+ u16 *uri;
struct list_head filepath_list;
bool file_selected;
};
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 8fd09aad2d0..3e70ac07055 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -312,6 +312,8 @@ extern const struct efi_hii_config_routing_protocol efi_hii_config_routing;
extern const struct efi_hii_config_access_protocol efi_hii_config_access;
extern const struct efi_hii_database_protocol efi_hii_database;
extern const struct efi_hii_string_protocol efi_hii_string;
+/* structure for EFI_DEBUG_SUPPORT_PROTOCOL */
+extern struct efi_debug_image_info_table_header efi_m_debug_info_table_header;
uint16_t *efi_dp_str(struct efi_device_path *dp);
@@ -643,6 +645,13 @@ efi_status_t efi_tcg2_measure_dtb(void *dtb);
efi_status_t efi_root_node_register(void);
/* Called by bootefi to initialize runtime */
efi_status_t efi_initialize_system_table(void);
+/* Called by bootefi to initialize debug */
+efi_status_t efi_initialize_system_table_pointer(void);
+/* Called by efi_load_image for register debug info */
+efi_status_t efi_core_new_debug_image_info_entry(u32 image_info_type,
+ struct efi_loaded_image *loaded_image,
+ efi_handle_t image_handle);
+void efi_core_remove_debug_image_info_entry(efi_handle_t image_handle);
/* efi_runtime_detach() - detach unimplemented runtime functions */
void efi_runtime_detach(void);
/* efi_convert_pointer() - convert pointer to virtual address */
@@ -871,6 +880,16 @@ efi_status_t efi_next_variable_name(efi_uintn_t *size, u16 **buf,
#define efi_size_in_pages(size) (((size) + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT)
/* Allocate boot service data pool memory */
void *efi_alloc(size_t len);
+/**
+ * efi_realloc() - reallocate boot services data pool memory
+ *
+ * Reallocate memory from pool for a new size and copy the data from old one.
+ *
+ * @ptr: pointer to the buffer
+ * @size: number of bytes to allocate
+ * Return: EFI status to indicate success or not
+ */
+efi_status_t efi_realloc(void **ptr, size_t len);
/* Allocate pages on the specified alignment */
void *efi_alloc_aligned_pages(u64 len, int memory_type, size_t align);
/* More specific EFI memory allocator, called by EFI payloads */
diff --git a/include/fsl_ifc.h b/include/fsl_ifc.h
index 3ac22687930..1c363115beb 100644
--- a/include/fsl_ifc.h
+++ b/include/fsl_ifc.h
@@ -803,29 +803,29 @@ void init_final_memctl_regs(void);
((struct fsl_ifc_fcm *)CFG_SYS_IFC_ADDR)
#define get_ifc_cspr_ext(i) \
- (ifc_in32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr_ext))
+ ifc_in32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr_ext)
#define get_ifc_cspr(i) \
- (ifc_in32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr))
+ ifc_in32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr)
#define get_ifc_csor_ext(i) \
- (ifc_in32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor_ext))
+ ifc_in32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor_ext)
#define get_ifc_csor(i) \
- (ifc_in32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor))
+ ifc_in32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor)
#define get_ifc_amask(i) \
- (ifc_in32(&(IFC_FCM_BASE_ADDR)->amask_cs[i].amask))
+ ifc_in32(&(IFC_FCM_BASE_ADDR)->amask_cs[i].amask)
#define get_ifc_ftim(i, j) \
- (ifc_in32(&(IFC_FCM_BASE_ADDR)->ftim_cs[i].ftim[j]))
+ ifc_in32(&(IFC_FCM_BASE_ADDR)->ftim_cs[i].ftim[j])
#define set_ifc_cspr_ext(i, v) \
- (ifc_out32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr_ext, v))
+ ifc_out32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr_ext, v)
#define set_ifc_cspr(i, v) \
- (ifc_out32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr, v))
+ ifc_out32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr, v)
#define set_ifc_csor_ext(i, v) \
- (ifc_out32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor_ext, v))
+ ifc_out32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor_ext, v)
#define set_ifc_csor(i, v) \
- (ifc_out32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor, v))
+ ifc_out32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor, v)
#define set_ifc_amask(i, v) \
- (ifc_out32(&(IFC_FCM_BASE_ADDR)->amask_cs[i].amask, v))
+ ifc_out32(&(IFC_FCM_BASE_ADDR)->amask_cs[i].amask, v)
#define set_ifc_ftim(i, j, v) \
- (ifc_out32(&(IFC_FCM_BASE_ADDR)->ftim_cs[i].ftim[j], v))
+ ifc_out32(&(IFC_FCM_BASE_ADDR)->ftim_cs[i].ftim[j], v)
enum ifc_chip_sel {
IFC_CS0,
diff --git a/include/image.h b/include/image.h
index 37506c81cdb..b695cc39447 100644
--- a/include/image.h
+++ b/include/image.h
@@ -1689,7 +1689,7 @@ struct sig_header_s {
*/
int image_pre_load(ulong addr);
-#if defined(USE_HOSTCC)
+#if defined(USE_HOSTCC) && CONFIG_IS_ENABLED(LIBCRYPTO)
/**
* rsa_verify_openssl() - Verify a signature against some data with openssl API
*
diff --git a/include/lmb.h b/include/lmb.h
index 606a92cca48..5d5f037ccb9 100644
--- a/include/lmb.h
+++ b/include/lmb.h
@@ -32,6 +32,18 @@
#define LMB_NONOTIFY BIT(3)
/**
+ * enum lmb_mem_type - type of memory allocation request
+ * @LMB_MEM_ALLOC_ADDR: request for a particular region of memory
+ * @LMB_MEM_ALLOC_ANY: allocate any available memory region
+ * @LMB_MEM_ALLOC_MAX: allocate memory below a particular address
+ */
+enum lmb_mem_type {
+ LMB_MEM_ALLOC_ADDR = 1,
+ LMB_MEM_ALLOC_ANY,
+ LMB_MEM_ALLOC_MAX,
+};
+
+/**
* enum lmb_map_op - memory map operation
*/
enum lmb_map_op {
@@ -68,6 +80,37 @@ struct lmb {
};
/**
+ * lmb_alloc_mem() - Request LMB memory
+ * @type: Type of memory allocation request
+ * @align: Alignment of the memory region requested(0 for none)
+ * @addr: Base address of the allocated memory region
+ * @size: Size in bytes of the allocation request
+ * @flags: Memory region attributes to be set
+ *
+ * Allocate a region of memory where the allocation is based on the parameters
+ * that have been passed to the function.The first parameter specifies the
+ * type of allocation that is being requested. The second parameter, @align
+ * is used to specify if the allocation is to be made with a particular
+ * alignment. Use 0 for no alignment requirements.
+ *
+ * The allocated address is returned through the @addr parameter when @type
+ * is @LMB_MEM_ALLOC_ANY or @LMB_MEM_ALLOC_MAX. If @type is
+ * @LMB_MEM_ALLOC_ADDR the @addr parameter would contain the address being
+ * requested.
+ *
+ * The flags parameter is used to specify the memory attributes of the
+ * requested region.
+ *
+ * Return: 0 on success, -ve value on failure
+ *
+ * When the allocation is of type @LMB_MEM_ALLOC_ADDR, the return value can
+ * be -EINVAL if the requested memory region is not part of the LMB memory
+ * map, and -EEXIST if the requested region is already allocated.
+ */
+int lmb_alloc_mem(enum lmb_mem_type type, u64 align, phys_addr_t *addr,
+ phys_size_t size, u32 flags);
+
+/**
* lmb_init() - Initialise the LMB module.
*
* Return: 0 on success, negative error code on failure.
@@ -81,65 +124,11 @@ struct lmb {
*/
int lmb_init(void);
-/**
- * lmb_add_memory() - Add memory range for LMB allocations.
- *
- * Add the entire available memory range to the pool of memory that
- * can be used by the LMB module for allocations.
- */
-void lmb_add_memory(void);
-
long lmb_add(phys_addr_t base, phys_size_t size);
-/**
- * lmb_reserve() - Reserve one region with a specific flags bitfield
- * @base: Base address of the memory region
- * @size: Size of the memory region
- * @flags: Flags for the memory region
- *
- * Return:
- * * %0 - Added successfully, or it's already added (only if LMB_NONE)
- * * %-EEXIST - The region is already added, and flags != LMB_NONE
- * * %-1 - Failure
- */
-long lmb_reserve(phys_addr_t base, phys_size_t size, u32 flags);
-
-phys_addr_t lmb_alloc(phys_size_t size, ulong align);
phys_size_t lmb_get_free_size(phys_addr_t addr);
/**
- * lmb_alloc_base() - Allocate specified memory region with specified
- * attributes
- * @size: Size of the region requested
- * @align: Alignment of the memory region requested
- * @max_addr: Maximum address of the requested region
- * @flags: Memory region attributes to be set
- *
- * Allocate a region of memory with the attributes specified through the
- * parameter. The max_addr parameter is used to specify the maximum address
- * below which the requested region should be allocated.
- *
- * Return: Base address on success, 0 on error.
- */
-phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr,
- uint flags);
-
-/**
- * lmb_alloc_addr() - Allocate specified memory address with specified attributes
- *
- * @base: Base Address requested
- * @size: Size of the region requested
- * @flags: Memory region attributes to be set
- *
- * Allocate a region of memory with the attributes specified through the
- * parameter. The base parameter is used to specify the base address
- * of the requested region.
- *
- * Return: 0 on success -1 on error
- */
-int lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags);
-
-/**
* lmb_is_reserved_flags() - Test if address is in reserved region with flag
* bits set
* @addr: Address to be tested
@@ -153,16 +142,14 @@ int lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags);
int lmb_is_reserved_flags(phys_addr_t addr, int flags);
/**
- * lmb_free_flags() - Free up a region of memory
+ * lmb_free() - Free up a region of memory
* @base: Base Address of region to be freed
* @size: Size of the region to be freed
* @flags: Memory region attributes
*
* Return: 0 on success, negative error code on failure.
*/
-long lmb_free_flags(phys_addr_t base, phys_size_t size, uint flags);
-
-long lmb_free(phys_addr_t base, phys_size_t size);
+long lmb_free(phys_addr_t base, phys_size_t size, u32 flags);
void lmb_dump_all(void);
void lmb_dump_all_force(void);
@@ -175,7 +162,7 @@ void lmb_pop(struct lmb *store);
static inline int lmb_read_check(phys_addr_t addr, phys_size_t len)
{
- return lmb_alloc_addr(addr, len, LMB_NONE);
+ return lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &addr, len, LMB_NONE);
}
/**
diff --git a/include/log.h b/include/log.h
index dd44badc361..59c66eb7909 100644
--- a/include/log.h
+++ b/include/log.h
@@ -176,7 +176,7 @@ int _log_buffer(enum log_category_t cat, enum log_level_t level,
#define _LOG_MAX_LEVEL LOGL_INFO
#endif
-#define log_emer(_fmt...) log(LOG_CATEGORY, LOGL_EMERG, ##_fmt)
+#define log_emerg(_fmt...) log(LOG_CATEGORY, LOGL_EMERG, ##_fmt)
#define log_alert(_fmt...) log(LOG_CATEGORY, LOGL_ALERT, ##_fmt)
#define log_crit(_fmt...) log(LOG_CATEGORY, LOGL_CRIT, ##_fmt)
#define log_err(_fmt...) log(LOG_CATEGORY, LOGL_ERR, ##_fmt)
diff --git a/include/ndisc.h b/include/ndisc.h
index d0fe3acca4a..7d9e58aa1c2 100644
--- a/include/ndisc.h
+++ b/include/ndisc.h
@@ -10,8 +10,6 @@
#ifndef __NDISC_H__
#define __NDISC_H__
-#include <ndisc.h>
-
/* struct nd_msg - ICMPv6 Neighbour Discovery message format */
struct nd_msg {
struct icmp6hdr icmph;
diff --git a/include/net-common.h b/include/net-common.h
index c04f86bdfcc..1112af381a9 100644
--- a/include/net-common.h
+++ b/include/net-common.h
@@ -492,6 +492,17 @@ int dhcp_run(ulong addr, const char *fname, bool autoload);
int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
/**
+ * do_sntp - Run the sntp command
+ *
+ * @cmdtp: Unused
+ * @flag: Command flags (CMD_FLAG_...)
+ * @argc: Number of arguments
+ * @argv: List of arguments
+ * Return: result (see enum command_ret_t)
+ */
+int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
+
+/**
* do_tftpb - Run the tftpboot command
*
* @cmdtp: Command information for tftpboot
@@ -574,4 +585,6 @@ extern struct wget_http_info default_wget_info;
extern struct wget_http_info *wget_info;
int wget_request(ulong dst_addr, char *uri, struct wget_http_info *info);
+void net_sntp_set_rtc(u32 seconds);
+
#endif /* __NET_COMMON_H__ */
diff --git a/include/net-lwip.h b/include/net-lwip.h
index b762956e8fd..f54f23471f1 100644
--- a/include/net-lwip.h
+++ b/include/net-lwip.h
@@ -6,6 +6,20 @@
#include <lwip/ip4.h>
#include <lwip/netif.h>
+/* HTTPS authentication mode */
+enum auth_mode {
+ AUTH_NONE,
+ AUTH_OPTIONAL,
+ AUTH_REQUIRED,
+};
+
+extern char *cacert;
+extern size_t cacert_size;
+extern enum auth_mode cacert_auth_mode;
+extern bool cacert_initialized;
+
+int set_cacert_builtin(void);
+
enum proto_t {
TFTPGET
};
@@ -17,12 +31,14 @@ static inline int eth_is_on_demand_init(void)
int eth_init_state_only(void); /* Set active state */
+int net_lwip_dns_init(void);
int net_lwip_eth_start(void);
struct netif *net_lwip_new_netif(struct udevice *udev);
struct netif *net_lwip_new_netif_noip(struct udevice *udev);
void net_lwip_remove_netif(struct netif *netif);
struct netif *net_lwip_get_netif(void);
int net_lwip_rx(struct udevice *udev, struct netif *netif);
+int net_lwip_dns_resolve(char *name_or_ip, ip_addr_t *ip);
/**
* wget_validate_uri() - varidate the uri
diff --git a/include/part.h b/include/part.h
index 7075b2cb116..b772fb34c8a 100644
--- a/include/part.h
+++ b/include/part.h
@@ -8,7 +8,6 @@
#include <blk.h>
#include <u-boot/uuid.h>
-#include <linker_lists.h>
#include <linux/errno.h>
#include <linux/list.h>
@@ -647,6 +646,20 @@ int gpt_verify_partitions(struct blk_desc *desc,
*/
int get_disk_guid(struct blk_desc *desc, char *guid);
+/**
+ * part_get_gpt_pte() - Get the GPT partition table entry of a partition
+ *
+ * This function reads the GPT partition table entry (PTE) for a given
+ * block device and partition number.
+ *
+ * @desc: block device descriptor
+ * @part: partition number for which to return the PTE
+ * @gpt_e: GPT partition table entry
+ *
+ * Return: 0 on success, otherwise error
+ */
+int part_get_gpt_pte(struct blk_desc *desc, int part, gpt_entry *gpt_e);
+
#endif
#if CONFIG_IS_ENABLED(DOS_PARTITION)
diff --git a/include/part_efi.h b/include/part_efi.h
index 59b7895b8a2..fb402df6f13 100644
--- a/include/part_efi.h
+++ b/include/part_efi.h
@@ -138,4 +138,24 @@ typedef struct _legacy_mbr {
__le16 signature;
} __packed legacy_mbr;
+#define EFI_PARTITION_INFO_PROTOCOL_GUID \
+ EFI_GUID(0x8cf2f62c, 0xbc9b, 0x4821, 0x80, \
+ 0x8d, 0xec, 0x9e, 0xc4, 0x21, 0xa1, 0xa0)
+
+#define EFI_PARTITION_INFO_PROTOCOL_REVISION 0x0001000
+#define PARTITION_TYPE_OTHER 0x00
+#define PARTITION_TYPE_MBR 0x01
+#define PARTITION_TYPE_GPT 0x02
+
+struct efi_partition_info {
+ u32 revision;
+ u32 type;
+ u8 system;
+ u8 reserved[7];
+ union {
+ struct partition mbr;
+ gpt_entry gpt;
+ } info;
+} __packed;
+
#endif /* _DISK_PART_EFI_H */
diff --git a/include/sata.h b/include/sata.h
index 8414e77e42b..868e89464f0 100644
--- a/include/sata.h
+++ b/include/sata.h
@@ -1,6 +1,7 @@
#ifndef __SATA_H__
#define __SATA_H__
-#include <part.h>
+
+#include <stdbool.h>
int sata_probe(int devnum);
int sata_remove(int devnum);
diff --git a/include/spl_gpio.h b/include/spl_gpio.h
index b33261a6485..a8aed4d77b9 100644
--- a/include/spl_gpio.h
+++ b/include/spl_gpio.h
@@ -9,7 +9,7 @@
#ifndef __SPL_GPIO_H
#define __SPL_GPIO_H
-#include <asm/gpio.h>
+#include <linux/types.h>
/*
* The functions listed here should be implemented in the SoC GPIO driver.
diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index ece422df0c7..f3eb2ef5643 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -20,6 +20,7 @@
#define __TPM_V2_H
#include <tpm-common.h>
+#include <linux/errno.h>
struct udevice;
@@ -266,6 +267,7 @@ enum tpm2_return_codes {
* TPM2 algorithms.
*/
enum tpm2_algorithms {
+ TPM2_ALG_INVAL = -EINVAL,
TPM2_ALG_SHA1 = 0x04,
TPM2_ALG_XOR = 0x0A,
TPM2_ALG_SHA256 = 0x0B,
diff --git a/include/vsc9953.h b/include/vsc9953.h
index fd52c93044b..1a1455af4f9 100644
--- a/include/vsc9953.h
+++ b/include/vsc9953.h
@@ -8,8 +8,6 @@
#ifndef _VSC9953_H_
#define _VSC9953_H_
-#include <config.h>
-#include <miiphy.h>
#include <asm/types.h>
#include <linux/bitops.h>
diff --git a/include/zynqmp_firmware.h b/include/zynqmp_firmware.h
index dc06abc52fc..7ef8a58847f 100644
--- a/include/zynqmp_firmware.h
+++ b/include/zynqmp_firmware.h
@@ -8,6 +8,8 @@
#ifndef _ZYNQMP_FIRMWARE_H_
#define _ZYNQMP_FIRMWARE_H_
+#include <compiler.h>
+
enum pm_api_id {
PM_GET_API_VERSION = 1,
PM_SET_CONFIGURATION = 2,
@@ -512,4 +514,11 @@ struct zynqmp_ipi_msg {
#define PM_REG_PMC_GLOBAL_NODE 0x30000004
#define PMC_MULTI_BOOT_MODE_REG_OFFSET 0x4
+#define __data __section(".data")
+
+typedef int (*smc_call_handler_t)(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
+ u32 arg3, u32 *ret_payload);
+
+extern smc_call_handler_t __data smc_call_handler;
+
#endif /* _ZYNQMP_FIRMWARE_H_ */
diff --git a/lib/ecdsa/ecdsa-libcrypto.c b/lib/ecdsa/ecdsa-libcrypto.c
index f0095e9dbcf..7415d685ee1 100644
--- a/lib/ecdsa/ecdsa-libcrypto.c
+++ b/lib/ecdsa/ecdsa-libcrypto.c
@@ -34,6 +34,112 @@ struct signer {
void *signature; /* Pointer to output signature. Do not free()!*/
};
+struct ecdsa_public_key {
+ const char *curve_name;
+ const uint8_t *x;
+ const uint8_t *y;
+ int size_bits;
+};
+
+static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)
+{
+ int x_len;
+ int y_len;
+
+ key->curve_name = fdt_getprop(fdt, node, "ecdsa,curve", NULL);
+ if (!key->curve_name)
+ return -ENOMSG;
+
+ if (!strcmp(key->curve_name, "prime256v1"))
+ key->size_bits = 256;
+ else if (!strcmp(key->curve_name, "secp384r1"))
+ key->size_bits = 384;
+ else
+ return -EINVAL;
+
+ key->x = fdt_getprop(fdt, node, "ecdsa,x-point", &x_len);
+ key->y = fdt_getprop(fdt, node, "ecdsa,y-point", &y_len);
+
+ if (!key->x || !key->y)
+ return -EINVAL;
+
+ if (x_len != key->size_bits / 8 || y_len != key->size_bits / 8)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)
+{
+ struct ecdsa_public_key pubkey;
+ const EC_GROUP *group;
+ EC_POINT *point;
+ EC_KEY *ec_key;
+ int ret;
+ int nid;
+ int len;
+
+ ret = fdt_get_key(&pubkey, fdt, node);
+ if (ret) {
+ fprintf(stderr, "Failed to parse ECDSA key from FDT node %d (ret=%d)\n", node, ret);
+ return ret;
+ }
+
+ if (!strcmp(pubkey.curve_name, "prime256v1")) {
+ nid = NID_X9_62_prime256v1;
+ } else if (!strcmp(pubkey.curve_name, "secp384r1")) {
+ nid = NID_secp384r1;
+ } else {
+ fprintf(stderr, "Unsupported curve name: '%s'\n", pubkey.curve_name);
+ return -EINVAL;
+ }
+
+ fprintf(stderr, "Loading ECDSA key: curve=%s, bits=%d\n", pubkey.curve_name,
+ pubkey.size_bits);
+
+ ec_key = EC_KEY_new_by_curve_name(nid);
+ if (!ec_key) {
+ fprintf(stderr, "Failed to allocate EC_KEY for curve %s\n", pubkey.curve_name);
+ return -ENOMEM;
+ }
+
+ group = EC_KEY_get0_group(ec_key);
+ point = EC_POINT_new(group);
+ if (!point) {
+ fprintf(stderr, "Failed to allocate EC_POINT\n");
+ EC_KEY_free(ec_key);
+ return -ENOMEM;
+ }
+
+ len = pubkey.size_bits / 8;
+
+ uint8_t buf[1 + len * 2];
+
+ /* uncompressed */
+ buf[0] = 0x04;
+ memcpy(&buf[1], pubkey.x, len);
+ memcpy(&buf[1 + len], pubkey.y, len);
+ if (!EC_POINT_oct2point(group, point, buf, sizeof(buf), NULL)) {
+ fprintf(stderr, "Failed to convert (x,y) point to EC_POINT\n");
+ EC_POINT_free(point);
+ EC_KEY_free(ec_key);
+ return -EINVAL;
+ }
+
+ if (!EC_KEY_set_public_key(ec_key, point)) {
+ fprintf(stderr, "Failed to set EC_POINT as public key\n");
+ EC_POINT_free(point);
+ EC_KEY_free(ec_key);
+ return -EINVAL;
+ }
+
+ fprintf(stderr, "Successfully loaded ECDSA key from FDT node %d\n", node);
+ EC_POINT_free(point);
+ ctx->ecdsa_key = ec_key;
+
+ return 0;
+}
+
static int alloc_ctx(struct signer *ctx, const struct image_sign_info *info)
{
memset(ctx, 0, sizeof(*ctx));
@@ -153,6 +259,72 @@ static int read_key(struct signer *ctx, const char *key_name)
return (ctx->ecdsa_key) ? 0 : -EINVAL;
}
+static int load_key_from_fdt(struct signer *ctx, const struct image_sign_info *info)
+{
+ const void *fdt = info->fdt_blob;
+ char name[128];
+ int sig_node;
+ int key_node;
+ int key_len;
+ int ret;
+
+ if (!fdt)
+ return -EINVAL;
+
+ ret = alloc_ctx(ctx, info);
+ if (ret)
+ return ret;
+
+ sig_node = fdt_subnode_offset(fdt, 0, FIT_SIG_NODENAME);
+ if (sig_node < 0) {
+ fprintf(stderr, "No /signature node found\n");
+ return -ENOENT;
+ }
+
+ /* Case 1: explicitly specified key node */
+ if (info->required_keynode >= 0) {
+ ret = read_key_from_fdt(ctx, fdt, info->required_keynode);
+ if (ret == 0)
+ goto check_key_len;
+
+ fprintf(stderr, "Failed to load required keynode %d\n", info->required_keynode);
+ return ret;
+ }
+
+ /* Case 2: use keyname hint */
+ if (info->keyname) {
+ snprintf(name, sizeof(name), "%s", info->keyname);
+ key_node = fdt_subnode_offset(fdt, sig_node, name);
+ if (key_node >= 0) {
+ ret = read_key_from_fdt(ctx, fdt, key_node);
+ if (ret == 0)
+ goto check_key_len;
+
+ fprintf(stderr, "Key hint '%s' found but failed to load\n", info->keyname);
+ }
+ }
+
+ /* Case 3: try all subnodes */
+ fdt_for_each_subnode(key_node, fdt, sig_node) {
+ ret = read_key_from_fdt(ctx, fdt, key_node);
+ if (ret == 0)
+ goto check_key_len;
+ }
+
+ fprintf(stderr, "Failed to load any usable ECDSA key from FDT\n");
+ return -EINVAL;
+
+check_key_len:
+ key_len = ecdsa_key_size_bytes(ctx->ecdsa_key);
+ if (key_len != info->crypto->key_len) {
+ fprintf(stderr, "Expected %u-bit key, got %u-bit key\n",
+ info->crypto->key_len * 8, key_len * 8);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
/* Prepare a 'signer' context that's ready to sign and verify. */
static int prepare_ctx(struct signer *ctx, const struct image_sign_info *info)
{
@@ -161,7 +333,9 @@ static int prepare_ctx(struct signer *ctx, const struct image_sign_info *info)
memset(ctx, 0, sizeof(*ctx));
- if (info->keyfile) {
+ if (info->fdt_blob) {
+ return load_key_from_fdt(ctx, info);
+ } else if (info->keyfile) {
snprintf(kname, sizeof(kname), "%s", info->keyfile);
} else if (info->keydir && info->keyname) {
snprintf(kname, sizeof(kname), "%s/%s.pem", info->keydir,
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 3dadbc54b58..077466f01f0 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -71,6 +71,15 @@ config EFI_SECURE_BOOT
config EFI_SIGNATURE_SUPPORT
bool
+config EFI_DEBUG_SUPPORT
+ bool "EFI Debug Support"
+ default y if !HAS_BOARD_SIZE_LIMIT
+ help
+ Select this option if you want to setup the EFI Debug Support
+ Table and the EFI_SYSTEM_TABLE_POINTER which is used by the debug
+ agent or an external debugger to determine loaded image information
+ in a quiescent manner.
+
menu "UEFI services"
config EFI_GET_TIME
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index cf050e5385d..bfa607c8827 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -21,6 +21,7 @@ ifeq ($(CONFIG_GENERATE_ACPI_TABLE),)
apps-y += dtbdump
endif
apps-$(CONFIG_BOOTEFI_TESTAPP_COMPILE) += testapp
+apps-y += dbginfodump
obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o
obj-$(CONFIG_EFI_BOOTMGR) += efi_bootmgr.o
@@ -70,6 +71,7 @@ obj-$(CONFIG_EFI_RISCV_BOOT_PROTOCOL) += efi_riscv.o
obj-$(CONFIG_EFI_LOAD_FILE2_INITRD) += efi_load_initrd.o
obj-$(CONFIG_EFI_SIGNATURE_SUPPORT) += efi_signature.o
obj-$(CONFIG_EFI_ECPT) += efi_conformance.o
+obj-$(CONFIG_EFI_DEBUG_SUPPORT) += efi_debug_support.o
EFI_VAR_SEED_FILE := $(subst $\",,$(CONFIG_EFI_VAR_SEED_FILE))
$(obj)/efi_var_seed.o: $(srctree)/$(EFI_VAR_SEED_FILE)
diff --git a/lib/efi_loader/dbginfodump.c b/lib/efi_loader/dbginfodump.c
new file mode 100644
index 00000000000..adbbd5060cc
--- /dev/null
+++ b/lib/efi_loader/dbginfodump.c
@@ -0,0 +1,356 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2025, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * dbginfodump.efi prints out the content of the EFI_DEBUG_IMAGE_INFO_TABLE.
+ */
+
+#include <efi_api.h>
+
+/**
+ * BUFFER_SIZE - size of the command line input buffer
+ */
+#define BUFFER_SIZE 64
+
+static struct efi_simple_text_output_protocol *cerr;
+static struct efi_simple_text_output_protocol *cout;
+static struct efi_simple_text_input_protocol *cin;
+static efi_handle_t handle;
+static struct efi_system_table *systable;
+static struct efi_boot_services *bs;
+
+static efi_guid_t guid_device_path_to_text_protocol =
+ EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID;
+
+static struct efi_device_path_to_text_protocol *device_path_to_text;
+
+/* EFI_DEBUG_IMAGE_INFO_TABLE_GUID */
+static const efi_guid_t dbg_info_guid =
+ EFI_GUID(0x49152E77, 0x1ADA, 0x4764, 0xB7, 0xA2,
+ 0x7A, 0xFE, 0xFE, 0xD9, 0x5E, 0x8B);
+
+/* EFI_DEBUG_IMAGE_INFO_NORMAL */
+struct dbg_info {
+ u32 type;
+ struct efi_loaded_image *info;
+ efi_handle_t handle;
+};
+
+/* FI_DEBUG_IMAGE_INFO_TABLE_HEADER */
+struct dbg_info_header {
+ u32 status;
+ u32 size;
+ struct dbg_info **info;
+};
+
+/**
+ * print() - print string
+ *
+ * @string: text
+ */
+static void print(u16 *string)
+{
+ cout->output_string(cout, string);
+}
+
+/**
+ * error() - print error string
+ *
+ * @string: error text
+ */
+static void error(u16 *string)
+{
+ cout->set_attribute(cout, EFI_LIGHTRED | EFI_BACKGROUND_BLACK);
+ print(string);
+ cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK);
+}
+
+/**
+ * printu() - print unsigned
+ *
+ * @val: value to print
+ */
+static void printu(u32 val)
+{
+ u16 str[19] = u"0x";
+ u16 *ptr = &str[2];
+ u16 ch;
+
+ for (ssize_t i = 8 * sizeof(u32) - 4; i >= 0; i -= 4) {
+ ch = (val >> i & 0xf) + '0';
+ if (ch > '9')
+ ch += 'a' - '9' - 1;
+ *ptr++ = ch;
+ }
+ *ptr = 0;
+ print(str);
+}
+
+/**
+ * printp() - print pointer
+ *
+ * @p: pointer
+ */
+static void printp(void *p)
+{
+ u16 str[19] = u"0x";
+ u16 *ptr = &str[2];
+ u16 ch;
+
+ for (ssize_t i = 8 * sizeof(void *) - 4; i >= 0; i -= 4) {
+ ch = ((uintptr_t)p >> i & 0xf) + '0';
+ if (ch > '9')
+ ch += 'a' - '9' - 1;
+ *ptr++ = ch;
+ }
+ *ptr = 0;
+ print(str);
+}
+
+/**
+ * efi_input() - read string from console
+ *
+ * @buffer: input buffer
+ * @buffer_size: buffer size
+ * Return: status code
+ */
+static efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size)
+{
+ struct efi_input_key key = {0};
+ efi_uintn_t index;
+ efi_uintn_t pos = 0;
+ u16 outbuf[2] = u" ";
+ efi_status_t ret;
+
+ /* Drain the console input */
+ ret = cin->reset(cin, true);
+ *buffer = 0;
+ for (;;) {
+ ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
+ if (ret != EFI_SUCCESS)
+ continue;
+ ret = cin->read_key_stroke(cin, &key);
+ if (ret != EFI_SUCCESS)
+ continue;
+ switch (key.scan_code) {
+ case 0x17: /* Escape */
+ print(u"\r\nAborted\r\n");
+ return EFI_ABORTED;
+ default:
+ break;
+ }
+ switch (key.unicode_char) {
+ case 0x08: /* Backspace */
+ if (pos) {
+ buffer[pos--] = 0;
+ print(u"\b \b");
+ }
+ break;
+ case 0x0a: /* Linefeed */
+ case 0x0d: /* Carriage return */
+ print(u"\r\n");
+ return EFI_SUCCESS;
+ default:
+ break;
+ }
+ /* Ignore surrogate codes */
+ if (key.unicode_char >= 0xD800 && key.unicode_char <= 0xDBFF)
+ continue;
+ if (key.unicode_char >= 0x20 &&
+ pos < buffer_size - 1) {
+ *outbuf = key.unicode_char;
+ buffer[pos++] = key.unicode_char;
+ buffer[pos] = 0;
+ print(outbuf);
+ }
+ }
+}
+
+/**
+ * skip_whitespace() - skip over leading whitespace
+ *
+ * @pos: UTF-16 string
+ * Return: pointer to first non-whitespace
+ */
+static u16 *skip_whitespace(u16 *pos)
+{
+ for (; *pos && *pos <= 0x20; ++pos)
+ ;
+ return pos;
+}
+
+/**
+ * starts_with() - check if @string starts with @keyword
+ *
+ * @string: string to search for keyword
+ * @keyword: keyword to be searched
+ * Return: true fi @string starts with the keyword
+ */
+static bool starts_with(u16 *string, u16 *keyword)
+{
+ for (; *keyword; ++string, ++keyword) {
+ if (*string != *keyword)
+ return false;
+ }
+ return true;
+}
+
+/**
+ * do_help() - print help
+ */
+static void do_help(void)
+{
+ error(u"dump - print debug info table\r\n");
+ error(u"exit - exit the shell\r\n");
+}
+
+/**
+ * get_dbg_info_table() - get debug info table
+ *
+ * Return: debug info table or NULL
+ */
+static void *get_dbg_info(void)
+{
+ void *dbg = NULL;
+ efi_uintn_t i;
+
+ for (i = 0; i < systable->nr_tables; ++i) {
+ if (!memcmp(&systable->tables[i].guid, &dbg_info_guid,
+ sizeof(efi_guid_t))) {
+ dbg = systable->tables[i].table;
+ break;
+ }
+ }
+ return dbg;
+}
+
+/**
+ * print_info() - print loaded image protocol
+ */
+static void print_info(struct efi_loaded_image *info)
+{
+ print(u" Address: [");
+ printp(info->image_base);
+ print(u", ");
+ printp(info->image_base + info->image_size - 1);
+ print(u"]\r\n");
+ if (device_path_to_text && info->file_path) {
+ u16 *string;
+
+ string = device_path_to_text->convert_device_path_to_text(
+ info->file_path, true, false);
+ if (!string) {
+ error(u"ConvertDevicePathToText failed");
+ } else {
+ print(u" File: ");
+ print(string);
+ }
+ print(u"\r\n");
+ }
+}
+
+/**
+ * do_dump() - print debug info table
+ */
+static efi_status_t do_dump(void)
+{
+ struct dbg_info_header *dbg;
+ u32 count;
+
+ dbg = get_dbg_info();
+ if (!dbg) {
+ error(u"Debug info table not found\r\n");
+ return EFI_NOT_FOUND;
+ }
+ if (dbg->status & 0x01) {
+ error(u"Update in progress\r\n");
+ return EFI_LOAD_ERROR;
+ }
+ if (dbg->status & 0x02)
+ print(u"Modified\r\n");
+ print(u"Number of entries: ");
+ printu(dbg->size);
+ print(u"\r\n");
+
+ count = dbg->size;
+ for (u32 i = 0; count; ++i) {
+ struct dbg_info *info = dbg->info[i];
+
+ /*
+ * The EDK II implementation decreases the size field and
+ * writes a NULL value when deleting an entry which is not
+ * backed by the UEFI specification.
+ */
+ if (!info) {
+ print(u"Deleted entry\r\n");
+ continue;
+ }
+ --count;
+ print(u"Info type ");
+ printu(info->type);
+ print(u"\r\n");
+ if (info->type != 1)
+ continue;
+ print_info(info->info);
+ print(u" Handle: ");
+ printp(info->handle);
+ print(u"\r\n");
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ * efi_main() - entry point of the EFI application.
+ *
+ * @handle: handle of the loaded image
+ * @systab: system table
+ * Return: status code
+ */
+efi_status_t EFIAPI efi_main(efi_handle_t image_handle,
+ struct efi_system_table *systab)
+{
+ efi_status_t ret;
+
+ handle = image_handle;
+ systable = systab;
+ cerr = systable->std_err;
+ cout = systable->con_out;
+ cin = systable->con_in;
+ bs = systable->boottime;
+
+ cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK);
+ cout->clear_screen(cout);
+ cout->set_attribute(cout, EFI_WHITE | EFI_BACKGROUND_BLACK);
+ print(u"Debug Info Table Dump\r\n=====================\r\n\r\n");
+ cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK);
+
+ ret = bs->locate_protocol(&guid_device_path_to_text_protocol,
+ NULL, (void **)&device_path_to_text);
+ if (ret != EFI_SUCCESS) {
+ error(u"No device path to text protocol\r\n");
+ device_path_to_text = NULL;
+ }
+
+ for (;;) {
+ u16 command[BUFFER_SIZE];
+ u16 *pos;
+ efi_uintn_t ret;
+
+ print(u"=> ");
+ ret = efi_input(command, sizeof(command));
+ if (ret == EFI_ABORTED)
+ break;
+ pos = skip_whitespace(command);
+ if (starts_with(pos, u"exit"))
+ break;
+ else if (starts_with(pos, u"dump"))
+ do_dump();
+ else
+ do_help();
+ }
+
+ cout->set_attribute(cout, EFI_LIGHTGRAY | EFI_BACKGROUND_BLACK);
+ cout->clear_screen(cout);
+ return EFI_SUCCESS;
+}
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
index b9437a81c64..662993fb809 100644
--- a/lib/efi_loader/efi_bootmgr.c
+++ b/lib/efi_loader/efi_bootmgr.c
@@ -1134,7 +1134,7 @@ efi_status_t efi_bootmgr_update_media_device_boot_option(void)
{
u32 i;
efi_status_t ret;
- efi_uintn_t count, num, total;
+ efi_uintn_t count, num, total = 0;
efi_handle_t *handles = NULL;
struct eficonfig_media_boot_option *opt = NULL;
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 754bc6a6519..ddc935d2240 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -2130,6 +2130,11 @@ efi_status_t EFIAPI efi_load_image(bool boot_policy,
*image_handle = NULL;
free(info);
}
+
+ if (IS_ENABLED(CONFIG_EFI_DEBUG_SUPPORT) && *image_handle)
+ efi_core_new_debug_image_info_entry(EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL,
+ info,
+ *image_handle);
error:
return EFI_EXIT(ret);
}
@@ -3360,6 +3365,8 @@ efi_status_t EFIAPI efi_unload_image(efi_handle_t image_handle)
ret = EFI_INVALID_PARAMETER;
goto out;
}
+ if (IS_ENABLED(CONFIG_EFI_DEBUG_SUPPORT))
+ efi_core_remove_debug_image_info_entry(image_handle);
switch (efiobj->type) {
case EFI_OBJECT_TYPE_STARTED_IMAGE:
/* Call the unload function */
diff --git a/lib/efi_loader/efi_debug_support.c b/lib/efi_loader/efi_debug_support.c
new file mode 100644
index 00000000000..186bdbce750
--- /dev/null
+++ b/lib/efi_loader/efi_debug_support.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * EFI debug support
+ *
+ * Copyright (c) 2025 Ying-Chun Liu, Linaro Ltd. <paul.liu@linaro.org>
+ */
+
+#include <efi_loader.h>
+#include <linux/sizes.h>
+#include <u-boot/crc.h>
+
+struct efi_system_table_pointer __efi_runtime_data * systab_pointer = NULL;
+
+struct efi_debug_image_info_table_header efi_m_debug_info_table_header = {
+ 0,
+ 0,
+ NULL
+};
+
+/* efi_m_max_table_entries is the maximum entries allocated for
+ * the efi_m_debug_info_table_header.efi_debug_image_info_table.
+ */
+static u32 efi_m_max_table_entries;
+
+#define EFI_DEBUG_TABLE_ENTRY_SIZE (sizeof(union efi_debug_image_info *))
+
+/**
+ * efi_initialize_system_table_pointer() - Initialize system table pointer
+ *
+ * Return: status code
+ */
+efi_status_t efi_initialize_system_table_pointer(void)
+{
+ /* Allocate efi_system_table_pointer structure with 4MB alignment. */
+ systab_pointer = efi_alloc_aligned_pages(sizeof(struct efi_system_table_pointer),
+ EFI_RUNTIME_SERVICES_DATA,
+ SZ_4M);
+
+ if (!systab_pointer) {
+ log_err("Installing EFI system table pointer failed\n");
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ systab_pointer->crc32 = 0;
+
+ systab_pointer->signature = EFI_SYSTEM_TABLE_SIGNATURE;
+ systab_pointer->efi_system_table_base = (uintptr_t)&systab;
+ systab_pointer->crc32 = crc32(0,
+ (const unsigned char *)systab_pointer,
+ sizeof(struct efi_system_table_pointer));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ * efi_core_new_debug_image_info_entry() - Add a new efi_loaded_image structure to the
+ * efi_debug_image_info table.
+ *
+ * @image_info_type: type of debug image information
+ * @loaded_image: pointer to the loaded image protocol for the image
+ * being loaded
+ * @image_handle: image handle for the image being loaded
+ *
+ * Re-Allocates the table if it's not large enough to accommodate another
+ * entry.
+ *
+ * Return: status code
+ **/
+efi_status_t efi_core_new_debug_image_info_entry(u32 image_info_type,
+ struct efi_loaded_image *loaded_image,
+ efi_handle_t image_handle)
+{
+ union efi_debug_image_info **table;
+ u32 index;
+ u32 table_size;
+ efi_status_t ret;
+
+ /* Set the flag indicating that we're in the process of updating
+ * the table.
+ */
+ efi_m_debug_info_table_header.update_status |=
+ EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
+
+ table = &efi_m_debug_info_table_header.efi_debug_image_info_table;
+
+ if (efi_m_debug_info_table_header.table_size >= efi_m_max_table_entries) {
+ /* table is full, re-allocate the buffer increasing the size
+ * by 4 KiB.
+ */
+ table_size = efi_m_max_table_entries * EFI_DEBUG_TABLE_ENTRY_SIZE;
+
+ ret = efi_realloc((void **)table, table_size + EFI_PAGE_SIZE);
+
+ if (ret != EFI_SUCCESS) {
+ efi_m_debug_info_table_header.update_status &=
+ ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
+ return ret;
+ }
+
+ /* Enlarge the max table entries and set the first empty
+ * entry index to be the original max table entries.
+ */
+ efi_m_max_table_entries +=
+ EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE;
+ }
+
+ /* We always put the next entry at the end of the currently consumed
+ * table (i.e. first free entry)
+ */
+ index = efi_m_debug_info_table_header.table_size;
+
+ /* Allocate data for new entry. */
+ ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA,
+ sizeof(union efi_debug_image_info),
+ (void **)(&(*table)[index].normal_image));
+ if (ret == EFI_SUCCESS && (*table)[index].normal_image) {
+ /* Update the entry. */
+ (*table)[index].normal_image->image_info_type = image_info_type;
+ (*table)[index].normal_image->loaded_image_protocol_instance =
+ loaded_image;
+ (*table)[index].normal_image->image_handle = image_handle;
+
+ /* Increase the number of EFI_DEBUG_IMAGE_INFO elements and
+ * set the efi_m_debug_info_table_header in modified status.
+ */
+ efi_m_debug_info_table_header.table_size++;
+ efi_m_debug_info_table_header.update_status |=
+ EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED;
+ } else {
+ log_err("Adding new efi_debug_image_info failed\n");
+ return ret;
+ }
+
+ efi_m_debug_info_table_header.update_status &=
+ ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ * efi_core_remove_debug_image_info_entry() - Remove an efi_debug_image_info entry.
+ *
+ * @image_handle: image handle for the image being removed
+ **/
+void efi_core_remove_debug_image_info_entry(efi_handle_t image_handle)
+{
+ union efi_debug_image_info *table;
+ u32 index;
+
+ efi_m_debug_info_table_header.update_status |=
+ EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
+
+ table = efi_m_debug_info_table_header.efi_debug_image_info_table;
+
+ for (index = 0; index < efi_m_max_table_entries; index++) {
+ if (table[index].normal_image &&
+ table[index].normal_image->image_handle == image_handle) {
+ /* Found a match. Free up the table entry.
+ * Move the tail of the table one slot to the front.
+ */
+ efi_free_pool(table[index].normal_image);
+
+ memmove(&table[index],
+ &table[index + 1],
+ (efi_m_debug_info_table_header.table_size -
+ index - 1) * EFI_DEBUG_TABLE_ENTRY_SIZE);
+
+ /* Decrease the number of EFI_DEBUG_IMAGE_INFO
+ * elements and set the efi_m_debug_info_table_header
+ * in modified status.
+ */
+ efi_m_debug_info_table_header.table_size--;
+ table[efi_m_debug_info_table_header.table_size].normal_image =
+ NULL;
+ efi_m_debug_info_table_header.update_status |=
+ EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED;
+ break;
+ }
+ }
+
+ efi_m_debug_info_table_header.update_status &=
+ ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
+}
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 47b583cc5e1..130c4db9606 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -26,6 +26,7 @@ struct efi_system_partition efi_system_partition = {
const efi_guid_t efi_block_io_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID;
+const efi_guid_t efi_partition_info_guid = EFI_PARTITION_INFO_PROTOCOL_GUID;
/**
* struct efi_disk_obj - EFI disk object
@@ -35,6 +36,7 @@ const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID;
* @media: block I/O media information
* @dp: device path to the block device
* @volume: simple file system protocol of the partition
+ * @info: EFI partition info protocol interface
*/
struct efi_disk_obj {
struct efi_object header;
@@ -42,6 +44,7 @@ struct efi_disk_obj {
struct efi_block_io_media media;
struct efi_device_path *dp;
struct efi_simple_file_system_protocol *volume;
+ struct efi_partition_info info;
};
/**
@@ -426,6 +429,7 @@ static efi_status_t efi_disk_add_dev(
/* Fill in object data */
if (part_info) {
struct efi_device_path *node = efi_dp_part_node(desc, part);
+ struct efi_partition_info *info = &diskobj->info;
struct efi_handler *handler;
void *protocol_interface;
@@ -454,18 +458,48 @@ static efi_status_t efi_disk_add_dev(
goto error;
}
+ info->revision = EFI_PARTITION_INFO_PROTOCOL_REVISION;
+
+ switch (desc->part_type) {
+#if CONFIG_IS_ENABLED(EFI_PARTITION)
+ case PART_TYPE_EFI:
+ info->type = PARTITION_TYPE_GPT;
+ ret = part_get_gpt_pte(desc, part, &info->info.gpt);
+ if (ret) {
+ log_debug("get PTE for part %d failed %ld\n",
+ part, ret);
+ goto error;
+ }
+ break;
+#endif
+#if CONFIG_IS_ENABLED(DOS_PARTITION)
+ case PART_TYPE_DOS:
+ info->type = PARTITION_TYPE_MBR;
+
+ /* TODO: implement support for MBR partition types */
+ log_debug("EFI_PARTITION_INFO_PROTOCOL doesn't support MBR\n");
+ break;
+#endif
+ default:
+ info->type = PARTITION_TYPE_OTHER;
+ break;
+ }
+
diskobj->dp = efi_dp_append_node(dp_parent, node);
efi_free_pool(node);
diskobj->media.last_block = part_info->size - 1;
- if (part_info->bootable & PART_EFI_SYSTEM_PARTITION)
+ if (part_info->bootable & PART_EFI_SYSTEM_PARTITION) {
esp_guid = &efi_system_partition_guid;
+ info->system = 1;
+ }
+
} else {
diskobj->dp = efi_dp_from_part(desc, part);
diskobj->media.last_block = desc->lba - 1;
}
/*
- * Install the device path and the block IO protocol.
+ * Install the device path, the block IO and partition info protocols.
*
* InstallMultipleProtocolInterfaces() checks if the device path is
* already installed on an other handle and returns EFI_ALREADY_STARTED
@@ -476,6 +510,7 @@ static efi_status_t efi_disk_add_dev(
&handle,
&efi_guid_device_path, diskobj->dp,
&efi_block_io_guid, &diskobj->ops,
+ &efi_partition_info_guid, &diskobj->info,
/*
* esp_guid must be last entry as it
* can be NULL. Its interface is NULL.
diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c
index 7d81da8f2d8..19b43c4a625 100644
--- a/lib/efi_loader/efi_file.c
+++ b/lib/efi_loader/efi_file.c
@@ -248,7 +248,7 @@ static struct efi_file_handle *file_open(struct file_system *fs,
return &fh->base;
error:
- free(fh->path);
+ free(path);
free(fh);
return NULL;
}
diff --git a/lib/efi_loader/efi_http.c b/lib/efi_loader/efi_http.c
index 189317fe2d2..9a0f2675132 100644
--- a/lib/efi_loader/efi_http.c
+++ b/lib/efi_loader/efi_http.c
@@ -453,7 +453,6 @@ static efi_status_t EFIAPI efi_http_service_binding_destroy_child(
efi_status_t ret = EFI_SUCCESS;
struct efi_http_instance *http_instance;
struct efi_handler *phandler;
- void *protocol_interface;
if (num_instances == 0)
return EFI_EXIT(EFI_NOT_FOUND);
@@ -463,18 +462,18 @@ static efi_status_t EFIAPI efi_http_service_binding_destroy_child(
efi_search_protocol(child_handle, &efi_http_guid, &phandler);
- if (phandler)
- protocol_interface = phandler->protocol_interface;
+ if (!phandler)
+ return EFI_EXIT(EFI_UNSUPPORTED);
ret = efi_delete_handle(child_handle);
if (ret != EFI_SUCCESS)
return EFI_EXIT(ret);
- http_instance = (struct efi_http_instance *)protocol_interface;
+ http_instance = phandler->protocol_interface;
efi_free_pool(http_instance->http_load_addr);
http_instance->http_load_addr = NULL;
- free(protocol_interface);
+ free(phandler->protocol_interface);
num_instances--;
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index 0abb1f6159a..6dfc698a247 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -454,6 +454,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type,
enum efi_memory_type memory_type,
efi_uintn_t pages, uint64_t *memory)
{
+ int err;
u64 efi_addr, len;
uint flags;
efi_status_t ret;
@@ -475,17 +476,18 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type,
switch (type) {
case EFI_ALLOCATE_ANY_PAGES:
/* Any page */
- addr = (u64)lmb_alloc_base(len, EFI_PAGE_SIZE,
- LMB_ALLOC_ANYWHERE, flags);
- if (!addr)
+ err = lmb_alloc_mem(LMB_MEM_ALLOC_ANY, EFI_PAGE_SIZE, &addr,
+ len, flags);
+ if (err)
return EFI_OUT_OF_RESOURCES;
break;
case EFI_ALLOCATE_MAX_ADDRESS:
/* Max address */
addr = map_to_sysmem((void *)(uintptr_t)*memory);
- addr = (u64)lmb_alloc_base(len, EFI_PAGE_SIZE, addr,
- flags);
- if (!addr)
+
+ err = lmb_alloc_mem(LMB_MEM_ALLOC_MAX, EFI_PAGE_SIZE, &addr,
+ len, flags);
+ if (err)
return EFI_OUT_OF_RESOURCES;
break;
case EFI_ALLOCATE_ADDRESS:
@@ -493,7 +495,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type,
return EFI_NOT_FOUND;
addr = map_to_sysmem((void *)(uintptr_t)*memory);
- if (lmb_alloc_addr(addr, len, flags))
+ if (lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &addr, len, flags))
return EFI_NOT_FOUND;
break;
default:
@@ -506,7 +508,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type,
ret = efi_update_memory_map(efi_addr, pages, memory_type, true, false);
if (ret != EFI_SUCCESS) {
/* Map would overlap, bail out */
- lmb_free_flags(addr, (u64)pages << EFI_PAGE_SHIFT, flags);
+ lmb_free(addr, (u64)pages << EFI_PAGE_SHIFT, flags);
unmap_sysmem((void *)(uintptr_t)efi_addr);
return EFI_OUT_OF_RESOURCES;
}
@@ -546,8 +548,8 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages)
* been mapped with map_sysmem() from efi_allocate_pages(). Convert
* it back to an address LMB understands
*/
- status = lmb_free_flags(map_to_sysmem((void *)(uintptr_t)memory), len,
- LMB_NOOVERWRITE);
+ status = lmb_free(map_to_sysmem((void *)(uintptr_t)memory), len,
+ LMB_NOOVERWRITE);
if (status)
return EFI_NOT_FOUND;
@@ -667,6 +669,64 @@ void *efi_alloc(size_t size)
}
/**
+ * efi_realloc() - reallocate boot services data pool memory
+ *
+ * Reallocate memory from pool for a new size and copy the data from old one.
+ *
+ * @ptr: pointer to old buffer
+ * @size: number of bytes to allocate
+ * Return: EFI status to indicate success or not
+ */
+efi_status_t efi_realloc(void **ptr, size_t size)
+{
+ efi_status_t ret;
+ void *new_ptr;
+ struct efi_pool_allocation *alloc;
+ u64 num_pages = efi_size_in_pages(size +
+ sizeof(struct efi_pool_allocation));
+ size_t old_size;
+
+ if (!*ptr) {
+ *ptr = efi_alloc(size);
+ if (*ptr)
+ return EFI_SUCCESS;
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ret = efi_check_allocated((uintptr_t)*ptr, true);
+ if (ret != EFI_SUCCESS)
+ return ret;
+
+ alloc = container_of(*ptr, struct efi_pool_allocation, data);
+
+ /* Check that this memory was allocated by efi_allocate_pool() */
+ if (((uintptr_t)alloc & EFI_PAGE_MASK) ||
+ alloc->checksum != checksum(alloc)) {
+ printf("%s: illegal realloc 0x%p\n", __func__, *ptr);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ /* Don't realloc. The actual size in pages is the same. */
+ if (alloc->num_pages == num_pages)
+ return EFI_SUCCESS;
+
+ old_size = alloc->num_pages * EFI_PAGE_SIZE -
+ sizeof(struct efi_pool_allocation);
+
+ new_ptr = efi_alloc(size);
+
+ /* copy old data to new alloced buffer */
+ memcpy(new_ptr, *ptr, min(size, old_size));
+
+ /* free the old buffer */
+ efi_free_pool(*ptr);
+
+ *ptr = new_ptr;
+
+ return EFI_SUCCESS;
+}
+
+/**
* efi_free_pool() - free memory from pool
*
* @buffer: start of memory to be freed
diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c
index 86f0af9538c..b8a6e08ba8e 100644
--- a/lib/efi_loader/efi_net.c
+++ b/lib/efi_loader/efi_net.c
@@ -1131,7 +1131,7 @@ efi_status_t efi_net_register(struct udevice *dev)
struct efi_net_obj *netobj;
void *transmit_buffer = NULL;
uchar **receive_buffer = NULL;
- size_t *receive_lengths;
+ size_t *receive_lengths = NULL;
int i, j;
if (!dev) {
diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
index 48f91da5df7..f06cf49e443 100644
--- a/lib/efi_loader/efi_setup.c
+++ b/lib/efi_loader/efi_setup.c
@@ -18,6 +18,9 @@
efi_status_t efi_obj_list_initialized = OBJ_LIST_NOT_INITIALIZED;
+const efi_guid_t efi_debug_image_info_table_guid =
+ EFI_DEBUG_IMAGE_INFO_TABLE_GUID;
+
/*
* Allow unaligned memory access.
*
@@ -278,6 +281,21 @@ efi_status_t efi_init_obj_list(void)
if (ret != EFI_SUCCESS)
goto out;
+ /* Initialize system table pointer */
+ if (IS_ENABLED(CONFIG_EFI_DEBUG_SUPPORT)) {
+ efi_guid_t debug_image_info_table_guid =
+ efi_debug_image_info_table_guid;
+
+ ret = efi_initialize_system_table_pointer();
+ if (ret != EFI_SUCCESS)
+ goto out;
+
+ ret = efi_install_configuration_table(&debug_image_info_table_guid,
+ &efi_m_debug_info_table_header);
+ if (ret != EFI_SUCCESS)
+ goto out;
+ }
+
if (IS_ENABLED(CONFIG_EFI_ECPT)) {
ret = efi_ecpt_register();
if (ret != EFI_SUCCESS)
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index d78bf7d6191..842433f68aa 100644
--- a/lib/efi_selftest/Makefile
+++ b/lib/efi_selftest/Makefile
@@ -78,6 +78,8 @@ endif
obj-$(CONFIG_EFI_ESRT) += efi_selftest_esrt.o
+obj-$(CONFIG_EFI_DEBUG_SUPPORT) += efi_selftest_debug_support.o
+
targets += \
efi_miniapp_file_image_exception.h \
efi_miniapp_file_image_exit.h \
diff --git a/lib/efi_selftest/efi_selftest_block_device.c b/lib/efi_selftest/efi_selftest_block_device.c
index a367e8b89d1..f145e58a267 100644
--- a/lib/efi_selftest/efi_selftest_block_device.c
+++ b/lib/efi_selftest/efi_selftest_block_device.c
@@ -18,6 +18,7 @@
#include <efi_selftest.h>
#include "efi_selftest_disk_image.h"
#include <asm/cache.h>
+#include <part_efi.h>
/* Block size of compressed disk image */
#define COMPRESSED_DISK_IMAGE_BLOCK_SIZE 8
@@ -29,6 +30,7 @@ static struct efi_boot_services *boottime;
static const efi_guid_t block_io_protocol_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
static const efi_guid_t guid_device_path = EFI_DEVICE_PATH_PROTOCOL_GUID;
+static const efi_guid_t partition_info_guid = EFI_PARTITION_INFO_PROTOCOL_GUID;
static const efi_guid_t guid_simple_file_system_protocol =
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
static const efi_guid_t guid_file_system_info = EFI_FILE_SYSTEM_INFO_GUID;
@@ -310,6 +312,7 @@ static int execute(void)
struct efi_file_system_info info;
u16 label[12];
} system_info;
+ struct efi_partition_info *part_info;
efi_uintn_t buf_size;
char buf[16] __aligned(ARCH_DMA_MINALIGN);
u32 part1_size;
@@ -375,6 +378,33 @@ static int execute(void)
part1_size - 1);
return EFI_ST_FAILURE;
}
+
+ /* Open the partition information protocol */
+ ret = boottime->open_protocol(handle_partition,
+ &partition_info_guid,
+ (void **)&part_info, NULL, NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to open partition information protocol\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Check that cached partition information is the expected */
+ if (part_info->revision != EFI_PARTITION_INFO_PROTOCOL_REVISION) {
+ efi_st_error("Partition info revision %x, expected %x\n",
+ part_info->revision, EFI_PARTITION_INFO_PROTOCOL_REVISION);
+ return EFI_ST_FAILURE;
+ }
+ if (part_info->type != PARTITION_TYPE_MBR) {
+ efi_st_error("Partition info type %x, expected %x\n",
+ part_info->type, PARTITION_TYPE_MBR);
+ return EFI_ST_FAILURE;
+ }
+ if (part_info->system != 0) {
+ efi_st_error("Partition info system %x, expected 0\n",
+ part_info->system);
+ return EFI_ST_FAILURE;
+ }
+
/* Open the simple file system protocol */
ret = boottime->open_protocol(handle_partition,
&guid_simple_file_system_protocol,
diff --git a/lib/efi_selftest/efi_selftest_debug_support.c b/lib/efi_selftest/efi_selftest_debug_support.c
new file mode 100644
index 00000000000..9ca8b3f82f5
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_debug_support.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * efi_selftest_debug_support
+ *
+ * Copyright (c) 2025 Ying-Chun Liu, Linaro Ltd. <paul.liu@linaro.org>
+ *
+ * Test the EFI_DEBUG_SUPPORT
+ */
+
+#include <efi_loader.h>
+#include <efi_selftest.h>
+
+/**
+ * efi_st_debug_support_execute() - execute test
+ *
+ * Test EFI_DEBUG_SUPPORT tables.
+ *
+ * Return: status code
+ */
+static int efi_st_debug_support_execute(void)
+{
+ struct efi_debug_image_info_table_header *efi_st_debug_info_table_header = NULL;
+ efi_guid_t efi_debug_image_info_table_guid = EFI_DEBUG_IMAGE_INFO_TABLE_GUID;
+
+ /* get EFI_DEBUG_IMAGE_INFO_TABLE */
+ efi_st_debug_info_table_header = efi_st_get_config_table(&efi_debug_image_info_table_guid);
+
+ if (!efi_st_debug_info_table_header) {
+ efi_st_error("Missing EFI_DEBUG_IMAGE_INFO_TABLE\n");
+ return EFI_ST_FAILURE;
+ }
+
+ return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(debug_support) = {
+ .name = "debug_support",
+ .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+ .execute = efi_st_debug_support_execute,
+};
diff --git a/lib/lmb.c b/lib/lmb.c
index bb6f232f6bc..45b26512a5b 100644
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -317,8 +317,34 @@ static long _lmb_free(struct alist *lmb_rgn_lst, phys_addr_t base,
rgn[i].flags);
}
-static long lmb_overlaps_region(struct alist *lmb_rgn_lst, phys_addr_t base,
- phys_size_t size)
+/**
+ * lmb_overlap_checks() - perform checks to see if region can be allocated or reserved
+ * @lmb_rgn_lst: list of LMB regions
+ * @base: base address of region to be checked
+ * @size: size of region to be checked
+ * @flags: flag of the region to be checked (only for reservation requests)
+ * @alloc: if checks are to be done for allocation or reservation request
+ *
+ * Check if the region passed to the function overlaps with any one of
+ * the regions of the passed lmb region list.
+ *
+ * If the @alloc flag is set to true, this check stops as soon an
+ * overlapping region is found. The function can also be called to
+ * check if a reservation request can be satisfied, by setting
+ * @alloc to false. In that case, the function then iterates through
+ * all the regions in the list passed to ensure that the requested
+ * region does not overlap with any existing regions. An overlap is
+ * allowed only when the flag of the requested region and the existing
+ * region is LMB_NONE.
+ *
+ * Return: index of the overlapping region, -1 if no overlap is found
+ *
+ * When the function is called for a reservation request check, -1 will
+ * also be returned when there is an allowed overlap, i.e. requested
+ * region and existing regions have flags as LMB_NONE.
+ */
+static long lmb_overlap_checks(struct alist *lmb_rgn_lst, phys_addr_t base,
+ phys_size_t size, u32 flags, bool alloc)
{
unsigned long i;
struct lmb_region *rgn = lmb_rgn_lst->data;
@@ -326,9 +352,12 @@ static long lmb_overlaps_region(struct alist *lmb_rgn_lst, phys_addr_t base,
for (i = 0; i < lmb_rgn_lst->count; i++) {
phys_addr_t rgnbase = rgn[i].base;
phys_size_t rgnsize = rgn[i].size;
+ u32 rgnflags = rgn[i].flags;
- if (lmb_addrs_overlap(base, size, rgnbase, rgnsize))
- break;
+ if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) {
+ if (alloc || flags != LMB_NONE || flags != rgnflags)
+ break;
+ }
}
return (i < lmb_rgn_lst->count) ? i : -1;
@@ -390,7 +419,8 @@ phys_addr_t io_lmb_alloc(struct lmb *io_lmb, phys_size_t size, ulong align)
base = ALIGN_DOWN(lmbbase + lmbsize - size, align);
while (base && lmbbase <= base) {
- rgn = lmb_overlaps_region(&io_lmb->used_mem, base, size);
+ rgn = lmb_overlap_checks(&io_lmb->used_mem, base, size,
+ LMB_NOOVERWRITE, true);
if (rgn < 0) {
/* This area isn't reserved, take it */
if (lmb_add_region_flags(&io_lmb->used_mem, base,
@@ -488,6 +518,21 @@ void lmb_dump_all(void)
#endif
}
+static long lmb_reserve(phys_addr_t base, phys_size_t size, u32 flags)
+{
+ long ret = 0;
+ struct alist *lmb_rgn_lst = &lmb.used_mem;
+
+ if (lmb_overlap_checks(lmb_rgn_lst, base, size, flags, false) != -1)
+ return -EEXIST;
+
+ ret = lmb_add_region_flags(lmb_rgn_lst, base, size, flags);
+ if (ret)
+ return ret;
+
+ return lmb_map_update_notify(base, size, LMB_MAP_OP_RESERVE, flags);
+}
+
static void lmb_reserve_uboot_region(void)
{
int bank;
@@ -557,40 +602,7 @@ static __maybe_unused void lmb_reserve_common_spl(void)
}
}
-/**
- * lmb_can_reserve_region() - check if the region can be reserved
- * @base: base address of region to be reserved
- * @size: size of region to be reserved
- * @flags: flag of the region to be reserved
- *
- * Go through all the reserved regions and ensure that the requested
- * region does not overlap with any existing regions. An overlap is
- * allowed only when the flag of the request region and the existing
- * region is LMB_NONE.
- *
- * Return: true if region can be reserved, false otherwise
- */
-static bool lmb_can_reserve_region(phys_addr_t base, phys_size_t size,
- u32 flags)
-{
- uint i;
- struct lmb_region *lmb_reserved = lmb.used_mem.data;
-
- for (i = 0; i < lmb.used_mem.count; i++) {
- u32 rgnflags = lmb_reserved[i].flags;
- phys_addr_t rgnbase = lmb_reserved[i].base;
- phys_size_t rgnsize = lmb_reserved[i].size;
-
- if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) {
- if (flags != LMB_NONE || flags != rgnflags)
- return false;
- }
- }
-
- return true;
-}
-
-void lmb_add_memory(void)
+static void lmb_add_memory(void)
{
int i;
phys_addr_t bank_end;
@@ -640,8 +652,7 @@ long lmb_add(phys_addr_t base, phys_size_t size)
return lmb_map_update_notify(base, size, LMB_MAP_OP_ADD, LMB_NONE);
}
-long lmb_free_flags(phys_addr_t base, phys_size_t size,
- uint flags)
+long lmb_free(phys_addr_t base, phys_size_t size, u32 flags)
{
long ret;
@@ -652,36 +663,18 @@ long lmb_free_flags(phys_addr_t base, phys_size_t size,
return lmb_map_update_notify(base, size, LMB_MAP_OP_FREE, flags);
}
-long lmb_free(phys_addr_t base, phys_size_t size)
-{
- return lmb_free_flags(base, size, LMB_NONE);
-}
-
-long lmb_reserve(phys_addr_t base, phys_size_t size, u32 flags)
-{
- long ret = 0;
- struct alist *lmb_rgn_lst = &lmb.used_mem;
-
- if (!lmb_can_reserve_region(base, size, flags))
- return -EEXIST;
-
- ret = lmb_add_region_flags(lmb_rgn_lst, base, size, flags);
- if (ret)
- return ret;
-
- return lmb_map_update_notify(base, size, LMB_MAP_OP_RESERVE, flags);
-}
-
-static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align,
- phys_addr_t max_addr, u32 flags)
+static int _lmb_alloc_base(phys_size_t size, ulong align,
+ phys_addr_t *addr, u32 flags)
{
int ret;
long i, rgn;
+ phys_addr_t max_addr;
phys_addr_t base = 0;
phys_addr_t res_base;
struct lmb_region *lmb_used = lmb.used_mem.data;
struct lmb_region *lmb_memory = lmb.available_mem.data;
+ max_addr = *addr;
for (i = lmb.available_mem.count - 1; i >= 0; i--) {
phys_addr_t lmbbase = lmb_memory[i].base;
phys_size_t lmbsize = lmb_memory[i].size;
@@ -702,7 +695,8 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align,
}
while (base && lmbbase <= base) {
- rgn = lmb_overlaps_region(&lmb.used_mem, base, size);
+ rgn = lmb_overlap_checks(&lmb.used_mem, base, size,
+ LMB_NOOVERWRITE, true);
if (rgn < 0) {
/* This area isn't reserved, take it */
if (lmb_add_region_flags(&lmb.used_mem, base,
@@ -714,8 +708,8 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align,
flags);
if (ret)
return ret;
-
- return base;
+ *addr = base;
+ return 0;
}
res_base = lmb_used[rgn].base;
@@ -728,27 +722,17 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align,
log_debug("%s: Failed to allocate 0x%lx bytes below 0x%lx\n",
__func__, (ulong)size, (ulong)max_addr);
- return 0;
-}
-
-phys_addr_t lmb_alloc(phys_size_t size, ulong align)
-{
- return _lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE, LMB_NONE);
-}
-
-phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr,
- uint flags)
-{
- return _lmb_alloc_base(size, align, max_addr, flags);
+ return -1;
}
-int lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags)
+static int _lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags)
{
long rgn;
struct lmb_region *lmb_memory = lmb.available_mem.data;
/* Check if the requested address is in one of the memory regions */
- rgn = lmb_overlaps_region(&lmb.available_mem, base, size);
+ rgn = lmb_overlap_checks(&lmb.available_mem, base, size,
+ LMB_NOOVERWRITE, true);
if (rgn >= 0) {
/*
* Check if the requested end address is in the same memory
@@ -756,14 +740,40 @@ int lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags)
*/
if (lmb_addrs_overlap(lmb_memory[rgn].base,
lmb_memory[rgn].size,
- base + size - 1, 1)) {
+ base + size - 1, 1))
/* ok, reserve the memory */
- if (!lmb_reserve(base, size, flags))
- return 0;
- }
+ return lmb_reserve(base, size, flags);
}
- return -1;
+ return -EINVAL;
+}
+
+int lmb_alloc_mem(enum lmb_mem_type type, u64 align, phys_addr_t *addr,
+ phys_size_t size, u32 flags)
+{
+ int ret = -1;
+
+ if (!size)
+ return 0;
+
+ if (!addr)
+ return -EINVAL;
+
+ switch (type) {
+ case LMB_MEM_ALLOC_ANY:
+ *addr = LMB_ALLOC_ANYWHERE;
+ case LMB_MEM_ALLOC_MAX:
+ ret = _lmb_alloc_base(size, align, addr, flags);
+ break;
+ case LMB_MEM_ALLOC_ADDR:
+ ret = _lmb_alloc_addr(*addr, size, flags);
+ break;
+ default:
+ log_debug("%s: Invalid memory allocation type requested %d\n",
+ __func__, type);
+ }
+
+ return ret;
}
/* Return number of bytes from a given address that are free */
@@ -775,7 +785,8 @@ phys_size_t lmb_get_free_size(phys_addr_t addr)
struct lmb_region *lmb_memory = lmb.available_mem.data;
/* check if the requested address is in the memory regions */
- rgn = lmb_overlaps_region(&lmb.available_mem, addr, 1);
+ rgn = lmb_overlap_checks(&lmb.available_mem, addr, 1, LMB_NOOVERWRITE,
+ true);
if (rgn >= 0) {
for (i = 0; i < lmb.used_mem.count; i++) {
if (addr < lmb_used[i].base) {
diff --git a/lib/lwip/Makefile b/lib/lwip/Makefile
index e9e8caee93a..c3f0e916f66 100644
--- a/lib/lwip/Makefile
+++ b/lib/lwip/Makefile
@@ -13,6 +13,7 @@ obj-y += \
lwip/src/api/sockets.o \
lwip/src/api/tcpip.o \
lwip/src/apps/http/http_client.o \
+ lwip/src/apps/sntp/sntp.o \
lwip/src/apps/tftp/tftp.o \
lwip/src/core/altcp_alloc.o \
lwip/src/core/altcp.o \
diff --git a/lib/lwip/u-boot/arch/cc.h b/lib/lwip/u-boot/arch/cc.h
index 6104c296f6f..f91127ac565 100644
--- a/lib/lwip/u-boot/arch/cc.h
+++ b/lib/lwip/u-boot/arch/cc.h
@@ -43,4 +43,8 @@
#define BYTE_ORDER BIG_ENDIAN
#endif
+#define SNTP_STARTUP_DELAY 0
+void sntp_set_system_time(uint32_t sec);
+#define SNTP_SET_SYSTEM_TIME(sec) sntp_set_system_time(sec)
+
#endif /* LWIP_ARCH_CC_H */
diff --git a/lib/lwip/u-boot/lwipopts.h b/lib/lwip/u-boot/lwipopts.h
index edac74ff7a2..46af91f9410 100644
--- a/lib/lwip/u-boot/lwipopts.h
+++ b/lib/lwip/u-boot/lwipopts.h
@@ -72,8 +72,8 @@
#define IP_FORWARD 0
#define IP_OPTIONS_ALLOWED 1
-#define IP_REASSEMBLY 0
-#define IP_FRAG 0
+#define IP_REASSEMBLY 1
+#define IP_FRAG 1
#define IP_REASS_MAXAGE 3
#define IP_REASS_MAX_PBUFS 4
#define IP_FRAG_USES_STATIC_BUF 0
@@ -162,4 +162,8 @@
#define LWIP_ALTCP_TLS_MBEDTLS 1
#endif
+#if defined(CONFIG_CMD_SNTP)
+#define LWIP_DHCP_GET_NTP_SRV 1
+#endif
+
#endif /* LWIP_UBOOT_LWIPOPTS_H */
diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c
index fa9e143b4ca..92b9d7876e5 100644
--- a/lib/rsa/rsa-sign.c
+++ b/lib/rsa/rsa-sign.c
@@ -122,7 +122,7 @@ static int rsa_engine_get_pub_key(const char *keydir, const char *name,
fprintf(stderr, "WARNING: Legacy URI specified. Please add '%s'.\n", pkcs11_schema);
}
- if (strstr(keydir, "object="))
+ if (strstr(keydir, "object=") || strstr(keydir, "id="))
snprintf(key_id, sizeof(key_id),
"%s%s;type=public",
pkcs11_uri_prepend, keydir);
@@ -253,7 +253,7 @@ static int rsa_engine_get_priv_key(const char *keydir, const char *name,
fprintf(stderr, "WARNING: Legacy URI specified. Please add '%s'.\n", pkcs11_schema);
}
- if (strstr(keydir, "object="))
+ if (strstr(keydir, "object=") || strstr(keydir, "id="))
snprintf(key_id, sizeof(key_id),
"%s%s;type=private",
pkcs11_uri_prepend, keydir);
diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
index 4a0418a75f1..b65fbe44007 100644
--- a/lib/rsa/rsa-verify.c
+++ b/lib/rsa/rsa-verify.c
@@ -570,7 +570,7 @@ int rsa_verify(struct image_sign_info *info,
uint8_t hash[info->crypto->key_len];
int ret;
-#ifdef USE_HOSTCC
+#if defined(USE_HOSTCC) && CONFIG_IS_ENABLED(LIBCRYPTO)
if (!info->fdt_blob)
return rsa_verify_openssl(info, region, region_count, sig, sig_len);
#endif
diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
index 9ca7933c094..5b21c57ae42 100644
--- a/lib/tpm-v2.c
+++ b/lib/tpm-v2.c
@@ -1141,7 +1141,7 @@ enum tpm2_algorithms tpm2_name_to_algorithm(const char *name)
}
printf("%s: unsupported algorithm %s\n", __func__, name);
- return -EINVAL;
+ return TPM2_ALG_INVAL;
}
const char *tpm2_algorithm_name(enum tpm2_algorithms algo)
diff --git a/lib/uuid.c b/lib/uuid.c
index 6abbcf27b1f..a1c88b9a622 100644
--- a/lib/uuid.c
+++ b/lib/uuid.c
@@ -62,184 +62,197 @@ int uuid_str_valid(const char *uuid)
return 1;
}
+/*
+ * Array of string (short and long) for known GUID of GPT partition type
+ * at least one string must be present, @type or @description
+ *
+ * @type : short name for the parameter 'type' of gpt command (max size UUID_STR_LEN = 36,
+ * no space), also used as fallback description when the next field is absent
+ * @description : long description associated to type GUID, used for %pUs
+ * @guid : known type GUID value
+ */
static const struct {
- const char *string;
+ const char *type;
+ const char *description;
efi_guid_t guid;
} list_guid[] = {
#ifndef USE_HOSTCC
-#if defined(CONFIG_PARTITION_TYPE_GUID) || defined(CONFIG_CMD_EFIDEBUG) || \
- defined(CONFIG_EFI)
- {"EFI System Partition", PARTITION_SYSTEM_GUID},
-#endif
-#ifdef CONFIG_PARTITION_TYPE_GUID
- {"mbr", LEGACY_MBR_PARTITION_GUID},
- {"msft", PARTITION_MSFT_RESERVED_GUID},
- {"data", PARTITION_BASIC_DATA_GUID},
- {"linux", PARTITION_LINUX_FILE_SYSTEM_DATA_GUID},
- {"raid", PARTITION_LINUX_RAID_GUID},
- {"swap", PARTITION_LINUX_SWAP_GUID},
- {"lvm", PARTITION_LINUX_LVM_GUID},
- {"u-boot-env", PARTITION_U_BOOT_ENVIRONMENT},
- {"cros-kern", PARTITION_CROS_KERNEL},
- {"cros-root", PARTITION_CROS_ROOT},
- {"cros-fw", PARTITION_CROS_FIRMWARE},
- {"cros-rsrv", PARTITION_CROS_RESERVED},
-#endif
+#if CONFIG_IS_ENABLED(EFI_PARTITION)
+ {"mbr", NULL, LEGACY_MBR_PARTITION_GUID},
+ {"msft", NULL, PARTITION_MSFT_RESERVED_GUID},
+ {"data", NULL, PARTITION_BASIC_DATA_GUID},
+ {"linux", NULL, PARTITION_LINUX_FILE_SYSTEM_DATA_GUID},
+ {"raid", NULL, PARTITION_LINUX_RAID_GUID},
+ {"swap", NULL, PARTITION_LINUX_SWAP_GUID},
+ {"lvm", NULL, PARTITION_LINUX_LVM_GUID},
+ {"u-boot-env", NULL, PARTITION_U_BOOT_ENVIRONMENT},
+ {"cros-kern", NULL, PARTITION_CROS_KERNEL},
+ {"cros-root", NULL, PARTITION_CROS_ROOT},
+ {"cros-fw", NULL, PARTITION_CROS_FIRMWARE},
+ {"cros-rsrv", NULL, PARTITION_CROS_RESERVED},
+ {
+ "system", "EFI System Partition",
+ PARTITION_SYSTEM_GUID,
+ },
#if defined(CONFIG_CMD_EFIDEBUG) || defined(CONFIG_EFI)
{
- "Device Path",
+ NULL, "Device Path",
+ PARTITION_SYSTEM_GUID,
+ },
+ {
+ NULL, "Device Path",
EFI_DEVICE_PATH_PROTOCOL_GUID,
},
{
- "Device Path To Text",
+ NULL, "Device Path To Text",
EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID,
},
{
- "Device Path Utilities",
+ NULL, "Device Path Utilities",
EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID,
},
{
- "Unicode Collation 2",
+ NULL, "Unicode Collation 2",
EFI_UNICODE_COLLATION_PROTOCOL2_GUID,
},
{
- "Driver Binding",
+ NULL, "Driver Binding",
EFI_DRIVER_BINDING_PROTOCOL_GUID,
},
{
- "Simple Text Input",
+ NULL, "Simple Text Input",
EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID,
},
{
- "Simple Text Input Ex",
+ NULL, "Simple Text Input Ex",
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID,
},
{
- "Simple Text Output",
+ NULL, "Simple Text Output",
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID,
},
{
- "Block IO",
+ NULL, "Block IO",
EFI_BLOCK_IO_PROTOCOL_GUID,
},
{
- "Disk IO",
+ NULL, "Disk IO",
EFI_DISK_IO_PROTOCOL_GUID,
},
{
- "Simple File System",
+ NULL, "Simple File System",
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID,
},
{
- "Loaded Image",
+ NULL, "Loaded Image",
EFI_LOADED_IMAGE_PROTOCOL_GUID,
},
{
- "Loaded Image Device Path",
+ NULL, "Loaded Image Device Path",
EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID,
},
{
- "Graphics Output",
+ NULL, "Graphics Output",
EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID,
},
{
- "HII String",
+ NULL, "HII String",
EFI_HII_STRING_PROTOCOL_GUID,
},
{
- "HII Database",
+ NULL, "HII Database",
EFI_HII_DATABASE_PROTOCOL_GUID,
},
{
- "HII Config Access",
+ NULL, "HII Config Access",
EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID,
},
{
- "HII Config Routing",
+ NULL, "HII Config Routing",
EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID,
},
{
- "Load File",
+ NULL, "Load File",
EFI_LOAD_FILE_PROTOCOL_GUID,
},
{
- "Load File2",
+ NULL, "Load File2",
EFI_LOAD_FILE2_PROTOCOL_GUID,
},
{
- "Random Number Generator",
+ NULL, "Random Number Generator",
EFI_RNG_PROTOCOL_GUID,
},
{
- "Simple Network",
+ NULL, "Simple Network",
EFI_SIMPLE_NETWORK_PROTOCOL_GUID,
},
{
- "PXE Base Code",
+ NULL, "PXE Base Code",
EFI_PXE_BASE_CODE_PROTOCOL_GUID,
},
{
- "Device-Tree Fixup",
+ NULL, "Device-Tree Fixup",
EFI_DT_FIXUP_PROTOCOL_GUID,
},
{
- "TCG2",
+ NULL, "TCG2",
EFI_TCG2_PROTOCOL_GUID,
},
{
- "Firmware Management",
+ NULL, "Firmware Management",
EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID
},
#if IS_ENABLED(CONFIG_EFI_HTTP_PROTOCOL)
{
- "HTTP",
+ NULL, "HTTP",
EFI_HTTP_PROTOCOL_GUID,
},
{
- "HTTP Service Binding",
+ NULL, "HTTP Service Binding",
EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID,
},
{
- "IPv4 Config2",
+ NULL, "IPv4 Config2",
EFI_IP4_CONFIG2_PROTOCOL_GUID,
},
#endif
/* Configuration table GUIDs */
{
- "ACPI table",
+ NULL, "ACPI table",
EFI_ACPI_TABLE_GUID,
},
{
- "EFI System Resource Table",
+ NULL, "EFI System Resource Table",
EFI_SYSTEM_RESOURCE_TABLE_GUID,
},
{
- "device tree",
+ NULL, "device tree",
EFI_FDT_GUID,
},
{
- "SMBIOS table",
+ NULL, "SMBIOS table",
SMBIOS_TABLE_GUID,
},
{
- "SMBIOS3 table",
+ NULL, "SMBIOS3 table",
SMBIOS3_TABLE_GUID,
},
{
- "Runtime properties",
+ NULL, "Runtime properties",
EFI_RT_PROPERTIES_TABLE_GUID,
},
{
- "TCG2 Final Events Table",
+ NULL, "TCG2 Final Events Table",
EFI_TCG2_FINAL_EVENTS_TABLE_GUID,
},
{
- "EFI Conformance Profiles Table",
+ NULL, "EFI Conformance Profiles Table",
EFI_CONFORMANCE_PROFILES_TABLE_GUID,
},
#ifdef CONFIG_EFI_RISCV_BOOT_PROTOCOL
{
- "RISC-V Boot",
+ NULL, "RISC-V Boot",
RISCV_EFI_BOOT_PROTOCOL_GUID,
},
#endif
@@ -247,35 +260,36 @@ static const struct {
#ifdef CONFIG_CMD_NVEDIT_EFI
/* signature database */
{
- "EFI_GLOBAL_VARIABLE_GUID",
+ "EFI_GLOBAL_VARIABLE_GUID", NULL,
EFI_GLOBAL_VARIABLE_GUID,
},
{
- "EFI_IMAGE_SECURITY_DATABASE_GUID",
+ "EFI_IMAGE_SECURITY_DATABASE_GUID", NULL,
EFI_IMAGE_SECURITY_DATABASE_GUID,
},
/* certificate types */
{
- "EFI_CERT_SHA256_GUID",
+ "EFI_CERT_SHA256_GUID", NULL,
EFI_CERT_SHA256_GUID,
},
{
- "EFI_CERT_X509_GUID",
+ "EFI_CERT_X509_GUID", NULL,
EFI_CERT_X509_GUID,
},
{
- "EFI_CERT_TYPE_PKCS7_GUID",
+ "EFI_CERT_TYPE_PKCS7_GUID", NULL,
EFI_CERT_TYPE_PKCS7_GUID,
},
#endif
#if defined(CONFIG_CMD_EFIDEBUG) || defined(CONFIG_EFI)
- { "EFI_LZMA_COMPRESSED", EFI_LZMA_COMPRESSED },
- { "EFI_DXE_SERVICES", EFI_DXE_SERVICES },
- { "EFI_HOB_LIST", EFI_HOB_LIST },
- { "EFI_MEMORY_TYPE", EFI_MEMORY_TYPE },
- { "EFI_MEM_STATUS_CODE_REC", EFI_MEM_STATUS_CODE_REC },
- { "EFI_GUID_EFI_ACPI1", EFI_GUID_EFI_ACPI1 },
+ { "EFI_LZMA_COMPRESSED", NULL, EFI_LZMA_COMPRESSED },
+ { "EFI_DXE_SERVICES", NULL, EFI_DXE_SERVICES },
+ { "EFI_HOB_LIST", NULL, EFI_HOB_LIST },
+ { "EFI_MEMORY_TYPE", NULL, EFI_MEMORY_TYPE },
+ { "EFI_MEM_STATUS_CODE_REC", NULL, EFI_MEM_STATUS_CODE_REC },
+ { "EFI_GUID_EFI_ACPI1", NULL, EFI_GUID_EFI_ACPI1 },
#endif
+#endif /* EFI_PARTITION */
#endif /* !USE_HOSTCC */
};
@@ -284,7 +298,8 @@ int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin)
int i;
for (i = 0; i < ARRAY_SIZE(list_guid); i++) {
- if (!strcmp(list_guid[i].string, guid_str)) {
+ if (list_guid[i].type &&
+ !strcmp(list_guid[i].type, guid_str)) {
memcpy(guid_bin, &list_guid[i].guid, 16);
return 0;
}
@@ -298,7 +313,9 @@ const char *uuid_guid_get_str(const unsigned char *guid_bin)
for (i = 0; i < ARRAY_SIZE(list_guid); i++) {
if (!memcmp(list_guid[i].guid.b, guid_bin, 16)) {
- return list_guid[i].string;
+ if (list_guid[i].description)
+ return list_guid[i].description;
+ return list_guid[i].type;
}
}
return NULL;
@@ -312,10 +329,9 @@ int uuid_str_to_bin(const char *uuid_str, unsigned char *uuid_bin,
uint64_t tmp64;
if (!uuid_str_valid(uuid_str)) {
-#ifdef CONFIG_PARTITION_TYPE_GUID
- if (!uuid_guid_get_bin(uuid_str, uuid_bin))
+ if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID) &&
+ !uuid_guid_get_bin(uuid_str, uuid_bin))
return 0;
-#endif
return -EINVAL;
}
diff --git a/net/bootp.c b/net/bootp.c
index f22921ed388..95d906e3b2d 100644
--- a/net/bootp.c
+++ b/net/bootp.c
@@ -545,14 +545,14 @@ static int dhcp_extended(u8 *e, int message_type, struct in_addr server_ip,
}
#endif
-#ifdef CONFIG_BOOTP_PXE_CLIENTARCH
- clientarch = CONFIG_BOOTP_PXE_CLIENTARCH;
+#ifdef CONFIG_DHCP_PXE_CLIENTARCH
+ clientarch = CONFIG_DHCP_PXE_CLIENTARCH;
#endif
if (env_get("bootp_arch"))
clientarch = env_get_ulong("bootp_arch", 16, clientarch);
- if (clientarch > 0) {
+ if (clientarch != 0xff) {
*e++ = 93; /* Client System Architecture */
*e++ = 2;
*e++ = (clientarch >> 8) & 0xff;
diff --git a/net/dhcpv6.c b/net/dhcpv6.c
index 0c2de75ba1d..5bf935cb6a3 100644
--- a/net/dhcpv6.c
+++ b/net/dhcpv6.c
@@ -128,7 +128,7 @@ static int dhcp6_add_option(int option_id, uchar *pkt)
break;
case DHCP6_OPTION_CLIENT_ARCH_TYPE:
client_arch_opt = (struct dhcp6_option_client_arch *)dhcp_option_start;
- client_arch_opt->arch_type[num_client_arch++] = htons(CONFIG_DHCP6_PXE_CLIENTARCH);
+ client_arch_opt->arch_type[num_client_arch++] = htons(CONFIG_DHCP_PXE_CLIENTARCH);
opt_len = sizeof(__be16) * num_client_arch;
break;
@@ -194,7 +194,7 @@ static void dhcp6_send_solicit_packet(void)
pkt += dhcp6_add_option(DHCP6_OPTION_ELAPSED_TIME, pkt);
pkt += dhcp6_add_option(DHCP6_OPTION_IA_NA, pkt);
pkt += dhcp6_add_option(DHCP6_OPTION_ORO, pkt);
- if (CONFIG_DHCP6_PXE_CLIENTARCH != 0xFF)
+ if (CONFIG_DHCP_PXE_CLIENTARCH != 0xFF)
pkt += dhcp6_add_option(DHCP6_OPTION_CLIENT_ARCH_TYPE, pkt);
pkt += dhcp6_add_option(DHCP6_OPTION_VENDOR_CLASS, pkt);
pkt += dhcp6_add_option(DHCP6_OPTION_NII, pkt);
@@ -244,7 +244,7 @@ static void dhcp6_send_request_packet(void)
memcpy(pkt, sm_params.server_uid.uid_ptr, sm_params.server_uid.uid_size);
pkt += sm_params.server_uid.uid_size;
}
- if (CONFIG_DHCP6_PXE_CLIENTARCH != 0xFF)
+ if (CONFIG_DHCP_PXE_CLIENTARCH != 0xFF)
pkt += dhcp6_add_option(DHCP6_OPTION_CLIENT_ARCH_TYPE, pkt);
pkt += dhcp6_add_option(DHCP6_OPTION_VENDOR_CLASS, pkt);
pkt += dhcp6_add_option(DHCP6_OPTION_NII, pkt);
diff --git a/net/lwip/Makefile b/net/lwip/Makefile
index 5df222589b8..97299d9b542 100644
--- a/net/lwip/Makefile
+++ b/net/lwip/Makefile
@@ -2,8 +2,6 @@ ccflags-y += -I$(srctree)/lib/lwip/lwip/src/include -I$(srctree)/lib/lwip/u-boot
obj-$(CONFIG_$(PHASE_)DM_ETH) += net-lwip.o
obj-$(CONFIG_CMD_DHCP) += dhcp.o
-obj-$(CONFIG_CMD_DNS) += dns.o
-obj-$(CONFIG_CMD_PING) += ping.o
obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o
obj-$(CONFIG_WGET) += wget.o
diff --git a/net/lwip/dhcp.c b/net/lwip/dhcp.c
index 043d2ab6e94..4c9cb0ecaa0 100644
--- a/net/lwip/dhcp.c
+++ b/net/lwip/dhcp.c
@@ -58,7 +58,6 @@ static int dhcp_loop(struct udevice *udev)
/* Wait for DHCP to complete */
do {
net_lwip_rx(udev, netif);
- sys_check_timeouts();
bound = dhcp_supplied_address(netif);
if (bound)
break;
diff --git a/net/lwip/eth_internal.h b/net/lwip/eth_internal.h
deleted file mode 100644
index 87561d5b214..00000000000
--- a/net/lwip/eth_internal.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * (C) Copyright 2001-2015
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- * Joe Hershberger, National Instruments
- */
-
-#ifndef __ETH_INTERNAL_H
-#define __ETH_INTERNAL_H
-
-/* Do init that is common to driver model and legacy networking */
-void eth_common_init(void);
-
-/**
- * eth_env_set_enetaddr_by_index() - set the MAC address environment variable
- *
- * This sets up an environment variable with the given MAC address (@enetaddr).
- * The environment variable to be set is defined by <@base_name><@index>addr.
- * If @index is 0 it is omitted. For common Ethernet this means ethaddr,
- * eth1addr, etc.
- *
- * @base_name: Base name for variable, typically "eth"
- * @index: Index of interface being updated (>=0)
- * @enetaddr: Pointer to MAC address to put into the variable
- * Return: 0 if OK, other value on error
- */
-int eth_env_set_enetaddr_by_index(const char *base_name, int index,
- uchar *enetaddr);
-
-int eth_mac_skip(int index);
-void eth_current_changed(void);
-void eth_set_dev(struct udevice *dev);
-void eth_set_current_to_next(void);
-
-#endif
diff --git a/net/lwip/net-lwip.c b/net/lwip/net-lwip.c
index abc52b32049..3918d57d7e5 100644
--- a/net/lwip/net-lwip.c
+++ b/net/lwip/net-lwip.c
@@ -7,15 +7,19 @@
#include <dm/device.h>
#include <dm/uclass.h>
#include <hexdump.h>
+#include <linux/kernel.h>
#include <lwip/ip4_addr.h>
+#include <lwip/dns.h>
#include <lwip/err.h>
#include <lwip/netif.h>
#include <lwip/pbuf.h>
#include <lwip/etharp.h>
#include <lwip/init.h>
#include <lwip/prot/etharp.h>
+#include <lwip/timeouts.h>
#include <net.h>
#include <timer.h>
+#include <u-boot/schedule.h>
/* xx:xx:xx:xx:xx:xx\0 */
#define MAC_ADDR_STRLEN 18
@@ -139,6 +143,40 @@ static int get_udev_ipv4_info(struct udevice *dev, ip4_addr_t *ip,
}
/*
+ * Initialize DNS via env
+ */
+int net_lwip_dns_init(void)
+{
+#if CONFIG_IS_ENABLED(CMD_DNS)
+ bool has_server = false;
+ ip_addr_t ns;
+ char *nsenv;
+
+ nsenv = env_get("dnsip");
+ if (nsenv && ipaddr_aton(nsenv, &ns)) {
+ dns_setserver(0, &ns);
+ has_server = true;
+ }
+
+ nsenv = env_get("dnsip2");
+ if (nsenv && ipaddr_aton(nsenv, &ns)) {
+ dns_setserver(1, &ns);
+ has_server = true;
+ }
+
+ if (!has_server) {
+ log_err("No valid name server (dnsip/dnsip2)\n");
+ return -EINVAL;
+ }
+
+ return 0;
+#else
+ log_err("DNS disabled\n");
+ return -EINVAL;
+#endif
+}
+
+/*
* Initialize the network stack if needed and start the current device if valid
*/
int net_lwip_eth_start(void)
@@ -285,6 +323,11 @@ int net_lwip_rx(struct udevice *udev, struct netif *netif)
int len;
int i;
+ /* lwIP timers */
+ sys_check_timeouts();
+ /* Other tasks and actions */
+ schedule();
+
if (!eth_is_active(udev))
return -EINVAL;
@@ -316,6 +359,44 @@ int net_lwip_rx(struct udevice *udev, struct netif *netif)
return len;
}
+/**
+ * net_lwip_dns_resolve() - find IP address from name or IP
+ *
+ * @name_or_ip: host name or IP address
+ * @ip: output IP address
+ *
+ * Return value: 0 on success, -1 on failure.
+ */
+int net_lwip_dns_resolve(char *name_or_ip, ip_addr_t *ip)
+{
+#if defined(CONFIG_CMD_DNS)
+ char *var = "_dnsres";
+ char *argv[] = { "dns", name_or_ip, var, NULL };
+ int argc = ARRAY_SIZE(argv) - 1;
+#endif
+
+ if (ipaddr_aton(name_or_ip, ip))
+ return 0;
+
+#if defined(CONFIG_CMD_DNS)
+ if (do_dns(NULL, 0, argc, argv) != CMD_RET_SUCCESS)
+ return -1;
+
+ name_or_ip = env_get(var);
+ if (!name_or_ip)
+ return -1;
+
+ if (!ipaddr_aton(name_or_ip, ip))
+ return -1;
+
+ env_set(var, NULL);
+
+ return 0;
+#else
+ return -1;
+#endif
+}
+
void net_process_received_packet(uchar *in_packet, int len)
{
#if defined(CONFIG_API) || defined(CONFIG_EFI_LOADER)
diff --git a/net/lwip/tftp.c b/net/lwip/tftp.c
index b7eb486ef77..94bacf63075 100644
--- a/net/lwip/tftp.c
+++ b/net/lwip/tftp.c
@@ -157,8 +157,10 @@ static void no_response(void *arg)
static int tftp_loop(struct udevice *udev, ulong addr, char *fname,
ip_addr_t srvip, uint16_t srvport)
{
+ int blksize = CONFIG_TFTP_BLOCKSIZE;
struct netif *netif;
struct tftp_ctx ctx;
+ const char *ep;
err_t err;
if (!fname || addr == 0)
@@ -187,7 +189,10 @@ static int tftp_loop(struct udevice *udev, ulong addr, char *fname,
if (!(err == ERR_OK || err == ERR_USE))
log_err("tftp_init_client err: %d\n", err);
- tftp_client_set_blksize(CONFIG_TFTP_BLOCKSIZE);
+ ep = env_get("tftpblocksize");
+ if (ep)
+ blksize = simple_strtol(ep, NULL, 10);
+ tftp_client_set_blksize(blksize);
ctx.start_time = get_timer(0);
err = tftp_get(&ctx, &srvip, srvport, fname, TFTP_MODE_OCTET);
@@ -201,7 +206,6 @@ static int tftp_loop(struct udevice *udev, ulong addr, char *fname,
sys_timeout(NO_RSP_TIMEOUT_MS, no_response, &ctx);
while (!ctx.done) {
net_lwip_rx(udev, netif);
- sys_check_timeouts();
if (ctrlc()) {
printf("\nAbort\n");
ctx.done = ABORTED;
diff --git a/net/lwip/wget.c b/net/lwip/wget.c
index f4fd9718285..55bd2b72e26 100644
--- a/net/lwip/wget.c
+++ b/net/lwip/wget.c
@@ -6,7 +6,6 @@
#include <display_options.h>
#include <efi_loader.h>
#include <env.h>
-#include <image.h>
#include <linux/kconfig.h>
#include <lwip/apps/http_client.h>
#include "lwip/altcp_tls.h"
@@ -138,72 +137,6 @@ static int parse_url(char *url, char *host, u16 *port, char **path,
return 0;
}
-/*
- * Legacy syntax support
- * Convert [<server_name_or_ip>:]filename into a URL if needed
- */
-static int parse_legacy_arg(char *arg, char *nurl, size_t rem)
-{
- char *p = nurl;
- size_t n;
- char *col = strchr(arg, ':');
- char *env;
- char *server;
- char *path;
-
- if (strstr(arg, "http") == arg) {
- n = snprintf(nurl, rem, "%s", arg);
- if (n < 0 || n > rem)
- return -1;
- return 0;
- }
-
- n = snprintf(p, rem, "%s", "http://");
- if (n < 0 || n > rem)
- return -1;
- p += n;
- rem -= n;
-
- if (col) {
- n = col - arg;
- server = arg;
- path = col + 1;
- } else {
- env = env_get("httpserverip");
- if (!env)
- env = env_get("serverip");
- if (!env) {
- log_err("error: httpserver/serverip has to be set\n");
- return -1;
- }
- n = strlen(env);
- server = env;
- path = arg;
- }
-
- if (rem < n)
- return -1;
- strncpy(p, server, n);
- p += n;
- rem -= n;
- if (rem < 1)
- return -1;
- *p = '/';
- p++;
- rem--;
- n = strlen(path);
- if (rem < n)
- return -1;
- strncpy(p, path, n);
- p += n;
- rem -= n;
- if (rem < 1)
- return -1;
- *p = '\0';
-
- return 0;
-}
-
/**
* store_block() - copy received data
*
@@ -338,94 +271,10 @@ static err_t httpc_headers_done_cb(httpc_state_t *connection, void *arg, struct
return ERR_OK;
}
-#if CONFIG_IS_ENABLED(WGET_HTTPS)
-enum auth_mode {
- AUTH_NONE,
- AUTH_OPTIONAL,
- AUTH_REQUIRED,
-};
-
-static char *cacert;
-static size_t cacert_size;
-static enum auth_mode cacert_auth_mode = AUTH_OPTIONAL;
-#endif
#if CONFIG_IS_ENABLED(WGET_CACERT)
-static int set_auth(enum auth_mode auth)
-{
- cacert_auth_mode = auth;
-
- return CMD_RET_SUCCESS;
-}
#endif
-#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT)
-extern const char builtin_cacert[];
-extern const size_t builtin_cacert_size;
-static bool cacert_initialized;
-#endif
-
-#if CONFIG_IS_ENABLED(WGET_CACERT) || CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT)
-static int _set_cacert(const void *addr, size_t sz)
-{
- mbedtls_x509_crt crt;
- void *p;
- int ret;
-
- if (cacert)
- free(cacert);
-
- if (!addr) {
- cacert = NULL;
- cacert_size = 0;
- return CMD_RET_SUCCESS;
- }
-
- p = malloc(sz);
- if (!p)
- return CMD_RET_FAILURE;
- cacert = p;
- cacert_size = sz;
-
- memcpy(cacert, (void *)addr, sz);
-
- mbedtls_x509_crt_init(&crt);
- ret = mbedtls_x509_crt_parse(&crt, cacert, cacert_size);
- if (ret) {
- if (!wget_info->silent)
- printf("Could not parse certificates (%d)\n", ret);
- free(cacert);
- cacert = NULL;
- cacert_size = 0;
- return CMD_RET_FAILURE;
- }
-
-#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT)
- cacert_initialized = true;
-#endif
- return CMD_RET_SUCCESS;
-}
-
-#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT)
-static int set_cacert_builtin(void)
-{
- return _set_cacert(builtin_cacert, builtin_cacert_size);
-}
-#endif
-
-#if CONFIG_IS_ENABLED(WGET_CACERT)
-static int set_cacert(char * const saddr, char * const ssz)
-{
- ulong addr, sz;
-
- addr = hextoul(saddr, NULL);
- sz = hextoul(ssz, NULL);
-
- return _set_cacert((void *)addr, sz);
-}
-#endif
-#endif /* CONFIG_WGET_CACERT || CONFIG_WGET_BUILTIN_CACERT */
-
int wget_do_request(ulong dst_addr, char *uri)
{
#if CONFIG_IS_ENABLED(WGET_HTTPS)
@@ -461,12 +310,17 @@ int wget_do_request(ulong dst_addr, char *uri)
if (!netif)
return -1;
+ /* if URL with hostname init dns */
+ if (!ipaddr_aton(ctx.server_name, NULL) && net_lwip_dns_init())
+ return CMD_RET_FAILURE;
+
memset(&conn, 0, sizeof(conn));
#if CONFIG_IS_ENABLED(WGET_HTTPS)
if (is_https) {
char *ca;
size_t ca_sz;
+#if CONFIG_IS_ENABLED(WGET_CACERT) || CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT)
#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT)
if (!cacert_initialized)
set_cacert_builtin();
@@ -493,7 +347,7 @@ int wget_do_request(ulong dst_addr, char *uri)
* with no verification if not.
*/
}
-
+#endif
if (!ca && !wget_info->silent) {
printf("WARNING: no CA certificates, ");
printf("HTTPS connections not authenticated\n");
@@ -526,7 +380,6 @@ int wget_do_request(ulong dst_addr, char *uri)
while (!ctx.done) {
net_lwip_rx(udev, netif);
- sys_check_timeouts();
if (ctrlc())
break;
}
@@ -542,54 +395,6 @@ int wget_do_request(ulong dst_addr, char *uri)
return -1;
}
-int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
-{
- char *end;
- char *url;
- ulong dst_addr;
- char nurl[1024];
-
-#if CONFIG_IS_ENABLED(WGET_CACERT)
- if (argc == 4 && !strncmp(argv[1], "cacert", strlen("cacert")))
- return set_cacert(argv[2], argv[3]);
- if (argc == 3 && !strncmp(argv[1], "cacert", strlen("cacert"))) {
-#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT)
- if (!strncmp(argv[2], "builtin", strlen("builtin")))
- return set_cacert_builtin();
-#endif
- if (!strncmp(argv[2], "none", strlen("none")))
- return set_auth(AUTH_NONE);
- if (!strncmp(argv[2], "optional", strlen("optional")))
- return set_auth(AUTH_OPTIONAL);
- if (!strncmp(argv[2], "required", strlen("required")))
- return set_auth(AUTH_REQUIRED);
- return CMD_RET_USAGE;
- }
-#endif
-
- if (argc < 2 || argc > 3)
- return CMD_RET_USAGE;
-
- dst_addr = hextoul(argv[1], &end);
- if (end == (argv[1] + strlen(argv[1]))) {
- if (argc < 3)
- return CMD_RET_USAGE;
- url = argv[2];
- } else {
- dst_addr = image_load_addr;
- url = argv[1];
- }
-
- if (parse_legacy_arg(url, nurl, sizeof(nurl)))
- return CMD_RET_FAILURE;
-
- wget_info = &default_wget_info;
- if (wget_do_request(dst_addr, nurl))
- return CMD_RET_FAILURE;
-
- return CMD_RET_SUCCESS;
-}
-
/**
* wget_validate_uri() - validate the uri for wget
*
diff --git a/net/net-common.c b/net/net-common.c
index e01b0da7d7b..b064557d524 100644
--- a/net/net-common.c
+++ b/net/net-common.c
@@ -1,5 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
+
+#include <dm/uclass.h>
#include <net-common.h>
+#include <linux/time.h>
+#include <rtc.h>
void copy_filename(char *dst, const char *src, int size)
{
@@ -25,3 +29,22 @@ int wget_request(ulong dst_addr, char *uri, struct wget_http_info *info)
wget_info = info ? info : &default_wget_info;
return wget_do_request(dst_addr, uri);
}
+
+void net_sntp_set_rtc(u32 seconds)
+{
+ struct rtc_time tm;
+ struct udevice *dev;
+ int ret;
+
+ rtc_to_tm(seconds, &tm);
+
+ ret = uclass_get_device(UCLASS_RTC, 0, &dev);
+ if (ret)
+ printf("SNTP: cannot find RTC: err=%d\n", ret);
+ else
+ dm_rtc_set(dev, &tm);
+
+ printf("Date: %4d-%02d-%02d Time: %2d:%02d:%02d\n",
+ tm.tm_year, tm.tm_mon, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+}
diff --git a/net/sntp.c b/net/sntp.c
index 73d1d87d38b..77cee0046bd 100644
--- a/net/sntp.c
+++ b/net/sntp.c
@@ -57,8 +57,7 @@ static void sntp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
unsigned src, unsigned len)
{
struct sntp_pkt_t *rpktp = (struct sntp_pkt_t *)pkt;
- struct rtc_time tm;
- ulong seconds;
+ u32 seconds;
debug("%s\n", __func__);
@@ -69,24 +68,8 @@ static void sntp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
* As the RTC's used in U-Boot support second resolution only
* we simply ignore the sub-second field.
*/
- memcpy(&seconds, &rpktp->transmit_timestamp, sizeof(ulong));
-
- rtc_to_tm(ntohl(seconds) - 2208988800UL + net_ntp_time_offset, &tm);
-#ifdef CONFIG_DM_RTC
- struct udevice *dev;
- int ret;
-
- ret = uclass_get_device(UCLASS_RTC, 0, &dev);
- if (ret)
- printf("SNTP: cannot find RTC: err=%d\n", ret);
- else
- dm_rtc_set(dev, &tm);
-#elif defined(CONFIG_CMD_DATE)
- rtc_set(&tm);
-#endif
- printf("Date: %4d-%02d-%02d Time: %2d:%02d:%02d\n",
- tm.tm_year, tm.tm_mon, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec);
+ memcpy(&seconds, &rpktp->transmit_timestamp, sizeof(seconds));
+ net_sntp_set_rtc(ntohl(seconds) - 2208988800UL + net_ntp_time_offset);
net_set_state(NETLOOP_SUCCESS);
}
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index aa48d249433..998679f00a0 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -76,10 +76,12 @@ endif
ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),)
lib-target := $(obj)/lib.a
+# Modified for U-Boot
+# real-obj-y += $(obj)/lib-ksyms.o
endif
-ifneq ($(strip $(obj-y) $(obj-m) $(obj-) $(subdir-m) $(lib-target)),)
-builtin-target := $(obj)/built-in.o
+ifneq ($(strip $(real-obj-y) $(need-builtin)),)
+builtin-target := $(obj)/built-in.a
endif
ifdef CONFIG_MODULES
@@ -102,7 +104,11 @@ else ifeq ($(KBUILD_CHECKSRC),2)
cmd_force_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $<
endif
-# Do section mismatch analysis for each module/built-in.o
+ifneq ($(KBUILD_ENABLE_EXTRA_GCC_CHECKS),)
+ cmd_checkdoc = $(srctree)/scripts/kernel-doc -none $<
+endif
+
+# Do section mismatch analysis for each module/built-in.a
ifdef CONFIG_DEBUG_SECTION_MISMATCH
cmd_secanalysis = ; scripts/mod/modpost $@
endif
@@ -111,101 +117,94 @@ endif
# ---------------------------------------------------------------------------
# Default is built-in, unless we know otherwise
+$(foreach x, i ll lst o s symtypes, $(patsubst %.o,%.$(x),$(real-obj-m))): \
+ part-of-module := y
+
modkern_cflags = \
$(if $(part-of-module), \
$(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \
$(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL))
quiet_modtag = $(if $(part-of-module),[M], )
-$(real-objs-m) : part-of-module := y
-$(real-objs-m:.o=.i) : part-of-module := y
-$(real-objs-m:.o=.s) : part-of-module := y
-$(real-objs-m:.o=.lst): part-of-module := y
-
-# Default for not multi-part modules
-modname = $(basetarget)
-
-$(multi-objs-m) : modname = $(modname-multi)
-$(multi-objs-m:.o=.i) : modname = $(modname-multi)
-$(multi-objs-m:.o=.s) : modname = $(modname-multi)
-$(multi-objs-m:.o=.lst) : modname = $(modname-multi)
-$(multi-objs-y) : modname = $(modname-multi)
-$(multi-objs-y:.o=.i) : modname = $(modname-multi)
-$(multi-objs-y:.o=.s) : modname = $(modname-multi)
-$(multi-objs-y:.o=.lst) : modname = $(modname-multi)
-
quiet_cmd_cc_s_c = CC $(quiet_modtag) $@
-cmd_cc_s_c = $(CC) $(c_flags) $(DISABLE_LTO) -fverbose-asm -S -o $@ $<
+ cmd_cc_s_c = $(CC) $(filter-out $(DEBUG_CFLAGS), $(c_flags)) $(DISABLE_LTO) -fverbose-asm -S -o $@ $<
$(obj)/%.s: $(src)/%.c FORCE
$(call if_changed_dep,cc_s_c)
-quiet_cmd_cc_i_c = CPP $(quiet_modtag) $@
-cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $<
+quiet_cmd_cpp_i_c = CPP $(quiet_modtag) $@
+cmd_cpp_i_c = $(CPP) $(c_flags) -o $@ $<
$(obj)/%.i: $(src)/%.c FORCE
- $(call if_changed_dep,cc_i_c)
+ $(call if_changed_dep,cpp_i_c)
-cmd_gensymtypes = \
+# These mirror gensymtypes_S and co below, keep them in synch.
+cmd_gensymtypes_c = \
$(CPP) -D__GENKSYMS__ $(c_flags) $< | \
- scripts/genksyms/genksyms $(if $(1), -T $(2)) \
+ scripts/genksyms/genksyms $(if $(1), -T $(2)) \
+ $(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \
$(if $(KBUILD_PRESERVE),-p) \
-r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
cmd_cc_symtypes_c = \
- $(call cmd_gensymtypes,true,$@) >/dev/null; \
+ $(call cmd_gensymtypes_c,true,$@) >/dev/null; \
test -s $@ || rm -f $@
$(obj)/%.symtypes : $(src)/%.c FORCE
$(call cmd,cc_symtypes_c)
+# LLVM assembly
+# Generate .ll files from .c
+quiet_cmd_cc_ll_c = CC $(quiet_modtag) $@
+ cmd_cc_ll_c = $(CC) $(c_flags) -emit-llvm -S -o $@ $<
+
+$(obj)/%.ll: $(src)/%.c FORCE
+ $(call if_changed_dep,cc_ll_c)
+
# C (.c) files
# The C file is compiled and updated dependency information is generated.
# (See cmd_cc_o_c + relevant part of rule_cc_o_c)
quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
-cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
+ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
ifdef CONFIG_MODVERSIONS
# When module versioning is enabled the following steps are executed:
# o compile a <file>.o from <file>.c
# o if <file>.o doesn't contain a __ksymtab version, i.e. does
-# not export symbols, it's done
+# not export symbols, it's done.
# o otherwise, we calculate symbol versions using the good old
# genksyms on the preprocessed source and postprocess them in a way
# that they are usable as a linker script
# o generate .tmp_<file>.o from <file>.o using the linker to
# replace the unresolved symbols __crc_exported_symbol with
# the actual value of the checksum generated by genksyms
-
# o remove .tmp_<file>.o to <file>.o
-cmd_modversions = \
+
+cmd_modversions_c = \
if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \
- $(call cmd_gensymtypes,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
+ $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
> $(@D)/.tmp_$(@F:.o=.ver); \
\
- $(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \
+ $(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \
-T $(@D)/.tmp_$(@F:.o=.ver); \
mv -f $(@D)/.tmp_$(@F) $@; \
rm -f $(@D)/.tmp_$(@F:.o=.ver); \
- fi;
+ fi
endif
ifdef CONFIG_FTRACE_MCOUNT_RECORD
-# gcc 5 supports generating the mcount tables directly
-ifneq ($(call cc-option,-mrecord-mcount,y),y)
-KBUILD_CFLAGS += -mrecord-mcount
-else
-# else do it all manually
+ifndef CC_USING_RECORD_MCOUNT
+# compiler will not generate __mcount_loc use recordmcount or recordmcount.pl
ifdef BUILD_C_RECORDMCOUNT
ifeq ("$(origin RECORDMCOUNT_WARN)", "command line")
RECORDMCOUNT_FLAGS = -w
endif
# Due to recursion, we must skip empty.o.
# The empty.o file is created in the make process in order to determine
-# the target endianness and word size. It is made before all other C
-# files, including recordmcount.
+# the target endianness and word size. It is made before all other C
+# files, including recordmcount.
sub_cmd_record_mcount = \
if [ $(@) != "scripts/mod/empty.o" ]; then \
$(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)"; \
@@ -213,17 +212,59 @@ sub_cmd_record_mcount = \
recordmcount_source := $(srctree)/scripts/recordmcount.c \
$(srctree)/scripts/recordmcount.h
else
-sub_cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
+sub_cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
"$(if $(CONFIG_SYS_BIG_ENDIAN),big,little)" \
"$(if $(CONFIG_64BIT),64,32)" \
"$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)" \
"$(LD) $(KBUILD_LDFLAGS)" "$(NM)" "$(RM)" "$(MV)" \
"$(if $(part-of-module),1,0)" "$(@)";
recordmcount_source := $(srctree)/scripts/recordmcount.pl
+endif # BUILD_C_RECORDMCOUNT
+cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)), \
+ $(sub_cmd_record_mcount))
+endif # CC_USING_RECORD_MCOUNT
+endif # CONFIG_FTRACE_MCOUNT_RECORD
+
+ifdef CONFIG_STACK_VALIDATION
+ifneq ($(SKIP_STACK_VALIDATION),1)
+
+__objtool_obj := $(objtree)/tools/objtool/objtool
+
+objtool_args = $(if $(CONFIG_UNWINDER_ORC),orc generate,check)
+
+objtool_args += $(if $(part-of-module), --module,)
+
+ifndef CONFIG_FRAME_POINTER
+objtool_args += --no-fp
endif
-cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)), \
- $(sub_cmd_record_mcount))
-endif # -record-mcount
+ifdef CONFIG_GCOV_KERNEL
+objtool_args += --no-unreachable
+endif
+ifdef CONFIG_RETPOLINE
+ objtool_args += --retpoline
+endif
+
+# 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory
+# 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file
+# 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file
+cmd_objtool = $(if $(patsubst y%,, \
+ $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n), \
+ $(__objtool_obj) $(objtool_args) $@)
+objtool_obj = $(if $(patsubst y%,, \
+ $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n), \
+ $(__objtool_obj))
+
+endif # SKIP_STACK_VALIDATION
+endif # CONFIG_STACK_VALIDATION
+
+# Rebuild all objects when objtool changes, or is enabled/disabled.
+objtool_dep = $(objtool_obj) \
+ $(wildcard include/config/orc/unwinder.h \
+ include/config/stack/validation.h)
+
+ifdef CONFIG_TRIM_UNUSED_KSYMS
+cmd_gen_ksymdeps = \
+ $(CONFIG_SHELL) $(srctree)/scripts/gen_ksymdeps.sh $@ >> $(dot-target).cmd
endif
define rule_cc_o_c
@@ -243,17 +284,25 @@ define rule_as_o_S
$(call cmd,modversions_S)
endef
+# List module undefined symbols (or empty line if not enabled)
+ifdef CONFIG_TRIM_UNUSED_KSYMS
+cmd_undef_syms = $(NM) $@ | sed -n 's/^ *U //p' | xargs echo
+else
+cmd_undef_syms = echo
+endif
+
# Built-in and composite module parts
-$(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE
+$(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE
$(call cmd,force_checksrc)
$(call if_changed_rule,cc_o_c)
# Single-part modules are special since we need to mark them in $(MODVERDIR)
-$(single-used-m): $(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE
+$(single-used-m): $(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE
$(call cmd,force_checksrc)
$(call if_changed_rule,cc_o_c)
- @{ echo $(@:.o=.ko); echo $@; } > $(MODVERDIR)/$(@F:.o=.mod)
+ @{ echo $(@:.o=.ko); echo $@; \
+ $(cmd_undef_syms); } > $(MODVERDIR)/$(@F:.o=.mod)
quiet_cmd_cc_lst_c = MKLST $@
cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \
@@ -268,29 +317,83 @@ $(obj)/%.lst: $(src)/%.c FORCE
modkern_aflags := $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)
-$(real-objs-m) : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
-$(real-objs-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
+$(real-obj-m) : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
+$(real-obj-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
+
+# .S file exports must have their C prototypes defined in asm/asm-prototypes.h
+# or a file that it includes, in order to get versioned symbols. We build a
+# dummy C file that includes asm-prototypes and the EXPORT_SYMBOL lines from
+# the .S file (with trailing ';'), and run genksyms on that, to extract vers.
+#
+# This is convoluted. The .S file must first be preprocessed to run guards and
+# expand names, then the resulting exports must be constructed into plain
+# EXPORT_SYMBOL(symbol); to build our dummy C file, and that gets preprocessed
+# to make the genksyms input.
+#
+# These mirror gensymtypes_c and co above, keep them in synch.
+cmd_gensymtypes_S = \
+ { echo "\#include <linux/kernel.h>" ; \
+ echo "\#include <asm/asm-prototypes.h>" ; \
+ $(CPP) $(a_flags) $< | \
+ grep "\<___EXPORT_SYMBOL\>" | \
+ sed 's/.*___EXPORT_SYMBOL[[:space:]]*\([a-zA-Z0-9_]*\)[[:space:]]*,.*/EXPORT_SYMBOL(\1);/' ; } | \
+ $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | \
+ scripts/genksyms/genksyms $(if $(1), -T $(2)) \
+ $(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \
+ $(if $(KBUILD_PRESERVE),-p) \
+ -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
+
+quiet_cmd_cc_symtypes_S = SYM $(quiet_modtag) $@
+cmd_cc_symtypes_S = \
+ $(call cmd_gensymtypes_S,true,$@) >/dev/null; \
+ test -s $@ || rm -f $@
-quiet_cmd_as_s_S = CPP $(quiet_modtag) $@
-cmd_as_s_S = $(CPP) $(a_flags) -o $@ $<
+$(obj)/%.symtypes : $(src)/%.S FORCE
+ $(call cmd,cc_symtypes_S)
+
+
+quiet_cmd_cpp_s_S = CPP $(quiet_modtag) $@
+cmd_cpp_s_S = $(CPP) $(a_flags) -o $@ $<
$(obj)/%.s: $(src)/%.S FORCE
- $(call if_changed_dep,as_s_S)
+ $(call if_changed_dep,cpp_s_S)
quiet_cmd_as_o_S = AS $(quiet_modtag) $@
-cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $<
+ cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $<
+
+ifdef CONFIG_MODVERSIONS
+
+ASM_PROTOTYPES := $(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/asm-prototypes.h)
-$(obj)/%.o: $(src)/%.S FORCE
- $(call if_changed_dep,as_o_S)
+ifneq ($(ASM_PROTOTYPES),)
-targets += $(real-objs-y) $(real-objs-m) $(lib-y)
+# versioning matches the C process described above, with difference that
+# we parse asm-prototypes.h C header to get function definitions.
+
+cmd_modversions_S = \
+ if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \
+ $(call cmd_gensymtypes_S,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
+ > $(@D)/.tmp_$(@F:.o=.ver); \
+ \
+ $(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \
+ -T $(@D)/.tmp_$(@F:.o=.ver); \
+ mv -f $(@D)/.tmp_$(@F) $@; \
+ rm -f $(@D)/.tmp_$(@F:.o=.ver); \
+ fi
+endif
+endif
+
+$(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE
+ $(call if_changed_rule,as_o_S)
+
+targets += $(filter-out $(subdir-obj-y), $(real-obj-y)) $(real-obj-m) $(lib-y)
targets += $(extra-y) $(MAKECMDGOALS) $(always)
targets += $(real-dtb-y) $(lib-y) $(always-y)
# Linker scripts preprocessor (.lds.S -> .lds)
# ---------------------------------------------------------------------------
quiet_cmd_cpp_lds_S = LDS $@
- cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -C -U$(ARCH) \
+ cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -U$(ARCH) \
-D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $<
$(obj)/%.lds: $(src)/%.lds.S FORCE
@@ -312,17 +415,17 @@ $(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/tools/asn1_compiler
$(sort $(subdir-obj-y)): $(subdir-ym) ;
#
-# Rule to compile a set of .o files into one .o file
+# Rule to compile a set of .o files into one .a file (without symbol table)
#
ifdef builtin-target
-quiet_cmd_link_o_target = AR $@
-# If the list of objects to link is empty, just create an empty built-in.o
-cmd_link_o_target = $(if $(strip $(obj-y)),\
- rm -f $@; $(AR) cDPrsT $@ $(filter $(obj-y), $^), \
- rm -f $@; $(AR) cDPrsT$(KBUILD_ARFLAGS) $@)
-$(builtin-target): $(obj-y) FORCE
- $(call if_changed,link_o_target)
+quiet_cmd_ar_builtin = AR $@
+# Modified for U-Boot, we create thin archives directly, instead of using the kernel script
+# Check f49821ee32b76 and 6358d6e8b98 in kernel
+ cmd_ar_builtin = rm -f $@; $(AR) rcTP$(KBUILD_ARFLAGS) $@ $(real-prereqs)
+
+$(builtin-target): $(real-obj-y) FORCE
+ $(call if_changed,ar_builtin)
targets += $(builtin-target)
endif # builtin-target
@@ -341,7 +444,7 @@ $(modorder-target): $(subdir-ym) FORCE
$(Q)(cat /dev/null; $(modorder-cmds)) > $@
#
-# Rule to compile a set of .o files into one .a file
+# Rule to compile a set of .o files into one .a file (with symbol table)
#
ifdef lib-target
@@ -349,25 +452,40 @@ $(lib-target): $(lib-y) FORCE
$(call if_changed,ar)
targets += $(lib-target)
-endif
-quiet_cmd_link_multi-y = AR $@
-cmd_link_multi-y = rm -f $@; $(AR) cDPrsT$(KBUILD_ARFLAGS) $@ $(filter %.o,$^)
+dummy-object = $(obj)/.lib_exports.o
+ksyms-lds = $(dot-target).lds
+
+quiet_cmd_export_list = EXPORTS $@
+cmd_export_list = $(OBJDUMP) -h $< | \
+ sed -ne '/___ksymtab/s/.*+\([^ ]*\).*/EXTERN(\1)/p' >$(ksyms-lds);\
+ rm -f $(dummy-object);\
+ echo | $(CC) $(a_flags) -c -o $(dummy-object) -x assembler -;\
+ $(LD) $(ld_flags) -r -o $@ -T $(ksyms-lds) $(dummy-object);\
+ rm $(dummy-object) $(ksyms-lds)
+
+$(obj)/lib-ksyms.o: $(lib-target) FORCE
+ $(call if_changed,export_list)
-quiet_cmd_link_multi-m = AR [M] $@
-cmd_link_multi-m = $(cmd_link_multi-y)
+targets += $(obj)/lib-ksyms.o
-$(multi-used-y): FORCE
- $(call if_changed,link_multi-y)
-$(call multi_depend, $(multi-used-y), .o, -objs -y)
+endif
+
+# NOTE:
+# Do not replace $(filter %.o,^) with $(real-prereqs). When a single object
+# module is turned into a multi object module, $^ will contain header file
+# dependencies recorded in the .*.cmd file.
+quiet_cmd_link_multi-m = LD [M] $@
+cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ $(filter %.o,$^) $(cmd_secanalysis)
$(multi-used-m): FORCE
$(call if_changed,link_multi-m)
- @{ echo $(@:.o=.ko); echo $(filter %.o,$^); } > $(MODVERDIR)/$(@F:.o=.mod)
-$(call multi_depend, $(multi-used-m), .o, -objs -y)
-
-targets += $(multi-used-y) $(multi-used-m)
+ @{ echo $(@:.o=.ko); echo $(filter %.o,$^); \
+ $(cmd_undef_syms); } > $(MODVERDIR)/$(@F:.o=.mod)
+$(call multi_depend, $(multi-used-m), .o, -objs -y -m)
+targets += $(multi-used-m)
+targets := $(filter-out $(PHONY), $(targets))
# Add intermediate targets:
# When building objects with specific suffix patterns, add intermediate
@@ -375,9 +493,13 @@ targets += $(multi-used-y) $(multi-used-m)
intermediate_targets = $(foreach sfx, $(2), \
$(patsubst %$(strip $(1)),%$(sfx), \
$(filter %$(strip $(1)), $(targets))))
+# %.asn1.o <- %.asn1.[ch] <- %.asn1
+# %.dtb.o <- %.dtb.S <- %.dtb <- %.dts
# %.lex.o <- %.lex.c <- %.l
# %.tab.o <- %.tab.[ch] <- %.y
-targets += $(call intermediate_targets, .lex.o, .lex.c) \
+targets += $(call intermediate_targets, .asn1.o, .asn1.c .asn1.h) \
+ $(call intermediate_targets, .dtb.o, .dtb.S .dtb) \
+ $(call intermediate_targets, .lex.o, .lex.c) \
$(call intermediate_targets, .tab.o, .tab.c .tab.h)
# Descending
@@ -385,7 +507,7 @@ targets += $(call intermediate_targets, .lex.o, .lex.c) \
PHONY += $(subdir-ym)
$(subdir-ym):
- $(Q)$(MAKE) $(build)=$@
+ $(Q)$(MAKE) $(build)=$@ need-builtin=$(if $(findstring $@,$(subdir-obj-y)),1)
# Add FORCE to the prequisites of a target to force it to be always rebuilt.
# ---------------------------------------------------------------------------
diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
index f687515fc79..7df62263bc4 100644
--- a/scripts/Makefile.extrawarn
+++ b/scripts/Makefile.extrawarn
@@ -67,5 +67,14 @@ ifeq ("$(strip $(warning))","")
endif
KBUILD_CFLAGS += $(warning)
+else
+ifdef CONFIG_CC_IS_CLANG
+KBUILD_CFLAGS += $(call cc-disable-warning, initializer-overrides)
+KBUILD_CFLAGS += $(call cc-disable-warning, unused-value)
+KBUILD_CFLAGS += $(call cc-disable-warning, format)
+KBUILD_CFLAGS += $(call cc-disable-warning, sign-compare)
+KBUILD_CFLAGS += $(call cc-disable-warning, format-zero-length)
+KBUILD_CFLAGS += $(call cc-disable-warning, uninitialized)
+endif
endif
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
new file mode 100644
index 00000000000..5f7df50cfe7
--- /dev/null
+++ b/scripts/Makefile.gcc-plugins
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: GPL-2.0
+
+gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) += cyc_complexity_plugin.so
+
+gcc-plugin-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) += latent_entropy_plugin.so
+gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) \
+ += -DLATENT_ENTROPY_PLUGIN
+ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
+ DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable
+endif
+export DISABLE_LATENT_ENTROPY_PLUGIN
+
+gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV) += sancov_plugin.so
+
+gcc-plugin-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += structleak_plugin.so
+gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE) \
+ += -fplugin-arg-structleak_plugin-verbose
+gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF) \
+ += -fplugin-arg-structleak_plugin-byref
+gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL) \
+ += -fplugin-arg-structleak_plugin-byref-all
+gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) \
+ += -DSTRUCTLEAK_PLUGIN
+
+gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so
+gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) \
+ += -DRANDSTRUCT_PLUGIN
+gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE) \
+ += -fplugin-arg-randomize_layout_plugin-performance-mode
+
+gcc-plugin-$(CONFIG_GCC_PLUGIN_STACKLEAK) += stackleak_plugin.so
+gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \
+ += -DSTACKLEAK_PLUGIN
+gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \
+ += -fplugin-arg-stackleak_plugin-track-min-size=$(CONFIG_STACKLEAK_TRACK_MIN_SIZE)
+ifdef CONFIG_GCC_PLUGIN_STACKLEAK
+ DISABLE_STACKLEAK_PLUGIN += -fplugin-arg-stackleak_plugin-disable
+endif
+export DISABLE_STACKLEAK_PLUGIN
+
+gcc-plugin-$(CONFIG_GCC_PLUGIN_ARM_SSP_PER_TASK) += arm_ssp_per_task_plugin.so
+ifdef CONFIG_GCC_PLUGIN_ARM_SSP_PER_TASK
+ DISABLE_ARM_SSP_PER_TASK_PLUGIN += -fplugin-arg-arm_ssp_per_task_plugin-disable
+endif
+export DISABLE_ARM_SSP_PER_TASK_PLUGIN
+
+# All the plugin CFLAGS are collected here in case a build target needs to
+# filter them out of the KBUILD_CFLAGS.
+GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y))
+# The sancov_plugin.so is included via CFLAGS_KCOV, so it is removed here.
+GCC_PLUGINS_CFLAGS := $(filter-out %/sancov_plugin.so, $(GCC_PLUGINS_CFLAGS))
+export GCC_PLUGINS_CFLAGS
+
+# Add the flags to the build!
+KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
+
+# All enabled GCC plugins are collected here for building below.
+GCC_PLUGIN := $(gcc-plugin-y)
+export GCC_PLUGIN
diff --git a/scripts/Makefile.kcov b/scripts/Makefile.kcov
new file mode 100644
index 00000000000..3d61c4bfcbe
--- /dev/null
+++ b/scripts/Makefile.kcov
@@ -0,0 +1,9 @@
+ifdef CONFIG_KCOV
+
+kcov-flags-$(CONFIG_CC_HAS_SANCOV_TRACE_PC) += -fsanitize-coverage=trace-pc
+kcov-flags-$(CONFIG_KCOV_ENABLE_COMPARISONS) += -fsanitize-coverage=trace-cmp
+kcov-flags-$(CONFIG_GCC_PLUGIN_SANCOV) += -fplugin=$(objtree)/scripts/gcc-plugins/sancov_plugin.so
+
+export CFLAGS_KCOV := $(kcov-flags-y)
+
+endif
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 19a5be57495..5db2fbc418a 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -5,46 +5,40 @@ ccflags-y += $(EXTRA_CFLAGS)
cppflags-y += $(EXTRA_CPPFLAGS)
ldflags-y += $(EXTRA_LDFLAGS)
-#
-# flags that take effect in sub directories
-export KBUILD_SUBDIR_ASFLAGS := $(KBUILD_SUBDIR_ASFLAGS) $(subdir-asflags-y)
-export KBUILD_SUBDIR_CCFLAGS := $(KBUILD_SUBDIR_CCFLAGS) $(subdir-ccflags-y)
+# flags that take effect in current and sub directories
+KBUILD_AFLAGS += $(subdir-asflags-y)
+KBUILD_CFLAGS += $(subdir-ccflags-y)
# Figure out what we need to build from the various variables
# ===========================================================================
# When an object is listed to be built compiled-in and modular,
# only build the compiled-in version
-
obj-m := $(filter-out $(obj-y),$(obj-m))
# Libraries are always collected in one lib file.
# Filter out objects already built-in
-
lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m)))
+# Determine modorder.
+# Unfortunately, we don't have information about ordering between -y
+# and -m subdirs. Just put -y's first.
+modorder := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m:.o=.ko))
# Handle objects in subdirs
# ---------------------------------------------------------------------------
-# o if we encounter foo/ in $(obj-y), replace it by foo/built-in.o
+# o if we encounter foo/ in $(obj-y), replace it by foo/built-in.a
# and add the directory to the list of dirs to descend into: $(subdir-y)
# o if we encounter foo/ in $(obj-m), remove it from $(obj-m)
# and add the directory to the list of dirs to descend into: $(subdir-m)
-
-# Determine modorder.
-# Unfortunately, we don't have information about ordering between -y
-# and -m subdirs. Just put -y's first.
-modorder := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m:.o=.ko))
-
__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
subdir-y += $(__subdir-y)
__subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m)))
subdir-m += $(__subdir-m)
-obj-y := $(patsubst %/, %/built-in.o, $(obj-y))
+obj-y := $(patsubst %/, %/built-in.a, $(obj-y))
obj-m := $(filter-out %/, $(obj-m))
# Subdirectories we need to descend into
-
subdir-ym := $(sort $(subdir-y) $(subdir-m))
# Expand $(foo-objs) $(foo-y) etc. by replacing their individuals
@@ -54,9 +48,9 @@ multi-search = $(sort $(foreach m, $1, $(if $(call suffix-search, $m, $2, $3 -),
# List primitive targets that are compiled from source files
real-search = $(foreach m, $1, $(if $(call suffix-search, $m, $2, $3 -), $(call suffix-search, $m, $2, $3), $m))
-# if $(foo-objs) exists, foo.o is a composite object
+# if $(foo-objs), $(foo-y), or $(foo-m) exists, foo.o is a composite object
multi-used-y := $(sort $(foreach m,$(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m))))
-multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m))))
+multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))), $(m))))
multi-used := $(multi-used-y) $(multi-used-m)
single-used-m := $(sort $(filter-out $(multi-used-m),$(obj-m)))
@@ -74,11 +68,22 @@ base-dtb-y := $(foreach m, $(multi-dtb-y), $(firstword $(call suffix-search, $m,
# $(subdir-obj-y) is the list of objects in $(obj-y) which uses dir/ to
# tell kbuild to descend
-subdir-obj-y := $(filter %/built-in.o, $(obj-y))
+subdir-obj-y := $(filter %/built-in.a, $(obj-y))
-# Replace multi-part objects by their individual parts, look at local dir only
-real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) $(extra-y)
-real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m)))
+# Replace multi-part objects by their individual parts,
+# including built-in.a from subdirectories
+real-obj-y := $(foreach m, $(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m)))
+real-obj-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))),$($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m)),$(m)))
+
+# DTB
+# If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built
+extra-y += $(dtb-y)
+extra-$(CONFIG_OF_ALL_DTBS) += $(dtb-)
+
+ifneq ($(CHECK_DTBS),)
+extra-y += $(patsubst %.dtb,%.dt.yaml, $(dtb-y))
+extra-$(CONFIG_OF_ALL_DTBS) += $(patsubst %.dtb,%.dt.yaml, $(dtb-))
+endif
# Add subdir path
@@ -91,8 +96,8 @@ obj-y := $(addprefix $(obj)/,$(obj-y))
obj-m := $(addprefix $(obj)/,$(obj-m))
lib-y := $(addprefix $(obj)/,$(lib-y))
subdir-obj-y := $(addprefix $(obj)/,$(subdir-obj-y))
-real-objs-y := $(addprefix $(obj)/,$(real-objs-y))
-real-objs-m := $(addprefix $(obj)/,$(real-objs-m))
+real-obj-y := $(addprefix $(obj)/,$(real-obj-y))
+real-obj-m := $(addprefix $(obj)/,$(real-obj-m))
single-used-m := $(addprefix $(obj)/,$(single-used-m))
multi-used-y := $(addprefix $(obj)/,$(multi-used-y))
multi-used-m := $(addprefix $(obj)/,$(multi-used-m))
@@ -102,22 +107,25 @@ multi-dtb-y := $(addprefix $(obj)/,$(multi-dtb-y))
real-dtb-y := $(addprefix $(obj)/,$(real-dtb-y))
subdir-ym := $(addprefix $(obj)/,$(subdir-ym))
+# Finds the multi-part object the current object will be linked into.
+# If the object belongs to two or more multi-part objects, all of them are
+# concatenated with a colon separator.
+modname-multi = $(subst $(space),:,$(sort $(foreach m,$(multi-used),\
+ $(if $(filter $*.o, $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))),$(m:.o=)))))
+
+modname = $(if $(modname-multi),$(modname-multi),$(basetarget))
+
# These flags are needed for modversions and compiling, so we define them here
-# already
-# $(modname_flags) #defines KBUILD_MODNAME as the name of the module it will
+# $(modname_flags) defines KBUILD_MODNAME as the name of the module it will
# end up in (or would, if it gets compiled in)
-# Note: Files that end up in two or more modules are compiled without the
-# KBUILD_MODNAME definition. The reason is that any made-up name would
-# differ in different configs.
name-fix = $(squote)$(quote)$(subst $(comma),_,$(subst -,_,$1))$(quote)$(squote)
basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget))
-modname_flags = $(if $(filter 1,$(words $(modname))),\
- -DKBUILD_MODNAME=$(call name-fix,$(modname)))
+modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname))
-orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \
+orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \
$(ccflags-y) $(CFLAGS_$(basetarget).o)
_c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags))
-orig_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(KBUILD_SUBDIR_ASFLAGS) \
+orig_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) \
$(asflags-y) $(AFLAGS_$(basetarget).o)
_a_flags = $(filter-out $(AFLAGS_REMOVE_$(basetarget).o), $(orig_a_flags))
_cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F))
@@ -140,7 +148,19 @@ endif
ifeq ($(CONFIG_KASAN),y)
_c_flags += $(if $(patsubst n%,, \
$(KASAN_SANITIZE_$(basetarget).o)$(KASAN_SANITIZE)y), \
- $(CFLAGS_KASAN))
+ $(CFLAGS_KASAN), $(CFLAGS_KASAN_NOSANITIZE))
+endif
+
+ifeq ($(CONFIG_UBSAN),y)
+_c_flags += $(if $(patsubst n%,, \
+ $(UBSAN_SANITIZE_$(basetarget).o)$(UBSAN_SANITIZE)$(CONFIG_UBSAN_SANITIZE_ALL)), \
+ $(CFLAGS_UBSAN))
+endif
+
+ifeq ($(CONFIG_KCOV),y)
+_c_flags += $(if $(patsubst n%,, \
+ $(KCOV_INSTRUMENT_$(basetarget).o)$(KCOV_INSTRUMENT)$(CONFIG_KCOV_INSTRUMENT_ALL)), \
+ $(CFLAGS_KCOV))
endif
__c_flags = $(_c_flags)
@@ -161,7 +181,6 @@ __a_flags = $(call flags,_a_flags)
__cpp_flags = $(call flags,_cpp_flags)
endif
endif
-
# Modified for U-Boot: LINUXINCLUDE -> UBOOTINCLUDE
c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(UBOOTINCLUDE) \
$(__c_flags) $(modkern_cflags) \
@@ -222,7 +241,6 @@ dtc_cpp_flags = -Wp,-MD,$(depfile).pre.tmp -nostdinc \
# Finds the multi-part object the current object will be linked into
modname-multi = $(sort $(foreach m,$(multi-used),\
$(if $(filter $(subst $(obj)/,,$*.o), $($(m:.o=-objs)) $($(m:.o=-y))),$(m:.o=))))
-
# Useful for describing the dependency of composite objects
# Usage:
# $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add)
@@ -278,12 +296,13 @@ $(obj)/%: $(src)/%_shipped
# ---------------------------------------------------------------------------
quiet_cmd_ld = LD $@
-cmd_ld = $(LD) $(ld_flags) $(filter-out FORCE,$^) -o $@
+ cmd_ld = $(LD) $(ld_flags) $(real-prereqs) -o $@
# Archive
# ---------------------------------------------------------------------------
+
quiet_cmd_ar = AR $@
-cmd_ar = rm -f $@; $(AR) rcsTP$(KBUILD_ARFLAGS) $@ $(real-prereqs)
+ cmd_ar = rm -f $@; $(AR) rcsTP$(KBUILD_ARFLAGS) $@ $(real-prereqs)
# Objcopy
# ---------------------------------------------------------------------------
@@ -295,10 +314,11 @@ cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
# ---------------------------------------------------------------------------
quiet_cmd_gzip = GZIP $@
-cmd_gzip = cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@
+ cmd_gzip = cat $(real-prereqs) | gzip -n -f -9 > $@
# DTC
# ---------------------------------------------------------------------------
+DTC ?= $(objtree)/scripts/dtc/dtc
# Disable noisy checks by default
ifeq ($(findstring 1,$(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),)
@@ -309,7 +329,6 @@ DTC_FLAGS += -Wno-unit_address_vs_reg \
-Wno-graph_child_address \
-Wno-simple_bus_reg \
-Wno-unique_unit_address \
- -Wno-simple_bus_reg \
-Wno-pci_device_reg
# U-Boot specific disables
@@ -567,20 +586,20 @@ printf "%08x\n" $$dec_size | \
)
quiet_cmd_bzip2 = BZIP2 $@
-cmd_bzip2 = { cat $(real-prereqs) | bzip2 -9 && $(size_append); } > $@
+ cmd_bzip2 = { cat $(real-prereqs) | bzip2 -9 && $(size_append); } > $@
# Lzma
# ---------------------------------------------------------------------------
quiet_cmd_lzma = LZMA $@
-cmd_lzma = { cat $(real-prereqs) | lzma -9 && $(size_append); } > $@
+ cmd_lzma = { cat $(real-prereqs) | lzma -9 && $(size_append); } > $@
quiet_cmd_lzo = LZO $@
-cmd_lzo = { cat $(real-prereqs) | lzop -9 && $(size_append); } > $@
+ cmd_lzo = { cat $(real-prereqs) | lzop -9 && $(size_append); } > $@
quiet_cmd_lz4 = LZ4 $@
-cmd_lz4 = { cat $(real-prereqs) | lz4c -l -c1 stdin stdout && \
- $(size_append); } > $@
+ cmd_lz4 = { cat $(real-prereqs) | lz4c -l -c1 stdin stdout && \
+ $(size_append); } > $@
# U-Boot mkimage
# ---------------------------------------------------------------------------
@@ -702,12 +721,15 @@ quiet_cmd_fdt_rm_props = FDTGREP $@
# ---------------------------------------------------------------------------
# Default sed regexp - multiline due to syntax constraints
+#
+# Use [:space:] because LLVM's integrated assembler inserts <tab> around
+# the .ascii directive whereas GCC keeps the <space> as-is.
define sed-offsets
- "s:[[:space:]]*\.ascii[[:space:]]*\"\(.*\)\":\1:; \
+ 's:^[[:space:]]*\.ascii[[:space:]]*"\(.*\)".*:\1:; \
/^->/{s:->#\(.*\):/* \1 */:; \
s:^->\([^ ]*\) [\$$#]*\([-0-9]*\) \(.*\):#define \1 \2 /* \3 */:; \
s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
- s:->::; p;}"
+ s:->::; p;}'
endef
# Use filechk to avoid rebuilds when a header changes, but the resulting file
diff --git a/scripts/Makefile.xpl b/scripts/Makefile.xpl
index 43f27874f9f..03a2f151d91 100644
--- a/scripts/Makefile.xpl
+++ b/scripts/Makefile.xpl
@@ -135,7 +135,7 @@ head-y := $(addprefix $(obj)/,$(head-y))
libs-y := $(addprefix $(obj)/,$(libs-y))
u-boot-spl-dirs := $(patsubst %/,%,$(filter %/, $(libs-y)))
-libs-y := $(patsubst %/, %/built-in.o, $(libs-y))
+libs-y := $(patsubst %/, %/built-in.a, $(libs-y))
# Add GCC lib
ifeq ($(CONFIG_USE_PRIVATE_LIBGCC),y)
diff --git a/scripts/dtc/pylibfdt/setup.py b/scripts/dtc/pylibfdt/setup.py
index 487e669f524..0f7485de9b5 100755
--- a/scripts/dtc/pylibfdt/setup.py
+++ b/scripts/dtc/pylibfdt/setup.py
@@ -157,7 +157,7 @@ setup(
long_description=long_description,
long_description_content_type="text/plain",
url="https://git.kernel.org/pub/scm/utils/dtc/dtc.git",
- license="BSD",
+ license="GPL-2.0-or-later OR BSD-2-Clause",
license_files=["Licenses/gpl-2.0.txt", "Licenses/bsd-2-clause.txt"],
classifiers=[
diff --git a/test/cmd/wget.c b/test/cmd/wget.c
index 445750660c2..1005392b952 100644
--- a/test/cmd/wget.c
+++ b/test/cmd/wget.c
@@ -241,3 +241,23 @@ static int net_test_wget(struct unit_test_state *uts)
return 0;
}
CMD_TEST(net_test_wget, UTF_CONSOLE);
+
+static int net_test_wget_uri_validate(struct unit_test_state *uts)
+{
+ ut_asserteq(true, wget_validate_uri("http://foo.com/bar.html"));
+ ut_asserteq(true, wget_validate_uri("http://1.1.2.3/bar.html"));
+ ut_asserteq(false, wget_validate_uri("http://foo/ba r.html"));
+ ut_asserteq(false, wget_validate_uri("http://"));
+
+ if (CONFIG_IS_ENABLED(WGET_HTTPS)) {
+ ut_asserteq(true,
+ wget_validate_uri("https://foo.com/bar.html"));
+ ut_asserteq(true,
+ wget_validate_uri("https://1.1.2.3/bar.html"));
+ ut_asserteq(false, wget_validate_uri("https://foo/ba r.html"));
+ ut_asserteq(false, wget_validate_uri("https://"));
+ }
+
+ return 0;
+}
+CMD_TEST(net_test_wget_uri_validate, UTF_CONSOLE);
diff --git a/test/common/print.c b/test/common/print.c
index c48efc2783f..76ee851fe6a 100644
--- a/test/common/print.c
+++ b/test/common/print.c
@@ -45,8 +45,7 @@ static int print_guid(struct unit_test_state *uts)
sprintf(str, "%pUL", guid);
ut_asserteq_str("04030201-0605-0807-090A-0B0C0D0E0F10", str);
sprintf(str, "%pUs", guid_esp);
- if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID) ||
- IS_ENABLED(CONFIG_CMD_EFIDEBUG) || IS_ENABLED(CONFIG_EFI))
+ if (IS_ENABLED(CONFIG_EFI_PARTITION))
ut_asserteq_str("EFI System Partition", str);
else
ut_asserteq_str("c12a7328-f81f-11d2-ba4b-00a0c93ec93b", str);
diff --git a/test/lib/Makefile b/test/lib/Makefile
index ff4ff63270d..35b40b584c4 100644
--- a/test/lib/Makefile
+++ b/test/lib/Makefile
@@ -8,7 +8,7 @@ obj-$(CONFIG_$(PHASE_)UT_COMPRESSION) += compression.o
ifeq ($(CONFIG_XPL_BUILD),)
obj-y += abuf.o
obj-y += alist.o
-obj-$(CONFIG_EFI_LOADER) += efi_device_path.o
+obj-$(CONFIG_EFI_LOADER) += efi_device_path.o efi_memory.o
obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o
obj-y += hexdump.o
obj-$(CONFIG_SANDBOX) += kconfig.o
diff --git a/test/lib/efi_memory.c b/test/lib/efi_memory.c
new file mode 100644
index 00000000000..d2e1ab6b4a3
--- /dev/null
+++ b/test/lib/efi_memory.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Test memory functions
+ *
+ * Copyright (c) 2025 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ */
+
+#include <efi_loader.h>
+#include <test/lib.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+static int lib_test_efi_alloc_aligned_pages(struct unit_test_state *uts)
+{
+ efi_status_t ret;
+
+ void *addr;
+ unsigned long align = 0x400000;
+
+ addr = efi_alloc_aligned_pages(4096, EFI_PERSISTENT_MEMORY_TYPE,
+ EFI_PAGE_SIZE);
+ ut_asserteq_ptr(NULL, addr);
+
+ addr = efi_alloc_aligned_pages(4096, 0x6FFFFFFF, EFI_PAGE_SIZE);
+ ut_asserteq_ptr(NULL, addr);
+
+ align = 0x200;
+ addr = efi_alloc_aligned_pages(4096, EFI_ACPI_RECLAIM_MEMORY, align);
+ ut_assertnonnull(addr);
+ ut_asserteq_64(0, (uintptr_t)addr & (align - 1));
+
+ ret = efi_free_pages((uintptr_t) addr, 1);
+ ut_asserteq_64(ret, EFI_SUCCESS);
+
+ align = 0x400000;
+ addr = efi_alloc_aligned_pages(4096, EFI_ACPI_RECLAIM_MEMORY, align);
+ ut_assertnonnull(addr);
+ ut_asserteq_64(0, (uintptr_t)addr & (align - 1));
+
+ ret = efi_free_pages((uintptr_t) addr, 1);
+ ut_asserteq_64(ret, EFI_SUCCESS);
+
+ return 0;
+}
+LIB_TEST(lib_test_efi_alloc_aligned_pages, 0);
+
+static int lib_test_efi_allocate_pages(struct unit_test_state *uts)
+{
+ efi_status_t ret;
+ u64 memory;
+
+ ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES,
+ EFI_ACPI_RECLAIM_MEMORY,
+ 1, &memory);
+ ut_asserteq_64(ret, EFI_SUCCESS);
+ ut_asserteq_64(0, memory & EFI_PAGE_MASK);
+
+ ret = efi_free_pages(memory, 1);
+ ut_asserteq_64(ret, EFI_SUCCESS);
+
+ return 0;
+}
+LIB_TEST(lib_test_efi_allocate_pages, 0);
diff --git a/test/lib/lmb.c b/test/lib/lmb.c
index 3bf558f7f4f..b6259bef442 100644
--- a/test/lib/lmb.c
+++ b/test/lib/lmb.c
@@ -71,6 +71,45 @@ static int setup_lmb_test(struct unit_test_state *uts, struct lmb *store,
return 0;
}
+static int lmb_reserve(phys_addr_t addr, phys_size_t size, u32 flags)
+{
+ int err;
+
+ err = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &addr, size, flags);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static phys_addr_t lmb_alloc(phys_size_t size, ulong align)
+{
+ int err;
+ phys_addr_t addr;
+
+ err = lmb_alloc_mem(LMB_MEM_ALLOC_ANY, align, &addr, size, LMB_NONE);
+ if (err)
+ return 0;
+
+ return addr;
+}
+
+static phys_addr_t lmb_alloc_base(phys_size_t size, ulong align,
+ phys_addr_t max_addr, u32 flags)
+{
+ int err;
+ phys_addr_t addr;
+
+ addr = max_addr;
+ err = lmb_alloc_mem(LMB_MEM_ALLOC_MAX, align, &addr, size, flags);
+ if (err)
+ return 0;
+
+ return addr;
+}
+
+#define lmb_alloc_addr(addr, size, flags) lmb_reserve(addr, size, flags)
+
static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram,
const phys_size_t ram_size, const phys_addr_t ram0,
const phys_size_t ram0_size,
@@ -143,7 +182,7 @@ static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram,
ASSERT_LMB(mem_lst, used_lst, 0, 0, 2,
alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0);
- ret = lmb_free(a, 4);
+ ret = lmb_free(a, 4, LMB_NONE);
ut_asserteq(ret, 0);
ASSERT_LMB(mem_lst, used_lst, 0, 0, 2,
alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0);
@@ -152,12 +191,12 @@ static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram,
ut_asserteq(a, a2);
ASSERT_LMB(mem_lst, used_lst, 0, 0, 2,
alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0);
- ret = lmb_free(a2, 4);
+ ret = lmb_free(a2, 4, LMB_NONE);
ut_asserteq(ret, 0);
ASSERT_LMB(mem_lst, used_lst, 0, 0, 2,
alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0);
- ret = lmb_free(b, 4);
+ ret = lmb_free(b, 4, LMB_NONE);
ut_asserteq(ret, 0);
ASSERT_LMB(mem_lst, used_lst, 0, 0, 3,
alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000,
@@ -167,17 +206,17 @@ static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram,
ut_asserteq(b, b2);
ASSERT_LMB(mem_lst, used_lst, 0, 0, 2,
alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0);
- ret = lmb_free(b2, 4);
+ ret = lmb_free(b2, 4, LMB_NONE);
ut_asserteq(ret, 0);
ASSERT_LMB(mem_lst, used_lst, 0, 0, 3,
alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000,
ram_end - 8, 4);
- ret = lmb_free(c, 4);
+ ret = lmb_free(c, 4, LMB_NONE);
ut_asserteq(ret, 0);
ASSERT_LMB(mem_lst, used_lst, 0, 0, 2,
alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000, 0, 0);
- ret = lmb_free(d, 4);
+ ret = lmb_free(d, 4, LMB_NONE);
ut_asserteq(ret, 0);
ASSERT_LMB(mem_lst, used_lst, 0, 0, 1, alloc_64k_addr, 0x10000,
0, 0, 0, 0);
@@ -281,7 +320,7 @@ static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram)
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, a,
big_block_size + 0x10000, 0, 0, 0, 0);
- ret = lmb_free(a, big_block_size);
+ ret = lmb_free(a, big_block_size, LMB_NONE);
ut_asserteq(ret, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, alloc_64k_addr, 0x10000,
0, 0, 0, 0);
@@ -353,12 +392,12 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram,
- alloc_size_aligned, alloc_size, 0, 0);
}
/* and free them */
- ret = lmb_free(b, alloc_size);
+ ret = lmb_free(b, alloc_size, LMB_NONE);
ut_asserteq(ret, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1,
ram + ram_size - alloc_size_aligned,
alloc_size, 0, 0, 0, 0);
- ret = lmb_free(a, alloc_size);
+ ret = lmb_free(a, alloc_size, LMB_NONE);
ut_asserteq(ret, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
@@ -369,7 +408,7 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram,
ram + ram_size - alloc_size_aligned,
alloc_size, 0, 0, 0, 0);
/* and free it */
- ret = lmb_free(b, alloc_size);
+ ret = lmb_free(b, alloc_size, LMB_NONE);
ut_asserteq(ret, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
@@ -437,12 +476,12 @@ static int lib_test_lmb_at_0(struct unit_test_state *uts)
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, a, ram_size - 4,
0, 0, 0, 0);
/* check that this was an error by freeing b */
- ret = lmb_free(b, 4);
+ ret = lmb_free(b, 4, LMB_NONE);
ut_asserteq(ret, -1);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, a, ram_size - 4,
0, 0, 0, 0);
- ret = lmb_free(a, ram_size - 4);
+ ret = lmb_free(a, ram_size - 4, LMB_NONE);
ut_asserteq(ret, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
@@ -568,20 +607,20 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NONE);
ut_asserteq(b, 0);
b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NOOVERWRITE);
- ut_asserteq(b, -1);
+ ut_asserteq(b, -EEXIST);
b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NONE);
ut_asserteq(b, 0);
b = lmb_alloc_addr(alloc_addr_a, 0x2000, LMB_NONE);
ut_asserteq(b, 0);
- ret = lmb_free(alloc_addr_a, 0x2000);
+ ret = lmb_free(alloc_addr_a, 0x2000, LMB_NONE);
ut_asserteq(ret, 0);
b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NOOVERWRITE);
ut_asserteq(b, 0);
b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NONE);
- ut_asserteq(b, -1);
+ ut_asserteq(b, -EEXIST);
b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NOOVERWRITE);
- ut_asserteq(b, -1);
- ret = lmb_free(alloc_addr_a, 0x1000);
+ ut_asserteq(b, -EEXIST);
+ ret = lmb_free(alloc_addr_a, 0x1000, LMB_NONE);
ut_asserteq(ret, 0);
/*
@@ -599,13 +638,13 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
alloc_addr_a + 0x4000, 0x1000, 0, 0);
c = lmb_alloc_addr(alloc_addr_a + 0x1000, 0x5000, LMB_NONE);
- ut_asserteq(c, -1);
+ ut_asserteq(c, -EEXIST);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, alloc_addr_a, 0x1000,
alloc_addr_a + 0x4000, 0x1000, 0, 0);
- ret = lmb_free(alloc_addr_a, 0x1000);
+ ret = lmb_free(alloc_addr_a, 0x1000, LMB_NONE);
ut_asserteq(ret, 0);
- ret = lmb_free(alloc_addr_a + 0x4000, 0x1000);
+ ret = lmb_free(alloc_addr_a + 0x4000, 0x1000, LMB_NOOVERWRITE);
ut_asserteq(ret, 0);
/*
@@ -628,7 +667,7 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, alloc_addr_a, 0x6000,
0, 0, 0, 0);
- ret = lmb_free(alloc_addr_a, 0x6000);
+ ret = lmb_free(alloc_addr_a, 0x6000, LMB_NONE);
ut_asserteq(ret, 0);
/*
@@ -646,13 +685,13 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
alloc_addr_a + 0x4000, 0x1000, 0, 0);
c = lmb_alloc_addr(alloc_addr_a + 0x1000, 0x5000, LMB_NOOVERWRITE);
- ut_asserteq(c, -1);
+ ut_asserteq(c, -EEXIST);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, alloc_addr_a, 0x1000,
alloc_addr_a + 0x4000, 0x1000, 0, 0);
- ret = lmb_free(alloc_addr_a, 0x1000);
+ ret = lmb_free(alloc_addr_a, 0x1000, LMB_NOOVERWRITE);
ut_asserteq(ret, 0);
- ret = lmb_free(alloc_addr_a + 0x4000, 0x1000);
+ ret = lmb_free(alloc_addr_a + 0x4000, 0x1000, LMB_NOOVERWRITE);
ut_asserteq(ret, 0);
/* reserve 3 blocks */
@@ -693,7 +732,8 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
0, 0, 0, 0);
/* free thge allocation from d */
- ret = lmb_free(alloc_addr_c + 0x10000, ram_end - alloc_addr_c - 0x10000);
+ ret = lmb_free(alloc_addr_c + 0x10000, ram_end - alloc_addr_c - 0x10000,
+ LMB_NONE);
ut_asserteq(ret, 0);
/* allocate at 3 points in free range */
@@ -702,7 +742,7 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
ut_asserteq(d, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, ram, 0x18010000,
ram_end - 4, 4, 0, 0);
- ret = lmb_free(ram_end - 4, 4);
+ ret = lmb_free(ram_end - 4, 4, LMB_NONE);
ut_asserteq(ret, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010000,
0, 0, 0, 0);
@@ -711,7 +751,7 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
ut_asserteq(d, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, ram, 0x18010000,
ram_end - 128, 4, 0, 0);
- ret = lmb_free(ram_end - 128, 4);
+ ret = lmb_free(ram_end - 128, 4, LMB_NONE);
ut_asserteq(ret, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010000,
0, 0, 0, 0);
@@ -720,13 +760,13 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
ut_asserteq(d, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010004,
0, 0, 0, 0);
- ret = lmb_free(alloc_addr_c + 0x10000, 4);
+ ret = lmb_free(alloc_addr_c + 0x10000, 4, LMB_NONE);
ut_asserteq(ret, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010000,
0, 0, 0, 0);
/* allocate at the bottom a was assigned to ram at the top */
- ret = lmb_free(ram, alloc_addr_a - ram);
+ ret = lmb_free(ram, alloc_addr_a - ram, LMB_NONE);
ut_asserteq(ret, 0);
ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram + 0x8000000,
0x10010000, 0, 0, 0, 0);
@@ -739,11 +779,11 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
/* check that allocating outside memory fails */
if (ram_end != 0) {
ret = lmb_alloc_addr(ram_end, 1, LMB_NONE);
- ut_asserteq(ret, -1);
+ ut_asserteq(ret, -EINVAL);
}
if (ram != 0) {
ret = lmb_alloc_addr(ram - 1, 1, LMB_NONE);
- ut_asserteq(ret, -1);
+ ut_asserteq(ret, -EINVAL);
}
lmb_pop(&store);
diff --git a/test/py/tests/test_efi_selftest.py b/test/py/tests/test_efi_selftest.py
index 12cbe5caa9b..58dac72fd40 100644
--- a/test/py/tests/test_efi_selftest.py
+++ b/test/py/tests/test_efi_selftest.py
@@ -179,6 +179,7 @@ def test_efi_selftest_text_input_ex(ubman):
@pytest.mark.buildconfigspec('cmd_bootefi_selftest')
@pytest.mark.buildconfigspec('efi_tcg2_protocol')
+@pytest.mark.notbuildconfigspec('sandbox')
def test_efi_selftest_tcg2(ubman):
"""Test the EFI_TCG2 PROTOCOL
diff --git a/test/py/tests/test_fit_mkimage_validate.py b/test/py/tests/test_fit_mkimage_validate.py
new file mode 100644
index 00000000000..af56f08ca10
--- /dev/null
+++ b/test/py/tests/test_fit_mkimage_validate.py
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2025
+#
+# Test that mkimage validates image references in configurations
+
+import os
+import subprocess
+import pytest
+import fit_util
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.requiredtool('dtc')
+def test_fit_invalid_image_reference(ubman):
+ """Test that mkimage fails when configuration references a missing image"""
+
+ its_fname = fit_util.make_fname(ubman, "invalid.its")
+ itb_fname = fit_util.make_fname(ubman, "invalid.itb")
+ kernel = fit_util.make_kernel(ubman, 'kernel.bin', 'kernel')
+
+ # Write ITS with an invalid reference to a nonexistent image
+ its_text = '''
+/dts-v1/;
+
+/ {
+ images {
+ kernel@1 {
+ description = "Test Kernel";
+ data = /incbin/("kernel.bin");
+ type = "kernel";
+ arch = "sandbox";
+ os = "linux";
+ compression = "none";
+ load = <0x40000>;
+ entry = <0x40000>;
+ };
+ };
+
+ configurations {
+ default = "conf@1";
+ conf@1 {
+ kernel = "kernel@1";
+ fdt = "notexist";
+ };
+ };
+};
+'''
+
+ with open(its_fname, 'w') as f:
+ f.write(its_text)
+
+ mkimage = os.path.join(ubman.config.build_dir, 'tools/mkimage')
+ cmd = [mkimage, '-f', its_fname, itb_fname]
+
+ result = subprocess.run(cmd, capture_output=True, text=True)
+
+ assert result.returncode != 0, "mkimage should fail due to missing image reference"
+ assert "references undefined image 'notexist'" in result.stderr
+
diff --git a/test/py/tests/test_gpt.py b/test/py/tests/test_gpt.py
index cfc8f1319a9..e6d8792ac1f 100644
--- a/test/py/tests/test_gpt.py
+++ b/test/py/tests/test_gpt.py
@@ -330,6 +330,33 @@ def test_gpt_write(state_disk_image, ubman):
output = ubman.run_command('gpt guid host 0')
assert '375a56f7-d6c9-4e81-b5f0-09d41ca89efe' in output
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('cmd_gpt')
+@pytest.mark.buildconfigspec('cmd_part')
+@pytest.mark.buildconfigspec('partition_type_guid')
+@pytest.mark.requiredtool('sgdisk')
+def test_gpt_write_part_type(state_disk_image, ubman):
+ """Test the gpt command with part type uuid."""
+
+ output = ubman.run_command('gpt write host 0 "name=part1,type=data,size=1M;name=part2,size=512K,type=system;name=part3,size=65536,type=u-boot-env;name=part4,size=65536,type=375a56f7-d6c9-4e81-b5f0-09d41ca89efe;name=part5,size=-,type=linux"')
+ assert 'Writing GPT: success!' in output
+ output = ubman.run_command('part list host 0')
+ assert '1\t0x00000022\t0x00000821\t"part1"' in output
+ assert 'ebd0a0a2-b9e5-4433-87c0-68b6b72699c7' in output
+ assert '(data)' in output
+ assert '2\t0x00000822\t0x00000c21\t"part2"' in output
+ assert 'c12a7328-f81f-11d2-ba4b-00a0c93ec93b' in output
+ assert '(EFI System Partition)' in output
+ assert '3\t0x00000c22\t0x00000ca1\t"part3"' in output
+ assert '3de21764-95bd-54bd-a5c3-4abe786f38a8' in output
+ assert '(u-boot-env)' in output
+ assert '4\t0x00000ca2\t0x00000d21\t"part4"' in output
+ assert 'ebd0a0a2-b9e5-4433-87c0-68b6b72699c7' in output
+ assert '(375a56f7-d6c9-4e81-b5f0-09d41ca89efe)' in output
+ assert '5\t0x00000d22\t0x00001fde\t"part5"' in output
+ assert '0fc63daf-8483-4772-8e79-3d69d8477de4' in output
+ assert '(linux)' in output
+
@pytest.mark.buildconfigspec('cmd_gpt')
@pytest.mark.buildconfigspec('cmd_gpt_rename')
@pytest.mark.buildconfigspec('cmd_part')
diff --git a/test/py/tests/test_help.py b/test/py/tests/test_help.py
index 12cb36b7b98..afb57201ba3 100644
--- a/test/py/tests/test_help.py
+++ b/test/py/tests/test_help.py
@@ -4,6 +4,7 @@
import pytest
+@pytest.mark.buildconfigspec('cmd_help')
def test_help(ubman):
"""Test that the "help" command can be executed."""
diff --git a/test/py/tests/test_mmc.py b/test/py/tests/test_mmc.py
index e751a3bd36a..1f738ef3dcb 100644
--- a/test/py/tests/test_mmc.py
+++ b/test/py/tests/test_mmc.py
@@ -99,7 +99,7 @@ def test_mmc_dev(ubman):
devices[x]['detected'] = 'yes'
for y in mmc_modes:
- output = ubman.run_command('mmc dev %d 0 %d' % x, y)
+ output = ubman.run_command('mmc dev %d 0 %d' % (x, y))
if 'Card did not respond to voltage select' in output:
fail = 1
@@ -122,7 +122,7 @@ def test_mmcinfo(ubman):
for x in range(0, controllers):
if devices[x]['detected'] == 'yes':
for y in mmc_modes:
- ubman.run_command('mmc dev %d 0 %d' % x, y)
+ ubman.run_command('mmc dev %d 0 %d' % (x, y))
output = ubman.run_command('mmcinfo')
if 'busy timeout' in output:
pytest.skip('No SD/MMC/eMMC device present')
@@ -146,7 +146,7 @@ def test_mmc_info(ubman):
for x in range(0, controllers):
if devices[x]['detected'] == 'yes':
for y in mmc_modes:
- ubman.run_command('mmc dev %d 0 %d' % x, y)
+ ubman.run_command('mmc dev %d 0 %d' % (x, y))
output = ubman.run_command('mmc info')
assert mmc_modes_name[mmc_modes.index(y)] in output
@@ -172,7 +172,7 @@ def test_mmc_rescan(ubman):
for x in range(0, controllers):
if devices[x]['detected'] == 'yes':
for y in mmc_modes:
- ubman.run_command('mmc dev %d 0 %d' % x, y)
+ ubman.run_command('mmc dev %d 0 %d' % (x, y))
output = ubman.run_command('mmc rescan')
if output:
pytest.fail('mmc rescan has something to check')
@@ -210,7 +210,7 @@ def test_mmc_part(ubman):
elif part_type == '83':
print('ext(2/4) detected')
output = ubman.run_command(
- 'fstype mmc %d:%d' % x, part_id
+ 'fstype mmc %d:%d' % (x, part_id)
)
if 'ext2' in output:
part_ext2.append(part_id)
@@ -246,7 +246,7 @@ def test_mmc_fatls_fatinfo(ubman):
for part in partitions:
for y in mmc_modes:
- ubman.run_command('mmc dev %d %d %d' % x, part, y)
+ ubman.run_command('mmc dev %d %d %d' % (x, part, y))
output = ubman.run_command(
'fatls mmc %d:%s' % (x, part))
if 'Unrecognized filesystem type' in output:
@@ -288,7 +288,7 @@ def test_mmc_fatload_fatwrite(ubman):
for part in partitions:
for y in mmc_modes:
- ubman.run_command('mmc dev %d %d %d' % x, part, y)
+ ubman.run_command('mmc dev %d %d %d' % (x, part, y))
part_detect = 1
addr = utils.find_ram_base(ubman)
devices[x]['addr_%d' % part] = addr
@@ -357,7 +357,7 @@ def test_mmc_ext4ls(ubman):
for part in partitions:
for y in mmc_modes:
- ubman.run_command('mmc dev %d %d %d' % x, part, y)
+ ubman.run_command('mmc dev %d %d %d' % (x, part, y))
output = ubman.run_command(
'%sls mmc %d:%s' % (fs, x, part)
)
@@ -392,7 +392,7 @@ def test_mmc_ext4load_ext4write(ubman):
for part in partitions:
for y in mmc_modes:
- ubman.run_command('mmc dev %d %d %d' % x, part, y)
+ ubman.run_command('mmc dev %d %d %d' % (x, part, y))
part_detect = 1
addr = utils.find_ram_base(ubman)
devices[x]['addr_%d' % part] = addr
@@ -454,7 +454,7 @@ def test_mmc_ext2ls(ubman):
for part in partitions:
for y in mmc_modes:
- ubman.run_command('mmc dev %d %d %d' % x, part, y)
+ ubman.run_command('mmc dev %d %d %d' % (x, part, y))
part_detect = 1
output = ubman.run_command(
'%sls mmc %d:%s' % (fs, x, part)
@@ -491,7 +491,7 @@ def test_mmc_ext2load(ubman):
for part in partitions:
for y in mmc_modes:
- ubman.run_command('mmc dev %d %d %d' % x, part, y)
+ ubman.run_command('mmc dev %d %d %d' % (x, part, y))
part_detect = 1
addr = devices[x]['addr_%d' % part]
size = devices[x]['size_%d' % part]
@@ -534,7 +534,7 @@ def test_mmc_ls(ubman):
for part in partitions:
for y in mmc_modes:
- ubman.run_command('mmc dev %d %d %d' % x, part, y)
+ ubman.run_command('mmc dev %d %d %d' % (x, part, y))
part_detect = 1
output = ubman.run_command('ls mmc %d:%s' % (x, part))
if re.search(r'No \w+ table on this device', output):
@@ -566,7 +566,7 @@ def test_mmc_load(ubman):
for part in partitions:
for y in mmc_modes:
- ubman.run_command('mmc dev %d %d %d' % x, part, y)
+ ubman.run_command('mmc dev %d %d %d' % (x, part, y))
part_detect = 1
addr = devices[x]['addr_%d' % part]
size = devices[x]['size_%d' % part]
@@ -609,7 +609,7 @@ def test_mmc_save(ubman):
for part in partitions:
for y in mmc_modes:
- ubman.run_command('mmc dev %d %d %d' % x, part, y)
+ ubman.run_command('mmc dev %d %d %d' % (x, part, y))
part_detect = 1
addr = devices[x]['addr_%d' % part]
size = 0
@@ -656,7 +656,7 @@ def test_mmc_fat_read_write_files(ubman):
for part in partitions:
for y in mmc_modes:
- ubman.run_command('mmc dev %d %d %d' % x, part, y)
+ ubman.run_command('mmc dev %d %d %d' % (x, part, y))
part_detect = 1
addr = utils.find_ram_base(ubman)
count_f = 0
diff --git a/tools/Makefile b/tools/Makefile
index 97ce1dbb17e..02297e8c93a 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -63,7 +63,8 @@ HOSTCFLAGS_img2srec.o := -pedantic
hostprogs-y += mkenvimage
mkenvimage-objs := mkenvimage.o os_support.o generated/lib/crc32.o
-hostprogs-y += dumpimage mkimage fit_info fit_check_sign
+hostprogs-y += dumpimage mkimage fit_info
+hostprogs-$(CONFIG_FIT_SIGNATURE) += fit_check_sign
hostprogs-$(CONFIG_TOOLS_LIBCRYPTO) += fdt_add_pubkey
hostprogs-$(CONFIG_TOOLS_LIBCRYPTO) += preload_check_sign
diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst
index 84b1331df5c..392e507d449 100644
--- a/tools/binman/binman.rst
+++ b/tools/binman/binman.rst
@@ -1143,6 +1143,13 @@ Optional entries
Some entries need to exist only if certain conditions are met. For example, an
entry may want to appear in the image only if a file has a particular format.
+Also, the ``optional`` property may be used to mark entries as optional::
+
+ tee-os {
+ filename = "tee.bin";
+ optional;
+ };
+
Obviously the entry must exist in the image description for it to be processed
at all, so a way needs to be found to have the entry remove itself.
diff --git a/tools/binman/btool/openssl.py b/tools/binman/btool/openssl.py
index c6df64c5316..b26f087c447 100644
--- a/tools/binman/btool/openssl.py
+++ b/tools/binman/btool/openssl.py
@@ -153,7 +153,7 @@ numFirewallRegions = INTEGER:{firewall_cert_data['num_firewalls']}
def x509_cert_rom(self, cert_fname, input_fname, key_fname, sw_rev,
config_fname, req_dist_name_dict, cert_type, bootcore,
- bootcore_opts, load_addr, sha):
+ bootcore_opts, load_addr, sha, debug):
"""Create a certificate
Args:
@@ -221,9 +221,13 @@ emailAddress = {req_dist_name_dict['emailAddress']}
# iterationCnt = INTEGER:TEST_IMAGE_KEY_DERIVE_INDEX
# salt = FORMAT:HEX,OCT:TEST_IMAGE_KEY_DERIVE_SALT
+ # When debugging low level boot firmware it can be useful to have ROM or TIFS
+ # unlock JTAG access to the misbehaving CPUs. However in a production setting
+ # this can lead to code modification by outside parties after it's been
+ # authenticated. To gain JTAG access add the 'debug' flag to the binman config
[ debug ]
debugUID = FORMAT:HEX,OCT:0000000000000000000000000000000000000000000000000000000000000000
- debugType = INTEGER:4
+ debugType = INTEGER:{ "4" if debug else "0" }
coreDbgEn = INTEGER:0
coreDbgSecEn = INTEGER:0
''', file=outf)
@@ -238,7 +242,7 @@ emailAddress = {req_dist_name_dict['emailAddress']}
imagesize_sbl, hashval_sbl, load_addr_sysfw, imagesize_sysfw,
hashval_sysfw, load_addr_sysfw_data, imagesize_sysfw_data,
hashval_sysfw_data, sysfw_inner_cert_ext_boot_block,
- dm_data_ext_boot_block, bootcore_opts):
+ dm_data_ext_boot_block, bootcore_opts, debug):
"""Create a certificate
Args:
@@ -324,9 +328,13 @@ compSize = INTEGER:{imagesize_sysfw_data}
shaType = OID:{sha_type}
shaValue = FORMAT:HEX,OCT:{hashval_sysfw_data}
+# When debugging low level boot firmware it can be useful to have ROM or TIFS
+# unlock JTAG access to the misbehaving CPUs. However in a production setting
+# this can lead to code modification by outside parties after it's been
+# authenticated. To gain JTAG access add the 'debug' flag to the binman config
[ debug ]
debugUID = FORMAT:HEX,OCT:0000000000000000000000000000000000000000000000000000000000000000
-debugType = INTEGER:4
+debugType = INTEGER:{ "4" if debug else "0" }
coreDbgEn = INTEGER:0
coreDbgSecEn = INTEGER:0
diff --git a/tools/binman/control.py b/tools/binman/control.py
index 1946656f7d3..af447d792a7 100644
--- a/tools/binman/control.py
+++ b/tools/binman/control.py
@@ -97,7 +97,7 @@ def _ReadMissingBlobHelp():
return tag, msg
my_data = pkg_resources.resource_string(__name__, 'missing-blob-help')
- re_tag = re.compile('^([-a-z0-9]+):$')
+ re_tag = re.compile(r"^([-\.a-z0-9]+):$")
result = {}
tag = None
msg = ''
@@ -530,6 +530,57 @@ def _RemoveTemplates(parent):
for node in del_nodes:
node.Delete()
+def propagate_prop(node, prop):
+ """Propagate the provided property to all the parent nodes up the hierarchy
+
+ Args:
+ node (fdt.Node): Node and all its parent nodes up to the root to
+ propagate the property.
+ prop (str): Boolean property to propagate
+
+ Return:
+ True if any change was made, else False
+ """
+ changed = False
+ while node:
+ if prop not in node.props:
+ node.AddEmptyProp(prop, 0)
+ changed = True
+ node = node.parent
+ return changed
+
+def scan_and_prop_bootph(node):
+ """Propagate bootph properties from children to parents
+
+ The bootph schema indicates that bootph properties in children should be
+ implied in their parents, all the way up the hierarchy. This is expensive
+ to implement in U-Boot before relocation at runtime, so this function
+ explicitly propagates these bootph properties upwards during build time.
+
+ This is used to set the bootph-all, bootph-some-ram property in the parent
+ node if the respective property is found in any of the parent's subnodes.
+ The other bootph-* properties are associated with the SPL stage and hence
+ handled by fdtgrep.c.
+
+ Args:
+ node (fdt.Node): Node to scan for bootph-all and bootph-some-ram
+ property
+
+ Return:
+ True if any change was made, else False
+
+ """
+ bootph_prop = {'bootph-all', 'bootph-some-ram'}
+
+ changed = False
+ for prop in bootph_prop:
+ if prop in node.props:
+ changed |= propagate_prop(node.parent, prop)
+
+ for subnode in node.subnodes:
+ changed |= scan_and_prop_bootph(subnode)
+ return changed
+
def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded, indir):
"""Prepare the images to be processed and select the device tree
@@ -589,6 +640,9 @@ def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded, ind
fname = tools.get_output_filename('u-boot.dtb.tmpl2')
tools.write_file(fname, dtb.GetContents())
+ if scan_and_prop_bootph(dtb.GetRoot()):
+ dtb.Sync(True)
+
images = _ReadImageDesc(node, use_expanded)
if select_images:
@@ -645,14 +699,27 @@ def CheckForProblems(image):
_ShowHelpForMissingBlobs(tout.ERROR, missing_list)
faked_list = []
+ faked_optional_list = []
+ faked_required_list = []
image.CheckFakedBlobs(faked_list)
- if faked_list:
+ for e in faked_list:
+ if e.optional:
+ faked_optional_list.append(e)
+ else:
+ faked_required_list.append(e)
+ if faked_required_list:
tout.warning(
"Image '%s' has faked external blobs and is non-functional: %s\n" %
(image.name, ' '.join([os.path.basename(e.GetDefaultFilename())
- for e in faked_list])))
+ for e in faked_required_list])))
optional_list = []
+ # For optional blobs, we should inform the user when the blob is not present. This will come as
+ # a warning since it may not be immediately apparent that something is missing otherwise.
+ # E.g. user thinks they supplied a blob, but there is no info of the contrary if they made an
+ # error.
+ # Faked optional blobs are not relevant for final images (as they are dropped anyway) so we
+ # will omit the message with default verbosity.
image.CheckOptional(optional_list)
if optional_list:
tout.warning(
@@ -660,6 +727,12 @@ def CheckForProblems(image):
(image.name, ' '.join([e.name for e in optional_list])))
_ShowHelpForMissingBlobs(tout.WARNING, optional_list)
+ if faked_optional_list:
+ tout.info(
+ "Image '%s' has faked optional external blobs but is still functional: %s\n" %
+ (image.name, ' '.join([os.path.basename(e.GetDefaultFilename())
+ for e in faked_optional_list])))
+
missing_bintool_list = []
image.check_missing_bintools(missing_bintool_list)
if missing_bintool_list:
@@ -667,7 +740,7 @@ def CheckForProblems(image):
"Image '%s' has missing bintools and is non-functional: %s\n" %
(image.name, ' '.join([os.path.basename(bintool.name)
for bintool in missing_bintool_list])))
- return any([missing_list, faked_list, missing_bintool_list])
+ return any([missing_list, faked_required_list, missing_bintool_list])
def ProcessImage(image, update_fdt, write_map, get_contents=True,
allow_resize=True, allow_missing=False,
@@ -697,7 +770,6 @@ def ProcessImage(image, update_fdt, write_map, get_contents=True,
image.SetAllowMissing(allow_missing)
image.SetAllowFakeBlob(allow_fake_blobs)
image.GetEntryContents()
- image.drop_absent()
image.GetEntryOffsets()
# We need to pack the entries to figure out where everything
@@ -736,12 +808,12 @@ def ProcessImage(image, update_fdt, write_map, get_contents=True,
image.Raise('Entries changed size after packing (tried %s passes)' %
passes)
+ has_problems = CheckForProblems(image)
+
image.BuildImage()
if write_map:
image.WriteMap()
- has_problems = CheckForProblems(image)
-
image.WriteAlternates()
return has_problems
diff --git a/tools/binman/entry.py b/tools/binman/entry.py
index bdc60e47fca..ce7ef28e94b 100644
--- a/tools/binman/entry.py
+++ b/tools/binman/entry.py
@@ -88,6 +88,7 @@ class Entry(object):
updated with a hash of the entry contents
comp_bintool: Bintools used for compress and decompress data
fake_fname: Fake filename, if one was created, else None
+ faked (bool): True if the entry is absent and faked
required_props (dict of str): Properties which must be present. This can
be added to by subclasses
elf_fname (str): Filename of the ELF file, if this entry holds an ELF
@@ -759,7 +760,7 @@ class Entry(object):
self.image_pos)
# pylint: disable=assignment-from-none
- def GetEntries(self):
+ def GetEntries(self) -> None:
"""Return a list of entries contained by this entry
Returns:
@@ -1120,7 +1121,7 @@ features to produce new behaviours.
if self.missing and not self.optional:
missing_list.append(self)
- def check_fake_fname(self, fname, size=0):
+ def check_fake_fname(self, fname: str, size: int = 0) -> str:
"""If the file is missing and the entry allows fake blobs, fake it
Sets self.faked to True if faked
@@ -1130,9 +1131,7 @@ features to produce new behaviours.
size (int): Size of fake file to create
Returns:
- tuple:
- fname (str): Filename of faked file
- bool: True if the blob was faked, False if not
+ fname (str): Filename of faked file
"""
if self.allow_fake and not pathlib.Path(fname).is_file():
if not self.fake_fname:
@@ -1142,8 +1141,8 @@ features to produce new behaviours.
tout.info(f"Entry '{self._node.path}': Faked blob '{outfname}'")
self.fake_fname = outfname
self.faked = True
- return self.fake_fname, True
- return fname, False
+ return self.fake_fname
+ return fname
def CheckFakedBlobs(self, faked_blobs_list):
"""Check if any entries in this section have faked external blobs
@@ -1352,6 +1351,10 @@ features to produce new behaviours.
os.mkdir(cls.fake_dir)
tout.notice(f"Fake-blob dir is '{cls.fake_dir}'")
+ def drop_absent_optional(self) -> None:
+ """Entries don't have any entries, do nothing"""
+ pass
+
def ensure_props(self):
"""Raise an exception if properties are missing
diff --git a/tools/binman/etype/blob.py b/tools/binman/etype/blob.py
index 041e1122953..acd9ae34074 100644
--- a/tools/binman/etype/blob.py
+++ b/tools/binman/etype/blob.py
@@ -42,7 +42,7 @@ class Entry_blob(Entry):
if fdt_util.GetBool(self._node, 'write-symbols'):
self.auto_write_symbols = True
- def ObtainContents(self, fake_size=0):
+ def ObtainContents(self, fake_size: int = 0) -> bool:
self._filename = self.GetDefaultFilename()
self._pathname = tools.get_input_filename(self._filename,
self.external and (self.optional or self.section.GetAllowMissing()))
@@ -50,10 +50,11 @@ class Entry_blob(Entry):
if not self._pathname:
if not fake_size and self.assume_size:
fake_size = self.assume_size
- self._pathname, faked = self.check_fake_fname(self._filename,
- fake_size)
+ self._pathname = self.check_fake_fname(self._filename, fake_size)
self.missing = True
- if not faked:
+ if self.optional:
+ self.mark_absent("missing but optional")
+ if not self.faked:
content_size = 0
if self.assume_size: # Ensure we get test coverage on next line
content_size = self.assume_size
diff --git a/tools/binman/etype/blob_ext_list.py b/tools/binman/etype/blob_ext_list.py
index 1bfcf6733a7..a8b5a24c3a1 100644
--- a/tools/binman/etype/blob_ext_list.py
+++ b/tools/binman/etype/blob_ext_list.py
@@ -33,11 +33,11 @@ class Entry_blob_ext_list(Entry_blob):
self._filenames = fdt_util.GetStringList(self._node, 'filenames')
self._pathnames = []
- def ObtainContents(self):
+ def ObtainContents(self) -> bool:
missing = False
pathnames = []
for fname in self._filenames:
- fname, _ = self.check_fake_fname(fname)
+ fname = self.check_fake_fname(fname)
pathname = tools.get_input_filename(
fname, self.external and self.section.GetAllowMissing())
# Allow the file to be missing
diff --git a/tools/binman/etype/cbfs.py b/tools/binman/etype/cbfs.py
index 124fa1e4ffc..5879f377231 100644
--- a/tools/binman/etype/cbfs.py
+++ b/tools/binman/etype/cbfs.py
@@ -276,7 +276,8 @@ class Entry_cbfs(Entry):
for entry in self._entries.values():
entry.ListEntries(entries, indent + 1)
- def GetEntries(self):
+ def GetEntries(self) -> dict[str, Entry]:
+ """Returns the entries (tree children) of this section"""
return self._entries
def ReadData(self, decomp=True, alt_format=None):
diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py
index ed3cac4ee7e..db40479d30e 100644
--- a/tools/binman/etype/fit.py
+++ b/tools/binman/etype/fit.py
@@ -557,12 +557,15 @@ class Entry_fit(Entry_section):
Raises:
ValueError: Filename 'rsa2048.key' not found in input path
ValueError: Multiple key paths found
+ ValueError: 'dir/rsa2048' is a path not a filename
"""
def _find_keys_dir(node):
for subnode in node.subnodes:
if (subnode.name.startswith('signature') or
subnode.name.startswith('cipher')):
hint = subnode.props['key-name-hint'].value
+ if '/' in hint:
+ self.Raise(f"'{hint}' is a path not a filename")
name = tools.get_input_filename(
f"{hint}.key" if subnode.name.startswith('signature')
else f"{hint}.bin")
diff --git a/tools/binman/etype/mkimage.py b/tools/binman/etype/mkimage.py
index 6ae5d0c8a4f..75e59c3d3a3 100644
--- a/tools/binman/etype/mkimage.py
+++ b/tools/binman/etype/mkimage.py
@@ -205,7 +205,7 @@ class Entry_mkimage(Entry_section):
self.record_missing_bintool(self.mkimage)
return data
- def GetEntries(self):
+ def GetEntries(self) -> dict[str, Entry]:
# Make a copy so we don't change the original
entries = OrderedDict(self._entries)
if self._imagename:
diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py
index 1d50bb47753..03c4f7c6ec7 100644
--- a/tools/binman/etype/section.py
+++ b/tools/binman/etype/section.py
@@ -537,7 +537,7 @@ class Entry_section(Entry):
for entry in self._entries.values():
entry.WriteMap(fd, indent + 1)
- def GetEntries(self):
+ def GetEntries(self) -> dict[str, Entry]:
return self._entries
def GetContentsByPhandle(self, phandle, source_entry, required):
@@ -772,9 +772,17 @@ class Entry_section(Entry):
todo)
return True
- def drop_absent(self):
- """Drop entries which are absent"""
- self._entries = {n: e for n, e in self._entries.items() if not e.absent}
+ def drop_absent_optional(self) -> None:
+ """Drop entries which are absent.
+ Call for all nodes in the tree. Leaf nodes will do nothing per
+ definition. Sections however have _entries and should drop all children
+ which are absent.
+ """
+ self._entries = {n: e for n, e in self._entries.items() if not (e.absent and e.optional)}
+ # Drop nodes first before traversing children to avoid superfluous calls
+ # to children of absent nodes.
+ for e in self.GetEntries().values():
+ e.drop_absent_optional()
def _SetEntryOffsetSize(self, name, offset, size):
"""Set the offset and size of an entry
diff --git a/tools/binman/etype/ti_secure.py b/tools/binman/etype/ti_secure.py
index 420ee263e4f..f6caa0286d9 100644
--- a/tools/binman/etype/ti_secure.py
+++ b/tools/binman/etype/ti_secure.py
@@ -124,6 +124,7 @@ class Entry_ti_secure(Entry_x509_cert):
'OU': 'Processors',
'CN': 'TI Support',
'emailAddress': 'support@ti.com'}
+ self.debug = fdt_util.GetBool(self._node, 'debug', False)
def ReadFirewallNode(self):
self.firewall_cert_data['certificate'] = ""
diff --git a/tools/binman/etype/ti_secure_rom.py b/tools/binman/etype/ti_secure_rom.py
index f6fc3f90f84..7e90c655940 100644
--- a/tools/binman/etype/ti_secure_rom.py
+++ b/tools/binman/etype/ti_secure_rom.py
@@ -87,6 +87,7 @@ class Entry_ti_secure_rom(Entry_x509_cert):
'OU': 'Processors',
'CN': 'TI Support',
'emailAddress': 'support@ti.com'}
+ self.debug = fdt_util.GetBool(self._node, 'debug', False)
def NonCombinedGetCertificate(self, required):
"""Generate certificate for legacy boot flow
diff --git a/tools/binman/etype/u_boot_spl_pubkey_dtb.py b/tools/binman/etype/u_boot_spl_pubkey_dtb.py
index cb196061de2..3061c4bcdc4 100644
--- a/tools/binman/etype/u_boot_spl_pubkey_dtb.py
+++ b/tools/binman/etype/u_boot_spl_pubkey_dtb.py
@@ -87,6 +87,8 @@ class Entry_u_boot_spl_pubkey_dtb(Entry_blob_dtb):
dir=tools.get_output_dir())\
as pubkey_tdb:
tools.write_file(pubkey_tdb.name, self.GetData())
+ if '/' in self._key_name_hint:
+ self.Raise(f"'{self._key_name_hint}' is a path not a filename")
keyname = tools.get_input_filename(self._key_name_hint + ".crt")
self.fdt_add_pubkey.run(pubkey_tdb.name,
os.path.dirname(keyname),
diff --git a/tools/binman/etype/x509_cert.py b/tools/binman/etype/x509_cert.py
index 25e6808b7f9..b6e8b0b4fb0 100644
--- a/tools/binman/etype/x509_cert.py
+++ b/tools/binman/etype/x509_cert.py
@@ -52,6 +52,7 @@ class Entry_x509_cert(Entry_collection):
self.sysfw_inner_cert_ext_boot_block = None
self.dm_data_ext_boot_block = None
self.firewall_cert_data = None
+ self.debug = False
def ReadNode(self):
super().ReadNode()
@@ -114,7 +115,8 @@ class Entry_x509_cert(Entry_collection):
bootcore=self.bootcore,
bootcore_opts=self.bootcore_opts,
load_addr=self.load_addr,
- sha=self.sha
+ sha=self.sha,
+ debug=self.debug
)
elif type == 'rom-combined':
stdout = self.openssl.x509_cert_rom_combined(
@@ -140,7 +142,8 @@ class Entry_x509_cert(Entry_collection):
hashval_sysfw_data=self.hashval_sysfw_data,
sysfw_inner_cert_ext_boot_block=self.sysfw_inner_cert_ext_boot_block,
dm_data_ext_boot_block=self.dm_data_ext_boot_block,
- bootcore_opts=self.bootcore_opts
+ bootcore_opts=self.bootcore_opts,
+ debug=self.debug
)
if stdout is not None:
data = tools.read_file(output_fname)
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 4cf7dfc8216..8225216fbec 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -84,6 +84,7 @@ FILES_DATA = (b"sorry I'm late\nOh, don't bother apologising, I'm " +
b"sorry you're alive\n")
COMPRESS_DATA = b'compress xxxxxxxxxxxxxxxxxxxxxx data'
COMPRESS_DATA_BIG = COMPRESS_DATA * 2
+MISSING_DATA = b'missing'
REFCODE_DATA = b'refcode'
FSP_M_DATA = b'fsp_m'
FSP_S_DATA = b'fsp_s'
@@ -250,7 +251,7 @@ class TestFunctional(unittest.TestCase):
# ATF and OP_TEE
TestFunctional._MakeInputFile('bl31.elf',
tools.read_file(cls.ElfTestFile('elf_sections')))
- TestFunctional._MakeInputFile('tee.elf',
+ TestFunctional.tee_elf_path = TestFunctional._MakeInputFile('tee.elf',
tools.read_file(cls.ElfTestFile('elf_sections')))
# Newer OP_TEE file in v1 binary format
@@ -514,9 +515,9 @@ class TestFunctional(unittest.TestCase):
return dtb.GetContents()
def _DoReadFileDtb(self, fname, use_real_dtb=False, use_expanded=False,
- verbosity=None, map=False, update_dtb=False,
- entry_args=None, reset_dtbs=True, extra_indirs=None,
- threads=None):
+ verbosity=None, allow_fake_blobs=True, map=False,
+ update_dtb=False, entry_args=None, reset_dtbs=True,
+ extra_indirs=None, threads=None):
"""Run binman and return the resulting image
This runs binman with a given test file and then reads the resulting
@@ -534,6 +535,7 @@ class TestFunctional(unittest.TestCase):
use_expanded: True to use expanded entries where available, e.g.
'u-boot-expanded' instead of 'u-boot'
verbosity: Verbosity level to use (0-3, None=don't set it)
+ allow_fake_blobs: whether binman should fake missing ext blobs
map: True to output map files for the images
update_dtb: Update the offset and size of each entry in the device
tree before packing it into the image
@@ -571,7 +573,7 @@ class TestFunctional(unittest.TestCase):
retcode = self._DoTestFile(fname, map=map, update_dtb=update_dtb,
entry_args=entry_args, use_real_dtb=use_real_dtb,
use_expanded=use_expanded, verbosity=verbosity,
- extra_indirs=extra_indirs,
+ allow_fake_blobs=allow_fake_blobs, extra_indirs=extra_indirs,
threads=threads)
self.assertEqual(0, retcode)
out_dtb_fname = tools.get_output_filename('u-boot.dtb.out')
@@ -4017,7 +4019,7 @@ class TestFunctional(unittest.TestCase):
self.assertEqual({
'image-pos': 0,
'offset': 0,
- 'size': 1890,
+ 'size': 1378,
'u-boot:image-pos': 0,
'u-boot:offset': 0,
@@ -4025,7 +4027,7 @@ class TestFunctional(unittest.TestCase):
'fit:image-pos': 4,
'fit:offset': 4,
- 'fit:size': 1840,
+ 'fit:size': 1328,
'fit/images/kernel:image-pos': 304,
'fit/images/kernel:offset': 300,
@@ -4043,8 +4045,8 @@ class TestFunctional(unittest.TestCase):
'fit/images/fdt-1/u-boot-spl-dtb:offset': 0,
'fit/images/fdt-1/u-boot-spl-dtb:size': 6,
- 'u-boot-nodtb:image-pos': 1844,
- 'u-boot-nodtb:offset': 1844,
+ 'u-boot-nodtb:image-pos': 1332,
+ 'u-boot-nodtb:offset': 1332,
'u-boot-nodtb:size': 46,
}, props)
@@ -5210,13 +5212,15 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
def testExtblobList(self):
"""Test an image with an external blob list"""
- data = self._DoReadFile('215_blob_ext_list.dts')
- self.assertEqual(REFCODE_DATA + FSP_M_DATA, data)
+ data = self._DoReadFileDtb('215_blob_ext_list.dts',
+ allow_fake_blobs=False)
+ self.assertEqual(REFCODE_DATA + FSP_M_DATA, data[0])
def testExtblobListMissing(self):
"""Test an image with a missing external blob"""
with self.assertRaises(ValueError) as e:
- self._DoReadFile('216_blob_ext_list_missing.dts')
+ self._DoReadFileDtb('216_blob_ext_list_missing.dts',
+ allow_fake_blobs=False)
self.assertIn("Filename 'missing-file' not found in input path",
str(e.exception))
@@ -5224,7 +5228,7 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
"""Test an image with an missing external blob that is allowed"""
with terminal.capture() as (stdout, stderr):
self._DoTestFile('216_blob_ext_list_missing.dts',
- allow_missing=True)
+ allow_missing=True, allow_fake_blobs=False)
err = stderr.getvalue()
self.assertRegex(err, "Image 'image'.*missing.*: blob-ext")
@@ -5766,10 +5770,10 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
def testFitSplitElfMissing(self):
- """Test an split-elf FIT with a missing ELF file"""
+ """Test an split-elf FIT with a missing ELF file. Don't fake the file."""
if not elf.ELF_TOOLS:
self.skipTest('Python elftools not available')
- out, err = self.checkFitSplitElf(allow_missing=True)
+ out, err = self.checkFitSplitElf(allow_missing=True, allow_fake_blobs=False)
self.assertRegex(
err,
"Image '.*' is missing external blobs and is non-functional: .*")
@@ -6458,16 +6462,18 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
def testAbsent(self):
"""Check handling of absent entries"""
data = self._DoReadFile('262_absent.dts')
- self.assertEqual(U_BOOT_DATA + U_BOOT_IMG_DATA, data)
+ self.assertEqual(U_BOOT_DATA + b'aa' + U_BOOT_IMG_DATA, data)
- def testPackTeeOsOptional(self):
- """Test that an image with an optional TEE binary can be created"""
+ def testPackTeeOsElf(self):
+ """Test that an image with a TEE elf binary can be created"""
entry_args = {
'tee-os-path': 'tee.elf',
}
+ tee_path = self.tee_elf_path
data = self._DoReadFileDtb('263_tee_os_opt.dts',
entry_args=entry_args)[0]
- self.assertEqual(U_BOOT_DATA + U_BOOT_IMG_DATA, data)
+ self.assertEqual(U_BOOT_DATA + tools.read_file(tee_path) +
+ U_BOOT_IMG_DATA, data)
def checkFitTee(self, dts, tee_fname):
"""Check that a tee-os entry works and returns data
@@ -6512,6 +6518,9 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
self.assertRegex(
err,
"Image '.*' is missing optional external blobs but is still functional: tee-os")
+ self.assertNotRegex(
+ err,
+ "Image '.*' has faked external blobs and is non-functional: tee-os")
def testFitTeeOsOptionalFitBad(self):
"""Test an image with a FIT with an optional OP-TEE binary"""
@@ -6537,7 +6546,15 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
"Node '/binman/fit/images/@tee-SEQ/tee-os': Invalid OP-TEE file: size mismatch (expected 0x4, have 0xe)",
str(exc.exception))
- def testExtblobOptional(self):
+ def testExtblobMissingOptional(self):
+ """Test an image with an external blob that is optional"""
+ with terminal.capture() as (stdout, stderr):
+ data = self._DoReadFileDtb('266_blob_ext_opt.dts',
+ allow_fake_blobs=False)[0]
+ self.assertEqual(REFCODE_DATA, data)
+ self.assertNotIn(MISSING_DATA, data)
+
+ def testExtblobFakedOptional(self):
"""Test an image with an external blob that is optional"""
with terminal.capture() as (stdout, stderr):
data = self._DoReadFile('266_blob_ext_opt.dts')
@@ -6546,6 +6563,9 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
self.assertRegex(
err,
"Image '.*' is missing optional external blobs but is still functional: missing")
+ self.assertNotRegex(
+ err,
+ "Image '.*' has faked external blobs and is non-functional: missing")
def testSectionInner(self):
"""Test an inner section with a size"""
@@ -6726,7 +6746,7 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
node = dtb.GetNode('/configurations/conf-missing-tee-1')
self.assertEqual('atf-1', node.props['firmware'].value)
- self.assertEqual(['u-boot', 'atf-2'],
+ self.assertEqual(['u-boot', 'tee', 'atf-2'],
fdt_util.GetStringList(node, 'loadables'))
def testTooldir(self):
@@ -7290,6 +7310,13 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
tools.to_bytes(''.join(node.props['key'].value)))
self.assertNotIn('key-source', node.props)
+ def testKeyNameHintIsPathSplPubkeyDtb(self):
+ """Test that binman errors out on key-name-hint being a path"""
+ with self.assertRaises(ValueError) as e:
+ self._DoReadFile('348_key_name_hint_dir_spl_pubkey_dtb.dts')
+ self.assertIn(
+ 'Node \'/binman/u-boot-spl-pubkey-dtb\': \'keys/key\' is a path not a filename',
+ str(e.exception))
def testSplPubkeyDtb(self):
"""Test u_boot_spl_pubkey_dtb etype"""
@@ -7963,6 +7990,24 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
entry_args=entry_args,
extra_indirs=[test_subdir])[0]
+ def testKeyNameHintIsPathSimpleFit(self):
+ """Test that binman errors out on key-name-hint being a path"""
+ if not elf.ELF_TOOLS:
+ self.skipTest('Python elftools not available')
+ entry_args = {
+ 'of-list': 'test-fdt1',
+ 'default-dt': 'test-fdt1',
+ 'atf-bl31-path': 'bl31.elf',
+ }
+ test_subdir = os.path.join(self._indir, TEST_FDT_SUBDIR)
+ with self.assertRaises(ValueError) as e:
+ self._DoReadFileDtb(
+ '347_key_name_hint_dir_fit_signature.dts',
+ entry_args=entry_args,
+ extra_indirs=[test_subdir])
+ self.assertIn(
+ 'Node \'/binman/fit\': \'keys/rsa2048\' is a path not a filename',
+ str(e.exception))
def testSimpleFitEncryptedData(self):
"""Test an image with a FIT containing data to be encrypted"""
@@ -8020,5 +8065,29 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
self._DoTestFile('346_remove_template.dts',
force_missing_bintools='openssl',)
+ def testBootphPropagation(self):
+ """Test that bootph-* properties are propagated correctly to supernodes"""
+ _, _, _, out_dtb_fname = self._DoReadFileDtb(
+ '347_bootph_prop.dts', use_real_dtb=True, update_dtb=True)
+ dtb = fdt.Fdt(out_dtb_fname)
+ dtb.Scan()
+ root = dtb.GetRoot()
+ parent_node = root.FindNode('dummy-parent')
+ subnode1 = parent_node.FindNode('subnode-1')
+ subnode2 = subnode1.FindNode('subnode-2')
+ subnode3 = subnode1.FindNode('subnode-3')
+ subnode4 = subnode3.FindNode('subnode-4')
+
+ self.assertIn('bootph-some-ram', subnode1.props,
+ "Child node is missing 'bootph-some-ram' property")
+ self.assertIn('bootph-all', subnode1.props,
+ "Child node is missing 'bootph-all' property")
+ self.assertIn('bootph-some-ram', parent_node.props,
+ "Parent node is missing 'bootph-some-ram' property")
+ self.assertIn('bootph-all', parent_node.props,
+ "Parent node is missing 'bootph-all' property")
+ self.assertEqual(len(subnode4.props), 0,
+ "subnode shouldn't have any properties")
+
if __name__ == "__main__":
unittest.main()
diff --git a/tools/binman/image.py b/tools/binman/image.py
index 24ce0af7c72..698cfa4148e 100644
--- a/tools/binman/image.py
+++ b/tools/binman/image.py
@@ -183,6 +183,8 @@ class Image(section.Entry_section):
fname = tools.get_output_filename(self._filename)
tout.info("Writing image to '%s'" % fname)
with open(fname, 'wb') as fd:
+ # For final image, don't write absent blobs to file
+ self.drop_absent_optional()
data = self.GetPaddedData()
fd.write(data)
tout.info("Wrote %#x bytes" % len(data))
diff --git a/tools/binman/missing-blob-help b/tools/binman/missing-blob-help
index ab0023eb9fb..d2ed35bef4d 100644
--- a/tools/binman/missing-blob-help
+++ b/tools/binman/missing-blob-help
@@ -14,15 +14,6 @@ atf-bl31-sunxi:
Please read the section on ARM Trusted Firmware (ATF) in
board/sunxi/README.sunxi64
-scp-sunxi:
-SCP firmware is required for system suspend, but is otherwise optional.
-Please read the section on SCP firmware in board/sunxi/README.sunxi64
-
-iot2050-seboot:
-See the documentation for IOT2050 board. Your image is missing SEBoot
-which is mandatory for board startup. Prebuilt SEBoot located at
-meta-iot2050/tree/master/recipes-bsp/u-boot/files/prebuild/seboot_pg*.bin.
-
iot2050-otpcmd:
See the documentation for IOT2050 board. Your image is missing OTP command data
block which is used for provisioning the customer keys to the board.
@@ -31,22 +22,62 @@ meta-iot2050/tree/master/recipes-bsp/secure-boot-otp-provisioning/files/make-otp
for how to generate this binary. If you are not using secure boot or do not
intend to provision the keys, disable CONFIG_IOT2050_EMBED_OTPCMD.
+iot2050-seboot:
+See the documentation for IOT2050 board. Your image is missing SEBoot
+which is mandatory for board startup. Prebuilt SEBoot located at
+meta-iot2050/tree/master/recipes-bsp/u-boot/files/prebuild/seboot_pg*.bin.
+
k3-rti-wdt-firmware:
If CONFIG_WDT_K3_RTI_LOAD_FW is enabled, a firmware image is needed for
the R5F core(s) to trigger the system reset. One possible source is
https://github.com/siemens/k3-rti-wdt.
+opensbi:
+See the documentation for your board. The OpenSBI git repo is at
+https://github.com/riscv/opensbi.git
+You may need to build fw_dynamic.bin first and re-build u-boot with
+OPENSBI=/path/to/fw_dynamic.bin
+
rockchip-tpl:
An external TPL is required to initialize DRAM. Get the external TPL
binary and build with ROCKCHIP_TPL=/path/to/ddr.bin. One possible source
for the external TPL binary is https://github.com/rockchip-linux/rkbin.
+scp-sunxi:
+SCP firmware is required for system suspend, but is otherwise optional.
+Please read the section on SCP firmware in board/sunxi/README.sunxi64
+
+sysfw-inner-cert:
+You are missing the inner certificate for TI's Foundational Security (TIFS)
+firmware which is critical to authenticating the TIFS firmware during boot.
+HS-FS and HS-SE parts will not boot without this certificate.
+
+Have a look at your board's documentation to find and include the latest
+TIFS certificate blobs and how to include them in the build.
+
+ https://docs.u-boot.org/en/latest/board/ti/k3.html
+
tee-os:
See the documentation for your board. You may need to build Open Portable
Trusted Execution Environment (OP-TEE) and build with TEE=/path/to/tee.bin
-opensbi:
-See the documentation for your board. The OpenSBI git repo is at
-https://github.com/riscv/opensbi.git
-You may need to build fw_dynamic.bin first and re-build u-boot with
-OPENSBI=/path/to/fw_dynamic.bin
+ti-dm:
+You are missing TI's Device Management (DM) firmware which is critical to
+provide resource and power management services for your board. Your board
+will not boot without this firmware.
+
+Have a look at your board's documentation to find the latest version of
+the DM firmware binary and how to include it in the build.
+
+ https://docs.u-boot.org/en/latest/board/ti/k3.html
+
+ti-fs-enc.bin:
+You are missing TI's Foundational Security (TIFS) firmware which is
+critical to provide foundational security services like authenticated boot,
+and firewall management for the SoC. Your board will not boot without
+this firmware.
+
+Have a look at your board's documentation to find the latest version of the
+TIFS firmware binary and how to include them in the build.
+
+ https://docs.u-boot.org/en/latest/board/ti/k3.html
diff --git a/tools/binman/test/170_fit_fdt.dts b/tools/binman/test/170_fit_fdt.dts
index 0197ffd1597..4b1e9b41ec0 100644
--- a/tools/binman/test/170_fit_fdt.dts
+++ b/tools/binman/test/170_fit_fdt.dts
@@ -15,6 +15,20 @@
fit,fdt-list = "of-list";
images {
+ atf {
+ description = "atf firmware";
+ type = "firmware";
+ compression = "none";
+ load = <00000000>;
+ entry = <00000000>;
+ };
+ uboot {
+ description = "U-Boot firmware";
+ type = "firmware";
+ compression = "none";
+ load = <00000000>;
+ entry = <00000000>;
+ };
kernel {
description = "Vanilla Linux kernel";
type = "kernel";
diff --git a/tools/binman/test/220_fit_subentry_bintool.dts b/tools/binman/test/220_fit_subentry_bintool.dts
index 6e29d41eeb3..b1d8fb0feae 100644
--- a/tools/binman/test/220_fit_subentry_bintool.dts
+++ b/tools/binman/test/220_fit_subentry_bintool.dts
@@ -12,7 +12,7 @@
#address-cells = <1>;
images {
- test {
+ kernel {
description = "Something using a bintool";
type = "kernel";
arch = "arm";
diff --git a/tools/binman/test/223_fit_fdt_oper.dts b/tools/binman/test/223_fit_fdt_oper.dts
index e630165acf4..cb3b31e36f6 100644
--- a/tools/binman/test/223_fit_fdt_oper.dts
+++ b/tools/binman/test/223_fit_fdt_oper.dts
@@ -15,6 +15,20 @@
fit,fdt-list = "of-list";
images {
+ atf {
+ description = "atf firmware";
+ type = "firmware";
+ compression = "none";
+ load = <00000000>;
+ entry = <00000000>;
+ };
+ uboot {
+ description = "U-Boot firmware";
+ type = "firmware";
+ compression = "none";
+ load = <00000000>;
+ entry = <00000000>;
+ };
kernel {
description = "Vanilla Linux kernel";
type = "kernel";
diff --git a/tools/binman/test/284_fit_fdt_list.dts b/tools/binman/test/284_fit_fdt_list.dts
index 8885313f5b8..70cdb326708 100644
--- a/tools/binman/test/284_fit_fdt_list.dts
+++ b/tools/binman/test/284_fit_fdt_list.dts
@@ -15,6 +15,20 @@
fit,fdt-list-val = "test-fdt1", "test-fdt2";
images {
+ atf {
+ description = "atf firmware";
+ type = "firmware";
+ compression = "none";
+ load = <00000000>;
+ entry = <00000000>;
+ };
+ uboot {
+ description = "U-Boot firmware";
+ type = "firmware";
+ compression = "none";
+ load = <00000000>;
+ entry = <00000000>;
+ };
kernel {
description = "Vanilla Linux kernel";
type = "kernel";
diff --git a/tools/binman/test/333_fit_fdt_dir.dts b/tools/binman/test/333_fit_fdt_dir.dts
index aa778451a4b..71971de4232 100644
--- a/tools/binman/test/333_fit_fdt_dir.dts
+++ b/tools/binman/test/333_fit_fdt_dir.dts
@@ -15,6 +15,20 @@
fit,fdt-list-dir = "fdts";
images {
+ atf {
+ description = "atf firmware";
+ type = "firmware";
+ compression = "none";
+ load = <00000000>;
+ entry = <00000000>;
+ };
+ uboot {
+ description = "U-Boot firmware";
+ type = "firmware";
+ compression = "none";
+ load = <00000000>;
+ entry = <00000000>;
+ };
kernel {
description = "Vanilla Linux kernel";
type = "kernel";
diff --git a/tools/binman/test/334_fit_fdt_compat.dts b/tools/binman/test/334_fit_fdt_compat.dts
index 3bf45c710db..bf1b5a4a94a 100644
--- a/tools/binman/test/334_fit_fdt_compat.dts
+++ b/tools/binman/test/334_fit_fdt_compat.dts
@@ -15,6 +15,20 @@
fit,fdt-list = "of-list";
images {
+ atf {
+ description = "atf firmware";
+ type = "firmware";
+ compression = "none";
+ load = <00000000>;
+ entry = <00000000>;
+ };
+ uboot {
+ description = "U-Boot firmware";
+ type = "firmware";
+ compression = "none";
+ load = <00000000>;
+ entry = <00000000>;
+ };
kernel {
description = "Vanilla Linux kernel";
type = "kernel";
diff --git a/tools/binman/test/335_fit_fdt_phase.dts b/tools/binman/test/335_fit_fdt_phase.dts
index f8d0740a394..c20bcad651a 100644
--- a/tools/binman/test/335_fit_fdt_phase.dts
+++ b/tools/binman/test/335_fit_fdt_phase.dts
@@ -15,6 +15,20 @@
fit,fdt-list = "of-list";
images {
+ atf {
+ description = "atf firmware";
+ type = "firmware";
+ compression = "none";
+ load = <00000000>;
+ entry = <00000000>;
+ };
+ uboot {
+ description = "U-Boot firmware";
+ type = "firmware";
+ compression = "none";
+ load = <00000000>;
+ entry = <00000000>;
+ };
kernel {
description = "Vanilla Linux kernel";
type = "kernel";
diff --git a/tools/binman/test/345_fit_fdt_name.dts b/tools/binman/test/345_fit_fdt_name.dts
index 631a8e5f59b..0ef2e1934a0 100644
--- a/tools/binman/test/345_fit_fdt_name.dts
+++ b/tools/binman/test/345_fit_fdt_name.dts
@@ -15,6 +15,20 @@
fit,fdt-list = "of-list";
images {
+ atf {
+ description = "atf firmware";
+ type = "firmware";
+ compression = "none";
+ load = <00000000>;
+ entry = <00000000>;
+ };
+ uboot {
+ description = "U-Boot firmware";
+ type = "firmware";
+ compression = "none";
+ load = <00000000>;
+ entry = <00000000>;
+ };
kernel {
description = "Vanilla Linux kernel";
type = "kernel";
diff --git a/tools/binman/test/347_bootph_prop.dts b/tools/binman/test/347_bootph_prop.dts
new file mode 100644
index 00000000000..91d4e4ad600
--- /dev/null
+++ b/tools/binman/test/347_bootph_prop.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+/ {
+ dummy-parent {
+ subnode-1 {
+ subnode-2 {
+ bootph-all;
+ };
+ subnode-3 {
+ bootph-some-ram;
+ subnode-4 {
+ };
+ };
+ };
+ };
+
+ binman: binman {
+ };
+};
+
diff --git a/tools/binman/test/347_key_name_hint_dir_fit_signature.dts b/tools/binman/test/347_key_name_hint_dir_fit_signature.dts
new file mode 100644
index 00000000000..96e2126dadb
--- /dev/null
+++ b/tools/binman/test/347_key_name_hint_dir_fit_signature.dts
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ fit {
+ description = "test desc";
+ #address-cells = <1>;
+ fit,fdt-list = "of-list";
+ fit,sign;
+
+ images {
+ u-boot {
+ description = "test u-boot";
+ type = "standalone";
+ arch = "arm64";
+ os = "u-boot";
+ compression = "none";
+ load = <0x00000000>;
+ entry = <0x00000000>;
+
+ u-boot-nodtb {
+ };
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "keys/rsa2048";
+ };
+ };
+ @atf-SEQ {
+ fit,operation = "split-elf";
+ description = "test tf-a";
+ type = "firmware";
+ arch = "arm64";
+ os = "arm-trusted-firmware";
+ compression = "none";
+ fit,load;
+ fit,entry;
+ fit,data;
+
+ atf-bl31 {
+ };
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "keys/rsa2048";
+ };
+ };
+ @fdt-SEQ {
+ description = "test fdt";
+ type = "flat_dt";
+ compression = "none";
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "keys/rsa2048";
+ };
+ };
+ };
+
+ configurations {
+ default = "@conf-uboot-DEFAULT-SEQ";
+ @conf-uboot-SEQ {
+ description = "uboot config";
+ fdt = "fdt-SEQ";
+ fit,firmware = "u-boot";
+ fit,loadables;
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "keys/rsa2048";
+ sign-images = "firmware", "loadables", "fdt";
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/348_key_name_hint_dir_spl_pubkey_dtb.dts b/tools/binman/test/348_key_name_hint_dir_spl_pubkey_dtb.dts
new file mode 100644
index 00000000000..85ebd58b6c0
--- /dev/null
+++ b/tools/binman/test/348_key_name_hint_dir_spl_pubkey_dtb.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ u-boot-spl-pubkey-dtb {
+ algo = "sha384,rsa4096";
+ required = "conf";
+ key-name-hint = "keys/key";
+ };
+ };
+};
diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py
index 6538a3d296f..9516e25e215 100644
--- a/tools/buildman/builder.py
+++ b/tools/buildman/builder.py
@@ -631,10 +631,13 @@ class Builder:
Args:
commit_upto: Commit number to use (0..self.count-1)
target: Target name
+
+ Return:
+ str: Output directory to use, or '' if None
"""
output_dir = self.get_output_dir(commit_upto)
if self.work_in_output:
- return output_dir
+ return output_dir or ''
return os.path.join(output_dir, target)
def get_done_file(self, commit_upto, target):
@@ -1683,7 +1686,7 @@ class Builder:
"""
thread_dir = self.get_thread_dir(thread_num)
builderthread.mkdir(thread_dir)
- git_dir = os.path.join(thread_dir, '.git')
+ git_dir = os.path.join(thread_dir, '.git') if thread_dir else None
# Create a worktree or a git repo clone for this thread if it
# doesn't already exist
diff --git a/tools/buildman/builderthread.py b/tools/buildman/builderthread.py
index b4cb66397bb..371708c8a98 100644
--- a/tools/buildman/builderthread.py
+++ b/tools/buildman/builderthread.py
@@ -31,12 +31,14 @@ def mkdir(dirname, parents=False):
"""Make a directory if it doesn't already exist.
Args:
- dirname (str): Directory to create
+ dirname (str): Directory to create, or None to do nothing
parents (bool): True to also make parent directories
Raises:
OSError: File already exists
"""
+ if not dirname or os.path.exists(dirname):
+ return
try:
if parents:
os.makedirs(dirname)
@@ -45,8 +47,8 @@ def mkdir(dirname, parents=False):
except OSError as err:
if err.errno == errno.EEXIST:
if os.path.realpath('.') == os.path.realpath(dirname):
- print(f"Cannot create the current working directory '{dirname}'!")
- sys.exit(1)
+ raise ValueError(
+ f"Cannot create the current working directory '{dirname}'!")
else:
raise
@@ -55,7 +57,7 @@ def _remove_old_outputs(out_dir):
"""Remove any old output-target files
Args:
- out_dir (str): Output directory for the build
+ out_dir (str): Output directory for the build, or None for current dir
Since we use a build directory that was previously used by another
board, it may have produced an SPL image. If we don't remove it (i.e.
@@ -63,7 +65,7 @@ def _remove_old_outputs(out_dir):
output of this build, even if it does not produce SPL images.
"""
for elf in BASE_ELF_FILENAMES:
- fname = os.path.join(out_dir, elf)
+ fname = os.path.join(out_dir or '', elf)
if os.path.exists(fname):
os.remove(fname)
@@ -191,9 +193,11 @@ class BuilderThread(threading.Thread):
Args:
brd (Board): Board to create arguments for
- out_dir (str): Path to output directory containing the files
+ out_dir (str): Path to output directory containing the files, or
+ or None to not use a separate output directory
out_rel_dir (str): Output directory relative to the current dir
- work_dir (str): Directory to which the source will be checked out
+ work_dir (str): Directory to which the source will be checked out,
+ or None to use current directory
commit_upto (int): Commit number to build (0...n-1)
Returns:
@@ -204,22 +208,22 @@ class BuilderThread(threading.Thread):
"""
args = []
cwd = work_dir
- src_dir = os.path.realpath(work_dir)
- if not self.builder.in_tree:
- if commit_upto is None:
- # In this case we are building in the original source directory
- # (i.e. the current directory where buildman is invoked. The
- # output directory is set to this thread's selected work
- # directory.
- #
- # Symlinks can confuse U-Boot's Makefile since we may use '..'
- # in our path, so remove them.
+ src_dir = os.path.realpath(work_dir) if work_dir else os.getcwd()
+ if commit_upto is None:
+ # In this case we are building in the original source directory
+ # (i.e. the current directory where buildman is invoked. The
+ # output directory is set to this thread's selected work
+ # directory.
+ #
+ # Symlinks can confuse U-Boot's Makefile since we may use '..'
+ # in our path, so remove them.
+ if out_dir:
real_dir = os.path.realpath(out_dir)
args.append(f'O={real_dir}')
- cwd = None
- src_dir = os.getcwd()
- else:
- args.append(f'O={out_rel_dir}')
+ cwd = None
+ src_dir = os.getcwd()
+ elif out_rel_dir:
+ args.append(f'O={out_rel_dir}')
if self.builder.verbose_build:
args.append('V=1')
else:
@@ -397,7 +401,8 @@ class BuilderThread(threading.Thread):
config_only (bool): Only configure the source, do not build it
adjust_cfg (list of str): See the cfgutil module and run_commit()
commit (Commit): Commit only being built
- out_dir (str): Output directory for the build
+ out_dir (str): Output directory for the build, or None to use
+ current
out_rel_dir (str): Output directory relatie to the current dir
result (CommandResult): Previous result
@@ -409,7 +414,8 @@ class BuilderThread(threading.Thread):
"""
# Set up the environment and command line
env = self.builder.make_environment(self.toolchain)
- mkdir(out_dir)
+ if out_dir and not os.path.exists(out_dir):
+ mkdir(out_dir)
args, cwd, src_dir = self._build_args(brd, out_dir, out_rel_dir,
work_dir, commit_upto)
@@ -419,7 +425,7 @@ class BuilderThread(threading.Thread):
_remove_old_outputs(out_dir)
# If we need to reconfigure, do that now
- cfg_file = os.path.join(out_dir, '.config')
+ cfg_file = os.path.join(out_dir or '', '.config')
cmd_list = []
if do_config or adjust_cfg:
result = self._reconfigure(
@@ -627,7 +633,7 @@ class BuilderThread(threading.Thread):
# Extract the environment from U-Boot and dump it out
cmd = [f'{self.toolchain.cross}objcopy', '-O', 'binary',
'-j', '.rodata.default_environment',
- 'env/built-in.o', 'uboot.env']
+ 'env/built-in.a', 'uboot.env']
command.run_one(*cmd, capture=True, capture_stderr=True,
cwd=result.out_dir, raise_on_error=False, env=env)
if not work_in_output:
diff --git a/tools/buildman/buildman.rst b/tools/buildman/buildman.rst
index 5fa7b277cb8..8c45a841024 100644
--- a/tools/buildman/buildman.rst
+++ b/tools/buildman/buildman.rst
@@ -1333,6 +1333,14 @@ To build a particular target, rather than the default U-Boot target, use the
`--target` option. This is unlikely to be useful unless you are building a
single board.
+Buildman normally builds out-of-tree, meaning that the source directory is not
+disturbed by the build. Use `-i` to do an in-tree build instead. Note that this
+does not affect the source directory, since buildman creates a separate git
+'worktree' for each board. This means that it is possible to do an in-tree
+build of an entire branch, or even a 'current source' build for multiple boards.
+As a special case, you can use `-wi` to do an in-tree build in the current
+directory.
+
Build summary
-------------
diff --git a/tools/buildman/control.py b/tools/buildman/control.py
index 4c9489126c1..4dedd333551 100644
--- a/tools/buildman/control.py
+++ b/tools/buildman/control.py
@@ -390,7 +390,7 @@ def get_boards_obj(output_dir, regen_board_list, maintainer_check, full_check,
read it in.
Args:
- output_dir (str): Output directory to use
+ output_dir (str): Output directory to use, or None to use current dir
regen_board_list (bool): True to just regenerate the board list
maintainer_check (bool): True to just run a maintainer check
full_check (bool): True to just run a full check of Kconfig and
@@ -414,9 +414,9 @@ def get_boards_obj(output_dir, regen_board_list, maintainer_check, full_check,
return 2
return 0
- if not os.path.exists(output_dir):
+ if output_dir and not os.path.exists(output_dir):
os.makedirs(output_dir)
- board_file = os.path.join(output_dir, 'boards.cfg')
+ board_file = os.path.join(output_dir or '', 'boards.cfg')
if regen_board_list and regen_board_list != '-':
board_file = regen_board_list
@@ -501,7 +501,7 @@ def adjust_args(args, series, selected):
def setup_output_dir(output_dir, work_in_output, branch, no_subdirs, col,
- clean_dir):
+ in_tree, clean_dir):
"""Set up the output directory
Args:
@@ -509,6 +509,7 @@ def setup_output_dir(output_dir, work_in_output, branch, no_subdirs, col,
work_in_output (bool): True to work in the output directory
branch (str): Name of branch to build, or None if none
no_subdirs (bool): True to put the output in the top-level output dir
+ in_tree (bool): True if doing an in-tree build
clean_dir: Used for tests only, indicates that the existing output_dir
should be removed before starting the build
@@ -516,9 +517,11 @@ def setup_output_dir(output_dir, work_in_output, branch, no_subdirs, col,
str: Updated output directory pathname
"""
if not output_dir:
- if work_in_output:
- sys.exit(col.build(col.RED, '-w requires that you specify -o'))
output_dir = '..'
+ if work_in_output:
+ if not in_tree:
+ sys.exit(col.build(col.RED, '-w requires that you specify -o'))
+ output_dir = None
if branch and not no_subdirs:
# As a special case allow the board directory to be placed in the
# output directory itself rather than any subdirectory.
@@ -751,7 +754,7 @@ def do_buildman(args, toolchains=None, make_func=None, brds=None,
output_dir = setup_output_dir(
args.output_dir, args.work_in_output, args.branch,
- args.no_subdirs, col, clean_dir)
+ args.no_subdirs, col, args.in_tree, clean_dir)
# Work out what subset of the boards we are building
if not brds:
diff --git a/tools/fit_image.c b/tools/fit_image.c
index caed8d5f901..8717dc9a3b1 100644
--- a/tools/fit_image.c
+++ b/tools/fit_image.c
@@ -24,6 +24,65 @@
static struct legacy_img_hdr header;
+static int fit_estimate_hash_sig_size(struct image_tool_params *params, const char *fname)
+{
+ bool signing = IMAGE_ENABLE_SIGN && (params->keydir || params->keyfile);
+ struct stat sbuf;
+ void *fdt;
+ int fd;
+ int estimate = 0;
+ int depth, noffset;
+ const char *name;
+
+ fd = mmap_fdt(params->cmdname, fname, 0, &fdt, &sbuf, false, true);
+ if (fd < 0)
+ return -EIO;
+
+ /*
+ * Walk the FIT image, looking for nodes named hash* and
+ * signature*. Since the interesting nodes are subnodes of an
+ * image or configuration node, we are only interested in
+ * those at depth exactly 3.
+ *
+ * The estimate for a hash node is based on a sha512 digest
+ * being 64 bytes, with another 64 bytes added to account for
+ * fdt structure overhead (the tags and the name of the
+ * "value" property).
+ *
+ * The estimate for a signature node is based on an rsa4096
+ * signature being 512 bytes, with another 512 bytes to
+ * account for fdt overhead and the various other properties
+ * (hashed-nodes etc.) that will also be filled in.
+ *
+ * One could try to be more precise in the estimates by
+ * looking at the "algo" property and, in the case of
+ * configuration signatures, the sign-images property. Also,
+ * when signing an already created FIT image, the hash nodes
+ * already have properly sized value properties, so one could
+ * also take pre-existence of "value" properties in hash nodes
+ * into account. But this rather simple approach should work
+ * well enough in practice.
+ */
+ for (depth = 0, noffset = fdt_next_node(fdt, 0, &depth);
+ noffset >= 0 && depth > 0;
+ noffset = fdt_next_node(fdt, noffset, &depth)) {
+ if (depth != 3)
+ continue;
+
+ name = fdt_get_name(fdt, noffset, NULL);
+ if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME)))
+ estimate += 128;
+
+ if (signing && !strncmp(name, FIT_SIG_NODENAME, strlen(FIT_SIG_NODENAME)))
+ estimate += 1024;
+ }
+
+ munmap(fdt, sbuf.st_size);
+ close(fd);
+
+ return estimate;
+}
+
static int fit_add_file_data(struct image_tool_params *params, size_t size_inc,
const char *tmpfile)
{
@@ -627,6 +686,7 @@ static int fit_import_data(struct image_tool_params *params, const char *fname)
struct stat sbuf;
int ret;
int images;
+ int confs;
int node;
fd = mmap_fdt(params->cmdname, fname, 0, &old_fdt, &sbuf, false, false);
@@ -695,6 +755,43 @@ static int fit_import_data(struct image_tool_params *params, const char *fname)
}
}
+ confs = fdt_path_offset(fdt, FIT_CONFS_PATH);
+ static const char * const props[] = { FIT_KERNEL_PROP,
+ FIT_RAMDISK_PROP,
+ FIT_FDT_PROP,
+ FIT_LOADABLE_PROP,
+ FIT_FPGA_PROP,
+ FIT_FIRMWARE_PROP,
+ FIT_SCRIPT_PROP};
+
+ fdt_for_each_subnode(node, fdt, confs) {
+ const char *conf_name = fdt_get_name(fdt, node, NULL);
+
+ for (int i = 0; i < ARRAY_SIZE(props); i++) {
+ int count = fdt_stringlist_count(fdt, node, props[i]);
+
+ if (count < 0)
+ continue;
+
+ for (int j = 0; j < count; j++) {
+ const char *img_name =
+ fdt_stringlist_get(fdt, node, props[i], j, NULL);
+ if (!img_name || !*img_name)
+ continue;
+
+ int img = fdt_subnode_offset(fdt, images, img_name);
+
+ if (img < 0) {
+ fprintf(stderr,
+ "Error: configuration '%s' references undefined image '%s' in property '%s'\n",
+ conf_name, img_name, props[i]);
+ ret = FDT_ERR_NOTFOUND;
+ goto err_munmap;
+ }
+ }
+ }
+ }
+
munmap(old_fdt, sbuf.st_size);
/* Close the old fd so we can re-use it. */
@@ -750,7 +847,7 @@ static int fit_handle_file(struct image_tool_params *params)
char bakfile[MKIMAGE_MAX_TMPFILE_LEN + 4] = {0};
char cmd[MKIMAGE_MAX_DTC_CMDLINE_LEN];
size_t size_inc;
- int ret;
+ int ret = EXIT_FAILURE;
/* Flattened Image Tree (FIT) format handling */
debug ("FIT format handling\n");
@@ -806,16 +903,16 @@ static int fit_handle_file(struct image_tool_params *params)
rename(tmpfile, bakfile);
/*
- * Set hashes for images in the blob. Unfortunately we may need more
- * space in either FDT, so keep trying until we succeed.
- *
- * Note: this is pretty inefficient for signing, since we must
- * calculate the signature every time. It would be better to calculate
- * all the data and then store it in a separate step. However, this
- * would be considerably more complex to implement. Generally a few
- * steps of this loop is enough to sign with several keys.
+ * Set hashes for images in the blob and compute
+ * signatures. We do an attempt at estimating the expected
+ * extra size, but just in case that is not sufficient, keep
+ * trying adding 1K, with a reasonable upper bound of 64K
+ * total, until we succeed.
*/
- for (size_inc = 0; size_inc < 64 * 1024; size_inc += 1024) {
+ size_inc = fit_estimate_hash_sig_size(params, bakfile);
+ if (size_inc < 0)
+ goto err_system;
+ do {
if (copyfile(bakfile, tmpfile) < 0) {
printf("Can't copy %s to %s\n", bakfile, tmpfile);
ret = -EIO;
@@ -824,7 +921,8 @@ static int fit_handle_file(struct image_tool_params *params)
ret = fit_add_file_data(params, size_inc, tmpfile);
if (!ret || ret != -ENOSPC)
break;
- }
+ size_inc += 1024;
+ } while (size_inc < 64 * 1024);
if (ret) {
fprintf(stderr, "%s Can't add hashes to FIT blob: %d\n",
@@ -854,7 +952,7 @@ static int fit_handle_file(struct image_tool_params *params)
err_system:
unlink(tmpfile);
unlink(bakfile);
- return -1;
+ return ret;
}
/**
diff --git a/tools/image-host.c b/tools/image-host.c
index a9b86902763..21dd7f2d922 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -19,7 +19,7 @@
#include <openssl/evp.h>
#endif
-#if CONFIG_IS_ENABLED(IMAGE_PRE_LOAD)
+#if CONFIG_IS_ENABLED(IMAGE_PRE_LOAD) && CONFIG_IS_ENABLED(LIBCRYPTO)
#include <openssl/rsa.h>
#include <openssl/err.h>
#endif
@@ -1416,7 +1416,7 @@ int fit_check_sign(const void *fit, const void *key,
}
#endif
-#if CONFIG_IS_ENABLED(IMAGE_PRE_LOAD)
+#if CONFIG_IS_ENABLED(IMAGE_PRE_LOAD) && CONFIG_IS_ENABLED(LIBCRYPTO)
/**
* rsa_verify_openssl() - Verify a signature against some data with openssl API
*
diff --git a/tools/imx8image.c b/tools/imx8image.c
index a333ded46e2..cad55fd3cf2 100644
--- a/tools/imx8image.c
+++ b/tools/imx8image.c
@@ -1146,7 +1146,7 @@ int imx8image_copy_image(int outfd, struct image_tool_params *mparams)
fprintf(stdout, "CONTAINER SW VERSION:\t0x%04x\n", sw_version);
build_container(soc, sector_size, emmc_fastboot,
- img_sp, false, fuse_version, sw_version, outfd);
+ img_sp, dcd_skip, fuse_version, sw_version, outfd);
return 0;
}
diff --git a/tools/mkimage.c b/tools/mkimage.c
index 2954626a283..361711c53b2 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -519,8 +519,13 @@ int main(int argc, char **argv)
*/
retval = tparams->fflag_handle(&params);
- if (retval != EXIT_SUCCESS)
+ if (retval != EXIT_SUCCESS) {
+ if (retval == FDT_ERR_NOTFOUND) {
+ // Already printed error, exit cleanly
+ exit(EXIT_FAILURE);
+ }
usage("Bad parameters for FIT image type");
+ }
}
if (params.lflag || params.fflag) {
diff --git a/tools/rmboard.py b/tools/rmboard.py
index 594fd89b8d7..21d68c57261 100755
--- a/tools/rmboard.py
+++ b/tools/rmboard.py
@@ -112,8 +112,7 @@ def rm_board(board):
rm_kconfig_include(fname)
# Remove unwanted files
- cmd = ['git', 'rm', '-r'] + real
- stdout = command.output(*cmd, capture=True)
+ stdout = command.output('git', 'rm', '-r', *real)
## Change the messages as needed
msg = '''arm: Remove %s board
@@ -130,7 +129,8 @@ Remove it.
# Check if the board is mentioned anywhere else. The user will need to deal
# with this
- print(command.output('git', 'grep', '-il', board, raise_on_error=False))
+ cmd = ['git', 'grep', '-il', board]
+ print(command.output(*cmd, raise_on_error=False))
print(' '.join(cmd))
for board in sys.argv[1:]:
diff --git a/tools/termios_linux.h b/tools/termios_linux.h
index 0806a91180a..0e5a5c475b5 100644
--- a/tools/termios_linux.h
+++ b/tools/termios_linux.h
@@ -32,13 +32,13 @@
#include <asm/ioctls.h>
#include <asm/termbits.h>
-#if defined(BOTHER) && defined(TCGETS2)
+#if defined(BOTHER) && defined(TCGETS2) && !defined(__powerpc64__)
#define termios termios2
#endif
static inline int tcgetattr(int fd, struct termios *t)
{
-#if defined(BOTHER) && defined(TCGETS2)
+#if defined(BOTHER) && defined(TCGETS2) && !defined(__powerpc64__)
return ioctl(fd, TCGETS2, t);
#else
return ioctl(fd, TCGETS, t);
@@ -50,7 +50,7 @@ static inline int tcsetattr(int fd, int a, const struct termios *t)
int cmd;
switch (a) {
-#if defined(BOTHER) && defined(TCGETS2)
+#if defined(BOTHER) && defined(TCGETS2) && !defined(__powerpc64__)
case TCSANOW:
cmd = TCSETS2;
break;