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