Blob Blame History Raw
From: Jernej Skrabec <jernej.skrabec@siol.net>
Date: Fri, 1 Dec 2017 07:05:33 +0100
Subject: drm/sun4i: Start using layer id in DE2 driver
Git-commit: f356fe8e0fb630b4b00c6207d5af53a5d1fab660
Patch-mainline: v4.16-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

Till now, plane selection was hardcoded to first overlay in first UI
channel and layer parameter is unused.

Rename and add parameters to layer functions so they would represent HW
more accurately and start using then.

It turns out that overlays don't fit well in current DRM design, because
they can't be blended together or scaled independetly when they are set
to same channel. Because of that, always use only first overlay in each
channel.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171201060550.10392-11-jernej.skrabec@siol.net

Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/sun4i/sun8i_layer.c |   18 ++++++++----
 drivers/gpu/drm/sun4i/sun8i_layer.h |    3 +-
 drivers/gpu/drm/sun4i/sun8i_mixer.c |   50 +++++++++++++++---------------------
 drivers/gpu/drm/sun4i/sun8i_mixer.h |   16 +++++------
 4 files changed, 43 insertions(+), 44 deletions(-)

--- a/drivers/gpu/drm/sun4i/sun8i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_layer.c
@@ -32,7 +32,8 @@ static void sun8i_mixer_layer_atomic_dis
 	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
 	struct sun8i_mixer *mixer = layer->mixer;
 
-	sun8i_mixer_layer_enable(mixer, layer->id, false);
+	sun8i_mixer_layer_enable(mixer, layer->channel,
+				 layer->overlay, false);
 }
 
 static void sun8i_mixer_layer_atomic_update(struct drm_plane *plane,
@@ -41,10 +42,14 @@ static void sun8i_mixer_layer_atomic_upd
 	struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
 	struct sun8i_mixer *mixer = layer->mixer;
 
-	sun8i_mixer_update_layer_coord(mixer, layer->id, plane);
-	sun8i_mixer_update_layer_formats(mixer, layer->id, plane);
-	sun8i_mixer_update_layer_buffer(mixer, layer->id, plane);
-	sun8i_mixer_layer_enable(mixer, layer->id, true);
+	sun8i_mixer_update_layer_coord(mixer, layer->channel,
+				       layer->overlay, plane);
+	sun8i_mixer_update_layer_formats(mixer, layer->channel,
+					 layer->overlay, plane);
+	sun8i_mixer_update_layer_buffer(mixer, layer->channel,
+					layer->overlay, plane);
+	sun8i_mixer_layer_enable(mixer, layer->channel,
+				 layer->overlay, true);
 }
 
 static struct drm_plane_helper_funcs sun8i_mixer_layer_helper_funcs = {
@@ -126,7 +131,8 @@ struct drm_plane **sun8i_layers_init(str
 			return ERR_CAST(layer);
 		};
 
-		layer->id = i;
+		layer->channel = mixer->cfg->vi_num + i;
+		layer->overlay = 0;
 		planes[i] = &layer->plane;
 	};
 
--- a/drivers/gpu/drm/sun4i/sun8i_layer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_layer.h
@@ -22,7 +22,8 @@ struct sun8i_layer {
 	struct drm_plane	plane;
 	struct sun4i_drv	*drv;
 	struct sun8i_mixer	*mixer;
-	int			id;
+	int			channel;
+	int			overlay;
 };
 
 static inline struct sun8i_layer *
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -37,15 +37,13 @@ static void sun8i_mixer_commit(struct su
 		     SUN8I_MIXER_GLOBAL_DBUFF_ENABLE);
 }
 
-void sun8i_mixer_layer_enable(struct sun8i_mixer *mixer,
-				int layer, bool enable)
+void sun8i_mixer_layer_enable(struct sun8i_mixer *mixer, int channel,
+			      int overlay, bool enable)
 {
 	u32 val;
-	/* Currently the first UI channel is used */
-	int chan = mixer->cfg->vi_num;
 
-	DRM_DEBUG_DRIVER("%sabling layer %d in channel %d\n",
-			 enable ? "En" : "Dis", layer, chan);
+	DRM_DEBUG_DRIVER("%sabling channel %d overlay %d\n",
+			 enable ? "En" : "Dis", channel, overlay);
 
 	if (enable)
 		val = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN;
@@ -53,17 +51,17 @@ void sun8i_mixer_layer_enable(struct sun
 		val = 0;
 
 	regmap_update_bits(mixer->engine.regs,
-			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR(chan, layer),
+			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR(channel, overlay),
 			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN, val);
 
 	if (enable)
-		val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(chan);
+		val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(channel);
 	else
 		val = 0;
 
 	regmap_update_bits(mixer->engine.regs,
 			   SUN8I_MIXER_BLEND_PIPE_CTL,
-			   SUN8I_MIXER_BLEND_PIPE_CTL_EN(chan), val);
+			   SUN8I_MIXER_BLEND_PIPE_CTL_EN(channel), val);
 }
 
 static int sun8i_mixer_drm_format_to_layer(struct drm_plane *plane,
@@ -89,15 +87,13 @@ static int sun8i_mixer_drm_format_to_lay
 	return 0;
 }
 
-int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer,
-				     int layer, struct drm_plane *plane)
+int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, int channel,
+				   int overlay, struct drm_plane *plane)
 {
 	struct drm_plane_state *state = plane->state;
 	struct drm_framebuffer *fb = state->fb;
-	/* Currently the first UI channel is used */
-	int chan = mixer->cfg->vi_num;
 
-	DRM_DEBUG_DRIVER("Updating layer %d\n", layer);
+	DRM_DEBUG_DRIVER("Updating channel %d overlay %d\n", channel, overlay);
 
 	if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
 		DRM_DEBUG_DRIVER("Primary layer, updating global size W: %u H: %u\n",
@@ -107,7 +103,7 @@ int sun8i_mixer_update_layer_coord(struc
 					      state->crtc_h));
 		DRM_DEBUG_DRIVER("Updating blender size\n");
 		regmap_write(mixer->engine.regs,
-			     SUN8I_MIXER_BLEND_ATTR_INSIZE(chan),
+			     SUN8I_MIXER_BLEND_ATTR_INSIZE(channel),
 			     SUN8I_MIXER_SIZE(state->crtc_w,
 					      state->crtc_h));
 		regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_OUTSIZE,
@@ -115,7 +111,7 @@ int sun8i_mixer_update_layer_coord(struc
 					      state->crtc_h));
 		DRM_DEBUG_DRIVER("Updating channel size\n");
 		regmap_write(mixer->engine.regs,
-			     SUN8I_MIXER_CHAN_UI_OVL_SIZE(chan),
+			     SUN8I_MIXER_CHAN_UI_OVL_SIZE(channel),
 			     SUN8I_MIXER_SIZE(state->crtc_w,
 					      state->crtc_h));
 	}
@@ -123,35 +119,33 @@ int sun8i_mixer_update_layer_coord(struc
 	/* Set the line width */
 	DRM_DEBUG_DRIVER("Layer line width: %d bytes\n", fb->pitches[0]);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_CHAN_UI_LAYER_PITCH(chan, layer),
+		     SUN8I_MIXER_CHAN_UI_LAYER_PITCH(channel, overlay),
 		     fb->pitches[0]);
 
 	/* Set height and width */
 	DRM_DEBUG_DRIVER("Layer size W: %u H: %u\n",
 			 state->crtc_w, state->crtc_h);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_CHAN_UI_LAYER_SIZE(chan, layer),
+		     SUN8I_MIXER_CHAN_UI_LAYER_SIZE(channel, overlay),
 		     SUN8I_MIXER_SIZE(state->crtc_w, state->crtc_h));
 
 	/* Set base coordinates */
 	DRM_DEBUG_DRIVER("Layer coordinates X: %d Y: %d\n",
 			 state->crtc_x, state->crtc_y);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_CHAN_UI_LAYER_COORD(chan, layer),
+		     SUN8I_MIXER_BLEND_ATTR_COORD(channel),
 		     SUN8I_MIXER_COORD(state->crtc_x, state->crtc_y));
 
 	return 0;
 }
 
-int sun8i_mixer_update_layer_formats(struct sun8i_mixer *mixer,
-				       int layer, struct drm_plane *plane)
+int sun8i_mixer_update_layer_formats(struct sun8i_mixer *mixer, int channel,
+				     int overlay, struct drm_plane *plane)
 {
 	struct drm_plane_state *state = plane->state;
 	struct drm_framebuffer *fb = state->fb;
 	bool interlaced = false;
 	u32 val;
-	/* Currently the first UI channel is used */
-	int chan = mixer->cfg->vi_num;
 	int ret;
 
 	if (plane->state->crtc)
@@ -175,21 +169,19 @@ int sun8i_mixer_update_layer_formats(str
 
 	val <<= SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_OFFSET;
 	regmap_update_bits(mixer->engine.regs,
-			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR(chan, layer),
+			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR(channel, overlay),
 			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_MASK, val);
 
 	return 0;
 }
 
-int sun8i_mixer_update_layer_buffer(struct sun8i_mixer *mixer,
-				      int layer, struct drm_plane *plane)
+int sun8i_mixer_update_layer_buffer(struct sun8i_mixer *mixer, int channel,
+				    int overlay, struct drm_plane *plane)
 {
 	struct drm_plane_state *state = plane->state;
 	struct drm_framebuffer *fb = state->fb;
 	struct drm_gem_cma_object *gem;
 	dma_addr_t paddr;
-	/* Currently the first UI channel is used */
-	int chan = mixer->cfg->vi_num;
 	int bpp;
 
 	/* Get the physical address of the buffer in memory */
@@ -221,7 +213,7 @@ int sun8i_mixer_update_layer_buffer(stru
 	DRM_DEBUG_DRIVER("Setting buffer address to %pad\n", &paddr);
 
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_CHAN_UI_LAYER_TOP_LADDR(chan, layer),
+		     SUN8I_MIXER_CHAN_UI_LAYER_TOP_LADDR(channel, overlay),
 		     lower_32_bits(paddr));
 
 	return 0;
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
@@ -123,12 +123,12 @@ engine_to_sun8i_mixer(struct sunxi_engin
 	return container_of(engine, struct sun8i_mixer, engine);
 }
 
-void sun8i_mixer_layer_enable(struct sun8i_mixer *mixer,
-				int layer, bool enable);
-int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer,
-				     int layer, struct drm_plane *plane);
-int sun8i_mixer_update_layer_formats(struct sun8i_mixer *mixer,
-				       int layer, struct drm_plane *plane);
-int sun8i_mixer_update_layer_buffer(struct sun8i_mixer *mixer,
-				      int layer, struct drm_plane *plane);
+void sun8i_mixer_layer_enable(struct sun8i_mixer *mixer, int channel,
+			      int overlay, bool enable);
+int sun8i_mixer_update_layer_coord(struct sun8i_mixer *mixer, int channel,
+				   int overlay, struct drm_plane *plane);
+int sun8i_mixer_update_layer_formats(struct sun8i_mixer *mixer, int channel,
+				     int overlay, struct drm_plane *plane);
+int sun8i_mixer_update_layer_buffer(struct sun8i_mixer *mixer, int channel,
+				    int overlay, struct drm_plane *plane);
 #endif /* _SUN8I_MIXER_H_ */