blob: 9ffad274e0f1caa6c03835ee88de75ee3a134740 [file] [log] [blame]
Jitao Shi56126602021-05-29 16:26:00 +08001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <console/console.h>
4#include <device/mmio.h>
5#include <delay.h>
6#include <edid.h>
7#include <soc/addressmap.h>
8#include <soc/dptx.h>
9#include <soc/dptx_hal.h>
10#include <soc/dptx_reg.h>
11#include <soc/dp_intf.h>
12#include <string.h>
13#include <timer.h>
14
15#define ONE_BLOCK_SIZE 128
16
17#define DP_LINK_CONSTANT_N_VALUE 0x8000
18#define DP_LINK_STATUS_SIZE 6
19
20#define DP_LANE0_1_STATUS 0x202
21#define DP_LANE2_3_STATUS 0x203
22#define DP_LANE_CR_DONE (1 << 0)
23#define DP_LANE_CHANNEL_EQ_DONE (1 << 1)
24#define DP_LANE_SYMBOL_LOCKED (1 << 2)
25
26#define DP_BRANCH_OUI_HEADER_SIZE 0xc
27#define DP_RECEIVER_CAP_SIZE 0xf
28#define DP_DSC_RECEIVER_CAP_SIZE 0xf
29#define EDP_PSR_RECEIVER_CAP_SIZE 2
30#define EDP_DISPLAY_CTL_CAP_SIZE 3
31#define DP_LTTPR_COMMON_CAP_SIZE 8
32#define DP_LTTPR_PHY_CAP_SIZE 3
33
34#define DP_TRAINING_AUX_RD_INTERVAL 0x00e
35#define DP_TRAINING_AUX_RD_MASK 0x7f
36#define DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT (1 << 7)
37
38#define DP_EDP_DPCD_REV 0x700
39#define DP_EDP_11 0x00
40#define DP_EDP_12 0x01
41#define DP_EDP_13 0x02
42#define DP_EDP_14 0x03
43#define DP_EDP_14a 0x04
44#define DP_EDP_14b 0x05
45
46/* Receiver Capability */
47#define DP_DPCD_REV 0x000
48#define DP_DPCD_REV_10 0x10
49#define DP_DPCD_REV_11 0x11
50#define DP_DPCD_REV_12 0x12
51#define DP_DPCD_REV_13 0x13
52#define DP_DPCD_REV_14 0x14
53
54#define DP_CHANNEL_EQ_BITS (DP_LANE_CR_DONE | \
55 DP_LANE_CHANNEL_EQ_DONE | \
56 DP_LANE_SYMBOL_LOCKED)
57
58#define DP_LANE_ALIGN_STATUS_UPDATED 0x204
59#define DP_INTERLANE_ALIGN_DONE (1 << 0)
60#define DP_DOWNSTREAM_PORT_STATUS_CHANGED (1 << 6)
61#define DP_LINK_STATUS_UPDATED (1 << 7)
62
63#define DP_SINK_STATUS 0x205
64#define DP_RECEIVE_PORT_0_STATUS (1 << 0)
65#define DP_RECEIVE_PORT_1_STATUS (1 << 1)
66#define DP_STREAM_REGENERATION_STATUS (1 << 2)
67
68#define DP_AUX_MAX_PAYLOAD_BYTES 16
69
70#define MAX_LANECOUNT 4
71
72enum {
73 DP_LANECOUNT_1 = 0x1,
74 DP_LANECOUNT_2 = 0x2,
75 DP_LANECOUNT_4 = 0x4,
76};
77
78enum {
79 DP_VERSION_11 = 0x11,
80 DP_VERSION_12 = 0x12,
81 DP_VERSION_14 = 0x14,
82 DP_VERSION_12_14 = 0x16,
83 DP_VERSION_14_14 = 0x17,
84 DP_VERSION_MAX,
85};
86
87enum {
88 DPTX_SWING0 = 0x00,
89 DPTX_SWING1 = 0x01,
90 DPTX_SWING2 = 0x02,
91 DPTX_SWING3 = 0x03,
92};
93
94enum {
95 DPTX_PREEMPHASIS0 = 0x00,
96 DPTX_PREEMPHASIS1 = 0x01,
97 DPTX_PREEMPHASIS2 = 0x02,
98 DPTX_PREEMPHASIS3 = 0x03,
99};
100
101enum {
102 DPTX_PASS = 0,
103 DPTX_PLUG_OUT = 1,
104 DPTX_TIMEOUT = 2,
105 DPTX_AUTH_FAIL = 3,
106 DPTX_EDID_FAIL = 4,
107 DPTX_TRANING_FAIL = 5,
108 DPTX_TRANING_STATE_CHANGE = 6,
109};
110
111enum {
112 FEC_ERROR_COUNT_DISABLE = 0x0,
113 FEC_UNCORRECTED_BLOCK_ERROR_COUNT = 0x1,
114 FEC_CORRECTED_BLOCK_ERROR_COUNT = 0x2,
115 FEC_BIT_ERROR_COUNT = 0x3,
116 FEC_PARITY_BLOCK_ERROR_COUNT = 0x4,
117 FEC_PARITY_BIT_ERROR_COUNT = 0x5,
118};
119
120enum {
121 DPTX_NTSTATE_STARTUP = 0x0,
122 DPTX_NTSTATE_CHECKCAP = 0x1,
123 DPTX_NTSTATE_CHECKEDID = 0x2,
124 DPTX_NTSTATE_TRAINING_PRE = 0x3,
125 DPTX_NTSTATE_TRAINING = 0x4,
126 DPTX_NTSTATE_CHECKTIMING = 0x5,
127 DPTX_NTSTATE_NORMAL = 0x6,
128 DPTX_NTSTATE_POWERSAVE = 0x7,
129 DPTX_NTSTATE_DPIDLE = 0x8,
130 DPTX_NTSTATE_MAX,
131};
132
133enum {
134 DPTX_DISP_NONE = 0,
135 DPTX_DISP_RESUME = 1,
136 DPTX_DISP_SUSPEND = 2,
137};
138
139enum {
140 TRAIN_STEP_SUCCESS = 0,
141 TRAIN_STEP_FAIL_BREAK = 1,
142 TRAIN_STEP_FAIL_NOT_BREAK = 2,
143};
144
145#define DPTX_TRAIN_RETRY_LIMIT 0x8
146#define DPTX_TRAIN_MAX_ITERATION 0x5
147
148#define HPD_INT_EVNET BIT(3)
149#define HPD_CONNECT BIT(2)
150#define HPD_DISCONNECT BIT(1)
151#define HPD_INITIAL_STATE 0
152
153static bool dptx_auxwrite_bytes(struct mtk_dp *mtk_dp, u8 cmd,
154 u32 dpcd_addr, size_t length, u8 *data)
155{
156 u8 retry = 7;
157
158 do {
159 if (dptx_hal_auxwrite_bytes(mtk_dp, cmd,
160 dpcd_addr, length, data))
161 return true;
162
163 mdelay(1);
164 } while (--retry > 0);
165
166 printk(BIOS_ERR, "aux write fail: cmd = %d, addr = %#x, len = %ld\n",
167 cmd, dpcd_addr, length);
168
169 return false;
170}
171
172static bool dptx_auxwrite_dpcd(struct mtk_dp *mtk_dp, u8 cmd,
173 u32 dpcd_addr, size_t length, u8 *data)
174{
175 bool ret = true;
176 size_t offset = 0;
177 size_t len;
178
179 while (offset < length) {
180 len = MIN(length - offset, DP_AUX_MAX_PAYLOAD_BYTES);
181 ret &= dptx_auxwrite_bytes(mtk_dp, cmd, dpcd_addr + offset,
182 len, data + offset);
183 offset += len;
184 }
185 return ret;
186}
187
188static bool dptx_auxread_bytes(struct mtk_dp *mtk_dp, u8 cmd,
189 u32 dpcd_addr, size_t length, u8 *data)
190{
191 u8 retry = 7;
192
193 do {
194 if (dptx_hal_auxread_bytes(mtk_dp, cmd,
195 dpcd_addr, length, data))
196 return true;
197
198 mdelay(1);
199 } while (--retry > 0);
200
201 printk(BIOS_ERR, "aux read fail: cmd = %d, addr = %#x, len = %ld\n",
202 cmd, dpcd_addr, length);
203
204 return false;
205}
206
207static bool dptx_auxread_dpcd(struct mtk_dp *mtk_dp, u8 cmd,
208 u32 dpcd_addr, size_t length, u8 *rxbuf)
209{
210 bool ret = true;
211 size_t offset = 0;
212 size_t len;
213
214 while (offset < length) {
215 len = MIN(length - offset, DP_AUX_MAX_PAYLOAD_BYTES);
216 ret &= dptx_auxread_bytes(mtk_dp, cmd, dpcd_addr + offset,
217 len, rxbuf + offset);
218 offset += len;
219 }
220 return ret;
221}
222
223static int dptx_get_edid(struct mtk_dp *mtk_dp, struct edid *out)
224{
225 int ret;
226 u8 edid[ONE_BLOCK_SIZE];
227 u8 tmp = 0;
228
229 dptx_auxwrite_dpcd(mtk_dp, DP_AUX_I2C_WRITE, 0x50, 0x1, &tmp);
230
231 for (tmp = 0; tmp < ONE_BLOCK_SIZE / DP_AUX_MAX_PAYLOAD_BYTES; tmp++)
232 dptx_auxread_dpcd(mtk_dp, DP_AUX_I2C_READ,
233 0x50, DP_AUX_MAX_PAYLOAD_BYTES,
234 edid + tmp * 16);
235
236 ret = decode_edid(edid, ONE_BLOCK_SIZE, out);
237 if (ret != EDID_CONFORMANT) {
238 printk(BIOS_ERR, "failed to decode edid(%d).\n", ret);
239 return -1;
240 }
241
242 mtk_dp->edid = out;
243 return 0;
244}
245
246static u8 dptx_link_status(const u8 link_status[DP_LINK_STATUS_SIZE], int r)
247{
248 return link_status[r - DP_LANE0_1_STATUS];
249}
250
251static u8 dptx_get_lane_status(const u8 link_status[DP_LINK_STATUS_SIZE],
252 int lane)
253{
254 int i = DP_LANE0_1_STATUS + (lane >> 1);
255 int s = (lane & 1) * 4;
256 u8 l = dptx_link_status(link_status, i);
257
258 return (l >> s) & 0xf;
259}
260
261static bool dptx_clock_recovery_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
262 int lane_count)
263{
264 int lane;
265 u8 lane_status;
266
267 for (lane = 0; lane < lane_count; lane++) {
268 lane_status = dptx_get_lane_status(link_status, lane);
269 if ((lane_status & DP_LANE_CR_DONE) == 0)
270 return false;
271 }
272 return true;
273}
274
275static void dptx_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
276{
277 u32 rd_interval = dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
278 DP_TRAINING_AUX_RD_MASK;
279
280 if (rd_interval > 4)
281 printk(BIOS_ERR, "aux interval %d, out of range (max 4)\n",
282 rd_interval);
283
284 if (rd_interval == 0 || dpcd[DP_DPCD_REV] >= DP_DPCD_REV_14)
285 rd_interval = 1;
286 else
287 rd_interval *= 4;
288
289 mdelay(rd_interval);
290}
291
292static void dptx_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
293{
294 u32 rd_interval = dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
295 DP_TRAINING_AUX_RD_MASK;
296
297 if (rd_interval > 4)
298 printk(BIOS_ERR, "aux interval %d, out of range (max 4)\n",
299 rd_interval);
300
301 if (rd_interval == 0)
302 rd_interval = 1;
303 else
304 rd_interval *= 4;
305
306 mdelay(rd_interval);
307}
308
309static bool dptx_channel_eq_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
310 int lane_count)
311{
312 u8 lane_align;
313 u8 lane_status;
314 int lane;
315
316 lane_align = dptx_link_status(link_status,
317 DP_LANE_ALIGN_STATUS_UPDATED);
318
319 if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
320 return false;
321
322 for (lane = 0; lane < lane_count; lane++) {
323 lane_status = dptx_get_lane_status(link_status, lane);
324 if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS)
325 return false;
326 }
327 return true;
328}
329
330static void dptx_videomute(struct mtk_dp *mtk_dp, bool enable)
331{
332 dptx_hal_videomute(mtk_dp, enable);
333}
334
335static void dptx_fec_ready(struct mtk_dp *mtk_dp, u8 err_cnt_sel)
336{
337 u8 i, data[3];
338
339 dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ, 0x90, 0x1, data);
340 printk(BIOS_DEBUG, "FEC Capable[0], [0:3] should be 1: %#x\n",
341 data[0]);
342
343 /*
344 * FEC error count select 120[3:1]:
345 * 000b: FEC_ERROR_COUNT_DIS
346 * 001b: UNCORRECTED_BLOCK_ERROR_COUNT
347 * 010b: CORRECTED_BLOCK_ERROR_COUNT
348 * 011b: BIT_ERROR_COUNT
349 * 100b: PARITY_BLOCK_ERROR_COUNT
350 * 101b: PARITY_BIT_ERROR_COUNT
351 */
352 if (data[0] & BIT(0)) {
353 mtk_dp->has_fec = true;
354 data[0] = (err_cnt_sel << 1) | 0x1;
355
356 dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE,
357 0x120, 0x1, data);
358 dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ,
359 0x280, 0x3, data);
360
361 for (i = 0; i < 3; i++)
362 printk(BIOS_DEBUG, "FEC status & error Count: %#x\n",
363 data[i]);
364 }
365}
366
367static void dptx_init_variable(struct mtk_dp *mtk_dp)
368{
369 mtk_dp->regs = (void *)EDP_BASE;
370 mtk_dp->train_info.sys_max_linkrate = DP_LINKRATE_HBR3;
371 mtk_dp->train_info.linkrate = DP_LINKRATE_HBR2;
372 mtk_dp->train_info.linklane_count = DP_LANECOUNT_4;
373 mtk_dp->train_info.sink_extcap_en = false;
374 mtk_dp->train_info.sink_ssc_en = false;
375 mtk_dp->train_info.tps3 = true;
376 mtk_dp->train_info.tps4 = true;
377 mtk_dp->training_state = DPTX_NTSTATE_STARTUP;
378 mtk_dp->info.format = DP_COLOR_FORMAT_RGB_444;
379 mtk_dp->info.depth = DP_COLOR_DEPTH_8BIT;
380 mtk_dp->power_on = false;
381 mtk_dp->video_enable = false;
382 mtk_dp->dp_ready = false;
383 mtk_dp->has_dsc = false;
384 mtk_dp->has_fec = false;
385 mtk_dp->dsc_enable = false;
386}
387
388static inline bool dptx_check_res_sample_rate(const struct edid *edid)
389{
390 return edid->mode.va + edid->mode.vbl <= 525;
391}
392
393static void dptx_setsdp_downcnt_init(struct mtk_dp *mtk_dp, u16 sram_read_start)
394{
395 u32 count = 0; /* count: sdp_down_cnt_init */
396 u8 offset;
397
398 if (mtk_dp->edid->mode.pixel_clock > 0)
399 count = (sram_read_start * 2700 * 8 *
400 mtk_dp->train_info.linkrate) /
401 (mtk_dp->edid->mode.pixel_clock * 4);
402
403 switch (mtk_dp->train_info.linklane_count) {
404 case DP_LANECOUNT_1:
405 count = (count > 0x1a) ? count : 0x1a;
406 break;
407 case DP_LANECOUNT_2:
408 /* Case for LowResolution and High Audio Sample Rate. */
409 offset = dptx_check_res_sample_rate(mtk_dp->edid) ?
410 0x04 : 0x00;
411 count = (count > 0x10) ? count : 0x10 + offset;
412 break;
413 case DP_LANECOUNT_4:
414 default:
415 count = (count > 0x06) ? count : 0x06;
416 break;
417 }
418
419 printk(BIOS_DEBUG, "pixel rate(khz) = %d, sdp_dc_init = %#x\n",
420 mtk_dp->edid->mode.pixel_clock, count);
421
422 dptx_hal_setsdp_downcnt_init(mtk_dp, count);
423}
424
425static void dptx_setsdp_downcnt_init_inhblanking(struct mtk_dp *mtk_dp)
426{
427 int pixclk_mhz = mtk_dp->edid->mode.pixel_clock / 1000;
428 u8 offset;
429 u16 count = 0; /* count: sdp_down_cnt_init*/
430
431 switch (mtk_dp->train_info.linklane_count) {
432 case DP_LANECOUNT_1:
433 count = 0x20;
434 break;
435 case DP_LANECOUNT_2:
436 offset = dptx_check_res_sample_rate(mtk_dp->edid) ?
437 0x14 : 0x00;
438 count = 0x0018 + offset;
439 break;
440 case DP_LANECOUNT_4:
441 default:
442 offset = dptx_check_res_sample_rate(mtk_dp->edid) ?
443 0x08 : 0x00;
444 if (pixclk_mhz > mtk_dp->train_info.linkrate * 27) {
445 count = 0x8;
446 printk(BIOS_ERR, "ERROR: Pixclk > LinkRateChange\n");
447 } else {
448 count = 0x10 + offset;
449 }
450 break;
451 }
452
453 dptx_hal_setsdp_downcnt_init_inhblanking(mtk_dp, count);
454}
455
456static void dptx_set_tu(struct mtk_dp *mtk_dp)
457{
458 u8 bpp;
459 u16 sram_read_start = DPTX_TBC_BUF_READSTARTADRTHRD;
460 int tu_size, n_value, f_value, pixclk_mhz;
461
462 bpp = dptx_hal_get_colorbpp(mtk_dp);
463 pixclk_mhz = mtk_dp->edid->mode.pixel_clock / 1000;
464 tu_size = (640 * pixclk_mhz * bpp) /
465 (mtk_dp->train_info.linkrate * 27 *
466 mtk_dp->train_info.linklane_count * 8);
467
468 n_value = tu_size / 10;
469 f_value = tu_size % 10;
470 printk(BIOS_DEBUG, "TU_size %d, FValue %d\n", tu_size, f_value);
471
472 if (mtk_dp->train_info.linklane_count > 0) {
473 sram_read_start = mtk_dp->edid->mode.ha /
474 (mtk_dp->train_info.linklane_count *
475 4 * 2 * 2);
476 sram_read_start = MIN(sram_read_start,
477 DPTX_TBC_BUF_READSTARTADRTHRD);
478 dptx_hal_settu_sramrd_start(mtk_dp, sram_read_start);
479 }
480
481 dptx_hal_settu_setencoder(mtk_dp);
482 dptx_setsdp_downcnt_init_inhblanking(mtk_dp);
483 dptx_setsdp_downcnt_init(mtk_dp, sram_read_start);
484}
485
486static void dptx_set_misc(struct mtk_dp *mtk_dp)
487{
488 u8 format, depth;
489 union misc_t dptx_misc;
490
491 format = mtk_dp->info.format;
492 depth = mtk_dp->info.depth;
493
494 /*
495 * MISC 0/1 reference to spec 1.4a p143 Table 2-96.
496 * MISC0[7:5] color depth.
497 */
498 dptx_misc.dp_misc.color_depth = depth;
499
500 /*
501 * MISC0[3]: 0->RGB, 1->YUV
502 * MISC0[2:1]: 01b->4:2:2, 10b->4:4:4
503 */
504 switch (format) {
505 case DP_COLOR_FORMAT_YUV_444:
506 dptx_misc.dp_misc.color_format = 0x1;
507 break;
508 case DP_COLOR_FORMAT_YUV_422:
509 dptx_misc.dp_misc.color_format = 0x2;
510 break;
511 case DP_COLOR_FORMAT_RAW:
512 dptx_misc.dp_misc.color_format = 0x1;
513 dptx_misc.dp_misc.spec_def2 = 0x1;
514 break;
515 case DP_COLOR_FORMAT_YONLY:
516 dptx_misc.dp_misc.color_format = 0x0;
517 dptx_misc.dp_misc.spec_def2 = 0x1;
518 break;
519 case DP_COLOR_FORMAT_YUV_420:
520 case DP_COLOR_FORMAT_RGB_444:
521 default:
522 break;
523 }
524
525 dptx_hal_setmisc(mtk_dp, dptx_misc.cmisc);
526}
527
528static void dptx_set_dptxout(struct mtk_dp *mtk_dp)
529{
530 dptx_hal_bypassmsa_en(mtk_dp, false);
531 dptx_set_tu(mtk_dp);
532}
533
534static bool dptx_training_checkswingpre(struct mtk_dp *mtk_dp,
535 u8 target_lane_count,
536 const u8 *dpcp202_x, u8 *dpcp_buf)
537{
538 bool ret = true;
539 u8 swing_value, preemphasis;
540
541 /* Lane 0 */
542 if (target_lane_count >= 0x1) {
543 swing_value = (dpcp202_x[4] & 0x3);
544 preemphasis = (dpcp202_x[4] & 0xc) >> 2;
545
546 /* Adjust the swing and pre-emphasis */
547 ret &= dptx_hal_setswing_preemphasis(mtk_dp, DPTX_LANE0,
548 swing_value, preemphasis);
549
550 /*
551 * Adjust the swing and pre-emphasis done,
552 * and notify sink side.
553 */
554 dpcp_buf[0] = swing_value | (preemphasis << 3);
555
556 /* Max swing reached. */
557 if (swing_value == DPTX_SWING3)
558 dpcp_buf[0] |= BIT(2);
559
560 /* Max pre-emphasis reached. */
561 if (preemphasis == DPTX_PREEMPHASIS3)
562 dpcp_buf[0] |= BIT(5);
563 }
564
565 /* Lane 1 */
566 if (target_lane_count >= 0x2) {
567 swing_value = (dpcp202_x[4] & 0x30) >> 4;
568 preemphasis = (dpcp202_x[4] & 0xc0) >> 6;
569
570 /* Adjust the swing and pre-emphasis */
571 ret &= dptx_hal_setswing_preemphasis(mtk_dp, DPTX_LANE1,
572 swing_value, preemphasis);
573
574 /*
575 * Adjust the swing and pre-emphasis done,
576 * and notify sink side.
577 */
578 dpcp_buf[1] = swing_value | (preemphasis << 3);
579
580 /* Max swing reached. */
581 if (swing_value == DPTX_SWING3)
582 dpcp_buf[1] |= BIT(2);
583
584 /* Max pre-emphasis reached. */
585 if (preemphasis == DPTX_PREEMPHASIS3)
586 dpcp_buf[1] |= BIT(5);
587 }
588
589 /* Lane 2 and Lane 3 */
590 if (target_lane_count == 0x4) {
591 /* Lane 2 */
592 swing_value = (dpcp202_x[5] & 0x3);
593 preemphasis = (dpcp202_x[5] & 0x0c) >> 2;
594
595 /* Adjust the swing and pre-emphasis */
596 ret &= dptx_hal_setswing_preemphasis(mtk_dp, DPTX_LANE2,
597 swing_value, preemphasis);
598
599 /*
600 * Adjust the swing and pre-emphasis done,
601 * and notify sink side.
602 */
603 dpcp_buf[2] = swing_value | (preemphasis << 3);
604
605 /* Max swing reached. */
606 if (swing_value == DPTX_SWING3)
607 dpcp_buf[2] |= BIT(2);
608
609 /* Max pre-emphasis reached. */
610 if (preemphasis == DPTX_PREEMPHASIS3)
611 dpcp_buf[2] |= BIT(5);
612
613 /* Lane 3 */
614 swing_value = (dpcp202_x[5] & 0x30) >> 4;
615 preemphasis = (dpcp202_x[5] & 0xc0) >> 6;
616
617 /* Adjust the swing and pre-emphasis */
618 ret &= dptx_hal_setswing_preemphasis(mtk_dp, DPTX_LANE3,
619 swing_value, preemphasis);
620
621 /*
622 * Adjust the swing and pre-emphasis done,
623 * and notify sink side.
624 */
625 dpcp_buf[0x3] = swing_value | (preemphasis << 3);
626
627 /* Max swing reached. */
628 if (swing_value == DPTX_SWING3)
629 dpcp_buf[3] |= BIT(2);
630
631 /* Max pre-emphasis reached. */
632 if (preemphasis == DPTX_PREEMPHASIS3)
633 dpcp_buf[3] |= BIT(5);
634 }
635
636 /* Wait signal stable enough */
637 mdelay(2);
638
639 return ret;
640}
641
642static int dptx_train_tps1(struct mtk_dp *mtk_dp, u8 target_lanecount,
643 int *status_ctrl, int *iteration, u8 *dpcp_buffer,
644 u8 *dpcd206)
645{
646 u8 tmp_val[6];
647 u8 dpcd200c[3];
648
649 printk(BIOS_INFO, "CR Training START\n");
650 dptx_hal_setscramble(mtk_dp, false);
651
652 if (*status_ctrl == 0x0) {
653 dptx_hal_set_txtrainingpattern(mtk_dp, BIT(4));
654 *status_ctrl = 0x1;
655 tmp_val[0] = 0x21;
656 dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE,
657 DPCD_00102, 0x1, tmp_val);
658 dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ,
659 DPCD_00206, 0x2, tmp_val + 4);
660 *iteration = *iteration + 1;
661
662 dptx_training_checkswingpre(mtk_dp, target_lanecount,
663 tmp_val, dpcp_buffer);
664 }
665
666 dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE,
667 DPCD_00103, target_lanecount, dpcp_buffer);
668
669 dptx_link_train_clock_recovery_delay(mtk_dp->rx_cap);
670
671 dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ,
672 DPCD_00202, 0x6, tmp_val);
673
674 if (mtk_dp->train_info.sink_extcap_en) {
675 dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ,
676 DPCD_0200C, 0x3, dpcd200c);
677 tmp_val[0] = dpcd200c[0];
678 tmp_val[1] = dpcd200c[1];
679 tmp_val[2] = dpcd200c[2];
680 }
681
682 if (dptx_clock_recovery_ok(tmp_val, target_lanecount)) {
683 printk(BIOS_INFO, "CR Training Success\n");
684
685 mtk_dp->train_info.cr_done = true;
686 *iteration = 0x1;
687
688 return TRAIN_STEP_SUCCESS;
689 }
690
691 printk(BIOS_INFO, "CR Training Fail\n");
692
693 /* Requested swing and emp is the same with last time. */
694 if (*dpcd206 == tmp_val[4]) {
695 *iteration = *iteration + 1;
696 if (*dpcd206 & 0x3)
697 return TRAIN_STEP_FAIL_BREAK;
698 } else {
699 *dpcd206 = tmp_val[4];
700 }
701
702 return TRAIN_STEP_FAIL_NOT_BREAK;
703}
704
705static int dptx_train_tps2_3(struct mtk_dp *mtk_dp, u8 target_lanecount,
706 int *status_ctrl, int *iteration, u8 *dpcp_buffer,
707 u8 *dpcd206)
708{
709 u8 tmp_val[6];
710 u8 dpcd200c[3];
711
712 printk(BIOS_INFO, "EQ Training START\n");
713
714 if (*status_ctrl == 0x1) {
715 if (mtk_dp->train_info.tps4)
716 dptx_hal_set_txtrainingpattern(mtk_dp, BIT(7));
717 else if (mtk_dp->train_info.tps3)
718 dptx_hal_set_txtrainingpattern(mtk_dp, BIT(6));
719 else
720 dptx_hal_set_txtrainingpattern(mtk_dp, BIT(5));
721
722 if (mtk_dp->train_info.tps4) {
723 tmp_val[0] = 0x07;
724 dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE,
725 DPCD_00102, 0x1, tmp_val);
726 } else if (mtk_dp->train_info.tps3) {
727 tmp_val[0] = 0x23;
728 dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE,
729 DPCD_00102, 0x1, tmp_val);
730 } else {
731 tmp_val[0] = 0x22;
732 dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE,
733 DPCD_00102, 0x1, tmp_val);
734 }
735
736 *status_ctrl = 0x2;
737 dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ,
738 DPCD_00206, 0x2, tmp_val + 4);
739
740 *iteration = *iteration + 1;
741 dptx_training_checkswingpre(mtk_dp, target_lanecount,
742 tmp_val, dpcp_buffer);
743 }
744
745 dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE, DPCD_00103,
746 target_lanecount, dpcp_buffer);
747 dptx_link_train_channel_eq_delay(mtk_dp->rx_cap);
748
749 dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ,
750 DPCD_00202, 0x6, tmp_val);
751
752 if (mtk_dp->train_info.sink_extcap_en) {
753 dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ,
754 DPCD_0200C, 0x3, dpcd200c);
755 tmp_val[0] |= dpcd200c[0];
756 tmp_val[1] |= dpcd200c[1];
757 tmp_val[2] |= dpcd200c[2];
758 }
759
760 if (!dptx_clock_recovery_ok(tmp_val, target_lanecount)) {
761 printk(BIOS_INFO, "EQ Training Fail\n");
762 mtk_dp->train_info.cr_done = false;
763 mtk_dp->train_info.eq_done = false;
764 return TRAIN_STEP_FAIL_BREAK;
765 }
766
767 if (dptx_channel_eq_ok(tmp_val, target_lanecount)) {
768 printk(BIOS_INFO, "EQ Training Success\n");
769 mtk_dp->train_info.eq_done = true;
770 return TRAIN_STEP_SUCCESS;
771 }
772 printk(BIOS_INFO, "EQ Training Fail\n");
773
774 if (*dpcd206 == tmp_val[4])
775 *iteration = *iteration + 1;
776 else
777 *dpcd206 = tmp_val[4];
778
779 return TRAIN_STEP_FAIL_NOT_BREAK;
780}
781
782static int dptx_trainingflow(struct mtk_dp *mtk_dp,
783 u8 lanerate, u8 lanecount)
784{
785 u8 tmp_val[6];
786 u8 target_linkrate = lanerate;
787 u8 target_lanecount = lanecount;
788 u8 dpcp_buffer[4];
789 u8 dpcd206;
790 bool pass_tps1 = false;
791 bool pass_tps2_3 = false;
792 int train_retry, status_ctrl, iteration;
793
794 memset(tmp_val, 0, sizeof(tmp_val));
795 memset(dpcp_buffer, 0, sizeof(dpcp_buffer));
796
797 dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ,
798 DPCD_00600, 0x1, tmp_val);
799 if (tmp_val[0] != 0x1) {
800 tmp_val[0] = 0x1;
801 dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE,
802 DPCD_00600, 0x1, tmp_val);
803 mdelay(1);
804 }
805
806 tmp_val[0] = target_linkrate;
807 tmp_val[1] = target_lanecount | DPTX_AUX_SET_ENAHNCED_FRAME;
808 dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE,
809 DPCD_00100, 0x2, tmp_val);
810
811 if (mtk_dp->train_info.sink_ssc_en) {
812 tmp_val[0x0] = 0x10;
813 dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE,
814 DPCD_00107, 0x1, tmp_val);
815 }
816
817 train_retry = 0x0;
818 status_ctrl = 0x0;
819 iteration = 0x1;
820 dpcd206 = 0xff;
821
822 dptx_hal_set_txlane(mtk_dp, target_lanecount / 2);
823 dptx_hal_set_txrate(mtk_dp, target_linkrate);
824
825 do {
826 train_retry++;
827 if (!pass_tps1) {
828 int ret = dptx_train_tps1(mtk_dp, target_lanecount,
829 &status_ctrl, &iteration,
830 dpcp_buffer, &dpcd206);
831 if (ret == TRAIN_STEP_FAIL_BREAK)
832 break;
833 if (ret == TRAIN_STEP_SUCCESS) {
834 pass_tps1 = true;
835 train_retry = 0;
836 }
837 } else {
838 int ret = dptx_train_tps2_3(mtk_dp, target_lanecount,
839 &status_ctrl, &iteration,
840 dpcp_buffer, &dpcd206);
841 if (ret == TRAIN_STEP_FAIL_BREAK)
842 break;
843 if (ret == TRAIN_STEP_SUCCESS) {
844 pass_tps2_3 = true;
845 break;
846 }
847 }
848
849 dptx_training_checkswingpre(mtk_dp, target_lanecount,
850 tmp_val, dpcp_buffer);
851
852 } while (train_retry < DPTX_TRAIN_RETRY_LIMIT &&
853 iteration < DPTX_TRAIN_MAX_ITERATION);
854
855 tmp_val[0] = 0x0;
856 dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE,
857 DPCD_00102, 0x1, tmp_val);
858 dptx_hal_set_txtrainingpattern(mtk_dp, 0);
859
860 if (!pass_tps2_3) {
861 printk(BIOS_ERR, "Link Training Fail\n");
862 return DPTX_TRANING_FAIL;
863 }
864
865 mtk_dp->train_info.linkrate = target_linkrate;
866 mtk_dp->train_info.linklane_count = target_lanecount;
867
868 dptx_hal_setscramble(mtk_dp, true);
869
870 tmp_val[0] = target_lanecount | DPTX_AUX_SET_ENAHNCED_FRAME;
871
872 dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE,
873 DPCD_00101, 0x1, tmp_val);
874 dptx_hal_set_ef_mode(mtk_dp, ENABLE_DPTX_EF_MODE);
875
876 printk(BIOS_INFO, "Link Training Success\n");
877 return DPTX_PASS;
878}
879
880static void dptx_check_sinkcap(struct mtk_dp *mtk_dp)
881{
882 u8 buffer[16];
883
884 memset(buffer, 0x0, sizeof(buffer));
885
886 buffer[0] = 0x1;
887 dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE,
888 DPCD_00600, 0x1, buffer);
889
890 mdelay(2);
891
892 dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ,
893 DPCD_00000, 0x10, buffer);
894
895 mtk_dp->train_info.sink_extcap_en = false;
896 mtk_dp->train_info.dpcd_rev = buffer[0];
897
898 printk(BIOS_INFO, "SINK DPCD version: %#x\n",
899 mtk_dp->train_info.dpcd_rev);
900
901 memcpy(mtk_dp->rx_cap, buffer, sizeof(mtk_dp->rx_cap));
902
903 mtk_dp->rx_cap[14] &= 0x7f;
904
905 if (mtk_dp->train_info.dpcd_rev >= 0x14)
906 dptx_fec_ready(mtk_dp, FEC_BIT_ERROR_COUNT);
907
908 mtk_dp->train_info.linkrate = MIN(buffer[0x1],
909 mtk_dp->train_info.sys_max_linkrate);
910 mtk_dp->train_info.linklane_count = MIN(buffer[2] & 0x1F,
911 MAX_LANECOUNT);
912
913 mtk_dp->train_info.tps3 = (buffer[2] & BIT(6)) >> 0x6;
914 mtk_dp->train_info.tps4 = (buffer[3] & BIT(7)) >> 0x7;
915
916 mtk_dp->train_info.down_stream_port_present = (buffer[5] & BIT(0));
917
918 if ((buffer[3] & BIT(0)) == 0x1) {
919 printk(BIOS_INFO, "SINK SUPPORT SSC!\n");
920 mtk_dp->train_info.sink_ssc_en = true;
921 } else {
922 printk(BIOS_INFO, "SINK NOT SUPPORT SSC!\n");
923 mtk_dp->train_info.sink_ssc_en = false;
924 }
925
926 dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ,
927 DPCD_00021, 0x1, buffer);
928 mtk_dp->train_info.dp_mstcap = (buffer[0] & BIT(0));
929 mtk_dp->train_info.dp_mstbranch = false;
930
931 if (mtk_dp->train_info.dp_mstcap == BIT(0)) {
932 if (mtk_dp->train_info.down_stream_port_present == 0x1)
933 mtk_dp->train_info.dp_mstbranch = true;
934
935 dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ,
936 DPCD_02003, 0x1, buffer);
937 if (buffer[0] != 0x0)
938 dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE,
939 DPCD_02003, 0x1, buffer);
940 }
941
942 dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ,
943 DPCD_00600, 0x1, buffer);
944 if (buffer[0] != 0x1) {
945 buffer[0] = 0x1;
946 dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE,
947 DPCD_00600, 0x1, buffer);
948 }
949
950 dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ,
951 DPCD_00200, 0x2, buffer);
952}
953
954static void dptx_training_changemode(struct mtk_dp *mtk_dp)
955{
956 dptx_hal_phyd_reset(mtk_dp);
957 dptx_hal_reset_swing_preemphasis(mtk_dp);
958 dptx_hal_ssc_en(mtk_dp, mtk_dp->train_info.sink_ssc_en);
959
960 mdelay(2);
961}
962
963static int dptx_set_trainingstart(struct mtk_dp *mtk_dp)
964{
965 int ret = DPTX_PASS;
966 u8 lanecount;
967 u8 linkrate;
968 u8 buffer;
969 u8 limit;
970 u8 max_linkrate;
971
972 buffer = 0x1;
973 dptx_auxwrite_dpcd(mtk_dp, DP_AUX_NATIVE_WRITE,
974 DPCD_00600, 0x1, &buffer);
975
976 linkrate = mtk_dp->rx_cap[1];
977 lanecount = mtk_dp->rx_cap[2] & 0x1f;
978
979 printk(BIOS_INFO, "RX support linkrate = %#x, lanecount = %#x\n",
980 linkrate, lanecount);
981
982 mtk_dp->train_info.linkrate =
983 (linkrate >= mtk_dp->train_info.sys_max_linkrate) ?
984 mtk_dp->train_info.sys_max_linkrate : linkrate;
985 mtk_dp->train_info.linklane_count = (lanecount >= MAX_LANECOUNT) ?
986 MAX_LANECOUNT : lanecount;
987
988 if (mtk_dp->train_info.sink_extcap_en)
989 dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ,
990 DPCD_02002, 0x1, &buffer);
991 else
992 dptx_auxread_dpcd(mtk_dp, DP_AUX_NATIVE_READ,
993 DPCD_00200, 0x1, &buffer);
994
995 if ((buffer & 0xbf) != 0)
996 mtk_dp->train_info.sink_count_num = buffer & 0xbf;
997
998 linkrate = mtk_dp->train_info.linkrate;
999 lanecount = mtk_dp->train_info.linklane_count;
1000
1001 switch (linkrate) {
1002 case DP_LINKRATE_RBR:
1003 case DP_LINKRATE_HBR:
1004 case DP_LINKRATE_HBR2:
1005 case DP_LINKRATE_HBR25:
1006 case DP_LINKRATE_HBR3:
1007 break;
1008 default:
1009 mtk_dp->train_info.linkrate = DP_LINKRATE_HBR3;
1010 break;
1011 };
1012
1013 max_linkrate = linkrate;
1014 limit = 0x6;
1015
1016 do {
1017 mtk_dp->train_info.cr_done = false;
1018 mtk_dp->train_info.eq_done = false;
1019
1020 dptx_training_changemode(mtk_dp);
1021 ret = dptx_trainingflow(mtk_dp, linkrate, lanecount);
1022
1023 if (!mtk_dp->train_info.cr_done) {
1024 /* CR fail and reduce link capability. */
1025 switch (linkrate) {
1026 case DP_LINKRATE_RBR:
1027 lanecount = lanecount / 2;
1028 linkrate = max_linkrate;
1029
1030 if (lanecount == 0x0)
1031 return DPTX_TRANING_FAIL;
1032 break;
1033 case DP_LINKRATE_HBR:
1034 linkrate = DP_LINKRATE_RBR;
1035 break;
1036 case DP_LINKRATE_HBR2:
1037 linkrate = DP_LINKRATE_HBR;
1038 break;
1039 case DP_LINKRATE_HBR3:
1040 linkrate = DP_LINKRATE_HBR2;
1041 break;
1042 default:
1043 return DPTX_TRANING_FAIL;
1044 };
1045 } else if (!mtk_dp->train_info.eq_done) {
1046 /* EQ fail and reduce lane counts. */
1047 if (lanecount == DP_LANECOUNT_4)
1048 lanecount = DP_LANECOUNT_2;
1049 else if (lanecount == DP_LANECOUNT_2)
1050 lanecount = DP_LANECOUNT_1;
1051 else
1052 return DPTX_TRANING_FAIL;
1053 } else {
1054 return DPTX_PASS;
1055 }
1056 } while (--limit > 0);
1057
1058 return DPTX_TRANING_FAIL;
1059}
1060
1061static void dptx_init_port(struct mtk_dp *mtk_dp)
1062{
1063 dptx_hal_phy_setidlepattern(mtk_dp, true);
1064 dptx_hal_init_setting(mtk_dp);
1065 dptx_hal_aux_setting(mtk_dp);
1066 dptx_hal_digital_setting(mtk_dp);
1067 dptx_hal_phy_setting(mtk_dp);
1068 dptx_hal_hpd_detect_setting(mtk_dp);
1069
1070 dptx_hal_digital_swreset(mtk_dp);
1071 dptx_hal_analog_power_en(mtk_dp, true);
1072 dptx_hal_hpd_int_en(mtk_dp, true);
1073}
1074
1075static void dptx_video_enable(struct mtk_dp *mtk_dp, bool enable)
1076{
1077 printk(BIOS_INFO, "Output Video %s!\n", enable ?
1078 "enable" : "disable");
1079
1080 if (enable) {
1081 dptx_set_dptxout(mtk_dp);
1082 dptx_videomute(mtk_dp, false);
1083 dptx_hal_verify_clock(mtk_dp);
1084 } else
1085 dptx_videomute(mtk_dp, true);
1086}
1087
1088static void dptx_set_color_format(struct mtk_dp *mtk_dp, u8 color_format)
1089{
1090 dptx_hal_set_color_format(mtk_dp, color_format);
1091}
1092
1093static void dptx_set_color_depth(struct mtk_dp *mtk_dp, u8 color_depth)
1094{
1095 dptx_hal_set_color_depth(mtk_dp, color_depth);
1096}
1097
1098static void dptx_video_config(struct mtk_dp *mtk_dp)
1099{
1100 u32 mvid = 0;
1101 bool overwrite = false;
1102
1103 dptx_hal_overwrite_mn(mtk_dp, overwrite, mvid, 0x8000);
1104
1105 /* Interlace does not support. */
1106 dptx_hal_set_msa(mtk_dp);
1107 dptx_set_misc(mtk_dp);
1108 dptx_set_color_depth(mtk_dp, mtk_dp->info.depth);
1109 dptx_set_color_format(mtk_dp, mtk_dp->info.format);
1110}
1111
1112int mtk_edp_init(struct edid *edid)
1113{
1114 struct mtk_dp mtk_edp;
1115
1116 dptx_init_variable(&mtk_edp);
1117 dptx_init_port(&mtk_edp);
1118
1119 if (!dptx_hal_hpd_high(&mtk_edp)) {
1120 printk(BIOS_ERR, "HPD is low\n");
1121 return -1;
1122 }
1123
1124 dptx_check_sinkcap(&mtk_edp);
1125
1126 dptx_get_edid(&mtk_edp, edid);
1127
1128 dptx_set_trainingstart(&mtk_edp);
1129 dp_intf_config(edid);
1130 dptx_video_config(&mtk_edp);
1131 dptx_video_enable(&mtk_edp, true);
1132
1133 return 0;
1134}