diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ddi.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 45 | 
1 files changed, 29 insertions, 16 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 852012b6fc5..4bad0f72401 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -138,6 +138,19 @@ static const long hsw_ddi_buf_ctl_values[] = {  	DDI_BUF_EMP_800MV_3_5DB_HSW  }; +static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, +				    enum port port) +{ +	uint32_t reg = DDI_BUF_CTL(port); +	int i; + +	for (i = 0; i < 8; i++) { +		udelay(1); +		if (I915_READ(reg) & DDI_BUF_IS_IDLE) +			return; +	} +	DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port)); +}  /* Starting with Haswell, different DDI ports can work in FDI mode for   * connection to the PCH-located connectors. For this, it is necessary to train @@ -167,6 +180,8 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)  	/* Enable the PCH Receiver FDI PLL */  	rx_ctl_val = FDI_RX_PLL_ENABLE | FDI_RX_ENHANCE_FRAME_ENABLE |  		     ((intel_crtc->fdi_lanes - 1) << 19); +	if (dev_priv->fdi_rx_polarity_reversed) +		rx_ctl_val |= FDI_RX_POLARITY_REVERSED_LPT;  	I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);  	POSTING_READ(_FDI_RXA_CTL);  	udelay(220); @@ -231,18 +246,30 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)  			return;  		} +		temp = I915_READ(DDI_BUF_CTL(PORT_E)); +		temp &= ~DDI_BUF_CTL_ENABLE; +		I915_WRITE(DDI_BUF_CTL(PORT_E), temp); +		POSTING_READ(DDI_BUF_CTL(PORT_E)); +  		/* Disable DP_TP_CTL and FDI_RX_CTL and retry */ -		I915_WRITE(DP_TP_CTL(PORT_E), -			   I915_READ(DP_TP_CTL(PORT_E)) & ~DP_TP_CTL_ENABLE); +		temp = I915_READ(DP_TP_CTL(PORT_E)); +		temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); +		temp |= DP_TP_CTL_LINK_TRAIN_PAT1; +		I915_WRITE(DP_TP_CTL(PORT_E), temp); +		POSTING_READ(DP_TP_CTL(PORT_E)); + +		intel_wait_ddi_buf_idle(dev_priv, PORT_E);  		rx_ctl_val &= ~FDI_RX_ENABLE;  		I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); +		POSTING_READ(_FDI_RXA_CTL);  		/* Reset FDI_RX_MISC pwrdn lanes */  		temp = I915_READ(_FDI_RXA_MISC);  		temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);  		temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);  		I915_WRITE(_FDI_RXA_MISC, temp); +		POSTING_READ(_FDI_RXA_MISC);  	}  	DRM_ERROR("FDI link training failed!\n"); @@ -1222,20 +1249,6 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)  	}  } -static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, -				    enum port port) -{ -	uint32_t reg = DDI_BUF_CTL(port); -	int i; - -	for (i = 0; i < 8; i++) { -		udelay(1); -		if (I915_READ(reg) & DDI_BUF_IS_IDLE) -			return; -	} -	DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port)); -} -  static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)  {  	struct drm_encoder *encoder = &intel_encoder->base;  |