drm_dp_atomic_find_vcpi_slots() should be called from ->atomic_check() to
check there are sufficient vcpi slots for a mode and to add that to the
state. This should be followed by a call to drm_dp_mst_allocate_vcpi()
in ->atomic_commit() to initialize a struct vcpi for the port.

drm_dp_atomic_release_vcpi_slots() should be called from
->atomic_check() to release a port's vcpi slot allocation from the
state.

Drivers that do not make use of this atomic helper are expected to call
drm_dp_find_vcpi_slots() instead before calling
drm_dp_mst_allocate_vcpi().

v2:
Added checks for verifying the port reference is valid
Moved get_mst_topology_state() into the helpers (Daniel)
Changed find_vcpi_slots() to not depend on current allocation

Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 75 +++++++++++++++++++++++++++++++++++
 include/drm/drm_dp_mst_helper.h       |  6 +++
 2 files changed, 81 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index a891c36..93de257 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -2498,6 +2498,81 @@ static int drm_dp_init_vcpi(struct 
drm_dp_mst_topology_mgr *mgr,
 }
 
 /**
+ * drm_dp_atomic_find_vcpi_slots() - Find and add vcpi slots to the state
+ * @state: global atomic state
+ * @mgr: MST topology manager for the port
+ * @port: port to find vcpi slots for
+ * @pbn: bandwidth required for the mode in PBN
+ *
+ * RETURNS:
+ * Total slots in the atomic state assigned for this port or error
+ */
+int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state,
+                                 struct drm_dp_mst_topology_mgr *mgr,
+                                 struct drm_dp_mst_port *port, int pbn)
+{
+       struct drm_dp_mst_topology_state *topology_state;
+       int req_slots;
+
+       topology_state = drm_atomic_get_mst_topology_state(state, mgr);
+       if (topology_state == NULL)
+               return -ENOMEM;
+
+       port = drm_dp_get_validated_port_ref(mgr, port);
+       if (port == NULL)
+               return -EINVAL;
+       req_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
+       DRM_DEBUG_KMS("vcpi slots req=%d, avail=%d\n",
+                       req_slots, topology_state->avail_slots);
+
+       if (req_slots > topology_state->avail_slots) {
+               drm_dp_put_port(port);
+               return -ENOSPC;
+       }
+
+       topology_state->avail_slots -= req_slots;
+       DRM_DEBUG_KMS("vcpi slots avail=%d", topology_state->avail_slots);
+
+       drm_dp_put_port(port);
+       return req_slots;
+}
+EXPORT_SYMBOL(drm_dp_atomic_find_vcpi_slots);
+
+/**
+ * drm_dp_atomic_release_vcpi_slots() - Release allocated vcpi slots
+ * @state: global atomic state
+ * @mgr: MST topology manager for the port
+ * @port: port to release the vcpi slots for
+ *
+ * RETURNS:
+ * Number of slots released from the atomic state for this port
+ */
+int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
+                                    struct drm_dp_mst_topology_mgr *mgr,
+                                    struct drm_dp_mst_port *port)
+{
+       struct drm_dp_mst_topology_state *topology_state;
+       int curr_slots;
+
+       topology_state = drm_atomic_get_mst_topology_state(state, mgr);
+       if (topology_state == NULL)
+               return -ENOMEM;
+
+       port = drm_dp_get_validated_port_ref(mgr, port);
+       if (port == NULL)
+               return -EINVAL;
+
+       curr_slots = port->vcpi.num_slots;
+       topology_state->avail_slots += curr_slots;
+       DRM_DEBUG_KMS("vcpi slots released=%d, avail=%d\n",
+                       curr_slots, topology_state->avail_slots);
+
+       drm_dp_put_port(port);
+       return curr_slots;
+}
+EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
+
+/**
  * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
  * @mgr: manager for this port
  * @port: port to allocate a virtual channel for.
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index 0b371df..64e7dac 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -615,5 +615,11 @@ void drm_dp_mst_topology_mgr_suspend(struct 
drm_dp_mst_topology_mgr *mgr);
 int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr);
 struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct 
drm_atomic_state *state,
                                                                    struct 
drm_dp_mst_topology_mgr *mgr);
+int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state,
+                                 struct drm_dp_mst_topology_mgr *mgr,
+                                 struct drm_dp_mst_port *port, int pbn);
+int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
+                                    struct drm_dp_mst_topology_mgr *mgr,
+                                    struct drm_dp_mst_port *port);
 
 #endif
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to