diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 6b52af19e886..223f77d167e1 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -1792,6 +1792,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi) return 0; } +static bool is_hdmi2_mode(const struct drm_display_mode *mode) +{ + if (mode->clock > 340000 && mode->clock <= 600000) + return true; + + return false; +} + static enum drm_mode_status dw_hdmi_rockchip_mode_valid(struct dw_hdmi *dw_hdmi, void *data, const struct drm_display_info *info, @@ -1821,6 +1829,28 @@ dw_hdmi_rockchip_mode_valid(struct dw_hdmi *dw_hdmi, void *data, hdmi = to_rockchip_hdmi(encoder); + if (!hdmi->skip_check_420_mode) { + /* edid isn't support yuv420 and max_tmds_clock is less than mode pixel clk */ + if (mode->clock < 600000 && connector->display_info.max_tmds_clock < mode->clock && + (!drm_mode_is_420(&connector->display_info, mode) || + !connector->ycbcr_420_allowed)) + return MODE_BAD; + + /* edid isn't support yuv420 and hdmitx only support hdmi1.4 clk */ + if (hdmi->max_tmdsclk <= 340000 && is_hdmi2_mode(mode) && + !drm_mode_is_420(&connector->display_info, mode)) + return MODE_BAD; + + /* + * hdmi cts hf1-31 required filtering yuv420 mode that frequency + * exceeds the max_tmds_clock of edid. + */ + if (drm_mode_is_420(&connector->display_info, mode) && + connector->display_info.max_tmds_clock < (mode->clock / 2) && + is_hdmi2_mode(mode)) + return MODE_BAD; + }; + if (hdmi->is_hdmi_qp) { if (!hdmi->enable_gpio && mode->clock > 600000) return MODE_BAD; @@ -1836,23 +1866,6 @@ dw_hdmi_rockchip_mode_valid(struct dw_hdmi *dw_hdmi, void *data, if (mode->clock > INT_MAX / 1000) return MODE_BAD; - /* - * If sink max TMDS clock < 340MHz, we should check the mode pixel - * clock > 340MHz is YCbCr420 or not and whether the platform supports - * YCbCr420. - */ - if (!hdmi->skip_check_420_mode) { - if (mode->clock > 340000 && - connector->display_info.max_tmds_clock < 340000 && - (!drm_mode_is_420(&connector->display_info, mode) || - !connector->ycbcr_420_allowed)) - return MODE_BAD; - - if (hdmi->max_tmdsclk <= 340000 && mode->clock > 340000 && - !drm_mode_is_420(&connector->display_info, mode)) - return MODE_BAD; - }; - if (hdmi->phy) { if (hdmi->is_hdmi_qp) phy_set_bus_width(hdmi->phy, mode->clock * 10);