blob: 07b2e96840643b6e8490125a1238d365e36e7833 [file] [log] [blame]
Daniel Vetter199e4e92016-08-31 18:09:05 +02001/*
2 * Copyright (c) 2016 Intel Corporation
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 * OF THIS SOFTWARE.
21 */
22
23#ifndef __DRM_BRIDGE_H__
24#define __DRM_BRIDGE_H__
25
26#include <linux/list.h>
27#include <linux/ctype.h>
28#include <drm/drm_mode_object.h>
29#include <drm/drm_modes.h>
30
31struct drm_bridge;
32
33/**
34 * struct drm_bridge_funcs - drm_bridge control functions
35 */
36struct drm_bridge_funcs {
37 /**
38 * @attach:
39 *
40 * This callback is invoked whenever our bridge is being attached to a
41 * &drm_encoder.
42 *
43 * The attach callback is optional.
44 *
45 * RETURNS:
46 *
47 * Zero on success, error code on failure.
48 */
49 int (*attach)(struct drm_bridge *bridge);
50
51 /**
52 * @detach:
53 *
54 * This callback is invoked whenever our bridge is being detached from a
55 * &drm_encoder.
56 *
57 * The detach callback is optional.
58 */
59 void (*detach)(struct drm_bridge *bridge);
60
61 /**
Ray Zhang5b7c5312018-01-22 09:51:28 +080062 * @connector_init:
63 *
64 * This callback is used to init the connector from bridge side. In some
65 * cases connector and bridge are created in different modules, and the
66 * connector ops might need extra info from bridge. This callback offers
67 * the opportunity to overwrite connector's behavior in external bridge.
68 *
69 * The connector_init callback is optional.
70 *
71 * RETURNS:
72 *
73 * Zero on success, error code on failure.
74 */
75 int (*connector_init)(struct drm_bridge *bridge,
76 struct drm_connector *connector);
77
78 /**
Daniel Vetter199e4e92016-08-31 18:09:05 +020079 * @mode_fixup:
80 *
81 * This callback is used to validate and adjust a mode. The paramater
82 * mode is the display mode that should be fed to the next element in
83 * the display chain, either the final &drm_connector or the next
84 * &drm_bridge. The parameter adjusted_mode is the input mode the bridge
85 * requires. It can be modified by this callback and does not need to
86 * match mode.
87 *
88 * This is the only hook that allows a bridge to reject a modeset. If
89 * this function passes all other callbacks must succeed for this
90 * configuration.
91 *
92 * The mode_fixup callback is optional.
93 *
94 * NOTE:
95 *
96 * This function is called in the check phase of atomic modesets, which
97 * can be aborted for any reason (including on userspace's request to
98 * just check whether a configuration would be possible). Drivers MUST
99 * NOT touch any persistent state (hardware or software) or data
100 * structures except the passed in @state parameter.
101 *
102 * RETURNS:
103 *
104 * True if an acceptable configuration is possible, false if the modeset
105 * operation should be rejected.
106 */
107 bool (*mode_fixup)(struct drm_bridge *bridge,
108 const struct drm_display_mode *mode,
109 struct drm_display_mode *adjusted_mode);
110 /**
111 * @disable:
112 *
113 * This callback should disable the bridge. It is called right before
114 * the preceding element in the display pipe is disabled. If the
115 * preceding element is a bridge this means it's called before that
116 * bridge's ->disable() function. If the preceding element is a
117 * &drm_encoder it's called right before the encoder's ->disable(),
118 * ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs.
119 *
120 * The bridge can assume that the display pipe (i.e. clocks and timing
121 * signals) feeding it is still running when this callback is called.
122 *
123 * The disable callback is optional.
124 */
125 void (*disable)(struct drm_bridge *bridge);
126
127 /**
128 * @post_disable:
129 *
130 * This callback should disable the bridge. It is called right after
131 * the preceding element in the display pipe is disabled. If the
132 * preceding element is a bridge this means it's called after that
133 * bridge's ->post_disable() function. If the preceding element is a
134 * &drm_encoder it's called right after the encoder's ->disable(),
135 * ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs.
136 *
137 * The bridge must assume that the display pipe (i.e. clocks and timing
138 * singals) feeding it is no longer running when this callback is
139 * called.
140 *
141 * The post_disable callback is optional.
142 */
143 void (*post_disable)(struct drm_bridge *bridge);
144
145 /**
146 * @mode_set:
147 *
148 * This callback should set the given mode on the bridge. It is called
149 * after the ->mode_set() callback for the preceding element in the
150 * display pipeline has been called already. The display pipe (i.e.
151 * clocks and timing signals) is off when this function is called.
152 */
153 void (*mode_set)(struct drm_bridge *bridge,
154 struct drm_display_mode *mode,
155 struct drm_display_mode *adjusted_mode);
156 /**
157 * @pre_enable:
158 *
159 * This callback should enable the bridge. It is called right before
160 * the preceding element in the display pipe is enabled. If the
161 * preceding element is a bridge this means it's called before that
162 * bridge's ->pre_enable() function. If the preceding element is a
163 * &drm_encoder it's called right before the encoder's ->enable(),
164 * ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs.
165 *
166 * The display pipe (i.e. clocks and timing signals) feeding this bridge
167 * will not yet be running when this callback is called. The bridge must
168 * not enable the display link feeding the next bridge in the chain (if
169 * there is one) when this callback is called.
170 *
171 * The pre_enable callback is optional.
172 */
173 void (*pre_enable)(struct drm_bridge *bridge);
174
175 /**
176 * @enable:
177 *
178 * This callback should enable the bridge. It is called right after
179 * the preceding element in the display pipe is enabled. If the
180 * preceding element is a bridge this means it's called after that
181 * bridge's ->enable() function. If the preceding element is a
182 * &drm_encoder it's called right after the encoder's ->enable(),
183 * ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs.
184 *
185 * The bridge can assume that the display pipe (i.e. clocks and timing
186 * signals) feeding it is running when this callback is called. This
187 * callback must enable the display link feeding the next bridge in the
188 * chain if there is one.
189 *
190 * The enable callback is optional.
191 */
192 void (*enable)(struct drm_bridge *bridge);
193};
194
195/**
196 * struct drm_bridge - central DRM bridge control structure
197 * @dev: DRM device this bridge belongs to
198 * @encoder: encoder to which this bridge is connected
199 * @next: the next bridge in the encoder chain
200 * @of_node: device node pointer to the bridge
201 * @list: to keep track of all added bridges
202 * @funcs: control functions
203 * @driver_private: pointer to the bridge driver's internal context
204 */
205struct drm_bridge {
206 struct drm_device *dev;
207 struct drm_encoder *encoder;
208 struct drm_bridge *next;
209#ifdef CONFIG_OF
210 struct device_node *of_node;
211#endif
212 struct list_head list;
213
214 const struct drm_bridge_funcs *funcs;
215 void *driver_private;
216};
217
218int drm_bridge_add(struct drm_bridge *bridge);
219void drm_bridge_remove(struct drm_bridge *bridge);
220struct drm_bridge *of_drm_find_bridge(struct device_node *np);
221int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge);
222void drm_bridge_detach(struct drm_bridge *bridge);
223
224bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
225 const struct drm_display_mode *mode,
226 struct drm_display_mode *adjusted_mode);
227void drm_bridge_disable(struct drm_bridge *bridge);
228void drm_bridge_post_disable(struct drm_bridge *bridge);
229void drm_bridge_mode_set(struct drm_bridge *bridge,
230 struct drm_display_mode *mode,
231 struct drm_display_mode *adjusted_mode);
232void drm_bridge_pre_enable(struct drm_bridge *bridge);
233void drm_bridge_enable(struct drm_bridge *bridge);
Ray Zhang5b7c5312018-01-22 09:51:28 +0800234int drm_bridge_connector_init(struct drm_bridge *bridge,
235 struct drm_connector *connector);
Daniel Vetter199e4e92016-08-31 18:09:05 +0200236
237#endif