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>
31 * $FreeBSD: src/sys/dev/drm2/drm_crtc_helper.c,v 1.1 2012/05/22 11:07:44 kib Exp $
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <dev/drm2/drmP.h>
37 #include <dev/drm2/drm_crtc.h>
38 #include <dev/drm2/drm_fourcc.h>
39 #include <dev/drm2/drm_crtc_helper.h>
40 #include <dev/drm2/drm_fb_helper.h>
43 drm_fetch_cmdline_mode_from_kenv(struct drm_connector *connector,
44 struct drm_cmdline_mode *cmdline_mode)
46 char *tun_var_name, *tun_mode;
47 static const char tun_prefix[] = "drm_mode.";
51 tun_var_name = kmalloc(sizeof(tun_prefix) +
52 strlen(drm_get_connector_name(connector)), M_TEMP, M_WAITOK);
53 strcpy(tun_var_name, tun_prefix);
54 strcat(tun_var_name, drm_get_connector_name(connector));
55 tun_mode = kgetenv(tun_var_name);
56 if (tun_mode != NULL) {
57 res = drm_mode_parse_command_line_for_connector(tun_mode,
58 connector, cmdline_mode);
61 free(tun_var_name, M_TEMP);
65 static bool drm_kms_helper_poll = true;
67 static void drm_mode_validate_flag(struct drm_connector *connector,
70 struct drm_display_mode *mode, *t;
72 if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE))
75 list_for_each_entry_safe(mode, t, &connector->modes, head) {
76 if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
77 !(flags & DRM_MODE_FLAG_INTERLACE))
78 mode->status = MODE_NO_INTERLACE;
79 if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
80 !(flags & DRM_MODE_FLAG_DBLSCAN))
81 mode->status = MODE_NO_DBLESCAN;
88 * drm_helper_probe_single_connector_modes - get complete set of display modes
90 * @maxX: max width for modes
91 * @maxY: max height for modes
94 * Caller must hold mode config lock.
96 * Based on @dev's mode_config layout, scan all the connectors and try to detect
97 * modes on them. Modes will first be added to the connector's probed_modes
98 * list, then culled (based on validity and the @maxX, @maxY parameters) and
99 * put into the normal modes list.
101 * Intended to be used either at bootup time or when major configuration
102 * changes have occurred.
104 * FIXME: take into account monitor limits
107 * Number of modes found on @connector.
109 int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
110 uint32_t maxX, uint32_t maxY)
112 struct drm_device *dev = connector->dev;
113 struct drm_display_mode *mode, *t;
114 struct drm_connector_helper_funcs *connector_funcs =
115 connector->helper_private;
116 struct drm_cmdline_mode cmdline_mode;
120 DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
121 drm_get_connector_name(connector));
122 /* set all modes to the unverified state */
123 list_for_each_entry_safe(mode, t, &connector->modes, head)
124 mode->status = MODE_UNVERIFIED;
126 if (connector->force) {
127 if (connector->force == DRM_FORCE_ON)
128 connector->status = connector_status_connected;
130 connector->status = connector_status_disconnected;
131 if (connector->funcs->force)
132 connector->funcs->force(connector);
134 connector->status = connector->funcs->detect(connector, true);
135 drm_kms_helper_poll_enable(dev);
138 if (connector->status == connector_status_disconnected) {
139 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
140 connector->base.id, drm_get_connector_name(connector));
141 drm_mode_connector_update_edid_property(connector, NULL);
145 count = (*connector_funcs->get_modes)(connector);
146 if (count == 0 && drm_fetch_cmdline_mode_from_kenv(connector,
148 mode = drm_mode_create_from_cmdline_mode(dev,
152 "[CONNECTOR:%d:%s] found manual override ",
154 drm_get_connector_name(connector));
155 drm_mode_debug_printmodeline(mode);
156 drm_mode_probed_add(connector, mode);
160 "[CONNECTOR:%d:%s] manual override mode: parse error\n",
162 drm_get_connector_name(connector));
165 if (count == 0 && connector->status == connector_status_connected)
166 count = drm_add_modes_noedid(connector, 1024, 768);
170 drm_mode_connector_list_update(connector);
173 drm_mode_validate_size(dev, &connector->modes, maxX,
176 if (connector->interlace_allowed)
177 mode_flags |= DRM_MODE_FLAG_INTERLACE;
178 if (connector->doublescan_allowed)
179 mode_flags |= DRM_MODE_FLAG_DBLSCAN;
180 drm_mode_validate_flag(connector, mode_flags);
182 list_for_each_entry_safe(mode, t, &connector->modes, head) {
183 if (mode->status == MODE_OK)
184 mode->status = connector_funcs->mode_valid(connector,
189 drm_mode_prune_invalid(dev, &connector->modes, true);
191 if (list_empty(&connector->modes))
194 drm_mode_sort(&connector->modes);
196 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
197 drm_get_connector_name(connector));
198 list_for_each_entry_safe(mode, t, &connector->modes, head) {
199 mode->vrefresh = drm_mode_vrefresh(mode);
201 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
202 drm_mode_debug_printmodeline(mode);
209 * drm_helper_encoder_in_use - check if a given encoder is in use
210 * @encoder: encoder to check
213 * Caller must hold mode config lock.
215 * Walk @encoders's DRM device's mode_config and see if it's in use.
218 * True if @encoder is part of the mode_config, false otherwise.
220 bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
222 struct drm_connector *connector;
223 struct drm_device *dev = encoder->dev;
224 list_for_each_entry(connector, &dev->mode_config.connector_list, head)
225 if (connector->encoder == encoder)
231 * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config
232 * @crtc: CRTC to check
235 * Caller must hold mode config lock.
237 * Walk @crtc's DRM device's mode_config and see if it's in use.
240 * True if @crtc is part of the mode_config, false otherwise.
242 bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
244 struct drm_encoder *encoder;
245 struct drm_device *dev = crtc->dev;
246 /* FIXME: Locking around list access? */
247 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
248 if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder))
254 drm_encoder_disable(struct drm_encoder *encoder)
256 struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
258 if (encoder_funcs->disable)
259 (*encoder_funcs->disable)(encoder);
261 (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
265 * drm_helper_disable_unused_functions - disable unused objects
269 * Caller must hold mode config lock.
271 * If an connector or CRTC isn't part of @dev's mode_config, it can be disabled
272 * by calling its dpms function, which should power it off.
274 void drm_helper_disable_unused_functions(struct drm_device *dev)
276 struct drm_encoder *encoder;
277 struct drm_connector *connector;
278 struct drm_crtc *crtc;
280 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
281 if (!connector->encoder)
283 if (connector->status == connector_status_disconnected)
284 connector->encoder = NULL;
287 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
288 if (!drm_helper_encoder_in_use(encoder)) {
289 drm_encoder_disable(encoder);
290 /* disconnector encoder from any connector */
291 encoder->crtc = NULL;
295 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
296 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
297 crtc->enabled = drm_helper_crtc_in_use(crtc);
298 if (!crtc->enabled) {
299 if (crtc_funcs->disable)
300 (*crtc_funcs->disable)(crtc);
302 (*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
309 * drm_encoder_crtc_ok - can a given crtc drive a given encoder?
310 * @encoder: encoder to test
311 * @crtc: crtc to test
313 * Return false if @encoder can't be driven by @crtc, true otherwise.
315 static bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
316 struct drm_crtc *crtc)
318 struct drm_device *dev;
319 struct drm_crtc *tmp;
323 kprintf("checking null crtc?\n");
327 list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) {
333 if (encoder->possible_crtcs & crtc_mask)
339 * Check the CRTC we're going to map each output to vs. its current
340 * CRTC. If they don't match, we have to disable the output and the CRTC
341 * since the driver will have to re-route things.
344 drm_crtc_prepare_encoders(struct drm_device *dev)
346 struct drm_encoder_helper_funcs *encoder_funcs;
347 struct drm_encoder *encoder;
349 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
350 encoder_funcs = encoder->helper_private;
351 /* Disable unused encoders */
352 if (encoder->crtc == NULL)
353 drm_encoder_disable(encoder);
354 /* Disable encoders whose CRTC is about to change */
355 if (encoder_funcs->get_crtc &&
356 encoder->crtc != (*encoder_funcs->get_crtc)(encoder))
357 drm_encoder_disable(encoder);
362 * drm_crtc_set_mode - set a mode
363 * @crtc: CRTC to program
369 * Caller must hold mode config lock.
371 * Try to set @mode on @crtc. Give @crtc and its associated connectors a chance
372 * to fixup or reject the mode prior to trying to set it.
375 * True if the mode was set successfully, or false otherwise.
377 bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
378 struct drm_display_mode *mode,
380 struct drm_framebuffer *old_fb)
382 struct drm_device *dev = crtc->dev;
383 struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
384 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
385 struct drm_encoder_helper_funcs *encoder_funcs;
386 int saved_x, saved_y;
387 struct drm_encoder *encoder;
390 crtc->enabled = drm_helper_crtc_in_use(crtc);
394 adjusted_mode = drm_mode_duplicate(dev, mode);
398 saved_hwmode = crtc->hwmode;
399 saved_mode = crtc->mode;
403 /* Update crtc values up front so the driver can rely on them for mode
410 /* Pass our mode to the connectors and the CRTC to give them a chance to
411 * adjust it according to limitations or connector properties, and also
412 * a chance to reject the mode entirely.
414 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
416 if (encoder->crtc != crtc)
418 encoder_funcs = encoder->helper_private;
419 if (!(ret = encoder_funcs->mode_fixup(encoder, mode,
425 if (!(ret = crtc_funcs->mode_fixup(crtc, mode, adjusted_mode))) {
428 DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
430 /* Prepare the encoders and CRTCs before setting the mode. */
431 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
433 if (encoder->crtc != crtc)
435 encoder_funcs = encoder->helper_private;
436 /* Disable the encoders as the first thing we do. */
437 encoder_funcs->prepare(encoder);
440 drm_crtc_prepare_encoders(dev);
442 crtc_funcs->prepare(crtc);
444 /* Set up the DPLL and any encoders state that needs to adjust or depend
447 ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
451 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
453 if (encoder->crtc != crtc)
456 DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n",
457 encoder->base.id, drm_get_encoder_name(encoder),
458 mode->base.id, mode->name);
459 encoder_funcs = encoder->helper_private;
460 encoder_funcs->mode_set(encoder, mode, adjusted_mode);
463 /* Now enable the clocks, plane, pipe, and connectors that we set up. */
464 crtc_funcs->commit(crtc);
466 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
468 if (encoder->crtc != crtc)
471 encoder_funcs = encoder->helper_private;
472 encoder_funcs->commit(encoder);
476 /* Store real post-adjustment hardware mode. */
477 crtc->hwmode = *adjusted_mode;
479 /* Calculate and store various constants which
480 * are later needed by vblank and swap-completion
481 * timestamping. They are derived from true hwmode.
483 drm_calc_timestamping_constants(crtc);
485 /* FIXME: add subpixel order */
487 drm_mode_destroy(dev, adjusted_mode);
489 crtc->hwmode = saved_hwmode;
490 crtc->mode = saved_mode;
499 drm_crtc_helper_disable(struct drm_crtc *crtc)
501 struct drm_device *dev = crtc->dev;
502 struct drm_connector *connector;
503 struct drm_encoder *encoder;
505 /* Decouple all encoders and their attached connectors from this crtc */
506 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
507 if (encoder->crtc != crtc)
510 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
511 if (connector->encoder != encoder)
514 connector->encoder = NULL;
518 drm_helper_disable_unused_functions(dev);
523 * drm_crtc_helper_set_config - set a new config from userspace
524 * @crtc: CRTC to setup
525 * @crtc_info: user provided configuration
526 * @new_mode: new mode to set
527 * @connector_set: set of connectors for the new config
528 * @fb: new framebuffer
531 * Caller must hold mode config lock.
533 * Setup a new configuration, provided by the user in @crtc_info, and enable
539 int drm_crtc_helper_set_config(struct drm_mode_set *set)
541 struct drm_device *dev;
542 struct drm_crtc *save_crtcs, *new_crtc, *crtc;
543 struct drm_encoder *save_encoders, *new_encoder, *encoder;
544 struct drm_framebuffer *old_fb = NULL;
545 bool mode_changed = false; /* if true do a full mode set */
546 bool fb_changed = false; /* if true and !mode_changed just do a flip */
547 struct drm_connector *save_connectors, *connector;
548 int count = 0, ro, fail = 0;
549 struct drm_crtc_helper_funcs *crtc_funcs;
550 struct drm_mode_set save_set;
562 if (!set->crtc->helper_private)
565 crtc_funcs = set->crtc->helper_private;
571 DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n",
572 set->crtc->base.id, set->fb->base.id,
573 (int)set->num_connectors, set->x, set->y);
575 DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id);
576 return drm_crtc_helper_disable(set->crtc);
579 dev = set->crtc->dev;
581 /* Allocate space for the backup of all (non-pointer) crtc, encoder and
583 save_crtcs = kmalloc(dev->mode_config.num_crtc * sizeof(struct drm_crtc),
584 DRM_MEM_KMS, M_WAITOK | M_ZERO);
585 save_encoders = kmalloc(dev->mode_config.num_encoder *
586 sizeof(struct drm_encoder), DRM_MEM_KMS, M_WAITOK | M_ZERO);
587 save_connectors = kmalloc(dev->mode_config.num_connector *
588 sizeof(struct drm_connector), DRM_MEM_KMS, M_WAITOK | M_ZERO);
590 /* Copy data. Note that driver private data is not affected.
591 * Should anything bad happen only the expected state is
592 * restored, not the drivers personal bookkeeping.
595 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
596 save_crtcs[count++] = *crtc;
600 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
601 save_encoders[count++] = *encoder;
605 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
606 save_connectors[count++] = *connector;
609 save_set.crtc = set->crtc;
610 save_set.mode = &set->crtc->mode;
611 save_set.x = set->crtc->x;
612 save_set.y = set->crtc->y;
613 save_set.fb = set->crtc->fb;
615 /* We should be able to check here if the fb has the same properties
616 * and then just flip_or_move it */
617 if (set->crtc->fb != set->fb) {
618 /* If we have no fb then treat it as a full mode set */
619 if (set->crtc->fb == NULL) {
620 DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
622 } else if (set->fb == NULL) {
628 if (set->x != set->crtc->x || set->y != set->crtc->y)
631 if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) {
632 DRM_DEBUG_KMS("modes are different, full mode set\n");
633 drm_mode_debug_printmodeline(&set->crtc->mode);
634 drm_mode_debug_printmodeline(set->mode);
638 /* a) traverse passed in connector list and get encoders for them */
640 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
641 struct drm_connector_helper_funcs *connector_funcs =
642 connector->helper_private;
643 new_encoder = connector->encoder;
644 for (ro = 0; ro < set->num_connectors; ro++) {
645 if (set->connectors[ro] == connector) {
646 new_encoder = connector_funcs->best_encoder(connector);
647 /* if we can't get an encoder for a connector
648 we are setting now - then fail */
649 if (new_encoder == NULL)
650 /* don't break so fail path works correct */
656 if (new_encoder != connector->encoder) {
657 DRM_DEBUG_KMS("encoder changed, full mode switch\n");
659 /* If the encoder is reused for another connector, then
660 * the appropriate crtc will be set later.
662 if (connector->encoder)
663 connector->encoder->crtc = NULL;
664 connector->encoder = new_encoder;
674 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
675 if (!connector->encoder)
678 if (connector->encoder->crtc == set->crtc)
681 new_crtc = connector->encoder->crtc;
683 for (ro = 0; ro < set->num_connectors; ro++) {
684 if (set->connectors[ro] == connector)
685 new_crtc = set->crtc;
688 /* Make sure the new CRTC will work with the encoder */
690 !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
694 if (new_crtc != connector->encoder->crtc) {
695 DRM_DEBUG_KMS("crtc changed, full mode switch\n");
697 connector->encoder->crtc = new_crtc;
700 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n",
701 connector->base.id, drm_get_connector_name(connector),
704 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
705 connector->base.id, drm_get_connector_name(connector));
709 /* mode_set_base is not a required function */
710 if (fb_changed && !crtc_funcs->mode_set_base)
714 set->crtc->enabled = drm_helper_crtc_in_use(set->crtc);
715 if (set->crtc->enabled) {
716 DRM_DEBUG_KMS("attempting to set mode from"
718 drm_mode_debug_printmodeline(set->mode);
719 old_fb = set->crtc->fb;
720 set->crtc->fb = set->fb;
721 if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
724 DRM_ERROR("failed to set mode on [CRTC:%d]\n",
726 set->crtc->fb = old_fb;
730 DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
731 for (i = 0; i < set->num_connectors; i++) {
732 DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id,
733 drm_get_connector_name(set->connectors[i]));
734 set->connectors[i]->dpms = DRM_MODE_DPMS_ON;
737 drm_helper_disable_unused_functions(dev);
738 } else if (fb_changed) {
739 set->crtc->x = set->x;
740 set->crtc->y = set->y;
742 old_fb = set->crtc->fb;
743 if (set->crtc->fb != set->fb)
744 set->crtc->fb = set->fb;
745 ret = crtc_funcs->mode_set_base(set->crtc,
746 set->x, set->y, old_fb);
748 set->crtc->fb = old_fb;
753 free(save_connectors, DRM_MEM_KMS);
754 free(save_encoders, DRM_MEM_KMS);
755 free(save_crtcs, DRM_MEM_KMS);
759 /* Restore all previous data. */
761 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
762 *crtc = save_crtcs[count++];
766 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
767 *encoder = save_encoders[count++];
771 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
772 *connector = save_connectors[count++];
775 /* Try to restore the config */
777 !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x,
778 save_set.y, save_set.fb))
779 DRM_ERROR("failed to restore config after modeset failure\n");
781 free(save_connectors, DRM_MEM_KMS);
782 free(save_encoders, DRM_MEM_KMS);
783 free(save_crtcs, DRM_MEM_KMS);
787 static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
789 int dpms = DRM_MODE_DPMS_OFF;
790 struct drm_connector *connector;
791 struct drm_device *dev = encoder->dev;
793 list_for_each_entry(connector, &dev->mode_config.connector_list, head)
794 if (connector->encoder == encoder)
795 if (connector->dpms < dpms)
796 dpms = connector->dpms;
800 static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
802 int dpms = DRM_MODE_DPMS_OFF;
803 struct drm_connector *connector;
804 struct drm_device *dev = crtc->dev;
806 list_for_each_entry(connector, &dev->mode_config.connector_list, head)
807 if (connector->encoder && connector->encoder->crtc == crtc)
808 if (connector->dpms < dpms)
809 dpms = connector->dpms;
814 * drm_helper_connector_dpms
815 * @connector affected connector
818 * Calls the low-level connector DPMS function, then
819 * calls appropriate encoder and crtc DPMS functions as well
821 void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
823 struct drm_encoder *encoder = connector->encoder;
824 struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
827 if (mode == connector->dpms)
830 old_dpms = connector->dpms;
831 connector->dpms = mode;
833 /* from off to on, do crtc then encoder */
834 if (mode < old_dpms) {
836 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
837 if (crtc_funcs->dpms)
838 (*crtc_funcs->dpms) (crtc,
839 drm_helper_choose_crtc_dpms(crtc));
842 struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
843 if (encoder_funcs->dpms)
844 (*encoder_funcs->dpms) (encoder,
845 drm_helper_choose_encoder_dpms(encoder));
849 /* from on to off, do encoder then crtc */
850 if (mode > old_dpms) {
852 struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
853 if (encoder_funcs->dpms)
854 (*encoder_funcs->dpms) (encoder,
855 drm_helper_choose_encoder_dpms(encoder));
858 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
859 if (crtc_funcs->dpms)
860 (*crtc_funcs->dpms) (crtc,
861 drm_helper_choose_crtc_dpms(crtc));
868 int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
869 struct drm_mode_fb_cmd2 *mode_cmd)
873 fb->width = mode_cmd->width;
874 fb->height = mode_cmd->height;
875 for (i = 0; i < 4; i++) {
876 fb->pitches[i] = mode_cmd->pitches[i];
877 fb->offsets[i] = mode_cmd->offsets[i];
879 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &fb->depth,
880 &fb->bits_per_pixel);
881 fb->pixel_format = mode_cmd->pixel_format;
886 int drm_helper_resume_force_mode(struct drm_device *dev)
888 struct drm_crtc *crtc;
889 struct drm_encoder *encoder;
890 struct drm_encoder_helper_funcs *encoder_funcs;
891 struct drm_crtc_helper_funcs *crtc_funcs;
894 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
899 ret = drm_crtc_helper_set_mode(crtc, &crtc->mode,
900 crtc->x, crtc->y, crtc->fb);
903 DRM_ERROR("failed to set mode on crtc %p\n", crtc);
905 /* Turn off outputs that were already powered off */
906 if (drm_helper_choose_crtc_dpms(crtc)) {
907 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
909 if(encoder->crtc != crtc)
912 encoder_funcs = encoder->helper_private;
913 if (encoder_funcs->dpms)
914 (*encoder_funcs->dpms) (encoder,
915 drm_helper_choose_encoder_dpms(encoder));
918 crtc_funcs = crtc->helper_private;
919 if (crtc_funcs->dpms)
920 (*crtc_funcs->dpms) (crtc,
921 drm_helper_choose_crtc_dpms(crtc));
924 /* disable the unused connectors while restoring the modesetting */
925 drm_helper_disable_unused_functions(dev);
929 #define DRM_OUTPUT_POLL_PERIOD (10 * hz)
930 static void output_poll_execute(void *ctx, int pending)
932 struct drm_device *dev;
933 struct drm_connector *connector;
934 enum drm_connector_status old_status;
935 bool repoll = false, changed = false;
937 if (!drm_kms_helper_poll)
942 lockmgr(&dev->mode_config.lock, LK_EXCLUSIVE);
943 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
945 /* if this is HPD or polled don't check it -
946 TV out for instance */
947 if (!connector->polled)
950 else if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
951 DRM_CONNECTOR_POLL_DISCONNECT))
954 old_status = connector->status;
955 /* if we are connected and don't want to poll for disconnect
957 if (old_status == connector_status_connected &&
958 !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT) &&
959 !(connector->polled & DRM_CONNECTOR_POLL_HPD))
962 connector->status = connector->funcs->detect(connector, false);
963 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
965 drm_get_connector_name(connector),
966 old_status, connector->status);
967 if (old_status != connector->status)
971 lockmgr(&dev->mode_config.lock, LK_RELEASE);
975 /* send a uevent + call fbdev */
976 drm_sysfs_hotplug_event(dev);
978 if (dev->mode_config.funcs->output_poll_changed)
979 dev->mode_config.funcs->output_poll_changed(dev);
983 taskqueue_enqueue_timeout(taskqueue_thread,
984 &dev->mode_config.output_poll_task,
985 DRM_OUTPUT_POLL_PERIOD);
989 void drm_kms_helper_poll_disable(struct drm_device *dev)
991 if (!dev->mode_config.poll_enabled)
993 taskqueue_cancel_timeout(taskqueue_thread,
994 &dev->mode_config.output_poll_task, NULL);
997 void drm_kms_helper_poll_enable(struct drm_device *dev)
1000 struct drm_connector *connector;
1002 if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
1005 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1006 if (connector->polled)
1011 taskqueue_enqueue_timeout(taskqueue_thread,
1012 &dev->mode_config.output_poll_task, DRM_OUTPUT_POLL_PERIOD);
1016 void drm_kms_helper_poll_init(struct drm_device *dev)
1019 TIMEOUT_TASK_INIT(taskqueue_thread, &dev->mode_config.output_poll_task,
1020 0, output_poll_execute, dev);
1021 dev->mode_config.poll_enabled = true;
1023 drm_kms_helper_poll_enable(dev);
1026 void drm_kms_helper_poll_fini(struct drm_device *dev)
1028 drm_kms_helper_poll_disable(dev);
1031 void drm_helper_hpd_irq_event(struct drm_device *dev)
1033 if (!dev->mode_config.poll_enabled)
1036 /* kill timer and schedule immediate execution, this doesn't block */
1037 taskqueue_cancel_timeout(taskqueue_thread,
1038 &dev->mode_config.output_poll_task, NULL);
1039 if (drm_kms_helper_poll)
1040 taskqueue_enqueue_timeout(taskqueue_thread,
1041 &dev->mode_config.output_poll_task, 0);