All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Noralf Trønnes" <noralf@tronnes.org>
To: Daniel Vetter <daniel@ffwll.ch>
Cc: intel-gfx@lists.freedesktop.org,
	laurent.pinchart@ideasonboard.com,
	dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 5/9] drm/fb-helper: Add generic fbdev emulation .fb_probe function
Date: Fri, 25 May 2018 14:42:02 +0200	[thread overview]
Message-ID: <8c876daa-5150-009f-af3a-01573144d452@tronnes.org> (raw)
In-Reply-To: <20180524091605.GH3438@phenom.ffwll.local>


Den 24.05.2018 11.16, skrev Daniel Vetter:
> On Wed, May 23, 2018 at 04:34:07PM +0200, Noralf Trønnes wrote:
>> This is the first step in getting generic fbdev emulation.
>> A drm_fb_helper_funcs.fb_probe function is added which uses the
>> DRM client API to get a framebuffer backed by a dumb buffer.
>>
>> A transitional hack for tinydrm is needed in order to switch over all
>> CMA helper drivers in a later patch. This hack will be removed when
>> tinydrm moves to vmalloc buffers.
>>
>> Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
>> ---
>>   drivers/gpu/drm/drm_fb_helper.c | 164 ++++++++++++++++++++++++++++++++++++++++
>>   include/drm/drm_fb_helper.h     |  26 +++++++
>>   2 files changed, 190 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
>> index 2ee1eaa66188..444c2b4040ea 100644
>> --- a/drivers/gpu/drm/drm_fb_helper.c
>> +++ b/drivers/gpu/drm/drm_fb_helper.c
>> @@ -30,11 +30,13 @@
>>   #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
>>   
>>   #include <linux/console.h>
>> +#include <linux/dma-buf.h>
>>   #include <linux/kernel.h>
>>   #include <linux/sysrq.h>
>>   #include <linux/slab.h>
>>   #include <linux/module.h>
>>   #include <drm/drmP.h>
>> +#include <drm/drm_client.h>
>>   #include <drm/drm_crtc.h>
>>   #include <drm/drm_fb_helper.h>
>>   #include <drm/drm_crtc_helper.h>
>> @@ -2928,6 +2930,168 @@ void drm_fb_helper_output_poll_changed(struct drm_device *dev)
>>   }
>>   EXPORT_SYMBOL(drm_fb_helper_output_poll_changed);
>>   
>> +/* @user: 1=userspace, 0=fbcon */
>> +static int drm_fbdev_fb_open(struct fb_info *info, int user)
>> +{
>> +	struct drm_fb_helper *fb_helper = info->par;
>> +
>> +	if (!try_module_get(fb_helper->dev->driver->fops->owner))
>> +		return -ENODEV;
>> +
>> +	return 0;
>> +}
>> +
>> +static int drm_fbdev_fb_release(struct fb_info *info, int user)
>> +{
>> +	struct drm_fb_helper *fb_helper = info->par;
>> +
>> +	module_put(fb_helper->dev->driver->fops->owner);
>> +
>> +	return 0;
>> +}
> Hm, I thought earlier versions of your patch series had this separately,
> for everyone. What's the reasons for merging this into the fb_probe
> implementation.

This is only necessary when struct fb_ops is defined in a library where
the owner field is the library module and not the driver module.
I realised that with this generic version it's highly unlikely that we
get another library that defines struct fb_ops, so it's only needed here.

Noralf.

>> +
>> +/*
>> + * fb_ops.fb_destroy is called by the last put_fb_info() call at the end of
>> + * unregister_framebuffer() or fb_release().
>> + */
>> +static void drm_fbdev_fb_destroy(struct fb_info *info)
>> +{
>> +	struct drm_fb_helper *fb_helper = info->par;
>> +	struct fb_ops *fbops = NULL;
>> +
>> +	DRM_DEBUG("\n");
>> +
>> +	if (fb_helper->fbdev->fbdefio) {
>> +		fb_deferred_io_cleanup(fb_helper->fbdev);
>> +		fbops = fb_helper->fbdev->fbops;
>> +	}
>> +
>> +	drm_fb_helper_fini(fb_helper);
>> +	drm_client_framebuffer_delete(fb_helper->buffer);
>> +	drm_client_free(fb_helper->client);
>> +	kfree(fb_helper);
>> +	kfree(fbops);
>> +}
> Hm, if we go with the idea that drm_clients could auto-unregister through
> a callback, then I expect this will lead to some control inversion. But we
> can fix that later on.
>
>> +
>> +static int drm_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
>> +{
>> +	struct drm_fb_helper *fb_helper = info->par;
>> +
>> +	if (fb_helper->dev->driver->gem_prime_mmap)
>> +		return fb_helper->dev->driver->gem_prime_mmap(fb_helper->buffer->gem, vma);
>> +	else
>> +		return -ENODEV;
>> +}
>> +
>> +static struct fb_ops drm_fbdev_fb_ops = {
>> +	/* No need to set owner, this module is already pinned by the driver. */
> I'd still set it, means less thinking since more obviously correct.
>
>> +	DRM_FB_HELPER_DEFAULT_OPS,
>> +	.fb_open	= drm_fbdev_fb_open,
>> +	.fb_release	= drm_fbdev_fb_release,
>> +	.fb_destroy	= drm_fbdev_fb_destroy,
>> +	.fb_mmap	= drm_fbdev_fb_mmap,
>> +	.fb_read	= drm_fb_helper_sys_read,
>> +	.fb_write	= drm_fb_helper_sys_write,
>> +	.fb_fillrect	= drm_fb_helper_sys_fillrect,
>> +	.fb_copyarea	= drm_fb_helper_sys_copyarea,
>> +	.fb_imageblit	= drm_fb_helper_sys_imageblit,
> Hm, some drivers require the cfb versions of these. In practice I guess
> there's not much of a difference really, at least on x86 and arm.
>
> We might want to document that though.
>
>> +};
>> +
>> +static struct fb_deferred_io drm_fbdev_defio = {
>> +	.delay		= HZ / 20,
>> +	.deferred_io	= drm_fb_helper_deferred_io,
>> +};
>> +
>> +/*
>> + * TODO: Remove this when tinydrm is converted to vmalloc buffers.
>> + */
>> +static int drm_fbdev_cma_deferred_io_mmap(struct fb_info *info,
>> +					  struct vm_area_struct *vma)
>> +{
>> +	fb_deferred_io_mmap(info, vma);
>> +	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
>> +
>> +	return 0;
>> +}
>> +
> Needs kerneldoc here.
>
>> +int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
>> +				struct drm_fb_helper_surface_size *sizes)
>> +{
>> +	struct drm_client_dev *client = fb_helper->client;
>> +	struct drm_client_buffer *buffer;
>> +	struct drm_framebuffer *fb;
>> +	struct fb_info *fbi;
>> +	u32 format;
>> +	int ret;
>> +
>> +	DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d)\n",
>> +		      sizes->surface_width, sizes->surface_height,
>> +		      sizes->surface_bpp);
>> +
>> +	format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth);
>> +	buffer = drm_client_framebuffer_create(client, sizes->surface_width,
>> +					       sizes->surface_height, format);
>> +	if (IS_ERR(buffer))
>> +		return PTR_ERR(buffer);
>> +
>> +	fb_helper->buffer = buffer;
>> +	fb_helper->fb = buffer->fb;
>> +	fb = buffer->fb;
>> +
>> +	fbi = drm_fb_helper_alloc_fbi(fb_helper);
>> +	if (IS_ERR(fbi)) {
>> +		ret = PTR_ERR(fbi);
>> +		goto err_free_buffer;
>> +	}
>> +
>> +	fbi->par = fb_helper;
>> +	fbi->fbops = &drm_fbdev_fb_ops;
>> +	fbi->screen_size = fb->height * fb->pitches[0];
>> +	fbi->fix.smem_len = fbi->screen_size;
>> +	fbi->screen_buffer = buffer->vaddr;
>> +	strcpy(fbi->fix.id, "DRM emulated");
>> +
>> +	drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->format->depth);
>> +	drm_fb_helper_fill_var(fbi, fb_helper, sizes->fb_width, sizes->fb_height);
>> +
>> +	if (fb->funcs->dirty) {
>> +		struct fb_ops *fbops;
>> +
>> +		/*
>> +		 * fb_deferred_io_cleanup() clears &fbops->fb_mmap so a per
>> +		 * instance version is necessary.
>> +		 */
>> +		fbops = kzalloc(sizeof(*fbops), GFP_KERNEL);
>> +		if (!fbops) {
>> +			ret = -ENOMEM;
>> +			goto err_fb_info_destroy;
>> +		}
>> +
>> +		*fbops = *fbi->fbops;
>> +		fbi->fbops = fbops;
>> +
>> +		fbi->fbdefio = &drm_fbdev_defio;
>> +
>> +		/* TODO: Remove this when tinydrm is converted to vmalloc buffers. */
>> +		fbi->fix.smem_start = page_to_phys(virt_to_page(buffer->vaddr));
>> +
>> +		fb_deferred_io_init(fbi);
>> +
>> +		/* TODO: Remove this when tinydrm is converted to vmalloc buffers. */
>> +		fbi->fbops->fb_mmap = drm_fbdev_cma_deferred_io_mmap;
>> +	}
> Ugh. Yeah defio and generic allocator through dumb buffers don't mix well.
> The only true generic solution for this would be to give userspace (and
> only userspace, for fbcon we can intercept everything) a staging buffer,
> and then upload things using the dirty callback.
>
> But that introduces another copy step, so isn't cool.
>
> I think a check for is_vmalloc_addr and if that's false, not doing any of
> the defio mmap setup would be good. Until we have a better idea. And yes
> that would need to be done after tinydrm is moved over.
>
>> +
>> +	return 0;
>> +
>> +err_fb_info_destroy:
>> +	drm_fb_helper_fini(fb_helper);
>> +err_free_buffer:
>> +	drm_client_framebuffer_delete(buffer);
>> +
>> +	return ret;
>> +}
>> +EXPORT_SYMBOL(drm_fb_helper_generic_probe);
>> +
>>   /* The Kconfig DRM_KMS_HELPER selects FRAMEBUFFER_CONSOLE (if !EXPERT)
>>    * but the module doesn't depend on any fb console symbols.  At least
>>    * attempt to load fbcon to avoid leaving the system without a usable console.
>> diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
>> index b069433e7fc1..bb38469a9502 100644
>> --- a/include/drm/drm_fb_helper.h
>> +++ b/include/drm/drm_fb_helper.h
>> @@ -30,6 +30,8 @@
>>   #ifndef DRM_FB_HELPER_H
>>   #define DRM_FB_HELPER_H
>>   
>> +struct drm_client_buffer;
>> +struct drm_client_dev;
>>   struct drm_fb_helper;
>>   
>>   #include <drm/drm_crtc.h>
>> @@ -232,6 +234,20 @@ struct drm_fb_helper {
>>   	 * See also: @deferred_setup
>>   	 */
>>   	int preferred_bpp;
>> +
>> +	/**
>> +	 * @client:
>> +	 *
>> +	 * DRM client used by the generic fbdev emulation.
>> +	 */
>> +	struct drm_client_dev *client;
>> +
>> +	/**
>> +	 * @buffer:
>> +	 *
>> +	 * Framebuffer used by the generic fbdev emulation.
>> +	 */
>> +	struct drm_client_buffer *buffer;
>>   };
>>   
>>   /**
>> @@ -330,6 +346,9 @@ void drm_fb_helper_fbdev_teardown(struct drm_device *dev);
>>   
>>   void drm_fb_helper_lastclose(struct drm_device *dev);
>>   void drm_fb_helper_output_poll_changed(struct drm_device *dev);
>> +
>> +int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
>> +				struct drm_fb_helper_surface_size *sizes);
>>   #else
>>   static inline void drm_fb_helper_prepare(struct drm_device *dev,
>>   					struct drm_fb_helper *helper,
>> @@ -564,6 +583,13 @@ static inline void drm_fb_helper_output_poll_changed(struct drm_device *dev)
>>   {
>>   }
>>   
>> +static inline int
>> +drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
>> +			    struct drm_fb_helper_surface_size *sizes)
>> +{
>> +	return 0;
>> +}
> Ok, I think this patch looks ok. With the missing kerneldoc added (which
> also explains the current limitations) this is
>
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
>
>> +
>>   #endif
>>   
>>   static inline int
>> -- 
>> 2.15.1
>>
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2018-05-25 12:42 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-23 14:34 [PATCH 0/9] drm: Add generic fbdev emulation Noralf Trønnes
2018-05-23 14:34 ` [PATCH 1/9] drm: provide management functions for drm_file Noralf Trønnes
2018-05-23 14:34 ` [PATCH 2/9] drm/file: Don't set master on in-kernel clients Noralf Trønnes
2018-05-23 14:34 ` [PATCH 3/9] drm: Make ioctls available for " Noralf Trønnes
2018-05-24  8:22   ` Daniel Vetter
2018-05-23 14:34 ` [PATCH 4/9] drm: Begin an API " Noralf Trønnes
2018-05-23 21:45   ` Thomas Hellstrom
2018-05-24  8:32     ` Daniel Vetter
2018-05-24  9:25       ` Thomas Hellstrom
2018-05-24 10:14         ` Daniel Vetter
2018-05-24 16:51           ` Thomas Hellstrom
2018-05-24  8:42   ` Daniel Vetter
2018-05-28 13:26     ` Noralf Trønnes
2018-05-29  7:53       ` Daniel Vetter
2018-05-23 14:34 ` [PATCH 5/9] drm/fb-helper: Add generic fbdev emulation .fb_probe function Noralf Trønnes
2018-05-24  9:16   ` Daniel Vetter
2018-05-24 10:16     ` Daniel Vetter
2018-05-25 12:42     ` Noralf Trønnes [this message]
2018-05-29  7:54       ` Daniel Vetter
2018-12-28 20:38         ` Daniel Vetter
2019-01-03 17:06           ` Noralf Trønnes
2019-01-07 10:14             ` Daniel Vetter
2018-05-23 14:34 ` [PATCH 6/9] drm/pl111: Set .gem_prime_vmap and .gem_prime_mmap Noralf Trønnes
2018-05-30 19:04   ` Eric Anholt
2018-05-23 14:34 ` [PATCH 7/9] drm/cma-helper: Use the generic fbdev emulation Noralf Trønnes
2018-05-24 10:16   ` Daniel Vetter
2018-05-23 14:34 ` [PATCH 8/9] drm/client: Add client callbacks Noralf Trønnes
2018-05-24  9:52   ` Daniel Vetter
2018-05-23 14:34 ` [PATCH 9/9] drm/fb-helper: Finish the generic fbdev emulation Noralf Trønnes
2018-05-24  9:57   ` Daniel Vetter
2018-05-23 15:20 ` ✗ Fi.CI.CHECKPATCH: warning for drm: Add " Patchwork
2018-05-23 15:38 ` ✓ Fi.CI.BAT: success " Patchwork
2018-05-23 17:31 ` ✗ Fi.CI.IGT: failure " Patchwork
2018-05-24 10:17 ` [PATCH 0/9] " Daniel Vetter

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=8c876daa-5150-009f-af3a-01573144d452@tronnes.org \
    --to=noralf@tronnes.org \
    --cc=daniel@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=laurent.pinchart@ideasonboard.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.