[Intel-gfx] [PATCH 3/4] drm/i915: Implement limited color range for SDVO properly
ville.syrjala at linux.intel.com
ville.syrjala at linux.intel.com
Thu Aug 13 07:55:54 PDT 2015
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
The SDVO/HDMI port register limited color range bit can only be used
with TMDS encoding and not SDVO encoding, ie. to be used only when
using the port as a HDMI port as opposed to a SDVO port.
To implement limited color range support for SDVO->HDMI we need to ask
the SDVO device to do the range compression. Do so, but first check if
the device even supports the colorimetry selection.
Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
drivers/gpu/drm/i915/intel_sdvo.c | 63 +++++++++++++++++++++++++++------------
1 file changed, 44 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 33e58c1..0d1fed4 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -85,6 +85,8 @@ struct intel_sdvo {
*/
struct intel_sdvo_caps caps;
+ uint8_t colorimetry_cap;
+
/* Pixel clock limitations reported by the SDVO device, in kHz */
int pixel_clock_min, pixel_clock_max;
@@ -1164,14 +1166,16 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
pipe_config->has_hdmi_sink = intel_sdvo->has_hdmi_monitor;
- if (intel_sdvo->color_range_auto) {
- /* See CEA-861-E - 5.1 Default Encoding Parameters */
- pipe_config->limited_color_range =
- pipe_config->has_hdmi_sink &&
- drm_match_cea_mode(adjusted_mode) > 1;
- } else {
- pipe_config->limited_color_range =
- intel_sdvo->limited_color_range;
+ if (intel_sdvo->colorimetry_cap & SDVO_COLORIMETRY_RGB220) {
+ if (intel_sdvo->color_range_auto) {
+ /* See CEA-861-E - 5.1 Default Encoding Parameters */
+ pipe_config->limited_color_range =
+ pipe_config->has_hdmi_sink &&
+ drm_match_cea_mode(adjusted_mode) > 1;
+ } else {
+ pipe_config->limited_color_range =
+ intel_sdvo->limited_color_range;
+ }
}
/* Clock computation needs to happen after pixel multiplier. */
@@ -1232,8 +1236,12 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder)
if (crtc->config->has_hdmi_sink) {
intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI);
- intel_sdvo_set_colorimetry(intel_sdvo,
- SDVO_COLORIMETRY_RGB256);
+ if (crtc->config->limited_color_range)
+ intel_sdvo_set_colorimetry(intel_sdvo,
+ SDVO_COLORIMETRY_RGB220);
+ else
+ intel_sdvo_set_colorimetry(intel_sdvo,
+ SDVO_COLORIMETRY_RGB256);
intel_sdvo_set_avi_infoframe(intel_sdvo, adjusted_mode);
} else
intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_DVI);
@@ -1265,10 +1273,6 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder)
/* The real mode polarity is set by the SDVO commands, using
* struct intel_sdvo_dtd. */
sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH;
- /* FIXME: this bit is only valid when using TMDS
- * encoding and 8 bit per color mode. */
- if (!HAS_PCH_SPLIT(dev) && crtc->config->limited_color_range)
- sdvox |= HDMI_COLOR_RANGE_16_235;
if (INTEL_INFO(dev)->gen < 5)
sdvox |= SDVO_BORDER_ENABLE;
} else {
@@ -1418,8 +1422,16 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
}
}
- if (sdvox & HDMI_COLOR_RANGE_16_235)
- pipe_config->limited_color_range = true;
+ if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_COLORIMETRY,
+ &val, 1)) {
+ switch (val) {
+ case SDVO_COLORIMETRY_RGB220:
+ pipe_config->limited_color_range = true;
+ break;
+ default:
+ break;
+ }
+ }
if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ENCODE,
&val, 1)) {
@@ -1570,6 +1582,17 @@ static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct in
return true;
}
+static uint8_t intel_sdvo_get_colorimetry_cap(struct intel_sdvo *intel_sdvo)
+{
+ uint8_t cap;
+
+ if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_COLORIMETRY_CAP,
+ &cap, sizeof(cap)))
+ return SDVO_COLORIMETRY_RGB256;
+
+ return cap;
+}
+
static uint16_t intel_sdvo_get_hotplug_support(struct intel_sdvo *intel_sdvo)
{
struct drm_device *dev = intel_sdvo->base.base.dev;
@@ -2373,10 +2396,9 @@ static void
intel_sdvo_add_hdmi_properties(struct intel_sdvo *intel_sdvo,
struct intel_sdvo_connector *connector)
{
- struct drm_device *dev = connector->base.base.dev;
-
intel_attach_force_audio_property(&connector->base.base);
- if (INTEL_INFO(dev)->gen >= 4 && IS_MOBILE(dev)) {
+
+ if (intel_sdvo->colorimetry_cap & SDVO_COLORIMETRY_RGB220) {
intel_attach_broadcast_rgb_property(&connector->base.base);
intel_sdvo->color_range_auto = true;
}
@@ -2958,6 +2980,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))
goto err;
+ intel_sdvo->colorimetry_cap =
+ intel_sdvo_get_colorimetry_cap(intel_sdvo);
+
if (intel_sdvo_output_setup(intel_sdvo,
intel_sdvo->caps.output_flags) != true) {
DRM_DEBUG_KMS("SDVO output failed to setup on %s\n",
--
2.4.6
More information about the Intel-gfx
mailing list