3 * (C) COPYRIGHT 2014-2016 ARM Limited. All rights reserved.
5 * This program is free software and is provided to you under the terms of the
6 * GNU General Public License version 2 as published by the Free Software
7 * Foundation, and any use by you of this program is subject to the terms
10 * A copy of the licence is included with the program, and can also be obtained
11 * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
12 * Boston, MA 02110-1301, USA.
17 #define ENABLE_DEBUG_LOG
18 #include "../../platform/rk/custom_log.h"
21 #include <mali_kbase.h>
22 #include <mali_kbase_tlstream.h>
23 #include <mali_kbase_config_defaults.h>
24 #include <backend/gpu/mali_kbase_pm_internal.h>
25 #ifdef CONFIG_DEVFREQ_THERMAL
26 #include <backend/gpu/mali_kbase_power_model_simple.h>
29 #include <linux/clk.h>
30 #include <linux/devfreq.h>
31 #ifdef CONFIG_DEVFREQ_THERMAL
32 #include <linux/devfreq_cooling.h>
35 #include <linux/version.h>
36 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
37 #include <linux/pm_opp.h>
38 #else /* Linux >= 3.13 */
39 /* In 3.13 the OPP include header file, types, and functions were all
40 * renamed. Use the old filename for the include, and define the new names to
41 * the old, when an old kernel is detected.
43 #include <linux/opp.h>
44 #define dev_pm_opp opp
45 #define dev_pm_opp_get_voltage opp_get_voltage
46 #define dev_pm_opp_get_opp_count opp_get_opp_count
47 #define dev_pm_opp_find_freq_ceil opp_find_freq_ceil
48 #endif /* Linux >= 3.13 */
52 kbase_devfreq_target(struct device *dev, unsigned long *target_freq, u32 flags)
54 struct kbase_device *kbdev = dev_get_drvdata(dev);
55 struct dev_pm_opp *opp;
56 unsigned long freq = 0;
57 unsigned long old_freq = kbdev->current_freq;
58 unsigned long voltage;
64 opp = devfreq_recommended_opp(dev, &freq, flags);
65 voltage = dev_pm_opp_get_voltage(opp);
67 if (IS_ERR_OR_NULL(opp)) {
68 dev_err(dev, "Failed to get opp (%ld)\n", PTR_ERR(opp));
73 * Only update if there is a change of frequency
75 if (old_freq == freq) {
77 #ifdef CONFIG_REGULATOR
78 if (kbdev->current_voltage == voltage)
80 err = regulator_set_voltage(kbdev->regulator, voltage, INT_MAX);
82 dev_err(dev, "Failed to set voltage (%d)\n", err);
90 #ifdef CONFIG_REGULATOR
91 if (kbdev->regulator && kbdev->current_voltage != voltage &&
93 err = regulator_set_voltage(kbdev->regulator, voltage, INT_MAX);
95 dev_err(dev, "Failed to increase voltage (%d)\n", err);
101 mutex_lock(&kbdev->mutex_for_clk);
102 if (!kbdev->is_power_off)
103 err = clk_set_rate(kbdev->clock, freq);
105 mutex_unlock(&kbdev->mutex_for_clk);
107 dev_err(dev, "Failed to set clock %lu (target %lu)\n",
112 kbdev->current_freq = freq;
114 #ifdef CONFIG_REGULATOR
115 if (kbdev->regulator && kbdev->current_voltage != voltage &&
117 err = regulator_set_voltage(kbdev->regulator, voltage, INT_MAX);
119 dev_err(dev, "Failed to decrease voltage (%d)\n", err);
125 kbdev->current_voltage = voltage;
127 kbase_tlstream_aux_devfreq_target((u64)freq);
129 kbase_pm_reset_dvfs_utilisation(kbdev);
135 kbase_devfreq_cur_freq(struct device *dev, unsigned long *freq)
137 struct kbase_device *kbdev = dev_get_drvdata(dev);
139 *freq = kbdev->current_freq;
145 kbase_devfreq_status(struct device *dev, struct devfreq_dev_status *stat)
147 struct kbase_device *kbdev = dev_get_drvdata(dev);
149 stat->current_frequency = kbdev->current_freq;
151 kbase_pm_get_dvfs_utilisation(kbdev,
152 &stat->total_time, &stat->busy_time);
154 stat->private_data = NULL;
156 #ifdef CONFIG_DEVFREQ_THERMAL
157 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
158 if (kbdev->devfreq_cooling)
159 memcpy(&kbdev->devfreq_cooling->last_status, stat,
167 static int kbase_devfreq_init_freq_table(struct kbase_device *kbdev,
168 struct devfreq_dev_profile *dp)
172 unsigned long freq = 0;
173 struct dev_pm_opp *opp;
176 count = dev_pm_opp_get_opp_count(kbdev->dev);
183 dp->freq_table = kmalloc_array(count, sizeof(dp->freq_table[0]),
189 for (i = 0; i < count; i++, freq++) {
190 opp = dev_pm_opp_find_freq_ceil(kbdev->dev, &freq);
194 dp->freq_table[i] = freq;
199 dev_warn(kbdev->dev, "Unable to enumerate all OPPs (%d!=%d\n",
207 static void kbase_devfreq_term_freq_table(struct kbase_device *kbdev)
209 struct devfreq_dev_profile *dp = kbdev->devfreq->profile;
211 kfree(dp->freq_table);
214 static void kbase_devfreq_exit(struct device *dev)
216 struct kbase_device *kbdev = dev_get_drvdata(dev);
218 kbase_devfreq_term_freq_table(kbdev);
221 int kbase_devfreq_init(struct kbase_device *kbdev)
223 struct devfreq_dev_profile *dp;
229 kbdev->current_freq = clk_get_rate(kbdev->clock);
230 #ifdef CONFIG_REGULATOR
231 if (kbdev->regulator)
232 kbdev->current_voltage =
233 regulator_get_voltage(kbdev->regulator);
236 dp = &kbdev->devfreq_profile;
238 dp->initial_freq = kbdev->current_freq;
239 /* .KP : set devfreq_dvfs_interval_in_ms */
241 dp->target = kbase_devfreq_target;
242 dp->get_dev_status = kbase_devfreq_status;
243 dp->get_cur_freq = kbase_devfreq_cur_freq;
244 dp->exit = kbase_devfreq_exit;
246 if (kbase_devfreq_init_freq_table(kbdev, dp))
249 kbdev->devfreq = devfreq_add_device(kbdev->dev, dp,
250 "simple_ondemand", NULL);
251 if (IS_ERR(kbdev->devfreq)) {
252 kbase_devfreq_term_freq_table(kbdev);
253 return PTR_ERR(kbdev->devfreq);
256 err = devfreq_register_opp_notifier(kbdev->dev, kbdev->devfreq);
259 "Failed to register OPP notifier (%d)\n", err);
260 goto opp_notifier_failed;
263 #ifdef CONFIG_DEVFREQ_THERMAL
264 err = kbase_power_model_simple_init(kbdev);
265 if (err && err != -ENODEV && err != -EPROBE_DEFER) {
267 "Failed to initialize simple power model (%d)\n",
271 if (err == -EPROBE_DEFER)
273 if (err != -ENODEV) {
274 kbdev->devfreq_cooling = of_devfreq_cooling_register_power(
277 &power_model_simple_ops);
278 if (IS_ERR_OR_NULL(kbdev->devfreq_cooling)) {
279 err = PTR_ERR(kbdev->devfreq_cooling);
281 "Failed to register cooling device (%d)\n",
288 I("success initing power_model_simple.");
293 #ifdef CONFIG_DEVFREQ_THERMAL
295 devfreq_unregister_opp_notifier(kbdev->dev, kbdev->devfreq);
296 #endif /* CONFIG_DEVFREQ_THERMAL */
298 if (devfreq_remove_device(kbdev->devfreq))
299 dev_err(kbdev->dev, "Failed to terminate devfreq (%d)\n", err);
301 kbdev->devfreq = NULL;
306 void kbase_devfreq_term(struct kbase_device *kbdev)
310 dev_dbg(kbdev->dev, "Term Mali devfreq\n");
312 #ifdef CONFIG_DEVFREQ_THERMAL
313 if (kbdev->devfreq_cooling)
314 devfreq_cooling_unregister(kbdev->devfreq_cooling);
317 devfreq_unregister_opp_notifier(kbdev->dev, kbdev->devfreq);
319 err = devfreq_remove_device(kbdev->devfreq);
321 dev_err(kbdev->dev, "Failed to terminate devfreq (%d)\n", err);
323 kbdev->devfreq = NULL;