From 5edad1e5eee38688507a5bb82e8991fb995029bf Mon Sep 17 00:00:00 2001 From: Zheng Yang Date: Fri, 17 Nov 2017 18:44:13 +0800 Subject: [PATCH] drm/rockchip: dw-hdmi: move depth checking into dw_hdmi_rockchip_select_output For some display device, max_tmds_clock is 0, we think max_tmds_clock is 340MHz. If tmdsclock > max_tmds_clock, depth should fall back to 8bit. And If display mode support YCBCR420, output format is YCBCR420. Because max tmds clk of RK3368 is 340MHz, hdmi output policy is same as mentioned above. It is need to check tmds clock rate at the last. So we move depth checking into dw_hdmi_rockchip_select_output. Change-Id: I27e029fc0171b175ddbfa453ed12854ab6a7432b Signed-off-by: Zheng Yang --- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 99 +++++++++------------ 1 file changed, 42 insertions(+), 57 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index deb309450d1c..754bc336eedb 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -491,55 +491,6 @@ static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder) ret ? "LIT" : "BIG"); } -static unsigned int -dw_hdmi_rockchip_check_depth(struct drm_display_info *info, - struct drm_display_mode *mode, - int color_format, int depth) -{ - unsigned long tmdsclock, pixclock = mode->crtc_clock; - int colordepth = 8; - - if (color_format == DRM_HDMI_OUTPUT_YCBCR444 && - !(info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_Y444)) - return colordepth; - else if (!depth) - colordepth = info->bpc; - else - colordepth = depth; - - /* Color depth on rockchip platform is limited up to 10bit */ - if (colordepth > 10) { - colordepth = 10; - if (color_format == DRM_HDMI_OUTPUT_YCBCR420 && - !(info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)) - return 8; - } - - if (mode->flags & DRM_MODE_FLAG_DBLCLK) - pixclock *= 2; - if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == - DRM_MODE_FLAG_3D_FRAME_PACKING) - pixclock *= 2; - - if (color_format == DRM_HDMI_OUTPUT_YCBCR422 || colordepth == 8) - tmdsclock = pixclock; - else - tmdsclock = pixclock * colordepth / 8; - - if (color_format == DRM_HDMI_OUTPUT_YCBCR420) - tmdsclock /= 2; - /* - * For some display device, max_tmds_clock is 0, we think - * max_tmds_clock is 340MHz. If tmdsclock > max_tmds_clock, - * fallback to 8bit. - */ - if ((!info->max_tmds_clock && tmdsclock > 340000) || - (info->max_tmds_clock && tmdsclock > info->max_tmds_clock)) - colordepth = 8; - - return colordepth; -} - static void dw_hdmi_rockchip_select_output(struct drm_connector_state *conn_state, struct drm_crtc_state *crtc_state, @@ -553,6 +504,7 @@ dw_hdmi_rockchip_select_output(struct drm_connector_state *conn_state, struct drm_display_mode *mode = &crtc_state->mode; struct hdr_static_metadata *hdr_metadata; u32 vic = drm_match_cea_mode(mode); + unsigned long tmdsclock, pixclock = mode->crtc_clock; *color_format = DRM_HDMI_OUTPUT_DEFAULT_RGB; @@ -593,15 +545,22 @@ dw_hdmi_rockchip_select_output(struct drm_connector_state *conn_state, break; } - /* RK3368 should limit 4K 50/60 to YCbCr420 mode */ - if (hdmi->max_tmdsclk <= 340000 && - mode->crtc_clock > 340000 && - drm_mode_is_420(info, mode)) - *color_format = DRM_HDMI_OUTPUT_YCBCR420; + if (*color_format == DRM_HDMI_OUTPUT_YCBCR444 && + !(info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_Y444)) + *color_depth = 8; + else if (!hdmi->colordepth) + *color_depth = info->bpc; + else + *color_depth = hdmi->colordepth; + + /* Color depth on rockchip platform is limited up to 10bit */ + if (*color_depth > 10) { + *color_depth = 10; + if (*color_format == DRM_HDMI_OUTPUT_YCBCR420 && + !(info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)) + *color_depth = 8; + } - *color_depth = dw_hdmi_rockchip_check_depth(info, mode, - *color_format, - hdmi->colordepth); *eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR; if (conn_state->hdr_output_metadata) { hdr_metadata = (struct hdr_static_metadata *) @@ -627,6 +586,32 @@ dw_hdmi_rockchip_select_output(struct drm_connector_state *conn_state, if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422) *color_format = DRM_HDMI_OUTPUT_YCBCR422; } + + if (mode->flags & DRM_MODE_FLAG_DBLCLK) + pixclock *= 2; + if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == + DRM_MODE_FLAG_3D_FRAME_PACKING) + pixclock *= 2; + + if (*color_format == DRM_HDMI_OUTPUT_YCBCR422 || *color_depth == 8) + tmdsclock = pixclock; + else + tmdsclock = pixclock * (*color_depth) / 8; + + if (*color_format == DRM_HDMI_OUTPUT_YCBCR420) + tmdsclock /= 2; + /* + * For some display device, max_tmds_clock is 0, we think + * max_tmds_clock is 340MHz. If tmdsclock > max_tmds_clock, + * fallback to 8bit. If mode support YCBCR420, use YCBCR420. + */ + if ((!info->max_tmds_clock && tmdsclock > 340000) || + (info->max_tmds_clock && tmdsclock > info->max_tmds_clock) || + tmdsclock > hdmi->max_tmdsclk) { + *color_depth = 8; + if (drm_mode_is_420(info, mode)) + *color_format = DRM_HDMI_OUTPUT_YCBCR420; + } } static int