[PATCH] drm: sti: convert driver to atomic modeset

Benjamin Gaignard benjamin.gaignard at linaro.org
Wed Mar 11 07:25:18 PDT 2015


This patch does the minimum to make sti driver use atomic helpers.
No big bang, only adapt some functions to new call order.

Later it will allow to clean the mess around sti_mixer_* functions
which are use either in plane and crtc.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard at linaro.org>
---
 drivers/gpu/drm/sti/sti_compositor.c |  3 --
 drivers/gpu/drm/sti/sti_drm_crtc.c   | 85 ++++++++++++++----------------------
 drivers/gpu/drm/sti/sti_drm_drv.c    |  5 +++
 drivers/gpu/drm/sti/sti_drm_plane.c  | 45 +++++++++++++++++--
 drivers/gpu/drm/sti/sti_dvo.c        |  4 ++
 drivers/gpu/drm/sti/sti_hda.c        |  4 ++
 drivers/gpu/drm/sti/sti_hdmi.c       |  4 ++
 7 files changed, 92 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/sti/sti_compositor.c b/drivers/gpu/drm/sti/sti_compositor.c
index 43215d3..9b2cc40 100644
--- a/drivers/gpu/drm/sti/sti_compositor.c
+++ b/drivers/gpu/drm/sti/sti_compositor.c
@@ -104,9 +104,6 @@ static int sti_compositor_bind(struct device *dev, struct device *master,
 			enum sti_layer_type type = desc & STI_LAYER_TYPE_MASK;
 			enum drm_plane_type plane_type = DRM_PLANE_TYPE_OVERLAY;
 
-			if (crtc < compo->nb_mixers)
-				plane_type = DRM_PLANE_TYPE_PRIMARY;
-
 			switch (type) {
 			case STI_CUR:
 				cursor = sti_drm_plane_init(drm_dev,
diff --git a/drivers/gpu/drm/sti/sti_drm_crtc.c b/drivers/gpu/drm/sti/sti_drm_crtc.c
index e6f6ef7..67a175b 100644
--- a/drivers/gpu/drm/sti/sti_drm_crtc.c
+++ b/drivers/gpu/drm/sti/sti_drm_crtc.c
@@ -9,6 +9,8 @@
 #include <linux/clk.h>
 
 #include <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_plane_helper.h>
 
@@ -77,22 +79,18 @@ static bool sti_drm_crtc_mode_fixup(struct drm_crtc *crtc,
 }
 
 static int
-sti_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
-		      struct drm_display_mode *adjusted_mode, int x, int y,
-		      struct drm_framebuffer *old_fb)
+sti_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode)
 {
 	struct sti_mixer *mixer = to_sti_mixer(crtc);
 	struct device *dev = mixer->dev;
 	struct sti_compositor *compo = dev_get_drvdata(dev);
-	struct sti_layer *layer;
 	struct clk *clk;
 	int rate = mode->clock * 1000;
 	int res;
-	unsigned int w, h;
 
-	DRM_DEBUG_KMS("CRTC:%d (%s) fb:%d mode:%d (%s)\n",
+	DRM_DEBUG_KMS("CRTC:%d (%s) mode:%d (%s)\n",
 		      crtc->base.id, sti_mixer_to_str(mixer),
-		      crtc->primary->fb->base.id, mode->base.id, mode->name);
+		      mode->base.id, mode->name);
 
 	DRM_DEBUG_KMS("%d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n",
 		      mode->vrefresh, mode->clock,
@@ -122,35 +120,13 @@ sti_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
 	sti_vtg_set_config(mixer->id == STI_MIXER_MAIN ?
 			compo->vtg_main : compo->vtg_aux, &crtc->mode);
 
-	/* a GDP is reserved to the CRTC FB */
-	layer = to_sti_layer(crtc->primary);
-	if (!layer) {
-		DRM_ERROR("Can not find GDP0)\n");
-		return -EINVAL;
-	}
-
-	/* copy the mode data adjusted by mode_fixup() into crtc->mode
-	 * so that hardware can be set to proper mode
-	 */
-	memcpy(&crtc->mode, adjusted_mode, sizeof(*adjusted_mode));
-
-	res = sti_mixer_set_layer_depth(mixer, layer);
-	if (res) {
-		DRM_ERROR("Can not set layer depth\n");
-		return -EINVAL;
-	}
 	res = sti_mixer_active_video_area(mixer, &crtc->mode);
 	if (res) {
 		DRM_ERROR("Can not set active video area\n");
 		return -EINVAL;
 	}
 
-	w = crtc->primary->fb->width - x;
-	h = crtc->primary->fb->height - y;
-
-	return sti_layer_prepare(layer, crtc,
-			crtc->primary->fb, &crtc->mode,
-			mixer->id, 0, 0, w, h, x, y, w, h);
+	return res;
 }
 
 static int sti_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
@@ -195,7 +171,6 @@ static void sti_drm_crtc_disable(struct drm_crtc *crtc)
 	struct sti_mixer *mixer = to_sti_mixer(crtc);
 	struct device *dev = mixer->dev;
 	struct sti_compositor *compo = dev_get_drvdata(dev);
-	struct sti_layer *layer;
 
 	if (!mixer->enabled)
 		return;
@@ -205,24 +180,6 @@ static void sti_drm_crtc_disable(struct drm_crtc *crtc)
 	/* Disable Background */
 	sti_mixer_set_background_status(mixer, false);
 
-	/* Disable GDP */
-	layer = to_sti_layer(crtc->primary);
-	if (!layer) {
-		DRM_ERROR("Cannot find GDP0\n");
-		return;
-	}
-
-	/* Disable layer at mixer level */
-	if (sti_mixer_set_layer_status(mixer, layer, false))
-		DRM_ERROR("Can not disable %s layer at mixer\n",
-				sti_layer_to_str(layer));
-
-	/* Wait a while to be sure that a Vsync event is received */
-	msleep(WAIT_NEXT_VSYNC_MS);
-
-	/* Then disable layer itself */
-	sti_layer_disable(layer);
-
 	drm_crtc_vblank_off(crtc);
 
 	/* Disable pixel clock and compo IP clocks */
@@ -237,14 +194,32 @@ static void sti_drm_crtc_disable(struct drm_crtc *crtc)
 	mixer->enabled = false;
 }
 
+static void
+sti_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
+{
+	sti_drm_crtc_prepare(crtc);
+	sti_drm_crtc_mode_set(crtc, &crtc->state->adjusted_mode);
+}
+
+static void sti_drm_atomic_begin(struct drm_crtc *crtc)
+{
+}
+
+static void sti_drm_atomic_flush(struct drm_crtc *crtc)
+{
+}
+
 static struct drm_crtc_helper_funcs sti_crtc_helper_funcs = {
 	.dpms = sti_drm_crtc_dpms,
 	.prepare = sti_drm_crtc_prepare,
 	.commit = sti_drm_crtc_commit,
 	.mode_fixup = sti_drm_crtc_mode_fixup,
-	.mode_set = sti_drm_crtc_mode_set,
-	.mode_set_base = sti_drm_crtc_mode_set_base,
+	.mode_set = drm_helper_crtc_mode_set,
+	.mode_set_nofb = sti_drm_crtc_mode_set_nofb,
+	.mode_set_base = drm_helper_crtc_mode_set_base,
 	.disable = sti_drm_crtc_disable,
+	.atomic_begin = sti_drm_atomic_begin,
+	.atomic_flush = sti_drm_atomic_flush,
 };
 
 static int sti_drm_crtc_page_flip(struct drm_crtc *crtc,
@@ -290,6 +265,9 @@ static int sti_drm_crtc_page_flip(struct drm_crtc *crtc,
 		}
 		spin_unlock_irqrestore(&drm_dev->event_lock, flags);
 	}
+
+	if (crtc->primary->state)
+		drm_atomic_set_fb_for_plane(crtc->primary->state, fb);
 out:
 	mutex_unlock(&drm_dev->struct_mutex);
 	return ret;
@@ -380,10 +358,13 @@ void sti_drm_crtc_disable_vblank(struct drm_device *dev, int crtc)
 EXPORT_SYMBOL(sti_drm_crtc_disable_vblank);
 
 static struct drm_crtc_funcs sti_crtc_funcs = {
-	.set_config = drm_crtc_helper_set_config,
+	.set_config = drm_atomic_helper_set_config,
 	.page_flip = sti_drm_crtc_page_flip,
 	.destroy = sti_drm_crtc_destroy,
 	.set_property = sti_drm_crtc_set_property,
+	.reset = drm_atomic_helper_crtc_reset,
+	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 };
 
 bool sti_drm_crtc_is_main(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/sti/sti_drm_drv.c b/drivers/gpu/drm/sti/sti_drm_drv.c
index 5239fa1..ad33c5b 100644
--- a/drivers/gpu/drm/sti/sti_drm_drv.c
+++ b/drivers/gpu/drm/sti/sti_drm_drv.c
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/of_platform.h>
 
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_fb_cma_helper.h>
@@ -30,6 +31,8 @@
 
 static struct drm_mode_config_funcs sti_drm_mode_config_funcs = {
 	.fb_create = drm_fb_cma_create,
+	.atomic_check = drm_atomic_helper_check,
+	.atomic_commit = drm_atomic_helper_commit,
 };
 
 static void sti_drm_mode_config_init(struct drm_device *dev)
@@ -74,6 +77,8 @@ static int sti_drm_load(struct drm_device *dev, unsigned long flags)
 		return ret;
 	}
 
+	drm_mode_config_reset(dev);
+
 	drm_helper_disable_unused_functions(dev);
 
 #ifdef CONFIG_DRM_STI_FBDEV
diff --git a/drivers/gpu/drm/sti/sti_drm_plane.c b/drivers/gpu/drm/sti/sti_drm_plane.c
index bb6a293..ca39faa 100644
--- a/drivers/gpu/drm/sti/sti_drm_plane.c
+++ b/drivers/gpu/drm/sti/sti_drm_plane.c
@@ -6,6 +6,10 @@
  * License terms:  GNU General Public License (GPL), version 2
  */
 
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_plane_helper.h>
+
 #include "sti_compositor.h"
 #include "sti_drm_drv.h"
 #include "sti_drm_plane.h"
@@ -133,10 +137,43 @@ static int sti_drm_plane_set_property(struct drm_plane *plane,
 }
 
 static struct drm_plane_funcs sti_drm_plane_funcs = {
-	.update_plane = sti_drm_update_plane,
-	.disable_plane = sti_drm_disable_plane,
+	.update_plane = drm_atomic_helper_update_plane,
+	.disable_plane = drm_atomic_helper_disable_plane,
 	.destroy = sti_drm_plane_destroy,
 	.set_property = sti_drm_plane_set_property,
+	.reset = drm_atomic_helper_plane_reset,
+	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+};
+
+static int sti_drm_plane_atomic_check(struct drm_plane *plane,
+				      struct drm_plane_state *state)
+{
+	return 0;
+}
+
+static void sti_drm_plane_atomic_update(struct drm_plane *plane,
+					struct drm_plane_state *oldstate)
+{
+	struct drm_plane_state *state = plane->state;
+
+	sti_drm_update_plane(plane, state->crtc, state->fb,
+			    state->crtc_x, state->crtc_y,
+			    state->crtc_w, state->crtc_h,
+			    state->src_x, state->src_y,
+			    state->src_w, state->src_h);
+}
+
+static void sti_drm_plane_atomic_disable(struct drm_plane *plane,
+					 struct drm_plane_state *oldstate)
+{
+	sti_drm_disable_plane(plane);
+}
+
+static const struct drm_plane_helper_funcs sti_drm_plane_helpers_funcs = {
+	.atomic_check = sti_drm_plane_atomic_check,
+	.atomic_update = sti_drm_plane_atomic_update,
+	.atomic_disable = sti_drm_plane_atomic_disable,
 };
 
 static void sti_drm_plane_attach_zorder_property(struct drm_plane *plane,
@@ -178,11 +215,13 @@ struct drm_plane *sti_drm_plane_init(struct drm_device *dev,
 		return NULL;
 	}
 
+	drm_plane_helper_add(&layer->plane, &sti_drm_plane_helpers_funcs);
+
 	for (i = 0; i < ARRAY_SIZE(sti_layer_default_zorder); i++)
 		if (sti_layer_default_zorder[i] == layer->desc)
 			break;
 
-	default_zorder = i;
+	default_zorder = i + 1;
 
 	if (type == DRM_PLANE_TYPE_OVERLAY)
 		sti_drm_plane_attach_zorder_property(&layer->plane,
diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c
index aeb5070..419bc6c 100644
--- a/drivers/gpu/drm/sti/sti_dvo.c
+++ b/drivers/gpu/drm/sti/sti_dvo.c
@@ -11,6 +11,7 @@
 #include <linux/platform_device.h>
 
 #include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_panel.h>
 
@@ -368,6 +369,9 @@ static struct drm_connector_funcs sti_dvo_connector_funcs = {
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.detect = sti_dvo_connector_detect,
 	.destroy = sti_dvo_connector_destroy,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
 static struct drm_encoder *sti_dvo_find_encoder(struct drm_device *dev)
diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
index a9bbb08..b9897f9 100644
--- a/drivers/gpu/drm/sti/sti_hda.c
+++ b/drivers/gpu/drm/sti/sti_hda.c
@@ -10,6 +10,7 @@
 #include <linux/platform_device.h>
 
 #include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 
 /* HDformatter registers */
@@ -615,6 +616,9 @@ static struct drm_connector_funcs sti_hda_connector_funcs = {
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.detect = sti_hda_connector_detect,
 	.destroy = sti_hda_connector_destroy,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
 static struct drm_encoder *sti_hda_find_encoder(struct drm_device *dev)
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index 1485ade..0dcbb73 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -13,6 +13,7 @@
 #include <linux/reset.h>
 
 #include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_edid.h>
 
@@ -667,6 +668,9 @@ static struct drm_connector_funcs sti_hdmi_connector_funcs = {
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.detect = sti_hdmi_connector_detect,
 	.destroy = sti_hdmi_connector_destroy,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
 static struct drm_encoder *sti_hdmi_find_encoder(struct drm_device *dev)
-- 
1.9.1



More information about the dri-devel mailing list