Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/gpu/drm/drm_crtc.c
15111 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/list.h>
33
#include <linux/slab.h>
34
#include "drm.h"
35
#include "drmP.h"
36
#include "drm_crtc.h"
37
#include "drm_edid.h"
38
39
struct drm_prop_enum_list {
40
int type;
41
char *name;
42
};
43
44
/* Avoid boilerplate. I'm tired of typing. */
45
#define DRM_ENUM_NAME_FN(fnname, list) \
46
char *fnname(int val) \
47
{ \
48
int i; \
49
for (i = 0; i < ARRAY_SIZE(list); i++) { \
50
if (list[i].type == val) \
51
return list[i].name; \
52
} \
53
return "(unknown)"; \
54
}
55
56
/*
57
* Global properties
58
*/
59
static struct drm_prop_enum_list drm_dpms_enum_list[] =
60
{ { DRM_MODE_DPMS_ON, "On" },
61
{ DRM_MODE_DPMS_STANDBY, "Standby" },
62
{ DRM_MODE_DPMS_SUSPEND, "Suspend" },
63
{ DRM_MODE_DPMS_OFF, "Off" }
64
};
65
66
DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
67
68
/*
69
* Optional properties
70
*/
71
static struct drm_prop_enum_list drm_scaling_mode_enum_list[] =
72
{
73
{ DRM_MODE_SCALE_NONE, "None" },
74
{ DRM_MODE_SCALE_FULLSCREEN, "Full" },
75
{ DRM_MODE_SCALE_CENTER, "Center" },
76
{ DRM_MODE_SCALE_ASPECT, "Full aspect" },
77
};
78
79
static struct drm_prop_enum_list drm_dithering_mode_enum_list[] =
80
{
81
{ DRM_MODE_DITHERING_OFF, "Off" },
82
{ DRM_MODE_DITHERING_ON, "On" },
83
{ DRM_MODE_DITHERING_AUTO, "Automatic" },
84
};
85
86
/*
87
* Non-global properties, but "required" for certain connectors.
88
*/
89
static struct drm_prop_enum_list drm_dvi_i_select_enum_list[] =
90
{
91
{ DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
92
{ DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */
93
{ DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */
94
};
95
96
DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list)
97
98
static struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] =
99
{
100
{ DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */
101
{ DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */
102
{ DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */
103
};
104
105
DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name,
106
drm_dvi_i_subconnector_enum_list)
107
108
static struct drm_prop_enum_list drm_tv_select_enum_list[] =
109
{
110
{ DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
111
{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
112
{ DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */
113
{ DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
114
{ DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */
115
};
116
117
DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)
118
119
static struct drm_prop_enum_list drm_tv_subconnector_enum_list[] =
120
{
121
{ DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */
122
{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
123
{ DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */
124
{ DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
125
{ DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */
126
};
127
128
DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
129
drm_tv_subconnector_enum_list)
130
131
static struct drm_prop_enum_list drm_dirty_info_enum_list[] = {
132
{ DRM_MODE_DIRTY_OFF, "Off" },
133
{ DRM_MODE_DIRTY_ON, "On" },
134
{ DRM_MODE_DIRTY_ANNOTATE, "Annotate" },
135
};
136
137
DRM_ENUM_NAME_FN(drm_get_dirty_info_name,
138
drm_dirty_info_enum_list)
139
140
struct drm_conn_prop_enum_list {
141
int type;
142
char *name;
143
int count;
144
};
145
146
/*
147
* Connector and encoder types.
148
*/
149
static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
150
{ { DRM_MODE_CONNECTOR_Unknown, "Unknown", 0 },
151
{ DRM_MODE_CONNECTOR_VGA, "VGA", 0 },
152
{ DRM_MODE_CONNECTOR_DVII, "DVI-I", 0 },
153
{ DRM_MODE_CONNECTOR_DVID, "DVI-D", 0 },
154
{ DRM_MODE_CONNECTOR_DVIA, "DVI-A", 0 },
155
{ DRM_MODE_CONNECTOR_Composite, "Composite", 0 },
156
{ DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 },
157
{ DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 },
158
{ DRM_MODE_CONNECTOR_Component, "Component", 0 },
159
{ DRM_MODE_CONNECTOR_9PinDIN, "DIN", 0 },
160
{ DRM_MODE_CONNECTOR_DisplayPort, "DP", 0 },
161
{ DRM_MODE_CONNECTOR_HDMIA, "HDMI-A", 0 },
162
{ DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 },
163
{ DRM_MODE_CONNECTOR_TV, "TV", 0 },
164
{ DRM_MODE_CONNECTOR_eDP, "eDP", 0 },
165
};
166
167
static struct drm_prop_enum_list drm_encoder_enum_list[] =
168
{ { DRM_MODE_ENCODER_NONE, "None" },
169
{ DRM_MODE_ENCODER_DAC, "DAC" },
170
{ DRM_MODE_ENCODER_TMDS, "TMDS" },
171
{ DRM_MODE_ENCODER_LVDS, "LVDS" },
172
{ DRM_MODE_ENCODER_TVDAC, "TV" },
173
};
174
175
char *drm_get_encoder_name(struct drm_encoder *encoder)
176
{
177
static char buf[32];
178
179
snprintf(buf, 32, "%s-%d",
180
drm_encoder_enum_list[encoder->encoder_type].name,
181
encoder->base.id);
182
return buf;
183
}
184
EXPORT_SYMBOL(drm_get_encoder_name);
185
186
char *drm_get_connector_name(struct drm_connector *connector)
187
{
188
static char buf[32];
189
190
snprintf(buf, 32, "%s-%d",
191
drm_connector_enum_list[connector->connector_type].name,
192
connector->connector_type_id);
193
return buf;
194
}
195
EXPORT_SYMBOL(drm_get_connector_name);
196
197
char *drm_get_connector_status_name(enum drm_connector_status status)
198
{
199
if (status == connector_status_connected)
200
return "connected";
201
else if (status == connector_status_disconnected)
202
return "disconnected";
203
else
204
return "unknown";
205
}
206
207
/**
208
* drm_mode_object_get - allocate a new identifier
209
* @dev: DRM device
210
* @ptr: object pointer, used to generate unique ID
211
* @type: object type
212
*
213
* LOCKING:
214
*
215
* Create a unique identifier based on @ptr in @dev's identifier space. Used
216
* for tracking modes, CRTCs and connectors.
217
*
218
* RETURNS:
219
* New unique (relative to other objects in @dev) integer identifier for the
220
* object.
221
*/
222
static int drm_mode_object_get(struct drm_device *dev,
223
struct drm_mode_object *obj, uint32_t obj_type)
224
{
225
int new_id = 0;
226
int ret;
227
228
again:
229
if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
230
DRM_ERROR("Ran out memory getting a mode number\n");
231
return -EINVAL;
232
}
233
234
mutex_lock(&dev->mode_config.idr_mutex);
235
ret = idr_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id);
236
mutex_unlock(&dev->mode_config.idr_mutex);
237
if (ret == -EAGAIN)
238
goto again;
239
240
obj->id = new_id;
241
obj->type = obj_type;
242
return 0;
243
}
244
245
/**
246
* drm_mode_object_put - free an identifer
247
* @dev: DRM device
248
* @id: ID to free
249
*
250
* LOCKING:
251
* Caller must hold DRM mode_config lock.
252
*
253
* Free @id from @dev's unique identifier pool.
254
*/
255
static void drm_mode_object_put(struct drm_device *dev,
256
struct drm_mode_object *object)
257
{
258
mutex_lock(&dev->mode_config.idr_mutex);
259
idr_remove(&dev->mode_config.crtc_idr, object->id);
260
mutex_unlock(&dev->mode_config.idr_mutex);
261
}
262
263
struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
264
uint32_t id, uint32_t type)
265
{
266
struct drm_mode_object *obj = NULL;
267
268
mutex_lock(&dev->mode_config.idr_mutex);
269
obj = idr_find(&dev->mode_config.crtc_idr, id);
270
if (!obj || (obj->type != type) || (obj->id != id))
271
obj = NULL;
272
mutex_unlock(&dev->mode_config.idr_mutex);
273
274
return obj;
275
}
276
EXPORT_SYMBOL(drm_mode_object_find);
277
278
/**
279
* drm_framebuffer_init - initialize a framebuffer
280
* @dev: DRM device
281
*
282
* LOCKING:
283
* Caller must hold mode config lock.
284
*
285
* Allocates an ID for the framebuffer's parent mode object, sets its mode
286
* functions & device file and adds it to the master fd list.
287
*
288
* RETURNS:
289
* Zero on success, error code on failure.
290
*/
291
int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
292
const struct drm_framebuffer_funcs *funcs)
293
{
294
int ret;
295
296
ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
297
if (ret) {
298
return ret;
299
}
300
301
fb->dev = dev;
302
fb->funcs = funcs;
303
dev->mode_config.num_fb++;
304
list_add(&fb->head, &dev->mode_config.fb_list);
305
306
return 0;
307
}
308
EXPORT_SYMBOL(drm_framebuffer_init);
309
310
/**
311
* drm_framebuffer_cleanup - remove a framebuffer object
312
* @fb: framebuffer to remove
313
*
314
* LOCKING:
315
* Caller must hold mode config lock.
316
*
317
* Scans all the CRTCs in @dev's mode_config. If they're using @fb, removes
318
* it, setting it to NULL.
319
*/
320
void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
321
{
322
struct drm_device *dev = fb->dev;
323
struct drm_crtc *crtc;
324
struct drm_mode_set set;
325
int ret;
326
327
/* remove from any CRTC */
328
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
329
if (crtc->fb == fb) {
330
/* should turn off the crtc */
331
memset(&set, 0, sizeof(struct drm_mode_set));
332
set.crtc = crtc;
333
set.fb = NULL;
334
ret = crtc->funcs->set_config(&set);
335
if (ret)
336
DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc);
337
}
338
}
339
340
drm_mode_object_put(dev, &fb->base);
341
list_del(&fb->head);
342
dev->mode_config.num_fb--;
343
}
344
EXPORT_SYMBOL(drm_framebuffer_cleanup);
345
346
/**
347
* drm_crtc_init - Initialise a new CRTC object
348
* @dev: DRM device
349
* @crtc: CRTC object to init
350
* @funcs: callbacks for the new CRTC
351
*
352
* LOCKING:
353
* Caller must hold mode config lock.
354
*
355
* Inits a new object created as base part of an driver crtc object.
356
*/
357
void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
358
const struct drm_crtc_funcs *funcs)
359
{
360
crtc->dev = dev;
361
crtc->funcs = funcs;
362
363
mutex_lock(&dev->mode_config.mutex);
364
drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
365
366
list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
367
dev->mode_config.num_crtc++;
368
mutex_unlock(&dev->mode_config.mutex);
369
}
370
EXPORT_SYMBOL(drm_crtc_init);
371
372
/**
373
* drm_crtc_cleanup - Cleans up the core crtc usage.
374
* @crtc: CRTC to cleanup
375
*
376
* LOCKING:
377
* Caller must hold mode config lock.
378
*
379
* Cleanup @crtc. Removes from drm modesetting space
380
* does NOT free object, caller does that.
381
*/
382
void drm_crtc_cleanup(struct drm_crtc *crtc)
383
{
384
struct drm_device *dev = crtc->dev;
385
386
if (crtc->gamma_store) {
387
kfree(crtc->gamma_store);
388
crtc->gamma_store = NULL;
389
}
390
391
drm_mode_object_put(dev, &crtc->base);
392
list_del(&crtc->head);
393
dev->mode_config.num_crtc--;
394
}
395
EXPORT_SYMBOL(drm_crtc_cleanup);
396
397
/**
398
* drm_mode_probed_add - add a mode to a connector's probed mode list
399
* @connector: connector the new mode
400
* @mode: mode data
401
*
402
* LOCKING:
403
* Caller must hold mode config lock.
404
*
405
* Add @mode to @connector's mode list for later use.
406
*/
407
void drm_mode_probed_add(struct drm_connector *connector,
408
struct drm_display_mode *mode)
409
{
410
list_add(&mode->head, &connector->probed_modes);
411
}
412
EXPORT_SYMBOL(drm_mode_probed_add);
413
414
/**
415
* drm_mode_remove - remove and free a mode
416
* @connector: connector list to modify
417
* @mode: mode to remove
418
*
419
* LOCKING:
420
* Caller must hold mode config lock.
421
*
422
* Remove @mode from @connector's mode list, then free it.
423
*/
424
void drm_mode_remove(struct drm_connector *connector,
425
struct drm_display_mode *mode)
426
{
427
list_del(&mode->head);
428
kfree(mode);
429
}
430
EXPORT_SYMBOL(drm_mode_remove);
431
432
/**
433
* drm_connector_init - Init a preallocated connector
434
* @dev: DRM device
435
* @connector: the connector to init
436
* @funcs: callbacks for this connector
437
* @name: user visible name of the connector
438
*
439
* LOCKING:
440
* Caller must hold @dev's mode_config lock.
441
*
442
* Initialises a preallocated connector. Connectors should be
443
* subclassed as part of driver connector objects.
444
*/
445
void drm_connector_init(struct drm_device *dev,
446
struct drm_connector *connector,
447
const struct drm_connector_funcs *funcs,
448
int connector_type)
449
{
450
mutex_lock(&dev->mode_config.mutex);
451
452
connector->dev = dev;
453
connector->funcs = funcs;
454
drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR);
455
connector->connector_type = connector_type;
456
connector->connector_type_id =
457
++drm_connector_enum_list[connector_type].count; /* TODO */
458
INIT_LIST_HEAD(&connector->user_modes);
459
INIT_LIST_HEAD(&connector->probed_modes);
460
INIT_LIST_HEAD(&connector->modes);
461
connector->edid_blob_ptr = NULL;
462
463
list_add_tail(&connector->head, &dev->mode_config.connector_list);
464
dev->mode_config.num_connector++;
465
466
drm_connector_attach_property(connector,
467
dev->mode_config.edid_property, 0);
468
469
drm_connector_attach_property(connector,
470
dev->mode_config.dpms_property, 0);
471
472
mutex_unlock(&dev->mode_config.mutex);
473
}
474
EXPORT_SYMBOL(drm_connector_init);
475
476
/**
477
* drm_connector_cleanup - cleans up an initialised connector
478
* @connector: connector to cleanup
479
*
480
* LOCKING:
481
* Caller must hold @dev's mode_config lock.
482
*
483
* Cleans up the connector but doesn't free the object.
484
*/
485
void drm_connector_cleanup(struct drm_connector *connector)
486
{
487
struct drm_device *dev = connector->dev;
488
struct drm_display_mode *mode, *t;
489
490
list_for_each_entry_safe(mode, t, &connector->probed_modes, head)
491
drm_mode_remove(connector, mode);
492
493
list_for_each_entry_safe(mode, t, &connector->modes, head)
494
drm_mode_remove(connector, mode);
495
496
list_for_each_entry_safe(mode, t, &connector->user_modes, head)
497
drm_mode_remove(connector, mode);
498
499
mutex_lock(&dev->mode_config.mutex);
500
drm_mode_object_put(dev, &connector->base);
501
list_del(&connector->head);
502
mutex_unlock(&dev->mode_config.mutex);
503
}
504
EXPORT_SYMBOL(drm_connector_cleanup);
505
506
void drm_encoder_init(struct drm_device *dev,
507
struct drm_encoder *encoder,
508
const struct drm_encoder_funcs *funcs,
509
int encoder_type)
510
{
511
mutex_lock(&dev->mode_config.mutex);
512
513
encoder->dev = dev;
514
515
drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
516
encoder->encoder_type = encoder_type;
517
encoder->funcs = funcs;
518
519
list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
520
dev->mode_config.num_encoder++;
521
522
mutex_unlock(&dev->mode_config.mutex);
523
}
524
EXPORT_SYMBOL(drm_encoder_init);
525
526
void drm_encoder_cleanup(struct drm_encoder *encoder)
527
{
528
struct drm_device *dev = encoder->dev;
529
mutex_lock(&dev->mode_config.mutex);
530
drm_mode_object_put(dev, &encoder->base);
531
list_del(&encoder->head);
532
mutex_unlock(&dev->mode_config.mutex);
533
}
534
EXPORT_SYMBOL(drm_encoder_cleanup);
535
536
/**
537
* drm_mode_create - create a new display mode
538
* @dev: DRM device
539
*
540
* LOCKING:
541
* Caller must hold DRM mode_config lock.
542
*
543
* Create a new drm_display_mode, give it an ID, and return it.
544
*
545
* RETURNS:
546
* Pointer to new mode on success, NULL on error.
547
*/
548
struct drm_display_mode *drm_mode_create(struct drm_device *dev)
549
{
550
struct drm_display_mode *nmode;
551
552
nmode = kzalloc(sizeof(struct drm_display_mode), GFP_KERNEL);
553
if (!nmode)
554
return NULL;
555
556
drm_mode_object_get(dev, &nmode->base, DRM_MODE_OBJECT_MODE);
557
return nmode;
558
}
559
EXPORT_SYMBOL(drm_mode_create);
560
561
/**
562
* drm_mode_destroy - remove a mode
563
* @dev: DRM device
564
* @mode: mode to remove
565
*
566
* LOCKING:
567
* Caller must hold mode config lock.
568
*
569
* Free @mode's unique identifier, then free it.
570
*/
571
void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
572
{
573
drm_mode_object_put(dev, &mode->base);
574
575
kfree(mode);
576
}
577
EXPORT_SYMBOL(drm_mode_destroy);
578
579
static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
580
{
581
struct drm_property *edid;
582
struct drm_property *dpms;
583
int i;
584
585
/*
586
* Standard properties (apply to all connectors)
587
*/
588
edid = drm_property_create(dev, DRM_MODE_PROP_BLOB |
589
DRM_MODE_PROP_IMMUTABLE,
590
"EDID", 0);
591
dev->mode_config.edid_property = edid;
592
593
dpms = drm_property_create(dev, DRM_MODE_PROP_ENUM,
594
"DPMS", ARRAY_SIZE(drm_dpms_enum_list));
595
for (i = 0; i < ARRAY_SIZE(drm_dpms_enum_list); i++)
596
drm_property_add_enum(dpms, i, drm_dpms_enum_list[i].type,
597
drm_dpms_enum_list[i].name);
598
dev->mode_config.dpms_property = dpms;
599
600
return 0;
601
}
602
603
/**
604
* drm_mode_create_dvi_i_properties - create DVI-I specific connector properties
605
* @dev: DRM device
606
*
607
* Called by a driver the first time a DVI-I connector is made.
608
*/
609
int drm_mode_create_dvi_i_properties(struct drm_device *dev)
610
{
611
struct drm_property *dvi_i_selector;
612
struct drm_property *dvi_i_subconnector;
613
int i;
614
615
if (dev->mode_config.dvi_i_select_subconnector_property)
616
return 0;
617
618
dvi_i_selector =
619
drm_property_create(dev, DRM_MODE_PROP_ENUM,
620
"select subconnector",
621
ARRAY_SIZE(drm_dvi_i_select_enum_list));
622
for (i = 0; i < ARRAY_SIZE(drm_dvi_i_select_enum_list); i++)
623
drm_property_add_enum(dvi_i_selector, i,
624
drm_dvi_i_select_enum_list[i].type,
625
drm_dvi_i_select_enum_list[i].name);
626
dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector;
627
628
dvi_i_subconnector =
629
drm_property_create(dev, DRM_MODE_PROP_ENUM |
630
DRM_MODE_PROP_IMMUTABLE,
631
"subconnector",
632
ARRAY_SIZE(drm_dvi_i_subconnector_enum_list));
633
for (i = 0; i < ARRAY_SIZE(drm_dvi_i_subconnector_enum_list); i++)
634
drm_property_add_enum(dvi_i_subconnector, i,
635
drm_dvi_i_subconnector_enum_list[i].type,
636
drm_dvi_i_subconnector_enum_list[i].name);
637
dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector;
638
639
return 0;
640
}
641
EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);
642
643
/**
644
* drm_create_tv_properties - create TV specific connector properties
645
* @dev: DRM device
646
* @num_modes: number of different TV formats (modes) supported
647
* @modes: array of pointers to strings containing name of each format
648
*
649
* Called by a driver's TV initialization routine, this function creates
650
* the TV specific connector properties for a given device. Caller is
651
* responsible for allocating a list of format names and passing them to
652
* this routine.
653
*/
654
int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
655
char *modes[])
656
{
657
struct drm_property *tv_selector;
658
struct drm_property *tv_subconnector;
659
int i;
660
661
if (dev->mode_config.tv_select_subconnector_property)
662
return 0;
663
664
/*
665
* Basic connector properties
666
*/
667
tv_selector = drm_property_create(dev, DRM_MODE_PROP_ENUM,
668
"select subconnector",
669
ARRAY_SIZE(drm_tv_select_enum_list));
670
for (i = 0; i < ARRAY_SIZE(drm_tv_select_enum_list); i++)
671
drm_property_add_enum(tv_selector, i,
672
drm_tv_select_enum_list[i].type,
673
drm_tv_select_enum_list[i].name);
674
dev->mode_config.tv_select_subconnector_property = tv_selector;
675
676
tv_subconnector =
677
drm_property_create(dev, DRM_MODE_PROP_ENUM |
678
DRM_MODE_PROP_IMMUTABLE, "subconnector",
679
ARRAY_SIZE(drm_tv_subconnector_enum_list));
680
for (i = 0; i < ARRAY_SIZE(drm_tv_subconnector_enum_list); i++)
681
drm_property_add_enum(tv_subconnector, i,
682
drm_tv_subconnector_enum_list[i].type,
683
drm_tv_subconnector_enum_list[i].name);
684
dev->mode_config.tv_subconnector_property = tv_subconnector;
685
686
/*
687
* Other, TV specific properties: margins & TV modes.
688
*/
689
dev->mode_config.tv_left_margin_property =
690
drm_property_create(dev, DRM_MODE_PROP_RANGE,
691
"left margin", 2);
692
dev->mode_config.tv_left_margin_property->values[0] = 0;
693
dev->mode_config.tv_left_margin_property->values[1] = 100;
694
695
dev->mode_config.tv_right_margin_property =
696
drm_property_create(dev, DRM_MODE_PROP_RANGE,
697
"right margin", 2);
698
dev->mode_config.tv_right_margin_property->values[0] = 0;
699
dev->mode_config.tv_right_margin_property->values[1] = 100;
700
701
dev->mode_config.tv_top_margin_property =
702
drm_property_create(dev, DRM_MODE_PROP_RANGE,
703
"top margin", 2);
704
dev->mode_config.tv_top_margin_property->values[0] = 0;
705
dev->mode_config.tv_top_margin_property->values[1] = 100;
706
707
dev->mode_config.tv_bottom_margin_property =
708
drm_property_create(dev, DRM_MODE_PROP_RANGE,
709
"bottom margin", 2);
710
dev->mode_config.tv_bottom_margin_property->values[0] = 0;
711
dev->mode_config.tv_bottom_margin_property->values[1] = 100;
712
713
dev->mode_config.tv_mode_property =
714
drm_property_create(dev, DRM_MODE_PROP_ENUM,
715
"mode", num_modes);
716
for (i = 0; i < num_modes; i++)
717
drm_property_add_enum(dev->mode_config.tv_mode_property, i,
718
i, modes[i]);
719
720
dev->mode_config.tv_brightness_property =
721
drm_property_create(dev, DRM_MODE_PROP_RANGE,
722
"brightness", 2);
723
dev->mode_config.tv_brightness_property->values[0] = 0;
724
dev->mode_config.tv_brightness_property->values[1] = 100;
725
726
dev->mode_config.tv_contrast_property =
727
drm_property_create(dev, DRM_MODE_PROP_RANGE,
728
"contrast", 2);
729
dev->mode_config.tv_contrast_property->values[0] = 0;
730
dev->mode_config.tv_contrast_property->values[1] = 100;
731
732
dev->mode_config.tv_flicker_reduction_property =
733
drm_property_create(dev, DRM_MODE_PROP_RANGE,
734
"flicker reduction", 2);
735
dev->mode_config.tv_flicker_reduction_property->values[0] = 0;
736
dev->mode_config.tv_flicker_reduction_property->values[1] = 100;
737
738
dev->mode_config.tv_overscan_property =
739
drm_property_create(dev, DRM_MODE_PROP_RANGE,
740
"overscan", 2);
741
dev->mode_config.tv_overscan_property->values[0] = 0;
742
dev->mode_config.tv_overscan_property->values[1] = 100;
743
744
dev->mode_config.tv_saturation_property =
745
drm_property_create(dev, DRM_MODE_PROP_RANGE,
746
"saturation", 2);
747
dev->mode_config.tv_saturation_property->values[0] = 0;
748
dev->mode_config.tv_saturation_property->values[1] = 100;
749
750
dev->mode_config.tv_hue_property =
751
drm_property_create(dev, DRM_MODE_PROP_RANGE,
752
"hue", 2);
753
dev->mode_config.tv_hue_property->values[0] = 0;
754
dev->mode_config.tv_hue_property->values[1] = 100;
755
756
return 0;
757
}
758
EXPORT_SYMBOL(drm_mode_create_tv_properties);
759
760
/**
761
* drm_mode_create_scaling_mode_property - create scaling mode property
762
* @dev: DRM device
763
*
764
* Called by a driver the first time it's needed, must be attached to desired
765
* connectors.
766
*/
767
int drm_mode_create_scaling_mode_property(struct drm_device *dev)
768
{
769
struct drm_property *scaling_mode;
770
int i;
771
772
if (dev->mode_config.scaling_mode_property)
773
return 0;
774
775
scaling_mode =
776
drm_property_create(dev, DRM_MODE_PROP_ENUM, "scaling mode",
777
ARRAY_SIZE(drm_scaling_mode_enum_list));
778
for (i = 0; i < ARRAY_SIZE(drm_scaling_mode_enum_list); i++)
779
drm_property_add_enum(scaling_mode, i,
780
drm_scaling_mode_enum_list[i].type,
781
drm_scaling_mode_enum_list[i].name);
782
783
dev->mode_config.scaling_mode_property = scaling_mode;
784
785
return 0;
786
}
787
EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
788
789
/**
790
* drm_mode_create_dithering_property - create dithering property
791
* @dev: DRM device
792
*
793
* Called by a driver the first time it's needed, must be attached to desired
794
* connectors.
795
*/
796
int drm_mode_create_dithering_property(struct drm_device *dev)
797
{
798
struct drm_property *dithering_mode;
799
int i;
800
801
if (dev->mode_config.dithering_mode_property)
802
return 0;
803
804
dithering_mode =
805
drm_property_create(dev, DRM_MODE_PROP_ENUM, "dithering",
806
ARRAY_SIZE(drm_dithering_mode_enum_list));
807
for (i = 0; i < ARRAY_SIZE(drm_dithering_mode_enum_list); i++)
808
drm_property_add_enum(dithering_mode, i,
809
drm_dithering_mode_enum_list[i].type,
810
drm_dithering_mode_enum_list[i].name);
811
dev->mode_config.dithering_mode_property = dithering_mode;
812
813
return 0;
814
}
815
EXPORT_SYMBOL(drm_mode_create_dithering_property);
816
817
/**
818
* drm_mode_create_dirty_property - create dirty property
819
* @dev: DRM device
820
*
821
* Called by a driver the first time it's needed, must be attached to desired
822
* connectors.
823
*/
824
int drm_mode_create_dirty_info_property(struct drm_device *dev)
825
{
826
struct drm_property *dirty_info;
827
int i;
828
829
if (dev->mode_config.dirty_info_property)
830
return 0;
831
832
dirty_info =
833
drm_property_create(dev, DRM_MODE_PROP_ENUM |
834
DRM_MODE_PROP_IMMUTABLE,
835
"dirty",
836
ARRAY_SIZE(drm_dirty_info_enum_list));
837
for (i = 0; i < ARRAY_SIZE(drm_dirty_info_enum_list); i++)
838
drm_property_add_enum(dirty_info, i,
839
drm_dirty_info_enum_list[i].type,
840
drm_dirty_info_enum_list[i].name);
841
dev->mode_config.dirty_info_property = dirty_info;
842
843
return 0;
844
}
845
EXPORT_SYMBOL(drm_mode_create_dirty_info_property);
846
847
/**
848
* drm_mode_config_init - initialize DRM mode_configuration structure
849
* @dev: DRM device
850
*
851
* LOCKING:
852
* None, should happen single threaded at init time.
853
*
854
* Initialize @dev's mode_config structure, used for tracking the graphics
855
* configuration of @dev.
856
*/
857
void drm_mode_config_init(struct drm_device *dev)
858
{
859
mutex_init(&dev->mode_config.mutex);
860
mutex_init(&dev->mode_config.idr_mutex);
861
INIT_LIST_HEAD(&dev->mode_config.fb_list);
862
INIT_LIST_HEAD(&dev->mode_config.crtc_list);
863
INIT_LIST_HEAD(&dev->mode_config.connector_list);
864
INIT_LIST_HEAD(&dev->mode_config.encoder_list);
865
INIT_LIST_HEAD(&dev->mode_config.property_list);
866
INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
867
idr_init(&dev->mode_config.crtc_idr);
868
869
mutex_lock(&dev->mode_config.mutex);
870
drm_mode_create_standard_connector_properties(dev);
871
mutex_unlock(&dev->mode_config.mutex);
872
873
/* Just to be sure */
874
dev->mode_config.num_fb = 0;
875
dev->mode_config.num_connector = 0;
876
dev->mode_config.num_crtc = 0;
877
dev->mode_config.num_encoder = 0;
878
}
879
EXPORT_SYMBOL(drm_mode_config_init);
880
881
int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
882
{
883
uint32_t total_objects = 0;
884
885
total_objects += dev->mode_config.num_crtc;
886
total_objects += dev->mode_config.num_connector;
887
total_objects += dev->mode_config.num_encoder;
888
889
group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
890
if (!group->id_list)
891
return -ENOMEM;
892
893
group->num_crtcs = 0;
894
group->num_connectors = 0;
895
group->num_encoders = 0;
896
return 0;
897
}
898
899
int drm_mode_group_init_legacy_group(struct drm_device *dev,
900
struct drm_mode_group *group)
901
{
902
struct drm_crtc *crtc;
903
struct drm_encoder *encoder;
904
struct drm_connector *connector;
905
int ret;
906
907
if ((ret = drm_mode_group_init(dev, group)))
908
return ret;
909
910
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
911
group->id_list[group->num_crtcs++] = crtc->base.id;
912
913
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
914
group->id_list[group->num_crtcs + group->num_encoders++] =
915
encoder->base.id;
916
917
list_for_each_entry(connector, &dev->mode_config.connector_list, head)
918
group->id_list[group->num_crtcs + group->num_encoders +
919
group->num_connectors++] = connector->base.id;
920
921
return 0;
922
}
923
924
/**
925
* drm_mode_config_cleanup - free up DRM mode_config info
926
* @dev: DRM device
927
*
928
* LOCKING:
929
* Caller must hold mode config lock.
930
*
931
* Free up all the connectors and CRTCs associated with this DRM device, then
932
* free up the framebuffers and associated buffer objects.
933
*
934
* FIXME: cleanup any dangling user buffer objects too
935
*/
936
void drm_mode_config_cleanup(struct drm_device *dev)
937
{
938
struct drm_connector *connector, *ot;
939
struct drm_crtc *crtc, *ct;
940
struct drm_encoder *encoder, *enct;
941
struct drm_framebuffer *fb, *fbt;
942
struct drm_property *property, *pt;
943
944
list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
945
head) {
946
encoder->funcs->destroy(encoder);
947
}
948
949
list_for_each_entry_safe(connector, ot,
950
&dev->mode_config.connector_list, head) {
951
connector->funcs->destroy(connector);
952
}
953
954
list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
955
head) {
956
drm_property_destroy(dev, property);
957
}
958
959
list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
960
fb->funcs->destroy(fb);
961
}
962
963
list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
964
crtc->funcs->destroy(crtc);
965
}
966
967
}
968
EXPORT_SYMBOL(drm_mode_config_cleanup);
969
970
/**
971
* drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
972
* @out: drm_mode_modeinfo struct to return to the user
973
* @in: drm_display_mode to use
974
*
975
* LOCKING:
976
* None.
977
*
978
* Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
979
* the user.
980
*/
981
void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
982
struct drm_display_mode *in)
983
{
984
out->clock = in->clock;
985
out->hdisplay = in->hdisplay;
986
out->hsync_start = in->hsync_start;
987
out->hsync_end = in->hsync_end;
988
out->htotal = in->htotal;
989
out->hskew = in->hskew;
990
out->vdisplay = in->vdisplay;
991
out->vsync_start = in->vsync_start;
992
out->vsync_end = in->vsync_end;
993
out->vtotal = in->vtotal;
994
out->vscan = in->vscan;
995
out->vrefresh = in->vrefresh;
996
out->flags = in->flags;
997
out->type = in->type;
998
strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
999
out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1000
}
1001
1002
/**
1003
* drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode
1004
* @out: drm_display_mode to return to the user
1005
* @in: drm_mode_modeinfo to use
1006
*
1007
* LOCKING:
1008
* None.
1009
*
1010
* Convert a drm_mode_modeinfo into a drm_display_mode structure to return to
1011
* the caller.
1012
*/
1013
void drm_crtc_convert_umode(struct drm_display_mode *out,
1014
struct drm_mode_modeinfo *in)
1015
{
1016
out->clock = in->clock;
1017
out->hdisplay = in->hdisplay;
1018
out->hsync_start = in->hsync_start;
1019
out->hsync_end = in->hsync_end;
1020
out->htotal = in->htotal;
1021
out->hskew = in->hskew;
1022
out->vdisplay = in->vdisplay;
1023
out->vsync_start = in->vsync_start;
1024
out->vsync_end = in->vsync_end;
1025
out->vtotal = in->vtotal;
1026
out->vscan = in->vscan;
1027
out->vrefresh = in->vrefresh;
1028
out->flags = in->flags;
1029
out->type = in->type;
1030
strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
1031
out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1032
}
1033
1034
/**
1035
* drm_mode_getresources - get graphics configuration
1036
* @inode: inode from the ioctl
1037
* @filp: file * from the ioctl
1038
* @cmd: cmd from ioctl
1039
* @arg: arg from ioctl
1040
*
1041
* LOCKING:
1042
* Takes mode config lock.
1043
*
1044
* Construct a set of configuration description structures and return
1045
* them to the user, including CRTC, connector and framebuffer configuration.
1046
*
1047
* Called by the user via ioctl.
1048
*
1049
* RETURNS:
1050
* Zero on success, errno on failure.
1051
*/
1052
int drm_mode_getresources(struct drm_device *dev, void *data,
1053
struct drm_file *file_priv)
1054
{
1055
struct drm_mode_card_res *card_res = data;
1056
struct list_head *lh;
1057
struct drm_framebuffer *fb;
1058
struct drm_connector *connector;
1059
struct drm_crtc *crtc;
1060
struct drm_encoder *encoder;
1061
int ret = 0;
1062
int connector_count = 0;
1063
int crtc_count = 0;
1064
int fb_count = 0;
1065
int encoder_count = 0;
1066
int copied = 0, i;
1067
uint32_t __user *fb_id;
1068
uint32_t __user *crtc_id;
1069
uint32_t __user *connector_id;
1070
uint32_t __user *encoder_id;
1071
struct drm_mode_group *mode_group;
1072
1073
if (!drm_core_check_feature(dev, DRIVER_MODESET))
1074
return -EINVAL;
1075
1076
mutex_lock(&dev->mode_config.mutex);
1077
1078
/*
1079
* For the non-control nodes we need to limit the list of resources
1080
* by IDs in the group list for this node
1081
*/
1082
list_for_each(lh, &file_priv->fbs)
1083
fb_count++;
1084
1085
mode_group = &file_priv->master->minor->mode_group;
1086
if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1087
1088
list_for_each(lh, &dev->mode_config.crtc_list)
1089
crtc_count++;
1090
1091
list_for_each(lh, &dev->mode_config.connector_list)
1092
connector_count++;
1093
1094
list_for_each(lh, &dev->mode_config.encoder_list)
1095
encoder_count++;
1096
} else {
1097
1098
crtc_count = mode_group->num_crtcs;
1099
connector_count = mode_group->num_connectors;
1100
encoder_count = mode_group->num_encoders;
1101
}
1102
1103
card_res->max_height = dev->mode_config.max_height;
1104
card_res->min_height = dev->mode_config.min_height;
1105
card_res->max_width = dev->mode_config.max_width;
1106
card_res->min_width = dev->mode_config.min_width;
1107
1108
/* handle this in 4 parts */
1109
/* FBs */
1110
if (card_res->count_fbs >= fb_count) {
1111
copied = 0;
1112
fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr;
1113
list_for_each_entry(fb, &file_priv->fbs, filp_head) {
1114
if (put_user(fb->base.id, fb_id + copied)) {
1115
ret = -EFAULT;
1116
goto out;
1117
}
1118
copied++;
1119
}
1120
}
1121
card_res->count_fbs = fb_count;
1122
1123
/* CRTCs */
1124
if (card_res->count_crtcs >= crtc_count) {
1125
copied = 0;
1126
crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr;
1127
if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1128
list_for_each_entry(crtc, &dev->mode_config.crtc_list,
1129
head) {
1130
DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
1131
if (put_user(crtc->base.id, crtc_id + copied)) {
1132
ret = -EFAULT;
1133
goto out;
1134
}
1135
copied++;
1136
}
1137
} else {
1138
for (i = 0; i < mode_group->num_crtcs; i++) {
1139
if (put_user(mode_group->id_list[i],
1140
crtc_id + copied)) {
1141
ret = -EFAULT;
1142
goto out;
1143
}
1144
copied++;
1145
}
1146
}
1147
}
1148
card_res->count_crtcs = crtc_count;
1149
1150
/* Encoders */
1151
if (card_res->count_encoders >= encoder_count) {
1152
copied = 0;
1153
encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr;
1154
if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1155
list_for_each_entry(encoder,
1156
&dev->mode_config.encoder_list,
1157
head) {
1158
DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", encoder->base.id,
1159
drm_get_encoder_name(encoder));
1160
if (put_user(encoder->base.id, encoder_id +
1161
copied)) {
1162
ret = -EFAULT;
1163
goto out;
1164
}
1165
copied++;
1166
}
1167
} else {
1168
for (i = mode_group->num_crtcs; i < mode_group->num_crtcs + mode_group->num_encoders; i++) {
1169
if (put_user(mode_group->id_list[i],
1170
encoder_id + copied)) {
1171
ret = -EFAULT;
1172
goto out;
1173
}
1174
copied++;
1175
}
1176
1177
}
1178
}
1179
card_res->count_encoders = encoder_count;
1180
1181
/* Connectors */
1182
if (card_res->count_connectors >= connector_count) {
1183
copied = 0;
1184
connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr;
1185
if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1186
list_for_each_entry(connector,
1187
&dev->mode_config.connector_list,
1188
head) {
1189
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
1190
connector->base.id,
1191
drm_get_connector_name(connector));
1192
if (put_user(connector->base.id,
1193
connector_id + copied)) {
1194
ret = -EFAULT;
1195
goto out;
1196
}
1197
copied++;
1198
}
1199
} else {
1200
int start = mode_group->num_crtcs +
1201
mode_group->num_encoders;
1202
for (i = start; i < start + mode_group->num_connectors; i++) {
1203
if (put_user(mode_group->id_list[i],
1204
connector_id + copied)) {
1205
ret = -EFAULT;
1206
goto out;
1207
}
1208
copied++;
1209
}
1210
}
1211
}
1212
card_res->count_connectors = connector_count;
1213
1214
DRM_DEBUG_KMS("CRTC[%d] CONNECTORS[%d] ENCODERS[%d]\n", card_res->count_crtcs,
1215
card_res->count_connectors, card_res->count_encoders);
1216
1217
out:
1218
mutex_unlock(&dev->mode_config.mutex);
1219
return ret;
1220
}
1221
1222
/**
1223
* drm_mode_getcrtc - get CRTC configuration
1224
* @inode: inode from the ioctl
1225
* @filp: file * from the ioctl
1226
* @cmd: cmd from ioctl
1227
* @arg: arg from ioctl
1228
*
1229
* LOCKING:
1230
* Caller? (FIXME)
1231
*
1232
* Construct a CRTC configuration structure to return to the user.
1233
*
1234
* Called by the user via ioctl.
1235
*
1236
* RETURNS:
1237
* Zero on success, errno on failure.
1238
*/
1239
int drm_mode_getcrtc(struct drm_device *dev,
1240
void *data, struct drm_file *file_priv)
1241
{
1242
struct drm_mode_crtc *crtc_resp = data;
1243
struct drm_crtc *crtc;
1244
struct drm_mode_object *obj;
1245
int ret = 0;
1246
1247
if (!drm_core_check_feature(dev, DRIVER_MODESET))
1248
return -EINVAL;
1249
1250
mutex_lock(&dev->mode_config.mutex);
1251
1252
obj = drm_mode_object_find(dev, crtc_resp->crtc_id,
1253
DRM_MODE_OBJECT_CRTC);
1254
if (!obj) {
1255
ret = -EINVAL;
1256
goto out;
1257
}
1258
crtc = obj_to_crtc(obj);
1259
1260
crtc_resp->x = crtc->x;
1261
crtc_resp->y = crtc->y;
1262
crtc_resp->gamma_size = crtc->gamma_size;
1263
if (crtc->fb)
1264
crtc_resp->fb_id = crtc->fb->base.id;
1265
else
1266
crtc_resp->fb_id = 0;
1267
1268
if (crtc->enabled) {
1269
1270
drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode);
1271
crtc_resp->mode_valid = 1;
1272
1273
} else {
1274
crtc_resp->mode_valid = 0;
1275
}
1276
1277
out:
1278
mutex_unlock(&dev->mode_config.mutex);
1279
return ret;
1280
}
1281
1282
/**
1283
* drm_mode_getconnector - get connector configuration
1284
* @inode: inode from the ioctl
1285
* @filp: file * from the ioctl
1286
* @cmd: cmd from ioctl
1287
* @arg: arg from ioctl
1288
*
1289
* LOCKING:
1290
* Caller? (FIXME)
1291
*
1292
* Construct a connector configuration structure to return to the user.
1293
*
1294
* Called by the user via ioctl.
1295
*
1296
* RETURNS:
1297
* Zero on success, errno on failure.
1298
*/
1299
int drm_mode_getconnector(struct drm_device *dev, void *data,
1300
struct drm_file *file_priv)
1301
{
1302
struct drm_mode_get_connector *out_resp = data;
1303
struct drm_mode_object *obj;
1304
struct drm_connector *connector;
1305
struct drm_display_mode *mode;
1306
int mode_count = 0;
1307
int props_count = 0;
1308
int encoders_count = 0;
1309
int ret = 0;
1310
int copied = 0;
1311
int i;
1312
struct drm_mode_modeinfo u_mode;
1313
struct drm_mode_modeinfo __user *mode_ptr;
1314
uint32_t __user *prop_ptr;
1315
uint64_t __user *prop_values;
1316
uint32_t __user *encoder_ptr;
1317
1318
if (!drm_core_check_feature(dev, DRIVER_MODESET))
1319
return -EINVAL;
1320
1321
memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
1322
1323
DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id);
1324
1325
mutex_lock(&dev->mode_config.mutex);
1326
1327
obj = drm_mode_object_find(dev, out_resp->connector_id,
1328
DRM_MODE_OBJECT_CONNECTOR);
1329
if (!obj) {
1330
ret = -EINVAL;
1331
goto out;
1332
}
1333
connector = obj_to_connector(obj);
1334
1335
for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
1336
if (connector->property_ids[i] != 0) {
1337
props_count++;
1338
}
1339
}
1340
1341
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1342
if (connector->encoder_ids[i] != 0) {
1343
encoders_count++;
1344
}
1345
}
1346
1347
if (out_resp->count_modes == 0) {
1348
connector->funcs->fill_modes(connector,
1349
dev->mode_config.max_width,
1350
dev->mode_config.max_height);
1351
}
1352
1353
/* delayed so we get modes regardless of pre-fill_modes state */
1354
list_for_each_entry(mode, &connector->modes, head)
1355
mode_count++;
1356
1357
out_resp->connector_id = connector->base.id;
1358
out_resp->connector_type = connector->connector_type;
1359
out_resp->connector_type_id = connector->connector_type_id;
1360
out_resp->mm_width = connector->display_info.width_mm;
1361
out_resp->mm_height = connector->display_info.height_mm;
1362
out_resp->subpixel = connector->display_info.subpixel_order;
1363
out_resp->connection = connector->status;
1364
if (connector->encoder)
1365
out_resp->encoder_id = connector->encoder->base.id;
1366
else
1367
out_resp->encoder_id = 0;
1368
1369
/*
1370
* This ioctl is called twice, once to determine how much space is
1371
* needed, and the 2nd time to fill it.
1372
*/
1373
if ((out_resp->count_modes >= mode_count) && mode_count) {
1374
copied = 0;
1375
mode_ptr = (struct drm_mode_modeinfo *)(unsigned long)out_resp->modes_ptr;
1376
list_for_each_entry(mode, &connector->modes, head) {
1377
drm_crtc_convert_to_umode(&u_mode, mode);
1378
if (copy_to_user(mode_ptr + copied,
1379
&u_mode, sizeof(u_mode))) {
1380
ret = -EFAULT;
1381
goto out;
1382
}
1383
copied++;
1384
}
1385
}
1386
out_resp->count_modes = mode_count;
1387
1388
if ((out_resp->count_props >= props_count) && props_count) {
1389
copied = 0;
1390
prop_ptr = (uint32_t *)(unsigned long)(out_resp->props_ptr);
1391
prop_values = (uint64_t *)(unsigned long)(out_resp->prop_values_ptr);
1392
for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
1393
if (connector->property_ids[i] != 0) {
1394
if (put_user(connector->property_ids[i],
1395
prop_ptr + copied)) {
1396
ret = -EFAULT;
1397
goto out;
1398
}
1399
1400
if (put_user(connector->property_values[i],
1401
prop_values + copied)) {
1402
ret = -EFAULT;
1403
goto out;
1404
}
1405
copied++;
1406
}
1407
}
1408
}
1409
out_resp->count_props = props_count;
1410
1411
if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
1412
copied = 0;
1413
encoder_ptr = (uint32_t *)(unsigned long)(out_resp->encoders_ptr);
1414
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1415
if (connector->encoder_ids[i] != 0) {
1416
if (put_user(connector->encoder_ids[i],
1417
encoder_ptr + copied)) {
1418
ret = -EFAULT;
1419
goto out;
1420
}
1421
copied++;
1422
}
1423
}
1424
}
1425
out_resp->count_encoders = encoders_count;
1426
1427
out:
1428
mutex_unlock(&dev->mode_config.mutex);
1429
return ret;
1430
}
1431
1432
int drm_mode_getencoder(struct drm_device *dev, void *data,
1433
struct drm_file *file_priv)
1434
{
1435
struct drm_mode_get_encoder *enc_resp = data;
1436
struct drm_mode_object *obj;
1437
struct drm_encoder *encoder;
1438
int ret = 0;
1439
1440
if (!drm_core_check_feature(dev, DRIVER_MODESET))
1441
return -EINVAL;
1442
1443
mutex_lock(&dev->mode_config.mutex);
1444
obj = drm_mode_object_find(dev, enc_resp->encoder_id,
1445
DRM_MODE_OBJECT_ENCODER);
1446
if (!obj) {
1447
ret = -EINVAL;
1448
goto out;
1449
}
1450
encoder = obj_to_encoder(obj);
1451
1452
if (encoder->crtc)
1453
enc_resp->crtc_id = encoder->crtc->base.id;
1454
else
1455
enc_resp->crtc_id = 0;
1456
enc_resp->encoder_type = encoder->encoder_type;
1457
enc_resp->encoder_id = encoder->base.id;
1458
enc_resp->possible_crtcs = encoder->possible_crtcs;
1459
enc_resp->possible_clones = encoder->possible_clones;
1460
1461
out:
1462
mutex_unlock(&dev->mode_config.mutex);
1463
return ret;
1464
}
1465
1466
/**
1467
* drm_mode_setcrtc - set CRTC configuration
1468
* @inode: inode from the ioctl
1469
* @filp: file * from the ioctl
1470
* @cmd: cmd from ioctl
1471
* @arg: arg from ioctl
1472
*
1473
* LOCKING:
1474
* Caller? (FIXME)
1475
*
1476
* Build a new CRTC configuration based on user request.
1477
*
1478
* Called by the user via ioctl.
1479
*
1480
* RETURNS:
1481
* Zero on success, errno on failure.
1482
*/
1483
int drm_mode_setcrtc(struct drm_device *dev, void *data,
1484
struct drm_file *file_priv)
1485
{
1486
struct drm_mode_config *config = &dev->mode_config;
1487
struct drm_mode_crtc *crtc_req = data;
1488
struct drm_mode_object *obj;
1489
struct drm_crtc *crtc, *crtcfb;
1490
struct drm_connector **connector_set = NULL, *connector;
1491
struct drm_framebuffer *fb = NULL;
1492
struct drm_display_mode *mode = NULL;
1493
struct drm_mode_set set;
1494
uint32_t __user *set_connectors_ptr;
1495
int ret = 0;
1496
int i;
1497
1498
if (!drm_core_check_feature(dev, DRIVER_MODESET))
1499
return -EINVAL;
1500
1501
mutex_lock(&dev->mode_config.mutex);
1502
obj = drm_mode_object_find(dev, crtc_req->crtc_id,
1503
DRM_MODE_OBJECT_CRTC);
1504
if (!obj) {
1505
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
1506
ret = -EINVAL;
1507
goto out;
1508
}
1509
crtc = obj_to_crtc(obj);
1510
DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
1511
1512
if (crtc_req->mode_valid) {
1513
/* If we have a mode we need a framebuffer. */
1514
/* If we pass -1, set the mode with the currently bound fb */
1515
if (crtc_req->fb_id == -1) {
1516
list_for_each_entry(crtcfb,
1517
&dev->mode_config.crtc_list, head) {
1518
if (crtcfb == crtc) {
1519
DRM_DEBUG_KMS("Using current fb for "
1520
"setmode\n");
1521
fb = crtc->fb;
1522
}
1523
}
1524
} else {
1525
obj = drm_mode_object_find(dev, crtc_req->fb_id,
1526
DRM_MODE_OBJECT_FB);
1527
if (!obj) {
1528
DRM_DEBUG_KMS("Unknown FB ID%d\n",
1529
crtc_req->fb_id);
1530
ret = -EINVAL;
1531
goto out;
1532
}
1533
fb = obj_to_fb(obj);
1534
}
1535
1536
mode = drm_mode_create(dev);
1537
drm_crtc_convert_umode(mode, &crtc_req->mode);
1538
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
1539
}
1540
1541
if (crtc_req->count_connectors == 0 && mode) {
1542
DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
1543
ret = -EINVAL;
1544
goto out;
1545
}
1546
1547
if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
1548
DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
1549
crtc_req->count_connectors);
1550
ret = -EINVAL;
1551
goto out;
1552
}
1553
1554
if (crtc_req->count_connectors > 0) {
1555
u32 out_id;
1556
1557
/* Avoid unbounded kernel memory allocation */
1558
if (crtc_req->count_connectors > config->num_connector) {
1559
ret = -EINVAL;
1560
goto out;
1561
}
1562
1563
connector_set = kmalloc(crtc_req->count_connectors *
1564
sizeof(struct drm_connector *),
1565
GFP_KERNEL);
1566
if (!connector_set) {
1567
ret = -ENOMEM;
1568
goto out;
1569
}
1570
1571
for (i = 0; i < crtc_req->count_connectors; i++) {
1572
set_connectors_ptr = (uint32_t *)(unsigned long)crtc_req->set_connectors_ptr;
1573
if (get_user(out_id, &set_connectors_ptr[i])) {
1574
ret = -EFAULT;
1575
goto out;
1576
}
1577
1578
obj = drm_mode_object_find(dev, out_id,
1579
DRM_MODE_OBJECT_CONNECTOR);
1580
if (!obj) {
1581
DRM_DEBUG_KMS("Connector id %d unknown\n",
1582
out_id);
1583
ret = -EINVAL;
1584
goto out;
1585
}
1586
connector = obj_to_connector(obj);
1587
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
1588
connector->base.id,
1589
drm_get_connector_name(connector));
1590
1591
connector_set[i] = connector;
1592
}
1593
}
1594
1595
set.crtc = crtc;
1596
set.x = crtc_req->x;
1597
set.y = crtc_req->y;
1598
set.mode = mode;
1599
set.connectors = connector_set;
1600
set.num_connectors = crtc_req->count_connectors;
1601
set.fb = fb;
1602
ret = crtc->funcs->set_config(&set);
1603
1604
out:
1605
kfree(connector_set);
1606
mutex_unlock(&dev->mode_config.mutex);
1607
return ret;
1608
}
1609
1610
int drm_mode_cursor_ioctl(struct drm_device *dev,
1611
void *data, struct drm_file *file_priv)
1612
{
1613
struct drm_mode_cursor *req = data;
1614
struct drm_mode_object *obj;
1615
struct drm_crtc *crtc;
1616
int ret = 0;
1617
1618
if (!drm_core_check_feature(dev, DRIVER_MODESET))
1619
return -EINVAL;
1620
1621
if (!req->flags) {
1622
DRM_ERROR("no operation set\n");
1623
return -EINVAL;
1624
}
1625
1626
mutex_lock(&dev->mode_config.mutex);
1627
obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC);
1628
if (!obj) {
1629
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
1630
ret = -EINVAL;
1631
goto out;
1632
}
1633
crtc = obj_to_crtc(obj);
1634
1635
if (req->flags & DRM_MODE_CURSOR_BO) {
1636
if (!crtc->funcs->cursor_set) {
1637
DRM_ERROR("crtc does not support cursor\n");
1638
ret = -ENXIO;
1639
goto out;
1640
}
1641
/* Turns off the cursor if handle is 0 */
1642
ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
1643
req->width, req->height);
1644
}
1645
1646
if (req->flags & DRM_MODE_CURSOR_MOVE) {
1647
if (crtc->funcs->cursor_move) {
1648
ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
1649
} else {
1650
DRM_ERROR("crtc does not support cursor\n");
1651
ret = -EFAULT;
1652
goto out;
1653
}
1654
}
1655
out:
1656
mutex_unlock(&dev->mode_config.mutex);
1657
return ret;
1658
}
1659
1660
/**
1661
* drm_mode_addfb - add an FB to the graphics configuration
1662
* @inode: inode from the ioctl
1663
* @filp: file * from the ioctl
1664
* @cmd: cmd from ioctl
1665
* @arg: arg from ioctl
1666
*
1667
* LOCKING:
1668
* Takes mode config lock.
1669
*
1670
* Add a new FB to the specified CRTC, given a user request.
1671
*
1672
* Called by the user via ioctl.
1673
*
1674
* RETURNS:
1675
* Zero on success, errno on failure.
1676
*/
1677
int drm_mode_addfb(struct drm_device *dev,
1678
void *data, struct drm_file *file_priv)
1679
{
1680
struct drm_mode_fb_cmd *r = data;
1681
struct drm_mode_config *config = &dev->mode_config;
1682
struct drm_framebuffer *fb;
1683
int ret = 0;
1684
1685
if (!drm_core_check_feature(dev, DRIVER_MODESET))
1686
return -EINVAL;
1687
1688
if ((config->min_width > r->width) || (r->width > config->max_width)) {
1689
DRM_ERROR("mode new framebuffer width not within limits\n");
1690
return -EINVAL;
1691
}
1692
if ((config->min_height > r->height) || (r->height > config->max_height)) {
1693
DRM_ERROR("mode new framebuffer height not within limits\n");
1694
return -EINVAL;
1695
}
1696
1697
mutex_lock(&dev->mode_config.mutex);
1698
1699
/* TODO check buffer is sufficiently large */
1700
/* TODO setup destructor callback */
1701
1702
fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
1703
if (IS_ERR(fb)) {
1704
DRM_ERROR("could not create framebuffer\n");
1705
ret = PTR_ERR(fb);
1706
goto out;
1707
}
1708
1709
r->fb_id = fb->base.id;
1710
list_add(&fb->filp_head, &file_priv->fbs);
1711
DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
1712
1713
out:
1714
mutex_unlock(&dev->mode_config.mutex);
1715
return ret;
1716
}
1717
1718
/**
1719
* drm_mode_rmfb - remove an FB from the configuration
1720
* @inode: inode from the ioctl
1721
* @filp: file * from the ioctl
1722
* @cmd: cmd from ioctl
1723
* @arg: arg from ioctl
1724
*
1725
* LOCKING:
1726
* Takes mode config lock.
1727
*
1728
* Remove the FB specified by the user.
1729
*
1730
* Called by the user via ioctl.
1731
*
1732
* RETURNS:
1733
* Zero on success, errno on failure.
1734
*/
1735
int drm_mode_rmfb(struct drm_device *dev,
1736
void *data, struct drm_file *file_priv)
1737
{
1738
struct drm_mode_object *obj;
1739
struct drm_framebuffer *fb = NULL;
1740
struct drm_framebuffer *fbl = NULL;
1741
uint32_t *id = data;
1742
int ret = 0;
1743
int found = 0;
1744
1745
if (!drm_core_check_feature(dev, DRIVER_MODESET))
1746
return -EINVAL;
1747
1748
mutex_lock(&dev->mode_config.mutex);
1749
obj = drm_mode_object_find(dev, *id, DRM_MODE_OBJECT_FB);
1750
/* TODO check that we really get a framebuffer back. */
1751
if (!obj) {
1752
DRM_ERROR("mode invalid framebuffer id\n");
1753
ret = -EINVAL;
1754
goto out;
1755
}
1756
fb = obj_to_fb(obj);
1757
1758
list_for_each_entry(fbl, &file_priv->fbs, filp_head)
1759
if (fb == fbl)
1760
found = 1;
1761
1762
if (!found) {
1763
DRM_ERROR("tried to remove a fb that we didn't own\n");
1764
ret = -EINVAL;
1765
goto out;
1766
}
1767
1768
/* TODO release all crtc connected to the framebuffer */
1769
/* TODO unhock the destructor from the buffer object */
1770
1771
list_del(&fb->filp_head);
1772
fb->funcs->destroy(fb);
1773
1774
out:
1775
mutex_unlock(&dev->mode_config.mutex);
1776
return ret;
1777
}
1778
1779
/**
1780
* drm_mode_getfb - get FB info
1781
* @inode: inode from the ioctl
1782
* @filp: file * from the ioctl
1783
* @cmd: cmd from ioctl
1784
* @arg: arg from ioctl
1785
*
1786
* LOCKING:
1787
* Caller? (FIXME)
1788
*
1789
* Lookup the FB given its ID and return info about it.
1790
*
1791
* Called by the user via ioctl.
1792
*
1793
* RETURNS:
1794
* Zero on success, errno on failure.
1795
*/
1796
int drm_mode_getfb(struct drm_device *dev,
1797
void *data, struct drm_file *file_priv)
1798
{
1799
struct drm_mode_fb_cmd *r = data;
1800
struct drm_mode_object *obj;
1801
struct drm_framebuffer *fb;
1802
int ret = 0;
1803
1804
if (!drm_core_check_feature(dev, DRIVER_MODESET))
1805
return -EINVAL;
1806
1807
mutex_lock(&dev->mode_config.mutex);
1808
obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB);
1809
if (!obj) {
1810
DRM_ERROR("invalid framebuffer id\n");
1811
ret = -EINVAL;
1812
goto out;
1813
}
1814
fb = obj_to_fb(obj);
1815
1816
r->height = fb->height;
1817
r->width = fb->width;
1818
r->depth = fb->depth;
1819
r->bpp = fb->bits_per_pixel;
1820
r->pitch = fb->pitch;
1821
fb->funcs->create_handle(fb, file_priv, &r->handle);
1822
1823
out:
1824
mutex_unlock(&dev->mode_config.mutex);
1825
return ret;
1826
}
1827
1828
int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
1829
void *data, struct drm_file *file_priv)
1830
{
1831
struct drm_clip_rect __user *clips_ptr;
1832
struct drm_clip_rect *clips = NULL;
1833
struct drm_mode_fb_dirty_cmd *r = data;
1834
struct drm_mode_object *obj;
1835
struct drm_framebuffer *fb;
1836
unsigned flags;
1837
int num_clips;
1838
int ret = 0;
1839
1840
if (!drm_core_check_feature(dev, DRIVER_MODESET))
1841
return -EINVAL;
1842
1843
mutex_lock(&dev->mode_config.mutex);
1844
obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB);
1845
if (!obj) {
1846
DRM_ERROR("invalid framebuffer id\n");
1847
ret = -EINVAL;
1848
goto out_err1;
1849
}
1850
fb = obj_to_fb(obj);
1851
1852
num_clips = r->num_clips;
1853
clips_ptr = (struct drm_clip_rect *)(unsigned long)r->clips_ptr;
1854
1855
if (!num_clips != !clips_ptr) {
1856
ret = -EINVAL;
1857
goto out_err1;
1858
}
1859
1860
flags = DRM_MODE_FB_DIRTY_FLAGS & r->flags;
1861
1862
/* If userspace annotates copy, clips must come in pairs */
1863
if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY && (num_clips % 2)) {
1864
ret = -EINVAL;
1865
goto out_err1;
1866
}
1867
1868
if (num_clips && clips_ptr) {
1869
clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL);
1870
if (!clips) {
1871
ret = -ENOMEM;
1872
goto out_err1;
1873
}
1874
1875
ret = copy_from_user(clips, clips_ptr,
1876
num_clips * sizeof(*clips));
1877
if (ret) {
1878
ret = -EFAULT;
1879
goto out_err2;
1880
}
1881
}
1882
1883
if (fb->funcs->dirty) {
1884
ret = fb->funcs->dirty(fb, file_priv, flags, r->color,
1885
clips, num_clips);
1886
} else {
1887
ret = -ENOSYS;
1888
goto out_err2;
1889
}
1890
1891
out_err2:
1892
kfree(clips);
1893
out_err1:
1894
mutex_unlock(&dev->mode_config.mutex);
1895
return ret;
1896
}
1897
1898
1899
/**
1900
* drm_fb_release - remove and free the FBs on this file
1901
* @filp: file * from the ioctl
1902
*
1903
* LOCKING:
1904
* Takes mode config lock.
1905
*
1906
* Destroy all the FBs associated with @filp.
1907
*
1908
* Called by the user via ioctl.
1909
*
1910
* RETURNS:
1911
* Zero on success, errno on failure.
1912
*/
1913
void drm_fb_release(struct drm_file *priv)
1914
{
1915
struct drm_device *dev = priv->minor->dev;
1916
struct drm_framebuffer *fb, *tfb;
1917
1918
mutex_lock(&dev->mode_config.mutex);
1919
list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
1920
list_del(&fb->filp_head);
1921
fb->funcs->destroy(fb);
1922
}
1923
mutex_unlock(&dev->mode_config.mutex);
1924
}
1925
1926
/**
1927
* drm_mode_attachmode - add a mode to the user mode list
1928
* @dev: DRM device
1929
* @connector: connector to add the mode to
1930
* @mode: mode to add
1931
*
1932
* Add @mode to @connector's user mode list.
1933
*/
1934
static int drm_mode_attachmode(struct drm_device *dev,
1935
struct drm_connector *connector,
1936
struct drm_display_mode *mode)
1937
{
1938
int ret = 0;
1939
1940
list_add_tail(&mode->head, &connector->user_modes);
1941
return ret;
1942
}
1943
1944
int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc,
1945
struct drm_display_mode *mode)
1946
{
1947
struct drm_connector *connector;
1948
int ret = 0;
1949
struct drm_display_mode *dup_mode;
1950
int need_dup = 0;
1951
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1952
if (!connector->encoder)
1953
break;
1954
if (connector->encoder->crtc == crtc) {
1955
if (need_dup)
1956
dup_mode = drm_mode_duplicate(dev, mode);
1957
else
1958
dup_mode = mode;
1959
ret = drm_mode_attachmode(dev, connector, dup_mode);
1960
if (ret)
1961
return ret;
1962
need_dup = 1;
1963
}
1964
}
1965
return 0;
1966
}
1967
EXPORT_SYMBOL(drm_mode_attachmode_crtc);
1968
1969
static int drm_mode_detachmode(struct drm_device *dev,
1970
struct drm_connector *connector,
1971
struct drm_display_mode *mode)
1972
{
1973
int found = 0;
1974
int ret = 0;
1975
struct drm_display_mode *match_mode, *t;
1976
1977
list_for_each_entry_safe(match_mode, t, &connector->user_modes, head) {
1978
if (drm_mode_equal(match_mode, mode)) {
1979
list_del(&match_mode->head);
1980
drm_mode_destroy(dev, match_mode);
1981
found = 1;
1982
break;
1983
}
1984
}
1985
1986
if (!found)
1987
ret = -EINVAL;
1988
1989
return ret;
1990
}
1991
1992
int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode)
1993
{
1994
struct drm_connector *connector;
1995
1996
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1997
drm_mode_detachmode(dev, connector, mode);
1998
}
1999
return 0;
2000
}
2001
EXPORT_SYMBOL(drm_mode_detachmode_crtc);
2002
2003
/**
2004
* drm_fb_attachmode - Attach a user mode to an connector
2005
* @inode: inode from the ioctl
2006
* @filp: file * from the ioctl
2007
* @cmd: cmd from ioctl
2008
* @arg: arg from ioctl
2009
*
2010
* This attaches a user specified mode to an connector.
2011
* Called by the user via ioctl.
2012
*
2013
* RETURNS:
2014
* Zero on success, errno on failure.
2015
*/
2016
int drm_mode_attachmode_ioctl(struct drm_device *dev,
2017
void *data, struct drm_file *file_priv)
2018
{
2019
struct drm_mode_mode_cmd *mode_cmd = data;
2020
struct drm_connector *connector;
2021
struct drm_display_mode *mode;
2022
struct drm_mode_object *obj;
2023
struct drm_mode_modeinfo *umode = &mode_cmd->mode;
2024
int ret = 0;
2025
2026
if (!drm_core_check_feature(dev, DRIVER_MODESET))
2027
return -EINVAL;
2028
2029
mutex_lock(&dev->mode_config.mutex);
2030
2031
obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
2032
if (!obj) {
2033
ret = -EINVAL;
2034
goto out;
2035
}
2036
connector = obj_to_connector(obj);
2037
2038
mode = drm_mode_create(dev);
2039
if (!mode) {
2040
ret = -ENOMEM;
2041
goto out;
2042
}
2043
2044
drm_crtc_convert_umode(mode, umode);
2045
2046
ret = drm_mode_attachmode(dev, connector, mode);
2047
out:
2048
mutex_unlock(&dev->mode_config.mutex);
2049
return ret;
2050
}
2051
2052
2053
/**
2054
* drm_fb_detachmode - Detach a user specified mode from an connector
2055
* @inode: inode from the ioctl
2056
* @filp: file * from the ioctl
2057
* @cmd: cmd from ioctl
2058
* @arg: arg from ioctl
2059
*
2060
* Called by the user via ioctl.
2061
*
2062
* RETURNS:
2063
* Zero on success, errno on failure.
2064
*/
2065
int drm_mode_detachmode_ioctl(struct drm_device *dev,
2066
void *data, struct drm_file *file_priv)
2067
{
2068
struct drm_mode_object *obj;
2069
struct drm_mode_mode_cmd *mode_cmd = data;
2070
struct drm_connector *connector;
2071
struct drm_display_mode mode;
2072
struct drm_mode_modeinfo *umode = &mode_cmd->mode;
2073
int ret = 0;
2074
2075
if (!drm_core_check_feature(dev, DRIVER_MODESET))
2076
return -EINVAL;
2077
2078
mutex_lock(&dev->mode_config.mutex);
2079
2080
obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
2081
if (!obj) {
2082
ret = -EINVAL;
2083
goto out;
2084
}
2085
connector = obj_to_connector(obj);
2086
2087
drm_crtc_convert_umode(&mode, umode);
2088
ret = drm_mode_detachmode(dev, connector, &mode);
2089
out:
2090
mutex_unlock(&dev->mode_config.mutex);
2091
return ret;
2092
}
2093
2094
struct drm_property *drm_property_create(struct drm_device *dev, int flags,
2095
const char *name, int num_values)
2096
{
2097
struct drm_property *property = NULL;
2098
2099
property = kzalloc(sizeof(struct drm_property), GFP_KERNEL);
2100
if (!property)
2101
return NULL;
2102
2103
if (num_values) {
2104
property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL);
2105
if (!property->values)
2106
goto fail;
2107
}
2108
2109
drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY);
2110
property->flags = flags;
2111
property->num_values = num_values;
2112
INIT_LIST_HEAD(&property->enum_blob_list);
2113
2114
if (name)
2115
strncpy(property->name, name, DRM_PROP_NAME_LEN);
2116
2117
list_add_tail(&property->head, &dev->mode_config.property_list);
2118
return property;
2119
fail:
2120
kfree(property);
2121
return NULL;
2122
}
2123
EXPORT_SYMBOL(drm_property_create);
2124
2125
int drm_property_add_enum(struct drm_property *property, int index,
2126
uint64_t value, const char *name)
2127
{
2128
struct drm_property_enum *prop_enum;
2129
2130
if (!(property->flags & DRM_MODE_PROP_ENUM))
2131
return -EINVAL;
2132
2133
if (!list_empty(&property->enum_blob_list)) {
2134
list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
2135
if (prop_enum->value == value) {
2136
strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
2137
prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
2138
return 0;
2139
}
2140
}
2141
}
2142
2143
prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL);
2144
if (!prop_enum)
2145
return -ENOMEM;
2146
2147
strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
2148
prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
2149
prop_enum->value = value;
2150
2151
property->values[index] = value;
2152
list_add_tail(&prop_enum->head, &property->enum_blob_list);
2153
return 0;
2154
}
2155
EXPORT_SYMBOL(drm_property_add_enum);
2156
2157
void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
2158
{
2159
struct drm_property_enum *prop_enum, *pt;
2160
2161
list_for_each_entry_safe(prop_enum, pt, &property->enum_blob_list, head) {
2162
list_del(&prop_enum->head);
2163
kfree(prop_enum);
2164
}
2165
2166
if (property->num_values)
2167
kfree(property->values);
2168
drm_mode_object_put(dev, &property->base);
2169
list_del(&property->head);
2170
kfree(property);
2171
}
2172
EXPORT_SYMBOL(drm_property_destroy);
2173
2174
int drm_connector_attach_property(struct drm_connector *connector,
2175
struct drm_property *property, uint64_t init_val)
2176
{
2177
int i;
2178
2179
for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
2180
if (connector->property_ids[i] == 0) {
2181
connector->property_ids[i] = property->base.id;
2182
connector->property_values[i] = init_val;
2183
break;
2184
}
2185
}
2186
2187
if (i == DRM_CONNECTOR_MAX_PROPERTY)
2188
return -EINVAL;
2189
return 0;
2190
}
2191
EXPORT_SYMBOL(drm_connector_attach_property);
2192
2193
int drm_connector_property_set_value(struct drm_connector *connector,
2194
struct drm_property *property, uint64_t value)
2195
{
2196
int i;
2197
2198
for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
2199
if (connector->property_ids[i] == property->base.id) {
2200
connector->property_values[i] = value;
2201
break;
2202
}
2203
}
2204
2205
if (i == DRM_CONNECTOR_MAX_PROPERTY)
2206
return -EINVAL;
2207
return 0;
2208
}
2209
EXPORT_SYMBOL(drm_connector_property_set_value);
2210
2211
int drm_connector_property_get_value(struct drm_connector *connector,
2212
struct drm_property *property, uint64_t *val)
2213
{
2214
int i;
2215
2216
for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
2217
if (connector->property_ids[i] == property->base.id) {
2218
*val = connector->property_values[i];
2219
break;
2220
}
2221
}
2222
2223
if (i == DRM_CONNECTOR_MAX_PROPERTY)
2224
return -EINVAL;
2225
return 0;
2226
}
2227
EXPORT_SYMBOL(drm_connector_property_get_value);
2228
2229
int drm_mode_getproperty_ioctl(struct drm_device *dev,
2230
void *data, struct drm_file *file_priv)
2231
{
2232
struct drm_mode_object *obj;
2233
struct drm_mode_get_property *out_resp = data;
2234
struct drm_property *property;
2235
int enum_count = 0;
2236
int blob_count = 0;
2237
int value_count = 0;
2238
int ret = 0, i;
2239
int copied;
2240
struct drm_property_enum *prop_enum;
2241
struct drm_mode_property_enum __user *enum_ptr;
2242
struct drm_property_blob *prop_blob;
2243
uint32_t *blob_id_ptr;
2244
uint64_t __user *values_ptr;
2245
uint32_t __user *blob_length_ptr;
2246
2247
if (!drm_core_check_feature(dev, DRIVER_MODESET))
2248
return -EINVAL;
2249
2250
mutex_lock(&dev->mode_config.mutex);
2251
obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
2252
if (!obj) {
2253
ret = -EINVAL;
2254
goto done;
2255
}
2256
property = obj_to_property(obj);
2257
2258
if (property->flags & DRM_MODE_PROP_ENUM) {
2259
list_for_each_entry(prop_enum, &property->enum_blob_list, head)
2260
enum_count++;
2261
} else if (property->flags & DRM_MODE_PROP_BLOB) {
2262
list_for_each_entry(prop_blob, &property->enum_blob_list, head)
2263
blob_count++;
2264
}
2265
2266
value_count = property->num_values;
2267
2268
strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN);
2269
out_resp->name[DRM_PROP_NAME_LEN-1] = 0;
2270
out_resp->flags = property->flags;
2271
2272
if ((out_resp->count_values >= value_count) && value_count) {
2273
values_ptr = (uint64_t *)(unsigned long)out_resp->values_ptr;
2274
for (i = 0; i < value_count; i++) {
2275
if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) {
2276
ret = -EFAULT;
2277
goto done;
2278
}
2279
}
2280
}
2281
out_resp->count_values = value_count;
2282
2283
if (property->flags & DRM_MODE_PROP_ENUM) {
2284
if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
2285
copied = 0;
2286
enum_ptr = (struct drm_mode_property_enum *)(unsigned long)out_resp->enum_blob_ptr;
2287
list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
2288
2289
if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {
2290
ret = -EFAULT;
2291
goto done;
2292
}
2293
2294
if (copy_to_user(&enum_ptr[copied].name,
2295
&prop_enum->name, DRM_PROP_NAME_LEN)) {
2296
ret = -EFAULT;
2297
goto done;
2298
}
2299
copied++;
2300
}
2301
}
2302
out_resp->count_enum_blobs = enum_count;
2303
}
2304
2305
if (property->flags & DRM_MODE_PROP_BLOB) {
2306
if ((out_resp->count_enum_blobs >= blob_count) && blob_count) {
2307
copied = 0;
2308
blob_id_ptr = (uint32_t *)(unsigned long)out_resp->enum_blob_ptr;
2309
blob_length_ptr = (uint32_t *)(unsigned long)out_resp->values_ptr;
2310
2311
list_for_each_entry(prop_blob, &property->enum_blob_list, head) {
2312
if (put_user(prop_blob->base.id, blob_id_ptr + copied)) {
2313
ret = -EFAULT;
2314
goto done;
2315
}
2316
2317
if (put_user(prop_blob->length, blob_length_ptr + copied)) {
2318
ret = -EFAULT;
2319
goto done;
2320
}
2321
2322
copied++;
2323
}
2324
}
2325
out_resp->count_enum_blobs = blob_count;
2326
}
2327
done:
2328
mutex_unlock(&dev->mode_config.mutex);
2329
return ret;
2330
}
2331
2332
static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length,
2333
void *data)
2334
{
2335
struct drm_property_blob *blob;
2336
2337
if (!length || !data)
2338
return NULL;
2339
2340
blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
2341
if (!blob)
2342
return NULL;
2343
2344
blob->data = (void *)((char *)blob + sizeof(struct drm_property_blob));
2345
blob->length = length;
2346
2347
memcpy(blob->data, data, length);
2348
2349
drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB);
2350
2351
list_add_tail(&blob->head, &dev->mode_config.property_blob_list);
2352
return blob;
2353
}
2354
2355
static void drm_property_destroy_blob(struct drm_device *dev,
2356
struct drm_property_blob *blob)
2357
{
2358
drm_mode_object_put(dev, &blob->base);
2359
list_del(&blob->head);
2360
kfree(blob);
2361
}
2362
2363
int drm_mode_getblob_ioctl(struct drm_device *dev,
2364
void *data, struct drm_file *file_priv)
2365
{
2366
struct drm_mode_object *obj;
2367
struct drm_mode_get_blob *out_resp = data;
2368
struct drm_property_blob *blob;
2369
int ret = 0;
2370
void *blob_ptr;
2371
2372
if (!drm_core_check_feature(dev, DRIVER_MODESET))
2373
return -EINVAL;
2374
2375
mutex_lock(&dev->mode_config.mutex);
2376
obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB);
2377
if (!obj) {
2378
ret = -EINVAL;
2379
goto done;
2380
}
2381
blob = obj_to_blob(obj);
2382
2383
if (out_resp->length == blob->length) {
2384
blob_ptr = (void *)(unsigned long)out_resp->data;
2385
if (copy_to_user(blob_ptr, blob->data, blob->length)){
2386
ret = -EFAULT;
2387
goto done;
2388
}
2389
}
2390
out_resp->length = blob->length;
2391
2392
done:
2393
mutex_unlock(&dev->mode_config.mutex);
2394
return ret;
2395
}
2396
2397
int drm_mode_connector_update_edid_property(struct drm_connector *connector,
2398
struct edid *edid)
2399
{
2400
struct drm_device *dev = connector->dev;
2401
int ret = 0, size;
2402
2403
if (connector->edid_blob_ptr)
2404
drm_property_destroy_blob(dev, connector->edid_blob_ptr);
2405
2406
/* Delete edid, when there is none. */
2407
if (!edid) {
2408
connector->edid_blob_ptr = NULL;
2409
ret = drm_connector_property_set_value(connector, dev->mode_config.edid_property, 0);
2410
return ret;
2411
}
2412
2413
size = EDID_LENGTH * (1 + edid->extensions);
2414
connector->edid_blob_ptr = drm_property_create_blob(connector->dev,
2415
size, edid);
2416
2417
ret = drm_connector_property_set_value(connector,
2418
dev->mode_config.edid_property,
2419
connector->edid_blob_ptr->base.id);
2420
2421
return ret;
2422
}
2423
EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
2424
2425
int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
2426
void *data, struct drm_file *file_priv)
2427
{
2428
struct drm_mode_connector_set_property *out_resp = data;
2429
struct drm_mode_object *obj;
2430
struct drm_property *property;
2431
struct drm_connector *connector;
2432
int ret = -EINVAL;
2433
int i;
2434
2435
if (!drm_core_check_feature(dev, DRIVER_MODESET))
2436
return -EINVAL;
2437
2438
mutex_lock(&dev->mode_config.mutex);
2439
2440
obj = drm_mode_object_find(dev, out_resp->connector_id, DRM_MODE_OBJECT_CONNECTOR);
2441
if (!obj) {
2442
goto out;
2443
}
2444
connector = obj_to_connector(obj);
2445
2446
for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
2447
if (connector->property_ids[i] == out_resp->prop_id)
2448
break;
2449
}
2450
2451
if (i == DRM_CONNECTOR_MAX_PROPERTY) {
2452
goto out;
2453
}
2454
2455
obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
2456
if (!obj) {
2457
goto out;
2458
}
2459
property = obj_to_property(obj);
2460
2461
if (property->flags & DRM_MODE_PROP_IMMUTABLE)
2462
goto out;
2463
2464
if (property->flags & DRM_MODE_PROP_RANGE) {
2465
if (out_resp->value < property->values[0])
2466
goto out;
2467
2468
if (out_resp->value > property->values[1])
2469
goto out;
2470
} else {
2471
int found = 0;
2472
for (i = 0; i < property->num_values; i++) {
2473
if (property->values[i] == out_resp->value) {
2474
found = 1;
2475
break;
2476
}
2477
}
2478
if (!found) {
2479
goto out;
2480
}
2481
}
2482
2483
/* Do DPMS ourselves */
2484
if (property == connector->dev->mode_config.dpms_property) {
2485
if (connector->funcs->dpms)
2486
(*connector->funcs->dpms)(connector, (int) out_resp->value);
2487
ret = 0;
2488
} else if (connector->funcs->set_property)
2489
ret = connector->funcs->set_property(connector, property, out_resp->value);
2490
2491
/* store the property value if successful */
2492
if (!ret)
2493
drm_connector_property_set_value(connector, property, out_resp->value);
2494
out:
2495
mutex_unlock(&dev->mode_config.mutex);
2496
return ret;
2497
}
2498
2499
int drm_mode_connector_attach_encoder(struct drm_connector *connector,
2500
struct drm_encoder *encoder)
2501
{
2502
int i;
2503
2504
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
2505
if (connector->encoder_ids[i] == 0) {
2506
connector->encoder_ids[i] = encoder->base.id;
2507
return 0;
2508
}
2509
}
2510
return -ENOMEM;
2511
}
2512
EXPORT_SYMBOL(drm_mode_connector_attach_encoder);
2513
2514
void drm_mode_connector_detach_encoder(struct drm_connector *connector,
2515
struct drm_encoder *encoder)
2516
{
2517
int i;
2518
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
2519
if (connector->encoder_ids[i] == encoder->base.id) {
2520
connector->encoder_ids[i] = 0;
2521
if (connector->encoder == encoder)
2522
connector->encoder = NULL;
2523
break;
2524
}
2525
}
2526
}
2527
EXPORT_SYMBOL(drm_mode_connector_detach_encoder);
2528
2529
bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
2530
int gamma_size)
2531
{
2532
crtc->gamma_size = gamma_size;
2533
2534
crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL);
2535
if (!crtc->gamma_store) {
2536
crtc->gamma_size = 0;
2537
return false;
2538
}
2539
2540
return true;
2541
}
2542
EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);
2543
2544
int drm_mode_gamma_set_ioctl(struct drm_device *dev,
2545
void *data, struct drm_file *file_priv)
2546
{
2547
struct drm_mode_crtc_lut *crtc_lut = data;
2548
struct drm_mode_object *obj;
2549
struct drm_crtc *crtc;
2550
void *r_base, *g_base, *b_base;
2551
int size;
2552
int ret = 0;
2553
2554
if (!drm_core_check_feature(dev, DRIVER_MODESET))
2555
return -EINVAL;
2556
2557
mutex_lock(&dev->mode_config.mutex);
2558
obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
2559
if (!obj) {
2560
ret = -EINVAL;
2561
goto out;
2562
}
2563
crtc = obj_to_crtc(obj);
2564
2565
/* memcpy into gamma store */
2566
if (crtc_lut->gamma_size != crtc->gamma_size) {
2567
ret = -EINVAL;
2568
goto out;
2569
}
2570
2571
size = crtc_lut->gamma_size * (sizeof(uint16_t));
2572
r_base = crtc->gamma_store;
2573
if (copy_from_user(r_base, (void __user *)(unsigned long)crtc_lut->red, size)) {
2574
ret = -EFAULT;
2575
goto out;
2576
}
2577
2578
g_base = r_base + size;
2579
if (copy_from_user(g_base, (void __user *)(unsigned long)crtc_lut->green, size)) {
2580
ret = -EFAULT;
2581
goto out;
2582
}
2583
2584
b_base = g_base + size;
2585
if (copy_from_user(b_base, (void __user *)(unsigned long)crtc_lut->blue, size)) {
2586
ret = -EFAULT;
2587
goto out;
2588
}
2589
2590
crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size);
2591
2592
out:
2593
mutex_unlock(&dev->mode_config.mutex);
2594
return ret;
2595
2596
}
2597
2598
int drm_mode_gamma_get_ioctl(struct drm_device *dev,
2599
void *data, struct drm_file *file_priv)
2600
{
2601
struct drm_mode_crtc_lut *crtc_lut = data;
2602
struct drm_mode_object *obj;
2603
struct drm_crtc *crtc;
2604
void *r_base, *g_base, *b_base;
2605
int size;
2606
int ret = 0;
2607
2608
if (!drm_core_check_feature(dev, DRIVER_MODESET))
2609
return -EINVAL;
2610
2611
mutex_lock(&dev->mode_config.mutex);
2612
obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
2613
if (!obj) {
2614
ret = -EINVAL;
2615
goto out;
2616
}
2617
crtc = obj_to_crtc(obj);
2618
2619
/* memcpy into gamma store */
2620
if (crtc_lut->gamma_size != crtc->gamma_size) {
2621
ret = -EINVAL;
2622
goto out;
2623
}
2624
2625
size = crtc_lut->gamma_size * (sizeof(uint16_t));
2626
r_base = crtc->gamma_store;
2627
if (copy_to_user((void __user *)(unsigned long)crtc_lut->red, r_base, size)) {
2628
ret = -EFAULT;
2629
goto out;
2630
}
2631
2632
g_base = r_base + size;
2633
if (copy_to_user((void __user *)(unsigned long)crtc_lut->green, g_base, size)) {
2634
ret = -EFAULT;
2635
goto out;
2636
}
2637
2638
b_base = g_base + size;
2639
if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) {
2640
ret = -EFAULT;
2641
goto out;
2642
}
2643
out:
2644
mutex_unlock(&dev->mode_config.mutex);
2645
return ret;
2646
}
2647
2648
int drm_mode_page_flip_ioctl(struct drm_device *dev,
2649
void *data, struct drm_file *file_priv)
2650
{
2651
struct drm_mode_crtc_page_flip *page_flip = data;
2652
struct drm_mode_object *obj;
2653
struct drm_crtc *crtc;
2654
struct drm_framebuffer *fb;
2655
struct drm_pending_vblank_event *e = NULL;
2656
unsigned long flags;
2657
int ret = -EINVAL;
2658
2659
if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS ||
2660
page_flip->reserved != 0)
2661
return -EINVAL;
2662
2663
mutex_lock(&dev->mode_config.mutex);
2664
obj = drm_mode_object_find(dev, page_flip->crtc_id, DRM_MODE_OBJECT_CRTC);
2665
if (!obj)
2666
goto out;
2667
crtc = obj_to_crtc(obj);
2668
2669
if (crtc->fb == NULL) {
2670
/* The framebuffer is currently unbound, presumably
2671
* due to a hotplug event, that userspace has not
2672
* yet discovered.
2673
*/
2674
ret = -EBUSY;
2675
goto out;
2676
}
2677
2678
if (crtc->funcs->page_flip == NULL)
2679
goto out;
2680
2681
obj = drm_mode_object_find(dev, page_flip->fb_id, DRM_MODE_OBJECT_FB);
2682
if (!obj)
2683
goto out;
2684
fb = obj_to_fb(obj);
2685
2686
if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
2687
ret = -ENOMEM;
2688
spin_lock_irqsave(&dev->event_lock, flags);
2689
if (file_priv->event_space < sizeof e->event) {
2690
spin_unlock_irqrestore(&dev->event_lock, flags);
2691
goto out;
2692
}
2693
file_priv->event_space -= sizeof e->event;
2694
spin_unlock_irqrestore(&dev->event_lock, flags);
2695
2696
e = kzalloc(sizeof *e, GFP_KERNEL);
2697
if (e == NULL) {
2698
spin_lock_irqsave(&dev->event_lock, flags);
2699
file_priv->event_space += sizeof e->event;
2700
spin_unlock_irqrestore(&dev->event_lock, flags);
2701
goto out;
2702
}
2703
2704
e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
2705
e->event.base.length = sizeof e->event;
2706
e->event.user_data = page_flip->user_data;
2707
e->base.event = &e->event.base;
2708
e->base.file_priv = file_priv;
2709
e->base.destroy =
2710
(void (*) (struct drm_pending_event *)) kfree;
2711
}
2712
2713
ret = crtc->funcs->page_flip(crtc, fb, e);
2714
if (ret) {
2715
spin_lock_irqsave(&dev->event_lock, flags);
2716
file_priv->event_space += sizeof e->event;
2717
spin_unlock_irqrestore(&dev->event_lock, flags);
2718
kfree(e);
2719
}
2720
2721
out:
2722
mutex_unlock(&dev->mode_config.mutex);
2723
return ret;
2724
}
2725
2726
void drm_mode_config_reset(struct drm_device *dev)
2727
{
2728
struct drm_crtc *crtc;
2729
struct drm_encoder *encoder;
2730
struct drm_connector *connector;
2731
2732
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
2733
if (crtc->funcs->reset)
2734
crtc->funcs->reset(crtc);
2735
2736
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
2737
if (encoder->funcs->reset)
2738
encoder->funcs->reset(encoder);
2739
2740
list_for_each_entry(connector, &dev->mode_config.connector_list, head)
2741
if (connector->funcs->reset)
2742
connector->funcs->reset(connector);
2743
}
2744
EXPORT_SYMBOL(drm_mode_config_reset);
2745
2746
int drm_mode_create_dumb_ioctl(struct drm_device *dev,
2747
void *data, struct drm_file *file_priv)
2748
{
2749
struct drm_mode_create_dumb *args = data;
2750
2751
if (!dev->driver->dumb_create)
2752
return -ENOSYS;
2753
return dev->driver->dumb_create(file_priv, dev, args);
2754
}
2755
2756
int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
2757
void *data, struct drm_file *file_priv)
2758
{
2759
struct drm_mode_map_dumb *args = data;
2760
2761
/* call driver ioctl to get mmap offset */
2762
if (!dev->driver->dumb_map_offset)
2763
return -ENOSYS;
2764
2765
return dev->driver->dumb_map_offset(file_priv, dev, args->handle, &args->offset);
2766
}
2767
2768
int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
2769
void *data, struct drm_file *file_priv)
2770
{
2771
struct drm_mode_destroy_dumb *args = data;
2772
2773
if (!dev->driver->dumb_destroy)
2774
return -ENOSYS;
2775
2776
return dev->driver->dumb_destroy(file_priv, dev, args->handle);
2777
}
2778
2779