[kernel] video: rockchip: lcdc: 3288: fix iommu pagefault when user set win3 dsp size bigger than act size
This commit is contained in:
@ -873,6 +873,8 @@ static int rk3288_win_2_3_reg_update(struct rk_lcdc_driver *dev_drv,int win_id)
|
||||
struct rk_lcdc_win *win = dev_drv->win[win_id];
|
||||
struct rk_screen *screen = dev_drv->cur_screen;
|
||||
unsigned int mask, val, off;
|
||||
struct fb_info *fb0 = rk_get_fb(0);
|
||||
|
||||
off = (win_id-2) * 0x50;
|
||||
if((screen->y_mirror == 1)&&(win->area_num > 1)){
|
||||
rk3288_lcdc_area_swap(win,win->area_num);
|
||||
@ -905,7 +907,8 @@ static int rk3288_win_2_3_reg_update(struct rk_lcdc_driver *dev_drv,int win_id)
|
||||
mask = m_WIN2_MST0_EN;
|
||||
val = v_WIN2_MST0_EN(0);
|
||||
lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
|
||||
lcdc_writel(lcdc_dev, WIN2_MST0 + off, 0x80000000);
|
||||
lcdc_writel(lcdc_dev, WIN2_MST0 + off,
|
||||
fb0->fix.smem_start);
|
||||
}
|
||||
/*area 1*/
|
||||
if(win->area[1].state == 1){
|
||||
@ -930,7 +933,8 @@ static int rk3288_win_2_3_reg_update(struct rk_lcdc_driver *dev_drv,int win_id)
|
||||
mask = m_WIN2_MST1_EN;
|
||||
val = v_WIN2_MST1_EN(0);
|
||||
lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
|
||||
lcdc_writel(lcdc_dev, WIN2_MST1 + off, 0x80000000);
|
||||
lcdc_writel(lcdc_dev, WIN2_MST1 + off,
|
||||
fb0->fix.smem_start);
|
||||
}
|
||||
/*area 2*/
|
||||
if(win->area[2].state == 1){
|
||||
@ -955,7 +959,8 @@ static int rk3288_win_2_3_reg_update(struct rk_lcdc_driver *dev_drv,int win_id)
|
||||
mask = m_WIN2_MST2_EN;
|
||||
val = v_WIN2_MST2_EN(0);
|
||||
lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
|
||||
lcdc_writel(lcdc_dev, WIN2_MST2 + off, 0x80000000);
|
||||
lcdc_writel(lcdc_dev, WIN2_MST2 + off,
|
||||
fb0->fix.smem_start);
|
||||
}
|
||||
/*area 3*/
|
||||
if(win->area[3].state == 1){
|
||||
@ -980,7 +985,8 @@ static int rk3288_win_2_3_reg_update(struct rk_lcdc_driver *dev_drv,int win_id)
|
||||
mask = m_WIN2_MST3_EN;
|
||||
val = v_WIN2_MST3_EN(0);
|
||||
lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
|
||||
lcdc_writel(lcdc_dev, WIN2_MST3 + off, 0x80000000);
|
||||
lcdc_writel(lcdc_dev, WIN2_MST3 + off,
|
||||
fb0->fix.smem_start);
|
||||
}
|
||||
|
||||
if(win->alpha_en == 1)
|
||||
@ -1594,10 +1600,18 @@ static int win2_display(struct lcdc_device *lcdc_dev,
|
||||
for(i=0;i<win->area_num;i++)
|
||||
win->area[i].y_addr =
|
||||
win->area[i].smem_start + win->area[i].y_offset;
|
||||
lcdc_writel(lcdc_dev,WIN2_MST0,win->area[0].y_addr);
|
||||
lcdc_writel(lcdc_dev,WIN2_MST1,win->area[1].y_addr);
|
||||
lcdc_writel(lcdc_dev,WIN2_MST2,win->area[2].y_addr);
|
||||
lcdc_writel(lcdc_dev,WIN2_MST3,win->area[3].y_addr);
|
||||
if (win->area[0].state)
|
||||
lcdc_writel(lcdc_dev, WIN2_MST0,
|
||||
win->area[0].y_addr);
|
||||
if (win->area[1].state)
|
||||
lcdc_writel(lcdc_dev, WIN2_MST1,
|
||||
win->area[1].y_addr);
|
||||
if (win->area[2].state)
|
||||
lcdc_writel(lcdc_dev, WIN2_MST2,
|
||||
win->area[2].y_addr);
|
||||
if (win->area[3].state)
|
||||
lcdc_writel(lcdc_dev, WIN2_MST3,
|
||||
win->area[3].y_addr);
|
||||
}
|
||||
spin_unlock(&lcdc_dev->reg_lock);
|
||||
return 0;
|
||||
@ -1616,10 +1630,18 @@ static int win3_display(struct lcdc_device *lcdc_dev,
|
||||
for(i=0;i<win->area_num;i++)
|
||||
win->area[i].y_addr =
|
||||
win->area[i].smem_start + win->area[i].y_offset;
|
||||
lcdc_writel(lcdc_dev,WIN3_MST0,win->area[0].y_addr);
|
||||
lcdc_writel(lcdc_dev,WIN3_MST1,win->area[1].y_addr);
|
||||
lcdc_writel(lcdc_dev,WIN3_MST2,win->area[2].y_addr);
|
||||
lcdc_writel(lcdc_dev,WIN3_MST3,win->area[3].y_addr);
|
||||
if (win->area[0].state)
|
||||
lcdc_writel(lcdc_dev, WIN3_MST0,
|
||||
win->area[0].y_addr);
|
||||
if (win->area[1].state)
|
||||
lcdc_writel(lcdc_dev, WIN3_MST1,
|
||||
win->area[1].y_addr);
|
||||
if (win->area[2].state)
|
||||
lcdc_writel(lcdc_dev, WIN3_MST2,
|
||||
win->area[2].y_addr);
|
||||
if (win->area[3].state)
|
||||
lcdc_writel(lcdc_dev, WIN3_MST3,
|
||||
win->area[3].y_addr);
|
||||
}
|
||||
spin_unlock(&lcdc_dev->reg_lock);
|
||||
return 0;
|
||||
@ -2411,16 +2433,16 @@ static int win3_set_par(struct lcdc_device *lcdc_dev,
|
||||
screen->mode.upper_margin +
|
||||
screen->mode.vsync_len;
|
||||
}
|
||||
}
|
||||
if ((win->area[i].xact != win->area[i].xsize) ||
|
||||
(win->area[i].yact != win->area[i].ysize)) {
|
||||
pr_err("win[%d]->area[%d],not support scale\n",
|
||||
win->id, i);
|
||||
pr_err("xact=%d,yact=%d,xsize=%d,ysize=%d\n",
|
||||
win->area[i].xact,win->area[i].yact,
|
||||
win->area[i].xsize,win->area[i].ysize);
|
||||
win->area[i].xsize = win->area[i].xact;
|
||||
win->area[i].ysize = win->area[i].yact;
|
||||
if ((win->area[i].xact != win->area[i].xsize) ||
|
||||
(win->area[i].yact != win->area[i].ysize)) {
|
||||
pr_err("win[%d]->area[%d],not support scale\n",
|
||||
win->id, i);
|
||||
pr_err("xact=%d,yact=%d,xsize=%d,ysize=%d\n",
|
||||
win->area[i].xact, win->area[i].yact,
|
||||
win->area[i].xsize, win->area[i].ysize);
|
||||
win->area[i].xsize = win->area[i].xact;
|
||||
win->area[i].ysize = win->area[i].yact;
|
||||
}
|
||||
}
|
||||
}
|
||||
rk3288_win_2_3_reg_update(&lcdc_dev->driver,3);
|
||||
|
||||
Reference in New Issue
Block a user