diff mbox

[PATCH/RFC,374/390] drm/rcar-du: Update plane format after releasing hardware planes

Message ID 1364525119-31791-375-git-send-email-horms+renesas@verge.net.au (mailing list archive)
State New, archived
Headers show

Commit Message

Simon Horman March 29, 2013, 2:45 a.m. UTC
From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Hardware planes were released after updating the plane format, which
resulted in an invalid number of hardware planes being released if the
format changed from uni-planar to multi-planar (and vice-versa).

Release the hardware planes before updating the plane format.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
(cherry picked from commit bef7cb8aae6e5f634510dfe2e094c50259bb15ea)

Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c  |    7 ++++++-
 drivers/gpu/drm/rcar-du/rcar_du_plane.c |   27 ++++++++++++++-------------
 drivers/gpu/drm/rcar-du/rcar_du_plane.h |    4 +++-
 3 files changed, 23 insertions(+), 15 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 57e6b89..b820099 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -293,6 +293,7 @@  static int rcar_du_crtc_mode_set(struct drm_crtc *crtc,
 	struct rcar_du_device *rcdu = crtc->dev->dev_private;
 	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
 	const struct rcar_du_format_info *format;
+	int ret;
 
 	format = rcar_du_format_info(crtc->fb->pixel_format);
 	if (format == NULL) {
@@ -301,6 +302,10 @@  static int rcar_du_crtc_mode_set(struct drm_crtc *crtc,
 		return -EINVAL;
 	}
 
+	ret = rcar_du_plane_reserve(rcrtc->plane, format);
+	if (ret < 0)
+		return ret;
+
 	rcrtc->plane->format = format;
 	rcrtc->plane->pitch = crtc->fb->pitches[0];
 
@@ -311,7 +316,7 @@  static int rcar_du_crtc_mode_set(struct drm_crtc *crtc,
 
 	rcar_du_plane_compute_base(rcrtc->plane, crtc->fb);
 
-	return rcar_du_plane_reserve(rcrtc->plane);
+	return 0;
 }
 
 static void rcar_du_crtc_mode_commit(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index 4fada59..3684de3 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -38,7 +38,8 @@  static void rcar_du_plane_write(struct rcar_du_device *rcdu,
 	rcar_du_write(rcdu, index * PLANE_OFF + reg, data);
 }
 
-int rcar_du_plane_reserve(struct rcar_du_plane *plane)
+int rcar_du_plane_reserve(struct rcar_du_plane *plane,
+			  const struct rcar_du_format_info *format)
 {
 	struct rcar_du_device *rcdu = plane->dev;
 	unsigned int i;
@@ -50,7 +51,7 @@  int rcar_du_plane_reserve(struct rcar_du_plane *plane)
 		if (!(rcdu->planes.free & (1 << i)))
 			continue;
 
-		if (plane->format->planes == 1 ||
+		if (format->planes == 1 ||
 		    rcdu->planes.free & (1 << ((i + 1) % 8)))
 			break;
 	}
@@ -59,7 +60,7 @@  int rcar_du_plane_reserve(struct rcar_du_plane *plane)
 		goto done;
 
 	rcdu->planes.free &= ~(1 << i);
-	if (plane->format->planes == 2)
+	if (format->planes == 2)
 		rcdu->planes.free &= ~(1 << ((i + 1) % 8));
 
 	plane->hwindex = i;
@@ -263,6 +264,16 @@  rcar_du_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
 
 	nplanes = rplane->format ? rplane->format->planes : 0;
 
+	/* Reallocate hardware planes if the number of required planes has
+	 * changed.
+	 */
+	if (format->planes != nplanes) {
+		rcar_du_plane_release(rplane);
+		ret = rcar_du_plane_reserve(rplane, format);
+		if (ret < 0)
+			return ret;
+	}
+
 	rplane->crtc = crtc;
 	rplane->format = format;
 	rplane->pitch = fb->pitches[0];
@@ -274,16 +285,6 @@  rcar_du_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
 	rplane->width = crtc_w;
 	rplane->height = crtc_h;
 
-	/* Reallocate hardware planes if the number of required planes has
-	 * changed.
-	 */
-	if (format->planes != nplanes) {
-		rcar_du_plane_release(rplane);
-		ret = rcar_du_plane_reserve(rplane);
-		if (ret < 0)
-			return ret;
-	}
-
 	rcar_du_plane_compute_base(rplane, fb);
 	rcar_du_plane_setup(rplane);
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
index 1a0a440..e8d2a26 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
@@ -19,6 +19,7 @@ 
 
 struct drm_framebuffer;
 struct rcar_du_device;
+struct rcar_du_format_info;
 
 struct rcar_du_plane {
 	struct drm_plane plane;
@@ -53,7 +54,8 @@  void rcar_du_plane_setup(struct rcar_du_plane *plane);
 void rcar_du_plane_update_base(struct rcar_du_plane *plane);
 void rcar_du_plane_compute_base(struct rcar_du_plane *plane,
 				struct drm_framebuffer *fb);
-int rcar_du_plane_reserve(struct rcar_du_plane *plane);
+int rcar_du_plane_reserve(struct rcar_du_plane *plane,
+			  const struct rcar_du_format_info *format);
 void rcar_du_plane_release(struct rcar_du_plane *plane);
 
 #endif /* __RCAR_DU_PLANE_H__ */