[PATCH v4 8/9] media: qcom: venus: add power domain enable logic for Venus cores

Erikas Bitovtas
2026-05-05T21:46:29Z

Attach power domains for vdec and venc cores and power them up if a vdec
or venc session is started.

Signed-off-by: Erikas Bitovtas <xerikasxx@gmail.com>
---
drivers/media/platform/qcom/venus/pm_helpers.c | 80 +++++++++++++++++++++++++-
1 file changed, 78 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c
index f0269524ac70..c8f7f220c713 100644
--- a/drivers/media/platform/qcom/venus/pm_helpers.c
+++ b/drivers/media/platform/qcom/venus/pm_helpers.c
@@ -299,8 +299,22 @@ static int load_scale_v1(struct venus_inst *inst)

static int core_get_v1(struct venus_core *core)
{
+ struct device *dev = core->dev;
+ const struct venus_resources *res = core->res;
+ const struct dev_pm_domain_attach_data vcodec_data = {
+ .pd_names = res->vcodec_pmdomains,
+ .num_pd_names = res->vcodec_pmdomains_num,
+ .pd_flags = PD_FLAG_NO_DEV_LINK,
+ };
int ret;

+ if (res->vcodec_pmdomains) {
+ ret = dev_pm_domain_attach_list(dev, &vcodec_data,
+ &core->pmdomains);
+ if (ret < 0)
+ return ret;
+ }
+
ret = core_clks_get(core);
if (ret)
return ret;
@@ -319,12 +333,70 @@ static void core_put_v1(struct venus_core *core)
static int core_power_v1(struct venus_core *core, int on)
{
int ret = 0;
+ struct device *pd_dev = core->res->vcodec_pmdomains ?
+ core->pmdomains->pd_devs[0] : NULL;

- if (on == POWER_ON)
+ if (on == POWER_ON) {
+ if (pd_dev) {
+ ret = pm_runtime_resume_and_get(pd_dev);
+ if (ret)
+ return ret;
+ }
ret = core_clks_enable(core);
- else
+ if (ret) {
+ pm_runtime_put_sync(pd_dev);
+ return ret;
+ }
+ } else {
+ if (pd_dev)
+ pm_runtime_put_sync(pd_dev);
core_clks_disable(core);
+ }

+ return 0;
+}
+
+static int vcodec_get_v1(struct device *dev)
+{
+ struct venus_core *core = dev_get_drvdata(dev);
+
+ return vcodec_clks_get(core, core->dev, core->vcodec_clks,
+ core->res->vcodec_clks);
+}
+
+static int vcodec_power_v1(struct device *dev, int on)
+{
+ struct venus_core *core = dev_get_drvdata(dev);
+ const struct venus_resources *res = core->res;
+ struct device *pd_dev;
+ int i = 1, ret;
+
+ if (on == POWER_ON) {
+ if (res->vcodec_pmdomains) {
+ for (; i < res->vcodec_pmdomains_num; i++) {
+ pd_dev = core->pmdomains->pd_devs[i];
+ ret = pm_runtime_resume_and_get(pd_dev);
+ if (ret)
+ goto err;
+ }
+ }
+
+ ret = vcodec_clks_enable(core, core->vcodec_clks);
+ if (ret)
+ goto err;
+ } else {
+ if (res->vcodec_pmdomains)
+ for (; i < res->vcodec_pmdomains_num; i++) {
+ pd_dev = core->pmdomains->pd_devs[i];
+ pm_runtime_put_sync(pd_dev);
+ }
+ vcodec_clks_disable(core, core->vcodec_clks);
+ }
+
+ return 0;
+err:
+ while (i-- > 1)
+ pm_runtime_put_sync(core->pmdomains->pd_devs[i]);
return ret;
}

@@ -332,6 +404,10 @@ static const struct venus_pm_ops pm_ops_v1 = {
.core_get = core_get_v1,
.core_put = core_put_v1,
.core_power = core_power_v1,
+ .vdec_get = vcodec_get_v1,
+ .vdec_power = vcodec_power_v1,
+ .venc_get = vcodec_get_v1,
+ .venc_power = vcodec_power_v1,
.load_scale = load_scale_v1,
};

--
2.54.0