From 5f159debc66288b552095acce08c2097db23b052 Mon Sep 17 00:00:00 2001 From: zwl Date: Mon, 25 Aug 2014 22:45:32 +0800 Subject: [PATCH] 1.rockchip:screen: add color-mode node in screen timing and add prop at lcd-xxx.dtsi 2.rk312x:lcdc: modify set overlay mode according to the screen color-mode --- arch/arm/boot/dts/lcd-b101ew05.dtsi | 1 + arch/arm/boot/dts/lcd-box.dtsi | 3 ++ drivers/video/of_display_timing.c | 2 ++ drivers/video/rockchip/hdmi/rk_hdmi_lcdc.c | 3 +- drivers/video/rockchip/lcdc/rk312x_lcdc.c | 38 +++++++++++++++------- drivers/video/rockchip/rk_fb.c | 1 + include/dt-bindings/rkfb/rk_fb.h | 3 ++ include/linux/rk_fb.h | 7 +--- include/linux/rk_screen.h | 1 + include/video/display_timing.h | 1 + 10 files changed, 41 insertions(+), 19 deletions(-) diff --git a/arch/arm/boot/dts/lcd-b101ew05.dtsi b/arch/arm/boot/dts/lcd-b101ew05.dtsi index 2d79841e5abd..00cbce6a763d 100644 --- a/arch/arm/boot/dts/lcd-b101ew05.dtsi +++ b/arch/arm/boot/dts/lcd-b101ew05.dtsi @@ -11,6 +11,7 @@ screen-type = ; lvds-format = ; out-face = ; + color-mode = ; clock-frequency = <71000000>; hactive = <1280>; vactive = <800>; diff --git a/arch/arm/boot/dts/lcd-box.dtsi b/arch/arm/boot/dts/lcd-box.dtsi index d5822467d0c9..4907735e621d 100755 --- a/arch/arm/boot/dts/lcd-box.dtsi +++ b/arch/arm/boot/dts/lcd-box.dtsi @@ -36,6 +36,7 @@ timing0: timing0 { screen-type = ; out-face = ; + color-mode = ; clock-frequency = <74250000>; hactive = <1280>; vactive = <720>; @@ -56,6 +57,7 @@ timing1: timing1 { screen-type = ; out-face = ; + color-mode = ; clock-frequency = <148500000>; hactive = <1920>; vactive = <1080>; @@ -76,6 +78,7 @@ timing2: timing2 { screen-type = ; out-face = ; + color-mode = ; clock-frequency = <297000000>; hactive = <3840>; vactive = <2160>; diff --git a/drivers/video/of_display_timing.c b/drivers/video/of_display_timing.c index 1e7ea6318cb8..bcc28c6a6099 100644 --- a/drivers/video/of_display_timing.c +++ b/drivers/video/of_display_timing.c @@ -111,6 +111,8 @@ static struct display_timing *of_get_display_timing(struct device_node *np) dt->lvds_format = val; if (!of_property_read_u32(np, "out-face", &val)) dt->face = val; + if (!of_property_read_u32(np, "color-mode", &val)) + dt->color_mode = val; #endif if (ret) { diff --git a/drivers/video/rockchip/hdmi/rk_hdmi_lcdc.c b/drivers/video/rockchip/hdmi/rk_hdmi_lcdc.c index 16d5dce051e3..f41a73a19fab 100755 --- a/drivers/video/rockchip/hdmi/rk_hdmi_lcdc.c +++ b/drivers/video/rockchip/hdmi/rk_hdmi_lcdc.c @@ -106,6 +106,7 @@ int hdmi_set_info(struct rk_screen *screen, unsigned int vic) /* screen type & face */ screen->type = OUT_TYPE; screen->face = OUT_FACE; + screen->color_mode = COLOR_YCBCR; /* Screen size */ screen->mode.xres = hdmi_mode[i].xres; @@ -582,7 +583,7 @@ int hdmi_init_video_para(struct hdmi *hdmi_drv, struct hdmi_video_para *video) video->vic = hdmi_drv->vic; video->input_mode = VIDEO_INPUT_RGB_YCBCR_444; - if (lcdc_drv->output_domain == OUTPUT_RGB_DOMAIN) + if (lcdc_drv->output_color == COLOR_RGB) video->input_color = VIDEO_INPUT_COLOR_RGB; else video->input_color = VIDEO_INPUT_COLOR_YCBCR444; diff --git a/drivers/video/rockchip/lcdc/rk312x_lcdc.c b/drivers/video/rockchip/lcdc/rk312x_lcdc.c index 4819c9c1d330..136cae945612 100755 --- a/drivers/video/rockchip/lcdc/rk312x_lcdc.c +++ b/drivers/video/rockchip/lcdc/rk312x_lcdc.c @@ -777,6 +777,16 @@ static int rk312x_lcdc_set_scaler(struct rk_lcdc_driver *dev_drv, scl_v_factor = ((src_h - 1) << 12) / (dst_h - 1); spin_lock(&lcdc_dev->reg_lock); + if (dst->color_mode != src->color_mode) { + dev_drv->output_color = dst->color_mode; + if (dev_drv->output_color == COLOR_YCBCR) + dev_drv->overlay_mode = VOP_YUV_DOMAIN; + else + dev_drv->overlay_mode = VOP_RGB_DOMAIN; + lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_SW_OVERLAY_MODE, + v_SW_OVERLAY_MODE(dev_drv->overlay_mode)); + } + lcdc_writel(lcdc_dev, SCALER_FACTOR, v_SCALER_H_FACTOR(scl_h_factor) | v_SCALER_V_FACTOR(scl_v_factor)); @@ -805,6 +815,8 @@ static int rk312x_lcdc_set_scaler(struct rk_lcdc_driver *dev_drv, lcdc_msk_reg(lcdc_dev, SCALER_CTRL, m_SCALER_EN | m_SCALER_OUT_ZERO | m_SCALER_OUT_EN, v_SCALER_EN(1) | v_SCALER_OUT_ZERO(0) | v_SCALER_OUT_EN(1)); + + lcdc_cfg_done(lcdc_dev); spin_unlock(&lcdc_dev->reg_lock); return 0; @@ -826,14 +838,24 @@ static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) spin_lock(&lcdc_dev->reg_lock); if (likely(lcdc_dev->clk_on)) { + /* Select output color domain */ + dev_drv->output_color = screen->color_mode; + if (lcdc_dev->soc_type == VOP_RK312X) { + if (dev_drv->output_color == COLOR_YCBCR) + dev_drv->overlay_mode = VOP_YUV_DOMAIN; + else + dev_drv->overlay_mode = VOP_RGB_DOMAIN; + } else { + dev_drv->output_color = COLOR_RGB; + dev_drv->overlay_mode = VOP_RGB_DOMAIN; + } + switch (screen->type) { case SCREEN_RGB: if (lcdc_dev->soc_type == VOP_RK312X) { 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); - dev_drv->overlay_mode = VOP_RGB_DOMAIN; - dev_drv->output_domain = OUTPUT_RGB_DOMAIN; } break; case SCREEN_LVDS: @@ -841,8 +863,6 @@ 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); - dev_drv->overlay_mode = VOP_RGB_DOMAIN; - dev_drv->output_domain = OUTPUT_RGB_DOMAIN; } break; case SCREEN_MIPI: @@ -850,8 +870,6 @@ 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); - dev_drv->overlay_mode = VOP_RGB_DOMAIN; - dev_drv->output_domain = OUTPUT_RGB_DOMAIN; } break; case SCREEN_HDMI: @@ -866,10 +884,6 @@ 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) { - 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)); @@ -1641,7 +1655,7 @@ static int rk312x_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open) } if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) { - if (dev_drv->output_domain == OUTPUT_YUV_DOMAIN) /* bypass */ + if (dev_drv->output_color == COLOR_YCBCR) /* bypass */ lcdc_msk_reg(lcdc_dev, BCSH_CTRL, m_BCSH_Y2R_EN, v_BCSH_Y2R_EN(0)); else /* YUV2RGB */ @@ -1649,7 +1663,7 @@ static int rk312x_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open) 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 */ + if (dev_drv->output_color == COLOR_RGB) /* bypass */ lcdc_msk_reg(lcdc_dev, BCSH_CTRL, m_BCSH_R2Y_EN, v_BCSH_R2Y_EN(0)); else /* RGB2YUV */ diff --git a/drivers/video/rockchip/rk_fb.c b/drivers/video/rockchip/rk_fb.c index 32d252d1b5b7..bfc6aec5bb9c 100755 --- a/drivers/video/rockchip/rk_fb.c +++ b/drivers/video/rockchip/rk_fb.c @@ -347,6 +347,7 @@ int rk_fb_video_mode_from_timing(const struct display_timing *dt, screen->type = dt->screen_type; screen->lvds_format = dt->lvds_format; screen->face = dt->face; + screen->color_mode = dt->color_mode; if (dt->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE) screen->pin_dclk = 1; diff --git a/include/dt-bindings/rkfb/rk_fb.h b/include/dt-bindings/rkfb/rk_fb.h index 59f23127e91c..4ee91d4bc0d3 100755 --- a/include/dt-bindings/rkfb/rk_fb.h +++ b/include/dt-bindings/rkfb/rk_fb.h @@ -45,6 +45,9 @@ #define ROTATE_180 8 #define ROTATE_270 12 +#define COLOR_RGB 0 +#define COLOR_YCBCR 1 + /* lvds connect config * * LVDS_8BIT_1 LVDS_8BIT_2 LVDS_8BIT_3 LVDS_6BIT diff --git a/include/linux/rk_fb.h b/include/linux/rk_fb.h index 3d605afe20da..44b581dbca1e 100755 --- a/include/linux/rk_fb.h +++ b/include/linux/rk_fb.h @@ -232,11 +232,6 @@ enum SCALE_DOWN = 0x2 }; -enum dsp_out_domain { - OUTPUT_RGB_DOMAIN = 0x0, - OUTPUT_YUV_DOMAIN, -}; - typedef enum { BRIGHTNESS = 0x0, CONTRAST = 0x1, @@ -553,7 +548,7 @@ struct rk_lcdc_driver { u16 rotate_mode; u16 cabc_mode; u16 overlay_mode; - u16 output_domain; + u16 output_color; char fb0_win_id; char fb1_win_id; diff --git a/include/linux/rk_screen.h b/include/linux/rk_screen.h index 013ccbb44c9c..681c453f5805 100755 --- a/include/linux/rk_screen.h +++ b/include/linux/rk_screen.h @@ -64,6 +64,7 @@ struct rk_screen { u16 type; u16 lvds_format; u16 face; + u16 color_mode; u8 lcdc_id; u8 screen_id; struct fb_videomode mode; diff --git a/include/video/display_timing.h b/include/video/display_timing.h index bf2bd657e0c4..365067d27cd4 100644 --- a/include/video/display_timing.h +++ b/include/video/display_timing.h @@ -79,6 +79,7 @@ struct display_timing { u16 screen_type; /*screen type*/ u16 lvds_format; /*lvds data format for lvds screen*/ u16 face; /*display output interface format:24bit 18bit 16bit*/ + u16 color_mode; /* input color mode: RGB or YUV */ #endif }; -- 2.34.1