aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_dp_mst_topology.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-07-26 15:32:45 -0400
committerDave Airlie <airlied@redhat.com>2017-07-26 15:32:45 -0400
commit542aefb5a2da8f67b8fb74a24f60ecb3ec479a06 (patch)
tree98858f6e890b7ce3609126446c4100461841e17c /drivers/gpu/drm/drm_dp_mst_topology.c
parent2d62c799f8ffac4f7ffba6a4e7f148827dfc24c7 (diff)
parent8bb9777332e5e0f90c64448e48d2554b8bf76a62 (diff)
Merge tag 'drm-misc-next-2017-07-26' of git://anongit.freedesktop.org/git/drm-misc into drm-next
drm-misc-next-2017-07-18: Core Changes: - A couple fixes to only opening crc when needed (Maarten) - Change atomic helper swap_state to be interruptible (Maarten) - fb_helper: Support waiting for an output before setting up (Daniel) - Allow drivers supporting runtime_pm to use helper_commit_tail (Maxime) Driver Changes: - misc: Use %pOF to print device node names (Rob) - Miscellaneous fixes drm-misc-next-2017-07-18: UAPI Changes: - Fail commits which request an event without including a crtc (Andrey) Core Changes: - Add YCBCR 4:2:0 support (Shashank) - s/drm_atomic_replace_property_blob/drm_property_replace_blob/ (Peter) - Add proper base class for private objs instead of using void* (Ville) - Remove pending_read/write_domains from drm_gem_object (Chris) - Add async plane update support (ie: cursor) to atomic helpers (Gustavo) - Add old state to .enable and rename to .atomic_enable (Laurent) - Add drm_atomic_helper_wait_for_flip_done() (Boris) - Remove drm_driver->set_busid hook (Daniel) - Migrate vblank documentation into the source files (Daniel) - Add fb_helper->lock instead of abusing modeset lock (Thierry/Daniel) Driver Changes: - stm: Add STM32 DSI controller driver (Phillipe) - amdgpu: Numerous small/misc fixes - bridge: Add Synopsys Designware MIPI DSI host bridge driver (Phillipe) - tinydrm: Add support for Pervasive Displays RePaper displays (Noralf) - misc: Replace for_each_[obj]_in_state to prep for removal (Maarten) - misc: Use .atomic_disable for atomic drivers (Laurent) - vgem: Pin pages when mapped/exported (Chris) - dw_hdmi: Add support for Rockchip RK3399 (Mark) - atmel-hlcdc: Add 8-bit color look-up table format (Peter) - vc4: Send vblank event when disabling a crtc (Boris) - vc4: Use atomic helpers for fence waits (Eric) - misc: drop drm_vblank_cleanup cargo-cult (Daniel) Cc: Daniel Vetter <daniel.vetter@intel.com> Cc: Boris Brezillon <boris.brezillon@free-electrons.com> Cc: Eric Anholt <eric@anholt.net> Cc: Peter Rosin <peda@axentia.se> Cc: Mark Yao <mark.yao@rock-chips.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com> Cc: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Cc: Gustavo Padovan <gustavo.padovan@collabora.com> Cc: Thierry Reding <treding@nvidia.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Peter Rosin <peda@axentia.se> Cc: Shashank Sharma <shashank.sharma@intel.com> Cc: Philippe CORNU <philippe.cornu@st.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Rob Herring <robh@kernel.org> Cc: Maxime Ripard <maxime.ripard@free-electrons.com> * tag 'drm-misc-next-2017-07-26' of git://anongit.freedesktop.org/git/drm-misc: (171 commits) drm/hisilicon: fix build error without fbdev emulation drm/atomic: implement drm_atomic_helper_commit_tail for runtime_pm users drm: Improve kerneldoc for drm_modeset_lock drm/hisilicon: Remove custom FB helper deferred setup drm/exynos: Remove custom FB helper deferred setup drm/fb-helper: Support deferred setup dma-fence: Don't BUG_ON when not absolutely needed drm: Convert to using %pOF instead of full_name drm/syncobj: Fix kerneldoc drm/atomic: Allow drm_atomic_helper_swap_state to fail drm/atomic: Add __must_check to drm_atomic_helper_swap_state. drm/vc4: Handle drm_atomic_helper_swap_state failure drm/tilcdc: Handle drm_atomic_helper_swap_state failure drm/tegra: Handle drm_atomic_helper_swap_state failure drm/msm: Handle drm_atomic_helper_swap_state failure drm/mediatek: Handle drm_atomic_helper_swap_state failure drm/i915: Handle drm_atomic_helper_swap_state failure drm/atmel-hlcdc: Handle drm_atomic_helper_swap_state failure drm/nouveau: Handle drm_atomic_helper_swap_state failure drm/atomic: Change drm_atomic_helper_swap_state to return an error. ...
Diffstat (limited to 'drivers/gpu/drm/drm_dp_mst_topology.c')
-rw-r--r--drivers/gpu/drm/drm_dp_mst_topology.c89
1 files changed, 44 insertions, 45 deletions
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index bfd237c15e76..f7e292bf2baf 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -31,6 +31,8 @@
31#include <drm/drmP.h> 31#include <drm/drmP.h>
32 32
33#include <drm/drm_fixed.h> 33#include <drm/drm_fixed.h>
34#include <drm/drm_atomic.h>
35#include <drm/drm_atomic_helper.h>
34 36
35/** 37/**
36 * DOC: dp mst helper 38 * DOC: dp mst helper
@@ -1335,15 +1337,17 @@ static void drm_dp_mst_link_probe_work(struct work_struct *work)
1335static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr, 1337static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr,
1336 u8 *guid) 1338 u8 *guid)
1337{ 1339{
1338 static u8 zero_guid[16]; 1340 u64 salt;
1339 1341
1340 if (!memcmp(guid, zero_guid, 16)) { 1342 if (memchr_inv(guid, 0, 16))
1341 u64 salt = get_jiffies_64(); 1343 return true;
1342 memcpy(&guid[0], &salt, sizeof(u64)); 1344
1343 memcpy(&guid[8], &salt, sizeof(u64)); 1345 salt = get_jiffies_64();
1344 return false; 1346
1345 } 1347 memcpy(&guid[0], &salt, sizeof(u64));
1346 return true; 1348 memcpy(&guid[8], &salt, sizeof(u64));
1349
1350 return false;
1347} 1351}
1348 1352
1349#if 0 1353#if 0
@@ -2515,8 +2519,8 @@ int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state,
2515 int req_slots; 2519 int req_slots;
2516 2520
2517 topology_state = drm_atomic_get_mst_topology_state(state, mgr); 2521 topology_state = drm_atomic_get_mst_topology_state(state, mgr);
2518 if (topology_state == NULL) 2522 if (IS_ERR(topology_state))
2519 return -ENOMEM; 2523 return PTR_ERR(topology_state);
2520 2524
2521 port = drm_dp_get_validated_port_ref(mgr, port); 2525 port = drm_dp_get_validated_port_ref(mgr, port);
2522 if (port == NULL) 2526 if (port == NULL)
@@ -2555,8 +2559,8 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
2555 struct drm_dp_mst_topology_state *topology_state; 2559 struct drm_dp_mst_topology_state *topology_state;
2556 2560
2557 topology_state = drm_atomic_get_mst_topology_state(state, mgr); 2561 topology_state = drm_atomic_get_mst_topology_state(state, mgr);
2558 if (topology_state == NULL) 2562 if (IS_ERR(topology_state))
2559 return -ENOMEM; 2563 return PTR_ERR(topology_state);
2560 2564
2561 /* We cannot rely on port->vcpi.num_slots to update 2565 /* We cannot rely on port->vcpi.num_slots to update
2562 * topology_state->avail_slots as the port may not exist if the parent 2566 * topology_state->avail_slots as the port may not exist if the parent
@@ -2992,41 +2996,32 @@ static void drm_dp_destroy_connector_work(struct work_struct *work)
2992 (*mgr->cbs->hotplug)(mgr); 2996 (*mgr->cbs->hotplug)(mgr);
2993} 2997}
2994 2998
2995void *drm_dp_mst_duplicate_state(struct drm_atomic_state *state, void *obj) 2999static struct drm_private_state *
3000drm_dp_mst_duplicate_state(struct drm_private_obj *obj)
2996{ 3001{
2997 struct drm_dp_mst_topology_mgr *mgr = obj; 3002 struct drm_dp_mst_topology_state *state;
2998 struct drm_dp_mst_topology_state *new_mst_state;
2999 3003
3000 if (WARN_ON(!mgr->state)) 3004 state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
3005 if (!state)
3001 return NULL; 3006 return NULL;
3002 3007
3003 new_mst_state = kmemdup(mgr->state, sizeof(*new_mst_state), GFP_KERNEL); 3008 __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
3004 if (new_mst_state)
3005 new_mst_state->state = state;
3006 return new_mst_state;
3007}
3008
3009void drm_dp_mst_swap_state(void *obj, void **obj_state_ptr)
3010{
3011 struct drm_dp_mst_topology_mgr *mgr = obj;
3012 struct drm_dp_mst_topology_state **topology_state_ptr;
3013
3014 topology_state_ptr = (struct drm_dp_mst_topology_state **)obj_state_ptr;
3015 3009
3016 mgr->state->state = (*topology_state_ptr)->state; 3010 return &state->base;
3017 swap(*topology_state_ptr, mgr->state);
3018 mgr->state->state = NULL;
3019} 3011}
3020 3012
3021void drm_dp_mst_destroy_state(void *obj_state) 3013static void drm_dp_mst_destroy_state(struct drm_private_obj *obj,
3014 struct drm_private_state *state)
3022{ 3015{
3023 kfree(obj_state); 3016 struct drm_dp_mst_topology_state *mst_state =
3017 to_dp_mst_topology_state(state);
3018
3019 kfree(mst_state);
3024} 3020}
3025 3021
3026static const struct drm_private_state_funcs mst_state_funcs = { 3022static const struct drm_private_state_funcs mst_state_funcs = {
3027 .duplicate_state = drm_dp_mst_duplicate_state, 3023 .atomic_duplicate_state = drm_dp_mst_duplicate_state,
3028 .swap_state = drm_dp_mst_swap_state, 3024 .atomic_destroy_state = drm_dp_mst_destroy_state,
3029 .destroy_state = drm_dp_mst_destroy_state,
3030}; 3025};
3031 3026
3032/** 3027/**
@@ -3050,8 +3045,7 @@ struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_a
3050 struct drm_device *dev = mgr->dev; 3045 struct drm_device *dev = mgr->dev;
3051 3046
3052 WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); 3047 WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
3053 return drm_atomic_get_private_obj_state(state, mgr, 3048 return to_dp_mst_topology_state(drm_atomic_get_private_obj_state(state, &mgr->base));
3054 &mst_state_funcs);
3055} 3049}
3056EXPORT_SYMBOL(drm_atomic_get_mst_topology_state); 3050EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
3057 3051
@@ -3071,6 +3065,8 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
3071 int max_dpcd_transaction_bytes, 3065 int max_dpcd_transaction_bytes,
3072 int max_payloads, int conn_base_id) 3066 int max_payloads, int conn_base_id)
3073{ 3067{
3068 struct drm_dp_mst_topology_state *mst_state;
3069
3074 mutex_init(&mgr->lock); 3070 mutex_init(&mgr->lock);
3075 mutex_init(&mgr->qlock); 3071 mutex_init(&mgr->qlock);
3076 mutex_init(&mgr->payload_lock); 3072 mutex_init(&mgr->payload_lock);
@@ -3099,14 +3095,18 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
3099 if (test_calc_pbn_mode() < 0) 3095 if (test_calc_pbn_mode() < 0)
3100 DRM_ERROR("MST PBN self-test failed\n"); 3096 DRM_ERROR("MST PBN self-test failed\n");
3101 3097
3102 mgr->state = kzalloc(sizeof(*mgr->state), GFP_KERNEL); 3098 mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
3103 if (mgr->state == NULL) 3099 if (mst_state == NULL)
3104 return -ENOMEM; 3100 return -ENOMEM;
3105 mgr->state->mgr = mgr; 3101
3102 mst_state->mgr = mgr;
3106 3103
3107 /* max. time slots - one slot for MTP header */ 3104 /* max. time slots - one slot for MTP header */
3108 mgr->state->avail_slots = 63; 3105 mst_state->avail_slots = 63;
3109 mgr->funcs = &mst_state_funcs; 3106
3107 drm_atomic_private_obj_init(&mgr->base,
3108 &mst_state->base,
3109 &mst_state_funcs);
3110 3110
3111 return 0; 3111 return 0;
3112} 3112}
@@ -3128,8 +3128,7 @@ void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr)
3128 mutex_unlock(&mgr->payload_lock); 3128 mutex_unlock(&mgr->payload_lock);
3129 mgr->dev = NULL; 3129 mgr->dev = NULL;
3130 mgr->aux = NULL; 3130 mgr->aux = NULL;
3131 kfree(mgr->state); 3131 drm_atomic_private_obj_fini(&mgr->base);
3132 mgr->state = NULL;
3133 mgr->funcs = NULL; 3132 mgr->funcs = NULL;
3134} 3133}
3135EXPORT_SYMBOL(drm_dp_mst_topology_mgr_destroy); 3134EXPORT_SYMBOL(drm_dp_mst_topology_mgr_destroy);