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