All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sharat Masetty <smasetty@codeaurora.org>
To: freedreno@lists.freedesktop.org, devicetree@vger.kernel.org
Cc: dri-devel@freedesktop.org, linux-arm-msm@vger.kernel.org,
	linux-kernel@vger.kernel.org, jcrouse@codeaurora.org,
	mka@chromium.org, sibis@codeaurora.org, saravanak@google.com,
	viresh.kumar@linaro.org, Sharat Masetty <smasetty@codeaurora.org>
Subject: [PATCH 3/5] drm: msm: scale DDR BW along with GPU frequency
Date: Tue, 31 Mar 2020 13:25:51 +0530	[thread overview]
Message-ID: <1585641353-23229-4-git-send-email-smasetty@codeaurora.org> (raw)
In-Reply-To: <1585641353-23229-1-git-send-email-smasetty@codeaurora.org>

This patch adds support to parse the OPP tables attached the GPU device,
the main opp table and the DDR bandwidth opp table. Additionally, vote
for the GPU->DDR bandwidth when setting the GPU frequency by querying
the linked DDR BW opp to the GPU opp.

Signed-off-by: Sharat Masetty <smasetty@codeaurora.org>
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c   | 41 ++++++++++++++++++++++++++----
 drivers/gpu/drm/msm/adreno/adreno_gpu.c | 44 +++++++++++++++++++++++++++++----
 drivers/gpu/drm/msm/msm_gpu.h           |  9 +++++++
 3 files changed, 84 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 748cd37..489d9b6 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -100,6 +100,40 @@ bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)
 		A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_CLK_OFF));
 }

+void a6xx_gmu_set_icc_vote(struct msm_gpu *gpu, unsigned long gpu_freq)
+{
+	struct dev_pm_opp *gpu_opp, *ddr_opp;
+	struct opp_table **tables = gpu->opp_tables;
+	unsigned long peak_bw;
+
+	if (!gpu->opp_tables[GPU_DDR_OPP_TABLE_INDEX])
+		goto done;
+
+	gpu_opp = dev_pm_opp_find_freq_exact(&gpu->pdev->dev, gpu_freq, true);
+	if (IS_ERR_OR_NULL(gpu_opp))
+		goto done;
+
+	ddr_opp = dev_pm_opp_xlate_required_opp(tables[GPU_OPP_TABLE_INDEX],
+					    tables[GPU_DDR_OPP_TABLE_INDEX],
+					    gpu_opp);
+	dev_pm_opp_put(gpu_opp);
+
+	if (IS_ERR_OR_NULL(ddr_opp))
+		goto done;
+
+	peak_bw = dev_pm_opp_get_bw(ddr_opp, NULL);
+	dev_pm_opp_put(ddr_opp);
+
+	icc_set_bw(gpu->icc_path, 0, peak_bw);
+	return;
+done:
+	/*
+	 * If there is a problem, for now leave it at max so that the
+	 * performance is nominal.
+	 */
+	icc_set_bw(gpu->icc_path, 0, MBps_to_icc(7216));
+}
+
 static void __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)
 {
 	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
@@ -128,11 +162,8 @@ static void __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)

 	gmu->freq = gmu->gpu_freqs[index];

-	/*
-	 * Eventually we will want to scale the path vote with the frequency but
-	 * for now leave it at max so that the performance is nominal.
-	 */
-	icc_set_bw(gpu->icc_path, 0, MBps_to_icc(7216));
+	if (gpu->icc_path)
+		a6xx_gmu_set_icc_vote(gpu, gmu->freq);
 }

 void a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long freq)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 2d13694..bbbcc7a 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -882,7 +882,7 @@ static int adreno_get_pwrlevels(struct device *dev,
 {
 	unsigned long freq = ULONG_MAX;
 	struct dev_pm_opp *opp;
-	int ret;
+	int ret, i;

 	gpu->fast_rate = 0;

@@ -890,9 +890,29 @@ static int adreno_get_pwrlevels(struct device *dev,
 	if (!of_find_property(dev->of_node, "operating-points-v2", NULL))
 		ret = adreno_get_legacy_pwrlevels(dev);
 	else {
-		ret = dev_pm_opp_of_add_table(dev);
-		if (ret)
-			DRM_DEV_ERROR(dev, "Unable to set the OPP table\n");
+		int count = of_count_phandle_with_args(dev->of_node,
+				"operating-points-v2", NULL);
+
+		count = min(count, GPU_DDR_OPP_TABLE_INDEX + 1);
+		count = max(count, 1);
+
+		for (i = 0; i < count; i++) {
+			ret = dev_pm_opp_of_add_table_indexed(dev, i);
+			if (ret) {
+				DRM_DEV_ERROR(dev, "Add OPP table %d: failed %d\n",
+						i, ret);
+				goto err;
+			}
+
+			gpu->opp_tables[i] =
+				dev_pm_opp_get_opp_table_indexed(dev, i);
+			if (!gpu->opp_tables[i]) {
+				DRM_DEV_ERROR(dev, "Get OPP table failed index %d\n",
+						i);
+				ret = -EINVAL;
+				goto err;
+			}
+		}
 	}

 	if (!ret) {
@@ -919,12 +939,24 @@ static int adreno_get_pwrlevels(struct device *dev,
 		gpu->icc_path = NULL;

 	return 0;
+err:
+	for (; i >= 0; i--) {
+		if (gpu->opp_tables[i]) {
+			dev_pm_opp_put_opp_table(gpu->opp_tables[i]);
+			gpu->opp_tables[i] = NULL;
+		}
+	}
+
+	dev_pm_opp_remove_table(dev);
+	return ret;
 }

 int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
 		struct adreno_gpu *adreno_gpu,
 		const struct adreno_gpu_funcs *funcs, int nr_rings)
 {
+	int ret = 0;
+
 	struct adreno_platform_config *config = pdev->dev.platform_data;
 	struct msm_gpu_config adreno_gpu_config  = { 0 };
 	struct msm_gpu *gpu = &adreno_gpu->base;
@@ -945,7 +977,9 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,

 	adreno_gpu_config.nr_rings = nr_rings;

-	adreno_get_pwrlevels(&pdev->dev, gpu);
+	ret = adreno_get_pwrlevels(&pdev->dev, gpu);
+	if (ret)
+		return ret;

 	pm_runtime_set_autosuspend_delay(&pdev->dev,
 		adreno_gpu->info->inactive_period);
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index ab8f0f9c..5b98b48 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -66,6 +66,12 @@ struct msm_gpu_funcs {
 	void (*gpu_set_freq)(struct msm_gpu *gpu, unsigned long freq);
 };

+/* opp table indices */
+enum {
+	GPU_OPP_TABLE_INDEX,
+	GPU_DDR_OPP_TABLE_INDEX,
+};
+
 struct msm_gpu {
 	const char *name;
 	struct drm_device *dev;
@@ -113,6 +119,9 @@ struct msm_gpu {

 	struct icc_path *icc_path;

+	/* gpu/ddr opp tables */
+	struct opp_table *opp_tables[2];
+
 	/* Hang and Inactivity Detection:
 	 */
 #define DRM_MSM_INACTIVE_PERIOD   66 /* in ms (roughly four frames) */
--
2.7.4

WARNING: multiple messages have this Message-ID (diff)
From: Sharat Masetty <smasetty@codeaurora.org>
To: freedreno@lists.freedesktop.org, devicetree@vger.kernel.org
Cc: saravanak@google.com, linux-arm-msm@vger.kernel.org,
	Sharat Masetty <smasetty@codeaurora.org>,
	linux-kernel@vger.kernel.org, mka@chromium.org,
	sibis@codeaurora.org, viresh.kumar@linaro.org,
	dri-devel@freedesktop.org
Subject: [PATCH 3/5] drm: msm: scale DDR BW along with GPU frequency
Date: Tue, 31 Mar 2020 13:25:51 +0530	[thread overview]
Message-ID: <1585641353-23229-4-git-send-email-smasetty@codeaurora.org> (raw)
In-Reply-To: <1585641353-23229-1-git-send-email-smasetty@codeaurora.org>

This patch adds support to parse the OPP tables attached the GPU device,
the main opp table and the DDR bandwidth opp table. Additionally, vote
for the GPU->DDR bandwidth when setting the GPU frequency by querying
the linked DDR BW opp to the GPU opp.

Signed-off-by: Sharat Masetty <smasetty@codeaurora.org>
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c   | 41 ++++++++++++++++++++++++++----
 drivers/gpu/drm/msm/adreno/adreno_gpu.c | 44 +++++++++++++++++++++++++++++----
 drivers/gpu/drm/msm/msm_gpu.h           |  9 +++++++
 3 files changed, 84 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 748cd37..489d9b6 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -100,6 +100,40 @@ bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)
 		A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_CLK_OFF));
 }

+void a6xx_gmu_set_icc_vote(struct msm_gpu *gpu, unsigned long gpu_freq)
+{
+	struct dev_pm_opp *gpu_opp, *ddr_opp;
+	struct opp_table **tables = gpu->opp_tables;
+	unsigned long peak_bw;
+
+	if (!gpu->opp_tables[GPU_DDR_OPP_TABLE_INDEX])
+		goto done;
+
+	gpu_opp = dev_pm_opp_find_freq_exact(&gpu->pdev->dev, gpu_freq, true);
+	if (IS_ERR_OR_NULL(gpu_opp))
+		goto done;
+
+	ddr_opp = dev_pm_opp_xlate_required_opp(tables[GPU_OPP_TABLE_INDEX],
+					    tables[GPU_DDR_OPP_TABLE_INDEX],
+					    gpu_opp);
+	dev_pm_opp_put(gpu_opp);
+
+	if (IS_ERR_OR_NULL(ddr_opp))
+		goto done;
+
+	peak_bw = dev_pm_opp_get_bw(ddr_opp, NULL);
+	dev_pm_opp_put(ddr_opp);
+
+	icc_set_bw(gpu->icc_path, 0, peak_bw);
+	return;
+done:
+	/*
+	 * If there is a problem, for now leave it at max so that the
+	 * performance is nominal.
+	 */
+	icc_set_bw(gpu->icc_path, 0, MBps_to_icc(7216));
+}
+
 static void __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)
 {
 	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
@@ -128,11 +162,8 @@ static void __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)

 	gmu->freq = gmu->gpu_freqs[index];

-	/*
-	 * Eventually we will want to scale the path vote with the frequency but
-	 * for now leave it at max so that the performance is nominal.
-	 */
-	icc_set_bw(gpu->icc_path, 0, MBps_to_icc(7216));
+	if (gpu->icc_path)
+		a6xx_gmu_set_icc_vote(gpu, gmu->freq);
 }

 void a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long freq)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 2d13694..bbbcc7a 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -882,7 +882,7 @@ static int adreno_get_pwrlevels(struct device *dev,
 {
 	unsigned long freq = ULONG_MAX;
 	struct dev_pm_opp *opp;
-	int ret;
+	int ret, i;

 	gpu->fast_rate = 0;

@@ -890,9 +890,29 @@ static int adreno_get_pwrlevels(struct device *dev,
 	if (!of_find_property(dev->of_node, "operating-points-v2", NULL))
 		ret = adreno_get_legacy_pwrlevels(dev);
 	else {
-		ret = dev_pm_opp_of_add_table(dev);
-		if (ret)
-			DRM_DEV_ERROR(dev, "Unable to set the OPP table\n");
+		int count = of_count_phandle_with_args(dev->of_node,
+				"operating-points-v2", NULL);
+
+		count = min(count, GPU_DDR_OPP_TABLE_INDEX + 1);
+		count = max(count, 1);
+
+		for (i = 0; i < count; i++) {
+			ret = dev_pm_opp_of_add_table_indexed(dev, i);
+			if (ret) {
+				DRM_DEV_ERROR(dev, "Add OPP table %d: failed %d\n",
+						i, ret);
+				goto err;
+			}
+
+			gpu->opp_tables[i] =
+				dev_pm_opp_get_opp_table_indexed(dev, i);
+			if (!gpu->opp_tables[i]) {
+				DRM_DEV_ERROR(dev, "Get OPP table failed index %d\n",
+						i);
+				ret = -EINVAL;
+				goto err;
+			}
+		}
 	}

 	if (!ret) {
@@ -919,12 +939,24 @@ static int adreno_get_pwrlevels(struct device *dev,
 		gpu->icc_path = NULL;

 	return 0;
+err:
+	for (; i >= 0; i--) {
+		if (gpu->opp_tables[i]) {
+			dev_pm_opp_put_opp_table(gpu->opp_tables[i]);
+			gpu->opp_tables[i] = NULL;
+		}
+	}
+
+	dev_pm_opp_remove_table(dev);
+	return ret;
 }

 int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
 		struct adreno_gpu *adreno_gpu,
 		const struct adreno_gpu_funcs *funcs, int nr_rings)
 {
+	int ret = 0;
+
 	struct adreno_platform_config *config = pdev->dev.platform_data;
 	struct msm_gpu_config adreno_gpu_config  = { 0 };
 	struct msm_gpu *gpu = &adreno_gpu->base;
@@ -945,7 +977,9 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,

 	adreno_gpu_config.nr_rings = nr_rings;

-	adreno_get_pwrlevels(&pdev->dev, gpu);
+	ret = adreno_get_pwrlevels(&pdev->dev, gpu);
+	if (ret)
+		return ret;

 	pm_runtime_set_autosuspend_delay(&pdev->dev,
 		adreno_gpu->info->inactive_period);
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index ab8f0f9c..5b98b48 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -66,6 +66,12 @@ struct msm_gpu_funcs {
 	void (*gpu_set_freq)(struct msm_gpu *gpu, unsigned long freq);
 };

+/* opp table indices */
+enum {
+	GPU_OPP_TABLE_INDEX,
+	GPU_DDR_OPP_TABLE_INDEX,
+};
+
 struct msm_gpu {
 	const char *name;
 	struct drm_device *dev;
@@ -113,6 +119,9 @@ struct msm_gpu {

 	struct icc_path *icc_path;

+	/* gpu/ddr opp tables */
+	struct opp_table *opp_tables[2];
+
 	/* Hang and Inactivity Detection:
 	 */
 #define DRM_MSM_INACTIVE_PERIOD   66 /* in ms (roughly four frames) */
--
2.7.4
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2020-03-31  7:56 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-31  7:55 [PATCH 0/5] Add support for GPU DDR BW scaling Sharat Masetty
2020-03-31  7:55 ` Sharat Masetty
2020-03-31  7:55 ` [PATCH 1/5] arm64: dts: qcom: sc7180: Add interconnect bindings for GPU Sharat Masetty
2020-03-31  7:55   ` Sharat Masetty
2020-03-31  7:55 ` [PATCH 2/5] arm64: dts: qcom: sc7180: Add GPU DDR BW opp table Sharat Masetty
2020-03-31  7:55   ` Sharat Masetty
2020-03-31  7:55 ` Sharat Masetty [this message]
2020-03-31  7:55   ` [PATCH 3/5] drm: msm: scale DDR BW along with GPU frequency Sharat Masetty
2020-03-31 17:26   ` Jordan Crouse
2020-03-31 17:26     ` Jordan Crouse
2020-04-01 12:30     ` Sharat Masetty
2020-04-01 12:30       ` Sharat Masetty
2020-03-31  7:55 ` [PATCH 4/5] drm: msm: a6xx: Fix off by one error when setting GPU freq Sharat Masetty
2020-03-31  7:55   ` Sharat Masetty
2020-03-31 16:43   ` Jordan Crouse
2020-03-31 16:43     ` Jordan Crouse
2020-03-31  7:55 ` [PATCH 5/5] dt-bindings: drm/msm/gpu: Document OPP phandle list for the GPU Sharat Masetty
2020-03-31  7:55   ` Sharat Masetty
2020-04-10 17:48   ` Rob Herring
2020-04-10 17:48     ` Rob Herring

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1585641353-23229-4-git-send-email-smasetty@codeaurora.org \
    --to=smasetty@codeaurora.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@freedesktop.org \
    --cc=freedreno@lists.freedesktop.org \
    --cc=jcrouse@codeaurora.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mka@chromium.org \
    --cc=saravanak@google.com \
    --cc=sibis@codeaurora.org \
    --cc=viresh.kumar@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.