drm/display/dp_mst: Add helper for finding payloads in atomic MST state
authorLyude Paul <lyude@redhat.com>
Wed, 17 Aug 2022 19:38:36 +0000 (15:38 -0400)
committerLyude Paul <lyude@redhat.com>
Tue, 23 Aug 2022 20:53:37 +0000 (16:53 -0400)
We already open-code this quite often, and will be iterating through
payloads even more once we've moved all of the payload tracking into the
atomic state. So, let's add a helper for doing this.

Signed-off-by: Lyude Paul <lyude@redhat.com>
Cc: Wayne Lin <Wayne.Lin@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Fangzhi Zuo <Jerry.Zuo@amd.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Sean Paul <sean@poorly.run>
Acked-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220817193847.557945-8-lyude@redhat.com
drivers/gpu/drm/display/drm_dp_mst_topology.c

index 8a2ddfde594ae62324fb21153c8be2baa5ce165c..1c054a5e2e779096b68f5fb3923f176a248199c1 100644 (file)
@@ -1738,6 +1738,19 @@ drm_dp_mst_dump_port_topology_history(struct drm_dp_mst_port *port) {}
 #define save_port_topology_ref(port, type)
 #endif
 
+static struct drm_dp_mst_atomic_payload *
+drm_atomic_get_mst_payload_state(struct drm_dp_mst_topology_state *state,
+                                struct drm_dp_mst_port *port)
+{
+       struct drm_dp_mst_atomic_payload *payload;
+
+       list_for_each_entry(payload, &state->payloads, next)
+               if (payload->port == port)
+                       return payload;
+
+       return NULL;
+}
+
 static void drm_dp_destroy_mst_branch_device(struct kref *kref)
 {
        struct drm_dp_mst_branch *mstb =
@@ -4370,39 +4383,31 @@ int drm_dp_atomic_find_time_slots(struct drm_atomic_state *state,
                                  int pbn_div)
 {
        struct drm_dp_mst_topology_state *topology_state;
-       struct drm_dp_mst_atomic_payload *pos, *payload = NULL;
-       int prev_slots, prev_bw, req_slots;
+       struct drm_dp_mst_atomic_payload *payload = NULL;
+       int prev_slots = 0, prev_bw = 0, req_slots;
 
        topology_state = drm_atomic_get_mst_topology_state(state, mgr);
        if (IS_ERR(topology_state))
                return PTR_ERR(topology_state);
 
        /* Find the current allocation for this port, if any */
-       list_for_each_entry(pos, &topology_state->payloads, next) {
-               if (pos->port == port) {
-                       payload = pos;
-                       prev_slots = payload->time_slots;
-                       prev_bw = payload->pbn;
-
-                       /*
-                        * This should never happen, unless the driver tries
-                        * releasing and allocating the same timeslot allocation,
-                        * which is an error
-                        */
-                       if (WARN_ON(!prev_slots)) {
-                               drm_err(mgr->dev,
-                                       "cannot allocate and release time slots on [MST PORT:%p] in the same state\n",
-                                       port);
-                               return -EINVAL;
-                       }
+       payload = drm_atomic_get_mst_payload_state(topology_state, port);
+       if (payload) {
+               prev_slots = payload->time_slots;
+               prev_bw = payload->pbn;
 
-                       break;
+               /*
+                * This should never happen, unless the driver tries
+                * releasing and allocating the same timeslot allocation,
+                * which is an error
+                */
+               if (WARN_ON(!prev_slots)) {
+                       drm_err(mgr->dev,
+                               "cannot allocate and release time slots on [MST PORT:%p] in the same state\n",
+                               port);
+                       return -EINVAL;
                }
        }
-       if (!payload) {
-               prev_slots = 0;
-               prev_bw = 0;
-       }
 
        if (pbn_div <= 0)
                pbn_div = mgr->pbn_div;
@@ -4463,30 +4468,24 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state,
                                     struct drm_dp_mst_port *port)
 {
        struct drm_dp_mst_topology_state *topology_state;
-       struct drm_dp_mst_atomic_payload *pos;
-       bool found = false;
+       struct drm_dp_mst_atomic_payload *payload;
 
        topology_state = drm_atomic_get_mst_topology_state(state, mgr);
        if (IS_ERR(topology_state))
                return PTR_ERR(topology_state);
 
-       list_for_each_entry(pos, &topology_state->payloads, next) {
-               if (pos->port == port) {
-                       found = true;
-                       break;
-               }
-       }
-       if (WARN_ON(!found)) {
+       payload = drm_atomic_get_mst_payload_state(topology_state, port);
+       if (WARN_ON(!payload)) {
                drm_err(mgr->dev, "No payload for [MST PORT:%p] found in mst state %p\n",
                        port, &topology_state->base);
                return -EINVAL;
        }
 
-       drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, pos->time_slots);
-       if (pos->time_slots) {
+       drm_dbg_atomic(mgr->dev, "[MST PORT:%p] TU %d -> 0\n", port, payload->time_slots);
+       if (payload->time_slots) {
                drm_dp_mst_put_port_malloc(port);
-               pos->time_slots = 0;
-               pos->pbn = 0;
+               payload->time_slots = 0;
+               payload->pbn = 0;
        }
 
        return 0;
@@ -5182,18 +5181,8 @@ drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port,
                return 0;
 
        if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) {
-               bool found = false;
-
-               list_for_each_entry(payload, &state->payloads, next) {
-                       if (payload->port != port)
-                               continue;
-                       if (!payload->pbn)
-                               return 0;
-
-                       found = true;
-                       break;
-               }
-               if (!found)
+               payload = drm_atomic_get_mst_payload_state(state, port);
+               if (!payload)
                        return 0;
 
                /*
@@ -5348,34 +5337,26 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state,
                                 bool enable)
 {
        struct drm_dp_mst_topology_state *mst_state;
-       struct drm_dp_mst_atomic_payload *pos;
-       bool found = false;
+       struct drm_dp_mst_atomic_payload *payload;
        int time_slots = 0;
 
        mst_state = drm_atomic_get_mst_topology_state(state, port->mgr);
-
        if (IS_ERR(mst_state))
                return PTR_ERR(mst_state);
 
-       list_for_each_entry(pos, &mst_state->payloads, next) {
-               if (pos->port == port) {
-                       found = true;
-                       break;
-               }
-       }
-
-       if (!found) {
+       payload = drm_atomic_get_mst_payload_state(mst_state, port);
+       if (!payload) {
                drm_dbg_atomic(state->dev,
                               "[MST PORT:%p] Couldn't find payload in mst state %p\n",
                               port, mst_state);
                return -EINVAL;
        }
 
-       if (pos->dsc_enabled == enable) {
+       if (payload->dsc_enabled == enable) {
                drm_dbg_atomic(state->dev,
                               "[MST PORT:%p] DSC flag is already set to %d, returning %d time slots\n",
-                              port, enable, pos->time_slots);
-               time_slots = pos->time_slots;
+                              port, enable, payload->time_slots);
+               time_slots = payload->time_slots;
        }
 
        if (enable) {
@@ -5387,7 +5368,7 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state,
                        return -EINVAL;
        }
 
-       pos->dsc_enabled = enable;
+       payload->dsc_enabled = enable;
 
        return time_slots;
 }