From 3f704fa2778d3fe45e6529825a5c7a8bcbc686f4 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Mon, 8 Apr 2013 15:48:07 -0300 Subject: [PATCH] drm/i915: set CPT FDI RX polarity bits based on VBT Check the VBT to see if the machine has inverted FDI RX polarity on CPT. Based on this bit, set the appropriate bit on the TRANS_CHICKEN2 registers. This should fix some machines that were showing black screens on all outputs. Cc: stable@vger.kernel.org Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=60029 Signed-off-by: Paulo Zanoni Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_reg.h | 2 +- drivers/gpu/drm/i915/intel_bios.c | 6 ++++-- drivers/gpu/drm/i915/intel_bios.h | 4 +++- drivers/gpu/drm/i915/intel_pm.c | 9 +++++++-- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9b85fcdb3918..d5dcf7fe1ee9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -976,6 +976,7 @@ typedef struct drm_i915_private { unsigned int int_crt_support:1; unsigned int lvds_use_ssc:1; unsigned int display_clock_mode:1; + unsigned int fdi_rx_polarity_inverted:1; int lvds_ssc_freq; unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */ struct { diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 077d40f37b97..fc8a4a940e92 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3960,7 +3960,7 @@ #define _TRANSB_CHICKEN2 0xf1064 #define TRANS_CHICKEN2(pipe) _PIPE(pipe, _TRANSA_CHICKEN2, _TRANSB_CHICKEN2) #define TRANS_CHICKEN2_TIMING_OVERRIDE (1<<31) - +#define TRANS_CHICKEN2_FDI_POLARITY_REVERSED (1<<29) #define SOUTH_CHICKEN1 0xc2000 #define FDIA_PHASE_SYNC_SHIFT_OVR 19 diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 194df27c89eb..95070b2124c6 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -351,12 +351,14 @@ parse_general_features(struct drm_i915_private *dev_priv, dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, general->ssc_freq); dev_priv->display_clock_mode = general->display_clock_mode; - DRM_DEBUG_KMS("BDB_GENERAL_FEATURES int_tv_support %d int_crt_support %d lvds_use_ssc %d lvds_ssc_freq %d display_clock_mode %d\n", + dev_priv->fdi_rx_polarity_inverted = general->fdi_rx_polarity_inverted; + DRM_DEBUG_KMS("BDB_GENERAL_FEATURES int_tv_support %d int_crt_support %d lvds_use_ssc %d lvds_ssc_freq %d display_clock_mode %d fdi_rx_polarity_inverted %d\n", dev_priv->int_tv_support, dev_priv->int_crt_support, dev_priv->lvds_use_ssc, dev_priv->lvds_ssc_freq, - dev_priv->display_clock_mode); + dev_priv->display_clock_mode, + dev_priv->fdi_rx_polarity_inverted); } } diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index 36e57f934373..e088d6f0956a 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -127,7 +127,9 @@ struct bdb_general_features { /* bits 3 */ u8 disable_smooth_vision:1; u8 single_dvi:1; - u8 rsvd9:6; /* finish byte */ + u8 rsvd9:1; + u8 fdi_rx_polarity_inverted:1; + u8 rsvd10:4; /* finish byte */ /* bits 4 */ u8 legacy_monitor_detect; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index f747cb036d8c..6f67fa122f81 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3590,6 +3590,7 @@ static void cpt_init_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int pipe; + uint32_t val; /* * On Ibex Peak and Cougar Point, we need to disable clock @@ -3602,8 +3603,12 @@ static void cpt_init_clock_gating(struct drm_device *dev) /* The below fixes the weird display corruption, a few pixels shifted * downward, on (only) LVDS of some HP laptops with IVY. */ - for_each_pipe(pipe) - I915_WRITE(TRANS_CHICKEN2(pipe), TRANS_CHICKEN2_TIMING_OVERRIDE); + for_each_pipe(pipe) { + val = TRANS_CHICKEN2_TIMING_OVERRIDE; + if (dev_priv->fdi_rx_polarity_inverted) + val |= TRANS_CHICKEN2_FDI_POLARITY_REVERSED; + I915_WRITE(TRANS_CHICKEN2(pipe), val); + } /* WADP0ClockGatingDisable */ for_each_pipe(pipe) { I915_WRITE(TRANS_CHICKEN1(pipe), -- 2.39.5