Commit 681a2c5d authored by Thomas Zimmermann's avatar Thomas Zimmermann

drm/cirrus: Move vmap out of commit tail

Vmap operations may acquire the dmabuf reservation lock, which is not
allowed within atomic commit-tail functions. Therefore move vmap and
vunmap from the damage handler into prepare_fb and cleanup_fb callbacks.

The mapping is provided as GEM shadow-buffered plane. The functions in
the commit tail use the pre-established mapping for damage handling.
Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Tested-by: default avatarGerd Hoffmann <kraxel@redhat.com>
Acked-by: default avatarGerd Hoffmann <kraxel@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210208115538.6430-6-tzimmermann@suse.de
parent 4862ffae
...@@ -33,8 +33,9 @@ ...@@ -33,8 +33,9 @@
#include <drm/drm_file.h> #include <drm/drm_file.h>
#include <drm/drm_format_helper.h> #include <drm/drm_format_helper.h>
#include <drm/drm_fourcc.h> #include <drm/drm_fourcc.h>
#include <drm/drm_gem_shmem_helper.h> #include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_gem_shmem_helper.h>
#include <drm/drm_ioctl.h> #include <drm/drm_ioctl.h>
#include <drm/drm_managed.h> #include <drm/drm_managed.h>
#include <drm/drm_modeset_helper_vtables.h> #include <drm/drm_modeset_helper_vtables.h>
...@@ -311,22 +312,15 @@ static int cirrus_mode_set(struct cirrus_device *cirrus, ...@@ -311,22 +312,15 @@ static int cirrus_mode_set(struct cirrus_device *cirrus,
return 0; return 0;
} }
static int cirrus_fb_blit_rect(struct drm_framebuffer *fb, static int cirrus_fb_blit_rect(struct drm_framebuffer *fb, const struct dma_buf_map *map,
struct drm_rect *rect) struct drm_rect *rect)
{ {
struct cirrus_device *cirrus = to_cirrus(fb->dev); struct cirrus_device *cirrus = to_cirrus(fb->dev);
struct dma_buf_map map; void *vmap = map->vaddr; /* TODO: Use mapping abstraction properly */
void *vmap; int idx;
int idx, ret;
ret = -ENODEV;
if (!drm_dev_enter(&cirrus->dev, &idx)) if (!drm_dev_enter(&cirrus->dev, &idx))
goto out; return -ENODEV;
ret = drm_gem_shmem_vmap(fb->obj[0], &map);
if (ret)
goto out_dev_exit;
vmap = map.vaddr; /* TODO: Use mapping abstraction properly */
if (cirrus->cpp == fb->format->cpp[0]) if (cirrus->cpp == fb->format->cpp[0])
drm_fb_memcpy_dstclip(cirrus->vram, drm_fb_memcpy_dstclip(cirrus->vram,
...@@ -345,16 +339,12 @@ static int cirrus_fb_blit_rect(struct drm_framebuffer *fb, ...@@ -345,16 +339,12 @@ static int cirrus_fb_blit_rect(struct drm_framebuffer *fb,
else else
WARN_ON_ONCE("cpp mismatch"); WARN_ON_ONCE("cpp mismatch");
drm_gem_shmem_vunmap(fb->obj[0], &map);
ret = 0;
out_dev_exit:
drm_dev_exit(idx); drm_dev_exit(idx);
out:
return ret; return 0;
} }
static int cirrus_fb_blit_fullscreen(struct drm_framebuffer *fb) static int cirrus_fb_blit_fullscreen(struct drm_framebuffer *fb, const struct dma_buf_map *map)
{ {
struct drm_rect fullscreen = { struct drm_rect fullscreen = {
.x1 = 0, .x1 = 0,
...@@ -362,7 +352,7 @@ static int cirrus_fb_blit_fullscreen(struct drm_framebuffer *fb) ...@@ -362,7 +352,7 @@ static int cirrus_fb_blit_fullscreen(struct drm_framebuffer *fb)
.y1 = 0, .y1 = 0,
.y2 = fb->height, .y2 = fb->height,
}; };
return cirrus_fb_blit_rect(fb, &fullscreen); return cirrus_fb_blit_rect(fb, map, &fullscreen);
} }
static int cirrus_check_size(int width, int height, static int cirrus_check_size(int width, int height,
...@@ -441,9 +431,10 @@ static void cirrus_pipe_enable(struct drm_simple_display_pipe *pipe, ...@@ -441,9 +431,10 @@ static void cirrus_pipe_enable(struct drm_simple_display_pipe *pipe,
struct drm_plane_state *plane_state) struct drm_plane_state *plane_state)
{ {
struct cirrus_device *cirrus = to_cirrus(pipe->crtc.dev); struct cirrus_device *cirrus = to_cirrus(pipe->crtc.dev);
struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
cirrus_mode_set(cirrus, &crtc_state->mode, plane_state->fb); cirrus_mode_set(cirrus, &crtc_state->mode, plane_state->fb);
cirrus_fb_blit_fullscreen(plane_state->fb); cirrus_fb_blit_fullscreen(plane_state->fb, &shadow_plane_state->map[0]);
} }
static void cirrus_pipe_update(struct drm_simple_display_pipe *pipe, static void cirrus_pipe_update(struct drm_simple_display_pipe *pipe,
...@@ -451,16 +442,15 @@ static void cirrus_pipe_update(struct drm_simple_display_pipe *pipe, ...@@ -451,16 +442,15 @@ static void cirrus_pipe_update(struct drm_simple_display_pipe *pipe,
{ {
struct cirrus_device *cirrus = to_cirrus(pipe->crtc.dev); struct cirrus_device *cirrus = to_cirrus(pipe->crtc.dev);
struct drm_plane_state *state = pipe->plane.state; struct drm_plane_state *state = pipe->plane.state;
struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(state);
struct drm_crtc *crtc = &pipe->crtc; struct drm_crtc *crtc = &pipe->crtc;
struct drm_rect rect; struct drm_rect rect;
if (pipe->plane.state->fb && if (state->fb && cirrus->cpp != cirrus_cpp(state->fb))
cirrus->cpp != cirrus_cpp(pipe->plane.state->fb)) cirrus_mode_set(cirrus, &crtc->mode, state->fb);
cirrus_mode_set(cirrus, &crtc->mode,
pipe->plane.state->fb);
if (drm_atomic_helper_damage_merged(old_state, state, &rect)) if (drm_atomic_helper_damage_merged(old_state, state, &rect))
cirrus_fb_blit_rect(pipe->plane.state->fb, &rect); cirrus_fb_blit_rect(state->fb, &shadow_plane_state->map[0], &rect);
} }
static const struct drm_simple_display_pipe_funcs cirrus_pipe_funcs = { static const struct drm_simple_display_pipe_funcs cirrus_pipe_funcs = {
...@@ -468,6 +458,7 @@ static const struct drm_simple_display_pipe_funcs cirrus_pipe_funcs = { ...@@ -468,6 +458,7 @@ static const struct drm_simple_display_pipe_funcs cirrus_pipe_funcs = {
.check = cirrus_pipe_check, .check = cirrus_pipe_check,
.enable = cirrus_pipe_enable, .enable = cirrus_pipe_enable,
.update = cirrus_pipe_update, .update = cirrus_pipe_update,
DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS,
}; };
static const uint32_t cirrus_formats[] = { static const uint32_t cirrus_formats[] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment