@@ -117,6 +117,13 @@ static void dpcd_set_link_settings(
117
117
core_link_write_dpcd (link , DP_DOWNSPREAD_CTRL ,
118
118
& downspread .raw , sizeof (downspread ));
119
119
120
+ if (link -> dpcd_caps .dpcd_rev .raw >= DPCD_REV_14 &&
121
+ (link -> dpcd_caps .link_rate_set >= 1 &&
122
+ link -> dpcd_caps .link_rate_set <= 8 )) {
123
+ core_link_write_dpcd (link , DP_LINK_RATE_SET ,
124
+ & link -> dpcd_caps .link_rate_set , 1 );
125
+ }
126
+
120
127
DC_LOG_HW_LINK_TRAINING ("%s\n %x rate = %x\n %x lane = %x\n %x spread = %x\n" ,
121
128
__func__ ,
122
129
DP_LINK_BW_SET ,
@@ -2489,13 +2496,105 @@ bool detect_dp_sink_caps(struct dc_link *link)
2489
2496
/* TODO save sink caps in link->sink */
2490
2497
}
2491
2498
2499
+ enum dc_link_rate linkRateInKHzToLinkRateMultiplier (uint32_t link_rate_in_khz )
2500
+ {
2501
+ enum dc_link_rate link_rate ;
2502
+ // LinkRate is normally stored as a multiplier of 0.27 Gbps per lane. Do the translation.
2503
+ switch (link_rate_in_khz ) {
2504
+ case 1620000 :
2505
+ link_rate = LINK_RATE_LOW ; // Rate_1 (RBR) - 1.62 Gbps/Lane
2506
+ break ;
2507
+ case 2160000 :
2508
+ link_rate = LINK_RATE_RATE_2 ; // Rate_2 - 2.16 Gbps/Lane
2509
+ break ;
2510
+ case 2430000 :
2511
+ link_rate = LINK_RATE_RATE_3 ; // Rate_3 - 2.43 Gbps/Lane
2512
+ break ;
2513
+ case 2700000 :
2514
+ link_rate = LINK_RATE_HIGH ; // Rate_4 (HBR) - 2.70 Gbps/Lane
2515
+ break ;
2516
+ case 3240000 :
2517
+ link_rate = LINK_RATE_RBR2 ; // Rate_5 (RBR2) - 3.24 Gbps/Lane
2518
+ break ;
2519
+ case 4320000 :
2520
+ link_rate = LINK_RATE_RATE_6 ; // Rate_6 - 4.32 Gbps/Lane
2521
+ break ;
2522
+ case 5400000 :
2523
+ link_rate = LINK_RATE_HIGH2 ; // Rate_7 (HBR2) - 5.40 Gbps/Lane
2524
+ break ;
2525
+ case 8100000 :
2526
+ link_rate = LINK_RATE_HIGH3 ; // Rate_8 (HBR3) - 8.10 Gbps/Lane
2527
+ break ;
2528
+ default :
2529
+ link_rate = LINK_RATE_UNKNOWN ;
2530
+ break ;
2531
+ }
2532
+ return link_rate ;
2533
+ }
2534
+
2492
2535
void detect_edp_sink_caps (struct dc_link * link )
2493
2536
{
2494
- retrieve_link_cap (link );
2537
+ uint8_t supported_link_rates [16 ] = {0 };
2538
+ uint32_t entry ;
2539
+ uint32_t link_rate_in_khz ;
2540
+ enum dc_link_rate link_rate = LINK_RATE_UNKNOWN ;
2541
+ uint8_t link_rate_set = 0 ;
2495
2542
2496
- if (link -> reported_link_cap .link_rate == LINK_RATE_UNKNOWN )
2497
- link -> reported_link_cap .link_rate = LINK_RATE_HIGH2 ;
2543
+ retrieve_link_cap (link );
2498
2544
2545
+ if (link -> dpcd_caps .dpcd_rev .raw >= DPCD_REV_14 ) {
2546
+ // Read DPCD 00010h - 0001Fh 16 bytes at one shot
2547
+ core_link_read_dpcd (link , DP_SUPPORTED_LINK_RATES ,
2548
+ supported_link_rates , sizeof (supported_link_rates ));
2549
+
2550
+ link -> dpcd_caps .link_rate_set = 0 ;
2551
+ for (entry = 0 ; entry < 16 ; entry += 2 ) {
2552
+ // DPCD register reports per-lane link rate = 16-bit link rate capability
2553
+ // value X 200 kHz. Need multipler to find link rate in kHz.
2554
+ link_rate_in_khz = (supported_link_rates [entry + 1 ] * 0x100 +
2555
+ supported_link_rates [entry ]) * 200 ;
2556
+
2557
+ if (link_rate_in_khz != 0 ) {
2558
+ link_rate = linkRateInKHzToLinkRateMultiplier (link_rate_in_khz );
2559
+ if (link -> reported_link_cap .link_rate < link_rate ) {
2560
+ link -> reported_link_cap .link_rate = link_rate ;
2561
+
2562
+ switch (link_rate ) {
2563
+ case LINK_RATE_LOW :
2564
+ link_rate_set = 1 ;
2565
+ break ;
2566
+ case LINK_RATE_RATE_2 :
2567
+ link_rate_set = 2 ;
2568
+ break ;
2569
+ case LINK_RATE_RATE_3 :
2570
+ link_rate_set = 3 ;
2571
+ break ;
2572
+ case LINK_RATE_HIGH :
2573
+ link_rate_set = 4 ;
2574
+ break ;
2575
+ case LINK_RATE_RBR2 :
2576
+ link_rate_set = 5 ;
2577
+ break ;
2578
+ case LINK_RATE_RATE_6 :
2579
+ link_rate_set = 6 ;
2580
+ break ;
2581
+ case LINK_RATE_HIGH2 :
2582
+ link_rate_set = 7 ;
2583
+ break ;
2584
+ case LINK_RATE_HIGH3 :
2585
+ link_rate_set = 8 ;
2586
+ break ;
2587
+ default :
2588
+ link_rate_set = 0 ;
2589
+ break ;
2590
+ }
2591
+
2592
+ if (link -> dpcd_caps .link_rate_set < link_rate_set )
2593
+ link -> dpcd_caps .link_rate_set = link_rate_set ;
2594
+ }
2595
+ }
2596
+ }
2597
+ }
2499
2598
link -> verified_link_cap = link -> reported_link_cap ;
2500
2599
}
2501
2600
0 commit comments