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