ddrfreq: add video scene, performan scene
author陈亮 <cl@rock-chips.com>
Thu, 8 May 2014 13:11:04 +0000 (06:11 -0700)
committer陈亮 <cl@rock-chips.com>
Thu, 8 May 2014 13:11:54 +0000 (06:11 -0700)
arch/arm/boot/dts/rk3288-p977.dts
arch/arm/boot/dts/rk3288-tb.dts
arch/arm/mach-rockchip/ddr_freq.c
include/dt-bindings/clock/ddr.h

index 2e6559ef8d06c501fcdbbe342a0ce8d1b9ee231e..f2ae61a651fcaf9af8770d8728c6f71bc5d79a1a 100755 (executable)
                /*status                freq(KHz)*/
                SYS_STATUS_NORMAL       400000
                SYS_STATUS_SUSPEND      200000
-               SYS_STATUS_VIDEO        300000
+               SYS_STATUS_VIDEO_1080P  240000
+               SYS_STATUS_VIDEO_4K     400000
+               SYS_STATUS_PERFORMANCE  528000
                SYS_STATUS_DUALVIEW     500000
                SYS_STATUS_BOOST        324000
                >;
index 7bcade47ebc5e95eb99a905ba08e35a6dd27910c..cba780af9979b6cfda994ebe3ed9bc4c3c6a2f15 100755 (executable)
@@ -696,7 +696,9 @@ rockchip,power_type = <GPIO>;
                /*status                freq(KHz)*/
                SYS_STATUS_NORMAL       400000
                SYS_STATUS_SUSPEND      200000
-               SYS_STATUS_VIDEO        300000
+               SYS_STATUS_VIDEO_1080P  240000
+               SYS_STATUS_VIDEO_4K     400000
+               SYS_STATUS_PERFORMANCE  528000
                SYS_STATUS_DUALVIEW     500000
                SYS_STATUS_BOOST        324000
                >;
index c9a5feeddf4b4d48faab481d92fac9df14fd8cae..884ef9cc1c662f24884691f42b63427d28b114f1 100644 (file)
@@ -73,10 +73,23 @@ enum ddr_bandwidth_id{
 #define MHZ    (1000*1000)
 #define KHZ    1000
 
+struct video_info {
+       int width;
+       int height;
+       int ishevc;
+       int videoFramerate;
+       int streamBitrate;
+
+       struct list_head node;
+};
+
 struct ddr {
        struct dvfs_node *clk_dvfs_node;
+       struct list_head video_info_list;
        unsigned long normal_rate;
-       unsigned long video_rate;
+       unsigned long video_1080p_rate;
+       unsigned long video_4k_rate;
+       unsigned long performace_rate;
        unsigned long dualview_rate;
        unsigned long idle_rate;
        unsigned long suspend_rate;
@@ -269,9 +282,12 @@ static noinline long ddrfreq_work(unsigned long sys_status)
        } else if (ddr.dualview_rate && 
                (s & SYS_STATUS_LCDC0) && (s & SYS_STATUS_LCDC1)) {
                ddrfreq_mode(false, &ddr.dualview_rate, "dual-view");
-       } else if (ddr.video_rate && 
-               ((s & SYS_STATUS_VIDEO_720P)||(s & SYS_STATUS_VIDEO_1080P))) {
-               ddrfreq_mode(false, &ddr.video_rate, "video");
+       } else if (ddr.video_1080p_rate && (s & SYS_STATUS_VIDEO_1080P)) {
+               ddrfreq_mode(false, &ddr.video_1080p_rate, "video_1080p");
+       } else if (ddr.video_4k_rate && (s & SYS_STATUS_VIDEO_4K)) {
+               ddrfreq_mode(false, &ddr.video_4k_rate, "video_4k");
+       } else if (ddr.video_4k_rate && (s & SYS_STATUS_PERFORMANCE)) {
+               ddrfreq_mode(false, &ddr.video_4k_rate, "video_4k");
        } else if (ddr.idle_rate
                && !(s & SYS_STATUS_GPU)
                && !(s & SYS_STATUS_RGA)
@@ -309,21 +325,70 @@ static int ddrfreq_task(void *data)
        return 0;
 }
 
-static int video_state_release(struct inode *inode, struct file *file)
+void add_video_info(struct video_info *video_info)
 {
-       dprintk(DEBUG_VIDEO_STATE, "video_state release\n");
-       return 0;
+       if (video_info)
+               list_add(&video_info->node, &ddr.video_info_list);
+}
+
+void del_video_info(struct video_info *video_info)
+{
+       if (video_info)
+               list_del(&video_info->node);
+}
+
+struct video_info *find_video_info(struct video_info *match_video_info)
+{
+       struct video_info *video_info;
+
+       list_for_each_entry(video_info, &ddr.video_info_list, node) {
+               if ((video_info->width == match_video_info->width)
+                       && (video_info->height == match_video_info->height)
+                       && (video_info->ishevc== match_video_info->ishevc)
+                       && (video_info->videoFramerate == match_video_info->videoFramerate)
+                       && (video_info->streamBitrate== match_video_info->streamBitrate)) {
+
+                       return video_info;
+               }
+
+       }
+
+       return NULL;
+}
+
+void update_video_info(void)
+{
+       struct video_info *video_info, *max_res_video;
+       int max_res=0, res=0;
+
+       if (list_empty(&ddr.video_info_list)) {
+               ddrfreq_clear_sys_status(SYS_STATUS_VIDEO_1080P | SYS_STATUS_VIDEO_4K);
+               return;
+       }
+
+
+       list_for_each_entry(video_info, &ddr.video_info_list, node) {
+               res = video_info->width * video_info->height;
+               if (res > max_res) {
+                       max_res = res;
+                       max_res_video = video_info;
+               }
+       }
+
+       if (max_res <= 1920*1080)
+               ddrfreq_set_sys_status(SYS_STATUS_VIDEO_1080P);
+       else
+               ddrfreq_set_sys_status(SYS_STATUS_VIDEO_4K);
+
+
+       return;
 }
 
-#define VIDEO_LOW_RESOLUTION       (1080*720)
 static ssize_t video_state_write(struct file *file, const char __user *buffer,
                                 size_t count, loff_t *ppos)
 {
-       char state;
-       char *cookie_pot;
-       char *p;
-       char *buf = vzalloc(count);
-       uint32_t v_width=0,v_height=0,v_sync=0;
+       struct video_info *video_info = NULL;
+       char state, *cookie_pot, *p, *buf = vzalloc(count);
        cookie_pot = buf;
 
        if(!buf)
@@ -339,59 +404,77 @@ static ssize_t video_state_write(struct file *file, const char __user *buffer,
                return -EFAULT;
        }
 
-       dprintk(DEBUG_VIDEO_STATE, "video_state write %s,len %d\n", cookie_pot,count);
+       dprintk(DEBUG_VIDEO_STATE, "%s: %s,len %d\n", __func__, cookie_pot,count);
 
        state=cookie_pot[0];
        if( (count>=3) && (cookie_pot[2]=='w') )
        {
+               video_info = kzalloc(sizeof(struct video_info), GFP_KERNEL);
+               if (!video_info){
+                       vfree(buf);
+                       return -ENOMEM;
+               }
+
                strsep(&cookie_pot,",");
                strsep(&cookie_pot,"=");
                p=strsep(&cookie_pot,",");
-               v_width = simple_strtol(p,NULL,10);
+               video_info->width = simple_strtol(p,NULL,10);
+
+               strsep(&cookie_pot,"=");
+               p=strsep(&cookie_pot,",");
+               video_info->height = simple_strtol(p,NULL,10);
+
                strsep(&cookie_pot,"=");
                p=strsep(&cookie_pot,",");
-               v_height= simple_strtol(p,NULL,10);
+               video_info->ishevc = simple_strtol(p,NULL,10);
+
                strsep(&cookie_pot,"=");
                p=strsep(&cookie_pot,",");
-               v_sync= simple_strtol(p,NULL,10);
-               dprintk(DEBUG_VIDEO_STATE, "video_state %c,width=%d,height=%d,sync=%d\n", state,v_width,v_height,v_sync);
+               video_info->videoFramerate = simple_strtol(p,NULL,10);
+
+               strsep(&cookie_pot,"=");
+               p=strsep(&cookie_pot,",");
+               video_info->streamBitrate = simple_strtol(p,NULL,10);
+
+               dprintk(DEBUG_VIDEO_STATE, "%s: video_state=%c,width=%d,height=%d,ishevc=%d,videoFramerate=%d,streamBitrate=%d\n",
+                       __func__, state,video_info->width,video_info->height,
+                       video_info->ishevc, video_info->videoFramerate,
+                       video_info->streamBitrate);
+
        }
 
        switch (state) {
        case '0':
-               high_load = 70;
-               low_load = 60;
-               if (!ddr.auto_freq)
-                       ddrfreq_clear_sys_status(SYS_STATUS_VIDEO);
+               del_video_info(find_video_info(video_info));
+               update_video_info();
                break;
        case '1':
-               high_load = 35;
-               low_load = 25;
-               if( (v_width == 0) && (v_height == 0)){
-                       if (!ddr.auto_freq)
-                               ddrfreq_set_sys_status(SYS_STATUS_VIDEO_1080P);
-               }
-               else if(v_sync==1){
-                       //if(ddr.video_low_rate && ((v_width*v_height) <= VIDEO_LOW_RESOLUTION) )
-                       //      ddrfreq_set_sys_status(SYS_STATUS_VIDEO_720P);
-                       //else
-                       if (!ddr.auto_freq)
-                               ddrfreq_set_sys_status(SYS_STATUS_VIDEO_1080P);
-               }
-               else{
-                       if (!ddr.auto_freq)
-                               ddrfreq_clear_sys_status(SYS_STATUS_VIDEO);
-               }
+               add_video_info(video_info);
+               update_video_info();
+               break;
+       case 'p'://performance
+               ddrfreq_set_sys_status(SYS_STATUS_PERFORMANCE);
+               break;
+       case 'n'://normal
+               ddrfreq_clear_sys_status(SYS_STATUS_PERFORMANCE);
                break;
        default:
                vfree(buf);
                return -EINVAL;
 
        }
+
        vfree(buf);
        return count;
 }
 
+static int video_state_release(struct inode *inode, struct file *file)
+{
+       dprintk(DEBUG_VIDEO_STATE, "video_state release\n");
+       return 0;
+}
+
+
 static const struct file_operations video_state_fops = {
        .owner  = THIS_MODULE,
        .release= video_state_release,
@@ -623,8 +706,12 @@ int of_init_ddr_freq_table(void)
                        ddr.normal_rate = rate;
                if (status & SYS_STATUS_SUSPEND)
                        ddr.suspend_rate = rate;
-               if ((status & SYS_STATUS_VIDEO_720P)||(status & SYS_STATUS_VIDEO_720P))
-                       ddr.video_rate = rate;
+               if (status & SYS_STATUS_VIDEO_1080P)
+                       ddr.video_1080p_rate = rate;
+               if (status & SYS_STATUS_VIDEO_4K)
+                       ddr.video_4k_rate = rate;
+               if (status & SYS_STATUS_PERFORMANCE)
+                       ddr.performace_rate= rate;
                if ((status & SYS_STATUS_LCDC0)&&(status & SYS_STATUS_LCDC1))
                        ddr.dualview_rate = rate;
                if (status & SYS_STATUS_IDLE)
@@ -655,7 +742,7 @@ static int ddrfreq_init(void)
        if (!clk_cpu_dvfs_node){
                return -EINVAL;
        }
-       
+
        memset(&ddr, 0x00, sizeof(ddr));
        ddr.clk_dvfs_node = clk_get_dvfs_node("clk_ddr");
        if (!ddr.clk_dvfs_node){
@@ -665,8 +752,8 @@ static int ddrfreq_init(void)
        clk_enable_dvfs(ddr.clk_dvfs_node);
        
        init_waitqueue_head(&ddr.wait);
+       INIT_LIST_HEAD(&ddr.video_info_list);
        ddr.mode = "normal";
-
        ddr.normal_rate = dvfs_clk_get_rate(ddr.clk_dvfs_node);
        ddr.suspend_rate = ddr.normal_rate;
        ddr.reboot_rate = ddr.normal_rate;
@@ -711,8 +798,8 @@ static int ddrfreq_init(void)
        register_reboot_notifier(&ddrfreq_reboot_notifier);
 
        pr_info("verion 1.0 20140228\n");
-       dprintk(DEBUG_DDR, "normal %luMHz video %luMHz dualview %luMHz idle %luMHz suspend %luMHz reboot %luMHz\n",
-               ddr.normal_rate / MHZ, ddr.video_rate / MHZ, ddr.dualview_rate / MHZ, ddr.idle_rate / MHZ, ddr.suspend_rate / MHZ, ddr.reboot_rate / MHZ);
+       dprintk(DEBUG_DDR, "normal %luMHz video_1080p %luMHz video_4k %luMHz dualview %luMHz idle %luMHz suspend %luMHz reboot %luMHz\n",
+               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);
 
        return 0;
 
index a26d6653fa3f32a26ddd4dcd6c09cdb08c3262d5..a2c15b81a13a0b6e153f4cbb0c7fb9c7a15f267f 100644 (file)
@@ -48,7 +48,7 @@
 #define SYS_STATUS_SUSPEND     (1<<1)
 #define SYS_STATUS_IDLE                (1<<2)
 #define SYS_STATUS_REBOOT      (1<<3)
-#define SYS_STATUS_VIDEO_720P  (1<<4)
+#define SYS_STATUS_VIDEO_4K    (1<<4)
 #define SYS_STATUS_VIDEO_1080P (1<<5)
 #define SYS_STATUS_GPU         (1<<6)
 #define SYS_STATUS_RGA         (1<<7)
@@ -57,8 +57,9 @@
 #define SYS_STATUS_LCDC0       (1<<10)
 #define SYS_STATUS_LCDC1       (1<<11)
 #define SYS_STATUS_BOOST       (1<<12)
+#define SYS_STATUS_PERFORMANCE (1<<13)
+
 
-#define SYS_STATUS_VIDEO       (SYS_STATUS_VIDEO_720P|SYS_STATUS_VIDEO_1080P)
 #define SYS_STATUS_DUALVIEW    (SYS_STATUS_LCDC0|SYS_STATUS_LCDC1)
 
 #endif