drm/amd/display: Reduce delay when sink device not able to ACK 00340h write
authorZhan Liu <zhan.liu@amd.com>
Tue, 29 Jun 2021 01:20:18 +0000 (21:20 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 23 Jul 2021 14:07:57 +0000 (10:07 -0400)
[Why]
Theoretically, per DP 1.4a spec, sink device needs to AUX_ACK 00340h
write. However, due to hardware limitation, some sink devices have no
00340h dpcd address at all. This results in sink side fails to reply
ACK, and consequently cause source side keep retrying DPCD write on DPCD
00340h. This results in significant delay when DPCD 00340h write is
triggered (e.g. at S3 resume).

[How]
Check whether sink device could ACK on DPCD 00340h write on boot. If
sink device fails to ACK, then remember that, so we won't write to DPCD
00340h later on.

There will be a drm.debug KMS level message to inform user once a 00340h
DPCD write is skipped on purpose.

Reviewed-by: Nikola Cornij <Nikola.Cornij@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Zhan Liu <zhan.liu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/dc_dp_types.h

index 655b48c..f68a0d9 100644 (file)
@@ -1665,6 +1665,12 @@ struct dc_link *link_create(const struct link_init_data *init_params)
        if (false == dc_link_construct(link, init_params))
                goto construct_fail;
 
+       /*
+        * Must use preferred_link_setting, not reported_link_cap or verified_link_cap,
+        * since struct preferred_link_setting won't be reset after S3.
+        */
+       link->preferred_link_setting.dpcd_source_device_specific_field_support = true;
+
        return link;
 
 construct_fail:
index 335018f..fba38d8 100644 (file)
@@ -4784,10 +4784,18 @@ void dpcd_set_source_specific_data(struct dc_link *link)
 
                        uint8_t hblank_size = (uint8_t)link->dc->caps.min_horizontal_blanking_period;
 
-                       result_write_min_hblank = core_link_write_dpcd(link,
-                               DP_SOURCE_MINIMUM_HBLANK_SUPPORTED, (uint8_t *)(&hblank_size),
-                               sizeof(hblank_size));
+                       if (link->preferred_link_setting.dpcd_source_device_specific_field_support) {
+                               result_write_min_hblank = core_link_write_dpcd(link,
+                                       DP_SOURCE_MINIMUM_HBLANK_SUPPORTED, (uint8_t *)(&hblank_size),
+                                       sizeof(hblank_size));
+
+                               if (result_write_min_hblank == DC_ERROR_UNEXPECTED)
+                                       link->preferred_link_setting.dpcd_source_device_specific_field_support = false;
+                       } else {
+                               DC_LOG_DC("Sink device does not support 00340h DPCD write. Skipping on purpose.\n");
+                       }
                }
+
                DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION,
                                                        WPP_BIT_FLAG_DC_DETECTION_DP_CAPS,
                                                        "result=%u link_index=%u enum dce_version=%d DPCD=0x%04X min_hblank=%u branch_dev_id=0x%x branch_dev_name='%c%c%c%c%c%c'",
index 1948cd9..4f54bde 100644 (file)
@@ -109,6 +109,7 @@ struct dc_link_settings {
        enum dc_link_spread link_spread;
        bool use_link_rate_set;
        uint8_t link_rate_set;
+       bool dpcd_source_device_specific_field_support;
 };
 
 struct dc_lane_settings {