1 // SPDX-License-Identifier: MIT
2 /*
3 * Copyright © 2020 Intel Corporation
4 */
5 #include "intel_atomic.h"
6 #include "intel_ddi.h"
7 #include "intel_ddi_buf_trans.h"
8 #include "intel_display_types.h"
9 #include "intel_fdi.h"
10
11 /* units of 100MHz */
pipe_required_fdi_lanes(struct intel_crtc_state * crtc_state)12 static int pipe_required_fdi_lanes(struct intel_crtc_state *crtc_state)
13 {
14 if (crtc_state->hw.enable && crtc_state->has_pch_encoder)
15 return crtc_state->fdi_lanes;
16
17 return 0;
18 }
19
ilk_check_fdi_lanes(struct drm_device * dev,enum pipe pipe,struct intel_crtc_state * pipe_config)20 static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
21 struct intel_crtc_state *pipe_config)
22 {
23 struct drm_i915_private *dev_priv = to_i915(dev);
24 struct drm_atomic_state *state = pipe_config->uapi.state;
25 struct intel_crtc *other_crtc;
26 struct intel_crtc_state *other_crtc_state;
27
28 drm_dbg_kms(&dev_priv->drm,
29 "checking fdi config on pipe %c, lanes %i\n",
30 pipe_name(pipe), pipe_config->fdi_lanes);
31 if (pipe_config->fdi_lanes > 4) {
32 drm_dbg_kms(&dev_priv->drm,
33 "invalid fdi lane config on pipe %c: %i lanes\n",
34 pipe_name(pipe), pipe_config->fdi_lanes);
35 return -EINVAL;
36 }
37
38 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
39 if (pipe_config->fdi_lanes > 2) {
40 drm_dbg_kms(&dev_priv->drm,
41 "only 2 lanes on haswell, required: %i lanes\n",
42 pipe_config->fdi_lanes);
43 return -EINVAL;
44 } else {
45 return 0;
46 }
47 }
48
49 if (INTEL_NUM_PIPES(dev_priv) == 2)
50 return 0;
51
52 /* Ivybridge 3 pipe is really complicated */
53 switch (pipe) {
54 case PIPE_A:
55 return 0;
56 case PIPE_B:
57 if (pipe_config->fdi_lanes <= 2)
58 return 0;
59
60 other_crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_C);
61 other_crtc_state =
62 intel_atomic_get_crtc_state(state, other_crtc);
63 if (IS_ERR(other_crtc_state))
64 return PTR_ERR(other_crtc_state);
65
66 if (pipe_required_fdi_lanes(other_crtc_state) > 0) {
67 drm_dbg_kms(&dev_priv->drm,
68 "invalid shared fdi lane config on pipe %c: %i lanes\n",
69 pipe_name(pipe), pipe_config->fdi_lanes);
70 return -EINVAL;
71 }
72 return 0;
73 case PIPE_C:
74 if (pipe_config->fdi_lanes > 2) {
75 drm_dbg_kms(&dev_priv->drm,
76 "only 2 lanes on pipe %c: required %i lanes\n",
77 pipe_name(pipe), pipe_config->fdi_lanes);
78 return -EINVAL;
79 }
80
81 other_crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_B);
82 other_crtc_state =
83 intel_atomic_get_crtc_state(state, other_crtc);
84 if (IS_ERR(other_crtc_state))
85 return PTR_ERR(other_crtc_state);
86
87 if (pipe_required_fdi_lanes(other_crtc_state) > 2) {
88 drm_dbg_kms(&dev_priv->drm,
89 "fdi link B uses too many lanes to enable link C\n");
90 return -EINVAL;
91 }
92 return 0;
93 default:
94 BUG();
95 }
96 }
97
ilk_fdi_compute_config(struct intel_crtc * intel_crtc,struct intel_crtc_state * pipe_config)98 int ilk_fdi_compute_config(struct intel_crtc *intel_crtc,
99 struct intel_crtc_state *pipe_config)
100 {
101 struct drm_device *dev = intel_crtc->base.dev;
102 struct drm_i915_private *i915 = to_i915(dev);
103 const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
104 int lane, link_bw, fdi_dotclock, ret;
105 bool needs_recompute = false;
106
107 retry:
108 /* FDI is a binary signal running at ~2.7GHz, encoding
109 * each output octet as 10 bits. The actual frequency
110 * is stored as a divider into a 100MHz clock, and the
111 * mode pixel clock is stored in units of 1KHz.
112 * Hence the bw of each lane in terms of the mode signal
113 * is:
114 */
115 link_bw = intel_fdi_link_freq(i915, pipe_config);
116
117 fdi_dotclock = adjusted_mode->crtc_clock;
118
119 lane = ilk_get_lanes_required(fdi_dotclock, link_bw,
120 pipe_config->pipe_bpp);
121
122 pipe_config->fdi_lanes = lane;
123
124 intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
125 link_bw, &pipe_config->fdi_m_n, false, false);
126
127 ret = ilk_check_fdi_lanes(dev, intel_crtc->pipe, pipe_config);
128 if (ret == -EDEADLK)
129 return ret;
130
131 if (ret == -EINVAL && pipe_config->pipe_bpp > 6*3) {
132 pipe_config->pipe_bpp -= 2*3;
133 drm_dbg_kms(&i915->drm,
134 "fdi link bw constraint, reducing pipe bpp to %i\n",
135 pipe_config->pipe_bpp);
136 needs_recompute = true;
137 pipe_config->bw_constrained = true;
138
139 goto retry;
140 }
141
142 if (needs_recompute)
143 return I915_DISPLAY_CONFIG_RETRY;
144
145 return ret;
146 }
147
intel_fdi_normal_train(struct intel_crtc * crtc)148 void intel_fdi_normal_train(struct intel_crtc *crtc)
149 {
150 struct drm_device *dev = crtc->base.dev;
151 struct drm_i915_private *dev_priv = to_i915(dev);
152 enum pipe pipe = crtc->pipe;
153 i915_reg_t reg;
154 u32 temp;
155
156 /* enable normal train */
157 reg = FDI_TX_CTL(pipe);
158 temp = intel_de_read(dev_priv, reg);
159 if (IS_IVYBRIDGE(dev_priv)) {
160 temp &= ~FDI_LINK_TRAIN_NONE_IVB;
161 temp |= FDI_LINK_TRAIN_NONE_IVB | FDI_TX_ENHANCE_FRAME_ENABLE;
162 } else {
163 temp &= ~FDI_LINK_TRAIN_NONE;
164 temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
165 }
166 intel_de_write(dev_priv, reg, temp);
167
168 reg = FDI_RX_CTL(pipe);
169 temp = intel_de_read(dev_priv, reg);
170 if (HAS_PCH_CPT(dev_priv)) {
171 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
172 temp |= FDI_LINK_TRAIN_NORMAL_CPT;
173 } else {
174 temp &= ~FDI_LINK_TRAIN_NONE;
175 temp |= FDI_LINK_TRAIN_NONE;
176 }
177 intel_de_write(dev_priv, reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE);
178
179 /* wait one idle pattern time */
180 intel_de_posting_read(dev_priv, reg);
181 udelay(1000);
182
183 /* IVB wants error correction enabled */
184 if (IS_IVYBRIDGE(dev_priv))
185 intel_de_write(dev_priv, reg,
186 intel_de_read(dev_priv, reg) | FDI_FS_ERRC_ENABLE | FDI_FE_ERRC_ENABLE);
187 }
188
189 /* The FDI link training functions for ILK/Ibexpeak. */
ilk_fdi_link_train(struct intel_crtc * crtc,const struct intel_crtc_state * crtc_state)190 static void ilk_fdi_link_train(struct intel_crtc *crtc,
191 const struct intel_crtc_state *crtc_state)
192 {
193 struct drm_device *dev = crtc->base.dev;
194 struct drm_i915_private *dev_priv = to_i915(dev);
195 enum pipe pipe = crtc->pipe;
196 i915_reg_t reg;
197 u32 temp, tries;
198
199 /* FDI needs bits from pipe first */
200 assert_pipe_enabled(dev_priv, crtc_state->cpu_transcoder);
201
202 /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
203 for train result */
204 reg = FDI_RX_IMR(pipe);
205 temp = intel_de_read(dev_priv, reg);
206 temp &= ~FDI_RX_SYMBOL_LOCK;
207 temp &= ~FDI_RX_BIT_LOCK;
208 intel_de_write(dev_priv, reg, temp);
209 intel_de_read(dev_priv, reg);
210 udelay(150);
211
212 /* enable CPU FDI TX and PCH FDI RX */
213 reg = FDI_TX_CTL(pipe);
214 temp = intel_de_read(dev_priv, reg);
215 temp &= ~FDI_DP_PORT_WIDTH_MASK;
216 temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
217 temp &= ~FDI_LINK_TRAIN_NONE;
218 temp |= FDI_LINK_TRAIN_PATTERN_1;
219 intel_de_write(dev_priv, reg, temp | FDI_TX_ENABLE);
220
221 reg = FDI_RX_CTL(pipe);
222 temp = intel_de_read(dev_priv, reg);
223 temp &= ~FDI_LINK_TRAIN_NONE;
224 temp |= FDI_LINK_TRAIN_PATTERN_1;
225 intel_de_write(dev_priv, reg, temp | FDI_RX_ENABLE);
226
227 intel_de_posting_read(dev_priv, reg);
228 udelay(150);
229
230 /* Ironlake workaround, enable clock pointer after FDI enable*/
231 intel_de_write(dev_priv, FDI_RX_CHICKEN(pipe),
232 FDI_RX_PHASE_SYNC_POINTER_OVR);
233 intel_de_write(dev_priv, FDI_RX_CHICKEN(pipe),
234 FDI_RX_PHASE_SYNC_POINTER_OVR | FDI_RX_PHASE_SYNC_POINTER_EN);
235
236 reg = FDI_RX_IIR(pipe);
237 for (tries = 0; tries < 5; tries++) {
238 temp = intel_de_read(dev_priv, reg);
239 drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
240
241 if ((temp & FDI_RX_BIT_LOCK)) {
242 drm_dbg_kms(&dev_priv->drm, "FDI train 1 done.\n");
243 intel_de_write(dev_priv, reg, temp | FDI_RX_BIT_LOCK);
244 break;
245 }
246 }
247 if (tries == 5)
248 drm_err(&dev_priv->drm, "FDI train 1 fail!\n");
249
250 /* Train 2 */
251 reg = FDI_TX_CTL(pipe);
252 temp = intel_de_read(dev_priv, reg);
253 temp &= ~FDI_LINK_TRAIN_NONE;
254 temp |= FDI_LINK_TRAIN_PATTERN_2;
255 intel_de_write(dev_priv, reg, temp);
256
257 reg = FDI_RX_CTL(pipe);
258 temp = intel_de_read(dev_priv, reg);
259 temp &= ~FDI_LINK_TRAIN_NONE;
260 temp |= FDI_LINK_TRAIN_PATTERN_2;
261 intel_de_write(dev_priv, reg, temp);
262
263 intel_de_posting_read(dev_priv, reg);
264 udelay(150);
265
266 reg = FDI_RX_IIR(pipe);
267 for (tries = 0; tries < 5; tries++) {
268 temp = intel_de_read(dev_priv, reg);
269 drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
270
271 if (temp & FDI_RX_SYMBOL_LOCK) {
272 intel_de_write(dev_priv, reg,
273 temp | FDI_RX_SYMBOL_LOCK);
274 drm_dbg_kms(&dev_priv->drm, "FDI train 2 done.\n");
275 break;
276 }
277 }
278 if (tries == 5)
279 drm_err(&dev_priv->drm, "FDI train 2 fail!\n");
280
281 drm_dbg_kms(&dev_priv->drm, "FDI train done\n");
282
283 }
284
285 static const int snb_b_fdi_train_param[] = {
286 FDI_LINK_TRAIN_400MV_0DB_SNB_B,
287 FDI_LINK_TRAIN_400MV_6DB_SNB_B,
288 FDI_LINK_TRAIN_600MV_3_5DB_SNB_B,
289 FDI_LINK_TRAIN_800MV_0DB_SNB_B,
290 };
291
292 /* The FDI link training functions for SNB/Cougarpoint. */
gen6_fdi_link_train(struct intel_crtc * crtc,const struct intel_crtc_state * crtc_state)293 static void gen6_fdi_link_train(struct intel_crtc *crtc,
294 const struct intel_crtc_state *crtc_state)
295 {
296 struct drm_device *dev = crtc->base.dev;
297 struct drm_i915_private *dev_priv = to_i915(dev);
298 enum pipe pipe = crtc->pipe;
299 i915_reg_t reg;
300 u32 temp, i, retry;
301
302 /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
303 for train result */
304 reg = FDI_RX_IMR(pipe);
305 temp = intel_de_read(dev_priv, reg);
306 temp &= ~FDI_RX_SYMBOL_LOCK;
307 temp &= ~FDI_RX_BIT_LOCK;
308 intel_de_write(dev_priv, reg, temp);
309
310 intel_de_posting_read(dev_priv, reg);
311 udelay(150);
312
313 /* enable CPU FDI TX and PCH FDI RX */
314 reg = FDI_TX_CTL(pipe);
315 temp = intel_de_read(dev_priv, reg);
316 temp &= ~FDI_DP_PORT_WIDTH_MASK;
317 temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
318 temp &= ~FDI_LINK_TRAIN_NONE;
319 temp |= FDI_LINK_TRAIN_PATTERN_1;
320 temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
321 /* SNB-B */
322 temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
323 intel_de_write(dev_priv, reg, temp | FDI_TX_ENABLE);
324
325 intel_de_write(dev_priv, FDI_RX_MISC(pipe),
326 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
327
328 reg = FDI_RX_CTL(pipe);
329 temp = intel_de_read(dev_priv, reg);
330 if (HAS_PCH_CPT(dev_priv)) {
331 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
332 temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
333 } else {
334 temp &= ~FDI_LINK_TRAIN_NONE;
335 temp |= FDI_LINK_TRAIN_PATTERN_1;
336 }
337 intel_de_write(dev_priv, reg, temp | FDI_RX_ENABLE);
338
339 intel_de_posting_read(dev_priv, reg);
340 udelay(150);
341
342 for (i = 0; i < 4; i++) {
343 reg = FDI_TX_CTL(pipe);
344 temp = intel_de_read(dev_priv, reg);
345 temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
346 temp |= snb_b_fdi_train_param[i];
347 intel_de_write(dev_priv, reg, temp);
348
349 intel_de_posting_read(dev_priv, reg);
350 udelay(500);
351
352 for (retry = 0; retry < 5; retry++) {
353 reg = FDI_RX_IIR(pipe);
354 temp = intel_de_read(dev_priv, reg);
355 drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
356 if (temp & FDI_RX_BIT_LOCK) {
357 intel_de_write(dev_priv, reg,
358 temp | FDI_RX_BIT_LOCK);
359 drm_dbg_kms(&dev_priv->drm,
360 "FDI train 1 done.\n");
361 break;
362 }
363 udelay(50);
364 }
365 if (retry < 5)
366 break;
367 }
368 if (i == 4)
369 drm_err(&dev_priv->drm, "FDI train 1 fail!\n");
370
371 /* Train 2 */
372 reg = FDI_TX_CTL(pipe);
373 temp = intel_de_read(dev_priv, reg);
374 temp &= ~FDI_LINK_TRAIN_NONE;
375 temp |= FDI_LINK_TRAIN_PATTERN_2;
376 if (IS_SANDYBRIDGE(dev_priv)) {
377 temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
378 /* SNB-B */
379 temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
380 }
381 intel_de_write(dev_priv, reg, temp);
382
383 reg = FDI_RX_CTL(pipe);
384 temp = intel_de_read(dev_priv, reg);
385 if (HAS_PCH_CPT(dev_priv)) {
386 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
387 temp |= FDI_LINK_TRAIN_PATTERN_2_CPT;
388 } else {
389 temp &= ~FDI_LINK_TRAIN_NONE;
390 temp |= FDI_LINK_TRAIN_PATTERN_2;
391 }
392 intel_de_write(dev_priv, reg, temp);
393
394 intel_de_posting_read(dev_priv, reg);
395 udelay(150);
396
397 for (i = 0; i < 4; i++) {
398 reg = FDI_TX_CTL(pipe);
399 temp = intel_de_read(dev_priv, reg);
400 temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
401 temp |= snb_b_fdi_train_param[i];
402 intel_de_write(dev_priv, reg, temp);
403
404 intel_de_posting_read(dev_priv, reg);
405 udelay(500);
406
407 for (retry = 0; retry < 5; retry++) {
408 reg = FDI_RX_IIR(pipe);
409 temp = intel_de_read(dev_priv, reg);
410 drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
411 if (temp & FDI_RX_SYMBOL_LOCK) {
412 intel_de_write(dev_priv, reg,
413 temp | FDI_RX_SYMBOL_LOCK);
414 drm_dbg_kms(&dev_priv->drm,
415 "FDI train 2 done.\n");
416 break;
417 }
418 udelay(50);
419 }
420 if (retry < 5)
421 break;
422 }
423 if (i == 4)
424 drm_err(&dev_priv->drm, "FDI train 2 fail!\n");
425
426 drm_dbg_kms(&dev_priv->drm, "FDI train done.\n");
427 }
428
429 /* Manual link training for Ivy Bridge A0 parts */
ivb_manual_fdi_link_train(struct intel_crtc * crtc,const struct intel_crtc_state * crtc_state)430 static void ivb_manual_fdi_link_train(struct intel_crtc *crtc,
431 const struct intel_crtc_state *crtc_state)
432 {
433 struct drm_device *dev = crtc->base.dev;
434 struct drm_i915_private *dev_priv = to_i915(dev);
435 enum pipe pipe = crtc->pipe;
436 i915_reg_t reg;
437 u32 temp, i, j;
438
439 /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
440 for train result */
441 reg = FDI_RX_IMR(pipe);
442 temp = intel_de_read(dev_priv, reg);
443 temp &= ~FDI_RX_SYMBOL_LOCK;
444 temp &= ~FDI_RX_BIT_LOCK;
445 intel_de_write(dev_priv, reg, temp);
446
447 intel_de_posting_read(dev_priv, reg);
448 udelay(150);
449
450 drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR before link train 0x%x\n",
451 intel_de_read(dev_priv, FDI_RX_IIR(pipe)));
452
453 /* Try each vswing and preemphasis setting twice before moving on */
454 for (j = 0; j < ARRAY_SIZE(snb_b_fdi_train_param) * 2; j++) {
455 /* disable first in case we need to retry */
456 reg = FDI_TX_CTL(pipe);
457 temp = intel_de_read(dev_priv, reg);
458 temp &= ~(FDI_LINK_TRAIN_AUTO | FDI_LINK_TRAIN_NONE_IVB);
459 temp &= ~FDI_TX_ENABLE;
460 intel_de_write(dev_priv, reg, temp);
461
462 reg = FDI_RX_CTL(pipe);
463 temp = intel_de_read(dev_priv, reg);
464 temp &= ~FDI_LINK_TRAIN_AUTO;
465 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
466 temp &= ~FDI_RX_ENABLE;
467 intel_de_write(dev_priv, reg, temp);
468
469 /* enable CPU FDI TX and PCH FDI RX */
470 reg = FDI_TX_CTL(pipe);
471 temp = intel_de_read(dev_priv, reg);
472 temp &= ~FDI_DP_PORT_WIDTH_MASK;
473 temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
474 temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
475 temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
476 temp |= snb_b_fdi_train_param[j/2];
477 temp |= FDI_COMPOSITE_SYNC;
478 intel_de_write(dev_priv, reg, temp | FDI_TX_ENABLE);
479
480 intel_de_write(dev_priv, FDI_RX_MISC(pipe),
481 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
482
483 reg = FDI_RX_CTL(pipe);
484 temp = intel_de_read(dev_priv, reg);
485 temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
486 temp |= FDI_COMPOSITE_SYNC;
487 intel_de_write(dev_priv, reg, temp | FDI_RX_ENABLE);
488
489 intel_de_posting_read(dev_priv, reg);
490 udelay(1); /* should be 0.5us */
491
492 for (i = 0; i < 4; i++) {
493 reg = FDI_RX_IIR(pipe);
494 temp = intel_de_read(dev_priv, reg);
495 drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
496
497 if (temp & FDI_RX_BIT_LOCK ||
498 (intel_de_read(dev_priv, reg) & FDI_RX_BIT_LOCK)) {
499 intel_de_write(dev_priv, reg,
500 temp | FDI_RX_BIT_LOCK);
501 drm_dbg_kms(&dev_priv->drm,
502 "FDI train 1 done, level %i.\n",
503 i);
504 break;
505 }
506 udelay(1); /* should be 0.5us */
507 }
508 if (i == 4) {
509 drm_dbg_kms(&dev_priv->drm,
510 "FDI train 1 fail on vswing %d\n", j / 2);
511 continue;
512 }
513
514 /* Train 2 */
515 reg = FDI_TX_CTL(pipe);
516 temp = intel_de_read(dev_priv, reg);
517 temp &= ~FDI_LINK_TRAIN_NONE_IVB;
518 temp |= FDI_LINK_TRAIN_PATTERN_2_IVB;
519 intel_de_write(dev_priv, reg, temp);
520
521 reg = FDI_RX_CTL(pipe);
522 temp = intel_de_read(dev_priv, reg);
523 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
524 temp |= FDI_LINK_TRAIN_PATTERN_2_CPT;
525 intel_de_write(dev_priv, reg, temp);
526
527 intel_de_posting_read(dev_priv, reg);
528 udelay(2); /* should be 1.5us */
529
530 for (i = 0; i < 4; i++) {
531 reg = FDI_RX_IIR(pipe);
532 temp = intel_de_read(dev_priv, reg);
533 drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
534
535 if (temp & FDI_RX_SYMBOL_LOCK ||
536 (intel_de_read(dev_priv, reg) & FDI_RX_SYMBOL_LOCK)) {
537 intel_de_write(dev_priv, reg,
538 temp | FDI_RX_SYMBOL_LOCK);
539 drm_dbg_kms(&dev_priv->drm,
540 "FDI train 2 done, level %i.\n",
541 i);
542 goto train_done;
543 }
544 udelay(2); /* should be 1.5us */
545 }
546 if (i == 4)
547 drm_dbg_kms(&dev_priv->drm,
548 "FDI train 2 fail on vswing %d\n", j / 2);
549 }
550
551 train_done:
552 drm_dbg_kms(&dev_priv->drm, "FDI train done.\n");
553 }
554
555 /* Starting with Haswell, different DDI ports can work in FDI mode for
556 * connection to the PCH-located connectors. For this, it is necessary to train
557 * both the DDI port and PCH receiver for the desired DDI buffer settings.
558 *
559 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
560 * please note that when FDI mode is active on DDI E, it shares 2 lines with
561 * DDI A (which is used for eDP)
562 */
hsw_fdi_link_train(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)563 void hsw_fdi_link_train(struct intel_encoder *encoder,
564 const struct intel_crtc_state *crtc_state)
565 {
566 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
567 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
568 u32 temp, i, rx_ctl_val;
569 int n_entries;
570
571 intel_ddi_get_buf_trans_fdi(dev_priv, &n_entries);
572
573 intel_prepare_dp_ddi_buffers(encoder, crtc_state);
574
575 /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
576 * mode set "sequence for CRT port" document:
577 * - TP1 to TP2 time with the default value
578 * - FDI delay to 90h
579 *
580 * WaFDIAutoLinkSetTimingOverrride:hsw
581 */
582 intel_de_write(dev_priv, FDI_RX_MISC(PIPE_A),
583 FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2) | FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
584
585 /* Enable the PCH Receiver FDI PLL */
586 rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
587 FDI_RX_PLL_ENABLE |
588 FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
589 intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val);
590 intel_de_posting_read(dev_priv, FDI_RX_CTL(PIPE_A));
591 udelay(220);
592
593 /* Switch from Rawclk to PCDclk */
594 rx_ctl_val |= FDI_PCDCLK;
595 intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val);
596
597 /* Configure Port Clock Select */
598 drm_WARN_ON(&dev_priv->drm, crtc_state->shared_dpll->info->id != DPLL_ID_SPLL);
599 intel_ddi_enable_clock(encoder, crtc_state);
600
601 /* Start the training iterating through available voltages and emphasis,
602 * testing each value twice. */
603 for (i = 0; i < n_entries * 2; i++) {
604 /* Configure DP_TP_CTL with auto-training */
605 intel_de_write(dev_priv, DP_TP_CTL(PORT_E),
606 DP_TP_CTL_FDI_AUTOTRAIN |
607 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
608 DP_TP_CTL_LINK_TRAIN_PAT1 |
609 DP_TP_CTL_ENABLE);
610
611 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
612 * DDI E does not support port reversal, the functionality is
613 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
614 * port reversal bit */
615 intel_de_write(dev_priv, DDI_BUF_CTL(PORT_E),
616 DDI_BUF_CTL_ENABLE | ((crtc_state->fdi_lanes - 1) << 1) | DDI_BUF_TRANS_SELECT(i / 2));
617 intel_de_posting_read(dev_priv, DDI_BUF_CTL(PORT_E));
618
619 udelay(600);
620
621 /* Program PCH FDI Receiver TU */
622 intel_de_write(dev_priv, FDI_RX_TUSIZE1(PIPE_A), TU_SIZE(64));
623
624 /* Enable PCH FDI Receiver with auto-training */
625 rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
626 intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val);
627 intel_de_posting_read(dev_priv, FDI_RX_CTL(PIPE_A));
628
629 /* Wait for FDI receiver lane calibration */
630 udelay(30);
631
632 /* Unset FDI_RX_MISC pwrdn lanes */
633 temp = intel_de_read(dev_priv, FDI_RX_MISC(PIPE_A));
634 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
635 intel_de_write(dev_priv, FDI_RX_MISC(PIPE_A), temp);
636 intel_de_posting_read(dev_priv, FDI_RX_MISC(PIPE_A));
637
638 /* Wait for FDI auto training time */
639 udelay(5);
640
641 temp = intel_de_read(dev_priv, DP_TP_STATUS(PORT_E));
642 if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
643 drm_dbg_kms(&dev_priv->drm,
644 "FDI link training done on step %d\n", i);
645 break;
646 }
647
648 /*
649 * Leave things enabled even if we failed to train FDI.
650 * Results in less fireworks from the state checker.
651 */
652 if (i == n_entries * 2 - 1) {
653 drm_err(&dev_priv->drm, "FDI link training failed!\n");
654 break;
655 }
656
657 rx_ctl_val &= ~FDI_RX_ENABLE;
658 intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val);
659 intel_de_posting_read(dev_priv, FDI_RX_CTL(PIPE_A));
660
661 temp = intel_de_read(dev_priv, DDI_BUF_CTL(PORT_E));
662 temp &= ~DDI_BUF_CTL_ENABLE;
663 intel_de_write(dev_priv, DDI_BUF_CTL(PORT_E), temp);
664 intel_de_posting_read(dev_priv, DDI_BUF_CTL(PORT_E));
665
666 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
667 temp = intel_de_read(dev_priv, DP_TP_CTL(PORT_E));
668 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
669 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
670 intel_de_write(dev_priv, DP_TP_CTL(PORT_E), temp);
671 intel_de_posting_read(dev_priv, DP_TP_CTL(PORT_E));
672
673 intel_wait_ddi_buf_idle(dev_priv, PORT_E);
674
675 /* Reset FDI_RX_MISC pwrdn lanes */
676 temp = intel_de_read(dev_priv, FDI_RX_MISC(PIPE_A));
677 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
678 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
679 intel_de_write(dev_priv, FDI_RX_MISC(PIPE_A), temp);
680 intel_de_posting_read(dev_priv, FDI_RX_MISC(PIPE_A));
681 }
682
683 /* Enable normal pixel sending for FDI */
684 intel_de_write(dev_priv, DP_TP_CTL(PORT_E),
685 DP_TP_CTL_FDI_AUTOTRAIN |
686 DP_TP_CTL_LINK_TRAIN_NORMAL |
687 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
688 DP_TP_CTL_ENABLE);
689 }
690
ilk_fdi_pll_enable(const struct intel_crtc_state * crtc_state)691 void ilk_fdi_pll_enable(const struct intel_crtc_state *crtc_state)
692 {
693 struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
694 struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
695 enum pipe pipe = intel_crtc->pipe;
696 i915_reg_t reg;
697 u32 temp;
698
699 /* enable PCH FDI RX PLL, wait warmup plus DMI latency */
700 reg = FDI_RX_CTL(pipe);
701 temp = intel_de_read(dev_priv, reg);
702 temp &= ~(FDI_DP_PORT_WIDTH_MASK | (0x7 << 16));
703 temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
704 temp |= (intel_de_read(dev_priv, PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
705 intel_de_write(dev_priv, reg, temp | FDI_RX_PLL_ENABLE);
706
707 intel_de_posting_read(dev_priv, reg);
708 udelay(200);
709
710 /* Switch from Rawclk to PCDclk */
711 temp = intel_de_read(dev_priv, reg);
712 intel_de_write(dev_priv, reg, temp | FDI_PCDCLK);
713
714 intel_de_posting_read(dev_priv, reg);
715 udelay(200);
716
717 /* Enable CPU FDI TX PLL, always on for Ironlake */
718 reg = FDI_TX_CTL(pipe);
719 temp = intel_de_read(dev_priv, reg);
720 if ((temp & FDI_TX_PLL_ENABLE) == 0) {
721 intel_de_write(dev_priv, reg, temp | FDI_TX_PLL_ENABLE);
722
723 intel_de_posting_read(dev_priv, reg);
724 udelay(100);
725 }
726 }
727
ilk_fdi_pll_disable(struct intel_crtc * intel_crtc)728 void ilk_fdi_pll_disable(struct intel_crtc *intel_crtc)
729 {
730 struct drm_device *dev = intel_crtc->base.dev;
731 struct drm_i915_private *dev_priv = to_i915(dev);
732 enum pipe pipe = intel_crtc->pipe;
733 i915_reg_t reg;
734 u32 temp;
735
736 /* Switch from PCDclk to Rawclk */
737 reg = FDI_RX_CTL(pipe);
738 temp = intel_de_read(dev_priv, reg);
739 intel_de_write(dev_priv, reg, temp & ~FDI_PCDCLK);
740
741 /* Disable CPU FDI TX PLL */
742 reg = FDI_TX_CTL(pipe);
743 temp = intel_de_read(dev_priv, reg);
744 intel_de_write(dev_priv, reg, temp & ~FDI_TX_PLL_ENABLE);
745
746 intel_de_posting_read(dev_priv, reg);
747 udelay(100);
748
749 reg = FDI_RX_CTL(pipe);
750 temp = intel_de_read(dev_priv, reg);
751 intel_de_write(dev_priv, reg, temp & ~FDI_RX_PLL_ENABLE);
752
753 /* Wait for the clocks to turn off. */
754 intel_de_posting_read(dev_priv, reg);
755 udelay(100);
756 }
757
ilk_fdi_disable(struct intel_crtc * crtc)758 void ilk_fdi_disable(struct intel_crtc *crtc)
759 {
760 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
761 enum pipe pipe = crtc->pipe;
762 i915_reg_t reg;
763 u32 temp;
764
765 /* disable CPU FDI tx and PCH FDI rx */
766 reg = FDI_TX_CTL(pipe);
767 temp = intel_de_read(dev_priv, reg);
768 intel_de_write(dev_priv, reg, temp & ~FDI_TX_ENABLE);
769 intel_de_posting_read(dev_priv, reg);
770
771 reg = FDI_RX_CTL(pipe);
772 temp = intel_de_read(dev_priv, reg);
773 temp &= ~(0x7 << 16);
774 temp |= (intel_de_read(dev_priv, PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
775 intel_de_write(dev_priv, reg, temp & ~FDI_RX_ENABLE);
776
777 intel_de_posting_read(dev_priv, reg);
778 udelay(100);
779
780 /* Ironlake workaround, disable clock pointer after downing FDI */
781 if (HAS_PCH_IBX(dev_priv))
782 intel_de_write(dev_priv, FDI_RX_CHICKEN(pipe),
783 FDI_RX_PHASE_SYNC_POINTER_OVR);
784
785 /* still set train pattern 1 */
786 reg = FDI_TX_CTL(pipe);
787 temp = intel_de_read(dev_priv, reg);
788 temp &= ~FDI_LINK_TRAIN_NONE;
789 temp |= FDI_LINK_TRAIN_PATTERN_1;
790 intel_de_write(dev_priv, reg, temp);
791
792 reg = FDI_RX_CTL(pipe);
793 temp = intel_de_read(dev_priv, reg);
794 if (HAS_PCH_CPT(dev_priv)) {
795 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
796 temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
797 } else {
798 temp &= ~FDI_LINK_TRAIN_NONE;
799 temp |= FDI_LINK_TRAIN_PATTERN_1;
800 }
801 /* BPC in FDI rx is consistent with that in PIPECONF */
802 temp &= ~(0x07 << 16);
803 temp |= (intel_de_read(dev_priv, PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
804 intel_de_write(dev_priv, reg, temp);
805
806 intel_de_posting_read(dev_priv, reg);
807 udelay(100);
808 }
809
810 void
intel_fdi_init_hook(struct drm_i915_private * dev_priv)811 intel_fdi_init_hook(struct drm_i915_private *dev_priv)
812 {
813 if (IS_IRONLAKE(dev_priv)) {
814 dev_priv->display.fdi_link_train = ilk_fdi_link_train;
815 } else if (IS_SANDYBRIDGE(dev_priv)) {
816 dev_priv->display.fdi_link_train = gen6_fdi_link_train;
817 } else if (IS_IVYBRIDGE(dev_priv)) {
818 /* FIXME: detect B0+ stepping and use auto training */
819 dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train;
820 }
821 }
822