diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_hdmi.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_modes.c | 30 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 20 |
7 files changed, 82 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6b86e83ae128..3d4fd0181f65 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -707,6 +707,8 @@ typedef struct drm_i915_private { | |||
707 | 707 | ||
708 | /* list of fbdev register on this device */ | 708 | /* list of fbdev register on this device */ |
709 | struct intel_fbdev *fbdev; | 709 | struct intel_fbdev *fbdev; |
710 | |||
711 | struct drm_property *broadcast_rgb_property; | ||
710 | } drm_i915_private_t; | 712 | } drm_i915_private_t; |
711 | 713 | ||
712 | struct drm_i915_gem_object { | 714 | struct drm_i915_gem_object { |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 139d15234ffb..63ed072e5fe3 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -1387,6 +1387,7 @@ | |||
1387 | #define SDVO_ENCODING_HDMI (0x2 << 10) | 1387 | #define SDVO_ENCODING_HDMI (0x2 << 10) |
1388 | /** Requird for HDMI operation */ | 1388 | /** Requird for HDMI operation */ |
1389 | #define SDVO_NULL_PACKETS_DURING_VSYNC (1 << 9) | 1389 | #define SDVO_NULL_PACKETS_DURING_VSYNC (1 << 9) |
1390 | #define SDVO_COLOR_RANGE_16_235 (1 << 8) | ||
1390 | #define SDVO_BORDER_ENABLE (1 << 7) | 1391 | #define SDVO_BORDER_ENABLE (1 << 7) |
1391 | #define SDVO_AUDIO_ENABLE (1 << 6) | 1392 | #define SDVO_AUDIO_ENABLE (1 << 6) |
1392 | /** New with 965, default is to be set */ | 1393 | /** New with 965, default is to be set */ |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 7ffb324b6a7d..3216adcf54d2 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -49,6 +49,7 @@ struct intel_dp { | |||
49 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; | 49 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; |
50 | bool has_audio; | 50 | bool has_audio; |
51 | int force_audio; | 51 | int force_audio; |
52 | uint32_t color_range; | ||
52 | int dpms_mode; | 53 | int dpms_mode; |
53 | uint8_t link_bw; | 54 | uint8_t link_bw; |
54 | uint8_t lane_count; | 55 | uint8_t lane_count; |
@@ -741,8 +742,8 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
741 | struct drm_crtc *crtc = intel_dp->base.base.crtc; | 742 | struct drm_crtc *crtc = intel_dp->base.base.crtc; |
742 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 743 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
743 | 744 | ||
744 | intel_dp->DP = (DP_VOLTAGE_0_4 | | 745 | intel_dp->DP = DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; |
745 | DP_PRE_EMPHASIS_0); | 746 | intel_dp->DP |= intel_dp->color_range; |
746 | 747 | ||
747 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 748 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
748 | intel_dp->DP |= DP_SYNC_HS_HIGH; | 749 | intel_dp->DP |= DP_SYNC_HS_HIGH; |
@@ -1680,6 +1681,7 @@ intel_dp_set_property(struct drm_connector *connector, | |||
1680 | struct drm_property *property, | 1681 | struct drm_property *property, |
1681 | uint64_t val) | 1682 | uint64_t val) |
1682 | { | 1683 | { |
1684 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | ||
1683 | struct intel_dp *intel_dp = intel_attached_dp(connector); | 1685 | struct intel_dp *intel_dp = intel_attached_dp(connector); |
1684 | int ret; | 1686 | int ret; |
1685 | 1687 | ||
@@ -1708,6 +1710,14 @@ intel_dp_set_property(struct drm_connector *connector, | |||
1708 | goto done; | 1710 | goto done; |
1709 | } | 1711 | } |
1710 | 1712 | ||
1713 | if (property == dev_priv->broadcast_rgb_property) { | ||
1714 | if (val == !!intel_dp->color_range) | ||
1715 | return 0; | ||
1716 | |||
1717 | intel_dp->color_range = val ? DP_COLOR_RANGE_16_235 : 0; | ||
1718 | goto done; | ||
1719 | } | ||
1720 | |||
1711 | return -EINVAL; | 1721 | return -EINVAL; |
1712 | 1722 | ||
1713 | done: | 1723 | done: |
@@ -1827,6 +1837,8 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect | |||
1827 | intel_dp->force_audio_property->values[1] = 1; | 1837 | intel_dp->force_audio_property->values[1] = 1; |
1828 | drm_connector_attach_property(connector, intel_dp->force_audio_property, 0); | 1838 | drm_connector_attach_property(connector, intel_dp->force_audio_property, 0); |
1829 | } | 1839 | } |
1840 | |||
1841 | intel_attach_broadcast_rgb_property(connector); | ||
1830 | } | 1842 | } |
1831 | 1843 | ||
1832 | void | 1844 | void |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 08cd27d2c132..5daa991cb287 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -237,6 +237,8 @@ struct intel_unpin_work { | |||
237 | int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); | 237 | int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); |
238 | extern bool intel_ddc_probe(struct intel_encoder *intel_encoder, int ddc_bus); | 238 | extern bool intel_ddc_probe(struct intel_encoder *intel_encoder, int ddc_bus); |
239 | 239 | ||
240 | extern void intel_attach_broadcast_rgb_property(struct drm_connector *connector); | ||
241 | |||
240 | extern void intel_crt_init(struct drm_device *dev); | 242 | extern void intel_crt_init(struct drm_device *dev); |
241 | extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg); | 243 | extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg); |
242 | void intel_dip_infoframe_csum(struct dip_infoframe *avi_if); | 244 | void intel_dip_infoframe_csum(struct dip_infoframe *avi_if); |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index c635c9e357b9..f289b8642976 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -41,6 +41,7 @@ struct intel_hdmi { | |||
41 | struct intel_encoder base; | 41 | struct intel_encoder base; |
42 | u32 sdvox_reg; | 42 | u32 sdvox_reg; |
43 | int ddc_bus; | 43 | int ddc_bus; |
44 | uint32_t color_range; | ||
44 | bool has_hdmi_sink; | 45 | bool has_hdmi_sink; |
45 | bool has_audio; | 46 | bool has_audio; |
46 | int force_audio; | 47 | int force_audio; |
@@ -124,6 +125,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
124 | u32 sdvox; | 125 | u32 sdvox; |
125 | 126 | ||
126 | sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE; | 127 | sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE; |
128 | sdvox |= intel_hdmi->color_range; | ||
127 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) | 129 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) |
128 | sdvox |= SDVO_VSYNC_ACTIVE_HIGH; | 130 | sdvox |= SDVO_VSYNC_ACTIVE_HIGH; |
129 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 131 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
@@ -278,6 +280,7 @@ intel_hdmi_set_property(struct drm_connector *connector, | |||
278 | uint64_t val) | 280 | uint64_t val) |
279 | { | 281 | { |
280 | struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); | 282 | struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); |
283 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | ||
281 | int ret; | 284 | int ret; |
282 | 285 | ||
283 | ret = drm_connector_property_set_value(connector, property, val); | 286 | ret = drm_connector_property_set_value(connector, property, val); |
@@ -305,6 +308,14 @@ intel_hdmi_set_property(struct drm_connector *connector, | |||
305 | goto done; | 308 | goto done; |
306 | } | 309 | } |
307 | 310 | ||
311 | if (property == dev_priv->broadcast_rgb_property) { | ||
312 | if (val == !!intel_hdmi->color_range) | ||
313 | return 0; | ||
314 | |||
315 | intel_hdmi->color_range = val ? SDVO_COLOR_RANGE_16_235 : 0; | ||
316 | goto done; | ||
317 | } | ||
318 | |||
308 | return -EINVAL; | 319 | return -EINVAL; |
309 | 320 | ||
310 | done: | 321 | done: |
@@ -363,6 +374,8 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *c | |||
363 | intel_hdmi->force_audio_property->values[1] = 1; | 374 | intel_hdmi->force_audio_property->values[1] = 1; |
364 | drm_connector_attach_property(connector, intel_hdmi->force_audio_property, 0); | 375 | drm_connector_attach_property(connector, intel_hdmi->force_audio_property, 0); |
365 | } | 376 | } |
377 | |||
378 | intel_attach_broadcast_rgb_property(connector); | ||
366 | } | 379 | } |
367 | 380 | ||
368 | void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | 381 | void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) |
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index f70b7cf32bff..9034dd8f33c7 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c | |||
@@ -80,3 +80,33 @@ int intel_ddc_get_modes(struct drm_connector *connector, | |||
80 | 80 | ||
81 | return ret; | 81 | return ret; |
82 | } | 82 | } |
83 | |||
84 | static const char *broadcast_rgb_names[] = { | ||
85 | "Full", | ||
86 | "Limited 16:235", | ||
87 | }; | ||
88 | |||
89 | void | ||
90 | intel_attach_broadcast_rgb_property(struct drm_connector *connector) | ||
91 | { | ||
92 | struct drm_device *dev = connector->dev; | ||
93 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
94 | struct drm_property *prop; | ||
95 | int i; | ||
96 | |||
97 | prop = dev_priv->broadcast_rgb_property; | ||
98 | if (prop == NULL) { | ||
99 | prop = drm_property_create(dev, DRM_MODE_PROP_ENUM, | ||
100 | "Broadcast RGB", | ||
101 | ARRAY_SIZE(broadcast_rgb_names)); | ||
102 | if (prop == NULL) | ||
103 | return; | ||
104 | |||
105 | for (i = 0; i < ARRAY_SIZE(broadcast_rgb_names); i++) | ||
106 | drm_property_add_enum(prop, i, i, broadcast_rgb_names[i]); | ||
107 | |||
108 | dev_priv->broadcast_rgb_property = prop; | ||
109 | } | ||
110 | |||
111 | drm_connector_attach_property(connector, prop, 0); | ||
112 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 19c817a2df0c..9698e91f6a37 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -93,6 +93,12 @@ struct intel_sdvo { | |||
93 | uint16_t attached_output; | 93 | uint16_t attached_output; |
94 | 94 | ||
95 | /** | 95 | /** |
96 | * This is used to select the color range of RBG outputs in HDMI mode. | ||
97 | * It is only valid when using TMDS encoding and 8 bit per color mode. | ||
98 | */ | ||
99 | uint32_t color_range; | ||
100 | |||
101 | /** | ||
96 | * This is set if we're going to treat the device as TV-out. | 102 | * This is set if we're going to treat the device as TV-out. |
97 | * | 103 | * |
98 | * While we have these nice friendly flags for output types that ought | 104 | * While we have these nice friendly flags for output types that ought |
@@ -1056,6 +1062,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1056 | /* Set the SDVO control regs. */ | 1062 | /* Set the SDVO control regs. */ |
1057 | if (INTEL_INFO(dev)->gen >= 4) { | 1063 | if (INTEL_INFO(dev)->gen >= 4) { |
1058 | sdvox = 0; | 1064 | sdvox = 0; |
1065 | if (intel_sdvo->is_hdmi) | ||
1066 | sdvox |= intel_sdvo->color_range; | ||
1059 | if (INTEL_INFO(dev)->gen < 5) | 1067 | if (INTEL_INFO(dev)->gen < 5) |
1060 | sdvox |= SDVO_BORDER_ENABLE; | 1068 | sdvox |= SDVO_BORDER_ENABLE; |
1061 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) | 1069 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) |
@@ -1695,6 +1703,7 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
1695 | { | 1703 | { |
1696 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); | 1704 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); |
1697 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); | 1705 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1706 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | ||
1698 | uint16_t temp_value; | 1707 | uint16_t temp_value; |
1699 | uint8_t cmd; | 1708 | uint8_t cmd; |
1700 | int ret; | 1709 | int ret; |
@@ -1724,6 +1733,14 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
1724 | goto done; | 1733 | goto done; |
1725 | } | 1734 | } |
1726 | 1735 | ||
1736 | if (property == dev_priv->broadcast_rgb_property) { | ||
1737 | if (val == !!intel_sdvo->color_range) | ||
1738 | return 0; | ||
1739 | |||
1740 | intel_sdvo->color_range = val ? SDVO_COLOR_RANGE_16_235 : 0; | ||
1741 | goto done; | ||
1742 | } | ||
1743 | |||
1727 | #define CHECK_PROPERTY(name, NAME) \ | 1744 | #define CHECK_PROPERTY(name, NAME) \ |
1728 | if (intel_sdvo_connector->name == property) { \ | 1745 | if (intel_sdvo_connector->name == property) { \ |
1729 | if (intel_sdvo_connector->cur_##name == temp_value) return 0; \ | 1746 | if (intel_sdvo_connector->cur_##name == temp_value) return 0; \ |
@@ -2028,6 +2045,9 @@ intel_sdvo_add_hdmi_properties(struct intel_sdvo_connector *connector) | |||
2028 | drm_connector_attach_property(&connector->base.base, | 2045 | drm_connector_attach_property(&connector->base.base, |
2029 | connector->force_audio_property, 0); | 2046 | connector->force_audio_property, 0); |
2030 | } | 2047 | } |
2048 | |||
2049 | if (INTEL_INFO(dev)->gen >= 4 && IS_MOBILE(dev)) | ||
2050 | intel_attach_broadcast_rgb_property(&connector->base.base); | ||
2031 | } | 2051 | } |
2032 | 2052 | ||
2033 | static bool | 2053 | static bool |