blob: 79b3d521c3885e4f13ea7153d742e8343a0ea4e7 [file] [log] [blame]
Dave Airlief453ba02008-11-07 14:05:41 -08001/*
2 * Copyright (c) 2006-2008 Intel Corporation
3 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
4 * Copyright (c) 2008 Red Hat Inc.
5 *
6 * DRM core CRTC related functions
7 *
8 * Permission to use, copy, modify, distribute, and sell this software and its
9 * documentation for any purpose is hereby granted without fee, provided that
10 * the above copyright notice appear in all copies and that both that copyright
11 * notice and this permission notice appear in supporting documentation, and
12 * that the name of the copyright holders not be used in advertising or
13 * publicity pertaining to distribution of the software without specific,
14 * written prior permission. The copyright holders make no representations
15 * about the suitability of this software for any purpose. It is provided "as
16 * is" without express or implied warranty.
17 *
18 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
20 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
21 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
23 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24 * OF THIS SOFTWARE.
25 *
26 * Authors:
27 * Keith Packard
28 * Eric Anholt <eric@anholt.net>
29 * Dave Airlie <airlied@linux.ie>
30 * Jesse Barnes <jesse.barnes@intel.com>
31 */
Ville Syrjälä6ba6d032013-06-10 11:15:10 +030032#include <linux/ctype.h>
Dave Airlief453ba02008-11-07 14:05:41 -080033#include <linux/list.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090034#include <linux/slab.h>
Paul Gortmaker2d1a8a42011-08-30 18:16:33 -040035#include <linux/export.h>
Gustavo Padovan2a380152016-11-15 23:37:08 +090036#include <linux/fence.h>
David Howells760285e2012-10-02 18:01:07 +010037#include <drm/drmP.h>
38#include <drm/drm_crtc.h>
39#include <drm/drm_edid.h>
40#include <drm/drm_fourcc.h>
Rob Clark51fd3712013-11-19 12:10:12 -050041#include <drm/drm_modeset_lock.h>
Rob Clark88a48e22014-12-18 16:01:50 -050042#include <drm/drm_atomic.h>
Daniel Vetter3b96a0b2016-06-21 10:54:22 +020043#include <drm/drm_auth.h>
Daniel Vetter7520a272016-08-15 16:07:02 +020044#include <drm/drm_framebuffer.h>
Dave Airlief453ba02008-11-07 14:05:41 -080045
Daniel Vetter8bd441b2014-01-23 15:35:24 +010046#include "drm_crtc_internal.h"
Daniel Vetter67d0ec42014-09-10 12:43:53 +020047#include "drm_internal.h"
Daniel Vetter8bd441b2014-01-23 15:35:24 +010048
Dave Airlief453ba02008-11-07 14:05:41 -080049/*
50 * Global properties
51 */
Thierry Reding4dfd9092014-12-10 13:03:34 +010052static const struct drm_prop_enum_list drm_plane_type_enum_list[] = {
Rob Clark9922ab52014-04-01 20:16:57 -040053 { DRM_PLANE_TYPE_OVERLAY, "Overlay" },
54 { DRM_PLANE_TYPE_PRIMARY, "Primary" },
55 { DRM_PLANE_TYPE_CURSOR, "Cursor" },
56};
57
Daniel Vetter52217192016-08-12 22:48:50 +020058/*
59 * Optional properties
Daniel Vetterc8e32cc2014-03-10 21:33:02 +010060 */
Lukas Wunner6a0d9522016-06-08 18:47:27 +020061/**
62 * drm_crtc_force_disable - Forcibly turn off a CRTC
63 * @crtc: CRTC to turn off
64 *
65 * Returns:
66 * Zero on success, error code on failure.
67 */
68int drm_crtc_force_disable(struct drm_crtc *crtc)
69{
70 struct drm_mode_set set = {
71 .crtc = crtc,
72 };
73
74 return drm_mode_set_config_internal(&set);
75}
76EXPORT_SYMBOL(drm_crtc_force_disable);
77
78/**
79 * drm_crtc_force_disable_all - Forcibly turn off all enabled CRTCs
80 * @dev: DRM device whose CRTCs to turn off
81 *
82 * Drivers may want to call this on unload to ensure that all displays are
83 * unlit and the GPU is in a consistent, low power state. Takes modeset locks.
84 *
85 * Returns:
86 * Zero on success, error code on failure.
87 */
88int drm_crtc_force_disable_all(struct drm_device *dev)
89{
90 struct drm_crtc *crtc;
91 int ret = 0;
92
93 drm_modeset_lock_all(dev);
94 drm_for_each_crtc(crtc, dev)
95 if (crtc->enabled) {
96 ret = drm_crtc_force_disable(crtc);
97 if (ret)
98 goto out;
99 }
100out:
101 drm_modeset_unlock_all(dev);
102 return ret;
103}
104EXPORT_SYMBOL(drm_crtc_force_disable_all);
105
Rob Clark51fd3712013-11-19 12:10:12 -0500106DEFINE_WW_CLASS(crtc_ww_class);
107
Ville Syrjäläfa3ab4c2015-12-08 18:41:53 +0200108static unsigned int drm_num_crtcs(struct drm_device *dev)
109{
110 unsigned int num = 0;
111 struct drm_crtc *tmp;
112
113 drm_for_each_crtc(tmp, dev) {
114 num++;
115 }
116
117 return num;
118}
119
Benjamin Gaignard79190ea2016-06-21 16:37:09 +0200120static int drm_crtc_register_all(struct drm_device *dev)
121{
122 struct drm_crtc *crtc;
123 int ret = 0;
124
125 drm_for_each_crtc(crtc, dev) {
126 if (crtc->funcs->late_register)
127 ret = crtc->funcs->late_register(crtc);
128 if (ret)
129 return ret;
130 }
131
132 return 0;
133}
134
135static void drm_crtc_unregister_all(struct drm_device *dev)
136{
137 struct drm_crtc *crtc;
138
139 drm_for_each_crtc(crtc, dev) {
140 if (crtc->funcs->early_unregister)
141 crtc->funcs->early_unregister(crtc);
142 }
143}
144
Gustavo Padovan34e0b7d2016-12-06 15:47:17 -0200145static const struct fence_ops drm_crtc_fence_ops;
146
Gustavo Padovan2a380152016-11-15 23:37:08 +0900147static struct drm_crtc *fence_to_crtc(struct fence *fence)
148{
149 BUG_ON(fence->ops != &drm_crtc_fence_ops);
150 return container_of(fence->lock, struct drm_crtc, fence_lock);
151}
152
153static const char *drm_crtc_fence_get_driver_name(struct fence *fence)
154{
155 struct drm_crtc *crtc = fence_to_crtc(fence);
156
157 return crtc->dev->driver->name;
158}
159
160static const char *drm_crtc_fence_get_timeline_name(struct fence *fence)
161{
162 struct drm_crtc *crtc = fence_to_crtc(fence);
163
164 return crtc->timeline_name;
165}
166
167static bool drm_crtc_fence_enable_signaling(struct fence *fence)
168{
169 return true;
170}
171
Gustavo Padovan34e0b7d2016-12-06 15:47:17 -0200172static const struct fence_ops drm_crtc_fence_ops = {
Gustavo Padovan2a380152016-11-15 23:37:08 +0900173 .get_driver_name = drm_crtc_fence_get_driver_name,
174 .get_timeline_name = drm_crtc_fence_get_timeline_name,
175 .enable_signaling = drm_crtc_fence_enable_signaling,
176 .wait = fence_default_wait,
177};
178
Gustavo Padovan34e0b7d2016-12-06 15:47:17 -0200179struct fence *drm_crtc_create_fence(struct drm_crtc *crtc)
180{
181 struct fence *fence;
182
183 fence = kzalloc(sizeof(*fence), GFP_KERNEL);
184 if (!fence)
185 return NULL;
186
187 fence_init(fence, &drm_crtc_fence_ops, &crtc->fence_lock,
188 crtc->fence_context, ++crtc->fence_seqno);
189
190 return fence;
191}
192
Dave Airlief453ba02008-11-07 14:05:41 -0800193/**
Matt Ropere13161a2014-04-01 15:22:38 -0700194 * drm_crtc_init_with_planes - Initialise a new CRTC object with
195 * specified primary and cursor planes.
Dave Airlief453ba02008-11-07 14:05:41 -0800196 * @dev: DRM device
197 * @crtc: CRTC object to init
Matt Ropere13161a2014-04-01 15:22:38 -0700198 * @primary: Primary plane for CRTC
199 * @cursor: Cursor plane for CRTC
Dave Airlief453ba02008-11-07 14:05:41 -0800200 * @funcs: callbacks for the new CRTC
Ville Syrjäläf9882872015-12-09 16:19:31 +0200201 * @name: printf style format string for the CRTC name, or NULL for default name
Dave Airlief453ba02008-11-07 14:05:41 -0800202 *
Daniel Vetter532b3672016-09-21 10:59:25 +0200203 * Inits a new object created as base part of a driver crtc object. Drivers
204 * should use this function instead of drm_crtc_init(), which is only provided
205 * for backwards compatibility with drivers which do not yet support universal
206 * planes). For really simple hardware which has only 1 plane look at
207 * drm_simple_display_pipe_init() instead.
Ville Syrjälä6bfc56a2012-03-13 12:35:48 +0200208 *
Daniel Vetterc8e32cc2014-03-10 21:33:02 +0100209 * Returns:
Ville Syrjälä6bfc56a2012-03-13 12:35:48 +0200210 * Zero on success, error code on failure.
Dave Airlief453ba02008-11-07 14:05:41 -0800211 */
Matt Ropere13161a2014-04-01 15:22:38 -0700212int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
213 struct drm_plane *primary,
Matt Roperfc1d3e42014-06-10 08:28:11 -0700214 struct drm_plane *cursor,
Ville Syrjäläf9882872015-12-09 16:19:31 +0200215 const struct drm_crtc_funcs *funcs,
216 const char *name, ...)
Dave Airlief453ba02008-11-07 14:05:41 -0800217{
Rob Clark51fd3712013-11-19 12:10:12 -0500218 struct drm_mode_config *config = &dev->mode_config;
Ville Syrjälä6bfc56a2012-03-13 12:35:48 +0200219 int ret;
220
Benjamin Gaignard522cf912015-03-17 12:05:29 +0100221 WARN_ON(primary && primary->type != DRM_PLANE_TYPE_PRIMARY);
222 WARN_ON(cursor && cursor->type != DRM_PLANE_TYPE_CURSOR);
223
Dave Airlief453ba02008-11-07 14:05:41 -0800224 crtc->dev = dev;
225 crtc->funcs = funcs;
226
Daniel Vetter3b24f7d2016-06-08 14:19:00 +0200227 INIT_LIST_HEAD(&crtc->commit_list);
228 spin_lock_init(&crtc->commit_lock);
229
Rob Clark51fd3712013-11-19 12:10:12 -0500230 drm_modeset_lock_init(&crtc->mutex);
Ville Syrjälä6bfc56a2012-03-13 12:35:48 +0200231 ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
232 if (ret)
Daniel Vetterbaf698b2014-11-12 11:59:47 +0100233 return ret;
Dave Airlief453ba02008-11-07 14:05:41 -0800234
Ville Syrjäläfa3ab4c2015-12-08 18:41:53 +0200235 if (name) {
236 va_list ap;
237
238 va_start(ap, name);
239 crtc->name = kvasprintf(GFP_KERNEL, name, ap);
240 va_end(ap);
241 } else {
242 crtc->name = kasprintf(GFP_KERNEL, "crtc-%d",
243 drm_num_crtcs(dev));
244 }
245 if (!crtc->name) {
Dave Airlie7c8f6d22016-04-15 15:10:32 +1000246 drm_mode_object_unregister(dev, &crtc->base);
Ville Syrjäläfa3ab4c2015-12-08 18:41:53 +0200247 return -ENOMEM;
248 }
249
Gustavo Padovan2a380152016-11-15 23:37:08 +0900250 crtc->fence_context = fence_context_alloc(1);
251 spin_lock_init(&crtc->fence_lock);
252 snprintf(crtc->timeline_name, sizeof(crtc->timeline_name),
253 "CRTC:%d-%s", crtc->base.id, crtc->name);
254
Paulo Zanonibffd9de02012-05-15 18:09:05 -0300255 crtc->base.properties = &crtc->properties;
256
Rob Clark51fd3712013-11-19 12:10:12 -0500257 list_add_tail(&crtc->head, &config->crtc_list);
Chris Wilson490d3d12016-05-27 20:05:00 +0100258 crtc->index = config->num_crtc++;
Ville Syrjälä6bfc56a2012-03-13 12:35:48 +0200259
Matt Ropere13161a2014-04-01 15:22:38 -0700260 crtc->primary = primary;
Matt Roperfc1d3e42014-06-10 08:28:11 -0700261 crtc->cursor = cursor;
Matt Ropere13161a2014-04-01 15:22:38 -0700262 if (primary)
263 primary->possible_crtcs = 1 << drm_crtc_index(crtc);
Matt Roperfc1d3e42014-06-10 08:28:11 -0700264 if (cursor)
265 cursor->possible_crtcs = 1 << drm_crtc_index(crtc);
Matt Ropere13161a2014-04-01 15:22:38 -0700266
Daniel Vettereab3bbe2015-01-22 16:36:21 +0100267 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
268 drm_object_attach_property(&crtc->base, config->prop_active, 0);
Daniel Stone955f3c32015-05-25 19:11:52 +0100269 drm_object_attach_property(&crtc->base, config->prop_mode_id, 0);
Gustavo Padovan710c1ed2016-11-16 22:00:21 +0900270 drm_object_attach_property(&crtc->base,
271 config->prop_out_fence_ptr, 0);
Daniel Vettereab3bbe2015-01-22 16:36:21 +0100272 }
273
Daniel Vetterbaf698b2014-11-12 11:59:47 +0100274 return 0;
Dave Airlief453ba02008-11-07 14:05:41 -0800275}
Matt Ropere13161a2014-04-01 15:22:38 -0700276EXPORT_SYMBOL(drm_crtc_init_with_planes);
Dave Airlief453ba02008-11-07 14:05:41 -0800277
278/**
Ville Syrjäläad6f5c32013-06-05 12:39:55 +0000279 * drm_crtc_cleanup - Clean up the core crtc usage
Dave Airlief453ba02008-11-07 14:05:41 -0800280 * @crtc: CRTC to cleanup
281 *
Ville Syrjäläad6f5c32013-06-05 12:39:55 +0000282 * This function cleans up @crtc and removes it from the DRM mode setting
283 * core. Note that the function does *not* free the crtc structure itself,
284 * this is the responsibility of the caller.
Dave Airlief453ba02008-11-07 14:05:41 -0800285 */
286void drm_crtc_cleanup(struct drm_crtc *crtc)
287{
288 struct drm_device *dev = crtc->dev;
289
Chris Wilson490d3d12016-05-27 20:05:00 +0100290 /* Note that the crtc_list is considered to be static; should we
291 * remove the drm_crtc at runtime we would have to decrement all
292 * the indices on the drm_crtc after us in the crtc_list.
293 */
294
Sachin Kamat9e1c1562012-11-19 09:44:56 +0000295 kfree(crtc->gamma_store);
296 crtc->gamma_store = NULL;
Dave Airlief453ba02008-11-07 14:05:41 -0800297
Rob Clark51fd3712013-11-19 12:10:12 -0500298 drm_modeset_lock_fini(&crtc->mutex);
299
Dave Airlie7c8f6d22016-04-15 15:10:32 +1000300 drm_mode_object_unregister(dev, &crtc->base);
Dave Airlief453ba02008-11-07 14:05:41 -0800301 list_del(&crtc->head);
302 dev->mode_config.num_crtc--;
Thierry Reding3009c032014-11-25 12:09:49 +0100303
304 WARN_ON(crtc->state && !crtc->funcs->atomic_destroy_state);
305 if (crtc->state && crtc->funcs->atomic_destroy_state)
306 crtc->funcs->atomic_destroy_state(crtc, crtc->state);
Thierry Redinga18c0af2014-12-10 11:38:49 +0100307
Ville Syrjäläfa3ab4c2015-12-08 18:41:53 +0200308 kfree(crtc->name);
309
Thierry Redinga18c0af2014-12-10 11:38:49 +0100310 memset(crtc, 0, sizeof(*crtc));
Dave Airlief453ba02008-11-07 14:05:41 -0800311}
312EXPORT_SYMBOL(drm_crtc_cleanup);
313
Benjamin Gaignard79190ea2016-06-21 16:37:09 +0200314int drm_modeset_register_all(struct drm_device *dev)
315{
316 int ret;
317
318 ret = drm_plane_register_all(dev);
319 if (ret)
320 goto err_plane;
321
322 ret = drm_crtc_register_all(dev);
323 if (ret)
324 goto err_crtc;
325
326 ret = drm_encoder_register_all(dev);
327 if (ret)
328 goto err_encoder;
329
330 ret = drm_connector_register_all(dev);
331 if (ret)
332 goto err_connector;
333
334 return 0;
335
336err_connector:
337 drm_encoder_unregister_all(dev);
338err_encoder:
339 drm_crtc_unregister_all(dev);
340err_crtc:
341 drm_plane_unregister_all(dev);
342err_plane:
343 return ret;
344}
345
346void drm_modeset_unregister_all(struct drm_device *dev)
347{
348 drm_connector_unregister_all(dev);
349 drm_encoder_unregister_all(dev);
350 drm_crtc_unregister_all(dev);
351 drm_plane_unregister_all(dev);
352}
353
Rob Clark6b4959f2014-12-18 16:01:53 -0500354static int drm_mode_create_standard_properties(struct drm_device *dev)
Dave Airlief453ba02008-11-07 14:05:41 -0800355{
Rob Clark356af0e2014-12-18 16:01:52 -0500356 struct drm_property *prop;
Daniel Vetter52217192016-08-12 22:48:50 +0200357 int ret;
Dave Airlief453ba02008-11-07 14:05:41 -0800358
Daniel Vetter52217192016-08-12 22:48:50 +0200359 ret = drm_connector_create_standard_properties(dev);
360 if (ret)
361 return ret;
Dave Airlie6f134d72014-10-20 16:30:50 +1000362
Rob Clark6b4959f2014-12-18 16:01:53 -0500363 prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
Rob Clark9922ab52014-04-01 20:16:57 -0400364 "type", drm_plane_type_enum_list,
365 ARRAY_SIZE(drm_plane_type_enum_list));
Rob Clark6b4959f2014-12-18 16:01:53 -0500366 if (!prop)
367 return -ENOMEM;
368 dev->mode_config.plane_type_property = prop;
369
370 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
371 "SRC_X", 0, UINT_MAX);
372 if (!prop)
373 return -ENOMEM;
374 dev->mode_config.prop_src_x = prop;
375
376 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
377 "SRC_Y", 0, UINT_MAX);
378 if (!prop)
379 return -ENOMEM;
380 dev->mode_config.prop_src_y = prop;
381
382 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
383 "SRC_W", 0, UINT_MAX);
384 if (!prop)
385 return -ENOMEM;
386 dev->mode_config.prop_src_w = prop;
387
388 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
389 "SRC_H", 0, UINT_MAX);
390 if (!prop)
391 return -ENOMEM;
392 dev->mode_config.prop_src_h = prop;
393
394 prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
395 "CRTC_X", INT_MIN, INT_MAX);
396 if (!prop)
397 return -ENOMEM;
398 dev->mode_config.prop_crtc_x = prop;
399
400 prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
401 "CRTC_Y", INT_MIN, INT_MAX);
402 if (!prop)
403 return -ENOMEM;
404 dev->mode_config.prop_crtc_y = prop;
405
406 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
407 "CRTC_W", 0, INT_MAX);
408 if (!prop)
409 return -ENOMEM;
410 dev->mode_config.prop_crtc_w = prop;
411
412 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
413 "CRTC_H", 0, INT_MAX);
414 if (!prop)
415 return -ENOMEM;
416 dev->mode_config.prop_crtc_h = prop;
417
418 prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
419 "FB_ID", DRM_MODE_OBJECT_FB);
420 if (!prop)
421 return -ENOMEM;
422 dev->mode_config.prop_fb_id = prop;
423
Gustavo Padovan96e02f42016-11-15 22:06:39 +0900424 prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
425 "IN_FENCE_FD", -1, INT_MAX);
426 if (!prop)
427 return -ENOMEM;
428 dev->mode_config.prop_in_fence_fd = prop;
429
Gustavo Padovan710c1ed2016-11-16 22:00:21 +0900430 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
431 "OUT_FENCE_PTR", 0, U64_MAX);
432 if (!prop)
433 return -ENOMEM;
434 dev->mode_config.prop_out_fence_ptr = prop;
435
Rob Clark6b4959f2014-12-18 16:01:53 -0500436 prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
437 "CRTC_ID", DRM_MODE_OBJECT_CRTC);
438 if (!prop)
439 return -ENOMEM;
440 dev->mode_config.prop_crtc_id = prop;
Rob Clark9922ab52014-04-01 20:16:57 -0400441
Daniel Vettereab3bbe2015-01-22 16:36:21 +0100442 prop = drm_property_create_bool(dev, DRM_MODE_PROP_ATOMIC,
443 "ACTIVE");
444 if (!prop)
445 return -ENOMEM;
446 dev->mode_config.prop_active = prop;
447
Daniel Stone955f3c32015-05-25 19:11:52 +0100448 prop = drm_property_create(dev,
449 DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
450 "MODE_ID", 0);
451 if (!prop)
452 return -ENOMEM;
453 dev->mode_config.prop_mode_id = prop;
454
Lionel Landwerlin5488dc12016-02-26 17:05:00 +0000455 prop = drm_property_create(dev,
456 DRM_MODE_PROP_BLOB,
457 "DEGAMMA_LUT", 0);
458 if (!prop)
459 return -ENOMEM;
460 dev->mode_config.degamma_lut_property = prop;
461
462 prop = drm_property_create_range(dev,
463 DRM_MODE_PROP_IMMUTABLE,
464 "DEGAMMA_LUT_SIZE", 0, UINT_MAX);
465 if (!prop)
466 return -ENOMEM;
467 dev->mode_config.degamma_lut_size_property = prop;
468
469 prop = drm_property_create(dev,
470 DRM_MODE_PROP_BLOB,
471 "CTM", 0);
472 if (!prop)
473 return -ENOMEM;
474 dev->mode_config.ctm_property = prop;
475
476 prop = drm_property_create(dev,
477 DRM_MODE_PROP_BLOB,
478 "GAMMA_LUT", 0);
479 if (!prop)
480 return -ENOMEM;
481 dev->mode_config.gamma_lut_property = prop;
482
483 prop = drm_property_create_range(dev,
484 DRM_MODE_PROP_IMMUTABLE,
485 "GAMMA_LUT_SIZE", 0, UINT_MAX);
486 if (!prop)
487 return -ENOMEM;
488 dev->mode_config.gamma_lut_size_property = prop;
489
Rob Clark9922ab52014-04-01 20:16:57 -0400490 return 0;
491}
492
Dave Airlief453ba02008-11-07 14:05:41 -0800493/**
Dave Airlief453ba02008-11-07 14:05:41 -0800494 * drm_mode_getresources - get graphics configuration
Daniel Vetter065a50ed2012-12-02 00:09:18 +0100495 * @dev: drm device for the ioctl
496 * @data: data pointer for the ioctl
497 * @file_priv: drm file for the ioctl call
Dave Airlief453ba02008-11-07 14:05:41 -0800498 *
Dave Airlief453ba02008-11-07 14:05:41 -0800499 * Construct a set of configuration description structures and return
500 * them to the user, including CRTC, connector and framebuffer configuration.
501 *
502 * Called by the user via ioctl.
503 *
Daniel Vetterc8e32cc2014-03-10 21:33:02 +0100504 * Returns:
Daniel Vetter1a498632014-11-19 18:38:09 +0100505 * Zero on success, negative errno on failure.
Dave Airlief453ba02008-11-07 14:05:41 -0800506 */
507int drm_mode_getresources(struct drm_device *dev, void *data,
508 struct drm_file *file_priv)
509{
510 struct drm_mode_card_res *card_res = data;
511 struct list_head *lh;
512 struct drm_framebuffer *fb;
513 struct drm_connector *connector;
514 struct drm_crtc *crtc;
515 struct drm_encoder *encoder;
516 int ret = 0;
517 int connector_count = 0;
518 int crtc_count = 0;
519 int fb_count = 0;
520 int encoder_count = 0;
Daniel Vetter9c7060f2015-07-09 23:44:36 +0200521 int copied = 0;
Dave Airlief453ba02008-11-07 14:05:41 -0800522 uint32_t __user *fb_id;
523 uint32_t __user *crtc_id;
524 uint32_t __user *connector_id;
525 uint32_t __user *encoder_id;
Dave Airlief453ba02008-11-07 14:05:41 -0800526
Dave Airliefb3b06c2011-02-08 13:55:21 +1000527 if (!drm_core_check_feature(dev, DRIVER_MODESET))
528 return -EINVAL;
529
Dave Airlief453ba02008-11-07 14:05:41 -0800530
Daniel Vetter4b096ac2012-12-10 21:19:18 +0100531 mutex_lock(&file_priv->fbs_lock);
Dave Airlief453ba02008-11-07 14:05:41 -0800532 /*
533 * For the non-control nodes we need to limit the list of resources
534 * by IDs in the group list for this node
535 */
536 list_for_each(lh, &file_priv->fbs)
537 fb_count++;
538
Daniel Vetter4b096ac2012-12-10 21:19:18 +0100539 /* handle this in 4 parts */
540 /* FBs */
541 if (card_res->count_fbs >= fb_count) {
542 copied = 0;
543 fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr;
544 list_for_each_entry(fb, &file_priv->fbs, filp_head) {
545 if (put_user(fb->base.id, fb_id + copied)) {
546 mutex_unlock(&file_priv->fbs_lock);
547 return -EFAULT;
548 }
549 copied++;
550 }
551 }
552 card_res->count_fbs = fb_count;
553 mutex_unlock(&file_priv->fbs_lock);
554
Daniel Vetterfcf93f62014-11-12 08:45:01 +0100555 /* mode_config.mutex protects the connector list against e.g. DP MST
556 * connector hot-adding. CRTC/Plane lists are invariant. */
557 mutex_lock(&dev->mode_config.mutex);
Daniel Vetter9c7060f2015-07-09 23:44:36 +0200558 drm_for_each_crtc(crtc, dev)
559 crtc_count++;
Dave Airlief453ba02008-11-07 14:05:41 -0800560
Daniel Vetter9c7060f2015-07-09 23:44:36 +0200561 drm_for_each_connector(connector, dev)
562 connector_count++;
Dave Airlief453ba02008-11-07 14:05:41 -0800563
Daniel Vetter9c7060f2015-07-09 23:44:36 +0200564 drm_for_each_encoder(encoder, dev)
565 encoder_count++;
Dave Airlief453ba02008-11-07 14:05:41 -0800566
567 card_res->max_height = dev->mode_config.max_height;
568 card_res->min_height = dev->mode_config.min_height;
569 card_res->max_width = dev->mode_config.max_width;
570 card_res->min_width = dev->mode_config.min_width;
571
Dave Airlief453ba02008-11-07 14:05:41 -0800572 /* CRTCs */
573 if (card_res->count_crtcs >= crtc_count) {
574 copied = 0;
575 crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr;
Daniel Vetter9c7060f2015-07-09 23:44:36 +0200576 drm_for_each_crtc(crtc, dev) {
Daniel Vetter9c7060f2015-07-09 23:44:36 +0200577 if (put_user(crtc->base.id, crtc_id + copied)) {
578 ret = -EFAULT;
579 goto out;
Dave Airlief453ba02008-11-07 14:05:41 -0800580 }
Daniel Vetter9c7060f2015-07-09 23:44:36 +0200581 copied++;
Dave Airlief453ba02008-11-07 14:05:41 -0800582 }
583 }
584 card_res->count_crtcs = crtc_count;
585
586 /* Encoders */
587 if (card_res->count_encoders >= encoder_count) {
588 copied = 0;
589 encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr;
Daniel Vetter9c7060f2015-07-09 23:44:36 +0200590 drm_for_each_encoder(encoder, dev) {
Daniel Vetter9c7060f2015-07-09 23:44:36 +0200591 if (put_user(encoder->base.id, encoder_id +
592 copied)) {
593 ret = -EFAULT;
594 goto out;
Dave Airlief453ba02008-11-07 14:05:41 -0800595 }
Daniel Vetter9c7060f2015-07-09 23:44:36 +0200596 copied++;
Dave Airlief453ba02008-11-07 14:05:41 -0800597 }
598 }
599 card_res->count_encoders = encoder_count;
600
601 /* Connectors */
602 if (card_res->count_connectors >= connector_count) {
603 copied = 0;
604 connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr;
Daniel Vetter9c7060f2015-07-09 23:44:36 +0200605 drm_for_each_connector(connector, dev) {
Daniel Vetter9c7060f2015-07-09 23:44:36 +0200606 if (put_user(connector->base.id,
607 connector_id + copied)) {
608 ret = -EFAULT;
609 goto out;
Dave Airlief453ba02008-11-07 14:05:41 -0800610 }
Daniel Vetter9c7060f2015-07-09 23:44:36 +0200611 copied++;
Dave Airlief453ba02008-11-07 14:05:41 -0800612 }
613 }
614 card_res->count_connectors = connector_count;
615
Dave Airlief453ba02008-11-07 14:05:41 -0800616out:
Daniel Vetterfcf93f62014-11-12 08:45:01 +0100617 mutex_unlock(&dev->mode_config.mutex);
Dave Airlief453ba02008-11-07 14:05:41 -0800618 return ret;
619}
620
621/**
622 * drm_mode_getcrtc - get CRTC configuration
Daniel Vetter065a50ed2012-12-02 00:09:18 +0100623 * @dev: drm device for the ioctl
624 * @data: data pointer for the ioctl
625 * @file_priv: drm file for the ioctl call
Dave Airlief453ba02008-11-07 14:05:41 -0800626 *
Dave Airlief453ba02008-11-07 14:05:41 -0800627 * Construct a CRTC configuration structure to return to the user.
628 *
629 * Called by the user via ioctl.
630 *
Daniel Vetterc8e32cc2014-03-10 21:33:02 +0100631 * Returns:
Daniel Vetter1a498632014-11-19 18:38:09 +0100632 * Zero on success, negative errno on failure.
Dave Airlief453ba02008-11-07 14:05:41 -0800633 */
634int drm_mode_getcrtc(struct drm_device *dev,
635 void *data, struct drm_file *file_priv)
636{
637 struct drm_mode_crtc *crtc_resp = data;
638 struct drm_crtc *crtc;
Dave Airlief453ba02008-11-07 14:05:41 -0800639
Dave Airliefb3b06c2011-02-08 13:55:21 +1000640 if (!drm_core_check_feature(dev, DRIVER_MODESET))
641 return -EINVAL;
642
Rob Clarka2b34e22013-10-05 16:36:52 -0400643 crtc = drm_crtc_find(dev, crtc_resp->crtc_id);
Daniel Vetterfcf93f62014-11-12 08:45:01 +0100644 if (!crtc)
645 return -ENOENT;
Dave Airlief453ba02008-11-07 14:05:41 -0800646
Daniel Vetterfcf93f62014-11-12 08:45:01 +0100647 drm_modeset_lock_crtc(crtc, crtc->primary);
Dave Airlief453ba02008-11-07 14:05:41 -0800648 crtc_resp->gamma_size = crtc->gamma_size;
Matt Roperf4510a22014-04-01 15:22:40 -0700649 if (crtc->primary->fb)
650 crtc_resp->fb_id = crtc->primary->fb->base.id;
Dave Airlief453ba02008-11-07 14:05:41 -0800651 else
652 crtc_resp->fb_id = 0;
653
Daniel Vetter31c946e2015-02-22 12:24:17 +0100654 if (crtc->state) {
655 crtc_resp->x = crtc->primary->state->src_x >> 16;
656 crtc_resp->y = crtc->primary->state->src_y >> 16;
657 if (crtc->state->enable) {
Daniel Stone934a8a82015-05-22 13:34:48 +0100658 drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->state->mode);
Daniel Vetter31c946e2015-02-22 12:24:17 +0100659 crtc_resp->mode_valid = 1;
Dave Airlief453ba02008-11-07 14:05:41 -0800660
Daniel Vetter31c946e2015-02-22 12:24:17 +0100661 } else {
662 crtc_resp->mode_valid = 0;
663 }
Dave Airlief453ba02008-11-07 14:05:41 -0800664 } else {
Daniel Vetter31c946e2015-02-22 12:24:17 +0100665 crtc_resp->x = crtc->x;
666 crtc_resp->y = crtc->y;
667 if (crtc->enabled) {
Daniel Stone934a8a82015-05-22 13:34:48 +0100668 drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->mode);
Daniel Vetter31c946e2015-02-22 12:24:17 +0100669 crtc_resp->mode_valid = 1;
670
671 } else {
672 crtc_resp->mode_valid = 0;
673 }
Dave Airlief453ba02008-11-07 14:05:41 -0800674 }
Daniel Vetterfcf93f62014-11-12 08:45:01 +0100675 drm_modeset_unlock_crtc(crtc);
Dave Airlief453ba02008-11-07 14:05:41 -0800676
Daniel Vetterbaf698b2014-11-12 11:59:47 +0100677 return 0;
Dave Airlief453ba02008-11-07 14:05:41 -0800678}
679
Dave Airlief453ba02008-11-07 14:05:41 -0800680/**
Daniel Vetter2d13b672012-12-11 13:47:23 +0100681 * drm_mode_set_config_internal - helper to call ->set_config
682 * @set: modeset config to set
683 *
684 * This is a little helper to wrap internal calls to the ->set_config driver
685 * interface. The only thing it adds is correct refcounting dance.
Thierry Reding4dfd9092014-12-10 13:03:34 +0100686 *
Daniel Vetterc8e32cc2014-03-10 21:33:02 +0100687 * Returns:
Daniel Vetter1a498632014-11-19 18:38:09 +0100688 * Zero on success, negative errno on failure.
Daniel Vetter2d13b672012-12-11 13:47:23 +0100689 */
690int drm_mode_set_config_internal(struct drm_mode_set *set)
691{
692 struct drm_crtc *crtc = set->crtc;
Daniel Vetter5cef29a2013-06-15 00:13:16 +0200693 struct drm_framebuffer *fb;
694 struct drm_crtc *tmp;
Daniel Vetterb0d12322012-12-11 01:07:12 +0100695 int ret;
Daniel Vetter2d13b672012-12-11 13:47:23 +0100696
Daniel Vetter5cef29a2013-06-15 00:13:16 +0200697 /*
698 * NOTE: ->set_config can also disable other crtcs (if we steal all
699 * connectors from it), hence we need to refcount the fbs across all
700 * crtcs. Atomic modeset will have saner semantics ...
701 */
Daniel Vettere4f62542015-07-09 23:44:35 +0200702 drm_for_each_crtc(tmp, crtc->dev)
Daniel Vetter3d30a592014-07-27 13:42:42 +0200703 tmp->primary->old_fb = tmp->primary->fb;
Daniel Vetter5cef29a2013-06-15 00:13:16 +0200704
Daniel Vetterb0d12322012-12-11 01:07:12 +0100705 fb = set->fb;
706
707 ret = crtc->funcs->set_config(set);
708 if (ret == 0) {
Matt Ropere13161a2014-04-01 15:22:38 -0700709 crtc->primary->crtc = crtc;
Daniel Vetter0fe27f02014-04-23 17:34:06 +0200710 crtc->primary->fb = fb;
Daniel Vetter5cef29a2013-06-15 00:13:16 +0200711 }
Daniel Vettercc85e122013-06-15 00:13:15 +0200712
Daniel Vettere4f62542015-07-09 23:44:35 +0200713 drm_for_each_crtc(tmp, crtc->dev) {
Matt Roperf4510a22014-04-01 15:22:40 -0700714 if (tmp->primary->fb)
715 drm_framebuffer_reference(tmp->primary->fb);
Daniel Vetter3d30a592014-07-27 13:42:42 +0200716 if (tmp->primary->old_fb)
717 drm_framebuffer_unreference(tmp->primary->old_fb);
718 tmp->primary->old_fb = NULL;
Daniel Vetterb0d12322012-12-11 01:07:12 +0100719 }
720
721 return ret;
Daniel Vetter2d13b672012-12-11 13:47:23 +0100722}
723EXPORT_SYMBOL(drm_mode_set_config_internal);
724
Matt Roperaf936292014-04-01 15:22:34 -0700725/**
Gustavo Padovanecb7e162014-12-01 15:40:09 -0800726 * drm_crtc_get_hv_timing - Fetches hdisplay/vdisplay for given mode
727 * @mode: mode to query
728 * @hdisplay: hdisplay value to fill in
729 * @vdisplay: vdisplay value to fill in
730 *
731 * The vdisplay value will be doubled if the specified mode is a stereo mode of
732 * the appropriate layout.
733 */
734void drm_crtc_get_hv_timing(const struct drm_display_mode *mode,
735 int *hdisplay, int *vdisplay)
736{
737 struct drm_display_mode adjusted;
738
739 drm_mode_copy(&adjusted, mode);
740 drm_mode_set_crtcinfo(&adjusted, CRTC_STEREO_DOUBLE_ONLY);
741 *hdisplay = adjusted.crtc_hdisplay;
742 *vdisplay = adjusted.crtc_vdisplay;
743}
744EXPORT_SYMBOL(drm_crtc_get_hv_timing);
745
746/**
Matt Roperaf936292014-04-01 15:22:34 -0700747 * drm_crtc_check_viewport - Checks that a framebuffer is big enough for the
748 * CRTC viewport
749 * @crtc: CRTC that framebuffer will be displayed on
750 * @x: x panning
751 * @y: y panning
752 * @mode: mode that framebuffer will be displayed under
753 * @fb: framebuffer to check size of
Damien Lespiauc11e9282013-09-25 16:45:30 +0100754 */
Matt Roperaf936292014-04-01 15:22:34 -0700755int drm_crtc_check_viewport(const struct drm_crtc *crtc,
756 int x, int y,
757 const struct drm_display_mode *mode,
758 const struct drm_framebuffer *fb)
Damien Lespiauc11e9282013-09-25 16:45:30 +0100759
760{
761 int hdisplay, vdisplay;
762
Gustavo Padovanecb7e162014-12-01 15:40:09 -0800763 drm_crtc_get_hv_timing(mode, &hdisplay, &vdisplay);
Damien Lespiaua0c1bbb2013-09-25 16:45:31 +0100764
Ville Syrjälä33e0be62015-10-16 18:38:39 +0300765 if (crtc->state &&
Joonas Lahtinen31ad61e2016-07-29 08:50:05 +0300766 crtc->primary->state->rotation & (DRM_ROTATE_90 |
767 DRM_ROTATE_270))
Damien Lespiauc11e9282013-09-25 16:45:30 +0100768 swap(hdisplay, vdisplay);
769
Daniel Vetter43968d72016-09-21 10:59:24 +0200770 return drm_framebuffer_check_src_coords(x << 16, y << 16,
771 hdisplay << 16, vdisplay << 16,
772 fb);
Damien Lespiauc11e9282013-09-25 16:45:30 +0100773}
Matt Roperaf936292014-04-01 15:22:34 -0700774EXPORT_SYMBOL(drm_crtc_check_viewport);
Damien Lespiauc11e9282013-09-25 16:45:30 +0100775
Daniel Vetter2d13b672012-12-11 13:47:23 +0100776/**
Dave Airlief453ba02008-11-07 14:05:41 -0800777 * drm_mode_setcrtc - set CRTC configuration
Daniel Vetter065a50ed2012-12-02 00:09:18 +0100778 * @dev: drm device for the ioctl
779 * @data: data pointer for the ioctl
780 * @file_priv: drm file for the ioctl call
Dave Airlief453ba02008-11-07 14:05:41 -0800781 *
Dave Airlief453ba02008-11-07 14:05:41 -0800782 * Build a new CRTC configuration based on user request.
783 *
784 * Called by the user via ioctl.
785 *
Daniel Vetterc8e32cc2014-03-10 21:33:02 +0100786 * Returns:
Daniel Vetter1a498632014-11-19 18:38:09 +0100787 * Zero on success, negative errno on failure.
Dave Airlief453ba02008-11-07 14:05:41 -0800788 */
789int drm_mode_setcrtc(struct drm_device *dev, void *data,
790 struct drm_file *file_priv)
791{
792 struct drm_mode_config *config = &dev->mode_config;
793 struct drm_mode_crtc *crtc_req = data;
Ville Syrjälä6653cc82012-03-13 12:35:38 +0200794 struct drm_crtc *crtc;
Dave Airlief453ba02008-11-07 14:05:41 -0800795 struct drm_connector **connector_set = NULL, *connector;
796 struct drm_framebuffer *fb = NULL;
797 struct drm_display_mode *mode = NULL;
798 struct drm_mode_set set;
799 uint32_t __user *set_connectors_ptr;
Laurent Pinchart4a1b0712012-05-17 13:27:21 +0200800 int ret;
Dave Airlief453ba02008-11-07 14:05:41 -0800801 int i;
802
Dave Airliefb3b06c2011-02-08 13:55:21 +1000803 if (!drm_core_check_feature(dev, DRIVER_MODESET))
804 return -EINVAL;
805
Zhao Junwang01447e92015-07-07 17:08:35 +0800806 /*
807 * Universal plane src offsets are only 16.16, prevent havoc for
808 * drivers using universal plane code internally.
809 */
810 if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
Ville Syrjälä1d97e912012-03-13 12:35:41 +0200811 return -ERANGE;
812
Daniel Vetter84849902012-12-02 00:28:11 +0100813 drm_modeset_lock_all(dev);
Rob Clarka2b34e22013-10-05 16:36:52 -0400814 crtc = drm_crtc_find(dev, crtc_req->crtc_id);
815 if (!crtc) {
Zhao Yakui58367ed2009-07-20 13:48:07 +0800816 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
Ville Syrjäläf27657f2013-10-17 13:35:00 +0300817 ret = -ENOENT;
Dave Airlief453ba02008-11-07 14:05:41 -0800818 goto out;
819 }
Ville Syrjäläfa3ab4c2015-12-08 18:41:53 +0200820 DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
Dave Airlief453ba02008-11-07 14:05:41 -0800821
822 if (crtc_req->mode_valid) {
823 /* If we have a mode we need a framebuffer. */
824 /* If we pass -1, set the mode with the currently bound fb */
825 if (crtc_req->fb_id == -1) {
Matt Roperf4510a22014-04-01 15:22:40 -0700826 if (!crtc->primary->fb) {
Ville Syrjälä6653cc82012-03-13 12:35:38 +0200827 DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
828 ret = -EINVAL;
829 goto out;
Dave Airlief453ba02008-11-07 14:05:41 -0800830 }
Matt Roperf4510a22014-04-01 15:22:40 -0700831 fb = crtc->primary->fb;
Daniel Vetterb0d12322012-12-11 01:07:12 +0100832 /* Make refcounting symmetric with the lookup path. */
833 drm_framebuffer_reference(fb);
Dave Airlief453ba02008-11-07 14:05:41 -0800834 } else {
Daniel Vetter786b99e2012-12-02 21:53:40 +0100835 fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);
836 if (!fb) {
Zhao Yakui58367ed2009-07-20 13:48:07 +0800837 DRM_DEBUG_KMS("Unknown FB ID%d\n",
838 crtc_req->fb_id);
Ville Syrjälä37c4e702013-10-17 13:35:01 +0300839 ret = -ENOENT;
Dave Airlief453ba02008-11-07 14:05:41 -0800840 goto out;
841 }
Dave Airlief453ba02008-11-07 14:05:41 -0800842 }
843
844 mode = drm_mode_create(dev);
Ville Syrjäläee34ab52012-03-13 12:35:43 +0200845 if (!mode) {
846 ret = -ENOMEM;
847 goto out;
848 }
849
Daniel Stone934a8a82015-05-22 13:34:48 +0100850 ret = drm_mode_convert_umode(mode, &crtc_req->mode);
Ville Syrjälä90367bf2012-03-13 12:35:44 +0200851 if (ret) {
852 DRM_DEBUG_KMS("Invalid mode\n");
853 goto out;
854 }
855
Laurent Pinchart7eb5f302015-03-09 10:41:07 +0200856 /*
857 * Check whether the primary plane supports the fb pixel format.
858 * Drivers not implementing the universal planes API use a
859 * default formats list provided by the DRM core which doesn't
860 * match real hardware capabilities. Skip the check in that
861 * case.
862 */
863 if (!crtc->primary->format_default) {
864 ret = drm_plane_check_pixel_format(crtc->primary,
865 fb->pixel_format);
866 if (ret) {
Eric Engestromd3828142016-08-15 16:29:55 +0100867 char *format_name = drm_get_format_name(fb->pixel_format);
Eric Engestrom90844f02016-08-15 01:02:38 +0100868 DRM_DEBUG_KMS("Invalid pixel format %s\n", format_name);
869 kfree(format_name);
Laurent Pinchart7eb5f302015-03-09 10:41:07 +0200870 goto out;
871 }
872 }
873
Damien Lespiauc11e9282013-09-25 16:45:30 +0100874 ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,
875 mode, fb);
876 if (ret)
Ville Syrjälä5f61bb42012-03-13 12:35:45 +0200877 goto out;
Damien Lespiauc11e9282013-09-25 16:45:30 +0100878
Dave Airlief453ba02008-11-07 14:05:41 -0800879 }
880
881 if (crtc_req->count_connectors == 0 && mode) {
Zhao Yakui58367ed2009-07-20 13:48:07 +0800882 DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
Dave Airlief453ba02008-11-07 14:05:41 -0800883 ret = -EINVAL;
884 goto out;
885 }
886
Jakob Bornecrantz7781de72009-08-03 13:43:58 +0100887 if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
Zhao Yakui58367ed2009-07-20 13:48:07 +0800888 DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
Dave Airlief453ba02008-11-07 14:05:41 -0800889 crtc_req->count_connectors);
890 ret = -EINVAL;
891 goto out;
892 }
893
894 if (crtc_req->count_connectors > 0) {
895 u32 out_id;
896
897 /* Avoid unbounded kernel memory allocation */
898 if (crtc_req->count_connectors > config->num_connector) {
899 ret = -EINVAL;
900 goto out;
901 }
902
Thierry Reding2f6c5382014-12-10 13:03:36 +0100903 connector_set = kmalloc_array(crtc_req->count_connectors,
904 sizeof(struct drm_connector *),
905 GFP_KERNEL);
Dave Airlief453ba02008-11-07 14:05:41 -0800906 if (!connector_set) {
907 ret = -ENOMEM;
908 goto out;
909 }
910
911 for (i = 0; i < crtc_req->count_connectors; i++) {
Dave Airlieb164d312016-04-27 11:10:09 +1000912 connector_set[i] = NULL;
Ville Syrjälä81f6c7f2011-12-20 00:06:42 +0200913 set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr;
Dave Airlief453ba02008-11-07 14:05:41 -0800914 if (get_user(out_id, &set_connectors_ptr[i])) {
915 ret = -EFAULT;
916 goto out;
917 }
918
Dave Airlieb164d312016-04-27 11:10:09 +1000919 connector = drm_connector_lookup(dev, out_id);
Rob Clarka2b34e22013-10-05 16:36:52 -0400920 if (!connector) {
Zhao Yakui58367ed2009-07-20 13:48:07 +0800921 DRM_DEBUG_KMS("Connector id %d unknown\n",
922 out_id);
Ville Syrjäläf27657f2013-10-17 13:35:00 +0300923 ret = -ENOENT;
Dave Airlief453ba02008-11-07 14:05:41 -0800924 goto out;
925 }
Jerome Glisse94401062010-07-15 15:43:25 -0400926 DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
927 connector->base.id,
Jani Nikula25933822014-06-03 14:56:20 +0300928 connector->name);
Dave Airlief453ba02008-11-07 14:05:41 -0800929
930 connector_set[i] = connector;
931 }
932 }
933
934 set.crtc = crtc;
935 set.x = crtc_req->x;
936 set.y = crtc_req->y;
937 set.mode = mode;
938 set.connectors = connector_set;
939 set.num_connectors = crtc_req->count_connectors;
Dave Airlie5ef5f722009-08-17 13:11:23 +1000940 set.fb = fb;
Daniel Vetter2d13b672012-12-11 13:47:23 +0100941 ret = drm_mode_set_config_internal(&set);
Dave Airlief453ba02008-11-07 14:05:41 -0800942
943out:
Daniel Vetterb0d12322012-12-11 01:07:12 +0100944 if (fb)
945 drm_framebuffer_unreference(fb);
946
Dave Airlieb164d312016-04-27 11:10:09 +1000947 if (connector_set) {
948 for (i = 0; i < crtc_req->count_connectors; i++) {
949 if (connector_set[i])
950 drm_connector_unreference(connector_set[i]);
951 }
952 }
Dave Airlief453ba02008-11-07 14:05:41 -0800953 kfree(connector_set);
Ville Syrjäläee34ab52012-03-13 12:35:43 +0200954 drm_mode_destroy(dev, mode);
Daniel Vetter84849902012-12-02 00:28:11 +0100955 drm_modeset_unlock_all(dev);
Dave Airlief453ba02008-11-07 14:05:41 -0800956 return ret;
957}
958
Daniel Vetter949619f2016-08-29 10:27:51 +0200959int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
960 struct drm_property *property,
961 uint64_t value)
Paulo Zanonibffd9de02012-05-15 18:09:05 -0300962{
963 int ret = -EINVAL;
964 struct drm_crtc *crtc = obj_to_crtc(obj);
965
966 if (crtc->funcs->set_property)
967 ret = crtc->funcs->set_property(crtc, property, value);
968 if (!ret)
969 drm_object_property_set_value(obj, property, value);
970
971 return ret;
972}
973
Thomas Wood3a5f87c2014-08-20 14:45:00 +0100974/**
Daniel Vetterc8e32cc2014-03-10 21:33:02 +0100975 * drm_mode_config_reset - call ->reset callbacks
976 * @dev: drm device
977 *
978 * This functions calls all the crtc's, encoder's and connector's ->reset
979 * callback. Drivers can use this in e.g. their driver load or resume code to
980 * reset hardware and software state.
981 */
Chris Wilsoneb033552011-01-24 15:11:08 +0000982void drm_mode_config_reset(struct drm_device *dev)
983{
984 struct drm_crtc *crtc;
Daniel Vetter2a0d7cf2014-07-29 15:32:37 +0200985 struct drm_plane *plane;
Chris Wilsoneb033552011-01-24 15:11:08 +0000986 struct drm_encoder *encoder;
987 struct drm_connector *connector;
988
Daniel Vettere4f62542015-07-09 23:44:35 +0200989 drm_for_each_plane(plane, dev)
Daniel Vetter2a0d7cf2014-07-29 15:32:37 +0200990 if (plane->funcs->reset)
991 plane->funcs->reset(plane);
992
Daniel Vettere4f62542015-07-09 23:44:35 +0200993 drm_for_each_crtc(crtc, dev)
Chris Wilsoneb033552011-01-24 15:11:08 +0000994 if (crtc->funcs->reset)
995 crtc->funcs->reset(crtc);
996
Daniel Vettere4f62542015-07-09 23:44:35 +0200997 drm_for_each_encoder(encoder, dev)
Chris Wilsoneb033552011-01-24 15:11:08 +0000998 if (encoder->funcs->reset)
999 encoder->funcs->reset(encoder);
1000
Daniel Vetterf8c2ba32015-07-29 08:32:43 +02001001 mutex_lock(&dev->mode_config.mutex);
Dave Airlie4eebf602015-08-17 14:13:53 +10001002 drm_for_each_connector(connector, dev)
Chris Wilsoneb033552011-01-24 15:11:08 +00001003 if (connector->funcs->reset)
1004 connector->funcs->reset(connector);
Daniel Vetterf8c2ba32015-07-29 08:32:43 +02001005 mutex_unlock(&dev->mode_config.mutex);
Chris Wilsoneb033552011-01-24 15:11:08 +00001006}
1007EXPORT_SYMBOL(drm_mode_config_reset);
Dave Airlieff72145b2011-02-07 12:16:14 +10001008
Daniel Vetterc8e32cc2014-03-10 21:33:02 +01001009/**
1010 * drm_mode_create_dumb_ioctl - create a dumb backing storage buffer
1011 * @dev: DRM device
1012 * @data: ioctl data
1013 * @file_priv: DRM file info
1014 *
1015 * This creates a new dumb buffer in the driver's backing storage manager (GEM,
1016 * TTM or something else entirely) and returns the resulting buffer handle. This
1017 * handle can then be wrapped up into a framebuffer modeset object.
1018 *
1019 * Note that userspace is not allowed to use such objects for render
1020 * acceleration - drivers must create their own private ioctls for such a use
1021 * case.
1022 *
1023 * Called by the user via ioctl.
1024 *
1025 * Returns:
Daniel Vetter1a498632014-11-19 18:38:09 +01001026 * Zero on success, negative errno on failure.
Daniel Vetterc8e32cc2014-03-10 21:33:02 +01001027 */
Dave Airlieff72145b2011-02-07 12:16:14 +10001028int drm_mode_create_dumb_ioctl(struct drm_device *dev,
1029 void *data, struct drm_file *file_priv)
1030{
1031 struct drm_mode_create_dumb *args = data;
David Herrmannb28cd412014-01-20 20:09:55 +01001032 u32 cpp, stride, size;
Dave Airlieff72145b2011-02-07 12:16:14 +10001033
1034 if (!dev->driver->dumb_create)
1035 return -ENOSYS;
David Herrmannb28cd412014-01-20 20:09:55 +01001036 if (!args->width || !args->height || !args->bpp)
1037 return -EINVAL;
1038
1039 /* overflow checks for 32bit size calculations */
David Herrmann00e72082014-08-24 19:23:26 +02001040 /* NOTE: DIV_ROUND_UP() can overflow */
David Herrmannb28cd412014-01-20 20:09:55 +01001041 cpp = DIV_ROUND_UP(args->bpp, 8);
David Herrmann00e72082014-08-24 19:23:26 +02001042 if (!cpp || cpp > 0xffffffffU / args->width)
David Herrmannb28cd412014-01-20 20:09:55 +01001043 return -EINVAL;
1044 stride = cpp * args->width;
1045 if (args->height > 0xffffffffU / stride)
1046 return -EINVAL;
1047
1048 /* test for wrap-around */
1049 size = args->height * stride;
1050 if (PAGE_ALIGN(size) == 0)
1051 return -EINVAL;
1052
Thierry Redingf6085952014-11-03 11:14:14 +01001053 /*
1054 * handle, pitch and size are output parameters. Zero them out to
1055 * prevent drivers from accidentally using uninitialized data. Since
1056 * not all existing userspace is clearing these fields properly we
1057 * cannot reject IOCTL with garbage in them.
1058 */
1059 args->handle = 0;
1060 args->pitch = 0;
1061 args->size = 0;
1062
Dave Airlieff72145b2011-02-07 12:16:14 +10001063 return dev->driver->dumb_create(file_priv, dev, args);
1064}
1065
Daniel Vetterc8e32cc2014-03-10 21:33:02 +01001066/**
1067 * drm_mode_mmap_dumb_ioctl - create an mmap offset for a dumb backing storage buffer
1068 * @dev: DRM device
1069 * @data: ioctl data
1070 * @file_priv: DRM file info
1071 *
1072 * Allocate an offset in the drm device node's address space to be able to
1073 * memory map a dumb buffer.
1074 *
1075 * Called by the user via ioctl.
1076 *
1077 * Returns:
Daniel Vetter1a498632014-11-19 18:38:09 +01001078 * Zero on success, negative errno on failure.
Daniel Vetterc8e32cc2014-03-10 21:33:02 +01001079 */
Dave Airlieff72145b2011-02-07 12:16:14 +10001080int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
1081 void *data, struct drm_file *file_priv)
1082{
1083 struct drm_mode_map_dumb *args = data;
1084
1085 /* call driver ioctl to get mmap offset */
1086 if (!dev->driver->dumb_map_offset)
1087 return -ENOSYS;
1088
1089 return dev->driver->dumb_map_offset(file_priv, dev, args->handle, &args->offset);
1090}
1091
Daniel Vetterc8e32cc2014-03-10 21:33:02 +01001092/**
1093 * drm_mode_destroy_dumb_ioctl - destroy a dumb backing strage buffer
1094 * @dev: DRM device
1095 * @data: ioctl data
1096 * @file_priv: DRM file info
1097 *
1098 * This destroys the userspace handle for the given dumb backing storage buffer.
1099 * Since buffer objects must be reference counted in the kernel a buffer object
1100 * won't be immediately freed if a framebuffer modeset object still uses it.
1101 *
1102 * Called by the user via ioctl.
1103 *
1104 * Returns:
Daniel Vetter1a498632014-11-19 18:38:09 +01001105 * Zero on success, negative errno on failure.
Daniel Vetterc8e32cc2014-03-10 21:33:02 +01001106 */
Dave Airlieff72145b2011-02-07 12:16:14 +10001107int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
1108 void *data, struct drm_file *file_priv)
1109{
1110 struct drm_mode_destroy_dumb *args = data;
1111
1112 if (!dev->driver->dumb_destroy)
1113 return -ENOSYS;
1114
1115 return dev->driver->dumb_destroy(file_priv, dev, args->handle);
1116}
Dave Airlie248dbc22011-11-29 20:02:54 +00001117
Daniel Vetterc8e32cc2014-03-10 21:33:02 +01001118/**
Laurent Pinchart87d24fc2013-04-15 15:37:16 +02001119 * drm_mode_config_init - initialize DRM mode_configuration structure
1120 * @dev: DRM device
1121 *
1122 * Initialize @dev's mode_config structure, used for tracking the graphics
1123 * configuration of @dev.
1124 *
1125 * Since this initializes the modeset locks, no locking is possible. Which is no
1126 * problem, since this should happen single threaded at init time. It is the
1127 * driver's problem to ensure this guarantee.
1128 *
1129 */
1130void drm_mode_config_init(struct drm_device *dev)
1131{
1132 mutex_init(&dev->mode_config.mutex);
Rob Clark51fd3712013-11-19 12:10:12 -05001133 drm_modeset_lock_init(&dev->mode_config.connection_mutex);
Laurent Pinchart87d24fc2013-04-15 15:37:16 +02001134 mutex_init(&dev->mode_config.idr_mutex);
1135 mutex_init(&dev->mode_config.fb_lock);
Daniel Stone8fb6e7a2015-04-20 19:22:54 +01001136 mutex_init(&dev->mode_config.blob_lock);
Laurent Pinchart87d24fc2013-04-15 15:37:16 +02001137 INIT_LIST_HEAD(&dev->mode_config.fb_list);
1138 INIT_LIST_HEAD(&dev->mode_config.crtc_list);
1139 INIT_LIST_HEAD(&dev->mode_config.connector_list);
1140 INIT_LIST_HEAD(&dev->mode_config.encoder_list);
1141 INIT_LIST_HEAD(&dev->mode_config.property_list);
1142 INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
1143 INIT_LIST_HEAD(&dev->mode_config.plane_list);
1144 idr_init(&dev->mode_config.crtc_idr);
Dave Airlie138f9eb2014-10-20 16:17:17 +10001145 idr_init(&dev->mode_config.tile_idr);
Maarten Lankhorst5fff80b2016-02-17 08:32:05 +01001146 ida_init(&dev->mode_config.connector_ida);
Laurent Pinchart87d24fc2013-04-15 15:37:16 +02001147
1148 drm_modeset_lock_all(dev);
Rob Clark6b4959f2014-12-18 16:01:53 -05001149 drm_mode_create_standard_properties(dev);
Laurent Pinchart87d24fc2013-04-15 15:37:16 +02001150 drm_modeset_unlock_all(dev);
1151
1152 /* Just to be sure */
1153 dev->mode_config.num_fb = 0;
1154 dev->mode_config.num_connector = 0;
1155 dev->mode_config.num_crtc = 0;
1156 dev->mode_config.num_encoder = 0;
Matt Ropere27dde32014-04-01 15:22:30 -07001157 dev->mode_config.num_overlay_plane = 0;
1158 dev->mode_config.num_total_plane = 0;
Laurent Pinchart87d24fc2013-04-15 15:37:16 +02001159}
1160EXPORT_SYMBOL(drm_mode_config_init);
1161
1162/**
1163 * drm_mode_config_cleanup - free up DRM mode_config info
1164 * @dev: DRM device
1165 *
1166 * Free up all the connectors and CRTCs associated with this DRM device, then
1167 * free up the framebuffers and associated buffer objects.
1168 *
1169 * Note that since this /should/ happen single-threaded at driver/device
1170 * teardown time, no locking is required. It's the driver's job to ensure that
1171 * this guarantee actually holds true.
1172 *
1173 * FIXME: cleanup any dangling user buffer objects too
1174 */
1175void drm_mode_config_cleanup(struct drm_device *dev)
1176{
1177 struct drm_connector *connector, *ot;
1178 struct drm_crtc *crtc, *ct;
1179 struct drm_encoder *encoder, *enct;
1180 struct drm_framebuffer *fb, *fbt;
1181 struct drm_property *property, *pt;
1182 struct drm_property_blob *blob, *bt;
1183 struct drm_plane *plane, *plt;
1184
1185 list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
1186 head) {
1187 encoder->funcs->destroy(encoder);
1188 }
1189
1190 list_for_each_entry_safe(connector, ot,
1191 &dev->mode_config.connector_list, head) {
1192 connector->funcs->destroy(connector);
1193 }
1194
1195 list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
1196 head) {
1197 drm_property_destroy(dev, property);
1198 }
1199
Maarten Lankhorstf35034f2016-03-22 15:42:14 +01001200 list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
1201 head) {
1202 plane->funcs->destroy(plane);
1203 }
1204
1205 list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
1206 crtc->funcs->destroy(crtc);
1207 }
1208
Laurent Pinchart87d24fc2013-04-15 15:37:16 +02001209 list_for_each_entry_safe(blob, bt, &dev->mode_config.property_blob_list,
Daniel Stonee2f5d2e2015-05-22 13:34:51 +01001210 head_global) {
Daniel Stone6bcacf52015-04-20 19:22:55 +01001211 drm_property_unreference_blob(blob);
Laurent Pinchart87d24fc2013-04-15 15:37:16 +02001212 }
1213
1214 /*
1215 * Single-threaded teardown context, so it's not required to grab the
1216 * fb_lock to protect against concurrent fb_list access. Contrary, it
1217 * would actually deadlock with the drm_framebuffer_cleanup function.
1218 *
1219 * Also, if there are any framebuffers left, that's a driver leak now,
1220 * so politely WARN about this.
1221 */
1222 WARN_ON(!list_empty(&dev->mode_config.fb_list));
1223 list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
Dave Airlied0f37cf62016-04-15 15:10:36 +10001224 drm_framebuffer_free(&fb->base.refcount);
Laurent Pinchart87d24fc2013-04-15 15:37:16 +02001225 }
1226
Maarten Lankhorst5fff80b2016-02-17 08:32:05 +01001227 ida_destroy(&dev->mode_config.connector_ida);
Dave Airlie138f9eb2014-10-20 16:17:17 +10001228 idr_destroy(&dev->mode_config.tile_idr);
Laurent Pinchart87d24fc2013-04-15 15:37:16 +02001229 idr_destroy(&dev->mode_config.crtc_idr);
Rob Clark51fd3712013-11-19 12:10:12 -05001230 drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
Laurent Pinchart87d24fc2013-04-15 15:37:16 +02001231}
1232EXPORT_SYMBOL(drm_mode_config_cleanup);
Ville Syrjäläc1df5f32014-07-08 10:31:53 +05301233
Dave Airlie138f9eb2014-10-20 16:17:17 +10001234/**
1235 * DOC: Tile group
1236 *
1237 * Tile groups are used to represent tiled monitors with a unique
1238 * integer identifier. Tiled monitors using DisplayID v1.3 have
1239 * a unique 8-byte handle, we store this in a tile group, so we
1240 * have a common identifier for all tiles in a monitor group.
1241 */
1242static void drm_tile_group_free(struct kref *kref)
1243{
1244 struct drm_tile_group *tg = container_of(kref, struct drm_tile_group, refcount);
1245 struct drm_device *dev = tg->dev;
1246 mutex_lock(&dev->mode_config.idr_mutex);
1247 idr_remove(&dev->mode_config.tile_idr, tg->id);
1248 mutex_unlock(&dev->mode_config.idr_mutex);
1249 kfree(tg);
1250}
1251
1252/**
1253 * drm_mode_put_tile_group - drop a reference to a tile group.
1254 * @dev: DRM device
1255 * @tg: tile group to drop reference to.
1256 *
1257 * drop reference to tile group and free if 0.
1258 */
1259void drm_mode_put_tile_group(struct drm_device *dev,
1260 struct drm_tile_group *tg)
1261{
1262 kref_put(&tg->refcount, drm_tile_group_free);
1263}
1264
1265/**
1266 * drm_mode_get_tile_group - get a reference to an existing tile group
1267 * @dev: DRM device
1268 * @topology: 8-bytes unique per monitor.
1269 *
1270 * Use the unique bytes to get a reference to an existing tile group.
1271 *
1272 * RETURNS:
1273 * tile group or NULL if not found.
1274 */
1275struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,
1276 char topology[8])
1277{
1278 struct drm_tile_group *tg;
1279 int id;
1280 mutex_lock(&dev->mode_config.idr_mutex);
1281 idr_for_each_entry(&dev->mode_config.tile_idr, tg, id) {
1282 if (!memcmp(tg->group_data, topology, 8)) {
1283 if (!kref_get_unless_zero(&tg->refcount))
1284 tg = NULL;
1285 mutex_unlock(&dev->mode_config.idr_mutex);
1286 return tg;
1287 }
1288 }
1289 mutex_unlock(&dev->mode_config.idr_mutex);
1290 return NULL;
1291}
Rob Clark81ddd1b2015-03-27 13:01:52 -04001292EXPORT_SYMBOL(drm_mode_get_tile_group);
Dave Airlie138f9eb2014-10-20 16:17:17 +10001293
1294/**
1295 * drm_mode_create_tile_group - create a tile group from a displayid description
1296 * @dev: DRM device
1297 * @topology: 8-bytes unique per monitor.
1298 *
1299 * Create a tile group for the unique monitor, and get a unique
1300 * identifier for the tile group.
1301 *
1302 * RETURNS:
1303 * new tile group or error.
1304 */
1305struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
1306 char topology[8])
1307{
1308 struct drm_tile_group *tg;
1309 int ret;
1310
1311 tg = kzalloc(sizeof(*tg), GFP_KERNEL);
1312 if (!tg)
1313 return ERR_PTR(-ENOMEM);
1314
1315 kref_init(&tg->refcount);
1316 memcpy(tg->group_data, topology, 8);
1317 tg->dev = dev;
1318
1319 mutex_lock(&dev->mode_config.idr_mutex);
1320 ret = idr_alloc(&dev->mode_config.tile_idr, tg, 1, 0, GFP_KERNEL);
1321 if (ret >= 0) {
1322 tg->id = ret;
1323 } else {
1324 kfree(tg);
1325 tg = ERR_PTR(ret);
1326 }
1327
1328 mutex_unlock(&dev->mode_config.idr_mutex);
1329 return tg;
1330}
Rob Clark81ddd1b2015-03-27 13:01:52 -04001331EXPORT_SYMBOL(drm_mode_create_tile_group);