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