aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2013-01-17 09:31:29 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-01-20 07:09:44 -0500
commit55bc60db5988c8366751d3d04dd690698a53412c (patch)
tree1fc546713d825d8b2892d2b113f36c965008f7f1
parent3685a8f38f2c54bb6058c0e66ae0562f8ab84e66 (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.h4
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c32
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c29
-rw-r--r--drivers/gpu/drm/i915/intel_modes.c5
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c38
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
969void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, 990void 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
102static const struct drm_prop_enum_list broadcast_rgb_names[] = { 102static 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
107void 108void
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
2202static void 2223static void
2203intel_sdvo_add_hdmi_properties(struct intel_sdvo_connector *connector) 2224intel_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
2212static bool 2236static 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}