Skip to content

Commit

Permalink
drm/mgag200: Move vmap out of commit tail
Browse files Browse the repository at this point in the history
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: Thomas Zimmermann <tzimmermann@suse.de>
Tested-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210208115538.6430-5-tzimmermann@suse.de
  • Loading branch information
Thomas Zimmermann committed Feb 8, 2021
1 parent 6dd7b6c commit 4862ffa
Showing 1 changed file with 8 additions and 15 deletions.
23 changes: 8 additions & 15 deletions drivers/gpu/drm/mgag200/mgag200_mode.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <drm/drm_damage_helper.h>
#include <drm/drm_format_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_print.h>
Expand Down Expand Up @@ -1549,22 +1550,12 @@ mgag200_simple_display_pipe_mode_valid(struct drm_simple_display_pipe *pipe,

static void
mgag200_handle_damage(struct mga_device *mdev, struct drm_framebuffer *fb,
struct drm_rect *clip)
struct drm_rect *clip, const struct dma_buf_map *map)
{
struct drm_device *dev = &mdev->base;
struct dma_buf_map map;
void *vmap;
int ret;

ret = drm_gem_shmem_vmap(fb->obj[0], &map);
if (drm_WARN_ON(dev, ret))
return; /* BUG: SHMEM BO should always be vmapped */
vmap = map.vaddr; /* TODO: Use mapping abstraction properly */
void *vmap = map->vaddr; /* TODO: Use mapping abstraction properly */

drm_fb_memcpy_dstclip(mdev->vram, vmap, fb, clip);

drm_gem_shmem_vunmap(fb->obj[0], &map);

/* Always scanout image at VRAM offset 0 */
mgag200_set_startadd(mdev, (u32)0);
mgag200_set_offset(mdev, fb);
Expand All @@ -1580,6 +1571,7 @@ mgag200_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
struct mga_device *mdev = to_mga_device(dev);
struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
struct drm_framebuffer *fb = plane_state->fb;
struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
struct drm_rect fullscreen = {
.x1 = 0,
.x2 = fb->width,
Expand Down Expand Up @@ -1608,7 +1600,7 @@ mgag200_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
mga_crtc_load_lut(crtc);
mgag200_enable_display(mdev);

mgag200_handle_damage(mdev, fb, &fullscreen);
mgag200_handle_damage(mdev, fb, &fullscreen, &shadow_plane_state->map[0]);
}

static void
Expand Down Expand Up @@ -1649,14 +1641,15 @@ mgag200_simple_display_pipe_update(struct drm_simple_display_pipe *pipe,
struct drm_device *dev = plane->dev;
struct mga_device *mdev = to_mga_device(dev);
struct drm_plane_state *state = plane->state;
struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(state);
struct drm_framebuffer *fb = state->fb;
struct drm_rect damage;

if (!fb)
return;

if (drm_atomic_helper_damage_merged(old_state, state, &damage))
mgag200_handle_damage(mdev, fb, &damage);
mgag200_handle_damage(mdev, fb, &damage, &shadow_plane_state->map[0]);
}

static const struct drm_simple_display_pipe_funcs
Expand All @@ -1666,7 +1659,7 @@ mgag200_simple_display_pipe_funcs = {
.disable = mgag200_simple_display_pipe_disable,
.check = mgag200_simple_display_pipe_check,
.update = mgag200_simple_display_pipe_update,
.prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS,
};

static const uint32_t mgag200_simple_display_pipe_formats[] = {
Expand Down

0 comments on commit 4862ffa

Please sign in to comment.