From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> 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@xxxxxxxxxxxxxxx> --- 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 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx