Skip to content

Commit d98d7db

Browse files
Vikash Garodiagouravk-qualcomm
authored andcommitted
FROMLIST: media: iris: switch to hardware mode after firmware boot
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. Link: https://lore.kernel.org/linux-media/20260126-kaanapali-iris-v1-4-e2646246bfc1@oss.qualcomm.com/ Co-developed-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com> Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com> Signed-off-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com> Reviewed-by: Dikshita Agarwal <dikshita.agarwal@oss.qualcomm.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> [bod: occassional => occasional] Fixes: dde659d ("media: iris: Introduce vpu ops for vpu4 with necessary hooks") Cc: stable@vger.kernel.org Signed-off-by: Bryan O'Donoghue <bod@kernel.org> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
1 parent 8d9f545 commit d98d7db

7 files changed

Lines changed: 38 additions & 23 deletions

File tree

drivers/media/platform/qcom/iris/iris_core.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ int iris_core_init(struct iris_core *core)
8181

8282
core->iris_firmware_data->init_hfi_ops(core);
8383

84+
ret = iris_vpu_switch_to_hwmode(core);
85+
if (ret)
86+
goto error_unload_fw;
87+
8488
ret = iris_hfi_core_init(core);
8589
if (ret)
8690
goto error_unload_fw;

drivers/media/platform/qcom/iris/iris_hfi_common.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,10 @@ int iris_hfi_pm_resume(struct iris_core *core)
159159
if (ret)
160160
goto err_suspend_hw;
161161

162+
ret = iris_vpu_switch_to_hwmode(core);
163+
if (ret)
164+
goto err_suspend_hw;
165+
162166
ret = ops->sys_interframe_powercollapse(core);
163167
if (ret)
164168
goto err_suspend_hw;

drivers/media/platform/qcom/iris/iris_vpu2.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,5 @@ const struct vpu_ops iris_vpu2_ops = {
4444
.power_off_controller = iris_vpu_power_off_controller,
4545
.power_on_controller = iris_vpu_power_on_controller,
4646
.calc_freq = iris_vpu2_calc_freq,
47+
.set_hwmode = iris_vpu_set_hwmode,
4748
};

drivers/media/platform/qcom/iris/iris_vpu3x.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,14 +234,8 @@ static int iris_vpu35_power_on_hw(struct iris_core *core)
234234
if (ret)
235235
goto err_disable_hw_free_clk;
236236

237-
ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], true);
238-
if (ret)
239-
goto err_disable_hw_clk;
240-
241237
return 0;
242238

243-
err_disable_hw_clk:
244-
iris_disable_unprepare_clock(core, IRIS_HW_CLK);
245239
err_disable_hw_free_clk:
246240
iris_disable_unprepare_clock(core, IRIS_HW_FREERUN_CLK);
247241
err_disable_axi_clk:
@@ -266,6 +260,7 @@ const struct vpu_ops iris_vpu3_ops = {
266260
.power_off_controller = iris_vpu_power_off_controller,
267261
.power_on_controller = iris_vpu_power_on_controller,
268262
.calc_freq = iris_vpu3x_vpu4x_calculate_frequency,
263+
.set_hwmode = iris_vpu_set_hwmode,
269264
};
270265

271266
const struct vpu_ops iris_vpu33_ops = {
@@ -274,6 +269,7 @@ const struct vpu_ops iris_vpu33_ops = {
274269
.power_off_controller = iris_vpu33_power_off_controller,
275270
.power_on_controller = iris_vpu_power_on_controller,
276271
.calc_freq = iris_vpu3x_vpu4x_calculate_frequency,
272+
.set_hwmode = iris_vpu_set_hwmode,
277273
};
278274

279275
const struct vpu_ops iris_vpu35_ops = {
@@ -283,4 +279,5 @@ const struct vpu_ops iris_vpu35_ops = {
283279
.power_on_controller = iris_vpu35_vpu4x_power_on_controller,
284280
.program_bootup_registers = iris_vpu35_vpu4x_program_bootup_registers,
285281
.calc_freq = iris_vpu3x_vpu4x_calculate_frequency,
282+
.set_hwmode = iris_vpu_set_hwmode,
286283
};

drivers/media/platform/qcom/iris/iris_vpu4x.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -252,21 +252,10 @@ static int iris_vpu4x_power_on_hardware(struct iris_core *core)
252252
ret = iris_vpu4x_power_on_apv(core);
253253
if (ret)
254254
goto disable_hw_clocks;
255-
256-
iris_vpu4x_ahb_sync_reset_apv(core);
257255
}
258256

259-
iris_vpu4x_ahb_sync_reset_hardware(core);
260-
261-
ret = iris_vpu4x_genpd_set_hwmode(core, true, efuse_value);
262-
if (ret)
263-
goto disable_apv_power_domain;
264-
265257
return 0;
266258

267-
disable_apv_power_domain:
268-
if (!(efuse_value & DISABLE_VIDEO_APV_BIT))
269-
iris_vpu4x_power_off_apv(core);
270259
disable_hw_clocks:
271260
iris_vpu4x_disable_hardware_clocks(core, efuse_value);
272261
disable_vpp1_power_domain:
@@ -359,11 +348,24 @@ static void iris_vpu4x_power_off_hardware(struct iris_core *core)
359348
iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
360349
}
361350

351+
static int iris_vpu4x_set_hwmode(struct iris_core *core)
352+
{
353+
u32 efuse_value = readl(core->reg_base + WRAPPER_EFUSE_MONITOR);
354+
355+
if (!(efuse_value & DISABLE_VIDEO_APV_BIT))
356+
iris_vpu4x_ahb_sync_reset_apv(core);
357+
358+
iris_vpu4x_ahb_sync_reset_hardware(core);
359+
360+
return iris_vpu4x_genpd_set_hwmode(core, true, efuse_value);
361+
}
362+
362363
const struct vpu_ops iris_vpu4x_ops = {
363364
.power_off_hw = iris_vpu4x_power_off_hardware,
364365
.power_on_hw = iris_vpu4x_power_on_hardware,
365366
.power_off_controller = iris_vpu35_vpu4x_power_off_controller,
366367
.power_on_controller = iris_vpu35_vpu4x_power_on_controller,
367368
.program_bootup_registers = iris_vpu35_vpu4x_program_bootup_registers,
368369
.calc_freq = iris_vpu3x_vpu4x_calculate_frequency,
370+
.set_hwmode = iris_vpu4x_set_hwmode,
369371
};

drivers/media/platform/qcom/iris/iris_vpu_common.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -297,14 +297,8 @@ int iris_vpu_power_on_hw(struct iris_core *core)
297297
if (ret && ret != -ENOENT)
298298
goto err_disable_hw_ahb_clock;
299299

300-
ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], true);
301-
if (ret)
302-
goto err_disable_bse_hw_clock;
303-
304300
return 0;
305301

306-
err_disable_bse_hw_clock:
307-
iris_disable_unprepare_clock(core, IRIS_BSE_HW_CLK);
308302
err_disable_hw_ahb_clock:
309303
iris_disable_unprepare_clock(core, IRIS_HW_AHB_CLK);
310304
err_disable_hw_clock:
@@ -315,6 +309,16 @@ int iris_vpu_power_on_hw(struct iris_core *core)
315309
return ret;
316310
}
317311

312+
int iris_vpu_set_hwmode(struct iris_core *core)
313+
{
314+
return dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], true);
315+
}
316+
317+
int iris_vpu_switch_to_hwmode(struct iris_core *core)
318+
{
319+
return core->iris_platform_data->vpu_ops->set_hwmode(core);
320+
}
321+
318322
int iris_vpu35_vpu4x_power_off_controller(struct iris_core *core)
319323
{
320324
u32 clk_rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;

drivers/media/platform/qcom/iris/iris_vpu_common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct vpu_ops {
2121
int (*power_on_controller)(struct iris_core *core);
2222
void (*program_bootup_registers)(struct iris_core *core);
2323
u64 (*calc_freq)(struct iris_inst *inst, size_t data_size);
24+
int (*set_hwmode)(struct iris_core *core);
2425
};
2526

2627
int iris_vpu_boot_firmware(struct iris_core *core);
@@ -30,6 +31,8 @@ int iris_vpu_watchdog(struct iris_core *core, u32 intr_status);
3031
int iris_vpu_prepare_pc(struct iris_core *core);
3132
int iris_vpu_power_on_controller(struct iris_core *core);
3233
int iris_vpu_power_on_hw(struct iris_core *core);
34+
int iris_vpu_set_hwmode(struct iris_core *core);
35+
int iris_vpu_switch_to_hwmode(struct iris_core *core);
3336
int iris_vpu_power_on(struct iris_core *core);
3437
int iris_vpu_power_off_controller(struct iris_core *core);
3538
void iris_vpu_power_off_hw(struct iris_core *core);

0 commit comments

Comments
 (0)