From: Thomas Zimmermann <tzimmermann@suse.de>
To: javierm@redhat.com, daniel@ffwll.ch,
maarten.lankhorst@linux.intel.com, mripard@kernel.org,
inki.dae@samsung.com, sw0312.kim@samsung.com,
kyungmin.park@samsung.com, linux@armlinux.org.uk,
krzk@kernel.org, alim.akhtar@samsung.com,
patrik.r.jakobsson@gmail.com, jani.nikula@linux.intel.com,
rodrigo.vivi@intel.com, joonas.lahtinen@linux.intel.com,
tursulin@ursulin.net, robdclark@gmail.com,
quic_abhinavk@quicinc.com, dmitry.baryshkov@linaro.org,
sean@poorly.run, marijn.suijten@somainline.org,
tomi.valkeinen@ideasonboard.com, alexander.deucher@amd.com,
christian.koenig@amd.com, Xinhui.Pan@amd.com,
thierry.reding@gmail.com, mperttunen@nvidia.com,
jonathanh@nvidia.com
Cc: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org,
amd-gfx@lists.freedesktop.org,
Thomas Zimmermann <tzimmermann@suse.de>
Subject: [PATCH 01/11] drm/fb-helper: Add helpers for struct drm_client_funcs
Date: Tue, 7 May 2024 13:58:22 +0200 [thread overview]
Message-ID: <20240507120422.25492-2-tzimmermann@suse.de> (raw)
In-Reply-To: <20240507120422.25492-1-tzimmermann@suse.de>
Add default implementations for unregister, restore and hotplug of
struct drm_client_funcs. The provided helpers are compatible with the
requirements of most DRM drivers.
The helpers handle support for VGA switcheroo automatically. With
DRM drivers that don't implement VGA switcheroo, this does nothing.
The helpers also support DRM drivers with non-atomic mode setting,
which require additional steps to disable their modesetting pipeline.
Compared to its current implementations in various drivers, there
is one difference in drm_fbdev_helper_client_hotplug(). The custom
functions perform hotpluging if struct drm_device.fb_helper has been
set, while the custom helper tests for struct drm_fb_helper.info.
Both fields signal the presence of an active fbdev emulation, but
the former field is deprecated.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/gpu/drm/drm_fb_helper.c | 103 ++++++++++++++++++++++++++++++++
include/drm/drm_fb_helper.h | 19 ++++++
2 files changed, 122 insertions(+)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index e2e19f49342e1..005debf61a571 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -35,6 +35,7 @@
#include <linux/vga_switcheroo.h>
#include <drm/drm_atomic.h>
+#include <drm/drm_crtc_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fourcc.h>
@@ -2013,3 +2014,105 @@ void drm_fb_helper_output_poll_changed(struct drm_device *dev)
drm_fb_helper_hotplug_event(dev->fb_helper);
}
EXPORT_SYMBOL(drm_fb_helper_output_poll_changed);
+
+/*
+ * struct drm_client_funcs
+ */
+
+/**
+ * drm_fbdev_helper_client_unregister - Unregister callback for fbdev emulation
+ * @client: The fbdev client
+ *
+ * Implements struct drm_client_funcs.unregister for fbdev emulation. The
+ * helper destroys the framebuffer device and releases all resources. It
+ * further disables all outputs and clears the VGA switcheroo framebuffer
+ * info for PCI devices.
+ */
+void drm_fbdev_helper_client_unregister(struct drm_client_dev *client)
+{
+ struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
+ struct drm_device *dev = fb_helper->dev;
+
+ if (fb_helper->info) {
+ if (dev_is_pci(dev->dev))
+ vga_switcheroo_client_fb_set(to_pci_dev(dev->dev), NULL);
+ drm_fb_helper_unregister_info(fb_helper);
+ if (!drm_drv_uses_atomic_modeset(dev))
+ drm_helper_force_disable_all(dev);
+ } else {
+ drm_client_release(client);
+ drm_fb_helper_unprepare(fb_helper);
+ kfree(fb_helper);
+ }
+}
+EXPORT_SYMBOL(drm_fbdev_helper_client_unregister);
+
+/**
+ * drm_fbdev_helper_client_restore - Restore callback for fbdev emulation
+ * @client: The fbdev client
+ *
+ * Implements struct drm_client_funcs.restore for fbdev emulation. The
+ * helper restores the console output after the fbdev emulation's current
+ * configuration. It also informs VGA switcheroo about the change.
+ *
+ * Returns:
+ * 0 on success, or a negative errno code otherwise.
+ */
+int drm_fbdev_helper_client_restore(struct drm_client_dev *client)
+{
+ struct drm_device *dev = client->dev;
+
+ drm_fb_helper_lastclose(dev);
+
+ if (dev_is_pci(dev->dev))
+ vga_switcheroo_process_delayed_switch();
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_fbdev_helper_client_restore);
+
+/**
+ * drm_fbdev_helper_client_hotplug - Hotplug callback for fbdev emulation
+ * @client: The fbdev client
+ *
+ * Implements struct drm_client_funcs.hotplug for fbdev emulation. The
+ * helper handles the hotplugging event by restoring the display output.
+ * If no output has been established yet, it instead performs an initial
+ * display configuration. On successful configuration, it installs the
+ * framebuffer info VGA switcheroo for PCI devices.
+ *
+ * Returns:
+ * 0 on success, or a negative errno code otherwise.
+ */
+int drm_fbdev_helper_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 (fb_helper->info)
+ return drm_fb_helper_hotplug_event(fb_helper);
+
+ ret = drm_fb_helper_init(dev, fb_helper);
+ if (ret)
+ goto err_drm_err;
+
+ if (!drm_drv_uses_atomic_modeset(dev))
+ drm_helper_disable_unused_functions(dev);
+
+ ret = drm_fb_helper_initial_config(fb_helper);
+ if (ret)
+ goto err_drm_fb_helper_fini;
+
+ if (dev_is_pci(dev->dev))
+ vga_switcheroo_client_fb_set(to_pci_dev(dev->dev), fb_helper->info);
+
+ return 0;
+
+err_drm_fb_helper_fini:
+ drm_fb_helper_fini(fb_helper);
+err_drm_err:
+ drm_err(dev, "Failed to setup fbdev emulation (ret=%d)\n", ret);
+ return ret;
+}
+EXPORT_SYMBOL(drm_fbdev_helper_client_hotplug);
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 375737fd6c36e..c3e8156e5f963 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -407,4 +407,23 @@ static inline void drm_fb_helper_output_poll_changed(struct drm_device *dev)
}
#endif
+/*
+ * struct drm_client_funcs
+ */
+
+void drm_fbdev_helper_client_unregister(struct drm_client_dev *client);
+int drm_fbdev_helper_client_restore(struct drm_client_dev *client);
+int drm_fbdev_helper_client_hotplug(struct drm_client_dev *client);
+
+/**
+ * DRM_FBDEV_HELPER_CLIENT_FUNCS - Initializer macro for struct drm_client_funcs
+ *
+ * Initializes an instance of struct drm_client_funcs to default values
+ * for framebuffer emulation.
+ */
+#define DRM_FBDEV_HELPER_CLIENT_FUNCS \
+ .unregister = drm_fbdev_helper_client_unregister, \
+ .restore = drm_fbdev_helper_client_restore, \
+ .hotplug = drm_fbdev_helper_client_hotplug
+
#endif
--
2.44.0
next prev parent reply other threads:[~2024-05-07 12:04 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-07 11:58 [PATCH 00/11] drm: Provide common fbdev client helpers Thomas Zimmermann
2024-05-07 11:58 ` Thomas Zimmermann [this message]
2024-05-07 11:58 ` [PATCH 02/11] drm/fbdev-dma: Use " Thomas Zimmermann
2024-05-07 11:58 ` [PATCH 03/11] drm/fbdev-shmem: " Thomas Zimmermann
2024-05-07 11:58 ` [PATCH 04/11] drm/fbdev-ttm: " Thomas Zimmermann
2024-05-07 11:58 ` [PATCH 05/11] drm/armada: " Thomas Zimmermann
2024-05-07 11:58 ` [PATCH 06/11] drm/exynos: " Thomas Zimmermann
2024-05-07 11:58 ` [PATCH 07/11] drm/gma500: " Thomas Zimmermann
2024-05-08 12:53 ` Patrik Jakobsson
2024-05-07 11:58 ` [PATCH 08/11] drm/i915: Use drm_fbdev_helper_client_unregister() Thomas Zimmermann
2024-05-07 12:25 ` Rodrigo Vivi
2024-05-07 13:10 ` Thomas Zimmermann
2024-05-07 11:58 ` [PATCH 09/11] drm/msm: Use fbdev client helpers Thomas Zimmermann
2024-05-07 14:36 ` Dmitry Baryshkov
2024-05-07 11:58 ` [PATCH 10/11] drm/omapdrm: " Thomas Zimmermann
2024-05-07 11:58 ` [PATCH 11/11] drm/tegra: " Thomas Zimmermann
2024-05-07 21:03 ` Felix Kuehling
2024-05-08 6:00 ` 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=20240507120422.25492-2-tzimmermann@suse.de \
--to=tzimmermann@suse.de \
--cc=Xinhui.Pan@amd.com \
--cc=alexander.deucher@amd.com \
--cc=alim.akhtar@samsung.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=christian.koenig@amd.com \
--cc=daniel@ffwll.ch \
--cc=dmitry.baryshkov@linaro.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=inki.dae@samsung.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=jani.nikula@linux.intel.com \
--cc=javierm@redhat.com \
--cc=jonathanh@nvidia.com \
--cc=joonas.lahtinen@linux.intel.com \
--cc=krzk@kernel.org \
--cc=kyungmin.park@samsung.com \
--cc=linux@armlinux.org.uk \
--cc=maarten.lankhorst@linux.intel.com \
--cc=marijn.suijten@somainline.org \
--cc=mperttunen@nvidia.com \
--cc=mripard@kernel.org \
--cc=patrik.r.jakobsson@gmail.com \
--cc=quic_abhinavk@quicinc.com \
--cc=robdclark@gmail.com \
--cc=rodrigo.vivi@intel.com \
--cc=sean@poorly.run \
--cc=sw0312.kim@samsung.com \
--cc=thierry.reding@gmail.com \
--cc=tomi.valkeinen@ideasonboard.com \
--cc=tursulin@ursulin.net \
/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