// SPDX-License-Identifier: MIT
/*
 * Copyright © 2022 Intel Corporation
 */

#include <linux/bitfield.h>
#include <linux/firmware.h>

#include <drm/drm_managed.h>

#include "regs/xe_guc_regs.h"
#include "xe_bo.h"
#include "xe_device_types.h"
#include "xe_force_wake.h"
#include "xe_gsc.h"
#include "xe_gt.h"
#include "xe_map.h"
#include "xe_mmio.h"
#include "xe_module.h"
#include "xe_uc_fw.h"

/*
 * List of required GuC and HuC binaries per-platform. They must be ordered
 * based on platform, from newer to older.
 *
 * Versioning follows the guidelines from
 * Documentation/driver-api/firmware/firmware-usage-guidelines.rst. There is a
 * distinction for platforms being officially supported by the driver or not.
 * Platforms not available publicly or not yet officially supported by the
 * driver (under force-probe), use the mmp_ver(): the firmware autoselect logic
 * will select the firmware from disk with filename that matches the full
 * "mpp version", i.e. major.minor.patch. mmp_ver() should only be used for
 * this case.
 *
 * For platforms officially supported by the driver, the filename always only
 * ever contains the major version (GuC) or no version at all (HuC).
 *
 * After loading the file, the driver parses the versions embedded in the blob.
 * The major version needs to match a major version supported by the driver (if
 * any). The minor version is also checked and a notice emitted to the log if
 * the version found is smaller than the version wanted. This is done only for
 * informational purposes so users may have a chance to upgrade, but the driver
 * still loads and use the older firmware.
 *
 * Examples:
 *
 *	1) Platform officially supported by i915 - using Tigerlake as example.
 *	   Driver loads the following firmware blobs from disk:
 *
 *		- i915/tgl_guc_<major>.bin
 *		- i915/tgl_huc.bin
 *
 *	   <major> number for GuC is checked that it matches the version inside
 *	   the blob. <minor> version is checked and if smaller than the expected
 *	   an info message is emitted about that.
 *
 *	1) XE_<FUTUREINTELPLATFORM>, still under require_force_probe. Using
 *	   "wipplat" as a short-name. Driver loads the following firmware blobs
 *	   from disk:
 *
 *		- xe/wipplat_guc_<major>.<minor>.<patch>.bin
 *		- xe/wipplat_huc_<major>.<minor>.<patch>.bin
 *
 *	   <major> and <minor> are checked that they match the version inside
 *	   the blob. Both of them need to match exactly what the driver is
 *	   expecting, otherwise it fails.
 *
 *	3) Platform officially supported by xe and out of force-probe. Using
 *	   "plat" as a short-name. Except for the different directory, the
 *	   behavior is the same as (1). Driver loads the following firmware
 *	   blobs from disk:
 *
 *		- xe/plat_guc_<major>.bin
 *		- xe/plat_huc.bin
 *
 *	   <major> number for GuC is checked that it matches the version inside
 *	   the blob. <minor> version is checked and if smaller than the expected
 *	   an info message is emitted about that.
 *
 * For the platforms already released with a major version, they should never be
 * removed from the table. Instead new entries with newer versions may be added
 * before them, so they take precedence.
 *
 * TODO: Currently there's no fallback on major version. That's because xe
 * driver only supports the one major version of each firmware in the table.
 * This needs to be fixed when the major version of GuC is updated.
 */

struct uc_fw_entry {
	enum xe_platform platform;
	struct {
		const char *path;
		u16 major;
		u16 minor;
		bool full_ver_required;
	};
};

struct fw_blobs_by_type {
	const struct uc_fw_entry *entries;
	u32 count;
};

#define XE_GUC_FIRMWARE_DEFS(fw_def, mmp_ver, major_ver)			\
	fw_def(METEORLAKE,	major_ver(i915,	guc,	mtl,	70, 7))		\
	fw_def(DG2,		major_ver(i915,	guc,	dg2,	70, 5))		\
	fw_def(DG1,		major_ver(i915,	guc,	dg1,	70, 5))		\
	fw_def(ALDERLAKE_N,	major_ver(i915,	guc,	tgl,	70, 5))		\
	fw_def(ALDERLAKE_P,	major_ver(i915,	guc,	adlp,	70, 5))		\
	fw_def(ALDERLAKE_S,	major_ver(i915,	guc,	tgl,	70, 5))		\
	fw_def(ROCKETLAKE,	major_ver(i915,	guc,	tgl,	70, 5))		\
	fw_def(TIGERLAKE,	major_ver(i915,	guc,	tgl,	70, 5))

#define XE_HUC_FIRMWARE_DEFS(fw_def, mmp_ver, no_ver)		\
	fw_def(METEORLAKE,	no_ver(i915,	huc_gsc,	mtl))		\
	fw_def(DG1,		no_ver(i915,	huc,		dg1))		\
	fw_def(ALDERLAKE_P,	no_ver(i915,	huc,		tgl))		\
	fw_def(ALDERLAKE_S,	no_ver(i915,	huc,		tgl))		\
	fw_def(ROCKETLAKE,	no_ver(i915,	huc,		tgl))		\
	fw_def(TIGERLAKE,	no_ver(i915,	huc,		tgl))

/* for the GSC FW we match the compatibility version and not the release one */
#define XE_GSC_FIRMWARE_DEFS(fw_def, major_ver)		\
	fw_def(METEORLAKE,	major_ver(i915,	gsc,	mtl,	1, 0))

#define MAKE_FW_PATH(dir__, uc__, shortname__, version__)			\
	__stringify(dir__) "/" __stringify(shortname__) "_" __stringify(uc__) version__ ".bin"

#define fw_filename_mmp_ver(dir_, uc_, shortname_, a, b, c)			\
	MAKE_FW_PATH(dir_, uc_, shortname_, "_" __stringify(a ## . ## b ## . ## c))
#define fw_filename_major_ver(dir_, uc_, shortname_, a, b)			\
	MAKE_FW_PATH(dir_, uc_, shortname_, "_" __stringify(a))
#define fw_filename_no_ver(dir_, uc_, shortname_)				\
	MAKE_FW_PATH(dir_, uc_, shortname_, "")

#define uc_fw_entry_mmp_ver(dir_, uc_, shortname_, a, b, c)			\
	{ fw_filename_mmp_ver(dir_, uc_, shortname_, a, b, c),			\
	  a, b, true }
#define uc_fw_entry_major_ver(dir_, uc_, shortname_, a, b)			\
	{ fw_filename_major_ver(dir_, uc_, shortname_, a, b),			\
	  a, b }
#define uc_fw_entry_no_ver(dir_, uc_, shortname_)				\
	{ fw_filename_no_ver(dir_, uc_, shortname_),				\
	  0, 0 }

/* All blobs need to be declared via MODULE_FIRMWARE() */
#define XE_UC_MODULE_FIRMWARE(platform__, fw_filename)				\
	MODULE_FIRMWARE(fw_filename);

#define XE_UC_FW_ENTRY(platform__, entry__)					\
	{									\
		.platform = XE_ ## platform__,					\
		entry__,							\
	},

XE_GUC_FIRMWARE_DEFS(XE_UC_MODULE_FIRMWARE,
		     fw_filename_mmp_ver, fw_filename_major_ver)
XE_HUC_FIRMWARE_DEFS(XE_UC_MODULE_FIRMWARE,
		     fw_filename_mmp_ver, fw_filename_no_ver)
XE_GSC_FIRMWARE_DEFS(XE_UC_MODULE_FIRMWARE, fw_filename_major_ver)

static struct xe_gt *
__uc_fw_to_gt(struct xe_uc_fw *uc_fw, enum xe_uc_fw_type type)
{
	XE_WARN_ON(type >= XE_UC_FW_NUM_TYPES);

	switch (type) {
	case XE_UC_FW_TYPE_GUC:
		return container_of(uc_fw, struct xe_gt, uc.guc.fw);
	case XE_UC_FW_TYPE_HUC:
		return container_of(uc_fw, struct xe_gt, uc.huc.fw);
	case XE_UC_FW_TYPE_GSC:
		return container_of(uc_fw, struct xe_gt, uc.gsc.fw);
	default:
		return NULL;
	}
}

static struct xe_gt *uc_fw_to_gt(struct xe_uc_fw *uc_fw)
{
	return __uc_fw_to_gt(uc_fw, uc_fw->type);
}

static struct xe_device *uc_fw_to_xe(struct xe_uc_fw *uc_fw)
{
	return gt_to_xe(uc_fw_to_gt(uc_fw));
}

static void
uc_fw_auto_select(struct xe_device *xe, struct xe_uc_fw *uc_fw)
{
	static const struct uc_fw_entry entries_guc[] = {
		XE_GUC_FIRMWARE_DEFS(XE_UC_FW_ENTRY,
				     uc_fw_entry_mmp_ver,
				     uc_fw_entry_major_ver)
	};
	static const struct uc_fw_entry entries_huc[] = {
		XE_HUC_FIRMWARE_DEFS(XE_UC_FW_ENTRY,
				     uc_fw_entry_mmp_ver,
				     uc_fw_entry_no_ver)
	};
	static const struct uc_fw_entry entries_gsc[] = {
		XE_GSC_FIRMWARE_DEFS(XE_UC_FW_ENTRY, uc_fw_entry_major_ver)
	};
	static const struct fw_blobs_by_type blobs_all[XE_UC_FW_NUM_TYPES] = {
		[XE_UC_FW_TYPE_GUC] = { entries_guc, ARRAY_SIZE(entries_guc) },
		[XE_UC_FW_TYPE_HUC] = { entries_huc, ARRAY_SIZE(entries_huc) },
		[XE_UC_FW_TYPE_GSC] = { entries_gsc, ARRAY_SIZE(entries_gsc) },
	};
	static const struct uc_fw_entry *entries;
	enum xe_platform p = xe->info.platform;
	u32 count;
	int i;

	xe_assert(xe, uc_fw->type < ARRAY_SIZE(blobs_all));
	entries = blobs_all[uc_fw->type].entries;
	count = blobs_all[uc_fw->type].count;

	for (i = 0; i < count && p <= entries[i].platform; i++) {
		if (p == entries[i].platform) {
			uc_fw->path = entries[i].path;
			uc_fw->versions.wanted.major = entries[i].major;
			uc_fw->versions.wanted.minor = entries[i].minor;
			uc_fw->full_ver_required = entries[i].full_ver_required;

			if (uc_fw->type == XE_UC_FW_TYPE_GSC)
				uc_fw->versions.wanted_type = XE_UC_FW_VER_COMPATIBILITY;
			else
				uc_fw->versions.wanted_type = XE_UC_FW_VER_RELEASE;

			break;
		}
	}
}

static void
uc_fw_override(struct xe_uc_fw *uc_fw)
{
	char *path_override = NULL;

	/* empty string disables, but it's not allowed for GuC */
	switch (uc_fw->type) {
	case XE_UC_FW_TYPE_GUC:
		if (xe_modparam.guc_firmware_path && *xe_modparam.guc_firmware_path)
			path_override = xe_modparam.guc_firmware_path;
		break;
	case XE_UC_FW_TYPE_HUC:
		path_override = xe_modparam.huc_firmware_path;
		break;
	case XE_UC_FW_TYPE_GSC:
		path_override = xe_modparam.gsc_firmware_path;
		break;
	default:
		break;
	}

	if (path_override) {
		uc_fw->path = path_override;
		uc_fw->user_overridden = true;
	}
}

/**
 * xe_uc_fw_copy_rsa - copy fw RSA to buffer
 *
 * @uc_fw: uC firmware
 * @dst: dst buffer
 * @max_len: max number of bytes to copy
 *
 * Return: number of copied bytes.
 */
size_t xe_uc_fw_copy_rsa(struct xe_uc_fw *uc_fw, void *dst, u32 max_len)
{
	struct xe_device *xe = uc_fw_to_xe(uc_fw);
	u32 size = min_t(u32, uc_fw->rsa_size, max_len);

	xe_assert(xe, !(size % 4));
	xe_assert(xe, xe_uc_fw_is_available(uc_fw));

	xe_map_memcpy_from(xe, dst, &uc_fw->bo->vmap,
			   xe_uc_fw_rsa_offset(uc_fw), size);

	return size;
}

static void uc_fw_fini(struct drm_device *drm, void *arg)
{
	struct xe_uc_fw *uc_fw = arg;

	if (!xe_uc_fw_is_available(uc_fw))
		return;

	xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_SELECTED);
}

static void guc_read_css_info(struct xe_uc_fw *uc_fw, struct uc_css_header *css)
{
	struct xe_gt *gt = uc_fw_to_gt(uc_fw);
	struct xe_uc_fw_version *release = &uc_fw->versions.found[XE_UC_FW_VER_RELEASE];
	struct xe_uc_fw_version *compatibility = &uc_fw->versions.found[XE_UC_FW_VER_COMPATIBILITY];

	xe_gt_assert(gt, uc_fw->type == XE_UC_FW_TYPE_GUC);
	xe_gt_assert(gt, release->major >= 70);

	if (release->major > 70 || release->minor >= 6) {
		/* v70.6.0 adds CSS header support */
		compatibility->major = FIELD_GET(CSS_SW_VERSION_UC_MAJOR,
						 css->submission_version);
		compatibility->minor = FIELD_GET(CSS_SW_VERSION_UC_MINOR,
						 css->submission_version);
		compatibility->patch = FIELD_GET(CSS_SW_VERSION_UC_PATCH,
						 css->submission_version);
	} else if (release->minor >= 3) {
		/* v70.3.0 introduced v1.1.0 */
		compatibility->major = 1;
		compatibility->minor = 1;
		compatibility->patch = 0;
	} else {
		/* v70.0.0 introduced v1.0.0 */
		compatibility->major = 1;
		compatibility->minor = 0;
		compatibility->patch = 0;
	}

	uc_fw->private_data_size = css->private_data_size;
}

int xe_uc_fw_check_version_requirements(struct xe_uc_fw *uc_fw)
{
	struct xe_device *xe = uc_fw_to_xe(uc_fw);
	struct xe_uc_fw_version *wanted = &uc_fw->versions.wanted;
	struct xe_uc_fw_version *found = &uc_fw->versions.found[uc_fw->versions.wanted_type];

	/* Driver has no requirement on any version, any is good. */
	if (!wanted->major)
		return 0;

	/*
	 * If full version is required, both major and minor should match.
	 * Otherwise, at least the major version.
	 */
	if (wanted->major != found->major ||
	    (uc_fw->full_ver_required && wanted->minor != found->minor)) {
		drm_notice(&xe->drm, "%s firmware %s: unexpected version: %u.%u != %u.%u\n",
			   xe_uc_fw_type_repr(uc_fw->type), uc_fw->path,
			   found->major, found->minor,
			   wanted->major, wanted->minor);
		goto fail;
	}

	if (wanted->minor > found->minor) {
		drm_notice(&xe->drm, "%s firmware (%u.%u) is recommended, but only (%u.%u) was found in %s\n",
			   xe_uc_fw_type_repr(uc_fw->type),
			   wanted->major, wanted->minor,
			   found->major, found->minor,
			   uc_fw->path);
		drm_info(&xe->drm, "Consider updating your linux-firmware pkg or downloading from %s\n",
			 XE_UC_FIRMWARE_URL);
	}

	return 0;

fail:
	if (xe_uc_fw_is_overridden(uc_fw))
		return 0;

	return -ENOEXEC;
}

/* Refer to the "CSS-based Firmware Layout" documentation entry for details */
static int parse_css_header(struct xe_uc_fw *uc_fw, const void *fw_data, size_t fw_size)
{
	struct xe_device *xe = uc_fw_to_xe(uc_fw);
	struct xe_uc_fw_version *release = &uc_fw->versions.found[XE_UC_FW_VER_RELEASE];
	struct uc_css_header *css;
	size_t size;

	/* Check the size of the blob before examining buffer contents */
	if (unlikely(fw_size < sizeof(struct uc_css_header))) {
		drm_warn(&xe->drm, "%s firmware %s: invalid size: %zu < %zu\n",
			 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path,
			 fw_size, sizeof(struct uc_css_header));
		return -ENODATA;
	}

	css = (struct uc_css_header *)fw_data;

	/* Check integrity of size values inside CSS header */
	size = (css->header_size_dw - css->key_size_dw - css->modulus_size_dw -
		css->exponent_size_dw) * sizeof(u32);
	if (unlikely(size != sizeof(struct uc_css_header))) {
		drm_warn(&xe->drm,
			 "%s firmware %s: unexpected header size: %zu != %zu\n",
			 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path,
			 fw_size, sizeof(struct uc_css_header));
		return -EPROTO;
	}

	/* uCode size must calculated from other sizes */
	uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32);

	/* now RSA */
	uc_fw->rsa_size = css->key_size_dw * sizeof(u32);

	/* At least, it should have header, uCode and RSA. Size of all three. */
	size = sizeof(struct uc_css_header) + uc_fw->ucode_size +
		uc_fw->rsa_size;
	if (unlikely(fw_size < size)) {
		drm_warn(&xe->drm, "%s firmware %s: invalid size: %zu < %zu\n",
			 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path,
			 fw_size, size);
		return -ENOEXEC;
	}

	/* Get version numbers from the CSS header */
	release->major = FIELD_GET(CSS_SW_VERSION_UC_MAJOR, css->sw_version);
	release->minor = FIELD_GET(CSS_SW_VERSION_UC_MINOR, css->sw_version);
	release->patch = FIELD_GET(CSS_SW_VERSION_UC_PATCH, css->sw_version);

	if (uc_fw->type == XE_UC_FW_TYPE_GUC)
		guc_read_css_info(uc_fw, css);

	return 0;
}

static bool is_cpd_header(const void *data)
{
	const u32 *marker = data;

	return *marker == GSC_CPD_HEADER_MARKER;
}

static u32 entry_offset(const struct gsc_cpd_header_v2 *header, const char *name)
{
	const struct gsc_cpd_entry *entry;
	int i;

	entry = (void *)header + header->header_length;

	for (i = 0; i < header->num_of_entries; i++, entry++)
		if (strcmp(entry->name, name) == 0)
			return entry->offset & GSC_CPD_ENTRY_OFFSET_MASK;

	return 0;
}

/* Refer to the "GSC-based Firmware Layout" documentation entry for details */
static int parse_cpd_header(struct xe_uc_fw *uc_fw, const void *data, size_t size,
			    const char *manifest_entry, const char *css_entry)
{
	struct xe_gt *gt = uc_fw_to_gt(uc_fw);
	struct xe_device *xe = gt_to_xe(gt);
	const struct gsc_cpd_header_v2 *header = data;
	struct xe_uc_fw_version *release = &uc_fw->versions.found[XE_UC_FW_VER_RELEASE];
	const struct gsc_manifest_header *manifest;
	size_t min_size = sizeof(*header);
	u32 offset;

	/* manifest_entry is mandatory, css_entry is optional */
	xe_assert(xe, manifest_entry);

	if (size < min_size || !is_cpd_header(header))
		return -ENOENT;

	if (header->header_length < sizeof(struct gsc_cpd_header_v2)) {
		xe_gt_err(gt, "invalid CPD header length %u!\n", header->header_length);
		return -EINVAL;
	}

	min_size = header->header_length + sizeof(struct gsc_cpd_entry) * header->num_of_entries;
	if (size < min_size) {
		xe_gt_err(gt, "FW too small! %zu < %zu\n", size, min_size);
		return -ENODATA;
	}

	/* Look for the manifest first */
	offset = entry_offset(header, manifest_entry);
	if (!offset) {
		xe_gt_err(gt, "Failed to find %s manifest!\n",
			  xe_uc_fw_type_repr(uc_fw->type));
		return -ENODATA;
	}

	min_size = offset + sizeof(struct gsc_manifest_header);
	if (size < min_size) {
		xe_gt_err(gt, "FW too small! %zu < %zu\n", size, min_size);
		return -ENODATA;
	}

	manifest = data + offset;

	release->major = manifest->fw_version.major;
	release->minor = manifest->fw_version.minor;
	release->patch = manifest->fw_version.hotfix;

	if (uc_fw->type == XE_UC_FW_TYPE_GSC) {
		struct xe_gsc *gsc = container_of(uc_fw, struct xe_gsc, fw);

		release->build = manifest->fw_version.build;
		gsc->security_version = manifest->security_version;
	}

	/* then optionally look for the css header */
	if (css_entry) {
		int ret;

		/*
		 * This section does not contain a CSS entry on DG2. We
		 * don't support DG2 HuC right now, so no need to handle
		 * it, just add a reminder in case that changes.
		 */
		xe_assert(xe, xe->info.platform != XE_DG2);

		offset = entry_offset(header, css_entry);

		/* the CSS header parser will check that the CSS header fits */
		if (offset > size) {
			xe_gt_err(gt, "FW too small! %zu < %u\n", size, offset);
			return -ENODATA;
		}

		ret = parse_css_header(uc_fw, data + offset, size - offset);
		if (ret)
			return ret;

		uc_fw->css_offset = offset;
	}

	uc_fw->has_gsc_headers = true;

	return 0;
}

static int parse_gsc_layout(struct xe_uc_fw *uc_fw, const void *data, size_t size)
{
	struct xe_gt *gt = uc_fw_to_gt(uc_fw);
	const struct gsc_layout_pointers *layout = data;
	const struct gsc_bpdt_header *bpdt_header = NULL;
	const struct gsc_bpdt_entry *bpdt_entry = NULL;
	size_t min_size = sizeof(*layout);
	int i;

	if (size < min_size) {
		xe_gt_err(gt, "GSC FW too small! %zu < %zu\n", size, min_size);
		return -ENODATA;
	}

	min_size = layout->boot1.offset + layout->boot1.size;
	if (size < min_size) {
		xe_gt_err(gt, "GSC FW too small for boot section! %zu < %zu\n",
			  size, min_size);
		return -ENODATA;
	}

	min_size = sizeof(*bpdt_header);
	if (layout->boot1.size < min_size) {
		xe_gt_err(gt, "GSC FW boot section too small for BPDT header: %u < %zu\n",
			  layout->boot1.size, min_size);
		return -ENODATA;
	}

	bpdt_header = data + layout->boot1.offset;
	if (bpdt_header->signature != GSC_BPDT_HEADER_SIGNATURE) {
		xe_gt_err(gt, "invalid signature for BPDT header: 0x%08x!\n",
			  bpdt_header->signature);
		return -EINVAL;
	}

	min_size += sizeof(*bpdt_entry) * bpdt_header->descriptor_count;
	if (layout->boot1.size < min_size) {
		xe_gt_err(gt, "GSC FW boot section too small for BPDT entries: %u < %zu\n",
			  layout->boot1.size, min_size);
		return -ENODATA;
	}

	bpdt_entry = (void *)bpdt_header + sizeof(*bpdt_header);
	for (i = 0; i < bpdt_header->descriptor_count; i++, bpdt_entry++) {
		if ((bpdt_entry->type & GSC_BPDT_ENTRY_TYPE_MASK) !=
		    GSC_BPDT_ENTRY_TYPE_GSC_RBE)
			continue;

		min_size = bpdt_entry->sub_partition_offset;

		/* the CPD header parser will check that the CPD header fits */
		if (layout->boot1.size < min_size) {
			xe_gt_err(gt, "GSC FW boot section too small for CPD offset: %u < %zu\n",
				  layout->boot1.size, min_size);
			return -ENODATA;
		}

		return parse_cpd_header(uc_fw,
					(void *)bpdt_header + min_size,
					layout->boot1.size - min_size,
					"RBEP.man", NULL);
	}

	xe_gt_err(gt, "couldn't find CPD header in GSC binary!\n");
	return -ENODATA;
}

static int parse_headers(struct xe_uc_fw *uc_fw, const struct firmware *fw)
{
	int ret;

	/*
	 * All GuC releases and older HuC ones use CSS headers, while newer HuC
	 * releases use GSC CPD headers.
	 */
	switch (uc_fw->type) {
	case XE_UC_FW_TYPE_GSC:
		return parse_gsc_layout(uc_fw, fw->data, fw->size);
	case XE_UC_FW_TYPE_HUC:
		ret = parse_cpd_header(uc_fw, fw->data, fw->size, "HUCP.man", "huc_fw");
		if (!ret || ret != -ENOENT)
			return ret;
		fallthrough;
	case XE_UC_FW_TYPE_GUC:
		return parse_css_header(uc_fw, fw->data, fw->size);
	default:
		return -EINVAL;
	}

	return 0;
}

#define print_uc_fw_version(p_, version_, prefix_, ...) \
do { \
	struct xe_uc_fw_version *ver_ = (version_); \
	if (ver_->build) \
		drm_printf(p_, prefix_ " version %u.%u.%u.%u\n", ##__VA_ARGS__, \
			   ver_->major, ver_->minor, \
			   ver_->patch, ver_->build); \
	else \
		drm_printf(p_, prefix_ " version %u.%u.%u\n", ##__VA_ARGS__, \
			  ver_->major, ver_->minor, ver_->patch); \
} while (0)

static int uc_fw_request(struct xe_uc_fw *uc_fw, const struct firmware **firmware_p)
{
	struct xe_device *xe = uc_fw_to_xe(uc_fw);
	struct device *dev = xe->drm.dev;
	struct drm_printer p = drm_info_printer(dev);
	const struct firmware *fw = NULL;
	int err;

	/*
	 * we use FIRMWARE_UNINITIALIZED to detect checks against uc_fw->status
	 * before we're looked at the HW caps to see if we have uc support
	 */
	BUILD_BUG_ON(XE_UC_FIRMWARE_UNINITIALIZED);
	xe_assert(xe, !uc_fw->status);
	xe_assert(xe, !uc_fw->path);

	uc_fw_auto_select(xe, uc_fw);
	xe_uc_fw_change_status(uc_fw, uc_fw->path ?
			       XE_UC_FIRMWARE_SELECTED :
			       XE_UC_FIRMWARE_NOT_SUPPORTED);

	if (!xe_uc_fw_is_supported(uc_fw))
		return 0;

	uc_fw_override(uc_fw);

	/* an empty path means the firmware is disabled */
	if (!xe_device_uc_enabled(xe) || !(*uc_fw->path)) {
		xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_DISABLED);
		drm_dbg(&xe->drm, "%s disabled", xe_uc_fw_type_repr(uc_fw->type));
		return 0;
	}

	err = request_firmware(&fw, uc_fw->path, dev);
	if (err)
		goto fail;

	err = parse_headers(uc_fw, fw);
	if (err)
		goto fail;

	print_uc_fw_version(&p,
			    &uc_fw->versions.found[XE_UC_FW_VER_RELEASE],
			    "Using %s firmware from %s",
			    xe_uc_fw_type_repr(uc_fw->type), uc_fw->path);

	/* for GSC FW we want the compatibility version, which we query after load */
	if (uc_fw->type != XE_UC_FW_TYPE_GSC) {
		err = xe_uc_fw_check_version_requirements(uc_fw);
		if (err)
			goto fail;
	}

	*firmware_p = fw;

	return 0;

fail:
	xe_uc_fw_change_status(uc_fw, err == -ENOENT ?
			       XE_UC_FIRMWARE_MISSING :
			       XE_UC_FIRMWARE_ERROR);

	drm_notice(&xe->drm, "%s firmware %s: fetch failed with error %d\n",
		   xe_uc_fw_type_repr(uc_fw->type), uc_fw->path, err);
	drm_info(&xe->drm, "%s firmware(s) can be downloaded from %s\n",
		 xe_uc_fw_type_repr(uc_fw->type), XE_UC_FIRMWARE_URL);

	release_firmware(fw);		/* OK even if fw is NULL */

	return err;
}

static void uc_fw_release(const struct firmware *fw)
{
	release_firmware(fw);
}

static int uc_fw_copy(struct xe_uc_fw *uc_fw, const void *data, size_t size, u32 flags)
{
	struct xe_device *xe = uc_fw_to_xe(uc_fw);
	struct xe_gt *gt = uc_fw_to_gt(uc_fw);
	struct xe_tile *tile = gt_to_tile(gt);
	struct xe_bo *obj;
	int err;

	obj = xe_managed_bo_create_from_data(xe, tile, data, size, flags);
	if (IS_ERR(obj)) {
		drm_notice(&xe->drm, "%s firmware %s: failed to create / populate bo",
			   xe_uc_fw_type_repr(uc_fw->type), uc_fw->path);
		err = PTR_ERR(obj);
		goto fail;
	}

	uc_fw->bo = obj;
	uc_fw->size = size;

	xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_AVAILABLE);

	err = drmm_add_action_or_reset(&xe->drm, uc_fw_fini, uc_fw);
	if (err)
		goto fail;

	return 0;

fail:
	xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_ERROR);
	drm_notice(&xe->drm, "%s firmware %s: copy failed with error %d\n",
		   xe_uc_fw_type_repr(uc_fw->type), uc_fw->path, err);

	return err;
}

int xe_uc_fw_init(struct xe_uc_fw *uc_fw)
{
	const struct firmware *fw = NULL;
	int err;

	err = uc_fw_request(uc_fw, &fw);
	if (err)
		return err;

	/* no error and no firmware means nothing to copy */
	if (!fw)
		return 0;

	err = uc_fw_copy(uc_fw, fw->data, fw->size,
			 XE_BO_CREATE_SYSTEM_BIT | XE_BO_CREATE_GGTT_BIT);

	uc_fw_release(fw);

	return err;
}

static u32 uc_fw_ggtt_offset(struct xe_uc_fw *uc_fw)
{
	return xe_bo_ggtt_addr(uc_fw->bo);
}

static int uc_fw_xfer(struct xe_uc_fw *uc_fw, u32 offset, u32 dma_flags)
{
	struct xe_device *xe = uc_fw_to_xe(uc_fw);
	struct xe_gt *gt = uc_fw_to_gt(uc_fw);
	u32 src_offset, dma_ctrl;
	int ret;

	xe_force_wake_assert_held(gt_to_fw(gt), XE_FW_GT);

	/* Set the source address for the uCode */
	src_offset = uc_fw_ggtt_offset(uc_fw) + uc_fw->css_offset;
	xe_mmio_write32(gt, DMA_ADDR_0_LOW, lower_32_bits(src_offset));
	xe_mmio_write32(gt, DMA_ADDR_0_HIGH,
			upper_32_bits(src_offset) | DMA_ADDRESS_SPACE_GGTT);

	/* Set the DMA destination */
	xe_mmio_write32(gt, DMA_ADDR_1_LOW, offset);
	xe_mmio_write32(gt, DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM);

	/*
	 * Set the transfer size. The header plus uCode will be copied to WOPCM
	 * via DMA, excluding any other components
	 */
	xe_mmio_write32(gt, DMA_COPY_SIZE,
			sizeof(struct uc_css_header) + uc_fw->ucode_size);

	/* Start the DMA */
	xe_mmio_write32(gt, DMA_CTRL,
			_MASKED_BIT_ENABLE(dma_flags | START_DMA));

	/* Wait for DMA to finish */
	ret = xe_mmio_wait32(gt, DMA_CTRL, START_DMA, 0, 100000, &dma_ctrl,
			     false);
	if (ret)
		drm_err(&xe->drm, "DMA for %s fw failed, DMA_CTRL=%u\n",
			xe_uc_fw_type_repr(uc_fw->type), dma_ctrl);

	/* Disable the bits once DMA is over */
	xe_mmio_write32(gt, DMA_CTRL, _MASKED_BIT_DISABLE(dma_flags));

	return ret;
}

int xe_uc_fw_upload(struct xe_uc_fw *uc_fw, u32 offset, u32 dma_flags)
{
	struct xe_device *xe = uc_fw_to_xe(uc_fw);
	int err;

	/* make sure the status was cleared the last time we reset the uc */
	xe_assert(xe, !xe_uc_fw_is_loaded(uc_fw));

	if (!xe_uc_fw_is_loadable(uc_fw))
		return -ENOEXEC;

	/* Call custom loader */
	err = uc_fw_xfer(uc_fw, offset, dma_flags);
	if (err)
		goto fail;

	xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_TRANSFERRED);
	return 0;

fail:
	drm_err(&xe->drm, "Failed to load %s firmware %s (%d)\n",
		xe_uc_fw_type_repr(uc_fw->type), uc_fw->path,
		err);
	xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_LOAD_FAIL);
	return err;
}

static const char *version_type_repr(enum xe_uc_fw_version_types type)
{
	switch (type) {
	case XE_UC_FW_VER_RELEASE:
		return "release";
	case XE_UC_FW_VER_COMPATIBILITY:
		return "compatibility";
	default:
		return "Unknown version type";
	}
}

void xe_uc_fw_print(struct xe_uc_fw *uc_fw, struct drm_printer *p)
{
	int i;

	drm_printf(p, "%s firmware: %s\n",
		   xe_uc_fw_type_repr(uc_fw->type), uc_fw->path);
	drm_printf(p, "\tstatus: %s\n",
		   xe_uc_fw_status_repr(uc_fw->status));

	print_uc_fw_version(p, &uc_fw->versions.wanted, "\twanted %s",
			    version_type_repr(uc_fw->versions.wanted_type));

	for (i = 0; i < XE_UC_FW_VER_TYPE_COUNT; i++) {
		struct xe_uc_fw_version *ver = &uc_fw->versions.found[i];

		if (ver->major)
			print_uc_fw_version(p, ver, "\tfound %s",
					    version_type_repr(i));
	}

	if (uc_fw->ucode_size)
		drm_printf(p, "\tuCode: %u bytes\n", uc_fw->ucode_size);
	if (uc_fw->rsa_size)
		drm_printf(p, "\tRSA: %u bytes\n", uc_fw->rsa_size);
}
