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

Erikas Bitovtas <[email protected]>
Newsgroups org.kernel.vger.phone-devel,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-clk,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel,org.kernel.vger.linux-media
Message-ID <[email protected]>
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 <[email protected]>
---
 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.