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