video: rockchip: vop: 3288: add parse dsp mode for VR
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / lcdc / rk3288_lcdc.c
index 09ba332ca2d76abb0140ac4b50b978424b0b4cc6..1f300c4d2bfff92d9656c554c069e3cf56cb73d8 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)
@@ -1079,7 +1085,6 @@ static int rk3288_lcdc_mmu_en(struct rk_lcdc_driver *dev_drv)
                pr_info("%s,clk_on = %d\n", __func__, lcdc_dev->clk_on);
                return 0;
        }
-#if defined(CONFIG_ROCKCHIP_IOMMU)
        if (dev_drv->iommu_enabled) {
                if (!lcdc_dev->iommu_status && dev_drv->mmu_dev) {
 
@@ -1097,7 +1102,6 @@ static int rk3288_lcdc_mmu_en(struct rk_lcdc_driver *dev_drv)
                        rockchip_iovmm_activate(dev_drv->dev);
                }
        }
-#endif
        return 0;
 }
 
@@ -1152,7 +1156,8 @@ static void rk3288_lcdc_bcsh_path_sel(struct rk_lcdc_driver *dev_drv)
 }
 
 static int rk3288_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact,
-                                 u16 *yact, int *format, u32 *dsp_addr)
+                                 u16 *yact, int *format, u32 *dsp_addr,
+                                 int *ymirror)
 {
        struct lcdc_device *lcdc_dev = container_of(dev_drv,
                                                    struct lcdc_device, driver);
@@ -1174,11 +1179,13 @@ static int rk3288_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact,
 }
 
 static int rk3288_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst,
-                             int format, u16 xact, u16 yact, u16 xvir)
+                             int format, u16 xact, u16 yact, u16 xvir,
+                             int ymirror)
 {
        struct lcdc_device *lcdc_dev = container_of(dev_drv,
                                                    struct lcdc_device, driver);
        u32 val, mask;
+       struct rk_lcdc_win *win = dev_drv->win[0];
        int swap = (format == RGB888) ? 1 : 0;
 
        mask = m_WIN0_DATA_FMT | m_WIN0_RB_SWAP;
@@ -1193,6 +1200,8 @@ static int rk3288_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst,
        lcdc_writel(lcdc_dev, WIN0_YRGB_MST, rgb_mst);
 
        lcdc_cfg_done(lcdc_dev);
+       win->state = 1;
+       win->last_state = 1;
 
        return 0;
 }
@@ -1345,6 +1354,11 @@ static int rk3288_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
                        mask = m_EDP_OUT_EN;
                        val = v_EDP_OUT_EN(1);
                        break;
+               default:
+                       mask = 0;
+                       val = 0;
+                       pr_info("unknow screen type: %d\n", screen->type);
+                       break;
                }
                if (dev_drv->version == VOP_FULL_RK3288_V1_1) {
                        mask |= m_HDMI_DCLK_OUT_EN;
@@ -1561,7 +1575,6 @@ static int rk3288_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
                rk3288_lcdc_pre_init(dev_drv);
                rk3288_lcdc_clk_enable(lcdc_dev);
                rk3288_lcdc_enable_irq(dev_drv);
-#if defined(CONFIG_ROCKCHIP_IOMMU)
                if (dev_drv->iommu_enabled) {
                        if (!dev_drv->mmu_dev) {
                                dev_drv->mmu_dev =
@@ -1576,7 +1589,6 @@ static int rk3288_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
                                }
                        }
                }
-#endif
                rk3288_lcdc_reg_restore(lcdc_dev);
                /*if (dev_drv->iommu_enabled)
                   rk3368_lcdc_mmu_en(dev_drv); */
@@ -1608,14 +1620,12 @@ static int rk3288_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
        if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
                rk3288_lcdc_disable_irq(lcdc_dev);
                rk3288_lcdc_reg_update(dev_drv);
-#if defined(CONFIG_ROCKCHIP_IOMMU)
                if (dev_drv->iommu_enabled) {
                        if (dev_drv->mmu_dev) {
                                rockchip_iovmm_deactivate(dev_drv->dev);
                                lcdc_dev->iommu_status = 0;
                        }
                }
-#endif
                rk3288_lcdc_clk_disable(lcdc_dev);
                rockchip_clear_system_status(sys_status);
        }
@@ -1682,10 +1692,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 +1722,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 +2525,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);
@@ -3936,9 +3962,6 @@ static irqreturn_t rk3288_lcdc_isr(int irq, void *dev_id)
                        complete(&(lcdc_dev->driver.frame_done));
                        spin_unlock(&(lcdc_dev->driver.cpl_lock));
                }
-#ifdef CONFIG_DRM_ROCKCHIP
-               lcdc_dev->driver.irq_call_back(&lcdc_dev->driver);
-#endif 
                lcdc_dev->driver.vsync_info.timestamp = timestamp;
                wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
 
@@ -4038,14 +4061,16 @@ static int rk3288_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
                dev_drv->bcsh.cos_hue = (val >> 8) & 0xff;
        }
 
-#if defined(CONFIG_ROCKCHIP_IOMMU)
        if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
                dev_drv->iommu_enabled = 0;
        else
                dev_drv->iommu_enabled = val;
-#else
-       dev_drv->iommu_enabled = 0;
-#endif
+
+       if (of_property_read_u32(np, "rockchip,dsp_mode", &val))
+               dev_drv->dsp_mode = DEFAULT_MODE;
+       else
+               dev_drv->dsp_mode = val;
+
        return 0;
 }