From: Mykola Lysenko <mykola.lyse...@amd.com>

    1. Get edid for all connected MST displays, not only on logical ports,
       in the same thread as MST topology detection is done:
         There are displays that have branches inside w/o logical ports.
         So in case another SST display connected downstream system can
         end-up in situation when 3 DOWN requests sent: two for
        ‘remote i2c read’ and one for ‘enum path resources’, making 
slots full.

    2. Call notification callback in one place in the end of topology 
discovery/update:
         This is done to reduce number of events sent to userspace in case 
complex
         topology discovery is going, adding multiple number of connectors;

    3. Remove notification callback call from short pulse interrupt processing 
function:
         This is done in order not to block interrupt processing function, in 
case any
         MST request will be made from it. Notification will be send from 
topology
         discovery/update work item.

    v2: This change also includes tile property set fix which caused regression
        in i915 driver.

Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
Signed-off-by: Mykola Lysenko <Mykola.Lysenko at amd.com>
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 36 +++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index 27fbd79..9971c46 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -1159,13 +1159,9 @@ static void drm_dp_add_port(struct drm_dp_mst_branch 
*mstb,
                        drm_dp_put_port(port);
                        goto out;
                }
-               if (port->port_num >= DP_MST_LOGICAL_PORT_0) {
-                       port->cached_edid = drm_get_edid(port->connector, 
&port->aux.ddc);
-                       drm_mode_connector_set_tile_property(port->connector);
-               }
+
                (*mstb->mgr->cbs->register_connector)(port->connector);
        }
-
 out:
        /* put reference to this port */
        drm_dp_put_port(port);
@@ -1190,8 +1186,8 @@ static void drm_dp_update_port(struct drm_dp_mst_branch 
*mstb,
        port->ddps = conn_stat->displayport_device_plug_status;

        if (old_ddps != port->ddps) {
+               dowork = true;
                if (port->ddps) {
-                       dowork = true;
                } else {
                        port->available_pbn = 0;
                }
@@ -1296,8 +1292,13 @@ static void drm_dp_check_and_send_link_address(struct 
drm_dp_mst_topology_mgr *m
                if (port->input)
                        continue;

-               if (!port->ddps)
+               if (!port->ddps) {
+                       if (port->cached_edid) {
+                               kfree(port->cached_edid);
+                               port->cached_edid = NULL;
+                       }
                        continue;
+               }

                if (!port->available_pbn)
                        drm_dp_send_enum_path_resources(mgr, mstb, port);
@@ -1308,6 +1309,13 @@ static void drm_dp_check_and_send_link_address(struct 
drm_dp_mst_topology_mgr *m
                                drm_dp_check_and_send_link_address(mgr, 
mstb_child);
                                drm_dp_put_mst_branch_device(mstb_child);
                        }
+               } else if (port->pdt == DP_PEER_DEVICE_SST_SINK ||
+                       port->pdt == DP_PEER_DEVICE_DP_LEGACY_CONV) {
+                       if (!port->cached_edid) {
+                               port->cached_edid =
+                                       drm_get_edid(port->connector, 
&port->aux.ddc);
+                               
drm_mode_connector_set_tile_property(port->connector);
+                       }
                }
        }
 }
@@ -1327,6 +1335,8 @@ static void drm_dp_mst_link_probe_work(struct work_struct 
*work)
                drm_dp_check_and_send_link_address(mgr, mstb);
                drm_dp_put_mst_branch_device(mstb);
        }
+
+       (*mgr->cbs->hotplug)(mgr);
 }

 static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr,
@@ -1586,7 +1596,6 @@ static void drm_dp_send_link_address(struct 
drm_dp_mst_topology_mgr *mgr,
                        for (i = 0; i < txmsg->reply.u.link_addr.nports; i++) {
                                drm_dp_add_port(mstb, mgr->dev, 
&txmsg->reply.u.link_addr.ports[i]);
                        }
-                       (*mgr->cbs->hotplug)(mgr);
                }
        } else {
                mstb->link_address_sent = false;
@@ -2283,8 +2292,6 @@ static int drm_dp_mst_handle_up_req(struct 
drm_dp_mst_topology_mgr *mgr)
                        drm_dp_update_port(mstb, &msg.u.conn_stat);

                        DRM_DEBUG_KMS("Got CSN: pn: %d ldps:%d ddps: %d mcs: %d 
ip: %d pdt: %d\n", msg.u.conn_stat.port_number, 
msg.u.conn_stat.legacy_device_plug_status, 
msg.u.conn_stat.displayport_device_plug_status, 
msg.u.conn_stat.message_capability_status, msg.u.conn_stat.input_port, 
msg.u.conn_stat.peer_device_type);
-                       (*mgr->cbs->hotplug)(mgr);
-
                } else if (msg.req_type == DP_RESOURCE_STATUS_NOTIFY) {
                        drm_dp_send_up_ack_reply(mgr, mgr->mst_primary, 
msg.req_type, seqno, false);
                        if (!mstb)
@@ -2371,10 +2378,6 @@ enum drm_connector_status drm_dp_mst_detect_port(struct 
drm_connector *connector

        case DP_PEER_DEVICE_SST_SINK:
                status = connector_status_connected;
-               /* for logical ports - cache the EDID */
-               if (port->port_num >= 8 && !port->cached_edid) {
-                       port->cached_edid = drm_get_edid(connector, 
&port->aux.ddc);
-               }
                break;
        case DP_PEER_DEVICE_DP_LEGACY_CONV:
                if (port->ldps)
@@ -2429,10 +2432,7 @@ struct edid *drm_dp_mst_get_edid(struct drm_connector 
*connector, struct drm_dp_

        if (port->cached_edid)
                edid = drm_edid_duplicate(port->cached_edid);
-       else {
-               edid = drm_get_edid(connector, &port->aux.ddc);
-               drm_mode_connector_set_tile_property(connector);
-       }
+
        port->has_audio = drm_detect_monitor_audio(edid);
        drm_dp_put_port(port);
        return edid;
-- 
1.9.1

Reply via email to