diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2013-01-17 09:31:29 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-01-20 07:09:44 -0500 |
commit | 55bc60db5988c8366751d3d04dd690698a53412c (patch) | |
tree | 1fc546713d825d8b2892d2b113f36c965008f7f1 | |
parent | 3685a8f38f2c54bb6058c0e66ae0562f8ab84e66 (diff) |
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>
-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 f3f2e5e1393f..0a2a18b8a075 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) | |||
1811 | #define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg) | 1811 | #define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg) |
1812 | #define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg) | 1812 | #define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg) |
1813 | 1813 | ||
1814 | /* "Broadcast RGB" property */ | ||
1815 | #define INTEL_BROADCAST_RGB_AUTO 0 | ||
1816 | #define INTEL_BROADCAST_RGB_FULL 1 | ||
1817 | #define INTEL_BROADCAST_RGB_LIMITED 2 | ||
1814 | 1818 | ||
1815 | #endif | 1819 | #endif |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index d9956278a56e..1492706ed087 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, | |||
764 | 764 | ||
765 | bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; | 765 | bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; |
766 | 766 | ||
767 | if (intel_dp->color_range_auto) { | ||
768 | /* | ||
769 | * See: | ||
770 | * CEA-861-E - 5.1 Default Encoding Parameters | ||
771 | * VESA DisplayPort Ver.1.2a - 5.1.1.1 Video Colorimetry | ||
772 | */ | ||
773 | if (bpp != 18 && drm_mode_cea_vic(adjusted_mode) > 1) | ||
774 | intel_dp->color_range = DP_COLOR_RANGE_16_235; | ||
775 | else | ||
776 | intel_dp->color_range = 0; | ||
777 | } | ||
778 | |||
767 | if (intel_dp->color_range) | 779 | if (intel_dp->color_range) |
768 | adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE; | 780 | adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE; |
769 | 781 | ||
@@ -2462,10 +2474,21 @@ intel_dp_set_property(struct drm_connector *connector, | |||
2462 | } | 2474 | } |
2463 | 2475 | ||
2464 | if (property == dev_priv->broadcast_rgb_property) { | 2476 | if (property == dev_priv->broadcast_rgb_property) { |
2465 | if (val == !!intel_dp->color_range) | 2477 | switch (val) { |
2466 | return 0; | 2478 | case INTEL_BROADCAST_RGB_AUTO: |
2467 | 2479 | intel_dp->color_range_auto = true; | |
2468 | intel_dp->color_range = val ? DP_COLOR_RANGE_16_235 : 0; | 2480 | break; |
2481 | case INTEL_BROADCAST_RGB_FULL: | ||
2482 | intel_dp->color_range_auto = false; | ||
2483 | intel_dp->color_range = 0; | ||
2484 | break; | ||
2485 | case INTEL_BROADCAST_RGB_LIMITED: | ||
2486 | intel_dp->color_range_auto = false; | ||
2487 | intel_dp->color_range = DP_COLOR_RANGE_16_235; | ||
2488 | break; | ||
2489 | default: | ||
2490 | return -EINVAL; | ||
2491 | } | ||
2469 | goto done; | 2492 | goto done; |
2470 | } | 2493 | } |
2471 | 2494 | ||
@@ -2606,6 +2629,7 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect | |||
2606 | 2629 | ||
2607 | intel_attach_force_audio_property(connector); | 2630 | intel_attach_force_audio_property(connector); |
2608 | intel_attach_broadcast_rgb_property(connector); | 2631 | intel_attach_broadcast_rgb_property(connector); |
2632 | intel_dp->color_range_auto = true; | ||
2609 | 2633 | ||
2610 | if (is_edp(intel_dp)) { | 2634 | if (is_edp(intel_dp)) { |
2611 | drm_mode_create_scaling_mode_property(connector->dev); | 2635 | 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 4df47be84abd..1a698c6f16e7 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -343,6 +343,7 @@ struct intel_hdmi { | |||
343 | u32 sdvox_reg; | 343 | u32 sdvox_reg; |
344 | int ddc_bus; | 344 | int ddc_bus; |
345 | uint32_t color_range; | 345 | uint32_t color_range; |
346 | bool color_range_auto; | ||
346 | bool has_hdmi_sink; | 347 | bool has_hdmi_sink; |
347 | bool has_audio; | 348 | bool has_audio; |
348 | enum hdmi_force_audio force_audio; | 349 | enum hdmi_force_audio force_audio; |
@@ -362,6 +363,7 @@ struct intel_dp { | |||
362 | bool has_audio; | 363 | bool has_audio; |
363 | enum hdmi_force_audio force_audio; | 364 | enum hdmi_force_audio force_audio; |
364 | uint32_t color_range; | 365 | uint32_t color_range; |
366 | bool color_range_auto; | ||
365 | uint8_t link_bw; | 367 | uint8_t link_bw; |
366 | uint8_t lane_count; | 368 | uint8_t lane_count; |
367 | uint8_t dpcd[DP_RECEIVER_CAP_SIZE]; | 369 | 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 f194d756a58c..db67be66639b 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, | |||
768 | { | 768 | { |
769 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | 769 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
770 | 770 | ||
771 | if (intel_hdmi->color_range_auto) { | ||
772 | /* See CEA-861-E - 5.1 Default Encoding Parameters */ | ||
773 | if (intel_hdmi->has_hdmi_sink && | ||
774 | drm_mode_cea_vic(adjusted_mode) > 1) | ||
775 | intel_hdmi->color_range = SDVO_COLOR_RANGE_16_235; | ||
776 | else | ||
777 | intel_hdmi->color_range = 0; | ||
778 | } | ||
779 | |||
771 | if (intel_hdmi->color_range) | 780 | if (intel_hdmi->color_range) |
772 | adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE; | 781 | adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE; |
773 | 782 | ||
@@ -912,10 +921,21 @@ intel_hdmi_set_property(struct drm_connector *connector, | |||
912 | } | 921 | } |
913 | 922 | ||
914 | if (property == dev_priv->broadcast_rgb_property) { | 923 | if (property == dev_priv->broadcast_rgb_property) { |
915 | if (val == !!intel_hdmi->color_range) | 924 | switch (val) { |
916 | return 0; | 925 | case INTEL_BROADCAST_RGB_AUTO: |
917 | 926 | intel_hdmi->color_range_auto = true; | |
918 | intel_hdmi->color_range = val ? SDVO_COLOR_RANGE_16_235 : 0; | 927 | break; |
928 | case INTEL_BROADCAST_RGB_FULL: | ||
929 | intel_hdmi->color_range_auto = false; | ||
930 | intel_hdmi->color_range = 0; | ||
931 | break; | ||
932 | case INTEL_BROADCAST_RGB_LIMITED: | ||
933 | intel_hdmi->color_range_auto = false; | ||
934 | intel_hdmi->color_range = SDVO_COLOR_RANGE_16_235; | ||
935 | break; | ||
936 | default: | ||
937 | return -EINVAL; | ||
938 | } | ||
919 | goto done; | 939 | goto done; |
920 | } | 940 | } |
921 | 941 | ||
@@ -964,6 +984,7 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *c | |||
964 | { | 984 | { |
965 | intel_attach_force_audio_property(connector); | 985 | intel_attach_force_audio_property(connector); |
966 | intel_attach_broadcast_rgb_property(connector); | 986 | intel_attach_broadcast_rgb_property(connector); |
987 | intel_hdmi->color_range_auto = true; | ||
967 | } | 988 | } |
968 | 989 | ||
969 | void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, | 990 | 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 49249bb97485..0e860f39933d 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) | |||
100 | } | 100 | } |
101 | 101 | ||
102 | static const struct drm_prop_enum_list broadcast_rgb_names[] = { | 102 | static const struct drm_prop_enum_list broadcast_rgb_names[] = { |
103 | { 0, "Full" }, | 103 | { INTEL_BROADCAST_RGB_AUTO, "Automatic" }, |
104 | { 1, "Limited 16:235" }, | 104 | { INTEL_BROADCAST_RGB_FULL, "Full" }, |
105 | { INTEL_BROADCAST_RGB_LIMITED, "Limited 16:235" }, | ||
105 | }; | 106 | }; |
106 | 107 | ||
107 | void | 108 | void |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 3b8491af1f23..3e34a3592e32 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -103,6 +103,7 @@ struct intel_sdvo { | |||
103 | * It is only valid when using TMDS encoding and 8 bit per color mode. | 103 | * It is only valid when using TMDS encoding and 8 bit per color mode. |
104 | */ | 104 | */ |
105 | uint32_t color_range; | 105 | uint32_t color_range; |
106 | bool color_range_auto; | ||
106 | 107 | ||
107 | /** | 108 | /** |
108 | * This is set if we're going to treat the device as TV-out. | 109 | * 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, | |||
1064 | multiplier = intel_sdvo_get_pixel_multiplier(adjusted_mode); | 1065 | multiplier = intel_sdvo_get_pixel_multiplier(adjusted_mode); |
1065 | intel_mode_set_pixel_multiplier(adjusted_mode, multiplier); | 1066 | intel_mode_set_pixel_multiplier(adjusted_mode, multiplier); |
1066 | 1067 | ||
1068 | if (intel_sdvo->color_range_auto) { | ||
1069 | /* See CEA-861-E - 5.1 Default Encoding Parameters */ | ||
1070 | if (intel_sdvo->has_hdmi_monitor && | ||
1071 | drm_mode_cea_vic(adjusted_mode) > 1) | ||
1072 | intel_sdvo->color_range = SDVO_COLOR_RANGE_16_235; | ||
1073 | else | ||
1074 | intel_sdvo->color_range = 0; | ||
1075 | } | ||
1076 | |||
1067 | if (intel_sdvo->color_range) | 1077 | if (intel_sdvo->color_range) |
1068 | adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE; | 1078 | adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE; |
1069 | 1079 | ||
@@ -1900,10 +1910,21 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
1900 | } | 1910 | } |
1901 | 1911 | ||
1902 | if (property == dev_priv->broadcast_rgb_property) { | 1912 | if (property == dev_priv->broadcast_rgb_property) { |
1903 | if (val == !!intel_sdvo->color_range) | 1913 | switch (val) { |
1904 | return 0; | 1914 | case INTEL_BROADCAST_RGB_AUTO: |
1905 | 1915 | intel_sdvo->color_range_auto = true; | |
1906 | intel_sdvo->color_range = val ? SDVO_COLOR_RANGE_16_235 : 0; | 1916 | break; |
1917 | case INTEL_BROADCAST_RGB_FULL: | ||
1918 | intel_sdvo->color_range_auto = false; | ||
1919 | intel_sdvo->color_range = 0; | ||
1920 | break; | ||
1921 | case INTEL_BROADCAST_RGB_LIMITED: | ||
1922 | intel_sdvo->color_range_auto = false; | ||
1923 | intel_sdvo->color_range = SDVO_COLOR_RANGE_16_235; | ||
1924 | break; | ||
1925 | default: | ||
1926 | return -EINVAL; | ||
1927 | } | ||
1907 | goto done; | 1928 | goto done; |
1908 | } | 1929 | } |
1909 | 1930 | ||
@@ -2200,13 +2221,16 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector, | |||
2200 | } | 2221 | } |
2201 | 2222 | ||
2202 | static void | 2223 | static void |
2203 | intel_sdvo_add_hdmi_properties(struct intel_sdvo_connector *connector) | 2224 | intel_sdvo_add_hdmi_properties(struct intel_sdvo *intel_sdvo, |
2225 | struct intel_sdvo_connector *connector) | ||
2204 | { | 2226 | { |
2205 | struct drm_device *dev = connector->base.base.dev; | 2227 | struct drm_device *dev = connector->base.base.dev; |
2206 | 2228 | ||
2207 | intel_attach_force_audio_property(&connector->base.base); | 2229 | intel_attach_force_audio_property(&connector->base.base); |
2208 | if (INTEL_INFO(dev)->gen >= 4 && IS_MOBILE(dev)) | 2230 | if (INTEL_INFO(dev)->gen >= 4 && IS_MOBILE(dev)) { |
2209 | intel_attach_broadcast_rgb_property(&connector->base.base); | 2231 | intel_attach_broadcast_rgb_property(&connector->base.base); |
2232 | intel_sdvo->color_range_auto = true; | ||
2233 | } | ||
2210 | } | 2234 | } |
2211 | 2235 | ||
2212 | static bool | 2236 | static bool |
@@ -2254,7 +2278,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) | |||
2254 | 2278 | ||
2255 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); | 2279 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
2256 | if (intel_sdvo->is_hdmi) | 2280 | if (intel_sdvo->is_hdmi) |
2257 | intel_sdvo_add_hdmi_properties(intel_sdvo_connector); | 2281 | intel_sdvo_add_hdmi_properties(intel_sdvo, intel_sdvo_connector); |
2258 | 2282 | ||
2259 | return true; | 2283 | return true; |
2260 | } | 2284 | } |