aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_edid.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_edid.c')
-rw-r--r--drivers/gpu/drm/drm_edid.c101
1 files changed, 51 insertions, 50 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index b506e3622b08..990b1909f9d7 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3641,6 +3641,20 @@ static bool cea_db_is_hdmi_forum_vsdb(const u8 *db)
3641 return oui == HDMI_FORUM_IEEE_OUI; 3641 return oui == HDMI_FORUM_IEEE_OUI;
3642} 3642}
3643 3643
3644static bool cea_db_is_vcdb(const u8 *db)
3645{
3646 if (cea_db_tag(db) != USE_EXTENDED_TAG)
3647 return false;
3648
3649 if (cea_db_payload_len(db) != 2)
3650 return false;
3651
3652 if (cea_db_extended_tag(db) != EXT_VIDEO_CAPABILITY_BLOCK)
3653 return false;
3654
3655 return true;
3656}
3657
3644static bool cea_db_is_y420cmdb(const u8 *db) 3658static bool cea_db_is_y420cmdb(const u8 *db)
3645{ 3659{
3646 if (cea_db_tag(db) != USE_EXTENDED_TAG) 3660 if (cea_db_tag(db) != USE_EXTENDED_TAG)
@@ -4223,41 +4237,6 @@ end:
4223} 4237}
4224EXPORT_SYMBOL(drm_detect_monitor_audio); 4238EXPORT_SYMBOL(drm_detect_monitor_audio);
4225 4239
4226/**
4227 * drm_rgb_quant_range_selectable - is RGB quantization range selectable?
4228 * @edid: EDID block to scan
4229 *
4230 * Check whether the monitor reports the RGB quantization range selection
4231 * as supported. The AVI infoframe can then be used to inform the monitor
4232 * which quantization range (full or limited) is used.
4233 *
4234 * Return: True if the RGB quantization range is selectable, false otherwise.
4235 */
4236bool drm_rgb_quant_range_selectable(struct edid *edid)
4237{
4238 u8 *edid_ext;
4239 int i, start, end;
4240
4241 edid_ext = drm_find_cea_extension(edid);
4242 if (!edid_ext)
4243 return false;
4244
4245 if (cea_db_offsets(edid_ext, &start, &end))
4246 return false;
4247
4248 for_each_cea_db(edid_ext, i, start, end) {
4249 if (cea_db_tag(&edid_ext[i]) == USE_EXTENDED_TAG &&
4250 cea_db_payload_len(&edid_ext[i]) == 2 &&
4251 cea_db_extended_tag(&edid_ext[i]) ==
4252 EXT_VIDEO_CAPABILITY_BLOCK) {
4253 DRM_DEBUG_KMS("CEA VCDB 0x%02x\n", edid_ext[i + 2]);
4254 return edid_ext[i + 2] & EDID_CEA_VCDB_QS;
4255 }
4256 }
4257
4258 return false;
4259}
4260EXPORT_SYMBOL(drm_rgb_quant_range_selectable);
4261 4240
4262/** 4241/**
4263 * drm_default_rgb_quant_range - default RGB quantization range 4242 * drm_default_rgb_quant_range - default RGB quantization range
@@ -4278,6 +4257,16 @@ drm_default_rgb_quant_range(const struct drm_display_mode *mode)
4278} 4257}
4279EXPORT_SYMBOL(drm_default_rgb_quant_range); 4258EXPORT_SYMBOL(drm_default_rgb_quant_range);
4280 4259
4260static void drm_parse_vcdb(struct drm_connector *connector, const u8 *db)
4261{
4262 struct drm_display_info *info = &connector->display_info;
4263
4264 DRM_DEBUG_KMS("CEA VCDB 0x%02x\n", db[2]);
4265
4266 if (db[2] & EDID_CEA_VCDB_QS)
4267 info->rgb_quant_range_selectable = true;
4268}
4269
4281static void drm_parse_ycbcr420_deep_color_info(struct drm_connector *connector, 4270static void drm_parse_ycbcr420_deep_color_info(struct drm_connector *connector,
4282 const u8 *db) 4271 const u8 *db)
4283{ 4272{
@@ -4452,6 +4441,8 @@ static void drm_parse_cea_ext(struct drm_connector *connector,
4452 drm_parse_hdmi_forum_vsdb(connector, db); 4441 drm_parse_hdmi_forum_vsdb(connector, db);
4453 if (cea_db_is_y420cmdb(db)) 4442 if (cea_db_is_y420cmdb(db))
4454 drm_parse_y420cmdb_bitmap(connector, db); 4443 drm_parse_y420cmdb_bitmap(connector, db);
4444 if (cea_db_is_vcdb(db))
4445 drm_parse_vcdb(connector, db);
4455 } 4446 }
4456} 4447}
4457 4448
@@ -4472,6 +4463,7 @@ drm_reset_display_info(struct drm_connector *connector)
4472 info->max_tmds_clock = 0; 4463 info->max_tmds_clock = 0;
4473 info->dvi_dual = false; 4464 info->dvi_dual = false;
4474 info->has_hdmi_infoframe = false; 4465 info->has_hdmi_infoframe = false;
4466 info->rgb_quant_range_selectable = false;
4475 memset(&info->hdmi, 0, sizeof(info->hdmi)); 4467 memset(&info->hdmi, 0, sizeof(info->hdmi));
4476 4468
4477 info->non_desktop = 0; 4469 info->non_desktop = 0;
@@ -4830,19 +4822,32 @@ void drm_set_preferred_mode(struct drm_connector *connector,
4830} 4822}
4831EXPORT_SYMBOL(drm_set_preferred_mode); 4823EXPORT_SYMBOL(drm_set_preferred_mode);
4832 4824
4825static bool is_hdmi2_sink(struct drm_connector *connector)
4826{
4827 /*
4828 * FIXME: sil-sii8620 doesn't have a connector around when
4829 * we need one, so we have to be prepared for a NULL connector.
4830 */
4831 if (!connector)
4832 return true;
4833
4834 return connector->display_info.hdmi.scdc.supported ||
4835 connector->display_info.color_formats & DRM_COLOR_FORMAT_YCRCB420;
4836}
4837
4833/** 4838/**
4834 * drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with 4839 * drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with
4835 * data from a DRM display mode 4840 * data from a DRM display mode
4836 * @frame: HDMI AVI infoframe 4841 * @frame: HDMI AVI infoframe
4842 * @connector: the connector
4837 * @mode: DRM display mode 4843 * @mode: DRM display mode
4838 * @is_hdmi2_sink: Sink is HDMI 2.0 compliant
4839 * 4844 *
4840 * Return: 0 on success or a negative error code on failure. 4845 * Return: 0 on success or a negative error code on failure.
4841 */ 4846 */
4842int 4847int
4843drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, 4848drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
4844 const struct drm_display_mode *mode, 4849 struct drm_connector *connector,
4845 bool is_hdmi2_sink) 4850 const struct drm_display_mode *mode)
4846{ 4851{
4847 enum hdmi_picture_aspect picture_aspect; 4852 enum hdmi_picture_aspect picture_aspect;
4848 int err; 4853 int err;
@@ -4864,7 +4869,7 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
4864 * HDMI 2.0 VIC range: 1 <= VIC <= 107 (CEA-861-F). So we 4869 * HDMI 2.0 VIC range: 1 <= VIC <= 107 (CEA-861-F). So we
4865 * have to make sure we dont break HDMI 1.4 sinks. 4870 * have to make sure we dont break HDMI 1.4 sinks.
4866 */ 4871 */
4867 if (!is_hdmi2_sink && frame->video_code > 64) 4872 if (!is_hdmi2_sink(connector) && frame->video_code > 64)
4868 frame->video_code = 0; 4873 frame->video_code = 0;
4869 4874
4870 /* 4875 /*
@@ -4923,22 +4928,18 @@ EXPORT_SYMBOL(drm_hdmi_avi_infoframe_from_display_mode);
4923 * drm_hdmi_avi_infoframe_quant_range() - fill the HDMI AVI infoframe 4928 * drm_hdmi_avi_infoframe_quant_range() - fill the HDMI AVI infoframe
4924 * quantization range information 4929 * quantization range information
4925 * @frame: HDMI AVI infoframe 4930 * @frame: HDMI AVI infoframe
4931 * @connector: the connector
4926 * @mode: DRM display mode 4932 * @mode: DRM display mode
4927 * @rgb_quant_range: RGB quantization range (Q) 4933 * @rgb_quant_range: RGB quantization range (Q)
4928 * @rgb_quant_range_selectable: Sink support selectable RGB quantization range (QS)
4929 * @is_hdmi2_sink: HDMI 2.0 sink, which has different default recommendations
4930 *
4931 * Note that @is_hdmi2_sink can be derived by looking at the
4932 * &drm_scdc.supported flag stored in &drm_hdmi_info.scdc,
4933 * &drm_display_info.hdmi, which can be found in &drm_connector.display_info.
4934 */ 4934 */
4935void 4935void
4936drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame, 4936drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
4937 struct drm_connector *connector,
4937 const struct drm_display_mode *mode, 4938 const struct drm_display_mode *mode,
4938 enum hdmi_quantization_range rgb_quant_range, 4939 enum hdmi_quantization_range rgb_quant_range)
4939 bool rgb_quant_range_selectable,
4940 bool is_hdmi2_sink)
4941{ 4940{
4941 const struct drm_display_info *info = &connector->display_info;
4942
4942 /* 4943 /*
4943 * CEA-861: 4944 * CEA-861:
4944 * "A Source shall not send a non-zero Q value that does not correspond 4945 * "A Source shall not send a non-zero Q value that does not correspond
@@ -4949,7 +4950,7 @@ drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
4949 * HDMI 2.0 recommends sending non-zero Q when it does match the 4950 * HDMI 2.0 recommends sending non-zero Q when it does match the
4950 * default RGB quantization range for the mode, even when QS=0. 4951 * default RGB quantization range for the mode, even when QS=0.
4951 */ 4952 */
4952 if (rgb_quant_range_selectable || 4953 if (info->rgb_quant_range_selectable ||
4953 rgb_quant_range == drm_default_rgb_quant_range(mode)) 4954 rgb_quant_range == drm_default_rgb_quant_range(mode))
4954 frame->quantization_range = rgb_quant_range; 4955 frame->quantization_range = rgb_quant_range;
4955 else 4956 else
@@ -4968,7 +4969,7 @@ drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
4968 * we limit non-zero YQ to HDMI 2.0 sinks only as HDMI 2.0 is based 4969 * we limit non-zero YQ to HDMI 2.0 sinks only as HDMI 2.0 is based
4969 * on on CEA-861-F. 4970 * on on CEA-861-F.
4970 */ 4971 */
4971 if (!is_hdmi2_sink || 4972 if (!is_hdmi2_sink(connector) ||
4972 rgb_quant_range == HDMI_QUANTIZATION_RANGE_LIMITED) 4973 rgb_quant_range == HDMI_QUANTIZATION_RANGE_LIMITED)
4973 frame->ycc_quantization_range = 4974 frame->ycc_quantization_range =
4974 HDMI_YCC_QUANTIZATION_RANGE_LIMITED; 4975 HDMI_YCC_QUANTIZATION_RANGE_LIMITED;