drm_probe_helper.c revision 1.2.30.1 1 /* $NetBSD: drm_probe_helper.c,v 1.2.30.1 2018/09/06 06:56:09 pgoyette Exp $ */
2
3 /*
4 * Copyright (c) 2006-2008 Intel Corporation
5 * Copyright (c) 2007 Dave Airlie <airlied (at) linux.ie>
6 *
7 * DRM core CRTC related functions
8 *
9 * Permission to use, copy, modify, distribute, and sell this software and its
10 * documentation for any purpose is hereby granted without fee, provided that
11 * the above copyright notice appear in all copies and that both that copyright
12 * notice and this permission notice appear in supporting documentation, and
13 * that the name of the copyright holders not be used in advertising or
14 * publicity pertaining to distribution of the software without specific,
15 * written prior permission. The copyright holders make no representations
16 * about the suitability of this software for any purpose. It is provided "as
17 * is" without express or implied warranty.
18 *
19 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
20 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
21 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
22 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
23 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
24 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
25 * OF THIS SOFTWARE.
26 *
27 * Authors:
28 * Keith Packard
29 * Eric Anholt <eric (at) anholt.net>
30 * Dave Airlie <airlied (at) linux.ie>
31 * Jesse Barnes <jesse.barnes (at) intel.com>
32 */
33
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: drm_probe_helper.c,v 1.2.30.1 2018/09/06 06:56:09 pgoyette Exp $");
36
37 #include <asm/param.h>
38 #include <linux/export.h>
39 #include <linux/moduleparam.h>
40
41 #include <drm/drmP.h>
42 #include <drm/drm_crtc.h>
43 #include <drm/drm_fourcc.h>
44 #include <drm/drm_crtc_helper.h>
45 #include <drm/drm_fb_helper.h>
46 #include <drm/drm_edid.h>
47
48 /**
49 * DOC: output probing helper overview
50 *
51 * This library provides some helper code for output probing. It provides an
52 * implementation of the core connector->fill_modes interface with
53 * drm_helper_probe_single_connector_modes.
54 *
55 * It also provides support for polling connectors with a work item and for
56 * generic hotplug interrupt handling where the driver doesn't or cannot keep
57 * track of a per-connector hpd interrupt.
58 *
59 * This helper library can be used independently of the modeset helper library.
60 * Drivers can also overwrite different parts e.g. use their own hotplug
61 * handling code to avoid probing unrelated outputs.
62 */
63
64 static bool drm_kms_helper_poll = true;
65 module_param_named(poll, drm_kms_helper_poll, bool, 0600);
66
67 static enum drm_mode_status
68 drm_mode_validate_flag(const struct drm_display_mode *mode,
69 int flags)
70 {
71 if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
72 !(flags & DRM_MODE_FLAG_INTERLACE))
73 return MODE_NO_INTERLACE;
74
75 if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
76 !(flags & DRM_MODE_FLAG_DBLSCAN))
77 return MODE_NO_DBLESCAN;
78
79 if ((mode->flags & DRM_MODE_FLAG_3D_MASK) &&
80 !(flags & DRM_MODE_FLAG_3D_MASK))
81 return MODE_NO_STEREO;
82
83 return MODE_OK;
84 }
85
86 static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
87 {
88 struct drm_display_mode *mode;
89
90 if (!connector->cmdline_mode.specified)
91 return 0;
92
93 mode = drm_mode_create_from_cmdline_mode(connector->dev,
94 &connector->cmdline_mode);
95 if (mode == NULL)
96 return 0;
97
98 drm_mode_probed_add(connector, mode);
99 return 1;
100 }
101
102 #define DRM_OUTPUT_POLL_PERIOD (10*HZ)
103 /**
104 * drm_kms_helper_poll_enable_locked - re-enable output polling.
105 * @dev: drm_device
106 *
107 * This function re-enables the output polling work without
108 * locking the mode_config mutex.
109 *
110 * This is like drm_kms_helper_poll_enable() however it is to be
111 * called from a context where the mode_config mutex is locked
112 * already.
113 */
114 void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
115 {
116 bool poll = false;
117 struct drm_connector *connector;
118
119 WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
120
121 if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
122 return;
123
124 drm_for_each_connector(connector, dev) {
125 if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
126 DRM_CONNECTOR_POLL_DISCONNECT))
127 poll = true;
128 }
129
130 if (poll)
131 schedule_delayed_work(&dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD);
132 }
133 EXPORT_SYMBOL(drm_kms_helper_poll_enable_locked);
134
135
136 static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connector *connector,
137 uint32_t maxX, uint32_t maxY, bool merge_type_bits)
138 {
139 struct drm_device *dev = connector->dev;
140 struct drm_display_mode *mode;
141 const struct drm_connector_helper_funcs *connector_funcs =
142 connector->helper_private;
143 int count = 0;
144 int mode_flags = 0;
145 bool verbose_prune = true;
146 enum drm_connector_status old_status;
147
148 WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
149
150 DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
151 connector->name);
152 /* set all modes to the unverified state */
153 list_for_each_entry(mode, &connector->modes, head)
154 mode->status = MODE_UNVERIFIED;
155
156 if (connector->force) {
157 if (connector->force == DRM_FORCE_ON ||
158 connector->force == DRM_FORCE_ON_DIGITAL)
159 connector->status = connector_status_connected;
160 else
161 connector->status = connector_status_disconnected;
162 if (connector->funcs->force)
163 connector->funcs->force(connector);
164 } else {
165 old_status = connector->status;
166
167 connector->status = connector->funcs->detect(connector, true);
168
169 /*
170 * Normally either the driver's hpd code or the poll loop should
171 * pick up any changes and fire the hotplug event. But if
172 * userspace sneaks in a probe, we might miss a change. Hence
173 * check here, and if anything changed start the hotplug code.
174 */
175 if (old_status != connector->status) {
176 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
177 connector->base.id,
178 connector->name,
179 old_status, connector->status);
180
181 /*
182 * The hotplug event code might call into the fb
183 * helpers, and so expects that we do not hold any
184 * locks. Fire up the poll struct instead, it will
185 * disable itself again.
186 */
187 dev->mode_config.delayed_event = true;
188 if (dev->mode_config.poll_enabled)
189 schedule_delayed_work(&dev->mode_config.output_poll_work,
190 0);
191 }
192 }
193
194 /* Re-enable polling in case the global poll config changed. */
195 if (drm_kms_helper_poll != dev->mode_config.poll_running)
196 drm_kms_helper_poll_enable_locked(dev);
197
198 dev->mode_config.poll_running = drm_kms_helper_poll;
199
200 if (connector->status == connector_status_disconnected) {
201 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
202 connector->base.id, connector->name);
203 drm_mode_connector_update_edid_property(connector, NULL);
204 verbose_prune = false;
205 goto prune;
206 }
207
208 #ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
209 count = drm_load_edid_firmware(connector);
210 if (count == 0)
211 #endif
212 {
213 if (connector->override_edid) {
214 struct edid *edid = (struct edid *) connector->edid_blob_ptr->data;
215
216 count = drm_add_edid_modes(connector, edid);
217 drm_edid_to_eld(connector, edid);
218 } else
219 count = (*connector_funcs->get_modes)(connector);
220 }
221
222 if (count == 0 && connector->status == connector_status_connected)
223 count = drm_add_modes_noedid(connector, 1024, 768);
224 count += drm_helper_probe_add_cmdline_mode(connector);
225 if (count == 0)
226 goto prune;
227
228 drm_mode_connector_list_update(connector, merge_type_bits);
229
230 if (connector->interlace_allowed)
231 mode_flags |= DRM_MODE_FLAG_INTERLACE;
232 if (connector->doublescan_allowed)
233 mode_flags |= DRM_MODE_FLAG_DBLSCAN;
234 if (connector->stereo_allowed)
235 mode_flags |= DRM_MODE_FLAG_3D_MASK;
236
237 list_for_each_entry(mode, &connector->modes, head) {
238 if (mode->status == MODE_OK)
239 mode->status = drm_mode_validate_basic(mode);
240
241 if (mode->status == MODE_OK)
242 mode->status = drm_mode_validate_size(mode, maxX, maxY);
243
244 if (mode->status == MODE_OK)
245 mode->status = drm_mode_validate_flag(mode, mode_flags);
246
247 if (mode->status == MODE_OK && connector_funcs->mode_valid)
248 mode->status = connector_funcs->mode_valid(connector,
249 mode);
250 }
251
252 prune:
253 drm_mode_prune_invalid(dev, &connector->modes, verbose_prune);
254
255 if (list_empty(&connector->modes))
256 return 0;
257
258 list_for_each_entry(mode, &connector->modes, head)
259 mode->vrefresh = drm_mode_vrefresh(mode);
260
261 drm_mode_sort(&connector->modes);
262
263 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
264 connector->name);
265 list_for_each_entry(mode, &connector->modes, head) {
266 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
267 drm_mode_debug_printmodeline(mode);
268 }
269
270 return count;
271 }
272
273 /**
274 * drm_helper_probe_single_connector_modes - get complete set of display modes
275 * @connector: connector to probe
276 * @maxX: max width for modes
277 * @maxY: max height for modes
278 *
279 * Based on the helper callbacks implemented by @connector try to detect all
280 * valid modes. Modes will first be added to the connector's probed_modes list,
281 * then culled (based on validity and the @maxX, @maxY parameters) and put into
282 * the normal modes list.
283 *
284 * Intended to be use as a generic implementation of the ->fill_modes()
285 * @connector vfunc for drivers that use the crtc helpers for output mode
286 * filtering and detection.
287 *
288 * Returns:
289 * The number of modes found on @connector.
290 */
291 int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
292 uint32_t maxX, uint32_t maxY)
293 {
294 return drm_helper_probe_single_connector_modes_merge_bits(connector, maxX, maxY, true);
295 }
296 EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
297
298 /**
299 * drm_helper_probe_single_connector_modes_nomerge - get complete set of display modes
300 * @connector: connector to probe
301 * @maxX: max width for modes
302 * @maxY: max height for modes
303 *
304 * This operates like drm_hehlper_probe_single_connector_modes except it
305 * replaces the mode bits instead of merging them for preferred modes.
306 */
307 int drm_helper_probe_single_connector_modes_nomerge(struct drm_connector *connector,
308 uint32_t maxX, uint32_t maxY)
309 {
310 return drm_helper_probe_single_connector_modes_merge_bits(connector, maxX, maxY, false);
311 }
312 EXPORT_SYMBOL(drm_helper_probe_single_connector_modes_nomerge);
313
314 /**
315 * drm_kms_helper_hotplug_event - fire off KMS hotplug events
316 * @dev: drm_device whose connector state changed
317 *
318 * This function fires off the uevent for userspace and also calls the
319 * output_poll_changed function, which is most commonly used to inform the fbdev
320 * emulation code and allow it to update the fbcon output configuration.
321 *
322 * Drivers should call this from their hotplug handling code when a change is
323 * detected. Note that this function does not do any output detection of its
324 * own, like drm_helper_hpd_irq_event() does - this is assumed to be done by the
325 * driver already.
326 *
327 * This function must be called from process context with no mode
328 * setting locks held.
329 */
330 void drm_kms_helper_hotplug_event(struct drm_device *dev)
331 {
332 /* send a uevent + call fbdev */
333 drm_sysfs_hotplug_event(dev);
334 if (dev->mode_config.funcs->output_poll_changed)
335 dev->mode_config.funcs->output_poll_changed(dev);
336 }
337 EXPORT_SYMBOL(drm_kms_helper_hotplug_event);
338
339 static void output_poll_execute(struct work_struct *work)
340 {
341 struct delayed_work *delayed_work = to_delayed_work(work);
342 struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
343 struct drm_connector *connector;
344 enum drm_connector_status old_status;
345 bool repoll = false, changed;
346
347 /* Pick up any changes detected by the probe functions. */
348 changed = dev->mode_config.delayed_event;
349 dev->mode_config.delayed_event = false;
350
351 if (!drm_kms_helper_poll)
352 goto out;
353
354 mutex_lock(&dev->mode_config.mutex);
355 drm_for_each_connector(connector, dev) {
356
357 /* Ignore forced connectors. */
358 if (connector->force)
359 continue;
360
361 /* Ignore HPD capable connectors and connectors where we don't
362 * want any hotplug detection at all for polling. */
363 if (!connector->polled || connector->polled == DRM_CONNECTOR_POLL_HPD)
364 continue;
365
366 old_status = connector->status;
367 /* if we are connected and don't want to poll for disconnect
368 skip it */
369 if (old_status == connector_status_connected &&
370 !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT))
371 continue;
372
373 repoll = true;
374
375 connector->status = connector->funcs->detect(connector, false);
376 if (old_status != connector->status) {
377 const char *old, *new;
378
379 /*
380 * The poll work sets force=false when calling detect so
381 * that drivers can avoid to do disruptive tests (e.g.
382 * when load detect cycles could cause flickering on
383 * other, running displays). This bears the risk that we
384 * flip-flop between unknown here in the poll work and
385 * the real state when userspace forces a full detect
386 * call after receiving a hotplug event due to this
387 * change.
388 *
389 * Hence clamp an unknown detect status to the old
390 * value.
391 */
392 if (connector->status == connector_status_unknown) {
393 connector->status = old_status;
394 continue;
395 }
396
397 old = drm_get_connector_status_name(old_status);
398 new = drm_get_connector_status_name(connector->status);
399
400 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] "
401 "status updated from %s to %s\n",
402 connector->base.id,
403 connector->name,
404 old, new);
405
406 changed = true;
407 }
408 }
409
410 mutex_unlock(&dev->mode_config.mutex);
411
412 out:
413 if (changed)
414 drm_kms_helper_hotplug_event(dev);
415
416 if (repoll)
417 schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD);
418 }
419
420 /**
421 * drm_kms_helper_is_poll_worker - is %current task an output poll worker?
422 *
423 * Determine if %current task is an output poll worker. This can be used
424 * to select distinct code paths for output polling versus other contexts.
425 *
426 * One use case is to avoid a deadlock between the output poll worker and
427 * the autosuspend worker wherein the latter waits for polling to finish
428 * upon calling drm_kms_helper_poll_disable(), while the former waits for
429 * runtime suspend to finish upon calling pm_runtime_get_sync() in a
430 * connector ->detect hook.
431 */
432 bool drm_kms_helper_is_poll_worker(void)
433 {
434 struct work_struct *work = current_work();
435
436 return work && work->func == output_poll_execute;
437 }
438 EXPORT_SYMBOL(drm_kms_helper_is_poll_worker);
439
440 /**
441 * drm_kms_helper_poll_disable - disable output polling
442 * @dev: drm_device
443 *
444 * This function disables the output polling work.
445 *
446 * Drivers can call this helper from their device suspend implementation. It is
447 * not an error to call this even when output polling isn't enabled or arlready
448 * disabled.
449 */
450 void drm_kms_helper_poll_disable(struct drm_device *dev)
451 {
452 if (!dev->mode_config.poll_enabled)
453 return;
454 cancel_delayed_work_sync(&dev->mode_config.output_poll_work);
455 }
456 EXPORT_SYMBOL(drm_kms_helper_poll_disable);
457
458 /**
459 * drm_kms_helper_poll_enable - re-enable output polling.
460 * @dev: drm_device
461 *
462 * This function re-enables the output polling work.
463 *
464 * Drivers can call this helper from their device resume implementation. It is
465 * an error to call this when the output polling support has not yet been set
466 * up.
467 */
468 void drm_kms_helper_poll_enable(struct drm_device *dev)
469 {
470 mutex_lock(&dev->mode_config.mutex);
471 drm_kms_helper_poll_enable_locked(dev);
472 mutex_unlock(&dev->mode_config.mutex);
473 }
474 EXPORT_SYMBOL(drm_kms_helper_poll_enable);
475
476 /**
477 * drm_kms_helper_poll_init - initialize and enable output polling
478 * @dev: drm_device
479 *
480 * This function intializes and then also enables output polling support for
481 * @dev. Drivers which do not have reliable hotplug support in hardware can use
482 * this helper infrastructure to regularly poll such connectors for changes in
483 * their connection state.
484 *
485 * Drivers can control which connectors are polled by setting the
486 * DRM_CONNECTOR_POLL_CONNECT and DRM_CONNECTOR_POLL_DISCONNECT flags. On
487 * connectors where probing live outputs can result in visual distortion drivers
488 * should not set the DRM_CONNECTOR_POLL_DISCONNECT flag to avoid this.
489 * Connectors which have no flag or only DRM_CONNECTOR_POLL_HPD set are
490 * completely ignored by the polling logic.
491 *
492 * Note that a connector can be both polled and probed from the hotplug handler,
493 * in case the hotplug interrupt is known to be unreliable.
494 */
495 void drm_kms_helper_poll_init(struct drm_device *dev)
496 {
497 INIT_DELAYED_WORK(&dev->mode_config.output_poll_work, output_poll_execute);
498 dev->mode_config.poll_enabled = true;
499
500 drm_kms_helper_poll_enable(dev);
501 }
502 EXPORT_SYMBOL(drm_kms_helper_poll_init);
503
504 /**
505 * drm_kms_helper_poll_fini - disable output polling and clean it up
506 * @dev: drm_device
507 */
508 void drm_kms_helper_poll_fini(struct drm_device *dev)
509 {
510 drm_kms_helper_poll_disable(dev);
511 }
512 EXPORT_SYMBOL(drm_kms_helper_poll_fini);
513
514 /**
515 * drm_helper_hpd_irq_event - hotplug processing
516 * @dev: drm_device
517 *
518 * Drivers can use this helper function to run a detect cycle on all connectors
519 * which have the DRM_CONNECTOR_POLL_HPD flag set in their &polled member. All
520 * other connectors are ignored, which is useful to avoid reprobing fixed
521 * panels.
522 *
523 * This helper function is useful for drivers which can't or don't track hotplug
524 * interrupts for each connector.
525 *
526 * Drivers which support hotplug interrupts for each connector individually and
527 * which have a more fine-grained detect logic should bypass this code and
528 * directly call drm_kms_helper_hotplug_event() in case the connector state
529 * changed.
530 *
531 * This function must be called from process context with no mode
532 * setting locks held.
533 *
534 * Note that a connector can be both polled and probed from the hotplug handler,
535 * in case the hotplug interrupt is known to be unreliable.
536 */
537 bool drm_helper_hpd_irq_event(struct drm_device *dev)
538 {
539 struct drm_connector *connector;
540 enum drm_connector_status old_status;
541 bool changed = false;
542
543 if (!dev->mode_config.poll_enabled)
544 return false;
545
546 mutex_lock(&dev->mode_config.mutex);
547 drm_for_each_connector(connector, dev) {
548
549 /* Only handle HPD capable connectors. */
550 if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))
551 continue;
552
553 old_status = connector->status;
554
555 connector->status = connector->funcs->detect(connector, false);
556 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n",
557 connector->base.id,
558 connector->name,
559 drm_get_connector_status_name(old_status),
560 drm_get_connector_status_name(connector->status));
561 if (old_status != connector->status)
562 changed = true;
563 }
564
565 mutex_unlock(&dev->mode_config.mutex);
566
567 if (changed)
568 drm_kms_helper_hotplug_event(dev);
569
570 return changed;
571 }
572 EXPORT_SYMBOL(drm_helper_hpd_irq_event);
573