Hi Panfrost and OPP Maintainers,
On Sat, 11 Apr 2020 at 22:06, Clément Péron peron.clem@gmail.com wrote:
OPP table can defined both frequency and voltage.
Register the mali regulator if it exist.
After this patch, Panfrost update properly both voltage and frequency. But the GPU is still not properly down-clocked when temperature is high.
I try to add a cooling map like this : https://github.com/clementperon/linux/commit/955961c7c035abbf44e74f608fe8f05...
But got the following error: [ 2.712082] panfrost 1800000.gpu: [drm:panfrost_devfreq_init [panfrost]] Failed to register cooling device
Do you see what I'm missing?
Thanks for your help, Clement
Signed-off-by: Clément Péron peron.clem@gmail.com
drivers/gpu/drm/panfrost/panfrost_devfreq.c | 34 ++++++++++++++++++--- drivers/gpu/drm/panfrost/panfrost_device.h | 1 + 2 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c index 62541f4edd81..2dc8e2355358 100644 --- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c +++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c @@ -78,12 +78,26 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) struct device *dev = &pfdev->pdev->dev; struct devfreq *devfreq; struct thermal_cooling_device *cooling;
const char *mali = "mali";
struct opp_table *opp_table = NULL;
/* Regulator is optional */
opp_table = dev_pm_opp_set_regulators(dev, &mali, 1);
if (IS_ERR(opp_table)) {
ret = PTR_ERR(opp_table);
if (ret != -ENODEV) {
DRM_DEV_ERROR(dev, "Failed to set regulator: %d\n", ret);
return ret;
}
}
pfdev->devfreq.opp_table = opp_table; ret = dev_pm_opp_of_add_table(dev);
if (ret == -ENODEV) /* Optional, continue without devfreq */
return 0;
else if (ret)
return ret;
if (ret) {
if (ret == -ENODEV) /* Optional, continue without devfreq */
ret = 0;
goto err_opp_reg;
} panfrost_devfreq_reset(pfdev);
@@ -119,6 +133,12 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) err_opp: dev_pm_opp_of_remove_table(dev);
+err_opp_reg:
if (pfdev->devfreq.opp_table) {
dev_pm_opp_put_regulators(pfdev->devfreq.opp_table);
pfdev->devfreq.opp_table = NULL;
}
return ret;
}
@@ -126,7 +146,13 @@ void panfrost_devfreq_fini(struct panfrost_device *pfdev) { if (pfdev->devfreq.cooling) devfreq_cooling_unregister(pfdev->devfreq.cooling);
dev_pm_opp_of_remove_table(&pfdev->pdev->dev);
if (pfdev->devfreq.opp_table) {
dev_pm_opp_put_regulators(pfdev->devfreq.opp_table);
pfdev->devfreq.opp_table = NULL;
}
}
void panfrost_devfreq_resume(struct panfrost_device *pfdev) diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h index 06713811b92c..f6b0c779dfe5 100644 --- a/drivers/gpu/drm/panfrost/panfrost_device.h +++ b/drivers/gpu/drm/panfrost/panfrost_device.h @@ -86,6 +86,7 @@ struct panfrost_device { struct { struct devfreq *devfreq; struct thermal_cooling_device *cooling;
struct opp_table *opp_table; ktime_t busy_time; ktime_t idle_time; ktime_t time_last_update;
-- 2.20.1