1
2
3
4
5#include "intel_atomic.h"
6#include "intel_ddi.h"
7#include "intel_de.h"
8#include "intel_display_types.h"
9#include "intel_fdi.h"
10
11
12static 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
20static 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
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
98int ilk_fdi_compute_config(struct intel_crtc *crtc,
99 struct intel_crtc_state *pipe_config)
100{
101 struct drm_device *dev = 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
107retry:
108
109
110
111
112
113
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, 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
148void 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
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
180 intel_de_posting_read(dev_priv, reg);
181 udelay(1000);
182
183
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
190static 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
200 assert_pipe_enabled(dev_priv, crtc_state->cpu_transcoder);
201
202
203
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
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
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
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
285static 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
293static 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
303
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
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
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
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
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
430static 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
440
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
454 for (j = 0; j < ARRAY_SIZE(snb_b_fdi_train_param) * 2; j++) {
455
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
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);
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);
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
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);
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);
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
551train_done:
552 drm_dbg_kms(&dev_priv->drm, "FDI train done.\n");
553}
554
555
556
557
558
559
560
561
562
563void 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 encoder->get_buf_trans(encoder, crtc_state, &n_entries);
572
573 hsw_prepare_dp_ddi_buffers(encoder, crtc_state);
574
575
576
577
578
579
580
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
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
594 rx_ctl_val |= FDI_PCDCLK;
595 intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val);
596
597
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
602
603 for (i = 0; i < n_entries * 2; i++) {
604
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
612
613
614
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
622 intel_de_write(dev_priv, FDI_RX_TUSIZE1(PIPE_A), TU_SIZE(64));
623
624
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
630 udelay(30);
631
632
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
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
650
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
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
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
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
691void ilk_fdi_pll_enable(const struct intel_crtc_state *crtc_state)
692{
693 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
694 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
695 enum pipe pipe = crtc->pipe;
696 i915_reg_t reg;
697 u32 temp;
698
699
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
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
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
728void ilk_fdi_pll_disable(struct intel_crtc *crtc)
729{
730 struct drm_device *dev = crtc->base.dev;
731 struct drm_i915_private *dev_priv = to_i915(dev);
732 enum pipe pipe = crtc->pipe;
733 i915_reg_t reg;
734 u32 temp;
735
736
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
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
754 intel_de_posting_read(dev_priv, reg);
755 udelay(100);
756}
757
758void 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
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
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
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
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
810void
811intel_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
819 dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train;
820 }
821}
822