Skip to content

Commit

Permalink
drm/panfrost: add regulators to devfreq
Browse files Browse the repository at this point in the history
Some OPP tables specify voltage for each frequency. Devfreq can
handle these regulators but they should be get only 1 time to avoid
issue and know who is in charge.

If OPP table is probe don't init regulator.

Reviewed-by: Steven Price <[email protected]>
Reviewed-by: Alyssa Rosenzweig <[email protected]>
Signed-off-by: Clément Péron <[email protected]>
Signed-off-by: Rob Herring <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
  • Loading branch information
clementperon authored and robherring committed Aug 7, 2020
1 parent 512f212 commit fd587ff
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 7 deletions.
29 changes: 25 additions & 4 deletions drivers/gpu/drm/panfrost/panfrost_devfreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,30 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
unsigned long cur_freq;
struct device *dev = &pfdev->pdev->dev;
struct devfreq *devfreq;
struct opp_table *opp_table;
struct thermal_cooling_device *cooling;
struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;

opp_table = dev_pm_opp_set_regulators(dev, pfdev->comp->supply_names,
pfdev->comp->num_supplies);
if (IS_ERR(opp_table)) {
ret = PTR_ERR(opp_table);
/* Continue if the optional regulator is missing */
if (ret != -ENODEV) {
DRM_DEV_ERROR(dev, "Couldn't set OPP regulators\n");
goto err_fini;
}
} else {
pfdevfreq->regulators_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) {
/* Optional, continue without devfreq */
if (ret == -ENODEV)
ret = 0;
goto err_fini;
}
pfdevfreq->opp_of_table_added = true;

spin_lock_init(&pfdevfreq->lock);
Expand Down Expand Up @@ -153,6 +169,11 @@ void panfrost_devfreq_fini(struct panfrost_device *pfdev)
dev_pm_opp_of_remove_table(&pfdev->pdev->dev);
pfdevfreq->opp_of_table_added = false;
}

if (pfdevfreq->regulators_opp_table) {
dev_pm_opp_put_regulators(pfdevfreq->regulators_opp_table);
pfdevfreq->regulators_opp_table = NULL;
}
}

void panfrost_devfreq_resume(struct panfrost_device *pfdev)
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/panfrost/panfrost_devfreq.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
#include <linux/ktime.h>

struct devfreq;
struct opp_table;
struct thermal_cooling_device;

struct panfrost_device;

struct panfrost_devfreq {
struct devfreq *devfreq;
struct opp_table *regulators_opp_table;
struct thermal_cooling_device *cooling;
bool opp_of_table_added;

Expand Down
9 changes: 6 additions & 3 deletions drivers/gpu/drm/panfrost/panfrost_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,12 @@ int panfrost_device_init(struct panfrost_device *pfdev)
goto out_clk;
}

err = panfrost_regulator_init(pfdev);
if (err)
goto out_devfreq;
/* OPP will handle regulators */
if (!pfdev->pfdevfreq.opp_of_table_added) {
err = panfrost_regulator_init(pfdev);
if (err)
goto out_devfreq;
}

err = panfrost_reset_init(pfdev);
if (err) {
Expand Down

0 comments on commit fd587ff

Please sign in to comment.