1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) ASPEED Technology Inc.
4 */
5
6 #include <common.h>
7 #include <exports.h>
8 #include <clk.h>
9 #include <dm.h>
10 #include <errno.h>
11 #include <reset.h>
12 #include <fdtdec.h>
13 #include <asm/io.h>
14
15 #include "dptest.h"
16
17 /* Version info*/
18 #define MAINVER 0
19 #define SUBVER 3
20 #define TEMPVER 3
21
22 #define YEAR 2023
23 #define MONTH 02
24 #define DAY 17
25
26 /* Compile define */
27 /* #define RE_DRIVER */
28 /* #define INTERNAL */
29
30 /* Debug define */
31 #define DBG_Print
32
33 #define DBG_ERR 0x00000001 /* DBG_ERROR */
34 #define DBG_NOR 0x00000002 /* DBG_NORMAL */
35 #define DBG_A_NOR 0x00000004 /* DBG_AUTO_NORMAL */
36 #define DBG_A_TEST 0x00000008 /* DBG_AUTO_TEST */
37 #define DBG_A_SUB 0x00000010 /* DBG_AUTO_SUBFUNS */
38 #define DBG_A_EDID 0x00000020 /* DBG_AUTO_EDID */
39 #define DBG_INF 0x00000040 /* DBG_INFORMATION */
40 #define DBG_STAGE 0x00000040 /* DBG_STAGE */
41 #define DBG_AUX_R 0x00001000 /* DBG_AUX_R_VALUE */
42 /* #define DBG_AUX_W 0x00002000 *//*DBG_AUX_W_VALUE */
43
44 int DBG_LEVEL = 0x00000040; /* Information and stage */
45 /* int DBG_LEVEL = 0x0000107F; *//*Fully */
46 /* int DBG_LEVEL = 0x00000001; *//*Error */
47
48 #ifdef DBG_Print
49 #define DBG(Level, format, args...) if ((Level) & DBG_LEVEL) printf(format, ##args)
50 #else
51 #define DBG(Level, format, args...)
52 #endif
53
54 int PHY_Cfg_N;
55 int PHY_Cfg;
56 int PHY_Cfg_1;
57 int TX_SSCG_Cfg;
58 int DP_Rate;
59 int Deemphasis_Level;
60 int Deemphasis_Level_1;
61 int Deemphasis_Show;
62 int Deemphasis_RD;
63 int Swing_Level;
64 int SSCG;
65 int SSC_SHIFT;
66 int Current_Item;
67 int GFlag;
68 uchar EDID[256];
69
70 int I2C_PORT;/* I2c port */
71 int I2C_BASE;
72 int I2C_BUFF;
73 uchar RD_VAL;
74
75 /* Record DP Sink status */
76 uchar bEn_Frame;
77 uchar Link_Aux_RD_Val;
78 uchar CR_EQ_Keep;
79 int Deemlevel[3] = {DP_DEEMP_2, DP_DEEMP_0, DP_DEEMP_1};
80 uchar Auto_Link_Rate;
81 uchar Auto_Lane_Count;
82 /* uchar Patch_Normal_Behavior; */
83
84 static int
do_ast_dptest(cmd_tbl_t * cmdtp,int flags,int argc,char * const argv[])85 do_ast_dptest(cmd_tbl_t *cmdtp, int flags, int argc, char *const argv[])
86 {
87 char received = 0;
88 char execute_test = 0;
89 int flag = 0, i;
90 char *Temp = NULL;
91
92 /* Default setting */
93 DP_Rate = DP_RATE_1_62;
94
95 Deemphasis_Show = DP_DEEMP_0;
96 Deemphasis_Level = DP_DEEMP_0;
97 Deemphasis_Level_1 = DP_DEEMP_2;
98 Swing_Level = 2;
99 SSCG = DP_SSCG_OFF;
100 SSC_SHIFT = 1;
101
102 /* Obtain the argc / argv */
103 for (i = 1; i < argc; i++) {
104 if (argv[i][0] == '-') {
105 switch (argv[i][1]) {
106 case 'D':
107 case 'd':
108 Temp = (char *)&argv[i][2];
109 DBG_LEVEL = (int)(strtoul(Temp, NULL, 16));
110 DBG_LEVEL |= DBG_ERR; /* Add must print. */
111 printf("DBG_LEVEL change into 0x%x\n", DBG_LEVEL);
112 break;
113 case 'R':
114 case 'r':
115 Temp = (char *)&argv[i][2];
116 I2C_PORT = (int)(strtoul(Temp, NULL, 16));
117 printf("I2C_PORT change into 0x%x\n", I2C_PORT);
118 break;
119 default:
120 I2C_PORT = 0x0;
121 break;
122 }
123 }
124 }
125
126 printf("ASPEED DP Physical Layer Test Tool V %d.%d.%d\n", MAINVER, SUBVER, TEMPVER);
127 #ifdef INTERNAL
128 printf("Internal Version\n");
129 #endif
130
131 printf("Build Date: %d.%d.%d\n\n", YEAR, MONTH, DAY);
132
133 printf("PLEASE REFER USER MANUAL BEFORE TEST!!\n\n");
134
135 /* DP TX MCU reset */
136 DPTX_MCU_Reset();
137 printf("DP TX MCU Initial Done!\n");
138
139 /* DP phy set */
140 DPPHY_Set();
141 printf("DP Physcial Config Done!\n");
142
143 printf("Commands as below:\n");
144 printf("0: Change SSC on/off\n");
145 printf("1: Set data rate 1.62\n");
146 printf("2: Set data rate 2.7\n");
147 #ifdef INTERNAL
148 printf("3: DE_LVL = 1, DE_LVL_1 = 2\n");
149 printf("4: DE_LVL = 0, DE_LVL_1 = 0\n");
150 printf("5: DE_LVL = 2, DE_LVL_1 = 1\n");
151 #endif
152 printf("6: SSC shift -80ppm\n");
153 printf("7: SSC shift -120ppm\n");
154 printf("!: Show configs\n\n");
155
156 printf("TestItems as below:\n");
157 printf("x: auto test\n");
158 printf("a: PRBS7\n");
159 printf("g: D10.2\n");
160 printf("Press ESC key to leave test ...\n\n");
161
162 // While for auto testing
163 while (1) {
164 if (tstc()) {
165 received = getc();
166
167 /* printf("Press %d\n",received); */
168
169 /* Set parameters path */
170 if (received >= '1' && received <= '9') {
171 switch (received) {
172 /* Press "1" : Set DP_Rate as 1.62 */
173 case '1':
174 DP_Rate = DP_RATE_1_62;
175 PRINT_RATE_1_62;
176 break;
177 /* Press "2" : Set DP_Rate as 2.701 */
178 case '2':
179 DP_Rate = DP_RATE_2_70;
180 PRINT_RATE_2_70;
181 break;
182 /* Press "3" : Set DP_Rate as 5.40 */
183 /* case '3': */
184 /* DP_Rate = DP_RATE_5_40; */
185 /* PRINT_RATE_5_40 */
186 /* break; */
187 #ifdef INTERNAL
188 /* Press "3" : Set Deemphasis_Level as 1 / Deemphasis_Level_1 as 2 */
189 case '3':
190 Deemphasis_Level = DP_DEEMP_1;
191 Deemphasis_Level_1 = DP_DEEMP_2;
192 Deemphasis_Show = DP_DEEMP_0;
193 Deemphasis_RD = Deemphasis_Show;
194 PRINT_DEEMP_0;
195 break;
196 /* Press "4" : Set Deemphasis_Level as 0 / Deemphasis_Level_1 as 0 */
197 case '4':
198 Deemphasis_Level = DP_DEEMP_0;
199 Deemphasis_Level_1 = DP_DEEMP_0;
200 Deemphasis_Show = DP_DEEMP_1;
201 Deemphasis_RD = Deemphasis_Show;
202 PRINT_DEEMP_1;
203 break;
204 /* Press "5" : Set Deemphasis_Level as 2 / Deemphasis_Level_1 as 1 */
205 case '5':
206 Deemphasis_Level = DP_DEEMP_2;
207 Deemphasis_Level_1 = DP_DEEMP_1;
208 Deemphasis_Show = DP_DEEMP_2;
209 Deemphasis_RD = Deemphasis_Show;
210 PRINT_DEEMP_2;
211 break;
212 #endif
213 case '6':
214 SSC_SHIFT = 2;
215 break;
216 case '7':
217 SSC_SHIFT = 3;
218 break;
219 default:
220 break;
221 }
222
223 if (execute_test)
224 printf("The parameter is applied next measure!\n");
225
226 } else if (received == '!') /* show config */ {
227 if (execute_test)
228 printf("Measurement is executed!\n");
229 else
230 printf("Measurement is stopped!\n");
231
232 DPPHYTX_Show_Cfg();
233 } else if (received == '0') /* change sscfg */ {
234 if (SSCG == DP_SSCG_ON) {
235 SSCG = DP_SSCG_OFF;
236 PRINT_SSCG_OFF;
237 } else {
238 SSCG = DP_SSCG_ON;
239 PRINT_SSCG_ON;
240 }
241
242 /* SSCG could be applied without reset device. */
243 if (execute_test) {
244 printf("Apply SSCG into current measurement !\n\n");
245 TX_SSCG_Cfg = DP_TX_RDY_TEST;
246 TX_SSCG_Cfg |= SSCG;
247 writel(TX_SSCG_Cfg, DP_TX_PHY_SET);
248 }
249 } else {
250 /* Check the ESC key */
251 if (received == 27) {
252 execute_test = 0;
253 DPTX_MCU_Reset();
254 printf("'ESC' is pressed!\n");
255 break;
256 }
257
258 /* If the test is execute, reset it */
259 if (execute_test) {
260 execute_test = 0;
261 DPTX_MCU_Reset();
262
263 printf("Stop current measurement !\n\n\n\n\n\n");
264 }
265
266 /* Clear flag */
267 flag = 0;
268
269 Current_Item = received;
270
271 switch (received) {
272 case 'a':
273 flag = (F_EMPHASIS_NULL | F_PAT_PRBS7);
274 break;
275
276 case 'g': /* D10.2 */
277 flag = (F_EMPHASIS_1 | F_PAT_D10_2);
278 break;
279
280 #ifdef INTERNAL
281 case 'b':
282 flag = (F_EMPHASIS_1 | F_PAT_PRBS7);
283 break;
284
285 case 'c':
286 flag = (F_EMPHASIS_1 | F_PAT_PLTPAT);
287 break;
288
289 case 'd': /* Non-Transition Voltage Range Measurement - PLTPAT */
290 flag = (F_EMPHASIS | F_PAT_PLTPAT);
291 break;
292
293 case 'e': /* Pre-Emphasis Level Test and Pre-Emphasis Level Delta Test- PRBS7 */
294 flag = (F_EMPHASIS_1 | F_PAT_PRBS7);
295 break;
296
297 case 'f': /* Non-Transition Voltage Range Measurement - PRBS7 */
298 flag = (F_EMPHASIS | F_PAT_PRBS7);
299 break;
300
301 case 'h':
302 printf("Change the Swing value from request\n");
303 flag = (F_EMPHASIS_1 | F_PAT_PRBS7 | F_SHOW_SWING);
304 break;
305
306 case 'i':
307 printf("Change the Swing value from request\n");
308 flag = (F_EMPHASIS_1 | F_PAT_PLTPAT | DP_TX_HIGH_SPEED | F_SHOW_SWING);
309 break;
310
311 case 'j':
312 flag = F_PAT_AUX;
313 break;
314 #endif
315 case 'x': /* Auto hand shaking with DPR-100 */
316 flag = F_EXE_AUTO;
317 break;
318
319 default:
320 printf("Non - define command!\n");
321 break;
322 }
323
324 // Execute testing
325 if (flag) {
326 execute_test = 1;
327 GFlag = flag;
328
329 if (flag & F_PAT_AUX) {
330 printf("######################################\n");
331 printf("#Current DP TX setting is shown below#\n");
332 printf("######################################\n\n");
333
334 DPPHYTX_Show_Item(Current_Item);
335 Apply_AUX_Mesument(flag);
336 } else if (flag & F_EXE_AUTO) {
337 printf("#########################\n");
338 printf("#Enter DP TX Auto Test!!#\n");
339 printf("#########################\n\n");
340
341 Apply_Auto_Preset(0x1);
342 Apply_Auto_Mesument();
343 Apply_Auto_Preset(0x0);
344
345 printf("#########################\n");
346 printf("#Leave DP TX Auto Test!!#\n");
347 printf("#########################\n\n");
348 } else {
349 DPPHYTX_Show_Cfg();
350 Apply_Main_Mesument(flag);
351 }
352 }
353 }
354 }
355 mdelay(200);
356 };
357
358 printf("\n\n");
359 return 0;
360 }
361
362 /* Temp for cording here */
Apply_Auto_Preset(char Init)363 void Apply_Auto_Preset(char Init)
364 {
365 /* Fill some nessary register value for auto test */
366 if (Init) {
367 /* Enable MCU received interrupt */
368 writel(0x00e80000, DP_TX_INT_CLEAR);
369
370 /* Set HPD irq time interval */
371 writel(0x04e300fb, DP_TX_IRQ_CFG);
372
373 /* Set HPD event time interval */
374 writel(0x000007d1, DP_TX_EVENT_CFG);
375 } else {
376 /* Recover */
377 writel(0x0, DP_TX_INT_CLEAR);
378 writel(0x0, DP_TX_IRQ_CFG);
379 writel(0x0, DP_TX_EVENT_CFG);
380 }
381 }
382
383 /* READ EDID */
Read_EDID_128(char Offset)384 void Read_EDID_128(char Offset)
385 {
386 char AUX_Data[16] = {0};
387 uchar Length = 1;
388 uchar Status = 0;
389 uchar i, j;
390
391 DBG(DBG_A_EDID, "R EDID Offset %d\n", Offset);
392
393 AUX_W(I2C_M_EA_CMD_W, 0x50, (int *)(&AUX_Data), &Length, &Status);
394
395 AUX_Data[0] = Offset;
396 AUX_W(I2C_M_CMD_W, 0x50, (int *)(&AUX_Data), &Length, &Status);
397
398 AUX_R(I2C_M_EA_CMD_R, 0x50, (int *)(&AUX_Data), &Length, &Status);
399
400 Length = 16;
401
402 // Read 128 bytes block
403 for (i = 0; i < 8; i++) {
404 do {
405 AUX_R(I2C_M_CMD_R, 0x50, (int *)(&AUX_Data), &Length, &Status);
406 DBG(DBG_A_EDID, "EDID read %d!\n", i);
407
408 udelay(100);
409 } while (Status == 0x20);
410
411 /* copy from temp into EDID */
412 for (j = 0; j < 16; j++)
413 EDID[Offset + i * 16 + j] = AUX_Data[j];
414 }
415
416 Length = 1;
417 AUX_R(I2C_EA_CMD_R, 0x50, (int *)(&AUX_Data), &Length, &Status);
418 }
419
Apply_EDID_Reading(void)420 void Apply_EDID_Reading(void)
421 {
422 char AUX_Data[16] = {0};
423 uchar Length = 1;
424 uchar Status = 0;
425
426 DBG(DBG_STAGE, "Apply EDID Reading!\n");
427
428 AUX_W(I2C_M_EA_CMD_W, 0x50, (int *)(&AUX_Data), &Length, &Status);
429
430 AUX_W(I2C_M_CMD_W, 0x50, (int *)(&AUX_Data), &Length, &Status);
431
432 AUX_R(I2C_M_EA_CMD_R, 0x50, (int *)(&AUX_Data), &Length, &Status);
433
434 /* Check read EDID header */
435 Length = 4;
436 do {
437 AUX_R(I2C_M_CMD_R, 0x50, (int *)(&AUX_Data), &Length, &Status);
438
439 udelay(100);
440 } while (Status == 0x20);
441
442 DBG(DBG_A_EDID, "EDID First 4 is 0x%X_0x%X_0x%X_0x%X\n", AUX_Data[0], AUX_Data[1], AUX_Data[2], AUX_Data[3]);
443
444 Length = 1;
445 AUX_R(I2C_EA_CMD_R, 0x50, (int *)(&AUX_Data), &Length, &Status);
446
447 DBG(DBG_A_EDID, "Read 128!\n");
448 Read_EDID_128(0x0);
449
450 /* If the extension bit is set, then read back next block */
451 if (EDID[0x7E] == 0x1) {
452 DBG(DBG_A_EDID, "Read 256!\n");
453 Read_EDID_128(0x80);
454 }
455 }
456
457 /* LINK TRAIN */
Adjust_CR_EQ_Train(int TrainPat,uchar ADJStatus)458 uchar Adjust_CR_EQ_Train(int TrainPat, uchar ADJStatus)
459 {
460 char AUX_Data[16] = {0};
461 uchar Ret = 0;
462 uchar Length = 1;
463 uchar Status = 0;
464 uchar AUX_R_Level = 0;
465 uchar AUX_W_Level = 0;
466 uchar DE_Level = 0x0;
467 uchar CR_Status = 0;
468 int value = 0;
469 uchar bFirst = 1;
470 uchar tempkeep = 0;
471
472 /* Set the main link pattern with TPS1 / TPS2 for Lanex_CR_Done */
473 value = ((readl(DP_TX_MAIN_PAT) & ~(0x30000000)) | TrainPat);
474 writel(value, DP_TX_MAIN_PAT);
475 DBG(DBG_A_SUB, "1.A_C_E Set Link Pattern\n");
476
477 /* AST phy 0xE4 Bit28 (0x1000000) / DP 0x102 Bit0 : TPS1 */
478 /* AST phy 0xE4 Bit29 (0x2000000) / DP 0x102 Bit1 : TPS2 */
479 if (TrainPat == 0x10000000)
480 AUX_Data[0] = 0x21;
481 else
482 AUX_Data[0] = 0x22;
483
484 AUX_W(AUX_CMD_W, 0x102, (int *)(&AUX_Data), &Length, &Status);
485 DBG(DBG_A_SUB, "2.A_C_E W 0x102 set 0x%x\n", AUX_Data[0]);
486
487 /* First */
488 if (bFirst) {
489 Length = 4;
490
491 AUX_Data[0] = CR_EQ_Keep;
492 AUX_Data[1] = CR_EQ_Keep;
493 AUX_Data[2] = CR_EQ_Keep;
494 AUX_Data[3] = CR_EQ_Keep;
495 tempkeep = CR_EQ_Keep;
496
497 do {
498 AUX_W(AUX_CMD_W, 0x103, (int *)(&AUX_Data), &Length, &Status);
499 DBG(DBG_A_SUB, "3.A_C_E W 0x103 - 0x106 set\n");
500 } while (Status == 0x20);
501
502 Length = 6;
503
504 udelay(1200);
505
506 AUX_R(AUX_CMD_R, 0x200, (int *)(&AUX_Data), &Length, &Status);
507 DBG(DBG_A_SUB, "4.A_C_E R 0x200 - 0x205 read back\n");
508
509 if ((AUX_Data[2] & ADJStatus) == ADJStatus) {
510 CR_EQ_Keep = tempkeep;
511 return Ret;
512 }
513
514 bFirst = 0;
515 }
516
517 /* loop for CR_lock */
518 do {
519 Length = 1;
520
521 AUX_R(AUX_CMD_R, 0x206, (int *)(&AUX_Data), &Length, &Status);
522 DBG(DBG_A_SUB, "5.A_C_E R 0x206 read back\n");
523 AUX_R_Level = AUX_Data[0];
524
525 AUX_R(AUX_CMD_R, 0x207, (int *)(&AUX_Data), &Length, &Status);
526 DBG(DBG_A_SUB, "6.A_C_E R 0x207 read back\n");
527
528 /* Update SW Level */
529 switch (AUX_R_Level & 0x33) {
530 case 0x00:
531 AUX_W_Level = 00;
532 break;
533 case 0x11:
534 AUX_W_Level = 01;
535 break;
536 default:
537 AUX_W_Level = 06;
538 break;
539 }
540
541 /* Update SW Level */
542 switch (AUX_R_Level & 0xCC) {
543 case 0x00:
544 /* AUX_W_Level |= 00; */
545 DE_Level = 0;
546 break;
547 case 0x44:
548 AUX_W_Level |= 0x08;
549 DE_Level = 1;
550 break;
551 default:
552 AUX_W_Level |= 0x30;
553 DE_Level = 2;
554 break;
555 }
556
557 /* Set the de-emphsis value */
558 value = ((readl(DP_TX_PHY_CFG) & ~(0x33000000)) | Deemlevel[DE_Level]);
559 writel(value, DP_TX_PHY_CFG);
560 DBG(DBG_A_SUB, "6.A_C_E Set Phy config %d\n", DE_Level);
561
562 DBG(DBG_A_SUB, "Link AUX_W_Level is 0x%x\n", AUX_W_Level);
563
564 Length = 4;
565
566 AUX_Data[0] = AUX_W_Level;
567 AUX_Data[1] = AUX_W_Level;
568 AUX_Data[2] = AUX_W_Level;
569 AUX_Data[3] = AUX_W_Level;
570 tempkeep = AUX_W_Level;
571
572 do {
573 AUX_W(AUX_CMD_W, 0x103, (int *)(&AUX_Data), &Length, &Status);
574 DBG(DBG_A_SUB, "7.A_C_E W 0x103 - 0x106 set\n");
575 } while (Status == 0x20);
576
577 udelay(1380);
578
579 Length = 6;
580 AUX_R(AUX_CMD_R, 0x200, (int *)(&AUX_Data), &Length, &Status);
581 DBG(DBG_A_SUB, "8.A_C_E R 0x200 - 0x205 read back\n");
582
583 CR_Status = AUX_Data[2] & ADJStatus;
584
585 /* Decrease speed because the deemphasis level reach max value */
586 if (AUX_W_Level == 0x36) {
587 Ret = 1;
588 break;
589 }
590
591 } while (CR_Status != ADJStatus);
592
593 CR_EQ_Keep = tempkeep;
594
595 return Ret;
596 }
597
Link_Train_Flow(char Link_Level)598 uchar Link_Train_Flow(char Link_Level)
599 {
600 char AUX_Data[16] = {0};
601 uchar Length = 1;
602 uchar Status = 0;
603 uchar Ret = 0;
604 int value = 0;
605
606 DBG(DBG_STAGE, "Link train flow! Level : %d\n", Link_Level);
607
608 AUX_R(AUX_CMD_R, 0x101, (int *)(&AUX_Data), &Length, &Status);
609 DBG(DBG_A_SUB, "1.Link R 0x101 read back\n");
610
611 /* Normal / Test case */
612 if (Auto_Lane_Count)
613 AUX_Data[0] = ((AUX_Data[0] & 0xE0) | Auto_Lane_Count);
614 else
615 AUX_Data[0] = ((AUX_Data[0] & 0xE0) | 0x2);
616
617 AUX_W(AUX_CMD_W, 0x101, (int *)(&AUX_Data), &Length, &Status);
618 DBG(DBG_A_SUB, "2.Link W 0x101 clear\n");
619
620 /* Set different clock bit rate */
621 value = ((readl(DP_TX_MAIN_SET) & ~(0x300)) | (Link_Level << 8));
622 writel(value, DP_TX_MAIN_SET);
623
624 switch (Link_Level) {
625 case 0x1: /* 2.7 */
626 AUX_Data[0] = 0x0a;
627 break;
628
629 default: /* 1.62 */
630 AUX_Data[0] = 0x06;
631 break;
632 }
633
634 AUX_W(AUX_CMD_W, 0x100, (int *)(&AUX_Data), &Length, &Status);
635 DBG(DBG_A_SUB, "3.Link W 0x100 set\n");
636
637 AUX_R(AUX_CMD_R, 0x101, (int *)(&AUX_Data), &Length, &Status);
638 DBG(DBG_A_SUB, "4.Link R 0x101 read back\n");
639
640 /* Normal / Test case */
641 if (Auto_Lane_Count)
642 AUX_Data[0] = ((AUX_Data[0] & 0xE0) | Auto_Lane_Count);
643 else
644 AUX_Data[0] = ((AUX_Data[0] & 0xE0) | 0x2);
645
646 AUX_W(AUX_CMD_W, 0x101, (int *)(&AUX_Data), &Length, &Status);
647 DBG(DBG_A_SUB, "5.Link W 0x101 clear\n");
648
649 /* Set the 2 lanes and enhance frame by checking AUX 0x2 bit 7 */
650 value = ((readl(DP_TX_MAIN_SET) & ~(0x1070)) | 0x20);
651
652 if (bEn_Frame)
653 value |= 0x1000;
654
655 writel(value, DP_TX_MAIN_SET);
656
657 value = ((readl(DP_TX_PHY_CFG) & ~(0x3000)) | 0x3000);
658
659 writel(value, DP_TX_PHY_CFG);
660
661 AUX_R(AUX_CMD_R, 0x101, (int *)(&AUX_Data), &Length, &Status);
662 DBG(DBG_A_SUB, "6.Link R 0x101 read back\n");
663
664 /* Normal / Test case */
665 if (Auto_Lane_Count)
666 AUX_Data[0] = ((AUX_Data[0] & 0xE0) | Auto_Lane_Count);
667 else
668 AUX_Data[0] = ((AUX_Data[0] & 0xE0) | 0x2);
669
670 AUX_W(AUX_CMD_W, 0x101, (int *)(&AUX_Data), &Length, &Status);
671 DBG(DBG_A_SUB, "7.Link W 0x101 clear\n");
672
673 /* Set the main link control on */
674 value = ((readl(DP_TX_PHY_SET) & ~(0x100)) | 0x100);
675
676 udelay(1000);
677 udelay(1500);
678
679 writel(value, DP_TX_PHY_SET);
680
681 do {
682 value = (readl(DP_TX_PHY_SET) & 0x200);
683 } while (value != 0x200);
684 DBG(DBG_A_SUB, "8.Link Main Link Ready\n");
685
686 /* Adjust for CR */
687 if (Adjust_CR_EQ_Train(0x10000000, 0x11)) {
688 Ret = 1;
689 return Ret;
690 }
691
692 /* Adjust for EQ */
693 if (Adjust_CR_EQ_Train(0x20000000, 0x77)) {
694 Ret = 1;
695 return Ret;
696 }
697
698 return Ret;
699 }
700
Apply_HPD_Normal(void)701 void Apply_HPD_Normal(void)
702 {
703 char AUX_Data[16] = {0};
704 uchar Length = 1;
705 uchar Status = 0;
706 int value = 0;
707
708 DBG(DBG_STAGE, "HPD Normal set!\n");
709
710 AUX_Data[0] = 0x01;
711 AUX_W(AUX_CMD_W, 0x600, (int *)(&AUX_Data), &Length, &Status);
712 DBG(DBG_NOR, "1.HPD_N W 0x600 set power!\n");
713
714 AUX_R(AUX_CMD_R, 0x0, (int *)(&AUX_Data), &Length, &Status);
715 DBG(DBG_NOR, "2.HPD_N R 0x0 read back is 0x%X!\n", AUX_Data[0]);
716
717 Length = 8;
718 AUX_R(AUX_CMD_R, 0x500, (int *)(&AUX_Data), &Length, &Status);
719 DBG(DBG_NOR, "3.HPD_N R 0x500 - 0x508 read back\n");
720
721 Length = 14;
722 AUX_R(AUX_CMD_R, 0x0, (int *)(&AUX_Data), &Length, &Status);
723 DBG(DBG_NOR, "4.HPD_N R 0x0 - 0xD read back\n");
724
725 bEn_Frame = AUX_Data[2] & 0x80;
726 Link_Aux_RD_Val = AUX_Data[14];
727
728 if (bEn_Frame)
729 DBG(DBG_NOR, "4.HPD_N R 0x2 En_Frame_Cap\n");
730
731 Length = 1;
732 AUX_R(AUX_CMD_R, 0xe, (int *)(&AUX_Data), &Length, &Status);
733 DBG(DBG_NOR, "5.HPD_N R 0xE read back\n");
734
735 /* Read EDID */
736 DBG(DBG_NOR, "6.HPD_N Apply_EDID_Reading Enter\n");
737
738 Apply_EDID_Reading();
739
740 DBG(DBG_NOR, "6.HPD_N Apply_EDID_Reading Leave\n");
741
742 Length = 2;
743 AUX_R(AUX_CMD_R, 0x200, (int *)(&AUX_Data), &Length, &Status);
744 DBG(DBG_NOR, "7.HPD_N R 0x200 - 0x201 read back.\n");
745
746 Length = 1;
747 AUX_R(AUX_CMD_R, 0x68028, (int *)(&AUX_Data), &Length, &Status);
748 DBG(DBG_NOR, "8.HPD_N R 0x68028 read back.\n");
749
750 AUX_R(AUX_CMD_R, 0x68028, (int *)(&AUX_Data), &Length, &Status);
751 DBG(DBG_NOR, "9.HPD_N R 0x68028 read back.\n");
752
753 AUX_R(AUX_CMD_R, 0x600, (int *)(&AUX_Data), &Length, &Status);
754 DBG(DBG_NOR, "10.HPD_N R 0x600 read back.\n");
755
756 AUX_Data[0] = 0x01;
757 AUX_W(AUX_CMD_W, 0x600, (int *)(&AUX_Data), &Length, &Status);
758 DBG(DBG_NOR, "11.HPD_N W 0x600 set power!\n");
759
760 DBG(DBG_NOR, "12.HPD_N Link_Train_Flow 0x1 Enter\n");
761
762 Status = Link_Train_Flow(0x1);
763
764 DBG(DBG_NOR, "12.HPD_N Link_Train_Flow 0x1 Leave\n");
765
766 if (Status) {
767 AUX_Data[0] = 0x20;
768 AUX_W(AUX_CMD_W, 0x102, (int *)(&AUX_Data), &Length, &Status);
769 DBG(DBG_ERR, "!!HPD_N W 0x102 set Train Flow 0x1 Fail!!\n");
770
771 DBG(DBG_NOR, "13.HPD_N Link_Train_Flow 0x0 Enter\n");
772
773 Status = Link_Train_Flow(0x0);
774
775 DBG(DBG_NOR, "13.HPD_NLink_Train_Flow 0x0 Leave\n");
776
777 if (Status) {
778 AUX_Data[0] = 0x20;
779 AUX_W(AUX_CMD_W, 0x102, (int *)(&AUX_Data), &Length, &Status);
780 DBG(DBG_ERR, "!!HPD_N W 0x102 set Train Flow 0x0 Fail!!\n");
781
782 DBG(DBG_ERR, "### CAUTION!! LINK TRAN FAIL!! ###\n");
783
784 return;
785 }
786 }
787
788 /* Link successful */
789 AUX_Data[0] = 0x00;
790 AUX_W(AUX_CMD_W, 0x102, (int *)(&AUX_Data), &Length, &Status);
791 DBG(DBG_NOR, "14.HPD_N W 0x102 clear!\n");
792
793 /* Fill idle pattern */
794 value = ((readl(DP_TX_MAIN_PAT) & ~(0x31000000)) | 0x01000000);
795 writel(value, DP_TX_MAIN_PAT);
796 DBG(DBG_NOR, "15.HPD_N Fill idle pattern!\n");
797
798 Length = 1;
799 AUX_R(AUX_CMD_R, 0x68028, (int *)(&AUX_Data), &Length, &Status);
800 DBG(DBG_NOR, "16.HPD_N R 0x68028 read back.\n");
801
802 Length = 5;
803 AUX_R(AUX_CMD_R, 0x68000, (int *)(&AUX_Data), &Length, &Status);
804 DBG(DBG_NOR, "17.HPD_N R 0x68000 - 0x68004 read back.\n");
805
806 Length = 1;
807 AUX_R(AUX_CMD_R, 0x68028, (int *)(&AUX_Data), &Length, &Status);
808 DBG(DBG_NOR, "18.HPD_N R 0x68028 read back.\n");
809
810 AUX_R(AUX_CMD_R, 0x68028, (int *)(&AUX_Data), &Length, &Status);
811 DBG(DBG_NOR, "19.HPD_N R 0x68028 read back.\n");
812
813 AUX_R(AUX_CMD_R, 0x0, (int *)(&AUX_Data), &Length, &Status);
814 DBG(DBG_NOR, "20.HPD_N R 0x0 read back.\n");
815 }
816
Apply_HPD_Auto_Test(void)817 void Apply_HPD_Auto_Test(void)
818 {
819 char AUX_Data[16];
820 uchar Length = 0;
821 uchar Status = 0;
822 uchar clear_auto_test = 0;
823 uchar auto_test_link = 0;
824 uchar auto_test_phy = 0;
825 uchar swing0 = 0, preemphasis0 = 0;
826 uchar swing1 = 0, preemphasis1 = 0;
827 int flag = 0;
828 char temp0 = 0, temp1 = 0;
829 char temp206 = 0;
830
831 DBG(DBG_STAGE, "HPD Auto test set!\n");
832
833 /* Set power D0 */
834 AUX_Data[0] = 0x01;
835 Length = 1;
836 AUX_W(AUX_CMD_W, 0x600, (int *)(&AUX_Data), &Length, &Status);
837 DBG(DBG_A_TEST, "1.HP_I W 0x600 done!\n");
838
839 Length = 6;
840 AUX_R(AUX_CMD_R, 0x200, (int *)(&AUX_Data), &Length, &Status);
841 DBG(DBG_A_TEST, "2.HP_I R 0x200 - 0x206 done!\n");
842
843 Length = 1;
844 AUX_R(AUX_CMD_R, 0x201, (int *)(&AUX_Data), &Length, &Status);
845 DBG(DBG_A_TEST, "3.HP_I R 0x201 : 0x%x\n", AUX_Data[0]);
846
847 /* Obtain auto test */
848 if (AUX_Data[0] & 0x2)
849 clear_auto_test = 1;
850 else
851 clear_auto_test = 0;
852
853 /* Read dummy */
854 Length = 3;
855 AUX_R(AUX_CMD_R, 0x202, (int *)(&AUX_Data), &Length, &Status);
856 Length = 1;
857 AUX_R(AUX_CMD_R, 0x101, (int *)(&AUX_Data), &Length, &Status);
858 AUX_R(AUX_CMD_R, 0x200, (int *)(&AUX_Data), &Length, &Status);
859 Length = 3;
860 AUX_R(AUX_CMD_R, 0x202, (int *)(&AUX_Data), &Length, &Status);
861 Length = 1;
862 AUX_R(AUX_CMD_R, 0x205, (int *)(&AUX_Data), &Length, &Status);
863 DBG(DBG_A_TEST, "4. HP_I R Dummy!\n");
864
865 AUX_R(AUX_CMD_R, 0x219, (int *)(&AUX_Data), &Length, &Status);
866 DBG(DBG_A_TEST, "5. HP_I Link Rate R 0x219 : 0x%x\n", AUX_Data[0]);
867
868 if (AUX_Data[0] == 0x06) {
869 Auto_Link_Rate = AUX_Data[0];
870 DP_Rate = DP_RATE_1_62;
871 PRINT_RATE_1_62;
872 } else if (AUX_Data[0] == 0x0a) {
873 Auto_Link_Rate = AUX_Data[0];
874 DP_Rate = DP_RATE_2_70;
875 PRINT_RATE_2_70;
876 } else if (AUX_Data[0] == 0x14) {
877 DBG(DBG_ERR, "!!DON'T SET 5.4 bps !!\n");
878 return;
879 }
880
881 if (clear_auto_test) {
882 AUX_Data[0] = 0x02;
883 AUX_W(AUX_CMD_W, 0x201, (int *)(&AUX_Data), &Length, &Status);
884 DBG(DBG_A_TEST, "1.HP_I CA W 0x201 clear auto!\n");
885 clear_auto_test = 0;
886
887 /* Fetch Testing data */
888 AUX_R(AUX_CMD_R, 0x218, (int *)(&AUX_Data), &Length, &Status);
889 DBG(DBG_A_TEST, "2.HP_I CA R 0x218 : 0x%x\n", AUX_Data[0]);
890
891 /* Check auto test link flag */
892 if (AUX_Data[0] & 0x1)
893 auto_test_link = 1;
894 else
895 auto_test_link = 0;
896
897 /* Check auto test phy flag */
898 if (AUX_Data[0] & 0x8)
899 auto_test_phy = 1;
900 else
901 auto_test_phy = 0;
902 DBG(DBG_A_TEST, "auto test link(%d) phy(%d)\n", auto_test_link, auto_test_phy);
903
904 if (auto_test_link) {
905 AUX_R(AUX_CMD_R, 0x219, (int *)(&AUX_Data), &Length, &Status);
906 DBG(DBG_A_TEST, "1.HP_I TL R 0x219 : 0x%x\n", AUX_Data[0]);
907
908 if (AUX_Data[0] == 0x06) {
909 Auto_Link_Rate = AUX_Data[0];
910 DP_Rate = DP_RATE_1_62;
911 PRINT_RATE_1_62;
912 } else if (AUX_Data[0] == 0x0a) {
913 Auto_Link_Rate = AUX_Data[0];
914 DP_Rate = DP_RATE_2_70;
915 PRINT_RATE_2_70;
916 } else if (AUX_Data[0] == 0x14) {
917 DBG(DBG_ERR, "!!DON'T SET 5.4 bps !!\n");
918 return;
919 }
920
921 AUX_R(AUX_CMD_R, 0x220, (int *)(&AUX_Data), &Length, &Status);
922 DBG(DBG_A_TEST, "2.HP_I TL R 0x220 : 0x%x\n", AUX_Data[0]);
923 Auto_Lane_Count = AUX_Data[0] & 0x1F;
924
925 AUX_Data[0] = 0x01;
926 AUX_W(AUX_CMD_W, 0x260, (int *)(&AUX_Data), &Length, &Status);
927 DBG(DBG_A_TEST, "3.HP_I TL W 0x260 test ACK\n");
928
929 mdelay(95);
930
931 /* Set power D0 */
932 AUX_Data[0] = 0x01;
933 AUX_W(AUX_CMD_W, 0x600, (int *)(&AUX_Data), &Length, &Status);
934 DBG(DBG_A_TEST, "3.1 HP_I W 0x600 done!\n");
935
936 switch (Auto_Link_Rate) {
937 case 0x06:
938 DBG(DBG_A_TEST, "4.HP_I TL Link_Train_Flow 1.62bps Enter\n");
939 Status = Link_Train_Flow(0x0);
940 DBG(DBG_A_TEST, "4.HP_I TL Link_Train_Flow 1.62bps Leave\n");
941 break;
942
943 case 0x0a:
944 DBG(DBG_A_TEST, "4.HP_I TL Link_Train_Flow 2.70bps Enter\n");
945 Status = Link_Train_Flow(0x1);
946 DBG(DBG_A_TEST, "4.HP_I TL Link_Train_Flow 2.70bps Leave\n");
947 break;
948
949 default:
950 DBG(DBG_ERR, "!!BAD LINK RATE!!\n");
951 return;
952 }
953
954 if (Status) {
955 DBG(DBG_ERR, "!!AUTO TEST LINK FAIL!!\n");
956 return;
957 }
958
959 /* Link successful */
960 AUX_Data[0] = 0x00;
961 AUX_W(AUX_CMD_W, 0x102, (int *)(&AUX_Data), &Length, &Status);
962 DBG(DBG_A_TEST, "5.HP_I TL Link clear!\n");
963
964 auto_test_link = 0;
965 }
966
967 if (auto_test_phy) {
968 Length = 1;
969 flag = 0;
970 temp206 = 0;
971
972 AUX_R(AUX_CMD_R, 0x248, (int *)(&AUX_Data), &Length, &Status);
973 DBG(DBG_A_TEST, "1.HP_I TP R 0x248 : 0x%x!\n", AUX_Data[0]);
974
975 if (AUX_Data[0] == 0x01) {
976 flag |= F_PAT_D10_2;
977 DBG(DBG_A_TEST, "HP_I TP D10.2!\n");
978 } else if (AUX_Data[0] == 0x03) {
979 flag |= F_PAT_PRBS7;
980 DBG(DBG_A_TEST, "HP_I TP PRBS7!\n");
981 }
982
983 AUX_R(AUX_CMD_R, 0x206, (int *)(&AUX_Data), &Length, &Status);
984 DBG(DBG_A_TEST, "2.HP_I TP R 0x206 : 0x%x!\n", AUX_Data[0]);
985
986 /* Temp for verified */
987 DBG(DBG_INF, "Read value 0x206 : 0x%x!\n", AUX_Data[0]);
988
989 /* Check Swing */
990 temp0 = (AUX_Data[0] & 0x03);
991 temp1 = (AUX_Data[0] & 0x30);
992
993 /* Check Swing0 */
994 switch (temp0) {
995 case 0x2:
996 swing0 = 0x2;
997 temp206 |= 6;
998 break;
999 case 0x1:
1000 swing0 = 0x1;
1001 temp206 |= 1;
1002 break;
1003 case 0x0:
1004 swing0 = 0x0;
1005 break;
1006 default:
1007 DBG(DBG_ERR, "HP_I TP 0x206 other swing0 val %x!\n", temp0);
1008 break;
1009 }
1010
1011 /* Check Swing1 */
1012 switch (temp1) {
1013 case 0x20:
1014 swing1 = 0x2;
1015 temp206 |= 6;
1016 break;
1017 case 0x10:
1018 swing1 = 0x1;
1019 temp206 |= 1;
1020 break;
1021 case 0x00:
1022 swing1 = 0x0;
1023 break;
1024 default:
1025 DBG(DBG_ERR, "HP_I TP 0x206 other swing1 val %x!\n", temp1);
1026 break;
1027 }
1028
1029 if (swing0 != swing1)
1030 DBG(DBG_ERR, "Swing 0 / 1 diff val %x!\n", AUX_Data[0]);
1031
1032 /* Check Pre-emphasis */
1033 temp0 = (AUX_Data[0] & 0x0C);
1034 temp1 = (AUX_Data[0] & 0xC0);
1035
1036 /* Check Pre-emphasis0 */
1037 switch (temp0) {
1038 case 0x8:
1039 preemphasis0 = 0x2;
1040 temp206 |= 0x30;
1041 break;
1042 case 0x4:
1043 preemphasis0 = 0x1;
1044 temp206 |= 0x08;
1045 break;
1046 case 0x0:
1047 preemphasis0 = 0x0;
1048 break;
1049 default:
1050 DBG(DBG_ERR, "HP_I TP 0x206 other Pre-emphasis0 val %x!\n", temp0);
1051 break;
1052 }
1053
1054 /* Check Pre-emphasis1 */
1055 switch (temp1) {
1056 case 0x80:
1057 preemphasis1 = 0x2;
1058 temp206 |= 0x30;
1059 break;
1060 case 0x40:
1061 preemphasis1 = 0x1;
1062 temp206 |= 0x08;
1063 break;
1064 case 0x00:
1065 preemphasis1 = 0x0;
1066 break;
1067 default:
1068 DBG(DBG_ERR, "HP_I TP 0x206 other Pre-emphasis1 val %x!\n", temp1);
1069 break;
1070 }
1071
1072 if (preemphasis0 != preemphasis1)
1073 DBG(DBG_ERR, "Preemphasis 0 / 1 diff val %x!\n", AUX_Data[0]);
1074
1075 /* Judgement */
1076 if (swing0 == 0x2 || swing1 == 0x2)
1077 Swing_Level = 0x2;
1078 else if (swing0 == 1 || swing1 == 0x1)
1079 Swing_Level = 0x1;
1080 else if (swing0 == 0x0 || swing1 == 0x0)
1081 Swing_Level = 0x0;
1082
1083 if (preemphasis0 == 0x2 || preemphasis1 == 0x2) {
1084 Deemphasis_RD = DP_DEEMP_2;
1085 Deemphasis_Level_1 = DP_DEEMP_1;
1086 DBG(DBG_ERR, "!!De-type 1 P_2 !!\n");
1087 } else if (preemphasis0 == 0x1 || preemphasis1 == 0x1) {
1088 Deemphasis_RD = DP_DEEMP_1;
1089 Deemphasis_Level_1 = DP_DEEMP_0;
1090 DBG(DBG_ERR, "!!De-type 0 P_1 !!\n");
1091 } else if (preemphasis0 == 0x0 || preemphasis1 == 0x0) {
1092 Deemphasis_RD = DP_DEEMP_0;
1093 Deemphasis_Level_1 = DP_DEEMP_2;
1094 DBG(DBG_ERR, "!!De-type 2 P_0 !!\n");
1095 }
1096
1097 DBG(DBG_INF, "!!Swing %d / Pre-emphasis %d !!\n", swing0, preemphasis0);
1098
1099 flag |= F_EMPHASIS_1;
1100
1101 AUX_R(AUX_CMD_R, 0x102, (int *)(&AUX_Data), &Length, &Status);
1102 DBG(DBG_A_TEST, "3.HP_I TP R 0x102 : 0x%x\n", AUX_Data[0]);
1103 temp0 = AUX_Data[0];
1104
1105 Length = 2;
1106 AUX_R(AUX_CMD_R, 0x10b, (int *)(&AUX_Data), &Length, &Status);
1107 DBG(DBG_A_TEST, "4.HP_I TP R 0x10b : 0x%x\n", AUX_Data[0]);
1108
1109 AUX_W(AUX_CMD_W, 0x10b, (int *)(&AUX_Data), &Length, &Status);
1110 DBG(DBG_A_TEST, "5.HP_I TP W 0x10b done!\n");
1111
1112 AUX_Data[0] = temp0 | 0x20;
1113 Length = 1;
1114 AUX_W(AUX_CMD_W, 0x102, (int *)(&AUX_Data), &Length, &Status);
1115 DBG(DBG_A_TEST, "6.HP_I TP W 0x102 done!\n");
1116
1117 AUX_Data[0] = temp206;
1118 AUX_Data[1] = temp206;
1119 Length = 2;
1120
1121 do {
1122 AUX_W(AUX_CMD_W, 0x103, (int *)(&AUX_Data), &Length, &Status);
1123 DBG(DBG_A_TEST, "7.HP_I TP W 0x103 - 0x104 done!\n");
1124 } while (Status == 0x20);
1125
1126 DPPHYTX_Show_Cfg();
1127 Apply_Main_Mesument(flag);
1128
1129 Length = 1;
1130 AUX_Data[0] = 0x01;
1131 AUX_W(AUX_CMD_W, 0x260, (int *)(&AUX_Data), &Length, &Status);
1132 DBG(DBG_A_TEST, "8.HP_I TP W 0x260 done!\n");
1133
1134 DBG(DBG_STAGE, "Leave Apply Auto Test\n");
1135
1136 auto_test_phy = 0;
1137 }
1138 clear_auto_test = 0;
1139 }
1140 }
1141
1142 /* TEST SECTION */
Apply_Auto_Mesument(void)1143 void Apply_Auto_Mesument(void)
1144 {
1145 char auto_received = 0;
1146 int temp = 0, wdata = 0;
1147 int breakcount = 0;
1148
1149 while (1) {
1150 breakcount = 0;
1151
1152 /* Wait HPD */
1153 do {
1154 temp = (readl(DP_TX_INT_STATUS) & 0x3800);
1155 breakcount++;
1156
1157 if (breakcount == 0x96000) {
1158 /* A simple break for esc press received */
1159 break;
1160 }
1161
1162 } while (!(temp & 0x3800));
1163
1164 if (temp) {
1165 /* Clear AUX write interrupt status */
1166 wdata = (readl(DP_TX_INT_CLEAR) | (temp >> 8));
1167 writel(wdata, DP_TX_INT_CLEAR);
1168 }
1169
1170 /* Interrupt occur */
1171 if (temp & 0x2800) {
1172 /* Initial global parameter */
1173 Auto_Link_Rate = 0;
1174 Auto_Lane_Count = 0;
1175 bEn_Frame = 0;
1176 CR_EQ_Keep = 0;
1177
1178 if (temp & 0x2000) {
1179 printf("DP HPD irq is detected!\n");
1180 Apply_HPD_Normal();
1181 }
1182
1183 if (temp & 0x800) {
1184 printf("DP HPD event is detected!\n");
1185 Apply_HPD_Auto_Test();
1186 }
1187 }
1188
1189 /* Leave auto test if the 'ESC' is pressed */
1190 if (tstc()) {
1191 auto_received = getc();
1192
1193 /* Check the ESC key */
1194 if (auto_received == 27) {
1195 printf("'ESC' is pressed under auto test!\n\n");
1196 return;
1197 }
1198
1199 printf("DP TX auto test is executed!\n");
1200 }
1201 }
1202 }
1203
Apply_Main_Mesument(int flag)1204 void Apply_Main_Mesument(int flag)
1205 {
1206 DPTX_MCU_Reset();
1207
1208 /* Emphasis setting */
1209 if (flag & F_EMPHASIS_NULL)
1210 writel(PHY_Cfg_N, DP_TX_PHY_CFG);
1211 else if (flag & F_EMPHASIS)
1212 writel(PHY_Cfg, DP_TX_PHY_CFG);
1213 else if (flag & F_EMPHASIS_1)
1214 writel(PHY_Cfg_1, DP_TX_PHY_CFG);
1215
1216 if (flag & F_RES_HIGH)
1217 writel(DP_TX_HIGH_SPEED, DP_TX_RES_CFG);
1218 else
1219 writel(DP_TX_NOR_SPEED, DP_TX_RES_CFG);
1220
1221 writel(PHY_Cfg_1, DP_TX_PHY_CFG);
1222
1223 DPPHY_Set();
1224
1225 if (flag & F_PAT_PRBS7)
1226 Set_PRBS7();
1227 else if (flag & F_PAT_PLTPAT)
1228 Set_PLTPAT();
1229 else if (flag & F_PAT_HBR2CPAT)
1230 Set_HBR2CPAT();
1231 else if (flag & F_PAT_D10_2)
1232 Set_D10_1();
1233
1234 // ssc only used if D10.2
1235 if ((flag & F_PAT_D10_2) == 0) {
1236 TX_SSCG_Cfg &= ~DP_SSCG_ON;
1237 printf("SSC isn't on for pattern other than D10.2\n");
1238 }
1239
1240 // ssc shift only used if ssc on
1241 if (TX_SSCG_Cfg & DP_SSCG_ON) {
1242 /*Apply special patch*/
1243 writel(SSC_SHIFT << 10, DP_TX_RES_CFG);
1244 } else {
1245 /*Recover into original setting*/
1246 writel(0x00000000, DP_TX_RES_CFG);
1247 }
1248
1249 writel(TX_SSCG_Cfg, DP_TX_PHY_SET);
1250 }
1251
Apply_AUX_Mesument(int flag)1252 void Apply_AUX_Mesument(int flag)
1253 {
1254 DPTX_MCU_Reset();
1255 DPPHY_Set();
1256
1257 writel(0x0F000000, DP_AUX_ADDR_LEN);
1258 writel(0x80000010, DP_AUX_REQ_CFG);
1259 }
1260
1261 /* FUNCTION SECTION */
1262 /* i2c set */
1263 #ifdef RE_DRIVER
Set_Redriver(void)1264 void Set_Redriver(void)
1265 {
1266 int value = 0x0;
1267 uchar offset = 0x0;
1268 uchar *set_table = &set_table0;
1269
1270 if (Deemphasis_RD == DP_DEEMP_1)
1271 set_table = &set_table1;
1272 else if (Deemphasis_RD == DP_DEEMP_2)
1273 set_table = &set_table2;
1274
1275 RD_VAL = set_table[Swing_Level];
1276
1277 printf("RD_VAL is 0x%x\n", RD_VAL);
1278
1279 writel(0x600, I2C_BASE + I2C0_COUNT_O);
1280 value = (0x0000f0f0 | (RD_VAL << 24));
1281 writel(value, I2C_BUFF);
1282 printf("value0 is 0x%x\n", value);
1283 value = (RD_VAL | (RD_VAL << 8) | (RD_VAL << 16) | (RD_VAL << 24));
1284 writel(value, (I2C_BUFF + 0x4));
1285 printf("value1 is 0x%x\n", value);
1286 writel(0x70010063, (I2C_BASE + I2C0_EXECUTE_O));
1287 mdelay(1000);
1288 }
1289
1290 /* i2c single initial */
I2C_L_Initial(void)1291 void I2C_L_Initial(void)
1292 {
1293 I2C_BASE = (I2C0_BASE + (I2C_DEV_OFFSET * I2C_PORT));
1294 I2C_BUFF = (I2C0_BUFF + (I2C_BUFF_OFFSET * I2C_PORT));
1295
1296 writel(0x0, I2C_BASE);
1297 mdelay(1);
1298 writel(0x28001, I2C_BASE);
1299 writel(0x344001, I2C_BASE + I2C0_TIMMING_O);
1300 writel(0xFFFFFFFF, I2C_BASE + I2C0_INT_STATUS_O);
1301 writel(0x0, I2C_BASE + I2C0_INT_O);
1302 mdelay(10);
1303 }
1304
1305 /* i2c golbal iniitial */
I2C_G_Initial(void)1306 void I2C_G_Initial(void)
1307 {
1308 /* i2c multi-function */
1309 writel(0x0FFF3000, MP_SCU410);
1310 writel(0x0F00FF00, MP_SCU414);
1311 writel(0xCFFF001F, MP_SCU418);
1312 writel(0xF00000FF, MP_SCU4b0);
1313 writel(0xF0FF00FF, MP_SCU4b4);
1314 writel(0x0000FF00, MP_SCU4b8);
1315
1316 /* I2c control */
1317 writel(0x16, (I2C_GBASE + 0xC));
1318 writel(0x041230C6, (I2C_GBASE + 0x10));
1319
1320 mdelay(1000);
1321 }
1322 #endif
1323
DPTX_MCU_Reset(void)1324 void DPTX_MCU_Reset(void)
1325 {
1326 /* Reset DPMCU & Release DPTX */
1327 writel(0x20000000, SYS_REST);
1328 writel(0x10000000, SYS_REST_CLR);
1329
1330 /* Wait for apply setting */
1331 mdelay(1000);
1332 }
1333
DPPHY_Set(void)1334 void DPPHY_Set(void)
1335 {
1336 int value = 0, count = 0;
1337
1338 /* Clear power on reset */
1339 writel(0x10000000, DP_TX_PHY_SET);
1340 mdelay(1);
1341
1342 /* Clear DPTX reset */
1343 writel(0x11000000, DP_TX_PHY_SET);
1344 mdelay(1);
1345
1346 /* Turn on Main link / Aux channel */
1347 writel(0x11001100, DP_TX_PHY_SET);
1348 mdelay(1);
1349
1350 while (value != DP_TX_RDY_TEST) {
1351 value = readl(DP_TX_PHY_SET);
1352 mdelay(1);
1353 count++;
1354 }
1355 }
1356
1357 // Show and update cfg for registers
1358 // DP_TX_PHY_CFG: PHY_Cfg and PHY_Cfg_1 are used here by condition
1359 // DP_TX_PHY_SET: TX_SSCG_Cfg used here
DPPHYTX_Show_Cfg(void)1360 char DPPHYTX_Show_Cfg(void)
1361 {
1362 char SetFail = 0;
1363
1364 PHY_Cfg = DP_PHY_INIT_CFG;
1365 PHY_Cfg_1 = DP_PHY_INIT_CFG;
1366 TX_SSCG_Cfg = DP_TX_RDY_TEST;
1367
1368 /* Show the setting */
1369
1370 printf("######################################\n");
1371 printf("#Current DP TX setting is shown below#\n");
1372 printf("######################################\n\n");
1373
1374 DPPHYTX_Show_Item(Current_Item);
1375
1376 switch (DP_Rate) {
1377 case DP_RATE_1_62:
1378 PRINT_RATE_1_62;
1379 break;
1380
1381 case DP_RATE_2_70:
1382 PRINT_RATE_2_70;
1383 break;
1384
1385 case DP_RATE_5_40:
1386 PRINT_RATE_5_40;
1387 break;
1388
1389 default:
1390 PRINT_INVALID;
1391 printf("DP Rate\n");
1392 SetFail = 1;
1393 break;
1394 }
1395
1396 switch (Deemphasis_Show) {
1397 case DP_DEEMP_0:
1398 if (GFlag & F_SHOW_SWING)
1399 PRINT_SWING_0;
1400 else
1401 PRINT_EMPVAL_0;
1402 break;
1403
1404 case DP_DEEMP_1:
1405 if (GFlag & F_SHOW_SWING)
1406 PRINT_SWING_1;
1407 else
1408 PRINT_EMPVAL_1;
1409 break;
1410
1411 case DP_DEEMP_2:
1412 if (GFlag & F_SHOW_SWING)
1413 PRINT_SWING_2;
1414 else
1415 PRINT_EMPVAL_2;
1416 break;
1417
1418 default:
1419 PRINT_INVALID;
1420 printf("Deemphasis Level\n");
1421 SetFail = 1;
1422 break;
1423 }
1424
1425 switch (Swing_Level) {
1426 case 0:
1427 PRINT_SWING_0;
1428 break;
1429
1430 case 1:
1431 PRINT_SWING_1;
1432 break;
1433
1434 case 2:
1435 PRINT_SWING_2;
1436 break;
1437
1438 default:
1439 PRINT_INVALID;
1440 printf("Swing Level\n");
1441 SetFail = 1;
1442 break;
1443 }
1444
1445 PHY_Cfg = DP_PHY_INIT_CFG | (DP_Rate | Deemphasis_Level);
1446 PHY_Cfg_1 = DP_PHY_INIT_CFG | (DP_Rate | Deemphasis_Level_1);
1447 PHY_Cfg_N = DP_PHY_INIT_CFG | (DP_Rate | DP_DEEMP_2);
1448
1449 switch (SSCG) {
1450 case DP_SSCG_ON:
1451 PRINT_SSCG_ON;
1452 printf("SSC shift -%d ppm\n", SSC_SHIFT * 40);
1453 break;
1454
1455 case DP_SSCG_OFF:
1456 PRINT_SSCG_OFF;
1457 break;
1458
1459 default:
1460 PRINT_INVALID;
1461 printf("SSCG\n");
1462 SetFail = 1;
1463 break;
1464 }
1465 TX_SSCG_Cfg |= SSCG;
1466
1467 printf("\n");
1468
1469 return SetFail;
1470 }
1471
DPPHYTX_Show_Item(char received)1472 void DPPHYTX_Show_Item(char received)
1473 {
1474 switch (received) {
1475 case 'a':
1476 PRINT_ITEM_A;
1477 break;
1478
1479 case 'b':
1480 PRINT_ITEM_B;
1481 break;
1482
1483 case 'c':
1484 PRINT_ITEM_C;
1485 break;
1486
1487 case 'd':
1488 PRINT_ITEM_D;
1489 break;
1490
1491 case 'e':
1492 PRINT_ITEM_E;
1493 break;
1494
1495 case 'f':
1496 PRINT_ITEM_F;
1497 break;
1498
1499 case 'g':
1500 PRINT_ITEM_G;
1501 break;
1502
1503 case 'h':
1504 PRINT_ITEM_H;
1505 break;
1506
1507 case 'i':
1508 PRINT_ITEM_I;
1509 break;
1510
1511 case 'j':
1512 PRINT_ITEM_J;
1513 break;
1514
1515 case 'x':
1516 PRINT_ITEM_X;
1517 break;
1518
1519 default:
1520 break;
1521 }
1522
1523 printf("\n");
1524 }
1525
Set_PRBS7(void)1526 void Set_PRBS7(void)
1527 {
1528 writel(DP_TX_MAIN_NOR, DP_TX_MAIN_SET);
1529 writel((DP_PY_PAT | DP_PY_PAT_PRB7), DP_TX_PHY_PAT);
1530 }
1531
Set_HBR2CPAT(void)1532 void Set_HBR2CPAT(void)
1533 {
1534 int value = 0, count = 0;
1535
1536 writel(DP_TX_MAIN_ADV, DP_TX_MAIN_SET);
1537
1538 writel(DP_TX_PAT_HBR2, DP_TX_MAIN_PAT);
1539 writel((DP_PY_PAT | DP_PY_PAT_SCRB), DP_TX_PHY_PAT);
1540
1541 writel(DP_TX_MAIN_TRA, DP_TX_MAIN_CFG);
1542 mdelay(1);
1543
1544 while (value != DP_TX_RDY_25201) {
1545 value = (readl(DP_TX_MAIN_CFG) & 0xFFF);
1546 mdelay(1);
1547 count++;
1548 }
1549
1550 /* Reset for signal apply */
1551 writel((DP_TX_MAIN_ADV | DP_TX_PY_RESET), DP_TX_MAIN_SET);
1552 }
1553
Set_PLTPAT(void)1554 void Set_PLTPAT(void)
1555 {
1556 writel(DP_TX_MAIN_NOR, DP_TX_MAIN_SET);
1557
1558 writel(DP_TX_PLTPAT_0, DP_TX_CUS_PAT_0);
1559 writel(DP_TX_PLTPAT_1, DP_TX_CUS_PAT_1);
1560 writel(DP_TX_PLTPAT_2, DP_TX_CUS_PAT_2);
1561
1562 writel((DP_PY_PAT | DP_PY_PAT_CUS), DP_TX_PHY_PAT);
1563 }
1564
Set_D10_1(void)1565 void Set_D10_1(void)
1566 {
1567 writel(DP_TX_MAIN_NOR, DP_TX_MAIN_SET);
1568
1569 writel(DP_TX_PAT_TPS1, DP_TX_MAIN_PAT);
1570 writel(DP_PY_PAT, DP_TX_PHY_PAT);
1571 }
1572
AUX_R(int aux_cmd,int aux_addr,int * aux_r_data,uchar * length,uchar * status)1573 uchar AUX_R(int aux_cmd, int aux_addr, int *aux_r_data, uchar *length, uchar *status)
1574 {
1575 int wdata = 0, temp = 0;
1576 uchar len = *length;
1577
1578 /* Check valid length */
1579 if (len >= 1)
1580 len -= 1;
1581 else
1582 return 1;
1583
1584 /* Prepare AUX write address and data */
1585 wdata = (int)((len << 24) | aux_addr);
1586 writel(wdata, DP_AUX_ADDR_LEN);
1587
1588 DBG(DBG_AUX_R, "AUX Read on 0x%x with %d bytes.\n", aux_addr, *length);
1589
1590 /* Fire AUX read */
1591 writel(aux_cmd, DP_AUX_REQ_CFG);
1592
1593 /* Wait AUX read finish or timeout */
1594 do {
1595 temp = (readl(DP_TX_INT_STATUS) & 0xC000);
1596 } while (!(temp & 0xC000));
1597
1598 /* Clear AUX write interrupt status */
1599 wdata = (readl(DP_TX_INT_CLEAR) | (temp >> 8));
1600 writel(wdata, DP_TX_INT_CLEAR);
1601
1602 if (temp & AUX_CMD_DONE) {
1603 /* Read back data count */
1604 *aux_r_data = readl(DP_AUX_R_D_0);
1605
1606 DBG(DBG_AUX_R, "Data on 0x0 is 0x%x.\n", *aux_r_data);
1607
1608 if ((*length) > 0x4) {
1609 aux_r_data++;
1610 *aux_r_data = readl(DP_AUX_R_D_4);
1611 DBG(DBG_AUX_R, "Data on 0x4 is 0x%x.\n", *aux_r_data);
1612 }
1613
1614 if ((*length) > 0x8) {
1615 aux_r_data++;
1616 *aux_r_data = readl(DP_AUX_R_D_8);
1617 DBG(DBG_AUX_R, "Data on 0x8 is 0x%x.\n", *aux_r_data);
1618 }
1619
1620 if ((*length) > 0xC) {
1621 aux_r_data++;
1622 *aux_r_data = readl(DP_AUX_R_D_C);
1623 DBG(DBG_AUX_R, "Data on 0xC is 0x%x.\n", *aux_r_data);
1624 }
1625
1626 (*status) = (uchar)(readl(DP_AUX_STATUS) & 0xFF);
1627 return 0;
1628 } else {
1629 return 1;
1630 }
1631 }
1632
AUX_W(int aux_cmd,int aux_addr,int * aux_w_data,uchar * length,uchar * status)1633 uchar AUX_W(int aux_cmd, int aux_addr, int *aux_w_data, uchar *length, uchar *status)
1634 {
1635 int wdata = 0, temp = 0;
1636 uchar len = *length;
1637
1638 /* Check valid length */
1639 if (len >= 1)
1640 len -= 1;
1641 else
1642 return 1;
1643
1644 /* Prepare AUX write address and data */
1645 wdata = (int)((len << 24) | aux_addr);
1646 writel(wdata, DP_AUX_ADDR_LEN);
1647
1648 writel(*aux_w_data, DP_AUX_W_D_0);
1649
1650 if ((*length) > 0x4) {
1651 aux_w_data++;
1652 writel(*aux_w_data, DP_AUX_W_D_4);
1653 }
1654
1655 if ((*length) > 0x8) {
1656 aux_w_data++;
1657 writel(*aux_w_data, DP_AUX_W_D_8);
1658 }
1659
1660 if ((*length) > 0xC) {
1661 aux_w_data++;
1662 writel(*aux_w_data, DP_AUX_W_D_C);
1663 }
1664
1665 /* Fire AUX write */
1666 writel(aux_cmd, DP_AUX_REQ_CFG);
1667
1668 /* Wait AUX write finish or timeout */
1669 do {
1670 temp = (readl(DP_TX_INT_STATUS) & 0xC000);
1671 } while (!(temp & 0xC000));
1672
1673 /* Clear AUX write interrupt status */
1674 wdata = (readl(DP_TX_INT_CLEAR) | (temp >> 8));
1675 writel(wdata, DP_TX_INT_CLEAR);
1676
1677 if (temp & AUX_CMD_DONE) {
1678 (*status) = (uchar)(readl(DP_AUX_STATUS) & 0xFF);
1679 return 0;
1680 } else {
1681 return 1;
1682 }
1683 }
1684
1685 U_BOOT_CMD(dptest, 2, 0, do_ast_dptest, "ASPEED Display Port phy test", "ASPEED DP test v.0.2.9");
1686