From: Mark Yao Date: Mon, 7 Dec 2015 00:49:38 +0000 (+0800) Subject: video: rk322x: rename vop rk3228 to rk322x X-Git-Tag: firefly_0821_release~3469 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=88f9467e5166be329dc197bde4849e9eca653d60;p=firefly-linux-kernel-4.4.55.git video: rk322x: rename vop rk3228 to rk322x Change-Id: I6d8d9ff84f76d7fa5c820b682081bbe0cb851ff1 Signed-off-by: Mark Yao --- diff --git a/Documentation/devicetree/bindings/video/rockchip_lcdc.txt b/Documentation/devicetree/bindings/video/rockchip_lcdc.txt index 333b329ddff9..b2226317312e 100755 --- a/Documentation/devicetree/bindings/video/rockchip_lcdc.txt +++ b/Documentation/devicetree/bindings/video/rockchip_lcdc.txt @@ -7,7 +7,7 @@ Required properties: - compatible: value should be one of the following "rockchip,rk3288-lcdc"; /* for RK3288 SoCs */ "rockchip,rk3368-lcdc"; /* for RK3368 SoCs */ - "rockchip,rk3228-lcdc"; /* for RK3228 SoCs */ + "rockchip,rk322x-lcdc"; /* for RK322X SoCs */ - rockchip,prop: set the lcdc as primary or extend display. - rochchip,pwr18: set the controller IO voltage,0 is 3.3v,1 is 1.8v. - reg: physical base address and length of the LCDC registers set. diff --git a/drivers/video/rockchip/lcdc/Kconfig b/drivers/video/rockchip/lcdc/Kconfig index bf63152d06a8..bec873068180 100644 --- a/drivers/video/rockchip/lcdc/Kconfig +++ b/drivers/video/rockchip/lcdc/Kconfig @@ -51,8 +51,8 @@ config LCDC_RK3368 help Driver for rk3368 lcdc.There are one lcd controllers on rk3368 -config LCDC_RK3228 - bool "rk3228 lcdc support" +config LCDC_RK322X + bool "rk322x lcdc support" depends on FB_ROCKCHIP help - Driver for rk3228 lcdc.There are one lcd controllers on rk3228 + Driver for rk322x lcdc.There are one lcd controllers on rk322x diff --git a/drivers/video/rockchip/lcdc/Makefile b/drivers/video/rockchip/lcdc/Makefile index fd84d05fb048..0cbe7f332104 100644 --- a/drivers/video/rockchip/lcdc/Makefile +++ b/drivers/video/rockchip/lcdc/Makefile @@ -6,4 +6,4 @@ 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 -obj-$(CONFIG_LCDC_RK3228) += rk3228_lcdc.o +obj-$(CONFIG_LCDC_RK322X) += rk322x_lcdc.o diff --git a/drivers/video/rockchip/lcdc/rk3228_lcdc.c b/drivers/video/rockchip/lcdc/rk3228_lcdc.c deleted file mode 100644 index 67d7a1119c56..000000000000 --- a/drivers/video/rockchip/lcdc/rk3228_lcdc.c +++ /dev/null @@ -1,3586 +0,0 @@ -/* - * drivers/video/rockchip/lcdc/rk3228_lcdc.c - * - * Copyright (C) 2015 ROCKCHIP, Inc. - * Author: Mark Yao - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rk3228_lcdc.h" - -/*#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 const uint32_t csc_y2r_bt601_limit[12] = { - 0x04a8, 0, 0x0662, 0xfffc8654, - 0x04a8, 0xfe6f, 0xfcbf, 0x00022056, - 0x04a8, 0x0812, 0, 0xfffbaeac, -}; - -static const uint32_t csc_y2r_bt709_full[12] = { - 0x04a8, 0, 0x072c, 0xfffc219e, - 0x04a8, 0xff26, 0xfdde, 0x0001357b, - 0x04a8, 0x0873, 0, 0xfffb7dee, -}; - -static const uint32_t csc_y2r_bt601_full[12] = { - 0x0400, 0, 0x059c, 0xfffd342d, - 0x0400, 0xfea0, 0xfd25, 0x00021fcc, - 0x0400, 0x0717, 0, 0xfffc76bc, -}; - -static const uint32_t csc_y2r_bt601_limit_10[12] = { - 0x04a8, 0, 0x0662, 0xfff2134e, - 0x04a8, 0xfe6f, 0xfcbf, 0x00087b58, - 0x04a8, 0x0812, 0, 0xffeeb4b0, -}; - -static const uint32_t csc_y2r_bt709_full_10[12] = { - 0x04a8, 0, 0x072c, 0xfff08077, - 0x04a8, 0xff26, 0xfdde, 0x0004cfed, - 0x04a8, 0x0873, 0, 0xffedf1b8, -}; - -static const uint32_t csc_y2r_bt601_full_10[12] = { - 0x0400, 0, 0x059c, 0xfff4cab4, - 0x0400, 0xfea0, 0xfd25, 0x00087932, - 0x0400, 0x0717, 0, 0xfff1d4f2, -}; - -static const uint32_t csc_y2r_bt2020[12] = { - 0x04a8, 0, 0x06b6, 0xfff16bfc, - 0x04a8, 0xff40, 0xfd66, 0x58ae9, - 0x04a8, 0x0890, 0, 0xffedb828, -}; - -static const uint32_t csc_r2y_bt601_limit[12] = { - 0x0107, 0x0204, 0x0064, 0x04200, - 0xff68, 0xfed6, 0x01c2, 0x20200, - 0x01c2, 0xfe87, 0xffb7, 0x20200, -}; - -static const uint32_t csc_r2y_bt709_full[12] = { - 0x00bb, 0x0275, 0x003f, 0x04200, - 0xff99, 0xfea5, 0x01c2, 0x20200, - 0x01c2, 0xfe68, 0xffd7, 0x20200, -}; - -static const uint32_t csc_r2y_bt601_full[12] = { - 0x0132, 0x0259, 0x0075, 0x200, - 0xff53, 0xfead, 0x0200, 0x20200, - 0x0200, 0xfe53, 0xffad, 0x20200, -}; - -static const uint32_t csc_r2y_bt601_limit_10[12] = { - 0x0107, 0x0204, 0x0064, 0x10200, - 0xff68, 0xfed6, 0x01c2, 0x80200, - 0x01c2, 0xfe87, 0xffb7, 0x80200, -}; - -static const uint32_t csc_r2y_bt709_full_10[12] = { - 0x00bb, 0x0275, 0x003f, 0x10200, - 0xff99, 0xfea5, 0x01c2, 0x80200, - 0x01c2, 0xfe68, 0xffd7, 0x80200, -}; - -static const uint32_t csc_r2y_bt601_full_10[12] = { - 0x0132, 0x0259, 0x0075, 0x200, - 0xff53, 0xfead, 0x0200, 0x80200, - 0x0200, 0xfe53, 0xffad, 0x80200, -}; - -static const uint32_t csc_r2y_bt2020[12] = { - 0x00e6, 0x0253, 0x0034, 0x10200, - 0xff83, 0xfebd, 0x01c1, 0x80200, - 0x01c1, 0xfe64, 0xffdc, 0x80200, -}; - -static const uint32_t csc_r2r_bt2020to709[12] = { - 0x06a4, 0xfda6, 0xffb5, 0x200, - 0xff80, 0x0488, 0xfff8, 0x200, - 0xffed, 0xff99, 0x047a, 0x200, -}; - -static const uint32_t csc_r2r_bt709to2020[12] = { - 0x282, 0x151, 0x02c, 0x200, - 0x047, 0x3ae, 0x00c, 0x200, - 0x011, 0x05a, 0x395, 0x200, -}; - -static struct rk_lcdc_win vop_win[] = { - { .name = "win0", .id = 0}, - { .name = "win1", .id = 1}, - { .name = "hwc", .id = 2} -}; - -static void vop_load_csc_table(struct vop_device *vop_dev, u32 offset, - const uint32_t *table) -{ - uint32_t csc_val; - - csc_val = table[1] << 16 | table[0]; - vop_writel(vop_dev, offset, csc_val); - csc_val = table[4] << 16 | table[2]; - vop_writel(vop_dev, offset + 4, csc_val); - csc_val = table[6] << 16 | table[5]; - vop_writel(vop_dev, offset + 8, csc_val); - csc_val = table[9] << 16 | table[8]; - vop_writel(vop_dev, offset + 0xc, csc_val); - csc_val = table[10]; - vop_writel(vop_dev, offset + 0x10, csc_val); - csc_val = table[3]; - vop_writel(vop_dev, offset + 0x14, csc_val); - csc_val = table[7]; - vop_writel(vop_dev, offset + 0x18, csc_val); - csc_val = table[11]; - vop_writel(vop_dev, offset + 0x1c, csc_val); -} - -static int vop_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable); - -static int vop_clk_enable(struct vop_device *vop_dev) -{ - if (!vop_dev->clk_on) { - clk_prepare_enable(vop_dev->hclk); - clk_prepare_enable(vop_dev->dclk); - clk_prepare_enable(vop_dev->aclk); - spin_lock(&vop_dev->reg_lock); - vop_dev->clk_on = 1; - spin_unlock(&vop_dev->reg_lock); - } - - return 0; -} - -static int vop_clk_disable(struct vop_device *vop_dev) -{ - if (vop_dev->clk_on) { - spin_lock(&vop_dev->reg_lock); - vop_dev->clk_on = 0; - spin_unlock(&vop_dev->reg_lock); - mdelay(25); - clk_disable_unprepare(vop_dev->dclk); - clk_disable_unprepare(vop_dev->hclk); - clk_disable_unprepare(vop_dev->aclk); - } - - return 0; -} - -static int __maybe_unused vop_disable_irq(struct vop_device *vop_dev) -{ - if (likely(vop_dev->clk_on)) { - spin_lock(&vop_dev->reg_lock); - vop_writel(vop_dev, INTR_EN0, 0); - vop_writel(vop_dev, INTR_EN1, 0); - vop_writel(vop_dev, INTR_CLEAR0, 0xffff); - vop_writel(vop_dev, INTR_CLEAR1, 0xffff); - vop_cfg_done(vop_dev); - spin_unlock(&vop_dev->reg_lock); - }; - - return 0; -} - -static int vop_reg_dump(struct rk_lcdc_driver *dev_drv) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - int *cbase = (int *)vop_dev->regs; - int *regsbak = (int *)vop_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 vop_device *vop_dev, int en) \ -{ \ - spin_lock(&vop_dev->reg_lock); \ - vop_msk_reg(vop_dev, WIN##id##_CTRL0, V_WIN##id##_EN((u64)en)); \ - vop_cfg_done(vop_dev); \ - spin_unlock(&vop_dev->reg_lock); \ - return 0; \ -} - -WIN_EN(0); -WIN_EN(1); - -/*enable/disable win directly*/ -static int vop_win_direct_en(struct rk_lcdc_driver *drv, - int win_id, int en) -{ - struct vop_device *vop_dev = - container_of(drv, struct vop_device, driver); - if (win_id == 0) - win0_enable(vop_dev, en); - else if (win_id == 1) - win1_enable(vop_dev, en); - else - dev_err(vop_dev->dev, "invalid win number:%d\n", win_id); - return 0; -} - -#define SET_WIN_ADDR(id) \ -static int set_win##id##_addr(struct vop_device *vop_dev, u32 addr) \ -{ \ - spin_lock(&vop_dev->reg_lock); \ - vop_writel(vop_dev, WIN##id##_YRGB_MST, addr); \ - vop_msk_reg(vop_dev, WIN##id##_CTRL0, V_WIN##id##_EN(1)); \ - vop_cfg_done(vop_dev); \ - spin_unlock(&vop_dev->reg_lock); \ - return 0; \ -} - -SET_WIN_ADDR(0); -SET_WIN_ADDR(1); -int vop_direct_set_win_addr(struct rk_lcdc_driver *dev_drv, - int win_id, u32 addr) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - if (win_id == 0) - set_win0_addr(vop_dev, addr); - else - set_win1_addr(vop_dev, addr); - - return 0; -} - -static void lcdc_read_reg_defalut_cfg(struct vop_device *vop_dev) -{ - int reg = 0; - u32 val = 0; - struct rk_screen *screen = vop_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 = vop_dev->driver.win[0]; - - spin_lock(&vop_dev->reg_lock); - for (reg = 0; reg < vop_dev->len; reg += 4) { - val = vop_readl_backup(vop_dev, reg); - switch (reg) { - case WIN0_ACT_INFO: - win0->area[0].xact = (val & MASK(WIN0_ACT_WIDTH)) + 1; - win0->area[0].yact = - ((val & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1; - break; - case WIN0_DSP_INFO: - win0->area[0].xsize = (val & MASK(WIN0_DSP_WIDTH)) + 1; - win0->area[0].ysize = - ((val & MASK(WIN0_DSP_HEIGHT)) >> 16) + 1; - break; - case WIN0_DSP_ST: - st_x = val & MASK(WIN0_DSP_XST); - st_y = (val & MASK(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 & MASK(WIN0_EN); - win0->area[0].fmt_cfg = - (val & MASK(WIN0_DATA_FMT)) >> 1; - win0->fmt_10 = (val & MASK(WIN0_FMT_10)) >> 4; - win0->area[0].format = win0->area[0].fmt_cfg; - break; - case WIN0_VIR: - win0->area[0].y_vir_stride = - val & MASK(WIN0_VIR_STRIDE); - win0->area[0].uv_vir_stride = - (val & MASK(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 - 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(&vop_dev->reg_lock); -} - -/********do basic init*********/ -static int vop_pre_init(struct rk_lcdc_driver *dev_drv) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - if (vop_dev->pre_init) - return 0; - - vop_dev->hclk = devm_clk_get(vop_dev->dev, "hclk_lcdc"); - vop_dev->aclk = devm_clk_get(vop_dev->dev, "aclk_lcdc"); - vop_dev->dclk = devm_clk_get(vop_dev->dev, "dclk_lcdc"); - - if ((IS_ERR(vop_dev->aclk)) || (IS_ERR(vop_dev->dclk)) || - (IS_ERR(vop_dev->hclk))) { - dev_err(vop_dev->dev, "failed to get lcdc%d clk source\n", - vop_dev->id); - } - if (!support_uboot_display()) - rk_disp_pwr_enable(dev_drv); - vop_clk_enable(vop_dev); - - memcpy(vop_dev->regsbak, vop_dev->regs, vop_dev->len); - /*backup reg config at uboot */ - lcdc_read_reg_defalut_cfg(vop_dev); - #ifndef CONFIG_RK_FPGA - /* - * Todo, not verified - * - if (vop_dev->pwr18 == 1) { - v = 0x00200020; - vop_grf_writel(vop_dev->pmugrf_base, - PMUGRF_SOC_CON0_VOP, v); - } else { - v = 0x00200000; - vop_grf_writel(vop_dev->pmugrf_base, - PMUGRF_SOC_CON0_VOP, v); - } - */ - #endif - vop_writel(vop_dev, FRC_LOWER01_0, 0x12844821); - vop_writel(vop_dev, FRC_LOWER01_1, 0x21488412); - vop_writel(vop_dev, FRC_LOWER10_0, 0xa55a9696); - vop_writel(vop_dev, FRC_LOWER10_1, 0x5aa56969); - vop_writel(vop_dev, FRC_LOWER11_0, 0xdeb77deb); - vop_writel(vop_dev, FRC_LOWER11_1, 0xed7bb7de); - - vop_msk_reg(vop_dev, SYS_CTRL, V_AUTO_GATING_EN(0)); - vop_msk_reg(vop_dev, DSP_CTRL1, V_DITHER_UP_EN(1)); - vop_cfg_done(vop_dev); - vop_dev->pre_init = true; - - return 0; -} - -static void vop_deint(struct vop_device *vop_dev) -{ - if (vop_dev->clk_on) { - vop_disable_irq(vop_dev); - spin_lock(&vop_dev->reg_lock); - vop_msk_reg(vop_dev, WIN0_CTRL0, V_WIN0_EN(0)); - vop_msk_reg(vop_dev, WIN1_CTRL0, V_WIN0_EN(0)); - - vop_cfg_done(vop_dev); - spin_unlock(&vop_dev->reg_lock); - } -} - - -static void vop_win_csc_mode(struct vop_device *vop_dev, - struct rk_lcdc_win *win, - int csc_mode) -{ - u64 val; - - if (win->id == 0) { - val = V_WIN0_CSC_MODE(csc_mode); - vop_msk_reg(vop_dev, WIN0_CTRL0, val); - } else if (win->id == 1) { - val = V_WIN1_CSC_MODE(csc_mode); - vop_msk_reg(vop_dev, WIN1_CTRL0, val); - } else { - val = V_HWC_CSC_MODE(csc_mode); - vop_msk_reg(vop_dev, HWC_CTRL0, val); - } -} - -/* - * colorspace path: - * Input Win csc Post csc Output - * 1. YUV(2020) --> bypass ---+ Y2R->2020To709->R2Y --> YUV_OUTPUT(601/709) - * RGB --> R2Y(709) __/ - * - * 2. YUV(2020) --> bypass ---+ bypass --> YUV_OUTPUT(2020) - * RGB --> R2Y(709) __/ - * - * 3. YUV(2020) --> bypass ---+ Y2R->2020To709 --> RGB_OUTPUT(709) - * RGB --> R2Y(709) __/ - * - * 4. YUV(601/709)-> bypass ---+ Y2R->709To2020->R2Y --> YUV_OUTPUT(2020) - * RGB --> R2Y(709) __/ - * - * 5. YUV(601/709)-> bypass ---+ bypass --> YUV_OUTPUT(709) - * RGB --> R2Y(709) __/ - * - * 6. YUV(601/709)-> bypass ---+ bypass --> YUV_OUTPUT(601) - * RGB --> R2Y(601) __/ - * - * 7. YUV(601) --> Y2R(601/mpeg)-+ bypass --> RGB_OUTPUT(709) - * RGB --> bypass ____/ - * - * 8. YUV(709) --> Y2R(709/hd) --+ bypass --> RGB_OUTPUT(709) - * RGB --> bypass ____/ - * - * 9. RGB --> bypass ---> 709To2020->R2Y --> YUV_OUTPUT(2020) - * - * 10. RGB --> R2Y(709) ---> Y2R --> YUV_OUTPUT(709) - * - * 11. RGB --> R2Y(601) ---> Y2R --> YUV_OUTPUT(601) - * - * 12. RGB --> bypass ---> bypass --> RGB_OUTPUT(709) - */ - -static void vop_post_csc_cfg(struct rk_lcdc_driver *dev_drv) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - struct rk_lcdc_win *win; - int output_color = dev_drv->output_color; - int i, r2y_mode; - int overlay_mode; - int win_csc = COLOR_RGB; - u64 val; - - if (output_color == COLOR_RGB) - overlay_mode = VOP_RGB_DOMAIN; - else - overlay_mode = VOP_YUV_DOMAIN; - - if (output_color == COLOR_YCBCR) - r2y_mode = VOP_R2Y_CSC_BT601; - else - r2y_mode = VOP_R2Y_CSC_BT709; - - for (i = 0; i < dev_drv->lcdc_win_num; i++) { - win = dev_drv->win[i]; - if (!win->state) - continue; - /* - * force use yuv domain when there is a windows's csc is bt2020. - */ - if (win->colorspace == CSC_BT2020) { - overlay_mode = VOP_YUV_DOMAIN; - r2y_mode = VOP_R2Y_CSC_BT709; - win_csc = COLOR_YCBCR_BT2020; - break; - } - if (IS_YUV(win->area[0].fmt_cfg)) - win_csc = COLOR_YCBCR; - } - - for (i = 0; i < dev_drv->lcdc_win_num; i++) { - win = dev_drv->win[i]; - if (!win->state) - continue; - if (overlay_mode == VOP_YUV_DOMAIN && - !IS_YUV(win->area[0].fmt_cfg)) - vop_win_csc_mode(vop_dev, win, r2y_mode); - if (overlay_mode == VOP_RGB_DOMAIN && - IS_YUV(win->area[0].fmt_cfg)) { - if (win->colorspace == CSC_BT709) - vop_win_csc_mode(vop_dev, win, VOP_Y2R_CSC_HD); - else if (win->colorspace == CSC_BT601) - vop_win_csc_mode(vop_dev, win, - VOP_Y2R_CSC_MPEG); - else - pr_err("Error Y2R path, colorspace=%d\n", - win->colorspace); - } - } - - if (win_csc == COLOR_RGB && overlay_mode == VOP_YUV_DOMAIN) - win_csc = COLOR_YCBCR; - else if (IS_YUV_COLOR(win_csc) && overlay_mode == VOP_RGB_DOMAIN) - win_csc = COLOR_RGB; - - val = V_YUV2YUV_POST_Y2R_EN(0) | V_YUV2YUV_POST_EN(0) | - V_YUV2YUV_POST_R2Y_EN(0); - /* Y2R */ - if (win_csc == COLOR_YCBCR && output_color == COLOR_YCBCR_BT2020) { - win_csc = COLOR_RGB; - val |= V_YUV2YUV_POST_Y2R_EN(1); - vop_load_csc_table(vop_dev, POST_YUV2YUV_Y2R_COE, - csc_y2r_bt709_full); - } - if (win_csc == COLOR_YCBCR_BT2020 && - output_color != COLOR_YCBCR_BT2020) { - win_csc = COLOR_RGB_BT2020; - val |= V_YUV2YUV_POST_Y2R_EN(1); - vop_load_csc_table(vop_dev, POST_YUV2YUV_Y2R_COE, - csc_y2r_bt2020); - } - - /* R2R */ - if (win_csc == COLOR_RGB && output_color == COLOR_YCBCR_BT2020) { - win_csc = COLOR_RGB_BT2020; - val |= V_YUV2YUV_POST_EN(1); - vop_load_csc_table(vop_dev, POST_YUV2YUV_3x3_COE, - csc_r2r_bt709to2020); - } - if (win_csc == COLOR_RGB_BT2020 && - (output_color == COLOR_YCBCR || - output_color == COLOR_YCBCR_BT709 || - output_color == COLOR_RGB)) { - win_csc = COLOR_RGB; - val |= V_YUV2YUV_POST_EN(1); - vop_load_csc_table(vop_dev, POST_YUV2YUV_3x3_COE, - csc_r2r_bt2020to709); - } - - /* R2Y */ - if (!IS_YUV_COLOR(win_csc) && IS_YUV_COLOR(output_color)) { - val |= V_YUV2YUV_POST_R2Y_EN(1); - - if (output_color == COLOR_YCBCR_BT2020) - vop_load_csc_table(vop_dev, POST_YUV2YUV_R2Y_COE, - csc_r2y_bt2020); - else - vop_load_csc_table(vop_dev, POST_YUV2YUV_R2Y_COE, - csc_r2y_bt709_full); - } - - DBG(1, "win_csc=%d output_color=%d val=%llx overlay_mode=%d\n", - win_csc, output_color, val, overlay_mode); - vop_msk_reg(vop_dev, SYS_CTRL, V_OVERLAY_MODE(overlay_mode)); - vop_msk_reg(vop_dev, YUV2YUV_POST, val); -} - -static int vop_post_cfg(struct rk_lcdc_driver *dev_drv) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - struct rk_screen *screen = dev_drv->cur_screen; - u16 x_res = screen->mode.xres; - u16 y_res = screen->mode.yres; - u64 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; - - screen->post_dsp_stx = x_res * (100 - dev_drv->overscan.left) / 200; - screen->post_dsp_sty = y_res * (100 - dev_drv->overscan.top) / 200; - screen->post_xsize = x_res * - (dev_drv->overscan.left + dev_drv->overscan.right) / 200; - screen->post_ysize = y_res * - (dev_drv->overscan.top + dev_drv->overscan.bottom) / 200; - - 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(vop_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(vop_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->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->mode.vmode & FB_VMODE_INTERLACED) { - post_dsp_vact_st = screen->post_dsp_sty / 2 + - screen->mode.vsync_len + - screen->mode.upper_margin; - post_dsp_vact_end = post_dsp_vact_st + - screen->post_ysize / 2; - - post_dsp_vact_st_f1 = screen->mode.vsync_len + - screen->mode.upper_margin + - y_res / 2 + - screen->mode.lower_margin + - screen->mode.vsync_len + - screen->mode.upper_margin + - screen->post_dsp_sty / 2 + - 1; - post_dsp_vact_end_f1 = post_dsp_vact_st_f1 + - screen->post_ysize/2; - } else { - 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; - } - 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); - val = V_DSP_HACT_END_POST(post_dsp_hact_end) | - V_DSP_HACT_ST_POST(post_dsp_hact_st); - vop_msk_reg(vop_dev, POST_DSP_HACT_INFO, val); - - val = V_DSP_VACT_END_POST(post_dsp_vact_end) | - V_DSP_VACT_ST_POST(post_dsp_vact_st); - vop_msk_reg(vop_dev, POST_DSP_VACT_INFO, val); - - val = V_POST_HS_FACTOR_YRGB(post_h_fac) | - V_POST_VS_FACTOR_YRGB(post_v_fac); - vop_msk_reg(vop_dev, POST_SCL_FACTOR_YRGB, val); - val = V_DSP_VACT_END_POST(post_dsp_vact_end_f1) | - V_DSP_VACT_ST_POST(post_dsp_vact_st_f1); - vop_msk_reg(vop_dev, POST_DSP_VACT_INFO_F1, val); - val = V_POST_HOR_SD_EN(post_hsd_en) | V_POST_VER_SD_EN(post_vsd_en); - vop_msk_reg(vop_dev, POST_SCL_CTRL, val); - - vop_post_csc_cfg(dev_drv); - - return 0; -} - -static int vop_clr_key_cfg(struct rk_lcdc_driver *dev_drv) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - struct rk_lcdc_win *win; - u32 colorkey_r, colorkey_g, colorkey_b; - int i, key_val; - - for (i = 0; i < dev_drv->lcdc_win_num; 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: - vop_writel(vop_dev, WIN0_COLOR_KEY, key_val); - break; - case 1: - vop_writel(vop_dev, WIN1_COLOR_KEY, key_val); - break; - default: - pr_info("%s:un support win num:%d\n", - __func__, i); - break; - } - } - return 0; -} - -static int vop_alpha_cfg(struct rk_lcdc_driver *dev_drv, int win_id) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - struct rk_lcdc_win *win = dev_drv->win[win_id]; - struct alpha_config alpha_config; - u64 val; - int ppixel_alpha = 0, global_alpha = 0, i; - u32 src_alpha_ctl, dst_alpha_ctl; - int alpha_en = 1; - int layer_count = 0; - - for (i = 0; i < win->area_num; i++) { - ppixel_alpha |= ((win->area[i].format == ARGB888) || - (win->area[i].format == FBDC_ARGB_888) || - (win->area[i].format == FBDC_ABGR_888) || - (win->area[i].format == ABGR888)) ? 1 : 0; - } - - global_alpha = (win->g_alpha_val == 0) ? 0 : 1; - - for (i = 0; i < dev_drv->lcdc_win_num; i++) { - if (dev_drv->win[i]->state) - layer_count++; - } - /* - * vop not support ppixel_alpha mode when only enable 1 layer. - */ - if (layer_count == 1) - ppixel_alpha = 0; - alpha_config.src_global_alpha_val = win->g_alpha_val; - win->alpha_mode = AB_SRC_OVER; - - 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 - alpha_en = 0; - 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 = 0x160; - dst_alpha_ctl = 0x164; - break; - } - val = V_WIN0_DST_FACTOR_MODE(alpha_config.dst_factor_mode); - vop_msk_reg(vop_dev, dst_alpha_ctl, val); - val = V_WIN0_SRC_ALPHA_EN(alpha_en) | - V_WIN0_SRC_COLOR_MODE(alpha_config.src_color_mode) | - V_WIN0_SRC_ALPHA_MODE(alpha_config.src_alpha_mode) | - V_WIN0_SRC_BLEND_MODE(alpha_config.src_global_alpha_mode) | - V_WIN0_SRC_ALPHA_CAL_MODE(alpha_config.src_alpha_cal_m0) | - V_WIN0_SRC_FACTOR_MODE(alpha_config.src_factor_mode) | - V_WIN0_SRC_GLOBAL_ALPHA(alpha_config.src_global_alpha_val); - - vop_msk_reg(vop_dev, src_alpha_ctl, val); - - return 0; -} - -static int vop_axi_gather_cfg(struct vop_device *vop_dev, - struct rk_lcdc_win *win) -{ - u64 val; - u16 yrgb_gather_num = 3; - u16 cbcr_gather_num = 1; - - switch (win->area[0].format) { - case ARGB888: - case XBGR888: - case ABGR888: - yrgb_gather_num = 3; - break; - case RGB888: - case RGB565: - yrgb_gather_num = 2; - break; - case YUV444: - case YUV422: - case YUV420: - case YUV420_NV21: - yrgb_gather_num = 1; - cbcr_gather_num = 2; - break; - default: - dev_err(vop_dev->driver.dev, "%s:un supported format!\n", - __func__); - return -EINVAL; - } - - if ((win->id == 0) || (win->id == 1)) { - val = V_WIN0_YRGB_AXI_GATHER_EN(1) | - V_WIN0_CBR_AXI_GATHER_EN(1) | - V_WIN0_YRGB_AXI_GATHER_NUM(yrgb_gather_num) | - V_WIN0_CBR_AXI_GATHER_NUM(cbcr_gather_num); - vop_msk_reg(vop_dev, WIN0_CTRL1 + (win->id * 0x40), val); - } else if (win->id == 2) { - val = V_HWC_AXI_GATHER_EN(1) | - V_HWC_AXI_GATHER_NUM(yrgb_gather_num); - vop_msk_reg(vop_dev, HWC_CTRL1, val); - } - return 0; -} - -static int vop_win_0_1_reg_update(struct rk_lcdc_driver *dev_drv, int win_id) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - struct rk_lcdc_win *win = dev_drv->win[win_id]; - u64 val; - uint32_t off; - - off = win_id * 0x40; - - if (win->state == 1) { - vop_axi_gather_cfg(vop_dev, win); - 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_MIR_EN(win->mirror_en) | - V_WIN0_Y_MIR_EN(win->mirror_en) | - V_WIN0_UV_SWAP(win->area[0].swap_uv); - vop_msk_reg(vop_dev, WIN0_CTRL0 + off, val); - 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); - vop_msk_reg(vop_dev, WIN0_CTRL1 + off, val); - val = V_WIN0_VIR_STRIDE(win->area[0].y_vir_stride) | - V_WIN0_VIR_STRIDE_UV(win->area[0].uv_vir_stride); - vop_writel(vop_dev, WIN0_VIR + off, val); - val = V_WIN0_ACT_WIDTH(win->area[0].xact - 1) | - V_WIN0_ACT_HEIGHT(win->area[0].yact - 1); - vop_writel(vop_dev, WIN0_ACT_INFO + off, val); - - val = V_WIN0_DSP_WIDTH(win->area[0].xsize - 1) | - V_WIN0_DSP_HEIGHT(win->area[0].ysize - 1); - vop_writel(vop_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); - vop_writel(vop_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); - vop_writel(vop_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); - vop_writel(vop_dev, WIN0_SCL_FACTOR_CBR + off, val); - if (win->alpha_en == 1) { - vop_alpha_cfg(dev_drv, win_id); - } else { - val = V_WIN0_SRC_ALPHA_EN(0); - vop_msk_reg(vop_dev, WIN0_SRC_ALPHA_CTRL + off, val); - } - - if (dev_drv->cur_screen->mode.vmode & FB_VMODE_INTERLACED) { - if (win->area[0].yact == 2 * win->area[0].ysize) - val = V_WIN0_YRGB_DEFLICK(0) | - V_WIN0_CBR_DEFLICK(0); - else - val = V_WIN0_YRGB_DEFLICK(1) | - V_WIN0_CBR_DEFLICK(1); - vop_msk_reg(vop_dev, WIN0_CTRL0, val); - } - } else { - val = V_WIN0_EN(win->state); - vop_msk_reg(vop_dev, WIN0_CTRL0 + off, val); - } - - return 0; -} - -static int vop_hwc_reg_update(struct rk_lcdc_driver *dev_drv, int win_id) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - struct rk_lcdc_win *win = dev_drv->win[win_id]; - unsigned int hwc_size = 0; - u64 val; - - if (win->state == 1) { - vop_axi_gather_cfg(vop_dev, win); - val = V_HWC_EN(1) | V_HWC_DATA_FMT(win->area[0].fmt_cfg) | - V_HWC_RB_SWAP(win->area[0].swap_rb); - vop_msk_reg(vop_dev, HWC_CTRL0, 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(vop_dev->dev, "un supported hwc size!\n"); - - val = V_HWC_SIZE(hwc_size); - vop_msk_reg(vop_dev, HWC_CTRL0, val); - - val = V_HWC_DSP_XST(win->area[0].dsp_stx) | - V_HWC_DSP_YST(win->area[0].dsp_sty); - vop_msk_reg(vop_dev, HWC_DSP_ST, val); - - if (win->alpha_en == 1) { - vop_alpha_cfg(dev_drv, win_id); - } else { - val = V_WIN2_SRC_ALPHA_EN(0); - vop_msk_reg(vop_dev, HWC_SRC_ALPHA_CTRL, val); - } - } else { - val = V_HWC_EN(win->state); - vop_msk_reg(vop_dev, HWC_CTRL0, val); - } - - return 0; -} - -static int vop_layer_update_regs(struct vop_device *vop_dev, - struct rk_lcdc_win *win) -{ - struct rk_lcdc_driver *dev_drv = &vop_dev->driver; - - if (likely(vop_dev->clk_on)) { - vop_msk_reg(vop_dev, SYS_CTRL, - V_VOP_STANDBY_EN(vop_dev->standby)); - if ((win->id == 0) || (win->id == 1)) - vop_win_0_1_reg_update(dev_drv, win->id); - else if (win->id == 2) - vop_hwc_reg_update(dev_drv, win->id); - vop_cfg_done(vop_dev); - } - - DBG(2, "%s for lcdc%d\n", __func__, vop_dev->id); - return 0; -} - -static int __maybe_unused vop_mmu_en(struct rk_lcdc_driver *dev_drv) -{ - u64 val; - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - - if (unlikely(!vop_dev->clk_on)) { - pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on); - return 0; - } -#if defined(CONFIG_ROCKCHIP_IOMMU) - if (dev_drv->iommu_enabled) { - if (!vop_dev->iommu_status && dev_drv->mmu_dev) { - if (likely(vop_dev->clk_on)) { - val = V_VOP_MMU_EN(1); - vop_msk_reg(vop_dev, SYS_CTRL, val); - val = V_AXI_OUTSTANDING_MAX_NUM(31) | - V_AXI_MAX_OUTSTANDING_EN(1); - vop_msk_reg(vop_dev, SYS_CTRL1, val); - } - vop_dev->iommu_status = 1; - rockchip_iovmm_activate(dev_drv->dev); - } - } -#endif - return 0; -} - -static int vop_set_dclk(struct rk_lcdc_driver *dev_drv, int reset_rate) -{ - int ret = 0, fps = 0; - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - struct rk_screen *screen = dev_drv->cur_screen; -#ifdef CONFIG_RK_FPGA - return 0; -#endif - if (reset_rate) - ret = clk_set_rate(vop_dev->dclk, screen->mode.pixclock); - if (ret) - dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", vop_dev->id); - vop_dev->pixclock = - div_u64(1000000000000llu, clk_get_rate(vop_dev->dclk)); - vop_dev->driver.pixclock = vop_dev->pixclock; - - fps = rk_fb_calc_fps(screen, vop_dev->pixclock); - screen->ft = 1000 / fps; - dev_info(vop_dev->dev, "%s: dclk:%lu>>fps:%d ", - vop_dev->driver.name, clk_get_rate(vop_dev->dclk), fps); - return 0; -} - -static int vop_config_timing(struct rk_lcdc_driver *dev_drv) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_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; - u64 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; - - val = V_DSP_HS_END(hsync_len) | V_DSP_HTOTAL(h_total); - vop_msk_reg(vop_dev, DSP_HTOTAL_HS_END, val); - - val = V_DSP_HACT_END(hsync_len + left_margin + x_res) | - V_DSP_HACT_ST(hsync_len + left_margin); - vop_msk_reg(vop_dev, DSP_HACT_ST_END, val); - - if (screen->mode.vmode & FB_VMODE_INTERLACED) { - /* First Field Timing */ - val = V_DSP_VS_END(vsync_len) | - V_DSP_VTOTAL(2 * (vsync_len + upper_margin + - lower_margin) + y_res + 1); - vop_msk_reg(vop_dev, DSP_VTOTAL_VS_END, val); - - val = V_DSP_VACT_END(vsync_len + upper_margin + y_res / 2) | - V_DSP_VACT_ST(vsync_len + upper_margin); - vop_msk_reg(vop_dev, DSP_VACT_ST_END, val); - - /* Second Field Timing */ - 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); - vop_msk_reg(vop_dev, DSP_VS_ST_END_F1, val); - - 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_VACT_ST_F1(vact_st_f1); - vop_msk_reg(vop_dev, DSP_VACT_ST_END_F1, val); - vop_msk_reg(vop_dev, DSP_CTRL0, - V_DSP_INTERLACE(1) | V_DSP_FIELD_POL(0)); - val = V_WIN0_INTERLACE_READ(1) | V_WIN0_YRGB_DEFLICK(0) | - V_WIN0_CBR_DEFLICK(0); - vop_msk_reg(vop_dev, WIN0_CTRL0, val); - - val = V_WIN1_INTERLACE_READ(1) | V_WIN1_YRGB_DEFLICK(0) | - V_WIN1_CBR_DEFLICK(0); - vop_msk_reg(vop_dev, WIN1_CTRL0, val); - - val = V_WIN2_INTERLACE_READ(1); - vop_msk_reg(vop_dev, WIN2_CTRL0, val); - - val = V_WIN3_INTERLACE_READ(1); - vop_msk_reg(vop_dev, WIN3_CTRL0, val); - - val = V_HWC_INTERLACE_READ(1); - vop_msk_reg(vop_dev, HWC_CTRL0, val); - - val = V_DSP_LINE_FLAG_NUM_0(vact_end_f1) | - V_DSP_LINE_FLAG_NUM_1(vact_end_f1); - vop_msk_reg(vop_dev, LINE_FLAG, val); - } else { - val = V_DSP_VS_END(vsync_len) | V_DSP_VTOTAL(v_total); - vop_msk_reg(vop_dev, DSP_VTOTAL_VS_END, val); - - val = V_DSP_VACT_END(vsync_len + upper_margin + y_res) | - V_DSP_VACT_ST(vsync_len + upper_margin); - vop_msk_reg(vop_dev, DSP_VACT_ST_END, val); - - vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_INTERLACE(0) | - V_DSP_FIELD_POL(0)); - - val = V_WIN0_INTERLACE_READ(0) | V_WIN0_YRGB_DEFLICK(0) | - V_WIN0_CBR_DEFLICK(0); - vop_msk_reg(vop_dev, WIN0_CTRL0, val); - - val = V_WIN1_INTERLACE_READ(0) | V_WIN1_YRGB_DEFLICK(0) | - V_WIN1_CBR_DEFLICK(0); - vop_msk_reg(vop_dev, WIN1_CTRL0, val); - - val = V_WIN2_INTERLACE_READ(0); - vop_msk_reg(vop_dev, WIN2_CTRL0, val); - - val = V_WIN3_INTERLACE_READ(0); - vop_msk_reg(vop_dev, WIN3_CTRL0, val); - - val = V_HWC_INTERLACE_READ(0); - vop_msk_reg(vop_dev, HWC_CTRL0, val); - - val = V_DSP_LINE_FLAG_NUM_0(vsync_len + upper_margin + y_res) | - V_DSP_LINE_FLAG_NUM_1(vsync_len + upper_margin + y_res); - vop_msk_reg(vop_dev, LINE_FLAG, val); - } - vop_post_cfg(dev_drv); - - return 0; -} - -static void vop_bcsh_path_sel(struct rk_lcdc_driver *dev_drv) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - u32 bcsh_ctrl; - - vop_msk_reg(vop_dev, SYS_CTRL, V_OVERLAY_MODE(dev_drv->overlay_mode)); - if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) { - if (dev_drv->output_color == COLOR_YCBCR) /* bypass */ - vop_msk_reg(vop_dev, BCSH_CTRL, - V_BCSH_Y2R_EN(0) | V_BCSH_R2Y_EN(0)); - else /* YUV2RGB */ - vop_msk_reg(vop_dev, BCSH_CTRL, 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 = vop_readl(vop_dev, BCSH_CTRL); - if (((bcsh_ctrl & MASK(BCSH_EN)) == 1) || - (dev_drv->bcsh.enable == 1))/*bcsh enabled */ - vop_msk_reg(vop_dev, BCSH_CTRL, - V_BCSH_R2Y_EN(1) | - V_BCSH_Y2R_EN(1)); - else - vop_msk_reg(vop_dev, BCSH_CTRL, - V_BCSH_R2Y_EN(0) | - V_BCSH_Y2R_EN(0)); - } else { - /* RGB2YUV */ - vop_msk_reg(vop_dev, BCSH_CTRL, - V_BCSH_R2Y_EN(1) | - V_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG) | - V_BCSH_Y2R_EN(0)); - } - } -} - -static int vop_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact, - u16 *yact, int *format, u32 *dsp_addr) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - u32 val; - - spin_lock(&vop_dev->reg_lock); - - val = vop_readl(vop_dev, WIN0_ACT_INFO); - *xact = (val & MASK(WIN0_ACT_WIDTH)) + 1; - *yact = ((val & MASK(WIN0_ACT_HEIGHT))>>16) + 1; - - val = vop_readl(vop_dev, WIN0_CTRL0); - *format = (val & MASK(WIN0_DATA_FMT)) >> 1; - *dsp_addr = vop_readl(vop_dev, WIN0_YRGB_MST); - - spin_unlock(&vop_dev->reg_lock); - - return 0; -} - -static int vop_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst, - int format, u16 xact, u16 yact, u16 xvir) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - int swap = (format == RGB888) ? 1 : 0; - u64 val; - - val = V_WIN0_DATA_FMT(format) | V_WIN0_RB_SWAP(swap); - vop_msk_reg(vop_dev, WIN0_CTRL0, val); - - vop_msk_reg(vop_dev, WIN0_VIR, V_WIN0_VIR_STRIDE(xvir)); - vop_writel(vop_dev, WIN0_ACT_INFO, V_WIN0_ACT_WIDTH(xact - 1) | - V_WIN0_ACT_HEIGHT(yact - 1)); - - vop_writel(vop_dev, WIN0_YRGB_MST, rgb_mst); - - vop_cfg_done(vop_dev); - - return 0; -} - -/* -static int lcdc_reset(struct rk_lcdc_driver *dev_drv, bool initscreen) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - u64 val; - u32 __maybe_unused v; - - if (!vop_dev->standby && initscreen && (dev_drv->first_frame != 1)) { - mdelay(150); - val = V_WIN0_EN(0); - vop_msk_reg(vop_dev, WIN0_CTRL0, val); - vop_msk_reg(vop_dev, WIN1_CTRL0, val); - - 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); - vop_msk_reg(vop_dev, WIN2_CTRL0, val); - vop_msk_reg(vop_dev, WIN3_CTRL0, val); - val = V_HDMI_OUT_EN(0); - vop_msk_reg(vop_dev, SYS_CTRL, val); - vop_cfg_done(vop_dev); - mdelay(50); - vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(1)); - writel_relaxed(0, vop_dev->regs + REG_CFG_DONE); - mdelay(50); - } - - return 0; -} -*/ - -static int vop_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) -{ - u16 face = 0; - u16 dclk_ddr = 0; - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - struct rk_screen *screen = dev_drv->cur_screen; - u64 val; - - if (unlikely(!vop_dev->clk_on)) { - pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on); - return 0; - } - - if (!vop_dev->standby && initscreen && (dev_drv->first_frame != 1)) - flush_kthread_worker(&dev_drv->update_regs_worker); - - spin_lock(&vop_dev->reg_lock); - if (likely(vop_dev->clk_on)) { - switch (screen->face) { - case OUT_P888: - face = OUT_P888; - val = V_DITHER_DOWN_EN(0); - break; - case OUT_YUV_420: - /*yuv420 output prefer yuv domain overlay */ - face = OUT_YUV_420; - dclk_ddr = 1; - val = V_DITHER_DOWN_EN(0); - break; - default: - dev_err(vop_dev->dev, "un supported interface!\n"); - break; - } - - vop_msk_reg(vop_dev, DSP_CTRL1, val); - switch (screen->type) { - case SCREEN_TVOUT: - val = V_SW_UV_OFFSET_EN(1) | V_SW_IMD_TVE_DCLK_EN(1) | - V_SW_IMD_TVE_DCLK_EN(1) | - V_SW_IMD_TVE_DCLK_POL(1) | - V_SW_GENLOCK(1) | V_SW_DAC_SEL(1); - if (screen->mode.xres == 720 && - screen->mode.yres == 576) - val |= V_SW_TVE_MODE(1); - else - val |= V_SW_TVE_MODE(0); - vop_msk_reg(vop_dev, SYS_CTRL, val); - break; - case SCREEN_HDMI: - val = V_HDMI_OUT_EN(1) | V_SW_UV_OFFSET_EN(0); - vop_msk_reg(vop_dev, SYS_CTRL, val); - break; - default: - dev_err(vop_dev->dev, "un supported interface!\n"); - break; - } - 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); - /*hsync vsync den dclk polo,dither */ - vop_msk_reg(vop_dev, DSP_CTRL1, val); - - if (screen->color_mode == COLOR_RGB) - dev_drv->overlay_mode = VOP_RGB_DOMAIN; - else - dev_drv->overlay_mode = VOP_YUV_DOMAIN; - -#ifndef CONFIG_RK_FPGA - /* - * Todo: - * writel_relaxed(v, RK_GRF_VIRT + vop_GRF_SOC_CON7); - * move to lvds driver - */ - /*GRF_SOC_CON7 bit[15]:0->dsi/lvds mode,1->ttl mode */ -#endif - 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); - if (screen->pixelrepeat) - val |= V_SW_CORE_DCLK_SEL(1); - if (screen->mode.vmode & FB_VMODE_INTERLACED) - val |= V_SW_HDMI_CLK_I_SEL(1); - vop_msk_reg(vop_dev, DSP_CTRL0, val); - /* BG color */ - if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) - val = V_DSP_BG_BLUE(0x80) | V_DSP_BG_GREEN(0x10) | - V_DSP_BG_RED(0x80); - else - val = V_DSP_BG_BLUE(0) | V_DSP_BG_GREEN(0) | - V_DSP_BG_RED(0); - vop_msk_reg(vop_dev, DSP_BG, val); - dev_drv->output_color = screen->color_mode; - vop_bcsh_path_sel(dev_drv); - vop_config_timing(dev_drv); - vop_cfg_done(vop_dev); - } - spin_unlock(&vop_dev->reg_lock); - vop_set_dclk(dev_drv, 1); - if (screen->type != SCREEN_HDMI && screen->type != SCREEN_TVOUT && - dev_drv->trsm_ops && dev_drv->trsm_ops->enable) - dev_drv->trsm_ops->enable(); - if (screen->init) - screen->init(); - - return 0; -} - -/*enable layer,open:1,enable;0 disable*/ -static void vop_layer_enable(struct vop_device *vop_dev, - unsigned int win_id, bool open) -{ - spin_lock(&vop_dev->reg_lock); - if (likely(vop_dev->clk_on) && - vop_dev->driver.win[win_id]->state != open) { - if (open) { - if (!vop_dev->atv_layer_cnt) { - dev_info(vop_dev->dev, - "wakeup from standby!\n"); - vop_dev->standby = 0; - } - vop_dev->atv_layer_cnt |= (1 << win_id); - } else { - if (vop_dev->atv_layer_cnt & (1 << win_id)) - vop_dev->atv_layer_cnt &= ~(1 << win_id); - } - vop_dev->driver.win[win_id]->state = open; - if (!open) { - vop_layer_update_regs(vop_dev, - vop_dev->driver.win[win_id]); - vop_cfg_done(vop_dev); - } - /* if no layer used,disable lcdc */ - if (!vop_dev->atv_layer_cnt) { - dev_info(vop_dev->dev, - "no layer is used,go to standby!\n"); - vop_dev->standby = 1; - } - } - spin_unlock(&vop_dev->reg_lock); -} - -static int vop_enable_irq(struct rk_lcdc_driver *dev_drv) -{ - struct vop_device *vop_dev = container_of(dev_drv, - struct vop_device, driver); - u64 val; - /* struct rk_screen *screen = dev_drv->cur_screen; */ - - vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, INTR_MASK); - - val = INTR_FS | INTR_LINE_FLAG0 | INTR_BUS_ERROR | INTR_LINE_FLAG1; - vop_mask_writel(vop_dev, INTR_EN0, INTR_MASK, val); - - return 0; -} - -static int vop_open(struct rk_lcdc_driver *dev_drv, int win_id, - bool open) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - - /* enable clk,when first layer open */ - if ((open) && (!vop_dev->atv_layer_cnt)) { - /* rockchip_set_system_status(sys_status); */ - vop_pre_init(dev_drv); - vop_clk_enable(vop_dev); - vop_enable_irq(dev_drv); -#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; - } - } - } -#endif - if ((support_uboot_display() && (vop_dev->prop == PRMRY))) - vop_set_dclk(dev_drv, 0); - else - vop_load_screen(dev_drv, 1); - if (dev_drv->bcsh.enable) - vop_set_bcsh(dev_drv, 1); - spin_lock(&vop_dev->reg_lock); - spin_unlock(&vop_dev->reg_lock); - } - - if (win_id < ARRAY_SIZE(vop_win)) - vop_layer_enable(vop_dev, win_id, open); - else - dev_err(vop_dev->dev, "invalid win id:%d\n", win_id); - - dev_drv->first_frame = 0; - return 0; -} - -static int win_0_1_display(struct vop_device *vop_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", - vop_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(&vop_dev->reg_lock); - if (likely(vop_dev->clk_on)) { - win->area[0].y_addr = y_addr; - win->area[0].uv_addr = uv_addr; - vop_writel(vop_dev, WIN0_YRGB_MST + off, win->area[0].y_addr); - vop_writel(vop_dev, WIN0_CBR_MST + off, win->area[0].uv_addr); - } - spin_unlock(&vop_dev->reg_lock); - - return 0; -} - -static int hwc_display(struct vop_device *vop_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", - vop_dev->id, __func__, y_addr); - spin_lock(&vop_dev->reg_lock); - if (likely(vop_dev->clk_on)) { - win->area[0].y_addr = y_addr; - vop_writel(vop_dev, HWC_MST, win->area[0].y_addr); - } - spin_unlock(&vop_dev->reg_lock); - - return 0; -} - -static int vop_pan_display(struct rk_lcdc_driver *dev_drv, int win_id) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - struct rk_lcdc_win *win = NULL; - struct rk_screen *screen = dev_drv->cur_screen; - - win = dev_drv->win[win_id]; - if (!screen) { - dev_err(dev_drv->dev, "screen is null!\n"); - return -ENOENT; - } - if (unlikely(!vop_dev->clk_on)) { - pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on); - return 0; - } - if (win_id == 0) { - win_0_1_display(vop_dev, win); - } else if (win_id == 1) { - win_0_1_display(vop_dev, win); - } else if (win_id == 2) { - hwc_display(vop_dev, win); - } else { - dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id); - return -EINVAL; - } - - return 0; -} - -static int vop_cal_scl_fac(struct rk_lcdc_win *win, struct rk_screen *screen) -{ - 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; - if ((screen->mode.vmode & FB_VMODE_INTERLACED) && - (win->area[0].yact == 2 * win->area[0].ysize)) { - srcH = win->area[0].yact / 2; - yrgb_vsd_bil_gt2 = 1; - cbcr_vsd_bil_gt2 = 1; - } else { - 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: - case YUV420_NV21: - 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; - - /* line buffer mode */ - if ((win->area[0].format == YUV422) || - (win->area[0].format == YUV420) || - (win->area[0].format == YUV420_NV21) || - (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) - win->yrgb_vsd_mode = SCALE_DOWN_BIL; - if (screen->mode.vmode & FB_VMODE_INTERLACED) { - /* interlace mode must bill */ - win->yrgb_vsd_mode = SCALE_DOWN_BIL; - win->cbr_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; - } - - /* (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 = - vop_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 less 0x2000"); - pr_err("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 = - vop_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 dsp_x_pos(int mirror_en, struct rk_screen *screen, - struct rk_lcdc_win_area *area) -{ - int pos; - - if (screen->x_mirror && mirror_en) - pr_err("not support both win and global mirror\n"); - - if ((!mirror_en) && (!screen->x_mirror)) - pos = area->xpos + screen->mode.left_margin + - screen->mode.hsync_len; - else - pos = screen->mode.xres - area->xpos - - area->xsize + screen->mode.left_margin + - screen->mode.hsync_len; - - return pos; -} - -static int dsp_y_pos(int mirror_en, struct rk_screen *screen, - struct rk_lcdc_win_area *area) -{ - int pos; - - if (screen->y_mirror && mirror_en) - pr_err("not support both win and global mirror\n"); - if (screen->mode.vmode & FB_VMODE_NONINTERLACED) { - if ((!mirror_en) && (!screen->y_mirror)) - pos = area->ypos + screen->mode.upper_margin + - screen->mode.vsync_len; - else - pos = screen->mode.yres - area->ypos - - area->ysize + screen->mode.upper_margin + - screen->mode.vsync_len; - } else if (screen->mode.vmode & FB_VMODE_INTERLACED) { - pos = area->ypos / 2 + screen->mode.upper_margin + - screen->mode.vsync_len; - } - - return pos; -} - -static int win_0_1_set_par(struct vop_device *vop_dev, - struct rk_screen *screen, struct rk_lcdc_win *win) -{ - u32 xact, yact, xvir, yvir, xpos, ypos; - u8 fmt_cfg = 0, swap_rb, swap_uv = 0; - char fmt[9] = "NULL"; - - xpos = dsp_x_pos(win->mirror_en, screen, &win->area[0]); - ypos = dsp_y_pos(win->mirror_en, screen, &win->area[0]); - - spin_lock(&vop_dev->reg_lock); - if (likely(vop_dev->clk_on)) { - vop_cal_scl_fac(win, screen); - switch (win->area[0].format) { - case FBDC_RGB_565: - fmt_cfg = 2; - swap_rb = 0; - win->fmt_10 = 0; - win->area[0].fbdc_fmt_cfg = 0x05; - break; - case FBDC_ARGB_888: - fmt_cfg = 0; - swap_rb = 0; - win->fmt_10 = 0; - win->area[0].fbdc_fmt_cfg = 0x0c; - break; - case FBDC_ABGR_888: - fmt_cfg = 0; - swap_rb = 1; - win->fmt_10 = 0; - win->area[0].fbdc_fmt_cfg = 0x0c; - break; - case FBDC_RGBX_888: - fmt_cfg = 0; - swap_rb = 0; - win->fmt_10 = 0; - win->area[0].fbdc_fmt_cfg = 0x3a; - break; - 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 YUV420_NV21: - fmt_cfg = 4; - swap_rb = 0; - swap_uv = 1; - 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(vop_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].swap_uv = swap_uv; - 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; - } - vop_win_0_1_reg_update(&vop_dev->driver, win->id); - spin_unlock(&vop_dev->reg_lock); - - DBG(1, "lcdc[%d]:win[%d]\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d", - vop_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 hwc_set_par(struct vop_device *vop_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(&vop_dev->reg_lock); - if (likely(vop_dev->clk_on)) { - 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(vop_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; - } - vop_hwc_reg_update(&vop_dev->driver, 4); - spin_unlock(&vop_dev->reg_lock); - - DBG(1, "lcdc[%d]:hwc>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d", - vop_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 vop_set_par(struct rk_lcdc_driver *dev_drv, int win_id) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - struct rk_lcdc_win *win = NULL; - struct rk_screen *screen = dev_drv->cur_screen; - - if (unlikely(!vop_dev->clk_on)) { - pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on); - return 0; - } - win = dev_drv->win[win_id]; - switch (win_id) { - case 0: - win_0_1_set_par(vop_dev, screen, win); - break; - case 1: - win_0_1_set_par(vop_dev, screen, win); - break; - case 2: - hwc_set_par(vop_dev, screen, win); - break; - default: - dev_err(dev_drv->dev, "unsupported win number:%d\n", win_id); - break; - } - return 0; -} - -static int vop_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd, - unsigned long arg, int win_id) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_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] = vop_dev->screen->mode.xres; - panel_size[1] = vop_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; - vop_clr_key_cfg(dev_drv); - vop_writel(vop_dev, WIN0_COLOR_KEY, - clr_key_cfg.win0_color_key_cfg); - vop_writel(vop_dev, WIN1_COLOR_KEY, - clr_key_cfg.win1_color_key_cfg); - break; - - default: - break; - } - return 0; -} - -static int vop_get_backlight_device(struct rk_lcdc_driver *dev_drv) -{ - struct vop_device *vop_dev = container_of(dev_drv, - struct vop_device, driver); - struct device_node *backlight; - struct property *prop; - u32 *brightness_levels; - u32 length, max, last; - - if (vop_dev->backlight) - return 0; - backlight = of_parse_phandle(vop_dev->dev->of_node, "backlight", 0); - if (backlight) { - vop_dev->backlight = of_find_backlight_by_node(backlight); - if (!vop_dev->backlight) - dev_info(vop_dev->dev, "No find backlight device\n"); - } else { - dev_info(vop_dev->dev, "No find backlight device node\n"); - } - prop = of_find_property(backlight, "brightness-levels", &length); - if (!prop) - return -EINVAL; - max = length / sizeof(u32); - last = max - 1; - brightness_levels = kmalloc(256, GFP_KERNEL); - if (brightness_levels) - return -ENOMEM; - - if (!of_property_read_u32_array(backlight, "brightness-levels", - brightness_levels, max)) { - if (brightness_levels[0] > brightness_levels[last]) - dev_drv->cabc_pwm_pol = 1;/*negative*/ - else - dev_drv->cabc_pwm_pol = 0;/*positive*/ - } else { - dev_info(vop_dev->dev, - "Can not read brightness-levels value\n"); - } - - kfree(brightness_levels); - - return 0; -} - -static int vop_early_suspend(struct rk_lcdc_driver *dev_drv) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - - if (dev_drv->suspend_flag) - return 0; - - dev_drv->suspend_flag = 1; - flush_kthread_worker(&dev_drv->update_regs_worker); - - if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable) - dev_drv->trsm_ops->disable(); - - if (likely(vop_dev->clk_on)) { - spin_lock(&vop_dev->reg_lock); - vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLANK_EN(1)); - vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, INTR_MASK); - vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_OUT_ZERO(1)); - vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(1)); - vop_cfg_done(vop_dev); - - if (dev_drv->iommu_enabled && dev_drv->mmu_dev) - rockchip_iovmm_deactivate(dev_drv->dev); - - spin_unlock(&vop_dev->reg_lock); - } - - vop_clk_disable(vop_dev); - rk_disp_pwr_disable(dev_drv); - - return 0; -} - -static int vop_early_resume(struct rk_lcdc_driver *dev_drv) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - - if (!dev_drv->suspend_flag) - return 0; - rk_disp_pwr_enable(dev_drv); - - vop_clk_enable(vop_dev); - memcpy(vop_dev->regs, vop_dev->regsbak, vop_dev->len); - - spin_lock(&vop_dev->reg_lock); - - vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_OUT_ZERO(0)); - vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(0)); - vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLANK_EN(0)); - vop_cfg_done(vop_dev); - spin_unlock(&vop_dev->reg_lock); - - if (dev_drv->iommu_enabled && dev_drv->mmu_dev) { - /* win address maybe effect after next frame start, - * but mmu maybe effect right now, so we delay 50ms - */ - mdelay(50); - rockchip_iovmm_activate(dev_drv->dev); - } - - dev_drv->suspend_flag = 0; - - if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable) - dev_drv->trsm_ops->enable(); - - return 0; -} - -static int vop_blank(struct rk_lcdc_driver *dev_drv, int win_id, int blank_mode) -{ - switch (blank_mode) { - case FB_BLANK_UNBLANK: - vop_early_resume(dev_drv); - break; - case FB_BLANK_NORMAL: - vop_early_suspend(dev_drv); - break; - default: - vop_early_suspend(dev_drv); - break; - } - - dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode); - - return 0; -} - -static int vop_get_win_state(struct rk_lcdc_driver *dev_drv, - int win_id, int area_id) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - u32 area_status = 0, state = 0; - - switch (win_id) { - case 0: - area_status = vop_read_bit(vop_dev, WIN0_CTRL0, V_WIN0_EN(0)); - break; - case 1: - area_status = vop_read_bit(vop_dev, WIN1_CTRL0, V_WIN1_EN(0)); - break; - case 2: - area_status = vop_read_bit(vop_dev, HWC_CTRL0, V_HWC_EN(0)); - break; - default: - pr_err("!!!%s,win[%d]area[%d],unsupport!!!\n", - __func__, win_id, area_id); - break; - } - - state = (area_status > 0) ? 1 : 0; - return state; -} - -static int vop_get_area_num(struct rk_lcdc_driver *dev_drv, - unsigned int *area_support) -{ - area_support[0] = 1; - area_support[1] = 1; - - return 0; -} - -/*overlay will be do at regupdate*/ -static int vop_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap, bool set) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - struct rk_lcdc_win *win = NULL; - int i, ovl; - u64 val; - int z_order_num = 0; - int layer0_sel, layer1_sel, layer2_sel, layer3_sel; - - if (swap == 0) { - for (i = 0; i < dev_drv->lcdc_win_num; i++) { - win = dev_drv->win[i]; - if (win->state == 1) - z_order_num++; - } - for (i = 0; i < dev_drv->lcdc_win_num; 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(&vop_dev->reg_lock); - if (vop_dev->clk_on) { - if (set) { - 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); - vop_msk_reg(vop_dev, DSP_CTRL1, val); - } else { - layer0_sel = vop_read_bit(vop_dev, DSP_CTRL1, - V_DSP_LAYER0_SEL(0)); - layer1_sel = vop_read_bit(vop_dev, DSP_CTRL1, - V_DSP_LAYER1_SEL(0)); - layer2_sel = vop_read_bit(vop_dev, DSP_CTRL1, - V_DSP_LAYER2_SEL(0)); - layer3_sel = vop_read_bit(vop_dev, DSP_CTRL1, - V_DSP_LAYER3_SEL(0)); - ovl = layer3_sel * 1000 + layer2_sel * 100 + - layer1_sel * 10 + layer0_sel; - } - } else { - ovl = -EPERM; - } - spin_unlock(&vop_dev->reg_lock); - - return ovl; -} - -static char *vop_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 vop_get_disp_info(struct rk_lcdc_driver *dev_drv, - char *buf, int win_id) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_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 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; - u8 w0_state, w1_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 dclk_freq; - int size = 0; - - dclk_freq = screen->mode.pixclock; - /*vop_reg_dump(dev_drv); */ - - spin_lock(&vop_dev->reg_lock); - if (vop_dev->clk_on) { - zorder = vop_readl(vop_dev, DSP_CTRL1); - layer0_sel = (zorder & MASK(DSP_LAYER0_SEL)) >> 8; - layer1_sel = (zorder & MASK(DSP_LAYER1_SEL)) >> 10; - /* WIN0 */ - win_ctrl = vop_readl(vop_dev, WIN0_CTRL0); - w0_state = win_ctrl & MASK(WIN0_EN); - fmt_id = (win_ctrl & MASK(WIN0_DATA_FMT)) >> 1; - vop_format_to_string(fmt_id, format_w0); - vir_info = vop_readl(vop_dev, WIN0_VIR); - act_info = vop_readl(vop_dev, WIN0_ACT_INFO); - dsp_info = vop_readl(vop_dev, WIN0_DSP_INFO); - dsp_st = vop_readl(vop_dev, WIN0_DSP_ST); - y_factor = vop_readl(vop_dev, WIN0_SCL_FACTOR_YRGB); - uv_factor = vop_readl(vop_dev, WIN0_SCL_FACTOR_CBR); - w0_vir_y = vir_info & MASK(WIN0_VIR_STRIDE); - w0_vir_uv = (vir_info & MASK(WIN0_VIR_STRIDE_UV)) >> 16; - w0_act_x = (act_info & MASK(WIN0_ACT_WIDTH)) + 1; - w0_act_y = ((act_info & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1; - w0_dsp_x = (dsp_info & MASK(WIN0_DSP_WIDTH)) + 1; - w0_dsp_y = ((dsp_info & MASK(WIN0_DSP_HEIGHT)) >> 16) + 1; - if (w0_state) { - w0_st_x = dsp_st & MASK(WIN0_DSP_XST); - w0_st_y = (dsp_st & MASK(WIN0_DSP_YST)) >> 16; - } - w0_y_h_fac = y_factor & MASK(WIN0_HS_FACTOR_YRGB); - w0_y_v_fac = (y_factor & MASK(WIN0_VS_FACTOR_YRGB)) >> 16; - w0_uv_h_fac = uv_factor & MASK(WIN0_HS_FACTOR_CBR); - w0_uv_v_fac = (uv_factor & MASK(WIN0_VS_FACTOR_CBR)) >> 16; - - /* WIN1 */ - win_ctrl = vop_readl(vop_dev, WIN1_CTRL0); - w1_state = win_ctrl & MASK(WIN1_EN); - fmt_id = (win_ctrl & MASK(WIN1_DATA_FMT)) >> 1; - vop_format_to_string(fmt_id, format_w1); - vir_info = vop_readl(vop_dev, WIN1_VIR); - act_info = vop_readl(vop_dev, WIN1_ACT_INFO); - dsp_info = vop_readl(vop_dev, WIN1_DSP_INFO); - dsp_st = vop_readl(vop_dev, WIN1_DSP_ST); - y_factor = vop_readl(vop_dev, WIN1_SCL_FACTOR_YRGB); - uv_factor = vop_readl(vop_dev, WIN1_SCL_FACTOR_CBR); - w1_vir_y = vir_info & MASK(WIN1_VIR_STRIDE); - w1_vir_uv = (vir_info & MASK(WIN1_VIR_STRIDE_UV)) >> 16; - w1_act_x = (act_info & MASK(WIN1_ACT_WIDTH)) + 1; - w1_act_y = ((act_info & MASK(WIN1_ACT_HEIGHT)) >> 16) + 1; - w1_dsp_x = (dsp_info & MASK(WIN1_DSP_WIDTH)) + 1; - w1_dsp_y = ((dsp_info & MASK(WIN1_DSP_HEIGHT)) >> 16) + 1; - if (w1_state) { - w1_st_x = dsp_st & MASK(WIN1_DSP_XST); - w1_st_y = (dsp_st & MASK(WIN1_DSP_YST)) >> 16; - } - w1_y_h_fac = y_factor & MASK(WIN1_HS_FACTOR_YRGB); - w1_y_v_fac = (y_factor & MASK(WIN1_VS_FACTOR_YRGB)) >> 16; - w1_uv_h_fac = uv_factor & MASK(WIN1_HS_FACTOR_CBR); - w1_uv_v_fac = (uv_factor & MASK(WIN1_VS_FACTOR_CBR)) >> 16; - } else { - spin_unlock(&vop_dev->reg_lock); - return -EPERM; - } - spin_unlock(&vop_dev->reg_lock); - size += snprintf(dsp_buf, 80, - "z-order:\n win[%d]\n win[%d]\n", - 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, vop_readl(vop_dev, WIN0_YRGB_MST), - vop_readl(vop_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, vop_readl(vop_dev, WIN1_YRGB_MST), - vop_readl(vop_dev, WIN1_CBR_MST)); - strcat(buf, dsp_buf); - memset(dsp_buf, 0, sizeof(dsp_buf)); - - return size; -} - -static int vop_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps, bool set) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_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(vop_dev->dclk, dotclk); - } - - pixclock = div_u64(1000000000000llu, clk_get_rate(vop_dev->dclk)); - vop_dev->pixclock = pixclock; - dev_drv->pixclock = vop_dev->pixclock; - fps = rk_fb_calc_fps(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(vop_dev->dclk), fps); - - return fps; -} - -static int vop_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 vop_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 vop_config_done(struct rk_lcdc_driver *dev_drv) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - int i; - u64 val; - struct rk_lcdc_win *win = NULL; - - spin_lock(&vop_dev->reg_lock); - vop_post_cfg(dev_drv); - vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(vop_dev->standby)); - for (i = 0; i < dev_drv->lcdc_win_num; i++) { - win = dev_drv->win[i]; - if ((win->state == 0) && (win->last_state == 1)) { - switch (win->id) { - case 0: - val = V_WIN0_EN(0); - vop_msk_reg(vop_dev, WIN0_CTRL0, val); - break; - case 1: - val = V_WIN1_EN(0); - vop_msk_reg(vop_dev, WIN1_CTRL0, val); - break; - case 2: - val = V_HWC_EN(0); - vop_msk_reg(vop_dev, HWC_CTRL0, val); - break; - default: - break; - } - } - win->last_state = win->state; - } - vop_cfg_done(vop_dev); - spin_unlock(&vop_dev->reg_lock); - return 0; -} - -static int vop_dpi_open(struct rk_lcdc_driver *dev_drv, bool open) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - spin_lock(&vop_dev->reg_lock); - vop_msk_reg(vop_dev, SYS_CTRL, V_DIRECT_PATH_EN(open)); - vop_cfg_done(vop_dev); - spin_unlock(&vop_dev->reg_lock); - return 0; -} - -static int vop_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id) -{ - struct vop_device *vop_dev = container_of(dev_drv, - struct vop_device, driver); - spin_lock(&vop_dev->reg_lock); - vop_msk_reg(vop_dev, SYS_CTRL, V_DIRECT_PATH_LAYER_SEL(win_id)); - vop_cfg_done(vop_dev); - spin_unlock(&vop_dev->reg_lock); - return 0; -} - -static int vop_dpi_status(struct rk_lcdc_driver *dev_drv) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - int ovl; - - spin_lock(&vop_dev->reg_lock); - ovl = vop_read_bit(vop_dev, SYS_CTRL, V_DIRECT_PATH_EN(0)); - spin_unlock(&vop_dev->reg_lock); - return ovl; -} - -static int vop_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv, int enable) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - if (enable) - enable_irq(vop_dev->irq); - else - disable_irq(vop_dev->irq); - return 0; -} - -int vop_poll_vblank(struct rk_lcdc_driver *dev_drv) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - u32 int_reg; - int ret; - - if (vop_dev->clk_on && (!dev_drv->suspend_flag)) { - int_reg = vop_readl(vop_dev, INTR_STATUS0); - if (int_reg & INTR_LINE_FLAG0) { - vop_dev->driver.frame_time.last_framedone_t = - vop_dev->driver.frame_time.framedone_t; - vop_dev->driver.frame_time.framedone_t = cpu_clock(0); - vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_LINE_FLAG0, - INTR_LINE_FLAG0); - ret = RK_LF_STATUS_FC; - } else { - ret = RK_LF_STATUS_FR; - } - } else { - ret = RK_LF_STATUS_NC; - } - - return ret; -} - -static int vop_get_dsp_addr(struct rk_lcdc_driver *dev_drv, - unsigned int dsp_addr[][4]) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - spin_lock(&vop_dev->reg_lock); - if (vop_dev->clk_on) { - dsp_addr[0][0] = vop_readl(vop_dev, WIN0_YRGB_MST); - dsp_addr[1][0] = vop_readl(vop_dev, WIN1_YRGB_MST); - dsp_addr[2][0] = vop_readl(vop_dev, HWC_MST); - } - spin_unlock(&vop_dev->reg_lock); - return 0; -} - -static u32 pwm_period_hpr, pwm_duty_lpr; - -int vop_update_pwm(int bl_pwm_period, int bl_pwm_duty) -{ - pwm_period_hpr = bl_pwm_period; - pwm_duty_lpr = bl_pwm_duty; - /*pr_info("bl_pwm_period_hpr = 0x%x, bl_pwm_duty_lpr = 0x%x\n", - bl_pwm_period, bl_pwm_duty);*/ - 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 vop_get_bcsh_hue(struct rk_lcdc_driver *dev_drv, bcsh_hue_mode mode) -{ -#if 1 - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - u32 val; - - spin_lock(&vop_dev->reg_lock); - if (vop_dev->clk_on) { - val = vop_readl(vop_dev, BCSH_H); - switch (mode) { - case H_SIN: - val &= MASK(SIN_HUE); - break; - case H_COS: - val &= MASK(COS_HUE); - val >>= 16; - break; - default: - break; - } - } - spin_unlock(&vop_dev->reg_lock); - - return val; -#endif - return 0; -} - -static int vop_set_bcsh_hue(struct rk_lcdc_driver *dev_drv, - int sin_hue, int cos_hue) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - u64 val; - - spin_lock(&vop_dev->reg_lock); - if (vop_dev->clk_on) { - val = V_SIN_HUE(sin_hue) | V_COS_HUE(cos_hue); - vop_msk_reg(vop_dev, BCSH_H, val); - vop_cfg_done(vop_dev); - } - spin_unlock(&vop_dev->reg_lock); - - return 0; -} - -static int vop_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv, - bcsh_bcs_mode mode, int value) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - u64 val; - - spin_lock(&vop_dev->reg_lock); - if (vop_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; - val = V_BRIGHTNESS(value); - break; - case CONTRAST: - /*from 0 to 510,typical is 256 */ - val = V_CONTRAST(value); - break; - case SAT_CON: - /*from 0 to 1015,typical is 256 */ - val = V_SAT_CON(value); - break; - default: - break; - } - vop_msk_reg(vop_dev, BCSH_BCS, val); - vop_cfg_done(vop_dev); - } - spin_unlock(&vop_dev->reg_lock); - - return val; -} - -static int vop_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv, bcsh_bcs_mode mode) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - u64 val; - - spin_lock(&vop_dev->reg_lock); - if (vop_dev->clk_on) { - val = vop_readl(vop_dev, BCSH_BCS); - switch (mode) { - case BRIGHTNESS: - val &= MASK(BRIGHTNESS); - if (val > 0x80) - val -= 0x80; - else - val += 0x80; - break; - case CONTRAST: - val &= MASK(CONTRAST); - val >>= 8; - break; - case SAT_CON: - val &= MASK(SAT_CON); - val >>= 20; - break; - default: - break; - } - } - spin_unlock(&vop_dev->reg_lock); - return val; -} - -static int vop_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - - spin_lock(&vop_dev->reg_lock); - if (vop_dev->clk_on) { - if (open) { - vop_writel(vop_dev, BCSH_COLOR_BAR, 0x1); - vop_writel(vop_dev, BCSH_BCS, 0xd0010000); - vop_writel(vop_dev, BCSH_H, 0x01000000); - dev_drv->bcsh.enable = 1; - } else { - vop_msk_reg(vop_dev, BCSH_COLOR_BAR, V_BCSH_EN(0)); - dev_drv->bcsh.enable = 0; - } - vop_bcsh_path_sel(dev_drv); - vop_cfg_done(vop_dev); - } - spin_unlock(&vop_dev->reg_lock); - - return 0; -} - -static int vop_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable) -{ - if (!enable || !dev_drv->bcsh.enable) { - vop_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)) { - vop_open_bcsh(dev_drv, true); - if (dev_drv->bcsh.brightness <= 255) - vop_set_bcsh_bcs(dev_drv, BRIGHTNESS, - dev_drv->bcsh.brightness); - if (dev_drv->bcsh.contrast <= 510) - vop_set_bcsh_bcs(dev_drv, CONTRAST, - dev_drv->bcsh.contrast); - if (dev_drv->bcsh.sat_con <= 1015) - vop_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) - vop_set_bcsh_hue(dev_drv, dev_drv->bcsh.sin_hue, - dev_drv->bcsh.cos_hue); - } - - return 0; -} - -static int __maybe_unused -vop_dsp_black(struct rk_lcdc_driver *dev_drv, int enable) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - - if (enable) { - spin_lock(&vop_dev->reg_lock); - if (likely(vop_dev->clk_on)) { - vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLACK_EN(1)); - vop_cfg_done(vop_dev); - } - spin_unlock(&vop_dev->reg_lock); - } else { - spin_lock(&vop_dev->reg_lock); - if (likely(vop_dev->clk_on)) { - vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLACK_EN(0)); - - vop_cfg_done(vop_dev); - } - spin_unlock(&vop_dev->reg_lock); - } - - return 0; -} - -static int vop_backlight_close(struct rk_lcdc_driver *dev_drv, int enable) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - - if (unlikely(!vop_dev->clk_on)) { - pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on); - return 0; - } - vop_get_backlight_device(dev_drv); - - if (enable) { - /* close the backlight */ - if (vop_dev->backlight) { - vop_dev->backlight->props.power = FB_BLANK_POWERDOWN; - backlight_update_status(vop_dev->backlight); - } - if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable) - dev_drv->trsm_ops->disable(); - } else { - if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable) - dev_drv->trsm_ops->enable(); - msleep(100); - /* open the backlight */ - if (vop_dev->backlight) { - vop_dev->backlight->props.power = FB_BLANK_UNBLANK; - backlight_update_status(vop_dev->backlight); - } - } - - return 0; -} - -static int vop_set_overscan(struct rk_lcdc_driver *dev_drv, - struct overscan *overscan) -{ - struct vop_device *vop_dev = - container_of(dev_drv, struct vop_device, driver); - - if (unlikely(!vop_dev->clk_on)) { - pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on); - return 0; - } - /*vop_post_cfg(dev_drv);*/ - - return 0; -} - -static struct rk_lcdc_drv_ops lcdc_drv_ops = { - .open = vop_open, - .win_direct_en = vop_win_direct_en, - .load_screen = vop_load_screen, - .get_dspbuf_info = vop_get_dspbuf_info, - .post_dspbuf = vop_post_dspbuf, - .set_par = vop_set_par, - .pan_display = vop_pan_display, - .direct_set_addr = vop_direct_set_win_addr, - /*.lcdc_reg_update = vop_reg_update,*/ - .blank = vop_blank, - .ioctl = vop_ioctl, - .suspend = vop_early_suspend, - .resume = vop_early_resume, - .get_win_state = vop_get_win_state, - .area_support_num = vop_get_area_num, - .ovl_mgr = vop_ovl_mgr, - .get_disp_info = vop_get_disp_info, - .fps_mgr = vop_fps_mgr, - .fb_get_win_id = vop_get_win_id, - .fb_win_remap = vop_fb_win_remap, - .poll_vblank = vop_poll_vblank, - .dpi_open = vop_dpi_open, - .dpi_win_sel = vop_dpi_win_sel, - .dpi_status = vop_dpi_status, - .get_dsp_addr = vop_get_dsp_addr, - .set_dsp_bcsh_hue = vop_set_bcsh_hue, - .set_dsp_bcsh_bcs = vop_set_bcsh_bcs, - .get_dsp_bcsh_hue = vop_get_bcsh_hue, - .get_dsp_bcsh_bcs = vop_get_bcsh_bcs, - .open_bcsh = vop_open_bcsh, - .dump_reg = vop_reg_dump, - .cfg_done = vop_config_done, - .set_irq_to_cpu = vop_set_irq_to_cpu, - /*.dsp_black = vop_dsp_black,*/ - .backlight_close = vop_backlight_close, - .mmu_en = vop_mmu_en, - .set_overscan = vop_set_overscan, -}; - -static irqreturn_t vop_isr(int irq, void *dev_id) -{ - struct vop_device *vop_dev = (struct vop_device *)dev_id; - ktime_t timestamp = ktime_get(); - u32 intr_status; - unsigned long flags; - - spin_lock_irqsave(&vop_dev->irq_lock, flags); - - intr_status = vop_readl(vop_dev, INTR_STATUS0); - vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, intr_status); - - spin_unlock_irqrestore(&vop_dev->irq_lock, flags); - /* This is expected for vop iommu irqs, since the irq is shared */ - if (!intr_status) - return IRQ_NONE; - - if (intr_status & INTR_FS) { - timestamp = ktime_get(); - vop_dev->driver.vsync_info.timestamp = timestamp; - wake_up_interruptible_all(&vop_dev->driver.vsync_info.wait); - intr_status &= ~INTR_FS; - } - - if (intr_status & INTR_LINE_FLAG0) - intr_status &= ~INTR_LINE_FLAG0; - - if (intr_status & INTR_LINE_FLAG1) - intr_status &= ~INTR_LINE_FLAG1; - - if (intr_status & INTR_FS_NEW) - intr_status &= ~INTR_FS_NEW; - - if (intr_status & INTR_BUS_ERROR) { - intr_status &= ~INTR_BUS_ERROR; - dev_warn(vop_dev->dev, "bus error!"); - } - if (intr_status) - dev_err(vop_dev->dev, "Unknown VOP IRQs: %#02x\n", intr_status); - - return IRQ_HANDLED; -} - -#if defined(CONFIG_PM) -static int vop_suspend(struct platform_device *pdev, pm_message_t state) -{ - return 0; -} - -static int vop_resume(struct platform_device *pdev) -{ - return 0; -} -#else -#define vop_suspend NULL -#define vop_resume NULL -#endif - -static int vop_parse_dt(struct vop_device *vop_dev) -{ - struct device_node *np = vop_dev->dev->of_node; - struct rk_lcdc_driver *dev_drv = &vop_dev->driver; - int val; - - if (of_property_read_u32(np, "rockchip,prop", &val)) - vop_dev->prop = PRMRY; /*default set it as primary */ - else - vop_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,pwr18", &val)) - /*default set it as 3.xv power supply */ - vop_dev->pwr18 = false; - else - vop_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 vop_probe(struct platform_device *pdev) -{ - struct vop_device *vop_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; - } - vop_dev = devm_kzalloc(dev, sizeof(struct vop_device), GFP_KERNEL); - if (!vop_dev) { - dev_err(&pdev->dev, "rk3228 lcdc device kmalloc fail!"); - return -ENOMEM; - } - platform_set_drvdata(pdev, vop_dev); - vop_dev->dev = dev; - vop_parse_dt(vop_dev); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - vop_dev->reg_phy_base = res->start; - vop_dev->len = resource_size(res); - vop_dev->regs = devm_ioremap_resource(dev, res); - if (IS_ERR(vop_dev->regs)) - return PTR_ERR(vop_dev->regs); - else - dev_info(dev, "vop_dev->regs=0x%lx\n", (long)vop_dev->regs); - - vop_dev->regsbak = devm_kzalloc(dev, vop_dev->len, GFP_KERNEL); - if (IS_ERR(vop_dev->regsbak)) - return PTR_ERR(vop_dev->regsbak); - - vop_dev->id = 0; - dev_set_name(vop_dev->dev, "vop%d", vop_dev->id); - dev_drv = &vop_dev->driver; - dev_drv->dev = dev; - dev_drv->prop = prop; - dev_drv->id = vop_dev->id; - dev_drv->ops = &lcdc_drv_ops; - dev_drv->lcdc_win_num = ARRAY_SIZE(vop_win); - dev_drv->reserved_fb = 1;/*only need reserved 1 buffer*/ - spin_lock_init(&vop_dev->reg_lock); - spin_lock_init(&vop_dev->irq_lock); - - vop_dev->irq = platform_get_irq(pdev, 0); - if (vop_dev->irq < 0) { - dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n", - vop_dev->id); - return -ENXIO; - } - - ret = devm_request_irq(dev, vop_dev->irq, vop_isr, - IRQF_DISABLED | IRQF_SHARED, - dev_name(dev), vop_dev); - if (ret) { - dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n", - vop_dev->irq, ret); - return ret; - } - - if (dev_drv->iommu_enabled) - strcpy(dev_drv->mmu_dts_name, VOP_IOMMU_COMPATIBLE_NAME); - - ret = rk_fb_register(dev_drv, vop_win, vop_dev->id); - if (ret < 0) { - dev_err(dev, "register fb for lcdc%d failed!\n", vop_dev->id); - return ret; - } - vop_dev->screen = dev_drv->screen0; - dev_info(dev, "lcdc%d probe ok, iommu %s\n", - vop_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled"); - - return 0; -} - -static int vop_remove(struct platform_device *pdev) -{ - return 0; -} - -static void vop_shutdown(struct platform_device *pdev) -{ - struct vop_device *vop_dev = platform_get_drvdata(pdev); - struct rk_lcdc_driver *dev_drv = &vop_dev->driver; - - dev_drv->suspend_flag = 1; - mdelay(100); - flush_kthread_worker(&dev_drv->update_regs_worker); - kthread_stop(dev_drv->update_regs_thread); - vop_deint(vop_dev); - /*if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable) - dev_drv->trsm_ops->disable();*/ - - vop_clk_disable(vop_dev); - rk_disp_pwr_disable(dev_drv); -} - -#if defined(CONFIG_OF) -static const struct of_device_id vop_dt_ids[] = { - {.compatible = "rockchip,rk3228-lcdc",}, - {} -}; -#endif - -static struct platform_driver vop_driver = { - .probe = vop_probe, - .remove = vop_remove, - .driver = { - .name = "rk3228-lcdc", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(vop_dt_ids), - }, - .suspend = vop_suspend, - .resume = vop_resume, - .shutdown = vop_shutdown, -}; - -static int __init vop_module_init(void) -{ - return platform_driver_register(&vop_driver); -} - -static void __exit vop_module_exit(void) -{ - platform_driver_unregister(&vop_driver); -} - -fs_initcall(vop_module_init); -module_exit(vop_module_exit); diff --git a/drivers/video/rockchip/lcdc/rk3228_lcdc.h b/drivers/video/rockchip/lcdc/rk3228_lcdc.h deleted file mode 100644 index 9df5760967fe..000000000000 --- a/drivers/video/rockchip/lcdc/rk3228_lcdc.h +++ /dev/null @@ -1,1676 +0,0 @@ -#ifndef RK3228_LCDC_H_ -#define RK3228_LCDC_H_ - -#include -#include -#include -#include -#include - -#define VOP_INPUT_MAX_WIDTH 4096 -/* - * Registers in this file - * REG_CFG_DONE: Register config done flag - * VERSION_INFO: Version for vop - * SYS_CTRL: System control register0 - * SYS_CTRL1: System control register1 - * DSP_CTRL0: Display control register0 - * DSP_CTRL1: Display control register1 - * DSP_BG: Background color - * MCU_CTRL: MCU mode control register - * WB_CTRL0: write back ctrl0 - * WB_CTRL1: write back ctrl1 - * WB_YRGB_MST: write back yrgb mst - * WB_CBR_MST: write back cbr mst - * WIN0_CTRL0: Win0 ctrl register0 - * WIN0_CTRL1: Win0 ctrl register1 - * WIN0_COLOR_KEY: Win0 color key register - * WIN0_VIR: Win0 virtual stride - * WIN0_YRGB_MST: Win0 YRGB memory start address - * WIN0_CBR_MST: Win0 Cbr memory start address - * WIN0_ACT_INFO: Win0 active window width/height - * WIN0_DSP_INFO: Win0 display width/height on panel - * WIN0_DSP_ST: Win0 display start point on panel - * WIN0_SCL_FACTOR_YRGB: Win0 YRGB scaling factor - * WIN0_SCL_FACTOR_CBR: Win0 Cbr scaling factor - * WIN0_SCL_OFFSET: Win0 scaling start point offset - * WIN0_SRC_ALPHA_CTRL: Win0 alpha source control register - * WIN0_DST_ALPHA_CTRL: Win0 alpha destination control register - * WIN0_FADING_CTRL: Win0 fading contrl register - * WIN0_CTRL2: Win0 ctrl register2 - * WIN1_CTRL0: Win1 ctrl register0 - * WIN1_CTRL1: Win1 ctrl register1 - * WIN1_COLOR_KEY: Win1 color key register - * WIN1_VIR: win1 virtual stride - * WIN1_YRGB_MST: Win1 YRGB memory start address - * WIN1_CBR_MST: Win1 Cbr memory start address - * WIN1_ACT_INFO: Win1 active window width/height - * WIN1_DSP_INFO: Win1 display width/height on panel - * WIN1_DSP_ST: Win1 display start point on panel - * WIN1_SCL_FACTOR_YRGB: Win1 YRGB scaling factor - * WIN1_SCL_FACTOR_CBR: Win1 Cbr scaling factor - * WIN1_SCL_OFFSET: Win1 scaling start point offset - * WIN1_SRC_ALPHA_CTRL: Win1 alpha source control register - * WIN1_DST_ALPHA_CTRL: Win1 alpha destination control register - * WIN1_FADING_CTRL: Win1 fading contrl register - * WIN1_CTRL2: Win1 ctrl register2 - * WIN2_CTRL0: win2 ctrl register0 - * WIN2_CTRL1: win2 ctrl register1 - * WIN2_VIR0_1: Win2 virtual stride0 and virtaul stride1 - * WIN2_VIR2_3: Win2 virtual stride2 and virtaul stride3 - * WIN2_MST0: Win2 memory start address0 - * WIN2_DSP_INFO0: Win2 display width0/height0 on panel - * WIN2_DSP_ST0: Win2 display start point0 on panel - * WIN2_COLOR_KEY: Win2 color key register - * WIN2_MST1: Win2 memory start address1 - * WIN2_DSP_INFO1: Win2 display width1/height1 on panel - * WIN2_DSP_ST1: Win2 display start point1 on panel - * WIN2_SRC_ALPHA_CTRL: Win2 alpha source control register - * WIN2_MST2: Win2 memory start address2 - * WIN2_DSP_INFO2: Win2 display width2/height2 on panel - * WIN2_DSP_ST2: Win2 display start point2 on panel - * WIN2_DST_ALPHA_CTRL: Win2 alpha destination control register - * WIN2_MST3: Win2 memory start address3 - * WIN2_DSP_INFO3: Win2 display width3/height3 on panel - * WIN2_DSP_ST3: Win2 display start point3 on panel - * WIN2_FADING_CTRL: Win2 fading contrl register - * WIN3_CTRL0: Win3 ctrl register0 - * WIN3_CTRL1: Win3 ctrl register1 - * WIN3_VIR0_1: Win3 virtual stride0 and virtaul stride1 - * WIN3_VIR2_3: Win3 virtual stride2 and virtaul stride3 - * WIN3_MST0: Win3 memory start address0 - * WIN3_DSP_INFO0: Win3 display width0/height0 on panel - * WIN3_DSP_ST0: Win3 display start point0 on panel - * WIN3_COLOR_KEY: Win3 color key register - * WIN3_MST1: Win3 memory start address1 - * WIN3_DSP_INFO1: Win3 display width1/height1 on panel - * WIN3_DSP_ST1: Win3 display start point1 on panel - * WIN3_SRC_ALPHA_CTRL: Win3 alpha source control register - * WIN3_MST2: Win3 memory start address2 - * WIN3_DSP_INFO2: Win3 display width2/height2 on panel - * WIN3_DSP_ST2: Win3 display start point2 on panel - * WIN3_DST_ALPHA_CTRL: Win3 alpha destination control register - * WIN3_MST3: Win3 memory start address3 - * WIN3_DSP_INFO3: Win3 display width3/height3 on panel - * WIN3_DSP_ST3: Win3 display start point3 on panel - * WIN3_FADING_CTRL: Win3 fading contrl register - * HWC_CTRL0: Hwc ctrl register0 - * HWC_CTRL1: Hwc ctrl register1 - * HWC_MST: Hwc memory start address - * HWC_DSP_ST: Hwc display start point on panel - * HWC_SRC_ALPHA_CTRL: Hwc alpha source control register - * HWC_DST_ALPHA_CTRL: Hwc alpha destination control register - * HWC_FADING_CTRL: Hwc fading contrl register - * HWC_RESERVED1: Hwc reserved - * POST_DSP_HACT_INFO: Post scaler down horizontal start and end - * POST_DSP_VACT_INFO: Panel active horizontal scanning start point - * and end point - * POST_SCL_FACTOR_YRGB: Post yrgb scaling factor - * POST_RESERVED: Post reserved - * POST_SCL_CTRL: Post scaling start point offset - * POST_DSP_VACT_INFO_F1: Panel active horizontal scanning start point - * and end point F1 - * DSP_HTOTAL_HS_END: Panel scanning horizontal width and hsync pulse end point - * DSP_HACT_ST_END: Panel active horizontal scanning start point and end point - * DSP_VTOTAL_VS_END: Panel scanning vertical height and vsync pulse end point - * DSP_VACT_ST_END: Panel active vertical scanning start point and end point - * DSP_VS_ST_END_F1: Vertical scanning start point and vsync pulse end point - * of even filed in interlace mode - * DSP_VACT_ST_END_F1: Vertical scanning active start point and end point of - * even filed in interlace mode - * PWM_CTRL: PWM Control Register - * PWM_PERIOD_HPR: PWM Period Register/High Polarity Capture Register - * PWM_DUTY_LPR: PWM Duty Register/Low Polarity Capture Register - * PWM_CNT: PWM Counter Register - * BCSH_COLOR_BAR: Color bar config register - * BCSH_BCS: Brightness contrast saturation*contrast config register - * BCSH_H: Sin hue and cos hue config register - * BCSH_CTRL: BCSH contrl register - * CABC_CTRL0: Content Adaptive Backlight Control register0 - * CABC_CTRL1: Content Adaptive Backlight Control register1 - * CABC_CTRL2: Content Adaptive Backlight Control register2 - * CABC_CTRL3: Content Adaptive Backlight Control register3 - * CABC_GAUSS_LINE0_0: CABC gauss line config register00 - * CABC_GAUSS_LINE0_1: CABC gauss line config register01 - * CABC_GAUSS_LINE1_0: CABC gauss line config register10 - * CABC_GAUSS_LINE1_1: CABC gauss line config register11 - * CABC_GAUSS_LINE2_0: CABC gauss line config register20 - * CABC_GAUSS_LINE2_1: CABC gauss line config register21 - * FRC_LOWER01_0: FRC lookup table config register010 - * FRC_LOWER01_1: FRC lookup table config register011 - * FRC_LOWER10_0: FRC lookup table config register100 - * FRC_LOWER10_1: FRC lookup table config register101 - * FRC_LOWER11_0: FRC lookup table config register110 - * FRC_LOWER11_1: FRC lookup table config register111 - * AFBCD0_CTRL: - * AFBCD0_HDR_PTR: - * AFBCD0_PIC_SIZE: - * AFBCD0_STATUS: - * AFBCD1_CTRL: - * AFBCD1_HDR_PTR: - * AFBCD1_PIC_SIZE: - * AFBCD1_STATUS: - * AFBCD2_CTRL: - * AFBCD2_HDR_PTR: - * AFBCD2_PIC_SIZE: - * AFBCD2_STATUS: - * AFBCD3_CTRL: - * AFBCD3_HDR_PTR: - * AFBCD3_PIC_SIZE: - * AFBCD3_STATUS: - * INTR_EN0: Interrupt enable register - * INTR_CLEAR0: Interrupt clear register - * INTR_STATUS0: interrupt status - * INTR_RAW_STATUS0: raw interrupt status - * INTR_EN1: Interrupt enable register - * INTR_CLEAR1: Interrupt clear register - * INTR_STATUS1: interrupt status - * INTR_RAW_STATUS1: raw interrupt status - * LINE_FLAG: Line flag config register - * VOP_STATUS: vop status register - * BLANKING_VALUE: Register0000 Abstract - * WIN0_DSP_BG: Win0 layer background color - * WIN1_DSP_BG: Win1 layer background color - * WIN2_DSP_BG: Win2 layer background color - * WIN3_DSP_BG: Win3 layer background color - * DBG_PERF_LATENCY_CTRL0: Axi performance latency module contrl register0 - * DBG_PERF_RD_MAX_LATENCY_NUM0: Read max latency number - * DBG_PERF_RD_LATENCY_THR_NUM0: The number of bigger than configed - * threshold value - * DBG_PERF_RD_LATENCY_SAMP_NUM0: Total sample number - * DBG_CABC0: CABC debug register0 - * DBG_CABC1: CABC debug register1 - * DBG_CABC2: CABC debug register2 - * DBG_CABC3: CABC debug register3 - * DBG_WIN0_REG0: Vop debug win0 register0 - * DBG_WIN0_REG1: Vop debug win0 register1 - * DBG_WIN0_REG2: Vop debug win0 register2 - * DBG_WIN0_RESERVED: Vop debug win0 register3 reserved - * DBG_WIN1_REG0: Vop debug win1 register0 - * DBG_WIN1_REG1: Vop debug win1 register1 - * DBG_WIN1_REG2: Vop debug win1 register2 - * DBG_WIN1_RESERVED: Vop debug win1 register3 reserved - * DBG_WIN2_REG0: Vop debug win2 register0 - * DBG_WIN2_REG1: Vop debug win2 register1 - * DBG_WIN2_REG2: Vop debug win2 register2 - * DBG_WIN2_REG3: Vop debug win2 register3 - * DBG_WIN3_REG0: Vop debug win3 register0 - * DBG_WIN3_REG1: Vop debug win3 register1 - * DBG_WIN3_REG2: Vop debug win3 register2 - * DBG_WIN3_REG3: Vop debug win3 register3 - * DBG_PRE_REG0: Vop debug pre register0 - * DBG_PRE_RESERVED: Vop debug pre register1 reserved - * DBG_POST_REG0: Vop debug post register0 - * DBG_POST_RESERVED: Vop debug post register1 reserved - * DBG_DATAO: debug data output path - * DBG_DATAO_2: debug data output path 2 - * WIN2_LUT_ADDR: Win2 lut base address - * WIN3_LUT_ADDR: Win3 lut base address - * HWC_LUT_ADDR: Hwc lut base address - * GAMMA0_LUT_ADDR: GAMMA lut base address - * GAMMA1_LUT_ADDR: GAMMA lut base address - * CABC_GAMMA_LUT_ADDR: CABC GAMMA lut base address - * MCU_BYPASS_WPORT: - * MCU_BYPASS_RPORT: - */ - -static inline u64 val_mask(int val, u64 msk, int shift) -{ - return (msk << (shift + 32)) | ((msk & val) << shift); -} - -#define VAL_MASK(x, width, shift) val_mask(x, (1 << width) - 1, shift) - -#define MASK(x) (V_##x(0) >> 32) - -#define REG_CFG_DONE 0x00000000 -#define V_REG_LOAD_EN(x) VAL_MASK(x, 1, 0) -#define V_REG_LOAD_WIN0_EN(x) VAL_MASK(x, 1, 1) -#define V_REG_LOAD_WIN1_EN(x) VAL_MASK(x, 1, 2) -#define V_REG_LOAD_WIN2_EN(x) VAL_MASK(x, 1, 3) -#define V_REG_LOAD_WIN3_EN(x) VAL_MASK(x, 1, 4) -#define V_REG_LOAD_HWC_EN(x) VAL_MASK(x, 1, 5) -#define V_REG_LOAD_IEP_EN(x) VAL_MASK(x, 1, 6) -#define V_REG_LOAD_FBDC_EN(x) VAL_MASK(x, 1, 7) -#define V_REG_LOAD_SYS_EN(x) VAL_MASK(x, 1, 8) -#define V_WRITE_MASK(x) VAL_MASK(x, 16, 16) -#define VERSION_INFO 0x00000004 -#define V_SVNBUILD(x) VAL_MASK(x, 16, 0) -#define V_MINOR(x) VAL_MASK(x, 8, 16) -#define V_MAJOR(x) VAL_MASK(x, 8, 24) -#define SYS_CTRL 0x00000008 -#define V_DIRECT_PATH_EN(x) VAL_MASK(x, 1, 0) -#define V_DIRECT_PATH_LAYER_SEL(x) VAL_MASK(x, 2, 1) -#define V_EDPI_HALT_EN(x) VAL_MASK(x, 1, 8) -#define V_EDPI_WMS_MODE(x) VAL_MASK(x, 1, 9) -#define V_EDPI_WMS_FS(x) VAL_MASK(x, 1, 10) -#define V_GLOBAL_REGDONE_EN(x) VAL_MASK(x, 1, 11) -#define V_RGB_OUT_EN(x) VAL_MASK(x, 1, 12) -#define V_HDMI_OUT_EN(x) VAL_MASK(x, 1, 13) -#define V_EDP_OUT_EN(x) VAL_MASK(x, 1, 14) -#define V_MIPI_OUT_EN(x) VAL_MASK(x, 1, 15) -#define V_OVERLAY_MODE(x) VAL_MASK(x, 1, 16) -#define V_FS_SAME_ADDR_MASK_EN(x) VAL_MASK(x, 1, 17) -#define V_POST_LB_MODE(x) VAL_MASK(x, 1, 18) -#define V_WIN23_PRI_OPT_MODE(x) VAL_MASK(x, 1, 19) -#define V_VOP_MMU_EN(x) VAL_MASK(x, 1, 20) -#define V_VOP_DMA_STOP(x) VAL_MASK(x, 1, 21) -#define V_VOP_STANDBY_EN(x) VAL_MASK(x, 1, 22) -#define V_AUTO_GATING_EN(x) VAL_MASK(x, 1, 23) -#define V_SW_IMD_TVE_DCLK_EN(x) VAL_MASK(x, 1, 24) -#define V_SW_IMD_TVE_DCLK_POL(x) VAL_MASK(x, 1, 25) -#define V_SW_TVE_MODE(x) VAL_MASK(x, 1, 26) -#define V_SW_UV_OFFSET_EN(x) VAL_MASK(x, 1, 27) -#define V_SW_GENLOCK(x) VAL_MASK(x, 1, 28) -#define V_SW_DAC_SEL(x) VAL_MASK(x, 1, 29) -#define V_VOP_FIELD_TVE_POL(x) VAL_MASK(x, 1, 30) -#define V_IO_PAD_CLK_SEL(x) VAL_MASK(x, 1, 31) -#define SYS_CTRL1 0x0000000c -#define V_NOC_HURRY_EN(x) VAL_MASK(x, 1, 0) -#define V_NOC_HURRY_VALUE(x) VAL_MASK(x, 2, 1) -#define V_NOC_HURRY_THRESHOLD(x) VAL_MASK(x, 6, 3) -#define V_NOC_QOS_EN(x) VAL_MASK(x, 1, 9) -#define V_NOC_WIN_QOS(x) VAL_MASK(x, 2, 10) -#define V_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 12) -#define V_AXI_OUTSTANDING_MAX_NUM(x) VAL_MASK(x, 5, 13) -#define V_NOC_HURRY_W_MODE(x) VAL_MASK(x, 2, 20) -#define V_NOC_HURRY_W_VALUE(x) VAL_MASK(x, 2, 22) -#define V_DSP_FP_STANDBY(x) VAL_MASK(x, 1, 31) -#define DSP_CTRL0 0x00000010 -#define V_DSP_OUT_MODE(x) VAL_MASK(x, 4, 0) -#define V_SW_CORE_DCLK_SEL(x) VAL_MASK(x, 1, 4) -#define V_SW_HDMI_CLK_I_SEL(x) VAL_MASK(x, 1, 5) -#define V_DSP_DCLK_DDR(x) VAL_MASK(x, 1, 8) -#define V_DSP_DDR_PHASE(x) VAL_MASK(x, 1, 9) -#define V_DSP_INTERLACE(x) VAL_MASK(x, 1, 10) -#define V_DSP_FIELD_POL(x) VAL_MASK(x, 1, 11) -#define V_DSP_BG_SWAP(x) VAL_MASK(x, 1, 12) -#define V_DSP_RB_SWAP(x) VAL_MASK(x, 1, 13) -#define V_DSP_RG_SWAP(x) VAL_MASK(x, 1, 14) -#define V_DSP_DELTA_SWAP(x) VAL_MASK(x, 1, 15) -#define V_DSP_DUMMY_SWAP(x) VAL_MASK(x, 1, 16) -#define V_DSP_OUT_ZERO(x) VAL_MASK(x, 1, 17) -#define V_DSP_BLANK_EN(x) VAL_MASK(x, 1, 18) -#define V_DSP_BLACK_EN(x) VAL_MASK(x, 1, 19) -#define V_DSP_CCIR656_AVG(x) VAL_MASK(x, 1, 20) -#define V_DSP_YUV_CLIP(x) VAL_MASK(x, 1, 21) -#define V_DSP_X_MIR_EN(x) VAL_MASK(x, 1, 22) -#define V_DSP_Y_MIR_EN(x) VAL_MASK(x, 1, 23) -#define V_DSP_FIELD(x) VAL_MASK(x, 1, 31) -#define DSP_CTRL1 0x00000014 -#define V_DSP_LUT_EN(x) VAL_MASK(x, 1, 0) -#define V_PRE_DITHER_DOWN_EN(x) VAL_MASK(x, 1, 1) -#define V_DITHER_DOWN_EN(x) VAL_MASK(x, 1, 2) -#define V_DITHER_DOWN_MODE(x) VAL_MASK(x, 1, 3) -#define V_DITHER_DOWN_SEL(x) VAL_MASK(x, 1, 4) -#define V_DITHER_UP_EN(x) VAL_MASK(x, 1, 6) -#define V_UPDATE_GAMMA_LUT(x) VAL_MASK(x, 1, 7) -#define V_DSP_LAYER0_SEL(x) VAL_MASK(x, 2, 8) -#define V_DSP_LAYER1_SEL(x) VAL_MASK(x, 2, 10) -#define V_DSP_LAYER2_SEL(x) VAL_MASK(x, 2, 12) -#define V_DSP_LAYER3_SEL(x) VAL_MASK(x, 2, 14) -#define V_RGB_LVDS_HSYNC_POL(x) VAL_MASK(x, 1, 16) -#define V_RGB_LVDS_VSYNC_POL(x) VAL_MASK(x, 1, 17) -#define V_RGB_LVDS_DEN_POL(x) VAL_MASK(x, 1, 18) -#define V_RGB_LVDS_DCLK_POL(x) VAL_MASK(x, 1, 19) -#define V_HDMI_HSYNC_POL(x) VAL_MASK(x, 1, 20) -#define V_HDMI_VSYNC_POL(x) VAL_MASK(x, 1, 21) -#define V_HDMI_DEN_POL(x) VAL_MASK(x, 1, 22) -#define V_HDMI_DCLK_POL(x) VAL_MASK(x, 1, 23) -#define V_EDP_HSYNC_POL(x) VAL_MASK(x, 1, 24) -#define V_EDP_VSYNC_POL(x) VAL_MASK(x, 1, 25) -#define V_EDP_DEN_POL(x) VAL_MASK(x, 1, 26) -#define V_EDP_DCLK_POL(x) VAL_MASK(x, 1, 27) -#define V_MIPI_HSYNC_POL(x) VAL_MASK(x, 1, 28) -#define V_MIPI_VSYNC_POL(x) VAL_MASK(x, 1, 29) -#define V_MIPI_DEN_POL(x) VAL_MASK(x, 1, 30) -#define V_MIPI_DCLK_POL(x) VAL_MASK(x, 1, 31) -#define DSP_BG 0x00000018 -#define V_DSP_BG_BLUE(x) VAL_MASK(x, 8, 0) -#define V_DSP_BG_GREEN(x) VAL_MASK(x, 8, 8) -#define V_DSP_BG_RED(x) VAL_MASK(x, 8, 16) -#define MCU_CTRL 0x0000001c -#define V_MCU_PIX_TOTAL(x) VAL_MASK(x, 6, 0) -#define V_MCU_CS_PST(x) VAL_MASK(x, 4, 6) -#define V_MCU_CS_PEND(x) VAL_MASK(x, 6, 10) -#define V_MCU_RW_PST(x) VAL_MASK(x, 4, 16) -#define V_MCU_RW_PEND(x) VAL_MASK(x, 6, 20) -#define V_MCU_CLK_SEL(x) VAL_MASK(x, 1, 26) -#define V_MCU_HOLD_MODE(x) VAL_MASK(x, 1, 27) -#define V_MCU_FRAME_ST(x) VAL_MASK(x, 1, 28) -#define V_MCU_RS(x) VAL_MASK(x, 1, 29) -#define V_MCU_BYPASS(x) VAL_MASK(x, 1, 30) -#define V_MCU_TYPE(x) VAL_MASK(x, 1, 31) -#define WB_CTRL0 0x00000020 -#define V_WB_EN(x) VAL_MASK(x, 1, 0) -#define V_WB_FMT(x) VAL_MASK(x, 3, 1) -#define V_WB_DITHER_EN(x) VAL_MASK(x, 1, 4) -#define V_WB_RGB2YUV_EN(x) VAL_MASK(x, 1, 5) -#define V_WB_RGB2YUV_MODE(x) VAL_MASK(x, 1, 6) -#define V_WB_XPSD_BIL_EN(x) VAL_MASK(x, 1, 7) -#define V_WB_YTHROW_EN(x) VAL_MASK(x, 1, 8) -#define V_WB_YTHROW_MODE(x) VAL_MASK(x, 1, 9) -#define V_WB_HANDSHAKE_MODE(x) VAL_MASK(x, 1, 11) -#define V_WB_YRGB_ID(x) VAL_MASK(x, 4, 24) -#define V_WB_UV_ID(x) VAL_MASK(x, 4, 28) -#define WB_CTRL1 0x00000024 -#define V_WB_WIDTH(x) VAL_MASK(x, 12, 0) -#define V_WB_XPSD_BIL_FACTOR(x) VAL_MASK(x, 14, 16) -#define WB_YRGB_MST 0x00000028 -#define V_WB_YRGB_MST(x) VAL_MASK(x, 32, 0) -#define WB_CBR_MST 0x0000002c -#define V_WB_CBR_MST(x) VAL_MASK(x, 32, 0) -#define WIN0_CTRL0 0x00000030 -#define V_WIN0_EN(x) VAL_MASK(x, 1, 0) -#define V_WIN0_DATA_FMT(x) VAL_MASK(x, 3, 1) -#define V_WIN0_FMT_10(x) VAL_MASK(x, 1, 4) -#define V_WIN0_LB_MODE(x) VAL_MASK(x, 3, 5) -#define V_WIN0_INTERLACE_READ(x) VAL_MASK(x, 1, 8) -#define V_WIN0_NO_OUTSTANDING(x) VAL_MASK(x, 1, 9) -#define V_WIN0_CSC_MODE(x) VAL_MASK(x, 2, 10) -#define V_WIN0_RB_SWAP(x) VAL_MASK(x, 1, 12) -#define V_WIN0_ALPHA_SWAP(x) VAL_MASK(x, 1, 13) -#define V_WIN0_MID_SWAP(x) VAL_MASK(x, 1, 14) -#define V_WIN0_UV_SWAP(x) VAL_MASK(x, 1, 15) -#define V_WIN0_HW_PRE_MUL_EN(x) VAL_MASK(x, 1, 16) -#define V_WIN0_YRGB_DEFLICK(x) VAL_MASK(x, 1, 18) -#define V_WIN0_CBR_DEFLICK(x) VAL_MASK(x, 1, 19) -#define V_WIN0_YUV_CLIP(x) VAL_MASK(x, 1, 20) -#define V_WIN0_X_MIR_EN(x) VAL_MASK(x, 1, 21) -#define V_WIN0_Y_MIR_EN(x) VAL_MASK(x, 1, 22) -#define V_WIN0_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 24) -#define V_WIN0_AXI_OUTSTANDING_MAX_NUM(x) VAL_MASK(x, 5, 25) -#define V_WIN0_DMA_BURST_LENGTH(x) VAL_MASK(x, 2, 30) -#define WIN0_CTRL1 0x00000034 -#define V_WIN0_YRGB_AXI_GATHER_EN(x) VAL_MASK(x, 1, 0) -#define V_WIN0_CBR_AXI_GATHER_EN(x) VAL_MASK(x, 1, 1) -#define V_WIN0_BIC_COE_SEL(x) VAL_MASK(x, 2, 2) -#define V_WIN0_VSD_YRGB_GT4(x) VAL_MASK(x, 1, 4) -#define V_WIN0_VSD_YRGB_GT2(x) VAL_MASK(x, 1, 5) -#define V_WIN0_VSD_CBR_GT4(x) VAL_MASK(x, 1, 6) -#define V_WIN0_VSD_CBR_GT2(x) VAL_MASK(x, 1, 7) -#define V_WIN0_YRGB_AXI_GATHER_NUM(x) VAL_MASK(x, 4, 8) -#define V_WIN0_CBR_AXI_GATHER_NUM(x) VAL_MASK(x, 3, 12) -#define V_WIN0_LINE_LOAD_MODE(x) VAL_MASK(x, 1, 15) -#define V_WIN0_YRGB_HOR_SCL_MODE(x) VAL_MASK(x, 2, 16) -#define V_WIN0_YRGB_VER_SCL_MODE(x) VAL_MASK(x, 2, 18) -#define V_WIN0_YRGB_HSD_MODE(x) VAL_MASK(x, 2, 20) -#define V_WIN0_YRGB_VSU_MODE(x) VAL_MASK(x, 1, 22) -#define V_WIN0_YRGB_VSD_MODE(x) VAL_MASK(x, 1, 23) -#define V_WIN0_CBR_HOR_SCL_MODE(x) VAL_MASK(x, 2, 24) -#define V_WIN0_CBR_VER_SCL_MODE(x) VAL_MASK(x, 2, 26) -#define V_WIN0_CBR_HSD_MODE(x) VAL_MASK(x, 2, 28) -#define V_WIN0_CBR_VSU_MODE(x) VAL_MASK(x, 1, 30) -#define V_WIN0_CBR_VSD_MODE(x) VAL_MASK(x, 1, 31) -#define WIN0_COLOR_KEY 0x00000038 -#define V_WIN0_KEY_COLOR(x) VAL_MASK(x, 24, 0) -#define V_WIN0_KEY_EN(x) VAL_MASK(x, 1, 31) -#define WIN0_VIR 0x0000003c -#define V_WIN0_VIR_STRIDE(x) VAL_MASK(x, 16, 0) -#define V_WIN0_VIR_STRIDE_UV(x) VAL_MASK(x, 16, 16) -#define WIN0_YRGB_MST 0x00000040 -#define V_WIN0_YRGB_MST(x) VAL_MASK(x, 32, 0) -#define WIN0_CBR_MST 0x00000044 -#define V_WIN0_CBR_MST(x) VAL_MASK(x, 32, 0) -#define WIN0_ACT_INFO 0x00000048 -#define V_WIN0_ACT_WIDTH(x) VAL_MASK(x, 13, 0) -#define V_FIELD0002(x) VAL_MASK(x, 1, 13) -#define V_FIELD0001(x) VAL_MASK(x, 1, 14) -#define V_FIELD0000(x) VAL_MASK(x, 1, 15) -#define V_WIN0_ACT_HEIGHT(x) VAL_MASK(x, 13, 16) -#define WIN0_DSP_INFO 0x0000004c -#define V_WIN0_DSP_WIDTH(x) VAL_MASK(x, 12, 0) -#define V_WIN0_DSP_HEIGHT(x) VAL_MASK(x, 12, 16) -#define WIN0_DSP_ST 0x00000050 -#define V_WIN0_DSP_XST(x) VAL_MASK(x, 13, 0) -#define V_WIN0_DSP_YST(x) VAL_MASK(x, 13, 16) -#define WIN0_SCL_FACTOR_YRGB 0x00000054 -#define V_WIN0_HS_FACTOR_YRGB(x) VAL_MASK(x, 16, 0) -#define V_WIN0_VS_FACTOR_YRGB(x) VAL_MASK(x, 16, 16) -#define WIN0_SCL_FACTOR_CBR 0x00000058 -#define V_WIN0_HS_FACTOR_CBR(x) VAL_MASK(x, 16, 0) -#define V_WIN0_VS_FACTOR_CBR(x) VAL_MASK(x, 16, 16) -#define WIN0_SCL_OFFSET 0x0000005c -#define V_WIN0_HS_OFFSET_YRGB(x) VAL_MASK(x, 8, 0) -#define V_WIN0_HS_OFFSET_CBR(x) VAL_MASK(x, 8, 8) -#define V_WIN0_VS_OFFSET_YRGB(x) VAL_MASK(x, 8, 16) -#define V_WIN0_VS_OFFSET_CBR(x) VAL_MASK(x, 8, 24) -#define WIN0_SRC_ALPHA_CTRL 0x00000060 -#define V_WIN0_SRC_ALPHA_EN(x) VAL_MASK(x, 1, 0) -#define V_WIN0_SRC_COLOR_MODE(x) VAL_MASK(x, 1, 1) -#define V_WIN0_SRC_ALPHA_MODE(x) VAL_MASK(x, 1, 2) -#define V_WIN0_SRC_BLEND_MODE(x) VAL_MASK(x, 2, 3) -#define V_WIN0_SRC_ALPHA_CAL_MODE(x) VAL_MASK(x, 1, 5) -#define V_WIN0_SRC_FACTOR_MODE(x) VAL_MASK(x, 3, 6) -#define V_WIN0_SRC_GLOBAL_ALPHA(x) VAL_MASK(x, 8, 16) -#define V_WIN0_FADING_VALUE(x) VAL_MASK(x, 8, 24) -#define WIN0_DST_ALPHA_CTRL 0x00000064 -#define V_WIN0_DST_M0_RESERVED(x) VAL_MASK(x, 6, 0) -#define V_WIN0_DST_FACTOR_MODE(x) VAL_MASK(x, 3, 6) -#define WIN0_FADING_CTRL 0x00000068 -#define V_LAYER0_FADING_OFFSET_R(x) VAL_MASK(x, 8, 0) -#define V_LAYER0_FADING_OFFSET_G(x) VAL_MASK(x, 8, 8) -#define V_LAYER0_FADING_OFFSET_B(x) VAL_MASK(x, 8, 16) -#define V_LAYER0_FADING_EN(x) VAL_MASK(x, 1, 24) -#define WIN0_CTRL2 0x0000006c -#define V_WIN_RID_WIN0_YRGB(x) VAL_MASK(x, 4, 0) -#define V_WIN_RID_WIN0_CBR(x) VAL_MASK(x, 4, 4) -#define WIN1_CTRL0 0x00000070 -#define V_WIN1_EN(x) VAL_MASK(x, 1, 0) -#define V_WIN1_DATA_FMT(x) VAL_MASK(x, 3, 1) -#define V_WIN1_FMT_10(x) VAL_MASK(x, 1, 4) -#define V_WIN1_LB_MODE(x) VAL_MASK(x, 3, 5) -#define V_WIN1_INTERLACE_READ(x) VAL_MASK(x, 1, 8) -#define V_WIN1_NO_OUTSTANDING(x) VAL_MASK(x, 1, 9) -#define V_WIN1_CSC_MODE(x) VAL_MASK(x, 2, 10) -#define V_WIN1_RB_SWAP(x) VAL_MASK(x, 1, 12) -#define V_WIN1_ALPHA_SWAP(x) VAL_MASK(x, 1, 13) -#define V_WIN1_MID_SWAP(x) VAL_MASK(x, 1, 14) -#define V_WIN1_UV_SWAP(x) VAL_MASK(x, 1, 15) -#define V_WIN1_HW_PRE_MUL_EN(x) VAL_MASK(x, 1, 16) -#define V_WIN1_YRGB_DEFLICK(x) VAL_MASK(x, 1, 18) -#define V_WIN1_CBR_DEFLICK(x) VAL_MASK(x, 1, 19) -#define V_WIN1_YUV_CLIP(x) VAL_MASK(x, 1, 20) -#define V_WIN1_X_MIR_EN(x) VAL_MASK(x, 1, 21) -#define V_WIN1_Y_MIR_EN(x) VAL_MASK(x, 1, 22) -#define V_WIN1_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 24) -#define V_WIN1_AXI_MAX_OUTSTANDING_NUM(x) VAL_MASK(x, 5, 25) -#define V_WIN1_DMA_BURST_LENGTH(x) VAL_MASK(x, 2, 30) -#define WIN1_CTRL1 0x00000074 -#define V_WIN1_YRGB_AXI_GATHER_EN(x) VAL_MASK(x, 1, 0) -#define V_WIN1_CBR_AXI_GATHER_EN(x) VAL_MASK(x, 1, 1) -#define V_WIN1_BIC_COE_SEL(x) VAL_MASK(x, 2, 2) -#define V_WIN1_VSD_YRGB_GT4(x) VAL_MASK(x, 1, 4) -#define V_WIN1_VSD_YRGB_GT2(x) VAL_MASK(x, 1, 5) -#define V_WIN1_VSD_CBR_GT4(x) VAL_MASK(x, 1, 6) -#define V_WIN1_VSD_CBR_GT2(x) VAL_MASK(x, 1, 7) -#define V_WIN1_YRGB_AXI_GATHER_NUM(x) VAL_MASK(x, 4, 8) -#define V_WIN1_CBR_AXI_GATHER_NUM(x) VAL_MASK(x, 3, 12) -#define V_WIN1_LINE_LOAD_MODE(x) VAL_MASK(x, 1, 15) -#define V_WIN1_YRGB_HOR_SCL_MODE(x) VAL_MASK(x, 2, 16) -#define V_WIN1_YRGB_VER_SCL_MODE(x) VAL_MASK(x, 2, 18) -#define V_WIN1_YRGB_HSD_MODE(x) VAL_MASK(x, 2, 20) -#define V_WIN1_YRGB_VSU_MODE(x) VAL_MASK(x, 1, 22) -#define V_WIN1_YRGB_VSD_MODE(x) VAL_MASK(x, 1, 23) -#define V_WIN1_CBR_HOR_SCL_MODE(x) VAL_MASK(x, 2, 24) -#define V_WIN1_CBR_VER_SCL_MODE(x) VAL_MASK(x, 2, 26) -#define V_WIN1_CBR_HSD_MODE(x) VAL_MASK(x, 2, 28) -#define V_WIN1_CBR_VSU_MODE(x) VAL_MASK(x, 1, 30) -#define V_WIN1_CBR_VSD_MODE(x) VAL_MASK(x, 1, 31) -#define WIN1_COLOR_KEY 0x00000078 -#define V_WIN1_KEY_COLOR(x) VAL_MASK(x, 24, 0) -#define V_WIN1_KEY_EN(x) VAL_MASK(x, 1, 31) -#define WIN1_VIR 0x0000007c -#define V_WIN1_VIR_STRIDE(x) VAL_MASK(x, 16, 0) -#define V_WIN1_VIR_STRIDE_UV(x) VAL_MASK(x, 16, 16) -#define WIN1_YRGB_MST 0x00000080 -#define V_WIN1_YRGB_MST(x) VAL_MASK(x, 32, 0) -#define WIN1_CBR_MST 0x00000084 -#define V_WIN1_CBR_MST(x) VAL_MASK(x, 32, 0) -#define WIN1_ACT_INFO 0x00000088 -#define V_WIN1_ACT_WIDTH(x) VAL_MASK(x, 13, 0) -#define V_WIN1_ACT_HEIGHT(x) VAL_MASK(x, 13, 16) -#define WIN1_DSP_INFO 0x0000008c -#define V_WIN1_DSP_WIDTH(x) VAL_MASK(x, 12, 0) -#define V_WIN1_DSP_HEIGHT(x) VAL_MASK(x, 12, 16) -#define WIN1_DSP_ST 0x00000090 -#define V_WIN1_DSP_XST(x) VAL_MASK(x, 13, 0) -#define V_WIN1_DSP_YST(x) VAL_MASK(x, 13, 16) -#define WIN1_SCL_FACTOR_YRGB 0x00000094 -#define V_WIN1_HS_FACTOR_YRGB(x) VAL_MASK(x, 16, 0) -#define V_WIN1_VS_FACTOR_YRGB(x) VAL_MASK(x, 16, 16) -#define WIN1_SCL_FACTOR_CBR 0x00000098 -#define V_WIN1_HS_FACTOR_CBR(x) VAL_MASK(x, 16, 0) -#define V_WIN1_VS_FACTOR_CBR(x) VAL_MASK(x, 16, 16) -#define WIN1_SCL_OFFSET 0x0000009c -#define V_WIN1_HS_OFFSET_YRGB(x) VAL_MASK(x, 8, 0) -#define V_WIN1_HS_OFFSET_CBR(x) VAL_MASK(x, 8, 8) -#define V_WIN1_VS_OFFSET_YRGB(x) VAL_MASK(x, 8, 16) -#define V_WIN1_VS_OFFSET_CBR(x) VAL_MASK(x, 8, 24) -#define WIN1_SRC_ALPHA_CTRL 0x000000a0 -#define V_WIN1_SRC_ALPHA_EN(x) VAL_MASK(x, 1, 0) -#define V_WIN1_SRC_COLOR_MODE(x) VAL_MASK(x, 1, 1) -#define V_WIN1_SRC_ALPHA_MODE(x) VAL_MASK(x, 1, 2) -#define V_WIN1_SRC_BLEND_MODE(x) VAL_MASK(x, 2, 3) -#define V_WIN1_SRC_ALPHA_CAL_MODE(x) VAL_MASK(x, 1, 5) -#define V_WIN1_SRC_FACTOR_MODE(x) VAL_MASK(x, 3, 6) -#define V_WIN1_SRC_GLOBAL_ALPHA(x) VAL_MASK(x, 8, 16) -#define V_WIN1_FADING_VALUE(x) VAL_MASK(x, 8, 24) -#define WIN1_DST_ALPHA_CTRL 0x000000a4 -#define V_WIN1_DSP_M0_RESERVED(x) VAL_MASK(x, 6, 0) -#define V_WIN1_DST_FACTOR_M0(x) VAL_MASK(x, 3, 6) -#define WIN1_FADING_CTRL 0x000000a8 -#define V_WIN1_FADING_OFFSET_R(x) VAL_MASK(x, 8, 0) -#define V_WIN1_FADING_OFFSET_G(x) VAL_MASK(x, 8, 8) -#define V_WIN1_FADING_OFFSET_B(x) VAL_MASK(x, 8, 16) -#define V_WIN1_FADING_EN(x) VAL_MASK(x, 1, 24) -#define WIN1_CTRL2 0x000000ac -#define V_WIN_RID_WIN1_YRGB(x) VAL_MASK(x, 4, 0) -#define V_WIN_RID_WIN1_CBR(x) VAL_MASK(x, 4, 4) -#define WIN2_CTRL0 0x000000b0 -#define V_WIN2_EN(x) VAL_MASK(x, 1, 0) -#define V_WIN2_INTERLACE_READ(x) VAL_MASK(x, 1, 1) -#define V_WIN2_CSC_MODE(x) VAL_MASK(x, 1, 2) -#define V_WIN2_MST0_EN(x) VAL_MASK(x, 1, 4) -#define V_WIN2_DATA_FMT0(x) VAL_MASK(x, 2, 5) -#define V_WIN2_MST1_EN(x) VAL_MASK(x, 1, 8) -#define V_WIN2_DATA_FMT1(x) VAL_MASK(x, 2, 9) -#define V_WIN2_MST2_EN(x) VAL_MASK(x, 1, 12) -#define V_WIN2_DATA_FMT2(x) VAL_MASK(x, 2, 13) -#define V_WIN2_MST3_EN(x) VAL_MASK(x, 1, 16) -#define V_WIN2_DATA_FMT3(x) VAL_MASK(x, 2, 17) -#define V_WIN2_RB_SWAP0(x) VAL_MASK(x, 1, 20) -#define V_WIN2_ALPHA_SWAP0(x) VAL_MASK(x, 1, 21) -#define V_WIN2_ENDIAN_SWAP0(x) VAL_MASK(x, 1, 22) -#define V_WIN2_RB_SWAP1(x) VAL_MASK(x, 1, 23) -#define V_WIN2_ALPHA_SWAP1(x) VAL_MASK(x, 1, 24) -#define V_WIN2_ENDIAN_SWAP1(x) VAL_MASK(x, 1, 25) -#define V_WIN2_RB_SWAP2(x) VAL_MASK(x, 1, 26) -#define V_WIN2_ALPHA_SWAP2(x) VAL_MASK(x, 1, 27) -#define V_WIN2_ENDIAN_SWAP2(x) VAL_MASK(x, 1, 28) -#define V_WIN2_RB_SWAP3(x) VAL_MASK(x, 1, 29) -#define V_WIN2_ALPHA_SWAP3(x) VAL_MASK(x, 1, 30) -#define V_WIN2_ENDIAN_SWAP3(x) VAL_MASK(x, 1, 31) -#define WIN2_CTRL1 0x000000b4 -#define V_WIN2_AXI_GATHER_EN(x) VAL_MASK(x, 1, 0) -#define V_WIN2_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 1) -#define V_WIN2_DMA_BURST_LENGTH(x) VAL_MASK(x, 2, 2) -#define V_WIN2_AXI_GATHER_NUM(x) VAL_MASK(x, 4, 4) -#define V_WIN2_AXI_MAX_OUTSTANDING_NUM(x) VAL_MASK(x, 5, 8) -#define V_WIN2_NO_OUTSTANDING(x) VAL_MASK(x, 1, 14) -#define V_WIN2_Y_MIR_EN(x) VAL_MASK(x, 1, 15) -#define V_WIN2_LUT_EN(x) VAL_MASK(x, 1, 16) -#define V_WIN_RID_WIN2(x) VAL_MASK(x, 4, 20) -#define WIN2_VIR0_1 0x000000b8 -#define V_WIN2_VIR_STRIDE0(x) VAL_MASK(x, 16, 0) -#define V_WIN2_VIR_STRIDE1(x) VAL_MASK(x, 16, 16) -#define WIN2_VIR2_3 0x000000bc -#define V_WIN2_VIR_STRIDE2(x) VAL_MASK(x, 16, 0) -#define V_WIN2_VIR_STRIDE3(x) VAL_MASK(x, 16, 16) -#define WIN2_MST0 0x000000c0 -#define V_WIN2_MST0(x) VAL_MASK(x, 32, 0) -#define WIN2_DSP_INFO0 0x000000c4 -#define V_WIN2_DSP_WIDTH0(x) VAL_MASK(x, 12, 0) -#define V_WIN2_DSP_HEIGHT0(x) VAL_MASK(x, 12, 16) -#define WIN2_DSP_ST0 0x000000c8 -#define V_WIN2_DSP_XST0(x) VAL_MASK(x, 13, 0) -#define V_WIN2_DSP_YST0(x) VAL_MASK(x, 13, 16) -#define WIN2_COLOR_KEY 0x000000cc -#define V_WIN2_KEY_COLOR(x) VAL_MASK(x, 24, 0) -#define V_WIN2_KEY_EN(x) VAL_MASK(x, 1, 24) -#define WIN2_MST1 0x000000d0 -#define V_WIN2_MST1(x) VAL_MASK(x, 32, 0) -#define WIN2_DSP_INFO1 0x000000d4 -#define V_WIN2_DSP_WIDTH1(x) VAL_MASK(x, 12, 0) -#define V_WIN2_DSP_HEIGHT1(x) VAL_MASK(x, 12, 16) -#define WIN2_DSP_ST1 0x000000d8 -#define V_WIN2_DSP_XST1(x) VAL_MASK(x, 13, 0) -#define V_WIN2_DSP_YST1(x) VAL_MASK(x, 13, 16) -#define WIN2_SRC_ALPHA_CTRL 0x000000dc -#define V_WIN2_SRC_ALPHA_EN(x) VAL_MASK(x, 1, 0) -#define V_WIN2_SRC_COLOR_MODE(x) VAL_MASK(x, 1, 1) -#define V_WIN2_SRC_ALPHA_MODE(x) VAL_MASK(x, 1, 2) -#define V_WIN2_SRC_BLEND_MODE(x) VAL_MASK(x, 2, 3) -#define V_WIN2_SRC_ALPHA_CAL_MODE(x) VAL_MASK(x, 1, 5) -#define V_WIN2_SRC_FACTOR_MODE(x) VAL_MASK(x, 3, 6) -#define V_WIN2_SRC_GLOBAL_ALPHA(x) VAL_MASK(x, 8, 16) -#define V_WIN2_FADING_VALUE(x) VAL_MASK(x, 8, 24) -#define WIN2_MST2 0x000000e0 -#define V_WIN2_MST2(x) VAL_MASK(x, 32, 0) -#define WIN2_DSP_INFO2 0x000000e4 -#define V_WIN2_DSP_WIDTH2(x) VAL_MASK(x, 12, 0) -#define V_WIN2_DSP_HEIGHT2(x) VAL_MASK(x, 12, 16) -#define WIN2_DSP_ST2 0x000000e8 -#define V_WIN2_DSP_XST2(x) VAL_MASK(x, 13, 0) -#define V_WIN2_DSP_YST2(x) VAL_MASK(x, 13, 16) -#define WIN2_DST_ALPHA_CTRL 0x000000ec -#define V_WIN2_DST_M0_RESERVED(x) VAL_MASK(x, 6, 0) -#define V_WIN2_DST_FACTOR_MODE(x) VAL_MASK(x, 3, 6) -#define WIN2_MST3 0x000000f0 -#define V_WIN2_MST3(x) VAL_MASK(x, 32, 0) -#define WIN2_DSP_INFO3 0x000000f4 -#define V_WIN2_DSP_WIDTH3(x) VAL_MASK(x, 12, 0) -#define V_WIN2_DSP_HEIGHT3(x) VAL_MASK(x, 12, 16) -#define WIN2_DSP_ST3 0x000000f8 -#define V_WIN2_DSP_XST3(x) VAL_MASK(x, 13, 0) -#define V_WIN2_DSP_YST3(x) VAL_MASK(x, 13, 16) -#define WIN2_FADING_CTRL 0x000000fc -#define V_WIN2_FADING_OFFSET_R(x) VAL_MASK(x, 8, 0) -#define V_WIN2_FADING_OFFSET_G(x) VAL_MASK(x, 8, 8) -#define V_WIN2_FADING_OFFSET_B(x) VAL_MASK(x, 8, 16) -#define V_WIN2_FADING_EN(x) VAL_MASK(x, 1, 24) -#define WIN3_CTRL0 0x00000100 -#define V_WIN3_EN(x) VAL_MASK(x, 1, 0) -#define V_WIN3_INTERLACE_READ(x) VAL_MASK(x, 1, 1) -#define V_WIN3_CSC_MODE(x) VAL_MASK(x, 1, 2) -#define V_WIN3_MST0_EN(x) VAL_MASK(x, 1, 4) -#define V_WIN3_DATA_FMT0(x) VAL_MASK(x, 2, 5) -#define V_WIN3_MST1_EN(x) VAL_MASK(x, 1, 8) -#define V_WIN3_DATA_FMT1(x) VAL_MASK(x, 2, 9) -#define V_WIN3_MST2_EN(x) VAL_MASK(x, 1, 12) -#define V_WIN3_DATA_FMT2(x) VAL_MASK(x, 2, 13) -#define V_WIN3_MST3_EN(x) VAL_MASK(x, 1, 16) -#define V_WIN3_DATA_FMT3(x) VAL_MASK(x, 2, 17) -#define V_WIN3_RB_SWAP0(x) VAL_MASK(x, 1, 20) -#define V_WIN3_ALPHA_SWAP0(x) VAL_MASK(x, 1, 21) -#define V_WIN3_ENDIAN_SWAP0(x) VAL_MASK(x, 1, 22) -#define V_WIN3_RB_SWAP1(x) VAL_MASK(x, 1, 23) -#define V_WIN3_ALPHA_SWAP1(x) VAL_MASK(x, 1, 24) -#define V_WIN3_ENDIAN_SWAP1(x) VAL_MASK(x, 1, 25) -#define V_WIN3_RB_SWAP2(x) VAL_MASK(x, 1, 26) -#define V_WIN3_ALPHA_SWAP2(x) VAL_MASK(x, 1, 27) -#define V_WIN3_ENDIAN_SWAP2(x) VAL_MASK(x, 1, 28) -#define V_WIN3_RB_SWAP3(x) VAL_MASK(x, 1, 29) -#define V_WIN3_ALPHA_SWAP3(x) VAL_MASK(x, 1, 30) -#define V_WIN3_ENDIAN_SWAP3(x) VAL_MASK(x, 1, 31) -#define WIN3_CTRL1 0x00000104 -#define V_WIN3_AXI_GATHER_EN(x) VAL_MASK(x, 1, 0) -#define V_WIN3_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 1) -#define V_WIN3_DMA_BURST_LENGTH(x) VAL_MASK(x, 2, 2) -#define V_WIN3_AXI_GATHER_NUM(x) VAL_MASK(x, 4, 4) -#define V_WIN3_AXI_MAX_OUTSTANDING_NUM(x) VAL_MASK(x, 5, 8) -#define V_WIN3_NO_OUTSTANDING(x) VAL_MASK(x, 1, 14) -#define V_WIN3_Y_MIR_EN(x) VAL_MASK(x, 1, 15) -#define V_WIN3_LUT_EN(x) VAL_MASK(x, 1, 16) -#define V_WIN_RID_WIN3(x) VAL_MASK(x, 4, 20) -#define WIN3_VIR0_1 0x00000108 -#define V_WIN3_VIR_STRIDE0(x) VAL_MASK(x, 16, 0) -#define V_WIN3_VIR_STRIDE1(x) VAL_MASK(x, 16, 16) -#define WIN3_VIR2_3 0x0000010c -#define V_WIN3_VIR_STRIDE2(x) VAL_MASK(x, 16, 0) -#define V_WIN3_VIR_STRIDE3(x) VAL_MASK(x, 16, 16) -#define WIN3_MST0 0x00000110 -#define V_WIN3_MST0(x) VAL_MASK(x, 32, 0) -#define WIN3_DSP_INFO0 0x00000114 -#define V_WIN3_DSP_WIDTH0(x) VAL_MASK(x, 12, 0) -#define V_WIN3_DSP_HEIGHT0(x) VAL_MASK(x, 12, 16) -#define WIN3_DSP_ST0 0x00000118 -#define V_WIN3_DSP_XST0(x) VAL_MASK(x, 13, 0) -#define V_WIN3_DSP_YST0(x) VAL_MASK(x, 13, 16) -#define WIN3_COLOR_KEY 0x0000011c -#define V_WIN3_KEY_COLOR(x) VAL_MASK(x, 24, 0) -#define V_WIN3_KEY_EN(x) VAL_MASK(x, 1, 24) -#define WIN3_MST1 0x00000120 -#define V_WIN3_MST1(x) VAL_MASK(x, 32, 0) -#define WIN3_DSP_INFO1 0x00000124 -#define V_WIN3_DSP_WIDTH1(x) VAL_MASK(x, 12, 0) -#define V_WIN3_DSP_HEIGHT1(x) VAL_MASK(x, 12, 16) -#define WIN3_DSP_ST1 0x00000128 -#define V_WIN3_DSP_XST1(x) VAL_MASK(x, 13, 0) -#define V_WIN3_DSP_YST1(x) VAL_MASK(x, 13, 16) -#define WIN3_SRC_ALPHA_CTRL 0x0000012c -#define V_WIN3_SRC_ALPHA_EN(x) VAL_MASK(x, 1, 0) -#define V_WIN3_SRC_COLOR_MODE(x) VAL_MASK(x, 1, 1) -#define V_WIN3_SRC_ALPHA_MODE(x) VAL_MASK(x, 1, 2) -#define V_WIN3_SRC_BLEND_MODE(x) VAL_MASK(x, 2, 3) -#define V_WIN3_SRC_ALPHA_CAL_MODE(x) VAL_MASK(x, 1, 5) -#define V_WIN3_SRC_FACTOR_MODE(x) VAL_MASK(x, 3, 6) -#define V_WIN3_SRC_GLOBAL_ALPHA(x) VAL_MASK(x, 8, 16) -#define V_WIN3_FADING_VALUE(x) VAL_MASK(x, 8, 24) -#define WIN3_MST2 0x00000130 -#define V_WIN3_MST2(x) VAL_MASK(x, 32, 0) -#define WIN3_DSP_INFO2 0x00000134 -#define V_WIN3_DSP_WIDTH2(x) VAL_MASK(x, 12, 0) -#define V_WIN3_DSP_HEIGHT2(x) VAL_MASK(x, 12, 16) -#define WIN3_DSP_ST2 0x00000138 -#define V_WIN3_DSP_XST2(x) VAL_MASK(x, 13, 0) -#define V_WIN3_DSP_YST2(x) VAL_MASK(x, 13, 16) -#define WIN3_DST_ALPHA_CTRL 0x0000013c -#define V_WIN3_DST_FACTOR_RESERVED(x) VAL_MASK(x, 6, 0) -#define V_WIN3_DST_FACTOR_MODE(x) VAL_MASK(x, 3, 6) -#define WIN3_MST3 0x00000140 -#define V_WIN3_MST3(x) VAL_MASK(x, 32, 0) -#define WIN3_DSP_INFO3 0x00000144 -#define V_WIN3_DSP_WIDTH3(x) VAL_MASK(x, 12, 0) -#define V_WIN3_DSP_HEIGHT3(x) VAL_MASK(x, 12, 16) -#define WIN3_DSP_ST3 0x00000148 -#define V_WIN3_DSP_XST3(x) VAL_MASK(x, 13, 0) -#define V_WIN3_DSP_YST3(x) VAL_MASK(x, 13, 16) -#define WIN3_FADING_CTRL 0x0000014c -#define V_WIN3_FADING_OFFSET_R(x) VAL_MASK(x, 8, 0) -#define V_WIN3_FADING_OFFSET_G(x) VAL_MASK(x, 8, 8) -#define V_WIN3_FADING_OFFSET_B(x) VAL_MASK(x, 8, 16) -#define V_WIN3_FADING_EN(x) VAL_MASK(x, 1, 24) -#define HWC_CTRL0 0x00000150 -#define V_HWC_EN(x) VAL_MASK(x, 1, 0) -#define V_HWC_DATA_FMT(x) VAL_MASK(x, 3, 1) -#define V_HWC_MODE(x) VAL_MASK(x, 1, 4) -#define V_HWC_SIZE(x) VAL_MASK(x, 2, 5) -#define V_HWC_INTERLACE_READ(x) VAL_MASK(x, 1, 8) -#define V_HWC_CSC_MODE(x) VAL_MASK(x, 1, 10) -#define V_HWC_RB_SWAP(x) VAL_MASK(x, 1, 12) -#define V_HWC_ALPHA_SWAP(x) VAL_MASK(x, 1, 13) -#define V_HWC_ENDIAN_SWAP(x) VAL_MASK(x, 1, 14) -#define HWC_CTRL1 0x00000154 -#define V_HWC_AXI_GATHER_EN(x) VAL_MASK(x, 1, 0) -#define V_HWC_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 1) -#define V_HWC_DMA_BURST_LENGTH(x) VAL_MASK(x, 2, 2) -#define V_HWC_AXI_GATHER_NUM(x) VAL_MASK(x, 3, 4) -#define V_HWC_AXI_MAX_OUTSTANDING_NUM(x) VAL_MASK(x, 5, 8) -#define V_HWC_RGB2YUV_EN(x) VAL_MASK(x, 1, 13) -#define V_HWC_NO_OUTSTANDING(x) VAL_MASK(x, 1, 14) -#define V_HWC_Y_MIR_EN(x) VAL_MASK(x, 1, 15) -#define V_HWC_LUT_EN(x) VAL_MASK(x, 1, 16) -#define V_WIN_RID_HWC(x) VAL_MASK(x, 4, 20) -#define HWC_MST 0x00000158 -#define V_HWC_MST(x) VAL_MASK(x, 32, 0) -#define HWC_DSP_ST 0x0000015c -#define V_HWC_DSP_XST(x) VAL_MASK(x, 13, 0) -#define V_HWC_DSP_YST(x) VAL_MASK(x, 13, 16) -#define HWC_SRC_ALPHA_CTRL 0x00000160 -#define V_HWC_SRC_ALPHA_EN(x) VAL_MASK(x, 1, 0) -#define V_HWC_SRC_COLOR_MODE(x) VAL_MASK(x, 1, 1) -#define V_HWC_SRC_ALPHA_MODE(x) VAL_MASK(x, 1, 2) -#define V_HWC_SRC_BLEND_MODE(x) VAL_MASK(x, 2, 3) -#define V_HWC_SRC_ALPHA_CAL_MODE(x) VAL_MASK(x, 1, 5) -#define V_HWC_SRC_FACTOR_MODE(x) VAL_MASK(x, 3, 6) -#define V_HWC_SRC_GLOBAL_ALPHA(x) VAL_MASK(x, 8, 16) -#define V_HWC_FADING_VALUE(x) VAL_MASK(x, 8, 24) -#define HWC_DST_ALPHA_CTRL 0x00000164 -#define V_HWC_DST_M0_RESERVED(x) VAL_MASK(x, 6, 0) -#define V_HWC_DST_FACTOR_MODE(x) VAL_MASK(x, 3, 6) -#define HWC_FADING_CTRL 0x00000168 -#define V_HWC_FADING_OFFSET_R(x) VAL_MASK(x, 8, 0) -#define V_HWC_FADING_OFFSET_G(x) VAL_MASK(x, 8, 8) -#define V_HWC_FADING_OFFSET_B(x) VAL_MASK(x, 8, 16) -#define V_HWC_FADING_EN(x) VAL_MASK(x, 1, 24) -#define HWC_RESERVED1 0x0000016c -#define POST_DSP_HACT_INFO 0x00000170 -#define V_DSP_HACT_END_POST(x) VAL_MASK(x, 13, 0) -#define V_DSP_HACT_ST_POST(x) VAL_MASK(x, 13, 16) -#define POST_DSP_VACT_INFO 0x00000174 -#define V_DSP_VACT_END_POST(x) VAL_MASK(x, 13, 0) -#define V_DSP_VACT_ST_POST(x) VAL_MASK(x, 13, 16) -#define POST_SCL_FACTOR_YRGB 0x00000178 -#define V_POST_HS_FACTOR_YRGB(x) VAL_MASK(x, 16, 0) -#define V_POST_VS_FACTOR_YRGB(x) VAL_MASK(x, 16, 16) -#define POST_RESERVED 0x0000017c -#define POST_SCL_CTRL 0x00000180 -#define V_POST_HOR_SD_EN(x) VAL_MASK(x, 1, 0) -#define V_POST_VER_SD_EN(x) VAL_MASK(x, 1, 1) -#define POST_DSP_VACT_INFO_F1 0x00000184 -#define V_DSP_VACT_END_POST(x) VAL_MASK(x, 13, 0) -#define V_DSP_VACT_ST_POST(x) VAL_MASK(x, 13, 16) -#define DSP_HTOTAL_HS_END 0x00000188 -#define V_DSP_HS_END(x) VAL_MASK(x, 13, 0) -#define V_DSP_HTOTAL(x) VAL_MASK(x, 13, 16) -#define DSP_HACT_ST_END 0x0000018c -#define V_DSP_HACT_END(x) VAL_MASK(x, 13, 0) -#define V_DSP_HACT_ST(x) VAL_MASK(x, 13, 16) -#define DSP_VTOTAL_VS_END 0x00000190 -#define V_DSP_VS_END(x) VAL_MASK(x, 13, 0) -#define V_SW_DSP_VTOTAL_IMD(x) VAL_MASK(x, 1, 15) -#define V_DSP_VTOTAL(x) VAL_MASK(x, 13, 16) -#define DSP_VACT_ST_END 0x00000194 -#define V_DSP_VACT_END(x) VAL_MASK(x, 13, 0) -#define V_DSP_VACT_ST(x) VAL_MASK(x, 13, 16) -#define DSP_VS_ST_END_F1 0x00000198 -#define V_DSP_VS_END_F1(x) VAL_MASK(x, 13, 0) -#define V_DSP_VS_ST_F1(x) VAL_MASK(x, 13, 16) -#define DSP_VACT_ST_END_F1 0x0000019c -#define V_DSP_VACT_END_F1(x) VAL_MASK(x, 13, 0) -#define V_DSP_VACT_ST_F1(x) VAL_MASK(x, 13, 16) -#define PWM_CTRL 0x000001a0 -#define V_PWM_EN(x) VAL_MASK(x, 1, 0) -#define V_PWM_MODE(x) VAL_MASK(x, 2, 1) -#define V_DUTY_POL(x) VAL_MASK(x, 1, 3) -#define V_INACTIVE_POL(x) VAL_MASK(x, 1, 4) -#define V_OUTPUT_MODE(x) VAL_MASK(x, 1, 5) -#define V_LP_EN(x) VAL_MASK(x, 1, 8) -#define V_CLK_SEL(x) VAL_MASK(x, 1, 9) -#define V_PRESCALE(x) VAL_MASK(x, 3, 12) -#define V_SCALE(x) VAL_MASK(x, 8, 16) -#define V_RPT(x) VAL_MASK(x, 8, 24) -#define PWM_PERIOD_HPR 0x000001a4 -#define V_PWM_PERIOD(x) VAL_MASK(x, 32, 0) -#define PWM_DUTY_LPR 0x000001a8 -#define V_PWM_DUTY(x) VAL_MASK(x, 32, 0) -#define PWM_CNT 0x000001ac -#define V_PWM_CNT(x) VAL_MASK(x, 32, 0) -#define BCSH_COLOR_BAR 0x000001b0 -#define V_BCSH_EN(x) VAL_MASK(x, 1, 0) -#define V_COLOR_BAR_Y(x) VAL_MASK(x, 8, 8) -#define V_COLOR_BAR_U(x) VAL_MASK(x, 8, 16) -#define V_COLOR_BAR_V(x) VAL_MASK(x, 8, 24) -#define BCSH_BCS 0x000001b4 -#define V_BRIGHTNESS(x) VAL_MASK(x, 8, 0) -#define V_CONTRAST(x) VAL_MASK(x, 9, 8) -#define V_SAT_CON(x) VAL_MASK(x, 10, 20) -#define V_OUT_MODE(x) VAL_MASK(x, 2, 30) -#define BCSH_H 0x000001b8 -#define V_SIN_HUE(x) VAL_MASK(x, 9, 0) -#define V_COS_HUE(x) VAL_MASK(x, 9, 16) -#define BCSH_CTRL 0x000001bc -#define V_BCSH_Y2R_EN(x) VAL_MASK(x, 1, 0) -#define V_BCSH_Y2R_CSC_MODE(x) VAL_MASK(x, 2, 2) -#define V_BCSH_R2Y_EN(x) VAL_MASK(x, 1, 4) -#define V_BCSH_R2Y_CSC_MODE(x) VAL_MASK(x, 1, 6) -#define CABC_CTRL0 0x000001c0 -#define V_CABC_EN(x) VAL_MASK(x, 1, 0) -#define V_PWM_CONFIG_MODE(x) VAL_MASK(x, 2, 1) -#define V_CABC_HANDLE_EN(x) VAL_MASK(x, 1, 3) -#define V_CABC_CALC_PIXEL_NUM(x) VAL_MASK(x, 23, 4) -#define CABC_CTRL1 0x000001c4 -#define V_CABC_LUT_EN(x) VAL_MASK(x, 1, 0) -#define V_CABC_TOTAL_NUM(x) VAL_MASK(x, 23, 4) -#define CABC_CTRL2 0x000001c8 -#define V_CABC_STAGE_DOWN(x) VAL_MASK(x, 8, 0) -#define V_CABC_STAGE_UP(x) VAL_MASK(x, 9, 8) -#define V_CABC_STAGE_UP_MODE(x) VAL_MASK(x, 1, 19) -#define CABC_CTRL3 0x000001cc -#define V_CABC_GLOBAL_DN(x) VAL_MASK(x, 8, 0) -#define V_CABC_GLOBAL_DN_LIMIT_EN(x) VAL_MASK(x, 1, 8) -#define CABC_GAUSS_LINE0_0 0x000001d0 -#define V_T_LINE0_0(x) VAL_MASK(x, 8, 0) -#define V_T_LINE0_1(x) VAL_MASK(x, 8, 8) -#define V_T_LINE0_2(x) VAL_MASK(x, 8, 16) -#define V_T_LINE0_3(x) VAL_MASK(x, 8, 24) -#define CABC_GAUSS_LINE0_1 0x000001d4 -#define V_T_LINE0_4(x) VAL_MASK(x, 8, 0) -#define V_T_LINE0_5(x) VAL_MASK(x, 8, 8) -#define V_T_LINE0_6(x) VAL_MASK(x, 8, 16) -#define CABC_GAUSS_LINE1_0 0x000001d8 -#define V_T_LINE1_0(x) VAL_MASK(x, 8, 0) -#define V_T_LINE1_1(x) VAL_MASK(x, 8, 8) -#define V_T_LINE1_2(x) VAL_MASK(x, 8, 16) -#define V_T_LINE1_3(x) VAL_MASK(x, 8, 24) -#define CABC_GAUSS_LINE1_1 0x000001dc -#define V_T_LINE1_4(x) VAL_MASK(x, 8, 0) -#define V_T_LINE1_5(x) VAL_MASK(x, 8, 8) -#define V_T_LINE1_6(x) VAL_MASK(x, 8, 16) -#define CABC_GAUSS_LINE2_0 0x000001e0 -#define V_T_LINE2_0(x) VAL_MASK(x, 8, 0) -#define V_T_LINE2_1(x) VAL_MASK(x, 8, 8) -#define V_T_LINE2_2(x) VAL_MASK(x, 8, 16) -#define V_T_LINE2_3(x) VAL_MASK(x, 8, 24) -#define CABC_GAUSS_LINE2_1 0x000001e4 -#define V_T_LINE2_4(x) VAL_MASK(x, 8, 0) -#define V_T_LINE2_5(x) VAL_MASK(x, 8, 8) -#define V_T_LINE2_6(x) VAL_MASK(x, 8, 16) -#define FRC_LOWER01_0 0x000001e8 -#define V_LOWER01_FRM0(x) VAL_MASK(x, 16, 0) -#define V_LOWER01_FRM1(x) VAL_MASK(x, 16, 16) -#define FRC_LOWER01_1 0x000001ec -#define V_LOWER01_FRM2(x) VAL_MASK(x, 16, 0) -#define V_LOWER01_FRM3(x) VAL_MASK(x, 16, 16) -#define FRC_LOWER10_0 0x000001f0 -#define V_LOWER10_FRM0(x) VAL_MASK(x, 16, 0) -#define V_LOWER10_FRM1(x) VAL_MASK(x, 16, 16) -#define FRC_LOWER10_1 0x000001f4 -#define V_LOWER10_FRM2(x) VAL_MASK(x, 16, 0) -#define V_LOWER10_FRM3(x) VAL_MASK(x, 16, 16) -#define FRC_LOWER11_0 0x000001f8 -#define V_LOWER11_FRM0(x) VAL_MASK(x, 16, 0) -#define V_LOWER11_FRM1(x) VAL_MASK(x, 16, 16) -#define FRC_LOWER11_1 0x000001fc -#define V_LOWER11_FRM2(x) VAL_MASK(x, 16, 0) -#define V_LOWER11_FRM3(x) VAL_MASK(x, 16, 16) -#define AFBCD0_CTRL 0x00000200 -#define V_VOP_FBDC_EN(x) VAL_MASK(x, 1, 0) -#define V_VOP_FBDC_WIN_SEL(x) VAL_MASK(x, 2, 1) -#define V_FBDC_RSTN(x) VAL_MASK(x, 1, 3) -#define V_VOP_FBDC_AXI_MAX_OUTSTANDING_NUM(x) VAL_MASK(x, 5, 4) -#define V_VOP_FBDC_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 9) -#define V_FBDC_RID(x) VAL_MASK(x, 4, 12) -#define V_AFBCD_HREG_PIXEL_PACKING_FMT(x) VAL_MASK(x, 5, 16) -#define V_AFBCD_HREG_BLOCK_SPLIT(x) VAL_MASK(x, 1, 21) -#define AFBCD0_HDR_PTR 0x00000204 -#define V_AFBCD_HREG_HDR_PTR(x) VAL_MASK(x, 32, 0) -#define AFBCD0_PIC_SIZE 0x00000208 -#define V_AFBCD_HREG_PIC_WIDTH(x) VAL_MASK(x, 16, 0) -#define V_AFBCD_HREG_PIC_HEIGHT(x) VAL_MASK(x, 16, 16) -#define AFBCD0_STATUS 0x0000020c -#define V_AFBCD_HREG_IDLE_N(x) VAL_MASK(x, 1, 0) -#define V_AFBCD_HREG_DEC_RESP(x) VAL_MASK(x, 1, 1) -#define V_AFBCD_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 2) -#define AFBCD1_CTRL 0x00000220 -#define V_VOP_FBDC1_EN(x) VAL_MASK(x, 1, 0) -#define V_VOP_FBDC1_WIN_SEL(x) VAL_MASK(x, 2, 1) -#define V_FBDC1_RSTN(x) VAL_MASK(x, 1, 3) -#define V_VOP_FBDC1_AXI_MAX_OUTSTANDING_NUM(x) VAL_MASK(x, 5, 4) -#define V_VOP_FBDC1_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 9) -#define V_FBDC1_RID(x) VAL_MASK(x, 4, 12) -#define V_AFBCD1_HREG_PIXEL_PACKING_FMT(x) VAL_MASK(x, 5, 16) -#define V_AFBCD1_HREG_BLOCK_SPLIT(x) VAL_MASK(x, 1, 21) -#define AFBCD1_HDR_PTR 0x00000224 -#define V_AFBCD1_HREG_HDR_PTR(x) VAL_MASK(x, 32, 0) -#define AFBCD1_PIC_SIZE 0x00000228 -#define V_AFBCD1_HREG_PIC_WIDTH(x) VAL_MASK(x, 16, 0) -#define V_AFBCD1_HREG_PIC_HEIGHT(x) VAL_MASK(x, 16, 16) -#define AFBCD1_STATUS 0x0000022c -#define V_AFBCD1_HREG_IDLE_N(x) VAL_MASK(x, 1, 0) -#define V_AFBCD1_HREG_DEC_RESP(x) VAL_MASK(x, 1, 1) -#define V_AFBCD1_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 2) -#define AFBCD2_CTRL 0x00000240 -#define V_VOP_FBDC2_EN(x) VAL_MASK(x, 1, 0) -#define V_VOP_FBDC2_WIN_SEL(x) VAL_MASK(x, 2, 1) -#define V_FBDC2_RSTN(x) VAL_MASK(x, 1, 3) -#define V_VOP_FBDC2_AXI_MAX_OUTSTANDING_NUM(x) VAL_MASK(x, 5, 4) -#define V_VOP_FBDC2_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 9) -#define V_FBDC2_RID(x) VAL_MASK(x, 4, 12) -#define V_AFBCD2_HREG_PIXEL_PACKING_FMT(x) VAL_MASK(x, 5, 16) -#define V_AFBCD2_HREG_BLOCK_SPLIT(x) VAL_MASK(x, 1, 21) -#define AFBCD2_HDR_PTR 0x00000244 -#define V_AFBCD2_HREG_HDR_PTR(x) VAL_MASK(x, 32, 0) -#define AFBCD2_PIC_SIZE 0x00000248 -#define V_AFBCD2_HREG_PIC_WIDTH(x) VAL_MASK(x, 16, 0) -#define V_AFBCD2_HREG_PIC_HEIGHT(x) VAL_MASK(x, 16, 16) -#define AFBCD2_STATUS 0x0000024c -#define V_AFBCD2_HREG_IDLE_N(x) VAL_MASK(x, 1, 0) -#define V_AFBCD2_HREG_DEC_RESP(x) VAL_MASK(x, 1, 1) -#define V_AFBCD2_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 2) -#define AFBCD3_CTRL 0x00000260 -#define V_VOP_FBDC3_EN(x) VAL_MASK(x, 1, 0) -#define V_VOP_FBDC3_WIN_SEL(x) VAL_MASK(x, 1, 1) -#define V_FBDC3_RSTN(x) VAL_MASK(x, 1, 2) -#define V_VOP_FBDC3_AXI_MAX_OUTSTANDING_NUM(x) VAL_MASK(x, 5, 3) -#define V_VOP_FBDC3_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 8) -#define V_FBDC3_RID(x) VAL_MASK(x, 4, 12) -#define V_AFBCD3_HREG_PIXEL_PACKING_FMT(x) VAL_MASK(x, 5, 16) -#define V_AFBCD3_HREG_BLOCK_SPLIT(x) VAL_MASK(x, 1, 21) -#define AFBCD3_HDR_PTR 0x00000264 -#define V_AFBCD3_HREG_HDR_PTR(x) VAL_MASK(x, 32, 0) -#define AFBCD3_PIC_SIZE 0x00000268 -#define V_AFBCD3_HREG_PIC_WIDTH(x) VAL_MASK(x, 16, 0) -#define V_AFBCD3_HREG_PIC_HEIGHT(x) VAL_MASK(x, 16, 16) -#define AFBCD3_STATUS 0x0000026c -#define V_AFBCD3_HREG_IDLE_N(x) VAL_MASK(x, 1, 0) -#define V_AFBCD3_HREG_DEC_RESP(x) VAL_MASK(x, 1, 1) -#define V_AFBCD3_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 2) -#define INTR_EN0 0x00000280 -#define V_INTR_EN_FS(x) VAL_MASK(x, 1, 0) -#define V_INTR_EN_FS_NEW(x) VAL_MASK(x, 1, 1) -#define V_INTR_EN_ADDR_SAME(x) VAL_MASK(x, 1, 2) -#define V_INTR_EN_LINE_FLAG0(x) VAL_MASK(x, 1, 3) -#define V_INTR_EN_LINE_FLAG1(x) VAL_MASK(x, 1, 4) -#define V_INTR_EN_BUS_ERROR(x) VAL_MASK(x, 1, 5) -#define V_INTR_EN_WIN0_EMPTY(x) VAL_MASK(x, 1, 6) -#define V_INTR_EN_WIN1_EMPTY(x) VAL_MASK(x, 1, 7) -#define V_INTR_EN_WIN2_EMPTY(x) VAL_MASK(x, 1, 8) -#define V_INTR_EN_WIN3_EMPTY(x) VAL_MASK(x, 1, 9) -#define V_INTR_EN_HWC_EMPTY(x) VAL_MASK(x, 1, 10) -#define V_INTR_EN_POST_BUF_EMPTY(x) VAL_MASK(x, 1, 11) -#define V_INTR_EN_PWM_GEN(x) VAL_MASK(x, 1, 12) -#define V_INTR_EN_DSP_HOLD_VALID(x) VAL_MASK(x, 1, 13) -#define V_INTR_EN_MMU(x) VAL_MASK(x, 1, 14) -#define V_INTR_EN_DMA_FINISH(x) VAL_MASK(x, 1, 15) -#define V_WRITE_MASK(x) VAL_MASK(x, 16, 16) -#define INTR_CLEAR0 0x00000284 -#define V_INT_CLR_FS(x) VAL_MASK(x, 1, 0) -#define V_INT_CLR_FS_NEW(x) VAL_MASK(x, 1, 1) -#define V_INT_CLR_ADDR_SAME(x) VAL_MASK(x, 1, 2) -#define V_INT_CLR_LINE_FLAG0(x) VAL_MASK(x, 1, 3) -#define V_INT_CLR_LINE_FLAG1(x) VAL_MASK(x, 1, 4) -#define V_INT_CLR_BUS_ERROR(x) VAL_MASK(x, 1, 5) -#define V_INT_CLR_WIN0_EMPTY(x) VAL_MASK(x, 1, 6) -#define V_INT_CLR_WIN1_EMPTY(x) VAL_MASK(x, 1, 7) -#define V_INT_CLR_WIN2_EMPTY(x) VAL_MASK(x, 1, 8) -#define V_INT_CLR_WIN3_EMPTY(x) VAL_MASK(x, 1, 9) -#define V_INT_CLR_HWC_EMPTY(x) VAL_MASK(x, 1, 10) -#define V_INT_CLR_POST_BUF_EMPTY(x) VAL_MASK(x, 1, 11) -#define V_INT_CLR_PWM_GEN(x) VAL_MASK(x, 1, 12) -#define V_INT_CLR_DSP_HOLD_VALID(x) VAL_MASK(x, 1, 13) -#define V_INT_CLR_MMU(x) VAL_MASK(x, 1, 14) -#define V_INT_CLR_DMA_FINISH(x) VAL_MASK(x, 1, 15) -#define V_WRITE_MASK(x) VAL_MASK(x, 16, 16) -#define INTR_STATUS0 0x00000288 -#define V_INT_STATUS_FS(x) VAL_MASK(x, 1, 0) -#define V_INT_STATUS_FS_NEW(x) VAL_MASK(x, 1, 1) -#define V_INT_STATUS_ADDR_SAME(x) VAL_MASK(x, 1, 2) -#define V_INT_STATUS_LINE_FLAG0(x) VAL_MASK(x, 1, 3) -#define V_INT_STATUS_LINE_FLAG1(x) VAL_MASK(x, 1, 4) -#define V_INT_STATUS_BUS_ERROR(x) VAL_MASK(x, 1, 5) -#define V_INT_STATUS_WIN0_EMPTY(x) VAL_MASK(x, 1, 6) -#define V_INT_STATUS_WIN1_EMPTY(x) VAL_MASK(x, 1, 7) -#define V_INT_STATUS_WIN2_EMPTY(x) VAL_MASK(x, 1, 8) -#define V_INT_STATUS_WIN3_EMPTY(x) VAL_MASK(x, 1, 9) -#define V_INT_STATUS_HWC_EMPTY(x) VAL_MASK(x, 1, 10) -#define V_INT_STATUS_POST_BUF_EMPTY(x) VAL_MASK(x, 1, 11) -#define V_INT_STATUS_PWM_GEN(x) VAL_MASK(x, 1, 12) -#define V_INT_STATUS_DSP_HOLD_VALID(x) VAL_MASK(x, 1, 13) -#define V_INT_STATUS_MMU(x) VAL_MASK(x, 1, 14) -#define V_INT_STATUS_DMA_FINISH(x) VAL_MASK(x, 1, 15) -#define INTR_RAW_STATUS0 0x0000028c -#define V_INT_RAW_STATUS_FS(x) VAL_MASK(x, 1, 0) -#define V_INT_RAW_STATUS_FS_NEW(x) VAL_MASK(x, 1, 1) -#define V_INT_RAW_STATUS_ADDR_SAME(x) VAL_MASK(x, 1, 2) -#define V_INT_RAW_STATUS_LINE_FRAG0(x) VAL_MASK(x, 1, 3) -#define V_INT_RAW_STATUS_LINE_FRAG1(x) VAL_MASK(x, 1, 4) -#define V_INT_RAW_STATUS_BUS_ERROR(x) VAL_MASK(x, 1, 5) -#define V_INT_RAW_STATUS_WIN0_EMPTY(x) VAL_MASK(x, 1, 6) -#define V_INT_RAW_STATUS_WIN1_EMPTY(x) VAL_MASK(x, 1, 7) -#define V_INT_RAW_STATUS_WIN2_EMPTY(x) VAL_MASK(x, 1, 8) -#define V_INT_RAW_STATUS_WIN3_EMPTY(x) VAL_MASK(x, 1, 9) -#define V_INT_RAW_STATUS_HWC_EMPTY(x) VAL_MASK(x, 1, 10) -#define V_INT_RAW_STATUS_POST_BUF_EMPTY(x) VAL_MASK(x, 1, 11) -#define V_INT_RAW_STATUS_PWM_GEN(x) VAL_MASK(x, 1, 12) -#define V_INT_RAW_STATUS_DSP_HOLD_VALID(x) VAL_MASK(x, 1, 13) -#define V_INT_RAW_STATUS_MMU(x) VAL_MASK(x, 1, 14) -#define V_INT_RAW_STATUS_DMA_FINISH(x) VAL_MASK(x, 1, 15) -#define INTR_EN1 0x00000290 -#define V_INT_EN_FBCD0(x) VAL_MASK(x, 1, 0) -#define V_INT_EN_FBCD1(x) VAL_MASK(x, 1, 1) -#define V_INT_EN_FBCD2(x) VAL_MASK(x, 1, 2) -#define V_INT_EN_FBCD3(x) VAL_MASK(x, 1, 3) -#define V_INT_EN_AFBCD0_HREG_DEC_RESP(x) VAL_MASK(x, 1, 4) -#define V_INT_EN_AFBCD0_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 5) -#define V_INT_EN_AFBCD1_HREG_DEC_RESP(x) VAL_MASK(x, 1, 6) -#define V_INT_EN_AFBCD1_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 7) -#define V_INT_EN_AFBCD2_HREG_DEC_RESP(x) VAL_MASK(x, 1, 8) -#define V_INT_EN_AFBCD2_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 9) -#define V_INT_EN_AFBCD3_HREG_DEC_RESP(x) VAL_MASK(x, 1, 10) -#define V_INT_EN_AFBCD3_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 11) -#define V_INT_EN_WB_YRGB_FIFO_FULL(x) VAL_MASK(x, 1, 12) -#define V_INT_EN_WB_UV_FIFO_FULL(x) VAL_MASK(x, 1, 13) -#define V_INT_EN_WB_FINISH(x) VAL_MASK(x, 1, 14) -#define V_INT_EN_VFP(x) VAL_MASK(x, 1, 15) -#define V_WRITE_MASK(x) VAL_MASK(x, 16, 16) -#define INTR_CLEAR1 0x00000294 -#define V_INT_CLR_FBCD0(x) VAL_MASK(x, 1, 0) -#define V_INT_CLR_FBCD1(x) VAL_MASK(x, 1, 1) -#define V_INT_CLR_FBCD2(x) VAL_MASK(x, 1, 2) -#define V_INT_CLR_FBCD3(x) VAL_MASK(x, 1, 3) -#define V_INT_CLR_AFBCD0_HREG_DEC_RESP(x) VAL_MASK(x, 1, 4) -#define V_INT_CLR_AFBCD0_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 5) -#define V_INT_CLR_AFBCD1_HREG_DEC_RESP(x) VAL_MASK(x, 1, 6) -#define V_INT_CLR_AFBCD1_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 7) -#define V_INT_CLR_AFBCD2_HREG_DEC_RESP(x) VAL_MASK(x, 1, 8) -#define V_INT_CLR_AFBCD2_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 9) -#define V_INT_CLR_AFBCD3_HREG_DEC_RESP(x) VAL_MASK(x, 1, 10) -#define V_INT_CLR_AFBCD3_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 11) -#define V_INT_CLR_VFP(x) VAL_MASK(x, 1, 15) -#define INTR_STATUS1 0x00000298 -#define V_INT_STATUS_FBCD0(x) VAL_MASK(x, 1, 0) -#define V_INT_STATUS_FBCD1(x) VAL_MASK(x, 1, 1) -#define V_INT_STATUS_FBCD2(x) VAL_MASK(x, 1, 2) -#define V_INT_STATUS_FBCD3(x) VAL_MASK(x, 1, 3) -#define V_INT_STATUS_AFBCD0_HREG_DEC_RESP(x) VAL_MASK(x, 1, 4) -#define V_INT_STATUS_AFBCD0_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 5) -#define V_INT_STATUS_AFBCD1_HREG_DEC_RESP(x) VAL_MASK(x, 1, 6) -#define V_INT_STATUS_AFBCD1_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 7) -#define V_INT_STATUS_AFBCD2_HREG_DEC_RESP(x) VAL_MASK(x, 1, 8) -#define V_INT_STATUS_AFBCD2_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 9) -#define V_INT_STATUS_AFBCD3_HREG_DEC_RESP(x) VAL_MASK(x, 1, 10) -#define V_INT_STATUS_AFBCD4_HREG_DEC_RESP(x) VAL_MASK(x, 1, 11) -#define V_INT_STATUS_VFP(x) VAL_MASK(x, 1, 15) -#define INTR_RAW_STATUS1 0x0000029c -#define V_INT_RAW_STATUS_FBCD0(x) VAL_MASK(x, 1, 0) -#define V_INT_RAW_STATUS_FBCD1(x) VAL_MASK(x, 1, 1) -#define V_INT_RAW_STATUS_FBCD2(x) VAL_MASK(x, 1, 2) -#define V_INT_RAW_STATUS_FBCD3(x) VAL_MASK(x, 1, 3) -#define V_INT_RAW_STATUS_AFBCD0_HREG_DEC_RESP(x) VAL_MASK(x, 1, 4) -#define V_INT_RAW_STATUS_AFBCD0_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 5) -#define V_INT_RAW_STATUS_AFBCD1_HREG_DEC_RESP(x) VAL_MASK(x, 1, 6) -#define V_INT_RAW_STATUS_AFBCD1_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 7) -#define V_INT_RAW_STATUS_AFBCD2_HREG_DEC_RESP(x) VAL_MASK(x, 1, 8) -#define V_INT_RAW_STATUS_AFBCD2_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 9) -#define V_INT_RAW_STATUS_AFBCD3_HREG_DEC_RESP(x) VAL_MASK(x, 1, 10) -#define V_INT_RAW_STATUS_AFBCD3_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 11) -#define V_INT_RAW_STATUS_VFP(x) VAL_MASK(x, 1, 15) -#define LINE_FLAG 0x000002a0 -#define V_DSP_LINE_FLAG_NUM_0(x) VAL_MASK(x, 13, 0) -#define V_DSP_LINE_FLAG_NUM_1(x) VAL_MASK(x, 13, 16) -#define VOP_STATUS 0x000002a4 -#define V_DSP_VCNT(x) VAL_MASK(x, 13, 0) -#define V_MMU_IDLE(x) VAL_MASK(x, 1, 16) -#define V_DMA_STOP_VALID(x) VAL_MASK(x, 1, 17) -#define BLANKING_VALUE 0x000002a8 -#define V_BLANKING_VALUE(x) VAL_MASK(x, 24, 0) -#define V_BLANKING_VALUE_CONFIG_EN(x) VAL_MASK(x, 1, 24) -#define MCU_BYPASS_PORT 0x000002ac -#define WIN0_DSP_BG 0x000002b0 -#define V_WIN0_DSP_BG_BLUE(x) VAL_MASK(x, 8, 0) -#define V_WIN0_DSP_BG_GREEN(x) VAL_MASK(x, 8, 8) -#define V_WIN0_DSP_BG_RED(x) VAL_MASK(x, 8, 16) -#define V_WIN0_BG_EN(x) VAL_MASK(x, 1, 31) -#define WIN1_DSP_BG 0x000002b4 -#define V_WIN1_DSP_BG_BLUE(x) VAL_MASK(x, 8, 0) -#define V_WIN1_DSP_BG_GREEN(x) VAL_MASK(x, 8, 8) -#define V_WIN1_DSP_BG_RED(x) VAL_MASK(x, 8, 16) -#define V_WIN1_BG_EN(x) VAL_MASK(x, 1, 31) -#define WIN2_DSP_BG 0x000002b8 -#define V_WIN2_DSP_BG_BLUE(x) VAL_MASK(x, 8, 0) -#define V_WIN2_DSP_BG_GREEN(x) VAL_MASK(x, 8, 8) -#define V_WIN2_DSP_BG_RED(x) VAL_MASK(x, 8, 16) -#define V_WIN2_BG_EN(x) VAL_MASK(x, 1, 31) -#define WIN3_DSP_BG 0x000002bc -#define V_WIN3_DSP_BG_BLUE(x) VAL_MASK(x, 8, 0) -#define V_WIN3_DSP_BG_GREEN(x) VAL_MASK(x, 8, 8) -#define V_WIN3_DSP_BG_RED(x) VAL_MASK(x, 8, 16) -#define V_WIN3_BG_EN(x) VAL_MASK(x, 1, 31) -#define YUV2YUV_WIN 0x000002c0 -#define V_WIN0_YUV2YUV_EN(x) VAL_MASK(x, 1, 0) -#define V_WIN0_YUV2YUV_Y2R_EN(x) VAL_MASK(x, 1, 1) -#define V_WIN0_YUV2YUV_R2Y_EN(x) VAL_MASK(x, 1, 2) -#define V_WIN0_YUV2YUV_GAMMA_MODE(x) VAL_MASK(x, 1, 3) -#define V_WIN0_YUV2YUV_Y2R_MODE(x) VAL_MASK(x, 2, 4) -#define V_WIN0_YUV2YUV_R2Y_MODE(x) VAL_MASK(x, 2, 6) -#define V_WIN1_YUV2YUV_EN(x) VAL_MASK(x, 1, 8) -#define V_WIN1_YUV2YUV_Y2R_EN(x) VAL_MASK(x, 1, 9) -#define V_WIN1_YUV2YUV_R2Y_EN(x) VAL_MASK(x, 1, 10) -#define V_WIN1_YUV2YUV_GAMMA_MODE(x) VAL_MASK(x, 1, 11) -#define V_WIN1_YUV2YUV_Y2R_MODE(x) VAL_MASK(x, 2, 12) -#define V_WIN1_YUV2YUV_R2Y_MODE(x) VAL_MASK(x, 2, 14) -#define V_WIN2_YUV2YUV_EN(x) VAL_MASK(x, 1, 16) -#define V_WIN2_YUV2YUV_R2Y_EN(x) VAL_MASK(x, 1, 18) -#define V_WIN2_YUV2YUV_GAMMA_MODE(x) VAL_MASK(x, 1, 19) -#define V_WIN2_YUV2YUV_R2Y_MODE(x) VAL_MASK(x, 2, 22) -#define V_WIN3_YUV2YUV_EN(x) VAL_MASK(x, 1, 24) -#define V_WIN3_YUV2YUV_R2Y_EN(x) VAL_MASK(x, 1, 26) -#define V_WIN3_YUV2YUV_GAMMA_MODE(x) VAL_MASK(x, 1, 27) -#define V_WIN3_YUV2YUV_R2Y_MODE(x) VAL_MASK(x, 2, 30) -#define YUV2YUV_POST 0x000002c4 -#define V_YUV2YUV_POST_EN(x) VAL_MASK(x, 1, 0) -#define V_YUV2YUV_POST_Y2R_EN(x) VAL_MASK(x, 1, 1) -#define V_YUV2YUV_POST_R2Y_EN(x) VAL_MASK(x, 1, 2) -#define V_YUV2YUV_GAMMA_MODE(x) VAL_MASK(x, 1, 3) -#define V_YUV2YUV_POST_Y2R_MODE(x) VAL_MASK(x, 2, 4) -#define V_YUV2YUV_POST_R2Y_MODE(x) VAL_MASK(x, 2, 6) -#define AUTO_GATING_EN 0x000002cc -#define V_WIN0_ACLK_GATING_EN(x) VAL_MASK(x, 1, 0) -#define V_WIN1_ACLK_GATING_EN(x) VAL_MASK(x, 1, 1) -#define V_WIN2_ACLK_GATING_EN(x) VAL_MASK(x, 1, 2) -#define V_WIN3_ACLK_GATING_EN(x) VAL_MASK(x, 1, 3) -#define V_HWC_ACLK_GATING_EN(x) VAL_MASK(x, 1, 4) -#define V_OVERLAY_ACLK_GATING_EN(x) VAL_MASK(x, 1, 5) -#define V_GAMMA_ACLK_GATING_EN(x) VAL_MASK(x, 1, 6) -#define V_CABC_ACLK_GATING_EN(x) VAL_MASK(x, 1, 7) -#define V_WB_ACLK_GATING_EN(x) VAL_MASK(x, 1, 8) -#define V_PWM_PWMCLK_GATING_EN(x) VAL_MASK(x, 1, 9) -#define V_DIRECT_PATH_ACLK_GATING_EN(x) VAL_MASK(x, 1, 10) -#define V_FBCD0_ACLK_GATING_EN(x) VAL_MASK(x, 1, 12) -#define V_FBCD1_ACLK_GATING_EN(x) VAL_MASK(x, 1, 13) -#define V_FBCD2_ACLK_GATING_EN(x) VAL_MASK(x, 1, 14) -#define V_FBCD3_ACLK_GATING_EN(x) VAL_MASK(x, 1, 15) -#define DBG_PERF_LATENCY_CTRL0 0x00000300 -#define V_RD_LATENCY_EN(x) VAL_MASK(x, 1, 0) -#define V_HAND_LATENCY_CLR(x) VAL_MASK(x, 1, 1) -#define V_RD_LATENCY_MODE(x) VAL_MASK(x, 1, 2) -#define V_RD_LATENCY_ID0(x) VAL_MASK(x, 4, 4) -#define V_RD_LATENCY_THR(x) VAL_MASK(x, 12, 8) -#define V_RD_LATENCY_ST_NUM(x) VAL_MASK(x, 5, 20) -#define DBG_PERF_RD_MAX_LATENCY_NUM0 0x00000304 -#define V_RD_MAX_LATENCY_NUM_CH0(x) VAL_MASK(x, 12, 0) -#define V_RD_LATENCY_OVERFLOW_CH0(x) VAL_MASK(x, 1, 16) -#define DBG_PERF_RD_LATENCY_THR_NUM0 0x00000308 -#define V_RD_LATENCY_THR_NUM_CH0(x) VAL_MASK(x, 24, 0) -#define DBG_PERF_RD_LATENCY_SAMP_NUM0 0x0000030c -#define V_RD_LATENCY_SAMP_NUM_CH0(x) VAL_MASK(x, 24, 0) -#define DBG_CABC0 0x00000310 -#define DBG_CABC1 0x00000314 -#define DBG_CABC2 0x00000318 -#define V_PWM_MUL_POST_VALUE(x) VAL_MASK(x, 8, 8) -#define DBG_CABC3 0x0000031c -#define DBG_WIN0_REG0 0x00000320 -#define DBG_WIN0_REG1 0x00000324 -#define DBG_WIN0_REG2 0x00000328 -#define V_DBG_WIN0_YRGB_CMD_LINE_CNT(x) VAL_MASK(x, 13, 16) -#define DBG_WIN0_RESERVED 0x0000032c -#define DBG_WIN1_REG0 0x00000330 -#define DBG_WIN1_REG1 0x00000334 -#define DBG_WIN1_REG2 0x00000338 -#define DBG_WIN1_RESERVED 0x0000033c -#define DBG_WIN2_REG0 0x00000340 -#define DBG_WIN2_REG1 0x00000344 -#define DBG_WIN2_REG2 0x00000348 -#define DBG_WIN2_REG3 0x0000034c -#define DBG_WIN3_REG0 0x00000350 -#define DBG_WIN3_REG1 0x00000354 -#define DBG_WIN3_REG2 0x00000358 -#define DBG_WIN3_REG3 0x0000035c -#define DBG_PRE_REG0 0x00000360 -#define DBG_PRE_RESERVED 0x00000364 -#define DBG_POST_REG0 0x00000368 -#define DBG_POST_REG1 0x0000036c -#define V_GAMMA_A2HCLK_CHANGE_DONE(x) VAL_MASK(x, 1, 0) -#define V_WHICH_GAMMA_LUT_WORKING(x) VAL_MASK(x, 1, 1) -#define DBG_DATAO 0x00000370 -#define V_SW_DATAO_SEL(x) VAL_MASK(x, 2, 30) -#define DBG_DATAO_2 0x00000374 -#define V_VOP_DATA_O_2(x) VAL_MASK(x, 30, 0) -#define V_SW_DATAO_SEL_2(x) VAL_MASK(x, 2, 30) -#define WIN0_CSC_COE 0x000003a0 -#define WIN1_CSC_COE 0x000003c0 -#define WIN2_CSC_COE 0x000003e0 -#define WIN3_CSC_COE 0x00000400 -#define HWC_CSC_COE 0x00000420 -#define BCSH_R2Y_CSC_COE 0x00000440 -#define BCSH_Y2R_CSC_COE 0x00000460 -#define POST_YUV2YUV_Y2R_COE 0x00000480 -#define POST_YUV2YUV_3x3_COE 0x000004a0 -#define POST_YUV2YUV_R2Y_COE 0x000004c0 -#define WIN2_LUT_ADDR 0x00001000 -#define V_WIN2_LUT_ADDR(x) VAL_MASK(x, 32, 0) -#define WIN3_LUT_ADDR 0x00001400 -#define V_WIN3_LUT_ADDR(x) VAL_MASK(x, 32, 0) -#define HWC_LUT_ADDR 0x00001800 -#define V_HWC_LUT_ADDR(x) VAL_MASK(x, 32, 0) -#define CABC_GAMMA_LUT_ADDR 0x00001c00 -#define V_GAMMA_LUT_ADDR(x) VAL_MASK(x, 32, 0) -#define GAMMA_LUT_ADDR 0x00002000 -#define V_GAMMA_LUT_ADDR(x) VAL_MASK(x, 32, 0) -#define TVE 0x00003e00 - -#define INTR_FS (1 << 0) -#define INTR_FS_NEW (1 << 1) -#define INTR_ADDR_SAME (1 << 2) -#define INTR_LINE_FLAG0 (1 << 3) -#define INTR_LINE_FLAG1 (1 << 4) -#define INTR_BUS_ERROR (1 << 5) -#define INTR_WIN0_EMPTY (1 << 6) -#define INTR_WIN1_EMPTY (1 << 7) -#define INTR_WIN2_EMPTY (1 << 8) -#define INTR_WIN3_EMPTY (1 << 9) -#define INTR_HWC_EMPTY (1 << 10) -#define INTR_POST_BUF_EMPTY (1 << 11) -#define INTR_PWM_GEN (1 << 12) -#define INTR_DSP_HOLD_VALID (1 << 13) -#define INTR_MMU (1 << 14) -#define INTR_DMA_FINISH (1 << 15) - -#define INTR_MASK (INTR_FS | INTR_FS_NEW | INTR_ADDR_SAME | INTR_LINE_FLAG0 | \ - INTR_LINE_FLAG1 | INTR_BUS_ERROR | INTR_WIN0_EMPTY | \ - INTR_WIN1_EMPTY | INTR_WIN2_EMPTY | INTR_WIN3_EMPTY | \ - INTR_HWC_EMPTY | INTR_POST_BUF_EMPTY | INTR_PWM_GEN | \ - INTR_DSP_HOLD_VALID | INTR_MMU | INTR_DMA_FINISH) - -#define INTR1_FBCD0 (1 << 0) -#define INTR1_FBCD1 (1 << 1) -#define INTR1_FBCD2 (1 << 2) -#define INTR1_FBCD3 (1 << 3) -#define INTR1_AFBCD0_HREG_DEC_RESP (1 << 4) -#define INTR1_AFBCD0_HREG_AXI_RRESP (1 << 5) -#define INTR1_AFBCD1_HREG_DEC_RESP (1 << 6) -#define INTR1_AFBCD1_HREG_AXI_RRESP (1 << 7) -#define INTR1_AFBCD2_HREG_DEC_RESP (1 << 8) -#define INTR1_AFBCD2_HREG_AXI_RRESP (1 << 9) -#define INTR1_AFBCD3_HREG_DEC_RESP (1 << 10) -#define INTR1_AFBCD3_HREG_AXI_RRESP (1 << 11) -#define INTR1_WB_YRGB_FIFO_FULL (1 << 12) -#define INTR1_WB_UV_FIFO_FULL (1 << 13) -#define INTR1_WB_FINISH (1 << 14) - -#define OUT_CCIR656_MODE_0 5 -#define OUT_CCIR656_MODE_1 6 -#define OUT_CCIR656_MODE_2 7 - -struct vop_device { - int id; - struct rk_lcdc_driver driver; - struct device *dev; - struct rk_screen *screen; - - void __iomem *regs; - void *regsbak; - u32 reg_phy_base; - u32 len; - - /* one time only one process allowed to config the register */ - spinlock_t reg_lock; - - 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 *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; - - /* lock vop irq reg */ - spinlock_t irq_lock; -}; - -static inline void vop_writel(struct vop_device *vop_dev, u32 offset, u32 v) -{ - u32 *_pv = (u32 *)vop_dev->regsbak; - - _pv += (offset >> 2); - *_pv = v; - writel_relaxed(v, vop_dev->regs + offset); -} - -static inline u32 vop_readl(struct vop_device *vop_dev, u32 offset) -{ - u32 v; - - v = readl_relaxed(vop_dev->regs + offset); - return v; -} - -static inline u32 vop_readl_backup(struct vop_device *vop_dev, u32 offset) -{ - u32 v; - u32 *_pv = (u32 *)vop_dev->regsbak; - - _pv += (offset >> 2); - v = readl_relaxed(vop_dev->regs + offset); - *_pv = v; - return v; -} - -static inline u32 vop_read_bit(struct vop_device *vop_dev, u32 offset, u64 v) -{ - u32 _v = readl_relaxed(vop_dev->regs + offset); - - _v &= v >> 32; - v = (_v ? 1 : 0); - return v; -} - -static inline void vop_set_bit(struct vop_device *vop_dev, u32 offset, u64 v) -{ - u32 *_pv = (u32 *)vop_dev->regsbak; - - _pv += (offset >> 2); - (*_pv) |= v >> 32; - writel_relaxed(*_pv, vop_dev->regs + offset); -} - -static inline void vop_clr_bit(struct vop_device *vop_dev, u32 offset, u64 v) -{ - u32 *_pv = (u32 *)vop_dev->regsbak; - - _pv += (offset >> 2); - (*_pv) &= (~(v >> 32)); - writel_relaxed(*_pv, vop_dev->regs + offset); -} - -static inline void vop_msk_reg(struct vop_device *vop_dev, u32 offset, u64 v) -{ - u32 *_pv = (u32 *)vop_dev->regsbak; - - _pv += (offset >> 2); - (*_pv) &= (~(v >> 32)); - (*_pv) |= (u32)v; - writel_relaxed(*_pv, vop_dev->regs + offset); -} - -static inline void vop_mask_writel(struct vop_device *vop_dev, u32 offset, - u32 mask, u32 v) -{ - v = mask << 16 | v; - writel_relaxed(v , vop_dev->regs + offset); -} - -static inline void vop_cfg_done(struct vop_device *vop_dev) -{ - writel_relaxed(0x001f001f, vop_dev->regs + REG_CFG_DONE); - dsb(sy); -} - -static inline int vop_grf_writel(struct regmap *base, u32 offset, u32 val) -{ - regmap_write(base, offset, val); - dsb(sy); - - return 0; -} - -static inline int vop_cru_writel(struct regmap *base, u32 offset, u32 val) -{ - regmap_write(base, offset, val); - dsb(sy); - - return 0; -} - -static inline int vop_cru_readl(struct regmap *base, u32 offset) -{ - u32 v; - - regmap_read(base, offset, &v); - - return v; -} - -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 -}; - -#define IS_YUV(x) ((x) >= VOP_FORMAT_YCBCR420) - -enum _vop_overlay_mode { - VOP_RGB_DOMAIN, - VOP_YUV_DOMAIN -}; - -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; -}; - -#define CUBIC_PRECISE 0 -#define CUBIC_SPLINE 1 -#define CUBIC_CATROM 2 -#define CUBIC_MITCHELL 3 - -#define FBDC_FMT_RGB565 0x5 -#define FBDC_FMT_U8U8U8U8 0xc /*ARGB888*/ -#define FBDC_FMT_U8U8U8 0x3a /*RGBP888*/ - -#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 -#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 -/*****************************************************************/ - -/*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))) - -static inline u32 vop_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; -} - -#endif diff --git a/drivers/video/rockchip/lcdc/rk322x_lcdc.c b/drivers/video/rockchip/lcdc/rk322x_lcdc.c new file mode 100644 index 000000000000..d444b0b872ea --- /dev/null +++ b/drivers/video/rockchip/lcdc/rk322x_lcdc.c @@ -0,0 +1,3586 @@ +/* + * drivers/video/rockchip/lcdc/rk322x_lcdc.c + * + * Copyright (C) 2015 ROCKCHIP, Inc. + * Author: Mark Yao + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rk322x_lcdc.h" + +/*#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 const uint32_t csc_y2r_bt601_limit[12] = { + 0x04a8, 0, 0x0662, 0xfffc8654, + 0x04a8, 0xfe6f, 0xfcbf, 0x00022056, + 0x04a8, 0x0812, 0, 0xfffbaeac, +}; + +static const uint32_t csc_y2r_bt709_full[12] = { + 0x04a8, 0, 0x072c, 0xfffc219e, + 0x04a8, 0xff26, 0xfdde, 0x0001357b, + 0x04a8, 0x0873, 0, 0xfffb7dee, +}; + +static const uint32_t csc_y2r_bt601_full[12] = { + 0x0400, 0, 0x059c, 0xfffd342d, + 0x0400, 0xfea0, 0xfd25, 0x00021fcc, + 0x0400, 0x0717, 0, 0xfffc76bc, +}; + +static const uint32_t csc_y2r_bt601_limit_10[12] = { + 0x04a8, 0, 0x0662, 0xfff2134e, + 0x04a8, 0xfe6f, 0xfcbf, 0x00087b58, + 0x04a8, 0x0812, 0, 0xffeeb4b0, +}; + +static const uint32_t csc_y2r_bt709_full_10[12] = { + 0x04a8, 0, 0x072c, 0xfff08077, + 0x04a8, 0xff26, 0xfdde, 0x0004cfed, + 0x04a8, 0x0873, 0, 0xffedf1b8, +}; + +static const uint32_t csc_y2r_bt601_full_10[12] = { + 0x0400, 0, 0x059c, 0xfff4cab4, + 0x0400, 0xfea0, 0xfd25, 0x00087932, + 0x0400, 0x0717, 0, 0xfff1d4f2, +}; + +static const uint32_t csc_y2r_bt2020[12] = { + 0x04a8, 0, 0x06b6, 0xfff16bfc, + 0x04a8, 0xff40, 0xfd66, 0x58ae9, + 0x04a8, 0x0890, 0, 0xffedb828, +}; + +static const uint32_t csc_r2y_bt601_limit[12] = { + 0x0107, 0x0204, 0x0064, 0x04200, + 0xff68, 0xfed6, 0x01c2, 0x20200, + 0x01c2, 0xfe87, 0xffb7, 0x20200, +}; + +static const uint32_t csc_r2y_bt709_full[12] = { + 0x00bb, 0x0275, 0x003f, 0x04200, + 0xff99, 0xfea5, 0x01c2, 0x20200, + 0x01c2, 0xfe68, 0xffd7, 0x20200, +}; + +static const uint32_t csc_r2y_bt601_full[12] = { + 0x0132, 0x0259, 0x0075, 0x200, + 0xff53, 0xfead, 0x0200, 0x20200, + 0x0200, 0xfe53, 0xffad, 0x20200, +}; + +static const uint32_t csc_r2y_bt601_limit_10[12] = { + 0x0107, 0x0204, 0x0064, 0x10200, + 0xff68, 0xfed6, 0x01c2, 0x80200, + 0x01c2, 0xfe87, 0xffb7, 0x80200, +}; + +static const uint32_t csc_r2y_bt709_full_10[12] = { + 0x00bb, 0x0275, 0x003f, 0x10200, + 0xff99, 0xfea5, 0x01c2, 0x80200, + 0x01c2, 0xfe68, 0xffd7, 0x80200, +}; + +static const uint32_t csc_r2y_bt601_full_10[12] = { + 0x0132, 0x0259, 0x0075, 0x200, + 0xff53, 0xfead, 0x0200, 0x80200, + 0x0200, 0xfe53, 0xffad, 0x80200, +}; + +static const uint32_t csc_r2y_bt2020[12] = { + 0x00e6, 0x0253, 0x0034, 0x10200, + 0xff83, 0xfebd, 0x01c1, 0x80200, + 0x01c1, 0xfe64, 0xffdc, 0x80200, +}; + +static const uint32_t csc_r2r_bt2020to709[12] = { + 0x06a4, 0xfda6, 0xffb5, 0x200, + 0xff80, 0x0488, 0xfff8, 0x200, + 0xffed, 0xff99, 0x047a, 0x200, +}; + +static const uint32_t csc_r2r_bt709to2020[12] = { + 0x282, 0x151, 0x02c, 0x200, + 0x047, 0x3ae, 0x00c, 0x200, + 0x011, 0x05a, 0x395, 0x200, +}; + +static struct rk_lcdc_win vop_win[] = { + { .name = "win0", .id = 0}, + { .name = "win1", .id = 1}, + { .name = "hwc", .id = 2} +}; + +static void vop_load_csc_table(struct vop_device *vop_dev, u32 offset, + const uint32_t *table) +{ + uint32_t csc_val; + + csc_val = table[1] << 16 | table[0]; + vop_writel(vop_dev, offset, csc_val); + csc_val = table[4] << 16 | table[2]; + vop_writel(vop_dev, offset + 4, csc_val); + csc_val = table[6] << 16 | table[5]; + vop_writel(vop_dev, offset + 8, csc_val); + csc_val = table[9] << 16 | table[8]; + vop_writel(vop_dev, offset + 0xc, csc_val); + csc_val = table[10]; + vop_writel(vop_dev, offset + 0x10, csc_val); + csc_val = table[3]; + vop_writel(vop_dev, offset + 0x14, csc_val); + csc_val = table[7]; + vop_writel(vop_dev, offset + 0x18, csc_val); + csc_val = table[11]; + vop_writel(vop_dev, offset + 0x1c, csc_val); +} + +static int vop_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable); + +static int vop_clk_enable(struct vop_device *vop_dev) +{ + if (!vop_dev->clk_on) { + clk_prepare_enable(vop_dev->hclk); + clk_prepare_enable(vop_dev->dclk); + clk_prepare_enable(vop_dev->aclk); + spin_lock(&vop_dev->reg_lock); + vop_dev->clk_on = 1; + spin_unlock(&vop_dev->reg_lock); + } + + return 0; +} + +static int vop_clk_disable(struct vop_device *vop_dev) +{ + if (vop_dev->clk_on) { + spin_lock(&vop_dev->reg_lock); + vop_dev->clk_on = 0; + spin_unlock(&vop_dev->reg_lock); + mdelay(25); + clk_disable_unprepare(vop_dev->dclk); + clk_disable_unprepare(vop_dev->hclk); + clk_disable_unprepare(vop_dev->aclk); + } + + return 0; +} + +static int __maybe_unused vop_disable_irq(struct vop_device *vop_dev) +{ + if (likely(vop_dev->clk_on)) { + spin_lock(&vop_dev->reg_lock); + vop_writel(vop_dev, INTR_EN0, 0); + vop_writel(vop_dev, INTR_EN1, 0); + vop_writel(vop_dev, INTR_CLEAR0, 0xffff); + vop_writel(vop_dev, INTR_CLEAR1, 0xffff); + vop_cfg_done(vop_dev); + spin_unlock(&vop_dev->reg_lock); + }; + + return 0; +} + +static int vop_reg_dump(struct rk_lcdc_driver *dev_drv) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + int *cbase = (int *)vop_dev->regs; + int *regsbak = (int *)vop_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 vop_device *vop_dev, int en) \ +{ \ + spin_lock(&vop_dev->reg_lock); \ + vop_msk_reg(vop_dev, WIN##id##_CTRL0, V_WIN##id##_EN((u64)en)); \ + vop_cfg_done(vop_dev); \ + spin_unlock(&vop_dev->reg_lock); \ + return 0; \ +} + +WIN_EN(0); +WIN_EN(1); + +/*enable/disable win directly*/ +static int vop_win_direct_en(struct rk_lcdc_driver *drv, + int win_id, int en) +{ + struct vop_device *vop_dev = + container_of(drv, struct vop_device, driver); + if (win_id == 0) + win0_enable(vop_dev, en); + else if (win_id == 1) + win1_enable(vop_dev, en); + else + dev_err(vop_dev->dev, "invalid win number:%d\n", win_id); + return 0; +} + +#define SET_WIN_ADDR(id) \ +static int set_win##id##_addr(struct vop_device *vop_dev, u32 addr) \ +{ \ + spin_lock(&vop_dev->reg_lock); \ + vop_writel(vop_dev, WIN##id##_YRGB_MST, addr); \ + vop_msk_reg(vop_dev, WIN##id##_CTRL0, V_WIN##id##_EN(1)); \ + vop_cfg_done(vop_dev); \ + spin_unlock(&vop_dev->reg_lock); \ + return 0; \ +} + +SET_WIN_ADDR(0); +SET_WIN_ADDR(1); +int vop_direct_set_win_addr(struct rk_lcdc_driver *dev_drv, + int win_id, u32 addr) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + if (win_id == 0) + set_win0_addr(vop_dev, addr); + else + set_win1_addr(vop_dev, addr); + + return 0; +} + +static void lcdc_read_reg_defalut_cfg(struct vop_device *vop_dev) +{ + int reg = 0; + u32 val = 0; + struct rk_screen *screen = vop_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 = vop_dev->driver.win[0]; + + spin_lock(&vop_dev->reg_lock); + for (reg = 0; reg < vop_dev->len; reg += 4) { + val = vop_readl_backup(vop_dev, reg); + switch (reg) { + case WIN0_ACT_INFO: + win0->area[0].xact = (val & MASK(WIN0_ACT_WIDTH)) + 1; + win0->area[0].yact = + ((val & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1; + break; + case WIN0_DSP_INFO: + win0->area[0].xsize = (val & MASK(WIN0_DSP_WIDTH)) + 1; + win0->area[0].ysize = + ((val & MASK(WIN0_DSP_HEIGHT)) >> 16) + 1; + break; + case WIN0_DSP_ST: + st_x = val & MASK(WIN0_DSP_XST); + st_y = (val & MASK(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 & MASK(WIN0_EN); + win0->area[0].fmt_cfg = + (val & MASK(WIN0_DATA_FMT)) >> 1; + win0->fmt_10 = (val & MASK(WIN0_FMT_10)) >> 4; + win0->area[0].format = win0->area[0].fmt_cfg; + break; + case WIN0_VIR: + win0->area[0].y_vir_stride = + val & MASK(WIN0_VIR_STRIDE); + win0->area[0].uv_vir_stride = + (val & MASK(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 + 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(&vop_dev->reg_lock); +} + +/********do basic init*********/ +static int vop_pre_init(struct rk_lcdc_driver *dev_drv) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + if (vop_dev->pre_init) + return 0; + + vop_dev->hclk = devm_clk_get(vop_dev->dev, "hclk_lcdc"); + vop_dev->aclk = devm_clk_get(vop_dev->dev, "aclk_lcdc"); + vop_dev->dclk = devm_clk_get(vop_dev->dev, "dclk_lcdc"); + + if ((IS_ERR(vop_dev->aclk)) || (IS_ERR(vop_dev->dclk)) || + (IS_ERR(vop_dev->hclk))) { + dev_err(vop_dev->dev, "failed to get lcdc%d clk source\n", + vop_dev->id); + } + if (!support_uboot_display()) + rk_disp_pwr_enable(dev_drv); + vop_clk_enable(vop_dev); + + memcpy(vop_dev->regsbak, vop_dev->regs, vop_dev->len); + /*backup reg config at uboot */ + lcdc_read_reg_defalut_cfg(vop_dev); + #ifndef CONFIG_RK_FPGA + /* + * Todo, not verified + * + if (vop_dev->pwr18 == 1) { + v = 0x00200020; + vop_grf_writel(vop_dev->pmugrf_base, + PMUGRF_SOC_CON0_VOP, v); + } else { + v = 0x00200000; + vop_grf_writel(vop_dev->pmugrf_base, + PMUGRF_SOC_CON0_VOP, v); + } + */ + #endif + vop_writel(vop_dev, FRC_LOWER01_0, 0x12844821); + vop_writel(vop_dev, FRC_LOWER01_1, 0x21488412); + vop_writel(vop_dev, FRC_LOWER10_0, 0xa55a9696); + vop_writel(vop_dev, FRC_LOWER10_1, 0x5aa56969); + vop_writel(vop_dev, FRC_LOWER11_0, 0xdeb77deb); + vop_writel(vop_dev, FRC_LOWER11_1, 0xed7bb7de); + + vop_msk_reg(vop_dev, SYS_CTRL, V_AUTO_GATING_EN(0)); + vop_msk_reg(vop_dev, DSP_CTRL1, V_DITHER_UP_EN(1)); + vop_cfg_done(vop_dev); + vop_dev->pre_init = true; + + return 0; +} + +static void vop_deint(struct vop_device *vop_dev) +{ + if (vop_dev->clk_on) { + vop_disable_irq(vop_dev); + spin_lock(&vop_dev->reg_lock); + vop_msk_reg(vop_dev, WIN0_CTRL0, V_WIN0_EN(0)); + vop_msk_reg(vop_dev, WIN1_CTRL0, V_WIN0_EN(0)); + + vop_cfg_done(vop_dev); + spin_unlock(&vop_dev->reg_lock); + } +} + + +static void vop_win_csc_mode(struct vop_device *vop_dev, + struct rk_lcdc_win *win, + int csc_mode) +{ + u64 val; + + if (win->id == 0) { + val = V_WIN0_CSC_MODE(csc_mode); + vop_msk_reg(vop_dev, WIN0_CTRL0, val); + } else if (win->id == 1) { + val = V_WIN1_CSC_MODE(csc_mode); + vop_msk_reg(vop_dev, WIN1_CTRL0, val); + } else { + val = V_HWC_CSC_MODE(csc_mode); + vop_msk_reg(vop_dev, HWC_CTRL0, val); + } +} + +/* + * colorspace path: + * Input Win csc Post csc Output + * 1. YUV(2020) --> bypass ---+ Y2R->2020To709->R2Y --> YUV_OUTPUT(601/709) + * RGB --> R2Y(709) __/ + * + * 2. YUV(2020) --> bypass ---+ bypass --> YUV_OUTPUT(2020) + * RGB --> R2Y(709) __/ + * + * 3. YUV(2020) --> bypass ---+ Y2R->2020To709 --> RGB_OUTPUT(709) + * RGB --> R2Y(709) __/ + * + * 4. YUV(601/709)-> bypass ---+ Y2R->709To2020->R2Y --> YUV_OUTPUT(2020) + * RGB --> R2Y(709) __/ + * + * 5. YUV(601/709)-> bypass ---+ bypass --> YUV_OUTPUT(709) + * RGB --> R2Y(709) __/ + * + * 6. YUV(601/709)-> bypass ---+ bypass --> YUV_OUTPUT(601) + * RGB --> R2Y(601) __/ + * + * 7. YUV(601) --> Y2R(601/mpeg)-+ bypass --> RGB_OUTPUT(709) + * RGB --> bypass ____/ + * + * 8. YUV(709) --> Y2R(709/hd) --+ bypass --> RGB_OUTPUT(709) + * RGB --> bypass ____/ + * + * 9. RGB --> bypass ---> 709To2020->R2Y --> YUV_OUTPUT(2020) + * + * 10. RGB --> R2Y(709) ---> Y2R --> YUV_OUTPUT(709) + * + * 11. RGB --> R2Y(601) ---> Y2R --> YUV_OUTPUT(601) + * + * 12. RGB --> bypass ---> bypass --> RGB_OUTPUT(709) + */ + +static void vop_post_csc_cfg(struct rk_lcdc_driver *dev_drv) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + struct rk_lcdc_win *win; + int output_color = dev_drv->output_color; + int i, r2y_mode; + int overlay_mode; + int win_csc = COLOR_RGB; + u64 val; + + if (output_color == COLOR_RGB) + overlay_mode = VOP_RGB_DOMAIN; + else + overlay_mode = VOP_YUV_DOMAIN; + + if (output_color == COLOR_YCBCR) + r2y_mode = VOP_R2Y_CSC_BT601; + else + r2y_mode = VOP_R2Y_CSC_BT709; + + for (i = 0; i < dev_drv->lcdc_win_num; i++) { + win = dev_drv->win[i]; + if (!win->state) + continue; + /* + * force use yuv domain when there is a windows's csc is bt2020. + */ + if (win->colorspace == CSC_BT2020) { + overlay_mode = VOP_YUV_DOMAIN; + r2y_mode = VOP_R2Y_CSC_BT709; + win_csc = COLOR_YCBCR_BT2020; + break; + } + if (IS_YUV(win->area[0].fmt_cfg)) + win_csc = COLOR_YCBCR; + } + + for (i = 0; i < dev_drv->lcdc_win_num; i++) { + win = dev_drv->win[i]; + if (!win->state) + continue; + if (overlay_mode == VOP_YUV_DOMAIN && + !IS_YUV(win->area[0].fmt_cfg)) + vop_win_csc_mode(vop_dev, win, r2y_mode); + if (overlay_mode == VOP_RGB_DOMAIN && + IS_YUV(win->area[0].fmt_cfg)) { + if (win->colorspace == CSC_BT709) + vop_win_csc_mode(vop_dev, win, VOP_Y2R_CSC_HD); + else if (win->colorspace == CSC_BT601) + vop_win_csc_mode(vop_dev, win, + VOP_Y2R_CSC_MPEG); + else + pr_err("Error Y2R path, colorspace=%d\n", + win->colorspace); + } + } + + if (win_csc == COLOR_RGB && overlay_mode == VOP_YUV_DOMAIN) + win_csc = COLOR_YCBCR; + else if (IS_YUV_COLOR(win_csc) && overlay_mode == VOP_RGB_DOMAIN) + win_csc = COLOR_RGB; + + val = V_YUV2YUV_POST_Y2R_EN(0) | V_YUV2YUV_POST_EN(0) | + V_YUV2YUV_POST_R2Y_EN(0); + /* Y2R */ + if (win_csc == COLOR_YCBCR && output_color == COLOR_YCBCR_BT2020) { + win_csc = COLOR_RGB; + val |= V_YUV2YUV_POST_Y2R_EN(1); + vop_load_csc_table(vop_dev, POST_YUV2YUV_Y2R_COE, + csc_y2r_bt709_full); + } + if (win_csc == COLOR_YCBCR_BT2020 && + output_color != COLOR_YCBCR_BT2020) { + win_csc = COLOR_RGB_BT2020; + val |= V_YUV2YUV_POST_Y2R_EN(1); + vop_load_csc_table(vop_dev, POST_YUV2YUV_Y2R_COE, + csc_y2r_bt2020); + } + + /* R2R */ + if (win_csc == COLOR_RGB && output_color == COLOR_YCBCR_BT2020) { + win_csc = COLOR_RGB_BT2020; + val |= V_YUV2YUV_POST_EN(1); + vop_load_csc_table(vop_dev, POST_YUV2YUV_3x3_COE, + csc_r2r_bt709to2020); + } + if (win_csc == COLOR_RGB_BT2020 && + (output_color == COLOR_YCBCR || + output_color == COLOR_YCBCR_BT709 || + output_color == COLOR_RGB)) { + win_csc = COLOR_RGB; + val |= V_YUV2YUV_POST_EN(1); + vop_load_csc_table(vop_dev, POST_YUV2YUV_3x3_COE, + csc_r2r_bt2020to709); + } + + /* R2Y */ + if (!IS_YUV_COLOR(win_csc) && IS_YUV_COLOR(output_color)) { + val |= V_YUV2YUV_POST_R2Y_EN(1); + + if (output_color == COLOR_YCBCR_BT2020) + vop_load_csc_table(vop_dev, POST_YUV2YUV_R2Y_COE, + csc_r2y_bt2020); + else + vop_load_csc_table(vop_dev, POST_YUV2YUV_R2Y_COE, + csc_r2y_bt709_full); + } + + DBG(1, "win_csc=%d output_color=%d val=%llx overlay_mode=%d\n", + win_csc, output_color, val, overlay_mode); + vop_msk_reg(vop_dev, SYS_CTRL, V_OVERLAY_MODE(overlay_mode)); + vop_msk_reg(vop_dev, YUV2YUV_POST, val); +} + +static int vop_post_cfg(struct rk_lcdc_driver *dev_drv) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + struct rk_screen *screen = dev_drv->cur_screen; + u16 x_res = screen->mode.xres; + u16 y_res = screen->mode.yres; + u64 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; + + screen->post_dsp_stx = x_res * (100 - dev_drv->overscan.left) / 200; + screen->post_dsp_sty = y_res * (100 - dev_drv->overscan.top) / 200; + screen->post_xsize = x_res * + (dev_drv->overscan.left + dev_drv->overscan.right) / 200; + screen->post_ysize = y_res * + (dev_drv->overscan.top + dev_drv->overscan.bottom) / 200; + + 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(vop_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(vop_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->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->mode.vmode & FB_VMODE_INTERLACED) { + post_dsp_vact_st = screen->post_dsp_sty / 2 + + screen->mode.vsync_len + + screen->mode.upper_margin; + post_dsp_vact_end = post_dsp_vact_st + + screen->post_ysize / 2; + + post_dsp_vact_st_f1 = screen->mode.vsync_len + + screen->mode.upper_margin + + y_res / 2 + + screen->mode.lower_margin + + screen->mode.vsync_len + + screen->mode.upper_margin + + screen->post_dsp_sty / 2 + + 1; + post_dsp_vact_end_f1 = post_dsp_vact_st_f1 + + screen->post_ysize/2; + } else { + 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; + } + 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); + val = V_DSP_HACT_END_POST(post_dsp_hact_end) | + V_DSP_HACT_ST_POST(post_dsp_hact_st); + vop_msk_reg(vop_dev, POST_DSP_HACT_INFO, val); + + val = V_DSP_VACT_END_POST(post_dsp_vact_end) | + V_DSP_VACT_ST_POST(post_dsp_vact_st); + vop_msk_reg(vop_dev, POST_DSP_VACT_INFO, val); + + val = V_POST_HS_FACTOR_YRGB(post_h_fac) | + V_POST_VS_FACTOR_YRGB(post_v_fac); + vop_msk_reg(vop_dev, POST_SCL_FACTOR_YRGB, val); + val = V_DSP_VACT_END_POST(post_dsp_vact_end_f1) | + V_DSP_VACT_ST_POST(post_dsp_vact_st_f1); + vop_msk_reg(vop_dev, POST_DSP_VACT_INFO_F1, val); + val = V_POST_HOR_SD_EN(post_hsd_en) | V_POST_VER_SD_EN(post_vsd_en); + vop_msk_reg(vop_dev, POST_SCL_CTRL, val); + + vop_post_csc_cfg(dev_drv); + + return 0; +} + +static int vop_clr_key_cfg(struct rk_lcdc_driver *dev_drv) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + struct rk_lcdc_win *win; + u32 colorkey_r, colorkey_g, colorkey_b; + int i, key_val; + + for (i = 0; i < dev_drv->lcdc_win_num; 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: + vop_writel(vop_dev, WIN0_COLOR_KEY, key_val); + break; + case 1: + vop_writel(vop_dev, WIN1_COLOR_KEY, key_val); + break; + default: + pr_info("%s:un support win num:%d\n", + __func__, i); + break; + } + } + return 0; +} + +static int vop_alpha_cfg(struct rk_lcdc_driver *dev_drv, int win_id) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + struct rk_lcdc_win *win = dev_drv->win[win_id]; + struct alpha_config alpha_config; + u64 val; + int ppixel_alpha = 0, global_alpha = 0, i; + u32 src_alpha_ctl, dst_alpha_ctl; + int alpha_en = 1; + int layer_count = 0; + + for (i = 0; i < win->area_num; i++) { + ppixel_alpha |= ((win->area[i].format == ARGB888) || + (win->area[i].format == FBDC_ARGB_888) || + (win->area[i].format == FBDC_ABGR_888) || + (win->area[i].format == ABGR888)) ? 1 : 0; + } + + global_alpha = (win->g_alpha_val == 0) ? 0 : 1; + + for (i = 0; i < dev_drv->lcdc_win_num; i++) { + if (dev_drv->win[i]->state) + layer_count++; + } + /* + * vop not support ppixel_alpha mode when only enable 1 layer. + */ + if (layer_count == 1) + ppixel_alpha = 0; + alpha_config.src_global_alpha_val = win->g_alpha_val; + win->alpha_mode = AB_SRC_OVER; + + 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 + alpha_en = 0; + 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 = 0x160; + dst_alpha_ctl = 0x164; + break; + } + val = V_WIN0_DST_FACTOR_MODE(alpha_config.dst_factor_mode); + vop_msk_reg(vop_dev, dst_alpha_ctl, val); + val = V_WIN0_SRC_ALPHA_EN(alpha_en) | + V_WIN0_SRC_COLOR_MODE(alpha_config.src_color_mode) | + V_WIN0_SRC_ALPHA_MODE(alpha_config.src_alpha_mode) | + V_WIN0_SRC_BLEND_MODE(alpha_config.src_global_alpha_mode) | + V_WIN0_SRC_ALPHA_CAL_MODE(alpha_config.src_alpha_cal_m0) | + V_WIN0_SRC_FACTOR_MODE(alpha_config.src_factor_mode) | + V_WIN0_SRC_GLOBAL_ALPHA(alpha_config.src_global_alpha_val); + + vop_msk_reg(vop_dev, src_alpha_ctl, val); + + return 0; +} + +static int vop_axi_gather_cfg(struct vop_device *vop_dev, + struct rk_lcdc_win *win) +{ + u64 val; + u16 yrgb_gather_num = 3; + u16 cbcr_gather_num = 1; + + switch (win->area[0].format) { + case ARGB888: + case XBGR888: + case ABGR888: + yrgb_gather_num = 3; + break; + case RGB888: + case RGB565: + yrgb_gather_num = 2; + break; + case YUV444: + case YUV422: + case YUV420: + case YUV420_NV21: + yrgb_gather_num = 1; + cbcr_gather_num = 2; + break; + default: + dev_err(vop_dev->driver.dev, "%s:un supported format!\n", + __func__); + return -EINVAL; + } + + if ((win->id == 0) || (win->id == 1)) { + val = V_WIN0_YRGB_AXI_GATHER_EN(1) | + V_WIN0_CBR_AXI_GATHER_EN(1) | + V_WIN0_YRGB_AXI_GATHER_NUM(yrgb_gather_num) | + V_WIN0_CBR_AXI_GATHER_NUM(cbcr_gather_num); + vop_msk_reg(vop_dev, WIN0_CTRL1 + (win->id * 0x40), val); + } else if (win->id == 2) { + val = V_HWC_AXI_GATHER_EN(1) | + V_HWC_AXI_GATHER_NUM(yrgb_gather_num); + vop_msk_reg(vop_dev, HWC_CTRL1, val); + } + return 0; +} + +static int vop_win_0_1_reg_update(struct rk_lcdc_driver *dev_drv, int win_id) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + struct rk_lcdc_win *win = dev_drv->win[win_id]; + u64 val; + uint32_t off; + + off = win_id * 0x40; + + if (win->state == 1) { + vop_axi_gather_cfg(vop_dev, win); + 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_MIR_EN(win->mirror_en) | + V_WIN0_Y_MIR_EN(win->mirror_en) | + V_WIN0_UV_SWAP(win->area[0].swap_uv); + vop_msk_reg(vop_dev, WIN0_CTRL0 + off, val); + 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); + vop_msk_reg(vop_dev, WIN0_CTRL1 + off, val); + val = V_WIN0_VIR_STRIDE(win->area[0].y_vir_stride) | + V_WIN0_VIR_STRIDE_UV(win->area[0].uv_vir_stride); + vop_writel(vop_dev, WIN0_VIR + off, val); + val = V_WIN0_ACT_WIDTH(win->area[0].xact - 1) | + V_WIN0_ACT_HEIGHT(win->area[0].yact - 1); + vop_writel(vop_dev, WIN0_ACT_INFO + off, val); + + val = V_WIN0_DSP_WIDTH(win->area[0].xsize - 1) | + V_WIN0_DSP_HEIGHT(win->area[0].ysize - 1); + vop_writel(vop_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); + vop_writel(vop_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); + vop_writel(vop_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); + vop_writel(vop_dev, WIN0_SCL_FACTOR_CBR + off, val); + if (win->alpha_en == 1) { + vop_alpha_cfg(dev_drv, win_id); + } else { + val = V_WIN0_SRC_ALPHA_EN(0); + vop_msk_reg(vop_dev, WIN0_SRC_ALPHA_CTRL + off, val); + } + + if (dev_drv->cur_screen->mode.vmode & FB_VMODE_INTERLACED) { + if (win->area[0].yact == 2 * win->area[0].ysize) + val = V_WIN0_YRGB_DEFLICK(0) | + V_WIN0_CBR_DEFLICK(0); + else + val = V_WIN0_YRGB_DEFLICK(1) | + V_WIN0_CBR_DEFLICK(1); + vop_msk_reg(vop_dev, WIN0_CTRL0, val); + } + } else { + val = V_WIN0_EN(win->state); + vop_msk_reg(vop_dev, WIN0_CTRL0 + off, val); + } + + return 0; +} + +static int vop_hwc_reg_update(struct rk_lcdc_driver *dev_drv, int win_id) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + struct rk_lcdc_win *win = dev_drv->win[win_id]; + unsigned int hwc_size = 0; + u64 val; + + if (win->state == 1) { + vop_axi_gather_cfg(vop_dev, win); + val = V_HWC_EN(1) | V_HWC_DATA_FMT(win->area[0].fmt_cfg) | + V_HWC_RB_SWAP(win->area[0].swap_rb); + vop_msk_reg(vop_dev, HWC_CTRL0, 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(vop_dev->dev, "un supported hwc size!\n"); + + val = V_HWC_SIZE(hwc_size); + vop_msk_reg(vop_dev, HWC_CTRL0, val); + + val = V_HWC_DSP_XST(win->area[0].dsp_stx) | + V_HWC_DSP_YST(win->area[0].dsp_sty); + vop_msk_reg(vop_dev, HWC_DSP_ST, val); + + if (win->alpha_en == 1) { + vop_alpha_cfg(dev_drv, win_id); + } else { + val = V_WIN2_SRC_ALPHA_EN(0); + vop_msk_reg(vop_dev, HWC_SRC_ALPHA_CTRL, val); + } + } else { + val = V_HWC_EN(win->state); + vop_msk_reg(vop_dev, HWC_CTRL0, val); + } + + return 0; +} + +static int vop_layer_update_regs(struct vop_device *vop_dev, + struct rk_lcdc_win *win) +{ + struct rk_lcdc_driver *dev_drv = &vop_dev->driver; + + if (likely(vop_dev->clk_on)) { + vop_msk_reg(vop_dev, SYS_CTRL, + V_VOP_STANDBY_EN(vop_dev->standby)); + if ((win->id == 0) || (win->id == 1)) + vop_win_0_1_reg_update(dev_drv, win->id); + else if (win->id == 2) + vop_hwc_reg_update(dev_drv, win->id); + vop_cfg_done(vop_dev); + } + + DBG(2, "%s for lcdc%d\n", __func__, vop_dev->id); + return 0; +} + +static int __maybe_unused vop_mmu_en(struct rk_lcdc_driver *dev_drv) +{ + u64 val; + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + + if (unlikely(!vop_dev->clk_on)) { + pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on); + return 0; + } +#if defined(CONFIG_ROCKCHIP_IOMMU) + if (dev_drv->iommu_enabled) { + if (!vop_dev->iommu_status && dev_drv->mmu_dev) { + if (likely(vop_dev->clk_on)) { + val = V_VOP_MMU_EN(1); + vop_msk_reg(vop_dev, SYS_CTRL, val); + val = V_AXI_OUTSTANDING_MAX_NUM(31) | + V_AXI_MAX_OUTSTANDING_EN(1); + vop_msk_reg(vop_dev, SYS_CTRL1, val); + } + vop_dev->iommu_status = 1; + rockchip_iovmm_activate(dev_drv->dev); + } + } +#endif + return 0; +} + +static int vop_set_dclk(struct rk_lcdc_driver *dev_drv, int reset_rate) +{ + int ret = 0, fps = 0; + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + struct rk_screen *screen = dev_drv->cur_screen; +#ifdef CONFIG_RK_FPGA + return 0; +#endif + if (reset_rate) + ret = clk_set_rate(vop_dev->dclk, screen->mode.pixclock); + if (ret) + dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", vop_dev->id); + vop_dev->pixclock = + div_u64(1000000000000llu, clk_get_rate(vop_dev->dclk)); + vop_dev->driver.pixclock = vop_dev->pixclock; + + fps = rk_fb_calc_fps(screen, vop_dev->pixclock); + screen->ft = 1000 / fps; + dev_info(vop_dev->dev, "%s: dclk:%lu>>fps:%d ", + vop_dev->driver.name, clk_get_rate(vop_dev->dclk), fps); + return 0; +} + +static int vop_config_timing(struct rk_lcdc_driver *dev_drv) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_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; + u64 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; + + val = V_DSP_HS_END(hsync_len) | V_DSP_HTOTAL(h_total); + vop_msk_reg(vop_dev, DSP_HTOTAL_HS_END, val); + + val = V_DSP_HACT_END(hsync_len + left_margin + x_res) | + V_DSP_HACT_ST(hsync_len + left_margin); + vop_msk_reg(vop_dev, DSP_HACT_ST_END, val); + + if (screen->mode.vmode & FB_VMODE_INTERLACED) { + /* First Field Timing */ + val = V_DSP_VS_END(vsync_len) | + V_DSP_VTOTAL(2 * (vsync_len + upper_margin + + lower_margin) + y_res + 1); + vop_msk_reg(vop_dev, DSP_VTOTAL_VS_END, val); + + val = V_DSP_VACT_END(vsync_len + upper_margin + y_res / 2) | + V_DSP_VACT_ST(vsync_len + upper_margin); + vop_msk_reg(vop_dev, DSP_VACT_ST_END, val); + + /* Second Field Timing */ + 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); + vop_msk_reg(vop_dev, DSP_VS_ST_END_F1, val); + + 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_VACT_ST_F1(vact_st_f1); + vop_msk_reg(vop_dev, DSP_VACT_ST_END_F1, val); + vop_msk_reg(vop_dev, DSP_CTRL0, + V_DSP_INTERLACE(1) | V_DSP_FIELD_POL(0)); + val = V_WIN0_INTERLACE_READ(1) | V_WIN0_YRGB_DEFLICK(0) | + V_WIN0_CBR_DEFLICK(0); + vop_msk_reg(vop_dev, WIN0_CTRL0, val); + + val = V_WIN1_INTERLACE_READ(1) | V_WIN1_YRGB_DEFLICK(0) | + V_WIN1_CBR_DEFLICK(0); + vop_msk_reg(vop_dev, WIN1_CTRL0, val); + + val = V_WIN2_INTERLACE_READ(1); + vop_msk_reg(vop_dev, WIN2_CTRL0, val); + + val = V_WIN3_INTERLACE_READ(1); + vop_msk_reg(vop_dev, WIN3_CTRL0, val); + + val = V_HWC_INTERLACE_READ(1); + vop_msk_reg(vop_dev, HWC_CTRL0, val); + + val = V_DSP_LINE_FLAG_NUM_0(vact_end_f1) | + V_DSP_LINE_FLAG_NUM_1(vact_end_f1); + vop_msk_reg(vop_dev, LINE_FLAG, val); + } else { + val = V_DSP_VS_END(vsync_len) | V_DSP_VTOTAL(v_total); + vop_msk_reg(vop_dev, DSP_VTOTAL_VS_END, val); + + val = V_DSP_VACT_END(vsync_len + upper_margin + y_res) | + V_DSP_VACT_ST(vsync_len + upper_margin); + vop_msk_reg(vop_dev, DSP_VACT_ST_END, val); + + vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_INTERLACE(0) | + V_DSP_FIELD_POL(0)); + + val = V_WIN0_INTERLACE_READ(0) | V_WIN0_YRGB_DEFLICK(0) | + V_WIN0_CBR_DEFLICK(0); + vop_msk_reg(vop_dev, WIN0_CTRL0, val); + + val = V_WIN1_INTERLACE_READ(0) | V_WIN1_YRGB_DEFLICK(0) | + V_WIN1_CBR_DEFLICK(0); + vop_msk_reg(vop_dev, WIN1_CTRL0, val); + + val = V_WIN2_INTERLACE_READ(0); + vop_msk_reg(vop_dev, WIN2_CTRL0, val); + + val = V_WIN3_INTERLACE_READ(0); + vop_msk_reg(vop_dev, WIN3_CTRL0, val); + + val = V_HWC_INTERLACE_READ(0); + vop_msk_reg(vop_dev, HWC_CTRL0, val); + + val = V_DSP_LINE_FLAG_NUM_0(vsync_len + upper_margin + y_res) | + V_DSP_LINE_FLAG_NUM_1(vsync_len + upper_margin + y_res); + vop_msk_reg(vop_dev, LINE_FLAG, val); + } + vop_post_cfg(dev_drv); + + return 0; +} + +static void vop_bcsh_path_sel(struct rk_lcdc_driver *dev_drv) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + u32 bcsh_ctrl; + + vop_msk_reg(vop_dev, SYS_CTRL, V_OVERLAY_MODE(dev_drv->overlay_mode)); + if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) { + if (dev_drv->output_color == COLOR_YCBCR) /* bypass */ + vop_msk_reg(vop_dev, BCSH_CTRL, + V_BCSH_Y2R_EN(0) | V_BCSH_R2Y_EN(0)); + else /* YUV2RGB */ + vop_msk_reg(vop_dev, BCSH_CTRL, 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 = vop_readl(vop_dev, BCSH_CTRL); + if (((bcsh_ctrl & MASK(BCSH_EN)) == 1) || + (dev_drv->bcsh.enable == 1))/*bcsh enabled */ + vop_msk_reg(vop_dev, BCSH_CTRL, + V_BCSH_R2Y_EN(1) | + V_BCSH_Y2R_EN(1)); + else + vop_msk_reg(vop_dev, BCSH_CTRL, + V_BCSH_R2Y_EN(0) | + V_BCSH_Y2R_EN(0)); + } else { + /* RGB2YUV */ + vop_msk_reg(vop_dev, BCSH_CTRL, + V_BCSH_R2Y_EN(1) | + V_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG) | + V_BCSH_Y2R_EN(0)); + } + } +} + +static int vop_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact, + u16 *yact, int *format, u32 *dsp_addr) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + u32 val; + + spin_lock(&vop_dev->reg_lock); + + val = vop_readl(vop_dev, WIN0_ACT_INFO); + *xact = (val & MASK(WIN0_ACT_WIDTH)) + 1; + *yact = ((val & MASK(WIN0_ACT_HEIGHT))>>16) + 1; + + val = vop_readl(vop_dev, WIN0_CTRL0); + *format = (val & MASK(WIN0_DATA_FMT)) >> 1; + *dsp_addr = vop_readl(vop_dev, WIN0_YRGB_MST); + + spin_unlock(&vop_dev->reg_lock); + + return 0; +} + +static int vop_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst, + int format, u16 xact, u16 yact, u16 xvir) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + int swap = (format == RGB888) ? 1 : 0; + u64 val; + + val = V_WIN0_DATA_FMT(format) | V_WIN0_RB_SWAP(swap); + vop_msk_reg(vop_dev, WIN0_CTRL0, val); + + vop_msk_reg(vop_dev, WIN0_VIR, V_WIN0_VIR_STRIDE(xvir)); + vop_writel(vop_dev, WIN0_ACT_INFO, V_WIN0_ACT_WIDTH(xact - 1) | + V_WIN0_ACT_HEIGHT(yact - 1)); + + vop_writel(vop_dev, WIN0_YRGB_MST, rgb_mst); + + vop_cfg_done(vop_dev); + + return 0; +} + +/* +static int lcdc_reset(struct rk_lcdc_driver *dev_drv, bool initscreen) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + u64 val; + u32 __maybe_unused v; + + if (!vop_dev->standby && initscreen && (dev_drv->first_frame != 1)) { + mdelay(150); + val = V_WIN0_EN(0); + vop_msk_reg(vop_dev, WIN0_CTRL0, val); + vop_msk_reg(vop_dev, WIN1_CTRL0, val); + + 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); + vop_msk_reg(vop_dev, WIN2_CTRL0, val); + vop_msk_reg(vop_dev, WIN3_CTRL0, val); + val = V_HDMI_OUT_EN(0); + vop_msk_reg(vop_dev, SYS_CTRL, val); + vop_cfg_done(vop_dev); + mdelay(50); + vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(1)); + writel_relaxed(0, vop_dev->regs + REG_CFG_DONE); + mdelay(50); + } + + return 0; +} +*/ + +static int vop_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) +{ + u16 face = 0; + u16 dclk_ddr = 0; + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + struct rk_screen *screen = dev_drv->cur_screen; + u64 val; + + if (unlikely(!vop_dev->clk_on)) { + pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on); + return 0; + } + + if (!vop_dev->standby && initscreen && (dev_drv->first_frame != 1)) + flush_kthread_worker(&dev_drv->update_regs_worker); + + spin_lock(&vop_dev->reg_lock); + if (likely(vop_dev->clk_on)) { + switch (screen->face) { + case OUT_P888: + face = OUT_P888; + val = V_DITHER_DOWN_EN(0); + break; + case OUT_YUV_420: + /*yuv420 output prefer yuv domain overlay */ + face = OUT_YUV_420; + dclk_ddr = 1; + val = V_DITHER_DOWN_EN(0); + break; + default: + dev_err(vop_dev->dev, "un supported interface!\n"); + break; + } + + vop_msk_reg(vop_dev, DSP_CTRL1, val); + switch (screen->type) { + case SCREEN_TVOUT: + val = V_SW_UV_OFFSET_EN(1) | V_SW_IMD_TVE_DCLK_EN(1) | + V_SW_IMD_TVE_DCLK_EN(1) | + V_SW_IMD_TVE_DCLK_POL(1) | + V_SW_GENLOCK(1) | V_SW_DAC_SEL(1); + if (screen->mode.xres == 720 && + screen->mode.yres == 576) + val |= V_SW_TVE_MODE(1); + else + val |= V_SW_TVE_MODE(0); + vop_msk_reg(vop_dev, SYS_CTRL, val); + break; + case SCREEN_HDMI: + val = V_HDMI_OUT_EN(1) | V_SW_UV_OFFSET_EN(0); + vop_msk_reg(vop_dev, SYS_CTRL, val); + break; + default: + dev_err(vop_dev->dev, "un supported interface!\n"); + break; + } + 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); + /*hsync vsync den dclk polo,dither */ + vop_msk_reg(vop_dev, DSP_CTRL1, val); + + if (screen->color_mode == COLOR_RGB) + dev_drv->overlay_mode = VOP_RGB_DOMAIN; + else + dev_drv->overlay_mode = VOP_YUV_DOMAIN; + +#ifndef CONFIG_RK_FPGA + /* + * Todo: + * writel_relaxed(v, RK_GRF_VIRT + vop_GRF_SOC_CON7); + * move to lvds driver + */ + /*GRF_SOC_CON7 bit[15]:0->dsi/lvds mode,1->ttl mode */ +#endif + 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); + if (screen->pixelrepeat) + val |= V_SW_CORE_DCLK_SEL(1); + if (screen->mode.vmode & FB_VMODE_INTERLACED) + val |= V_SW_HDMI_CLK_I_SEL(1); + vop_msk_reg(vop_dev, DSP_CTRL0, val); + /* BG color */ + if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) + val = V_DSP_BG_BLUE(0x80) | V_DSP_BG_GREEN(0x10) | + V_DSP_BG_RED(0x80); + else + val = V_DSP_BG_BLUE(0) | V_DSP_BG_GREEN(0) | + V_DSP_BG_RED(0); + vop_msk_reg(vop_dev, DSP_BG, val); + dev_drv->output_color = screen->color_mode; + vop_bcsh_path_sel(dev_drv); + vop_config_timing(dev_drv); + vop_cfg_done(vop_dev); + } + spin_unlock(&vop_dev->reg_lock); + vop_set_dclk(dev_drv, 1); + if (screen->type != SCREEN_HDMI && screen->type != SCREEN_TVOUT && + dev_drv->trsm_ops && dev_drv->trsm_ops->enable) + dev_drv->trsm_ops->enable(); + if (screen->init) + screen->init(); + + return 0; +} + +/*enable layer,open:1,enable;0 disable*/ +static void vop_layer_enable(struct vop_device *vop_dev, + unsigned int win_id, bool open) +{ + spin_lock(&vop_dev->reg_lock); + if (likely(vop_dev->clk_on) && + vop_dev->driver.win[win_id]->state != open) { + if (open) { + if (!vop_dev->atv_layer_cnt) { + dev_info(vop_dev->dev, + "wakeup from standby!\n"); + vop_dev->standby = 0; + } + vop_dev->atv_layer_cnt |= (1 << win_id); + } else { + if (vop_dev->atv_layer_cnt & (1 << win_id)) + vop_dev->atv_layer_cnt &= ~(1 << win_id); + } + vop_dev->driver.win[win_id]->state = open; + if (!open) { + vop_layer_update_regs(vop_dev, + vop_dev->driver.win[win_id]); + vop_cfg_done(vop_dev); + } + /* if no layer used,disable lcdc */ + if (!vop_dev->atv_layer_cnt) { + dev_info(vop_dev->dev, + "no layer is used,go to standby!\n"); + vop_dev->standby = 1; + } + } + spin_unlock(&vop_dev->reg_lock); +} + +static int vop_enable_irq(struct rk_lcdc_driver *dev_drv) +{ + struct vop_device *vop_dev = container_of(dev_drv, + struct vop_device, driver); + u64 val; + /* struct rk_screen *screen = dev_drv->cur_screen; */ + + vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, INTR_MASK); + + val = INTR_FS | INTR_LINE_FLAG0 | INTR_BUS_ERROR | INTR_LINE_FLAG1; + vop_mask_writel(vop_dev, INTR_EN0, INTR_MASK, val); + + return 0; +} + +static int vop_open(struct rk_lcdc_driver *dev_drv, int win_id, + bool open) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + + /* enable clk,when first layer open */ + if ((open) && (!vop_dev->atv_layer_cnt)) { + /* rockchip_set_system_status(sys_status); */ + vop_pre_init(dev_drv); + vop_clk_enable(vop_dev); + vop_enable_irq(dev_drv); +#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; + } + } + } +#endif + if ((support_uboot_display() && (vop_dev->prop == PRMRY))) + vop_set_dclk(dev_drv, 0); + else + vop_load_screen(dev_drv, 1); + if (dev_drv->bcsh.enable) + vop_set_bcsh(dev_drv, 1); + spin_lock(&vop_dev->reg_lock); + spin_unlock(&vop_dev->reg_lock); + } + + if (win_id < ARRAY_SIZE(vop_win)) + vop_layer_enable(vop_dev, win_id, open); + else + dev_err(vop_dev->dev, "invalid win id:%d\n", win_id); + + dev_drv->first_frame = 0; + return 0; +} + +static int win_0_1_display(struct vop_device *vop_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", + vop_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(&vop_dev->reg_lock); + if (likely(vop_dev->clk_on)) { + win->area[0].y_addr = y_addr; + win->area[0].uv_addr = uv_addr; + vop_writel(vop_dev, WIN0_YRGB_MST + off, win->area[0].y_addr); + vop_writel(vop_dev, WIN0_CBR_MST + off, win->area[0].uv_addr); + } + spin_unlock(&vop_dev->reg_lock); + + return 0; +} + +static int hwc_display(struct vop_device *vop_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", + vop_dev->id, __func__, y_addr); + spin_lock(&vop_dev->reg_lock); + if (likely(vop_dev->clk_on)) { + win->area[0].y_addr = y_addr; + vop_writel(vop_dev, HWC_MST, win->area[0].y_addr); + } + spin_unlock(&vop_dev->reg_lock); + + return 0; +} + +static int vop_pan_display(struct rk_lcdc_driver *dev_drv, int win_id) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + struct rk_lcdc_win *win = NULL; + struct rk_screen *screen = dev_drv->cur_screen; + + win = dev_drv->win[win_id]; + if (!screen) { + dev_err(dev_drv->dev, "screen is null!\n"); + return -ENOENT; + } + if (unlikely(!vop_dev->clk_on)) { + pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on); + return 0; + } + if (win_id == 0) { + win_0_1_display(vop_dev, win); + } else if (win_id == 1) { + win_0_1_display(vop_dev, win); + } else if (win_id == 2) { + hwc_display(vop_dev, win); + } else { + dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id); + return -EINVAL; + } + + return 0; +} + +static int vop_cal_scl_fac(struct rk_lcdc_win *win, struct rk_screen *screen) +{ + 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; + if ((screen->mode.vmode & FB_VMODE_INTERLACED) && + (win->area[0].yact == 2 * win->area[0].ysize)) { + srcH = win->area[0].yact / 2; + yrgb_vsd_bil_gt2 = 1; + cbcr_vsd_bil_gt2 = 1; + } else { + 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: + case YUV420_NV21: + 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; + + /* line buffer mode */ + if ((win->area[0].format == YUV422) || + (win->area[0].format == YUV420) || + (win->area[0].format == YUV420_NV21) || + (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) + win->yrgb_vsd_mode = SCALE_DOWN_BIL; + if (screen->mode.vmode & FB_VMODE_INTERLACED) { + /* interlace mode must bill */ + win->yrgb_vsd_mode = SCALE_DOWN_BIL; + win->cbr_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; + } + + /* (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 = + vop_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 less 0x2000"); + pr_err("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 = + vop_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 dsp_x_pos(int mirror_en, struct rk_screen *screen, + struct rk_lcdc_win_area *area) +{ + int pos; + + if (screen->x_mirror && mirror_en) + pr_err("not support both win and global mirror\n"); + + if ((!mirror_en) && (!screen->x_mirror)) + pos = area->xpos + screen->mode.left_margin + + screen->mode.hsync_len; + else + pos = screen->mode.xres - area->xpos - + area->xsize + screen->mode.left_margin + + screen->mode.hsync_len; + + return pos; +} + +static int dsp_y_pos(int mirror_en, struct rk_screen *screen, + struct rk_lcdc_win_area *area) +{ + int pos; + + if (screen->y_mirror && mirror_en) + pr_err("not support both win and global mirror\n"); + if (screen->mode.vmode & FB_VMODE_NONINTERLACED) { + if ((!mirror_en) && (!screen->y_mirror)) + pos = area->ypos + screen->mode.upper_margin + + screen->mode.vsync_len; + else + pos = screen->mode.yres - area->ypos - + area->ysize + screen->mode.upper_margin + + screen->mode.vsync_len; + } else if (screen->mode.vmode & FB_VMODE_INTERLACED) { + pos = area->ypos / 2 + screen->mode.upper_margin + + screen->mode.vsync_len; + } + + return pos; +} + +static int win_0_1_set_par(struct vop_device *vop_dev, + struct rk_screen *screen, struct rk_lcdc_win *win) +{ + u32 xact, yact, xvir, yvir, xpos, ypos; + u8 fmt_cfg = 0, swap_rb, swap_uv = 0; + char fmt[9] = "NULL"; + + xpos = dsp_x_pos(win->mirror_en, screen, &win->area[0]); + ypos = dsp_y_pos(win->mirror_en, screen, &win->area[0]); + + spin_lock(&vop_dev->reg_lock); + if (likely(vop_dev->clk_on)) { + vop_cal_scl_fac(win, screen); + switch (win->area[0].format) { + case FBDC_RGB_565: + fmt_cfg = 2; + swap_rb = 0; + win->fmt_10 = 0; + win->area[0].fbdc_fmt_cfg = 0x05; + break; + case FBDC_ARGB_888: + fmt_cfg = 0; + swap_rb = 0; + win->fmt_10 = 0; + win->area[0].fbdc_fmt_cfg = 0x0c; + break; + case FBDC_ABGR_888: + fmt_cfg = 0; + swap_rb = 1; + win->fmt_10 = 0; + win->area[0].fbdc_fmt_cfg = 0x0c; + break; + case FBDC_RGBX_888: + fmt_cfg = 0; + swap_rb = 0; + win->fmt_10 = 0; + win->area[0].fbdc_fmt_cfg = 0x3a; + break; + 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 YUV420_NV21: + fmt_cfg = 4; + swap_rb = 0; + swap_uv = 1; + 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(vop_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].swap_uv = swap_uv; + 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; + } + vop_win_0_1_reg_update(&vop_dev->driver, win->id); + spin_unlock(&vop_dev->reg_lock); + + DBG(1, "lcdc[%d]:win[%d]\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d", + vop_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 hwc_set_par(struct vop_device *vop_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(&vop_dev->reg_lock); + if (likely(vop_dev->clk_on)) { + 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(vop_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; + } + vop_hwc_reg_update(&vop_dev->driver, 4); + spin_unlock(&vop_dev->reg_lock); + + DBG(1, "lcdc[%d]:hwc>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d", + vop_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 vop_set_par(struct rk_lcdc_driver *dev_drv, int win_id) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + struct rk_lcdc_win *win = NULL; + struct rk_screen *screen = dev_drv->cur_screen; + + if (unlikely(!vop_dev->clk_on)) { + pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on); + return 0; + } + win = dev_drv->win[win_id]; + switch (win_id) { + case 0: + win_0_1_set_par(vop_dev, screen, win); + break; + case 1: + win_0_1_set_par(vop_dev, screen, win); + break; + case 2: + hwc_set_par(vop_dev, screen, win); + break; + default: + dev_err(dev_drv->dev, "unsupported win number:%d\n", win_id); + break; + } + return 0; +} + +static int vop_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd, + unsigned long arg, int win_id) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_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] = vop_dev->screen->mode.xres; + panel_size[1] = vop_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; + vop_clr_key_cfg(dev_drv); + vop_writel(vop_dev, WIN0_COLOR_KEY, + clr_key_cfg.win0_color_key_cfg); + vop_writel(vop_dev, WIN1_COLOR_KEY, + clr_key_cfg.win1_color_key_cfg); + break; + + default: + break; + } + return 0; +} + +static int vop_get_backlight_device(struct rk_lcdc_driver *dev_drv) +{ + struct vop_device *vop_dev = container_of(dev_drv, + struct vop_device, driver); + struct device_node *backlight; + struct property *prop; + u32 *brightness_levels; + u32 length, max, last; + + if (vop_dev->backlight) + return 0; + backlight = of_parse_phandle(vop_dev->dev->of_node, "backlight", 0); + if (backlight) { + vop_dev->backlight = of_find_backlight_by_node(backlight); + if (!vop_dev->backlight) + dev_info(vop_dev->dev, "No find backlight device\n"); + } else { + dev_info(vop_dev->dev, "No find backlight device node\n"); + } + prop = of_find_property(backlight, "brightness-levels", &length); + if (!prop) + return -EINVAL; + max = length / sizeof(u32); + last = max - 1; + brightness_levels = kmalloc(256, GFP_KERNEL); + if (brightness_levels) + return -ENOMEM; + + if (!of_property_read_u32_array(backlight, "brightness-levels", + brightness_levels, max)) { + if (brightness_levels[0] > brightness_levels[last]) + dev_drv->cabc_pwm_pol = 1;/*negative*/ + else + dev_drv->cabc_pwm_pol = 0;/*positive*/ + } else { + dev_info(vop_dev->dev, + "Can not read brightness-levels value\n"); + } + + kfree(brightness_levels); + + return 0; +} + +static int vop_early_suspend(struct rk_lcdc_driver *dev_drv) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + + if (dev_drv->suspend_flag) + return 0; + + dev_drv->suspend_flag = 1; + flush_kthread_worker(&dev_drv->update_regs_worker); + + if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable) + dev_drv->trsm_ops->disable(); + + if (likely(vop_dev->clk_on)) { + spin_lock(&vop_dev->reg_lock); + vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLANK_EN(1)); + vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, INTR_MASK); + vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_OUT_ZERO(1)); + vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(1)); + vop_cfg_done(vop_dev); + + if (dev_drv->iommu_enabled && dev_drv->mmu_dev) + rockchip_iovmm_deactivate(dev_drv->dev); + + spin_unlock(&vop_dev->reg_lock); + } + + vop_clk_disable(vop_dev); + rk_disp_pwr_disable(dev_drv); + + return 0; +} + +static int vop_early_resume(struct rk_lcdc_driver *dev_drv) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + + if (!dev_drv->suspend_flag) + return 0; + rk_disp_pwr_enable(dev_drv); + + vop_clk_enable(vop_dev); + memcpy(vop_dev->regs, vop_dev->regsbak, vop_dev->len); + + spin_lock(&vop_dev->reg_lock); + + vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_OUT_ZERO(0)); + vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(0)); + vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLANK_EN(0)); + vop_cfg_done(vop_dev); + spin_unlock(&vop_dev->reg_lock); + + if (dev_drv->iommu_enabled && dev_drv->mmu_dev) { + /* win address maybe effect after next frame start, + * but mmu maybe effect right now, so we delay 50ms + */ + mdelay(50); + rockchip_iovmm_activate(dev_drv->dev); + } + + dev_drv->suspend_flag = 0; + + if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable) + dev_drv->trsm_ops->enable(); + + return 0; +} + +static int vop_blank(struct rk_lcdc_driver *dev_drv, int win_id, int blank_mode) +{ + switch (blank_mode) { + case FB_BLANK_UNBLANK: + vop_early_resume(dev_drv); + break; + case FB_BLANK_NORMAL: + vop_early_suspend(dev_drv); + break; + default: + vop_early_suspend(dev_drv); + break; + } + + dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode); + + return 0; +} + +static int vop_get_win_state(struct rk_lcdc_driver *dev_drv, + int win_id, int area_id) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + u32 area_status = 0, state = 0; + + switch (win_id) { + case 0: + area_status = vop_read_bit(vop_dev, WIN0_CTRL0, V_WIN0_EN(0)); + break; + case 1: + area_status = vop_read_bit(vop_dev, WIN1_CTRL0, V_WIN1_EN(0)); + break; + case 2: + area_status = vop_read_bit(vop_dev, HWC_CTRL0, V_HWC_EN(0)); + break; + default: + pr_err("!!!%s,win[%d]area[%d],unsupport!!!\n", + __func__, win_id, area_id); + break; + } + + state = (area_status > 0) ? 1 : 0; + return state; +} + +static int vop_get_area_num(struct rk_lcdc_driver *dev_drv, + unsigned int *area_support) +{ + area_support[0] = 1; + area_support[1] = 1; + + return 0; +} + +/*overlay will be do at regupdate*/ +static int vop_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap, bool set) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + struct rk_lcdc_win *win = NULL; + int i, ovl; + u64 val; + int z_order_num = 0; + int layer0_sel, layer1_sel, layer2_sel, layer3_sel; + + if (swap == 0) { + for (i = 0; i < dev_drv->lcdc_win_num; i++) { + win = dev_drv->win[i]; + if (win->state == 1) + z_order_num++; + } + for (i = 0; i < dev_drv->lcdc_win_num; 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(&vop_dev->reg_lock); + if (vop_dev->clk_on) { + if (set) { + 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); + vop_msk_reg(vop_dev, DSP_CTRL1, val); + } else { + layer0_sel = vop_read_bit(vop_dev, DSP_CTRL1, + V_DSP_LAYER0_SEL(0)); + layer1_sel = vop_read_bit(vop_dev, DSP_CTRL1, + V_DSP_LAYER1_SEL(0)); + layer2_sel = vop_read_bit(vop_dev, DSP_CTRL1, + V_DSP_LAYER2_SEL(0)); + layer3_sel = vop_read_bit(vop_dev, DSP_CTRL1, + V_DSP_LAYER3_SEL(0)); + ovl = layer3_sel * 1000 + layer2_sel * 100 + + layer1_sel * 10 + layer0_sel; + } + } else { + ovl = -EPERM; + } + spin_unlock(&vop_dev->reg_lock); + + return ovl; +} + +static char *vop_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 vop_get_disp_info(struct rk_lcdc_driver *dev_drv, + char *buf, int win_id) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_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 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; + u8 w0_state, w1_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 dclk_freq; + int size = 0; + + dclk_freq = screen->mode.pixclock; + /*vop_reg_dump(dev_drv); */ + + spin_lock(&vop_dev->reg_lock); + if (vop_dev->clk_on) { + zorder = vop_readl(vop_dev, DSP_CTRL1); + layer0_sel = (zorder & MASK(DSP_LAYER0_SEL)) >> 8; + layer1_sel = (zorder & MASK(DSP_LAYER1_SEL)) >> 10; + /* WIN0 */ + win_ctrl = vop_readl(vop_dev, WIN0_CTRL0); + w0_state = win_ctrl & MASK(WIN0_EN); + fmt_id = (win_ctrl & MASK(WIN0_DATA_FMT)) >> 1; + vop_format_to_string(fmt_id, format_w0); + vir_info = vop_readl(vop_dev, WIN0_VIR); + act_info = vop_readl(vop_dev, WIN0_ACT_INFO); + dsp_info = vop_readl(vop_dev, WIN0_DSP_INFO); + dsp_st = vop_readl(vop_dev, WIN0_DSP_ST); + y_factor = vop_readl(vop_dev, WIN0_SCL_FACTOR_YRGB); + uv_factor = vop_readl(vop_dev, WIN0_SCL_FACTOR_CBR); + w0_vir_y = vir_info & MASK(WIN0_VIR_STRIDE); + w0_vir_uv = (vir_info & MASK(WIN0_VIR_STRIDE_UV)) >> 16; + w0_act_x = (act_info & MASK(WIN0_ACT_WIDTH)) + 1; + w0_act_y = ((act_info & MASK(WIN0_ACT_HEIGHT)) >> 16) + 1; + w0_dsp_x = (dsp_info & MASK(WIN0_DSP_WIDTH)) + 1; + w0_dsp_y = ((dsp_info & MASK(WIN0_DSP_HEIGHT)) >> 16) + 1; + if (w0_state) { + w0_st_x = dsp_st & MASK(WIN0_DSP_XST); + w0_st_y = (dsp_st & MASK(WIN0_DSP_YST)) >> 16; + } + w0_y_h_fac = y_factor & MASK(WIN0_HS_FACTOR_YRGB); + w0_y_v_fac = (y_factor & MASK(WIN0_VS_FACTOR_YRGB)) >> 16; + w0_uv_h_fac = uv_factor & MASK(WIN0_HS_FACTOR_CBR); + w0_uv_v_fac = (uv_factor & MASK(WIN0_VS_FACTOR_CBR)) >> 16; + + /* WIN1 */ + win_ctrl = vop_readl(vop_dev, WIN1_CTRL0); + w1_state = win_ctrl & MASK(WIN1_EN); + fmt_id = (win_ctrl & MASK(WIN1_DATA_FMT)) >> 1; + vop_format_to_string(fmt_id, format_w1); + vir_info = vop_readl(vop_dev, WIN1_VIR); + act_info = vop_readl(vop_dev, WIN1_ACT_INFO); + dsp_info = vop_readl(vop_dev, WIN1_DSP_INFO); + dsp_st = vop_readl(vop_dev, WIN1_DSP_ST); + y_factor = vop_readl(vop_dev, WIN1_SCL_FACTOR_YRGB); + uv_factor = vop_readl(vop_dev, WIN1_SCL_FACTOR_CBR); + w1_vir_y = vir_info & MASK(WIN1_VIR_STRIDE); + w1_vir_uv = (vir_info & MASK(WIN1_VIR_STRIDE_UV)) >> 16; + w1_act_x = (act_info & MASK(WIN1_ACT_WIDTH)) + 1; + w1_act_y = ((act_info & MASK(WIN1_ACT_HEIGHT)) >> 16) + 1; + w1_dsp_x = (dsp_info & MASK(WIN1_DSP_WIDTH)) + 1; + w1_dsp_y = ((dsp_info & MASK(WIN1_DSP_HEIGHT)) >> 16) + 1; + if (w1_state) { + w1_st_x = dsp_st & MASK(WIN1_DSP_XST); + w1_st_y = (dsp_st & MASK(WIN1_DSP_YST)) >> 16; + } + w1_y_h_fac = y_factor & MASK(WIN1_HS_FACTOR_YRGB); + w1_y_v_fac = (y_factor & MASK(WIN1_VS_FACTOR_YRGB)) >> 16; + w1_uv_h_fac = uv_factor & MASK(WIN1_HS_FACTOR_CBR); + w1_uv_v_fac = (uv_factor & MASK(WIN1_VS_FACTOR_CBR)) >> 16; + } else { + spin_unlock(&vop_dev->reg_lock); + return -EPERM; + } + spin_unlock(&vop_dev->reg_lock); + size += snprintf(dsp_buf, 80, + "z-order:\n win[%d]\n win[%d]\n", + 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, vop_readl(vop_dev, WIN0_YRGB_MST), + vop_readl(vop_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, vop_readl(vop_dev, WIN1_YRGB_MST), + vop_readl(vop_dev, WIN1_CBR_MST)); + strcat(buf, dsp_buf); + memset(dsp_buf, 0, sizeof(dsp_buf)); + + return size; +} + +static int vop_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps, bool set) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_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(vop_dev->dclk, dotclk); + } + + pixclock = div_u64(1000000000000llu, clk_get_rate(vop_dev->dclk)); + vop_dev->pixclock = pixclock; + dev_drv->pixclock = vop_dev->pixclock; + fps = rk_fb_calc_fps(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(vop_dev->dclk), fps); + + return fps; +} + +static int vop_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 vop_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 vop_config_done(struct rk_lcdc_driver *dev_drv) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + int i; + u64 val; + struct rk_lcdc_win *win = NULL; + + spin_lock(&vop_dev->reg_lock); + vop_post_cfg(dev_drv); + vop_msk_reg(vop_dev, SYS_CTRL, V_VOP_STANDBY_EN(vop_dev->standby)); + for (i = 0; i < dev_drv->lcdc_win_num; i++) { + win = dev_drv->win[i]; + if ((win->state == 0) && (win->last_state == 1)) { + switch (win->id) { + case 0: + val = V_WIN0_EN(0); + vop_msk_reg(vop_dev, WIN0_CTRL0, val); + break; + case 1: + val = V_WIN1_EN(0); + vop_msk_reg(vop_dev, WIN1_CTRL0, val); + break; + case 2: + val = V_HWC_EN(0); + vop_msk_reg(vop_dev, HWC_CTRL0, val); + break; + default: + break; + } + } + win->last_state = win->state; + } + vop_cfg_done(vop_dev); + spin_unlock(&vop_dev->reg_lock); + return 0; +} + +static int vop_dpi_open(struct rk_lcdc_driver *dev_drv, bool open) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + spin_lock(&vop_dev->reg_lock); + vop_msk_reg(vop_dev, SYS_CTRL, V_DIRECT_PATH_EN(open)); + vop_cfg_done(vop_dev); + spin_unlock(&vop_dev->reg_lock); + return 0; +} + +static int vop_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id) +{ + struct vop_device *vop_dev = container_of(dev_drv, + struct vop_device, driver); + spin_lock(&vop_dev->reg_lock); + vop_msk_reg(vop_dev, SYS_CTRL, V_DIRECT_PATH_LAYER_SEL(win_id)); + vop_cfg_done(vop_dev); + spin_unlock(&vop_dev->reg_lock); + return 0; +} + +static int vop_dpi_status(struct rk_lcdc_driver *dev_drv) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + int ovl; + + spin_lock(&vop_dev->reg_lock); + ovl = vop_read_bit(vop_dev, SYS_CTRL, V_DIRECT_PATH_EN(0)); + spin_unlock(&vop_dev->reg_lock); + return ovl; +} + +static int vop_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv, int enable) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + if (enable) + enable_irq(vop_dev->irq); + else + disable_irq(vop_dev->irq); + return 0; +} + +int vop_poll_vblank(struct rk_lcdc_driver *dev_drv) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + u32 int_reg; + int ret; + + if (vop_dev->clk_on && (!dev_drv->suspend_flag)) { + int_reg = vop_readl(vop_dev, INTR_STATUS0); + if (int_reg & INTR_LINE_FLAG0) { + vop_dev->driver.frame_time.last_framedone_t = + vop_dev->driver.frame_time.framedone_t; + vop_dev->driver.frame_time.framedone_t = cpu_clock(0); + vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_LINE_FLAG0, + INTR_LINE_FLAG0); + ret = RK_LF_STATUS_FC; + } else { + ret = RK_LF_STATUS_FR; + } + } else { + ret = RK_LF_STATUS_NC; + } + + return ret; +} + +static int vop_get_dsp_addr(struct rk_lcdc_driver *dev_drv, + unsigned int dsp_addr[][4]) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + spin_lock(&vop_dev->reg_lock); + if (vop_dev->clk_on) { + dsp_addr[0][0] = vop_readl(vop_dev, WIN0_YRGB_MST); + dsp_addr[1][0] = vop_readl(vop_dev, WIN1_YRGB_MST); + dsp_addr[2][0] = vop_readl(vop_dev, HWC_MST); + } + spin_unlock(&vop_dev->reg_lock); + return 0; +} + +static u32 pwm_period_hpr, pwm_duty_lpr; + +int vop_update_pwm(int bl_pwm_period, int bl_pwm_duty) +{ + pwm_period_hpr = bl_pwm_period; + pwm_duty_lpr = bl_pwm_duty; + /*pr_info("bl_pwm_period_hpr = 0x%x, bl_pwm_duty_lpr = 0x%x\n", + bl_pwm_period, bl_pwm_duty);*/ + 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 vop_get_bcsh_hue(struct rk_lcdc_driver *dev_drv, bcsh_hue_mode mode) +{ +#if 1 + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + u32 val; + + spin_lock(&vop_dev->reg_lock); + if (vop_dev->clk_on) { + val = vop_readl(vop_dev, BCSH_H); + switch (mode) { + case H_SIN: + val &= MASK(SIN_HUE); + break; + case H_COS: + val &= MASK(COS_HUE); + val >>= 16; + break; + default: + break; + } + } + spin_unlock(&vop_dev->reg_lock); + + return val; +#endif + return 0; +} + +static int vop_set_bcsh_hue(struct rk_lcdc_driver *dev_drv, + int sin_hue, int cos_hue) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + u64 val; + + spin_lock(&vop_dev->reg_lock); + if (vop_dev->clk_on) { + val = V_SIN_HUE(sin_hue) | V_COS_HUE(cos_hue); + vop_msk_reg(vop_dev, BCSH_H, val); + vop_cfg_done(vop_dev); + } + spin_unlock(&vop_dev->reg_lock); + + return 0; +} + +static int vop_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv, + bcsh_bcs_mode mode, int value) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + u64 val; + + spin_lock(&vop_dev->reg_lock); + if (vop_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; + val = V_BRIGHTNESS(value); + break; + case CONTRAST: + /*from 0 to 510,typical is 256 */ + val = V_CONTRAST(value); + break; + case SAT_CON: + /*from 0 to 1015,typical is 256 */ + val = V_SAT_CON(value); + break; + default: + break; + } + vop_msk_reg(vop_dev, BCSH_BCS, val); + vop_cfg_done(vop_dev); + } + spin_unlock(&vop_dev->reg_lock); + + return val; +} + +static int vop_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv, bcsh_bcs_mode mode) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + u64 val; + + spin_lock(&vop_dev->reg_lock); + if (vop_dev->clk_on) { + val = vop_readl(vop_dev, BCSH_BCS); + switch (mode) { + case BRIGHTNESS: + val &= MASK(BRIGHTNESS); + if (val > 0x80) + val -= 0x80; + else + val += 0x80; + break; + case CONTRAST: + val &= MASK(CONTRAST); + val >>= 8; + break; + case SAT_CON: + val &= MASK(SAT_CON); + val >>= 20; + break; + default: + break; + } + } + spin_unlock(&vop_dev->reg_lock); + return val; +} + +static int vop_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + + spin_lock(&vop_dev->reg_lock); + if (vop_dev->clk_on) { + if (open) { + vop_writel(vop_dev, BCSH_COLOR_BAR, 0x1); + vop_writel(vop_dev, BCSH_BCS, 0xd0010000); + vop_writel(vop_dev, BCSH_H, 0x01000000); + dev_drv->bcsh.enable = 1; + } else { + vop_msk_reg(vop_dev, BCSH_COLOR_BAR, V_BCSH_EN(0)); + dev_drv->bcsh.enable = 0; + } + vop_bcsh_path_sel(dev_drv); + vop_cfg_done(vop_dev); + } + spin_unlock(&vop_dev->reg_lock); + + return 0; +} + +static int vop_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable) +{ + if (!enable || !dev_drv->bcsh.enable) { + vop_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)) { + vop_open_bcsh(dev_drv, true); + if (dev_drv->bcsh.brightness <= 255) + vop_set_bcsh_bcs(dev_drv, BRIGHTNESS, + dev_drv->bcsh.brightness); + if (dev_drv->bcsh.contrast <= 510) + vop_set_bcsh_bcs(dev_drv, CONTRAST, + dev_drv->bcsh.contrast); + if (dev_drv->bcsh.sat_con <= 1015) + vop_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) + vop_set_bcsh_hue(dev_drv, dev_drv->bcsh.sin_hue, + dev_drv->bcsh.cos_hue); + } + + return 0; +} + +static int __maybe_unused +vop_dsp_black(struct rk_lcdc_driver *dev_drv, int enable) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + + if (enable) { + spin_lock(&vop_dev->reg_lock); + if (likely(vop_dev->clk_on)) { + vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLACK_EN(1)); + vop_cfg_done(vop_dev); + } + spin_unlock(&vop_dev->reg_lock); + } else { + spin_lock(&vop_dev->reg_lock); + if (likely(vop_dev->clk_on)) { + vop_msk_reg(vop_dev, DSP_CTRL0, V_DSP_BLACK_EN(0)); + + vop_cfg_done(vop_dev); + } + spin_unlock(&vop_dev->reg_lock); + } + + return 0; +} + +static int vop_backlight_close(struct rk_lcdc_driver *dev_drv, int enable) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + + if (unlikely(!vop_dev->clk_on)) { + pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on); + return 0; + } + vop_get_backlight_device(dev_drv); + + if (enable) { + /* close the backlight */ + if (vop_dev->backlight) { + vop_dev->backlight->props.power = FB_BLANK_POWERDOWN; + backlight_update_status(vop_dev->backlight); + } + if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable) + dev_drv->trsm_ops->disable(); + } else { + if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable) + dev_drv->trsm_ops->enable(); + msleep(100); + /* open the backlight */ + if (vop_dev->backlight) { + vop_dev->backlight->props.power = FB_BLANK_UNBLANK; + backlight_update_status(vop_dev->backlight); + } + } + + return 0; +} + +static int vop_set_overscan(struct rk_lcdc_driver *dev_drv, + struct overscan *overscan) +{ + struct vop_device *vop_dev = + container_of(dev_drv, struct vop_device, driver); + + if (unlikely(!vop_dev->clk_on)) { + pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on); + return 0; + } + /*vop_post_cfg(dev_drv);*/ + + return 0; +} + +static struct rk_lcdc_drv_ops lcdc_drv_ops = { + .open = vop_open, + .win_direct_en = vop_win_direct_en, + .load_screen = vop_load_screen, + .get_dspbuf_info = vop_get_dspbuf_info, + .post_dspbuf = vop_post_dspbuf, + .set_par = vop_set_par, + .pan_display = vop_pan_display, + .direct_set_addr = vop_direct_set_win_addr, + /*.lcdc_reg_update = vop_reg_update,*/ + .blank = vop_blank, + .ioctl = vop_ioctl, + .suspend = vop_early_suspend, + .resume = vop_early_resume, + .get_win_state = vop_get_win_state, + .area_support_num = vop_get_area_num, + .ovl_mgr = vop_ovl_mgr, + .get_disp_info = vop_get_disp_info, + .fps_mgr = vop_fps_mgr, + .fb_get_win_id = vop_get_win_id, + .fb_win_remap = vop_fb_win_remap, + .poll_vblank = vop_poll_vblank, + .dpi_open = vop_dpi_open, + .dpi_win_sel = vop_dpi_win_sel, + .dpi_status = vop_dpi_status, + .get_dsp_addr = vop_get_dsp_addr, + .set_dsp_bcsh_hue = vop_set_bcsh_hue, + .set_dsp_bcsh_bcs = vop_set_bcsh_bcs, + .get_dsp_bcsh_hue = vop_get_bcsh_hue, + .get_dsp_bcsh_bcs = vop_get_bcsh_bcs, + .open_bcsh = vop_open_bcsh, + .dump_reg = vop_reg_dump, + .cfg_done = vop_config_done, + .set_irq_to_cpu = vop_set_irq_to_cpu, + /*.dsp_black = vop_dsp_black,*/ + .backlight_close = vop_backlight_close, + .mmu_en = vop_mmu_en, + .set_overscan = vop_set_overscan, +}; + +static irqreturn_t vop_isr(int irq, void *dev_id) +{ + struct vop_device *vop_dev = (struct vop_device *)dev_id; + ktime_t timestamp = ktime_get(); + u32 intr_status; + unsigned long flags; + + spin_lock_irqsave(&vop_dev->irq_lock, flags); + + intr_status = vop_readl(vop_dev, INTR_STATUS0); + vop_mask_writel(vop_dev, INTR_CLEAR0, INTR_MASK, intr_status); + + spin_unlock_irqrestore(&vop_dev->irq_lock, flags); + /* This is expected for vop iommu irqs, since the irq is shared */ + if (!intr_status) + return IRQ_NONE; + + if (intr_status & INTR_FS) { + timestamp = ktime_get(); + vop_dev->driver.vsync_info.timestamp = timestamp; + wake_up_interruptible_all(&vop_dev->driver.vsync_info.wait); + intr_status &= ~INTR_FS; + } + + if (intr_status & INTR_LINE_FLAG0) + intr_status &= ~INTR_LINE_FLAG0; + + if (intr_status & INTR_LINE_FLAG1) + intr_status &= ~INTR_LINE_FLAG1; + + if (intr_status & INTR_FS_NEW) + intr_status &= ~INTR_FS_NEW; + + if (intr_status & INTR_BUS_ERROR) { + intr_status &= ~INTR_BUS_ERROR; + dev_warn(vop_dev->dev, "bus error!"); + } + if (intr_status) + dev_err(vop_dev->dev, "Unknown VOP IRQs: %#02x\n", intr_status); + + return IRQ_HANDLED; +} + +#if defined(CONFIG_PM) +static int vop_suspend(struct platform_device *pdev, pm_message_t state) +{ + return 0; +} + +static int vop_resume(struct platform_device *pdev) +{ + return 0; +} +#else +#define vop_suspend NULL +#define vop_resume NULL +#endif + +static int vop_parse_dt(struct vop_device *vop_dev) +{ + struct device_node *np = vop_dev->dev->of_node; + struct rk_lcdc_driver *dev_drv = &vop_dev->driver; + int val; + + if (of_property_read_u32(np, "rockchip,prop", &val)) + vop_dev->prop = PRMRY; /*default set it as primary */ + else + vop_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,pwr18", &val)) + /*default set it as 3.xv power supply */ + vop_dev->pwr18 = false; + else + vop_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 vop_probe(struct platform_device *pdev) +{ + struct vop_device *vop_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; + } + vop_dev = devm_kzalloc(dev, sizeof(struct vop_device), GFP_KERNEL); + if (!vop_dev) { + dev_err(&pdev->dev, "rk3228 lcdc device kmalloc fail!"); + return -ENOMEM; + } + platform_set_drvdata(pdev, vop_dev); + vop_dev->dev = dev; + vop_parse_dt(vop_dev); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + vop_dev->reg_phy_base = res->start; + vop_dev->len = resource_size(res); + vop_dev->regs = devm_ioremap_resource(dev, res); + if (IS_ERR(vop_dev->regs)) + return PTR_ERR(vop_dev->regs); + else + dev_info(dev, "vop_dev->regs=0x%lx\n", (long)vop_dev->regs); + + vop_dev->regsbak = devm_kzalloc(dev, vop_dev->len, GFP_KERNEL); + if (IS_ERR(vop_dev->regsbak)) + return PTR_ERR(vop_dev->regsbak); + + vop_dev->id = 0; + dev_set_name(vop_dev->dev, "vop%d", vop_dev->id); + dev_drv = &vop_dev->driver; + dev_drv->dev = dev; + dev_drv->prop = prop; + dev_drv->id = vop_dev->id; + dev_drv->ops = &lcdc_drv_ops; + dev_drv->lcdc_win_num = ARRAY_SIZE(vop_win); + dev_drv->reserved_fb = 1;/*only need reserved 1 buffer*/ + spin_lock_init(&vop_dev->reg_lock); + spin_lock_init(&vop_dev->irq_lock); + + vop_dev->irq = platform_get_irq(pdev, 0); + if (vop_dev->irq < 0) { + dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n", + vop_dev->id); + return -ENXIO; + } + + ret = devm_request_irq(dev, vop_dev->irq, vop_isr, + IRQF_DISABLED | IRQF_SHARED, + dev_name(dev), vop_dev); + if (ret) { + dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n", + vop_dev->irq, ret); + return ret; + } + + if (dev_drv->iommu_enabled) + strcpy(dev_drv->mmu_dts_name, VOP_IOMMU_COMPATIBLE_NAME); + + ret = rk_fb_register(dev_drv, vop_win, vop_dev->id); + if (ret < 0) { + dev_err(dev, "register fb for lcdc%d failed!\n", vop_dev->id); + return ret; + } + vop_dev->screen = dev_drv->screen0; + dev_info(dev, "lcdc%d probe ok, iommu %s\n", + vop_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled"); + + return 0; +} + +static int vop_remove(struct platform_device *pdev) +{ + return 0; +} + +static void vop_shutdown(struct platform_device *pdev) +{ + struct vop_device *vop_dev = platform_get_drvdata(pdev); + struct rk_lcdc_driver *dev_drv = &vop_dev->driver; + + dev_drv->suspend_flag = 1; + mdelay(100); + flush_kthread_worker(&dev_drv->update_regs_worker); + kthread_stop(dev_drv->update_regs_thread); + vop_deint(vop_dev); + /*if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable) + dev_drv->trsm_ops->disable();*/ + + vop_clk_disable(vop_dev); + rk_disp_pwr_disable(dev_drv); +} + +#if defined(CONFIG_OF) +static const struct of_device_id vop_dt_ids[] = { + {.compatible = "rockchip,rk322x-lcdc",}, + {} +}; +#endif + +static struct platform_driver vop_driver = { + .probe = vop_probe, + .remove = vop_remove, + .driver = { + .name = "rk322x-lcdc", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(vop_dt_ids), + }, + .suspend = vop_suspend, + .resume = vop_resume, + .shutdown = vop_shutdown, +}; + +static int __init vop_module_init(void) +{ + return platform_driver_register(&vop_driver); +} + +static void __exit vop_module_exit(void) +{ + platform_driver_unregister(&vop_driver); +} + +fs_initcall(vop_module_init); +module_exit(vop_module_exit); diff --git a/drivers/video/rockchip/lcdc/rk322x_lcdc.h b/drivers/video/rockchip/lcdc/rk322x_lcdc.h new file mode 100644 index 000000000000..3be4be76ff09 --- /dev/null +++ b/drivers/video/rockchip/lcdc/rk322x_lcdc.h @@ -0,0 +1,1676 @@ +#ifndef RK322X_LCDC_H_ +#define RK322X_LCDC_H_ + +#include +#include +#include +#include +#include + +#define VOP_INPUT_MAX_WIDTH 4096 +/* + * Registers in this file + * REG_CFG_DONE: Register config done flag + * VERSION_INFO: Version for vop + * SYS_CTRL: System control register0 + * SYS_CTRL1: System control register1 + * DSP_CTRL0: Display control register0 + * DSP_CTRL1: Display control register1 + * DSP_BG: Background color + * MCU_CTRL: MCU mode control register + * WB_CTRL0: write back ctrl0 + * WB_CTRL1: write back ctrl1 + * WB_YRGB_MST: write back yrgb mst + * WB_CBR_MST: write back cbr mst + * WIN0_CTRL0: Win0 ctrl register0 + * WIN0_CTRL1: Win0 ctrl register1 + * WIN0_COLOR_KEY: Win0 color key register + * WIN0_VIR: Win0 virtual stride + * WIN0_YRGB_MST: Win0 YRGB memory start address + * WIN0_CBR_MST: Win0 Cbr memory start address + * WIN0_ACT_INFO: Win0 active window width/height + * WIN0_DSP_INFO: Win0 display width/height on panel + * WIN0_DSP_ST: Win0 display start point on panel + * WIN0_SCL_FACTOR_YRGB: Win0 YRGB scaling factor + * WIN0_SCL_FACTOR_CBR: Win0 Cbr scaling factor + * WIN0_SCL_OFFSET: Win0 scaling start point offset + * WIN0_SRC_ALPHA_CTRL: Win0 alpha source control register + * WIN0_DST_ALPHA_CTRL: Win0 alpha destination control register + * WIN0_FADING_CTRL: Win0 fading contrl register + * WIN0_CTRL2: Win0 ctrl register2 + * WIN1_CTRL0: Win1 ctrl register0 + * WIN1_CTRL1: Win1 ctrl register1 + * WIN1_COLOR_KEY: Win1 color key register + * WIN1_VIR: win1 virtual stride + * WIN1_YRGB_MST: Win1 YRGB memory start address + * WIN1_CBR_MST: Win1 Cbr memory start address + * WIN1_ACT_INFO: Win1 active window width/height + * WIN1_DSP_INFO: Win1 display width/height on panel + * WIN1_DSP_ST: Win1 display start point on panel + * WIN1_SCL_FACTOR_YRGB: Win1 YRGB scaling factor + * WIN1_SCL_FACTOR_CBR: Win1 Cbr scaling factor + * WIN1_SCL_OFFSET: Win1 scaling start point offset + * WIN1_SRC_ALPHA_CTRL: Win1 alpha source control register + * WIN1_DST_ALPHA_CTRL: Win1 alpha destination control register + * WIN1_FADING_CTRL: Win1 fading contrl register + * WIN1_CTRL2: Win1 ctrl register2 + * WIN2_CTRL0: win2 ctrl register0 + * WIN2_CTRL1: win2 ctrl register1 + * WIN2_VIR0_1: Win2 virtual stride0 and virtaul stride1 + * WIN2_VIR2_3: Win2 virtual stride2 and virtaul stride3 + * WIN2_MST0: Win2 memory start address0 + * WIN2_DSP_INFO0: Win2 display width0/height0 on panel + * WIN2_DSP_ST0: Win2 display start point0 on panel + * WIN2_COLOR_KEY: Win2 color key register + * WIN2_MST1: Win2 memory start address1 + * WIN2_DSP_INFO1: Win2 display width1/height1 on panel + * WIN2_DSP_ST1: Win2 display start point1 on panel + * WIN2_SRC_ALPHA_CTRL: Win2 alpha source control register + * WIN2_MST2: Win2 memory start address2 + * WIN2_DSP_INFO2: Win2 display width2/height2 on panel + * WIN2_DSP_ST2: Win2 display start point2 on panel + * WIN2_DST_ALPHA_CTRL: Win2 alpha destination control register + * WIN2_MST3: Win2 memory start address3 + * WIN2_DSP_INFO3: Win2 display width3/height3 on panel + * WIN2_DSP_ST3: Win2 display start point3 on panel + * WIN2_FADING_CTRL: Win2 fading contrl register + * WIN3_CTRL0: Win3 ctrl register0 + * WIN3_CTRL1: Win3 ctrl register1 + * WIN3_VIR0_1: Win3 virtual stride0 and virtaul stride1 + * WIN3_VIR2_3: Win3 virtual stride2 and virtaul stride3 + * WIN3_MST0: Win3 memory start address0 + * WIN3_DSP_INFO0: Win3 display width0/height0 on panel + * WIN3_DSP_ST0: Win3 display start point0 on panel + * WIN3_COLOR_KEY: Win3 color key register + * WIN3_MST1: Win3 memory start address1 + * WIN3_DSP_INFO1: Win3 display width1/height1 on panel + * WIN3_DSP_ST1: Win3 display start point1 on panel + * WIN3_SRC_ALPHA_CTRL: Win3 alpha source control register + * WIN3_MST2: Win3 memory start address2 + * WIN3_DSP_INFO2: Win3 display width2/height2 on panel + * WIN3_DSP_ST2: Win3 display start point2 on panel + * WIN3_DST_ALPHA_CTRL: Win3 alpha destination control register + * WIN3_MST3: Win3 memory start address3 + * WIN3_DSP_INFO3: Win3 display width3/height3 on panel + * WIN3_DSP_ST3: Win3 display start point3 on panel + * WIN3_FADING_CTRL: Win3 fading contrl register + * HWC_CTRL0: Hwc ctrl register0 + * HWC_CTRL1: Hwc ctrl register1 + * HWC_MST: Hwc memory start address + * HWC_DSP_ST: Hwc display start point on panel + * HWC_SRC_ALPHA_CTRL: Hwc alpha source control register + * HWC_DST_ALPHA_CTRL: Hwc alpha destination control register + * HWC_FADING_CTRL: Hwc fading contrl register + * HWC_RESERVED1: Hwc reserved + * POST_DSP_HACT_INFO: Post scaler down horizontal start and end + * POST_DSP_VACT_INFO: Panel active horizontal scanning start point + * and end point + * POST_SCL_FACTOR_YRGB: Post yrgb scaling factor + * POST_RESERVED: Post reserved + * POST_SCL_CTRL: Post scaling start point offset + * POST_DSP_VACT_INFO_F1: Panel active horizontal scanning start point + * and end point F1 + * DSP_HTOTAL_HS_END: Panel scanning horizontal width and hsync pulse end point + * DSP_HACT_ST_END: Panel active horizontal scanning start point and end point + * DSP_VTOTAL_VS_END: Panel scanning vertical height and vsync pulse end point + * DSP_VACT_ST_END: Panel active vertical scanning start point and end point + * DSP_VS_ST_END_F1: Vertical scanning start point and vsync pulse end point + * of even filed in interlace mode + * DSP_VACT_ST_END_F1: Vertical scanning active start point and end point of + * even filed in interlace mode + * PWM_CTRL: PWM Control Register + * PWM_PERIOD_HPR: PWM Period Register/High Polarity Capture Register + * PWM_DUTY_LPR: PWM Duty Register/Low Polarity Capture Register + * PWM_CNT: PWM Counter Register + * BCSH_COLOR_BAR: Color bar config register + * BCSH_BCS: Brightness contrast saturation*contrast config register + * BCSH_H: Sin hue and cos hue config register + * BCSH_CTRL: BCSH contrl register + * CABC_CTRL0: Content Adaptive Backlight Control register0 + * CABC_CTRL1: Content Adaptive Backlight Control register1 + * CABC_CTRL2: Content Adaptive Backlight Control register2 + * CABC_CTRL3: Content Adaptive Backlight Control register3 + * CABC_GAUSS_LINE0_0: CABC gauss line config register00 + * CABC_GAUSS_LINE0_1: CABC gauss line config register01 + * CABC_GAUSS_LINE1_0: CABC gauss line config register10 + * CABC_GAUSS_LINE1_1: CABC gauss line config register11 + * CABC_GAUSS_LINE2_0: CABC gauss line config register20 + * CABC_GAUSS_LINE2_1: CABC gauss line config register21 + * FRC_LOWER01_0: FRC lookup table config register010 + * FRC_LOWER01_1: FRC lookup table config register011 + * FRC_LOWER10_0: FRC lookup table config register100 + * FRC_LOWER10_1: FRC lookup table config register101 + * FRC_LOWER11_0: FRC lookup table config register110 + * FRC_LOWER11_1: FRC lookup table config register111 + * AFBCD0_CTRL: + * AFBCD0_HDR_PTR: + * AFBCD0_PIC_SIZE: + * AFBCD0_STATUS: + * AFBCD1_CTRL: + * AFBCD1_HDR_PTR: + * AFBCD1_PIC_SIZE: + * AFBCD1_STATUS: + * AFBCD2_CTRL: + * AFBCD2_HDR_PTR: + * AFBCD2_PIC_SIZE: + * AFBCD2_STATUS: + * AFBCD3_CTRL: + * AFBCD3_HDR_PTR: + * AFBCD3_PIC_SIZE: + * AFBCD3_STATUS: + * INTR_EN0: Interrupt enable register + * INTR_CLEAR0: Interrupt clear register + * INTR_STATUS0: interrupt status + * INTR_RAW_STATUS0: raw interrupt status + * INTR_EN1: Interrupt enable register + * INTR_CLEAR1: Interrupt clear register + * INTR_STATUS1: interrupt status + * INTR_RAW_STATUS1: raw interrupt status + * LINE_FLAG: Line flag config register + * VOP_STATUS: vop status register + * BLANKING_VALUE: Register0000 Abstract + * WIN0_DSP_BG: Win0 layer background color + * WIN1_DSP_BG: Win1 layer background color + * WIN2_DSP_BG: Win2 layer background color + * WIN3_DSP_BG: Win3 layer background color + * DBG_PERF_LATENCY_CTRL0: Axi performance latency module contrl register0 + * DBG_PERF_RD_MAX_LATENCY_NUM0: Read max latency number + * DBG_PERF_RD_LATENCY_THR_NUM0: The number of bigger than configed + * threshold value + * DBG_PERF_RD_LATENCY_SAMP_NUM0: Total sample number + * DBG_CABC0: CABC debug register0 + * DBG_CABC1: CABC debug register1 + * DBG_CABC2: CABC debug register2 + * DBG_CABC3: CABC debug register3 + * DBG_WIN0_REG0: Vop debug win0 register0 + * DBG_WIN0_REG1: Vop debug win0 register1 + * DBG_WIN0_REG2: Vop debug win0 register2 + * DBG_WIN0_RESERVED: Vop debug win0 register3 reserved + * DBG_WIN1_REG0: Vop debug win1 register0 + * DBG_WIN1_REG1: Vop debug win1 register1 + * DBG_WIN1_REG2: Vop debug win1 register2 + * DBG_WIN1_RESERVED: Vop debug win1 register3 reserved + * DBG_WIN2_REG0: Vop debug win2 register0 + * DBG_WIN2_REG1: Vop debug win2 register1 + * DBG_WIN2_REG2: Vop debug win2 register2 + * DBG_WIN2_REG3: Vop debug win2 register3 + * DBG_WIN3_REG0: Vop debug win3 register0 + * DBG_WIN3_REG1: Vop debug win3 register1 + * DBG_WIN3_REG2: Vop debug win3 register2 + * DBG_WIN3_REG3: Vop debug win3 register3 + * DBG_PRE_REG0: Vop debug pre register0 + * DBG_PRE_RESERVED: Vop debug pre register1 reserved + * DBG_POST_REG0: Vop debug post register0 + * DBG_POST_RESERVED: Vop debug post register1 reserved + * DBG_DATAO: debug data output path + * DBG_DATAO_2: debug data output path 2 + * WIN2_LUT_ADDR: Win2 lut base address + * WIN3_LUT_ADDR: Win3 lut base address + * HWC_LUT_ADDR: Hwc lut base address + * GAMMA0_LUT_ADDR: GAMMA lut base address + * GAMMA1_LUT_ADDR: GAMMA lut base address + * CABC_GAMMA_LUT_ADDR: CABC GAMMA lut base address + * MCU_BYPASS_WPORT: + * MCU_BYPASS_RPORT: + */ + +static inline u64 val_mask(int val, u64 msk, int shift) +{ + return (msk << (shift + 32)) | ((msk & val) << shift); +} + +#define VAL_MASK(x, width, shift) val_mask(x, (1 << width) - 1, shift) + +#define MASK(x) (V_##x(0) >> 32) + +#define REG_CFG_DONE 0x00000000 +#define V_REG_LOAD_EN(x) VAL_MASK(x, 1, 0) +#define V_REG_LOAD_WIN0_EN(x) VAL_MASK(x, 1, 1) +#define V_REG_LOAD_WIN1_EN(x) VAL_MASK(x, 1, 2) +#define V_REG_LOAD_WIN2_EN(x) VAL_MASK(x, 1, 3) +#define V_REG_LOAD_WIN3_EN(x) VAL_MASK(x, 1, 4) +#define V_REG_LOAD_HWC_EN(x) VAL_MASK(x, 1, 5) +#define V_REG_LOAD_IEP_EN(x) VAL_MASK(x, 1, 6) +#define V_REG_LOAD_FBDC_EN(x) VAL_MASK(x, 1, 7) +#define V_REG_LOAD_SYS_EN(x) VAL_MASK(x, 1, 8) +#define V_WRITE_MASK(x) VAL_MASK(x, 16, 16) +#define VERSION_INFO 0x00000004 +#define V_SVNBUILD(x) VAL_MASK(x, 16, 0) +#define V_MINOR(x) VAL_MASK(x, 8, 16) +#define V_MAJOR(x) VAL_MASK(x, 8, 24) +#define SYS_CTRL 0x00000008 +#define V_DIRECT_PATH_EN(x) VAL_MASK(x, 1, 0) +#define V_DIRECT_PATH_LAYER_SEL(x) VAL_MASK(x, 2, 1) +#define V_EDPI_HALT_EN(x) VAL_MASK(x, 1, 8) +#define V_EDPI_WMS_MODE(x) VAL_MASK(x, 1, 9) +#define V_EDPI_WMS_FS(x) VAL_MASK(x, 1, 10) +#define V_GLOBAL_REGDONE_EN(x) VAL_MASK(x, 1, 11) +#define V_RGB_OUT_EN(x) VAL_MASK(x, 1, 12) +#define V_HDMI_OUT_EN(x) VAL_MASK(x, 1, 13) +#define V_EDP_OUT_EN(x) VAL_MASK(x, 1, 14) +#define V_MIPI_OUT_EN(x) VAL_MASK(x, 1, 15) +#define V_OVERLAY_MODE(x) VAL_MASK(x, 1, 16) +#define V_FS_SAME_ADDR_MASK_EN(x) VAL_MASK(x, 1, 17) +#define V_POST_LB_MODE(x) VAL_MASK(x, 1, 18) +#define V_WIN23_PRI_OPT_MODE(x) VAL_MASK(x, 1, 19) +#define V_VOP_MMU_EN(x) VAL_MASK(x, 1, 20) +#define V_VOP_DMA_STOP(x) VAL_MASK(x, 1, 21) +#define V_VOP_STANDBY_EN(x) VAL_MASK(x, 1, 22) +#define V_AUTO_GATING_EN(x) VAL_MASK(x, 1, 23) +#define V_SW_IMD_TVE_DCLK_EN(x) VAL_MASK(x, 1, 24) +#define V_SW_IMD_TVE_DCLK_POL(x) VAL_MASK(x, 1, 25) +#define V_SW_TVE_MODE(x) VAL_MASK(x, 1, 26) +#define V_SW_UV_OFFSET_EN(x) VAL_MASK(x, 1, 27) +#define V_SW_GENLOCK(x) VAL_MASK(x, 1, 28) +#define V_SW_DAC_SEL(x) VAL_MASK(x, 1, 29) +#define V_VOP_FIELD_TVE_POL(x) VAL_MASK(x, 1, 30) +#define V_IO_PAD_CLK_SEL(x) VAL_MASK(x, 1, 31) +#define SYS_CTRL1 0x0000000c +#define V_NOC_HURRY_EN(x) VAL_MASK(x, 1, 0) +#define V_NOC_HURRY_VALUE(x) VAL_MASK(x, 2, 1) +#define V_NOC_HURRY_THRESHOLD(x) VAL_MASK(x, 6, 3) +#define V_NOC_QOS_EN(x) VAL_MASK(x, 1, 9) +#define V_NOC_WIN_QOS(x) VAL_MASK(x, 2, 10) +#define V_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 12) +#define V_AXI_OUTSTANDING_MAX_NUM(x) VAL_MASK(x, 5, 13) +#define V_NOC_HURRY_W_MODE(x) VAL_MASK(x, 2, 20) +#define V_NOC_HURRY_W_VALUE(x) VAL_MASK(x, 2, 22) +#define V_DSP_FP_STANDBY(x) VAL_MASK(x, 1, 31) +#define DSP_CTRL0 0x00000010 +#define V_DSP_OUT_MODE(x) VAL_MASK(x, 4, 0) +#define V_SW_CORE_DCLK_SEL(x) VAL_MASK(x, 1, 4) +#define V_SW_HDMI_CLK_I_SEL(x) VAL_MASK(x, 1, 5) +#define V_DSP_DCLK_DDR(x) VAL_MASK(x, 1, 8) +#define V_DSP_DDR_PHASE(x) VAL_MASK(x, 1, 9) +#define V_DSP_INTERLACE(x) VAL_MASK(x, 1, 10) +#define V_DSP_FIELD_POL(x) VAL_MASK(x, 1, 11) +#define V_DSP_BG_SWAP(x) VAL_MASK(x, 1, 12) +#define V_DSP_RB_SWAP(x) VAL_MASK(x, 1, 13) +#define V_DSP_RG_SWAP(x) VAL_MASK(x, 1, 14) +#define V_DSP_DELTA_SWAP(x) VAL_MASK(x, 1, 15) +#define V_DSP_DUMMY_SWAP(x) VAL_MASK(x, 1, 16) +#define V_DSP_OUT_ZERO(x) VAL_MASK(x, 1, 17) +#define V_DSP_BLANK_EN(x) VAL_MASK(x, 1, 18) +#define V_DSP_BLACK_EN(x) VAL_MASK(x, 1, 19) +#define V_DSP_CCIR656_AVG(x) VAL_MASK(x, 1, 20) +#define V_DSP_YUV_CLIP(x) VAL_MASK(x, 1, 21) +#define V_DSP_X_MIR_EN(x) VAL_MASK(x, 1, 22) +#define V_DSP_Y_MIR_EN(x) VAL_MASK(x, 1, 23) +#define V_DSP_FIELD(x) VAL_MASK(x, 1, 31) +#define DSP_CTRL1 0x00000014 +#define V_DSP_LUT_EN(x) VAL_MASK(x, 1, 0) +#define V_PRE_DITHER_DOWN_EN(x) VAL_MASK(x, 1, 1) +#define V_DITHER_DOWN_EN(x) VAL_MASK(x, 1, 2) +#define V_DITHER_DOWN_MODE(x) VAL_MASK(x, 1, 3) +#define V_DITHER_DOWN_SEL(x) VAL_MASK(x, 1, 4) +#define V_DITHER_UP_EN(x) VAL_MASK(x, 1, 6) +#define V_UPDATE_GAMMA_LUT(x) VAL_MASK(x, 1, 7) +#define V_DSP_LAYER0_SEL(x) VAL_MASK(x, 2, 8) +#define V_DSP_LAYER1_SEL(x) VAL_MASK(x, 2, 10) +#define V_DSP_LAYER2_SEL(x) VAL_MASK(x, 2, 12) +#define V_DSP_LAYER3_SEL(x) VAL_MASK(x, 2, 14) +#define V_RGB_LVDS_HSYNC_POL(x) VAL_MASK(x, 1, 16) +#define V_RGB_LVDS_VSYNC_POL(x) VAL_MASK(x, 1, 17) +#define V_RGB_LVDS_DEN_POL(x) VAL_MASK(x, 1, 18) +#define V_RGB_LVDS_DCLK_POL(x) VAL_MASK(x, 1, 19) +#define V_HDMI_HSYNC_POL(x) VAL_MASK(x, 1, 20) +#define V_HDMI_VSYNC_POL(x) VAL_MASK(x, 1, 21) +#define V_HDMI_DEN_POL(x) VAL_MASK(x, 1, 22) +#define V_HDMI_DCLK_POL(x) VAL_MASK(x, 1, 23) +#define V_EDP_HSYNC_POL(x) VAL_MASK(x, 1, 24) +#define V_EDP_VSYNC_POL(x) VAL_MASK(x, 1, 25) +#define V_EDP_DEN_POL(x) VAL_MASK(x, 1, 26) +#define V_EDP_DCLK_POL(x) VAL_MASK(x, 1, 27) +#define V_MIPI_HSYNC_POL(x) VAL_MASK(x, 1, 28) +#define V_MIPI_VSYNC_POL(x) VAL_MASK(x, 1, 29) +#define V_MIPI_DEN_POL(x) VAL_MASK(x, 1, 30) +#define V_MIPI_DCLK_POL(x) VAL_MASK(x, 1, 31) +#define DSP_BG 0x00000018 +#define V_DSP_BG_BLUE(x) VAL_MASK(x, 8, 0) +#define V_DSP_BG_GREEN(x) VAL_MASK(x, 8, 8) +#define V_DSP_BG_RED(x) VAL_MASK(x, 8, 16) +#define MCU_CTRL 0x0000001c +#define V_MCU_PIX_TOTAL(x) VAL_MASK(x, 6, 0) +#define V_MCU_CS_PST(x) VAL_MASK(x, 4, 6) +#define V_MCU_CS_PEND(x) VAL_MASK(x, 6, 10) +#define V_MCU_RW_PST(x) VAL_MASK(x, 4, 16) +#define V_MCU_RW_PEND(x) VAL_MASK(x, 6, 20) +#define V_MCU_CLK_SEL(x) VAL_MASK(x, 1, 26) +#define V_MCU_HOLD_MODE(x) VAL_MASK(x, 1, 27) +#define V_MCU_FRAME_ST(x) VAL_MASK(x, 1, 28) +#define V_MCU_RS(x) VAL_MASK(x, 1, 29) +#define V_MCU_BYPASS(x) VAL_MASK(x, 1, 30) +#define V_MCU_TYPE(x) VAL_MASK(x, 1, 31) +#define WB_CTRL0 0x00000020 +#define V_WB_EN(x) VAL_MASK(x, 1, 0) +#define V_WB_FMT(x) VAL_MASK(x, 3, 1) +#define V_WB_DITHER_EN(x) VAL_MASK(x, 1, 4) +#define V_WB_RGB2YUV_EN(x) VAL_MASK(x, 1, 5) +#define V_WB_RGB2YUV_MODE(x) VAL_MASK(x, 1, 6) +#define V_WB_XPSD_BIL_EN(x) VAL_MASK(x, 1, 7) +#define V_WB_YTHROW_EN(x) VAL_MASK(x, 1, 8) +#define V_WB_YTHROW_MODE(x) VAL_MASK(x, 1, 9) +#define V_WB_HANDSHAKE_MODE(x) VAL_MASK(x, 1, 11) +#define V_WB_YRGB_ID(x) VAL_MASK(x, 4, 24) +#define V_WB_UV_ID(x) VAL_MASK(x, 4, 28) +#define WB_CTRL1 0x00000024 +#define V_WB_WIDTH(x) VAL_MASK(x, 12, 0) +#define V_WB_XPSD_BIL_FACTOR(x) VAL_MASK(x, 14, 16) +#define WB_YRGB_MST 0x00000028 +#define V_WB_YRGB_MST(x) VAL_MASK(x, 32, 0) +#define WB_CBR_MST 0x0000002c +#define V_WB_CBR_MST(x) VAL_MASK(x, 32, 0) +#define WIN0_CTRL0 0x00000030 +#define V_WIN0_EN(x) VAL_MASK(x, 1, 0) +#define V_WIN0_DATA_FMT(x) VAL_MASK(x, 3, 1) +#define V_WIN0_FMT_10(x) VAL_MASK(x, 1, 4) +#define V_WIN0_LB_MODE(x) VAL_MASK(x, 3, 5) +#define V_WIN0_INTERLACE_READ(x) VAL_MASK(x, 1, 8) +#define V_WIN0_NO_OUTSTANDING(x) VAL_MASK(x, 1, 9) +#define V_WIN0_CSC_MODE(x) VAL_MASK(x, 2, 10) +#define V_WIN0_RB_SWAP(x) VAL_MASK(x, 1, 12) +#define V_WIN0_ALPHA_SWAP(x) VAL_MASK(x, 1, 13) +#define V_WIN0_MID_SWAP(x) VAL_MASK(x, 1, 14) +#define V_WIN0_UV_SWAP(x) VAL_MASK(x, 1, 15) +#define V_WIN0_HW_PRE_MUL_EN(x) VAL_MASK(x, 1, 16) +#define V_WIN0_YRGB_DEFLICK(x) VAL_MASK(x, 1, 18) +#define V_WIN0_CBR_DEFLICK(x) VAL_MASK(x, 1, 19) +#define V_WIN0_YUV_CLIP(x) VAL_MASK(x, 1, 20) +#define V_WIN0_X_MIR_EN(x) VAL_MASK(x, 1, 21) +#define V_WIN0_Y_MIR_EN(x) VAL_MASK(x, 1, 22) +#define V_WIN0_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 24) +#define V_WIN0_AXI_OUTSTANDING_MAX_NUM(x) VAL_MASK(x, 5, 25) +#define V_WIN0_DMA_BURST_LENGTH(x) VAL_MASK(x, 2, 30) +#define WIN0_CTRL1 0x00000034 +#define V_WIN0_YRGB_AXI_GATHER_EN(x) VAL_MASK(x, 1, 0) +#define V_WIN0_CBR_AXI_GATHER_EN(x) VAL_MASK(x, 1, 1) +#define V_WIN0_BIC_COE_SEL(x) VAL_MASK(x, 2, 2) +#define V_WIN0_VSD_YRGB_GT4(x) VAL_MASK(x, 1, 4) +#define V_WIN0_VSD_YRGB_GT2(x) VAL_MASK(x, 1, 5) +#define V_WIN0_VSD_CBR_GT4(x) VAL_MASK(x, 1, 6) +#define V_WIN0_VSD_CBR_GT2(x) VAL_MASK(x, 1, 7) +#define V_WIN0_YRGB_AXI_GATHER_NUM(x) VAL_MASK(x, 4, 8) +#define V_WIN0_CBR_AXI_GATHER_NUM(x) VAL_MASK(x, 3, 12) +#define V_WIN0_LINE_LOAD_MODE(x) VAL_MASK(x, 1, 15) +#define V_WIN0_YRGB_HOR_SCL_MODE(x) VAL_MASK(x, 2, 16) +#define V_WIN0_YRGB_VER_SCL_MODE(x) VAL_MASK(x, 2, 18) +#define V_WIN0_YRGB_HSD_MODE(x) VAL_MASK(x, 2, 20) +#define V_WIN0_YRGB_VSU_MODE(x) VAL_MASK(x, 1, 22) +#define V_WIN0_YRGB_VSD_MODE(x) VAL_MASK(x, 1, 23) +#define V_WIN0_CBR_HOR_SCL_MODE(x) VAL_MASK(x, 2, 24) +#define V_WIN0_CBR_VER_SCL_MODE(x) VAL_MASK(x, 2, 26) +#define V_WIN0_CBR_HSD_MODE(x) VAL_MASK(x, 2, 28) +#define V_WIN0_CBR_VSU_MODE(x) VAL_MASK(x, 1, 30) +#define V_WIN0_CBR_VSD_MODE(x) VAL_MASK(x, 1, 31) +#define WIN0_COLOR_KEY 0x00000038 +#define V_WIN0_KEY_COLOR(x) VAL_MASK(x, 24, 0) +#define V_WIN0_KEY_EN(x) VAL_MASK(x, 1, 31) +#define WIN0_VIR 0x0000003c +#define V_WIN0_VIR_STRIDE(x) VAL_MASK(x, 16, 0) +#define V_WIN0_VIR_STRIDE_UV(x) VAL_MASK(x, 16, 16) +#define WIN0_YRGB_MST 0x00000040 +#define V_WIN0_YRGB_MST(x) VAL_MASK(x, 32, 0) +#define WIN0_CBR_MST 0x00000044 +#define V_WIN0_CBR_MST(x) VAL_MASK(x, 32, 0) +#define WIN0_ACT_INFO 0x00000048 +#define V_WIN0_ACT_WIDTH(x) VAL_MASK(x, 13, 0) +#define V_FIELD0002(x) VAL_MASK(x, 1, 13) +#define V_FIELD0001(x) VAL_MASK(x, 1, 14) +#define V_FIELD0000(x) VAL_MASK(x, 1, 15) +#define V_WIN0_ACT_HEIGHT(x) VAL_MASK(x, 13, 16) +#define WIN0_DSP_INFO 0x0000004c +#define V_WIN0_DSP_WIDTH(x) VAL_MASK(x, 12, 0) +#define V_WIN0_DSP_HEIGHT(x) VAL_MASK(x, 12, 16) +#define WIN0_DSP_ST 0x00000050 +#define V_WIN0_DSP_XST(x) VAL_MASK(x, 13, 0) +#define V_WIN0_DSP_YST(x) VAL_MASK(x, 13, 16) +#define WIN0_SCL_FACTOR_YRGB 0x00000054 +#define V_WIN0_HS_FACTOR_YRGB(x) VAL_MASK(x, 16, 0) +#define V_WIN0_VS_FACTOR_YRGB(x) VAL_MASK(x, 16, 16) +#define WIN0_SCL_FACTOR_CBR 0x00000058 +#define V_WIN0_HS_FACTOR_CBR(x) VAL_MASK(x, 16, 0) +#define V_WIN0_VS_FACTOR_CBR(x) VAL_MASK(x, 16, 16) +#define WIN0_SCL_OFFSET 0x0000005c +#define V_WIN0_HS_OFFSET_YRGB(x) VAL_MASK(x, 8, 0) +#define V_WIN0_HS_OFFSET_CBR(x) VAL_MASK(x, 8, 8) +#define V_WIN0_VS_OFFSET_YRGB(x) VAL_MASK(x, 8, 16) +#define V_WIN0_VS_OFFSET_CBR(x) VAL_MASK(x, 8, 24) +#define WIN0_SRC_ALPHA_CTRL 0x00000060 +#define V_WIN0_SRC_ALPHA_EN(x) VAL_MASK(x, 1, 0) +#define V_WIN0_SRC_COLOR_MODE(x) VAL_MASK(x, 1, 1) +#define V_WIN0_SRC_ALPHA_MODE(x) VAL_MASK(x, 1, 2) +#define V_WIN0_SRC_BLEND_MODE(x) VAL_MASK(x, 2, 3) +#define V_WIN0_SRC_ALPHA_CAL_MODE(x) VAL_MASK(x, 1, 5) +#define V_WIN0_SRC_FACTOR_MODE(x) VAL_MASK(x, 3, 6) +#define V_WIN0_SRC_GLOBAL_ALPHA(x) VAL_MASK(x, 8, 16) +#define V_WIN0_FADING_VALUE(x) VAL_MASK(x, 8, 24) +#define WIN0_DST_ALPHA_CTRL 0x00000064 +#define V_WIN0_DST_M0_RESERVED(x) VAL_MASK(x, 6, 0) +#define V_WIN0_DST_FACTOR_MODE(x) VAL_MASK(x, 3, 6) +#define WIN0_FADING_CTRL 0x00000068 +#define V_LAYER0_FADING_OFFSET_R(x) VAL_MASK(x, 8, 0) +#define V_LAYER0_FADING_OFFSET_G(x) VAL_MASK(x, 8, 8) +#define V_LAYER0_FADING_OFFSET_B(x) VAL_MASK(x, 8, 16) +#define V_LAYER0_FADING_EN(x) VAL_MASK(x, 1, 24) +#define WIN0_CTRL2 0x0000006c +#define V_WIN_RID_WIN0_YRGB(x) VAL_MASK(x, 4, 0) +#define V_WIN_RID_WIN0_CBR(x) VAL_MASK(x, 4, 4) +#define WIN1_CTRL0 0x00000070 +#define V_WIN1_EN(x) VAL_MASK(x, 1, 0) +#define V_WIN1_DATA_FMT(x) VAL_MASK(x, 3, 1) +#define V_WIN1_FMT_10(x) VAL_MASK(x, 1, 4) +#define V_WIN1_LB_MODE(x) VAL_MASK(x, 3, 5) +#define V_WIN1_INTERLACE_READ(x) VAL_MASK(x, 1, 8) +#define V_WIN1_NO_OUTSTANDING(x) VAL_MASK(x, 1, 9) +#define V_WIN1_CSC_MODE(x) VAL_MASK(x, 2, 10) +#define V_WIN1_RB_SWAP(x) VAL_MASK(x, 1, 12) +#define V_WIN1_ALPHA_SWAP(x) VAL_MASK(x, 1, 13) +#define V_WIN1_MID_SWAP(x) VAL_MASK(x, 1, 14) +#define V_WIN1_UV_SWAP(x) VAL_MASK(x, 1, 15) +#define V_WIN1_HW_PRE_MUL_EN(x) VAL_MASK(x, 1, 16) +#define V_WIN1_YRGB_DEFLICK(x) VAL_MASK(x, 1, 18) +#define V_WIN1_CBR_DEFLICK(x) VAL_MASK(x, 1, 19) +#define V_WIN1_YUV_CLIP(x) VAL_MASK(x, 1, 20) +#define V_WIN1_X_MIR_EN(x) VAL_MASK(x, 1, 21) +#define V_WIN1_Y_MIR_EN(x) VAL_MASK(x, 1, 22) +#define V_WIN1_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 24) +#define V_WIN1_AXI_MAX_OUTSTANDING_NUM(x) VAL_MASK(x, 5, 25) +#define V_WIN1_DMA_BURST_LENGTH(x) VAL_MASK(x, 2, 30) +#define WIN1_CTRL1 0x00000074 +#define V_WIN1_YRGB_AXI_GATHER_EN(x) VAL_MASK(x, 1, 0) +#define V_WIN1_CBR_AXI_GATHER_EN(x) VAL_MASK(x, 1, 1) +#define V_WIN1_BIC_COE_SEL(x) VAL_MASK(x, 2, 2) +#define V_WIN1_VSD_YRGB_GT4(x) VAL_MASK(x, 1, 4) +#define V_WIN1_VSD_YRGB_GT2(x) VAL_MASK(x, 1, 5) +#define V_WIN1_VSD_CBR_GT4(x) VAL_MASK(x, 1, 6) +#define V_WIN1_VSD_CBR_GT2(x) VAL_MASK(x, 1, 7) +#define V_WIN1_YRGB_AXI_GATHER_NUM(x) VAL_MASK(x, 4, 8) +#define V_WIN1_CBR_AXI_GATHER_NUM(x) VAL_MASK(x, 3, 12) +#define V_WIN1_LINE_LOAD_MODE(x) VAL_MASK(x, 1, 15) +#define V_WIN1_YRGB_HOR_SCL_MODE(x) VAL_MASK(x, 2, 16) +#define V_WIN1_YRGB_VER_SCL_MODE(x) VAL_MASK(x, 2, 18) +#define V_WIN1_YRGB_HSD_MODE(x) VAL_MASK(x, 2, 20) +#define V_WIN1_YRGB_VSU_MODE(x) VAL_MASK(x, 1, 22) +#define V_WIN1_YRGB_VSD_MODE(x) VAL_MASK(x, 1, 23) +#define V_WIN1_CBR_HOR_SCL_MODE(x) VAL_MASK(x, 2, 24) +#define V_WIN1_CBR_VER_SCL_MODE(x) VAL_MASK(x, 2, 26) +#define V_WIN1_CBR_HSD_MODE(x) VAL_MASK(x, 2, 28) +#define V_WIN1_CBR_VSU_MODE(x) VAL_MASK(x, 1, 30) +#define V_WIN1_CBR_VSD_MODE(x) VAL_MASK(x, 1, 31) +#define WIN1_COLOR_KEY 0x00000078 +#define V_WIN1_KEY_COLOR(x) VAL_MASK(x, 24, 0) +#define V_WIN1_KEY_EN(x) VAL_MASK(x, 1, 31) +#define WIN1_VIR 0x0000007c +#define V_WIN1_VIR_STRIDE(x) VAL_MASK(x, 16, 0) +#define V_WIN1_VIR_STRIDE_UV(x) VAL_MASK(x, 16, 16) +#define WIN1_YRGB_MST 0x00000080 +#define V_WIN1_YRGB_MST(x) VAL_MASK(x, 32, 0) +#define WIN1_CBR_MST 0x00000084 +#define V_WIN1_CBR_MST(x) VAL_MASK(x, 32, 0) +#define WIN1_ACT_INFO 0x00000088 +#define V_WIN1_ACT_WIDTH(x) VAL_MASK(x, 13, 0) +#define V_WIN1_ACT_HEIGHT(x) VAL_MASK(x, 13, 16) +#define WIN1_DSP_INFO 0x0000008c +#define V_WIN1_DSP_WIDTH(x) VAL_MASK(x, 12, 0) +#define V_WIN1_DSP_HEIGHT(x) VAL_MASK(x, 12, 16) +#define WIN1_DSP_ST 0x00000090 +#define V_WIN1_DSP_XST(x) VAL_MASK(x, 13, 0) +#define V_WIN1_DSP_YST(x) VAL_MASK(x, 13, 16) +#define WIN1_SCL_FACTOR_YRGB 0x00000094 +#define V_WIN1_HS_FACTOR_YRGB(x) VAL_MASK(x, 16, 0) +#define V_WIN1_VS_FACTOR_YRGB(x) VAL_MASK(x, 16, 16) +#define WIN1_SCL_FACTOR_CBR 0x00000098 +#define V_WIN1_HS_FACTOR_CBR(x) VAL_MASK(x, 16, 0) +#define V_WIN1_VS_FACTOR_CBR(x) VAL_MASK(x, 16, 16) +#define WIN1_SCL_OFFSET 0x0000009c +#define V_WIN1_HS_OFFSET_YRGB(x) VAL_MASK(x, 8, 0) +#define V_WIN1_HS_OFFSET_CBR(x) VAL_MASK(x, 8, 8) +#define V_WIN1_VS_OFFSET_YRGB(x) VAL_MASK(x, 8, 16) +#define V_WIN1_VS_OFFSET_CBR(x) VAL_MASK(x, 8, 24) +#define WIN1_SRC_ALPHA_CTRL 0x000000a0 +#define V_WIN1_SRC_ALPHA_EN(x) VAL_MASK(x, 1, 0) +#define V_WIN1_SRC_COLOR_MODE(x) VAL_MASK(x, 1, 1) +#define V_WIN1_SRC_ALPHA_MODE(x) VAL_MASK(x, 1, 2) +#define V_WIN1_SRC_BLEND_MODE(x) VAL_MASK(x, 2, 3) +#define V_WIN1_SRC_ALPHA_CAL_MODE(x) VAL_MASK(x, 1, 5) +#define V_WIN1_SRC_FACTOR_MODE(x) VAL_MASK(x, 3, 6) +#define V_WIN1_SRC_GLOBAL_ALPHA(x) VAL_MASK(x, 8, 16) +#define V_WIN1_FADING_VALUE(x) VAL_MASK(x, 8, 24) +#define WIN1_DST_ALPHA_CTRL 0x000000a4 +#define V_WIN1_DSP_M0_RESERVED(x) VAL_MASK(x, 6, 0) +#define V_WIN1_DST_FACTOR_M0(x) VAL_MASK(x, 3, 6) +#define WIN1_FADING_CTRL 0x000000a8 +#define V_WIN1_FADING_OFFSET_R(x) VAL_MASK(x, 8, 0) +#define V_WIN1_FADING_OFFSET_G(x) VAL_MASK(x, 8, 8) +#define V_WIN1_FADING_OFFSET_B(x) VAL_MASK(x, 8, 16) +#define V_WIN1_FADING_EN(x) VAL_MASK(x, 1, 24) +#define WIN1_CTRL2 0x000000ac +#define V_WIN_RID_WIN1_YRGB(x) VAL_MASK(x, 4, 0) +#define V_WIN_RID_WIN1_CBR(x) VAL_MASK(x, 4, 4) +#define WIN2_CTRL0 0x000000b0 +#define V_WIN2_EN(x) VAL_MASK(x, 1, 0) +#define V_WIN2_INTERLACE_READ(x) VAL_MASK(x, 1, 1) +#define V_WIN2_CSC_MODE(x) VAL_MASK(x, 1, 2) +#define V_WIN2_MST0_EN(x) VAL_MASK(x, 1, 4) +#define V_WIN2_DATA_FMT0(x) VAL_MASK(x, 2, 5) +#define V_WIN2_MST1_EN(x) VAL_MASK(x, 1, 8) +#define V_WIN2_DATA_FMT1(x) VAL_MASK(x, 2, 9) +#define V_WIN2_MST2_EN(x) VAL_MASK(x, 1, 12) +#define V_WIN2_DATA_FMT2(x) VAL_MASK(x, 2, 13) +#define V_WIN2_MST3_EN(x) VAL_MASK(x, 1, 16) +#define V_WIN2_DATA_FMT3(x) VAL_MASK(x, 2, 17) +#define V_WIN2_RB_SWAP0(x) VAL_MASK(x, 1, 20) +#define V_WIN2_ALPHA_SWAP0(x) VAL_MASK(x, 1, 21) +#define V_WIN2_ENDIAN_SWAP0(x) VAL_MASK(x, 1, 22) +#define V_WIN2_RB_SWAP1(x) VAL_MASK(x, 1, 23) +#define V_WIN2_ALPHA_SWAP1(x) VAL_MASK(x, 1, 24) +#define V_WIN2_ENDIAN_SWAP1(x) VAL_MASK(x, 1, 25) +#define V_WIN2_RB_SWAP2(x) VAL_MASK(x, 1, 26) +#define V_WIN2_ALPHA_SWAP2(x) VAL_MASK(x, 1, 27) +#define V_WIN2_ENDIAN_SWAP2(x) VAL_MASK(x, 1, 28) +#define V_WIN2_RB_SWAP3(x) VAL_MASK(x, 1, 29) +#define V_WIN2_ALPHA_SWAP3(x) VAL_MASK(x, 1, 30) +#define V_WIN2_ENDIAN_SWAP3(x) VAL_MASK(x, 1, 31) +#define WIN2_CTRL1 0x000000b4 +#define V_WIN2_AXI_GATHER_EN(x) VAL_MASK(x, 1, 0) +#define V_WIN2_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 1) +#define V_WIN2_DMA_BURST_LENGTH(x) VAL_MASK(x, 2, 2) +#define V_WIN2_AXI_GATHER_NUM(x) VAL_MASK(x, 4, 4) +#define V_WIN2_AXI_MAX_OUTSTANDING_NUM(x) VAL_MASK(x, 5, 8) +#define V_WIN2_NO_OUTSTANDING(x) VAL_MASK(x, 1, 14) +#define V_WIN2_Y_MIR_EN(x) VAL_MASK(x, 1, 15) +#define V_WIN2_LUT_EN(x) VAL_MASK(x, 1, 16) +#define V_WIN_RID_WIN2(x) VAL_MASK(x, 4, 20) +#define WIN2_VIR0_1 0x000000b8 +#define V_WIN2_VIR_STRIDE0(x) VAL_MASK(x, 16, 0) +#define V_WIN2_VIR_STRIDE1(x) VAL_MASK(x, 16, 16) +#define WIN2_VIR2_3 0x000000bc +#define V_WIN2_VIR_STRIDE2(x) VAL_MASK(x, 16, 0) +#define V_WIN2_VIR_STRIDE3(x) VAL_MASK(x, 16, 16) +#define WIN2_MST0 0x000000c0 +#define V_WIN2_MST0(x) VAL_MASK(x, 32, 0) +#define WIN2_DSP_INFO0 0x000000c4 +#define V_WIN2_DSP_WIDTH0(x) VAL_MASK(x, 12, 0) +#define V_WIN2_DSP_HEIGHT0(x) VAL_MASK(x, 12, 16) +#define WIN2_DSP_ST0 0x000000c8 +#define V_WIN2_DSP_XST0(x) VAL_MASK(x, 13, 0) +#define V_WIN2_DSP_YST0(x) VAL_MASK(x, 13, 16) +#define WIN2_COLOR_KEY 0x000000cc +#define V_WIN2_KEY_COLOR(x) VAL_MASK(x, 24, 0) +#define V_WIN2_KEY_EN(x) VAL_MASK(x, 1, 24) +#define WIN2_MST1 0x000000d0 +#define V_WIN2_MST1(x) VAL_MASK(x, 32, 0) +#define WIN2_DSP_INFO1 0x000000d4 +#define V_WIN2_DSP_WIDTH1(x) VAL_MASK(x, 12, 0) +#define V_WIN2_DSP_HEIGHT1(x) VAL_MASK(x, 12, 16) +#define WIN2_DSP_ST1 0x000000d8 +#define V_WIN2_DSP_XST1(x) VAL_MASK(x, 13, 0) +#define V_WIN2_DSP_YST1(x) VAL_MASK(x, 13, 16) +#define WIN2_SRC_ALPHA_CTRL 0x000000dc +#define V_WIN2_SRC_ALPHA_EN(x) VAL_MASK(x, 1, 0) +#define V_WIN2_SRC_COLOR_MODE(x) VAL_MASK(x, 1, 1) +#define V_WIN2_SRC_ALPHA_MODE(x) VAL_MASK(x, 1, 2) +#define V_WIN2_SRC_BLEND_MODE(x) VAL_MASK(x, 2, 3) +#define V_WIN2_SRC_ALPHA_CAL_MODE(x) VAL_MASK(x, 1, 5) +#define V_WIN2_SRC_FACTOR_MODE(x) VAL_MASK(x, 3, 6) +#define V_WIN2_SRC_GLOBAL_ALPHA(x) VAL_MASK(x, 8, 16) +#define V_WIN2_FADING_VALUE(x) VAL_MASK(x, 8, 24) +#define WIN2_MST2 0x000000e0 +#define V_WIN2_MST2(x) VAL_MASK(x, 32, 0) +#define WIN2_DSP_INFO2 0x000000e4 +#define V_WIN2_DSP_WIDTH2(x) VAL_MASK(x, 12, 0) +#define V_WIN2_DSP_HEIGHT2(x) VAL_MASK(x, 12, 16) +#define WIN2_DSP_ST2 0x000000e8 +#define V_WIN2_DSP_XST2(x) VAL_MASK(x, 13, 0) +#define V_WIN2_DSP_YST2(x) VAL_MASK(x, 13, 16) +#define WIN2_DST_ALPHA_CTRL 0x000000ec +#define V_WIN2_DST_M0_RESERVED(x) VAL_MASK(x, 6, 0) +#define V_WIN2_DST_FACTOR_MODE(x) VAL_MASK(x, 3, 6) +#define WIN2_MST3 0x000000f0 +#define V_WIN2_MST3(x) VAL_MASK(x, 32, 0) +#define WIN2_DSP_INFO3 0x000000f4 +#define V_WIN2_DSP_WIDTH3(x) VAL_MASK(x, 12, 0) +#define V_WIN2_DSP_HEIGHT3(x) VAL_MASK(x, 12, 16) +#define WIN2_DSP_ST3 0x000000f8 +#define V_WIN2_DSP_XST3(x) VAL_MASK(x, 13, 0) +#define V_WIN2_DSP_YST3(x) VAL_MASK(x, 13, 16) +#define WIN2_FADING_CTRL 0x000000fc +#define V_WIN2_FADING_OFFSET_R(x) VAL_MASK(x, 8, 0) +#define V_WIN2_FADING_OFFSET_G(x) VAL_MASK(x, 8, 8) +#define V_WIN2_FADING_OFFSET_B(x) VAL_MASK(x, 8, 16) +#define V_WIN2_FADING_EN(x) VAL_MASK(x, 1, 24) +#define WIN3_CTRL0 0x00000100 +#define V_WIN3_EN(x) VAL_MASK(x, 1, 0) +#define V_WIN3_INTERLACE_READ(x) VAL_MASK(x, 1, 1) +#define V_WIN3_CSC_MODE(x) VAL_MASK(x, 1, 2) +#define V_WIN3_MST0_EN(x) VAL_MASK(x, 1, 4) +#define V_WIN3_DATA_FMT0(x) VAL_MASK(x, 2, 5) +#define V_WIN3_MST1_EN(x) VAL_MASK(x, 1, 8) +#define V_WIN3_DATA_FMT1(x) VAL_MASK(x, 2, 9) +#define V_WIN3_MST2_EN(x) VAL_MASK(x, 1, 12) +#define V_WIN3_DATA_FMT2(x) VAL_MASK(x, 2, 13) +#define V_WIN3_MST3_EN(x) VAL_MASK(x, 1, 16) +#define V_WIN3_DATA_FMT3(x) VAL_MASK(x, 2, 17) +#define V_WIN3_RB_SWAP0(x) VAL_MASK(x, 1, 20) +#define V_WIN3_ALPHA_SWAP0(x) VAL_MASK(x, 1, 21) +#define V_WIN3_ENDIAN_SWAP0(x) VAL_MASK(x, 1, 22) +#define V_WIN3_RB_SWAP1(x) VAL_MASK(x, 1, 23) +#define V_WIN3_ALPHA_SWAP1(x) VAL_MASK(x, 1, 24) +#define V_WIN3_ENDIAN_SWAP1(x) VAL_MASK(x, 1, 25) +#define V_WIN3_RB_SWAP2(x) VAL_MASK(x, 1, 26) +#define V_WIN3_ALPHA_SWAP2(x) VAL_MASK(x, 1, 27) +#define V_WIN3_ENDIAN_SWAP2(x) VAL_MASK(x, 1, 28) +#define V_WIN3_RB_SWAP3(x) VAL_MASK(x, 1, 29) +#define V_WIN3_ALPHA_SWAP3(x) VAL_MASK(x, 1, 30) +#define V_WIN3_ENDIAN_SWAP3(x) VAL_MASK(x, 1, 31) +#define WIN3_CTRL1 0x00000104 +#define V_WIN3_AXI_GATHER_EN(x) VAL_MASK(x, 1, 0) +#define V_WIN3_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 1) +#define V_WIN3_DMA_BURST_LENGTH(x) VAL_MASK(x, 2, 2) +#define V_WIN3_AXI_GATHER_NUM(x) VAL_MASK(x, 4, 4) +#define V_WIN3_AXI_MAX_OUTSTANDING_NUM(x) VAL_MASK(x, 5, 8) +#define V_WIN3_NO_OUTSTANDING(x) VAL_MASK(x, 1, 14) +#define V_WIN3_Y_MIR_EN(x) VAL_MASK(x, 1, 15) +#define V_WIN3_LUT_EN(x) VAL_MASK(x, 1, 16) +#define V_WIN_RID_WIN3(x) VAL_MASK(x, 4, 20) +#define WIN3_VIR0_1 0x00000108 +#define V_WIN3_VIR_STRIDE0(x) VAL_MASK(x, 16, 0) +#define V_WIN3_VIR_STRIDE1(x) VAL_MASK(x, 16, 16) +#define WIN3_VIR2_3 0x0000010c +#define V_WIN3_VIR_STRIDE2(x) VAL_MASK(x, 16, 0) +#define V_WIN3_VIR_STRIDE3(x) VAL_MASK(x, 16, 16) +#define WIN3_MST0 0x00000110 +#define V_WIN3_MST0(x) VAL_MASK(x, 32, 0) +#define WIN3_DSP_INFO0 0x00000114 +#define V_WIN3_DSP_WIDTH0(x) VAL_MASK(x, 12, 0) +#define V_WIN3_DSP_HEIGHT0(x) VAL_MASK(x, 12, 16) +#define WIN3_DSP_ST0 0x00000118 +#define V_WIN3_DSP_XST0(x) VAL_MASK(x, 13, 0) +#define V_WIN3_DSP_YST0(x) VAL_MASK(x, 13, 16) +#define WIN3_COLOR_KEY 0x0000011c +#define V_WIN3_KEY_COLOR(x) VAL_MASK(x, 24, 0) +#define V_WIN3_KEY_EN(x) VAL_MASK(x, 1, 24) +#define WIN3_MST1 0x00000120 +#define V_WIN3_MST1(x) VAL_MASK(x, 32, 0) +#define WIN3_DSP_INFO1 0x00000124 +#define V_WIN3_DSP_WIDTH1(x) VAL_MASK(x, 12, 0) +#define V_WIN3_DSP_HEIGHT1(x) VAL_MASK(x, 12, 16) +#define WIN3_DSP_ST1 0x00000128 +#define V_WIN3_DSP_XST1(x) VAL_MASK(x, 13, 0) +#define V_WIN3_DSP_YST1(x) VAL_MASK(x, 13, 16) +#define WIN3_SRC_ALPHA_CTRL 0x0000012c +#define V_WIN3_SRC_ALPHA_EN(x) VAL_MASK(x, 1, 0) +#define V_WIN3_SRC_COLOR_MODE(x) VAL_MASK(x, 1, 1) +#define V_WIN3_SRC_ALPHA_MODE(x) VAL_MASK(x, 1, 2) +#define V_WIN3_SRC_BLEND_MODE(x) VAL_MASK(x, 2, 3) +#define V_WIN3_SRC_ALPHA_CAL_MODE(x) VAL_MASK(x, 1, 5) +#define V_WIN3_SRC_FACTOR_MODE(x) VAL_MASK(x, 3, 6) +#define V_WIN3_SRC_GLOBAL_ALPHA(x) VAL_MASK(x, 8, 16) +#define V_WIN3_FADING_VALUE(x) VAL_MASK(x, 8, 24) +#define WIN3_MST2 0x00000130 +#define V_WIN3_MST2(x) VAL_MASK(x, 32, 0) +#define WIN3_DSP_INFO2 0x00000134 +#define V_WIN3_DSP_WIDTH2(x) VAL_MASK(x, 12, 0) +#define V_WIN3_DSP_HEIGHT2(x) VAL_MASK(x, 12, 16) +#define WIN3_DSP_ST2 0x00000138 +#define V_WIN3_DSP_XST2(x) VAL_MASK(x, 13, 0) +#define V_WIN3_DSP_YST2(x) VAL_MASK(x, 13, 16) +#define WIN3_DST_ALPHA_CTRL 0x0000013c +#define V_WIN3_DST_FACTOR_RESERVED(x) VAL_MASK(x, 6, 0) +#define V_WIN3_DST_FACTOR_MODE(x) VAL_MASK(x, 3, 6) +#define WIN3_MST3 0x00000140 +#define V_WIN3_MST3(x) VAL_MASK(x, 32, 0) +#define WIN3_DSP_INFO3 0x00000144 +#define V_WIN3_DSP_WIDTH3(x) VAL_MASK(x, 12, 0) +#define V_WIN3_DSP_HEIGHT3(x) VAL_MASK(x, 12, 16) +#define WIN3_DSP_ST3 0x00000148 +#define V_WIN3_DSP_XST3(x) VAL_MASK(x, 13, 0) +#define V_WIN3_DSP_YST3(x) VAL_MASK(x, 13, 16) +#define WIN3_FADING_CTRL 0x0000014c +#define V_WIN3_FADING_OFFSET_R(x) VAL_MASK(x, 8, 0) +#define V_WIN3_FADING_OFFSET_G(x) VAL_MASK(x, 8, 8) +#define V_WIN3_FADING_OFFSET_B(x) VAL_MASK(x, 8, 16) +#define V_WIN3_FADING_EN(x) VAL_MASK(x, 1, 24) +#define HWC_CTRL0 0x00000150 +#define V_HWC_EN(x) VAL_MASK(x, 1, 0) +#define V_HWC_DATA_FMT(x) VAL_MASK(x, 3, 1) +#define V_HWC_MODE(x) VAL_MASK(x, 1, 4) +#define V_HWC_SIZE(x) VAL_MASK(x, 2, 5) +#define V_HWC_INTERLACE_READ(x) VAL_MASK(x, 1, 8) +#define V_HWC_CSC_MODE(x) VAL_MASK(x, 1, 10) +#define V_HWC_RB_SWAP(x) VAL_MASK(x, 1, 12) +#define V_HWC_ALPHA_SWAP(x) VAL_MASK(x, 1, 13) +#define V_HWC_ENDIAN_SWAP(x) VAL_MASK(x, 1, 14) +#define HWC_CTRL1 0x00000154 +#define V_HWC_AXI_GATHER_EN(x) VAL_MASK(x, 1, 0) +#define V_HWC_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 1) +#define V_HWC_DMA_BURST_LENGTH(x) VAL_MASK(x, 2, 2) +#define V_HWC_AXI_GATHER_NUM(x) VAL_MASK(x, 3, 4) +#define V_HWC_AXI_MAX_OUTSTANDING_NUM(x) VAL_MASK(x, 5, 8) +#define V_HWC_RGB2YUV_EN(x) VAL_MASK(x, 1, 13) +#define V_HWC_NO_OUTSTANDING(x) VAL_MASK(x, 1, 14) +#define V_HWC_Y_MIR_EN(x) VAL_MASK(x, 1, 15) +#define V_HWC_LUT_EN(x) VAL_MASK(x, 1, 16) +#define V_WIN_RID_HWC(x) VAL_MASK(x, 4, 20) +#define HWC_MST 0x00000158 +#define V_HWC_MST(x) VAL_MASK(x, 32, 0) +#define HWC_DSP_ST 0x0000015c +#define V_HWC_DSP_XST(x) VAL_MASK(x, 13, 0) +#define V_HWC_DSP_YST(x) VAL_MASK(x, 13, 16) +#define HWC_SRC_ALPHA_CTRL 0x00000160 +#define V_HWC_SRC_ALPHA_EN(x) VAL_MASK(x, 1, 0) +#define V_HWC_SRC_COLOR_MODE(x) VAL_MASK(x, 1, 1) +#define V_HWC_SRC_ALPHA_MODE(x) VAL_MASK(x, 1, 2) +#define V_HWC_SRC_BLEND_MODE(x) VAL_MASK(x, 2, 3) +#define V_HWC_SRC_ALPHA_CAL_MODE(x) VAL_MASK(x, 1, 5) +#define V_HWC_SRC_FACTOR_MODE(x) VAL_MASK(x, 3, 6) +#define V_HWC_SRC_GLOBAL_ALPHA(x) VAL_MASK(x, 8, 16) +#define V_HWC_FADING_VALUE(x) VAL_MASK(x, 8, 24) +#define HWC_DST_ALPHA_CTRL 0x00000164 +#define V_HWC_DST_M0_RESERVED(x) VAL_MASK(x, 6, 0) +#define V_HWC_DST_FACTOR_MODE(x) VAL_MASK(x, 3, 6) +#define HWC_FADING_CTRL 0x00000168 +#define V_HWC_FADING_OFFSET_R(x) VAL_MASK(x, 8, 0) +#define V_HWC_FADING_OFFSET_G(x) VAL_MASK(x, 8, 8) +#define V_HWC_FADING_OFFSET_B(x) VAL_MASK(x, 8, 16) +#define V_HWC_FADING_EN(x) VAL_MASK(x, 1, 24) +#define HWC_RESERVED1 0x0000016c +#define POST_DSP_HACT_INFO 0x00000170 +#define V_DSP_HACT_END_POST(x) VAL_MASK(x, 13, 0) +#define V_DSP_HACT_ST_POST(x) VAL_MASK(x, 13, 16) +#define POST_DSP_VACT_INFO 0x00000174 +#define V_DSP_VACT_END_POST(x) VAL_MASK(x, 13, 0) +#define V_DSP_VACT_ST_POST(x) VAL_MASK(x, 13, 16) +#define POST_SCL_FACTOR_YRGB 0x00000178 +#define V_POST_HS_FACTOR_YRGB(x) VAL_MASK(x, 16, 0) +#define V_POST_VS_FACTOR_YRGB(x) VAL_MASK(x, 16, 16) +#define POST_RESERVED 0x0000017c +#define POST_SCL_CTRL 0x00000180 +#define V_POST_HOR_SD_EN(x) VAL_MASK(x, 1, 0) +#define V_POST_VER_SD_EN(x) VAL_MASK(x, 1, 1) +#define POST_DSP_VACT_INFO_F1 0x00000184 +#define V_DSP_VACT_END_POST(x) VAL_MASK(x, 13, 0) +#define V_DSP_VACT_ST_POST(x) VAL_MASK(x, 13, 16) +#define DSP_HTOTAL_HS_END 0x00000188 +#define V_DSP_HS_END(x) VAL_MASK(x, 13, 0) +#define V_DSP_HTOTAL(x) VAL_MASK(x, 13, 16) +#define DSP_HACT_ST_END 0x0000018c +#define V_DSP_HACT_END(x) VAL_MASK(x, 13, 0) +#define V_DSP_HACT_ST(x) VAL_MASK(x, 13, 16) +#define DSP_VTOTAL_VS_END 0x00000190 +#define V_DSP_VS_END(x) VAL_MASK(x, 13, 0) +#define V_SW_DSP_VTOTAL_IMD(x) VAL_MASK(x, 1, 15) +#define V_DSP_VTOTAL(x) VAL_MASK(x, 13, 16) +#define DSP_VACT_ST_END 0x00000194 +#define V_DSP_VACT_END(x) VAL_MASK(x, 13, 0) +#define V_DSP_VACT_ST(x) VAL_MASK(x, 13, 16) +#define DSP_VS_ST_END_F1 0x00000198 +#define V_DSP_VS_END_F1(x) VAL_MASK(x, 13, 0) +#define V_DSP_VS_ST_F1(x) VAL_MASK(x, 13, 16) +#define DSP_VACT_ST_END_F1 0x0000019c +#define V_DSP_VACT_END_F1(x) VAL_MASK(x, 13, 0) +#define V_DSP_VACT_ST_F1(x) VAL_MASK(x, 13, 16) +#define PWM_CTRL 0x000001a0 +#define V_PWM_EN(x) VAL_MASK(x, 1, 0) +#define V_PWM_MODE(x) VAL_MASK(x, 2, 1) +#define V_DUTY_POL(x) VAL_MASK(x, 1, 3) +#define V_INACTIVE_POL(x) VAL_MASK(x, 1, 4) +#define V_OUTPUT_MODE(x) VAL_MASK(x, 1, 5) +#define V_LP_EN(x) VAL_MASK(x, 1, 8) +#define V_CLK_SEL(x) VAL_MASK(x, 1, 9) +#define V_PRESCALE(x) VAL_MASK(x, 3, 12) +#define V_SCALE(x) VAL_MASK(x, 8, 16) +#define V_RPT(x) VAL_MASK(x, 8, 24) +#define PWM_PERIOD_HPR 0x000001a4 +#define V_PWM_PERIOD(x) VAL_MASK(x, 32, 0) +#define PWM_DUTY_LPR 0x000001a8 +#define V_PWM_DUTY(x) VAL_MASK(x, 32, 0) +#define PWM_CNT 0x000001ac +#define V_PWM_CNT(x) VAL_MASK(x, 32, 0) +#define BCSH_COLOR_BAR 0x000001b0 +#define V_BCSH_EN(x) VAL_MASK(x, 1, 0) +#define V_COLOR_BAR_Y(x) VAL_MASK(x, 8, 8) +#define V_COLOR_BAR_U(x) VAL_MASK(x, 8, 16) +#define V_COLOR_BAR_V(x) VAL_MASK(x, 8, 24) +#define BCSH_BCS 0x000001b4 +#define V_BRIGHTNESS(x) VAL_MASK(x, 8, 0) +#define V_CONTRAST(x) VAL_MASK(x, 9, 8) +#define V_SAT_CON(x) VAL_MASK(x, 10, 20) +#define V_OUT_MODE(x) VAL_MASK(x, 2, 30) +#define BCSH_H 0x000001b8 +#define V_SIN_HUE(x) VAL_MASK(x, 9, 0) +#define V_COS_HUE(x) VAL_MASK(x, 9, 16) +#define BCSH_CTRL 0x000001bc +#define V_BCSH_Y2R_EN(x) VAL_MASK(x, 1, 0) +#define V_BCSH_Y2R_CSC_MODE(x) VAL_MASK(x, 2, 2) +#define V_BCSH_R2Y_EN(x) VAL_MASK(x, 1, 4) +#define V_BCSH_R2Y_CSC_MODE(x) VAL_MASK(x, 1, 6) +#define CABC_CTRL0 0x000001c0 +#define V_CABC_EN(x) VAL_MASK(x, 1, 0) +#define V_PWM_CONFIG_MODE(x) VAL_MASK(x, 2, 1) +#define V_CABC_HANDLE_EN(x) VAL_MASK(x, 1, 3) +#define V_CABC_CALC_PIXEL_NUM(x) VAL_MASK(x, 23, 4) +#define CABC_CTRL1 0x000001c4 +#define V_CABC_LUT_EN(x) VAL_MASK(x, 1, 0) +#define V_CABC_TOTAL_NUM(x) VAL_MASK(x, 23, 4) +#define CABC_CTRL2 0x000001c8 +#define V_CABC_STAGE_DOWN(x) VAL_MASK(x, 8, 0) +#define V_CABC_STAGE_UP(x) VAL_MASK(x, 9, 8) +#define V_CABC_STAGE_UP_MODE(x) VAL_MASK(x, 1, 19) +#define CABC_CTRL3 0x000001cc +#define V_CABC_GLOBAL_DN(x) VAL_MASK(x, 8, 0) +#define V_CABC_GLOBAL_DN_LIMIT_EN(x) VAL_MASK(x, 1, 8) +#define CABC_GAUSS_LINE0_0 0x000001d0 +#define V_T_LINE0_0(x) VAL_MASK(x, 8, 0) +#define V_T_LINE0_1(x) VAL_MASK(x, 8, 8) +#define V_T_LINE0_2(x) VAL_MASK(x, 8, 16) +#define V_T_LINE0_3(x) VAL_MASK(x, 8, 24) +#define CABC_GAUSS_LINE0_1 0x000001d4 +#define V_T_LINE0_4(x) VAL_MASK(x, 8, 0) +#define V_T_LINE0_5(x) VAL_MASK(x, 8, 8) +#define V_T_LINE0_6(x) VAL_MASK(x, 8, 16) +#define CABC_GAUSS_LINE1_0 0x000001d8 +#define V_T_LINE1_0(x) VAL_MASK(x, 8, 0) +#define V_T_LINE1_1(x) VAL_MASK(x, 8, 8) +#define V_T_LINE1_2(x) VAL_MASK(x, 8, 16) +#define V_T_LINE1_3(x) VAL_MASK(x, 8, 24) +#define CABC_GAUSS_LINE1_1 0x000001dc +#define V_T_LINE1_4(x) VAL_MASK(x, 8, 0) +#define V_T_LINE1_5(x) VAL_MASK(x, 8, 8) +#define V_T_LINE1_6(x) VAL_MASK(x, 8, 16) +#define CABC_GAUSS_LINE2_0 0x000001e0 +#define V_T_LINE2_0(x) VAL_MASK(x, 8, 0) +#define V_T_LINE2_1(x) VAL_MASK(x, 8, 8) +#define V_T_LINE2_2(x) VAL_MASK(x, 8, 16) +#define V_T_LINE2_3(x) VAL_MASK(x, 8, 24) +#define CABC_GAUSS_LINE2_1 0x000001e4 +#define V_T_LINE2_4(x) VAL_MASK(x, 8, 0) +#define V_T_LINE2_5(x) VAL_MASK(x, 8, 8) +#define V_T_LINE2_6(x) VAL_MASK(x, 8, 16) +#define FRC_LOWER01_0 0x000001e8 +#define V_LOWER01_FRM0(x) VAL_MASK(x, 16, 0) +#define V_LOWER01_FRM1(x) VAL_MASK(x, 16, 16) +#define FRC_LOWER01_1 0x000001ec +#define V_LOWER01_FRM2(x) VAL_MASK(x, 16, 0) +#define V_LOWER01_FRM3(x) VAL_MASK(x, 16, 16) +#define FRC_LOWER10_0 0x000001f0 +#define V_LOWER10_FRM0(x) VAL_MASK(x, 16, 0) +#define V_LOWER10_FRM1(x) VAL_MASK(x, 16, 16) +#define FRC_LOWER10_1 0x000001f4 +#define V_LOWER10_FRM2(x) VAL_MASK(x, 16, 0) +#define V_LOWER10_FRM3(x) VAL_MASK(x, 16, 16) +#define FRC_LOWER11_0 0x000001f8 +#define V_LOWER11_FRM0(x) VAL_MASK(x, 16, 0) +#define V_LOWER11_FRM1(x) VAL_MASK(x, 16, 16) +#define FRC_LOWER11_1 0x000001fc +#define V_LOWER11_FRM2(x) VAL_MASK(x, 16, 0) +#define V_LOWER11_FRM3(x) VAL_MASK(x, 16, 16) +#define AFBCD0_CTRL 0x00000200 +#define V_VOP_FBDC_EN(x) VAL_MASK(x, 1, 0) +#define V_VOP_FBDC_WIN_SEL(x) VAL_MASK(x, 2, 1) +#define V_FBDC_RSTN(x) VAL_MASK(x, 1, 3) +#define V_VOP_FBDC_AXI_MAX_OUTSTANDING_NUM(x) VAL_MASK(x, 5, 4) +#define V_VOP_FBDC_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 9) +#define V_FBDC_RID(x) VAL_MASK(x, 4, 12) +#define V_AFBCD_HREG_PIXEL_PACKING_FMT(x) VAL_MASK(x, 5, 16) +#define V_AFBCD_HREG_BLOCK_SPLIT(x) VAL_MASK(x, 1, 21) +#define AFBCD0_HDR_PTR 0x00000204 +#define V_AFBCD_HREG_HDR_PTR(x) VAL_MASK(x, 32, 0) +#define AFBCD0_PIC_SIZE 0x00000208 +#define V_AFBCD_HREG_PIC_WIDTH(x) VAL_MASK(x, 16, 0) +#define V_AFBCD_HREG_PIC_HEIGHT(x) VAL_MASK(x, 16, 16) +#define AFBCD0_STATUS 0x0000020c +#define V_AFBCD_HREG_IDLE_N(x) VAL_MASK(x, 1, 0) +#define V_AFBCD_HREG_DEC_RESP(x) VAL_MASK(x, 1, 1) +#define V_AFBCD_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 2) +#define AFBCD1_CTRL 0x00000220 +#define V_VOP_FBDC1_EN(x) VAL_MASK(x, 1, 0) +#define V_VOP_FBDC1_WIN_SEL(x) VAL_MASK(x, 2, 1) +#define V_FBDC1_RSTN(x) VAL_MASK(x, 1, 3) +#define V_VOP_FBDC1_AXI_MAX_OUTSTANDING_NUM(x) VAL_MASK(x, 5, 4) +#define V_VOP_FBDC1_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 9) +#define V_FBDC1_RID(x) VAL_MASK(x, 4, 12) +#define V_AFBCD1_HREG_PIXEL_PACKING_FMT(x) VAL_MASK(x, 5, 16) +#define V_AFBCD1_HREG_BLOCK_SPLIT(x) VAL_MASK(x, 1, 21) +#define AFBCD1_HDR_PTR 0x00000224 +#define V_AFBCD1_HREG_HDR_PTR(x) VAL_MASK(x, 32, 0) +#define AFBCD1_PIC_SIZE 0x00000228 +#define V_AFBCD1_HREG_PIC_WIDTH(x) VAL_MASK(x, 16, 0) +#define V_AFBCD1_HREG_PIC_HEIGHT(x) VAL_MASK(x, 16, 16) +#define AFBCD1_STATUS 0x0000022c +#define V_AFBCD1_HREG_IDLE_N(x) VAL_MASK(x, 1, 0) +#define V_AFBCD1_HREG_DEC_RESP(x) VAL_MASK(x, 1, 1) +#define V_AFBCD1_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 2) +#define AFBCD2_CTRL 0x00000240 +#define V_VOP_FBDC2_EN(x) VAL_MASK(x, 1, 0) +#define V_VOP_FBDC2_WIN_SEL(x) VAL_MASK(x, 2, 1) +#define V_FBDC2_RSTN(x) VAL_MASK(x, 1, 3) +#define V_VOP_FBDC2_AXI_MAX_OUTSTANDING_NUM(x) VAL_MASK(x, 5, 4) +#define V_VOP_FBDC2_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 9) +#define V_FBDC2_RID(x) VAL_MASK(x, 4, 12) +#define V_AFBCD2_HREG_PIXEL_PACKING_FMT(x) VAL_MASK(x, 5, 16) +#define V_AFBCD2_HREG_BLOCK_SPLIT(x) VAL_MASK(x, 1, 21) +#define AFBCD2_HDR_PTR 0x00000244 +#define V_AFBCD2_HREG_HDR_PTR(x) VAL_MASK(x, 32, 0) +#define AFBCD2_PIC_SIZE 0x00000248 +#define V_AFBCD2_HREG_PIC_WIDTH(x) VAL_MASK(x, 16, 0) +#define V_AFBCD2_HREG_PIC_HEIGHT(x) VAL_MASK(x, 16, 16) +#define AFBCD2_STATUS 0x0000024c +#define V_AFBCD2_HREG_IDLE_N(x) VAL_MASK(x, 1, 0) +#define V_AFBCD2_HREG_DEC_RESP(x) VAL_MASK(x, 1, 1) +#define V_AFBCD2_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 2) +#define AFBCD3_CTRL 0x00000260 +#define V_VOP_FBDC3_EN(x) VAL_MASK(x, 1, 0) +#define V_VOP_FBDC3_WIN_SEL(x) VAL_MASK(x, 1, 1) +#define V_FBDC3_RSTN(x) VAL_MASK(x, 1, 2) +#define V_VOP_FBDC3_AXI_MAX_OUTSTANDING_NUM(x) VAL_MASK(x, 5, 3) +#define V_VOP_FBDC3_AXI_MAX_OUTSTANDING_EN(x) VAL_MASK(x, 1, 8) +#define V_FBDC3_RID(x) VAL_MASK(x, 4, 12) +#define V_AFBCD3_HREG_PIXEL_PACKING_FMT(x) VAL_MASK(x, 5, 16) +#define V_AFBCD3_HREG_BLOCK_SPLIT(x) VAL_MASK(x, 1, 21) +#define AFBCD3_HDR_PTR 0x00000264 +#define V_AFBCD3_HREG_HDR_PTR(x) VAL_MASK(x, 32, 0) +#define AFBCD3_PIC_SIZE 0x00000268 +#define V_AFBCD3_HREG_PIC_WIDTH(x) VAL_MASK(x, 16, 0) +#define V_AFBCD3_HREG_PIC_HEIGHT(x) VAL_MASK(x, 16, 16) +#define AFBCD3_STATUS 0x0000026c +#define V_AFBCD3_HREG_IDLE_N(x) VAL_MASK(x, 1, 0) +#define V_AFBCD3_HREG_DEC_RESP(x) VAL_MASK(x, 1, 1) +#define V_AFBCD3_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 2) +#define INTR_EN0 0x00000280 +#define V_INTR_EN_FS(x) VAL_MASK(x, 1, 0) +#define V_INTR_EN_FS_NEW(x) VAL_MASK(x, 1, 1) +#define V_INTR_EN_ADDR_SAME(x) VAL_MASK(x, 1, 2) +#define V_INTR_EN_LINE_FLAG0(x) VAL_MASK(x, 1, 3) +#define V_INTR_EN_LINE_FLAG1(x) VAL_MASK(x, 1, 4) +#define V_INTR_EN_BUS_ERROR(x) VAL_MASK(x, 1, 5) +#define V_INTR_EN_WIN0_EMPTY(x) VAL_MASK(x, 1, 6) +#define V_INTR_EN_WIN1_EMPTY(x) VAL_MASK(x, 1, 7) +#define V_INTR_EN_WIN2_EMPTY(x) VAL_MASK(x, 1, 8) +#define V_INTR_EN_WIN3_EMPTY(x) VAL_MASK(x, 1, 9) +#define V_INTR_EN_HWC_EMPTY(x) VAL_MASK(x, 1, 10) +#define V_INTR_EN_POST_BUF_EMPTY(x) VAL_MASK(x, 1, 11) +#define V_INTR_EN_PWM_GEN(x) VAL_MASK(x, 1, 12) +#define V_INTR_EN_DSP_HOLD_VALID(x) VAL_MASK(x, 1, 13) +#define V_INTR_EN_MMU(x) VAL_MASK(x, 1, 14) +#define V_INTR_EN_DMA_FINISH(x) VAL_MASK(x, 1, 15) +#define V_WRITE_MASK(x) VAL_MASK(x, 16, 16) +#define INTR_CLEAR0 0x00000284 +#define V_INT_CLR_FS(x) VAL_MASK(x, 1, 0) +#define V_INT_CLR_FS_NEW(x) VAL_MASK(x, 1, 1) +#define V_INT_CLR_ADDR_SAME(x) VAL_MASK(x, 1, 2) +#define V_INT_CLR_LINE_FLAG0(x) VAL_MASK(x, 1, 3) +#define V_INT_CLR_LINE_FLAG1(x) VAL_MASK(x, 1, 4) +#define V_INT_CLR_BUS_ERROR(x) VAL_MASK(x, 1, 5) +#define V_INT_CLR_WIN0_EMPTY(x) VAL_MASK(x, 1, 6) +#define V_INT_CLR_WIN1_EMPTY(x) VAL_MASK(x, 1, 7) +#define V_INT_CLR_WIN2_EMPTY(x) VAL_MASK(x, 1, 8) +#define V_INT_CLR_WIN3_EMPTY(x) VAL_MASK(x, 1, 9) +#define V_INT_CLR_HWC_EMPTY(x) VAL_MASK(x, 1, 10) +#define V_INT_CLR_POST_BUF_EMPTY(x) VAL_MASK(x, 1, 11) +#define V_INT_CLR_PWM_GEN(x) VAL_MASK(x, 1, 12) +#define V_INT_CLR_DSP_HOLD_VALID(x) VAL_MASK(x, 1, 13) +#define V_INT_CLR_MMU(x) VAL_MASK(x, 1, 14) +#define V_INT_CLR_DMA_FINISH(x) VAL_MASK(x, 1, 15) +#define V_WRITE_MASK(x) VAL_MASK(x, 16, 16) +#define INTR_STATUS0 0x00000288 +#define V_INT_STATUS_FS(x) VAL_MASK(x, 1, 0) +#define V_INT_STATUS_FS_NEW(x) VAL_MASK(x, 1, 1) +#define V_INT_STATUS_ADDR_SAME(x) VAL_MASK(x, 1, 2) +#define V_INT_STATUS_LINE_FLAG0(x) VAL_MASK(x, 1, 3) +#define V_INT_STATUS_LINE_FLAG1(x) VAL_MASK(x, 1, 4) +#define V_INT_STATUS_BUS_ERROR(x) VAL_MASK(x, 1, 5) +#define V_INT_STATUS_WIN0_EMPTY(x) VAL_MASK(x, 1, 6) +#define V_INT_STATUS_WIN1_EMPTY(x) VAL_MASK(x, 1, 7) +#define V_INT_STATUS_WIN2_EMPTY(x) VAL_MASK(x, 1, 8) +#define V_INT_STATUS_WIN3_EMPTY(x) VAL_MASK(x, 1, 9) +#define V_INT_STATUS_HWC_EMPTY(x) VAL_MASK(x, 1, 10) +#define V_INT_STATUS_POST_BUF_EMPTY(x) VAL_MASK(x, 1, 11) +#define V_INT_STATUS_PWM_GEN(x) VAL_MASK(x, 1, 12) +#define V_INT_STATUS_DSP_HOLD_VALID(x) VAL_MASK(x, 1, 13) +#define V_INT_STATUS_MMU(x) VAL_MASK(x, 1, 14) +#define V_INT_STATUS_DMA_FINISH(x) VAL_MASK(x, 1, 15) +#define INTR_RAW_STATUS0 0x0000028c +#define V_INT_RAW_STATUS_FS(x) VAL_MASK(x, 1, 0) +#define V_INT_RAW_STATUS_FS_NEW(x) VAL_MASK(x, 1, 1) +#define V_INT_RAW_STATUS_ADDR_SAME(x) VAL_MASK(x, 1, 2) +#define V_INT_RAW_STATUS_LINE_FRAG0(x) VAL_MASK(x, 1, 3) +#define V_INT_RAW_STATUS_LINE_FRAG1(x) VAL_MASK(x, 1, 4) +#define V_INT_RAW_STATUS_BUS_ERROR(x) VAL_MASK(x, 1, 5) +#define V_INT_RAW_STATUS_WIN0_EMPTY(x) VAL_MASK(x, 1, 6) +#define V_INT_RAW_STATUS_WIN1_EMPTY(x) VAL_MASK(x, 1, 7) +#define V_INT_RAW_STATUS_WIN2_EMPTY(x) VAL_MASK(x, 1, 8) +#define V_INT_RAW_STATUS_WIN3_EMPTY(x) VAL_MASK(x, 1, 9) +#define V_INT_RAW_STATUS_HWC_EMPTY(x) VAL_MASK(x, 1, 10) +#define V_INT_RAW_STATUS_POST_BUF_EMPTY(x) VAL_MASK(x, 1, 11) +#define V_INT_RAW_STATUS_PWM_GEN(x) VAL_MASK(x, 1, 12) +#define V_INT_RAW_STATUS_DSP_HOLD_VALID(x) VAL_MASK(x, 1, 13) +#define V_INT_RAW_STATUS_MMU(x) VAL_MASK(x, 1, 14) +#define V_INT_RAW_STATUS_DMA_FINISH(x) VAL_MASK(x, 1, 15) +#define INTR_EN1 0x00000290 +#define V_INT_EN_FBCD0(x) VAL_MASK(x, 1, 0) +#define V_INT_EN_FBCD1(x) VAL_MASK(x, 1, 1) +#define V_INT_EN_FBCD2(x) VAL_MASK(x, 1, 2) +#define V_INT_EN_FBCD3(x) VAL_MASK(x, 1, 3) +#define V_INT_EN_AFBCD0_HREG_DEC_RESP(x) VAL_MASK(x, 1, 4) +#define V_INT_EN_AFBCD0_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 5) +#define V_INT_EN_AFBCD1_HREG_DEC_RESP(x) VAL_MASK(x, 1, 6) +#define V_INT_EN_AFBCD1_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 7) +#define V_INT_EN_AFBCD2_HREG_DEC_RESP(x) VAL_MASK(x, 1, 8) +#define V_INT_EN_AFBCD2_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 9) +#define V_INT_EN_AFBCD3_HREG_DEC_RESP(x) VAL_MASK(x, 1, 10) +#define V_INT_EN_AFBCD3_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 11) +#define V_INT_EN_WB_YRGB_FIFO_FULL(x) VAL_MASK(x, 1, 12) +#define V_INT_EN_WB_UV_FIFO_FULL(x) VAL_MASK(x, 1, 13) +#define V_INT_EN_WB_FINISH(x) VAL_MASK(x, 1, 14) +#define V_INT_EN_VFP(x) VAL_MASK(x, 1, 15) +#define V_WRITE_MASK(x) VAL_MASK(x, 16, 16) +#define INTR_CLEAR1 0x00000294 +#define V_INT_CLR_FBCD0(x) VAL_MASK(x, 1, 0) +#define V_INT_CLR_FBCD1(x) VAL_MASK(x, 1, 1) +#define V_INT_CLR_FBCD2(x) VAL_MASK(x, 1, 2) +#define V_INT_CLR_FBCD3(x) VAL_MASK(x, 1, 3) +#define V_INT_CLR_AFBCD0_HREG_DEC_RESP(x) VAL_MASK(x, 1, 4) +#define V_INT_CLR_AFBCD0_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 5) +#define V_INT_CLR_AFBCD1_HREG_DEC_RESP(x) VAL_MASK(x, 1, 6) +#define V_INT_CLR_AFBCD1_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 7) +#define V_INT_CLR_AFBCD2_HREG_DEC_RESP(x) VAL_MASK(x, 1, 8) +#define V_INT_CLR_AFBCD2_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 9) +#define V_INT_CLR_AFBCD3_HREG_DEC_RESP(x) VAL_MASK(x, 1, 10) +#define V_INT_CLR_AFBCD3_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 11) +#define V_INT_CLR_VFP(x) VAL_MASK(x, 1, 15) +#define INTR_STATUS1 0x00000298 +#define V_INT_STATUS_FBCD0(x) VAL_MASK(x, 1, 0) +#define V_INT_STATUS_FBCD1(x) VAL_MASK(x, 1, 1) +#define V_INT_STATUS_FBCD2(x) VAL_MASK(x, 1, 2) +#define V_INT_STATUS_FBCD3(x) VAL_MASK(x, 1, 3) +#define V_INT_STATUS_AFBCD0_HREG_DEC_RESP(x) VAL_MASK(x, 1, 4) +#define V_INT_STATUS_AFBCD0_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 5) +#define V_INT_STATUS_AFBCD1_HREG_DEC_RESP(x) VAL_MASK(x, 1, 6) +#define V_INT_STATUS_AFBCD1_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 7) +#define V_INT_STATUS_AFBCD2_HREG_DEC_RESP(x) VAL_MASK(x, 1, 8) +#define V_INT_STATUS_AFBCD2_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 9) +#define V_INT_STATUS_AFBCD3_HREG_DEC_RESP(x) VAL_MASK(x, 1, 10) +#define V_INT_STATUS_AFBCD4_HREG_DEC_RESP(x) VAL_MASK(x, 1, 11) +#define V_INT_STATUS_VFP(x) VAL_MASK(x, 1, 15) +#define INTR_RAW_STATUS1 0x0000029c +#define V_INT_RAW_STATUS_FBCD0(x) VAL_MASK(x, 1, 0) +#define V_INT_RAW_STATUS_FBCD1(x) VAL_MASK(x, 1, 1) +#define V_INT_RAW_STATUS_FBCD2(x) VAL_MASK(x, 1, 2) +#define V_INT_RAW_STATUS_FBCD3(x) VAL_MASK(x, 1, 3) +#define V_INT_RAW_STATUS_AFBCD0_HREG_DEC_RESP(x) VAL_MASK(x, 1, 4) +#define V_INT_RAW_STATUS_AFBCD0_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 5) +#define V_INT_RAW_STATUS_AFBCD1_HREG_DEC_RESP(x) VAL_MASK(x, 1, 6) +#define V_INT_RAW_STATUS_AFBCD1_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 7) +#define V_INT_RAW_STATUS_AFBCD2_HREG_DEC_RESP(x) VAL_MASK(x, 1, 8) +#define V_INT_RAW_STATUS_AFBCD2_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 9) +#define V_INT_RAW_STATUS_AFBCD3_HREG_DEC_RESP(x) VAL_MASK(x, 1, 10) +#define V_INT_RAW_STATUS_AFBCD3_HREG_AXI_RRESP(x) VAL_MASK(x, 1, 11) +#define V_INT_RAW_STATUS_VFP(x) VAL_MASK(x, 1, 15) +#define LINE_FLAG 0x000002a0 +#define V_DSP_LINE_FLAG_NUM_0(x) VAL_MASK(x, 13, 0) +#define V_DSP_LINE_FLAG_NUM_1(x) VAL_MASK(x, 13, 16) +#define VOP_STATUS 0x000002a4 +#define V_DSP_VCNT(x) VAL_MASK(x, 13, 0) +#define V_MMU_IDLE(x) VAL_MASK(x, 1, 16) +#define V_DMA_STOP_VALID(x) VAL_MASK(x, 1, 17) +#define BLANKING_VALUE 0x000002a8 +#define V_BLANKING_VALUE(x) VAL_MASK(x, 24, 0) +#define V_BLANKING_VALUE_CONFIG_EN(x) VAL_MASK(x, 1, 24) +#define MCU_BYPASS_PORT 0x000002ac +#define WIN0_DSP_BG 0x000002b0 +#define V_WIN0_DSP_BG_BLUE(x) VAL_MASK(x, 8, 0) +#define V_WIN0_DSP_BG_GREEN(x) VAL_MASK(x, 8, 8) +#define V_WIN0_DSP_BG_RED(x) VAL_MASK(x, 8, 16) +#define V_WIN0_BG_EN(x) VAL_MASK(x, 1, 31) +#define WIN1_DSP_BG 0x000002b4 +#define V_WIN1_DSP_BG_BLUE(x) VAL_MASK(x, 8, 0) +#define V_WIN1_DSP_BG_GREEN(x) VAL_MASK(x, 8, 8) +#define V_WIN1_DSP_BG_RED(x) VAL_MASK(x, 8, 16) +#define V_WIN1_BG_EN(x) VAL_MASK(x, 1, 31) +#define WIN2_DSP_BG 0x000002b8 +#define V_WIN2_DSP_BG_BLUE(x) VAL_MASK(x, 8, 0) +#define V_WIN2_DSP_BG_GREEN(x) VAL_MASK(x, 8, 8) +#define V_WIN2_DSP_BG_RED(x) VAL_MASK(x, 8, 16) +#define V_WIN2_BG_EN(x) VAL_MASK(x, 1, 31) +#define WIN3_DSP_BG 0x000002bc +#define V_WIN3_DSP_BG_BLUE(x) VAL_MASK(x, 8, 0) +#define V_WIN3_DSP_BG_GREEN(x) VAL_MASK(x, 8, 8) +#define V_WIN3_DSP_BG_RED(x) VAL_MASK(x, 8, 16) +#define V_WIN3_BG_EN(x) VAL_MASK(x, 1, 31) +#define YUV2YUV_WIN 0x000002c0 +#define V_WIN0_YUV2YUV_EN(x) VAL_MASK(x, 1, 0) +#define V_WIN0_YUV2YUV_Y2R_EN(x) VAL_MASK(x, 1, 1) +#define V_WIN0_YUV2YUV_R2Y_EN(x) VAL_MASK(x, 1, 2) +#define V_WIN0_YUV2YUV_GAMMA_MODE(x) VAL_MASK(x, 1, 3) +#define V_WIN0_YUV2YUV_Y2R_MODE(x) VAL_MASK(x, 2, 4) +#define V_WIN0_YUV2YUV_R2Y_MODE(x) VAL_MASK(x, 2, 6) +#define V_WIN1_YUV2YUV_EN(x) VAL_MASK(x, 1, 8) +#define V_WIN1_YUV2YUV_Y2R_EN(x) VAL_MASK(x, 1, 9) +#define V_WIN1_YUV2YUV_R2Y_EN(x) VAL_MASK(x, 1, 10) +#define V_WIN1_YUV2YUV_GAMMA_MODE(x) VAL_MASK(x, 1, 11) +#define V_WIN1_YUV2YUV_Y2R_MODE(x) VAL_MASK(x, 2, 12) +#define V_WIN1_YUV2YUV_R2Y_MODE(x) VAL_MASK(x, 2, 14) +#define V_WIN2_YUV2YUV_EN(x) VAL_MASK(x, 1, 16) +#define V_WIN2_YUV2YUV_R2Y_EN(x) VAL_MASK(x, 1, 18) +#define V_WIN2_YUV2YUV_GAMMA_MODE(x) VAL_MASK(x, 1, 19) +#define V_WIN2_YUV2YUV_R2Y_MODE(x) VAL_MASK(x, 2, 22) +#define V_WIN3_YUV2YUV_EN(x) VAL_MASK(x, 1, 24) +#define V_WIN3_YUV2YUV_R2Y_EN(x) VAL_MASK(x, 1, 26) +#define V_WIN3_YUV2YUV_GAMMA_MODE(x) VAL_MASK(x, 1, 27) +#define V_WIN3_YUV2YUV_R2Y_MODE(x) VAL_MASK(x, 2, 30) +#define YUV2YUV_POST 0x000002c4 +#define V_YUV2YUV_POST_EN(x) VAL_MASK(x, 1, 0) +#define V_YUV2YUV_POST_Y2R_EN(x) VAL_MASK(x, 1, 1) +#define V_YUV2YUV_POST_R2Y_EN(x) VAL_MASK(x, 1, 2) +#define V_YUV2YUV_GAMMA_MODE(x) VAL_MASK(x, 1, 3) +#define V_YUV2YUV_POST_Y2R_MODE(x) VAL_MASK(x, 2, 4) +#define V_YUV2YUV_POST_R2Y_MODE(x) VAL_MASK(x, 2, 6) +#define AUTO_GATING_EN 0x000002cc +#define V_WIN0_ACLK_GATING_EN(x) VAL_MASK(x, 1, 0) +#define V_WIN1_ACLK_GATING_EN(x) VAL_MASK(x, 1, 1) +#define V_WIN2_ACLK_GATING_EN(x) VAL_MASK(x, 1, 2) +#define V_WIN3_ACLK_GATING_EN(x) VAL_MASK(x, 1, 3) +#define V_HWC_ACLK_GATING_EN(x) VAL_MASK(x, 1, 4) +#define V_OVERLAY_ACLK_GATING_EN(x) VAL_MASK(x, 1, 5) +#define V_GAMMA_ACLK_GATING_EN(x) VAL_MASK(x, 1, 6) +#define V_CABC_ACLK_GATING_EN(x) VAL_MASK(x, 1, 7) +#define V_WB_ACLK_GATING_EN(x) VAL_MASK(x, 1, 8) +#define V_PWM_PWMCLK_GATING_EN(x) VAL_MASK(x, 1, 9) +#define V_DIRECT_PATH_ACLK_GATING_EN(x) VAL_MASK(x, 1, 10) +#define V_FBCD0_ACLK_GATING_EN(x) VAL_MASK(x, 1, 12) +#define V_FBCD1_ACLK_GATING_EN(x) VAL_MASK(x, 1, 13) +#define V_FBCD2_ACLK_GATING_EN(x) VAL_MASK(x, 1, 14) +#define V_FBCD3_ACLK_GATING_EN(x) VAL_MASK(x, 1, 15) +#define DBG_PERF_LATENCY_CTRL0 0x00000300 +#define V_RD_LATENCY_EN(x) VAL_MASK(x, 1, 0) +#define V_HAND_LATENCY_CLR(x) VAL_MASK(x, 1, 1) +#define V_RD_LATENCY_MODE(x) VAL_MASK(x, 1, 2) +#define V_RD_LATENCY_ID0(x) VAL_MASK(x, 4, 4) +#define V_RD_LATENCY_THR(x) VAL_MASK(x, 12, 8) +#define V_RD_LATENCY_ST_NUM(x) VAL_MASK(x, 5, 20) +#define DBG_PERF_RD_MAX_LATENCY_NUM0 0x00000304 +#define V_RD_MAX_LATENCY_NUM_CH0(x) VAL_MASK(x, 12, 0) +#define V_RD_LATENCY_OVERFLOW_CH0(x) VAL_MASK(x, 1, 16) +#define DBG_PERF_RD_LATENCY_THR_NUM0 0x00000308 +#define V_RD_LATENCY_THR_NUM_CH0(x) VAL_MASK(x, 24, 0) +#define DBG_PERF_RD_LATENCY_SAMP_NUM0 0x0000030c +#define V_RD_LATENCY_SAMP_NUM_CH0(x) VAL_MASK(x, 24, 0) +#define DBG_CABC0 0x00000310 +#define DBG_CABC1 0x00000314 +#define DBG_CABC2 0x00000318 +#define V_PWM_MUL_POST_VALUE(x) VAL_MASK(x, 8, 8) +#define DBG_CABC3 0x0000031c +#define DBG_WIN0_REG0 0x00000320 +#define DBG_WIN0_REG1 0x00000324 +#define DBG_WIN0_REG2 0x00000328 +#define V_DBG_WIN0_YRGB_CMD_LINE_CNT(x) VAL_MASK(x, 13, 16) +#define DBG_WIN0_RESERVED 0x0000032c +#define DBG_WIN1_REG0 0x00000330 +#define DBG_WIN1_REG1 0x00000334 +#define DBG_WIN1_REG2 0x00000338 +#define DBG_WIN1_RESERVED 0x0000033c +#define DBG_WIN2_REG0 0x00000340 +#define DBG_WIN2_REG1 0x00000344 +#define DBG_WIN2_REG2 0x00000348 +#define DBG_WIN2_REG3 0x0000034c +#define DBG_WIN3_REG0 0x00000350 +#define DBG_WIN3_REG1 0x00000354 +#define DBG_WIN3_REG2 0x00000358 +#define DBG_WIN3_REG3 0x0000035c +#define DBG_PRE_REG0 0x00000360 +#define DBG_PRE_RESERVED 0x00000364 +#define DBG_POST_REG0 0x00000368 +#define DBG_POST_REG1 0x0000036c +#define V_GAMMA_A2HCLK_CHANGE_DONE(x) VAL_MASK(x, 1, 0) +#define V_WHICH_GAMMA_LUT_WORKING(x) VAL_MASK(x, 1, 1) +#define DBG_DATAO 0x00000370 +#define V_SW_DATAO_SEL(x) VAL_MASK(x, 2, 30) +#define DBG_DATAO_2 0x00000374 +#define V_VOP_DATA_O_2(x) VAL_MASK(x, 30, 0) +#define V_SW_DATAO_SEL_2(x) VAL_MASK(x, 2, 30) +#define WIN0_CSC_COE 0x000003a0 +#define WIN1_CSC_COE 0x000003c0 +#define WIN2_CSC_COE 0x000003e0 +#define WIN3_CSC_COE 0x00000400 +#define HWC_CSC_COE 0x00000420 +#define BCSH_R2Y_CSC_COE 0x00000440 +#define BCSH_Y2R_CSC_COE 0x00000460 +#define POST_YUV2YUV_Y2R_COE 0x00000480 +#define POST_YUV2YUV_3x3_COE 0x000004a0 +#define POST_YUV2YUV_R2Y_COE 0x000004c0 +#define WIN2_LUT_ADDR 0x00001000 +#define V_WIN2_LUT_ADDR(x) VAL_MASK(x, 32, 0) +#define WIN3_LUT_ADDR 0x00001400 +#define V_WIN3_LUT_ADDR(x) VAL_MASK(x, 32, 0) +#define HWC_LUT_ADDR 0x00001800 +#define V_HWC_LUT_ADDR(x) VAL_MASK(x, 32, 0) +#define CABC_GAMMA_LUT_ADDR 0x00001c00 +#define V_GAMMA_LUT_ADDR(x) VAL_MASK(x, 32, 0) +#define GAMMA_LUT_ADDR 0x00002000 +#define V_GAMMA_LUT_ADDR(x) VAL_MASK(x, 32, 0) +#define TVE 0x00003e00 + +#define INTR_FS (1 << 0) +#define INTR_FS_NEW (1 << 1) +#define INTR_ADDR_SAME (1 << 2) +#define INTR_LINE_FLAG0 (1 << 3) +#define INTR_LINE_FLAG1 (1 << 4) +#define INTR_BUS_ERROR (1 << 5) +#define INTR_WIN0_EMPTY (1 << 6) +#define INTR_WIN1_EMPTY (1 << 7) +#define INTR_WIN2_EMPTY (1 << 8) +#define INTR_WIN3_EMPTY (1 << 9) +#define INTR_HWC_EMPTY (1 << 10) +#define INTR_POST_BUF_EMPTY (1 << 11) +#define INTR_PWM_GEN (1 << 12) +#define INTR_DSP_HOLD_VALID (1 << 13) +#define INTR_MMU (1 << 14) +#define INTR_DMA_FINISH (1 << 15) + +#define INTR_MASK (INTR_FS | INTR_FS_NEW | INTR_ADDR_SAME | INTR_LINE_FLAG0 | \ + INTR_LINE_FLAG1 | INTR_BUS_ERROR | INTR_WIN0_EMPTY | \ + INTR_WIN1_EMPTY | INTR_WIN2_EMPTY | INTR_WIN3_EMPTY | \ + INTR_HWC_EMPTY | INTR_POST_BUF_EMPTY | INTR_PWM_GEN | \ + INTR_DSP_HOLD_VALID | INTR_MMU | INTR_DMA_FINISH) + +#define INTR1_FBCD0 (1 << 0) +#define INTR1_FBCD1 (1 << 1) +#define INTR1_FBCD2 (1 << 2) +#define INTR1_FBCD3 (1 << 3) +#define INTR1_AFBCD0_HREG_DEC_RESP (1 << 4) +#define INTR1_AFBCD0_HREG_AXI_RRESP (1 << 5) +#define INTR1_AFBCD1_HREG_DEC_RESP (1 << 6) +#define INTR1_AFBCD1_HREG_AXI_RRESP (1 << 7) +#define INTR1_AFBCD2_HREG_DEC_RESP (1 << 8) +#define INTR1_AFBCD2_HREG_AXI_RRESP (1 << 9) +#define INTR1_AFBCD3_HREG_DEC_RESP (1 << 10) +#define INTR1_AFBCD3_HREG_AXI_RRESP (1 << 11) +#define INTR1_WB_YRGB_FIFO_FULL (1 << 12) +#define INTR1_WB_UV_FIFO_FULL (1 << 13) +#define INTR1_WB_FINISH (1 << 14) + +#define OUT_CCIR656_MODE_0 5 +#define OUT_CCIR656_MODE_1 6 +#define OUT_CCIR656_MODE_2 7 + +struct vop_device { + int id; + struct rk_lcdc_driver driver; + struct device *dev; + struct rk_screen *screen; + + void __iomem *regs; + void *regsbak; + u32 reg_phy_base; + u32 len; + + /* one time only one process allowed to config the register */ + spinlock_t reg_lock; + + 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 *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; + + /* lock vop irq reg */ + spinlock_t irq_lock; +}; + +static inline void vop_writel(struct vop_device *vop_dev, u32 offset, u32 v) +{ + u32 *_pv = (u32 *)vop_dev->regsbak; + + _pv += (offset >> 2); + *_pv = v; + writel_relaxed(v, vop_dev->regs + offset); +} + +static inline u32 vop_readl(struct vop_device *vop_dev, u32 offset) +{ + u32 v; + + v = readl_relaxed(vop_dev->regs + offset); + return v; +} + +static inline u32 vop_readl_backup(struct vop_device *vop_dev, u32 offset) +{ + u32 v; + u32 *_pv = (u32 *)vop_dev->regsbak; + + _pv += (offset >> 2); + v = readl_relaxed(vop_dev->regs + offset); + *_pv = v; + return v; +} + +static inline u32 vop_read_bit(struct vop_device *vop_dev, u32 offset, u64 v) +{ + u32 _v = readl_relaxed(vop_dev->regs + offset); + + _v &= v >> 32; + v = (_v ? 1 : 0); + return v; +} + +static inline void vop_set_bit(struct vop_device *vop_dev, u32 offset, u64 v) +{ + u32 *_pv = (u32 *)vop_dev->regsbak; + + _pv += (offset >> 2); + (*_pv) |= v >> 32; + writel_relaxed(*_pv, vop_dev->regs + offset); +} + +static inline void vop_clr_bit(struct vop_device *vop_dev, u32 offset, u64 v) +{ + u32 *_pv = (u32 *)vop_dev->regsbak; + + _pv += (offset >> 2); + (*_pv) &= (~(v >> 32)); + writel_relaxed(*_pv, vop_dev->regs + offset); +} + +static inline void vop_msk_reg(struct vop_device *vop_dev, u32 offset, u64 v) +{ + u32 *_pv = (u32 *)vop_dev->regsbak; + + _pv += (offset >> 2); + (*_pv) &= (~(v >> 32)); + (*_pv) |= (u32)v; + writel_relaxed(*_pv, vop_dev->regs + offset); +} + +static inline void vop_mask_writel(struct vop_device *vop_dev, u32 offset, + u32 mask, u32 v) +{ + v = mask << 16 | v; + writel_relaxed(v , vop_dev->regs + offset); +} + +static inline void vop_cfg_done(struct vop_device *vop_dev) +{ + writel_relaxed(0x001f001f, vop_dev->regs + REG_CFG_DONE); + dsb(sy); +} + +static inline int vop_grf_writel(struct regmap *base, u32 offset, u32 val) +{ + regmap_write(base, offset, val); + dsb(sy); + + return 0; +} + +static inline int vop_cru_writel(struct regmap *base, u32 offset, u32 val) +{ + regmap_write(base, offset, val); + dsb(sy); + + return 0; +} + +static inline int vop_cru_readl(struct regmap *base, u32 offset) +{ + u32 v; + + regmap_read(base, offset, &v); + + return v; +} + +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 +}; + +#define IS_YUV(x) ((x) >= VOP_FORMAT_YCBCR420) + +enum _vop_overlay_mode { + VOP_RGB_DOMAIN, + VOP_YUV_DOMAIN +}; + +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; +}; + +#define CUBIC_PRECISE 0 +#define CUBIC_SPLINE 1 +#define CUBIC_CATROM 2 +#define CUBIC_MITCHELL 3 + +#define FBDC_FMT_RGB565 0x5 +#define FBDC_FMT_U8U8U8U8 0xc /*ARGB888*/ +#define FBDC_FMT_U8U8U8 0x3a /*RGBP888*/ + +#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 +#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 +/*****************************************************************/ + +/*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))) + +static inline u32 vop_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; +} + +#endif