xref: /linux/drivers/gpu/drm/i915/display/intel_fdi.c (revision 07fdad3a93756b872da7b53647715c48d0f4a2d0)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2020 Intel Corporation
4  */
5 
6 #include <linux/string_helpers.h>
7 
8 #include <drm/drm_fixed.h>
9 #include <drm/drm_print.h>
10 
11 #include "i915_reg.h"
12 #include "i915_utils.h"
13 #include "intel_atomic.h"
14 #include "intel_crtc.h"
15 #include "intel_ddi.h"
16 #include "intel_de.h"
17 #include "intel_display_regs.h"
18 #include "intel_display_types.h"
19 #include "intel_dp.h"
20 #include "intel_fdi.h"
21 #include "intel_fdi_regs.h"
22 #include "intel_link_bw.h"
23 
24 struct intel_fdi_funcs {
25 	void (*fdi_link_train)(struct intel_crtc *crtc,
26 			       const struct intel_crtc_state *crtc_state);
27 };
28 
29 static void assert_fdi_tx(struct intel_display *display,
30 			  enum pipe pipe, bool state)
31 {
32 	bool cur_state;
33 
34 	if (HAS_DDI(display)) {
35 		/*
36 		 * DDI does not have a specific FDI_TX register.
37 		 *
38 		 * FDI is never fed from EDP transcoder
39 		 * so pipe->transcoder cast is fine here.
40 		 */
41 		enum transcoder cpu_transcoder = (enum transcoder)pipe;
42 		cur_state = intel_de_read(display,
43 					  TRANS_DDI_FUNC_CTL(display, cpu_transcoder)) & TRANS_DDI_FUNC_ENABLE;
44 	} else {
45 		cur_state = intel_de_read(display, FDI_TX_CTL(pipe)) & FDI_TX_ENABLE;
46 	}
47 	INTEL_DISPLAY_STATE_WARN(display, cur_state != state,
48 				 "FDI TX state assertion failure (expected %s, current %s)\n",
49 				 str_on_off(state), str_on_off(cur_state));
50 }
51 
52 void assert_fdi_tx_enabled(struct intel_display *display, enum pipe pipe)
53 {
54 	assert_fdi_tx(display, pipe, true);
55 }
56 
57 void assert_fdi_tx_disabled(struct intel_display *display, enum pipe pipe)
58 {
59 	assert_fdi_tx(display, pipe, false);
60 }
61 
62 static void assert_fdi_rx(struct intel_display *display,
63 			  enum pipe pipe, bool state)
64 {
65 	bool cur_state;
66 
67 	cur_state = intel_de_read(display, FDI_RX_CTL(pipe)) & FDI_RX_ENABLE;
68 	INTEL_DISPLAY_STATE_WARN(display, cur_state != state,
69 				 "FDI RX state assertion failure (expected %s, current %s)\n",
70 				 str_on_off(state), str_on_off(cur_state));
71 }
72 
73 void assert_fdi_rx_enabled(struct intel_display *display, enum pipe pipe)
74 {
75 	assert_fdi_rx(display, pipe, true);
76 }
77 
78 void assert_fdi_rx_disabled(struct intel_display *display, enum pipe pipe)
79 {
80 	assert_fdi_rx(display, pipe, false);
81 }
82 
83 void assert_fdi_tx_pll_enabled(struct intel_display *display, enum pipe pipe)
84 {
85 	bool cur_state;
86 
87 	/* ILK FDI PLL is always enabled */
88 	if (display->platform.ironlake)
89 		return;
90 
91 	/* On Haswell, DDI ports are responsible for the FDI PLL setup */
92 	if (HAS_DDI(display))
93 		return;
94 
95 	cur_state = intel_de_read(display, FDI_TX_CTL(pipe)) & FDI_TX_PLL_ENABLE;
96 	INTEL_DISPLAY_STATE_WARN(display, !cur_state,
97 				 "FDI TX PLL assertion failure, should be active but is disabled\n");
98 }
99 
100 static void assert_fdi_rx_pll(struct intel_display *display,
101 			      enum pipe pipe, bool state)
102 {
103 	bool cur_state;
104 
105 	cur_state = intel_de_read(display, FDI_RX_CTL(pipe)) & FDI_RX_PLL_ENABLE;
106 	INTEL_DISPLAY_STATE_WARN(display, cur_state != state,
107 				 "FDI RX PLL assertion failure (expected %s, current %s)\n",
108 				 str_on_off(state), str_on_off(cur_state));
109 }
110 
111 void assert_fdi_rx_pll_enabled(struct intel_display *display, enum pipe pipe)
112 {
113 	assert_fdi_rx_pll(display, pipe, true);
114 }
115 
116 void assert_fdi_rx_pll_disabled(struct intel_display *display, enum pipe pipe)
117 {
118 	assert_fdi_rx_pll(display, pipe, false);
119 }
120 
121 void intel_fdi_link_train(struct intel_crtc *crtc,
122 			  const struct intel_crtc_state *crtc_state)
123 {
124 	struct intel_display *display = to_intel_display(crtc);
125 
126 	display->funcs.fdi->fdi_link_train(crtc, crtc_state);
127 }
128 
129 /**
130  * intel_fdi_add_affected_crtcs - add CRTCs on FDI affected by other modeset CRTCs
131  * @state: intel atomic state
132  *
133  * Add a CRTC using FDI to @state if changing another CRTC's FDI BW usage is
134  * known to affect the available FDI BW for the former CRTC. In practice this
135  * means adding CRTC B on IVYBRIDGE if its use of FDI lanes is limited (by
136  * CRTC C) and CRTC C is getting disabled.
137  *
138  * Returns 0 in case of success, or a negative error code otherwise.
139  */
140 int intel_fdi_add_affected_crtcs(struct intel_atomic_state *state)
141 {
142 	struct intel_display *display = to_intel_display(state);
143 	const struct intel_crtc_state *old_crtc_state;
144 	const struct intel_crtc_state *new_crtc_state;
145 	struct intel_crtc *crtc;
146 
147 	if (!display->platform.ivybridge || INTEL_NUM_PIPES(display) != 3)
148 		return 0;
149 
150 	crtc = intel_crtc_for_pipe(display, PIPE_C);
151 	new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
152 	if (!new_crtc_state)
153 		return 0;
154 
155 	if (!intel_crtc_needs_modeset(new_crtc_state))
156 		return 0;
157 
158 	old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
159 	if (!old_crtc_state->fdi_lanes)
160 		return 0;
161 
162 	crtc = intel_crtc_for_pipe(display, PIPE_B);
163 	new_crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
164 	if (IS_ERR(new_crtc_state))
165 		return PTR_ERR(new_crtc_state);
166 
167 	old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
168 	if (!old_crtc_state->fdi_lanes)
169 		return 0;
170 
171 	return intel_modeset_pipes_in_mask_early(state,
172 						 "FDI link BW decrease on pipe C",
173 						 BIT(PIPE_B));
174 }
175 
176 /* units of 100MHz */
177 static int pipe_required_fdi_lanes(struct intel_crtc_state *crtc_state)
178 {
179 	if (crtc_state->hw.enable && crtc_state->has_pch_encoder)
180 		return crtc_state->fdi_lanes;
181 
182 	return 0;
183 }
184 
185 static int ilk_check_fdi_lanes(struct intel_display *display, enum pipe pipe,
186 			       struct intel_crtc_state *pipe_config,
187 			       enum pipe *pipe_to_reduce)
188 {
189 	struct drm_atomic_state *state = pipe_config->uapi.state;
190 	struct intel_crtc *other_crtc;
191 	struct intel_crtc_state *other_crtc_state;
192 
193 	*pipe_to_reduce = pipe;
194 
195 	drm_dbg_kms(display->drm,
196 		    "checking fdi config on pipe %c, lanes %i\n",
197 		    pipe_name(pipe), pipe_config->fdi_lanes);
198 	if (pipe_config->fdi_lanes > 4) {
199 		drm_dbg_kms(display->drm,
200 			    "invalid fdi lane config on pipe %c: %i lanes\n",
201 			    pipe_name(pipe), pipe_config->fdi_lanes);
202 		return -EINVAL;
203 	}
204 
205 	if (display->platform.haswell || display->platform.broadwell) {
206 		if (pipe_config->fdi_lanes > 2) {
207 			drm_dbg_kms(display->drm,
208 				    "only 2 lanes on haswell, required: %i lanes\n",
209 				    pipe_config->fdi_lanes);
210 			return -EINVAL;
211 		} else {
212 			return 0;
213 		}
214 	}
215 
216 	if (INTEL_NUM_PIPES(display) == 2)
217 		return 0;
218 
219 	/* Ivybridge 3 pipe is really complicated */
220 	switch (pipe) {
221 	case PIPE_A:
222 		return 0;
223 	case PIPE_B:
224 		if (pipe_config->fdi_lanes <= 2)
225 			return 0;
226 
227 		other_crtc = intel_crtc_for_pipe(display, PIPE_C);
228 		other_crtc_state =
229 			intel_atomic_get_crtc_state(state, other_crtc);
230 		if (IS_ERR(other_crtc_state))
231 			return PTR_ERR(other_crtc_state);
232 
233 		if (pipe_required_fdi_lanes(other_crtc_state) > 0) {
234 			drm_dbg_kms(display->drm,
235 				    "invalid shared fdi lane config on pipe %c: %i lanes\n",
236 				    pipe_name(pipe), pipe_config->fdi_lanes);
237 			return -EINVAL;
238 		}
239 		return 0;
240 	case PIPE_C:
241 		if (pipe_config->fdi_lanes > 2) {
242 			drm_dbg_kms(display->drm,
243 				    "only 2 lanes on pipe %c: required %i lanes\n",
244 				    pipe_name(pipe), pipe_config->fdi_lanes);
245 			return -EINVAL;
246 		}
247 
248 		other_crtc = intel_crtc_for_pipe(display, PIPE_B);
249 		other_crtc_state =
250 			intel_atomic_get_crtc_state(state, other_crtc);
251 		if (IS_ERR(other_crtc_state))
252 			return PTR_ERR(other_crtc_state);
253 
254 		if (pipe_required_fdi_lanes(other_crtc_state) > 2) {
255 			drm_dbg_kms(display->drm,
256 				    "fdi link B uses too many lanes to enable link C\n");
257 
258 			*pipe_to_reduce = PIPE_B;
259 
260 			return -EINVAL;
261 		}
262 		return 0;
263 	default:
264 		MISSING_CASE(pipe);
265 		return 0;
266 	}
267 }
268 
269 void intel_fdi_pll_freq_update(struct intel_display *display)
270 {
271 	if (display->platform.ironlake) {
272 		u32 fdi_pll_clk;
273 
274 		fdi_pll_clk = intel_de_read(display, FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK;
275 
276 		display->fdi.pll_freq = (fdi_pll_clk + 2) * 10000;
277 	} else if (display->platform.sandybridge || display->platform.ivybridge) {
278 		display->fdi.pll_freq = 270000;
279 	} else {
280 		return;
281 	}
282 
283 	drm_dbg(display->drm, "FDI PLL freq=%d\n", display->fdi.pll_freq);
284 }
285 
286 int intel_fdi_link_freq(struct intel_display *display,
287 			const struct intel_crtc_state *pipe_config)
288 {
289 	if (HAS_DDI(display))
290 		return pipe_config->port_clock; /* SPLL */
291 	else
292 		return display->fdi.pll_freq;
293 }
294 
295 int ilk_fdi_compute_config(struct intel_crtc *crtc,
296 			   struct intel_crtc_state *pipe_config)
297 {
298 	struct intel_display *display = to_intel_display(crtc);
299 	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
300 	int lane, link_bw, fdi_dotclock;
301 
302 	/* FDI is a binary signal running at ~2.7GHz, encoding
303 	 * each output octet as 10 bits. The actual frequency
304 	 * is stored as a divider into a 100MHz clock, and the
305 	 * mode pixel clock is stored in units of 1KHz.
306 	 * Hence the bw of each lane in terms of the mode signal
307 	 * is:
308 	 */
309 	link_bw = intel_fdi_link_freq(display, pipe_config);
310 
311 	fdi_dotclock = adjusted_mode->crtc_clock;
312 
313 	lane = ilk_get_lanes_required(fdi_dotclock, link_bw,
314 				      pipe_config->pipe_bpp);
315 
316 	pipe_config->fdi_lanes = lane;
317 
318 	intel_link_compute_m_n(fxp_q4_from_int(pipe_config->pipe_bpp),
319 			       lane, fdi_dotclock,
320 			       link_bw,
321 			       intel_dp_bw_fec_overhead(false),
322 			       &pipe_config->fdi_m_n);
323 
324 	return 0;
325 }
326 
327 static int intel_fdi_atomic_check_bw(struct intel_atomic_state *state,
328 				     struct intel_crtc *crtc,
329 				     struct intel_crtc_state *pipe_config,
330 				     struct intel_link_bw_limits *limits)
331 {
332 	struct intel_display *display = to_intel_display(crtc);
333 	enum pipe pipe_to_reduce;
334 	int ret;
335 
336 	ret = ilk_check_fdi_lanes(display, crtc->pipe, pipe_config,
337 				  &pipe_to_reduce);
338 	if (ret != -EINVAL)
339 		return ret;
340 
341 	ret = intel_link_bw_reduce_bpp(state, limits,
342 				       BIT(pipe_to_reduce),
343 				       "FDI link BW");
344 
345 	return ret ? : -EAGAIN;
346 }
347 
348 /**
349  * intel_fdi_atomic_check_link - check all modeset FDI link configuration
350  * @state: intel atomic state
351  * @limits: link BW limits
352  *
353  * Check the link configuration for all modeset FDI outputs. If the
354  * configuration is invalid @limits will be updated if possible to
355  * reduce the total BW, after which the configuration for all CRTCs in
356  * @state must be recomputed with the updated @limits.
357  *
358  * Returns:
359  *   - 0 if the configuration is valid
360  *   - %-EAGAIN, if the configuration is invalid and @limits got updated
361  *     with fallback values with which the configuration of all CRTCs
362  *     in @state must be recomputed
363  *   - Other negative error, if the configuration is invalid without a
364  *     fallback possibility, or the check failed for another reason
365  */
366 int intel_fdi_atomic_check_link(struct intel_atomic_state *state,
367 				struct intel_link_bw_limits *limits)
368 {
369 	struct intel_crtc *crtc;
370 	struct intel_crtc_state *crtc_state;
371 	int i;
372 
373 	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
374 		int ret;
375 
376 		if (!crtc_state->has_pch_encoder ||
377 		    !intel_crtc_needs_modeset(crtc_state) ||
378 		    !crtc_state->hw.enable)
379 			continue;
380 
381 		ret = intel_fdi_atomic_check_bw(state, crtc, crtc_state, limits);
382 		if (ret)
383 			return ret;
384 	}
385 
386 	return 0;
387 }
388 
389 static void cpt_set_fdi_bc_bifurcation(struct intel_display *display, bool enable)
390 {
391 	u32 temp;
392 
393 	temp = intel_de_read(display, SOUTH_CHICKEN1);
394 	if (!!(temp & FDI_BC_BIFURCATION_SELECT) == enable)
395 		return;
396 
397 	drm_WARN_ON(display->drm,
398 		    intel_de_read(display, FDI_RX_CTL(PIPE_B)) &
399 		    FDI_RX_ENABLE);
400 	drm_WARN_ON(display->drm,
401 		    intel_de_read(display, FDI_RX_CTL(PIPE_C)) &
402 		    FDI_RX_ENABLE);
403 
404 	temp &= ~FDI_BC_BIFURCATION_SELECT;
405 	if (enable)
406 		temp |= FDI_BC_BIFURCATION_SELECT;
407 
408 	drm_dbg_kms(display->drm, "%sabling fdi C rx\n",
409 		    enable ? "en" : "dis");
410 	intel_de_write(display, SOUTH_CHICKEN1, temp);
411 	intel_de_posting_read(display, SOUTH_CHICKEN1);
412 }
413 
414 static void ivb_update_fdi_bc_bifurcation(const struct intel_crtc_state *crtc_state)
415 {
416 	struct intel_display *display = to_intel_display(crtc_state);
417 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
418 
419 	switch (crtc->pipe) {
420 	case PIPE_A:
421 		break;
422 	case PIPE_B:
423 		if (crtc_state->fdi_lanes > 2)
424 			cpt_set_fdi_bc_bifurcation(display, false);
425 		else
426 			cpt_set_fdi_bc_bifurcation(display, true);
427 
428 		break;
429 	case PIPE_C:
430 		cpt_set_fdi_bc_bifurcation(display, true);
431 
432 		break;
433 	default:
434 		MISSING_CASE(crtc->pipe);
435 	}
436 }
437 
438 void intel_fdi_normal_train(struct intel_crtc *crtc)
439 {
440 	struct intel_display *display = to_intel_display(crtc);
441 	enum pipe pipe = crtc->pipe;
442 	i915_reg_t reg;
443 	u32 temp;
444 
445 	/* enable normal train */
446 	reg = FDI_TX_CTL(pipe);
447 	temp = intel_de_read(display, reg);
448 	if (display->platform.ivybridge) {
449 		temp &= ~FDI_LINK_TRAIN_NONE_IVB;
450 		temp |= FDI_LINK_TRAIN_NONE_IVB | FDI_TX_ENHANCE_FRAME_ENABLE;
451 	} else {
452 		temp &= ~FDI_LINK_TRAIN_NONE;
453 		temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
454 	}
455 	intel_de_write(display, reg, temp);
456 
457 	reg = FDI_RX_CTL(pipe);
458 	temp = intel_de_read(display, reg);
459 	if (HAS_PCH_CPT(display)) {
460 		temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
461 		temp |= FDI_LINK_TRAIN_NORMAL_CPT;
462 	} else {
463 		temp &= ~FDI_LINK_TRAIN_NONE;
464 		temp |= FDI_LINK_TRAIN_NONE;
465 	}
466 	intel_de_write(display, reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE);
467 
468 	/* wait one idle pattern time */
469 	intel_de_posting_read(display, reg);
470 	udelay(1000);
471 
472 	/* IVB wants error correction enabled */
473 	if (display->platform.ivybridge)
474 		intel_de_rmw(display, reg, 0, FDI_FS_ERRC_ENABLE | FDI_FE_ERRC_ENABLE);
475 }
476 
477 /* The FDI link training functions for ILK/Ibexpeak. */
478 static void ilk_fdi_link_train(struct intel_crtc *crtc,
479 			       const struct intel_crtc_state *crtc_state)
480 {
481 	struct intel_display *display = to_intel_display(crtc);
482 	enum pipe pipe = crtc->pipe;
483 	i915_reg_t reg;
484 	u32 temp, tries;
485 
486 	/*
487 	 * Write the TU size bits before fdi link training, so that error
488 	 * detection works.
489 	 */
490 	intel_de_write(display, FDI_RX_TUSIZE1(pipe),
491 		       intel_de_read(display, PIPE_DATA_M1(display, pipe)) & TU_SIZE_MASK);
492 
493 	/* FDI needs bits from pipe first */
494 	assert_transcoder_enabled(display, crtc_state->cpu_transcoder);
495 
496 	/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
497 	   for train result */
498 	reg = FDI_RX_IMR(pipe);
499 	temp = intel_de_read(display, reg);
500 	temp &= ~FDI_RX_SYMBOL_LOCK;
501 	temp &= ~FDI_RX_BIT_LOCK;
502 	intel_de_write(display, reg, temp);
503 	intel_de_read(display, reg);
504 	udelay(150);
505 
506 	/* enable CPU FDI TX and PCH FDI RX */
507 	reg = FDI_TX_CTL(pipe);
508 	temp = intel_de_read(display, reg);
509 	temp &= ~FDI_DP_PORT_WIDTH_MASK;
510 	temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
511 	temp &= ~FDI_LINK_TRAIN_NONE;
512 	temp |= FDI_LINK_TRAIN_PATTERN_1;
513 	intel_de_write(display, reg, temp | FDI_TX_ENABLE);
514 
515 	reg = FDI_RX_CTL(pipe);
516 	temp = intel_de_read(display, reg);
517 	temp &= ~FDI_LINK_TRAIN_NONE;
518 	temp |= FDI_LINK_TRAIN_PATTERN_1;
519 	intel_de_write(display, reg, temp | FDI_RX_ENABLE);
520 
521 	intel_de_posting_read(display, reg);
522 	udelay(150);
523 
524 	/* Ironlake workaround, enable clock pointer after FDI enable*/
525 	intel_de_write(display, FDI_RX_CHICKEN(pipe),
526 		       FDI_RX_PHASE_SYNC_POINTER_OVR);
527 	intel_de_write(display, FDI_RX_CHICKEN(pipe),
528 		       FDI_RX_PHASE_SYNC_POINTER_OVR | FDI_RX_PHASE_SYNC_POINTER_EN);
529 
530 	reg = FDI_RX_IIR(pipe);
531 	for (tries = 0; tries < 5; tries++) {
532 		temp = intel_de_read(display, reg);
533 		drm_dbg_kms(display->drm, "FDI_RX_IIR 0x%x\n", temp);
534 
535 		if ((temp & FDI_RX_BIT_LOCK)) {
536 			drm_dbg_kms(display->drm, "FDI train 1 done.\n");
537 			intel_de_write(display, reg, temp | FDI_RX_BIT_LOCK);
538 			break;
539 		}
540 	}
541 	if (tries == 5)
542 		drm_err(display->drm, "FDI train 1 fail!\n");
543 
544 	/* Train 2 */
545 	intel_de_rmw(display, FDI_TX_CTL(pipe),
546 		     FDI_LINK_TRAIN_NONE, FDI_LINK_TRAIN_PATTERN_2);
547 	intel_de_rmw(display, FDI_RX_CTL(pipe),
548 		     FDI_LINK_TRAIN_NONE, FDI_LINK_TRAIN_PATTERN_2);
549 	intel_de_posting_read(display, FDI_RX_CTL(pipe));
550 	udelay(150);
551 
552 	reg = FDI_RX_IIR(pipe);
553 	for (tries = 0; tries < 5; tries++) {
554 		temp = intel_de_read(display, reg);
555 		drm_dbg_kms(display->drm, "FDI_RX_IIR 0x%x\n", temp);
556 
557 		if (temp & FDI_RX_SYMBOL_LOCK) {
558 			intel_de_write(display, reg,
559 				       temp | FDI_RX_SYMBOL_LOCK);
560 			drm_dbg_kms(display->drm, "FDI train 2 done.\n");
561 			break;
562 		}
563 	}
564 	if (tries == 5)
565 		drm_err(display->drm, "FDI train 2 fail!\n");
566 
567 	drm_dbg_kms(display->drm, "FDI train done\n");
568 
569 }
570 
571 static const int snb_b_fdi_train_param[] = {
572 	FDI_LINK_TRAIN_400MV_0DB_SNB_B,
573 	FDI_LINK_TRAIN_400MV_6DB_SNB_B,
574 	FDI_LINK_TRAIN_600MV_3_5DB_SNB_B,
575 	FDI_LINK_TRAIN_800MV_0DB_SNB_B,
576 };
577 
578 /* The FDI link training functions for SNB/Cougarpoint. */
579 static void gen6_fdi_link_train(struct intel_crtc *crtc,
580 				const struct intel_crtc_state *crtc_state)
581 {
582 	struct intel_display *display = to_intel_display(crtc);
583 	enum pipe pipe = crtc->pipe;
584 	i915_reg_t reg;
585 	u32 temp, i, retry;
586 
587 	/*
588 	 * Write the TU size bits before fdi link training, so that error
589 	 * detection works.
590 	 */
591 	intel_de_write(display, FDI_RX_TUSIZE1(pipe),
592 		       intel_de_read(display, PIPE_DATA_M1(display, pipe)) & TU_SIZE_MASK);
593 
594 	/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
595 	   for train result */
596 	reg = FDI_RX_IMR(pipe);
597 	temp = intel_de_read(display, reg);
598 	temp &= ~FDI_RX_SYMBOL_LOCK;
599 	temp &= ~FDI_RX_BIT_LOCK;
600 	intel_de_write(display, reg, temp);
601 
602 	intel_de_posting_read(display, reg);
603 	udelay(150);
604 
605 	/* enable CPU FDI TX and PCH FDI RX */
606 	reg = FDI_TX_CTL(pipe);
607 	temp = intel_de_read(display, reg);
608 	temp &= ~FDI_DP_PORT_WIDTH_MASK;
609 	temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
610 	temp &= ~FDI_LINK_TRAIN_NONE;
611 	temp |= FDI_LINK_TRAIN_PATTERN_1;
612 	temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
613 	/* SNB-B */
614 	temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
615 	intel_de_write(display, reg, temp | FDI_TX_ENABLE);
616 
617 	intel_de_write(display, FDI_RX_MISC(pipe),
618 		       FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
619 
620 	reg = FDI_RX_CTL(pipe);
621 	temp = intel_de_read(display, reg);
622 	if (HAS_PCH_CPT(display)) {
623 		temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
624 		temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
625 	} else {
626 		temp &= ~FDI_LINK_TRAIN_NONE;
627 		temp |= FDI_LINK_TRAIN_PATTERN_1;
628 	}
629 	intel_de_write(display, reg, temp | FDI_RX_ENABLE);
630 
631 	intel_de_posting_read(display, reg);
632 	udelay(150);
633 
634 	for (i = 0; i < 4; i++) {
635 		intel_de_rmw(display, FDI_TX_CTL(pipe),
636 			     FDI_LINK_TRAIN_VOL_EMP_MASK, snb_b_fdi_train_param[i]);
637 		intel_de_posting_read(display, FDI_TX_CTL(pipe));
638 		udelay(500);
639 
640 		for (retry = 0; retry < 5; retry++) {
641 			reg = FDI_RX_IIR(pipe);
642 			temp = intel_de_read(display, reg);
643 			drm_dbg_kms(display->drm, "FDI_RX_IIR 0x%x\n", temp);
644 			if (temp & FDI_RX_BIT_LOCK) {
645 				intel_de_write(display, reg,
646 					       temp | FDI_RX_BIT_LOCK);
647 				drm_dbg_kms(display->drm,
648 					    "FDI train 1 done.\n");
649 				break;
650 			}
651 			udelay(50);
652 		}
653 		if (retry < 5)
654 			break;
655 	}
656 	if (i == 4)
657 		drm_err(display->drm, "FDI train 1 fail!\n");
658 
659 	/* Train 2 */
660 	reg = FDI_TX_CTL(pipe);
661 	temp = intel_de_read(display, reg);
662 	temp &= ~FDI_LINK_TRAIN_NONE;
663 	temp |= FDI_LINK_TRAIN_PATTERN_2;
664 	if (display->platform.sandybridge) {
665 		temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
666 		/* SNB-B */
667 		temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
668 	}
669 	intel_de_write(display, reg, temp);
670 
671 	reg = FDI_RX_CTL(pipe);
672 	temp = intel_de_read(display, reg);
673 	if (HAS_PCH_CPT(display)) {
674 		temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
675 		temp |= FDI_LINK_TRAIN_PATTERN_2_CPT;
676 	} else {
677 		temp &= ~FDI_LINK_TRAIN_NONE;
678 		temp |= FDI_LINK_TRAIN_PATTERN_2;
679 	}
680 	intel_de_write(display, reg, temp);
681 
682 	intel_de_posting_read(display, reg);
683 	udelay(150);
684 
685 	for (i = 0; i < 4; i++) {
686 		intel_de_rmw(display, FDI_TX_CTL(pipe),
687 			     FDI_LINK_TRAIN_VOL_EMP_MASK, snb_b_fdi_train_param[i]);
688 		intel_de_posting_read(display, FDI_TX_CTL(pipe));
689 		udelay(500);
690 
691 		for (retry = 0; retry < 5; retry++) {
692 			reg = FDI_RX_IIR(pipe);
693 			temp = intel_de_read(display, reg);
694 			drm_dbg_kms(display->drm, "FDI_RX_IIR 0x%x\n", temp);
695 			if (temp & FDI_RX_SYMBOL_LOCK) {
696 				intel_de_write(display, reg,
697 					       temp | FDI_RX_SYMBOL_LOCK);
698 				drm_dbg_kms(display->drm,
699 					    "FDI train 2 done.\n");
700 				break;
701 			}
702 			udelay(50);
703 		}
704 		if (retry < 5)
705 			break;
706 	}
707 	if (i == 4)
708 		drm_err(display->drm, "FDI train 2 fail!\n");
709 
710 	drm_dbg_kms(display->drm, "FDI train done.\n");
711 }
712 
713 /* Manual link training for Ivy Bridge A0 parts */
714 static void ivb_manual_fdi_link_train(struct intel_crtc *crtc,
715 				      const struct intel_crtc_state *crtc_state)
716 {
717 	struct intel_display *display = to_intel_display(crtc);
718 	enum pipe pipe = crtc->pipe;
719 	i915_reg_t reg;
720 	u32 temp, i, j;
721 
722 	ivb_update_fdi_bc_bifurcation(crtc_state);
723 
724 	/*
725 	 * Write the TU size bits before fdi link training, so that error
726 	 * detection works.
727 	 */
728 	intel_de_write(display, FDI_RX_TUSIZE1(pipe),
729 		       intel_de_read(display, PIPE_DATA_M1(display, pipe)) & TU_SIZE_MASK);
730 
731 	/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
732 	   for train result */
733 	reg = FDI_RX_IMR(pipe);
734 	temp = intel_de_read(display, reg);
735 	temp &= ~FDI_RX_SYMBOL_LOCK;
736 	temp &= ~FDI_RX_BIT_LOCK;
737 	intel_de_write(display, reg, temp);
738 
739 	intel_de_posting_read(display, reg);
740 	udelay(150);
741 
742 	drm_dbg_kms(display->drm, "FDI_RX_IIR before link train 0x%x\n",
743 		    intel_de_read(display, FDI_RX_IIR(pipe)));
744 
745 	/* Try each vswing and preemphasis setting twice before moving on */
746 	for (j = 0; j < ARRAY_SIZE(snb_b_fdi_train_param) * 2; j++) {
747 		/* disable first in case we need to retry */
748 		reg = FDI_TX_CTL(pipe);
749 		temp = intel_de_read(display, reg);
750 		temp &= ~(FDI_LINK_TRAIN_AUTO | FDI_LINK_TRAIN_NONE_IVB);
751 		temp &= ~FDI_TX_ENABLE;
752 		intel_de_write(display, reg, temp);
753 
754 		reg = FDI_RX_CTL(pipe);
755 		temp = intel_de_read(display, reg);
756 		temp &= ~FDI_LINK_TRAIN_AUTO;
757 		temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
758 		temp &= ~FDI_RX_ENABLE;
759 		intel_de_write(display, reg, temp);
760 
761 		/* enable CPU FDI TX and PCH FDI RX */
762 		reg = FDI_TX_CTL(pipe);
763 		temp = intel_de_read(display, reg);
764 		temp &= ~FDI_DP_PORT_WIDTH_MASK;
765 		temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
766 		temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
767 		temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
768 		temp |= snb_b_fdi_train_param[j/2];
769 		temp |= FDI_COMPOSITE_SYNC;
770 		intel_de_write(display, reg, temp | FDI_TX_ENABLE);
771 
772 		intel_de_write(display, FDI_RX_MISC(pipe),
773 			       FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
774 
775 		reg = FDI_RX_CTL(pipe);
776 		temp = intel_de_read(display, reg);
777 		temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
778 		temp |= FDI_COMPOSITE_SYNC;
779 		intel_de_write(display, reg, temp | FDI_RX_ENABLE);
780 
781 		intel_de_posting_read(display, reg);
782 		udelay(1); /* should be 0.5us */
783 
784 		for (i = 0; i < 4; i++) {
785 			reg = FDI_RX_IIR(pipe);
786 			temp = intel_de_read(display, reg);
787 			drm_dbg_kms(display->drm, "FDI_RX_IIR 0x%x\n", temp);
788 
789 			if (temp & FDI_RX_BIT_LOCK ||
790 			    (intel_de_read(display, reg) & FDI_RX_BIT_LOCK)) {
791 				intel_de_write(display, reg,
792 					       temp | FDI_RX_BIT_LOCK);
793 				drm_dbg_kms(display->drm,
794 					    "FDI train 1 done, level %i.\n",
795 					    i);
796 				break;
797 			}
798 			udelay(1); /* should be 0.5us */
799 		}
800 		if (i == 4) {
801 			drm_dbg_kms(display->drm,
802 				    "FDI train 1 fail on vswing %d\n", j / 2);
803 			continue;
804 		}
805 
806 		/* Train 2 */
807 		intel_de_rmw(display, FDI_TX_CTL(pipe),
808 			     FDI_LINK_TRAIN_NONE_IVB,
809 			     FDI_LINK_TRAIN_PATTERN_2_IVB);
810 		intel_de_rmw(display, FDI_RX_CTL(pipe),
811 			     FDI_LINK_TRAIN_PATTERN_MASK_CPT,
812 			     FDI_LINK_TRAIN_PATTERN_2_CPT);
813 		intel_de_posting_read(display, FDI_RX_CTL(pipe));
814 		udelay(2); /* should be 1.5us */
815 
816 		for (i = 0; i < 4; i++) {
817 			reg = FDI_RX_IIR(pipe);
818 			temp = intel_de_read(display, reg);
819 			drm_dbg_kms(display->drm, "FDI_RX_IIR 0x%x\n", temp);
820 
821 			if (temp & FDI_RX_SYMBOL_LOCK ||
822 			    (intel_de_read(display, reg) & FDI_RX_SYMBOL_LOCK)) {
823 				intel_de_write(display, reg,
824 					       temp | FDI_RX_SYMBOL_LOCK);
825 				drm_dbg_kms(display->drm,
826 					    "FDI train 2 done, level %i.\n",
827 					    i);
828 				goto train_done;
829 			}
830 			udelay(2); /* should be 1.5us */
831 		}
832 		if (i == 4)
833 			drm_dbg_kms(display->drm,
834 				    "FDI train 2 fail on vswing %d\n", j / 2);
835 	}
836 
837 train_done:
838 	drm_dbg_kms(display->drm, "FDI train done.\n");
839 }
840 
841 /* Starting with Haswell, different DDI ports can work in FDI mode for
842  * connection to the PCH-located connectors. For this, it is necessary to train
843  * both the DDI port and PCH receiver for the desired DDI buffer settings.
844  *
845  * The recommended port to work in FDI mode is DDI E, which we use here. Also,
846  * please note that when FDI mode is active on DDI E, it shares 2 lines with
847  * DDI A (which is used for eDP)
848  */
849 void hsw_fdi_link_train(struct intel_encoder *encoder,
850 			const struct intel_crtc_state *crtc_state)
851 {
852 	struct intel_display *display = to_intel_display(crtc_state);
853 	u32 temp, i, rx_ctl_val;
854 	int n_entries;
855 
856 	encoder->get_buf_trans(encoder, crtc_state, &n_entries);
857 
858 	hsw_prepare_dp_ddi_buffers(encoder, crtc_state);
859 
860 	/* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
861 	 * mode set "sequence for CRT port" document:
862 	 * - TP1 to TP2 time with the default value
863 	 * - FDI delay to 90h
864 	 *
865 	 * WaFDIAutoLinkSetTimingOverrride:hsw
866 	 */
867 	intel_de_write(display, FDI_RX_MISC(PIPE_A),
868 		       FDI_RX_PWRDN_LANE1_VAL(2) |
869 		       FDI_RX_PWRDN_LANE0_VAL(2) |
870 		       FDI_RX_TP1_TO_TP2_48 |
871 		       FDI_RX_FDI_DELAY_90);
872 
873 	/* Enable the PCH Receiver FDI PLL */
874 	rx_ctl_val = display->fdi.rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
875 		     FDI_RX_PLL_ENABLE |
876 		     FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
877 	intel_de_write(display, FDI_RX_CTL(PIPE_A), rx_ctl_val);
878 	intel_de_posting_read(display, FDI_RX_CTL(PIPE_A));
879 	udelay(220);
880 
881 	/* Switch from Rawclk to PCDclk */
882 	rx_ctl_val |= FDI_PCDCLK;
883 	intel_de_write(display, FDI_RX_CTL(PIPE_A), rx_ctl_val);
884 
885 	/* Configure Port Clock Select */
886 	drm_WARN_ON(display->drm, crtc_state->intel_dpll->info->id != DPLL_ID_SPLL);
887 	intel_ddi_enable_clock(encoder, crtc_state);
888 
889 	/* Start the training iterating through available voltages and emphasis,
890 	 * testing each value twice. */
891 	for (i = 0; i < n_entries * 2; i++) {
892 		/* Configure DP_TP_CTL with auto-training */
893 		intel_de_write(display, DP_TP_CTL(PORT_E),
894 			       DP_TP_CTL_FDI_AUTOTRAIN |
895 			       DP_TP_CTL_ENHANCED_FRAME_ENABLE |
896 			       DP_TP_CTL_LINK_TRAIN_PAT1 |
897 			       DP_TP_CTL_ENABLE);
898 
899 		/* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
900 		 * DDI E does not support port reversal, the functionality is
901 		 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
902 		 * port reversal bit */
903 		intel_de_write(display, DDI_BUF_CTL(PORT_E),
904 			       DDI_BUF_CTL_ENABLE |
905 			       ((crtc_state->fdi_lanes - 1) << 1) |
906 			       DDI_BUF_TRANS_SELECT(i / 2));
907 		intel_de_posting_read(display, DDI_BUF_CTL(PORT_E));
908 
909 		udelay(600);
910 
911 		/* Program PCH FDI Receiver TU */
912 		intel_de_write(display, FDI_RX_TUSIZE1(PIPE_A), TU_SIZE(64));
913 
914 		/* Enable PCH FDI Receiver with auto-training */
915 		rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
916 		intel_de_write(display, FDI_RX_CTL(PIPE_A), rx_ctl_val);
917 		intel_de_posting_read(display, FDI_RX_CTL(PIPE_A));
918 
919 		/* Wait for FDI receiver lane calibration */
920 		udelay(30);
921 
922 		/* Unset FDI_RX_MISC pwrdn lanes */
923 		intel_de_rmw(display, FDI_RX_MISC(PIPE_A),
924 			     FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK, 0);
925 		intel_de_posting_read(display, FDI_RX_MISC(PIPE_A));
926 
927 		/* Wait for FDI auto training time */
928 		udelay(5);
929 
930 		temp = intel_de_read(display, DP_TP_STATUS(PORT_E));
931 		if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
932 			drm_dbg_kms(display->drm,
933 				    "FDI link training done on step %d\n", i);
934 			break;
935 		}
936 
937 		/*
938 		 * Leave things enabled even if we failed to train FDI.
939 		 * Results in less fireworks from the state checker.
940 		 */
941 		if (i == n_entries * 2 - 1) {
942 			drm_err(display->drm, "FDI link training failed!\n");
943 			break;
944 		}
945 
946 		rx_ctl_val &= ~FDI_RX_ENABLE;
947 		intel_de_write(display, FDI_RX_CTL(PIPE_A), rx_ctl_val);
948 		intel_de_posting_read(display, FDI_RX_CTL(PIPE_A));
949 
950 		intel_de_rmw(display, DDI_BUF_CTL(PORT_E), DDI_BUF_CTL_ENABLE, 0);
951 		intel_de_posting_read(display, DDI_BUF_CTL(PORT_E));
952 
953 		/* Disable DP_TP_CTL and FDI_RX_CTL and retry */
954 		intel_de_rmw(display, DP_TP_CTL(PORT_E), DP_TP_CTL_ENABLE, 0);
955 		intel_de_posting_read(display, DP_TP_CTL(PORT_E));
956 
957 		intel_wait_ddi_buf_idle(display, PORT_E);
958 
959 		/* Reset FDI_RX_MISC pwrdn lanes */
960 		intel_de_rmw(display, FDI_RX_MISC(PIPE_A),
961 			     FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK,
962 			     FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2));
963 		intel_de_posting_read(display, FDI_RX_MISC(PIPE_A));
964 	}
965 
966 	/* Enable normal pixel sending for FDI */
967 	intel_de_write(display, DP_TP_CTL(PORT_E),
968 		       DP_TP_CTL_FDI_AUTOTRAIN |
969 		       DP_TP_CTL_LINK_TRAIN_NORMAL |
970 		       DP_TP_CTL_ENHANCED_FRAME_ENABLE |
971 		       DP_TP_CTL_ENABLE);
972 }
973 
974 void hsw_fdi_disable(struct intel_encoder *encoder)
975 {
976 	struct intel_display *display = to_intel_display(encoder);
977 
978 	/*
979 	 * Bspec lists this as both step 13 (before DDI_BUF_CTL disable)
980 	 * and step 18 (after clearing PORT_CLK_SEL). Based on a BUN,
981 	 * step 13 is the correct place for it. Step 18 is where it was
982 	 * originally before the BUN.
983 	 */
984 	intel_de_rmw(display, FDI_RX_CTL(PIPE_A), FDI_RX_ENABLE, 0);
985 	intel_de_rmw(display, DDI_BUF_CTL(PORT_E), DDI_BUF_CTL_ENABLE, 0);
986 	intel_wait_ddi_buf_idle(display, PORT_E);
987 	intel_ddi_disable_clock(encoder);
988 	intel_de_rmw(display, FDI_RX_MISC(PIPE_A),
989 		     FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK,
990 		     FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2));
991 	intel_de_rmw(display, FDI_RX_CTL(PIPE_A), FDI_PCDCLK, 0);
992 	intel_de_rmw(display, FDI_RX_CTL(PIPE_A), FDI_RX_PLL_ENABLE, 0);
993 }
994 
995 void ilk_fdi_pll_enable(const struct intel_crtc_state *crtc_state)
996 {
997 	struct intel_display *display = to_intel_display(crtc_state);
998 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
999 	enum pipe pipe = crtc->pipe;
1000 	i915_reg_t reg;
1001 	u32 temp;
1002 
1003 	/* enable PCH FDI RX PLL, wait warmup plus DMI latency */
1004 	reg = FDI_RX_CTL(pipe);
1005 	temp = intel_de_read(display, reg);
1006 	temp &= ~(FDI_DP_PORT_WIDTH_MASK | (0x7 << 16));
1007 	temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
1008 	temp |= (intel_de_read(display, TRANSCONF(display, pipe)) & TRANSCONF_BPC_MASK) << 11;
1009 	intel_de_write(display, reg, temp | FDI_RX_PLL_ENABLE);
1010 
1011 	intel_de_posting_read(display, reg);
1012 	udelay(200);
1013 
1014 	/* Switch from Rawclk to PCDclk */
1015 	intel_de_rmw(display, reg, 0, FDI_PCDCLK);
1016 	intel_de_posting_read(display, reg);
1017 	udelay(200);
1018 
1019 	/* Enable CPU FDI TX PLL, always on for Ironlake */
1020 	reg = FDI_TX_CTL(pipe);
1021 	temp = intel_de_read(display, reg);
1022 	if ((temp & FDI_TX_PLL_ENABLE) == 0) {
1023 		intel_de_write(display, reg, temp | FDI_TX_PLL_ENABLE);
1024 
1025 		intel_de_posting_read(display, reg);
1026 		udelay(100);
1027 	}
1028 }
1029 
1030 void ilk_fdi_pll_disable(struct intel_crtc *crtc)
1031 {
1032 	struct intel_display *display = to_intel_display(crtc);
1033 	enum pipe pipe = crtc->pipe;
1034 
1035 	/* Switch from PCDclk to Rawclk */
1036 	intel_de_rmw(display, FDI_RX_CTL(pipe), FDI_PCDCLK, 0);
1037 
1038 	/* Disable CPU FDI TX PLL */
1039 	intel_de_rmw(display, FDI_TX_CTL(pipe), FDI_TX_PLL_ENABLE, 0);
1040 	intel_de_posting_read(display, FDI_TX_CTL(pipe));
1041 	udelay(100);
1042 
1043 	/* Wait for the clocks to turn off. */
1044 	intel_de_rmw(display, FDI_RX_CTL(pipe), FDI_RX_PLL_ENABLE, 0);
1045 	intel_de_posting_read(display, FDI_RX_CTL(pipe));
1046 	udelay(100);
1047 }
1048 
1049 void ilk_fdi_disable(struct intel_crtc *crtc)
1050 {
1051 	struct intel_display *display = to_intel_display(crtc);
1052 	enum pipe pipe = crtc->pipe;
1053 	i915_reg_t reg;
1054 	u32 temp;
1055 
1056 	/* disable CPU FDI tx and PCH FDI rx */
1057 	intel_de_rmw(display, FDI_TX_CTL(pipe), FDI_TX_ENABLE, 0);
1058 	intel_de_posting_read(display, FDI_TX_CTL(pipe));
1059 
1060 	reg = FDI_RX_CTL(pipe);
1061 	temp = intel_de_read(display, reg);
1062 	temp &= ~(0x7 << 16);
1063 	temp |= (intel_de_read(display, TRANSCONF(display, pipe)) & TRANSCONF_BPC_MASK) << 11;
1064 	intel_de_write(display, reg, temp & ~FDI_RX_ENABLE);
1065 
1066 	intel_de_posting_read(display, reg);
1067 	udelay(100);
1068 
1069 	/* Ironlake workaround, disable clock pointer after downing FDI */
1070 	if (HAS_PCH_IBX(display))
1071 		intel_de_write(display, FDI_RX_CHICKEN(pipe),
1072 			       FDI_RX_PHASE_SYNC_POINTER_OVR);
1073 
1074 	/* still set train pattern 1 */
1075 	intel_de_rmw(display, FDI_TX_CTL(pipe),
1076 		     FDI_LINK_TRAIN_NONE, FDI_LINK_TRAIN_PATTERN_1);
1077 
1078 	reg = FDI_RX_CTL(pipe);
1079 	temp = intel_de_read(display, reg);
1080 	if (HAS_PCH_CPT(display)) {
1081 		temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
1082 		temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
1083 	} else {
1084 		temp &= ~FDI_LINK_TRAIN_NONE;
1085 		temp |= FDI_LINK_TRAIN_PATTERN_1;
1086 	}
1087 	/* BPC in FDI rx is consistent with that in TRANSCONF */
1088 	temp &= ~(0x07 << 16);
1089 	temp |= (intel_de_read(display, TRANSCONF(display, pipe)) & TRANSCONF_BPC_MASK) << 11;
1090 	intel_de_write(display, reg, temp);
1091 
1092 	intel_de_posting_read(display, reg);
1093 	udelay(100);
1094 }
1095 
1096 static const struct intel_fdi_funcs ilk_funcs = {
1097 	.fdi_link_train = ilk_fdi_link_train,
1098 };
1099 
1100 static const struct intel_fdi_funcs gen6_funcs = {
1101 	.fdi_link_train = gen6_fdi_link_train,
1102 };
1103 
1104 static const struct intel_fdi_funcs ivb_funcs = {
1105 	.fdi_link_train = ivb_manual_fdi_link_train,
1106 };
1107 
1108 void
1109 intel_fdi_init_hook(struct intel_display *display)
1110 {
1111 	if (display->platform.ironlake) {
1112 		display->funcs.fdi = &ilk_funcs;
1113 	} else if (display->platform.sandybridge) {
1114 		display->funcs.fdi = &gen6_funcs;
1115 	} else if (display->platform.ivybridge) {
1116 		/* FIXME: detect B0+ stepping and use auto training */
1117 		display->funcs.fdi = &ivb_funcs;
1118 	}
1119 }
1120