1 #define pr_fmt(fmt) "ddrfreq: " fmt
6 #include <linux/cpufreq.h>
7 #include <linux/delay.h>
8 #include <linux/freezer.h>
10 #include <linux/kthread.h>
11 #include <linux/miscdevice.h>
12 #include <linux/module.h>
13 #include <linux/reboot.h>
14 #include <linux/slab.h>
15 #include <linux/uaccess.h>
16 #include <linux/sched/rt.h>
19 #include <linux/input.h>
20 #include <asm/cacheflush.h>
21 #include <asm/tlbflush.h>
22 #include <linux/vmalloc.h>
23 #include <linux/rockchip/common.h>
24 #include <linux/rockchip/cpu_axi.h>
25 #include <linux/rockchip/dvfs.h>
26 #include <dt-bindings/clock/ddr.h>
27 #include <dt-bindings/clock/rk_system_status.h>
29 #include <linux/rockchip/grf.h>
30 #include <linux/rockchip/iomap.h>
31 #include <linux/clk-private.h>
32 #include <linux/rockchip/cpu.h>
33 #include "../../../drivers/clk/rockchip/clk-pd.h"
35 static DECLARE_COMPLETION(ddrfreq_completion);
36 static DEFINE_MUTEX(ddrfreq_mutex);
40 static DECLARE_COMPLETION(vop_req_completion);
43 static struct dvfs_node *clk_cpu_dvfs_node = NULL;
44 static int ddr_boost = 0;
47 static int high_load = 70;
48 static int low_load = 60;
49 static int auto_freq_interval_ms = 20;
50 static int down_rate_delay_ms = 500;
51 static unsigned long *auto_freq_table = NULL;
52 static int cur_freq_index;
53 static int auto_freq_table_size;
54 static unsigned long vop_bandwidth_update_jiffies = 0, vop_bandwidth = 0;
55 static int vop_bandwidth_update_flag = 0;
56 static struct ddr_bw_info ddr_bw_ch0 = {0}, ddr_bw_ch1 = {0};
57 static struct cpufreq_frequency_table *bd_freq_table;
61 DEBUG_VIDEO_STATE = 1U << 1,
62 DEBUG_SUSPEND = 1U << 2,
63 DEBUG_VERBOSE = 1U << 3,
65 static int debug_mask;
67 module_param(debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
68 #define dprintk(mask, fmt, ...) do { if (mask & debug_mask) pr_debug(fmt, ##__VA_ARGS__); } while (0)
70 #define MHZ (1000*1000)
80 struct list_head node;
90 struct vop_info vopinfo[4];
96 struct dvfs_node *clk_dvfs_node;
97 struct list_head video_info_list;
98 unsigned long normal_rate;
99 unsigned long video_1080p_rate;
100 unsigned long video_4k_rate;
101 unsigned long performance_rate;
102 unsigned long dualview_rate;
103 unsigned long hdmi_rate;
104 unsigned long idle_rate;
105 unsigned long suspend_rate;
106 unsigned long reboot_rate;
107 unsigned long boost_rate;
108 unsigned long isp_rate;
110 bool auto_self_refresh;
112 unsigned long sys_status;
113 struct task_struct *task;
114 wait_queue_head_t wait;
116 static struct ddr ddr;
118 module_param_named(sys_status, ddr.sys_status, ulong, S_IRUGO);
119 module_param_named(auto_self_refresh, ddr.auto_self_refresh, bool, S_IRUGO);
120 module_param_named(mode, ddr.mode, charp, S_IRUGO);
122 static unsigned long auto_freq_round(unsigned long freq)
126 if (!auto_freq_table)
129 for (i = 0; auto_freq_table[i] != 0; i++) {
130 if (auto_freq_table[i] >= freq) {
131 return auto_freq_table[i];
135 return auto_freq_table[i-1];
138 static unsigned long auto_freq_get_index(unsigned long freq)
142 if (!auto_freq_table)
145 for (i = 0; auto_freq_table[i] != 0; i++) {
146 if (auto_freq_table[i] >= freq) {
153 static unsigned int auto_freq_update_index(unsigned long freq)
155 cur_freq_index = auto_freq_get_index(freq);
157 return cur_freq_index;
161 static unsigned long auto_freq_get_next_step(void)
163 if (cur_freq_index < auto_freq_table_size-1) {
164 return auto_freq_table[cur_freq_index+1];
167 return auto_freq_table[cur_freq_index];
170 static void ddrfreq_mode(bool auto_self_refresh, unsigned long target_rate, char *name)
172 unsigned int min_rate, max_rate;
176 if (auto_self_refresh != ddr.auto_self_refresh) {
177 ddr_set_auto_self_refresh(auto_self_refresh);
178 ddr.auto_self_refresh = auto_self_refresh;
179 dprintk(DEBUG_DDR, "change auto self refresh to %d when %s\n", auto_self_refresh, name);
182 if (target_rate != dvfs_clk_get_last_set_rate(ddr.clk_dvfs_node)) {
183 if (clk_cpu_dvfs_node) {
184 freq_limit_en = dvfs_clk_get_limit(clk_cpu_dvfs_node,
188 dvfs_clk_enable_limit(clk_cpu_dvfs_node, 600000000, -1);
190 if (dvfs_clk_set_rate(ddr.clk_dvfs_node, target_rate) == 0) {
191 target_rate = dvfs_clk_get_rate(ddr.clk_dvfs_node);
192 auto_freq_update_index(target_rate);
193 dprintk(DEBUG_DDR, "change freq to %lu MHz when %s\n", target_rate / MHZ, name);
195 if (clk_cpu_dvfs_node) {
197 dvfs_clk_enable_limit(clk_cpu_dvfs_node,
200 dvfs_clk_disable_limit(clk_cpu_dvfs_node);
206 unsigned long req_freq_by_vop(unsigned long bandwidth)
210 if (time_after(jiffies, vop_bandwidth_update_jiffies +
211 msecs_to_jiffies(down_rate_delay_ms)))
214 if (bd_freq_table == NULL)
216 for (i = 0; bd_freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
217 if (bandwidth >= bd_freq_table[i].index)
218 return bd_freq_table[i].frequency * 1000;
224 static void ddr_auto_freq(void)
226 unsigned long freq, new_freq=0, vop_req_freq=0, total_bw_req_freq=0;
227 u32 ddr_percent, target_load;
228 static unsigned long local_jiffies=0, max_ddr_percent=0;
231 local_jiffies = jiffies;
232 freq = dvfs_clk_get_rate(ddr.clk_dvfs_node);
234 ddr_bandwidth_get(&ddr_bw_ch0, &ddr_bw_ch1);
235 ddr_percent = ddr_bw_ch0.ddr_percent;
237 if ((watch)||(print)) {
238 if((watch == 2)&& (ddr_bw_ch0.ddr_percent < max_ddr_percent)) {
240 } else if(watch == 2) {
241 max_ddr_percent = ddr_bw_ch0.ddr_percent;
243 printk("Unit:MB/s total use%% rd wr cpum gpu peri video vio0 vio1 vio2\n");
244 printk("%3u(ms): %5u %5u %5u %5u %5u %5u %5u %5u %5u %5u %5u\n",
246 ddr_bw_ch0.ddr_total,
247 ddr_bw_ch0.ddr_percent,
264 new_freq = max(ddr.boost_rate, new_freq);
267 if(ddr_percent > high_load){
268 total_bw_req_freq = auto_freq_get_next_step();
269 } else if (ddr_percent < low_load){
270 target_load = (low_load+high_load)/2;
271 total_bw_req_freq = ddr_percent*(freq/target_load);
273 new_freq = max(total_bw_req_freq, new_freq);
275 vop_req_freq = req_freq_by_vop(vop_bandwidth);
276 new_freq = max(vop_req_freq, new_freq);
280 new_freq = auto_freq_round(new_freq);
282 if (new_freq < freq) {
283 if (time_after(jiffies, local_jiffies+down_rate_delay_ms/10)) {
284 local_jiffies = jiffies;
285 ddrfreq_mode(false, new_freq, "auto down rate");
287 } else if(new_freq > freq){
288 local_jiffies = jiffies;
289 ddrfreq_mode(false, new_freq, "auto up rate");
293 static noinline long ddrfreq_work(unsigned long sys_status)
295 long timeout = MAX_SCHEDULE_TIMEOUT;
296 unsigned long target_rate = 0;
297 unsigned long s = sys_status;
298 bool auto_self_refresh = false;
301 dprintk(DEBUG_VERBOSE, "sys_status %02lx\n", sys_status);
303 if (ddr.reboot_rate && (s & SYS_STATUS_REBOOT)) {
304 ddrfreq_mode(false, ddr.reboot_rate, "shutdown/reboot");
309 if (ddr.suspend_rate && (s & SYS_STATUS_SUSPEND)) {
310 if (ddr.suspend_rate > target_rate) {
311 target_rate = ddr.suspend_rate;
312 auto_self_refresh = true;
317 if (ddr.performance_rate && (s & SYS_STATUS_PERFORMANCE)) {
318 if (ddr.performance_rate > target_rate) {
319 target_rate = ddr.performance_rate;
320 auto_self_refresh = false;
321 mode = "performance";
325 if (ddr.dualview_rate &&
326 (s & SYS_STATUS_LCDC0) && (s & SYS_STATUS_LCDC1)) {
327 if (ddr.dualview_rate > target_rate) {
328 target_rate = ddr.dualview_rate;
329 auto_self_refresh = false;
335 (s & SYS_STATUS_HDMI)) {
336 if (ddr.hdmi_rate > target_rate) {
337 target_rate = ddr.hdmi_rate;
338 auto_self_refresh = false;
343 if (ddr.video_4k_rate && (s & SYS_STATUS_VIDEO_4K) && !(s & SYS_STATUS_SUSPEND)) {
344 if (ddr.video_4k_rate > target_rate) {
345 target_rate = ddr.video_4k_rate;
346 auto_self_refresh = false;
351 if (ddr.video_1080p_rate && (s & SYS_STATUS_VIDEO_1080P)) {
352 if (ddr.video_1080p_rate > target_rate) {
353 target_rate = ddr.video_1080p_rate;
354 auto_self_refresh = false;
355 mode = "video_1080p";
359 if (ddr.isp_rate && (s & SYS_STATUS_ISP)) {
360 if (ddr.isp_rate > target_rate) {
361 target_rate = ddr.isp_rate;
362 auto_self_refresh = false;
367 if (target_rate > 0) {
368 ddrfreq_mode(auto_self_refresh, target_rate, mode);
372 timeout = auto_freq_interval_ms/10;
375 ddrfreq_mode(false, ddr.normal_rate, "normal");
382 if (ddr.reboot_rate && (s & SYS_STATUS_REBOOT)) {
383 ddrfreq_mode(false, &ddr.reboot_rate, "shutdown/reboot");
384 rockchip_cpufreq_reboot_limit_freq();
385 reboot_config_done = 1;
386 } else if (ddr.suspend_rate && (s & SYS_STATUS_SUSPEND)) {
387 ddrfreq_mode(true, &ddr.suspend_rate, "suspend");
388 } else if (ddr.dualview_rate &&
389 (s & SYS_STATUS_LCDC0) && (s & SYS_STATUS_LCDC1)) {
390 ddrfreq_mode(false, &ddr.dualview_rate, "dual-view");
391 } else if (ddr.video_1080p_rate && (s & SYS_STATUS_VIDEO_1080P)) {
392 ddrfreq_mode(false, &ddr.video_1080p_rate, "video_1080p");
393 } else if (ddr.video_4k_rate && (s & SYS_STATUS_VIDEO_4K)) {
394 ddrfreq_mode(false, &ddr.video_4k_rate, "video_4k");
395 } else if (ddr.performance_rate && (s & SYS_STATUS_PERFORMANCE)) {
396 ddrfreq_mode(false, &ddr.performance_rate, "performance");
397 } else if (ddr.isp_rate && (s & SYS_STATUS_ISP)) {
398 ddrfreq_mode(false, &ddr.isp_rate, "isp");
399 } else if (ddr.idle_rate
400 && !(s & SYS_STATUS_GPU)
401 && !(s & SYS_STATUS_RGA)
402 && !(s & SYS_STATUS_CIF0)
403 && !(s & SYS_STATUS_CIF1)
404 && (clk_get_rate(cpu) < 816 * MHZ)
405 && (clk_get_rate(gpu) <= 200 * MHZ)
407 ddrfreq_mode(false, &ddr.idle_rate, "idle");
411 timeout = auto_freq_interval_ms;
414 ddrfreq_mode(false, &ddr.normal_rate, "normal");
424 static int ddrfreq_task(void *data)
427 unsigned long status=ddr.sys_status, old_status=ddr.sys_status;
432 status = ddr.sys_status;
433 timeout = ddrfreq_work(status);
434 if (old_status != status)
435 complete(&ddrfreq_completion);
436 if (vop_bandwidth_update_flag) {
437 vop_bandwidth_update_flag = 0;
439 complete(&vop_req_completion);
442 wait_event_freezable_timeout(ddr.wait, vop_bandwidth_update_flag || (status != ddr.sys_status) || kthread_should_stop(), timeout);
444 } while (!kthread_should_stop());
449 void add_video_info(struct video_info *video_info)
452 list_add(&video_info->node, &ddr.video_info_list);
455 void del_video_info(struct video_info *video_info)
458 list_del(&video_info->node);
463 void clear_video_info(void)
465 struct video_info *video_info, *next;
467 list_for_each_entry_safe(video_info, next, &ddr.video_info_list, node) {
468 del_video_info(video_info);
472 struct video_info *find_video_info(struct video_info *match_video_info)
474 struct video_info *video_info;
476 if (!match_video_info)
479 list_for_each_entry(video_info, &ddr.video_info_list, node) {
480 if ((video_info->width == match_video_info->width)
481 && (video_info->height == match_video_info->height)
482 && (video_info->ishevc== match_video_info->ishevc)
483 && (video_info->videoFramerate == match_video_info->videoFramerate)
484 && (video_info->streamBitrate== match_video_info->streamBitrate)) {
494 void update_video_info(void)
496 struct video_info *video_info, *max_res_video;
497 int max_res=0, res=0;
499 if (list_empty(&ddr.video_info_list)) {
500 rockchip_clear_system_status(SYS_STATUS_VIDEO_1080P|SYS_STATUS_VIDEO_4K);
504 list_for_each_entry(video_info, &ddr.video_info_list, node) {
505 res = video_info->width * video_info->height;
508 max_res_video = video_info;
512 if (max_res <= 1920*1080)
513 rockchip_set_system_status(SYS_STATUS_VIDEO_1080P);
515 rockchip_set_system_status(SYS_STATUS_VIDEO_4K);
520 /***format: width=val,height=val,ishevc=val,videoFramerate=val,streamBitrate=val***/
521 static long get_video_param(char **str)
528 return simple_strtol(p,NULL,10);
533 static ssize_t video_state_write(struct file *file, const char __user *buffer,
534 size_t count, loff_t *ppos)
536 struct video_info *video_info = NULL;
537 char state, *cookie_pot, *buf = vzalloc(count);
548 if (copy_from_user(cookie_pot, buffer, count)) {
553 dprintk(DEBUG_VIDEO_STATE, "%s: %s,len %zu\n", __func__, cookie_pot,count);
556 if( (count>=3) && (cookie_pot[2]=='w') )
558 video_info = kzalloc(sizeof(struct video_info), GFP_KERNEL);
563 INIT_LIST_HEAD(&video_info->node);
565 strsep(&cookie_pot,",");
567 video_info->width = get_video_param(&cookie_pot);
568 video_info->height = get_video_param(&cookie_pot);
569 video_info->ishevc = get_video_param(&cookie_pot);
570 video_info->videoFramerate = get_video_param(&cookie_pot);
571 video_info->streamBitrate = get_video_param(&cookie_pot);
573 dprintk(DEBUG_VIDEO_STATE, "%s: video_state=%c,width=%d,height=%d,ishevc=%d,videoFramerate=%d,streamBitrate=%d\n",
574 __func__, state,video_info->width,video_info->height,
575 video_info->ishevc, video_info->videoFramerate,
576 video_info->streamBitrate);
581 del_video_info(find_video_info(video_info));
586 add_video_info(video_info);
589 case 'p'://performance
590 rockchip_set_system_status(SYS_STATUS_PERFORMANCE);
593 rockchip_clear_system_status(SYS_STATUS_PERFORMANCE);
605 static int video_state_release(struct inode *inode, struct file *file)
607 dprintk(DEBUG_VIDEO_STATE, "video_state release\n");
614 static const struct file_operations video_state_fops = {
615 .owner = THIS_MODULE,
616 .release= video_state_release,
617 .write = video_state_write,
620 static struct miscdevice video_state_dev = {
621 .fops = &video_state_fops,
622 .name = "video_state",
623 .minor = MISC_DYNAMIC_MINOR,
626 static long ddr_freq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
628 struct bpvopinfo *bpvinfo = (struct bpvopinfo *)arg;
629 unsigned long vop_req_freq;
632 vop_bandwidth = bpvinfo->bp_vop_size;
633 vop_bandwidth_update_jiffies = jiffies;
634 vop_req_freq = req_freq_by_vop(vop_bandwidth);
635 if (dvfs_clk_get_rate(ddr.clk_dvfs_node) >= vop_req_freq)
638 vop_bandwidth_update_flag = 1;
641 wait_for_completion(&vop_req_completion);
642 if (dvfs_clk_get_rate(ddr.clk_dvfs_node) >= vop_req_freq)
650 static const struct file_operations ddr_freq_fops = {
651 .owner = THIS_MODULE,
652 .unlocked_ioctl = ddr_freq_ioctl,
654 .compat_ioctl = ddr_freq_ioctl,
658 static struct miscdevice ddr_freq_dev = {
659 .fops = &ddr_freq_fops,
661 .mode = S_IRUGO | S_IWUSR | S_IWUGO,
662 .minor = MISC_DYNAMIC_MINOR,
666 static void ddr_freq_input_event(struct input_handle *handle, unsigned int type,
667 unsigned int code, int value)
673 static int ddr_freq_input_connect(struct input_handler *handler,
674 struct input_dev *dev, const struct input_device_id *id)
676 struct input_handle *handle;
679 handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
684 handle->handler = handler;
685 handle->name = "ddr_freq";
687 error = input_register_handle(handle);
691 error = input_open_device(handle);
697 input_unregister_handle(handle);
703 static void ddr_freq_input_disconnect(struct input_handle *handle)
705 input_close_device(handle);
706 input_unregister_handle(handle);
710 static const struct input_device_id ddr_freq_ids[] = {
712 .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
713 INPUT_DEVICE_ID_MATCH_ABSBIT,
714 .evbit = { BIT_MASK(EV_ABS) },
715 .absbit = { [BIT_WORD(ABS_MT_POSITION_X)] =
716 BIT_MASK(ABS_MT_POSITION_X) |
717 BIT_MASK(ABS_MT_POSITION_Y) },
720 .flags = INPUT_DEVICE_ID_MATCH_KEYBIT |
721 INPUT_DEVICE_ID_MATCH_ABSBIT,
722 .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
723 .absbit = { [BIT_WORD(ABS_X)] =
724 BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
727 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
728 .evbit = { BIT_MASK(EV_KEY) },
733 static struct input_handler ddr_freq_input_handler = {
734 .event = ddr_freq_input_event,
735 .connect = ddr_freq_input_connect,
736 .disconnect = ddr_freq_input_disconnect,
738 .id_table = ddr_freq_ids,
742 static int ddrfreq_clk_event(int status, unsigned long event)
745 case RK_CLK_PD_PREPARE:
746 ddrfreq_set_sys_status(status);
748 case RK_CLK_PD_UNPREPARE:
749 ddrfreq_clear_sys_status(status);
755 #define CLK_NOTIFIER(name, status) \
756 static int ddrfreq_clk_##name##_event(struct notifier_block *this, unsigned long event, void *ptr) \
758 return ddrfreq_clk_event(SYS_STATUS_##status, event); \
760 static struct notifier_block ddrfreq_clk_##name##_notifier = { .notifier_call = ddrfreq_clk_##name##_event };
762 #define REGISTER_CLK_NOTIFIER(name) \
764 struct clk *clk = clk_get(NULL, #name); \
765 rk_clk_pd_notifier_register(clk, &ddrfreq_clk_##name##_notifier); \
769 #define UNREGISTER_CLK_NOTIFIER(name) \
771 struct clk *clk = clk_get(NULL, #name); \
772 rk_clk_pd_notifier_unregister(clk, &ddrfreq_clk_##name##_notifier); \
776 CLK_NOTIFIER(pd_isp, ISP)
777 CLK_NOTIFIER(pd_vop0, LCDC0)
778 CLK_NOTIFIER(pd_vop1, LCDC1)
781 static int ddr_freq_suspend_notifier_call(struct notifier_block *self,
782 unsigned long action, void *data)
784 struct fb_event *event = data;
785 int blank_mode = *((int *)event->data);
787 if (action == FB_EARLY_EVENT_BLANK) {
788 switch (blank_mode) {
789 case FB_BLANK_UNBLANK:
790 rockchip_clear_system_status(SYS_STATUS_SUSPEND);
796 else if (action == FB_EVENT_BLANK) {
797 switch (blank_mode) {
798 case FB_BLANK_POWERDOWN:
799 rockchip_set_system_status(SYS_STATUS_SUSPEND);
809 static struct notifier_block ddr_freq_suspend_notifier = {
810 .notifier_call = ddr_freq_suspend_notifier_call,
813 static int ddrfreq_system_status_notifier_call(struct notifier_block *nb,
814 unsigned long val, void *data)
816 mutex_lock(&ddrfreq_mutex);
817 ddr.sys_status = val;
819 wait_for_completion(&ddrfreq_completion);
820 mutex_unlock(&ddrfreq_mutex);
825 static struct notifier_block ddrfreq_system_status_notifier = {
826 .notifier_call = ddrfreq_system_status_notifier_call,
829 static struct cpufreq_frequency_table
830 *of_get_bd_freq_table(struct device_node *np, const char *propname)
832 struct cpufreq_frequency_table *freq_table = NULL;
833 const struct property *prop;
837 prop = of_find_property(np, propname, NULL);
843 nr = prop->length / sizeof(u32);
845 pr_err("%s: Invalid freq list\n", __func__);
849 freq_table = kzalloc(sizeof(*freq_table) * (nr/2 + 1), GFP_KERNEL);
853 for (i = 0; i < nr/2; i++) {
854 freq_table[i].index = be32_to_cpup(val++);
855 freq_table[i].frequency = be32_to_cpup(val++);
858 freq_table[i].index = 0;
859 freq_table[i].frequency = CPUFREQ_TABLE_END;
864 int of_init_ddr_freq_table(void)
866 struct device_node *clk_ddr_dev_node;
867 const struct property *prop;
871 clk_ddr_dev_node = of_find_node_by_name(NULL, "clk_ddr");
872 if (IS_ERR_OR_NULL(clk_ddr_dev_node)) {
873 pr_err("%s: get clk ddr dev node err\n", __func__);
874 return PTR_ERR(clk_ddr_dev_node);
877 prop = of_find_property(clk_ddr_dev_node, "auto-freq", NULL);
878 if (prop && prop->value)
879 ddr.auto_freq = be32_to_cpup(prop->value);
881 prop = of_find_property(clk_ddr_dev_node, "auto-freq-table", NULL);
882 if (prop && prop->value) {
883 nr = prop->length / sizeof(u32);
884 auto_freq_table = kzalloc((sizeof(u32) *(nr+1)), GFP_KERNEL);
887 auto_freq_table[i++] =
888 dvfs_clk_round_rate(ddr.clk_dvfs_node, 1000 * be32_to_cpup(val++));
892 auto_freq_table_size = i;
895 prop = of_find_property(clk_ddr_dev_node, "freq-table", NULL);
901 nr = prop->length / sizeof(u32);
903 pr_err("%s: Invalid freq list\n", __func__);
909 unsigned long status = be32_to_cpup(val++);
911 dvfs_clk_round_rate(ddr.clk_dvfs_node, be32_to_cpup(val++) * 1000);
913 if (status & SYS_STATUS_NORMAL)
914 ddr.normal_rate = rate;
915 if (status & SYS_STATUS_SUSPEND)
916 ddr.suspend_rate = rate;
917 if (status & SYS_STATUS_VIDEO_1080P)
918 ddr.video_1080p_rate = rate;
919 if (status & SYS_STATUS_VIDEO_4K)
920 ddr.video_4k_rate = rate;
921 if (status & SYS_STATUS_PERFORMANCE)
922 ddr.performance_rate= rate;
923 if ((status & SYS_STATUS_LCDC0)&&(status & SYS_STATUS_LCDC1))
924 ddr.dualview_rate = rate;
925 if (status & SYS_STATUS_HDMI)
926 ddr.hdmi_rate = rate;
927 if (status & SYS_STATUS_IDLE)
929 if (status & SYS_STATUS_REBOOT)
930 ddr.reboot_rate= rate;
931 if (status & SYS_STATUS_BOOST)
932 ddr.boost_rate= rate;
933 if (status & SYS_STATUS_ISP)
939 bd_freq_table = of_get_bd_freq_table(clk_ddr_dev_node, "bd-freq-table");
941 of_property_read_u32_index(clk_ddr_dev_node, "high_load", 0,
943 of_property_read_u32_index(clk_ddr_dev_node, "low_load", 0, &low_load);
944 of_property_read_u32_index(clk_ddr_dev_node, "auto_freq_interval", 0,
945 &auto_freq_interval_ms);
946 of_property_read_u32_index(clk_ddr_dev_node, "down_rate_delay", 0,
947 &down_rate_delay_ms);
952 static int ddrfreq_scale_rate_for_dvfs(struct clk *clk, unsigned long rate)
954 unsigned long real_rate;
956 real_rate = ddr_change_freq(rate/MHZ);
960 if (cpu_is_rk312x()) {
961 clk->parent->rate = 2 * real_rate;
962 clk->rate = real_rate;
964 clk->rate = real_rate;
965 clk->parent->rate = real_rate;
971 #if defined(CONFIG_RK_PM_TESTS)
972 static void ddrfreq_tst_init(void);
975 static int ddrfreq_init(void)
978 struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
980 #if defined(CONFIG_RK_PM_TESTS)
984 clk_cpu_dvfs_node = clk_get_dvfs_node("clk_core");
985 memset(&ddr, 0x00, sizeof(ddr));
986 ddr.clk_dvfs_node = clk_get_dvfs_node("clk_ddr");
987 if (!ddr.clk_dvfs_node){
990 clk_enable_dvfs(ddr.clk_dvfs_node);
992 dvfs_clk_register_set_rate_callback(ddr.clk_dvfs_node, ddrfreq_scale_rate_for_dvfs);
994 init_waitqueue_head(&ddr.wait);
995 INIT_LIST_HEAD(&ddr.video_info_list);
997 ddr.normal_rate = dvfs_clk_get_rate(ddr.clk_dvfs_node);
998 ddr.sys_status = rockchip_get_system_status();
1000 of_init_ddr_freq_table();
1002 if (!ddr.reboot_rate)
1003 ddr.reboot_rate = ddr.normal_rate;
1006 ret = input_register_handler(&ddr_freq_input_handler);
1008 ddr.auto_freq = false;
1011 //REGISTER_CLK_NOTIFIER(pd_isp);
1012 //REGISTER_CLK_NOTIFIER(pd_vop0);
1013 //REGISTER_CLK_NOTIFIER(pd_vop1);
1015 ret = misc_register(&video_state_dev);
1016 ret = misc_register(&ddr_freq_dev);
1017 if (unlikely(ret)) {
1018 pr_err("failed to register video_state misc device! error %d\n", ret);
1022 ddr.task = kthread_create(ddrfreq_task, NULL, "ddrfreqd");
1023 if (IS_ERR(ddr.task)) {
1024 ret = PTR_ERR(ddr.task);
1025 pr_err("failed to create kthread! error %d\n", ret);
1029 sched_setscheduler_nocheck(ddr.task, SCHED_FIFO, ¶m);
1030 get_task_struct(ddr.task);
1031 kthread_bind(ddr.task, 0);
1032 wake_up_process(ddr.task);
1034 rockchip_register_system_status_notifier(&ddrfreq_system_status_notifier);
1035 fb_register_client(&ddr_freq_suspend_notifier);
1037 pr_info("verion 1.2 20140526\n");
1038 pr_info("normal %luMHz video_1080p %luMHz video_4k %luMHz dualview %luMHz idle %luMHz suspend %luMHz reboot %luMHz\n",
1039 ddr.normal_rate / MHZ,
1040 ddr.video_1080p_rate / MHZ,
1041 ddr.video_4k_rate / MHZ,
1042 ddr.dualview_rate / MHZ,
1043 ddr.idle_rate / MHZ,
1044 ddr.suspend_rate / MHZ,
1045 ddr.reboot_rate / MHZ);
1047 pr_info("auto-freq=%d\n", ddr.auto_freq);
1048 if (auto_freq_table) {
1049 for (i = 0; i < auto_freq_table_size; i++) {
1050 pr_info("auto-freq-table[%d] %luMHz\n", i, auto_freq_table[i] / MHZ);
1053 pr_info("auto-freq-table epmty!\n");
1058 misc_deregister(&video_state_dev);
1062 late_initcall(ddrfreq_init);
1063 /****************************ddr bandwith tst************************************/
1064 #if defined(CONFIG_RK_PM_TESTS)
1065 static ssize_t ddrbw_dyn_show(struct kobject *kobj, struct kobj_attribute *attr,
1069 str += sprintf(str, "print: %d\n", print);
1070 str += sprintf(str, "watch: %d\n", watch);
1071 str += sprintf(str, "high_load: %d\n", high_load);
1072 str += sprintf(str, "low_load: %d\n", low_load);
1073 str += sprintf(str, "auto_freq_interval_ms: %d\n", auto_freq_interval_ms);
1074 str += sprintf(str, "down_rate_delay_ms: %d\n", down_rate_delay_ms);
1075 // str += sprintf(str, "low_load_last_ms: %d\n", low_load_last_ms);
1081 static ssize_t ddrbw_dyn_store(struct kobject *kobj, struct kobj_attribute *attr,
1082 const char *buf, size_t n)
1087 sscanf(buf, "%s %u", var_name, &value);
1089 if((strncmp(buf, "print", strlen("print")) == 0)) {
1091 } else if((strncmp(buf, "watch", strlen("watch")) == 0)) {
1093 } else if((strncmp(buf, "high", strlen("high")) == 0)) {
1095 } else if((strncmp(buf, "low", strlen("low")) == 0)) {
1097 } else if((strncmp(buf, "interval", strlen("interval")) == 0)) {
1098 auto_freq_interval_ms = value;
1099 } else if((strncmp(buf, "downdelay", strlen("downdelay")) == 0)) {
1100 down_rate_delay_ms = value;
1105 struct ddrfreq_attribute {
1106 struct attribute attr;
1107 ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,
1109 ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
1110 const char *buf, size_t n);
1113 static struct ddrfreq_attribute ddrfreq_attrs[] = {
1114 /* node_name permision show_func store_func */
1115 __ATTR(ddrfreq, S_IRUSR|S_IRGRP|S_IWUSR, ddrbw_dyn_show, ddrbw_dyn_store),
1117 int rk_pm_tests_kobj_atrradd(const struct attribute *attr);
1119 static void ddrfreq_tst_init(void)
1123 ret = rk_pm_tests_kobj_atrradd(&ddrfreq_attrs[0].attr);
1126 printk("%s: create ddrfreq sysfs node error, ret: %d\n", __func__, ret);