| ============= | |
| DRM Internals | |
| ============= | |
| This chapter documents DRM internals relevant to driver authors and | |
| developers working to add support for the latest features to existing | |
| drivers. | |
| First, we go over some typical driver initialization requirements, like | |
| setting up command buffers, creating an initial output configuration, | |
| and initializing core services. Subsequent sections cover core internals | |
| in more detail, providing implementation notes and examples. | |
| The DRM layer provides several services to graphics drivers, many of | |
| them driven by the application interfaces it provides through libdrm, | |
| the library that wraps most of the DRM ioctls. These include vblank | |
| event handling, memory management, output management, framebuffer | |
| management, command submission & fencing, suspend/resume support, and | |
| DMA services. | |
| .. contents:: | |
| Driver Initialization | |
| ===================== | |
| At the core of every DRM driver is a :c:type:`struct drm_driver | |
| <drm_driver>` structure. Drivers typically statically initialize | |
| a drm_driver structure, and then pass it to | |
| drm_dev_alloc() to allocate a device instance. After the | |
| device instance is fully initialized it can be registered (which makes | |
| it accessible from userspace) using drm_dev_register(). | |
| The :c:type:`struct drm_driver <drm_driver>` structure | |
| contains static information that describes the driver and features it | |
| supports, and pointers to methods that the DRM core will call to | |
| implement the DRM API. We will first go through the :c:type:`struct | |
| drm_driver <drm_driver>` static information fields, and will | |
| then describe individual operations in details as they get used in later | |
| sections. | |
| Driver Information | |
| ------------------ | |
| Major, Minor and Patchlevel | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| int major; int minor; int patchlevel; | |
| The DRM core identifies driver versions by a major, minor and patch | |
| level triplet. The information is printed to the kernel log at | |
| initialization time and passed to userspace through the | |
| DRM_IOCTL_VERSION ioctl. | |
| The major and minor numbers are also used to verify the requested driver | |
| API version passed to DRM_IOCTL_SET_VERSION. When the driver API | |
| changes between minor versions, applications can call | |
| DRM_IOCTL_SET_VERSION to select a specific version of the API. If the | |
| requested major isn't equal to the driver major, or the requested minor | |
| is larger than the driver minor, the DRM_IOCTL_SET_VERSION call will | |
| return an error. Otherwise the driver's set_version() method will be | |
| called with the requested version. | |
| Name and Description | |
| ~~~~~~~~~~~~~~~~~~~~ | |
| char \*name; char \*desc; char \*date; | |
| The driver name is printed to the kernel log at initialization time, | |
| used for IRQ registration and passed to userspace through | |
| DRM_IOCTL_VERSION. | |
| The driver description is a purely informative string passed to | |
| userspace through the DRM_IOCTL_VERSION ioctl and otherwise unused by | |
| the kernel. | |
| Module Initialization | |
| --------------------- | |
| .. kernel-doc:: include/drm/drm_module.h | |
| :doc: overview | |
| Device Instance and Driver Handling | |
| ----------------------------------- | |
| .. kernel-doc:: drivers/gpu/drm/drm_drv.c | |
| :doc: driver instance overview | |
| .. kernel-doc:: include/drm/drm_device.h | |
| :internal: | |
| .. kernel-doc:: include/drm/drm_drv.h | |
| :internal: | |
| .. kernel-doc:: drivers/gpu/drm/drm_drv.c | |
| :export: | |
| Driver Load | |
| ----------- | |
| Component Helper Usage | |
| ~~~~~~~~~~~~~~~~~~~~~~ | |
| .. kernel-doc:: drivers/gpu/drm/drm_drv.c | |
| :doc: component helper usage recommendations | |
| Memory Manager Initialization | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| Every DRM driver requires a memory manager which must be initialized at | |
| load time. DRM currently contains two memory managers, the Translation | |
| Table Manager (TTM) and the Graphics Execution Manager (GEM). This | |
| document describes the use of the GEM memory manager only. See ? for | |
| details. | |
| Miscellaneous Device Configuration | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| Another task that may be necessary for PCI devices during configuration | |
| is mapping the video BIOS. On many devices, the VBIOS describes device | |
| configuration, LCD panel timings (if any), and contains flags indicating | |
| device state. Mapping the BIOS can be done using the pci_map_rom() | |
| call, a convenience function that takes care of mapping the actual ROM, | |
| whether it has been shadowed into memory (typically at address 0xc0000) | |
| or exists on the PCI device in the ROM BAR. Note that after the ROM has | |
| been mapped and any necessary information has been extracted, it should | |
| be unmapped; on many devices, the ROM address decoder is shared with | |
| other BARs, so leaving it mapped could cause undesired behaviour like | |
| hangs or memory corruption. | |
| Managed Resources | |
| ----------------- | |
| .. kernel-doc:: drivers/gpu/drm/drm_managed.c | |
| :doc: managed resources | |
| .. kernel-doc:: drivers/gpu/drm/drm_managed.c | |
| :export: | |
| .. kernel-doc:: include/drm/drm_managed.h | |
| :internal: | |
| Open/Close, File Operations and IOCTLs | |
| ====================================== | |
| .. _drm_driver_fops: | |
| File Operations | |
| --------------- | |
| .. kernel-doc:: drivers/gpu/drm/drm_file.c | |
| :doc: file operations | |
| .. kernel-doc:: include/drm/drm_file.h | |
| :internal: | |
| .. kernel-doc:: drivers/gpu/drm/drm_file.c | |
| :export: | |
| Misc Utilities | |
| ============== | |
| Printer | |
| ------- | |
| .. kernel-doc:: include/drm/drm_print.h | |
| :doc: print | |
| .. kernel-doc:: include/drm/drm_print.h | |
| :internal: | |
| .. kernel-doc:: drivers/gpu/drm/drm_print.c | |
| :export: | |
| Utilities | |
| --------- | |
| .. kernel-doc:: include/drm/drm_util.h | |
| :doc: drm utils | |
| .. kernel-doc:: include/drm/drm_util.h | |
| :internal: | |
| Unit testing | |
| ============ | |
| KUnit | |
| ----- | |
| KUnit (Kernel unit testing framework) provides a common framework for unit tests | |
| within the Linux kernel. | |
| This section covers the specifics for the DRM subsystem. For general information | |
| about KUnit, please refer to Documentation/dev-tools/kunit/start.rst. | |
| How to run the tests? | |
| ~~~~~~~~~~~~~~~~~~~~~ | |
| In order to facilitate running the test suite, a configuration file is present | |
| in ``drivers/gpu/drm/tests/.kunitconfig``. It can be used by ``kunit.py`` as | |
| follows: | |
| .. code-block:: bash | |
| $ ./tools/testing/kunit/kunit.py run --kunitconfig=drivers/gpu/drm/tests \ | |
| --kconfig_add CONFIG_VIRTIO_UML=y \ | |
| --kconfig_add CONFIG_UML_PCI_OVER_VIRTIO=y | |
| .. note:: | |
| The configuration included in ``.kunitconfig`` should be as generic as | |
| possible. | |
| ``CONFIG_VIRTIO_UML`` and ``CONFIG_UML_PCI_OVER_VIRTIO`` are not | |
| included in it because they are only required for User Mode Linux. | |
| KUnit Coverage Rules | |
| ~~~~~~~~~~~~~~~~~~~~ | |
| KUnit support is gradually added to the DRM framework and helpers. There's no | |
| general requirement for the framework and helpers to have KUnit tests at the | |
| moment. However, patches that are affecting a function or helper already | |
| covered by KUnit tests must provide tests if the change calls for one. | |
| Legacy Support Code | |
| =================== | |
| The section very briefly covers some of the old legacy support code | |
| which is only used by old DRM drivers which have done a so-called | |
| shadow-attach to the underlying device instead of registering as a real | |
| driver. This also includes some of the old generic buffer management and | |
| command submission code. Do not use any of this in new and modern | |
| drivers. | |
| Legacy Suspend/Resume | |
| --------------------- | |
| The DRM core provides some suspend/resume code, but drivers wanting full | |
| suspend/resume support should provide save() and restore() functions. | |
| These are called at suspend, hibernate, or resume time, and should | |
| perform any state save or restore required by your device across suspend | |
| or hibernate states. | |
| int (\*suspend) (struct drm_device \*, pm_message_t state); int | |
| (\*resume) (struct drm_device \*); | |
| Those are legacy suspend and resume methods which *only* work with the | |
| legacy shadow-attach driver registration functions. New driver should | |
| use the power management interface provided by their bus type (usually | |
| through the :c:type:`struct device_driver <device_driver>` | |
| dev_pm_ops) and set these methods to NULL. | |
| Legacy DMA Services | |
| ------------------- | |
| This should cover how DMA mapping etc. is supported by the core. These | |
| functions are deprecated and should not be used. |