forked from Minki/linux
drm/doc: Add KMS overview graphs
Oh, the shiny and pretties! v2: Review from Laurent. Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Eric Anholt <eric@anholt.net> Reviewed-by: Gabriel Krisman Bertazi <krisman@collabora.co.uk> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170302151638.1882-3-daniel.vetter@ffwll.ch
This commit is contained in:
parent
b70366e5d3
commit
2564d0b043
@ -114,6 +114,8 @@ Framebuffer CMA Helper Functions Reference
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_fb_cma_helper.c
|
||||
:export:
|
||||
|
||||
.. _drm_bridges:
|
||||
|
||||
Bridges
|
||||
=======
|
||||
|
||||
@ -139,6 +141,8 @@ Bridge Helper Reference
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_bridge.c
|
||||
:export:
|
||||
|
||||
.. _drm_panel_helper:
|
||||
|
||||
Panel Helper Reference
|
||||
======================
|
||||
|
||||
|
@ -15,7 +15,139 @@ be setup by initializing the following fields.
|
||||
- struct drm_mode_config_funcs \*funcs;
|
||||
Mode setting functions.
|
||||
|
||||
Mode Configuration
|
||||
Overview
|
||||
========
|
||||
|
||||
.. kernel-render:: DOT
|
||||
:alt: KMS Display Pipeline
|
||||
:caption: KMS Display Pipeline Overview
|
||||
|
||||
digraph "KMS" {
|
||||
node [shape=box]
|
||||
|
||||
subgraph cluster_static {
|
||||
style=dashed
|
||||
label="Static Objects"
|
||||
|
||||
node [bgcolor=grey style=filled]
|
||||
"drm_plane A" -> "drm_crtc"
|
||||
"drm_plane B" -> "drm_crtc"
|
||||
"drm_crtc" -> "drm_encoder A"
|
||||
"drm_crtc" -> "drm_encoder B"
|
||||
}
|
||||
|
||||
subgraph cluster_user_created {
|
||||
style=dashed
|
||||
label="Userspace-Created"
|
||||
|
||||
node [shape=oval]
|
||||
"drm_framebuffer 1" -> "drm_plane A"
|
||||
"drm_framebuffer 2" -> "drm_plane B"
|
||||
}
|
||||
|
||||
subgraph cluster_connector {
|
||||
style=dashed
|
||||
label="Hotpluggable"
|
||||
|
||||
"drm_encoder A" -> "drm_connector A"
|
||||
"drm_encoder B" -> "drm_connector B"
|
||||
}
|
||||
}
|
||||
|
||||
The basic object structure KMS presents to userspace is fairly simple.
|
||||
Framebuffers (represented by :c:type:`struct drm_framebuffer <drm_framebuffer>`,
|
||||
see `Frame Buffer Abstraction`_) feed into planes. One or more (or even no)
|
||||
planes feed their pixel data into a CRTC (represented by :c:type:`struct
|
||||
drm_crtc <drm_crtc>`, see `CRTC Abstraction`_) for blending. The precise
|
||||
blending step is explained in more detail in `Plane Composition Properties`_ and
|
||||
related chapters.
|
||||
|
||||
For the output routing the first step is encoders (represented by
|
||||
:c:type:`struct drm_encoder <drm_encoder>`, see `Encoder Abstraction`_). Those
|
||||
are really just internal artifacts of the helper libraries used to implement KMS
|
||||
drivers. Besides that they make it unecessarily more complicated for userspace
|
||||
to figure out which connections between a CRTC and a connector are possible, and
|
||||
what kind of cloning is supported, they serve no purpose in the userspace API.
|
||||
Unfortunately encoders have been exposed to userspace, hence can't remove them
|
||||
at this point. Futhermore the exposed restrictions are often wrongly set by
|
||||
drivers, and in many cases not powerful enough to express the real restrictions.
|
||||
A CRTC can be connected to multiple encoders, and for an active CRTC there must
|
||||
be at least one encoder.
|
||||
|
||||
The final, and real, endpoint in the display chain is the connector (represented
|
||||
by :c:type:`struct drm_connector <drm_connector>`, see `Connector
|
||||
Abstraction`_). Connectors can have different possible encoders, but the kernel
|
||||
driver selects which encoder to use for each connector. The use case is DVI,
|
||||
which could switch between an analog and a digital encoder. Encoders can also
|
||||
drive multiple different connectors. There is exactly one active connector for
|
||||
every active encoder.
|
||||
|
||||
Internally the output pipeline is a bit more complex and matches today's
|
||||
hardware more closely:
|
||||
|
||||
.. kernel-render:: DOT
|
||||
:alt: KMS Output Pipeline
|
||||
:caption: KMS Output Pipeline
|
||||
|
||||
digraph "Output Pipeline" {
|
||||
node [shape=box]
|
||||
|
||||
subgraph {
|
||||
"drm_crtc" [bgcolor=grey style=filled]
|
||||
}
|
||||
|
||||
subgraph cluster_internal {
|
||||
style=dashed
|
||||
label="Internal Pipeline"
|
||||
{
|
||||
node [bgcolor=grey style=filled]
|
||||
"drm_encoder A";
|
||||
"drm_encoder B";
|
||||
"drm_encoder C";
|
||||
}
|
||||
|
||||
{
|
||||
node [bgcolor=grey style=filled]
|
||||
"drm_encoder B" -> "drm_bridge B"
|
||||
"drm_encoder C" -> "drm_bridge C1"
|
||||
"drm_bridge C1" -> "drm_bridge C2";
|
||||
}
|
||||
}
|
||||
|
||||
"drm_crtc" -> "drm_encoder A"
|
||||
"drm_crtc" -> "drm_encoder B"
|
||||
"drm_crtc" -> "drm_encoder C"
|
||||
|
||||
|
||||
subgraph cluster_output {
|
||||
style=dashed
|
||||
label="Outputs"
|
||||
|
||||
"drm_encoder A" -> "drm_connector A";
|
||||
"drm_bridge B" -> "drm_connector B";
|
||||
"drm_bridge C2" -> "drm_connector C";
|
||||
|
||||
"drm_panel"
|
||||
}
|
||||
}
|
||||
|
||||
Internally two additional helper objects come into play. First, to be able to
|
||||
share code for encoders (sometimes on the same SoC, sometimes off-chip) one or
|
||||
more :ref:`drm_bridges` (represented by :c:type:`struct drm_bridge
|
||||
<drm_bridge>`) can be linked to an encoder. This link is static and cannot be
|
||||
changed, which means the cross-bar (if there is any) needs to be mapped between
|
||||
the CRTC and any encoders. Often for drivers with bridges there's no code left
|
||||
at the encoder level. Atomic drivers can leave out all the encoder callbacks to
|
||||
essentially only leave a dummy routing object behind, which is needed for
|
||||
backwards compatibility since encoders are exposed to userspace.
|
||||
|
||||
The second object is for panels, represented by :c:type:`struct drm_panel
|
||||
<drm_panel>`, see :ref:`drm_panel_helper`. Panels do not have a fixed binding
|
||||
point, but are generally linked to the driver private structure that embeds
|
||||
:c:type:`struct drm_connector <drm_connector>`.
|
||||
|
||||
Note that currently the bridge chaining and interactions with connectors and
|
||||
panels are still in-flux and not really fully sorted out yet.
|
||||
|
||||
KMS Core Structures and Functions
|
||||
=================================
|
||||
|
Loading…
Reference in New Issue
Block a user