From: "Noralf Trønnes" <noralf@tronnes.org>
To: dri-devel@lists.freedesktop.org
Cc: intel-gfx@lists.freedesktop.org,
"Noralf Trønnes" <noralf@tronnes.org>,
laurent.pinchart@ideasonboard.com
Subject: [PATCH v2 10/12] drm/fb-helper: Finish the generic fbdev emulation
Date: Mon, 18 Jun 2018 16:17:37 +0200 [thread overview]
Message-ID: <20180618141739.48151-11-noralf@tronnes.org> (raw)
In-Reply-To: <20180618141739.48151-1-noralf@tronnes.org>
This adds a drm_fbdev_generic_setup() function that sets up generic
fbdev emulation with client callbacks for lastclose, hotplug and
remove/unregister.
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
---
drivers/gpu/drm/drm_fb_helper.c | 123 +++++++++++++++++++++++++++++++++++++++-
include/drm/drm_fb_helper.h | 7 +++
2 files changed, 129 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index be6bab889f1b..de98d6217864 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -67,6 +67,9 @@ static DEFINE_MUTEX(kernel_fb_helper_lock);
* helper functions used by many drivers to implement the kernel mode setting
* interfaces.
*
+ * Drivers that support a dumb buffer with a virtual address and mmap support,
+ * should try out the generic fbdev emulation using drm_fbdev_generic_setup().
+ *
* Setup fbdev emulation by calling drm_fb_helper_fbdev_setup() and tear it
* down by calling drm_fb_helper_fbdev_teardown().
*
@@ -3012,7 +3015,8 @@ static void drm_fbdev_fb_destroy(struct fb_info *info)
* Remove this when all CMA drivers have been moved over to using
* drm_fbdev_generic_setup().
*/
- drm_fbdev_generic_client_release_do(&fb_helper->client);
+ if (!fb_helper->client.funcs)
+ drm_fbdev_generic_client_release_do(&fb_helper->client);
drm_client_put(&fb_helper->client);
}
@@ -3135,6 +3139,123 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
}
EXPORT_SYMBOL(drm_fb_helper_generic_probe);
+static const struct drm_fb_helper_funcs drm_fb_helper_generic_funcs = {
+ .fb_probe = drm_fb_helper_generic_probe,
+};
+
+static void drm_fbdev_generic_client_release(struct drm_client_dev *client)
+{
+ struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
+
+ /* Check if drm_fb_helper_fbdev_setup() has been run */
+ if (fb_helper->dev)
+ drm_fbdev_generic_client_release_do(client);
+ drm_client_close(client);
+ kfree(fb_helper);
+}
+
+static void drm_fbdev_client_unregister(struct drm_client_dev *client)
+{
+ struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
+
+ if (fb_helper->fbdev)
+ drm_fb_helper_unregister_fbi(fb_helper);
+ else
+ drm_client_put(client);
+}
+
+static int drm_fbdev_client_restore(struct drm_client_dev *client)
+{
+ struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
+
+ drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper);
+
+ return 0;
+}
+
+static int drm_fbdev_client_hotplug(struct drm_client_dev *client)
+{
+ struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
+ struct drm_device *dev = client->dev;
+ int ret;
+
+ /* If drm_fb_helper_fbdev_setup() failed, we only try once */
+ if (!fb_helper->dev && fb_helper->funcs)
+ return 0;
+
+ if (dev->fb_helper)
+ return drm_fb_helper_hotplug_event(dev->fb_helper);
+
+ if (!dev->mode_config.num_connector)
+ return 0;
+
+ ret = drm_fb_helper_fbdev_setup(dev, fb_helper, &drm_fb_helper_generic_funcs,
+ fb_helper->preferred_bpp, 0);
+ if (ret) {
+ fb_helper->dev = NULL;
+ fb_helper->fbdev = NULL;
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct drm_client_funcs drm_fbdev_client_funcs = {
+ .release = drm_fbdev_generic_client_release,
+ .unregister = drm_fbdev_client_unregister,
+ .restore = drm_fbdev_client_restore,
+ .hotplug = drm_fbdev_client_hotplug,
+};
+
+/**
+ * drm_fb_helper_generic_fbdev_setup() - Setup generic fbdev emulation
+ * @dev: DRM device
+ * @preferred_bpp: Preferred bits per pixel for the device.
+ * @dev->mode_config.preferred_depth is used if this is zero.
+ *
+ * This function sets up generic fbdev emulation for drivers that supports
+ * dumb buffers with a virtual address and that can be mmap'ed.
+ *
+ * Restore, hotplug events and teardown are all taken care of. Drivers that do
+ * suspend/resume need to call drm_fb_helper_set_suspend_unlocked() themselves.
+ * Simple drivers might use drm_mode_config_helper_suspend().
+ *
+ * Drivers that set the dirty callback on their framebuffer will get a shadow
+ * fbdev buffer that is blitted onto the real buffer. This is done in order to
+ * make deferred I/O work with all kinds of buffers.
+ *
+ * This function is safe to call even when there are no connectors present.
+ * Setup will be retried on the next hotplug event.
+ *
+ * Returns:
+ * Zero on success or negative error code on failure.
+ */
+int drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp)
+{
+ struct drm_fb_helper *fb_helper;
+ int ret;
+
+ if (!drm_fbdev_emulation)
+ return 0;
+
+ fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL);
+ if (!fb_helper)
+ return -ENOMEM;
+
+ ret = drm_client_new(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs);
+ if (ret) {
+ kfree(fb_helper);
+ return ret;
+ }
+
+ fb_helper->preferred_bpp = preferred_bpp;
+
+ drm_fbdev_client_hotplug(&fb_helper->client);
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_fbdev_generic_setup);
+
/* 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 c134bbcfd2e9..5db08c8f1d25 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -354,6 +354,7 @@ 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);
+int drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp);
#else
static inline void drm_fb_helper_prepare(struct drm_device *dev,
struct drm_fb_helper *helper,
@@ -595,6 +596,12 @@ drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
return 0;
}
+static inline int
+drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp)
+{
+ return 0;
+}
+
#endif
static inline int
--
2.15.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2018-06-18 14:17 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-18 14:17 [PATCH v2 00/12] drm: Add generic fbdev emulation Noralf Trønnes
2018-06-18 14:17 ` [PATCH v2 01/12] drm: provide management functions for drm_file Noralf Trønnes
2018-06-18 14:17 ` [PATCH v2 02/12] drm/file: Don't set master on in-kernel clients Noralf Trønnes
2018-06-18 14:17 ` [PATCH v2 03/12] drm: Make ioctls available for " Noralf Trønnes
2018-06-18 14:17 ` [PATCH v2 04/12] drm: Begin an API " Noralf Trønnes
2018-06-18 14:17 ` [PATCH v2 05/12] drm/fb-helper: Add generic fbdev emulation .fb_probe function Noralf Trønnes
2018-06-18 14:17 ` [PATCH v2 06/12] drm/pl111: Set .gem_prime_vmap and .gem_prime_mmap Noralf Trønnes
2018-06-18 14:17 ` [PATCH v2 07/12] drm/cma-helper: Use the generic fbdev emulation Noralf Trønnes
2018-06-18 14:17 ` [PATCH v2 08/12] drm/client: Add client callbacks Noralf Trønnes
2018-06-18 14:17 ` [PATCH v2 09/12] drm/debugfs: Add internal client debugfs file Noralf Trønnes
2018-06-20 9:23 ` [Intel-gfx] " Daniel Vetter
2018-06-18 14:17 ` Noralf Trønnes [this message]
2018-06-18 14:17 ` [PATCH v2 11/12] drm/tinydrm: Use drm_fbdev_generic_setup() Noralf Trønnes
2018-06-18 14:17 ` [PATCH v2 12/12] drm/cma-helper: Remove drm_fb_cma_fbdev_init_with_funcs() Noralf Trønnes
2018-06-18 15:05 ` ✗ Fi.CI.CHECKPATCH: warning for drm: Add generic fbdev emulation Patchwork
2018-06-18 15:09 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-06-18 15:20 ` ✓ Fi.CI.BAT: success " Patchwork
2018-06-18 20:02 ` ✓ Fi.CI.IGT: " Patchwork
2018-06-20 9:34 ` [PATCH v2 00/12] " Daniel Vetter
2018-06-20 13:52 ` [Intel-gfx] " Noralf Trønnes
2018-06-20 15:28 ` Noralf Trønnes
2018-06-21 7:14 ` Daniel Vetter
2018-06-21 17:19 ` Noralf Trønnes
2018-06-26 13:41 ` [Intel-gfx] " Noralf Trønnes
2018-06-26 13:42 ` Daniel Vetter
2018-06-25 14:28 ` Noralf Trønnes
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=20180618141739.48151-11-noralf@tronnes.org \
--to=noralf@tronnes.org \
--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.