summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/ast/ast_cursor.c
diff options
context:
space:
mode:
authorThomas Zimmermann <tzimmermann@suse.de>2020-07-02 13:50:18 +0200
committerThomas Zimmermann <tzimmermann@suse.de>2020-07-07 11:11:24 +0200
commitdd004b9a5505f9810f66a9ddfbdf02978703f1f6 (patch)
treeb0b664d2af93fa1111df0764ed77f3e5ac3aeba9 /drivers/gpu/drm/ast/ast_cursor.c
parentbeb2355eecbf67d2fce79af73215c875173d9990 (diff)
downloadlinux-dd004b9a5505f9810f66a9ddfbdf02978703f1f6.tar.gz
drm/ast: Move cursor fb pinning and mapping into helper
The new helper ast_cursor_blit() updates a cursor's backbuffer HW BO from a framebuffer structure. The cursor plane's prepare_fb() function now uses the new interface. Pinning and mapping of BOs is done automatically by the helper. This includes the source BO, which was not pinned by the original code in prepare_fb(). Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Sam Ravnborg <sam@ravnborg.org> Link: https://patchwork.freedesktop.org/patch/msgid/20200702115029.5281-4-tzimmermann@suse.de
Diffstat (limited to 'drivers/gpu/drm/ast/ast_cursor.c')
-rw-r--r--drivers/gpu/drm/ast/ast_cursor.c57
1 files changed, 55 insertions, 2 deletions
diff --git a/drivers/gpu/drm/ast/ast_cursor.c b/drivers/gpu/drm/ast/ast_cursor.c
index 1d4f51a7fe22..8f94d4712f66 100644
--- a/drivers/gpu/drm/ast/ast_cursor.c
+++ b/drivers/gpu/drm/ast/ast_cursor.c
@@ -140,8 +140,8 @@ static u32 copy_cursor_image(u8 *src, u8 *dst, int width, int height)
return csum;
}
-int ast_cursor_update(void *dst, void *src, unsigned int width,
- unsigned int height)
+static int ast_cursor_update(void *dst, void *src, unsigned int width,
+ unsigned int height)
{
u32 csum;
@@ -159,6 +159,59 @@ int ast_cursor_update(void *dst, void *src, unsigned int width,
return 0;
}
+int ast_cursor_blit(struct ast_private *ast, struct drm_framebuffer *fb)
+{
+ struct drm_device *dev = ast->dev;
+ struct drm_gem_vram_object *gbo;
+ int ret;
+ void *src;
+ void *dst;
+
+ if (drm_WARN_ON_ONCE(dev, fb->width > AST_MAX_HWC_WIDTH) ||
+ drm_WARN_ON_ONCE(dev, fb->height > AST_MAX_HWC_HEIGHT))
+ return -EINVAL;
+
+ gbo = drm_gem_vram_of_gem(fb->obj[0]);
+
+ ret = drm_gem_vram_pin(gbo, 0);
+ if (ret)
+ return ret;
+ src = drm_gem_vram_vmap(gbo);
+ if (IS_ERR(src)) {
+ ret = PTR_ERR(src);
+ goto err_drm_gem_vram_unpin;
+ }
+
+ dst = drm_gem_vram_vmap(ast->cursor.gbo[ast->cursor.next_index]);
+ if (IS_ERR(dst)) {
+ ret = PTR_ERR(dst);
+ goto err_drm_gem_vram_vunmap_src;
+ }
+
+ ret = ast_cursor_update(dst, src, fb->width, fb->height);
+ if (ret)
+ goto err_drm_gem_vram_vunmap_dst;
+
+ /*
+ * Always unmap buffers here. Destination buffers are
+ * perma-pinned while the driver is active. We're only
+ * changing ref-counters here.
+ */
+ drm_gem_vram_vunmap(ast->cursor.gbo[ast->cursor.next_index], dst);
+ drm_gem_vram_vunmap(gbo, src);
+ drm_gem_vram_unpin(gbo);
+
+ return 0;
+
+err_drm_gem_vram_vunmap_dst:
+ drm_gem_vram_vunmap(ast->cursor.gbo[ast->cursor.next_index], dst);
+err_drm_gem_vram_vunmap_src:
+ drm_gem_vram_vunmap(gbo, src);
+err_drm_gem_vram_unpin:
+ drm_gem_vram_unpin(gbo);
+ return ret;
+}
+
void ast_cursor_set_base(struct ast_private *ast, u64 address)
{
u8 addr0 = (address >> 3) & 0xff;