1 // SPDX-License-Identifier: GPL-2.0 or MIT
2 /* Copyright 2019 Collabora ltd. */
3
4 #include <linux/clk.h>
5 #include <linux/devfreq.h>
6 #include <linux/devfreq_cooling.h>
7 #include <linux/platform_device.h>
8 #include <linux/pm_opp.h>
9
10 #include <drm/drm_managed.h>
11
12 #include "panthor_devfreq.h"
13 #include "panthor_device.h"
14
15 /**
16 * struct panthor_devfreq - Device frequency management
17 */
18 struct panthor_devfreq {
19 /** @devfreq: devfreq device. */
20 struct devfreq *devfreq;
21
22 /** @gov_data: Governor data. */
23 struct devfreq_simple_ondemand_data gov_data;
24
25 /** @busy_time: Busy time. */
26 ktime_t busy_time;
27
28 /** @idle_time: Idle time. */
29 ktime_t idle_time;
30
31 /** @time_last_update: Last update time. */
32 ktime_t time_last_update;
33
34 /** @last_busy_state: True if the GPU was busy last time we updated the state. */
35 bool last_busy_state;
36
37 /**
38 * @lock: Lock used to protect busy_time, idle_time, time_last_update and
39 * last_busy_state.
40 *
41 * These fields can be accessed concurrently by panthor_devfreq_get_dev_status()
42 * and panthor_devfreq_record_{busy,idle}().
43 */
44 spinlock_t lock;
45 };
46
panthor_devfreq_update_utilization(struct panthor_devfreq * pdevfreq)47 static void panthor_devfreq_update_utilization(struct panthor_devfreq *pdevfreq)
48 {
49 ktime_t now, last;
50
51 now = ktime_get();
52 last = pdevfreq->time_last_update;
53
54 if (pdevfreq->last_busy_state)
55 pdevfreq->busy_time += ktime_sub(now, last);
56 else
57 pdevfreq->idle_time += ktime_sub(now, last);
58
59 pdevfreq->time_last_update = now;
60 }
61
panthor_devfreq_target(struct device * dev,unsigned long * freq,u32 flags)62 static int panthor_devfreq_target(struct device *dev, unsigned long *freq,
63 u32 flags)
64 {
65 struct dev_pm_opp *opp;
66
67 opp = devfreq_recommended_opp(dev, freq, flags);
68 if (IS_ERR(opp))
69 return PTR_ERR(opp);
70 dev_pm_opp_put(opp);
71
72 return dev_pm_opp_set_rate(dev, *freq);
73 }
74
panthor_devfreq_reset(struct panthor_devfreq * pdevfreq)75 static void panthor_devfreq_reset(struct panthor_devfreq *pdevfreq)
76 {
77 pdevfreq->busy_time = 0;
78 pdevfreq->idle_time = 0;
79 pdevfreq->time_last_update = ktime_get();
80 }
81
panthor_devfreq_get_dev_status(struct device * dev,struct devfreq_dev_status * status)82 static int panthor_devfreq_get_dev_status(struct device *dev,
83 struct devfreq_dev_status *status)
84 {
85 struct panthor_device *ptdev = dev_get_drvdata(dev);
86 struct panthor_devfreq *pdevfreq = ptdev->devfreq;
87 unsigned long irqflags;
88
89 status->current_frequency = clk_get_rate(ptdev->clks.core);
90
91 spin_lock_irqsave(&pdevfreq->lock, irqflags);
92
93 panthor_devfreq_update_utilization(pdevfreq);
94
95 status->total_time = ktime_to_ns(ktime_add(pdevfreq->busy_time,
96 pdevfreq->idle_time));
97
98 status->busy_time = ktime_to_ns(pdevfreq->busy_time);
99
100 panthor_devfreq_reset(pdevfreq);
101
102 spin_unlock_irqrestore(&pdevfreq->lock, irqflags);
103
104 drm_dbg(&ptdev->base, "busy %lu total %lu %lu %% freq %lu MHz\n",
105 status->busy_time, status->total_time,
106 status->busy_time / (status->total_time / 100),
107 status->current_frequency / 1000 / 1000);
108
109 return 0;
110 }
111
112 static struct devfreq_dev_profile panthor_devfreq_profile = {
113 .timer = DEVFREQ_TIMER_DELAYED,
114 .polling_ms = 50, /* ~3 frames */
115 .target = panthor_devfreq_target,
116 .get_dev_status = panthor_devfreq_get_dev_status,
117 };
118
panthor_devfreq_init(struct panthor_device * ptdev)119 int panthor_devfreq_init(struct panthor_device *ptdev)
120 {
121 /* There's actually 2 regulators (mali and sram), but the OPP core only
122 * supports one.
123 *
124 * We assume the sram regulator is coupled with the mali one and let
125 * the coupling logic deal with voltage updates.
126 */
127 static const char * const reg_names[] = { "mali", NULL };
128 struct thermal_cooling_device *cooling;
129 struct device *dev = ptdev->base.dev;
130 struct panthor_devfreq *pdevfreq;
131 struct dev_pm_opp *opp;
132 unsigned long cur_freq;
133 int ret;
134
135 pdevfreq = drmm_kzalloc(&ptdev->base, sizeof(*ptdev->devfreq), GFP_KERNEL);
136 if (!pdevfreq)
137 return -ENOMEM;
138
139 ptdev->devfreq = pdevfreq;
140
141 ret = devm_pm_opp_set_regulators(dev, reg_names);
142 if (ret) {
143 if (ret != -EPROBE_DEFER)
144 DRM_DEV_ERROR(dev, "Couldn't set OPP regulators\n");
145
146 return ret;
147 }
148
149 ret = devm_pm_opp_of_add_table(dev);
150 if (ret)
151 return ret;
152
153 spin_lock_init(&pdevfreq->lock);
154
155 panthor_devfreq_reset(pdevfreq);
156
157 cur_freq = clk_get_rate(ptdev->clks.core);
158
159 opp = devfreq_recommended_opp(dev, &cur_freq, 0);
160 if (IS_ERR(opp))
161 return PTR_ERR(opp);
162
163 panthor_devfreq_profile.initial_freq = cur_freq;
164
165 /* Regulator coupling only takes care of synchronizing/balancing voltage
166 * updates, but the coupled regulator needs to be enabled manually.
167 *
168 * We use devm_regulator_get_enable_optional() and keep the sram supply
169 * enabled until the device is removed, just like we do for the mali
170 * supply, which is enabled when dev_pm_opp_set_opp(dev, opp) is called,
171 * and disabled when the opp_table is torn down, using the devm action.
172 *
173 * If we really care about disabling regulators on suspend, we should:
174 * - use devm_regulator_get_optional() here
175 * - call dev_pm_opp_set_opp(dev, NULL) before leaving this function
176 * (this disables the regulator passed to the OPP layer)
177 * - call dev_pm_opp_set_opp(dev, NULL) and
178 * regulator_disable(ptdev->regulators.sram) in
179 * panthor_devfreq_suspend()
180 * - call dev_pm_opp_set_opp(dev, default_opp) and
181 * regulator_enable(ptdev->regulators.sram) in
182 * panthor_devfreq_resume()
183 *
184 * But without knowing if it's beneficial or not (in term of power
185 * consumption), or how much it slows down the suspend/resume steps,
186 * let's just keep regulators enabled for the device lifetime.
187 */
188 ret = devm_regulator_get_enable_optional(dev, "sram");
189 if (ret && ret != -ENODEV) {
190 if (ret != -EPROBE_DEFER)
191 DRM_DEV_ERROR(dev, "Couldn't retrieve/enable sram supply\n");
192 return ret;
193 }
194
195 /*
196 * Set the recommend OPP this will enable and configure the regulator
197 * if any and will avoid a switch off by regulator_late_cleanup()
198 */
199 ret = dev_pm_opp_set_opp(dev, opp);
200 if (ret) {
201 DRM_DEV_ERROR(dev, "Couldn't set recommended OPP\n");
202 return ret;
203 }
204
205 dev_pm_opp_put(opp);
206
207 /*
208 * Setup default thresholds for the simple_ondemand governor.
209 * The values are chosen based on experiments.
210 */
211 pdevfreq->gov_data.upthreshold = 45;
212 pdevfreq->gov_data.downdifferential = 5;
213
214 pdevfreq->devfreq = devm_devfreq_add_device(dev, &panthor_devfreq_profile,
215 DEVFREQ_GOV_SIMPLE_ONDEMAND,
216 &pdevfreq->gov_data);
217 if (IS_ERR(pdevfreq->devfreq)) {
218 DRM_DEV_ERROR(dev, "Couldn't initialize GPU devfreq\n");
219 ret = PTR_ERR(pdevfreq->devfreq);
220 pdevfreq->devfreq = NULL;
221 return ret;
222 }
223
224 cooling = devfreq_cooling_em_register(pdevfreq->devfreq, NULL);
225 if (IS_ERR(cooling))
226 DRM_DEV_INFO(dev, "Failed to register cooling device\n");
227
228 return 0;
229 }
230
panthor_devfreq_resume(struct panthor_device * ptdev)231 int panthor_devfreq_resume(struct panthor_device *ptdev)
232 {
233 struct panthor_devfreq *pdevfreq = ptdev->devfreq;
234
235 if (!pdevfreq->devfreq)
236 return 0;
237
238 panthor_devfreq_reset(pdevfreq);
239
240 return devfreq_resume_device(pdevfreq->devfreq);
241 }
242
panthor_devfreq_suspend(struct panthor_device * ptdev)243 int panthor_devfreq_suspend(struct panthor_device *ptdev)
244 {
245 struct panthor_devfreq *pdevfreq = ptdev->devfreq;
246
247 if (!pdevfreq->devfreq)
248 return 0;
249
250 return devfreq_suspend_device(pdevfreq->devfreq);
251 }
252
panthor_devfreq_record_busy(struct panthor_device * ptdev)253 void panthor_devfreq_record_busy(struct panthor_device *ptdev)
254 {
255 struct panthor_devfreq *pdevfreq = ptdev->devfreq;
256 unsigned long irqflags;
257
258 if (!pdevfreq->devfreq)
259 return;
260
261 spin_lock_irqsave(&pdevfreq->lock, irqflags);
262
263 panthor_devfreq_update_utilization(pdevfreq);
264 pdevfreq->last_busy_state = true;
265
266 spin_unlock_irqrestore(&pdevfreq->lock, irqflags);
267 }
268
panthor_devfreq_record_idle(struct panthor_device * ptdev)269 void panthor_devfreq_record_idle(struct panthor_device *ptdev)
270 {
271 struct panthor_devfreq *pdevfreq = ptdev->devfreq;
272 unsigned long irqflags;
273
274 if (!pdevfreq->devfreq)
275 return;
276
277 spin_lock_irqsave(&pdevfreq->lock, irqflags);
278
279 panthor_devfreq_update_utilization(pdevfreq);
280 pdevfreq->last_busy_state = false;
281
282 spin_unlock_irqrestore(&pdevfreq->lock, irqflags);
283 }
284