summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_aperture.c
diff options
context:
space:
mode:
authorThomas Zimmermann <tzimmermann@suse.de>2021-04-12 16:10:41 +0300
committerThomas Zimmermann <tzimmermann@suse.de>2021-04-14 10:00:04 +0300
commit2916059147ea38f76787d7b38dee883da2e9def2 (patch)
treeef39697149594663b0bd00e61b8b9732b4817956 /drivers/gpu/drm/drm_aperture.c
parentd510c88cfbb294d2b1e2d0b71576e9b79d0e2e83 (diff)
downloadlinux-2916059147ea38f76787d7b38dee883da2e9def2.tar.xz
drm/aperture: Add infrastructure for aperture ownership
Platform devices might operate on firmware framebuffers, such as VESA or EFI. Before a native driver for the graphics hardware can take over the device, it has to remove any platform driver that operates on the firmware framebuffer. Aperture helpers provide the infrastructure for native drivers to remove the generic ones. For now, this only concerns generic fbdev drivers. Code for removing these is provided by drm_fb_helper_remove_conflicting_framebuffers() et al. Simply wrap these functions for now. At a later point, code can be added for generic DRM drivers to acquire firmware framebuffers. v2: * fix docs for drm_aperture_remove_framebuffers() Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Acked-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20210412131043.5787-2-tzimmermann@suse.de
Diffstat (limited to 'drivers/gpu/drm/drm_aperture.c')
-rw-r--r--drivers/gpu/drm/drm_aperture.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_aperture.c b/drivers/gpu/drm/drm_aperture.c
new file mode 100644
index 000000000000..929dcbc0758a
--- /dev/null
+++ b/drivers/gpu/drm/drm_aperture.c
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: MIT
+
+#include <drm/drm_aperture.h>
+#include <drm/drm_fb_helper.h>
+
+/**
+ * DOC: overview
+ *
+ * A graphics device might be supported by different drivers, but only one
+ * driver can be active at any given time. Many systems load a generic
+ * graphics drivers, such as EFI-GOP or VESA, early during the boot process.
+ * During later boot stages, they replace the generic driver with a dedicated,
+ * hardware-specific driver. To take over the device the dedicated driver
+ * first has to remove the generic driver. DRM aperture functions manage
+ * ownership of DRM framebuffer memory and hand-over between drivers.
+ *
+ * DRM drivers should call drm_aperture_remove_conflicting_framebuffers()
+ * at the top of their probe function. The function removes any generic
+ * driver that is currently associated with the given framebuffer memory.
+ * If the framebuffer is located at PCI BAR 0, the rsp code looks as in the
+ * example given below.
+ *
+ * .. code-block:: c
+ *
+ * static int remove_conflicting_framebuffers(struct pci_dev *pdev)
+ * {
+ * bool primary = false;
+ * resource_size_t base, size;
+ * int ret;
+ *
+ * base = pci_resource_start(pdev, 0);
+ * size = pci_resource_len(pdev, 0);
+ * #ifdef CONFIG_X86
+ * primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
+ * #endif
+ *
+ * return drm_aperture_remove_conflicting_framebuffers(base, size, primary,
+ * "example driver");
+ * }
+ *
+ * static int probe(struct pci_dev *pdev)
+ * {
+ * int ret;
+ *
+ * // Remove any generic drivers...
+ * ret = remove_conflicting_framebuffers(pdev);
+ * if (ret)
+ * return ret;
+ *
+ * // ... and initialize the hardware.
+ * ...
+ *
+ * drm_dev_register();
+ *
+ * return 0;
+ * }
+ *
+ * PCI device drivers should call
+ * drm_aperture_remove_conflicting_pci_framebuffers() and let it detect the
+ * framebuffer apertures automatically. Device drivers without knowledge of
+ * the framebuffer's location shall call drm_aperture_remove_framebuffers(),
+ * which removes all drivers for known framebuffer.
+ */
+
+/**
+ * drm_aperture_remove_conflicting_framebuffers - remove existing framebuffers in the given range
+ * @base: the aperture's base address in physical memory
+ * @size: aperture size in bytes
+ * @primary: also kick vga16fb if present
+ * @name: requesting driver name
+ *
+ * This function removes graphics device drivers which use memory range described by
+ * @base and @size.
+ *
+ * Returns:
+ * 0 on success, or a negative errno code otherwise
+ */
+int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size,
+ bool primary, const char *name)
+{
+ struct apertures_struct *a;
+ int ret;
+
+ a = alloc_apertures(1);
+ if (!a)
+ return -ENOMEM;
+
+ a->ranges[0].base = base;
+ a->ranges[0].size = size;
+
+ ret = drm_fb_helper_remove_conflicting_framebuffers(a, name, primary);
+ kfree(a);
+
+ return ret;
+}
+EXPORT_SYMBOL(drm_aperture_remove_conflicting_framebuffers);
+
+/**
+ * drm_aperture_remove_conflicting_pci_framebuffers - remove existing framebuffers for PCI devices
+ * @pdev: PCI device
+ * @name: requesting driver name
+ *
+ * This function removes graphics device drivers using memory range configured
+ * for any of @pdev's memory bars. The function assumes that PCI device with
+ * shadowed ROM drives a primary display and so kicks out vga16fb.
+ *
+ * Returns:
+ * 0 on success, or a negative errno code otherwise
+ */
+int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev, const char *name)
+{
+ return drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, name);
+}
+EXPORT_SYMBOL(drm_aperture_remove_conflicting_pci_framebuffers);