Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/gpu/drm/drm_crtc.c
26444 views
1
/*
2
* Copyright (c) 2006-2008 Intel Corporation
3
* Copyright (c) 2007 Dave Airlie <[email protected]>
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 <[email protected]>
29
* Dave Airlie <[email protected]>
30
* Jesse Barnes <[email protected]>
31
*/
32
#include <linux/ctype.h>
33
#include <linux/list.h>
34
#include <linux/slab.h>
35
#include <linux/export.h>
36
#include <linux/dma-fence.h>
37
#include <linux/uaccess.h>
38
#include <drm/drm_blend.h>
39
#include <drm/drm_crtc.h>
40
#include <drm/drm_edid.h>
41
#include <drm/drm_fourcc.h>
42
#include <drm/drm_framebuffer.h>
43
#include <drm/drm_managed.h>
44
#include <drm/drm_modeset_lock.h>
45
#include <drm/drm_atomic.h>
46
#include <drm/drm_auth.h>
47
#include <drm/drm_debugfs_crc.h>
48
#include <drm/drm_drv.h>
49
#include <drm/drm_print.h>
50
#include <drm/drm_file.h>
51
52
#include "drm_crtc_internal.h"
53
#include "drm_internal.h"
54
55
/**
56
* DOC: overview
57
*
58
* A CRTC represents the overall display pipeline. It receives pixel data from
59
* &drm_plane and blends them together. The &drm_display_mode is also attached
60
* to the CRTC, specifying display timings. On the output side the data is fed
61
* to one or more &drm_encoder, which are then each connected to one
62
* &drm_connector.
63
*
64
* To create a CRTC, a KMS driver allocates and zeroes an instance of
65
* &struct drm_crtc (possibly as part of a larger structure) and registers it
66
* with a call to drm_crtc_init_with_planes().
67
*
68
* The CRTC is also the entry point for legacy modeset operations (see
69
* &drm_crtc_funcs.set_config), legacy plane operations (see
70
* &drm_crtc_funcs.page_flip and &drm_crtc_funcs.cursor_set2), and other legacy
71
* operations like &drm_crtc_funcs.gamma_set. For atomic drivers all these
72
* features are controlled through &drm_property and
73
* &drm_mode_config_funcs.atomic_check.
74
*/
75
76
/**
77
* drm_crtc_from_index - find the registered CRTC at an index
78
* @dev: DRM device
79
* @idx: index of registered CRTC to find for
80
*
81
* Given a CRTC index, return the registered CRTC from DRM device's
82
* list of CRTCs with matching index. This is the inverse of drm_crtc_index().
83
* It's useful in the vblank callbacks (like &drm_driver.enable_vblank or
84
* &drm_driver.disable_vblank), since that still deals with indices instead
85
* of pointers to &struct drm_crtc."
86
*/
87
struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx)
88
{
89
struct drm_crtc *crtc;
90
91
drm_for_each_crtc(crtc, dev)
92
if (idx == crtc->index)
93
return crtc;
94
95
return NULL;
96
}
97
EXPORT_SYMBOL(drm_crtc_from_index);
98
99
int drm_crtc_force_disable(struct drm_crtc *crtc)
100
{
101
struct drm_mode_set set = {
102
.crtc = crtc,
103
};
104
105
WARN_ON(drm_drv_uses_atomic_modeset(crtc->dev));
106
107
return drm_mode_set_config_internal(&set);
108
}
109
110
int drm_crtc_register_all(struct drm_device *dev)
111
{
112
struct drm_crtc *crtc;
113
int ret = 0;
114
115
drm_for_each_crtc(crtc, dev) {
116
drm_debugfs_crtc_add(crtc);
117
118
if (crtc->funcs->late_register)
119
ret = crtc->funcs->late_register(crtc);
120
if (ret)
121
return ret;
122
}
123
124
return 0;
125
}
126
127
void drm_crtc_unregister_all(struct drm_device *dev)
128
{
129
struct drm_crtc *crtc;
130
131
drm_for_each_crtc(crtc, dev) {
132
if (crtc->funcs->early_unregister)
133
crtc->funcs->early_unregister(crtc);
134
drm_debugfs_crtc_remove(crtc);
135
}
136
}
137
138
static int drm_crtc_crc_init(struct drm_crtc *crtc)
139
{
140
#ifdef CONFIG_DEBUG_FS
141
spin_lock_init(&crtc->crc.lock);
142
init_waitqueue_head(&crtc->crc.wq);
143
crtc->crc.source = kstrdup("auto", GFP_KERNEL);
144
if (!crtc->crc.source)
145
return -ENOMEM;
146
#endif
147
return 0;
148
}
149
150
static void drm_crtc_crc_fini(struct drm_crtc *crtc)
151
{
152
#ifdef CONFIG_DEBUG_FS
153
kfree(crtc->crc.source);
154
#endif
155
}
156
157
static const struct dma_fence_ops drm_crtc_fence_ops;
158
159
static struct drm_crtc *fence_to_crtc(struct dma_fence *fence)
160
{
161
BUG_ON(fence->ops != &drm_crtc_fence_ops);
162
return container_of(fence->lock, struct drm_crtc, fence_lock);
163
}
164
165
static const char *drm_crtc_fence_get_driver_name(struct dma_fence *fence)
166
{
167
struct drm_crtc *crtc = fence_to_crtc(fence);
168
169
return crtc->dev->driver->name;
170
}
171
172
static const char *drm_crtc_fence_get_timeline_name(struct dma_fence *fence)
173
{
174
struct drm_crtc *crtc = fence_to_crtc(fence);
175
176
return crtc->timeline_name;
177
}
178
179
static const struct dma_fence_ops drm_crtc_fence_ops = {
180
.get_driver_name = drm_crtc_fence_get_driver_name,
181
.get_timeline_name = drm_crtc_fence_get_timeline_name,
182
};
183
184
struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc)
185
{
186
struct dma_fence *fence;
187
188
fence = kzalloc(sizeof(*fence), GFP_KERNEL);
189
if (!fence)
190
return NULL;
191
192
dma_fence_init(fence, &drm_crtc_fence_ops, &crtc->fence_lock,
193
crtc->fence_context, ++crtc->fence_seqno);
194
195
return fence;
196
}
197
198
/**
199
* DOC: standard CRTC properties
200
*
201
* DRM CRTCs have a few standardized properties:
202
*
203
* ACTIVE:
204
* Atomic property for setting the power state of the CRTC. When set to 1
205
* the CRTC will actively display content. When set to 0 the CRTC will be
206
* powered off. There is no expectation that user-space will reset CRTC
207
* resources like the mode and planes when setting ACTIVE to 0.
208
*
209
* User-space can rely on an ACTIVE change to 1 to never fail an atomic
210
* test as long as no other property has changed. If a change to ACTIVE
211
* fails an atomic test, this is a driver bug. For this reason setting
212
* ACTIVE to 0 must not release internal resources (like reserved memory
213
* bandwidth or clock generators).
214
*
215
* Note that the legacy DPMS property on connectors is internally routed
216
* to control this property for atomic drivers.
217
* MODE_ID:
218
* Atomic property for setting the CRTC display timings. The value is the
219
* ID of a blob containing the DRM mode info. To disable the CRTC,
220
* user-space must set this property to 0.
221
*
222
* Setting MODE_ID to 0 will release reserved resources for the CRTC.
223
* SCALING_FILTER:
224
* Atomic property for setting the scaling filter for CRTC scaler
225
*
226
* The value of this property can be one of the following:
227
*
228
* Default:
229
* Driver's default scaling filter
230
* Nearest Neighbor:
231
* Nearest Neighbor scaling filter
232
*/
233
234
__printf(6, 0)
235
static int __drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
236
struct drm_plane *primary,
237
struct drm_plane *cursor,
238
const struct drm_crtc_funcs *funcs,
239
const char *name, va_list ap)
240
{
241
struct drm_mode_config *config = &dev->mode_config;
242
int ret;
243
244
WARN_ON(primary && primary->type != DRM_PLANE_TYPE_PRIMARY);
245
WARN_ON(cursor && cursor->type != DRM_PLANE_TYPE_CURSOR);
246
247
/* crtc index is used with 32bit bitmasks */
248
if (WARN_ON(config->num_crtc >= 32))
249
return -EINVAL;
250
251
WARN_ON(drm_drv_uses_atomic_modeset(dev) &&
252
(!funcs->atomic_destroy_state ||
253
!funcs->atomic_duplicate_state));
254
255
crtc->dev = dev;
256
crtc->funcs = funcs;
257
258
INIT_LIST_HEAD(&crtc->commit_list);
259
spin_lock_init(&crtc->commit_lock);
260
261
drm_modeset_lock_init(&crtc->mutex);
262
ret = drm_mode_object_add(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
263
if (ret)
264
return ret;
265
266
if (name) {
267
crtc->name = kvasprintf(GFP_KERNEL, name, ap);
268
} else {
269
crtc->name = kasprintf(GFP_KERNEL, "crtc-%d", config->num_crtc);
270
}
271
if (!crtc->name) {
272
drm_mode_object_unregister(dev, &crtc->base);
273
return -ENOMEM;
274
}
275
276
crtc->fence_context = dma_fence_context_alloc(1);
277
spin_lock_init(&crtc->fence_lock);
278
snprintf(crtc->timeline_name, sizeof(crtc->timeline_name),
279
"CRTC:%d-%s", crtc->base.id, crtc->name);
280
281
crtc->base.properties = &crtc->properties;
282
283
list_add_tail(&crtc->head, &config->crtc_list);
284
crtc->index = config->num_crtc++;
285
286
crtc->primary = primary;
287
crtc->cursor = cursor;
288
if (primary && !primary->possible_crtcs)
289
primary->possible_crtcs = drm_crtc_mask(crtc);
290
if (cursor && !cursor->possible_crtcs)
291
cursor->possible_crtcs = drm_crtc_mask(crtc);
292
293
ret = drm_crtc_crc_init(crtc);
294
if (ret) {
295
drm_mode_object_unregister(dev, &crtc->base);
296
return ret;
297
}
298
299
if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
300
drm_object_attach_property(&crtc->base, config->prop_active, 0);
301
drm_object_attach_property(&crtc->base, config->prop_mode_id, 0);
302
drm_object_attach_property(&crtc->base,
303
config->prop_out_fence_ptr, 0);
304
drm_object_attach_property(&crtc->base,
305
config->prop_vrr_enabled, 0);
306
}
307
308
return 0;
309
}
310
311
/**
312
* drm_crtc_init_with_planes - Initialise a new CRTC object with
313
* specified primary and cursor planes.
314
* @dev: DRM device
315
* @crtc: CRTC object to init
316
* @primary: Primary plane for CRTC
317
* @cursor: Cursor plane for CRTC
318
* @funcs: callbacks for the new CRTC
319
* @name: printf style format string for the CRTC name, or NULL for default name
320
*
321
* Inits a new object created as base part of a driver crtc object. Drivers
322
* should use this function instead of drm_crtc_init(), which is only provided
323
* for backwards compatibility with drivers which do not yet support universal
324
* planes). For really simple hardware which has only 1 plane look at
325
* drm_simple_display_pipe_init() instead.
326
* The &drm_crtc_funcs.destroy hook should call drm_crtc_cleanup() and kfree()
327
* the crtc structure. The crtc structure should not be allocated with
328
* devm_kzalloc().
329
*
330
* The @primary and @cursor planes are only relevant for legacy uAPI, see
331
* &drm_crtc.primary and &drm_crtc.cursor.
332
*
333
* Note: consider using drmm_crtc_alloc_with_planes() or
334
* drmm_crtc_init_with_planes() instead of drm_crtc_init_with_planes()
335
* to let the DRM managed resource infrastructure take care of cleanup
336
* and deallocation.
337
*
338
* Returns:
339
* Zero on success, error code on failure.
340
*/
341
int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
342
struct drm_plane *primary,
343
struct drm_plane *cursor,
344
const struct drm_crtc_funcs *funcs,
345
const char *name, ...)
346
{
347
va_list ap;
348
int ret;
349
350
WARN_ON(!funcs->destroy);
351
352
va_start(ap, name);
353
ret = __drm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs,
354
name, ap);
355
va_end(ap);
356
357
return ret;
358
}
359
EXPORT_SYMBOL(drm_crtc_init_with_planes);
360
361
static void drmm_crtc_init_with_planes_cleanup(struct drm_device *dev,
362
void *ptr)
363
{
364
struct drm_crtc *crtc = ptr;
365
366
drm_crtc_cleanup(crtc);
367
}
368
369
__printf(6, 0)
370
static int __drmm_crtc_init_with_planes(struct drm_device *dev,
371
struct drm_crtc *crtc,
372
struct drm_plane *primary,
373
struct drm_plane *cursor,
374
const struct drm_crtc_funcs *funcs,
375
const char *name,
376
va_list args)
377
{
378
int ret;
379
380
drm_WARN_ON(dev, funcs && funcs->destroy);
381
382
ret = __drm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs,
383
name, args);
384
if (ret)
385
return ret;
386
387
ret = drmm_add_action_or_reset(dev, drmm_crtc_init_with_planes_cleanup,
388
crtc);
389
if (ret)
390
return ret;
391
392
return 0;
393
}
394
395
/**
396
* drmm_crtc_init_with_planes - Initialise a new CRTC object with
397
* specified primary and cursor planes.
398
* @dev: DRM device
399
* @crtc: CRTC object to init
400
* @primary: Primary plane for CRTC
401
* @cursor: Cursor plane for CRTC
402
* @funcs: callbacks for the new CRTC
403
* @name: printf style format string for the CRTC name, or NULL for default name
404
*
405
* Inits a new object created as base part of a driver crtc object. Drivers
406
* should use this function instead of drm_crtc_init(), which is only provided
407
* for backwards compatibility with drivers which do not yet support universal
408
* planes). For really simple hardware which has only 1 plane look at
409
* drm_simple_display_pipe_init() instead.
410
*
411
* Cleanup is automatically handled through registering
412
* drmm_crtc_cleanup() with drmm_add_action(). The crtc structure should
413
* be allocated with drmm_kzalloc().
414
*
415
* The @drm_crtc_funcs.destroy hook must be NULL.
416
*
417
* The @primary and @cursor planes are only relevant for legacy uAPI, see
418
* &drm_crtc.primary and &drm_crtc.cursor.
419
*
420
* Returns:
421
* Zero on success, error code on failure.
422
*/
423
int drmm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
424
struct drm_plane *primary,
425
struct drm_plane *cursor,
426
const struct drm_crtc_funcs *funcs,
427
const char *name, ...)
428
{
429
va_list ap;
430
int ret;
431
432
va_start(ap, name);
433
ret = __drmm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs,
434
name, ap);
435
va_end(ap);
436
if (ret)
437
return ret;
438
439
return 0;
440
}
441
EXPORT_SYMBOL(drmm_crtc_init_with_planes);
442
443
void *__drmm_crtc_alloc_with_planes(struct drm_device *dev,
444
size_t size, size_t offset,
445
struct drm_plane *primary,
446
struct drm_plane *cursor,
447
const struct drm_crtc_funcs *funcs,
448
const char *name, ...)
449
{
450
void *container;
451
struct drm_crtc *crtc;
452
va_list ap;
453
int ret;
454
455
if (WARN_ON(!funcs || funcs->destroy))
456
return ERR_PTR(-EINVAL);
457
458
container = drmm_kzalloc(dev, size, GFP_KERNEL);
459
if (!container)
460
return ERR_PTR(-ENOMEM);
461
462
crtc = container + offset;
463
464
va_start(ap, name);
465
ret = __drmm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs,
466
name, ap);
467
va_end(ap);
468
if (ret)
469
return ERR_PTR(ret);
470
471
return container;
472
}
473
EXPORT_SYMBOL(__drmm_crtc_alloc_with_planes);
474
475
/**
476
* drm_crtc_cleanup - Clean up the core crtc usage
477
* @crtc: CRTC to cleanup
478
*
479
* This function cleans up @crtc and removes it from the DRM mode setting
480
* core. Note that the function does *not* free the crtc structure itself,
481
* this is the responsibility of the caller.
482
*/
483
void drm_crtc_cleanup(struct drm_crtc *crtc)
484
{
485
struct drm_device *dev = crtc->dev;
486
487
/* Note that the crtc_list is considered to be static; should we
488
* remove the drm_crtc at runtime we would have to decrement all
489
* the indices on the drm_crtc after us in the crtc_list.
490
*/
491
492
drm_crtc_crc_fini(crtc);
493
494
kfree(crtc->gamma_store);
495
crtc->gamma_store = NULL;
496
497
drm_modeset_lock_fini(&crtc->mutex);
498
499
drm_mode_object_unregister(dev, &crtc->base);
500
list_del(&crtc->head);
501
dev->mode_config.num_crtc--;
502
503
WARN_ON(crtc->state && !crtc->funcs->atomic_destroy_state);
504
if (crtc->state && crtc->funcs->atomic_destroy_state)
505
crtc->funcs->atomic_destroy_state(crtc, crtc->state);
506
507
kfree(crtc->name);
508
509
memset(crtc, 0, sizeof(*crtc));
510
}
511
EXPORT_SYMBOL(drm_crtc_cleanup);
512
513
/**
514
* drm_mode_getcrtc - get CRTC configuration
515
* @dev: drm device for the ioctl
516
* @data: data pointer for the ioctl
517
* @file_priv: drm file for the ioctl call
518
*
519
* Construct a CRTC configuration structure to return to the user.
520
*
521
* Called by the user via ioctl.
522
*
523
* Returns:
524
* Zero on success, negative errno on failure.
525
*/
526
int drm_mode_getcrtc(struct drm_device *dev,
527
void *data, struct drm_file *file_priv)
528
{
529
struct drm_mode_crtc *crtc_resp = data;
530
struct drm_crtc *crtc;
531
struct drm_plane *plane;
532
533
if (!drm_core_check_feature(dev, DRIVER_MODESET))
534
return -EOPNOTSUPP;
535
536
crtc = drm_crtc_find(dev, file_priv, crtc_resp->crtc_id);
537
if (!crtc)
538
return -ENOENT;
539
540
plane = crtc->primary;
541
542
crtc_resp->gamma_size = crtc->gamma_size;
543
544
drm_modeset_lock(&plane->mutex, NULL);
545
if (plane->state && plane->state->fb)
546
crtc_resp->fb_id = plane->state->fb->base.id;
547
else if (!plane->state && plane->fb)
548
crtc_resp->fb_id = plane->fb->base.id;
549
else
550
crtc_resp->fb_id = 0;
551
552
if (plane->state) {
553
crtc_resp->x = plane->state->src_x >> 16;
554
crtc_resp->y = plane->state->src_y >> 16;
555
}
556
drm_modeset_unlock(&plane->mutex);
557
558
drm_modeset_lock(&crtc->mutex, NULL);
559
if (crtc->state) {
560
if (crtc->state->enable) {
561
drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->state->mode);
562
crtc_resp->mode_valid = 1;
563
} else {
564
crtc_resp->mode_valid = 0;
565
}
566
} else {
567
crtc_resp->x = crtc->x;
568
crtc_resp->y = crtc->y;
569
570
if (crtc->enabled) {
571
drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->mode);
572
crtc_resp->mode_valid = 1;
573
574
} else {
575
crtc_resp->mode_valid = 0;
576
}
577
}
578
if (!file_priv->aspect_ratio_allowed)
579
crtc_resp->mode.flags &= ~DRM_MODE_FLAG_PIC_AR_MASK;
580
drm_modeset_unlock(&crtc->mutex);
581
582
return 0;
583
}
584
585
static int __drm_mode_set_config_internal(struct drm_mode_set *set,
586
struct drm_modeset_acquire_ctx *ctx)
587
{
588
struct drm_crtc *crtc = set->crtc;
589
struct drm_framebuffer *fb;
590
struct drm_crtc *tmp;
591
int ret;
592
593
WARN_ON(drm_drv_uses_atomic_modeset(crtc->dev));
594
595
/*
596
* NOTE: ->set_config can also disable other crtcs (if we steal all
597
* connectors from it), hence we need to refcount the fbs across all
598
* crtcs. Atomic modeset will have saner semantics ...
599
*/
600
drm_for_each_crtc(tmp, crtc->dev) {
601
struct drm_plane *plane = tmp->primary;
602
603
plane->old_fb = plane->fb;
604
}
605
606
fb = set->fb;
607
608
ret = crtc->funcs->set_config(set, ctx);
609
if (ret == 0) {
610
struct drm_plane *plane = crtc->primary;
611
612
plane->crtc = fb ? crtc : NULL;
613
plane->fb = fb;
614
}
615
616
drm_for_each_crtc(tmp, crtc->dev) {
617
struct drm_plane *plane = tmp->primary;
618
619
if (plane->fb)
620
drm_framebuffer_get(plane->fb);
621
if (plane->old_fb)
622
drm_framebuffer_put(plane->old_fb);
623
plane->old_fb = NULL;
624
}
625
626
return ret;
627
}
628
629
/**
630
* drm_mode_set_config_internal - helper to call &drm_mode_config_funcs.set_config
631
* @set: modeset config to set
632
*
633
* This is a little helper to wrap internal calls to the
634
* &drm_mode_config_funcs.set_config driver interface. The only thing it adds is
635
* correct refcounting dance.
636
*
637
* This should only be used by non-atomic legacy drivers.
638
*
639
* Returns:
640
* Zero on success, negative errno on failure.
641
*/
642
int drm_mode_set_config_internal(struct drm_mode_set *set)
643
{
644
WARN_ON(drm_drv_uses_atomic_modeset(set->crtc->dev));
645
646
return __drm_mode_set_config_internal(set, NULL);
647
}
648
EXPORT_SYMBOL(drm_mode_set_config_internal);
649
650
/**
651
* drm_crtc_check_viewport - Checks that a framebuffer is big enough for the
652
* CRTC viewport
653
* @crtc: CRTC that framebuffer will be displayed on
654
* @x: x panning
655
* @y: y panning
656
* @mode: mode that framebuffer will be displayed under
657
* @fb: framebuffer to check size of
658
*/
659
int drm_crtc_check_viewport(const struct drm_crtc *crtc,
660
int x, int y,
661
const struct drm_display_mode *mode,
662
const struct drm_framebuffer *fb)
663
664
{
665
int hdisplay, vdisplay;
666
667
drm_mode_get_hv_timing(mode, &hdisplay, &vdisplay);
668
669
if (crtc->state &&
670
drm_rotation_90_or_270(crtc->primary->state->rotation))
671
swap(hdisplay, vdisplay);
672
673
return drm_framebuffer_check_src_coords(x << 16, y << 16,
674
hdisplay << 16, vdisplay << 16,
675
fb);
676
}
677
EXPORT_SYMBOL(drm_crtc_check_viewport);
678
679
/**
680
* drm_mode_setcrtc - set CRTC configuration
681
* @dev: drm device for the ioctl
682
* @data: data pointer for the ioctl
683
* @file_priv: drm file for the ioctl call
684
*
685
* Build a new CRTC configuration based on user request.
686
*
687
* Called by the user via ioctl.
688
*
689
* Returns:
690
* Zero on success, negative errno on failure.
691
*/
692
int drm_mode_setcrtc(struct drm_device *dev, void *data,
693
struct drm_file *file_priv)
694
{
695
struct drm_mode_config *config = &dev->mode_config;
696
struct drm_mode_crtc *crtc_req = data;
697
struct drm_crtc *crtc;
698
struct drm_plane *plane;
699
struct drm_connector **connector_set = NULL, *connector;
700
struct drm_framebuffer *fb = NULL;
701
struct drm_display_mode *mode = NULL;
702
struct drm_mode_set set;
703
uint32_t __user *set_connectors_ptr;
704
struct drm_modeset_acquire_ctx ctx;
705
int ret, i, num_connectors = 0;
706
707
if (!drm_core_check_feature(dev, DRIVER_MODESET))
708
return -EOPNOTSUPP;
709
710
/*
711
* Universal plane src offsets are only 16.16, prevent havoc for
712
* drivers using universal plane code internally.
713
*/
714
if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
715
return -ERANGE;
716
717
crtc = drm_crtc_find(dev, file_priv, crtc_req->crtc_id);
718
if (!crtc) {
719
drm_dbg_kms(dev, "Unknown CRTC ID %d\n", crtc_req->crtc_id);
720
return -ENOENT;
721
}
722
drm_dbg_kms(dev, "[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
723
724
plane = crtc->primary;
725
726
/* allow disabling with the primary plane leased */
727
if (crtc_req->mode_valid && !drm_lease_held(file_priv, plane->base.id))
728
return -EACCES;
729
730
DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx,
731
DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret);
732
733
if (crtc_req->mode_valid) {
734
/* If we have a mode we need a framebuffer. */
735
/* If we pass -1, set the mode with the currently bound fb */
736
if (crtc_req->fb_id == -1) {
737
struct drm_framebuffer *old_fb;
738
739
if (plane->state)
740
old_fb = plane->state->fb;
741
else
742
old_fb = plane->fb;
743
744
if (!old_fb) {
745
drm_dbg_kms(dev, "CRTC doesn't have current FB\n");
746
ret = -EINVAL;
747
goto out;
748
}
749
750
fb = old_fb;
751
/* Make refcounting symmetric with the lookup path. */
752
drm_framebuffer_get(fb);
753
} else {
754
fb = drm_framebuffer_lookup(dev, file_priv, crtc_req->fb_id);
755
if (!fb) {
756
drm_dbg_kms(dev, "Unknown FB ID%d\n",
757
crtc_req->fb_id);
758
ret = -ENOENT;
759
goto out;
760
}
761
}
762
763
mode = drm_mode_create(dev);
764
if (!mode) {
765
ret = -ENOMEM;
766
goto out;
767
}
768
if (!file_priv->aspect_ratio_allowed &&
769
(crtc_req->mode.flags & DRM_MODE_FLAG_PIC_AR_MASK) != DRM_MODE_FLAG_PIC_AR_NONE) {
770
drm_dbg_kms(dev, "Unexpected aspect-ratio flag bits\n");
771
ret = -EINVAL;
772
goto out;
773
}
774
775
776
ret = drm_mode_convert_umode(dev, mode, &crtc_req->mode);
777
if (ret) {
778
drm_dbg_kms(dev, "Invalid mode (%s, %pe): " DRM_MODE_FMT "\n",
779
drm_get_mode_status_name(mode->status),
780
ERR_PTR(ret), DRM_MODE_ARG(mode));
781
goto out;
782
}
783
784
/*
785
* Check whether the primary plane supports the fb pixel format.
786
* Drivers not implementing the universal planes API use a
787
* default formats list provided by the DRM core which doesn't
788
* match real hardware capabilities. Skip the check in that
789
* case.
790
*/
791
if (!plane->format_default) {
792
if (!drm_plane_has_format(plane, fb->format->format, fb->modifier)) {
793
drm_dbg_kms(dev, "Invalid pixel format %p4cc, modifier 0x%llx\n",
794
&fb->format->format, fb->modifier);
795
ret = -EINVAL;
796
goto out;
797
}
798
}
799
800
ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,
801
mode, fb);
802
if (ret)
803
goto out;
804
805
}
806
807
if (crtc_req->count_connectors == 0 && mode) {
808
drm_dbg_kms(dev, "Count connectors is 0 but mode set\n");
809
ret = -EINVAL;
810
goto out;
811
}
812
813
if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
814
drm_dbg_kms(dev, "Count connectors is %d but no mode or fb set\n",
815
crtc_req->count_connectors);
816
ret = -EINVAL;
817
goto out;
818
}
819
820
if (crtc_req->count_connectors > 0) {
821
u32 out_id;
822
823
/* Avoid unbounded kernel memory allocation */
824
if (crtc_req->count_connectors > config->num_connector) {
825
ret = -EINVAL;
826
goto out;
827
}
828
829
connector_set = kmalloc_array(crtc_req->count_connectors,
830
sizeof(struct drm_connector *),
831
GFP_KERNEL);
832
if (!connector_set) {
833
ret = -ENOMEM;
834
goto out;
835
}
836
837
for (i = 0; i < crtc_req->count_connectors; i++) {
838
connector_set[i] = NULL;
839
set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr;
840
if (get_user(out_id, &set_connectors_ptr[i])) {
841
ret = -EFAULT;
842
goto out;
843
}
844
845
connector = drm_connector_lookup(dev, file_priv, out_id);
846
if (!connector) {
847
drm_dbg_kms(dev, "Connector id %d unknown\n",
848
out_id);
849
ret = -ENOENT;
850
goto out;
851
}
852
drm_dbg_kms(dev, "[CONNECTOR:%d:%s]\n",
853
connector->base.id, connector->name);
854
855
connector_set[i] = connector;
856
num_connectors++;
857
}
858
}
859
860
set.crtc = crtc;
861
set.x = crtc_req->x;
862
set.y = crtc_req->y;
863
set.mode = mode;
864
set.connectors = connector_set;
865
set.num_connectors = num_connectors;
866
set.fb = fb;
867
868
if (drm_drv_uses_atomic_modeset(dev))
869
ret = crtc->funcs->set_config(&set, &ctx);
870
else
871
ret = __drm_mode_set_config_internal(&set, &ctx);
872
873
out:
874
if (fb)
875
drm_framebuffer_put(fb);
876
877
if (connector_set) {
878
for (i = 0; i < num_connectors; i++) {
879
if (connector_set[i])
880
drm_connector_put(connector_set[i]);
881
}
882
}
883
kfree(connector_set);
884
drm_mode_destroy(dev, mode);
885
886
/* In case we need to retry... */
887
connector_set = NULL;
888
fb = NULL;
889
mode = NULL;
890
num_connectors = 0;
891
892
DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
893
894
return ret;
895
}
896
897
int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
898
struct drm_property *property,
899
uint64_t value)
900
{
901
int ret = -EINVAL;
902
struct drm_crtc *crtc = obj_to_crtc(obj);
903
904
if (crtc->funcs->set_property)
905
ret = crtc->funcs->set_property(crtc, property, value);
906
if (!ret)
907
drm_object_property_set_value(obj, property, value);
908
909
return ret;
910
}
911
912
/**
913
* drm_crtc_create_scaling_filter_property - create a new scaling filter
914
* property
915
*
916
* @crtc: drm CRTC
917
* @supported_filters: bitmask of supported scaling filters, must include
918
* BIT(DRM_SCALING_FILTER_DEFAULT).
919
*
920
* This function lets driver to enable the scaling filter property on a given
921
* CRTC.
922
*
923
* RETURNS:
924
* Zero for success or -errno
925
*/
926
int drm_crtc_create_scaling_filter_property(struct drm_crtc *crtc,
927
unsigned int supported_filters)
928
{
929
struct drm_property *prop =
930
drm_create_scaling_filter_prop(crtc->dev, supported_filters);
931
932
if (IS_ERR(prop))
933
return PTR_ERR(prop);
934
935
drm_object_attach_property(&crtc->base, prop,
936
DRM_SCALING_FILTER_DEFAULT);
937
crtc->scaling_filter_property = prop;
938
939
return 0;
940
}
941
EXPORT_SYMBOL(drm_crtc_create_scaling_filter_property);
942
943
/**
944
* drm_crtc_in_clone_mode - check if the given CRTC state is in clone mode
945
*
946
* @crtc_state: CRTC state to check
947
*
948
* This function determines if the given CRTC state is being cloned by multiple
949
* encoders.
950
*
951
* RETURNS:
952
* True if the CRTC state is in clone mode. False otherwise
953
*/
954
bool drm_crtc_in_clone_mode(struct drm_crtc_state *crtc_state)
955
{
956
if (!crtc_state)
957
return false;
958
959
return hweight32(crtc_state->encoder_mask) > 1;
960
}
961
EXPORT_SYMBOL(drm_crtc_in_clone_mode);
962
963