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"); |