xref: /dragonfly/sys/dev/drm/drm_crtc_helper.c (revision 18e26a6d)
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  * $FreeBSD: src/sys/dev/drm2/drm_crtc_helper.c,v 1.1 2012/05/22 11:07:44 kib Exp $
32  */
33 
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <drm/drmP.h>
37 #include <drm/drm_crtc.h>
38 #include <uapi_drm/drm_fourcc.h>
39 #include <drm/drm_crtc_helper.h>
40 #include <drm/drm_fb_helper.h>
41 
42 bool
43 drm_fetch_cmdline_mode_from_kenv(struct drm_connector *connector,
44     struct drm_cmdline_mode *cmdline_mode)
45 {
46 	char *tun_var_name, *tun_mode;
47 	static const char tun_prefix[] = "drm_mode.";
48 	bool res;
49 
50 	res = false;
51 	tun_var_name = kmalloc(sizeof(tun_prefix) +
52 	    strlen(drm_get_connector_name(connector)), M_TEMP, M_WAITOK);
53 	strcpy(tun_var_name, tun_prefix);
54 	strcat(tun_var_name, drm_get_connector_name(connector));
55 	tun_mode = kgetenv(tun_var_name);
56 	if (tun_mode != NULL) {
57 		res = drm_mode_parse_command_line_for_connector(tun_mode,
58 		    connector, cmdline_mode);
59 		kfreeenv(tun_mode);
60 	}
61 	drm_free(tun_var_name, M_TEMP);
62 	return (res);
63 }
64 
65 static bool drm_kms_helper_poll = false; // XXX fix and reenable
66 
67 static void drm_mode_validate_flag(struct drm_connector *connector,
68 				   int flags)
69 {
70 	struct drm_display_mode *mode, *t;
71 
72 	if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE))
73 		return;
74 
75 	list_for_each_entry_safe(mode, t, &connector->modes, head) {
76 		if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
77 				!(flags & DRM_MODE_FLAG_INTERLACE))
78 			mode->status = MODE_NO_INTERLACE;
79 		if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
80 				!(flags & DRM_MODE_FLAG_DBLSCAN))
81 			mode->status = MODE_NO_DBLESCAN;
82 	}
83 
84 	return;
85 }
86 
87 /**
88  * drm_helper_probe_single_connector_modes - get complete set of display modes
89  * @dev: DRM device
90  * @maxX: max width for modes
91  * @maxY: max height for modes
92  *
93  * LOCKING:
94  * Caller must hold mode config lock.
95  *
96  * Based on @dev's mode_config layout, scan all the connectors and try to detect
97  * modes on them.  Modes will first be added to the connector's probed_modes
98  * list, then culled (based on validity and the @maxX, @maxY parameters) and
99  * put into the normal modes list.
100  *
101  * Intended to be used either at bootup time or when major configuration
102  * changes have occurred.
103  *
104  * FIXME: take into account monitor limits
105  *
106  * RETURNS:
107  * Number of modes found on @connector.
108  */
109 int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
110 					    uint32_t maxX, uint32_t maxY)
111 {
112 	struct drm_device *dev = connector->dev;
113 	struct drm_display_mode *mode, *t;
114 	struct drm_connector_helper_funcs *connector_funcs =
115 		connector->helper_private;
116 	struct drm_cmdline_mode cmdline_mode;
117 	int count = 0;
118 	int mode_flags = 0;
119 
120 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
121 			drm_get_connector_name(connector));
122 	/* set all modes to the unverified state */
123 	list_for_each_entry_safe(mode, t, &connector->modes, head)
124 		mode->status = MODE_UNVERIFIED;
125 
126 	if (connector->force) {
127 		if (connector->force == DRM_FORCE_ON)
128 			connector->status = connector_status_connected;
129 		else
130 			connector->status = connector_status_disconnected;
131 		if (connector->funcs->force)
132 			connector->funcs->force(connector);
133 	} else {
134 		connector->status = connector->funcs->detect(connector, true);
135 		drm_kms_helper_poll_enable(dev);
136 	}
137 
138 	if (connector->status == connector_status_disconnected) {
139 		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
140 			connector->base.id, drm_get_connector_name(connector));
141 		drm_mode_connector_update_edid_property(connector, NULL);
142 		goto prune;
143 	}
144 
145 	count = (*connector_funcs->get_modes)(connector);
146 	if (count == 0 && drm_fetch_cmdline_mode_from_kenv(connector,
147 	    &cmdline_mode)) {
148 		mode = drm_mode_create_from_cmdline_mode(dev,
149 		    &cmdline_mode);
150 		if (mode != NULL) {
151 			DRM_DEBUG_KMS(
152 	"[CONNECTOR:%d:%s] found manual override ",
153 			    connector->base.id,
154 			    drm_get_connector_name(connector));
155 			drm_mode_debug_printmodeline(mode);
156 			drm_mode_probed_add(connector, mode);
157 			count++;
158 		} else {
159 			DRM_ERROR(
160 	"[CONNECTOR:%d:%s] manual override mode: parse error\n",
161 			    connector->base.id,
162 			    drm_get_connector_name(connector));
163 		}
164 	}
165 	if (count == 0 && connector->status == connector_status_connected)
166 		count = drm_add_modes_noedid(connector, 1024, 768);
167 	if (count == 0)
168 		goto prune;
169 
170 	drm_mode_connector_list_update(connector);
171 
172 	if (maxX && maxY)
173 		drm_mode_validate_size(dev, &connector->modes, maxX,
174 				       maxY, 0);
175 
176 	if (connector->interlace_allowed)
177 		mode_flags |= DRM_MODE_FLAG_INTERLACE;
178 	if (connector->doublescan_allowed)
179 		mode_flags |= DRM_MODE_FLAG_DBLSCAN;
180 	drm_mode_validate_flag(connector, mode_flags);
181 
182 	list_for_each_entry_safe(mode, t, &connector->modes, head) {
183 		if (mode->status == MODE_OK)
184 			mode->status = connector_funcs->mode_valid(connector,
185 								   mode);
186 	}
187 
188 prune:
189 	drm_mode_prune_invalid(dev, &connector->modes, true);
190 
191 	if (list_empty(&connector->modes))
192 		return 0;
193 
194 	drm_mode_sort(&connector->modes);
195 
196 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
197 			drm_get_connector_name(connector));
198 	list_for_each_entry_safe(mode, t, &connector->modes, head) {
199 		mode->vrefresh = drm_mode_vrefresh(mode);
200 
201 		drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
202 		drm_mode_debug_printmodeline(mode);
203 	}
204 
205 	return count;
206 }
207 
208 /**
209  * drm_helper_encoder_in_use - check if a given encoder is in use
210  * @encoder: encoder to check
211  *
212  * LOCKING:
213  * Caller must hold mode config lock.
214  *
215  * Walk @encoders's DRM device's mode_config and see if it's in use.
216  *
217  * RETURNS:
218  * True if @encoder is part of the mode_config, false otherwise.
219  */
220 bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
221 {
222 	struct drm_connector *connector;
223 	struct drm_device *dev = encoder->dev;
224 	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
225 		if (connector->encoder == encoder)
226 			return true;
227 	return false;
228 }
229 
230 /**
231  * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config
232  * @crtc: CRTC to check
233  *
234  * LOCKING:
235  * Caller must hold mode config lock.
236  *
237  * Walk @crtc's DRM device's mode_config and see if it's in use.
238  *
239  * RETURNS:
240  * True if @crtc is part of the mode_config, false otherwise.
241  */
242 bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
243 {
244 	struct drm_encoder *encoder;
245 	struct drm_device *dev = crtc->dev;
246 	/* FIXME: Locking around list access? */
247 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
248 		if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder))
249 			return true;
250 	return false;
251 }
252 
253 static void
254 drm_encoder_disable(struct drm_encoder *encoder)
255 {
256 	struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
257 
258 	if (encoder_funcs->disable)
259 		(*encoder_funcs->disable)(encoder);
260 	else
261 		(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
262 }
263 
264 /**
265  * drm_helper_disable_unused_functions - disable unused objects
266  * @dev: DRM device
267  *
268  * LOCKING:
269  * Caller must hold mode config lock.
270  *
271  * If an connector or CRTC isn't part of @dev's mode_config, it can be disabled
272  * by calling its dpms function, which should power it off.
273  */
274 void drm_helper_disable_unused_functions(struct drm_device *dev)
275 {
276 	struct drm_encoder *encoder;
277 	struct drm_connector *connector;
278 	struct drm_crtc *crtc;
279 
280 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
281 		if (!connector->encoder)
282 			continue;
283 		if (connector->status == connector_status_disconnected)
284 			connector->encoder = NULL;
285 	}
286 
287 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
288 		if (!drm_helper_encoder_in_use(encoder)) {
289 			drm_encoder_disable(encoder);
290 			/* disconnector encoder from any connector */
291 			encoder->crtc = NULL;
292 		}
293 	}
294 
295 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
296 		struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
297 		crtc->enabled = drm_helper_crtc_in_use(crtc);
298 		if (!crtc->enabled) {
299 			if (crtc_funcs->disable)
300 				(*crtc_funcs->disable)(crtc);
301 			else
302 				(*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
303 			crtc->fb = NULL;
304 		}
305 	}
306 }
307 
308 /**
309  * drm_encoder_crtc_ok - can a given crtc drive a given encoder?
310  * @encoder: encoder to test
311  * @crtc: crtc to test
312  *
313  * Return false if @encoder can't be driven by @crtc, true otherwise.
314  */
315 static bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
316 				struct drm_crtc *crtc)
317 {
318 	struct drm_device *dev;
319 	struct drm_crtc *tmp;
320 	int crtc_mask = 1;
321 
322 	if (crtc == NULL)
323 		kprintf("checking null crtc?\n");
324 
325 	dev = crtc->dev;
326 
327 	list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) {
328 		if (tmp == crtc)
329 			break;
330 		crtc_mask <<= 1;
331 	}
332 
333 	if (encoder->possible_crtcs & crtc_mask)
334 		return true;
335 	return false;
336 }
337 
338 /*
339  * Check the CRTC we're going to map each output to vs. its current
340  * CRTC.  If they don't match, we have to disable the output and the CRTC
341  * since the driver will have to re-route things.
342  */
343 static void
344 drm_crtc_prepare_encoders(struct drm_device *dev)
345 {
346 	struct drm_encoder_helper_funcs *encoder_funcs;
347 	struct drm_encoder *encoder;
348 
349 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
350 		encoder_funcs = encoder->helper_private;
351 		/* Disable unused encoders */
352 		if (encoder->crtc == NULL)
353 			drm_encoder_disable(encoder);
354 		/* Disable encoders whose CRTC is about to change */
355 		if (encoder_funcs->get_crtc &&
356 		    encoder->crtc != (*encoder_funcs->get_crtc)(encoder))
357 			drm_encoder_disable(encoder);
358 	}
359 }
360 
361 /**
362  * drm_crtc_set_mode - set a mode
363  * @crtc: CRTC to program
364  * @mode: mode to use
365  * @x: width of mode
366  * @y: height of mode
367  *
368  * LOCKING:
369  * Caller must hold mode config lock.
370  *
371  * Try to set @mode on @crtc.  Give @crtc and its associated connectors a chance
372  * to fixup or reject the mode prior to trying to set it.
373  *
374  * RETURNS:
375  * True if the mode was set successfully, or false otherwise.
376  */
377 bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
378 			      struct drm_display_mode *mode,
379 			      int x, int y,
380 			      struct drm_framebuffer *old_fb)
381 {
382 	struct drm_device *dev = crtc->dev;
383 	struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
384 	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
385 	struct drm_encoder_helper_funcs *encoder_funcs;
386 	int saved_x, saved_y;
387 	struct drm_encoder *encoder;
388 	bool ret = true;
389 
390 	crtc->enabled = drm_helper_crtc_in_use(crtc);
391 	if (!crtc->enabled)
392 		return true;
393 
394 	adjusted_mode = drm_mode_duplicate(dev, mode);
395 	if (!adjusted_mode)
396 		return false;
397 
398 	saved_hwmode = crtc->hwmode;
399 	saved_mode = crtc->mode;
400 	saved_x = crtc->x;
401 	saved_y = crtc->y;
402 
403 	/* Update crtc values up front so the driver can rely on them for mode
404 	 * setting.
405 	 */
406 	crtc->mode = *mode;
407 	crtc->x = x;
408 	crtc->y = y;
409 
410 	/* Pass our mode to the connectors and the CRTC to give them a chance to
411 	 * adjust it according to limitations or connector properties, and also
412 	 * a chance to reject the mode entirely.
413 	 */
414 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
415 
416 		if (encoder->crtc != crtc)
417 			continue;
418 		encoder_funcs = encoder->helper_private;
419 		if (!(ret = encoder_funcs->mode_fixup(encoder, mode,
420 						      adjusted_mode))) {
421 			goto done;
422 		}
423 	}
424 
425 	if (!(ret = crtc_funcs->mode_fixup(crtc, mode, adjusted_mode))) {
426 		goto done;
427 	}
428 	DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
429 
430 	/* Prepare the encoders and CRTCs before setting the mode. */
431 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
432 
433 		if (encoder->crtc != crtc)
434 			continue;
435 		encoder_funcs = encoder->helper_private;
436 		/* Disable the encoders as the first thing we do. */
437 		encoder_funcs->prepare(encoder);
438 	}
439 
440 	drm_crtc_prepare_encoders(dev);
441 
442 	crtc_funcs->prepare(crtc);
443 
444 	/* Set up the DPLL and any encoders state that needs to adjust or depend
445 	 * on the DPLL.
446 	 */
447 	ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
448 	if (!ret)
449 	    goto done;
450 
451 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
452 
453 		if (encoder->crtc != crtc)
454 			continue;
455 
456 		DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n",
457 			encoder->base.id, drm_get_encoder_name(encoder),
458 			mode->base.id, mode->name);
459 		encoder_funcs = encoder->helper_private;
460 		encoder_funcs->mode_set(encoder, mode, adjusted_mode);
461 	}
462 
463 	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
464 	crtc_funcs->commit(crtc);
465 
466 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
467 
468 		if (encoder->crtc != crtc)
469 			continue;
470 
471 		encoder_funcs = encoder->helper_private;
472 		encoder_funcs->commit(encoder);
473 
474 	}
475 
476 	/* Store real post-adjustment hardware mode. */
477 	crtc->hwmode = *adjusted_mode;
478 
479 	/* Calculate and store various constants which
480 	 * are later needed by vblank and swap-completion
481 	 * timestamping. They are derived from true hwmode.
482 	 */
483 	drm_calc_timestamping_constants(crtc);
484 
485 	/* FIXME: add subpixel order */
486 done:
487 	drm_mode_destroy(dev, adjusted_mode);
488 	if (!ret) {
489 		crtc->hwmode = saved_hwmode;
490 		crtc->mode = saved_mode;
491 		crtc->x = saved_x;
492 		crtc->y = saved_y;
493 	}
494 
495 	return ret;
496 }
497 
498 static int
499 drm_crtc_helper_disable(struct drm_crtc *crtc)
500 {
501 	struct drm_device *dev = crtc->dev;
502 	struct drm_connector *connector;
503 	struct drm_encoder *encoder;
504 
505 	/* Decouple all encoders and their attached connectors from this crtc */
506 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
507 		if (encoder->crtc != crtc)
508 			continue;
509 
510 		list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
511 			if (connector->encoder != encoder)
512 				continue;
513 
514 			connector->encoder = NULL;
515 		}
516 	}
517 
518 	drm_helper_disable_unused_functions(dev);
519 	return 0;
520 }
521 
522 /**
523  * drm_crtc_helper_set_config - set a new config from userspace
524  * @crtc: CRTC to setup
525  * @crtc_info: user provided configuration
526  * @new_mode: new mode to set
527  * @connector_set: set of connectors for the new config
528  * @fb: new framebuffer
529  *
530  * LOCKING:
531  * Caller must hold mode config lock.
532  *
533  * Setup a new configuration, provided by the user in @crtc_info, and enable
534  * it.
535  *
536  * RETURNS:
537  * Zero. (FIXME)
538  */
539 int drm_crtc_helper_set_config(struct drm_mode_set *set)
540 {
541 	struct drm_device *dev;
542 	struct drm_crtc *save_crtcs, *new_crtc, *crtc;
543 	struct drm_encoder *save_encoders, *new_encoder, *encoder;
544 	struct drm_framebuffer *old_fb = NULL;
545 	bool mode_changed = false; /* if true do a full mode set */
546 	bool fb_changed = false; /* if true and !mode_changed just do a flip */
547 	struct drm_connector *save_connectors, *connector;
548 	int count = 0, ro, fail = 0;
549 	struct drm_crtc_helper_funcs *crtc_funcs;
550 	struct drm_mode_set save_set;
551 	int ret = 0;
552 	int i;
553 
554 	DRM_DEBUG_KMS("\n");
555 
556 	if (!set)
557 		return -EINVAL;
558 
559 	if (!set->crtc)
560 		return -EINVAL;
561 
562 	if (!set->crtc->helper_private)
563 		return -EINVAL;
564 
565 	crtc_funcs = set->crtc->helper_private;
566 
567 	if (!set->mode)
568 		set->fb = NULL;
569 
570 	if (set->fb) {
571 		DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n",
572 				set->crtc->base.id, set->fb->base.id,
573 				(int)set->num_connectors, set->x, set->y);
574 	} else {
575 		DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id);
576 		return drm_crtc_helper_disable(set->crtc);
577 	}
578 
579 	dev = set->crtc->dev;
580 
581 	/* Allocate space for the backup of all (non-pointer) crtc, encoder and
582 	 * connector data. */
583 	save_crtcs = kmalloc(dev->mode_config.num_crtc * sizeof(struct drm_crtc),
584 	    DRM_MEM_KMS, M_WAITOK | M_ZERO);
585 	save_encoders = kmalloc(dev->mode_config.num_encoder *
586 	    sizeof(struct drm_encoder), DRM_MEM_KMS, M_WAITOK | M_ZERO);
587 	save_connectors = kmalloc(dev->mode_config.num_connector *
588 	    sizeof(struct drm_connector), DRM_MEM_KMS, M_WAITOK | M_ZERO);
589 
590 	/* Copy data. Note that driver private data is not affected.
591 	 * Should anything bad happen only the expected state is
592 	 * restored, not the drivers personal bookkeeping.
593 	 */
594 	count = 0;
595 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
596 		save_crtcs[count++] = *crtc;
597 	}
598 
599 	count = 0;
600 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
601 		save_encoders[count++] = *encoder;
602 	}
603 
604 	count = 0;
605 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
606 		save_connectors[count++] = *connector;
607 	}
608 
609 	save_set.crtc = set->crtc;
610 	save_set.mode = &set->crtc->mode;
611 	save_set.x = set->crtc->x;
612 	save_set.y = set->crtc->y;
613 	save_set.fb = set->crtc->fb;
614 
615 	/* We should be able to check here if the fb has the same properties
616 	 * and then just flip_or_move it */
617 	if (set->crtc->fb != set->fb) {
618 		/* If we have no fb then treat it as a full mode set */
619 		if (set->crtc->fb == NULL) {
620 			DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
621 			mode_changed = true;
622 		} else if (set->fb == NULL) {
623 			mode_changed = true;
624 		} else
625 			fb_changed = true;
626 	}
627 
628 	if (set->x != set->crtc->x || set->y != set->crtc->y)
629 		fb_changed = true;
630 
631 	if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) {
632 		DRM_DEBUG_KMS("modes are different, full mode set\n");
633 		drm_mode_debug_printmodeline(&set->crtc->mode);
634 		drm_mode_debug_printmodeline(set->mode);
635 		mode_changed = true;
636 	}
637 
638 	/* a) traverse passed in connector list and get encoders for them */
639 	count = 0;
640 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
641 		struct drm_connector_helper_funcs *connector_funcs =
642 			connector->helper_private;
643 		new_encoder = connector->encoder;
644 		for (ro = 0; ro < set->num_connectors; ro++) {
645 			if (set->connectors[ro] == connector) {
646 				new_encoder = connector_funcs->best_encoder(connector);
647 				/* if we can't get an encoder for a connector
648 				   we are setting now - then fail */
649 				if (new_encoder == NULL)
650 					/* don't break so fail path works correct */
651 					fail = 1;
652 				break;
653 			}
654 		}
655 
656 		if (new_encoder != connector->encoder) {
657 			DRM_DEBUG_KMS("encoder changed, full mode switch\n");
658 			mode_changed = true;
659 			/* If the encoder is reused for another connector, then
660 			 * the appropriate crtc will be set later.
661 			 */
662 			if (connector->encoder)
663 				connector->encoder->crtc = NULL;
664 			connector->encoder = new_encoder;
665 		}
666 	}
667 
668 	if (fail) {
669 		ret = -EINVAL;
670 		goto fail;
671 	}
672 
673 	count = 0;
674 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
675 		if (!connector->encoder)
676 			continue;
677 
678 		if (connector->encoder->crtc == set->crtc)
679 			new_crtc = NULL;
680 		else
681 			new_crtc = connector->encoder->crtc;
682 
683 		for (ro = 0; ro < set->num_connectors; ro++) {
684 			if (set->connectors[ro] == connector)
685 				new_crtc = set->crtc;
686 		}
687 
688 		/* Make sure the new CRTC will work with the encoder */
689 		if (new_crtc &&
690 		    !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
691 			ret = -EINVAL;
692 			goto fail;
693 		}
694 		if (new_crtc != connector->encoder->crtc) {
695 			DRM_DEBUG_KMS("crtc changed, full mode switch\n");
696 			mode_changed = true;
697 			connector->encoder->crtc = new_crtc;
698 		}
699 		if (new_crtc) {
700 			DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n",
701 				connector->base.id, drm_get_connector_name(connector),
702 				new_crtc->base.id);
703 		} else {
704 			DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
705 				connector->base.id, drm_get_connector_name(connector));
706 		}
707 	}
708 
709 	/* mode_set_base is not a required function */
710 	if (fb_changed && !crtc_funcs->mode_set_base)
711 		mode_changed = true;
712 
713 	if (mode_changed) {
714 		set->crtc->enabled = drm_helper_crtc_in_use(set->crtc);
715 		if (set->crtc->enabled) {
716 			DRM_DEBUG_KMS("attempting to set mode from"
717 					" userspace\n");
718 			drm_mode_debug_printmodeline(set->mode);
719 			old_fb = set->crtc->fb;
720 			set->crtc->fb = set->fb;
721 			if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
722 						      set->x, set->y,
723 						      old_fb)) {
724 				DRM_ERROR("failed to set mode on [CRTC:%d]\n",
725 					  set->crtc->base.id);
726 				set->crtc->fb = old_fb;
727 				ret = -EINVAL;
728 				goto fail;
729 			}
730 			DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
731 			for (i = 0; i < set->num_connectors; i++) {
732 				DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id,
733 					      drm_get_connector_name(set->connectors[i]));
734 				set->connectors[i]->dpms = DRM_MODE_DPMS_ON;
735 			}
736 		}
737 		drm_helper_disable_unused_functions(dev);
738 	} else if (fb_changed) {
739 		set->crtc->x = set->x;
740 		set->crtc->y = set->y;
741 
742 		old_fb = set->crtc->fb;
743 		if (set->crtc->fb != set->fb)
744 			set->crtc->fb = set->fb;
745 		ret = crtc_funcs->mode_set_base(set->crtc,
746 						set->x, set->y, old_fb);
747 		if (ret != 0) {
748 			set->crtc->fb = old_fb;
749 			goto fail;
750 		}
751 	}
752 
753 	drm_free(save_connectors, DRM_MEM_KMS);
754 	drm_free(save_encoders, DRM_MEM_KMS);
755 	drm_free(save_crtcs, DRM_MEM_KMS);
756 	return 0;
757 
758 fail:
759 	/* Restore all previous data. */
760 	count = 0;
761 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
762 		*crtc = save_crtcs[count++];
763 	}
764 
765 	count = 0;
766 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
767 		*encoder = save_encoders[count++];
768 	}
769 
770 	count = 0;
771 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
772 		*connector = save_connectors[count++];
773 	}
774 
775 	/* Try to restore the config */
776 	if (mode_changed &&
777 	    !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x,
778 				      save_set.y, save_set.fb))
779 		DRM_ERROR("failed to restore config after modeset failure\n");
780 
781 	drm_free(save_connectors, DRM_MEM_KMS);
782 	drm_free(save_encoders, DRM_MEM_KMS);
783 	drm_free(save_crtcs, DRM_MEM_KMS);
784 	return ret;
785 }
786 
787 static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
788 {
789 	int dpms = DRM_MODE_DPMS_OFF;
790 	struct drm_connector *connector;
791 	struct drm_device *dev = encoder->dev;
792 
793 	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
794 		if (connector->encoder == encoder)
795 			if (connector->dpms < dpms)
796 				dpms = connector->dpms;
797 	return dpms;
798 }
799 
800 static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
801 {
802 	int dpms = DRM_MODE_DPMS_OFF;
803 	struct drm_connector *connector;
804 	struct drm_device *dev = crtc->dev;
805 
806 	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
807 		if (connector->encoder && connector->encoder->crtc == crtc)
808 			if (connector->dpms < dpms)
809 				dpms = connector->dpms;
810 	return dpms;
811 }
812 
813 /**
814  * drm_helper_connector_dpms
815  * @connector affected connector
816  * @mode DPMS mode
817  *
818  * Calls the low-level connector DPMS function, then
819  * calls appropriate encoder and crtc DPMS functions as well
820  */
821 void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
822 {
823 	struct drm_encoder *encoder = connector->encoder;
824 	struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
825 	int old_dpms;
826 
827 	if (mode == connector->dpms)
828 		return;
829 
830 	old_dpms = connector->dpms;
831 	connector->dpms = mode;
832 
833 	/* from off to on, do crtc then encoder */
834 	if (mode < old_dpms) {
835 		if (crtc) {
836 			struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
837 			if (crtc_funcs->dpms)
838 				(*crtc_funcs->dpms) (crtc,
839 						     drm_helper_choose_crtc_dpms(crtc));
840 		}
841 		if (encoder) {
842 			struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
843 			if (encoder_funcs->dpms)
844 				(*encoder_funcs->dpms) (encoder,
845 							drm_helper_choose_encoder_dpms(encoder));
846 		}
847 	}
848 
849 	/* from on to off, do encoder then crtc */
850 	if (mode > old_dpms) {
851 		if (encoder) {
852 			struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
853 			if (encoder_funcs->dpms)
854 				(*encoder_funcs->dpms) (encoder,
855 							drm_helper_choose_encoder_dpms(encoder));
856 		}
857 		if (crtc) {
858 			struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
859 			if (crtc_funcs->dpms)
860 				(*crtc_funcs->dpms) (crtc,
861 						     drm_helper_choose_crtc_dpms(crtc));
862 		}
863 	}
864 
865 	return;
866 }
867 
868 int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
869 				   struct drm_mode_fb_cmd2 *mode_cmd)
870 {
871 	int i;
872 
873 	fb->width = mode_cmd->width;
874 	fb->height = mode_cmd->height;
875 	for (i = 0; i < 4; i++) {
876 		fb->pitches[i] = mode_cmd->pitches[i];
877 		fb->offsets[i] = mode_cmd->offsets[i];
878 	}
879 	drm_fb_get_bpp_depth(mode_cmd->pixel_format, &fb->depth,
880 				    &fb->bits_per_pixel);
881 	fb->pixel_format = mode_cmd->pixel_format;
882 
883 	return 0;
884 }
885 
886 int drm_helper_resume_force_mode(struct drm_device *dev)
887 {
888 	struct drm_crtc *crtc;
889 	struct drm_encoder *encoder;
890 	struct drm_encoder_helper_funcs *encoder_funcs;
891 	struct drm_crtc_helper_funcs *crtc_funcs;
892 	int ret;
893 
894 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
895 
896 		if (!crtc->enabled)
897 			continue;
898 
899 		ret = drm_crtc_helper_set_mode(crtc, &crtc->mode,
900 					       crtc->x, crtc->y, crtc->fb);
901 
902 		if (!ret)
903 			DRM_ERROR("failed to set mode on crtc %p\n", crtc);
904 
905 		/* Turn off outputs that were already powered off */
906 		if (drm_helper_choose_crtc_dpms(crtc)) {
907 			list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
908 
909 				if(encoder->crtc != crtc)
910 					continue;
911 
912 				encoder_funcs = encoder->helper_private;
913 				if (encoder_funcs->dpms)
914 					(*encoder_funcs->dpms) (encoder,
915 					    drm_helper_choose_encoder_dpms(encoder));
916 			}
917 
918 			crtc_funcs = crtc->helper_private;
919 			if (crtc_funcs->dpms)
920 				(*crtc_funcs->dpms) (crtc,
921 				    drm_helper_choose_crtc_dpms(crtc));
922 		}
923 	}
924 	/* disable the unused connectors while restoring the modesetting */
925 	drm_helper_disable_unused_functions(dev);
926 	return 0;
927 }
928 
929 #define DRM_OUTPUT_POLL_PERIOD (10 * hz)
930 static void output_poll_execute(void *ctx, int pending)
931 {
932 	struct drm_device *dev;
933 	struct drm_connector *connector;
934 	enum drm_connector_status old_status;
935 	bool repoll = false, changed = false;
936 
937 	if (!drm_kms_helper_poll)
938 		return;
939 
940 	dev = ctx;
941 
942 	lockmgr(&dev->mode_config.lock, LK_EXCLUSIVE);
943 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
944 
945 		/* if this is HPD or polled don't check it -
946 		   TV out for instance */
947 		if (!connector->polled)
948 			continue;
949 
950 		else if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
951 		    DRM_CONNECTOR_POLL_DISCONNECT))
952 			repoll = true;
953 
954 		old_status = connector->status;
955 		/* if we are connected and don't want to poll for disconnect
956 		   skip it */
957 		if (old_status == connector_status_connected &&
958 		    !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT) &&
959 		    !(connector->polled & DRM_CONNECTOR_POLL_HPD))
960 			continue;
961 
962 		connector->status = connector->funcs->detect(connector, false);
963 		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
964 			      connector->base.id,
965 			      drm_get_connector_name(connector),
966 			      old_status, connector->status);
967 		if (old_status != connector->status)
968 			changed = true;
969 	}
970 
971 	lockmgr(&dev->mode_config.lock, LK_RELEASE);
972 
973 	if (changed) {
974 #if 0
975 		/* send a uevent + call fbdev */
976 		drm_sysfs_hotplug_event(dev);
977 #endif
978 		if (dev->mode_config.funcs->output_poll_changed)
979 			dev->mode_config.funcs->output_poll_changed(dev);
980 	}
981 
982 	if (repoll) {
983 		taskqueue_enqueue_timeout(taskqueue_thread[mycpuid],
984 		    &dev->mode_config.output_poll_task,
985 		    DRM_OUTPUT_POLL_PERIOD);
986 	}
987 }
988 
989 void drm_kms_helper_poll_disable(struct drm_device *dev)
990 {
991 	if (!dev->mode_config.poll_enabled)
992 		return;
993 	taskqueue_cancel_timeout(taskqueue_thread[mycpuid],
994 	    &dev->mode_config.output_poll_task, NULL);
995 }
996 
997 void drm_kms_helper_poll_enable(struct drm_device *dev)
998 {
999 	bool poll = false;
1000 	struct drm_connector *connector;
1001 
1002 	if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
1003 		return;
1004 
1005 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1006 		if (connector->polled)
1007 			poll = true;
1008 	}
1009 
1010 	if (poll) {
1011 		taskqueue_enqueue_timeout(taskqueue_thread[mycpuid],
1012 		    &dev->mode_config.output_poll_task, DRM_OUTPUT_POLL_PERIOD);
1013 	}
1014 }
1015 
1016 void drm_kms_helper_poll_init(struct drm_device *dev)
1017 {
1018 
1019 	TIMEOUT_TASK_INIT(taskqueue_thread[mycpuid], &dev->mode_config.output_poll_task,
1020 	    0, output_poll_execute, dev);
1021 	dev->mode_config.poll_enabled = true;
1022 
1023 	drm_kms_helper_poll_enable(dev);
1024 }
1025 
1026 void drm_kms_helper_poll_fini(struct drm_device *dev)
1027 {
1028 	drm_kms_helper_poll_disable(dev);
1029 }
1030 
1031 void drm_helper_hpd_irq_event(struct drm_device *dev)
1032 {
1033 	if (!dev->mode_config.poll_enabled)
1034 		return;
1035 
1036 	/* kill timer and schedule immediate execution, this doesn't block */
1037 	taskqueue_cancel_timeout(taskqueue_thread[mycpuid],
1038 	    &dev->mode_config.output_poll_task, NULL);
1039 	if (drm_kms_helper_poll)
1040 		taskqueue_enqueue_timeout(taskqueue_thread[mycpuid],
1041 		    &dev->mode_config.output_poll_task, 0);
1042 }
1043