Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/gpu/drm/drm_crtc.c
49640 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
* SHARPNESS_STRENGTH:
233
* Atomic property for setting the sharpness strength/intensity by userspace.
234
*
235
* The value of this property is set as an integer value ranging
236
* from 0 - 255 where:
237
*
238
* 0: Sharpness feature is disabled(default value).
239
*
240
* 1: Minimum sharpness.
241
*
242
* 255: Maximum sharpness.
243
*
244
* User can gradually increase or decrease the sharpness level and can
245
* set the optimum value depending on content.
246
* This value will be passed to kernel through the UAPI.
247
* The setting of this property does not require modeset.
248
* The sharpness effect takes place post blending on the final composed output.
249
* If the feature is disabled, the content remains same without any sharpening effect
250
* and when this feature is applied, it enhances the clarity of the content.
251
*/
252
253
__printf(6, 0)
254
static int __drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
255
struct drm_plane *primary,
256
struct drm_plane *cursor,
257
const struct drm_crtc_funcs *funcs,
258
const char *name, va_list ap)
259
{
260
struct drm_mode_config *config = &dev->mode_config;
261
int ret;
262
263
WARN_ON(primary && primary->type != DRM_PLANE_TYPE_PRIMARY);
264
WARN_ON(cursor && cursor->type != DRM_PLANE_TYPE_CURSOR);
265
266
/* crtc index is used with 32bit bitmasks */
267
if (WARN_ON(config->num_crtc >= 32))
268
return -EINVAL;
269
270
WARN_ON(drm_drv_uses_atomic_modeset(dev) &&
271
(!funcs->atomic_destroy_state ||
272
!funcs->atomic_duplicate_state));
273
274
crtc->dev = dev;
275
crtc->funcs = funcs;
276
277
INIT_LIST_HEAD(&crtc->commit_list);
278
spin_lock_init(&crtc->commit_lock);
279
280
drm_modeset_lock_init(&crtc->mutex);
281
ret = drm_mode_object_add(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
282
if (ret)
283
return ret;
284
285
if (name) {
286
crtc->name = kvasprintf(GFP_KERNEL, name, ap);
287
} else {
288
crtc->name = kasprintf(GFP_KERNEL, "crtc-%d", config->num_crtc);
289
}
290
if (!crtc->name) {
291
drm_mode_object_unregister(dev, &crtc->base);
292
return -ENOMEM;
293
}
294
295
crtc->fence_context = dma_fence_context_alloc(1);
296
spin_lock_init(&crtc->fence_lock);
297
snprintf(crtc->timeline_name, sizeof(crtc->timeline_name),
298
"CRTC:%d-%s", crtc->base.id, crtc->name);
299
300
crtc->base.properties = &crtc->properties;
301
302
list_add_tail(&crtc->head, &config->crtc_list);
303
crtc->index = config->num_crtc++;
304
305
crtc->primary = primary;
306
crtc->cursor = cursor;
307
if (primary && !primary->possible_crtcs)
308
primary->possible_crtcs = drm_crtc_mask(crtc);
309
if (cursor && !cursor->possible_crtcs)
310
cursor->possible_crtcs = drm_crtc_mask(crtc);
311
312
ret = drm_crtc_crc_init(crtc);
313
if (ret) {
314
drm_mode_object_unregister(dev, &crtc->base);
315
return ret;
316
}
317
318
if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
319
drm_object_attach_property(&crtc->base, config->prop_active, 0);
320
drm_object_attach_property(&crtc->base, config->prop_mode_id, 0);
321
drm_object_attach_property(&crtc->base,
322
config->prop_out_fence_ptr, 0);
323
drm_object_attach_property(&crtc->base,
324
config->prop_vrr_enabled, 0);
325
}
326
327
return 0;
328
}
329
330
/**
331
* drm_crtc_init_with_planes - Initialise a new CRTC object with
332
* specified primary and cursor planes.
333
* @dev: DRM device
334
* @crtc: CRTC object to init
335
* @primary: Primary plane for CRTC
336
* @cursor: Cursor plane for CRTC
337
* @funcs: callbacks for the new CRTC
338
* @name: printf style format string for the CRTC name, or NULL for default name
339
*
340
* Inits a new object created as base part of a driver crtc object. Drivers
341
* should use this function instead of drm_crtc_init(), which is only provided
342
* for backwards compatibility with drivers which do not yet support universal
343
* planes). For really simple hardware which has only 1 plane look at
344
* drm_simple_display_pipe_init() instead.
345
* The &drm_crtc_funcs.destroy hook should call drm_crtc_cleanup() and kfree()
346
* the crtc structure. The crtc structure should not be allocated with
347
* devm_kzalloc().
348
*
349
* The @primary and @cursor planes are only relevant for legacy uAPI, see
350
* &drm_crtc.primary and &drm_crtc.cursor.
351
*
352
* Note: consider using drmm_crtc_alloc_with_planes() or
353
* drmm_crtc_init_with_planes() instead of drm_crtc_init_with_planes()
354
* to let the DRM managed resource infrastructure take care of cleanup
355
* and deallocation.
356
*
357
* Returns:
358
* Zero on success, error code on failure.
359
*/
360
int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
361
struct drm_plane *primary,
362
struct drm_plane *cursor,
363
const struct drm_crtc_funcs *funcs,
364
const char *name, ...)
365
{
366
va_list ap;
367
int ret;
368
369
WARN_ON(!funcs->destroy);
370
371
va_start(ap, name);
372
ret = __drm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs,
373
name, ap);
374
va_end(ap);
375
376
return ret;
377
}
378
EXPORT_SYMBOL(drm_crtc_init_with_planes);
379
380
static void drmm_crtc_init_with_planes_cleanup(struct drm_device *dev,
381
void *ptr)
382
{
383
struct drm_crtc *crtc = ptr;
384
385
drm_crtc_cleanup(crtc);
386
}
387
388
__printf(6, 0)
389
static int __drmm_crtc_init_with_planes(struct drm_device *dev,
390
struct drm_crtc *crtc,
391
struct drm_plane *primary,
392
struct drm_plane *cursor,
393
const struct drm_crtc_funcs *funcs,
394
const char *name,
395
va_list args)
396
{
397
int ret;
398
399
drm_WARN_ON(dev, funcs && funcs->destroy);
400
401
ret = __drm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs,
402
name, args);
403
if (ret)
404
return ret;
405
406
ret = drmm_add_action_or_reset(dev, drmm_crtc_init_with_planes_cleanup,
407
crtc);
408
if (ret)
409
return ret;
410
411
return 0;
412
}
413
414
/**
415
* drmm_crtc_init_with_planes - Initialise a new CRTC object with
416
* specified primary and cursor planes.
417
* @dev: DRM device
418
* @crtc: CRTC object to init
419
* @primary: Primary plane for CRTC
420
* @cursor: Cursor plane for CRTC
421
* @funcs: callbacks for the new CRTC
422
* @name: printf style format string for the CRTC name, or NULL for default name
423
*
424
* Inits a new object created as base part of a driver crtc object. Drivers
425
* should use this function instead of drm_crtc_init(), which is only provided
426
* for backwards compatibility with drivers which do not yet support universal
427
* planes). For really simple hardware which has only 1 plane look at
428
* drm_simple_display_pipe_init() instead.
429
*
430
* Cleanup is automatically handled through registering
431
* drmm_crtc_cleanup() with drmm_add_action(). The crtc structure should
432
* be allocated with drmm_kzalloc().
433
*
434
* The @drm_crtc_funcs.destroy hook must be NULL.
435
*
436
* The @primary and @cursor planes are only relevant for legacy uAPI, see
437
* &drm_crtc.primary and &drm_crtc.cursor.
438
*
439
* Returns:
440
* Zero on success, error code on failure.
441
*/
442
int drmm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
443
struct drm_plane *primary,
444
struct drm_plane *cursor,
445
const struct drm_crtc_funcs *funcs,
446
const char *name, ...)
447
{
448
va_list ap;
449
int ret;
450
451
va_start(ap, name);
452
ret = __drmm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs,
453
name, ap);
454
va_end(ap);
455
if (ret)
456
return ret;
457
458
return 0;
459
}
460
EXPORT_SYMBOL(drmm_crtc_init_with_planes);
461
462
void *__drmm_crtc_alloc_with_planes(struct drm_device *dev,
463
size_t size, size_t offset,
464
struct drm_plane *primary,
465
struct drm_plane *cursor,
466
const struct drm_crtc_funcs *funcs,
467
const char *name, ...)
468
{
469
void *container;
470
struct drm_crtc *crtc;
471
va_list ap;
472
int ret;
473
474
if (WARN_ON(!funcs || funcs->destroy))
475
return ERR_PTR(-EINVAL);
476
477
container = drmm_kzalloc(dev, size, GFP_KERNEL);
478
if (!container)
479
return ERR_PTR(-ENOMEM);
480
481
crtc = container + offset;
482
483
va_start(ap, name);
484
ret = __drmm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs,
485
name, ap);
486
va_end(ap);
487
if (ret)
488
return ERR_PTR(ret);
489
490
return container;
491
}
492
EXPORT_SYMBOL(__drmm_crtc_alloc_with_planes);
493
494
/**
495
* drm_crtc_cleanup - Clean up the core crtc usage
496
* @crtc: CRTC to cleanup
497
*
498
* This function cleans up @crtc and removes it from the DRM mode setting
499
* core. Note that the function does *not* free the crtc structure itself,
500
* this is the responsibility of the caller.
501
*/
502
void drm_crtc_cleanup(struct drm_crtc *crtc)
503
{
504
struct drm_device *dev = crtc->dev;
505
506
/* Note that the crtc_list is considered to be static; should we
507
* remove the drm_crtc at runtime we would have to decrement all
508
* the indices on the drm_crtc after us in the crtc_list.
509
*/
510
511
drm_crtc_crc_fini(crtc);
512
513
kfree(crtc->gamma_store);
514
crtc->gamma_store = NULL;
515
516
drm_modeset_lock_fini(&crtc->mutex);
517
518
drm_mode_object_unregister(dev, &crtc->base);
519
list_del(&crtc->head);
520
dev->mode_config.num_crtc--;
521
522
WARN_ON(crtc->state && !crtc->funcs->atomic_destroy_state);
523
if (crtc->state && crtc->funcs->atomic_destroy_state)
524
crtc->funcs->atomic_destroy_state(crtc, crtc->state);
525
526
kfree(crtc->name);
527
528
memset(crtc, 0, sizeof(*crtc));
529
}
530
EXPORT_SYMBOL(drm_crtc_cleanup);
531
532
/**
533
* drm_mode_getcrtc - get CRTC configuration
534
* @dev: drm device for the ioctl
535
* @data: data pointer for the ioctl
536
* @file_priv: drm file for the ioctl call
537
*
538
* Construct a CRTC configuration structure to return to the user.
539
*
540
* Called by the user via ioctl.
541
*
542
* Returns:
543
* Zero on success, negative errno on failure.
544
*/
545
int drm_mode_getcrtc(struct drm_device *dev,
546
void *data, struct drm_file *file_priv)
547
{
548
struct drm_mode_crtc *crtc_resp = data;
549
struct drm_crtc *crtc;
550
struct drm_plane *plane;
551
552
if (!drm_core_check_feature(dev, DRIVER_MODESET))
553
return -EOPNOTSUPP;
554
555
crtc = drm_crtc_find(dev, file_priv, crtc_resp->crtc_id);
556
if (!crtc)
557
return -ENOENT;
558
559
plane = crtc->primary;
560
561
crtc_resp->gamma_size = crtc->gamma_size;
562
563
drm_modeset_lock(&plane->mutex, NULL);
564
if (plane->state && plane->state->fb)
565
crtc_resp->fb_id = plane->state->fb->base.id;
566
else if (!plane->state && plane->fb)
567
crtc_resp->fb_id = plane->fb->base.id;
568
else
569
crtc_resp->fb_id = 0;
570
571
if (plane->state) {
572
crtc_resp->x = plane->state->src_x >> 16;
573
crtc_resp->y = plane->state->src_y >> 16;
574
}
575
drm_modeset_unlock(&plane->mutex);
576
577
drm_modeset_lock(&crtc->mutex, NULL);
578
if (crtc->state) {
579
if (crtc->state->enable) {
580
drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->state->mode);
581
crtc_resp->mode_valid = 1;
582
} else {
583
crtc_resp->mode_valid = 0;
584
}
585
} else {
586
crtc_resp->x = crtc->x;
587
crtc_resp->y = crtc->y;
588
589
if (crtc->enabled) {
590
drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->mode);
591
crtc_resp->mode_valid = 1;
592
593
} else {
594
crtc_resp->mode_valid = 0;
595
}
596
}
597
if (!file_priv->aspect_ratio_allowed)
598
crtc_resp->mode.flags &= ~DRM_MODE_FLAG_PIC_AR_MASK;
599
drm_modeset_unlock(&crtc->mutex);
600
601
return 0;
602
}
603
604
static int __drm_mode_set_config_internal(struct drm_mode_set *set,
605
struct drm_modeset_acquire_ctx *ctx)
606
{
607
struct drm_crtc *crtc = set->crtc;
608
struct drm_framebuffer *fb;
609
struct drm_crtc *tmp;
610
int ret;
611
612
WARN_ON(drm_drv_uses_atomic_modeset(crtc->dev));
613
614
/*
615
* NOTE: ->set_config can also disable other crtcs (if we steal all
616
* connectors from it), hence we need to refcount the fbs across all
617
* crtcs. Atomic modeset will have saner semantics ...
618
*/
619
drm_for_each_crtc(tmp, crtc->dev) {
620
struct drm_plane *plane = tmp->primary;
621
622
plane->old_fb = plane->fb;
623
}
624
625
fb = set->fb;
626
627
ret = crtc->funcs->set_config(set, ctx);
628
if (ret == 0) {
629
struct drm_plane *plane = crtc->primary;
630
631
plane->crtc = fb ? crtc : NULL;
632
plane->fb = fb;
633
}
634
635
drm_for_each_crtc(tmp, crtc->dev) {
636
struct drm_plane *plane = tmp->primary;
637
638
if (plane->fb)
639
drm_framebuffer_get(plane->fb);
640
if (plane->old_fb)
641
drm_framebuffer_put(plane->old_fb);
642
plane->old_fb = NULL;
643
}
644
645
return ret;
646
}
647
648
/**
649
* drm_mode_set_config_internal - helper to call &drm_mode_config_funcs.set_config
650
* @set: modeset config to set
651
*
652
* This is a little helper to wrap internal calls to the
653
* &drm_mode_config_funcs.set_config driver interface. The only thing it adds is
654
* correct refcounting dance.
655
*
656
* This should only be used by non-atomic legacy drivers.
657
*
658
* Returns:
659
* Zero on success, negative errno on failure.
660
*/
661
int drm_mode_set_config_internal(struct drm_mode_set *set)
662
{
663
WARN_ON(drm_drv_uses_atomic_modeset(set->crtc->dev));
664
665
return __drm_mode_set_config_internal(set, NULL);
666
}
667
EXPORT_SYMBOL(drm_mode_set_config_internal);
668
669
/**
670
* drm_crtc_check_viewport - Checks that a framebuffer is big enough for the
671
* CRTC viewport
672
* @crtc: CRTC that framebuffer will be displayed on
673
* @x: x panning
674
* @y: y panning
675
* @mode: mode that framebuffer will be displayed under
676
* @fb: framebuffer to check size of
677
*/
678
int drm_crtc_check_viewport(const struct drm_crtc *crtc,
679
int x, int y,
680
const struct drm_display_mode *mode,
681
const struct drm_framebuffer *fb)
682
683
{
684
int hdisplay, vdisplay;
685
686
drm_mode_get_hv_timing(mode, &hdisplay, &vdisplay);
687
688
if (crtc->state &&
689
drm_rotation_90_or_270(crtc->primary->state->rotation))
690
swap(hdisplay, vdisplay);
691
692
return drm_framebuffer_check_src_coords(x << 16, y << 16,
693
hdisplay << 16, vdisplay << 16,
694
fb);
695
}
696
EXPORT_SYMBOL(drm_crtc_check_viewport);
697
698
/**
699
* drm_mode_setcrtc - set CRTC configuration
700
* @dev: drm device for the ioctl
701
* @data: data pointer for the ioctl
702
* @file_priv: drm file for the ioctl call
703
*
704
* Build a new CRTC configuration based on user request.
705
*
706
* Called by the user via ioctl.
707
*
708
* Returns:
709
* Zero on success, negative errno on failure.
710
*/
711
int drm_mode_setcrtc(struct drm_device *dev, void *data,
712
struct drm_file *file_priv)
713
{
714
struct drm_mode_config *config = &dev->mode_config;
715
struct drm_mode_crtc *crtc_req = data;
716
struct drm_crtc *crtc;
717
struct drm_plane *plane;
718
struct drm_connector **connector_set = NULL, *connector;
719
struct drm_framebuffer *fb = NULL;
720
struct drm_display_mode *mode = NULL;
721
struct drm_mode_set set;
722
uint32_t __user *set_connectors_ptr;
723
struct drm_modeset_acquire_ctx ctx;
724
int ret, i, num_connectors = 0;
725
726
if (!drm_core_check_feature(dev, DRIVER_MODESET))
727
return -EOPNOTSUPP;
728
729
/*
730
* Universal plane src offsets are only 16.16, prevent havoc for
731
* drivers using universal plane code internally.
732
*/
733
if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
734
return -ERANGE;
735
736
crtc = drm_crtc_find(dev, file_priv, crtc_req->crtc_id);
737
if (!crtc) {
738
drm_dbg_kms(dev, "Unknown CRTC ID %d\n", crtc_req->crtc_id);
739
return -ENOENT;
740
}
741
drm_dbg_kms(dev, "[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
742
743
plane = crtc->primary;
744
745
/* allow disabling with the primary plane leased */
746
if (crtc_req->mode_valid && !drm_lease_held(file_priv, plane->base.id))
747
return -EACCES;
748
749
DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx,
750
DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret);
751
752
if (crtc_req->mode_valid) {
753
/* If we have a mode we need a framebuffer. */
754
/* If we pass -1, set the mode with the currently bound fb */
755
if (crtc_req->fb_id == -1) {
756
struct drm_framebuffer *old_fb;
757
758
if (plane->state)
759
old_fb = plane->state->fb;
760
else
761
old_fb = plane->fb;
762
763
if (!old_fb) {
764
drm_dbg_kms(dev, "CRTC doesn't have current FB\n");
765
ret = -EINVAL;
766
goto out;
767
}
768
769
fb = old_fb;
770
/* Make refcounting symmetric with the lookup path. */
771
drm_framebuffer_get(fb);
772
} else {
773
fb = drm_framebuffer_lookup(dev, file_priv, crtc_req->fb_id);
774
if (!fb) {
775
drm_dbg_kms(dev, "Unknown FB ID%d\n",
776
crtc_req->fb_id);
777
ret = -ENOENT;
778
goto out;
779
}
780
}
781
782
mode = drm_mode_create(dev);
783
if (!mode) {
784
ret = -ENOMEM;
785
goto out;
786
}
787
if (!file_priv->aspect_ratio_allowed &&
788
(crtc_req->mode.flags & DRM_MODE_FLAG_PIC_AR_MASK) != DRM_MODE_FLAG_PIC_AR_NONE) {
789
drm_dbg_kms(dev, "Unexpected aspect-ratio flag bits\n");
790
ret = -EINVAL;
791
goto out;
792
}
793
794
795
ret = drm_mode_convert_umode(dev, mode, &crtc_req->mode);
796
if (ret) {
797
drm_dbg_kms(dev, "Invalid mode (%s, %pe): " DRM_MODE_FMT "\n",
798
drm_get_mode_status_name(mode->status),
799
ERR_PTR(ret), DRM_MODE_ARG(mode));
800
goto out;
801
}
802
803
/*
804
* Check whether the primary plane supports the fb pixel format.
805
* Drivers not implementing the universal planes API use a
806
* default formats list provided by the DRM core which doesn't
807
* match real hardware capabilities. Skip the check in that
808
* case.
809
*/
810
if (!plane->format_default) {
811
if (!drm_plane_has_format(plane, fb->format->format, fb->modifier)) {
812
drm_dbg_kms(dev, "Invalid pixel format %p4cc, modifier 0x%llx\n",
813
&fb->format->format, fb->modifier);
814
ret = -EINVAL;
815
goto out;
816
}
817
}
818
819
ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,
820
mode, fb);
821
if (ret)
822
goto out;
823
824
}
825
826
if (crtc_req->count_connectors == 0 && mode) {
827
drm_dbg_kms(dev, "Count connectors is 0 but mode set\n");
828
ret = -EINVAL;
829
goto out;
830
}
831
832
if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
833
drm_dbg_kms(dev, "Count connectors is %d but no mode or fb set\n",
834
crtc_req->count_connectors);
835
ret = -EINVAL;
836
goto out;
837
}
838
839
if (crtc_req->count_connectors > 0) {
840
u32 out_id;
841
842
/* Avoid unbounded kernel memory allocation */
843
if (crtc_req->count_connectors > config->num_connector) {
844
ret = -EINVAL;
845
goto out;
846
}
847
848
connector_set = kmalloc_array(crtc_req->count_connectors,
849
sizeof(struct drm_connector *),
850
GFP_KERNEL);
851
if (!connector_set) {
852
ret = -ENOMEM;
853
goto out;
854
}
855
856
for (i = 0; i < crtc_req->count_connectors; i++) {
857
connector_set[i] = NULL;
858
set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr;
859
if (get_user(out_id, &set_connectors_ptr[i])) {
860
ret = -EFAULT;
861
goto out;
862
}
863
864
connector = drm_connector_lookup(dev, file_priv, out_id);
865
if (!connector) {
866
drm_dbg_kms(dev, "Connector id %d unknown\n",
867
out_id);
868
ret = -ENOENT;
869
goto out;
870
}
871
drm_dbg_kms(dev, "[CONNECTOR:%d:%s]\n",
872
connector->base.id, connector->name);
873
874
connector_set[i] = connector;
875
num_connectors++;
876
}
877
}
878
879
set.crtc = crtc;
880
set.x = crtc_req->x;
881
set.y = crtc_req->y;
882
set.mode = mode;
883
set.connectors = connector_set;
884
set.num_connectors = num_connectors;
885
set.fb = fb;
886
887
if (drm_drv_uses_atomic_modeset(dev))
888
ret = crtc->funcs->set_config(&set, &ctx);
889
else
890
ret = __drm_mode_set_config_internal(&set, &ctx);
891
892
out:
893
if (fb)
894
drm_framebuffer_put(fb);
895
896
if (connector_set) {
897
for (i = 0; i < num_connectors; i++) {
898
if (connector_set[i])
899
drm_connector_put(connector_set[i]);
900
}
901
}
902
kfree(connector_set);
903
drm_mode_destroy(dev, mode);
904
905
/* In case we need to retry... */
906
connector_set = NULL;
907
fb = NULL;
908
mode = NULL;
909
num_connectors = 0;
910
911
DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
912
913
return ret;
914
}
915
916
int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
917
struct drm_property *property,
918
uint64_t value)
919
{
920
int ret = -EINVAL;
921
struct drm_crtc *crtc = obj_to_crtc(obj);
922
923
if (crtc->funcs->set_property)
924
ret = crtc->funcs->set_property(crtc, property, value);
925
if (!ret)
926
drm_object_property_set_value(obj, property, value);
927
928
return ret;
929
}
930
931
/**
932
* drm_crtc_create_scaling_filter_property - create a new scaling filter
933
* property
934
*
935
* @crtc: drm CRTC
936
* @supported_filters: bitmask of supported scaling filters, must include
937
* BIT(DRM_SCALING_FILTER_DEFAULT).
938
*
939
* This function lets driver to enable the scaling filter property on a given
940
* CRTC.
941
*
942
* RETURNS:
943
* Zero for success or -errno
944
*/
945
int drm_crtc_create_scaling_filter_property(struct drm_crtc *crtc,
946
unsigned int supported_filters)
947
{
948
struct drm_property *prop =
949
drm_create_scaling_filter_prop(crtc->dev, supported_filters);
950
951
if (IS_ERR(prop))
952
return PTR_ERR(prop);
953
954
drm_object_attach_property(&crtc->base, prop,
955
DRM_SCALING_FILTER_DEFAULT);
956
crtc->scaling_filter_property = prop;
957
958
return 0;
959
}
960
EXPORT_SYMBOL(drm_crtc_create_scaling_filter_property);
961
962
int drm_crtc_create_sharpness_strength_property(struct drm_crtc *crtc)
963
{
964
struct drm_device *dev = crtc->dev;
965
struct drm_property *prop =
966
drm_property_create_range(dev, 0, "SHARPNESS_STRENGTH", 0, 255);
967
968
if (!prop)
969
return -ENOMEM;
970
971
crtc->sharpness_strength_property = prop;
972
drm_object_attach_property(&crtc->base, prop, 0);
973
974
return 0;
975
}
976
EXPORT_SYMBOL(drm_crtc_create_sharpness_strength_property);
977
978
/**
979
* drm_crtc_in_clone_mode - check if the given CRTC state is in clone mode
980
*
981
* @crtc_state: CRTC state to check
982
*
983
* This function determines if the given CRTC state is being cloned by multiple
984
* encoders.
985
*
986
* RETURNS:
987
* True if the CRTC state is in clone mode. False otherwise
988
*/
989
bool drm_crtc_in_clone_mode(struct drm_crtc_state *crtc_state)
990
{
991
if (!crtc_state)
992
return false;
993
994
return hweight32(crtc_state->encoder_mask) > 1;
995
}
996
EXPORT_SYMBOL(drm_crtc_in_clone_mode);
997
998