modesetting: fixup property setting and add connector property
[profile/ivi/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  *
5  * DRM core CRTC related functions
6  *
7  * Permission to use, copy, modify, distribute, and sell this software and its
8  * documentation for any purpose is hereby granted without fee, provided that
9  * the above copyright notice appear in all copies and that both that copyright
10  * notice and this permission notice appear in supporting documentation, and
11  * that the name of the copyright holders not be used in advertising or
12  * publicity pertaining to distribution of the software without specific,
13  * written prior permission.  The copyright holders make no representations
14  * about the suitability of this software for any purpose.  It is provided "as
15  * is" without express or implied warranty.
16  *
17  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
23  * OF THIS SOFTWARE.
24  *
25  * Authors:
26  *      Keith Packard
27  *      Eric Anholt <eric@anholt.net>
28  *      Dave Airlie <airlied@linux.ie>
29  *      Jesse Barnes <jesse.barnes@intel.com>
30  */
31 #include <linux/list.h>
32 #include "drm.h"
33 #include "drmP.h"
34 #include "drm_crtc.h"
35
36 struct drm_prop_enum_list {
37         int type;
38         char *name;
39 };
40
41 static struct drm_prop_enum_list drm_dpms_enum_list[] =
42 { { DPMSModeOn, "On" },
43   { DPMSModeStandby, "Standby" },
44   { DPMSModeSuspend, "Suspend" },
45   { DPMSModeOff, "Off" }
46 };
47 static struct drm_prop_enum_list drm_conn_enum_list[] = 
48 { { ConnectorVGA, "VGA" },
49   { ConnectorDVII, "DVI-I" },
50   { ConnectorDVID, "DVI-D" },
51   { ConnectorDVIA, "DVI-A" },
52   { ConnectorComposite, "Composite" },
53   { ConnectorSVIDEO, "SVIDEO" },
54   { ConnectorLVDS, "LVDS" },
55   { ConnectorComponent, "Component" },
56   { Connector9PinDIN, "9-pin DIN" },
57   { ConnectorDisplayPort, "DisplayPort" },
58   { ConnectorHDMIA, "HDMI Type A" },
59   { ConnectorHDMIB, "HDMI Type B" },
60 };
61
62
63 /**
64  * drm_idr_get - allocate a new identifier
65  * @dev: DRM device
66  * @ptr: object pointer, used to generate unique ID
67  *
68  * LOCKING:
69  * Caller must hold DRM mode_config lock.
70  *
71  * Create a unique identifier based on @ptr in @dev's identifier space.  Used
72  * for tracking modes, CRTCs and outputs.
73  *
74  * RETURNS:
75  * New unique (relative to other objects in @dev) integer identifier for the
76  * object.
77  */
78 int drm_idr_get(struct drm_device *dev, void *ptr)
79 {
80         int new_id = 0;
81         int ret;
82 again:
83         if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
84                 DRM_ERROR("Ran out memory getting a mode number\n");
85                 return 0;
86         }
87
88         ret = idr_get_new_above(&dev->mode_config.crtc_idr, ptr, 1, &new_id);
89         if (ret == -EAGAIN)
90                 goto again;     
91
92         return new_id;
93 }
94
95 /**
96  * drm_idr_put - free an identifer
97  * @dev: DRM device
98  * @id: ID to free
99  *
100  * LOCKING:
101  * Caller must hold DRM mode_config lock.
102  *
103  * Free @id from @dev's unique identifier pool.
104  */
105 void drm_idr_put(struct drm_device *dev, int id)
106 {
107         idr_remove(&dev->mode_config.crtc_idr, id);
108 }
109
110 /**
111  * drm_crtc_from_fb - find the CRTC structure associated with an fb
112  * @dev: DRM device
113  * @fb: framebuffer in question
114  *
115  * LOCKING:
116  * Caller must hold mode_config lock.
117  *
118  * Find CRTC in the mode_config structure that matches @fb.
119  *
120  * RETURNS:
121  * Pointer to the CRTC or NULL if it wasn't found.
122  */
123 struct drm_crtc *drm_crtc_from_fb(struct drm_device *dev,
124                                   struct drm_framebuffer *fb)
125 {
126         struct drm_crtc *crtc;
127
128         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
129                 if (crtc->fb == fb)
130                         return crtc;
131         }
132         return NULL;
133 }
134
135 /**
136  * drm_framebuffer_create - create a new framebuffer object
137  * @dev: DRM device
138  *
139  * LOCKING:
140  * Caller must hold mode config lock.
141  *
142  * Creates a new framebuffer objects and adds it to @dev's DRM mode_config.
143  *
144  * RETURNS:
145  * Pointer to new framebuffer or NULL on error.
146  */
147 struct drm_framebuffer *drm_framebuffer_create(struct drm_device *dev)
148 {
149         struct drm_framebuffer *fb;
150
151         /* Limit to single framebuffer for now */
152         if (dev->mode_config.num_fb > 1) {
153                 mutex_unlock(&dev->mode_config.mutex);
154                 DRM_ERROR("Attempt to add multiple framebuffers failed\n");
155                 return NULL;
156         }
157
158         fb = kzalloc(sizeof(struct drm_framebuffer), GFP_KERNEL);
159         if (!fb)
160                 return NULL;
161         
162         fb->id = drm_idr_get(dev, fb);
163         fb->dev = dev;
164         dev->mode_config.num_fb++;
165         list_add(&fb->head, &dev->mode_config.fb_list);
166
167         return fb;
168 }
169 EXPORT_SYMBOL(drm_framebuffer_create);
170
171 /**
172  * drm_framebuffer_destroy - remove a framebuffer object
173  * @fb: framebuffer to remove
174  *
175  * LOCKING:
176  * Caller must hold mode config lock.
177  *
178  * Scans all the CRTCs in @dev's mode_config.  If they're using @fb, removes
179  * it, setting it to NULL.
180  */
181 void drm_framebuffer_destroy(struct drm_framebuffer *fb)
182 {
183         struct drm_device *dev = fb->dev;
184         struct drm_crtc *crtc;
185
186         /* remove from any CRTC */
187         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
188                 if (crtc->fb == fb)
189                         crtc->fb = NULL;
190         }
191
192         drm_idr_put(dev, fb->id);
193         list_del(&fb->head);
194         dev->mode_config.num_fb--;
195
196         kfree(fb);
197 }
198 EXPORT_SYMBOL(drm_framebuffer_destroy);
199
200 /**
201  * drm_crtc_create - create a new CRTC object
202  * @dev: DRM device
203  * @funcs: callbacks for the new CRTC
204  *
205  * LOCKING:
206  * Caller must hold mode config lock.
207  *
208  * Creates a new CRTC object and adds it to @dev's mode_config structure.
209  *
210  * RETURNS:
211  * Pointer to new CRTC object or NULL on error.
212  */
213 struct drm_crtc *drm_crtc_create(struct drm_device *dev,
214                                  const struct drm_crtc_funcs *funcs)
215 {
216         struct drm_crtc *crtc;
217
218         crtc = kzalloc(sizeof(struct drm_crtc), GFP_KERNEL);
219         if (!crtc)
220                 return NULL;
221
222         crtc->dev = dev;
223         crtc->funcs = funcs;
224
225         crtc->id = drm_idr_get(dev, crtc);
226
227         list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
228         dev->mode_config.num_crtc++;
229
230         return crtc;
231 }
232 EXPORT_SYMBOL(drm_crtc_create);
233
234 /**
235  * drm_crtc_destroy - remove a CRTC object
236  * @crtc: CRTC to remove
237  *
238  * LOCKING:
239  * Caller must hold mode config lock.
240  *
241  * Cleanup @crtc.  Calls @crtc's cleanup function, then removes @crtc from
242  * its associated DRM device's mode_config.  Frees it afterwards.
243  */
244 void drm_crtc_destroy(struct drm_crtc *crtc)
245 {
246         struct drm_device *dev = crtc->dev;
247
248         if (crtc->funcs->cleanup)
249                 (*crtc->funcs->cleanup)(crtc);
250
251         drm_idr_put(dev, crtc->id);
252         list_del(&crtc->head);
253         dev->mode_config.num_crtc--;
254         kfree(crtc);
255 }
256 EXPORT_SYMBOL(drm_crtc_destroy);
257
258 /**
259  * drm_crtc_in_use - check if a given CRTC is in a mode_config
260  * @crtc: CRTC to check
261  *
262  * LOCKING:
263  * Caller must hold mode config lock.
264  *
265  * Walk @crtc's DRM device's mode_config and see if it's in use.
266  *
267  * RETURNS:
268  * True if @crtc is part of the mode_config, false otherwise.
269  */
270 bool drm_crtc_in_use(struct drm_crtc *crtc)
271 {
272         struct drm_output *output;
273         struct drm_device *dev = crtc->dev;
274         /* FIXME: Locking around list access? */
275         list_for_each_entry(output, &dev->mode_config.output_list, head)
276                 if (output->crtc == crtc)
277                         return true;
278         return false;
279 }
280 EXPORT_SYMBOL(drm_crtc_in_use);
281
282 /*
283  * Detailed mode info for a standard 640x480@60Hz monitor
284  */
285 static struct drm_display_mode std_mode[] = {
286         { DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 25200, 640, 656,
287                    752, 800, 0, 480, 490, 492, 525, 0,
288                    V_NHSYNC | V_NVSYNC) }, /* 640x480@60Hz */
289 };
290
291 /**
292  * drm_crtc_probe_output_modes - get complete set of display modes
293  * @dev: DRM device
294  * @maxX: max width for modes
295  * @maxY: max height for modes
296  *
297  * LOCKING:
298  * Caller must hold mode config lock.
299  *
300  * Based on @dev's mode_config layout, scan all the outputs and try to detect
301  * modes on them.  Modes will first be added to the output's probed_modes
302  * list, then culled (based on validity and the @maxX, @maxY parameters) and
303  * put into the normal modes list.
304  *
305  * Intended to be used either at bootup time or when major configuration
306  * changes have occurred.
307  *
308  * FIXME: take into account monitor limits
309  */
310 void drm_crtc_probe_single_output_modes(struct drm_output *output, int maxX, int maxY)
311 {
312         struct drm_device *dev = output->dev;
313         struct drm_display_mode *mode, *t;
314         int ret;
315         //if (maxX == 0 || maxY == 0) 
316         // TODO
317
318         /* set all modes to the unverified state */
319         list_for_each_entry_safe(mode, t, &output->modes, head)
320                 mode->status = MODE_UNVERIFIED;
321                 
322         output->status = (*output->funcs->detect)(output);
323         
324         if (output->status == output_status_disconnected) {
325                 DRM_DEBUG("%s is disconnected\n", output->name);
326                 /* TODO set EDID to NULL */
327                 return;
328         }
329         
330         ret = (*output->funcs->get_modes)(output);
331         
332         if (ret) {
333                 drm_mode_output_list_update(output);
334         }
335         
336         if (maxX && maxY)
337                 drm_mode_validate_size(dev, &output->modes, maxX,
338                                        maxY, 0);
339         list_for_each_entry_safe(mode, t, &output->modes, head) {
340                 if (mode->status == MODE_OK)
341                         mode->status = (*output->funcs->mode_valid)(output,mode);
342         }
343         
344         
345         drm_mode_prune_invalid(dev, &output->modes, TRUE);
346         
347         if (list_empty(&output->modes)) {
348                 struct drm_display_mode *stdmode;
349                 
350                 DRM_DEBUG("No valid modes on %s\n", output->name);
351                 
352                 /* Should we do this here ???
353                  * When no valid EDID modes are available we end up
354                  * here and bailed in the past, now we add a standard
355                  * 640x480@60Hz mode and carry on.
356                  */
357                 stdmode = drm_mode_duplicate(dev, &std_mode[0]);
358                 drm_mode_probed_add(output, stdmode);
359                 drm_mode_list_concat(&output->probed_modes,
360                                      &output->modes);
361                 
362                 DRM_DEBUG("Adding standard 640x480 @ 60Hz to %s\n",
363                           output->name);
364         }
365         
366         drm_mode_sort(&output->modes);
367         
368         DRM_DEBUG("Probed modes for %s\n", output->name);
369         list_for_each_entry_safe(mode, t, &output->modes, head) {
370                 mode->vrefresh = drm_mode_vrefresh(mode);
371                 
372                 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
373                 drm_mode_debug_printmodeline(dev, mode);
374         }
375 }
376
377 void drm_crtc_probe_output_modes(struct drm_device *dev, int maxX, int maxY)
378 {
379         struct drm_output *output;
380
381         list_for_each_entry(output, &dev->mode_config.output_list, head) {
382                 drm_crtc_probe_single_output_modes(output, maxX, maxY);
383         }
384 }
385
386 /**
387  * drm_crtc_set_mode - set a mode
388  * @crtc: CRTC to program
389  * @mode: mode to use
390  * @x: width of mode
391  * @y: height of mode
392  *
393  * LOCKING:
394  * Caller must hold mode config lock.
395  *
396  * Try to set @mode on @crtc.  Give @crtc and its associated outputs a chance
397  * to fixup or reject the mode prior to trying to set it.
398  *
399  * RETURNS:
400  * True if the mode was set successfully, or false otherwise.
401  */
402 bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
403                        int x, int y)
404 {
405         struct drm_device *dev = crtc->dev;
406         struct drm_display_mode *adjusted_mode, saved_mode;
407         int saved_x, saved_y;
408         bool didLock = false;
409         bool ret = false;
410         struct drm_output *output;
411
412         adjusted_mode = drm_mode_duplicate(dev, mode);
413
414         crtc->enabled = drm_crtc_in_use(crtc);
415
416         if (!crtc->enabled) {
417                 return true;
418         }
419
420         didLock = crtc->funcs->lock(crtc);
421
422         saved_mode = crtc->mode;
423         saved_x = crtc->x;
424         saved_y = crtc->y;
425         
426         /* Update crtc values up front so the driver can rely on them for mode
427          * setting.
428          */
429         crtc->mode = *mode;
430         crtc->x = x;
431         crtc->y = y;
432
433         /* XXX short-circuit changes to base location only */
434         
435         /* Pass our mode to the outputs and the CRTC to give them a chance to
436          * adjust it according to limitations or output properties, and also
437          * a chance to reject the mode entirely.
438          */
439         list_for_each_entry(output, &dev->mode_config.output_list, head) {
440                 
441                 if (output->crtc != crtc)
442                         continue;
443                 
444                 if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) {
445                         goto done;
446                 }
447         }
448         
449         if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) {
450                 goto done;
451         }
452
453         /* Prepare the outputs and CRTCs before setting the mode. */
454         list_for_each_entry(output, &dev->mode_config.output_list, head) {
455
456                 if (output->crtc != crtc)
457                         continue;
458                 
459                 /* Disable the output as the first thing we do. */
460                 output->funcs->prepare(output);
461         }
462         
463         crtc->funcs->prepare(crtc);
464         
465         /* Set up the DPLL and any output state that needs to adjust or depend
466          * on the DPLL.
467          */
468         crtc->funcs->mode_set(crtc, mode, adjusted_mode, x, y);
469
470         list_for_each_entry(output, &dev->mode_config.output_list, head) {
471
472                 if (output->crtc != crtc)
473                         continue;
474                 
475                 DRM_INFO("%s: set mode %s %x\n", output->name, mode->name, mode->mode_id);
476
477                 output->funcs->mode_set(output, mode, adjusted_mode);
478         }
479         
480         /* Now, enable the clocks, plane, pipe, and outputs that we set up. */
481         crtc->funcs->commit(crtc);
482
483         list_for_each_entry(output, &dev->mode_config.output_list, head) {
484
485                 if (output->crtc != crtc)
486                         continue;
487                 
488                 output->funcs->commit(output);
489
490 #if 0 // TODO def RANDR_12_INTERFACE
491                 if (output->randr_output)
492                         RRPostPendingProperties (output->randr_output);
493 #endif
494         }
495         
496         /* XXX free adjustedmode */
497         drm_mode_destroy(dev, adjusted_mode);
498         ret = TRUE;
499         /* TODO */
500 //      if (scrn->pScreen)
501 //              drm_crtc_set_screen_sub_pixel_order(dev);
502
503 done:
504         if (!ret) {
505                 crtc->x = saved_x;
506                 crtc->y = saved_y;
507                 crtc->mode = saved_mode;
508         }
509         
510         if (didLock)
511                 crtc->funcs->unlock (crtc);
512         
513         return ret;
514 }
515 EXPORT_SYMBOL(drm_crtc_set_mode);
516
517 /**
518  * drm_disable_unused_functions - disable unused objects
519  * @dev: DRM device
520  *
521  * LOCKING:
522  * Caller must hold mode config lock.
523  *
524  * If an output or CRTC isn't part of @dev's mode_config, it can be disabled
525  * by calling its dpms function, which should power it off.
526  */
527 void drm_disable_unused_functions(struct drm_device *dev)
528 {
529         struct drm_output *output;
530         struct drm_crtc *crtc;
531
532         list_for_each_entry(output, &dev->mode_config.output_list, head) {
533                 if (!output->crtc)
534                         (*output->funcs->dpms)(output, DPMSModeOff);
535         }
536
537         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
538                 if (!crtc->enabled)
539                         crtc->funcs->dpms(crtc, DPMSModeOff);
540         }
541 }
542         
543 /**
544  * drm_mode_probed_add - add a mode to the specified output's probed mode list
545  * @output: output the new mode
546  * @mode: mode data
547  *
548  * LOCKING:
549  * Caller must hold mode config lock.
550  * 
551  * Add @mode to @output's mode list for later use.
552  */
553 void drm_mode_probed_add(struct drm_output *output,
554                          struct drm_display_mode *mode)
555 {
556         list_add(&mode->head, &output->probed_modes);
557 }
558 EXPORT_SYMBOL(drm_mode_probed_add);
559
560 /**
561  * drm_mode_remove - remove and free a mode
562  * @output: output list to modify
563  * @mode: mode to remove
564  *
565  * LOCKING:
566  * Caller must hold mode config lock.
567  * 
568  * Remove @mode from @output's mode list, then free it.
569  */
570 void drm_mode_remove(struct drm_output *output, struct drm_display_mode *mode)
571 {
572         list_del(&mode->head);
573         kfree(mode);
574 }
575 EXPORT_SYMBOL(drm_mode_remove);
576
577 /**
578  * drm_output_create - create a new output
579  * @dev: DRM device
580  * @funcs: callbacks for this output
581  * @name: user visible name of the output
582  *
583  * LOCKING:
584  * Caller must hold @dev's mode_config lock.
585  *
586  * Creates a new drm_output structure and adds it to @dev's mode_config
587  * structure.
588  *
589  * RETURNS:
590  * Pointer to the new output or NULL on error.
591  */
592 struct drm_output *drm_output_create(struct drm_device *dev,
593                                      const struct drm_output_funcs *funcs,
594                                      const char *name)
595 {
596         struct drm_output *output = NULL;
597
598         output = kzalloc(sizeof(struct drm_output), GFP_KERNEL);
599         if (!output)
600                 return NULL;
601                 
602         output->dev = dev;
603         output->funcs = funcs;
604         output->id = drm_idr_get(dev, output);
605         if (name)
606                 strncpy(output->name, name, DRM_OUTPUT_LEN);
607         output->name[DRM_OUTPUT_LEN - 1] = 0;
608         output->subpixel_order = SubPixelUnknown;
609         INIT_LIST_HEAD(&output->user_modes);
610         INIT_LIST_HEAD(&output->probed_modes);
611         INIT_LIST_HEAD(&output->modes);
612         /* randr_output? */
613         /* output_set_monitor(output)? */
614         /* check for output_ignored(output)? */
615
616         mutex_lock(&dev->mode_config.mutex);
617         list_add_tail(&output->head, &dev->mode_config.output_list);
618         dev->mode_config.num_output++;
619
620         drm_output_attach_property(output, dev->mode_config.edid_property, 0);
621
622         drm_output_attach_property(output, dev->mode_config.dpms_property, 0);
623
624         mutex_unlock(&dev->mode_config.mutex);
625
626         return output;
627
628 }
629 EXPORT_SYMBOL(drm_output_create);
630
631 /**
632  * drm_output_destroy - remove an output
633  * @output: output to remove
634  *
635  * LOCKING:
636  * Caller must hold @dev's mode_config lock.
637  *
638  * Call @output's cleanup function, then remove the output from the DRM
639  * mode_config after freeing @output's modes.
640  */
641 void drm_output_destroy(struct drm_output *output)
642 {
643         struct drm_device *dev = output->dev;
644         struct drm_display_mode *mode, *t;
645
646         if (*output->funcs->cleanup)
647                 (*output->funcs->cleanup)(output);
648
649         list_for_each_entry_safe(mode, t, &output->probed_modes, head)
650                 drm_mode_remove(output, mode);
651
652         list_for_each_entry_safe(mode, t, &output->modes, head)
653                 drm_mode_remove(output, mode);
654
655         list_for_each_entry_safe(mode, t, &output->user_modes, head)
656                 drm_mode_remove(output, mode);
657
658         mutex_lock(&dev->mode_config.mutex);
659         drm_idr_put(dev, output->id);
660         list_del(&output->head);
661         mutex_unlock(&dev->mode_config.mutex);
662         kfree(output);
663 }
664 EXPORT_SYMBOL(drm_output_destroy);
665
666 /**
667  * drm_output_rename - rename an output
668  * @output: output to rename
669  * @name: new user visible name
670  *
671  * LOCKING:
672  * None.
673  *
674  * Simply stuff a new name into @output's name field, based on @name.
675  *
676  * RETURNS:
677  * True if the name was changed, false otherwise.
678  */
679 bool drm_output_rename(struct drm_output *output, const char *name)
680 {
681         if (!name)
682                 return false;
683
684         strncpy(output->name, name, DRM_OUTPUT_LEN);
685         output->name[DRM_OUTPUT_LEN - 1] = 0;
686
687         DRM_DEBUG("Changed name to %s\n", output->name);
688 //      drm_output_set_monitor(output);
689 //      if (drm_output_ignored(output))
690 //              return FALSE;
691
692         return TRUE;
693 }
694 EXPORT_SYMBOL(drm_output_rename);
695
696 /**
697  * drm_mode_create - create a new display mode
698  * @dev: DRM device
699  *
700  * LOCKING:
701  * None.
702  *
703  * Create a new drm_display_mode, give it an ID, and return it.
704  *
705  * RETURNS:
706  * Pointer to new mode on success, NULL on error.
707  */
708 struct drm_display_mode *drm_mode_create(struct drm_device *dev)
709 {
710         struct drm_display_mode *nmode;
711
712         nmode = kzalloc(sizeof(struct drm_display_mode), GFP_KERNEL);
713         if (!nmode)
714                 return NULL;
715
716         nmode->mode_id = drm_idr_get(dev, nmode);
717         return nmode;
718 }
719 EXPORT_SYMBOL(drm_mode_create);
720
721 /**
722  * drm_mode_destroy - remove a mode
723  * @dev: DRM device
724  * @mode: mode to remove
725  *
726  * LOCKING:
727  * Caller must hold mode config lock.
728  *
729  * Free @mode's unique identifier, then free it.
730  */
731 void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
732 {
733         drm_idr_put(dev, mode->mode_id);
734
735         kfree(mode);
736 }
737 EXPORT_SYMBOL(drm_mode_destroy);
738
739 static int drm_mode_create_standard_output_properties(struct drm_device *dev)
740 {
741         int i;
742
743         dev->mode_config.edid_property =
744                 drm_property_create(dev, DRM_MODE_PROP_BLOB | DRM_MODE_PROP_IMMUTABLE,
745                                     "EDID", 0);
746
747         dev->mode_config.dpms_property =
748                 drm_property_create(dev, DRM_MODE_PROP_ENUM, "DPMS", 4);
749
750         for (i = 0; i < ARRAY_SIZE(drm_dpms_enum_list); i++)
751                 drm_property_add_enum(dev->mode_config.dpms_property, i, drm_dpms_enum_list[i].type, drm_dpms_enum_list[i].name);
752
753         dev->mode_config.connector_type_property =
754                 drm_property_create(dev, DRM_MODE_PROP_ENUM | DRM_MODE_PROP_IMMUTABLE,
755                                     "Connector Type", 10);
756         for (i = 0; i < ARRAY_SIZE(drm_conn_enum_list); i++)
757                 drm_property_add_enum(dev->mode_config.connector_type_property, i, drm_conn_enum_list[i].type, drm_conn_enum_list[i].name);
758
759         dev->mode_config.connector_num_property =
760                 drm_property_create(dev, DRM_MODE_PROP_RANGE | DRM_MODE_PROP_IMMUTABLE,
761                                     "Connector ID", 2);
762         dev->mode_config.connector_num_property->values[0] = 0;
763         dev->mode_config.connector_num_property->values[1] = 20;
764         return 0;
765 }
766
767 /**
768  * drm_mode_config_init - initialize DRM mode_configuration structure
769  * @dev: DRM device
770  *
771  * LOCKING:
772  * None, should happen single threaded at init time.
773  *
774  * Initialize @dev's mode_config structure, used for tracking the graphics
775  * configuration of @dev.
776  */
777 void drm_mode_config_init(struct drm_device *dev)
778 {
779         mutex_init(&dev->mode_config.mutex);
780         INIT_LIST_HEAD(&dev->mode_config.fb_list);
781         INIT_LIST_HEAD(&dev->mode_config.crtc_list);
782         INIT_LIST_HEAD(&dev->mode_config.output_list);
783         INIT_LIST_HEAD(&dev->mode_config.property_list);
784         INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
785         idr_init(&dev->mode_config.crtc_idr);
786
787         drm_mode_create_standard_output_properties(dev);
788         
789 }
790 EXPORT_SYMBOL(drm_mode_config_init);
791
792 /**
793  * drm_get_buffer_object - find the buffer object for a given handle
794  * @dev: DRM device
795  * @bo: pointer to caller's buffer_object pointer
796  * @handle: handle to lookup
797  *
798  * LOCKING:
799  * Must take @dev's struct_mutex to protect buffer object lookup.
800  *
801  * Given @handle, lookup the buffer object in @dev and put it in the caller's
802  * @bo pointer.
803  *
804  * RETURNS:
805  * Zero on success, -EINVAL if the handle couldn't be found.
806  */
807 static int drm_get_buffer_object(struct drm_device *dev, struct drm_buffer_object **bo, unsigned long handle)
808 {
809         struct drm_user_object *uo;
810         struct drm_hash_item *hash;
811         int ret;
812
813         *bo = NULL;
814
815         mutex_lock(&dev->struct_mutex);
816         ret = drm_ht_find_item(&dev->object_hash, handle, &hash);
817         if (ret) {
818                 DRM_ERROR("Couldn't find handle.\n");
819                 ret = -EINVAL;
820                 goto out_err;
821         }
822
823         uo = drm_hash_entry(hash, struct drm_user_object, hash);
824         if (uo->type != drm_buffer_type) {
825                 ret = -EINVAL;
826                 goto out_err;
827         }
828         
829         *bo = drm_user_object_entry(uo, struct drm_buffer_object, base);
830         ret = 0;
831 out_err:
832         mutex_unlock(&dev->struct_mutex);
833         return ret;
834 }
835
836 /**
837  * drm_pick_crtcs - pick crtcs for output devices
838  * @dev: DRM device
839  *
840  * LOCKING:
841  * Caller must hold mode config lock.
842  */
843 static void drm_pick_crtcs (struct drm_device *dev)
844 {
845         int c, o, assigned;
846         struct drm_output *output, *output_equal;
847         struct drm_crtc   *crtc;
848         struct drm_display_mode *des_mode = NULL, *modes, *modes_equal;
849
850         list_for_each_entry(output, &dev->mode_config.output_list, head) {
851                 output->crtc = NULL;
852     
853                 /* Don't hook up outputs that are disconnected ??
854                  *
855                  * This is debateable. Do we want fixed /dev/fbX or
856                  * dynamic on hotplug (need mode code for that though) ?
857                  *
858                  * If we don't hook up outputs now, then we only create
859                  * /dev/fbX for the output that's enabled, that's good as
860                  * the users console will be on that output.
861                  *
862                  * If we do hook up outputs that are disconnected now, then
863                  * the user may end up having to muck about with the fbcon
864                  * map flags to assign his console to the enabled output. Ugh.
865                  */
866                 if (output->status != output_status_connected)
867                         continue;
868
869                 des_mode = NULL;
870                 list_for_each_entry(des_mode, &output->modes, head) {
871                         if (des_mode->type & DRM_MODE_TYPE_PREFERRED)
872                                 break;
873                 }
874
875                 /* No preferred mode, let's just select the first available */
876                 if (!des_mode || !(des_mode->type & DRM_MODE_TYPE_PREFERRED)) {
877                         list_for_each_entry(des_mode, &output->modes, head) {
878                                 if (des_mode)
879                                         break;
880                         }
881                 }
882
883                 c = -1;
884                 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
885                         assigned = 0;
886
887                         c++;
888                         if ((output->possible_crtcs & (1 << c)) == 0)
889                                 continue;
890         
891                         list_for_each_entry(output_equal, &dev->mode_config.output_list, head) {
892                                 if (output->id == output_equal->id)
893                                         continue;
894
895                                 /* Find out if crtc has been assigned before */
896                                 if (output_equal->crtc == crtc)
897                                         assigned = 1;
898                         }
899
900 #if 1 /* continue for now */
901                         if (assigned)
902                                 continue;
903 #endif
904
905                         o = -1;
906                         list_for_each_entry(output_equal, &dev->mode_config.output_list, head) {
907                                 o++;
908                                 if (output->id == output_equal->id)
909                                         continue;
910
911                                 list_for_each_entry(modes, &output->modes, head) {
912                                         list_for_each_entry(modes_equal, &output_equal->modes, head) {
913                                                 if (drm_mode_equal (modes, modes_equal)) {
914                                                         if ((output->possible_clones & output_equal->possible_clones) && (output_equal->crtc == crtc)) {
915                                                                 printk("Cloning %s (0x%lx) to %s (0x%lx)\n",output->name,output->possible_clones,output_equal->name,output_equal->possible_clones);
916                                                                 assigned = 0;
917                                                                 goto clone;
918                                                         }
919                                                 }
920                                         }
921                                 }
922                         }
923
924 clone:
925                         /* crtc has been assigned skip it */
926                         if (assigned)
927                                 continue;
928
929                         /* Found a CRTC to attach to, do it ! */
930                         output->crtc = crtc;
931                         output->crtc->desired_mode = des_mode;
932                         output->initial_x = 0;
933                         output->initial_y = 0;
934                         DRM_DEBUG("Desired mode for CRTC %d is 0x%x:%s\n",c,des_mode->mode_id, des_mode->name);
935                         break;
936                 }
937         }
938 }
939
940
941 /**
942  * drm_initial_config - setup a sane initial output configuration
943  * @dev: DRM device
944  * @can_grow: this configuration is growable
945  *
946  * LOCKING:
947  * Called at init time, must take mode config lock.
948  *
949  * Scan the CRTCs and outputs and try to put together an initial setup.
950  * At the moment, this is a cloned configuration across all heads with
951  * a new framebuffer object as the backing store.
952  *
953  * RETURNS:
954  * Zero if everything went ok, nonzero otherwise.
955  */
956 bool drm_initial_config(struct drm_device *dev, bool can_grow)
957 {
958         struct drm_output *output;
959         struct drm_crtc *crtc;
960         int ret = false;
961
962         mutex_lock(&dev->mode_config.mutex);
963
964         drm_crtc_probe_output_modes(dev, 2048, 2048);
965
966         drm_pick_crtcs(dev);
967
968         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
969
970                 /* can't setup the crtc if there's no assigned mode */
971                 if (!crtc->desired_mode)
972                         continue;
973
974                 /* Now setup the fbdev for attached crtcs */
975                 dev->driver->fb_probe(dev, crtc);
976         }
977
978         /* This is a little screwy, as we've already walked the outputs 
979          * above, but it's a little bit of magic too. There's the potential
980          * for things not to get setup above if an existing device gets
981          * re-assigned thus confusing the hardware. By walking the outputs
982          * this fixes up their crtc's.
983          */
984         list_for_each_entry(output, &dev->mode_config.output_list, head) {
985
986                 /* can't setup the output if there's no assigned mode */
987                 if (!output->crtc || !output->crtc->desired_mode)
988                         continue;
989
990                 /* and needs an attached fb */
991                 if (output->crtc->fb)
992                         drm_crtc_set_mode(output->crtc, output->crtc->desired_mode, 0, 0);
993         }
994
995         drm_disable_unused_functions(dev);
996
997         mutex_unlock(&dev->mode_config.mutex);
998         return ret;
999 }
1000 EXPORT_SYMBOL(drm_initial_config);
1001
1002 /**
1003  * drm_mode_config_cleanup - free up DRM mode_config info
1004  * @dev: DRM device
1005  *
1006  * LOCKING:
1007  * Caller must hold mode config lock.
1008  *
1009  * Free up all the outputs and CRTCs associated with this DRM device, then
1010  * free up the framebuffers and associated buffer objects.
1011  *
1012  * FIXME: cleanup any dangling user buffer objects too
1013  */
1014 void drm_mode_config_cleanup(struct drm_device *dev)
1015 {
1016         struct drm_output *output, *ot;
1017         struct drm_crtc *crtc, *ct;
1018         struct drm_framebuffer *fb, *fbt;
1019         struct drm_property *property, *pt;
1020
1021         list_for_each_entry_safe(output, ot, &dev->mode_config.output_list, head) {
1022                 drm_output_destroy(output);
1023         }
1024
1025         list_for_each_entry_safe(property, pt, &dev->mode_config.property_list, head) {
1026                 drm_property_destroy(dev, property);
1027         }
1028
1029         list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
1030                 if (fb->bo->type != drm_bo_type_kernel)
1031                         drm_framebuffer_destroy(fb);
1032                 else
1033                         dev->driver->fb_remove(dev, drm_crtc_from_fb(dev, fb));
1034         }
1035
1036         list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
1037                 drm_crtc_destroy(crtc);
1038         }
1039
1040 }
1041 EXPORT_SYMBOL(drm_mode_config_cleanup);
1042
1043 /**
1044  * drm_crtc_set_config - set a new config from userspace
1045  * @crtc: CRTC to setup
1046  * @crtc_info: user provided configuration
1047  * @new_mode: new mode to set
1048  * @output_set: set of outputs for the new config
1049  * @fb: new framebuffer
1050  *
1051  * LOCKING:
1052  * Caller must hold mode config lock.
1053  *
1054  * Setup a new configuration, provided by the user in @crtc_info, and enable
1055  * it.
1056  *
1057  * RETURNS:
1058  * Zero. (FIXME)
1059  */
1060 int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, struct drm_display_mode *new_mode, struct drm_output **output_set, struct drm_framebuffer *fb)
1061 {
1062         struct drm_device *dev = crtc->dev;
1063         struct drm_crtc **save_crtcs, *new_crtc;
1064         bool save_enabled = crtc->enabled;
1065         bool changed = false;
1066         struct drm_output *output;
1067         int count = 0, ro;
1068
1069         save_crtcs = kzalloc(dev->mode_config.num_crtc * sizeof(struct drm_crtc *), GFP_KERNEL);
1070         if (!save_crtcs)
1071                 return -ENOMEM;
1072
1073         if (crtc->fb != fb)
1074                 changed = true;
1075
1076         if (crtc_info->x != crtc->x || crtc_info->y != crtc->y)
1077                 changed = true;
1078
1079         if (new_mode && !drm_mode_equal(new_mode, &crtc->mode))
1080                 changed = true;
1081
1082         list_for_each_entry(output, &dev->mode_config.output_list, head) {
1083                 save_crtcs[count++] = output->crtc;
1084
1085                 if (output->crtc == crtc)
1086                         new_crtc = NULL;
1087                 else
1088                         new_crtc = output->crtc;
1089
1090                 for (ro = 0; ro < crtc_info->count_outputs; ro++) {
1091                         if (output_set[ro] == output)
1092                                 new_crtc = crtc;
1093                 }
1094                 if (new_crtc != output->crtc) {
1095                         changed = true;
1096                         output->crtc = new_crtc;
1097                 }
1098         }
1099
1100         if (changed) {
1101                 crtc->fb = fb;
1102                 crtc->enabled = (new_mode != NULL);
1103                 if (new_mode != NULL) {
1104                         DRM_DEBUG("attempting to set mode from userspace\n");
1105                         drm_mode_debug_printmodeline(dev, new_mode);
1106                         if (!drm_crtc_set_mode(crtc, new_mode, crtc_info->x,
1107                                                crtc_info->y)) {
1108                                 crtc->enabled = save_enabled;
1109                                 count = 0;
1110                                 list_for_each_entry(output, &dev->mode_config.output_list, head)
1111                                         output->crtc = save_crtcs[count++];
1112                                 kfree(save_crtcs);
1113                                 return -EINVAL;
1114                         }
1115                         crtc->desired_x = crtc_info->x;
1116                         crtc->desired_y = crtc_info->y;
1117                         crtc->desired_mode = new_mode;
1118                 }
1119                 drm_disable_unused_functions(dev);
1120         }
1121         kfree(save_crtcs);
1122         return 0;
1123 }
1124
1125 /**
1126  * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
1127  * @out: drm_mode_modeinfo struct to return to the user
1128  * @in: drm_display_mode to use
1129  *
1130  * LOCKING:
1131  * None.
1132  *
1133  * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
1134  * the user.
1135  */
1136 void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out, struct drm_display_mode *in)
1137 {
1138         out->clock = in->clock;
1139         out->hdisplay = in->hdisplay;
1140         out->hsync_start = in->hsync_start;
1141         out->hsync_end = in->hsync_end;
1142         out->htotal = in->htotal;
1143         out->hskew = in->hskew;
1144         out->vdisplay = in->vdisplay;
1145         out->vsync_start = in->vsync_start;
1146         out->vsync_end = in->vsync_end;
1147         out->vtotal = in->vtotal;
1148         out->vscan = in->vscan;
1149         out->vrefresh = in->vrefresh;
1150         out->flags = in->flags;
1151         out->type = in->type;
1152         strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
1153         out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1154 }
1155
1156 /**
1157  * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode
1158  * @out: drm_display_mode to return to the user
1159  * @in: drm_mode_modeinfo to use
1160  *
1161  * LOCKING:
1162  * None.
1163  *
1164  * Convert a drmo_mode_modeinfo into a drm_display_mode structure to return to
1165  * the caller.
1166  */
1167 void drm_crtc_convert_umode(struct drm_display_mode *out, struct drm_mode_modeinfo *in)
1168 {
1169         out->clock = in->clock;
1170         out->hdisplay = in->hdisplay;
1171         out->hsync_start = in->hsync_start;
1172         out->hsync_end = in->hsync_end;
1173         out->htotal = in->htotal;
1174         out->hskew = in->hskew;
1175         out->vdisplay = in->vdisplay;
1176         out->vsync_start = in->vsync_start;
1177         out->vsync_end = in->vsync_end;
1178         out->vtotal = in->vtotal;
1179         out->vscan = in->vscan;
1180         out->vrefresh = in->vrefresh;
1181         out->flags = in->flags;
1182         out->type = in->type;
1183         strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
1184         out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1185 }
1186         
1187 /**
1188  * drm_mode_getresources - get graphics configuration
1189  * @inode: inode from the ioctl
1190  * @filp: file * from the ioctl
1191  * @cmd: cmd from ioctl
1192  * @arg: arg from ioctl
1193  *
1194  * LOCKING:
1195  * Takes mode config lock.
1196  *
1197  * Construct a set of configuration description structures and return
1198  * them to the user, including CRTC, output and framebuffer configuration.
1199  *
1200  * Called by the user via ioctl.
1201  *
1202  * RETURNS:
1203  * Zero on success, errno on failure.
1204  */
1205 int drm_mode_getresources(struct drm_device *dev,
1206                           void *data, struct drm_file *file_priv)
1207 {
1208         struct drm_mode_card_res *card_res = data;
1209         struct list_head *lh;
1210         struct drm_framebuffer *fb;
1211         struct drm_output *output;
1212         struct drm_crtc *crtc;
1213         int ret = 0;
1214         int output_count = 0;
1215         int crtc_count = 0;
1216         int fb_count = 0;
1217         int copied = 0;
1218         uint32_t __user *fb_id;
1219         uint32_t __user *crtc_id;
1220         uint32_t __user *output_id;
1221
1222         mutex_lock(&dev->mode_config.mutex);
1223
1224         list_for_each(lh, &dev->mode_config.fb_list)
1225                 fb_count++;
1226
1227         list_for_each(lh, &dev->mode_config.crtc_list)
1228                 crtc_count++;
1229
1230         list_for_each(lh, &dev->mode_config.output_list)
1231                 output_count++;
1232
1233         card_res->max_height = dev->mode_config.max_height;
1234         card_res->min_height = dev->mode_config.min_height;
1235         card_res->max_width = dev->mode_config.max_width;
1236         card_res->min_width = dev->mode_config.min_width;
1237
1238         /* handle this in 4 parts */
1239         /* FBs */
1240         if (card_res->count_fbs >= fb_count) {
1241                 copied = 0;
1242                 fb_id = (uint32_t *)(unsigned long)card_res->fb_id_ptr;
1243                 list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
1244                         if (put_user(fb->id, fb_id + copied)) {
1245                                 ret = -EFAULT;
1246                                 goto out;
1247                         }
1248                         copied++;
1249                 }
1250         }
1251         card_res->count_fbs = fb_count;
1252
1253         /* CRTCs */
1254         if (card_res->count_crtcs >= crtc_count) {
1255                 copied = 0;
1256                 crtc_id = (uint32_t *)(unsigned long)card_res->crtc_id_ptr;
1257                 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head){
1258                         DRM_DEBUG("CRTC ID is %d\n", crtc->id);
1259                         if (put_user(crtc->id, crtc_id + copied)) {
1260                                 ret = -EFAULT;
1261                                 goto out;
1262                         }
1263                         copied++;
1264                 }
1265         }
1266         card_res->count_crtcs = crtc_count;
1267
1268
1269         /* Outputs */
1270         if (card_res->count_outputs >= output_count) {
1271                 copied = 0;
1272                 output_id = (uint32_t *)(unsigned long)card_res->output_id_ptr;
1273                 list_for_each_entry(output, &dev->mode_config.output_list,
1274                                     head) {
1275                         DRM_DEBUG("OUTPUT ID is %d\n", output->id);
1276                         if (put_user(output->id, output_id + copied)) {
1277                                 ret = -EFAULT;
1278                                 goto out;
1279                         }
1280                         copied++;
1281                 }
1282         }
1283         card_res->count_outputs = output_count;
1284         
1285         DRM_DEBUG("Counted %d %d\n", card_res->count_crtcs,
1286                   card_res->count_outputs);
1287
1288 out:    
1289         mutex_unlock(&dev->mode_config.mutex);
1290         return ret;
1291 }
1292
1293 /**
1294  * drm_mode_getcrtc - get CRTC configuration
1295  * @inode: inode from the ioctl
1296  * @filp: file * from the ioctl
1297  * @cmd: cmd from ioctl
1298  * @arg: arg from ioctl
1299  *
1300  * LOCKING:
1301  * Caller? (FIXME)
1302  *
1303  * Construct a CRTC configuration structure to return to the user.
1304  *
1305  * Called by the user via ioctl.
1306  *
1307  * RETURNS:
1308  * Zero on success, errno on failure.
1309  */
1310 int drm_mode_getcrtc(struct drm_device *dev,
1311                      void *data, struct drm_file *file_priv)
1312 {
1313         struct drm_mode_crtc *crtc_resp = data;
1314         struct drm_crtc *crtc;
1315         struct drm_output *output;
1316         int ocount;
1317         int ret = 0;
1318
1319         mutex_lock(&dev->mode_config.mutex);
1320         crtc = idr_find(&dev->mode_config.crtc_idr, crtc_resp->crtc_id);
1321         if (!crtc || (crtc->id != crtc_resp->crtc_id)) {
1322                 ret = -EINVAL;
1323                 goto out;
1324         }
1325
1326         crtc_resp->x = crtc->x;
1327         crtc_resp->y = crtc->y;
1328
1329         if (crtc->fb)
1330                 crtc_resp->fb_id = crtc->fb->id;
1331         else
1332                 crtc_resp->fb_id = 0;
1333
1334         crtc_resp->outputs = 0;
1335         if (crtc->enabled) {
1336
1337                 drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode);
1338                 crtc_resp->mode_valid = 1;
1339                 ocount = 0;
1340                 list_for_each_entry(output, &dev->mode_config.output_list, head) {
1341                         if (output->crtc == crtc)
1342                                 crtc_resp->outputs |= 1 << (ocount++);
1343                 }
1344                 
1345         } else {
1346                 crtc_resp->mode_valid = 0;
1347         }
1348
1349 out:
1350         mutex_unlock(&dev->mode_config.mutex);
1351         return ret;
1352 }
1353
1354 /**
1355  * drm_mode_getoutput - get output configuration
1356  * @inode: inode from the ioctl
1357  * @filp: file * from the ioctl
1358  * @cmd: cmd from ioctl
1359  * @arg: arg from ioctl
1360  *
1361  * LOCKING:
1362  * Caller? (FIXME)
1363  *
1364  * Construct a output configuration structure to return to the user.
1365  *
1366  * Called by the user via ioctl.
1367  *
1368  * RETURNS:
1369  * Zero on success, errno on failure.
1370  */
1371 int drm_mode_getoutput(struct drm_device *dev,
1372                        void *data, struct drm_file *file_priv)
1373 {
1374         struct drm_mode_get_output *out_resp = data;
1375         struct drm_output *output;
1376         struct drm_display_mode *mode;
1377         int mode_count = 0;
1378         int props_count = 0;
1379         int ret = 0;
1380         int copied = 0;
1381         int i;
1382         struct drm_mode_modeinfo u_mode;
1383         struct drm_mode_modeinfo __user *mode_ptr;
1384         uint32_t __user *prop_ptr;
1385         uint64_t __user *prop_values;
1386
1387         memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
1388
1389         DRM_DEBUG("output id %d:\n", out_resp->output);
1390
1391         mutex_lock(&dev->mode_config.mutex);
1392         output= idr_find(&dev->mode_config.crtc_idr, out_resp->output);
1393         if (!output || (output->id != out_resp->output)) {
1394                 ret = -EINVAL;
1395                 goto out;
1396         }
1397
1398         list_for_each_entry(mode, &output->modes, head)
1399                 mode_count++;
1400         
1401         for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) {
1402                 if (output->property_ids[i] != 0) {
1403                         props_count++;
1404                 }
1405         }
1406
1407         if (out_resp->count_modes == 0) {
1408                 drm_crtc_probe_single_output_modes(output, dev->mode_config.max_width, dev->mode_config.max_height);
1409         }
1410
1411         strncpy(out_resp->name, output->name, DRM_OUTPUT_NAME_LEN);
1412         out_resp->name[DRM_OUTPUT_NAME_LEN-1] = 0;
1413
1414         out_resp->mm_width = output->mm_width;
1415         out_resp->mm_height = output->mm_height;
1416         out_resp->subpixel = output->subpixel_order;
1417         out_resp->connection = output->status;
1418         if (output->crtc)
1419                 out_resp->crtc = output->crtc->id;
1420         else
1421                 out_resp->crtc = 0;
1422
1423         out_resp->crtcs = output->possible_crtcs;
1424         out_resp->clones = output->possible_clones;
1425
1426         if ((out_resp->count_modes >= mode_count) && mode_count) {
1427                 copied = 0;
1428                 mode_ptr = (struct drm_mode_modeinfo *)(unsigned long)out_resp->modes_ptr;
1429                 list_for_each_entry(mode, &output->modes, head) {
1430                         drm_crtc_convert_to_umode(&u_mode, mode);
1431                         if (copy_to_user(mode_ptr + copied,
1432                                          &u_mode, sizeof(u_mode))) {
1433                                 ret = -EFAULT;
1434                                 goto out;
1435                         }
1436                         copied++;
1437                         
1438                 }
1439         }
1440         out_resp->count_modes = mode_count;
1441
1442         if ((out_resp->count_props >= props_count) && props_count) {
1443                 copied = 0;
1444                 prop_ptr = (uint32_t *)(unsigned long)(out_resp->props_ptr);
1445                 prop_values = (uint64_t *)(unsigned long)(out_resp->prop_values_ptr);
1446                 for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) {
1447                         if (output->property_ids[i] != 0) {
1448                                 if (put_user(output->property_ids[i], prop_ptr + copied)) {
1449                                         ret = -EFAULT;
1450                                         goto out;
1451                                 }
1452
1453                                 if (put_user(output->property_values[i], prop_values + copied)) {
1454                                         ret = -EFAULT;
1455                                         goto out;
1456                                 }
1457                                 copied++;
1458                         }
1459                 }
1460         }
1461         out_resp->count_props = props_count;
1462
1463 out:
1464         mutex_unlock(&dev->mode_config.mutex);
1465         return ret;
1466 }
1467
1468 /**
1469  * drm_mode_setcrtc - set CRTC configuration
1470  * @inode: inode from the ioctl
1471  * @filp: file * from the ioctl
1472  * @cmd: cmd from ioctl
1473  * @arg: arg from ioctl
1474  *
1475  * LOCKING:
1476  * Caller? (FIXME)
1477  *
1478  * Build a new CRTC configuration based on user request.
1479  *
1480  * Called by the user via ioctl.
1481  *
1482  * RETURNS:
1483  * Zero on success, errno on failure.
1484  */
1485 int drm_mode_setcrtc(struct drm_device *dev,
1486                      void *data, struct drm_file *file_priv)
1487 {
1488         struct drm_mode_crtc *crtc_req = data;
1489         struct drm_crtc *crtc;
1490         struct drm_output **output_set = NULL, *output;
1491         struct drm_framebuffer *fb = NULL;
1492         struct drm_display_mode *mode = NULL;
1493         int ret = 0;
1494         int i;
1495         uint32_t __user *set_outputs_ptr;
1496
1497         mutex_lock(&dev->mode_config.mutex);
1498         crtc = idr_find(&dev->mode_config.crtc_idr, crtc_req->crtc_id);
1499         if (!crtc || (crtc->id != crtc_req->crtc_id)) {
1500                 DRM_DEBUG("Unknown CRTC ID %d\n", crtc_req->crtc_id);
1501                 ret = -EINVAL;
1502                 goto out;
1503         }
1504
1505         if (crtc_req->mode_valid) {
1506                 /* if we have a mode we need a framebuffer */
1507                 if (crtc_req->fb_id) {
1508                         fb = idr_find(&dev->mode_config.crtc_idr, crtc_req->fb_id);
1509                         if (!fb || (fb->id != crtc_req->fb_id)) {
1510                                 DRM_DEBUG("Unknown FB ID%d\n", crtc_req->fb_id);
1511                                 ret = -EINVAL;
1512                                 goto out;
1513                         }
1514                 }
1515
1516                 mode = drm_mode_create(dev);
1517                 drm_crtc_convert_umode(mode, &crtc_req->mode);
1518         }
1519
1520         if (crtc_req->count_outputs == 0 && mode) {
1521                 DRM_DEBUG("Count outputs is 0 but mode set\n");
1522                 ret = -EINVAL;
1523                 goto out;
1524         }
1525
1526         if (crtc_req->count_outputs > 0 && !mode && !fb) {
1527                 DRM_DEBUG("Count outputs is %d but no mode or fb set\n", crtc_req->count_outputs);
1528                 ret = -EINVAL;
1529                 goto out;
1530         }
1531
1532         if (crtc_req->count_outputs > 0) {
1533                 u32 out_id;
1534                 output_set = kmalloc(crtc_req->count_outputs *
1535                                      sizeof(struct drm_output *), GFP_KERNEL);
1536                 if (!output_set) {
1537                         ret = -ENOMEM;
1538                         goto out;
1539                 }
1540
1541                 for (i = 0; i < crtc_req->count_outputs; i++) {
1542                         set_outputs_ptr = (uint32_t *)(unsigned long)crtc_req->set_outputs_ptr;
1543                         if (get_user(out_id, &set_outputs_ptr[i])) {
1544                                 ret = -EFAULT;
1545                                 goto out;
1546                         }
1547
1548                         output = idr_find(&dev->mode_config.crtc_idr, out_id);
1549                         if (!output || (out_id != output->id)) {
1550                                 DRM_DEBUG("Output id %d unknown\n", out_id);
1551                                 ret = -EINVAL;
1552                                 goto out;
1553                         }
1554
1555                         output_set[i] = output;
1556                 }
1557         }
1558
1559         ret = drm_crtc_set_config(crtc, crtc_req, mode, output_set, fb);
1560
1561 out:
1562         mutex_unlock(&dev->mode_config.mutex);
1563         return ret;
1564 }
1565
1566 /**
1567  * drm_mode_addfb - add an FB to the graphics configuration
1568  * @inode: inode from the ioctl
1569  * @filp: file * from the ioctl
1570  * @cmd: cmd from ioctl
1571  * @arg: arg from ioctl
1572  *
1573  * LOCKING:
1574  * Takes mode config lock.
1575  *
1576  * Add a new FB to the specified CRTC, given a user request.
1577  *
1578  * Called by the user via ioctl.
1579  *
1580  * RETURNS:
1581  * Zero on success, errno on failure.
1582  */
1583 int drm_mode_addfb(struct drm_device *dev,
1584                    void *data, struct drm_file *file_priv)
1585 {
1586         struct drm_mode_fb_cmd *r = data;
1587         struct drm_mode_config *config = &dev->mode_config;
1588         struct drm_framebuffer *fb;
1589         struct drm_buffer_object *bo;
1590         struct drm_crtc *crtc;
1591         int ret = 0;
1592
1593         if ((config->min_width > r->width) || (r->width > config->max_width)) {
1594                 DRM_ERROR("mode new framebuffer width not within limits\n");
1595                 return -EINVAL;
1596         }
1597         if ((config->min_height > r->height) || (r->height > config->max_height)) {
1598                 DRM_ERROR("mode new framebuffer height not within limits\n");
1599                 return -EINVAL;
1600         }
1601
1602         mutex_lock(&dev->mode_config.mutex);
1603         /* TODO check limits are okay */
1604         ret = drm_get_buffer_object(dev, &bo, r->handle);
1605         if (ret || !bo) {
1606                 ret = -EINVAL;
1607                 goto out;
1608         }
1609
1610         /* TODO check buffer is sufficently large */
1611         /* TODO setup destructor callback */
1612
1613         fb = drm_framebuffer_create(dev);
1614         if (!fb) {
1615                 ret = -EINVAL;
1616                 goto out;
1617         }
1618
1619         fb->width = r->width;
1620         fb->height = r->height;
1621         fb->pitch = r->pitch;
1622         fb->bits_per_pixel = r->bpp;
1623         fb->depth = r->depth;
1624         fb->offset = bo->offset;
1625         fb->bo = bo;
1626
1627         r->buffer_id = fb->id;
1628
1629         list_add(&fb->filp_head, &file_priv->fbs);
1630
1631         /* FIXME: bind the fb to the right crtc */
1632         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
1633                 crtc->fb = fb;
1634                 dev->driver->fb_probe(dev, crtc);
1635         }
1636
1637 out:
1638         mutex_unlock(&dev->mode_config.mutex);
1639         return ret;
1640 }
1641
1642 /**
1643  * drm_mode_rmfb - remove an FB from the configuration
1644  * @inode: inode from the ioctl
1645  * @filp: file * from the ioctl
1646  * @cmd: cmd from ioctl
1647  * @arg: arg from ioctl
1648  *
1649  * LOCKING:
1650  * Takes mode config lock.
1651  *
1652  * Remove the FB specified by the user.
1653  *
1654  * Called by the user via ioctl.
1655  *
1656  * RETURNS:
1657  * Zero on success, errno on failure.
1658  */
1659 int drm_mode_rmfb(struct drm_device *dev,
1660                    void *data, struct drm_file *file_priv)
1661 {
1662         struct drm_framebuffer *fb = 0;
1663         uint32_t *id = data;
1664         int ret = 0;
1665
1666         mutex_lock(&dev->mode_config.mutex);
1667         fb = idr_find(&dev->mode_config.crtc_idr, *id);
1668         /* TODO check that we realy get a framebuffer back. */
1669         if (!fb || (*id != fb->id)) {
1670                 DRM_ERROR("mode invalid framebuffer id\n");
1671                 ret = -EINVAL;
1672                 goto out;
1673         }
1674
1675         /* TODO check if we own the buffer */
1676         /* TODO release all crtc connected to the framebuffer */
1677         /* bind the fb to the crtc for now */
1678         /* TODO unhock the destructor from the buffer object */
1679
1680         if (fb->bo->type != drm_bo_type_kernel)
1681                 drm_framebuffer_destroy(fb);
1682         else
1683                 dev->driver->fb_remove(dev, drm_crtc_from_fb(dev, fb));
1684
1685 out:
1686         mutex_unlock(&dev->mode_config.mutex);
1687         return ret;
1688 }
1689
1690 /**
1691  * drm_mode_getfb - get FB info
1692  * @inode: inode from the ioctl
1693  * @filp: file * from the ioctl
1694  * @cmd: cmd from ioctl
1695  * @arg: arg from ioctl
1696  *
1697  * LOCKING:
1698  * Caller? (FIXME)
1699  *
1700  * Lookup the FB given its ID and return info about it.
1701  *
1702  * Called by the user via ioctl.
1703  *
1704  * RETURNS:
1705  * Zero on success, errno on failure.
1706  */
1707 int drm_mode_getfb(struct drm_device *dev,
1708                    void *data, struct drm_file *file_priv)
1709 {
1710         struct drm_mode_fb_cmd *r = data;
1711         struct drm_framebuffer *fb;
1712         int ret = 0;
1713
1714         mutex_lock(&dev->mode_config.mutex);
1715         fb = idr_find(&dev->mode_config.crtc_idr, r->buffer_id);
1716         if (!fb || (r->buffer_id != fb->id)) {
1717                 DRM_ERROR("invalid framebuffer id\n");
1718                 ret = -EINVAL;
1719                 goto out;
1720         }
1721
1722         r->height = fb->height;
1723         r->width = fb->width;
1724         r->depth = fb->depth;
1725         r->bpp = fb->bits_per_pixel;
1726         r->handle = fb->bo->base.hash.key;
1727         r->pitch = fb->pitch;
1728
1729 out:
1730         mutex_unlock(&dev->mode_config.mutex);
1731         return ret;
1732 }
1733
1734 /**
1735  * drm_fb_release - remove and free the FBs on this file
1736  * @filp: file * from the ioctl
1737  *
1738  * LOCKING:
1739  * Takes mode config lock.
1740  *
1741  * Destroy all the FBs associated with @filp.
1742  *
1743  * Called by the user via ioctl.
1744  *
1745  * RETURNS:
1746  * Zero on success, errno on failure.
1747  */
1748 void drm_fb_release(struct file *filp)
1749 {
1750         struct drm_file *priv = filp->private_data;
1751         struct drm_device *dev = priv->head->dev;
1752         struct drm_framebuffer *fb, *tfb;
1753
1754         mutex_lock(&dev->mode_config.mutex);
1755         list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
1756                 list_del(&fb->filp_head);
1757                 if (fb->bo->type != drm_bo_type_kernel)
1758                         drm_framebuffer_destroy(fb);
1759                 else
1760                         dev->driver->fb_remove(dev, drm_crtc_from_fb(dev, fb));
1761         }
1762         mutex_unlock(&dev->mode_config.mutex);
1763 }
1764
1765 /*
1766  *
1767  */
1768
1769 static int drm_mode_attachmode(struct drm_device *dev,
1770                                struct drm_output *output,
1771                                struct drm_display_mode *mode)
1772 {
1773         int ret = 0;
1774
1775         list_add_tail(&mode->head, &output->user_modes);
1776         return ret;
1777 }
1778
1779 int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc,
1780                              struct drm_display_mode *mode)
1781 {
1782         struct drm_output *output;
1783         int ret = 0;
1784         struct drm_display_mode *dup_mode;
1785         int need_dup = 0;
1786         list_for_each_entry(output, &dev->mode_config.output_list, head) {
1787                 if (output->crtc == crtc) {
1788                         if (need_dup)
1789                                 dup_mode = drm_mode_duplicate(dev, mode);
1790                         else
1791                                 dup_mode = mode;
1792                         ret = drm_mode_attachmode(dev, output, dup_mode); 
1793                         if (ret)
1794                                 return ret;
1795                         need_dup = 1;
1796                 }
1797         }
1798         return 0;
1799 }
1800 EXPORT_SYMBOL(drm_mode_attachmode_crtc);
1801
1802 static int drm_mode_detachmode(struct drm_device *dev,
1803                                struct drm_output *output,
1804                                struct drm_display_mode *mode)
1805 {
1806         int found = 0;
1807         int ret = 0;
1808         struct drm_display_mode *match_mode, *t;
1809
1810         list_for_each_entry_safe(match_mode, t, &output->user_modes, head) {
1811                 if (drm_mode_equal(match_mode, mode)) {
1812                         list_del(&match_mode->head);
1813                         drm_mode_destroy(dev, match_mode);
1814                         found = 1;
1815                         break;
1816                 }
1817         }
1818
1819         if (!found)
1820                 ret = -EINVAL;
1821
1822         return ret;
1823 }
1824
1825 int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode)
1826 {
1827         struct drm_output *output;
1828
1829         list_for_each_entry(output, &dev->mode_config.output_list, head) {
1830                 drm_mode_detachmode(dev, output, mode);
1831         }
1832         return 0;
1833 }
1834 EXPORT_SYMBOL(drm_mode_detachmode_crtc);
1835
1836 /**
1837  * drm_fb_attachmode - Attach a user mode to an output
1838  * @inode: inode from the ioctl
1839  * @filp: file * from the ioctl
1840  * @cmd: cmd from ioctl
1841  * @arg: arg from ioctl
1842  *
1843  * This attaches a user specified mode to an output.
1844  * Called by the user via ioctl.
1845  *
1846  * RETURNS:
1847  * Zero on success, errno on failure.
1848  */
1849 int drm_mode_attachmode_ioctl(struct drm_device *dev,
1850                               void *data, struct drm_file *file_priv)
1851 {
1852         struct drm_mode_mode_cmd *mode_cmd = data;
1853         struct drm_output *output;
1854         struct drm_display_mode *mode;
1855         struct drm_mode_modeinfo *umode = &mode_cmd->mode;
1856         int ret = 0;
1857
1858         mutex_lock(&dev->mode_config.mutex);
1859
1860         output = idr_find(&dev->mode_config.crtc_idr, mode_cmd->output_id);
1861         if (!output || (output->id != mode_cmd->output_id)) {
1862                 ret = -EINVAL;
1863                 goto out;
1864         }
1865
1866         mode = drm_mode_create(dev);
1867         if (!mode) {
1868                 ret = -ENOMEM;
1869                 goto out;
1870         }
1871         
1872         drm_crtc_convert_umode(mode, umode);
1873
1874         ret = drm_mode_attachmode(dev, output, mode);
1875 out:
1876         mutex_unlock(&dev->mode_config.mutex);
1877         return ret;
1878 }
1879
1880
1881 /**
1882  * drm_fb_detachmode - Detach a user specified mode from an output
1883  * @inode: inode from the ioctl
1884  * @filp: file * from the ioctl
1885  * @cmd: cmd from ioctl
1886  * @arg: arg from ioctl
1887  *
1888  * Called by the user via ioctl.
1889  *
1890  * RETURNS:
1891  * Zero on success, errno on failure.
1892  */
1893 int drm_mode_detachmode_ioctl(struct drm_device *dev,
1894                               void *data, struct drm_file *file_priv)
1895 {
1896         struct drm_mode_mode_cmd *mode_cmd = data;
1897         struct drm_output *output;
1898         struct drm_display_mode mode;
1899         struct drm_mode_modeinfo *umode = &mode_cmd->mode;
1900         int ret = 0;
1901
1902         mutex_lock(&dev->mode_config.mutex);
1903
1904         output = idr_find(&dev->mode_config.crtc_idr, mode_cmd->output_id);
1905         if (!output || (output->id != mode_cmd->output_id)) {
1906                 ret = -EINVAL;
1907                 goto out;
1908         }
1909         
1910         drm_crtc_convert_umode(&mode, umode);
1911         ret = drm_mode_detachmode(dev, output, &mode);
1912 out:           
1913         mutex_unlock(&dev->mode_config.mutex);
1914         return ret;
1915 }
1916
1917 struct drm_property *drm_property_create(struct drm_device *dev, int flags,
1918                                          const char *name, int num_values)
1919 {
1920         struct drm_property *property = NULL;
1921
1922         property = kzalloc(sizeof(struct drm_output), GFP_KERNEL);
1923         if (!property)
1924                 return NULL;
1925
1926         if (num_values) {
1927                 property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL);
1928                 if (!property->values)
1929                         goto fail;
1930         }
1931
1932         property->id = drm_idr_get(dev, property);
1933         property->flags = flags;
1934         property->num_values = num_values;
1935         INIT_LIST_HEAD(&property->enum_blob_list);
1936
1937         if (name)
1938                 strncpy(property->name, name, DRM_PROP_NAME_LEN);
1939
1940         list_add_tail(&property->head, &dev->mode_config.property_list);
1941         return property;
1942 fail:
1943         kfree(property);
1944         return NULL;
1945 }
1946 EXPORT_SYMBOL(drm_property_create);
1947
1948 int drm_property_add_enum(struct drm_property *property, int index,
1949                           uint64_t value, const char *name)
1950 {
1951         struct drm_property_enum *prop_enum;
1952
1953         if (!(property->flags & DRM_MODE_PROP_ENUM))
1954                 return -EINVAL;
1955
1956         if (!list_empty(&property->enum_blob_list)) {
1957                 list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
1958                         if (prop_enum->value == value) {
1959                                 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN); 
1960                                 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
1961                                 return 0;
1962                         }
1963                 }
1964         }
1965
1966         prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL);
1967         if (!prop_enum)
1968                 return -ENOMEM;
1969
1970         strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN); 
1971         prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
1972         prop_enum->value = value;
1973
1974         property->values[index] = value;
1975         list_add_tail(&prop_enum->head, &property->enum_blob_list);
1976         return 0;
1977 }
1978 EXPORT_SYMBOL(drm_property_add_enum);
1979
1980 void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
1981 {
1982         struct drm_property_enum *prop_enum, *pt;
1983
1984         list_for_each_entry_safe(prop_enum, pt, &property->enum_blob_list, head) {
1985                 list_del(&prop_enum->head);
1986                 kfree(prop_enum);
1987         }
1988
1989         if (property->num_values)
1990                 kfree(property->values);
1991         drm_idr_put(dev, property->id);
1992         list_del(&property->head);
1993         kfree(property);        
1994 }
1995 EXPORT_SYMBOL(drm_property_destroy);
1996
1997 int drm_output_attach_property(struct drm_output *output,
1998                                struct drm_property *property, uint64_t init_val)
1999 {
2000         int i;
2001
2002         for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) {
2003                 if (output->property_ids[i] == 0) {
2004                         output->property_ids[i] = property->id;
2005                         output->property_values[i] = init_val;
2006                         break;
2007                 }
2008         }
2009
2010         if (i == DRM_OUTPUT_MAX_PROPERTY)
2011                 return -EINVAL;
2012         return 0;
2013 }
2014 EXPORT_SYMBOL(drm_output_attach_property);
2015
2016 int drm_output_property_set_value(struct drm_output *output,
2017                                   struct drm_property *property, uint64_t value)
2018 {
2019         int i;
2020
2021         for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) {
2022                 if (output->property_ids[i] == property->id) {
2023                         output->property_values[i] = value;
2024                         break;
2025                 }
2026         }
2027
2028         if (i == DRM_OUTPUT_MAX_PROPERTY)
2029                 return -EINVAL;
2030         return 0;
2031 }
2032 EXPORT_SYMBOL(drm_output_property_set_value);
2033
2034 int drm_mode_getproperty_ioctl(struct drm_device *dev,
2035                                void *data, struct drm_file *file_priv)
2036 {
2037         struct drm_mode_get_property *out_resp = data;
2038         struct drm_property *property;
2039         int enum_count = 0;
2040         int blob_count = 0;
2041         int value_count = 0;
2042         int ret = 0, i;
2043         int copied;
2044         struct drm_property_enum *prop_enum;
2045         struct drm_mode_property_enum __user *enum_ptr;
2046         struct drm_property_blob *prop_blob;
2047         uint32_t *blob_id_ptr;
2048         uint64_t __user *values_ptr;
2049         uint32_t __user *blob_length_ptr;
2050
2051         mutex_lock(&dev->mode_config.mutex);
2052         property = idr_find(&dev->mode_config.crtc_idr, out_resp->prop_id);
2053         if (!property || (property->id != out_resp->prop_id)) {
2054                 ret = -EINVAL;
2055                 goto done;
2056         }
2057
2058         if (property->flags & DRM_MODE_PROP_ENUM) {
2059                 list_for_each_entry(prop_enum, &property->enum_blob_list, head)
2060                         enum_count++;
2061         } else if (property->flags & DRM_MODE_PROP_BLOB) {
2062                 list_for_each_entry(prop_blob, &property->enum_blob_list, head)
2063                         blob_count++;
2064         }
2065
2066         value_count = property->num_values;
2067
2068         strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN);
2069         out_resp->name[DRM_PROP_NAME_LEN-1] = 0;
2070         out_resp->flags = property->flags;
2071
2072         if ((out_resp->count_values >= value_count) && value_count) {
2073                 values_ptr = (uint64_t *)(unsigned long)out_resp->values_ptr;
2074                 for (i = 0; i < value_count; i++) {
2075                         if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) {
2076                                 ret = -EFAULT;
2077                                 goto done;
2078                         }
2079                 }
2080         }
2081         out_resp->count_values = value_count;
2082
2083         if (property->flags & DRM_MODE_PROP_ENUM) {
2084
2085                 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
2086                         copied = 0;
2087                         enum_ptr = (struct drm_mode_property_enum *)(unsigned long)out_resp->enum_blob_ptr;
2088                         list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
2089                                 
2090                                 if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {
2091                                         ret = -EFAULT;
2092                                         goto done;
2093                                 }
2094                                 
2095                                 if (copy_to_user(&enum_ptr[copied].name,
2096                                                  &prop_enum->name, DRM_PROP_NAME_LEN)) {
2097                                         ret = -EFAULT;
2098                                         goto done;
2099                                 }
2100                                 copied++;
2101                         }
2102                 }
2103                 out_resp->count_enum_blobs = enum_count;
2104         }
2105
2106         if (property->flags & DRM_MODE_PROP_BLOB) {
2107                 if ((out_resp->count_enum_blobs >= blob_count) && blob_count) {
2108                         copied = 0;
2109                         blob_id_ptr = (uint32_t *)(unsigned long)out_resp->enum_blob_ptr;
2110                         blob_length_ptr = (uint32_t *)(unsigned long)out_resp->values_ptr;
2111                         
2112                         list_for_each_entry(prop_blob, &property->enum_blob_list, head) {
2113                                 if (put_user(prop_blob->id, blob_id_ptr + copied)) {
2114                                         ret = -EFAULT;
2115                                         goto done;
2116                                 }
2117                                 
2118                                 if (put_user(prop_blob->length, blob_length_ptr + copied)) {
2119                                         ret = -EFAULT;
2120                                         goto done;
2121                                 }
2122                                 
2123                                 copied++;
2124                         }
2125                 }
2126                 out_resp->count_enum_blobs = enum_count;
2127         }
2128 done:
2129         mutex_unlock(&dev->mode_config.mutex);
2130         return ret;
2131 }
2132
2133 static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length,
2134                                                           void *data)
2135 {
2136         struct drm_property_blob *blob;
2137
2138         if (!length || !data)
2139                 return NULL;
2140
2141         blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
2142         if (!blob)
2143                 return NULL;
2144
2145         blob->data = (void *)((char *)blob + sizeof(struct drm_property_blob));
2146         blob->length = length;
2147
2148         memcpy(blob->data, data, length);
2149
2150         blob->id = drm_idr_get(dev, blob);
2151         
2152         list_add_tail(&blob->head, &dev->mode_config.property_blob_list);
2153         return blob;
2154 }
2155
2156 static void drm_property_destroy_blob(struct drm_device *dev,
2157                                struct drm_property_blob *blob)
2158 {
2159         drm_idr_put(dev, blob->id);
2160         list_del(&blob->head);
2161         kfree(blob);
2162 }
2163
2164 int drm_mode_getblob_ioctl(struct drm_device *dev,
2165                            void *data, struct drm_file *file_priv)
2166 {
2167         struct drm_mode_get_blob *out_resp = data;
2168         struct drm_property_blob *blob;
2169         int ret = 0;
2170         void *blob_ptr;
2171
2172         mutex_lock(&dev->mode_config.mutex);
2173         
2174         blob = idr_find(&dev->mode_config.crtc_idr, out_resp->blob_id);
2175         if (!blob || (blob->id != out_resp->blob_id)) {
2176                 ret = -EINVAL;
2177                 goto done;
2178         }
2179
2180         if (out_resp->length == blob->length) {
2181                 blob_ptr = (void *)(unsigned long)out_resp->data;
2182                 if (copy_to_user(blob_ptr, blob->data, blob->length)){
2183                         ret = -EFAULT;
2184                         goto done;
2185                 }
2186         }
2187         out_resp->length = blob->length;
2188
2189 done:
2190         mutex_unlock(&dev->mode_config.mutex);
2191         return ret;
2192 }
2193
2194 int drm_mode_output_update_edid_property(struct drm_output *output, unsigned char *edid)
2195 {
2196         struct drm_device *dev = output->dev;
2197         int ret = 0;
2198         if (output->edid_blob_ptr)
2199                 drm_property_destroy_blob(dev, output->edid_blob_ptr);
2200
2201         output->edid_blob_ptr = drm_property_create_blob(output->dev, 128, edid);
2202         
2203         ret = drm_output_property_set_value(output, dev->mode_config.edid_property, output->edid_blob_ptr->id);
2204         return ret;
2205 }
2206 EXPORT_SYMBOL(drm_mode_output_update_edid_property);
2207
2208 int drm_mode_output_property_set_ioctl(struct drm_device *dev,
2209                                        void *data, struct drm_file *file_priv)
2210 {
2211         struct drm_mode_output_set_property *out_resp = data;
2212         struct drm_property *property;
2213         struct drm_output *output;
2214         int ret = -EINVAL;
2215         int i;
2216
2217         mutex_lock(&dev->mode_config.mutex);
2218         output = idr_find(&dev->mode_config.crtc_idr, out_resp->output_id);
2219         if (!output || (output->id != out_resp->output_id)) {
2220                 goto out;
2221         }
2222
2223         for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) {
2224                 if (output->property_ids[i] == out_resp->prop_id)
2225                         break;
2226         }
2227
2228         if (i == DRM_OUTPUT_MAX_PROPERTY) {
2229                 goto out;
2230         }
2231         
2232         property = idr_find(&dev->mode_config.crtc_idr, out_resp->prop_id);
2233         if (!property || (property->id != out_resp->prop_id)) {
2234                 goto out;
2235         }
2236
2237         if (property->flags & DRM_MODE_PROP_IMMUTABLE)
2238                 goto out;
2239
2240         if (property->flags & DRM_MODE_PROP_RANGE) {
2241                 if (out_resp->value < property->values[0])
2242                         goto out;
2243
2244                 if (out_resp->value > property->values[1])
2245                         goto out;
2246         } else {
2247                 int found = 0;
2248                 for (i = 0; i < property->num_values; i++) {
2249                         if (property->values[i] == out_resp->value) {
2250                                 found = 1;
2251                                 break;
2252                         }
2253                 }
2254                 if (!found) {
2255                         goto out;
2256                 }
2257         }
2258
2259         if (output->funcs->set_property)
2260                 ret = output->funcs->set_property(output, property, out_resp->value);
2261
2262 out:
2263         mutex_unlock(&dev->mode_config.mutex);
2264         return ret;
2265 }
2266