aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2016-08-29 04:27:50 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2016-08-29 09:37:08 -0400
commite03e6de03e931bd3d93b1e2a9dc7d0bf0b505287 (patch)
tree5347b3a7fc64a3db34b469549a17311e1305b2eb
parent321a95ae35f2ec4f58c4cda28d3606cc6f2b97d1 (diff)
drm/doc: Polish kerneldoc for encoders
- Move missing bits into struct drm_encoder docs. - Explain that encoders are 95% internal and only 5% uapi, and that in general the uapi part is broken. - Remove verbose comments for functions not exposed to drivers. v2: Review from Archit: - Appease checkpatch in the moved code. - Make it clearer that bridges are not exposed to userspace. Reviewed-by: Archit Taneja <architt@codeaurora.org> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20160829082757.17913-2-daniel.vetter@ffwll.ch
-rw-r--r--Documentation/gpu/drm-kms.rst46
-rw-r--r--drivers/gpu/drm/drm_encoder.c48
-rw-r--r--include/drm/drm_encoder.h70
3 files changed, 101 insertions, 63 deletions
diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
index 7f788caebea3..47c2835b7c2d 100644
--- a/Documentation/gpu/drm-kms.rst
+++ b/Documentation/gpu/drm-kms.rst
@@ -128,6 +128,12 @@ Connector Functions Reference
128Encoder Abstraction 128Encoder Abstraction
129=================== 129===================
130 130
131.. kernel-doc:: drivers/gpu/drm/drm_encoder.c
132 :doc: overview
133
134Encoder Functions Reference
135---------------------------
136
131.. kernel-doc:: include/drm/drm_encoder.h 137.. kernel-doc:: include/drm/drm_encoder.h
132 :internal: 138 :internal:
133 139
@@ -207,46 +213,6 @@ future); drivers that do not wish to provide special handling for
207primary planes may make use of the helper functions described in ? to 213primary planes may make use of the helper functions described in ? to
208create and register a primary plane with standard capabilities. 214create and register a primary plane with standard capabilities.
209 215
210Encoders (:c:type:`struct drm_encoder <drm_encoder>`)
211-----------------------------------------------------
212
213An encoder takes pixel data from a CRTC and converts it to a format
214suitable for any attached connectors. On some devices, it may be
215possible to have a CRTC send data to more than one encoder. In that
216case, both encoders would receive data from the same scanout buffer,
217resulting in a "cloned" display configuration across the connectors
218attached to each encoder.
219
220Encoder Initialization
221~~~~~~~~~~~~~~~~~~~~~~
222
223As for CRTCs, a KMS driver must create, initialize and register at least
224one :c:type:`struct drm_encoder <drm_encoder>` instance. The
225instance is allocated and zeroed by the driver, possibly as part of a
226larger structure.
227
228Drivers must initialize the :c:type:`struct drm_encoder
229<drm_encoder>` possible_crtcs and possible_clones fields before
230registering the encoder. Both fields are bitmasks of respectively the
231CRTCs that the encoder can be connected to, and sibling encoders
232candidate for cloning.
233
234After being initialized, the encoder must be registered with a call to
235:c:func:`drm_encoder_init()`. The function takes a pointer to the
236encoder functions and an encoder type. Supported types are
237
238- DRM_MODE_ENCODER_DAC for VGA and analog on DVI-I/DVI-A
239- DRM_MODE_ENCODER_TMDS for DVI, HDMI and (embedded) DisplayPort
240- DRM_MODE_ENCODER_LVDS for display panels
241- DRM_MODE_ENCODER_TVDAC for TV output (Composite, S-Video,
242 Component, SCART)
243- DRM_MODE_ENCODER_VIRTUAL for virtual machine displays
244
245Encoders must be attached to a CRTC to be used. DRM drivers leave
246encoders unattached at initialization time. Applications (or the fbdev
247compatibility layer when implemented) are responsible for attaching the
248encoders they want to use to a CRTC.
249
250Cleanup 216Cleanup
251------- 217-------
252 218
diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
index bce781b7bb5f..998a6743a586 100644
--- a/drivers/gpu/drm/drm_encoder.c
+++ b/drivers/gpu/drm/drm_encoder.c
@@ -26,6 +26,30 @@
26 26
27#include "drm_crtc_internal.h" 27#include "drm_crtc_internal.h"
28 28
29/**
30 * DOC: overview
31 *
32 * Encoders represent the connecting element between the CRTC (as the overall
33 * pixel pipeline, represented by struct &drm_crtc) and the connectors (as the
34 * generic sink entity, represented by struct &drm_connector). Encoders are
35 * objects exposed to userspace, originally to allow userspace to infer cloning
36 * and connector/CRTC restrictions. Unfortunately almost all drivers get this
37 * wrong, making the uabi pretty much useless. On top of that the exposed
38 * restrictions are too simple for todays hardware, and the recommend way to
39 * infer restrictions is by using the DRM_MODE_ATOMIC_TEST_ONLY flag for the
40 * atomic IOCTL.
41 *
42 * Otherwise encoders aren't used in the uapi at all (any modeset request from
43 * userspace directly connects a connector with a CRTC), drivers are therefore
44 * free to use them however they wish. Modeset helper libraries make strong use
45 * of encoders to facilitate code sharing. But for more complex settings it is
46 * usually better to move shared code into a separate &drm_bridge. Compared to
47 * encoders bridges also have the benefit of not being purely an internal
48 * abstraction since they are not exposed to userspace at all.
49 *
50 * Encoders are initialized with drm_encoder_init() and cleaned up using
51 * drm_encoder_cleanup().
52 */
29static const struct drm_prop_enum_list drm_encoder_enum_list[] = { 53static const struct drm_prop_enum_list drm_encoder_enum_list[] = {
30 { DRM_MODE_ENCODER_NONE, "None" }, 54 { DRM_MODE_ENCODER_NONE, "None" },
31 { DRM_MODE_ENCODER_DAC, "DAC" }, 55 { DRM_MODE_ENCODER_DAC, "DAC" },
@@ -71,16 +95,17 @@ void drm_encoder_unregister_all(struct drm_device *dev)
71 * @encoder_type: user visible type of the encoder 95 * @encoder_type: user visible type of the encoder
72 * @name: printf style format string for the encoder name, or NULL for default name 96 * @name: printf style format string for the encoder name, or NULL for default name
73 * 97 *
74 * Initialises a preallocated encoder. Encoder should be 98 * Initialises a preallocated encoder. Encoder should be subclassed as part of
75 * subclassed as part of driver encoder objects. 99 * driver encoder objects. At driver unload time drm_encoder_cleanup() should be
100 * called from the driver's destroy hook in &drm_encoder_funcs.
76 * 101 *
77 * Returns: 102 * Returns:
78 * Zero on success, error code on failure. 103 * Zero on success, error code on failure.
79 */ 104 */
80int drm_encoder_init(struct drm_device *dev, 105int drm_encoder_init(struct drm_device *dev,
81 struct drm_encoder *encoder, 106 struct drm_encoder *encoder,
82 const struct drm_encoder_funcs *funcs, 107 const struct drm_encoder_funcs *funcs,
83 int encoder_type, const char *name, ...) 108 int encoder_type, const char *name, ...)
84{ 109{
85 int ret; 110 int ret;
86 111
@@ -176,19 +201,6 @@ static struct drm_crtc *drm_encoder_get_crtc(struct drm_encoder *encoder)
176 return encoder->crtc; 201 return encoder->crtc;
177} 202}
178 203
179/**
180 * drm_mode_getencoder - get encoder configuration
181 * @dev: drm device for the ioctl
182 * @data: data pointer for the ioctl
183 * @file_priv: drm file for the ioctl call
184 *
185 * Construct a encoder configuration structure to return to the user.
186 *
187 * Called by the user via ioctl.
188 *
189 * Returns:
190 * Zero on success, negative errno on failure.
191 */
192int drm_mode_getencoder(struct drm_device *dev, void *data, 204int drm_mode_getencoder(struct drm_device *dev, void *data,
193 struct drm_file *file_priv) 205 struct drm_file *file_priv)
194{ 206{
diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h
index 2712fd1a686b..3d7350f1fcc1 100644
--- a/include/drm/drm_encoder.h
+++ b/include/drm/drm_encoder.h
@@ -84,9 +84,6 @@ struct drm_encoder_funcs {
84 * @head: list management 84 * @head: list management
85 * @base: base KMS object 85 * @base: base KMS object
86 * @name: human readable name, can be overwritten by the driver 86 * @name: human readable name, can be overwritten by the driver
87 * @encoder_type: one of the DRM_MODE_ENCODER_<foo> types in drm_mode.h
88 * @possible_crtcs: bitmask of potential CRTC bindings
89 * @possible_clones: bitmask of potential sibling encoders for cloning
90 * @crtc: currently bound CRTC 87 * @crtc: currently bound CRTC
91 * @bridge: bridge associated to the encoder 88 * @bridge: bridge associated to the encoder
92 * @funcs: control functions 89 * @funcs: control functions
@@ -101,6 +98,32 @@ struct drm_encoder {
101 98
102 struct drm_mode_object base; 99 struct drm_mode_object base;
103 char *name; 100 char *name;
101 /**
102 * @encoder_type:
103 *
104 * One of the DRM_MODE_ENCODER_<foo> types in drm_mode.h. The following
105 * encoder types are defined thus far:
106 *
107 * - DRM_MODE_ENCODER_DAC for VGA and analog on DVI-I/DVI-A.
108 *
109 * - DRM_MODE_ENCODER_TMDS for DVI, HDMI and (embedded) DisplayPort.
110 *
111 * - DRM_MODE_ENCODER_LVDS for display panels, or in general any panel
112 * with a proprietary parallel connector.
113 *
114 * - DRM_MODE_ENCODER_TVDAC for TV output (Composite, S-Video,
115 * Component, SCART).
116 *
117 * - DRM_MODE_ENCODER_VIRTUAL for virtual machine displays
118 *
119 * - DRM_MODE_ENCODER_DSI for panels connected using the DSI serial bus.
120 *
121 * - DRM_MODE_ENCODER_DPI for panels connected using the DPI parallel
122 * bus.
123 *
124 * - DRM_MODE_ENCODER_DPMST for special fake encoders used to allow
125 * mutliple DP MST streams to share one physical encoder.
126 */
104 int encoder_type; 127 int encoder_type;
105 128
106 /** 129 /**
@@ -109,7 +132,34 @@ struct drm_encoder {
109 */ 132 */
110 unsigned index; 133 unsigned index;
111 134
135 /**
136 * @possible_crtcs: Bitmask of potential CRTC bindings, using
137 * drm_crtc_index() as the index into the bitfield. The driver must set
138 * the bits for all &drm_crtc objects this encoder can be connected to
139 * before calling drm_encoder_init().
140 *
141 * In reality almost every driver gets this wrong.
142 *
143 * Note that since CRTC objects can't be hotplugged the assigned indices
144 * are stable and hence known before registering all objects.
145 */
112 uint32_t possible_crtcs; 146 uint32_t possible_crtcs;
147
148 /**
149 * @possible_clones: Bitmask of potential sibling encoders for cloning,
150 * using drm_encoder_index() as the index into the bitfield. The driver
151 * must set the bits for all &drm_encoder objects which can clone a
152 * &drm_crtc together with this encoder before calling
153 * drm_encoder_init(). Drivers should set the bit representing the
154 * encoder itself, too. Cloning bits should be set such that when two
155 * encoders can be used in a cloned configuration, they both should have
156 * each another bits set.
157 *
158 * In reality almost every driver gets this wrong.
159 *
160 * Note that since encoder objects can't be hotplugged the assigned indices
161 * are stable and hence known before registering all objects.
162 */
113 uint32_t possible_clones; 163 uint32_t possible_clones;
114 164
115 struct drm_crtc *crtc; 165 struct drm_crtc *crtc;
@@ -146,7 +196,7 @@ static inline uint32_t drm_crtc_mask(struct drm_crtc *crtc);
146 * @encoder: encoder to test 196 * @encoder: encoder to test
147 * @crtc: crtc to test 197 * @crtc: crtc to test
148 * 198 *
149 * Return false if @encoder can't be driven by @crtc, true otherwise. 199 * Returns false if @encoder can't be driven by @crtc, true otherwise.
150 */ 200 */
151static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder, 201static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
152 struct drm_crtc *crtc) 202 struct drm_crtc *crtc)
@@ -154,11 +204,21 @@ static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
154 return !!(encoder->possible_crtcs & drm_crtc_mask(crtc)); 204 return !!(encoder->possible_crtcs & drm_crtc_mask(crtc));
155} 205}
156 206
207/**
208 * drm_encoder_find - find a &drm_encoder
209 * @dev: DRM device
210 * @id: encoder id
211 *
212 * Returns the encoder with @id, NULL if it doesn't exist. Simple wrapper around
213 * drm_mode_object_find().
214 */
157static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev, 215static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev,
158 uint32_t id) 216 uint32_t id)
159{ 217{
160 struct drm_mode_object *mo; 218 struct drm_mode_object *mo;
219
161 mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER); 220 mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
221
162 return mo ? obj_to_encoder(mo) : NULL; 222 return mo ? obj_to_encoder(mo) : NULL;
163} 223}
164 224