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 }
684