1 | /* |
2 | * Copyright (c) 2006-2008 Intel Corporation |
3 | * Copyright (c) 2007 Dave Airlie <airlied@linux.ie> |
4 | * |
5 | * DRM core CRTC related functions |
6 | * |
7 | * Permission to use, copy, modify, distribute, and sell this software and its |
8 | * documentation for any purpose is hereby granted without fee, provided that |
9 | * the above copyright notice appear in all copies and that both that copyright |
10 | * notice and this permission notice appear in supporting documentation, and |
11 | * that the name of the copyright holders not be used in advertising or |
12 | * publicity pertaining to distribution of the software without specific, |
13 | * written prior permission. The copyright holders make no representations |
14 | * about the suitability of this software for any purpose. It is provided "as |
15 | * is" without express or implied warranty. |
16 | * |
17 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
18 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO |
19 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
20 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, |
21 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
22 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE |
23 | * OF THIS SOFTWARE. |
24 | * |
25 | * Authors: |
26 | * Keith Packard |
27 | * Eric Anholt <eric@anholt.net> |
28 | * Dave Airlie <airlied@linux.ie> |
29 | * Jesse Barnes <jesse.barnes@intel.com> |
30 | */ |
31 | |
32 | #include <linux/export.h> |
33 | #include <linux/moduleparam.h> |
34 | |
35 | #include <drm/drm_bridge.h> |
36 | #include <drm/drm_client.h> |
37 | #include <drm/drm_crtc.h> |
38 | #include <drm/drm_edid.h> |
39 | #include <drm/drm_fourcc.h> |
40 | #include <drm/drm_modeset_helper_vtables.h> |
41 | #include <drm/drm_print.h> |
42 | #include <drm/drm_probe_helper.h> |
43 | #include <drm/drm_sysfs.h> |
44 | |
45 | #include "drm_crtc_helper_internal.h" |
46 | |
47 | /** |
48 | * DOC: output probing helper overview |
49 | * |
50 | * This library provides some helper code for output probing. It provides an |
51 | * implementation of the core &drm_connector_funcs.fill_modes interface with |
52 | * drm_helper_probe_single_connector_modes(). |
53 | * |
54 | * It also provides support for polling connectors with a work item and for |
55 | * generic hotplug interrupt handling where the driver doesn't or cannot keep |
56 | * track of a per-connector hpd interrupt. |
57 | * |
58 | * This helper library can be used independently of the modeset helper library. |
59 | * Drivers can also overwrite different parts e.g. use their own hotplug |
60 | * handling code to avoid probing unrelated outputs. |
61 | * |
62 | * The probe helpers share the function table structures with other display |
63 | * helper libraries. See &struct drm_connector_helper_funcs for the details. |
64 | */ |
65 | |
66 | static bool drm_kms_helper_poll = true; |
67 | module_param_named(poll, drm_kms_helper_poll, bool, 0600); |
68 | |
69 | static enum drm_mode_status |
70 | drm_mode_validate_flag(const struct drm_display_mode *mode, |
71 | int flags) |
72 | { |
73 | if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && |
74 | !(flags & DRM_MODE_FLAG_INTERLACE)) |
75 | return MODE_NO_INTERLACE; |
76 | |
77 | if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) && |
78 | !(flags & DRM_MODE_FLAG_DBLSCAN)) |
79 | return MODE_NO_DBLESCAN; |
80 | |
81 | if ((mode->flags & DRM_MODE_FLAG_3D_MASK) && |
82 | !(flags & DRM_MODE_FLAG_3D_MASK)) |
83 | return MODE_NO_STEREO; |
84 | |
85 | return MODE_OK; |
86 | } |
87 | |
88 | static int |
89 | drm_mode_validate_pipeline(struct drm_display_mode *mode, |
90 | struct drm_connector *connector, |
91 | struct drm_modeset_acquire_ctx *ctx, |
92 | enum drm_mode_status *status) |
93 | { |
94 | struct drm_device *dev = connector->dev; |
95 | struct drm_encoder *encoder; |
96 | int ret; |
97 | |
98 | /* Step 1: Validate against connector */ |
99 | ret = drm_connector_mode_valid(connector, mode, ctx, status); |
100 | if (ret || *status != MODE_OK) |
101 | return ret; |
102 | |
103 | /* Step 2: Validate against encoders and crtcs */ |
104 | drm_connector_for_each_possible_encoder(connector, encoder) { |
105 | struct drm_bridge *bridge; |
106 | struct drm_crtc *crtc; |
107 | |
108 | *status = drm_encoder_mode_valid(encoder, mode); |
109 | if (*status != MODE_OK) { |
110 | /* No point in continuing for crtc check as this encoder |
111 | * will not accept the mode anyway. If all encoders |
112 | * reject the mode then, at exit, ret will not be |
113 | * MODE_OK. */ |
114 | continue; |
115 | } |
116 | |
117 | bridge = drm_bridge_chain_get_first_bridge(encoder); |
118 | *status = drm_bridge_chain_mode_valid(bridge, |
119 | info: &connector->display_info, |
120 | mode); |
121 | if (*status != MODE_OK) { |
122 | /* There is also no point in continuing for crtc check |
123 | * here. */ |
124 | continue; |
125 | } |
126 | |
127 | drm_for_each_crtc(crtc, dev) { |
128 | if (!drm_encoder_crtc_ok(encoder, crtc)) |
129 | continue; |
130 | |
131 | *status = drm_crtc_mode_valid(crtc, mode); |
132 | if (*status == MODE_OK) { |
133 | /* If we get to this point there is at least |
134 | * one combination of encoder+crtc that works |
135 | * for this mode. Lets return now. */ |
136 | return 0; |
137 | } |
138 | } |
139 | } |
140 | |
141 | return 0; |
142 | } |
143 | |
144 | static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector) |
145 | { |
146 | struct drm_cmdline_mode *cmdline_mode; |
147 | struct drm_display_mode *mode; |
148 | |
149 | cmdline_mode = &connector->cmdline_mode; |
150 | if (!cmdline_mode->specified) |
151 | return 0; |
152 | |
153 | /* Only add a GTF mode if we find no matching probed modes */ |
154 | list_for_each_entry(mode, &connector->probed_modes, head) { |
155 | if (mode->hdisplay != cmdline_mode->xres || |
156 | mode->vdisplay != cmdline_mode->yres) |
157 | continue; |
158 | |
159 | if (cmdline_mode->refresh_specified) { |
160 | /* The probed mode's vrefresh is set until later */ |
161 | if (drm_mode_vrefresh(mode) != cmdline_mode->refresh) |
162 | continue; |
163 | } |
164 | |
165 | /* Mark the matching mode as being preferred by the user */ |
166 | mode->type |= DRM_MODE_TYPE_USERDEF; |
167 | return 0; |
168 | } |
169 | |
170 | mode = drm_mode_create_from_cmdline_mode(dev: connector->dev, |
171 | cmd: cmdline_mode); |
172 | if (mode == NULL) |
173 | return 0; |
174 | |
175 | drm_mode_probed_add(connector, mode); |
176 | return 1; |
177 | } |
178 | |
179 | enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc, |
180 | const struct drm_display_mode *mode) |
181 | { |
182 | const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; |
183 | |
184 | if (!crtc_funcs || !crtc_funcs->mode_valid) |
185 | return MODE_OK; |
186 | |
187 | return crtc_funcs->mode_valid(crtc, mode); |
188 | } |
189 | |
190 | enum drm_mode_status drm_encoder_mode_valid(struct drm_encoder *encoder, |
191 | const struct drm_display_mode *mode) |
192 | { |
193 | const struct drm_encoder_helper_funcs *encoder_funcs = |
194 | encoder->helper_private; |
195 | |
196 | if (!encoder_funcs || !encoder_funcs->mode_valid) |
197 | return MODE_OK; |
198 | |
199 | return encoder_funcs->mode_valid(encoder, mode); |
200 | } |
201 | |
202 | int |
203 | drm_connector_mode_valid(struct drm_connector *connector, |
204 | struct drm_display_mode *mode, |
205 | struct drm_modeset_acquire_ctx *ctx, |
206 | enum drm_mode_status *status) |
207 | { |
208 | const struct drm_connector_helper_funcs *connector_funcs = |
209 | connector->helper_private; |
210 | int ret = 0; |
211 | |
212 | if (!connector_funcs) |
213 | *status = MODE_OK; |
214 | else if (connector_funcs->mode_valid_ctx) |
215 | ret = connector_funcs->mode_valid_ctx(connector, mode, ctx, |
216 | status); |
217 | else if (connector_funcs->mode_valid) |
218 | *status = connector_funcs->mode_valid(connector, mode); |
219 | else |
220 | *status = MODE_OK; |
221 | |
222 | return ret; |
223 | } |
224 | |
225 | static void drm_kms_helper_disable_hpd(struct drm_device *dev) |
226 | { |
227 | struct drm_connector *connector; |
228 | struct drm_connector_list_iter conn_iter; |
229 | |
230 | drm_connector_list_iter_begin(dev, iter: &conn_iter); |
231 | drm_for_each_connector_iter(connector, &conn_iter) { |
232 | const struct drm_connector_helper_funcs *funcs = |
233 | connector->helper_private; |
234 | |
235 | if (funcs && funcs->disable_hpd) |
236 | funcs->disable_hpd(connector); |
237 | } |
238 | drm_connector_list_iter_end(iter: &conn_iter); |
239 | } |
240 | |
241 | static bool drm_kms_helper_enable_hpd(struct drm_device *dev) |
242 | { |
243 | bool poll = false; |
244 | struct drm_connector *connector; |
245 | struct drm_connector_list_iter conn_iter; |
246 | |
247 | drm_connector_list_iter_begin(dev, iter: &conn_iter); |
248 | drm_for_each_connector_iter(connector, &conn_iter) { |
249 | const struct drm_connector_helper_funcs *funcs = |
250 | connector->helper_private; |
251 | |
252 | if (funcs && funcs->enable_hpd) |
253 | funcs->enable_hpd(connector); |
254 | |
255 | if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT | |
256 | DRM_CONNECTOR_POLL_DISCONNECT)) |
257 | poll = true; |
258 | } |
259 | drm_connector_list_iter_end(iter: &conn_iter); |
260 | |
261 | return poll; |
262 | } |
263 | |
264 | #define DRM_OUTPUT_POLL_PERIOD (10*HZ) |
265 | static void reschedule_output_poll_work(struct drm_device *dev) |
266 | { |
267 | unsigned long delay = DRM_OUTPUT_POLL_PERIOD; |
268 | |
269 | if (dev->mode_config.delayed_event) |
270 | /* |
271 | * FIXME: |
272 | * |
273 | * Use short (1s) delay to handle the initial delayed event. |
274 | * This delay should not be needed, but Optimus/nouveau will |
275 | * fail in a mysterious way if the delayed event is handled as |
276 | * soon as possible like it is done in |
277 | * drm_helper_probe_single_connector_modes() in case the poll |
278 | * was enabled before. |
279 | */ |
280 | delay = HZ; |
281 | |
282 | schedule_delayed_work(dwork: &dev->mode_config.output_poll_work, delay); |
283 | } |
284 | |
285 | /** |
286 | * drm_kms_helper_poll_enable - re-enable output polling. |
287 | * @dev: drm_device |
288 | * |
289 | * This function re-enables the output polling work, after it has been |
290 | * temporarily disabled using drm_kms_helper_poll_disable(), for example over |
291 | * suspend/resume. |
292 | * |
293 | * Drivers can call this helper from their device resume implementation. It is |
294 | * not an error to call this even when output polling isn't enabled. |
295 | * |
296 | * Note that calls to enable and disable polling must be strictly ordered, which |
297 | * is automatically the case when they're only call from suspend/resume |
298 | * callbacks. |
299 | */ |
300 | void drm_kms_helper_poll_enable(struct drm_device *dev) |
301 | { |
302 | if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll || |
303 | dev->mode_config.poll_running) |
304 | return; |
305 | |
306 | if (drm_kms_helper_enable_hpd(dev) || |
307 | dev->mode_config.delayed_event) |
308 | reschedule_output_poll_work(dev); |
309 | |
310 | dev->mode_config.poll_running = true; |
311 | } |
312 | EXPORT_SYMBOL(drm_kms_helper_poll_enable); |
313 | |
314 | /** |
315 | * drm_kms_helper_poll_reschedule - reschedule the output polling work |
316 | * @dev: drm_device |
317 | * |
318 | * This function reschedules the output polling work, after polling for a |
319 | * connector has been enabled. |
320 | * |
321 | * Drivers must call this helper after enabling polling for a connector by |
322 | * setting %DRM_CONNECTOR_POLL_CONNECT / %DRM_CONNECTOR_POLL_DISCONNECT flags |
323 | * in drm_connector::polled. Note that after disabling polling by clearing these |
324 | * flags for a connector will stop the output polling work automatically if |
325 | * the polling is disabled for all other connectors as well. |
326 | * |
327 | * The function can be called only after polling has been enabled by calling |
328 | * drm_kms_helper_poll_init() / drm_kms_helper_poll_enable(). |
329 | */ |
330 | void drm_kms_helper_poll_reschedule(struct drm_device *dev) |
331 | { |
332 | if (dev->mode_config.poll_running) |
333 | reschedule_output_poll_work(dev); |
334 | } |
335 | EXPORT_SYMBOL(drm_kms_helper_poll_reschedule); |
336 | |
337 | static enum drm_connector_status |
338 | drm_helper_probe_detect_ctx(struct drm_connector *connector, bool force) |
339 | { |
340 | const struct drm_connector_helper_funcs *funcs = connector->helper_private; |
341 | struct drm_modeset_acquire_ctx ctx; |
342 | int ret; |
343 | |
344 | drm_modeset_acquire_init(ctx: &ctx, flags: 0); |
345 | |
346 | retry: |
347 | ret = drm_modeset_lock(lock: &connector->dev->mode_config.connection_mutex, ctx: &ctx); |
348 | if (!ret) { |
349 | if (funcs->detect_ctx) |
350 | ret = funcs->detect_ctx(connector, &ctx, force); |
351 | else if (connector->funcs->detect) |
352 | ret = connector->funcs->detect(connector, force); |
353 | else |
354 | ret = connector_status_connected; |
355 | } |
356 | |
357 | if (ret == -EDEADLK) { |
358 | drm_modeset_backoff(ctx: &ctx); |
359 | goto retry; |
360 | } |
361 | |
362 | if (WARN_ON(ret < 0)) |
363 | ret = connector_status_unknown; |
364 | |
365 | if (ret != connector->status) |
366 | connector->epoch_counter += 1; |
367 | |
368 | drm_modeset_drop_locks(ctx: &ctx); |
369 | drm_modeset_acquire_fini(ctx: &ctx); |
370 | |
371 | return ret; |
372 | } |
373 | |
374 | /** |
375 | * drm_helper_probe_detect - probe connector status |
376 | * @connector: connector to probe |
377 | * @ctx: acquire_ctx, or NULL to let this function handle locking. |
378 | * @force: Whether destructive probe operations should be performed. |
379 | * |
380 | * This function calls the detect callbacks of the connector. |
381 | * This function returns &drm_connector_status, or |
382 | * if @ctx is set, it might also return -EDEADLK. |
383 | */ |
384 | int |
385 | drm_helper_probe_detect(struct drm_connector *connector, |
386 | struct drm_modeset_acquire_ctx *ctx, |
387 | bool force) |
388 | { |
389 | const struct drm_connector_helper_funcs *funcs = connector->helper_private; |
390 | struct drm_device *dev = connector->dev; |
391 | int ret; |
392 | |
393 | if (!ctx) |
394 | return drm_helper_probe_detect_ctx(connector, force); |
395 | |
396 | ret = drm_modeset_lock(lock: &dev->mode_config.connection_mutex, ctx); |
397 | if (ret) |
398 | return ret; |
399 | |
400 | if (funcs->detect_ctx) |
401 | ret = funcs->detect_ctx(connector, ctx, force); |
402 | else if (connector->funcs->detect) |
403 | ret = connector->funcs->detect(connector, force); |
404 | else |
405 | ret = connector_status_connected; |
406 | |
407 | if (ret != connector->status) |
408 | connector->epoch_counter += 1; |
409 | |
410 | return ret; |
411 | } |
412 | EXPORT_SYMBOL(drm_helper_probe_detect); |
413 | |
414 | static int drm_helper_probe_get_modes(struct drm_connector *connector) |
415 | { |
416 | const struct drm_connector_helper_funcs *connector_funcs = |
417 | connector->helper_private; |
418 | int count; |
419 | |
420 | count = connector_funcs->get_modes(connector); |
421 | |
422 | /* |
423 | * Fallback for when DDC probe failed in drm_get_edid() and thus skipped |
424 | * override/firmware EDID. |
425 | */ |
426 | if (count == 0 && connector->status == connector_status_connected) |
427 | count = drm_edid_override_connector_update(connector); |
428 | |
429 | return count; |
430 | } |
431 | |
432 | static int __drm_helper_update_and_validate(struct drm_connector *connector, |
433 | uint32_t maxX, uint32_t maxY, |
434 | struct drm_modeset_acquire_ctx *ctx) |
435 | { |
436 | struct drm_device *dev = connector->dev; |
437 | struct drm_display_mode *mode; |
438 | int mode_flags = 0; |
439 | int ret; |
440 | |
441 | drm_connector_list_update(connector); |
442 | |
443 | if (connector->interlace_allowed) |
444 | mode_flags |= DRM_MODE_FLAG_INTERLACE; |
445 | if (connector->doublescan_allowed) |
446 | mode_flags |= DRM_MODE_FLAG_DBLSCAN; |
447 | if (connector->stereo_allowed) |
448 | mode_flags |= DRM_MODE_FLAG_3D_MASK; |
449 | |
450 | list_for_each_entry(mode, &connector->modes, head) { |
451 | if (mode->status != MODE_OK) |
452 | continue; |
453 | |
454 | mode->status = drm_mode_validate_driver(dev, mode); |
455 | if (mode->status != MODE_OK) |
456 | continue; |
457 | |
458 | mode->status = drm_mode_validate_size(mode, maxX, maxY); |
459 | if (mode->status != MODE_OK) |
460 | continue; |
461 | |
462 | mode->status = drm_mode_validate_flag(mode, flags: mode_flags); |
463 | if (mode->status != MODE_OK) |
464 | continue; |
465 | |
466 | ret = drm_mode_validate_pipeline(mode, connector, ctx, |
467 | status: &mode->status); |
468 | if (ret) { |
469 | drm_dbg_kms(dev, |
470 | "drm_mode_validate_pipeline failed: %d\n" , |
471 | ret); |
472 | |
473 | if (drm_WARN_ON_ONCE(dev, ret != -EDEADLK)) |
474 | mode->status = MODE_ERROR; |
475 | else |
476 | return -EDEADLK; |
477 | } |
478 | |
479 | if (mode->status != MODE_OK) |
480 | continue; |
481 | mode->status = drm_mode_validate_ycbcr420(mode, connector); |
482 | } |
483 | |
484 | return 0; |
485 | } |
486 | |
487 | /** |
488 | * drm_helper_probe_single_connector_modes - get complete set of display modes |
489 | * @connector: connector to probe |
490 | * @maxX: max width for modes |
491 | * @maxY: max height for modes |
492 | * |
493 | * Based on the helper callbacks implemented by @connector in struct |
494 | * &drm_connector_helper_funcs try to detect all valid modes. Modes will first |
495 | * be added to the connector's probed_modes list, then culled (based on validity |
496 | * and the @maxX, @maxY parameters) and put into the normal modes list. |
497 | * |
498 | * Intended to be used as a generic implementation of the |
499 | * &drm_connector_funcs.fill_modes() vfunc for drivers that use the CRTC helpers |
500 | * for output mode filtering and detection. |
501 | * |
502 | * The basic procedure is as follows |
503 | * |
504 | * 1. All modes currently on the connector's modes list are marked as stale |
505 | * |
506 | * 2. New modes are added to the connector's probed_modes list with |
507 | * drm_mode_probed_add(). New modes start their life with status as OK. |
508 | * Modes are added from a single source using the following priority order. |
509 | * |
510 | * - &drm_connector_helper_funcs.get_modes vfunc |
511 | * - if the connector status is connector_status_connected, standard |
512 | * VESA DMT modes up to 1024x768 are automatically added |
513 | * (drm_add_modes_noedid()) |
514 | * |
515 | * Finally modes specified via the kernel command line (video=...) are |
516 | * added in addition to what the earlier probes produced |
517 | * (drm_helper_probe_add_cmdline_mode()). These modes are generated |
518 | * using the VESA GTF/CVT formulas. |
519 | * |
520 | * 3. Modes are moved from the probed_modes list to the modes list. Potential |
521 | * duplicates are merged together (see drm_connector_list_update()). |
522 | * After this step the probed_modes list will be empty again. |
523 | * |
524 | * 4. Any non-stale mode on the modes list then undergoes validation |
525 | * |
526 | * - drm_mode_validate_basic() performs basic sanity checks |
527 | * - drm_mode_validate_size() filters out modes larger than @maxX and @maxY |
528 | * (if specified) |
529 | * - drm_mode_validate_flag() checks the modes against basic connector |
530 | * capabilities (interlace_allowed,doublescan_allowed,stereo_allowed) |
531 | * - the optional &drm_connector_helper_funcs.mode_valid or |
532 | * &drm_connector_helper_funcs.mode_valid_ctx helpers can perform driver |
533 | * and/or sink specific checks |
534 | * - the optional &drm_crtc_helper_funcs.mode_valid, |
535 | * &drm_bridge_funcs.mode_valid and &drm_encoder_helper_funcs.mode_valid |
536 | * helpers can perform driver and/or source specific checks which are also |
537 | * enforced by the modeset/atomic helpers |
538 | * |
539 | * 5. Any mode whose status is not OK is pruned from the connector's modes list, |
540 | * accompanied by a debug message indicating the reason for the mode's |
541 | * rejection (see drm_mode_prune_invalid()). |
542 | * |
543 | * Returns: |
544 | * The number of modes found on @connector. |
545 | */ |
546 | int drm_helper_probe_single_connector_modes(struct drm_connector *connector, |
547 | uint32_t maxX, uint32_t maxY) |
548 | { |
549 | struct drm_device *dev = connector->dev; |
550 | struct drm_display_mode *mode; |
551 | int count = 0, ret; |
552 | enum drm_connector_status old_status; |
553 | struct drm_modeset_acquire_ctx ctx; |
554 | |
555 | WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); |
556 | |
557 | drm_modeset_acquire_init(ctx: &ctx, flags: 0); |
558 | |
559 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n" , connector->base.id, |
560 | connector->name); |
561 | |
562 | retry: |
563 | ret = drm_modeset_lock(lock: &dev->mode_config.connection_mutex, ctx: &ctx); |
564 | if (ret == -EDEADLK) { |
565 | drm_modeset_backoff(ctx: &ctx); |
566 | goto retry; |
567 | } else |
568 | WARN_ON(ret < 0); |
569 | |
570 | /* set all old modes to the stale state */ |
571 | list_for_each_entry(mode, &connector->modes, head) |
572 | mode->status = MODE_STALE; |
573 | |
574 | old_status = connector->status; |
575 | |
576 | if (connector->force) { |
577 | if (connector->force == DRM_FORCE_ON || |
578 | connector->force == DRM_FORCE_ON_DIGITAL) |
579 | connector->status = connector_status_connected; |
580 | else |
581 | connector->status = connector_status_disconnected; |
582 | if (connector->funcs->force) |
583 | connector->funcs->force(connector); |
584 | } else { |
585 | ret = drm_helper_probe_detect(connector, &ctx, true); |
586 | |
587 | if (ret == -EDEADLK) { |
588 | drm_modeset_backoff(ctx: &ctx); |
589 | goto retry; |
590 | } else if (WARN(ret < 0, "Invalid return value %i for connector detection\n" , ret)) |
591 | ret = connector_status_unknown; |
592 | |
593 | connector->status = ret; |
594 | } |
595 | |
596 | /* |
597 | * Normally either the driver's hpd code or the poll loop should |
598 | * pick up any changes and fire the hotplug event. But if |
599 | * userspace sneaks in a probe, we might miss a change. Hence |
600 | * check here, and if anything changed start the hotplug code. |
601 | */ |
602 | if (old_status != connector->status) { |
603 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n" , |
604 | connector->base.id, |
605 | connector->name, |
606 | drm_get_connector_status_name(old_status), |
607 | drm_get_connector_status_name(connector->status)); |
608 | |
609 | /* |
610 | * The hotplug event code might call into the fb |
611 | * helpers, and so expects that we do not hold any |
612 | * locks. Fire up the poll struct instead, it will |
613 | * disable itself again. |
614 | */ |
615 | dev->mode_config.delayed_event = true; |
616 | if (dev->mode_config.poll_enabled) |
617 | mod_delayed_work(wq: system_wq, |
618 | dwork: &dev->mode_config.output_poll_work, |
619 | delay: 0); |
620 | } |
621 | |
622 | /* Re-enable polling in case the global poll config changed. */ |
623 | drm_kms_helper_poll_enable(dev); |
624 | |
625 | if (connector->status == connector_status_disconnected) { |
626 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n" , |
627 | connector->base.id, connector->name); |
628 | drm_connector_update_edid_property(connector, NULL); |
629 | drm_mode_prune_invalid(dev, mode_list: &connector->modes, verbose: false); |
630 | goto exit; |
631 | } |
632 | |
633 | count = drm_helper_probe_get_modes(connector); |
634 | |
635 | if (count == 0 && (connector->status == connector_status_connected || |
636 | connector->status == connector_status_unknown)) { |
637 | count = drm_add_modes_noedid(connector, hdisplay: 1024, vdisplay: 768); |
638 | |
639 | /* |
640 | * Section 4.2.2.6 (EDID Corruption Detection) of the DP 1.4a |
641 | * Link CTS specifies that 640x480 (the official "failsafe" |
642 | * mode) needs to be the default if there's no EDID. |
643 | */ |
644 | if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) |
645 | drm_set_preferred_mode(connector, hpref: 640, vpref: 480); |
646 | } |
647 | count += drm_helper_probe_add_cmdline_mode(connector); |
648 | if (count != 0) { |
649 | ret = __drm_helper_update_and_validate(connector, maxX, maxY, ctx: &ctx); |
650 | if (ret == -EDEADLK) { |
651 | drm_modeset_backoff(ctx: &ctx); |
652 | goto retry; |
653 | } |
654 | } |
655 | |
656 | drm_mode_prune_invalid(dev, mode_list: &connector->modes, verbose: true); |
657 | |
658 | /* |
659 | * Displayport spec section 5.2.1.2 ("Video Timing Format") says that |
660 | * all detachable sinks shall support 640x480 @60Hz as a fail safe |
661 | * mode. If all modes were pruned, perhaps because they need more |
662 | * lanes or a higher pixel clock than available, at least try to add |
663 | * in 640x480. |
664 | */ |
665 | if (list_empty(head: &connector->modes) && |
666 | connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { |
667 | count = drm_add_modes_noedid(connector, hdisplay: 640, vdisplay: 480); |
668 | ret = __drm_helper_update_and_validate(connector, maxX, maxY, ctx: &ctx); |
669 | if (ret == -EDEADLK) { |
670 | drm_modeset_backoff(ctx: &ctx); |
671 | goto retry; |
672 | } |
673 | drm_mode_prune_invalid(dev, mode_list: &connector->modes, verbose: true); |
674 | } |
675 | |
676 | exit: |
677 | drm_modeset_drop_locks(ctx: &ctx); |
678 | drm_modeset_acquire_fini(ctx: &ctx); |
679 | |
680 | if (list_empty(head: &connector->modes)) |
681 | return 0; |
682 | |
683 | drm_mode_sort(mode_list: &connector->modes); |
684 | |
685 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n" , connector->base.id, |
686 | connector->name); |
687 | list_for_each_entry(mode, &connector->modes, head) { |
688 | drm_mode_set_crtcinfo(p: mode, CRTC_INTERLACE_HALVE_V); |
689 | drm_mode_debug_printmodeline(mode); |
690 | } |
691 | |
692 | return count; |
693 | } |
694 | EXPORT_SYMBOL(drm_helper_probe_single_connector_modes); |
695 | |
696 | /** |
697 | * drm_kms_helper_hotplug_event - fire off KMS hotplug events |
698 | * @dev: drm_device whose connector state changed |
699 | * |
700 | * This function fires off the uevent for userspace and also calls the |
701 | * output_poll_changed function, which is most commonly used to inform the fbdev |
702 | * emulation code and allow it to update the fbcon output configuration. |
703 | * |
704 | * Drivers should call this from their hotplug handling code when a change is |
705 | * detected. Note that this function does not do any output detection of its |
706 | * own, like drm_helper_hpd_irq_event() does - this is assumed to be done by the |
707 | * driver already. |
708 | * |
709 | * This function must be called from process context with no mode |
710 | * setting locks held. |
711 | * |
712 | * If only a single connector has changed, consider calling |
713 | * drm_kms_helper_connector_hotplug_event() instead. |
714 | */ |
715 | void drm_kms_helper_hotplug_event(struct drm_device *dev) |
716 | { |
717 | /* send a uevent + call fbdev */ |
718 | drm_sysfs_hotplug_event(dev); |
719 | if (dev->mode_config.funcs->output_poll_changed) |
720 | dev->mode_config.funcs->output_poll_changed(dev); |
721 | |
722 | drm_client_dev_hotplug(dev); |
723 | } |
724 | EXPORT_SYMBOL(drm_kms_helper_hotplug_event); |
725 | |
726 | /** |
727 | * drm_kms_helper_connector_hotplug_event - fire off a KMS connector hotplug event |
728 | * @connector: drm_connector which has changed |
729 | * |
730 | * This is the same as drm_kms_helper_hotplug_event(), except it fires a more |
731 | * fine-grained uevent for a single connector. |
732 | */ |
733 | void drm_kms_helper_connector_hotplug_event(struct drm_connector *connector) |
734 | { |
735 | struct drm_device *dev = connector->dev; |
736 | |
737 | /* send a uevent + call fbdev */ |
738 | drm_sysfs_connector_hotplug_event(connector); |
739 | if (dev->mode_config.funcs->output_poll_changed) |
740 | dev->mode_config.funcs->output_poll_changed(dev); |
741 | |
742 | drm_client_dev_hotplug(dev); |
743 | } |
744 | EXPORT_SYMBOL(drm_kms_helper_connector_hotplug_event); |
745 | |
746 | static void output_poll_execute(struct work_struct *work) |
747 | { |
748 | struct delayed_work *delayed_work = to_delayed_work(work); |
749 | struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work); |
750 | struct drm_connector *connector; |
751 | struct drm_connector_list_iter conn_iter; |
752 | enum drm_connector_status old_status; |
753 | bool repoll = false, changed; |
754 | u64 old_epoch_counter; |
755 | |
756 | if (!dev->mode_config.poll_enabled) |
757 | return; |
758 | |
759 | /* Pick up any changes detected by the probe functions. */ |
760 | changed = dev->mode_config.delayed_event; |
761 | dev->mode_config.delayed_event = false; |
762 | |
763 | if (!drm_kms_helper_poll && dev->mode_config.poll_running) { |
764 | drm_kms_helper_disable_hpd(dev); |
765 | dev->mode_config.poll_running = false; |
766 | goto out; |
767 | } |
768 | |
769 | if (!mutex_trylock(lock: &dev->mode_config.mutex)) { |
770 | repoll = true; |
771 | goto out; |
772 | } |
773 | |
774 | drm_connector_list_iter_begin(dev, iter: &conn_iter); |
775 | drm_for_each_connector_iter(connector, &conn_iter) { |
776 | /* Ignore forced connectors. */ |
777 | if (connector->force) |
778 | continue; |
779 | |
780 | /* Ignore HPD capable connectors and connectors where we don't |
781 | * want any hotplug detection at all for polling. */ |
782 | if (!connector->polled || connector->polled == DRM_CONNECTOR_POLL_HPD) |
783 | continue; |
784 | |
785 | old_status = connector->status; |
786 | /* if we are connected and don't want to poll for disconnect |
787 | skip it */ |
788 | if (old_status == connector_status_connected && |
789 | !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT)) |
790 | continue; |
791 | |
792 | repoll = true; |
793 | |
794 | old_epoch_counter = connector->epoch_counter; |
795 | connector->status = drm_helper_probe_detect(connector, NULL, false); |
796 | if (old_epoch_counter != connector->epoch_counter) { |
797 | const char *old, *new; |
798 | |
799 | /* |
800 | * The poll work sets force=false when calling detect so |
801 | * that drivers can avoid to do disruptive tests (e.g. |
802 | * when load detect cycles could cause flickering on |
803 | * other, running displays). This bears the risk that we |
804 | * flip-flop between unknown here in the poll work and |
805 | * the real state when userspace forces a full detect |
806 | * call after receiving a hotplug event due to this |
807 | * change. |
808 | * |
809 | * Hence clamp an unknown detect status to the old |
810 | * value. |
811 | */ |
812 | if (connector->status == connector_status_unknown) { |
813 | connector->status = old_status; |
814 | continue; |
815 | } |
816 | |
817 | old = drm_get_connector_status_name(status: old_status); |
818 | new = drm_get_connector_status_name(status: connector->status); |
819 | |
820 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] " |
821 | "status updated from %s to %s\n" , |
822 | connector->base.id, |
823 | connector->name, |
824 | old, new); |
825 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] epoch counter %llu -> %llu\n" , |
826 | connector->base.id, connector->name, |
827 | old_epoch_counter, connector->epoch_counter); |
828 | |
829 | changed = true; |
830 | } |
831 | } |
832 | drm_connector_list_iter_end(iter: &conn_iter); |
833 | |
834 | mutex_unlock(lock: &dev->mode_config.mutex); |
835 | |
836 | out: |
837 | if (changed) |
838 | drm_kms_helper_hotplug_event(dev); |
839 | |
840 | if (repoll) |
841 | schedule_delayed_work(dwork: delayed_work, DRM_OUTPUT_POLL_PERIOD); |
842 | } |
843 | |
844 | /** |
845 | * drm_kms_helper_is_poll_worker - is %current task an output poll worker? |
846 | * |
847 | * Determine if %current task is an output poll worker. This can be used |
848 | * to select distinct code paths for output polling versus other contexts. |
849 | * |
850 | * One use case is to avoid a deadlock between the output poll worker and |
851 | * the autosuspend worker wherein the latter waits for polling to finish |
852 | * upon calling drm_kms_helper_poll_disable(), while the former waits for |
853 | * runtime suspend to finish upon calling pm_runtime_get_sync() in a |
854 | * connector ->detect hook. |
855 | */ |
856 | bool drm_kms_helper_is_poll_worker(void) |
857 | { |
858 | struct work_struct *work = current_work(); |
859 | |
860 | return work && work->func == output_poll_execute; |
861 | } |
862 | EXPORT_SYMBOL(drm_kms_helper_is_poll_worker); |
863 | |
864 | /** |
865 | * drm_kms_helper_poll_disable - disable output polling |
866 | * @dev: drm_device |
867 | * |
868 | * This function disables the output polling work. |
869 | * |
870 | * Drivers can call this helper from their device suspend implementation. It is |
871 | * not an error to call this even when output polling isn't enabled or already |
872 | * disabled. Polling is re-enabled by calling drm_kms_helper_poll_enable(). |
873 | * |
874 | * Note that calls to enable and disable polling must be strictly ordered, which |
875 | * is automatically the case when they're only call from suspend/resume |
876 | * callbacks. |
877 | */ |
878 | void drm_kms_helper_poll_disable(struct drm_device *dev) |
879 | { |
880 | if (dev->mode_config.poll_running) |
881 | drm_kms_helper_disable_hpd(dev); |
882 | |
883 | cancel_delayed_work_sync(dwork: &dev->mode_config.output_poll_work); |
884 | |
885 | dev->mode_config.poll_running = false; |
886 | } |
887 | EXPORT_SYMBOL(drm_kms_helper_poll_disable); |
888 | |
889 | /** |
890 | * drm_kms_helper_poll_init - initialize and enable output polling |
891 | * @dev: drm_device |
892 | * |
893 | * This function initializes and then also enables output polling support for |
894 | * @dev. Drivers which do not have reliable hotplug support in hardware can use |
895 | * this helper infrastructure to regularly poll such connectors for changes in |
896 | * their connection state. |
897 | * |
898 | * Drivers can control which connectors are polled by setting the |
899 | * DRM_CONNECTOR_POLL_CONNECT and DRM_CONNECTOR_POLL_DISCONNECT flags. On |
900 | * connectors where probing live outputs can result in visual distortion drivers |
901 | * should not set the DRM_CONNECTOR_POLL_DISCONNECT flag to avoid this. |
902 | * Connectors which have no flag or only DRM_CONNECTOR_POLL_HPD set are |
903 | * completely ignored by the polling logic. |
904 | * |
905 | * Note that a connector can be both polled and probed from the hotplug handler, |
906 | * in case the hotplug interrupt is known to be unreliable. |
907 | */ |
908 | void drm_kms_helper_poll_init(struct drm_device *dev) |
909 | { |
910 | INIT_DELAYED_WORK(&dev->mode_config.output_poll_work, output_poll_execute); |
911 | dev->mode_config.poll_enabled = true; |
912 | |
913 | drm_kms_helper_poll_enable(dev); |
914 | } |
915 | EXPORT_SYMBOL(drm_kms_helper_poll_init); |
916 | |
917 | /** |
918 | * drm_kms_helper_poll_fini - disable output polling and clean it up |
919 | * @dev: drm_device |
920 | */ |
921 | void drm_kms_helper_poll_fini(struct drm_device *dev) |
922 | { |
923 | if (!dev->mode_config.poll_enabled) |
924 | return; |
925 | |
926 | drm_kms_helper_poll_disable(dev); |
927 | |
928 | dev->mode_config.poll_enabled = false; |
929 | } |
930 | EXPORT_SYMBOL(drm_kms_helper_poll_fini); |
931 | |
932 | static bool check_connector_changed(struct drm_connector *connector) |
933 | { |
934 | struct drm_device *dev = connector->dev; |
935 | enum drm_connector_status old_status; |
936 | u64 old_epoch_counter; |
937 | |
938 | /* Only handle HPD capable connectors. */ |
939 | drm_WARN_ON(dev, !(connector->polled & DRM_CONNECTOR_POLL_HPD)); |
940 | |
941 | drm_WARN_ON(dev, !mutex_is_locked(&dev->mode_config.mutex)); |
942 | |
943 | old_status = connector->status; |
944 | old_epoch_counter = connector->epoch_counter; |
945 | connector->status = drm_helper_probe_detect(connector, NULL, false); |
946 | |
947 | if (old_epoch_counter == connector->epoch_counter) { |
948 | drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Same epoch counter %llu\n" , |
949 | connector->base.id, |
950 | connector->name, |
951 | connector->epoch_counter); |
952 | |
953 | return false; |
954 | } |
955 | |
956 | drm_dbg_kms(dev, "[CONNECTOR:%d:%s] status updated from %s to %s\n" , |
957 | connector->base.id, |
958 | connector->name, |
959 | drm_get_connector_status_name(old_status), |
960 | drm_get_connector_status_name(connector->status)); |
961 | |
962 | drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Changed epoch counter %llu => %llu\n" , |
963 | connector->base.id, |
964 | connector->name, |
965 | old_epoch_counter, |
966 | connector->epoch_counter); |
967 | |
968 | return true; |
969 | } |
970 | |
971 | /** |
972 | * drm_connector_helper_hpd_irq_event - hotplug processing |
973 | * @connector: drm_connector |
974 | * |
975 | * Drivers can use this helper function to run a detect cycle on a connector |
976 | * which has the DRM_CONNECTOR_POLL_HPD flag set in its &polled member. |
977 | * |
978 | * This helper function is useful for drivers which can track hotplug |
979 | * interrupts for a single connector. Drivers that want to send a |
980 | * hotplug event for all connectors or can't track hotplug interrupts |
981 | * per connector need to use drm_helper_hpd_irq_event(). |
982 | * |
983 | * This function must be called from process context with no mode |
984 | * setting locks held. |
985 | * |
986 | * Note that a connector can be both polled and probed from the hotplug |
987 | * handler, in case the hotplug interrupt is known to be unreliable. |
988 | * |
989 | * Returns: |
990 | * A boolean indicating whether the connector status changed or not |
991 | */ |
992 | bool drm_connector_helper_hpd_irq_event(struct drm_connector *connector) |
993 | { |
994 | struct drm_device *dev = connector->dev; |
995 | bool changed; |
996 | |
997 | mutex_lock(&dev->mode_config.mutex); |
998 | changed = check_connector_changed(connector); |
999 | mutex_unlock(lock: &dev->mode_config.mutex); |
1000 | |
1001 | if (changed) { |
1002 | drm_kms_helper_connector_hotplug_event(connector); |
1003 | drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Sent hotplug event\n" , |
1004 | connector->base.id, |
1005 | connector->name); |
1006 | } |
1007 | |
1008 | return changed; |
1009 | } |
1010 | EXPORT_SYMBOL(drm_connector_helper_hpd_irq_event); |
1011 | |
1012 | /** |
1013 | * drm_helper_hpd_irq_event - hotplug processing |
1014 | * @dev: drm_device |
1015 | * |
1016 | * Drivers can use this helper function to run a detect cycle on all connectors |
1017 | * which have the DRM_CONNECTOR_POLL_HPD flag set in their &polled member. All |
1018 | * other connectors are ignored, which is useful to avoid reprobing fixed |
1019 | * panels. |
1020 | * |
1021 | * This helper function is useful for drivers which can't or don't track hotplug |
1022 | * interrupts for each connector. |
1023 | * |
1024 | * Drivers which support hotplug interrupts for each connector individually and |
1025 | * which have a more fine-grained detect logic can use |
1026 | * drm_connector_helper_hpd_irq_event(). Alternatively, they should bypass this |
1027 | * code and directly call drm_kms_helper_hotplug_event() in case the connector |
1028 | * state changed. |
1029 | * |
1030 | * This function must be called from process context with no mode |
1031 | * setting locks held. |
1032 | * |
1033 | * Note that a connector can be both polled and probed from the hotplug handler, |
1034 | * in case the hotplug interrupt is known to be unreliable. |
1035 | * |
1036 | * Returns: |
1037 | * A boolean indicating whether the connector status changed or not |
1038 | */ |
1039 | bool drm_helper_hpd_irq_event(struct drm_device *dev) |
1040 | { |
1041 | struct drm_connector *connector, *first_changed_connector = NULL; |
1042 | struct drm_connector_list_iter conn_iter; |
1043 | int changed = 0; |
1044 | |
1045 | if (!dev->mode_config.poll_enabled) |
1046 | return false; |
1047 | |
1048 | mutex_lock(&dev->mode_config.mutex); |
1049 | drm_connector_list_iter_begin(dev, iter: &conn_iter); |
1050 | drm_for_each_connector_iter(connector, &conn_iter) { |
1051 | /* Only handle HPD capable connectors. */ |
1052 | if (!(connector->polled & DRM_CONNECTOR_POLL_HPD)) |
1053 | continue; |
1054 | |
1055 | if (check_connector_changed(connector)) { |
1056 | if (!first_changed_connector) { |
1057 | drm_connector_get(connector); |
1058 | first_changed_connector = connector; |
1059 | } |
1060 | |
1061 | changed++; |
1062 | } |
1063 | } |
1064 | drm_connector_list_iter_end(iter: &conn_iter); |
1065 | mutex_unlock(lock: &dev->mode_config.mutex); |
1066 | |
1067 | if (changed == 1) |
1068 | drm_kms_helper_connector_hotplug_event(first_changed_connector); |
1069 | else if (changed > 0) |
1070 | drm_kms_helper_hotplug_event(dev); |
1071 | |
1072 | if (first_changed_connector) |
1073 | drm_connector_put(connector: first_changed_connector); |
1074 | |
1075 | return changed; |
1076 | } |
1077 | EXPORT_SYMBOL(drm_helper_hpd_irq_event); |
1078 | |
1079 | /** |
1080 | * drm_crtc_helper_mode_valid_fixed - Validates a display mode |
1081 | * @crtc: the crtc |
1082 | * @mode: the mode to validate |
1083 | * @fixed_mode: the display hardware's mode |
1084 | * |
1085 | * Returns: |
1086 | * MODE_OK on success, or another mode-status code otherwise. |
1087 | */ |
1088 | enum drm_mode_status drm_crtc_helper_mode_valid_fixed(struct drm_crtc *crtc, |
1089 | const struct drm_display_mode *mode, |
1090 | const struct drm_display_mode *fixed_mode) |
1091 | { |
1092 | if (mode->hdisplay != fixed_mode->hdisplay && mode->vdisplay != fixed_mode->vdisplay) |
1093 | return MODE_ONE_SIZE; |
1094 | else if (mode->hdisplay != fixed_mode->hdisplay) |
1095 | return MODE_ONE_WIDTH; |
1096 | else if (mode->vdisplay != fixed_mode->vdisplay) |
1097 | return MODE_ONE_HEIGHT; |
1098 | |
1099 | return MODE_OK; |
1100 | } |
1101 | EXPORT_SYMBOL(drm_crtc_helper_mode_valid_fixed); |
1102 | |
1103 | /** |
1104 | * drm_connector_helper_get_modes_from_ddc - Updates the connector's EDID |
1105 | * property from the connector's |
1106 | * DDC channel |
1107 | * @connector: The connector |
1108 | * |
1109 | * Returns: |
1110 | * The number of detected display modes. |
1111 | * |
1112 | * Uses a connector's DDC channel to retrieve EDID data and update the |
1113 | * connector's EDID property and display modes. Drivers can use this |
1114 | * function to implement struct &drm_connector_helper_funcs.get_modes |
1115 | * for connectors with a DDC channel. |
1116 | */ |
1117 | int drm_connector_helper_get_modes_from_ddc(struct drm_connector *connector) |
1118 | { |
1119 | struct edid *edid; |
1120 | int count = 0; |
1121 | |
1122 | if (!connector->ddc) |
1123 | return 0; |
1124 | |
1125 | edid = drm_get_edid(connector, adapter: connector->ddc); |
1126 | |
1127 | // clears property if EDID is NULL |
1128 | drm_connector_update_edid_property(connector, edid); |
1129 | |
1130 | if (edid) { |
1131 | count = drm_add_edid_modes(connector, edid); |
1132 | kfree(objp: edid); |
1133 | } |
1134 | |
1135 | return count; |
1136 | } |
1137 | EXPORT_SYMBOL(drm_connector_helper_get_modes_from_ddc); |
1138 | |
1139 | /** |
1140 | * drm_connector_helper_get_modes_fixed - Duplicates a display mode for a connector |
1141 | * @connector: the connector |
1142 | * @fixed_mode: the display hardware's mode |
1143 | * |
1144 | * This function duplicates a display modes for a connector. Drivers for hardware |
1145 | * that only supports a single fixed mode can use this function in their connector's |
1146 | * get_modes helper. |
1147 | * |
1148 | * Returns: |
1149 | * The number of created modes. |
1150 | */ |
1151 | int drm_connector_helper_get_modes_fixed(struct drm_connector *connector, |
1152 | const struct drm_display_mode *fixed_mode) |
1153 | { |
1154 | struct drm_device *dev = connector->dev; |
1155 | struct drm_display_mode *mode; |
1156 | |
1157 | mode = drm_mode_duplicate(dev, mode: fixed_mode); |
1158 | if (!mode) { |
1159 | drm_err(dev, "Failed to duplicate mode " DRM_MODE_FMT "\n" , |
1160 | DRM_MODE_ARG(fixed_mode)); |
1161 | return 0; |
1162 | } |
1163 | |
1164 | if (mode->name[0] == '\0') |
1165 | drm_mode_set_name(mode); |
1166 | |
1167 | mode->type |= DRM_MODE_TYPE_PREFERRED; |
1168 | drm_mode_probed_add(connector, mode); |
1169 | |
1170 | if (mode->width_mm) |
1171 | connector->display_info.width_mm = mode->width_mm; |
1172 | if (mode->height_mm) |
1173 | connector->display_info.height_mm = mode->height_mm; |
1174 | |
1175 | return 1; |
1176 | } |
1177 | EXPORT_SYMBOL(drm_connector_helper_get_modes_fixed); |
1178 | |
1179 | /** |
1180 | * drm_connector_helper_get_modes - Read EDID and update connector. |
1181 | * @connector: The connector |
1182 | * |
1183 | * Read the EDID using drm_edid_read() (which requires that connector->ddc is |
1184 | * set), and update the connector using the EDID. |
1185 | * |
1186 | * This can be used as the "default" connector helper .get_modes() hook if the |
1187 | * driver does not need any special processing. This is sets the example what |
1188 | * custom .get_modes() hooks should do regarding EDID read and connector update. |
1189 | * |
1190 | * Returns: Number of modes. |
1191 | */ |
1192 | int drm_connector_helper_get_modes(struct drm_connector *connector) |
1193 | { |
1194 | const struct drm_edid *drm_edid; |
1195 | int count; |
1196 | |
1197 | drm_edid = drm_edid_read(connector); |
1198 | |
1199 | /* |
1200 | * Unconditionally update the connector. If the EDID was read |
1201 | * successfully, fill in the connector information derived from the |
1202 | * EDID. Otherwise, if the EDID is NULL, clear the connector |
1203 | * information. |
1204 | */ |
1205 | drm_edid_connector_update(connector, edid: drm_edid); |
1206 | |
1207 | count = drm_edid_connector_add_modes(connector); |
1208 | |
1209 | drm_edid_free(drm_edid); |
1210 | |
1211 | return count; |
1212 | } |
1213 | EXPORT_SYMBOL(drm_connector_helper_get_modes); |
1214 | |
1215 | /** |
1216 | * drm_connector_helper_tv_get_modes - Fills the modes availables to a TV connector |
1217 | * @connector: The connector |
1218 | * |
1219 | * Fills the available modes for a TV connector based on the supported |
1220 | * TV modes, and the default mode expressed by the kernel command line. |
1221 | * |
1222 | * This can be used as the default TV connector helper .get_modes() hook |
1223 | * if the driver does not need any special processing. |
1224 | * |
1225 | * Returns: |
1226 | * The number of modes added to the connector. |
1227 | */ |
1228 | int drm_connector_helper_tv_get_modes(struct drm_connector *connector) |
1229 | { |
1230 | struct drm_device *dev = connector->dev; |
1231 | struct drm_property *tv_mode_property = |
1232 | dev->mode_config.tv_mode_property; |
1233 | struct drm_cmdline_mode *cmdline = &connector->cmdline_mode; |
1234 | unsigned int ntsc_modes = BIT(DRM_MODE_TV_MODE_NTSC) | |
1235 | BIT(DRM_MODE_TV_MODE_NTSC_443) | |
1236 | BIT(DRM_MODE_TV_MODE_NTSC_J) | |
1237 | BIT(DRM_MODE_TV_MODE_PAL_M); |
1238 | unsigned int pal_modes = BIT(DRM_MODE_TV_MODE_PAL) | |
1239 | BIT(DRM_MODE_TV_MODE_PAL_N) | |
1240 | BIT(DRM_MODE_TV_MODE_SECAM); |
1241 | unsigned int tv_modes[2] = { UINT_MAX, UINT_MAX }; |
1242 | unsigned int i, supported_tv_modes = 0; |
1243 | |
1244 | if (!tv_mode_property) |
1245 | return 0; |
1246 | |
1247 | for (i = 0; i < tv_mode_property->num_values; i++) |
1248 | supported_tv_modes |= BIT(tv_mode_property->values[i]); |
1249 | |
1250 | if ((supported_tv_modes & ntsc_modes) && |
1251 | (supported_tv_modes & pal_modes)) { |
1252 | uint64_t default_mode; |
1253 | |
1254 | if (drm_object_property_get_default_value(obj: &connector->base, |
1255 | property: tv_mode_property, |
1256 | val: &default_mode)) |
1257 | return 0; |
1258 | |
1259 | if (cmdline->tv_mode_specified) |
1260 | default_mode = cmdline->tv_mode; |
1261 | |
1262 | if (BIT(default_mode) & ntsc_modes) { |
1263 | tv_modes[0] = DRM_MODE_TV_MODE_NTSC; |
1264 | tv_modes[1] = DRM_MODE_TV_MODE_PAL; |
1265 | } else { |
1266 | tv_modes[0] = DRM_MODE_TV_MODE_PAL; |
1267 | tv_modes[1] = DRM_MODE_TV_MODE_NTSC; |
1268 | } |
1269 | } else if (supported_tv_modes & ntsc_modes) { |
1270 | tv_modes[0] = DRM_MODE_TV_MODE_NTSC; |
1271 | } else if (supported_tv_modes & pal_modes) { |
1272 | tv_modes[0] = DRM_MODE_TV_MODE_PAL; |
1273 | } else { |
1274 | return 0; |
1275 | } |
1276 | |
1277 | for (i = 0; i < ARRAY_SIZE(tv_modes); i++) { |
1278 | struct drm_display_mode *mode; |
1279 | |
1280 | if (tv_modes[i] == DRM_MODE_TV_MODE_NTSC) |
1281 | mode = drm_mode_analog_ntsc_480i(dev); |
1282 | else if (tv_modes[i] == DRM_MODE_TV_MODE_PAL) |
1283 | mode = drm_mode_analog_pal_576i(dev); |
1284 | else |
1285 | break; |
1286 | if (!mode) |
1287 | return i; |
1288 | if (!i) |
1289 | mode->type |= DRM_MODE_TYPE_PREFERRED; |
1290 | drm_mode_probed_add(connector, mode); |
1291 | } |
1292 | |
1293 | return i; |
1294 | } |
1295 | EXPORT_SYMBOL(drm_connector_helper_tv_get_modes); |
1296 | |