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