]> Git Repo - linux.git/blobdiff - drivers/gpu/drm/display/drm_dp_mst_topology.c
Merge tag 'drm-intel-next-2024-08-13' of https://gitlab.freedesktop.org/drm/i915...
[linux.git] / drivers / gpu / drm / display / drm_dp_mst_topology.c
index fc2ceae61db2d0f6c31f6e6e1da35b2fce6a79db..379a449a28a26c76fa928c905a58a07c05fb8f4b 100644 (file)
@@ -2339,7 +2339,7 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb,
 {
        struct drm_dp_mst_topology_mgr *mgr = mstb->mgr;
        struct drm_dp_mst_port *port;
-       int old_ddps = 0, ret;
+       int ret;
        u8 new_pdt = DP_PEER_DEVICE_NONE;
        bool new_mcs = 0;
        bool created = false, send_link_addr = false, changed = false;
@@ -2372,7 +2372,6 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb,
                 */
                drm_modeset_lock(&mgr->base.lock, NULL);
 
-               old_ddps = port->ddps;
                changed = port->ddps != port_msg->ddps ||
                        (port->ddps &&
                         (port->ldps != port_msg->legacy_device_plug_status ||
@@ -2407,15 +2406,13 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb,
         * Reprobe PBN caps on both hotplug, and when re-probing the link
         * for our parent mstb
         */
-       if (old_ddps != port->ddps || !created) {
-               if (port->ddps && !port->input) {
-                       ret = drm_dp_send_enum_path_resources(mgr, mstb,
-                                                             port);
-                       if (ret == 1)
-                               changed = true;
-               } else {
-                       port->full_pbn = 0;
-               }
+       if (port->ddps && !port->input) {
+               ret = drm_dp_send_enum_path_resources(mgr, mstb,
+                                                     port);
+               if (ret == 1)
+                       changed = true;
+       } else {
+               port->full_pbn = 0;
        }
 
        ret = drm_dp_port_set_pdt(port, new_pdt, new_mcs);
@@ -2692,6 +2689,11 @@ static void drm_dp_mst_link_probe_work(struct work_struct *work)
                drm_kms_helper_hotplug_event(dev);
 }
 
+static void drm_dp_mst_queue_probe_work(struct drm_dp_mst_topology_mgr *mgr)
+{
+       queue_work(system_long_wq, &mgr->work);
+}
+
 static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr,
                                 u8 *guid)
 {
@@ -3685,7 +3687,7 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms
                /* Write reset payload */
                drm_dp_dpcd_write_payload(mgr, 0, 0, 0x3f);
 
-               queue_work(system_long_wq, &mgr->work);
+               drm_dp_mst_queue_probe_work(mgr);
 
                ret = 0;
        } else {
@@ -3723,6 +3725,33 @@ drm_dp_mst_topology_mgr_invalidate_mstb(struct drm_dp_mst_branch *mstb)
                        drm_dp_mst_topology_mgr_invalidate_mstb(port->mstb);
 }
 
+/**
+ * drm_dp_mst_topology_queue_probe - Queue a topology probe
+ * @mgr: manager to probe
+ *
+ * Queue a work to probe the MST topology. Driver's should call this only to
+ * sync the topology's HW->SW state after the MST link's parameters have
+ * changed in a way the state could've become out-of-sync. This is the case
+ * for instance when the link rate between the source and first downstream
+ * branch device has switched between UHBR and non-UHBR rates. Except of those
+ * cases - for instance when a sink gets plugged/unplugged to a port - the SW
+ * state will get updated automatically via MST UP message notifications.
+ */
+void drm_dp_mst_topology_queue_probe(struct drm_dp_mst_topology_mgr *mgr)
+{
+       mutex_lock(&mgr->lock);
+
+       if (drm_WARN_ON(mgr->dev, !mgr->mst_state || !mgr->mst_primary))
+               goto out_unlock;
+
+       drm_dp_mst_topology_mgr_invalidate_mstb(mgr->mst_primary);
+       drm_dp_mst_queue_probe_work(mgr);
+
+out_unlock:
+       mutex_unlock(&mgr->lock);
+}
+EXPORT_SYMBOL(drm_dp_mst_topology_queue_probe);
+
 /**
  * drm_dp_mst_topology_mgr_suspend() - suspend the MST manager
  * @mgr: manager to suspend
@@ -3809,7 +3838,7 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr,
         * state of our in-memory topology back into sync with reality. So,
         * restart the probing process as if we're probing a new hub
         */
-       queue_work(system_long_wq, &mgr->work);
+       drm_dp_mst_queue_probe_work(mgr);
        mutex_unlock(&mgr->lock);
 
        if (sync) {
@@ -4963,7 +4992,7 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
                seq_printf(m, "branch oui: %*phN devid: ", 3, buf);
 
                for (i = 0x3; i < 0x8 && buf[i]; i++)
-                       seq_printf(m, "%c", buf[i]);
+                       seq_putc(m, buf[i]);
                seq_printf(m, " revision: hw: %x.%x sw: %x.%x\n",
                           buf[0x9] >> 4, buf[0x9] & 0xf, buf[0xa], buf[0xb]);
                if (dump_dp_payload_table(mgr, buf))
This page took 0.039758 seconds and 4 git commands to generate.