Blob Blame History Raw
From 22bd4df9dadf46f56f2eb16859439a7a600d106a Mon Sep 17 00:00:00 2001
From: Steven Price <steven.price@arm.com>
Date: Mon, 18 Nov 2019 17:30:02 +0000
Subject: drm/panfrost: devfreq: Round frequencies to OPPs
Git-commit: 22bd4df9dadf46f56f2eb16859439a7a600d106a
Patch-mainline: v5.5-rc2
References: bsc#1152489

Currently when setting a frequency in panfrost_devfreq_target the
returned frequency is the actual frequency that the clock driver reports
(the return of clk_get_rate()). However, where the provided OPPs don't
precisely match the frequencies that the clock actually achieves devfreq
will then complain (repeatedly):

  devfreq devfreq0: Couldn't update frequency transition information.

To avoid this change panfrost_devfreq_target() to fetch the opp using
devfreq_recommened_opp() and not actually query the clock for the
frequency.

A similar problem exists with panfrost_devfreq_get_cur_freq(), but in
this case because the function is optional we can just remove it and
devfreq will fall back to using the previously set frequency.

Fixes: 221bc77914cb ("drm/panfrost: Use generic code for devfreq")
Signed-off-by: Steven Price <steven.price@arm.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191118173002.32015-1-steven.price@arm.com
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/panfrost/panfrost_devfreq.c | 19 ++++++-------------
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
index 4c4e8a30a1ac..536ba93b0f46 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
@@ -18,15 +18,18 @@ static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev);
 static int panfrost_devfreq_target(struct device *dev, unsigned long *freq,
 				   u32 flags)
 {
-	struct panfrost_device *pfdev = dev_get_drvdata(dev);
+	struct dev_pm_opp *opp;
 	int err;
 
+	opp = devfreq_recommended_opp(dev, freq, flags);
+	if (IS_ERR(opp))
+		return PTR_ERR(opp);
+	dev_pm_opp_put(opp);
+
 	err = dev_pm_opp_set_rate(dev, *freq);
 	if (err)
 		return err;
 
-	*freq = clk_get_rate(pfdev->clock);
-
 	return 0;
 }
 
@@ -60,20 +63,10 @@ static int panfrost_devfreq_get_dev_status(struct device *dev,
 	return 0;
 }
 
-static int panfrost_devfreq_get_cur_freq(struct device *dev, unsigned long *freq)
-{
-	struct panfrost_device *pfdev = platform_get_drvdata(to_platform_device(dev));
-
-	*freq = clk_get_rate(pfdev->clock);
-
-	return 0;
-}
-
 static struct devfreq_dev_profile panfrost_devfreq_profile = {
 	.polling_ms = 50, /* ~3 frames */
 	.target = panfrost_devfreq_target,
 	.get_dev_status = panfrost_devfreq_get_dev_status,
-	.get_cur_freq = panfrost_devfreq_get_cur_freq,
 };
 
 int panfrost_devfreq_init(struct panfrost_device *pfdev)
-- 
2.28.0