All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] drm/sun4i: Fix formats usable by the primary plane
@ 2016-09-19 20:17 Maxime Ripard
  2016-09-19 20:17 ` [PATCH 2/3] drm/sun4i: tv: Check mode pointer Maxime Ripard
  2016-09-19 20:17 ` [PATCH 3/3] drm/sun4i: Fix the high buffer address mask Maxime Ripard
  0 siblings, 2 replies; 3+ messages in thread
From: Maxime Ripard @ 2016-09-19 20:17 UTC (permalink / raw)
  To: dri-devel; +Cc: Daniel Vetter, Chen-Yu Tsai, Maxime Ripard

Even though all our planes can support the ARGB formats, the lowest plane
(ie the primary plane) cannot use the alpha component, otherwise it will
just result in the transparent area being entirely black.

Since some applications will still require the ARGB format, let's force the
format to XRGB to drop the alpha component entirely.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/gpu/drm/sun4i/sun4i_backend.c |  9 ++++--
 drivers/gpu/drm/sun4i/sun4i_layer.c   | 56 ++++++++++++++++++++++++-----------
 2 files changed, 46 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
index 3ab560450a82..df7e95ac8e56 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
@@ -83,8 +83,13 @@ void sun4i_backend_layer_enable(struct sun4i_backend *backend,
 }
 EXPORT_SYMBOL(sun4i_backend_layer_enable);
 
-static int sun4i_backend_drm_format_to_layer(u32 format, u32 *mode)
+static int sun4i_backend_drm_format_to_layer(struct drm_plane *plane,
+					     u32 format, u32 *mode)
 {
+	if ((plane->type == DRM_PLANE_TYPE_PRIMARY) &&
+	    (format == DRM_FORMAT_ARGB8888))
+		format = DRM_FORMAT_XRGB8888;
+
 	switch (format) {
 	case DRM_FORMAT_ARGB8888:
 		*mode = SUN4I_BACKEND_LAY_FBFMT_ARGB8888;
@@ -164,7 +169,7 @@ int sun4i_backend_update_layer_formats(struct sun4i_backend *backend,
 	DRM_DEBUG_DRIVER("Switching display backend interlaced mode %s\n",
 			 interlaced ? "on" : "off");
 
-	ret = sun4i_backend_drm_format_to_layer(fb->pixel_format, &val);
+	ret = sun4i_backend_drm_format_to_layer(plane, fb->pixel_format, &val);
 	if (ret) {
 		DRM_DEBUG_DRIVER("Invalid format\n");
 		return val;
diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
index 068ab806309b..ea9a42176bd5 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
@@ -19,7 +19,12 @@
 #include "sun4i_drv.h"
 #include "sun4i_layer.h"
 
-#define SUN4I_NUM_LAYERS	2
+struct sun4i_plane_desc {
+	       enum drm_plane_type     type;
+	       u8                      pipe;
+	       const uint32_t          *formats;
+	       uint32_t                nformats;
+};
 
 static int sun4i_backend_layer_atomic_check(struct drm_plane *plane,
 					    struct drm_plane_state *state)
@@ -65,14 +70,35 @@ static const struct drm_plane_funcs sun4i_backend_layer_funcs = {
 	.update_plane		= drm_atomic_helper_update_plane,
 };
 
-static const uint32_t sun4i_backend_layer_formats[] = {
+static const uint32_t sun4i_backend_layer_formats_primary[] = {
 	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_RGB888,
 	DRM_FORMAT_XRGB8888,
+};
+
+static const uint32_t sun4i_backend_layer_formats_overlay[] = {
+	DRM_FORMAT_ARGB8888,
 	DRM_FORMAT_RGB888,
+	DRM_FORMAT_XRGB8888,
+};
+
+static const struct sun4i_plane_desc sun4i_backend_planes[] = {
+       {
+	       .type = DRM_PLANE_TYPE_PRIMARY,
+	       .pipe = 0,
+	       .formats = sun4i_backend_layer_formats_primary,
+	       .nformats = ARRAY_SIZE(sun4i_backend_layer_formats_primary),
+       },
+       {
+	       .type = DRM_PLANE_TYPE_OVERLAY,
+	       .pipe = 1,
+	       .formats = sun4i_backend_layer_formats_overlay,
+	       .nformats = ARRAY_SIZE(sun4i_backend_layer_formats_overlay),
+       },
 };
 
 static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
-						enum drm_plane_type type)
+						const struct sun4i_plane_desc *plane)
 {
 	struct sun4i_drv *drv = drm->dev_private;
 	struct sun4i_layer *layer;
@@ -84,10 +110,8 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
 
 	ret = drm_universal_plane_init(drm, &layer->plane, BIT(0),
 				       &sun4i_backend_layer_funcs,
-				       sun4i_backend_layer_formats,
-				       ARRAY_SIZE(sun4i_backend_layer_formats),
-				       type,
-				       NULL);
+				       plane->formats, plane->nformats,
+				       plane->type, NULL);
 	if (ret) {
 		dev_err(drm->dev, "Couldn't initialize layer\n");
 		return ERR_PTR(ret);
@@ -97,7 +121,7 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
 			     &sun4i_backend_layer_helper_funcs);
 	layer->drv = drv;
 
-	if (type == DRM_PLANE_TYPE_PRIMARY)
+	if (plane->type == DRM_PLANE_TYPE_PRIMARY)
 		drv->primary = &layer->plane;
 
 	return layer;
@@ -109,8 +133,8 @@ struct sun4i_layer **sun4i_layers_init(struct drm_device *drm)
 	struct sun4i_layer **layers;
 	int i;
 
-	layers = devm_kcalloc(drm->dev, SUN4I_NUM_LAYERS, sizeof(**layers),
-			      GFP_KERNEL);
+	layers = devm_kcalloc(drm->dev, ARRAY_SIZE(sun4i_backend_planes),
+			      sizeof(**layers), GFP_KERNEL);
 	if (!layers)
 		return ERR_PTR(-ENOMEM);
 
@@ -135,13 +159,11 @@ struct sun4i_layer **sun4i_layers_init(struct drm_device *drm)
 	 * SoCs that support it, sprites could fill the need for more
 	 * layers.
 	 */
-	for (i = 0; i < SUN4I_NUM_LAYERS; i++) {
-		enum drm_plane_type type = (i == 0)
-					 ? DRM_PLANE_TYPE_PRIMARY
-					 : DRM_PLANE_TYPE_OVERLAY;
+	for (i = 0; i < ARRAY_SIZE(sun4i_backend_planes); i++) {
+		const struct sun4i_plane_desc *plane = &sun4i_backend_planes[i];
 		struct sun4i_layer *layer = layers[i];
 
-		layer = sun4i_layer_init_one(drm, type);
+		layer = sun4i_layer_init_one(drm, plane);
 		if (IS_ERR(layer)) {
 			dev_err(drm->dev, "Couldn't initialize %s plane\n",
 				i ? "overlay" : "primary");
@@ -149,10 +171,10 @@ struct sun4i_layer **sun4i_layers_init(struct drm_device *drm)
 		};
 
 		DRM_DEBUG_DRIVER("Assigning %s plane to pipe %d\n",
-				 i ? "overlay" : "primary", i);
+				 i ? "overlay" : "primary", plane->pipe);
 		regmap_update_bits(drv->backend->regs, SUN4I_BACKEND_ATTCTL_REG0(i),
 				   SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL_MASK,
-				   SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL(i));
+				   SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL(plane->pipe));
 
 		layer->id = i;
 	};
-- 
2.9.3

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

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

* [PATCH 2/3] drm/sun4i: tv: Check mode pointer
  2016-09-19 20:17 [PATCH 1/3] drm/sun4i: Fix formats usable by the primary plane Maxime Ripard
@ 2016-09-19 20:17 ` Maxime Ripard
  2016-09-19 20:17 ` [PATCH 3/3] drm/sun4i: Fix the high buffer address mask Maxime Ripard
  1 sibling, 0 replies; 3+ messages in thread
From: Maxime Ripard @ 2016-09-19 20:17 UTC (permalink / raw)
  To: dri-devel; +Cc: Daniel Vetter, Chen-Yu Tsai, Maxime Ripard

The drm_mode_create call might return NULL in case of a failure, and the
current code doesn't check for that. Make sure it does.

Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/gpu/drm/sun4i/sun4i_tv.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index b84147896294..6bf1057c132b 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -507,9 +507,15 @@ static int sun4i_tv_comp_get_modes(struct drm_connector *connector)
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
-		struct drm_display_mode *mode = drm_mode_create(connector->dev);
+		struct drm_display_mode *mode;
 		struct tv_mode *tv_mode = &tv_modes[i];
 
+		mode = drm_mode_create(connector->dev);
+		if (!mode) {
+			DRM_ERROR("Failed to create a new display mode\n");
+			return 0;
+		}
+
 		strcpy(mode->name, tv_mode->name);
 
 		sun4i_tv_mode_to_drm_mode(tv_mode, mode);
-- 
2.9.3

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

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

* [PATCH 3/3] drm/sun4i: Fix the high buffer address mask
  2016-09-19 20:17 [PATCH 1/3] drm/sun4i: Fix formats usable by the primary plane Maxime Ripard
  2016-09-19 20:17 ` [PATCH 2/3] drm/sun4i: tv: Check mode pointer Maxime Ripard
@ 2016-09-19 20:17 ` Maxime Ripard
  1 sibling, 0 replies; 3+ messages in thread
From: Maxime Ripard @ 2016-09-19 20:17 UTC (permalink / raw)
  To: dri-devel; +Cc: Daniel Vetter, Chen-Yu Tsai, Maxime Ripard

The highest 3bits of the 4 layers buffers are all part of the same
register. However, our mask computation was wrong, leading to all the
lowest register bits being removed when we use regmap_update_bits, which
will lead to the buffers being set to some random part of the RAM.

Fix our mask.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/gpu/drm/sun4i/sun4i_backend.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.h b/drivers/gpu/drm/sun4i/sun4i_backend.h
index 7070bb3434e5..19c9b2a84b9c 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.h
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.h
@@ -52,8 +52,8 @@
 #define SUN4I_BACKEND_LAYFB_L32ADD_REG(l)	(0x850 + (0x4 * (l)))
 
 #define SUN4I_BACKEND_LAYFB_H4ADD_REG		0x860
-#define SUN4I_BACKEND_LAYFB_H4ADD_MSK(l)		GENMASK(3 + ((l) * 8), 0)
-#define SUN4I_BACKEND_LAYFB_H4ADD(l, val)			((val) << ((l) * 8))
+#define SUN4I_BACKEND_LAYFB_H4ADD_MSK(l)		GENMASK(3 + ((l) * 8), (l) * 8)
+#define SUN4I_BACKEND_LAYFB_H4ADD(l, val)		((val) << ((l) * 8))
 
 #define SUN4I_BACKEND_REGBUFFCTL_REG		0x870
 #define SUN4I_BACKEND_REGBUFFCTL_AUTOLOAD_DIS		BIT(1)
-- 
2.9.3

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

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

end of thread, other threads:[~2016-09-19 20:18 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-19 20:17 [PATCH 1/3] drm/sun4i: Fix formats usable by the primary plane Maxime Ripard
2016-09-19 20:17 ` [PATCH 2/3] drm/sun4i: tv: Check mode pointer Maxime Ripard
2016-09-19 20:17 ` [PATCH 3/3] drm/sun4i: Fix the high buffer address mask Maxime Ripard

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.