All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan Agner <stefan@agner.ch>
To: dri-devel@lists.freedesktop.org, meng.yi@nxp.com
Cc: alison.wang@freescale.com, jianwei.wang.chn@gmail.com,
	linux-kernel@vger.kernel.org, Stefan Agner <stefan@agner.ch>
Subject: [PATCH 1/4] drm/fsl-dcu: support overlay and cursor planes
Date: Mon,  5 Sep 2016 21:02:30 -0700	[thread overview]
Message-ID: <20160906040233.32471-2-stefan@agner.ch> (raw)
In-Reply-To: <20160906040233.32471-1-stefan@agner.ch>

Add support for overlay plane and a cursor plane. The driver uses
the topmost plane as cursor plane. The DCU IP would have dedicated
cursor support, but that lacks proper color support and hence is
not practical to use for Linux systems.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c  | 47 ++++++++++++++++++++++++-----
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 37 ++++++++++++-----------
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h |  3 +-
 3 files changed, 60 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
index 3371635..d30b61e 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
@@ -139,20 +139,51 @@ static const struct drm_crtc_funcs fsl_dcu_drm_crtc_funcs = {
 
 int fsl_dcu_drm_crtc_create(struct fsl_dcu_drm_device *fsl_dev)
 {
-	struct drm_plane *primary;
+	struct drm_device *drm = fsl_dev->drm;
+	struct drm_plane *primary, *cursor;
 	struct drm_crtc *crtc = &fsl_dev->crtc;
-	int ret;
+	int total_layer = fsl_dev->soc->total_layer;
+	int ret, i;
 
-	fsl_dcu_drm_init_planes(fsl_dev->drm);
+	fsl_dcu_drm_init_planes(drm);
 
-	primary = fsl_dcu_drm_primary_create_plane(fsl_dev->drm);
-	if (!primary)
-		return -ENOMEM;
+	primary = fsl_dcu_drm_create_plane(drm, DRM_PLANE_TYPE_PRIMARY);
+	if (IS_ERR(primary)) {
+		dev_err(fsl_dev->dev, "failed to construct primary plane\n");
+		ret = PTR_ERR(primary);
+		return ret;
+	}
+
+	/*
+	 * Initialize overlay layers. The hardware does not have specific
+	 * layer types, we just happen to use one layer as primary layer
+	 * and one layer as cursor layer, hence total_layer - 2 = overlays.
+	 */
+	for (i = 0; i < total_layer - 2; i++) {
+		struct drm_plane *plane =
+			fsl_dcu_drm_create_plane(drm, DRM_PLANE_TYPE_OVERLAY);
+
+		if (IS_ERR(plane))
+			continue;
+	}
 
-	ret = drm_crtc_init_with_planes(fsl_dev->drm, crtc, primary, NULL,
+	cursor = fsl_dcu_drm_create_plane(drm, DRM_PLANE_TYPE_CURSOR);
+	if (IS_ERR(cursor)) {
+		dev_warn(fsl_dev->dev, "failed to construct cursor plane\n");
+		cursor = NULL;
+	}
+
+	/*
+	 * Initialize cursor plane after overlay planes since the initialization
+	 * order is crucial to the layer id (and hence layer stacking order).
+	 */
+	ret = drm_crtc_init_with_planes(drm, crtc, primary, cursor,
 					&fsl_dcu_drm_crtc_funcs, NULL);
 	if (ret) {
-		primary->funcs->destroy(primary);
+		struct drm_plane *plane;
+
+		list_for_each_entry(plane, &drm->mode_config.plane_list, head)
+			drm_plane_cleanup(plane);
 		return ret;
 	}
 
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
index a7e5486..a6af3d9 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
@@ -178,7 +178,6 @@ static const struct drm_plane_helper_funcs fsl_dcu_drm_plane_helper_funcs = {
 static void fsl_dcu_drm_plane_destroy(struct drm_plane *plane)
 {
 	drm_plane_cleanup(plane);
-	kfree(plane);
 }
 
 static const struct drm_plane_funcs fsl_dcu_drm_plane_funcs = {
@@ -218,28 +217,30 @@ void fsl_dcu_drm_init_planes(struct drm_device *dev)
 		     DCU_UPDATE_MODE_READREG);
 }
 
-struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev)
+struct drm_plane *fsl_dcu_drm_create_plane(struct drm_device *dev,
+					   enum drm_plane_type type)
 {
-	struct drm_plane *primary;
+	struct drm_plane *plane;
 	int ret;
 
-	primary = kzalloc(sizeof(*primary), GFP_KERNEL);
-	if (!primary) {
-		DRM_DEBUG_KMS("Failed to allocate primary plane\n");
-		return NULL;
-	}
+	plane = devm_kzalloc(dev->dev, sizeof(struct drm_plane),
+			      GFP_KERNEL);
+	if (!plane)
+		return ERR_PTR(-ENOMEM);
 
-	/* possible_crtc's will be filled in later by crtc_init */
-	ret = drm_universal_plane_init(dev, primary, 0,
-				       &fsl_dcu_drm_plane_funcs,
+	ret = drm_universal_plane_init(dev, plane, 1, &fsl_dcu_drm_plane_funcs,
 				       fsl_dcu_drm_plane_formats,
 				       ARRAY_SIZE(fsl_dcu_drm_plane_formats),
-				       DRM_PLANE_TYPE_PRIMARY, NULL);
-	if (ret) {
-		kfree(primary);
-		primary = NULL;
-	}
-	drm_plane_helper_add(primary, &fsl_dcu_drm_plane_helper_funcs);
+				       type, NULL);
+	if (ret)
+		goto err_cleanup_plane;
+
+	drm_plane_helper_add(plane, &fsl_dcu_drm_plane_helper_funcs);
+
+	return plane;
+
+err_cleanup_plane:
+	drm_plane_cleanup(plane);
 
-	return primary;
+	return ERR_PTR(ret);
 }
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h
index 8ee45f8..bd36166 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h
@@ -13,6 +13,7 @@
 #define __FSL_DCU_DRM_PLANE_H__
 
 void fsl_dcu_drm_init_planes(struct drm_device *dev);
-struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev);
+struct drm_plane *fsl_dcu_drm_create_plane(struct drm_device *dev,
+					   enum drm_plane_type type);
 
 #endif /* __FSL_DCU_DRM_PLANE_H__ */
-- 
2.9.3

WARNING: multiple messages have this Message-ID (diff)
From: Stefan Agner <stefan@agner.ch>
To: dri-devel@lists.freedesktop.org, meng.yi@nxp.com
Cc: jianwei.wang.chn@gmail.com, linux-kernel@vger.kernel.org,
	alison.wang@freescale.com
Subject: [PATCH 1/4] drm/fsl-dcu: support overlay and cursor planes
Date: Mon,  5 Sep 2016 21:02:30 -0700	[thread overview]
Message-ID: <20160906040233.32471-2-stefan@agner.ch> (raw)
In-Reply-To: <20160906040233.32471-1-stefan@agner.ch>

Add support for overlay plane and a cursor plane. The driver uses
the topmost plane as cursor plane. The DCU IP would have dedicated
cursor support, but that lacks proper color support and hence is
not practical to use for Linux systems.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c  | 47 ++++++++++++++++++++++++-----
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 37 ++++++++++++-----------
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h |  3 +-
 3 files changed, 60 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
index 3371635..d30b61e 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
@@ -139,20 +139,51 @@ static const struct drm_crtc_funcs fsl_dcu_drm_crtc_funcs = {
 
 int fsl_dcu_drm_crtc_create(struct fsl_dcu_drm_device *fsl_dev)
 {
-	struct drm_plane *primary;
+	struct drm_device *drm = fsl_dev->drm;
+	struct drm_plane *primary, *cursor;
 	struct drm_crtc *crtc = &fsl_dev->crtc;
-	int ret;
+	int total_layer = fsl_dev->soc->total_layer;
+	int ret, i;
 
-	fsl_dcu_drm_init_planes(fsl_dev->drm);
+	fsl_dcu_drm_init_planes(drm);
 
-	primary = fsl_dcu_drm_primary_create_plane(fsl_dev->drm);
-	if (!primary)
-		return -ENOMEM;
+	primary = fsl_dcu_drm_create_plane(drm, DRM_PLANE_TYPE_PRIMARY);
+	if (IS_ERR(primary)) {
+		dev_err(fsl_dev->dev, "failed to construct primary plane\n");
+		ret = PTR_ERR(primary);
+		return ret;
+	}
+
+	/*
+	 * Initialize overlay layers. The hardware does not have specific
+	 * layer types, we just happen to use one layer as primary layer
+	 * and one layer as cursor layer, hence total_layer - 2 = overlays.
+	 */
+	for (i = 0; i < total_layer - 2; i++) {
+		struct drm_plane *plane =
+			fsl_dcu_drm_create_plane(drm, DRM_PLANE_TYPE_OVERLAY);
+
+		if (IS_ERR(plane))
+			continue;
+	}
 
-	ret = drm_crtc_init_with_planes(fsl_dev->drm, crtc, primary, NULL,
+	cursor = fsl_dcu_drm_create_plane(drm, DRM_PLANE_TYPE_CURSOR);
+	if (IS_ERR(cursor)) {
+		dev_warn(fsl_dev->dev, "failed to construct cursor plane\n");
+		cursor = NULL;
+	}
+
+	/*
+	 * Initialize cursor plane after overlay planes since the initialization
+	 * order is crucial to the layer id (and hence layer stacking order).
+	 */
+	ret = drm_crtc_init_with_planes(drm, crtc, primary, cursor,
 					&fsl_dcu_drm_crtc_funcs, NULL);
 	if (ret) {
-		primary->funcs->destroy(primary);
+		struct drm_plane *plane;
+
+		list_for_each_entry(plane, &drm->mode_config.plane_list, head)
+			drm_plane_cleanup(plane);
 		return ret;
 	}
 
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
index a7e5486..a6af3d9 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
@@ -178,7 +178,6 @@ static const struct drm_plane_helper_funcs fsl_dcu_drm_plane_helper_funcs = {
 static void fsl_dcu_drm_plane_destroy(struct drm_plane *plane)
 {
 	drm_plane_cleanup(plane);
-	kfree(plane);
 }
 
 static const struct drm_plane_funcs fsl_dcu_drm_plane_funcs = {
@@ -218,28 +217,30 @@ void fsl_dcu_drm_init_planes(struct drm_device *dev)
 		     DCU_UPDATE_MODE_READREG);
 }
 
-struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev)
+struct drm_plane *fsl_dcu_drm_create_plane(struct drm_device *dev,
+					   enum drm_plane_type type)
 {
-	struct drm_plane *primary;
+	struct drm_plane *plane;
 	int ret;
 
-	primary = kzalloc(sizeof(*primary), GFP_KERNEL);
-	if (!primary) {
-		DRM_DEBUG_KMS("Failed to allocate primary plane\n");
-		return NULL;
-	}
+	plane = devm_kzalloc(dev->dev, sizeof(struct drm_plane),
+			      GFP_KERNEL);
+	if (!plane)
+		return ERR_PTR(-ENOMEM);
 
-	/* possible_crtc's will be filled in later by crtc_init */
-	ret = drm_universal_plane_init(dev, primary, 0,
-				       &fsl_dcu_drm_plane_funcs,
+	ret = drm_universal_plane_init(dev, plane, 1, &fsl_dcu_drm_plane_funcs,
 				       fsl_dcu_drm_plane_formats,
 				       ARRAY_SIZE(fsl_dcu_drm_plane_formats),
-				       DRM_PLANE_TYPE_PRIMARY, NULL);
-	if (ret) {
-		kfree(primary);
-		primary = NULL;
-	}
-	drm_plane_helper_add(primary, &fsl_dcu_drm_plane_helper_funcs);
+				       type, NULL);
+	if (ret)
+		goto err_cleanup_plane;
+
+	drm_plane_helper_add(plane, &fsl_dcu_drm_plane_helper_funcs);
+
+	return plane;
+
+err_cleanup_plane:
+	drm_plane_cleanup(plane);
 
-	return primary;
+	return ERR_PTR(ret);
 }
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h
index 8ee45f8..bd36166 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h
@@ -13,6 +13,7 @@
 #define __FSL_DCU_DRM_PLANE_H__
 
 void fsl_dcu_drm_init_planes(struct drm_device *dev);
-struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev);
+struct drm_plane *fsl_dcu_drm_create_plane(struct drm_device *dev,
+					   enum drm_plane_type type);
 
 #endif /* __FSL_DCU_DRM_PLANE_H__ */
-- 
2.9.3

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

  reply	other threads:[~2016-09-06  4:02 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-06  4:02 [PATCH 0/4] drm/fsl-dcu: add overlay and cursor plane support Stefan Agner
2016-09-06  4:02 ` Stefan Agner
2016-09-06  4:02 ` Stefan Agner [this message]
2016-09-06  4:02   ` [PATCH 1/4] drm/fsl-dcu: support overlay and cursor planes Stefan Agner
2016-09-06  4:02 ` [PATCH 2/4] drm/fsl-dcu: respect pos/size register sizes Stefan Agner
2016-09-06  4:02   ` Stefan Agner
2016-09-06  4:02 ` [PATCH 3/4] drm/fsl-dcu: update all registers on flush Stefan Agner
2016-09-06  4:02   ` Stefan Agner
2016-09-07  8:46   ` Meng Yi
2016-09-06  4:02 ` [PATCH 4/4] drm/fsl-dcu: do not update when modifying irq registers Stefan Agner
2016-09-06  4:02   ` Stefan Agner
2016-09-07  8:43 ` [PATCH 0/4] drm/fsl-dcu: add overlay and cursor plane support Meng Yi
2016-09-07  8:43   ` Meng Yi
2016-09-21 18:13   ` Stefan Agner
2016-09-21 18:13     ` Stefan Agner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160906040233.32471-2-stefan@agner.ch \
    --to=stefan@agner.ch \
    --cc=alison.wang@freescale.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=jianwei.wang.chn@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=meng.yi@nxp.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.