diff options
author | Pandiyan, Dhinakaran <dhinakaran.pandiyan@intel.com> | 2017-04-21 01:51:32 -0400 |
---|---|---|
committer | Maarten Lankhorst <maarten.lankhorst@linux.intel.com> | 2017-05-04 09:02:47 -0400 |
commit | edb1ed1ab7d314e114de84003f763da34c0f34c0 (patch) | |
tree | 3a86ea1787e96060dc245bcd805c5593318ffdde /drivers/gpu/drm/drm_dp_mst_topology.c | |
parent | 3f3353b7e1218d208507bc52688cacb4ff893c28 (diff) |
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
Diffstat (limited to 'drivers/gpu/drm/drm_dp_mst_topology.c')
-rw-r--r-- | drivers/gpu/drm/drm_dp_mst_topology.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 0ad0baae5c7e..d1cbb9c8f806 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, | |||
2498 | } | 2498 | } |
2499 | 2499 | ||
2500 | /** | 2500 | /** |
2501 | * drm_dp_atomic_find_vcpi_slots() - Find and add vcpi slots to the state | ||
2502 | * @state: global atomic state | ||
2503 | * @mgr: MST topology manager for the port | ||
2504 | * @port: port to find vcpi slots for | ||
2505 | * @pbn: bandwidth required for the mode in PBN | ||
2506 | * | ||
2507 | * RETURNS: | ||
2508 | * Total slots in the atomic state assigned for this port or error | ||
2509 | */ | ||
2510 | int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, | ||
2511 | struct drm_dp_mst_topology_mgr *mgr, | ||
2512 | struct drm_dp_mst_port *port, int pbn) | ||
2513 | { | ||
2514 | struct drm_dp_mst_topology_state *topology_state; | ||
2515 | int req_slots; | ||
2516 | |||
2517 | topology_state = drm_atomic_get_mst_topology_state(state, mgr); | ||
2518 | if (topology_state == NULL) | ||
2519 | return -ENOMEM; | ||
2520 | |||
2521 | port = drm_dp_get_validated_port_ref(mgr, port); | ||
2522 | if (port == NULL) | ||
2523 | return -EINVAL; | ||
2524 | req_slots = DIV_ROUND_UP(pbn, mgr->pbn_div); | ||
2525 | DRM_DEBUG_KMS("vcpi slots req=%d, avail=%d\n", | ||
2526 | req_slots, topology_state->avail_slots); | ||
2527 | |||
2528 | if (req_slots > topology_state->avail_slots) { | ||
2529 | drm_dp_put_port(port); | ||
2530 | return -ENOSPC; | ||
2531 | } | ||
2532 | |||
2533 | topology_state->avail_slots -= req_slots; | ||
2534 | DRM_DEBUG_KMS("vcpi slots avail=%d", topology_state->avail_slots); | ||
2535 | |||
2536 | drm_dp_put_port(port); | ||
2537 | return req_slots; | ||
2538 | } | ||
2539 | EXPORT_SYMBOL(drm_dp_atomic_find_vcpi_slots); | ||
2540 | |||
2541 | /** | ||
2542 | * drm_dp_atomic_release_vcpi_slots() - Release allocated vcpi slots | ||
2543 | * @state: global atomic state | ||
2544 | * @mgr: MST topology manager for the port | ||
2545 | * @slots: number of vcpi slots to release | ||
2546 | * | ||
2547 | * RETURNS: | ||
2548 | * 0 if @slots were added back to &drm_dp_mst_topology_state->avail_slots or | ||
2549 | * negative error code | ||
2550 | */ | ||
2551 | int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, | ||
2552 | struct drm_dp_mst_topology_mgr *mgr, | ||
2553 | int slots) | ||
2554 | { | ||
2555 | struct drm_dp_mst_topology_state *topology_state; | ||
2556 | |||
2557 | topology_state = drm_atomic_get_mst_topology_state(state, mgr); | ||
2558 | if (topology_state == NULL) | ||
2559 | return -ENOMEM; | ||
2560 | |||
2561 | /* We cannot rely on port->vcpi.num_slots to update | ||
2562 | * topology_state->avail_slots as the port may not exist if the parent | ||
2563 | * branch device was unplugged. This should be fixed by tracking | ||
2564 | * per-port slot allocation in drm_dp_mst_topology_state instead of | ||
2565 | * depending on the caller to tell us how many slots to release. | ||
2566 | */ | ||
2567 | topology_state->avail_slots += slots; | ||
2568 | DRM_DEBUG_KMS("vcpi slots released=%d, avail=%d\n", | ||
2569 | slots, topology_state->avail_slots); | ||
2570 | |||
2571 | return 0; | ||
2572 | } | ||
2573 | EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots); | ||
2574 | |||
2575 | /** | ||
2501 | * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel | 2576 | * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel |
2502 | * @mgr: manager for this port | 2577 | * @mgr: manager for this port |
2503 | * @port: port to allocate a virtual channel for. | 2578 | * @port: port to allocate a virtual channel for. |