From: zwl Date: Thu, 21 Aug 2014 14:24:09 +0000 (+0800) Subject: rk312x:lcdc: add config output_domain(RGB/YUV) and modify BCSH CSC config X-Git-Tag: firefly_0821_release~4827 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=c0d496b44f569597f15dad60d21350009ea9491f;p=firefly-linux-kernel-4.4.55.git rk312x:lcdc: add config output_domain(RGB/YUV) and modify BCSH CSC config --- diff --git a/drivers/video/rockchip/lcdc/rk312x_lcdc.c b/drivers/video/rockchip/lcdc/rk312x_lcdc.c index f2b8be9e8512..5fa0dfed2bd2 100755 --- a/drivers/video/rockchip/lcdc/rk312x_lcdc.c +++ b/drivers/video/rockchip/lcdc/rk312x_lcdc.c @@ -235,9 +235,10 @@ static int rk312x_lcdc_alpha_cfg(struct lcdc_device *lcdc_dev) static void lcdc_layer_csc_mode(struct lcdc_device *lcdc_dev, struct rk_lcdc_win *win) { - struct rk_screen *screen = lcdc_dev->driver.cur_screen; + struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver; + struct rk_screen *screen = dev_drv->cur_screen; - if (lcdc_dev->overlay_mode == VOP_YUV_DOMAIN) { + if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) { switch (win->fmt_cfg) { case VOP_FORMAT_ARGB888: case VOP_FORMAT_RGB888: @@ -259,7 +260,7 @@ static void lcdc_layer_csc_mode(struct lcdc_device *lcdc_dev, lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN1_CSC_MODE, v_WIN1_CSC_MODE(win->csc_mode)); } - } else if (lcdc_dev->overlay_mode == VOP_RGB_DOMAIN) { + } else if (dev_drv->overlay_mode == VOP_RGB_DOMAIN) { switch (win->fmt_cfg) { case VOP_FORMAT_YCBCR420: if (win->id == 0) { @@ -283,7 +284,7 @@ static void lcdc_layer_update_regs(struct lcdc_device *lcdc_dev, if (win->state == 1) { if (lcdc_dev->soc_type == VOP_RK312X) - lcdc_layer_csc_mode(lcdc_dev,win); + lcdc_layer_csc_mode(lcdc_dev, win); if (win->id == 0) { mask = m_WIN0_EN | m_WIN0_FORMAT | m_WIN0_RB_SWAP; @@ -828,7 +829,8 @@ static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) mask = m_RGB_DCLK_EN | m_RGB_DCLK_INVERT; val = v_RGB_DCLK_EN(1) | v_RGB_DCLK_INVERT(0); lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val); - lcdc_dev->overlay_mode = VOP_RGB_DOMAIN; + dev_drv->overlay_mode = VOP_RGB_DOMAIN; + dev_drv->output_domain = OUTPUT_RGB_DOMAIN; } break; case SCREEN_LVDS: @@ -836,7 +838,8 @@ static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) mask = m_LVDS_DCLK_EN | m_LVDS_DCLK_INVERT; val = v_LVDS_DCLK_EN(1) | v_LVDS_DCLK_INVERT(1); lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val); - lcdc_dev->overlay_mode = VOP_RGB_DOMAIN; + dev_drv->overlay_mode = VOP_RGB_DOMAIN; + dev_drv->output_domain = OUTPUT_RGB_DOMAIN; } break; case SCREEN_MIPI: @@ -844,7 +847,8 @@ static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) mask = m_MIPI_DCLK_EN | m_MIPI_DCLK_INVERT; val = v_MIPI_DCLK_EN(1) | v_MIPI_DCLK_INVERT(0); lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val); - lcdc_dev->overlay_mode = VOP_RGB_DOMAIN; + dev_drv->overlay_mode = VOP_RGB_DOMAIN; + dev_drv->output_domain = OUTPUT_RGB_DOMAIN; } break; case SCREEN_HDMI: @@ -859,7 +863,10 @@ static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) } lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val); if (lcdc_dev->soc_type == VOP_RK312X) { - lcdc_dev->overlay_mode = VOP_YUV_DOMAIN; + if (dev_drv->output_domain == OUTPUT_YUV_DOMAIN) + dev_drv->overlay_mode = VOP_YUV_DOMAIN; + else + dev_drv->overlay_mode = VOP_RGB_DOMAIN; lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_SW_UV_OFFSET_EN, v_SW_UV_OFFSET_EN(0)); @@ -897,7 +904,7 @@ static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) return -1; } if (lcdc_dev->soc_type == VOP_RK312X) { - lcdc_dev->overlay_mode = VOP_YUV_DOMAIN; + dev_drv->overlay_mode = VOP_YUV_DOMAIN; lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_SW_UV_OFFSET_EN, v_SW_UV_OFFSET_EN(1)); @@ -960,7 +967,7 @@ static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) break; } lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_SW_OVERLAY_MODE, - v_SW_OVERLAY_MODE(lcdc_dev->overlay_mode)); + v_SW_OVERLAY_MODE(dev_drv->overlay_mode)); } mask = m_DSP_OUT_FORMAT | m_HSYNC_POL | m_VSYNC_POL | @@ -1637,12 +1644,22 @@ static int rk312x_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open) lcdc_cfg_done(lcdc_dev); } - if (lcdc_dev->overlay_mode == VOP_YUV_DOMAIN) { - lcdc_msk_reg(lcdc_dev, BCSH_CTRL, m_BCSH_R2Y_CSC_MODE, - v_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_BYPASS)); - } else { - lcdc_msk_reg(lcdc_dev, BCSH_CTRL, m_BCSH_R2Y_CSC_MODE, - v_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG)); + if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) { + if (dev_drv->output_domain == OUTPUT_YUV_DOMAIN) /* bypass */ + lcdc_msk_reg(lcdc_dev, BCSH_CTRL, m_BCSH_Y2R_EN, + v_BCSH_Y2R_EN(0)); + else /* YUV2RGB */ + lcdc_msk_reg(lcdc_dev, BCSH_CTRL, + m_BCSH_Y2R_EN | m_BCSH_Y2R_CSC_MODE, + v_BCSH_Y2R_EN(1) | v_BCSH_Y2R_CSC_MODE(VOP_Y2R_CSC_MPEG)); + } else { /* overlay_mode=VOP_RGB_DOMAIN */ + if (dev_drv->output_domain == OUTPUT_RGB_DOMAIN) /* bypass */ + lcdc_msk_reg(lcdc_dev, BCSH_CTRL, m_BCSH_R2Y_EN, + v_BCSH_R2Y_EN(0)); + else /* RGB2YUV */ + lcdc_msk_reg(lcdc_dev, BCSH_CTRL, + m_BCSH_R2Y_EN | m_BCSH_R2Y_CSC_MODE, + v_BCSH_R2Y_EN(1) | v_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG)); } spin_unlock(&lcdc_dev->reg_lock); diff --git a/drivers/video/rockchip/lcdc/rk312x_lcdc.h b/drivers/video/rockchip/lcdc/rk312x_lcdc.h index 92cd5400c1c3..8422303fb2b5 100755 --- a/drivers/video/rockchip/lcdc/rk312x_lcdc.h +++ b/drivers/video/rockchip/lcdc/rk312x_lcdc.h @@ -415,7 +415,7 @@ enum _VOP_SOC_TYPE { #define v_BCSH_EN(x) BITS_MASK(x, 1, 0) #define v_BCSH_R2Y_CSC_MODE(x) BITS_MASK(x, 1, 1) /* rk312x */ #define v_BCSH_OUT_MODE(x) BITS_MASK(x, 3, 2) - #define v_BCSH_CSC_MODE(x) BITS_MASK(x, 3, 4) + #define v_BCSH_Y2R_CSC_MODE(x) BITS_MASK(x, 3, 4) #define v_BCSH_Y2R_EN(x) BITS_MASK(x, 1, 6) /* rk312x */ #define v_BCSH_R2Y_EN(x) BITS_MASK(x, 1, 7) /* rk312x */ @@ -688,7 +688,6 @@ struct lcdc_device { u32 s_pixclock; u32 standby; /* 1:standby,0:work */ - u16 overlay_mode; }; static inline void lcdc_writel(struct lcdc_device *lcdc_dev, u32 offset, u32 v) diff --git a/drivers/video/rockchip/rk_fb.c b/drivers/video/rockchip/rk_fb.c index a2065a9a0792..4aa72e57430d 100755 --- a/drivers/video/rockchip/rk_fb.c +++ b/drivers/video/rockchip/rk_fb.c @@ -3247,8 +3247,12 @@ int rk_fb_switch_screen(struct rk_screen *screen, int enable, int lcdc_id) * switch lcdc screen to primary screen size that may * used for MID, when hdmi remove if disp mode is ONE DUAL */ - if (primary_screen.type != SCREEN_HDMI) + if (primary_screen.type != SCREEN_HDMI) { + dev_drv->output_domain = OUTPUT_RGB_DOMAIN; rk_fb_set_screen_scaler(&primary_screen, 0); + } else { + dev_drv->output_domain = OUTPUT_YUV_DOMAIN; + } } else { dev_drv = rk_get_lcdc_drv(name); if (dev_drv == NULL) { diff --git a/include/linux/rk_fb.h b/include/linux/rk_fb.h index 4388a8646423..b99acfdee3a9 100755 --- a/include/linux/rk_fb.h +++ b/include/linux/rk_fb.h @@ -227,9 +227,14 @@ enum fb_win_map_order { enum { - SCALE_NONE = 0x0, - SCALE_UP = 0x1, - SCALE_DOWN = 0x2 + SCALE_NONE = 0x0, + SCALE_UP = 0x1, + SCALE_DOWN = 0x2 +}; + +enum dsp_out_domain { + OUTPUT_RGB_DOMAIN = 0x0, + OUTPUT_YUV_DOMAIN, }; typedef enum { @@ -547,6 +552,9 @@ struct rk_lcdc_driver { struct rk_screen *cur_screen; //screen0 is primary screen ,like lcd panel,screen1 is extend screen,like hdmi u32 pixclock; u16 rotate_mode; + u16 cabc_mode; + u16 overlay_mode; + u16 output_domain; char fb0_win_id; char fb1_win_id; @@ -571,7 +579,6 @@ struct rk_lcdc_driver { struct sw_sync_timeline *timeline; int timeline_max; int suspend_flag; - int cabc_mode; struct list_head update_regs_list; struct mutex update_regs_list_lock; struct kthread_worker update_regs_worker;