aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_dp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c79
1 files changed, 38 insertions, 41 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 9caccd03dccb..9ab8708ac6ba 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -239,7 +239,6 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
239 uint32_t ch_data = ch_ctl + 4; 239 uint32_t ch_data = ch_ctl + 4;
240 int i; 240 int i;
241 int recv_bytes; 241 int recv_bytes;
242 uint32_t ctl;
243 uint32_t status; 242 uint32_t status;
244 uint32_t aux_clock_divider; 243 uint32_t aux_clock_divider;
245 int try, precharge; 244 int try, precharge;
@@ -263,41 +262,43 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
263 else 262 else
264 precharge = 5; 263 precharge = 5;
265 264
265 if (I915_READ(ch_ctl) & DP_AUX_CH_CTL_SEND_BUSY) {
266 DRM_ERROR("dp_aux_ch not started status 0x%08x\n",
267 I915_READ(ch_ctl));
268 return -EBUSY;
269 }
270
266 /* Must try at least 3 times according to DP spec */ 271 /* Must try at least 3 times according to DP spec */
267 for (try = 0; try < 5; try++) { 272 for (try = 0; try < 5; try++) {
268 /* Load the send data into the aux channel data registers */ 273 /* Load the send data into the aux channel data registers */
269 for (i = 0; i < send_bytes; i += 4) { 274 for (i = 0; i < send_bytes; i += 4)
270 uint32_t d = pack_aux(send + i, send_bytes - i); 275 I915_WRITE(ch_data + i,
271 276 pack_aux(send + i, send_bytes - i));
272 I915_WRITE(ch_data + i, d);
273 }
274
275 ctl = (DP_AUX_CH_CTL_SEND_BUSY |
276 DP_AUX_CH_CTL_TIME_OUT_400us |
277 (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
278 (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
279 (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) |
280 DP_AUX_CH_CTL_DONE |
281 DP_AUX_CH_CTL_TIME_OUT_ERROR |
282 DP_AUX_CH_CTL_RECEIVE_ERROR);
283 277
284 /* Send the command and wait for it to complete */ 278 /* Send the command and wait for it to complete */
285 I915_WRITE(ch_ctl, ctl); 279 I915_WRITE(ch_ctl,
286 (void) I915_READ(ch_ctl); 280 DP_AUX_CH_CTL_SEND_BUSY |
281 DP_AUX_CH_CTL_TIME_OUT_400us |
282 (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
283 (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
284 (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) |
285 DP_AUX_CH_CTL_DONE |
286 DP_AUX_CH_CTL_TIME_OUT_ERROR |
287 DP_AUX_CH_CTL_RECEIVE_ERROR);
287 for (;;) { 288 for (;;) {
288 udelay(100);
289 status = I915_READ(ch_ctl); 289 status = I915_READ(ch_ctl);
290 if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) 290 if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0)
291 break; 291 break;
292 udelay(100);
292 } 293 }
293 294
294 /* Clear done status and any errors */ 295 /* Clear done status and any errors */
295 I915_WRITE(ch_ctl, (status | 296 I915_WRITE(ch_ctl,
296 DP_AUX_CH_CTL_DONE | 297 status |
297 DP_AUX_CH_CTL_TIME_OUT_ERROR | 298 DP_AUX_CH_CTL_DONE |
298 DP_AUX_CH_CTL_RECEIVE_ERROR)); 299 DP_AUX_CH_CTL_TIME_OUT_ERROR |
299 (void) I915_READ(ch_ctl); 300 DP_AUX_CH_CTL_RECEIVE_ERROR);
300 if ((status & DP_AUX_CH_CTL_TIME_OUT_ERROR) == 0) 301 if (status & DP_AUX_CH_CTL_DONE)
301 break; 302 break;
302 } 303 }
303 304
@@ -324,15 +325,12 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
324 /* Unload any bytes sent back from the other side */ 325 /* Unload any bytes sent back from the other side */
325 recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >> 326 recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >>
326 DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT); 327 DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT);
327
328 if (recv_bytes > recv_size) 328 if (recv_bytes > recv_size)
329 recv_bytes = recv_size; 329 recv_bytes = recv_size;
330 330
331 for (i = 0; i < recv_bytes; i += 4) { 331 for (i = 0; i < recv_bytes; i += 4)
332 uint32_t d = I915_READ(ch_data + i); 332 unpack_aux(I915_READ(ch_data + i),
333 333 recv + i, recv_bytes - i);
334 unpack_aux(d, recv + i, recv_bytes - i);
335 }
336 334
337 return recv_bytes; 335 return recv_bytes;
338} 336}
@@ -1140,18 +1138,14 @@ static bool
1140intel_dp_set_link_train(struct intel_dp *intel_dp, 1138intel_dp_set_link_train(struct intel_dp *intel_dp,
1141 uint32_t dp_reg_value, 1139 uint32_t dp_reg_value,
1142 uint8_t dp_train_pat, 1140 uint8_t dp_train_pat,
1143 uint8_t train_set[4], 1141 uint8_t train_set[4])
1144 bool first)
1145{ 1142{
1146 struct drm_device *dev = intel_dp->base.enc.dev; 1143 struct drm_device *dev = intel_dp->base.enc.dev;
1147 struct drm_i915_private *dev_priv = dev->dev_private; 1144 struct drm_i915_private *dev_priv = dev->dev_private;
1148 struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc);
1149 int ret; 1145 int ret;
1150 1146
1151 I915_WRITE(intel_dp->output_reg, dp_reg_value); 1147 I915_WRITE(intel_dp->output_reg, dp_reg_value);
1152 POSTING_READ(intel_dp->output_reg); 1148 POSTING_READ(intel_dp->output_reg);
1153 if (first)
1154 intel_wait_for_vblank(dev, intel_crtc->pipe);
1155 1149
1156 intel_dp_aux_native_write_1(intel_dp, 1150 intel_dp_aux_native_write_1(intel_dp,
1157 DP_TRAINING_PATTERN_SET, 1151 DP_TRAINING_PATTERN_SET,
@@ -1176,10 +1170,15 @@ intel_dp_link_train(struct intel_dp *intel_dp)
1176 uint8_t voltage; 1170 uint8_t voltage;
1177 bool clock_recovery = false; 1171 bool clock_recovery = false;
1178 bool channel_eq = false; 1172 bool channel_eq = false;
1179 bool first = true;
1180 int tries; 1173 int tries;
1181 u32 reg; 1174 u32 reg;
1182 uint32_t DP = intel_dp->DP; 1175 uint32_t DP = intel_dp->DP;
1176 struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc);
1177
1178 /* Enable output, wait for it to become active */
1179 I915_WRITE(intel_dp->output_reg, intel_dp->DP);
1180 POSTING_READ(intel_dp->output_reg);
1181 intel_wait_for_vblank(dev, intel_crtc->pipe);
1183 1182
1184 /* Write the link configuration data */ 1183 /* Write the link configuration data */
1185 intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, 1184 intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
@@ -1212,9 +1211,8 @@ intel_dp_link_train(struct intel_dp *intel_dp)
1212 reg = DP | DP_LINK_TRAIN_PAT_1; 1211 reg = DP | DP_LINK_TRAIN_PAT_1;
1213 1212
1214 if (!intel_dp_set_link_train(intel_dp, reg, 1213 if (!intel_dp_set_link_train(intel_dp, reg,
1215 DP_TRAINING_PATTERN_1, train_set, first)) 1214 DP_TRAINING_PATTERN_1, train_set))
1216 break; 1215 break;
1217 first = false;
1218 /* Set training pattern 1 */ 1216 /* Set training pattern 1 */
1219 1217
1220 udelay(100); 1218 udelay(100);
@@ -1268,8 +1266,7 @@ intel_dp_link_train(struct intel_dp *intel_dp)
1268 1266
1269 /* channel eq pattern */ 1267 /* channel eq pattern */
1270 if (!intel_dp_set_link_train(intel_dp, reg, 1268 if (!intel_dp_set_link_train(intel_dp, reg,
1271 DP_TRAINING_PATTERN_2, train_set, 1269 DP_TRAINING_PATTERN_2, train_set))
1272 false))
1273 break; 1270 break;
1274 1271
1275 udelay(400); 1272 udelay(400);
@@ -1388,7 +1385,7 @@ ironlake_dp_detect(struct drm_connector *connector)
1388 * \return false if DP port is disconnected. 1385 * \return false if DP port is disconnected.
1389 */ 1386 */
1390static enum drm_connector_status 1387static enum drm_connector_status
1391intel_dp_detect(struct drm_connector *connector) 1388intel_dp_detect(struct drm_connector *connector, bool force)
1392{ 1389{
1393 struct drm_encoder *encoder = intel_attached_encoder(connector); 1390 struct drm_encoder *encoder = intel_attached_encoder(connector);
1394 struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 1391 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);