From 8f49e6018ecc92ec1973d4f7dfadcee7b0d8e62e Mon Sep 17 00:00:00 2001 From: Zheng Yang Date: Tue, 27 Jun 2017 16:22:01 +0800 Subject: [PATCH] drm: bridge: dw-hdmi: support dynamically get input/out color info To get input/output bus_format/enc_format dynamically, this patch introduce following funstion in plat_data: - get_input_bus_format - get_output_bus_format - get_enc_in_encoding - get_enc_out_encoding Change-Id: Ic703cba93fad8ceff773e1caca80759f95a9d547 Signed-off-by: Zheng Yang --- drivers/gpu/drm/bridge/dw-hdmi.c | 61 +++++++++++++++++--------------- include/drm/bridge/dw_hdmi.h | 5 +++ 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c index ffc4fdf49005..5014ae7c6d3c 100644 --- a/drivers/gpu/drm/bridge/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/dw-hdmi.c @@ -1589,7 +1589,7 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) u8 val; bool is_hdmi2 = false; - if ((mode->flags & DRM_MODE_FLAG_420_MASK) || + if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format) || hdmi->connector.display_info.hdmi.scdc.supported) is_hdmi2 = true; /* Initialise info frame from DRM mode */ @@ -1760,7 +1760,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, unsigned int hdisplay, vdisplay; vmode->mpixelclock = mode->crtc_clock * 1000; - if (mode->flags & DRM_MODE_FLAG_420_MASK) + if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) vmode->mpixelclock /= 2; if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING) @@ -1814,7 +1814,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, * When we're setting a YCbCr420 mode, we need * to adjust the horizontal timing to suit. */ - if (mode->flags & DRM_MODE_FLAG_420_MASK) { + if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) { hdisplay /= 2; hblank /= 2; h_de_hs /= 2; @@ -1995,6 +1995,7 @@ static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi) static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) { int ret; + void *data = hdmi->plat_data->phy_data; hdmi_disable_overflow_interrupts(hdmi); @@ -2006,10 +2007,13 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic); } - if ((hdmi->vic == 6) || (hdmi->vic == 7) || - (hdmi->vic == 21) || (hdmi->vic == 22) || - (hdmi->vic == 2) || (hdmi->vic == 3) || - (hdmi->vic == 17) || (hdmi->vic == 18)) + if (hdmi->plat_data->get_enc_out_encoding) + hdmi->hdmi_data.enc_out_encoding = + hdmi->plat_data->get_enc_out_encoding(data); + else if ((hdmi->vic == 6) || (hdmi->vic == 7) || + (hdmi->vic == 21) || (hdmi->vic == 22) || + (hdmi->vic == 2) || (hdmi->vic == 3) || + (hdmi->vic == 17) || (hdmi->vic == 18)) hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_601; else hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_709; @@ -2022,31 +2026,30 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0; } - if ((hdmi->dev_type == RK3328_HDMI || - hdmi->dev_type == RK3228_HDMI) && - drm_match_cea_mode(mode) > 94 && - mode->crtc_clock > 340000 && - !(mode->flags & DRM_MODE_FLAG_420_MASK)) - mode->flags |= DRM_MODE_FLAG_420; - - if (mode->flags & DRM_MODE_FLAG_420_MASK) { + /* TOFIX: Get input format from plat data or fallback to RGB888 */ + if (hdmi->plat_data->get_input_bus_format) hdmi->hdmi_data.enc_in_bus_format = - MEDIA_BUS_FMT_UYYVYY8_0_5X24; + hdmi->plat_data->get_input_bus_format(data); + else if (hdmi->plat_data->input_bus_format) + hdmi->hdmi_data.enc_in_bus_format = + hdmi->plat_data->input_bus_format; + else + hdmi->hdmi_data.enc_in_bus_format = + MEDIA_BUS_FMT_RGB888_1X24; + + /* TOFIX: Default to RGB888 output format */ + if (hdmi->plat_data->get_output_bus_format) hdmi->hdmi_data.enc_out_bus_format = - MEDIA_BUS_FMT_UYYVYY8_0_5X24; - } else { - /* TOFIX: Get input format from plat data or fallback to RGB888 */ - if (hdmi->plat_data->input_bus_format) - hdmi->hdmi_data.enc_in_bus_format = - hdmi->plat_data->input_bus_format; - else - hdmi->hdmi_data.enc_in_bus_format = - MEDIA_BUS_FMT_RGB888_1X24; - /* TOFIX: Default to RGB888 output format */ - hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24; - } + hdmi->plat_data->get_output_bus_format(data); + else + hdmi->hdmi_data.enc_out_bus_format = + MEDIA_BUS_FMT_RGB888_1X24; + /* TOFIX: Get input encoding from plat data or fallback to none */ - if (hdmi->plat_data->input_bus_encoding) + if (hdmi->plat_data->get_enc_in_encoding) + hdmi->hdmi_data.enc_in_encoding = + hdmi->plat_data->get_enc_in_encoding(data); + else if (hdmi->plat_data->input_bus_encoding) hdmi->hdmi_data.enc_in_encoding = hdmi->plat_data->input_bus_encoding; else diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index 656eb9a2bd8c..580fe067d736 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -157,6 +157,11 @@ struct dw_hdmi_plat_data { int (*configure_phy)(struct dw_hdmi *hdmi, const struct dw_hdmi_plat_data *pdata, unsigned long mpixelclock); + + unsigned long (*get_input_bus_format)(void *data); + unsigned long (*get_output_bus_format)(void *data); + unsigned long (*get_enc_in_encoding)(void *data); + unsigned long (*get_enc_out_encoding)(void *data); }; void dw_hdmi_unbind(struct device *dev, struct device *master, void *data);