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