|
@@ -29,12 +29,26 @@
|
|
|
</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>
|
|
|
</authorgroup>
|
|
|
|
|
|
<copyright>
|
|
|
<year>2008-2009</year>
|
|
|
- <year>2012</year>
|
|
|
+ <year>2013-2014</year>
|
|
|
<holder>Intel Corporation</holder>
|
|
|
+ </copyright>
|
|
|
+ <copyright>
|
|
|
+ <year>2012</year>
|
|
|
<holder>Laurent Pinchart</holder>
|
|
|
</copyright>
|
|
|
|
|
@@ -60,7 +74,15 @@
|
|
|
|
|
|
<toc></toc>
|
|
|
|
|
|
- <!-- Introduction -->
|
|
|
+<part id="drmCore">
|
|
|
+ <title>DRM Core</title>
|
|
|
+ <partintro>
|
|
|
+ <para>
|
|
|
+ This first part of the DRM Developer's Guide documents core DRM code,
|
|
|
+ helper libraries for writting drivers and generic userspace interfaces
|
|
|
+ exposed by DRM drivers.
|
|
|
+ </para>
|
|
|
+ </partintro>
|
|
|
|
|
|
<chapter id="drmIntroduction">
|
|
|
<title>Introduction</title>
|
|
@@ -264,8 +286,8 @@ char *date;</synopsis>
|
|
|
<para>
|
|
|
The <methodname>load</methodname> method is the driver and device
|
|
|
initialization entry point. The method is responsible for allocating and
|
|
|
- initializing driver private data, specifying supported performance
|
|
|
- counters, performing resource allocation and mapping (e.g. acquiring
|
|
|
+ initializing driver private data, performing resource allocation and
|
|
|
+ mapping (e.g. acquiring
|
|
|
clocks, mapping registers or allocating command buffers), initializing
|
|
|
the memory manager (<xref linkend="drm-memory-management"/>), installing
|
|
|
the IRQ handler (<xref linkend="drm-irq-registration"/>), setting up
|
|
@@ -295,7 +317,7 @@ char *date;</synopsis>
|
|
|
their <methodname>load</methodname> method called with flags to 0.
|
|
|
</para>
|
|
|
<sect3>
|
|
|
- <title>Driver Private & Performance Counters</title>
|
|
|
+ <title>Driver Private Data</title>
|
|
|
<para>
|
|
|
The driver private hangs off the main
|
|
|
<structname>drm_device</structname> structure and can be used for
|
|
@@ -307,14 +329,6 @@ char *date;</synopsis>
|
|
|
<structname>drm_device</structname>.<structfield>dev_priv</structfield>
|
|
|
set to NULL when the driver is unloaded.
|
|
|
</para>
|
|
|
- <para>
|
|
|
- DRM supports several counters which were used for rough performance
|
|
|
- characterization. This stat counter system is deprecated and should not
|
|
|
- be used. If performance monitoring is desired, the developer should
|
|
|
- investigate and potentially enhance the kernel perf and tracing
|
|
|
- infrastructure to export GPU related performance information for
|
|
|
- consumption by performance monitoring tools and applications.
|
|
|
- </para>
|
|
|
</sect3>
|
|
|
<sect3 id="drm-irq-registration">
|
|
|
<title>IRQ Registration</title>
|
|
@@ -697,55 +711,16 @@ char *date;</synopsis>
|
|
|
respectively. The conversion is handled by the DRM core without any
|
|
|
driver-specific support.
|
|
|
</para>
|
|
|
- <para>
|
|
|
- Similar to global names, GEM file descriptors are also used to share GEM
|
|
|
- objects across processes. They offer additional security: as file
|
|
|
- descriptors must be explicitly sent over UNIX domain sockets to be shared
|
|
|
- between applications, they can't be guessed like the globally unique GEM
|
|
|
- names.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Drivers that support GEM file descriptors, also known as the DRM PRIME
|
|
|
- API, must set the DRIVER_PRIME bit in the struct
|
|
|
- <structname>drm_driver</structname>
|
|
|
- <structfield>driver_features</structfield> field, and implement the
|
|
|
- <methodname>prime_handle_to_fd</methodname> and
|
|
|
- <methodname>prime_fd_to_handle</methodname> operations.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <synopsis>int (*prime_handle_to_fd)(struct drm_device *dev,
|
|
|
- struct drm_file *file_priv, uint32_t handle,
|
|
|
- uint32_t flags, int *prime_fd);
|
|
|
- int (*prime_fd_to_handle)(struct drm_device *dev,
|
|
|
- struct drm_file *file_priv, int prime_fd,
|
|
|
- uint32_t *handle);</synopsis>
|
|
|
- Those two operations convert a handle to a PRIME file descriptor and
|
|
|
- vice versa. Drivers must use the kernel dma-buf buffer sharing framework
|
|
|
- to manage the PRIME file descriptors.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- While non-GEM drivers must implement the operations themselves, GEM
|
|
|
- drivers must use the <function>drm_gem_prime_handle_to_fd</function>
|
|
|
- and <function>drm_gem_prime_fd_to_handle</function> helper functions.
|
|
|
- Those helpers rely on the driver
|
|
|
- <methodname>gem_prime_export</methodname> and
|
|
|
- <methodname>gem_prime_import</methodname> operations to create a dma-buf
|
|
|
- instance from a GEM object (dma-buf exporter role) and to create a GEM
|
|
|
- object from a dma-buf instance (dma-buf importer role).
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- <synopsis>struct dma_buf * (*gem_prime_export)(struct drm_device *dev,
|
|
|
- struct drm_gem_object *obj,
|
|
|
- int flags);
|
|
|
- struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev,
|
|
|
- struct dma_buf *dma_buf);</synopsis>
|
|
|
- These two operations are mandatory for GEM drivers that support DRM
|
|
|
- PRIME.
|
|
|
- </para>
|
|
|
- <sect4>
|
|
|
- <title>DRM PRIME Helper Functions Reference</title>
|
|
|
-!Pdrivers/gpu/drm/drm_prime.c PRIME Helpers
|
|
|
- </sect4>
|
|
|
+ <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>
|
|
@@ -829,62 +804,6 @@ char *date;</synopsis>
|
|
|
faults can implement their own mmap file operation handler.
|
|
|
</para>
|
|
|
</sect3>
|
|
|
- <sect3>
|
|
|
- <title>Dumb GEM Objects</title>
|
|
|
- <para>
|
|
|
- The GEM API doesn't standardize GEM objects creation and leaves it to
|
|
|
- driver-specific ioctls. While not an issue for full-fledged graphics
|
|
|
- stacks that include device-specific userspace components (in libdrm for
|
|
|
- instance), this limit makes DRM-based early boot graphics unnecessarily
|
|
|
- complex.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- Dumb GEM objects partly alleviate the problem by providing a standard
|
|
|
- API to create dumb buffers suitable for scanout, which can then be used
|
|
|
- to create KMS frame buffers.
|
|
|
- </para>
|
|
|
- <para>
|
|
|
- To support dumb GEM objects drivers must implement the
|
|
|
- <methodname>dumb_create</methodname>,
|
|
|
- <methodname>dumb_destroy</methodname> and
|
|
|
- <methodname>dumb_map_offset</methodname> operations.
|
|
|
- </para>
|
|
|
- <itemizedlist>
|
|
|
- <listitem>
|
|
|
- <synopsis>int (*dumb_create)(struct drm_file *file_priv, struct drm_device *dev,
|
|
|
- struct drm_mode_create_dumb *args);</synopsis>
|
|
|
- <para>
|
|
|
- The <methodname>dumb_create</methodname> operation creates a GEM
|
|
|
- object suitable for scanout based on the width, height and depth
|
|
|
- from the struct <structname>drm_mode_create_dumb</structname>
|
|
|
- argument. It fills the argument's <structfield>handle</structfield>,
|
|
|
- <structfield>pitch</structfield> and <structfield>size</structfield>
|
|
|
- fields with a handle for the newly created GEM object and its line
|
|
|
- pitch and size in bytes.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <synopsis>int (*dumb_destroy)(struct drm_file *file_priv, struct drm_device *dev,
|
|
|
- uint32_t handle);</synopsis>
|
|
|
- <para>
|
|
|
- The <methodname>dumb_destroy</methodname> operation destroys a dumb
|
|
|
- GEM object created by <methodname>dumb_create</methodname>.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- <listitem>
|
|
|
- <synopsis>int (*dumb_map_offset)(struct drm_file *file_priv, struct drm_device *dev,
|
|
|
- uint32_t handle, uint64_t *offset);</synopsis>
|
|
|
- <para>
|
|
|
- The <methodname>dumb_map_offset</methodname> operation associates an
|
|
|
- mmap fake offset with the GEM object given by the handle and returns
|
|
|
- it. Drivers must use the
|
|
|
- <function>drm_gem_create_mmap_offset</function> function to
|
|
|
- associate the fake offset as described in
|
|
|
- <xref linkend="drm-gem-objects-mapping"/>.
|
|
|
- </para>
|
|
|
- </listitem>
|
|
|
- </itemizedlist>
|
|
|
- </sect3>
|
|
|
<sect3>
|
|
|
<title>Memory Coherency</title>
|
|
|
<para>
|
|
@@ -924,7 +843,99 @@ char *date;</synopsis>
|
|
|
abstracted from the client in libdrm.
|
|
|
</para>
|
|
|
</sect3>
|
|
|
- </sect2>
|
|
|
+ <sect3>
|
|
|
+ <title>GEM Function Reference</title>
|
|
|
+!Edrivers/gpu/drm/drm_gem.c
|
|
|
+ </sect3>
|
|
|
+ </sect2>
|
|
|
+ <sect2>
|
|
|
+ <title>VMA Offset Manager</title>
|
|
|
+!Pdrivers/gpu/drm/drm_vma_manager.c vma offset manager
|
|
|
+!Edrivers/gpu/drm/drm_vma_manager.c
|
|
|
+!Iinclude/drm/drm_vma_manager.h
|
|
|
+ </sect2>
|
|
|
+ <sect2 id="drm-prime-support">
|
|
|
+ <title>PRIME Buffer Sharing</title>
|
|
|
+ <para>
|
|
|
+ PRIME is the cross device buffer sharing framework in drm, originally
|
|
|
+ created for the OPTIMUS range of multi-gpu platforms. To userspace
|
|
|
+ PRIME buffers are dma-buf based file descriptors.
|
|
|
+ </para>
|
|
|
+ <sect3>
|
|
|
+ <title>Overview and Driver Interface</title>
|
|
|
+ <para>
|
|
|
+ Similar to GEM global names, PRIME file descriptors are
|
|
|
+ also used to share buffer objects across processes. They offer
|
|
|
+ additional security: as file descriptors must be explicitly sent over
|
|
|
+ UNIX domain sockets to be shared between applications, they can't be
|
|
|
+ guessed like the globally unique GEM names.
|
|
|
+ </para>
|
|
|
+ <para>
|
|
|
+ Drivers that support the PRIME
|
|
|
+ API must set the DRIVER_PRIME bit in the struct
|
|
|
+ <structname>drm_driver</structname>
|
|
|
+ <structfield>driver_features</structfield> field, and implement the
|
|
|
+ <methodname>prime_handle_to_fd</methodname> and
|
|
|
+ <methodname>prime_fd_to_handle</methodname> operations.
|
|
|
+ </para>
|
|
|
+ <para>
|
|
|
+ <synopsis>int (*prime_handle_to_fd)(struct drm_device *dev,
|
|
|
+ struct drm_file *file_priv, uint32_t handle,
|
|
|
+ uint32_t flags, int *prime_fd);
|
|
|
+int (*prime_fd_to_handle)(struct drm_device *dev,
|
|
|
+ struct drm_file *file_priv, int prime_fd,
|
|
|
+ uint32_t *handle);</synopsis>
|
|
|
+ Those two operations convert a handle to a PRIME file descriptor and
|
|
|
+ vice versa. Drivers must use the kernel dma-buf buffer sharing framework
|
|
|
+ to manage the PRIME file descriptors. Similar to the mode setting
|
|
|
+ API PRIME is agnostic to the underlying buffer object manager, as
|
|
|
+ long as handles are 32bit unsinged integers.
|
|
|
+ </para>
|
|
|
+ <para>
|
|
|
+ While non-GEM drivers must implement the operations themselves, GEM
|
|
|
+ drivers must use the <function>drm_gem_prime_handle_to_fd</function>
|
|
|
+ and <function>drm_gem_prime_fd_to_handle</function> helper functions.
|
|
|
+ Those helpers rely on the driver
|
|
|
+ <methodname>gem_prime_export</methodname> and
|
|
|
+ <methodname>gem_prime_import</methodname> operations to create a dma-buf
|
|
|
+ instance from a GEM object (dma-buf exporter role) and to create a GEM
|
|
|
+ object from a dma-buf instance (dma-buf importer role).
|
|
|
+ </para>
|
|
|
+ <para>
|
|
|
+ <synopsis>struct dma_buf * (*gem_prime_export)(struct drm_device *dev,
|
|
|
+ struct drm_gem_object *obj,
|
|
|
+ int flags);
|
|
|
+struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev,
|
|
|
+ struct dma_buf *dma_buf);</synopsis>
|
|
|
+ These two operations are mandatory for GEM drivers that support
|
|
|
+ PRIME.
|
|
|
+ </para>
|
|
|
+ </sect3>
|
|
|
+ <sect3>
|
|
|
+ <title>PRIME Helper Functions</title>
|
|
|
+!Pdrivers/gpu/drm/drm_prime.c PRIME Helpers
|
|
|
+ </sect3>
|
|
|
+ </sect2>
|
|
|
+ <sect2>
|
|
|
+ <title>PRIME Function References</title>
|
|
|
+!Edrivers/gpu/drm/drm_prime.c
|
|
|
+ </sect2>
|
|
|
+ <sect2>
|
|
|
+ <title>DRM MM Range Allocator</title>
|
|
|
+ <sect3>
|
|
|
+ <title>Overview</title>
|
|
|
+!Pdrivers/gpu/drm/drm_mm.c Overview
|
|
|
+ </sect3>
|
|
|
+ <sect3>
|
|
|
+ <title>LRU Scan/Eviction Support</title>
|
|
|
+!Pdrivers/gpu/drm/drm_mm.c lru scan roaster
|
|
|
+ </sect3>
|
|
|
+ </sect2>
|
|
|
+ <sect2>
|
|
|
+ <title>DRM MM Range Allocator Function References</title>
|
|
|
+!Edrivers/gpu/drm/drm_mm.c
|
|
|
+!Iinclude/drm/drm_mm.h
|
|
|
+ </sect2>
|
|
|
</sect1>
|
|
|
|
|
|
<!-- Internals: mode setting -->
|
|
@@ -952,6 +963,11 @@ int max_width, max_height;</synopsis>
|
|
|
<para>Mode setting functions.</para>
|
|
|
</listitem>
|
|
|
</itemizedlist>
|
|
|
+ <sect2>
|
|
|
+ <title>Display Modes Function Reference</title>
|
|
|
+!Iinclude/drm/drm_modes.h
|
|
|
+!Edrivers/gpu/drm/drm_modes.c
|
|
|
+ </sect2>
|
|
|
<sect2>
|
|
|
<title>Frame Buffer Creation</title>
|
|
|
<synopsis>struct drm_framebuffer *(*fb_create)(struct drm_device *dev,
|
|
@@ -968,9 +984,11 @@ int max_width, max_height;</synopsis>
|
|
|
Frame buffers rely on the underneath memory manager for low-level memory
|
|
|
operations. When creating a frame buffer applications pass a memory
|
|
|
handle (or a list of memory handles for multi-planar formats) through
|
|
|
- the <parameter>drm_mode_fb_cmd2</parameter> argument. This document
|
|
|
- assumes that the driver uses GEM, those handles thus reference GEM
|
|
|
- objects.
|
|
|
+ the <parameter>drm_mode_fb_cmd2</parameter> argument. For drivers using
|
|
|
+ GEM as their userspace buffer management interface this would be a GEM
|
|
|
+ handle. Drivers are however free to use their own backing storage object
|
|
|
+ handles, e.g. vmwgfx directly exposes special TTM handles to userspace
|
|
|
+ and so expects TTM handles in the create ioctl and not GEM handles.
|
|
|
</para>
|
|
|
<para>
|
|
|
Drivers must first validate the requested frame buffer parameters passed
|
|
@@ -992,7 +1010,7 @@ int max_width, max_height;</synopsis>
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- The initailization of the new framebuffer instance is finalized with a
|
|
|
+ The initialization of the new framebuffer instance is finalized with a
|
|
|
call to <function>drm_framebuffer_init</function> which takes a pointer
|
|
|
to DRM frame buffer operations (struct
|
|
|
<structname>drm_framebuffer_funcs</structname>). Note that this function
|
|
@@ -1042,7 +1060,7 @@ int max_width, max_height;</synopsis>
|
|
|
<para>
|
|
|
The lifetime of a drm framebuffer is controlled with a reference count,
|
|
|
drivers can grab additional references with
|
|
|
- <function>drm_framebuffer_reference</function> </para> and drop them
|
|
|
+ <function>drm_framebuffer_reference</function>and drop them
|
|
|
again with <function>drm_framebuffer_unreference</function>. For
|
|
|
driver-private framebuffers for which the last reference is never
|
|
|
dropped (e.g. for the fbdev framebuffer when the struct
|
|
@@ -1050,6 +1068,72 @@ int max_width, max_height;</synopsis>
|
|
|
helper struct) drivers can manually clean up a framebuffer at module
|
|
|
unload time with
|
|
|
<function>drm_framebuffer_unregister_private</function>.
|
|
|
+ </para>
|
|
|
+ </sect2>
|
|
|
+ <sect2>
|
|
|
+ <title>Dumb Buffer Objects</title>
|
|
|
+ <para>
|
|
|
+ The KMS API doesn't standardize backing storage object creation and
|
|
|
+ leaves it to driver-specific ioctls. Furthermore actually creating a
|
|
|
+ buffer object even for GEM-based drivers is done through a
|
|
|
+ driver-specific ioctl - GEM only has a common userspace interface for
|
|
|
+ sharing and destroying objects. While not an issue for full-fledged
|
|
|
+ graphics stacks that include device-specific userspace components (in
|
|
|
+ libdrm for instance), this limit makes DRM-based early boot graphics
|
|
|
+ unnecessarily complex.
|
|
|
+ </para>
|
|
|
+ <para>
|
|
|
+ Dumb objects partly alleviate the problem by providing a standard
|
|
|
+ API to create dumb buffers suitable for scanout, which can then be used
|
|
|
+ to create KMS frame buffers.
|
|
|
+ </para>
|
|
|
+ <para>
|
|
|
+ To support dumb objects drivers must implement the
|
|
|
+ <methodname>dumb_create</methodname>,
|
|
|
+ <methodname>dumb_destroy</methodname> and
|
|
|
+ <methodname>dumb_map_offset</methodname> operations.
|
|
|
+ </para>
|
|
|
+ <itemizedlist>
|
|
|
+ <listitem>
|
|
|
+ <synopsis>int (*dumb_create)(struct drm_file *file_priv, struct drm_device *dev,
|
|
|
+ struct drm_mode_create_dumb *args);</synopsis>
|
|
|
+ <para>
|
|
|
+ The <methodname>dumb_create</methodname> operation creates a driver
|
|
|
+ object (GEM or TTM handle) suitable for scanout based on the
|
|
|
+ width, height and depth from the struct
|
|
|
+ <structname>drm_mode_create_dumb</structname> argument. It fills the
|
|
|
+ argument's <structfield>handle</structfield>,
|
|
|
+ <structfield>pitch</structfield> and <structfield>size</structfield>
|
|
|
+ fields with a handle for the newly created object and its line
|
|
|
+ pitch and size in bytes.
|
|
|
+ </para>
|
|
|
+ </listitem>
|
|
|
+ <listitem>
|
|
|
+ <synopsis>int (*dumb_destroy)(struct drm_file *file_priv, struct drm_device *dev,
|
|
|
+ uint32_t handle);</synopsis>
|
|
|
+ <para>
|
|
|
+ The <methodname>dumb_destroy</methodname> operation destroys a dumb
|
|
|
+ object created by <methodname>dumb_create</methodname>.
|
|
|
+ </para>
|
|
|
+ </listitem>
|
|
|
+ <listitem>
|
|
|
+ <synopsis>int (*dumb_map_offset)(struct drm_file *file_priv, struct drm_device *dev,
|
|
|
+ uint32_t handle, uint64_t *offset);</synopsis>
|
|
|
+ <para>
|
|
|
+ The <methodname>dumb_map_offset</methodname> operation associates an
|
|
|
+ mmap fake offset with the object given by the handle and returns
|
|
|
+ it. Drivers must use the
|
|
|
+ <function>drm_gem_create_mmap_offset</function> function to
|
|
|
+ associate the fake offset as described in
|
|
|
+ <xref linkend="drm-gem-objects-mapping"/>.
|
|
|
+ </para>
|
|
|
+ </listitem>
|
|
|
+ </itemizedlist>
|
|
|
+ <para>
|
|
|
+ Note that dumb objects may not be used for gpu acceleration, as has been
|
|
|
+ attempted on some ARM embedded platforms. Such drivers really must have
|
|
|
+ a hardware-specific ioctl to allocate suitable buffer objects.
|
|
|
+ </para>
|
|
|
</sect2>
|
|
|
<sect2>
|
|
|
<title>Output Polling</title>
|
|
@@ -1110,7 +1194,7 @@ int max_width, max_height;</synopsis>
|
|
|
pointer to CRTC functions.
|
|
|
</para>
|
|
|
</sect3>
|
|
|
- <sect3>
|
|
|
+ <sect3 id="drm-kms-crtcops">
|
|
|
<title>CRTC Operations</title>
|
|
|
<sect4>
|
|
|
<title>Set Configuration</title>
|
|
@@ -1130,8 +1214,11 @@ int max_width, max_height;</synopsis>
|
|
|
This operation is called with the mode config lock held.
|
|
|
</para>
|
|
|
<note><para>
|
|
|
- FIXME: How should set_config interact with DPMS? If the CRTC is
|
|
|
- suspended, should it be resumed?
|
|
|
+ Note that the drm core has no notion of restoring the mode setting
|
|
|
+ state after resume, since all resume handling is in the full
|
|
|
+ responsibility of the driver. The common mode setting helper library
|
|
|
+ though provides a helper which can be used for this:
|
|
|
+ <function>drm_helper_resume_force_mode</function>.
|
|
|
</para></note>
|
|
|
</sect4>
|
|
|
<sect4>
|
|
@@ -1248,15 +1335,47 @@ int max_width, max_height;</synopsis>
|
|
|
optionally scale it to a destination size. The result is then blended
|
|
|
with or overlayed on top of a CRTC.
|
|
|
</para>
|
|
|
+ <para>
|
|
|
+ The DRM core recognizes three types of planes:
|
|
|
+ <itemizedlist>
|
|
|
+ <listitem>
|
|
|
+ DRM_PLANE_TYPE_PRIMARY represents a "main" plane for a CRTC. Primary
|
|
|
+ planes are the planes operated upon by by CRTC modesetting and flipping
|
|
|
+ operations described in <xref linkend="drm-kms-crtcops"/>.
|
|
|
+ </listitem>
|
|
|
+ <listitem>
|
|
|
+ DRM_PLANE_TYPE_CURSOR represents a "cursor" plane for a CRTC. Cursor
|
|
|
+ planes are the planes operated upon by the DRM_IOCTL_MODE_CURSOR and
|
|
|
+ DRM_IOCTL_MODE_CURSOR2 ioctls.
|
|
|
+ </listitem>
|
|
|
+ <listitem>
|
|
|
+ DRM_PLANE_TYPE_OVERLAY represents all non-primary, non-cursor planes.
|
|
|
+ Some drivers refer to these types of planes as "sprites" internally.
|
|
|
+ </listitem>
|
|
|
+ </itemizedlist>
|
|
|
+ For compatibility with legacy userspace, only overlay planes are made
|
|
|
+ available to userspace by default. Userspace clients may set the
|
|
|
+ DRM_CLIENT_CAP_UNIVERSAL_PLANES client capability bit to indicate that
|
|
|
+ they wish to receive a universal plane list containing all plane types.
|
|
|
+ </para>
|
|
|
<sect3>
|
|
|
<title>Plane Initialization</title>
|
|
|
<para>
|
|
|
- Planes are optional. To create a plane, a KMS drivers allocates and
|
|
|
+ To create a plane, a KMS drivers allocates and
|
|
|
zeroes an instances of struct <structname>drm_plane</structname>
|
|
|
(possibly as part of a larger structure) and registers it with a call
|
|
|
- to <function>drm_plane_init</function>. The function takes a bitmask
|
|
|
+ to <function>drm_universal_plane_init</function>. The function takes a bitmask
|
|
|
of the CRTCs that can be associated with the plane, a pointer to the
|
|
|
- plane functions and a list of format supported formats.
|
|
|
+ plane functions, a list of format supported formats, and the type of
|
|
|
+ plane (primary, cursor, or overlay) being initialized.
|
|
|
+ </para>
|
|
|
+ <para>
|
|
|
+ Cursor and overlay planes are optional. All drivers should provide
|
|
|
+ one primary plane per CRTC (although this requirement may change in
|
|
|
+ the future); drivers that do not wish to provide special handling for
|
|
|
+ primary planes may make use of the helper functions described in
|
|
|
+ <xref linkend="drm-kms-planehelpers"/> to create and register a
|
|
|
+ primary plane with standard capabilities.
|
|
|
</para>
|
|
|
</sect3>
|
|
|
<sect3>
|
|
@@ -1687,7 +1806,7 @@ void intel_crt_init(struct drm_device *dev)
|
|
|
<sect1>
|
|
|
<title>Mode Setting Helper Functions</title>
|
|
|
<para>
|
|
|
- The CRTC, encoder and connector functions provided by the drivers
|
|
|
+ The plane, CRTC, encoder and connector functions provided by the drivers
|
|
|
implement the DRM API. They're called by the DRM core and ioctl handlers
|
|
|
to handle device state changes and configuration request. As implementing
|
|
|
those functions often requires logic not specific to drivers, mid-layer
|
|
@@ -1695,8 +1814,8 @@ void intel_crt_init(struct drm_device *dev)
|
|
|
</para>
|
|
|
<para>
|
|
|
The DRM core contains one mid-layer implementation. The mid-layer provides
|
|
|
- implementations of several CRTC, encoder and connector functions (called
|
|
|
- from the top of the mid-layer) that pre-process requests and call
|
|
|
+ implementations of several plane, CRTC, encoder and connector functions
|
|
|
+ (called from the top of the mid-layer) that pre-process requests and call
|
|
|
lower-level functions provided by the driver (at the bottom of the
|
|
|
mid-layer). For instance, the
|
|
|
<function>drm_crtc_helper_set_config</function> function can be used to
|
|
@@ -2134,7 +2253,7 @@ void intel_crt_init(struct drm_device *dev)
|
|
|
set the <structfield>display_info</structfield>
|
|
|
<structfield>width_mm</structfield> and
|
|
|
<structfield>height_mm</structfield> fields if they haven't been set
|
|
|
- already (for instance at initilization time when a fixed-size panel is
|
|
|
+ already (for instance at initialization time when a fixed-size panel is
|
|
|
attached to the connector). The mode <structfield>width_mm</structfield>
|
|
|
and <structfield>height_mm</structfield> fields are only used internally
|
|
|
during EDID parsing and should not be set when creating modes manually.
|
|
@@ -2196,10 +2315,19 @@ void intel_crt_init(struct drm_device *dev)
|
|
|
!Edrivers/gpu/drm/drm_flip_work.c
|
|
|
</sect2>
|
|
|
<sect2>
|
|
|
- <title>VMA Offset Manager</title>
|
|
|
-!Pdrivers/gpu/drm/drm_vma_manager.c vma offset manager
|
|
|
-!Edrivers/gpu/drm/drm_vma_manager.c
|
|
|
-!Iinclude/drm/drm_vma_manager.h
|
|
|
+ <title>HDMI Infoframes Helper Reference</title>
|
|
|
+ <para>
|
|
|
+ Strictly speaking this is not a DRM helper library but generally useable
|
|
|
+ by any driver interfacing with HDMI outputs like v4l or alsa drivers.
|
|
|
+ But it nicely fits into the overall topic of mode setting helper
|
|
|
+ libraries and hence is also included here.
|
|
|
+ </para>
|
|
|
+!Iinclude/linux/hdmi.h
|
|
|
+!Edrivers/video/hdmi.c
|
|
|
+ </sect2>
|
|
|
+ <sect2>
|
|
|
+ <title id="drm-kms-planehelpers">Plane Helper Reference</title>
|
|
|
+!Edrivers/gpu/drm/drm_plane_helper.c Plane Helpers
|
|
|
</sect2>
|
|
|
</sect1>
|
|
|
|
|
@@ -2561,42 +2689,44 @@ int num_ioctls;</synopsis>
|
|
|
</para>
|
|
|
</sect2>
|
|
|
</sect1>
|
|
|
-
|
|
|
<sect1>
|
|
|
- <title>Command submission & fencing</title>
|
|
|
+ <title>Legacy Support Code</title>
|
|
|
<para>
|
|
|
- This should cover a few device-specific command submission
|
|
|
- implementations.
|
|
|
+ The section very brievely 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 mangement and command
|
|
|
+ submission code. Do not use any of this in new and modern drivers.
|
|
|
</para>
|
|
|
- </sect1>
|
|
|
-
|
|
|
- <!-- Internals: suspend/resume -->
|
|
|
|
|
|
- <sect1>
|
|
|
- <title>Suspend/Resume</title>
|
|
|
- <para>
|
|
|
- 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.
|
|
|
- </para>
|
|
|
- <synopsis>int (*suspend) (struct drm_device *, pm_message_t state);
|
|
|
-int (*resume) (struct drm_device *);</synopsis>
|
|
|
- <para>
|
|
|
- Those are legacy suspend and resume methods. New driver should use the
|
|
|
- power management interface provided by their bus type (usually through
|
|
|
- the struct <structname>device_driver</structname> dev_pm_ops) and set
|
|
|
- these methods to NULL.
|
|
|
- </para>
|
|
|
- </sect1>
|
|
|
+ <sect2>
|
|
|
+ <title>Legacy Suspend/Resume</title>
|
|
|
+ <para>
|
|
|
+ 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.
|
|
|
+ </para>
|
|
|
+ <synopsis>int (*suspend) (struct drm_device *, pm_message_t state);
|
|
|
+ int (*resume) (struct drm_device *);</synopsis>
|
|
|
+ <para>
|
|
|
+ Those are legacy suspend and resume methods which
|
|
|
+ <emphasis>only</emphasis> 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 struct <structname>device_driver</structname> dev_pm_ops) and set
|
|
|
+ these methods to NULL.
|
|
|
+ </para>
|
|
|
+ </sect2>
|
|
|
|
|
|
- <sect1>
|
|
|
- <title>DMA services</title>
|
|
|
- <para>
|
|
|
- This should cover how DMA mapping etc. is supported by the core.
|
|
|
- These functions are deprecated and should not be used.
|
|
|
- </para>
|
|
|
+ <sect2>
|
|
|
+ <title>Legacy DMA Services</title>
|
|
|
+ <para>
|
|
|
+ This should cover how DMA mapping etc. is supported by the core.
|
|
|
+ These functions are deprecated and should not be used.
|
|
|
+ </para>
|
|
|
+ </sect2>
|
|
|
</sect1>
|
|
|
</chapter>
|
|
|
|
|
@@ -2658,8 +2788,8 @@ int (*resume) (struct drm_device *);</synopsis>
|
|
|
DRM core provides multiple character-devices for user-space to use.
|
|
|
Depending on which device is opened, user-space can perform a different
|
|
|
set of operations (mainly ioctls). The primary node is always created
|
|
|
- and called <term>card<num></term>. Additionally, a currently
|
|
|
- unused control node, called <term>controlD<num></term> is also
|
|
|
+ and called card<num>. Additionally, a currently
|
|
|
+ unused control node, called controlD<num> is also
|
|
|
created. The primary node provides all legacy operations and
|
|
|
historically was the only interface used by userspace. With KMS, the
|
|
|
control node was introduced. However, the planned KMS control interface
|
|
@@ -2674,21 +2804,21 @@ int (*resume) (struct drm_device *);</synopsis>
|
|
|
nodes were introduced. Render nodes solely serve render clients, that
|
|
|
is, no modesetting or privileged ioctls can be issued on render nodes.
|
|
|
Only non-global rendering commands are allowed. If a driver supports
|
|
|
- render nodes, it must advertise it via the <term>DRIVER_RENDER</term>
|
|
|
+ render nodes, it must advertise it via the DRIVER_RENDER
|
|
|
DRM driver capability. If not supported, the primary node must be used
|
|
|
for render clients together with the legacy drmAuth authentication
|
|
|
procedure.
|
|
|
</para>
|
|
|
<para>
|
|
|
If a driver advertises render node support, DRM core will create a
|
|
|
- separate render node called <term>renderD<num></term>. There will
|
|
|
+ separate render node called renderD<num>. There will
|
|
|
be one render node per device. No ioctls except PRIME-related ioctls
|
|
|
- will be allowed on this node. Especially <term>GEM_OPEN</term> will be
|
|
|
+ will be allowed on this node. Especially GEM_OPEN will be
|
|
|
explicitly prohibited. Render nodes are designed to avoid the
|
|
|
buffer-leaks, which occur if clients guess the flink names or mmap
|
|
|
offsets on the legacy interface. Additionally to this basic interface,
|
|
|
drivers must mark their driver-dependent render-only ioctls as
|
|
|
- <term>DRM_RENDER_ALLOW</term> so render clients can use them. Driver
|
|
|
+ DRM_RENDER_ALLOW so render clients can use them. Driver
|
|
|
authors must be careful not to allow any privileged ioctls on render
|
|
|
nodes.
|
|
|
</para>
|
|
@@ -2749,15 +2879,73 @@ int (*resume) (struct drm_device *);</synopsis>
|
|
|
</sect1>
|
|
|
|
|
|
</chapter>
|
|
|
+</part>
|
|
|
+<part id="drmDrivers">
|
|
|
+ <title>DRM Drivers</title>
|
|
|
|
|
|
- <!-- API reference -->
|
|
|
+ <partintro>
|
|
|
+ <para>
|
|
|
+ This second part of the DRM Developer's Guide documents driver code,
|
|
|
+ implementation details and also all the driver-specific userspace
|
|
|
+ interfaces. Especially since all hardware-acceleration interfaces to
|
|
|
+ userspace are driver specific for efficiency and other reasons these
|
|
|
+ interfaces can be rather substantial. Hence every driver has its own
|
|
|
+ chapter.
|
|
|
+ </para>
|
|
|
+ </partintro>
|
|
|
|
|
|
- <appendix id="drmDriverApi">
|
|
|
- <title>DRM Driver API</title>
|
|
|
+ <chapter id="drmI915">
|
|
|
+ <title>drm/i915 Intel GFX Driver</title>
|
|
|
<para>
|
|
|
- Include auto-generated API reference here (need to reference it
|
|
|
- from paragraphs above too).
|
|
|
+ The drm/i915 driver supports all (with the exception of some very early
|
|
|
+ models) integrated GFX chipsets with both Intel display and rendering
|
|
|
+ blocks. This excludes a set of SoC platforms with an SGX rendering unit,
|
|
|
+ those have basic support through the gma500 drm driver.
|
|
|
</para>
|
|
|
- </appendix>
|
|
|
+ <sect1>
|
|
|
+ <title>Display Hardware Handling</title>
|
|
|
+ <para>
|
|
|
+ This section covers everything related to the display hardware including
|
|
|
+ the mode setting infrastructure, plane, sprite and cursor handling and
|
|
|
+ display, output probing and related topics.
|
|
|
+ </para>
|
|
|
+ <sect2>
|
|
|
+ <title>Mode Setting Infrastructure</title>
|
|
|
+ <para>
|
|
|
+ The i915 driver is thus far the only DRM driver which doesn't use the
|
|
|
+ common DRM helper code to implement mode setting sequences. Thus it
|
|
|
+ has its own tailor-made infrastructure for executing a display
|
|
|
+ configuration change.
|
|
|
+ </para>
|
|
|
+ </sect2>
|
|
|
+ <sect2>
|
|
|
+ <title>Plane Configuration</title>
|
|
|
+ <para>
|
|
|
+ This section covers plane configuration and composition with the
|
|
|
+ primary plane, sprites, cursors and overlays. This includes the
|
|
|
+ infrastructure to do atomic vsync'ed updates of all this state and
|
|
|
+ also tightly coupled topics like watermark setup and computation,
|
|
|
+ framebuffer compression and panel self refresh.
|
|
|
+ </para>
|
|
|
+ </sect2>
|
|
|
+ <sect2>
|
|
|
+ <title>Output Probing</title>
|
|
|
+ <para>
|
|
|
+ This section covers output probing and related infrastructure like the
|
|
|
+ hotplug interrupt storm detection and mitigation code. Note that the
|
|
|
+ i915 driver still uses most of the common DRM helper code for output
|
|
|
+ probing, so those sections fully apply.
|
|
|
+ </para>
|
|
|
+ </sect2>
|
|
|
+ </sect1>
|
|
|
|
|
|
+ <sect1>
|
|
|
+ <title>Memory Management and Command Submission</title>
|
|
|
+ <para>
|
|
|
+ This sections covers all things related to the GEM implementation in the
|
|
|
+ i915 driver.
|
|
|
+ </para>
|
|
|
+ </sect1>
|
|
|
+ </chapter>
|
|
|
+</part>
|
|
|
</book>
|