1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright 2019 Collabora ltd. */
5 #include <linux/devfreq.h>
6 #include <linux/devfreq_cooling.h>
7 #include <linux/nvmem-consumer.h>
8 #include <linux/platform_device.h>
9 #include <linux/pm_opp.h>
11 #include "panfrost_device.h"
12 #include "panfrost_devfreq.h"
14 static void panfrost_devfreq_update_utilization(struct panfrost_devfreq
*pfdevfreq
)
19 last
= pfdevfreq
->time_last_update
;
21 if (pfdevfreq
->busy_count
> 0)
22 pfdevfreq
->busy_time
+= ktime_sub(now
, last
);
24 pfdevfreq
->idle_time
+= ktime_sub(now
, last
);
26 pfdevfreq
->time_last_update
= now
;
29 static int panfrost_devfreq_target(struct device
*dev
, unsigned long *freq
,
32 struct panfrost_device
*ptdev
= dev_get_drvdata(dev
);
33 struct dev_pm_opp
*opp
;
36 opp
= devfreq_recommended_opp(dev
, freq
, flags
);
41 err
= dev_pm_opp_set_rate(dev
, *freq
);
43 ptdev
->pfdevfreq
.current_frequency
= *freq
;
48 static void panfrost_devfreq_reset(struct panfrost_devfreq
*pfdevfreq
)
50 pfdevfreq
->busy_time
= 0;
51 pfdevfreq
->idle_time
= 0;
52 pfdevfreq
->time_last_update
= ktime_get();
55 static int panfrost_devfreq_get_dev_status(struct device
*dev
,
56 struct devfreq_dev_status
*status
)
58 struct panfrost_device
*pfdev
= dev_get_drvdata(dev
);
59 struct panfrost_devfreq
*pfdevfreq
= &pfdev
->pfdevfreq
;
60 unsigned long irqflags
;
62 status
->current_frequency
= clk_get_rate(pfdev
->clock
);
64 spin_lock_irqsave(&pfdevfreq
->lock
, irqflags
);
66 panfrost_devfreq_update_utilization(pfdevfreq
);
68 status
->total_time
= ktime_to_ns(ktime_add(pfdevfreq
->busy_time
,
69 pfdevfreq
->idle_time
));
71 status
->busy_time
= ktime_to_ns(pfdevfreq
->busy_time
);
73 panfrost_devfreq_reset(pfdevfreq
);
75 spin_unlock_irqrestore(&pfdevfreq
->lock
, irqflags
);
77 dev_dbg(pfdev
->dev
, "busy %lu total %lu %lu %% freq %lu MHz\n",
78 status
->busy_time
, status
->total_time
,
79 status
->busy_time
/ (status
->total_time
/ 100),
80 status
->current_frequency
/ 1000 / 1000);
85 static struct devfreq_dev_profile panfrost_devfreq_profile
= {
86 .timer
= DEVFREQ_TIMER_DELAYED
,
87 .polling_ms
= 50, /* ~3 frames */
88 .target
= panfrost_devfreq_target
,
89 .get_dev_status
= panfrost_devfreq_get_dev_status
,
92 static int panfrost_read_speedbin(struct device
*dev
)
97 ret
= nvmem_cell_read_variable_le_u32(dev
, "speed-bin", &val
);
100 * -ENOENT means that this platform doesn't support speedbins
101 * as it didn't declare any speed-bin nvmem: in this case, we
102 * keep going without it; any other error means that we are
103 * supposed to read the bin value, but we failed doing so.
105 if (ret
!= -ENOENT
&& ret
!= -EOPNOTSUPP
) {
106 DRM_DEV_ERROR(dev
, "Cannot read speed-bin (%d).", ret
);
112 DRM_DEV_DEBUG(dev
, "Using speed-bin = 0x%x\n", val
);
114 return devm_pm_opp_set_supported_hw(dev
, &val
, 1);
117 int panfrost_devfreq_init(struct panfrost_device
*pfdev
)
120 struct dev_pm_opp
*opp
;
121 unsigned long cur_freq
;
122 struct device
*dev
= &pfdev
->pdev
->dev
;
123 struct devfreq
*devfreq
;
124 struct thermal_cooling_device
*cooling
;
125 struct panfrost_devfreq
*pfdevfreq
= &pfdev
->pfdevfreq
;
126 unsigned long freq
= ULONG_MAX
;
128 if (pfdev
->comp
->num_supplies
> 1) {
130 * GPUs with more than 1 supply require platform-specific handling:
131 * continue without devfreq
133 DRM_DEV_INFO(dev
, "More than 1 supply is not supported yet\n");
137 ret
= panfrost_read_speedbin(dev
);
141 ret
= devm_pm_opp_set_regulators(dev
, pfdev
->comp
->supply_names
);
143 /* Continue if the optional regulator is missing */
144 if (ret
!= -ENODEV
) {
145 if (ret
!= -EPROBE_DEFER
)
146 DRM_DEV_ERROR(dev
, "Couldn't set OPP regulators\n");
151 ret
= devm_pm_opp_of_add_table(dev
);
153 /* Optional, continue without devfreq */
158 pfdevfreq
->opp_of_table_added
= true;
160 spin_lock_init(&pfdevfreq
->lock
);
162 panfrost_devfreq_reset(pfdevfreq
);
164 cur_freq
= clk_get_rate(pfdev
->clock
);
166 opp
= devfreq_recommended_opp(dev
, &cur_freq
, 0);
170 panfrost_devfreq_profile
.initial_freq
= cur_freq
;
173 * We could wait until panfrost_devfreq_target() to set this value, but
174 * since the simple_ondemand governor works asynchronously, there's a
175 * chance by the time someone opens the device's fdinfo file, current
176 * frequency hasn't been updated yet, so let's just do an early set.
178 pfdevfreq
->current_frequency
= cur_freq
;
181 * Set the recommend OPP this will enable and configure the regulator
182 * if any and will avoid a switch off by regulator_late_cleanup()
184 ret
= dev_pm_opp_set_opp(dev
, opp
);
186 DRM_DEV_ERROR(dev
, "Couldn't set recommended OPP\n");
190 /* Find the fastest defined rate */
191 opp
= dev_pm_opp_find_freq_floor(dev
, &freq
);
194 pfdevfreq
->fast_rate
= freq
;
199 * Setup default thresholds for the simple_ondemand governor.
200 * The values are chosen based on experiments.
202 pfdevfreq
->gov_data
.upthreshold
= 45;
203 pfdevfreq
->gov_data
.downdifferential
= 5;
205 devfreq
= devm_devfreq_add_device(dev
, &panfrost_devfreq_profile
,
206 DEVFREQ_GOV_SIMPLE_ONDEMAND
,
207 &pfdevfreq
->gov_data
);
208 if (IS_ERR(devfreq
)) {
209 DRM_DEV_ERROR(dev
, "Couldn't initialize GPU devfreq\n");
210 return PTR_ERR(devfreq
);
212 pfdevfreq
->devfreq
= devfreq
;
214 cooling
= devfreq_cooling_em_register(devfreq
, NULL
);
216 DRM_DEV_INFO(dev
, "Failed to register cooling device\n");
218 pfdevfreq
->cooling
= cooling
;
223 void panfrost_devfreq_fini(struct panfrost_device
*pfdev
)
225 struct panfrost_devfreq
*pfdevfreq
= &pfdev
->pfdevfreq
;
227 if (pfdevfreq
->cooling
) {
228 devfreq_cooling_unregister(pfdevfreq
->cooling
);
229 pfdevfreq
->cooling
= NULL
;
233 void panfrost_devfreq_resume(struct panfrost_device
*pfdev
)
235 struct panfrost_devfreq
*pfdevfreq
= &pfdev
->pfdevfreq
;
237 if (!pfdevfreq
->devfreq
)
240 panfrost_devfreq_reset(pfdevfreq
);
242 devfreq_resume_device(pfdevfreq
->devfreq
);
245 void panfrost_devfreq_suspend(struct panfrost_device
*pfdev
)
247 struct panfrost_devfreq
*pfdevfreq
= &pfdev
->pfdevfreq
;
249 if (!pfdevfreq
->devfreq
)
252 devfreq_suspend_device(pfdevfreq
->devfreq
);
255 void panfrost_devfreq_record_busy(struct panfrost_devfreq
*pfdevfreq
)
257 unsigned long irqflags
;
259 if (!pfdevfreq
->devfreq
)
262 spin_lock_irqsave(&pfdevfreq
->lock
, irqflags
);
264 panfrost_devfreq_update_utilization(pfdevfreq
);
266 pfdevfreq
->busy_count
++;
268 spin_unlock_irqrestore(&pfdevfreq
->lock
, irqflags
);
271 void panfrost_devfreq_record_idle(struct panfrost_devfreq
*pfdevfreq
)
273 unsigned long irqflags
;
275 if (!pfdevfreq
->devfreq
)
278 spin_lock_irqsave(&pfdevfreq
->lock
, irqflags
);
280 panfrost_devfreq_update_utilization(pfdevfreq
);
282 WARN_ON(--pfdevfreq
->busy_count
< 0);
284 spin_unlock_irqrestore(&pfdevfreq
->lock
, irqflags
);