drm: Reduce differences with Linux 3.8
[dragonfly.git] / sys / dev / 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  * $FreeBSD: src/sys/dev/drm2/drm_crtc_helper.c,v 1.1 2012/05/22 11:07:44 kib Exp $
32  */
33
34 #include <linux/export.h>
35
36 #include <drm/drmP.h>
37 #include <drm/drm_crtc.h>
38 #include <uapi_drm/drm_fourcc.h>
39 #include <drm/drm_crtc_helper.h>
40 #include <drm/drm_fb_helper.h>
41 #include <drm/drm_edid.h>
42
43 bool
44 drm_fetch_cmdline_mode_from_kenv(struct drm_connector *connector,
45     struct drm_cmdline_mode *cmdline_mode)
46 {
47         char *tun_var_name, *tun_mode;
48         static const char tun_prefix[] = "drm_mode.";
49         bool res;
50
51         res = false;
52         tun_var_name = kmalloc(sizeof(tun_prefix) +
53             strlen(drm_get_connector_name(connector)), M_TEMP, M_WAITOK);
54         strcpy(tun_var_name, tun_prefix);
55         strcat(tun_var_name, drm_get_connector_name(connector));
56         tun_mode = kgetenv(tun_var_name);
57         if (tun_mode != NULL) {
58                 res = drm_mode_parse_command_line_for_connector(tun_mode,
59                     connector, cmdline_mode);
60                 kfreeenv(tun_mode);
61         }
62         drm_free(tun_var_name, M_TEMP);
63         return (res);
64 }
65
66 /**
67  * drm_helper_move_panel_connectors_to_head() - move panels to the front in the
68  *                                              connector list
69  * @dev: drm device to operate on
70  *
71  * Some userspace presumes that the first connected connector is the main
72  * display, where it's supposed to display e.g. the login screen. For
73  * laptops, this should be the main panel. Use this function to sort all
74  * (eDP/LVDS) panels to the front of the connector list, instead of
75  * painstakingly trying to initialize them in the right order.
76  */
77 void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
78 {
79         struct drm_connector *connector, *tmp;
80         struct list_head panel_list;
81
82         INIT_LIST_HEAD(&panel_list);
83
84         list_for_each_entry_safe(connector, tmp,
85                                  &dev->mode_config.connector_list, head) {
86                 if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
87                     connector->connector_type == DRM_MODE_CONNECTOR_eDP)
88                         list_move_tail(&connector->head, &panel_list);
89         }
90
91         list_splice(&panel_list, &dev->mode_config.connector_list);
92 }
93 EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head);
94
95 static bool drm_kms_helper_poll = true;
96
97 static void drm_mode_validate_flag(struct drm_connector *connector,
98                                    int flags)
99 {
100         struct drm_display_mode *mode;
101
102         if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE))
103                 return;
104
105         list_for_each_entry(mode, &connector->modes, head) {
106                 if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
107                                 !(flags & DRM_MODE_FLAG_INTERLACE))
108                         mode->status = MODE_NO_INTERLACE;
109                 if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
110                                 !(flags & DRM_MODE_FLAG_DBLSCAN))
111                         mode->status = MODE_NO_DBLESCAN;
112         }
113
114         return;
115 }
116
117 /**
118  * drm_helper_probe_single_connector_modes - get complete set of display modes
119  * @connector: connector to probe
120  * @maxX: max width for modes
121  * @maxY: max height for modes
122  *
123  * LOCKING:
124  * Caller must hold mode config lock.
125  *
126  * Based on the helper callbacks implemented by @connector try to detect all
127  * valid modes.  Modes will first be added to the connector's probed_modes list,
128  * then culled (based on validity and the @maxX, @maxY parameters) and put into
129  * the normal modes list.
130  *
131  * Intended to be use as a generic implementation of the ->probe() @connector
132  * callback for drivers that use the crtc helpers for output mode filtering and
133  * detection.
134  *
135  * RETURNS:
136  * Number of modes found on @connector.
137  */
138 int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
139                                             uint32_t maxX, uint32_t maxY)
140 {
141         struct drm_device *dev = connector->dev;
142         struct drm_display_mode *mode;
143         struct drm_connector_helper_funcs *connector_funcs =
144                 connector->helper_private;
145         int count = 0;
146         int mode_flags = 0;
147
148         DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
149                         drm_get_connector_name(connector));
150         /* set all modes to the unverified state */
151         list_for_each_entry(mode, &connector->modes, head)
152                 mode->status = MODE_UNVERIFIED;
153
154         if (connector->force) {
155                 if (connector->force == DRM_FORCE_ON)
156                         connector->status = connector_status_connected;
157                 else
158                         connector->status = connector_status_disconnected;
159                 if (connector->funcs->force)
160                         connector->funcs->force(connector);
161         } else {
162                 connector->status = connector->funcs->detect(connector, true);
163         }
164
165         /* Re-enable polling in case the global poll config changed. */
166         if (drm_kms_helper_poll != dev->mode_config.poll_running)
167                 drm_kms_helper_poll_enable(dev);
168
169         dev->mode_config.poll_running = drm_kms_helper_poll;
170
171         if (connector->status == connector_status_disconnected) {
172                 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
173                         connector->base.id, drm_get_connector_name(connector));
174                 drm_mode_connector_update_edid_property(connector, NULL);
175                 goto prune;
176         }
177
178 #ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
179         count = drm_load_edid_firmware(connector);
180         if (count == 0)
181 #endif
182                 count = (*connector_funcs->get_modes)(connector);
183
184         if (count == 0 && connector->status == connector_status_connected)
185                 count = drm_add_modes_noedid(connector, 1024, 768);
186         if (count == 0)
187                 goto prune;
188
189         drm_mode_connector_list_update(connector);
190
191         if (maxX && maxY)
192                 drm_mode_validate_size(dev, &connector->modes, maxX,
193                                        maxY, 0);
194
195         if (connector->interlace_allowed)
196                 mode_flags |= DRM_MODE_FLAG_INTERLACE;
197         if (connector->doublescan_allowed)
198                 mode_flags |= DRM_MODE_FLAG_DBLSCAN;
199         drm_mode_validate_flag(connector, mode_flags);
200
201         list_for_each_entry(mode, &connector->modes, head) {
202                 if (mode->status == MODE_OK)
203                         mode->status = connector_funcs->mode_valid(connector,
204                                                                    mode);
205         }
206
207 prune:
208         drm_mode_prune_invalid(dev, &connector->modes, true);
209
210         if (list_empty(&connector->modes))
211                 return 0;
212
213         drm_mode_sort(&connector->modes);
214
215         DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
216                         drm_get_connector_name(connector));
217         list_for_each_entry(mode, &connector->modes, head) {
218                 mode->vrefresh = drm_mode_vrefresh(mode);
219
220                 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
221                 drm_mode_debug_printmodeline(mode);
222         }
223
224         return count;
225 }
226 EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
227
228 /**
229  * drm_helper_encoder_in_use - check if a given encoder is in use
230  * @encoder: encoder to check
231  *
232  * LOCKING:
233  * Caller must hold mode config lock.
234  *
235  * Walk @encoders's DRM device's mode_config and see if it's in use.
236  *
237  * RETURNS:
238  * True if @encoder is part of the mode_config, false otherwise.
239  */
240 bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
241 {
242         struct drm_connector *connector;
243         struct drm_device *dev = encoder->dev;
244         list_for_each_entry(connector, &dev->mode_config.connector_list, head)
245                 if (connector->encoder == encoder)
246                         return true;
247         return false;
248 }
249 EXPORT_SYMBOL(drm_helper_encoder_in_use);
250
251 /**
252  * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config
253  * @crtc: CRTC to check
254  *
255  * LOCKING:
256  * Caller must hold mode config lock.
257  *
258  * Walk @crtc's DRM device's mode_config and see if it's in use.
259  *
260  * RETURNS:
261  * True if @crtc is part of the mode_config, false otherwise.
262  */
263 bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
264 {
265         struct drm_encoder *encoder;
266         struct drm_device *dev = crtc->dev;
267         /* FIXME: Locking around list access? */
268         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
269                 if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder))
270                         return true;
271         return false;
272 }
273 EXPORT_SYMBOL(drm_helper_crtc_in_use);
274
275 static void
276 drm_encoder_disable(struct drm_encoder *encoder)
277 {
278         struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
279
280         if (encoder_funcs->disable)
281                 (*encoder_funcs->disable)(encoder);
282         else
283                 (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
284 }
285
286 /**
287  * drm_helper_disable_unused_functions - disable unused objects
288  * @dev: DRM device
289  *
290  * LOCKING:
291  * Caller must hold mode config lock.
292  *
293  * If an connector or CRTC isn't part of @dev's mode_config, it can be disabled
294  * by calling its dpms function, which should power it off.
295  */
296 void drm_helper_disable_unused_functions(struct drm_device *dev)
297 {
298         struct drm_encoder *encoder;
299         struct drm_connector *connector;
300         struct drm_crtc *crtc;
301
302         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
303                 if (!connector->encoder)
304                         continue;
305                 if (connector->status == connector_status_disconnected)
306                         connector->encoder = NULL;
307         }
308
309         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
310                 if (!drm_helper_encoder_in_use(encoder)) {
311                         drm_encoder_disable(encoder);
312                         /* disconnector encoder from any connector */
313                         encoder->crtc = NULL;
314                 }
315         }
316
317         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
318                 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
319                 crtc->enabled = drm_helper_crtc_in_use(crtc);
320                 if (!crtc->enabled) {
321                         if (crtc_funcs->disable)
322                                 (*crtc_funcs->disable)(crtc);
323                         else
324                                 (*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
325                         crtc->fb = NULL;
326                 }
327         }
328 }
329 EXPORT_SYMBOL(drm_helper_disable_unused_functions);
330
331 /**
332  * drm_encoder_crtc_ok - can a given crtc drive a given encoder?
333  * @encoder: encoder to test
334  * @crtc: crtc to test
335  *
336  * Return false if @encoder can't be driven by @crtc, true otherwise.
337  */
338 static bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
339                                 struct drm_crtc *crtc)
340 {
341         struct drm_device *dev;
342         struct drm_crtc *tmp;
343         int crtc_mask = 1;
344
345         WARN(!crtc, "checking null crtc?\n");
346
347         dev = crtc->dev;
348
349         list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) {
350                 if (tmp == crtc)
351                         break;
352                 crtc_mask <<= 1;
353         }
354
355         if (encoder->possible_crtcs & crtc_mask)
356                 return true;
357         return false;
358 }
359
360 /*
361  * Check the CRTC we're going to map each output to vs. its current
362  * CRTC.  If they don't match, we have to disable the output and the CRTC
363  * since the driver will have to re-route things.
364  */
365 static void
366 drm_crtc_prepare_encoders(struct drm_device *dev)
367 {
368         struct drm_encoder_helper_funcs *encoder_funcs;
369         struct drm_encoder *encoder;
370
371         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
372                 encoder_funcs = encoder->helper_private;
373                 /* Disable unused encoders */
374                 if (encoder->crtc == NULL)
375                         drm_encoder_disable(encoder);
376                 /* Disable encoders whose CRTC is about to change */
377                 if (encoder_funcs->get_crtc &&
378                     encoder->crtc != (*encoder_funcs->get_crtc)(encoder))
379                         drm_encoder_disable(encoder);
380         }
381 }
382
383 /**
384  * drm_crtc_helper_set_mode - internal helper to set a mode
385  * @crtc: CRTC to program
386  * @mode: mode to use
387  * @x: horizontal offset into the surface
388  * @y: vertical offset into the surface
389  * @old_fb: old framebuffer, for cleanup
390  *
391  * LOCKING:
392  * Caller must hold mode config lock.
393  *
394  * Try to set @mode on @crtc.  Give @crtc and its associated connectors a chance
395  * to fixup or reject the mode prior to trying to set it. This is an internal
396  * helper that drivers could e.g. use to update properties that require the
397  * entire output pipe to be disabled and re-enabled in a new configuration. For
398  * example for changing whether audio is enabled on a hdmi link or for changing
399  * panel fitter or dither attributes. It is also called by the
400  * drm_crtc_helper_set_config() helper function to drive the mode setting
401  * sequence.
402  *
403  * RETURNS:
404  * True if the mode was set successfully, or false otherwise.
405  */
406 bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
407                               struct drm_display_mode *mode,
408                               int x, int y,
409                               struct drm_framebuffer *old_fb)
410 {
411         struct drm_device *dev = crtc->dev;
412         struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
413         struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
414         struct drm_encoder_helper_funcs *encoder_funcs;
415         int saved_x, saved_y;
416         struct drm_encoder *encoder;
417         bool ret = true;
418
419         crtc->enabled = drm_helper_crtc_in_use(crtc);
420         if (!crtc->enabled)
421                 return true;
422
423         adjusted_mode = drm_mode_duplicate(dev, mode);
424         if (!adjusted_mode)
425                 return false;
426
427         saved_hwmode = crtc->hwmode;
428         saved_mode = crtc->mode;
429         saved_x = crtc->x;
430         saved_y = crtc->y;
431
432         /* Update crtc values up front so the driver can rely on them for mode
433          * setting.
434          */
435         crtc->mode = *mode;
436         crtc->x = x;
437         crtc->y = y;
438
439         /* Pass our mode to the connectors and the CRTC to give them a chance to
440          * adjust it according to limitations or connector properties, and also
441          * a chance to reject the mode entirely.
442          */
443         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
444
445                 if (encoder->crtc != crtc)
446                         continue;
447                 encoder_funcs = encoder->helper_private;
448                 if (!(ret = encoder_funcs->mode_fixup(encoder, mode,
449                                                       adjusted_mode))) {
450                         DRM_DEBUG_KMS("Encoder fixup failed\n");
451                         goto done;
452                 }
453         }
454
455         if (!(ret = crtc_funcs->mode_fixup(crtc, mode, adjusted_mode))) {
456                 DRM_DEBUG_KMS("CRTC fixup failed\n");
457                 goto done;
458         }
459         DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
460
461         /* Prepare the encoders and CRTCs before setting the mode. */
462         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
463
464                 if (encoder->crtc != crtc)
465                         continue;
466                 encoder_funcs = encoder->helper_private;
467                 /* Disable the encoders as the first thing we do. */
468                 encoder_funcs->prepare(encoder);
469         }
470
471         drm_crtc_prepare_encoders(dev);
472
473         crtc_funcs->prepare(crtc);
474
475         /* Set up the DPLL and any encoders state that needs to adjust or depend
476          * on the DPLL.
477          */
478         ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
479         if (!ret)
480             goto done;
481
482         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
483
484                 if (encoder->crtc != crtc)
485                         continue;
486
487                 DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n",
488                         encoder->base.id, drm_get_encoder_name(encoder),
489                         mode->base.id, mode->name);
490                 encoder_funcs = encoder->helper_private;
491                 encoder_funcs->mode_set(encoder, mode, adjusted_mode);
492         }
493
494         /* Now enable the clocks, plane, pipe, and connectors that we set up. */
495         crtc_funcs->commit(crtc);
496
497         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
498
499                 if (encoder->crtc != crtc)
500                         continue;
501
502                 encoder_funcs = encoder->helper_private;
503                 encoder_funcs->commit(encoder);
504
505         }
506
507         /* Store real post-adjustment hardware mode. */
508         crtc->hwmode = *adjusted_mode;
509
510         /* Calculate and store various constants which
511          * are later needed by vblank and swap-completion
512          * timestamping. They are derived from true hwmode.
513          */
514         drm_calc_timestamping_constants(crtc);
515
516         /* FIXME: add subpixel order */
517 done:
518         drm_mode_destroy(dev, adjusted_mode);
519         if (!ret) {
520                 crtc->hwmode = saved_hwmode;
521                 crtc->mode = saved_mode;
522                 crtc->x = saved_x;
523                 crtc->y = saved_y;
524         }
525
526         return ret;
527 }
528 EXPORT_SYMBOL(drm_crtc_helper_set_mode);
529
530
531 static int
532 drm_crtc_helper_disable(struct drm_crtc *crtc)
533 {
534         struct drm_device *dev = crtc->dev;
535         struct drm_connector *connector;
536         struct drm_encoder *encoder;
537
538         /* Decouple all encoders and their attached connectors from this crtc */
539         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
540                 if (encoder->crtc != crtc)
541                         continue;
542
543                 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
544                         if (connector->encoder != encoder)
545                                 continue;
546
547                         connector->encoder = NULL;
548                 }
549         }
550
551         drm_helper_disable_unused_functions(dev);
552         return 0;
553 }
554
555 /**
556  * drm_crtc_helper_set_config - set a new config from userspace
557  * @set: mode set configuration
558  *
559  * LOCKING:
560  * Caller must hold mode config lock.
561  *
562  * Setup a new configuration, provided by the upper layers (either an ioctl call
563  * from userspace or internally e.g. from the fbdev suppport code) in @set, and
564  * enable it. This is the main helper functions for drivers that implement
565  * kernel mode setting with the crtc helper functions and the assorted
566  * ->prepare(), ->modeset() and ->commit() helper callbacks.
567  *
568  * RETURNS:
569  * Returns 0 on success, -ERRNO on failure.
570  */
571 int drm_crtc_helper_set_config(struct drm_mode_set *set)
572 {
573         struct drm_device *dev;
574         struct drm_crtc *save_crtcs, *new_crtc, *crtc;
575         struct drm_encoder *save_encoders, *new_encoder, *encoder;
576         struct drm_framebuffer *old_fb = NULL;
577         bool mode_changed = false; /* if true do a full mode set */
578         bool fb_changed = false; /* if true and !mode_changed just do a flip */
579         struct drm_connector *save_connectors, *connector;
580         int count = 0, ro, fail = 0;
581         struct drm_crtc_helper_funcs *crtc_funcs;
582         struct drm_mode_set save_set;
583         int ret;
584         int i;
585
586         DRM_DEBUG_KMS("\n");
587
588         if (!set)
589                 return -EINVAL;
590
591         if (!set->crtc)
592                 return -EINVAL;
593
594         if (!set->crtc->helper_private)
595                 return -EINVAL;
596
597         crtc_funcs = set->crtc->helper_private;
598
599         if (!set->mode)
600                 set->fb = NULL;
601
602         if (set->fb) {
603                 DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n",
604                                 set->crtc->base.id, set->fb->base.id,
605                                 (int)set->num_connectors, set->x, set->y);
606         } else {
607                 DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id);
608                 return drm_crtc_helper_disable(set->crtc);
609         }
610
611         dev = set->crtc->dev;
612
613         /* Allocate space for the backup of all (non-pointer) crtc, encoder and
614          * connector data. */
615         save_crtcs = kmalloc(dev->mode_config.num_crtc * sizeof(struct drm_crtc),
616             DRM_MEM_KMS, M_WAITOK | M_ZERO);
617         save_encoders = kmalloc(dev->mode_config.num_encoder *
618             sizeof(struct drm_encoder), DRM_MEM_KMS, M_WAITOK | M_ZERO);
619         save_connectors = kmalloc(dev->mode_config.num_connector *
620             sizeof(struct drm_connector), DRM_MEM_KMS, M_WAITOK | M_ZERO);
621
622         /* Copy data. Note that driver private data is not affected.
623          * Should anything bad happen only the expected state is
624          * restored, not the drivers personal bookkeeping.
625          */
626         count = 0;
627         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
628                 save_crtcs[count++] = *crtc;
629         }
630
631         count = 0;
632         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
633                 save_encoders[count++] = *encoder;
634         }
635
636         count = 0;
637         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
638                 save_connectors[count++] = *connector;
639         }
640
641         save_set.crtc = set->crtc;
642         save_set.mode = &set->crtc->mode;
643         save_set.x = set->crtc->x;
644         save_set.y = set->crtc->y;
645         save_set.fb = set->crtc->fb;
646
647         /* We should be able to check here if the fb has the same properties
648          * and then just flip_or_move it */
649         if (set->crtc->fb != set->fb) {
650                 /* If we have no fb then treat it as a full mode set */
651                 if (set->crtc->fb == NULL) {
652                         DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
653                         mode_changed = true;
654                 } else if (set->fb == NULL) {
655                         mode_changed = true;
656                 } else if (set->fb->depth != set->crtc->fb->depth) {
657                         mode_changed = true;
658                 } else if (set->fb->bits_per_pixel !=
659                            set->crtc->fb->bits_per_pixel) {
660                         mode_changed = true;
661                 } else
662                         fb_changed = true;
663         }
664
665         if (set->x != set->crtc->x || set->y != set->crtc->y)
666                 fb_changed = true;
667
668         if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) {
669                 DRM_DEBUG_KMS("modes are different, full mode set\n");
670                 drm_mode_debug_printmodeline(&set->crtc->mode);
671                 drm_mode_debug_printmodeline(set->mode);
672                 mode_changed = true;
673         }
674
675         /* a) traverse passed in connector list and get encoders for them */
676         count = 0;
677         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
678                 struct drm_connector_helper_funcs *connector_funcs =
679                         connector->helper_private;
680                 new_encoder = connector->encoder;
681                 for (ro = 0; ro < set->num_connectors; ro++) {
682                         if (set->connectors[ro] == connector) {
683                                 new_encoder = connector_funcs->best_encoder(connector);
684                                 /* if we can't get an encoder for a connector
685                                    we are setting now - then fail */
686                                 if (new_encoder == NULL)
687                                         /* don't break so fail path works correct */
688                                         fail = 1;
689                                 break;
690                         }
691                 }
692
693                 if (new_encoder != connector->encoder) {
694                         DRM_DEBUG_KMS("encoder changed, full mode switch\n");
695                         mode_changed = true;
696                         /* If the encoder is reused for another connector, then
697                          * the appropriate crtc will be set later.
698                          */
699                         if (connector->encoder)
700                                 connector->encoder->crtc = NULL;
701                         connector->encoder = new_encoder;
702                 }
703         }
704
705         if (fail) {
706                 ret = -EINVAL;
707                 goto fail;
708         }
709
710         count = 0;
711         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
712                 if (!connector->encoder)
713                         continue;
714
715                 if (connector->encoder->crtc == set->crtc)
716                         new_crtc = NULL;
717                 else
718                         new_crtc = connector->encoder->crtc;
719
720                 for (ro = 0; ro < set->num_connectors; ro++) {
721                         if (set->connectors[ro] == connector)
722                                 new_crtc = set->crtc;
723                 }
724
725                 /* Make sure the new CRTC will work with the encoder */
726                 if (new_crtc &&
727                     !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
728                         ret = -EINVAL;
729                         goto fail;
730                 }
731                 if (new_crtc != connector->encoder->crtc) {
732                         DRM_DEBUG_KMS("crtc changed, full mode switch\n");
733                         mode_changed = true;
734                         connector->encoder->crtc = new_crtc;
735                 }
736                 if (new_crtc) {
737                         DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n",
738                                 connector->base.id, drm_get_connector_name(connector),
739                                 new_crtc->base.id);
740                 } else {
741                         DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
742                                 connector->base.id, drm_get_connector_name(connector));
743                 }
744         }
745
746         /* mode_set_base is not a required function */
747         if (fb_changed && !crtc_funcs->mode_set_base)
748                 mode_changed = true;
749
750         if (mode_changed) {
751                 set->crtc->enabled = drm_helper_crtc_in_use(set->crtc);
752                 if (set->crtc->enabled) {
753                         DRM_DEBUG_KMS("attempting to set mode from"
754                                         " userspace\n");
755                         drm_mode_debug_printmodeline(set->mode);
756                         old_fb = set->crtc->fb;
757                         set->crtc->fb = set->fb;
758                         if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
759                                                       set->x, set->y,
760                                                       old_fb)) {
761                                 DRM_ERROR("failed to set mode on [CRTC:%d]\n",
762                                           set->crtc->base.id);
763                                 set->crtc->fb = old_fb;
764                                 ret = -EINVAL;
765                                 goto fail;
766                         }
767                         DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
768                         for (i = 0; i < set->num_connectors; i++) {
769                                 DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id,
770                                               drm_get_connector_name(set->connectors[i]));
771                                 set->connectors[i]->funcs->dpms(set->connectors[i], DRM_MODE_DPMS_ON);
772                         }
773                 }
774                 drm_helper_disable_unused_functions(dev);
775         } else if (fb_changed) {
776                 set->crtc->x = set->x;
777                 set->crtc->y = set->y;
778
779                 old_fb = set->crtc->fb;
780                 if (set->crtc->fb != set->fb)
781                         set->crtc->fb = set->fb;
782                 ret = crtc_funcs->mode_set_base(set->crtc,
783                                                 set->x, set->y, old_fb);
784                 if (ret != 0) {
785                         set->crtc->fb = old_fb;
786                         goto fail;
787                 }
788         }
789
790         kfree(save_connectors, DRM_MEM_KMS);
791         kfree(save_encoders, DRM_MEM_KMS);
792         kfree(save_crtcs, DRM_MEM_KMS);
793         return 0;
794
795 fail:
796         /* Restore all previous data. */
797         count = 0;
798         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
799                 *crtc = save_crtcs[count++];
800         }
801
802         count = 0;
803         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
804                 *encoder = save_encoders[count++];
805         }
806
807         count = 0;
808         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
809                 *connector = save_connectors[count++];
810         }
811
812         /* Try to restore the config */
813         if (mode_changed &&
814             !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x,
815                                       save_set.y, save_set.fb))
816                 DRM_ERROR("failed to restore config after modeset failure\n");
817
818         drm_free(save_connectors, DRM_MEM_KMS);
819         drm_free(save_encoders, DRM_MEM_KMS);
820         drm_free(save_crtcs, DRM_MEM_KMS);
821         return ret;
822 }
823 EXPORT_SYMBOL(drm_crtc_helper_set_config);
824
825 static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
826 {
827         int dpms = DRM_MODE_DPMS_OFF;
828         struct drm_connector *connector;
829         struct drm_device *dev = encoder->dev;
830
831         list_for_each_entry(connector, &dev->mode_config.connector_list, head)
832                 if (connector->encoder == encoder)
833                         if (connector->dpms < dpms)
834                                 dpms = connector->dpms;
835         return dpms;
836 }
837
838 static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
839 {
840         int dpms = DRM_MODE_DPMS_OFF;
841         struct drm_connector *connector;
842         struct drm_device *dev = crtc->dev;
843
844         list_for_each_entry(connector, &dev->mode_config.connector_list, head)
845                 if (connector->encoder && connector->encoder->crtc == crtc)
846                         if (connector->dpms < dpms)
847                                 dpms = connector->dpms;
848         return dpms;
849 }
850
851 /**
852  * drm_helper_connector_dpms() - connector dpms helper implementation
853  * @connector: affected connector
854  * @mode: DPMS mode
855  *
856  * This is the main helper function provided by the crtc helper framework for
857  * implementing the DPMS connector attribute. It computes the new desired DPMS
858  * state for all encoders and crtcs in the output mesh and calls the ->dpms()
859  * callback provided by the driver appropriately.
860  */
861 void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
862 {
863         struct drm_encoder *encoder = connector->encoder;
864         struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
865         int old_dpms;
866
867         if (mode == connector->dpms)
868                 return;
869
870         old_dpms = connector->dpms;
871         connector->dpms = mode;
872
873         /* from off to on, do crtc then encoder */
874         if (mode < old_dpms) {
875                 if (crtc) {
876                         struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
877                         if (crtc_funcs->dpms)
878                                 (*crtc_funcs->dpms) (crtc,
879                                                      drm_helper_choose_crtc_dpms(crtc));
880                 }
881                 if (encoder) {
882                         struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
883                         if (encoder_funcs->dpms)
884                                 (*encoder_funcs->dpms) (encoder,
885                                                         drm_helper_choose_encoder_dpms(encoder));
886                 }
887         }
888
889         /* from on to off, do encoder then crtc */
890         if (mode > old_dpms) {
891                 if (encoder) {
892                         struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
893                         if (encoder_funcs->dpms)
894                                 (*encoder_funcs->dpms) (encoder,
895                                                         drm_helper_choose_encoder_dpms(encoder));
896                 }
897                 if (crtc) {
898                         struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
899                         if (crtc_funcs->dpms)
900                                 (*crtc_funcs->dpms) (crtc,
901                                                      drm_helper_choose_crtc_dpms(crtc));
902                 }
903         }
904
905         return;
906 }
907 EXPORT_SYMBOL(drm_helper_connector_dpms);
908
909 int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
910                                    struct drm_mode_fb_cmd2 *mode_cmd)
911 {
912         int i;
913
914         fb->width = mode_cmd->width;
915         fb->height = mode_cmd->height;
916         for (i = 0; i < 4; i++) {
917                 fb->pitches[i] = mode_cmd->pitches[i];
918                 fb->offsets[i] = mode_cmd->offsets[i];
919         }
920         drm_fb_get_bpp_depth(mode_cmd->pixel_format, &fb->depth,
921                                     &fb->bits_per_pixel);
922         fb->pixel_format = mode_cmd->pixel_format;
923
924         return 0;
925 }
926 EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct);
927
928 int drm_helper_resume_force_mode(struct drm_device *dev)
929 {
930         struct drm_crtc *crtc;
931         struct drm_encoder *encoder;
932         struct drm_encoder_helper_funcs *encoder_funcs;
933         struct drm_crtc_helper_funcs *crtc_funcs;
934         int ret;
935
936         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
937
938                 if (!crtc->enabled)
939                         continue;
940
941                 ret = drm_crtc_helper_set_mode(crtc, &crtc->mode,
942                                                crtc->x, crtc->y, crtc->fb);
943
944                 if (ret == false)
945                         DRM_ERROR("failed to set mode on crtc %p\n", crtc);
946
947                 /* Turn off outputs that were already powered off */
948                 if (drm_helper_choose_crtc_dpms(crtc)) {
949                         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
950
951                                 if(encoder->crtc != crtc)
952                                         continue;
953
954                                 encoder_funcs = encoder->helper_private;
955                                 if (encoder_funcs->dpms)
956                                         (*encoder_funcs->dpms) (encoder,
957                                                                 drm_helper_choose_encoder_dpms(encoder));
958                         }
959
960                         crtc_funcs = crtc->helper_private;
961                         if (crtc_funcs->dpms)
962                                 (*crtc_funcs->dpms) (crtc,
963                                                      drm_helper_choose_crtc_dpms(crtc));
964                 }
965         }
966         /* disable the unused connectors while restoring the modesetting */
967         drm_helper_disable_unused_functions(dev);
968         return 0;
969 }
970 EXPORT_SYMBOL(drm_helper_resume_force_mode);
971
972 void drm_kms_helper_hotplug_event(struct drm_device *dev)
973 {
974 #if 0
975         /* send a uevent + call fbdev */
976         drm_sysfs_hotplug_event(dev);
977         if (dev->mode_config.funcs->output_poll_changed)
978                 dev->mode_config.funcs->output_poll_changed(dev);
979 #endif
980 }
981 EXPORT_SYMBOL(drm_kms_helper_hotplug_event);
982
983 #define DRM_OUTPUT_POLL_PERIOD (10 * hz)
984 static void output_poll_execute(void *ctx, int pending)
985 {
986         struct drm_device *dev;
987         struct drm_connector *connector;
988         enum drm_connector_status old_status;
989         bool repoll = false, changed = false;
990
991         if (!drm_kms_helper_poll)
992                 return;
993
994         dev = ctx;
995
996         lockmgr(&dev->mode_config.mutex, LK_EXCLUSIVE);
997         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
998
999                 /* Ignore forced connectors. */
1000                 if (connector->force)
1001                         continue;
1002
1003                 /* Ignore HPD capable connectors and connectors where we don't
1004                  * want any hotplug detection at all for polling. */
1005                 if (!connector->polled || connector->polled == DRM_CONNECTOR_POLL_HPD)
1006                         continue;
1007
1008                 repoll = true;
1009
1010                 old_status = connector->status;
1011                 /* if we are connected and don't want to poll for disconnect
1012                    skip it */
1013                 if (old_status == connector_status_connected &&
1014                     !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT))
1015                         continue;
1016
1017                 connector->status = connector->funcs->detect(connector, false);
1018                 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
1019                               connector->base.id,
1020                               drm_get_connector_name(connector),
1021                               old_status, connector->status);
1022                 if (old_status != connector->status)
1023                         changed = true;
1024         }
1025
1026         lockmgr(&dev->mode_config.mutex, LK_RELEASE);
1027
1028         if (changed)
1029                 drm_kms_helper_hotplug_event(dev);
1030
1031         if (repoll) {
1032                 taskqueue_enqueue_timeout(taskqueue_thread[mycpuid],
1033                     &dev->mode_config.output_poll_task,
1034                     DRM_OUTPUT_POLL_PERIOD);
1035         }
1036 }
1037
1038 void drm_kms_helper_poll_disable(struct drm_device *dev)
1039 {
1040         if (!dev->mode_config.poll_enabled)
1041                 return;
1042         taskqueue_cancel_timeout(taskqueue_thread[mycpuid],
1043             &dev->mode_config.output_poll_task, NULL);
1044 }
1045 EXPORT_SYMBOL(drm_kms_helper_poll_disable);
1046
1047 void drm_kms_helper_poll_enable(struct drm_device *dev)
1048 {
1049         bool poll = false;
1050         struct drm_connector *connector;
1051
1052         if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
1053                 return;
1054
1055         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1056                 if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
1057                                          DRM_CONNECTOR_POLL_DISCONNECT))
1058                         poll = true;
1059         }
1060
1061         if (poll) {
1062                 taskqueue_enqueue_timeout(taskqueue_thread[mycpuid],
1063                     &dev->mode_config.output_poll_task, DRM_OUTPUT_POLL_PERIOD);
1064         }
1065 }
1066 EXPORT_SYMBOL(drm_kms_helper_poll_enable);
1067
1068 void drm_kms_helper_poll_init(struct drm_device *dev)
1069 {
1070         TIMEOUT_TASK_INIT(taskqueue_thread[mycpuid], &dev->mode_config.output_poll_task,
1071             0, output_poll_execute, dev);
1072         dev->mode_config.poll_enabled = true;
1073
1074         drm_kms_helper_poll_enable(dev);
1075 }
1076 EXPORT_SYMBOL(drm_kms_helper_poll_init);
1077
1078 void drm_kms_helper_poll_fini(struct drm_device *dev)
1079 {
1080         drm_kms_helper_poll_disable(dev);
1081 }
1082 EXPORT_SYMBOL(drm_kms_helper_poll_fini);
1083
1084 void drm_helper_hpd_irq_event(struct drm_device *dev)
1085 {
1086         struct drm_connector *connector;
1087         enum drm_connector_status old_status;
1088         bool changed = false;
1089
1090         if (!dev->mode_config.poll_enabled)
1091                 return;
1092
1093         lockmgr(&dev->mode_config.mutex, LK_EXCLUSIVE);
1094         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1095
1096                 /* Only handle HPD capable connectors. */
1097                 if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))
1098                         continue;
1099
1100                 old_status = connector->status;
1101
1102                 connector->status = connector->funcs->detect(connector, false);
1103                 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
1104                               connector->base.id,
1105                               drm_get_connector_name(connector),
1106                               old_status, connector->status);
1107                 if (old_status != connector->status)
1108                         changed = true;
1109         }
1110
1111         lockmgr(&dev->mode_config.mutex, LK_RELEASE);
1112
1113         if (changed)
1114                 drm_kms_helper_hotplug_event(dev);
1115 }
1116 EXPORT_SYMBOL(drm_helper_hpd_irq_event);