rk3368 lcdc: add lcdc driver
authorhjc <hjc@rock-chips.com>
Tue, 9 Dec 2014 04:18:12 +0000 (12:18 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Tue, 9 Dec 2014 07:12:14 +0000 (15:12 +0800)
Signed-off-by: hjc <hjc@rock-chips.com>
drivers/video/rockchip/lcdc/Kconfig
drivers/video/rockchip/lcdc/Makefile
drivers/video/rockchip/lcdc/rk3368_lcdc.c [new file with mode: 0644]
drivers/video/rockchip/lcdc/rk3368_lcdc.h [new file with mode: 0644]

index 5c69c75ffd161807ab8f14ef2ffc8943dad906df..4731bdb7207e31d0f1edc31848aa1d7ce488c342 100755 (executable)
@@ -43,3 +43,8 @@ config LCDC_RK312X
         depends on DRM_ROCKCHIP || FB_ROCKCHIP
         help
           Driver for rk312x lcdc.
+config LCDC_RK3368
+               bool "rk3368 lcdc support"
+                       depends on DRM_ROCKCHIP || FB_ROCKCHIP
+                       help
+                       Driver for rk3368 lcdc.There are one lcd controllers on rk3368
index 5f075557dbe77181afb86c6c5b19a2f8e52d5e51..8c878d025af91cf2a568e848a157b6ee21310d21 100644 (file)
@@ -5,3 +5,4 @@ obj-$(CONFIG_LCDC_RK3188) += rk3188_lcdc.o
 obj-$(CONFIG_LCDC_RK3288) += rk3288_lcdc.o
 obj-$(CONFIG_LCDC_RK3036) += rk3036_lcdc.o
 obj-$(CONFIG_LCDC_RK312X) += rk312x_lcdc.o
+obj-$(CONFIG_LCDC_RK3368) += rk3368_lcdc.o
diff --git a/drivers/video/rockchip/lcdc/rk3368_lcdc.c b/drivers/video/rockchip/lcdc/rk3368_lcdc.c
new file mode 100644 (file)
index 0000000..2340d65
--- /dev/null
@@ -0,0 +1,4431 @@
+/*
+ * drivers/video/rockchip/lcdc/rk3368_lcdc.c
+ *
+ * Copyright (C) 2014 ROCKCHIP, Inc.
+ *Author:hjc<hjc@rock-chips.com>
+ *This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/rockchip-iovmm.h>
+#include <asm/div64.h>
+#include <linux/uaccess.h>
+#include <linux/rockchip/cpu.h>
+#include <linux/rockchip/iomap.h>
+#include <linux/rockchip/grf.h>
+#include <linux/rockchip/common.h>
+#include <dt-bindings/clock/rk_system_status.h>
+
+#include "rk3368_lcdc.h"
+
+#if defined(CONFIG_HAS_EARLYSUSPEND)
+#include <linux/earlysuspend.h>
+#endif
+#define CONFIG_RK_FPGA 1
+
+static int dbg_thresd;
+module_param(dbg_thresd, int, S_IRUGO | S_IWUSR);
+
+#define DBG(level, x...) do {                  \
+       if (unlikely(dbg_thresd >= level))      \
+               pr_info(x);\
+       } while (0)
+
+static struct rk_lcdc_win lcdc_win[] = {
+       [0] = {
+              .name = "win0",
+              .id = 0,
+              .support_3d = false,
+              },
+       [1] = {
+              .name = "win1",
+              .id = 1,
+              .support_3d = false,
+              },
+       [2] = {
+              .name = "win2",
+              .id = 2,
+              .support_3d = false,
+              },
+       [3] = {
+              .name = "win3",
+              .id = 3,
+              .support_3d = false,
+              },
+       [4] = {
+              .name = "hwc",
+              .id = 4,
+              .support_3d = false,
+              }
+};
+
+static int rk3368_lcdc_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable);
+
+/*#define WAIT_FOR_SYNC 1*/
+u32 rk3368_get_hard_ware_vskiplines(u32 srch, u32 dsth)
+{
+       u32 vscalednmult;
+
+       if (srch >= (u32) (4 * dsth * MIN_SCALE_FACTOR_AFTER_VSKIP))
+               vscalednmult = 4;
+       else if (srch >= (u32) (2 * dsth * MIN_SCALE_FACTOR_AFTER_VSKIP))
+               vscalednmult = 2;
+       else
+               vscalednmult = 1;
+
+       return vscalednmult;
+}
+
+static int rk3368_lcdc_set_lut(struct rk_lcdc_driver *dev_drv)
+{
+       int i, j;
+       int __iomem *c;
+       u32 v, r, g, b;
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
+       lcdc_cfg_done(lcdc_dev);
+       mdelay(25);
+       for (i = 0; i < 256; i++) {
+               v = dev_drv->cur_screen->dsp_lut[i];
+               c = lcdc_dev->dsp_lut_addr_base + (i << 2);
+               b = (v & 0xff) << 2;
+               g = (v & 0xff00) << 4;
+               r = (v & 0xff0000) << 6;
+               v = r + g + b;
+               for (j = 0; j < 4; j++) {
+                       writel_relaxed(v, c);
+                       v += (1 + (1 << 10) + (1 << 20));
+                       c++;
+               }
+       }
+       lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
+
+       return 0;
+}
+
+static int rk3368_lcdc_clk_enable(struct lcdc_device *lcdc_dev)
+{
+#ifdef CONFIG_RK_FPGA
+       lcdc_dev->clk_on = 1;
+       return 0;
+#endif
+       if (!lcdc_dev->clk_on) {
+               clk_prepare_enable(lcdc_dev->hclk);
+               clk_prepare_enable(lcdc_dev->dclk);
+               clk_prepare_enable(lcdc_dev->aclk);
+               clk_prepare_enable(lcdc_dev->pd);
+               spin_lock(&lcdc_dev->reg_lock);
+               lcdc_dev->clk_on = 1;
+               spin_unlock(&lcdc_dev->reg_lock);
+       }
+
+       return 0;
+}
+
+static int rk3368_lcdc_clk_disable(struct lcdc_device *lcdc_dev)
+{
+#ifdef CONFIG_RK_FPGA
+       lcdc_dev->clk_on = 0;
+       return 0;
+#endif
+       if (lcdc_dev->clk_on) {
+               spin_lock(&lcdc_dev->reg_lock);
+               lcdc_dev->clk_on = 0;
+               spin_unlock(&lcdc_dev->reg_lock);
+               mdelay(25);
+               clk_disable_unprepare(lcdc_dev->dclk);
+               clk_disable_unprepare(lcdc_dev->hclk);
+               clk_disable_unprepare(lcdc_dev->aclk);
+               clk_disable_unprepare(lcdc_dev->pd);
+       }
+
+       return 0;
+}
+
+static int rk3368_lcdc_disable_irq(struct lcdc_device *lcdc_dev)
+{
+       u32 mask, val;
+
+       spin_lock(&lcdc_dev->reg_lock);
+       if (likely(lcdc_dev->clk_on)) {
+               mask = m_FS_INTR_EN | m_FS_NEW_INTR_EN |
+                   m_ADDR_SAME_INTR_EN | m_LINE_FLAG0_INTR_EN |
+                   m_LINE_FLAG1_INTR_EN | m_BUS_ERROR_INTR_EN |
+                   m_WIN0_EMPTY_INTR_EN | m_WIN1_EMPTY_INTR_EN |
+                   m_WIN2_EMPTY_INTR_EN | m_WIN3_EMPTY_INTR_EN |
+                   m_HWC_EMPTY_INTR_EN | m_POST_BUF_EMPTY_INTR_EN |
+                   m_PWM_GEN_INTR_EN | m_DSP_HOLD_VALID_INTR_EN;
+               val = v_FS_INTR_EN(0) | v_FS_NEW_INTR_EN(0) |
+                   v_ADDR_SAME_INTR_EN(0) |
+                   v_LINE_FLAG0_INTR_EN(0) | v_LINE_FLAG1_INTR_EN(0) |
+                   v_BUS_ERROR_INTR_EN(0) | v_WIN0_EMPTY_INTR_EN(0) |
+                   v_WIN1_EMPTY_INTR_EN(0) | v_WIN2_EMPTY_INTR_EN(0) |
+                   v_WIN3_EMPTY_INTR_EN(0) | v_HWC_EMPTY_INTR_EN(0) |
+                   v_POST_BUF_EMPTY_INTR_EN(0) |
+                   v_PWM_GEN_INTR_EN(0) | v_DSP_HOLD_VALID_INTR_EN(0);
+               lcdc_msk_reg(lcdc_dev, INTR_EN, mask, val);
+
+               mask = m_FS_INTR_CLR | m_FS_NEW_INTR_CLR |
+                   m_ADDR_SAME_INTR_CLR | m_LINE_FLAG0_INTR_CLR |
+                   m_LINE_FLAG1_INTR_CLR | m_BUS_ERROR_INTR_CLR |
+                   m_WIN0_EMPTY_INTR_CLR | m_WIN1_EMPTY_INTR_CLR |
+                   m_WIN2_EMPTY_INTR_CLR | m_WIN3_EMPTY_INTR_CLR |
+                   m_HWC_EMPTY_INTR_CLR | m_POST_BUF_EMPTY_INTR_CLR |
+                   m_PWM_GEN_INTR_CLR | m_DSP_HOLD_VALID_INTR_CLR;
+               val = v_FS_INTR_CLR(1) | v_FS_NEW_INTR_CLR(1) |
+                   v_ADDR_SAME_INTR_CLR(1) |
+                   v_LINE_FLAG0_INTR_CLR(1) | v_LINE_FLAG1_INTR_CLR(1) |
+                   v_BUS_ERROR_INTR_CLR(1) | v_WIN0_EMPTY_INTR_CLR(1) |
+                   v_WIN1_EMPTY_INTR_CLR(1) | v_WIN2_EMPTY_INTR_CLR(1) |
+                   v_WIN3_EMPTY_INTR_CLR(1) | v_HWC_EMPTY_INTR_CLR(1) |
+                   v_POST_BUF_EMPTY_INTR_CLR(1) |
+                   v_PWM_GEN_INTR_CLR(1) | v_DSP_HOLD_VALID_INTR_CLR(1);
+               lcdc_msk_reg(lcdc_dev, INTR_CLEAR, mask, val);
+               lcdc_cfg_done(lcdc_dev);
+               spin_unlock(&lcdc_dev->reg_lock);
+       } else {
+               spin_unlock(&lcdc_dev->reg_lock);
+       }
+       mdelay(1);
+       return 0;
+}
+
+static int rk3368_lcdc_reg_dump(struct rk_lcdc_driver *dev_drv)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       int *cbase = (int *)lcdc_dev->regs;
+       int *regsbak = (int *)lcdc_dev->regsbak;
+       int i, j, val;
+       char dbg_message[30];
+       char buf[10];
+
+       pr_info("lcd back up reg:\n");
+       memset(dbg_message, 0, sizeof(dbg_message));
+       memset(buf, 0, sizeof(buf));
+       for (i = 0; i <= (0x200 >> 4); i++) {
+               val = sprintf(dbg_message, "0x%04x: ", i * 16);
+               for (j = 0; j < 4; j++) {
+                       val = sprintf(buf, "%08x  ", *(regsbak + i * 4 + j));
+                       strcat(dbg_message, buf);
+               }
+               pr_info("%s\n", dbg_message);
+               memset(dbg_message, 0, sizeof(dbg_message));
+               memset(buf, 0, sizeof(buf));
+       }
+
+       pr_info("lcdc reg:\n");
+       for (i = 0; i <= (0x200 >> 4); i++) {
+               val = sprintf(dbg_message, "0x%04x: ", i * 16);
+               for (j = 0; j < 4; j++) {
+                       sprintf(buf, "%08x  ",
+                               readl_relaxed(cbase + i * 4 + j));
+                       strcat(dbg_message, buf);
+               }
+               pr_info("%s\n", dbg_message);
+               memset(dbg_message, 0, sizeof(dbg_message));
+               memset(buf, 0, sizeof(buf));
+       }
+
+       return 0;
+}
+
+#define WIN_EN(id)             \
+static int win##id##_enable(struct lcdc_device *lcdc_dev, int en)      \
+{ \
+       u32 msk, val;                                                   \
+       spin_lock(&lcdc_dev->reg_lock);                                 \
+       msk =  m_WIN##id##_EN;                                          \
+       val  =  v_WIN##id##_EN(en);                                     \
+       lcdc_msk_reg(lcdc_dev, WIN##id##_CTRL0, msk, val);              \
+       lcdc_cfg_done(lcdc_dev);                                        \
+       val = lcdc_read_bit(lcdc_dev, WIN##id##_CTRL0, msk);            \
+       while (val !=  (!!en))  {                                       \
+               val = lcdc_read_bit(lcdc_dev, WIN##id##_CTRL0, msk);    \
+       }                                                               \
+       spin_unlock(&lcdc_dev->reg_lock);                               \
+       return 0;                                                       \
+}
+
+WIN_EN(0);
+WIN_EN(1);
+WIN_EN(2);
+WIN_EN(3);
+/*enable/disable win directly*/
+static int rk3368_lcdc_win_direct_en(struct rk_lcdc_driver *drv,
+                                    int win_id, int en)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(drv, struct lcdc_device, driver);
+       if (win_id == 0)
+               win0_enable(lcdc_dev, en);
+       else if (win_id == 1)
+               win1_enable(lcdc_dev, en);
+       else if (win_id == 2)
+               win2_enable(lcdc_dev, en);
+       else if (win_id == 3)
+               win3_enable(lcdc_dev, en);
+       else
+               dev_err(lcdc_dev->dev, "invalid win number:%d\n", win_id);
+       return 0;
+}
+
+#define SET_WIN_ADDR(id) \
+static int set_win##id##_addr(struct lcdc_device *lcdc_dev, u32 addr) \
+{                                                      \
+       u32 msk, val;                                   \
+       spin_lock(&lcdc_dev->reg_lock);                 \
+       lcdc_writel(lcdc_dev, WIN##id##_YRGB_MST, addr);        \
+       msk =  m_WIN##id##_EN;                          \
+       val  =  v_WIN0_EN(1);                           \
+       lcdc_msk_reg(lcdc_dev, WIN##id##_CTRL0, msk, val);      \
+       lcdc_cfg_done(lcdc_dev);                        \
+       spin_unlock(&lcdc_dev->reg_lock);               \
+       return 0;                                       \
+}
+
+SET_WIN_ADDR(0);
+SET_WIN_ADDR(1);
+int rk3368_lcdc_direct_set_win_addr(struct rk_lcdc_driver *dev_drv,
+                                   int win_id, u32 addr)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       if (win_id == 0)
+               set_win0_addr(lcdc_dev, addr);
+       else
+               set_win1_addr(lcdc_dev, addr);
+
+       return 0;
+}
+
+static void lcdc_read_reg_defalut_cfg(struct lcdc_device *lcdc_dev)
+{
+       int reg = 0;
+       u32 val = 0;
+       struct rk_screen *screen = lcdc_dev->driver.cur_screen;
+       u32 h_pw_bp = screen->mode.hsync_len + screen->mode.left_margin;
+       u32 v_pw_bp = screen->mode.vsync_len + screen->mode.upper_margin;
+       u32 st_x, st_y;
+       struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
+
+       spin_lock(&lcdc_dev->reg_lock);
+       for (reg = 0; reg < FRC_LOWER11_1; reg += 4) {
+               val = lcdc_readl(lcdc_dev, reg);
+               switch (reg) {
+               case WIN0_ACT_INFO:
+                       win0->area[0].xact = (val & m_WIN0_ACT_WIDTH) + 1;
+                       win0->area[0].yact =
+                           ((val & m_WIN0_ACT_HEIGHT) >> 16) + 1;
+                       break;
+               case WIN0_DSP_INFO:
+                       win0->area[0].xsize = (val & m_WIN0_DSP_WIDTH) + 1;
+                       win0->area[0].ysize =
+                           ((val & m_WIN0_DSP_HEIGHT) >> 16) + 1;
+                       break;
+               case WIN0_DSP_ST:
+                       st_x = val & m_WIN0_DSP_XST;
+                       st_y = (val & m_WIN0_DSP_YST) >> 16;
+                       win0->area[0].xpos = st_x - h_pw_bp;
+                       win0->area[0].ypos = st_y - v_pw_bp;
+                       break;
+               case WIN0_CTRL0:
+                       win0->state = val & m_WIN0_EN;
+                       win0->area[0].fmt_cfg = (val & m_WIN0_DATA_FMT) >> 1;
+                       win0->fmt_10 = (val & m_WIN0_FMT_10) >> 4;
+                       win0->area[0].format = win0->area[0].fmt_cfg;
+                       break;
+               case WIN0_VIR:
+                       win0->area[0].y_vir_stride = val & m_WIN0_VIR_STRIDE;
+                       win0->area[0].uv_vir_stride =
+                           (val & m_WIN0_VIR_STRIDE_UV) >> 16;
+                       if (win0->area[0].format == ARGB888)
+                               win0->area[0].xvir = win0->area[0].y_vir_stride;
+                       else if (win0->area[0].format == RGB888)
+                               win0->area[0].xvir =
+                                   win0->area[0].y_vir_stride * 4 / 3;
+                       else if (win0->area[0].format == RGB565)
+                               win0->area[0].xvir =
+                                   2 * win0->area[0].y_vir_stride;
+                       else    /* YUV */
+                               win0->area[0].xvir =
+                                   4 * win0->area[0].y_vir_stride;
+                       break;
+               case WIN0_YRGB_MST:
+                       win0->area[0].smem_start = val;
+                       break;
+               case WIN0_CBR_MST:
+                       win0->area[0].cbr_start = val;
+                       break;
+               default:
+                       break;
+               }
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+}
+
+/********do basic init*********/
+static int rk3368_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
+{
+       u32 mask, val;
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       if (lcdc_dev->pre_init)
+               return 0;
+
+       lcdc_dev->hclk = devm_clk_get(lcdc_dev->dev, "hclk_lcdc");
+       lcdc_dev->aclk = devm_clk_get(lcdc_dev->dev, "aclk_lcdc");
+       lcdc_dev->dclk = devm_clk_get(lcdc_dev->dev, "dclk_lcdc");
+       lcdc_dev->pll_sclk = devm_clk_get(lcdc_dev->dev, "sclk_pll");
+       lcdc_dev->pd = devm_clk_get(lcdc_dev->dev, "pd_lcdc");
+
+       if (IS_ERR(lcdc_dev->pd) || (IS_ERR(lcdc_dev->aclk)) ||
+           (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
+               dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
+                       lcdc_dev->id);
+       }
+
+       rk_disp_pwr_enable(dev_drv);
+       rk3368_lcdc_clk_enable(lcdc_dev);
+
+       /*backup reg config at uboot */
+       lcdc_read_reg_defalut_cfg(lcdc_dev);
+       lcdc_writel(lcdc_dev, CABC_GAUSS_LINE0_0, 0x15110903);
+       lcdc_writel(lcdc_dev, CABC_GAUSS_LINE0_1, 0x00030911);
+       lcdc_writel(lcdc_dev, CABC_GAUSS_LINE1_0, 0x1a150b04);
+       lcdc_writel(lcdc_dev, CABC_GAUSS_LINE1_1, 0x00040b15);
+       lcdc_writel(lcdc_dev, CABC_GAUSS_LINE2_0, 0x15110903);
+       lcdc_writel(lcdc_dev, CABC_GAUSS_LINE2_1, 0x00030911);
+
+       lcdc_writel(lcdc_dev, FRC_LOWER01_0, 0x12844821);
+       lcdc_writel(lcdc_dev, FRC_LOWER01_1, 0x21488412);
+       lcdc_writel(lcdc_dev, FRC_LOWER10_0, 0xa55a9696);
+       lcdc_writel(lcdc_dev, FRC_LOWER10_1, 0x5aa56969);
+       lcdc_writel(lcdc_dev, FRC_LOWER11_0, 0xdeb77deb);
+       lcdc_writel(lcdc_dev, FRC_LOWER11_1, 0xed7bb7de);
+
+       mask = m_AUTO_GATING_EN;
+       val = v_AUTO_GATING_EN(0);
+       lcdc_cfg_done(lcdc_dev);
+       /*disable win0 to workaround iommu pagefault */
+       /*if (dev_drv->iommu_enabled) */
+       /*      win0_enable(lcdc_dev, 0); */
+       lcdc_dev->pre_init = true;
+
+       return 0;
+}
+
+static void rk3368_lcdc_deint(struct lcdc_device *lcdc_dev)
+{
+       rk3368_lcdc_disable_irq(lcdc_dev);
+       spin_lock(&lcdc_dev->reg_lock);
+       if (likely(lcdc_dev->clk_on)) {
+               lcdc_dev->clk_on = 0;
+               lcdc_set_bit(lcdc_dev, SYS_CTRL, m_STANDBY_EN);
+               lcdc_cfg_done(lcdc_dev);
+               spin_unlock(&lcdc_dev->reg_lock);
+       } else {
+               spin_unlock(&lcdc_dev->reg_lock);
+       }
+       mdelay(1);
+}
+
+static int rk3368_lcdc_post_cfg(struct rk_lcdc_driver *dev_drv)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       struct rk_screen *screen = dev_drv->cur_screen;
+       u16 x_res = screen->mode.xres;
+       u16 y_res = screen->mode.yres;
+       u32 mask, val;
+       u16 h_total, v_total;
+       u16 post_hsd_en, post_vsd_en;
+       u16 post_dsp_hact_st, post_dsp_hact_end;
+       u16 post_dsp_vact_st, post_dsp_vact_end;
+       u16 post_dsp_vact_st_f1, post_dsp_vact_end_f1;
+       u16 post_h_fac, post_v_fac;
+
+       h_total = screen->mode.hsync_len + screen->mode.left_margin +
+           x_res + screen->mode.right_margin;
+       v_total = screen->mode.vsync_len + screen->mode.upper_margin +
+           y_res + screen->mode.lower_margin;
+
+       if (screen->post_dsp_stx + screen->post_xsize > x_res) {
+               dev_warn(lcdc_dev->dev, "post:stx[%d]+xsize[%d]>x_res[%d]\n",
+                        screen->post_dsp_stx, screen->post_xsize, x_res);
+               screen->post_dsp_stx = x_res - screen->post_xsize;
+       }
+       if (screen->x_mirror == 0) {
+               post_dsp_hact_st = screen->post_dsp_stx +
+                   screen->mode.hsync_len + screen->mode.left_margin;
+               post_dsp_hact_end = post_dsp_hact_st + screen->post_xsize;
+       } else {
+               post_dsp_hact_end = h_total - screen->mode.right_margin -
+                   screen->post_dsp_stx;
+               post_dsp_hact_st = post_dsp_hact_end - screen->post_xsize;
+       }
+       if ((screen->post_xsize < x_res) && (screen->post_xsize != 0)) {
+               post_hsd_en = 1;
+               post_h_fac =
+                   GET_SCALE_FACTOR_BILI_DN(x_res, screen->post_xsize);
+       } else {
+               post_hsd_en = 0;
+               post_h_fac = 0x1000;
+       }
+
+       if (screen->post_dsp_sty + screen->post_ysize > y_res) {
+               dev_warn(lcdc_dev->dev, "post:sty[%d]+ysize[%d]> y_res[%d]\n",
+                        screen->post_dsp_sty, screen->post_ysize, y_res);
+               screen->post_dsp_sty = y_res - screen->post_ysize;
+       }
+
+       if (screen->y_mirror == 0) {
+               post_dsp_vact_st = screen->post_dsp_sty +
+                   screen->mode.vsync_len + screen->mode.upper_margin;
+               post_dsp_vact_end = post_dsp_vact_st + screen->post_ysize;
+       } else {
+               post_dsp_vact_end = v_total - screen->mode.lower_margin -
+                   screen->post_dsp_sty;
+               post_dsp_vact_st = post_dsp_vact_end - screen->post_ysize;
+       }
+       if ((screen->post_ysize < y_res) && (screen->post_ysize != 0)) {
+               post_vsd_en = 1;
+               post_v_fac = GET_SCALE_FACTOR_BILI_DN(y_res,
+                                                     screen->post_ysize);
+       } else {
+               post_vsd_en = 0;
+               post_v_fac = 0x1000;
+       }
+
+       if (screen->interlace == 1) {
+               post_dsp_vact_st_f1 = v_total + post_dsp_vact_st;
+               post_dsp_vact_end_f1 = post_dsp_vact_st_f1 + screen->post_ysize;
+       } else {
+               post_dsp_vact_st_f1 = 0;
+               post_dsp_vact_end_f1 = 0;
+       }
+       DBG(1, "post:xsize=%d,ysize=%d,xpos=%d",
+           screen->post_xsize, screen->post_ysize, screen->xpos);
+       DBG(1, ",ypos=%d,hsd_en=%d,h_fac=%d,vsd_en=%d,v_fac=%d\n",
+           screen->ypos, post_hsd_en, post_h_fac, post_vsd_en, post_v_fac);
+       mask = m_DSP_HACT_END_POST | m_DSP_HACT_ST_POST;
+       val = v_DSP_HACT_END_POST(post_dsp_hact_end) |
+           v_DSP_HACT_ST_POST(post_dsp_hact_st);
+       lcdc_msk_reg(lcdc_dev, POST_DSP_HACT_INFO, mask, val);
+
+       mask = m_DSP_VACT_END_POST | m_DSP_VACT_ST_POST;
+       val = v_DSP_VACT_END_POST(post_dsp_vact_end) |
+           v_DSP_VACT_ST_POST(post_dsp_vact_st);
+       lcdc_msk_reg(lcdc_dev, POST_DSP_VACT_INFO, mask, val);
+
+       mask = m_POST_HS_FACTOR_YRGB | m_POST_VS_FACTOR_YRGB;
+       val = v_POST_HS_FACTOR_YRGB(post_h_fac) |
+           v_POST_VS_FACTOR_YRGB(post_v_fac);
+       lcdc_msk_reg(lcdc_dev, POST_SCL_FACTOR_YRGB, mask, val);
+
+       mask = m_DSP_VACT_END_POST_F1 | m_DSP_VACT_ST_POST_F1;
+       val = v_DSP_VACT_END_POST_F1(post_dsp_vact_end_f1) |
+           v_DSP_VACT_ST_POST_F1(post_dsp_vact_st_f1);
+       lcdc_msk_reg(lcdc_dev, POST_DSP_VACT_INFO_F1, mask, val);
+
+       mask = m_POST_HOR_SD_EN | m_POST_VER_SD_EN;
+       val = v_POST_HOR_SD_EN(post_hsd_en) | v_POST_VER_SD_EN(post_vsd_en);
+       lcdc_msk_reg(lcdc_dev, POST_SCL_CTRL, mask, val);
+       return 0;
+}
+
+static int rk3368_lcdc_clr_key_cfg(struct rk_lcdc_driver *dev_drv)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       struct rk_lcdc_win *win;
+       u32 colorkey_r, colorkey_g, colorkey_b;
+       int i, key_val;
+
+       for (i = 0; i < 4; i++) {
+               win = dev_drv->win[i];
+               key_val = win->color_key_val;
+               colorkey_r = (key_val & 0xff) << 2;
+               colorkey_g = ((key_val >> 8) & 0xff) << 12;
+               colorkey_b = ((key_val >> 16) & 0xff) << 22;
+               /*color key dither 565/888->aaa */
+               key_val = colorkey_r | colorkey_g | colorkey_b;
+               switch (i) {
+               case 0:
+                       lcdc_writel(lcdc_dev, WIN0_COLOR_KEY, key_val);
+                       break;
+               case 1:
+                       lcdc_writel(lcdc_dev, WIN1_COLOR_KEY, key_val);
+                       break;
+               case 2:
+                       lcdc_writel(lcdc_dev, WIN2_COLOR_KEY, key_val);
+                       break;
+               case 3:
+                       lcdc_writel(lcdc_dev, WIN3_COLOR_KEY, key_val);
+                       break;
+               default:
+                       pr_info("%s:un support win num:%d\n",
+                               __func__, i);
+                       break;
+               }
+       }
+       return 0;
+}
+
+static int rk3368_lcdc_alpha_cfg(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 = dev_drv->win[win_id];
+       struct alpha_config alpha_config;
+       u32 mask, val;
+       int ppixel_alpha = 0, global_alpha = 0, i;
+       u32 src_alpha_ctl, dst_alpha_ctl;
+
+       for (i = 0; i < win->area_num; i++) {
+               ppixel_alpha |= ((win->area[i].format == ARGB888) ||
+                                (win->area[i].format == ABGR888)) ? 1 : 0;
+       }
+       global_alpha = (win->g_alpha_val == 0) ? 0 : 1;
+       alpha_config.src_global_alpha_val = win->g_alpha_val;
+       win->alpha_mode = AB_SRC_OVER;
+       /*printk("%s,alpha_mode=%d,alpha_en=%d,ppixel_a=%d,gla_a=%d\n",
+          __func__,win->alpha_mode,win->alpha_en,ppixel_alpha,
+          global_alpha); */
+       switch (win->alpha_mode) {
+       case AB_USER_DEFINE:
+               break;
+       case AB_CLEAR:
+               alpha_config.src_factor_mode = AA_ZERO;
+               alpha_config.dst_factor_mode = AA_ZERO;
+               break;
+       case AB_SRC:
+               alpha_config.src_factor_mode = AA_ONE;
+               alpha_config.dst_factor_mode = AA_ZERO;
+               break;
+       case AB_DST:
+               alpha_config.src_factor_mode = AA_ZERO;
+               alpha_config.dst_factor_mode = AA_ONE;
+               break;
+       case AB_SRC_OVER:
+               alpha_config.src_color_mode = AA_SRC_PRE_MUL;
+               if (global_alpha)
+                       alpha_config.src_factor_mode = AA_SRC_GLOBAL;
+               else
+                       alpha_config.src_factor_mode = AA_ONE;
+               alpha_config.dst_factor_mode = AA_SRC_INVERSE;
+               break;
+       case AB_DST_OVER:
+               alpha_config.src_color_mode = AA_SRC_PRE_MUL;
+               alpha_config.src_factor_mode = AA_SRC_INVERSE;
+               alpha_config.dst_factor_mode = AA_ONE;
+               break;
+       case AB_SRC_IN:
+               alpha_config.src_color_mode = AA_SRC_PRE_MUL;
+               alpha_config.src_factor_mode = AA_SRC;
+               alpha_config.dst_factor_mode = AA_ZERO;
+               break;
+       case AB_DST_IN:
+               alpha_config.src_factor_mode = AA_ZERO;
+               alpha_config.dst_factor_mode = AA_SRC;
+               break;
+       case AB_SRC_OUT:
+               alpha_config.src_color_mode = AA_SRC_PRE_MUL;
+               alpha_config.src_factor_mode = AA_SRC_INVERSE;
+               alpha_config.dst_factor_mode = AA_ZERO;
+               break;
+       case AB_DST_OUT:
+               alpha_config.src_factor_mode = AA_ZERO;
+               alpha_config.dst_factor_mode = AA_SRC_INVERSE;
+               break;
+       case AB_SRC_ATOP:
+               alpha_config.src_color_mode = AA_SRC_PRE_MUL;
+               alpha_config.src_factor_mode = AA_SRC;
+               alpha_config.dst_factor_mode = AA_SRC_INVERSE;
+               break;
+       case AB_DST_ATOP:
+               alpha_config.src_color_mode = AA_SRC_PRE_MUL;
+               alpha_config.src_factor_mode = AA_SRC_INVERSE;
+               alpha_config.dst_factor_mode = AA_SRC;
+               break;
+       case XOR:
+               alpha_config.src_color_mode = AA_SRC_PRE_MUL;
+               alpha_config.src_factor_mode = AA_SRC_INVERSE;
+               alpha_config.dst_factor_mode = AA_SRC_INVERSE;
+               break;
+       case AB_SRC_OVER_GLOBAL:
+               alpha_config.src_global_alpha_mode = AA_PER_PIX_GLOBAL;
+               alpha_config.src_color_mode = AA_SRC_NO_PRE_MUL;
+               alpha_config.src_factor_mode = AA_SRC_GLOBAL;
+               alpha_config.dst_factor_mode = AA_SRC_INVERSE;
+               break;
+       default:
+               pr_err("alpha mode error\n");
+               break;
+       }
+       if ((ppixel_alpha == 1) && (global_alpha == 1))
+               alpha_config.src_global_alpha_mode = AA_PER_PIX_GLOBAL;
+       else if (ppixel_alpha == 1)
+               alpha_config.src_global_alpha_mode = AA_PER_PIX;
+       else if (global_alpha == 1)
+               alpha_config.src_global_alpha_mode = AA_GLOBAL;
+       else
+               dev_warn(lcdc_dev->dev, "alpha_en should be 0\n");
+       alpha_config.src_alpha_mode = AA_STRAIGHT;
+       alpha_config.src_alpha_cal_m0 = AA_NO_SAT;
+
+       switch (win_id) {
+       case 0:
+               src_alpha_ctl = 0x60;
+               dst_alpha_ctl = 0x64;
+               break;
+       case 1:
+               src_alpha_ctl = 0xa0;
+               dst_alpha_ctl = 0xa4;
+               break;
+       case 2:
+               src_alpha_ctl = 0xdc;
+               dst_alpha_ctl = 0xec;
+               break;
+       case 3:
+               src_alpha_ctl = 0x12c;
+               dst_alpha_ctl = 0x13c;
+               break;
+       case 4:
+               src_alpha_ctl = 0x160;
+               dst_alpha_ctl = 0x164;
+               break;
+       }
+       mask = m_WIN0_DST_FACTOR_M0;
+       val = v_WIN0_DST_FACTOR_M0(alpha_config.dst_factor_mode);
+       lcdc_msk_reg(lcdc_dev, dst_alpha_ctl, mask, val);
+       mask = m_WIN0_SRC_ALPHA_EN | m_WIN0_SRC_COLOR_M0 |
+           m_WIN0_SRC_ALPHA_M0 | m_WIN0_SRC_BLEND_M0 |
+           m_WIN0_SRC_ALPHA_CAL_M0 | m_WIN0_SRC_FACTOR_M0 |
+           m_WIN0_SRC_GLOBAL_ALPHA;
+       val = v_WIN0_SRC_ALPHA_EN(1) |
+           v_WIN0_SRC_COLOR_M0(alpha_config.src_color_mode) |
+           v_WIN0_SRC_ALPHA_M0(alpha_config.src_alpha_mode) |
+           v_WIN0_SRC_BLEND_M0(alpha_config.src_global_alpha_mode) |
+           v_WIN0_SRC_ALPHA_CAL_M0(alpha_config.src_alpha_cal_m0) |
+           v_WIN0_SRC_FACTOR_M0(alpha_config.src_factor_mode) |
+           v_WIN0_SRC_GLOBAL_ALPHA(alpha_config.src_global_alpha_val);
+       lcdc_msk_reg(lcdc_dev, src_alpha_ctl, mask, val);
+
+       return 0;
+}
+
+static int rk3368_lcdc_area_xst(struct rk_lcdc_win *win, int area_num)
+{
+       struct rk_lcdc_win_area area_temp;
+       int i, j;
+
+       for (i = 0; i < area_num; i++) {
+               for (j = i + 1; j < area_num; j++) {
+                       if (win->area[i].dsp_stx >  win->area[j].dsp_stx) {
+                               memcpy(&area_temp, &win->area[i],
+                                      sizeof(struct rk_lcdc_win_area));
+                               memcpy(&win->area[i], &win->area[j],
+                                      sizeof(struct rk_lcdc_win_area));
+                               memcpy(&win->area[j], &area_temp,
+                                      sizeof(struct rk_lcdc_win_area));
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static int rk3368_lcdc_area_swap(struct rk_lcdc_win *win, int area_num)
+{
+       struct rk_lcdc_win_area area_temp;
+
+       switch (area_num) {
+       case 2:
+               area_temp = win->area[0];
+               win->area[0] = win->area[1];
+               win->area[1] = area_temp;
+               break;
+       case 3:
+               area_temp = win->area[0];
+               win->area[0] = win->area[2];
+               win->area[2] = area_temp;
+               break;
+       case 4:
+               area_temp = win->area[0];
+               win->area[0] = win->area[3];
+               win->area[3] = area_temp;
+
+               area_temp = win->area[1];
+               win->area[1] = win->area[2];
+               win->area[2] = area_temp;
+               break;
+       default:
+               pr_info("un supported area num!\n");
+               break;
+       }
+       return 0;
+}
+
+static int rk3368_win_area_check_var(int win_id, int area_num,
+                                    struct rk_lcdc_win_area *area_pre,
+                                    struct rk_lcdc_win_area *area_now)
+{
+       if ((area_pre->xpos > area_now->xpos) ||
+           ((area_pre->xpos + area_pre->xsize > area_now->xpos) &&
+            (area_pre->ypos + area_pre->ysize > area_now->ypos))) {
+               area_now->state = 0;
+               pr_err("win[%d]:\n"
+                      "area_pre[%d]:xpos[%d],xsize[%d],ypos[%d],ysize[%d]\n"
+                      "area_now[%d]:xpos[%d],xsize[%d],ypos[%d],ysize[%d]\n",
+                      win_id,
+                      area_num - 1, area_pre->xpos, area_pre->xsize,
+                      area_pre->ypos, area_pre->ysize,
+                      area_num, area_now->xpos, area_now->xsize,
+                      area_now->ypos, area_now->ysize);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int __maybe_unused rk3368_get_fbdc_idle(struct rk_lcdc_driver *dev_drv)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       u32 val, i;
+
+       for (i = 0; i < 100; i++) {
+               val = lcdc_readl(lcdc_dev, IFBDC_DEBUG0);
+               val &= m_DBG_IFBDC_IDLE;
+               if (val)
+                       continue;
+               else
+                       mdelay(10);
+       };
+       return val;
+}
+
+static int rk3368_fbdc_reg_update(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 = dev_drv->win[win_id];
+       u32 mask, val;
+
+       mask = m_IFBDC_CTRL_FBDC_EN | m_IFBDC_CTRL_FBDC_COR_EN |
+           m_IFBDC_CTRL_FBDC_WIN_SEL | m_IFBDC_CTRL_FBDC_ROTATION_MODE |
+           m_IFBDC_CTRL_FBDC_FMT | m_IFBDC_CTRL_WIDTH_RATIO;
+       val = v_IFBDC_CTRL_FBDC_EN(win->area[0].fbdc_en) |
+           v_IFBDC_CTRL_FBDC_COR_EN(win->area[0].fbdc_cor_en) |
+           v_IFBDC_CTRL_FBDC_WIN_SEL(win->id) |
+           v_IFBDC_CTRL_FBDC_ROTATION_MODE(win->mirror_en << 1) |
+           v_IFBDC_CTRL_FBDC_FMT(win->area[0].fbdc_fmt_cfg) |
+           v_IFBDC_CTRL_WIDTH_RATIO(win->area[0].fbdc_dsp_width_ratio);
+       lcdc_msk_reg(lcdc_dev, IFBDC_CTRL, mask, val);
+
+       mask = m_IFBDC_TILES_NUM;
+       val = v_IFBDC_TILES_NUM(win->area[0].fbdc_num_tiles);
+       lcdc_msk_reg(lcdc_dev, IFBDC_TILES_NUM, mask, val);
+
+       mask = m_IFBDC_BASE_ADDR;
+       val = v_IFBDC_BASE_ADDR(win->area[0].y_addr);
+       lcdc_msk_reg(lcdc_dev, IFBDC_BASE_ADDR, mask, val);
+
+       mask = m_IFBDC_MB_SIZE_WIDTH | m_IFBDC_MB_SIZE_HEIGHT;
+       val = v_IFBDC_MB_SIZE_WIDTH(win->area[0].fbdc_mb_width) |
+           v_IFBDC_MB_SIZE_HEIGHT(win->area[0].fbdc_mb_height);
+       lcdc_msk_reg(lcdc_dev, IFBDC_MB_SIZE, mask, val);
+
+       mask = m_IFBDC_CMP_INDEX_INIT;
+       val = v_IFBDC_CMP_INDEX_INIT(win->area[0].fbdc_cmp_index_init);
+       lcdc_msk_reg(lcdc_dev, IFBDC_CMP_INDEX_INIT, mask, val);
+
+       mask = m_IFBDC_MB_VIR_WIDTH;
+       val = v_IFBDC_MB_VIR_WIDTH(win->area[0].fbdc_mb_vir_width);
+       lcdc_msk_reg(lcdc_dev, IFBDC_MB_VIR_WIDTH, mask, val);
+
+       return 0;
+}
+
+static int rk3368_init_fbdc_config(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 = dev_drv->win[win_id];
+       u8 fbdc_dsp_width_ratio;
+       u16 fbdc_mb_vir_width, fbdc_mb_vir_height;
+       u16 fbdc_mb_width, fbdc_mb_height;
+       u16 fbdc_mb_xst, fbdc_mb_yst, fbdc_num_tiles;
+       u16 fbdc_cmp_index_init;
+       u8 mb_w_size, mb_h_size;
+       struct rk_screen *screen = dev_drv->cur_screen;
+
+       if (screen->mode.flag == FB_VMODE_INTERLACED) {
+               dev_err(lcdc_dev->dev, "unsupport fbdc+interlace!\n");
+               return 0;
+       }
+
+       switch (win->area[0].fmt_cfg) {
+       case VOP_FORMAT_ARGB888:
+               fbdc_dsp_width_ratio = 0;
+               mb_w_size = 16;
+               break;
+       case VOP_FORMAT_RGB888:
+               fbdc_dsp_width_ratio = 0;
+               mb_w_size = 16;
+               break;
+       case VOP_FORMAT_RGB565:
+               mb_w_size = 32;
+               break;
+       default:
+               dev_err(lcdc_dev->dev,
+                       "in fbdc mode,unsupport fmt:%d!\n",
+                       win->area[0].fmt_cfg);
+               break;
+       }
+       mb_h_size = 4;
+
+       /*macro block xvir and yvir */
+       if ((win->area[0].xvir % mb_w_size == 0) &&
+           (win->area[0].yvir % mb_h_size == 0)) {
+               fbdc_mb_vir_width = win->area[0].xvir / mb_w_size;
+               fbdc_mb_vir_height = win->area[0].yvir / mb_h_size;
+       } else {
+               pr_err("fbdc fmt[%d]:", win->area[0].fmt_cfg);
+               pr_err("xvir[%d]/yvir[%d] should %d/%d pix align!\n",
+                      win->area[0].xvir, win->area[0].yvir,
+                      mb_w_size, mb_h_size);
+       }
+       /*macro block xact and yact */
+       if ((win->area[0].xact % mb_w_size == 0) &&
+           (win->area[0].yact % mb_h_size == 0)) {
+               fbdc_mb_width = win->area[0].xact / mb_w_size;
+               fbdc_mb_height = win->area[0].yact / mb_h_size;
+       } else {
+               pr_err("fbdc fmt[%d]:", win->area[0].fmt_cfg);
+               pr_err("xact[%d]/yact[%d] should %d/%d pix align!\n",
+                      win->area[0].xact, win->area[0].yact,
+                      mb_w_size, mb_h_size);
+       }
+       /*macro block xoff and yoff */
+       if ((win->area[0].xoff % mb_w_size == 0) &&
+           (win->area[0].yoff % mb_h_size == 0)) {
+               fbdc_mb_xst = win->area[0].xoff / mb_w_size;
+               fbdc_mb_yst = win->area[0].yoff / mb_h_size;
+       } else {
+               pr_err("fbdc fmt[%d]:", win->area[0].fmt_cfg);
+               pr_err("xoff[%d]/yoff[%d] should %d/%d pix align!\n",
+                      win->area[0].xoff, win->area[0].yoff,
+                      mb_w_size, mb_h_size);
+       }
+
+       /*FBDC tiles */
+       fbdc_num_tiles = fbdc_mb_vir_width * fbdc_mb_vir_height;
+
+       /*
+          switch (fbdc_rotation_mode)  {
+          case FBDC_ROT_NONE:
+          fbdc_cmp_index_init =
+          (fbdc_mb_yst*fbdc_mb_vir_width) +  fbdc_mb_xst;
+          break;
+          case FBDC_X_MIRROR:
+          fbdc_cmp_index_init =
+          (fbdc_mb_yst*fbdc_mb_vir_width) + (fbdc_mb_xst+
+          (fbdc_mb_width-1));
+          break;
+          case FBDC_Y_MIRROR:
+          fbdc_cmp_index_init =
+          ((fbdc_mb_yst+(fbdc_mb_height-1))*fbdc_mb_vir_width)  +
+          fbdc_mb_xst;
+          break;
+          case FBDC_ROT_180:
+          fbdc_cmp_index_init =
+          ((fbdc_mb_yst+(fbdc_mb_height-1))*fbdc_mb_vir_width) +
+          (fbdc_mb_xst+(fbdc_mb_width-1));
+          break;
+          }
+        */
+       if ((win->mirror_en) && ((win_id == 2) || (win_id == 3))) {
+               fbdc_cmp_index_init =
+                   ((fbdc_mb_yst + (fbdc_mb_height - 1)) * fbdc_mb_vir_width) +
+                   (fbdc_mb_xst + (fbdc_mb_width - 1));
+       } else {
+               fbdc_cmp_index_init =
+                   (fbdc_mb_yst * fbdc_mb_vir_width) + fbdc_mb_xst;
+       }
+       /*fbdc fmt maybe need to change*/
+       win->area[0].fbdc_fmt_cfg = win->area[0].fbdc_data_format;
+       win->area[0].fbdc_dsp_width_ratio = fbdc_dsp_width_ratio;
+       win->area[0].fbdc_mb_vir_width = fbdc_mb_vir_width;
+       win->area[0].fbdc_mb_vir_height = fbdc_mb_vir_height;
+       win->area[0].fbdc_mb_width = fbdc_mb_width;
+       win->area[0].fbdc_mb_height = fbdc_mb_height;
+       win->area[0].fbdc_mb_xst = fbdc_mb_xst;
+       win->area[0].fbdc_mb_yst = fbdc_mb_yst;
+       win->area[0].fbdc_num_tiles = fbdc_num_tiles;
+       win->area[0].fbdc_cmp_index_init = fbdc_cmp_index_init;
+
+       return 0;
+}
+
+static void rk3368_lcdc_csc_mode(struct lcdc_device *lcdc_dev,
+                                struct rk_lcdc_win *win)
+{
+       struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver;
+       struct rk_screen *screen = dev_drv->cur_screen;
+
+       if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
+               switch (win->area[0].fmt_cfg) {
+               case VOP_FORMAT_ARGB888:
+               case VOP_FORMAT_RGB888:
+               case VOP_FORMAT_RGB565:
+                       if ((screen->mode.xres < 1280) &&
+                           (screen->mode.yres < 720)) {
+                               win->csc_mode = VOP_R2Y_CSC_BT601;
+                       } else {
+                               win->csc_mode = VOP_R2Y_CSC_BT709;
+                       }
+                       break;
+               default:
+                       break;
+               }
+       } else if (dev_drv->overlay_mode == VOP_RGB_DOMAIN) {
+               switch (win->area[0].fmt_cfg) {
+               case VOP_FORMAT_YCBCR420:
+                       if ((win->id == 0) || (win->id == 1))
+                               win->csc_mode = VOP_Y2R_CSC_MPEG;
+                       break;
+               default:
+                       break;
+               }
+       }
+}
+
+static int rk3368_win_0_1_reg_update(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 = dev_drv->win[win_id];
+       unsigned int mask, val, off;
+
+       off = win_id * 0x40;
+       /*if(win->win_lb_mode == 5)
+          win->win_lb_mode = 4;
+          for rk3288 to fix hw bug? */
+
+       if (win->state == 1) {
+               rk3368_lcdc_csc_mode(lcdc_dev, win);
+               if (win->area[0].fbdc_en)
+                       rk3368_fbdc_reg_update(&lcdc_dev->driver, win_id);
+               mask = m_WIN0_EN | m_WIN0_DATA_FMT | m_WIN0_FMT_10 |
+                   m_WIN0_LB_MODE | m_WIN0_RB_SWAP | m_WIN0_X_MIRROR |
+                   m_WIN0_Y_MIRROR | m_WIN0_CSC_MODE;
+               val = v_WIN0_EN(win->state) |
+                   v_WIN0_DATA_FMT(win->area[0].fmt_cfg) |
+                   v_WIN0_FMT_10(win->fmt_10) |
+                   v_WIN0_LB_MODE(win->win_lb_mode) |
+                   v_WIN0_RB_SWAP(win->area[0].swap_rb) |
+                   v_WIN0_X_MIRROR(win->mirror_en) |
+                   v_WIN0_Y_MIRROR(win->mirror_en) |
+                   v_WIN0_CSC_MODE(win->csc_mode);
+               lcdc_msk_reg(lcdc_dev, WIN0_CTRL0 + off, mask, val);
+
+               mask = m_WIN0_BIC_COE_SEL |
+                   m_WIN0_VSD_YRGB_GT4 | m_WIN0_VSD_YRGB_GT2 |
+                   m_WIN0_VSD_CBR_GT4 | m_WIN0_VSD_CBR_GT2 |
+                   m_WIN0_YRGB_HOR_SCL_MODE | m_WIN0_YRGB_VER_SCL_MODE |
+                   m_WIN0_YRGB_HSD_MODE | m_WIN0_YRGB_VSU_MODE |
+                   m_WIN0_YRGB_VSD_MODE | m_WIN0_CBR_HOR_SCL_MODE |
+                   m_WIN0_CBR_VER_SCL_MODE | m_WIN0_CBR_HSD_MODE |
+                   m_WIN0_CBR_VSU_MODE | m_WIN0_CBR_VSD_MODE;
+               val = v_WIN0_BIC_COE_SEL(win->bic_coe_el) |
+                   v_WIN0_VSD_YRGB_GT4(win->vsd_yrgb_gt4) |
+                   v_WIN0_VSD_YRGB_GT2(win->vsd_yrgb_gt2) |
+                   v_WIN0_VSD_CBR_GT4(win->vsd_cbr_gt4) |
+                   v_WIN0_VSD_CBR_GT2(win->vsd_cbr_gt2) |
+                   v_WIN0_YRGB_HOR_SCL_MODE(win->yrgb_hor_scl_mode) |
+                   v_WIN0_YRGB_VER_SCL_MODE(win->yrgb_ver_scl_mode) |
+                   v_WIN0_YRGB_HSD_MODE(win->yrgb_hsd_mode) |
+                   v_WIN0_YRGB_VSU_MODE(win->yrgb_vsu_mode) |
+                   v_WIN0_YRGB_VSD_MODE(win->yrgb_vsd_mode) |
+                   v_WIN0_CBR_HOR_SCL_MODE(win->cbr_hor_scl_mode) |
+                   v_WIN0_CBR_VER_SCL_MODE(win->cbr_ver_scl_mode) |
+                   v_WIN0_CBR_HSD_MODE(win->cbr_hsd_mode) |
+                   v_WIN0_CBR_VSU_MODE(win->cbr_vsu_mode) |
+                   v_WIN0_CBR_VSD_MODE(win->cbr_vsd_mode);
+               lcdc_msk_reg(lcdc_dev, WIN0_CTRL1 + off, mask, val);
+               val = v_WIN0_VIR_STRIDE(win->area[0].y_vir_stride) |
+                   v_WIN0_VIR_STRIDE_UV(win->area[0].uv_vir_stride);
+               lcdc_writel(lcdc_dev, WIN0_VIR + off, val);
+               /*lcdc_writel(lcdc_dev, WIN0_YRGB_MST+off,
+                               win->area[0].y_addr);
+                  lcdc_writel(lcdc_dev, WIN0_CBR_MST+off,
+                               win->area[0].uv_addr); */
+               val = v_WIN0_ACT_WIDTH(win->area[0].xact) |
+                   v_WIN0_ACT_HEIGHT(win->area[0].yact);
+               lcdc_writel(lcdc_dev, WIN0_ACT_INFO + off, val);
+
+               val = v_WIN0_DSP_WIDTH(win->area[0].xsize) |
+                   v_WIN0_DSP_HEIGHT(win->area[0].ysize);
+               lcdc_writel(lcdc_dev, WIN0_DSP_INFO + off, val);
+
+               val = v_WIN0_DSP_XST(win->area[0].dsp_stx) |
+                   v_WIN0_DSP_YST(win->area[0].dsp_sty);
+               lcdc_writel(lcdc_dev, WIN0_DSP_ST + off, val);
+
+               val = v_WIN0_HS_FACTOR_YRGB(win->scale_yrgb_x) |
+                   v_WIN0_VS_FACTOR_YRGB(win->scale_yrgb_y);
+               lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB + off, val);
+
+               val = v_WIN0_HS_FACTOR_CBR(win->scale_cbcr_x) |
+                   v_WIN0_VS_FACTOR_CBR(win->scale_cbcr_y);
+               lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR + off, val);
+               if (win->alpha_en == 1) {
+                       rk3368_lcdc_alpha_cfg(dev_drv, win_id);
+               } else {
+                       mask = m_WIN0_SRC_ALPHA_EN;
+                       val = v_WIN0_SRC_ALPHA_EN(0);
+                       lcdc_msk_reg(lcdc_dev, WIN0_SRC_ALPHA_CTRL + off,
+                                    mask, val);
+               }
+       } else {
+               mask = m_WIN0_EN;
+               val = v_WIN0_EN(win->state);
+               lcdc_msk_reg(lcdc_dev, WIN0_CTRL0 + off, mask, val);
+       }
+       return 0;
+}
+
+static int rk3368_win_2_3_reg_update(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 = dev_drv->win[win_id];
+       struct rk_screen *screen = dev_drv->cur_screen;
+       unsigned int mask, val, off;
+
+       off = (win_id - 2) * 0x50;
+       rk3368_lcdc_area_xst(win, win->area_num);
+       if (((screen->y_mirror == 1) || (win->mirror_en)) &&
+           (win->area_num > 1)) {
+               rk3368_lcdc_area_swap(win, win->area_num);
+       }
+
+       if (win->state == 1) {
+               rk3368_lcdc_csc_mode(lcdc_dev, win);
+               if (win->area[0].fbdc_en)
+                       rk3368_fbdc_reg_update(&lcdc_dev->driver, win_id);
+
+               mask = m_WIN2_EN | m_WIN2_CSC_MODE;
+               val = v_WIN2_EN(1) | v_WIN1_CSC_MODE(win->csc_mode);
+               lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
+               /*area 0 */
+               if (win->area[0].state == 1) {
+                       mask = m_WIN2_MST0_EN | m_WIN2_DATA_FMT0 |
+                           m_WIN2_RB_SWAP0;
+                       val = v_WIN2_MST0_EN(win->area[0].state) |
+                           v_WIN2_DATA_FMT0(win->area[0].fmt_cfg) |
+                           v_WIN2_RB_SWAP0(win->area[0].swap_rb);
+                       lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
+
+                       mask = m_WIN2_VIR_STRIDE0;
+                       val = v_WIN2_VIR_STRIDE0(win->area[0].y_vir_stride);
+                       lcdc_msk_reg(lcdc_dev, WIN2_VIR0_1 + off, mask, val);
+
+                       /*lcdc_writel(lcdc_dev,WIN2_MST0+off,
+                          win->area[0].y_addr); */
+                       val = v_WIN2_DSP_WIDTH0(win->area[0].xsize) |
+                           v_WIN2_DSP_HEIGHT0(win->area[0].ysize);
+                       lcdc_writel(lcdc_dev, WIN2_DSP_INFO0 + off, val);
+                       val = v_WIN2_DSP_XST0(win->area[0].dsp_stx) |
+                           v_WIN2_DSP_YST0(win->area[0].dsp_sty);
+                       lcdc_writel(lcdc_dev, WIN2_DSP_ST0 + off, val);
+               } else {
+                       mask = m_WIN2_MST0_EN;
+                       val = v_WIN2_MST0_EN(0);
+                       lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
+               }
+               /*area 1 */
+               if (win->area[1].state == 1) {
+                       rk3368_win_area_check_var(win_id, 1,
+                                                 &win->area[0], &win->area[1]);
+
+                       mask = m_WIN2_MST1_EN | m_WIN2_DATA_FMT1 |
+                           m_WIN2_RB_SWAP1;
+                       val = v_WIN2_MST1_EN(win->area[1].state) |
+                           v_WIN2_DATA_FMT0(win->area[1].fmt_cfg) |
+                           v_WIN2_RB_SWAP0(win->area[1].swap_rb);
+                       lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
+
+                       mask = m_WIN2_VIR_STRIDE1;
+                       val = v_WIN2_VIR_STRIDE1(win->area[1].y_vir_stride);
+                       lcdc_msk_reg(lcdc_dev, WIN2_VIR0_1 + off, mask, val);
+
+                       /*lcdc_writel(lcdc_dev,WIN2_MST1+off,
+                          win->area[1].y_addr); */
+                       val = v_WIN2_DSP_WIDTH1(win->area[1].xsize) |
+                           v_WIN2_DSP_HEIGHT1(win->area[1].ysize);
+                       lcdc_writel(lcdc_dev, WIN2_DSP_INFO1 + off, val);
+                       val = v_WIN2_DSP_XST1(win->area[1].dsp_stx) |
+                           v_WIN2_DSP_YST1(win->area[1].dsp_sty);
+                       lcdc_writel(lcdc_dev, WIN2_DSP_ST1 + off, val);
+               } else {
+                       mask = m_WIN2_MST1_EN;
+                       val = v_WIN2_MST1_EN(0);
+                       lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
+               }
+               /*area 2 */
+               if (win->area[2].state == 1) {
+                       rk3368_win_area_check_var(win_id, 2,
+                                                 &win->area[1], &win->area[2]);
+
+                       mask = m_WIN2_MST2_EN | m_WIN2_DATA_FMT2 |
+                           m_WIN2_RB_SWAP2;
+                       val = v_WIN2_MST2_EN(win->area[2].state) |
+                           v_WIN2_DATA_FMT0(win->area[2].fmt_cfg) |
+                           v_WIN2_RB_SWAP0(win->area[2].swap_rb);
+                       lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
+
+                       mask = m_WIN2_VIR_STRIDE2;
+                       val = v_WIN2_VIR_STRIDE2(win->area[2].y_vir_stride);
+                       lcdc_msk_reg(lcdc_dev, WIN2_VIR2_3 + off, mask, val);
+
+                       /*lcdc_writel(lcdc_dev,WIN2_MST2+off,
+                          win->area[2].y_addr); */
+                       val = v_WIN2_DSP_WIDTH2(win->area[2].xsize) |
+                           v_WIN2_DSP_HEIGHT2(win->area[2].ysize);
+                       lcdc_writel(lcdc_dev, WIN2_DSP_INFO2 + off, val);
+                       val = v_WIN2_DSP_XST2(win->area[2].dsp_stx) |
+                           v_WIN2_DSP_YST2(win->area[2].dsp_sty);
+                       lcdc_writel(lcdc_dev, WIN2_DSP_ST2 + off, val);
+               } else {
+                       mask = m_WIN2_MST2_EN;
+                       val = v_WIN2_MST2_EN(0);
+                       lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
+               }
+               /*area 3 */
+               if (win->area[3].state == 1) {
+                       rk3368_win_area_check_var(win_id, 3,
+                                                 &win->area[2], &win->area[3]);
+
+                       mask = m_WIN2_MST3_EN | m_WIN2_DATA_FMT3 |
+                           m_WIN2_RB_SWAP3;
+                       val = v_WIN2_MST3_EN(win->area[3].state) |
+                           v_WIN2_DATA_FMT0(win->area[3].fmt_cfg) |
+                           v_WIN2_RB_SWAP0(win->area[3].swap_rb);
+                       lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
+
+                       mask = m_WIN2_VIR_STRIDE3;
+                       val = v_WIN2_VIR_STRIDE3(win->area[3].y_vir_stride);
+                       lcdc_msk_reg(lcdc_dev, WIN2_VIR2_3 + off, mask, val);
+
+                       /*lcdc_writel(lcdc_dev,WIN2_MST3+off,
+                          win->area[3].y_addr); */
+                       val = v_WIN2_DSP_WIDTH3(win->area[3].xsize) |
+                           v_WIN2_DSP_HEIGHT3(win->area[3].ysize);
+                       lcdc_writel(lcdc_dev, WIN2_DSP_INFO3 + off, val);
+                       val = v_WIN2_DSP_XST3(win->area[3].dsp_stx) |
+                           v_WIN2_DSP_YST3(win->area[3].dsp_sty);
+                       lcdc_writel(lcdc_dev, WIN2_DSP_ST3 + off, val);
+               } else {
+                       mask = m_WIN2_MST3_EN;
+                       val = v_WIN2_MST3_EN(0);
+                       lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
+               }
+
+               if (win->alpha_en == 1) {
+                       rk3368_lcdc_alpha_cfg(dev_drv, win_id);
+               } else {
+                       mask = m_WIN2_SRC_ALPHA_EN;
+                       val = v_WIN2_SRC_ALPHA_EN(0);
+                       lcdc_msk_reg(lcdc_dev, WIN2_SRC_ALPHA_CTRL + off,
+                                    mask, val);
+               }
+       } else {
+               mask = m_WIN2_EN | m_WIN2_MST0_EN |
+                   m_WIN2_MST0_EN | m_WIN2_MST2_EN | m_WIN2_MST3_EN;
+               val = v_WIN2_EN(win->state) | v_WIN2_MST0_EN(0) |
+                   v_WIN2_MST1_EN(0) | v_WIN2_MST2_EN(0) | v_WIN2_MST3_EN(0);
+               lcdc_msk_reg(lcdc_dev, WIN2_CTRL0 + off, mask, val);
+       }
+       return 0;
+}
+
+static int rk3368_hwc_reg_update(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 = dev_drv->win[win_id];
+       unsigned int mask, val, hwc_size = 0;
+
+       if (win->state == 1) {
+               rk3368_lcdc_csc_mode(lcdc_dev, win);
+               mask = m_HWC_EN | m_HWC_DATA_FMT |
+                   m_HWC_RB_SWAP | m_WIN0_CSC_MODE;
+               val = v_HWC_EN(1) | v_HWC_DATA_FMT(win->area[0].fmt_cfg) |
+                   v_HWC_RB_SWAP(win->area[0].swap_rb) |
+                   v_WIN0_CSC_MODE(win->csc_mode);
+               lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
+
+               if ((win->area[0].xsize == 32) && (win->area[0].ysize == 32))
+                       hwc_size = 0;
+               else if ((win->area[0].xsize == 64) &&
+                        (win->area[0].ysize == 64))
+                       hwc_size = 1;
+               else if ((win->area[0].xsize == 96) &&
+                        (win->area[0].ysize == 96))
+                       hwc_size = 2;
+               else if ((win->area[0].xsize == 128) &&
+                        (win->area[0].ysize == 128))
+                       hwc_size = 3;
+               else
+                       dev_err(lcdc_dev->dev, "un supported hwc size!\n");
+
+               mask = m_HWC_SIZE;
+               val = v_HWC_SIZE(hwc_size);
+               lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
+
+               mask = m_HWC_DSP_XST | m_HWC_DSP_YST;
+               val = v_HWC_DSP_XST(win->area[0].dsp_stx) |
+                   v_HWC_DSP_YST(win->area[0].dsp_sty);
+               lcdc_msk_reg(lcdc_dev, HWC_DSP_ST, mask, val);
+
+               if (win->alpha_en == 1) {
+                       rk3368_lcdc_alpha_cfg(dev_drv, win_id);
+               } else {
+                       mask = m_WIN2_SRC_ALPHA_EN;
+                       val = v_WIN2_SRC_ALPHA_EN(0);
+                       lcdc_msk_reg(lcdc_dev, WIN2_SRC_ALPHA_CTRL, mask, val);
+               }
+       } else {
+               mask = m_HWC_EN;
+               val = v_HWC_EN(win->state);
+               lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
+       }
+       return 0;
+}
+
+static int rk3368_lcdc_layer_update_regs(struct lcdc_device *lcdc_dev,
+                                        struct rk_lcdc_win *win)
+{
+       struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver;
+       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_STANDBY_EN,
+                            v_STANDBY_EN(lcdc_dev->standby));
+               if ((win->id == 0) || (win->id == 1))
+                       rk3368_win_0_1_reg_update(dev_drv, win->id);
+               else if ((win->id == 2) || (win->id == 3))
+                       rk3368_win_2_3_reg_update(dev_drv, win->id);
+               else if (win->id == 4)
+                       rk3368_hwc_reg_update(dev_drv, win->id);
+               /*rk3368_lcdc_post_cfg(dev_drv); */
+               lcdc_cfg_done(lcdc_dev);
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+
+       /*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);
+               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_warn(lcdc_dev->dev,
+                                "wait for new frame start time out!\n");
+                       return -ETIMEDOUT;
+               }
+       }
+       DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
+       return 0;
+}
+
+static int rk3368_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
+{
+       if (lcdc_dev->driver.iommu_enabled)
+               memcpy((u8 *)lcdc_dev->regs, (u8 *)lcdc_dev->regsbak, 0x330);
+       else
+               memcpy((u8 *)lcdc_dev->regs, (u8 *)lcdc_dev->regsbak, 0x260);
+       return 0;
+}
+
+static int __maybe_unused rk3368_lcdc_mmu_en(struct rk_lcdc_driver *dev_drv)
+{
+       u32 mask, val;
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       /*spin_lock(&lcdc_dev->reg_lock); */
+       if (likely(lcdc_dev->clk_on)) {
+               mask = m_MMU_EN;
+               val = v_MMU_EN(1);
+               lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
+               mask = m_AXI_MAX_OUTSTANDING_EN | m_AXI_OUTSTANDING_MAX_NUM;
+               val = v_AXI_OUTSTANDING_MAX_NUM(31) |
+                   v_AXI_MAX_OUTSTANDING_EN(1);
+               lcdc_msk_reg(lcdc_dev, SYS_CTRL1, mask, val);
+       }
+       /*spin_unlock(&lcdc_dev->reg_lock); */
+#if defined(CONFIG_ROCKCHIP_IOMMU)
+       if (dev_drv->iommu_enabled) {
+               if (!lcdc_dev->iommu_status && dev_drv->mmu_dev) {
+                       lcdc_dev->iommu_status = 1;
+                       rockchip_iovmm_activate(dev_drv->dev);
+                       rk312x_lcdc_mmu_en(dev_drv);
+               }
+       }
+#endif
+       return 0;
+}
+
+static int rk3368_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv)
+{
+       int ret = 0, fps = 0;
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       struct rk_screen *screen = dev_drv->cur_screen;
+#ifdef CONFIG_RK_FPGA
+       return 0;
+#endif
+       /*set pll */
+       ret = clk_set_rate(lcdc_dev->pll_sclk, screen->mode.pixclock);
+       if (ret)
+               dev_err(dev_drv->dev, "set lcdc%d pll_sclk failed\n",
+                       lcdc_dev->id);
+
+       ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);/*set pll */
+       if (ret)
+               dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
+       lcdc_dev->pixclock =
+           div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
+       lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
+
+       fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
+       screen->ft = 1000 / fps;
+       dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
+                lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
+       return 0;
+}
+
+static int rk3368_config_timing(struct rk_lcdc_driver *dev_drv)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       struct rk_screen *screen = dev_drv->cur_screen;
+       u16 hsync_len = screen->mode.hsync_len;
+       u16 left_margin = screen->mode.left_margin;
+       u16 right_margin = screen->mode.right_margin;
+       u16 vsync_len = screen->mode.vsync_len;
+       u16 upper_margin = screen->mode.upper_margin;
+       u16 lower_margin = screen->mode.lower_margin;
+       u16 x_res = screen->mode.xres;
+       u16 y_res = screen->mode.yres;
+       u32 mask, val;
+       u16 h_total, v_total;
+       u16 vact_end_f1, vact_st_f1, vs_end_f1, vs_st_f1;
+
+       h_total = hsync_len + left_margin + x_res + right_margin;
+       v_total = vsync_len + upper_margin + y_res + lower_margin;
+
+       screen->post_dsp_stx = x_res * (100 - screen->overscan.left) / 200;
+       screen->post_dsp_sty = y_res * (100 - screen->overscan.top) / 200;
+       screen->post_xsize = x_res *
+           (screen->overscan.left + screen->overscan.right) / 200;
+       screen->post_ysize = y_res *
+           (screen->overscan.top + screen->overscan.bottom) / 200;
+
+       mask = m_DSP_HS_PW | m_DSP_HTOTAL;
+       val = v_DSP_HS_PW(hsync_len) | v_DSP_HTOTAL(h_total);
+       lcdc_msk_reg(lcdc_dev, DSP_HTOTAL_HS_END, mask, val);
+
+       mask = m_DSP_HACT_END | m_DSP_HACT_ST;
+       val = v_DSP_HACT_END(hsync_len + left_margin + x_res) |
+           v_DSP_HACT_ST(hsync_len + left_margin);
+       lcdc_msk_reg(lcdc_dev, DSP_HACT_ST_END, mask, val);
+
+       if (screen->mode.vmode == FB_VMODE_INTERLACED) {
+               /* First Field Timing */
+               mask = m_DSP_VS_PW | m_DSP_VTOTAL;
+               val = v_DSP_VS_PW(vsync_len) |
+                   v_DSP_VTOTAL(2 * (vsync_len + upper_margin +
+                                     lower_margin) + y_res + 1);
+               lcdc_msk_reg(lcdc_dev, DSP_VTOTAL_VS_END, mask, val);
+
+               mask = m_DSP_VACT_END | m_DSP_VACT_ST;
+               val = v_DSP_VACT_END(vsync_len + upper_margin + y_res / 2) |
+                   v_DSP_VACT_ST(vsync_len + upper_margin);
+               lcdc_msk_reg(lcdc_dev, DSP_VACT_ST_END, mask, val);
+
+               /* Second Field Timing */
+               mask = m_DSP_VS_ST_F1 | m_DSP_VS_END_F1;
+               vs_st_f1 = vsync_len + upper_margin + y_res / 2 + lower_margin;
+               vs_end_f1 = 2 * vsync_len + upper_margin + y_res / 2 +
+                   lower_margin;
+               val = v_DSP_VS_ST_F1(vs_st_f1) | v_DSP_VS_END_F1(vs_end_f1);
+               lcdc_msk_reg(lcdc_dev, DSP_VS_ST_END_F1, mask, val);
+
+               mask = m_DSP_VACT_END_F1 | m_DSP_VAC_ST_F1;
+               vact_end_f1 = 2 * (vsync_len + upper_margin) + y_res +
+                   lower_margin + 1;
+               vact_st_f1 = 2 * (vsync_len + upper_margin) + y_res / 2 +
+                   lower_margin + 1;
+               val =
+                   v_DSP_VACT_END_F1(vact_end_f1) |
+                   v_DSP_VAC_ST_F1(vact_st_f1);
+               lcdc_msk_reg(lcdc_dev, DSP_VACT_ST_END_F1, mask, val);
+
+               lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
+                            m_DSP_INTERLACE | m_DSP_FIELD_POL,
+                            v_DSP_INTERLACE(1) | v_DSP_FIELD_POL(0));
+               mask =
+                   m_WIN0_INTERLACE_READ | m_WIN0_YRGB_DEFLICK |
+                   m_WIN0_CBR_DEFLICK;
+               val =
+                   v_WIN0_INTERLACE_READ(1) | v_WIN0_YRGB_DEFLICK(1) |
+                   v_WIN0_CBR_DEFLICK(1);
+               lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
+
+               mask =
+                   m_WIN1_INTERLACE_READ | m_WIN1_YRGB_DEFLICK |
+                   m_WIN1_CBR_DEFLICK;
+               val =
+                   v_WIN1_INTERLACE_READ(1) | v_WIN1_YRGB_DEFLICK(1) |
+                   v_WIN1_CBR_DEFLICK(1);
+               lcdc_msk_reg(lcdc_dev, WIN1_CTRL0, mask, val);
+
+               mask = m_WIN2_INTERLACE_READ;
+               val = v_WIN2_INTERLACE_READ(1);
+               lcdc_msk_reg(lcdc_dev, WIN2_CTRL0, mask, val);
+
+               mask = m_WIN3_INTERLACE_READ;
+               val = v_WIN3_INTERLACE_READ(1);
+               lcdc_msk_reg(lcdc_dev, WIN3_CTRL0, mask, val);
+
+               mask = m_HWC_INTERLACE_READ;
+               val = v_HWC_INTERLACE_READ(1);
+               lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
+
+               mask = m_DSP_LINE_FLAG0_NUM;
+               val =
+                   v_DSP_LINE_FLAG0_NUM(vsync_len + upper_margin + y_res / 2);
+               lcdc_msk_reg(lcdc_dev, LINE_FLAG, mask, val);
+       } else {
+               mask = m_DSP_VS_PW | m_DSP_VTOTAL;
+               val = v_DSP_VS_PW(vsync_len) | v_DSP_VTOTAL(v_total);
+               lcdc_msk_reg(lcdc_dev, DSP_VTOTAL_VS_END, mask, val);
+
+               mask = m_DSP_VACT_END | m_DSP_VACT_ST;
+               val = v_DSP_VACT_END(vsync_len + upper_margin + y_res) |
+                   v_DSP_VACT_ST(vsync_len + upper_margin);
+               lcdc_msk_reg(lcdc_dev, DSP_VACT_ST_END, mask, val);
+
+               lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
+                            m_DSP_INTERLACE | m_DSP_FIELD_POL,
+                            v_DSP_INTERLACE(0) | v_DSP_FIELD_POL(0));
+
+               mask =
+                   m_WIN0_INTERLACE_READ | m_WIN0_YRGB_DEFLICK |
+                   m_WIN0_CBR_DEFLICK;
+               val =
+                   v_WIN0_INTERLACE_READ(0) | v_WIN0_YRGB_DEFLICK(0) |
+                   v_WIN0_CBR_DEFLICK(0);
+               lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
+
+               mask =
+                   m_WIN1_INTERLACE_READ | m_WIN1_YRGB_DEFLICK |
+                   m_WIN1_CBR_DEFLICK;
+               val =
+                   v_WIN1_INTERLACE_READ(0) | v_WIN1_YRGB_DEFLICK(0) |
+                   v_WIN1_CBR_DEFLICK(0);
+               lcdc_msk_reg(lcdc_dev, WIN1_CTRL0, mask, val);
+
+               mask = m_WIN2_INTERLACE_READ;
+               val = v_WIN2_INTERLACE_READ(0);
+               lcdc_msk_reg(lcdc_dev, WIN2_CTRL0, mask, val);
+
+               mask = m_WIN3_INTERLACE_READ;
+               val = v_WIN3_INTERLACE_READ(0);
+               lcdc_msk_reg(lcdc_dev, WIN3_CTRL0, mask, val);
+
+               mask = m_HWC_INTERLACE_READ;
+               val = v_HWC_INTERLACE_READ(0);
+               lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
+
+               mask = m_DSP_LINE_FLAG0_NUM;
+               val = v_DSP_LINE_FLAG0_NUM(vsync_len + upper_margin + y_res);
+               lcdc_msk_reg(lcdc_dev, LINE_FLAG, mask, val);
+       }
+       rk3368_lcdc_post_cfg(dev_drv);
+       return 0;
+}
+
+static void rk3368_lcdc_bcsh_path_sel(struct rk_lcdc_driver *dev_drv)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       u32 bcsh_ctrl;
+
+       if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
+               if (dev_drv->output_color == COLOR_YCBCR)       /* bypass */
+                       lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
+                                    m_BCSH_Y2R_EN | m_BCSH_R2Y_EN,
+                                    v_BCSH_Y2R_EN(0) | v_BCSH_R2Y_EN(0));
+               else            /* YUV2RGB */
+                       lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
+                                    m_BCSH_Y2R_EN | m_BCSH_Y2R_CSC_MODE |
+                                    m_BCSH_R2Y_EN,
+                                    v_BCSH_Y2R_EN(1) |
+                                    v_BCSH_Y2R_CSC_MODE(VOP_Y2R_CSC_MPEG) |
+                                    v_BCSH_R2Y_EN(0));
+       } else {                /* overlay_mode=VOP_RGB_DOMAIN */
+               /* bypass  --need check,if bcsh close? */
+               if (dev_drv->output_color == COLOR_RGB) {
+                       bcsh_ctrl = lcdc_readl(lcdc_dev, BCSH_CTRL);
+                       if ((bcsh_ctrl & m_BCSH_EN) == 1)/*bcsh enabled */
+                               lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
+                                            m_BCSH_R2Y_EN |
+                                            m_BCSH_Y2R_EN,
+                                            v_BCSH_R2Y_EN(1) |
+                                            v_BCSH_Y2R_EN(1));
+                       else
+                               lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
+                                            m_BCSH_R2Y_EN | m_BCSH_Y2R_EN,
+                                            v_BCSH_R2Y_EN(0) |
+                                            v_BCSH_Y2R_EN(0));
+               } else          /* RGB2YUV */
+                       lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
+                                    m_BCSH_R2Y_EN |
+                                    m_BCSH_R2Y_CSC_MODE | m_BCSH_Y2R_EN,
+                                    v_BCSH_R2Y_EN(1) |
+                                    v_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG) |
+                                    v_BCSH_Y2R_EN(0));
+       }
+}
+
+static int rk3368_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
+{
+       u16 face = 0;
+       u16 dclk_ddr = 0;
+       u32 v = 0;
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       struct rk_screen *screen = dev_drv->cur_screen;
+       u32 mask, val;
+
+       spin_lock(&lcdc_dev->reg_lock);
+       if (likely(lcdc_dev->clk_on)) {
+               dev_drv->overlay_mode = VOP_RGB_DOMAIN;
+               if (!lcdc_dev->standby && !initscreen) {
+                       lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
+                                    v_STANDBY_EN(1));
+                       lcdc_cfg_done(lcdc_dev);
+                       mdelay(50);
+               }
+               switch (screen->face) {
+               case OUT_P565:
+                       face = OUT_P565;
+                       mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
+                           m_DITHER_DOWN_SEL;
+                       val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
+                           v_DITHER_DOWN_SEL(1);
+                       lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
+                       break;
+               case OUT_P666:
+                       face = OUT_P666;
+                       mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
+                           m_DITHER_DOWN_SEL;
+                       val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
+                           v_DITHER_DOWN_SEL(1);
+                       lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
+                       break;
+               case OUT_D888_P565:
+                       face = OUT_P888;
+                       mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
+                           m_DITHER_DOWN_SEL;
+                       val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
+                           v_DITHER_DOWN_SEL(1);
+                       lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
+                       break;
+               case OUT_D888_P666:
+                       face = OUT_P888;
+                       mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
+                           m_DITHER_DOWN_SEL;
+                       val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
+                           v_DITHER_DOWN_SEL(1);
+                       lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
+                       break;
+               case OUT_P888:
+                       face = OUT_P888;
+                       mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
+                       val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
+                       lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
+                       break;
+               case OUT_YUV_420:
+                       /*yuv420 output prefer yuv domain overlay */
+                       face = OUT_YUV_420;
+                       dclk_ddr = 1;
+                       mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
+                       val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
+                       lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
+                       break;
+               default:
+                       dev_err(lcdc_dev->dev, "un supported interface!\n");
+                       break;
+               }
+               switch (screen->type) {
+               case SCREEN_RGB:
+                       mask = m_RGB_OUT_EN;
+                       val = v_RGB_OUT_EN(1);
+                       lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
+                       mask = m_RGB_LVDS_HSYNC_POL | m_RGB_LVDS_VSYNC_POL |
+                           m_RGB_LVDS_DEN_POL | m_RGB_LVDS_DCLK_POL;
+                       val = v_RGB_LVDS_HSYNC_POL(screen->pin_hsync) |
+                           v_RGB_LVDS_VSYNC_POL(screen->pin_vsync) |
+                           v_RGB_LVDS_DEN_POL(screen->pin_den) |
+                           v_RGB_LVDS_DCLK_POL(screen->pin_dclk);
+                       v = 1 << 15 | (1 << (15 + 16));
+
+                       break;
+               case SCREEN_LVDS:
+                       mask = m_RGB_OUT_EN;
+                       val = v_RGB_OUT_EN(1);
+                       lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
+                       mask = m_RGB_LVDS_HSYNC_POL | m_RGB_LVDS_VSYNC_POL |
+                           m_RGB_LVDS_DEN_POL | m_RGB_LVDS_DCLK_POL;
+                       val = v_RGB_LVDS_HSYNC_POL(screen->pin_hsync) |
+                           v_RGB_LVDS_VSYNC_POL(screen->pin_vsync) |
+                           v_RGB_LVDS_DEN_POL(screen->pin_den) |
+                           v_RGB_LVDS_DCLK_POL(screen->pin_dclk);
+                       v = 0 << 15 | (1 << (15 + 16));
+                       break;
+               case SCREEN_HDMI:
+                       face = OUT_RGB_AAA;
+                       mask = m_HDMI_OUT_EN;
+                       val = v_HDMI_OUT_EN(1);
+                       lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
+                       mask = m_HDMI_HSYNC_POL | m_HDMI_VSYNC_POL |
+                           m_HDMI_DEN_POL | m_HDMI_DCLK_POL;
+                       val = v_HDMI_HSYNC_POL(screen->pin_hsync) |
+                           v_HDMI_VSYNC_POL(screen->pin_vsync) |
+                           v_HDMI_DEN_POL(screen->pin_den) |
+                           v_HDMI_DCLK_POL(screen->pin_dclk);
+                       break;
+               case SCREEN_MIPI:
+                       mask = m_MIPI_OUT_EN;
+                       val = v_MIPI_OUT_EN(1);
+                       lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
+                       mask = m_MIPI_HSYNC_POL | m_MIPI_VSYNC_POL |
+                           m_MIPI_DEN_POL | m_MIPI_DCLK_POL;
+                       val = v_MIPI_HSYNC_POL(screen->pin_hsync) |
+                           v_MIPI_VSYNC_POL(screen->pin_vsync) |
+                           v_MIPI_DEN_POL(screen->pin_den) |
+                           v_MIPI_DCLK_POL(screen->pin_dclk);
+                       break;
+               case SCREEN_DUAL_MIPI:
+                       mask = m_MIPI_OUT_EN | m_DOUB_CHANNEL_EN;
+                       val = v_MIPI_OUT_EN(1) | v_DOUB_CHANNEL_EN(1);
+                       lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
+                       mask = m_MIPI_HSYNC_POL | m_MIPI_VSYNC_POL |
+                           m_MIPI_DEN_POL | m_MIPI_DCLK_POL;
+                       val = v_MIPI_HSYNC_POL(screen->pin_hsync) |
+                           v_MIPI_VSYNC_POL(screen->pin_vsync) |
+                           v_MIPI_DEN_POL(screen->pin_den) |
+                           v_MIPI_DCLK_POL(screen->pin_dclk);
+                       break;
+               case SCREEN_EDP:
+                       face = OUT_RGB_AAA;     /*RGB AAA output */
+
+                       mask = m_EDP_OUT_EN;
+                       val = v_EDP_OUT_EN(1);
+                       lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
+                       /*because edp have to sent aaa fmt */
+                       mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
+                       val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
+
+                       mask |= m_EDP_HSYNC_POL | m_EDP_VSYNC_POL |
+                           m_EDP_DEN_POL | m_EDP_DCLK_POL;
+                       val |= v_EDP_HSYNC_POL(screen->pin_hsync) |
+                           v_EDP_VSYNC_POL(screen->pin_vsync) |
+                           v_EDP_DEN_POL(screen->pin_den) |
+                           v_EDP_DCLK_POL(screen->pin_dclk);
+                       break;
+               }
+               /*hsync vsync den dclk polo,dither */
+               lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
+#ifndef CONFIG_RK_FPGA
+               /*writel_relaxed(v, RK_GRF_VIRT + rk3368_GRF_SOC_CON7);
+               move to  lvds driver*/
+               /*GRF_SOC_CON7 bit[15]:0->dsi/lvds mode,1->ttl mode */
+#endif
+               mask = m_DSP_OUT_MODE | m_DSP_DCLK_DDR | m_DSP_BG_SWAP |
+                   m_DSP_RB_SWAP | m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
+                   m_DSP_DUMMY_SWAP | m_DSP_OUT_ZERO | m_DSP_BLANK_EN |
+                   m_DSP_BLACK_EN | m_DSP_X_MIR_EN | m_DSP_Y_MIR_EN;
+               val = v_DSP_OUT_MODE(face) | v_DSP_DCLK_DDR(dclk_ddr) |
+                   v_DSP_BG_SWAP(screen->swap_gb) |
+                   v_DSP_RB_SWAP(screen->swap_rb) |
+                   v_DSP_RG_SWAP(screen->swap_rg) |
+                   v_DSP_DELTA_SWAP(screen->swap_delta) |
+                   v_DSP_DUMMY_SWAP(screen->swap_dumy) | v_DSP_OUT_ZERO(0) |
+                   v_DSP_BLANK_EN(0) | v_DSP_BLACK_EN(0) |
+                   v_DSP_X_MIR_EN(screen->x_mirror) |
+                   v_DSP_Y_MIR_EN(screen->y_mirror);
+               lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
+               /*BG color */
+               mask = m_DSP_BG_BLUE | m_DSP_BG_GREEN | m_DSP_BG_RED;
+               val = v_DSP_BG_BLUE(0) | v_DSP_BG_GREEN(0) | v_DSP_BG_RED(0);
+               lcdc_msk_reg(lcdc_dev, DSP_BG, mask, val);
+               rk3368_lcdc_bcsh_path_sel(dev_drv);
+               rk3368_config_timing(dev_drv);
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+       rk3368_lcdc_set_dclk(dev_drv);
+       if (screen->type != SCREEN_HDMI && dev_drv->trsm_ops &&
+           dev_drv->trsm_ops->enable)
+               dev_drv->trsm_ops->enable();
+       if (screen->init)
+               screen->init();
+       if (!lcdc_dev->standby)
+               lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN, v_STANDBY_EN(0));
+       return 0;
+}
+
+
+/*enable layer,open:1,enable;0 disable*/
+static void rk3368_lcdc_layer_enable(struct lcdc_device *lcdc_dev,
+                                    unsigned int win_id, bool open)
+{
+       spin_lock(&lcdc_dev->reg_lock);
+       if (likely(lcdc_dev->clk_on) &&
+           lcdc_dev->driver.win[win_id]->state != open) {
+               if (open) {
+                       if (!lcdc_dev->atv_layer_cnt) {
+                               dev_info(lcdc_dev->dev,
+                                        "wakeup from standby!\n");
+                               lcdc_dev->standby = 0;
+                       }
+                       lcdc_dev->atv_layer_cnt |= (1 << win_id);
+               } else {
+                       if (lcdc_dev->atv_layer_cnt & (1 << win_id))
+                               lcdc_dev->atv_layer_cnt &= ~(1 << win_id);
+               }
+               lcdc_dev->driver.win[win_id]->state = open;
+               if (!open) {
+                       /*rk3368_lcdc_reg_update(dev_drv);*/
+                       rk3368_lcdc_layer_update_regs
+                       (lcdc_dev, lcdc_dev->driver.win[win_id]);
+                       lcdc_cfg_done(lcdc_dev);
+               }
+               /*if no layer used,disable lcdc */
+               if (!lcdc_dev->atv_layer_cnt) {
+                       dev_info(lcdc_dev->dev,
+                                "no layer is used,go to standby!\n");
+                       lcdc_dev->standby = 1;
+               }
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+}
+
+static int rk3368_lcdc_enable_irq(struct rk_lcdc_driver *dev_drv)
+{
+       struct lcdc_device *lcdc_dev = container_of(dev_drv,
+                                                   struct lcdc_device, driver);
+       u32 mask, val;
+       /*struct rk_screen *screen = dev_drv->cur_screen; */
+
+       mask = m_FS_INTR_CLR | m_FS_NEW_INTR_CLR | m_LINE_FLAG0_INTR_CLR |
+           m_LINE_FLAG1_INTR_CLR;
+       val = v_FS_INTR_CLR(1) | v_FS_NEW_INTR_CLR(1) |
+           v_LINE_FLAG0_INTR_CLR(1) | v_LINE_FLAG1_INTR_CLR(1);
+       lcdc_msk_reg(lcdc_dev, INTR_CLEAR, mask, val);
+
+       mask = m_FS_INTR_EN | m_LINE_FLAG0_INTR_EN | m_BUS_ERROR_INTR_EN;
+       val = v_FS_INTR_EN(1) | v_LINE_FLAG0_INTR_EN(1) |
+           v_BUS_ERROR_INTR_EN(1);
+       lcdc_msk_reg(lcdc_dev, INTR_EN, mask, val);
+
+#ifdef LCDC_IRQ_EMPTY_DEBUG
+       mask = m_WIN0_EMPTY_INTR_EN | m_WIN1_EMPTY_INTR_EN |
+           m_WIN2_EMPTY_INTR_EN |
+           m_WIN3_EMPTY_INTR_EN | m_HWC_EMPTY_INTR_EN |
+           m_POST_BUF_EMPTY_INTR_EN | m_PWM_GEN_INTR_EN;
+       val = v_WIN0_EMPTY_INTR_EN(1) | v_WIN1_EMPTY_INTR_EN(1) |
+           v_WIN2_EMPTY_INTR_EN(1) |
+           v_WIN3_EMPTY_INTR_EN(1) | v_HWC_EMPTY_INTR_EN(1) |
+           v_POST_BUF_EMPTY_INTR_EN(1) | v_PWM_GEN_INTR_EN(1);
+       lcdc_msk_reg(lcdc_dev, INTR_EN, mask, val);
+#endif
+       return 0;
+}
+
+static int rk3368_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
+                           bool open)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+#ifndef CONFIG_RK_FPGA
+       int sys_status =
+           (dev_drv->id == 0) ? SYS_STATUS_LCDC0 : SYS_STATUS_LCDC1;
+#endif
+       /*enable clk,when first layer open */
+       if ((open) && (!lcdc_dev->atv_layer_cnt)) {
+#ifndef CONFIG_RK_FPGA
+               rockchip_set_system_status(sys_status);
+#endif
+               rk3368_lcdc_pre_init(dev_drv);
+               rk3368_lcdc_clk_enable(lcdc_dev);
+#if defined(CONFIG_ROCKCHIP_IOMMU)
+               if (dev_drv->iommu_enabled) {
+                       if (!dev_drv->mmu_dev) {
+                               dev_drv->mmu_dev =
+                                   rk_fb_get_sysmmu_device_by_compatible
+                                   (dev_drv->mmu_dts_name);
+                               if (dev_drv->mmu_dev) {
+                                       rk_fb_platform_set_sysmmu
+                                           (dev_drv->mmu_dev, dev_drv->dev);
+                               } else {
+                                       dev_err(dev_drv->dev,
+                                               "fail get rk iommu device\n");
+                                       return -1;
+                               }
+                       }
+                       /*if (dev_drv->mmu_dev)
+                          rockchip_iovmm_activate(dev_drv->dev); */
+               }
+#endif
+               rk3368_lcdc_reg_restore(lcdc_dev);
+               /*if (dev_drv->iommu_enabled)
+                  rk3368_lcdc_mmu_en(dev_drv); */
+               if ((support_uboot_display() && (lcdc_dev->prop == PRMRY))) {
+                       /*rk3368_lcdc_set_dclk(dev_drv); */
+                       rk3368_lcdc_enable_irq(dev_drv);
+               } else {
+                       rk3368_load_screen(dev_drv, 1);
+               }
+               if (dev_drv->bcsh.enable)
+                       rk3368_lcdc_set_bcsh(dev_drv, 1);
+               spin_lock(&lcdc_dev->reg_lock);
+               if (dev_drv->cur_screen->dsp_lut)
+                       rk3368_lcdc_set_lut(dev_drv);
+               spin_unlock(&lcdc_dev->reg_lock);
+       }
+
+       if (win_id < ARRAY_SIZE(lcdc_win))
+               rk3368_lcdc_layer_enable(lcdc_dev, win_id, open);
+       else
+               dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
+
+
+       /* when all layer closed,disable clk */
+       /*if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
+          rk3368_lcdc_disable_irq(lcdc_dev);
+          rk3368_lcdc_reg_update(dev_drv);
+          #if defined(CONFIG_ROCKCHIP_IOMMU)
+          if (dev_drv->iommu_enabled) {
+          if (dev_drv->mmu_dev)
+          rockchip_iovmm_deactivate(dev_drv->dev);
+          }
+          #endif
+          rk3368_lcdc_clk_disable(lcdc_dev);
+          #ifndef CONFIG_RK_FPGA
+          rockchip_clear_system_status(sys_status);
+          #endif
+          } */
+
+       return 0;
+}
+
+static int win_0_1_display(struct lcdc_device *lcdc_dev,
+                          struct rk_lcdc_win *win)
+{
+       u32 y_addr;
+       u32 uv_addr;
+       unsigned int off;
+
+       off = win->id * 0x40;
+       /*win->smem_start + win->y_offset; */
+       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]:win[%d]>>:y_addr:0x%x>>uv_addr:0x%x",
+           lcdc_dev->id, win->id, y_addr, uv_addr);
+       DBG(2, ">>y_offset:0x%x>>c_offset=0x%x\n",
+           win->area[0].y_offset, win->area[0].c_offset);
+       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;
+               lcdc_writel(lcdc_dev, WIN0_YRGB_MST + off, win->area[0].y_addr);
+               lcdc_writel(lcdc_dev, WIN0_CBR_MST + off, win->area[0].uv_addr);
+               /*lcdc_cfg_done(lcdc_dev); */
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+
+       return 0;
+}
+
+static int win_2_3_display(struct lcdc_device *lcdc_dev,
+                          struct rk_lcdc_win *win)
+{
+       u32 i, y_addr;
+       unsigned int off;
+
+       off = (win->id - 2) * 0x50;
+       y_addr = win->area[0].smem_start + win->area[0].y_offset;
+       DBG(2, "lcdc[%d]:win[%d]:", lcdc_dev->id, win->id);
+
+       spin_lock(&lcdc_dev->reg_lock);
+       if (likely(lcdc_dev->clk_on)) {
+               for (i = 0; i < win->area_num; i++) {
+                       DBG(2, "area[%d]:yaddr:0x%x>>offset:0x%x>>\n",
+                           i, win->area[i].y_addr, win->area[i].y_offset);
+                       win->area[i].y_addr =
+                           win->area[i].smem_start + win->area[i].y_offset;
+                       }
+               lcdc_writel(lcdc_dev, WIN2_MST0 + off, win->area[0].y_addr);
+               lcdc_writel(lcdc_dev, WIN2_MST1 + off, win->area[1].y_addr);
+               lcdc_writel(lcdc_dev, WIN2_MST2 + off, win->area[2].y_addr);
+               lcdc_writel(lcdc_dev, WIN2_MST3 + off, win->area[3].y_addr);
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+       return 0;
+}
+
+static int hwc_display(struct lcdc_device *lcdc_dev, struct rk_lcdc_win *win)
+{
+       u32 y_addr;
+
+       y_addr = win->area[0].smem_start + win->area[0].y_offset;
+       DBG(2, "lcdc[%d]:hwc>>%s>>y_addr:0x%x>>\n",
+           lcdc_dev->id, __func__, y_addr);
+       spin_lock(&lcdc_dev->reg_lock);
+       if (likely(lcdc_dev->clk_on)) {
+               win->area[0].y_addr = y_addr;
+               lcdc_writel(lcdc_dev, HWC_MST, win->area[0].y_addr);
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+
+       return 0;
+}
+
+static int rk3368_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;
+
+#if defined(WAIT_FOR_SYNC)
+       int timeout;
+       unsigned long flags;
+#endif
+       win = dev_drv->win[win_id];
+       if (!screen) {
+               dev_err(dev_drv->dev, "screen is null!\n");
+               return -ENOENT;
+       }
+       if (win_id == 0) {
+               win_0_1_display(lcdc_dev, win);
+       } else if (win_id == 1) {
+               win_0_1_display(lcdc_dev, win);
+       } else if (win_id == 2) {
+               win_2_3_display(lcdc_dev, win);
+       } else if (win_id == 3) {
+               win_2_3_display(lcdc_dev, win);
+       } else if (win_id == 4) {
+               hwc_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;
+               rk3368_lcdc_enable_irq(dev_drv);
+       }
+#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
+       return 0;
+}
+
+static int rk3368_lcdc_cal_scl_fac(struct rk_lcdc_win *win)
+{
+       u16 srcW;
+       u16 srcH;
+       u16 dstW;
+       u16 dstH;
+       u16 yrgb_srcW;
+       u16 yrgb_srcH;
+       u16 yrgb_dstW;
+       u16 yrgb_dstH;
+       u32 yrgb_vscalednmult;
+       u32 yrgb_xscl_factor;
+       u32 yrgb_yscl_factor;
+       u8 yrgb_vsd_bil_gt2 = 0;
+       u8 yrgb_vsd_bil_gt4 = 0;
+
+       u16 cbcr_srcW;
+       u16 cbcr_srcH;
+       u16 cbcr_dstW;
+       u16 cbcr_dstH;
+       u32 cbcr_vscalednmult;
+       u32 cbcr_xscl_factor;
+       u32 cbcr_yscl_factor;
+       u8 cbcr_vsd_bil_gt2 = 0;
+       u8 cbcr_vsd_bil_gt4 = 0;
+       u8 yuv_fmt = 0;
+
+       srcW = win->area[0].xact;
+       srcH = win->area[0].yact;
+       dstW = win->area[0].xsize;
+       dstH = win->area[0].ysize;
+
+       /*yrgb scl mode */
+       yrgb_srcW = srcW;
+       yrgb_srcH = srcH;
+       yrgb_dstW = dstW;
+       yrgb_dstH = dstH;
+       if ((yrgb_dstW * 8 <= yrgb_srcW) || (yrgb_dstH * 8 <= yrgb_srcH)) {
+               pr_err("ERROR: yrgb scale exceed 8,");
+               pr_err("srcW=%d,srcH=%d,dstW=%d,dstH=%d\n",
+                      yrgb_srcW, yrgb_srcH, yrgb_dstW, yrgb_dstH);
+       }
+       if (yrgb_srcW < yrgb_dstW)
+               win->yrgb_hor_scl_mode = SCALE_UP;
+       else if (yrgb_srcW > yrgb_dstW)
+               win->yrgb_hor_scl_mode = SCALE_DOWN;
+       else
+               win->yrgb_hor_scl_mode = SCALE_NONE;
+
+       if (yrgb_srcH < yrgb_dstH)
+               win->yrgb_ver_scl_mode = SCALE_UP;
+       else if (yrgb_srcH > yrgb_dstH)
+               win->yrgb_ver_scl_mode = SCALE_DOWN;
+       else
+               win->yrgb_ver_scl_mode = SCALE_NONE;
+
+       /*cbcr scl mode */
+       switch (win->area[0].format) {
+       case YUV422:
+       case YUV422_A:
+               cbcr_srcW = srcW / 2;
+               cbcr_dstW = dstW;
+               cbcr_srcH = srcH;
+               cbcr_dstH = dstH;
+               yuv_fmt = 1;
+               break;
+       case YUV420:
+       case YUV420_A:
+               cbcr_srcW = srcW / 2;
+               cbcr_dstW = dstW;
+               cbcr_srcH = srcH / 2;
+               cbcr_dstH = dstH;
+               yuv_fmt = 1;
+               break;
+       case YUV444:
+       case YUV444_A:
+               cbcr_srcW = srcW;
+               cbcr_dstW = dstW;
+               cbcr_srcH = srcH;
+               cbcr_dstH = dstH;
+               yuv_fmt = 1;
+               break;
+       default:
+               cbcr_srcW = 0;
+               cbcr_dstW = 0;
+               cbcr_srcH = 0;
+               cbcr_dstH = 0;
+               yuv_fmt = 0;
+               break;
+       }
+       if (yuv_fmt) {
+               if ((cbcr_dstW * 8 <= cbcr_srcW) ||
+                   (cbcr_dstH * 8 <= cbcr_srcH)) {
+                       pr_err("ERROR: cbcr scale exceed 8,");
+                       pr_err("srcW=%d,srcH=%d,dstW=%d,dstH=%d\n", cbcr_srcW,
+                              cbcr_srcH, cbcr_dstW, cbcr_dstH);
+               }
+       }
+
+       if (cbcr_srcW < cbcr_dstW)
+               win->cbr_hor_scl_mode = SCALE_UP;
+       else if (cbcr_srcW > cbcr_dstW)
+               win->cbr_hor_scl_mode = SCALE_DOWN;
+       else
+               win->cbr_hor_scl_mode = SCALE_NONE;
+
+       if (cbcr_srcH < cbcr_dstH)
+               win->cbr_ver_scl_mode = SCALE_UP;
+       else if (cbcr_srcH > cbcr_dstH)
+               win->cbr_ver_scl_mode = SCALE_DOWN;
+       else
+               win->cbr_ver_scl_mode = SCALE_NONE;
+
+       /*DBG(1, "srcW:%d>>srcH:%d>>dstW:%d>>dstH:%d>>\n"
+           "yrgb:src:W=%d>>H=%d,dst:W=%d>>H=%d,H_mode=%d,V_mode=%d\n"
+           "cbcr:src:W=%d>>H=%d,dst:W=%d>>H=%d,H_mode=%d,V_mode=%d\n", srcW,
+           srcH, dstW, dstH, yrgb_srcW, yrgb_srcH, yrgb_dstW, yrgb_dstH,
+           win->yrgb_hor_scl_mode, win->yrgb_ver_scl_mode, cbcr_srcW,
+           cbcr_srcH, cbcr_dstW, cbcr_dstH, win->cbr_hor_scl_mode,
+           win->cbr_ver_scl_mode);*/
+
+       /*line buffer mode */
+       if ((win->area[0].format == YUV422) ||
+           (win->area[0].format == YUV420) ||
+           (win->area[0].format == YUV422_A) ||
+           (win->area[0].format == YUV420_A)) {
+               if (win->cbr_hor_scl_mode == SCALE_DOWN) {
+                       if ((cbcr_dstW > VOP_INPUT_MAX_WIDTH / 2) ||
+                           (cbcr_dstW == 0))
+                               pr_err("ERROR cbcr_dstW = %d,exceeds 2048\n",
+                                      cbcr_dstW);
+                       else if (cbcr_dstW > 1280)
+                               win->win_lb_mode = LB_YUV_3840X5;
+                       else
+                               win->win_lb_mode = LB_YUV_2560X8;
+               } else {        /*SCALE_UP or SCALE_NONE */
+                       if ((cbcr_srcW > VOP_INPUT_MAX_WIDTH / 2) ||
+                           (cbcr_srcW == 0))
+                               pr_err("ERROR cbcr_srcW = %d,exceeds 2048\n",
+                                      cbcr_srcW);
+                       else if (cbcr_srcW > 1280)
+                               win->win_lb_mode = LB_YUV_3840X5;
+                       else
+                               win->win_lb_mode = LB_YUV_2560X8;
+               }
+       } else {
+               if (win->yrgb_hor_scl_mode == SCALE_DOWN) {
+                       if ((yrgb_dstW > VOP_INPUT_MAX_WIDTH) ||
+                           (yrgb_dstW == 0))
+                               pr_err("ERROR yrgb_dstW = %d\n", yrgb_dstW);
+                       else if (yrgb_dstW > 2560)
+                               win->win_lb_mode = LB_RGB_3840X2;
+                       else if (yrgb_dstW > 1920)
+                               win->win_lb_mode = LB_RGB_2560X4;
+                       else if (yrgb_dstW > 1280)
+                               win->win_lb_mode = LB_RGB_1920X5;
+                       else
+                               win->win_lb_mode = LB_RGB_1280X8;
+               } else {        /*SCALE_UP or SCALE_NONE */
+                       if ((yrgb_srcW > VOP_INPUT_MAX_WIDTH) ||
+                           (yrgb_srcW == 0))
+                               pr_err("ERROR yrgb_srcW = %d\n", yrgb_srcW);
+                       else if (yrgb_srcW > 2560)
+                               win->win_lb_mode = LB_RGB_3840X2;
+                       else if (yrgb_srcW > 1920)
+                               win->win_lb_mode = LB_RGB_2560X4;
+                       else if (yrgb_srcW > 1280)
+                               win->win_lb_mode = LB_RGB_1920X5;
+                       else
+                               win->win_lb_mode = LB_RGB_1280X8;
+               }
+       }
+       DBG(1, "win->win_lb_mode = %d;\n", win->win_lb_mode);
+
+       /*vsd/vsu scale ALGORITHM */
+       win->yrgb_hsd_mode = SCALE_DOWN_BIL;    /*not to specify */
+       win->cbr_hsd_mode = SCALE_DOWN_BIL;     /*not to specify */
+       win->yrgb_vsd_mode = SCALE_DOWN_BIL;    /*not to specify */
+       win->cbr_vsd_mode = SCALE_DOWN_BIL;     /*not to specify */
+       switch (win->win_lb_mode) {
+       case LB_YUV_3840X5:
+       case LB_YUV_2560X8:
+       case LB_RGB_1920X5:
+       case LB_RGB_1280X8:
+               win->yrgb_vsu_mode = SCALE_UP_BIC;
+               win->cbr_vsu_mode = SCALE_UP_BIC;
+               break;
+       case LB_RGB_3840X2:
+               if (win->yrgb_ver_scl_mode != SCALE_NONE)
+                       pr_err("ERROR : not allow yrgb ver scale\n");
+               if (win->cbr_ver_scl_mode != SCALE_NONE)
+                       pr_err("ERROR : not allow cbcr ver scale\n");
+               break;
+       case LB_RGB_2560X4:
+               win->yrgb_vsu_mode = SCALE_UP_BIL;
+               win->cbr_vsu_mode = SCALE_UP_BIL;
+               break;
+       default:
+               pr_info("%s:un supported win_lb_mode:%d\n",
+                       __func__, win->win_lb_mode);
+               break;
+       }
+       if (win->mirror_en == 1) {      /*interlace mode must bill */
+               win->yrgb_vsd_mode = SCALE_DOWN_BIL;
+       }
+
+       if ((win->yrgb_ver_scl_mode == SCALE_DOWN) &&
+           (win->area[0].fbdc_en == 1)) {
+               /*in this pattern,use bil mode,not support souble scd,
+               use avg mode, support double scd, but aclk should be
+               bigger than dclk,aclk>>dclk */
+               if (yrgb_srcH >= 2 * yrgb_dstH) {
+                       pr_err("ERROR : fbdc mode,not support y scale down:");
+                       pr_err("srcH[%d] > 2 *dstH[%d]\n",
+                              yrgb_srcH, yrgb_dstH);
+               }
+       }
+       DBG(1, "yrgb:hsd=%d,vsd=%d,vsu=%d;cbcr:hsd=%d,vsd=%d,vsu=%d\n",
+           win->yrgb_hsd_mode, win->yrgb_vsd_mode, win->yrgb_vsu_mode,
+           win->cbr_hsd_mode, win->cbr_vsd_mode, win->cbr_vsu_mode);
+
+       /*SCALE FACTOR */
+
+       /*(1.1)YRGB HOR SCALE FACTOR */
+       switch (win->yrgb_hor_scl_mode) {
+       case SCALE_NONE:
+               yrgb_xscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
+               break;
+       case SCALE_UP:
+               yrgb_xscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcW, yrgb_dstW);
+               break;
+       case SCALE_DOWN:
+               switch (win->yrgb_hsd_mode) {
+               case SCALE_DOWN_BIL:
+                       yrgb_xscl_factor =
+                           GET_SCALE_FACTOR_BILI_DN(yrgb_srcW, yrgb_dstW);
+                       break;
+               case SCALE_DOWN_AVG:
+                       yrgb_xscl_factor =
+                           GET_SCALE_FACTOR_AVRG(yrgb_srcW, yrgb_dstW);
+                       break;
+               default:
+                       pr_info(
+                               "%s:un supported yrgb_hsd_mode:%d\n", __func__,
+                              win->yrgb_hsd_mode);
+                       break;
+               }
+               break;
+       default:
+               pr_info("%s:un supported yrgb_hor_scl_mode:%d\n",
+                       __func__, win->yrgb_hor_scl_mode);
+               break;
+       }                       /*win->yrgb_hor_scl_mode */
+
+       /*(1.2)YRGB VER SCALE FACTOR */
+       switch (win->yrgb_ver_scl_mode) {
+       case SCALE_NONE:
+               yrgb_yscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
+               break;
+       case SCALE_UP:
+               switch (win->yrgb_vsu_mode) {
+               case SCALE_UP_BIL:
+                       yrgb_yscl_factor =
+                           GET_SCALE_FACTOR_BILI_UP(yrgb_srcH, yrgb_dstH);
+                       break;
+               case SCALE_UP_BIC:
+                       if (yrgb_srcH < 3) {
+                               pr_err("yrgb_srcH should be");
+                               pr_err(" greater than 3 !!!\n");
+                       }
+                       yrgb_yscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcH,
+                                                               yrgb_dstH);
+                       break;
+               default:
+                       pr_info("%s:un support yrgb_vsu_mode:%d\n",
+                               __func__, win->yrgb_vsu_mode);
+                       break;
+               }
+               break;
+       case SCALE_DOWN:
+               switch (win->yrgb_vsd_mode) {
+               case SCALE_DOWN_BIL:
+                       yrgb_vscalednmult =
+                           rk3368_get_hard_ware_vskiplines(yrgb_srcH,
+                                                           yrgb_dstH);
+                       yrgb_yscl_factor =
+                           GET_SCALE_FACTOR_BILI_DN_VSKIP(yrgb_srcH, yrgb_dstH,
+                                                          yrgb_vscalednmult);
+                       if (yrgb_yscl_factor >= 0x2000) {
+                               pr_err("yrgb_yscl_factor should be ");
+                               pr_err("less than 0x2000,yrgb_yscl_factor=%4x;\n",
+                                      yrgb_yscl_factor);
+                       }
+                       if (yrgb_vscalednmult == 4) {
+                               yrgb_vsd_bil_gt4 = 1;
+                               yrgb_vsd_bil_gt2 = 0;
+                       } else if (yrgb_vscalednmult == 2) {
+                               yrgb_vsd_bil_gt4 = 0;
+                               yrgb_vsd_bil_gt2 = 1;
+                       } else {
+                               yrgb_vsd_bil_gt4 = 0;
+                               yrgb_vsd_bil_gt2 = 0;
+                       }
+                       break;
+               case SCALE_DOWN_AVG:
+                       yrgb_yscl_factor = GET_SCALE_FACTOR_AVRG(yrgb_srcH,
+                                                                yrgb_dstH);
+                       break;
+               default:
+                       pr_info("%s:un support yrgb_vsd_mode:%d\n",
+                               __func__, win->yrgb_vsd_mode);
+                       break;
+               }               /*win->yrgb_vsd_mode */
+               break;
+       default:
+               pr_info("%s:un supported yrgb_ver_scl_mode:%d\n",
+                       __func__, win->yrgb_ver_scl_mode);
+               break;
+       }
+       win->scale_yrgb_x = yrgb_xscl_factor;
+       win->scale_yrgb_y = yrgb_yscl_factor;
+       win->vsd_yrgb_gt4 = yrgb_vsd_bil_gt4;
+       win->vsd_yrgb_gt2 = yrgb_vsd_bil_gt2;
+       DBG(1, "yrgb:h_fac=%d, v_fac=%d,gt4=%d, gt2=%d\n", yrgb_xscl_factor,
+           yrgb_yscl_factor, yrgb_vsd_bil_gt4, yrgb_vsd_bil_gt2);
+
+       /*(2.1)CBCR HOR SCALE FACTOR */
+       switch (win->cbr_hor_scl_mode) {
+       case SCALE_NONE:
+               cbcr_xscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
+               break;
+       case SCALE_UP:
+               cbcr_xscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcW, cbcr_dstW);
+               break;
+       case SCALE_DOWN:
+               switch (win->cbr_hsd_mode) {
+               case SCALE_DOWN_BIL:
+                       cbcr_xscl_factor =
+                           GET_SCALE_FACTOR_BILI_DN(cbcr_srcW, cbcr_dstW);
+                       break;
+               case SCALE_DOWN_AVG:
+                       cbcr_xscl_factor =
+                           GET_SCALE_FACTOR_AVRG(cbcr_srcW, cbcr_dstW);
+                       break;
+               default:
+                       pr_info("%s:un support cbr_hsd_mode:%d\n",
+                               __func__, win->cbr_hsd_mode);
+                       break;
+               }
+               break;
+       default:
+               pr_info("%s:un supported cbr_hor_scl_mode:%d\n",
+                       __func__, win->cbr_hor_scl_mode);
+               break;
+       }                       /*win->cbr_hor_scl_mode */
+
+       /*(2.2)CBCR VER SCALE FACTOR */
+       switch (win->cbr_ver_scl_mode) {
+       case SCALE_NONE:
+               cbcr_yscl_factor = (1 << SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
+               break;
+       case SCALE_UP:
+               switch (win->cbr_vsu_mode) {
+               case SCALE_UP_BIL:
+                       cbcr_yscl_factor =
+                           GET_SCALE_FACTOR_BILI_UP(cbcr_srcH, cbcr_dstH);
+                       break;
+               case SCALE_UP_BIC:
+                       if (cbcr_srcH < 3) {
+                               pr_err("cbcr_srcH should be ");
+                               pr_err("greater than 3 !!!\n");
+                       }
+                       cbcr_yscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcH,
+                                                               cbcr_dstH);
+                       break;
+               default:
+                       pr_info("%s:un support cbr_vsu_mode:%d\n",
+                               __func__, win->cbr_vsu_mode);
+                       break;
+               }
+               break;
+       case SCALE_DOWN:
+               switch (win->cbr_vsd_mode) {
+               case SCALE_DOWN_BIL:
+                       cbcr_vscalednmult =
+                           rk3368_get_hard_ware_vskiplines(cbcr_srcH,
+                                                           cbcr_dstH);
+                       cbcr_yscl_factor =
+                           GET_SCALE_FACTOR_BILI_DN_VSKIP(cbcr_srcH, cbcr_dstH,
+                                                          cbcr_vscalednmult);
+                       if (cbcr_yscl_factor >= 0x2000) {
+                               pr_err("cbcr_yscl_factor should be less ");
+                               pr_err("than 0x2000,cbcr_yscl_factor=%4x;\n",
+                                      cbcr_yscl_factor);
+                       }
+
+                       if (cbcr_vscalednmult == 4) {
+                               cbcr_vsd_bil_gt4 = 1;
+                               cbcr_vsd_bil_gt2 = 0;
+                       } else if (cbcr_vscalednmult == 2) {
+                               cbcr_vsd_bil_gt4 = 0;
+                               cbcr_vsd_bil_gt2 = 1;
+                       } else {
+                               cbcr_vsd_bil_gt4 = 0;
+                               cbcr_vsd_bil_gt2 = 0;
+                       }
+                       break;
+               case SCALE_DOWN_AVG:
+                       cbcr_yscl_factor = GET_SCALE_FACTOR_AVRG(cbcr_srcH,
+                                                                cbcr_dstH);
+                       break;
+               default:
+                       pr_info("%s:un support cbr_vsd_mode:%d\n",
+                               __func__, win->cbr_vsd_mode);
+                       break;
+               }
+               break;
+       default:
+               pr_info("%s:un supported cbr_ver_scl_mode:%d\n",
+                       __func__, win->cbr_ver_scl_mode);
+               break;
+       }
+       win->scale_cbcr_x = cbcr_xscl_factor;
+       win->scale_cbcr_y = cbcr_yscl_factor;
+       win->vsd_cbr_gt4 = cbcr_vsd_bil_gt4;
+       win->vsd_cbr_gt2 = cbcr_vsd_bil_gt2;
+
+       DBG(1, "cbcr:h_fac=%d,v_fac=%d,gt4=%d,gt2=%d\n", cbcr_xscl_factor,
+           cbcr_yscl_factor, cbcr_vsd_bil_gt4, cbcr_vsd_bil_gt2);
+       return 0;
+}
+
+static int win_0_1_set_par(struct lcdc_device *lcdc_dev,
+                          struct rk_screen *screen, struct rk_lcdc_win *win)
+{
+       u32 xact, yact, xvir, yvir, xpos, ypos;
+       u8 fmt_cfg = 0, swap_rb;
+       char fmt[9] = "NULL";
+
+       if (!win->mirror_en) {
+               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;
+       } else {
+               xpos = screen->mode.xres - win->area[0].xpos -
+                       win->area[0].xsize +
+                       screen->mode.left_margin + screen->mode.hsync_len;
+               ypos = screen->mode.yres - win->area[0].ypos -
+                       win->area[0].ysize + screen->mode.upper_margin +
+                       screen->mode.vsync_len;
+       }
+       spin_lock(&lcdc_dev->reg_lock);
+       if (likely(lcdc_dev->clk_on)) {
+               rk3368_lcdc_cal_scl_fac(win);   /*fac,lb,gt2,gt4 */
+               switch (win->area[0].format) {
+               case ARGB888:
+                       fmt_cfg = 0;
+                       swap_rb = 0;
+                       win->fmt_10 = 0;
+                       break;
+               case XBGR888:
+               case ABGR888:
+                       fmt_cfg = 0;
+                       swap_rb = 1;
+                       win->fmt_10 = 0;
+                       break;
+               case RGB888:
+                       fmt_cfg = 1;
+                       swap_rb = 0;
+                       win->fmt_10 = 0;
+                       break;
+               case RGB565:
+                       fmt_cfg = 2;
+                       swap_rb = 0;
+                       win->fmt_10 = 0;
+                       break;
+               case YUV422:
+                       fmt_cfg = 5;
+                       swap_rb = 0;
+                       win->fmt_10 = 0;
+                       break;
+               case YUV420:
+                       fmt_cfg = 4;
+                       swap_rb = 0;
+                       win->fmt_10 = 0;
+                       break;
+               case YUV444:
+                       fmt_cfg = 6;
+                       swap_rb = 0;
+                       win->fmt_10 = 0;
+                       break;
+               case YUV422_A:
+                       fmt_cfg = 5;
+                       swap_rb = 0;
+                       win->fmt_10 = 1;
+                       break;
+               case YUV420_A:
+                       fmt_cfg = 4;
+                       swap_rb = 0;
+                       win->fmt_10 = 1;
+                       break;
+               case YUV444_A:
+                       fmt_cfg = 6;
+                       swap_rb = 0;
+                       win->fmt_10 = 1;
+                       break;
+               default:
+                       dev_err(lcdc_dev->driver.dev, "%s:unsupport format!\n",
+                               __func__);
+                       break;
+               }
+               win->area[0].fmt_cfg = fmt_cfg;
+               win->area[0].swap_rb = swap_rb;
+               win->area[0].dsp_stx = xpos;
+               win->area[0].dsp_sty = ypos;
+               xact = win->area[0].xact;
+               yact = win->area[0].yact;
+               xvir = win->area[0].xvir;
+               yvir = win->area[0].yvir;
+       }
+       if (win->area[0].fbdc_en)
+               rk3368_init_fbdc_config(&lcdc_dev->driver, win->id);
+       rk3368_win_0_1_reg_update(&lcdc_dev->driver, win->id);
+       spin_unlock(&lcdc_dev->reg_lock);
+
+       DBG(1, "lcdc[%d]:win[%d]\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d",
+           lcdc_dev->id, win->id, get_format_string(win->area[0].format, fmt),
+           xact, yact, win->area[0].xsize);
+       DBG(1, ">>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
+           win->area[0].ysize, xvir, yvir, xpos, ypos);
+
+       return 0;
+}
+
+
+static int win_2_3_set_par(struct lcdc_device *lcdc_dev,
+                          struct rk_screen *screen, struct rk_lcdc_win *win)
+{
+       int i;
+       u8 fmt_cfg, swap_rb;
+       char fmt[9] = "NULL";
+
+       spin_lock(&lcdc_dev->reg_lock);
+       if (likely(lcdc_dev->clk_on)) {
+               DBG(2, "lcdc[%d]:win[%d]>>\n>\n", lcdc_dev->id, win->id);
+               for (i = 0; i < win->area_num; i++) {
+                       switch (win->area[i].format) {
+                       case ARGB888:
+                               fmt_cfg = 0;
+                               swap_rb = 0;
+                               break;
+                       case XBGR888:
+                       case ABGR888:
+                               fmt_cfg = 0;
+                               swap_rb = 1;
+                               break;
+                       case RGB888:
+                               fmt_cfg = 1;
+                               swap_rb = 0;
+                               break;
+                       case RGB565:
+                               fmt_cfg = 2;
+                               swap_rb = 0;
+                               break;
+                       default:
+                               dev_err(lcdc_dev->driver.dev,
+                                       "%s:un supported format!\n", __func__);
+                               break;
+                       }
+                       win->area[i].fmt_cfg = fmt_cfg;
+                       win->area[i].swap_rb = swap_rb;
+                       win->area[i].dsp_stx = win->area[i].xpos +
+                           screen->mode.left_margin + screen->mode.hsync_len;
+                       if (screen->y_mirror == 1) {
+                               win->area[i].dsp_sty = screen->mode.yres -
+                                   win->area[i].ypos -
+                                   win->area[i].ysize +
+                                   screen->mode.upper_margin +
+                                   screen->mode.vsync_len;
+                       } else {
+                               win->area[i].dsp_sty = win->area[i].ypos +
+                                   screen->mode.upper_margin +
+                                   screen->mode.vsync_len;
+                       }
+
+                       DBG(2, "fmt:%s:xsize:%d>>ysize:%d>>xpos:%d>>ypos:%d\n",
+                           get_format_string(win->area[i].format, fmt),
+                           win->area[i].xsize, win->area[i].ysize,
+                           win->area[i].xpos, win->area[i].ypos);
+               }
+       }
+       if (win->area[0].fbdc_en)
+               rk3368_init_fbdc_config(&lcdc_dev->driver, win->id);
+       rk3368_win_2_3_reg_update(&lcdc_dev->driver, win->id);
+       spin_unlock(&lcdc_dev->reg_lock);
+       return 0;
+}
+
+static int hwc_set_par(struct lcdc_device *lcdc_dev,
+                      struct rk_screen *screen, struct rk_lcdc_win *win)
+{
+       u32 xact, yact, xvir, yvir, xpos, ypos;
+       u8 fmt_cfg = 0, swap_rb;
+       char fmt[9] = "NULL";
+
+       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;
+
+       spin_lock(&lcdc_dev->reg_lock);
+       if (likely(lcdc_dev->clk_on)) {
+               /*rk3368_lcdc_cal_scl_fac(win); *//*fac,lb,gt2,gt4 */
+               switch (win->area[0].format) {
+               case ARGB888:
+                       fmt_cfg = 0;
+                       swap_rb = 0;
+                       break;
+               case XBGR888:
+               case ABGR888:
+                       fmt_cfg = 0;
+                       swap_rb = 1;
+                       break;
+               case RGB888:
+                       fmt_cfg = 1;
+                       swap_rb = 0;
+                       break;
+               case RGB565:
+                       fmt_cfg = 2;
+                       swap_rb = 0;
+                       break;
+               default:
+                       dev_err(lcdc_dev->driver.dev,
+                               "%s:un supported format!\n", __func__);
+                       break;
+               }
+               win->area[0].fmt_cfg = fmt_cfg;
+               win->area[0].swap_rb = swap_rb;
+               win->area[0].dsp_stx = xpos;
+               win->area[0].dsp_sty = ypos;
+               xact = win->area[0].xact;
+               yact = win->area[0].yact;
+               xvir = win->area[0].xvir;
+               yvir = win->area[0].yvir;
+       }
+       rk3368_hwc_reg_update(&lcdc_dev->driver, 4);
+       spin_unlock(&lcdc_dev->reg_lock);
+
+       DBG(1, "lcdc[%d]:hwc>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d",
+           lcdc_dev->id, __func__, get_format_string(win->area[0].format, fmt),
+           xact, yact, win->area[0].xsize);
+       DBG(1, ">>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
+           win->area[0].ysize, xvir, yvir, xpos, ypos);
+       return 0;
+}
+
+static int rk3368_lcdc_set_par(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;
+
+       win = dev_drv->win[win_id];
+       switch (win_id) {
+       case 0:
+               win_0_1_set_par(lcdc_dev, screen, win);
+               break;
+       case 1:
+               win_0_1_set_par(lcdc_dev, screen, win);
+               break;
+       case 2:
+               win_2_3_set_par(lcdc_dev, screen, win);
+               break;
+       case 3:
+               win_2_3_set_par(lcdc_dev, screen, win);
+               break;
+       case 4:
+               hwc_set_par(lcdc_dev, screen, win);
+               break;
+       default:
+               dev_err(dev_drv->dev, "unsupported win number:%d\n", win_id);
+               break;
+       }
+       return 0;
+}
+
+static int rk3368_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
+                            unsigned long arg, int win_id)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       u32 panel_size[2];
+       void __user *argp = (void __user *)arg;
+       struct color_key_cfg clr_key_cfg;
+
+       switch (cmd) {
+       case RK_FBIOGET_PANEL_SIZE:
+               panel_size[0] = lcdc_dev->screen->mode.xres;
+               panel_size[1] = lcdc_dev->screen->mode.yres;
+               if (copy_to_user(argp, panel_size, 8))
+                       return -EFAULT;
+               break;
+       case RK_FBIOPUT_COLOR_KEY_CFG:
+               if (copy_from_user(&clr_key_cfg, argp,
+                                  sizeof(struct color_key_cfg)))
+                       return -EFAULT;
+               rk3368_lcdc_clr_key_cfg(dev_drv);
+               lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
+                           clr_key_cfg.win0_color_key_cfg);
+               lcdc_writel(lcdc_dev, WIN1_COLOR_KEY,
+                           clr_key_cfg.win1_color_key_cfg);
+               break;
+
+       default:
+               break;
+       }
+       return 0;
+}
+
+static int rk3368_lcdc_get_backlight_device(struct rk_lcdc_driver *dev_drv)
+{
+       struct lcdc_device *lcdc_dev = container_of(dev_drv,
+                                                   struct lcdc_device, driver);
+       /*struct device_node *backlight;*/
+
+       if (lcdc_dev->backlight)
+               return 0;
+#if 0
+       backlight = of_parse_phandle(lcdc_dev->dev->of_node, "backlight", 0);
+       if (backlight) {
+               lcdc_dev->backlight = of_find_backlight_by_node(backlight);
+               if (!lcdc_dev->backlight)
+                       dev_info(lcdc_dev->dev, "No find backlight device\n");
+       } else {
+               dev_info(lcdc_dev->dev, "No find backlight device node\n");
+       }
+#endif
+       return 0;
+}
+
+static int rk3368_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
+{
+       u32 reg;
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       if (dev_drv->suspend_flag)
+               return 0;
+       /* close the backlight */
+       /*rk3368_lcdc_get_backlight_device(dev_drv);
+       if (lcdc_dev->backlight) {
+               lcdc_dev->backlight->props.fb_blank = FB_BLANK_POWERDOWN;
+               backlight_update_status(lcdc_dev->backlight);
+       }*/
+
+       dev_drv->suspend_flag = 1;
+       flush_kthread_worker(&dev_drv->update_regs_worker);
+
+       for (reg = MMU_DTE_ADDR; reg <= MMU_AUTO_GATING; reg += 4)
+               lcdc_readl(lcdc_dev, reg);
+       if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
+               dev_drv->trsm_ops->disable();
+
+       spin_lock(&lcdc_dev->reg_lock);
+       if (likely(lcdc_dev->clk_on)) {
+               lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN,
+                            v_DSP_BLANK_EN(1));
+               lcdc_msk_reg(lcdc_dev,
+                            INTR_CLEAR, m_FS_INTR_CLR | m_LINE_FLAG0_INTR_CLR,
+                            v_FS_INTR_CLR(1) | v_LINE_FLAG0_INTR_CLR(1));
+               lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_OUT_ZERO,
+                            v_DSP_OUT_ZERO(1));
+               lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN, v_STANDBY_EN(1));
+               lcdc_cfg_done(lcdc_dev);
+
+               if (dev_drv->iommu_enabled) {
+                       if (dev_drv->mmu_dev)
+                               rockchip_iovmm_deactivate(dev_drv->dev);
+               }
+
+               spin_unlock(&lcdc_dev->reg_lock);
+       } else {
+               spin_unlock(&lcdc_dev->reg_lock);
+               return 0;
+       }
+       rk3368_lcdc_clk_disable(lcdc_dev);
+       rk_disp_pwr_disable(dev_drv);
+       return 0;
+}
+
+static int rk3368_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       int i, j;
+       int __iomem *c;
+       int v, r, g, b;
+
+       if (!dev_drv->suspend_flag)
+               return 0;
+       rk_disp_pwr_enable(dev_drv);
+       dev_drv->suspend_flag = 0;
+
+       if (1/*lcdc_dev->atv_layer_cnt*/) {
+               rk3368_lcdc_clk_enable(lcdc_dev);
+               rk3368_lcdc_reg_restore(lcdc_dev);
+
+               spin_lock(&lcdc_dev->reg_lock);
+               if (dev_drv->cur_screen->dsp_lut) {
+                       lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
+                                    v_DSP_LUT_EN(0));
+                       lcdc_cfg_done(lcdc_dev);
+                       mdelay(25);
+                       for (i = 0; i < 256; i++) {
+                               v = dev_drv->cur_screen->dsp_lut[i];
+                               c = lcdc_dev->dsp_lut_addr_base + (i << 2);
+                               b = (v & 0xff);
+                               g = (v & 0xff00);
+                               r = (v & 0xff0000);
+                               v = r + g + b;
+                               for (j = 0; j < 4; j++) {
+                                       writel_relaxed(v, c);
+                                       v += (1 + (1 << 10) + (1 << 20));
+                                       c++;
+                               }
+                       }
+                       lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
+                                    v_DSP_LUT_EN(1));
+               }
+
+               lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_OUT_ZERO,
+                            v_DSP_OUT_ZERO(0));
+               lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN, v_STANDBY_EN(0));
+               lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN,
+                            v_DSP_BLANK_EN(0));
+               lcdc_cfg_done(lcdc_dev);
+
+               if (dev_drv->iommu_enabled) {
+                       if (dev_drv->mmu_dev)
+                               rockchip_iovmm_activate(dev_drv->dev);
+               }
+
+               spin_unlock(&lcdc_dev->reg_lock);
+       }
+
+       if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
+               dev_drv->trsm_ops->enable();
+
+       return 0;
+}
+
+static int rk3368_lcdc_blank(struct rk_lcdc_driver *dev_drv,
+                            int win_id, int blank_mode)
+{
+       switch (blank_mode) {
+       case FB_BLANK_UNBLANK:
+               rk3368_lcdc_early_resume(dev_drv);
+               break;
+       case FB_BLANK_NORMAL:
+               rk3368_lcdc_early_suspend(dev_drv);
+               break;
+       default:
+               rk3368_lcdc_early_suspend(dev_drv);
+               break;
+       }
+
+       dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
+
+       return 0;
+}
+
+static int rk3368_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv, int win_id)
+{
+       return 0;
+}
+
+/*overlay will be do at regupdate*/
+static int rk3368_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
+                              bool set)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       struct rk_lcdc_win *win = NULL;
+       int i, ovl;
+       unsigned int mask, val;
+       int z_order_num = 0;
+       int layer0_sel, layer1_sel, layer2_sel, layer3_sel;
+
+       if (swap == 0) {
+               for (i = 0; i < 4; i++) {
+                       win = dev_drv->win[i];
+                       if (win->state == 1)
+                               z_order_num++;
+               }
+               for (i = 0; i < 4; i++) {
+                       win = dev_drv->win[i];
+                       if (win->state == 0)
+                               win->z_order = z_order_num++;
+                       switch (win->z_order) {
+                       case 0:
+                               layer0_sel = win->id;
+                               break;
+                       case 1:
+                               layer1_sel = win->id;
+                               break;
+                       case 2:
+                               layer2_sel = win->id;
+                               break;
+                       case 3:
+                               layer3_sel = win->id;
+                               break;
+                       default:
+                               break;
+                       }
+               }
+       } else {
+               layer0_sel = swap % 10;
+               layer1_sel = swap / 10 % 10;
+               layer2_sel = swap / 100 % 10;
+               layer3_sel = swap / 1000;
+       }
+
+       spin_lock(&lcdc_dev->reg_lock);
+       if (lcdc_dev->clk_on) {
+               if (set) {
+                       mask = m_DSP_LAYER0_SEL | m_DSP_LAYER1_SEL |
+                           m_DSP_LAYER2_SEL | m_DSP_LAYER3_SEL;
+                       val = v_DSP_LAYER0_SEL(layer0_sel) |
+                           v_DSP_LAYER1_SEL(layer1_sel) |
+                           v_DSP_LAYER2_SEL(layer2_sel) |
+                           v_DSP_LAYER3_SEL(layer3_sel);
+                       lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
+               } else {
+                       layer0_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1,
+                                                  m_DSP_LAYER0_SEL);
+                       layer1_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1,
+                                                  m_DSP_LAYER1_SEL);
+                       layer2_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1,
+                                                  m_DSP_LAYER2_SEL);
+                       layer3_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1,
+                                                  m_DSP_LAYER3_SEL);
+                       ovl = layer3_sel * 1000 + layer2_sel * 100 +
+                           layer1_sel * 10 + layer0_sel;
+               }
+       } else {
+               ovl = -EPERM;
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+
+       return ovl;
+}
+
+static char *rk3368_lcdc_format_to_string(int format, char *fmt)
+{
+       if (!fmt)
+               return NULL;
+
+       switch (format) {
+       case 0:
+               strcpy(fmt, "ARGB888");
+               break;
+       case 1:
+               strcpy(fmt, "RGB888");
+               break;
+       case 2:
+               strcpy(fmt, "RGB565");
+               break;
+       case 4:
+               strcpy(fmt, "YCbCr420");
+               break;
+       case 5:
+               strcpy(fmt, "YCbCr422");
+               break;
+       case 6:
+               strcpy(fmt, "YCbCr444");
+               break;
+       default:
+               strcpy(fmt, "invalid\n");
+               break;
+       }
+       return fmt;
+}
+static ssize_t rk3368_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
+                                        char *buf, int win_id)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       struct rk_screen *screen = dev_drv->cur_screen;
+       u16 hsync_len = screen->mode.hsync_len;
+       u16 left_margin = screen->mode.left_margin;
+       u16 vsync_len = screen->mode.vsync_len;
+       u16 upper_margin = screen->mode.upper_margin;
+       u32 h_pw_bp = hsync_len + left_margin;
+       u32 v_pw_bp = vsync_len + upper_margin;
+       u32 fmt_id;
+       char format_w0[9] = "NULL";
+       char format_w1[9] = "NULL";
+       char format_w2_0[9] = "NULL";
+       char format_w2_1[9] = "NULL";
+       char format_w2_2[9] = "NULL";
+       char format_w2_3[9] = "NULL";
+       char format_w3_0[9] = "NULL";
+       char format_w3_1[9] = "NULL";
+       char format_w3_2[9] = "NULL";
+       char format_w3_3[9] = "NULL";
+       char dsp_buf[100];
+       u32 win_ctrl, zorder, vir_info, act_info, dsp_info, dsp_st;
+       u32 y_factor, uv_factor;
+       u8 layer0_sel, layer1_sel, layer2_sel, layer3_sel;
+       u8 w0_state, w1_state, w2_state, w3_state;
+       u8 w2_0_state, w2_1_state, w2_2_state, w2_3_state;
+       u8 w3_0_state, w3_1_state, w3_2_state, w3_3_state;
+
+       u32 w0_vir_y, w0_vir_uv, w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y;
+       u32 w0_st_x = h_pw_bp, w0_st_y = v_pw_bp;
+       u32 w1_vir_y, w1_vir_uv, w1_act_x, w1_act_y, w1_dsp_x, w1_dsp_y;
+       u32 w1_st_x = h_pw_bp, w1_st_y = v_pw_bp;
+       u32 w0_y_h_fac, w0_y_v_fac, w0_uv_h_fac, w0_uv_v_fac;
+       u32 w1_y_h_fac, w1_y_v_fac, w1_uv_h_fac, w1_uv_v_fac;
+
+       u32 w2_0_vir_y, w2_1_vir_y, w2_2_vir_y, w2_3_vir_y;
+       u32 w2_0_dsp_x, w2_1_dsp_x, w2_2_dsp_x, w2_3_dsp_x;
+       u32 w2_0_dsp_y, w2_1_dsp_y, w2_2_dsp_y, w2_3_dsp_y;
+       u32 w2_0_st_x = h_pw_bp, w2_1_st_x = h_pw_bp;
+       u32 w2_2_st_x = h_pw_bp, w2_3_st_x = h_pw_bp;
+       u32 w2_0_st_y = v_pw_bp, w2_1_st_y = v_pw_bp;
+       u32 w2_2_st_y = v_pw_bp, w2_3_st_y = v_pw_bp;
+
+       u32 w3_0_vir_y, w3_1_vir_y, w3_2_vir_y, w3_3_vir_y;
+       u32 w3_0_dsp_x, w3_1_dsp_x, w3_2_dsp_x, w3_3_dsp_x;
+       u32 w3_0_dsp_y, w3_1_dsp_y, w3_2_dsp_y, w3_3_dsp_y;
+       u32 w3_0_st_x = h_pw_bp, w3_1_st_x = h_pw_bp;
+       u32 w3_2_st_x = h_pw_bp, w3_3_st_x = h_pw_bp;
+       u32 w3_0_st_y = v_pw_bp, w3_1_st_y = v_pw_bp;
+       u32 w3_2_st_y = v_pw_bp, w3_3_st_y = v_pw_bp;
+       u32 dclk_freq;
+       int size = 0;
+
+       dclk_freq = screen->mode.pixclock;
+       /*rk3368_lcdc_reg_dump(dev_drv); */
+
+       spin_lock(&lcdc_dev->reg_lock);
+       if (lcdc_dev->clk_on) {
+               zorder = lcdc_readl(lcdc_dev, DSP_CTRL1);
+               layer0_sel = (zorder & m_DSP_LAYER0_SEL) >> 8;
+               layer1_sel = (zorder & m_DSP_LAYER1_SEL) >> 10;
+               layer2_sel = (zorder & m_DSP_LAYER2_SEL) >> 12;
+               layer3_sel = (zorder & m_DSP_LAYER3_SEL) >> 14;
+               /*WIN0 */
+               win_ctrl = lcdc_readl(lcdc_dev, WIN0_CTRL0);
+               w0_state = win_ctrl & m_WIN0_EN;
+               fmt_id = (win_ctrl & m_WIN0_DATA_FMT) >> 1;
+               rk3368_lcdc_format_to_string(fmt_id, format_w0);
+               vir_info = lcdc_readl(lcdc_dev, WIN0_VIR);
+               act_info = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
+               dsp_info = lcdc_readl(lcdc_dev, WIN0_DSP_INFO);
+               dsp_st = lcdc_readl(lcdc_dev, WIN0_DSP_ST);
+               y_factor = lcdc_readl(lcdc_dev, WIN0_SCL_FACTOR_YRGB);
+               uv_factor = lcdc_readl(lcdc_dev, WIN0_SCL_FACTOR_CBR);
+               w0_vir_y = vir_info & m_WIN0_VIR_STRIDE;
+               w0_vir_uv = (vir_info & m_WIN0_VIR_STRIDE_UV) >> 16;
+               w0_act_x = (act_info & m_WIN0_ACT_WIDTH) + 1;
+               w0_act_y = ((act_info & m_WIN0_ACT_HEIGHT) >> 16) + 1;
+               w0_dsp_x = (dsp_info & m_WIN0_DSP_WIDTH) + 1;
+               w0_dsp_y = ((dsp_info & m_WIN0_DSP_HEIGHT) >> 16) + 1;
+               if (w0_state) {
+                       w0_st_x = dsp_st & m_WIN0_DSP_XST;
+                       w0_st_y = (dsp_st & m_WIN0_DSP_YST) >> 16;
+               }
+               w0_y_h_fac = y_factor & m_WIN0_HS_FACTOR_YRGB;
+               w0_y_v_fac = (y_factor & m_WIN0_VS_FACTOR_YRGB) >> 16;
+               w0_uv_h_fac = uv_factor & m_WIN0_HS_FACTOR_CBR;
+               w0_uv_v_fac = (uv_factor & m_WIN0_VS_FACTOR_CBR) >> 16;
+
+               /*WIN1 */
+               win_ctrl = lcdc_readl(lcdc_dev, WIN1_CTRL0);
+               w1_state = win_ctrl & m_WIN1_EN;
+               fmt_id = (win_ctrl & m_WIN1_DATA_FMT) >> 1;
+               rk3368_lcdc_format_to_string(fmt_id, format_w1);
+               vir_info = lcdc_readl(lcdc_dev, WIN1_VIR);
+               act_info = lcdc_readl(lcdc_dev, WIN1_ACT_INFO);
+               dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO);
+               dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST);
+               y_factor = lcdc_readl(lcdc_dev, WIN1_SCL_FACTOR_YRGB);
+               uv_factor = lcdc_readl(lcdc_dev, WIN1_SCL_FACTOR_CBR);
+               w1_vir_y = vir_info & m_WIN1_VIR_STRIDE;
+               w1_vir_uv = (vir_info & m_WIN1_VIR_STRIDE_UV) >> 16;
+               w1_act_x = (act_info & m_WIN1_ACT_WIDTH) + 1;
+               w1_act_y = ((act_info & m_WIN1_ACT_HEIGHT) >> 16) + 1;
+               w1_dsp_x = (dsp_info & m_WIN1_DSP_WIDTH) + 1;
+               w1_dsp_y = ((dsp_info & m_WIN1_DSP_HEIGHT) >> 16) + 1;
+               if (w1_state) {
+                       w1_st_x = dsp_st & m_WIN1_DSP_XST;
+                       w1_st_y = (dsp_st & m_WIN1_DSP_YST) >> 16;
+               }
+               w1_y_h_fac = y_factor & m_WIN1_HS_FACTOR_YRGB;
+               w1_y_v_fac = (y_factor & m_WIN1_VS_FACTOR_YRGB) >> 16;
+               w1_uv_h_fac = uv_factor & m_WIN1_HS_FACTOR_CBR;
+               w1_uv_v_fac = (uv_factor & m_WIN1_VS_FACTOR_CBR) >> 16;
+               /*WIN2 */
+               win_ctrl = lcdc_readl(lcdc_dev, WIN2_CTRL0);
+               w2_state = win_ctrl & m_WIN2_EN;
+               w2_0_state = (win_ctrl & m_WIN2_MST0_EN) >> 4;
+               w2_1_state = (win_ctrl & m_WIN2_MST1_EN) >> 5;
+               w2_2_state = (win_ctrl & m_WIN2_MST2_EN) >> 6;
+               w2_3_state = (win_ctrl & m_WIN2_MST3_EN) >> 7;
+               vir_info = lcdc_readl(lcdc_dev, WIN2_VIR0_1);
+               w2_0_vir_y = vir_info & m_WIN2_VIR_STRIDE0;
+               w2_1_vir_y = (vir_info & m_WIN2_VIR_STRIDE1) >> 16;
+               vir_info = lcdc_readl(lcdc_dev, WIN2_VIR2_3);
+               w2_2_vir_y = vir_info & m_WIN2_VIR_STRIDE2;
+               w2_3_vir_y = (vir_info & m_WIN2_VIR_STRIDE3) >> 16;
+
+               fmt_id = (win_ctrl & m_WIN2_DATA_FMT0) >> 1;
+               rk3368_lcdc_format_to_string(fmt_id, format_w2_0);
+               fmt_id = (win_ctrl & m_WIN2_DATA_FMT1) >> 1;
+               rk3368_lcdc_format_to_string(fmt_id, format_w2_1);
+               fmt_id = (win_ctrl & m_WIN2_DATA_FMT2) >> 1;
+               rk3368_lcdc_format_to_string(fmt_id, format_w2_2);
+               fmt_id = (win_ctrl & m_WIN2_DATA_FMT3) >> 1;
+               rk3368_lcdc_format_to_string(fmt_id, format_w2_3);
+
+               dsp_info = lcdc_readl(lcdc_dev, WIN2_DSP_INFO0);
+               dsp_st = lcdc_readl(lcdc_dev, WIN2_DSP_ST0);
+               w2_0_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH0) + 1;
+               w2_0_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT0) >> 16) + 1;
+               if (w2_0_state) {
+                       w2_0_st_x = dsp_st & m_WIN2_DSP_XST0;
+                       w2_0_st_y = (dsp_st & m_WIN2_DSP_YST0) >> 16;
+               }
+               dsp_info = lcdc_readl(lcdc_dev, WIN2_DSP_INFO1);
+               dsp_st = lcdc_readl(lcdc_dev, WIN2_DSP_ST1);
+               w2_1_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH1) + 1;
+               w2_1_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT1) >> 16) + 1;
+               if (w2_1_state) {
+                       w2_1_st_x = dsp_st & m_WIN2_DSP_XST1;
+                       w2_1_st_y = (dsp_st & m_WIN2_DSP_YST1) >> 16;
+               }
+               dsp_info = lcdc_readl(lcdc_dev, WIN2_DSP_INFO2);
+               dsp_st = lcdc_readl(lcdc_dev, WIN2_DSP_ST2);
+               w2_2_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH2) + 1;
+               w2_2_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT2) >> 16) + 1;
+               if (w2_2_state) {
+                       w2_2_st_x = dsp_st & m_WIN2_DSP_XST2;
+                       w2_2_st_y = (dsp_st & m_WIN2_DSP_YST2) >> 16;
+               }
+               dsp_info = lcdc_readl(lcdc_dev, WIN2_DSP_INFO3);
+               dsp_st = lcdc_readl(lcdc_dev, WIN2_DSP_ST3);
+               w2_3_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH3) + 1;
+               w2_3_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT3) >> 16) + 1;
+               if (w2_3_state) {
+                       w2_3_st_x = dsp_st & m_WIN2_DSP_XST3;
+                       w2_3_st_y = (dsp_st & m_WIN2_DSP_YST3) >> 16;
+               }
+
+               /*WIN3 */
+               win_ctrl = lcdc_readl(lcdc_dev, WIN3_CTRL0);
+               w3_state = win_ctrl & m_WIN3_EN;
+               w3_0_state = (win_ctrl & m_WIN3_MST0_EN) >> 4;
+               w3_1_state = (win_ctrl & m_WIN3_MST1_EN) >> 5;
+               w3_2_state = (win_ctrl & m_WIN3_MST2_EN) >> 6;
+               w3_3_state = (win_ctrl & m_WIN3_MST3_EN) >> 7;
+               vir_info = lcdc_readl(lcdc_dev, WIN3_VIR0_1);
+               w3_0_vir_y = vir_info & m_WIN3_VIR_STRIDE0;
+               w3_1_vir_y = (vir_info & m_WIN3_VIR_STRIDE1) >> 16;
+               vir_info = lcdc_readl(lcdc_dev, WIN3_VIR2_3);
+               w3_2_vir_y = vir_info & m_WIN3_VIR_STRIDE2;
+               w3_3_vir_y = (vir_info & m_WIN3_VIR_STRIDE3) >> 16;
+               fmt_id = (win_ctrl & m_WIN3_DATA_FMT0) >> 1;
+               rk3368_lcdc_format_to_string(fmt_id, format_w3_0);
+               fmt_id = (win_ctrl & m_WIN3_DATA_FMT1) >> 1;
+               rk3368_lcdc_format_to_string(fmt_id, format_w3_1);
+               fmt_id = (win_ctrl & m_WIN3_DATA_FMT2) >> 1;
+               rk3368_lcdc_format_to_string(fmt_id, format_w3_2);
+               fmt_id = (win_ctrl & m_WIN3_DATA_FMT3) >> 1;
+               rk3368_lcdc_format_to_string(fmt_id, format_w3_3);
+               dsp_info = lcdc_readl(lcdc_dev, WIN3_DSP_INFO0);
+               dsp_st = lcdc_readl(lcdc_dev, WIN3_DSP_ST0);
+               w3_0_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH0) + 1;
+               w3_0_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT0) >> 16) + 1;
+               if (w3_0_state) {
+                       w3_0_st_x = dsp_st & m_WIN3_DSP_XST0;
+                       w3_0_st_y = (dsp_st & m_WIN3_DSP_YST0) >> 16;
+               }
+
+               dsp_info = lcdc_readl(lcdc_dev, WIN3_DSP_INFO1);
+               dsp_st = lcdc_readl(lcdc_dev, WIN3_DSP_ST1);
+               w3_1_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH1) + 1;
+               w3_1_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT1) >> 16) + 1;
+               if (w3_1_state) {
+                       w3_1_st_x = dsp_st & m_WIN3_DSP_XST1;
+                       w3_1_st_y = (dsp_st & m_WIN3_DSP_YST1) >> 16;
+               }
+
+               dsp_info = lcdc_readl(lcdc_dev, WIN3_DSP_INFO2);
+               dsp_st = lcdc_readl(lcdc_dev, WIN3_DSP_ST2);
+               w3_2_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH2) + 1;
+               w3_2_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT2) >> 16) + 1;
+               if (w3_2_state) {
+                       w3_2_st_x = dsp_st & m_WIN3_DSP_XST2;
+                       w3_2_st_y = (dsp_st & m_WIN3_DSP_YST2) >> 16;
+               }
+
+               dsp_info = lcdc_readl(lcdc_dev, WIN3_DSP_INFO3);
+               dsp_st = lcdc_readl(lcdc_dev, WIN3_DSP_ST3);
+               w3_3_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH3) + 1;
+               w3_3_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT3) >> 16) + 1;
+               if (w3_3_state) {
+                       w3_3_st_x = dsp_st & m_WIN3_DSP_XST3;
+                       w3_3_st_y = (dsp_st & m_WIN3_DSP_YST3) >> 16;
+               }
+
+       } else {
+               spin_unlock(&lcdc_dev->reg_lock);
+               return -EPERM;
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+       size += snprintf(dsp_buf, 80,
+               "z-order:\n  win[%d]\n  win[%d]\n  win[%d]\n  win[%d]\n",
+               layer3_sel, layer2_sel, layer1_sel, layer0_sel);
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+       /*win0*/
+       size += snprintf(dsp_buf, 80,
+                "win0:\n  state:%d, fmt:%7s\n  y_vir:%4d, uv_vir:%4d,",
+                w0_state, format_w0, w0_vir_y, w0_vir_uv);
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+
+       size += snprintf(dsp_buf, 80,
+                " x_act  :%5d, y_act  :%5d, dsp_x   :%5d, dsp_y   :%5d\n",
+                w0_act_x, w0_act_y, w0_dsp_x, w0_dsp_y);
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+
+       size += snprintf(dsp_buf, 80,
+                "  x_st :%4d, y_st  :%4d, y_h_fac:%5d, y_v_fac:%5d, ",
+                w0_st_x-h_pw_bp, w0_st_y-v_pw_bp, w0_y_h_fac, w0_y_v_fac);
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+
+       size += snprintf(dsp_buf, 80,
+                "uv_h_fac:%5d, uv_v_fac:%5d\n  y_addr:0x%08x,    uv_addr:0x%08x\n",
+                w0_uv_h_fac, w0_uv_v_fac, lcdc_readl(lcdc_dev, WIN0_YRGB_MST),
+                lcdc_readl(lcdc_dev, WIN0_CBR_MST));
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+
+       /*win1*/
+       size += snprintf(dsp_buf, 80,
+                "win1:\n  state:%d, fmt:%7s\n  y_vir:%4d, uv_vir:%4d,",
+                w1_state, format_w1, w1_vir_y, w1_vir_uv);
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+
+       size += snprintf(dsp_buf, 80,
+                " x_act  :%5d, y_act  :%5d, dsp_x   :%5d, dsp_y   :%5d\n",
+                w1_act_x, w1_act_y, w1_dsp_x, w1_dsp_y);
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+
+       size += snprintf(dsp_buf, 80,
+                "  x_st :%4d, y_st  :%4d, y_h_fac:%5d, y_v_fac:%5d, ",
+                w1_st_x-h_pw_bp, w1_st_y-v_pw_bp, w1_y_h_fac, w1_y_v_fac);
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+
+       size += snprintf(dsp_buf, 80,
+                "uv_h_fac:%5d, uv_v_fac:%5d\n  y_addr:0x%08x,    uv_addr:0x%08x\n",
+                w1_uv_h_fac, w1_uv_v_fac, lcdc_readl(lcdc_dev, WIN1_YRGB_MST),
+                lcdc_readl(lcdc_dev, WIN1_CBR_MST));
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+
+       /*win2*/
+       size += snprintf(dsp_buf, 80,
+                "win2:\n  state:%d\n",
+                w2_state);
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+       /*area 0*/
+       size += snprintf(dsp_buf, 80,
+                "  area0: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
+                w2_0_state, format_w2_0, w2_0_dsp_x, w2_0_dsp_y);
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+       size += snprintf(dsp_buf, 80,
+                " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
+                w2_0_st_x - h_pw_bp, w2_0_st_y - v_pw_bp,
+                lcdc_readl(lcdc_dev, WIN2_MST0));
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+
+       /*area 1*/
+       size += snprintf(dsp_buf, 80,
+                "  area1: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
+                w2_1_state, format_w2_1, w2_1_dsp_x, w2_1_dsp_y);
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+       size += snprintf(dsp_buf, 80,
+                " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
+                w2_1_st_x - h_pw_bp, w2_1_st_y - v_pw_bp,
+                lcdc_readl(lcdc_dev, WIN2_MST1));
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+
+       /*area 2*/
+       size += snprintf(dsp_buf, 80,
+                "  area2: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
+                w2_2_state, format_w2_2, w2_2_dsp_x, w2_2_dsp_y);
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+       size += snprintf(dsp_buf, 80,
+                " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
+                w2_2_st_x - h_pw_bp, w2_2_st_y - v_pw_bp,
+                lcdc_readl(lcdc_dev, WIN2_MST2));
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+
+       /*area 3*/
+       size += snprintf(dsp_buf, 80,
+                "  area3: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
+                w2_3_state, format_w2_3, w2_3_dsp_x, w2_3_dsp_y);
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+       size += snprintf(dsp_buf, 80,
+                " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
+                w2_3_st_x - h_pw_bp, w2_3_st_y - v_pw_bp,
+                lcdc_readl(lcdc_dev, WIN2_MST3));
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+
+       /*win3*/
+       size += snprintf(dsp_buf, 80,
+                "win3:\n  state:%d\n",
+                w3_state);
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+       /*area 0*/
+       size += snprintf(dsp_buf, 80,
+                "  area0: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
+                w3_0_state, format_w3_0, w3_0_dsp_x, w3_0_dsp_y);
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+       size += snprintf(dsp_buf, 80,
+                " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
+                w3_0_st_x - h_pw_bp, w3_0_st_y - v_pw_bp,
+                lcdc_readl(lcdc_dev, WIN3_MST0));
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+
+       /*area 1*/
+       size += snprintf(dsp_buf, 80,
+                "  area1: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
+                w3_1_state, format_w3_1, w3_1_dsp_x, w3_1_dsp_y);
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+       size += snprintf(dsp_buf, 80,
+                " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
+                w3_1_st_x - h_pw_bp, w3_1_st_y - v_pw_bp,
+                lcdc_readl(lcdc_dev, WIN3_MST1));
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+
+       /*area 2*/
+       size += snprintf(dsp_buf, 80,
+                "  area2: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
+                w3_2_state, format_w3_2, w3_2_dsp_x, w3_2_dsp_y);
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+       size += snprintf(dsp_buf, 80,
+                " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
+                w3_2_st_x - h_pw_bp, w3_2_st_y - v_pw_bp,
+                lcdc_readl(lcdc_dev, WIN3_MST2));
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+
+       /*area 3*/
+       size += snprintf(dsp_buf, 80,
+                "  area3: state:%d, fmt:%7s, dsp_x:%4d, dsp_y:%4d,",
+                w3_3_state, format_w3_3, w3_3_dsp_x, w3_3_dsp_y);
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+       size += snprintf(dsp_buf, 80,
+                " x_st:%4d, y_st:%4d, y_addr:0x%08x\n",
+                w3_3_st_x - h_pw_bp, w3_3_st_y - v_pw_bp,
+                lcdc_readl(lcdc_dev, WIN3_MST3));
+       strcat(buf, dsp_buf);
+       memset(dsp_buf, 0, sizeof(dsp_buf));
+
+       return size;
+}
+
+static int rk3368_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
+                              bool set)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       struct rk_screen *screen = dev_drv->cur_screen;
+       u64 ft = 0;
+       u32 dotclk;
+       int ret;
+       u32 pixclock;
+       u32 x_total, y_total;
+
+       if (set) {
+               if (fps == 0) {
+                       dev_info(dev_drv->dev, "unsupport set fps=0\n");
+                       return 0;
+               }
+               ft = div_u64(1000000000000llu, fps);
+               x_total =
+                   screen->mode.upper_margin + screen->mode.lower_margin +
+                   screen->mode.yres + screen->mode.vsync_len;
+               y_total =
+                   screen->mode.left_margin + screen->mode.right_margin +
+                   screen->mode.xres + screen->mode.hsync_len;
+               dev_drv->pixclock = div_u64(ft, x_total * y_total);
+               dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
+               ret = clk_set_rate(lcdc_dev->pll_sclk, dotclk); /*set pll */
+               if (ret)
+                       dev_err(dev_drv->dev,
+                               "set lcdc%d pll_sclk failed\n", lcdc_dev->id);
+
+               ret = clk_set_rate(lcdc_dev->dclk, dotclk);
+               /*SET NEW PLL FOR RK3368 */
+       }
+
+       pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
+       lcdc_dev->pixclock = pixclock;
+       dev_drv->pixclock = lcdc_dev->pixclock;
+       fps = rk_fb_calc_fps(lcdc_dev->screen, pixclock);
+       screen->ft = 1000 / fps;        /*one frame time in ms */
+
+       if (set)
+               dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
+                        clk_get_rate(lcdc_dev->dclk), fps);
+
+       return fps;
+}
+
+static int rk3368_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
+{
+       mutex_lock(&dev_drv->fb_win_id_mutex);
+       if (order == FB_DEFAULT_ORDER)
+               order = FB0_WIN0_FB1_WIN1_FB2_WIN2_FB3_WIN3_FB4_HWC;
+       dev_drv->fb4_win_id = order / 10000;
+       dev_drv->fb3_win_id = (order / 1000) % 10;
+       dev_drv->fb2_win_id = (order / 100) % 10;
+       dev_drv->fb1_win_id = (order / 10) % 10;
+       dev_drv->fb0_win_id = order % 10;
+       mutex_unlock(&dev_drv->fb_win_id_mutex);
+
+       return 0;
+}
+
+static int rk3368_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
+                                 const char *id)
+{
+       int win_id = 0;
+
+       mutex_lock(&dev_drv->fb_win_id_mutex);
+       if (!strcmp(id, "fb0") || !strcmp(id, "fb5"))
+               win_id = dev_drv->fb0_win_id;
+       else if (!strcmp(id, "fb1") || !strcmp(id, "fb6"))
+               win_id = dev_drv->fb1_win_id;
+       else if (!strcmp(id, "fb2") || !strcmp(id, "fb7"))
+               win_id = dev_drv->fb2_win_id;
+       else if (!strcmp(id, "fb3") || !strcmp(id, "fb8"))
+               win_id = dev_drv->fb3_win_id;
+       else if (!strcmp(id, "fb4") || !strcmp(id, "fb9"))
+               win_id = dev_drv->fb4_win_id;
+       mutex_unlock(&dev_drv->fb_win_id_mutex);
+
+       return win_id;
+}
+
+static int rk3368_set_dsp_lut(struct rk_lcdc_driver *dev_drv, int *lut)
+{
+       int i, j;
+       int __iomem *c;
+       int v, r, g, b;
+       int ret = 0;
+
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
+       lcdc_cfg_done(lcdc_dev);
+       mdelay(25);
+       if (dev_drv->cur_screen->dsp_lut) {
+               for (i = 0; i < 256; i++) {
+                       dev_drv->cur_screen->dsp_lut[i] = lut[i];
+                       v = dev_drv->cur_screen->dsp_lut[i];
+                       c = lcdc_dev->dsp_lut_addr_base + (i << 2);
+                       b = (v & 0xff) << 2;
+                       g = (v & 0xff00) << 4;
+                       r = (v & 0xff0000) << 6;
+                       v = r + g + b;
+                       for (j = 0; j < 4; j++) {
+                               writel_relaxed(v, c);
+                               v += (1 + (1 << 10) + (1 << 20));
+                               c++;
+                       }
+               }
+       } else {
+               dev_err(dev_drv->dev, "no buffer to backup lut data!\n");
+               ret = -1;
+       }
+
+       do {
+               lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
+                            v_DSP_LUT_EN(1));
+               lcdc_cfg_done(lcdc_dev);
+       } while (!lcdc_read_bit(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN));
+       return ret;
+}
+
+static int rk3368_lcdc_config_done(struct rk_lcdc_driver *dev_drv)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       int i;
+       unsigned int mask, val;
+       struct rk_lcdc_win *win = NULL;
+
+       spin_lock(&lcdc_dev->reg_lock);
+       lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
+                    v_STANDBY_EN(lcdc_dev->standby));
+       for (i = 0; i < 4; i++) {
+               win = dev_drv->win[i];
+               if ((win->state == 0) && (win->last_state == 1)) {
+                       switch (win->id) {
+                       case 0:
+                               /*lcdc_writel(lcdc_dev,WIN0_CTRL1,0x0);
+                                  for rk3288 to fix hw bug? */
+                               mask = m_WIN0_EN;
+                               val = v_WIN0_EN(0);
+                               lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
+                               break;
+                       case 1:
+                               /*lcdc_writel(lcdc_dev,WIN1_CTRL1,0x0);
+                                  for rk3288 to fix hw bug? */
+                               mask = m_WIN1_EN;
+                               val = v_WIN1_EN(0);
+                               lcdc_msk_reg(lcdc_dev, WIN1_CTRL0, mask, val);
+                               break;
+                       case 2:
+                               mask = m_WIN2_EN | m_WIN2_MST0_EN |
+                                   m_WIN2_MST1_EN |
+                                   m_WIN2_MST2_EN | m_WIN2_MST3_EN;
+                               val = v_WIN2_EN(0) | v_WIN2_MST0_EN(0) |
+                                   v_WIN2_MST1_EN(0) |
+                                   v_WIN2_MST2_EN(0) | v_WIN2_MST3_EN(0);
+                               lcdc_msk_reg(lcdc_dev, WIN2_CTRL0, mask, val);
+                               break;
+                       case 3:
+                               mask = m_WIN3_EN | m_WIN3_MST0_EN |
+                                   m_WIN3_MST1_EN |
+                                   m_WIN3_MST2_EN | m_WIN3_MST3_EN;
+                               val = v_WIN3_EN(0) | v_WIN3_MST0_EN(0) |
+                                   v_WIN3_MST1_EN(0) |
+                                   v_WIN3_MST2_EN(0) | v_WIN3_MST3_EN(0);
+                               lcdc_msk_reg(lcdc_dev, WIN3_CTRL0, mask, val);
+                               break;
+                       case 4:
+                               mask = m_HWC_EN;
+                               val = v_HWC_EN(0);
+                               lcdc_msk_reg(lcdc_dev, HWC_CTRL0, mask, val);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               win->last_state = win->state;
+       }
+       lcdc_cfg_done(lcdc_dev);
+       spin_unlock(&lcdc_dev->reg_lock);
+       return 0;
+}
+
+static int rk3368_lcdc_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       spin_lock(&lcdc_dev->reg_lock);
+       lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN,
+                    v_DIRECT_PATH_EN(open));
+       lcdc_cfg_done(lcdc_dev);
+       spin_unlock(&lcdc_dev->reg_lock);
+       return 0;
+}
+
+static int rk3368_lcdc_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
+{
+       struct lcdc_device *lcdc_dev = container_of(dev_drv,
+                                                   struct lcdc_device, driver);
+       spin_lock(&lcdc_dev->reg_lock);
+       lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATCH_SEL,
+                    v_DIRECT_PATCH_SEL(win_id));
+       lcdc_cfg_done(lcdc_dev);
+       spin_unlock(&lcdc_dev->reg_lock);
+       return 0;
+}
+
+static int rk3368_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       int ovl;
+
+       spin_lock(&lcdc_dev->reg_lock);
+       ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN);
+       spin_unlock(&lcdc_dev->reg_lock);
+       return ovl;
+}
+
+static int rk3368_lcdc_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv,
+                                     int enable)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       if (enable)
+               enable_irq(lcdc_dev->irq);
+       else
+               disable_irq(lcdc_dev->irq);
+       return 0;
+}
+
+int rk3368_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       u32 int_reg;
+       int ret;
+
+       if (lcdc_dev->clk_on && (!dev_drv->suspend_flag)) {
+               int_reg = lcdc_readl(lcdc_dev, INTR_STATUS);
+               if (int_reg & m_LINE_FLAG0_INTR_STS) {
+                       lcdc_dev->driver.frame_time.last_framedone_t =
+                           lcdc_dev->driver.frame_time.framedone_t;
+                       lcdc_dev->driver.frame_time.framedone_t = cpu_clock(0);
+                       lcdc_msk_reg(lcdc_dev, INTR_CLEAR,
+                                    m_LINE_FLAG0_INTR_CLR,
+                                    v_LINE_FLAG0_INTR_CLR(1));
+                       ret = RK_LF_STATUS_FC;
+               } else {
+                       ret = RK_LF_STATUS_FR;
+               }
+       } else {
+               ret = RK_LF_STATUS_NC;
+       }
+
+       return ret;
+}
+
+static int rk3368_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);
+       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);
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+       return 0;
+}
+
+static struct lcdc_cabc_mode cabc_mode[4] = {
+       /* pixel_num,8 stage_up, stage_down */
+       {5, 148, 20, 300},      /*mode 1 */
+       {10, 148, 20, 300},     /*mode 2 */
+       {15, 148, 20, 300},     /*mode 3 */
+       {20, 148, 20, 300},     /*mode 4 */
+};
+
+static int rk3368_lcdc_set_dsp_cabc(struct rk_lcdc_driver *dev_drv, int mode)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       struct rk_screen *screen = dev_drv->cur_screen;
+       u32 total_pixel, calc_pixel, stage_up, stage_down;
+       u32 pixel_num, global_su;
+       u32 stage_up_rec, stage_down_rec, global_su_rec;
+       u32 mask = 0, val = 0, cabc_en = 0;
+       u32 __maybe_unused max_mode_num =
+           sizeof(cabc_mode) / sizeof(struct lcdc_cabc_mode);
+
+       dev_drv->cabc_mode = mode;
+#if 0/*ndef CONFIG_RK_FPGA*/
+       /* iomux connect to vop or pwm */
+       if (mode == 0) {
+               DBG(3, "close cabc and select rk pwm\n");
+               val = 0x30002;
+               writel_relaxed(val, RK_GRF_VIRT + rk3368_GRF_GPIO3C_IOMUX);
+               cabc_en = 0;
+       } else if (mode > 0 && mode <= max_mode_num) {
+               DBG(3, "open cabc and select vop pwm\n");
+               val = 0x30003;
+               writel_relaxed(val, RK_GRF_VIRT + rk3368_GRF_GPIO3C_IOMUX);
+               cabc_en = 1;
+       } else if (mode > 0x10 && mode <= (max_mode_num + 0x10)) {
+               DBG(3, "open cabc and select rk pwm\n");
+               val = 0x30003;
+               writel_relaxed(val, RK_GRF_VIRT + rk3368_GRF_GPIO3C_IOMUX);
+               cabc_en = 1;
+               mode -= 0x10;
+       } else if (mode == 0xff) {
+               DBG(3, "close cabc and select vop pwm\n");
+               val = 0x30002;
+               writel_relaxed(val, RK_GRF_VIRT + rk3368_GRF_GPIO3C_IOMUX);
+               cabc_en = 0;
+       } else {
+               dev_err(lcdc_dev->dev, "invalid cabc mode value:%d", mode);
+               return 0;
+       }
+#endif
+       if (cabc_en == 0) {
+               spin_lock(&lcdc_dev->reg_lock);
+               if (lcdc_dev->clk_on) {
+                       lcdc_msk_reg(lcdc_dev, CABC_CTRL0,
+                                    m_CABC_EN, v_CABC_EN(0));
+                       lcdc_cfg_done(lcdc_dev);
+               }
+               spin_unlock(&lcdc_dev->reg_lock);
+               return 0;
+       }
+
+       total_pixel = screen->mode.xres * screen->mode.yres;
+       pixel_num = 1000 - (cabc_mode[mode - 1].pixel_num);
+       calc_pixel = (total_pixel * pixel_num) / 1000;
+       stage_up = cabc_mode[mode - 1].stage_up;
+       stage_down = cabc_mode[mode - 1].stage_down;
+       global_su = cabc_mode[mode - 1].global_su;
+
+       stage_up_rec = 256 * 256 / stage_up;
+       stage_down_rec = 256 * 256 / stage_down;
+       global_su_rec = 256 * 256 / global_su;
+
+       spin_lock(&lcdc_dev->reg_lock);
+       if (lcdc_dev->clk_on) {
+               mask = m_CABC_CALC_PIXEL_NUM;
+               val = v_CABC_CALC_PIXEL_NUM(calc_pixel);
+               lcdc_msk_reg(lcdc_dev, CABC_CTRL0, mask, val);
+
+               mask = m_CABC_TOTAL_PIXEL_NUM;
+               val = v_CABC_TOTAL_PIXEL_NUM(total_pixel);
+               lcdc_msk_reg(lcdc_dev, CABC_CTRL1, mask, val);
+
+               mask = m_CABC_STAGE_UP | m_CABC_STAGE_UP_REC |
+                   m_CABC_GLOBAL_SU_LIMIT_EN | m_CABC_GLOBAL_SU_REC;
+               val = v_CABC_STAGE_UP(stage_up) |
+                   v_CABC_STAGE_UP_REC(stage_up_rec) |
+                   v_CABC_GLOBAL_SU_LIMIT_EN(1) |
+                   v_CABC_GLOBAL_SU_REC(global_su_rec);
+               lcdc_msk_reg(lcdc_dev, CABC_CTRL2, mask, val);
+
+               mask = m_CABC_STAGE_DOWN | m_CABC_STAGE_DOWN_REC |
+                   m_CABC_GLOBAL_SU;
+               val = v_CABC_STAGE_DOWN(stage_down) |
+                   v_CABC_STAGE_DOWN_REC(stage_down_rec) |
+                   v_CABC_GLOBAL_SU(global_su);
+               lcdc_msk_reg(lcdc_dev, CABC_CTRL3, mask, val);
+               lcdc_cfg_done(lcdc_dev);
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+
+       return 0;
+}
+
+/*
+       a:[-30~0]:
+           sin_hue = sin(a)*256 +0x100;
+           cos_hue = cos(a)*256;
+       a:[0~30]
+           sin_hue = sin(a)*256;
+           cos_hue = cos(a)*256;
+*/
+static int rk3368_lcdc_get_bcsh_hue(struct rk_lcdc_driver *dev_drv,
+                                   bcsh_hue_mode mode)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       u32 val;
+
+       spin_lock(&lcdc_dev->reg_lock);
+       if (lcdc_dev->clk_on) {
+               val = lcdc_readl(lcdc_dev, BCSH_H);
+               switch (mode) {
+               case H_SIN:
+                       val &= m_BCSH_SIN_HUE;
+                       break;
+               case H_COS:
+                       val &= m_BCSH_COS_HUE;
+                       val >>= 16;
+                       break;
+               default:
+                       break;
+               }
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+
+       return val;
+}
+
+static int rk3368_lcdc_set_bcsh_hue(struct rk_lcdc_driver *dev_drv,
+                                   int sin_hue, int cos_hue)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       u32 mask, val;
+
+       spin_lock(&lcdc_dev->reg_lock);
+       if (lcdc_dev->clk_on) {
+               mask = m_BCSH_SIN_HUE | m_BCSH_COS_HUE;
+               val = v_BCSH_SIN_HUE(sin_hue) | v_BCSH_COS_HUE(cos_hue);
+               lcdc_msk_reg(lcdc_dev, BCSH_H, mask, val);
+               lcdc_cfg_done(lcdc_dev);
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+
+       return 0;
+}
+
+static int rk3368_lcdc_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
+                                   bcsh_bcs_mode mode, int value)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       u32 mask, val;
+
+       spin_lock(&lcdc_dev->reg_lock);
+       if (lcdc_dev->clk_on) {
+               switch (mode) {
+               case BRIGHTNESS:
+                       /*from 0 to 255,typical is 128 */
+                       if (value < 0x80)
+                               value += 0x80;
+                       else if (value >= 0x80)
+                               value = value - 0x80;
+                       mask = m_BCSH_BRIGHTNESS;
+                       val = v_BCSH_BRIGHTNESS(value);
+                       break;
+               case CONTRAST:
+                       /*from 0 to 510,typical is 256 */
+                       mask = m_BCSH_CONTRAST;
+                       val = v_BCSH_CONTRAST(value);
+                       break;
+               case SAT_CON:
+                       /*from 0 to 1015,typical is 256 */
+                       mask = m_BCSH_SAT_CON;
+                       val = v_BCSH_SAT_CON(value);
+                       break;
+               default:
+                       break;
+               }
+               lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
+               lcdc_cfg_done(lcdc_dev);
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+       return val;
+}
+
+static int rk3368_lcdc_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv,
+                                   bcsh_bcs_mode mode)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       u32 val;
+
+       spin_lock(&lcdc_dev->reg_lock);
+       if (lcdc_dev->clk_on) {
+               val = lcdc_readl(lcdc_dev, BCSH_BCS);
+               switch (mode) {
+               case BRIGHTNESS:
+                       val &= m_BCSH_BRIGHTNESS;
+                       if (val > 0x80)
+                               val -= 0x80;
+                       else
+                               val += 0x80;
+                       break;
+               case CONTRAST:
+                       val &= m_BCSH_CONTRAST;
+                       val >>= 8;
+                       break;
+               case SAT_CON:
+                       val &= m_BCSH_SAT_CON;
+                       val >>= 20;
+                       break;
+               default:
+                       break;
+               }
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+       return val;
+}
+
+static int rk3368_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       u32 mask, val;
+
+       spin_lock(&lcdc_dev->reg_lock);
+       if (lcdc_dev->clk_on) {
+               rk3368_lcdc_bcsh_path_sel(dev_drv);
+               if (open) {
+                       lcdc_writel(lcdc_dev, BCSH_COLOR_BAR, 0x1);
+                       lcdc_writel(lcdc_dev, BCSH_BCS, 0xd0010000);
+                       lcdc_writel(lcdc_dev, BCSH_H, 0x01000000);
+               } else {
+                       mask = m_BCSH_EN;
+                       val = v_BCSH_EN(0);
+                       lcdc_msk_reg(lcdc_dev, BCSH_COLOR_BAR, mask, val);
+               }
+               lcdc_cfg_done(lcdc_dev);
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+       return 0;
+}
+
+static int rk3368_lcdc_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable)
+{
+       if (!enable || !dev_drv->bcsh.enable) {
+               rk3368_lcdc_open_bcsh(dev_drv, false);
+               return 0;
+       }
+
+       if (dev_drv->bcsh.brightness <= 255 ||
+           dev_drv->bcsh.contrast <= 510 ||
+           dev_drv->bcsh.sat_con <= 1015 ||
+           (dev_drv->bcsh.sin_hue <= 511 && dev_drv->bcsh.cos_hue <= 511)) {
+               rk3368_lcdc_open_bcsh(dev_drv, true);
+               if (dev_drv->bcsh.brightness <= 255)
+                       rk3368_lcdc_set_bcsh_bcs(dev_drv, BRIGHTNESS,
+                                                dev_drv->bcsh.brightness);
+               if (dev_drv->bcsh.contrast <= 510)
+                       rk3368_lcdc_set_bcsh_bcs(dev_drv, CONTRAST,
+                                                dev_drv->bcsh.contrast);
+               if (dev_drv->bcsh.sat_con <= 1015)
+                       rk3368_lcdc_set_bcsh_bcs(dev_drv, SAT_CON,
+                                                dev_drv->bcsh.sat_con);
+               if (dev_drv->bcsh.sin_hue <= 511 &&
+                   dev_drv->bcsh.cos_hue <= 511)
+                       rk3368_lcdc_set_bcsh_hue(dev_drv,
+                                                dev_drv->bcsh.sin_hue,
+                                                dev_drv->bcsh.cos_hue);
+       }
+       return 0;
+}
+
+static int rk3368_lcdc_dsp_black(struct rk_lcdc_driver *dev_drv, int enable)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+
+       rk3368_lcdc_get_backlight_device(dev_drv);
+
+       if (enable) {
+               /* close the backlight */
+               if (lcdc_dev->backlight) {
+                       lcdc_dev->backlight->props.power = FB_BLANK_POWERDOWN;
+                       backlight_update_status(lcdc_dev->backlight);
+               }
+#if 1
+               spin_lock(&lcdc_dev->reg_lock);
+               if (likely(lcdc_dev->clk_on)) {
+                       lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLACK_EN,
+                                    v_DSP_BLACK_EN(1));
+                       lcdc_cfg_done(lcdc_dev);
+               }
+               spin_unlock(&lcdc_dev->reg_lock);
+#endif
+               if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
+                       dev_drv->trsm_ops->disable();
+       } else {
+#if 1
+               spin_lock(&lcdc_dev->reg_lock);
+               if (likely(lcdc_dev->clk_on)) {
+                       lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLACK_EN,
+                                    v_DSP_BLACK_EN(0));
+
+                       lcdc_cfg_done(lcdc_dev);
+               }
+               spin_unlock(&lcdc_dev->reg_lock);
+#endif
+               if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
+                       dev_drv->trsm_ops->enable();
+               msleep(100);
+               /* open the backlight */
+               if (lcdc_dev->backlight) {
+                       lcdc_dev->backlight->props.power = FB_BLANK_UNBLANK;
+                       backlight_update_status(lcdc_dev->backlight);
+               }
+       }
+
+       return 0;
+}
+
+static struct rk_lcdc_drv_ops lcdc_drv_ops = {
+       .open = rk3368_lcdc_open,
+       .win_direct_en = rk3368_lcdc_win_direct_en,
+       .load_screen = rk3368_load_screen,
+       .set_par = rk3368_lcdc_set_par,
+       .pan_display = rk3368_lcdc_pan_display,
+       .direct_set_addr = rk3368_lcdc_direct_set_win_addr,
+       /*.lcdc_reg_update = rk3368_lcdc_reg_update,*/
+       .blank = rk3368_lcdc_blank,
+       .ioctl = rk3368_lcdc_ioctl,
+       .suspend = rk3368_lcdc_early_suspend,
+       .resume = rk3368_lcdc_early_resume,
+       .get_win_state = rk3368_lcdc_get_win_state,
+       .ovl_mgr = rk3368_lcdc_ovl_mgr,
+       .get_disp_info = rk3368_lcdc_get_disp_info,
+       .fps_mgr = rk3368_lcdc_fps_mgr,
+       .fb_get_win_id = rk3368_lcdc_get_win_id,
+       .fb_win_remap = rk3368_fb_win_remap,
+       .set_dsp_lut = rk3368_set_dsp_lut,
+       .poll_vblank = rk3368_lcdc_poll_vblank,
+       .dpi_open = rk3368_lcdc_dpi_open,
+       .dpi_win_sel = rk3368_lcdc_dpi_win_sel,
+       .dpi_status = rk3368_lcdc_dpi_status,
+       .get_dsp_addr = rk3368_lcdc_get_dsp_addr,
+       .set_dsp_cabc = rk3368_lcdc_set_dsp_cabc,
+       .set_dsp_bcsh_hue = rk3368_lcdc_set_bcsh_hue,
+       .set_dsp_bcsh_bcs = rk3368_lcdc_set_bcsh_bcs,
+       .get_dsp_bcsh_hue = rk3368_lcdc_get_bcsh_hue,
+       .get_dsp_bcsh_bcs = rk3368_lcdc_get_bcsh_bcs,
+       .open_bcsh = rk3368_lcdc_open_bcsh,
+       .dump_reg = rk3368_lcdc_reg_dump,
+       .cfg_done = rk3368_lcdc_config_done,
+       .set_irq_to_cpu = rk3368_lcdc_set_irq_to_cpu,
+       .dsp_black = rk3368_lcdc_dsp_black,
+       .mmu_en    = rk3368_lcdc_mmu_en,
+};
+
+#ifdef LCDC_IRQ_EMPTY_DEBUG
+static int rk3368_lcdc_parse_irq(struct lcdc_device *lcdc_dev,
+                                unsigned int intr_status)
+{
+       if (intr_status & m_WIN0_EMPTY_INTR_STS) {
+               lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN0_EMPTY_INTR_CLR,
+                            v_WIN0_EMPTY_INTR_CLR(1));
+               dev_warn(lcdc_dev->dev, "win0 empty irq!");
+       } else if (intr_status & m_WIN1_EMPTY_INTR_STS) {
+               lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN1_EMPTY_INTR_CLR,
+                            v_WIN1_EMPTY_INTR_CLR(1));
+               dev_warn(lcdc_dev->dev, "win1 empty irq!");
+       } else if (intr_status & m_WIN2_EMPTY_INTR_STS) {
+               lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN2_EMPTY_INTR_CLR,
+                            v_WIN2_EMPTY_INTR_CLR(1));
+               dev_warn(lcdc_dev->dev, "win2 empty irq!");
+       } else if (intr_status & m_WIN3_EMPTY_INTR_STS) {
+               lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN3_EMPTY_INTR_CLR,
+                            v_WIN3_EMPTY_INTR_CLR(1));
+               dev_warn(lcdc_dev->dev, "win3 empty irq!");
+       } else if (intr_status & m_HWC_EMPTY_INTR_STS) {
+               lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_HWC_EMPTY_INTR_CLR,
+                            v_HWC_EMPTY_INTR_CLR(1));
+               dev_warn(lcdc_dev->dev, "HWC empty irq!");
+       } else if (intr_status & m_POST_BUF_EMPTY_INTR_STS) {
+               lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_POST_BUF_EMPTY_INTR_CLR,
+                            v_POST_BUF_EMPTY_INTR_CLR(1));
+               dev_warn(lcdc_dev->dev, "post buf empty irq!");
+       } else if (intr_status & m_PWM_GEN_INTR_STS) {
+               lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_PWM_GEN_INTR_CLR,
+                            v_PWM_GEN_INTR_CLR(1));
+               dev_warn(lcdc_dev->dev, "PWM gen irq!");
+       }
+       return 0;
+}
+#endif
+
+static irqreturn_t rk3368_lcdc_isr(int irq, void *dev_id)
+{
+       struct lcdc_device *lcdc_dev = (struct lcdc_device *)dev_id;
+       ktime_t timestamp = ktime_get();
+       u32 intr_status;
+
+       intr_status = lcdc_readl(lcdc_dev, INTR_STATUS);
+
+       if (intr_status & m_FS_INTR_STS) {
+               timestamp = ktime_get();
+               lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_FS_INTR_CLR,
+                            v_FS_INTR_CLR(1));
+               /*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));
+               }
+#ifdef CONFIG_DRM_ROCKCHIP
+               lcdc_dev->driver.irq_call_back(&lcdc_dev->driver);
+#endif
+               lcdc_dev->driver.vsync_info.timestamp = timestamp;
+               wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
+
+       } else if (intr_status & m_LINE_FLAG0_INTR_STS) {
+               lcdc_dev->driver.frame_time.last_framedone_t =
+                   lcdc_dev->driver.frame_time.framedone_t;
+               lcdc_dev->driver.frame_time.framedone_t = cpu_clock(0);
+               lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_LINE_FLAG0_INTR_CLR,
+                            v_LINE_FLAG0_INTR_CLR(1));
+       } else if (intr_status & m_LINE_FLAG1_INTR_STS) {
+               /*line flag1 */
+               lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_LINE_FLAG1_INTR_CLR,
+                            v_LINE_FLAG1_INTR_CLR(1));
+       } else if (intr_status & m_FS_NEW_INTR_STS) {
+               /*new frame start */
+               lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_FS_NEW_INTR_CLR,
+                            v_FS_NEW_INTR_CLR(1));
+       } else if (intr_status & m_BUS_ERROR_INTR_STS) {
+               lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_BUS_ERROR_INTR_CLR,
+                            v_BUS_ERROR_INTR_CLR(1));
+               dev_warn(lcdc_dev->dev, "bus error!");
+       }
+
+       /* for win empty debug */
+#ifdef LCDC_IRQ_EMPTY_DEBUG
+       rk3368_lcdc_parse_irq(lcdc_dev, intr_status);
+#endif
+       return IRQ_HANDLED;
+}
+
+#if defined(CONFIG_PM)
+static int rk3368_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       return 0;
+}
+
+static int rk3368_lcdc_resume(struct platform_device *pdev)
+{
+       return 0;
+}
+#else
+#define rk3368_lcdc_suspend NULL
+#define rk3368_lcdc_resume  NULL
+#endif
+
+static int rk3368_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
+{
+       struct device_node *np = lcdc_dev->dev->of_node;
+       struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver;
+       int val;
+
+       if (of_property_read_u32(np, "rockchip,prop", &val))
+               lcdc_dev->prop = PRMRY; /*default set it as primary */
+       else
+               lcdc_dev->prop = val;
+
+       if (of_property_read_u32(np, "rockchip,mirror", &val))
+               dev_drv->rotate_mode = NO_MIRROR;
+       else
+               dev_drv->rotate_mode = val;
+
+       if (of_property_read_u32(np, "rockchip,cabc_mode", &val))
+               dev_drv->cabc_mode = 0; /* default set close cabc */
+       else
+               dev_drv->cabc_mode = val;
+
+       if (of_property_read_u32(np, "rockchip,pwr18", &val))
+               /*default set it as 3.xv power supply */
+               lcdc_dev->pwr18 = false;
+       else
+               lcdc_dev->pwr18 = (val ? true : false);
+
+       if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
+               dev_drv->fb_win_map = FB_DEFAULT_ORDER;
+       else
+               dev_drv->fb_win_map = val;
+
+       if (of_property_read_u32(np, "rockchip,bcsh-en", &val))
+               dev_drv->bcsh.enable = false;
+       else
+               dev_drv->bcsh.enable = (val ? true : false);
+
+       if (of_property_read_u32(np, "rockchip,brightness", &val))
+               dev_drv->bcsh.brightness = 0xffff;
+       else
+               dev_drv->bcsh.brightness = val;
+
+       if (of_property_read_u32(np, "rockchip,contrast", &val))
+               dev_drv->bcsh.contrast = 0xffff;
+       else
+               dev_drv->bcsh.contrast = val;
+
+       if (of_property_read_u32(np, "rockchip,sat-con", &val))
+               dev_drv->bcsh.sat_con = 0xffff;
+       else
+               dev_drv->bcsh.sat_con = val;
+
+       if (of_property_read_u32(np, "rockchip,hue", &val)) {
+               dev_drv->bcsh.sin_hue = 0xffff;
+               dev_drv->bcsh.cos_hue = 0xffff;
+       } else {
+               dev_drv->bcsh.sin_hue = val & 0xff;
+               dev_drv->bcsh.cos_hue = (val >> 8) & 0xff;
+       }
+
+#if defined(CONFIG_ROCKCHIP_IOMMU)
+       if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
+               dev_drv->iommu_enabled = 0;
+       else
+               dev_drv->iommu_enabled = val;
+#else
+       dev_drv->iommu_enabled = 0;
+#endif
+       return 0;
+}
+
+static int rk3368_lcdc_probe(struct platform_device *pdev)
+{
+       struct lcdc_device *lcdc_dev = NULL;
+       struct rk_lcdc_driver *dev_drv;
+       struct device *dev = &pdev->dev;
+       struct resource *res;
+       struct device_node *np = pdev->dev.of_node;
+       int prop;
+       int ret = 0;
+
+       /*if the primary lcdc has not registered ,the extend
+          lcdc register later */
+       of_property_read_u32(np, "rockchip,prop", &prop);
+       if (prop == EXTEND) {
+               if (!is_prmry_rk_lcdc_registered())
+                       return -EPROBE_DEFER;
+       }
+       lcdc_dev = devm_kzalloc(dev, sizeof(struct lcdc_device), GFP_KERNEL);
+       if (!lcdc_dev) {
+               dev_err(&pdev->dev, "rk3368 lcdc device kmalloc fail!");
+               return -ENOMEM;
+       }
+       platform_set_drvdata(pdev, lcdc_dev);
+       lcdc_dev->dev = dev;
+       rk3368_lcdc_parse_dt(lcdc_dev);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       lcdc_dev->reg_phy_base = res->start;
+       lcdc_dev->len = resource_size(res);
+       lcdc_dev->regs = devm_ioremap_resource(dev, res);
+       if (IS_ERR(lcdc_dev->regs))
+               return PTR_ERR(lcdc_dev->regs);
+       else
+               dev_info(dev, "lcdc_dev->regs=0x%lx\n", (long)lcdc_dev->regs);
+
+       lcdc_dev->regsbak = devm_kzalloc(dev, lcdc_dev->len, GFP_KERNEL);
+       if (IS_ERR(lcdc_dev->regsbak))
+               return PTR_ERR(lcdc_dev->regsbak);
+       lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + GAMMA_LUT_ADDR);
+       lcdc_dev->id = 0;
+       dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
+       dev_drv = &lcdc_dev->driver;
+       dev_drv->dev = dev;
+       dev_drv->prop = prop;
+       dev_drv->id = lcdc_dev->id;
+       dev_drv->ops = &lcdc_drv_ops;
+       dev_drv->lcdc_win_num = ARRAY_SIZE(lcdc_win);
+       spin_lock_init(&lcdc_dev->reg_lock);
+
+       lcdc_dev->irq = platform_get_irq(pdev, 0);
+       if (lcdc_dev->irq < 0) {
+               dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
+                       lcdc_dev->id);
+               return -ENXIO;
+       }
+
+       ret = devm_request_irq(dev, lcdc_dev->irq, rk3368_lcdc_isr,
+                              IRQF_DISABLED | IRQF_SHARED,
+                              dev_name(dev), lcdc_dev);
+       if (ret) {
+               dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
+                       lcdc_dev->irq, ret);
+               return ret;
+       }
+
+       if (dev_drv->iommu_enabled) {
+               if (lcdc_dev->id == 0) {
+                       strcpy(dev_drv->mmu_dts_name,
+                              VOPB_IOMMU_COMPATIBLE_NAME);
+               } else {
+                       strcpy(dev_drv->mmu_dts_name,
+                              VOPL_IOMMU_COMPATIBLE_NAME);
+               }
+       }
+
+       ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
+       if (ret < 0) {
+               dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
+               return ret;
+       }
+       lcdc_dev->screen = dev_drv->screen0;
+       dev_info(dev, "lcdc%d probe ok, iommu %s\n",
+                lcdc_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
+
+       return 0;
+}
+
+static int rk3368_lcdc_remove(struct platform_device *pdev)
+{
+       return 0;
+}
+
+static void rk3368_lcdc_shutdown(struct platform_device *pdev)
+{
+       struct lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
+
+       rk3368_lcdc_deint(lcdc_dev);
+       rk_disp_pwr_disable(&lcdc_dev->driver);
+}
+
+#if defined(CONFIG_OF)
+static const struct of_device_id rk3368_lcdc_dt_ids[] = {
+       {.compatible = "rockchip,rk3368-lcdc",},
+       {}
+};
+#endif
+
+static struct platform_driver rk3368_lcdc_driver = {
+       .probe = rk3368_lcdc_probe,
+       .remove = rk3368_lcdc_remove,
+       .driver = {
+                  .name = "rk3368-lcdc",
+                  .owner = THIS_MODULE,
+                  .of_match_table = of_match_ptr(rk3368_lcdc_dt_ids),
+                  },
+       .suspend = rk3368_lcdc_suspend,
+       .resume = rk3368_lcdc_resume,
+       .shutdown = rk3368_lcdc_shutdown,
+};
+
+static int __init rk3368_lcdc_module_init(void)
+{
+       return platform_driver_register(&rk3368_lcdc_driver);
+}
+
+static void __exit rk3368_lcdc_module_exit(void)
+{
+       platform_driver_unregister(&rk3368_lcdc_driver);
+}
+
+fs_initcall(rk3368_lcdc_module_init);
+module_exit(rk3368_lcdc_module_exit);
diff --git a/drivers/video/rockchip/lcdc/rk3368_lcdc.h b/drivers/video/rockchip/lcdc/rk3368_lcdc.h
new file mode 100644 (file)
index 0000000..c9de882
--- /dev/null
@@ -0,0 +1,1980 @@
+#ifndef RK3368_LCDC_H_
+#define RK3368_LCDC_H_
+
+#include<linux/rk_fb.h>
+#include<linux/io.h>
+#include<linux/clk.h>
+
+#define VOP_INPUT_MAX_WIDTH 4096 /*3840 for LINCOLN*/
+
+#define REG_CFG_DONE                   (0x0000)
+#define VOP_CFG_DONE(x)                                (((x)&1)<<0)
+#define WIN0_CFG_DONE(x)                       (((x)&1)<<1)
+#define WIN1_CFG_DONE(x)                       (((x)&1)<<2)
+#define WIN2_CFG_DONE(x)                       (((x)&1)<<3)
+#define WIN3_CFG_DONE(x)                       (((x)&1)<<4)
+#define HWC_CFG_DONE(x)                                (((x)&1)<<5)
+#define IEP_CFG_DONE(x)                                (((x)&1)<<6)
+#define FBDC_CFG_DONE(x)                       (((x)&1)<<7)
+#define SYS_CFG_DONE(x)                                (((x)&1)<<8)
+
+#define VOP_CFG_DONE_WMSK(x)                   (((x)&1)<<(0+16))
+#define WIN0_CFG_DONE_WMSK(x)                  (((x)&1)<<(1+16))
+#define WIN1_CFG_DONE_WMSK(x)                  (((x)&1)<<(2+16))
+#define WIN2_CFG_DONE_WMSK(x)                  (((x)&1)<<(3+16))
+#define WIN3_CFG_DONE_WMSK(x)                  (((x)&1)<<(4+16))
+#define HWC_CFG_DONE_WMSK(x)                   (((x)&1)<<(5+16))
+#define IEP_CFG_DONE_WMSK(x)                   (((x)&1)<<(6+16))
+#define FBDC_CFG_DONE_WMSK(x)                  (((x)&1)<<(7+16))
+#define SYS_CFG_DONE_WMSK(x)                   (((x)&1)<<(8+16))
+
+#define VOP_REG_DONE           (VOP_CFG_DONE(1)  | VOP_CFG_DONE_WMSK(1))
+#define WIN0_REG_DONE          (WIN0_CFG_DONE(1) | WIN0_CFG_DONE_WMSK(1))
+#define WIN1_REG_DONE          (WIN1_CFG_DONE(1) | WIN1_CFG_DONE_WMSK(1))
+#define WIN2_REG_DONE          (WIN2_CFG_DONE(1) | WIN2_CFG_DONE_WMSK(1))
+#define WIN3_REG_DONE          (WIN3_CFG_DONE(1) | WIN3_CFG_DONE_WMSK(1))
+#define HWC_REG_DONE           (HWC_CFG_DONE(1)  | HWC_CFG_DONE_WMSK(1))
+#define IEP_REG_DONE           (IEP_CFG_DONE(1)  | IEP_CFG_DONE_WMSK(1))
+#define FBDC_REG_DONE          (FBDC_CFG_DONE(1) | FBDC_CFG_DONE_WMSK(1))
+#define SYS_REG_DONE           (SYS_CFG_DONE(1)  | SYS_CFG_DONE_WMSK(1))
+#define VERSION_INFO                   (0x0004)
+#define m_RTL_VERSION                  (0xffff<<0)
+#define m_FPGA_VERSION                 (0xffff<<16)
+#define SYS_CTRL                       (0x0008)
+#define v_DIRECT_PATH_EN(x)                    (((x)&1)<<0)
+#define v_DIRECT_PATCH_SEL(x)                  (((x)&3)<<1)
+#define v_DOUB_CHANNEL_EN(x)                   (((x)&1)<<3)
+#define v_DOUB_CH_OVERLAP_NUM(x)               (((x)&0xf)<<4)
+#define v_EDPI_HALT_EN(x)                      (((x)&1)<<8)
+#define v_EDPI_WMS_MODE(x)                     (((x)&1)<<9)
+#define v_EDPI_WMS_FS(x)                       (((x)&1)<<10)
+#define v_GLOBAL_REGDONE_EN(x)                 (((x)&1)<<11)
+#define v_RGB_OUT_EN(x)                                (((x)&1)<<12)
+#define v_HDMI_OUT_EN(x)                       (((x)&1)<<13)
+#define v_EDP_OUT_EN(x)                                (((x)&1)<<14)
+#define v_MIPI_OUT_EN(x)                       (((x)&1)<<15)
+#define v_OVERLAY_MODE(x)                      (((x)&1)<<16)
+#define v_FS_SAME_ADDR_MASK_EN(x)              (((x)&1)<<17)
+#define v_POST_LB_MODE(x)                      (((x)&1)<<18)
+#define v_WIN23_PRI_OPT_MODE(x)                        (((x)&1)<<19)
+#define v_MMU_EN(x)                            (((x)&1)<<20)
+#define v_DMA_STOP(x)                          (((x)&1)<<21)
+#define v_STANDBY_EN(x)                                (((x)&1)<<22)
+#define v_AUTO_GATING_EN(x)                    (((x)&1)<<23)
+
+#define m_DIRECT_PATH_EN                       (1<<0)
+#define m_DIRECT_PATCH_SEL                     (3<<1)
+#define m_DOUB_CHANNEL_EN                      (1<<3)
+#define m_DOUB_CH_OVERLAP_NUM                  (0xf<<4)
+#define m_EDPI_HALT_EN                         (1<<8)
+#define m_EDPI_WMS_MODE                                (1<<9)
+#define m_EDPI_WMS_FS                          (1<<10)
+#define m_GLOBAL_REGDONE_EN                    (1<<11)
+#define m_RGB_OUT_EN                           (1<<12)
+#define m_HDMI_OUT_EN                          (1<<13)
+#define m_EDP_OUT_EN                           (1<<14)
+#define m_MIPI_OUT_EN                          (1<<15)
+#define m_OVERLAY_MODE                         (1<<16)
+#define m_FS_SAME_ADDR_MASK_EN                 (1<<17)
+#define m_POST_LB_MODE                         (1<<18)
+#define m_WIN23_PRI_OPT_MODE                   (1<<19)
+#define m_MMU_EN                               (1<<20)
+#define m_DMA_STOP                             (1<<21)
+#define m_STANDBY_EN                           (1<<22)
+#define m_AUTO_GATING_EN                       (1<<23)
+
+#define SYS_CTRL1                      (0x000c)
+#define v_NOC_HURRY_EN(x)                      (((x)&0x1)<<0)
+#define v_NOC_HURRY_VALUE(x)                   (((x)&0x3)<<1)
+#define v_NOC_HURRY_THRESHOLD(x)               (((x)&0x3f)<<3)
+#define v_NOC_QOS_EN(x)                                (((x)&0x1)<<9)
+#define v_NOC_WIN_QOS(x)                       (((x)&0x3)<<10)
+#define v_AXI_MAX_OUTSTANDING_EN(x)            (((x)&0x1)<<12)
+#define v_AXI_OUTSTANDING_MAX_NUM(x)           (((x)&0x1f)<<13)
+
+#define m_NOC_HURRY_EN                         (0x1<<0)
+#define m_NOC_HURRY_VALUE                      (0x3<<1)
+#define m_NOC_HURRY_THRESHOLD                  (0x3f<<3)
+#define m_NOC_QOS_EN                           (0x1<<9)
+#define m_NOC_WIN_QOS                          (0x3<<10)
+#define m_AXI_MAX_OUTSTANDING_EN               (0x1<<12)
+#define m_AXI_OUTSTANDING_MAX_NUM              (0x1f<<13)
+
+#define DSP_CTRL0                      (0x0010)
+#define v_DSP_OUT_MODE(x)                      (((x)&0x0f)<<0)
+#define v_DSP_DCLK_DDR(x)                      (((x)&1)<<8)
+#define v_DSP_DDR_PHASE(x)                     (((x)&1)<<9)
+#define v_DSP_INTERLACE(x)                     (((x)&1)<<10)
+#define v_DSP_FIELD_POL(x)                     (((x)&1)<<11)
+#define v_DSP_BG_SWAP(x)                       (((x)&1)<<12)
+#define v_DSP_RB_SWAP(x)                       (((x)&1)<<13)
+#define v_DSP_RG_SWAP(x)                       (((x)&1)<<14)
+#define v_DSP_DELTA_SWAP(x)                    (((x)&1)<<15)
+#define v_DSP_DUMMY_SWAP(x)                    (((x)&1)<<16)
+#define v_DSP_OUT_ZERO(x)                      (((x)&1)<<17)
+#define v_DSP_BLANK_EN(x)                      (((x)&1)<<18)
+#define v_DSP_BLACK_EN(x)                      (((x)&1)<<19)
+#define v_DSP_CCIR656_AVG(x)                   (((x)&1)<<20)
+#define v_DSP_YUV_CLIP(x)                      (((x)&1)<<21)
+#define v_DSP_X_MIR_EN(x)                      (((x)&1)<<22)
+#define v_DSP_Y_MIR_EN(x)                      (((x)&1)<<23)
+#define m_DSP_OUT_MODE                         (0x0f<<0)
+#define m_DSP_DCLK_DDR                         (1<<8)
+#define m_DSP_DDR_PHASE                                (1<<9)
+#define m_DSP_INTERLACE                                (1<<10)
+#define m_DSP_FIELD_POL                                (1<<11)
+#define m_DSP_BG_SWAP                          (1<<12)
+#define m_DSP_RB_SWAP                          (1<<13)
+#define m_DSP_RG_SWAP                          (1<<14)
+#define m_DSP_DELTA_SWAP                       (1<<15)
+#define m_DSP_DUMMY_SWAP                       (1<<16)
+#define m_DSP_OUT_ZERO                         (1<<17)
+#define m_DSP_BLANK_EN                         (1<<18)
+#define m_DSP_BLACK_EN                         (1<<19)
+#define m_DSP_CCIR656_AVG                      (1<<20)
+#define m_DSP_YUV_CLIP                         (1<<21)
+#define m_DSP_X_MIR_EN                         (1<<22)
+#define m_DSP_Y_MIR_EN                         (1<<23)
+
+#define DSP_CTRL1                      (0x0014)
+#define v_DSP_LUT_EN(x)                                (((x)&1)<<0)
+#define v_PRE_DITHER_DOWN_EN(x)                        (((x)&1)<<1)
+#define v_DITHER_DOWN_EN(x)                    (((x)&1)<<2)
+#define v_DITHER_DOWN_MODE(x)                  (((x)&1)<<3)
+#define v_DITHER_DOWN_SEL(x)                   (((x)&1)<<4)
+#define v_DITHER_UP_EN(x)                      (((x)&1)<<6)
+#define v_DSP_LAYER0_SEL(x)                    (((x)&3)<<8)
+#define v_DSP_LAYER1_SEL(x)                    (((x)&3)<<10)
+#define v_DSP_LAYER2_SEL(x)                    (((x)&3)<<12)
+#define v_DSP_LAYER3_SEL(x)                    (((x)&3)<<14)
+
+#define v_RGB_LVDS_HSYNC_POL(x)                        (((x)&1)<<16)
+#define v_RGB_LVDS_VSYNC_POL(x)                        (((x)&1)<<17)
+#define v_RGB_LVDS_DEN_POL(x)                  (((x)&1)<<18)
+#define v_RGB_LVDS_DCLK_POL(x)                 (((x)&1)<<19)
+
+#define v_HDMI_HSYNC_POL(x)                    (((x)&1)<<20)
+#define v_HDMI_VSYNC_POL(x)                    (((x)&1)<<21)
+#define v_HDMI_DEN_POL(x)                      (((x)&1)<<22)
+#define v_HDMI_DCLK_POL(x)                     (((x)&1)<<23)
+
+#define v_EDP_HSYNC_POL(x)                     (((x)&1)<<24)
+#define v_EDP_VSYNC_POL(x)                     (((x)&1)<<25)
+#define v_EDP_DEN_POL(x)                       (((x)&1)<<26)
+#define v_EDP_DCLK_POL(x)                      (((x)&1)<<27)
+
+#define v_MIPI_HSYNC_POL(x)                    (((x)&1)<<28)
+#define v_MIPI_VSYNC_POL(x)                    (((x)&1)<<29)
+#define v_MIPI_DEN_POL(x)                      (((x)&1)<<30)
+#define v_MIPI_DCLK_POL(x)                     (((x)&1)<<31)
+
+#define m_DSP_LUT_EN                           (1<<0)
+#define m_PRE_DITHER_DOWN_EN                   (1<<1)
+#define m_DITHER_DOWN_EN                       (1<<2)
+#define m_DITHER_DOWN_MODE                     (1<<3)
+#define m_DITHER_DOWN_SEL                      (1<<4)
+#define m_DITHER_UP_EN                         (1<<6)
+#define m_DSP_LAYER0_SEL                       (3<<8)
+#define m_DSP_LAYER1_SEL                       (3<<10)
+#define m_DSP_LAYER2_SEL                       (3<<12)
+#define m_DSP_LAYER3_SEL                       (3<<14)
+
+#define m_RGB_LVDS_HSYNC_POL                   (1<<16)
+#define m_RGB_LVDS_VSYNC_POL                   (1<<17)
+#define m_RGB_LVDS_DEN_POL                     (1<<18)
+#define m_RGB_LVDS_DCLK_POL                    (1<<19)
+
+#define m_HDMI_HSYNC_POL                       (1<<20)
+#define m_HDMI_VSYNC_POL                       (1<<21)
+#define m_HDMI_DEN_POL                         (1<<22)
+#define m_HDMI_DCLK_POL                                (1<<23)
+
+#define m_EDP_HSYNC_POL                                (1<<24)
+#define m_EDP_VSYNC_POL                                (1<<25)
+#define m_EDP_DEN_POL                          (1<<26)
+#define m_EDP_DCLK_POL                         (1<<27)
+
+#define m_MIPI_HSYNC_POL                       (1<<28)
+#define m_MIPI_VSYNC_POL                       (1<<29)
+#define m_MIPI_DEN_POL                         (1<<30)
+#define m_MIPI_DCLK_POL                                (1<<31)
+
+#define DSP_BG                         (0x0018)
+#define v_DSP_BG_BLUE(x)                       (((x)&0xff) << 0)
+#define v_DSP_BG_GREEN(x)                      (((x)&0xff) << 8)
+#define v_DSP_BG_RED(x)                                (((x)&0xff) << 16)
+#define m_DSP_BG_BLUE                          (0xff << 0)
+#define m_DSP_BG_GREEN                         (0xff << 8)
+#define m_DSP_BG_RED                           (0xff << 16)
+
+#define MCU_CTRL                       (0x001c)
+#define v_MCU_PIX_TOTAL(x)                     (((x)&0x3f)<<0)
+#define v_MCU_CS_PST(x)                                (((x)&0xf)<<6)
+#define v_MCU_CS_PEND(x)                       (((x)&0x3f)<<10)
+#define v_MCU_RW_PST(x)                                (((x)&0xf)<<16)
+#define v_MCU_RW_PEND(x)                       (((x)&0x3f)<<20)
+#define v_MCU_CLK_SEL(x)                       (((x)&1)<<26)
+#define v_MCU_HOLD_MODE(x)                     (((x)&1)<<27)
+#define v_MCU_FRAME_ST(x)                      (((x)&1)<<28)
+#define v_MCU_RS(x)                            (((x)&1)<<29)
+#define v_MCU_BYPASS(x)                                (((x)&1)<<30)
+#define v_MCU_TYPE(x)                          (((x)&1)<<31)
+#define m_MCU_PIX_TOTAL                                (0x3f<<0)
+#define m_MCU_CS_PST                           (0xf<<6)
+#define m_MCU_CS_PEND                          (0x3f<<10)
+#define m_MCU_RW_PST                           (0xf<<16)
+#define m_MCU_RW_PEND                          (0x3f<<20)
+#define m_MCU_CLK_SEL                          (1<<26)
+#define m_MCU_HOLD_MODE                                (1<<27)
+#define m_MCU_FRAME_ST                         (1<<28)
+#define m_MCU_RS                               (1<<29)
+#define m_MCU_BYPASS                           (1<<30)
+#define m_MCU_TYPE                             ((u32)1<<31)
+
+#define LINE_FLAG                      (0x0020)
+#define m_DSP_LINE_FLAG0_NUM                   (0x1fff<<0)
+#define m_DSP_LINE_FLAG1_NUM                   (0x1fff<<16)
+#define v_DSP_LINE_FLAG0_NUM(x)                        (((x)&0x1fff)<<0)
+#define v_DSP_LINE_FLAG1_NUM(x)                        (((x)&0x1fff)<<16)
+
+#define INTR_EN                                (0x0024)
+#define v_FS_INTR_EN(x)                                ((((x)&1)<<0) | ((1<<(0+16))))
+#define v_FS_NEW_INTR_EN(x)                    ((((x)&1)<<1) | ((1<<(1+16))))
+#define v_ADDR_SAME_INTR_EN(x)                 ((((x)&1)<<2) | ((1<<(2+16))))
+#define v_LINE_FLAG0_INTR_EN(x)                        ((((x)&1)<<3) | ((1<<(3+16))))
+#define v_LINE_FLAG1_INTR_EN(x)                        ((((x)&1)<<4) | ((1<<(4+16))))
+#define v_BUS_ERROR_INTR_EN(x)                 ((((x)&1)<<5) | ((1<<(5+16))))
+#define v_WIN0_EMPTY_INTR_EN(x)                        ((((x)&1)<<6) | ((1<<(6+16))))
+#define v_WIN1_EMPTY_INTR_EN(x)                        ((((x)&1)<<7) | ((1<<(7+16))))
+#define v_WIN2_EMPTY_INTR_EN(x)                        ((((x)&1)<<8) | ((1<<(8+16))))
+#define v_WIN3_EMPTY_INTR_EN(x)                        ((((x)&1)<<9) | ((1<<(9+16))))
+#define v_HWC_EMPTY_INTR_EN(x)         ((((x)&1)<<10) | ((1<<(10+16))))
+#define v_POST_BUF_EMPTY_INTR_EN(x)    ((((x)&1)<<11) | ((1<<(11+16))))
+#define v_PWM_GEN_INTR_EN(x)           ((((x)&1)<<12) | ((1<<(12+16))))
+#define v_DSP_HOLD_VALID_INTR_EN(x)    ((((x)&1)<<13) | ((1<<(13+16))))
+
+#define m_FS_INTR_EN                           ((1<<0) | ((1<<(0+16))))
+#define m_FS_NEW_INTR_EN                       ((1<<1) | ((1<<(1+16))))
+#define m_ADDR_SAME_INTR_EN                    ((1<<2) | ((1<<(2+16))))
+#define m_LINE_FLAG0_INTR_EN                   ((1<<3) | ((1<<(3+16))))
+#define m_LINE_FLAG1_INTR_EN                   ((1<<4) | ((1<<(4+16))))
+#define m_BUS_ERROR_INTR_EN                    ((1<<5) | ((1<<(5+16))))
+#define m_WIN0_EMPTY_INTR_EN                   ((1<<6) | ((1<<(6+16))))
+#define m_WIN1_EMPTY_INTR_EN                   ((1<<7) | ((1<<(7+16))))
+#define m_WIN2_EMPTY_INTR_EN                   ((1<<8) | ((1<<(8+16))))
+#define m_WIN3_EMPTY_INTR_EN                   ((1<<9) | ((1<<(9+16))))
+#define m_HWC_EMPTY_INTR_EN                    ((1<<10) | ((1<<(10+16))))
+#define m_POST_BUF_EMPTY_INTR_EN               ((1<<11) | ((1<<(11+16))))
+#define m_PWM_GEN_INTR_EN                      ((1<<12) | ((1<<(12+16))))
+#define m_DSP_HOLD_VALID_INTR_EN               ((1<<13) | ((1<<(13+16))))
+
+#define  INTR_CLEAR                    (0x0028)
+#define v_FS_INTR_CLR(x)                       ((((x)&1)<<0) | (1<<(0+16)))
+#define v_FS_NEW_INTR_CLR(x)                   ((((x)&1)<<1) | (1<<(1+16)))
+#define v_ADDR_SAME_INTR_CLR(x)                        ((((x)&1)<<2) | (1<<(2+16)))
+#define v_LINE_FLAG0_INTR_CLR(x)               ((((x)&1)<<3) | (1<<(3+16)))
+#define v_LINE_FLAG1_INTR_CLR(x)               ((((x)&1)<<4) | (1<<(4+16)))
+#define v_BUS_ERROR_INTR_CLR(x)                        ((((x)&1)<<5) | (1<<(5+16)))
+#define v_WIN0_EMPTY_INTR_CLR(x)               ((((x)&1)<<6) | (1<<(6+16)))
+#define v_WIN1_EMPTY_INTR_CLR(x)               ((((x)&1)<<7) | (1<<(7+16)))
+#define v_WIN2_EMPTY_INTR_CLR(x)               ((((x)&1)<<8) | (1<<(8+16)))
+#define v_WIN3_EMPTY_INTR_CLR(x)               ((((x)&1)<<9) | (1<<(9+16)))
+#define v_HWC_EMPTY_INTR_CLR(x)                        ((((x)&1)<<10) | (1<<(10+16)))
+#define v_POST_BUF_EMPTY_INTR_CLR(x)           ((((x)&1)<<11) | (1<<(11+16)))
+#define v_PWM_GEN_INTR_CLR(x)                  ((((x)&1)<<12) | (1<<(12+16)))
+#define v_DSP_HOLD_VALID_INTR_CLR(x)           ((((x)&1)<<13) | (1<<(13+16)))
+
+#define m_FS_INTR_CLR                          ((1<<0) | ((1<<(0+16))))
+#define m_FS_NEW_INTR_CLR                      ((1<<1) | ((1<<(1+16))))
+#define m_ADDR_SAME_INTR_CLR                   ((1<<2) | ((1<<(2+16))))
+#define m_LINE_FLAG0_INTR_CLR                  ((1<<3) | ((1<<(3+16))))
+#define m_LINE_FLAG1_INTR_CLR                  ((1<<4) | ((1<<(4+16))))
+#define m_BUS_ERROR_INTR_CLR                   ((1<<5) | ((1<<(5+16))))
+#define m_WIN0_EMPTY_INTR_CLR                  ((1<<6) | ((1<<(5+16))))
+#define m_WIN1_EMPTY_INTR_CLR                  ((1<<7) | ((1<<(7+16))))
+#define m_WIN2_EMPTY_INTR_CLR                  ((1<<8) | ((1<<(8+16))))
+#define m_WIN3_EMPTY_INTR_CLR                  ((1<<9) | ((1<<(9+16))))
+#define m_HWC_EMPTY_INTR_CLR                   ((1<<10) | ((1<<(10+16))))
+#define m_POST_BUF_EMPTY_INTR_CLR              ((1<<11) | ((1<<(11+16))))
+#define m_PWM_GEN_INTR_CLR                     ((1<<12) | ((1<<(12+16))))
+#define m_DSP_HOLD_VALID_INTR_CLR              ((1<<13) | ((1<<(13+16))))
+
+#define  INTR_STATUS                   (0x002c)
+#define m_FS_INTR_STS                          (1<<0)
+#define m_FS_NEW_INTR_STS                      (1<<1)
+#define m_ADDR_SAME_INTR_STS                   (1<<2)
+#define m_LINE_FLAG0_INTR_STS                  (1<<3)
+#define m_LINE_FLAG1_INTR_STS                  (1<<4)
+#define m_BUS_ERROR_INTR_STS                   (1<<5)
+#define m_WIN0_EMPTY_INTR_STS                  (1<<6)
+#define m_WIN1_EMPTY_INTR_STS                  (1<<7)
+#define m_WIN2_EMPTY_INTR_STS                  (1<<8)
+#define m_WIN3_EMPTY_INTR_STS                  (1<<9)
+#define m_HWC_EMPTY_INTR_STS                   (1<<10)
+#define m_POST_BUF_EMPTY_INTR_STS              (1<<11)
+#define m_PWM_GEN_INTR_STS                     (1<<12)
+#define m_DSP_HOLD_VALID_INTR_STS              (1<<13)
+
+#define m_FS_INTR_RAWSTS                       (1<<(0+16))
+#define m_FS_NEW_INTR_RAWSTS                   (1<<(1+16))
+#define m_ADDR_SAME_INTR_RAWSTS                        (1<<(2+16))
+#define m_LINE_FLAG0_INTR_RAWSTS               (1<<(3+16))
+#define m_LINE_FLAG1_INTR_RAWSTS               (1<<(4+16))
+#define m_BUS_ERROR_INTR_RAWSTS                        (1<<(5+16))
+#define m_WIN0_EMPTY_INTR_RAWSTS               (1<<(6+16))
+#define m_WIN1_EMPTY_INTR_RAWSTS               (1<<(7+16))
+#define m_WIN2_EMPTY_INTR_RAWSTS               (1<<(8+16))
+#define m_WIN3_EMPTY_INTR_RAWSTS               (1<<(9+16))
+#define m_HWC_EMPTY_INTR_RAWSTS                        (1<<(10+16))
+#define m_POST_BUF_EMPTY_INTR_RAWSTS           (1<<(11+16))
+#define m_PWM_GEN_INTR_RAWSTS                  (1<<(12+16))
+#define m_DSP_HOLD_VALID_INTR_RAWSTS           (1<<(13+16))
+
+/*win0 register*/
+#define WIN0_CTRL0                     (0x0030)
+#define v_WIN0_EN(x)                           (((x)&1)<<0)
+#define v_WIN0_DATA_FMT(x)                     (((x)&7)<<1)
+#define v_WIN0_FMT_10(x)                       (((x)&1)<<4)
+#define v_WIN0_LB_MODE(x)                      (((x)&7)<<5)
+#define v_WIN0_INTERLACE_READ(x)               (((x)&1)<<8)
+#define v_WIN0_NO_OUTSTANDING(x)               (((x)&1)<<9)
+#define v_WIN0_CSC_MODE(x)                     (((x)&3)<<10)
+#define v_WIN0_RB_SWAP(x)                      (((x)&1)<<12)
+#define v_WIN0_ALPHA_SWAP(x)                   (((x)&1)<<13)
+#define v_WIN0_MID_SWAP(x)                     (((x)&1)<<14)
+#define v_WIN0_UV_SWAP(x)                      (((x)&1)<<15)
+#define v_WIN0_HW_PRE_MUL_EN(x)                        (((x)&1)<<16)
+#define v_WIN0_YRGB_DEFLICK(x)                 (((x)&1)<<18)
+#define v_WIN0_CBR_DEFLICK(x)                  (((x)&1)<<19)
+#define v_WIN0_YUV_CLIP(x)                     (((x)&1)<<20)
+#define v_WIN0_X_MIRROR(x)                     (((x)&1)<<21)
+#define v_WIN0_Y_MIRROR(x)                     (((x)&1)<<22)
+#define v_WIN0_AXI_MAX_OUTSTANDING_EN(x)       (((x)&1)<<24)
+#define v_WIN0_AXI_OUTSTANDING_MAX_NUM(x)      (((x)&0x1f)<<25)
+#define v_WIN0_DMA_BURST_LENGTH(x)             (((x)&0x3)<<30)
+
+#define m_WIN0_EN                              (1<<0)
+#define m_WIN0_DATA_FMT                                (7<<1)
+#define m_WIN0_FMT_10                          (1<<4)
+#define m_WIN0_LB_MODE                         (7<<5)
+#define m_WIN0_INTERLACE_READ                  (1<<8)
+#define m_WIN0_NO_OUTSTANDING                  (1<<9)
+#define m_WIN0_CSC_MODE                                (3<<10)
+#define m_WIN0_RB_SWAP                         (1<<12)
+#define m_WIN0_ALPHA_SWAP                      (1<<13)
+#define m_WIN0_MID_SWAP                                (1<<14)
+#define m_WIN0_UV_SWAP                         (1<<15)
+#define m_WIN0_HW_PRE_MUL_EN                   (1<<16)
+#define m_WIN0_YRGB_DEFLICK                    (1<<18)
+#define m_WIN0_CBR_DEFLICK                     (1<<19)
+#define m_WIN0_YUV_CLIP                                (1<<20)
+#define m_WIN0_X_MIRROR                                (1<<21)
+#define m_WIN0_Y_MIRROR                                (1<<22)
+#define m_WIN0_AXI_MAX_OUTSTANDING_EN          (1<<24)
+#define m_WIN0_AXI_OUTSTANDING_MAX_NUM         (0x1f<<25)
+#define m_WIN0_DMA_BURST_LENGTH                        (0x3<<30)
+
+#define WIN0_CTRL1                     (0x0034)
+#define v_WIN0_YRGB_AXI_GATHER_EN(x)           (((x)&1)<<0)
+#define v_WIN0_CBR_AXI_GATHER_EN(x)            (((x)&1)<<1)
+#define v_WIN0_BIC_COE_SEL(x)                  (((x)&3)<<2)
+#define v_WIN0_VSD_YRGB_GT4(x)                 (((x)&1)<<4)
+#define v_WIN0_VSD_YRGB_GT2(x)                 (((x)&1)<<5)
+#define v_WIN0_VSD_CBR_GT4(x)                  (((x)&1)<<6)
+#define v_WIN0_VSD_CBR_GT2(x)                  (((x)&1)<<7)
+#define v_WIN0_YRGB_AXI_GATHER_NUM(x)          (((x)&0xf)<<8)
+#define v_WIN0_CBR_AXI_GATHER_NUM(x)           (((x)&7)<<12)
+#define v_WIN0_LINE_LOAD_MODE(x)               (((x)&1)<<15)
+#define v_WIN0_YRGB_HOR_SCL_MODE(x)            (((x)&3)<<16)
+#define v_WIN0_YRGB_VER_SCL_MODE(x)            (((x)&3)<<18)
+#define v_WIN0_YRGB_HSD_MODE(x)                        (((x)&3)<<20)
+#define v_WIN0_YRGB_VSU_MODE(x)                        (((x)&1)<<22)
+#define v_WIN0_YRGB_VSD_MODE(x)                        (((x)&1)<<23)
+#define v_WIN0_CBR_HOR_SCL_MODE(x)             (((x)&3)<<24)
+#define v_WIN0_CBR_VER_SCL_MODE(x)             (((x)&3)<<26)
+#define v_WIN0_CBR_HSD_MODE(x)                 (((x)&3)<<28)
+#define v_WIN0_CBR_VSU_MODE(x)                 (((x)&1)<<30)
+#define v_WIN0_CBR_VSD_MODE(x)                 (((x)&1)<<31)
+
+#define m_WIN0_YRGB_AXI_GATHER_EN              (1<<0)
+#define m_WIN0_CBR_AXI_GATHER_EN               (1<<1)
+#define m_WIN0_BIC_COE_SEL                     (3<<2)
+#define m_WIN0_VSD_YRGB_GT4                    (1<<4)
+#define m_WIN0_VSD_YRGB_GT2                    (1<<5)
+#define m_WIN0_VSD_CBR_GT4                     (1<<6)
+#define m_WIN0_VSD_CBR_GT2                     (1<<7)
+#define m_WIN0_YRGB_AXI_GATHER_NUM             (0xf<<8)
+#define m_WIN0_CBR_AXI_GATHER_NUM              (7<<12)
+#define m_WIN0_LINE_LOAD_MODE                  (1<<15)
+#define m_WIN0_YRGB_HOR_SCL_MODE               (3<<16)
+#define m_WIN0_YRGB_VER_SCL_MODE               (3<<18)
+#define m_WIN0_YRGB_HSD_MODE                   (3<<20)
+#define m_WIN0_YRGB_VSU_MODE                   (1<<22)
+#define m_WIN0_YRGB_VSD_MODE                   (1<<23)
+#define m_WIN0_CBR_HOR_SCL_MODE                        (3<<24)
+#define m_WIN0_CBR_VER_SCL_MODE                        (3<<26)
+#define m_WIN0_CBR_HSD_MODE                    (3<<28)
+#define m_WIN0_CBR_VSU_MODE                    ((u32)1<<30)
+#define m_WIN0_CBR_VSD_MODE                    ((u32)1<<31)
+
+#define WIN0_COLOR_KEY                 (0x0038)
+#define v_WIN0_COLOR_KEY(x)                    (((x)&0x3fffffff)<<0)
+#define v_WIN0_COLOR_KEY_EN(x)                 (((x)&1)<<31)
+#define m_WIN0_COLOR_KEY                       (0x3fffffff<<0)
+#define m_WIN0_COLOR_KEY_EN                    ((u32)1<<31)
+
+#define WIN0_VIR                       (0x003c)
+#define v_WIN0_VIR_STRIDE(x)                   (((x)&0xffff)<<0)
+#define v_WIN0_VIR_STRIDE_UV(x)                        (((x)&0xffff)<<16)
+#define m_WIN0_VIR_STRIDE                      (0xffff<<0)
+#define m_WIN0_VIR_STRIDE_UV                   (0xffff<<16)
+
+#define WIN0_YRGB_MST                  (0x0040)
+#define WIN0_CBR_MST                   (0x0044)
+#define WIN0_ACT_INFO                  (0x0048)
+#define v_WIN0_ACT_WIDTH(x)                    (((x-1)&0x1fff)<<0)
+#define v_WIN0_ACT_HEIGHT(x)                   (((x-1)&0x1fff)<<16)
+#define m_WIN0_ACT_WIDTH                       (0x1fff<<0)
+#define m_WIN0_ACT_HEIGHT                      (0x1fff<<16)
+
+#define WIN0_DSP_INFO                  (0x004c)
+#define v_WIN0_DSP_WIDTH(x)                    (((x-1)&0xfff)<<0)
+#define v_WIN0_DSP_HEIGHT(x)                   (((x-1)&0xfff)<<16)
+#define m_WIN0_DSP_WIDTH                       (0xfff<<0)
+#define m_WIN0_DSP_HEIGHT                      (0xfff<<16)
+
+#define WIN0_DSP_ST                    (0x0050)
+#define v_WIN0_DSP_XST(x)                      (((x)&0x1fff)<<0)
+#define v_WIN0_DSP_YST(x)                      (((x)&0x1fff)<<16)
+#define m_WIN0_DSP_XST                         (0x1fff<<0)
+#define m_WIN0_DSP_YST                         (0x1fff<<16)
+
+#define WIN0_SCL_FACTOR_YRGB           (0x0054)
+#define v_WIN0_HS_FACTOR_YRGB(x)               (((x)&0xffff)<<0)
+#define v_WIN0_VS_FACTOR_YRGB(x)               (((x)&0xffff)<<16)
+#define m_WIN0_HS_FACTOR_YRGB                  (0xffff<<0)
+#define m_WIN0_VS_FACTOR_YRGB                  ((u32)0xffff<<16)
+
+#define WIN0_SCL_FACTOR_CBR            (0x0058)
+#define v_WIN0_HS_FACTOR_CBR(x)                        (((x)&0xffff)<<0)
+#define v_WIN0_VS_FACTOR_CBR(x)                        (((x)&0xffff)<<16)
+#define m_WIN0_HS_FACTOR_CBR                   (0xffff<<0)
+#define m_WIN0_VS_FACTOR_CBR                   ((u32)0xffff<<16)
+
+#define WIN0_SCL_OFFSET                        (0x005c)
+#define v_WIN0_HS_OFFSET_YRGB(x)               (((x)&0xff)<<0)
+#define v_WIN0_HS_OFFSET_CBR(x)                        (((x)&0xff)<<8)
+#define v_WIN0_VS_OFFSET_YRGB(x)               (((x)&0xff)<<16)
+#define v_WIN0_VS_OFFSET_CBR(x)                        (((x)&0xff)<<24)
+
+#define m_WIN0_HS_OFFSET_YRGB                  (0xff<<0)
+#define m_WIN0_HS_OFFSET_CBR                   (0xff<<8)
+#define m_WIN0_VS_OFFSET_YRGB                  (0xff<<16)
+#define m_WIN0_VS_OFFSET_CBR                   ((u32)0xff<<24)
+
+#define WIN0_SRC_ALPHA_CTRL            (0x0060)
+#define v_WIN0_SRC_ALPHA_EN(x)                 (((x)&1)<<0)
+#define v_WIN0_SRC_COLOR_M0(x)                 (((x)&1)<<1)
+#define v_WIN0_SRC_ALPHA_M0(x)                 (((x)&1)<<2)
+#define v_WIN0_SRC_BLEND_M0(x)                 (((x)&3)<<3)
+#define v_WIN0_SRC_ALPHA_CAL_M0(x)             (((x)&1)<<5)
+#define v_WIN0_SRC_FACTOR_M0(x)                        (((x)&7)<<6)
+#define v_WIN0_SRC_GLOBAL_ALPHA(x)             (((x)&0xff)<<16)
+#define v_WIN0_FADING_VALUE(x)                 (((x)&0xff)<<24)
+
+#define m_WIN0_SRC_ALPHA_EN                    (1<<0)
+#define m_WIN0_SRC_COLOR_M0                    (1<<1)
+#define m_WIN0_SRC_ALPHA_M0                    (1<<2)
+#define m_WIN0_SRC_BLEND_M0                    (3<<3)
+#define m_WIN0_SRC_ALPHA_CAL_M0                        (1<<5)
+#define m_WIN0_SRC_FACTOR_M0                   (7<<6)
+#define m_WIN0_SRC_GLOBAL_ALPHA                        (0xff<<16)
+#define m_WIN0_FADING_VALUE                    (0xff<<24)
+
+#define WIN0_DST_ALPHA_CTRL            (0x0064)
+#define v_WIN0_DST_FACTOR_M0(x)                        (((x)&7)<<6)
+#define m_WIN0_DST_FACTOR_M0                   (7<<6)
+
+#define WIN0_FADING_CTRL               (0x0068)
+#define v_WIN0_FADING_OFFSET_R(x)              (((x)&0xff)<<0)
+#define v_WIN0_FADING_OFFSET_G(x)              (((x)&0xff)<<8)
+#define v_WIN0_FADING_OFFSET_B(x)              (((x)&0xff)<<16)
+#define v_WIN0_FADING_EN(x)                    (((x)&1)<<24)
+
+#define m_WIN0_FADING_OFFSET_R                 (0xff<<0)
+#define m_WIN0_FADING_OFFSET_G                 (0xff<<8)
+#define m_WIN0_FADING_OFFSET_B                 (0xff<<16)
+#define m_WIN0_FADING_EN                       (1<<24)
+
+#define WIN0_CTRL2                     (0x006c)
+#define v_WIN_RID_WIN0_YRGB(x)                 (((x)&0xf)<<0)
+#define v_WIN_RID_WIN0_CBR(x)                  (((x)&0xf)<<4)
+#define m_WIN_RID_WIN0_YRGB                    ((0xf)<<0)
+#define m_WIN_RID_WIN0_CBR                     ((0xf)<<4)
+/*win1 register*/
+#define WIN1_CTRL0                     (0x0070)
+#define v_WIN1_EN(x)                           (((x)&1)<<0)
+#define v_WIN1_DATA_FMT(x)                     (((x)&7)<<1)
+#define v_WIN1_FMT_10(x)                       (((x)&1)<<4)
+#define v_WIN1_LB_MODE(x)                      (((x)&7)<<5)
+#define v_WIN1_INTERLACE_READ(x)               (((x)&1)<<8)
+#define v_WIN1_NO_OUTSTANDING(x)               (((x)&1)<<9)
+#define v_WIN1_CSC_MODE(x)                     (((x)&3)<<10)
+#define v_WIN1_RB_SWAP(x)                      (((x)&1)<<12)
+#define v_WIN1_ALPHA_SWAP(x)                   (((x)&1)<<13)
+#define v_WIN1_MID_SWAP(x)                     (((x)&1)<<14)
+#define v_WIN1_UV_SWAP(x)                      (((x)&1)<<15)
+#define v_WIN1_HW_PRE_MUL_EN(x)                        (((x)&1)<<16)
+#define v_WIN1_YRGB_DEFLICK(x)                 (((x)&1)<<18)
+#define v_WIN1_CBR_DEFLICK(x)                  (((x)&1)<<19)
+#define v_WIN1_YUV_CLIP(x)                     (((x)&1)<<20)
+#define v_WIN1_X_MIRROR(x)                     (((x)&1)<<21)
+#define v_WIN1_Y_MIRROR(x)                     (((x)&1)<<22)
+#define v_WIN1_AXI_MAX_OUTSTANDING_EN(x)       (((x)&1)<<24)
+#define v_WIN1_AXI_OUTSTANDING_MAX_NUM(x)      (((x)&0x1f)<<25)
+#define v_WIN1_DMA_BURST_LENGTH(x)             (((x)&0x3)<<30)
+#define m_WIN1_EN                              (1<<0)
+#define m_WIN1_DATA_FMT                                (7<<1)
+#define m_WIN1_FMT_10                          (1<<4)
+#define m_WIN1_LB_MODE                         (7<<5)
+#define m_WIN1_INTERLACE_READ                  (1<<8)
+#define m_WIN1_NO_OUTSTANDING                  (1<<9)
+#define m_WIN1_CSC_MODE                                (3<<10)
+#define m_WIN1_RB_SWAP                         (1<<12)
+#define m_WIN1_ALPHA_SWAP                      (1<<13)
+#define m_WIN1_MID_SWAP                                (1<<14)
+#define m_WIN1_UV_SWAP                         (1<<15)
+#define m_WIN1_HW_PRE_MUL_EN                   (1<<16)
+#define m_WIN1_YRGB_DEFLICK                    (1<<18)
+#define m_WIN1_CBR_DEFLICK                     (1<<19)
+#define m_WIN1_YUV_CLIP                                (1<<20)
+#define m_WIN1_X_MIRROR                                (1<<21)
+#define m_WIN1_Y_MIRROR                                (1<<22)
+#define m_WIN1_AXI_MAX_OUTSTANDING_EN          (1<<24)
+#define m_WIN1_AXI_OUTSTANDING_MAX_NUM         (0x1f<<25)
+#define m_WIN1_DMA_BURST_LENGTH                        (0x3<<30)
+
+#define WIN1_CTRL1                     (0x0074)
+#define v_WIN1_YRGB_AXI_GATHER_EN(x)           (((x)&1)<<0)
+#define v_WIN1_CBR_AXI_GATHER_EN(x)            (((x)&1)<<1)
+#define v_WIN1_BIC_COE_SEL(x)                  (((x)&3)<<2)
+#define v_WIN1_VSD_YRGB_GT4(x)                 (((x)&1)<<4)
+#define v_WIN1_VSD_YRGB_GT2(x)                 (((x)&1)<<5)
+#define v_WIN1_VSD_CBR_GT4(x)                  (((x)&1)<<6)
+#define v_WIN1_VSD_CBR_GT2(x)                  (((x)&1)<<7)
+#define v_WIN1_YRGB_AXI_GATHER_NUM(x)          (((x)&0xf)<<8)
+#define v_WIN1_CBR_AXI_GATHER_NUM(x)           (((x)&7)<<12)
+#define v_WIN1_LINE_LOAD_MODE(x)               (((x)&1)<<15)
+#define v_WIN1_YRGB_HOR_SCL_MODE(x)            (((x)&3)<<16)
+#define v_WIN1_YRGB_VER_SCL_MODE(x)            (((x)&3)<<18)
+#define v_WIN1_YRGB_HSD_MODE(x)                        (((x)&3)<<20)
+#define v_WIN1_YRGB_VSU_MODE(x)                        (((x)&1)<<22)
+#define v_WIN1_YRGB_VSD_MODE(x)                        (((x)&1)<<23)
+#define v_WIN1_CBR_HOR_SCL_MODE(x)             (((x)&3)<<24)
+#define v_WIN1_CBR_VER_SCL_MODE(x)             (((x)&3)<<26)
+#define v_WIN1_CBR_HSD_MODE(x)                 (((x)&3)<<28)
+#define v_WIN1_CBR_VSU_MODE(x)                 (((x)&1)<<30)
+#define v_WIN1_CBR_VSD_MODE(x)                 (((x)&1)<<31)
+
+#define m_WIN1_YRGB_AXI_GATHER_EN              (1<<0)
+#define m_WIN1_CBR_AXI_GATHER_EN               (1<<1)
+#define m_WIN1_BIC_COE_SEL                     (3<<2)
+#define m_WIN1_VSD_YRGB_GT4                    (1<<4)
+#define m_WIN1_VSD_YRGB_GT2                    (1<<5)
+#define m_WIN1_VSD_CBR_GT4                     (1<<6)
+#define m_WIN1_VSD_CBR_GT2                     (1<<7)
+#define m_WIN1_YRGB_AXI_GATHER_NUM             (0xf<<8)
+#define m_WIN1_CBR_AXI_GATHER_NUM              (7<<12)
+#define m_WIN1_LINE_LOAD_MODE                  (1<<15)
+#define m_WIN1_YRGB_HOR_SCL_MODE               (3<<16)
+#define m_WIN1_YRGB_VER_SCL_MODE               (3<<18)
+#define m_WIN1_YRGB_HSD_MODE                   (3<<20)
+#define m_WIN1_YRGB_VSU_MODE                   (1<<22)
+#define m_WIN1_YRGB_VSD_MODE                   (1<<23)
+#define m_WIN1_CBR_HOR_SCL_MODE                        (3<<24)
+#define m_WIN1_CBR_VER_SCL_MODE                        (3<<26)
+#define m_WIN1_CBR_HSD_MODE                    (3<<28)
+#define m_WIN1_CBR_VSU_MODE                    (1<<30)
+#define m_WIN1_CBR_VSD_MODE                    ((u32)1<<31)
+
+#define WIN1_COLOR_KEY                 (0x0078)
+#define v_WIN1_COLOR_KEY(x)                    (((x)&0x3fffffff)<<0)
+#define v_WIN1_COLOR_KEY_EN(x)                 (((x)&1)<<31)
+#define m_WIN1_COLOR_KEY                       (0x3fffffff<<0)
+#define m_WIN1_COLOR_KEY_EN                    ((u32)1<<31)
+
+#define WIN1_VIR                       (0x007c)
+#define v_WIN1_VIR_STRIDE(x)                   (((x)&0xffff)<<0)
+#define v_WIN1_VIR_STRIDE_UV(x)                        (((x)&0xffff)<<16)
+#define m_WIN1_VIR_STRIDE                      (0xffff<<0)
+#define m_WIN1_VIR_STRIDE_UV                   (0xffff<<16)
+
+#define WIN1_YRGB_MST                  (0x0080)
+#define WIN1_CBR_MST                   (0x0084)
+#define WIN1_ACT_INFO                  (0x0088)
+#define v_WIN1_ACT_WIDTH(x)                    (((x-1)&0x1fff)<<0)
+#define v_WIN1_ACT_HEIGHT(x)                   (((x-1)&0x1fff)<<16)
+#define m_WIN1_ACT_WIDTH                       (0x1fff<<0)
+#define m_WIN1_ACT_HEIGHT                      (0x1fff<<16)
+
+#define WIN1_DSP_INFO                  (0x008c)
+#define v_WIN1_DSP_WIDTH(x)                    (((x-1)&0xfff)<<0)
+#define v_WIN1_DSP_HEIGHT(x)                   (((x-1)&0xfff)<<16)
+#define m_WIN1_DSP_WIDTH                       (0xfff<<0)
+#define m_WIN1_DSP_HEIGHT                      (0xfff<<16)
+
+#define WIN1_DSP_ST                    (0x0090)
+#define v_WIN1_DSP_XST(x)                      (((x)&0x1fff)<<0)
+#define v_WIN1_DSP_YST(x)                      (((x)&0x1fff)<<16)
+#define m_WIN1_DSP_XST                         (0x1fff<<0)
+#define m_WIN1_DSP_YST                         (0x1fff<<16)
+
+#define WIN1_SCL_FACTOR_YRGB           (0x0094)
+#define v_WIN1_HS_FACTOR_YRGB(x)               (((x)&0xffff)<<0)
+#define v_WIN1_VS_FACTOR_YRGB(x)               (((x)&0xffff)<<16)
+#define m_WIN1_HS_FACTOR_YRGB                  (0xffff<<0)
+#define m_WIN1_VS_FACTOR_YRGB                  ((u32)0xffff<<16)
+
+#define WIN1_SCL_FACTOR_CBR            (0x0098)
+#define v_WIN1_HS_FACTOR_CBR(x)                        (((x)&0xffff)<<0)
+#define v_WIN1_VS_FACTOR_CBR(x)                        (((x)&0xffff)<<16)
+#define m_WIN1_HS_FACTOR_CBR                   (0xffff<<0)
+#define m_WIN1_VS_FACTOR_CBR                   ((u32)0xffff<<16)
+
+#define WIN1_SCL_OFFSET                        (0x009c)
+#define v_WIN1_HS_OFFSET_YRGB(x)               (((x)&0xff)<<0)
+#define v_WIN1_HS_OFFSET_CBR(x)                        (((x)&0xff)<<8)
+#define v_WIN1_VS_OFFSET_YRGB(x)               (((x)&0xff)<<16)
+#define v_WIN1_VS_OFFSET_CBR(x)                        (((x)&0xff)<<24)
+
+#define m_WIN1_HS_OFFSET_YRGB                  (0xff<<0)
+#define m_WIN1_HS_OFFSET_CBR                   (0xff<<8)
+#define m_WIN1_VS_OFFSET_YRGB                  (0xff<<16)
+#define m_WIN1_VS_OFFSET_CBR                   ((u32)0xff<<24)
+
+#define WIN1_SRC_ALPHA_CTRL            (0x00a0)
+#define v_WIN1_SRC_ALPHA_EN(x)                 (((x)&1)<<0)
+#define v_WIN1_SRC_COLOR_M0(x)                 (((x)&1)<<1)
+#define v_WIN1_SRC_ALPHA_M0(x)                 (((x)&1)<<2)
+#define v_WIN1_SRC_BLEND_M0(x)                 (((x)&3)<<3)
+#define v_WIN1_SRC_ALPHA_CAL_M0(x)             (((x)&1)<<5)
+#define v_WIN1_SRC_FACTOR_M0(x)                        (((x)&7)<<6)
+#define v_WIN1_SRC_GLOBAL_ALPHA(x)             (((x)&0xff)<<16)
+#define v_WIN1_FADING_VALUE(x)                 (((x)&0xff)<<24)
+
+#define m_WIN1_SRC_ALPHA_EN                    (1<<0)
+#define m_WIN1_SRC_COLOR_M0                    (1<<1)
+#define m_WIN1_SRC_ALPHA_M0                    (1<<2)
+#define m_WIN1_SRC_BLEND_M0                    (3<<3)
+#define m_WIN1_SRC_ALPHA_CAL_M0                        (1<<5)
+#define m_WIN1_SRC_FACTOR_M0                   (7<<6)
+#define m_WIN1_SRC_GLOBAL_ALPHA                        (0xff<<16)
+#define m_WIN1_FADING_VALUE                    (0xff<<24)
+
+#define WIN1_DST_ALPHA_CTRL                    (0x00a4)
+#define v_WIN1_DST_FACTOR_M0(x)                        (((x)&7)<<6)
+#define m_WIN1_DST_FACTOR_M0                   (7<<6)
+
+#define WIN1_FADING_CTRL               (0x00a8)
+#define v_WIN1_FADING_OFFSET_R(x)              (((x)&0xff)<<0)
+#define v_WIN1_FADING_OFFSET_G(x)              (((x)&0xff)<<8)
+#define v_WIN1_FADING_OFFSET_B(x)              (((x)&0xff)<<16)
+#define v_WIN1_FADING_EN(x)                    (((x)&1)<<24)
+
+#define m_WIN1_FADING_OFFSET_R                 (0xff<<0)
+#define m_WIN1_FADING_OFFSET_G                 (0xff<<8)
+#define m_WIN1_FADING_OFFSET_B                 (0xff<<16)
+#define m_WIN1_FADING_EN                       (1<<24)
+
+#define WIN1_CTRL2                     (0xac)
+#define v_WIN_RID_WIN1_YRGB(x)                 (((x)&0xf)<<0)
+#define v_WIN_RID_WIN1_CBR(x)                  (((x)&0xf)<<4)
+#define m_WIN_RID_WIN1_YRGB                    ((0xf)<<0)
+#define m_WIN_RID_WIN1_CBR                     ((0xf)<<4)
+/*win2 register*/
+#define WIN2_CTRL0                     (0x00b0)
+#define v_WIN2_EN(x)                           (((x)&1)<<0)
+#define v_WIN2_INTERLACE_READ(x)               (((x)&1)<<1)
+#define v_WIN2_CSC_MODE(x)                     (((x)&1)<<2)
+#define v_WIN2_MST0_EN(x)                      (((x)&1)<<4)
+#define v_WIN2_DATA_FMT0(x)                    (((x)&3)<<5)
+#define v_WIN2_MST1_EN(x)                      (((x)&1)<<8)
+#define v_WIN2_DATA_FMT1(x)                    (((x)&3)<<9)
+#define v_WIN2_MST2_EN(x)                      (((x)&1)<<12)
+#define v_WIN2_DATA_FMT2(x)                    (((x)&3)<<13)
+#define v_WIN2_MST3_EN(x)                      (((x)&1)<<16)
+#define v_WIN2_DATA_FMT3(x)                    (((x)&3)<<17)
+#define v_WIN2_RB_SWAP0(x)                     (((x)&1)<<20)
+#define v_WIN2_ALPHA_SWAP0(x)                  (((x)&1)<<21)
+#define v_WIN2_ENDIAN_SWAP0(x)                 (((x)&1)<<22)
+#define v_WIN2_RB_SWAP1(x)                     (((x)&1)<<23)
+#define v_WIN2_ALPHA_SWAP1(x)                  (((x)&1)<<24)
+#define v_WIN2_ENDIAN_SWAP1(x)                 (((x)&1)<<25)
+#define v_WIN2_RB_SWAP2(x)                     (((x)&1)<<26)
+#define v_WIN2_ALPHA_SWAP2(x)                  (((x)&1)<<27)
+#define v_WIN2_ENDIAN_SWAP2(x)                 (((x)&1)<<28)
+#define v_WIN2_RB_SWAP3(x)                     (((x)&1)<<29)
+#define v_WIN2_ALPHA_SWAP3(x)                  (((x)&1)<<30)
+#define v_WIN2_ENDIAN_SWAP3(x)                 (((x)&1)<<31)
+
+#define m_WIN2_EN                              (1<<0)
+#define m_WIN2_INTERLACE_READ                  (1<<1)
+#define m_WIN2_CSC_MODE                                (1<<2)
+#define m_WIN2_MST0_EN                         (1<<4)
+#define m_WIN2_DATA_FMT0                       (3<<5)
+#define m_WIN2_MST1_EN                         (1<<8)
+#define m_WIN2_DATA_FMT1                       (3<<9)
+#define m_WIN2_MST2_EN                         (1<<12)
+#define m_WIN2_DATA_FMT2                       (3<<13)
+#define m_WIN2_MST3_EN                         (1<<16)
+#define m_WIN2_DATA_FMT3                       (3<<17)
+#define m_WIN2_RB_SWAP0                                (1<<20)
+#define m_WIN2_ALPHA_SWAP0                     (1<<21)
+#define m_WIN2_ENDIAN_SWAP0                    (1<<22)
+#define m_WIN2_RB_SWAP1                                (1<<23)
+#define m_WIN2_ALPHA_SWAP1                     (1<<24)
+#define m_WIN2_ENDIAN_SWAP1                    (1<<25)
+#define m_WIN2_RB_SWAP2                                (1<<26)
+#define m_WIN2_ALPHA_SWAP2                     (1<<27)
+#define m_WIN2_ENDIAN_SWAP2                    (1<<28)
+#define m_WIN2_RB_SWAP3                                (1<<29)
+#define m_WIN2_ALPHA_SWAP3                     (1<<30)
+#define m_WIN2_ENDIAN_SWAP3                    (1<<31)
+
+#define WIN2_CTRL1                     (0x00b4)
+#define v_WIN2_AXI_GATHER_EN(x)                        (((x)&1)<<0)
+#define v_WIN2_AXI_MAX_OUTSTANDING_EN(x)       (((x)&1)<<1)
+#define v_WIN2_DMA_BURST_LENGTH(x)             (((x)&0x3)<<2)
+#define v_WIN2_AXI_GATHER_NUM(x)               (((x)&0xf)<<4)
+#define v_WIN2_AXI_OUTSTANDING_MAX_NUM(x)      (((x)&0x1f)<<8)
+#define v_WIN2_RGB2YUV_EN(x)                   (((x)&1)<<13)
+#define v_WIN2_NO_OUTSTANDING(x)               (((x)&1)<<14)
+#define v_WIN2_Y_MIR(x)                                (((x)&1)<<15)
+#define v_WIN2_LUT_EN(x)                       (((x)&1)<<16)
+#define v_WIN_RID_WIN2(x)                      (((x)&0xf)<<20)
+
+#define m_WIN2_AXI_GATHER_EN                   (1<<0)
+#define m_WIN2_AXI_MAX_OUTSTANDING_EN          (1<<1)
+#define m_WIN2_DMA_BURST_LENGTH                        (0x3<<2)
+#define m_WIN2_AXI_GATHER_NUM                  (0xf<<4)
+#define m_WIN2_AXI_OUTSTANDING_MAX_NUM         (0x1f<<8)
+#define m_WIN2_RGB2YUV_EN                      (1<<13)
+#define m_WIN2_NO_OUTSTANDING                  (1<<14)
+#define m_WIN2_Y_MIR                           (1<<15)
+#define m_WIN2_LUT_EN                          (1<<16)
+#define m_WIN_RID_WIN2                         (0xf<<20)
+
+#define WIN2_VIR0_1                    (0x00b8)
+#define v_WIN2_VIR_STRIDE0(x)                  (((x)&0xffff)<<0)
+#define v_WIN2_VIR_STRIDE1(x)                  (((x)&0xffff)<<16)
+#define m_WIN2_VIR_STRIDE0                     (((u32)0xffff)<<0)
+#define m_WIN2_VIR_STRIDE1                     (((u32)0xffff)<<16)
+
+#define WIN2_VIR2_3                    (0x00bc)
+#define v_WIN2_VIR_STRIDE2(x)                  (((x)&0xffff)<<0)
+#define v_WIN2_VIR_STRIDE3(x)                  (((x)&0xffff)<<16)
+#define m_WIN2_VIR_STRIDE2                     (((u32)0xffff)<<0)
+#define m_WIN2_VIR_STRIDE3                     (((u32)0xffff)<<16)
+
+#define WIN2_MST0                      (0x00c0)
+#define WIN2_DSP_INFO0                 (0x00c4)
+#define v_WIN2_DSP_WIDTH0(x)                   (((x-1)&0xfff)<<0)
+#define v_WIN2_DSP_HEIGHT0(x)                  (((x-1)&0xfff)<<16)
+#define m_WIN2_DSP_WIDTH0                      (0xfff<<0)
+#define m_WIN2_DSP_HEIGHT0                     (0xfff<<16)
+
+#define WIN2_DSP_ST0                   (0x00c8)
+#define v_WIN2_DSP_XST0(x)                     (((x)&0x1fff)<<0)
+#define v_WIN2_DSP_YST0(x)                     (((x)&0x1fff)<<16)
+#define m_WIN2_DSP_XST0                                (0x1fff<<0)
+#define m_WIN2_DSP_YST0                                (0x1fff<<16)
+
+#define WIN2_COLOR_KEY                 (0x00cc)
+#define v_WIN2_COLOR_KEY(x)                    (((x)&0xffffff)<<0)
+#define v_WIN2_KEY_EN(x)                       (((x)&1)<<24)
+#define m_WIN2_COLOR_KEY                       (0xffffff<<0)
+#define m_WIN2_KEY_EN                          ((u32)1<<24)
+
+
+#define WIN2_MST1                      (0x00d0)
+#define WIN2_DSP_INFO1                 (0x00d4)
+#define v_WIN2_DSP_WIDTH1(x)                   (((x-1)&0xfff)<<0)
+#define v_WIN2_DSP_HEIGHT1(x)                  (((x-1)&0xfff)<<16)
+
+#define m_WIN2_DSP_WIDTH1                      (0xfff<<0)
+#define m_WIN2_DSP_HEIGHT1                     (0xfff<<16)
+
+#define WIN2_DSP_ST1                   (0x00d8)
+#define v_WIN2_DSP_XST1(x)                     (((x)&0x1fff)<<0)
+#define v_WIN2_DSP_YST1(x)                     (((x)&0x1fff)<<16)
+#define m_WIN2_DSP_XST1                                (0x1fff<<0)
+#define m_WIN2_DSP_YST1                                (0x1fff<<16)
+
+#define WIN2_SRC_ALPHA_CTRL            (0x00dc)
+#define v_WIN2_SRC_ALPHA_EN(x)                 (((x)&1)<<0)
+#define v_WIN2_SRC_COLOR_M0(x)                 (((x)&1)<<1)
+#define v_WIN2_SRC_ALPHA_M0(x)                 (((x)&1)<<2)
+#define v_WIN2_SRC_BLEND_M0(x)                 (((x)&3)<<3)
+#define v_WIN2_SRC_ALPHA_CAL_M0(x)             (((x)&1)<<5)
+#define v_WIN2_SRC_FACTOR_M0(x)                        (((x)&7)<<6)
+#define v_WIN2_SRC_GLOBAL_ALPHA(x)             (((x)&0xff)<<16)
+#define v_WIN2_FADING_VALUE(x)                 (((x)&0xff)<<24)
+#define m_WIN2_SRC_ALPHA_EN                    (1<<0)
+#define m_WIN2_SRC_COLOR_M0                    (1<<1)
+#define m_WIN2_SRC_ALPHA_M0                    (1<<2)
+#define m_WIN2_SRC_BLEND_M0                    (3<<3)
+#define m_WIN2_SRC_ALPHA_CAL_M0                        (1<<5)
+#define m_WIN2_SRC_FACTOR_M0                   (7<<6)
+#define m_WIN2_SRC_GLOBAL_ALPHA                        (0xff<<16)
+#define m_WIN2_FADING_VALUE                    (0xff<<24)
+
+#define WIN2_MST2                      (0x00e0)
+#define WIN2_DSP_INFO2                 (0x00e4)
+#define v_WIN2_DSP_WIDTH2(x)                   (((x-1)&0xfff)<<0)
+#define v_WIN2_DSP_HEIGHT2(x)                  (((x-1)&0xfff)<<16)
+#define m_WIN2_DSP_WIDTH2                      (0xfff<<0)
+#define m_WIN2_DSP_HEIGHT2                     (0xfff<<16)
+
+#define WIN2_DSP_ST2                   (0x00e8)
+#define v_WIN2_DSP_XST2(x)                     (((x)&0x1fff)<<0)
+#define v_WIN2_DSP_YST2(x)                     (((x)&0x1fff)<<16)
+#define m_WIN2_DSP_XST2                                (0x1fff<<0)
+#define m_WIN2_DSP_YST2                                (0x1fff<<16)
+
+#define WIN2_DST_ALPHA_CTRL            (0x00ec)
+#define v_WIN2_DST_FACTOR_M0(x)                        (((x)&7)<<6)
+#define m_WIN2_DST_FACTOR_M0                   (7<<6)
+
+#define WIN2_MST3                      (0x00f0)
+#define WIN2_DSP_INFO3                 (0x00f4)
+#define v_WIN2_DSP_WIDTH3(x)                   (((x-1)&0xfff)<<0)
+#define v_WIN2_DSP_HEIGHT3(x)                  (((x-1)&0xfff)<<16)
+#define m_WIN2_DSP_WIDTH3                      (0xfff<<0)
+#define m_WIN2_DSP_HEIGHT3                     (0xfff<<16)
+
+#define WIN2_DSP_ST3                   (0x00f8)
+#define v_WIN2_DSP_XST3(x)                     (((x)&0x1fff)<<0)
+#define v_WIN2_DSP_YST3(x)                     (((x)&0x1fff)<<16)
+#define m_WIN2_DSP_XST3                                (0x1fff<<0)
+#define m_WIN2_DSP_YST3                                (0x1fff<<16)
+
+#define WIN2_FADING_CTRL               (0x00fc)
+#define v_WIN2_FADING_OFFSET_R(x)              (((x)&0xff)<<0)
+#define v_WIN2_FADING_OFFSET_G(x)              (((x)&0xff)<<8)
+#define v_WIN2_FADING_OFFSET_B(x)              (((x)&0xff)<<16)
+#define v_WIN2_FADING_EN(x)                    (((x)&1)<<24)
+
+#define m_WIN2_FADING_OFFSET_R                 (0xff<<0)
+#define m_WIN2_FADING_OFFSET_G                 (0xff<<8)
+#define m_WIN2_FADING_OFFSET_B                 (0xff<<16)
+#define m_WIN2_FADING_EN                       (1<<24)
+
+/*win3 register*/
+#define WIN3_CTRL0                     (0x0100)
+#define v_WIN3_EN(x)                           (((x)&1)<<0)
+#define v_WIN3_INTERLACE_READ(x)               (((x)&1)<<1)
+#define v_WIN3_CSC_MODE(x)                     (((x)&1)<<2)
+#define v_WIN3_MST0_EN(x)                      (((x)&1)<<4)
+#define v_WIN3_DATA_FMT0(x)                    (((x)&3)<<5)
+#define v_WIN3_MST1_EN(x)                      (((x)&1)<<8)
+#define v_WIN3_DATA_FMT1(x)                    (((x)&3)<<9)
+#define v_WIN3_MST2_EN(x)                      (((x)&1)<<12)
+#define v_WIN3_DATA_FMT2(x)                    (((x)&3)<<13)
+#define v_WIN3_MST3_EN(x)                      (((x)&1)<<16)
+#define v_WIN3_DATA_FMT3(x)                    (((x)&3)<<17)
+#define v_WIN3_RB_SWAP0(x)                     (((x)&1)<<20)
+#define v_WIN3_ALPHA_SWAP0(x)                  (((x)&1)<<21)
+#define v_WIN3_ENDIAN_SWAP0(x)                 (((x)&1)<<22)
+#define v_WIN3_RB_SWAP1(x)                     (((x)&1)<<23)
+#define v_WIN3_ALPHA_SWAP1(x)                  (((x)&1)<<24)
+#define v_WIN3_ENDIAN_SWAP1(x)                 (((x)&1)<<25)
+#define v_WIN3_RB_SWAP2(x)                     (((x)&1)<<26)
+#define v_WIN3_ALPHA_SWAP2(x)                  (((x)&1)<<27)
+#define v_WIN3_ENDIAN_SWAP2(x)                 (((x)&1)<<28)
+#define v_WIN3_RB_SWAP3(x)                     (((x)&1)<<29)
+#define v_WIN3_ALPHA_SWAP3(x)                  (((x)&1)<<30)
+#define v_WIN3_ENDIAN_SWAP3(x)                 (((x)&1)<<31)
+
+#define m_WIN3_EN                              (1<<0)
+#define m_WIN3_INTERLACE_READ                  (1<<1)
+#define m_WIN3_CSC_MODE                                (1<<2)
+#define m_WIN3_MST0_EN                         (1<<4)
+#define m_WIN3_DATA_FMT0                       (3<<5)
+#define m_WIN3_MST1_EN                         (1<<8)
+#define m_WIN3_DATA_FMT1                       (3<<9)
+#define m_WIN3_MST2_EN                         (1<<12)
+#define m_WIN3_DATA_FMT2                       (3<<13)
+#define m_WIN3_MST3_EN                         (1<<16)
+#define m_WIN3_DATA_FMT3                       (3<<17)
+#define m_WIN3_RB_SWAP0                                (1<<20)
+#define m_WIN3_ALPHA_SWAP0                     (1<<21)
+#define m_WIN3_ENDIAN_SWAP0                    (1<<22)
+#define m_WIN3_RB_SWAP1                                (1<<23)
+#define m_WIN3_ALPHA_SWAP1                     (1<<24)
+#define m_WIN3_ENDIAN_SWAP1                    (1<<25)
+#define m_WIN3_RB_SWAP2                                (1<<26)
+#define m_WIN3_ALPHA_SWAP2                     (1<<27)
+#define m_WIN3_ENDIAN_SWAP2                    (1<<28)
+#define m_WIN3_RB_SWAP3                                (1<<29)
+#define m_WIN3_ALPHA_SWAP3                     (1<<30)
+#define m_WIN3_ENDIAN_SWAP3                    (1<<31)
+
+#define WIN3_CTRL1                     (0x0104)
+#define v_WIN3_AXI_GATHER_EN(x)                        (((x)&1)<<0)
+#define v_WIN3_AXI_MAX_OUTSTANDING_EN(x)       (((x)&1)<<1)
+#define v_WIN3_DMA_BURST_LENGTH(x)             (((x)&0x3)<<2)
+#define v_WIN3_AXI_GATHER_NUM(x)               (((x)&0xf)<<4)
+#define v_WIN3_AXI_OUTSTANDING_MAX_NUM(x)      (((x)&0x1f)<<8)
+#define v_WIN3_NO_OUTSTANDING(x)               (((x)&1)<<14)
+#define v_WIN3_Y_MIR(x)                                (((x)&1)<<15)
+#define v_WIN3_LUT_EN(x)                       (((x)&1)<<16)
+#define v_WIN_RID_WIN3(x)                      (((x)&0xf)<<20)
+
+#define m_WIN3_AXI_GATHER_EN                   (1<<0)
+#define m_WIN3_AXI_MAX_OUTSTANDING_EN          (1<<1)
+#define m_WIN3_DMA_BURST_LENGTH                        (0x3<<2)
+#define m_WIN3_AXI_GATHER_NUM                  (0xf<<4)
+#define m_WIN3_AXI_OUTSTANDING_MAX_NUM         (0x1f<<8)
+#define m_WIN3_NO_OUTSTANDING                  (1<<14)
+#define m_WIN3_Y_MIR                           (1<<15)
+#define m_WIN3_LUT_EN                          (1<<16)
+#define m_WIN_RID_WIN3                         (0xf<<20)
+
+#define WIN3_VIR0_1                    (0x0108)
+#define v_WIN3_VIR_STRIDE0(x)                  (((x)&0xffff)<<0)
+#define v_WIN3_VIR_STRIDE1(x)                  (((x)&0xffff)<<16)
+#define m_WIN3_VIR_STRIDE0                     (0xffff<<0)
+#define m_WIN3_VIR_STRIDE1                     (0xffff<<16)
+
+#define WIN3_VIR2_3                    (0x010c)
+#define v_WIN3_VIR_STRIDE2(x)                  (((x)&0xffff)<<0)
+#define v_WIN3_VIR_STRIDE3(x)                  (((x)&0xffff)<<16)
+#define m_WIN3_VIR_STRIDE2                     (0xffff<<0)
+#define m_WIN3_VIR_STRIDE3                     (0xffff<<16)
+
+#define WIN3_MST0                      (0x0110)
+#define WIN3_DSP_INFO0                 (0x0114)
+#define v_WIN3_DSP_WIDTH0(x)                   (((x-1)&0xfff)<<0)
+#define v_WIN3_DSP_HEIGHT0(x)                  (((x-1)&0xfff)<<16)
+#define m_WIN3_DSP_WIDTH0                      (0xfff<<0)
+#define m_WIN3_DSP_HEIGHT0                     (0xfff<<16)
+
+#define WIN3_DSP_ST0                   (0x0118)
+#define v_WIN3_DSP_XST0(x)                     (((x)&0x1fff)<<0)
+#define v_WIN3_DSP_YST0(x)                     (((x)&0x1fff)<<16)
+#define m_WIN3_DSP_XST0                                (0x1fff<<0)
+#define m_WIN3_DSP_YST0                                (0x1fff<<16)
+
+#define WIN3_COLOR_KEY                 (0x011c)
+#define v_WIN3_COLOR_KEY(x)                    (((x)&0xffffff)<<0)
+#define v_WIN3_KEY_EN(x)                       (((x)&1)<<24)
+#define m_WIN3_COLOR_KEY                       (0xffffff<<0)
+#define m_WIN3_KEY_EN                          ((u32)1<<24)
+
+#define WIN3_MST1                      (0x0120)
+#define WIN3_DSP_INFO1                 (0x0124)
+#define v_WIN3_DSP_WIDTH1(x)                   (((x-1)&0xfff)<<0)
+#define v_WIN3_DSP_HEIGHT1(x)                  (((x-1)&0xfff)<<16)
+#define m_WIN3_DSP_WIDTH1                      (0xfff<<0)
+#define m_WIN3_DSP_HEIGHT1                     (0xfff<<16)
+
+#define WIN3_DSP_ST1                   (0x0128)
+#define v_WIN3_DSP_XST1(x)                     (((x)&0x1fff)<<0)
+#define v_WIN3_DSP_YST1(x)                     (((x)&0x1fff)<<16)
+#define m_WIN3_DSP_XST1                                (0x1fff<<0)
+#define m_WIN3_DSP_YST1                                (0x1fff<<16)
+
+#define WIN3_SRC_ALPHA_CTRL            (0x012c)
+#define v_WIN3_SRC_ALPHA_EN(x)                 (((x)&1)<<0)
+#define v_WIN3_SRC_COLOR_M0(x)                 (((x)&1)<<1)
+#define v_WIN3_SRC_ALPHA_M0(x)                 (((x)&1)<<2)
+#define v_WIN3_SRC_BLEND_M0(x)                 (((x)&3)<<3)
+#define v_WIN3_SRC_ALPHA_CAL_M0(x)             (((x)&1)<<5)
+#define v_WIN3_SRC_FACTOR_M0(x)                        (((x)&7)<<6)
+#define v_WIN3_SRC_GLOBAL_ALPHA(x)             (((x)&0xff)<<16)
+#define v_WIN3_FADING_VALUE(x)                 (((x)&0xff)<<24)
+
+#define m_WIN3_SRC_ALPHA_EN                    (1<<0)
+#define m_WIN3_SRC_COLOR_M0                    (1<<1)
+#define m_WIN3_SRC_ALPHA_M0                    (1<<2)
+#define m_WIN3_SRC_BLEND_M0                    (3<<3)
+#define m_WIN3_SRC_ALPHA_CAL_M0                        (1<<5)
+#define m_WIN3_SRC_FACTOR_M0                   (7<<6)
+#define m_WIN3_SRC_GLOBAL_ALPHA                        (0xff<<16)
+#define m_WIN3_FADING_VALUE                    (0xff<<24)
+
+#define WIN3_MST2                      (0x0130)
+#define WIN3_DSP_INFO2                 (0x0134)
+#define v_WIN3_DSP_WIDTH2(x)                   (((x-1)&0xfff)<<0)
+#define v_WIN3_DSP_HEIGHT2(x)                  (((x-1)&0xfff)<<16)
+#define m_WIN3_DSP_WIDTH2                      (0xfff<<0)
+#define m_WIN3_DSP_HEIGHT2                     (0xfff<<16)
+
+#define WIN3_DSP_ST2                   (0x0138)
+#define v_WIN3_DSP_XST2(x)                     (((x)&0x1fff)<<0)
+#define v_WIN3_DSP_YST2(x)                     (((x)&0x1fff)<<16)
+#define m_WIN3_DSP_XST2                                (0x1fff<<0)
+#define m_WIN3_DSP_YST2                                (0x1fff<<16)
+
+#define WIN3_DST_ALPHA_CTRL            (0x013c)
+#define v_WIN3_DST_FACTOR_M0(x)                        (((x)&7)<<6)
+#define m_WIN3_DST_FACTOR_M0                   (7<<6)
+
+
+#define WIN3_MST3                      (0x0140)
+#define WIN3_DSP_INFO3                 (0x0144)
+#define v_WIN3_DSP_WIDTH3(x)                   (((x-1)&0xfff)<<0)
+#define v_WIN3_DSP_HEIGHT3(x)                  (((x-1)&0xfff)<<16)
+#define m_WIN3_DSP_WIDTH3              (0xfff<<0)
+#define m_WIN3_DSP_HEIGHT3             (0xfff<<16)
+
+#define WIN3_DSP_ST3                   (0x0148)
+#define v_WIN3_DSP_XST3(x)                     (((x)&0x1fff)<<0)
+#define v_WIN3_DSP_YST3(x)                     (((x)&0x1fff)<<16)
+#define m_WIN3_DSP_XST3                        (0x1fff<<0)
+#define m_WIN3_DSP_YST3                        (0x1fff<<16)
+
+#define WIN3_FADING_CTRL               (0x014c)
+#define v_WIN3_FADING_OFFSET_R(x)              (((x)&0xff)<<0)
+#define v_WIN3_FADING_OFFSET_G(x)              (((x)&0xff)<<8)
+#define v_WIN3_FADING_OFFSET_B(x)              (((x)&0xff)<<16)
+#define v_WIN3_FADING_EN(x)                    (((x)&1)<<24)
+
+#define m_WIN3_FADING_OFFSET_R                 (0xff<<0)
+#define m_WIN3_FADING_OFFSET_G                 (0xff<<8)
+#define m_WIN3_FADING_OFFSET_B                 (0xff<<16)
+#define m_WIN3_FADING_EN                       (1<<24)
+
+
+/*hwc register*/
+#define HWC_CTRL0                      (0x0150)
+#define v_HWC_EN(x)                            (((x)&1)<<0)
+#define v_HWC_DATA_FMT(x)                      (((x)&7)<<1)
+#define v_HWC_MODE(x)                          (((x)&1)<<4)
+#define v_HWC_SIZE(x)                          (((x)&3)<<5)
+#define v_HWC_INTERLACE_READ(x)                        (((x)&1)<<8)
+#define v_HWC_CSC_MODE(x)                      (((x)&1)<<10)
+#define v_HWC_RB_SWAP(x)                       (((x)&1)<<12)
+#define v_HWC_ALPHA_SWAP(x)                    (((x)&1)<<13)
+#define v_HWC_ENDIAN_SWAP(x)                   (((x)&1)<<14)
+
+#define m_HWC_EN                               (1<<0)
+#define m_HWC_DATA_FMT                         (7<<1)
+#define m_HWC_MODE                             (1<<4)
+#define m_HWC_SIZE                             (3<<5)
+#define m_HWC_INTERLACE_READ                   (1<<8)
+#define m_HWC_CSC_MODE                         (1<<10)
+#define m_HWC_RB_SWAP                          (1<<12)
+#define m_HWC_ALPHA_SWAP                       (1<<13)
+#define m_HWC_ENDIAN_SWAP                      (1<<14)
+
+
+#define HWC_CTRL1                      (0x0154)
+#define v_HWC_AXI_GATHER_EN(x)                 (((x)&1)<<0)
+#define v_HWC_AXI_MAX_OUTSTANDING_EN(x)                (((x)&1)<<1)
+#define v_HWC_DMA_BURST_LENGTH(x)              (((x)&0x3)<<2)
+#define v_HWC_AXI_GATHER_NUM(x)                        (((x)&0x7)<<4)
+#define v_HWC_AXI_OUTSTANDING_MAX_NUM(x)       (((x)&0x1f)<<8)
+#define v_HWC_RGB2YUV_EN(x)                    (((x)&1)<<13)
+#define v_HWC_NO_OUTSTANDING(x)                        (((x)&1)<<14)
+#define v_HWC_Y_MIR(x)                         (((x)&1)<<15)
+#define v_HWC_LUT_EN(x)                                (((x)&1)<<16)
+#define v_WIN_RID_HWC(x)                       (((x)&0xf)<<20)
+
+#define m_HWC_AXI_GATHER_EN                    (1<<0)
+#define m_HWC_AXI_MAX_OUTSTANDING_EN           (1<<1)
+#define m_HWC_DMA_BURST_LENGTH                 (0x3<<2)
+#define m_HWC_AXI_GATHER_NUM                   (0x7<<4)
+#define m_HWC_AXI_OUTSTANDING_MAX_NUM          (0x1f<<8)
+#define m_HWC_RGB2YUV_EN                       (1<<13)
+#define m_HWC_NO_OUTSTANDING                   (1<<14)
+#define m_HWC_Y_MIR                            (1<<15)
+#define m_HWC_LUT_EN                           (1<<16)
+#define m_WIN_RID_HWC                          (0xf<<20)
+
+#define HWC_MST                                (0x0158)
+#define HWC_DSP_ST                     (0x015c)
+#define v_HWC_DSP_XST(x)                       (((x)&0x1fff)<<0)
+#define v_HWC_DSP_YST(x)                       (((x)&0x1fff)<<16)
+#define m_HWC_DSP_XST                          (0x1fff<<0)
+#define m_HWC_DSP_YST                          (0x1fff<<16)
+
+#define HWC_SRC_ALPHA_CTRL             (0x0160)
+#define v_HWC_SRC_ALPHA_EN(x)                  (((x)&1)<<0)
+#define v_HWC_SRC_COLOR_M0(x)                  (((x)&1)<<1)
+#define v_HWC_SRC_ALPHA_M0(x)                  (((x)&1)<<2)
+#define v_HWC_SRC_BLEND_M0(x)                  (((x)&3)<<3)
+#define v_HWC_SRC_ALPHA_CAL_M0(x)              (((x)&1)<<5)
+#define v_HWC_SRC_FACTOR_M0(x)                 (((x)&7)<<6)
+#define v_HWC_SRC_GLOBAL_ALPHA(x)              (((x)&0xff)<<16)
+#define v_HWC_FADING_VALUE(x)                  (((x)&0xff)<<24)
+
+#define m_HWC_SRC_ALPHA_EN                     (1<<0)
+#define m_HWC_SRC_COLOR_M0                     (1<<1)
+#define m_HWC_SRC_ALPHA_M0                     (1<<2)
+#define m_HWC_SRC_BLEND_M0                     (3<<3)
+#define m_HWC_SRC_ALPHA_CAL_M0                 (1<<5)
+#define m_HWC_SRC_FACTOR_M0                    (7<<6)
+#define m_HWC_SRC_GLOBAL_ALPHA                 (0xff<<16)
+#define m_HWC_FADING_VALUE                     (0xff<<24)
+
+#define HWC_DST_ALPHA_CTRL             (0x0164)
+#define v_HWC_DST_FACTOR_M0(x)                 (((x)&7)<<6)
+#define m_HWC_DST_FACTOR_M0                    (7<<6)
+
+
+#define HWC_FADING_CTRL                        (0x0168)
+#define v_HWC_FADING_OFFSET_R(x)               (((x)&0xff)<<0)
+#define v_HWC_FADING_OFFSET_G(x)               (((x)&0xff)<<8)
+#define v_HWC_FADING_OFFSET_B(x)               (((x)&0xff)<<16)
+#define v_HWC_FADING_EN(x)                     (((x)&1)<<24)
+
+#define m_HWC_FADING_OFFSET_R                  (0xff<<0)
+#define m_HWC_FADING_OFFSET_G                  (0xff<<8)
+#define m_HWC_FADING_OFFSET_B                  (0xff<<16)
+#define m_HWC_FADING_EN                                (1<<24)
+
+/*post process register*/
+#define POST_DSP_HACT_INFO             (0x0170)
+#define v_DSP_HACT_END_POST(x)                 (((x)&0x1fff)<<0)
+#define v_DSP_HACT_ST_POST(x)                  (((x)&0x1fff)<<16)
+#define m_DSP_HACT_END_POST                    (0x1fff<<0)
+#define m_DSP_HACT_ST_POST                     (0x1fff<<16)
+
+#define POST_DSP_VACT_INFO             (0x0174)
+#define v_DSP_VACT_END_POST(x)                 (((x)&0x1fff)<<0)
+#define v_DSP_VACT_ST_POST(x)                  (((x)&0x1fff)<<16)
+#define m_DSP_VACT_END_POST                    (0x1fff<<0)
+#define m_DSP_VACT_ST_POST                     (0x1fff<<16)
+
+#define POST_SCL_FACTOR_YRGB           (0x0178)
+#define v_POST_HS_FACTOR_YRGB(x)               (((x)&0xffff)<<0)
+#define v_POST_VS_FACTOR_YRGB(x)               (((x)&0xffff)<<16)
+#define m_POST_HS_FACTOR_YRGB                  (0xffff<<0)
+#define m_POST_VS_FACTOR_YRGB                  (0xffff<<16)
+
+#define POST_SCL_CTRL                  (0x0180)
+#define v_POST_HOR_SD_EN(x)                    (((x)&1)<<0)
+#define v_POST_VER_SD_EN(x)                    (((x)&1)<<1)
+
+#define m_POST_HOR_SD_EN                       (0x1<<0)
+#define m_POST_VER_SD_EN                       (0x1<<1)
+
+#define POST_DSP_VACT_INFO_F1          (0x0184)
+#define v_DSP_VACT_END_POST_F1(x)              (((x)&0x1fff)<<0)
+#define v_DSP_VACT_ST_POST_F1(x)               (((x)&0x1fff)<<16)
+
+#define m_DSP_VACT_END_POST_F1                 (0x1fff<<0)
+#define m_DSP_VACT_ST_POST_F1                  (0x1fff<<16)
+
+#define DSP_HTOTAL_HS_END              (0x0188)
+#define v_DSP_HS_PW(x)                         (((x)&0x1fff)<<0)
+#define v_DSP_HTOTAL(x)                                (((x)&0x1fff)<<16)
+#define m_DSP_HS_PW                            (0x1fff<<0)
+#define m_DSP_HTOTAL                           (0x1fff<<16)
+
+#define DSP_HACT_ST_END                        (0x018c)
+#define v_DSP_HACT_END(x)                      (((x)&0x1fff)<<0)
+#define v_DSP_HACT_ST(x)                       (((x)&0x1fff)<<16)
+#define m_DSP_HACT_END                         (0x1fff<<0)
+#define m_DSP_HACT_ST                          (0x1fff<<16)
+
+#define DSP_VTOTAL_VS_END              (0x0190)
+#define v_DSP_VS_PW(x)                         (((x)&0x1fff)<<0)
+#define v_DSP_VTOTAL(x)                                (((x)&0x1fff)<<16)
+#define m_DSP_VS_PW                            (0x1fff<<0)
+#define m_DSP_VTOTAL                           (0x1fff<<16)
+
+#define DSP_VACT_ST_END                        (0x0194)
+#define v_DSP_VACT_END(x)                      (((x)&0x1fff)<<0)
+#define v_DSP_VACT_ST(x)                       (((x)&0x1fff)<<16)
+#define m_DSP_VACT_END                         (0x1fff<<0)
+#define m_DSP_VACT_ST                          (0x1fff<<16)
+
+#define DSP_VS_ST_END_F1               (0x0198)
+#define v_DSP_VS_END_F1(x)                     (((x)&0x1fff)<<0)
+#define v_DSP_VS_ST_F1(x)                      (((x)&0x1fff)<<16)
+#define m_DSP_VS_END_F1                                (0x1fff<<0)
+#define m_DSP_VS_ST_F1                         (0x1fff<<16)
+
+#define DSP_VACT_ST_END_F1             (0x019c)
+#define v_DSP_VACT_END_F1(x)                   (((x)&0x1fff)<<0)
+#define v_DSP_VAC_ST_F1(x)                     (((x)&0x1fff)<<16)
+#define m_DSP_VACT_END_F1                      (0x1fff<<0)
+#define m_DSP_VAC_ST_F1                                (0x1fff<<16)
+
+
+/*pwm register*/
+#define PWM_CTRL                       (0x01a0)
+#define v_PWM_EN(x)                            (((x)&1)<<0)
+#define v_PWM_MODE(x)                          (((x)&3)<<1)
+
+#define v_DUTY_POL(x)                          (((x)&1)<<3)
+#define v_INACTIVE_POL(x)                      (((x)&1)<<4)
+#define v_OUTPUT_MODE(x)                       (((x)&1)<<5)
+#define v_BL_EN(x)                             (((x)&1)<<8)
+#define v_CLK_SEL(x)                           (((x)&1)<<9)
+#define v_PRESCALE(x)                          (((x)&7)<<12)
+#define v_SCALE(x)                             (((x)&0xff)<<16)
+#define v_RPT(x)                               (((x)&0xff)<<24)
+
+#define m_PWM_EN                               (1<<0)
+#define m_PWM_MODE                             (3<<1)
+
+#define m_DUTY_POL                             (1<<3)
+#define m_INACTIVE_POL                         (1<<4)
+#define m_OUTPUT_MODE                          (1<<5)
+#define m_BL_EN                                        (1<<8)
+#define m_CLK_SEL                              (1<<9)
+#define m_PRESCALE                             (7<<12)
+#define m_SCALE                                        (0xff<<16)
+#define m_RPT                                  ((u32)0xff<<24)
+
+#define PWM_PERIOD_HPR                         (0x01a4)
+#define PWM_DUTY_LPR                           (0x01a8)
+#define PWM_CNT                                        (0x01ac)
+
+/*BCSH register*/
+#define BCSH_COLOR_BAR                 (0x01b0)
+#define v_BCSH_EN(x)                           (((x)&1)<<0)
+#define v_BCSH_COLOR_BAR_Y(x)                  (((x)&0xff)<<8)
+#define v_BCSH_COLOR_BAR_U(x)                  (((x)&0xff)<<16)
+#define v_BCSH_COLOR_BAR_V(x)                  (((x)&0xff)<<24)
+#define m_BCSH_EN                              (1<<0)
+#define m_BCSH_COLOR_BAR_Y                     (0xff<<8)
+#define m_BCSH_COLOR_BAR_U                     (0xff<<16)
+#define m_BCSH_COLOR_BAR_V                     (0xff<<24)
+
+#define BCSH_BCS                       (0x01b4)
+#define v_BCSH_BRIGHTNESS(x)                   (((x)&0xff)<<0)
+#define v_BCSH_CONTRAST(x)                     (((x)&0x1ff)<<8)
+#define v_BCSH_SAT_CON(x)                      (((x)&0x3ff)<<20)
+#define v_BCSH_OUT_MODE(x)                     (((x)&0x3)<<30)
+#define m_BCSH_BRIGHTNESS                      (0xff<<0)
+#define m_BCSH_CONTRAST                                (0x1ff<<8)
+#define m_BCSH_SAT_CON                         (0x3ff<<20)
+#define m_BCSH_OUT_MODE                                ((u32)0x3<<30)
+
+#define BCSH_H                         (0x01b8)
+#define v_BCSH_SIN_HUE(x)                      (((x)&0x1ff)<<0)
+#define v_BCSH_COS_HUE(x)                      (((x)&0x1ff)<<16)
+
+#define m_BCSH_SIN_HUE                         (0x1ff<<0)
+#define m_BCSH_COS_HUE                         (0x1ff<<16)
+
+#define BCSH_CTRL                      (0x01bc)
+#define   m_BCSH_Y2R_EN                                (0x1<<0)
+#define   m_BCSH_Y2R_CSC_MODE                  (0x3<<2)
+#define   m_BCSH_R2Y_EN                                (0x1<<4)
+#define   m_BCSH_R2Y_CSC_MODE                  (0x1<<6)
+#define   v_BCSH_Y2R_EN(x)                     (((x)&0x1)<<0)
+#define   v_BCSH_Y2R_CSC_MODE(x)               (((x)&0x3)<<2)
+#define   v_BCSH_R2Y_EN(x)                     (((x)&0x1)<<4)
+#define   v_BCSH_R2Y_CSC_MODE(x)               (((x)&0x1)<<6)
+
+#define CABC_CTRL0                     (0x01c0)
+#define v_CABC_EN(x)                           (((x)&1)<<0)
+#define v_CABC_CALC_PIXEL_NUM(x)               (((x)&0xffffff)<<1)
+#define m_CABC_EN                              (1<<0)
+#define m_CABC_CALC_PIXEL_NUM                  (0xffffff<<1)
+
+
+#define CABC_CTRL1                     (0x01c4)
+#define v_CABC_LUT_EN(x)                       (((x)&1)<<0)
+#define v_CABC_TOTAL_PIXEL_NUM(x)              (((x)&0xffffff)<<1)
+#define m_CABC_LUT_EN                          (1<<0)
+#define m_CABC_TOTAL_PIXEL_NUM                 (0xffffff<<1)
+
+#define CABC_CTRL2                     (0x01c8)
+#define v_CABC_STAGE_UP_REC(x)                 (((x)&0xff)<<0)
+#define m_CABC_STAGE_UP_REC                    (0xff<<0)
+#define v_CABC_STAGE_UP(x)                     (((x)&0x1ff)<<8)
+#define m_CABC_STAGE_UP                                (0x1ff<<8)
+#define v_CABC_GLOBAL_SU_LIMIT_EN(x)           (((x)&0x1)<<23)
+#define m_CABC_GLOBAL_SU_LIMIT_EN              (0x1<<23)
+#define v_CABC_GLOBAL_SU_REC(x)                        (((x)&0xff)<<24)
+#define m_CABC_GLOBAL_SU_REC                   (0xff<<24)
+
+#define CABC_CTRL3                     (0x01cc)
+#define v_CABC_STAGE_DOWN(x)                   (((x)&0xff)<<0)
+#define m_CABC_STAGE_DOWN                      (0xff<<0)
+#define v_CABC_STAGE_DOWN_REC(x)               (((x)&0x1ff)<<8)
+#define m_CABC_STAGE_DOWN_REC                  (0x1ff<<8)
+#define v_CABC_GLOBAL_SU(x)                    (((x)&0x1ff)<<23)
+#define m_CABC_GLOBAL_SU                       (0x1ff<<23)
+#define CABC_GAUSS_LINE0_0             (0x01d0)
+#define v_CABC_T_LINE0_0(x)                    (((x)&0xff)<<0)
+#define v_CABC_T_LINE0_1(x)                    (((x)&0xff)<<8)
+#define v_CABC_T_LINE0_2(x)                    (((x)&0xff)<<16)
+#define v_CABC_T_LINE0_3(x)                    (((x)&0xff)<<24)
+#define m_CABC_T_LINE0_0                       (0xff<<0)
+#define m_CABC_T_LINE0_1                       (0xff<<8)
+#define m_CABC_T_LINE0_2                       (0xff<<16)
+#define m_CABC_T_LINE0_3                       ((u32)0xff<<24)
+
+#define CABC_GAUSS_LINE0_1             (0x01d4)
+#define v_CABC_T_LINE0_4(x)                    (((x)&0xff)<<0)
+#define v_CABC_T_LINE0_5(x)                    (((x)&0xff)<<8)
+#define v_CABC_T_LINE0_6(x)                    (((x)&0xff)<<16)
+#define m_CABC_T_LINE0_4                       (0xff<<0)
+#define m_CABC_T_LINE0_5                       (0xff<<8)
+#define m_CABC_T_LINE0_6                       (0xff<<16)
+
+
+#define CABC_GAUSS_LINE1_0             (0x01d8)
+#define v_CABC_T_LINE1_0(x)                    (((x)&0xff)<<0)
+#define v_CABC_T_LINE1_1(x)                    (((x)&0xff)<<8)
+#define v_CABC_T_LINE1_2(x)                    (((x)&0xff)<<16)
+#define v_CABC_T_LINE1_3(x)                    (((x)&0xff)<<24)
+#define m_CABC_T_LINE1_0                       (0xff<<0)
+#define m_CABC_T_LINE1_1                       (0xff<<8)
+#define m_CABC_T_LINE1_2                       (0xff<<16)
+#define m_CABC_T_LINE1_3                       ((u32)0xff<<24)
+
+
+#define CABC_GAUSS_LINE1_1             (0x01dc)
+#define v_CABC_T_LINE1_4(x)                    (((x)&0xff)<<0)
+#define v_CABC_T_LINE1_5(x)                    (((x)&0xff)<<8)
+#define v_CABC_T_LINE1_6(x)                    (((x)&0xff)<<16)
+#define m_CABC_T_LINE1_4                       (0xff<<0)
+#define m_CABC_T_LINE1_5                       (0xff<<8)
+#define m_CABC_T_LINE1_6                       (0xff<<16)
+
+
+#define CABC_GAUSS_LINE2_0             (0x01e0)
+#define v_CABC_T_LINE2_0(x)                    (((x)&0xff)<<0)
+#define v_CABC_T_LINE2_1(x)                    (((x)&0xff)<<8)
+#define v_CABC_T_LINE2_2(x)                    (((x)&0xff)<<16)
+#define v_CABC_T_LINE2_3(x)                    (((x)&0xff)<<24)
+#define m_CABC_T_LINE2_0                       (0xff<<0)
+#define m_CABC_T_LINE2_1                       (0xff<<8)
+#define m_CABC_T_LINE2_2                       (0xff<<16)
+#define m_CABC_T_LINE2_3                       ((u32)0xff<<24)
+
+
+#define CABC_GAUSS_LINE2_1             (0x01e4)
+#define v_CABC_T_LINE2_4(x)                    (((x)&0xff)<<0)
+#define v_CABC_T_LINE2_5(x)                    (((x)&0xff)<<8)
+#define v_CABC_T_LINE2_6(x)                    (((x)&0xff)<<16)
+#define m_CABC_T_LINE2_4                       (0xff<<0)
+#define m_CABC_T_LINE2_5                       (0xff<<8)
+#define m_CABC_T_LINE2_6                       (0xff<<16)
+
+/*FRC register*/
+#define FRC_LOWER01_0                  (0x01e8)
+#define v_FRC_LOWER01_FRM0(x)                  (((x)&0xffff)<<0)
+#define v_FRC_LOWER01_FRM1(x)                  (((x)&0xffff)<<16)
+#define m_FRC_LOWER01_FRM0                     (0xffff<<0)
+#define m_FRC_LOWER01_FRM1                     ((u32)0xffff<<16)
+
+#define FRC_LOWER01_1                  (0x01ec)
+#define v_FRC_LOWER01_FRM2(x)                  (((x)&0xffff)<<0)
+#define v_FRC_LOWER01_FRM3(x)                  (((x)&0xffff)<<16)
+#define m_FRC_LOWER01_FRM2                     (0xffff<<0)
+#define m_FRC_LOWER01_FRM3                     ((u32)0xffff<<16)
+
+
+#define FRC_LOWER10_0                  (0x01f0)
+#define v_FRC_LOWER10_FRM0(x)                  (((x)&0xffff)<<0)
+#define v_FRC_LOWER10_FRM1(x)                  (((x)&0xffff)<<16)
+#define m_FRC_LOWER10_FRM0                     (0xffff<<0)
+#define m_FRC_LOWER10_FRM1                     ((u32)0xffff<<16)
+
+
+#define FRC_LOWER10_1                  (0x01f4)
+#define v_FRC_LOWER10_FRM2(x)                  (((x)&0xffff)<<0)
+#define v_FRC_LOWER10_FRM3(x)                  (((x)&0xffff)<<16)
+#define m_FRC_LOWER10_FRM2                     (0xffff<<0)
+#define m_FRC_LOWER10_FRM3                     ((u32)0xffff<<16)
+
+
+#define FRC_LOWER11_0                  (0x01f8)
+#define v_FRC_LOWER11_FRM0(x)                  (((x)&0xffff)<<0)
+#define v_FRC_LOWER11_FRM1(x)                  (((x)&0xffff)<<16)
+#define m_FRC_LOWER11_FRM0                     (0xffff<<0)
+#define m_FRC_LOWER11_FRM1                     ((u32)0xffff<<16)
+
+
+#define FRC_LOWER11_1                  (0x01fc)
+#define v_FRC_LOWER11_FRM2(x)                  (((x)&0xffff)<<0)
+#define v_FRC_LOWER11_FRM3(x)                  (((x)&0xffff)<<16)
+#define m_FRC_LOWER11_FRM2                     (0xffff<<0)
+#define m_FRC_LOWER11_FRM3                     ((u32)0xffff<<16)
+
+#define IFBDC_CTRL                     (0x0200)
+#define v_IFBDC_CTRL_FBDC_EN(x)                (((x)&0x1)<<0)
+#define v_IFBDC_CTRL_FBDC_COR_EN(x)            (((x)&0x1)<<1)
+#define v_IFBDC_CTRL_FBDC_WIN_SEL(x)           (((x)&0x3)<<2)
+#define v_IFBDC_CTRL_FBDC_ROTATION_MODE(x)     (((x)&0x7)<<4)
+#define v_IFBDC_CTRL_FBDC_FMT(x)               (((x)&0x7f)<<7)
+#define v_IFBDC_AXI_MAX_OUTSTANDING_EN(x)      (((x)&0x1)<<14)
+#define v_IFBDC_AXI_OUTSTANDING_MAX_NUM(x)     (((x)&0x1f)<<15)
+#define v_IFBDC_CTRL_WIDTH_RATIO(x)            (((x)&0x1)<<20)
+#define v_IFBDC_FRAME_RST_EN(x)                        (((x)&0x1)<<21)
+#define v_IFBDC_ICTRL_NOTIFY(x)                        (((x)&0x1)<<22)
+#define v_IFBDC_INVALIDATE_PENDING_O(x)                (((x)&0x1)<<23)
+#define v_IFBDC_RID(x)                         (((x)&0xf)<<24)
+#define v_IFBDC_RSTN(x)                                (((x)&0x1)<<28)
+
+#define m_IFBDC_CTRL_FBDC_EN                   (0x1<<0)
+#define m_IFBDC_CTRL_FBDC_COR_EN               (0x1<<1)
+#define m_IFBDC_CTRL_FBDC_WIN_SEL              (0x3<<2)
+#define m_IFBDC_CTRL_FBDC_ROTATION_MODE                (0x7<<4)
+#define m_IFBDC_CTRL_FBDC_FMT                  (0x7f<<7)
+#define m_IFBDC_AXI_MAX_OUTSTANDING_EN         (0x1<<14)
+#define m_IFBDC_AXI_OUTSTANDING_MAX_NUM                (0x1f<<15)
+#define m_IFBDC_CTRL_WIDTH_RATIO               (0x1<<20)
+#define m_IFBDC_FRAME_RST_EN                   (0x1<<21)
+#define m_IFBDC_ICTRL_NOTIFY                   (0x1<<22)
+#define m_IFBDC_INVALIDATE_PENDING_O           (0x1<<23)
+#define m_IFBDC_RID                            (0xf<<24)
+#define m_IFBDC_RSTN                           (0x1<<28)
+
+#define IFBDC_TILES_NUM                        (0x0204)
+#define v_IFBDC_TILES_NUM(x)                   (((x-1)&0x7fffff)<<0)
+#define m_IFBDC_TILES_NUM                      (0x7fffff<<0)
+
+#define IFBDC_FRAME_RST_CYCLE          (0x0208)
+#define v_IFBDC_FRAME_RST_CYCLE(x)             (((x)&0x3ff)<<0)
+#define v_DMA_IFBDC_FRAME_RST_CYCLE(x)         (((x)&0x3ff)<<16)
+#define m_IFBDC_FRAME_RST_CYCLE                        ((0x3ff)<<0)
+#define m_DMA_IFBDC_FRAME_RST_CYCLE            ((0x3ff)<<16)
+
+
+
+#define IFBDC_BASE_ADDR                        (0x20c)
+#define v_IFBDC_BASE_ADDR(x)                   (((x)&0xffffffff)<<0)
+#define m_IFBDC_BASE_ADDR                      ((0xffffffff)<<0)
+
+#define IFBDC_MB_SIZE                  (0x210)
+#define  v_IFBDC_MB_SIZE_WIDTH(x)              (((x-1)&0x7f)<<0)
+#define  v_IFBDC_MB_SIZE_HEIGHT(x)             (((x-1)&0x1ff)<<16)
+#define  m_IFBDC_MB_SIZE_WIDTH                 ((0x7f)<<0)
+#define  m_IFBDC_MB_SIZE_HEIGHT                        ((0x1ff)<<16)
+
+
+#define IFBDC_CMP_INDEX_INIT           (0x0214)
+#define v_IFBDC_CMP_INDEX_INIT(x)               (((x)&0x7fffff) << 0)
+#define m_IFBDC_CMP_INDEX_INIT                  (0x7fffff<<0)
+
+#define IFBDC_MB_VIR_WIDTH             (0x220)
+#define  v_IFBDC_MB_VIR_WIDTH(x)               (((x)&0xff)<<0)
+#define  m_IFBDC_MB_VIR_WIDTH                  ((0xff)<<0)
+
+#define IFBDC_DEBUG0                   (0x230)
+#define v_DBG_IFBDC_MB_Y_WCNT(x)               (((x)&0x1ff)<<0)
+#define v_DBG_IFBDC_IDLE(x)                    (((x)&0x1)<<12)
+#define v_DBG_IFBDC_LB_RCNT(x)                 (((x)&0x7FF)<<16)
+#define v_DBG_IFBDC_INVALIDATE_PENDING_I(x)    (((x)&0x1)<<28)
+
+#define m_DBG_IFBDC_MB_Y_WCNT                  (0x1ff<<0)
+#define m_DBG_IFBDC_IDLE                       (0x1<<12)
+#define m_DBG_IFBDC_LB_RCNT                    (0x7FF<<16)
+#define m_DBG_IFBDC_INVALIDATE_PENDING_I       (0x1<<28)
+
+#define IFBDC_DEBUG1                   (0x234)
+#define V_DBG_FBDC_CMP_TILE_INDEX(x)           (((x)&0x7fffff)<<0)
+#define m_DBG_FBDC_CMP_TILE_INDEX              (0x7fffff<<0)
+
+#define LATENCY_CTRL0                  (0x250)
+#define  v_RD_LATENCY_EN(x)                    (((x)&0x1)<<0)
+#define  v_HAND_LATENCY_CLR(x)                 (((x)&0x1)<<1)
+#define  v_RD_LATENCY_MODE(x)                  (((x)&0x1)<<2)
+#define  v_RD_LATENCY_ID0(x)                   (((x)&0xf)<<4)
+#define  v_RD_LATENCY_THR(x)                   (((x)&0xfff)<<8)
+#define  v_RD_LATENCY_ST_NUM(x)                        (((x)&0x1f)<<20)
+#define  m_RD_LATENCY_EN                       (0x1<<0)
+#define  m_HAND_LATENCY_CLR                    (0x1<<1)
+#define  m_RD_LATENCY_MODE                     (0x1<<2)
+#define  m_RD_LATENCY_ID0                      (0xf<<4)
+#define  m_RD_LATENCY_THR                      (0xfff<<8)
+#define  m_RD_LATENCY_ST_NUM                   (0x1f<<20)
+
+#define RD_MAX_LATENCY_NUM0            (0x254)
+#define v_RD_MAX_LATENCY_NUM_CH0(x)            (((x)&0xFFF)<<0)
+#define v_RD_LATENCY_OVERFLOW_CH0(x)           (((x)&0x1)<<16)
+#define m_RD_MAX_LATENCY_NUM_CH0               (0xFFF<<0)
+#define m_RD_LATENCY_OVERFLOW_CH0              (0x1<<16)
+
+#define RD_LATENCY_THR_NUM0            (0x258)
+#define v_RD_LATENCY_THR_NUM_CH0(x)            (((x)&0xFFFFFF)<<0)
+#define m_RD_LATENCY_THR_NUM_CH0               (0xFFFFFF<<0)
+
+#define RD_LATENCY_SWAP_NUM0           (0x25c)
+#define v_RD_LATENCY_SAMP_NUM_CH0(x)           (((x)&0xFFFFFF)<<0)
+#define m_RD_LATENCY_SAMP_NUM_CH0              (0xFFFFFF<<0)
+
+#define WIN0_DSP_BG                    (0x260)
+#define v_WIN0_DSP_BG_BLUE(x)                  (((x)&0xff)<<0)
+#define v_WIN0_DSP_BG_GREEN(x)                 (((x)&0xff)<<8)
+#define v_WIN0_DSP_BG_RED(x)                   (((x)&0xff)<<16)
+#define v_WIN0_DSP_BG_EN(x)                    (((x)&1)<<31)
+#define m_WIN0_DSP_BG_BLUE                     (0xff<<0)
+#define m_WIN0_DSP_BG_GREEN                    (0xff<<8)
+#define m_WIN0_DSP_BG_RED                      (0xff<<16)
+#define m_WIN0_DSP_BG_EN                       (0x1<<31)
+
+#define WIN1_DSP_BG                    (0x264)
+#define v_WIN1_DSP_BG_BLUE(x)                  (((x)&0xff)<<0)
+#define v_WIN1_DSP_BG_GREEN(x)                 (((x)&0xff)<<8)
+#define v_WIN1_DSP_BG_RED(x)                   (((x)&0xff)<<16)
+#define v_WIN1_DSP_BG_EN(x)                    (((x)&1)<<31)
+#define m_WIN1_DSP_BG_BLUE                     (0xff<<0)
+#define m_WIN1_DSP_BG_GREEN                    (0xff<<8)
+#define m_WIN1_DSP_BG_RED                      (0xff<<16)
+#define m_WIN1_DSP_BG_EN                       (0x1<<31)
+
+#define WIN2_DSP_BG                    (0x268)
+#define v_WIN2_DSP_BG_BLUE(x)                  (((x)&0xff)<<0)
+#define v_WIN2_DSP_BG_GREEN(x)                 (((x)&0xff)<<8)
+#define v_WIN2_DSP_BG_RED(x)                   (((x)&0xff)<<16)
+#define v_WIN2_DSP_BG_EN(x)                    (((x)&1)<<31)
+#define m_WIN2_DSP_BG_BLUE                     (0xff<<0)
+#define m_WIN2_DSP_BG_GREEN                    (0xff<<8)
+#define m_WIN2_DSP_BG_RED                      (0xff<<16)
+#define m_WIN2_DSP_BG_EN                       (0x1<<31)
+
+#define WIN3_DSP_BG                    (0x26c)
+#define v_WIN3_DSP_BG_BLUE(x)                  (((x)&0xff)<<0)
+#define v_WIN3_DSP_BG_GREEN(x)                 (((x)&0xff)<<8)
+#define v_WIN3_DSP_BG_RED(x)                   (((x)&0xff)<<16)
+#define v_WIN3_DSP_BG_EN(x)                    (((x)&1)<<31)
+#define m_WIN3_DSP_BG_BLUE                     (0xff<<0)
+#define m_WIN3_DSP_BG_GREEN                    (0xff<<8)
+#define m_WIN3_DSP_BG_RED                      (0xff<<16)
+#define m_WIN3_DSP_BG_EN                       (0x1<<31)
+
+#define SCAN_LINE_NUM                  (0x270)
+#define CABC_DEBUG0                    (0x274)
+#define CABC_DEBUG1                    (0x278)
+#define CABC_DEBUG2                    (0x27c)
+#define DBG_REG_000                    (0x280)
+#define DBG_REG_001                    (0x284)
+#define DBG_REG_002                    (0x288)
+#define DBG_REG_003                    (0x28c)
+#define DBG_REG_004                    (0x290)
+#define DBG_REG_005                    (0x294)
+#define DBG_REG_006                    (0x298)
+#define DBG_REG_007                    (0x29c)
+#define DBG_REG_008                    (0x2a0)
+#define DBG_REG_016                    (0x2c0)
+#define DBG_REG_017                    (0x2c4)
+#define DBG_REG_018                    (0x2c8)
+#define DBG_REG_019                    (0x2cc)
+#define DBG_REG_020                    (0x2d0)
+#define DBG_REG_021                    (0x2d4)
+#define DBG_REG_022                    (0x2d8)
+#define DBG_REG_023                    (0x2dc)
+#define DBG_REG_028                    (0x2f0)
+
+#define MMU_DTE_ADDR                   (0x0300)
+#define v_MMU_DTE_ADDR(x)                      (((x)&0xffffffff)<<0)
+#define m_MMU_DTE_ADDR                         (0xffffffff<<0)
+
+#define MMU_STATUS                     (0x0304)
+#define v_PAGING_ENABLED(x)                    (((x)&1)<<0)
+#define v_PAGE_FAULT_ACTIVE(x)                 (((x)&1)<<1)
+#define v_STAIL_ACTIVE(x)                      (((x)&1)<<2)
+#define v_MMU_IDLE(x)                          (((x)&1)<<3)
+#define v_REPLAY_BUFFER_EMPTY(x)               (((x)&1)<<4)
+#define v_PAGE_FAULT_IS_WRITE(x)               (((x)&1)<<5)
+#define v_PAGE_FAULT_BUS_ID(x)                 (((x)&0x1f)<<6)
+#define m_PAGING_ENABLED                       (1<<0)
+#define m_PAGE_FAULT_ACTIVE                    (1<<1)
+#define m_STAIL_ACTIVE                         (1<<2)
+#define m_MMU_IDLE                             (1<<3)
+#define m_REPLAY_BUFFER_EMPTY                  (1<<4)
+#define m_PAGE_FAULT_IS_WRITE                  (1<<5)
+#define m_PAGE_FAULT_BUS_ID                    (0x1f<<6)
+
+#define MMU_COMMAND                    (0x0308)
+#define v_MMU_CMD(x)                           (((x)&0x3)<<0)
+#define m_MMU_CMD                      (0x3<<0)
+
+#define MMU_PAGE_FAULT_ADDR            (0x030c)
+#define v_PAGE_FAULT_ADDR(x)                   (((x)&0xffffffff)<<0)
+#define m_PAGE_FAULT_ADDR                      (0xffffffff<<0)
+
+#define MMU_ZAP_ONE_LINE               (0x0310)
+#define v_MMU_ZAP_ONE_LINE(x)                  (((x)&0xffffffff)<<0)
+#define m_MMU_ZAP_ONE_LINE                     (0xffffffff<<0)
+
+#define MMU_INT_RAWSTAT                        (0x0314)
+#define v_PAGE_FAULT_RAWSTAT(x)                        (((x)&1)<<0)
+#define v_READ_BUS_ERROR_RAWSTAT(x)            (((x)&1)<<1)
+#define m_PAGE_FAULT_RAWSTAT                   (1<<0)
+#define m_READ_BUS_ERROR_RAWSTAT               (1<<1)
+
+#define MMU_INT_CLEAR                  (0x0318)
+#define v_PAGE_FAULT_CLEAR(x)                  (((x)&1)<<0)
+#define v_READ_BUS_ERROR_CLEAR(x)              (((x)&1)<<1)
+#define m_PAGE_FAULT_CLEAR                     (1<<0)
+#define m_READ_BUS_ERROR_CLEAR                 (1<<1)
+
+#define MMU_INT_MASK                   (0x031c)
+#define v_PAGE_FAULT_MASK(x)                   (((x)&1)<<0)
+#define v_READ_BUS_ERROR_MASK(x)               (((x)&1)<<1)
+#define m_PAGE_FAULT_MASK                      (1<<0)
+#define m_READ_BUS_ERROR_MASK                  (1<<1)
+
+#define MMU_INT_STATUS                 (0x0320)
+#define v_PAGE_FAULT_STATUS(x)                 (((x)&1)<<0)
+#define v_READ_BUS_ERROR_STATUS(x)             (((x)&1)<<1)
+#define m_PAGE_FAULT_STATUS                    (1<<0)
+#define m_READ_BUS_ERROR_STATUS                        (1<<1)
+
+#define MMU_AUTO_GATING                        (0x0324)
+#define v_MMU_AUTO_GATING(x)                   (((x)&1)<<0)
+#define m_MMU_AUTO_GATING                      (1<<0)
+
+#define WIN2_LUT_ADDR                  (0x0400)
+#define WIN3_LUT_ADDR                  (0x0800)
+#define HWC_LUT_ADDR                   (0x0c00)
+#define GAMMA_LUT_ADDR                 (0x1000)
+#define CABC_GAMMA_LUT_ADDR            (0x1800)
+#define MCU_BYPASS_WPORT               (0x2200)
+#define MCU_BYPASS_RPORT               (0x2300)
+
+
+
+enum lb_mode {
+       LB_YUV_3840X5 = 0x0,
+       LB_YUV_2560X8 = 0x1,
+       LB_RGB_3840X2 = 0x2,
+       LB_RGB_2560X4 = 0x3,
+       LB_RGB_1920X5 = 0x4,
+       LB_RGB_1280X8 = 0x5
+};
+
+enum sacle_up_mode {
+       SCALE_UP_BIL = 0x0,
+       SCALE_UP_BIC = 0x1
+};
+
+enum scale_down_mode {
+       SCALE_DOWN_BIL = 0x0,
+       SCALE_DOWN_AVG = 0x1
+};
+
+/*ALPHA BLENDING MODE*/
+enum alpha_mode {               /*  Fs       Fd */
+       AB_USER_DEFINE     = 0x0,
+       AB_CLEAR           = 0x1,/*  0          0*/
+       AB_SRC             = 0x2,/*  1          0*/
+       AB_DST             = 0x3,/*  0          1  */
+       AB_SRC_OVER        = 0x4,/*  1              1-As''*/
+       AB_DST_OVER        = 0x5,/*  1-Ad''   1*/
+       AB_SRC_IN          = 0x6,
+       AB_DST_IN          = 0x7,
+       AB_SRC_OUT         = 0x8,
+       AB_DST_OUT         = 0x9,
+       AB_SRC_ATOP        = 0xa,
+       AB_DST_ATOP        = 0xb,
+       XOR                = 0xc,
+       AB_SRC_OVER_GLOBAL = 0xd
+}; /*alpha_blending_mode*/
+
+enum src_alpha_mode {
+       AA_STRAIGHT        = 0x0,
+       AA_INVERSE         = 0x1
+};/*src_alpha_mode*/
+
+enum global_alpha_mode {
+       AA_GLOBAL         = 0x0,
+       AA_PER_PIX        = 0x1,
+       AA_PER_PIX_GLOBAL = 0x2
+};/*src_global_alpha_mode*/
+
+enum src_alpha_sel {
+       AA_SAT          = 0x0,
+       AA_NO_SAT       = 0x1
+};/*src_alpha_sel*/
+
+enum src_color_mode {
+       AA_SRC_PRE_MUL         = 0x0,
+       AA_SRC_NO_PRE_MUL      = 0x1
+};/*src_color_mode*/
+
+enum factor_mode {
+       AA_ZERO                 = 0x0,
+       AA_ONE                  = 0x1,
+       AA_SRC                  = 0x2,
+       AA_SRC_INVERSE          = 0x3,
+       AA_SRC_GLOBAL           = 0x4
+};/*src_factor_mode  &&  dst_factor_mode*/
+
+enum _vop_r2y_csc_mode {
+       VOP_R2Y_CSC_BT601 = 0,
+       VOP_R2Y_CSC_BT709
+};
+
+enum _vop_y2r_csc_mode {
+       VOP_Y2R_CSC_MPEG = 0,
+       VOP_Y2R_CSC_JPEG,
+       VOP_Y2R_CSC_HD,
+       VOP_Y2R_CSC_BYPASS
+};
+enum _vop_format {
+       VOP_FORMAT_ARGB888 = 0,
+       VOP_FORMAT_RGB888,
+       VOP_FORMAT_RGB565,
+       VOP_FORMAT_YCBCR420 = 4,
+       VOP_FORMAT_YCBCR422,
+       VOP_FORMAT_YCBCR444
+};
+
+enum _vop_overlay_mode {
+       VOP_RGB_DOMAIN,
+       VOP_YUV_DOMAIN
+};
+
+struct lcdc_device {
+       int id;
+       struct rk_lcdc_driver driver;
+       struct device *dev;
+       struct rk_screen *screen;
+
+       void __iomem *regs;
+       void *regsbak;          /*back up reg*/
+       u32 reg_phy_base;       /* physical basic address of lcdc register*/
+       u32 len;                /* physical map length of lcdc register*/
+       /*one time only one process allowed to config the register*/
+       spinlock_t reg_lock;
+
+       int __iomem *dsp_lut_addr_base;
+
+
+       int prop;               /*used for primary or extended display device*/
+       bool pre_init;
+       bool pwr18;             /*if lcdc use 1.8v power supply*/
+       /*if aclk or hclk is closed ,acess to register is not allowed*/
+       bool clk_on;
+       /*active layer counter,when  atv_layer_cnt = 0,disable lcdc*/
+       u8 atv_layer_cnt;
+
+
+       unsigned int            irq;
+
+       struct clk              *pd;            /*lcdc power domain*/
+       struct clk              *hclk;          /*lcdc AHP clk*/
+       struct clk              *dclk;          /*lcdc dclk*/
+       struct clk              *aclk;          /*lcdc share memory frequency*/
+       u32 pixclock;
+
+       u32 standby;                            /*1:standby,0:wrok*/
+       u32 iommu_status;
+       struct backlight_device *backlight;
+       struct clk              *pll_sclk;
+};
+
+struct alpha_config {
+       enum src_alpha_mode src_alpha_mode;       /*win0_src_alpha_m0*/
+       u32 src_global_alpha_val; /*win0_src_global_alpha*/
+       enum global_alpha_mode src_global_alpha_mode;/*win0_src_blend_m0*/
+       enum src_alpha_sel src_alpha_cal_m0;     /*win0_src_alpha_cal_m0*/
+       enum src_color_mode src_color_mode;      /*win0_src_color_m0*/
+       enum factor_mode src_factor_mode;        /*win0_src_factor_m0*/
+       enum factor_mode dst_factor_mode;      /*win0_dst_factor_m0*/
+};
+
+struct lcdc_cabc_mode {
+       u32 pixel_num;                  /* pixel precent number */
+       u16 stage_up;                   /* up stride */
+       u16 stage_down;         /* down stride */
+       u16 global_su;
+};
+
+static inline void lcdc_writel(struct lcdc_device *lcdc_dev, u32 offset, u32 v)
+{
+       u32 *_pv = (u32 *)lcdc_dev->regsbak;
+
+       _pv += (offset >> 2);
+       *_pv = v;
+       writel_relaxed(v, lcdc_dev->regs + offset);
+}
+
+static inline u32 lcdc_readl(struct lcdc_device *lcdc_dev, u32 offset)
+{
+       u32 v;
+       u32 *_pv = (u32 *)lcdc_dev->regsbak;
+
+       _pv += (offset >> 2);
+       v = readl_relaxed(lcdc_dev->regs + offset);
+       *_pv = v;
+       return v;
+}
+
+static inline u32 lcdc_read_bit(struct lcdc_device *lcdc_dev,
+                               u32 offset, u32 msk)
+{
+       u32 v;
+       u32 *_pv = (u32 *)lcdc_dev->regsbak;
+       u32 _v = readl_relaxed(lcdc_dev->regs + offset);
+
+       _pv += (offset >> 2);
+       *_pv = _v;
+       _v &= msk;
+       v = (_v ? 1 : 0);
+       return v;
+}
+
+static inline void  lcdc_set_bit(struct lcdc_device *lcdc_dev,
+                                u32 offset, u32 msk)
+{
+       u32 *_pv = (u32 *)lcdc_dev->regsbak;
+
+       _pv += (offset >> 2);
+       (*_pv) |= msk;
+       writel_relaxed(*_pv, lcdc_dev->regs + offset);
+}
+
+static inline void lcdc_clr_bit(struct lcdc_device *lcdc_dev,
+                               u32 offset, u32 msk)
+{
+       u32 *_pv = (u32 *)lcdc_dev->regsbak;
+
+       _pv += (offset >> 2);
+       (*_pv) &= (~msk);
+       writel_relaxed(*_pv, lcdc_dev->regs + offset);
+}
+
+static inline void  lcdc_msk_reg(struct lcdc_device *lcdc_dev,
+                                u32 offset, u32 msk, u32 v)
+{
+       u32 *_pv = (u32 *)lcdc_dev->regsbak;
+
+       _pv += (offset >> 2);
+       (*_pv) &= (~msk);
+       (*_pv) |= v;
+       writel_relaxed(*_pv, lcdc_dev->regs + offset);
+}
+
+static inline void lcdc_cfg_done(struct lcdc_device *lcdc_dev)
+{
+       writel_relaxed(0x01, lcdc_dev->regs + REG_CFG_DONE);
+       dsb();
+}
+
+#define CUBIC_PRECISE  0
+#define CUBIC_SPLINE   1
+#define CUBIC_CATROM   2
+#define CUBIC_MITCHELL 3
+
+#define CUBIC_MODE_SELETION      CUBIC_PRECISE
+
+/*************************************************************/
+#define SCALE_FACTOR_BILI_DN_FIXPOINT_SHIFT   12   /* 4.12*/
+#define SCALE_FACTOR_BILI_DN_FIXPOINT(x)      \
+       ((INT32)((x) * (1 << SCALE_FACTOR_BILI_DN_FIXPOINT_SHIFT)))
+
+#define SCALE_FACTOR_BILI_UP_FIXPOINT_SHIFT   16   /* 0.16*/
+
+#define SCALE_FACTOR_AVRG_FIXPOINT_SHIFT   16   /*0.16*/
+#define SCALE_FACTOR_AVRG_FIXPOINT(x)      \
+       ((INT32)((x) * (1 << SCALE_FACTOR_AVRG_FIXPOINT_SHIFT)))
+
+#define SCALE_FACTOR_BIC_FIXPOINT_SHIFT    16   /* 0.16*/
+#define SCALE_FACTOR_BIC_FIXPOINT(x)       \
+       ((INT32)((x) * (1 << SCALE_FACTOR_BIC_FIXPOINT_SHIFT)))
+
+#define SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT    12  /*NONE SCALE,vsd_bil*/
+#define SCALE_FACTOR_VSDBIL_FIXPOINT_SHIFT     12  /*VER SCALE DOWN BIL*/
+
+/*********************************************************/
+
+/*#define GET_SCALE_FACTOR_BILI(src, dst)  \
+       ((((src) - 1) << SCALE_FACTOR_BILI_FIXPOINT_SHIFT) / ((dst) - 1))*/
+/*#define GET_SCALE_FACTOR_BIC(src, dst)   \
+       ((((src) - 1) << SCALE_FACTOR_BIC_FIXPOINT_SHIFT) / ((dst) - 1))*/
+/*modified by hpz*/
+#define GET_SCALE_FACTOR_BILI_DN(src, dst)  \
+       ((((src) * 2 - 3) << (SCALE_FACTOR_BILI_DN_FIXPOINT_SHIFT - 1)) \
+       / ((dst) - 1))
+#define GET_SCALE_FACTOR_BILI_UP(src, dst)  \
+       ((((src) * 2 - 3) << (SCALE_FACTOR_BILI_UP_FIXPOINT_SHIFT - 1)) \
+       / ((dst) - 1))
+#define GET_SCALE_FACTOR_BIC(src, dst)      \
+       ((((src) * 2 - 3) << (SCALE_FACTOR_BIC_FIXPOINT_SHIFT - 1)) \
+       / ((dst) - 1))
+
+/*********************************************************/
+/*NOTE: hardware in order to save resource , srch first to get interlace line
+(srch+vscalednmult-1)/vscalednmult; and do scale*/
+#define GET_SCALE_DN_ACT_HEIGHT(srch, vscalednmult) \
+       (((srch) + (vscalednmult) - 1) / (vscalednmult))
+
+/*#define VSKIP_MORE_PRECISE*/
+
+#ifdef VSKIP_MORE_PRECISE
+#define MIN_SCALE_FACTOR_AFTER_VSKIP        1.5f
+#define GET_SCALE_FACTOR_BILI_DN_VSKIP(srch, dsth, vscalednmult) \
+       (GET_SCALE_FACTOR_BILI_DN(GET_SCALE_DN_ACT_HEIGHT((srch),\
+       (vscalednmult)), (dsth)))
+#else
+#define MIN_SCALE_FACTOR_AFTER_VSKIP        1
+#if 0/*rk3288*/
+#define GET_SCALE_FACTOR_BILI_DN_VSKIP(srch, dsth, vscalednmult) \
+       ((GET_SCALE_DN_ACT_HEIGHT((srch), (vscalednmult)) == (dsth))\
+               ? (GET_SCALE_FACTOR_BILI_DN((srch),\
+               (dsth))/(vscalednmult))\
+               : GET_SCALE_FACTOR_BILI_DN(GET_SCALE_DN_ACT_HEIGHT((srch),\
+               (vscalednmult)), (dsth)))
+#else/*rk3368*/
+#define GET_SCALE_FACTOR_BILI_DN_VSKIP(srch, dsth, vscalednmult) \
+       ((GET_SCALE_DN_ACT_HEIGHT((srch) , (vscalednmult)) == (dsth)) \
+       ? (GET_SCALE_FACTOR_BILI_DN((srch) , (dsth)) / (vscalednmult)) \
+       : (GET_SCALE_DN_ACT_HEIGHT((srch) , (vscalednmult)) == ((dsth) * 2)) \
+       ?  GET_SCALE_FACTOR_BILI_DN(GET_SCALE_DN_ACT_HEIGHT(((srch) - 1),\
+       (vscalednmult)) , (dsth)) : \
+       GET_SCALE_FACTOR_BILI_DN(GET_SCALE_DN_ACT_HEIGHT((srch),\
+       (vscalednmult)) , (dsth)))
+#endif
+
+
+#endif
+/*****************************************************************/
+
+
+/*scalefactor must >= dst/src, or pixels at end of line may be unused*/
+/*scalefactor must < dst/(src-1), or dst buffer may overflow*/
+/*avrg old code: ((((dst) << SCALE_FACTOR_AVRG_FIXPOINT_SHIFT))\
+       /((src) - 1)) hxx_chgsrc*/
+/*modified by hpz:*/
+#define GET_SCALE_FACTOR_AVRG(src, dst)  ((((dst) << \
+       (SCALE_FACTOR_AVRG_FIXPOINT_SHIFT + 1))) / (2 * (src) - 1))
+
+/*************************************************************************/
+/*Scale Coordinate Accumulate, x.16*/
+#define SCALE_COOR_ACC_FIXPOINT_SHIFT     16
+#define SCALE_COOR_ACC_FIXPOINT_ONE (1 << SCALE_COOR_ACC_FIXPOINT_SHIFT)
+#define SCALE_COOR_ACC_FIXPOINT(x) \
+       ((INT32)((x)*(1 << SCALE_COOR_ACC_FIXPOINT_SHIFT)))
+#define SCALE_COOR_ACC_FIXPOINT_REVERT(x) \
+       ((((x) >> (SCALE_COOR_ACC_FIXPOINT_SHIFT - 1)) + 1) >> 1)
+
+#define SCALE_GET_COOR_ACC_FIXPOINT(scalefactor, factorfixpointshift)  \
+       ((scalefactor) << \
+       (SCALE_COOR_ACC_FIXPOINT_SHIFT - (factorfixpointshift)))
+
+
+/************************************************************************/
+/*CoarsePart of Scale Coordinate Accumulate, used for pixel mult-add factor, 0.8*/
+#define SCALE_FILTER_FACTOR_FIXPOINT_SHIFT     8
+#define SCALE_FILTER_FACTOR_FIXPOINT_ONE       \
+       (1 << SCALE_FILTER_FACTOR_FIXPOINT_SHIFT)
+#define SCALE_FILTER_FACTOR_FIXPOINT(x)        \
+       ((INT32)((x) * (1 << SCALE_FILTER_FACTOR_FIXPOINT_SHIFT)))
+#define SCALE_FILTER_FACTOR_FIXPOINT_REVERT(x) \
+       ((((x) >> (SCALE_FILTER_FACTOR_FIXPOINT_SHIFT-1)) + 1) >> 1)
+
+#define SCALE_GET_FILTER_FACTOR_FIXPOINT(cooraccumulate, \
+       cooraccfixpointshift) \
+       (((cooraccumulate) >> \
+       ((cooraccfixpointshift) - SCALE_FILTER_FACTOR_FIXPOINT_SHIFT)) & \
+       (SCALE_FILTER_FACTOR_FIXPOINT_ONE - 1))
+
+#define SCALE_OFFSET_FIXPOINT_SHIFT            8
+#define SCALE_OFFSET_FIXPOINT(x)              \
+       ((INT32)((x) * (1 << SCALE_OFFSET_FIXPOINT_SHIFT)))
+
+#endif