diff options
Diffstat (limited to 'drivers/gpu/drm/drm_gem_atomic_helper.c')
| -rw-r--r-- | drivers/gpu/drm/drm_gem_atomic_helper.c | 97 | 
1 files changed, 59 insertions, 38 deletions
diff --git a/drivers/gpu/drm/drm_gem_atomic_helper.c b/drivers/gpu/drm/drm_gem_atomic_helper.c index a27135084ae5..e570398abd78 100644 --- a/drivers/gpu/drm/drm_gem_atomic_helper.c +++ b/drivers/gpu/drm/drm_gem_atomic_helper.c @@ -52,7 +52,7 @@   *   * The helpers for shadow-buffered planes establish and release mappings,   * and provide struct drm_shadow_plane_state, which stores the plane's mapping - * for commit-tail functons. + * for commit-tail functions.   *   * Shadow-buffered planes can easily be enabled by using the provided macros   * %DRM_GEM_SHADOW_PLANE_FUNCS and %DRM_GEM_SHADOW_PLANE_HELPER_FUNCS. @@ -135,6 +135,9 @@   * GEM based framebuffer drivers which have their buffers always pinned in   * memory.   * + * This function is the default implementation for GEM drivers of + * &drm_plane_helper_funcs.prepare_fb if no callback is provided. + *   * See drm_atomic_set_fence_for_plane() for a discussion of implicit and   * explicit fencing in atomic modeset updates.   */ @@ -180,6 +183,27 @@ EXPORT_SYMBOL(drm_gem_simple_display_pipe_prepare_fb);   */  /** + * __drm_gem_duplicate_shadow_plane_state - duplicates shadow-buffered plane state + * @plane: the plane + * @new_shadow_plane_state: the new shadow-buffered plane state + * + * This function duplicates shadow-buffered plane state. This is helpful for drivers + * that subclass struct drm_shadow_plane_state. + * + * The function does not duplicate existing mappings of the shadow buffers. + * Mappings are maintained during the atomic commit by the plane's prepare_fb + * and cleanup_fb helpers. See drm_gem_prepare_shadow_fb() and drm_gem_cleanup_shadow_fb() + * for corresponding helpers. + */ +void +__drm_gem_duplicate_shadow_plane_state(struct drm_plane *plane, +				       struct drm_shadow_plane_state *new_shadow_plane_state) +{ +	__drm_atomic_helper_plane_duplicate_state(plane, &new_shadow_plane_state->base); +} +EXPORT_SYMBOL(__drm_gem_duplicate_shadow_plane_state); + +/**   * drm_gem_duplicate_shadow_plane_state - duplicates shadow-buffered plane state   * @plane: the plane   * @@ -208,13 +232,26 @@ drm_gem_duplicate_shadow_plane_state(struct drm_plane *plane)  	new_shadow_plane_state = kzalloc(sizeof(*new_shadow_plane_state), GFP_KERNEL);  	if (!new_shadow_plane_state)  		return NULL; -	__drm_atomic_helper_plane_duplicate_state(plane, &new_shadow_plane_state->base); +	__drm_gem_duplicate_shadow_plane_state(plane, new_shadow_plane_state);  	return &new_shadow_plane_state->base;  }  EXPORT_SYMBOL(drm_gem_duplicate_shadow_plane_state);  /** + * __drm_gem_destroy_shadow_plane_state - cleans up shadow-buffered plane state + * @shadow_plane_state: the shadow-buffered plane state + * + * This function cleans up shadow-buffered plane state. Helpful for drivers that + * subclass struct drm_shadow_plane_state. + */ +void __drm_gem_destroy_shadow_plane_state(struct drm_shadow_plane_state *shadow_plane_state) +{ +	__drm_atomic_helper_plane_destroy_state(&shadow_plane_state->base); +} +EXPORT_SYMBOL(__drm_gem_destroy_shadow_plane_state); + +/**   * drm_gem_destroy_shadow_plane_state - deletes shadow-buffered plane state   * @plane: the plane   * @plane_state: the plane state of type struct drm_shadow_plane_state @@ -229,12 +266,27 @@ void drm_gem_destroy_shadow_plane_state(struct drm_plane *plane,  	struct drm_shadow_plane_state *shadow_plane_state =  		to_drm_shadow_plane_state(plane_state); -	__drm_atomic_helper_plane_destroy_state(&shadow_plane_state->base); +	__drm_gem_destroy_shadow_plane_state(shadow_plane_state);  	kfree(shadow_plane_state);  }  EXPORT_SYMBOL(drm_gem_destroy_shadow_plane_state);  /** + * __drm_gem_reset_shadow_plane - resets a shadow-buffered plane + * @plane: the plane + * @shadow_plane_state: the shadow-buffered plane state + * + * This function resets state for shadow-buffered planes. Helpful + * for drivers that subclass struct drm_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); +} +EXPORT_SYMBOL(__drm_gem_reset_shadow_plane); + +/**   * drm_gem_reset_shadow_plane - resets a shadow-buffered plane   * @plane: the plane   * @@ -255,7 +307,7 @@ 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_atomic_helper_plane_reset(plane, &shadow_plane_state->base); +	__drm_gem_reset_shadow_plane(plane, shadow_plane_state);  }  EXPORT_SYMBOL(drm_gem_reset_shadow_plane); @@ -278,10 +330,7 @@ int drm_gem_prepare_shadow_fb(struct drm_plane *plane, struct drm_plane_state *p  {  	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);  	struct drm_framebuffer *fb = plane_state->fb; -	struct drm_gem_object *obj; -	struct dma_buf_map map;  	int ret; -	size_t i;  	if (!fb)  		return 0; @@ -290,27 +339,7 @@ int drm_gem_prepare_shadow_fb(struct drm_plane *plane, struct drm_plane_state *p  	if (ret)  		return ret; -	for (i = 0; i < ARRAY_SIZE(shadow_plane_state->map); ++i) { -		obj = drm_gem_fb_get_obj(fb, i); -		if (!obj) -			continue; -		ret = drm_gem_vmap(obj, &map); -		if (ret) -			goto err_drm_gem_vunmap; -		shadow_plane_state->map[i] = map; -	} - -	return 0; - -err_drm_gem_vunmap: -	while (i) { -		--i; -		obj = drm_gem_fb_get_obj(fb, i); -		if (!obj) -			continue; -		drm_gem_vunmap(obj, &shadow_plane_state->map[i]); -	} -	return ret; +	return drm_gem_fb_vmap(fb, shadow_plane_state->map, shadow_plane_state->data);  }  EXPORT_SYMBOL(drm_gem_prepare_shadow_fb); @@ -322,25 +351,17 @@ EXPORT_SYMBOL(drm_gem_prepare_shadow_fb);   * This function implements struct &drm_plane_helper_funcs.cleanup_fb.   * This function unmaps all buffer objects of the plane's framebuffer.   * - * See drm_gem_prepare_shadow_fb() for more inforamtion. + * See drm_gem_prepare_shadow_fb() for more information.   */  void drm_gem_cleanup_shadow_fb(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; -	size_t i = ARRAY_SIZE(shadow_plane_state->map); -	struct drm_gem_object *obj;  	if (!fb)  		return; -	while (i) { -		--i; -		obj = drm_gem_fb_get_obj(fb, i); -		if (!obj) -			continue; -		drm_gem_vunmap(obj, &shadow_plane_state->map[i]); -	} +	drm_gem_fb_vunmap(fb, shadow_plane_state->map);  }  EXPORT_SYMBOL(drm_gem_cleanup_shadow_fb);  |