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