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/dvfs.h>
25 #include <dt-bindings/clock/ddr.h>
27 #include <linux/rockchip/grf.h>
28 #include <linux/rockchip/iomap.h>
29 #include <linux/clk-private.h>
30 #include "../../../drivers/clk/rockchip/clk-pd.h"
32 extern int rockchip_cpufreq_reboot_limit_freq(void);
34 static struct dvfs_node *clk_cpu_dvfs_node = NULL;
35 static int reboot_config_done = 0;
36 static int ddr_boost = 0;
39 static int high_load = 70;
40 static int low_load = 60;
41 static int auto_freq_interval_ms = 20;
42 static int high_load_last_ms = 0;
43 static int low_load_last_ms = 200;
44 static unsigned long *auto_freq_table = NULL;
45 static int cur_freq_index;
46 static int auto_freq_table_size;
50 DEBUG_VIDEO_STATE = 1U << 1,
51 DEBUG_SUSPEND = 1U << 2,
52 DEBUG_VERBOSE = 1U << 3,
54 static int debug_mask = DEBUG_DDR;
56 module_param(debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
57 #define dprintk(mask, fmt, ...) do { if (mask & debug_mask) pr_debug(fmt, ##__VA_ARGS__); } while (0)
59 enum ddr_bandwidth_id{
68 #define ddr_monitor_start() grf_writel((((readl_relaxed(RK_PMU_VIRT + 0x9c)>>13)&7)==3)?0xc000c000:0xe000e000,RK3288_GRF_SOC_CON4)
69 #define ddr_monitor_stop() grf_writel(0xc0000000,RK3288_GRF_SOC_CON4)
71 #define grf_readl(offset) readl_relaxed(RK_GRF_VIRT + offset)
72 #define grf_writel(v, offset) do { writel_relaxed(v, RK_GRF_VIRT + offset); dsb(); } while (0)
75 #define MHZ (1000*1000)
85 struct list_head node;
89 struct dvfs_node *clk_dvfs_node;
90 struct list_head video_info_list;
91 unsigned long normal_rate;
92 unsigned long video_1080p_rate;
93 unsigned long video_4k_rate;
94 unsigned long performance_rate;
95 unsigned long dualview_rate;
96 unsigned long idle_rate;
97 unsigned long suspend_rate;
98 unsigned long reboot_rate;
99 unsigned long boost_rate;
100 unsigned long isp_rate;
102 bool auto_self_refresh;
104 unsigned long sys_status;
105 struct task_struct *task;
106 wait_queue_head_t wait;
108 static struct ddr ddr;
110 module_param_named(sys_status, ddr.sys_status, ulong, S_IRUGO);
111 module_param_named(auto_self_refresh, ddr.auto_self_refresh, bool, S_IRUGO);
112 module_param_named(mode, ddr.mode, charp, S_IRUGO);
114 static unsigned long get_freq_from_table(unsigned long freq)
118 if (!auto_freq_table)
121 for (i = 0; auto_freq_table[i] != 0; i++) {
122 if (auto_freq_table[i] >= freq) {
123 return auto_freq_table[i];
127 return auto_freq_table[i-1];
130 static unsigned long get_index_from_table(unsigned long freq)
134 if (!auto_freq_table)
137 for (i = 0; auto_freq_table[i] != 0; i++) {
138 if (auto_freq_table[i] >= freq) {
146 static noinline void ddrfreq_set_sys_status(int status)
148 ddr.sys_status |= status;
152 static noinline void ddrfreq_clear_sys_status(int status)
154 ddr.sys_status &= ~status;
158 static void ddrfreq_mode(bool auto_self_refresh, unsigned long *target_rate, char *name)
160 unsigned int min_rate, max_rate;
164 if (auto_self_refresh != ddr.auto_self_refresh) {
165 ddr_set_auto_self_refresh(auto_self_refresh);
166 ddr.auto_self_refresh = auto_self_refresh;
167 dprintk(DEBUG_DDR, "change auto self refresh to %d when %s\n", auto_self_refresh, name);
170 cur_freq_index = get_index_from_table(*target_rate);
172 if (*target_rate != dvfs_clk_get_rate(ddr.clk_dvfs_node)) {
173 freq_limit_en = dvfs_clk_get_limit(clk_cpu_dvfs_node, &min_rate, &max_rate);
175 dvfs_clk_enable_limit(clk_cpu_dvfs_node, 600000000, -1);
176 if (dvfs_clk_set_rate(ddr.clk_dvfs_node, *target_rate) == 0) {
177 *target_rate = dvfs_clk_get_rate(ddr.clk_dvfs_node);
178 dprintk(DEBUG_DDR, "change freq to %lu MHz when %s\n", *target_rate / MHZ, name);
182 dvfs_clk_enable_limit(clk_cpu_dvfs_node, min_rate, max_rate);
184 dvfs_clk_disable_limit(clk_cpu_dvfs_node);
189 void ddr_bandwidth_get(u32 *ch0_eff, u32 *ch1_eff)
191 u32 ddr_bw_val[2][ddrbw_id_end];
195 for(j = 0; j < 2; j++) {
196 for(i = 0; i < ddrbw_eff; i++ ){
197 ddr_bw_val[j][i] = grf_readl(RK3288_GRF_SOC_STATUS11+i*4+j*16);
201 temp64 = ((u64)ddr_bw_val[0][0]+ddr_bw_val[0][1])*4*100;
202 do_div(temp64, ddr_bw_val[0][ddrbw_time_num]);
203 ddr_bw_val[0][ddrbw_eff] = temp64;
206 temp64 = ((u64)ddr_bw_val[1][0]+ddr_bw_val[1][1])*4*100;
207 do_div(temp64, ddr_bw_val[1][ddrbw_time_num]);
208 ddr_bw_val[1][ddrbw_eff] = temp64;
212 static void ddr_auto_freq(void)
215 u32 ch0_eff, ch1_eff, max_eff;
216 static u32 high_load_last = 0, low_load_last = 0;
218 freq = dvfs_clk_get_rate(ddr.clk_dvfs_node);
221 ddr_bandwidth_get(&ch0_eff, &ch1_eff);
222 max_eff = (ch0_eff > ch1_eff) ? ch0_eff : ch1_eff;
225 printk("%d %d\n", ch0_eff, ch1_eff);
231 printk("%d %d\n", ch0_eff, ch1_eff);
236 if (freq < ddr.boost_rate) {
237 low_load_last = low_load_last_ms/auto_freq_interval_ms;
238 freq = ddr.boost_rate;
239 ddrfreq_mode(false, &freq, "boost");
241 } else if(max_eff > high_load){
242 low_load_last = low_load_last_ms/auto_freq_interval_ms;
243 if (!high_load_last) {
244 if (cur_freq_index < auto_freq_table_size-1) {
245 freq = auto_freq_table[cur_freq_index+1];
246 ddrfreq_mode(false, &freq, "high load");
251 } else if (max_eff < low_load){
252 high_load_last = high_load_last_ms/auto_freq_interval_ms;
253 if (!low_load_last) {
254 freq = max_eff*(freq/low_load);
255 freq = get_freq_from_table(freq);
256 ddrfreq_mode(false, &freq, "low load");
265 static noinline long ddrfreq_work(unsigned long sys_status)
267 static struct clk *cpu = NULL;
268 static struct clk *gpu = NULL;
269 long timeout = MAX_SCHEDULE_TIMEOUT;
270 unsigned long s = sys_status;
273 cpu = clk_get(NULL, "cpu");
275 gpu = clk_get(NULL, "gpu");
277 dprintk(DEBUG_VERBOSE, "sys_status %02lx\n", sys_status);
279 if (ddr.reboot_rate && (s & SYS_STATUS_REBOOT)) {
280 ddrfreq_mode(false, &ddr.reboot_rate, "shutdown/reboot");
281 rockchip_cpufreq_reboot_limit_freq();
282 reboot_config_done = 1;
283 } else if (ddr.suspend_rate && (s & SYS_STATUS_SUSPEND)) {
284 ddrfreq_mode(true, &ddr.suspend_rate, "suspend");
285 } else if (ddr.dualview_rate &&
286 (s & SYS_STATUS_LCDC0) && (s & SYS_STATUS_LCDC1)) {
287 ddrfreq_mode(false, &ddr.dualview_rate, "dual-view");
288 } else if (ddr.video_1080p_rate && (s & SYS_STATUS_VIDEO_1080P)) {
289 ddrfreq_mode(false, &ddr.video_1080p_rate, "video_1080p");
290 } else if (ddr.video_4k_rate && (s & SYS_STATUS_VIDEO_4K)) {
291 ddrfreq_mode(false, &ddr.video_4k_rate, "video_4k");
292 } else if (ddr.performance_rate && (s & SYS_STATUS_PERFORMANCE)) {
293 ddrfreq_mode(false, &ddr.performance_rate, "performance");
294 } else if (ddr.isp_rate && (s & SYS_STATUS_ISP)) {
295 ddrfreq_mode(false, &ddr.isp_rate, "isp");
296 } else if (ddr.idle_rate
297 && !(s & SYS_STATUS_GPU)
298 && !(s & SYS_STATUS_RGA)
299 && !(s & SYS_STATUS_CIF0)
300 && !(s & SYS_STATUS_CIF1)
301 && (clk_get_rate(cpu) < 816 * MHZ)
302 && (clk_get_rate(gpu) <= 200 * MHZ)
304 ddrfreq_mode(false, &ddr.idle_rate, "idle");
308 timeout = auto_freq_interval_ms;
311 ddrfreq_mode(false, &ddr.normal_rate, "normal");
318 static int ddrfreq_task(void *data)
325 unsigned long status = ddr.sys_status;
326 timeout = ddrfreq_work(status);
327 wait_event_freezable_timeout(ddr.wait, (status != ddr.sys_status) || kthread_should_stop(), timeout);
328 } while (!kthread_should_stop());
333 void add_video_info(struct video_info *video_info)
336 list_add(&video_info->node, &ddr.video_info_list);
339 void del_video_info(struct video_info *video_info)
342 list_del(&video_info->node);
347 void clear_video_info(void)
349 struct video_info *video_info, *next;
351 list_for_each_entry_safe(video_info, next, &ddr.video_info_list, node) {
352 del_video_info(video_info);
356 struct video_info *find_video_info(struct video_info *match_video_info)
358 struct video_info *video_info;
360 if (!match_video_info)
363 list_for_each_entry(video_info, &ddr.video_info_list, node) {
364 if ((video_info->width == match_video_info->width)
365 && (video_info->height == match_video_info->height)
366 && (video_info->ishevc== match_video_info->ishevc)
367 && (video_info->videoFramerate == match_video_info->videoFramerate)
368 && (video_info->streamBitrate== match_video_info->streamBitrate)) {
378 void update_video_info(void)
380 struct video_info *video_info, *max_res_video;
381 int max_res=0, res=0;
383 if (list_empty(&ddr.video_info_list)) {
384 ddrfreq_clear_sys_status(SYS_STATUS_VIDEO_1080P | SYS_STATUS_VIDEO_4K);
389 list_for_each_entry(video_info, &ddr.video_info_list, node) {
390 res = video_info->width * video_info->height;
393 max_res_video = video_info;
397 if (max_res <= 1920*1080)
398 ddrfreq_set_sys_status(SYS_STATUS_VIDEO_1080P);
400 ddrfreq_set_sys_status(SYS_STATUS_VIDEO_4K);
406 /***format: width=val,height=val,ishevc=val,videoFramerate=val,streamBitrate=val***/
407 static long get_video_param(char **str)
414 return simple_strtol(p,NULL,10);
419 static ssize_t video_state_write(struct file *file, const char __user *buffer,
420 size_t count, loff_t *ppos)
422 struct video_info *video_info = NULL;
423 char state, *cookie_pot, *buf = vzalloc(count);
434 if (copy_from_user(cookie_pot, buffer, count)) {
439 dprintk(DEBUG_VIDEO_STATE, "%s: %s,len %d\n", __func__, cookie_pot,count);
442 if( (count>=3) && (cookie_pot[2]=='w') )
444 video_info = kzalloc(sizeof(struct video_info), GFP_KERNEL);
449 INIT_LIST_HEAD(&video_info->node);
451 strsep(&cookie_pot,",");
453 video_info->width = get_video_param(&cookie_pot);
454 video_info->height = get_video_param(&cookie_pot);
455 video_info->ishevc = get_video_param(&cookie_pot);
456 video_info->videoFramerate = get_video_param(&cookie_pot);
457 video_info->streamBitrate = get_video_param(&cookie_pot);
459 dprintk(DEBUG_VIDEO_STATE, "%s: video_state=%c,width=%d,height=%d,ishevc=%d,videoFramerate=%d,streamBitrate=%d\n",
460 __func__, state,video_info->width,video_info->height,
461 video_info->ishevc, video_info->videoFramerate,
462 video_info->streamBitrate);
468 del_video_info(find_video_info(video_info));
473 add_video_info(video_info);
476 case 'p'://performance
477 ddrfreq_set_sys_status(SYS_STATUS_PERFORMANCE);
480 ddrfreq_clear_sys_status(SYS_STATUS_PERFORMANCE);
492 static int video_state_release(struct inode *inode, struct file *file)
494 dprintk(DEBUG_VIDEO_STATE, "video_state release\n");
501 static const struct file_operations video_state_fops = {
502 .owner = THIS_MODULE,
503 .release= video_state_release,
504 .write = video_state_write,
507 static struct miscdevice video_state_dev = {
508 .fops = &video_state_fops,
509 .name = "video_state",
510 .minor = MISC_DYNAMIC_MINOR,
513 static void ddr_freq_input_event(struct input_handle *handle, unsigned int type,
514 unsigned int code, int value)
520 static int ddr_freq_input_connect(struct input_handler *handler,
521 struct input_dev *dev, const struct input_device_id *id)
523 struct input_handle *handle;
526 handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
531 handle->handler = handler;
532 handle->name = "ddr_freq";
534 error = input_register_handle(handle);
538 error = input_open_device(handle);
544 input_unregister_handle(handle);
550 static void ddr_freq_input_disconnect(struct input_handle *handle)
552 input_close_device(handle);
553 input_unregister_handle(handle);
557 static const struct input_device_id ddr_freq_ids[] = {
559 .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
560 INPUT_DEVICE_ID_MATCH_ABSBIT,
561 .evbit = { BIT_MASK(EV_ABS) },
562 .absbit = { [BIT_WORD(ABS_MT_POSITION_X)] =
563 BIT_MASK(ABS_MT_POSITION_X) |
564 BIT_MASK(ABS_MT_POSITION_Y) },
567 .flags = INPUT_DEVICE_ID_MATCH_KEYBIT |
568 INPUT_DEVICE_ID_MATCH_ABSBIT,
569 .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
570 .absbit = { [BIT_WORD(ABS_X)] =
571 BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
574 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
575 .evbit = { BIT_MASK(EV_KEY) },
580 static struct input_handler ddr_freq_input_handler = {
581 .event = ddr_freq_input_event,
582 .connect = ddr_freq_input_connect,
583 .disconnect = ddr_freq_input_disconnect,
585 .id_table = ddr_freq_ids,
588 static int ddrfreq_clk_event(int status, unsigned long event)
591 case RK_CLK_PD_PREPARE:
592 ddrfreq_set_sys_status(status);
594 case RK_CLK_PD_UNPREPARE:
595 ddrfreq_clear_sys_status(status);
601 #define CLK_NOTIFIER(name, status) \
602 static int ddrfreq_clk_##name##_event(struct notifier_block *this, unsigned long event, void *ptr) \
604 return ddrfreq_clk_event(SYS_STATUS_##status, event); \
606 static struct notifier_block ddrfreq_clk_##name##_notifier = { .notifier_call = ddrfreq_clk_##name##_event };
608 #define REGISTER_CLK_NOTIFIER(name) \
610 struct clk *clk = clk_get(NULL, #name); \
611 rk_clk_pd_notifier_register(clk, &ddrfreq_clk_##name##_notifier); \
615 #define UNREGISTER_CLK_NOTIFIER(name) \
617 struct clk *clk = clk_get(NULL, #name); \
618 rk_clk_pd_notifier_unregister(clk, &ddrfreq_clk_##name##_notifier); \
622 CLK_NOTIFIER(pd_isp, ISP)
623 CLK_NOTIFIER(pd_vop0, LCDC0)
624 CLK_NOTIFIER(pd_vop1, LCDC1)
626 static int ddrfreq_reboot_notifier_event(struct notifier_block *this, unsigned long event, void *ptr)
628 u32 timeout = 1000; // 10s
629 ddrfreq_set_sys_status(SYS_STATUS_REBOOT);
630 while (!reboot_config_done && --timeout) {
634 pr_err("failed to set ddr clk from %luMHz to %luMHz when shutdown/reboot\n", dvfs_clk_get_rate(ddr.clk_dvfs_node) / MHZ, ddr.reboot_rate / MHZ);
639 static struct notifier_block ddrfreq_reboot_notifier = {
640 .notifier_call = ddrfreq_reboot_notifier_event,
643 static int ddr_freq_suspend_notifier_call(struct notifier_block *self,
644 unsigned long action, void *data)
646 struct fb_event *event = data;
647 int blank_mode = *((int *)event->data);
649 if (action == FB_EARLY_EVENT_BLANK) {
650 switch (blank_mode) {
651 case FB_BLANK_UNBLANK:
652 ddrfreq_clear_sys_status(SYS_STATUS_SUSPEND);
658 else if (action == FB_EVENT_BLANK) {
659 switch (blank_mode) {
660 case FB_BLANK_POWERDOWN:
661 ddrfreq_set_sys_status(SYS_STATUS_SUSPEND);
671 static struct notifier_block ddr_freq_suspend_notifier = {
672 .notifier_call = ddr_freq_suspend_notifier_call,
675 int of_init_ddr_freq_table(void)
677 struct device_node *clk_ddr_dev_node;
678 const struct property *prop;
682 clk_ddr_dev_node = of_find_node_by_name(NULL, "clk_ddr");
683 if (IS_ERR_OR_NULL(clk_ddr_dev_node)) {
684 pr_err("%s: get clk ddr dev node err\n", __func__);
685 return PTR_ERR(clk_ddr_dev_node);
688 prop = of_find_property(clk_ddr_dev_node, "auto-freq", NULL);
689 if (prop && prop->value)
690 ddr.auto_freq = be32_to_cpup(prop->value);
692 prop = of_find_property(clk_ddr_dev_node, "auto-freq-table", NULL);
693 if (prop && prop->value) {
694 nr = prop->length / sizeof(u32);
695 auto_freq_table = kzalloc((sizeof(u32) *(nr+1)), GFP_KERNEL);
698 auto_freq_table[i++] = 1000 * be32_to_cpup(val++);
702 auto_freq_table_size = i;
705 prop = of_find_property(clk_ddr_dev_node, "freq-table", NULL);
711 nr = prop->length / sizeof(u32);
713 pr_err("%s: Invalid freq list\n", __func__);
719 unsigned long status = be32_to_cpup(val++);
720 unsigned long rate = be32_to_cpup(val++) * 1000;
722 if (status & SYS_STATUS_NORMAL)
723 ddr.normal_rate = rate;
724 if (status & SYS_STATUS_SUSPEND)
725 ddr.suspend_rate = rate;
726 if (status & SYS_STATUS_VIDEO_1080P)
727 ddr.video_1080p_rate = rate;
728 if (status & SYS_STATUS_VIDEO_4K)
729 ddr.video_4k_rate = rate;
730 if (status & SYS_STATUS_PERFORMANCE)
731 ddr.performance_rate= rate;
732 if ((status & SYS_STATUS_LCDC0)&&(status & SYS_STATUS_LCDC1))
733 ddr.dualview_rate = rate;
734 if (status & SYS_STATUS_IDLE)
736 if (status & SYS_STATUS_REBOOT)
737 ddr.reboot_rate= rate;
738 if (status & SYS_STATUS_BOOST)
739 ddr.boost_rate= rate;
740 if (status & SYS_STATUS_ISP)
749 static int ddrfreq_scale_rate_for_dvfs(struct clk *clk, unsigned long rate)
751 unsigned long real_rate;
753 real_rate = ddr_change_freq(rate/MHZ);
758 clk->parent->rate = clk->rate = real_rate;
763 #if defined(CONFIG_RK_PM_TESTS)
764 static void ddrfreq_tst_init(void);
767 static int ddrfreq_init(void)
770 struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
772 #if defined(CONFIG_RK_PM_TESTS)
776 clk_cpu_dvfs_node = clk_get_dvfs_node("clk_core");
777 if (!clk_cpu_dvfs_node){
781 memset(&ddr, 0x00, sizeof(ddr));
782 ddr.clk_dvfs_node = clk_get_dvfs_node("clk_ddr");
783 if (!ddr.clk_dvfs_node){
786 clk_enable_dvfs(ddr.clk_dvfs_node);
788 dvfs_clk_register_set_rate_callback(ddr.clk_dvfs_node, ddrfreq_scale_rate_for_dvfs);
790 init_waitqueue_head(&ddr.wait);
791 INIT_LIST_HEAD(&ddr.video_info_list);
793 ddr.normal_rate = dvfs_clk_get_rate(ddr.clk_dvfs_node);
794 ddr.suspend_rate = ddr.normal_rate;
795 ddr.reboot_rate = ddr.normal_rate;
797 of_init_ddr_freq_table();
799 ret = input_register_handler(&ddr_freq_input_handler);
801 ddr.auto_freq = false;
803 REGISTER_CLK_NOTIFIER(pd_isp);
804 REGISTER_CLK_NOTIFIER(pd_vop0);
805 REGISTER_CLK_NOTIFIER(pd_vop1);
807 ret = misc_register(&video_state_dev);
809 pr_err("failed to register video_state misc device! error %d\n", ret);
813 ddr.task = kthread_create(ddrfreq_task, NULL, "ddrfreqd");
814 if (IS_ERR(ddr.task)) {
815 ret = PTR_ERR(ddr.task);
816 pr_err("failed to create kthread! error %d\n", ret);
820 sched_setscheduler_nocheck(ddr.task, SCHED_FIFO, ¶m);
821 get_task_struct(ddr.task);
822 kthread_bind(ddr.task, 0);
823 wake_up_process(ddr.task);
825 fb_register_client(&ddr_freq_suspend_notifier);
826 register_reboot_notifier(&ddrfreq_reboot_notifier);
828 pr_info("verion 1.1 20140509\n");
829 dprintk(DEBUG_DDR, "normal %luMHz video_1080p %luMHz video_4k %luMHz dualview %luMHz idle %luMHz suspend %luMHz reboot %luMHz\n",
830 ddr.normal_rate / MHZ, ddr.video_1080p_rate / MHZ, ddr.video_1080p_rate / MHZ, ddr.dualview_rate / MHZ, ddr.idle_rate / MHZ, ddr.suspend_rate / MHZ, ddr.reboot_rate / MHZ);
835 misc_deregister(&video_state_dev);
839 late_initcall(ddrfreq_init);
840 /****************************ddr bandwith tst************************************/
841 #if defined(CONFIG_RK_PM_TESTS)
842 static ssize_t ddrbw_dyn_show(struct kobject *kobj, struct kobj_attribute *attr,
846 str += sprintf(str, "print: %d\n", print);
847 str += sprintf(str, "watch: %d\n", watch);
848 str += sprintf(str, "high_load: %d\n", high_load);
849 str += sprintf(str, "low_load: %d\n", low_load);
850 str += sprintf(str, "auto_freq_interval_ms: %d\n", auto_freq_interval_ms);
851 str += sprintf(str, "high_load_last_ms: %d\n", high_load_last_ms);
852 str += sprintf(str, "low_load_last_ms: %d\n", low_load_last_ms);
858 static ssize_t ddrbw_dyn_store(struct kobject *kobj, struct kobj_attribute *attr,
859 const char *buf, size_t n)
864 sscanf(buf, "%s %u", var_name, &value);
866 if((strncmp(buf, "print", strlen("print")) == 0)) {
868 } else if((strncmp(buf, "watch", strlen("watch")) == 0)) {
870 } else if((strncmp(buf, "high", strlen("high")) == 0)) {
872 } else if((strncmp(buf, "low", strlen("low")) == 0)) {
874 } else if((strncmp(buf, "interval", strlen("interval")) == 0)) {
875 auto_freq_interval_ms = value;;
876 } else if((strncmp(buf, "high_last", strlen("high_last")) == 0)) {
877 high_load_last_ms = value;;
878 } else if((strncmp(buf, "low_last", strlen("low_last")) == 0)) {
879 low_load_last_ms = value;;
884 struct ddrfreq_attribute {
885 struct attribute attr;
886 ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,
888 ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
889 const char *buf, size_t n);
892 static struct ddrfreq_attribute ddrfreq_attrs[] = {
893 /* node_name permision show_func store_func */
894 __ATTR(ddrfreq, S_IRUSR|S_IRGRP|S_IWUSR, ddrbw_dyn_show, ddrbw_dyn_store),
896 int rk_pm_tests_kobj_atrradd(const struct attribute *attr);
898 static void ddrfreq_tst_init(void)
902 ret = rk_pm_tests_kobj_atrradd(&ddrfreq_attrs[0].attr);
905 printk("%s: create ddrfreq sysfs node error, ret: %d\n", __func__, ret);