0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #include <linux/export.h>
0024
0025 #include <drm/drm_bridge.h>
0026 #include <drm/drm_device.h>
0027 #include <drm/drm_drv.h>
0028 #include <drm/drm_encoder.h>
0029 #include <drm/drm_managed.h>
0030
0031 #include "drm_crtc_internal.h"
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 static const struct drm_prop_enum_list drm_encoder_enum_list[] = {
0059 { DRM_MODE_ENCODER_NONE, "None" },
0060 { DRM_MODE_ENCODER_DAC, "DAC" },
0061 { DRM_MODE_ENCODER_TMDS, "TMDS" },
0062 { DRM_MODE_ENCODER_LVDS, "LVDS" },
0063 { DRM_MODE_ENCODER_TVDAC, "TV" },
0064 { DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
0065 { DRM_MODE_ENCODER_DSI, "DSI" },
0066 { DRM_MODE_ENCODER_DPMST, "DP MST" },
0067 { DRM_MODE_ENCODER_DPI, "DPI" },
0068 };
0069
0070 int drm_encoder_register_all(struct drm_device *dev)
0071 {
0072 struct drm_encoder *encoder;
0073 int ret = 0;
0074
0075 drm_for_each_encoder(encoder, dev) {
0076 if (encoder->funcs && encoder->funcs->late_register)
0077 ret = encoder->funcs->late_register(encoder);
0078 if (ret)
0079 return ret;
0080 }
0081
0082 return 0;
0083 }
0084
0085 void drm_encoder_unregister_all(struct drm_device *dev)
0086 {
0087 struct drm_encoder *encoder;
0088
0089 drm_for_each_encoder(encoder, dev) {
0090 if (encoder->funcs && encoder->funcs->early_unregister)
0091 encoder->funcs->early_unregister(encoder);
0092 }
0093 }
0094
0095 __printf(5, 0)
0096 static int __drm_encoder_init(struct drm_device *dev,
0097 struct drm_encoder *encoder,
0098 const struct drm_encoder_funcs *funcs,
0099 int encoder_type, const char *name, va_list ap)
0100 {
0101 int ret;
0102
0103
0104 if (WARN_ON(dev->mode_config.num_encoder >= 32))
0105 return -EINVAL;
0106
0107 ret = drm_mode_object_add(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
0108 if (ret)
0109 return ret;
0110
0111 encoder->dev = dev;
0112 encoder->encoder_type = encoder_type;
0113 encoder->funcs = funcs;
0114 if (name) {
0115 encoder->name = kvasprintf(GFP_KERNEL, name, ap);
0116 } else {
0117 encoder->name = kasprintf(GFP_KERNEL, "%s-%d",
0118 drm_encoder_enum_list[encoder_type].name,
0119 encoder->base.id);
0120 }
0121 if (!encoder->name) {
0122 ret = -ENOMEM;
0123 goto out_put;
0124 }
0125
0126 INIT_LIST_HEAD(&encoder->bridge_chain);
0127 list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
0128 encoder->index = dev->mode_config.num_encoder++;
0129
0130 out_put:
0131 if (ret)
0132 drm_mode_object_unregister(dev, &encoder->base);
0133
0134 return ret;
0135 }
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158 int drm_encoder_init(struct drm_device *dev,
0159 struct drm_encoder *encoder,
0160 const struct drm_encoder_funcs *funcs,
0161 int encoder_type, const char *name, ...)
0162 {
0163 va_list ap;
0164 int ret;
0165
0166 WARN_ON(!funcs->destroy);
0167
0168 va_start(ap, name);
0169 ret = __drm_encoder_init(dev, encoder, funcs, encoder_type, name, ap);
0170 va_end(ap);
0171
0172 return ret;
0173 }
0174 EXPORT_SYMBOL(drm_encoder_init);
0175
0176
0177
0178
0179
0180
0181
0182 void drm_encoder_cleanup(struct drm_encoder *encoder)
0183 {
0184 struct drm_device *dev = encoder->dev;
0185 struct drm_bridge *bridge, *next;
0186
0187
0188
0189
0190
0191
0192 list_for_each_entry_safe(bridge, next, &encoder->bridge_chain,
0193 chain_node)
0194 drm_bridge_detach(bridge);
0195
0196 drm_mode_object_unregister(dev, &encoder->base);
0197 kfree(encoder->name);
0198 list_del(&encoder->head);
0199 dev->mode_config.num_encoder--;
0200
0201 memset(encoder, 0, sizeof(*encoder));
0202 }
0203 EXPORT_SYMBOL(drm_encoder_cleanup);
0204
0205 static void drmm_encoder_alloc_release(struct drm_device *dev, void *ptr)
0206 {
0207 struct drm_encoder *encoder = ptr;
0208
0209 if (WARN_ON(!encoder->dev))
0210 return;
0211
0212 drm_encoder_cleanup(encoder);
0213 }
0214
0215 void *__drmm_encoder_alloc(struct drm_device *dev, size_t size, size_t offset,
0216 const struct drm_encoder_funcs *funcs,
0217 int encoder_type, const char *name, ...)
0218 {
0219 void *container;
0220 struct drm_encoder *encoder;
0221 va_list ap;
0222 int ret;
0223
0224 if (WARN_ON(funcs && funcs->destroy))
0225 return ERR_PTR(-EINVAL);
0226
0227 container = drmm_kzalloc(dev, size, GFP_KERNEL);
0228 if (!container)
0229 return ERR_PTR(-ENOMEM);
0230
0231 encoder = container + offset;
0232
0233 va_start(ap, name);
0234 ret = __drm_encoder_init(dev, encoder, funcs, encoder_type, name, ap);
0235 va_end(ap);
0236 if (ret)
0237 return ERR_PTR(ret);
0238
0239 ret = drmm_add_action_or_reset(dev, drmm_encoder_alloc_release, encoder);
0240 if (ret)
0241 return ERR_PTR(ret);
0242
0243 return container;
0244 }
0245 EXPORT_SYMBOL(__drmm_encoder_alloc);
0246
0247 static struct drm_crtc *drm_encoder_get_crtc(struct drm_encoder *encoder)
0248 {
0249 struct drm_connector *connector;
0250 struct drm_device *dev = encoder->dev;
0251 bool uses_atomic = false;
0252 struct drm_connector_list_iter conn_iter;
0253
0254
0255
0256 drm_connector_list_iter_begin(dev, &conn_iter);
0257 drm_for_each_connector_iter(connector, &conn_iter) {
0258 if (!connector->state)
0259 continue;
0260
0261 uses_atomic = true;
0262
0263 if (connector->state->best_encoder != encoder)
0264 continue;
0265
0266 drm_connector_list_iter_end(&conn_iter);
0267 return connector->state->crtc;
0268 }
0269 drm_connector_list_iter_end(&conn_iter);
0270
0271
0272 if (uses_atomic)
0273 return NULL;
0274
0275 return encoder->crtc;
0276 }
0277
0278 int drm_mode_getencoder(struct drm_device *dev, void *data,
0279 struct drm_file *file_priv)
0280 {
0281 struct drm_mode_get_encoder *enc_resp = data;
0282 struct drm_encoder *encoder;
0283 struct drm_crtc *crtc;
0284
0285 if (!drm_core_check_feature(dev, DRIVER_MODESET))
0286 return -EOPNOTSUPP;
0287
0288 encoder = drm_encoder_find(dev, file_priv, enc_resp->encoder_id);
0289 if (!encoder)
0290 return -ENOENT;
0291
0292 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
0293 crtc = drm_encoder_get_crtc(encoder);
0294 if (crtc && drm_lease_held(file_priv, crtc->base.id))
0295 enc_resp->crtc_id = crtc->base.id;
0296 else
0297 enc_resp->crtc_id = 0;
0298 drm_modeset_unlock(&dev->mode_config.connection_mutex);
0299
0300 enc_resp->encoder_type = encoder->encoder_type;
0301 enc_resp->encoder_id = encoder->base.id;
0302 enc_resp->possible_crtcs = drm_lease_filter_crtcs(file_priv,
0303 encoder->possible_crtcs);
0304 enc_resp->possible_clones = encoder->possible_clones;
0305
0306 return 0;
0307 }