1 #define pr_fmt(fmt) "ddrfreq: " fmt
4 #include <linux/cpufreq.h>
5 #include <linux/delay.h>
6 #include <linux/earlysuspend.h>
7 #include <linux/freezer.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>
15 #include <mach/board.h>
16 #include <mach/clock.h>
18 #include <mach/dvfs.h>
22 DEBUG_VIDEO_STATE = 1U << 1,
23 DEBUG_SUSPEND = 1U << 2,
24 DEBUG_VERBOSE = 1U << 3,
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)
30 #define MHZ (1000*1000)
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
43 #ifdef CONFIG_HAS_EARLYSUSPEND
44 struct early_suspend early_suspend;
48 unsigned long normal_rate;
49 unsigned long video_rate;
50 unsigned long idle_rate;
51 unsigned long suspend_rate;
53 bool auto_self_refresh;
55 unsigned long sys_status;
56 struct task_struct *task;
57 wait_queue_head_t wait;
59 static struct ddr ddr;
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);
66 static noinline void ddrfreq_set_sys_status(enum SYS_STATUS status)
68 set_bit(status, &ddr.sys_status);
72 static noinline void ddrfreq_clear_sys_status(enum SYS_STATUS status)
74 clear_bit(status, &ddr.sys_status);
78 static void ddrfreq_mode(bool auto_self_refresh, unsigned long *target_rate, char *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);
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);
94 static noinline void ddrfreq_work(unsigned long sys_status)
96 static struct clk *cpu = NULL;
97 static struct clk *gpu = NULL;
98 unsigned long s = sys_status;
101 cpu = clk_get(NULL, "cpu");
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)
117 ddrfreq_mode(false, &ddr.idle_rate, "idle");
119 ddrfreq_mode(false, &ddr.normal_rate, "normal");
123 static int ddrfreq_task(void *data)
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());
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)
143 for (cpu = 0; cpu < NR_CPUS; cpu++)
144 cpu_pause[cpu] = pause;
147 #define MAX_TIMEOUT (16000000UL << 6) //>0.64s
149 /* Do not use stack, safe on SMP */
150 static void __sramfunc pause_cpu(void *info)
152 u32 timeout = MAX_TIMEOUT;
154 unsigned int cpu = raw_smp_processor_id();
156 local_irq_save(flags);
158 set_cpu_pause(cpu, true);
159 while (is_cpu_paused(cpu) && --timeout);
161 local_irq_restore(flags);
164 static void _ddr_change_freq(uint32_t nMHz)
166 u32 timeout = MAX_TIMEOUT;
168 unsigned int this_cpu = get_cpu();
169 cpu_maps_update_begin();
171 BUG_ON(this_cpu != 0);
173 set_other_cpus_pause(false);
175 smp_call_function((smp_call_func_t)pause_cpu, NULL, 0);
176 for_each_online_cpu(cpu) {
179 while (!is_cpu_paused(cpu) && --timeout);
181 pr_err("pause cpu %d timeout\n", cpu);
186 ddr_change_freq(nMHz);
188 set_other_cpus_pause(false);
191 cpu_maps_update_done();
195 static void _ddr_change_freq(uint32_t nMHz)
197 ddr_change_freq(nMHz);
201 static void ddr_set_rate(uint32_t nMHz)
203 _ddr_change_freq(nMHz);
204 clk_set_rate(ddr.pll, 0);
207 #ifdef CONFIG_HAS_EARLYSUSPEND
208 static void ddrfreq_early_suspend(struct early_suspend *h)
210 dprintk(DEBUG_SUSPEND, "early suspend\n");
211 ddrfreq_set_sys_status(SYS_STATUS_SUSPEND);
214 static void ddrfreq_late_resume(struct early_suspend *h)
216 dprintk(DEBUG_SUSPEND, "late resume\n");
217 ddrfreq_clear_sys_status(SYS_STATUS_SUSPEND);
221 static int video_state_release(struct inode *inode, struct file *file)
223 dprintk(DEBUG_VIDEO_STATE, "video_state release\n");
224 ddr.video_state = '0';
225 ddrfreq_clear_sys_status(SYS_STATUS_VIDEO);
229 static ssize_t video_state_write(struct file *file, const char __user *buffer,
230 size_t count, loff_t *ppos)
236 if (copy_from_user(&state, buffer, 1)) {
240 dprintk(DEBUG_VIDEO_STATE, "video_state write %c\n", state);
243 ddrfreq_clear_sys_status(SYS_STATUS_VIDEO);
246 ddrfreq_set_sys_status(SYS_STATUS_VIDEO);
251 ddr.video_state = state;
255 static const struct file_operations video_state_fops = {
256 .owner = THIS_MODULE,
257 .release= video_state_release,
258 .write = video_state_write,
261 static struct miscdevice video_state_dev = {
262 .fops = &video_state_fops,
263 .name = "video_state",
264 .minor = MISC_DYNAMIC_MINOR,
267 static int ddrfreq_clk_event(enum SYS_STATUS status, unsigned long event)
271 ddrfreq_set_sys_status(status);
273 case CLK_ABORT_ENABLE:
274 case CLK_POST_DISABLE:
275 ddrfreq_clear_sys_status(status);
282 #define CLK_NOTIFIER(name, status) \
283 static int ddrfreq_clk_##name##_event(struct notifier_block *this, unsigned long event, void *ptr) \
285 return ddrfreq_clk_event(SYS_STATUS_##status, event); \
287 static struct notifier_block ddrfreq_clk_##name##_notifier = { .notifier_call = ddrfreq_clk_##name##_event };
289 #define REGISTER_CLK_NOTIFIER(name) \
291 struct clk *clk = clk_get(NULL, #name); \
292 clk_notifier_register(clk, &ddrfreq_clk_##name##_notifier); \
296 #define UNREGISTER_CLK_NOTIFIER(name) \
298 struct clk *clk = clk_get(NULL, #name); \
299 clk_notifier_unregister(clk, &ddrfreq_clk_##name##_notifier); \
303 CLK_NOTIFIER(pd_gpu, GPU);
304 CLK_NOTIFIER(pd_rga, RGA);
305 CLK_NOTIFIER(pd_cif0, CIF0);
306 CLK_NOTIFIER(pd_cif1, CIF1);
308 static int ddr_scale_rate_for_dvfs(struct clk *clk, unsigned long rate, dvfs_set_rate_callback set_rate)
310 ddr_set_rate(rate/(1000*1000));
311 /* return 0 when ok */
312 return !(clk_get_rate(clk) == rate);
315 static int ddrfreq_init(void)
318 struct cpufreq_frequency_table *table;
319 bool new_version = false;
321 init_waitqueue_head(&ddr.wait);
322 ddr.video_state = '0';
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);
330 pr_err("failed to get ddr clk, error %d\n", ret);
333 dvfs_clk_register_set_rate_callback(ddr.clk, ddr_scale_rate_for_dvfs);
335 ddr.normal_rate = clk_get_rate(ddr.clk);
337 table = dvfs_get_freq_volt_table(ddr.clk);
339 pr_err("failed to get ddr freq volt table\n");
342 for (i = 0; table && table[i].frequency != CPUFREQ_TABLE_END; i++) {
343 if (table[i].frequency % 1000) {
349 ddr.video_rate = 300 * MHZ;
350 ddr.suspend_rate = 200 * MHZ;
352 for (i = 0; new_version && table && table[i].frequency != CPUFREQ_TABLE_END; i++) {
353 unsigned int mode = table[i].frequency % 1000;
356 table[i].frequency -= mode;
357 rate = table[i].frequency * 1000;
360 case DDR_FREQ_NORMAL:
361 ddr.normal_rate = rate;
364 ddr.video_rate = rate;
367 ddr.idle_rate = rate;
369 case DDR_FREQ_SUSPEND:
370 ddr.suspend_rate = 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);
385 core_initcall(ddrfreq_init);
387 static int ddrfreq_late_init(void)
390 struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
396 ret = misc_register(&video_state_dev);
398 pr_err("failed to register video_state misc device! error %d\n", ret);
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);
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);
416 sched_setscheduler_nocheck(ddr.task, SCHED_FIFO, ¶m);
417 get_task_struct(ddr.task);
418 kthread_bind(ddr.task, 0);
419 wake_up_process(ddr.task);
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);
428 #ifdef CONFIG_HAS_EARLYSUSPEND
429 unregister_early_suspend(&ddr.early_suspend);
431 misc_deregister(&video_state_dev);
434 UNREGISTER_CLK_NOTIFIER(pd_gpu);
435 UNREGISTER_CLK_NOTIFIER(pd_rga);
436 UNREGISTER_CLK_NOTIFIER(pd_cif0);
437 UNREGISTER_CLK_NOTIFIER(pd_cif1);
442 late_initcall(ddrfreq_late_init);