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