[ARM] tegra: spdif/i2s audio: fixes
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-tegra / cpu-tegra.c
1 /*
2  * arch/arm/mach-tegra/cpu-tegra.c
3  *
4  * Copyright (C) 2010 Google, Inc.
5  *
6  * Author:
7  *      Colin Cross <ccross@google.com>
8  *      Based on arch/arm/plat-omap/cpu-omap.c, (C) 2005 Nokia Corporation
9  *
10  * This software is licensed under the terms of the GNU General Public
11  * License version 2, as published by the Free Software Foundation, and
12  * may be copied, distributed, and modified under those terms.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  */
20
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/types.h>
24 #include <linux/sched.h>
25 #include <linux/cpufreq.h>
26 #include <linux/delay.h>
27 #include <linux/init.h>
28 #include <linux/err.h>
29 #include <linux/clk.h>
30 #include <linux/io.h>
31 #include <linux/suspend.h>
32 #include <linux/debugfs.h>
33
34 #include <asm/smp_twd.h>
35 #include <asm/system.h>
36
37 #include <mach/hardware.h>
38 #include <mach/clk.h>
39
40 /* Frequency table index must be sequential starting at 0 and frequencies must be ascending*/
41 static struct cpufreq_frequency_table freq_table[] = {
42         { 0, 216000 },
43         { 1, 312000 },
44         { 2, 456000 },
45         { 3, 608000 },
46         { 4, 760000 },
47         { 5, 816000 },
48         { 6, 912000 },
49         { 7, 1000000 },
50         { 8, CPUFREQ_TABLE_END },
51 };
52
53 /* CPU frequency is gradually lowered when throttling is enabled */
54 #define THROTTLE_START_INDEX    2
55 #define THROTTLE_END_INDEX      6
56 #define THROTTLE_DELAY          msecs_to_jiffies(2000)
57 #define NO_DELAY                msecs_to_jiffies(0)
58
59 #define NUM_CPUS        2
60
61 static struct clk *cpu_clk;
62
63 static struct workqueue_struct *workqueue;
64
65 static unsigned long target_cpu_speed[NUM_CPUS];
66 static DEFINE_MUTEX(tegra_cpu_lock);
67 static bool is_suspended;
68
69 static DEFINE_MUTEX(throttling_lock);
70 static bool is_throttling;
71 static struct delayed_work throttle_work;
72
73
74 int tegra_verify_speed(struct cpufreq_policy *policy)
75 {
76         return cpufreq_frequency_table_verify(policy, freq_table);
77 }
78
79 unsigned int tegra_getspeed(unsigned int cpu)
80 {
81         unsigned long rate;
82
83         if (cpu >= NUM_CPUS)
84                 return 0;
85
86         rate = clk_get_rate(cpu_clk) / 1000;
87         return rate;
88 }
89
90 #ifdef CONFIG_HAVE_ARM_TWD
91 static void tegra_cpufreq_rescale_twd_other_cpu(void *data) {
92         unsigned long new_rate = *(unsigned long *)data;
93         twd_recalc_prescaler(new_rate);
94 }
95
96 static void tegra_cpufreq_rescale_twds(unsigned long new_rate)
97 {
98         twd_recalc_prescaler(new_rate);
99         smp_call_function(tegra_cpufreq_rescale_twd_other_cpu, &new_rate, 1);
100 }
101 #else
102 static inline void tegra_cpufreq_rescale_twds(unsigned long new_rate)
103 {
104 }
105 #endif
106
107 static int tegra_update_cpu_speed(unsigned long rate)
108 {
109         int ret = 0;
110         struct cpufreq_freqs freqs;
111
112         freqs.old = tegra_getspeed(0);
113         freqs.new = rate;
114
115         if (freqs.old == freqs.new)
116                 return ret;
117
118         for_each_online_cpu(freqs.cpu)
119                 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
120
121         if (freqs.new > freqs.old)
122                 tegra_cpufreq_rescale_twds(freqs.new * 1000);
123
124 #ifdef CONFIG_CPU_FREQ_DEBUG
125         printk(KERN_DEBUG "cpufreq-tegra: transition: %u --> %u\n",
126                freqs.old, freqs.new);
127 #endif
128
129         ret = clk_set_rate(cpu_clk, freqs.new * 1000);
130         if (ret) {
131                 pr_err("cpu-tegra: Failed to set cpu frequency to %d kHz\n",
132                         freqs.new);
133                 return ret;
134         }
135
136         if (freqs.new < freqs.old)
137                 tegra_cpufreq_rescale_twds(freqs.new * 1000);
138
139         for_each_online_cpu(freqs.cpu)
140                 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
141
142         return 0;
143 }
144
145 static unsigned long tegra_cpu_highest_speed(void) {
146         unsigned long rate = 0;
147         int i;
148
149         for_each_online_cpu(i)
150                 rate = max(rate, target_cpu_speed[i]);
151         return rate;
152 }
153
154 static int tegra_target(struct cpufreq_policy *policy,
155                        unsigned int target_freq,
156                        unsigned int relation)
157 {
158         int idx;
159         unsigned int freq;
160         unsigned int highest_speed;
161         unsigned int limit_when_throttling;
162         int ret = 0;
163
164         mutex_lock(&tegra_cpu_lock);
165
166         if (is_suspended) {
167                 ret = -EBUSY;
168                 goto out;
169         }
170
171         cpufreq_frequency_table_target(policy, freq_table, target_freq,
172                 relation, &idx);
173
174         freq = freq_table[idx].frequency;
175
176         target_cpu_speed[policy->cpu] = freq;
177
178         highest_speed = tegra_cpu_highest_speed();
179
180         /* Do not go above this frequency when throttling */
181         limit_when_throttling = freq_table[THROTTLE_START_INDEX].frequency;
182
183         if (is_throttling && highest_speed > limit_when_throttling) {
184                 if (tegra_getspeed(0) < limit_when_throttling) {
185                         ret = tegra_update_cpu_speed(limit_when_throttling);
186                         goto out;
187                 } else {
188                         ret = -EBUSY;
189                         goto out;
190                 }
191         }
192
193         ret = tegra_update_cpu_speed(highest_speed);
194 out:
195         mutex_unlock(&tegra_cpu_lock);
196         return ret;
197 }
198
199 static bool tegra_throttling_needed(unsigned long *rate)
200 {
201         unsigned int current_freq = tegra_getspeed(0);
202         int i;
203
204         for (i = THROTTLE_END_INDEX; i >= THROTTLE_START_INDEX; i--) {
205                 if (freq_table[i].frequency < current_freq) {
206                         *rate = freq_table[i].frequency;
207                         return true;
208                 }
209         }
210
211         return false;
212 }
213
214 static void tegra_throttle_work_func(struct work_struct *work)
215 {
216         unsigned long rate;
217
218         mutex_lock(&tegra_cpu_lock);
219
220         if (tegra_throttling_needed(&rate) && tegra_update_cpu_speed(rate) == 0) {
221                 queue_delayed_work(workqueue, &throttle_work, THROTTLE_DELAY);
222         }
223
224         mutex_unlock(&tegra_cpu_lock);
225 }
226
227 /**
228  * tegra_throttling_enable
229  * This functions may sleep
230  */
231 void tegra_throttling_enable(void)
232 {
233         mutex_lock(&throttling_lock);
234
235         if (!is_throttling) {
236                 is_throttling = true;
237                 queue_delayed_work(workqueue, &throttle_work, NO_DELAY);
238         }
239
240         mutex_unlock(&throttling_lock);
241 }
242 EXPORT_SYMBOL_GPL(tegra_throttling_enable);
243
244 /**
245  * tegra_throttling_disable
246  * This functions may sleep
247  */
248 void tegra_throttling_disable(void)
249 {
250         mutex_lock(&throttling_lock);
251
252         if (is_throttling) {
253                 cancel_delayed_work_sync(&throttle_work);
254                 is_throttling = false;
255         }
256
257         mutex_unlock(&throttling_lock);
258 }
259 EXPORT_SYMBOL_GPL(tegra_throttling_disable);
260
261 #ifdef CONFIG_DEBUG_FS
262 static int throttle_debug_set(void *data, u64 val)
263 {
264         if (val) {
265                 tegra_throttling_enable();
266         } else {
267                 tegra_throttling_disable();
268         }
269
270         return 0;
271 }
272 static int throttle_debug_get(void *data, u64 *val)
273 {
274         *val = (u64) is_throttling;
275         return 0;
276 }
277
278 DEFINE_SIMPLE_ATTRIBUTE(throttle_fops, throttle_debug_get, throttle_debug_set, "%llu\n");
279
280 static struct dentry *cpu_tegra_debugfs_root;
281
282 static int __init tegra_cpu_debug_init(void)
283 {
284         cpu_tegra_debugfs_root = debugfs_create_dir("cpu-tegra", 0);
285
286         if (!cpu_tegra_debugfs_root)
287                 return -ENOMEM;
288
289         if (!debugfs_create_file("throttle", 0644, cpu_tegra_debugfs_root, NULL, &throttle_fops))
290                 goto err_out;
291
292         return 0;
293
294 err_out:
295         debugfs_remove_recursive(cpu_tegra_debugfs_root);
296         return -ENOMEM;
297
298 }
299
300 static void __exit tegra_cpu_debug_exit(void)
301 {
302         debugfs_remove_recursive(cpu_tegra_debugfs_root);
303 }
304
305 late_initcall(tegra_cpu_debug_init);
306 module_exit(tegra_cpu_debug_exit);
307 #endif
308
309 static int tegra_pm_notify(struct notifier_block *nb, unsigned long event,
310         void *dummy)
311 {
312         mutex_lock(&tegra_cpu_lock);
313         if (event == PM_SUSPEND_PREPARE) {
314                 is_suspended = true;
315                 pr_info("Tegra cpufreq suspend: setting frequency to %d kHz\n",
316                         freq_table[0].frequency);
317                 tegra_update_cpu_speed(freq_table[0].frequency);
318         } else if (event == PM_POST_SUSPEND) {
319                 is_suspended = false;
320         }
321         mutex_unlock(&tegra_cpu_lock);
322
323         return NOTIFY_OK;
324 }
325
326 static struct notifier_block tegra_cpu_pm_notifier = {
327         .notifier_call = tegra_pm_notify,
328 };
329
330 static int tegra_cpu_init(struct cpufreq_policy *policy)
331 {
332         if (policy->cpu >= NUM_CPUS)
333                 return -EINVAL;
334
335         cpu_clk = clk_get_sys(NULL, "cpu");
336         if (IS_ERR(cpu_clk))
337                 return PTR_ERR(cpu_clk);
338
339         cpufreq_frequency_table_cpuinfo(policy, freq_table);
340         cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
341         policy->cur = tegra_getspeed(policy->cpu);
342         target_cpu_speed[policy->cpu] = policy->cur;
343
344         /* FIXME: what's the actual transition time? */
345         policy->cpuinfo.transition_latency = 300 * 1000;
346
347         policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
348         cpumask_copy(policy->related_cpus, cpu_possible_mask);
349
350         if (policy->cpu == 0) {
351                 INIT_DELAYED_WORK(&throttle_work, tegra_throttle_work_func);
352                 register_pm_notifier(&tegra_cpu_pm_notifier);
353         }
354
355         return 0;
356 }
357
358 static int tegra_cpu_exit(struct cpufreq_policy *policy)
359 {
360         cpufreq_frequency_table_cpuinfo(policy, freq_table);
361         clk_put(cpu_clk);
362         return 0;
363 }
364
365 static struct freq_attr *tegra_cpufreq_attr[] = {
366         &cpufreq_freq_attr_scaling_available_freqs,
367         NULL,
368 };
369
370 static struct cpufreq_driver tegra_cpufreq_driver = {
371         .verify         = tegra_verify_speed,
372         .target         = tegra_target,
373         .get            = tegra_getspeed,
374         .init           = tegra_cpu_init,
375         .exit           = tegra_cpu_exit,
376         .name           = "tegra",
377         .attr           = tegra_cpufreq_attr,
378 };
379
380 static int __init tegra_cpufreq_init(void)
381 {
382         workqueue = create_singlethread_workqueue("cpu-tegra");
383         if (!workqueue)
384                 return -ENOMEM;
385         return cpufreq_register_driver(&tegra_cpufreq_driver);
386 }
387
388 static void __exit tegra_cpufreq_exit(void)
389 {
390         destroy_workqueue(workqueue);
391         cpufreq_unregister_driver(&tegra_cpufreq_driver);
392 }
393
394
395 MODULE_AUTHOR("Colin Cross <ccross@android.com>");
396 MODULE_DESCRIPTION("cpufreq driver for Nvidia Tegra2");
397 MODULE_LICENSE("GPL");
398 module_init(tegra_cpufreq_init);
399 module_exit(tegra_cpufreq_exit);