aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2013-01-17 09:31:28 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-01-20 07:09:43 -0500
commit3685a8f38f2c54bb6058c0e66ae0562f8ab84e66 (patch)
treea4aef93a243338e65c7bdfbeb28c5010963b7d59
parent93d187993b783c68383a884091a600d9ad499ea6 (diff)
drm/i915: Fix RGB color range property for PCH platforms
The RGB color range select bit on the DP/SDVO/HDMI registers disappeared when PCH was introduced, and instead a new PIPECONF bit was added that performs the same function. Add a new INTEL_MODE_LIMITED_COLOR_RANGE private mode flag, and set it in the encoder mode_fixup if limited color range is requested. Set the the PIPECONF bit 13 based on the flag. Experimentation showed that simply toggling the bit while the pipe is active doesn't work. We need to restart the pipe, which luckily already happens. The DP/SDVO/HDMI bit 8 is marked MBZ in the docs, so avoid setting it, although it doesn't seem to do any harm in practice. TODO: - the PIPECONF bit too seems to have disappeared from HSW. Need a volunteer to test if it's just a documentation issue or if it's really gone. If the bit is gone and no easy replacement is found, then I suppose we may need to use the pipe CSC unit to perform the range compression. v2: Use mode private_flags instead of intel_encoder virtual functions v3: Moved the intel_dp color_range handling after bpc check to help later patches Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=46800 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_reg.h1
-rw-r--r--drivers/gpu/drm/i915/intel_display.c5
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c7
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h5
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c5
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c5
6 files changed, 26 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 4c33bd2bd4e6..2521617b55da 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2650,6 +2650,7 @@
2650#define PIPECONF_INTERLACED_DBL_ILK (4 << 21) /* ilk/snb only */ 2650#define PIPECONF_INTERLACED_DBL_ILK (4 << 21) /* ilk/snb only */
2651#define PIPECONF_PFIT_PF_INTERLACED_DBL_ILK (5 << 21) /* ilk/snb only */ 2651#define PIPECONF_PFIT_PF_INTERLACED_DBL_ILK (5 << 21) /* ilk/snb only */
2652#define PIPECONF_CXSR_DOWNCLOCK (1<<16) 2652#define PIPECONF_CXSR_DOWNCLOCK (1<<16)
2653#define PIPECONF_COLOR_RANGE_SELECT (1 << 13)
2653#define PIPECONF_BPC_MASK (0x7 << 5) 2654#define PIPECONF_BPC_MASK (0x7 << 5)
2654#define PIPECONF_8BPC (0<<5) 2655#define PIPECONF_8BPC (0<<5)
2655#define PIPECONF_10BPC (1<<5) 2656#define PIPECONF_10BPC (1<<5)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e4c5067a54d3..b35902e5d925 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5096,6 +5096,11 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc,
5096 else 5096 else
5097 val |= PIPECONF_PROGRESSIVE; 5097 val |= PIPECONF_PROGRESSIVE;
5098 5098
5099 if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE)
5100 val |= PIPECONF_COLOR_RANGE_SELECT;
5101 else
5102 val &= ~PIPECONF_COLOR_RANGE_SELECT;
5103
5099 I915_WRITE(PIPECONF(pipe), val); 5104 I915_WRITE(PIPECONF(pipe), val);
5100 POSTING_READ(PIPECONF(pipe)); 5105 POSTING_READ(PIPECONF(pipe));
5101} 5106}
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 5f12eb2d0fb5..d9956278a56e 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -763,6 +763,10 @@ intel_dp_mode_fixup(struct drm_encoder *encoder,
763 return false; 763 return false;
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
767 if (intel_dp->color_range)
768 adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE;
769
766 mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp); 770 mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp);
767 771
768 for (clock = 0; clock <= max_clock; clock++) { 772 for (clock = 0; clock <= max_clock; clock++) {
@@ -967,7 +971,8 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
967 else 971 else
968 intel_dp->DP |= DP_PLL_FREQ_270MHZ; 972 intel_dp->DP |= DP_PLL_FREQ_270MHZ;
969 } else if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) { 973 } else if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) {
970 intel_dp->DP |= intel_dp->color_range; 974 if (!HAS_PCH_SPLIT(dev))
975 intel_dp->DP |= intel_dp->color_range;
971 976
972 if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) 977 if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
973 intel_dp->DP |= DP_SYNC_HS_HIGH; 978 intel_dp->DP |= DP_SYNC_HS_HIGH;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 54a034c82061..4df47be84abd 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -109,6 +109,11 @@
109 * timings in the mode to prevent the crtc fixup from overwriting them. 109 * timings in the mode to prevent the crtc fixup from overwriting them.
110 * Currently only lvds needs that. */ 110 * Currently only lvds needs that. */
111#define INTEL_MODE_CRTC_TIMINGS_SET (0x20) 111#define INTEL_MODE_CRTC_TIMINGS_SET (0x20)
112/*
113 * Set when limited 16-235 (as opposed to full 0-255) RGB color range is
114 * to be used.
115 */
116#define INTEL_MODE_LIMITED_COLOR_RANGE (0x40)
112 117
113static inline void 118static inline void
114intel_mode_set_pixel_multiplier(struct drm_display_mode *mode, 119intel_mode_set_pixel_multiplier(struct drm_display_mode *mode,
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 6387f9b0df99..f194d756a58c 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -766,6 +766,11 @@ bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
766 const struct drm_display_mode *mode, 766 const struct drm_display_mode *mode,
767 struct drm_display_mode *adjusted_mode) 767 struct drm_display_mode *adjusted_mode)
768{ 768{
769 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
770
771 if (intel_hdmi->color_range)
772 adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE;
773
769 return true; 774 return true;
770} 775}
771 776
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 153377bed66a..3b8491af1f23 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1064,6 +1064,9 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
1064 multiplier = intel_sdvo_get_pixel_multiplier(adjusted_mode); 1064 multiplier = intel_sdvo_get_pixel_multiplier(adjusted_mode);
1065 intel_mode_set_pixel_multiplier(adjusted_mode, multiplier); 1065 intel_mode_set_pixel_multiplier(adjusted_mode, multiplier);
1066 1066
1067 if (intel_sdvo->color_range)
1068 adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE;
1069
1067 return true; 1070 return true;
1068} 1071}
1069 1072
@@ -1153,7 +1156,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
1153 /* The real mode polarity is set by the SDVO commands, using 1156 /* The real mode polarity is set by the SDVO commands, using
1154 * struct intel_sdvo_dtd. */ 1157 * struct intel_sdvo_dtd. */
1155 sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH; 1158 sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH;
1156 if (intel_sdvo->is_hdmi) 1159 if (!HAS_PCH_SPLIT(dev) && intel_sdvo->is_hdmi)
1157 sdvox |= intel_sdvo->color_range; 1160 sdvox |= intel_sdvo->color_range;
1158 if (INTEL_INFO(dev)->gen < 5) 1161 if (INTEL_INFO(dev)->gen < 5)
1159 sdvox |= SDVO_BORDER_ENABLE; 1162 sdvox |= SDVO_BORDER_ENABLE;