All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/10] drm/ast: Clean-up cursor-plane updates
@ 2021-02-09 13:46 Thomas Zimmermann
  2021-02-09 13:46 ` [PATCH v2 01/10] drm/ast: Add constants for VGACRCB register bits Thomas Zimmermann
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Thomas Zimmermann @ 2021-02-09 13:46 UTC (permalink / raw)
  To: airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

(was: drm/ast: Move cursor vmap calls out of commit tail)

Ast has vmap calls in its cursor's atomic_update function. This is not
supported as vmap might aquire the dma reservation lock. While at it,
cleanup the whole cursor code: the patchset removes all possible runtime
errors from the atomic_update function and reduces the overhead from
vmap calls on the HW cursor BOs to a minimum.

Patches 1 to 3 update the cursor code and prepare before the refactoring.

Patch 4 and 5 inline the cursor update logic into the rsp cursor-plane
functions. This is mostly about moving code around.

Patches 6 to 9 add a dedicated cursor plane that maintains the two BOs
for HW cursors. The HW cursor BOs are permanently pinned and vmapped
while the cursor plane is initialized. Thus removing the related vmap
operations from atomic_update.

Finally patch 10 converts ast cursors to struct drm_shadow_plane_state.
BOs with cursor image data from userspace are vmapped in prepare_fb and
vunampped in cleanup_fb. The actual update of the cursor image is being
moved from prepare_fb to atomic_update.

With the patchset applied, all cursor preparation is performed before
the commit-tail functions; while the actual update is performed within.

Tested by running X11 and Weston on ast hardware.

v2:
	* convert to drm_shadow_plane_state helpers

Thomas Zimmermann (10):
  drm/ast: Add constants for VGACRCB register bits
  drm/ast: Fix invalid usage of AST_MAX_HWC_WIDTH in cursor atomic_check
  drm/ast: Initialize planes in helper functions
  drm/ast: Allocate HW cursor BOs during cursor-plane initialization
  drm/ast: Inline ast cursor-update functions into modesetting code
  drm/ast: Add cursor-plane data structure
  drm/ast: Store cursor BOs in cursor plane
  drm/ast: Map HW cursor BOs permanently
  drm/ast: Store each HW cursor offset after pinning the rsp BO
  drm/ast: Move all of the cursor-update functionality to atomic_update

 drivers/gpu/drm/ast/Makefile     |   3 +-
 drivers/gpu/drm/ast/ast_cursor.c | 286 --------------------------
 drivers/gpu/drm/ast/ast_drv.h    |  47 +++--
 drivers/gpu/drm/ast/ast_mode.c   | 334 +++++++++++++++++++++++++------
 4 files changed, 312 insertions(+), 358 deletions(-)
 delete mode 100644 drivers/gpu/drm/ast/ast_cursor.c

--
2.30.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 01/10] drm/ast: Add constants for VGACRCB register bits
  2021-02-09 13:46 [PATCH v2 00/10] drm/ast: Clean-up cursor-plane updates Thomas Zimmermann
@ 2021-02-09 13:46 ` Thomas Zimmermann
  2021-02-09 13:46 ` [PATCH v2 02/10] drm/ast: Fix invalid usage of AST_MAX_HWC_WIDTH in cursor atomic_check Thomas Zimmermann
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Thomas Zimmermann @ 2021-02-09 13:46 UTC (permalink / raw)
  To: airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

Set the bits in VGACRCB with constants. Alo move the rsp code into a
helper function.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/ast/ast_cursor.c | 21 +++++++++++++++------
 drivers/gpu/drm/ast/ast_drv.h    |  3 +++
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/ast/ast_cursor.c b/drivers/gpu/drm/ast/ast_cursor.c
index fac1ee79c372..024858371f64 100644
--- a/drivers/gpu/drm/ast/ast_cursor.c
+++ b/drivers/gpu/drm/ast/ast_cursor.c
@@ -236,6 +236,19 @@ static void ast_cursor_set_location(struct ast_private *ast, u16 x, u16 y,
 	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, y1);
 }
 
+static void ast_set_cursor_enabled(struct ast_private *ast, bool enabled)
+{
+	static const u8 mask = (u8)~(AST_IO_VGACRCB_HWC_16BPP |
+				     AST_IO_VGACRCB_HWC_ENABLED);
+
+	u8 vgacrcb = AST_IO_VGACRCB_HWC_16BPP;
+
+	if (enabled)
+		vgacrcb |= AST_IO_VGACRCB_HWC_ENABLED;
+
+	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, mask, vgacrcb);
+}
+
 void ast_cursor_show(struct ast_private *ast, int x, int y,
 		     unsigned int offset_x, unsigned int offset_y)
 {
@@ -245,7 +258,6 @@ void ast_cursor_show(struct ast_private *ast, int x, int y,
 	u8 x_offset, y_offset;
 	u8 __iomem *dst;
 	u8 __iomem *sig;
-	u8 jreg;
 	int ret;
 
 	ret = drm_gem_vram_vmap(gbo, &map);
@@ -274,13 +286,10 @@ void ast_cursor_show(struct ast_private *ast, int x, int y,
 
 	ast_cursor_set_location(ast, x, y, x_offset, y_offset);
 
-	/* dummy write to fire HWC */
-	jreg = 0x02 |
-	       0x01; /* enable ARGB4444 cursor */
-	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, jreg);
+	ast_set_cursor_enabled(ast, true); /* dummy write to fire HWC */
 }
 
 void ast_cursor_hide(struct ast_private *ast)
 {
-	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, 0x00);
+	ast_set_cursor_enabled(ast, false);
 }
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index f871fc36c2f7..1575e8e636d7 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -179,6 +179,9 @@ struct ast_private *ast_device_create(const struct drm_driver *drv,
 
 #define AST_IO_VGAIR1_VREFRESH		BIT(3)
 
+#define AST_IO_VGACRCB_HWC_ENABLED     BIT(1)
+#define AST_IO_VGACRCB_HWC_16BPP       BIT(0) /* set: ARGB4444, cleared: 2bpp palette */
+
 #define __ast_read(x) \
 static inline u##x ast_read##x(struct ast_private *ast, u32 reg) { \
 u##x val = 0;\
-- 
2.30.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 02/10] drm/ast: Fix invalid usage of AST_MAX_HWC_WIDTH in cursor atomic_check
  2021-02-09 13:46 [PATCH v2 00/10] drm/ast: Clean-up cursor-plane updates Thomas Zimmermann
  2021-02-09 13:46 ` [PATCH v2 01/10] drm/ast: Add constants for VGACRCB register bits Thomas Zimmermann
@ 2021-02-09 13:46 ` Thomas Zimmermann
  2021-02-09 13:46 ` [PATCH v2 03/10] drm/ast: Initialize planes in helper functions Thomas Zimmermann
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Thomas Zimmermann @ 2021-02-09 13:46 UTC (permalink / raw)
  To: airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

Use AST_MAX_HWC_HEIGHT for setting offset_y in the cursor plane's
atomic_check. The code used AST_MAX_HWC_WIDTH instead. This worked
because both constants has the same value.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/ast/ast_mode.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 988b270fea5e..758c69aa7232 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -688,7 +688,7 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
 	unsigned int offset_x, offset_y;
 
 	offset_x = AST_MAX_HWC_WIDTH - fb->width;
-	offset_y = AST_MAX_HWC_WIDTH - fb->height;
+	offset_y = AST_MAX_HWC_HEIGHT - fb->height;
 
 	if (state->fb != old_state->fb) {
 		/* A new cursor image was installed. */
-- 
2.30.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 03/10] drm/ast: Initialize planes in helper functions
  2021-02-09 13:46 [PATCH v2 00/10] drm/ast: Clean-up cursor-plane updates Thomas Zimmermann
  2021-02-09 13:46 ` [PATCH v2 01/10] drm/ast: Add constants for VGACRCB register bits Thomas Zimmermann
  2021-02-09 13:46 ` [PATCH v2 02/10] drm/ast: Fix invalid usage of AST_MAX_HWC_WIDTH in cursor atomic_check Thomas Zimmermann
@ 2021-02-09 13:46 ` Thomas Zimmermann
  2021-02-09 13:46 ` [PATCH v2 04/10] drm/ast: Allocate HW cursor BOs during cursor-plane initialization Thomas Zimmermann
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Thomas Zimmermann @ 2021-02-09 13:46 UTC (permalink / raw)
  To: airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

This change will help with inlining cursor functions into modesetting
code. The primary plane's field used to be cleared with memset(). This
has been dropped as the memory is always allocated with kzalloc().

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/ast/ast_mode.c | 66 +++++++++++++++++++++++-----------
 1 file changed, 45 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 758c69aa7232..f86773a869f0 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -621,6 +621,26 @@ static const struct drm_plane_funcs ast_primary_plane_funcs = {
 	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
 };
 
+static int ast_primary_plane_init(struct ast_private *ast)
+{
+	struct drm_device *dev = &ast->base;
+	struct drm_plane *primary_plane = &ast->primary_plane;
+	int ret;
+
+	ret = drm_universal_plane_init(dev, primary_plane, 0x01,
+				       &ast_primary_plane_funcs,
+				       ast_primary_plane_formats,
+				       ARRAY_SIZE(ast_primary_plane_formats),
+				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
+	if (ret) {
+		drm_err(dev, "drm_universal_plane_init() failed: %d\n", ret);
+		return ret;
+	}
+	drm_plane_helper_add(primary_plane, &ast_primary_plane_helper_funcs);
+
+	return 0;
+}
+
 /*
  * Cursor plane
  */
@@ -725,6 +745,26 @@ static const struct drm_plane_funcs ast_cursor_plane_funcs = {
 	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
 };
 
+static int ast_cursor_plane_init(struct ast_private *ast)
+{
+	struct drm_device *dev = &ast->base;
+	struct drm_plane *cursor_plane = &ast->cursor_plane;
+	int ret;
+
+	ret = drm_universal_plane_init(dev, cursor_plane, 0x01,
+				       &ast_cursor_plane_funcs,
+				       ast_cursor_plane_formats,
+				       ARRAY_SIZE(ast_cursor_plane_formats),
+				       NULL, DRM_PLANE_TYPE_CURSOR, NULL);
+	if (ret) {
+		drm_err(dev, "drm_universal_plane_failed(): %d\n", ret);
+		return ret;
+	}
+	drm_plane_helper_add(cursor_plane, &ast_cursor_plane_helper_funcs);
+
+	return 0;
+}
+
 /*
  * CRTC
  */
@@ -1138,30 +1178,14 @@ int ast_mode_config_init(struct ast_private *ast)
 
 	dev->mode_config.helper_private = &ast_mode_config_helper_funcs;
 
-	memset(&ast->primary_plane, 0, sizeof(ast->primary_plane));
-	ret = drm_universal_plane_init(dev, &ast->primary_plane, 0x01,
-				       &ast_primary_plane_funcs,
-				       ast_primary_plane_formats,
-				       ARRAY_SIZE(ast_primary_plane_formats),
-				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
-	if (ret) {
-		drm_err(dev, "ast: drm_universal_plane_init() failed: %d\n", ret);
+
+	ret = ast_primary_plane_init(ast);
+	if (ret)
 		return ret;
-	}
-	drm_plane_helper_add(&ast->primary_plane,
-			     &ast_primary_plane_helper_funcs);
 
-	ret = drm_universal_plane_init(dev, &ast->cursor_plane, 0x01,
-				       &ast_cursor_plane_funcs,
-				       ast_cursor_plane_formats,
-				       ARRAY_SIZE(ast_cursor_plane_formats),
-				       NULL, DRM_PLANE_TYPE_CURSOR, NULL);
-	if (ret) {
-		drm_err(dev, "drm_universal_plane_failed(): %d\n", ret);
+	ret = ast_cursor_plane_init(ast);
+	if (ret)
 		return ret;
-	}
-	drm_plane_helper_add(&ast->cursor_plane,
-			     &ast_cursor_plane_helper_funcs);
 
 	ast_crtc_init(dev);
 	ast_encoder_init(dev);
-- 
2.30.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 04/10] drm/ast: Allocate HW cursor BOs during cursor-plane initialization
  2021-02-09 13:46 [PATCH v2 00/10] drm/ast: Clean-up cursor-plane updates Thomas Zimmermann
                   ` (2 preceding siblings ...)
  2021-02-09 13:46 ` [PATCH v2 03/10] drm/ast: Initialize planes in helper functions Thomas Zimmermann
@ 2021-02-09 13:46 ` Thomas Zimmermann
  2021-02-09 13:46 ` [PATCH v2 05/10] drm/ast: Inline ast cursor-update functions into modesetting code Thomas Zimmermann
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Thomas Zimmermann @ 2021-02-09 13:46 UTC (permalink / raw)
  To: airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

The BOs are eventually released by the cursor plane's destroy callback.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/ast/ast_cursor.c | 58 ------------------------------
 drivers/gpu/drm/ast/ast_drv.h    |  1 -
 drivers/gpu/drm/ast/ast_mode.c   | 62 ++++++++++++++++++++++++++++----
 3 files changed, 55 insertions(+), 66 deletions(-)

diff --git a/drivers/gpu/drm/ast/ast_cursor.c b/drivers/gpu/drm/ast/ast_cursor.c
index 024858371f64..31c35296a107 100644
--- a/drivers/gpu/drm/ast/ast_cursor.c
+++ b/drivers/gpu/drm/ast/ast_cursor.c
@@ -32,64 +32,6 @@
 
 #include "ast_drv.h"
 
-static void ast_cursor_fini(struct ast_private *ast)
-{
-	size_t i;
-	struct drm_gem_vram_object *gbo;
-
-	for (i = 0; i < ARRAY_SIZE(ast->cursor.gbo); ++i) {
-		gbo = ast->cursor.gbo[i];
-		drm_gem_vram_unpin(gbo);
-		drm_gem_vram_put(gbo);
-	}
-}
-
-static void ast_cursor_release(struct drm_device *dev, void *ptr)
-{
-	struct ast_private *ast = to_ast_private(dev);
-
-	ast_cursor_fini(ast);
-}
-
-/*
- * Allocate cursor BOs and pin them at the end of VRAM.
- */
-int ast_cursor_init(struct ast_private *ast)
-{
-	struct drm_device *dev = &ast->base;
-	size_t size, i;
-	struct drm_gem_vram_object *gbo;
-	int ret;
-
-	size = roundup(AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE, PAGE_SIZE);
-
-	for (i = 0; i < ARRAY_SIZE(ast->cursor.gbo); ++i) {
-		gbo = drm_gem_vram_create(dev, size, 0);
-		if (IS_ERR(gbo)) {
-			ret = PTR_ERR(gbo);
-			goto err_drm_gem_vram_put;
-		}
-		ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM |
-					    DRM_GEM_VRAM_PL_FLAG_TOPDOWN);
-		if (ret) {
-			drm_gem_vram_put(gbo);
-			goto err_drm_gem_vram_put;
-		}
-		ast->cursor.gbo[i] = gbo;
-	}
-
-	return drmm_add_action_or_reset(dev, ast_cursor_release, NULL);
-
-err_drm_gem_vram_put:
-	while (i) {
-		--i;
-		gbo = ast->cursor.gbo[i];
-		drm_gem_vram_unpin(gbo);
-		drm_gem_vram_put(gbo);
-	}
-	return ret;
-}
-
 static void update_cursor_image(u8 __iomem *dst, const u8 *src, int width, int height)
 {
 	union {
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 1575e8e636d7..c9c3950449b5 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -318,7 +318,6 @@ u8 ast_get_dp501_max_clk(struct drm_device *dev);
 void ast_init_3rdtx(struct drm_device *dev);
 
 /* ast_cursor.c */
-int ast_cursor_init(struct ast_private *ast);
 int ast_cursor_blit(struct ast_private *ast, struct drm_framebuffer *fb);
 void ast_cursor_page_flip(struct ast_private *ast);
 void ast_cursor_show(struct ast_private *ast, int x, int y,
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index f86773a869f0..99b6f7c5cb2f 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -736,10 +736,25 @@ static const struct drm_plane_helper_funcs ast_cursor_plane_helper_funcs = {
 	.atomic_disable = ast_cursor_plane_helper_atomic_disable,
 };
 
+static void ast_cursor_plane_destroy(struct drm_plane *plane)
+{
+	struct ast_private *ast = to_ast_private(plane->dev);
+	size_t i;
+	struct drm_gem_vram_object *gbo;
+
+	for (i = 0; i < ARRAY_SIZE(ast->cursor.gbo); ++i) {
+		gbo = ast->cursor.gbo[i];
+		drm_gem_vram_unpin(gbo);
+		drm_gem_vram_put(gbo);
+	}
+
+	drm_plane_cleanup(plane);
+}
+
 static const struct drm_plane_funcs ast_cursor_plane_funcs = {
 	.update_plane = drm_atomic_helper_update_plane,
 	.disable_plane = drm_atomic_helper_disable_plane,
-	.destroy = drm_plane_cleanup,
+	.destroy = ast_cursor_plane_destroy,
 	.reset = drm_atomic_helper_plane_reset,
 	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -749,20 +764,57 @@ static int ast_cursor_plane_init(struct ast_private *ast)
 {
 	struct drm_device *dev = &ast->base;
 	struct drm_plane *cursor_plane = &ast->cursor_plane;
+	size_t size, i;
+	struct drm_gem_vram_object *gbo;
 	int ret;
 
+	/*
+	 * Allocate backing storage for cursors. The BOs are permanently
+	 * pinned to the top end of the VRAM.
+	 */
+
+	size = roundup(AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE, PAGE_SIZE);
+
+	for (i = 0; i < ARRAY_SIZE(ast->cursor.gbo); ++i) {
+		gbo = drm_gem_vram_create(dev, size, 0);
+		if (IS_ERR(gbo)) {
+			ret = PTR_ERR(gbo);
+			goto err_hwc;
+		}
+		ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM |
+					    DRM_GEM_VRAM_PL_FLAG_TOPDOWN);
+		if (ret)
+			goto err_drm_gem_vram_put;
+		ast->cursor.gbo[i] = gbo;
+	}
+
+	/*
+	 * Create the cursor plane. The plane's destroy callback will release
+	 * the backing storages' BO memory.
+	 */
+
 	ret = drm_universal_plane_init(dev, cursor_plane, 0x01,
 				       &ast_cursor_plane_funcs,
 				       ast_cursor_plane_formats,
 				       ARRAY_SIZE(ast_cursor_plane_formats),
 				       NULL, DRM_PLANE_TYPE_CURSOR, NULL);
 	if (ret) {
-		drm_err(dev, "drm_universal_plane_failed(): %d\n", ret);
-		return ret;
+		drm_err(dev, "drm_universal_plane failed(): %d\n", ret);
+		goto err_hwc;
 	}
 	drm_plane_helper_add(cursor_plane, &ast_cursor_plane_helper_funcs);
 
 	return 0;
+
+err_hwc:
+	while (i) {
+		--i;
+		gbo = ast->cursor.gbo[i];
+		drm_gem_vram_unpin(gbo);
+err_drm_gem_vram_put:
+		drm_gem_vram_put(gbo);
+	}
+	return ret;
 }
 
 /*
@@ -1149,10 +1201,6 @@ int ast_mode_config_init(struct ast_private *ast)
 	struct pci_dev *pdev = to_pci_dev(dev->dev);
 	int ret;
 
-	ret = ast_cursor_init(ast);
-	if (ret)
-		return ret;
-
 	ret = drmm_mode_config_init(dev);
 	if (ret)
 		return ret;
-- 
2.30.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 05/10] drm/ast: Inline ast cursor-update functions into modesetting code
  2021-02-09 13:46 [PATCH v2 00/10] drm/ast: Clean-up cursor-plane updates Thomas Zimmermann
                   ` (3 preceding siblings ...)
  2021-02-09 13:46 ` [PATCH v2 04/10] drm/ast: Allocate HW cursor BOs during cursor-plane initialization Thomas Zimmermann
@ 2021-02-09 13:46 ` Thomas Zimmermann
  2021-02-09 13:46 ` [PATCH v2 06/10] drm/ast: Add cursor-plane data structure Thomas Zimmermann
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Thomas Zimmermann @ 2021-02-09 13:46 UTC (permalink / raw)
  To: airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

The logic for cursor updates is now located in the cursor plane's
modesetting code. A number of helper functions remain to modify the
rsp registers and image.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/ast/Makefile     |   3 +-
 drivers/gpu/drm/ast/ast_cursor.c | 237 -------------------------------
 drivers/gpu/drm/ast/ast_drv.h    |   7 -
 drivers/gpu/drm/ast/ast_mode.c   | 191 +++++++++++++++++++++++--
 4 files changed, 181 insertions(+), 257 deletions(-)
 delete mode 100644 drivers/gpu/drm/ast/ast_cursor.c

diff --git a/drivers/gpu/drm/ast/Makefile b/drivers/gpu/drm/ast/Makefile
index 2265a8a624dd..438a2d05b115 100644
--- a/drivers/gpu/drm/ast/Makefile
+++ b/drivers/gpu/drm/ast/Makefile
@@ -3,7 +3,6 @@
 # Makefile for the drm device driver.  This driver provides support for the
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 
-ast-y := ast_cursor.o ast_drv.o ast_main.o ast_mm.o ast_mode.o ast_post.o \
-	 ast_dp501.o
+ast-y := ast_drv.o ast_main.o ast_mm.o ast_mode.o ast_post.o ast_dp501.o
 
 obj-$(CONFIG_DRM_AST) := ast.o
diff --git a/drivers/gpu/drm/ast/ast_cursor.c b/drivers/gpu/drm/ast/ast_cursor.c
deleted file mode 100644
index 31c35296a107..000000000000
--- a/drivers/gpu/drm/ast/ast_cursor.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- * Parts based on xf86-video-ast
- * Copyright (c) 2005 ASPEED Technology Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- */
-/*
- * Authors: Dave Airlie <airlied@redhat.com>
- */
-
-#include <drm/drm_gem_vram_helper.h>
-#include <drm/drm_managed.h>
-
-#include "ast_drv.h"
-
-static void update_cursor_image(u8 __iomem *dst, const u8 *src, int width, int height)
-{
-	union {
-		u32 ul;
-		u8 b[4];
-	} srcdata32[2], data32;
-	union {
-		u16 us;
-		u8 b[2];
-	} data16;
-	u32 csum = 0;
-	s32 alpha_dst_delta, last_alpha_dst_delta;
-	u8 __iomem *dstxor;
-	const u8 *srcxor;
-	int i, j;
-	u32 per_pixel_copy, two_pixel_copy;
-
-	alpha_dst_delta = AST_MAX_HWC_WIDTH << 1;
-	last_alpha_dst_delta = alpha_dst_delta - (width << 1);
-
-	srcxor = src;
-	dstxor = (u8 *)dst + last_alpha_dst_delta + (AST_MAX_HWC_HEIGHT - height) * alpha_dst_delta;
-	per_pixel_copy = width & 1;
-	two_pixel_copy = width >> 1;
-
-	for (j = 0; j < height; j++) {
-		for (i = 0; i < two_pixel_copy; i++) {
-			srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0;
-			srcdata32[1].ul = *((u32 *)(srcxor + 4)) & 0xf0f0f0f0;
-			data32.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4);
-			data32.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4);
-			data32.b[2] = srcdata32[1].b[1] | (srcdata32[1].b[0] >> 4);
-			data32.b[3] = srcdata32[1].b[3] | (srcdata32[1].b[2] >> 4);
-
-			writel(data32.ul, dstxor);
-			csum += data32.ul;
-
-			dstxor += 4;
-			srcxor += 8;
-
-		}
-
-		for (i = 0; i < per_pixel_copy; i++) {
-			srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0;
-			data16.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4);
-			data16.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4);
-			writew(data16.us, dstxor);
-			csum += (u32)data16.us;
-
-			dstxor += 2;
-			srcxor += 4;
-		}
-		dstxor += last_alpha_dst_delta;
-	}
-
-	/* write checksum + signature */
-	dst += AST_HWC_SIZE;
-	writel(csum, dst);
-	writel(width, dst + AST_HWC_SIGNATURE_SizeX);
-	writel(height, dst + AST_HWC_SIGNATURE_SizeY);
-	writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTX);
-	writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTY);
-}
-
-int ast_cursor_blit(struct ast_private *ast, struct drm_framebuffer *fb)
-{
-	struct drm_device *dev = &ast->base;
-	struct drm_gem_vram_object *dst_gbo = ast->cursor.gbo[ast->cursor.next_index];
-	struct drm_gem_vram_object *src_gbo = drm_gem_vram_of_gem(fb->obj[0]);
-	struct dma_buf_map src_map, dst_map;
-	void __iomem *dst;
-	void *src;
-	int ret;
-
-	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;
-
-	ret = drm_gem_vram_vmap(src_gbo, &src_map);
-	if (ret)
-		return ret;
-	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 */
-
-	/* do data transfer to cursor BO */
-	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);
-
-	return 0;
-
-err_drm_gem_vram_vunmap:
-	drm_gem_vram_vunmap(src_gbo, &src_map);
-	return ret;
-}
-
-static void ast_cursor_set_base(struct ast_private *ast, u64 address)
-{
-	u8 addr0 = (address >> 3) & 0xff;
-	u8 addr1 = (address >> 11) & 0xff;
-	u8 addr2 = (address >> 19) & 0xff;
-
-	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc8, addr0);
-	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc9, addr1);
-	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xca, addr2);
-}
-
-void ast_cursor_page_flip(struct ast_private *ast)
-{
-	struct drm_device *dev = &ast->base;
-	struct drm_gem_vram_object *gbo;
-	s64 off;
-
-	gbo = ast->cursor.gbo[ast->cursor.next_index];
-
-	off = drm_gem_vram_offset(gbo);
-	if (drm_WARN_ON_ONCE(dev, off < 0))
-		return; /* Bug: we didn't pin the cursor HW BO to VRAM. */
-
-	ast_cursor_set_base(ast, off);
-
-	++ast->cursor.next_index;
-	ast->cursor.next_index %= ARRAY_SIZE(ast->cursor.gbo);
-}
-
-static void ast_cursor_set_location(struct ast_private *ast, u16 x, u16 y,
-				    u8 x_offset, u8 y_offset)
-{
-	u8 x0 = (x & 0x00ff);
-	u8 x1 = (x & 0x0f00) >> 8;
-	u8 y0 = (y & 0x00ff);
-	u8 y1 = (y & 0x0700) >> 8;
-
-	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc2, x_offset);
-	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc3, y_offset);
-	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc4, x0);
-	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc5, x1);
-	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc6, y0);
-	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, y1);
-}
-
-static void ast_set_cursor_enabled(struct ast_private *ast, bool enabled)
-{
-	static const u8 mask = (u8)~(AST_IO_VGACRCB_HWC_16BPP |
-				     AST_IO_VGACRCB_HWC_ENABLED);
-
-	u8 vgacrcb = AST_IO_VGACRCB_HWC_16BPP;
-
-	if (enabled)
-		vgacrcb |= AST_IO_VGACRCB_HWC_ENABLED;
-
-	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, mask, vgacrcb);
-}
-
-void ast_cursor_show(struct ast_private *ast, int x, int y,
-		     unsigned int offset_x, unsigned int offset_y)
-{
-	struct drm_device *dev = &ast->base;
-	struct drm_gem_vram_object *gbo = ast->cursor.gbo[ast->cursor.next_index];
-	struct dma_buf_map map;
-	u8 x_offset, y_offset;
-	u8 __iomem *dst;
-	u8 __iomem *sig;
-	int ret;
-
-	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 */
-
-	sig = dst + AST_HWC_SIZE;
-	writel(x, sig + AST_HWC_SIGNATURE_X);
-	writel(y, sig + AST_HWC_SIGNATURE_Y);
-
-	drm_gem_vram_vunmap(gbo, &map);
-
-	if (x < 0) {
-		x_offset = (-x) + offset_x;
-		x = 0;
-	} else {
-		x_offset = offset_x;
-	}
-	if (y < 0) {
-		y_offset = (-y) + offset_y;
-		y = 0;
-	} else {
-		y_offset = offset_y;
-	}
-
-	ast_cursor_set_location(ast, x, y, x_offset, y_offset);
-
-	ast_set_cursor_enabled(ast, true); /* dummy write to fire HWC */
-}
-
-void ast_cursor_hide(struct ast_private *ast)
-{
-	ast_set_cursor_enabled(ast, false);
-}
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index c9c3950449b5..2761fa547c35 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -317,11 +317,4 @@ bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata);
 u8 ast_get_dp501_max_clk(struct drm_device *dev);
 void ast_init_3rdtx(struct drm_device *dev);
 
-/* ast_cursor.c */
-int ast_cursor_blit(struct ast_private *ast, struct drm_framebuffer *fb);
-void ast_cursor_page_flip(struct ast_private *ast);
-void ast_cursor_show(struct ast_private *ast, int x, int y,
-		     unsigned int offset_x, unsigned int offset_y);
-void ast_cursor_hide(struct ast_private *ast);
-
 #endif
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 99b6f7c5cb2f..968ee0c69ec3 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -645,6 +645,110 @@ static int ast_primary_plane_init(struct ast_private *ast)
  * Cursor plane
  */
 
+static void ast_update_cursor_image(u8 __iomem *dst, const u8 *src, int width, int height)
+{
+	union {
+		u32 ul;
+		u8 b[4];
+	} srcdata32[2], data32;
+	union {
+		u16 us;
+		u8 b[2];
+	} data16;
+	u32 csum = 0;
+	s32 alpha_dst_delta, last_alpha_dst_delta;
+	u8 __iomem *dstxor;
+	const u8 *srcxor;
+	int i, j;
+	u32 per_pixel_copy, two_pixel_copy;
+
+	alpha_dst_delta = AST_MAX_HWC_WIDTH << 1;
+	last_alpha_dst_delta = alpha_dst_delta - (width << 1);
+
+	srcxor = src;
+	dstxor = (u8 *)dst + last_alpha_dst_delta + (AST_MAX_HWC_HEIGHT - height) * alpha_dst_delta;
+	per_pixel_copy = width & 1;
+	two_pixel_copy = width >> 1;
+
+	for (j = 0; j < height; j++) {
+		for (i = 0; i < two_pixel_copy; i++) {
+			srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0;
+			srcdata32[1].ul = *((u32 *)(srcxor + 4)) & 0xf0f0f0f0;
+			data32.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4);
+			data32.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4);
+			data32.b[2] = srcdata32[1].b[1] | (srcdata32[1].b[0] >> 4);
+			data32.b[3] = srcdata32[1].b[3] | (srcdata32[1].b[2] >> 4);
+
+			writel(data32.ul, dstxor);
+			csum += data32.ul;
+
+			dstxor += 4;
+			srcxor += 8;
+
+		}
+
+		for (i = 0; i < per_pixel_copy; i++) {
+			srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0;
+			data16.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4);
+			data16.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4);
+			writew(data16.us, dstxor);
+			csum += (u32)data16.us;
+
+			dstxor += 2;
+			srcxor += 4;
+		}
+		dstxor += last_alpha_dst_delta;
+	}
+
+	/* write checksum + signature */
+	dst += AST_HWC_SIZE;
+	writel(csum, dst);
+	writel(width, dst + AST_HWC_SIGNATURE_SizeX);
+	writel(height, dst + AST_HWC_SIGNATURE_SizeY);
+	writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTX);
+	writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTY);
+}
+
+static void ast_set_cursor_base(struct ast_private *ast, u64 address)
+{
+	u8 addr0 = (address >> 3) & 0xff;
+	u8 addr1 = (address >> 11) & 0xff;
+	u8 addr2 = (address >> 19) & 0xff;
+
+	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc8, addr0);
+	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc9, addr1);
+	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xca, addr2);
+}
+
+static void ast_set_cursor_location(struct ast_private *ast, u16 x, u16 y,
+				    u8 x_offset, u8 y_offset)
+{
+	u8 x0 = (x & 0x00ff);
+	u8 x1 = (x & 0x0f00) >> 8;
+	u8 y0 = (y & 0x00ff);
+	u8 y1 = (y & 0x0700) >> 8;
+
+	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc2, x_offset);
+	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc3, y_offset);
+	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc4, x0);
+	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc5, x1);
+	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc6, y0);
+	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, y1);
+}
+
+static void ast_set_cursor_enabled(struct ast_private *ast, bool enabled)
+{
+	static const u8 mask = (u8)~(AST_IO_VGACRCB_HWC_16BPP |
+				     AST_IO_VGACRCB_HWC_ENABLED);
+
+	u8 vgacrcb = AST_IO_VGACRCB_HWC_16BPP;
+
+	if (enabled)
+		vgacrcb |= AST_IO_VGACRCB_HWC_ENABLED;
+
+	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, mask, vgacrcb);
+}
+
 static const uint32_t ast_cursor_plane_formats[] = {
 	DRM_FORMAT_ARGB8888,
 };
@@ -654,20 +758,40 @@ ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane,
 				   struct drm_plane_state *new_state)
 {
 	struct drm_framebuffer *fb = new_state->fb;
-	struct drm_crtc *crtc = new_state->crtc;
-	struct ast_private *ast;
+	struct ast_private *ast = to_ast_private(plane->dev);
+	struct drm_gem_vram_object *dst_gbo = ast->cursor.gbo[ast->cursor.next_index];
+	struct drm_gem_vram_object *src_gbo;
+	struct dma_buf_map src_map, dst_map;
+	void __iomem *dst;
+	void *src;
 	int ret;
 
-	if (!crtc || !fb)
+	if (!fb)
 		return 0;
 
-	ast = to_ast_private(plane->dev);
+	src_gbo = drm_gem_vram_of_gem(fb->obj[0]);
 
-	ret = ast_cursor_blit(ast, fb);
+	ret = drm_gem_vram_vmap(src_gbo, &src_map);
 	if (ret)
 		return ret;
+	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 */
+
+	/* do data transfer to cursor BO */
+	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);
 
 	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,
@@ -705,18 +829,63 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
 	struct drm_plane_state *state = plane->state;
 	struct drm_framebuffer *fb = state->fb;
 	struct ast_private *ast = to_ast_private(plane->dev);
+	struct drm_device *dev = &ast->base;
+	struct drm_gem_vram_object *gbo = ast->cursor.gbo[ast->cursor.next_index];
 	unsigned int offset_x, offset_y;
+	s64 off;
+	struct dma_buf_map map;
+	u16 x, y;
+	u8 x_offset, y_offset;
+	u8 __iomem *dst;
+	u8 __iomem *sig;
+	int ret;
 
-	offset_x = AST_MAX_HWC_WIDTH - fb->width;
-	offset_y = AST_MAX_HWC_HEIGHT - fb->height;
+	gbo = ast->cursor.gbo[ast->cursor.next_index];
 
 	if (state->fb != old_state->fb) {
 		/* A new cursor image was installed. */
-		ast_cursor_page_flip(ast);
+		off = drm_gem_vram_offset(gbo);
+		if (drm_WARN_ON_ONCE(dev, off < 0))
+			return; /* Bug: we didn't pin the cursor HW BO to VRAM. */
+		ast_set_cursor_base(ast, off);
+
+		++ast->cursor.next_index;
+		ast->cursor.next_index %= ARRAY_SIZE(ast->cursor.gbo);
+	}
+
+	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 */
+
+	sig = dst + AST_HWC_SIZE;
+	writel(state->crtc_x, sig + AST_HWC_SIGNATURE_X);
+	writel(state->crtc_y, sig + AST_HWC_SIGNATURE_Y);
+
+	drm_gem_vram_vunmap(gbo, &map);
+
+	offset_x = AST_MAX_HWC_WIDTH - fb->width;
+	offset_y = AST_MAX_HWC_HEIGHT - fb->height;
+
+	if (state->crtc_x < 0) {
+		x_offset = (-state->crtc_x) + offset_x;
+		x = 0;
+	} else {
+		x_offset = offset_x;
+		x = state->crtc_x;
 	}
+	if (state->crtc_y < 0) {
+		y_offset = (-state->crtc_y) + offset_y;
+		y = 0;
+	} else {
+		y_offset = offset_y;
+		y = state->crtc_y;
+	}
+
+	ast_set_cursor_location(ast, x, y, x_offset, y_offset);
 
-	ast_cursor_show(ast, state->crtc_x, state->crtc_y,
-			offset_x, offset_y);
+	/* dummy write to fire HWC */
+	ast_set_cursor_enabled(ast, true);
 }
 
 static void
@@ -725,7 +894,7 @@ ast_cursor_plane_helper_atomic_disable(struct drm_plane *plane,
 {
 	struct ast_private *ast = to_ast_private(plane->dev);
 
-	ast_cursor_hide(ast);
+	ast_set_cursor_enabled(ast, false);
 }
 
 static const struct drm_plane_helper_funcs ast_cursor_plane_helper_funcs = {
-- 
2.30.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 06/10] drm/ast: Add cursor-plane data structure
  2021-02-09 13:46 [PATCH v2 00/10] drm/ast: Clean-up cursor-plane updates Thomas Zimmermann
                   ` (4 preceding siblings ...)
  2021-02-09 13:46 ` [PATCH v2 05/10] drm/ast: Inline ast cursor-update functions into modesetting code Thomas Zimmermann
@ 2021-02-09 13:46 ` Thomas Zimmermann
  2021-02-09 13:46 ` [PATCH v2 07/10] drm/ast: Store cursor BOs in cursor plane Thomas Zimmermann
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Thomas Zimmermann @ 2021-02-09 13:46 UTC (permalink / raw)
  To: airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

Cursor state is currently located throughout struct ast_private. Having
struct ast_cursor_plane as dedicated data structure for cursors helps to
organize the modesetting code.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/ast/ast_drv.h  | 23 ++++++++++++++++++++++-
 drivers/gpu/drm/ast/ast_mode.c |  5 +++--
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 2761fa547c35..9eefd3f01f4c 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -81,6 +81,9 @@ enum ast_tx_chip {
 #define AST_DRAM_4Gx16   7
 #define AST_DRAM_8Gx16   8
 
+/*
+ * Cursor plane
+ */
 
 #define AST_MAX_HWC_WIDTH	64
 #define AST_MAX_HWC_HEIGHT	64
@@ -99,6 +102,20 @@ enum ast_tx_chip {
 #define AST_HWC_SIGNATURE_HOTSPOTX	0x14
 #define AST_HWC_SIGNATURE_HOTSPOTY	0x18
 
+struct ast_cursor_plane {
+	struct drm_plane base;
+};
+
+static inline struct ast_cursor_plane *
+to_ast_cursor_plane(struct drm_plane *plane)
+{
+	return container_of(plane, struct ast_cursor_plane, base);
+}
+
+/*
+ * Connector with i2c channel
+ */
+
 struct ast_i2c_chan {
 	struct i2c_adapter adapter;
 	struct drm_device *dev;
@@ -116,6 +133,10 @@ to_ast_connector(struct drm_connector *connector)
 	return container_of(connector, struct ast_connector, base);
 }
 
+/*
+ * Device
+ */
+
 struct ast_private {
 	struct drm_device base;
 
@@ -136,7 +157,7 @@ struct ast_private {
 	} cursor;
 
 	struct drm_plane primary_plane;
-	struct drm_plane cursor_plane;
+	struct ast_cursor_plane cursor_plane;
 	struct drm_crtc crtc;
 	struct drm_encoder encoder;
 	struct ast_connector connector;
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 968ee0c69ec3..9dc70aa62fef 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -932,7 +932,8 @@ static const struct drm_plane_funcs ast_cursor_plane_funcs = {
 static int ast_cursor_plane_init(struct ast_private *ast)
 {
 	struct drm_device *dev = &ast->base;
-	struct drm_plane *cursor_plane = &ast->cursor_plane;
+	struct ast_cursor_plane *ast_cursor_plane = &ast->cursor_plane;
+	struct drm_plane *cursor_plane = &ast_cursor_plane->base;
 	size_t size, i;
 	struct drm_gem_vram_object *gbo;
 	int ret;
@@ -1178,7 +1179,7 @@ static int ast_crtc_init(struct drm_device *dev)
 	int ret;
 
 	ret = drm_crtc_init_with_planes(dev, crtc, &ast->primary_plane,
-					&ast->cursor_plane, &ast_crtc_funcs,
+					&ast->cursor_plane.base, &ast_crtc_funcs,
 					NULL);
 	if (ret)
 		return ret;
-- 
2.30.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 07/10] drm/ast: Store cursor BOs in cursor plane
  2021-02-09 13:46 [PATCH v2 00/10] drm/ast: Clean-up cursor-plane updates Thomas Zimmermann
                   ` (5 preceding siblings ...)
  2021-02-09 13:46 ` [PATCH v2 06/10] drm/ast: Add cursor-plane data structure Thomas Zimmermann
@ 2021-02-09 13:46 ` Thomas Zimmermann
  2021-02-09 13:46 ` [PATCH v2 08/10] drm/ast: Map HW cursor BOs permanently Thomas Zimmermann
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Thomas Zimmermann @ 2021-02-09 13:46 UTC (permalink / raw)
  To: airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

The cursor uses two BOs in video RAM to implement double buffering. Store
both in struct ast_cursor_plane.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/ast/ast_drv.h  | 11 ++++++-----
 drivers/gpu/drm/ast/ast_mode.c | 27 +++++++++++++++------------
 2 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 9eefd3f01f4c..4117c49096d4 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -104,6 +104,12 @@ enum ast_tx_chip {
 
 struct ast_cursor_plane {
 	struct drm_plane base;
+
+	struct {
+		struct drm_gem_vram_object *gbo;
+	} hwc[AST_DEFAULT_HWC_NUM];
+
+	unsigned int next_hwc_index;
 };
 
 static inline struct ast_cursor_plane *
@@ -151,11 +157,6 @@ struct ast_private {
 
 	int fb_mtrr;
 
-	struct {
-		struct drm_gem_vram_object *gbo[AST_DEFAULT_HWC_NUM];
-		unsigned int next_index;
-	} cursor;
-
 	struct drm_plane primary_plane;
 	struct ast_cursor_plane cursor_plane;
 	struct drm_crtc crtc;
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 9dc70aa62fef..dfff30e3d411 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -757,9 +757,10 @@ static int
 ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane,
 				   struct drm_plane_state *new_state)
 {
+	struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane);
 	struct drm_framebuffer *fb = new_state->fb;
-	struct ast_private *ast = to_ast_private(plane->dev);
-	struct drm_gem_vram_object *dst_gbo = ast->cursor.gbo[ast->cursor.next_index];
+	struct drm_gem_vram_object *dst_gbo =
+		ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].gbo;
 	struct drm_gem_vram_object *src_gbo;
 	struct dma_buf_map src_map, dst_map;
 	void __iomem *dst;
@@ -826,11 +827,13 @@ static void
 ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
 				      struct drm_plane_state *old_state)
 {
+	struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane);
 	struct drm_plane_state *state = plane->state;
 	struct drm_framebuffer *fb = state->fb;
 	struct ast_private *ast = to_ast_private(plane->dev);
 	struct drm_device *dev = &ast->base;
-	struct drm_gem_vram_object *gbo = ast->cursor.gbo[ast->cursor.next_index];
+	struct drm_gem_vram_object *gbo =
+		ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].gbo;
 	unsigned int offset_x, offset_y;
 	s64 off;
 	struct dma_buf_map map;
@@ -840,7 +843,7 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
 	u8 __iomem *sig;
 	int ret;
 
-	gbo = ast->cursor.gbo[ast->cursor.next_index];
+	gbo = ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].gbo;
 
 	if (state->fb != old_state->fb) {
 		/* A new cursor image was installed. */
@@ -849,8 +852,8 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
 			return; /* Bug: we didn't pin the cursor HW BO to VRAM. */
 		ast_set_cursor_base(ast, off);
 
-		++ast->cursor.next_index;
-		ast->cursor.next_index %= ARRAY_SIZE(ast->cursor.gbo);
+		++ast_cursor_plane->next_hwc_index;
+		ast_cursor_plane->next_hwc_index %= ARRAY_SIZE(ast_cursor_plane->hwc);
 	}
 
 	ret = drm_gem_vram_vmap(gbo, &map);
@@ -907,12 +910,12 @@ static const struct drm_plane_helper_funcs ast_cursor_plane_helper_funcs = {
 
 static void ast_cursor_plane_destroy(struct drm_plane *plane)
 {
-	struct ast_private *ast = to_ast_private(plane->dev);
+	struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane);
 	size_t i;
 	struct drm_gem_vram_object *gbo;
 
-	for (i = 0; i < ARRAY_SIZE(ast->cursor.gbo); ++i) {
-		gbo = ast->cursor.gbo[i];
+	for (i = 0; i < ARRAY_SIZE(ast_cursor_plane->hwc); ++i) {
+		gbo = ast_cursor_plane->hwc[i].gbo;
 		drm_gem_vram_unpin(gbo);
 		drm_gem_vram_put(gbo);
 	}
@@ -945,7 +948,7 @@ static int ast_cursor_plane_init(struct ast_private *ast)
 
 	size = roundup(AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE, PAGE_SIZE);
 
-	for (i = 0; i < ARRAY_SIZE(ast->cursor.gbo); ++i) {
+	for (i = 0; i < ARRAY_SIZE(ast_cursor_plane->hwc); ++i) {
 		gbo = drm_gem_vram_create(dev, size, 0);
 		if (IS_ERR(gbo)) {
 			ret = PTR_ERR(gbo);
@@ -955,7 +958,7 @@ static int ast_cursor_plane_init(struct ast_private *ast)
 					    DRM_GEM_VRAM_PL_FLAG_TOPDOWN);
 		if (ret)
 			goto err_drm_gem_vram_put;
-		ast->cursor.gbo[i] = gbo;
+		ast_cursor_plane->hwc[i].gbo = gbo;
 	}
 
 	/*
@@ -979,7 +982,7 @@ static int ast_cursor_plane_init(struct ast_private *ast)
 err_hwc:
 	while (i) {
 		--i;
-		gbo = ast->cursor.gbo[i];
+		gbo = ast_cursor_plane->hwc[i].gbo;
 		drm_gem_vram_unpin(gbo);
 err_drm_gem_vram_put:
 		drm_gem_vram_put(gbo);
-- 
2.30.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 08/10] drm/ast: Map HW cursor BOs permanently
  2021-02-09 13:46 [PATCH v2 00/10] drm/ast: Clean-up cursor-plane updates Thomas Zimmermann
                   ` (6 preceding siblings ...)
  2021-02-09 13:46 ` [PATCH v2 07/10] drm/ast: Store cursor BOs in cursor plane Thomas Zimmermann
@ 2021-02-09 13:46 ` Thomas Zimmermann
  2021-02-09 13:46 ` [PATCH v2 09/10] drm/ast: Store each HW cursor offset after pinning the rsp BO Thomas Zimmermann
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Thomas Zimmermann @ 2021-02-09 13:46 UTC (permalink / raw)
  To: airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

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: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/ast/ast_drv.h  |  1 +
 drivers/gpu/drm/ast/ast_mode.c | 32 +++++++++++++++-----------------
 2 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 4117c49096d4..22193cfde255 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -107,6 +107,7 @@ struct ast_cursor_plane {
 
 	struct {
 		struct drm_gem_vram_object *gbo;
+		struct dma_buf_map map;
 	} hwc[AST_DEFAULT_HWC_NUM];
 
 	unsigned int next_hwc_index;
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index dfff30e3d411..b9b9badcee00 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -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 drm_framebuffer *fb = new_state->fb;
-	struct drm_gem_vram_object *dst_gbo =
-		ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].gbo;
+	struct dma_buf_map dst_map =
+		ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].map;
 	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 *src;
 	int ret;
@@ -777,22 +777,14 @@ ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane,
 		return ret;
 	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 */
 
 	/* do data transfer to cursor BO */
 	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);
 
 	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,
@@ -841,9 +833,9 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
 	u8 x_offset, y_offset;
 	u8 __iomem *dst;
 	u8 __iomem *sig;
-	int ret;
 
 	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) {
 		/* A new cursor image was installed. */
@@ -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);
 	}
 
-	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 */
 
 	sig = dst + AST_HWC_SIZE;
 	writel(state->crtc_x, sig + AST_HWC_SIGNATURE_X);
 	writel(state->crtc_y, sig + AST_HWC_SIGNATURE_Y);
 
-	drm_gem_vram_vunmap(gbo, &map);
-
 	offset_x = AST_MAX_HWC_WIDTH - fb->width;
 	offset_y = AST_MAX_HWC_HEIGHT - fb->height;
 
@@ -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);
 	size_t i;
 	struct drm_gem_vram_object *gbo;
+	struct dma_buf_map map;
 
 	for (i = 0; i < ARRAY_SIZE(ast_cursor_plane->hwc); ++i) {
 		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_put(gbo);
 	}
@@ -939,6 +929,7 @@ static int ast_cursor_plane_init(struct ast_private *ast)
 	struct drm_plane *cursor_plane = &ast_cursor_plane->base;
 	size_t size, i;
 	struct drm_gem_vram_object *gbo;
+	struct dma_buf_map map;
 	int ret;
 
 	/*
@@ -958,7 +949,11 @@ static int ast_cursor_plane_init(struct ast_private *ast)
 					    DRM_GEM_VRAM_PL_FLAG_TOPDOWN);
 		if (ret)
 			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].map = map;
 	}
 
 	/*
@@ -983,6 +978,9 @@ static int ast_cursor_plane_init(struct ast_private *ast)
 	while (i) {
 		--i;
 		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);
 err_drm_gem_vram_put:
 		drm_gem_vram_put(gbo);
-- 
2.30.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 09/10] drm/ast: Store each HW cursor offset after pinning the rsp BO
  2021-02-09 13:46 [PATCH v2 00/10] drm/ast: Clean-up cursor-plane updates Thomas Zimmermann
                   ` (7 preceding siblings ...)
  2021-02-09 13:46 ` [PATCH v2 08/10] drm/ast: Map HW cursor BOs permanently Thomas Zimmermann
@ 2021-02-09 13:46 ` Thomas Zimmermann
  2021-02-09 13:46 ` [PATCH v2 10/10] drm/ast: Move all of the cursor-update functionality to atomic_update Thomas Zimmermann
  2021-02-17  9:53 ` [PATCH v2 00/10] drm/ast: Clean-up cursor-plane updates Gerd Hoffmann
  10 siblings, 0 replies; 12+ messages in thread
From: Thomas Zimmermann @ 2021-02-09 13:46 UTC (permalink / raw)
  To: airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

As HW cursor BOs never move, we can store the offset in VRAM in the
cursor-plane's HWC state. This removes the last possible source of
runtime errors from atomic_update.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/ast/ast_drv.h  |  1 +
 drivers/gpu/drm/ast/ast_mode.c | 21 +++++++++++----------
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 22193cfde255..e82ab8628770 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -108,6 +108,7 @@ struct ast_cursor_plane {
 	struct {
 		struct drm_gem_vram_object *gbo;
 		struct dma_buf_map map;
+		u64 off;
 	} hwc[AST_DEFAULT_HWC_NUM];
 
 	unsigned int next_hwc_index;
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index b9b9badcee00..e8de86d23805 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -823,26 +823,19 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
 	struct drm_plane_state *state = plane->state;
 	struct drm_framebuffer *fb = state->fb;
 	struct ast_private *ast = to_ast_private(plane->dev);
-	struct drm_device *dev = &ast->base;
-	struct drm_gem_vram_object *gbo =
-		ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].gbo;
+	u64 dst_off =
+		ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].off;
 	unsigned int offset_x, offset_y;
-	s64 off;
 	struct dma_buf_map map;
 	u16 x, y;
 	u8 x_offset, y_offset;
 	u8 __iomem *dst;
 	u8 __iomem *sig;
 
-	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) {
-		/* A new cursor image was installed. */
-		off = drm_gem_vram_offset(gbo);
-		if (drm_WARN_ON_ONCE(dev, off < 0))
-			return; /* Bug: we didn't pin the cursor HW BO to VRAM. */
-		ast_set_cursor_base(ast, off);
+		ast_set_cursor_base(ast, dst_off);
 
 		++ast_cursor_plane->next_hwc_index;
 		ast_cursor_plane->next_hwc_index %= ARRAY_SIZE(ast_cursor_plane->hwc);
@@ -931,6 +924,7 @@ static int ast_cursor_plane_init(struct ast_private *ast)
 	struct drm_gem_vram_object *gbo;
 	struct dma_buf_map map;
 	int ret;
+	s64 off;
 
 	/*
 	 * Allocate backing storage for cursors. The BOs are permanently
@@ -952,8 +946,14 @@ static int ast_cursor_plane_init(struct ast_private *ast)
 		ret = drm_gem_vram_vmap(gbo, &map);
 		if (ret)
 			goto err_drm_gem_vram_unpin;
+		off = drm_gem_vram_offset(gbo);
+		if (off < 0) {
+			ret = off;
+			goto err_drm_gem_vram_vunmap;
+		}
 		ast_cursor_plane->hwc[i].gbo = gbo;
 		ast_cursor_plane->hwc[i].map = map;
+		ast_cursor_plane->hwc[i].off = off;
 	}
 
 	/*
@@ -979,6 +979,7 @@ static int ast_cursor_plane_init(struct ast_private *ast)
 		--i;
 		gbo = ast_cursor_plane->hwc[i].gbo;
 		map = ast_cursor_plane->hwc[i].map;
+err_drm_gem_vram_vunmap:
 		drm_gem_vram_vunmap(gbo, &map);
 err_drm_gem_vram_unpin:
 		drm_gem_vram_unpin(gbo);
-- 
2.30.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 10/10] drm/ast: Move all of the cursor-update functionality to atomic_update
  2021-02-09 13:46 [PATCH v2 00/10] drm/ast: Clean-up cursor-plane updates Thomas Zimmermann
                   ` (8 preceding siblings ...)
  2021-02-09 13:46 ` [PATCH v2 09/10] drm/ast: Store each HW cursor offset after pinning the rsp BO Thomas Zimmermann
@ 2021-02-09 13:46 ` Thomas Zimmermann
  2021-02-17  9:53 ` [PATCH v2 00/10] drm/ast: Clean-up cursor-plane updates Gerd Hoffmann
  10 siblings, 0 replies; 12+ messages in thread
From: Thomas Zimmermann @ 2021-02-09 13:46 UTC (permalink / raw)
  To: airlied, daniel; +Cc: Thomas Zimmermann, dri-devel

We used to update the cursor image in prepare_fb. Move all this code to
atomic_update (where it belongs). The generic helper for shadow-buffered
planes now implement the cursor plane's prepare_fb.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/ast/ast_mode.c | 66 ++++++++++++----------------------
 1 file changed, 22 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index e8de86d23805..617b4c4af1a5 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -37,6 +37,7 @@
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_fourcc.h>
+#include <drm/drm_gem_atomic_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_gem_vram_helper.h>
 #include <drm/drm_plane_helper.h>
@@ -753,40 +754,6 @@ static const uint32_t ast_cursor_plane_formats[] = {
 	DRM_FORMAT_ARGB8888,
 };
 
-static int
-ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane,
-				   struct drm_plane_state *new_state)
-{
-	struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane);
-	struct drm_framebuffer *fb = new_state->fb;
-	struct dma_buf_map dst_map =
-		ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].map;
-	struct drm_gem_vram_object *src_gbo;
-	struct dma_buf_map src_map;
-	void __iomem *dst;
-	void *src;
-	int ret;
-
-	if (!fb)
-		return 0;
-
-	src_gbo = drm_gem_vram_of_gem(fb->obj[0]);
-
-	ret = drm_gem_vram_vmap(src_gbo, &src_map);
-	if (ret)
-		return ret;
-	src = src_map.vaddr; /* TODO: Use mapping abstraction properly */
-
-	dst = dst_map.vaddr_iomem; /* TODO: Use mapping abstraction properly */
-
-	/* do data transfer to cursor BO */
-	ast_update_cursor_image(dst, src, fb->width, fb->height);
-
-	drm_gem_vram_vunmap(src_gbo, &src_map);
-
-	return 0;
-}
-
 static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane,
 						struct drm_plane_state *state)
 {
@@ -821,18 +788,31 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
 {
 	struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane);
 	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 ast_private *ast = to_ast_private(plane->dev);
+	struct dma_buf_map dst_map =
+		ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].map;
 	u64 dst_off =
 		ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].off;
+	struct dma_buf_map src_map = shadow_plane_state->map[0];
 	unsigned int offset_x, offset_y;
-	struct dma_buf_map map;
 	u16 x, y;
 	u8 x_offset, y_offset;
 	u8 __iomem *dst;
 	u8 __iomem *sig;
+	const u8 *src;
+
+	src = src_map.vaddr; /* TODO: Use mapping abstraction properly */
+	dst = dst_map.vaddr_iomem; /* TODO: Use mapping abstraction properly */
+	sig = dst + AST_HWC_SIZE; /* TODO: Use mapping abstraction properly */
 
-	map = ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].map;
+	/*
+	 * Do data transfer to HW cursor BO. If a new cursor image was installed,
+	 * point the scanout engine to dst_gbo's offset and page-flip the HWC buffers.
+	 */
+
+	ast_update_cursor_image(dst, src, fb->width, fb->height);
 
 	if (state->fb != old_state->fb) {
 		ast_set_cursor_base(ast, dst_off);
@@ -841,9 +821,10 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
 		ast_cursor_plane->next_hwc_index %= ARRAY_SIZE(ast_cursor_plane->hwc);
 	}
 
-	dst = map.vaddr_iomem; /* TODO: Use mapping abstraction properly */
+	/*
+	 * Update location in HWC signature and registers.
+	 */
 
-	sig = dst + AST_HWC_SIZE;
 	writel(state->crtc_x, sig + AST_HWC_SIGNATURE_X);
 	writel(state->crtc_y, sig + AST_HWC_SIGNATURE_Y);
 
@@ -867,7 +848,7 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
 
 	ast_set_cursor_location(ast, x, y, x_offset, y_offset);
 
-	/* dummy write to fire HWC */
+	/* Dummy write to enable HWC and make the HW pick-up the changes. */
 	ast_set_cursor_enabled(ast, true);
 }
 
@@ -881,8 +862,7 @@ ast_cursor_plane_helper_atomic_disable(struct drm_plane *plane,
 }
 
 static const struct drm_plane_helper_funcs ast_cursor_plane_helper_funcs = {
-	.prepare_fb = ast_cursor_plane_helper_prepare_fb,
-	.cleanup_fb = NULL, /* not required for cursor plane */
+	DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
 	.atomic_check = ast_cursor_plane_helper_atomic_check,
 	.atomic_update = ast_cursor_plane_helper_atomic_update,
 	.atomic_disable = ast_cursor_plane_helper_atomic_disable,
@@ -910,9 +890,7 @@ static const struct drm_plane_funcs ast_cursor_plane_funcs = {
 	.update_plane = drm_atomic_helper_update_plane,
 	.disable_plane = drm_atomic_helper_disable_plane,
 	.destroy = ast_cursor_plane_destroy,
-	.reset = drm_atomic_helper_plane_reset,
-	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
-	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+	DRM_GEM_SHADOW_PLANE_FUNCS,
 };
 
 static int ast_cursor_plane_init(struct ast_private *ast)
-- 
2.30.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 00/10] drm/ast: Clean-up cursor-plane updates
  2021-02-09 13:46 [PATCH v2 00/10] drm/ast: Clean-up cursor-plane updates Thomas Zimmermann
                   ` (9 preceding siblings ...)
  2021-02-09 13:46 ` [PATCH v2 10/10] drm/ast: Move all of the cursor-update functionality to atomic_update Thomas Zimmermann
@ 2021-02-17  9:53 ` Gerd Hoffmann
  10 siblings, 0 replies; 12+ messages in thread
From: Gerd Hoffmann @ 2021-02-17  9:53 UTC (permalink / raw)
  To: Thomas Zimmermann; +Cc: airlied, dri-devel

On Tue, Feb 09, 2021 at 02:46:22PM +0100, Thomas Zimmermann wrote:
> (was: drm/ast: Move cursor vmap calls out of commit tail)
> 
> Ast has vmap calls in its cursor's atomic_update function. This is not
> supported as vmap might aquire the dma reservation lock. While at it,
> cleanup the whole cursor code: the patchset removes all possible runtime
> errors from the atomic_update function and reduces the overhead from
> vmap calls on the HW cursor BOs to a minimum.
> 
> Patches 1 to 3 update the cursor code and prepare before the refactoring.
> 
> Patch 4 and 5 inline the cursor update logic into the rsp cursor-plane
> functions. This is mostly about moving code around.
> 
> Patches 6 to 9 add a dedicated cursor plane that maintains the two BOs
> for HW cursors. The HW cursor BOs are permanently pinned and vmapped
> while the cursor plane is initialized. Thus removing the related vmap
> operations from atomic_update.
> 
> Finally patch 10 converts ast cursors to struct drm_shadow_plane_state.
> BOs with cursor image data from userspace are vmapped in prepare_fb and
> vunampped in cleanup_fb. The actual update of the cursor image is being
> moved from prepare_fb to atomic_update.
> 
> With the patchset applied, all cursor preparation is performed before
> the commit-tail functions; while the actual update is performed within.
> 
> Tested by running X11 and Weston on ast hardware.
> 
> v2:
> 	* convert to drm_shadow_plane_state helpers

Looks all sane to me.
Acked-by: Gerd Hoffmann <kraxel@redhat.com>

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2021-02-17  9:53 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-09 13:46 [PATCH v2 00/10] drm/ast: Clean-up cursor-plane updates Thomas Zimmermann
2021-02-09 13:46 ` [PATCH v2 01/10] drm/ast: Add constants for VGACRCB register bits Thomas Zimmermann
2021-02-09 13:46 ` [PATCH v2 02/10] drm/ast: Fix invalid usage of AST_MAX_HWC_WIDTH in cursor atomic_check Thomas Zimmermann
2021-02-09 13:46 ` [PATCH v2 03/10] drm/ast: Initialize planes in helper functions Thomas Zimmermann
2021-02-09 13:46 ` [PATCH v2 04/10] drm/ast: Allocate HW cursor BOs during cursor-plane initialization Thomas Zimmermann
2021-02-09 13:46 ` [PATCH v2 05/10] drm/ast: Inline ast cursor-update functions into modesetting code Thomas Zimmermann
2021-02-09 13:46 ` [PATCH v2 06/10] drm/ast: Add cursor-plane data structure Thomas Zimmermann
2021-02-09 13:46 ` [PATCH v2 07/10] drm/ast: Store cursor BOs in cursor plane Thomas Zimmermann
2021-02-09 13:46 ` [PATCH v2 08/10] drm/ast: Map HW cursor BOs permanently Thomas Zimmermann
2021-02-09 13:46 ` [PATCH v2 09/10] drm/ast: Store each HW cursor offset after pinning the rsp BO Thomas Zimmermann
2021-02-09 13:46 ` [PATCH v2 10/10] drm/ast: Move all of the cursor-update functionality to atomic_update Thomas Zimmermann
2021-02-17  9:53 ` [PATCH v2 00/10] drm/ast: Clean-up cursor-plane updates Gerd Hoffmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.