diff options
Diffstat (limited to 'drivers/gpu/drm/drm_gem_atomic_helper.c')
| -rw-r--r-- | drivers/gpu/drm/drm_gem_atomic_helper.c | 115 |
1 files changed, 46 insertions, 69 deletions
diff --git a/drivers/gpu/drm/drm_gem_atomic_helper.c b/drivers/gpu/drm/drm_gem_atomic_helper.c index b6a0110eb64a..569d41a65a0b 100644 --- a/drivers/gpu/drm/drm_gem_atomic_helper.c +++ b/drivers/gpu/drm/drm_gem_atomic_helper.c @@ -2,6 +2,7 @@ #include <linux/dma-resv.h> #include <linux/dma-fence-chain.h> +#include <linux/export.h> #include <drm/drm_atomic_state_helper.h> #include <drm/drm_atomic_uapi.h> @@ -26,11 +27,8 @@ * call drm_gem_plane_helper_prepare_fb() from their implementation of * struct &drm_plane_helper.prepare_fb . It sets the plane's fence from * the framebuffer so that the DRM core can synchronize access automatically. - * * drm_gem_plane_helper_prepare_fb() can also be used directly as - * implementation of prepare_fb. For drivers based on - * struct drm_simple_display_pipe, drm_gem_simple_display_pipe_prepare_fb() - * provides equivalent functionality. + * implementation of prepare_fb. * * .. code-block:: c * @@ -41,11 +39,6 @@ * . prepare_fb = drm_gem_plane_helper_prepare_fb, * }; * - * struct drm_simple_display_pipe_funcs driver_pipe_funcs = { - * ..., - * . prepare_fb = drm_gem_simple_display_pipe_prepare_fb, - * }; - * * A driver using a shadow buffer copies the content of the shadow buffers * into the HW's framebuffer memory during an atomic update. This requires * a mapping of the shadow buffer into kernel address space. The mappings @@ -205,27 +198,6 @@ error: } EXPORT_SYMBOL_GPL(drm_gem_plane_helper_prepare_fb); -/** - * drm_gem_simple_display_pipe_prepare_fb - prepare_fb helper for &drm_simple_display_pipe - * @pipe: Simple display pipe - * @plane_state: Plane state - * - * This function uses drm_gem_plane_helper_prepare_fb() to extract the fences - * from &drm_gem_object.resv and attaches them to the plane state for the atomic - * helper to wait on. This is necessary to correctly implement implicit - * synchronization for any buffers shared as a struct &dma_buf. Drivers can use - * this as their &drm_simple_display_pipe_funcs.prepare_fb callback. - * - * See drm_gem_plane_helper_prepare_fb() for a discussion of implicit and - * explicit fencing in atomic modeset updates. - */ -int drm_gem_simple_display_pipe_prepare_fb(struct drm_simple_display_pipe *pipe, - struct drm_plane_state *plane_state) -{ - return drm_gem_plane_helper_prepare_fb(&pipe->plane, plane_state); -} -EXPORT_SYMBOL(drm_gem_simple_display_pipe_prepare_fb); - /* * Shadow-buffered Planes */ @@ -247,7 +219,14 @@ void __drm_gem_duplicate_shadow_plane_state(struct drm_plane *plane, struct drm_shadow_plane_state *new_shadow_plane_state) { + struct drm_plane_state *plane_state = plane->state; + struct drm_shadow_plane_state *shadow_plane_state = + to_drm_shadow_plane_state(plane_state); + __drm_atomic_helper_plane_duplicate_state(plane, &new_shadow_plane_state->base); + + drm_format_conv_state_copy(&new_shadow_plane_state->fmtcnv_state, + &shadow_plane_state->fmtcnv_state); } EXPORT_SYMBOL(__drm_gem_duplicate_shadow_plane_state); @@ -295,6 +274,7 @@ EXPORT_SYMBOL(drm_gem_duplicate_shadow_plane_state); */ void __drm_gem_destroy_shadow_plane_state(struct drm_shadow_plane_state *shadow_plane_state) { + drm_format_conv_state_release(&shadow_plane_state->fmtcnv_state); __drm_atomic_helper_plane_destroy_state(&shadow_plane_state->base); } EXPORT_SYMBOL(__drm_gem_destroy_shadow_plane_state); @@ -330,7 +310,12 @@ EXPORT_SYMBOL(drm_gem_destroy_shadow_plane_state); void __drm_gem_reset_shadow_plane(struct drm_plane *plane, struct drm_shadow_plane_state *shadow_plane_state) { - __drm_atomic_helper_plane_reset(plane, &shadow_plane_state->base); + if (shadow_plane_state) { + __drm_atomic_helper_plane_reset(plane, &shadow_plane_state->base); + drm_format_conv_state_init(&shadow_plane_state->fmtcnv_state); + } else { + __drm_atomic_helper_plane_reset(plane, NULL); + } } EXPORT_SYMBOL(__drm_gem_reset_shadow_plane); @@ -353,55 +338,48 @@ void drm_gem_reset_shadow_plane(struct drm_plane *plane) } shadow_plane_state = kzalloc(sizeof(*shadow_plane_state), GFP_KERNEL); - if (!shadow_plane_state) - return; __drm_gem_reset_shadow_plane(plane, shadow_plane_state); } EXPORT_SYMBOL(drm_gem_reset_shadow_plane); /** - * drm_gem_prepare_shadow_fb - prepares shadow framebuffers + * drm_gem_begin_shadow_fb_access - prepares shadow framebuffers for CPU access * @plane: the plane * @plane_state: the plane state of type struct drm_shadow_plane_state * - * This function implements struct &drm_plane_helper_funcs.prepare_fb. It + * This function implements struct &drm_plane_helper_funcs.begin_fb_access. It * maps all buffer objects of the plane's framebuffer into kernel address - * space and stores them in &struct drm_shadow_plane_state.map. The - * framebuffer will be synchronized as part of the atomic commit. + * space and stores them in struct &drm_shadow_plane_state.map. The first data + * bytes are available in struct &drm_shadow_plane_state.data. * - * See drm_gem_cleanup_shadow_fb() for cleanup. + * See drm_gem_end_shadow_fb_access() for cleanup. * * Returns: * 0 on success, or a negative errno code otherwise. */ -int drm_gem_prepare_shadow_fb(struct drm_plane *plane, struct drm_plane_state *plane_state) +int drm_gem_begin_shadow_fb_access(struct drm_plane *plane, struct drm_plane_state *plane_state) { struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); struct drm_framebuffer *fb = plane_state->fb; - int ret; if (!fb) return 0; - ret = drm_gem_plane_helper_prepare_fb(plane, plane_state); - if (ret) - return ret; - return drm_gem_fb_vmap(fb, shadow_plane_state->map, shadow_plane_state->data); } -EXPORT_SYMBOL(drm_gem_prepare_shadow_fb); +EXPORT_SYMBOL(drm_gem_begin_shadow_fb_access); /** - * drm_gem_cleanup_shadow_fb - releases shadow framebuffers + * drm_gem_end_shadow_fb_access - releases shadow framebuffers from CPU access * @plane: the plane * @plane_state: the plane state of type struct drm_shadow_plane_state * - * This function implements struct &drm_plane_helper_funcs.cleanup_fb. - * This function unmaps all buffer objects of the plane's framebuffer. + * This function implements struct &drm_plane_helper_funcs.end_fb_access. It + * undoes all effects of drm_gem_begin_shadow_fb_access() in reverse order. * - * See drm_gem_prepare_shadow_fb() for more information. + * See drm_gem_begin_shadow_fb_access() for more information. */ -void drm_gem_cleanup_shadow_fb(struct drm_plane *plane, struct drm_plane_state *plane_state) +void drm_gem_end_shadow_fb_access(struct drm_plane *plane, struct drm_plane_state *plane_state) { struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); struct drm_framebuffer *fb = plane_state->fb; @@ -411,46 +389,45 @@ void drm_gem_cleanup_shadow_fb(struct drm_plane *plane, struct drm_plane_state * drm_gem_fb_vunmap(fb, shadow_plane_state->map); } -EXPORT_SYMBOL(drm_gem_cleanup_shadow_fb); +EXPORT_SYMBOL(drm_gem_end_shadow_fb_access); /** - * drm_gem_simple_kms_prepare_shadow_fb - prepares shadow framebuffers + * drm_gem_simple_kms_begin_shadow_fb_access - prepares shadow framebuffers for CPU access * @pipe: the simple display pipe * @plane_state: the plane state of type struct drm_shadow_plane_state * - * This function implements struct drm_simple_display_funcs.prepare_fb. It - * maps all buffer objects of the plane's framebuffer into kernel address - * space and stores them in struct drm_shadow_plane_state.map. The - * framebuffer will be synchronized as part of the atomic commit. + * This function implements struct drm_simple_display_funcs.begin_fb_access. * - * See drm_gem_simple_kms_cleanup_shadow_fb() for cleanup. + * See drm_gem_begin_shadow_fb_access() for details and + * drm_gem_simple_kms_cleanup_shadow_fb() for cleanup. * * Returns: * 0 on success, or a negative errno code otherwise. */ -int drm_gem_simple_kms_prepare_shadow_fb(struct drm_simple_display_pipe *pipe, - struct drm_plane_state *plane_state) +int drm_gem_simple_kms_begin_shadow_fb_access(struct drm_simple_display_pipe *pipe, + struct drm_plane_state *plane_state) { - return drm_gem_prepare_shadow_fb(&pipe->plane, plane_state); + return drm_gem_begin_shadow_fb_access(&pipe->plane, plane_state); } -EXPORT_SYMBOL(drm_gem_simple_kms_prepare_shadow_fb); +EXPORT_SYMBOL(drm_gem_simple_kms_begin_shadow_fb_access); /** - * drm_gem_simple_kms_cleanup_shadow_fb - releases shadow framebuffers + * drm_gem_simple_kms_end_shadow_fb_access - releases shadow framebuffers from CPU access * @pipe: the simple display pipe * @plane_state: the plane state of type struct drm_shadow_plane_state * - * This function implements struct drm_simple_display_funcs.cleanup_fb. - * This function unmaps all buffer objects of the plane's framebuffer. + * This function implements struct drm_simple_display_funcs.end_fb_access. + * It undoes all effects of drm_gem_simple_kms_begin_shadow_fb_access() in + * reverse order. * - * See drm_gem_simple_kms_prepare_shadow_fb(). + * See drm_gem_simple_kms_begin_shadow_fb_access(). */ -void drm_gem_simple_kms_cleanup_shadow_fb(struct drm_simple_display_pipe *pipe, - struct drm_plane_state *plane_state) +void drm_gem_simple_kms_end_shadow_fb_access(struct drm_simple_display_pipe *pipe, + struct drm_plane_state *plane_state) { - drm_gem_cleanup_shadow_fb(&pipe->plane, plane_state); + drm_gem_end_shadow_fb_access(&pipe->plane, plane_state); } -EXPORT_SYMBOL(drm_gem_simple_kms_cleanup_shadow_fb); +EXPORT_SYMBOL(drm_gem_simple_kms_end_shadow_fb_access); /** * drm_gem_simple_kms_reset_shadow_plane - resets a shadow-buffered plane |
