video: rockchip: lcdc: 3288: fix iommu pagefault when user set win3 dsp size bigger...
authorHuang Jiachai <hjc@rock-chips.com>
Tue, 13 Oct 2015 10:12:14 +0000 (18:12 +0800)
committerGerrit Code Review <gerrit@rock-chips.com>
Wed, 14 Oct 2015 08:01:05 +0000 (16:01 +0800)
Change-Id: Icf474cf35c9bbf37deccd415e810f7d0a0c2142d
Signed-off-by: Huang Jiachai <hjc@rock-chips.com>
drivers/video/rockchip/lcdc/rk3288_lcdc.c

index 09ba332ca2d76abb0140ac4b50b978424b0b4cc6..63c019339bd2daffb099c3823213acc7b4e2574f 100755 (executable)
@@ -895,6 +895,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);
@@ -927,7 +929,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){
@@ -952,7 +955,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){
@@ -977,7 +981,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){
@@ -1002,7 +1007,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)
@@ -1682,10 +1688,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;
@@ -1704,10 +1718,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;
@@ -2499,16 +2521,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);