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