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 852012b6fc5b..4bad0f724019 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[] = { | |||
138 | DDI_BUF_EMP_800MV_3_5DB_HSW | 138 | DDI_BUF_EMP_800MV_3_5DB_HSW |
139 | }; | 139 | }; |
140 | 140 | ||
141 | static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, | ||
142 | enum port port) | ||
143 | { | ||
144 | uint32_t reg = DDI_BUF_CTL(port); | ||
145 | int i; | ||
146 | |||
147 | for (i = 0; i < 8; i++) { | ||
148 | udelay(1); | ||
149 | if (I915_READ(reg) & DDI_BUF_IS_IDLE) | ||
150 | return; | ||
151 | } | ||
152 | DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port)); | ||
153 | } | ||
141 | 154 | ||
142 | /* Starting with Haswell, different DDI ports can work in FDI mode for | 155 | /* Starting with Haswell, different DDI ports can work in FDI mode for |
143 | * connection to the PCH-located connectors. For this, it is necessary to train | 156 | * 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) | |||
167 | /* Enable the PCH Receiver FDI PLL */ | 180 | /* Enable the PCH Receiver FDI PLL */ |
168 | rx_ctl_val = FDI_RX_PLL_ENABLE | FDI_RX_ENHANCE_FRAME_ENABLE | | 181 | rx_ctl_val = FDI_RX_PLL_ENABLE | FDI_RX_ENHANCE_FRAME_ENABLE | |
169 | ((intel_crtc->fdi_lanes - 1) << 19); | 182 | ((intel_crtc->fdi_lanes - 1) << 19); |
183 | if (dev_priv->fdi_rx_polarity_reversed) | ||
184 | rx_ctl_val |= FDI_RX_POLARITY_REVERSED_LPT; | ||
170 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); | 185 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
171 | POSTING_READ(_FDI_RXA_CTL); | 186 | POSTING_READ(_FDI_RXA_CTL); |
172 | udelay(220); | 187 | udelay(220); |
@@ -231,18 +246,30 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) | |||
231 | return; | 246 | return; |
232 | } | 247 | } |
233 | 248 | ||
249 | temp = I915_READ(DDI_BUF_CTL(PORT_E)); | ||
250 | temp &= ~DDI_BUF_CTL_ENABLE; | ||
251 | I915_WRITE(DDI_BUF_CTL(PORT_E), temp); | ||
252 | POSTING_READ(DDI_BUF_CTL(PORT_E)); | ||
253 | |||
234 | /* Disable DP_TP_CTL and FDI_RX_CTL and retry */ | 254 | /* Disable DP_TP_CTL and FDI_RX_CTL and retry */ |
235 | I915_WRITE(DP_TP_CTL(PORT_E), | 255 | temp = I915_READ(DP_TP_CTL(PORT_E)); |
236 | I915_READ(DP_TP_CTL(PORT_E)) & ~DP_TP_CTL_ENABLE); | 256 | temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); |
257 | temp |= DP_TP_CTL_LINK_TRAIN_PAT1; | ||
258 | I915_WRITE(DP_TP_CTL(PORT_E), temp); | ||
259 | POSTING_READ(DP_TP_CTL(PORT_E)); | ||
260 | |||
261 | intel_wait_ddi_buf_idle(dev_priv, PORT_E); | ||
237 | 262 | ||
238 | rx_ctl_val &= ~FDI_RX_ENABLE; | 263 | rx_ctl_val &= ~FDI_RX_ENABLE; |
239 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); | 264 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
265 | POSTING_READ(_FDI_RXA_CTL); | ||
240 | 266 | ||
241 | /* Reset FDI_RX_MISC pwrdn lanes */ | 267 | /* Reset FDI_RX_MISC pwrdn lanes */ |
242 | temp = I915_READ(_FDI_RXA_MISC); | 268 | temp = I915_READ(_FDI_RXA_MISC); |
243 | temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); | 269 | temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
244 | temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2); | 270 | temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2); |
245 | I915_WRITE(_FDI_RXA_MISC, temp); | 271 | I915_WRITE(_FDI_RXA_MISC, temp); |
272 | POSTING_READ(_FDI_RXA_MISC); | ||
246 | } | 273 | } |
247 | 274 | ||
248 | DRM_ERROR("FDI link training failed!\n"); | 275 | DRM_ERROR("FDI link training failed!\n"); |
@@ -1222,20 +1249,6 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) | |||
1222 | } | 1249 | } |
1223 | } | 1250 | } |
1224 | 1251 | ||
1225 | static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, | ||
1226 | enum port port) | ||
1227 | { | ||
1228 | uint32_t reg = DDI_BUF_CTL(port); | ||
1229 | int i; | ||
1230 | |||
1231 | for (i = 0; i < 8; i++) { | ||
1232 | udelay(1); | ||
1233 | if (I915_READ(reg) & DDI_BUF_IS_IDLE) | ||
1234 | return; | ||
1235 | } | ||
1236 | DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port)); | ||
1237 | } | ||
1238 | |||
1239 | static void intel_ddi_post_disable(struct intel_encoder *intel_encoder) | 1252 | static void intel_ddi_post_disable(struct intel_encoder *intel_encoder) |
1240 | { | 1253 | { |
1241 | struct drm_encoder *encoder = &intel_encoder->base; | 1254 | struct drm_encoder *encoder = &intel_encoder->base; |