drm/amd/display: Handle branch device with DFP count = 0 case.
authorHugo Hu <hugo.hu@amd.com>
Mon, 25 Feb 2019 11:16:52 +0000 (19:16 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 28 Mar 2019 03:41:32 +0000 (22:41 -0500)
[Why]
When you have a SST branch device the driver, Even no sink device connected,
it also send HPD with a valid EDID. Driver will config it to DP sink.
Therefore, there're two displays in display setting.

DPCD 0x05, DFP_PRESENT = 1 (branch device),
DFP_TYPE = 00 (Display Port)

[How]
Driver determine DPCD 0x05 DFP_PRESENT = 1(branch) as an active dongle
And check DFP count.

Signed-off-by: Hugo Hu <hugo.hu@amd.com>
Reviewed-by: Hugo Hu <Hugo.Hu@amd.com>
Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@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.h

index 5575d1adb9b581f002be9a2c36f458af50528536..ac128f7a9d854e7032941ec8023099932450d3f9 100644 (file)
@@ -720,9 +720,8 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
                                        same_dpcd = false;
                        }
                        /* 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 (link->type == dc_connection_active_dongle &&
+                               link->dpcd_caps.sink_count.bits.SINK_COUNT == 0) {
                                if (prev_sink != NULL) {
                                        /* Downstream unplug */
                                        dc_sink_release(prev_sink);
index 72a88b1808fecea99b82e88ed111e4bdeeeb3125..063d019a3f6f0440b12a0081d0be0c8c64e3b35c 100644 (file)
@@ -2226,11 +2226,7 @@ bool is_mst_supported(struct dc_link *link)
 
 bool is_dp_active_dongle(const struct dc_link *link)
 {
-       enum display_dongle_type dongle_type = link->dpcd_caps.dongle_type;
-
-       return (dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER) ||
-                       (dongle_type == DISPLAY_DONGLE_DP_DVI_CONVERTER) ||
-                       (dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER);
+       return link->dpcd_caps.is_branch_dev;
 }
 
 static int translate_dpcd_max_bpc(enum dpcd_downstream_port_max_bpc bpc)
@@ -2264,6 +2260,9 @@ static void get_active_converter_info(
                return;
        }
 
+       /* DPCD 0x5 bit 0 = 1, it indicate it's branch device */
+       link->dpcd_caps.is_branch_dev = ds_port.fields.PORT_PRESENT;
+
        switch (ds_port.fields.PORT_TYPE) {
        case DOWNSTREAM_VGA:
                link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_VGA_CONVERTER;
index c37a0ede132ec069dacefbc619cc4f67168cc02b..cfcb35f8f7d3f3e8fab40d325b0bcb366883c7d2 100644 (file)
@@ -689,6 +689,8 @@ struct dpcd_caps {
 
        /* dongle type (DP converter, CV smart dongle) */
        enum display_dongle_type dongle_type;
+       /* branch device or sink device */
+       bool is_branch_dev;
        /* Dongle's downstream count. */
        union sink_count sink_count;
        /* If dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER,