On Fri Mar 13 18:49:36 2026 +0530, Vikash Garodia wrote:
> Currently the driver switches the vcodec GDSC to hardware (HW) mode
> before firmware load and boot sequence. GDSC can be powered off, keeping
> in hw mode, thereby the vcodec registers programmed in TrustZone (TZ)
> carry default (reset) values.
> Move the transition to HW mode after firmware load and boot sequence.
> 
> The bug was exposed with driver configuring different stream ids to
> different devices via iommu-map. With registers carrying reset values,
> VPU would not generate desired stream-id, thereby leading to SMMU fault.
> 
> For vpu4, when GDSC is switched to HW mode, there is a need to perform
> the reset operation. Without reset, there are occasional issues of
> register corruption observed. Hence the vpu GDSC switch also involves
> the reset.
> 
> Co-developed-by: Vishnu Reddy <[email protected]>
> Signed-off-by: Vishnu Reddy <[email protected]>
> Signed-off-by: Vikash Garodia <[email protected]>
> Reviewed-by: Dikshita Agarwal <[email protected]>
> Reviewed-by: Dmitry Baryshkov <[email protected]>
> [bod: occassional => occasional]
> Fixes: dde659d37036 ("media: iris: Introduce vpu ops for vpu4 with necessary 
> hooks")
> Cc: [email protected]
> Signed-off-by: Bryan O'Donoghue <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/platform/qcom/iris/iris_core.c       |  4 ++++
 drivers/media/platform/qcom/iris/iris_hfi_common.c |  4 ++++
 drivers/media/platform/qcom/iris/iris_vpu2.c       |  1 +
 drivers/media/platform/qcom/iris/iris_vpu3x.c      |  9 +++-----
 drivers/media/platform/qcom/iris/iris_vpu4x.c      | 24 ++++++++++++----------
 drivers/media/platform/qcom/iris/iris_vpu_common.c | 16 +++++++++------
 drivers/media/platform/qcom/iris/iris_vpu_common.h |  3 +++
 7 files changed, 38 insertions(+), 23 deletions(-)

---

diff --git a/drivers/media/platform/qcom/iris/iris_core.c 
b/drivers/media/platform/qcom/iris/iris_core.c
index 8406c48d635b..dbaac01eb15a 100644
--- a/drivers/media/platform/qcom/iris/iris_core.c
+++ b/drivers/media/platform/qcom/iris/iris_core.c
@@ -75,6 +75,10 @@ int iris_core_init(struct iris_core *core)
        if (ret)
                goto error_unload_fw;
 
+       ret = iris_vpu_switch_to_hwmode(core);
+       if (ret)
+               goto error_unload_fw;
+
        ret = iris_hfi_core_init(core);
        if (ret)
                goto error_unload_fw;
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.c 
b/drivers/media/platform/qcom/iris/iris_hfi_common.c
index 92112eb16c11..621c66593d88 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_common.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.c
@@ -159,6 +159,10 @@ int iris_hfi_pm_resume(struct iris_core *core)
        if (ret)
                goto err_suspend_hw;
 
+       ret = iris_vpu_switch_to_hwmode(core);
+       if (ret)
+               goto err_suspend_hw;
+
        ret = ops->sys_interframe_powercollapse(core);
        if (ret)
                goto err_suspend_hw;
diff --git a/drivers/media/platform/qcom/iris/iris_vpu2.c 
b/drivers/media/platform/qcom/iris/iris_vpu2.c
index 9c103a2e4e4e..01ef40f38957 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu2.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu2.c
@@ -44,4 +44,5 @@ const struct vpu_ops iris_vpu2_ops = {
        .power_off_controller = iris_vpu_power_off_controller,
        .power_on_controller = iris_vpu_power_on_controller,
        .calc_freq = iris_vpu2_calc_freq,
+       .set_hwmode = iris_vpu_set_hwmode,
 };
diff --git a/drivers/media/platform/qcom/iris/iris_vpu3x.c 
b/drivers/media/platform/qcom/iris/iris_vpu3x.c
index fe4423b951b1..3dad47be78b5 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu3x.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu3x.c
@@ -234,14 +234,8 @@ static int iris_vpu35_power_on_hw(struct iris_core *core)
        if (ret)
                goto err_disable_hw_free_clk;
 
-       ret = 
dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], 
true);
-       if (ret)
-               goto err_disable_hw_clk;
-
        return 0;
 
-err_disable_hw_clk:
-       iris_disable_unprepare_clock(core, IRIS_HW_CLK);
 err_disable_hw_free_clk:
        iris_disable_unprepare_clock(core, IRIS_HW_FREERUN_CLK);
 err_disable_axi_clk:
@@ -266,6 +260,7 @@ const struct vpu_ops iris_vpu3_ops = {
        .power_off_controller = iris_vpu_power_off_controller,
        .power_on_controller = iris_vpu_power_on_controller,
        .calc_freq = iris_vpu3x_vpu4x_calculate_frequency,
+       .set_hwmode = iris_vpu_set_hwmode,
 };
 
 const struct vpu_ops iris_vpu33_ops = {
@@ -274,6 +269,7 @@ const struct vpu_ops iris_vpu33_ops = {
        .power_off_controller = iris_vpu33_power_off_controller,
        .power_on_controller = iris_vpu_power_on_controller,
        .calc_freq = iris_vpu3x_vpu4x_calculate_frequency,
+       .set_hwmode = iris_vpu_set_hwmode,
 };
 
 const struct vpu_ops iris_vpu35_ops = {
@@ -283,4 +279,5 @@ const struct vpu_ops iris_vpu35_ops = {
        .power_on_controller = iris_vpu35_vpu4x_power_on_controller,
        .program_bootup_registers = iris_vpu35_vpu4x_program_bootup_registers,
        .calc_freq = iris_vpu3x_vpu4x_calculate_frequency,
+       .set_hwmode = iris_vpu_set_hwmode,
 };
diff --git a/drivers/media/platform/qcom/iris/iris_vpu4x.c 
b/drivers/media/platform/qcom/iris/iris_vpu4x.c
index a8db02ce5c5e..02e100a4045f 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu4x.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu4x.c
@@ -252,21 +252,10 @@ static int iris_vpu4x_power_on_hardware(struct iris_core 
*core)
                ret = iris_vpu4x_power_on_apv(core);
                if (ret)
                        goto disable_hw_clocks;
-
-               iris_vpu4x_ahb_sync_reset_apv(core);
        }
 
-       iris_vpu4x_ahb_sync_reset_hardware(core);
-
-       ret = iris_vpu4x_genpd_set_hwmode(core, true, efuse_value);
-       if (ret)
-               goto disable_apv_power_domain;
-
        return 0;
 
-disable_apv_power_domain:
-       if (!(efuse_value & DISABLE_VIDEO_APV_BIT))
-               iris_vpu4x_power_off_apv(core);
 disable_hw_clocks:
        iris_vpu4x_disable_hardware_clocks(core, efuse_value);
 disable_vpp1_power_domain:
@@ -359,6 +348,18 @@ disable_clocks_and_power:
        iris_disable_power_domains(core, 
core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
 }
 
+static int iris_vpu4x_set_hwmode(struct iris_core *core)
+{
+       u32 efuse_value = readl(core->reg_base + WRAPPER_EFUSE_MONITOR);
+
+       if (!(efuse_value & DISABLE_VIDEO_APV_BIT))
+               iris_vpu4x_ahb_sync_reset_apv(core);
+
+       iris_vpu4x_ahb_sync_reset_hardware(core);
+
+       return iris_vpu4x_genpd_set_hwmode(core, true, efuse_value);
+}
+
 const struct vpu_ops iris_vpu4x_ops = {
        .power_off_hw = iris_vpu4x_power_off_hardware,
        .power_on_hw = iris_vpu4x_power_on_hardware,
@@ -366,4 +367,5 @@ const struct vpu_ops iris_vpu4x_ops = {
        .power_on_controller = iris_vpu35_vpu4x_power_on_controller,
        .program_bootup_registers = iris_vpu35_vpu4x_program_bootup_registers,
        .calc_freq = iris_vpu3x_vpu4x_calculate_frequency,
+       .set_hwmode = iris_vpu4x_set_hwmode,
 };
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c 
b/drivers/media/platform/qcom/iris/iris_vpu_common.c
index 548e5f1727fd..69e6126dc4d9 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_common.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
@@ -292,14 +292,8 @@ int iris_vpu_power_on_hw(struct iris_core *core)
        if (ret && ret != -ENOENT)
                goto err_disable_hw_clock;
 
-       ret = 
dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], 
true);
-       if (ret)
-               goto err_disable_hw_ahb_clock;
-
        return 0;
 
-err_disable_hw_ahb_clock:
-       iris_disable_unprepare_clock(core, IRIS_HW_AHB_CLK);
 err_disable_hw_clock:
        iris_disable_unprepare_clock(core, IRIS_HW_CLK);
 err_disable_power:
@@ -308,6 +302,16 @@ err_disable_power:
        return ret;
 }
 
+int iris_vpu_set_hwmode(struct iris_core *core)
+{
+       return 
dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], 
true);
+}
+
+int iris_vpu_switch_to_hwmode(struct iris_core *core)
+{
+       return core->iris_platform_data->vpu_ops->set_hwmode(core);
+}
+
 int iris_vpu35_vpu4x_power_off_controller(struct iris_core *core)
 {
        u32 clk_rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h 
b/drivers/media/platform/qcom/iris/iris_vpu_common.h
index f6dffc613b82..dee3b1349c5e 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
@@ -21,6 +21,7 @@ struct vpu_ops {
        int (*power_on_controller)(struct iris_core *core);
        void (*program_bootup_registers)(struct iris_core *core);
        u64 (*calc_freq)(struct iris_inst *inst, size_t data_size);
+       int (*set_hwmode)(struct iris_core *core);
 };
 
 int iris_vpu_boot_firmware(struct iris_core *core);
@@ -30,6 +31,8 @@ int iris_vpu_watchdog(struct iris_core *core, u32 
intr_status);
 int iris_vpu_prepare_pc(struct iris_core *core);
 int iris_vpu_power_on_controller(struct iris_core *core);
 int iris_vpu_power_on_hw(struct iris_core *core);
+int iris_vpu_set_hwmode(struct iris_core *core);
+int iris_vpu_switch_to_hwmode(struct iris_core *core);
 int iris_vpu_power_on(struct iris_core *core);
 int iris_vpu_power_off_controller(struct iris_core *core);
 void iris_vpu_power_off_hw(struct iris_core *core);
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to