diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-08-29 04:27:50 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-08-29 09:37:08 -0400 |
commit | e03e6de03e931bd3d93b1e2a9dc7d0bf0b505287 (patch) | |
tree | 5347b3a7fc64a3db34b469549a17311e1305b2eb | |
parent | 321a95ae35f2ec4f58c4cda28d3606cc6f2b97d1 (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.rst | 46 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_encoder.c | 48 | ||||
-rw-r--r-- | include/drm/drm_encoder.h | 70 |
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 | |||
128 | Encoder Abstraction | 128 | Encoder Abstraction |
129 | =================== | 129 | =================== |
130 | 130 | ||
131 | .. kernel-doc:: drivers/gpu/drm/drm_encoder.c | ||
132 | :doc: overview | ||
133 | |||
134 | Encoder 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 | |||
207 | primary planes may make use of the helper functions described in ? to | 213 | primary planes may make use of the helper functions described in ? to |
208 | create and register a primary plane with standard capabilities. | 214 | create and register a primary plane with standard capabilities. |
209 | 215 | ||
210 | Encoders (:c:type:`struct drm_encoder <drm_encoder>`) | ||
211 | ----------------------------------------------------- | ||
212 | |||
213 | An encoder takes pixel data from a CRTC and converts it to a format | ||
214 | suitable for any attached connectors. On some devices, it may be | ||
215 | possible to have a CRTC send data to more than one encoder. In that | ||
216 | case, both encoders would receive data from the same scanout buffer, | ||
217 | resulting in a "cloned" display configuration across the connectors | ||
218 | attached to each encoder. | ||
219 | |||
220 | Encoder Initialization | ||
221 | ~~~~~~~~~~~~~~~~~~~~~~ | ||
222 | |||
223 | As for CRTCs, a KMS driver must create, initialize and register at least | ||
224 | one :c:type:`struct drm_encoder <drm_encoder>` instance. The | ||
225 | instance is allocated and zeroed by the driver, possibly as part of a | ||
226 | larger structure. | ||
227 | |||
228 | Drivers must initialize the :c:type:`struct drm_encoder | ||
229 | <drm_encoder>` possible_crtcs and possible_clones fields before | ||
230 | registering the encoder. Both fields are bitmasks of respectively the | ||
231 | CRTCs that the encoder can be connected to, and sibling encoders | ||
232 | candidate for cloning. | ||
233 | |||
234 | After being initialized, the encoder must be registered with a call to | ||
235 | :c:func:`drm_encoder_init()`. The function takes a pointer to the | ||
236 | encoder 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 | |||
245 | Encoders must be attached to a CRTC to be used. DRM drivers leave | ||
246 | encoders unattached at initialization time. Applications (or the fbdev | ||
247 | compatibility layer when implemented) are responsible for attaching the | ||
248 | encoders they want to use to a CRTC. | ||
249 | |||
250 | Cleanup | 216 | Cleanup |
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 | */ | ||
29 | static const struct drm_prop_enum_list drm_encoder_enum_list[] = { | 53 | static 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 | */ |
80 | int drm_encoder_init(struct drm_device *dev, | 105 | int 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 | */ | ||
192 | int drm_mode_getencoder(struct drm_device *dev, void *data, | 204 | int 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 | */ |
151 | static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder, | 201 | static 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 | */ | ||
157 | static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev, | 215 | static 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 | ||