xref: /openbmc/u-boot/cmd/aspeed/dptest.c (revision 7ad6685b)
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