MALI: rockchip: upgrade midgard DDK to r14p0-01rel0
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / arm / midgard / backend / gpu / mali_kbase_devfreq.c
1 /*
2  *
3  * (C) COPYRIGHT 2014-2016 ARM Limited. All rights reserved.
4  *
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
8  * of such GNU licence.
9  *
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.
13  *
14  */
15
16
17 #define ENABLE_DEBUG_LOG
18 #include "../../platform/rk/custom_log.h"
19
20
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>
27 #endif
28
29 #include <linux/clk.h>
30 #include <linux/devfreq.h>
31 #ifdef CONFIG_DEVFREQ_THERMAL
32 #include <linux/devfreq_cooling.h>
33 #endif
34
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.
42  */
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 */
49
50
51 static int
52 kbase_devfreq_target(struct device *dev, unsigned long *target_freq, u32 flags)
53 {
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;
59         int err = 0;
60
61         freq = *target_freq;
62
63         rcu_read_lock();
64         opp = devfreq_recommended_opp(dev, &freq, flags);
65         voltage = dev_pm_opp_get_voltage(opp);
66         rcu_read_unlock();
67         if (IS_ERR_OR_NULL(opp)) {
68                 dev_err(dev, "Failed to get opp (%ld)\n", PTR_ERR(opp));
69                 return PTR_ERR(opp);
70         }
71
72         /*
73          * Only update if there is a change of frequency
74          */
75         if (old_freq == freq) {
76                 *target_freq = freq;
77 #ifdef CONFIG_REGULATOR
78                 if (kbdev->current_voltage == voltage)
79                         return 0;
80                 err = regulator_set_voltage(kbdev->regulator, voltage, INT_MAX);
81                 if (err) {
82                         dev_err(dev, "Failed to set voltage (%d)\n", err);
83                         return err;
84                 }
85 #else
86                 return 0;
87 #endif
88         }
89
90 #ifdef CONFIG_REGULATOR
91         if (kbdev->regulator && kbdev->current_voltage != voltage &&
92             old_freq < freq) {
93                 err = regulator_set_voltage(kbdev->regulator, voltage, INT_MAX);
94                 if (err) {
95                         dev_err(dev, "Failed to increase voltage (%d)\n", err);
96                         return err;
97                 }
98         }
99 #endif
100
101         mutex_lock(&kbdev->mutex_for_clk);
102         if (!kbdev->is_power_off)
103                 err = clk_set_rate(kbdev->clock, freq);
104         kbdev->freq = freq;
105         mutex_unlock(&kbdev->mutex_for_clk);
106         if (err) {
107                 dev_err(dev, "Failed to set clock %lu (target %lu)\n",
108                                 freq, *target_freq);
109                 return err;
110         }
111         *target_freq = freq;
112         kbdev->current_freq = freq;
113
114 #ifdef CONFIG_REGULATOR
115         if (kbdev->regulator && kbdev->current_voltage != voltage &&
116             old_freq > freq) {
117                 err = regulator_set_voltage(kbdev->regulator, voltage, INT_MAX);
118                 if (err) {
119                         dev_err(dev, "Failed to decrease voltage (%d)\n", err);
120                         return err;
121                 }
122         }
123 #endif
124
125         kbdev->current_voltage = voltage;
126
127         kbase_tlstream_aux_devfreq_target((u64)freq);
128
129         kbase_pm_reset_dvfs_utilisation(kbdev);
130
131         return err;
132 }
133
134 static int
135 kbase_devfreq_cur_freq(struct device *dev, unsigned long *freq)
136 {
137         struct kbase_device *kbdev = dev_get_drvdata(dev);
138
139         *freq = kbdev->current_freq;
140
141         return 0;
142 }
143
144 static int
145 kbase_devfreq_status(struct device *dev, struct devfreq_dev_status *stat)
146 {
147         struct kbase_device *kbdev = dev_get_drvdata(dev);
148
149         stat->current_frequency = kbdev->current_freq;
150
151         kbase_pm_get_dvfs_utilisation(kbdev,
152                         &stat->total_time, &stat->busy_time);
153
154         stat->private_data = NULL;
155
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,
160                                 sizeof(*stat));
161 #endif
162 #endif
163
164         return 0;
165 }
166
167 static int kbase_devfreq_init_freq_table(struct kbase_device *kbdev,
168                 struct devfreq_dev_profile *dp)
169 {
170         int count;
171         int i = 0;
172         unsigned long freq = 0;
173         struct dev_pm_opp *opp;
174
175         rcu_read_lock();
176         count = dev_pm_opp_get_opp_count(kbdev->dev);
177         if (count < 0) {
178                 rcu_read_unlock();
179                 return count;
180         }
181         rcu_read_unlock();
182
183         dp->freq_table = kmalloc_array(count, sizeof(dp->freq_table[0]),
184                                 GFP_KERNEL);
185         if (!dp->freq_table)
186                 return -ENOMEM;
187
188         rcu_read_lock();
189         for (i = 0; i < count; i++, freq++) {
190                 opp = dev_pm_opp_find_freq_ceil(kbdev->dev, &freq);
191                 if (IS_ERR(opp))
192                         break;
193
194                 dp->freq_table[i] = freq;
195         }
196         rcu_read_unlock();
197
198         if (count != i)
199                 dev_warn(kbdev->dev, "Unable to enumerate all OPPs (%d!=%d\n",
200                                 count, i);
201
202         dp->max_state = i;
203
204         return 0;
205 }
206
207 static void kbase_devfreq_term_freq_table(struct kbase_device *kbdev)
208 {
209         struct devfreq_dev_profile *dp = kbdev->devfreq->profile;
210
211         kfree(dp->freq_table);
212 }
213
214 static void kbase_devfreq_exit(struct device *dev)
215 {
216         struct kbase_device *kbdev = dev_get_drvdata(dev);
217
218         kbase_devfreq_term_freq_table(kbdev);
219 }
220
221 int kbase_devfreq_init(struct kbase_device *kbdev)
222 {
223         struct devfreq_dev_profile *dp;
224         int err;
225
226         if (!kbdev->clock)
227                 return -ENODEV;
228
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);
234 #endif
235
236         dp = &kbdev->devfreq_profile;
237
238         dp->initial_freq = kbdev->current_freq;
239         /* .KP : set devfreq_dvfs_interval_in_ms */
240         dp->polling_ms = 20;
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;
245
246         if (kbase_devfreq_init_freq_table(kbdev, dp))
247                 return -EFAULT;
248
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);
254         }
255
256         err = devfreq_register_opp_notifier(kbdev->dev, kbdev->devfreq);
257         if (err) {
258                 dev_err(kbdev->dev,
259                         "Failed to register OPP notifier (%d)\n", err);
260                 goto opp_notifier_failed;
261         }
262
263 #ifdef CONFIG_DEVFREQ_THERMAL
264         err = kbase_power_model_simple_init(kbdev);
265         if (err && err != -ENODEV && err != -EPROBE_DEFER) {
266                 dev_err(kbdev->dev,
267                         "Failed to initialize simple power model (%d)\n",
268                         err);
269                 goto cooling_failed;
270         }
271         if (err == -EPROBE_DEFER)
272                 goto cooling_failed;
273         if (err != -ENODEV) {
274                 kbdev->devfreq_cooling = of_devfreq_cooling_register_power(
275                                 kbdev->dev->of_node,
276                                 kbdev->devfreq,
277                                 &power_model_simple_ops);
278                 if (IS_ERR_OR_NULL(kbdev->devfreq_cooling)) {
279                         err = PTR_ERR(kbdev->devfreq_cooling);
280                         dev_err(kbdev->dev,
281                                 "Failed to register cooling device (%d)\n",
282                                 err);
283                         goto cooling_failed;
284                 }
285         } else {
286                 err = 0;
287         }
288         I("success initing power_model_simple.");
289 #endif
290
291         return 0;
292
293 #ifdef CONFIG_DEVFREQ_THERMAL
294 cooling_failed:
295         devfreq_unregister_opp_notifier(kbdev->dev, kbdev->devfreq);
296 #endif /* CONFIG_DEVFREQ_THERMAL */
297 opp_notifier_failed:
298         if (devfreq_remove_device(kbdev->devfreq))
299                 dev_err(kbdev->dev, "Failed to terminate devfreq (%d)\n", err);
300         else
301                 kbdev->devfreq = NULL;
302
303         return err;
304 }
305
306 void kbase_devfreq_term(struct kbase_device *kbdev)
307 {
308         int err;
309
310         dev_dbg(kbdev->dev, "Term Mali devfreq\n");
311
312 #ifdef CONFIG_DEVFREQ_THERMAL
313         if (kbdev->devfreq_cooling)
314                 devfreq_cooling_unregister(kbdev->devfreq_cooling);
315 #endif
316
317         devfreq_unregister_opp_notifier(kbdev->dev, kbdev->devfreq);
318
319         err = devfreq_remove_device(kbdev->devfreq);
320         if (err)
321                 dev_err(kbdev->dev, "Failed to terminate devfreq (%d)\n", err);
322         else
323                 kbdev->devfreq = NULL;
324 }