drm/amd/display: Don't skip link training for empty dongle
authorEric Yang <Eric.Yang2@amd.com>
Fri, 23 Nov 2018 10:55:20 +0000 (05:55 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 18 Dec 2018 23:25:12 +0000 (18:25 -0500)
[Why]
Skipping initial link training will result in no verified link cap for
mode enumeration. Some versions of the BIOS seem to have PHY programming
sequence issue as well if initial link training is skipped, resulting in
a softlock in BIOS command table.

[How]
Identify the empty dongle hotplug case, and still do initial link
training.

Signed-off-by: Eric Yang <Eric.Yang2@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc_link.c

index 564f140d4e60f3c5a287851f44098f5e9e2dedfe..9f551fc6862206a8507dc5af35669bc71e309208 100644 (file)
@@ -706,12 +706,26 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
                                if (memcmp(&link->dpcd_caps, &prev_dpcd_caps, sizeof(struct dpcd_caps)))
                                        same_dpcd = false;
                        }
-                       /* Active dongle downstream unplug */
+                       /* Active dongle plug in without display or downstream unplug*/
                        if (link->type == dc_connection_active_dongle
                                        && link->dpcd_caps.sink_count.
                                        bits.SINK_COUNT == 0) {
-                               if (prev_sink != NULL)
+                               if (prev_sink != NULL) {
+                                       /* Downstream unplug */
                                        dc_sink_release(prev_sink);
+                               } else {
+                                       /* Empty dongle plug in */
+                                       for (i = 0; i < LINK_TRAINING_MAX_VERIFY_RETRY; i++) {
+                                               int fail_count = 0;
+
+                                               dp_verify_link_cap(link,
+                                                                 &link->reported_link_cap,
+                                                                 &fail_count);
+
+                                               if (fail_count == 0)
+                                                       break;
+                                       }
+                               }
                                return true;
                        }