dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Vetter <daniel@ffwll.ch>
To: Thomas Zimmermann <tzimmermann@suse.de>
Cc: dri-devel@lists.freedesktop.org, kraxel@redhat.com,
	airlied@redhat.com, sam@ravnborg.org, emil.velikov@collabora.com
Subject: Re: [PATCH 2/7] drm/udl: Convert to struct drm_simple_display_pipe
Date: Thu, 28 Nov 2019 15:09:18 +0100	[thread overview]
Message-ID: <20191128140918.GW406127@phenom.ffwll.local> (raw)
In-Reply-To: <20191126134707.22385-3-tzimmermann@suse.de>

On Tue, Nov 26, 2019 at 02:47:02PM +0100, Thomas Zimmermann wrote:
> Udl has a single display pipeline with aprimary plane; perfect for
> simple-pipe helpers. Convert it over. The old encoder and CRTC code
> becomes unused and obsolete.
> 
> Exported formats for the primary plane are RGB565 and XRGB8888, with
> the latter being emulated. The 16-bit format is the default and what
> is used when communicating with the device.
> 
> This patch enables atomic modesetting for udl devices.
> 
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
>  drivers/gpu/drm/udl/udl_connector.c |  12 +--
>  drivers/gpu/drm/udl/udl_drv.c       |   9 +-
>  drivers/gpu/drm/udl/udl_drv.h       |   4 +-
>  drivers/gpu/drm/udl/udl_modeset.c   | 142 ++++++++++++++++++++++++----
>  4 files changed, 136 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c
> index 68e113ae44f7..47ab8d150f1a 100644
> --- a/drivers/gpu/drm/udl/udl_connector.c
> +++ b/drivers/gpu/drm/udl/udl_connector.c
> @@ -7,6 +7,7 @@
>   * Copyright (C) 2009 Bernie Thompson <bernie@plugable.com>
>   */
>  
> +#include <drm/drm_atomic_state_helper.h>
>  #include <drm/drm_crtc_helper.h>
>  #include <drm/drm_probe_helper.h>
>  
> @@ -90,13 +91,6 @@ udl_detect(struct drm_connector *connector, bool force)
>  	return connector_status_connected;
>  }
>  
> -static int udl_connector_set_property(struct drm_connector *connector,
> -				      struct drm_property *property,
> -				      uint64_t val)
> -{
> -	return 0;
> -}
> -
>  static void udl_connector_destroy(struct drm_connector *connector)
>  {
>  	struct udl_drm_connector *udl_connector =
> @@ -117,10 +111,12 @@ static const struct drm_connector_helper_funcs udl_connector_helper_funcs = {
>  
>  static const struct drm_connector_funcs udl_connector_funcs = {
>  	.dpms = drm_helper_connector_dpms,
> +	.reset = drm_atomic_helper_connector_reset,
>  	.detect = udl_detect,
>  	.fill_modes = drm_helper_probe_single_connector_modes,
>  	.destroy = udl_connector_destroy,
> -	.set_property = udl_connector_set_property,
> +	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> +	.atomic_destroy_state   = drm_atomic_helper_connector_destroy_state,
>  };
>  
>  struct drm_connector *udl_connector_init(struct drm_device *dev)
> diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
> index d5783fa32c5b..b3fa6bf41acc 100644
> --- a/drivers/gpu/drm/udl/udl_drv.c
> +++ b/drivers/gpu/drm/udl/udl_drv.c
> @@ -21,17 +21,14 @@ static int udl_usb_suspend(struct usb_interface *interface,
>  {
>  	struct drm_device *dev = usb_get_intfdata(interface);
>  
> -	drm_kms_helper_poll_disable(dev);
> -	return 0;
> +	return drm_mode_config_helper_suspend(dev);
>  }
>  
>  static int udl_usb_resume(struct usb_interface *interface)
>  {
>  	struct drm_device *dev = usb_get_intfdata(interface);
>  
> -	drm_kms_helper_poll_enable(dev);
> -	udl_modeset_restore(dev);
> -	return 0;
> +	return drm_mode_config_helper_resume(dev);

Please mention in the commit message that you're also switching over to
the atomic-based generic suspend/resume helpers. Might even want to split
that out as a separate patch (but will require minor adjustements in
udl_modeset_restore).


>  }
>  
>  DEFINE_DRM_GEM_FOPS(udl_driver_fops);
> @@ -45,7 +42,7 @@ static void udl_driver_release(struct drm_device *dev)
>  }
>  
>  static struct drm_driver driver = {
> -	.driver_features = DRIVER_MODESET | DRIVER_GEM,
> +	.driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
>  	.release = udl_driver_release,
>  
>  	/* gem hooks */
> diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
> index 8dc04717abac..23346bdc74bc 100644
> --- a/drivers/gpu/drm/udl/udl_drv.h
> +++ b/drivers/gpu/drm/udl/udl_drv.h
> @@ -17,6 +17,7 @@
>  #include <drm/drm_device.h>
>  #include <drm/drm_framebuffer.h>
>  #include <drm/drm_gem.h>
> +#include <drm/drm_simple_kms_helper.h>
>  
>  struct drm_encoder;
>  struct drm_mode_create_dumb;
> @@ -53,6 +54,8 @@ struct udl_device {
>  	struct usb_device *udev;
>  	struct drm_crtc *crtc;
>  
> +	struct drm_simple_display_pipe display_pipe;
> +
>  	/* active framebuffer on the 16-bit channel */
>  	const struct drm_framebuffer *active_fb_16;
>  	spinlock_t active_fb_16_lock;
> @@ -76,7 +79,6 @@ struct udl_device {
>  
>  /* modeset */
>  int udl_modeset_init(struct drm_device *dev);
> -void udl_modeset_restore(struct drm_device *dev);
>  void udl_modeset_cleanup(struct drm_device *dev);
>  struct drm_connector *udl_connector_init(struct drm_device *dev);
>  
> diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c
> index 5bb1522036c7..c8bd438de6e9 100644
> --- a/drivers/gpu/drm/udl/udl_modeset.c
> +++ b/drivers/gpu/drm/udl/udl_modeset.c
> @@ -9,12 +9,16 @@
>  
>   */
>  
> +#include <drm/drm_atomic_helper.h>
>  #include <drm/drm_crtc_helper.h>
> +#include <drm/drm_gem_framebuffer_helper.h>
>  #include <drm/drm_modeset_helper_vtables.h>
>  #include <drm/drm_vblank.h>
>  
>  #include "udl_drv.h"
>  
> +#define UDL_COLOR_DEPTH_16BPP	0
> +
>  /*
>   * All DisplayLink bulk operations start with 0xAF, followed by specific code
>   * All operations are written to buffers which then later get sent to device
> @@ -415,14 +419,126 @@ static int udl_crtc_init(struct drm_device *dev)
>  	return 0;
>  }
>  
> +/*
> + * Simple display pipeline
> + */
> +
> +static const uint32_t udl_simple_display_pipe_formats[] = {
> +	DRM_FORMAT_RGB565,
> +	DRM_FORMAT_XRGB8888,
> +};
> +
> +static enum drm_mode_status
> +udl_simple_display_pipe_mode_valid(struct drm_simple_display_pipe *pipe,
> +				   const struct drm_display_mode *mode)
> +{
> +	return MODE_OK;
> +}
> +
> +static void
> +udl_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
> +			       struct drm_crtc_state *crtc_state,
> +			       struct drm_plane_state *plane_state)
> +{
> +	struct drm_crtc *crtc = &pipe->crtc;
> +	struct drm_device *dev = crtc->dev;
> +	struct drm_framebuffer *fb = plane_state->fb;
> +	struct udl_device *udl = dev->dev_private;
> +	struct drm_display_mode *mode = &crtc_state->mode;
> +	char *buf;
> +	char *wrptr;
> +	int color_depth = UDL_COLOR_DEPTH_16BPP;
> +
> +	udl->crtc = crtc;
> +
> +	buf = (char *)udl->mode_buf;
> +
> +	/* This first section has to do with setting the base address on the
> +	 * controller associated with the display. There are 2 base
> +	 * pointers, currently, we only use the 16 bpp segment.
> +	 */
> +	wrptr = udl_vidreg_lock(buf);
> +	wrptr = udl_set_color_depth(wrptr, color_depth);
> +	/* set base for 16bpp segment to 0 */
> +	wrptr = udl_set_base16bpp(wrptr, 0);
> +	/* set base for 8bpp segment to end of fb */
> +	wrptr = udl_set_base8bpp(wrptr, 2 * mode->vdisplay * mode->hdisplay);
> +
> +	wrptr = udl_set_vid_cmds(wrptr, mode);
> +	wrptr = udl_set_blank(wrptr, DRM_MODE_DPMS_ON);
> +	wrptr = udl_vidreg_unlock(wrptr);
> +
> +	wrptr = udl_dummy_render(wrptr);
> +
> +	spin_lock(&udl->active_fb_16_lock);
> +	udl->active_fb_16 = fb;
> +	spin_unlock(&udl->active_fb_16_lock);
> +	udl->mode_buf_len = wrptr - buf;
> +
> +	udl_handle_damage(fb, 0, 0, fb->width, fb->height);
> +
> +	udl_crtc_dpms(&pipe->crtc, DRM_MODE_DPMS_ON);

Having a _dpms() function is very much legacy-modeset style. I think much
cleaner if you'd just inline the relevant part of the function here and
below.

> +
> +	crtc_state->no_vblank = true;
> +}
> +
> +static void
> +udl_simple_display_pipe_disable(struct drm_simple_display_pipe *pipe)
> +{
> +	udl_crtc_dpms(&pipe->crtc, DRM_MODE_DPMS_OFF);
> +}
> +
> +static int
> +udl_simple_display_pipe_check(struct drm_simple_display_pipe *pipe,
> +			      struct drm_plane_state *plane_state,
> +			      struct drm_crtc_state *crtc_state)
> +{
> +	return 0;
> +}
> +
> +static void
> +udl_simple_display_pipe_update(struct drm_simple_display_pipe *pipe,
> +			       struct drm_plane_state *old_plane_state)
> +{
> +	struct drm_device *dev = pipe->crtc.dev;
> +	struct udl_device *udl = dev->dev_private;
> +	struct drm_framebuffer *fb = pipe->plane.state->fb;
> +
> +	spin_lock(&udl->active_fb_16_lock);
> +	udl->active_fb_16 = fb;
> +	spin_unlock(&udl->active_fb_16_lock);
> +
> +	if (!fb)
> +		return;
> +
> +	udl_handle_damage(fb, 0, 0, fb->width, fb->height);
> +}
> +
> +static const
> +struct drm_simple_display_pipe_funcs udl_simple_display_pipe_funcs = {
> +	.mode_valid = udl_simple_display_pipe_mode_valid,
> +	.enable = udl_simple_display_pipe_enable,
> +	.disable = udl_simple_display_pipe_disable,
> +	.check = udl_simple_display_pipe_check,
> +	.update = udl_simple_display_pipe_update,
> +	.prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
> +};
> +
> +/*
> + * Modesetting
> + */
> +
>  static const struct drm_mode_config_funcs udl_mode_funcs = {
>  	.fb_create = udl_fb_user_fb_create,
> +	.atomic_check  = drm_atomic_helper_check,
> +	.atomic_commit = drm_atomic_helper_commit,
>  };
>  
>  int udl_modeset_init(struct drm_device *dev)
>  {
> +	size_t format_count = ARRAY_SIZE(udl_simple_display_pipe_formats);
> +	struct udl_device *udl = dev->dev_private;
>  	struct drm_connector *connector;
> -	struct drm_encoder *encoder;
>  	int ret;
>  
>  	drm_mode_config_init(dev);
> @@ -444,10 +560,16 @@ int udl_modeset_init(struct drm_device *dev)
>  		goto err_drm_mode_config_cleanup;
>  	}
>  
> -	udl_crtc_init(dev);
> +	format_count = ARRAY_SIZE(udl_simple_display_pipe_formats);
>  
> -	encoder = udl_encoder_init(dev);
> -	drm_connector_attach_encoder(connector, encoder);
> +	ret = drm_simple_display_pipe_init(dev, &udl->display_pipe,
> +					   &udl_simple_display_pipe_funcs,
> +					   udl_simple_display_pipe_formats,
> +					   format_count, NULL, connector);
> +	if (ret)
> +		goto err_drm_mode_config_cleanup;
> +
> +	drm_mode_config_reset(dev);
>  
>  	return 0;
>  
> @@ -456,18 +578,6 @@ int udl_modeset_init(struct drm_device *dev)
>  	return ret;
>  }
>  
> -void udl_modeset_restore(struct drm_device *dev)
> -{
> -	struct udl_device *udl = dev->dev_private;
> -	struct drm_framebuffer *fb;
> -
> -	if (!udl->crtc || !udl->crtc->primary->fb)
> -		return;
> -	udl_crtc_commit(udl->crtc);
> -	fb = udl->crtc->primary->fb;
> -	udl_handle_damage(fb, 0, 0, fb->width, fb->height);
> -}
> -
>  void udl_modeset_cleanup(struct drm_device *dev)
>  {
>  	drm_mode_config_cleanup(dev);

Where's all the deleted code that removes the udl crtc and encoder
code/structs?

Cheers, Daniel

> -- 
> 2.23.0
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2019-11-28 14:09 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-26 13:47 [PATCH 0/7] drm/udl: Convert to simple-pipe helpers and clean up Thomas Zimmermann
2019-11-26 13:47 ` [PATCH 1/7] drm/udl: Init connector before encoder and CRTC Thomas Zimmermann
2019-11-28 14:02   ` Daniel Vetter
2019-11-26 13:47 ` [PATCH 2/7] drm/udl: Convert to struct drm_simple_display_pipe Thomas Zimmermann
2019-11-28 14:09   ` Daniel Vetter [this message]
2019-11-26 13:47 ` [PATCH 3/7] drm/udl: Remove unused encoder and CRTC code Thomas Zimmermann
2019-11-28 14:10   ` Daniel Vetter
2019-11-26 13:47 ` [PATCH 4/7] drm/udl: Set preferred color depth to 16 bpp Thomas Zimmermann
2019-11-26 13:47 ` [PATCH 5/7] drm/udl: Convert to drm_atomic_helper_dirtyfb() Thomas Zimmermann
2019-11-28 14:13   ` Daniel Vetter
2019-11-29 18:04   ` Emil Velikov
2019-11-29 18:38     ` Daniel Vetter
2019-11-26 13:47 ` [PATCH 6/7] drm/udl: Remove struct udl_device.active_fb_16 Thomas Zimmermann
2019-11-28 14:14   ` Daniel Vetter
2019-11-26 13:47 ` [PATCH 7/7] drm/udl: Move udl_handle_damage() into udl_modeset.c Thomas Zimmermann
2019-11-28 14:15   ` Daniel Vetter
2019-12-02  9:27   ` Emil Velikov
2019-12-03 11:31     ` Thomas Zimmermann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191128140918.GW406127@phenom.ffwll.local \
    --to=daniel@ffwll.ch \
    --cc=airlied@redhat.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=emil.velikov@collabora.com \
    --cc=kraxel@redhat.com \
    --cc=sam@ravnborg.org \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox