| File: | dev/pci/drm/drm_bridge.c |
| Warning: | line 875, column 9 Assigned value is garbage or undefined |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 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/media-bus-format.h> | |||
| 26 | #include <linux/module.h> | |||
| 27 | #include <linux/mutex.h> | |||
| 28 | ||||
| 29 | #include <drm/drm_atomic_state_helper.h> | |||
| 30 | #include <drm/drm_bridge.h> | |||
| 31 | #include <drm/drm_encoder.h> | |||
| 32 | #include <drm/drm_of.h> | |||
| 33 | #include <drm/drm_print.h> | |||
| 34 | ||||
| 35 | #include "drm_crtc_internal.h" | |||
| 36 | ||||
| 37 | /** | |||
| 38 | * DOC: overview | |||
| 39 | * | |||
| 40 | * &struct drm_bridge represents a device that hangs on to an encoder. These are | |||
| 41 | * handy when a regular &drm_encoder entity isn't enough to represent the entire | |||
| 42 | * encoder chain. | |||
| 43 | * | |||
| 44 | * A bridge is always attached to a single &drm_encoder at a time, but can be | |||
| 45 | * either connected to it directly, or through a chain of bridges:: | |||
| 46 | * | |||
| 47 | * [ CRTC ---> ] Encoder ---> Bridge A ---> Bridge B | |||
| 48 | * | |||
| 49 | * Here, the output of the encoder feeds to bridge A, and that furthers feeds to | |||
| 50 | * bridge B. Bridge chains can be arbitrarily long, and shall be fully linear: | |||
| 51 | * Chaining multiple bridges to the output of a bridge, or the same bridge to | |||
| 52 | * the output of different bridges, is not supported. | |||
| 53 | * | |||
| 54 | * &drm_bridge, like &drm_panel, aren't &drm_mode_object entities like planes, | |||
| 55 | * CRTCs, encoders or connectors and hence are not visible to userspace. They | |||
| 56 | * just provide additional hooks to get the desired output at the end of the | |||
| 57 | * encoder chain. | |||
| 58 | */ | |||
| 59 | ||||
| 60 | /** | |||
| 61 | * DOC: display driver integration | |||
| 62 | * | |||
| 63 | * Display drivers are responsible for linking encoders with the first bridge | |||
| 64 | * in the chains. This is done by acquiring the appropriate bridge with | |||
| 65 | * devm_drm_of_get_bridge(). Once acquired, the bridge shall be attached to the | |||
| 66 | * encoder with a call to drm_bridge_attach(). | |||
| 67 | * | |||
| 68 | * Bridges are responsible for linking themselves with the next bridge in the | |||
| 69 | * chain, if any. This is done the same way as for encoders, with the call to | |||
| 70 | * drm_bridge_attach() occurring in the &drm_bridge_funcs.attach operation. | |||
| 71 | * | |||
| 72 | * Once these links are created, the bridges can participate along with encoder | |||
| 73 | * functions to perform mode validation and fixup (through | |||
| 74 | * drm_bridge_chain_mode_valid() and drm_atomic_bridge_chain_check()), mode | |||
| 75 | * setting (through drm_bridge_chain_mode_set()), enable (through | |||
| 76 | * drm_atomic_bridge_chain_pre_enable() and drm_atomic_bridge_chain_enable()) | |||
| 77 | * and disable (through drm_atomic_bridge_chain_disable() and | |||
| 78 | * drm_atomic_bridge_chain_post_disable()). Those functions call the | |||
| 79 | * corresponding operations provided in &drm_bridge_funcs in sequence for all | |||
| 80 | * bridges in the chain. | |||
| 81 | * | |||
| 82 | * For display drivers that use the atomic helpers | |||
| 83 | * drm_atomic_helper_check_modeset(), | |||
| 84 | * drm_atomic_helper_commit_modeset_enables() and | |||
| 85 | * drm_atomic_helper_commit_modeset_disables() (either directly in hand-rolled | |||
| 86 | * commit check and commit tail handlers, or through the higher-level | |||
| 87 | * drm_atomic_helper_check() and drm_atomic_helper_commit_tail() or | |||
| 88 | * drm_atomic_helper_commit_tail_rpm() helpers), this is done transparently and | |||
| 89 | * requires no intervention from the driver. For other drivers, the relevant | |||
| 90 | * DRM bridge chain functions shall be called manually. | |||
| 91 | * | |||
| 92 | * Bridges also participate in implementing the &drm_connector at the end of | |||
| 93 | * the bridge chain. Display drivers may use the drm_bridge_connector_init() | |||
| 94 | * helper to create the &drm_connector, or implement it manually on top of the | |||
| 95 | * connector-related operations exposed by the bridge (see the overview | |||
| 96 | * documentation of bridge operations for more details). | |||
| 97 | */ | |||
| 98 | ||||
| 99 | /** | |||
| 100 | * DOC: special care dsi | |||
| 101 | * | |||
| 102 | * The interaction between the bridges and other frameworks involved in | |||
| 103 | * the probing of the upstream driver and the bridge driver can be | |||
| 104 | * challenging. Indeed, there's multiple cases that needs to be | |||
| 105 | * considered: | |||
| 106 | * | |||
| 107 | * - The upstream driver doesn't use the component framework and isn't a | |||
| 108 | * MIPI-DSI host. In this case, the bridge driver will probe at some | |||
| 109 | * point and the upstream driver should try to probe again by returning | |||
| 110 | * EPROBE_DEFER as long as the bridge driver hasn't probed. | |||
| 111 | * | |||
| 112 | * - The upstream driver doesn't use the component framework, but is a | |||
| 113 | * MIPI-DSI host. The bridge device uses the MIPI-DCS commands to be | |||
| 114 | * controlled. In this case, the bridge device is a child of the | |||
| 115 | * display device and when it will probe it's assured that the display | |||
| 116 | * device (and MIPI-DSI host) is present. The upstream driver will be | |||
| 117 | * assured that the bridge driver is connected between the | |||
| 118 | * &mipi_dsi_host_ops.attach and &mipi_dsi_host_ops.detach operations. | |||
| 119 | * Therefore, it must run mipi_dsi_host_register() in its probe | |||
| 120 | * function, and then run drm_bridge_attach() in its | |||
| 121 | * &mipi_dsi_host_ops.attach hook. | |||
| 122 | * | |||
| 123 | * - The upstream driver uses the component framework and is a MIPI-DSI | |||
| 124 | * host. The bridge device uses the MIPI-DCS commands to be | |||
| 125 | * controlled. This is the same situation than above, and can run | |||
| 126 | * mipi_dsi_host_register() in either its probe or bind hooks. | |||
| 127 | * | |||
| 128 | * - The upstream driver uses the component framework and is a MIPI-DSI | |||
| 129 | * host. The bridge device uses a separate bus (such as I2C) to be | |||
| 130 | * controlled. In this case, there's no correlation between the probe | |||
| 131 | * of the bridge and upstream drivers, so care must be taken to avoid | |||
| 132 | * an endless EPROBE_DEFER loop, with each driver waiting for the | |||
| 133 | * other to probe. | |||
| 134 | * | |||
| 135 | * The ideal pattern to cover the last item (and all the others in the | |||
| 136 | * MIPI-DSI host driver case) is to split the operations like this: | |||
| 137 | * | |||
| 138 | * - The MIPI-DSI host driver must run mipi_dsi_host_register() in its | |||
| 139 | * probe hook. It will make sure that the MIPI-DSI host sticks around, | |||
| 140 | * and that the driver's bind can be called. | |||
| 141 | * | |||
| 142 | * - In its probe hook, the bridge driver must try to find its MIPI-DSI | |||
| 143 | * host, register as a MIPI-DSI device and attach the MIPI-DSI device | |||
| 144 | * to its host. The bridge driver is now functional. | |||
| 145 | * | |||
| 146 | * - In its &struct mipi_dsi_host_ops.attach hook, the MIPI-DSI host can | |||
| 147 | * now add its component. Its bind hook will now be called and since | |||
| 148 | * the bridge driver is attached and registered, we can now look for | |||
| 149 | * and attach it. | |||
| 150 | * | |||
| 151 | * At this point, we're now certain that both the upstream driver and | |||
| 152 | * the bridge driver are functional and we can't have a deadlock-like | |||
| 153 | * situation when probing. | |||
| 154 | */ | |||
| 155 | ||||
| 156 | static DEFINE_MUTEX(bridge_lock)struct rwlock bridge_lock = { 0, "bridge_lock" }; | |||
| 157 | static DRM_LIST_HEAD(bridge_list)struct list_head bridge_list = { &(bridge_list), &(bridge_list ) }; | |||
| 158 | ||||
| 159 | /** | |||
| 160 | * drm_bridge_add - add the given bridge to the global bridge list | |||
| 161 | * | |||
| 162 | * @bridge: bridge control structure | |||
| 163 | */ | |||
| 164 | void drm_bridge_add(struct drm_bridge *bridge) | |||
| 165 | { | |||
| 166 | rw_init(&bridge->hpd_mutex, "brhpd")_rw_init_flags(&bridge->hpd_mutex, "brhpd", 0, ((void * )0)); | |||
| 167 | ||||
| 168 | mutex_lock(&bridge_lock)rw_enter_write(&bridge_lock); | |||
| 169 | list_add_tail(&bridge->list, &bridge_list); | |||
| 170 | mutex_unlock(&bridge_lock)rw_exit_write(&bridge_lock); | |||
| 171 | } | |||
| 172 | EXPORT_SYMBOL(drm_bridge_add); | |||
| 173 | ||||
| 174 | #ifdef notyet | |||
| 175 | static void drm_bridge_remove_void(void *bridge) | |||
| 176 | { | |||
| 177 | drm_bridge_remove(bridge); | |||
| 178 | } | |||
| 179 | #endif | |||
| 180 | ||||
| 181 | /** | |||
| 182 | * devm_drm_bridge_add - devm managed version of drm_bridge_add() | |||
| 183 | * | |||
| 184 | * @dev: device to tie the bridge lifetime to | |||
| 185 | * @bridge: bridge control structure | |||
| 186 | * | |||
| 187 | * This is the managed version of drm_bridge_add() which automatically | |||
| 188 | * calls drm_bridge_remove() when @dev is unbound. | |||
| 189 | * | |||
| 190 | * Return: 0 if no error or negative error code. | |||
| 191 | */ | |||
| 192 | int devm_drm_bridge_add(struct device *dev, struct drm_bridge *bridge) | |||
| 193 | { | |||
| 194 | drm_bridge_add(bridge); | |||
| 195 | #ifdef notyet | |||
| 196 | return devm_add_action_or_reset(dev, drm_bridge_remove_void, bridge); | |||
| 197 | #else | |||
| 198 | STUB()do { printf("%s: stub\n", __func__); } while(0); | |||
| 199 | return -ENOSYS78; | |||
| 200 | #endif | |||
| 201 | } | |||
| 202 | EXPORT_SYMBOL(devm_drm_bridge_add); | |||
| 203 | ||||
| 204 | /** | |||
| 205 | * drm_bridge_remove - remove the given bridge from the global bridge list | |||
| 206 | * | |||
| 207 | * @bridge: bridge control structure | |||
| 208 | */ | |||
| 209 | void drm_bridge_remove(struct drm_bridge *bridge) | |||
| 210 | { | |||
| 211 | mutex_lock(&bridge_lock)rw_enter_write(&bridge_lock); | |||
| 212 | list_del_init(&bridge->list); | |||
| 213 | mutex_unlock(&bridge_lock)rw_exit_write(&bridge_lock); | |||
| 214 | ||||
| 215 | mutex_destroy(&bridge->hpd_mutex); | |||
| 216 | } | |||
| 217 | EXPORT_SYMBOL(drm_bridge_remove); | |||
| 218 | ||||
| 219 | static struct drm_private_state * | |||
| 220 | drm_bridge_atomic_duplicate_priv_state(struct drm_private_obj *obj) | |||
| 221 | { | |||
| 222 | struct drm_bridge *bridge = drm_priv_to_bridge(obj); | |||
| 223 | struct drm_bridge_state *state; | |||
| 224 | ||||
| 225 | state = bridge->funcs->atomic_duplicate_state(bridge); | |||
| 226 | return state ? &state->base : NULL((void *)0); | |||
| 227 | } | |||
| 228 | ||||
| 229 | static void | |||
| 230 | drm_bridge_atomic_destroy_priv_state(struct drm_private_obj *obj, | |||
| 231 | struct drm_private_state *s) | |||
| 232 | { | |||
| 233 | struct drm_bridge_state *state = drm_priv_to_bridge_state(s); | |||
| 234 | struct drm_bridge *bridge = drm_priv_to_bridge(obj); | |||
| 235 | ||||
| 236 | bridge->funcs->atomic_destroy_state(bridge, state); | |||
| 237 | } | |||
| 238 | ||||
| 239 | static const struct drm_private_state_funcs drm_bridge_priv_state_funcs = { | |||
| 240 | .atomic_duplicate_state = drm_bridge_atomic_duplicate_priv_state, | |||
| 241 | .atomic_destroy_state = drm_bridge_atomic_destroy_priv_state, | |||
| 242 | }; | |||
| 243 | ||||
| 244 | /** | |||
| 245 | * drm_bridge_attach - attach the bridge to an encoder's chain | |||
| 246 | * | |||
| 247 | * @encoder: DRM encoder | |||
| 248 | * @bridge: bridge to attach | |||
| 249 | * @previous: previous bridge in the chain (optional) | |||
| 250 | * @flags: DRM_BRIDGE_ATTACH_* flags | |||
| 251 | * | |||
| 252 | * Called by a kms driver to link the bridge to an encoder's chain. The previous | |||
| 253 | * argument specifies the previous bridge in the chain. If NULL, the bridge is | |||
| 254 | * linked directly at the encoder's output. Otherwise it is linked at the | |||
| 255 | * previous bridge's output. | |||
| 256 | * | |||
| 257 | * If non-NULL the previous bridge must be already attached by a call to this | |||
| 258 | * function. | |||
| 259 | * | |||
| 260 | * Note that bridges attached to encoders are auto-detached during encoder | |||
| 261 | * cleanup in drm_encoder_cleanup(), so drm_bridge_attach() should generally | |||
| 262 | * *not* be balanced with a drm_bridge_detach() in driver code. | |||
| 263 | * | |||
| 264 | * RETURNS: | |||
| 265 | * Zero on success, error code on failure | |||
| 266 | */ | |||
| 267 | int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge, | |||
| 268 | struct drm_bridge *previous, | |||
| 269 | enum drm_bridge_attach_flags flags) | |||
| 270 | { | |||
| 271 | int ret; | |||
| 272 | ||||
| 273 | if (!encoder || !bridge) | |||
| 274 | return -EINVAL22; | |||
| 275 | ||||
| 276 | if (previous && (!previous->dev || previous->encoder != encoder)) | |||
| 277 | return -EINVAL22; | |||
| 278 | ||||
| 279 | if (bridge->dev) | |||
| 280 | return -EBUSY16; | |||
| 281 | ||||
| 282 | bridge->dev = encoder->dev; | |||
| 283 | bridge->encoder = encoder; | |||
| 284 | ||||
| 285 | if (previous) | |||
| 286 | list_add(&bridge->chain_node, &previous->chain_node); | |||
| 287 | else | |||
| 288 | list_add(&bridge->chain_node, &encoder->bridge_chain); | |||
| 289 | ||||
| 290 | if (bridge->funcs->attach) { | |||
| 291 | ret = bridge->funcs->attach(bridge, flags); | |||
| 292 | if (ret < 0) | |||
| 293 | goto err_reset_bridge; | |||
| 294 | } | |||
| 295 | ||||
| 296 | if (bridge->funcs->atomic_reset) { | |||
| 297 | struct drm_bridge_state *state; | |||
| 298 | ||||
| 299 | state = bridge->funcs->atomic_reset(bridge); | |||
| 300 | if (IS_ERR(state)) { | |||
| 301 | ret = PTR_ERR(state); | |||
| 302 | goto err_detach_bridge; | |||
| 303 | } | |||
| 304 | ||||
| 305 | drm_atomic_private_obj_init(bridge->dev, &bridge->base, | |||
| 306 | &state->base, | |||
| 307 | &drm_bridge_priv_state_funcs); | |||
| 308 | } | |||
| 309 | ||||
| 310 | return 0; | |||
| 311 | ||||
| 312 | err_detach_bridge: | |||
| 313 | if (bridge->funcs->detach) | |||
| 314 | bridge->funcs->detach(bridge); | |||
| 315 | ||||
| 316 | err_reset_bridge: | |||
| 317 | bridge->dev = NULL((void *)0); | |||
| 318 | bridge->encoder = NULL((void *)0); | |||
| 319 | list_del(&bridge->chain_node); | |||
| 320 | ||||
| 321 | #ifdef CONFIG_OF | |||
| 322 | DRM_ERROR("failed to attach bridge %pOF to encoder %s: %d\n",__drm_err("failed to attach bridge %pOF to encoder %s: %d\n", bridge->of_node, encoder->name, ret) | |||
| 323 | bridge->of_node, encoder->name, ret)__drm_err("failed to attach bridge %pOF to encoder %s: %d\n", bridge->of_node, encoder->name, ret); | |||
| 324 | #else | |||
| 325 | DRM_ERROR("failed to attach bridge to encoder %s: %d\n",__drm_err("failed to attach bridge to encoder %s: %d\n", encoder ->name, ret) | |||
| 326 | encoder->name, ret)__drm_err("failed to attach bridge to encoder %s: %d\n", encoder ->name, ret); | |||
| 327 | #endif | |||
| 328 | ||||
| 329 | return ret; | |||
| 330 | } | |||
| 331 | EXPORT_SYMBOL(drm_bridge_attach); | |||
| 332 | ||||
| 333 | void drm_bridge_detach(struct drm_bridge *bridge) | |||
| 334 | { | |||
| 335 | if (WARN_ON(!bridge)({ int __ret = !!(!bridge); if (__ret) printf("WARNING %s failed at %s:%d\n" , "!bridge", "/usr/src/sys/dev/pci/drm/drm_bridge.c", 335); __builtin_expect (!!(__ret), 0); })) | |||
| 336 | return; | |||
| 337 | ||||
| 338 | if (WARN_ON(!bridge->dev)({ int __ret = !!(!bridge->dev); if (__ret) printf("WARNING %s failed at %s:%d\n" , "!bridge->dev", "/usr/src/sys/dev/pci/drm/drm_bridge.c", 338); __builtin_expect(!!(__ret), 0); })) | |||
| 339 | return; | |||
| 340 | ||||
| 341 | if (bridge->funcs->atomic_reset) | |||
| 342 | drm_atomic_private_obj_fini(&bridge->base); | |||
| 343 | ||||
| 344 | if (bridge->funcs->detach) | |||
| 345 | bridge->funcs->detach(bridge); | |||
| 346 | ||||
| 347 | list_del(&bridge->chain_node); | |||
| 348 | bridge->dev = NULL((void *)0); | |||
| 349 | } | |||
| 350 | ||||
| 351 | /** | |||
| 352 | * DOC: bridge operations | |||
| 353 | * | |||
| 354 | * Bridge drivers expose operations through the &drm_bridge_funcs structure. | |||
| 355 | * The DRM internals (atomic and CRTC helpers) use the helpers defined in | |||
| 356 | * drm_bridge.c to call bridge operations. Those operations are divided in | |||
| 357 | * three big categories to support different parts of the bridge usage. | |||
| 358 | * | |||
| 359 | * - The encoder-related operations support control of the bridges in the | |||
| 360 | * chain, and are roughly counterparts to the &drm_encoder_helper_funcs | |||
| 361 | * operations. They are used by the legacy CRTC and the atomic modeset | |||
| 362 | * helpers to perform mode validation, fixup and setting, and enable and | |||
| 363 | * disable the bridge automatically. | |||
| 364 | * | |||
| 365 | * The enable and disable operations are split in | |||
| 366 | * &drm_bridge_funcs.pre_enable, &drm_bridge_funcs.enable, | |||
| 367 | * &drm_bridge_funcs.disable and &drm_bridge_funcs.post_disable to provide | |||
| 368 | * finer-grained control. | |||
| 369 | * | |||
| 370 | * Bridge drivers may implement the legacy version of those operations, or | |||
| 371 | * the atomic version (prefixed with atomic\_), in which case they shall also | |||
| 372 | * implement the atomic state bookkeeping operations | |||
| 373 | * (&drm_bridge_funcs.atomic_duplicate_state, | |||
| 374 | * &drm_bridge_funcs.atomic_destroy_state and &drm_bridge_funcs.reset). | |||
| 375 | * Mixing atomic and non-atomic versions of the operations is not supported. | |||
| 376 | * | |||
| 377 | * - The bus format negotiation operations | |||
| 378 | * &drm_bridge_funcs.atomic_get_output_bus_fmts and | |||
| 379 | * &drm_bridge_funcs.atomic_get_input_bus_fmts allow bridge drivers to | |||
| 380 | * negotiate the formats transmitted between bridges in the chain when | |||
| 381 | * multiple formats are supported. Negotiation for formats is performed | |||
| 382 | * transparently for display drivers by the atomic modeset helpers. Only | |||
| 383 | * atomic versions of those operations exist, bridge drivers that need to | |||
| 384 | * implement them shall thus also implement the atomic version of the | |||
| 385 | * encoder-related operations. This feature is not supported by the legacy | |||
| 386 | * CRTC helpers. | |||
| 387 | * | |||
| 388 | * - The connector-related operations support implementing a &drm_connector | |||
| 389 | * based on a chain of bridges. DRM bridges traditionally create a | |||
| 390 | * &drm_connector for bridges meant to be used at the end of the chain. This | |||
| 391 | * puts additional burden on bridge drivers, especially for bridges that may | |||
| 392 | * be used in the middle of a chain or at the end of it. Furthermore, it | |||
| 393 | * requires all operations of the &drm_connector to be handled by a single | |||
| 394 | * bridge, which doesn't always match the hardware architecture. | |||
| 395 | * | |||
| 396 | * To simplify bridge drivers and make the connector implementation more | |||
| 397 | * flexible, a new model allows bridges to unconditionally skip creation of | |||
| 398 | * &drm_connector and instead expose &drm_bridge_funcs operations to support | |||
| 399 | * an externally-implemented &drm_connector. Those operations are | |||
| 400 | * &drm_bridge_funcs.detect, &drm_bridge_funcs.get_modes, | |||
| 401 | * &drm_bridge_funcs.get_edid, &drm_bridge_funcs.hpd_notify, | |||
| 402 | * &drm_bridge_funcs.hpd_enable and &drm_bridge_funcs.hpd_disable. When | |||
| 403 | * implemented, display drivers shall create a &drm_connector instance for | |||
| 404 | * each chain of bridges, and implement those connector instances based on | |||
| 405 | * the bridge connector operations. | |||
| 406 | * | |||
| 407 | * Bridge drivers shall implement the connector-related operations for all | |||
| 408 | * the features that the bridge hardware support. For instance, if a bridge | |||
| 409 | * supports reading EDID, the &drm_bridge_funcs.get_edid shall be | |||
| 410 | * implemented. This however doesn't mean that the DDC lines are wired to the | |||
| 411 | * bridge on a particular platform, as they could also be connected to an I2C | |||
| 412 | * controller of the SoC. Support for the connector-related operations on the | |||
| 413 | * running platform is reported through the &drm_bridge.ops flags. Bridge | |||
| 414 | * drivers shall detect which operations they can support on the platform | |||
| 415 | * (usually this information is provided by ACPI or DT), and set the | |||
| 416 | * &drm_bridge.ops flags for all supported operations. A flag shall only be | |||
| 417 | * set if the corresponding &drm_bridge_funcs operation is implemented, but | |||
| 418 | * an implemented operation doesn't necessarily imply that the corresponding | |||
| 419 | * flag will be set. Display drivers shall use the &drm_bridge.ops flags to | |||
| 420 | * decide which bridge to delegate a connector operation to. This mechanism | |||
| 421 | * allows providing a single static const &drm_bridge_funcs instance in | |||
| 422 | * bridge drivers, improving security by storing function pointers in | |||
| 423 | * read-only memory. | |||
| 424 | * | |||
| 425 | * In order to ease transition, bridge drivers may support both the old and | |||
| 426 | * new models by making connector creation optional and implementing the | |||
| 427 | * connected-related bridge operations. Connector creation is then controlled | |||
| 428 | * by the flags argument to the drm_bridge_attach() function. Display drivers | |||
| 429 | * that support the new model and create connectors themselves shall set the | |||
| 430 | * %DRM_BRIDGE_ATTACH_NO_CONNECTOR flag, and bridge drivers shall then skip | |||
| 431 | * connector creation. For intermediate bridges in the chain, the flag shall | |||
| 432 | * be passed to the drm_bridge_attach() call for the downstream bridge. | |||
| 433 | * Bridge drivers that implement the new model only shall return an error | |||
| 434 | * from their &drm_bridge_funcs.attach handler when the | |||
| 435 | * %DRM_BRIDGE_ATTACH_NO_CONNECTOR flag is not set. New display drivers | |||
| 436 | * should use the new model, and convert the bridge drivers they use if | |||
| 437 | * needed, in order to gradually transition to the new model. | |||
| 438 | */ | |||
| 439 | ||||
| 440 | /** | |||
| 441 | * drm_bridge_chain_mode_fixup - fixup proposed mode for all bridges in the | |||
| 442 | * encoder chain | |||
| 443 | * @bridge: bridge control structure | |||
| 444 | * @mode: desired mode to be set for the bridge | |||
| 445 | * @adjusted_mode: updated mode that works for this bridge | |||
| 446 | * | |||
| 447 | * Calls &drm_bridge_funcs.mode_fixup for all the bridges in the | |||
| 448 | * encoder chain, starting from the first bridge to the last. | |||
| 449 | * | |||
| 450 | * Note: the bridge passed should be the one closest to the encoder | |||
| 451 | * | |||
| 452 | * RETURNS: | |||
| 453 | * true on success, false on failure | |||
| 454 | */ | |||
| 455 | bool_Bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge, | |||
| 456 | const struct drm_display_mode *mode, | |||
| 457 | struct drm_display_mode *adjusted_mode) | |||
| 458 | { | |||
| 459 | struct drm_encoder *encoder; | |||
| 460 | ||||
| 461 | if (!bridge) | |||
| 462 | return true1; | |||
| 463 | ||||
| 464 | encoder = bridge->encoder; | |||
| 465 | list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node)for (; &bridge->chain_node != (&encoder->bridge_chain ); bridge = ({ const __typeof( ((__typeof(*bridge) *)0)->chain_node ) *__mptr = (bridge->chain_node.next); (__typeof(*bridge) *)( (char *)__mptr - __builtin_offsetof(__typeof(*bridge), chain_node ) );})) { | |||
| 466 | if (!bridge->funcs->mode_fixup) | |||
| 467 | continue; | |||
| 468 | ||||
| 469 | if (!bridge->funcs->mode_fixup(bridge, mode, adjusted_mode)) | |||
| 470 | return false0; | |||
| 471 | } | |||
| 472 | ||||
| 473 | return true1; | |||
| 474 | } | |||
| 475 | EXPORT_SYMBOL(drm_bridge_chain_mode_fixup); | |||
| 476 | ||||
| 477 | /** | |||
| 478 | * drm_bridge_chain_mode_valid - validate the mode against all bridges in the | |||
| 479 | * encoder chain. | |||
| 480 | * @bridge: bridge control structure | |||
| 481 | * @info: display info against which the mode shall be validated | |||
| 482 | * @mode: desired mode to be validated | |||
| 483 | * | |||
| 484 | * Calls &drm_bridge_funcs.mode_valid for all the bridges in the encoder | |||
| 485 | * chain, starting from the first bridge to the last. If at least one bridge | |||
| 486 | * does not accept the mode the function returns the error code. | |||
| 487 | * | |||
| 488 | * Note: the bridge passed should be the one closest to the encoder. | |||
| 489 | * | |||
| 490 | * RETURNS: | |||
| 491 | * MODE_OK on success, drm_mode_status Enum error code on failure | |||
| 492 | */ | |||
| 493 | enum drm_mode_status | |||
| 494 | drm_bridge_chain_mode_valid(struct drm_bridge *bridge, | |||
| 495 | const struct drm_display_info *info, | |||
| 496 | const struct drm_display_mode *mode) | |||
| 497 | { | |||
| 498 | struct drm_encoder *encoder; | |||
| 499 | ||||
| 500 | if (!bridge) | |||
| 501 | return MODE_OK; | |||
| 502 | ||||
| 503 | encoder = bridge->encoder; | |||
| 504 | list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node)for (; &bridge->chain_node != (&encoder->bridge_chain ); bridge = ({ const __typeof( ((__typeof(*bridge) *)0)->chain_node ) *__mptr = (bridge->chain_node.next); (__typeof(*bridge) *)( (char *)__mptr - __builtin_offsetof(__typeof(*bridge), chain_node ) );})) { | |||
| 505 | enum drm_mode_status ret; | |||
| 506 | ||||
| 507 | if (!bridge->funcs->mode_valid) | |||
| 508 | continue; | |||
| 509 | ||||
| 510 | ret = bridge->funcs->mode_valid(bridge, info, mode); | |||
| 511 | if (ret != MODE_OK) | |||
| 512 | return ret; | |||
| 513 | } | |||
| 514 | ||||
| 515 | return MODE_OK; | |||
| 516 | } | |||
| 517 | EXPORT_SYMBOL(drm_bridge_chain_mode_valid); | |||
| 518 | ||||
| 519 | /** | |||
| 520 | * drm_bridge_chain_disable - disables all bridges in the encoder chain | |||
| 521 | * @bridge: bridge control structure | |||
| 522 | * | |||
| 523 | * Calls &drm_bridge_funcs.disable op for all the bridges in the encoder | |||
| 524 | * chain, starting from the last bridge to the first. These are called before | |||
| 525 | * calling the encoder's prepare op. | |||
| 526 | * | |||
| 527 | * Note: the bridge passed should be the one closest to the encoder | |||
| 528 | */ | |||
| 529 | void drm_bridge_chain_disable(struct drm_bridge *bridge) | |||
| 530 | { | |||
| 531 | struct drm_encoder *encoder; | |||
| 532 | struct drm_bridge *iter; | |||
| 533 | ||||
| 534 | if (!bridge) | |||
| 535 | return; | |||
| 536 | ||||
| 537 | encoder = bridge->encoder; | |||
| 538 | list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node)for (iter = ({ const __typeof( ((__typeof(*iter) *)0)->chain_node ) *__mptr = ((&encoder->bridge_chain)->prev); (__typeof (*iter) *)( (char *)__mptr - __builtin_offsetof(__typeof(*iter ), chain_node) );}); &iter->chain_node != (&encoder ->bridge_chain); iter = ({ const __typeof( ((__typeof(*iter ) *)0)->chain_node ) *__mptr = (iter->chain_node.prev); (__typeof(*iter) *)( (char *)__mptr - __builtin_offsetof(__typeof (*iter), chain_node) );})) { | |||
| 539 | if (iter->funcs->disable) | |||
| 540 | iter->funcs->disable(iter); | |||
| 541 | ||||
| 542 | if (iter == bridge) | |||
| 543 | break; | |||
| 544 | } | |||
| 545 | } | |||
| 546 | EXPORT_SYMBOL(drm_bridge_chain_disable); | |||
| 547 | ||||
| 548 | /** | |||
| 549 | * drm_bridge_chain_post_disable - cleans up after disabling all bridges in the | |||
| 550 | * encoder chain | |||
| 551 | * @bridge: bridge control structure | |||
| 552 | * | |||
| 553 | * Calls &drm_bridge_funcs.post_disable op for all the bridges in the | |||
| 554 | * encoder chain, starting from the first bridge to the last. These are called | |||
| 555 | * after completing the encoder's prepare op. | |||
| 556 | * | |||
| 557 | * Note: the bridge passed should be the one closest to the encoder | |||
| 558 | */ | |||
| 559 | void drm_bridge_chain_post_disable(struct drm_bridge *bridge) | |||
| 560 | { | |||
| 561 | struct drm_encoder *encoder; | |||
| 562 | ||||
| 563 | if (!bridge) | |||
| 564 | return; | |||
| 565 | ||||
| 566 | encoder = bridge->encoder; | |||
| 567 | list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node)for (; &bridge->chain_node != (&encoder->bridge_chain ); bridge = ({ const __typeof( ((__typeof(*bridge) *)0)->chain_node ) *__mptr = (bridge->chain_node.next); (__typeof(*bridge) *)( (char *)__mptr - __builtin_offsetof(__typeof(*bridge), chain_node ) );})) { | |||
| 568 | if (bridge->funcs->post_disable) | |||
| 569 | bridge->funcs->post_disable(bridge); | |||
| 570 | } | |||
| 571 | } | |||
| 572 | EXPORT_SYMBOL(drm_bridge_chain_post_disable); | |||
| 573 | ||||
| 574 | /** | |||
| 575 | * drm_bridge_chain_mode_set - set proposed mode for all bridges in the | |||
| 576 | * encoder chain | |||
| 577 | * @bridge: bridge control structure | |||
| 578 | * @mode: desired mode to be set for the encoder chain | |||
| 579 | * @adjusted_mode: updated mode that works for this encoder chain | |||
| 580 | * | |||
| 581 | * Calls &drm_bridge_funcs.mode_set op for all the bridges in the | |||
| 582 | * encoder chain, starting from the first bridge to the last. | |||
| 583 | * | |||
| 584 | * Note: the bridge passed should be the one closest to the encoder | |||
| 585 | */ | |||
| 586 | void drm_bridge_chain_mode_set(struct drm_bridge *bridge, | |||
| 587 | const struct drm_display_mode *mode, | |||
| 588 | const struct drm_display_mode *adjusted_mode) | |||
| 589 | { | |||
| 590 | struct drm_encoder *encoder; | |||
| 591 | ||||
| 592 | if (!bridge) | |||
| 593 | return; | |||
| 594 | ||||
| 595 | encoder = bridge->encoder; | |||
| 596 | list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node)for (; &bridge->chain_node != (&encoder->bridge_chain ); bridge = ({ const __typeof( ((__typeof(*bridge) *)0)->chain_node ) *__mptr = (bridge->chain_node.next); (__typeof(*bridge) *)( (char *)__mptr - __builtin_offsetof(__typeof(*bridge), chain_node ) );})) { | |||
| 597 | if (bridge->funcs->mode_set) | |||
| 598 | bridge->funcs->mode_set(bridge, mode, adjusted_mode); | |||
| 599 | } | |||
| 600 | } | |||
| 601 | EXPORT_SYMBOL(drm_bridge_chain_mode_set); | |||
| 602 | ||||
| 603 | /** | |||
| 604 | * drm_bridge_chain_pre_enable - prepares for enabling all bridges in the | |||
| 605 | * encoder chain | |||
| 606 | * @bridge: bridge control structure | |||
| 607 | * | |||
| 608 | * Calls &drm_bridge_funcs.pre_enable op for all the bridges in the encoder | |||
| 609 | * chain, starting from the last bridge to the first. These are called | |||
| 610 | * before calling the encoder's commit op. | |||
| 611 | * | |||
| 612 | * Note: the bridge passed should be the one closest to the encoder | |||
| 613 | */ | |||
| 614 | void drm_bridge_chain_pre_enable(struct drm_bridge *bridge) | |||
| 615 | { | |||
| 616 | struct drm_encoder *encoder; | |||
| 617 | struct drm_bridge *iter; | |||
| 618 | ||||
| 619 | if (!bridge) | |||
| 620 | return; | |||
| 621 | ||||
| 622 | encoder = bridge->encoder; | |||
| 623 | list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node)for (iter = ({ const __typeof( ((__typeof(*iter) *)0)->chain_node ) *__mptr = ((&encoder->bridge_chain)->prev); (__typeof (*iter) *)( (char *)__mptr - __builtin_offsetof(__typeof(*iter ), chain_node) );}); &iter->chain_node != (&encoder ->bridge_chain); iter = ({ const __typeof( ((__typeof(*iter ) *)0)->chain_node ) *__mptr = (iter->chain_node.prev); (__typeof(*iter) *)( (char *)__mptr - __builtin_offsetof(__typeof (*iter), chain_node) );})) { | |||
| 624 | if (iter->funcs->pre_enable) | |||
| 625 | iter->funcs->pre_enable(iter); | |||
| 626 | ||||
| 627 | if (iter == bridge) | |||
| 628 | break; | |||
| 629 | } | |||
| 630 | } | |||
| 631 | EXPORT_SYMBOL(drm_bridge_chain_pre_enable); | |||
| 632 | ||||
| 633 | /** | |||
| 634 | * drm_bridge_chain_enable - enables all bridges in the encoder chain | |||
| 635 | * @bridge: bridge control structure | |||
| 636 | * | |||
| 637 | * Calls &drm_bridge_funcs.enable op for all the bridges in the encoder | |||
| 638 | * chain, starting from the first bridge to the last. These are called | |||
| 639 | * after completing the encoder's commit op. | |||
| 640 | * | |||
| 641 | * Note that the bridge passed should be the one closest to the encoder | |||
| 642 | */ | |||
| 643 | void drm_bridge_chain_enable(struct drm_bridge *bridge) | |||
| 644 | { | |||
| 645 | struct drm_encoder *encoder; | |||
| 646 | ||||
| 647 | if (!bridge) | |||
| 648 | return; | |||
| 649 | ||||
| 650 | encoder = bridge->encoder; | |||
| 651 | list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node)for (; &bridge->chain_node != (&encoder->bridge_chain ); bridge = ({ const __typeof( ((__typeof(*bridge) *)0)->chain_node ) *__mptr = (bridge->chain_node.next); (__typeof(*bridge) *)( (char *)__mptr - __builtin_offsetof(__typeof(*bridge), chain_node ) );})) { | |||
| 652 | if (bridge->funcs->enable) | |||
| 653 | bridge->funcs->enable(bridge); | |||
| 654 | } | |||
| 655 | } | |||
| 656 | EXPORT_SYMBOL(drm_bridge_chain_enable); | |||
| 657 | ||||
| 658 | /** | |||
| 659 | * drm_atomic_bridge_chain_disable - disables all bridges in the encoder chain | |||
| 660 | * @bridge: bridge control structure | |||
| 661 | * @old_state: old atomic state | |||
| 662 | * | |||
| 663 | * Calls &drm_bridge_funcs.atomic_disable (falls back on | |||
| 664 | * &drm_bridge_funcs.disable) op for all the bridges in the encoder chain, | |||
| 665 | * starting from the last bridge to the first. These are called before calling | |||
| 666 | * &drm_encoder_helper_funcs.atomic_disable | |||
| 667 | * | |||
| 668 | * Note: the bridge passed should be the one closest to the encoder | |||
| 669 | */ | |||
| 670 | void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge, | |||
| 671 | struct drm_atomic_state *old_state) | |||
| 672 | { | |||
| 673 | struct drm_encoder *encoder; | |||
| 674 | struct drm_bridge *iter; | |||
| 675 | ||||
| 676 | if (!bridge) | |||
| 677 | return; | |||
| 678 | ||||
| 679 | encoder = bridge->encoder; | |||
| 680 | list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node)for (iter = ({ const __typeof( ((__typeof(*iter) *)0)->chain_node ) *__mptr = ((&encoder->bridge_chain)->prev); (__typeof (*iter) *)( (char *)__mptr - __builtin_offsetof(__typeof(*iter ), chain_node) );}); &iter->chain_node != (&encoder ->bridge_chain); iter = ({ const __typeof( ((__typeof(*iter ) *)0)->chain_node ) *__mptr = (iter->chain_node.prev); (__typeof(*iter) *)( (char *)__mptr - __builtin_offsetof(__typeof (*iter), chain_node) );})) { | |||
| 681 | if (iter->funcs->atomic_disable) { | |||
| 682 | struct drm_bridge_state *old_bridge_state; | |||
| 683 | ||||
| 684 | old_bridge_state = | |||
| 685 | drm_atomic_get_old_bridge_state(old_state, | |||
| 686 | iter); | |||
| 687 | if (WARN_ON(!old_bridge_state)({ int __ret = !!(!old_bridge_state); if (__ret) printf("WARNING %s failed at %s:%d\n" , "!old_bridge_state", "/usr/src/sys/dev/pci/drm/drm_bridge.c" , 687); __builtin_expect(!!(__ret), 0); })) | |||
| 688 | return; | |||
| 689 | ||||
| 690 | iter->funcs->atomic_disable(iter, old_bridge_state); | |||
| 691 | } else if (iter->funcs->disable) { | |||
| 692 | iter->funcs->disable(iter); | |||
| 693 | } | |||
| 694 | ||||
| 695 | if (iter == bridge) | |||
| 696 | break; | |||
| 697 | } | |||
| 698 | } | |||
| 699 | EXPORT_SYMBOL(drm_atomic_bridge_chain_disable); | |||
| 700 | ||||
| 701 | static void drm_atomic_bridge_call_post_disable(struct drm_bridge *bridge, | |||
| 702 | struct drm_atomic_state *old_state) | |||
| 703 | { | |||
| 704 | if (old_state && bridge->funcs->atomic_post_disable) { | |||
| 705 | struct drm_bridge_state *old_bridge_state; | |||
| 706 | ||||
| 707 | old_bridge_state = | |||
| 708 | drm_atomic_get_old_bridge_state(old_state, | |||
| 709 | bridge); | |||
| 710 | if (WARN_ON(!old_bridge_state)({ int __ret = !!(!old_bridge_state); if (__ret) printf("WARNING %s failed at %s:%d\n" , "!old_bridge_state", "/usr/src/sys/dev/pci/drm/drm_bridge.c" , 710); __builtin_expect(!!(__ret), 0); })) | |||
| 711 | return; | |||
| 712 | ||||
| 713 | bridge->funcs->atomic_post_disable(bridge, | |||
| 714 | old_bridge_state); | |||
| 715 | } else if (bridge->funcs->post_disable) { | |||
| 716 | bridge->funcs->post_disable(bridge); | |||
| 717 | } | |||
| 718 | } | |||
| 719 | ||||
| 720 | /** | |||
| 721 | * drm_atomic_bridge_chain_post_disable - cleans up after disabling all bridges | |||
| 722 | * in the encoder chain | |||
| 723 | * @bridge: bridge control structure | |||
| 724 | * @old_state: old atomic state | |||
| 725 | * | |||
| 726 | * Calls &drm_bridge_funcs.atomic_post_disable (falls back on | |||
| 727 | * &drm_bridge_funcs.post_disable) op for all the bridges in the encoder chain, | |||
| 728 | * starting from the first bridge to the last. These are called after completing | |||
| 729 | * &drm_encoder_helper_funcs.atomic_disable | |||
| 730 | * | |||
| 731 | * If a bridge sets @pre_enable_prev_first, then the @post_disable for that | |||
| 732 | * bridge will be called before the previous one to reverse the @pre_enable | |||
| 733 | * calling direction. | |||
| 734 | * | |||
| 735 | * Note: the bridge passed should be the one closest to the encoder | |||
| 736 | */ | |||
| 737 | void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge, | |||
| 738 | struct drm_atomic_state *old_state) | |||
| 739 | { | |||
| 740 | struct drm_encoder *encoder; | |||
| 741 | struct drm_bridge *next, *limit; | |||
| 742 | ||||
| 743 | if (!bridge) | |||
| 744 | return; | |||
| 745 | ||||
| 746 | encoder = bridge->encoder; | |||
| 747 | ||||
| 748 | list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node)for (; &bridge->chain_node != (&encoder->bridge_chain ); bridge = ({ const __typeof( ((__typeof(*bridge) *)0)->chain_node ) *__mptr = (bridge->chain_node.next); (__typeof(*bridge) *)( (char *)__mptr - __builtin_offsetof(__typeof(*bridge), chain_node ) );})) { | |||
| 749 | limit = NULL((void *)0); | |||
| 750 | ||||
| 751 | if (!list_is_last(&bridge->chain_node, &encoder->bridge_chain)) { | |||
| 752 | next = list_next_entry(bridge, chain_node)({ const __typeof( ((typeof(*(bridge)) *)0)->chain_node ) * __mptr = (((bridge)->chain_node.next)); (typeof(*(bridge)) *)( (char *)__mptr - __builtin_offsetof(typeof(*(bridge)), chain_node ) );}); | |||
| 753 | ||||
| 754 | if (next->pre_enable_prev_first) { | |||
| 755 | /* next bridge had requested that prev | |||
| 756 | * was enabled first, so disabled last | |||
| 757 | */ | |||
| 758 | limit = next; | |||
| 759 | ||||
| 760 | /* Find the next bridge that has NOT requested | |||
| 761 | * prev to be enabled first / disabled last | |||
| 762 | */ | |||
| 763 | list_for_each_entry_from(next, &encoder->bridge_chain,for (; &next->chain_node != (&encoder->bridge_chain ); next = ({ const __typeof( ((__typeof(*next) *)0)->chain_node ) *__mptr = (next->chain_node.next); (__typeof(*next) *)( (char *)__mptr - __builtin_offsetof(__typeof(*next), chain_node ) );})) | |||
| 764 | chain_node)for (; &next->chain_node != (&encoder->bridge_chain ); next = ({ const __typeof( ((__typeof(*next) *)0)->chain_node ) *__mptr = (next->chain_node.next); (__typeof(*next) *)( (char *)__mptr - __builtin_offsetof(__typeof(*next), chain_node ) );})) { | |||
| 765 | if (next->pre_enable_prev_first) { | |||
| 766 | next = list_prev_entry(next, chain_node)({ const __typeof( ((typeof(*(next)) *)0)->chain_node ) *__mptr = (((next)->chain_node.prev)); (typeof(*(next)) *)( (char *)__mptr - __builtin_offsetof(typeof(*(next)), chain_node) ) ;}); | |||
| 767 | limit = next; | |||
| 768 | break; | |||
| 769 | } | |||
| 770 | } | |||
| 771 | ||||
| 772 | /* Call these bridges in reverse order */ | |||
| 773 | list_for_each_entry_from_reverse(next, &encoder->bridge_chain,for (; &next->chain_node != (&encoder->bridge_chain ); next = ({ const __typeof( ((__typeof(*next) *)0)->chain_node ) *__mptr = (next->chain_node.prev); (__typeof(*next) *)( (char *)__mptr - __builtin_offsetof(__typeof(*next), chain_node ) );})) | |||
| 774 | chain_node)for (; &next->chain_node != (&encoder->bridge_chain ); next = ({ const __typeof( ((__typeof(*next) *)0)->chain_node ) *__mptr = (next->chain_node.prev); (__typeof(*next) *)( (char *)__mptr - __builtin_offsetof(__typeof(*next), chain_node ) );})) { | |||
| 775 | if (next == bridge) | |||
| 776 | break; | |||
| 777 | ||||
| 778 | drm_atomic_bridge_call_post_disable(next, | |||
| 779 | old_state); | |||
| 780 | } | |||
| 781 | } | |||
| 782 | } | |||
| 783 | ||||
| 784 | drm_atomic_bridge_call_post_disable(bridge, old_state); | |||
| 785 | ||||
| 786 | if (limit) | |||
| 787 | /* Jump all bridges that we have already post_disabled */ | |||
| 788 | bridge = limit; | |||
| 789 | } | |||
| 790 | } | |||
| 791 | EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable); | |||
| 792 | ||||
| 793 | static void drm_atomic_bridge_call_pre_enable(struct drm_bridge *bridge, | |||
| 794 | struct drm_atomic_state *old_state) | |||
| 795 | { | |||
| 796 | if (old_state && bridge->funcs->atomic_pre_enable) { | |||
| 797 | struct drm_bridge_state *old_bridge_state; | |||
| 798 | ||||
| 799 | old_bridge_state = | |||
| 800 | drm_atomic_get_old_bridge_state(old_state, | |||
| 801 | bridge); | |||
| 802 | if (WARN_ON(!old_bridge_state)({ int __ret = !!(!old_bridge_state); if (__ret) printf("WARNING %s failed at %s:%d\n" , "!old_bridge_state", "/usr/src/sys/dev/pci/drm/drm_bridge.c" , 802); __builtin_expect(!!(__ret), 0); })) | |||
| 803 | return; | |||
| 804 | ||||
| 805 | bridge->funcs->atomic_pre_enable(bridge, old_bridge_state); | |||
| 806 | } else if (bridge->funcs->pre_enable) { | |||
| 807 | bridge->funcs->pre_enable(bridge); | |||
| 808 | } | |||
| 809 | } | |||
| 810 | ||||
| 811 | /** | |||
| 812 | * drm_atomic_bridge_chain_pre_enable - prepares for enabling all bridges in | |||
| 813 | * the encoder chain | |||
| 814 | * @bridge: bridge control structure | |||
| 815 | * @old_state: old atomic state | |||
| 816 | * | |||
| 817 | * Calls &drm_bridge_funcs.atomic_pre_enable (falls back on | |||
| 818 | * &drm_bridge_funcs.pre_enable) op for all the bridges in the encoder chain, | |||
| 819 | * starting from the last bridge to the first. These are called before calling | |||
| 820 | * &drm_encoder_helper_funcs.atomic_enable | |||
| 821 | * | |||
| 822 | * If a bridge sets @pre_enable_prev_first, then the pre_enable for the | |||
| 823 | * prev bridge will be called before pre_enable of this bridge. | |||
| 824 | * | |||
| 825 | * Note: the bridge passed should be the one closest to the encoder | |||
| 826 | */ | |||
| 827 | void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge, | |||
| 828 | struct drm_atomic_state *old_state) | |||
| 829 | { | |||
| 830 | struct drm_encoder *encoder; | |||
| 831 | struct drm_bridge *iter, *next, *limit; | |||
| ||||
| 832 | ||||
| 833 | if (!bridge) | |||
| 834 | return; | |||
| 835 | ||||
| 836 | encoder = bridge->encoder; | |||
| 837 | ||||
| 838 | list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node)for (iter = ({ const __typeof( ((__typeof(*iter) *)0)->chain_node ) *__mptr = ((&encoder->bridge_chain)->prev); (__typeof (*iter) *)( (char *)__mptr - __builtin_offsetof(__typeof(*iter ), chain_node) );}); &iter->chain_node != (&encoder ->bridge_chain); iter = ({ const __typeof( ((__typeof(*iter ) *)0)->chain_node ) *__mptr = (iter->chain_node.prev); (__typeof(*iter) *)( (char *)__mptr - __builtin_offsetof(__typeof (*iter), chain_node) );})) { | |||
| 839 | if (iter->pre_enable_prev_first) { | |||
| 840 | next = iter; | |||
| 841 | limit = bridge; | |||
| 842 | list_for_each_entry_from_reverse(next,for (; &next->chain_node != (&encoder->bridge_chain ); next = ({ const __typeof( ((__typeof(*next) *)0)->chain_node ) *__mptr = (next->chain_node.prev); (__typeof(*next) *)( (char *)__mptr - __builtin_offsetof(__typeof(*next), chain_node ) );})) | |||
| 843 | &encoder->bridge_chain,for (; &next->chain_node != (&encoder->bridge_chain ); next = ({ const __typeof( ((__typeof(*next) *)0)->chain_node ) *__mptr = (next->chain_node.prev); (__typeof(*next) *)( (char *)__mptr - __builtin_offsetof(__typeof(*next), chain_node ) );})) | |||
| 844 | chain_node)for (; &next->chain_node != (&encoder->bridge_chain ); next = ({ const __typeof( ((__typeof(*next) *)0)->chain_node ) *__mptr = (next->chain_node.prev); (__typeof(*next) *)( (char *)__mptr - __builtin_offsetof(__typeof(*next), chain_node ) );})) { | |||
| 845 | if (next == bridge) | |||
| 846 | break; | |||
| 847 | ||||
| 848 | if (!next->pre_enable_prev_first) { | |||
| 849 | /* Found first bridge that does NOT | |||
| 850 | * request prev to be enabled first | |||
| 851 | */ | |||
| 852 | limit = list_prev_entry(next, chain_node)({ const __typeof( ((typeof(*(next)) *)0)->chain_node ) *__mptr = (((next)->chain_node.prev)); (typeof(*(next)) *)( (char *)__mptr - __builtin_offsetof(typeof(*(next)), chain_node) ) ;}); | |||
| 853 | break; | |||
| 854 | } | |||
| 855 | } | |||
| 856 | ||||
| 857 | list_for_each_entry_from(next, &encoder->bridge_chain, chain_node)for (; &next->chain_node != (&encoder->bridge_chain ); next = ({ const __typeof( ((__typeof(*next) *)0)->chain_node ) *__mptr = (next->chain_node.next); (__typeof(*next) *)( (char *)__mptr - __builtin_offsetof(__typeof(*next), chain_node ) );})) { | |||
| 858 | /* Call requested prev bridge pre_enable | |||
| 859 | * in order. | |||
| 860 | */ | |||
| 861 | if (next == iter) | |||
| 862 | /* At the first bridge to request prev | |||
| 863 | * bridges called first. | |||
| 864 | */ | |||
| 865 | break; | |||
| 866 | ||||
| 867 | drm_atomic_bridge_call_pre_enable(next, old_state); | |||
| 868 | } | |||
| 869 | } | |||
| 870 | ||||
| 871 | drm_atomic_bridge_call_pre_enable(iter, old_state); | |||
| 872 | ||||
| 873 | if (iter->pre_enable_prev_first) | |||
| 874 | /* Jump all bridges that we have already pre_enabled */ | |||
| 875 | iter = limit; | |||
| ||||
| 876 | ||||
| 877 | if (iter == bridge) | |||
| 878 | break; | |||
| 879 | } | |||
| 880 | } | |||
| 881 | EXPORT_SYMBOL(drm_atomic_bridge_chain_pre_enable); | |||
| 882 | ||||
| 883 | /** | |||
| 884 | * drm_atomic_bridge_chain_enable - enables all bridges in the encoder chain | |||
| 885 | * @bridge: bridge control structure | |||
| 886 | * @old_state: old atomic state | |||
| 887 | * | |||
| 888 | * Calls &drm_bridge_funcs.atomic_enable (falls back on | |||
| 889 | * &drm_bridge_funcs.enable) op for all the bridges in the encoder chain, | |||
| 890 | * starting from the first bridge to the last. These are called after completing | |||
| 891 | * &drm_encoder_helper_funcs.atomic_enable | |||
| 892 | * | |||
| 893 | * Note: the bridge passed should be the one closest to the encoder | |||
| 894 | */ | |||
| 895 | void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge, | |||
| 896 | struct drm_atomic_state *old_state) | |||
| 897 | { | |||
| 898 | struct drm_encoder *encoder; | |||
| 899 | ||||
| 900 | if (!bridge) | |||
| 901 | return; | |||
| 902 | ||||
| 903 | encoder = bridge->encoder; | |||
| 904 | list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node)for (; &bridge->chain_node != (&encoder->bridge_chain ); bridge = ({ const __typeof( ((__typeof(*bridge) *)0)->chain_node ) *__mptr = (bridge->chain_node.next); (__typeof(*bridge) *)( (char *)__mptr - __builtin_offsetof(__typeof(*bridge), chain_node ) );})) { | |||
| 905 | if (bridge->funcs->atomic_enable) { | |||
| 906 | struct drm_bridge_state *old_bridge_state; | |||
| 907 | ||||
| 908 | old_bridge_state = | |||
| 909 | drm_atomic_get_old_bridge_state(old_state, | |||
| 910 | bridge); | |||
| 911 | if (WARN_ON(!old_bridge_state)({ int __ret = !!(!old_bridge_state); if (__ret) printf("WARNING %s failed at %s:%d\n" , "!old_bridge_state", "/usr/src/sys/dev/pci/drm/drm_bridge.c" , 911); __builtin_expect(!!(__ret), 0); })) | |||
| 912 | return; | |||
| 913 | ||||
| 914 | bridge->funcs->atomic_enable(bridge, old_bridge_state); | |||
| 915 | } else if (bridge->funcs->enable) { | |||
| 916 | bridge->funcs->enable(bridge); | |||
| 917 | } | |||
| 918 | } | |||
| 919 | } | |||
| 920 | EXPORT_SYMBOL(drm_atomic_bridge_chain_enable); | |||
| 921 | ||||
| 922 | static int drm_atomic_bridge_check(struct drm_bridge *bridge, | |||
| 923 | struct drm_crtc_state *crtc_state, | |||
| 924 | struct drm_connector_state *conn_state) | |||
| 925 | { | |||
| 926 | if (bridge->funcs->atomic_check) { | |||
| 927 | struct drm_bridge_state *bridge_state; | |||
| 928 | int ret; | |||
| 929 | ||||
| 930 | bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state, | |||
| 931 | bridge); | |||
| 932 | if (WARN_ON(!bridge_state)({ int __ret = !!(!bridge_state); if (__ret) printf("WARNING %s failed at %s:%d\n" , "!bridge_state", "/usr/src/sys/dev/pci/drm/drm_bridge.c", 932 ); __builtin_expect(!!(__ret), 0); })) | |||
| 933 | return -EINVAL22; | |||
| 934 | ||||
| 935 | ret = bridge->funcs->atomic_check(bridge, bridge_state, | |||
| 936 | crtc_state, conn_state); | |||
| 937 | if (ret) | |||
| 938 | return ret; | |||
| 939 | } else if (bridge->funcs->mode_fixup) { | |||
| 940 | if (!bridge->funcs->mode_fixup(bridge, &crtc_state->mode, | |||
| 941 | &crtc_state->adjusted_mode)) | |||
| 942 | return -EINVAL22; | |||
| 943 | } | |||
| 944 | ||||
| 945 | return 0; | |||
| 946 | } | |||
| 947 | ||||
| 948 | static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, | |||
| 949 | struct drm_bridge *cur_bridge, | |||
| 950 | struct drm_crtc_state *crtc_state, | |||
| 951 | struct drm_connector_state *conn_state, | |||
| 952 | u32 out_bus_fmt) | |||
| 953 | { | |||
| 954 | unsigned int i, num_in_bus_fmts = 0; | |||
| 955 | struct drm_bridge_state *cur_state; | |||
| 956 | struct drm_bridge *prev_bridge; | |||
| 957 | u32 *in_bus_fmts; | |||
| 958 | int ret; | |||
| 959 | ||||
| 960 | prev_bridge = drm_bridge_get_prev_bridge(cur_bridge); | |||
| 961 | cur_state = drm_atomic_get_new_bridge_state(crtc_state->state, | |||
| 962 | cur_bridge); | |||
| 963 | ||||
| 964 | /* | |||
| 965 | * If bus format negotiation is not supported by this bridge, let's | |||
| 966 | * pass MEDIA_BUS_FMT_FIXED to the previous bridge in the chain and | |||
| 967 | * hope that it can handle this situation gracefully (by providing | |||
| 968 | * appropriate default values). | |||
| 969 | */ | |||
| 970 | if (!cur_bridge->funcs->atomic_get_input_bus_fmts) { | |||
| 971 | if (cur_bridge != first_bridge) { | |||
| 972 | ret = select_bus_fmt_recursive(first_bridge, | |||
| 973 | prev_bridge, crtc_state, | |||
| 974 | conn_state, | |||
| 975 | MEDIA_BUS_FMT_FIXED1); | |||
| 976 | if (ret) | |||
| 977 | return ret; | |||
| 978 | } | |||
| 979 | ||||
| 980 | /* | |||
| 981 | * Driver does not implement the atomic state hooks, but that's | |||
| 982 | * fine, as long as it does not access the bridge state. | |||
| 983 | */ | |||
| 984 | if (cur_state) { | |||
| 985 | cur_state->input_bus_cfg.format = MEDIA_BUS_FMT_FIXED1; | |||
| 986 | cur_state->output_bus_cfg.format = out_bus_fmt; | |||
| 987 | } | |||
| 988 | ||||
| 989 | return 0; | |||
| 990 | } | |||
| 991 | ||||
| 992 | /* | |||
| 993 | * If the driver implements ->atomic_get_input_bus_fmts() it | |||
| 994 | * should also implement the atomic state hooks. | |||
| 995 | */ | |||
| 996 | if (WARN_ON(!cur_state)({ int __ret = !!(!cur_state); if (__ret) printf("WARNING %s failed at %s:%d\n" , "!cur_state", "/usr/src/sys/dev/pci/drm/drm_bridge.c", 996) ; __builtin_expect(!!(__ret), 0); })) | |||
| 997 | return -EINVAL22; | |||
| 998 | ||||
| 999 | in_bus_fmts = cur_bridge->funcs->atomic_get_input_bus_fmts(cur_bridge, | |||
| 1000 | cur_state, | |||
| 1001 | crtc_state, | |||
| 1002 | conn_state, | |||
| 1003 | out_bus_fmt, | |||
| 1004 | &num_in_bus_fmts); | |||
| 1005 | if (!num_in_bus_fmts) | |||
| 1006 | return -ENOTSUPP91; | |||
| 1007 | else if (!in_bus_fmts) | |||
| 1008 | return -ENOMEM12; | |||
| 1009 | ||||
| 1010 | if (first_bridge == cur_bridge) { | |||
| 1011 | cur_state->input_bus_cfg.format = in_bus_fmts[0]; | |||
| 1012 | cur_state->output_bus_cfg.format = out_bus_fmt; | |||
| 1013 | kfree(in_bus_fmts); | |||
| 1014 | return 0; | |||
| 1015 | } | |||
| 1016 | ||||
| 1017 | for (i = 0; i < num_in_bus_fmts; i++) { | |||
| 1018 | ret = select_bus_fmt_recursive(first_bridge, prev_bridge, | |||
| 1019 | crtc_state, conn_state, | |||
| 1020 | in_bus_fmts[i]); | |||
| 1021 | if (ret != -ENOTSUPP91) | |||
| 1022 | break; | |||
| 1023 | } | |||
| 1024 | ||||
| 1025 | if (!ret) { | |||
| 1026 | cur_state->input_bus_cfg.format = in_bus_fmts[i]; | |||
| 1027 | cur_state->output_bus_cfg.format = out_bus_fmt; | |||
| 1028 | } | |||
| 1029 | ||||
| 1030 | kfree(in_bus_fmts); | |||
| 1031 | return ret; | |||
| 1032 | } | |||
| 1033 | ||||
| 1034 | /* | |||
| 1035 | * This function is called by &drm_atomic_bridge_chain_check() just before | |||
| 1036 | * calling &drm_bridge_funcs.atomic_check() on all elements of the chain. | |||
| 1037 | * It performs bus format negotiation between bridge elements. The negotiation | |||
| 1038 | * happens in reverse order, starting from the last element in the chain up to | |||
| 1039 | * @bridge. | |||
| 1040 | * | |||
| 1041 | * Negotiation starts by retrieving supported output bus formats on the last | |||
| 1042 | * bridge element and testing them one by one. The test is recursive, meaning | |||
| 1043 | * that for each tested output format, the whole chain will be walked backward, | |||
| 1044 | * and each element will have to choose an input bus format that can be | |||
| 1045 | * transcoded to the requested output format. When a bridge element does not | |||
| 1046 | * support transcoding into a specific output format -ENOTSUPP is returned and | |||
| 1047 | * the next bridge element will have to try a different format. If none of the | |||
| 1048 | * combinations worked, -ENOTSUPP is returned and the atomic modeset will fail. | |||
| 1049 | * | |||
| 1050 | * This implementation is relying on | |||
| 1051 | * &drm_bridge_funcs.atomic_get_output_bus_fmts() and | |||
| 1052 | * &drm_bridge_funcs.atomic_get_input_bus_fmts() to gather supported | |||
| 1053 | * input/output formats. | |||
| 1054 | * | |||
| 1055 | * When &drm_bridge_funcs.atomic_get_output_bus_fmts() is not implemented by | |||
| 1056 | * the last element of the chain, &drm_atomic_bridge_chain_select_bus_fmts() | |||
| 1057 | * tries a single format: &drm_connector.display_info.bus_formats[0] if | |||
| 1058 | * available, MEDIA_BUS_FMT_FIXED otherwise. | |||
| 1059 | * | |||
| 1060 | * When &drm_bridge_funcs.atomic_get_input_bus_fmts() is not implemented, | |||
| 1061 | * &drm_atomic_bridge_chain_select_bus_fmts() skips the negotiation on the | |||
| 1062 | * bridge element that lacks this hook and asks the previous element in the | |||
| 1063 | * chain to try MEDIA_BUS_FMT_FIXED. It's up to bridge drivers to decide what | |||
| 1064 | * to do in that case (fail if they want to enforce bus format negotiation, or | |||
| 1065 | * provide a reasonable default if they need to support pipelines where not | |||
| 1066 | * all elements support bus format negotiation). | |||
| 1067 | */ | |||
| 1068 | static int | |||
| 1069 | drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge, | |||
| 1070 | struct drm_crtc_state *crtc_state, | |||
| 1071 | struct drm_connector_state *conn_state) | |||
| 1072 | { | |||
| 1073 | struct drm_connector *conn = conn_state->connector; | |||
| 1074 | struct drm_encoder *encoder = bridge->encoder; | |||
| 1075 | struct drm_bridge_state *last_bridge_state; | |||
| 1076 | unsigned int i, num_out_bus_fmts = 0; | |||
| 1077 | struct drm_bridge *last_bridge; | |||
| 1078 | u32 *out_bus_fmts; | |||
| 1079 | int ret = 0; | |||
| 1080 | ||||
| 1081 | last_bridge = list_last_entry(&encoder->bridge_chain,({ const __typeof( ((struct drm_bridge *)0)->chain_node ) * __mptr = ((&encoder->bridge_chain)->prev); (struct drm_bridge *)( (char *)__mptr - __builtin_offsetof(struct drm_bridge, chain_node ) );}) | |||
| 1082 | struct drm_bridge, chain_node)({ const __typeof( ((struct drm_bridge *)0)->chain_node ) * __mptr = ((&encoder->bridge_chain)->prev); (struct drm_bridge *)( (char *)__mptr - __builtin_offsetof(struct drm_bridge, chain_node ) );}); | |||
| 1083 | last_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state, | |||
| 1084 | last_bridge); | |||
| 1085 | ||||
| 1086 | if (last_bridge->funcs->atomic_get_output_bus_fmts) { | |||
| 1087 | const struct drm_bridge_funcs *funcs = last_bridge->funcs; | |||
| 1088 | ||||
| 1089 | /* | |||
| 1090 | * If the driver implements ->atomic_get_output_bus_fmts() it | |||
| 1091 | * should also implement the atomic state hooks. | |||
| 1092 | */ | |||
| 1093 | if (WARN_ON(!last_bridge_state)({ int __ret = !!(!last_bridge_state); if (__ret) printf("WARNING %s failed at %s:%d\n" , "!last_bridge_state", "/usr/src/sys/dev/pci/drm/drm_bridge.c" , 1093); __builtin_expect(!!(__ret), 0); })) | |||
| 1094 | return -EINVAL22; | |||
| 1095 | ||||
| 1096 | out_bus_fmts = funcs->atomic_get_output_bus_fmts(last_bridge, | |||
| 1097 | last_bridge_state, | |||
| 1098 | crtc_state, | |||
| 1099 | conn_state, | |||
| 1100 | &num_out_bus_fmts); | |||
| 1101 | if (!num_out_bus_fmts) | |||
| 1102 | return -ENOTSUPP91; | |||
| 1103 | else if (!out_bus_fmts) | |||
| 1104 | return -ENOMEM12; | |||
| 1105 | } else { | |||
| 1106 | num_out_bus_fmts = 1; | |||
| 1107 | out_bus_fmts = kmalloc(sizeof(*out_bus_fmts), GFP_KERNEL(0x0001 | 0x0004)); | |||
| 1108 | if (!out_bus_fmts) | |||
| 1109 | return -ENOMEM12; | |||
| 1110 | ||||
| 1111 | if (conn->display_info.num_bus_formats && | |||
| 1112 | conn->display_info.bus_formats) | |||
| 1113 | out_bus_fmts[0] = conn->display_info.bus_formats[0]; | |||
| 1114 | else | |||
| 1115 | out_bus_fmts[0] = MEDIA_BUS_FMT_FIXED1; | |||
| 1116 | } | |||
| 1117 | ||||
| 1118 | for (i = 0; i < num_out_bus_fmts; i++) { | |||
| 1119 | ret = select_bus_fmt_recursive(bridge, last_bridge, crtc_state, | |||
| 1120 | conn_state, out_bus_fmts[i]); | |||
| 1121 | if (ret != -ENOTSUPP91) | |||
| 1122 | break; | |||
| 1123 | } | |||
| 1124 | ||||
| 1125 | kfree(out_bus_fmts); | |||
| 1126 | ||||
| 1127 | return ret; | |||
| 1128 | } | |||
| 1129 | ||||
| 1130 | static void | |||
| 1131 | drm_atomic_bridge_propagate_bus_flags(struct drm_bridge *bridge, | |||
| 1132 | struct drm_connector *conn, | |||
| 1133 | struct drm_atomic_state *state) | |||
| 1134 | { | |||
| 1135 | struct drm_bridge_state *bridge_state, *next_bridge_state; | |||
| 1136 | struct drm_bridge *next_bridge; | |||
| 1137 | u32 output_flags = 0; | |||
| 1138 | ||||
| 1139 | bridge_state = drm_atomic_get_new_bridge_state(state, bridge); | |||
| 1140 | ||||
| 1141 | /* No bridge state attached to this bridge => nothing to propagate. */ | |||
| 1142 | if (!bridge_state) | |||
| 1143 | return; | |||
| 1144 | ||||
| 1145 | next_bridge = drm_bridge_get_next_bridge(bridge); | |||
| 1146 | ||||
| 1147 | /* | |||
| 1148 | * Let's try to apply the most common case here, that is, propagate | |||
| 1149 | * display_info flags for the last bridge, and propagate the input | |||
| 1150 | * flags of the next bridge element to the output end of the current | |||
| 1151 | * bridge when the bridge is not the last one. | |||
| 1152 | * There are exceptions to this rule, like when signal inversion is | |||
| 1153 | * happening at the board level, but that's something drivers can deal | |||
| 1154 | * with from their &drm_bridge_funcs.atomic_check() implementation by | |||
| 1155 | * simply overriding the flags value we've set here. | |||
| 1156 | */ | |||
| 1157 | if (!next_bridge) { | |||
| 1158 | output_flags = conn->display_info.bus_flags; | |||
| 1159 | } else { | |||
| 1160 | next_bridge_state = drm_atomic_get_new_bridge_state(state, | |||
| 1161 | next_bridge); | |||
| 1162 | /* | |||
| 1163 | * No bridge state attached to the next bridge, just leave the | |||
| 1164 | * flags to 0. | |||
| 1165 | */ | |||
| 1166 | if (next_bridge_state) | |||
| 1167 | output_flags = next_bridge_state->input_bus_cfg.flags; | |||
| 1168 | } | |||
| 1169 | ||||
| 1170 | bridge_state->output_bus_cfg.flags = output_flags; | |||
| 1171 | ||||
| 1172 | /* | |||
| 1173 | * Propagate the output flags to the input end of the bridge. Again, it's | |||
| 1174 | * not necessarily what all bridges want, but that's what most of them | |||
| 1175 | * do, and by doing that by default we avoid forcing drivers to | |||
| 1176 | * duplicate the "dummy propagation" logic. | |||
| 1177 | */ | |||
| 1178 | bridge_state->input_bus_cfg.flags = output_flags; | |||
| 1179 | } | |||
| 1180 | ||||
| 1181 | /** | |||
| 1182 | * drm_atomic_bridge_chain_check() - Do an atomic check on the bridge chain | |||
| 1183 | * @bridge: bridge control structure | |||
| 1184 | * @crtc_state: new CRTC state | |||
| 1185 | * @conn_state: new connector state | |||
| 1186 | * | |||
| 1187 | * First trigger a bus format negotiation before calling | |||
| 1188 | * &drm_bridge_funcs.atomic_check() (falls back on | |||
| 1189 | * &drm_bridge_funcs.mode_fixup()) op for all the bridges in the encoder chain, | |||
| 1190 | * starting from the last bridge to the first. These are called before calling | |||
| 1191 | * &drm_encoder_helper_funcs.atomic_check() | |||
| 1192 | * | |||
| 1193 | * RETURNS: | |||
| 1194 | * 0 on success, a negative error code on failure | |||
| 1195 | */ | |||
| 1196 | int drm_atomic_bridge_chain_check(struct drm_bridge *bridge, | |||
| 1197 | struct drm_crtc_state *crtc_state, | |||
| 1198 | struct drm_connector_state *conn_state) | |||
| 1199 | { | |||
| 1200 | struct drm_connector *conn = conn_state->connector; | |||
| 1201 | struct drm_encoder *encoder; | |||
| 1202 | struct drm_bridge *iter; | |||
| 1203 | int ret; | |||
| 1204 | ||||
| 1205 | if (!bridge) | |||
| 1206 | return 0; | |||
| 1207 | ||||
| 1208 | ret = drm_atomic_bridge_chain_select_bus_fmts(bridge, crtc_state, | |||
| 1209 | conn_state); | |||
| 1210 | if (ret) | |||
| 1211 | return ret; | |||
| 1212 | ||||
| 1213 | encoder = bridge->encoder; | |||
| 1214 | list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node)for (iter = ({ const __typeof( ((__typeof(*iter) *)0)->chain_node ) *__mptr = ((&encoder->bridge_chain)->prev); (__typeof (*iter) *)( (char *)__mptr - __builtin_offsetof(__typeof(*iter ), chain_node) );}); &iter->chain_node != (&encoder ->bridge_chain); iter = ({ const __typeof( ((__typeof(*iter ) *)0)->chain_node ) *__mptr = (iter->chain_node.prev); (__typeof(*iter) *)( (char *)__mptr - __builtin_offsetof(__typeof (*iter), chain_node) );})) { | |||
| 1215 | int ret; | |||
| 1216 | ||||
| 1217 | /* | |||
| 1218 | * Bus flags are propagated by default. If a bridge needs to | |||
| 1219 | * tweak the input bus flags for any reason, it should happen | |||
| 1220 | * in its &drm_bridge_funcs.atomic_check() implementation such | |||
| 1221 | * that preceding bridges in the chain can propagate the new | |||
| 1222 | * bus flags. | |||
| 1223 | */ | |||
| 1224 | drm_atomic_bridge_propagate_bus_flags(iter, conn, | |||
| 1225 | crtc_state->state); | |||
| 1226 | ||||
| 1227 | ret = drm_atomic_bridge_check(iter, crtc_state, conn_state); | |||
| 1228 | if (ret) | |||
| 1229 | return ret; | |||
| 1230 | ||||
| 1231 | if (iter == bridge) | |||
| 1232 | break; | |||
| 1233 | } | |||
| 1234 | ||||
| 1235 | return 0; | |||
| 1236 | } | |||
| 1237 | EXPORT_SYMBOL(drm_atomic_bridge_chain_check); | |||
| 1238 | ||||
| 1239 | /** | |||
| 1240 | * drm_bridge_detect - check if anything is attached to the bridge output | |||
| 1241 | * @bridge: bridge control structure | |||
| 1242 | * | |||
| 1243 | * If the bridge supports output detection, as reported by the | |||
| 1244 | * DRM_BRIDGE_OP_DETECT bridge ops flag, call &drm_bridge_funcs.detect for the | |||
| 1245 | * bridge and return the connection status. Otherwise return | |||
| 1246 | * connector_status_unknown. | |||
| 1247 | * | |||
| 1248 | * RETURNS: | |||
| 1249 | * The detection status on success, or connector_status_unknown if the bridge | |||
| 1250 | * doesn't support output detection. | |||
| 1251 | */ | |||
| 1252 | enum drm_connector_status drm_bridge_detect(struct drm_bridge *bridge) | |||
| 1253 | { | |||
| 1254 | if (!(bridge->ops & DRM_BRIDGE_OP_DETECT)) | |||
| 1255 | return connector_status_unknown; | |||
| 1256 | ||||
| 1257 | return bridge->funcs->detect(bridge); | |||
| 1258 | } | |||
| 1259 | EXPORT_SYMBOL_GPL(drm_bridge_detect); | |||
| 1260 | ||||
| 1261 | /** | |||
| 1262 | * drm_bridge_get_modes - fill all modes currently valid for the sink into the | |||
| 1263 | * @connector | |||
| 1264 | * @bridge: bridge control structure | |||
| 1265 | * @connector: the connector to fill with modes | |||
| 1266 | * | |||
| 1267 | * If the bridge supports output modes retrieval, as reported by the | |||
| 1268 | * DRM_BRIDGE_OP_MODES bridge ops flag, call &drm_bridge_funcs.get_modes to | |||
| 1269 | * fill the connector with all valid modes and return the number of modes | |||
| 1270 | * added. Otherwise return 0. | |||
| 1271 | * | |||
| 1272 | * RETURNS: | |||
| 1273 | * The number of modes added to the connector. | |||
| 1274 | */ | |||
| 1275 | int drm_bridge_get_modes(struct drm_bridge *bridge, | |||
| 1276 | struct drm_connector *connector) | |||
| 1277 | { | |||
| 1278 | if (!(bridge->ops & DRM_BRIDGE_OP_MODES)) | |||
| 1279 | return 0; | |||
| 1280 | ||||
| 1281 | return bridge->funcs->get_modes(bridge, connector); | |||
| 1282 | } | |||
| 1283 | EXPORT_SYMBOL_GPL(drm_bridge_get_modes); | |||
| 1284 | ||||
| 1285 | /** | |||
| 1286 | * drm_bridge_get_edid - get the EDID data of the connected display | |||
| 1287 | * @bridge: bridge control structure | |||
| 1288 | * @connector: the connector to read EDID for | |||
| 1289 | * | |||
| 1290 | * If the bridge supports output EDID retrieval, as reported by the | |||
| 1291 | * DRM_BRIDGE_OP_EDID bridge ops flag, call &drm_bridge_funcs.get_edid to | |||
| 1292 | * get the EDID and return it. Otherwise return NULL. | |||
| 1293 | * | |||
| 1294 | * RETURNS: | |||
| 1295 | * The retrieved EDID on success, or NULL otherwise. | |||
| 1296 | */ | |||
| 1297 | struct edid *drm_bridge_get_edid(struct drm_bridge *bridge, | |||
| 1298 | struct drm_connector *connector) | |||
| 1299 | { | |||
| 1300 | if (!(bridge->ops & DRM_BRIDGE_OP_EDID)) | |||
| 1301 | return NULL((void *)0); | |||
| 1302 | ||||
| 1303 | return bridge->funcs->get_edid(bridge, connector); | |||
| 1304 | } | |||
| 1305 | EXPORT_SYMBOL_GPL(drm_bridge_get_edid); | |||
| 1306 | ||||
| 1307 | /** | |||
| 1308 | * drm_bridge_hpd_enable - enable hot plug detection for the bridge | |||
| 1309 | * @bridge: bridge control structure | |||
| 1310 | * @cb: hot-plug detection callback | |||
| 1311 | * @data: data to be passed to the hot-plug detection callback | |||
| 1312 | * | |||
| 1313 | * Call &drm_bridge_funcs.hpd_enable if implemented and register the given @cb | |||
| 1314 | * and @data as hot plug notification callback. From now on the @cb will be | |||
| 1315 | * called with @data when an output status change is detected by the bridge, | |||
| 1316 | * until hot plug notification gets disabled with drm_bridge_hpd_disable(). | |||
| 1317 | * | |||
| 1318 | * Hot plug detection is supported only if the DRM_BRIDGE_OP_HPD flag is set in | |||
| 1319 | * bridge->ops. This function shall not be called when the flag is not set. | |||
| 1320 | * | |||
| 1321 | * Only one hot plug detection callback can be registered at a time, it is an | |||
| 1322 | * error to call this function when hot plug detection is already enabled for | |||
| 1323 | * the bridge. | |||
| 1324 | */ | |||
| 1325 | void drm_bridge_hpd_enable(struct drm_bridge *bridge, | |||
| 1326 | void (*cb)(void *data, | |||
| 1327 | enum drm_connector_status status), | |||
| 1328 | void *data) | |||
| 1329 | { | |||
| 1330 | if (!(bridge->ops & DRM_BRIDGE_OP_HPD)) | |||
| 1331 | return; | |||
| 1332 | ||||
| 1333 | mutex_lock(&bridge->hpd_mutex)rw_enter_write(&bridge->hpd_mutex); | |||
| 1334 | ||||
| 1335 | if (WARN(bridge->hpd_cb, "Hot plug detection already enabled\n")({ int __ret = !!(bridge->hpd_cb); if (__ret) printf("Hot plug detection already enabled\n" ); __builtin_expect(!!(__ret), 0); })) | |||
| 1336 | goto unlock; | |||
| 1337 | ||||
| 1338 | bridge->hpd_cb = cb; | |||
| 1339 | bridge->hpd_data = data; | |||
| 1340 | ||||
| 1341 | if (bridge->funcs->hpd_enable) | |||
| 1342 | bridge->funcs->hpd_enable(bridge); | |||
| 1343 | ||||
| 1344 | unlock: | |||
| 1345 | mutex_unlock(&bridge->hpd_mutex)rw_exit_write(&bridge->hpd_mutex); | |||
| 1346 | } | |||
| 1347 | EXPORT_SYMBOL_GPL(drm_bridge_hpd_enable); | |||
| 1348 | ||||
| 1349 | /** | |||
| 1350 | * drm_bridge_hpd_disable - disable hot plug detection for the bridge | |||
| 1351 | * @bridge: bridge control structure | |||
| 1352 | * | |||
| 1353 | * Call &drm_bridge_funcs.hpd_disable if implemented and unregister the hot | |||
| 1354 | * plug detection callback previously registered with drm_bridge_hpd_enable(). | |||
| 1355 | * Once this function returns the callback will not be called by the bridge | |||
| 1356 | * when an output status change occurs. | |||
| 1357 | * | |||
| 1358 | * Hot plug detection is supported only if the DRM_BRIDGE_OP_HPD flag is set in | |||
| 1359 | * bridge->ops. This function shall not be called when the flag is not set. | |||
| 1360 | */ | |||
| 1361 | void drm_bridge_hpd_disable(struct drm_bridge *bridge) | |||
| 1362 | { | |||
| 1363 | if (!(bridge->ops & DRM_BRIDGE_OP_HPD)) | |||
| 1364 | return; | |||
| 1365 | ||||
| 1366 | mutex_lock(&bridge->hpd_mutex)rw_enter_write(&bridge->hpd_mutex); | |||
| 1367 | if (bridge->funcs->hpd_disable) | |||
| 1368 | bridge->funcs->hpd_disable(bridge); | |||
| 1369 | ||||
| 1370 | bridge->hpd_cb = NULL((void *)0); | |||
| 1371 | bridge->hpd_data = NULL((void *)0); | |||
| 1372 | mutex_unlock(&bridge->hpd_mutex)rw_exit_write(&bridge->hpd_mutex); | |||
| 1373 | } | |||
| 1374 | EXPORT_SYMBOL_GPL(drm_bridge_hpd_disable); | |||
| 1375 | ||||
| 1376 | /** | |||
| 1377 | * drm_bridge_hpd_notify - notify hot plug detection events | |||
| 1378 | * @bridge: bridge control structure | |||
| 1379 | * @status: output connection status | |||
| 1380 | * | |||
| 1381 | * Bridge drivers shall call this function to report hot plug events when they | |||
| 1382 | * detect a change in the output status, when hot plug detection has been | |||
| 1383 | * enabled by drm_bridge_hpd_enable(). | |||
| 1384 | * | |||
| 1385 | * This function shall be called in a context that can sleep. | |||
| 1386 | */ | |||
| 1387 | void drm_bridge_hpd_notify(struct drm_bridge *bridge, | |||
| 1388 | enum drm_connector_status status) | |||
| 1389 | { | |||
| 1390 | mutex_lock(&bridge->hpd_mutex)rw_enter_write(&bridge->hpd_mutex); | |||
| 1391 | if (bridge->hpd_cb) | |||
| 1392 | bridge->hpd_cb(bridge->hpd_data, status); | |||
| 1393 | mutex_unlock(&bridge->hpd_mutex)rw_exit_write(&bridge->hpd_mutex); | |||
| 1394 | } | |||
| 1395 | EXPORT_SYMBOL_GPL(drm_bridge_hpd_notify); | |||
| 1396 | ||||
| 1397 | #ifdef CONFIG_OF | |||
| 1398 | /** | |||
| 1399 | * of_drm_find_bridge - find the bridge corresponding to the device node in | |||
| 1400 | * the global bridge list | |||
| 1401 | * | |||
| 1402 | * @np: device node | |||
| 1403 | * | |||
| 1404 | * RETURNS: | |||
| 1405 | * drm_bridge control struct on success, NULL on failure | |||
| 1406 | */ | |||
| 1407 | struct drm_bridge *of_drm_find_bridge(struct device_node *np) | |||
| 1408 | { | |||
| 1409 | struct drm_bridge *bridge; | |||
| 1410 | ||||
| 1411 | mutex_lock(&bridge_lock)rw_enter_write(&bridge_lock); | |||
| 1412 | ||||
| 1413 | list_for_each_entry(bridge, &bridge_list, list)for (bridge = ({ const __typeof( ((__typeof(*bridge) *)0)-> list ) *__mptr = ((&bridge_list)->next); (__typeof(*bridge ) *)( (char *)__mptr - __builtin_offsetof(__typeof(*bridge), list ) );}); &bridge->list != (&bridge_list); bridge = ( { const __typeof( ((__typeof(*bridge) *)0)->list ) *__mptr = (bridge->list.next); (__typeof(*bridge) *)( (char *)__mptr - __builtin_offsetof(__typeof(*bridge), list) );})) { | |||
| 1414 | if (bridge->of_node == np) { | |||
| 1415 | mutex_unlock(&bridge_lock)rw_exit_write(&bridge_lock); | |||
| 1416 | return bridge; | |||
| 1417 | } | |||
| 1418 | } | |||
| 1419 | ||||
| 1420 | mutex_unlock(&bridge_lock)rw_exit_write(&bridge_lock); | |||
| 1421 | return NULL((void *)0); | |||
| 1422 | } | |||
| 1423 | EXPORT_SYMBOL(of_drm_find_bridge); | |||
| 1424 | #endif | |||
| 1425 | ||||
| 1426 | MODULE_AUTHOR("Ajay Kumar <ajaykumar.rs@samsung.com>"); | |||
| 1427 | MODULE_DESCRIPTION("DRM bridge infrastructure"); | |||
| 1428 | MODULE_LICENSE("GPL and additional rights"); |