diff --git a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c index 302ed39d9218..1f0a9d44d426 100644 --- a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c +++ b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c @@ -2754,6 +2754,13 @@ enum drm_mode_status sde_hdmi_mode_valid(struct drm_connector *connector, if (actual != requested) return MODE_CLOCK_RANGE; + /* if no format flags are present remove the mode */ + if (!(mode->flags & SDE_DRM_MODE_FLAG_FMT_MASK)) { + SDE_HDMI_DEBUG("removing following mode from list\n"); + drm_mode_debug_printmodeline(mode); + return MODE_BAD; + } + return MODE_OK; } diff --git a/drivers/gpu/drm/msm/sde_edid_parser.c b/drivers/gpu/drm/msm/sde_edid_parser.c index 043e439835f1..cceaf1c27716 100644 --- a/drivers/gpu/drm/msm/sde_edid_parser.c +++ b/drivers/gpu/drm/msm/sde_edid_parser.c @@ -366,6 +366,33 @@ struct drm_connector *connector, struct sde_edid_ctrl *edid_ctrl) else SDE_EDID_DEBUG("YCbCr420 CMDB is not present\n"); + /* + * As per HDMI 2.0 spec, a sink supporting any modes + * requiring more than 340Mhz clock rate should support + * SCDC as well. This is required because we need the SCDC + * channel to set the TMDS clock ratio. However in cases + * where the TV publishes such a mode in its list of modes + * but does not have SCDC support as per HDMI HFVSDB block + * remove RGB mode support from the flags. Currently, in + * the list of modes not having deep color support only RGB + * modes shall requre a clock of 340Mhz and above such as the + * 4K@60fps case. All other modes shall be YUV. + * Deep color case is handled separately while choosing the + * best mode in the _sde_hdmi_choose_best_format API where + * we enable deep color only if it satisfies both source and + * sink requirements. However, that API assumes that at least + * RGB mode is supported on the mode. Hence, it would be better + * to remove the format support flags while parsing the EDID + * itself if it doesn't satisfy the HDMI spec requirement. + */ + + list_for_each_entry(mode, &connector->probed_modes, head) { + if ((mode->clock > MIN_SCRAMBLER_REQ_RATE) && + !connector->scdc_present) { + mode->flags &= ~DRM_MODE_FLAG_SUPPORTS_RGB; + } + } + SDE_EDID_DEBUG("%s -\n", __func__); } diff --git a/drivers/gpu/drm/msm/sde_edid_parser.h b/drivers/gpu/drm/msm/sde_edid_parser.h index 59e3dceca33c..a913219aac50 100644 --- a/drivers/gpu/drm/msm/sde_edid_parser.h +++ b/drivers/gpu/drm/msm/sde_edid_parser.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -33,6 +33,8 @@ #define SDE_CEA_EXT 0x02 #define SDE_EXTENDED_TAG 0x07 +#define MIN_SCRAMBLER_REQ_RATE 340000 + #define SDE_DRM_MODE_FLAG_FMT_MASK (0x3 << 20) enum extended_data_block_types {