From: Karol Wachowski <karol.wachowski@linux.intel.com>
To: dri-devel@lists.freedesktop.org
Cc: oded.gabbay@gmail.com, jeff.hugo@oss.qualcomm.com,
lizhi.hou@amd.com, andrzej.kacprowski@linux.intel.com,
dawid.osuchowski@linux.intel.com,
Karol Wachowski <karol.wachowski@linux.intel.com>
Subject: [PATCH] accel/ivpu: Cache FW API version and simplify API check macros
Date: Mon, 12 Oct 2026 10:09:33 +0200 [thread overview]
Message-ID: <20261012080933.2771862-1-karol.wachowski@linux.intel.com> (raw)
Copy the API version array from the firmware image header into
struct ivpu_fw_info while the header is being parsed, and use the
cached copy afterwards. This way the raw firmware image header is only
accessed during image parsing, which is a step towards releasing the
firmware image once it has been loaded.
Since the API version is now available in vdev->fw before the
compatibility checks run, drop the redundant fw_hdr parameter from
IVPU_FW_CHECK_API_COMPAT(), IVPU_FW_CHECK_API_VER_LT() and the helpers
behind them, as well as from ivpu_fw_sched_mode_select().
Also make DRM_IVPU_PARAM_FW_API_VERSION read the cached copy instead of
dereferencing the firmware image directly.
No functional change.
Co-developed-by: Andrzej Kacprowski <andrzej.kacprowski@linux.intel.com>
Signed-off-by: Andrzej Kacprowski <andrzej.kacprowski@linux.intel.com>
Signed-off-by: Karol Wachowski <karol.wachowski@linux.intel.com>
---
drivers/accel/ivpu/ivpu_drv.c | 5 +----
drivers/accel/ivpu/ivpu_fw.c | 36 +++++++++++++++++------------------
drivers/accel/ivpu/ivpu_fw.h | 1 +
3 files changed, 20 insertions(+), 22 deletions(-)
diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c
index 8c3fb0f01a31..ada18a36caef 100644
--- a/drivers/accel/ivpu/ivpu_drv.c
+++ b/drivers/accel/ivpu/ivpu_drv.c
@@ -290,10 +290,7 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
break;
case DRM_IVPU_PARAM_FW_API_VERSION:
if (args->index < VPU_FW_API_VER_NUM) {
- struct vpu_firmware_header *fw_hdr;
-
- fw_hdr = (struct vpu_firmware_header *)vdev->fw->file->data;
- args->value = fw_hdr->api_version[args->index];
+ args->value = vdev->fw->api_version[args->index];
} else {
ret = -EINVAL;
}
diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c
index f9ddaa2420c4..71ac0a861935 100644
--- a/drivers/accel/ivpu/ivpu_fw.c
+++ b/drivers/accel/ivpu/ivpu_fw.c
@@ -28,15 +28,15 @@
#define ADDR_TO_L2_CACHE_CFG(addr) ((addr) >> 31)
/* Check if FW API is compatible with the driver */
-#define IVPU_FW_CHECK_API_COMPAT(vdev, fw_hdr, name, min_major) \
- ivpu_fw_check_api(vdev, fw_hdr, #name, \
+#define IVPU_FW_CHECK_API_COMPAT(vdev, name, min_major) \
+ ivpu_fw_check_api(vdev, #name, \
VPU_##name##_API_VER_INDEX, \
VPU_##name##_API_VER_MAJOR, \
VPU_##name##_API_VER_MINOR, min_major)
/* Check if API version is lower that the given version */
-#define IVPU_FW_CHECK_API_VER_LT(vdev, fw_hdr, name, major, minor) \
- ivpu_fw_check_api_ver_lt(vdev, fw_hdr, #name, VPU_##name##_API_VER_INDEX, major, minor)
+#define IVPU_FW_CHECK_API_VER_LT(vdev, name, major, minor) \
+ ivpu_fw_check_api_ver_lt(vdev, #name, VPU_##name##_API_VER_INDEX, major, minor)
#define IVPU_FOCUS_PRESENT_TIMER_MS 1000
@@ -93,12 +93,11 @@ static int ivpu_fw_request(struct ivpu_device *vdev)
}
static int
-ivpu_fw_check_api(struct ivpu_device *vdev, const struct vpu_firmware_header *fw_hdr,
- const char *str, int index, u16 expected_major, u16 expected_minor,
- u16 min_major)
+ivpu_fw_check_api(struct ivpu_device *vdev, const char *str, int index, u16 expected_major,
+ u16 expected_minor, u16 min_major)
{
- u16 major = (u16)(fw_hdr->api_version[index] >> 16);
- u16 minor = (u16)(fw_hdr->api_version[index]);
+ u16 major = (u16)(vdev->fw->api_version[index] >> 16);
+ u16 minor = (u16)(vdev->fw->api_version[index]);
if (major < min_major) {
ivpu_err(vdev, "Incompatible FW %s API version: %d.%d, required %d.0 or later\n",
@@ -116,11 +115,10 @@ ivpu_fw_check_api(struct ivpu_device *vdev, const struct vpu_firmware_header *fw
}
static bool
-ivpu_fw_check_api_ver_lt(struct ivpu_device *vdev, const struct vpu_firmware_header *fw_hdr,
- const char *str, int index, u16 major, u16 minor)
+ivpu_fw_check_api_ver_lt(struct ivpu_device *vdev, const char *str, int index, u16 major, u16 minor)
{
- u16 fw_major = (u16)(fw_hdr->api_version[index] >> 16);
- u16 fw_minor = (u16)(fw_hdr->api_version[index]);
+ u16 fw_major = (u16)(vdev->fw->api_version[index] >> 16);
+ u16 fw_minor = (u16)(vdev->fw->api_version[index]);
if (fw_major < major || (fw_major == major && fw_minor < minor))
return true;
@@ -142,7 +140,7 @@ bool ivpu_is_within_range(u64 addr, size_t size, struct ivpu_addr_range *range)
}
static u32
-ivpu_fw_sched_mode_select(struct ivpu_device *vdev, const struct vpu_firmware_header *fw_hdr)
+ivpu_fw_sched_mode_select(struct ivpu_device *vdev)
{
if (ivpu_hw_ip_gen(vdev) >= IVPU_HW_IP_60XX &&
ivpu_sched_mode == VPU_SCHEDULING_MODE_OS) {
@@ -153,7 +151,7 @@ ivpu_fw_sched_mode_select(struct ivpu_device *vdev, const struct vpu_firmware_he
if (ivpu_sched_mode != IVPU_SCHED_MODE_AUTO)
return ivpu_sched_mode;
- if (IVPU_FW_CHECK_API_VER_LT(vdev, fw_hdr, JSM, 3, 24))
+ if (IVPU_FW_CHECK_API_VER_LT(vdev, JSM, 3, 24))
return VPU_SCHEDULING_MODE_OS;
return VPU_SCHEDULING_MODE_HW;
@@ -302,9 +300,11 @@ static int ivpu_fw_parse(struct ivpu_device *vdev)
ivpu_info(vdev, "Firmware: %s, version: %s\n", fw->name, fw->version);
- if (IVPU_FW_CHECK_API_COMPAT(vdev, fw_hdr, BOOT, 3))
+ memcpy(fw->api_version, fw_hdr->api_version, sizeof(fw->api_version));
+
+ if (IVPU_FW_CHECK_API_COMPAT(vdev, BOOT, 3))
return -EINVAL;
- if (IVPU_FW_CHECK_API_COMPAT(vdev, fw_hdr, JSM, 3))
+ if (IVPU_FW_CHECK_API_COMPAT(vdev, JSM, 3))
return -EINVAL;
fw->boot_params_addr = boot_params_addr;
@@ -324,7 +324,7 @@ static int ivpu_fw_parse(struct ivpu_device *vdev)
fw->dvfs_mode = 0;
- fw->sched_mode = ivpu_fw_sched_mode_select(vdev, fw_hdr);
+ fw->sched_mode = ivpu_fw_sched_mode_select(vdev);
ivpu_info(vdev, "Scheduler mode: %s\n", fw->sched_mode ? "HW" : "OS");
ivpu_preemption_config_parse(vdev, fw_hdr);
diff --git a/drivers/accel/ivpu/ivpu_fw.h b/drivers/accel/ivpu/ivpu_fw.h
index d3c410912c9c..e7045b47dfaf 100644
--- a/drivers/accel/ivpu/ivpu_fw.h
+++ b/drivers/accel/ivpu/ivpu_fw.h
@@ -20,6 +20,7 @@ struct ivpu_fw_info {
const struct firmware *file;
const char *name;
char version[FW_VERSION_STR_SIZE];
+ u32 api_version[VPU_FW_API_VER_NUM];
struct ivpu_bo *mem_bp;
struct ivpu_bo *mem_fw_ver;
struct ivpu_bo *mem;
--
2.43.0
next reply other threads:[~2026-10-12 8:10 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-12 8:09 Karol Wachowski [this message]
2026-10-12 10:38 ` [PATCH] accel/ivpu: Cache FW API version and simplify API check macros Dawid Osuchowski
2026-10-14 6:05 ` Wachowski, Karol
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261012080933.2771862-1-karol.wachowski@linux.intel.com \
--to=karol.wachowski@linux.intel.com \
--cc=andrzej.kacprowski@linux.intel.com \
--cc=dawid.osuchowski@linux.intel.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=jeff.hugo@oss.qualcomm.com \
--cc=lizhi.hou@amd.com \
--cc=oded.gabbay@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.