All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Zimmermann <tzimmermann@suse.de>
To: daniel@ffwll.ch, christian.koenig@amd.com, noralf@tronnes.org
Cc: Thomas Zimmermann <tzimmermann@suse.de>, dri-devel@lists.freedesktop.org
Subject: [PATCH 7/8] drm/fb-helper: Select between fb_{sys, cfb}_read() and _write()
Date: Wed,  6 Nov 2019 10:31:20 +0100	[thread overview]
Message-ID: <20191106093121.21762-8-tzimmermann@suse.de> (raw)
In-Reply-To: <20191106093121.21762-1-tzimmermann@suse.de>

Generic fbdev emulation used to access framebuffers as if they were
located in system memory.

Depending on the whether the framebuffer is in I/O or system memory,
the fbdev emulation now calls the correct functions for accessing each.
This change allows to support generic fbdev emulation on systems that
treat both memory areas differently.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/drm_fb_helper.c | 110 ++++++++++++++++++++++++++++++--
 include/drm/drm_fb_helper.h     |  14 ++++
 2 files changed, 118 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index eff75fad7cab..174e6d97223f 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -771,6 +771,45 @@ void drm_fb_helper_sys_imageblit(struct fb_info *info,
 }
 EXPORT_SYMBOL(drm_fb_helper_sys_imageblit);
 
+/**
+ * drm_fb_helper_cfb_read - wrapper around fb_cfb_read
+ * @info: fb_info struct pointer
+ * @buf: userspace buffer to read from framebuffer memory
+ * @count: number of bytes to read from framebuffer memory
+ * @ppos: read offset within framebuffer memory
+ *
+ * A wrapper around fb_cfb_read implemented by fbdev core
+ */
+ssize_t drm_fb_helper_cfb_read(struct fb_info *info, char __user *buf,
+			       size_t count, loff_t *ppos)
+{
+	return fb_cfb_read(info, buf, count, ppos);
+}
+EXPORT_SYMBOL(drm_fb_helper_cfb_read);
+
+/**
+ * drm_fb_helper_cfb_write - wrapper around fb_cfb_write
+ * @info: fb_info struct pointer
+ * @buf: userspace buffer to write to framebuffer memory
+ * @count: number of bytes to write to framebuffer memory
+ * @ppos: write offset within framebuffer memory
+ *
+ * A wrapper around fb_cfb_write implemented by fbdev core
+ */
+ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf,
+				size_t count, loff_t *ppos)
+{
+	ssize_t ret;
+
+	ret = fb_cfb_write(info, buf, count, ppos);
+	if (ret > 0)
+		drm_fb_helper_dirty(info, 0, 0, info->var.xres,
+				    info->var.yres);
+
+	return ret;
+}
+EXPORT_SYMBOL(drm_fb_helper_cfb_write);
+
 /**
  * drm_fb_helper_cfb_fillrect - wrapper around cfb_fillrect
  * @info: fbdev registered by the helper
@@ -2122,6 +2161,59 @@ static int drm_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 		return -ENODEV;
 }
 
+static ssize_t drm_fbdev_fb_read(struct fb_info *info, char __user *buf,
+				 size_t count, loff_t *ppos)
+{
+	struct drm_fb_helper *fb_helper = info->par;
+
+	if (fb_helper->screen_buffer_is_iomem)
+		return drm_fb_helper_cfb_read(info, buf, count, ppos);
+	return drm_fb_helper_sys_read(info, buf, count, ppos);
+}
+
+static ssize_t drm_fbdev_fb_write(struct fb_info *info, const char __user *buf,
+				  size_t count, loff_t *ppos)
+{
+	struct drm_fb_helper *fb_helper = info->par;
+
+	if (fb_helper->screen_buffer_is_iomem)
+		return drm_fb_helper_cfb_write(info, buf, count, ppos);
+	return drm_fb_helper_sys_write(info, buf, count, ppos);
+}
+
+static void drm_fbdev_fb_fillrect(struct fb_info *info,
+				  const struct fb_fillrect *rect)
+{
+	struct drm_fb_helper *fb_helper = info->par;
+
+	if (fb_helper->screen_buffer_is_iomem)
+		drm_fb_helper_cfb_fillrect(info, rect);
+	else
+		drm_fb_helper_sys_fillrect(info, rect);
+}
+
+static void drm_fbdev_fb_copyarea(struct fb_info *info,
+				  const struct fb_copyarea *region)
+{
+	struct drm_fb_helper *fb_helper = info->par;
+
+	if (fb_helper->screen_buffer_is_iomem)
+		drm_fb_helper_cfb_copyarea(info, region);
+	else
+		drm_fb_helper_sys_copyarea(info, region);
+}
+
+static void drm_fbdev_fb_imageblit(struct fb_info *info,
+				   const struct fb_image *image)
+{
+	struct drm_fb_helper *fb_helper = info->par;
+
+	if (fb_helper->screen_buffer_is_iomem)
+		drm_fb_helper_cfb_imageblit(info, image);
+	else
+		drm_fb_helper_sys_imageblit(info, image);
+}
+
 static struct fb_ops drm_fbdev_fb_ops = {
 	.owner		= THIS_MODULE,
 	DRM_FB_HELPER_DEFAULT_OPS,
@@ -2129,11 +2221,11 @@ static struct fb_ops drm_fbdev_fb_ops = {
 	.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,
+	.fb_read	= drm_fbdev_fb_read,
+	.fb_write	= drm_fbdev_fb_write,
+	.fb_fillrect	= drm_fbdev_fb_fillrect,
+	.fb_copyarea	= drm_fbdev_fb_copyarea,
+	.fb_imageblit	= drm_fbdev_fb_imageblit,
 };
 
 static struct fb_deferred_io drm_fbdev_defio = {
@@ -2209,10 +2301,15 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
 		fbi->screen_buffer = shadow;
 		fbi->fbdefio = &drm_fbdev_defio;
 
+		/* The shadowfb is always in system memory. */
+		fb_helper->screen_buffer_is_iomem = false;
+
 		fb_deferred_io_init(fbi);
 	} else {
+		bool is_iomem;
+
 		/* buffer is mapped for HW framebuffer */
-		vaddr = drm_client_buffer_vmap(fb_helper->buffer, NULL);
+		vaddr = drm_client_buffer_vmap(fb_helper->buffer, &is_iomem);
 		if (IS_ERR(vaddr))
 			return PTR_ERR(vaddr);
 
@@ -2223,6 +2320,7 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
 			fbi->fix.smem_start =
 				page_to_phys(virt_to_page(fbi->screen_buffer));
 #endif
+		fb_helper->screen_buffer_is_iomem = is_iomem;
 	}
 
 	return 0;
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 2338e9f94a03..afceae8db4af 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -155,6 +155,15 @@ struct drm_fb_helper {
 	 */
 	struct list_head kernel_fb_list;
 
+	/**
+	 * @screen_buffer_is_iomem
+	 *
+	 * True if info->screen_buffer refers to I/O memory, false otherwise.
+	 * Depending on this flag, fb_ops should either use sys to cfb
+	 * functions.
+	 */
+	bool screen_buffer_is_iomem;
+
 	/**
 	 * @delayed_hotplug:
 	 *
@@ -248,6 +257,11 @@ void drm_fb_helper_sys_copyarea(struct fb_info *info,
 void drm_fb_helper_sys_imageblit(struct fb_info *info,
 				 const struct fb_image *image);
 
+ssize_t drm_fb_helper_cfb_read(struct fb_info *info, char __user *buf,
+			       size_t count, loff_t *ppos);
+ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf,
+				size_t count, loff_t *ppos);
+
 void drm_fb_helper_cfb_fillrect(struct fb_info *info,
 				const struct fb_fillrect *rect);
 void drm_fb_helper_cfb_copyarea(struct fb_info *info,
-- 
2.23.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2019-11-06  9:31 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-06  9:31 [RFC][PATCH 0/8] Support I/O memory in generic fbdev emulation Thomas Zimmermann
2019-11-06  9:31 ` [PATCH 1/8] drm/vram-helper: Tell caller if vmap() returned I/O memory Thomas Zimmermann
2019-11-06  9:31 ` [PATCH 2/8] drm/qxl: Tell caller if kmap() " Thomas Zimmermann
2019-11-06  9:31 ` [PATCH 3/8] drm: Add is_iomem return parameter to struct drm_gem_object_funcs.vmap Thomas Zimmermann
2019-11-06  9:31 ` [PATCH 4/8] drm/gem: Return I/O-memory flag from drm_gem_vram() Thomas Zimmermann
2019-11-06  9:31 ` [PATCH 5/8] drm/client: Return I/O memory flag from drm_client_buffer_vmap() Thomas Zimmermann
2019-11-06  9:31 ` [PATCH 6/8] fbdev: Export default read and write operations as fb_cfb_{read, write}() Thomas Zimmermann
2019-11-06  9:31 ` Thomas Zimmermann [this message]
2019-11-06  9:31 ` [PATCH 8/8] drm/fb-helper: Handle I/O memory correctly when flushing shadow fb Thomas Zimmermann
2019-11-06 10:05 ` [RFC][PATCH 0/8] Support I/O memory in generic fbdev emulation 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=20191106093121.21762-8-tzimmermann@suse.de \
    --to=tzimmermann@suse.de \
    --cc=christian.koenig@amd.com \
    --cc=daniel@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=noralf@tronnes.org \
    /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.