Commit 84810d6a authored by Thomas Zimmermann's avatar Thomas Zimmermann

drm/ast: Map HW cursor BOs permanently

The BOs of the hardware cursor are now mapped permanently while the
cursor plane is being used. This reduces the CPU overhead of the cursor
plane's atomic_update function.

The change also resolves a problem with the vmap call in the commit tail.
The vmap implementation could acquire the DMA reservation lock on the
BO, which is not allowed that late in the atomic update. Removing the
vmap call from atomic_update fixes the issue.
Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Acked-by: default avatarGerd Hoffmann <kraxel@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210209134632.12157-9-tzimmermann@suse.de
parent afee7e95
...@@ -107,6 +107,7 @@ struct ast_cursor_plane { ...@@ -107,6 +107,7 @@ struct ast_cursor_plane {
struct { struct {
struct drm_gem_vram_object *gbo; struct drm_gem_vram_object *gbo;
struct dma_buf_map map;
} hwc[AST_DEFAULT_HWC_NUM]; } hwc[AST_DEFAULT_HWC_NUM];
unsigned int next_hwc_index; unsigned int next_hwc_index;
......
...@@ -759,10 +759,10 @@ ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane, ...@@ -759,10 +759,10 @@ ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane,
{ {
struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane); struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane);
struct drm_framebuffer *fb = new_state->fb; struct drm_framebuffer *fb = new_state->fb;
struct drm_gem_vram_object *dst_gbo = struct dma_buf_map dst_map =
ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].gbo; ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].map;
struct drm_gem_vram_object *src_gbo; struct drm_gem_vram_object *src_gbo;
struct dma_buf_map src_map, dst_map; struct dma_buf_map src_map;
void __iomem *dst; void __iomem *dst;
void *src; void *src;
int ret; int ret;
...@@ -777,22 +777,14 @@ ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane, ...@@ -777,22 +777,14 @@ ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane,
return ret; return ret;
src = src_map.vaddr; /* TODO: Use mapping abstraction properly */ src = src_map.vaddr; /* TODO: Use mapping abstraction properly */
ret = drm_gem_vram_vmap(dst_gbo, &dst_map);
if (ret)
goto err_drm_gem_vram_vunmap;
dst = dst_map.vaddr_iomem; /* TODO: Use mapping abstraction properly */ dst = dst_map.vaddr_iomem; /* TODO: Use mapping abstraction properly */
/* do data transfer to cursor BO */ /* do data transfer to cursor BO */
ast_update_cursor_image(dst, src, fb->width, fb->height); ast_update_cursor_image(dst, src, fb->width, fb->height);
drm_gem_vram_vunmap(dst_gbo, &dst_map);
drm_gem_vram_vunmap(src_gbo, &src_map); drm_gem_vram_vunmap(src_gbo, &src_map);
return 0; return 0;
err_drm_gem_vram_vunmap:
drm_gem_vram_vunmap(src_gbo, &src_map);
return ret;
} }
static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane, static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane,
...@@ -841,9 +833,9 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, ...@@ -841,9 +833,9 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
u8 x_offset, y_offset; u8 x_offset, y_offset;
u8 __iomem *dst; u8 __iomem *dst;
u8 __iomem *sig; u8 __iomem *sig;
int ret;
gbo = ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].gbo; gbo = ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].gbo;
map = ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].map;
if (state->fb != old_state->fb) { if (state->fb != old_state->fb) {
/* A new cursor image was installed. */ /* A new cursor image was installed. */
...@@ -856,17 +848,12 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, ...@@ -856,17 +848,12 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
ast_cursor_plane->next_hwc_index %= ARRAY_SIZE(ast_cursor_plane->hwc); ast_cursor_plane->next_hwc_index %= ARRAY_SIZE(ast_cursor_plane->hwc);
} }
ret = drm_gem_vram_vmap(gbo, &map);
if (drm_WARN_ONCE(dev, ret, "drm_gem_vram_vmap() failed, ret=%d\n", ret))
return;
dst = map.vaddr_iomem; /* TODO: Use mapping abstraction properly */ dst = map.vaddr_iomem; /* TODO: Use mapping abstraction properly */
sig = dst + AST_HWC_SIZE; sig = dst + AST_HWC_SIZE;
writel(state->crtc_x, sig + AST_HWC_SIGNATURE_X); writel(state->crtc_x, sig + AST_HWC_SIGNATURE_X);
writel(state->crtc_y, sig + AST_HWC_SIGNATURE_Y); writel(state->crtc_y, sig + AST_HWC_SIGNATURE_Y);
drm_gem_vram_vunmap(gbo, &map);
offset_x = AST_MAX_HWC_WIDTH - fb->width; offset_x = AST_MAX_HWC_WIDTH - fb->width;
offset_y = AST_MAX_HWC_HEIGHT - fb->height; offset_y = AST_MAX_HWC_HEIGHT - fb->height;
...@@ -913,9 +900,12 @@ static void ast_cursor_plane_destroy(struct drm_plane *plane) ...@@ -913,9 +900,12 @@ static void ast_cursor_plane_destroy(struct drm_plane *plane)
struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane); struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane);
size_t i; size_t i;
struct drm_gem_vram_object *gbo; struct drm_gem_vram_object *gbo;
struct dma_buf_map map;
for (i = 0; i < ARRAY_SIZE(ast_cursor_plane->hwc); ++i) { for (i = 0; i < ARRAY_SIZE(ast_cursor_plane->hwc); ++i) {
gbo = ast_cursor_plane->hwc[i].gbo; gbo = ast_cursor_plane->hwc[i].gbo;
map = ast_cursor_plane->hwc[i].map;
drm_gem_vram_vunmap(gbo, &map);
drm_gem_vram_unpin(gbo); drm_gem_vram_unpin(gbo);
drm_gem_vram_put(gbo); drm_gem_vram_put(gbo);
} }
...@@ -939,6 +929,7 @@ static int ast_cursor_plane_init(struct ast_private *ast) ...@@ -939,6 +929,7 @@ static int ast_cursor_plane_init(struct ast_private *ast)
struct drm_plane *cursor_plane = &ast_cursor_plane->base; struct drm_plane *cursor_plane = &ast_cursor_plane->base;
size_t size, i; size_t size, i;
struct drm_gem_vram_object *gbo; struct drm_gem_vram_object *gbo;
struct dma_buf_map map;
int ret; int ret;
/* /*
...@@ -958,7 +949,11 @@ static int ast_cursor_plane_init(struct ast_private *ast) ...@@ -958,7 +949,11 @@ static int ast_cursor_plane_init(struct ast_private *ast)
DRM_GEM_VRAM_PL_FLAG_TOPDOWN); DRM_GEM_VRAM_PL_FLAG_TOPDOWN);
if (ret) if (ret)
goto err_drm_gem_vram_put; goto err_drm_gem_vram_put;
ret = drm_gem_vram_vmap(gbo, &map);
if (ret)
goto err_drm_gem_vram_unpin;
ast_cursor_plane->hwc[i].gbo = gbo; ast_cursor_plane->hwc[i].gbo = gbo;
ast_cursor_plane->hwc[i].map = map;
} }
/* /*
...@@ -983,6 +978,9 @@ static int ast_cursor_plane_init(struct ast_private *ast) ...@@ -983,6 +978,9 @@ static int ast_cursor_plane_init(struct ast_private *ast)
while (i) { while (i) {
--i; --i;
gbo = ast_cursor_plane->hwc[i].gbo; gbo = ast_cursor_plane->hwc[i].gbo;
map = ast_cursor_plane->hwc[i].map;
drm_gem_vram_vunmap(gbo, &map);
err_drm_gem_vram_unpin:
drm_gem_vram_unpin(gbo); drm_gem_vram_unpin(gbo);
err_drm_gem_vram_put: err_drm_gem_vram_put:
drm_gem_vram_put(gbo); drm_gem_vram_put(gbo);
......
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