Merge tag 'v5.12-rc4' into next
[linux-2.6-microblaze.git] / drivers / gpu / drm / i915 / display / intel_fdi.c
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2020 Intel Corporation
4  */
5 #include "intel_atomic.h"
6 #include "intel_display_types.h"
7 #include "intel_fdi.h"
8
9 /* units of 100MHz */
10 static int pipe_required_fdi_lanes(struct intel_crtc_state *crtc_state)
11 {
12         if (crtc_state->hw.enable && crtc_state->has_pch_encoder)
13                 return crtc_state->fdi_lanes;
14
15         return 0;
16 }
17
18 static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
19                                struct intel_crtc_state *pipe_config)
20 {
21         struct drm_i915_private *dev_priv = to_i915(dev);
22         struct drm_atomic_state *state = pipe_config->uapi.state;
23         struct intel_crtc *other_crtc;
24         struct intel_crtc_state *other_crtc_state;
25
26         drm_dbg_kms(&dev_priv->drm,
27                     "checking fdi config on pipe %c, lanes %i\n",
28                     pipe_name(pipe), pipe_config->fdi_lanes);
29         if (pipe_config->fdi_lanes > 4) {
30                 drm_dbg_kms(&dev_priv->drm,
31                             "invalid fdi lane config on pipe %c: %i lanes\n",
32                             pipe_name(pipe), pipe_config->fdi_lanes);
33                 return -EINVAL;
34         }
35
36         if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
37                 if (pipe_config->fdi_lanes > 2) {
38                         drm_dbg_kms(&dev_priv->drm,
39                                     "only 2 lanes on haswell, required: %i lanes\n",
40                                     pipe_config->fdi_lanes);
41                         return -EINVAL;
42                 } else {
43                         return 0;
44                 }
45         }
46
47         if (INTEL_NUM_PIPES(dev_priv) == 2)
48                 return 0;
49
50         /* Ivybridge 3 pipe is really complicated */
51         switch (pipe) {
52         case PIPE_A:
53                 return 0;
54         case PIPE_B:
55                 if (pipe_config->fdi_lanes <= 2)
56                         return 0;
57
58                 other_crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_C);
59                 other_crtc_state =
60                         intel_atomic_get_crtc_state(state, other_crtc);
61                 if (IS_ERR(other_crtc_state))
62                         return PTR_ERR(other_crtc_state);
63
64                 if (pipe_required_fdi_lanes(other_crtc_state) > 0) {
65                         drm_dbg_kms(&dev_priv->drm,
66                                     "invalid shared fdi lane config on pipe %c: %i lanes\n",
67                                     pipe_name(pipe), pipe_config->fdi_lanes);
68                         return -EINVAL;
69                 }
70                 return 0;
71         case PIPE_C:
72                 if (pipe_config->fdi_lanes > 2) {
73                         drm_dbg_kms(&dev_priv->drm,
74                                     "only 2 lanes on pipe %c: required %i lanes\n",
75                                     pipe_name(pipe), pipe_config->fdi_lanes);
76                         return -EINVAL;
77                 }
78
79                 other_crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_B);
80                 other_crtc_state =
81                         intel_atomic_get_crtc_state(state, other_crtc);
82                 if (IS_ERR(other_crtc_state))
83                         return PTR_ERR(other_crtc_state);
84
85                 if (pipe_required_fdi_lanes(other_crtc_state) > 2) {
86                         drm_dbg_kms(&dev_priv->drm,
87                                     "fdi link B uses too many lanes to enable link C\n");
88                         return -EINVAL;
89                 }
90                 return 0;
91         default:
92                 BUG();
93         }
94 }
95
96 int ilk_fdi_compute_config(struct intel_crtc *intel_crtc,
97                                   struct intel_crtc_state *pipe_config)
98 {
99         struct drm_device *dev = intel_crtc->base.dev;
100         struct drm_i915_private *i915 = to_i915(dev);
101         const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
102         int lane, link_bw, fdi_dotclock, ret;
103         bool needs_recompute = false;
104
105 retry:
106         /* FDI is a binary signal running at ~2.7GHz, encoding
107          * each output octet as 10 bits. The actual frequency
108          * is stored as a divider into a 100MHz clock, and the
109          * mode pixel clock is stored in units of 1KHz.
110          * Hence the bw of each lane in terms of the mode signal
111          * is:
112          */
113         link_bw = intel_fdi_link_freq(i915, pipe_config);
114
115         fdi_dotclock = adjusted_mode->crtc_clock;
116
117         lane = ilk_get_lanes_required(fdi_dotclock, link_bw,
118                                       pipe_config->pipe_bpp);
119
120         pipe_config->fdi_lanes = lane;
121
122         intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
123                                link_bw, &pipe_config->fdi_m_n, false, false);
124
125         ret = ilk_check_fdi_lanes(dev, intel_crtc->pipe, pipe_config);
126         if (ret == -EDEADLK)
127                 return ret;
128
129         if (ret == -EINVAL && pipe_config->pipe_bpp > 6*3) {
130                 pipe_config->pipe_bpp -= 2*3;
131                 drm_dbg_kms(&i915->drm,
132                             "fdi link bw constraint, reducing pipe bpp to %i\n",
133                             pipe_config->pipe_bpp);
134                 needs_recompute = true;
135                 pipe_config->bw_constrained = true;
136
137                 goto retry;
138         }
139
140         if (needs_recompute)
141                 return I915_DISPLAY_CONFIG_RETRY;
142
143         return ret;
144 }
145
146 void intel_fdi_normal_train(struct intel_crtc *crtc)
147 {
148         struct drm_device *dev = crtc->base.dev;
149         struct drm_i915_private *dev_priv = to_i915(dev);
150         enum pipe pipe = crtc->pipe;
151         i915_reg_t reg;
152         u32 temp;
153
154         /* enable normal train */
155         reg = FDI_TX_CTL(pipe);
156         temp = intel_de_read(dev_priv, reg);
157         if (IS_IVYBRIDGE(dev_priv)) {
158                 temp &= ~FDI_LINK_TRAIN_NONE_IVB;
159                 temp |= FDI_LINK_TRAIN_NONE_IVB | FDI_TX_ENHANCE_FRAME_ENABLE;
160         } else {
161                 temp &= ~FDI_LINK_TRAIN_NONE;
162                 temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
163         }
164         intel_de_write(dev_priv, reg, temp);
165
166         reg = FDI_RX_CTL(pipe);
167         temp = intel_de_read(dev_priv, reg);
168         if (HAS_PCH_CPT(dev_priv)) {
169                 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
170                 temp |= FDI_LINK_TRAIN_NORMAL_CPT;
171         } else {
172                 temp &= ~FDI_LINK_TRAIN_NONE;
173                 temp |= FDI_LINK_TRAIN_NONE;
174         }
175         intel_de_write(dev_priv, reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE);
176
177         /* wait one idle pattern time */
178         intel_de_posting_read(dev_priv, reg);
179         udelay(1000);
180
181         /* IVB wants error correction enabled */
182         if (IS_IVYBRIDGE(dev_priv))
183                 intel_de_write(dev_priv, reg,
184                                intel_de_read(dev_priv, reg) | FDI_FS_ERRC_ENABLE | FDI_FE_ERRC_ENABLE);
185 }
186
187 /* The FDI link training functions for ILK/Ibexpeak. */
188 static void ilk_fdi_link_train(struct intel_crtc *crtc,
189                                const struct intel_crtc_state *crtc_state)
190 {
191         struct drm_device *dev = crtc->base.dev;
192         struct drm_i915_private *dev_priv = to_i915(dev);
193         enum pipe pipe = crtc->pipe;
194         i915_reg_t reg;
195         u32 temp, tries;
196
197         /* FDI needs bits from pipe first */
198         assert_pipe_enabled(dev_priv, crtc_state->cpu_transcoder);
199
200         /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
201            for train result */
202         reg = FDI_RX_IMR(pipe);
203         temp = intel_de_read(dev_priv, reg);
204         temp &= ~FDI_RX_SYMBOL_LOCK;
205         temp &= ~FDI_RX_BIT_LOCK;
206         intel_de_write(dev_priv, reg, temp);
207         intel_de_read(dev_priv, reg);
208         udelay(150);
209
210         /* enable CPU FDI TX and PCH FDI RX */
211         reg = FDI_TX_CTL(pipe);
212         temp = intel_de_read(dev_priv, reg);
213         temp &= ~FDI_DP_PORT_WIDTH_MASK;
214         temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
215         temp &= ~FDI_LINK_TRAIN_NONE;
216         temp |= FDI_LINK_TRAIN_PATTERN_1;
217         intel_de_write(dev_priv, reg, temp | FDI_TX_ENABLE);
218
219         reg = FDI_RX_CTL(pipe);
220         temp = intel_de_read(dev_priv, reg);
221         temp &= ~FDI_LINK_TRAIN_NONE;
222         temp |= FDI_LINK_TRAIN_PATTERN_1;
223         intel_de_write(dev_priv, reg, temp | FDI_RX_ENABLE);
224
225         intel_de_posting_read(dev_priv, reg);
226         udelay(150);
227
228         /* Ironlake workaround, enable clock pointer after FDI enable*/
229         intel_de_write(dev_priv, FDI_RX_CHICKEN(pipe),
230                        FDI_RX_PHASE_SYNC_POINTER_OVR);
231         intel_de_write(dev_priv, FDI_RX_CHICKEN(pipe),
232                        FDI_RX_PHASE_SYNC_POINTER_OVR | FDI_RX_PHASE_SYNC_POINTER_EN);
233
234         reg = FDI_RX_IIR(pipe);
235         for (tries = 0; tries < 5; tries++) {
236                 temp = intel_de_read(dev_priv, reg);
237                 drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
238
239                 if ((temp & FDI_RX_BIT_LOCK)) {
240                         drm_dbg_kms(&dev_priv->drm, "FDI train 1 done.\n");
241                         intel_de_write(dev_priv, reg, temp | FDI_RX_BIT_LOCK);
242                         break;
243                 }
244         }
245         if (tries == 5)
246                 drm_err(&dev_priv->drm, "FDI train 1 fail!\n");
247
248         /* Train 2 */
249         reg = FDI_TX_CTL(pipe);
250         temp = intel_de_read(dev_priv, reg);
251         temp &= ~FDI_LINK_TRAIN_NONE;
252         temp |= FDI_LINK_TRAIN_PATTERN_2;
253         intel_de_write(dev_priv, reg, temp);
254
255         reg = FDI_RX_CTL(pipe);
256         temp = intel_de_read(dev_priv, reg);
257         temp &= ~FDI_LINK_TRAIN_NONE;
258         temp |= FDI_LINK_TRAIN_PATTERN_2;
259         intel_de_write(dev_priv, reg, temp);
260
261         intel_de_posting_read(dev_priv, reg);
262         udelay(150);
263
264         reg = FDI_RX_IIR(pipe);
265         for (tries = 0; tries < 5; tries++) {
266                 temp = intel_de_read(dev_priv, reg);
267                 drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
268
269                 if (temp & FDI_RX_SYMBOL_LOCK) {
270                         intel_de_write(dev_priv, reg,
271                                        temp | FDI_RX_SYMBOL_LOCK);
272                         drm_dbg_kms(&dev_priv->drm, "FDI train 2 done.\n");
273                         break;
274                 }
275         }
276         if (tries == 5)
277                 drm_err(&dev_priv->drm, "FDI train 2 fail!\n");
278
279         drm_dbg_kms(&dev_priv->drm, "FDI train done\n");
280
281 }
282
283 static const int snb_b_fdi_train_param[] = {
284         FDI_LINK_TRAIN_400MV_0DB_SNB_B,
285         FDI_LINK_TRAIN_400MV_6DB_SNB_B,
286         FDI_LINK_TRAIN_600MV_3_5DB_SNB_B,
287         FDI_LINK_TRAIN_800MV_0DB_SNB_B,
288 };
289
290 /* The FDI link training functions for SNB/Cougarpoint. */
291 static void gen6_fdi_link_train(struct intel_crtc *crtc,
292                                 const struct intel_crtc_state *crtc_state)
293 {
294         struct drm_device *dev = crtc->base.dev;
295         struct drm_i915_private *dev_priv = to_i915(dev);
296         enum pipe pipe = crtc->pipe;
297         i915_reg_t reg;
298         u32 temp, i, retry;
299
300         /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
301            for train result */
302         reg = FDI_RX_IMR(pipe);
303         temp = intel_de_read(dev_priv, reg);
304         temp &= ~FDI_RX_SYMBOL_LOCK;
305         temp &= ~FDI_RX_BIT_LOCK;
306         intel_de_write(dev_priv, reg, temp);
307
308         intel_de_posting_read(dev_priv, reg);
309         udelay(150);
310
311         /* enable CPU FDI TX and PCH FDI RX */
312         reg = FDI_TX_CTL(pipe);
313         temp = intel_de_read(dev_priv, reg);
314         temp &= ~FDI_DP_PORT_WIDTH_MASK;
315         temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
316         temp &= ~FDI_LINK_TRAIN_NONE;
317         temp |= FDI_LINK_TRAIN_PATTERN_1;
318         temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
319         /* SNB-B */
320         temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
321         intel_de_write(dev_priv, reg, temp | FDI_TX_ENABLE);
322
323         intel_de_write(dev_priv, FDI_RX_MISC(pipe),
324                        FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
325
326         reg = FDI_RX_CTL(pipe);
327         temp = intel_de_read(dev_priv, reg);
328         if (HAS_PCH_CPT(dev_priv)) {
329                 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
330                 temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
331         } else {
332                 temp &= ~FDI_LINK_TRAIN_NONE;
333                 temp |= FDI_LINK_TRAIN_PATTERN_1;
334         }
335         intel_de_write(dev_priv, reg, temp | FDI_RX_ENABLE);
336
337         intel_de_posting_read(dev_priv, reg);
338         udelay(150);
339
340         for (i = 0; i < 4; i++) {
341                 reg = FDI_TX_CTL(pipe);
342                 temp = intel_de_read(dev_priv, reg);
343                 temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
344                 temp |= snb_b_fdi_train_param[i];
345                 intel_de_write(dev_priv, reg, temp);
346
347                 intel_de_posting_read(dev_priv, reg);
348                 udelay(500);
349
350                 for (retry = 0; retry < 5; retry++) {
351                         reg = FDI_RX_IIR(pipe);
352                         temp = intel_de_read(dev_priv, reg);
353                         drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
354                         if (temp & FDI_RX_BIT_LOCK) {
355                                 intel_de_write(dev_priv, reg,
356                                                temp | FDI_RX_BIT_LOCK);
357                                 drm_dbg_kms(&dev_priv->drm,
358                                             "FDI train 1 done.\n");
359                                 break;
360                         }
361                         udelay(50);
362                 }
363                 if (retry < 5)
364                         break;
365         }
366         if (i == 4)
367                 drm_err(&dev_priv->drm, "FDI train 1 fail!\n");
368
369         /* Train 2 */
370         reg = FDI_TX_CTL(pipe);
371         temp = intel_de_read(dev_priv, reg);
372         temp &= ~FDI_LINK_TRAIN_NONE;
373         temp |= FDI_LINK_TRAIN_PATTERN_2;
374         if (IS_GEN(dev_priv, 6)) {
375                 temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
376                 /* SNB-B */
377                 temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
378         }
379         intel_de_write(dev_priv, reg, temp);
380
381         reg = FDI_RX_CTL(pipe);
382         temp = intel_de_read(dev_priv, reg);
383         if (HAS_PCH_CPT(dev_priv)) {
384                 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
385                 temp |= FDI_LINK_TRAIN_PATTERN_2_CPT;
386         } else {
387                 temp &= ~FDI_LINK_TRAIN_NONE;
388                 temp |= FDI_LINK_TRAIN_PATTERN_2;
389         }
390         intel_de_write(dev_priv, reg, temp);
391
392         intel_de_posting_read(dev_priv, reg);
393         udelay(150);
394
395         for (i = 0; i < 4; i++) {
396                 reg = FDI_TX_CTL(pipe);
397                 temp = intel_de_read(dev_priv, reg);
398                 temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
399                 temp |= snb_b_fdi_train_param[i];
400                 intel_de_write(dev_priv, reg, temp);
401
402                 intel_de_posting_read(dev_priv, reg);
403                 udelay(500);
404
405                 for (retry = 0; retry < 5; retry++) {
406                         reg = FDI_RX_IIR(pipe);
407                         temp = intel_de_read(dev_priv, reg);
408                         drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
409                         if (temp & FDI_RX_SYMBOL_LOCK) {
410                                 intel_de_write(dev_priv, reg,
411                                                temp | FDI_RX_SYMBOL_LOCK);
412                                 drm_dbg_kms(&dev_priv->drm,
413                                             "FDI train 2 done.\n");
414                                 break;
415                         }
416                         udelay(50);
417                 }
418                 if (retry < 5)
419                         break;
420         }
421         if (i == 4)
422                 drm_err(&dev_priv->drm, "FDI train 2 fail!\n");
423
424         drm_dbg_kms(&dev_priv->drm, "FDI train done.\n");
425 }
426
427 /* Manual link training for Ivy Bridge A0 parts */
428 static void ivb_manual_fdi_link_train(struct intel_crtc *crtc,
429                                       const struct intel_crtc_state *crtc_state)
430 {
431         struct drm_device *dev = crtc->base.dev;
432         struct drm_i915_private *dev_priv = to_i915(dev);
433         enum pipe pipe = crtc->pipe;
434         i915_reg_t reg;
435         u32 temp, i, j;
436
437         /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
438            for train result */
439         reg = FDI_RX_IMR(pipe);
440         temp = intel_de_read(dev_priv, reg);
441         temp &= ~FDI_RX_SYMBOL_LOCK;
442         temp &= ~FDI_RX_BIT_LOCK;
443         intel_de_write(dev_priv, reg, temp);
444
445         intel_de_posting_read(dev_priv, reg);
446         udelay(150);
447
448         drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR before link train 0x%x\n",
449                     intel_de_read(dev_priv, FDI_RX_IIR(pipe)));
450
451         /* Try each vswing and preemphasis setting twice before moving on */
452         for (j = 0; j < ARRAY_SIZE(snb_b_fdi_train_param) * 2; j++) {
453                 /* disable first in case we need to retry */
454                 reg = FDI_TX_CTL(pipe);
455                 temp = intel_de_read(dev_priv, reg);
456                 temp &= ~(FDI_LINK_TRAIN_AUTO | FDI_LINK_TRAIN_NONE_IVB);
457                 temp &= ~FDI_TX_ENABLE;
458                 intel_de_write(dev_priv, reg, temp);
459
460                 reg = FDI_RX_CTL(pipe);
461                 temp = intel_de_read(dev_priv, reg);
462                 temp &= ~FDI_LINK_TRAIN_AUTO;
463                 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
464                 temp &= ~FDI_RX_ENABLE;
465                 intel_de_write(dev_priv, reg, temp);
466
467                 /* enable CPU FDI TX and PCH FDI RX */
468                 reg = FDI_TX_CTL(pipe);
469                 temp = intel_de_read(dev_priv, reg);
470                 temp &= ~FDI_DP_PORT_WIDTH_MASK;
471                 temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
472                 temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
473                 temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
474                 temp |= snb_b_fdi_train_param[j/2];
475                 temp |= FDI_COMPOSITE_SYNC;
476                 intel_de_write(dev_priv, reg, temp | FDI_TX_ENABLE);
477
478                 intel_de_write(dev_priv, FDI_RX_MISC(pipe),
479                                FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
480
481                 reg = FDI_RX_CTL(pipe);
482                 temp = intel_de_read(dev_priv, reg);
483                 temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
484                 temp |= FDI_COMPOSITE_SYNC;
485                 intel_de_write(dev_priv, reg, temp | FDI_RX_ENABLE);
486
487                 intel_de_posting_read(dev_priv, reg);
488                 udelay(1); /* should be 0.5us */
489
490                 for (i = 0; i < 4; i++) {
491                         reg = FDI_RX_IIR(pipe);
492                         temp = intel_de_read(dev_priv, reg);
493                         drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
494
495                         if (temp & FDI_RX_BIT_LOCK ||
496                             (intel_de_read(dev_priv, reg) & FDI_RX_BIT_LOCK)) {
497                                 intel_de_write(dev_priv, reg,
498                                                temp | FDI_RX_BIT_LOCK);
499                                 drm_dbg_kms(&dev_priv->drm,
500                                             "FDI train 1 done, level %i.\n",
501                                             i);
502                                 break;
503                         }
504                         udelay(1); /* should be 0.5us */
505                 }
506                 if (i == 4) {
507                         drm_dbg_kms(&dev_priv->drm,
508                                     "FDI train 1 fail on vswing %d\n", j / 2);
509                         continue;
510                 }
511
512                 /* Train 2 */
513                 reg = FDI_TX_CTL(pipe);
514                 temp = intel_de_read(dev_priv, reg);
515                 temp &= ~FDI_LINK_TRAIN_NONE_IVB;
516                 temp |= FDI_LINK_TRAIN_PATTERN_2_IVB;
517                 intel_de_write(dev_priv, reg, temp);
518
519                 reg = FDI_RX_CTL(pipe);
520                 temp = intel_de_read(dev_priv, reg);
521                 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
522                 temp |= FDI_LINK_TRAIN_PATTERN_2_CPT;
523                 intel_de_write(dev_priv, reg, temp);
524
525                 intel_de_posting_read(dev_priv, reg);
526                 udelay(2); /* should be 1.5us */
527
528                 for (i = 0; i < 4; i++) {
529                         reg = FDI_RX_IIR(pipe);
530                         temp = intel_de_read(dev_priv, reg);
531                         drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
532
533                         if (temp & FDI_RX_SYMBOL_LOCK ||
534                             (intel_de_read(dev_priv, reg) & FDI_RX_SYMBOL_LOCK)) {
535                                 intel_de_write(dev_priv, reg,
536                                                temp | FDI_RX_SYMBOL_LOCK);
537                                 drm_dbg_kms(&dev_priv->drm,
538                                             "FDI train 2 done, level %i.\n",
539                                             i);
540                                 goto train_done;
541                         }
542                         udelay(2); /* should be 1.5us */
543                 }
544                 if (i == 4)
545                         drm_dbg_kms(&dev_priv->drm,
546                                     "FDI train 2 fail on vswing %d\n", j / 2);
547         }
548
549 train_done:
550         drm_dbg_kms(&dev_priv->drm, "FDI train done.\n");
551 }
552
553 void ilk_fdi_pll_enable(const struct intel_crtc_state *crtc_state)
554 {
555         struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
556         struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
557         enum pipe pipe = intel_crtc->pipe;
558         i915_reg_t reg;
559         u32 temp;
560
561         /* enable PCH FDI RX PLL, wait warmup plus DMI latency */
562         reg = FDI_RX_CTL(pipe);
563         temp = intel_de_read(dev_priv, reg);
564         temp &= ~(FDI_DP_PORT_WIDTH_MASK | (0x7 << 16));
565         temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
566         temp |= (intel_de_read(dev_priv, PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
567         intel_de_write(dev_priv, reg, temp | FDI_RX_PLL_ENABLE);
568
569         intel_de_posting_read(dev_priv, reg);
570         udelay(200);
571
572         /* Switch from Rawclk to PCDclk */
573         temp = intel_de_read(dev_priv, reg);
574         intel_de_write(dev_priv, reg, temp | FDI_PCDCLK);
575
576         intel_de_posting_read(dev_priv, reg);
577         udelay(200);
578
579         /* Enable CPU FDI TX PLL, always on for Ironlake */
580         reg = FDI_TX_CTL(pipe);
581         temp = intel_de_read(dev_priv, reg);
582         if ((temp & FDI_TX_PLL_ENABLE) == 0) {
583                 intel_de_write(dev_priv, reg, temp | FDI_TX_PLL_ENABLE);
584
585                 intel_de_posting_read(dev_priv, reg);
586                 udelay(100);
587         }
588 }
589
590 void ilk_fdi_pll_disable(struct intel_crtc *intel_crtc)
591 {
592         struct drm_device *dev = intel_crtc->base.dev;
593         struct drm_i915_private *dev_priv = to_i915(dev);
594         enum pipe pipe = intel_crtc->pipe;
595         i915_reg_t reg;
596         u32 temp;
597
598         /* Switch from PCDclk to Rawclk */
599         reg = FDI_RX_CTL(pipe);
600         temp = intel_de_read(dev_priv, reg);
601         intel_de_write(dev_priv, reg, temp & ~FDI_PCDCLK);
602
603         /* Disable CPU FDI TX PLL */
604         reg = FDI_TX_CTL(pipe);
605         temp = intel_de_read(dev_priv, reg);
606         intel_de_write(dev_priv, reg, temp & ~FDI_TX_PLL_ENABLE);
607
608         intel_de_posting_read(dev_priv, reg);
609         udelay(100);
610
611         reg = FDI_RX_CTL(pipe);
612         temp = intel_de_read(dev_priv, reg);
613         intel_de_write(dev_priv, reg, temp & ~FDI_RX_PLL_ENABLE);
614
615         /* Wait for the clocks to turn off. */
616         intel_de_posting_read(dev_priv, reg);
617         udelay(100);
618 }
619
620 void ilk_fdi_disable(struct intel_crtc *crtc)
621 {
622         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
623         enum pipe pipe = crtc->pipe;
624         i915_reg_t reg;
625         u32 temp;
626
627         /* disable CPU FDI tx and PCH FDI rx */
628         reg = FDI_TX_CTL(pipe);
629         temp = intel_de_read(dev_priv, reg);
630         intel_de_write(dev_priv, reg, temp & ~FDI_TX_ENABLE);
631         intel_de_posting_read(dev_priv, reg);
632
633         reg = FDI_RX_CTL(pipe);
634         temp = intel_de_read(dev_priv, reg);
635         temp &= ~(0x7 << 16);
636         temp |= (intel_de_read(dev_priv, PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
637         intel_de_write(dev_priv, reg, temp & ~FDI_RX_ENABLE);
638
639         intel_de_posting_read(dev_priv, reg);
640         udelay(100);
641
642         /* Ironlake workaround, disable clock pointer after downing FDI */
643         if (HAS_PCH_IBX(dev_priv))
644                 intel_de_write(dev_priv, FDI_RX_CHICKEN(pipe),
645                                FDI_RX_PHASE_SYNC_POINTER_OVR);
646
647         /* still set train pattern 1 */
648         reg = FDI_TX_CTL(pipe);
649         temp = intel_de_read(dev_priv, reg);
650         temp &= ~FDI_LINK_TRAIN_NONE;
651         temp |= FDI_LINK_TRAIN_PATTERN_1;
652         intel_de_write(dev_priv, reg, temp);
653
654         reg = FDI_RX_CTL(pipe);
655         temp = intel_de_read(dev_priv, reg);
656         if (HAS_PCH_CPT(dev_priv)) {
657                 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
658                 temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
659         } else {
660                 temp &= ~FDI_LINK_TRAIN_NONE;
661                 temp |= FDI_LINK_TRAIN_PATTERN_1;
662         }
663         /* BPC in FDI rx is consistent with that in PIPECONF */
664         temp &= ~(0x07 << 16);
665         temp |= (intel_de_read(dev_priv, PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
666         intel_de_write(dev_priv, reg, temp);
667
668         intel_de_posting_read(dev_priv, reg);
669         udelay(100);
670 }
671
672 void
673 intel_fdi_init_hook(struct drm_i915_private *dev_priv)
674 {
675         if (IS_GEN(dev_priv, 5)) {
676                 dev_priv->display.fdi_link_train = ilk_fdi_link_train;
677         } else if (IS_GEN(dev_priv, 6)) {
678                 dev_priv->display.fdi_link_train = gen6_fdi_link_train;
679         } else if (IS_IVYBRIDGE(dev_priv)) {
680                 /* FIXME: detect B0+ stepping and use auto training */
681                 dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train;
682         }
683 }