drm/i915: Update to Linux 4.1
[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
32 #include <linux/export.h>
33 #include <linux/moduleparam.h>
34
35 #include <drm/drmP.h>
36 #include <drm/drm_atomic.h>
37 #include <drm/drm_crtc.h>
38 #include <drm/drm_crtc_helper.h>
39 #include <drm/drm_fb_helper.h>
40 #include <drm/drm_plane_helper.h>
41 #include <drm/drm_atomic_helper.h>
42 #include <drm/drm_edid.h>
43
44 /**
45  * DOC: overview
46  *
47  * The CRTC modeset helper library provides a default set_config implementation
48  * in drm_crtc_helper_set_config(). Plus a few other convenience functions using
49  * the same callbacks which drivers can use to e.g. restore the modeset
50  * configuration on resume with drm_helper_resume_force_mode().
51  *
52  * The driver callbacks are mostly compatible with the atomic modeset helpers,
53  * except for the handling of the primary plane: Atomic helpers require that the
54  * primary plane is implemented as a real standalone plane and not directly tied
55  * to the CRTC state. For easier transition this library provides functions to
56  * implement the old semantics required by the CRTC helpers using the new plane
57  * and atomic helper callbacks.
58  *
59  * Drivers are strongly urged to convert to the atomic helpers (by way of first
60  * converting to the plane helpers). New drivers must not use these functions
61  * but need to implement the atomic interface instead, potentially using the
62  * atomic helpers for that.
63  */
64 MODULE_AUTHOR("David Airlie, Jesse Barnes");
65 MODULE_DESCRIPTION("DRM KMS helper");
66
67 /**
68  * drm_helper_move_panel_connectors_to_head() - move panels to the front in the
69  *                                              connector list
70  * @dev: drm device to operate on
71  *
72  * Some userspace presumes that the first connected connector is the main
73  * display, where it's supposed to display e.g. the login screen. For
74  * laptops, this should be the main panel. Use this function to sort all
75  * (eDP/LVDS) panels to the front of the connector list, instead of
76  * painstakingly trying to initialize them in the right order.
77  */
78 void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
79 {
80         struct drm_connector *connector, *tmp;
81         struct list_head panel_list;
82
83         INIT_LIST_HEAD(&panel_list);
84
85         list_for_each_entry_safe(connector, tmp,
86                                  &dev->mode_config.connector_list, head) {
87                 if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
88                     connector->connector_type == DRM_MODE_CONNECTOR_eDP)
89                         list_move_tail(&connector->head, &panel_list);
90         }
91
92         list_splice(&panel_list, &dev->mode_config.connector_list);
93 }
94 EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head);
95
96 /**
97  * drm_helper_encoder_in_use - check if a given encoder is in use
98  * @encoder: encoder to check
99  *
100  * Checks whether @encoder is with the current mode setting output configuration
101  * in use by any connector. This doesn't mean that it is actually enabled since
102  * the DPMS state is tracked separately.
103  *
104  * Returns:
105  * True if @encoder is used, false otherwise.
106  */
107 bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
108 {
109         struct drm_connector *connector;
110         struct drm_device *dev = encoder->dev;
111
112         WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
113         WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
114         list_for_each_entry(connector, &dev->mode_config.connector_list, head)
115                 if (connector->encoder == encoder)
116                         return true;
117         return false;
118 }
119 EXPORT_SYMBOL(drm_helper_encoder_in_use);
120
121 /**
122  * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config
123  * @crtc: CRTC to check
124  *
125  * Checks whether @crtc is with the current mode setting output configuration
126  * in use by any connector. This doesn't mean that it is actually enabled since
127  * the DPMS state is tracked separately.
128  *
129  * Returns:
130  * True if @crtc is used, false otherwise.
131  */
132 bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
133 {
134         struct drm_encoder *encoder;
135         struct drm_device *dev = crtc->dev;
136
137         WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
138         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
139                 if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder))
140                         return true;
141         return false;
142 }
143 EXPORT_SYMBOL(drm_helper_crtc_in_use);
144
145 static void
146 drm_encoder_disable(struct drm_encoder *encoder)
147 {
148         const struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
149
150         if (encoder->bridge)
151                 encoder->bridge->funcs->disable(encoder->bridge);
152
153         if (encoder_funcs->disable)
154                 (*encoder_funcs->disable)(encoder);
155         else
156                 (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
157
158         if (encoder->bridge)
159                 encoder->bridge->funcs->post_disable(encoder->bridge);
160 }
161
162 static void __drm_helper_disable_unused_functions(struct drm_device *dev)
163 {
164         struct drm_encoder *encoder;
165         struct drm_crtc *crtc;
166
167         drm_warn_on_modeset_not_all_locked(dev);
168
169         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
170                 if (!drm_helper_encoder_in_use(encoder)) {
171                         drm_encoder_disable(encoder);
172                         /* disconnect encoder from any connector */
173                         encoder->crtc = NULL;
174                 }
175         }
176
177         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
178                 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
179                 crtc->enabled = drm_helper_crtc_in_use(crtc);
180                 if (!crtc->enabled) {
181                         if (crtc_funcs->disable)
182                                 (*crtc_funcs->disable)(crtc);
183                         else
184                                 (*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
185                         crtc->primary->fb = NULL;
186                 }
187         }
188 }
189
190 /**
191  * drm_helper_disable_unused_functions - disable unused objects
192  * @dev: DRM device
193  *
194  * This function walks through the entire mode setting configuration of @dev. It
195  * will remove any crtc links of unused encoders and encoder links of
196  * disconnected connectors. Then it will disable all unused encoders and crtcs
197  * either by calling their disable callback if available or by calling their
198  * dpms callback with DRM_MODE_DPMS_OFF.
199  */
200 void drm_helper_disable_unused_functions(struct drm_device *dev)
201 {
202         drm_modeset_lock_all(dev);
203         __drm_helper_disable_unused_functions(dev);
204         drm_modeset_unlock_all(dev);
205 }
206 EXPORT_SYMBOL(drm_helper_disable_unused_functions);
207
208 /*
209  * Check the CRTC we're going to map each output to vs. its current
210  * CRTC.  If they don't match, we have to disable the output and the CRTC
211  * since the driver will have to re-route things.
212  */
213 static void
214 drm_crtc_prepare_encoders(struct drm_device *dev)
215 {
216         const struct drm_encoder_helper_funcs *encoder_funcs;
217         struct drm_encoder *encoder;
218
219         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
220                 encoder_funcs = encoder->helper_private;
221                 /* Disable unused encoders */
222                 if (encoder->crtc == NULL)
223                         drm_encoder_disable(encoder);
224                 /* Disable encoders whose CRTC is about to change */
225                 if (encoder_funcs->get_crtc &&
226                     encoder->crtc != (*encoder_funcs->get_crtc)(encoder))
227                         drm_encoder_disable(encoder);
228         }
229 }
230
231 /**
232  * drm_crtc_helper_set_mode - internal helper to set a mode
233  * @crtc: CRTC to program
234  * @mode: mode to use
235  * @x: horizontal offset into the surface
236  * @y: vertical offset into the surface
237  * @old_fb: old framebuffer, for cleanup
238  *
239  * Try to set @mode on @crtc.  Give @crtc and its associated connectors a chance
240  * to fixup or reject the mode prior to trying to set it. This is an internal
241  * helper that drivers could e.g. use to update properties that require the
242  * entire output pipe to be disabled and re-enabled in a new configuration. For
243  * example for changing whether audio is enabled on a hdmi link or for changing
244  * panel fitter or dither attributes. It is also called by the
245  * drm_crtc_helper_set_config() helper function to drive the mode setting
246  * sequence.
247  *
248  * Returns:
249  * True if the mode was set successfully, false otherwise.
250  */
251 bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
252                               struct drm_display_mode *mode,
253                               int x, int y,
254                               struct drm_framebuffer *old_fb)
255 {
256         struct drm_device *dev = crtc->dev;
257         struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
258         const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
259         const struct drm_encoder_helper_funcs *encoder_funcs;
260         int saved_x, saved_y;
261         bool saved_enabled;
262         struct drm_encoder *encoder;
263         bool ret = true;
264
265         drm_warn_on_modeset_not_all_locked(dev);
266
267         saved_enabled = crtc->enabled;
268         crtc->enabled = drm_helper_crtc_in_use(crtc);
269         if (!crtc->enabled)
270                 return true;
271
272         adjusted_mode = drm_mode_duplicate(dev, mode);
273         if (!adjusted_mode) {
274                 crtc->enabled = saved_enabled;
275                 return false;
276         }
277
278         saved_mode = crtc->mode;
279         saved_hwmode = crtc->hwmode;
280         saved_x = crtc->x;
281         saved_y = crtc->y;
282
283         /* Update crtc values up front so the driver can rely on them for mode
284          * setting.
285          */
286         crtc->mode = *mode;
287         crtc->x = x;
288         crtc->y = y;
289
290         /* Pass our mode to the connectors and the CRTC to give them a chance to
291          * adjust it according to limitations or connector properties, and also
292          * a chance to reject the mode entirely.
293          */
294         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
295
296                 if (encoder->crtc != crtc)
297                         continue;
298
299                 if (encoder->bridge && encoder->bridge->funcs->mode_fixup) {
300                         ret = encoder->bridge->funcs->mode_fixup(
301                                         encoder->bridge, mode, adjusted_mode);
302                         if (!ret) {
303                                 DRM_DEBUG_KMS("Bridge fixup failed\n");
304                                 goto done;
305                         }
306                 }
307
308                 encoder_funcs = encoder->helper_private;
309                 if (!(ret = encoder_funcs->mode_fixup(encoder, mode,
310                                                       adjusted_mode))) {
311                         DRM_DEBUG_KMS("Encoder fixup failed\n");
312                         goto done;
313                 }
314         }
315
316         if (!(ret = crtc_funcs->mode_fixup(crtc, mode, adjusted_mode))) {
317                 DRM_DEBUG_KMS("CRTC fixup failed\n");
318                 goto done;
319         }
320         DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
321
322         crtc->hwmode = *adjusted_mode;
323
324         /* Prepare the encoders and CRTCs before setting the mode. */
325         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
326
327                 if (encoder->crtc != crtc)
328                         continue;
329
330                 if (encoder->bridge)
331                         encoder->bridge->funcs->disable(encoder->bridge);
332
333                 encoder_funcs = encoder->helper_private;
334                 /* Disable the encoders as the first thing we do. */
335                 encoder_funcs->prepare(encoder);
336
337                 if (encoder->bridge)
338                         encoder->bridge->funcs->post_disable(encoder->bridge);
339         }
340
341         drm_crtc_prepare_encoders(dev);
342
343         crtc_funcs->prepare(crtc);
344
345         /* Set up the DPLL and any encoders state that needs to adjust or depend
346          * on the DPLL.
347          */
348         ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
349         if (!ret)
350             goto done;
351
352         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
353
354                 if (encoder->crtc != crtc)
355                         continue;
356
357                 DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n",
358                         encoder->base.id, encoder->name,
359                         mode->base.id, mode->name);
360                 encoder_funcs = encoder->helper_private;
361                 encoder_funcs->mode_set(encoder, mode, adjusted_mode);
362
363                 if (encoder->bridge && encoder->bridge->funcs->mode_set)
364                         encoder->bridge->funcs->mode_set(encoder->bridge, mode,
365                                         adjusted_mode);
366         }
367
368         /* Now enable the clocks, plane, pipe, and connectors that we set up. */
369         crtc_funcs->commit(crtc);
370
371         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
372
373                 if (encoder->crtc != crtc)
374                         continue;
375
376                 if (encoder->bridge)
377                         encoder->bridge->funcs->pre_enable(encoder->bridge);
378
379                 encoder_funcs = encoder->helper_private;
380                 encoder_funcs->commit(encoder);
381
382                 if (encoder->bridge)
383                         encoder->bridge->funcs->enable(encoder->bridge);
384         }
385
386         /* Calculate and store various constants which
387          * are later needed by vblank and swap-completion
388          * timestamping. They are derived from true hwmode.
389          */
390         drm_calc_timestamping_constants(crtc, &crtc->hwmode);
391
392         /* FIXME: add subpixel order */
393 done:
394         drm_mode_destroy(dev, adjusted_mode);
395         if (!ret) {
396                 crtc->enabled = saved_enabled;
397                 crtc->mode = saved_mode;
398                 crtc->hwmode = saved_hwmode;
399                 crtc->x = saved_x;
400                 crtc->y = saved_y;
401         }
402
403         return ret;
404 }
405 EXPORT_SYMBOL(drm_crtc_helper_set_mode);
406
407 static void
408 drm_crtc_helper_disable(struct drm_crtc *crtc)
409 {
410         struct drm_device *dev = crtc->dev;
411         struct drm_connector *connector;
412         struct drm_encoder *encoder;
413
414         /* Decouple all encoders and their attached connectors from this crtc */
415         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
416                 if (encoder->crtc != crtc)
417                         continue;
418
419                 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
420                         if (connector->encoder != encoder)
421                                 continue;
422
423                         connector->encoder = NULL;
424
425                         /*
426                          * drm_helper_disable_unused_functions() ought to be
427                          * doing this, but since we've decoupled the encoder
428                          * from the connector above, the required connection
429                          * between them is henceforth no longer available.
430                          */
431                         connector->dpms = DRM_MODE_DPMS_OFF;
432                 }
433         }
434
435         __drm_helper_disable_unused_functions(dev);
436 }
437
438 /**
439  * drm_crtc_helper_set_config - set a new config from userspace
440  * @set: mode set configuration
441  *
442  * Setup a new configuration, provided by the upper layers (either an ioctl call
443  * from userspace or internally e.g. from the fbdev support code) in @set, and
444  * enable it. This is the main helper functions for drivers that implement
445  * kernel mode setting with the crtc helper functions and the assorted
446  * ->prepare(), ->modeset() and ->commit() helper callbacks.
447  *
448  * Returns:
449  * Returns 0 on success, negative errno numbers on failure.
450  */
451 int drm_crtc_helper_set_config(struct drm_mode_set *set)
452 {
453         struct drm_device *dev;
454         struct drm_crtc *new_crtc;
455         struct drm_encoder *save_encoders, *new_encoder, *encoder;
456         bool mode_changed = false; /* if true do a full mode set */
457         bool fb_changed = false; /* if true and !mode_changed just do a flip */
458         struct drm_connector *save_connectors, *connector;
459         int count = 0, ro, fail = 0;
460         const struct drm_crtc_helper_funcs *crtc_funcs;
461         struct drm_mode_set save_set;
462         int ret;
463         int i;
464
465         DRM_DEBUG_KMS("\n");
466
467         BUG_ON(!set);
468         BUG_ON(!set->crtc);
469         BUG_ON(!set->crtc->helper_private);
470
471         /* Enforce sane interface api - has been abused by the fb helper. */
472         BUG_ON(!set->mode && set->fb);
473         BUG_ON(set->fb && set->num_connectors == 0);
474
475         crtc_funcs = set->crtc->helper_private;
476
477         if (!set->mode)
478                 set->fb = NULL;
479
480         if (set->fb) {
481                 DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n",
482                                 set->crtc->base.id, set->fb->base.id,
483                                 (int)set->num_connectors, set->x, set->y);
484         } else {
485                 DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id);
486                 drm_crtc_helper_disable(set->crtc);
487                 return 0;
488         }
489
490         dev = set->crtc->dev;
491
492         drm_warn_on_modeset_not_all_locked(dev);
493
494         /*
495          * Allocate space for the backup of all (non-pointer) encoder and
496          * connector data.
497          */
498         save_encoders = kzalloc(dev->mode_config.num_encoder *
499                                 sizeof(struct drm_encoder), GFP_KERNEL);
500         if (!save_encoders)
501                 return -ENOMEM;
502
503         save_connectors = kzalloc(dev->mode_config.num_connector *
504                                 sizeof(struct drm_connector), GFP_KERNEL);
505         if (!save_connectors) {
506                 kfree(save_encoders);
507                 return -ENOMEM;
508         }
509
510         /*
511          * Copy data. Note that driver private data is not affected.
512          * Should anything bad happen only the expected state is
513          * restored, not the drivers personal bookkeeping.
514          */
515         count = 0;
516         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
517                 save_encoders[count++] = *encoder;
518         }
519
520         count = 0;
521         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
522                 save_connectors[count++] = *connector;
523         }
524
525         save_set.crtc = set->crtc;
526         save_set.mode = &set->crtc->mode;
527         save_set.x = set->crtc->x;
528         save_set.y = set->crtc->y;
529         save_set.fb = set->crtc->primary->fb;
530
531         /* We should be able to check here if the fb has the same properties
532          * and then just flip_or_move it */
533         if (set->crtc->primary->fb != set->fb) {
534                 /* If we have no fb then treat it as a full mode set */
535                 if (set->crtc->primary->fb == NULL) {
536                         DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
537                         mode_changed = true;
538                 } else if (set->fb == NULL) {
539                         mode_changed = true;
540                 } else if (set->fb->pixel_format !=
541                            set->crtc->primary->fb->pixel_format) {
542                         mode_changed = true;
543                 } else
544                         fb_changed = true;
545         }
546
547         if (set->x != set->crtc->x || set->y != set->crtc->y)
548                 fb_changed = true;
549
550         if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) {
551                 DRM_DEBUG_KMS("modes are different, full mode set\n");
552                 drm_mode_debug_printmodeline(&set->crtc->mode);
553                 drm_mode_debug_printmodeline(set->mode);
554                 mode_changed = true;
555         }
556
557         /* a) traverse passed in connector list and get encoders for them */
558         count = 0;
559         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
560                 const struct drm_connector_helper_funcs *connector_funcs =
561                         connector->helper_private;
562                 new_encoder = connector->encoder;
563                 for (ro = 0; ro < set->num_connectors; ro++) {
564                         if (set->connectors[ro] == connector) {
565                                 new_encoder = connector_funcs->best_encoder(connector);
566                                 /* if we can't get an encoder for a connector
567                                    we are setting now - then fail */
568                                 if (new_encoder == NULL)
569                                         /* don't break so fail path works correct */
570                                         fail = 1;
571
572                                 if (connector->dpms != DRM_MODE_DPMS_ON) {
573                                         DRM_DEBUG_KMS("connector dpms not on, full mode switch\n");
574                                         mode_changed = true;
575                                 }
576
577                                 break;
578                         }
579                 }
580
581                 if (new_encoder != connector->encoder) {
582                         DRM_DEBUG_KMS("encoder changed, full mode switch\n");
583                         mode_changed = true;
584                         /* If the encoder is reused for another connector, then
585                          * the appropriate crtc will be set later.
586                          */
587                         if (connector->encoder)
588                                 connector->encoder->crtc = NULL;
589                         connector->encoder = new_encoder;
590                 }
591         }
592
593         if (fail) {
594                 ret = -EINVAL;
595                 goto fail;
596         }
597
598         count = 0;
599         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
600                 if (!connector->encoder)
601                         continue;
602
603                 if (connector->encoder->crtc == set->crtc)
604                         new_crtc = NULL;
605                 else
606                         new_crtc = connector->encoder->crtc;
607
608                 for (ro = 0; ro < set->num_connectors; ro++) {
609                         if (set->connectors[ro] == connector)
610                                 new_crtc = set->crtc;
611                 }
612
613                 /* Make sure the new CRTC will work with the encoder */
614                 if (new_crtc &&
615                     !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
616                         ret = -EINVAL;
617                         goto fail;
618                 }
619                 if (new_crtc != connector->encoder->crtc) {
620                         DRM_DEBUG_KMS("crtc changed, full mode switch\n");
621                         mode_changed = true;
622                         connector->encoder->crtc = new_crtc;
623                 }
624                 if (new_crtc) {
625                         DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n",
626                                 connector->base.id, connector->name,
627                                 new_crtc->base.id);
628                 } else {
629                         DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
630                                 connector->base.id, connector->name);
631                 }
632         }
633
634         /* mode_set_base is not a required function */
635         if (fb_changed && !crtc_funcs->mode_set_base)
636                 mode_changed = true;
637
638         if (mode_changed) {
639                 if (drm_helper_crtc_in_use(set->crtc)) {
640                         DRM_DEBUG_KMS("attempting to set mode from"
641                                         " userspace\n");
642                         drm_mode_debug_printmodeline(set->mode);
643                         set->crtc->primary->fb = set->fb;
644                         if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
645                                                       set->x, set->y,
646                                                       save_set.fb)) {
647                                 DRM_ERROR("failed to set mode on [CRTC:%d]\n",
648                                           set->crtc->base.id);
649                                 set->crtc->primary->fb = save_set.fb;
650                                 ret = -EINVAL;
651                                 goto fail;
652                         }
653                         DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
654                         for (i = 0; i < set->num_connectors; i++) {
655                                 DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id,
656                                               set->connectors[i]->name);
657                                 set->connectors[i]->funcs->dpms(set->connectors[i], DRM_MODE_DPMS_ON);
658                         }
659                 }
660                 __drm_helper_disable_unused_functions(dev);
661         } else if (fb_changed) {
662                 set->crtc->x = set->x;
663                 set->crtc->y = set->y;
664                 set->crtc->primary->fb = set->fb;
665                 ret = crtc_funcs->mode_set_base(set->crtc,
666                                                 set->x, set->y, save_set.fb);
667                 if (ret != 0) {
668                         set->crtc->x = save_set.x;
669                         set->crtc->y = save_set.y;
670                         set->crtc->primary->fb = save_set.fb;
671                         goto fail;
672                 }
673         }
674
675         kfree(save_connectors);
676         kfree(save_encoders);
677         return 0;
678
679 fail:
680         /* Restore all previous data. */
681         count = 0;
682         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
683                 *encoder = save_encoders[count++];
684         }
685
686         count = 0;
687         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
688                 *connector = save_connectors[count++];
689         }
690
691         /* Try to restore the config */
692         if (mode_changed &&
693             !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x,
694                                       save_set.y, save_set.fb))
695                 DRM_ERROR("failed to restore config after modeset failure\n");
696
697         kfree(save_connectors);
698         kfree(save_encoders);
699         return ret;
700 }
701 EXPORT_SYMBOL(drm_crtc_helper_set_config);
702
703 static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
704 {
705         int dpms = DRM_MODE_DPMS_OFF;
706         struct drm_connector *connector;
707         struct drm_device *dev = encoder->dev;
708
709         list_for_each_entry(connector, &dev->mode_config.connector_list, head)
710                 if (connector->encoder == encoder)
711                         if (connector->dpms < dpms)
712                                 dpms = connector->dpms;
713         return dpms;
714 }
715
716 /* Helper which handles bridge ordering around encoder dpms */
717 static void drm_helper_encoder_dpms(struct drm_encoder *encoder, int mode)
718 {
719         struct drm_bridge *bridge = encoder->bridge;
720         const struct drm_encoder_helper_funcs *encoder_funcs;
721
722         if (bridge) {
723                 if (mode == DRM_MODE_DPMS_ON)
724                         bridge->funcs->pre_enable(bridge);
725                 else
726                         bridge->funcs->disable(bridge);
727         }
728
729         encoder_funcs = encoder->helper_private;
730         if (encoder_funcs->dpms)
731                 encoder_funcs->dpms(encoder, mode);
732
733         if (bridge) {
734                 if (mode == DRM_MODE_DPMS_ON)
735                         bridge->funcs->enable(bridge);
736                 else
737                         bridge->funcs->post_disable(bridge);
738         }
739 }
740
741 static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
742 {
743         int dpms = DRM_MODE_DPMS_OFF;
744         struct drm_connector *connector;
745         struct drm_device *dev = crtc->dev;
746
747         list_for_each_entry(connector, &dev->mode_config.connector_list, head)
748                 if (connector->encoder && connector->encoder->crtc == crtc)
749                         if (connector->dpms < dpms)
750                                 dpms = connector->dpms;
751         return dpms;
752 }
753
754 /**
755  * drm_helper_connector_dpms() - connector dpms helper implementation
756  * @connector: affected connector
757  * @mode: DPMS mode
758  *
759  * This is the main helper function provided by the crtc helper framework for
760  * implementing the DPMS connector attribute. It computes the new desired DPMS
761  * state for all encoders and crtcs in the output mesh and calls the ->dpms()
762  * callback provided by the driver appropriately.
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, encoder_dpms = DRM_MODE_DPMS_OFF;
769
770         if (mode == connector->dpms)
771                 return;
772
773         old_dpms = connector->dpms;
774         connector->dpms = mode;
775
776         if (encoder)
777                 encoder_dpms = drm_helper_choose_encoder_dpms(encoder);
778
779         /* from off to on, do crtc then encoder */
780         if (mode < old_dpms) {
781                 if (crtc) {
782                         const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
783                         if (crtc_funcs->dpms)
784                                 (*crtc_funcs->dpms) (crtc,
785                                                      drm_helper_choose_crtc_dpms(crtc));
786                 }
787                 if (encoder)
788                         drm_helper_encoder_dpms(encoder, encoder_dpms);
789         }
790
791         /* from on to off, do encoder then crtc */
792         if (mode > old_dpms) {
793                 if (encoder)
794                         drm_helper_encoder_dpms(encoder, encoder_dpms);
795                 if (crtc) {
796                         const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
797                         if (crtc_funcs->dpms)
798                                 (*crtc_funcs->dpms) (crtc,
799                                                      drm_helper_choose_crtc_dpms(crtc));
800                 }
801         }
802
803         return;
804 }
805 EXPORT_SYMBOL(drm_helper_connector_dpms);
806
807 /**
808  * drm_helper_mode_fill_fb_struct - fill out framebuffer metadata
809  * @fb: drm_framebuffer object to fill out
810  * @mode_cmd: metadata from the userspace fb creation request
811  *
812  * This helper can be used in a drivers fb_create callback to pre-fill the fb's
813  * metadata fields.
814  */
815 void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
816                                     struct drm_mode_fb_cmd2 *mode_cmd)
817 {
818         int i;
819
820         fb->width = mode_cmd->width;
821         fb->height = mode_cmd->height;
822         for (i = 0; i < 4; i++) {
823                 fb->pitches[i] = mode_cmd->pitches[i];
824                 fb->offsets[i] = mode_cmd->offsets[i];
825                 fb->modifier[i] = mode_cmd->modifier[i];
826         }
827         drm_fb_get_bpp_depth(mode_cmd->pixel_format, &fb->depth,
828                                     &fb->bits_per_pixel);
829         fb->pixel_format = mode_cmd->pixel_format;
830         fb->flags = mode_cmd->flags;
831 }
832 EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct);
833
834 /**
835  * drm_helper_resume_force_mode - force-restore mode setting configuration
836  * @dev: drm_device which should be restored
837  *
838  * Drivers which use the mode setting helpers can use this function to
839  * force-restore the mode setting configuration e.g. on resume or when something
840  * else might have trampled over the hw state (like some overzealous old BIOSen
841  * tended to do).
842  *
843  * This helper doesn't provide a error return value since restoring the old
844  * config should never fail due to resource allocation issues since the driver
845  * has successfully set the restored configuration already. Hence this should
846  * boil down to the equivalent of a few dpms on calls, which also don't provide
847  * an error code.
848  *
849  * Drivers where simply restoring an old configuration again might fail (e.g.
850  * due to slight differences in allocating shared resources when the
851  * configuration is restored in a different order than when userspace set it up)
852  * need to use their own restore logic.
853  */
854 void drm_helper_resume_force_mode(struct drm_device *dev)
855 {
856         struct drm_crtc *crtc;
857         struct drm_encoder *encoder;
858         const struct drm_crtc_helper_funcs *crtc_funcs;
859         int encoder_dpms;
860         bool ret;
861
862         drm_modeset_lock_all(dev);
863         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
864
865                 if (!crtc->enabled)
866                         continue;
867
868                 ret = drm_crtc_helper_set_mode(crtc, &crtc->mode,
869                                                crtc->x, crtc->y, crtc->primary->fb);
870
871                 /* Restoring the old config should never fail! */
872                 if (ret == false)
873                         DRM_ERROR("failed to set mode on crtc %p\n", crtc);
874
875                 /* Turn off outputs that were already powered off */
876                 if (drm_helper_choose_crtc_dpms(crtc)) {
877                         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
878
879                                 if(encoder->crtc != crtc)
880                                         continue;
881
882                                 encoder_dpms = drm_helper_choose_encoder_dpms(
883                                                         encoder);
884
885                                 drm_helper_encoder_dpms(encoder, encoder_dpms);
886                         }
887
888                         crtc_funcs = crtc->helper_private;
889                         if (crtc_funcs->dpms)
890                                 (*crtc_funcs->dpms) (crtc,
891                                                      drm_helper_choose_crtc_dpms(crtc));
892                 }
893         }
894
895         /* disable the unused connectors while restoring the modesetting */
896         __drm_helper_disable_unused_functions(dev);
897         drm_modeset_unlock_all(dev);
898 }
899 EXPORT_SYMBOL(drm_helper_resume_force_mode);
900
901 /**
902  * drm_helper_crtc_mode_set - mode_set implementation for atomic plane helpers
903  * @crtc: DRM CRTC
904  * @mode: DRM display mode which userspace requested
905  * @adjusted_mode: DRM display mode adjusted by ->mode_fixup callbacks
906  * @x: x offset of the CRTC scanout area on the underlying framebuffer
907  * @y: y offset of the CRTC scanout area on the underlying framebuffer
908  * @old_fb: previous framebuffer
909  *
910  * This function implements a callback useable as the ->mode_set callback
911  * required by the crtc helpers. Besides the atomic plane helper functions for
912  * the primary plane the driver must also provide the ->mode_set_nofb callback
913  * to set up the crtc.
914  *
915  * This is a transitional helper useful for converting drivers to the atomic
916  * interfaces.
917  */
918 int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
919                              struct drm_display_mode *adjusted_mode, int x, int y,
920                              struct drm_framebuffer *old_fb)
921 {
922         struct drm_crtc_state *crtc_state;
923         const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
924         int ret;
925
926         if (crtc->funcs->atomic_duplicate_state)
927                 crtc_state = crtc->funcs->atomic_duplicate_state(crtc);
928         else if (crtc->state)
929                 crtc_state = kmemdup(crtc->state, sizeof(*crtc_state),
930                                      GFP_KERNEL);
931         else
932                 crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
933         if (!crtc_state)
934                 return -ENOMEM;
935         crtc_state->crtc = crtc;
936
937         crtc_state->enable = true;
938         crtc_state->planes_changed = true;
939         crtc_state->mode_changed = true;
940         drm_mode_copy(&crtc_state->mode, mode);
941         drm_mode_copy(&crtc_state->adjusted_mode, adjusted_mode);
942
943         if (crtc_funcs->atomic_check) {
944                 ret = crtc_funcs->atomic_check(crtc, crtc_state);
945                 if (ret) {
946                         kfree(crtc_state);
947
948                         return ret;
949                 }
950         }
951
952         swap(crtc->state, crtc_state);
953
954         crtc_funcs->mode_set_nofb(crtc);
955
956         if (crtc_state) {
957                 if (crtc->funcs->atomic_destroy_state)
958                         crtc->funcs->atomic_destroy_state(crtc, crtc_state);
959                 else
960                         kfree(crtc_state);
961         }
962
963         return drm_helper_crtc_mode_set_base(crtc, x, y, old_fb);
964 }
965 EXPORT_SYMBOL(drm_helper_crtc_mode_set);
966
967 /**
968  * drm_helper_crtc_mode_set_base - mode_set_base implementation for atomic plane helpers
969  * @crtc: DRM CRTC
970  * @x: x offset of the CRTC scanout area on the underlying framebuffer
971  * @y: y offset of the CRTC scanout area on the underlying framebuffer
972  * @old_fb: previous framebuffer
973  *
974  * This function implements a callback useable as the ->mode_set_base used
975  * required by the crtc helpers. The driver must provide the atomic plane helper
976  * functions for the primary plane.
977  *
978  * This is a transitional helper useful for converting drivers to the atomic
979  * interfaces.
980  */
981 int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
982                                   struct drm_framebuffer *old_fb)
983 {
984         struct drm_plane_state *plane_state;
985         struct drm_plane *plane = crtc->primary;
986
987         if (plane->funcs->atomic_duplicate_state)
988                 plane_state = plane->funcs->atomic_duplicate_state(plane);
989         else if (plane->state)
990                 plane_state = drm_atomic_helper_plane_duplicate_state(plane);
991         else
992                 plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL);
993         if (!plane_state)
994                 return -ENOMEM;
995         plane_state->plane = plane;
996
997         plane_state->crtc = crtc;
998         drm_atomic_set_fb_for_plane(plane_state, crtc->primary->fb);
999         plane_state->crtc_x = 0;
1000         plane_state->crtc_y = 0;
1001         plane_state->crtc_h = crtc->mode.vdisplay;
1002         plane_state->crtc_w = crtc->mode.hdisplay;
1003         plane_state->src_x = x << 16;
1004         plane_state->src_y = y << 16;
1005         plane_state->src_h = crtc->mode.vdisplay << 16;
1006         plane_state->src_w = crtc->mode.hdisplay << 16;
1007
1008         return drm_plane_helper_commit(plane, plane_state, old_fb);
1009 }
1010 EXPORT_SYMBOL(drm_helper_crtc_mode_set_base);