Linux Gpu Documentation
Total Page:16
File Type:pdf, Size:1020Kb
Linux Gpu Documentation The kernel development community Jul 14, 2020 CONTENTS i ii CHAPTER ONE INTRODUCTION The Linux DRM layer contains code intended to support the needs of complex graphics devices, usually containing programmable pipelines well suited to 3D graphics acceleration. Graphics drivers in the kernel may make use of DRM func- tions to make tasks like memory management, interrupt handling and DMA easier, and provide a uniform interface to applications. A note on versions: this guide covers features found in the DRM tree, including the TTM memory manager, output configuration and mode setting, and the new vblank internals, in addition to all the regular features found in current kernels. [Insert diagram of typical DRM stack here] 1.1 Style Guidelines For consistency this documentation uses American English. Abbreviations are written as all-uppercase, for example: DRM, KMS, IOCTL, CRTC, and so on. To aid in reading, documentations make full use of the markup characters kerneldoc provides: @parameter for function parameters, @member for structure members (within the same structure), &struct structure to reference structures and func- tion() for functions. These all get automatically hyperlinked if kerneldoc for the referenced objects exists. When referencing entries in function vtables (and struc- ture members in general) please use &vtable_name.vfunc. Unfortunately this does not yet yield a direct link to the member, only the structure. Except in special situations (to separate locked from unlocked variants) locking requirements for functions aren’t documented in the kerneldoc. Instead locking should be check at runtime using e.g. WARN_ON(!mutex_is_locked(...));. Since it’s much easier to ignore documentation than runtime noise this provides more value. And on top of that runtime checks do need to be updated when the locking rules change, increasing the chances that they’re correct. Within the documenta- tion the locking rules should be explained in the relevant structures: Either in the comment for the lock explaining what it protects, or data fields need a note about which lock protects them, or both. Functions which have a non-void return value should have a section called “Re- turns”explaining the expected return values in different cases and their meanings. Currently there’s no consensus whether that section name should be all upper- case or not, and whether it should end in a colon or not. Go with the file-local style. Other common section names are “Notes”with information for dangerous or tricky corner cases, and “FIXME”where the interface could be cleaned up. 1 Linux Gpu Documentation Also read the guidelines for the kernel documentation at large. 1.1.1 Documentation Requirements for kAPI All kernel APIs exported to other modules must be documented, including their datastructures and at least a short introductory section explaining the overall con- cepts. Documentation should be put into the code itself as kerneldoc comments as much as reasonable. Do not blindly document everything, but document only what’s relevant for driver authors: Internal functions of drm.ko and definitely static functions should not have formal kerneldoc comments. Use normal C comments if you feel like a com- ment is warranted. You may use kerneldoc syntax in the comment, but it shall not start with a /** kerneldoc marker. Similar for data structures, annotate anything entirely private with /* private: */ comments as per the documentation guide. 1.2 Getting Started Developers interested in helping out with the DRM subsystem are very welcome. Often people will resort to sending in patches for various issues reported by check- patch or sparse. We welcome such contributions. Anyone looking to kick it up a notch can find a list of janitorial tasks on the TODO list. 1.3 Contribution Process Mostly the DRM subsystem works like any other kernel subsystem, see the main process guidelines and documentation for how things work. Here we just docu- ment some of the specialities of the GPU subsystem. 1.3.1 Feature Merge Deadlines All feature work must be in the linux-next tree by the -rc6 release of the current release cycle, otherwise they must be postponed and can’t reach the next merge window. All patches must have landed in the drm-next tree by latest -rc7, but if your branch is not in linux-next then this must have happened by -rc6 already. After that point only bugfixes (like after the upstream merge window has closed with the -rc1 release) are allowed. No new platform enabling or new drivers are allowed. This means that there’s a blackout-period of about one month where feature work can’t be merged. The recommended way to deal with that is having a -next tree that’s always open, but making sure to not feed it into linux-next during the black- out period. As an example, drm-misc works like that. 2 Chapter 1. Introduction Linux Gpu Documentation 1.3.2 Code of Conduct As a freedesktop.org project, dri-devel, and the DRM community, follows the Con- tributor Covenant, found at: https://www.freedesktop.org/wiki/CodeOfConduct Please conduct yourself in a respectful and civilised manner when interacting with community members on mailing lists, IRC, or bug trackers. The community rep- resents the project as a whole, and abusive or bullying behaviour is not tolerated by the project. 1.3. Contribution Process 3 Linux Gpu Documentation 4 Chapter 1. Introduction CHAPTER TWO 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 im- plementation 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 man- agement, output management, framebuffer management, command submission & fencing, suspend/resume support, and DMA services. 2.1 Driver Initialization At the core of every DRM driver is a struct 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 struct 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 struct drm_driver static information fields, and will then describe individual operations in details as they get used in later sections. 2.1.1 Driver Information Major, Minor and Patchlevel int major; int minor; int patchlevel; The DRM core identifies driver versions bya 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 ver- sion passed to DRM_IOCTL_SET_VERSION. When the driver API changes between 5 Linux Gpu Documentation minor versions, applications can call DRM_IOCTL_SET_VERSION to select a spe- cific 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, Description and Date 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. The driver date, formatted as YYYYMMDD, is meant to identify the date of the latest modification to the driver. However, as most drivers fail to update it,its value is mostly useless. The DRM core prints it to the kernel log at initialization time and passes it to userspace through the DRM_IOCTL_VERSION ioctl. 2.1.2 Device Instance and Driver Handling A device instance for a drm driver is represented by struct drm_device. This is initialized with drm_dev_init(), usually from bus-specific ->probe() callbacks implemented by the driver. The driver then needs to initialize all the various sub- systems for the drm device like memory management, vblank handling, modeset- ting support and intial output configuration plus obviously initialize all the corre- sponding hardware bits. Finally when everything is up and running and ready for userspace the device instance can be published using drm_dev_register(). There is also deprecated support for initalizing device instances using bus-specific helpers and the drm_driver.load callback. But due to backwards-compatibility needs the device instance have to be published too early, which requires unpretty global locking to make safe and is therefore only support for existing drivers not yet converted to the new scheme. When cleaning up a device instance everything needs to be done in reverse: First unpublish the device instance with drm_dev_unregister(). Then clean up any other resources allocated at device initialization and drop the driver’s reference to drm_device using drm_dev_put(). Note that any allocation or resource which is visible to userspace must be released only when the final drm_dev_put() is called, and not when the driver is unbound from the underlying physical struct device. Best to use drm_device managed resources with drmm_add_action(), drmm_kmalloc() and related functions. devres managed resources like devm_kmalloc() can only be used for resources directly related to the underlying hardware device, and only used in code paths fully protected by drm_dev_enter() and drm_dev_exit().