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