The Bifrost GPU on MT8183 uses 2 regulators (core and SRAM) for
devfreq, and provides OPP table with 2 sets of voltages.

TODO: This is incomplete as we'll need add support for setting
a pair of voltages as well. I also realized that the out-of-tree
driver has complex logic to ensure voltage delta between the
regulators stays within a specific range, so we'd need to port
that as well.

Signed-off-by: Nicolas Boichat <drink...@chromium.org>
---
 drivers/gpu/drm/panfrost/panfrost_devfreq.c | 17 +++++++++++++++++
 drivers/gpu/drm/panfrost/panfrost_device.h  |  1 +
 2 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c 
b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
index 413987038fbfccb..9c0987a3d71c597 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
@@ -79,6 +79,21 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
        struct devfreq *devfreq;
        struct thermal_cooling_device *cooling;
 
+       /* If we have 2 regulator, we need an OPP table with 2 voltages. */
+       if (pfdev->comp->num_supplies > 1) {
+               pfdev->devfreq.dev_opp_table =
+                       dev_pm_opp_set_regulators(dev,
+                                       pfdev->comp->supply_names,
+                                       pfdev->comp->num_supplies);
+               if (IS_ERR(pfdev->devfreq.dev_opp_table)) {
+                       ret = PTR_ERR(pfdev->devfreq.dev_opp_table);
+                       pfdev->devfreq.dev_opp_table = NULL;
+                       dev_err(dev,
+                               "Failed to init devfreq opp table: %d\n", ret);
+                       return ret;
+               }
+       }
+
        ret = dev_pm_opp_of_add_table(dev);
        if (ret == -ENODEV) /* Optional, continue without devfreq */
                return 0;
@@ -119,6 +134,8 @@ 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.dev_opp_table)
+               dev_pm_opp_put_regulators(pfdev->devfreq.dev_opp_table);
 }
 
 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 c30c719a805940a..5009a8b7c853ea1 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.h
+++ b/drivers/gpu/drm/panfrost/panfrost_device.h
@@ -110,6 +110,7 @@ struct panfrost_device {
        struct {
                struct devfreq *devfreq;
                struct thermal_cooling_device *cooling;
+               struct opp_table *dev_opp_table;
                ktime_t busy_time;
                ktime_t idle_time;
                ktime_t time_last_update;
-- 
2.25.1.481.gfbce0eb801-goog

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to