drm/amd/display: Allow UHBR Interop With eDP Supported Link Rates Table
authorMichael Strauss <michael.strauss@amd.com>
Thu, 15 Aug 2024 22:45:17 +0000 (18:45 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 21 Aug 2024 02:14:13 +0000 (22:14 -0400)
[WHY]
eDP 2.0 is introducing support for UHBR link rates, however current eDP ILR
link optimization does not account for UHBR capabilities.
Either UHBR capabilities will be provided via the same 128b/132b rate DPCD caps
that are currently used on DP2.1, or Table 4-13 may be updated to include UHBR
rates.

[HOW]
Add extra Supported Link Rates table translations for UHBR10/13.5/20.
Update eDP link setting optimization search to be aware of 128b/132b DPCD
rate caps in order to unblock UHBR on panels with Supported Link Rates table.

Reviewed-by: Wenjing Liu <wenjing.liu@amd.com>
Signed-off-by: Michael Strauss <michael.strauss@amd.com>
Signed-off-by: Roman Li <roman.li@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/link/link_detection.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h

index 391dbe81534da7b1ce707a5cef33dff82bd41fea..d21ee9d12d269b51fc9fc26a4dc36fa94a89fd04 100644 (file)
@@ -1189,8 +1189,7 @@ static bool detect_link_and_local_sink(struct dc_link *link,
                        //sink only can use supported link rate table, we are foreced to enable it
                        if (link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN)
                                link->panel_config.ilr.optimize_edp_link_rate = true;
-                       if (edp_is_ilr_optimization_enabled(link))
-                               link->reported_link_cap.link_rate = get_max_link_rate_from_ilr_table(link);
+                       link->reported_link_cap.link_rate = get_max_edp_link_rate(link);
                }
 
        } else {
index 59c9dde10885007a856aa78ab3bccf754078c36f..34a618a7278b0af014ef300b0a30d28f7318f2aa 100644 (file)
@@ -212,6 +212,13 @@ static enum dc_link_rate linkRateInKHzToLinkRateMultiplier(uint32_t link_rate_in
        case 10000000:
                link_rate = LINK_RATE_UHBR10;   // UHBR10 - 10.0 Gbps/Lane
                break;
+       case 13500000:
+               link_rate = LINK_RATE_UHBR13_5; // UHBR13.5 - 13.5 Gbps/Lane
+               break;
+       case 20000000:
+               link_rate = LINK_RATE_UHBR20;   // UHBR20 - 20.0 Gbps/Lane
+               break;
+
        default:
                link_rate = LINK_RATE_UNKNOWN;
                break;
@@ -541,6 +548,23 @@ static enum dc_link_rate increase_link_rate(struct dc_link *link,
        }
 }
 
+static void increase_edp_link_rate(struct dc_link *link,
+               struct dc_link_settings *current_link_setting)
+{
+       if (current_link_setting->use_link_rate_set) {
+               if (current_link_setting->link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
+                       current_link_setting->link_rate_set++;
+                       current_link_setting->link_rate =
+                               link->dpcd_caps.edp_supported_link_rates[current_link_setting->link_rate_set];
+               } else {
+                       current_link_setting->use_link_rate_set = false;
+                       current_link_setting->link_rate = LINK_RATE_UHBR10;
+               }
+       } else {
+               current_link_setting->link_rate = increase_link_rate(link, current_link_setting->link_rate);
+       }
+}
+
 static bool decide_fallback_link_setting_max_bw_policy(
                struct dc_link *link,
                const struct dc_link_settings *max,
@@ -759,14 +783,7 @@ bool edp_decide_link_settings(struct dc_link *link,
                                        increase_lane_count(
                                                        current_link_setting.lane_count);
                } else {
-                       if (current_link_setting.link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
-                               current_link_setting.link_rate_set++;
-                               current_link_setting.link_rate =
-                                       link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
-                               current_link_setting.lane_count =
-                                                                       initial_link_setting.lane_count;
-                       } else
-                               break;
+                       increase_edp_link_rate(link, &current_link_setting);
                }
        }
        return false;
@@ -818,9 +835,7 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link,
                        if (policy) {
                                /* minimize lane */
                                if (current_link_setting.link_rate < max_link_rate) {
-                                       current_link_setting.link_rate =
-                                                       increase_link_rate(link,
-                                                                       current_link_setting.link_rate);
+                                       increase_edp_link_rate(link, &current_link_setting);
                                } else {
                                        if (current_link_setting.lane_count <
                                                                        link->verified_link_cap.lane_count) {
@@ -839,9 +854,7 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link,
                                                        increase_lane_count(
                                                                        current_link_setting.lane_count);
                                } else {
-                                       current_link_setting.link_rate =
-                                                       increase_link_rate(link,
-                                                                       current_link_setting.link_rate);
+                                       increase_edp_link_rate(link, &current_link_setting);
                                        current_link_setting.lane_count =
                                                        initial_link_setting.lane_count;
                                }
@@ -874,18 +887,15 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link,
                }
                if (policy) {
                        /* minimize lane */
-                       if (current_link_setting.link_rate_set <
-                                       link->dpcd_caps.edp_supported_link_rates_count
-                                       && current_link_setting.link_rate < max_link_rate) {
-                               current_link_setting.link_rate_set++;
-                               current_link_setting.link_rate =
-                                       link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
+                       if (current_link_setting.link_rate < max_link_rate) {
+                               increase_edp_link_rate(link, &current_link_setting);
                        } else {
                                if (current_link_setting.lane_count < link->verified_link_cap.lane_count) {
                                        current_link_setting.lane_count =
                                                        increase_lane_count(
                                                                        current_link_setting.lane_count);
                                        current_link_setting.link_rate_set = initial_link_setting.link_rate_set;
+                                       current_link_setting.use_link_rate_set = initial_link_setting.use_link_rate_set;
                                        current_link_setting.link_rate =
                                                link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
                                } else
@@ -899,13 +909,8 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link,
                                                increase_lane_count(
                                                                current_link_setting.lane_count);
                        } else {
-                               if (current_link_setting.link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
-                                       current_link_setting.link_rate_set++;
-                                       current_link_setting.link_rate =
-                                               link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
-                                       current_link_setting.lane_count =
-                                               initial_link_setting.lane_count;
-                               } else
+                               increase_edp_link_rate(link, &current_link_setting);
+                               if (current_link_setting.link_rate == LINK_RATE_UNKNOWN)
                                        break;
                        }
                }
index bf820d2b4dc4ad3838ea671158627a353af05d83..070b6c8c1aef93a4f86264d0433891382f6c27b2 100644 (file)
@@ -305,16 +305,17 @@ bool edp_is_ilr_optimization_enabled(struct dc_link *link)
        return true;
 }
 
-enum dc_link_rate get_max_link_rate_from_ilr_table(struct dc_link *link)
+enum dc_link_rate get_max_edp_link_rate(struct dc_link *link)
 {
-       enum dc_link_rate link_rate = link->reported_link_cap.link_rate;
+       enum dc_link_rate max_ilr_rate = LINK_RATE_UNKNOWN;
+       enum dc_link_rate max_non_ilr_rate = dp_get_max_link_cap(link).link_rate;
 
        for (int i = 0; i < link->dpcd_caps.edp_supported_link_rates_count; i++) {
-               if (link_rate < link->dpcd_caps.edp_supported_link_rates[i])
-                       link_rate = link->dpcd_caps.edp_supported_link_rates[i];
+               if (max_ilr_rate < link->dpcd_caps.edp_supported_link_rates[i])
+                       max_ilr_rate = link->dpcd_caps.edp_supported_link_rates[i];
        }
 
-       return link_rate;
+       return (max_ilr_rate > max_non_ilr_rate ? max_ilr_rate : max_non_ilr_rate);
 }
 
 bool edp_is_ilr_optimization_required(struct dc_link *link,
index 8df8ac5bde5b164bf5fc9ebdca05e770b92cfc8e..30dc8c24c008c4b9e15cb7b782e1bf452e2d443c 100644 (file)
@@ -69,7 +69,7 @@ bool edp_wait_for_t12(struct dc_link *link);
 bool edp_is_ilr_optimization_required(struct dc_link *link,
        struct dc_crtc_timing *crtc_timing);
 bool edp_is_ilr_optimization_enabled(struct dc_link *link);
-enum dc_link_rate get_max_link_rate_from_ilr_table(struct dc_link *link);
+enum dc_link_rate get_max_edp_link_rate(struct dc_link *link);
 bool edp_backlight_enable_aux(struct dc_link *link, bool enable);
 void edp_add_delay_for_T9(struct dc_link *link);
 bool edp_receiver_ready_T9(struct dc_link *link);