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