rk fb: new framework test ok at rk3188
authorhjc <hjc@rock-chips.com>
Fri, 7 Mar 2014 03:49:23 +0000 (11:49 +0800)
committerhjc <hjc@rock-chips.com>
Fri, 7 Mar 2014 04:30:05 +0000 (12:30 +0800)
this commit depend on the hwc commit:
commit 59966e5cc0530d936435052d187fbe574684f21e
Author: huangds <hds@rock-chips.com>
Date:   Fri Mar 7 11:17:56 2014 +0800

    lcdc ok ,enable hwc

drivers/video/rockchip/lcdc/rk3188_lcdc.c
drivers/video/rockchip/rk_fb.c
drivers/video/rockchip/rkfb_sysfs.c [changed mode: 0644->0755]
include/linux/rk_fb.h
include/linux/rk_screen.h

index 7d24755f3a4e73f37c8a4d9f617c1e12d8db76cd..8d26fe0475c8f0493c4e2cbd4b6f3fe3cda5c489 100755 (executable)
@@ -189,37 +189,37 @@ static void rk3188_lcdc_read_reg_defalut_cfg(struct lcdc_device
                        win0->scale_cbcr_y = (value >> 16) & 0xffff;
                        break;
                case WIN0_ACT_INFO:
-                       win0->xact = (((value >> 0) & 0x1fff) + 1);
-                       win0->yact = (((value >> 16) & 0x1fff) + 1);
+                       win0->area[0].xact = (((value >> 0) & 0x1fff) + 1);
+                       win0->area[0].yact = (((value >> 16) & 0x1fff) + 1);
                        break;
                case WIN0_DSP_ST:
-                       win0->dsp_stx = (value >> 0) & 0xfff;
-                       win0->dsp_sty = (value >> 16) & 0xfff;
+                       win0->area[0].dsp_stx = (value >> 0) & 0xfff;
+                       win0->area[0].dsp_sty = (value >> 16) & 0xfff;
                        break;
                case WIN0_DSP_INFO:
-                       win0->xsize = (((value >> 0) & 0x7ff) + 1);
-                       win0->ysize = (((value >> 16) & 0x7ff) + 1);
+                       win0->area[0].xsize = (((value >> 0) & 0x7ff) + 1);
+                       win0->area[0].ysize = (((value >> 16) & 0x7ff) + 1);
                        break;
                case WIN_VIR:
-                       win0->vir_stride = (value >> 0) & 0x1fff;
-                       win1->vir_stride = (value) & 0x1fff0000;
+                       win0->area[0].y_vir_stride = (value >> 0) & 0x1fff;
+                       win1->area[0].y_vir_stride = (value) & 0x1fff0000;
                        break;
                case WIN0_YRGB_MST0:
-                       win0->y_addr = value >> 0;
+                       win0->area[0].y_addr = value >> 0;
                        break;
                case WIN0_CBR_MST0:
-                       win0->uv_addr = value >> 0;
+                       win0->area[0].uv_addr = value >> 0;
                        break;
                case WIN1_DSP_INFO:
-                       win1->xsize = (((value >> 0) & 0x7ff) + 1);
-                       win1->ysize = (((value >> 16) & 0x7ff) + 1);
+                       win1->area[0].xsize = (((value >> 0) & 0x7ff) + 1);
+                       win1->area[0].ysize = (((value >> 16) & 0x7ff) + 1);
                        break;
                case WIN1_DSP_ST:
-                       win1->dsp_stx = (value >> 0) & 0xfff;
-                       win1->dsp_sty = (value >> 16) & 0xfff;
+                       win1->area[0].dsp_stx = (value >> 0) & 0xfff;
+                       win1->area[0].dsp_sty = (value >> 16) & 0xfff;
                        break;
                case WIN1_MST:
-                       win1->y_addr = value >> 0;
+                       win1->area[0].y_addr = value >> 0;
                        break;
                default:
                        DBG(2, "%s:uncare reg\n", __func__);
@@ -337,7 +337,6 @@ static int rk3188_lcdc_alpha_cfg(struct lcdc_device *lcdc_dev)
        u32 *_pv = (u32 *) lcdc_dev->regsbak;
        _pv += (DSP_CTRL0 >> 2);
        win0_top = ((*_pv) & (m_WIN0_TOP)) >> 8;
-
        if (win0_top && (lcdc_dev->atv_layer_cnt >= 2) && (win0_alpha_en)) {
                lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, m_WIN0_ALPHA_EN |
                             m_WIN1_ALPHA_EN, v_WIN0_ALPHA_EN(1) |
@@ -371,7 +370,6 @@ static int rk3188_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
        struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
        int timeout;
        unsigned long flags;
-
        spin_lock(&lcdc_dev->reg_lock);
        if (likely(lcdc_dev->clk_on)) {
                lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
@@ -389,30 +387,32 @@ static int rk3188_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
                            v_X_SCL_FACTOR(win0->scale_cbcr_x) |
                            v_Y_SCL_FACTOR(win0->scale_cbcr_y));
                lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_FORMAT, v_WIN0_FORMAT(win0->fmt_cfg));
-               lcdc_writel(lcdc_dev, WIN0_ACT_INFO, v_ACT_WIDTH(win0->xact) |
-                           v_ACT_HEIGHT(win0->yact));
-               lcdc_writel(lcdc_dev, WIN0_DSP_ST, v_DSP_STX(win0->dsp_stx) |
-                           v_DSP_STY(win0->dsp_sty));
-               lcdc_writel(lcdc_dev, WIN0_DSP_INFO, v_DSP_WIDTH(win0->xsize) |
-                           v_DSP_HEIGHT(win0->ysize));
+               lcdc_writel(lcdc_dev, WIN0_ACT_INFO, v_ACT_WIDTH(win0->area[0].xact) |
+                           v_ACT_HEIGHT(win0->area[0].yact));
+               lcdc_writel(lcdc_dev, WIN0_DSP_ST, v_DSP_STX(win0->area[0].dsp_stx) |
+                           v_DSP_STY(win0->area[0].dsp_sty));
+               lcdc_writel(lcdc_dev, WIN0_DSP_INFO, v_DSP_WIDTH(win0->area[0].xsize) |
+                           v_DSP_HEIGHT(win0->area[0].ysize));
                lcdc_msk_reg(lcdc_dev, WIN_VIR, m_WIN0_VIR,
-                            v_WIN0_VIR_VAL(win0->vir_stride));
-               lcdc_writel(lcdc_dev, WIN0_YRGB_MST0, win0->y_addr);
-               lcdc_writel(lcdc_dev, WIN0_CBR_MST0, win0->uv_addr);
-               lcdc_writel(lcdc_dev, WIN1_DSP_INFO, v_DSP_WIDTH(win1->xsize) |
-                           v_DSP_HEIGHT(win1->ysize));
-               lcdc_writel(lcdc_dev, WIN1_DSP_ST, v_DSP_STX(win1->dsp_stx) |
-                           v_DSP_STY(win1->dsp_sty));
-               lcdc_msk_reg(lcdc_dev, WIN_VIR, m_WIN1_VIR, win1->vir_stride);
+                            v_WIN0_VIR_VAL(win0->area[0].y_vir_stride));
+               lcdc_writel(lcdc_dev, WIN0_YRGB_MST0, win0->area[0].y_addr);
+               lcdc_writel(lcdc_dev, WIN0_CBR_MST0, win0->area[0].uv_addr);
+               lcdc_writel(lcdc_dev, WIN1_DSP_INFO, v_DSP_WIDTH(win1->area[0].xsize) |
+                           v_DSP_HEIGHT(win1->area[0].ysize));
+               lcdc_writel(lcdc_dev, WIN1_DSP_ST, v_DSP_STX(win1->area[0].dsp_stx) |
+                           v_DSP_STY(win1->area[0].dsp_sty));
+               lcdc_msk_reg(lcdc_dev, WIN_VIR, m_WIN1_VIR, ((win1->area[0].y_vir_stride)&0x1fff)<<16);
                lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_FORMAT,
                             v_WIN1_FORMAT(win1->fmt_cfg));
-               lcdc_writel(lcdc_dev, WIN1_MST, win1->y_addr);
+               lcdc_writel(lcdc_dev, WIN1_MST, win1->area[0].y_addr);
+               //printk("rk3188_lcdc_reg_update,win_num=%d\n",dev_drv->atv_layer_cnt);
                rk3188_lcdc_alpha_cfg(lcdc_dev);
                lcdc_cfg_done(lcdc_dev);
 
        }
        spin_unlock(&lcdc_dev->reg_lock);
-       if (dev_drv->wait_fs) {
+       //if (dev_drv->wait_fs) {
+       if (0) {
                spin_lock_irqsave(&dev_drv->cpl_lock, flags);
                init_completion(&dev_drv->frame_done);
                spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
@@ -647,6 +647,148 @@ static int rk3188_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
        return 0;
 }
 
+static int win0_display(struct lcdc_device *lcdc_dev,
+                       struct rk_lcdc_win *win)
+{
+       u32 y_addr;
+       u32 uv_addr;
+       y_addr = win->area[0].smem_start+win->area[0].y_offset;//win->smem_start + win->y_offset;
+       uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
+       DBG(2, "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x\n",
+           lcdc_dev->id, __func__, y_addr, uv_addr);
+       //printk("y_offset=0x%x,y_addr=0x%x\n",win->area[0].y_offset,y_addr);
+       spin_lock(&lcdc_dev->reg_lock);
+       if (likely(lcdc_dev->clk_on)) {
+               win->area[0].y_addr = y_addr;
+               win->area[0].uv_addr = uv_addr;
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+
+       return 0;
+
+}
+
+static int win1_display(struct lcdc_device *lcdc_dev,
+                       struct rk_lcdc_win *win)
+{
+       u32 y_addr;
+       u32 uv_addr;
+       y_addr = win->area[0].smem_start + win->area[0].y_offset;
+       uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
+       DBG(2, "lcdc%d>>%s>>y_addr:0x%x>>uv_addr:0x%x\n",
+           lcdc_dev->id, __func__, y_addr, uv_addr);
+
+       spin_lock(&lcdc_dev->reg_lock);
+       if (likely(lcdc_dev->clk_on))
+               win->area[0].y_addr = y_addr;
+       spin_unlock(&lcdc_dev->reg_lock);
+
+       return 0;
+}
+
+static int rk3188_lcdc_win_display(struct rk_lcdc_driver *dev_drv, struct rk_lcdc_win *win,int win_id)
+{
+       struct lcdc_device *lcdc_dev = container_of(dev_drv,
+                               struct lcdc_device, driver);
+       struct rk_screen *screen = dev_drv->cur_screen;
+       u32 mask, val;
+
+       lcdc_dev->atv_layer_cnt = dev_drv->atv_layer_cnt;
+       if (!screen) {
+               dev_err(dev_drv->dev, "screen is null!\n");
+               return -ENOENT;
+       }
+       if (win_id == 0) {
+               win0_display(lcdc_dev, win);
+       } else if (win_id == 1) {
+               win1_display(lcdc_dev, win);
+       } else {
+               dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
+               return -EINVAL;
+       }
+       /*this is the first frame of the system ,enable frame start interrupt */
+       if ((dev_drv->first_frame)) {
+               dev_drv->first_frame = 0;
+               mask = m_HS_INT_CLEAR | m_HS_INT_EN | m_FS_INT_CLEAR |
+                   m_FS_INT_EN | m_LF_INT_EN | m_LF_INT_CLEAR |
+                   m_LF_INT_NUM | m_BUS_ERR_INT_CLEAR | m_BUS_ERR_INT_EN;
+               val = v_FS_INT_CLEAR(1) | v_FS_INT_EN(1) | v_HS_INT_CLEAR(1) |
+                   v_HS_INT_EN(0) | v_LF_INT_CLEAR(1) | v_LF_INT_EN(1) |
+                   v_LF_INT_NUM(screen->mode.vsync_len + screen->mode.upper_margin +
+                   screen->mode.yres -1);
+               lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
+               lcdc_cfg_done(lcdc_dev);
+       }
+
+}
+
+static int rk3188_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
+{
+       struct lcdc_device *lcdc_dev = container_of(dev_drv,
+                               struct lcdc_device, driver);
+       struct rk_lcdc_win *win = NULL;
+       struct rk_screen *screen = dev_drv->cur_screen;
+       u32 mask, val;
+#if defined(WAIT_FOR_SYNC)
+       int timeout;
+       unsigned long flags;
+#endif
+       lcdc_dev->atv_layer_cnt = dev_drv->atv_layer_cnt;
+       if (!screen) {
+               dev_err(dev_drv->dev, "screen is null!\n");
+               return -ENOENT;
+       }
+       if (win_id == 0) {
+               win = dev_drv->win[0];
+               win0_display(lcdc_dev, win);
+               if(win->z_order == 0){
+                       dev_drv->ops->ovl_mgr(dev_drv, 0, 1);
+               }else{
+                       dev_drv->ops->ovl_mgr(dev_drv, 1, 1);
+               }
+       } else if (win_id == 1) {
+               win = dev_drv->win[1];
+               win1_display(lcdc_dev, win);
+       } else {
+               dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
+               return -EINVAL;
+       }
+
+
+       /*this is the first frame of the system ,enable frame start interrupt */
+       if ((dev_drv->first_frame)) {
+               dev_drv->first_frame = 0;
+               mask = m_HS_INT_CLEAR | m_HS_INT_EN | m_FS_INT_CLEAR |
+                   m_FS_INT_EN | m_LF_INT_EN | m_LF_INT_CLEAR |
+                   m_LF_INT_NUM | m_BUS_ERR_INT_CLEAR | m_BUS_ERR_INT_EN;
+               val = v_FS_INT_CLEAR(1) | v_FS_INT_EN(1) | v_HS_INT_CLEAR(1) |
+                   v_HS_INT_EN(0) | v_LF_INT_CLEAR(1) | v_LF_INT_EN(1) |
+                   v_LF_INT_NUM(screen->mode.vsync_len + screen->mode.upper_margin +
+                   screen->mode.yres -1);
+               lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
+               lcdc_cfg_done(lcdc_dev);
+       }
+#if defined(WAIT_FOR_SYNC)
+       spin_lock_irqsave(&dev_drv->cpl_lock, flags);
+       init_completion(&dev_drv->frame_done);
+       spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
+       timeout = wait_for_completion_timeout(&dev_drv->frame_done,
+                                             msecs_to_jiffies(dev_drv->
+                                                              cur_screen->ft +
+                                                              5));
+       if (!timeout && (!dev_drv->frame_done.done)) {
+               dev_info(dev_drv->dev, "wait for new frame start time out!\n");
+               return -ETIMEDOUT;
+       }
+#endif
+       //printk("rk3188_lcdc_pan_display,win_num=%d\n",dev_drv->atv_layer_cnt);
+
+       rk3188_lcdc_reg_update(dev_drv);
+
+       return 0;
+}
+
+
 static int win0_set_par(struct lcdc_device *lcdc_dev,
                        struct rk_screen *screen, struct rk_lcdc_win *win)
 {
@@ -657,15 +799,15 @@ static int win0_set_par(struct lcdc_device *lcdc_dev,
        u32 ScaleCbrY = 0x1000;
        u8 fmt_cfg = 0;
        char fmt[9] = "NULL";
-       xact = win->xact;
-       yact = win->yact;
-       xvir = win->xvir;
-       yvir = win->yvir;
-       xpos = win->xpos + screen->mode.left_margin + screen->mode.hsync_len;
-       ypos = win->ypos + screen->mode.upper_margin + screen->mode.vsync_len;
-
-       ScaleYrgbX = CalScale(xact, win->xsize);
-       ScaleYrgbY = CalScale(yact, win->ysize);
+       xact = win->area[0].xact;//win->xact;
+       yact = win->area[0].yact;
+       xvir = win->area[0].xvir;
+       yvir = win->area[0].yvir;
+       xpos = win->area[0].xpos + screen->mode.left_margin + screen->mode.hsync_len;
+       ypos = win->area[0].ypos + screen->mode.upper_margin + screen->mode.vsync_len;
+
+       ScaleYrgbX = CalScale(xact, win->area[0].xsize);
+       ScaleYrgbY = CalScale(yact, win->area[0].ysize);
        switch (win->format) {
        case ARGB888:
        case XBGR888:
@@ -680,18 +822,18 @@ static int win0_set_par(struct lcdc_device *lcdc_dev,
                break;
        case YUV422:
                fmt_cfg = 5;
-               ScaleCbrX = CalScale((xact / 2), win->xsize);
-               ScaleCbrY = CalScale(yact, win->ysize);
+               ScaleCbrX = CalScale((xact / 2), win->area[0].xsize);
+               ScaleCbrY = CalScale(yact, win->area[0].ysize);
                break;
        case YUV420:
                fmt_cfg = 4;
-               ScaleCbrX = CalScale(xact / 2, win->xsize);
-               ScaleCbrY = CalScale(yact / 2, win->ysize);
+               ScaleCbrX = CalScale(xact / 2, win->area[0].xsize);
+               ScaleCbrY = CalScale(yact / 2, win->area[0].ysize);
                break;
        case YUV444:
                fmt_cfg = 6;
-               ScaleCbrX = CalScale(xact, win->xsize);
-               ScaleCbrY = CalScale(yact, win->ysize);
+               ScaleCbrX = CalScale(xact, win->area[0].xsize);
+               ScaleCbrY = CalScale(yact, win->area[0].ysize);
                break;
        default:
                dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
@@ -702,7 +844,7 @@ static int win0_set_par(struct lcdc_device *lcdc_dev,
        DBG(1, "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
                ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
                __func__, get_format_string(win->format, fmt), xact,
-               yact, win->xsize, win->ysize, xvir, yvir, xpos, ypos);
+               yact, win->area[0].xsize, win->area[0].ysize, xvir, yvir, xpos, ypos);
 
        spin_lock(&lcdc_dev->reg_lock);
        if (likely(lcdc_dev->clk_on)) {
@@ -711,30 +853,26 @@ static int win0_set_par(struct lcdc_device *lcdc_dev,
                win->scale_cbcr_x = ScaleCbrX;
                win->scale_cbcr_y = ScaleCbrY;
                win->fmt_cfg = fmt_cfg;
-               win->dsp_stx = xpos;
-               win->dsp_sty = ypos;
+               win->area[0].dsp_stx = xpos;
+               win->area[0].dsp_sty = ypos;
+               
                switch (win->format) {
                case XBGR888:
                case ABGR888:
-                       win->vir_stride = v_ARGB888_VIRWIDTH(xvir);
                        win->swap_rb = 1;
                        break;
                case ARGB888:
-                       win->vir_stride = v_ARGB888_VIRWIDTH(xvir);
                        win->swap_rb = 0;
                        break;
                case RGB888:
-                       win->vir_stride = v_RGB888_VIRWIDTH(xvir);
                        win->swap_rb = 0;
                        break;
                case RGB565:
-                       win->vir_stride = v_RGB565_VIRWIDTH(xvir);
                        win->swap_rb = 0;
                        break;
                case YUV422:
                case YUV420:
                case YUV444:
-                       win->vir_stride = v_YUV_VIRWIDTH(xvir);
                        win->swap_rb = 0;
                        break;
                default:
@@ -756,43 +894,39 @@ static int win1_set_par(struct lcdc_device *lcdc_dev,
        u32 xact, yact, xvir, yvir, xpos, ypos;
        u8 fmt_cfg;
        char fmt[9] = "NULL";
-       xact = win->xact;
-       yact = win->yact;
-       xvir = win->xvir;
-       yvir = win->yvir;
-       xpos = win->xpos + screen->mode.left_margin + screen->mode.hsync_len;
-       ypos = win->ypos + screen->mode.upper_margin + screen->mode.vsync_len;
+       xact = win->area[0].xact;
+       yact = win->area[0].yact;
+       xvir = win->area[0].xvir;
+       yvir = win->area[0].yvir;
+       xpos = win->area[0].xpos + screen->mode.left_margin + screen->mode.hsync_len;
+       ypos = win->area[0].ypos + screen->mode.upper_margin + screen->mode.vsync_len;
 
        DBG(1, "lcdc%d>>%s>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
                ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
                __func__, get_format_string(win->format, fmt), xact, yact,
-               win->xsize, win->ysize, xvir, yvir, xpos, ypos);
+               win->area[0].xsize, win->area[0].ysize, xvir, yvir, xpos, ypos);
 
        spin_lock(&lcdc_dev->reg_lock);
        if (likely(lcdc_dev->clk_on)) {
-               win->dsp_stx = xpos;
-               win->dsp_sty = ypos;
+               win->area[0].dsp_stx = xpos;
+               win->area[0].dsp_sty = ypos;
                switch (win->format) {
                case XBGR888:
                case ABGR888:
                        fmt_cfg = 0;
-                       win->vir_stride = v_WIN1_ARGB888_VIRWIDTH(xvir);
                        win->swap_rb = 1;
                        break;
                case ARGB888:
                        fmt_cfg = 0;
-                       win->vir_stride = v_WIN1_ARGB888_VIRWIDTH(xvir);
                        win->swap_rb = 0;
 
                        break;
                case RGB888:
                        fmt_cfg = 1;
-                       win->vir_stride = v_WIN1_RGB888_VIRWIDTH(xvir);
                        win->swap_rb = 0;
                        break;
                case RGB565:
                        fmt_cfg = 2;
-                       win->vir_stride = v_WIN1_RGB565_VIRWIDTH(xvir);
                        win->swap_rb = 0;
                        break;
                default:
@@ -808,125 +942,57 @@ static int win1_set_par(struct lcdc_device *lcdc_dev,
        return 0;
 }
 
-static int rk3188_lcdc_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
+static int rk3188_set_win_par(struct rk_lcdc_driver *dev_drv,
+                       struct rk_screen *screen, struct rk_lcdc_win *win,int win_id)
 {
        struct lcdc_device *lcdc_dev =
            container_of(dev_drv, struct lcdc_device, driver);
-       struct rk_lcdc_win *win = NULL;
-       struct rk_screen *screen = dev_drv->cur_screen;
 
-       if (!screen) {
-               dev_err(dev_drv->dev, "screen is null!\n");
-               return -ENOENT;
-       }
-       if (win_id == 0) {
-               win = dev_drv->win[0];
+       switch(win_id)
+       {
+       case 0:
                win0_set_par(lcdc_dev, screen, win);
-       } else if (win_id == 1) {
-               win = dev_drv->win[1];
+               break;
+       case 1:
                win1_set_par(lcdc_dev, screen, win);
-       } else {
+               break;                  
+       default:
                dev_err(dev_drv->dev, "unsupported win number:%d\n", win_id);
-               return -EINVAL;
+               break;  
        }
-
        return 0;
 }
-
-static int win0_display(struct lcdc_device *lcdc_dev,
-                       struct rk_lcdc_win *win)
+static int rk3188_lcdc_set_par(struct rk_lcdc_driver *dev_drv,int win_id)
 {
-       u32 y_addr;
-       u32 uv_addr;
-       y_addr = win->smem_start + win->y_offset;
-       uv_addr = win->cbr_start + win->c_offset;
-       DBG(2, "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x\n",
-           lcdc_dev->id, __func__, y_addr, uv_addr);
-
-       spin_lock(&lcdc_dev->reg_lock);
-       if (likely(lcdc_dev->clk_on)) {
-               win->y_addr = y_addr;
-               win->uv_addr = uv_addr;
-       }
-       spin_unlock(&lcdc_dev->reg_lock);
-
-       return 0;
-
-}
-
-static int win1_display(struct lcdc_device *lcdc_dev,
-                       struct rk_lcdc_win *win)
-{
-       u32 y_addr;
-       u32 uv_addr;
-       y_addr = win->smem_start + win->y_offset;
-       uv_addr = win->cbr_start + win->c_offset;
-       DBG(2, "lcdc%d>>%s>>y_addr:0x%x>>uv_addr:0x%x\n",
-           lcdc_dev->id, __func__, y_addr, uv_addr);
-
-       spin_lock(&lcdc_dev->reg_lock);
-       if (likely(lcdc_dev->clk_on))
-               win->y_addr = y_addr;
-       spin_unlock(&lcdc_dev->reg_lock);
-
-       return 0;
-}
-
-static int rk3188_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
-{
-       struct lcdc_device *lcdc_dev = container_of(dev_drv,
-                               struct lcdc_device, driver);
+       int i;
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
        struct rk_lcdc_win *win = NULL;
        struct rk_screen *screen = dev_drv->cur_screen;
-       u32 mask, val;
-#if defined(WAIT_FOR_SYNC)
-       int timeout;
-       unsigned long flags;
-#endif
+
        if (!screen) {
                dev_err(dev_drv->dev, "screen is null!\n");
                return -ENOENT;
        }
-       if (win_id == 0) {
-               win = dev_drv->win[0];
-               win0_display(lcdc_dev, win);
-       } else if (win_id == 1) {
-               win = dev_drv->win[1];
-               win1_display(lcdc_dev, win);
-       } else {
-               dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
-               return -EINVAL;
-       }
-
-       /*this is the first frame of the system ,enable frame start interrupt */
-       if ((dev_drv->first_frame)) {
-               dev_drv->first_frame = 0;
-               mask = m_HS_INT_CLEAR | m_HS_INT_EN | m_FS_INT_CLEAR |
-                   m_FS_INT_EN | m_LF_INT_EN | m_LF_INT_CLEAR |
-                   m_LF_INT_NUM | m_BUS_ERR_INT_CLEAR | m_BUS_ERR_INT_EN;
-               val = v_FS_INT_CLEAR(1) | v_FS_INT_EN(1) | v_HS_INT_CLEAR(1) |
-                   v_HS_INT_EN(0) | v_LF_INT_CLEAR(1) | v_LF_INT_EN(1) |
-                   v_LF_INT_NUM(screen->mode.vsync_len + screen->mode.upper_margin +
-                   screen->mode.yres -1);
-               lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
-               lcdc_cfg_done(lcdc_dev);
+       for(i=0;i<dev_drv->lcdc_win_num;i++){
+               if(dev_drv->win[i]->state == 1){
+                       win = dev_drv->win[i];
+                       rk3188_set_win_par(dev_drv,screen,win,i);
+                       rk3188_lcdc_win_display(dev_drv,win,i);
+               }
        }
-#if defined(WAIT_FOR_SYNC)
-       spin_lock_irqsave(&dev_drv->cpl_lock, flags);
-       init_completion(&dev_drv->frame_done);
-       spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
-       timeout = wait_for_completion_timeout(&dev_drv->frame_done,
-                                             msecs_to_jiffies(dev_drv->
-                                                              cur_screen->ft +
-                                                              5));
-       if (!timeout && (!dev_drv->frame_done.done)) {
-               dev_info(dev_drv->dev, "wait for new frame start time out!\n");
-               return -ETIMEDOUT;
+       if(dev_drv->win[0]->z_order == 0){
+               dev_drv->ops->ovl_mgr(dev_drv, 0, 1);
+       }else{
+               dev_drv->ops->ovl_mgr(dev_drv, 1, 1);
        }
-#endif
+       rk3188_lcdc_reg_update(dev_drv);
+
+
        return 0;
 }
 
+
 static int rk3188_lcdc_blank(struct rk_lcdc_driver *dev_drv,
                             int win_id, int blank_mode)
 {
@@ -998,11 +1064,12 @@ static int rk3188_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
 
        struct lcdc_device *lcdc_dev =
            container_of(dev_drv, struct lcdc_device, driver);
-
        if (dev_drv->screen0->standby)
                dev_drv->screen0->standby(1);
        if (dev_drv->screen_ctr_info->io_disable)
                dev_drv->screen_ctr_info->io_disable();
+       dev_drv->suspend_flag = 1;
+       flush_kthread_worker(&dev_drv->update_regs_worker);
 
        spin_lock(&lcdc_dev->reg_lock);
        if (likely(lcdc_dev->clk_on)) {
@@ -1028,6 +1095,7 @@ static int rk3188_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
        }
        gpio_direction_output(gpio_dclk, GPIO_LOW);
 #endif
+
        return 0;
 }
 
@@ -1043,8 +1111,10 @@ static int rk3188_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
        gpio_free(gpio_dclk);
        iomux_set(LCDC0_DCLK);
 #endif
+
        if (dev_drv->screen_ctr_info->io_enable)
                dev_drv->screen_ctr_info->io_enable();
+       dev_drv->suspend_flag = 0;
 
        if (lcdc_dev->atv_layer_cnt) {
                rk3188_lcdc_clk_enable(lcdc_dev);
@@ -1410,6 +1480,18 @@ int rk3188_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
 
        return ret;
 }
+static int rk3188_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,unsigned int *dsp_addr)
+{
+       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);
+       }
+       return 0;
+}
+
 
 static struct rk_lcdc_win lcdc_win[] = {
        [0] = {
@@ -1445,6 +1527,7 @@ static struct rk_lcdc_drv_ops lcdc_drv_ops = {
        .dpi_open = rk3188_lcdc_dpi_open,
        .dpi_win_sel = rk3188_lcdc_dpi_win_sel,
        .dpi_status = rk3188_lcdc_dpi_status,
+       .get_dsp_addr = rk3188_lcdc_get_dsp_addr,
 };
 
 static irqreturn_t rk3188_lcdc_isr(int irq, void *dev_id)
@@ -1458,7 +1541,8 @@ static irqreturn_t rk3188_lcdc_isr(int irq, void *dev_id)
                timestamp = ktime_get();
                lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
                             v_FS_INT_CLEAR(1));
-               if (lcdc_dev->driver.wait_fs) {
+               //if (lcdc_dev->driver.wait_fs) {
+               if (0) {        
                        spin_lock(&(lcdc_dev->driver.cpl_lock));
                        complete(&(lcdc_dev->driver.frame_done));
                        spin_unlock(&(lcdc_dev->driver.cpl_lock));
@@ -1552,7 +1636,7 @@ static int rk3188_lcdc_probe(struct platform_device *pdev)
        dev_drv->prop = prop;
        dev_drv->id = lcdc_dev->id;
        dev_drv->ops = &lcdc_drv_ops;
-       dev_drv->num_win = ARRAY_SIZE(lcdc_win);
+       dev_drv->lcdc_win_num = ARRAY_SIZE(lcdc_win);
        spin_lock_init(&lcdc_dev->reg_lock);
 
        lcdc_dev->irq = platform_get_irq(pdev, 0);
index e1844e7b2b9d78315787d9762060268ba9a9ed3a..93ea7ec1c2f5fee12927889460cf18397e06e4ba 100755 (executable)
@@ -50,7 +50,7 @@
 
 static int hdmi_switch_complete;
 static struct platform_device *fb_pdev;
-
+struct list_head saved_list;
 
 #if defined(CONFIG_FB_MIRRORING)
 int (*video_data_to_mirroring)(struct fb_info *info, u32 yuv_phy[2]);
@@ -58,7 +58,77 @@ EXPORT_SYMBOL(video_data_to_mirroring);
 #endif
 
 
+int rk_fb_pixel_width(int data_format)
+{
+       int pixel_width;
+       switch(data_format){
+       case XBGR888:
+       case ABGR888:
+       case ARGB888:
+               pixel_width = 4*8;
+               break;
+       case RGB888:
+               pixel_width = 3*8;
+               break;
+       case RGB565:
+               pixel_width = 2*8;
+               break;
+       case YUV422:
+       case YUV420:
+       case YUV444:
+               pixel_width = 1*8;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return pixel_width;
+}
 
+static int rk_fb_data_fmt(int data_format,int bits_per_pixel)
+{
+       int fb_data_fmt;
+       if(bits_per_pixel == 0){
+               switch(data_format){
+               case HAL_PIXEL_FORMAT_RGBX_8888: 
+                       fb_data_fmt = XBGR888;
+                       break;
+               case HAL_PIXEL_FORMAT_RGBA_8888:
+                       fb_data_fmt = ABGR888;
+                       break;
+               case HAL_PIXEL_FORMAT_BGRA_8888: 
+                       fb_data_fmt = ARGB888;
+                       break;
+               case HAL_PIXEL_FORMAT_RGB_888:
+                       fb_data_fmt = RGB888;
+                       break;
+               case HAL_PIXEL_FORMAT_RGB_565:
+                       fb_data_fmt = RGB565;
+                       break;
+               case HAL_PIXEL_FORMAT_YCbCr_422_SP: // yuv422
+                       fb_data_fmt = YUV422;
+                       break;
+               case HAL_PIXEL_FORMAT_YCrCb_NV12: // YUV420---uvuvuv
+                       fb_data_fmt = YUV420;
+                       break;
+               case HAL_PIXEL_FORMAT_YCrCb_444: // yuv444
+                       fb_data_fmt = YUV444;
+                       break;
+               default:
+                       printk("%s:un supported format:0x%x\n",__func__,data_format);
+                   return -EINVAL;
+               }
+       }else{
+               switch(bits_per_pixel){
+               case 32:
+                       fb_data_fmt = ARGB888;
+                       break;
+               case 16:
+                       fb_data_fmt = RGB565;
+                       break;
+               }
+       }
+       return fb_data_fmt;
+}
 
 /* rk display power control parse from dts
  *
@@ -443,7 +513,7 @@ static int  get_extend_fb_id(struct fb_info *info)
                fb_id = 0;
        else if (!strcmp(id, "fb1"))
                fb_id = 1;
-       else if (!strcmp(id, "fb2") && (dev_drv->num_win > 2))
+       else if (!strcmp(id, "fb2") && (dev_drv->lcdc_win_num > 2))
                fb_id = 2;
        return fb_id;
 }
@@ -640,8 +710,19 @@ static int rk_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;
        u8 data_format = var->nonstd&0xff;
 
+       u8  pixel_width;
+       u32 vir_width_bit;
+       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;
+       u8  is_pic_yuv=0;
+
        win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
        if (win_id < 0)
                return  -ENODEV;
@@ -656,44 +737,93 @@ static int rk_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
                                                extend_info->fix.id);
                extend_win = extend_dev_drv->win[extend_win_id];
        }
+       pixel_width = rk_fb_pixel_width(win->format);
+       vir_width_bit = pixel_width * xvir;
+       stride_128bit_1 = ((vir_width_bit   + 127) & (~127))/8; //pixel_width = byte_num *8
+       stride_128bit_2 = ((vir_width_bit*2 + 127) & (~127))/8; //pixel_width = byte_num *8
+       stride_32bit_1  = ((vir_width_bit   + 31 ) & (~31 ))/8; //pixel_width = byte_num *8
+       stride_32bit_2  = ((vir_width_bit*2 + 31 ) & (~31 ))/8; //pixel_width = byte_num *8
+
+       stride    = stride_32bit_1;//default rgb
+       fix->line_length = stride;
+
+       switch (win->format){
+       case YUV422:
+               is_pic_yuv = 1;
+               stride     = stride_32bit_1;
+               uv_stride  = stride_32bit_1>> 1 ;//
+               uv_x_off   = xoffset >> 1 ;//
+               uv_y_off   = yoffset;//0
+               fix->line_length = stride;
+               break;
+       case YUV420://420sp
+               is_pic_yuv = 1;
+               stride     = stride_32bit_1;
+               uv_stride  = stride_32bit_1;
+               uv_x_off   = xoffset;
+               uv_y_off   = yoffset >> 1;
+               fix->line_length = stride;
+               break;
+       case YUV444:
+               is_pic_yuv = 1;
+               stride     = stride_32bit_1;
+               uv_stride  = stride_32bit_2;
+               uv_x_off   = xoffset*2;
+               uv_y_off   = yoffset;
+               fix->line_length = stride<<2;
+               break;
+       default:
+               printk(KERN_ERR "%s:un supported format:0x%x\n", __func__, data_format);
+               return -EINVAL;
+       }
+
+       // x y mirror ,jump line
+       win->area[0].y_offset = yoffset*stride+xoffset*pixel_width/8;
+       if(is_pic_yuv == 1){
+               win->area[0].c_offset = uv_y_off*uv_stride+uv_x_off*pixel_width/8;
+       }
 
        switch (win->format) {
        case XBGR888:
        case ARGB888:
        case ABGR888:
-               win->y_offset = (yoffset*xvir + xoffset)*4;
+               win->area[0].y_offset=(yoffset*xvir + xoffset)*4;//win->y_offset = (yoffset*xvir + xoffset)*4;
                break;
        case  RGB888:
-               win->y_offset = (yoffset*xvir + xoffset)*3;
+               win->area[0].y_offset = (yoffset*xvir + xoffset)*3;
                break;
        case RGB565:
-               win->y_offset = (yoffset*xvir + xoffset)*2;
+               win->area[0].y_offset = (yoffset*xvir + xoffset)*2;
                break;
        case  YUV422:
-               win->y_offset = yoffset*xvir + xoffset;
-               win->c_offset = win->y_offset;
+               win->area[0].y_offset = yoffset*xvir + xoffset;
+               win->area[0].c_offset = win->area[0].y_offset;
                break;
        case  YUV420:
-               win->y_offset = yoffset*xvir + xoffset;
-               win->c_offset = (yoffset>>1)*xvir + xoffset;
+               win->area[0].y_offset = yoffset*xvir + xoffset;
+               win->area[0].c_offset = (yoffset>>1)*xvir + xoffset;
                break;
        case  YUV444:
-               win->y_offset = yoffset*xvir + xoffset;
-               win->c_offset = yoffset*2*xvir + (xoffset<<1);
+               win->area[0].y_offset = yoffset*xvir + xoffset;
+               win->area[0].c_offset = yoffset*2*xvir + (xoffset<<1);
                break;
        default:
                printk(KERN_ERR "%s un supported format:0x%x\n",
                        __func__, data_format);
                return -EINVAL;
        }
-       win->smem_start = fix->smem_start;
-       win->cbr_start = fix->mmio_start;
+       win->area[0].smem_start = fix->smem_start;
+       win->area[0].cbr_start = fix->smem_start + xvir * yvir;
+       win->state=1;
+       win->area[0].state=1;
+       win->area_num = 1;
+       
        dev_drv->ops->pan_display(dev_drv, win_id);
        if (rk_fb->disp_mode == DUAL) {
                if (extend_win->state && (hdmi_switch_complete)) {
-                       extend_win->y_offset = win->y_offset;
+                       extend_win->area[0].y_offset = win->area[0].y_offset;
                #if defined(CONFIG_FB_ROTATE) || !defined(CONFIG_THREE_FB_BUFFER)
-                       rk_fb_rotate(extend_info, info, win->y_offset);
+                       rk_fb_rotate(extend_info, info, win->area[0].y_offset);
                #endif
                        extend_dev_drv->ops->pan_display(extend_dev_drv, extend_win_id);
                }
@@ -706,6 +836,440 @@ static int rk_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
        return 0;
 }
 
+static int rk_fb_get_list_stat(struct rk_lcdc_driver *dev_drv)
+{
+       int i,j;
+       i = list_empty(&dev_drv->update_regs_list);
+       j = list_empty(&saved_list);
+       return i==j?0:1;
+
+}
+
+void rk_fd_fence_wait(struct rk_lcdc_driver *dev_drv,
+       struct sync_fence *fence)
+{
+       int err = sync_fence_wait(fence, 1000);
+       
+       if (err >= 0)
+               return;
+
+       if (err == -ETIME)
+               err = sync_fence_wait(fence, 10 * MSEC_PER_SEC);
+
+       if (err < 0)
+               printk("error waiting on fence\n");
+}
+
+
+void rk_fb_free_dma_buf(struct rk_fb_reg_win_data *reg_win_data)
+{
+#ifdef H_USE_FENCE
+       int i;
+       for(i=0;i<RK_WIN_MAX_AREA;i++){
+               if(reg_win_data->reg_area_data[i].acq_fence)
+                       sync_fence_put(reg_win_data->reg_area_data[i].acq_fence);
+       }
+#endif
+       memset(reg_win_data, 0, sizeof(struct rk_fb_reg_win_data));
+}
+
+static void rk_fb_update_driver(struct rk_lcdc_win *win,struct rk_fb_reg_win_data *reg_win_data)
+{
+       int i=0;
+       //struct rk_lcdc_win *win;      
+       //win = dev_drv->win[reg_win_data->win_id];
+       win->area_num = reg_win_data->area_num;
+       win->format = reg_win_data->data_format;
+       win->id = reg_win_data->win_id;
+       win->z_order = reg_win_data->z_order;
+       
+       #if 0
+       for(i=0;i<win->area_num;i++)
+       {
+               printk("i=%d:area[%d]=%x,reg_area_data[%d]=%x,mem_start=%x\n",
+                       i,i,&win->area[i],i,&reg_win_data->reg_area_data[i],reg_win_data->reg_area_data[i].smem_start);
+               
+               win->area[i].smem_start = reg_win_data->reg_area_data[i].smem_start;
+               win->area[i].cbr_start  = reg_win_data->reg_area_data[i].cbr_start;
+               win->area[i].xpos          = reg_win_data->reg_area_data[i].xpos;
+               win->area[i].ypos          = reg_win_data->reg_area_data[i].ypos;
+               win->area[i].xsize         = reg_win_data->reg_area_data[i].xsize;
+               win->area[i].ysize         = reg_win_data->reg_area_data[i].ysize;
+               win->area[i].xact          = reg_win_data->reg_area_data[i].xact;
+               win->area[i].yact          = reg_win_data->reg_area_data[i].yact;
+               win->area[i].xvir          = reg_win_data->reg_area_data[i].xvir;
+               win->area[i].yvir          = reg_win_data->reg_area_data[i].yvir;
+               win->area[i].y_offset      = reg_win_data->reg_area_data[i].y_offset;
+               win->area[i].c_offset      = reg_win_data->reg_area_data[i].c_offset;
+               win->area[i].state = 1;
+       }       
+       #else
+       if(reg_win_data->reg_area_data[0].smem_start > 0){
+               win->state = 1;
+               win->area_num = reg_win_data->area_num;
+               win->format = reg_win_data->data_format;
+               win->id = reg_win_data->win_id;
+               win->z_order = reg_win_data->z_order;
+               win->area[0].uv_vir_stride = reg_win_data->reg_area_data[0].uv_vir_stride;
+               win->area[0].cbr_start = reg_win_data->reg_area_data[0].cbr_start;
+               win->area[0].c_offset = reg_win_data->reg_area_data[0].c_offset;
+               win->alpha_en = reg_win_data->alpha_en;
+               win->alpha_mode = reg_win_data->alpha_mode;
+               win->g_alpha_val = reg_win_data->g_alpha_val;
+               for(i=0;i<RK_WIN_MAX_AREA;i++)
+               {
+                       if(reg_win_data->reg_area_data[i].smem_start > 0){
+                               win->area[i].smem_start = reg_win_data->reg_area_data[i].smem_start;
+                               win->area[i].xpos          = reg_win_data->reg_area_data[i].xpos;
+                               win->area[i].ypos          = reg_win_data->reg_area_data[i].ypos;
+                               win->area[i].xsize         = reg_win_data->reg_area_data[i].xsize;
+                               win->area[i].ysize         = reg_win_data->reg_area_data[i].ysize;
+                               win->area[i].xact          = reg_win_data->reg_area_data[i].xact;
+                               win->area[i].yact          = reg_win_data->reg_area_data[i].yact;
+                               win->area[i].xvir          = reg_win_data->reg_area_data[i].xvir;
+                               win->area[i].yvir          = reg_win_data->reg_area_data[i].yvir;
+                               win->area[i].y_offset      = reg_win_data->reg_area_data[i].y_offset;
+                               win->area[i].y_vir_stride  = reg_win_data->reg_area_data[i].y_vir_stride;
+                               win->area[i].state = 1;
+                       }else{
+                               win->area[i].state = 0;
+                       }
+               }
+       }else{
+               win->state = 0;
+       }
+       #endif
+
+}
+
+
+static void rk_fb_update_reg(struct rk_lcdc_driver * dev_drv,struct rk_fb_reg_data *regs)
+{
+       int i,j,ret=0;
+       struct rk_lcdc_win *win;
+       ktime_t timestamp = dev_drv->vsync_info.timestamp;
+       //struct rk_fb_reg_win_data old_reg_win_data[RK30_MAX_LAYER_SUPPORT];
+
+       for(i=0;i<dev_drv->lcdc_win_num;i++){ 
+               //old_reg_win_data[i]= regs->reg_win_data[i];
+               win = dev_drv->win[i];
+               for(j=0;j<regs->win_num;j++){
+                       if(i == regs->reg_win_data[j].win_id)
+                               break;
+               }
+               if(j<regs->win_num){
+                       rk_fb_update_driver(win,&regs->reg_win_data[j]);
+                       win->state = 1;
+               }else{
+                       win->state = 0;
+               }
+       }
+#if 0
+       for(i=0;i<2;i++){
+               printk("win[%d]:drv_win_state=%d\n",i,dev_drv->win[i]->state);
+               for(j=0;j<4;j++){
+                       printk("area[%d]:state=%d,mem_addr=%x\n",
+                               i,dev_drv->win[i]->area[j].state,dev_drv->win[i]->area[j].smem_start);
+               }
+       }
+#endif 
+       dev_drv->atv_layer_cnt = regs->win_num;
+       dev_drv->cur_screen->post_xsize = regs->post_cfg.xsize;
+       dev_drv->cur_screen->post_ysize = regs->post_cfg.ysize;
+       dev_drv->cur_screen->post_dsp_stx = regs->post_cfg.xpos;
+       dev_drv->cur_screen->post_dsp_sty = regs->post_cfg.ypos;
+       dev_drv->ops->set_par(dev_drv,0);
+
+       ret = wait_event_interruptible_timeout(dev_drv->vsync_info.wait,
+                       !ktime_equal(timestamp, dev_drv->vsync_info.timestamp),msecs_to_jiffies(dev_drv->cur_screen->ft+5));
+
+       sw_sync_timeline_inc(dev_drv->timeline, 1);
+
+       for(i=0;i<regs->win_num;i++){
+               rk_fb_free_dma_buf(&regs->reg_win_data[i]);
+       }
+}
+
+static void rk_fb_update_regs_handler(struct kthread_work *work)
+{
+       struct rk_lcdc_driver * dev_drv =
+                       container_of(work, struct rk_lcdc_driver, update_regs_work);
+       struct rk_fb_reg_data *data, *next;
+       //struct list_head saved_list;
+       mutex_lock(&dev_drv->update_regs_list_lock);
+       saved_list = dev_drv->update_regs_list;
+       list_replace_init(&dev_drv->update_regs_list, &saved_list);
+       mutex_unlock(&dev_drv->update_regs_list_lock);
+       
+       list_for_each_entry_safe(data, next, &saved_list, list) {
+               rk_fb_update_reg(dev_drv,data);
+               list_del(&data->list);
+               kfree(data);
+       }
+}
+
+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)
+{
+       struct rk_fb *rk_fb = dev_get_drvdata(info->device);
+       //struct fb_var_screeninfo *var = &info->var;
+       struct fb_fix_screeninfo *fix = &info->fix;
+       //struct rk_lcdc_driver * dev_drv = (struct rk_lcdc_driver * )info->par;
+
+       int i,j,ion_fd,acq_fence_fd;
+       u32 xvir,yvir;
+       u32 xoffset,yoffset;
+
+       struct ion_handle *hdl;
+       ion_phys_addr_t phy_addr;
+       size_t len;
+       int index_buf;
+       u8  fb_data_fmt;
+       u8  pixel_width;
+       u32 vir_width_bit;
+       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;
+       u8  is_pic_yuv=0;
+       u8  ppixel_a=0,global_a=0;
+       reg_win_data->area_num = 0;
+       if(win_par->area_par[0].phy_addr == 0){
+               for(i=0;i<RK_WIN_MAX_AREA;i++){ 
+                       ion_fd = win_par->area_par[i].ion_fd;
+                       if(ion_fd > 0){
+                               reg_win_data->area_num++;
+                               for(j=0;j<i;j++){
+                                       if(ion_fd == win_par->area_par[j].ion_fd){
+                                               printk("region[%d] fd is same to region[%d]:fd=%d",
+                                                       i,j,ion_fd);
+                                               break;
+                                       }       
+                               }
+                               if(j == i){
+                                       hdl = ion_import_dma_buf(rk_fb->ion_client, ion_fd);
+                                       ion_phys(rk_fb->ion_client, hdl, &phy_addr, &len);
+                                       reg_win_data->reg_area_data[i].smem_start = phy_addr;
+                                       reg_win_data->area_buf_num++;
+                                       reg_win_data->reg_area_data[i].index_buf = 1;
+                               }else{
+                                       reg_win_data->reg_area_data[i].smem_start = 
+                                               reg_win_data->reg_area_data[j].smem_start;                      
+                               }
+                       }
+                       #if 0
+                       printk("i=%d,ion_fd=%d,addr=0x%x,area_num=%d,area_buf_num=%d\n",
+                               i,ion_fd,reg_win_data->reg_area_data[i].smem_start,
+                               reg_win_data->area_num,reg_win_data->area_buf_num);
+                       #endif
+               }
+       }else{
+               reg_win_data->reg_area_data[0].smem_start = 
+               win_par->area_par[0].phy_addr;
+               reg_win_data->area_num = 1;
+       }       
+
+       if(reg_win_data->area_num == 0){
+               return 0;
+       }
+
+       for(i=0;i<reg_win_data->area_num;i++){
+               acq_fence_fd = win_par->area_par[i].acq_fence_fd;
+               index_buf = reg_win_data->reg_area_data[i].index_buf;
+               if((acq_fence_fd > 0)&&(index_buf == 1)){
+                       reg_win_data->reg_area_data[i].acq_fence = 
+                               sync_fence_fdget(win_par->area_par[i].acq_fence_fd);
+               }
+       }
+       fb_data_fmt = rk_fb_data_fmt(win_par->data_format,0);
+       reg_win_data->data_format = fb_data_fmt;
+       pixel_width = rk_fb_pixel_width(fb_data_fmt);
+       
+       ppixel_a = ((fb_data_fmt == ARGB888)||(fb_data_fmt == ABGR888)) ? 1:0;
+       global_a = (win_par->g_alpha_val == 0) ? 0:1;
+       reg_win_data->alpha_en = ppixel_a | global_a;
+       
+       reg_win_data->z_order = win_par->z_order;
+       reg_win_data->win_id  = win_par->win_id;        
+       
+       for(i=0;i<reg_win_data->area_num;i++){  
+               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;
+
+               reg_win_data->reg_area_data[i].xsize= win_par->area_par[i].xsize;//realy size in panel
+               reg_win_data->reg_area_data[i].ysize= win_par->area_par[i].ysize;
+
+               reg_win_data->reg_area_data[i].xact= win_par->area_par[i].xact;//realy size in panel
+               reg_win_data->reg_area_data[i].yact= win_par->area_par[i].yact; 
+
+               xoffset = win_par->area_par[i].x_offset;//buf offset
+               yoffset = win_par->area_par[i].y_offset;
+               xvir = win_par->area_par[i].xvir;
+               reg_win_data->reg_area_data[i].xvir = xvir;
+               yvir = win_par->area_par[i].yvir;
+               reg_win_data->reg_area_data[i].yvir = yvir;
+               #if 0
+               printk("i=%d,xpos=%d,ypos=%d,xsize=%d,ysize=%d,xact=%d,yact=%d,x_off=%d,y_off=%d,xvir=%d,yvir=%d\n",
+               i,reg_win_data->reg_area_data[i].xpos,reg_win_data->reg_area_data[i].ypos,reg_win_data->reg_area_data[i].xsize,reg_win_data->reg_area_data[i].ysize,
+               reg_win_data->reg_area_data[i].xact,reg_win_data->reg_area_data[i].yact,xoffset,yoffset,xvir,yvir);
+               #endif
+
+               vir_width_bit = pixel_width * xvir;
+               stride_128bit_1 = ((vir_width_bit   + 127) & (~127))/8; //pixel_width = byte_num *8
+               stride_128bit_2 = ((vir_width_bit*2 + 127) & (~127))/8; //pixel_width = byte_num *8
+               stride_32bit_1  = ((vir_width_bit   + 31 ) & (~31 ))/8; //pixel_width = byte_num *8
+               stride_32bit_2  = ((vir_width_bit*2 + 31 ) & (~31 ))/8; //pixel_width = byte_num *8
+
+               stride    = stride_32bit_1;//default rgb
+               fix->line_length = stride;
+               reg_win_data->reg_area_data[i].y_vir_stride = stride >> 2;
+               // x y mirror ,jump line
+               reg_win_data->reg_area_data[i].y_offset = yoffset*stride+xoffset*pixel_width/8;
+       }
+       switch (fb_data_fmt){
+       case YUV422:
+               is_pic_yuv = 1;
+               stride     = stride_32bit_1;
+               uv_stride  = stride_32bit_1>> 1 ;//
+               uv_x_off   = xoffset >> 1 ;//
+               uv_y_off   = yoffset;//0
+               fix->line_length = stride;
+               break;
+       case YUV420://420sp
+               is_pic_yuv = 1;
+               stride     = stride_32bit_1;
+               uv_stride  = stride_32bit_1;
+               uv_x_off   = xoffset;
+               uv_y_off   = yoffset >> 1;
+               fix->line_length = stride;
+               break;
+       case YUV444:
+               is_pic_yuv = 1;
+               stride     = stride_32bit_1;
+               uv_stride  = stride_32bit_2;
+               uv_x_off   = xoffset*2;
+               uv_y_off   = yoffset;
+               fix->line_length = stride<<2;
+               break;
+       }
+       if(is_pic_yuv == 1){
+               reg_win_data->reg_area_data[0].cbr_start = 
+                       reg_win_data->reg_area_data[0].smem_start + xvir*yvir;          
+               reg_win_data->reg_area_data[0].c_offset = 
+                       uv_y_off*uv_stride+uv_x_off*pixel_width/8;
+               reg_win_data->reg_area_data[0].uv_vir_stride = 
+                       uv_stride >> 2;
+       }       
+       return 0;
+}
+
+static int rk_fb_set_win_config(struct fb_info *info,
+               struct rk_fb_win_cfg_data *win_data)
+{
+       //struct rk_fb *rk_fb = dev_get_drvdata(info->device);
+       struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
+       struct rk_fb_reg_data *regs;
+       struct rk_fb_reg_win_data *reg_win_data;
+       struct sync_fence *release_fence[RK_MAX_BUF_NUM];
+       struct sync_fence *retire_fence;
+       struct sync_pt *release_sync_pt[RK_MAX_BUF_NUM];
+       struct sync_pt *retire_sync_pt;
+       int ret,i,j=0,fence_fd;
+       char fence_name[20];
+
+       //mutex_lock(&dev_drv->output_lock);
+       regs = kzalloc(sizeof(struct rk_fb_reg_data), GFP_KERNEL);
+       if (!regs) {
+               printk("could not allocate rk_fb_reg_data\n");
+               ret = -ENOMEM;
+               return ret;
+       }
+       
+       regs->post_cfg.xpos = win_data->post_cfg.xpos;
+       regs->post_cfg.ypos = win_data->post_cfg.ypos;
+       regs->post_cfg.xsize = win_data->post_cfg.xsize;
+       regs->post_cfg.ysize = win_data->post_cfg.xsize;
+       for (i=0; i<dev_drv->lcdc_win_num; i++) {
+               if(win_data->win_par[i].win_id < dev_drv->lcdc_win_num){
+                       rk_fb_set_win_buffer(info,&win_data->win_par[i],&regs->reg_win_data[j]);
+                       if(regs->reg_win_data[j].area_num > 0){
+                               regs->win_num++;
+                               regs->buf_num += regs->reg_win_data[j].area_buf_num;
+                       }
+                       j++;
+               }else{
+                       printk("error:win_id bigger than lcdc_win_num\n");
+                       printk("i=%d,win_id=%d\n",i,win_data->win_par[i].win_id);
+               }
+       }       
+       for(i=0; i<regs->win_num; i++){
+               reg_win_data = &regs->reg_win_data[i];
+               for(j=0;j<RK_WIN_MAX_AREA;j++){
+                       if(reg_win_data->reg_area_data[j].acq_fence){
+                               printk("acq_fence wait!!!!!\n");
+                               rk_fd_fence_wait(dev_drv,
+                               reg_win_data->reg_area_data[j].acq_fence);
+                       }
+               }
+       }
+
+       mutex_lock(&dev_drv->output_lock);
+       if(!(dev_drv->suspend_flag == 0)){
+               rk_fb_update_reg(dev_drv,regs);
+               printk("suspend_flag == 0\n");
+               goto err;
+       }
+       mutex_lock(&dev_drv->update_regs_list_lock);
+       dev_drv->timeline_max++;
+#ifdef H_USE_FENCE
+       for(i=0;i<RK_MAX_BUF_NUM;i++){
+               if(i<regs->buf_num){
+                       sprintf(fence_name,"fence%d",i);
+                       win_data->rel_fence_fd[i] =  get_unused_fd();
+                       if (win_data->rel_fence_fd[i] < 0){
+                               printk("rel_fence_fd=%d\n",win_data->rel_fence_fd[i]);
+                               return -EFAULT;
+                       }
+                       release_sync_pt[i] = sw_sync_pt_create(dev_drv->timeline,
+                               dev_drv->timeline_max);
+                       release_fence[i] = sync_fence_create(fence_name, release_sync_pt[i]);
+                       sync_fence_install(release_fence[i], win_data->rel_fence_fd[i]);        
+               }else{
+                       win_data->rel_fence_fd[i] = -1;
+               }
+       }
+       
+       win_data->ret_fence_fd =  get_unused_fd();
+       if (win_data->ret_fence_fd < 0){
+               printk("ret_fence_fd=%d\n",win_data->ret_fence_fd);
+               return -EFAULT;
+       }
+       retire_sync_pt = sw_sync_pt_create(dev_drv->timeline, dev_drv->timeline_max);
+       retire_fence = sync_fence_create("ret_fence", retire_sync_pt);
+       sync_fence_install(retire_fence, win_data->ret_fence_fd);
+#else
+       for(i=0;i<RK_MAX_BUF_NUM;i++){
+               win_data->rel_fence_fd[i] = -1;
+       }
+       win_data->ret_fence_fd = -1;    
+#endif 
+       if(dev_drv->wait_fs == 0){
+               list_add_tail(&regs->list,&dev_drv->update_regs_list);  
+               mutex_unlock(&dev_drv->update_regs_list_lock);
+               queue_kthread_work(&dev_drv->update_regs_worker,
+                               &dev_drv->update_regs_work);
+       }else{
+               mutex_unlock(&dev_drv->update_regs_list_lock);
+               rk_fb_update_reg(dev_drv,regs);
+       }
+
+err:
+       mutex_unlock(&dev_drv->output_lock);
+       return ret;
+}
+
 static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
 {
        struct rk_fb *rk_fb = dev_get_drvdata(info->device);
@@ -720,11 +1284,13 @@ static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg
        int ovl;   /*overlay:0 win1 on the top of win0;1,win0 on the top of win1*/
        int num_buf; /*buffer_number*/
        int ret;
+       struct rk_fb_win_cfg_data win_data;
+       unsigned int dsp_addr[2];
+       int list_stat;
 
        int  win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
        
        void __user *argp = (void __user *)arg;
-
        win = dev_drv->win[win_id];
        if (rk_fb->disp_mode == DUAL) {
                fb_id = get_extend_fb_id(info);
@@ -775,6 +1341,19 @@ static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg
                        return -EFAULT;
                dev_drv->vsync_info.active = enable;
                break;
+
+       case RK_FBIOGET_DSP_ADDR:
+               dev_drv->ops->get_dsp_addr(dev_drv,dsp_addr);
+               if (copy_to_user(argp, &dsp_addr, sizeof(dsp_addr)))
+                       return -EFAULT;
+               break;
+       case RK_FBIOGET_LIST_STAT:
+               list_stat = rk_fb_get_list_stat(dev_drv);
+               if (copy_to_user(argp, &list_stat, sizeof(list_stat)))
+                       return -EFAULT;
+
+               break;
+
 #if defined(CONFIG_ION_ROCKCHIP)
        case RK_FBIOSET_DMABUF_FD:
        {
@@ -791,11 +1370,10 @@ static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg
        }
        case RK_FBIOGET_DMABUF_FD:
        {
-               int fd = ion_share_dma_buf_fd(rk_fb->ion_client, win->ion_hdl);
+               int fd = ion_share_dma_buf_fd(rk_fb->ion_client, win->area[0].ion_hdl);
                if (fd < 0) {
                        dev_err(info->dev, "ion_share_dma_buf_fd failed\n");
                        return fd;
-
                }
                if (copy_to_user(argp, &fd, sizeof(fd)))
                        return -EFAULT;
@@ -803,9 +1381,24 @@ static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg
        }
 #endif
        case RK_FBIOSET_CONFIG_DONE:
-               ret = copy_from_user(&(dev_drv->wait_fs), argp, sizeof(dev_drv->wait_fs));
-               if (dev_drv->ops->lcdc_reg_update)
-                       dev_drv->ops->lcdc_reg_update(dev_drv);
+               if(copy_from_user(&win_data,
+                       (struct rk_fb_win_cfg_data __user *)argp,
+                       sizeof(win_data))){
+                       ret = -EFAULT;
+                       break;
+               };
+
+               dev_drv->wait_fs = win_data.wait_fs;
+               rk_fb_set_win_config(info,&win_data);   
+
+               if (copy_to_user((struct rk_fb_win_cfg_data __user *)arg,
+                        &win_data,
+                       sizeof(win_data))) {
+                       ret = -EFAULT;
+                       break;
+               }       
+               memset(&win_data, 0, sizeof(struct rk_fb_win_cfg_data));
+
                if (rk_fb->disp_mode == DUAL) {
                        if (extend_win->state && (hdmi_switch_complete)) {
                                if (rk_fb->num_fb >= 2) {
@@ -820,7 +1413,7 @@ static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg
                break;
        }
        
-       return 0;
+       return 0;       
 }
 
 static int rk_fb_blank(int blank_mode, struct fb_info *info)
@@ -892,6 +1485,10 @@ static ssize_t rk_fb_read(struct fb_info *info, char __user *buf,
        struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
        struct rk_lcdc_win *win = NULL;
        int win_id = 0;
+       int list_empty=0;
+
+       list_empty = rk_fb_get_list_stat(dev_drv);
+       printk("list_empty=%d\n",list_empty);
 
        win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
        if (win_id < 0)
@@ -900,9 +1497,9 @@ static ssize_t rk_fb_read(struct fb_info *info, char __user *buf,
                win = dev_drv->win[win_id];
 
        if (win->format == RGB565)
-               total_size = win->xact*win->yact<<1; /*only read the current frame buffer*/
+               total_size = win->area[0].xact*win->area[0].yact<<1; /*only read the current frame buffer*/
        else
-               total_size = win->xact*win->yact<<2;
+               total_size = win->area[0].xact*win->area[0].yact<<2;
 
 
        if (p >= total_size)
@@ -919,7 +1516,7 @@ static ssize_t rk_fb_read(struct fb_info *info, char __user *buf,
        if (!buffer)
                return -ENOMEM;
 
-       src = (u8 __iomem *) (info->screen_base + p + win->y_offset);
+       src = (u8 __iomem *) (info->screen_base + p + win->area[0].y_offset);
 
        while (count) {
                c  = (count > PAGE_SIZE) ? PAGE_SIZE : count;
@@ -962,9 +1559,9 @@ static ssize_t rk_fb_write(struct fb_info *info, const char __user *buf,
                win = dev_drv->win[win_id];
 
        if (win->format == RGB565)
-               total_size = win->xact*win->yact<<1; /*write the current frame buffer*/
+               total_size = win->area[0].xact*win->area[0].yact<<1; /*write the current frame buffer*/
        else
-               total_size = win->xact*win->yact<<2;
+               total_size = win->area[0].xact*win->area[0].yact<<2;
 
        if (p > total_size)
                return -EFBIG;
@@ -986,7 +1583,7 @@ static ssize_t rk_fb_write(struct fb_info *info, const char __user *buf,
        if (!buffer)
                return -ENOMEM;
 
-       dst = (u8 __iomem *) (info->screen_base + p + win->y_offset);
+       dst = (u8 __iomem *) (info->screen_base + p + win->area[0].y_offset);
 
        while (count) {
                c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
@@ -1033,9 +1630,17 @@ static int rk_fb_set_par(struct fb_info *info)
        u16 ypos = (var->nonstd>>20) & 0xfff;
        u32 xvir = var->xres_virtual;
        u32 yvir = var->yres_virtual;
-       u8 data_format = var->nonstd&0xff;
-
-
+       u8  data_format = var->nonstd&0xff;
+       u8  fb_data_fmt;
+       u8  pixel_width;
+       u32 vir_width_bit;
+       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;
+       u8  is_pic_yuv=0;
 
        var->pixclock = dev_drv->pixclock;
        win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
@@ -1043,7 +1648,6 @@ static int rk_fb_set_par(struct fb_info *info)
                return  -ENODEV;
        else
                win = dev_drv->win[win_id];
-
        if (rk_fb->disp_mode == DUAL) {
                fb_id = get_extend_fb_id(info);
                extend_info = rk_fb->fb[(rk_fb->num_fb>>1) + fb_id];
@@ -1077,99 +1681,85 @@ if (rk_fb->disp_mode != DUAL) {
        }
 }
 
-#if 1
-       switch (data_format) {
-       case HAL_PIXEL_FORMAT_RGBX_8888:
-               win->format = XBGR888;
-               fix->line_length = 4 * xvir;
-               win->y_offset = (yoffset*xvir + xoffset)*4;
-               break;
-       case HAL_PIXEL_FORMAT_RGBA_8888:
-               win->format = ABGR888;
-               fix->line_length = 4 * xvir;
-               win->y_offset = (yoffset*xvir + xoffset)*4;
-               break;
-       case HAL_PIXEL_FORMAT_BGRA_8888:
-               win->format = ARGB888;
-               fix->line_length = 4 * xvir;
-               win->y_offset = (yoffset*xvir + xoffset)*4;
-               break;
-       case HAL_PIXEL_FORMAT_RGB_888:
-               win->format = RGB888;
-               fix->line_length = 3 * xvir;
-               win->y_offset = (yoffset*xvir + xoffset)*3;
-               break;
-       case HAL_PIXEL_FORMAT_RGB_565:
-               win->format = RGB565;
-               fix->line_length = 2 * xvir;
-               win->y_offset = (yoffset*xvir + xoffset)*2;
-               break;
-       case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-               win->format = YUV422;
-               fix->line_length = xvir;
+       fb_data_fmt = rk_fb_data_fmt(data_format,var->bits_per_pixel);
+       pixel_width = rk_fb_pixel_width(fb_data_fmt);
+       vir_width_bit = pixel_width * xvir;
+       stride_128bit_1 = ((vir_width_bit   + 127) & (~127))/8; //pixel_width = byte_num *8
+       stride_128bit_2 = ((vir_width_bit*2 + 127) & (~127))/8; //pixel_width = byte_num *8
+       stride_32bit_1  = ((vir_width_bit   + 31 ) & (~31 ))/8; //pixel_width = byte_num *8
+       stride_32bit_2  = ((vir_width_bit*2 + 31 ) & (~31 ))/8; //pixel_width = byte_num *8
+
+       stride    = stride_32bit_1;//default rgb
+       fix->line_length = stride;
+
+       switch (fb_data_fmt){
+       case YUV422:
+               is_pic_yuv = 1;
+               stride     = stride_32bit_1;
+               uv_stride  = stride_32bit_1>> 1 ;//
+               uv_x_off   = xoffset >> 1 ;//
+               uv_y_off   = yoffset;//0
+               fix->line_length = stride;
                cblen = crlen = (xvir*yvir)>>1;
-               win->y_offset = yoffset*xvir + xoffset;
-               win->c_offset = win->y_offset;
                break;
-       case HAL_PIXEL_FORMAT_YCrCb_NV12:
-               win->format = YUV420;
-               fix->line_length = xvir;
+       case YUV420://420sp
+               is_pic_yuv = 1;
+               stride     = stride_32bit_1;
+               uv_stride  = stride_32bit_1;
+               uv_x_off   = xoffset;
+               uv_y_off   = yoffset >> 1;
+               fix->line_length = stride;
                cblen = crlen = (xvir*yvir)>>2;
-               win->y_offset = yoffset*xvir + xoffset;
-               win->c_offset = (yoffset>>1)*xvir + xoffset;
                break;
-       case HAL_PIXEL_FORMAT_YCrCb_444:
-               win->format = 5;
-               fix->line_length = xvir<<2;
-               win->y_offset = yoffset*xvir + xoffset;
-               win->c_offset = yoffset*2*xvir + (xoffset<<1);
+       case YUV444:
+               is_pic_yuv = 1;
+               stride     = stride_32bit_1;
+               uv_stride  = stride_32bit_2;
+               uv_x_off   = xoffset*2;
+               uv_y_off   = yoffset;
+               fix->line_length = stride<<2;
                cblen = crlen = (xvir*yvir);
                break;
-       default:
-               printk(KERN_ERR "%s:un supported format:0x%x\n", __func__, data_format);
-               return -EINVAL;
        }
-#else
-       switch (var->bits_per_pixel) {
-       case 32:
-               win->format = ARGB888;
-               fix->line_length = 4 * xvir;
-               win->y_offset = (yoffset*xvir + xoffset)*4;
-               break;
-       case 16:
-               win->format = RGB565;
-               fix->line_length = 2 * xvir;
-               win->y_offset = (yoffset*xvir + xoffset)*2;
-               break;
 
-       }
-#endif
+       // x y mirror ,jump line
+       win->area[0].y_offset = yoffset*stride+xoffset*pixel_width/8;
+       if(is_pic_yuv == 1){
+               win->area[0].c_offset = uv_y_off*uv_stride+uv_x_off*pixel_width/8;
+       }
+       win->format = fb_data_fmt;
+       win->area[0].y_vir_stride = stride>>2;
+       win->area[0].uv_vir_stride = uv_stride>>2;
+       win->area[0].xpos = xpos;
+       win->area[0].ypos = ypos;
+       win->area[0].xsize = xsize;
+       win->area[0].ysize = ysize;
+
+       win->area[0].smem_start = fix->smem_start;
+       win->area[0].cbr_start = fix->smem_start+stride*yvir;//fix->mmio_start;
+       win->area[0].xact = var->xres;              /*winx active window height,is a wint of vir*/
+       win->area[0].yact = var->yres;
+       win->area[0].xvir =  var->xres_virtual;    /*virtual resolution  stride --->LCDC_WINx_VIR*/
+       win->area[0].yvir =  var->yres_virtual;
+       win->state=1;
+       win->area[0].state=1;
+       win->area_num = 1;
 
-       win->xpos = xpos;
-       win->ypos = ypos;
-       win->xsize = xsize;
-       win->ysize = ysize;
-
-       win->smem_start = fix->smem_start;
-       win->cbr_start = fix->mmio_start;
-       win->xact = var->xres;              /*winx active window height,is a wint of vir*/
-       win->yact = var->yres;
-       win->xvir =  var->xres_virtual;    /*virtual resolution  stride --->LCDC_WINx_VIR*/
-       win->yvir =  var->yres_virtual;
        if (rk_fb->disp_mode == DUAL) {
                if (extend_win->state && (hdmi_switch_complete)) {
                        if (info != extend_info) {
-                               if (win->xact < win->yact) {
-                                       extend_win->xact = win->yact;
-                                       extend_win->yact = win->xact;
-                                       extend_win->xvir = win->yact;
+                               if (win->area[0].xact < win->area[0].yact) {
+                                       //extend_win->xact = win->area[0].yact;
+                                       extend_win->area[0].xact = win->area[0].yact;
+                                       extend_win->area[0].yact = win->area[0].xact;
+                                       extend_win->area[0].xvir = win->area[0].yact;
                                        extend_info->var.xres = var->yres;
                                        extend_info->var.yres = var->xres;
                                        extend_info->var.xres_virtual = var->yres;
                                } else {
-                                       extend_win->xact = win->xact;
-                                       extend_win->yact = win->yact;
-                                       extend_win->xvir = win->xvir;
+                                       extend_win->area[0].xact = win->area[0].xact;
+                                       extend_win->area[0].yact = win->area[0].yact;
+                                       extend_win->area[0].xvir = win->area[0].xvir;
                                        extend_info->var.xres = var->xres;
                                        extend_info->var.yres = var->yres;
                                        extend_info->var.xres_virtual = var->xres_virtual;
@@ -1411,7 +2001,7 @@ int rk_fb_switch_screen(struct rk_screen *screen , int enable, int lcdc_id)
        if (rk_fb->num_lcdc == 1)
                info = rk_fb->fb[0];
        else if (rk_fb->num_lcdc == 2)
-               info = rk_fb->fb[dev_drv->num_win]; /*the main fb of lcdc1*/
+               info = rk_fb->fb[dev_drv->lcdc_win_num]; /*the main fb of lcdc1*/
 
        if (dev_drv->screen1) { /*device like rk2928 ,have only one lcdc but two outputs*/
                if (enable) {
@@ -1552,7 +2142,7 @@ int rk_fb_disp_scale(u8 scale_x, u8 scale_y, u8 lcdc_id)
        if (inf->num_lcdc == 1)
                info = inf->fb[0];
        else if (inf->num_lcdc == 2)
-               info = inf->fb[dev_drv->num_win];
+               info = inf->fb[dev_drv->lcdc_win_num];
 
        var = &info->var;
        screen_x = dev_drv->cur_screen->mode.xres;
@@ -1615,11 +2205,12 @@ static int rk_fb_alloc_buffer(struct fb_info *fbi, int fb_id)
                        dev_err(fbi->device, "failed to ion_alloc:%ld\n",PTR_ERR(handle));
                        return -ENOMEM;
                }
-               win->ion_hdl = handle;
+               win->area[0].ion_hdl = handle;
                fbi->screen_base = ion_map_kernel(rk_fb->ion_client, handle);
                ion_phys(rk_fb->ion_client, handle, &phy_addr, &len);
                fbi->fix.smem_start = phy_addr;
-               fbi->fix.smem_len = len;        
+               fbi->fix.smem_len = len;
+               printk("alloc_buffer:smem_start=0x%x\n",phy_addr);
 #else
 
                fb_mem_virt = dma_alloc_writecombine(fbi->dev, fb_mem_size, &fb_mem_phys,
@@ -1680,8 +2271,8 @@ static int rk_release_fb_buffer(struct fb_info *fbi)
 static int init_lcdc_win(struct rk_lcdc_driver *dev_drv, struct rk_lcdc_win *def_win)
 {
        int i;
-       int num_win = dev_drv->num_win;
-       for (i = 0; i < num_win; i++) {
+       int lcdc_win_num = dev_drv->lcdc_win_num;
+       for (i = 0; i < lcdc_win_num; i++) {
                struct rk_lcdc_win *win = NULL;
                win =  kzalloc(sizeof(struct rk_lcdc_win), GFP_KERNEL);
                if (!win) {
@@ -1804,7 +2395,7 @@ int rk_fb_register(struct rk_lcdc_driver *dev_drv,
        index = i;
        init_lcdc_device_driver(rk_fb, win, index);
        dev_drv->fb_index_base = rk_fb->num_fb;
-       for (i = 0; i < dev_drv->num_win; i++) {
+       for (i = 0; i < dev_drv->lcdc_win_num; i++) {
                fbi = framebuffer_alloc(0, &fb_pdev->dev);
                if (!fbi) {
                        dev_err(&fb_pdev->dev, "fb framebuffer_alloc fail!");
@@ -1854,6 +2445,25 @@ int rk_fb_register(struct rk_lcdc_driver *dev_drv,
                                dev_drv->vsync_info.thread = NULL;
                        }
                        dev_drv->vsync_info.active = 1;
+
+                       mutex_init(&dev_drv->output_lock);
+
+                       INIT_LIST_HEAD(&dev_drv->update_regs_list);
+                       mutex_init(&dev_drv->update_regs_list_lock);
+                       init_kthread_worker(&dev_drv->update_regs_worker);
+
+                       dev_drv->update_regs_thread = kthread_run(kthread_worker_fn,
+                                       &dev_drv->update_regs_worker, "rk-fb");
+                       if (IS_ERR(dev_drv->update_regs_thread)) {
+                               int err = PTR_ERR(dev_drv->update_regs_thread);
+                               dev_drv->update_regs_thread = NULL;
+
+                               printk("failed to run update_regs thread\n");
+                               return err;
+                       }
+                       init_kthread_work(&dev_drv->update_regs_work, rk_fb_update_regs_handler);
+
+                       dev_drv->timeline = sw_sync_timeline_create("fb-timeline");                     dev_drv->timeline_max = 1;
                }
 
        }
@@ -1877,7 +2487,9 @@ if (dev_drv->prop == PRMRY) {
                main_fbi->fbops->fb_pan_display(&main_fbi->var, main_fbi);
        }
 #endif
-       main_fbi->fbops->fb_ioctl(main_fbi, RK_FBIOSET_CONFIG_DONE, 0);
+       //main_fbi->fbops->fb_ioctl(main_fbi, RK_FBIOSET_CONFIG_DONE, 0);
+       main_fbi->fbops->fb_set_par(main_fbi);
+
 }
 #endif
        return 0;
@@ -1891,7 +2503,7 @@ int rk_fb_unregister(struct rk_lcdc_driver *dev_drv)
        struct rk_fb *fb_inf = platform_get_drvdata(fb_pdev);
        struct fb_info *fbi;
        int fb_index_base = dev_drv->fb_index_base;
-       int fb_num = dev_drv->num_win;
+       int fb_num = dev_drv->lcdc_win_num;
        int i = 0;
 
        if (fb_inf->lcdc_dev_drv[i]->vsync_info.thread) {
old mode 100644 (file)
new mode 100755 (executable)
index 2d96db8..ed8d933
@@ -291,6 +291,85 @@ static ssize_t set_dsp_lut(struct device *dev, struct device_attribute *attr,
        return count;
 
 }
+static ssize_t show_dsp_cabc(struct device *dev,
+                           struct device_attribute *attr, char *buf)
+{
+
+       return 0;
+}
+
+static ssize_t set_dsp_cabc(struct device *dev, struct device_attribute *attr,
+                          const char *buf, size_t count)
+{
+       struct fb_info *fbi = dev_get_drvdata(dev);
+       struct rk_lcdc_driver *dev_drv =
+           (struct rk_lcdc_driver *)fbi->par;
+       int ret,mode=0;
+       
+       ret = kstrtoint(buf, 0, &mode);
+       if (ret)
+               return ret;
+
+       ret = dev_drv->ops->set_dsp_cabc(dev_drv, mode);
+       if(ret < 0)
+               return ret;
+       
+       return count;
+
+       
+}
+
+static ssize_t show_hue(struct device *dev,
+                           struct device_attribute *attr, char *buf)
+{
+
+       return 0;
+}
+
+static ssize_t set_hue(struct device *dev, struct device_attribute *attr,
+                          const char *buf, size_t count)
+{
+       struct fb_info *fbi = dev_get_drvdata(dev);
+       struct rk_lcdc_driver *dev_drv =
+           (struct rk_lcdc_driver *)fbi->par;
+       int ret,hue;
+       
+       ret = kstrtoint(buf, 0, &hue);
+       if (ret)
+               return ret;
+
+       ret = dev_drv->ops->set_dsp_hue(dev_drv, hue);
+       if(ret < 0)
+               return ret;
+       
+       return count;
+}
+
+static ssize_t show_dsp_bcs(struct device *dev,
+                           struct device_attribute *attr, char *buf)
+{
+
+       return 0;
+}
+
+static ssize_t set_dsp_bcs(struct device *dev, struct device_attribute *attr,
+                          const char *buf, size_t count)
+{
+       struct fb_info *fbi = dev_get_drvdata(dev);
+       struct rk_lcdc_driver *dev_drv =
+           (struct rk_lcdc_driver *)fbi->par;
+       int ret,bri,con,sat;
+       
+       ret = kstrtoint(buf, 0, &bri);
+       if (ret)
+               return ret;
+
+       ret = dev_drv->ops->set_dsp_bcsh_bcs(dev_drv, bri,con,sat);
+       if(ret < 0)
+               return ret;
+       
+       return count;
+}
 
 static struct device_attribute rkfb_attrs[] = {
        __ATTR(phys_addr, S_IRUGO, show_phys, NULL),
@@ -303,6 +382,9 @@ static struct device_attribute rkfb_attrs[] = {
        __ATTR(fps, S_IRUGO | S_IWUSR, show_fps, set_fps),
        __ATTR(map, S_IRUGO | S_IWUSR, show_fb_win_map, set_fb_win_map),
        __ATTR(dsp_lut, S_IRUGO | S_IWUSR, show_dsp_lut, set_dsp_lut),
+       __ATTR(cabc, S_IRUGO | S_IWUSR, show_dsp_cabc, set_dsp_cabc),
+       __ATTR(hue, S_IRUGO | S_IWUSR, show_hue, set_hue),
+       __ATTR(bcs, S_IRUGO | S_IWUSR, show_dsp_bcs, set_dsp_bcs),
 };
 
 int rkfb_create_sysfs(struct fb_info *fbi)
index bf77050fe6f97f8679b3cc83e7b4fd15bfbbd9e2..f711e1f500fd1d756ca056dd5b09fb44e48a6df4 100755 (executable)
 #if defined(CONFIG_OF)
 #include <dt-bindings/rkfb/rk_fb.h>
 #endif
+#include "../../drivers/staging/android/sw_sync.h"
+#include <linux/file.h>
+#include <linux/kthread.h>
+
 
 #define RK30_MAX_LCDC_SUPPORT  4
 #define RK30_MAX_LAYER_SUPPORT 4
-#define RK_MAX_FB_SUPPORT       8
+#define RK_MAX_FB_SUPPORT       4
+#define RK_WIN_MAX_AREA                4
+#define RK_MAX_BUF_NUM         10
 
 #define FB0_IOCTL_STOP_TIMER_FLUSH             0x6001
 #define FB0_IOCTL_SET_PANEL                            0x6002
@@ -61,6 +67,9 @@
 #define RK_FBIOSET_VSYNC_ENABLE                0x4629
 #define RK_FBIOPUT_NUM_BUFFERS                 0x4625
 #define RK_FBIOPUT_COLOR_KEY_CFG       0x4626
+#define RK_FBIOGET_DSP_ADDR            0x4630
+#define RK_FBIOGET_LIST_STAT                   0X4631
+
 
 /**rk fb events**/
 #define RK_LF_STATUS_FC                  0xef
@@ -149,6 +158,7 @@ enum {
        HAL_PIXEL_FORMAT_YCrCb_NV12 = 0x20,     // YUY2
        HAL_PIXEL_FORMAT_YCrCb_NV12_VIDEO = 0x21,       // YUY2
        HAL_PIXEL_FORMAT_YCrCb_444 = 0x22,      //yuv444
+       HAL_PIXEL_FORMAT_H265 = 0x23,   //yuv444
 
 };
 
@@ -173,8 +183,17 @@ enum fb_win_map_order {
        FB0_WIN0_FB1_WIN2_FB2_WIN1 = 120,
        FB0_WIN0_FB1_WIN1_FB2_WIN2 = 210,
        FB0_WIN1_FB1_WIN0_FB2_WIN2 = 201,
+       FB0_WIN0_FB1_WIN1_FB2_WIN2_FB3_WIN3 = 3210,
+};
+
+enum
+{
+    SCALE_NONE = 0x0,
+    SCALE_UP   = 0x1,
+    SCALE_DOWN = 0x2
 };
 
+
 struct rk_fb_rgb {
        struct fb_bitfield red;
        struct fb_bitfield green;
@@ -224,11 +243,15 @@ typedef enum _TRSP_MODE {
        TRSP_INVAL
 } TRSP_MODE;
 
-struct rk_lcdc_win {
-       char name[5];
-       int id;
-       bool state;             /*on or off*/
-       u32 pseudo_pal[16];
+struct rk_lcdc_post_cfg{
+       u32 xpos;
+       u32 ypos;
+       u32 xsize;
+       u32 ysize;
+};
+
+struct rk_lcdc_area{
+       bool state;
        u32 y_offset;           /*yuv/rgb offset  -->LCDC_WINx_YRGB_MSTx*/
        u32 c_offset;           /*cb cr offset--->LCDC_WINx_CBR_MSTx*/
        u32 xpos;               /*start point in panel  --->LCDC_WINx_DSP_ST*/
@@ -241,28 +264,68 @@ struct rk_lcdc_win {
        u16 yvir;
        unsigned long smem_start;
        unsigned long cbr_start;        /*Cbr memory start address*/
-       enum data_format format;
 #if defined(CONFIG_ION_ROCKCHIP)
-       struct ion_handle *ion_hdl;
-       int dma_buf_fd;
+               struct ion_handle *ion_hdl;
+               int dma_buf_fd;
 #endif
-       bool support_3d;
-       u32 scale_yrgb_x;
-       u32 scale_yrgb_y;
-       u32 scale_cbcr_x;
-       u32 scale_cbcr_y;
        u32 dsp_stx;
        u32 dsp_sty;
-       u32 vir_stride;
+       u32 y_vir_stride;
+       u32 uv_vir_stride;
        u32 y_addr;
        u32 uv_addr;
+
+};
+
+
+struct rk_lcdc_win {
+       char name[5];
+       int id;
+       bool state;             /*on or off*/
+       u32 pseudo_pal[16];
+       enum data_format format;
+       u8 z_order;             /*win sel layer*/
        u8 fmt_cfg;
+       u8 fmt_10;;
        u8 swap_rb;
        u32 reserved;
+       u32 area_num;
+       u32 scale_yrgb_x;
+       u32 scale_yrgb_y;
+       u32 scale_cbcr_x;
+       u32 scale_cbcr_y;
+       bool support_3d;
+
+       u8 win_lb_mode;
+
+       u8 bic_coe_el;
+       u8 yrgb_hor_scl_mode;//h 01:scale up ;10:down
+       u8 yrgb_ver_scl_mode;//v 01:scale up ;10:down
+       u8 yrgb_hsd_mode;//h scale down mode
+       u8 yrgb_vsu_mode;//v scale up mode
+       u8 yrgb_vsd_mode;//v scale down mode
+       u8 cbr_hor_scl_mode;
+       u8 cbr_ver_scl_mode;
+       u8 cbr_hsd_mode;
+       u8 cbr_vsu_mode;
+       u8 cbr_vsd_mode;
+       u8 vsd_yrgb_gt4;
+       u8 vsd_yrgb_gt2;
+       u8 vsd_cbr_gt4;
+       u8 vsd_cbr_gt2;
+
+       u8 alpha_en;
+       u32 alpha_mode;
+       u32 g_alpha_val;
+       u32 color_key_val;
+
+       struct rk_lcdc_area area[RK_WIN_MAX_AREA];
+       struct rk_lcdc_post_cfg post_cfg;
 };
 
 struct rk_lcdc_driver;
 
+
 struct rk_lcdc_drv_ops {
        int (*open) (struct rk_lcdc_driver * dev_drv, int layer_id, bool open);
        int (*init_lcdc) (struct rk_lcdc_driver * dev_drv);
@@ -292,7 +355,90 @@ 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 (*set_dsp_cabc) (struct rk_lcdc_driver * dev_drv, int mode);
+       int (*set_dsp_hue) (struct rk_lcdc_driver *dev_drv,int hue);
+       int (*set_dsp_bcsh_bcs)(struct rk_lcdc_driver *dev_drv,int bri,int con,int sat);
+};
+
+struct rk_fb_area_par {
+       u16 ion_fd;
+       unsigned long phy_addr;
+       u16 acq_fence_fd;
+       u32 x_offset;
+       u32 y_offset;
+       u32 xpos;               /*start point in panel  --->LCDC_WINx_DSP_ST*/
+       u32 ypos;
+       u32 xsize;              /* display window width/height  -->LCDC_WINx_DSP_INFO*/
+       u32 ysize;
+       u32 xact;               /*origin display window size -->LCDC_WINx_ACT_INFO*/
+       u32 yact;
+       u32 xvir;               /*virtual width/height     -->LCDC_WINx_VIR*/
+       u32 yvir;
+};
+
+
+struct rk_fb_win_par {
+       u8 data_format;        /*layer data fmt*/
+       u8 win_id;
+       u8 z_order;             /*win sel layer*/
+       struct rk_fb_area_par area_par[RK_WIN_MAX_AREA];
+       u32 alpha_mode;
+       u32 g_alpha_val;
+};
+
+struct rk_fb_win_cfg_data {
+       u16 ret_fence_fd;
+       u16 rel_fence_fd[RK_MAX_BUF_NUM];
+       struct  rk_fb_win_par win_par[RK30_MAX_LAYER_SUPPORT];
+       struct  rk_lcdc_post_cfg post_cfg;
+       u8      wait_fs;
+       //u8      fence_begin;
+};
+
+struct rk_fb_reg_area_data {
+       struct sync_fence *acq_fence;
+       u8  index_buf;          /*judge if the buffer is index*/
+       u32 y_offset;           /*yuv/rgb offset  -->LCDC_WINx_YRGB_MSTx*/
+       u32 c_offset;           /*cb cr offset--->LCDC_WINx_CBR_MSTx*/
+       u32 y_vir_stride;
+       u32 uv_vir_stride;
+       u32 xpos;               /*start point in panel  --->LCDC_WINx_DSP_ST*/
+       u32 ypos;
+       u16 xsize;              /* display window width/height  -->LCDC_WINx_DSP_INFO*/
+       u16 ysize;
+       u16 xact;               /*origin display window size -->LCDC_WINx_ACT_INFO*/
+       u16 yact;
+       u16 xvir;               /*virtual width/height     -->LCDC_WINx_VIR*/
+       u16 yvir;
+       unsigned long smem_start;
+       unsigned long cbr_start;        /*Cbr memory start address*/
+       u32 line_length;
+};
 
+struct rk_fb_reg_win_data {
+       u8 data_format;        /*layer data fmt*/
+       u8 win_id;
+       u8 z_order;             /*win sel layer*/
+       u32 area_num;           /*maybe two region have the same dma buff,*/
+       u32 area_buf_num;     /*so area_num  maybe not equal to area_buf_num*/
+       u8 alpha_en;
+       u32 alpha_mode;
+       u32 g_alpha_val;
+       u32 color_key_val;
+
+       struct rk_fb_reg_area_data reg_area_data[RK_WIN_MAX_AREA];
+};
+
+struct rk_fb_reg_data {
+       struct list_head list;
+       int     win_num;
+       int     buf_num;
+       int     acq_num;
+       struct rk_fb_reg_win_data reg_win_data[RK30_MAX_LAYER_SUPPORT];
+       struct rk_lcdc_post_cfg post_cfg;
+       //struct sync_fence *acq_fence[RK_MAX_BUF_NUM];
+       //int     fence_wait_begin;
 };
 
 struct rk_lcdc_driver {
@@ -302,8 +448,9 @@ struct rk_lcdc_driver {
        struct device *dev;
 
        struct rk_lcdc_win *win[RK_MAX_FB_SUPPORT];
-       int num_win;
+       int lcdc_win_num;
        int num_buf;            //the num_of buffer
+       int atv_layer_cnt;
        int fb_index_base;      //the first fb index of the lcdc device
        struct rk_screen *screen0;      //some platform have only one lcdc,but extend
        struct rk_screen *screen1;      //two display devices for dual display,such as rk2918,rk2928
@@ -313,6 +460,7 @@ struct rk_lcdc_driver {
        char fb0_win_id;
        char fb1_win_id;
        char fb2_win_id;
+       char fb3_win_id;
        struct mutex fb_win_id_mutex;
 
        struct completion frame_done;   //sync for pan_display,whe we set a new frame address to lcdc register,we must make sure the frame begain to display
@@ -320,7 +468,16 @@ struct rk_lcdc_driver {
        int first_frame;
        struct rk_fb_vsync vsync_info;
        int wait_fs;            //wait for new frame start in kernel
-
+       struct sw_sync_timeline *timeline;
+       int                     timeline_max;
+       int                     suspend_flag;
+       struct list_head        update_regs_list;
+       struct mutex            update_regs_list_lock;
+       struct kthread_worker   update_regs_worker;
+       struct task_struct      *update_regs_thread;
+       struct kthread_work     update_regs_work;
+
+       struct mutex            output_lock;
        struct rk29fb_info *screen_ctr_info;
        struct list_head pwrlist_head;
        struct rk_lcdc_drv_ops *ops;
@@ -338,7 +495,7 @@ struct rk_lcdc_driver {
 struct rk_fb {
        int disp_mode;
        struct rk29fb_info *mach_info;
-       struct fb_info *fb[RK_MAX_FB_SUPPORT];
+       struct fb_info *fb[RK_MAX_FB_SUPPORT*2];
        int num_fb;
 
        struct rk_lcdc_driver *lcdc_dev_drv[RK30_MAX_LCDC_SUPPORT];
@@ -378,6 +535,8 @@ extern int rkfb_create_sysfs(struct fb_info *fbi);
 extern char *get_format_string(enum data_format, char *fmt);
 extern int support_uboot_display(void);
 extern int  rk_fb_calc_fps(struct rk_screen * screen, u32 pixclock);
+extern void rk_fd_fence_wait(struct rk_lcdc_driver *dev_drv, struct sync_fence *fence);
+extern void rk_fb_free_dma_buf(struct rk_fb_reg_win_data *reg_win_data);
 
 #if defined(CONFIG_BACKLIGHT_RK29_BL)
 void rk29_backlight_set(bool on);
index 19e62306796f56c1fd3bd9473b509e1d10587905..f03ab5ce2cc7c6a0f6141fbb1bf355fd03938563 100755 (executable)
@@ -61,6 +61,12 @@ struct rk_screen {
        u8 lcdc_id;   
        u8 screen_id; 
        struct fb_videomode mode;
+       u32 post_dsp_stx;
+       u32 post_dsp_sty;
+       u32 post_xsize;
+       u32 post_ysize;
+       u16 x_mirror;
+       u16 y_mirror;
        u16 width;
        u16 height;
        u8  ft;