# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2022-2026, Advanced Micro Devices, Inc.
#

KERNEL_VER ?= $(shell uname -r)
KERNEL_SRC ?= /lib/modules/$(KERNEL_VER)/build

mkfile_path = $(abspath $(lastword $(MAKEFILE_LIST)))
SRC_DIR = $(patsubst %/,%,$(dir $(mkfile_path)))
BUILD_ROOT_DIR := $(SRC_DIR)/build

ifeq ($(BUILD_ROOT_DIR),$(SRC_DIR))
$(error BUILD_ROOT_DIR and SRC_DIR can NOT be the same)
endif

.PHONY: all clean modules modules_install copy_ko

all: $(BUILD_ROOT_DIR)
	$(MAKE) -C $(BUILD_ROOT_DIR)/drivers/accel/$(notdir $(SRC_DIR)) modules

# add EXTRA_CFLAGS='-save-temps' to keep intermedia files
DEFINES := -DAMDXDNA_DEVEL

# Driver version
XDNA_DRIVER_VERSION ?= 2.21.0
XDNA_DATE ?= $(shell date +%Y%m%d)
XDNA_HASH ?= $(shell git rev-parse HEAD)

ifndef MODULE_VER_STR
MODULE_VER_STR := $(XDNA_DRIVER_VERSION)_$(XDNA_DATE),$(XDNA_HASH)
endif

DEFINES += -DMODULE_VER_STR='\"$(MODULE_VER_STR)\"'

# Not upstreamed: enabled via build.sh -npu3a (XDNA_DRV_BLD_FLAGS), forwarded
# to both the native build and the DKMS rebuild so the macro survives packaging.
ifeq ($(AMDXDNA_NPU3A),1)
DEFINES += -DAMDXDNA_NPU3A
endif

# Platform (non-PCI) build: forward the aie4 platform-transport select to Kbuild,
# which then builds aie4_plat.o (and the transport-independent aie4 core) instead
# of aie4_pci.o.  Enable with `make ... CONFIG_DRM_ACCEL_AMDXDNA_PLAT=y`.
ifeq ($(CONFIG_DRM_ACCEL_AMDXDNA_PLAT),y)
KBUILD_PLAT := CONFIG_DRM_ACCEL_AMDXDNA_PLAT=y
endif

# Compiler (gcc/clang) comes from the LLVM= kbuild var set by DKMS/caller, not probed here (#1377)
# config_kernel.h is normally generated by CMake (native build) or DKMS PRE_BUILD.
# For the Yocto/bitbake and plain `make` flows it may be absent, so generate it
# here by feature-testing the *target* kernel (ARCH/CROSS_COMPILE are forwarded so
# cross conftests build correctly).  An existing header is reused as-is.
modules:
	@cfg_script="$(SRC_DIR)/../tools/configure_kernel.sh"; \
	[ -f "$$cfg_script" ] || cfg_script="$(SRC_DIR)/../../../configure_kernel.sh"; \
	if [ ! -f "$(SRC_DIR)/config_kernel.h" ]; then \
		[ -f "$$cfg_script" ] || { echo "[ERROR] config_kernel.h missing and configure_kernel.sh not found"; exit 1; }; \
		echo "[INFO] Generating config_kernel.h via $$cfg_script"; \
		ARCH="$(ARCH)" CROSS_COMPILE="$(CROSS_COMPILE)" KERNEL_SRC="$(KERNEL_SRC)" \
			OUT="$(SRC_DIR)/config_kernel.h" sh "$$cfg_script" || \
			{ echo "[ERROR] config_kernel.h generation failed"; exit 1; }; \
	fi
	$(MAKE) -C $(KERNEL_SRC) M=$(SRC_DIR) CFLAGS_MODULE="$(DEFINES)" $(KBUILD_PLAT) modules

modules_install:
	$(MAKE) -C $(KERNEL_SRC) M=$(SRC_DIR) modules_install

$(BUILD_ROOT_DIR): $(SRC_DIR)
	@echo "[INFO] BUILD Directory not exist or SRC Directory is newer"
	@echo "[INFO] Re-Generate BUILD_ROOT_DIR: $(BUILD_ROOT_DIR)"
	@rm -rf $@
	@$(eval TMP_DIR := $(shell mktemp -d))
	@mkdir -p $(TMP_DIR)/drivers/accel
	@cp -rs $(SRC_DIR) $(TMP_DIR)/drivers/accel
	@# Stage configure_kernel.sh so a plain `make all` can self-generate
	@# config_kernel.h; absent in the CMake copy (which pregenerates the header).
	@[ -d "$(SRC_DIR)/../tools" ] && cp -rs $(SRC_DIR)/../tools $(TMP_DIR)/drivers/accel || true
	@cp -rs $(SRC_DIR)/../../../include $(TMP_DIR)
	@mv $(TMP_DIR) $(BUILD_ROOT_DIR)

copy_ko:
	@find $(BUILD_ROOT_DIR) -mindepth 2 -name "*.ko" -type f -exec cp -f {} $(BUILD_ROOT_DIR) \;

clean:
	rm -rf $(BUILD_ROOT_DIR)
	rm -rf *.o *.cmd .*.cmd *.ko *.dwo *.mod* modules.order Module.symvers
