1 /* 2 * Copyright (c) 2014 Samsung Electronics Co., Ltd 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sub license, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the 12 * next paragraph) shall be included in all copies or substantial portions 13 * of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24 #include <linux/err.h> 25 #include <linux/module.h> 26 #include <linux/mutex.h> 27 28 #include <drm/drm_bridge.h> 29 30 /** 31 * DOC: overview 32 * 33 * struct &drm_bridge represents a device that hangs on to an encoder. These are 34 * handy when a regular &drm_encoder entity isn't enough to represent the entire 35 * encoder chain. 36 * 37 * A bridge is always attached to a single &drm_encoder at a time, but can be 38 * either connected to it directly, or through an intermediate bridge:: 39 * 40 * encoder ---> bridge B ---> bridge A 41 * 42 * Here, the output of the encoder feeds to bridge B, and that furthers feeds to 43 * bridge A. 44 * 45 * The driver using the bridge is responsible to make the associations between 46 * the encoder and bridges. Once these links are made, the bridges will 47 * participate along with encoder functions to perform mode_set/enable/disable 48 * through the ops provided in &drm_bridge_funcs. 49 * 50 * drm_bridge, like drm_panel, aren't drm_mode_object entities like planes, 51 * CRTCs, encoders or connectors and hence are not visible to userspace. They 52 * just provide additional hooks to get the desired output at the end of the 53 * encoder chain. 54 * 55 * Bridges can also be chained up using the next pointer in struct &drm_bridge. 56 * 57 * Both legacy CRTC helpers and the new atomic modeset helpers support bridges. 58 */ 59 60 static DEFINE_MUTEX(bridge_lock); 61 static LIST_HEAD(bridge_list); 62 63 /** 64 * drm_bridge_add - add the given bridge to the global bridge list 65 * 66 * @bridge: bridge control structure 67 * 68 * RETURNS: 69 * Unconditionally returns Zero. 70 */ 71 int drm_bridge_add(struct drm_bridge *bridge) 72 { 73 mutex_lock(&bridge_lock); 74 list_add_tail(&bridge->list, &bridge_list); 75 mutex_unlock(&bridge_lock); 76 77 return 0; 78 } 79 EXPORT_SYMBOL(drm_bridge_add); 80 81 /** 82 * drm_bridge_remove - remove the given bridge from the global bridge list 83 * 84 * @bridge: bridge control structure 85 */ 86 void drm_bridge_remove(struct drm_bridge *bridge) 87 { 88 mutex_lock(&bridge_lock); 89 list_del_init(&bridge->list); 90 mutex_unlock(&bridge_lock); 91 } 92 EXPORT_SYMBOL(drm_bridge_remove); 93 94 /** 95 * drm_bridge_attach - associate given bridge to our DRM device 96 * 97 * @dev: DRM device 98 * @bridge: bridge control structure 99 * 100 * Called by a kms driver to link one of our encoder/bridge to the given 101 * bridge. 102 * 103 * Note that setting up links between the bridge and our encoder/bridge 104 * objects needs to be handled by the kms driver itself. 105 * 106 * RETURNS: 107 * Zero on success, error code on failure 108 */ 109 int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge) 110 { 111 if (!dev || !bridge) 112 return -EINVAL; 113 114 if (bridge->dev) 115 return -EBUSY; 116 117 bridge->dev = dev; 118 119 if (bridge->funcs->attach) 120 return bridge->funcs->attach(bridge); 121 122 return 0; 123 } 124 EXPORT_SYMBOL(drm_bridge_attach); 125 126 /** 127 * drm_bridge_detach - deassociate given bridge from its DRM device 128 * 129 * @bridge: bridge control structure 130 * 131 * Called by a kms driver to unlink the given bridge from its DRM device. 132 * 133 * Note that tearing down links between the bridge and our encoder/bridge 134 * objects needs to be handled by the kms driver itself. 135 */ 136 void drm_bridge_detach(struct drm_bridge *bridge) 137 { 138 if (WARN_ON(!bridge)) 139 return; 140 141 if (WARN_ON(!bridge->dev)) 142 return; 143 144 if (bridge->funcs->detach) 145 bridge->funcs->detach(bridge); 146 147 bridge->dev = NULL; 148 } 149 EXPORT_SYMBOL(drm_bridge_detach); 150 151 /** 152 * DOC: bridge callbacks 153 * 154 * The &drm_bridge_funcs ops are populated by the bridge driver. The DRM 155 * internals (atomic and CRTC helpers) use the helpers defined in drm_bridge.c 156 * These helpers call a specific &drm_bridge_funcs op for all the bridges 157 * during encoder configuration. 158 * 159 * For detailed specification of the bridge callbacks see &drm_bridge_funcs. 160 */ 161 162 /** 163 * drm_bridge_mode_fixup - fixup proposed mode for all bridges in the 164 * encoder chain 165 * @bridge: bridge control structure 166 * @mode: desired mode to be set for the bridge 167 * @adjusted_mode: updated mode that works for this bridge 168 * 169 * Calls ->mode_fixup() &drm_bridge_funcs op for all the bridges in the 170 * encoder chain, starting from the first bridge to the last. 171 * 172 * Note: the bridge passed should be the one closest to the encoder 173 * 174 * RETURNS: 175 * true on success, false on failure 176 */ 177 bool drm_bridge_mode_fixup(struct drm_bridge *bridge, 178 const struct drm_display_mode *mode, 179 struct drm_display_mode *adjusted_mode) 180 { 181 bool ret = true; 182 183 if (!bridge) 184 return true; 185 186 if (bridge->funcs->mode_fixup) 187 ret = bridge->funcs->mode_fixup(bridge, mode, adjusted_mode); 188 189 ret = ret && drm_bridge_mode_fixup(bridge->next, mode, adjusted_mode); 190 191 return ret; 192 } 193 EXPORT_SYMBOL(drm_bridge_mode_fixup); 194 195 /** 196 * drm_bridge_disable - calls ->disable() &drm_bridge_funcs op for all 197 * bridges in the encoder chain. 198 * @bridge: bridge control structure 199 * 200 * Calls ->disable() &drm_bridge_funcs op for all the bridges in the encoder 201 * chain, starting from the last bridge to the first. These are called before 202 * calling the encoder's prepare op. 203 * 204 * Note: the bridge passed should be the one closest to the encoder 205 */ 206 void drm_bridge_disable(struct drm_bridge *bridge) 207 { 208 if (!bridge) 209 return; 210 211 drm_bridge_disable(bridge->next); 212 213 if (bridge->funcs->disable) 214 bridge->funcs->disable(bridge); 215 } 216 EXPORT_SYMBOL(drm_bridge_disable); 217 218 /** 219 * drm_bridge_post_disable - calls ->post_disable() &drm_bridge_funcs op for 220 * all bridges in the encoder chain. 221 * @bridge: bridge control structure 222 * 223 * Calls ->post_disable() &drm_bridge_funcs op for all the bridges in the 224 * encoder chain, starting from the first bridge to the last. These are called 225 * after completing the encoder's prepare op. 226 * 227 * Note: the bridge passed should be the one closest to the encoder 228 */ 229 void drm_bridge_post_disable(struct drm_bridge *bridge) 230 { 231 if (!bridge) 232 return; 233 234 if (bridge->funcs->post_disable) 235 bridge->funcs->post_disable(bridge); 236 237 drm_bridge_post_disable(bridge->next); 238 } 239 EXPORT_SYMBOL(drm_bridge_post_disable); 240 241 /** 242 * drm_bridge_mode_set - set proposed mode for all bridges in the 243 * encoder chain 244 * @bridge: bridge control structure 245 * @mode: desired mode to be set for the bridge 246 * @adjusted_mode: updated mode that works for this bridge 247 * 248 * Calls ->mode_set() &drm_bridge_funcs op for all the bridges in the 249 * encoder chain, starting from the first bridge to the last. 250 * 251 * Note: the bridge passed should be the one closest to the encoder 252 */ 253 void drm_bridge_mode_set(struct drm_bridge *bridge, 254 struct drm_display_mode *mode, 255 struct drm_display_mode *adjusted_mode) 256 { 257 if (!bridge) 258 return; 259 260 if (bridge->funcs->mode_set) 261 bridge->funcs->mode_set(bridge, mode, adjusted_mode); 262 263 drm_bridge_mode_set(bridge->next, mode, adjusted_mode); 264 } 265 EXPORT_SYMBOL(drm_bridge_mode_set); 266 267 /** 268 * drm_bridge_pre_enable - calls ->pre_enable() &drm_bridge_funcs op for all 269 * bridges in the encoder chain. 270 * @bridge: bridge control structure 271 * 272 * Calls ->pre_enable() &drm_bridge_funcs op for all the bridges in the encoder 273 * chain, starting from the last bridge to the first. These are called 274 * before calling the encoder's commit op. 275 * 276 * Note: the bridge passed should be the one closest to the encoder 277 */ 278 void drm_bridge_pre_enable(struct drm_bridge *bridge) 279 { 280 if (!bridge) 281 return; 282 283 drm_bridge_pre_enable(bridge->next); 284 285 if (bridge->funcs->pre_enable) 286 bridge->funcs->pre_enable(bridge); 287 } 288 EXPORT_SYMBOL(drm_bridge_pre_enable); 289 290 /** 291 * drm_bridge_enable - calls ->enable() &drm_bridge_funcs op for all bridges 292 * in the encoder chain. 293 * @bridge: bridge control structure 294 * 295 * Calls ->enable() &drm_bridge_funcs op for all the bridges in the encoder 296 * chain, starting from the first bridge to the last. These are called 297 * after completing the encoder's commit op. 298 * 299 * Note that the bridge passed should be the one closest to the encoder 300 */ 301 void drm_bridge_enable(struct drm_bridge *bridge) 302 { 303 if (!bridge) 304 return; 305 306 if (bridge->funcs->enable) 307 bridge->funcs->enable(bridge); 308 309 drm_bridge_enable(bridge->next); 310 } 311 EXPORT_SYMBOL(drm_bridge_enable); 312 313 #ifdef CONFIG_OF 314 /** 315 * of_drm_find_bridge - find the bridge corresponding to the device node in 316 * the global bridge list 317 * 318 * @np: device node 319 * 320 * RETURNS: 321 * drm_bridge control struct on success, NULL on failure 322 */ 323 struct drm_bridge *of_drm_find_bridge(struct device_node *np) 324 { 325 struct drm_bridge *bridge; 326 327 mutex_lock(&bridge_lock); 328 329 list_for_each_entry(bridge, &bridge_list, list) { 330 if (bridge->of_node == np) { 331 mutex_unlock(&bridge_lock); 332 return bridge; 333 } 334 } 335 336 mutex_unlock(&bridge_lock); 337 return NULL; 338 } 339 EXPORT_SYMBOL(of_drm_find_bridge); 340 #endif 341 342 MODULE_AUTHOR("Ajay Kumar <ajaykumar.rs@samsung.com>"); 343 MODULE_DESCRIPTION("DRM bridge infrastructure"); 344 MODULE_LICENSE("GPL and additional rights"); 345