From: Ville Syrjälä <ville.syrj...@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.syrj...@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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to