[PATCH 04/36] drm: omapdrm: Switch to the universal plane API

Tomi Valkeinen tomi.valkeinen at ti.com
Tue Mar 24 05:15:21 PDT 2015


From: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

Remove the CRTC private planes by switching to the universal plane API.
This results in a merge of the CRTC private plane created by the driver
(omap_crtc->plane) and the CRTC primary plane created by the DRM core
(crtc->primary).

Reference counting of the framebuffers in the update plane operation is
thus simplified as no reference needs to be stored in the private plane
anymore.

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/omap_crtc.c  | 43 ++++++++++++++++++------------------
 drivers/gpu/drm/omapdrm/omap_drv.c   |  4 ++--
 drivers/gpu/drm/omapdrm/omap_drv.h   |  2 +-
 drivers/gpu/drm/omapdrm/omap_plane.c | 36 ++++++++++++++++++------------
 4 files changed, 46 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index b9c3d8f830e8..7570db59a9ea 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -28,7 +28,6 @@
 
 struct omap_crtc {
 	struct drm_crtc base;
-	struct drm_plane *plane;
 
 	const char *name;
 	int pipe;
@@ -217,10 +216,7 @@ static void omap_crtc_dpms(struct drm_crtc *crtc, int mode)
 		omap_crtc->full_update = true;
 		omap_crtc_apply(crtc, &omap_crtc->apply);
 
-		/* also enable our private plane: */
-		WARN_ON(omap_plane_dpms(omap_crtc->plane, mode));
-
-		/* and any attached overlay planes: */
+		/* Enable/disable all planes associated with the CRTC. */
 		for (i = 0; i < priv->num_planes; i++) {
 			struct drm_plane *plane = priv->planes[i];
 			if (plane->crtc == crtc)
@@ -258,7 +254,13 @@ static int omap_crtc_mode_set(struct drm_crtc *crtc,
 	copy_timings_drm_to_omap(&omap_crtc->timings, mode);
 	omap_crtc->full_update = true;
 
-	return omap_plane_mode_set(omap_crtc->plane, crtc, crtc->primary->fb,
+	/*
+	 * The primary plane CRTC can be reset if the plane is disabled directly
+	 * through the universal plane API. Set it again here.
+	 */
+	crtc->primary->crtc = crtc;
+
+	return omap_plane_mode_set(crtc->primary, crtc, crtc->primary->fb,
 			0, 0, mode->hdisplay, mode->vdisplay,
 			x << 16, y << 16,
 			mode->hdisplay << 16, mode->vdisplay << 16,
@@ -282,8 +284,7 @@ static void omap_crtc_commit(struct drm_crtc *crtc)
 static int omap_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 		struct drm_framebuffer *old_fb)
 {
-	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-	struct drm_plane *plane = omap_crtc->plane;
+	struct drm_plane *plane = crtc->primary;
 	struct drm_display_mode *mode = &crtc->mode;
 
 	return omap_plane_mode_set(plane, crtc, crtc->primary->fb,
@@ -321,7 +322,7 @@ static void page_flip_worker(struct work_struct *work)
 	struct drm_gem_object *bo;
 
 	drm_modeset_lock(&crtc->mutex, NULL);
-	omap_plane_mode_set(omap_crtc->plane, crtc, crtc->primary->fb,
+	omap_plane_mode_set(crtc->primary, crtc, crtc->primary->fb,
 			0, 0, mode->hdisplay, mode->vdisplay,
 			crtc->x << 16, crtc->y << 16,
 			mode->hdisplay << 16, mode->vdisplay << 16,
@@ -385,7 +386,6 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc,
 static int omap_crtc_set_property(struct drm_crtc *crtc,
 		struct drm_property *property, uint64_t val)
 {
-	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
 	struct omap_drm_private *priv = crtc->dev->dev_private;
 
 	if (property == priv->rotation_prop) {
@@ -393,7 +393,7 @@ static int omap_crtc_set_property(struct drm_crtc *crtc,
 				!!(val & ((1LL << DRM_ROTATE_90) | (1LL << DRM_ROTATE_270)));
 	}
 
-	return omap_plane_set_property(omap_crtc->plane, property, val);
+	return omap_plane_set_property(crtc->primary, property, val);
 }
 
 static const struct drm_crtc_funcs omap_crtc_funcs = {
@@ -681,12 +681,13 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
 	struct drm_crtc *crtc = NULL;
 	struct omap_crtc *omap_crtc;
 	struct omap_overlay_manager_info *info;
+	int ret;
 
 	DBG("%s", channel_names[channel]);
 
 	omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL);
 	if (!omap_crtc)
-		goto fail;
+		return NULL;
 
 	crtc = &omap_crtc->base;
 
@@ -700,8 +701,6 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
 	omap_crtc->apply.post_apply = omap_crtc_post_apply;
 
 	omap_crtc->channel = channel;
-	omap_crtc->plane = plane;
-	omap_crtc->plane->crtc = crtc;
 	omap_crtc->name = channel_names[channel];
 	omap_crtc->pipe = id;
 
@@ -723,18 +722,18 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
 	info->trans_key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
 	info->trans_enabled = false;
 
-	drm_crtc_init(dev, crtc, &omap_crtc_funcs);
+	ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,
+					&omap_crtc_funcs);
+	if (ret < 0) {
+		kfree(omap_crtc);
+		return NULL;
+	}
+
 	drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs);
 
-	omap_plane_install_properties(omap_crtc->plane, &crtc->base);
+	omap_plane_install_properties(crtc->primary, &crtc->base);
 
 	omap_crtcs[channel] = omap_crtc;
 
 	return crtc;
-
-fail:
-	if (crtc)
-		omap_crtc_destroy(crtc);
-
-	return NULL;
 }
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 021855605a1f..5eab83d7de15 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -135,7 +135,7 @@ static int omap_modeset_create_crtc(struct drm_device *dev, int id,
 	struct drm_plane *plane;
 	struct drm_crtc *crtc;
 
-	plane = omap_plane_init(dev, id, true);
+	plane = omap_plane_init(dev, id, DRM_PLANE_TYPE_PRIMARY);
 	if (IS_ERR(plane))
 		return PTR_ERR(plane);
 
@@ -277,7 +277,7 @@ static int omap_modeset_init(struct drm_device *dev)
 	for (; id < num_ovls; id++) {
 		struct drm_plane *plane;
 
-		plane = omap_plane_init(dev, id, false);
+		plane = omap_plane_init(dev, id, DRM_PLANE_TYPE_OVERLAY);
 		if (IS_ERR(plane))
 			return PTR_ERR(plane);
 
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 60e47b33c801..f38ffd14ff06 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -160,7 +160,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
 void omap_crtc_flush(struct drm_crtc *crtc);
 
 struct drm_plane *omap_plane_init(struct drm_device *dev,
-		int plane_id, bool private_plane);
+		int id, enum drm_plane_type type);
 int omap_plane_dpms(struct drm_plane *plane, int mode);
 int omap_plane_mode_set(struct drm_plane *plane,
 		struct drm_crtc *crtc, struct drm_framebuffer *fb,
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index c17460336fcc..32df3e783128 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -220,14 +220,6 @@ int omap_plane_mode_set(struct drm_plane *plane,
 		omap_plane->apply_done_cb.arg = arg;
 	}
 
-	if (plane->fb)
-		drm_framebuffer_unreference(plane->fb);
-
-	drm_framebuffer_reference(fb);
-
-	plane->fb = fb;
-	plane->crtc = crtc;
-
 	return apply(plane);
 }
 
@@ -249,6 +241,13 @@ static int omap_plane_update(struct drm_plane *plane,
 		break;
 	}
 
+	/*
+	 * We don't need to take a reference to the framebuffer as the DRM core
+	 * has already done so for the purpose of setting plane->fb.
+	 */
+	plane->fb = fb;
+	plane->crtc = crtc;
+
 	return omap_plane_mode_set(plane, crtc, fb,
 			crtc_x, crtc_y, crtc_w, crtc_h,
 			src_x, src_y, src_w, src_h,
@@ -377,14 +376,15 @@ static const uint32_t error_irqs[] = {
 
 /* initialize plane */
 struct drm_plane *omap_plane_init(struct drm_device *dev,
-		int id, bool private_plane)
+		int id, enum drm_plane_type type)
 {
 	struct omap_drm_private *priv = dev->dev_private;
-	struct drm_plane *plane = NULL;
+	struct drm_plane *plane;
 	struct omap_plane *omap_plane;
 	struct omap_overlay_info *info;
+	int ret;
 
-	DBG("%s: priv=%d", plane_names[id], private_plane);
+	DBG("%s: type=%d", plane_names[id], type);
 
 	omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL);
 	if (!omap_plane)
@@ -408,8 +408,11 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
 	omap_plane->error_irq.irq = omap_plane_error_irq;
 	omap_irq_register(dev, &omap_plane->error_irq);
 
-	drm_plane_init(dev, plane, (1 << priv->num_crtcs) - 1, &omap_plane_funcs,
-			omap_plane->formats, omap_plane->nformats, private_plane);
+	ret = drm_universal_plane_init(dev, plane, (1 << priv->num_crtcs) - 1,
+				       &omap_plane_funcs, omap_plane->formats,
+				       omap_plane->nformats, type);
+	if (ret < 0)
+		goto error;
 
 	omap_plane_install_properties(plane, &plane->base);
 
@@ -427,10 +430,15 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
 	 * TODO add ioctl to give userspace an API to change this.. this
 	 * will come in a subsequent patch.
 	 */
-	if (private_plane)
+	if (type == DRM_PLANE_TYPE_PRIMARY)
 		omap_plane->info.zorder = 0;
 	else
 		omap_plane->info.zorder = id;
 
 	return plane;
+
+error:
+	omap_irq_unregister(plane->dev, &omap_plane->error_irq);
+	kfree(omap_plane);
+	return NULL;
 }
-- 
2.3.3



More information about the dri-devel mailing list