rk3288 lcdc: add var check
authorhjc <hjc@rock-chips.com>
Sat, 5 Apr 2014 10:34:05 +0000 (18:34 +0800)
committerhjc <hjc@rock-chips.com>
Tue, 8 Apr 2014 01:00:31 +0000 (09:00 +0800)
drivers/video/rockchip/lcdc/rk3288_lcdc.c
drivers/video/rockchip/rk_fb.c
include/linux/rk_fb.h

index 0f928f6c3e05ce7dedd8b9be890c63f4adc2a666..ef647ff2774bec0b444cc2e4ae27d0ff05984297 100755 (executable)
@@ -585,6 +585,23 @@ static int rk3288_lcdc_area_swap(struct rk_lcdc_win *win,int area_num)
        return 0;
 }
 
+static int rk3288_win_area_check_var(int win_id,int area_num,struct rk_lcdc_win_area *area_pre,
+                       struct rk_lcdc_win_area *area_now)
+{
+       if((area_pre->ypos >= area_now->ypos) ||
+               (area_pre->ypos+area_pre->ysize >= area_now->ypos)){
+               area_now->state = 0;
+               pr_err("win[%d]:\n"
+                       "area_pre[%d]:ypos[%d],ysize[%d]\n"
+                       "area_now[%d]:ypos[%d],ysize[%d]\n",
+                       win_id,
+                       area_num-1,area_pre->ypos,area_pre->ysize,
+                       area_num,  area_now->ypos,area_now->ysize);
+               return -EINVAL;
+       }
+       return 0;
+}
+
 static int rk3288_win_0_1_reg_update(struct rk_lcdc_driver *dev_drv,int win_id)
 {
        struct lcdc_device *lcdc_dev =
@@ -603,7 +620,7 @@ static int rk3288_win_0_1_reg_update(struct rk_lcdc_driver *dev_drv,int win_id)
        
                mask =  m_WIN0_BIC_COE_SEL |
                        m_WIN0_VSD_YRGB_GT4 | m_WIN0_VSD_YRGB_GT2 |
-                       m_WIN0_VSD_CBR_GT4 | m_WIN0_VSD_CBR_GT4 |
+                       m_WIN0_VSD_CBR_GT4 | m_WIN0_VSD_CBR_GT2 |
                        m_WIN0_YRGB_HOR_SCL_MODE | m_WIN0_YRGB_VER_SCL_MODE |
                        m_WIN0_YRGB_HSD_MODE | m_WIN0_YRGB_VSU_MODE |
                        m_WIN0_YRGB_VSD_MODE | m_WIN0_CBR_HOR_SCL_MODE |
@@ -686,7 +703,7 @@ static int rk3288_win_2_3_reg_update(struct rk_lcdc_driver *dev_drv,int win_id)
                /*area 0*/
                if(win->area[0].state == 1){
                        mask = m_WIN2_MST0_EN;
-                       val  = v_WIN2_MST0_EN(1);
+                       val  = v_WIN2_MST0_EN(win->area[0].state);
                        lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
 
                        mask = m_WIN2_VIR_STRIDE0;
@@ -707,8 +724,10 @@ static int rk3288_win_2_3_reg_update(struct rk_lcdc_driver *dev_drv,int win_id)
                }
                /*area 1*/
                if(win->area[1].state == 1){
+                       rk3288_win_area_check_var(win_id,1,&win->area[0],&win->area[1]);
+                       
                        mask = m_WIN2_MST1_EN;
-                       val  = v_WIN2_MST1_EN(1);
+                       val  = v_WIN2_MST1_EN(win->area[1].state);
                        lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
 
                        mask = m_WIN2_VIR_STRIDE1;
@@ -729,8 +748,10 @@ static int rk3288_win_2_3_reg_update(struct rk_lcdc_driver *dev_drv,int win_id)
                }
                /*area 2*/
                if(win->area[2].state == 1){
+                       rk3288_win_area_check_var(win_id,2,&win->area[1],&win->area[2]);
+                       
                        mask = m_WIN2_MST2_EN;
-                       val  = v_WIN2_MST2_EN(1);
+                       val  = v_WIN2_MST2_EN(win->area[2].state);
                        lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
 
                        mask = m_WIN2_VIR_STRIDE2;
@@ -751,8 +772,10 @@ static int rk3288_win_2_3_reg_update(struct rk_lcdc_driver *dev_drv,int win_id)
                }
                /*area 3*/
                if(win->area[3].state == 1){
+                       rk3288_win_area_check_var(win_id,3,&win->area[2],&win->area[3]);
+                       
                        mask = m_WIN2_MST3_EN;
-                       val  = v_WIN2_MST3_EN(1);
+                       val  = v_WIN2_MST3_EN(win->area[3].state);
                        lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
 
                        mask = m_WIN2_VIR_STRIDE3;
@@ -2142,9 +2165,6 @@ static int rk3288_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
 static int rk3288_lcdc_blank(struct rk_lcdc_driver *dev_drv,
                             int win_id, int blank_mode)
 {
-       struct lcdc_device *lcdc_dev =
-           container_of(dev_drv, struct lcdc_device, driver);
-
        switch (blank_mode) {
        case FB_BLANK_UNBLANK:
                rk3288_lcdc_early_resume(dev_drv);
@@ -2799,7 +2819,7 @@ static int rk3288_lcdc_config_done(struct rk_lcdc_driver *dev_drv)
                             v_STANDBY_EN(lcdc_dev->standby));
        for (i=0;i<4;i++) {
                win = dev_drv->win[i];
-               if (win->state == 0) {
+               if ((win->state == 0)&&(win->last_state == 1)) {
                        switch (win->id) {
                        case 0:
                                mask =  m_WIN0_EN;
@@ -2829,6 +2849,7 @@ static int rk3288_lcdc_config_done(struct rk_lcdc_driver *dev_drv)
                                break;
                        }
                }       
+               win->last_state = win->state;
        }
        lcdc_cfg_done(lcdc_dev);
        spin_unlock(&lcdc_dev->reg_lock);
@@ -2865,8 +2886,9 @@ static int rk3288_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv)
 {
        struct lcdc_device *lcdc_dev =
            container_of(dev_drv, struct lcdc_device, driver);
+       int ovl;
        spin_lock(&lcdc_dev->reg_lock);
-       int ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN);
+       ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN);
        spin_unlock(&lcdc_dev->reg_lock);
        return ovl;
 }
@@ -2912,7 +2934,7 @@ static int rk3288_lcdc_set_dsp_cabc(struct rk_lcdc_driver *dev_drv,int mode)
            container_of(dev_drv, struct lcdc_device, driver);
        struct rk_screen *screen = dev_drv->cur_screen;
        int total_pixel,calc_pixel,stage_up,stage_down;
-       u32 mask, val;
+       u32 mask=0, val=0;
 
        u32 cabc_mode[5][3]={
                /*num ,up,  down*/
index 73ba40e4fe05de38f68d10941ca680f94f4c068c..9d9801260705602c787bcc503d00d85f582859a0 100755 (executable)
@@ -815,7 +815,7 @@ static int rk_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info
        u32 xoffset = var->xoffset;
        u32 yoffset = var->yoffset;
        u32 xvir = var->xres_virtual;
-       u32 yvir = var->yres_virtual;
+       /*u32 yvir = var->yres_virtual;*/
        /*u8 data_format = var->nonstd&0xff;*/
 
        u8  pixel_width;
@@ -1270,6 +1270,33 @@ static void rk_fb_update_regs_handler(struct kthread_work *work)
                kfree(data);
        }
 }
+static int rk_fb_check_config_var(struct rk_fb_area_par *area_par,struct rk_screen *screen)
+{
+       if(area_par->x_offset+area_par->xact > area_par->xvir){
+               pr_err("check config var fail 0:\n"
+                       "x_offset=%d,xact=%d,xvir=%d\n",
+                       area_par->x_offset,
+                       area_par->xact,
+                       area_par->xvir);
+               return -EINVAL;
+       }
+
+       if((area_par->xpos+area_par->xsize > screen->mode.xres) ||
+               (area_par->ypos+area_par->ysize > screen->mode.yres)){
+               pr_err("check config var fail 1:\n"
+                       "xpos=%d,xsize=%d,xres=%d\n"
+                       "ypos=%d,ysize=%d,yres=%d\n",
+                       area_par->xpos,
+                       area_par->xsize,
+                       screen->mode.xres,
+                       area_par->ypos,
+                       area_par->ysize,
+                       screen->mode.yres                       
+                       );
+               return -EINVAL;
+       }
+       return 0;
+}
 
 static int rk_fb_set_win_buffer(struct fb_info *info,
        struct rk_fb_win_par *win_par,struct rk_fb_reg_win_data *reg_win_data)
@@ -1280,7 +1307,7 @@ static int rk_fb_set_win_buffer(struct fb_info *info,
        struct rk_lcdc_driver * dev_drv = (struct rk_lcdc_driver * )info->par;
        struct rk_screen *screen = dev_drv->cur_screen;
 
-       int i,j,ion_fd,acq_fence_fd;
+       int i,ion_fd,acq_fence_fd;
        u32 xvir,yvir;
        u32 xoffset,yoffset;
 
@@ -1293,8 +1320,6 @@ static int rk_fb_set_win_buffer(struct fb_info *info,
        u32 stride,uv_stride;
        u32 stride_32bit_1;
        u32 stride_32bit_2;
-       u32 stride_128bit_1;
-       u32 stride_128bit_2;
        u16 uv_x_off,uv_y_off,uv_y_act;
        u8  is_pic_yuv=0;
        u8  ppixel_a=0,global_a=0;
@@ -1375,6 +1400,7 @@ static int rk_fb_set_win_buffer(struct fb_info *info,
                reg_win_data->win_id  = -1;
        }
        for(i=0;i<reg_win_data->area_num;i++){
+               rk_fb_check_config_var(&win_par->area_par[i],screen);
                reg_win_data->reg_area_data[i].xpos = win_par->area_par[i].xpos;//visiable pos in panel
                reg_win_data->reg_area_data[i].ypos = win_par->area_par[i].ypos;
 
@@ -1509,7 +1535,6 @@ static int rk_fb_set_win_config(struct fb_info *info,
        struct sync_fence *retire_fence;
        struct sync_pt *release_sync_pt[RK_MAX_BUF_NUM];
        struct sync_pt *retire_sync_pt;
-       int fencd_fd;
        char fence_name[20];
 #endif
        int ret,i,j=0;
@@ -1961,8 +1986,6 @@ static int rk_fb_set_par(struct fb_info *info)
        u32 stride,uv_stride;
        u32 stride_32bit_1;
        u32 stride_32bit_2;
-       u32 stride_128bit_1;
-       u32 stride_128bit_2;
        u16 uv_x_off,uv_y_off,uv_y_act;
        u8  is_pic_yuv=0;
 
index 8cc9e78da782c385f7277652805056df5b32b534..c1faa919e1a8ccb05541269cf467f390ff330543 100755 (executable)
@@ -299,6 +299,7 @@ struct rk_lcdc_win {
        char name[5];
        int id;
        bool state;             /*on or off*/
+       bool last_state;                /*on or off*/
        u32 pseudo_pal[16];
        enum data_format format;
        int z_order;            /*win sel layer*/