diff options
author | Jani Nikula <jani.nikula@intel.com> | 2019-01-08 09:50:22 +0100 |
---|---|---|
committer | Jani Nikula <jani.nikula@intel.com> | 2019-01-08 09:50:22 +0100 |
commit | 3eb0930a425b086bdab38156aa4708427479a201 (patch) | |
tree | ea0bceef5bd1f62e4993f8f2f22a81f9da5f1f09 /include/drm | |
parent | Merge tag 'topic/drmp-cleanup-2019-01-02' of git://anongit.freedesktop.org/dr... (diff) | |
parent | Linux 5.0-rc1 (diff) | |
download | linux-3eb0930a425b086bdab38156aa4708427479a201.tar.xz linux-3eb0930a425b086bdab38156aa4708427479a201.zip |
Merge drm/drm-next into drm-intel-next-queued
Generally catch up with 5.0-rc1, and specifically get the changes:
96d4f267e40f ("Remove 'type' argument from access_ok() function")
0b2c8f8b6b0c ("i915: fix missing user_access_end() in page fault exception case")
594cc251fdd0 ("make 'user_access_begin()' do 'access_ok()'")
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Diffstat (limited to 'include/drm')
-rw-r--r-- | include/drm/drm_atomic_helper.h | 7 | ||||
-rw-r--r-- | include/drm/drm_atomic_state_helper.h | 7 | ||||
-rw-r--r-- | include/drm/drm_connector.h | 39 | ||||
-rw-r--r-- | include/drm/drm_crtc.h | 9 | ||||
-rw-r--r-- | include/drm/drm_damage_helper.h | 99 | ||||
-rw-r--r-- | include/drm/drm_drv.h | 14 | ||||
-rw-r--r-- | include/drm/drm_framebuffer.h | 24 | ||||
-rw-r--r-- | include/drm/drm_gem.h | 181 | ||||
-rw-r--r-- | include/drm/drm_gem_cma_helper.h | 24 | ||||
-rw-r--r-- | include/drm/drm_mode_config.h | 14 | ||||
-rw-r--r-- | include/drm/drm_modeset_lock.h | 59 | ||||
-rw-r--r-- | include/drm/drm_plane.h | 42 | ||||
-rw-r--r-- | include/drm/drm_prime.h | 1 | ||||
-rw-r--r-- | include/drm/drm_syncobj.h | 75 | ||||
-rw-r--r-- | include/drm/gpu_scheduler.h | 4 | ||||
-rw-r--r-- | include/drm/tinydrm/tinydrm.h | 35 | ||||
-rw-r--r-- | include/drm/ttm/ttm_execbuf_util.h | 4 |
17 files changed, 460 insertions, 178 deletions
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 25ca0097563e..58214be3bf3d 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -127,6 +127,9 @@ int __drm_atomic_helper_set_config(struct drm_mode_set *set, int drm_atomic_helper_disable_all(struct drm_device *dev, struct drm_modeset_acquire_ctx *ctx); void drm_atomic_helper_shutdown(struct drm_device *dev); +struct drm_atomic_state * +drm_atomic_helper_duplicate_state(struct drm_device *dev, + struct drm_modeset_acquire_ctx *ctx); struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev); int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state, struct drm_modeset_acquire_ctx *ctx); @@ -145,6 +148,10 @@ int drm_atomic_helper_page_flip_target( uint32_t flags, uint32_t target, struct drm_modeset_acquire_ctx *ctx); +int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, + u16 *red, u16 *green, u16 *blue, + uint32_t size, + struct drm_modeset_acquire_ctx *ctx); /** * drm_atomic_crtc_for_each_plane - iterate over planes currently attached to CRTC diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h index 5b82ccfdb502..66c92cbd8e16 100644 --- a/include/drm/drm_atomic_state_helper.h +++ b/include/drm/drm_atomic_state_helper.h @@ -65,16 +65,9 @@ __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector, struct drm_connector_state *state); struct drm_connector_state * drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector); -struct drm_atomic_state * -drm_atomic_helper_duplicate_state(struct drm_device *dev, - struct drm_modeset_acquire_ctx *ctx); void __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state); void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, struct drm_connector_state *state); -int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, - u16 *red, u16 *green, u16 *blue, - uint32_t size, - struct drm_modeset_acquire_ctx *ctx); void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj, struct drm_private_state *state); diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index af0a761f52f0..9be2181b3ed7 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -972,6 +972,17 @@ struct drm_connector { struct drm_property *scaling_mode_property; /** + * @vrr_capable_property: Optional property to help userspace + * query hardware support for variable refresh rate on a connector. + * connector. Drivers can add the property to a connector by + * calling drm_connector_attach_vrr_capable_property(). + * + * This should be updated only by calling + * drm_connector_set_vrr_capable_property(). + */ + struct drm_property *vrr_capable_property; + + /** * @content_protection_property: DRM ENUM property for content * protection. See drm_connector_attach_content_protection_property(). */ @@ -1211,30 +1222,6 @@ static inline void drm_connector_put(struct drm_connector *connector) } /** - * drm_connector_reference - acquire a connector reference - * @connector: DRM connector - * - * This is a compatibility alias for drm_connector_get() and should not be - * used by new code. - */ -static inline void drm_connector_reference(struct drm_connector *connector) -{ - drm_connector_get(connector); -} - -/** - * drm_connector_unreference - release a connector reference - * @connector: DRM connector - * - * This is a compatibility alias for drm_connector_put() and should not be - * used by new code. - */ -static inline void drm_connector_unreference(struct drm_connector *connector) -{ - drm_connector_put(connector); -} - -/** * drm_connector_is_unregistered - has the connector been unregistered from * userspace? * @connector: DRM connector @@ -1269,6 +1256,8 @@ int drm_mode_create_scaling_mode_property(struct drm_device *dev); int drm_connector_attach_content_type_property(struct drm_connector *dev); int drm_connector_attach_scaling_mode_property(struct drm_connector *connector, u32 scaling_mode_mask); +int drm_connector_attach_vrr_capable_property( + struct drm_connector *connector); int drm_connector_attach_content_protection_property( struct drm_connector *connector); int drm_mode_create_aspect_ratio_property(struct drm_device *dev); @@ -1285,6 +1274,8 @@ int drm_connector_update_edid_property(struct drm_connector *connector, const struct edid *edid); void drm_connector_set_link_status_property(struct drm_connector *connector, uint64_t link_status); +void drm_connector_set_vrr_capable_property( + struct drm_connector *connector, bool capable); int drm_connector_init_panel_orientation_property( struct drm_connector *connector, int width, int height); int drm_connector_attach_max_bpc_property(struct drm_connector *connector, diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index b21437bc95bf..39c3900aab3c 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -291,6 +291,15 @@ struct drm_crtc_state { u32 pageflip_flags; /** + * @vrr_enabled: + * + * Indicates if variable refresh rate should be enabled for the CRTC. + * Support for the requested vrr state will depend on driver and + * hardware capabiltiy - lacking support is not treated as failure. + */ + bool vrr_enabled; + + /** * @event: * * Optional pointer to a DRM event to signal upon completion of the diff --git a/include/drm/drm_damage_helper.h b/include/drm/drm_damage_helper.h new file mode 100644 index 000000000000..4487660b26b8 --- /dev/null +++ b/include/drm/drm_damage_helper.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/************************************************************************** + * + * Copyright (c) 2018 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Deepak Rawat <drawat@vmware.com> + * + **************************************************************************/ + +#ifndef DRM_DAMAGE_HELPER_H_ +#define DRM_DAMAGE_HELPER_H_ + +#include <drm/drm_atomic_helper.h> + +/** + * drm_atomic_for_each_plane_damage - Iterator macro for plane damage. + * @iter: The iterator to advance. + * @rect: Return a rectangle in fb coordinate clipped to plane src. + * + * Note that if the first call to iterator macro return false then no need to do + * plane update. Iterator will return full plane src when damage is not passed + * by user-space. + */ +#define drm_atomic_for_each_plane_damage(iter, rect) \ + while (drm_atomic_helper_damage_iter_next(iter, rect)) + +/** + * struct drm_atomic_helper_damage_iter - Closure structure for damage iterator. + * + * This structure tracks state needed to walk the list of plane damage clips. + */ +struct drm_atomic_helper_damage_iter { + /* private: Plane src in whole number. */ + struct drm_rect plane_src; + /* private: Rectangles in plane damage blob. */ + const struct drm_rect *clips; + /* private: Number of rectangles in plane damage blob. */ + uint32_t num_clips; + /* private: Current clip iterator is advancing on. */ + uint32_t curr_clip; + /* private: Whether need full plane update. */ + bool full_update; +}; + +void drm_plane_enable_fb_damage_clips(struct drm_plane *plane); +void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, + struct drm_plane_state *plane_state); +int drm_atomic_helper_dirtyfb(struct drm_framebuffer *fb, + struct drm_file *file_priv, unsigned int flags, + unsigned int color, struct drm_clip_rect *clips, + unsigned int num_clips); +void +drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter *iter, + const struct drm_plane_state *old_state, + const struct drm_plane_state *new_state); +bool +drm_atomic_helper_damage_iter_next(struct drm_atomic_helper_damage_iter *iter, + struct drm_rect *rect); + +/** + * drm_helper_get_plane_damage_clips - Returns damage clips in &drm_rect. + * @state: Plane state. + * + * Returns plane damage rectangles in internal &drm_rect. Currently &drm_rect + * can be obtained by simply typecasting &drm_mode_rect. This is because both + * are signed 32 and during drm_atomic_check_only() it is verified that damage + * clips are inside fb. + * + * Return: Clips in plane fb_damage_clips blob property. + */ +static inline struct drm_rect * +drm_helper_get_plane_damage_clips(const struct drm_plane_state *state) +{ + return (struct drm_rect *)drm_plane_get_damage_clips(state); +} + +#endif diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 3199ef70c007..35af23f5fa0d 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -471,6 +471,8 @@ struct drm_driver { * @gem_prime_export: * * export GEM -> dmabuf + * + * This defaults to drm_gem_prime_export() if not set. */ struct dma_buf * (*gem_prime_export)(struct drm_device *dev, struct drm_gem_object *obj, int flags); @@ -478,6 +480,8 @@ struct drm_driver { * @gem_prime_import: * * import dmabuf -> GEM + * + * This defaults to drm_gem_prime_import() if not set. */ struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev, struct dma_buf *dma_buf); @@ -523,8 +527,10 @@ struct drm_driver { * @dumb_map_offset: * * Allocate an offset in the drm device node's address space to be able to - * memory map a dumb buffer. GEM-based drivers must use - * drm_gem_create_mmap_offset() to implement this. + * memory map a dumb buffer. + * + * The default implementation is drm_gem_create_mmap_offset(). GEM based + * drivers must not overwrite this. * * Called by the user via ioctl. * @@ -544,6 +550,9 @@ struct drm_driver { * * Called by the user via ioctl. * + * The default implementation is drm_gem_dumb_destroy(). GEM based drivers + * must not overwrite this. + * * Returns: * * Zero on success, negative errno on failure. @@ -621,7 +630,6 @@ void drm_dev_unregister(struct drm_device *dev); void drm_dev_get(struct drm_device *dev); void drm_dev_put(struct drm_device *dev); -void drm_dev_unref(struct drm_device *dev); void drm_put_dev(struct drm_device *dev); bool drm_dev_enter(struct drm_device *dev, int *idx); void drm_dev_exit(int idx); diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h index c50502c656e5..c94acedfb08e 100644 --- a/include/drm/drm_framebuffer.h +++ b/include/drm/drm_framebuffer.h @@ -241,30 +241,6 @@ static inline void drm_framebuffer_put(struct drm_framebuffer *fb) } /** - * drm_framebuffer_reference - acquire a framebuffer reference - * @fb: DRM framebuffer - * - * This is a compatibility alias for drm_framebuffer_get() and should not be - * used by new code. - */ -static inline void drm_framebuffer_reference(struct drm_framebuffer *fb) -{ - drm_framebuffer_get(fb); -} - -/** - * drm_framebuffer_unreference - release a framebuffer reference - * @fb: DRM framebuffer - * - * This is a compatibility alias for drm_framebuffer_put() and should not be - * used by new code. - */ -static inline void drm_framebuffer_unreference(struct drm_framebuffer *fb) -{ - drm_framebuffer_put(fb); -} - -/** * drm_framebuffer_read_refcount - read the framebuffer reference count. * @fb: framebuffer * diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h index 3583b98a1718..c95727425284 100644 --- a/include/drm/drm_gem.h +++ b/include/drm/drm_gem.h @@ -38,6 +38,121 @@ #include <drm/drm_vma_manager.h> +struct drm_gem_object; + +/** + * struct drm_gem_object_funcs - GEM object functions + */ +struct drm_gem_object_funcs { + /** + * @free: + * + * Deconstructor for drm_gem_objects. + * + * This callback is mandatory. + */ + void (*free)(struct drm_gem_object *obj); + + /** + * @open: + * + * Called upon GEM handle creation. + * + * This callback is optional. + */ + int (*open)(struct drm_gem_object *obj, struct drm_file *file); + + /** + * @close: + * + * Called upon GEM handle release. + * + * This callback is optional. + */ + void (*close)(struct drm_gem_object *obj, struct drm_file *file); + + /** + * @print_info: + * + * If driver subclasses struct &drm_gem_object, it can implement this + * optional hook for printing additional driver specific info. + * + * drm_printf_indent() should be used in the callback passing it the + * indent argument. + * + * This callback is called from drm_gem_print_info(). + * + * This callback is optional. + */ + void (*print_info)(struct drm_printer *p, unsigned int indent, + const struct drm_gem_object *obj); + + /** + * @export: + * + * Export backing buffer as a &dma_buf. + * If this is not set drm_gem_prime_export() is used. + * + * This callback is optional. + */ + struct dma_buf *(*export)(struct drm_gem_object *obj, int flags); + + /** + * @pin: + * + * Pin backing buffer in memory. + * + * This callback is optional. + */ + int (*pin)(struct drm_gem_object *obj); + + /** + * @unpin: + * + * Unpin backing buffer. + * + * This callback is optional. + */ + void (*unpin)(struct drm_gem_object *obj); + + /** + * @get_sg_table: + * + * Returns a Scatter-Gather table representation of the buffer. + * Used when exporting a buffer. + * + * This callback is mandatory if buffer export is supported. + */ + struct sg_table *(*get_sg_table)(struct drm_gem_object *obj); + + /** + * @vmap: + * + * Returns a virtual address for the buffer. + * + * This callback is optional. + */ + void *(*vmap)(struct drm_gem_object *obj); + + /** + * @vunmap: + * + * Releases the the address previously returned by @vmap. + * + * This callback is optional. + */ + void (*vunmap)(struct drm_gem_object *obj, void *vaddr); + + /** + * @vm_ops: + * + * Virtual memory operations used with mmap. + * + * This is optional but necessary for mmap support. + */ + const struct vm_operations_struct *vm_ops; +}; + /** * struct drm_gem_object - GEM buffer object * @@ -146,6 +261,17 @@ struct drm_gem_object { * simply leave it as NULL. */ struct dma_buf_attachment *import_attach; + + /** + * @funcs: + * + * Optional GEM object functions. If this is set, it will be used instead of the + * corresponding &drm_driver GEM callbacks. + * + * New drivers should use this. + * + */ + const struct drm_gem_object_funcs *funcs; }; /** @@ -222,56 +348,6 @@ __drm_gem_object_put(struct drm_gem_object *obj) void drm_gem_object_put_unlocked(struct drm_gem_object *obj); void drm_gem_object_put(struct drm_gem_object *obj); -/** - * drm_gem_object_reference - acquire a GEM buffer object reference - * @obj: GEM buffer object - * - * This is a compatibility alias for drm_gem_object_get() and should not be - * used by new code. - */ -static inline void drm_gem_object_reference(struct drm_gem_object *obj) -{ - drm_gem_object_get(obj); -} - -/** - * __drm_gem_object_unreference - raw function to release a GEM buffer object - * reference - * @obj: GEM buffer object - * - * This is a compatibility alias for __drm_gem_object_put() and should not be - * used by new code. - */ -static inline void __drm_gem_object_unreference(struct drm_gem_object *obj) -{ - __drm_gem_object_put(obj); -} - -/** - * drm_gem_object_unreference_unlocked - release a GEM buffer object reference - * @obj: GEM buffer object - * - * This is a compatibility alias for drm_gem_object_put_unlocked() and should - * not be used by new code. - */ -static inline void -drm_gem_object_unreference_unlocked(struct drm_gem_object *obj) -{ - drm_gem_object_put_unlocked(obj); -} - -/** - * drm_gem_object_unreference - release a GEM buffer object reference - * @obj: GEM buffer object - * - * This is a compatibility alias for drm_gem_object_put() and should not be - * used by new code. - */ -static inline void drm_gem_object_unreference(struct drm_gem_object *obj) -{ - drm_gem_object_put(obj); -} - int drm_gem_handle_create(struct drm_file *file_priv, struct drm_gem_object *obj, u32 *handlep); @@ -293,4 +369,9 @@ int drm_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, uint32_t handle); +int drm_gem_pin(struct drm_gem_object *obj); +void drm_gem_unpin(struct drm_gem_object *obj); +void *drm_gem_vmap(struct drm_gem_object *obj); +void drm_gem_vunmap(struct drm_gem_object *obj, void *vaddr); + #endif /* __DRM_GEM_H__ */ diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h index 19777145cf8e..07c504940ba1 100644 --- a/include/drm/drm_gem_cma_helper.h +++ b/include/drm/drm_gem_cma_helper.h @@ -103,4 +103,28 @@ int drm_gem_cma_prime_mmap(struct drm_gem_object *obj, void *drm_gem_cma_prime_vmap(struct drm_gem_object *obj); void drm_gem_cma_prime_vunmap(struct drm_gem_object *obj, void *vaddr); +struct drm_gem_object * +drm_cma_gem_create_object_default_funcs(struct drm_device *dev, size_t size); + +/** + * DRM_GEM_CMA_VMAP_DRIVER_OPS - CMA GEM driver operations ensuring a virtual + * address on the buffer + * + * This macro provides a shortcut for setting the default GEM operations in the + * &drm_driver structure for drivers that need the virtual address also on + * imported buffers. + */ +#define DRM_GEM_CMA_VMAP_DRIVER_OPS \ + .gem_create_object = drm_cma_gem_create_object_default_funcs, \ + .dumb_create = drm_gem_cma_dumb_create, \ + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, \ + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, \ + .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table_vmap, \ + .gem_prime_mmap = drm_gem_prime_mmap + +struct drm_gem_object * +drm_gem_cma_prime_import_sg_table_vmap(struct drm_device *drm, + struct dma_buf_attachment *attach, + struct sg_table *sgt); + #endif /* __DRM_GEM_CMA_HELPER_H__ */ diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 5dbeabdbaf91..572274ccbec7 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -634,6 +634,15 @@ struct drm_mode_config { */ struct drm_property *prop_crtc_id; /** + * @prop_fb_damage_clips: Optional plane property to mark damaged + * regions on the plane in framebuffer coordinates of the framebuffer + * attached to the plane. + * + * The layout of blob data is simply an array of &drm_mode_rect. Unlike + * plane src coordinates, damage clips are not in 16.16 fixed point. + */ + struct drm_property *prop_fb_damage_clips; + /** * @prop_active: Default atomic CRTC property to control the active * state, which is the simplified implementation for DPMS in atomic * drivers. @@ -645,6 +654,11 @@ struct drm_mode_config { * connectors must be of and active must be set to disabled, too. */ struct drm_property *prop_mode_id; + /** + * @prop_vrr_enabled: Default atomic CRTC property to indicate + * whether variable refresh rate should be enabled on the CRTC. + */ + struct drm_property *prop_vrr_enabled; /** * @dvi_i_subconnector_property: Optional DVI-I property to diff --git a/include/drm/drm_modeset_lock.h b/include/drm/drm_modeset_lock.h index a685d1bb21f2..a308f2d6496f 100644 --- a/include/drm/drm_modeset_lock.h +++ b/include/drm/drm_modeset_lock.h @@ -130,4 +130,63 @@ void drm_warn_on_modeset_not_all_locked(struct drm_device *dev); int drm_modeset_lock_all_ctx(struct drm_device *dev, struct drm_modeset_acquire_ctx *ctx); +/** + * DRM_MODESET_LOCK_ALL_BEGIN - Helper to acquire modeset locks + * @dev: drm device + * @ctx: local modeset acquire context, will be dereferenced + * @flags: DRM_MODESET_ACQUIRE_* flags to pass to drm_modeset_acquire_init() + * @ret: local ret/err/etc variable to track error status + * + * Use these macros to simplify grabbing all modeset locks using a local + * context. This has the advantage of reducing boilerplate, but also properly + * checking return values where appropriate. + * + * Any code run between BEGIN and END will be holding the modeset locks. + * + * This must be paired with DRM_MODESET_LOCK_ALL_END(). We will jump back and + * forth between the labels on deadlock and error conditions. + * + * Drivers can acquire additional modeset locks. If any lock acquisition + * fails, the control flow needs to jump to DRM_MODESET_LOCK_ALL_END() with + * the @ret parameter containing the return value of drm_modeset_lock(). + * + * Returns: + * The only possible value of ret immediately after DRM_MODESET_LOCK_ALL_BEGIN() + * is 0, so no error checking is necessary + */ +#define DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, flags, ret) \ + drm_modeset_acquire_init(&ctx, flags); \ +modeset_lock_retry: \ + ret = drm_modeset_lock_all_ctx(dev, &ctx); \ + if (ret) \ + goto modeset_lock_fail; + +/** + * DRM_MODESET_LOCK_ALL_END - Helper to release and cleanup modeset locks + * @ctx: local modeset acquire context, will be dereferenced + * @ret: local ret/err/etc variable to track error status + * + * The other side of DRM_MODESET_LOCK_ALL_BEGIN(). It will bounce back to BEGIN + * if ret is -EDEADLK. + * + * It's important that you use the same ret variable for begin and end so + * deadlock conditions are properly handled. + * + * Returns: + * ret will be untouched unless it is -EDEADLK on entry. That means that if you + * successfully acquire the locks, ret will be whatever your code sets it to. If + * there is a deadlock or other failure with acquire or backoff, ret will be set + * to that failure. In both of these cases the code between BEGIN/END will not + * be run, so the failure will reflect the inability to grab the locks. + */ +#define DRM_MODESET_LOCK_ALL_END(ctx, ret) \ +modeset_lock_fail: \ + if (ret == -EDEADLK) { \ + ret = drm_modeset_backoff(&ctx); \ + if (!ret) \ + goto modeset_lock_retry; \ + } \ + drm_modeset_drop_locks(&ctx); \ + drm_modeset_acquire_fini(&ctx); + #endif /* DRM_MODESET_LOCK_H_ */ diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 3701f56c3362..6078c700d9ba 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -173,6 +173,16 @@ struct drm_plane_state { */ enum drm_color_range color_range; + /** + * @fb_damage_clips: + * + * Blob representing damage (area in plane framebuffer that changed + * since last plane update) as an array of &drm_mode_rect in framebuffer + * coodinates of the attached framebuffer. Note that unlike plane src, + * damage clips are not in 16.16 fixed point. + */ + struct drm_property_blob *fb_damage_clips; + /** @src: clipped source coordinates of the plane (in 16.16) */ /** @dst: clipped destination coordinates of the plane */ struct drm_rect src, dst; @@ -800,5 +810,37 @@ static inline struct drm_plane *drm_plane_find(struct drm_device *dev, bool drm_any_plane_has_format(struct drm_device *dev, u32 format, u64 modifier); +/** + * drm_plane_get_damage_clips_count - Returns damage clips count. + * @state: Plane state. + * + * Simple helper to get the number of &drm_mode_rect clips set by user-space + * during plane update. + * + * Return: Number of clips in plane fb_damage_clips blob property. + */ +static inline unsigned int +drm_plane_get_damage_clips_count(const struct drm_plane_state *state) +{ + return (state && state->fb_damage_clips) ? + state->fb_damage_clips->length/sizeof(struct drm_mode_rect) : 0; +} + +/** + * drm_plane_get_damage_clips - Returns damage clips. + * @state: Plane state. + * + * Note that this function returns uapi type &drm_mode_rect. Drivers might + * instead be interested in internal &drm_rect which can be obtained by calling + * drm_helper_get_plane_damage_clips(). + * + * Return: Damage clips in plane fb_damage_clips blob property. + */ +static inline struct drm_mode_rect * +drm_plane_get_damage_clips(const struct drm_plane_state *state) +{ + return (struct drm_mode_rect *)((state && state->fb_damage_clips) ? + state->fb_damage_clips->data : NULL); +} #endif diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h index e2032fbc0f08..b03731a3f079 100644 --- a/include/drm/drm_prime.h +++ b/include/drm/drm_prime.h @@ -70,6 +70,7 @@ struct dma_buf *drm_gem_prime_export(struct drm_device *dev, int drm_gem_prime_handle_to_fd(struct drm_device *dev, struct drm_file *file_priv, uint32_t handle, uint32_t flags, int *prime_fd); +int drm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf); diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h index ef5721512632..a08e9232dba1 100644 --- a/include/drm/drm_syncobj.h +++ b/include/drm/drm_syncobj.h @@ -32,15 +32,10 @@ struct drm_file; struct drm_syncobj_cb; -enum drm_syncobj_type { - DRM_SYNCOBJ_TYPE_BINARY, - DRM_SYNCOBJ_TYPE_TIMELINE -}; - /** * struct drm_syncobj - sync object. * - * This structure defines a generic sync object which is timeline based. + * This structure defines a generic sync object which wraps a &dma_fence. */ struct drm_syncobj { /** @@ -48,42 +43,21 @@ struct drm_syncobj { */ struct kref refcount; /** - * @type: indicate syncobj type - */ - enum drm_syncobj_type type; - /** - * @wq: wait signal operation work queue - */ - wait_queue_head_t wq; - /** - * @timeline_context: fence context used by timeline + * @fence: + * NULL or a pointer to the fence bound to this object. + * + * This field should not be used directly. Use drm_syncobj_fence_get() + * and drm_syncobj_replace_fence() instead. */ - u64 timeline_context; + struct dma_fence __rcu *fence; /** - * @timeline: syncobj timeline value, which indicates point is signaled. + * @cb_list: List of callbacks to call when the &fence gets replaced. */ - u64 timeline; - /** - * @signal_point: which indicates the latest signaler point. - */ - u64 signal_point; - /** - * @signal_pt_list: signaler point list. - */ - struct list_head signal_pt_list; - - /** - * @cb_list: List of callbacks to call when the &fence gets replaced. - */ struct list_head cb_list; /** - * @pt_lock: Protects pt list. + * @lock: Protects &cb_list and write-locks &fence. */ - spinlock_t pt_lock; - /** - * @cb_mutex: Protects syncobj cb list. - */ - struct mutex cb_mutex; + spinlock_t lock; /** * @file: A file backing for this syncobj. */ @@ -96,7 +70,7 @@ typedef void (*drm_syncobj_func_t)(struct drm_syncobj *syncobj, /** * struct drm_syncobj_cb - callback for drm_syncobj_add_callback * @node: used by drm_syncob_add_callback to append this struct to - * &drm_syncobj.cb_list + * &drm_syncobj.cb_list * @func: drm_syncobj_func_t to call * * This struct will be initialized by drm_syncobj_add_callback, additional @@ -134,9 +108,32 @@ drm_syncobj_put(struct drm_syncobj *obj) kref_put(&obj->refcount, drm_syncobj_free); } +/** + * drm_syncobj_fence_get - get a reference to a fence in a sync object + * @syncobj: sync object. + * + * This acquires additional reference to &drm_syncobj.fence contained in @obj, + * if not NULL. It is illegal to call this without already holding a reference. + * No locks required. + * + * Returns: + * Either the fence of @obj or NULL if there's none. + */ +static inline struct dma_fence * +drm_syncobj_fence_get(struct drm_syncobj *syncobj) +{ + struct dma_fence *fence; + + rcu_read_lock(); + fence = dma_fence_get_rcu_safe(&syncobj->fence); + rcu_read_unlock(); + + return fence; +} + struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private, u32 handle); -void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, u64 point, +void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, struct dma_fence *fence); int drm_syncobj_find_fence(struct drm_file *file_private, u32 handle, u64 point, u64 flags, @@ -147,7 +144,5 @@ int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags, int drm_syncobj_get_handle(struct drm_file *file_private, struct drm_syncobj *syncobj, u32 *handle); int drm_syncobj_get_fd(struct drm_syncobj *syncobj, int *p_fd); -int drm_syncobj_search_fence(struct drm_syncobj *syncobj, u64 point, u64 flags, - struct dma_fence **fence); #endif diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index 926379d53484..47e19796c450 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -331,4 +331,8 @@ struct drm_sched_fence *drm_sched_fence_create( void drm_sched_fence_scheduled(struct drm_sched_fence *fence); void drm_sched_fence_finished(struct drm_sched_fence *fence); +unsigned long drm_sched_suspend_timeout(struct drm_gpu_scheduler *sched); +void drm_sched_resume_timeout(struct drm_gpu_scheduler *sched, + unsigned long remaining); + #endif diff --git a/include/drm/tinydrm/tinydrm.h b/include/drm/tinydrm/tinydrm.h index fe9827d0ca8a..448aa5ea4722 100644 --- a/include/drm/tinydrm/tinydrm.h +++ b/include/drm/tinydrm/tinydrm.h @@ -10,10 +10,15 @@ #ifndef __LINUX_TINYDRM_H #define __LINUX_TINYDRM_H -#include <drm/drm_gem_cma_helper.h> -#include <drm/drm_fb_cma_helper.h> +#include <linux/mutex.h> #include <drm/drm_simple_kms_helper.h> +struct drm_clip_rect; +struct drm_driver; +struct drm_file; +struct drm_framebuffer; +struct drm_framebuffer_funcs; + /** * struct tinydrm_device - tinydrm device */ @@ -54,27 +59,6 @@ pipe_to_tinydrm(struct drm_simple_display_pipe *pipe) } /** - * TINYDRM_GEM_DRIVER_OPS - default tinydrm gem operations - * - * This macro provides a shortcut for setting the tinydrm GEM operations in - * the &drm_driver structure. - */ -#define TINYDRM_GEM_DRIVER_OPS \ - .gem_free_object_unlocked = tinydrm_gem_cma_free_object, \ - .gem_print_info = drm_gem_cma_print_info, \ - .gem_vm_ops = &drm_gem_cma_vm_ops, \ - .prime_handle_to_fd = drm_gem_prime_handle_to_fd, \ - .prime_fd_to_handle = drm_gem_prime_fd_to_handle, \ - .gem_prime_import = drm_gem_prime_import, \ - .gem_prime_export = drm_gem_prime_export, \ - .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, \ - .gem_prime_import_sg_table = tinydrm_gem_cma_prime_import_sg_table, \ - .gem_prime_vmap = drm_gem_cma_prime_vmap, \ - .gem_prime_vunmap = drm_gem_cma_prime_vunmap, \ - .gem_prime_mmap = drm_gem_cma_prime_mmap, \ - .dumb_create = drm_gem_cma_dumb_create - -/** * TINYDRM_MODE - tinydrm display mode * @hd: Horizontal resolution, width * @vd: Vertical resolution, height @@ -97,11 +81,6 @@ pipe_to_tinydrm(struct drm_simple_display_pipe *pipe) .type = DRM_MODE_TYPE_DRIVER, \ .clock = 1 /* pass validation */ -void tinydrm_gem_cma_free_object(struct drm_gem_object *gem_obj); -struct drm_gem_object * -tinydrm_gem_cma_prime_import_sg_table(struct drm_device *drm, - struct dma_buf_attachment *attach, - struct sg_table *sgt); int devm_tinydrm_init(struct device *parent, struct tinydrm_device *tdev, const struct drm_framebuffer_funcs *fb_funcs, struct drm_driver *driver); diff --git a/include/drm/ttm/ttm_execbuf_util.h b/include/drm/ttm/ttm_execbuf_util.h index b0fdd1980034..621615fa7728 100644 --- a/include/drm/ttm/ttm_execbuf_util.h +++ b/include/drm/ttm/ttm_execbuf_util.h @@ -40,13 +40,13 @@ * * @head: list head for thread-private list. * @bo: refcounted buffer object pointer. - * @shared: should the fence be added shared? + * @num_shared: How many shared fences we want to add. */ struct ttm_validate_buffer { struct list_head head; struct ttm_buffer_object *bo; - bool shared; + unsigned int num_shared; }; /** |