rk_fb: add extern screen open iommu, when dual screen display using iommu
[firefly-linux-kernel-4.4.55.git] / drivers / cpuquiet / rockchip-cpuquiet.c
1 /*
2  * Cpuquiet driver for Rockchip SoCs
3  *
4  * Copyright (c) 2015, Fuzhou Rockchip Electronics Co., Ltd
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  */
15
16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17
18 #include <linux/kernel.h>
19 #include <linux/types.h>
20 #include <linux/sched.h>
21 #include <linux/module.h>
22 #include <linux/cpufreq.h>
23 #include <linux/delay.h>
24 #include <linux/err.h>
25 #include <linux/io.h>
26 #include <linux/cpu.h>
27 #include <linux/clk.h>
28 #include <linux/debugfs.h>
29 #include <linux/seq_file.h>
30 #include <linux/cpuquiet.h>
31 #include <linux/pm_qos.h>
32 #include <linux/debugfs.h>
33 #include <linux/slab.h>
34
35 #define INITIAL_STATE           CPQ_DISABLED
36 #define HOTPLUG_DELAY_MS        100
37
38 static DEFINE_MUTEX(rockchip_cpuquiet_lock);
39 static DEFINE_MUTEX(rockchip_cpq_lock_stats);
40
41 static struct workqueue_struct *cpuquiet_wq;
42 static struct work_struct cpuquiet_work;
43
44 static wait_queue_head_t wait_enable;
45 static wait_queue_head_t wait_cpu;
46
47 static bool enable;
48 static unsigned long hotplug_timeout_jiffies;
49
50 static struct cpumask cpumask_online_requests;
51 static struct cpumask cpumask_offline_requests;
52
53 enum {
54         CPQ_DISABLED = 0,
55         CPQ_ENABLED,
56         CPQ_IDLE,
57 };
58
59 static int cpq_target_state;
60
61 static int cpq_state;
62
63 static struct {
64         cputime64_t time_up_total;
65         u64 last_update;
66         unsigned int up_down_count;
67 } hp_stats[CONFIG_NR_CPUS];
68
69 static void hp_init_stats(void)
70 {
71         int i;
72         u64 cur_jiffies = get_jiffies_64();
73
74         mutex_lock(&rockchip_cpq_lock_stats);
75
76         for (i = 0; i < nr_cpu_ids; i++) {
77                 hp_stats[i].time_up_total = 0;
78                 hp_stats[i].last_update = cur_jiffies;
79
80                 hp_stats[i].up_down_count = 0;
81                 if (cpu_online(i))
82                         hp_stats[i].up_down_count = 1;
83         }
84
85         mutex_unlock(&rockchip_cpq_lock_stats);
86 }
87
88 /* must be called with rockchip_cpq_lock_stats held */
89 static void __hp_stats_update(unsigned int cpu, bool up)
90 {
91         u64 cur_jiffies = get_jiffies_64();
92         bool was_up;
93
94         was_up = hp_stats[cpu].up_down_count & 0x1;
95
96         if (was_up)
97                 hp_stats[cpu].time_up_total =
98                         hp_stats[cpu].time_up_total +
99                         (cur_jiffies - hp_stats[cpu].last_update);
100
101         if (was_up != up) {
102                 hp_stats[cpu].up_down_count++;
103                 if ((hp_stats[cpu].up_down_count & 0x1) != up) {
104                         /* FIXME: sysfs user space CPU control breaks stats */
105                         pr_err("hotplug stats out of sync with CPU%d", cpu);
106                         hp_stats[cpu].up_down_count ^=  0x1;
107                 }
108         }
109         hp_stats[cpu].last_update = cur_jiffies;
110 }
111
112 static void hp_stats_update(unsigned int cpu, bool up)
113 {
114         mutex_lock(&rockchip_cpq_lock_stats);
115
116         __hp_stats_update(cpu, up);
117
118         mutex_unlock(&rockchip_cpq_lock_stats);
119 }
120
121 static int update_core_config(unsigned int cpunumber, bool up)
122 {
123         int ret = 0;
124
125         mutex_lock(&rockchip_cpuquiet_lock);
126
127         if (cpq_state == CPQ_DISABLED || cpunumber >= nr_cpu_ids) {
128                 mutex_unlock(&rockchip_cpuquiet_lock);
129                 return -EINVAL;
130         }
131
132         if (up) {
133                 cpumask_set_cpu(cpunumber, &cpumask_online_requests);
134                 cpumask_clear_cpu(cpunumber, &cpumask_offline_requests);
135                 queue_work(cpuquiet_wq, &cpuquiet_work);
136         } else {
137                 cpumask_set_cpu(cpunumber, &cpumask_offline_requests);
138                 cpumask_clear_cpu(cpunumber, &cpumask_online_requests);
139                 queue_work(cpuquiet_wq, &cpuquiet_work);
140         }
141
142         mutex_unlock(&rockchip_cpuquiet_lock);
143
144         return ret;
145 }
146
147 static int rockchip_quiesence_cpu(unsigned int cpunumber, bool sync)
148 {
149         int err = 0;
150
151         err = update_core_config(cpunumber, false);
152         if (err || !sync)
153                 return err;
154
155         err = wait_event_interruptible_timeout(wait_cpu,
156                                                !cpu_online(cpunumber),
157                                                hotplug_timeout_jiffies);
158
159         if (err < 0)
160                 return err;
161
162         if (err > 0)
163                 return 0;
164         else
165                 return -ETIMEDOUT;
166 }
167
168 static int rockchip_wake_cpu(unsigned int cpunumber, bool sync)
169 {
170         int err = 0;
171
172         err = update_core_config(cpunumber, true);
173         if (err || !sync)
174                 return err;
175
176         err = wait_event_interruptible_timeout(wait_cpu, cpu_online(cpunumber),
177                                                hotplug_timeout_jiffies);
178
179         if (err < 0)
180                 return err;
181
182         if (err > 0)
183                 return 0;
184         else
185                 return -ETIMEDOUT;
186 }
187
188 static struct cpuquiet_driver rockchip_cpuquiet_driver = {
189         .name           = "rockchip",
190         .quiesence_cpu  = rockchip_quiesence_cpu,
191         .wake_cpu       = rockchip_wake_cpu,
192 };
193
194 /* must be called from worker function */
195 static void __cpuinit __apply_core_config(void)
196 {
197         int count = -1;
198         unsigned int cpu;
199         int nr_cpus;
200         struct cpumask online, offline, cpu_online;
201         int max_cpus = pm_qos_request(PM_QOS_MAX_ONLINE_CPUS);
202         int min_cpus = pm_qos_request(PM_QOS_MIN_ONLINE_CPUS);
203
204         if (min_cpus > num_possible_cpus())
205                 min_cpus = 0;
206         if (max_cpus <= 0)
207                 max_cpus = num_present_cpus();
208
209         mutex_lock(&rockchip_cpuquiet_lock);
210
211         online = cpumask_online_requests;
212         offline = cpumask_offline_requests;
213
214         mutex_unlock(&rockchip_cpuquiet_lock);
215
216         /* always keep CPU0 online */
217         cpumask_set_cpu(0, &online);
218         cpu_online = *cpu_online_mask;
219
220         if (max_cpus < min_cpus)
221                 max_cpus = min_cpus;
222
223         nr_cpus = cpumask_weight(&online);
224         if (nr_cpus < min_cpus) {
225                 cpu = 0;
226                 count = min_cpus - nr_cpus;
227                 for (; count > 0; count--) {
228                         cpu = cpumask_next_zero(cpu, &online);
229                         cpumask_set_cpu(cpu, &online);
230                         cpumask_clear_cpu(cpu, &offline);
231                 }
232         } else if (nr_cpus > max_cpus) {
233                 count = nr_cpus - max_cpus;
234                 cpu = 0;
235                 for (; count > 0; count--) {
236                         /* CPU0 should always be online */
237                         cpu = cpumask_next(cpu, &online);
238                         cpumask_set_cpu(cpu, &offline);
239                         cpumask_clear_cpu(cpu, &online);
240                 }
241         }
242
243         cpumask_andnot(&online, &online, &cpu_online);
244         for_each_cpu(cpu, &online) {
245                 cpu_up(cpu);
246                 hp_stats_update(cpu, true);
247         }
248
249         cpumask_and(&offline, &offline, &cpu_online);
250         for_each_cpu(cpu, &offline) {
251                 cpu_down(cpu);
252                 hp_stats_update(cpu, false);
253         }
254         wake_up_interruptible(&wait_cpu);
255 }
256
257 static void __cpuinit rockchip_cpuquiet_work_func(struct work_struct *work)
258 {
259         int action;
260
261         mutex_lock(&rockchip_cpuquiet_lock);
262
263         action = cpq_target_state;
264
265         if (action == CPQ_ENABLED) {
266                 hp_init_stats();
267                 cpuquiet_device_free();
268                 pr_info("cpuquiet enabled\n");
269                 cpq_state = CPQ_ENABLED;
270                 cpq_target_state = CPQ_IDLE;
271                 wake_up_interruptible(&wait_enable);
272         }
273
274         if (cpq_state == CPQ_DISABLED) {
275                 mutex_unlock(&rockchip_cpuquiet_lock);
276                 return;
277         }
278
279         if (action == CPQ_DISABLED) {
280                 cpq_state = CPQ_DISABLED;
281                 mutex_unlock(&rockchip_cpuquiet_lock);
282                 cpuquiet_device_busy();
283                 pr_info("cpuquiet disabled\n");
284                 wake_up_interruptible(&wait_enable);
285                 return;
286         }
287
288         mutex_unlock(&rockchip_cpuquiet_lock);
289         __apply_core_config();
290 }
291
292 static int min_cpus_notify(struct notifier_block *nb, unsigned long n, void *p)
293 {
294         mutex_lock(&rockchip_cpuquiet_lock);
295
296         if (cpq_state != CPQ_DISABLED)
297                 queue_work(cpuquiet_wq, &cpuquiet_work);
298
299         mutex_unlock(&rockchip_cpuquiet_lock);
300
301         return NOTIFY_OK;
302 }
303
304 static int max_cpus_notify(struct notifier_block *nb, unsigned long n, void *p)
305 {
306         mutex_lock(&rockchip_cpuquiet_lock);
307
308         if (cpq_state != CPQ_DISABLED)
309                 queue_work(cpuquiet_wq, &cpuquiet_work);
310
311         mutex_unlock(&rockchip_cpuquiet_lock);
312
313         return NOTIFY_OK;
314 }
315
316 /* Must be called with rockchip_cpuquiet_lock held */
317 static void __idle_stop_governor(void)
318 {
319         if (cpq_state == CPQ_DISABLED)
320                 return;
321
322         if (num_online_cpus() == 1)
323                 cpuquiet_device_busy();
324         else
325                 cpuquiet_device_free();
326 }
327
328 static int __cpuinit cpu_online_notify(struct notifier_block *nfb,
329                                        unsigned long action, void *hcpu)
330 {
331         switch (action) {
332         case CPU_POST_DEAD:
333                 if (num_online_cpus() == 1) {
334                         mutex_lock(&rockchip_cpuquiet_lock);
335                         __idle_stop_governor();
336                         mutex_unlock(&rockchip_cpuquiet_lock);
337                 }
338                 break;
339         case CPU_ONLINE:
340         case CPU_ONLINE_FROZEN:
341                 mutex_lock(&rockchip_cpuquiet_lock);
342                 __idle_stop_governor();
343                 mutex_unlock(&rockchip_cpuquiet_lock);
344                 break;
345         }
346
347         return NOTIFY_OK;
348 }
349
350 static struct notifier_block cpu_online_notifier __cpuinitdata = {
351         .notifier_call = cpu_online_notify,
352 };
353
354 static struct notifier_block min_cpus_notifier = {
355         .notifier_call = min_cpus_notify,
356 };
357
358 static struct notifier_block max_cpus_notifier = {
359         .notifier_call = max_cpus_notify,
360 };
361
362 static void delay_callback(struct cpuquiet_attribute *attr)
363 {
364         unsigned long val;
365
366         if (attr) {
367                 val = (*((unsigned long *)(attr->param)));
368                 (*((unsigned long *)(attr->param))) = msecs_to_jiffies(val);
369         }
370 }
371
372 static void enable_callback(struct cpuquiet_attribute *attr)
373 {
374         int target_state = enable ? CPQ_ENABLED : CPQ_DISABLED;
375
376         mutex_lock(&rockchip_cpuquiet_lock);
377
378         if (cpq_state != target_state) {
379                 cpq_target_state = target_state;
380                 queue_work(cpuquiet_wq, &cpuquiet_work);
381         }
382
383         mutex_unlock(&rockchip_cpuquiet_lock);
384
385         wait_event_interruptible(wait_enable, cpq_state == target_state);
386 }
387
388 CPQ_ATTRIBUTE(hotplug_timeout_jiffies, 0644, ulong, delay_callback);
389 CPQ_ATTRIBUTE(enable, 0644, bool, enable_callback);
390
391 static struct attribute *rockchip_cpuquiet_attributes[] = {
392         &enable_attr.attr,
393         &hotplug_timeout_jiffies_attr.attr,
394         NULL,
395 };
396
397 static const struct sysfs_ops rockchip_cpuquiet_sysfs_ops = {
398         .show = cpuquiet_auto_sysfs_show,
399         .store = cpuquiet_auto_sysfs_store,
400 };
401
402 static struct kobj_type ktype_sysfs = {
403         .sysfs_ops = &rockchip_cpuquiet_sysfs_ops,
404         .default_attrs = rockchip_cpuquiet_attributes,
405 };
406
407 static int rockchip_cpuquiet_sysfs_init(void)
408 {
409         int err;
410
411         struct kobject *kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
412
413         if (!kobj)
414                 return -ENOMEM;
415
416         err = cpuquiet_kobject_init(kobj, &ktype_sysfs, "rockchip_cpuquiet");
417
418         if (err)
419                 kfree(kobj);
420
421         return err;
422 }
423
424 #ifdef CONFIG_DEBUG_FS
425 static int hp_stats_show(struct seq_file *s, void *data)
426 {
427         int i;
428         u64 cur_jiffies = get_jiffies_64();
429
430         mutex_lock(&rockchip_cpuquiet_lock);
431
432         mutex_lock(&rockchip_cpq_lock_stats);
433
434         if (cpq_state != CPQ_DISABLED) {
435                 for (i = 0; i < nr_cpu_ids; i++) {
436                         bool was_up;
437
438                         was_up = (hp_stats[i].up_down_count & 0x1);
439                         __hp_stats_update(i, was_up);
440                 }
441         }
442         mutex_unlock(&rockchip_cpq_lock_stats);
443
444         mutex_unlock(&rockchip_cpuquiet_lock);
445
446         seq_printf(s, "%-15s ", "cpu:");
447         for (i = 0; i < nr_cpu_ids; i++)
448                 seq_printf(s, "G%-9d ", i);
449
450         seq_printf(s, "%-15s ", "transitions:");
451         for (i = 0; i < nr_cpu_ids; i++)
452                 seq_printf(s, "%-10u ", hp_stats[i].up_down_count);
453         seq_puts(s, "\n");
454
455         seq_printf(s, "%-15s ", "time plugged:");
456         for (i = 0; i < nr_cpu_ids; i++) {
457                 seq_printf(s, "%-10llu ",
458                            cputime64_to_clock_t(hp_stats[i].time_up_total));
459         }
460         seq_puts(s, "\n");
461
462         seq_printf(s, "%-15s %llu\n", "time-stamp:",
463                    cputime64_to_clock_t(cur_jiffies));
464
465         return 0;
466 }
467
468 static int hp_stats_open(struct inode *inode, struct file *file)
469 {
470         return single_open(file, hp_stats_show, inode->i_private);
471 }
472
473 static const struct file_operations hp_stats_fops = {
474         .open           = hp_stats_open,
475         .read           = seq_read,
476         .llseek         = seq_lseek,
477         .release        = single_release,
478 };
479
480 static int __init rockchip_cpuquiet_debug_init(void)
481 {
482         struct dentry *dir;
483
484         dir = debugfs_create_dir("rockchip_cpuquiet", NULL);
485         if (!dir)
486                 return -ENOMEM;
487
488         if (!debugfs_create_file("stats", S_IRUGO, dir, NULL, &hp_stats_fops))
489                 goto err_out;
490
491         return 0;
492
493 err_out:
494         debugfs_remove_recursive(dir);
495         return -ENOMEM;
496 }
497
498 late_initcall(rockchip_cpuquiet_debug_init);
499 #endif /* CONFIG_DEBUG_FS */
500
501 static int __init rockchip_cpuquiet_init(void)
502 {
503         int err;
504
505         init_waitqueue_head(&wait_enable);
506         init_waitqueue_head(&wait_cpu);
507
508         /*
509          * Not bound to the issuer CPU (=> high-priority), has rescue worker
510          * task, single-threaded, freezable.
511          */
512         cpuquiet_wq = alloc_workqueue(
513                 "cpuquiet", WQ_NON_REENTRANT | WQ_FREEZABLE, 1);
514
515         if (!cpuquiet_wq)
516                 return -ENOMEM;
517
518         INIT_WORK(&cpuquiet_work, rockchip_cpuquiet_work_func);
519         hotplug_timeout_jiffies = msecs_to_jiffies(HOTPLUG_DELAY_MS);
520         cpumask_clear(&cpumask_online_requests);
521         cpumask_clear(&cpumask_offline_requests);
522
523         cpq_state = INITIAL_STATE;
524         enable = cpq_state == CPQ_DISABLED ? false : true;
525         hp_init_stats();
526
527         pr_info("cpuquiet initialized: %s\n",
528                 (cpq_state == CPQ_DISABLED) ? "disabled" : "enabled");
529
530         if (pm_qos_add_notifier(PM_QOS_MIN_ONLINE_CPUS, &min_cpus_notifier))
531                 pr_err("Failed to register min cpus PM QoS notifier\n");
532         if (pm_qos_add_notifier(PM_QOS_MAX_ONLINE_CPUS, &max_cpus_notifier))
533                 pr_err("Failed to register max cpus PM QoS notifier\n");
534
535         register_hotcpu_notifier(&cpu_online_notifier);
536
537         err = cpuquiet_register_driver(&rockchip_cpuquiet_driver);
538         if (err) {
539                 destroy_workqueue(cpuquiet_wq);
540                 return err;
541         }
542
543         err = rockchip_cpuquiet_sysfs_init();
544         if (err) {
545                 cpuquiet_unregister_driver(&rockchip_cpuquiet_driver);
546                 destroy_workqueue(cpuquiet_wq);
547         }
548
549         return err;
550 }
551 device_initcall(rockchip_cpuquiet_init);