[PATCH v2 3/5] media: iris: Add IRIS_BSE_HW_CLK handling in vpu3 power on/off sequence

Wangao Wang posted 5 patches 1 month ago
There is a newer version of this series
[PATCH v2 3/5] media: iris: Add IRIS_BSE_HW_CLK handling in vpu3 power on/off sequence
Posted by Wangao Wang 1 month ago
On X1P42100 the Iris block has an extra BSE clock. Wire this clock into
the power on/off sequence.

The BSE clock is used to drive the Bin Stream Engine, which is a sub-block
of the video codec hardware responsible for bitstream-level processing. It
is required to be enabled separately from the core clock to ensure proper
codec operation.

Signed-off-by: Wangao Wang <wangao.wang@oss.qualcomm.com>
---
 drivers/media/platform/qcom/iris/iris_vpu3x.c | 55 +++++++++++++++++++++++++--
 1 file changed, 51 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/qcom/iris/iris_vpu3x.c b/drivers/media/platform/qcom/iris/iris_vpu3x.c
index fe4423b951b1e9e31d06dffc69d18071cc985731..3f9e67604ef6aad773837df584362446052e34c2 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu3x.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu3x.c
@@ -27,6 +27,53 @@ static bool iris_vpu3x_hw_power_collapsed(struct iris_core *core)
 	return pwr_status ? false : true;
 }
 
+static int iris_vpu3_power_on_hw(struct iris_core *core)
+{
+	int ret;
+
+	ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
+	if (ret)
+		return ret;
+
+	ret = iris_prepare_enable_clock(core, IRIS_HW_CLK);
+	if (ret)
+		goto err_disable_power;
+
+	ret = iris_prepare_enable_clock(core, IRIS_HW_AHB_CLK);
+	if (ret && ret != -ENOENT)
+		goto err_disable_hw_clock;
+
+	ret = iris_prepare_enable_clock(core, IRIS_BSE_HW_CLK);
+	if (ret && ret != -ENOENT)
+		goto err_disable_hw_ahb_clock;
+
+	ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], true);
+	if (ret)
+		goto err_disable_bse_hw_clock;
+
+	return 0;
+
+err_disable_bse_hw_clock:
+	iris_disable_unprepare_clock(core, IRIS_BSE_HW_CLK);
+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:
+	iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
+
+	return ret;
+}
+
+static void iris_vpu3_power_off_hw(struct iris_core *core)
+{
+	dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], false);
+	iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
+	iris_disable_unprepare_clock(core, IRIS_BSE_HW_CLK);
+	iris_disable_unprepare_clock(core, IRIS_HW_AHB_CLK);
+	iris_disable_unprepare_clock(core, IRIS_HW_CLK);
+}
+
 static void iris_vpu3_power_off_hardware(struct iris_core *core)
 {
 	u32 reg_val = 0, value, i;
@@ -68,7 +115,7 @@ static void iris_vpu3_power_off_hardware(struct iris_core *core)
 	writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
 
 disable_power:
-	iris_vpu_power_off_hw(core);
+	iris_vpu3_power_off_hw(core);
 }
 
 static void iris_vpu33_power_off_hardware(struct iris_core *core)
@@ -131,7 +178,7 @@ static void iris_vpu33_power_off_hardware(struct iris_core *core)
 	writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
 
 disable_power:
-	iris_vpu_power_off_hw(core);
+	iris_vpu3_power_off_hw(core);
 }
 
 static int iris_vpu33_power_off_controller(struct iris_core *core)
@@ -262,7 +309,7 @@ static void iris_vpu35_power_off_hw(struct iris_core *core)
 
 const struct vpu_ops iris_vpu3_ops = {
 	.power_off_hw = iris_vpu3_power_off_hardware,
-	.power_on_hw = iris_vpu_power_on_hw,
+	.power_on_hw = iris_vpu3_power_on_hw,
 	.power_off_controller = iris_vpu_power_off_controller,
 	.power_on_controller = iris_vpu_power_on_controller,
 	.calc_freq = iris_vpu3x_vpu4x_calculate_frequency,
@@ -270,7 +317,7 @@ const struct vpu_ops iris_vpu3_ops = {
 
 const struct vpu_ops iris_vpu33_ops = {
 	.power_off_hw = iris_vpu33_power_off_hardware,
-	.power_on_hw = iris_vpu_power_on_hw,
+	.power_on_hw = iris_vpu3_power_on_hw,
 	.power_off_controller = iris_vpu33_power_off_controller,
 	.power_on_controller = iris_vpu_power_on_controller,
 	.calc_freq = iris_vpu3x_vpu4x_calculate_frequency,

-- 
2.43.0
Re: [PATCH v2 3/5] media: iris: Add IRIS_BSE_HW_CLK handling in vpu3 power on/off sequence
Posted by Dmitry Baryshkov 1 month ago
On Fri, Mar 06, 2026 at 04:44:31PM +0800, Wangao Wang wrote:
> On X1P42100 the Iris block has an extra BSE clock. Wire this clock into
> the power on/off sequence.
> 
> The BSE clock is used to drive the Bin Stream Engine, which is a sub-block
> of the video codec hardware responsible for bitstream-level processing. It
> is required to be enabled separately from the core clock to ensure proper
> codec operation.

As far as I can see, Purwa is a one-off. Why are we forcing support for
the platform (and for the BSE clock) into the generic code?

> 
> Signed-off-by: Wangao Wang <wangao.wang@oss.qualcomm.com>
> ---
>  drivers/media/platform/qcom/iris/iris_vpu3x.c | 55 +++++++++++++++++++++++++--
>  1 file changed, 51 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu3x.c b/drivers/media/platform/qcom/iris/iris_vpu3x.c
> index fe4423b951b1e9e31d06dffc69d18071cc985731..3f9e67604ef6aad773837df584362446052e34c2 100644
> --- a/drivers/media/platform/qcom/iris/iris_vpu3x.c
> +++ b/drivers/media/platform/qcom/iris/iris_vpu3x.c
> @@ -27,6 +27,53 @@ static bool iris_vpu3x_hw_power_collapsed(struct iris_core *core)
>  	return pwr_status ? false : true;
>  }
>  
> +static int iris_vpu3_power_on_hw(struct iris_core *core)
> +{
> +	int ret;
> +
> +	ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
> +	if (ret)
> +		return ret;
> +
> +	ret = iris_prepare_enable_clock(core, IRIS_HW_CLK);
> +	if (ret)
> +		goto err_disable_power;
> +
> +	ret = iris_prepare_enable_clock(core, IRIS_HW_AHB_CLK);
> +	if (ret && ret != -ENOENT)
> +		goto err_disable_hw_clock;
> +
> +	ret = iris_prepare_enable_clock(core, IRIS_BSE_HW_CLK);
> +	if (ret && ret != -ENOENT)
> +		goto err_disable_hw_ahb_clock;
> +
> +	ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], true);
> +	if (ret)
> +		goto err_disable_bse_hw_clock;
> +
> +	return 0;
> +
> +err_disable_bse_hw_clock:
> +	iris_disable_unprepare_clock(core, IRIS_BSE_HW_CLK);
> +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:
> +	iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
> +
> +	return ret;
> +}
> +
> +static void iris_vpu3_power_off_hw(struct iris_core *core)
> +{
> +	dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], false);
> +	iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
> +	iris_disable_unprepare_clock(core, IRIS_BSE_HW_CLK);
> +	iris_disable_unprepare_clock(core, IRIS_HW_AHB_CLK);
> +	iris_disable_unprepare_clock(core, IRIS_HW_CLK);
> +}
> +
>  static void iris_vpu3_power_off_hardware(struct iris_core *core)
>  {
>  	u32 reg_val = 0, value, i;
> @@ -68,7 +115,7 @@ static void iris_vpu3_power_off_hardware(struct iris_core *core)
>  	writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
>  
>  disable_power:
> -	iris_vpu_power_off_hw(core);
> +	iris_vpu3_power_off_hw(core);
>  }
>  
>  static void iris_vpu33_power_off_hardware(struct iris_core *core)
> @@ -131,7 +178,7 @@ static void iris_vpu33_power_off_hardware(struct iris_core *core)
>  	writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
>  
>  disable_power:
> -	iris_vpu_power_off_hw(core);
> +	iris_vpu3_power_off_hw(core);
>  }
>  
>  static int iris_vpu33_power_off_controller(struct iris_core *core)
> @@ -262,7 +309,7 @@ static void iris_vpu35_power_off_hw(struct iris_core *core)
>  
>  const struct vpu_ops iris_vpu3_ops = {
>  	.power_off_hw = iris_vpu3_power_off_hardware,
> -	.power_on_hw = iris_vpu_power_on_hw,
> +	.power_on_hw = iris_vpu3_power_on_hw,
>  	.power_off_controller = iris_vpu_power_off_controller,
>  	.power_on_controller = iris_vpu_power_on_controller,
>  	.calc_freq = iris_vpu3x_vpu4x_calculate_frequency,
> @@ -270,7 +317,7 @@ const struct vpu_ops iris_vpu3_ops = {
>  
>  const struct vpu_ops iris_vpu33_ops = {
>  	.power_off_hw = iris_vpu33_power_off_hardware,
> -	.power_on_hw = iris_vpu_power_on_hw,
> +	.power_on_hw = iris_vpu3_power_on_hw,
>  	.power_off_controller = iris_vpu33_power_off_controller,
>  	.power_on_controller = iris_vpu_power_on_controller,
>  	.calc_freq = iris_vpu3x_vpu4x_calculate_frequency,
> 
> -- 
> 2.43.0
> 

-- 
With best wishes
Dmitry
Re: [PATCH v2 3/5] media: iris: Add IRIS_BSE_HW_CLK handling in vpu3 power on/off sequence
Posted by Wangao Wang 1 month ago

On 2026/3/10 7:58, Dmitry Baryshkov wrote:
> On Fri, Mar 06, 2026 at 04:44:31PM +0800, Wangao Wang wrote:
>> On X1P42100 the Iris block has an extra BSE clock. Wire this clock into
>> the power on/off sequence.
>>
>> The BSE clock is used to drive the Bin Stream Engine, which is a sub-block
>> of the video codec hardware responsible for bitstream-level processing. It
>> is required to be enabled separately from the core clock to ensure proper
>> codec operation.
> 
> As far as I can see, Purwa is a one-off. Why are we forcing support for
> the platform (and for the BSE clock) into the generic code?
> 
>>

So should I add a dedicated power on/off API for Purwa, and name it 
something like iris_vpu31_power_on_hw() / iris_vpu31_power_off_hw()?

-- 
Best Regards,
Wangao
Re: [PATCH v2 3/5] media: iris: Add IRIS_BSE_HW_CLK handling in vpu3 power on/off sequence
Posted by Dmitry Baryshkov 3 weeks, 6 days ago
On Tue, Mar 10, 2026 at 03:14:37PM +0800, Wangao Wang wrote:
> 
> 
> On 2026/3/10 7:58, Dmitry Baryshkov wrote:
> > On Fri, Mar 06, 2026 at 04:44:31PM +0800, Wangao Wang wrote:
> > > On X1P42100 the Iris block has an extra BSE clock. Wire this clock into
> > > the power on/off sequence.
> > > 
> > > The BSE clock is used to drive the Bin Stream Engine, which is a sub-block
> > > of the video codec hardware responsible for bitstream-level processing. It
> > > is required to be enabled separately from the core clock to ensure proper
> > > codec operation.
> > 
> > As far as I can see, Purwa is a one-off. Why are we forcing support for
> > the platform (and for the BSE clock) into the generic code?
> > 
> > > 
> 
> So should I add a dedicated power on/off API for Purwa, and name it
> something like iris_vpu31_power_on_hw() / iris_vpu31_power_off_hw()?

Or iris_vpu_purwa_power_on/off.

-- 
With best wishes
Dmitry