From d4fa5b4b681fc76dc78fe39c127d3fcdb4e40619 Mon Sep 17 00:00:00 2001 From: hjc Date: Sat, 5 Apr 2014 18:34:05 +0800 Subject: [PATCH] rk3288 lcdc: add var check --- drivers/video/rockchip/lcdc/rk3288_lcdc.c | 44 +++++++++++++++++------ drivers/video/rockchip/rk_fb.c | 37 +++++++++++++++---- include/linux/rk_fb.h | 1 + 3 files changed, 64 insertions(+), 18 deletions(-) diff --git a/drivers/video/rockchip/lcdc/rk3288_lcdc.c b/drivers/video/rockchip/lcdc/rk3288_lcdc.c index 0f928f6c3e05..ef647ff2774b 100755 --- a/drivers/video/rockchip/lcdc/rk3288_lcdc.c +++ b/drivers/video/rockchip/lcdc/rk3288_lcdc.c @@ -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*/ diff --git a/drivers/video/rockchip/rk_fb.c b/drivers/video/rockchip/rk_fb.c index 73ba40e4fe05..9d9801260705 100755 --- a/drivers/video/rockchip/rk_fb.c +++ b/drivers/video/rockchip/rk_fb.c @@ -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;iarea_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; diff --git a/include/linux/rk_fb.h b/include/linux/rk_fb.h index 8cc9e78da782..c1faa919e1a8 100755 --- a/include/linux/rk_fb.h +++ b/include/linux/rk_fb.h @@ -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*/ -- 2.34.1