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