2 * Copyright (c) 2006-2008 Intel Corporation
3 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
5 * DRM core CRTC related functions
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.
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
27 * Eric Anholt <eric@anholt.net>
28 * Dave Airlie <airlied@linux.ie>
29 * Jesse Barnes <jesse.barnes@intel.com>
32 #include <linux/export.h>
33 #include <linux/moduleparam.h>
36 #include <drm/drm_crtc.h>
37 #include <drm/drm_fourcc.h>
38 #include <drm/drm_crtc_helper.h>
39 #include <drm/drm_fb_helper.h>
40 #include <drm/drm_edid.h>
43 * drm_helper_move_panel_connectors_to_head() - move panels to the front in the
45 * @dev: drm device to operate on
47 * Some userspace presumes that the first connected connector is the main
48 * display, where it's supposed to display e.g. the login screen. For
49 * laptops, this should be the main panel. Use this function to sort all
50 * (eDP/LVDS) panels to the front of the connector list, instead of
51 * painstakingly trying to initialize them in the right order.
53 void drm_helper_move_panel_connectors_to_head(struct drm_device
*dev
)
55 struct drm_connector
*connector
, *tmp
;
56 struct list_head panel_list
;
58 INIT_LIST_HEAD(&panel_list
);
60 list_for_each_entry_safe(connector
, tmp
,
61 &dev
->mode_config
.connector_list
, head
) {
62 if (connector
->connector_type
== DRM_MODE_CONNECTOR_LVDS
||
63 connector
->connector_type
== DRM_MODE_CONNECTOR_eDP
)
64 list_move_tail(&connector
->head
, &panel_list
);
67 list_splice(&panel_list
, &dev
->mode_config
.connector_list
);
69 EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head
);
71 static bool drm_kms_helper_poll
= true;
72 module_param_named(poll
, drm_kms_helper_poll
, bool, 0600);
74 static void drm_mode_validate_flag(struct drm_connector
*connector
,
77 struct drm_display_mode
*mode
;
79 if (flags
== (DRM_MODE_FLAG_DBLSCAN
| DRM_MODE_FLAG_INTERLACE
|
80 DRM_MODE_FLAG_3D_MASK
))
83 list_for_each_entry(mode
, &connector
->modes
, head
) {
84 if ((mode
->flags
& DRM_MODE_FLAG_INTERLACE
) &&
85 !(flags
& DRM_MODE_FLAG_INTERLACE
))
86 mode
->status
= MODE_NO_INTERLACE
;
87 if ((mode
->flags
& DRM_MODE_FLAG_DBLSCAN
) &&
88 !(flags
& DRM_MODE_FLAG_DBLSCAN
))
89 mode
->status
= MODE_NO_DBLESCAN
;
90 if ((mode
->flags
& DRM_MODE_FLAG_3D_MASK
) &&
91 !(flags
& DRM_MODE_FLAG_3D_MASK
))
92 mode
->status
= MODE_NO_STEREO
;
99 * drm_helper_probe_single_connector_modes - get complete set of display modes
100 * @connector: connector to probe
101 * @maxX: max width for modes
102 * @maxY: max height for modes
105 * Caller must hold mode config lock.
107 * Based on the helper callbacks implemented by @connector try to detect all
108 * valid modes. Modes will first be added to the connector's probed_modes list,
109 * then culled (based on validity and the @maxX, @maxY parameters) and put into
110 * the normal modes list.
112 * Intended to be use as a generic implementation of the ->fill_modes()
113 * @connector vfunc for drivers that use the crtc helpers for output mode
114 * filtering and detection.
117 * Number of modes found on @connector.
119 int drm_helper_probe_single_connector_modes(struct drm_connector
*connector
,
120 uint32_t maxX
, uint32_t maxY
)
122 struct drm_device
*dev
= connector
->dev
;
123 struct drm_display_mode
*mode
;
124 struct drm_connector_helper_funcs
*connector_funcs
=
125 connector
->helper_private
;
128 bool verbose_prune
= true;
130 DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector
->base
.id
,
131 drm_get_connector_name(connector
));
132 /* set all modes to the unverified state */
133 list_for_each_entry(mode
, &connector
->modes
, head
)
134 mode
->status
= MODE_UNVERIFIED
;
136 if (connector
->force
) {
137 if (connector
->force
== DRM_FORCE_ON
)
138 connector
->status
= connector_status_connected
;
140 connector
->status
= connector_status_disconnected
;
141 if (connector
->funcs
->force
)
142 connector
->funcs
->force(connector
);
144 connector
->status
= connector
->funcs
->detect(connector
, true);
147 /* Re-enable polling in case the global poll config changed. */
148 if (drm_kms_helper_poll
!= dev
->mode_config
.poll_running
)
149 drm_kms_helper_poll_enable(dev
);
151 dev
->mode_config
.poll_running
= drm_kms_helper_poll
;
153 if (connector
->status
== connector_status_disconnected
) {
154 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
155 connector
->base
.id
, drm_get_connector_name(connector
));
156 drm_mode_connector_update_edid_property(connector
, NULL
);
157 verbose_prune
= false;
161 #ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
162 count
= drm_load_edid_firmware(connector
);
165 count
= (*connector_funcs
->get_modes
)(connector
);
167 if (count
== 0 && connector
->status
== connector_status_connected
)
168 count
= drm_add_modes_noedid(connector
, 1024, 768);
172 drm_mode_connector_list_update(connector
);
175 drm_mode_validate_size(dev
, &connector
->modes
, maxX
,
178 if (connector
->interlace_allowed
)
179 mode_flags
|= DRM_MODE_FLAG_INTERLACE
;
180 if (connector
->doublescan_allowed
)
181 mode_flags
|= DRM_MODE_FLAG_DBLSCAN
;
182 if (connector
->stereo_allowed
)
183 mode_flags
|= DRM_MODE_FLAG_3D_MASK
;
184 drm_mode_validate_flag(connector
, mode_flags
);
186 list_for_each_entry(mode
, &connector
->modes
, head
) {
187 if (mode
->status
== MODE_OK
)
188 mode
->status
= connector_funcs
->mode_valid(connector
,
193 drm_mode_prune_invalid(dev
, &connector
->modes
, verbose_prune
);
195 if (list_empty(&connector
->modes
))
198 list_for_each_entry(mode
, &connector
->modes
, head
)
199 mode
->vrefresh
= drm_mode_vrefresh(mode
);
201 drm_mode_sort(&connector
->modes
);
203 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector
->base
.id
,
204 drm_get_connector_name(connector
));
205 list_for_each_entry(mode
, &connector
->modes
, head
) {
206 drm_mode_set_crtcinfo(mode
, CRTC_INTERLACE_HALVE_V
);
207 drm_mode_debug_printmodeline(mode
);
212 EXPORT_SYMBOL(drm_helper_probe_single_connector_modes
);
215 * drm_helper_encoder_in_use - check if a given encoder is in use
216 * @encoder: encoder to check
219 * Caller must hold mode config lock.
221 * Walk @encoders's DRM device's mode_config and see if it's in use.
224 * True if @encoder is part of the mode_config, false otherwise.
226 bool drm_helper_encoder_in_use(struct drm_encoder
*encoder
)
228 struct drm_connector
*connector
;
229 struct drm_device
*dev
= encoder
->dev
;
230 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
)
231 if (connector
->encoder
== encoder
)
235 EXPORT_SYMBOL(drm_helper_encoder_in_use
);
238 * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config
239 * @crtc: CRTC to check
242 * Caller must hold mode config lock.
244 * Walk @crtc's DRM device's mode_config and see if it's in use.
247 * True if @crtc is part of the mode_config, false otherwise.
249 bool drm_helper_crtc_in_use(struct drm_crtc
*crtc
)
251 struct drm_encoder
*encoder
;
252 struct drm_device
*dev
= crtc
->dev
;
253 /* FIXME: Locking around list access? */
254 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
)
255 if (encoder
->crtc
== crtc
&& drm_helper_encoder_in_use(encoder
))
259 EXPORT_SYMBOL(drm_helper_crtc_in_use
);
262 drm_encoder_disable(struct drm_encoder
*encoder
)
264 struct drm_encoder_helper_funcs
*encoder_funcs
= encoder
->helper_private
;
267 encoder
->bridge
->funcs
->disable(encoder
->bridge
);
269 if (encoder_funcs
->disable
)
270 (*encoder_funcs
->disable
)(encoder
);
272 (*encoder_funcs
->dpms
)(encoder
, DRM_MODE_DPMS_OFF
);
275 encoder
->bridge
->funcs
->post_disable(encoder
->bridge
);
279 * drm_helper_disable_unused_functions - disable unused objects
283 * Caller must hold mode config lock.
285 * If an connector or CRTC isn't part of @dev's mode_config, it can be disabled
286 * by calling its dpms function, which should power it off.
288 void drm_helper_disable_unused_functions(struct drm_device
*dev
)
290 struct drm_encoder
*encoder
;
291 struct drm_connector
*connector
;
292 struct drm_crtc
*crtc
;
294 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
295 if (!connector
->encoder
)
297 if (connector
->status
== connector_status_disconnected
)
298 connector
->encoder
= NULL
;
301 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
) {
302 if (!drm_helper_encoder_in_use(encoder
)) {
303 drm_encoder_disable(encoder
);
304 /* disconnector encoder from any connector */
305 encoder
->crtc
= NULL
;
309 list_for_each_entry(crtc
, &dev
->mode_config
.crtc_list
, head
) {
310 struct drm_crtc_helper_funcs
*crtc_funcs
= crtc
->helper_private
;
311 crtc
->enabled
= drm_helper_crtc_in_use(crtc
);
312 if (!crtc
->enabled
) {
313 if (crtc_funcs
->disable
)
314 (*crtc_funcs
->disable
)(crtc
);
316 (*crtc_funcs
->dpms
)(crtc
, DRM_MODE_DPMS_OFF
);
321 EXPORT_SYMBOL(drm_helper_disable_unused_functions
);
324 * drm_encoder_crtc_ok - can a given crtc drive a given encoder?
325 * @encoder: encoder to test
326 * @crtc: crtc to test
328 * Return false if @encoder can't be driven by @crtc, true otherwise.
330 static bool drm_encoder_crtc_ok(struct drm_encoder
*encoder
,
331 struct drm_crtc
*crtc
)
333 struct drm_device
*dev
;
334 struct drm_crtc
*tmp
;
337 WARN(!crtc
, "checking null crtc?\n");
341 list_for_each_entry(tmp
, &dev
->mode_config
.crtc_list
, head
) {
347 if (encoder
->possible_crtcs
& crtc_mask
)
353 * Check the CRTC we're going to map each output to vs. its current
354 * CRTC. If they don't match, we have to disable the output and the CRTC
355 * since the driver will have to re-route things.
358 drm_crtc_prepare_encoders(struct drm_device
*dev
)
360 struct drm_encoder_helper_funcs
*encoder_funcs
;
361 struct drm_encoder
*encoder
;
363 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
) {
364 encoder_funcs
= encoder
->helper_private
;
365 /* Disable unused encoders */
366 if (encoder
->crtc
== NULL
)
367 drm_encoder_disable(encoder
);
368 /* Disable encoders whose CRTC is about to change */
369 if (encoder_funcs
->get_crtc
&&
370 encoder
->crtc
!= (*encoder_funcs
->get_crtc
)(encoder
))
371 drm_encoder_disable(encoder
);
376 * drm_crtc_helper_set_mode - internal helper to set a mode
377 * @crtc: CRTC to program
379 * @x: horizontal offset into the surface
380 * @y: vertical offset into the surface
381 * @old_fb: old framebuffer, for cleanup
384 * Caller must hold mode config lock.
386 * Try to set @mode on @crtc. Give @crtc and its associated connectors a chance
387 * to fixup or reject the mode prior to trying to set it. This is an internal
388 * helper that drivers could e.g. use to update properties that require the
389 * entire output pipe to be disabled and re-enabled in a new configuration. For
390 * example for changing whether audio is enabled on a hdmi link or for changing
391 * panel fitter or dither attributes. It is also called by the
392 * drm_crtc_helper_set_config() helper function to drive the mode setting
396 * True if the mode was set successfully, or false otherwise.
398 bool drm_crtc_helper_set_mode(struct drm_crtc
*crtc
,
399 struct drm_display_mode
*mode
,
401 struct drm_framebuffer
*old_fb
)
403 struct drm_device
*dev
= crtc
->dev
;
404 struct drm_display_mode
*adjusted_mode
, saved_mode
, saved_hwmode
;
405 struct drm_crtc_helper_funcs
*crtc_funcs
= crtc
->helper_private
;
406 struct drm_encoder_helper_funcs
*encoder_funcs
;
407 int saved_x
, saved_y
;
408 struct drm_encoder
*encoder
;
411 crtc
->enabled
= drm_helper_crtc_in_use(crtc
);
415 adjusted_mode
= drm_mode_duplicate(dev
, mode
);
419 saved_hwmode
= crtc
->hwmode
;
420 saved_mode
= crtc
->mode
;
424 /* Update crtc values up front so the driver can rely on them for mode
431 /* Pass our mode to the connectors and the CRTC to give them a chance to
432 * adjust it according to limitations or connector properties, and also
433 * a chance to reject the mode entirely.
435 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
) {
437 if (encoder
->crtc
!= crtc
)
440 if (encoder
->bridge
&& encoder
->bridge
->funcs
->mode_fixup
) {
441 ret
= encoder
->bridge
->funcs
->mode_fixup(
442 encoder
->bridge
, mode
, adjusted_mode
);
444 DRM_DEBUG_KMS("Bridge fixup failed\n");
449 encoder_funcs
= encoder
->helper_private
;
450 if (!(ret
= encoder_funcs
->mode_fixup(encoder
, mode
,
452 DRM_DEBUG_KMS("Encoder fixup failed\n");
457 if (!(ret
= crtc_funcs
->mode_fixup(crtc
, mode
, adjusted_mode
))) {
458 DRM_DEBUG_KMS("CRTC fixup failed\n");
461 DRM_DEBUG_KMS("[CRTC:%d]\n", crtc
->base
.id
);
463 /* Prepare the encoders and CRTCs before setting the mode. */
464 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
) {
466 if (encoder
->crtc
!= crtc
)
470 encoder
->bridge
->funcs
->disable(encoder
->bridge
);
472 encoder_funcs
= encoder
->helper_private
;
473 /* Disable the encoders as the first thing we do. */
474 encoder_funcs
->prepare(encoder
);
477 encoder
->bridge
->funcs
->post_disable(encoder
->bridge
);
480 drm_crtc_prepare_encoders(dev
);
482 crtc_funcs
->prepare(crtc
);
484 /* Set up the DPLL and any encoders state that needs to adjust or depend
487 ret
= !crtc_funcs
->mode_set(crtc
, mode
, adjusted_mode
, x
, y
, old_fb
);
491 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
) {
493 if (encoder
->crtc
!= crtc
)
496 DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n",
497 encoder
->base
.id
, drm_get_encoder_name(encoder
),
498 mode
->base
.id
, mode
->name
);
499 encoder_funcs
= encoder
->helper_private
;
500 encoder_funcs
->mode_set(encoder
, mode
, adjusted_mode
);
502 if (encoder
->bridge
&& encoder
->bridge
->funcs
->mode_set
)
503 encoder
->bridge
->funcs
->mode_set(encoder
->bridge
, mode
,
507 /* Now enable the clocks, plane, pipe, and connectors that we set up. */
508 crtc_funcs
->commit(crtc
);
510 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
) {
512 if (encoder
->crtc
!= crtc
)
516 encoder
->bridge
->funcs
->pre_enable(encoder
->bridge
);
518 encoder_funcs
= encoder
->helper_private
;
519 encoder_funcs
->commit(encoder
);
522 encoder
->bridge
->funcs
->enable(encoder
->bridge
);
525 /* Store real post-adjustment hardware mode. */
526 crtc
->hwmode
= *adjusted_mode
;
528 /* Calculate and store various constants which
529 * are later needed by vblank and swap-completion
530 * timestamping. They are derived from true hwmode.
532 drm_calc_timestamping_constants(crtc
);
534 /* FIXME: add subpixel order */
536 drm_mode_destroy(dev
, adjusted_mode
);
538 crtc
->hwmode
= saved_hwmode
;
539 crtc
->mode
= saved_mode
;
546 EXPORT_SYMBOL(drm_crtc_helper_set_mode
);
550 drm_crtc_helper_disable(struct drm_crtc
*crtc
)
552 struct drm_device
*dev
= crtc
->dev
;
553 struct drm_connector
*connector
;
554 struct drm_encoder
*encoder
;
556 /* Decouple all encoders and their attached connectors from this crtc */
557 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
) {
558 if (encoder
->crtc
!= crtc
)
561 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
562 if (connector
->encoder
!= encoder
)
565 connector
->encoder
= NULL
;
568 * drm_helper_disable_unused_functions() ought to be
569 * doing this, but since we've decoupled the encoder
570 * from the connector above, the required connection
571 * between them is henceforth no longer available.
573 connector
->dpms
= DRM_MODE_DPMS_OFF
;
577 drm_helper_disable_unused_functions(dev
);
582 * drm_crtc_helper_set_config - set a new config from userspace
583 * @set: mode set configuration
586 * Caller must hold mode config lock.
588 * Setup a new configuration, provided by the upper layers (either an ioctl call
589 * from userspace or internally e.g. from the fbdev suppport code) in @set, and
590 * enable it. This is the main helper functions for drivers that implement
591 * kernel mode setting with the crtc helper functions and the assorted
592 * ->prepare(), ->modeset() and ->commit() helper callbacks.
595 * Returns 0 on success, -ERRNO on failure.
597 int drm_crtc_helper_set_config(struct drm_mode_set
*set
)
599 struct drm_device
*dev
;
600 struct drm_crtc
*save_crtcs
, *new_crtc
, *crtc
;
601 struct drm_encoder
*save_encoders
, *new_encoder
, *encoder
;
602 struct drm_framebuffer
*old_fb
= NULL
;
603 bool mode_changed
= false; /* if true do a full mode set */
604 bool fb_changed
= false; /* if true and !mode_changed just do a flip */
605 struct drm_connector
*save_connectors
, *connector
;
606 int count
= 0, ro
, fail
= 0;
607 struct drm_crtc_helper_funcs
*crtc_funcs
;
608 struct drm_mode_set save_set
;
616 BUG_ON(!set
->crtc
->helper_private
);
618 /* Enforce sane interface api - has been abused by the fb helper. */
619 BUG_ON(!set
->mode
&& set
->fb
);
620 BUG_ON(set
->fb
&& set
->num_connectors
== 0);
622 crtc_funcs
= set
->crtc
->helper_private
;
628 DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n",
629 set
->crtc
->base
.id
, set
->fb
->base
.id
,
630 (int)set
->num_connectors
, set
->x
, set
->y
);
632 DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set
->crtc
->base
.id
);
633 return drm_crtc_helper_disable(set
->crtc
);
636 dev
= set
->crtc
->dev
;
638 /* Allocate space for the backup of all (non-pointer) crtc, encoder and
640 save_crtcs
= kzalloc(dev
->mode_config
.num_crtc
*
641 sizeof(struct drm_crtc
), GFP_KERNEL
);
645 save_encoders
= kzalloc(dev
->mode_config
.num_encoder
*
646 sizeof(struct drm_encoder
), GFP_KERNEL
);
647 if (!save_encoders
) {
652 save_connectors
= kzalloc(dev
->mode_config
.num_connector
*
653 sizeof(struct drm_connector
), GFP_KERNEL
);
654 if (!save_connectors
) {
656 kfree(save_encoders
);
660 /* Copy data. Note that driver private data is not affected.
661 * Should anything bad happen only the expected state is
662 * restored, not the drivers personal bookkeeping.
665 list_for_each_entry(crtc
, &dev
->mode_config
.crtc_list
, head
) {
666 save_crtcs
[count
++] = *crtc
;
670 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
) {
671 save_encoders
[count
++] = *encoder
;
675 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
676 save_connectors
[count
++] = *connector
;
679 save_set
.crtc
= set
->crtc
;
680 save_set
.mode
= &set
->crtc
->mode
;
681 save_set
.x
= set
->crtc
->x
;
682 save_set
.y
= set
->crtc
->y
;
683 save_set
.fb
= set
->crtc
->fb
;
685 /* We should be able to check here if the fb has the same properties
686 * and then just flip_or_move it */
687 if (set
->crtc
->fb
!= set
->fb
) {
688 /* If we have no fb then treat it as a full mode set */
689 if (set
->crtc
->fb
== NULL
) {
690 DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
692 } else if (set
->fb
== NULL
) {
694 } else if (set
->fb
->pixel_format
!=
695 set
->crtc
->fb
->pixel_format
) {
701 if (set
->x
!= set
->crtc
->x
|| set
->y
!= set
->crtc
->y
)
704 if (set
->mode
&& !drm_mode_equal(set
->mode
, &set
->crtc
->mode
)) {
705 DRM_DEBUG_KMS("modes are different, full mode set\n");
706 drm_mode_debug_printmodeline(&set
->crtc
->mode
);
707 drm_mode_debug_printmodeline(set
->mode
);
711 /* a) traverse passed in connector list and get encoders for them */
713 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
714 struct drm_connector_helper_funcs
*connector_funcs
=
715 connector
->helper_private
;
716 new_encoder
= connector
->encoder
;
717 for (ro
= 0; ro
< set
->num_connectors
; ro
++) {
718 if (set
->connectors
[ro
] == connector
) {
719 new_encoder
= connector_funcs
->best_encoder(connector
);
720 /* if we can't get an encoder for a connector
721 we are setting now - then fail */
722 if (new_encoder
== NULL
)
723 /* don't break so fail path works correct */
727 if (connector
->dpms
!= DRM_MODE_DPMS_ON
) {
728 DRM_DEBUG_KMS("connector dpms not on, full mode switch\n");
734 if (new_encoder
!= connector
->encoder
) {
735 DRM_DEBUG_KMS("encoder changed, full mode switch\n");
737 /* If the encoder is reused for another connector, then
738 * the appropriate crtc will be set later.
740 if (connector
->encoder
)
741 connector
->encoder
->crtc
= NULL
;
742 connector
->encoder
= new_encoder
;
752 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
753 if (!connector
->encoder
)
756 if (connector
->encoder
->crtc
== set
->crtc
)
759 new_crtc
= connector
->encoder
->crtc
;
761 for (ro
= 0; ro
< set
->num_connectors
; ro
++) {
762 if (set
->connectors
[ro
] == connector
)
763 new_crtc
= set
->crtc
;
766 /* Make sure the new CRTC will work with the encoder */
768 !drm_encoder_crtc_ok(connector
->encoder
, new_crtc
)) {
772 if (new_crtc
!= connector
->encoder
->crtc
) {
773 DRM_DEBUG_KMS("crtc changed, full mode switch\n");
775 connector
->encoder
->crtc
= new_crtc
;
778 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n",
779 connector
->base
.id
, drm_get_connector_name(connector
),
782 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
783 connector
->base
.id
, drm_get_connector_name(connector
));
787 /* mode_set_base is not a required function */
788 if (fb_changed
&& !crtc_funcs
->mode_set_base
)
792 set
->crtc
->enabled
= drm_helper_crtc_in_use(set
->crtc
);
793 if (set
->crtc
->enabled
) {
794 DRM_DEBUG_KMS("attempting to set mode from"
796 drm_mode_debug_printmodeline(set
->mode
);
797 old_fb
= set
->crtc
->fb
;
798 set
->crtc
->fb
= set
->fb
;
799 if (!drm_crtc_helper_set_mode(set
->crtc
, set
->mode
,
802 DRM_ERROR("failed to set mode on [CRTC:%d]\n",
804 set
->crtc
->fb
= old_fb
;
808 DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
809 for (i
= 0; i
< set
->num_connectors
; i
++) {
810 DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set
->connectors
[i
]->base
.id
,
811 drm_get_connector_name(set
->connectors
[i
]));
812 set
->connectors
[i
]->funcs
->dpms(set
->connectors
[i
], DRM_MODE_DPMS_ON
);
815 drm_helper_disable_unused_functions(dev
);
816 } else if (fb_changed
) {
817 set
->crtc
->x
= set
->x
;
818 set
->crtc
->y
= set
->y
;
820 old_fb
= set
->crtc
->fb
;
821 if (set
->crtc
->fb
!= set
->fb
)
822 set
->crtc
->fb
= set
->fb
;
823 ret
= crtc_funcs
->mode_set_base(set
->crtc
,
824 set
->x
, set
->y
, old_fb
);
826 set
->crtc
->fb
= old_fb
;
831 kfree(save_connectors
);
832 kfree(save_encoders
);
837 /* Restore all previous data. */
839 list_for_each_entry(crtc
, &dev
->mode_config
.crtc_list
, head
) {
840 *crtc
= save_crtcs
[count
++];
844 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
) {
845 *encoder
= save_encoders
[count
++];
849 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
850 *connector
= save_connectors
[count
++];
853 /* Try to restore the config */
855 !drm_crtc_helper_set_mode(save_set
.crtc
, save_set
.mode
, save_set
.x
,
856 save_set
.y
, save_set
.fb
))
857 DRM_ERROR("failed to restore config after modeset failure\n");
859 kfree(save_connectors
);
860 kfree(save_encoders
);
864 EXPORT_SYMBOL(drm_crtc_helper_set_config
);
866 static int drm_helper_choose_encoder_dpms(struct drm_encoder
*encoder
)
868 int dpms
= DRM_MODE_DPMS_OFF
;
869 struct drm_connector
*connector
;
870 struct drm_device
*dev
= encoder
->dev
;
872 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
)
873 if (connector
->encoder
== encoder
)
874 if (connector
->dpms
< dpms
)
875 dpms
= connector
->dpms
;
879 /* Helper which handles bridge ordering around encoder dpms */
880 static void drm_helper_encoder_dpms(struct drm_encoder
*encoder
, int mode
)
882 struct drm_bridge
*bridge
= encoder
->bridge
;
883 struct drm_encoder_helper_funcs
*encoder_funcs
;
886 if (mode
== DRM_MODE_DPMS_ON
)
887 bridge
->funcs
->pre_enable(bridge
);
889 bridge
->funcs
->disable(bridge
);
892 encoder_funcs
= encoder
->helper_private
;
893 if (encoder_funcs
->dpms
)
894 encoder_funcs
->dpms(encoder
, mode
);
897 if (mode
== DRM_MODE_DPMS_ON
)
898 bridge
->funcs
->enable(bridge
);
900 bridge
->funcs
->post_disable(bridge
);
904 static int drm_helper_choose_crtc_dpms(struct drm_crtc
*crtc
)
906 int dpms
= DRM_MODE_DPMS_OFF
;
907 struct drm_connector
*connector
;
908 struct drm_device
*dev
= crtc
->dev
;
910 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
)
911 if (connector
->encoder
&& connector
->encoder
->crtc
== crtc
)
912 if (connector
->dpms
< dpms
)
913 dpms
= connector
->dpms
;
918 * drm_helper_connector_dpms() - connector dpms helper implementation
919 * @connector: affected connector
922 * This is the main helper function provided by the crtc helper framework for
923 * implementing the DPMS connector attribute. It computes the new desired DPMS
924 * state for all encoders and crtcs in the output mesh and calls the ->dpms()
925 * callback provided by the driver appropriately.
927 void drm_helper_connector_dpms(struct drm_connector
*connector
, int mode
)
929 struct drm_encoder
*encoder
= connector
->encoder
;
930 struct drm_crtc
*crtc
= encoder
? encoder
->crtc
: NULL
;
931 int old_dpms
, encoder_dpms
= DRM_MODE_DPMS_OFF
;
933 if (mode
== connector
->dpms
)
936 old_dpms
= connector
->dpms
;
937 connector
->dpms
= mode
;
940 encoder_dpms
= drm_helper_choose_encoder_dpms(encoder
);
942 /* from off to on, do crtc then encoder */
943 if (mode
< old_dpms
) {
945 struct drm_crtc_helper_funcs
*crtc_funcs
= crtc
->helper_private
;
946 if (crtc_funcs
->dpms
)
947 (*crtc_funcs
->dpms
) (crtc
,
948 drm_helper_choose_crtc_dpms(crtc
));
951 drm_helper_encoder_dpms(encoder
, encoder_dpms
);
954 /* from on to off, do encoder then crtc */
955 if (mode
> old_dpms
) {
957 drm_helper_encoder_dpms(encoder
, encoder_dpms
);
959 struct drm_crtc_helper_funcs
*crtc_funcs
= crtc
->helper_private
;
960 if (crtc_funcs
->dpms
)
961 (*crtc_funcs
->dpms
) (crtc
,
962 drm_helper_choose_crtc_dpms(crtc
));
968 EXPORT_SYMBOL(drm_helper_connector_dpms
);
970 int drm_helper_mode_fill_fb_struct(struct drm_framebuffer
*fb
,
971 struct drm_mode_fb_cmd2
*mode_cmd
)
975 fb
->width
= mode_cmd
->width
;
976 fb
->height
= mode_cmd
->height
;
977 for (i
= 0; i
< 4; i
++) {
978 fb
->pitches
[i
] = mode_cmd
->pitches
[i
];
979 fb
->offsets
[i
] = mode_cmd
->offsets
[i
];
981 drm_fb_get_bpp_depth(mode_cmd
->pixel_format
, &fb
->depth
,
982 &fb
->bits_per_pixel
);
983 fb
->pixel_format
= mode_cmd
->pixel_format
;
987 EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct
);
989 int drm_helper_resume_force_mode(struct drm_device
*dev
)
991 struct drm_crtc
*crtc
;
992 struct drm_encoder
*encoder
;
993 struct drm_crtc_helper_funcs
*crtc_funcs
;
994 int ret
, encoder_dpms
;
996 list_for_each_entry(crtc
, &dev
->mode_config
.crtc_list
, head
) {
1001 ret
= drm_crtc_helper_set_mode(crtc
, &crtc
->mode
,
1002 crtc
->x
, crtc
->y
, crtc
->fb
);
1005 DRM_ERROR("failed to set mode on crtc %p\n", crtc
);
1007 /* Turn off outputs that were already powered off */
1008 if (drm_helper_choose_crtc_dpms(crtc
)) {
1009 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
) {
1011 if(encoder
->crtc
!= crtc
)
1014 encoder_dpms
= drm_helper_choose_encoder_dpms(
1017 drm_helper_encoder_dpms(encoder
, encoder_dpms
);
1020 crtc_funcs
= crtc
->helper_private
;
1021 if (crtc_funcs
->dpms
)
1022 (*crtc_funcs
->dpms
) (crtc
,
1023 drm_helper_choose_crtc_dpms(crtc
));
1026 /* disable the unused connectors while restoring the modesetting */
1027 drm_helper_disable_unused_functions(dev
);
1030 EXPORT_SYMBOL(drm_helper_resume_force_mode
);
1032 void drm_kms_helper_hotplug_event(struct drm_device
*dev
)
1034 /* send a uevent + call fbdev */
1035 drm_sysfs_hotplug_event(dev
);
1036 if (dev
->mode_config
.funcs
->output_poll_changed
)
1037 dev
->mode_config
.funcs
->output_poll_changed(dev
);
1039 EXPORT_SYMBOL(drm_kms_helper_hotplug_event
);
1041 #define DRM_OUTPUT_POLL_PERIOD (10*HZ)
1042 static void output_poll_execute(struct work_struct
*work
)
1044 struct delayed_work
*delayed_work
= to_delayed_work(work
);
1045 struct drm_device
*dev
= container_of(delayed_work
, struct drm_device
, mode_config
.output_poll_work
);
1046 struct drm_connector
*connector
;
1047 enum drm_connector_status old_status
;
1048 bool repoll
= false, changed
= false;
1050 if (!drm_kms_helper_poll
)
1053 mutex_lock(&dev
->mode_config
.mutex
);
1054 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
1056 /* Ignore forced connectors. */
1057 if (connector
->force
)
1060 /* Ignore HPD capable connectors and connectors where we don't
1061 * want any hotplug detection at all for polling. */
1062 if (!connector
->polled
|| connector
->polled
== DRM_CONNECTOR_POLL_HPD
)
1067 old_status
= connector
->status
;
1068 /* if we are connected and don't want to poll for disconnect
1070 if (old_status
== connector_status_connected
&&
1071 !(connector
->polled
& DRM_CONNECTOR_POLL_DISCONNECT
))
1074 connector
->status
= connector
->funcs
->detect(connector
, false);
1075 if (old_status
!= connector
->status
) {
1076 const char *old
, *new;
1078 old
= drm_get_connector_status_name(old_status
);
1079 new = drm_get_connector_status_name(connector
->status
);
1081 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] "
1082 "status updated from %s to %s\n",
1084 drm_get_connector_name(connector
),
1091 mutex_unlock(&dev
->mode_config
.mutex
);
1094 drm_kms_helper_hotplug_event(dev
);
1097 schedule_delayed_work(delayed_work
, DRM_OUTPUT_POLL_PERIOD
);
1100 void drm_kms_helper_poll_disable(struct drm_device
*dev
)
1102 if (!dev
->mode_config
.poll_enabled
)
1104 cancel_delayed_work_sync(&dev
->mode_config
.output_poll_work
);
1106 EXPORT_SYMBOL(drm_kms_helper_poll_disable
);
1108 void drm_kms_helper_poll_enable(struct drm_device
*dev
)
1111 struct drm_connector
*connector
;
1113 if (!dev
->mode_config
.poll_enabled
|| !drm_kms_helper_poll
)
1116 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
1117 if (connector
->polled
& (DRM_CONNECTOR_POLL_CONNECT
|
1118 DRM_CONNECTOR_POLL_DISCONNECT
))
1123 schedule_delayed_work(&dev
->mode_config
.output_poll_work
, DRM_OUTPUT_POLL_PERIOD
);
1125 EXPORT_SYMBOL(drm_kms_helper_poll_enable
);
1127 void drm_kms_helper_poll_init(struct drm_device
*dev
)
1129 INIT_DELAYED_WORK(&dev
->mode_config
.output_poll_work
, output_poll_execute
);
1130 dev
->mode_config
.poll_enabled
= true;
1132 drm_kms_helper_poll_enable(dev
);
1134 EXPORT_SYMBOL(drm_kms_helper_poll_init
);
1136 void drm_kms_helper_poll_fini(struct drm_device
*dev
)
1138 drm_kms_helper_poll_disable(dev
);
1140 EXPORT_SYMBOL(drm_kms_helper_poll_fini
);
1142 void drm_helper_hpd_irq_event(struct drm_device
*dev
)
1144 struct drm_connector
*connector
;
1145 enum drm_connector_status old_status
;
1146 bool changed
= false;
1148 if (!dev
->mode_config
.poll_enabled
)
1151 mutex_lock(&dev
->mode_config
.mutex
);
1152 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
1154 /* Only handle HPD capable connectors. */
1155 if (!(connector
->polled
& DRM_CONNECTOR_POLL_HPD
))
1158 old_status
= connector
->status
;
1160 connector
->status
= connector
->funcs
->detect(connector
, false);
1161 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n",
1163 drm_get_connector_name(connector
),
1164 drm_get_connector_status_name(old_status
),
1165 drm_get_connector_status_name(connector
->status
));
1166 if (old_status
!= connector
->status
)
1170 mutex_unlock(&dev
->mode_config
.mutex
);
1173 drm_kms_helper_hotplug_event(dev
);
1175 EXPORT_SYMBOL(drm_helper_hpd_irq_event
);