aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2013-01-17 09:31:31 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-01-20 07:09:45 -0500
commitabedc077b45eff0b5a8630af8431ad5d59213582 (patch)
treee5a4f22ef38595086f48cb414d362f4b9f935de6
parentb1edd6a6ecd436af33f210a5c75e0249466fd200 (diff)
drm/i915: Provide the quantization range in the AVI infoframe
The AVI infoframe is able to inform the display whether the source is sending full or limited range RGB data. As per CEA-861 [1] we must first check whether the display reports the quantization range as selectable, and if so we can set the approriate bits in the AVI inforframe. [1] CEA-861-E - 6.4 Format of Version 2 AVI InfoFrame v2: Give the Q bits better names, add spec chapter information Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h4
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c11
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c16
3 files changed, 29 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 1a698c6f16e7..aeff0d1067ad 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -289,6 +289,9 @@ struct cxsr_latency {
289#define DIP_LEN_AVI 13 289#define DIP_LEN_AVI 13
290#define DIP_AVI_PR_1 0 290#define DIP_AVI_PR_1 0
291#define DIP_AVI_PR_2 1 291#define DIP_AVI_PR_2 1
292#define DIP_AVI_RGB_QUANT_RANGE_DEFAULT (0 << 2)
293#define DIP_AVI_RGB_QUANT_RANGE_LIMITED (1 << 2)
294#define DIP_AVI_RGB_QUANT_RANGE_FULL (2 << 2)
292 295
293#define DIP_TYPE_SPD 0x83 296#define DIP_TYPE_SPD 0x83
294#define DIP_VERSION_SPD 0x1 297#define DIP_VERSION_SPD 0x1
@@ -347,6 +350,7 @@ struct intel_hdmi {
347 bool has_hdmi_sink; 350 bool has_hdmi_sink;
348 bool has_audio; 351 bool has_audio;
349 enum hdmi_force_audio force_audio; 352 enum hdmi_force_audio force_audio;
353 bool rgb_quant_range_selectable;
350 void (*write_infoframe)(struct drm_encoder *encoder, 354 void (*write_infoframe)(struct drm_encoder *encoder,
351 struct dip_infoframe *frame); 355 struct dip_infoframe *frame);
352 void (*set_infoframes)(struct drm_encoder *encoder, 356 void (*set_infoframes)(struct drm_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index db67be66639b..d53b73131b0e 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -331,6 +331,7 @@ static void intel_set_infoframe(struct drm_encoder *encoder,
331static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, 331static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
332 struct drm_display_mode *adjusted_mode) 332 struct drm_display_mode *adjusted_mode)
333{ 333{
334 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
334 struct dip_infoframe avi_if = { 335 struct dip_infoframe avi_if = {
335 .type = DIP_TYPE_AVI, 336 .type = DIP_TYPE_AVI,
336 .ver = DIP_VERSION_AVI, 337 .ver = DIP_VERSION_AVI,
@@ -340,6 +341,13 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
340 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) 341 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
341 avi_if.body.avi.YQ_CN_PR |= DIP_AVI_PR_2; 342 avi_if.body.avi.YQ_CN_PR |= DIP_AVI_PR_2;
342 343
344 if (intel_hdmi->rgb_quant_range_selectable) {
345 if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE)
346 avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_LIMITED;
347 else
348 avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_FULL;
349 }
350
343 avi_if.body.avi.VIC = drm_mode_cea_vic(adjusted_mode); 351 avi_if.body.avi.VIC = drm_mode_cea_vic(adjusted_mode);
344 352
345 intel_set_infoframe(encoder, &avi_if); 353 intel_set_infoframe(encoder, &avi_if);
@@ -825,6 +833,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
825 833
826 intel_hdmi->has_hdmi_sink = false; 834 intel_hdmi->has_hdmi_sink = false;
827 intel_hdmi->has_audio = false; 835 intel_hdmi->has_audio = false;
836 intel_hdmi->rgb_quant_range_selectable = false;
828 edid = drm_get_edid(connector, 837 edid = drm_get_edid(connector,
829 intel_gmbus_get_adapter(dev_priv, 838 intel_gmbus_get_adapter(dev_priv,
830 intel_hdmi->ddc_bus)); 839 intel_hdmi->ddc_bus));
@@ -836,6 +845,8 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
836 intel_hdmi->has_hdmi_sink = 845 intel_hdmi->has_hdmi_sink =
837 drm_detect_hdmi_monitor(edid); 846 drm_detect_hdmi_monitor(edid);
838 intel_hdmi->has_audio = drm_detect_monitor_audio(edid); 847 intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
848 intel_hdmi->rgb_quant_range_selectable =
849 drm_rgb_quant_range_selectable(edid);
839 } 850 }
840 kfree(edid); 851 kfree(edid);
841 } 852 }
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 3e34a3592e32..f01063a2323a 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -126,6 +126,7 @@ struct intel_sdvo {
126 bool is_hdmi; 126 bool is_hdmi;
127 bool has_hdmi_monitor; 127 bool has_hdmi_monitor;
128 bool has_hdmi_audio; 128 bool has_hdmi_audio;
129 bool rgb_quant_range_selectable;
129 130
130 /** 131 /**
131 * This is set if we detect output of sdvo device as LVDS and 132 * This is set if we detect output of sdvo device as LVDS and
@@ -947,7 +948,8 @@ static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo,
947 &tx_rate, 1); 948 &tx_rate, 1);
948} 949}
949 950
950static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) 951static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo,
952 const struct drm_display_mode *adjusted_mode)
951{ 953{
952 struct dip_infoframe avi_if = { 954 struct dip_infoframe avi_if = {
953 .type = DIP_TYPE_AVI, 955 .type = DIP_TYPE_AVI,
@@ -956,6 +958,13 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)
956 }; 958 };
957 uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; 959 uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)];
958 960
961 if (intel_sdvo->rgb_quant_range_selectable) {
962 if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE)
963 avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_LIMITED;
964 else
965 avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_FULL;
966 }
967
959 intel_dip_infoframe_csum(&avi_if); 968 intel_dip_infoframe_csum(&avi_if);
960 969
961 /* sdvo spec says that the ecc is handled by the hw, and it looks like 970 /* sdvo spec says that the ecc is handled by the hw, and it looks like
@@ -1134,7 +1143,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
1134 intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI); 1143 intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI);
1135 intel_sdvo_set_colorimetry(intel_sdvo, 1144 intel_sdvo_set_colorimetry(intel_sdvo,
1136 SDVO_COLORIMETRY_RGB256); 1145 SDVO_COLORIMETRY_RGB256);
1137 intel_sdvo_set_avi_infoframe(intel_sdvo); 1146 intel_sdvo_set_avi_infoframe(intel_sdvo, adjusted_mode);
1138 } else 1147 } else
1139 intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_DVI); 1148 intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_DVI);
1140 1149
@@ -1526,6 +1535,8 @@ intel_sdvo_tmds_sink_detect(struct drm_connector *connector)
1526 if (intel_sdvo->is_hdmi) { 1535 if (intel_sdvo->is_hdmi) {
1527 intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid); 1536 intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid);
1528 intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid); 1537 intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid);
1538 intel_sdvo->rgb_quant_range_selectable =
1539 drm_rgb_quant_range_selectable(edid);
1529 } 1540 }
1530 } else 1541 } else
1531 status = connector_status_disconnected; 1542 status = connector_status_disconnected;
@@ -1577,6 +1588,7 @@ intel_sdvo_detect(struct drm_connector *connector, bool force)
1577 1588
1578 intel_sdvo->has_hdmi_monitor = false; 1589 intel_sdvo->has_hdmi_monitor = false;
1579 intel_sdvo->has_hdmi_audio = false; 1590 intel_sdvo->has_hdmi_audio = false;
1591 intel_sdvo->rgb_quant_range_selectable = false;
1580 1592
1581 if ((intel_sdvo_connector->output_flag & response) == 0) 1593 if ((intel_sdvo_connector->output_flag & response) == 0)
1582 ret = connector_status_disconnected; 1594 ret = connector_status_disconnected;