[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250805064430.782201-3-jorge.ramirez@oss.qualcomm.com>
Date: Tue, 5 Aug 2025 08:44:25 +0200
From: Jorge Ramirez-Ortiz <jorge.ramirez@....qualcomm.com>
To: jorge.ramirez@....qualcomm.com, bryan.odonoghue@...aro.org,
quic_dikshita@...cinc.com, quic_vgarodia@...cinc.com,
konradybcio@...nel.org, krzk+dt@...nel.org
Cc: mchehab@...nel.org, conor+dt@...nel.org, andersson@...nel.org,
linux-media@...r.kernel.org, linux-arm-msm@...r.kernel.org,
devicetree@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH v8 2/7] media: venus: Define minimum valid firmware version
Add support for specifying the minimum firmware version required for
correct operation.
When set, the driver compares this value against the version reported by
the firmware: if the firmware is older than required, driver
initialization will fail.
The version check is performed before creating dynamic device tree
nodes, to avoid the need for reverting nodes on failure.
Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez@....qualcomm.com>
---
drivers/media/platform/qcom/venus/core.c | 40 +++++++++++---------
drivers/media/platform/qcom/venus/core.h | 7 ++++
drivers/media/platform/qcom/venus/firmware.c | 13 +++++++
drivers/media/platform/qcom/venus/firmware.h | 1 +
4 files changed, 43 insertions(+), 18 deletions(-)
diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index 4c049c694d9c..f45715c9b222 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -448,19 +448,9 @@ static int venus_probe(struct platform_device *pdev)
if (ret < 0)
goto err_runtime_disable;
- if (core->res->dec_nodename || core->res->enc_nodename) {
- ret = venus_add_dynamic_nodes(core);
- if (ret)
- goto err_runtime_disable;
- }
-
- ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
- if (ret)
- goto err_remove_dynamic_nodes;
-
ret = venus_firmware_init(core);
if (ret)
- goto err_of_depopulate;
+ goto err_runtime_disable;
ret = venus_boot(core);
if (ret)
@@ -474,34 +464,48 @@ static int venus_probe(struct platform_device *pdev)
if (ret)
goto err_venus_shutdown;
- ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_DEC);
+ ret = venus_firmware_check(core);
if (ret)
goto err_core_deinit;
+ if (core->res->dec_nodename || core->res->enc_nodename) {
+ ret = venus_add_dynamic_nodes(core);
+ if (ret)
+ goto err_core_deinit;
+ }
+
+ ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
+ if (ret)
+ goto err_remove_dynamic_nodes;
+
+ ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_DEC);
+ if (ret)
+ goto err_of_depopulate;
+
ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_ENC);
if (ret)
- goto err_core_deinit;
+ goto err_of_depopulate;
ret = pm_runtime_put_sync(dev);
if (ret) {
pm_runtime_get_noresume(dev);
- goto err_core_deinit;
+ goto err_of_depopulate;
}
venus_dbgfs_init(core);
return 0;
+err_of_depopulate:
+ of_platform_depopulate(dev);
+err_remove_dynamic_nodes:
+ venus_remove_dynamic_nodes(core);
err_core_deinit:
hfi_core_deinit(core, false);
err_venus_shutdown:
venus_shutdown(core);
err_firmware_deinit:
venus_firmware_deinit(core);
-err_of_depopulate:
- of_platform_depopulate(dev);
-err_remove_dynamic_nodes:
- venus_remove_dynamic_nodes(core);
err_runtime_disable:
pm_runtime_put_noidle(dev);
pm_runtime_disable(dev);
diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h
index 5b1ba1c69adb..2d3cf920198f 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -58,6 +58,12 @@ enum vpu_version {
VPU_VERSION_IRIS2_1,
};
+struct firmware_version {
+ u32 major;
+ u32 minor;
+ u32 rev;
+};
+
struct venus_resources {
u64 dma_mask;
const struct freq_tbl *freq_tbl;
@@ -94,6 +100,7 @@ struct venus_resources {
const char *fwname;
const char *enc_nodename;
const char *dec_nodename;
+ const struct firmware_version *min_fw;
};
enum venus_fmt {
diff --git a/drivers/media/platform/qcom/venus/firmware.c b/drivers/media/platform/qcom/venus/firmware.c
index 66a18830e66d..503dd270a14a 100644
--- a/drivers/media/platform/qcom/venus/firmware.c
+++ b/drivers/media/platform/qcom/venus/firmware.c
@@ -280,6 +280,19 @@ int venus_shutdown(struct venus_core *core)
return ret;
}
+int venus_firmware_check(struct venus_core *core)
+{
+ const struct firmware_version *ver = core->res->min_fw;
+
+ if (!ver)
+ return 0;
+
+ if (!is_fw_rev_or_newer(core, ver->major, ver->minor, ver->rev))
+ return -EINVAL;
+
+ return 0;
+}
+
int venus_firmware_init(struct venus_core *core)
{
struct platform_device_info info;
diff --git a/drivers/media/platform/qcom/venus/firmware.h b/drivers/media/platform/qcom/venus/firmware.h
index aaccd847fa30..ead39e3797f0 100644
--- a/drivers/media/platform/qcom/venus/firmware.h
+++ b/drivers/media/platform/qcom/venus/firmware.h
@@ -9,6 +9,7 @@ struct device;
int venus_firmware_init(struct venus_core *core);
void venus_firmware_deinit(struct venus_core *core);
+int venus_firmware_check(struct venus_core *core);
int venus_boot(struct venus_core *core);
int venus_shutdown(struct venus_core *core);
int venus_set_hw_state(struct venus_core *core, bool suspend);
--
2.34.1
Powered by blists - more mailing lists