Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+158 -1
+12
Documentation/gpu/drm-internals.rst
··· 75 75 kernel log at initialization time and passes it to userspace through the 76 76 DRM_IOCTL_VERSION ioctl. 77 77 78 + Managing Ownership of the Framebuffer Aperture 79 + ---------------------------------------------- 80 + 81 + .. kernel-doc:: drivers/gpu/drm/drm_aperture.c 82 + :doc: overview 83 + 84 + .. kernel-doc:: include/drm/drm_aperture.h 85 + :internal: 86 + 87 + .. kernel-doc:: drivers/gpu/drm/drm_aperture.c 88 + :export: 89 + 78 90 Device Instance and Driver Handling 79 91 ----------------------------------- 80 92
+1 -1
drivers/gpu/drm/Makefile
··· 3 3 # Makefile for the drm device driver. This driver provides support for the 4 4 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. 5 5 6 - drm-y := drm_auth.o drm_cache.o \ 6 + drm-y := drm_aperture.o drm_auth.o drm_cache.o \ 7 7 drm_file.o drm_gem.o drm_ioctl.o drm_irq.o \ 8 8 drm_drv.o \ 9 9 drm_sysfs.o drm_hashtab.o drm_mm.o \
+114
drivers/gpu/drm/drm_aperture.c
··· 1 + // SPDX-License-Identifier: MIT 2 + 3 + #include <drm/drm_aperture.h> 4 + #include <drm/drm_fb_helper.h> 5 + 6 + /** 7 + * DOC: overview 8 + * 9 + * A graphics device might be supported by different drivers, but only one 10 + * driver can be active at any given time. Many systems load a generic 11 + * graphics drivers, such as EFI-GOP or VESA, early during the boot process. 12 + * During later boot stages, they replace the generic driver with a dedicated, 13 + * hardware-specific driver. To take over the device the dedicated driver 14 + * first has to remove the generic driver. DRM aperture functions manage 15 + * ownership of DRM framebuffer memory and hand-over between drivers. 16 + * 17 + * DRM drivers should call drm_aperture_remove_conflicting_framebuffers() 18 + * at the top of their probe function. The function removes any generic 19 + * driver that is currently associated with the given framebuffer memory. 20 + * If the framebuffer is located at PCI BAR 0, the rsp code looks as in the 21 + * example given below. 22 + * 23 + * .. code-block:: c 24 + * 25 + * static int remove_conflicting_framebuffers(struct pci_dev *pdev) 26 + * { 27 + * bool primary = false; 28 + * resource_size_t base, size; 29 + * int ret; 30 + * 31 + * base = pci_resource_start(pdev, 0); 32 + * size = pci_resource_len(pdev, 0); 33 + * #ifdef CONFIG_X86 34 + * primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; 35 + * #endif 36 + * 37 + * return drm_aperture_remove_conflicting_framebuffers(base, size, primary, 38 + * "example driver"); 39 + * } 40 + * 41 + * static int probe(struct pci_dev *pdev) 42 + * { 43 + * int ret; 44 + * 45 + * // Remove any generic drivers... 46 + * ret = remove_conflicting_framebuffers(pdev); 47 + * if (ret) 48 + * return ret; 49 + * 50 + * // ... and initialize the hardware. 51 + * ... 52 + * 53 + * drm_dev_register(); 54 + * 55 + * return 0; 56 + * } 57 + * 58 + * PCI device drivers should call 59 + * drm_aperture_remove_conflicting_pci_framebuffers() and let it detect the 60 + * framebuffer apertures automatically. Device drivers without knowledge of 61 + * the framebuffer's location shall call drm_aperture_remove_framebuffers(), 62 + * which removes all drivers for known framebuffer. 63 + */ 64 + 65 + /** 66 + * drm_aperture_remove_conflicting_framebuffers - remove existing framebuffers in the given range 67 + * @base: the aperture's base address in physical memory 68 + * @size: aperture size in bytes 69 + * @primary: also kick vga16fb if present 70 + * @name: requesting driver name 71 + * 72 + * This function removes graphics device drivers which use memory range described by 73 + * @base and @size. 74 + * 75 + * Returns: 76 + * 0 on success, or a negative errno code otherwise 77 + */ 78 + int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size, 79 + bool primary, const char *name) 80 + { 81 + struct apertures_struct *a; 82 + int ret; 83 + 84 + a = alloc_apertures(1); 85 + if (!a) 86 + return -ENOMEM; 87 + 88 + a->ranges[0].base = base; 89 + a->ranges[0].size = size; 90 + 91 + ret = drm_fb_helper_remove_conflicting_framebuffers(a, name, primary); 92 + kfree(a); 93 + 94 + return ret; 95 + } 96 + EXPORT_SYMBOL(drm_aperture_remove_conflicting_framebuffers); 97 + 98 + /** 99 + * drm_aperture_remove_conflicting_pci_framebuffers - remove existing framebuffers for PCI devices 100 + * @pdev: PCI device 101 + * @name: requesting driver name 102 + * 103 + * This function removes graphics device drivers using memory range configured 104 + * for any of @pdev's memory bars. The function assumes that PCI device with 105 + * shadowed ROM drives a primary display and so kicks out vga16fb. 106 + * 107 + * Returns: 108 + * 0 on success, or a negative errno code otherwise 109 + */ 110 + int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev, const char *name) 111 + { 112 + return drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, name); 113 + } 114 + EXPORT_SYMBOL(drm_aperture_remove_conflicting_pci_framebuffers);
+31
include/drm/drm_aperture.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + 3 + #ifndef _DRM_APERTURE_H_ 4 + #define _DRM_APERTURE_H_ 5 + 6 + #include <linux/types.h> 7 + 8 + struct pci_dev; 9 + 10 + int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size, 11 + bool primary, const char *name); 12 + 13 + int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev, const char *name); 14 + 15 + /** 16 + * drm_aperture_remove_framebuffers - remove all existing framebuffers 17 + * @primary: also kick vga16fb if present 18 + * @name: requesting driver name 19 + * 20 + * This function removes all graphics device drivers. Use this function on systems 21 + * that can have their framebuffer located anywhere in memory. 22 + * 23 + * Returns: 24 + * 0 on success, or a negative errno code otherwise 25 + */ 26 + static inline int drm_aperture_remove_framebuffers(bool primary, const char *name) 27 + { 28 + return drm_aperture_remove_conflicting_framebuffers(0, (resource_size_t)-1, primary, name); 29 + } 30 + 31 + #endif