forked from mirrors/linux
		
	drm/dp: Add DP MST helpers to atomically find and release vcpi slots
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().
v3: drm_dp_atomic_release_vcpi_slots() now needs to know how many slots
    to release as we may not have a valid reference to port.
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
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Archit Taneja <architt@codeaurora.org>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Harry Wentland <Harry.wentland@amd.com>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1492753893-3748-4-git-send-email-dhinakaran.pandiyan@intel.com
			
			
This commit is contained in:
		
							parent
							
								
									3f3353b7e1
								
							
						
					
					
						commit
						edb1ed1ab7
					
				
					 2 changed files with 81 additions and 0 deletions
				
			
		| 
						 | 
					@ -2497,6 +2497,81 @@ static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 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
 | 
				
			||||||
 | 
					 * @slots: number of vcpi slots to release
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * RETURNS:
 | 
				
			||||||
 | 
					 * 0 if @slots were added back to &drm_dp_mst_topology_state->avail_slots or
 | 
				
			||||||
 | 
					 * negative error code
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
 | 
				
			||||||
 | 
									     struct drm_dp_mst_topology_mgr *mgr,
 | 
				
			||||||
 | 
									     int slots)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct drm_dp_mst_topology_state *topology_state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						topology_state = drm_atomic_get_mst_topology_state(state, mgr);
 | 
				
			||||||
 | 
						if (topology_state == NULL)
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* We cannot rely on port->vcpi.num_slots to update
 | 
				
			||||||
 | 
						 * topology_state->avail_slots as the port may not exist if the parent
 | 
				
			||||||
 | 
						 * branch device was unplugged. This should be fixed by tracking
 | 
				
			||||||
 | 
						 * per-port slot allocation in drm_dp_mst_topology_state instead of
 | 
				
			||||||
 | 
						 * depending on the caller to tell us how many slots to release.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						topology_state->avail_slots += slots;
 | 
				
			||||||
 | 
						DRM_DEBUG_KMS("vcpi slots released=%d, avail=%d\n",
 | 
				
			||||||
 | 
								slots, topology_state->avail_slots);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
 | 
					 * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
 | 
				
			||||||
 * @mgr: manager for this port
 | 
					 * @mgr: manager for this port
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
					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_state *drm_atomic_get_mst_topology_state(struct drm_atomic_state *state,
 | 
				
			||||||
								    struct drm_dp_mst_topology_mgr *mgr);
 | 
													    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,
 | 
				
			||||||
 | 
									     int slots);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue