diff options
| author | Dave Airlie <airlied@redhat.com> | 2017-07-27 05:32:45 +1000 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2017-07-27 05:32:45 +1000 |
| commit | 542aefb5a2da8f67b8fb74a24f60ecb3ec479a06 (patch) | |
| tree | 98858f6e890b7ce3609126446c4100461841e17c /drivers/gpu/drm/drm_atomic.c | |
| parent | 2d62c799f8ffac4f7ffba6a4e7f148827dfc24c7 (diff) | |
| parent | 8bb9777332e5e0f90c64448e48d2554b8bf76a62 (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_atomic.c')
| -rw-r--r-- | drivers/gpu/drm/drm_atomic.c | 121 |
1 files changed, 70 insertions, 51 deletions
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index c0f336d23f9c..01192dd3ed79 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -29,7 +29,6 @@ #include <drm/drmP.h> #include <drm/drm_atomic.h> #include <drm/drm_mode.h> -#include <drm/drm_plane_helper.h> #include <drm/drm_print.h> #include <linux/sync_file.h> @@ -188,12 +187,15 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state) } for (i = 0; i < state->num_private_objs; i++) { - void *obj_state = state->private_objs[i].obj_state; + struct drm_private_obj *obj = state->private_objs[i].ptr; - state->private_objs[i].funcs->destroy_state(obj_state); - state->private_objs[i].obj = NULL; - state->private_objs[i].obj_state = NULL; - state->private_objs[i].funcs = NULL; + if (!obj) + continue; + + obj->funcs->atomic_destroy_state(obj, + state->private_objs[i].state); + state->private_objs[i].ptr = NULL; + state->private_objs[i].state = NULL; } state->num_private_objs = 0; @@ -409,34 +411,6 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, } EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc); -/** - * drm_atomic_replace_property_blob - replace a blob property - * @blob: a pointer to the member blob to be replaced - * @new_blob: the new blob to replace with - * @replaced: whether the blob has been replaced - * - * RETURNS: - * Zero on success, error code on failure - */ -static void -drm_atomic_replace_property_blob(struct drm_property_blob **blob, - struct drm_property_blob *new_blob, - bool *replaced) -{ - struct drm_property_blob *old_blob = *blob; - - if (old_blob == new_blob) - return; - - drm_property_blob_put(old_blob); - if (new_blob) - drm_property_blob_get(new_blob); - *blob = new_blob; - *replaced = true; - - return; -} - static int drm_atomic_replace_property_blob_from_id(struct drm_device *dev, struct drm_property_blob **blob, @@ -457,7 +431,7 @@ drm_atomic_replace_property_blob_from_id(struct drm_device *dev, } } - drm_atomic_replace_property_blob(blob, new_blob, replaced); + *replaced |= drm_property_replace_blob(blob, new_blob); drm_property_blob_put(new_blob); return 0; @@ -991,11 +965,44 @@ static void drm_atomic_plane_print_state(struct drm_printer *p, } /** + * drm_atomic_private_obj_init - initialize private object + * @obj: private object + * @state: initial private object state + * @funcs: pointer to the struct of function pointers that identify the object + * type + * + * Initialize the private object, which can be embedded into any + * driver private object that needs its own atomic state. + */ +void +drm_atomic_private_obj_init(struct drm_private_obj *obj, + struct drm_private_state *state, + const struct drm_private_state_funcs *funcs) +{ + memset(obj, 0, sizeof(*obj)); + + obj->state = state; + obj->funcs = funcs; +} +EXPORT_SYMBOL(drm_atomic_private_obj_init); + +/** + * drm_atomic_private_obj_fini - finalize private object + * @obj: private object + * + * Finalize the private object. + */ +void +drm_atomic_private_obj_fini(struct drm_private_obj *obj) +{ + obj->funcs->atomic_destroy_state(obj, obj->state); +} +EXPORT_SYMBOL(drm_atomic_private_obj_fini); + +/** * drm_atomic_get_private_obj_state - get private object state * @state: global atomic state * @obj: private object to get the state for - * @funcs: pointer to the struct of function pointers that identify the object - * type * * This function returns the private object state for the given private object, * allocating the state if needed. It does not grab any locks as the caller is @@ -1005,18 +1012,18 @@ static void drm_atomic_plane_print_state(struct drm_printer *p, * * Either the allocated state or the error code encoded into a pointer. */ -void * -drm_atomic_get_private_obj_state(struct drm_atomic_state *state, void *obj, - const struct drm_private_state_funcs *funcs) +struct drm_private_state * +drm_atomic_get_private_obj_state(struct drm_atomic_state *state, + struct drm_private_obj *obj) { int index, num_objs, i; size_t size; struct __drm_private_objs_state *arr; + struct drm_private_state *obj_state; for (i = 0; i < state->num_private_objs; i++) - if (obj == state->private_objs[i].obj && - state->private_objs[i].obj_state) - return state->private_objs[i].obj_state; + if (obj == state->private_objs[i].ptr) + return state->private_objs[i].state; num_objs = state->num_private_objs + 1; size = sizeof(*state->private_objs) * num_objs; @@ -1028,18 +1035,21 @@ drm_atomic_get_private_obj_state(struct drm_atomic_state *state, void *obj, index = state->num_private_objs; memset(&state->private_objs[index], 0, sizeof(*state->private_objs)); - state->private_objs[index].obj_state = funcs->duplicate_state(state, obj); - if (!state->private_objs[index].obj_state) + obj_state = obj->funcs->atomic_duplicate_state(obj); + if (!obj_state) return ERR_PTR(-ENOMEM); - state->private_objs[index].obj = obj; - state->private_objs[index].funcs = funcs; + state->private_objs[index].state = obj_state; + state->private_objs[index].old_state = obj->state; + state->private_objs[index].new_state = obj_state; + state->private_objs[index].ptr = obj; + state->num_private_objs = num_objs; - DRM_DEBUG_ATOMIC("Added new private object state %p to %p\n", - state->private_objs[index].obj_state, state); + DRM_DEBUG_ATOMIC("Added new private object %p state %p to %p\n", + obj, obj_state, state); - return state->private_objs[index].obj_state; + return obj_state; } EXPORT_SYMBOL(drm_atomic_get_private_obj_state); @@ -2039,7 +2049,7 @@ static int prepare_crtc_signaling(struct drm_device *dev, { struct drm_crtc *crtc; struct drm_crtc_state *crtc_state; - int i, ret; + int i, c = 0, ret; if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) return 0; @@ -2100,8 +2110,17 @@ static int prepare_crtc_signaling(struct drm_device *dev, crtc_state->event->base.fence = fence; } + + c++; } + /* + * Having this flag means user mode pends on event which will never + * reach due to lack of at least one CRTC for signaling + */ + if (c == 0 && (arg->flags & DRM_MODE_PAGE_FLIP_EVENT)) + return -EINVAL; + return 0; } |
