162306a36Sopenharmony_ci============= 262306a36Sopenharmony_ciDRM Internals 362306a36Sopenharmony_ci============= 462306a36Sopenharmony_ci 562306a36Sopenharmony_ciThis chapter documents DRM internals relevant to driver authors and 662306a36Sopenharmony_cidevelopers working to add support for the latest features to existing 762306a36Sopenharmony_cidrivers. 862306a36Sopenharmony_ci 962306a36Sopenharmony_ciFirst, we go over some typical driver initialization requirements, like 1062306a36Sopenharmony_cisetting up command buffers, creating an initial output configuration, 1162306a36Sopenharmony_ciand initializing core services. Subsequent sections cover core internals 1262306a36Sopenharmony_ciin more detail, providing implementation notes and examples. 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ciThe DRM layer provides several services to graphics drivers, many of 1562306a36Sopenharmony_cithem driven by the application interfaces it provides through libdrm, 1662306a36Sopenharmony_cithe library that wraps most of the DRM ioctls. These include vblank 1762306a36Sopenharmony_cievent handling, memory management, output management, framebuffer 1862306a36Sopenharmony_cimanagement, command submission & fencing, suspend/resume support, and 1962306a36Sopenharmony_ciDMA services. 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ciDriver Initialization 2262306a36Sopenharmony_ci===================== 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ciAt the core of every DRM driver is a :c:type:`struct drm_driver 2562306a36Sopenharmony_ci<drm_driver>` structure. Drivers typically statically initialize 2662306a36Sopenharmony_cia drm_driver structure, and then pass it to 2762306a36Sopenharmony_cidrm_dev_alloc() to allocate a device instance. After the 2862306a36Sopenharmony_cidevice instance is fully initialized it can be registered (which makes 2962306a36Sopenharmony_ciit accessible from userspace) using drm_dev_register(). 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ciThe :c:type:`struct drm_driver <drm_driver>` structure 3262306a36Sopenharmony_cicontains static information that describes the driver and features it 3362306a36Sopenharmony_cisupports, and pointers to methods that the DRM core will call to 3462306a36Sopenharmony_ciimplement the DRM API. We will first go through the :c:type:`struct 3562306a36Sopenharmony_cidrm_driver <drm_driver>` static information fields, and will 3662306a36Sopenharmony_cithen describe individual operations in details as they get used in later 3762306a36Sopenharmony_cisections. 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ciDriver Information 4062306a36Sopenharmony_ci------------------ 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ciMajor, Minor and Patchlevel 4362306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ciint major; int minor; int patchlevel; 4662306a36Sopenharmony_ciThe DRM core identifies driver versions by a major, minor and patch 4762306a36Sopenharmony_cilevel triplet. The information is printed to the kernel log at 4862306a36Sopenharmony_ciinitialization time and passed to userspace through the 4962306a36Sopenharmony_ciDRM_IOCTL_VERSION ioctl. 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ciThe major and minor numbers are also used to verify the requested driver 5262306a36Sopenharmony_ciAPI version passed to DRM_IOCTL_SET_VERSION. When the driver API 5362306a36Sopenharmony_cichanges between minor versions, applications can call 5462306a36Sopenharmony_ciDRM_IOCTL_SET_VERSION to select a specific version of the API. If the 5562306a36Sopenharmony_cirequested major isn't equal to the driver major, or the requested minor 5662306a36Sopenharmony_ciis larger than the driver minor, the DRM_IOCTL_SET_VERSION call will 5762306a36Sopenharmony_cireturn an error. Otherwise the driver's set_version() method will be 5862306a36Sopenharmony_cicalled with the requested version. 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ciName, Description and Date 6162306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~ 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cichar \*name; char \*desc; char \*date; 6462306a36Sopenharmony_ciThe driver name is printed to the kernel log at initialization time, 6562306a36Sopenharmony_ciused for IRQ registration and passed to userspace through 6662306a36Sopenharmony_ciDRM_IOCTL_VERSION. 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ciThe driver description is a purely informative string passed to 6962306a36Sopenharmony_ciuserspace through the DRM_IOCTL_VERSION ioctl and otherwise unused by 7062306a36Sopenharmony_cithe kernel. 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ciThe driver date, formatted as YYYYMMDD, is meant to identify the date of 7362306a36Sopenharmony_cithe latest modification to the driver. However, as most drivers fail to 7462306a36Sopenharmony_ciupdate it, its value is mostly useless. The DRM core prints it to the 7562306a36Sopenharmony_cikernel log at initialization time and passes it to userspace through the 7662306a36Sopenharmony_ciDRM_IOCTL_VERSION ioctl. 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ciModule Initialization 7962306a36Sopenharmony_ci--------------------- 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci.. kernel-doc:: include/drm/drm_module.h 8262306a36Sopenharmony_ci :doc: overview 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ciManaging Ownership of the Framebuffer Aperture 8562306a36Sopenharmony_ci---------------------------------------------- 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci.. kernel-doc:: drivers/gpu/drm/drm_aperture.c 8862306a36Sopenharmony_ci :doc: overview 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci.. kernel-doc:: include/drm/drm_aperture.h 9162306a36Sopenharmony_ci :internal: 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci.. kernel-doc:: drivers/gpu/drm/drm_aperture.c 9462306a36Sopenharmony_ci :export: 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ciDevice Instance and Driver Handling 9762306a36Sopenharmony_ci----------------------------------- 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci.. kernel-doc:: drivers/gpu/drm/drm_drv.c 10062306a36Sopenharmony_ci :doc: driver instance overview 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci.. kernel-doc:: include/drm/drm_device.h 10362306a36Sopenharmony_ci :internal: 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci.. kernel-doc:: include/drm/drm_drv.h 10662306a36Sopenharmony_ci :internal: 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci.. kernel-doc:: drivers/gpu/drm/drm_drv.c 10962306a36Sopenharmony_ci :export: 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ciDriver Load 11262306a36Sopenharmony_ci----------- 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ciComponent Helper Usage 11562306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~ 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci.. kernel-doc:: drivers/gpu/drm/drm_drv.c 11862306a36Sopenharmony_ci :doc: component helper usage recommendations 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ciMemory Manager Initialization 12162306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ciEvery DRM driver requires a memory manager which must be initialized at 12462306a36Sopenharmony_ciload time. DRM currently contains two memory managers, the Translation 12562306a36Sopenharmony_ciTable Manager (TTM) and the Graphics Execution Manager (GEM). This 12662306a36Sopenharmony_cidocument describes the use of the GEM memory manager only. See ? for 12762306a36Sopenharmony_cidetails. 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ciMiscellaneous Device Configuration 13062306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ciAnother task that may be necessary for PCI devices during configuration 13362306a36Sopenharmony_ciis mapping the video BIOS. On many devices, the VBIOS describes device 13462306a36Sopenharmony_ciconfiguration, LCD panel timings (if any), and contains flags indicating 13562306a36Sopenharmony_cidevice state. Mapping the BIOS can be done using the pci_map_rom() 13662306a36Sopenharmony_cicall, a convenience function that takes care of mapping the actual ROM, 13762306a36Sopenharmony_ciwhether it has been shadowed into memory (typically at address 0xc0000) 13862306a36Sopenharmony_cior exists on the PCI device in the ROM BAR. Note that after the ROM has 13962306a36Sopenharmony_cibeen mapped and any necessary information has been extracted, it should 14062306a36Sopenharmony_cibe unmapped; on many devices, the ROM address decoder is shared with 14162306a36Sopenharmony_ciother BARs, so leaving it mapped could cause undesired behaviour like 14262306a36Sopenharmony_cihangs or memory corruption. 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ciManaged Resources 14562306a36Sopenharmony_ci----------------- 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci.. kernel-doc:: drivers/gpu/drm/drm_managed.c 14862306a36Sopenharmony_ci :doc: managed resources 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci.. kernel-doc:: drivers/gpu/drm/drm_managed.c 15162306a36Sopenharmony_ci :export: 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci.. kernel-doc:: include/drm/drm_managed.h 15462306a36Sopenharmony_ci :internal: 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ciBus-specific Device Registration and PCI Support 15762306a36Sopenharmony_ci------------------------------------------------ 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ciA number of functions are provided to help with device registration. The 16062306a36Sopenharmony_cifunctions deal with PCI and platform devices respectively and are only 16162306a36Sopenharmony_ciprovided for historical reasons. These are all deprecated and shouldn't 16262306a36Sopenharmony_cibe used in new drivers. Besides that there's a few helpers for pci 16362306a36Sopenharmony_cidrivers. 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci.. kernel-doc:: drivers/gpu/drm/drm_pci.c 16662306a36Sopenharmony_ci :export: 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ciOpen/Close, File Operations and IOCTLs 16962306a36Sopenharmony_ci====================================== 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci.. _drm_driver_fops: 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ciFile Operations 17462306a36Sopenharmony_ci--------------- 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci.. kernel-doc:: drivers/gpu/drm/drm_file.c 17762306a36Sopenharmony_ci :doc: file operations 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci.. kernel-doc:: include/drm/drm_file.h 18062306a36Sopenharmony_ci :internal: 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci.. kernel-doc:: drivers/gpu/drm/drm_file.c 18362306a36Sopenharmony_ci :export: 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ciMisc Utilities 18662306a36Sopenharmony_ci============== 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ciPrinter 18962306a36Sopenharmony_ci------- 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci.. kernel-doc:: include/drm/drm_print.h 19262306a36Sopenharmony_ci :doc: print 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci.. kernel-doc:: include/drm/drm_print.h 19562306a36Sopenharmony_ci :internal: 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci.. kernel-doc:: drivers/gpu/drm/drm_print.c 19862306a36Sopenharmony_ci :export: 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ciUtilities 20162306a36Sopenharmony_ci--------- 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci.. kernel-doc:: include/drm/drm_util.h 20462306a36Sopenharmony_ci :doc: drm utils 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci.. kernel-doc:: include/drm/drm_util.h 20762306a36Sopenharmony_ci :internal: 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ciUnit testing 21162306a36Sopenharmony_ci============ 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ciKUnit 21462306a36Sopenharmony_ci----- 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ciKUnit (Kernel unit testing framework) provides a common framework for unit tests 21762306a36Sopenharmony_ciwithin the Linux kernel. 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ciThis section covers the specifics for the DRM subsystem. For general information 22062306a36Sopenharmony_ciabout KUnit, please refer to Documentation/dev-tools/kunit/start.rst. 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ciHow to run the tests? 22362306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~ 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ciIn order to facilitate running the test suite, a configuration file is present 22662306a36Sopenharmony_ciin ``drivers/gpu/drm/tests/.kunitconfig``. It can be used by ``kunit.py`` as 22762306a36Sopenharmony_cifollows: 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci.. code-block:: bash 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci $ ./tools/testing/kunit/kunit.py run --kunitconfig=drivers/gpu/drm/tests \ 23262306a36Sopenharmony_ci --kconfig_add CONFIG_VIRTIO_UML=y \ 23362306a36Sopenharmony_ci --kconfig_add CONFIG_UML_PCI_OVER_VIRTIO=y 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci.. note:: 23662306a36Sopenharmony_ci The configuration included in ``.kunitconfig`` should be as generic as 23762306a36Sopenharmony_ci possible. 23862306a36Sopenharmony_ci ``CONFIG_VIRTIO_UML`` and ``CONFIG_UML_PCI_OVER_VIRTIO`` are not 23962306a36Sopenharmony_ci included in it because they are only required for User Mode Linux. 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ciLegacy Support Code 24362306a36Sopenharmony_ci=================== 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ciThe section very briefly covers some of the old legacy support code 24662306a36Sopenharmony_ciwhich is only used by old DRM drivers which have done a so-called 24762306a36Sopenharmony_cishadow-attach to the underlying device instead of registering as a real 24862306a36Sopenharmony_cidriver. This also includes some of the old generic buffer management and 24962306a36Sopenharmony_cicommand submission code. Do not use any of this in new and modern 25062306a36Sopenharmony_cidrivers. 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ciLegacy Suspend/Resume 25362306a36Sopenharmony_ci--------------------- 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ciThe DRM core provides some suspend/resume code, but drivers wanting full 25662306a36Sopenharmony_cisuspend/resume support should provide save() and restore() functions. 25762306a36Sopenharmony_ciThese are called at suspend, hibernate, or resume time, and should 25862306a36Sopenharmony_ciperform any state save or restore required by your device across suspend 25962306a36Sopenharmony_cior hibernate states. 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ciint (\*suspend) (struct drm_device \*, pm_message_t state); int 26262306a36Sopenharmony_ci(\*resume) (struct drm_device \*); 26362306a36Sopenharmony_ciThose are legacy suspend and resume methods which *only* work with the 26462306a36Sopenharmony_cilegacy shadow-attach driver registration functions. New driver should 26562306a36Sopenharmony_ciuse the power management interface provided by their bus type (usually 26662306a36Sopenharmony_cithrough the :c:type:`struct device_driver <device_driver>` 26762306a36Sopenharmony_cidev_pm_ops) and set these methods to NULL. 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ciLegacy DMA Services 27062306a36Sopenharmony_ci------------------- 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ciThis should cover how DMA mapping etc. is supported by the core. These 27362306a36Sopenharmony_cifunctions are deprecated and should not be used. 274