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