Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <paulo.r.zanoni@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

authored by

Paulo Zanoni and committed by
Daniel Vetter
3f704fa2 ac4c16c5

+16 -6
+1
drivers/gpu/drm/i915/i915_drv.h
··· 976 976 unsigned int int_crt_support:1; 977 977 unsigned int lvds_use_ssc:1; 978 978 unsigned int display_clock_mode:1; 979 + unsigned int fdi_rx_polarity_inverted:1; 979 980 int lvds_ssc_freq; 980 981 unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */ 981 982 struct {
+1 -1
drivers/gpu/drm/i915/i915_reg.h
··· 3960 3960 #define _TRANSB_CHICKEN2 0xf1064 3961 3961 #define TRANS_CHICKEN2(pipe) _PIPE(pipe, _TRANSA_CHICKEN2, _TRANSB_CHICKEN2) 3962 3962 #define TRANS_CHICKEN2_TIMING_OVERRIDE (1<<31) 3963 - 3963 + #define TRANS_CHICKEN2_FDI_POLARITY_REVERSED (1<<29) 3964 3964 3965 3965 #define SOUTH_CHICKEN1 0xc2000 3966 3966 #define FDIA_PHASE_SYNC_SHIFT_OVR 19
+4 -2
drivers/gpu/drm/i915/intel_bios.c
··· 351 351 dev_priv->lvds_ssc_freq = 352 352 intel_bios_ssc_frequency(dev, general->ssc_freq); 353 353 dev_priv->display_clock_mode = general->display_clock_mode; 354 - 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", 354 + dev_priv->fdi_rx_polarity_inverted = general->fdi_rx_polarity_inverted; 355 + 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", 355 356 dev_priv->int_tv_support, 356 357 dev_priv->int_crt_support, 357 358 dev_priv->lvds_use_ssc, 358 359 dev_priv->lvds_ssc_freq, 359 - dev_priv->display_clock_mode); 360 + dev_priv->display_clock_mode, 361 + dev_priv->fdi_rx_polarity_inverted); 360 362 } 361 363 } 362 364
+3 -1
drivers/gpu/drm/i915/intel_bios.h
··· 127 127 /* bits 3 */ 128 128 u8 disable_smooth_vision:1; 129 129 u8 single_dvi:1; 130 - u8 rsvd9:6; /* finish byte */ 130 + u8 rsvd9:1; 131 + u8 fdi_rx_polarity_inverted:1; 132 + u8 rsvd10:4; /* finish byte */ 131 133 132 134 /* bits 4 */ 133 135 u8 legacy_monitor_detect;
+7 -2
drivers/gpu/drm/i915/intel_pm.c
··· 3590 3590 { 3591 3591 struct drm_i915_private *dev_priv = dev->dev_private; 3592 3592 int pipe; 3593 + uint32_t val; 3593 3594 3594 3595 /* 3595 3596 * On Ibex Peak and Cougar Point, we need to disable clock ··· 3603 3602 /* The below fixes the weird display corruption, a few pixels shifted 3604 3603 * downward, on (only) LVDS of some HP laptops with IVY. 3605 3604 */ 3606 - for_each_pipe(pipe) 3607 - I915_WRITE(TRANS_CHICKEN2(pipe), TRANS_CHICKEN2_TIMING_OVERRIDE); 3605 + for_each_pipe(pipe) { 3606 + val = TRANS_CHICKEN2_TIMING_OVERRIDE; 3607 + if (dev_priv->fdi_rx_polarity_inverted) 3608 + val |= TRANS_CHICKEN2_FDI_POLARITY_REVERSED; 3609 + I915_WRITE(TRANS_CHICKEN2(pipe), val); 3610 + } 3608 3611 /* WADP0ClockGatingDisable */ 3609 3612 for_each_pipe(pipe) { 3610 3613 I915_WRITE(TRANS_CHICKEN1(pipe),