diff options
| author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2013-01-17 16:31:29 +0200 | 
|---|---|---|
| committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-01-20 13:09:44 +0100 | 
| commit | 55bc60db5988c8366751d3d04dd690698a53412c (patch) | |
| tree | 1fc546713d825d8b2892d2b113f36c965008f7f1 /drivers | |
| parent | 3685a8f38f2c54bb6058c0e66ae0562f8ab84e66 (diff) | |
| download | olio-linux-3.10-55bc60db5988c8366751d3d04dd690698a53412c.tar.xz olio-linux-3.10-55bc60db5988c8366751d3d04dd690698a53412c.zip  | |
drm/i915: Add "Automatic" mode for the "Broadcast RGB" property
Add a new "Automatic" mode to the "Broadcast RGB" range property.
When selected the driver automagically selects between full range and
limited range output.
Based on CEA-861 [1] guidelines, limited range output is selected if the
mode is a CEA mode, except 640x480. Otherwise full range output is used.
Additionally DVI monitors should most likely default to full range
always.
As per DP1.2a [2] DisplayPort should always use full range for 18bpp, and
otherwise will follow CEA-861 rules.
NOTE: The default value for the property will now be "Automatic"
so some people may be affected in case they're relying on the
current full range default.
[1] CEA-861-E - 5.1 Default Encoding Parameters
[2] VESA DisplayPort Ver.1.2a - 5.1.1.1 Video Colorimetry
v2: Use has_hdmi_sink to check if a HDMI monitor is present
v3: Add information about relevant spec chapters
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>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 32 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_hdmi.c | 29 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_modes.c | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 38 | 
6 files changed, 93 insertions, 17 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f3f2e5e1393..0a2a18b8a07 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1811,5 +1811,9 @@ __i915_write(64, q)  #define POSTING_READ(reg)	(void)I915_READ_NOTRACE(reg)  #define POSTING_READ16(reg)	(void)I915_READ16_NOTRACE(reg) +/* "Broadcast RGB" property */ +#define INTEL_BROADCAST_RGB_AUTO 0 +#define INTEL_BROADCAST_RGB_FULL 1 +#define INTEL_BROADCAST_RGB_LIMITED 2  #endif diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index d9956278a56..1492706ed08 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -764,6 +764,18 @@ intel_dp_mode_fixup(struct drm_encoder *encoder,  	bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; +	if (intel_dp->color_range_auto) { +		/* +		 * See: +		 * CEA-861-E - 5.1 Default Encoding Parameters +		 * VESA DisplayPort Ver.1.2a - 5.1.1.1 Video Colorimetry +		 */ +		if (bpp != 18 && drm_mode_cea_vic(adjusted_mode) > 1) +			intel_dp->color_range = DP_COLOR_RANGE_16_235; +		else +			intel_dp->color_range = 0; +	} +  	if (intel_dp->color_range)  		adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE; @@ -2462,10 +2474,21 @@ intel_dp_set_property(struct drm_connector *connector,  	}  	if (property == dev_priv->broadcast_rgb_property) { -		if (val == !!intel_dp->color_range) -			return 0; - -		intel_dp->color_range = val ? DP_COLOR_RANGE_16_235 : 0; +		switch (val) { +		case INTEL_BROADCAST_RGB_AUTO: +			intel_dp->color_range_auto = true; +			break; +		case INTEL_BROADCAST_RGB_FULL: +			intel_dp->color_range_auto = false; +			intel_dp->color_range = 0; +			break; +		case INTEL_BROADCAST_RGB_LIMITED: +			intel_dp->color_range_auto = false; +			intel_dp->color_range = DP_COLOR_RANGE_16_235; +			break; +		default: +			return -EINVAL; +		}  		goto done;  	} @@ -2606,6 +2629,7 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect  	intel_attach_force_audio_property(connector);  	intel_attach_broadcast_rgb_property(connector); +	intel_dp->color_range_auto = true;  	if (is_edp(intel_dp)) {  		drm_mode_create_scaling_mode_property(connector->dev); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 4df47be84ab..1a698c6f16e 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -343,6 +343,7 @@ struct intel_hdmi {  	u32 sdvox_reg;  	int ddc_bus;  	uint32_t color_range; +	bool color_range_auto;  	bool has_hdmi_sink;  	bool has_audio;  	enum hdmi_force_audio force_audio; @@ -362,6 +363,7 @@ struct intel_dp {  	bool has_audio;  	enum hdmi_force_audio force_audio;  	uint32_t color_range; +	bool color_range_auto;  	uint8_t link_bw;  	uint8_t lane_count;  	uint8_t dpcd[DP_RECEIVER_CAP_SIZE]; diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index f194d756a58..db67be66639 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -768,6 +768,15 @@ bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,  {  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); +	if (intel_hdmi->color_range_auto) { +		/* See CEA-861-E - 5.1 Default Encoding Parameters */ +		if (intel_hdmi->has_hdmi_sink && +		    drm_mode_cea_vic(adjusted_mode) > 1) +			intel_hdmi->color_range = SDVO_COLOR_RANGE_16_235; +		else +			intel_hdmi->color_range = 0; +	} +  	if (intel_hdmi->color_range)  		adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE; @@ -912,10 +921,21 @@ intel_hdmi_set_property(struct drm_connector *connector,  	}  	if (property == dev_priv->broadcast_rgb_property) { -		if (val == !!intel_hdmi->color_range) -			return 0; - -		intel_hdmi->color_range = val ? SDVO_COLOR_RANGE_16_235 : 0; +		switch (val) { +		case INTEL_BROADCAST_RGB_AUTO: +			intel_hdmi->color_range_auto = true; +			break; +		case INTEL_BROADCAST_RGB_FULL: +			intel_hdmi->color_range_auto = false; +			intel_hdmi->color_range = 0; +			break; +		case INTEL_BROADCAST_RGB_LIMITED: +			intel_hdmi->color_range_auto = false; +			intel_hdmi->color_range = SDVO_COLOR_RANGE_16_235; +			break; +		default: +			return -EINVAL; +		}  		goto done;  	} @@ -964,6 +984,7 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *c  {  	intel_attach_force_audio_property(connector);  	intel_attach_broadcast_rgb_property(connector); +	intel_hdmi->color_range_auto = true;  }  void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index 49249bb9748..0e860f39933 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c @@ -100,8 +100,9 @@ intel_attach_force_audio_property(struct drm_connector *connector)  }  static const struct drm_prop_enum_list broadcast_rgb_names[] = { -	{ 0, "Full" }, -	{ 1, "Limited 16:235" }, +	{ INTEL_BROADCAST_RGB_AUTO, "Automatic" }, +	{ INTEL_BROADCAST_RGB_FULL, "Full" }, +	{ INTEL_BROADCAST_RGB_LIMITED, "Limited 16:235" },  };  void diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 3b8491af1f2..3e34a3592e3 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -103,6 +103,7 @@ struct intel_sdvo {  	 * It is only valid when using TMDS encoding and 8 bit per color mode.  	 */  	uint32_t color_range; +	bool color_range_auto;  	/**  	 * This is set if we're going to treat the device as TV-out. @@ -1064,6 +1065,15 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,  	multiplier = intel_sdvo_get_pixel_multiplier(adjusted_mode);  	intel_mode_set_pixel_multiplier(adjusted_mode, multiplier); +	if (intel_sdvo->color_range_auto) { +		/* See CEA-861-E - 5.1 Default Encoding Parameters */ +		if (intel_sdvo->has_hdmi_monitor && +		    drm_mode_cea_vic(adjusted_mode) > 1) +			intel_sdvo->color_range = SDVO_COLOR_RANGE_16_235; +		else +			intel_sdvo->color_range = 0; +	} +  	if (intel_sdvo->color_range)  		adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE; @@ -1900,10 +1910,21 @@ intel_sdvo_set_property(struct drm_connector *connector,  	}  	if (property == dev_priv->broadcast_rgb_property) { -		if (val == !!intel_sdvo->color_range) -			return 0; - -		intel_sdvo->color_range = val ? SDVO_COLOR_RANGE_16_235 : 0; +		switch (val) { +		case INTEL_BROADCAST_RGB_AUTO: +			intel_sdvo->color_range_auto = true; +			break; +		case INTEL_BROADCAST_RGB_FULL: +			intel_sdvo->color_range_auto = false; +			intel_sdvo->color_range = 0; +			break; +		case INTEL_BROADCAST_RGB_LIMITED: +			intel_sdvo->color_range_auto = false; +			intel_sdvo->color_range = SDVO_COLOR_RANGE_16_235; +			break; +		default: +			return -EINVAL; +		}  		goto done;  	} @@ -2200,13 +2221,16 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector,  }  static void -intel_sdvo_add_hdmi_properties(struct intel_sdvo_connector *connector) +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_INFO(dev)->gen >= 4 && IS_MOBILE(dev)) {  		intel_attach_broadcast_rgb_property(&connector->base.base); +		intel_sdvo->color_range_auto = true; +	}  }  static bool @@ -2254,7 +2278,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)  	intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);  	if (intel_sdvo->is_hdmi) -		intel_sdvo_add_hdmi_properties(intel_sdvo_connector); +		intel_sdvo_add_hdmi_properties(intel_sdvo, intel_sdvo_connector);  	return true;  }  |