xref: /netbsd-src/sys/external/bsd/drm2/dist/drm/drm_crtc_helper.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
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/kernel.h>
33 #include <linux/export.h>
34 #include <linux/module.h>
35 #include <linux/moduleparam.h>
36 #include <asm/param.h>
37 #include <asm/bug.h>
38 
39 #include <drm/drmP.h>
40 #include <drm/drm_crtc.h>
41 #include <drm/drm_fourcc.h>
42 #include <drm/drm_crtc_helper.h>
43 #ifndef __NetBSD__
44 #include <drm/drm_fb_helper.h>
45 #endif
46 #include <drm/drm_edid.h>
47 
48 MODULE_AUTHOR("David Airlie, Jesse Barnes");
49 MODULE_DESCRIPTION("DRM KMS helper");
50 MODULE_LICENSE("GPL and additional rights");
51 
52 /**
53  * drm_helper_move_panel_connectors_to_head() - move panels to the front in the
54  * 						connector list
55  * @dev: drm device to operate on
56  *
57  * Some userspace presumes that the first connected connector is the main
58  * display, where it's supposed to display e.g. the login screen. For
59  * laptops, this should be the main panel. Use this function to sort all
60  * (eDP/LVDS) panels to the front of the connector list, instead of
61  * painstakingly trying to initialize them in the right order.
62  */
63 void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
64 {
65 	struct drm_connector *connector, *tmp;
66 	struct list_head panel_list;
67 
68 	INIT_LIST_HEAD(&panel_list);
69 
70 	list_for_each_entry_safe(connector, tmp,
71 				 &dev->mode_config.connector_list, head) {
72 		if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
73 		    connector->connector_type == DRM_MODE_CONNECTOR_eDP)
74 			list_move_tail(&connector->head, &panel_list);
75 	}
76 
77 	list_splice(&panel_list, &dev->mode_config.connector_list);
78 }
79 EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head);
80 
81 /**
82  * drm_helper_encoder_in_use - check if a given encoder is in use
83  * @encoder: encoder to check
84  *
85  * Checks whether @encoder is with the current mode setting output configuration
86  * in use by any connector. This doesn't mean that it is actually enabled since
87  * the DPMS state is tracked separately.
88  *
89  * Returns:
90  * True if @encoder is used, false otherwise.
91  */
92 bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
93 {
94 	struct drm_connector *connector;
95 	struct drm_device *dev = encoder->dev;
96 
97 	/*
98 	 * We can expect this mutex to be locked if we are not panicking.
99 	 * Locking is currently fubar in the panic handler.
100 	 */
101 	if (!oops_in_progress)
102 		WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
103 
104 	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
105 		if (connector->encoder == encoder)
106 			return true;
107 	return false;
108 }
109 EXPORT_SYMBOL(drm_helper_encoder_in_use);
110 
111 /**
112  * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config
113  * @crtc: CRTC to check
114  *
115  * Checks whether @crtc is with the current mode setting output configuration
116  * in use by any connector. This doesn't mean that it is actually enabled since
117  * the DPMS state is tracked separately.
118  *
119  * Returns:
120  * True if @crtc is used, false otherwise.
121  */
122 bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
123 {
124 	struct drm_encoder *encoder;
125 	struct drm_device *dev = crtc->dev;
126 
127 	/*
128 	 * We can expect this mutex to be locked if we are not panicking.
129 	 * Locking is currently fubar in the panic handler.
130 	 */
131 	if (!oops_in_progress)
132 		WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
133 
134 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
135 		if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder))
136 			return true;
137 	return false;
138 }
139 EXPORT_SYMBOL(drm_helper_crtc_in_use);
140 
141 static void
142 drm_encoder_disable(struct drm_encoder *encoder)
143 {
144 	struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
145 
146 	if (encoder->bridge)
147 		encoder->bridge->funcs->disable(encoder->bridge);
148 
149 	if (encoder_funcs->disable)
150 		(*encoder_funcs->disable)(encoder);
151 	else
152 		(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
153 
154 	if (encoder->bridge)
155 		encoder->bridge->funcs->post_disable(encoder->bridge);
156 }
157 
158 static void __drm_helper_disable_unused_functions(struct drm_device *dev)
159 {
160 	struct drm_encoder *encoder;
161 	struct drm_connector *connector;
162 	struct drm_crtc *crtc;
163 
164 	drm_warn_on_modeset_not_all_locked(dev);
165 
166 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
167 		if (!connector->encoder)
168 			continue;
169 	}
170 
171 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
172 		if (!drm_helper_encoder_in_use(encoder)) {
173 			drm_encoder_disable(encoder);
174 			/* disconnector encoder from any connector */
175 			encoder->crtc = NULL;
176 		}
177 	}
178 
179 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
180 		struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
181 		crtc->enabled = drm_helper_crtc_in_use(crtc);
182 		if (!crtc->enabled) {
183 			if (crtc_funcs->disable)
184 				(*crtc_funcs->disable)(crtc);
185 			else
186 				(*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
187 			crtc->primary->fb = NULL;
188 		}
189 	}
190 }
191 
192 /**
193  * drm_helper_disable_unused_functions - disable unused objects
194  * @dev: DRM device
195  *
196  * This function walks through the entire mode setting configuration of @dev. It
197  * will remove any crtc links of unused encoders and encoder links of
198  * disconnected connectors. Then it will disable all unused encoders and crtcs
199  * either by calling their disable callback if available or by calling their
200  * dpms callback with DRM_MODE_DPMS_OFF.
201  */
202 void drm_helper_disable_unused_functions(struct drm_device *dev)
203 {
204 	drm_modeset_lock_all(dev);
205 	__drm_helper_disable_unused_functions(dev);
206 	drm_modeset_unlock_all(dev);
207 }
208 EXPORT_SYMBOL(drm_helper_disable_unused_functions);
209 
210 /*
211  * Check the CRTC we're going to map each output to vs. its current
212  * CRTC.  If they don't match, we have to disable the output and the CRTC
213  * since the driver will have to re-route things.
214  */
215 static void
216 drm_crtc_prepare_encoders(struct drm_device *dev)
217 {
218 	struct drm_encoder_helper_funcs *encoder_funcs;
219 	struct drm_encoder *encoder;
220 
221 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
222 		encoder_funcs = encoder->helper_private;
223 		/* Disable unused encoders */
224 		if (encoder->crtc == NULL)
225 			drm_encoder_disable(encoder);
226 		/* Disable encoders whose CRTC is about to change */
227 		if (encoder_funcs->get_crtc &&
228 		    encoder->crtc != (*encoder_funcs->get_crtc)(encoder))
229 			drm_encoder_disable(encoder);
230 	}
231 }
232 
233 /**
234  * drm_crtc_helper_set_mode - internal helper to set a mode
235  * @crtc: CRTC to program
236  * @mode: mode to use
237  * @x: horizontal offset into the surface
238  * @y: vertical offset into the surface
239  * @old_fb: old framebuffer, for cleanup
240  *
241  * Try to set @mode on @crtc.  Give @crtc and its associated connectors a chance
242  * to fixup or reject the mode prior to trying to set it. This is an internal
243  * helper that drivers could e.g. use to update properties that require the
244  * entire output pipe to be disabled and re-enabled in a new configuration. For
245  * example for changing whether audio is enabled on a hdmi link or for changing
246  * panel fitter or dither attributes. It is also called by the
247  * drm_crtc_helper_set_config() helper function to drive the mode setting
248  * sequence.
249  *
250  * Returns:
251  * True if the mode was set successfully, false otherwise.
252  */
253 bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
254 			      struct drm_display_mode *mode,
255 			      int x, int y,
256 			      struct drm_framebuffer *old_fb)
257 {
258 	struct drm_device *dev = crtc->dev;
259 	struct drm_display_mode *adjusted_mode, saved_mode;
260 	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
261 	struct drm_encoder_helper_funcs *encoder_funcs;
262 	int saved_x, saved_y;
263 	bool saved_enabled;
264 	struct drm_encoder *encoder;
265 	bool ret = true;
266 
267 	drm_warn_on_modeset_not_all_locked(dev);
268 
269 	saved_enabled = crtc->enabled;
270 	crtc->enabled = drm_helper_crtc_in_use(crtc);
271 	if (!crtc->enabled)
272 		return true;
273 
274 	adjusted_mode = drm_mode_duplicate(dev, mode);
275 	if (!adjusted_mode) {
276 		crtc->enabled = saved_enabled;
277 		return false;
278 	}
279 
280 	saved_mode = crtc->mode;
281 	saved_x = crtc->x;
282 	saved_y = crtc->y;
283 
284 	/* Update crtc values up front so the driver can rely on them for mode
285 	 * setting.
286 	 */
287 	crtc->mode = *mode;
288 	crtc->x = x;
289 	crtc->y = y;
290 
291 	/* Pass our mode to the connectors and the CRTC to give them a chance to
292 	 * adjust it according to limitations or connector properties, and also
293 	 * a chance to reject the mode entirely.
294 	 */
295 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
296 
297 		if (encoder->crtc != crtc)
298 			continue;
299 
300 		if (encoder->bridge && encoder->bridge->funcs->mode_fixup) {
301 			ret = encoder->bridge->funcs->mode_fixup(
302 					encoder->bridge, mode, adjusted_mode);
303 			if (!ret) {
304 				DRM_DEBUG_KMS("Bridge fixup failed\n");
305 				goto done;
306 			}
307 		}
308 
309 		encoder_funcs = encoder->helper_private;
310 		if (!(ret = encoder_funcs->mode_fixup(encoder, mode,
311 						      adjusted_mode))) {
312 			DRM_DEBUG_KMS("Encoder fixup failed\n");
313 			goto done;
314 		}
315 	}
316 
317 	if (!(ret = crtc_funcs->mode_fixup(crtc, mode, adjusted_mode))) {
318 		DRM_DEBUG_KMS("CRTC fixup failed\n");
319 		goto done;
320 	}
321 	DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
322 
323 	/* Prepare the encoders and CRTCs before setting the mode. */
324 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
325 
326 		if (encoder->crtc != crtc)
327 			continue;
328 
329 		if (encoder->bridge)
330 			encoder->bridge->funcs->disable(encoder->bridge);
331 
332 		encoder_funcs = encoder->helper_private;
333 		/* Disable the encoders as the first thing we do. */
334 		encoder_funcs->prepare(encoder);
335 
336 		if (encoder->bridge)
337 			encoder->bridge->funcs->post_disable(encoder->bridge);
338 	}
339 
340 	drm_crtc_prepare_encoders(dev);
341 
342 	crtc_funcs->prepare(crtc);
343 
344 	/* Set up the DPLL and any encoders state that needs to adjust or depend
345 	 * on the DPLL.
346 	 */
347 	ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
348 	if (!ret)
349 	    goto done;
350 
351 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
352 
353 		if (encoder->crtc != crtc)
354 			continue;
355 
356 		DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n",
357 			encoder->base.id, drm_get_encoder_name(encoder),
358 			mode->base.id, mode->name);
359 		encoder_funcs = encoder->helper_private;
360 		encoder_funcs->mode_set(encoder, mode, adjusted_mode);
361 
362 		if (encoder->bridge && encoder->bridge->funcs->mode_set)
363 			encoder->bridge->funcs->mode_set(encoder->bridge, mode,
364 					adjusted_mode);
365 	}
366 
367 	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
368 	crtc_funcs->commit(crtc);
369 
370 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
371 
372 		if (encoder->crtc != crtc)
373 			continue;
374 
375 		if (encoder->bridge)
376 			encoder->bridge->funcs->pre_enable(encoder->bridge);
377 
378 		encoder_funcs = encoder->helper_private;
379 		encoder_funcs->commit(encoder);
380 
381 		if (encoder->bridge)
382 			encoder->bridge->funcs->enable(encoder->bridge);
383 	}
384 
385 	/* Store real post-adjustment hardware mode. */
386 	crtc->hwmode = *adjusted_mode;
387 
388 	/* Calculate and store various constants which
389 	 * are later needed by vblank and swap-completion
390 	 * timestamping. They are derived from true hwmode.
391 	 */
392 	drm_calc_timestamping_constants(crtc, &crtc->hwmode);
393 
394 	/* FIXME: add subpixel order */
395 done:
396 	drm_mode_destroy(dev, adjusted_mode);
397 	if (!ret) {
398 		crtc->enabled = saved_enabled;
399 		crtc->mode = saved_mode;
400 		crtc->x = saved_x;
401 		crtc->y = saved_y;
402 	}
403 
404 	return ret;
405 }
406 EXPORT_SYMBOL(drm_crtc_helper_set_mode);
407 
408 
409 static int
410 drm_crtc_helper_disable(struct drm_crtc *crtc)
411 {
412 	struct drm_device *dev = crtc->dev;
413 	struct drm_connector *connector;
414 	struct drm_encoder *encoder;
415 
416 	/* Decouple all encoders and their attached connectors from this crtc */
417 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
418 		if (encoder->crtc != crtc)
419 			continue;
420 
421 		list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
422 			if (connector->encoder != encoder)
423 				continue;
424 
425 			connector->encoder = NULL;
426 
427 			/*
428 			 * drm_helper_disable_unused_functions() ought to be
429 			 * doing this, but since we've decoupled the encoder
430 			 * from the connector above, the required connection
431 			 * between them is henceforth no longer available.
432 			 */
433 			connector->dpms = DRM_MODE_DPMS_OFF;
434 		}
435 	}
436 
437 	__drm_helper_disable_unused_functions(dev);
438 	return 0;
439 }
440 
441 /**
442  * drm_crtc_helper_set_config - set a new config from userspace
443  * @set: mode set configuration
444  *
445  * Setup a new configuration, provided by the upper layers (either an ioctl call
446  * from userspace or internally e.g. from the fbdev support code) in @set, and
447  * enable it. This is the main helper functions for drivers that implement
448  * kernel mode setting with the crtc helper functions and the assorted
449  * ->prepare(), ->modeset() and ->commit() helper callbacks.
450  *
451  * Returns:
452  * Returns 0 on success, negative errno numbers on failure.
453  */
454 int drm_crtc_helper_set_config(struct drm_mode_set *set)
455 {
456 	struct drm_device *dev;
457 	struct drm_crtc *new_crtc;
458 	struct drm_encoder *save_encoders, *new_encoder, *encoder;
459 	bool mode_changed = false; /* if true do a full mode set */
460 	bool fb_changed = false; /* if true and !mode_changed just do a flip */
461 	struct drm_connector *save_connectors, *connector;
462 	int count = 0, ro, fail = 0;
463 	struct drm_crtc_helper_funcs *crtc_funcs;
464 	struct drm_mode_set save_set;
465 	int ret;
466 	int i;
467 
468 	DRM_DEBUG_KMS("\n");
469 
470 	BUG_ON(!set);
471 	BUG_ON(!set->crtc);
472 	BUG_ON(!set->crtc->helper_private);
473 
474 	/* Enforce sane interface api - has been abused by the fb helper. */
475 	BUG_ON(!set->mode && set->fb);
476 	BUG_ON(set->fb && set->num_connectors == 0);
477 
478 	crtc_funcs = set->crtc->helper_private;
479 
480 	if (!set->mode)
481 		set->fb = NULL;
482 
483 	if (set->fb) {
484 		DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n",
485 				set->crtc->base.id, set->fb->base.id,
486 				(int)set->num_connectors, set->x, set->y);
487 	} else {
488 		DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id);
489 		return drm_crtc_helper_disable(set->crtc);
490 	}
491 
492 	dev = set->crtc->dev;
493 
494 	drm_warn_on_modeset_not_all_locked(dev);
495 
496 	/*
497 	 * Allocate space for the backup of all (non-pointer) encoder and
498 	 * connector data.
499 	 */
500 	save_encoders = kzalloc(dev->mode_config.num_encoder *
501 				sizeof(struct drm_encoder), GFP_KERNEL);
502 	if (!save_encoders)
503 		return -ENOMEM;
504 
505 	save_connectors = kzalloc(dev->mode_config.num_connector *
506 				sizeof(struct drm_connector), GFP_KERNEL);
507 	if (!save_connectors) {
508 		kfree(save_encoders);
509 		return -ENOMEM;
510 	}
511 
512 	/*
513 	 * Copy data. Note that driver private data is not affected.
514 	 * Should anything bad happen only the expected state is
515 	 * restored, not the drivers personal bookkeeping.
516 	 */
517 	count = 0;
518 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
519 		save_encoders[count++] = *encoder;
520 	}
521 
522 	count = 0;
523 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
524 		save_connectors[count++] = *connector;
525 	}
526 
527 	save_set.crtc = set->crtc;
528 	save_set.mode = &set->crtc->mode;
529 	save_set.x = set->crtc->x;
530 	save_set.y = set->crtc->y;
531 	save_set.fb = set->crtc->primary->fb;
532 
533 	/* We should be able to check here if the fb has the same properties
534 	 * and then just flip_or_move it */
535 	if (set->crtc->primary->fb != set->fb) {
536 		/* If we have no fb then treat it as a full mode set */
537 		if (set->crtc->primary->fb == NULL) {
538 			DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
539 			mode_changed = true;
540 		} else if (set->fb == NULL) {
541 			mode_changed = true;
542 		} else if (set->fb->pixel_format !=
543 			   set->crtc->primary->fb->pixel_format) {
544 			mode_changed = true;
545 		} else
546 			fb_changed = true;
547 	}
548 
549 	if (set->x != set->crtc->x || set->y != set->crtc->y)
550 		fb_changed = true;
551 
552 	if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) {
553 		DRM_DEBUG_KMS("modes are different, full mode set\n");
554 		drm_mode_debug_printmodeline(&set->crtc->mode);
555 		drm_mode_debug_printmodeline(set->mode);
556 		mode_changed = true;
557 	}
558 
559 	/* a) traverse passed in connector list and get encoders for them */
560 	count = 0;
561 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
562 		struct drm_connector_helper_funcs *connector_funcs =
563 			connector->helper_private;
564 		new_encoder = connector->encoder;
565 		for (ro = 0; ro < set->num_connectors; ro++) {
566 			if (set->connectors[ro] == connector) {
567 				new_encoder = connector_funcs->best_encoder(connector);
568 				/* if we can't get an encoder for a connector
569 				   we are setting now - then fail */
570 				if (new_encoder == NULL)
571 					/* don't break so fail path works correct */
572 					fail = 1;
573 
574 				if (connector->dpms != DRM_MODE_DPMS_ON) {
575 					DRM_DEBUG_KMS("connector dpms not on, full mode switch\n");
576 					mode_changed = true;
577 				}
578 
579 				break;
580 			}
581 		}
582 
583 		if (new_encoder != connector->encoder) {
584 			DRM_DEBUG_KMS("encoder changed, full mode switch\n");
585 			mode_changed = true;
586 			/* If the encoder is reused for another connector, then
587 			 * the appropriate crtc will be set later.
588 			 */
589 			if (connector->encoder)
590 				connector->encoder->crtc = NULL;
591 			connector->encoder = new_encoder;
592 		}
593 	}
594 
595 	if (fail) {
596 		ret = -EINVAL;
597 		goto fail;
598 	}
599 
600 	count = 0;
601 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
602 		if (!connector->encoder)
603 			continue;
604 
605 		if (connector->encoder->crtc == set->crtc)
606 			new_crtc = NULL;
607 		else
608 			new_crtc = connector->encoder->crtc;
609 
610 		for (ro = 0; ro < set->num_connectors; ro++) {
611 			if (set->connectors[ro] == connector)
612 				new_crtc = set->crtc;
613 		}
614 
615 		/* Make sure the new CRTC will work with the encoder */
616 		if (new_crtc &&
617 		    !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
618 			ret = -EINVAL;
619 			goto fail;
620 		}
621 		if (new_crtc != connector->encoder->crtc) {
622 			DRM_DEBUG_KMS("crtc changed, full mode switch\n");
623 			mode_changed = true;
624 			connector->encoder->crtc = new_crtc;
625 		}
626 		if (new_crtc) {
627 			DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n",
628 				connector->base.id, drm_get_connector_name(connector),
629 				new_crtc->base.id);
630 		} else {
631 			DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
632 				connector->base.id, drm_get_connector_name(connector));
633 		}
634 	}
635 
636 	/* mode_set_base is not a required function */
637 	if (fb_changed && !crtc_funcs->mode_set_base)
638 		mode_changed = true;
639 
640 	if (mode_changed) {
641 		if (drm_helper_crtc_in_use(set->crtc)) {
642 			DRM_DEBUG_KMS("attempting to set mode from"
643 					" userspace\n");
644 			drm_mode_debug_printmodeline(set->mode);
645 			set->crtc->primary->fb = set->fb;
646 			if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
647 						      set->x, set->y,
648 						      save_set.fb)) {
649 				DRM_ERROR("failed to set mode on [CRTC:%d]\n",
650 					  set->crtc->base.id);
651 				set->crtc->primary->fb = save_set.fb;
652 				ret = -EINVAL;
653 				goto fail;
654 			}
655 			DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
656 			for (i = 0; i < set->num_connectors; i++) {
657 				DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id,
658 					      drm_get_connector_name(set->connectors[i]));
659 				set->connectors[i]->funcs->dpms(set->connectors[i], DRM_MODE_DPMS_ON);
660 			}
661 		}
662 		__drm_helper_disable_unused_functions(dev);
663 	} else if (fb_changed) {
664 		set->crtc->x = set->x;
665 		set->crtc->y = set->y;
666 		set->crtc->primary->fb = set->fb;
667 		ret = crtc_funcs->mode_set_base(set->crtc,
668 						set->x, set->y, save_set.fb);
669 		if (ret != 0) {
670 			set->crtc->x = save_set.x;
671 			set->crtc->y = save_set.y;
672 			set->crtc->primary->fb = save_set.fb;
673 			goto fail;
674 		}
675 	}
676 
677 	kfree(save_connectors);
678 	kfree(save_encoders);
679 	return 0;
680 
681 fail:
682 	/* Restore all previous data. */
683 	count = 0;
684 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
685 		*encoder = save_encoders[count++];
686 	}
687 
688 	count = 0;
689 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
690 		*connector = save_connectors[count++];
691 	}
692 
693 	/* Try to restore the config */
694 	if (mode_changed &&
695 	    !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x,
696 				      save_set.y, save_set.fb))
697 		DRM_ERROR("failed to restore config after modeset failure\n");
698 
699 	kfree(save_connectors);
700 	kfree(save_encoders);
701 	return ret;
702 }
703 EXPORT_SYMBOL(drm_crtc_helper_set_config);
704 
705 static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
706 {
707 	int dpms = DRM_MODE_DPMS_OFF;
708 	struct drm_connector *connector;
709 	struct drm_device *dev = encoder->dev;
710 
711 	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
712 		if (connector->encoder == encoder)
713 			if (connector->dpms < dpms)
714 				dpms = connector->dpms;
715 	return dpms;
716 }
717 
718 /* Helper which handles bridge ordering around encoder dpms */
719 static void drm_helper_encoder_dpms(struct drm_encoder *encoder, int mode)
720 {
721 	struct drm_bridge *bridge = encoder->bridge;
722 	struct drm_encoder_helper_funcs *encoder_funcs;
723 
724 	if (bridge) {
725 		if (mode == DRM_MODE_DPMS_ON)
726 			bridge->funcs->pre_enable(bridge);
727 		else
728 			bridge->funcs->disable(bridge);
729 	}
730 
731 	encoder_funcs = encoder->helper_private;
732 	if (encoder_funcs->dpms)
733 		encoder_funcs->dpms(encoder, mode);
734 
735 	if (bridge) {
736 		if (mode == DRM_MODE_DPMS_ON)
737 			bridge->funcs->enable(bridge);
738 		else
739 			bridge->funcs->post_disable(bridge);
740 	}
741 }
742 
743 static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
744 {
745 	int dpms = DRM_MODE_DPMS_OFF;
746 	struct drm_connector *connector;
747 	struct drm_device *dev = crtc->dev;
748 
749 	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
750 		if (connector->encoder && connector->encoder->crtc == crtc)
751 			if (connector->dpms < dpms)
752 				dpms = connector->dpms;
753 	return dpms;
754 }
755 
756 /**
757  * drm_helper_connector_dpms() - connector dpms helper implementation
758  * @connector: affected connector
759  * @mode: DPMS mode
760  *
761  * This is the main helper function provided by the crtc helper framework for
762  * implementing the DPMS connector attribute. It computes the new desired DPMS
763  * state for all encoders and crtcs in the output mesh and calls the ->dpms()
764  * callback provided by the driver appropriately.
765  */
766 void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
767 {
768 	struct drm_encoder *encoder = connector->encoder;
769 	struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
770 	int old_dpms, encoder_dpms = DRM_MODE_DPMS_OFF;
771 
772 	if (mode == connector->dpms)
773 		return;
774 
775 	old_dpms = connector->dpms;
776 	connector->dpms = mode;
777 
778 	if (encoder)
779 		encoder_dpms = drm_helper_choose_encoder_dpms(encoder);
780 
781 	/* from off to on, do crtc then encoder */
782 	if (mode < old_dpms) {
783 		if (crtc) {
784 			struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
785 			if (crtc_funcs->dpms)
786 				(*crtc_funcs->dpms) (crtc,
787 						     drm_helper_choose_crtc_dpms(crtc));
788 		}
789 		if (encoder)
790 			drm_helper_encoder_dpms(encoder, encoder_dpms);
791 	}
792 
793 	/* from on to off, do encoder then crtc */
794 	if (mode > old_dpms) {
795 		if (encoder)
796 			drm_helper_encoder_dpms(encoder, encoder_dpms);
797 		if (crtc) {
798 			struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
799 			if (crtc_funcs->dpms)
800 				(*crtc_funcs->dpms) (crtc,
801 						     drm_helper_choose_crtc_dpms(crtc));
802 		}
803 	}
804 
805 	return;
806 }
807 EXPORT_SYMBOL(drm_helper_connector_dpms);
808 
809 /**
810  * drm_helper_mode_fill_fb_struct - fill out framebuffer metadata
811  * @fb: drm_framebuffer object to fill out
812  * @mode_cmd: metadata from the userspace fb creation request
813  *
814  * This helper can be used in a drivers fb_create callback to pre-fill the fb's
815  * metadata fields.
816  */
817 void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
818 				    struct drm_mode_fb_cmd2 *mode_cmd)
819 {
820 	int i;
821 
822 	fb->width = mode_cmd->width;
823 	fb->height = mode_cmd->height;
824 	for (i = 0; i < 4; i++) {
825 		fb->pitches[i] = mode_cmd->pitches[i];
826 		fb->offsets[i] = mode_cmd->offsets[i];
827 	}
828 	drm_fb_get_bpp_depth(mode_cmd->pixel_format, &fb->depth,
829 				    &fb->bits_per_pixel);
830 	fb->pixel_format = mode_cmd->pixel_format;
831 }
832 EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct);
833 
834 /**
835  * drm_helper_resume_force_mode - force-restore mode setting configuration
836  * @dev: drm_device which should be restored
837  *
838  * Drivers which use the mode setting helpers can use this function to
839  * force-restore the mode setting configuration e.g. on resume or when something
840  * else might have trampled over the hw state (like some overzealous old BIOSen
841  * tended to do).
842  *
843  * This helper doesn't provide a error return value since restoring the old
844  * config should never fail due to resource allocation issues since the driver
845  * has successfully set the restored configuration already. Hence this should
846  * boil down to the equivalent of a few dpms on calls, which also don't provide
847  * an error code.
848  *
849  * Drivers where simply restoring an old configuration again might fail (e.g.
850  * due to slight differences in allocating shared resources when the
851  * configuration is restored in a different order than when userspace set it up)
852  * need to use their own restore logic.
853  */
854 void drm_helper_resume_force_mode(struct drm_device *dev)
855 {
856 	struct drm_crtc *crtc;
857 	struct drm_encoder *encoder;
858 	struct drm_crtc_helper_funcs *crtc_funcs;
859 	int encoder_dpms;
860 	bool ret;
861 
862 	drm_modeset_lock_all(dev);
863 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
864 
865 		if (!crtc->enabled)
866 			continue;
867 
868 		ret = drm_crtc_helper_set_mode(crtc, &crtc->mode,
869 					       crtc->x, crtc->y, crtc->primary->fb);
870 
871 		/* Restoring the old config should never fail! */
872 		if (ret == false)
873 			DRM_ERROR("failed to set mode on crtc %p\n", crtc);
874 
875 		/* Turn off outputs that were already powered off */
876 		if (drm_helper_choose_crtc_dpms(crtc)) {
877 			list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
878 
879 				if(encoder->crtc != crtc)
880 					continue;
881 
882 				encoder_dpms = drm_helper_choose_encoder_dpms(
883 							encoder);
884 
885 				drm_helper_encoder_dpms(encoder, encoder_dpms);
886 			}
887 
888 			crtc_funcs = crtc->helper_private;
889 			if (crtc_funcs->dpms)
890 				(*crtc_funcs->dpms) (crtc,
891 						     drm_helper_choose_crtc_dpms(crtc));
892 		}
893 	}
894 
895 	/* disable the unused connectors while restoring the modesetting */
896 	__drm_helper_disable_unused_functions(dev);
897 	drm_modeset_unlock_all(dev);
898 }
899 EXPORT_SYMBOL(drm_helper_resume_force_mode);
900