From: Thomas Zimmermann <tzimmermann@suse.de>
To: airlied@linux.ie, daniel@ffwll.ch,
maarten.lankhorst@linux.intel.com, mripard@kernel.org,
sean@poorly.run, b.zolnierkie@samsung.com, ajax@redhat.com,
ville.syrjala@linux.intel.com, malat@debian.org,
michel@daenzer.net
Cc: gregkh@linuxfoundation.org, linux-fbdev@vger.kernel.org,
Thomas Zimmermann <tzimmermann@suse.de>,
dri-devel@lists.freedesktop.org, corbet@lwn.net
Subject: [PATCH v2 12/15] drm/fbconv: Add helper documentation
Date: Mon, 14 Oct 2019 14:04:13 +0000 [thread overview]
Message-ID: <20191014140416.28517-13-tzimmermann@suse.de> (raw)
In-Reply-To: <20191014140416.28517-1-tzimmermann@suse.de>
There's now a tutorial on how to create a DRM driver on top of fbconv
helpers. The DRM TODO list contains an entry for converting fbdev
drivers over to DRM.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
Documentation/gpu/drm-kms-helpers.rst | 12 ++
Documentation/gpu/todo.rst | 15 +++
drivers/gpu/drm/drm_fbconv_helper.c | 181 ++++++++++++++++++++++++++
3 files changed, 208 insertions(+)
diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
index 9668a7fe2408..1232a3ef24ff 100644
--- a/Documentation/gpu/drm-kms-helpers.rst
+++ b/Documentation/gpu/drm-kms-helpers.rst
@@ -411,3 +411,15 @@ SHMEM GEM Helper Reference
.. kernel-doc:: drivers/gpu/drm/drm_gem_shmem_helper.c
:export:
+
+fbdev Conversion Helper Reference
+================+
+.. kernel-doc:: drivers/gpu/drm/drm_fbconv_helper.c
+ :doc: fbconv helpers
+
+.. kernel-doc:: include/drm/drm_fbconv_helper.h
+ :internal:
+
+.. kernel-doc:: drivers/gpu/drm/drm_fbconv_helper.c
+ :export:
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 79785559d711..1be44a17f3e8 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -462,3 +462,18 @@ Contact: Sam Ravnborg
Outside DRM
=====+
+Convert fbdev drivers to DRM
+----------------------------
+
+There are plenty of fbdev drivers for old hardware. With fbconv helpers, we
+have a simple and clean way of transitioning fbdev drivers to DRM. Set up a
+simple DRM driver that builds onto the fbconv helpers, copy over the fbdev
+driver and connect both. This should result in a basic DRM driver that can
+run X11 and Weston. There's a tutorial for this process with example source
+code in the fbconv documentation.
+
+From there, refactor the driver source code into a clean DRM driver that
+requires neither fbdev nor fbconv helpers.
+
+Contact: Thomas Zimmermann
diff --git a/drivers/gpu/drm/drm_fbconv_helper.c b/drivers/gpu/drm/drm_fbconv_helper.c
index 7d7e4da2a29e..1fa240a4789f 100644
--- a/drivers/gpu/drm/drm_fbconv_helper.c
+++ b/drivers/gpu/drm/drm_fbconv_helper.c
@@ -18,6 +18,187 @@
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>
+/**
+ * DOC: fbconv helpers
+ *
+ * The Linux kernel's fbdev subsystem provides a wide range of drivers for
+ * older graphics hardware. Except for these existng drivers, fbdev is
+ * deprecated and expected to be removed at some point in the future. All new
+ * development happens in DRM. Some of the fbdev drivers are worth carrying
+ * forward. The fbconv helper functions provide a framework for porting fbdev
+ * drivers to DRM.
+ *
+ * When porting over fbdev drivers to DRM, the most significant problem is the
+ * difference in how the internal driver interfaces work. Fbdev has a single
+ * function, struct fb_ops.fb_set_par(), to set video mode and framebuffer
+ * format. DRM use a much more fine-grained interface. In fbdev, framebuffer
+ * memory is managed by a single client, while in DRM multiple clients can
+ * hold buffers with framebuffer data.
+ *
+ * The fbconv helper library provides a set of data structures and functions
+ * that connect DRM and fbdev. The resulting DRM driver maps DRM operations
+ * to fbdev interfaces and uses an fbdev driver for its hardware operations.
+ * Such a driver is not intended to be merged into DRM as-is. It does,
+ * however, provide a starting point for refactoring the fbdev driver's
+ * implementation into first-class DRM code.
+ *
+ * As an example, we create a DRM driver from vesafb, fbdev's generic
+ * vesa driver. We begin by creating a DRM stub driver vesadrm. Please keep
+ * in mind that the provided code is for illustrative purposes and requires
+ * error handling.
+ *
+ * .. code-block:: c
+ *
+ * DEFINE_DRM_GEM_SHMEM_FOPS(vesadrm_file_operations);
+ *
+ * static struct drm_driver vesadrm_driver = {
+ * .major = 1,
+ * .minor = 0,
+ * .patchlevel = 0,
+ * .name = "vesadrm",
+ * .desc = "DRM VESA driver",
+ * .date = "01/01/1970",
+ * .driver_features = DRIVER_ATOMIC |
+ * DRIVER_GEM |
+ * DRIVER_MODESET,
+ * .fops = &vesadrm_file_operations,
+ * DRM_GEM_SHMEM_DRIVER_OPS,
+ * };
+ *
+ * Fbconv uses SHMEM, so we set up the structures accordingly.
+ *
+ * The fbdev code usually calls register_framebuffer() and
+ * unregister_framebuffer() to connect and disconnect itself to the fbdev
+ * core code. In our case, we replace these calls with
+ * vesadrm_register_framebuffer() and vesadrm_unregister_framebuffer(), which
+ * serve as entry points for vesafb.
+ *
+ * .. code-block:: c
+ *
+ * #include <drm/drm/fbconv_helper.h>
+ *
+ * struct vesadrm_device {
+ * struct drm_device dev;
+ * struct fb_info *fb_info;
+ *
+ * struct drm_fbconv_modeset modeset;
+ * };
+ *
+ * struct vesadrm_device* vesadrm_register_framebuffer(struct fb_info *fb_info)
+ * {
+ * struct vesadrm *vdev;
+ *
+ * drm_fbconv_fill_fb_info(fb_info);
+ *
+ * vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
+ * vesadrm_device_init(vdev, &vesadrm_driver, fb_info)
+ *
+ * drm_dev_register(&vdev->dev, 0);
+ *
+ * return vdev;
+ * }
+ *
+ * Here, we have the first references to fbconf helpers. The instance
+ * of struct drm_fbconv_modeset is the central data structure for fbconv.
+ * Built upon struct drm_simple_display_pipe, it stores most state for the
+ * DRM driver.
+ *
+ * The function vesadrm_register_framebuffer() will later be called by
+ * vesafb code with the fbdev driver's fb_info structure. In core fbdev,
+ * register_framebuffer() would fill fb_info with general state and complete
+ * registration. With fbconv helpers, drm_fbconv_fill_fb_info() does this.
+ * It's a simplified version of the fbdev setup process, without device file
+ * creation, registration, or events. No console is created either.
+ * Finally vesadrm_register_framebuffer() initializes the vesadrm device and
+ * registers the DRM device. At this point, vesadrm is completely initialized.
+ *
+ * For completeness, here's the implementation of
+ * vesadrm_unregister_framebuffer(), which shuts the device down.
+ *
+ * .. code-block:: c
+ *
+ * void vesadrm_unregister_framebuffer(struct vesadrm_device *vdev)
+ * {
+ * struct fb_info *fb_info = vdev->fb_info;
+ *
+ * vesadrm_device_cleanup(vdev);
+ * kfree(vdev);
+ * drm_fbconv_cleanup_fb_info(fb_info);
+ * }
+ *
+ * Next we need an implementation of vesadrm_device_init() and
+ * vesadrm_device_cleanup(). These functions handle the details of
+ * device configuration and console setup. As all this functionality
+ * is provided by helpers, the actual implementation is fairly small.
+ *
+ * .. code-block:: c
+ *
+ * static int vesadrm_device_init(struct vesadrm_device *vdev,
+ * struct drm_driver *drv,
+ * struct fb_info *fb_info)
+ * {
+ * static const uint32_t formats[] = {
+ * DRM_FORMAT_XRGB8888,
+ * DRM_FORMAT_RGB565
+ * };
+ * static unsigned int max_width = 1600;
+ * static unsigned int max_height = 1200;
+ * static unsigned int preferred_depth = 32;
+ *
+ * drm_dev_init(&vdev->dev, drv, fb_info->device);
+ *
+ * vdev->dev.dev_private = vdev;
+ * vdev->dev.pdev = container_of(fb_info->device, struct pci_dev, dev);
+ * vdev->fb_info = fb_info;
+ *
+ * drm_fbconv_modeset_init(&vdev->modeset, &vdev->dev, fb_info,
+ * max_width, max_height, preferred_depth);
+ *
+ * drm_fbconv_modeset_setup_pipe(&vdev->modeset, NULL, formats,
+ * ARRAY_SIZE(formats), NULL, NULL);
+ *
+ * drm_fbdev_generic_setup(&vdev->dev, 0);
+ *
+ * return 0;
+ * }
+ *
+ * static void vesadrm_device_cleanup(struct vesadrm_device *vdev)
+ * {
+ * struct drm_device *dev = &vdev->dev;
+ *
+ * drm_fbconv_modeset_cleanup(&vdev->modeset);
+ *
+ * drm_dev_fini(dev);
+ * dev->dev_private = NULL;
+ * }
+ *
+ * In vesadrm_device_init(), several device-specific constants are declared.
+ * Depending on the hardware, drivers should set them accordingly.
+ * The call to drm_fbconv_modeset_init() initializes fbconv modesetting
+ * helpers with these device constants.
+ *
+ * The drm_fbconv_modeset_setup_pipe() creates the simple display pipe with
+ * the specified color formats. By default, everything is set up
+ * automatically. But the function also accepts format modifiers, a DRM
+ * connector, and call-back functions for struct drm_simple_display_pipe.
+ * So each of these can be refactored individually later on.
+ *
+ * After setting up the fbconv helpers, there's is a call to
+ * drm_fbdev_generic_setup(), which set an initial mode and creates a
+ * framebuffer console.
+ *
+ * The implementation of vesadrm_device_cleanup() is the inverse of the
+ * init function. It cleans up the fbconv modesetting helper and releases
+ * the DRM device.
+ *
+ * What is left is connecting vesafb to vesadrm. As a first step, we need a
+ * copy the vesafb source files into the vesadrm driver and make them compile.
+ * Once this is done, we have to replace the call to register_framebuffer()
+ * with a call to vesadrm_register_framebuffer(), and unregister_framebuffer()
+ * with vesadrm_unregister_framebuffer(). We have now disconnected vesafb from
+ * the fbdev core and run it as part of DRM.
+ */
+
/*
* Format conversion helpers
*/
--
2.23.0
next prev parent reply other threads:[~2019-10-14 14:04 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-14 14:04 [PATCH v2 00/15] DRM fbconv helpers for converting fbdev drivers Thomas Zimmermann
2019-10-14 14:04 ` [PATCH v2 01/15] fbdev: Export fb_check_foreignness() Thomas Zimmermann
2019-10-14 14:04 ` [PATCH v2 02/15] fbdev: Export FBPIXMAPSIZE Thomas Zimmermann
2019-10-14 14:04 ` [PATCH v2 03/15] drm/simple-kms-helper: Add mode_fixup() to simple display pipe Thomas Zimmermann
2019-10-14 14:04 ` [PATCH v2 04/15] drm: Add fbconv helper module Thomas Zimmermann
2019-10-14 14:04 ` [PATCH v2 05/15] drm/fbconv: Add DRM <-> fbdev pixel-format conversion Thomas Zimmermann
2019-10-14 20:30 ` Sam Ravnborg
2019-10-15 5:48 ` Thomas Zimmermann
2019-10-14 14:04 ` [PATCH v2 06/15] drm/fbconv: Add mode conversion DRM <-> fbdev Thomas Zimmermann
2019-10-14 14:04 ` [PATCH v2 07/15] drm/fbconv: Add modesetting infrastructure Thomas Zimmermann
2019-10-14 14:04 ` [PATCH v2 08/15] drm/fbconv: Add plane-state check and update Thomas Zimmermann
2019-10-15 8:30 ` kbuild test robot
2019-10-15 17:28 ` kbuild test robot
2019-10-14 14:04 ` [PATCH v2 09/15] drm/fbconv: Mode-setting pipeline enable / disable Thomas Zimmermann
2022-05-28 20:17 ` Geert Uytterhoeven
2022-05-30 7:47 ` Thomas Zimmermann
2022-05-30 8:34 ` Geert Uytterhoeven
2022-07-01 20:01 ` Geert Uytterhoeven
2019-10-14 14:04 ` [PATCH v2 10/15] drm/fbconv: Reimplement several fbdev interfaces Thomas Zimmermann
2019-10-14 14:04 ` [PATCH v2 11/15] drm/fbconv: Add helpers for init and cleanup of fb_info structures Thomas Zimmermann
2019-10-14 14:04 ` Thomas Zimmermann [this message]
2019-10-15 8:40 ` [PATCH v2 12/15] drm/fbconv: Add helper documentation kbuild test robot
2019-10-14 14:04 ` [PATCH v2 13/15] staging: Add mgakms driver Thomas Zimmermann
2019-10-14 14:04 ` [PATCH v2 15/15] staging/mgakms: Update matroxfb driver code for DRM Thomas Zimmermann
2019-10-17 16:19 ` kbuild test robot
2019-10-14 20:36 ` [PATCH v2 00/15] DRM fbconv helpers for converting fbdev drivers Sam Ravnborg
2019-10-15 6:11 ` Thomas Zimmermann
[not found] ` <20191014140416.28517-15-tzimmermann@suse.de>
2019-10-15 11:48 ` [PATCH v2 14/15] staging/mgakms: Import matroxfb driver source code Ville Syrjälä
2019-10-15 12:46 ` Thomas Zimmermann
2019-10-15 14:33 ` [PATCH v2 00/15] DRM fbconv helpers for converting fbdev drivers Daniel Vetter
2019-10-15 17:28 ` Thomas Zimmermann
2019-10-15 17:48 ` Daniel Vetter
2019-10-15 18:05 ` Greg KH
2019-10-15 18:13 ` Ville Syrjälä
2019-10-15 18:28 ` Ville Syrjälä
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=20191014140416.28517-13-tzimmermann@suse.de \
--to=tzimmermann@suse.de \
--cc=airlied@linux.ie \
--cc=ajax@redhat.com \
--cc=b.zolnierkie@samsung.com \
--cc=corbet@lwn.net \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=gregkh@linuxfoundation.org \
--cc=linux-fbdev@vger.kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=malat@debian.org \
--cc=michel@daenzer.net \
--cc=mripard@kernel.org \
--cc=sean@poorly.run \
--cc=ville.syrjala@linux.intel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).