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

Daniel Vetter daniel at ffwll.ch
Wed Mar 18 03:04:52 PDT 2015


On Wed, Mar 11, 2015 at 03:25:18PM +0100, Benjamin Gaignard wrote:
> 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>

Seems to be incomplete - you don't switch over the legacy entry points to
atomic helpers for plane update/disable, connector->dpms and page_flip.
-Daniel

> ---
>  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
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


More information about the dri-devel mailing list