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
24struct intel_fdi_funcs {
25 void (*fdi_link_train)(struct intel_crtc *crtc,
26 const struct intel_crtc_state *crtc_state);
27};
28
29static 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
52void assert_fdi_tx_enabled(struct intel_display *display, enum pipe pipe)
53{
54 assert_fdi_tx(display, pipe, state: true);
55}
56
57void assert_fdi_tx_disabled(struct intel_display *display, enum pipe pipe)
58{
59 assert_fdi_tx(display, pipe, state: false);
60}
61
62static 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
73void assert_fdi_rx_enabled(struct intel_display *display, enum pipe pipe)
74{
75 assert_fdi_rx(display, pipe, state: true);
76}
77
78void assert_fdi_rx_disabled(struct intel_display *display, enum pipe pipe)
79{
80 assert_fdi_rx(display, pipe, state: false);
81}
82
83void 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
100static 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
111void assert_fdi_rx_pll_enabled(struct intel_display *display, enum pipe pipe)
112{
113 assert_fdi_rx_pll(display, pipe, state: true);
114}
115
116void assert_fdi_rx_pll_disabled(struct intel_display *display, enum pipe pipe)
117{
118 assert_fdi_rx_pll(display, pipe, state: false);
119}
120
121void 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 */
140int 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: 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(crtc_state: 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: PIPE_B);
163 new_crtc_state = intel_atomic_get_crtc_state(state: &state->base, crtc);
164 if (IS_ERR(ptr: new_crtc_state))
165 return PTR_ERR(ptr: 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 reason: "FDI link BW decrease on pipe C",
173 BIT(PIPE_B));
174}
175
176/* units of 100MHz */
177static 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
185static 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: PIPE_C);
228 other_crtc_state =
229 intel_atomic_get_crtc_state(state, crtc: other_crtc);
230 if (IS_ERR(ptr: other_crtc_state))
231 return PTR_ERR(ptr: other_crtc_state);
232
233 if (pipe_required_fdi_lanes(crtc_state: 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: PIPE_B);
249 other_crtc_state =
250 intel_atomic_get_crtc_state(state, crtc: other_crtc);
251 if (IS_ERR(ptr: other_crtc_state))
252 return PTR_ERR(ptr: other_crtc_state);
253
254 if (pipe_required_fdi_lanes(crtc_state: 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
269void 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
286int 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
295int 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(target_clock: fdi_dotclock, link_bw,
314 bpp: pipe_config->pipe_bpp);
315
316 pipe_config->fdi_lanes = lane;
317
318 intel_link_compute_m_n(bpp: fxp_q4_from_int(val_int: pipe_config->pipe_bpp),
319 nlanes: lane, pixel_clock: fdi_dotclock,
320 link_clock: link_bw,
321 bw_overhead: intel_dp_bw_fec_overhead(fec_enabled: false),
322 m_n: &pipe_config->fdi_m_n);
323
324 return 0;
325}
326
327static 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, pipe: crtc->pipe, pipe_config,
337 pipe_to_reduce: &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 reason: "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 */
366int 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, pipe_config: crtc_state, limits);
382 if (ret)
383 return ret;
384 }
385
386 return 0;
387}
388
389static 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, val: temp);
411 intel_de_posting_read(display, SOUTH_CHICKEN1);
412}
413
414static 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, enable: false);
425 else
426 cpt_set_fdi_bc_bifurcation(display, enable: true);
427
428 break;
429 case PIPE_C:
430 cpt_set_fdi_bc_bifurcation(display, enable: true);
431
432 break;
433 default:
434 MISSING_CASE(crtc->pipe);
435 }
436}
437
438void 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, val: 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, val: temp | FDI_RX_ENHANCE_FRAME_ENABLE);
467
468 /* wait one idle pattern time */
469 intel_de_posting_read(display, reg);
470 udelay(usec: 1000);
471
472 /* IVB wants error correction enabled */
473 if (display->platform.ivybridge)
474 intel_de_rmw(display, reg, clear: 0, FDI_FS_ERRC_ENABLE | FDI_FE_ERRC_ENABLE);
475}
476
477/* The FDI link training functions for ILK/Ibexpeak. */
478static 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 val: 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, val: temp);
503 intel_de_read(display, reg);
504 udelay(usec: 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, val: 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, val: temp | FDI_RX_ENABLE);
520
521 intel_de_posting_read(display, reg);
522 udelay(usec: 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, val: 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(usec: 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 val: 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
571static 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. */
579static 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 val: 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, val: temp);
601
602 intel_de_posting_read(display, reg);
603 udelay(usec: 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, val: 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, val: temp | FDI_RX_ENABLE);
630
631 intel_de_posting_read(display, reg);
632 udelay(usec: 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, set: snb_b_fdi_train_param[i]);
637 intel_de_posting_read(display, FDI_TX_CTL(pipe));
638 udelay(usec: 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 val: temp | FDI_RX_BIT_LOCK);
647 drm_dbg_kms(display->drm,
648 "FDI train 1 done.\n");
649 break;
650 }
651 udelay(usec: 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, val: 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, val: temp);
681
682 intel_de_posting_read(display, reg);
683 udelay(usec: 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, set: snb_b_fdi_train_param[i]);
688 intel_de_posting_read(display, FDI_TX_CTL(pipe));
689 udelay(usec: 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 val: temp | FDI_RX_SYMBOL_LOCK);
698 drm_dbg_kms(display->drm,
699 "FDI train 2 done.\n");
700 break;
701 }
702 udelay(usec: 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 */
714static 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 val: 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, val: temp);
738
739 intel_de_posting_read(display, reg);
740 udelay(usec: 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, val: 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, val: 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, val: 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, val: temp | FDI_RX_ENABLE);
780
781 intel_de_posting_read(display, reg);
782 udelay(usec: 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 val: 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(usec: 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(usec: 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 val: 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(usec: 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
837train_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 */
849void 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), val: rx_ctl_val);
878 intel_de_posting_read(display, FDI_RX_CTL(PIPE_A));
879 udelay(usec: 220);
880
881 /* Switch from Rawclk to PCDclk */
882 rx_ctl_val |= FDI_PCDCLK;
883 intel_de_write(display, FDI_RX_CTL(PIPE_A), val: 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(usec: 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), val: rx_ctl_val);
917 intel_de_posting_read(display, FDI_RX_CTL(PIPE_A));
918
919 /* Wait for FDI receiver lane calibration */
920 udelay(usec: 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, set: 0);
925 intel_de_posting_read(display, FDI_RX_MISC(PIPE_A));
926
927 /* Wait for FDI auto training time */
928 udelay(usec: 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), val: 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, set: 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, set: 0);
955 intel_de_posting_read(display, DP_TP_CTL(PORT_E));
956
957 intel_wait_ddi_buf_idle(display, port: 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
974void 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, set: 0);
985 intel_de_rmw(display, DDI_BUF_CTL(PORT_E), DDI_BUF_CTL_ENABLE, set: 0);
986 intel_wait_ddi_buf_idle(display, port: 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, set: 0);
992 intel_de_rmw(display, FDI_RX_CTL(PIPE_A), FDI_RX_PLL_ENABLE, set: 0);
993}
994
995void 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, val: temp | FDI_RX_PLL_ENABLE);
1010
1011 intel_de_posting_read(display, reg);
1012 udelay(usec: 200);
1013
1014 /* Switch from Rawclk to PCDclk */
1015 intel_de_rmw(display, reg, clear: 0, FDI_PCDCLK);
1016 intel_de_posting_read(display, reg);
1017 udelay(usec: 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, val: temp | FDI_TX_PLL_ENABLE);
1024
1025 intel_de_posting_read(display, reg);
1026 udelay(usec: 100);
1027 }
1028}
1029
1030void 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, set: 0);
1037
1038 /* Disable CPU FDI TX PLL */
1039 intel_de_rmw(display, FDI_TX_CTL(pipe), FDI_TX_PLL_ENABLE, set: 0);
1040 intel_de_posting_read(display, FDI_TX_CTL(pipe));
1041 udelay(usec: 100);
1042
1043 /* Wait for the clocks to turn off. */
1044 intel_de_rmw(display, FDI_RX_CTL(pipe), FDI_RX_PLL_ENABLE, set: 0);
1045 intel_de_posting_read(display, FDI_RX_CTL(pipe));
1046 udelay(usec: 100);
1047}
1048
1049void 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, set: 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, val: temp & ~FDI_RX_ENABLE);
1065
1066 intel_de_posting_read(display, reg);
1067 udelay(usec: 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, val: temp);
1091
1092 intel_de_posting_read(display, reg);
1093 udelay(usec: 100);
1094}
1095
1096static const struct intel_fdi_funcs ilk_funcs = {
1097 .fdi_link_train = ilk_fdi_link_train,
1098};
1099
1100static const struct intel_fdi_funcs gen6_funcs = {
1101 .fdi_link_train = gen6_fdi_link_train,
1102};
1103
1104static const struct intel_fdi_funcs ivb_funcs = {
1105 .fdi_link_train = ivb_manual_fdi_link_train,
1106};
1107
1108void
1109intel_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