1 1.5 riastrad /* $NetBSD: drm_bridge.c,v 1.5 2021/12/18 23:44:57 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /* 4 1.1 riastrad * Copyright (c) 2014 Samsung Electronics Co., Ltd 5 1.1 riastrad * 6 1.1 riastrad * Permission is hereby granted, free of charge, to any person obtaining a 7 1.1 riastrad * copy of this software and associated documentation files (the "Software"), 8 1.1 riastrad * to deal in the Software without restriction, including without limitation 9 1.1 riastrad * the rights to use, copy, modify, merge, publish, distribute, sub license, 10 1.1 riastrad * and/or sell copies of the Software, and to permit persons to whom the 11 1.1 riastrad * Software is furnished to do so, subject to the following conditions: 12 1.1 riastrad * 13 1.1 riastrad * The above copyright notice and this permission notice (including the 14 1.1 riastrad * next paragraph) shall be included in all copies or substantial portions 15 1.1 riastrad * of the Software. 16 1.1 riastrad * 17 1.1 riastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 1.1 riastrad * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 1.1 riastrad * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 20 1.1 riastrad * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 1.1 riastrad * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 1.1 riastrad * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 1.1 riastrad * DEALINGS IN THE SOFTWARE. 24 1.1 riastrad */ 25 1.1 riastrad 26 1.1 riastrad #include <sys/cdefs.h> 27 1.5 riastrad __KERNEL_RCSID(0, "$NetBSD: drm_bridge.c,v 1.5 2021/12/18 23:44:57 riastradh Exp $"); 28 1.1 riastrad 29 1.1 riastrad #include <linux/err.h> 30 1.1 riastrad #include <linux/module.h> 31 1.5 riastrad #include <linux/mutex.h> 32 1.1 riastrad 33 1.5 riastrad #include <drm/drm_bridge.h> 34 1.5 riastrad #include <drm/drm_encoder.h> 35 1.1 riastrad 36 1.5 riastrad #include "drm_crtc_internal.h" 37 1.1 riastrad 38 1.1 riastrad /** 39 1.1 riastrad * DOC: overview 40 1.1 riastrad * 41 1.5 riastrad * &struct drm_bridge represents a device that hangs on to an encoder. These are 42 1.5 riastrad * handy when a regular &drm_encoder entity isn't enough to represent the entire 43 1.1 riastrad * encoder chain. 44 1.1 riastrad * 45 1.5 riastrad * A bridge is always attached to a single &drm_encoder at a time, but can be 46 1.5 riastrad * either connected to it directly, or through an intermediate bridge:: 47 1.1 riastrad * 48 1.5 riastrad * encoder ---> bridge B ---> bridge A 49 1.1 riastrad * 50 1.1 riastrad * Here, the output of the encoder feeds to bridge B, and that furthers feeds to 51 1.1 riastrad * bridge A. 52 1.1 riastrad * 53 1.1 riastrad * The driver using the bridge is responsible to make the associations between 54 1.1 riastrad * the encoder and bridges. Once these links are made, the bridges will 55 1.1 riastrad * participate along with encoder functions to perform mode_set/enable/disable 56 1.5 riastrad * through the ops provided in &drm_bridge_funcs. 57 1.1 riastrad * 58 1.1 riastrad * drm_bridge, like drm_panel, aren't drm_mode_object entities like planes, 59 1.5 riastrad * CRTCs, encoders or connectors and hence are not visible to userspace. They 60 1.5 riastrad * just provide additional hooks to get the desired output at the end of the 61 1.5 riastrad * encoder chain. 62 1.5 riastrad * 63 1.5 riastrad * Bridges can also be chained up using the &drm_bridge.chain_node field. 64 1.5 riastrad * 65 1.5 riastrad * Both legacy CRTC helpers and the new atomic modeset helpers support bridges. 66 1.1 riastrad */ 67 1.1 riastrad 68 1.3 riastrad #ifdef __NetBSD__ 69 1.3 riastrad static struct mutex bridge_lock; 70 1.3 riastrad static struct list_head bridge_list = LIST_HEAD_INIT(bridge_list); 71 1.3 riastrad #else 72 1.1 riastrad static DEFINE_MUTEX(bridge_lock); 73 1.1 riastrad static LIST_HEAD(bridge_list); 74 1.3 riastrad #endif 75 1.1 riastrad 76 1.4 jmcneill #ifdef __NetBSD__ 77 1.4 jmcneill void drm_bridge_init_lock(void) 78 1.4 jmcneill { 79 1.4 jmcneill linux_mutex_init(&bridge_lock); 80 1.4 jmcneill } 81 1.4 jmcneill void drm_bridge_fini_lock(void) 82 1.4 jmcneill { 83 1.4 jmcneill linux_mutex_destroy(&bridge_lock); 84 1.4 jmcneill } 85 1.4 jmcneill #endif 86 1.4 jmcneill 87 1.1 riastrad /** 88 1.1 riastrad * drm_bridge_add - add the given bridge to the global bridge list 89 1.1 riastrad * 90 1.1 riastrad * @bridge: bridge control structure 91 1.1 riastrad */ 92 1.5 riastrad void drm_bridge_add(struct drm_bridge *bridge) 93 1.1 riastrad { 94 1.1 riastrad mutex_lock(&bridge_lock); 95 1.1 riastrad list_add_tail(&bridge->list, &bridge_list); 96 1.1 riastrad mutex_unlock(&bridge_lock); 97 1.1 riastrad } 98 1.1 riastrad EXPORT_SYMBOL(drm_bridge_add); 99 1.1 riastrad 100 1.1 riastrad /** 101 1.1 riastrad * drm_bridge_remove - remove the given bridge from the global bridge list 102 1.1 riastrad * 103 1.1 riastrad * @bridge: bridge control structure 104 1.1 riastrad */ 105 1.1 riastrad void drm_bridge_remove(struct drm_bridge *bridge) 106 1.1 riastrad { 107 1.1 riastrad mutex_lock(&bridge_lock); 108 1.1 riastrad list_del_init(&bridge->list); 109 1.1 riastrad mutex_unlock(&bridge_lock); 110 1.1 riastrad } 111 1.1 riastrad EXPORT_SYMBOL(drm_bridge_remove); 112 1.1 riastrad 113 1.1 riastrad /** 114 1.5 riastrad * drm_bridge_attach - attach the bridge to an encoder's chain 115 1.1 riastrad * 116 1.5 riastrad * @encoder: DRM encoder 117 1.5 riastrad * @bridge: bridge to attach 118 1.5 riastrad * @previous: previous bridge in the chain (optional) 119 1.5 riastrad * 120 1.5 riastrad * Called by a kms driver to link the bridge to an encoder's chain. The previous 121 1.5 riastrad * argument specifies the previous bridge in the chain. If NULL, the bridge is 122 1.5 riastrad * linked directly at the encoder's output. Otherwise it is linked at the 123 1.5 riastrad * previous bridge's output. 124 1.5 riastrad * 125 1.5 riastrad * If non-NULL the previous bridge must be already attached by a call to this 126 1.5 riastrad * function. 127 1.5 riastrad * 128 1.5 riastrad * Note that bridges attached to encoders are auto-detached during encoder 129 1.5 riastrad * cleanup in drm_encoder_cleanup(), so drm_bridge_attach() should generally 130 1.5 riastrad * *not* be balanced with a drm_bridge_detach() in driver code. 131 1.1 riastrad * 132 1.1 riastrad * RETURNS: 133 1.1 riastrad * Zero on success, error code on failure 134 1.1 riastrad */ 135 1.5 riastrad int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge, 136 1.5 riastrad struct drm_bridge *previous) 137 1.1 riastrad { 138 1.5 riastrad int ret; 139 1.5 riastrad 140 1.5 riastrad if (!encoder || !bridge) 141 1.5 riastrad return -EINVAL; 142 1.5 riastrad 143 1.5 riastrad if (previous && (!previous->dev || previous->encoder != encoder)) 144 1.1 riastrad return -EINVAL; 145 1.1 riastrad 146 1.1 riastrad if (bridge->dev) 147 1.1 riastrad return -EBUSY; 148 1.1 riastrad 149 1.5 riastrad bridge->dev = encoder->dev; 150 1.5 riastrad bridge->encoder = encoder; 151 1.1 riastrad 152 1.5 riastrad if (previous) 153 1.5 riastrad list_add(&bridge->chain_node, &previous->chain_node); 154 1.5 riastrad else 155 1.5 riastrad list_add(&bridge->chain_node, &encoder->bridge_chain); 156 1.5 riastrad 157 1.5 riastrad if (bridge->funcs->attach) { 158 1.5 riastrad ret = bridge->funcs->attach(bridge); 159 1.5 riastrad if (ret < 0) { 160 1.5 riastrad list_del(&bridge->chain_node); 161 1.5 riastrad bridge->dev = NULL; 162 1.5 riastrad bridge->encoder = NULL; 163 1.5 riastrad return ret; 164 1.5 riastrad } 165 1.5 riastrad } 166 1.1 riastrad 167 1.1 riastrad return 0; 168 1.1 riastrad } 169 1.1 riastrad EXPORT_SYMBOL(drm_bridge_attach); 170 1.1 riastrad 171 1.5 riastrad void drm_bridge_detach(struct drm_bridge *bridge) 172 1.5 riastrad { 173 1.5 riastrad if (WARN_ON(!bridge)) 174 1.5 riastrad return; 175 1.5 riastrad 176 1.5 riastrad if (WARN_ON(!bridge->dev)) 177 1.5 riastrad return; 178 1.5 riastrad 179 1.5 riastrad if (bridge->funcs->detach) 180 1.5 riastrad bridge->funcs->detach(bridge); 181 1.5 riastrad 182 1.5 riastrad list_del(&bridge->chain_node); 183 1.5 riastrad bridge->dev = NULL; 184 1.5 riastrad } 185 1.5 riastrad 186 1.1 riastrad /** 187 1.1 riastrad * DOC: bridge callbacks 188 1.1 riastrad * 189 1.5 riastrad * The &drm_bridge_funcs ops are populated by the bridge driver. The DRM 190 1.5 riastrad * internals (atomic and CRTC helpers) use the helpers defined in drm_bridge.c 191 1.5 riastrad * These helpers call a specific &drm_bridge_funcs op for all the bridges 192 1.1 riastrad * during encoder configuration. 193 1.1 riastrad * 194 1.5 riastrad * For detailed specification of the bridge callbacks see &drm_bridge_funcs. 195 1.1 riastrad */ 196 1.1 riastrad 197 1.1 riastrad /** 198 1.5 riastrad * drm_bridge_chain_mode_fixup - fixup proposed mode for all bridges in the 199 1.5 riastrad * encoder chain 200 1.1 riastrad * @bridge: bridge control structure 201 1.1 riastrad * @mode: desired mode to be set for the bridge 202 1.1 riastrad * @adjusted_mode: updated mode that works for this bridge 203 1.1 riastrad * 204 1.5 riastrad * Calls &drm_bridge_funcs.mode_fixup for all the bridges in the 205 1.1 riastrad * encoder chain, starting from the first bridge to the last. 206 1.1 riastrad * 207 1.1 riastrad * Note: the bridge passed should be the one closest to the encoder 208 1.1 riastrad * 209 1.1 riastrad * RETURNS: 210 1.1 riastrad * true on success, false on failure 211 1.1 riastrad */ 212 1.5 riastrad bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge, 213 1.5 riastrad const struct drm_display_mode *mode, 214 1.5 riastrad struct drm_display_mode *adjusted_mode) 215 1.1 riastrad { 216 1.5 riastrad struct drm_encoder *encoder; 217 1.1 riastrad 218 1.1 riastrad if (!bridge) 219 1.1 riastrad return true; 220 1.1 riastrad 221 1.5 riastrad encoder = bridge->encoder; 222 1.5 riastrad list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { 223 1.5 riastrad if (!bridge->funcs->mode_fixup) 224 1.5 riastrad continue; 225 1.1 riastrad 226 1.5 riastrad if (!bridge->funcs->mode_fixup(bridge, mode, adjusted_mode)) 227 1.5 riastrad return false; 228 1.5 riastrad } 229 1.1 riastrad 230 1.5 riastrad return true; 231 1.1 riastrad } 232 1.5 riastrad EXPORT_SYMBOL(drm_bridge_chain_mode_fixup); 233 1.1 riastrad 234 1.1 riastrad /** 235 1.5 riastrad * drm_bridge_chain_mode_valid - validate the mode against all bridges in the 236 1.5 riastrad * encoder chain. 237 1.1 riastrad * @bridge: bridge control structure 238 1.5 riastrad * @mode: desired mode to be validated 239 1.1 riastrad * 240 1.5 riastrad * Calls &drm_bridge_funcs.mode_valid for all the bridges in the encoder 241 1.5 riastrad * chain, starting from the first bridge to the last. If at least one bridge 242 1.5 riastrad * does not accept the mode the function returns the error code. 243 1.5 riastrad * 244 1.5 riastrad * Note: the bridge passed should be the one closest to the encoder. 245 1.5 riastrad * 246 1.5 riastrad * RETURNS: 247 1.5 riastrad * MODE_OK on success, drm_mode_status Enum error code on failure 248 1.5 riastrad */ 249 1.5 riastrad enum drm_mode_status 250 1.5 riastrad drm_bridge_chain_mode_valid(struct drm_bridge *bridge, 251 1.5 riastrad const struct drm_display_mode *mode) 252 1.5 riastrad { 253 1.5 riastrad struct drm_encoder *encoder; 254 1.5 riastrad 255 1.5 riastrad if (!bridge) 256 1.5 riastrad return MODE_OK; 257 1.5 riastrad 258 1.5 riastrad encoder = bridge->encoder; 259 1.5 riastrad list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { 260 1.5 riastrad enum drm_mode_status ret; 261 1.5 riastrad 262 1.5 riastrad if (!bridge->funcs->mode_valid) 263 1.5 riastrad continue; 264 1.5 riastrad 265 1.5 riastrad ret = bridge->funcs->mode_valid(bridge, mode); 266 1.5 riastrad if (ret != MODE_OK) 267 1.5 riastrad return ret; 268 1.5 riastrad } 269 1.5 riastrad 270 1.5 riastrad return MODE_OK; 271 1.5 riastrad } 272 1.5 riastrad EXPORT_SYMBOL(drm_bridge_chain_mode_valid); 273 1.5 riastrad 274 1.5 riastrad /** 275 1.5 riastrad * drm_bridge_chain_disable - disables all bridges in the encoder chain 276 1.5 riastrad * @bridge: bridge control structure 277 1.5 riastrad * 278 1.5 riastrad * Calls &drm_bridge_funcs.disable op for all the bridges in the encoder 279 1.1 riastrad * chain, starting from the last bridge to the first. These are called before 280 1.1 riastrad * calling the encoder's prepare op. 281 1.1 riastrad * 282 1.1 riastrad * Note: the bridge passed should be the one closest to the encoder 283 1.1 riastrad */ 284 1.5 riastrad void drm_bridge_chain_disable(struct drm_bridge *bridge) 285 1.1 riastrad { 286 1.5 riastrad struct drm_encoder *encoder; 287 1.5 riastrad struct drm_bridge *iter; 288 1.5 riastrad 289 1.1 riastrad if (!bridge) 290 1.1 riastrad return; 291 1.1 riastrad 292 1.5 riastrad encoder = bridge->encoder; 293 1.5 riastrad list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { 294 1.5 riastrad if (iter->funcs->disable) 295 1.5 riastrad iter->funcs->disable(iter); 296 1.1 riastrad 297 1.5 riastrad if (iter == bridge) 298 1.5 riastrad break; 299 1.5 riastrad } 300 1.1 riastrad } 301 1.5 riastrad EXPORT_SYMBOL(drm_bridge_chain_disable); 302 1.1 riastrad 303 1.1 riastrad /** 304 1.5 riastrad * drm_bridge_chain_post_disable - cleans up after disabling all bridges in the 305 1.5 riastrad * encoder chain 306 1.1 riastrad * @bridge: bridge control structure 307 1.1 riastrad * 308 1.5 riastrad * Calls &drm_bridge_funcs.post_disable op for all the bridges in the 309 1.1 riastrad * encoder chain, starting from the first bridge to the last. These are called 310 1.1 riastrad * after completing the encoder's prepare op. 311 1.1 riastrad * 312 1.1 riastrad * Note: the bridge passed should be the one closest to the encoder 313 1.1 riastrad */ 314 1.5 riastrad void drm_bridge_chain_post_disable(struct drm_bridge *bridge) 315 1.1 riastrad { 316 1.5 riastrad struct drm_encoder *encoder; 317 1.5 riastrad 318 1.1 riastrad if (!bridge) 319 1.1 riastrad return; 320 1.1 riastrad 321 1.5 riastrad encoder = bridge->encoder; 322 1.5 riastrad list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { 323 1.5 riastrad if (bridge->funcs->post_disable) 324 1.5 riastrad bridge->funcs->post_disable(bridge); 325 1.5 riastrad } 326 1.1 riastrad } 327 1.5 riastrad EXPORT_SYMBOL(drm_bridge_chain_post_disable); 328 1.1 riastrad 329 1.1 riastrad /** 330 1.5 riastrad * drm_bridge_chain_mode_set - set proposed mode for all bridges in the 331 1.5 riastrad * encoder chain 332 1.1 riastrad * @bridge: bridge control structure 333 1.5 riastrad * @mode: desired mode to be set for the encoder chain 334 1.5 riastrad * @adjusted_mode: updated mode that works for this encoder chain 335 1.1 riastrad * 336 1.5 riastrad * Calls &drm_bridge_funcs.mode_set op for all the bridges in the 337 1.1 riastrad * encoder chain, starting from the first bridge to the last. 338 1.1 riastrad * 339 1.1 riastrad * Note: the bridge passed should be the one closest to the encoder 340 1.1 riastrad */ 341 1.5 riastrad void drm_bridge_chain_mode_set(struct drm_bridge *bridge, 342 1.5 riastrad const struct drm_display_mode *mode, 343 1.5 riastrad const struct drm_display_mode *adjusted_mode) 344 1.1 riastrad { 345 1.5 riastrad struct drm_encoder *encoder; 346 1.5 riastrad 347 1.1 riastrad if (!bridge) 348 1.1 riastrad return; 349 1.1 riastrad 350 1.5 riastrad encoder = bridge->encoder; 351 1.5 riastrad list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { 352 1.5 riastrad if (bridge->funcs->mode_set) 353 1.5 riastrad bridge->funcs->mode_set(bridge, mode, adjusted_mode); 354 1.5 riastrad } 355 1.1 riastrad } 356 1.5 riastrad EXPORT_SYMBOL(drm_bridge_chain_mode_set); 357 1.1 riastrad 358 1.1 riastrad /** 359 1.5 riastrad * drm_bridge_chain_pre_enable - prepares for enabling all bridges in the 360 1.5 riastrad * encoder chain 361 1.1 riastrad * @bridge: bridge control structure 362 1.1 riastrad * 363 1.5 riastrad * Calls &drm_bridge_funcs.pre_enable op for all the bridges in the encoder 364 1.1 riastrad * chain, starting from the last bridge to the first. These are called 365 1.1 riastrad * before calling the encoder's commit op. 366 1.1 riastrad * 367 1.1 riastrad * Note: the bridge passed should be the one closest to the encoder 368 1.1 riastrad */ 369 1.5 riastrad void drm_bridge_chain_pre_enable(struct drm_bridge *bridge) 370 1.1 riastrad { 371 1.5 riastrad struct drm_encoder *encoder; 372 1.5 riastrad struct drm_bridge *iter; 373 1.5 riastrad 374 1.1 riastrad if (!bridge) 375 1.1 riastrad return; 376 1.1 riastrad 377 1.5 riastrad encoder = bridge->encoder; 378 1.5 riastrad list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { 379 1.5 riastrad if (iter->funcs->pre_enable) 380 1.5 riastrad iter->funcs->pre_enable(iter); 381 1.5 riastrad } 382 1.1 riastrad } 383 1.5 riastrad EXPORT_SYMBOL(drm_bridge_chain_pre_enable); 384 1.1 riastrad 385 1.1 riastrad /** 386 1.5 riastrad * drm_bridge_chain_enable - enables all bridges in the encoder chain 387 1.1 riastrad * @bridge: bridge control structure 388 1.1 riastrad * 389 1.5 riastrad * Calls &drm_bridge_funcs.enable op for all the bridges in the encoder 390 1.1 riastrad * chain, starting from the first bridge to the last. These are called 391 1.1 riastrad * after completing the encoder's commit op. 392 1.1 riastrad * 393 1.1 riastrad * Note that the bridge passed should be the one closest to the encoder 394 1.1 riastrad */ 395 1.5 riastrad void drm_bridge_chain_enable(struct drm_bridge *bridge) 396 1.1 riastrad { 397 1.5 riastrad struct drm_encoder *encoder; 398 1.5 riastrad 399 1.1 riastrad if (!bridge) 400 1.1 riastrad return; 401 1.1 riastrad 402 1.5 riastrad encoder = bridge->encoder; 403 1.5 riastrad list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { 404 1.5 riastrad if (bridge->funcs->enable) 405 1.5 riastrad bridge->funcs->enable(bridge); 406 1.5 riastrad } 407 1.5 riastrad } 408 1.5 riastrad EXPORT_SYMBOL(drm_bridge_chain_enable); 409 1.5 riastrad 410 1.5 riastrad /** 411 1.5 riastrad * drm_atomic_bridge_chain_disable - disables all bridges in the encoder chain 412 1.5 riastrad * @bridge: bridge control structure 413 1.5 riastrad * @old_state: old atomic state 414 1.5 riastrad * 415 1.5 riastrad * Calls &drm_bridge_funcs.atomic_disable (falls back on 416 1.5 riastrad * &drm_bridge_funcs.disable) op for all the bridges in the encoder chain, 417 1.5 riastrad * starting from the last bridge to the first. These are called before calling 418 1.5 riastrad * &drm_encoder_helper_funcs.atomic_disable 419 1.5 riastrad * 420 1.5 riastrad * Note: the bridge passed should be the one closest to the encoder 421 1.5 riastrad */ 422 1.5 riastrad void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge, 423 1.5 riastrad struct drm_atomic_state *old_state) 424 1.5 riastrad { 425 1.5 riastrad struct drm_encoder *encoder; 426 1.5 riastrad struct drm_bridge *iter; 427 1.5 riastrad 428 1.5 riastrad if (!bridge) 429 1.5 riastrad return; 430 1.5 riastrad 431 1.5 riastrad encoder = bridge->encoder; 432 1.5 riastrad list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { 433 1.5 riastrad if (iter->funcs->atomic_disable) 434 1.5 riastrad iter->funcs->atomic_disable(iter, old_state); 435 1.5 riastrad else if (iter->funcs->disable) 436 1.5 riastrad iter->funcs->disable(iter); 437 1.5 riastrad 438 1.5 riastrad if (iter == bridge) 439 1.5 riastrad break; 440 1.5 riastrad } 441 1.5 riastrad } 442 1.5 riastrad EXPORT_SYMBOL(drm_atomic_bridge_chain_disable); 443 1.5 riastrad 444 1.5 riastrad /** 445 1.5 riastrad * drm_atomic_bridge_chain_post_disable - cleans up after disabling all bridges 446 1.5 riastrad * in the encoder chain 447 1.5 riastrad * @bridge: bridge control structure 448 1.5 riastrad * @old_state: old atomic state 449 1.5 riastrad * 450 1.5 riastrad * Calls &drm_bridge_funcs.atomic_post_disable (falls back on 451 1.5 riastrad * &drm_bridge_funcs.post_disable) op for all the bridges in the encoder chain, 452 1.5 riastrad * starting from the first bridge to the last. These are called after completing 453 1.5 riastrad * &drm_encoder_helper_funcs.atomic_disable 454 1.5 riastrad * 455 1.5 riastrad * Note: the bridge passed should be the one closest to the encoder 456 1.5 riastrad */ 457 1.5 riastrad void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge, 458 1.5 riastrad struct drm_atomic_state *old_state) 459 1.5 riastrad { 460 1.5 riastrad struct drm_encoder *encoder; 461 1.5 riastrad 462 1.5 riastrad if (!bridge) 463 1.5 riastrad return; 464 1.5 riastrad 465 1.5 riastrad encoder = bridge->encoder; 466 1.5 riastrad list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { 467 1.5 riastrad if (bridge->funcs->atomic_post_disable) 468 1.5 riastrad bridge->funcs->atomic_post_disable(bridge, old_state); 469 1.5 riastrad else if (bridge->funcs->post_disable) 470 1.5 riastrad bridge->funcs->post_disable(bridge); 471 1.5 riastrad } 472 1.5 riastrad } 473 1.5 riastrad EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable); 474 1.1 riastrad 475 1.5 riastrad /** 476 1.5 riastrad * drm_atomic_bridge_chain_pre_enable - prepares for enabling all bridges in 477 1.5 riastrad * the encoder chain 478 1.5 riastrad * @bridge: bridge control structure 479 1.5 riastrad * @old_state: old atomic state 480 1.5 riastrad * 481 1.5 riastrad * Calls &drm_bridge_funcs.atomic_pre_enable (falls back on 482 1.5 riastrad * &drm_bridge_funcs.pre_enable) op for all the bridges in the encoder chain, 483 1.5 riastrad * starting from the last bridge to the first. These are called before calling 484 1.5 riastrad * &drm_encoder_helper_funcs.atomic_enable 485 1.5 riastrad * 486 1.5 riastrad * Note: the bridge passed should be the one closest to the encoder 487 1.5 riastrad */ 488 1.5 riastrad void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge, 489 1.5 riastrad struct drm_atomic_state *old_state) 490 1.5 riastrad { 491 1.5 riastrad struct drm_encoder *encoder; 492 1.5 riastrad struct drm_bridge *iter; 493 1.5 riastrad 494 1.5 riastrad if (!bridge) 495 1.5 riastrad return; 496 1.5 riastrad 497 1.5 riastrad encoder = bridge->encoder; 498 1.5 riastrad list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { 499 1.5 riastrad if (iter->funcs->atomic_pre_enable) 500 1.5 riastrad iter->funcs->atomic_pre_enable(iter, old_state); 501 1.5 riastrad else if (iter->funcs->pre_enable) 502 1.5 riastrad iter->funcs->pre_enable(iter); 503 1.5 riastrad 504 1.5 riastrad if (iter == bridge) 505 1.5 riastrad break; 506 1.5 riastrad } 507 1.5 riastrad } 508 1.5 riastrad EXPORT_SYMBOL(drm_atomic_bridge_chain_pre_enable); 509 1.5 riastrad 510 1.5 riastrad /** 511 1.5 riastrad * drm_atomic_bridge_chain_enable - enables all bridges in the encoder chain 512 1.5 riastrad * @bridge: bridge control structure 513 1.5 riastrad * @old_state: old atomic state 514 1.5 riastrad * 515 1.5 riastrad * Calls &drm_bridge_funcs.atomic_enable (falls back on 516 1.5 riastrad * &drm_bridge_funcs.enable) op for all the bridges in the encoder chain, 517 1.5 riastrad * starting from the first bridge to the last. These are called after completing 518 1.5 riastrad * &drm_encoder_helper_funcs.atomic_enable 519 1.5 riastrad * 520 1.5 riastrad * Note: the bridge passed should be the one closest to the encoder 521 1.5 riastrad */ 522 1.5 riastrad void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge, 523 1.5 riastrad struct drm_atomic_state *old_state) 524 1.5 riastrad { 525 1.5 riastrad struct drm_encoder *encoder; 526 1.5 riastrad 527 1.5 riastrad if (!bridge) 528 1.5 riastrad return; 529 1.5 riastrad 530 1.5 riastrad encoder = bridge->encoder; 531 1.5 riastrad list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { 532 1.5 riastrad if (bridge->funcs->atomic_enable) 533 1.5 riastrad bridge->funcs->atomic_enable(bridge, old_state); 534 1.5 riastrad else if (bridge->funcs->enable) 535 1.5 riastrad bridge->funcs->enable(bridge); 536 1.5 riastrad } 537 1.1 riastrad } 538 1.5 riastrad EXPORT_SYMBOL(drm_atomic_bridge_chain_enable); 539 1.1 riastrad 540 1.1 riastrad #ifdef CONFIG_OF 541 1.1 riastrad /** 542 1.1 riastrad * of_drm_find_bridge - find the bridge corresponding to the device node in 543 1.1 riastrad * the global bridge list 544 1.1 riastrad * 545 1.1 riastrad * @np: device node 546 1.1 riastrad * 547 1.1 riastrad * RETURNS: 548 1.1 riastrad * drm_bridge control struct on success, NULL on failure 549 1.1 riastrad */ 550 1.1 riastrad struct drm_bridge *of_drm_find_bridge(struct device_node *np) 551 1.1 riastrad { 552 1.1 riastrad struct drm_bridge *bridge; 553 1.1 riastrad 554 1.1 riastrad mutex_lock(&bridge_lock); 555 1.1 riastrad 556 1.1 riastrad list_for_each_entry(bridge, &bridge_list, list) { 557 1.1 riastrad if (bridge->of_node == np) { 558 1.1 riastrad mutex_unlock(&bridge_lock); 559 1.1 riastrad return bridge; 560 1.1 riastrad } 561 1.1 riastrad } 562 1.1 riastrad 563 1.1 riastrad mutex_unlock(&bridge_lock); 564 1.1 riastrad return NULL; 565 1.1 riastrad } 566 1.1 riastrad EXPORT_SYMBOL(of_drm_find_bridge); 567 1.1 riastrad #endif 568 1.1 riastrad 569 1.1 riastrad MODULE_AUTHOR("Ajay Kumar <ajaykumar.rs (at) samsung.com>"); 570 1.1 riastrad MODULE_DESCRIPTION("DRM bridge infrastructure"); 571 1.1 riastrad MODULE_LICENSE("GPL and additional rights"); 572