diff options
Diffstat (limited to 'Documentation/DocBook/gpu.tmpl')
-rw-r--r-- | Documentation/DocBook/gpu.tmpl | 3540 |
1 files changed, 0 insertions, 3540 deletions
diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl deleted file mode 100644 index 7586bf75f62e..000000000000 --- a/Documentation/DocBook/gpu.tmpl +++ /dev/null @@ -1,3540 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" - "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> - -<book id="gpuDevelopersGuide"> - <bookinfo> - <title>Linux GPU Driver Developer's Guide</title> - - <authorgroup> - <author> - <firstname>Jesse</firstname> - <surname>Barnes</surname> - <contrib>Initial version</contrib> - <affiliation> - <orgname>Intel Corporation</orgname> - <address> - <email>jesse.barnes@intel.com</email> - </address> - </affiliation> - </author> - <author> - <firstname>Laurent</firstname> - <surname>Pinchart</surname> - <contrib>Driver internals</contrib> - <affiliation> - <orgname>Ideas on board SPRL</orgname> - <address> - <email>laurent.pinchart@ideasonboard.com</email> - </address> - </affiliation> - </author> - <author> - <firstname>Daniel</firstname> - <surname>Vetter</surname> - <contrib>Contributions all over the place</contrib> - <affiliation> - <orgname>Intel Corporation</orgname> - <address> - <email>daniel.vetter@ffwll.ch</email> - </address> - </affiliation> - </author> - <author> - <firstname>Lukas</firstname> - <surname>Wunner</surname> - <contrib>vga_switcheroo documentation</contrib> - <affiliation> - <address> - <email>lukas@wunner.de</email> - </address> - </affiliation> - </author> - </authorgroup> - - <copyright> - <year>2008-2009</year> - <year>2013-2014</year> - <holder>Intel Corporation</holder> - </copyright> - <copyright> - <year>2012</year> - <holder>Laurent Pinchart</holder> - </copyright> - <copyright> - <year>2015</year> - <holder>Lukas Wunner</holder> - </copyright> - - <legalnotice> - <para> - The contents of this file may be used under the terms of the GNU - General Public License version 2 (the "GPL") as distributed in - the kernel source COPYING file. - </para> - </legalnotice> - - <revhistory> - <!-- Put document revisions here, newest first. --> - <revision> - <revnumber>1.0</revnumber> - <date>2012-07-13</date> - <authorinitials>LP</authorinitials> - <revremark>Added extensive documentation about driver internals. - </revremark> - </revision> - <revision> - <revnumber>1.1</revnumber> - <date>2015-10-11</date> - <authorinitials>LW</authorinitials> - <revremark>Added vga_switcheroo documentation. - </revremark> - </revision> - </revhistory> - </bookinfo> - -<toc></toc> - -<part id="drmCore"> - <title>DRM Core</title> - <partintro> - <para> - This first part of the GPU Driver Developer's Guide documents core DRM - code, helper libraries for writing drivers and generic userspace - interfaces exposed by DRM drivers. - </para> - </partintro> - - <chapter id="drmIntroduction"> - <title>Introduction</title> - <para> - 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 functions to make - tasks like memory management, interrupt handling and DMA easier, - and provide a uniform interface to applications. - </para> - <para> - 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. - </para> - <para> - [Insert diagram of typical DRM stack here] - </para> - <sect1> - <title>Style Guidelines</title> - <para> - 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, &structure to reference structures and - function() for functions. These all get automatically hyperlinked if - kerneldoc for the referenced objects exists. When referencing entries in - function vtables please use ->vfunc(). Note that kerneldoc does - not support referencing struct members directly, so please add a reference - to the vtable struct somewhere in the same paragraph or at least section. - </para> - <para> - 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. - <code>WARN_ON(!mutex_is_locked(...));</code>. 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 - documentation 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. - </para> - <para> - Functions which have a non-<code>void</code> return value should have a - section called "Returns" 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. - </para> - </sect1> - </chapter> - - <!-- Internals --> - - <chapter id="drmInternals"> - <title>DRM Internals</title> - <para> - This chapter documents DRM internals relevant to driver authors - and developers working to add support for the latest features to - existing drivers. - </para> - <para> - 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. - </para> - <para> - 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. - </para> - - <!-- Internals: driver init --> - - <sect1> - <title>Driver Initialization</title> - <para> - At the core of every DRM driver is a <structname>drm_driver</structname> - structure. Drivers typically statically initialize a drm_driver structure, - and then pass it to <function>drm_dev_alloc()</function> to allocate a - device instance. After the device instance is fully initialized it can be - registered (which makes it accessible from userspace) using - <function>drm_dev_register()</function>. - </para> - <para> - The <structname>drm_driver</structname> 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 <structname>drm_driver</structname> static - information fields, and will then describe individual operations in - details as they get used in later sections. - </para> - <sect2> - <title>Driver Information</title> - <sect3> - <title>Driver Features</title> - <para> - Drivers inform the DRM core about their requirements and supported - features by setting appropriate flags in the - <structfield>driver_features</structfield> field. Since those flags - influence the DRM core behaviour since registration time, most of them - must be set to registering the <structname>drm_driver</structname> - instance. - </para> - <synopsis>u32 driver_features;</synopsis> - <variablelist> - <title>Driver Feature Flags</title> - <varlistentry> - <term>DRIVER_USE_AGP</term> - <listitem><para> - Driver uses AGP interface, the DRM core will manage AGP resources. - </para></listitem> - </varlistentry> - <varlistentry> - <term>DRIVER_REQUIRE_AGP</term> - <listitem><para> - Driver needs AGP interface to function. AGP initialization failure - will become a fatal error. - </para></listitem> - </varlistentry> - <varlistentry> - <term>DRIVER_PCI_DMA</term> - <listitem><para> - Driver is capable of PCI DMA, mapping of PCI DMA buffers to - userspace will be enabled. Deprecated. - </para></listitem> - </varlistentry> - <varlistentry> - <term>DRIVER_SG</term> - <listitem><para> - Driver can perform scatter/gather DMA, allocation and mapping of - scatter/gather buffers will be enabled. Deprecated. - </para></listitem> - </varlistentry> - <varlistentry> - <term>DRIVER_HAVE_DMA</term> - <listitem><para> - Driver supports DMA, the userspace DMA API will be supported. - Deprecated. - </para></listitem> - </varlistentry> - <varlistentry> - <term>DRIVER_HAVE_IRQ</term><term>DRIVER_IRQ_SHARED</term> - <listitem><para> - DRIVER_HAVE_IRQ indicates whether the driver has an IRQ handler - managed by the DRM Core. The core will support simple IRQ handler - installation when the flag is set. The installation process is - described in <xref linkend="drm-irq-registration"/>.</para> - <para>DRIVER_IRQ_SHARED indicates whether the device & handler - support shared IRQs (note that this is required of PCI drivers). - </para></listitem> - </varlistentry> - <varlistentry> - <term>DRIVER_GEM</term> - <listitem><para> - Driver use the GEM memory manager. - </para></listitem> - </varlistentry> - <varlistentry> - <term>DRIVER_MODESET</term> - <listitem><para> - Driver supports mode setting interfaces (KMS). - </para></listitem> - </varlistentry> - <varlistentry> - <term>DRIVER_PRIME</term> - <listitem><para> - Driver implements DRM PRIME buffer sharing. - </para></listitem> - </varlistentry> - <varlistentry> - <term>DRIVER_RENDER</term> - <listitem><para> - Driver supports dedicated render nodes. - </para></listitem> - </varlistentry> - <varlistentry> - <term>DRIVER_ATOMIC</term> - <listitem><para> - Driver supports atomic properties. In this case the driver - must implement appropriate obj->atomic_get_property() vfuncs - for any modeset objects with driver specific properties. - </para></listitem> - </varlistentry> - </variablelist> - </sect3> - <sect3> - <title>Major, Minor and Patchlevel</title> - <synopsis>int major; -int minor; -int patchlevel;</synopsis> - <para> - 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. - </para> - <para> - 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. - </para> - </sect3> - <sect3> - <title>Name, Description and Date</title> - <synopsis>char *name; -char *desc; -char *date;</synopsis> - <para> - The driver name is printed to the kernel log at initialization time, - used for IRQ registration and passed to userspace through - DRM_IOCTL_VERSION. - </para> - <para> - The driver description is a purely informative string passed to - userspace through the DRM_IOCTL_VERSION ioctl and otherwise unused by - the kernel. - </para> - <para> - 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. - </para> - </sect3> - </sect2> - <sect2> - <title>Device Instance and Driver Handling</title> -!Pdrivers/gpu/drm/drm_drv.c driver instance overview -!Edrivers/gpu/drm/drm_drv.c - </sect2> - <sect2> - <title>Driver Load</title> - <sect3 id="drm-irq-registration"> - <title>IRQ Registration</title> - <para> - The DRM core tries to facilitate IRQ handler registration and - unregistration by providing <function>drm_irq_install</function> and - <function>drm_irq_uninstall</function> functions. Those functions only - support a single interrupt per device, devices that use more than one - IRQs need to be handled manually. - </para> - <sect4> - <title>Managed IRQ Registration</title> - <para> - <function>drm_irq_install</function> starts by calling the - <methodname>irq_preinstall</methodname> driver operation. The operation - is optional and must make sure that the interrupt will not get fired by - clearing all pending interrupt flags or disabling the interrupt. - </para> - <para> - The passed-in IRQ will then be requested by a call to - <function>request_irq</function>. If the DRIVER_IRQ_SHARED driver - feature flag is set, a shared (IRQF_SHARED) IRQ handler will be - requested. - </para> - <para> - The IRQ handler function must be provided as the mandatory irq_handler - driver operation. It will get passed directly to - <function>request_irq</function> and thus has the same prototype as all - IRQ handlers. It will get called with a pointer to the DRM device as the - second argument. - </para> - <para> - Finally the function calls the optional - <methodname>irq_postinstall</methodname> driver operation. The operation - usually enables interrupts (excluding the vblank interrupt, which is - enabled separately), but drivers may choose to enable/disable interrupts - at a different time. - </para> - <para> - <function>drm_irq_uninstall</function> is similarly used to uninstall an - IRQ handler. It starts by waking up all processes waiting on a vblank - interrupt to make sure they don't hang, and then calls the optional - <methodname>irq_uninstall</methodname> driver operation. The operation - must disable all hardware interrupts. Finally the function frees the IRQ - by calling <function>free_irq</function>. - </para> - </sect4> - <sect4> - <title>Manual IRQ Registration</title> - <para> - Drivers that require multiple interrupt handlers can't use the managed - IRQ registration functions. In that case IRQs must be registered and - unregistered manually (usually with the <function>request_irq</function> - and <function>free_irq</function> functions, or their devm_* equivalent). - </para> - <para> - When manually registering IRQs, drivers must not set the DRIVER_HAVE_IRQ - driver feature flag, and must not provide the - <methodname>irq_handler</methodname> driver operation. They must set the - <structname>drm_device</structname> <structfield>irq_enabled</structfield> - field to 1 upon registration of the IRQs, and clear it to 0 after - unregistering the IRQs. - </para> - </sect4> - </sect3> - <sect3> - <title>Memory Manager Initialization</title> - <para> - 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 - <xref linkend="drm-memory-management"/> for details. - </para> - </sect3> - <sect3> - <title>Miscellaneous Device Configuration</title> - <para> - 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. - <!--!Fdrivers/pci/rom.c pci_map_rom--> - </para> - </sect3> - </sect2> - <sect2> - <title>Bus-specific Device Registration and PCI Support</title> - <para> - A number of functions are provided to help with device registration. - The functions deal with PCI and platform devices respectively and are - only provided for historical reasons. These are all deprecated and - shouldn't be used in new drivers. Besides that there's a few - helpers for pci drivers. - </para> -!Edrivers/gpu/drm/drm_pci.c -!Edrivers/gpu/drm/drm_platform.c - </sect2> - </sect1> - - <!-- Internals: memory management --> - - <sect1 id="drm-memory-management"> - <title>Memory management</title> - <para> - Modern Linux systems require large amount of graphics memory to store - frame buffers, textures, vertices and other graphics-related data. Given - the very dynamic nature of many of that data, managing graphics memory - efficiently is thus crucial for the graphics stack and plays a central - role in the DRM infrastructure. - </para> - <para> - The DRM core includes two memory managers, namely Translation Table Maps - (TTM) and Graphics Execution Manager (GEM). TTM was the first DRM memory - manager to be developed and tried to be a one-size-fits-them all - solution. It provides a single userspace API to accommodate the need of - all hardware, supporting both Unified Memory Architecture (UMA) devices - and devices with dedicated video RAM (i.e. most discrete video cards). - This resulted in a large, complex piece of code that turned out to be - hard to use for driver development. - </para> - <para> - GEM started as an Intel-sponsored project in reaction to TTM's - complexity. Its design philosophy is completely different: instead of - providing a solution to every graphics memory-related problems, GEM - identified common code between drivers and created a support library to - share it. GEM has simpler initialization and execution requirements than - TTM, but has no video RAM management capabilities and is thus limited to - UMA devices. - </para> - <sect2> - <title>The Translation Table Manager (TTM)</title> - <para> - TTM design background and information belongs here. - </para> - <sect3> - <title>TTM initialization</title> - <warning><para>This section is outdated.</para></warning> - <para> - Drivers wishing to support TTM must fill out a drm_bo_driver - structure. The structure contains several fields with function - pointers for initializing the TTM, allocating and freeing memory, - waiting for command completion and fence synchronization, and memory - migration. See the radeon_ttm.c file for an example of usage. - </para> - <para> - The ttm_global_reference structure is made up of several fields: - </para> - <programlisting> - struct ttm_global_reference { - enum ttm_global_types global_type; - size_t size; - void *object; - int (*init) (struct ttm_global_reference *); - void (*release) (struct ttm_global_reference *); - }; - </programlisting> - <para> - There should be one global reference structure for your memory - manager as a whole, and there will be others for each object - created by the memory manager at runtime. Your global TTM should - have a type of TTM_GLOBAL_TTM_MEM. The size field for the global - object should be sizeof(struct ttm_mem_global), and the init and - release hooks should point at your driver-specific init and - release routines, which probably eventually call - ttm_mem_global_init and ttm_mem_global_release, respectively. - </para> - <para> - Once your global TTM accounting structure is set up and initialized - by calling ttm_global_item_ref() on it, - you need to create a buffer object TTM to - provide a pool for buffer object allocation by clients and the - kernel itself. The type of this object should be TTM_GLOBAL_TTM_BO, - and its size should be sizeof(struct ttm_bo_global). Again, - driver-specific init and release functions may be provided, - likely eventually calling ttm_bo_global_init() and - ttm_bo_global_release(), respectively. Also, like the previous - object, ttm_global_item_ref() is used to create an initial reference - count for the TTM, which will call your initialization function. - </para> - </sect3> - </sect2> - <sect2 id="drm-gem"> - <title>The Graphics Execution Manager (GEM)</title> - <para> - The GEM design approach has resulted in a memory manager that doesn't - provide full coverage of all (or even all common) use cases in its - userspace or kernel API. GEM exposes a set of standard memory-related - operations to userspace and a set of helper functions to drivers, and let - drivers implement hardware-specific operations with their own private API. - </para> - <para> - The GEM userspace API is described in the - <ulink url="http://lwn.net/Articles/283798/"><citetitle>GEM - the Graphics - Execution Manager</citetitle></ulink> article on LWN. While slightly - outdated, the document provides a good overview of the GEM API principles. - Buffer allocation and read and write operations, described as part of the - common GEM API, are currently implemented using driver-specific ioctls. - </para> - <para> - GEM is data-agnostic. It manages abstract buffer objects without knowing - what individual buffers contain. APIs that require knowledge of buffer - contents or purpose, such as buffer allocation or synchronization - primitives, are thus outside of the scope of GEM and must be implemented - using driver-specific ioctls. - </para> - <para> - On a fundamental level, GEM involves several operations: - <itemizedlist> - <listitem>Memory allocation and freeing</listitem> - <listitem>Command execution</listitem> - <listitem>Aperture management at command execution time</listitem> - </itemizedlist> - Buffer object allocation is relatively straightforward and largely - provided by Linux's shmem layer, which provides memory to back each - object. - </para> - <para> - Device-specific operations, such as command execution, pinning, buffer - read & write, mapping, and domain ownership transfers are left to - driver-specific ioctls. - </para> - <sect3> - <title>GEM Initialization</title> - <para> - Drivers that use GEM must set the DRIVER_GEM bit in the struct - <structname>drm_driver</structname> - <structfield>driver_features</structfield> field. The DRM core will - then automatically initialize the GEM core before calling the - <methodname>load</methodname> operation. Behind the scene, this will - create a DRM Memory Manager object which provides an address space - pool for object allocation. - </para> - <para> - In a KMS configuration, drivers need to allocate and initialize a - command ring buffer following core GEM initialization if required by - the hardware. UMA devices usually have what is called a "stolen" - memory region, which provides space for the initial framebuffer and - large, contiguous memory regions required by the device. This space is - typically not managed by GEM, and must be initialized separately into - its own DRM MM object. - </para> - </sect3> - <sect3> - <title>GEM Objects Creation</title> - <para> - GEM splits creation of GEM objects and allocation of the memory that - backs them in two distinct operations. - </para> - <para> - GEM objects are represented by an instance of struct - <structname>drm_gem_object</structname>. Drivers usually need to extend - GEM objects with private information and thus create a driver-specific - GEM object structure type that embeds an instance of struct - <structname>drm_gem_object</structname>. - </para> - <para> - To create a GEM object, a driver allocates memory for an instance of its - specific GEM object type and initializes the embedded struct - <structname>drm_gem_object</structname> with a call to - <function>drm_gem_object_init</function>. The function takes a pointer to - the DRM device, a pointer to the GEM object and the buffer object size - in bytes. - </para> - <para> - GEM uses shmem to allocate anonymous pageable memory. - <function>drm_gem_object_init</function> will create an shmfs file of - the requested size and store it into the struct - <structname>drm_gem_object</structname> <structfield>filp</structfield> - field. The memory is used as either main storage for the object when the - graphics hardware uses system memory directly or as a backing store - otherwise. - </para> - <para> - Drivers are responsible for the actual physical pages allocation by - calling <function>shmem_read_mapping_page_gfp</function> for each page. - Note that they can decide to allocate pages when initializing the GEM - object, or to delay allocation until the memory is needed (for instance - when a page fault occurs as a result of a userspace memory access or - when the driver needs to start a DMA transfer involving the memory). - </para> - <para> - Anonymous pageable memory allocation is not always desired, for instance - when the hardware requires physically contiguous system memory as is - often the case in embedded devices. Drivers can create GEM objects with - no shmfs backing (called private GEM objects) by initializing them with - a call to <function>drm_gem_private_object_init</function> instead of - <function>drm_gem_object_init</function>. Storage for private GEM - objects must be managed by drivers. - </para> - </sect3> - <sect3> - <title>GEM Objects Lifetime</title> - <para> - All GEM objects are reference-counted by the GEM core. References can be - acquired and release by <function>calling drm_gem_object_reference</function> - and <function>drm_gem_object_unreference</function> respectively. The - caller must hold the <structname>drm_device</structname> - <structfield>struct_mutex</structfield> lock when calling - <function>drm_gem_object_reference</function>. As a convenience, GEM - provides <function>drm_gem_object_unreference_unlocked</function> - functions that can be called without holding the lock. - </para> - <para> - When the last reference to a GEM object is released the GEM core calls - the <structname>drm_driver</structname> - <methodname>gem_free_object</methodname> operation. That operation is - mandatory for GEM-enabled drivers and must free the GEM object and all - associated resources. - </para> - <para> - <synopsis>void (*gem_free_object) (struct drm_gem_object *obj);</synopsis> - Drivers are responsible for freeing all GEM object resources. This includes - the resources created by the GEM core, which need to be released with - <function>drm_gem_object_release</function>. - </para> - </sect3> - <sect3> - <title>GEM Objects Naming</title> - <para> - Communication between userspace and the kernel refers to GEM objects - using local handles, global names or, more recently, file descriptors. - All of those are 32-bit integer values; the usual Linux kernel limits - apply to the file descriptors. - </para> - <para> - GEM handles are local to a DRM file. Applications get a handle to a GEM - object through a driver-specific ioctl, and can use that handle to refer - to the GEM object in other standard or driver-specific ioctls. Closing a - DRM file handle frees all its GEM handles and dereferences the - associated GEM objects. - </para> - <para> - To create a handle for a GEM object drivers call - <function>drm_gem_handle_create</function>. The function takes a pointer - to the DRM file and the GEM object and returns a locally unique handle. - When the handle is no longer needed drivers delete it with a call to - <function>drm_gem_handle_delete</function>. Finally the GEM object - associated with a handle can be retrieved by a call to - <function>drm_gem_object_lookup</function>. - </para> - <para> - Handles don't take ownership of GEM objects, they only take a reference - to the object that will be dropped when the handle is destroyed. To - avoid leaking GEM objects, drivers must make sure they drop the - reference(s) they own (such as the initial reference taken at object - creation time) as appropriate, without any special consideration for the - handle. For example, in the particular case of combined GEM object and - handle creation in the implementation of the - <methodname>dumb_create</methodname> operation, drivers must drop the - initial reference to the GEM object before returning the handle. - </para> - <para> - GEM names are similar in purpose to handles but are not local to DRM - files. They can be passed between processes to reference a GEM object - globally. Names can't be used directly to refer to objects in the DRM - API, applications must convert handles to names and names to handles - using the DRM_IOCTL_GEM_FLINK and DRM_IOCTL_GEM_OPEN ioctls - respectively. The conversion is handled by the DRM core without any - driver-specific support. - </para> - <para> - GEM also supports buffer sharing with dma-buf file descriptors through - PRIME. GEM-based drivers must use the provided helpers functions to - implement the exporting and importing correctly. See <xref linkend="drm-prime-support" />. - Since sharing file descriptors is inherently more secure than the - easily guessable and global GEM names it is the preferred buffer - sharing mechanism. Sharing buffers through GEM names is only supported - for legacy userspace. Furthermore PRIME also allows cross-device - buffer sharing since it is based on dma-bufs. - </para> - </sect3> - <sect3 id="drm-gem-objects-mapping"> - <title>GEM Objects Mapping</title> - <para> - Because mapping operations are fairly heavyweight GEM favours - read/write-like access to buffers, implemented through driver-specific - ioctls, over mapping buffers to userspace. However, when random access - to the buffer is needed (to perform software rendering for instance), - direct access to the object can be more efficient. - </para> - <para> - The mmap system call can't be used directly to map GEM objects, as they - don't have their own file handle. Two alternative methods currently - co-exist to map GEM objects to userspace. The first method uses a - driver-specific ioctl to perform the mapping operation, calling - <function>do_mmap</function> under the hood. This is often considered - dubious, seems to be discouraged for new GEM-enabled drivers, and will - thus not be described here. - </para> - <para> - The second method uses the mmap system call on the DRM file handle. - <synopsis>void *mmap(void *addr, size_t length, int prot, int flags, int fd, - off_t offset);</synopsis> - DRM identifies the GEM object to be mapped by a fake offset passed - through the mmap offset argument. Prior to being mapped, a GEM object - must thus be associated with a fake offset. To do so, drivers must call - <function>drm_gem_create_mmap_offset</function> on the object. - </para> - <para> - Once allocated, the fake offset value - must be passed to the application in a driver-specific way and can then - be used as the mmap offset argument. - </para> - <para> - The GEM core provides a helper method <function>drm_gem_mmap</function> - to handle object mapping. The method can be set directly as the mmap - file operation handler. It will look up the GEM object based on the - offset value and set the VMA operations to the - <structname>drm_driver</structname> <structfield>gem_vm_ops</structfield> - field. Note that <function>drm_gem_mmap</function> doesn't map memory to - userspace, but relies on the driver-provided fault handler to map pages - individually. - </para> - <para> - To use <function>drm_gem_mmap</function>, drivers must fill the struct - <structname>drm_driver</structname> <structfield>gem_vm_ops</structfield> - field with a pointer to VM operations. - </para> - <para> - <synopsis>struct vm_operations_struct *gem_vm_ops - - struct vm_operations_struct { - void (*open)(struct vm_area_struct * area); - void (*close)(struct vm_area_struct * area); - int (*fault)(struct vm_area_struct *vma, struct vm_fault *vmf); - };</synopsis> - </para> - <para> - The <methodname>open</methodname> and <methodname>close</methodname> - operations must update the GEM object reference count. Drivers can use - the <function>drm_gem_vm_open</function> and - <function>drm_gem_vm_close</function> helper functions directly as open - and close handlers. - </para> - <para> - The fault operation handler is responsible for mapping individual pages - to userspace when a page fault occurs. Depending on the memory - allocation scheme, drivers can allocate pages at fault time, or can - decide to allocate memory for the GEM object at the time the object is - created. - </para> - <para> - Drivers that want to map the GEM object upfront instead of handling page - faults can implement their own mmap file op |