1 /* $NetBSD: drm_encoder.c,v 1.2 2021/12/18 23:44:57 riastradh Exp $ */ 2 3 /* 4 * Copyright (c) 2016 Intel Corporation 5 * 6 * Permission to use, copy, modify, distribute, and sell this software and its 7 * documentation for any purpose is hereby granted without fee, provided that 8 * the above copyright notice appear in all copies and that both that copyright 9 * notice and this permission notice appear in supporting documentation, and 10 * that the name of the copyright holders not be used in advertising or 11 * publicity pertaining to distribution of the software without specific, 12 * written prior permission. The copyright holders make no representations 13 * about the suitability of this software for any purpose. It is provided "as 14 * is" without express or implied warranty. 15 * 16 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 18 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 22 * OF THIS SOFTWARE. 23 */ 24 25 #include <sys/cdefs.h> 26 __KERNEL_RCSID(0, "$NetBSD: drm_encoder.c,v 1.2 2021/12/18 23:44:57 riastradh Exp $"); 27 28 #include <linux/export.h> 29 30 #include <drm/drm_bridge.h> 31 #include <drm/drm_device.h> 32 #include <drm/drm_drv.h> 33 #include <drm/drm_encoder.h> 34 35 #include "drm_crtc_internal.h" 36 37 /** 38 * DOC: overview 39 * 40 * Encoders represent the connecting element between the CRTC (as the overall 41 * pixel pipeline, represented by &struct drm_crtc) and the connectors (as the 42 * generic sink entity, represented by &struct drm_connector). An encoder takes 43 * pixel data from a CRTC and converts it to a format suitable for any attached 44 * connector. Encoders are objects exposed to userspace, originally to allow 45 * userspace to infer cloning and connector/CRTC restrictions. Unfortunately 46 * almost all drivers get this wrong, making the uabi pretty much useless. On 47 * top of that the exposed restrictions are too simple for today's hardware, and 48 * the recommended way to infer restrictions is by using the 49 * DRM_MODE_ATOMIC_TEST_ONLY flag for the atomic IOCTL. 50 * 51 * Otherwise encoders aren't used in the uapi at all (any modeset request from 52 * userspace directly connects a connector with a CRTC), drivers are therefore 53 * free to use them however they wish. Modeset helper libraries make strong use 54 * of encoders to facilitate code sharing. But for more complex settings it is 55 * usually better to move shared code into a separate &drm_bridge. Compared to 56 * encoders, bridges also have the benefit of being purely an internal 57 * abstraction since they are not exposed to userspace at all. 58 * 59 * Encoders are initialized with drm_encoder_init() and cleaned up using 60 * drm_encoder_cleanup(). 61 */ 62 static const struct drm_prop_enum_list drm_encoder_enum_list[] = { 63 { DRM_MODE_ENCODER_NONE, "None" }, 64 { DRM_MODE_ENCODER_DAC, "DAC" }, 65 { DRM_MODE_ENCODER_TMDS, "TMDS" }, 66 { DRM_MODE_ENCODER_LVDS, "LVDS" }, 67 { DRM_MODE_ENCODER_TVDAC, "TV" }, 68 { DRM_MODE_ENCODER_VIRTUAL, "Virtual" }, 69 { DRM_MODE_ENCODER_DSI, "DSI" }, 70 { DRM_MODE_ENCODER_DPMST, "DP MST" }, 71 { DRM_MODE_ENCODER_DPI, "DPI" }, 72 }; 73 74 int drm_encoder_register_all(struct drm_device *dev) 75 { 76 struct drm_encoder *encoder; 77 int ret = 0; 78 79 drm_for_each_encoder(encoder, dev) { 80 if (encoder->funcs->late_register) 81 ret = encoder->funcs->late_register(encoder); 82 if (ret) 83 return ret; 84 } 85 86 return 0; 87 } 88 89 void drm_encoder_unregister_all(struct drm_device *dev) 90 { 91 struct drm_encoder *encoder; 92 93 drm_for_each_encoder(encoder, dev) { 94 if (encoder->funcs->early_unregister) 95 encoder->funcs->early_unregister(encoder); 96 } 97 } 98 99 /** 100 * drm_encoder_init - Init a preallocated encoder 101 * @dev: drm device 102 * @encoder: the encoder to init 103 * @funcs: callbacks for this encoder 104 * @encoder_type: user visible type of the encoder 105 * @name: printf style format string for the encoder name, or NULL for default name 106 * 107 * Initialises a preallocated encoder. Encoder should be subclassed as part of 108 * driver encoder objects. At driver unload time drm_encoder_cleanup() should be 109 * called from the driver's &drm_encoder_funcs.destroy hook. 110 * 111 * Returns: 112 * Zero on success, error code on failure. 113 */ 114 int drm_encoder_init(struct drm_device *dev, 115 struct drm_encoder *encoder, 116 const struct drm_encoder_funcs *funcs, 117 int encoder_type, const char *name, ...) 118 { 119 int ret; 120 121 /* encoder index is used with 32bit bitmasks */ 122 if (WARN_ON(dev->mode_config.num_encoder >= 32)) 123 return -EINVAL; 124 125 ret = drm_mode_object_add(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER); 126 if (ret) 127 return ret; 128 129 encoder->dev = dev; 130 encoder->encoder_type = encoder_type; 131 encoder->funcs = funcs; 132 if (name) { 133 va_list ap; 134 135 va_start(ap, name); 136 encoder->name = kvasprintf(GFP_KERNEL, name, ap); 137 va_end(ap); 138 } else { 139 encoder->name = kasprintf(GFP_KERNEL, "%s-%d", 140 drm_encoder_enum_list[encoder_type].name, 141 encoder->base.id); 142 } 143 if (!encoder->name) { 144 ret = -ENOMEM; 145 goto out_put; 146 } 147 148 INIT_LIST_HEAD(&encoder->bridge_chain); 149 list_add_tail(&encoder->head, &dev->mode_config.encoder_list); 150 encoder->index = dev->mode_config.num_encoder++; 151 152 out_put: 153 if (ret) 154 drm_mode_object_unregister(dev, &encoder->base); 155 156 return ret; 157 } 158 EXPORT_SYMBOL(drm_encoder_init); 159 160 /** 161 * drm_encoder_cleanup - cleans up an initialised encoder 162 * @encoder: encoder to cleanup 163 * 164 * Cleans up the encoder but doesn't free the object. 165 */ 166 void drm_encoder_cleanup(struct drm_encoder *encoder) 167 { 168 struct drm_device *dev = encoder->dev; 169 struct drm_bridge *bridge, *next; 170 171 /* Note that the encoder_list is considered to be static; should we 172 * remove the drm_encoder at runtime we would have to decrement all 173 * the indices on the drm_encoder after us in the encoder_list. 174 */ 175 176 list_for_each_entry_safe(bridge, next, &encoder->bridge_chain, 177 chain_node) 178 drm_bridge_detach(bridge); 179 180 drm_mode_object_unregister(dev, &encoder->base); 181 kfree(encoder->name); 182 list_del(&encoder->head); 183 dev->mode_config.num_encoder--; 184 185 memset(encoder, 0, sizeof(*encoder)); 186 } 187 EXPORT_SYMBOL(drm_encoder_cleanup); 188 189 static struct drm_crtc *drm_encoder_get_crtc(struct drm_encoder *encoder) 190 { 191 struct drm_connector *connector; 192 struct drm_device *dev = encoder->dev; 193 bool uses_atomic = false; 194 struct drm_connector_list_iter conn_iter; 195 196 /* For atomic drivers only state objects are synchronously updated and 197 * protected by modeset locks, so check those first. */ 198 drm_connector_list_iter_begin(dev, &conn_iter); 199 drm_for_each_connector_iter(connector, &conn_iter) { 200 if (!connector->state) 201 continue; 202 203 uses_atomic = true; 204 205 if (connector->state->best_encoder != encoder) 206 continue; 207 208 drm_connector_list_iter_end(&conn_iter); 209 return connector->state->crtc; 210 } 211 drm_connector_list_iter_end(&conn_iter); 212 213 /* Don't return stale data (e.g. pending async disable). */ 214 if (uses_atomic) 215 return NULL; 216 217 return encoder->crtc; 218 } 219 220 int drm_mode_getencoder(struct drm_device *dev, void *data, 221 struct drm_file *file_priv) 222 { 223 struct drm_mode_get_encoder *enc_resp = data; 224 struct drm_encoder *encoder; 225 struct drm_crtc *crtc; 226 227 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 228 return -EOPNOTSUPP; 229 230 encoder = drm_encoder_find(dev, file_priv, enc_resp->encoder_id); 231 if (!encoder) 232 return -ENOENT; 233 234 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); 235 crtc = drm_encoder_get_crtc(encoder); 236 if (crtc && drm_lease_held(file_priv, crtc->base.id)) 237 enc_resp->crtc_id = crtc->base.id; 238 else 239 enc_resp->crtc_id = 0; 240 drm_modeset_unlock(&dev->mode_config.connection_mutex); 241 242 enc_resp->encoder_type = encoder->encoder_type; 243 enc_resp->encoder_id = encoder->base.id; 244 enc_resp->possible_crtcs = drm_lease_filter_crtcs(file_priv, 245 encoder->possible_crtcs); 246 enc_resp->possible_clones = encoder->possible_clones; 247 248 return 0; 249 } 250