1 #if defined(CONFIG_DDR_TEST)
2 #include <linux/kernel.h>
3 #include <linux/slab.h>
5 #include <linux/delay.h>
6 #include <linux/proc_fs.h>
7 #include <linux/vmalloc.h>
8 #include <linux/random.h>
9 #include <linux/uaccess.h>
10 #include <linux/clk.h>
11 #include <linux/freezer.h>
12 #include <linux/kthread.h>
13 #include <linux/sched/rt.h>
14 #include <linux/rockchip/dvfs.h>
16 #include <dt-bindings/clock/ddr.h>
21 struct dvfs_node *clk_dvfs_node;
22 volatile unsigned int freq;
23 volatile bool change_end;
24 struct task_struct *task;
25 wait_queue_head_t wait;
27 static struct ddrtest ddrtest;
29 static ssize_t ddr_proc_read(struct file *file, char __user *buffer,
30 size_t len, loff_t *data)
32 char version[]={"V100"};
35 printk("ddr_test Version V1.0\n");
38 buffer[i] = version[i];
43 static ssize_t ddr_proc_write(struct file *file, const char __user *buffer,
44 size_t len, loff_t *data)
48 uint32_t value, value1, value2;
49 uint32_t count, total;
51 struct clk *clk_ddr = NULL;
53 char *buf = vzalloc(len);
63 if (copy_from_user( cookie_pot, buffer, len )) {
69 clk_ddr = clk_get(NULL, "clk_ddr");
70 if (IS_ERR(clk_ddr)) {
71 ret = PTR_ERR(clk_ddr);
80 printk("change ddr freq:\n");
81 if(cookie_pot[1] ==':')
83 strsep(&cookie_pot,":");
84 p=strsep(&cookie_pot,"M");
85 value = simple_strtol(p,NULL,10);
86 printk("change!!! freq=%dMHz\n", value);
87 //clk_set_rate(clk_ddr, value * 1000000);
89 ddrtest.change_end = false;
90 wake_up(&ddrtest.wait);
91 while(ddrtest.change_end != true); //wait change freq end
92 value = clk_get_rate(clk_ddr) / 1000000;
93 printk("success!!! freq=%dMHz\n", value);
99 printk("Error auto change ddr freq debug.\n");
100 printk("-->'c&&C' change freq,Example: echo 'c:400M' > ddr_test\n");
106 printk("auto change ddr freq test (random):\n");
107 if(cookie_pot[1] ==':')
109 strsep(&cookie_pot,":");
110 p=strsep(&cookie_pot,"M");
111 value1 = simple_strtol(p,NULL,10);
112 strsep(&cookie_pot,"-");
113 p=strsep(&cookie_pot,"M");
114 value2 = simple_strtol(p,NULL,10);
115 strsep(&cookie_pot,"-");
116 p=strsep(&cookie_pot,"T");
117 total = simple_strtol(p,NULL,10);
121 while ( count < total )
123 printk("auto change ddr freq test (random):[%d-%d]\n",count,total);
126 value = value1 + prandom_u32();
128 }while(value < value1);
130 printk("change!!! freq=%dMHz\n", value);
131 //clk_set_rate(clk_ddr, value * 1000000);
132 ddrtest.freq = value;
133 ddrtest.change_end = false;
134 wake_up(&ddrtest.wait);
135 while(ddrtest.change_end != true); //wait change freq end
136 value = clk_get_rate(clk_ddr) / 1000000;
137 printk("success!!! freq=%dMHz\n", value);
145 printk("Error auto change ddr freq test debug.\n");
146 printk("-->'a&&A' auto change ddr freq test (random),Example: echo 'a:200M-400M-1000T' > ddr_test\n");
152 printk("auto change ddr freq test (specific):\n");
153 if(cookie_pot[1] ==':')
155 strsep(&cookie_pot,":");
156 p=strsep(&cookie_pot,"M");
157 value1 = simple_strtol(p,NULL,10);
158 strsep(&cookie_pot,"-");
159 p=strsep(&cookie_pot,"M");
160 value2 = simple_strtol(p,NULL,10);
161 strsep(&cookie_pot,"-");
162 p=strsep(&cookie_pot,"T");
163 total = simple_strtol(p,NULL,10);
168 while ( count < total )
170 printk("auto change ddr freq test (specific):[%d-%d]\n",count,total);
182 printk("change!!! freq=%dMHz\n", value);
183 //clk_set_rate(clk_ddr, value * 1000000);
184 ddrtest.freq = value;
185 ddrtest.change_end = false;
186 wake_up(&ddrtest.wait);
187 while(ddrtest.change_end != true); //wait change freq end
188 value = clk_get_rate(clk_ddr) / 1000000;
189 printk("success!!! freq=%dMHz\n", value);
197 printk("Error auto change ddr freq test debug.\n");
198 printk("-->'b&&B' auto change ddr freq test (specific),Example: echo 'a:200M-400M-1000T' > ddr_test\n");
205 printk("Help for ddr_ts .\n-->The Cmd list: \n");
206 printk("-->'a&&A' auto change ddr freq test (random),Example: echo 'a:200M-400M-100T' > ddr_test\n");
207 printk("-->'b&&B' auto change ddr freq test (specific),Example: echo 'b:200M-400M-100T' > ddr_test\n");
208 printk("-->'c&&C' change freq,Example: echo 'c:400M' > ddr_test\n");
219 static const struct file_operations ddr_proc_fops = {
220 .owner = THIS_MODULE,
223 static void ddrtest_work(unsigned int value)
225 dvfs_clk_set_rate(ddrtest.clk_dvfs_node, value * 1000000);
226 ddrtest.change_end = true;
229 static int ddrtest_task(void *data)
234 //unsigned long status = ddr.sys_status;
235 ddrtest_work(ddrtest.freq);
236 wait_event_freezable(ddrtest.wait, (ddrtest.change_end == false ) || kthread_should_stop());
237 } while (!kthread_should_stop());
242 static const struct file_operations ddrtest_proc_fops = {
243 .owner = THIS_MODULE,
244 .read = ddr_proc_read,
245 .write = ddr_proc_write,
248 static int ddr_proc_init(void)
250 struct proc_dir_entry *ddr_proc_entry;
252 struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
253 init_waitqueue_head(&ddrtest.wait);
255 //ddrtest.pll = clk_get(NULL, "ddr_pll");
256 ddrtest.clk = clk_get(NULL, "clk_ddr");
257 if (IS_ERR(ddrtest.clk)) {
258 ret = PTR_ERR(ddrtest.clk);
260 pr_err("failed to get ddr clk, error %d\n", ret);
263 ddrtest.freq = clk_get_rate(ddrtest.clk)/1000000;
265 ddrtest.clk_dvfs_node = clk_get_dvfs_node("clk_ddr");
266 if (!ddrtest.clk_dvfs_node)
269 ddr_proc_entry = proc_create("driver/ddr_ts",
270 S_IRUGO | S_IWUGO | S_IWUSR | S_IRUSR,
271 NULL,&ddrtest_proc_fops);
273 if(ddr_proc_entry == NULL){
275 pr_err("failed to create proc entry, error %d\n", ret);
279 ddrtest.task = kthread_create(ddrtest_task, NULL, "ddrtestd");
280 if (IS_ERR(ddrtest.task)) {
281 ret = PTR_ERR(ddrtest.task);
282 pr_err("failed to create kthread! error %d\n", ret);
285 sched_setscheduler_nocheck(ddrtest.task,SCHED_FIFO, ¶m);
286 get_task_struct(ddrtest.task);
287 kthread_bind(ddrtest.task, 0);
288 wake_up_process(ddrtest.task);
294 late_initcall_sync(ddr_proc_init);
295 #endif // CONFIG_DDR_TEST