rk: move ddr freq scale test function to a standalone ddr_test.c file, and rk30 ddr freq scale use clk api

This commit is contained in:
黄涛 2012-11-27 19:30:24 +08:00
parent dac9df953e
commit ccb16a4962
4 changed files with 220 additions and 377 deletions

View File

@ -76,180 +76,3 @@ static int rk30_ddr_late_init (void)
}
late_initcall(rk30_ddr_late_init);
#endif
#ifdef CONFIG_DDR_TEST
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/vmalloc.h>
#include <sound/pcm.h>
#include <linux/random.h>
static ssize_t ddr_proc_write(struct file *file, const char __user *buffer,
unsigned long len, void *data)
{
char *cookie_pot;
char *p;
uint32_t value, value1, value2;
uint32_t count, total;
char tmp;
bool cpu1_online;
cookie_pot = (char *)vmalloc( len );
memset(cookie_pot,0,len);
if (!cookie_pot)
{
return -ENOMEM;
}
else
{
if (copy_from_user( cookie_pot, buffer, len ))
return -EFAULT;
}
switch(cookie_pot[0])
{
case 'c':
case 'C':
printk("change ddr freq:\n");
if(cookie_pot[1] ==':')
{
strsep(&cookie_pot,":");
p=strsep(&cookie_pot,"M");
value = simple_strtol(p,NULL,10);
printk("change!!! freq=%dMHz\n", value);
value=ddr_set_rate(value);
printk("success!!! freq=%dMHz\n", value);
msleep(32);
printk("\n");
}
else
{
printk("Error auto change ddr freq debug.\n");
printk("-->'c&&C' change freq,Example: echo 'c:400M' > ddr_test\n");
}
break;
case 'a':
case 'A':
printk("auto change ddr freq test (random):\n");
if(cookie_pot[1] ==':')
{
strsep(&cookie_pot,":");
p=strsep(&cookie_pot,"M");
value1 = simple_strtol(p,NULL,10);
strsep(&cookie_pot,"-");
p=strsep(&cookie_pot,"M");
value2 = simple_strtol(p,NULL,10);
strsep(&cookie_pot,"-");
p=strsep(&cookie_pot,"T");
total = simple_strtol(p,NULL,10);
count = 0;
while ( count < total )
{
printk("auto change ddr freq test (random):[%d-%d]\n",count,total);
do
{
value = value1 + random32();
value %= value2;
}while(value < value1);
printk("change!!! freq=%dMHz\n", value);
value=ddr_set_rate(value);
printk("success!!! freq=%dMHz\n", value);
msleep(32);
count++;
}
}
else
{
printk("Error auto change ddr freq test debug.\n");
printk("-->'a&&A' auto change ddr freq test (random),Example: echo 'a:200M-400M-1000T' > ddr_test\n");
}
break;
case 'b':
case 'B':
printk("auto change ddr freq test (specific):\n");
if(cookie_pot[1] ==':')
{
strsep(&cookie_pot,":");
p=strsep(&cookie_pot,"M");
value1 = simple_strtol(p,NULL,10);
strsep(&cookie_pot,"-");
p=strsep(&cookie_pot,"M");
value2 = simple_strtol(p,NULL,10);
strsep(&cookie_pot,"-");
p=strsep(&cookie_pot,"T");
total = simple_strtol(p,NULL,10);
count = 0;
while ( count < total )
{
printk("auto change ddr freq test (specific):[%d-%d]\n",count,total);
if(tmp == 1)
{
value = value1;
tmp = 0;
}
else
{
value = value2;
tmp = 1;
}
printk("change!!! freq=%dMHz\n", value);
value=ddr_set_rate(value);
printk("success!!! freq=%dMHz\n", value);
msleep(32);
count++;
}
}
else
{
printk("Error auto change ddr freq test debug.\n");
printk("-->'b&&B' auto change ddr freq test (specific),Example: echo 'a:200M-400M-1000T' > ddr_test\n");
}
break;
case 'h':
case 'H':
default:
printk("Help for ddr_ts .\n-->The Cmd list: \n");
printk("-->'a&&A' auto change ddr freq test (random),Example: echo 'a:200M-400M-100T' > ddr_test\n");
printk("-->'b&&B' auto change ddr freq test (specific),Example: echo 'b:200M-400M-100T' > ddr_test\n");
printk("-->'c&&C' change freq,Example: echo 'c:400M' > ddr_test\n");
break;
}
return len;
}
static const struct file_operations ddr_proc_fops = {
.owner = THIS_MODULE,
};
static int ddr_proc_init(void)
{
struct proc_dir_entry *ddr_proc_entry;
ddr_proc_entry = create_proc_entry("driver/ddr_ts", 0777, NULL);
if(ddr_proc_entry != NULL)
{
ddr_proc_entry->write_proc = ddr_proc_write;
return -1;
}
else
{
printk("create proc error !\n");
}
return 0;
}
late_initcall(ddr_proc_init);
#endif //CONFIG_DDR_TEST

View File

@ -12,6 +12,7 @@ struct ddr {
int suspend;
struct early_suspend early_suspend;
struct clk *ddr_pll;
struct clk *clk;
};
static void ddr_early_suspend(struct early_suspend *h);
@ -79,7 +80,6 @@ static uint32_t _ddr_change_freq(uint32_t nMHz)
pause_cpu1(NULL);
}
clk_set_rate(ddr.ddr_pll, 0);
out:
put_cpu();
@ -88,222 +88,46 @@ static uint32_t _ddr_change_freq(uint32_t nMHz)
uint32_t ddr_set_rate(uint32_t nMHz)
{
nMHz = _ddr_change_freq(nMHz);
return nMHz;
nMHz = _ddr_change_freq(nMHz);
clk_set_rate(ddr.ddr_pll, 0);
return nMHz;
}
#ifdef CONFIG_HAS_EARLYSUSPEND
static uint32_t ddr_resume_freq=DDR_FREQ;
static uint32_t ddr_suspend_freq=120;
static uint32_t ddr_resume_freq;
static uint32_t ddr_suspend_freq = 120 * 1000000;
static void ddr_early_suspend(struct early_suspend *h)
{
uint32_t value;
//Enable auto self refresh 0x01*32 DDR clk cycle
ddr_set_auto_self_refresh(true);
//Enable auto self refresh 0x01*32 DDR clk cycle
ddr_set_auto_self_refresh(true);
ddr_resume_freq=clk_get_rate(ddr.ddr_pll)/1000000;
value = ddr_set_rate(ddr_suspend_freq);
ddr_print("init success!!! freq=%dMHz\n", value);
ddr_resume_freq = clk_get_rate(ddr.clk);
return;
clk_set_rate(ddr.clk, ddr_suspend_freq);
ddr_print("%s: freq=%luMHz\n", __func__, clk_get_rate(ddr.clk)/1000000);
return;
}
static void ddr_late_resume(struct early_suspend *h)
{
uint32_t value;
//Disable auto self refresh
ddr_set_auto_self_refresh(false);
//Disable auto self refresh
ddr_set_auto_self_refresh(false);
clk_set_rate(ddr.clk, ddr_resume_freq);
value = ddr_set_rate(ddr_resume_freq);
ddr_print("init success!!! freq=%dMHz\n", value);
ddr_print("%s: freq=%luMHz\n", __func__, clk_get_rate(ddr.clk)/1000000);
return;
return;
}
static int rk30_ddr_late_init (void)
{
ddr.ddr_pll = clk_get(NULL, "ddr_pll");
register_early_suspend(&ddr.early_suspend);
return 0;
ddr.ddr_pll = clk_get(NULL, "ddr_pll");
ddr.clk = clk_get(NULL, "ddr");
register_early_suspend(&ddr.early_suspend);
return 0;
}
late_initcall(rk30_ddr_late_init);
#endif
#ifdef CONFIG_DDR_TEST
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/vmalloc.h>
#include <sound/pcm.h>
#include <linux/random.h>
static ssize_t ddr_proc_write(struct file *file, const char __user *buffer,
unsigned long len, void *data)
{
char *cookie_pot;
char *p;
uint32_t value, value1, value2;
uint32_t count, total;
char tmp;
bool cpu1_online;
cookie_pot = (char *)vmalloc( len );
memset(cookie_pot,0,len);
if (!cookie_pot)
{
return -ENOMEM;
}
else
{
if (copy_from_user( cookie_pot, buffer, len ))
return -EFAULT;
}
switch(cookie_pot[0])
{
case 'c':
case 'C':
printk("change ddr freq:\n");
if(cookie_pot[1] ==':')
{
strsep(&cookie_pot,":");
p=strsep(&cookie_pot,"M");
value = simple_strtol(p,NULL,10);
printk("change!!! freq=%dMHz\n", value);
value=ddr_set_rate(value);
printk("success!!! freq=%dMHz\n", value);
msleep(32);
printk("\n");
}
else
{
printk("Error auto change ddr freq debug.\n");
printk("-->'c&&C' change freq,Example: echo 'c:400M' > ddr_test\n");
}
break;
case 'a':
case 'A':
printk("auto change ddr freq test (random):\n");
if(cookie_pot[1] ==':')
{
strsep(&cookie_pot,":");
p=strsep(&cookie_pot,"M");
value1 = simple_strtol(p,NULL,10);
strsep(&cookie_pot,"-");
p=strsep(&cookie_pot,"M");
value2 = simple_strtol(p,NULL,10);
strsep(&cookie_pot,"-");
p=strsep(&cookie_pot,"T");
total = simple_strtol(p,NULL,10);
count = 0;
while ( count < total )
{
printk("auto change ddr freq test (random):[%d-%d]\n",count,total);
do
{
value = value1 + random32();
value %= value2;
}while(value < value1);
printk("change!!! freq=%dMHz\n", value);
value=ddr_set_rate(value);
printk("success!!! freq=%dMHz\n", value);
msleep(32);
count++;
}
}
else
{
printk("Error auto change ddr freq test debug.\n");
printk("-->'a&&A' auto change ddr freq test (random),Example: echo 'a:200M-400M-1000T' > ddr_test\n");
}
break;
case 'b':
case 'B':
printk("auto change ddr freq test (specific):\n");
if(cookie_pot[1] ==':')
{
strsep(&cookie_pot,":");
p=strsep(&cookie_pot,"M");
value1 = simple_strtol(p,NULL,10);
strsep(&cookie_pot,"-");
p=strsep(&cookie_pot,"M");
value2 = simple_strtol(p,NULL,10);
strsep(&cookie_pot,"-");
p=strsep(&cookie_pot,"T");
total = simple_strtol(p,NULL,10);
count = 0;
while ( count < total )
{
printk("auto change ddr freq test (specific):[%d-%d]\n",count,total);
if(tmp == 1)
{
value = value1;
tmp = 0;
}
else
{
value = value2;
tmp = 1;
}
printk("change!!! freq=%dMHz\n", value);
value=ddr_set_rate(value);
printk("success!!! freq=%dMHz\n", value);
msleep(32);
count++;
}
}
else
{
printk("Error auto change ddr freq test debug.\n");
printk("-->'b&&B' auto change ddr freq test (specific),Example: echo 'a:200M-400M-1000T' > ddr_test\n");
}
break;
case 'h':
case 'H':
default:
printk("Help for ddr_ts .\n-->The Cmd list: \n");
printk("-->'a&&A' auto change ddr freq test (random),Example: echo 'a:200M-400M-100T' > ddr_test\n");
printk("-->'b&&B' auto change ddr freq test (specific),Example: echo 'b:200M-400M-100T' > ddr_test\n");
printk("-->'c&&C' change freq,Example: echo 'c:400M' > ddr_test\n");
break;
}
return len;
}
static const struct file_operations ddr_proc_fops = {
.owner = THIS_MODULE,
};
static int ddr_proc_init(void)
{
struct proc_dir_entry *ddr_proc_entry;
ddr_proc_entry = create_proc_entry("driver/ddr_ts", 0777, NULL);
if(ddr_proc_entry != NULL)
{
ddr_proc_entry->write_proc = ddr_proc_write;
return -1;
}
else
{
printk("create proc error !\n");
}
return 0;
}
late_initcall(ddr_proc_init);
#endif //CONFIG_DDR_TEST

View File

@ -11,5 +11,5 @@ obj-y += mem_reserve.o
obj-y += config.o
obj-y += sram.o
CFLAGS_sram.o += -mthumb
obj-$(CONFIG_DDR_TEST) += memtester.o
obj-$(CONFIG_DDR_TEST) += memtester.o ddr_test.o
obj-$(CONFIG_DDR_FREQ) += video_state.o

196
arch/arm/plat-rk/ddr_test.c Normal file
View File

@ -0,0 +1,196 @@
#if defined(CONFIG_DDR_TEST) && defined(CONFIG_DDR_FREQ)
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/vmalloc.h>
#include <linux/random.h>
#include <linux/uaccess.h>
#include <linux/clk.h>
static ssize_t ddr_proc_write(struct file *file, const char __user *buffer,
unsigned long len, void *data)
{
char *cookie_pot;
char *p;
uint32_t value, value1, value2;
uint32_t count, total;
char tmp;
struct clk *clk_ddr = NULL;
int ret = len;
char *buf = vzalloc(len);
cookie_pot = buf;
if (!cookie_pot)
{
return -ENOMEM;
}
else
{
if (copy_from_user( cookie_pot, buffer, len )) {
ret = -EFAULT;
goto out;
}
}
clk_ddr = clk_get(NULL, "ddr");
if (IS_ERR(clk_ddr)) {
ret = PTR_ERR(clk_ddr);
clk_ddr = NULL;
goto out;
}
switch(cookie_pot[0])
{
case 'c':
case 'C':
printk("change ddr freq:\n");
if(cookie_pot[1] ==':')
{
strsep(&cookie_pot,":");
p=strsep(&cookie_pot,"M");
value = simple_strtol(p,NULL,10);
printk("change!!! freq=%dMHz\n", value);
clk_set_rate(clk_ddr, value * 1000000);
value = clk_get_rate(clk_ddr) / 1000000;
printk("success!!! freq=%dMHz\n", value);
msleep(32);
printk("\n");
}
else
{
printk("Error auto change ddr freq debug.\n");
printk("-->'c&&C' change freq,Example: echo 'c:400M' > ddr_test\n");
}
break;
case 'a':
case 'A':
printk("auto change ddr freq test (random):\n");
if(cookie_pot[1] ==':')
{
strsep(&cookie_pot,":");
p=strsep(&cookie_pot,"M");
value1 = simple_strtol(p,NULL,10);
strsep(&cookie_pot,"-");
p=strsep(&cookie_pot,"M");
value2 = simple_strtol(p,NULL,10);
strsep(&cookie_pot,"-");
p=strsep(&cookie_pot,"T");
total = simple_strtol(p,NULL,10);
count = 0;
while ( count < total )
{
printk("auto change ddr freq test (random):[%d-%d]\n",count,total);
do
{
value = value1 + random32();
value %= value2;
}while(value < value1);
printk("change!!! freq=%dMHz\n", value);
clk_set_rate(clk_ddr, value * 1000000);
value = clk_get_rate(clk_ddr) / 1000000;
printk("success!!! freq=%dMHz\n", value);
msleep(32);
count++;
}
}
else
{
printk("Error auto change ddr freq test debug.\n");
printk("-->'a&&A' auto change ddr freq test (random),Example: echo 'a:200M-400M-1000T' > ddr_test\n");
}
break;
case 'b':
case 'B':
printk("auto change ddr freq test (specific):\n");
if(cookie_pot[1] ==':')
{
strsep(&cookie_pot,":");
p=strsep(&cookie_pot,"M");
value1 = simple_strtol(p,NULL,10);
strsep(&cookie_pot,"-");
p=strsep(&cookie_pot,"M");
value2 = simple_strtol(p,NULL,10);
strsep(&cookie_pot,"-");
p=strsep(&cookie_pot,"T");
total = simple_strtol(p,NULL,10);
count = 0;
tmp = 0;
while ( count < total )
{
printk("auto change ddr freq test (specific):[%d-%d]\n",count,total);
if(tmp == 1)
{
value = value1;
tmp = 0;
}
else
{
value = value2;
tmp = 1;
}
printk("change!!! freq=%dMHz\n", value);
clk_set_rate(clk_ddr, value * 1000000);
value = clk_get_rate(clk_ddr) / 1000000;
printk("success!!! freq=%dMHz\n", value);
msleep(32);
count++;
}
}
else
{
printk("Error auto change ddr freq test debug.\n");
printk("-->'b&&B' auto change ddr freq test (specific),Example: echo 'a:200M-400M-1000T' > ddr_test\n");
}
break;
case 'h':
case 'H':
default:
printk("Help for ddr_ts .\n-->The Cmd list: \n");
printk("-->'a&&A' auto change ddr freq test (random),Example: echo 'a:200M-400M-100T' > ddr_test\n");
printk("-->'b&&B' auto change ddr freq test (specific),Example: echo 'b:200M-400M-100T' > ddr_test\n");
printk("-->'c&&C' change freq,Example: echo 'c:400M' > ddr_test\n");
break;
}
out:
if (clk_ddr)
clk_put(clk_ddr);
vfree(buf);
return ret;
}
static const struct file_operations ddr_proc_fops = {
.owner = THIS_MODULE,
};
static int ddr_proc_init(void)
{
struct proc_dir_entry *ddr_proc_entry;
ddr_proc_entry = create_proc_entry("driver/ddr_ts", 0777, NULL);
if(ddr_proc_entry != NULL)
{
ddr_proc_entry->write_proc = ddr_proc_write;
return -1;
}
else
{
printk("create proc error !\n");
}
return 0;
}
late_initcall(ddr_proc_init);
#endif // CONFIG_DDR_TEST && CONFIG_DDR_FREQ