xref: /dragonfly/sys/dev/drm/drm_crtc_helper.c (revision cb740add)
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/moduleparam.h>
35 
36 #include <drm/drmP.h>
37 #include <drm/drm_atomic.h>
38 #include <drm/drm_crtc.h>
39 #include <uapi_drm/drm_fourcc.h>
40 #include <drm/drm_crtc_helper.h>
41 #include <drm/drm_fb_helper.h>
42 #include <drm/drm_plane_helper.h>
43 #include <drm/drm_atomic_helper.h>
44 #include <drm/drm_edid.h>
45 
46 /**
47  * DOC: overview
48  *
49  * The CRTC modeset helper library provides a default set_config implementation
50  * in drm_crtc_helper_set_config(). Plus a few other convenience functions using
51  * the same callbacks which drivers can use to e.g. restore the modeset
52  * configuration on resume with drm_helper_resume_force_mode().
53  *
54  * Note that this helper library doesn't track the current power state of CRTCs
55  * and encoders. It can call callbacks like ->dpms() even though the hardware is
56  * already in the desired state. This deficiency has been fixed in the atomic
57  * helpers.
58  *
59  * The driver callbacks are mostly compatible with the atomic modeset helpers,
60  * except for the handling of the primary plane: Atomic helpers require that the
61  * primary plane is implemented as a real standalone plane and not directly tied
62  * to the CRTC state. For easier transition this library provides functions to
63  * implement the old semantics required by the CRTC helpers using the new plane
64  * and atomic helper callbacks.
65  *
66  * Drivers are strongly urged to convert to the atomic helpers (by way of first
67  * converting to the plane helpers). New drivers must not use these functions
68  * but need to implement the atomic interface instead, potentially using the
69  * atomic helpers for that.
70  *
71  * These legacy modeset helpers use the same function table structures as
72  * all other modesetting helpers. See the documentation for struct
73  * &drm_crtc_helper_funcs, struct &drm_encoder_helper_funcs and struct
74  * &drm_connector_helper_funcs.
75  */
76 
77 /**
78  * drm_helper_move_panel_connectors_to_head() - move panels to the front in the
79  * 						connector list
80  * @dev: drm device to operate on
81  *
82  * Some userspace presumes that the first connected connector is the main
83  * display, where it's supposed to display e.g. the login screen. For
84  * laptops, this should be the main panel. Use this function to sort all
85  * (eDP/LVDS) panels to the front of the connector list, instead of
86  * painstakingly trying to initialize them in the right order.
87  */
88 void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
89 {
90 	struct drm_connector *connector, *tmp;
91 	struct list_head panel_list;
92 
93 	INIT_LIST_HEAD(&panel_list);
94 
95 	list_for_each_entry_safe(connector, tmp,
96 				 &dev->mode_config.connector_list, head) {
97 		if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
98 		    connector->connector_type == DRM_MODE_CONNECTOR_eDP)
99 			list_move_tail(&connector->head, &panel_list);
100 	}
101 
102 	list_splice(&panel_list, &dev->mode_config.connector_list);
103 }
104 EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head);
105 
106 /**
107  * drm_helper_encoder_in_use - check if a given encoder is in use
108  * @encoder: encoder to check
109  *
110  * Checks whether @encoder is with the current mode setting output configuration
111  * in use by any connector. This doesn't mean that it is actually enabled since
112  * the DPMS state is tracked separately.
113  *
114  * Returns:
115  * True if @encoder is used, false otherwise.
116  */
117 bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
118 {
119 	struct drm_connector *connector;
120 	struct drm_device *dev = encoder->dev;
121 
122 	/*
123 	 * We can expect this mutex to be locked if we are not panicking.
124 	 * Locking is currently fubar in the panic handler.
125 	 */
126 #if 0
127 	if (!oops_in_progress) {
128 		WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
129 		WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
130 	}
131 #endif
132 
133 	drm_for_each_connector(connector, dev)
134 		if (connector->encoder == encoder)
135 			return true;
136 	return false;
137 }
138 EXPORT_SYMBOL(drm_helper_encoder_in_use);
139 
140 /**
141  * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config
142  * @crtc: CRTC to check
143  *
144  * Checks whether @crtc is with the current mode setting output configuration
145  * in use by any connector. This doesn't mean that it is actually enabled since
146  * the DPMS state is tracked separately.
147  *
148  * Returns:
149  * True if @crtc is used, false otherwise.
150  */
151 bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
152 {
153 	struct drm_encoder *encoder;
154 	struct drm_device *dev = crtc->dev;
155 
156 	/*
157 	 * We can expect this mutex to be locked if we are not panicking.
158 	 * Locking is currently fubar in the panic handler.
159 	 */
160 #if 0
161 	if (!oops_in_progress)
162 #endif
163 		WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
164 
165 	drm_for_each_encoder(encoder, dev)
166 		if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder))
167 			return true;
168 	return false;
169 }
170 EXPORT_SYMBOL(drm_helper_crtc_in_use);
171 
172 static void
173 drm_encoder_disable(struct drm_encoder *encoder)
174 {
175 	const struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
176 
177 	drm_bridge_disable(encoder->bridge);
178 
179 	if (encoder_funcs->disable)
180 		(*encoder_funcs->disable)(encoder);
181 	else
182 		(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
183 
184 	drm_bridge_post_disable(encoder->bridge);
185 }
186 
187 static void __drm_helper_disable_unused_functions(struct drm_device *dev)
188 {
189 	struct drm_encoder *encoder;
190 	struct drm_crtc *crtc;
191 
192 	drm_warn_on_modeset_not_all_locked(dev);
193 
194 	drm_for_each_encoder(encoder, dev) {
195 		if (!drm_helper_encoder_in_use(encoder)) {
196 			drm_encoder_disable(encoder);
197 			/* disconnect encoder from any connector */
198 			encoder->crtc = NULL;
199 		}
200 	}
201 
202 	drm_for_each_crtc(crtc, dev) {
203 		const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
204 		crtc->enabled = drm_helper_crtc_in_use(crtc);
205 		if (!crtc->enabled) {
206 			if (crtc_funcs->disable)
207 				(*crtc_funcs->disable)(crtc);
208 			else
209 				(*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
210 			crtc->primary->fb = NULL;
211 		}
212 	}
213 }
214 
215 /**
216  * drm_helper_disable_unused_functions - disable unused objects
217  * @dev: DRM device
218  *
219  * This function walks through the entire mode setting configuration of @dev. It
220  * will remove any CRTC links of unused encoders and encoder links of
221  * disconnected connectors. Then it will disable all unused encoders and CRTCs
222  * either by calling their disable callback if available or by calling their
223  * dpms callback with DRM_MODE_DPMS_OFF.
224  *
225  * NOTE:
226  *
227  * This function is part of the legacy modeset helper library and will cause
228  * major confusion with atomic drivers. This is because atomic helpers guarantee
229  * to never call ->disable() hooks on a disabled function, or ->enable() hooks
230  * on an enabled functions. drm_helper_disable_unused_functions() on the other
231  * hand throws such guarantees into the wind and calls disable hooks
232  * unconditionally on unused functions.
233  */
234 void drm_helper_disable_unused_functions(struct drm_device *dev)
235 {
236 	drm_modeset_lock_all(dev);
237 	__drm_helper_disable_unused_functions(dev);
238 	drm_modeset_unlock_all(dev);
239 }
240 EXPORT_SYMBOL(drm_helper_disable_unused_functions);
241 
242 /*
243  * Check the CRTC we're going to map each output to vs. its current
244  * CRTC.  If they don't match, we have to disable the output and the CRTC
245  * since the driver will have to re-route things.
246  */
247 static void
248 drm_crtc_prepare_encoders(struct drm_device *dev)
249 {
250 	const struct drm_encoder_helper_funcs *encoder_funcs;
251 	struct drm_encoder *encoder;
252 
253 	drm_for_each_encoder(encoder, dev) {
254 		encoder_funcs = encoder->helper_private;
255 		/* Disable unused encoders */
256 		if (encoder->crtc == NULL)
257 			drm_encoder_disable(encoder);
258 		/* Disable encoders whose CRTC is about to change */
259 		if (encoder_funcs->get_crtc &&
260 		    encoder->crtc != (*encoder_funcs->get_crtc)(encoder))
261 			drm_encoder_disable(encoder);
262 	}
263 }
264 
265 /**
266  * drm_crtc_helper_set_mode - internal helper to set a mode
267  * @crtc: CRTC to program
268  * @mode: mode to use
269  * @x: horizontal offset into the surface
270  * @y: vertical offset into the surface
271  * @old_fb: old framebuffer, for cleanup
272  *
273  * Try to set @mode on @crtc.  Give @crtc and its associated connectors a chance
274  * to fixup or reject the mode prior to trying to set it. This is an internal
275  * helper that drivers could e.g. use to update properties that require the
276  * entire output pipe to be disabled and re-enabled in a new configuration. For
277  * example for changing whether audio is enabled on a hdmi link or for changing
278  * panel fitter or dither attributes. It is also called by the
279  * drm_crtc_helper_set_config() helper function to drive the mode setting
280  * sequence.
281  *
282  * Returns:
283  * True if the mode was set successfully, false otherwise.
284  */
285 bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
286 			      struct drm_display_mode *mode,
287 			      int x, int y,
288 			      struct drm_framebuffer *old_fb)
289 {
290 	struct drm_device *dev = crtc->dev;
291 	struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
292 	const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
293 	const struct drm_encoder_helper_funcs *encoder_funcs;
294 	int saved_x, saved_y;
295 	bool saved_enabled;
296 	struct drm_encoder *encoder;
297 	bool ret = true;
298 
299 	drm_warn_on_modeset_not_all_locked(dev);
300 
301 	saved_enabled = crtc->enabled;
302 	crtc->enabled = drm_helper_crtc_in_use(crtc);
303 	if (!crtc->enabled)
304 		return true;
305 
306 	adjusted_mode = drm_mode_duplicate(dev, mode);
307 	if (!adjusted_mode) {
308 		crtc->enabled = saved_enabled;
309 		return false;
310 	}
311 
312 	saved_mode = crtc->mode;
313 	saved_hwmode = crtc->hwmode;
314 	saved_x = crtc->x;
315 	saved_y = crtc->y;
316 
317 	/* Update crtc values up front so the driver can rely on them for mode
318 	 * setting.
319 	 */
320 	crtc->mode = *mode;
321 	crtc->x = x;
322 	crtc->y = y;
323 
324 	/* Pass our mode to the connectors and the CRTC to give them a chance to
325 	 * adjust it according to limitations or connector properties, and also
326 	 * a chance to reject the mode entirely.
327 	 */
328 	drm_for_each_encoder(encoder, dev) {
329 
330 		if (encoder->crtc != crtc)
331 			continue;
332 
333 		ret = drm_bridge_mode_fixup(encoder->bridge,
334 			mode, adjusted_mode);
335 		if (!ret) {
336 			DRM_DEBUG_KMS("Bridge fixup failed\n");
337 			goto done;
338 		}
339 
340 		encoder_funcs = encoder->helper_private;
341 		if (encoder_funcs->mode_fixup) {
342 			if (!(ret = encoder_funcs->mode_fixup(encoder, mode,
343 							      adjusted_mode))) {
344 				DRM_DEBUG_KMS("Encoder fixup failed\n");
345 				goto done;
346 			}
347 		}
348 	}
349 
350 	if (crtc_funcs->mode_fixup) {
351 		if (!(ret = crtc_funcs->mode_fixup(crtc, mode,
352 						adjusted_mode))) {
353 			DRM_DEBUG_KMS("CRTC fixup failed\n");
354 			goto done;
355 		}
356 	}
357 	DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
358 
359 	crtc->hwmode = *adjusted_mode;
360 
361 	/* Prepare the encoders and CRTCs before setting the mode. */
362 	drm_for_each_encoder(encoder, dev) {
363 
364 		if (encoder->crtc != crtc)
365 			continue;
366 
367 		drm_bridge_disable(encoder->bridge);
368 
369 		encoder_funcs = encoder->helper_private;
370 		/* Disable the encoders as the first thing we do. */
371 		encoder_funcs->prepare(encoder);
372 
373 		drm_bridge_post_disable(encoder->bridge);
374 	}
375 
376 	drm_crtc_prepare_encoders(dev);
377 
378 	crtc_funcs->prepare(crtc);
379 
380 	/* Set up the DPLL and any encoders state that needs to adjust or depend
381 	 * on the DPLL.
382 	 */
383 	ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
384 	if (!ret)
385 	    goto done;
386 
387 	drm_for_each_encoder(encoder, dev) {
388 
389 		if (encoder->crtc != crtc)
390 			continue;
391 
392 		DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n",
393 			encoder->base.id, encoder->name,
394 			mode->base.id, mode->name);
395 		encoder_funcs = encoder->helper_private;
396 		encoder_funcs->mode_set(encoder, mode, adjusted_mode);
397 
398 		drm_bridge_mode_set(encoder->bridge, mode, adjusted_mode);
399 	}
400 
401 	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
402 	crtc_funcs->commit(crtc);
403 
404 	drm_for_each_encoder(encoder, dev) {
405 
406 		if (encoder->crtc != crtc)
407 			continue;
408 
409 		drm_bridge_pre_enable(encoder->bridge);
410 
411 		encoder_funcs = encoder->helper_private;
412 		encoder_funcs->commit(encoder);
413 
414 		drm_bridge_enable(encoder->bridge);
415 	}
416 
417 	/* Calculate and store various constants which
418 	 * are later needed by vblank and swap-completion
419 	 * timestamping. They are derived from true hwmode.
420 	 */
421 	drm_calc_timestamping_constants(crtc, &crtc->hwmode);
422 
423 	/* FIXME: add subpixel order */
424 done:
425 	drm_mode_destroy(dev, adjusted_mode);
426 	if (!ret) {
427 		crtc->enabled = saved_enabled;
428 		crtc->mode = saved_mode;
429 		crtc->hwmode = saved_hwmode;
430 		crtc->x = saved_x;
431 		crtc->y = saved_y;
432 	}
433 
434 	return ret;
435 }
436 EXPORT_SYMBOL(drm_crtc_helper_set_mode);
437 
438 static void
439 drm_crtc_helper_disable(struct drm_crtc *crtc)
440 {
441 	struct drm_device *dev = crtc->dev;
442 	struct drm_connector *connector;
443 	struct drm_encoder *encoder;
444 
445 	/* Decouple all encoders and their attached connectors from this crtc */
446 	drm_for_each_encoder(encoder, dev) {
447 		if (encoder->crtc != crtc)
448 			continue;
449 
450 		drm_for_each_connector(connector, dev) {
451 			if (connector->encoder != encoder)
452 				continue;
453 
454 			connector->encoder = NULL;
455 
456 			/*
457 			 * drm_helper_disable_unused_functions() ought to be
458 			 * doing this, but since we've decoupled the encoder
459 			 * from the connector above, the required connection
460 			 * between them is henceforth no longer available.
461 			 */
462 			connector->dpms = DRM_MODE_DPMS_OFF;
463 		}
464 	}
465 
466 	__drm_helper_disable_unused_functions(dev);
467 }
468 
469 /**
470  * drm_crtc_helper_set_config - set a new config from userspace
471  * @set: mode set configuration
472  *
473  * The drm_crtc_helper_set_config() helper function implements the set_config
474  * callback of struct &drm_crtc_funcs for drivers using the legacy CRTC helpers.
475  *
476  * It first tries to locate the best encoder for each connector by calling the
477  * connector ->best_encoder() (struct &drm_connector_helper_funcs) helper
478  * operation.
479  *
480  * After locating the appropriate encoders, the helper function will call the
481  * mode_fixup encoder and CRTC helper operations to adjust the requested mode,
482  * or reject it completely in which case an error will be returned to the
483  * application. If the new configuration after mode adjustment is identical to
484  * the current configuration the helper function will return without performing
485  * any other operation.
486  *
487  * If the adjusted mode is identical to the current mode but changes to the
488  * frame buffer need to be applied, the drm_crtc_helper_set_config() function
489  * will call the CRTC ->mode_set_base() (struct &drm_crtc_helper_funcs) helper
490  * operation.
491  *
492  * If the adjusted mode differs from the current mode, or if the
493  * ->mode_set_base() helper operation is not provided, the helper function
494  * performs a full mode set sequence by calling the ->prepare(), ->mode_set()
495  * and ->commit() CRTC and encoder helper operations, in that order.
496  * Alternatively it can also use the dpms and disable helper operations. For
497  * details see struct &drm_crtc_helper_funcs and struct
498  * &drm_encoder_helper_funcs.
499  *
500  * This function is deprecated.  New drivers must implement atomic modeset
501  * support, for which this function is unsuitable. Instead drivers should use
502  * drm_atomic_helper_set_config().
503  *
504  * Returns:
505  * Returns 0 on success, negative errno numbers on failure.
506  */
507 int drm_crtc_helper_set_config(struct drm_mode_set *set)
508 {
509 	struct drm_device *dev;
510 	struct drm_crtc *new_crtc;
511 	struct drm_encoder *save_encoders, *new_encoder, *encoder;
512 	bool mode_changed = false; /* if true do a full mode set */
513 	bool fb_changed = false; /* if true and !mode_changed just do a flip */
514 	struct drm_connector *save_connectors, *connector;
515 	int count = 0, ro, fail = 0;
516 	const struct drm_crtc_helper_funcs *crtc_funcs;
517 	struct drm_mode_set save_set;
518 	int ret;
519 	int i;
520 
521 	DRM_DEBUG_KMS("\n");
522 
523 	BUG_ON(!set);
524 	BUG_ON(!set->crtc);
525 	BUG_ON(!set->crtc->helper_private);
526 
527 	/* Enforce sane interface api - has been abused by the fb helper. */
528 	BUG_ON(!set->mode && set->fb);
529 	BUG_ON(set->fb && set->num_connectors == 0);
530 
531 	crtc_funcs = set->crtc->helper_private;
532 
533 	if (!set->mode)
534 		set->fb = NULL;
535 
536 	if (set->fb) {
537 		DRM_DEBUG_KMS("[CRTC:%d:%s] [FB:%d] #connectors=%d (x y) (%i %i)\n",
538 			      set->crtc->base.id, set->crtc->name,
539 			      set->fb->base.id,
540 			      (int)set->num_connectors, set->x, set->y);
541 	} else {
542 		DRM_DEBUG_KMS("[CRTC:%d:%s] [NOFB]\n",
543 			      set->crtc->base.id, set->crtc->name);
544 		drm_crtc_helper_disable(set->crtc);
545 		return 0;
546 	}
547 
548 	dev = set->crtc->dev;
549 
550 	drm_warn_on_modeset_not_all_locked(dev);
551 
552 	/*
553 	 * Allocate space for the backup of all (non-pointer) encoder and
554 	 * connector data.
555 	 */
556 	save_encoders = kzalloc(dev->mode_config.num_encoder *
557 				sizeof(struct drm_encoder), GFP_KERNEL);
558 	if (!save_encoders)
559 		return -ENOMEM;
560 
561 	save_connectors = kzalloc(dev->mode_config.num_connector *
562 				sizeof(struct drm_connector), GFP_KERNEL);
563 	if (!save_connectors) {
564 		kfree(save_encoders);
565 		return -ENOMEM;
566 	}
567 
568 	/*
569 	 * Copy data. Note that driver private data is not affected.
570 	 * Should anything bad happen only the expected state is
571 	 * restored, not the drivers personal bookkeeping.
572 	 */
573 	count = 0;
574 	drm_for_each_encoder(encoder, dev) {
575 		save_encoders[count++] = *encoder;
576 	}
577 
578 	count = 0;
579 	drm_for_each_connector(connector, dev) {
580 		save_connectors[count++] = *connector;
581 	}
582 
583 	save_set.crtc = set->crtc;
584 	save_set.mode = &set->crtc->mode;
585 	save_set.x = set->crtc->x;
586 	save_set.y = set->crtc->y;
587 	save_set.fb = set->crtc->primary->fb;
588 
589 	/* We should be able to check here if the fb has the same properties
590 	 * and then just flip_or_move it */
591 	if (set->crtc->primary->fb != set->fb) {
592 		/* If we have no fb then treat it as a full mode set */
593 		if (set->crtc->primary->fb == NULL) {
594 			DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
595 			mode_changed = true;
596 		} else if (set->fb->pixel_format !=
597 			   set->crtc->primary->fb->pixel_format) {
598 			mode_changed = true;
599 		} else
600 			fb_changed = true;
601 	}
602 
603 	if (set->x != set->crtc->x || set->y != set->crtc->y)
604 		fb_changed = true;
605 
606 	if (!drm_mode_equal(set->mode, &set->crtc->mode)) {
607 		DRM_DEBUG_KMS("modes are different, full mode set\n");
608 		drm_mode_debug_printmodeline(&set->crtc->mode);
609 		drm_mode_debug_printmodeline(set->mode);
610 		mode_changed = true;
611 	}
612 
613 	/* a) traverse passed in connector list and get encoders for them */
614 	count = 0;
615 	drm_for_each_connector(connector, dev) {
616 		const struct drm_connector_helper_funcs *connector_funcs =
617 			connector->helper_private;
618 		new_encoder = connector->encoder;
619 		for (ro = 0; ro < set->num_connectors; ro++) {
620 			if (set->connectors[ro] == connector) {
621 				new_encoder = connector_funcs->best_encoder(connector);
622 				/* if we can't get an encoder for a connector
623 				   we are setting now - then fail */
624 				if (new_encoder == NULL)
625 					/* don't break so fail path works correct */
626 					fail = 1;
627 
628 				if (connector->dpms != DRM_MODE_DPMS_ON) {
629 					DRM_DEBUG_KMS("connector dpms not on, full mode switch\n");
630 					mode_changed = true;
631 				}
632 
633 				break;
634 			}
635 		}
636 
637 		if (new_encoder != connector->encoder) {
638 			DRM_DEBUG_KMS("encoder changed, full mode switch\n");
639 			mode_changed = true;
640 			/* If the encoder is reused for another connector, then
641 			 * the appropriate crtc will be set later.
642 			 */
643 			if (connector->encoder)
644 				connector->encoder->crtc = NULL;
645 			connector->encoder = new_encoder;
646 		}
647 	}
648 
649 	if (fail) {
650 		ret = -EINVAL;
651 		goto fail;
652 	}
653 
654 	count = 0;
655 	drm_for_each_connector(connector, dev) {
656 		if (!connector->encoder)
657 			continue;
658 
659 		if (connector->encoder->crtc == set->crtc)
660 			new_crtc = NULL;
661 		else
662 			new_crtc = connector->encoder->crtc;
663 
664 		for (ro = 0; ro < set->num_connectors; ro++) {
665 			if (set->connectors[ro] == connector)
666 				new_crtc = set->crtc;
667 		}
668 
669 		/* Make sure the new CRTC will work with the encoder */
670 		if (new_crtc &&
671 		    !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
672 			ret = -EINVAL;
673 			goto fail;
674 		}
675 		if (new_crtc != connector->encoder->crtc) {
676 			DRM_DEBUG_KMS("crtc changed, full mode switch\n");
677 			mode_changed = true;
678 			connector->encoder->crtc = new_crtc;
679 		}
680 		if (new_crtc) {
681 			DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d:%s]\n",
682 				      connector->base.id, connector->name,
683 				      new_crtc->base.id, new_crtc->name);
684 		} else {
685 			DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
686 				      connector->base.id, connector->name);
687 		}
688 	}
689 
690 	/* mode_set_base is not a required function */
691 	if (fb_changed && !crtc_funcs->mode_set_base)
692 		mode_changed = true;
693 
694 	if (mode_changed) {
695 		if (drm_helper_crtc_in_use(set->crtc)) {
696 			DRM_DEBUG_KMS("attempting to set mode from"
697 					" userspace\n");
698 			drm_mode_debug_printmodeline(set->mode);
699 			set->crtc->primary->fb = set->fb;
700 			if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
701 						      set->x, set->y,
702 						      save_set.fb)) {
703 				DRM_ERROR("failed to set mode on [CRTC:%d:%s]\n",
704 					  set->crtc->base.id, set->crtc->name);
705 				set->crtc->primary->fb = save_set.fb;
706 				ret = -EINVAL;
707 				goto fail;
708 			}
709 			DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
710 			for (i = 0; i < set->num_connectors; i++) {
711 				DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id,
712 					      set->connectors[i]->name);
713 				set->connectors[i]->funcs->dpms(set->connectors[i], DRM_MODE_DPMS_ON);
714 			}
715 		}
716 		__drm_helper_disable_unused_functions(dev);
717 	} else if (fb_changed) {
718 		set->crtc->x = set->x;
719 		set->crtc->y = set->y;
720 		set->crtc->primary->fb = set->fb;
721 		ret = crtc_funcs->mode_set_base(set->crtc,
722 						set->x, set->y, save_set.fb);
723 		if (ret != 0) {
724 			set->crtc->x = save_set.x;
725 			set->crtc->y = save_set.y;
726 			set->crtc->primary->fb = save_set.fb;
727 			goto fail;
728 		}
729 	}
730 
731 	kfree(save_connectors);
732 	kfree(save_encoders);
733 	return 0;
734 
735 fail:
736 	/* Restore all previous data. */
737 	count = 0;
738 	drm_for_each_encoder(encoder, dev) {
739 		*encoder = save_encoders[count++];
740 	}
741 
742 	count = 0;
743 	drm_for_each_connector(connector, dev) {
744 		*connector = save_connectors[count++];
745 	}
746 
747 	/* Try to restore the config */
748 	if (mode_changed &&
749 	    !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x,
750 				      save_set.y, save_set.fb))
751 		DRM_ERROR("failed to restore config after modeset failure\n");
752 
753 	kfree(save_connectors);
754 	kfree(save_encoders);
755 	return ret;
756 }
757 EXPORT_SYMBOL(drm_crtc_helper_set_config);
758 
759 static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
760 {
761 	int dpms = DRM_MODE_DPMS_OFF;
762 	struct drm_connector *connector;
763 	struct drm_device *dev = encoder->dev;
764 
765 	drm_for_each_connector(connector, dev)
766 		if (connector->encoder == encoder)
767 			if (connector->dpms < dpms)
768 				dpms = connector->dpms;
769 	return dpms;
770 }
771 
772 /* Helper which handles bridge ordering around encoder dpms */
773 static void drm_helper_encoder_dpms(struct drm_encoder *encoder, int mode)
774 {
775 	struct drm_bridge *bridge = encoder->bridge;
776 	const struct drm_encoder_helper_funcs *encoder_funcs;
777 
778 	if (mode == DRM_MODE_DPMS_ON)
779 		drm_bridge_pre_enable(bridge);
780 	else
781 		drm_bridge_disable(bridge);
782 
783 	encoder_funcs = encoder->helper_private;
784 	if (encoder_funcs->dpms)
785 		encoder_funcs->dpms(encoder, mode);
786 
787 	if (mode == DRM_MODE_DPMS_ON)
788 		drm_bridge_enable(bridge);
789 	else
790 		drm_bridge_post_disable(bridge);
791 }
792 
793 static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
794 {
795 	int dpms = DRM_MODE_DPMS_OFF;
796 	struct drm_connector *connector;
797 	struct drm_device *dev = crtc->dev;
798 
799 	drm_for_each_connector(connector, dev)
800 		if (connector->encoder && connector->encoder->crtc == crtc)
801 			if (connector->dpms < dpms)
802 				dpms = connector->dpms;
803 	return dpms;
804 }
805 
806 /**
807  * drm_helper_connector_dpms() - connector dpms helper implementation
808  * @connector: affected connector
809  * @mode: DPMS mode
810  *
811  * The drm_helper_connector_dpms() helper function implements the ->dpms()
812  * callback of struct &drm_connector_funcs for drivers using the legacy CRTC helpers.
813  *
814  * This is the main helper function provided by the CRTC helper framework for
815  * implementing the DPMS connector attribute. It computes the new desired DPMS
816  * state for all encoders and CRTCs in the output mesh and calls the ->dpms()
817  * callbacks provided by the driver in struct &drm_crtc_helper_funcs and struct
818  * &drm_encoder_helper_funcs appropriately.
819  *
820  * This function is deprecated.  New drivers must implement atomic modeset
821  * support, for which this function is unsuitable. Instead drivers should use
822  * drm_atomic_helper_connector_dpms().
823  *
824  * Returns:
825  * Always returns 0.
826  */
827 int drm_helper_connector_dpms(struct drm_connector *connector, int mode)
828 {
829 	struct drm_encoder *encoder = connector->encoder;
830 	struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
831 	int old_dpms, encoder_dpms = DRM_MODE_DPMS_OFF;
832 
833 	if (mode == connector->dpms)
834 		return 0;
835 
836 	old_dpms = connector->dpms;
837 	connector->dpms = mode;
838 
839 	if (encoder)
840 		encoder_dpms = drm_helper_choose_encoder_dpms(encoder);
841 
842 	/* from off to on, do crtc then encoder */
843 	if (mode < old_dpms) {
844 		if (crtc) {
845 			const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
846 			if (crtc_funcs->dpms)
847 				(*crtc_funcs->dpms) (crtc,
848 						     drm_helper_choose_crtc_dpms(crtc));
849 		}
850 		if (encoder)
851 			drm_helper_encoder_dpms(encoder, encoder_dpms);
852 	}
853 
854 	/* from on to off, do encoder then crtc */
855 	if (mode > old_dpms) {
856 		if (encoder)
857 			drm_helper_encoder_dpms(encoder, encoder_dpms);
858 		if (crtc) {
859 			const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
860 			if (crtc_funcs->dpms)
861 				(*crtc_funcs->dpms) (crtc,
862 						     drm_helper_choose_crtc_dpms(crtc));
863 		}
864 	}
865 
866 	return 0;
867 }
868 EXPORT_SYMBOL(drm_helper_connector_dpms);
869 
870 /**
871  * drm_helper_mode_fill_fb_struct - fill out framebuffer metadata
872  * @fb: drm_framebuffer object to fill out
873  * @mode_cmd: metadata from the userspace fb creation request
874  *
875  * This helper can be used in a drivers fb_create callback to pre-fill the fb's
876  * metadata fields.
877  */
878 void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
879 				    const struct drm_mode_fb_cmd2 *mode_cmd)
880 {
881 	int i;
882 
883 	fb->width = mode_cmd->width;
884 	fb->height = mode_cmd->height;
885 	for (i = 0; i < 4; i++) {
886 		fb->pitches[i] = mode_cmd->pitches[i];
887 		fb->offsets[i] = mode_cmd->offsets[i];
888 		fb->modifier[i] = mode_cmd->modifier[i];
889 	}
890 	drm_fb_get_bpp_depth(mode_cmd->pixel_format, &fb->depth,
891 				    &fb->bits_per_pixel);
892 	fb->pixel_format = mode_cmd->pixel_format;
893 	fb->flags = mode_cmd->flags;
894 }
895 EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct);
896 
897 /**
898  * drm_helper_resume_force_mode - force-restore mode setting configuration
899  * @dev: drm_device which should be restored
900  *
901  * Drivers which use the mode setting helpers can use this function to
902  * force-restore the mode setting configuration e.g. on resume or when something
903  * else might have trampled over the hw state (like some overzealous old BIOSen
904  * tended to do).
905  *
906  * This helper doesn't provide a error return value since restoring the old
907  * config should never fail due to resource allocation issues since the driver
908  * has successfully set the restored configuration already. Hence this should
909  * boil down to the equivalent of a few dpms on calls, which also don't provide
910  * an error code.
911  *
912  * Drivers where simply restoring an old configuration again might fail (e.g.
913  * due to slight differences in allocating shared resources when the
914  * configuration is restored in a different order than when userspace set it up)
915  * need to use their own restore logic.
916  *
917  * This function is deprecated. New drivers should implement atomic mode-
918  * setting and use the atomic suspend/resume helpers.
919  *
920  * See also:
921  * drm_atomic_helper_suspend(), drm_atomic_helper_resume()
922  */
923 void drm_helper_resume_force_mode(struct drm_device *dev)
924 {
925 	struct drm_crtc *crtc;
926 	struct drm_encoder *encoder;
927 	const struct drm_crtc_helper_funcs *crtc_funcs;
928 	int encoder_dpms;
929 	bool ret;
930 
931 	drm_modeset_lock_all(dev);
932 	drm_for_each_crtc(crtc, dev) {
933 
934 		if (!crtc->enabled)
935 			continue;
936 
937 		ret = drm_crtc_helper_set_mode(crtc, &crtc->mode,
938 					       crtc->x, crtc->y, crtc->primary->fb);
939 
940 		/* Restoring the old config should never fail! */
941 		if (ret == false)
942 			DRM_ERROR("failed to set mode on crtc %p\n", crtc);
943 
944 		/* Turn off outputs that were already powered off */
945 		if (drm_helper_choose_crtc_dpms(crtc)) {
946 			drm_for_each_encoder(encoder, dev) {
947 
948 				if(encoder->crtc != crtc)
949 					continue;
950 
951 				encoder_dpms = drm_helper_choose_encoder_dpms(
952 							encoder);
953 
954 				drm_helper_encoder_dpms(encoder, encoder_dpms);
955 			}
956 
957 			crtc_funcs = crtc->helper_private;
958 			if (crtc_funcs->dpms)
959 				(*crtc_funcs->dpms) (crtc,
960 						     drm_helper_choose_crtc_dpms(crtc));
961 		}
962 	}
963 
964 	/* disable the unused connectors while restoring the modesetting */
965 	__drm_helper_disable_unused_functions(dev);
966 	drm_modeset_unlock_all(dev);
967 }
968 EXPORT_SYMBOL(drm_helper_resume_force_mode);
969 
970 /**
971  * drm_helper_crtc_mode_set - mode_set implementation for atomic plane helpers
972  * @crtc: DRM CRTC
973  * @mode: DRM display mode which userspace requested
974  * @adjusted_mode: DRM display mode adjusted by ->mode_fixup callbacks
975  * @x: x offset of the CRTC scanout area on the underlying framebuffer
976  * @y: y offset of the CRTC scanout area on the underlying framebuffer
977  * @old_fb: previous framebuffer
978  *
979  * This function implements a callback useable as the ->mode_set callback
980  * required by the CRTC helpers. Besides the atomic plane helper functions for
981  * the primary plane the driver must also provide the ->mode_set_nofb callback
982  * to set up the CRTC.
983  *
984  * This is a transitional helper useful for converting drivers to the atomic
985  * interfaces.
986  */
987 int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
988 			     struct drm_display_mode *adjusted_mode, int x, int y,
989 			     struct drm_framebuffer *old_fb)
990 {
991 	struct drm_crtc_state *crtc_state;
992 	const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
993 	int ret;
994 
995 	if (crtc->funcs->atomic_duplicate_state)
996 		crtc_state = crtc->funcs->atomic_duplicate_state(crtc);
997 	else {
998 		if (!crtc->state)
999 			drm_atomic_helper_crtc_reset(crtc);
1000 
1001 		crtc_state = drm_atomic_helper_crtc_duplicate_state(crtc);
1002 	}
1003 
1004 	if (!crtc_state)
1005 		return -ENOMEM;
1006 
1007 	crtc_state->planes_changed = true;
1008 	crtc_state->mode_changed = true;
1009 	ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
1010 	if (ret)
1011 		goto out;
1012 	drm_mode_copy(&crtc_state->adjusted_mode, adjusted_mode);
1013 
1014 	if (crtc_funcs->atomic_check) {
1015 		ret = crtc_funcs->atomic_check(crtc, crtc_state);
1016 		if (ret)
1017 			goto out;
1018 	}
1019 
1020 	swap(crtc->state, crtc_state);
1021 
1022 	crtc_funcs->mode_set_nofb(crtc);
1023 
1024 	ret = drm_helper_crtc_mode_set_base(crtc, x, y, old_fb);
1025 
1026 out:
1027 	if (crtc_state) {
1028 		if (crtc->funcs->atomic_destroy_state)
1029 			crtc->funcs->atomic_destroy_state(crtc, crtc_state);
1030 		else
1031 			drm_atomic_helper_crtc_destroy_state(crtc, crtc_state);
1032 	}
1033 
1034 	return ret;
1035 }
1036 EXPORT_SYMBOL(drm_helper_crtc_mode_set);
1037 
1038 /**
1039  * drm_helper_crtc_mode_set_base - mode_set_base implementation for atomic plane helpers
1040  * @crtc: DRM CRTC
1041  * @x: x offset of the CRTC scanout area on the underlying framebuffer
1042  * @y: y offset of the CRTC scanout area on the underlying framebuffer
1043  * @old_fb: previous framebuffer
1044  *
1045  * This function implements a callback useable as the ->mode_set_base used
1046  * required by the CRTC helpers. The driver must provide the atomic plane helper
1047  * functions for the primary plane.
1048  *
1049  * This is a transitional helper useful for converting drivers to the atomic
1050  * interfaces.
1051  */
1052 int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
1053 				  struct drm_framebuffer *old_fb)
1054 {
1055 	struct drm_plane_state *plane_state;
1056 	struct drm_plane *plane = crtc->primary;
1057 
1058 	if (plane->funcs->atomic_duplicate_state)
1059 		plane_state = plane->funcs->atomic_duplicate_state(plane);
1060 	else if (plane->state)
1061 		plane_state = drm_atomic_helper_plane_duplicate_state(plane);
1062 	else
1063 		plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL);
1064 	if (!plane_state)
1065 		return -ENOMEM;
1066 	plane_state->plane = plane;
1067 
1068 	plane_state->crtc = crtc;
1069 	drm_atomic_set_fb_for_plane(plane_state, crtc->primary->fb);
1070 	plane_state->crtc_x = 0;
1071 	plane_state->crtc_y = 0;
1072 	plane_state->crtc_h = crtc->mode.vdisplay;
1073 	plane_state->crtc_w = crtc->mode.hdisplay;
1074 	plane_state->src_x = x << 16;
1075 	plane_state->src_y = y << 16;
1076 	plane_state->src_h = crtc->mode.vdisplay << 16;
1077 	plane_state->src_w = crtc->mode.hdisplay << 16;
1078 
1079 	return drm_plane_helper_commit(plane, plane_state, old_fb);
1080 }
1081 EXPORT_SYMBOL(drm_helper_crtc_mode_set_base);
1082 
1083 /**
1084  * drm_helper_crtc_enable_color_mgmt - enable color management properties
1085  * @crtc: DRM CRTC
1086  * @degamma_lut_size: the size of the degamma lut (before CSC)
1087  * @gamma_lut_size: the size of the gamma lut (after CSC)
1088  *
1089  * This function lets the driver enable the color correction properties on a
1090  * CRTC. This includes 3 degamma, csc and gamma properties that userspace can
1091  * set and 2 size properties to inform the userspace of the lut sizes.
1092  */
1093 void drm_helper_crtc_enable_color_mgmt(struct drm_crtc *crtc,
1094 				       int degamma_lut_size,
1095 				       int gamma_lut_size)
1096 {
1097 	struct drm_device *dev = crtc->dev;
1098 	struct drm_mode_config *config = &dev->mode_config;
1099 
1100 	drm_object_attach_property(&crtc->base,
1101 				   config->degamma_lut_property, 0);
1102 	drm_object_attach_property(&crtc->base,
1103 				   config->ctm_property, 0);
1104 	drm_object_attach_property(&crtc->base,
1105 				   config->gamma_lut_property, 0);
1106 
1107 	drm_object_attach_property(&crtc->base,
1108 				   config->degamma_lut_size_property,
1109 				   degamma_lut_size);
1110 	drm_object_attach_property(&crtc->base,
1111 				   config->gamma_lut_size_property,
1112 				   gamma_lut_size);
1113 }
1114 EXPORT_SYMBOL(drm_helper_crtc_enable_color_mgmt);
1115