drm/rockchip: dw_hdmi: Fix hdmi cts hf1-31 failed

Hdmi cts hf1-31 required filtering yuv420 mode that frequency
exceeds the max tmds clock of edid.

Change-Id: I746a9f910444845ab84b7804ebc63bb934363ebe
Signed-off-by: Algea Cao <algea.cao@rock-chips.com>
This commit is contained in:
Algea Cao
2024-04-29 15:22:51 +08:00
committed by Tao Huang
parent b0186da406
commit c1dcc6ec1e

View File

@@ -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);