# SPDX-License-Identifier: GPL-2.0

pbl-firmware-$(CONFIG_FIRMWARE_IMX_LPDDR4_PMU_TRAIN) += \
	lpddr4_pmu_train_1d_dmem.bin \
	lpddr4_pmu_train_1d_imem.bin \
	lpddr4_pmu_train_2d_dmem.bin \
	lpddr4_pmu_train_2d_imem.bin

pbl-firmware-$(CONFIG_FIRMWARE_IMX_DDR4_PMU_TRAIN) += \
	ddr4_dmem_1d.bin \
	ddr4_dmem_2d.bin \
	ddr4_imem_1d.bin \
	ddr4_imem_2d.bin

pbl-firmware-$(CONFIG_FIRMWARE_IMX_DDR3_PMU_TRAIN) += \
	ddr3_dmem_1d.bin \
	ddr3_imem_1d.bin

pbl-firmware-$(CONFIG_FIRMWARE_IMX8MM_ATF) += imx8mm-bl31.bin$(if $(CONFIG_FIRMWARE_IMX8MM_OPTEE),-optee,)
pbl-firmware-$(CONFIG_FIRMWARE_IMX8MN_ATF) += imx8mn-bl31.bin$(if $(CONFIG_FIRMWARE_IMX8MN_OPTEE),-optee,)
pbl-firmware-$(CONFIG_FIRMWARE_IMX8MP_ATF) += imx8mp-bl31.bin$(if $(CONFIG_FIRMWARE_IMX8MP_OPTEE),-optee,)
pbl-firmware-$(CONFIG_FIRMWARE_IMX8MQ_ATF) += imx8mq-bl31.bin
pbl-firmware-$(CONFIG_FIRMWARE_IMX93_ATF) += imx93-bl31.bin$(if $(CONFIG_FIRMWARE_IMX93_OPTEE),-optee,)
pbl-firmware-$(CONFIG_FIRMWARE_AGILEX5_ATF) += agilex5-bl31.bin
pbl-firmware-$(CONFIG_FIRMWARE_IMX6_OPTEE) += imx6-optee.bin
fw-external-$(CONFIG_FIRMWARE_IMX8MM_OPTEE) += imx8mm-bl32.bin
fw-external-$(CONFIG_FIRMWARE_IMX8MN_OPTEE) += imx8mn-bl32.bin
fw-external-$(CONFIG_FIRMWARE_IMX8MP_OPTEE) += imx8mp-bl32.bin
fw-external-$(CONFIG_FIRMWARE_IMX93_OPTEE) += imx93-bl32.bin \
					      mx93a1-ahab-container.img
fw-external-$(CONFIG_FIRMWARE_IMX93_OPTEE_A0) += mx93a0-ahab-container.img
pbl-firmware-$(CONFIG_ARCH_RK3562) += rk3562-bl31.bin
pbl-firmware-$(CONFIG_ARCH_RK3568) += rk3568-bl31.bin
pbl-firmware-$(CONFIG_ARCH_RK3576) += rk3576-bl31.bin
pbl-firmware-$(CONFIG_ARCH_RK3588) += rk3588-bl31.bin
ifeq ($(CONFIG_ARCH_ROCKCHIP_OPTEE),y)
# We install BL31 & BL32 while already running in DRAM,
# so fw-external is not needed
pbl-firmware-$(CONFIG_ARCH_RK3562) += rk3562-bl32.bin
pbl-firmware-$(CONFIG_ARCH_RK3568) += rk3568-bl32.bin
pbl-firmware-$(CONFIG_ARCH_RK3576) += rk3576-bl32.bin
pbl-firmware-$(CONFIG_ARCH_RK3588) += rk3588-bl32.bin
endif

firmware-$(CONFIG_FIRMWARE_NEXT_IMAGE) += next-image.bin

obj-firmware-$(CONFIG_DRIVER_NET_FSL_FMAN) += fsl_fman_ucode_ls1046_r1.0_106_4_18.bin

fw-external-$(CONFIG_FIRMWARE_LS1028A_ATF) += ls1028a-bl31.bin
fw-external-$(CONFIG_FIRMWARE_LS1046A_ATF) += ls1046a-bl31.bin

pbl-firmware-$(CONFIG_FIRMWARE_CCBV2_OPTEE) += ccbv2_optee.bin
pbl-firmware-$(CONFIG_FIRMWARE_TQMA6UL_OPTEE) += mba6ul_optee.bin

fwobjdir := $(objtree)/firmware

pbl-y     := $(addsuffix .gen.o, $(pbl-firmware-y))
obj-y     := $(addsuffix .gen.o, $(obj-firmware-y))
obj-pbl-y := $(addsuffix .gen.o, $(firmware-y))
pbl-fwext-y := $(addsuffix .extgen.o, $(fw-external-y))

FWNAME    = $(patsubst $(obj)/%.extgen.S,%,$(patsubst $(obj)/%.gen.S,%,$@))

filechk_fwbin = $(srctree)/scripts/gen-fw-s $(FWNAME) $(FIRMWARE_DIR) .rodata '' $(fwobjdir)
filechk_fwbin_ext = $(srctree)/scripts/gen-fw-s $(FWNAME) $(FIRMWARE_DIR) .pblext a $(fwobjdir)

$(obj)/%.gen.S: FORCE
	$(call filechk,fwbin)

$(obj)/%.extgen.S: FORCE
	$(call filechk,fwbin_ext)

# Compress firmware files
$(fwobjdir)/%.z: $(FIRMWARE_DIR)/% FORCE
	$(call if_changed,$(suffix_y))

# This dependency is used if missing firmware should fail the build immediately
fwdep-required-y = $(FIRMWARE_DIR)/%
# This dependency expands to nothing if the file doesn't exist. This allows
# delaying the firmware check:
#
#   - to final assembly of the PBL image for pbl-firmware
#   - to runtime for firmware in barebox proper
#
# This way, we allow users to build defconfigs with multiple images without requiring
# them to install all firmware for all platforms if only few are of interest.
fwdep-required-n = $$(wildcard $(FIRMWARE_DIR)/%)

# Compressed firmware dependency: only if the firmware binary exists.
# Use $$* (stem) instead of % because % is not substituted inside $$(if ...).
fwzdep-n = $$(if $$(wildcard $(FIRMWARE_DIR)/$$*),$(fwobjdir)/$$*.z)

.SECONDEXPANSION:
# .gen.S files depend on compressed firmware for correct size computation
$(patsubst %.gen.o,$(obj)/%.gen.S, $(obj-pbl-y) $(pbl-y)): $(obj)/%.gen.S: $(fwzdep-n)
$(patsubst %.extgen.o,$(obj)/%.extgen.S, $(pbl-fwext-y)): $(obj)/%.extgen.S: $(fwzdep-n)
# The .o files depend on the binaries directly if available; the .S files don't.
$(patsubst %.gen.o,$(obj)/%.gen.pbl.o, $(obj-pbl-y) $(pbl-y)): $(obj)/%.gen.pbl.o: $(fwdep-required-n) $(fwzdep-n)
$(patsubst %.extgen.o,$(obj)/%.extgen.pbl.o, $(pbl-fwext-y)): $(obj)/%.extgen.pbl.o: $(fwdep-required-n) $(fwzdep-n)
# For barebox proper, firmware existance is either checked here
# or in driver code by checking whether size != 0
$(patsubst %.gen.o,$(obj)/%.gen.o, $(obj-pbl-y)): $(obj)/%.gen.o: $(fwdep-required-$(CONFIG_MISSING_FIRMWARE_ERROR))

pbl-y += $(pbl-fwext-y)

targets := $(patsubst $(obj)/%,%, \
	                        $(shell find $(obj) -name \*.gen.S 2>/dev/null))
targets += $(patsubst $(obj)/%,%, \
	                        $(shell find $(obj) -name \*.extgen.S 2>/dev/null))
targets += $(patsubst $(obj)/%,%, \
	                        $(shell find $(obj) -name \*.z 2>/dev/null))

# just to build a built-in.o. Otherwise compilation fails when no
# firmware is built.
obj- += dummy.o
