1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. |
4 | */ |
5 | |
6 | #include <drm/drm_atomic_helper.h> |
7 | #include <drm/drm_atomic.h> |
8 | #include <drm/drm_bridge.h> |
9 | #include <drm/drm_bridge_connector.h> |
10 | #include <drm/drm_crtc.h> |
11 | |
12 | #include "msm_drv.h" |
13 | #include "msm_kms.h" |
14 | #include "dp_drm.h" |
15 | |
16 | /** |
17 | * dp_bridge_detect - callback to determine if connector is connected |
18 | * @bridge: Pointer to drm bridge structure |
19 | * Returns: Bridge's 'is connected' status |
20 | */ |
21 | static enum drm_connector_status dp_bridge_detect(struct drm_bridge *bridge) |
22 | { |
23 | struct msm_dp *dp; |
24 | |
25 | dp = to_dp_bridge(bridge)->dp_display; |
26 | |
27 | drm_dbg_dp(dp->drm_dev, "link_ready = %s\n" , |
28 | (dp->link_ready) ? "true" : "false" ); |
29 | |
30 | return (dp->link_ready) ? connector_status_connected : |
31 | connector_status_disconnected; |
32 | } |
33 | |
34 | static int dp_bridge_atomic_check(struct drm_bridge *bridge, |
35 | struct drm_bridge_state *bridge_state, |
36 | struct drm_crtc_state *crtc_state, |
37 | struct drm_connector_state *conn_state) |
38 | { |
39 | struct msm_dp *dp; |
40 | |
41 | dp = to_dp_bridge(bridge)->dp_display; |
42 | |
43 | drm_dbg_dp(dp->drm_dev, "link_ready = %s\n" , |
44 | (dp->link_ready) ? "true" : "false" ); |
45 | |
46 | /* |
47 | * There is no protection in the DRM framework to check if the display |
48 | * pipeline has been already disabled before trying to disable it again. |
49 | * Hence if the sink is unplugged, the pipeline gets disabled, but the |
50 | * crtc->active is still true. Any attempt to set the mode or manually |
51 | * disable this encoder will result in the crash. |
52 | * |
53 | * TODO: add support for telling the DRM subsystem that the pipeline is |
54 | * disabled by the hardware and thus all access to it should be forbidden. |
55 | * After that this piece of code can be removed. |
56 | */ |
57 | if (bridge->ops & DRM_BRIDGE_OP_HPD) |
58 | return (dp->link_ready) ? 0 : -ENOTCONN; |
59 | |
60 | return 0; |
61 | } |
62 | |
63 | |
64 | /** |
65 | * dp_bridge_get_modes - callback to add drm modes via drm_mode_probed_add() |
66 | * @bridge: Poiner to drm bridge |
67 | * @connector: Pointer to drm connector structure |
68 | * Returns: Number of modes added |
69 | */ |
70 | static int dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *connector) |
71 | { |
72 | int rc = 0; |
73 | struct msm_dp *dp; |
74 | |
75 | if (!connector) |
76 | return 0; |
77 | |
78 | dp = to_dp_bridge(bridge)->dp_display; |
79 | |
80 | /* pluggable case assumes EDID is read when HPD */ |
81 | if (dp->link_ready) { |
82 | rc = dp_display_get_modes(dp_display: dp); |
83 | if (rc <= 0) { |
84 | DRM_ERROR("failed to get DP sink modes, rc=%d\n" , rc); |
85 | return rc; |
86 | } |
87 | } else { |
88 | drm_dbg_dp(connector->dev, "No sink connected\n" ); |
89 | } |
90 | return rc; |
91 | } |
92 | |
93 | static void dp_bridge_debugfs_init(struct drm_bridge *bridge, struct dentry *root) |
94 | { |
95 | struct msm_dp *dp = to_dp_bridge(bridge)->dp_display; |
96 | |
97 | dp_display_debugfs_init(dp_display: dp, dentry: root, is_edp: false); |
98 | } |
99 | |
100 | static const struct drm_bridge_funcs dp_bridge_ops = { |
101 | .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, |
102 | .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, |
103 | .atomic_reset = drm_atomic_helper_bridge_reset, |
104 | .atomic_enable = dp_bridge_atomic_enable, |
105 | .atomic_disable = dp_bridge_atomic_disable, |
106 | .atomic_post_disable = dp_bridge_atomic_post_disable, |
107 | .mode_set = dp_bridge_mode_set, |
108 | .mode_valid = dp_bridge_mode_valid, |
109 | .get_modes = dp_bridge_get_modes, |
110 | .detect = dp_bridge_detect, |
111 | .atomic_check = dp_bridge_atomic_check, |
112 | .hpd_enable = dp_bridge_hpd_enable, |
113 | .hpd_disable = dp_bridge_hpd_disable, |
114 | .hpd_notify = dp_bridge_hpd_notify, |
115 | .debugfs_init = dp_bridge_debugfs_init, |
116 | }; |
117 | |
118 | static int edp_bridge_atomic_check(struct drm_bridge *drm_bridge, |
119 | struct drm_bridge_state *bridge_state, |
120 | struct drm_crtc_state *crtc_state, |
121 | struct drm_connector_state *conn_state) |
122 | { |
123 | struct msm_dp *dp = to_dp_bridge(drm_bridge)->dp_display; |
124 | |
125 | if (WARN_ON(!conn_state)) |
126 | return -ENODEV; |
127 | |
128 | conn_state->self_refresh_aware = dp->psr_supported; |
129 | |
130 | if (!conn_state->crtc || !crtc_state) |
131 | return 0; |
132 | |
133 | if (crtc_state->self_refresh_active && !dp->psr_supported) |
134 | return -EINVAL; |
135 | |
136 | return 0; |
137 | } |
138 | |
139 | static void edp_bridge_atomic_enable(struct drm_bridge *drm_bridge, |
140 | struct drm_bridge_state *old_bridge_state) |
141 | { |
142 | struct drm_atomic_state *atomic_state = old_bridge_state->base.state; |
143 | struct drm_crtc *crtc; |
144 | struct drm_crtc_state *old_crtc_state; |
145 | struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge); |
146 | struct msm_dp *dp = dp_bridge->dp_display; |
147 | |
148 | /* |
149 | * Check the old state of the crtc to determine if the panel |
150 | * was put into psr state previously by the edp_bridge_atomic_disable. |
151 | * If the panel is in psr, just exit psr state and skip the full |
152 | * bridge enable sequence. |
153 | */ |
154 | crtc = drm_atomic_get_new_crtc_for_encoder(state: atomic_state, |
155 | encoder: drm_bridge->encoder); |
156 | if (!crtc) |
157 | return; |
158 | |
159 | old_crtc_state = drm_atomic_get_old_crtc_state(state: atomic_state, crtc); |
160 | |
161 | if (old_crtc_state && old_crtc_state->self_refresh_active) { |
162 | dp_display_set_psr(dp, enter: false); |
163 | return; |
164 | } |
165 | |
166 | dp_bridge_atomic_enable(drm_bridge, old_bridge_state); |
167 | } |
168 | |
169 | static void edp_bridge_atomic_disable(struct drm_bridge *drm_bridge, |
170 | struct drm_bridge_state *old_bridge_state) |
171 | { |
172 | struct drm_atomic_state *atomic_state = old_bridge_state->base.state; |
173 | struct drm_crtc *crtc; |
174 | struct drm_crtc_state *new_crtc_state = NULL, *old_crtc_state = NULL; |
175 | struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge); |
176 | struct msm_dp *dp = dp_bridge->dp_display; |
177 | |
178 | crtc = drm_atomic_get_old_crtc_for_encoder(state: atomic_state, |
179 | encoder: drm_bridge->encoder); |
180 | if (!crtc) |
181 | goto out; |
182 | |
183 | new_crtc_state = drm_atomic_get_new_crtc_state(state: atomic_state, crtc); |
184 | if (!new_crtc_state) |
185 | goto out; |
186 | |
187 | old_crtc_state = drm_atomic_get_old_crtc_state(state: atomic_state, crtc); |
188 | if (!old_crtc_state) |
189 | goto out; |
190 | |
191 | /* |
192 | * Set self refresh mode if current crtc state is active. |
193 | * |
194 | * If old crtc state is active, then this is a display disable |
195 | * call while the sink is in psr state. So, exit psr here. |
196 | * The eDP controller will be disabled in the |
197 | * edp_bridge_atomic_post_disable function. |
198 | * |
199 | * We observed sink is stuck in self refresh if psr exit is skipped |
200 | * when display disable occurs while the sink is in psr state. |
201 | */ |
202 | if (new_crtc_state->self_refresh_active) { |
203 | dp_display_set_psr(dp, enter: true); |
204 | return; |
205 | } else if (old_crtc_state->self_refresh_active) { |
206 | dp_display_set_psr(dp, enter: false); |
207 | return; |
208 | } |
209 | |
210 | out: |
211 | dp_bridge_atomic_disable(drm_bridge, old_bridge_state); |
212 | } |
213 | |
214 | static void edp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge, |
215 | struct drm_bridge_state *old_bridge_state) |
216 | { |
217 | struct drm_atomic_state *atomic_state = old_bridge_state->base.state; |
218 | struct drm_crtc *crtc; |
219 | struct drm_crtc_state *new_crtc_state = NULL; |
220 | |
221 | crtc = drm_atomic_get_old_crtc_for_encoder(state: atomic_state, |
222 | encoder: drm_bridge->encoder); |
223 | if (!crtc) |
224 | return; |
225 | |
226 | new_crtc_state = drm_atomic_get_new_crtc_state(state: atomic_state, crtc); |
227 | if (!new_crtc_state) |
228 | return; |
229 | |
230 | /* |
231 | * Self refresh mode is already set in edp_bridge_atomic_disable. |
232 | */ |
233 | if (new_crtc_state->self_refresh_active) |
234 | return; |
235 | |
236 | dp_bridge_atomic_post_disable(drm_bridge, old_bridge_state); |
237 | } |
238 | |
239 | /** |
240 | * edp_bridge_mode_valid - callback to determine if specified mode is valid |
241 | * @bridge: Pointer to drm bridge structure |
242 | * @info: display info |
243 | * @mode: Pointer to drm mode structure |
244 | * Returns: Validity status for specified mode |
245 | */ |
246 | static enum drm_mode_status edp_bridge_mode_valid(struct drm_bridge *bridge, |
247 | const struct drm_display_info *info, |
248 | const struct drm_display_mode *mode) |
249 | { |
250 | struct msm_dp *dp; |
251 | int mode_pclk_khz = mode->clock; |
252 | |
253 | dp = to_dp_bridge(bridge)->dp_display; |
254 | |
255 | if (!dp || !mode_pclk_khz || !dp->connector) { |
256 | DRM_ERROR("invalid params\n" ); |
257 | return -EINVAL; |
258 | } |
259 | |
260 | if (mode->clock > DP_MAX_PIXEL_CLK_KHZ) |
261 | return MODE_CLOCK_HIGH; |
262 | |
263 | /* |
264 | * The eDP controller currently does not have a reliable way of |
265 | * enabling panel power to read sink capabilities. So, we rely |
266 | * on the panel driver to populate only supported modes for now. |
267 | */ |
268 | return MODE_OK; |
269 | } |
270 | |
271 | static void edp_bridge_debugfs_init(struct drm_bridge *bridge, struct dentry *root) |
272 | { |
273 | struct msm_dp *dp = to_dp_bridge(bridge)->dp_display; |
274 | |
275 | dp_display_debugfs_init(dp_display: dp, dentry: root, is_edp: true); |
276 | } |
277 | |
278 | static const struct drm_bridge_funcs edp_bridge_ops = { |
279 | .atomic_enable = edp_bridge_atomic_enable, |
280 | .atomic_disable = edp_bridge_atomic_disable, |
281 | .atomic_post_disable = edp_bridge_atomic_post_disable, |
282 | .mode_set = dp_bridge_mode_set, |
283 | .mode_valid = edp_bridge_mode_valid, |
284 | .atomic_reset = drm_atomic_helper_bridge_reset, |
285 | .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, |
286 | .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, |
287 | .atomic_check = edp_bridge_atomic_check, |
288 | .debugfs_init = edp_bridge_debugfs_init, |
289 | }; |
290 | |
291 | int dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev, |
292 | struct drm_encoder *encoder) |
293 | { |
294 | int rc; |
295 | struct msm_dp_bridge *dp_bridge; |
296 | struct drm_bridge *bridge; |
297 | |
298 | dp_bridge = devm_kzalloc(dev: dev->dev, size: sizeof(*dp_bridge), GFP_KERNEL); |
299 | if (!dp_bridge) |
300 | return -ENOMEM; |
301 | |
302 | dp_bridge->dp_display = dp_display; |
303 | |
304 | bridge = &dp_bridge->bridge; |
305 | bridge->funcs = dp_display->is_edp ? &edp_bridge_ops : &dp_bridge_ops; |
306 | bridge->type = dp_display->connector_type; |
307 | |
308 | /* |
309 | * Many ops only make sense for DP. Why? |
310 | * - Detect/HPD are used by DRM to know if a display is _physically_ |
311 | * there, not whether the display is powered on / finished initting. |
312 | * On eDP we assume the display is always there because you can't |
313 | * know until power is applied. If we don't implement the ops DRM will |
314 | * assume our display is always there. |
315 | * - Currently eDP mode reading is driven by the panel driver. This |
316 | * allows the panel driver to properly power itself on to read the |
317 | * modes. |
318 | */ |
319 | if (!dp_display->is_edp) { |
320 | bridge->ops = |
321 | DRM_BRIDGE_OP_DETECT | |
322 | DRM_BRIDGE_OP_HPD | |
323 | DRM_BRIDGE_OP_MODES; |
324 | } |
325 | |
326 | rc = devm_drm_bridge_add(dev: dev->dev, bridge); |
327 | if (rc) { |
328 | DRM_ERROR("failed to add bridge, rc=%d\n" , rc); |
329 | |
330 | return rc; |
331 | } |
332 | |
333 | rc = drm_bridge_attach(encoder, bridge, NULL, flags: DRM_BRIDGE_ATTACH_NO_CONNECTOR); |
334 | if (rc) { |
335 | DRM_ERROR("failed to attach bridge, rc=%d\n" , rc); |
336 | |
337 | return rc; |
338 | } |
339 | |
340 | if (dp_display->next_bridge) { |
341 | rc = drm_bridge_attach(encoder, |
342 | bridge: dp_display->next_bridge, previous: bridge, |
343 | flags: DRM_BRIDGE_ATTACH_NO_CONNECTOR); |
344 | if (rc < 0) { |
345 | DRM_ERROR("failed to attach panel bridge: %d\n" , rc); |
346 | return rc; |
347 | } |
348 | } |
349 | |
350 | dp_display->bridge = bridge; |
351 | |
352 | return 0; |
353 | } |
354 | |
355 | /* connector initialization */ |
356 | struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display, struct drm_encoder *encoder, |
357 | bool yuv_supported) |
358 | { |
359 | struct drm_connector *connector = NULL; |
360 | |
361 | connector = drm_bridge_connector_init(drm: dp_display->drm_dev, encoder); |
362 | if (IS_ERR(ptr: connector)) |
363 | return connector; |
364 | |
365 | if (!dp_display->is_edp) |
366 | drm_connector_attach_dp_subconnector_property(connector); |
367 | |
368 | if (yuv_supported) |
369 | connector->ycbcr_420_allowed = true; |
370 | |
371 | drm_connector_attach_encoder(connector, encoder); |
372 | |
373 | return connector; |
374 | } |
375 | |