rk fb: add consider vop full mutile area for vsync register check
authorhjc <hjc@rock-chips.com>
Mon, 30 Mar 2015 10:02:23 +0000 (18:02 +0800)
committerhjc <hjc@rock-chips.com>
Mon, 30 Mar 2015 10:02:23 +0000 (18:02 +0800)
Signed-off-by: hjc <hjc@rock-chips.com>
drivers/video/rockchip/lcdc/rk3036_lcdc.c
drivers/video/rockchip/lcdc/rk312x_lcdc.c
drivers/video/rockchip/lcdc/rk3188_lcdc.c
drivers/video/rockchip/lcdc/rk3288_lcdc.c
drivers/video/rockchip/rk_fb.c
drivers/video/rockchip/rkfb_sysfs.c
include/linux/rk_fb.h

index 1ff927adcec02f048d9a89de7207157cc1bbcbb0..38747dad9d996dde0cd87a4417ca96ecc37097be 100755 (executable)
@@ -1011,7 +1011,8 @@ static int rk3036_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
 }
 
 static int rk3036_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv,
-                                    int win_id)
+                                    int win_id,
+                                    int area_id)
 {
        return dev_drv->win[win_id]->state;
 }
@@ -1450,14 +1451,14 @@ static int rk3036_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
 }
 
 static int rk3036_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
-                                   unsigned int *dsp_addr)
+                                   unsigned int dsp_addr[][4])
 {
        struct lcdc_device *lcdc_dev =
            container_of(dev_drv, struct lcdc_device, driver);
 
        if (lcdc_dev->clk_on) {
-               dsp_addr[0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
-               dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_MST);
+               dsp_addr[0][0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
+               dsp_addr[1][0] = lcdc_readl(lcdc_dev, WIN1_MST);
        }
        return 0;
 }
index 26c4ca84eec2958725358e46ee8b9d2e376b7299..786794ed2996b1ba31b2d08ba4e034b4c0249c92 100755 (executable)
@@ -1734,7 +1734,9 @@ static int rk312x_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
        return win_id;
 }
 
-static int rk312x_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv, int win_id)
+static int rk312x_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv,
+                                    int win_id,
+                                    int area_id)
 {
        struct lcdc_device *lcdc_dev =
                container_of(dev_drv, struct lcdc_device, driver);
@@ -2206,17 +2208,17 @@ static int rk312x_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
 }
 
 static int rk312x_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
-                                   unsigned int *dsp_addr)
+                                   unsigned int dsp_addr[][4])
 {
        struct lcdc_device *lcdc_dev =
            container_of(dev_drv, struct lcdc_device, driver);
 
        if (lcdc_dev->clk_on) {
-               dsp_addr[0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
+               dsp_addr[0][0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
                if (lcdc_dev->soc_type == VOP_RK3036)
-                       dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_MST);
+                       dsp_addr[1][0] = lcdc_readl(lcdc_dev, WIN1_MST);
                else if (lcdc_dev->soc_type == VOP_RK312X)
-                       dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_MST_RK312X);
+                       dsp_addr[1][0] = lcdc_readl(lcdc_dev, WIN1_MST_RK312X);
        }
        return 0;
 }
index b1eb96793a4bafcb6df2f07502b809b7209f3e4a..b689e9c33752cd0b02f25f32d7a5ddc9e6f63dcb 100755 (executable)
@@ -1083,7 +1083,9 @@ static int rk3188_lcdc_blank(struct rk_lcdc_driver *dev_drv,
        return 0;
 }
 
-static int rk3188_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv, int win_id)
+static int rk3188_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv,
+                                    int win_id,
+                                    int area_id)
 {
        return 0;
 }
@@ -1414,14 +1416,14 @@ int rk3188_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
 }
 
 
-static int rk3188_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,unsigned int *dsp_addr)
+static int rk3188_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,unsigned int dsp_addr[][4])
 {
        struct lcdc_device *lcdc_dev =
            container_of(dev_drv, struct lcdc_device, driver);
 
        if(lcdc_dev->clk_on){
-               dsp_addr[0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST0);
-               dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_MST);
+               dsp_addr[0][0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST0);
+               dsp_addr[1][0] = lcdc_readl(lcdc_dev, WIN1_MST);
        }
        return 0;
 }
index 89832b948992095fe9708f7d96364983dcfab529..65b2f354a6f2fa17425b9913d70ca1ed44dc8b4b 100755 (executable)
@@ -2563,27 +2563,43 @@ static int rk3288_lcdc_blank(struct rk_lcdc_driver *dev_drv,
        return 0;
 }
 
-static int rk3288_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv, int win_id)
+static int rk3288_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv,
+                                           int win_id, int area_id)
 {
         struct lcdc_device *lcdc_dev =
                 container_of(dev_drv, struct lcdc_device, driver);
         int win_status = 0;
+        u32 area_bit;
+
         if (win_id == 0)
                 win_status = lcdc_read_bit(lcdc_dev, WIN0_CTRL0, m_WIN0_EN);
         else if (win_id == 1)
                 win_status = lcdc_read_bit(lcdc_dev, WIN1_CTRL0, m_WIN1_EN);
-        else if (win_id == 2)
+        else if (win_id == 2) {
+                area_bit = m_WIN2_EN << (area_id + 4);
                 win_status = lcdc_read_bit(lcdc_dev, WIN2_CTRL0, m_WIN2_EN);
-        else if (win_id == 3)
+        } else if (win_id == 3) {
+                area_bit = m_WIN3_EN << (area_id + 4);
                 win_status = lcdc_read_bit(lcdc_dev, WIN3_CTRL0, m_WIN3_EN);
-        else if (win_id == 4)
+        else if (win_id == 4)
                 win_status = lcdc_read_bit(lcdc_dev, HWC_CTRL0, m_HWC_EN);
         else
-                pr_err("!!!%s,win_id :%d,unsupport!!!\n",__func__,win_id);
+                pr_err("!!!%s,win[%d]area[%d],unsupport!!!\n",__func__,win_id,area_id);
 
         return win_status;
 }
 
+static int rk3288_lcdc_get_area_num(struct rk_lcdc_driver *dev_drv,
+                                          unsigned int *area_support)
+{
+        area_support[0] = 1;
+        area_support[1] = 1;
+        area_support[2] = 4;
+        area_support[3] = 4;
+
+        return 0;
+}
+
 /*overlay will be do at regupdate*/
 static int rk3288_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
                               bool set)
@@ -3339,16 +3355,24 @@ int rk3288_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
 
        return ret;
 }
-static int rk3288_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,unsigned int *dsp_addr)
+
+static int rk3288_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,
+                                   unsigned int dsp_addr[][4])
 {
        struct lcdc_device *lcdc_dev =
            container_of(dev_drv, struct lcdc_device, driver);
        spin_lock(&lcdc_dev->reg_lock);
-       if(lcdc_dev->clk_on){
-               dsp_addr[0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
-               dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_YRGB_MST);
-               dsp_addr[2] = lcdc_readl(lcdc_dev, WIN2_MST0);
-               dsp_addr[3] = lcdc_readl(lcdc_dev, WIN3_MST0);
+       if (lcdc_dev->clk_on) {
+               dsp_addr[0][0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
+               dsp_addr[1][0] = lcdc_readl(lcdc_dev, WIN1_YRGB_MST);
+               dsp_addr[2][0] = lcdc_readl(lcdc_dev, WIN2_MST0);
+               dsp_addr[2][1] = lcdc_readl(lcdc_dev, WIN2_MST1);
+               dsp_addr[2][2] = lcdc_readl(lcdc_dev, WIN2_MST2);
+               dsp_addr[2][3] = lcdc_readl(lcdc_dev, WIN2_MST3);
+               dsp_addr[3][0] = lcdc_readl(lcdc_dev, WIN3_MST0);
+               dsp_addr[3][1] = lcdc_readl(lcdc_dev, WIN3_MST1);
+               dsp_addr[3][2] = lcdc_readl(lcdc_dev, WIN3_MST2);
+               dsp_addr[3][3] = lcdc_readl(lcdc_dev, WIN3_MST3);
        }
        spin_unlock(&lcdc_dev->reg_lock);
        return 0;
@@ -3653,6 +3677,7 @@ static struct rk_lcdc_drv_ops lcdc_drv_ops = {
        .suspend                = rk3288_lcdc_early_suspend,
        .resume                 = rk3288_lcdc_early_resume,
        .get_win_state          = rk3288_lcdc_get_win_state,
+       .area_support_num = rk3288_lcdc_get_area_num,
        .ovl_mgr                = rk3288_lcdc_ovl_mgr,
        .get_disp_info          = rk3288_lcdc_get_disp_info,
        .fps_mgr                = rk3288_lcdc_fps_mgr,
index 31bdd472dfa7834420f296c4a61300a1dd4cee06..96cd1b58fa638e7c14e3443be38d68e12c3a90ad 100644 (file)
@@ -1653,6 +1653,70 @@ static struct rk_fb_reg_win_data *rk_fb_get_win_data(struct rk_fb_reg_data
        return win_data;
 }
 
+static int rk_fb_reg_effect(struct rk_lcdc_driver *dev_drv,
+                            struct rk_fb_reg_data *regs,
+                            int count)
+{
+       struct rk_fb *rk_fb = platform_get_drvdata(fb_pdev);
+       int i, j, wait_for_vsync = false;
+       unsigned int dsp_addr[5][4];
+       unsigned int area_support[5] = {1, 1, 1, 1, 1};
+       int win_status = 0;
+       u32 temp;
+
+       memset(dsp_addr, 0, sizeof(dsp_addr));
+       if (dev_drv->ops->get_dsp_addr)
+               dev_drv->ops->get_dsp_addr(dev_drv, dsp_addr);
+
+       if (dev_drv->ops->area_support_num)
+               dev_drv->ops->area_support_num(dev_drv, area_support);
+
+       for (i = 0; i < dev_drv->lcdc_win_num; i++) {
+               if (rk_fb->disp_policy == DISPLAY_POLICY_BOX &&
+                   (!strcmp(dev_drv->win[i]->name, "hwc")))
+                       continue;
+
+               for (j = 0;j < RK_WIN_MAX_AREA; j++) {
+                       if ((j > 0) && (area_support[i] == 1)) {
+                               continue;
+                       }
+                       temp = dsp_addr[i][j];
+                       win_status =
+                               dev_drv->ops->get_win_state(dev_drv, i, j);
+                       if (dev_drv->win[i]->area[j].state == 1) {
+                               u32 new_start =
+                                       dev_drv->win[i]->area[j].smem_start +
+                                       dev_drv->win[i]->area[j].y_offset;
+                               u32 reg_start = dsp_addr[i][j];
+                               if ((rk_fb->disp_policy ==
+                                       DISPLAY_POLICY_BOX) &&
+                                       (dev_drv->suspend_flag))
+                                       continue;
+                               if (unlikely(new_start != reg_start)) {
+                                       wait_for_vsync = true;
+                                       dev_info(dev_drv->dev,
+                                                "win%d:new_addr:0x%08x cur_addr:0x%08x--%d\n",
+                                                i, new_start, reg_start, 101 - count);
+                                       break;
+                               }
+                       } else if (dev_drv->win[i]->area[j].state == 0) {
+                               if (dev_drv->ops->get_win_state) {
+                                       win_status =
+                                       dev_drv->ops->get_win_state(dev_drv, i, j);
+                                       if (win_status)
+                                               wait_for_vsync = true;
+                               }
+                       } else {
+                               pr_err("!!!win[%d]state:%d,error!!!\n",
+                                      i, dev_drv->win[i]->state);
+                       }
+                       printk("win[%d]area[%d]reg_start = 0x%x,state=%d\n",i,j,temp,win_status);
+               }
+       }
+
+       return wait_for_vsync;
+}
+
 static void rk_fb_update_reg(struct rk_lcdc_driver *dev_drv,
                             struct rk_fb_reg_data *regs)
 {
@@ -1663,9 +1727,7 @@ static void rk_fb_update_reg(struct rk_lcdc_driver *dev_drv,
        struct rk_fb_reg_win_data *win_data;
        bool wait_for_vsync;
        int count = 100;
-       unsigned int dsp_addr[4];
        long timeout;
-       int win_status = 0;
 
        /* acq_fence wait */
        for (i = 0; i < regs->win_num; i++) {
@@ -1713,45 +1775,12 @@ static void rk_fb_update_reg(struct rk_lcdc_driver *dev_drv,
                                ktime_compare(dev_drv->vsync_info.timestamp, timestamp) > 0,
                                msecs_to_jiffies(25));
 
-               dev_drv->ops->get_dsp_addr(dev_drv, dsp_addr);
-               wait_for_vsync = false;
-               for (i = 0; i < dev_drv->lcdc_win_num; i++) {
-                        if (rk_fb->disp_policy == DISPLAY_POLICY_BOX &&
-                           (!strcmp(dev_drv->win[i]->name, "hwc")))
-                               continue;
-                       if (dev_drv->win[i]->state == 1) {
-                               u32 new_start =
-                                   dev_drv->win[i]->area[0].smem_start +
-                                   dev_drv->win[i]->area[0].y_offset;
-                               u32 reg_start = dsp_addr[i];
-
-                               if ((rk_fb->disp_policy ==
-                                    DISPLAY_POLICY_BOX) &&
-                                   (dev_drv->suspend_flag))
-                                       continue;
-                               if (unlikely(new_start != reg_start)) {
-                                       wait_for_vsync = true;
-                                       dev_info(dev_drv->dev,
-                                              "win%d:new_addr:0x%08x cur_addr:0x%08x--%d\n",
-                                              i, new_start, reg_start, 101 - count);
-                                       break;
-                               }
-                       } else if (dev_drv->win[i]->state == 0) {
-                                if (dev_drv->ops->get_win_state) {
-                                        win_status =
-                                        dev_drv->ops->get_win_state(dev_drv, i);
-                                        if (win_status)
-                                               wait_for_vsync = true;
-                                }
-                       } else {
-                                pr_err("!!!win[%d]state:%d,error!!!\n",
-                                        i, dev_drv->win[i]->state);
-                       }
-               }
+               wait_for_vsync = rk_fb_reg_effect(dev_drv, regs, count);
        } while (wait_for_vsync && count--);
 #ifdef H_USE_FENCE
        sw_sync_timeline_inc(dev_drv->timeline, 1);
 #endif
+
        if (dev_drv->front_regs) {
 #if defined(CONFIG_ROCKCHIP_IOMMU)
                if (dev_drv->iommu_enabled) {
@@ -2338,7 +2367,7 @@ static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd,
        int num_buf;    /* buffer_number */
        int ret;
        struct rk_fb_win_cfg_data win_data;
-       unsigned int dsp_addr[4];
+       unsigned int dsp_addr[4][4];
        int list_stat;
 
        int win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
@@ -2468,7 +2497,7 @@ static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd,
                dev_drv->ops->open(dev_drv, win_id, enable);
                break;
        case RK_FBIOGET_ENABLE:
-               enable = dev_drv->ops->get_win_state(dev_drv, win_id);
+               enable = dev_drv->ops->get_win_state(dev_drv, win_id, 0);
                if (copy_to_user(argp, &enable, sizeof(enable)))
                        return -EFAULT;
                break;
index d8a992df7c26c5e478c69aaa4b5c008d0511e8b5..3f9327e8181c88008f6cb091cdea9ccd58ca0db5 100644 (file)
@@ -277,7 +277,7 @@ static ssize_t show_fb_state(struct device *dev,
        struct rk_lcdc_driver *dev_drv = fb_par->lcdc_drv;
 
        int win_id = dev_drv->ops->fb_get_win_id(dev_drv, fbi->fix.id);
-       int state = dev_drv->ops->get_win_state(dev_drv, win_id);
+       int state = dev_drv->ops->get_win_state(dev_drv, win_id, 0);
 
        return snprintf(buf, PAGE_SIZE, "%s\n", state ? "enabled" : "disabled");
 }
index 43cf5c86ef806f89495e373b27cef9654dda9e13..39fc2a76dfe492b09681cc1aebf248493a9ec4b1 100644 (file)
@@ -442,7 +442,7 @@ struct rk_lcdc_drv_ops {
        int (*post_dspbuf)(struct rk_lcdc_driver *dev_drv, u32 rgb_mst,
                           int format, u16 xact, u16 yact, u16 xvir);
 
-       int (*get_win_state) (struct rk_lcdc_driver *dev_drv, int layer_id);
+       int (*get_win_state) (struct rk_lcdc_driver *dev_drv, int layer_id, int area_id);
        int (*ovl_mgr) (struct rk_lcdc_driver *dev_drv, int swap, bool set);    /*overlay manager*/
        int (*fps_mgr) (struct rk_lcdc_driver *dev_drv, int fps, bool set);
        int (*fb_get_win_id) (struct rk_lcdc_driver *dev_drv, const char *id);  /*find layer for fb*/
@@ -459,7 +459,7 @@ struct rk_lcdc_drv_ops {
        int (*dpi_open) (struct rk_lcdc_driver *dev_drv, bool open);
        int (*dpi_win_sel) (struct rk_lcdc_driver *dev_drv, int layer_id);
        int (*dpi_status) (struct rk_lcdc_driver *dev_drv);
-       int (*get_dsp_addr)(struct rk_lcdc_driver *dev_drv,unsigned int *dsp_addr);
+       int (*get_dsp_addr)(struct rk_lcdc_driver *dev_drv, unsigned int dsp_addr[][4]);
        int (*set_dsp_cabc) (struct rk_lcdc_driver *dev_drv, int mode, int calc, int up, int down, int global);
        int (*set_dsp_bcsh_hue) (struct rk_lcdc_driver *dev_drv,int sin_hue, int cos_hue);
        int (*set_dsp_bcsh_bcs)(struct rk_lcdc_driver *dev_drv,bcsh_bcs_mode mode,int value);
@@ -474,6 +474,7 @@ struct rk_lcdc_drv_ops {
                             struct overscan *overscan);
        int (*dsp_black) (struct rk_lcdc_driver *dev_drv, int enable);
        int (*backlight_close)(struct rk_lcdc_driver *dev_drv, int enable);
+       int (*area_support_num)(struct rk_lcdc_driver *dev_drv, unsigned int *area_support);
 };
 
 struct rk_fb_area_par {