LOCAL / GPU: ARM: add MALI R12P0_04REL0 drivers
[platform/kernel/linux-exynos.git] / drivers / gpu / arm / midgard / r12p0_04rel0 / backend / gpu / mali_kbase_devfreq.c
1 /*
2  *
3  * (C) COPYRIGHT 2014-2015 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
18 #include <mali_kbase.h>
19 #include <mali_kbase_config_defaults.h>
20 #include <backend/gpu/mali_kbase_pm_internal.h>
21 #ifdef CONFIG_DEVFREQ_THERMAL
22 #include <backend/gpu/mali_kbase_power_model_simple.h>
23 #endif
24
25 #include <linux/clk.h>
26 #include <linux/devfreq.h>
27 #ifdef CONFIG_DEVFREQ_THERMAL
28 #include <linux/devfreq_cooling.h>
29 #endif
30
31 #include <linux/version.h>
32 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
33 #include <linux/pm_opp.h>
34 #else /* Linux >= 3.13 */
35 /* In 3.13 the OPP include header file, types, and functions were all
36  * renamed. Use the old filename for the include, and define the new names to
37  * the old, when an old kernel is detected.
38  */
39 #include <linux/opp.h>
40 #define dev_pm_opp opp
41 #define dev_pm_opp_get_voltage opp_get_voltage
42 #define dev_pm_opp_get_opp_count opp_get_opp_count
43 #define dev_pm_opp_find_freq_ceil opp_find_freq_ceil
44 #endif /* Linux >= 3.13 */
45
46
47 static int
48 kbase_devfreq_target(struct device *dev, unsigned long *target_freq, u32 flags)
49 {
50         struct kbase_device *kbdev = dev_get_drvdata(dev);
51         struct dev_pm_opp *opp;
52         unsigned long freq = 0, last_freq = 0;
53         unsigned long voltage, last_voltage = 0;
54         int err;
55
56         freq = *target_freq;
57
58         rcu_read_lock();
59         opp = devfreq_recommended_opp(dev, &freq, flags);
60         voltage = dev_pm_opp_get_voltage(opp);
61         rcu_read_unlock();
62         if (IS_ERR(opp)) {
63                 dev_err(dev, "Failed to get opp (%ld)\n", PTR_ERR(opp));
64                 return PTR_ERR(opp);
65         }
66
67         /*
68          * Only update if there is a change of frequency
69          */
70         if (kbdev->current_freq == freq) {
71                 *target_freq = freq;
72                 return 0;
73         }
74
75 #ifdef CONFIG_REGULATOR
76         if (kbdev->regulator && kbdev->current_voltage != voltage
77                         && kbdev->current_freq < freq) {
78                 last_voltage = regulator_get_voltage(kbdev->regulator);
79                 if (last_voltage < 0) {
80                         dev_err(dev, "Failed to get voltage (%lu)\n",
81                                 last_voltage);
82                         return last_voltage;
83                 }
84
85                 err = regulator_set_voltage(kbdev->regulator, voltage, voltage);
86                 if (err) {
87                         dev_err(dev, "Failed to increase voltage (%d)\n", err);
88                         return err;
89                 }
90         }
91 #endif
92         if (kbdev->current_freq > freq)
93                 last_freq = clk_get_rate(kbdev->clock);
94
95         err = clk_set_rate(kbdev->clock, freq);
96         if (err) {
97                 dev_err(dev, "Failed to set clock %lu (target %lu)\n",
98                                 freq, *target_freq);
99                 if (last_voltage > 0)
100                         regulator_set_voltage(kbdev->regulator, last_voltage,
101                                               last_voltage);
102                 return err;
103         }
104
105 #ifdef CONFIG_REGULATOR
106         if (kbdev->regulator && kbdev->current_voltage != voltage
107                         && kbdev->current_freq > freq) {
108                 err = regulator_set_voltage(kbdev->regulator, voltage, voltage);
109                 if (err) {
110                         clk_set_rate(kbdev->clock, last_freq);
111                         dev_err(dev, "Failed to decrease voltage (%d)\n", err);
112                         return err;
113                 }
114         }
115 #endif
116
117         *target_freq = freq;
118         kbdev->current_voltage = voltage;
119         kbdev->current_freq = freq;
120
121         kbase_pm_reset_dvfs_utilisation(kbdev);
122
123         return err;
124 }
125
126 static int
127 kbase_devfreq_cur_freq(struct device *dev, unsigned long *freq)
128 {
129         struct kbase_device *kbdev = dev_get_drvdata(dev);
130
131         *freq = kbdev->current_freq;
132
133         return 0;
134 }
135
136 static int
137 kbase_devfreq_status(struct device *dev, struct devfreq_dev_status *stat)
138 {
139         struct kbase_device *kbdev = dev_get_drvdata(dev);
140
141         stat->current_frequency = kbdev->current_freq;
142
143         kbase_pm_get_dvfs_utilisation(kbdev,
144                         &stat->total_time, &stat->busy_time);
145
146         stat->private_data = NULL;
147
148 #ifdef CONFIG_DEVFREQ_THERMAL
149 #if 0 /* FIXME: devfreq_cooling has no last_status field */
150         if (kbdev->devfreq_cooling)
151                 memcpy(&kbdev->devfreq_cooling->last_status, stat,
152                                 sizeof(*stat));
153 #endif
154 #endif
155
156         return 0;
157 }
158
159 static int kbase_devfreq_init_freq_table(struct kbase_device *kbdev,
160                 struct devfreq_dev_profile *dp)
161 {
162         int count;
163         int i = 0;
164         unsigned long freq = 0;
165         struct dev_pm_opp *opp;
166
167         rcu_read_lock();
168         count = dev_pm_opp_get_opp_count(kbdev->dev);
169         if (count < 0) {
170                 rcu_read_unlock();
171                 return count;
172         }
173         rcu_read_unlock();
174
175         dp->freq_table = kmalloc_array(count, sizeof(dp->freq_table[0]),
176                                 GFP_KERNEL);
177         if (!dp->freq_table)
178                 return -ENOMEM;
179
180         rcu_read_lock();
181         freq = ULONG_MAX;
182         for (i = 0; i < count; i++, freq--) {
183                 opp = dev_pm_opp_find_freq_floor(kbdev->dev, &freq);
184                 if (IS_ERR(opp))
185                         break;
186
187                 dp->freq_table[i] = freq;
188         }
189         rcu_read_unlock();
190
191         if (count != i)
192                 dev_warn(kbdev->dev, "Unable to enumerate all OPPs (%d!=%d\n",
193                                 count, i);
194
195         dp->max_state = i;
196
197         return 0;
198 }
199
200 static void kbase_devfreq_term_freq_table(struct kbase_device *kbdev)
201 {
202         struct devfreq_dev_profile *dp = kbdev->devfreq->profile;
203
204         kfree(dp->freq_table);
205 }
206
207 static void kbase_devfreq_exit(struct device *dev)
208 {
209         struct kbase_device *kbdev = dev_get_drvdata(dev);
210
211         kbase_devfreq_term_freq_table(kbdev);
212 }
213
214 static struct devfreq_simple_ondemand_data kbase_devfreq_ondemand_data = {
215         .upthreshold            = 40,
216         .downdifferential       = 5,
217 };
218
219 int kbase_devfreq_init(struct kbase_device *kbdev)
220 {
221         struct devfreq_dev_profile *dp;
222         int err;
223
224         if (!kbdev->clock)
225                 return -ENODEV;
226
227         kbdev->current_freq = clk_get_rate(kbdev->clock);
228
229         dp = &kbdev->devfreq_profile;
230
231         dp->initial_freq = kbdev->current_freq;
232         dp->polling_ms = 100;
233         dp->target = kbase_devfreq_target;
234         dp->get_dev_status = kbase_devfreq_status;
235         dp->get_cur_freq = kbase_devfreq_cur_freq;
236         dp->exit = kbase_devfreq_exit;
237
238         if (kbase_devfreq_init_freq_table(kbdev, dp))
239                 return -EFAULT;
240
241         kbdev->devfreq = devfreq_add_device(kbdev->dev, dp,
242                                 "simple_ondemand",
243                                 &kbase_devfreq_ondemand_data);
244         if (IS_ERR(kbdev->devfreq)) {
245                 kbase_devfreq_term_freq_table(kbdev);
246                 return PTR_ERR(kbdev->devfreq);
247         }
248
249         err = devfreq_register_opp_notifier(kbdev->dev, kbdev->devfreq);
250         if (err) {
251                 dev_err(kbdev->dev,
252                         "Failed to register OPP notifier (%d)\n", err);
253                 goto opp_notifier_failed;
254         }
255
256 #ifdef CONFIG_DEVFREQ_THERMAL
257         err = kbase_power_model_simple_init(kbdev);
258         if (err && err != -ENODEV && err != -EPROBE_DEFER) {
259                 dev_err(kbdev->dev,
260                         "Failed to initialize simple power model (%d)\n",
261                         err);
262                 goto cooling_failed;
263         }
264         if (err == -EPROBE_DEFER)
265                 goto cooling_failed;
266         if (err != -ENODEV) {
267                 kbdev->devfreq_cooling = of_devfreq_cooling_register_power(
268                                 kbdev->dev->of_node,
269                                 kbdev->devfreq,
270                                 &power_model_simple_ops);
271                 if (IS_ERR(kbdev->devfreq_cooling)) {
272                         err = PTR_ERR(kbdev->devfreq_cooling);
273                         dev_err(kbdev->dev,
274                                 "Failed to register cooling device (%d)\n",
275                                 err);
276                         goto cooling_failed;
277                 }
278         } else {
279                 err = 0;
280         }
281 #endif
282
283         return 0;
284
285 #ifdef CONFIG_DEVFREQ_THERMAL
286 cooling_failed:
287         devfreq_unregister_opp_notifier(kbdev->dev, kbdev->devfreq);
288 #endif /* CONFIG_DEVFREQ_THERMAL */
289 opp_notifier_failed:
290         if (devfreq_remove_device(kbdev->devfreq))
291                 dev_err(kbdev->dev, "Failed to terminate devfreq (%d)\n", err);
292         else
293                 kbdev->devfreq = NULL;
294
295         return err;
296 }
297
298 void kbase_devfreq_term(struct kbase_device *kbdev)
299 {
300         int err;
301
302         dev_dbg(kbdev->dev, "Term Mali devfreq\n");
303
304 #ifdef CONFIG_DEVFREQ_THERMAL
305         if (kbdev->devfreq_cooling)
306                 devfreq_cooling_unregister(kbdev->devfreq_cooling);
307 #endif
308
309         devfreq_unregister_opp_notifier(kbdev->dev, kbdev->devfreq);
310
311         err = devfreq_remove_device(kbdev->devfreq);
312         if (err)
313                 dev_err(kbdev->dev, "Failed to terminate devfreq (%d)\n", err);
314         else
315                 kbdev->devfreq = NULL;
316 }