struct thermal_cooling_device *cooling;
struct device *dev = ptdev->base.dev;
struct panthor_devfreq *pdevfreq;
+ struct opp_table *table;
struct dev_pm_opp *opp;
unsigned long cur_freq;
unsigned long freq = ULONG_MAX;
ptdev->devfreq = pdevfreq;
- ret = devm_pm_opp_set_regulators(dev, reg_names);
- if (ret && ret != -ENODEV) {
- if (ret != -EPROBE_DEFER)
- DRM_DEV_ERROR(dev, "Couldn't set OPP regulators\n");
- return ret;
+ /*
+ * The power domain associated with the GPU may have already added an
+ * OPP table, complete with OPPs, as part of the platform bus
+ * initialization. If this is the case, the power domain is in charge of
+ * also controlling the performance, with a set_performance callback.
+ * Only add a new OPP table from DT if there isn't such a table present
+ * already.
+ */
+ table = dev_pm_opp_get_opp_table(dev);
+ if (IS_ERR_OR_NULL(table)) {
+ ret = devm_pm_opp_set_regulators(dev, reg_names);
+ if (ret && ret != -ENODEV) {
+ if (ret != -EPROBE_DEFER)
+ DRM_DEV_ERROR(dev, "Couldn't set OPP regulators\n");
+ return ret;
+ }
+
+ ret = devm_pm_opp_of_add_table(dev);
+ if (ret)
+ return ret;
+ } else {
+ dev_pm_opp_put_opp_table(table);
}
- ret = devm_pm_opp_of_add_table(dev);
- if (ret)
- return ret;
-
spin_lock_init(&pdevfreq->lock);
panthor_devfreq_reset(pdevfreq);