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/platform_device.h>
8 #include <linux/pm_opp.h>
10 #include "panfrost_device.h"
11 #include "panfrost_devfreq.h"
13 static void panfrost_devfreq_update_utilization(struct panfrost_devfreq
*pfdevfreq
)
18 last
= pfdevfreq
->time_last_update
;
20 if (pfdevfreq
->busy_count
> 0)
21 pfdevfreq
->busy_time
+= ktime_sub(now
, last
);
23 pfdevfreq
->idle_time
+= ktime_sub(now
, last
);
25 pfdevfreq
->time_last_update
= now
;
28 static int panfrost_devfreq_target(struct device
*dev
, unsigned long *freq
,
31 struct dev_pm_opp
*opp
;
33 opp
= devfreq_recommended_opp(dev
, freq
, flags
);
38 return dev_pm_opp_set_rate(dev
, *freq
);
41 static void panfrost_devfreq_reset(struct panfrost_devfreq
*pfdevfreq
)
43 pfdevfreq
->busy_time
= 0;
44 pfdevfreq
->idle_time
= 0;
45 pfdevfreq
->time_last_update
= ktime_get();
48 static int panfrost_devfreq_get_dev_status(struct device
*dev
,
49 struct devfreq_dev_status
*status
)
51 struct panfrost_device
*pfdev
= dev_get_drvdata(dev
);
52 struct panfrost_devfreq
*pfdevfreq
= &pfdev
->pfdevfreq
;
53 unsigned long irqflags
;
55 status
->current_frequency
= clk_get_rate(pfdev
->clock
);
57 spin_lock_irqsave(&pfdevfreq
->lock
, irqflags
);
59 panfrost_devfreq_update_utilization(pfdevfreq
);
61 status
->total_time
= ktime_to_ns(ktime_add(pfdevfreq
->busy_time
,
62 pfdevfreq
->idle_time
));
64 status
->busy_time
= ktime_to_ns(pfdevfreq
->busy_time
);
66 panfrost_devfreq_reset(pfdevfreq
);
68 spin_unlock_irqrestore(&pfdevfreq
->lock
, irqflags
);
70 dev_dbg(pfdev
->dev
, "busy %lu total %lu %lu %% freq %lu MHz\n",
71 status
->busy_time
, status
->total_time
,
72 status
->busy_time
/ (status
->total_time
/ 100),
73 status
->current_frequency
/ 1000 / 1000);
78 static struct devfreq_dev_profile panfrost_devfreq_profile
= {
79 .polling_ms
= 50, /* ~3 frames */
80 .target
= panfrost_devfreq_target
,
81 .get_dev_status
= panfrost_devfreq_get_dev_status
,
84 int panfrost_devfreq_init(struct panfrost_device
*pfdev
)
87 struct dev_pm_opp
*opp
;
88 unsigned long cur_freq
;
89 struct device
*dev
= &pfdev
->pdev
->dev
;
90 struct devfreq
*devfreq
;
91 struct opp_table
*opp_table
;
92 struct thermal_cooling_device
*cooling
;
93 struct panfrost_devfreq
*pfdevfreq
= &pfdev
->pfdevfreq
;
95 opp_table
= dev_pm_opp_set_regulators(dev
, pfdev
->comp
->supply_names
,
96 pfdev
->comp
->num_supplies
);
97 if (IS_ERR(opp_table
)) {
98 ret
= PTR_ERR(opp_table
);
99 /* Continue if the optional regulator is missing */
100 if (ret
!= -ENODEV
) {
101 DRM_DEV_ERROR(dev
, "Couldn't set OPP regulators\n");
105 pfdevfreq
->regulators_opp_table
= opp_table
;
108 ret
= dev_pm_opp_of_add_table(dev
);
110 /* Optional, continue without devfreq */
115 pfdevfreq
->opp_of_table_added
= true;
117 spin_lock_init(&pfdevfreq
->lock
);
119 panfrost_devfreq_reset(pfdevfreq
);
121 cur_freq
= clk_get_rate(pfdev
->clock
);
123 opp
= devfreq_recommended_opp(dev
, &cur_freq
, 0);
129 panfrost_devfreq_profile
.initial_freq
= cur_freq
;
132 devfreq
= devm_devfreq_add_device(dev
, &panfrost_devfreq_profile
,
133 DEVFREQ_GOV_SIMPLE_ONDEMAND
, NULL
);
134 if (IS_ERR(devfreq
)) {
135 DRM_DEV_ERROR(dev
, "Couldn't initialize GPU devfreq\n");
136 ret
= PTR_ERR(devfreq
);
139 pfdevfreq
->devfreq
= devfreq
;
141 cooling
= devfreq_cooling_em_register(devfreq
, NULL
);
143 DRM_DEV_INFO(dev
, "Failed to register cooling device\n");
145 pfdevfreq
->cooling
= cooling
;
150 panfrost_devfreq_fini(pfdev
);
154 void panfrost_devfreq_fini(struct panfrost_device
*pfdev
)
156 struct panfrost_devfreq
*pfdevfreq
= &pfdev
->pfdevfreq
;
158 if (pfdevfreq
->cooling
) {
159 devfreq_cooling_unregister(pfdevfreq
->cooling
);
160 pfdevfreq
->cooling
= NULL
;
163 if (pfdevfreq
->opp_of_table_added
) {
164 dev_pm_opp_of_remove_table(&pfdev
->pdev
->dev
);
165 pfdevfreq
->opp_of_table_added
= false;
168 dev_pm_opp_put_regulators(pfdevfreq
->regulators_opp_table
);
169 pfdevfreq
->regulators_opp_table
= NULL
;
172 void panfrost_devfreq_resume(struct panfrost_device
*pfdev
)
174 struct panfrost_devfreq
*pfdevfreq
= &pfdev
->pfdevfreq
;
176 if (!pfdevfreq
->devfreq
)
179 panfrost_devfreq_reset(pfdevfreq
);
181 devfreq_resume_device(pfdevfreq
->devfreq
);
184 void panfrost_devfreq_suspend(struct panfrost_device
*pfdev
)
186 struct panfrost_devfreq
*pfdevfreq
= &pfdev
->pfdevfreq
;
188 if (!pfdevfreq
->devfreq
)
191 devfreq_suspend_device(pfdevfreq
->devfreq
);
194 void panfrost_devfreq_record_busy(struct panfrost_devfreq
*pfdevfreq
)
196 unsigned long irqflags
;
198 if (!pfdevfreq
->devfreq
)
201 spin_lock_irqsave(&pfdevfreq
->lock
, irqflags
);
203 panfrost_devfreq_update_utilization(pfdevfreq
);
205 pfdevfreq
->busy_count
++;
207 spin_unlock_irqrestore(&pfdevfreq
->lock
, irqflags
);
210 void panfrost_devfreq_record_idle(struct panfrost_devfreq
*pfdevfreq
)
212 unsigned long irqflags
;
214 if (!pfdevfreq
->devfreq
)
217 spin_lock_irqsave(&pfdevfreq
->lock
, irqflags
);
219 panfrost_devfreq_update_utilization(pfdevfreq
);
221 WARN_ON(--pfdevfreq
->busy_count
< 0);
223 spin_unlock_irqrestore(&pfdevfreq
->lock
, irqflags
);