From 03746519c9d23d1172c295658010b0b873e68155 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Date: Wed, 30 Aug 2023 04:35:31 +0300
Subject: [PATCH 2/4] drm/msm/gpu: use devlink to manage GX domain state

Instead of manually toggling the GX domain, use corresponding deivce
link. This ensures that GX domain follows the state of the device and
doesn't get toggled too fast (which is ensured by the autosuspend delay
set for the GPU device).

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 kernel/drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 28 ++++++++++++--------
 kernel/drivers/gpu/drm/msm/adreno/a5xx_gpu.h |  1 +
 2 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/kernel/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/kernel/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 6cb33af3612f..47cf3facce37 100644
--- a/kernel/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/kernel/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -1084,6 +1084,9 @@ static void a5xx_destroy(struct msm_gpu *gpu)
 	if (a5xx_gpu->mx_link)
 		device_link_del(a5xx_gpu->mx_link);
 
+	if (a5xx_gpu->gx_link)
+		device_link_del(a5xx_gpu->gx_link);
+
 	if (a5xx_gpu->gxpd)
 		dev_pm_domain_detach(a5xx_gpu->gxpd, true);
 
@@ -1385,15 +1388,8 @@ static void a5xx_dump(struct msm_gpu *gpu)
 static int a5xx_pm_resume(struct msm_gpu *gpu)
 {
 	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
-	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
 	int ret;
 
-	if (a5xx_gpu->gxpd) {
-		ret = pm_runtime_resume_and_get(a5xx_gpu->gxpd);
-		if (ret < 0)
-			return ret;
-	}
-
 	/* Turn on the core power */
 	ret = msm_gpu_pm_resume_no_devfreq(gpu);
 	if (ret)
@@ -1468,9 +1464,6 @@ static int a5xx_pm_suspend(struct msm_gpu *gpu)
 	if (ret)
 		return ret;
 
-	if (a5xx_gpu->gxpd)
-		pm_runtime_put(a5xx_gpu->gxpd);
-
 	if (a5xx_gpu->has_whereami)
 		for (i = 0; i < gpu->nr_rings; i++)
 			a5xx_gpu->shadow[i] = 0;
@@ -1855,8 +1848,18 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
 
 		a5xx_gpu->gxpd = pd;
 
+		a5xx_gpu->gx_link = device_link_add(&pdev->dev, a5xx_gpu->gxpd,
+						    DL_FLAG_RPM_ACTIVE |
+						    DL_FLAG_PM_RUNTIME |
+						    DL_FLAG_STATELESS);
+		if (!a5xx_gpu->gx_link) {
+			dev_pm_domain_detach(a5xx_gpu->gxpd, true);
+			return ERR_PTR(-ENODEV);
+		}
+
 		ret = devm_pm_opp_attach_genpd(&pdev->dev, cpr_genpd_names, &opp_virt_dev);
 		if (ret) {
+			device_link_del(a5xx_gpu->gx_link);
 			dev_pm_domain_detach(a5xx_gpu->gxpd, true);
 			return ERR_PTR(ret);
 		}
@@ -1865,8 +1868,11 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
 						    DL_FLAG_RPM_ACTIVE |
 						    DL_FLAG_PM_RUNTIME |
 						    DL_FLAG_STATELESS);
-		if (!a5xx_gpu->mx_link)
+		if (!a5xx_gpu->mx_link) {
+			device_link_del(a5xx_gpu->gx_link);
+			dev_pm_domain_detach(a5xx_gpu->gxpd, true);
 			return ERR_PTR(-ENODEV);
+		}
 	}
 
 	check_speed_bin(&pdev->dev);
diff --git a/kernel/drivers/gpu/drm/msm/adreno/a5xx_gpu.h b/kernel/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
index 36e910397c14..89357c4b1811 100644
--- a/kernel/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
+++ b/kernel/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
@@ -46,6 +46,7 @@ struct a5xx_gpu {
 	bool has_whereami;
 
 	struct device *gxpd;
+	struct device_link *gx_link;
 	struct device_link *mx_link;
 };
 
-- 
2.39.2

