Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/panthor: Use existing OPP table if present

On SoCs where the GPU's power-domain is in charge of setting performance
levels, the OPP table of the GPU node will have already been populated
during said power-domain's attach_dev operation.

To avoid initialising an OPP table twice, only set the OPP regulator and
the OPPs from DT if there's no OPP table present.

Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Link: https://patch.msgid.link/20251017-mt8196-gpufreq-v8-4-98fc1cc566a1@collabora.com
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>

authored by

Nicolas Frattaroli and committed by
Liviu Dudau
3668133e 3dd4844b

+23 -9
+23 -9
drivers/gpu/drm/panthor/panthor_devfreq.c
··· 142 142 struct thermal_cooling_device *cooling; 143 143 struct device *dev = ptdev->base.dev; 144 144 struct panthor_devfreq *pdevfreq; 145 + struct opp_table *table; 145 146 struct dev_pm_opp *opp; 146 147 unsigned long cur_freq; 147 148 unsigned long freq = ULONG_MAX; ··· 154 153 155 154 ptdev->devfreq = pdevfreq; 156 155 157 - ret = devm_pm_opp_set_regulators(dev, reg_names); 158 - if (ret && ret != -ENODEV) { 159 - if (ret != -EPROBE_DEFER) 160 - DRM_DEV_ERROR(dev, "Couldn't set OPP regulators\n"); 161 - return ret; 162 - } 156 + /* 157 + * The power domain associated with the GPU may have already added an 158 + * OPP table, complete with OPPs, as part of the platform bus 159 + * initialization. If this is the case, the power domain is in charge of 160 + * also controlling the performance, with a set_performance callback. 161 + * Only add a new OPP table from DT if there isn't such a table present 162 + * already. 163 + */ 164 + table = dev_pm_opp_get_opp_table(dev); 165 + if (IS_ERR_OR_NULL(table)) { 166 + ret = devm_pm_opp_set_regulators(dev, reg_names); 167 + if (ret && ret != -ENODEV) { 168 + if (ret != -EPROBE_DEFER) 169 + DRM_DEV_ERROR(dev, "Couldn't set OPP regulators\n"); 170 + return ret; 171 + } 163 172 164 - ret = devm_pm_opp_of_add_table(dev); 165 - if (ret) 166 - return ret; 173 + ret = devm_pm_opp_of_add_table(dev); 174 + if (ret) 175 + return ret; 176 + } else { 177 + dev_pm_opp_put_opp_table(table); 178 + } 167 179 168 180 spin_lock_init(&pdevfreq->lock); 169 181