]>
Commit | Line | Data |
---|---|---|
2fa91d15 JN |
1 | ========================= |
2 | Kernel Mode Setting (KMS) | |
3 | ========================= | |
4 | ||
2fa91d15 JN |
5 | Drivers must initialize the mode setting core by calling |
6 | :c:func:`drm_mode_config_init()` on the DRM device. The function | |
7 | initializes the :c:type:`struct drm_device <drm_device>` | |
8 | mode_config field and never fails. Once done, mode configuration must | |
9 | be setup by initializing the following fields. | |
10 | ||
11 | - int min_width, min_height; int max_width, max_height; | |
12 | Minimum and maximum width and height of the frame buffers in pixel | |
13 | units. | |
14 | ||
15 | - struct drm_mode_config_funcs \*funcs; | |
16 | Mode setting functions. | |
17 | ||
2564d0b0 DV |
18 | Overview |
19 | ======== | |
20 | ||
21 | .. kernel-render:: DOT | |
22 | :alt: KMS Display Pipeline | |
23 | :caption: KMS Display Pipeline Overview | |
24 | ||
25 | digraph "KMS" { | |
26 | node [shape=box] | |
27 | ||
28 | subgraph cluster_static { | |
29 | style=dashed | |
30 | label="Static Objects" | |
31 | ||
32 | node [bgcolor=grey style=filled] | |
33 | "drm_plane A" -> "drm_crtc" | |
34 | "drm_plane B" -> "drm_crtc" | |
35 | "drm_crtc" -> "drm_encoder A" | |
36 | "drm_crtc" -> "drm_encoder B" | |
37 | } | |
38 | ||
39 | subgraph cluster_user_created { | |
40 | style=dashed | |
41 | label="Userspace-Created" | |
42 | ||
43 | node [shape=oval] | |
44 | "drm_framebuffer 1" -> "drm_plane A" | |
45 | "drm_framebuffer 2" -> "drm_plane B" | |
46 | } | |
47 | ||
48 | subgraph cluster_connector { | |
49 | style=dashed | |
50 | label="Hotpluggable" | |
51 | ||
52 | "drm_encoder A" -> "drm_connector A" | |
53 | "drm_encoder B" -> "drm_connector B" | |
54 | } | |
55 | } | |
56 | ||
57 | The basic object structure KMS presents to userspace is fairly simple. | |
58 | Framebuffers (represented by :c:type:`struct drm_framebuffer <drm_framebuffer>`, | |
268bc24e DV |
59 | see `Frame Buffer Abstraction`_) feed into planes. Planes are represented by |
60 | :c:type:`struct drm_plane <drm_plane>`, see `Plane Abstraction`_ for more | |
61 | details. One or more (or even no) planes feed their pixel data into a CRTC | |
62 | (represented by :c:type:`struct drm_crtc <drm_crtc>`, see `CRTC Abstraction`_) | |
63 | for blending. The precise blending step is explained in more detail in `Plane | |
64 | Composition Properties`_ and related chapters. | |
2564d0b0 DV |
65 | |
66 | For the output routing the first step is encoders (represented by | |
67 | :c:type:`struct drm_encoder <drm_encoder>`, see `Encoder Abstraction`_). Those | |
68 | are really just internal artifacts of the helper libraries used to implement KMS | |
69 | drivers. Besides that they make it unecessarily more complicated for userspace | |
70 | to figure out which connections between a CRTC and a connector are possible, and | |
71 | what kind of cloning is supported, they serve no purpose in the userspace API. | |
72 | Unfortunately encoders have been exposed to userspace, hence can't remove them | |
73 | at this point. Futhermore the exposed restrictions are often wrongly set by | |
74 | drivers, and in many cases not powerful enough to express the real restrictions. | |
75 | A CRTC can be connected to multiple encoders, and for an active CRTC there must | |
76 | be at least one encoder. | |
77 | ||
78 | The final, and real, endpoint in the display chain is the connector (represented | |
79 | by :c:type:`struct drm_connector <drm_connector>`, see `Connector | |
80 | Abstraction`_). Connectors can have different possible encoders, but the kernel | |
81 | driver selects which encoder to use for each connector. The use case is DVI, | |
82 | which could switch between an analog and a digital encoder. Encoders can also | |
83 | drive multiple different connectors. There is exactly one active connector for | |
84 | every active encoder. | |
85 | ||
86 | Internally the output pipeline is a bit more complex and matches today's | |
87 | hardware more closely: | |
88 | ||
89 | .. kernel-render:: DOT | |
90 | :alt: KMS Output Pipeline | |
91 | :caption: KMS Output Pipeline | |
92 | ||
93 | digraph "Output Pipeline" { | |
94 | node [shape=box] | |
95 | ||
96 | subgraph { | |
97 | "drm_crtc" [bgcolor=grey style=filled] | |
98 | } | |
99 | ||
100 | subgraph cluster_internal { | |
101 | style=dashed | |
102 | label="Internal Pipeline" | |
103 | { | |
104 | node [bgcolor=grey style=filled] | |
105 | "drm_encoder A"; | |
106 | "drm_encoder B"; | |
107 | "drm_encoder C"; | |
108 | } | |
109 | ||
110 | { | |
111 | node [bgcolor=grey style=filled] | |
112 | "drm_encoder B" -> "drm_bridge B" | |
113 | "drm_encoder C" -> "drm_bridge C1" | |
114 | "drm_bridge C1" -> "drm_bridge C2"; | |
115 | } | |
116 | } | |
117 | ||
118 | "drm_crtc" -> "drm_encoder A" | |
119 | "drm_crtc" -> "drm_encoder B" | |
120 | "drm_crtc" -> "drm_encoder C" | |
121 | ||
122 | ||
123 | subgraph cluster_output { | |
124 | style=dashed | |
125 | label="Outputs" | |
126 | ||
127 | "drm_encoder A" -> "drm_connector A"; | |
128 | "drm_bridge B" -> "drm_connector B"; | |
129 | "drm_bridge C2" -> "drm_connector C"; | |
130 | ||
131 | "drm_panel" | |
132 | } | |
133 | } | |
134 | ||
135 | Internally two additional helper objects come into play. First, to be able to | |
136 | share code for encoders (sometimes on the same SoC, sometimes off-chip) one or | |
137 | more :ref:`drm_bridges` (represented by :c:type:`struct drm_bridge | |
138 | <drm_bridge>`) can be linked to an encoder. This link is static and cannot be | |
139 | changed, which means the cross-bar (if there is any) needs to be mapped between | |
140 | the CRTC and any encoders. Often for drivers with bridges there's no code left | |
141 | at the encoder level. Atomic drivers can leave out all the encoder callbacks to | |
142 | essentially only leave a dummy routing object behind, which is needed for | |
143 | backwards compatibility since encoders are exposed to userspace. | |
144 | ||
145 | The second object is for panels, represented by :c:type:`struct drm_panel | |
146 | <drm_panel>`, see :ref:`drm_panel_helper`. Panels do not have a fixed binding | |
147 | point, but are generally linked to the driver private structure that embeds | |
148 | :c:type:`struct drm_connector <drm_connector>`. | |
149 | ||
150 | Note that currently the bridge chaining and interactions with connectors and | |
151 | panels are still in-flux and not really fully sorted out yet. | |
949619f3 | 152 | |
28575f16 DV |
153 | KMS Core Structures and Functions |
154 | ================================= | |
949619f3 | 155 | |
28575f16 | 156 | .. kernel-doc:: include/drm/drm_mode_config.h |
2fa91d15 JN |
157 | :internal: |
158 | ||
1ea35768 DV |
159 | .. kernel-doc:: drivers/gpu/drm/drm_mode_config.c |
160 | :export: | |
161 | ||
28575f16 DV |
162 | Modeset Base Object Abstraction |
163 | =============================== | |
311b62d9 | 164 | |
b2b82c26 DV |
165 | .. kernel-render:: DOT |
166 | :alt: Mode Objects and Properties | |
167 | :caption: Mode Objects and Properties | |
168 | ||
169 | digraph { | |
170 | node [shape=box] | |
171 | ||
172 | "drm_property A" -> "drm_mode_object A" | |
173 | "drm_property A" -> "drm_mode_object B" | |
174 | "drm_property B" -> "drm_mode_object A" | |
175 | } | |
176 | ||
177 | The base structure for all KMS objects is :c:type:`struct drm_mode_object | |
178 | <drm_mode_object>`. One of the base services it provides is tracking properties, | |
179 | which are especially important for the atomic IOCTL (see `Atomic Mode | |
180 | Setting`_). The somewhat surprising part here is that properties are not | |
181 | directly instantiated on each object, but free-standing mode objects themselves, | |
182 | represented by :c:type:`struct drm_property <drm_property>`, which only specify | |
183 | the type and value range of a property. Any given property can be attached | |
184 | multiple times to different objects using :c:func:`drm_object_attach_property() | |
185 | <drm_object_attach_property>`. | |
186 | ||
28575f16 DV |
187 | .. kernel-doc:: include/drm/drm_mode_object.h |
188 | :internal: | |
189 | ||
190 | .. kernel-doc:: drivers/gpu/drm/drm_mode_object.c | |
2fa91d15 JN |
191 | :export: |
192 | ||
4a8e2292 DV |
193 | Atomic Mode Setting |
194 | =================== | |
195 | ||
196 | ||
197 | .. kernel-render:: DOT | |
198 | :alt: Mode Objects and Properties | |
199 | :caption: Mode Objects and Properties | |
200 | ||
201 | digraph { | |
202 | node [shape=box] | |
203 | ||
204 | subgraph cluster_state { | |
205 | style=dashed | |
206 | label="Free-standing state" | |
207 | ||
208 | "drm_atomic_state" -> "duplicated drm_plane_state A" | |
209 | "drm_atomic_state" -> "duplicated drm_plane_state B" | |
210 | "drm_atomic_state" -> "duplicated drm_crtc_state" | |
211 | "drm_atomic_state" -> "duplicated drm_connector_state" | |
212 | "drm_atomic_state" -> "duplicated driver private state" | |
213 | } | |
214 | ||
215 | subgraph cluster_current { | |
216 | style=dashed | |
217 | label="Current state" | |
218 | ||
219 | "drm_device" -> "drm_plane A" | |
220 | "drm_device" -> "drm_plane B" | |
221 | "drm_device" -> "drm_crtc" | |
222 | "drm_device" -> "drm_connector" | |
223 | "drm_device" -> "driver private object" | |
224 | ||
225 | "drm_plane A" -> "drm_plane_state A" | |
226 | "drm_plane B" -> "drm_plane_state B" | |
227 | "drm_crtc" -> "drm_crtc_state" | |
228 | "drm_connector" -> "drm_connector_state" | |
229 | "driver private object" -> "driver private state" | |
230 | } | |
231 | ||
232 | "drm_atomic_state" -> "drm_device" [label="atomic_commit"] | |
233 | "duplicated drm_plane_state A" -> "drm_device"[style=invis] | |
234 | } | |
235 | ||
236 | Atomic provides transactional modeset (including planes) updates, but a | |
237 | bit differently from the usual transactional approach of try-commit and | |
238 | rollback: | |
239 | ||
240 | - Firstly, no hardware changes are allowed when the commit would fail. This | |
241 | allows us to implement the DRM_MODE_ATOMIC_TEST_ONLY mode, which allows | |
242 | userspace to explore whether certain configurations would work or not. | |
243 | ||
244 | - This would still allow setting and rollback of just the software state, | |
245 | simplifying conversion of existing drivers. But auditing drivers for | |
246 | correctness of the atomic_check code becomes really hard with that: Rolling | |
247 | back changes in data structures all over the place is hard to get right. | |
248 | ||
249 | - Lastly, for backwards compatibility and to support all use-cases, atomic | |
250 | updates need to be incremental and be able to execute in parallel. Hardware | |
251 | doesn't always allow it, but where possible plane updates on different CRTCs | |
252 | should not interfere, and not get stalled due to output routing changing on | |
253 | different CRTCs. | |
254 | ||
255 | Taken all together there's two consequences for the atomic design: | |
256 | ||
257 | - The overall state is split up into per-object state structures: | |
258 | :c:type:`struct drm_plane_state <drm_plane_state>` for planes, :c:type:`struct | |
259 | drm_crtc_state <drm_crtc_state>` for CRTCs and :c:type:`struct | |
260 | drm_connector_state <drm_connector_state>` for connectors. These are the only | |
261 | objects with userspace-visible and settable state. For internal state drivers | |
262 | can subclass these structures through embeddeding, or add entirely new state | |
263 | structures for their globally shared hardware functions. | |
264 | ||
265 | - An atomic update is assembled and validated as an entirely free-standing pile | |
266 | of structures within the :c:type:`drm_atomic_state <drm_atomic_state>` | |
5fca5ece DV |
267 | container. Driver private state structures are also tracked in the same |
268 | structure; see the next chapter. Only when a state is committed is it applied | |
269 | to the driver and modeset objects. This way rolling back an update boils down | |
270 | to releasing memory and unreferencing objects like framebuffers. | |
4a8e2292 DV |
271 | |
272 | Read on in this chapter, and also in :ref:`drm_atomic_helper` for more detailed | |
273 | coverage of specific topics. | |
274 | ||
da6c0596 DV |
275 | Handling Driver Private State |
276 | ----------------------------- | |
277 | ||
278 | .. kernel-doc:: drivers/gpu/drm/drm_atomic.c | |
279 | :doc: handling driver private state | |
280 | ||
2fa91d15 | 281 | Atomic Mode Setting Function Reference |
4a8e2292 | 282 | -------------------------------------- |
2fa91d15 | 283 | |
5d070be6 | 284 | .. kernel-doc:: include/drm/drm_atomic.h |
2fa91d15 JN |
285 | :internal: |
286 | ||
1ea35768 DV |
287 | .. kernel-doc:: drivers/gpu/drm/drm_atomic.c |
288 | :export: | |
289 | ||
72fdb40c DV |
290 | Atomic Mode Setting IOCTL and UAPI Functions |
291 | -------------------------------------------- | |
292 | ||
293 | .. kernel-doc:: drivers/gpu/drm/drm_atomic_uapi.c | |
294 | :doc: overview | |
295 | ||
296 | .. kernel-doc:: drivers/gpu/drm/drm_atomic_uapi.c | |
297 | :export: | |
298 | ||
28575f16 DV |
299 | CRTC Abstraction |
300 | ================ | |
301 | ||
302 | .. kernel-doc:: drivers/gpu/drm/drm_crtc.c | |
d5d487eb DV |
303 | :doc: overview |
304 | ||
305 | CRTC Functions Reference | |
306 | -------------------------------- | |
28575f16 DV |
307 | |
308 | .. kernel-doc:: include/drm/drm_crtc.h | |
309 | :internal: | |
310 | ||
d5d487eb DV |
311 | .. kernel-doc:: drivers/gpu/drm/drm_crtc.c |
312 | :export: | |
313 | ||
2fa91d15 | 314 | Frame Buffer Abstraction |
311b62d9 | 315 | ======================== |
2fa91d15 | 316 | |
750fb8c4 DV |
317 | .. kernel-doc:: drivers/gpu/drm/drm_framebuffer.c |
318 | :doc: overview | |
2fa91d15 | 319 | |
7520a277 DV |
320 | Frame Buffer Functions Reference |
321 | -------------------------------- | |
322 | ||
7520a277 DV |
323 | .. kernel-doc:: include/drm/drm_framebuffer.h |
324 | :internal: | |
325 | ||
1ea35768 DV |
326 | .. kernel-doc:: drivers/gpu/drm/drm_framebuffer.c |
327 | :export: | |
328 | ||
2fa91d15 | 329 | DRM Format Handling |
311b62d9 | 330 | =================== |
2fa91d15 | 331 | |
7e7b68ef BS |
332 | .. kernel-doc:: include/uapi/drm/drm_fourcc.h |
333 | :doc: overview | |
334 | ||
335 | Format Functions Reference | |
336 | -------------------------- | |
337 | ||
84770cc2 LP |
338 | .. kernel-doc:: include/drm/drm_fourcc.h |
339 | :internal: | |
340 | ||
2fa91d15 JN |
341 | .. kernel-doc:: drivers/gpu/drm/drm_fourcc.c |
342 | :export: | |
343 | ||
344 | Dumb Buffer Objects | |
311b62d9 | 345 | =================== |
2fa91d15 | 346 | |
4f93624e DV |
347 | .. kernel-doc:: drivers/gpu/drm/drm_dumb_buffers.c |
348 | :doc: overview | |
2fa91d15 | 349 | |
43968d7b DV |
350 | Plane Abstraction |
351 | ================= | |
352 | ||
532b3671 DV |
353 | .. kernel-doc:: drivers/gpu/drm/drm_plane.c |
354 | :doc: overview | |
355 | ||
43968d7b DV |
356 | Plane Functions Reference |
357 | ------------------------- | |
358 | ||
359 | .. kernel-doc:: include/drm/drm_plane.h | |
360 | :internal: | |
361 | ||
362 | .. kernel-doc:: drivers/gpu/drm/drm_plane.c | |
363 | :export: | |
364 | ||
311b62d9 DV |
365 | Display Modes Function Reference |
366 | ================================ | |
2fa91d15 | 367 | |
311b62d9 DV |
368 | .. kernel-doc:: include/drm/drm_modes.h |
369 | :internal: | |
370 | ||
371 | .. kernel-doc:: drivers/gpu/drm/drm_modes.c | |
372 | :export: | |
2fa91d15 | 373 | |
ae2a6da8 DV |
374 | Connector Abstraction |
375 | ===================== | |
376 | ||
377 | .. kernel-doc:: drivers/gpu/drm/drm_connector.c | |
378 | :doc: overview | |
379 | ||
380 | Connector Functions Reference | |
381 | ----------------------------- | |
52217195 DV |
382 | |
383 | .. kernel-doc:: include/drm/drm_connector.h | |
384 | :internal: | |
385 | ||
386 | .. kernel-doc:: drivers/gpu/drm/drm_connector.c | |
387 | :export: | |
388 | ||
935774cd BS |
389 | Writeback Connectors |
390 | -------------------- | |
391 | ||
392 | .. kernel-doc:: drivers/gpu/drm/drm_writeback.c | |
393 | :doc: overview | |
394 | ||
395 | .. kernel-doc:: drivers/gpu/drm/drm_writeback.c | |
396 | :export: | |
397 | ||
321a95ae DV |
398 | Encoder Abstraction |
399 | =================== | |
400 | ||
e03e6de0 DV |
401 | .. kernel-doc:: drivers/gpu/drm/drm_encoder.c |
402 | :doc: overview | |
403 | ||
404 | Encoder Functions Reference | |
405 | --------------------------- | |
406 | ||
321a95ae DV |
407 | .. kernel-doc:: include/drm/drm_encoder.h |
408 | :internal: | |
409 | ||
410 | .. kernel-doc:: drivers/gpu/drm/drm_encoder.c | |
411 | :export: | |
412 | ||
2fa91d15 | 413 | KMS Locking |
311b62d9 | 414 | =========== |
2fa91d15 JN |
415 | |
416 | .. kernel-doc:: drivers/gpu/drm/drm_modeset_lock.c | |
417 | :doc: kms locking | |
418 | ||
419 | .. kernel-doc:: include/drm/drm_modeset_lock.h | |
420 | :internal: | |
421 | ||
422 | .. kernel-doc:: drivers/gpu/drm/drm_modeset_lock.c | |
423 | :export: | |
424 | ||
425 | KMS Properties | |
426 | ============== | |
427 | ||
59e71ee7 DV |
428 | Property Types and Blob Property Support |
429 | ---------------------------------------- | |
430 | ||
c8458c7e DV |
431 | .. kernel-doc:: drivers/gpu/drm/drm_property.c |
432 | :doc: overview | |
433 | ||
59e71ee7 DV |
434 | .. kernel-doc:: include/drm/drm_property.h |
435 | :internal: | |
436 | ||
437 | .. kernel-doc:: drivers/gpu/drm/drm_property.c | |
438 | :export: | |
439 | ||
4ada6f22 DV |
440 | Standard Connector Properties |
441 | ----------------------------- | |
442 | ||
443 | .. kernel-doc:: drivers/gpu/drm/drm_connector.c | |
444 | :doc: standard connector properties | |
445 | ||
50525c33 | 446 | HDMI Specific Connector Properties |
ba609631 | 447 | ---------------------------------- |
50525c33 SL |
448 | |
449 | .. kernel-doc:: drivers/gpu/drm/drm_connector.c | |
450 | :doc: HDMI connector properties | |
451 | ||
1e4d84c6 DV |
452 | Plane Composition Properties |
453 | ---------------------------- | |
454 | ||
455 | .. kernel-doc:: drivers/gpu/drm/drm_blend.c | |
456 | :doc: overview | |
52a9fcda DV |
457 | |
458 | .. kernel-doc:: drivers/gpu/drm/drm_blend.c | |
459 | :export: | |
460 | ||
d3b21767 LS |
461 | FB_DAMAGE_CLIPS |
462 | ~~~~~~~~~~~~~~~ | |
463 | ||
464 | .. kernel-doc:: drivers/gpu/drm/drm_damage_helper.c | |
465 | :doc: overview | |
466 | ||
467 | .. kernel-doc:: drivers/gpu/drm/drm_damage_helper.c | |
468 | :export: | |
469 | ||
470 | .. kernel-doc:: include/drm/drm_damage_helper.h | |
471 | :internal: | |
472 | ||
a6acccf8 DV |
473 | Color Management Properties |
474 | --------------------------- | |
475 | ||
476 | .. kernel-doc:: drivers/gpu/drm/drm_color_mgmt.c | |
477 | :doc: overview | |
478 | ||
a6acccf8 DV |
479 | .. kernel-doc:: drivers/gpu/drm/drm_color_mgmt.c |
480 | :export: | |
481 | ||
9498c19b DV |
482 | Tile Group Property |
483 | ------------------- | |
484 | ||
485 | .. kernel-doc:: drivers/gpu/drm/drm_connector.c | |
486 | :doc: Tile group | |
487 | ||
9a83a71a GP |
488 | Explicit Fencing Properties |
489 | --------------------------- | |
490 | ||
72fdb40c | 491 | .. kernel-doc:: drivers/gpu/drm/drm_atomic_uapi.c |
9a83a71a GP |
492 | :doc: explicit fencing properties |
493 | ||
ab7a664f NK |
494 | |
495 | Variable Refresh Properties | |
496 | --------------------------- | |
497 | ||
498 | .. kernel-doc:: drivers/gpu/drm/drm_connector.c | |
499 | :doc: Variable refresh properties | |
500 | ||
2fa91d15 JN |
501 | Existing KMS Properties |
502 | ----------------------- | |
503 | ||
3f0df756 DV |
504 | The following table gives description of drm properties exposed by various |
505 | modules/drivers. Because this table is very unwieldy, do not add any new | |
506 | properties here. Instead document them in a section above. | |
2fa91d15 JN |
507 | |
508 | .. csv-table:: | |
509 | :header-rows: 1 | |
510 | :file: kms-properties.csv | |
511 | ||
512 | Vertical Blanking | |
513 | ================= | |
514 | ||
57d30230 DV |
515 | .. kernel-doc:: drivers/gpu/drm/drm_vblank.c |
516 | :doc: vblank handling | |
2fa91d15 JN |
517 | |
518 | Vertical Blanking and Interrupt Handling Functions Reference | |
519 | ------------------------------------------------------------ | |
520 | ||
3ed4351a | 521 | .. kernel-doc:: include/drm/drm_vblank.h |
34a67dd7 | 522 | :internal: |
1ea35768 | 523 | |
3ed4351a | 524 | .. kernel-doc:: drivers/gpu/drm/drm_vblank.c |
1ea35768 | 525 | :export: |