This source file includes following definitions.
- drm_encoder_register_all
- drm_encoder_unregister_all
- drm_encoder_init
- drm_encoder_cleanup
- drm_encoder_get_crtc
- drm_mode_getencoder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <linux/export.h>
24
25 #include <drm/drm_device.h>
26 #include <drm/drm_drv.h>
27 #include <drm/drm_encoder.h>
28
29 #include "drm_crtc_internal.h"
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 static const struct drm_prop_enum_list drm_encoder_enum_list[] = {
57 { DRM_MODE_ENCODER_NONE, "None" },
58 { DRM_MODE_ENCODER_DAC, "DAC" },
59 { DRM_MODE_ENCODER_TMDS, "TMDS" },
60 { DRM_MODE_ENCODER_LVDS, "LVDS" },
61 { DRM_MODE_ENCODER_TVDAC, "TV" },
62 { DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
63 { DRM_MODE_ENCODER_DSI, "DSI" },
64 { DRM_MODE_ENCODER_DPMST, "DP MST" },
65 { DRM_MODE_ENCODER_DPI, "DPI" },
66 };
67
68 int drm_encoder_register_all(struct drm_device *dev)
69 {
70 struct drm_encoder *encoder;
71 int ret = 0;
72
73 drm_for_each_encoder(encoder, dev) {
74 if (encoder->funcs->late_register)
75 ret = encoder->funcs->late_register(encoder);
76 if (ret)
77 return ret;
78 }
79
80 return 0;
81 }
82
83 void drm_encoder_unregister_all(struct drm_device *dev)
84 {
85 struct drm_encoder *encoder;
86
87 drm_for_each_encoder(encoder, dev) {
88 if (encoder->funcs->early_unregister)
89 encoder->funcs->early_unregister(encoder);
90 }
91 }
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108 int drm_encoder_init(struct drm_device *dev,
109 struct drm_encoder *encoder,
110 const struct drm_encoder_funcs *funcs,
111 int encoder_type, const char *name, ...)
112 {
113 int ret;
114
115
116 if (WARN_ON(dev->mode_config.num_encoder >= 32))
117 return -EINVAL;
118
119 ret = drm_mode_object_add(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
120 if (ret)
121 return ret;
122
123 encoder->dev = dev;
124 encoder->encoder_type = encoder_type;
125 encoder->funcs = funcs;
126 if (name) {
127 va_list ap;
128
129 va_start(ap, name);
130 encoder->name = kvasprintf(GFP_KERNEL, name, ap);
131 va_end(ap);
132 } else {
133 encoder->name = kasprintf(GFP_KERNEL, "%s-%d",
134 drm_encoder_enum_list[encoder_type].name,
135 encoder->base.id);
136 }
137 if (!encoder->name) {
138 ret = -ENOMEM;
139 goto out_put;
140 }
141
142 list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
143 encoder->index = dev->mode_config.num_encoder++;
144
145 out_put:
146 if (ret)
147 drm_mode_object_unregister(dev, &encoder->base);
148
149 return ret;
150 }
151 EXPORT_SYMBOL(drm_encoder_init);
152
153
154
155
156
157
158
159 void drm_encoder_cleanup(struct drm_encoder *encoder)
160 {
161 struct drm_device *dev = encoder->dev;
162
163
164
165
166
167
168 if (encoder->bridge) {
169 struct drm_bridge *bridge = encoder->bridge;
170 struct drm_bridge *next;
171
172 while (bridge) {
173 next = bridge->next;
174 drm_bridge_detach(bridge);
175 bridge = next;
176 }
177 }
178
179 drm_mode_object_unregister(dev, &encoder->base);
180 kfree(encoder->name);
181 list_del(&encoder->head);
182 dev->mode_config.num_encoder--;
183
184 memset(encoder, 0, sizeof(*encoder));
185 }
186 EXPORT_SYMBOL(drm_encoder_cleanup);
187
188 static struct drm_crtc *drm_encoder_get_crtc(struct drm_encoder *encoder)
189 {
190 struct drm_connector *connector;
191 struct drm_device *dev = encoder->dev;
192 bool uses_atomic = false;
193 struct drm_connector_list_iter conn_iter;
194
195
196
197 drm_connector_list_iter_begin(dev, &conn_iter);
198 drm_for_each_connector_iter(connector, &conn_iter) {
199 if (!connector->state)
200 continue;
201
202 uses_atomic = true;
203
204 if (connector->state->best_encoder != encoder)
205 continue;
206
207 drm_connector_list_iter_end(&conn_iter);
208 return connector->state->crtc;
209 }
210 drm_connector_list_iter_end(&conn_iter);
211
212
213 if (uses_atomic)
214 return NULL;
215
216 return encoder->crtc;
217 }
218
219 int drm_mode_getencoder(struct drm_device *dev, void *data,
220 struct drm_file *file_priv)
221 {
222 struct drm_mode_get_encoder *enc_resp = data;
223 struct drm_encoder *encoder;
224 struct drm_crtc *crtc;
225
226 if (!drm_core_check_feature(dev, DRIVER_MODESET))
227 return -EOPNOTSUPP;
228
229 encoder = drm_encoder_find(dev, file_priv, enc_resp->encoder_id);
230 if (!encoder)
231 return -ENOENT;
232
233 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
234 crtc = drm_encoder_get_crtc(encoder);
235 if (crtc && drm_lease_held(file_priv, crtc->base.id))
236 enc_resp->crtc_id = crtc->base.id;
237 else
238 enc_resp->crtc_id = 0;
239 drm_modeset_unlock(&dev->mode_config.connection_mutex);
240
241 enc_resp->encoder_type = encoder->encoder_type;
242 enc_resp->encoder_id = encoder->base.id;
243 enc_resp->possible_crtcs = drm_lease_filter_crtcs(file_priv,
244 encoder->possible_crtcs);
245 enc_resp->possible_clones = encoder->possible_clones;
246
247 return 0;
248 }