4f919c741525c31ee8468a80e87c36b94d29aeb5
[firefly-linux-kernel-4.4.55.git] / arch / arm / plat-rk / ddr_freq.c
1 #define pr_fmt(fmt) "ddrfreq: " fmt
2 #include <linux/clk.h>
3 #include <linux/cpu.h>
4 #include <linux/cpufreq.h>
5 #include <linux/delay.h>
6 #include <linux/earlysuspend.h>
7 #include <linux/freezer.h>
8 #include <linux/fs.h>
9 #include <linux/kthread.h>
10 #include <linux/miscdevice.h>
11 #include <linux/module.h>
12 #include <linux/slab.h>
13 #include <linux/uaccess.h>
14
15 #include <mach/board.h>
16 #include <mach/clock.h>
17 #include <mach/ddr.h>
18 #include <mach/dvfs.h>
19
20 enum {
21         DEBUG_DDR = 1U << 0,
22         DEBUG_VIDEO_STATE = 1U << 1,
23         DEBUG_SUSPEND = 1U << 2,
24         DEBUG_VERBOSE = 1U << 3,
25 };
26 static int debug_mask = DEBUG_DDR;
27 module_param(debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
28 #define dprintk(mask, fmt, ...) do { if (mask & debug_mask) pr_info(fmt, ##__VA_ARGS__); } while (0)
29
30 #define MHZ     (1000*1000)
31 #define KHZ     1000
32
33 enum SYS_STATUS {
34         SYS_STATUS_SUSPEND = 0, // 0x01
35         SYS_STATUS_VIDEO,       // 0x02
36         SYS_STATUS_GPU,         // 0x04
37         SYS_STATUS_RGA,         // 0x08
38         SYS_STATUS_CIF0,        // 0x10
39         SYS_STATUS_CIF1,        // 0x20
40 };
41
42 struct ddr {
43 #ifdef CONFIG_HAS_EARLYSUSPEND
44         struct early_suspend early_suspend;
45 #endif
46         struct clk *pll;
47         struct clk *clk;
48         unsigned long normal_rate;
49         unsigned long video_rate;
50         unsigned long idle_rate;
51         unsigned long suspend_rate;
52         char video_state;
53         bool auto_self_refresh;
54         char *mode;
55         unsigned long sys_status;
56         struct task_struct *task;
57         wait_queue_head_t wait;
58 };
59 static struct ddr ddr;
60
61 module_param_named(sys_status, ddr.sys_status, ulong, S_IRUGO);
62 module_param_named(video_state, ddr.video_state, byte, S_IRUGO);
63 module_param_named(auto_self_refresh, ddr.auto_self_refresh, bool, S_IRUGO);
64 module_param_named(mode, ddr.mode, charp, S_IRUGO);
65
66 static noinline void ddrfreq_set_sys_status(enum SYS_STATUS status)
67 {
68         set_bit(status, &ddr.sys_status);
69         wake_up(&ddr.wait);
70 }
71
72 static noinline void ddrfreq_clear_sys_status(enum SYS_STATUS status)
73 {
74         clear_bit(status, &ddr.sys_status);
75         wake_up(&ddr.wait);
76 }
77
78 static void ddrfreq_mode(bool auto_self_refresh, unsigned long *target_rate, char *name)
79 {
80         ddr.mode = name;
81         if (auto_self_refresh != ddr.auto_self_refresh) {
82                 ddr_set_auto_self_refresh(auto_self_refresh);
83                 ddr.auto_self_refresh = auto_self_refresh;
84                 dprintk(DEBUG_DDR, "change auto self refresh to %d when %s\n", auto_self_refresh, name);
85         }
86         if (*target_rate != clk_get_rate(ddr.clk)) {
87                 if (clk_set_rate(ddr.clk, *target_rate) == 0) {
88                         *target_rate = clk_get_rate(ddr.clk);
89                         dprintk(DEBUG_DDR, "change freq to %lu MHz when %s\n", *target_rate / MHZ, name);
90                 }
91         }
92 }
93
94 static noinline void ddrfreq_work(unsigned long sys_status)
95 {
96         static struct clk *cpu = NULL;
97         static struct clk *gpu = NULL;
98         unsigned long s = sys_status;
99
100         if (!cpu)
101                 cpu = clk_get(NULL, "cpu");
102         if (!gpu)
103                 gpu = clk_get(NULL, "gpu");
104         dprintk(DEBUG_VERBOSE, "sys_status %02lx\n", sys_status);
105         if (ddr.suspend_rate && (s & (1 << SYS_STATUS_SUSPEND))) {
106                 ddrfreq_mode(true, &ddr.suspend_rate, "suspend");
107         } else if (ddr.video_rate && (s & (1 << SYS_STATUS_VIDEO))) {
108                 ddrfreq_mode(false, &ddr.video_rate, "video");
109         } else if (ddr.idle_rate
110                 && !(s & (1 << SYS_STATUS_GPU))
111                 && !(s & (1 << SYS_STATUS_RGA))
112                 && !(s & (1 << SYS_STATUS_CIF0))
113                 && !(s & (1 << SYS_STATUS_CIF1))
114                 && (clk_get_rate(cpu) < 816 * MHZ)
115                 && (clk_get_rate(gpu) <= 200 * MHZ)
116                 ) {
117                 ddrfreq_mode(false, &ddr.idle_rate, "idle");
118         } else {
119                 ddrfreq_mode(false, &ddr.normal_rate, "normal");
120         }
121 }
122
123 static int ddrfreq_task(void *data)
124 {
125         set_freezable();
126
127         do {
128                 unsigned long status = ddr.sys_status;
129                 ddrfreq_work(status);
130                 wait_event_freezable(ddr.wait, (status != ddr.sys_status) || kthread_should_stop());
131         } while (!kthread_should_stop());
132
133         return 0;
134 }
135
136 #ifdef CONFIG_SMP
137 static volatile bool __sramdata cpu_pause[NR_CPUS];
138 static inline bool is_cpu_paused(unsigned int cpu) { smp_rmb(); return cpu_pause[cpu]; }
139 static inline void set_cpu_pause(unsigned int cpu, bool pause) { cpu_pause[cpu] = pause; smp_wmb(); }
140 static inline void set_other_cpus_pause(bool pause)
141 {
142         unsigned int cpu;
143         for (cpu = 0; cpu < NR_CPUS; cpu++)
144                 cpu_pause[cpu] = pause;
145         smp_wmb();
146 }
147 #define MAX_TIMEOUT (16000000UL << 6) //>0.64s
148
149 /* Do not use stack, safe on SMP */
150 static void __sramfunc pause_cpu(void *info)
151 {
152         u32 timeout = MAX_TIMEOUT;
153         unsigned long flags;
154         unsigned int cpu = raw_smp_processor_id();
155
156         local_irq_save(flags);
157
158         set_cpu_pause(cpu, true);
159         while (is_cpu_paused(cpu) && --timeout);
160
161         local_irq_restore(flags);
162 }
163
164 static void _ddr_change_freq(uint32_t nMHz)
165 {
166         u32 timeout = MAX_TIMEOUT;
167         unsigned int cpu;
168         unsigned int this_cpu = get_cpu();
169         cpu_maps_update_begin();
170
171         BUG_ON(this_cpu != 0);
172
173         set_other_cpus_pause(false);
174
175         smp_call_function((smp_call_func_t)pause_cpu, NULL, 0);
176         for_each_online_cpu(cpu) {
177                 if (cpu == this_cpu)
178                         continue;
179                 while (!is_cpu_paused(cpu) && --timeout);
180                 if (timeout == 0) {
181                         pr_err("pause cpu %d timeout\n", cpu);
182                         goto out;
183                 }
184         }
185
186         ddr_change_freq(nMHz);
187
188         set_other_cpus_pause(false);
189
190 out:
191         cpu_maps_update_done();
192         put_cpu();
193 }
194 #else
195 static void _ddr_change_freq(uint32_t nMHz)
196 {
197         ddr_change_freq(nMHz);
198 }
199 #endif
200
201 static void ddr_set_rate(uint32_t nMHz)
202 {
203         _ddr_change_freq(nMHz);
204         clk_set_rate(ddr.pll, 0);
205 }
206
207 #ifdef CONFIG_HAS_EARLYSUSPEND
208 static void ddrfreq_early_suspend(struct early_suspend *h)
209 {
210         dprintk(DEBUG_SUSPEND, "early suspend\n");
211         ddrfreq_set_sys_status(SYS_STATUS_SUSPEND);
212 }
213
214 static void ddrfreq_late_resume(struct early_suspend *h)
215 {
216         dprintk(DEBUG_SUSPEND, "late resume\n");
217         ddrfreq_clear_sys_status(SYS_STATUS_SUSPEND);
218 }
219 #endif
220
221 static int video_state_release(struct inode *inode, struct file *file)
222 {
223         dprintk(DEBUG_VIDEO_STATE, "video_state release\n");
224         ddr.video_state = '0';
225         ddrfreq_clear_sys_status(SYS_STATUS_VIDEO);
226         return 0;
227 }
228
229 static ssize_t video_state_write(struct file *file, const char __user *buffer,
230                                  size_t count, loff_t *ppos)
231 {
232         char state;
233
234         if (count < 1)
235                 return count;
236         if (copy_from_user(&state, buffer, 1)) {
237                 return -EFAULT;
238         }
239
240         dprintk(DEBUG_VIDEO_STATE, "video_state write %c\n", state);
241         switch (state) {
242         case '0':
243                 ddrfreq_clear_sys_status(SYS_STATUS_VIDEO);
244                 break;
245         case '1':
246                 ddrfreq_set_sys_status(SYS_STATUS_VIDEO);
247                 break;
248         default:
249                 return -EINVAL;
250         }
251         ddr.video_state = state;
252         return count;
253 }
254
255 static const struct file_operations video_state_fops = {
256         .owner  = THIS_MODULE,
257         .release= video_state_release,
258         .write  = video_state_write,
259 };
260
261 static struct miscdevice video_state_dev = {
262         .fops   = &video_state_fops,
263         .name   = "video_state",
264         .minor  = MISC_DYNAMIC_MINOR,
265 };
266
267 static int ddrfreq_clk_event(enum SYS_STATUS status, unsigned long event)
268 {
269         switch (event) {
270         case CLK_PRE_ENABLE:
271                 ddrfreq_set_sys_status(status);
272                 break;
273         case CLK_ABORT_ENABLE:
274         case CLK_POST_DISABLE:
275                 ddrfreq_clear_sys_status(status);
276                 break;
277         }
278
279         return NOTIFY_OK;
280 }
281
282 #define CLK_NOTIFIER(name, status) \
283 static int ddrfreq_clk_##name##_event(struct notifier_block *this, unsigned long event, void *ptr) \
284 { \
285         return ddrfreq_clk_event(SYS_STATUS_##status, event); \
286 } \
287 static struct notifier_block ddrfreq_clk_##name##_notifier = { .notifier_call = ddrfreq_clk_##name##_event };
288
289 #define REGISTER_CLK_NOTIFIER(name) \
290 do { \
291         struct clk *clk = clk_get(NULL, #name); \
292         clk_notifier_register(clk, &ddrfreq_clk_##name##_notifier); \
293         clk_put(clk); \
294 } while (0)
295
296 #define UNREGISTER_CLK_NOTIFIER(name) \
297 do { \
298         struct clk *clk = clk_get(NULL, #name); \
299         clk_notifier_unregister(clk, &ddrfreq_clk_##name##_notifier); \
300         clk_put(clk); \
301 } while (0)
302
303 CLK_NOTIFIER(pd_gpu, GPU);
304 CLK_NOTIFIER(pd_rga, RGA);
305 CLK_NOTIFIER(pd_cif0, CIF0);
306 CLK_NOTIFIER(pd_cif1, CIF1);
307
308 static int ddr_scale_rate_for_dvfs(struct clk *clk, unsigned long rate, dvfs_set_rate_callback set_rate)
309 {
310         ddr_set_rate(rate/(1000*1000));
311         /* return 0 when ok */
312         return !(clk_get_rate(clk) == rate);
313 }
314
315 static int ddrfreq_init(void)
316 {
317         int i, ret;
318         struct cpufreq_frequency_table *table;
319         bool new_version = false;
320
321         init_waitqueue_head(&ddr.wait);
322         ddr.video_state = '0';
323         ddr.mode = "normal";
324
325         ddr.pll = clk_get(NULL, "ddr_pll");
326         ddr.clk = clk_get(NULL, "ddr");
327         if (IS_ERR(ddr.clk)) {
328                 ret = PTR_ERR(ddr.clk);
329                 ddr.clk = NULL;
330                 pr_err("failed to get ddr clk, error %d\n", ret);
331                 return ret;
332         }
333     dvfs_clk_register_set_rate_callback(ddr.clk, ddr_scale_rate_for_dvfs);
334
335         ddr.normal_rate = clk_get_rate(ddr.clk);
336
337         table = dvfs_get_freq_volt_table(ddr.clk);
338         if (!table) {
339                 pr_err("failed to get ddr freq volt table\n");
340         }
341
342         for (i = 0; table && table[i].frequency != CPUFREQ_TABLE_END; i++) {
343                 if (table[i].frequency % 1000) {
344                         new_version = true;
345                         break;
346                 }
347         }
348         if (!new_version) {
349                 ddr.video_rate = 300 * MHZ;
350                 ddr.suspend_rate = 200 * MHZ;
351         }
352         for (i = 0; new_version && table && table[i].frequency != CPUFREQ_TABLE_END; i++) {
353                 unsigned int mode = table[i].frequency % 1000;
354                 unsigned long rate;
355
356                 table[i].frequency -= mode;
357                 rate = table[i].frequency * 1000;
358
359                 switch (mode) {
360                 case DDR_FREQ_NORMAL:
361                         ddr.normal_rate = rate;
362                         break;
363                 case DDR_FREQ_VIDEO:
364                         ddr.video_rate = rate;
365                         break;
366                 case DDR_FREQ_IDLE:
367                         ddr.idle_rate = rate;
368                         break;
369                 case DDR_FREQ_SUSPEND:
370                         ddr.suspend_rate = rate;
371                         break;
372                 }
373         }
374
375         if (ddr.idle_rate) {
376                 REGISTER_CLK_NOTIFIER(pd_gpu);
377                 REGISTER_CLK_NOTIFIER(pd_rga);
378                 REGISTER_CLK_NOTIFIER(pd_cif0);
379                 REGISTER_CLK_NOTIFIER(pd_cif1);
380         }
381
382         return 0;
383
384 }
385 core_initcall(ddrfreq_init);
386
387 static int ddrfreq_late_init(void)
388 {
389         int ret;
390         struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
391
392         if (!ddr.clk) {
393                 return -EINVAL;
394         }
395
396         ret = misc_register(&video_state_dev);
397         if (unlikely(ret)) {
398                 pr_err("failed to register video_state misc device! error %d\n", ret);
399                 goto err;
400         }
401
402 #ifdef CONFIG_HAS_EARLYSUSPEND
403         ddr.early_suspend.suspend = ddrfreq_early_suspend;
404         ddr.early_suspend.resume = ddrfreq_late_resume;
405         ddr.early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 50;
406         register_early_suspend(&ddr.early_suspend);
407 #endif
408
409         ddr.task = kthread_create(ddrfreq_task, NULL, "ddrfreqd");
410         if (IS_ERR(ddr.task)) {
411                 ret = PTR_ERR(ddr.task);
412                 pr_err("failed to create kthread! error %d\n", ret);
413                 goto err1;
414         }
415
416         sched_setscheduler_nocheck(ddr.task, SCHED_FIFO, &param);
417         get_task_struct(ddr.task);
418         kthread_bind(ddr.task, 0);
419         wake_up_process(ddr.task);
420
421         pr_info("verion 2.0\n");
422         dprintk(DEBUG_DDR, "normal %luMHz video %luMHz idle %luMHz suspend %luMHz\n",
423                 ddr.normal_rate / MHZ, ddr.video_rate / MHZ, ddr.idle_rate / MHZ, ddr.suspend_rate / MHZ);
424
425         return 0;
426
427 err1:
428 #ifdef CONFIG_HAS_EARLYSUSPEND
429         unregister_early_suspend(&ddr.early_suspend);
430 #endif
431         misc_deregister(&video_state_dev);
432 err:
433         if (ddr.idle_rate) {
434                 UNREGISTER_CLK_NOTIFIER(pd_gpu);
435                 UNREGISTER_CLK_NOTIFIER(pd_rga);
436                 UNREGISTER_CLK_NOTIFIER(pd_cif0);
437                 UNREGISTER_CLK_NOTIFIER(pd_cif1);
438         }
439
440         return ret;
441 }
442 late_initcall(ddrfreq_late_init);