123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613 |
- =========================
- Kernel Mode Setting (KMS)
- =========================
- Drivers must initialize the mode setting core by calling
- drmm_mode_config_init() on the DRM device. The function
- initializes the :c:type:`struct drm_device <drm_device>`
- mode_config field and never fails. Once done, mode configuration must
- be setup by initializing the following fields.
- - int min_width, min_height; int max_width, max_height;
- Minimum and maximum width and height of the frame buffers in pixel
- units.
- - struct drm_mode_config_funcs \*funcs;
- Mode setting functions.
- 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. Planes are represented by
- :c:type:`struct drm_plane <drm_plane>`, see `Plane Abstraction`_ for more
- details. 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
- =================================
- .. kernel-doc:: include/drm/drm_mode_config.h
- :internal:
- .. kernel-doc:: drivers/gpu/drm/drm_mode_config.c
- :export:
- .. _kms_base_object_abstraction:
- Modeset Base Object Abstraction
- ===============================
- .. kernel-render:: DOT
- :alt: Mode Objects and Properties
- :caption: Mode Objects and Properties
- digraph {
- node [shape=box]
- "drm_property A" -> "drm_mode_object A"
- "drm_property A" -> "drm_mode_object B"
- "drm_property B" -> "drm_mode_object A"
- }
- The base structure for all KMS objects is :c:type:`struct drm_mode_object
- <drm_mode_object>`. One of the base services it provides is tracking properties,
- which are especially important for the atomic IOCTL (see `Atomic Mode
- Setting`_). The somewhat surprising part here is that properties are not
- directly instantiated on each object, but free-standing mode objects themselves,
- represented by :c:type:`struct drm_property <drm_property>`, which only specify
- the type and value range of a property. Any given property can be attached
- multiple times to different objects using drm_object_attach_property().
- .. kernel-doc:: include/drm/drm_mode_object.h
- :internal:
- .. kernel-doc:: drivers/gpu/drm/drm_mode_object.c
- :export:
- Atomic Mode Setting
- ===================
- .. kernel-render:: DOT
- :alt: Mode Objects and Properties
- :caption: Mode Objects and Properties
- digraph {
- node [shape=box]
- subgraph cluster_state {
- style=dashed
- label="Free-standing state"
- "drm_atomic_state" -> "duplicated drm_plane_state A"
- "drm_atomic_state" -> "duplicated drm_plane_state B"
- "drm_atomic_state" -> "duplicated drm_crtc_state"
- "drm_atomic_state" -> "duplicated drm_connector_state"
- "drm_atomic_state" -> "duplicated driver private state"
- }
- subgraph cluster_current {
- style=dashed
- label="Current state"
- "drm_device" -> "drm_plane A"
- "drm_device" -> "drm_plane B"
- "drm_device" -> "drm_crtc"
- "drm_device" -> "drm_connector"
- "drm_device" -> "driver private object"
- "drm_plane A" -> "drm_plane_state A"
- "drm_plane B" -> "drm_plane_state B"
- "drm_crtc" -> "drm_crtc_state"
- "drm_connector" -> "drm_connector_state"
- "driver private object" -> "driver private state"
- }
- "drm_atomic_state" -> "drm_device" [label="atomic_commit"]
- "duplicated drm_plane_state A" -> "drm_device"[style=invis]
- }
- Atomic provides transactional modeset (including planes) updates, but a
- bit differently from the usual transactional approach of try-commit and
- rollback:
- - Firstly, no hardware changes are allowed when the commit would fail. This
- allows us to implement the DRM_MODE_ATOMIC_TEST_ONLY mode, which allows
- userspace to explore whether certain configurations would work or not.
- - This would still allow setting and rollback of just the software state,
- simplifying conversion of existing drivers. But auditing drivers for
- correctness of the atomic_check code becomes really hard with that: Rolling
- back changes in data structures all over the place is hard to get right.
- - Lastly, for backwards compatibility and to support all use-cases, atomic
- updates need to be incremental and be able to execute in parallel. Hardware
- doesn't always allow it, but where possible plane updates on different CRTCs
- should not interfere, and not get stalled due to output routing changing on
- different CRTCs.
- Taken all together there's two consequences for the atomic design:
- - The overall state is split up into per-object state structures:
- :c:type:`struct drm_plane_state <drm_plane_state>` for planes, :c:type:`struct
- drm_crtc_state <drm_crtc_state>` for CRTCs and :c:type:`struct
- drm_connector_state <drm_connector_state>` for connectors. These are the only
- objects with userspace-visible and settable state. For internal state drivers
- can subclass these structures through embeddeding, or add entirely new state
- structures for their globally shared hardware functions, see :c:type:`struct
- drm_private_state<drm_private_state>`.
- - An atomic update is assembled and validated as an entirely free-standing pile
- of structures within the :c:type:`drm_atomic_state <drm_atomic_state>`
- container. Driver private state structures are also tracked in the same
- structure; see the next chapter. Only when a state is committed is it applied
- to the driver and modeset objects. This way rolling back an update boils down
- to releasing memory and unreferencing objects like framebuffers.
- Locking of atomic state structures is internally using :c:type:`struct
- drm_modeset_lock <drm_modeset_lock>`. As a general rule the locking shouldn't be
- exposed to drivers, instead the right locks should be automatically acquired by
- any function that duplicates or peeks into a state, like e.g.
- drm_atomic_get_crtc_state(). Locking only protects the software data
- structure, ordering of committing state changes to hardware is sequenced using
- :c:type:`struct drm_crtc_commit <drm_crtc_commit>`.
- Read on in this chapter, and also in :ref:`drm_atomic_helper` for more detailed
- coverage of specific topics.
- Handling Driver Private State
- -----------------------------
- .. kernel-doc:: drivers/gpu/drm/drm_atomic.c
- :doc: handling driver private state
- Atomic Mode Setting Function Reference
- --------------------------------------
- .. kernel-doc:: include/drm/drm_atomic.h
- :internal:
- .. kernel-doc:: drivers/gpu/drm/drm_atomic.c
- :export:
- Atomic Mode Setting IOCTL and UAPI Functions
- --------------------------------------------
- .. kernel-doc:: drivers/gpu/drm/drm_atomic_uapi.c
- :doc: overview
- .. kernel-doc:: drivers/gpu/drm/drm_atomic_uapi.c
- :export:
- CRTC Abstraction
- ================
- .. kernel-doc:: drivers/gpu/drm/drm_crtc.c
- :doc: overview
- CRTC Functions Reference
- --------------------------------
- .. kernel-doc:: include/drm/drm_crtc.h
- :internal:
- .. kernel-doc:: drivers/gpu/drm/drm_crtc.c
- :export:
- Color Management Functions Reference
- ------------------------------------
- .. kernel-doc:: drivers/gpu/drm/drm_color_mgmt.c
- :export:
- .. kernel-doc:: include/drm/drm_color_mgmt.h
- :internal:
- Frame Buffer Abstraction
- ========================
- .. kernel-doc:: drivers/gpu/drm/drm_framebuffer.c
- :doc: overview
- Frame Buffer Functions Reference
- --------------------------------
- .. kernel-doc:: include/drm/drm_framebuffer.h
- :internal:
- .. kernel-doc:: drivers/gpu/drm/drm_framebuffer.c
- :export:
- DRM Format Handling
- ===================
- .. kernel-doc:: include/uapi/drm/drm_fourcc.h
- :doc: overview
- Format Functions Reference
- --------------------------
- .. kernel-doc:: include/drm/drm_fourcc.h
- :internal:
- .. kernel-doc:: drivers/gpu/drm/drm_fourcc.c
- :export:
- Dumb Buffer Objects
- ===================
- .. kernel-doc:: drivers/gpu/drm/drm_dumb_buffers.c
- :doc: overview
- Plane Abstraction
- =================
- .. kernel-doc:: drivers/gpu/drm/drm_plane.c
- :doc: overview
- Plane Functions Reference
- -------------------------
- .. kernel-doc:: include/drm/drm_plane.h
- :internal:
- .. kernel-doc:: drivers/gpu/drm/drm_plane.c
- :export:
- Plane Composition Functions Reference
- -------------------------------------
- .. kernel-doc:: drivers/gpu/drm/drm_blend.c
- :export:
- Plane Damage Tracking Functions Reference
- -----------------------------------------
- .. kernel-doc:: drivers/gpu/drm/drm_damage_helper.c
- :export:
- .. kernel-doc:: include/drm/drm_damage_helper.h
- :internal:
- Display Modes Function Reference
- ================================
- .. kernel-doc:: include/drm/drm_modes.h
- :internal:
- .. kernel-doc:: drivers/gpu/drm/drm_modes.c
- :export:
- Connector Abstraction
- =====================
- .. kernel-doc:: drivers/gpu/drm/drm_connector.c
- :doc: overview
- Connector Functions Reference
- -----------------------------
- .. kernel-doc:: include/drm/drm_connector.h
- :internal:
- .. kernel-doc:: drivers/gpu/drm/drm_connector.c
- :export:
- Writeback Connectors
- --------------------
- .. kernel-doc:: drivers/gpu/drm/drm_writeback.c
- :doc: overview
- .. kernel-doc:: include/drm/drm_writeback.h
- :internal:
- .. kernel-doc:: drivers/gpu/drm/drm_writeback.c
- :export:
- Encoder Abstraction
- ===================
- .. kernel-doc:: drivers/gpu/drm/drm_encoder.c
- :doc: overview
- Encoder Functions Reference
- ---------------------------
- .. kernel-doc:: include/drm/drm_encoder.h
- :internal:
- .. kernel-doc:: drivers/gpu/drm/drm_encoder.c
- :export:
- KMS Locking
- ===========
- .. kernel-doc:: drivers/gpu/drm/drm_modeset_lock.c
- :doc: kms locking
- .. kernel-doc:: include/drm/drm_modeset_lock.h
- :internal:
- .. kernel-doc:: drivers/gpu/drm/drm_modeset_lock.c
- :export:
- KMS Properties
- ==============
- This section of the documentation is primarily aimed at user-space developers.
- For the driver APIs, see the other sections.
- Requirements
- ------------
- KMS drivers might need to add extra properties to support new features. Each
- new property introduced in a driver needs to meet a few requirements, in
- addition to the one mentioned above:
- * It must be standardized, documenting:
- * The full, exact, name string;
- * If the property is an enum, all the valid value name strings;
- * What values are accepted, and what these values mean;
- * What the property does and how it can be used;
- * How the property might interact with other, existing properties.
- * It must provide a generic helper in the core code to register that
- property on the object it attaches to.
- * Its content must be decoded by the core and provided in the object's
- associated state structure. That includes anything drivers might want
- to precompute, like struct drm_clip_rect for planes.
- * Its initial state must match the behavior prior to the property
- introduction. This might be a fixed value matching what the hardware
- does, or it may be inherited from the state the firmware left the
- system in during boot.
- * An IGT test must be submitted where reasonable.
- Property Types and Blob Property Support
- ----------------------------------------
- .. kernel-doc:: drivers/gpu/drm/drm_property.c
- :doc: overview
- .. kernel-doc:: include/drm/drm_property.h
- :internal:
- .. kernel-doc:: drivers/gpu/drm/drm_property.c
- :export:
- .. _standard_connector_properties:
- Standard Connector Properties
- -----------------------------
- .. kernel-doc:: drivers/gpu/drm/drm_connector.c
- :doc: standard connector properties
- HDMI Specific Connector Properties
- ----------------------------------
- .. kernel-doc:: drivers/gpu/drm/drm_connector.c
- :doc: HDMI connector properties
- Standard CRTC Properties
- ------------------------
- .. kernel-doc:: drivers/gpu/drm/drm_crtc.c
- :doc: standard CRTC properties
- Standard Plane Properties
- -------------------------
- .. kernel-doc:: drivers/gpu/drm/drm_plane.c
- :doc: standard plane properties
- .. _plane_composition_properties:
- Plane Composition Properties
- ----------------------------
- .. kernel-doc:: drivers/gpu/drm/drm_blend.c
- :doc: overview
- Damage Tracking Properties
- --------------------------
- .. kernel-doc:: drivers/gpu/drm/drm_plane.c
- :doc: damage tracking
- Color Management Properties
- ---------------------------
- .. kernel-doc:: drivers/gpu/drm/drm_color_mgmt.c
- :doc: overview
- Tile Group Property
- -------------------
- .. kernel-doc:: drivers/gpu/drm/drm_connector.c
- :doc: Tile group
- Explicit Fencing Properties
- ---------------------------
- .. kernel-doc:: drivers/gpu/drm/drm_atomic_uapi.c
- :doc: explicit fencing properties
- Variable Refresh Properties
- ---------------------------
- .. kernel-doc:: drivers/gpu/drm/drm_connector.c
- :doc: Variable refresh properties
- Existing KMS Properties
- -----------------------
- The following table gives description of drm properties exposed by various
- modules/drivers. Because this table is very unwieldy, do not add any new
- properties here. Instead document them in a section above.
- .. csv-table::
- :header-rows: 1
- :file: kms-properties.csv
- Vertical Blanking
- =================
- .. kernel-doc:: drivers/gpu/drm/drm_vblank.c
- :doc: vblank handling
- Vertical Blanking and Interrupt Handling Functions Reference
- ------------------------------------------------------------
- .. kernel-doc:: include/drm/drm_vblank.h
- :internal:
- .. kernel-doc:: drivers/gpu/drm/drm_vblank.c
- :export:
- Vertical Blank Work
- ===================
- .. kernel-doc:: drivers/gpu/drm/drm_vblank_work.c
- :doc: vblank works
- Vertical Blank Work Functions Reference
- ---------------------------------------
- .. kernel-doc:: include/drm/drm_vblank_work.h
- :internal:
- .. kernel-doc:: drivers/gpu/drm/drm_vblank_work.c
- :export:
|