fb: fixup the offset by getting it from the right place
[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         dev->mode_config.hotplug_counter = 0;
774 }
775 EXPORT_SYMBOL(drm_mode_config_init);
776
777 /**
778  * drm_get_buffer_object - find the buffer object for a given handle
779  * @dev: DRM device
780  * @bo: pointer to caller's buffer_object pointer
781  * @handle: handle to lookup
782  *
783  * LOCKING:
784  * Must take @dev's struct_mutex to protect buffer object lookup.
785  *
786  * Given @handle, lookup the buffer object in @dev and put it in the caller's
787  * @bo pointer.
788  *
789  * RETURNS:
790  * Zero on success, -EINVAL if the handle couldn't be found.
791  */
792 static int drm_get_buffer_object(struct drm_device *dev, struct drm_buffer_object **bo, unsigned long handle)
793 {
794         struct drm_user_object *uo;
795         struct drm_hash_item *hash;
796         int ret;
797
798         *bo = NULL;
799
800         mutex_lock(&dev->struct_mutex);
801         ret = drm_ht_find_item(&dev->object_hash, handle, &hash);
802         if (ret) {
803                 DRM_ERROR("Couldn't find handle.\n");
804                 ret = -EINVAL;
805                 goto out_err;
806         }
807
808         uo = drm_hash_entry(hash, struct drm_user_object, hash);
809         if (uo->type != drm_buffer_type) {
810                 ret = -EINVAL;
811                 goto out_err;
812         }
813         
814         *bo = drm_user_object_entry(uo, struct drm_buffer_object, base);
815         ret = 0;
816 out_err:
817         mutex_unlock(&dev->struct_mutex);
818         return ret;
819 }
820
821 /**
822  * drm_pick_crtcs - pick crtcs for output devices
823  * @dev: DRM device
824  *
825  * LOCKING:
826  * Caller must hold mode config lock.
827  */
828 static void drm_pick_crtcs (struct drm_device *dev)
829 {
830         int c, o, assigned;
831         struct drm_output *output, *output_equal;
832         struct drm_crtc   *crtc;
833         struct drm_display_mode *des_mode = NULL, *modes, *modes_equal;
834
835         list_for_each_entry(output, &dev->mode_config.output_list, head) {
836                 output->crtc = NULL;
837     
838                 /* Don't hook up outputs that are disconnected ??
839                  *
840                  * This is debateable. Do we want fixed /dev/fbX or
841                  * dynamic on hotplug (need mode code for that though) ?
842                  *
843                  * If we don't hook up outputs now, then we only create
844                  * /dev/fbX for the output that's enabled, that's good as
845                  * the users console will be on that output.
846                  *
847                  * If we do hook up outputs that are disconnected now, then
848                  * the user may end up having to muck about with the fbcon
849                  * map flags to assign his console to the enabled output. Ugh.
850                  */
851                 if (output->status != output_status_connected)
852                         continue;
853
854                 des_mode = NULL;
855                 list_for_each_entry(des_mode, &output->modes, head) {
856                         if (des_mode->type & DRM_MODE_TYPE_PREFERRED)
857                                 break;
858                 }
859
860                 /* No preferred mode, let's just select the first available */
861                 if (!des_mode || !(des_mode->type & DRM_MODE_TYPE_PREFERRED)) {
862                         list_for_each_entry(des_mode, &output->modes, head) {
863                                 if (des_mode)
864                                         break;
865                         }
866                 }
867
868                 c = -1;
869                 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
870                         assigned = 0;
871
872                         c++;
873                         if ((output->possible_crtcs & (1 << c)) == 0)
874                                 continue;
875         
876                         list_for_each_entry(output_equal, &dev->mode_config.output_list, head) {
877                                 if (output->id == output_equal->id)
878                                         continue;
879
880                                 /* Find out if crtc has been assigned before */
881                                 if (output_equal->crtc == crtc)
882                                         assigned = 1;
883                         }
884
885 #if 1 /* continue for now */
886                         if (assigned)
887                                 continue;
888 #endif
889
890                         o = -1;
891                         list_for_each_entry(output_equal, &dev->mode_config.output_list, head) {
892                                 o++;
893                                 if (output->id == output_equal->id)
894                                         continue;
895
896                                 list_for_each_entry(modes, &output->modes, head) {
897                                         list_for_each_entry(modes_equal, &output_equal->modes, head) {
898                                                 if (drm_mode_equal (modes, modes_equal)) {
899                                                         if ((output->possible_clones & output_equal->possible_clones) && (output_equal->crtc == crtc)) {
900                                                                 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);
901                                                                 assigned = 0;
902                                                                 goto clone;
903                                                         }
904                                                 }
905                                         }
906                                 }
907                         }
908
909 clone:
910                         /* crtc has been assigned skip it */
911                         if (assigned)
912                                 continue;
913
914                         /* Found a CRTC to attach to, do it ! */
915                         output->crtc = crtc;
916                         output->crtc->desired_mode = des_mode;
917                         output->initial_x = 0;
918                         output->initial_y = 0;
919                         DRM_DEBUG("Desired mode for CRTC %d is 0x%x:%s\n",c,des_mode->mode_id, des_mode->name);
920                         break;
921                 }
922         }
923 }
924 EXPORT_SYMBOL(drm_pick_crtcs);
925
926 /**
927  * drm_initial_config - setup a sane initial output configuration
928  * @dev: DRM device
929  * @can_grow: this configuration is growable
930  *
931  * LOCKING:
932  * Called at init time, must take mode config lock.
933  *
934  * Scan the CRTCs and outputs and try to put together an initial setup.
935  * At the moment, this is a cloned configuration across all heads with
936  * a new framebuffer object as the backing store.
937  *
938  * RETURNS:
939  * Zero if everything went ok, nonzero otherwise.
940  */
941 bool drm_initial_config(struct drm_device *dev, bool can_grow)
942 {
943         struct drm_output *output;
944         struct drm_crtc *crtc;
945         int ret = false;
946
947         mutex_lock(&dev->mode_config.mutex);
948
949         drm_crtc_probe_output_modes(dev, 2048, 2048);
950
951         drm_pick_crtcs(dev);
952
953         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
954
955                 /* can't setup the crtc if there's no assigned mode */
956                 if (!crtc->desired_mode)
957                         continue;
958
959                 /* Now setup the fbdev for attached crtcs */
960                 dev->driver->fb_probe(dev, crtc);
961         }
962
963         /* This is a little screwy, as we've already walked the outputs 
964          * above, but it's a little bit of magic too. There's the potential
965          * for things not to get setup above if an existing device gets
966          * re-assigned thus confusing the hardware. By walking the outputs
967          * this fixes up their crtc's.
968          */
969         list_for_each_entry(output, &dev->mode_config.output_list, head) {
970
971                 /* can't setup the output if there's no assigned mode */
972                 if (!output->crtc || !output->crtc->desired_mode)
973                         continue;
974
975                 /* and needs an attached fb */
976                 if (output->crtc->fb)
977                         drm_crtc_set_mode(output->crtc, output->crtc->desired_mode, 0, 0);
978         }
979
980         drm_disable_unused_functions(dev);
981
982         mutex_unlock(&dev->mode_config.mutex);
983         return ret;
984 }
985 EXPORT_SYMBOL(drm_initial_config);
986
987 /**
988  * drm_mode_config_cleanup - free up DRM mode_config info
989  * @dev: DRM device
990  *
991  * LOCKING:
992  * Caller must hold mode config lock.
993  *
994  * Free up all the outputs and CRTCs associated with this DRM device, then
995  * free up the framebuffers and associated buffer objects.
996  *
997  * FIXME: cleanup any dangling user buffer objects too
998  */
999 void drm_mode_config_cleanup(struct drm_device *dev)
1000 {
1001         struct drm_output *output, *ot;
1002         struct drm_crtc *crtc, *ct;
1003         struct drm_framebuffer *fb, *fbt;
1004         struct drm_property *property, *pt;
1005
1006         list_for_each_entry_safe(output, ot, &dev->mode_config.output_list, head) {
1007                 drm_output_destroy(output);
1008         }
1009
1010         list_for_each_entry_safe(property, pt, &dev->mode_config.property_list, head) {
1011                 drm_property_destroy(dev, property);
1012         }
1013
1014         list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
1015                 /* there should only be bo of kernel type left */
1016                 if (fb->bo->type != drm_bo_type_kernel)
1017                         drm_framebuffer_destroy(fb);
1018                 else
1019                         dev->driver->fb_remove(dev, drm_crtc_from_fb(dev, fb));
1020         }
1021
1022         list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
1023                 drm_crtc_destroy(crtc);
1024         }
1025
1026 }
1027 EXPORT_SYMBOL(drm_mode_config_cleanup);
1028
1029 /**
1030  * drm_crtc_set_config - set a new config from userspace
1031  * @crtc: CRTC to setup
1032  * @crtc_info: user provided configuration
1033  * @new_mode: new mode to set
1034  * @output_set: set of outputs for the new config
1035  * @fb: new framebuffer
1036  *
1037  * LOCKING:
1038  * Caller must hold mode config lock.
1039  *
1040  * Setup a new configuration, provided by the user in @crtc_info, and enable
1041  * it.
1042  *
1043  * RETURNS:
1044  * Zero. (FIXME)
1045  */
1046 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)
1047 {
1048         struct drm_device *dev = crtc->dev;
1049         struct drm_crtc **save_crtcs, *new_crtc;
1050         bool save_enabled = crtc->enabled;
1051         bool changed = false;
1052         bool flip_or_move = false;
1053         struct drm_output *output;
1054         int count = 0, ro;
1055
1056         save_crtcs = kzalloc(dev->mode_config.num_crtc * sizeof(struct drm_crtc *), GFP_KERNEL);
1057         if (!save_crtcs)
1058                 return -ENOMEM;
1059
1060         /* We should be able to check here if the fb has the same properties
1061          * and then just flip_or_move it */
1062         if (crtc->fb != fb)
1063                 changed = true;
1064
1065         if (crtc_info->x != crtc->x || crtc_info->y != crtc->y)
1066                 flip_or_move = true;
1067
1068         if (new_mode && !drm_mode_equal(new_mode, &crtc->mode))
1069                 changed = true;
1070
1071         list_for_each_entry(output, &dev->mode_config.output_list, head) {
1072                 save_crtcs[count++] = output->crtc;
1073
1074                 if (output->crtc == crtc)
1075                         new_crtc = NULL;
1076                 else
1077                         new_crtc = output->crtc;
1078
1079                 for (ro = 0; ro < crtc_info->count_outputs; ro++) {
1080                         if (output_set[ro] == output)
1081                                 new_crtc = crtc;
1082                 }
1083                 if (new_crtc != output->crtc) {
1084                         changed = true;
1085                         output->crtc = new_crtc;
1086                 }
1087         }
1088
1089         /* mode_set_base is not a required function */
1090         if (flip_or_move && !crtc->funcs->mode_set_base)
1091                 changed = true;
1092
1093         if (changed) {
1094                 crtc->fb = fb;
1095                 crtc->enabled = (new_mode != NULL);
1096                 if (new_mode != NULL) {
1097                         DRM_DEBUG("attempting to set mode from userspace %p\n", crtc->fb);
1098                         drm_mode_debug_printmodeline(dev, new_mode);
1099                         if (!drm_crtc_set_mode(crtc, new_mode, crtc_info->x,
1100                                                crtc_info->y)) {
1101                                 crtc->enabled = save_enabled;
1102                                 count = 0;
1103                                 list_for_each_entry(output, &dev->mode_config.output_list, head)
1104                                         output->crtc = save_crtcs[count++];
1105                                 kfree(save_crtcs);
1106                                 return -EINVAL;
1107                         }
1108                         crtc->desired_x = crtc_info->x;
1109                         crtc->desired_y = crtc_info->y;
1110                         crtc->desired_mode = new_mode;
1111                 }
1112                 drm_disable_unused_functions(dev);
1113         } else if (flip_or_move) {
1114                 crtc->funcs->mode_set_base(crtc, crtc_info->x, crtc_info->y);
1115         }
1116
1117         kfree(save_crtcs);
1118         return 0;
1119 }
1120
1121 /**
1122  * drm_hotplug_stage_two
1123  * @dev DRM device
1124  * @output hotpluged output
1125  *
1126  * LOCKING.
1127  * Caller must hold mode config lock, function might grap struct lock.
1128  *
1129  * Stage two of a hotplug.
1130  *
1131  * RETURNS:
1132  * Zero on success, errno on failure.
1133  */
1134 int drm_hotplug_stage_two(struct drm_device *dev, struct drm_output *output,
1135                           bool connected)
1136 {
1137         int has_config = 0;
1138
1139         /* We might want to do something more here */
1140         if (!connected) {
1141                 DRM_DEBUG("not connected\n");
1142                 dev->mode_config.hotplug_counter++;
1143                 return 0;
1144         }
1145
1146         if (output->crtc && output->crtc->desired_mode) {
1147                 DRM_DEBUG("drm thinks that the output already has a config\n");
1148                 has_config = 1;
1149         }
1150
1151         drm_crtc_probe_output_modes(dev, 2048, 2048);
1152
1153         if (!has_config)
1154                 drm_pick_crtcs(dev);
1155
1156         if (!output->crtc || !output->crtc->desired_mode) {
1157                 DRM_DEBUG("could not find a desired mode or crtc for output\n");
1158                 goto out_err;
1159         }
1160
1161         /* We should realy check if there is a fb using this crtc */
1162         if (!has_config)
1163                 dev->driver->fb_probe(dev, output->crtc);
1164         else {
1165                 dev->driver->fb_resize(dev, output->crtc);
1166
1167                 if (!drm_crtc_set_mode(output->crtc, output->crtc->desired_mode, 0, 0))
1168                         DRM_ERROR("failed to set mode after hotplug\n");
1169         }
1170
1171         drm_disable_unused_functions(dev);
1172
1173         dev->mode_config.hotplug_counter++;
1174         return 0;
1175
1176 out_err:
1177         dev->mode_config.hotplug_counter++;
1178         return 1;
1179 }
1180 EXPORT_SYMBOL(drm_hotplug_stage_two);
1181
1182 int drm_mode_hotplug_ioctl(struct drm_device *dev,
1183                            void *data, struct drm_file *file_priv)
1184 {
1185         struct drm_mode_hotplug *arg = data;
1186
1187         arg->counter = dev->mode_config.hotplug_counter;
1188
1189         return 0;
1190 }
1191
1192 /**
1193  * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
1194  * @out: drm_mode_modeinfo struct to return to the user
1195  * @in: drm_display_mode to use
1196  *
1197  * LOCKING:
1198  * None.
1199  *
1200  * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
1201  * the user.
1202  */
1203 void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out, struct drm_display_mode *in)
1204 {
1205         out->clock = in->clock;
1206         out->hdisplay = in->hdisplay;
1207         out->hsync_start = in->hsync_start;
1208         out->hsync_end = in->hsync_end;
1209         out->htotal = in->htotal;
1210         out->hskew = in->hskew;
1211         out->vdisplay = in->vdisplay;
1212         out->vsync_start = in->vsync_start;
1213         out->vsync_end = in->vsync_end;
1214         out->vtotal = in->vtotal;
1215         out->vscan = in->vscan;
1216         out->vrefresh = in->vrefresh;
1217         out->flags = in->flags;
1218         out->type = in->type;
1219         strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
1220         out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1221 }
1222
1223 /**
1224  * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode
1225  * @out: drm_display_mode to return to the user
1226  * @in: drm_mode_modeinfo to use
1227  *
1228  * LOCKING:
1229  * None.
1230  *
1231  * Convert a drmo_mode_modeinfo into a drm_display_mode structure to return to
1232  * the caller.
1233  */
1234 void drm_crtc_convert_umode(struct drm_display_mode *out, struct drm_mode_modeinfo *in)
1235 {
1236         out->clock = in->clock;
1237         out->hdisplay = in->hdisplay;
1238         out->hsync_start = in->hsync_start;
1239         out->hsync_end = in->hsync_end;
1240         out->htotal = in->htotal;
1241         out->hskew = in->hskew;
1242         out->vdisplay = in->vdisplay;
1243         out->vsync_start = in->vsync_start;
1244         out->vsync_end = in->vsync_end;
1245         out->vtotal = in->vtotal;
1246         out->vscan = in->vscan;
1247         out->vrefresh = in->vrefresh;
1248         out->flags = in->flags;
1249         out->type = in->type;
1250         strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
1251         out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1252 }
1253         
1254 /**
1255  * drm_mode_getresources - get graphics configuration
1256  * @inode: inode from the ioctl
1257  * @filp: file * from the ioctl
1258  * @cmd: cmd from ioctl
1259  * @arg: arg from ioctl
1260  *
1261  * LOCKING:
1262  * Takes mode config lock.
1263  *
1264  * Construct a set of configuration description structures and return
1265  * them to the user, including CRTC, output and framebuffer configuration.
1266  *
1267  * Called by the user via ioctl.
1268  *
1269  * RETURNS:
1270  * Zero on success, errno on failure.
1271  */
1272 int drm_mode_getresources(struct drm_device *dev,
1273                           void *data, struct drm_file *file_priv)
1274 {
1275         struct drm_mode_card_res *card_res = data;
1276         struct list_head *lh;
1277         struct drm_framebuffer *fb;
1278         struct drm_output *output;
1279         struct drm_crtc *crtc;
1280         int ret = 0;
1281         int output_count = 0;
1282         int crtc_count = 0;
1283         int fb_count = 0;
1284         int copied = 0;
1285         uint32_t __user *fb_id;
1286         uint32_t __user *crtc_id;
1287         uint32_t __user *output_id;
1288
1289         mutex_lock(&dev->mode_config.mutex);
1290
1291         list_for_each(lh, &dev->mode_config.fb_list)
1292                 fb_count++;
1293
1294         list_for_each(lh, &dev->mode_config.crtc_list)
1295                 crtc_count++;
1296
1297         list_for_each(lh, &dev->mode_config.output_list)
1298                 output_count++;
1299
1300         card_res->max_height = dev->mode_config.max_height;
1301         card_res->min_height = dev->mode_config.min_height;
1302         card_res->max_width = dev->mode_config.max_width;
1303         card_res->min_width = dev->mode_config.min_width;
1304
1305         /* handle this in 4 parts */
1306         /* FBs */
1307         if (card_res->count_fbs >= fb_count) {
1308                 copied = 0;
1309                 fb_id = (uint32_t *)(unsigned long)card_res->fb_id_ptr;
1310                 list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
1311                         if (put_user(fb->id, fb_id + copied)) {
1312                                 ret = -EFAULT;
1313                                 goto out;
1314                         }
1315                         copied++;
1316                 }
1317         }
1318         card_res->count_fbs = fb_count;
1319
1320         /* CRTCs */
1321         if (card_res->count_crtcs >= crtc_count) {
1322                 copied = 0;
1323                 crtc_id = (uint32_t *)(unsigned long)card_res->crtc_id_ptr;
1324                 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head){
1325                         DRM_DEBUG("CRTC ID is %d\n", crtc->id);
1326                         if (put_user(crtc->id, crtc_id + copied)) {
1327                                 ret = -EFAULT;
1328                                 goto out;
1329                         }
1330                         copied++;
1331                 }
1332         }
1333         card_res->count_crtcs = crtc_count;
1334
1335
1336         /* Outputs */
1337         if (card_res->count_outputs >= output_count) {
1338                 copied = 0;
1339                 output_id = (uint32_t *)(unsigned long)card_res->output_id_ptr;
1340                 list_for_each_entry(output, &dev->mode_config.output_list,
1341                                     head) {
1342                         DRM_DEBUG("OUTPUT ID is %d\n", output->id);
1343                         if (put_user(output->id, output_id + copied)) {
1344                                 ret = -EFAULT;
1345                                 goto out;
1346                         }
1347                         copied++;
1348                 }
1349         }
1350         card_res->count_outputs = output_count;
1351         
1352         DRM_DEBUG("Counted %d %d\n", card_res->count_crtcs,
1353                   card_res->count_outputs);
1354
1355 out:    
1356         mutex_unlock(&dev->mode_config.mutex);
1357         return ret;
1358 }
1359
1360 /**
1361  * drm_mode_getcrtc - get CRTC configuration
1362  * @inode: inode from the ioctl
1363  * @filp: file * from the ioctl
1364  * @cmd: cmd from ioctl
1365  * @arg: arg from ioctl
1366  *
1367  * LOCKING:
1368  * Caller? (FIXME)
1369  *
1370  * Construct a CRTC configuration structure to return to the user.
1371  *
1372  * Called by the user via ioctl.
1373  *
1374  * RETURNS:
1375  * Zero on success, errno on failure.
1376  */
1377 int drm_mode_getcrtc(struct drm_device *dev,
1378                      void *data, struct drm_file *file_priv)
1379 {
1380         struct drm_mode_crtc *crtc_resp = data;
1381         struct drm_crtc *crtc;
1382         struct drm_output *output;
1383         int ocount;
1384         int ret = 0;
1385
1386         mutex_lock(&dev->mode_config.mutex);
1387         crtc = idr_find(&dev->mode_config.crtc_idr, crtc_resp->crtc_id);
1388         if (!crtc || (crtc->id != crtc_resp->crtc_id)) {
1389                 ret = -EINVAL;
1390                 goto out;
1391         }
1392
1393         crtc_resp->x = crtc->x;
1394         crtc_resp->y = crtc->y;
1395
1396         if (crtc->fb)
1397                 crtc_resp->fb_id = crtc->fb->id;
1398         else
1399                 crtc_resp->fb_id = 0;
1400
1401         crtc_resp->outputs = 0;
1402         if (crtc->enabled) {
1403
1404                 drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode);
1405                 crtc_resp->mode_valid = 1;
1406                 ocount = 0;
1407                 list_for_each_entry(output, &dev->mode_config.output_list, head) {
1408                         if (output->crtc == crtc)
1409                                 crtc_resp->outputs |= 1 << (ocount++);
1410                 }
1411                 
1412         } else {
1413                 crtc_resp->mode_valid = 0;
1414         }
1415
1416 out:
1417         mutex_unlock(&dev->mode_config.mutex);
1418         return ret;
1419 }
1420
1421 /**
1422  * drm_mode_getoutput - get output configuration
1423  * @inode: inode from the ioctl
1424  * @filp: file * from the ioctl
1425  * @cmd: cmd from ioctl
1426  * @arg: arg from ioctl
1427  *
1428  * LOCKING:
1429  * Caller? (FIXME)
1430  *
1431  * Construct a output configuration structure to return to the user.
1432  *
1433  * Called by the user via ioctl.
1434  *
1435  * RETURNS:
1436  * Zero on success, errno on failure.
1437  */
1438 int drm_mode_getoutput(struct drm_device *dev,
1439                        void *data, struct drm_file *file_priv)
1440 {
1441         struct drm_mode_get_output *out_resp = data;
1442         struct drm_output *output;
1443         struct drm_display_mode *mode;
1444         int mode_count = 0;
1445         int props_count = 0;
1446         int ret = 0;
1447         int copied = 0;
1448         int i;
1449         struct drm_mode_modeinfo u_mode;
1450         struct drm_mode_modeinfo __user *mode_ptr;
1451         uint32_t __user *prop_ptr;
1452         uint64_t __user *prop_values;
1453
1454         memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
1455
1456         DRM_DEBUG("output id %d:\n", out_resp->output);
1457
1458         mutex_lock(&dev->mode_config.mutex);
1459         output= idr_find(&dev->mode_config.crtc_idr, out_resp->output);
1460         if (!output || (output->id != out_resp->output)) {
1461                 ret = -EINVAL;
1462                 goto out;
1463         }
1464
1465         list_for_each_entry(mode, &output->modes, head)
1466                 mode_count++;
1467         
1468         for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) {
1469                 if (output->property_ids[i] != 0) {
1470                         props_count++;
1471                 }
1472         }
1473
1474         if (out_resp->count_modes == 0) {
1475                 drm_crtc_probe_single_output_modes(output, dev->mode_config.max_width, dev->mode_config.max_height);
1476         }
1477
1478         out_resp->output_type = output->output_type;
1479         out_resp->output_type_id = output->output_type_id;
1480         out_resp->mm_width = output->mm_width;
1481         out_resp->mm_height = output->mm_height;
1482         out_resp->subpixel = output->subpixel_order;
1483         out_resp->connection = output->status;
1484         if (output->crtc)
1485                 out_resp->crtc = output->crtc->id;
1486         else
1487                 out_resp->crtc = 0;
1488
1489         out_resp->crtcs = output->possible_crtcs;
1490         out_resp->clones = output->possible_clones;
1491
1492         if ((out_resp->count_modes >= mode_count) && mode_count) {
1493                 copied = 0;
1494                 mode_ptr = (struct drm_mode_modeinfo *)(unsigned long)out_resp->modes_ptr;
1495                 list_for_each_entry(mode, &output->modes, head) {
1496                         drm_crtc_convert_to_umode(&u_mode, mode);
1497                         if (copy_to_user(mode_ptr + copied,
1498                                          &u_mode, sizeof(u_mode))) {
1499                                 ret = -EFAULT;
1500                                 goto out;
1501                         }
1502                         copied++;
1503                         
1504                 }
1505         }
1506         out_resp->count_modes = mode_count;
1507
1508         if ((out_resp->count_props >= props_count) && props_count) {
1509                 copied = 0;
1510                 prop_ptr = (uint32_t *)(unsigned long)(out_resp->props_ptr);
1511                 prop_values = (uint64_t *)(unsigned long)(out_resp->prop_values_ptr);
1512                 for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) {
1513                         if (output->property_ids[i] != 0) {
1514                                 if (put_user(output->property_ids[i], prop_ptr + copied)) {
1515                                         ret = -EFAULT;
1516                                         goto out;
1517                                 }
1518
1519                                 if (put_user(output->property_values[i], prop_values + copied)) {
1520                                         ret = -EFAULT;
1521                                         goto out;
1522                                 }
1523                                 copied++;
1524                         }
1525                 }
1526         }
1527         out_resp->count_props = props_count;
1528
1529 out:
1530         mutex_unlock(&dev->mode_config.mutex);
1531         return ret;
1532 }
1533
1534 /**
1535  * drm_mode_setcrtc - set CRTC configuration
1536  * @inode: inode from the ioctl
1537  * @filp: file * from the ioctl
1538  * @cmd: cmd from ioctl
1539  * @arg: arg from ioctl
1540  *
1541  * LOCKING:
1542  * Caller? (FIXME)
1543  *
1544  * Build a new CRTC configuration based on user request.
1545  *
1546  * Called by the user via ioctl.
1547  *
1548  * RETURNS:
1549  * Zero on success, errno on failure.
1550  */
1551 int drm_mode_setcrtc(struct drm_device *dev,
1552                      void *data, struct drm_file *file_priv)
1553 {
1554         struct drm_mode_crtc *crtc_req = data;
1555         struct drm_crtc *crtc;
1556         struct drm_output **output_set = NULL, *output;
1557         struct drm_framebuffer *fb = NULL;
1558         struct drm_display_mode *mode = NULL;
1559         int ret = 0;
1560         int i;
1561         uint32_t __user *set_outputs_ptr;
1562
1563         mutex_lock(&dev->mode_config.mutex);
1564         crtc = idr_find(&dev->mode_config.crtc_idr, crtc_req->crtc_id);
1565         if (!crtc || (crtc->id != crtc_req->crtc_id)) {
1566                 DRM_DEBUG("Unknown CRTC ID %d\n", crtc_req->crtc_id);
1567                 ret = -EINVAL;
1568                 goto out;
1569         }
1570
1571         if (crtc_req->mode_valid) {
1572                 /* if we have a mode we need a framebuffer */
1573                 if (crtc_req->fb_id) {
1574                         fb = idr_find(&dev->mode_config.crtc_idr, crtc_req->fb_id);
1575                         if (!fb || (fb->id != crtc_req->fb_id)) {
1576                                 DRM_DEBUG("Unknown FB ID%d\n", crtc_req->fb_id);
1577                                 ret = -EINVAL;
1578                                 goto out;
1579                         }
1580                         DRM_DEBUG("found fb %p for id %d\n", fb, crtc_req->fb_id);
1581                 } else {
1582                         DRM_DEBUG("Unknown FB ID %d\n", crtc_req->fb_id);
1583                         ret = -EINVAL;
1584                         goto out;
1585                 }
1586                         
1587
1588                 mode = drm_mode_create(dev);
1589                 drm_crtc_convert_umode(mode, &crtc_req->mode);
1590                 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
1591         }
1592
1593         if (crtc_req->count_outputs == 0 && mode) {
1594                 DRM_DEBUG("Count outputs is 0 but mode set\n");
1595                 ret = -EINVAL;
1596                 goto out;
1597         }
1598
1599         if (crtc_req->count_outputs > 0 && !mode && !fb) {
1600                 DRM_DEBUG("Count outputs is %d but no mode or fb set\n", crtc_req->count_outputs);
1601                 ret = -EINVAL;
1602                 goto out;
1603         }
1604
1605         if (crtc_req->count_outputs > 0) {
1606                 u32 out_id;
1607                 /* Maybe we should check that count_outputs is a sensible value. */
1608                 output_set = kmalloc(crtc_req->count_outputs *
1609                                      sizeof(struct drm_output *), GFP_KERNEL);
1610                 if (!output_set) {
1611                         ret = -ENOMEM;
1612                         goto out;
1613                 }
1614
1615                 for (i = 0; i < crtc_req->count_outputs; i++) {
1616                         set_outputs_ptr = (uint32_t *)(unsigned long)crtc_req->set_outputs_ptr;
1617                         if (get_user(out_id, &set_outputs_ptr[i])) {
1618                                 ret = -EFAULT;
1619                                 goto out;
1620                         }
1621
1622                         output = idr_find(&dev->mode_config.crtc_idr, out_id);
1623                         if (!output || (out_id != output->id)) {
1624                                 DRM_DEBUG("Output id %d unknown\n", out_id);
1625                                 ret = -EINVAL;
1626                                 goto out;
1627                         }
1628
1629                         output_set[i] = output;
1630                 }
1631         }
1632
1633         /* What happens to output_set, leak? */
1634         ret = drm_crtc_set_config(crtc, crtc_req, mode, output_set, fb);
1635
1636 out:
1637         mutex_unlock(&dev->mode_config.mutex);
1638         return ret;
1639 }
1640
1641 int drm_mode_cursor_ioctl(struct drm_device *dev,
1642                         void *data, struct drm_file *file_priv)
1643 {
1644         struct drm_mode_cursor *req = data;
1645         struct drm_crtc *crtc;
1646         struct drm_buffer_object *bo = NULL; /* must be set */
1647         int ret = 0;
1648
1649         DRM_DEBUG("\n");
1650
1651         if (!req->flags) {
1652                 DRM_ERROR("no operation set\n");
1653                 return -EINVAL;
1654         }
1655
1656         mutex_lock(&dev->mode_config.mutex);
1657         crtc = idr_find(&dev->mode_config.crtc_idr, req->crtc);
1658         if (!crtc || (crtc->id != req->crtc)) {
1659                 DRM_DEBUG("Unknown CRTC ID %d\n", req->crtc);
1660                 ret = -EINVAL;
1661                 goto out;
1662         }
1663
1664         if (req->flags & DRM_MODE_CURSOR_BO) {
1665                 /* Turn of the cursor if handle is 0 */
1666                 if (req->handle)
1667                         ret = drm_get_buffer_object(dev, &bo, req->handle);
1668
1669                 if (ret) {
1670                         DRM_ERROR("invalid buffer id\n");
1671                         ret = -EINVAL;
1672                         goto out;
1673                 }
1674
1675                 if (crtc->funcs->cursor_set) {
1676                         ret = crtc->funcs->cursor_set(crtc, bo, req->width, req->height);
1677                 } else {
1678                         DRM_ERROR("crtc does not support cursor\n");
1679                         ret = -EFAULT;
1680                         goto out;
1681                 }
1682         }
1683
1684         if (req->flags & DRM_MODE_CURSOR_MOVE) {
1685                 if (crtc->funcs->cursor_move) {
1686                         ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
1687                 } else {
1688                         DRM_ERROR("crtc does not support cursor\n");
1689                         ret = -EFAULT;
1690                         goto out;
1691                 }
1692         }
1693 out:
1694         mutex_unlock(&dev->mode_config.mutex);
1695         return ret;
1696 }
1697
1698 /**
1699  * drm_mode_addfb - add an FB to the graphics configuration
1700  * @inode: inode from the ioctl
1701  * @filp: file * from the ioctl
1702  * @cmd: cmd from ioctl
1703  * @arg: arg from ioctl
1704  *
1705  * LOCKING:
1706  * Takes mode config lock.
1707  *
1708  * Add a new FB to the specified CRTC, given a user request.
1709  *
1710  * Called by the user via ioctl.
1711  *
1712  * RETURNS:
1713  * Zero on success, errno on failure.
1714  */
1715 int drm_mode_addfb(struct drm_device *dev,
1716                    void *data, struct drm_file *file_priv)
1717 {
1718         struct drm_mode_fb_cmd *r = data;
1719         struct drm_mode_config *config = &dev->mode_config;
1720         struct drm_framebuffer *fb;
1721         struct drm_buffer_object *bo;
1722         int ret = 0;
1723
1724         if ((config->min_width > r->width) || (r->width > config->max_width)) {
1725                 DRM_ERROR("mode new framebuffer width not within limits\n");
1726                 return -EINVAL;
1727         }
1728         if ((config->min_height > r->height) || (r->height > config->max_height)) {
1729                 DRM_ERROR("mode new framebuffer height not within limits\n");
1730                 return -EINVAL;
1731         }
1732
1733         mutex_lock(&dev->mode_config.mutex);
1734         /* TODO check limits are okay */
1735         ret = drm_get_buffer_object(dev, &bo, r->handle);
1736         if (ret || !bo) {
1737                 DRM_ERROR("BO handle not valid\n");
1738                 ret = -EINVAL;
1739                 goto out;
1740         }
1741
1742         /* TODO check buffer is sufficently large */
1743         /* TODO setup destructor callback */
1744
1745         fb = drm_framebuffer_create(dev);
1746         if (!fb) {
1747                 DRM_ERROR("could not create framebuffer\n");
1748                 ret = -EINVAL;
1749                 goto out;
1750         }
1751
1752         fb->width = r->width;
1753         fb->height = r->height;
1754         fb->pitch = r->pitch;
1755         fb->bits_per_pixel = r->bpp;
1756         fb->depth = r->depth;
1757         fb->bo = bo;
1758
1759         r->buffer_id = fb->id;
1760
1761         list_add(&fb->filp_head, &file_priv->fbs);
1762
1763 out:
1764         mutex_unlock(&dev->mode_config.mutex);
1765         return ret;
1766 }
1767
1768 /**
1769  * drm_mode_rmfb - remove an FB from the configuration
1770  * @inode: inode from the ioctl
1771  * @filp: file * from the ioctl
1772  * @cmd: cmd from ioctl
1773  * @arg: arg from ioctl
1774  *
1775  * LOCKING:
1776  * Takes mode config lock.
1777  *
1778  * Remove the FB specified by the user.
1779  *
1780  * Called by the user via ioctl.
1781  *
1782  * RETURNS:
1783  * Zero on success, errno on failure.
1784  */
1785 int drm_mode_rmfb(struct drm_device *dev,
1786                    void *data, struct drm_file *file_priv)
1787 {
1788         struct drm_framebuffer *fb = 0;
1789         struct drm_framebuffer *fbl = 0;
1790         uint32_t *id = data;
1791         int ret = 0;
1792         int found = 0;
1793
1794         mutex_lock(&dev->mode_config.mutex);
1795         fb = idr_find(&dev->mode_config.crtc_idr, *id);
1796         /* TODO check that we realy get a framebuffer back. */
1797         if (!fb || (*id != fb->id)) {
1798                 DRM_ERROR("mode invalid framebuffer id\n");
1799                 ret = -EINVAL;
1800                 goto out;
1801         }
1802
1803         list_for_each_entry(fbl, &file_priv->fbs, filp_head)
1804                 if (fb == fbl)
1805                         found = 1;
1806
1807         if (!found) {
1808                 DRM_ERROR("tried to remove a fb that we didn't own\n");
1809                 ret = -EINVAL;
1810                 goto out;
1811         }
1812
1813         /* TODO release all crtc connected to the framebuffer */
1814         /* TODO unhock the destructor from the buffer object */
1815
1816         if (fb->bo->type == drm_bo_type_kernel)
1817                 DRM_ERROR("the bo type should not be of kernel type\n");
1818
1819         list_del(&fb->filp_head);
1820         drm_framebuffer_destroy(fb);
1821
1822 out:
1823         mutex_unlock(&dev->mode_config.mutex);
1824         return ret;
1825 }
1826
1827 /**
1828  * drm_mode_getfb - get FB info
1829  * @inode: inode from the ioctl
1830  * @filp: file * from the ioctl
1831  * @cmd: cmd from ioctl
1832  * @arg: arg from ioctl
1833  *
1834  * LOCKING:
1835  * Caller? (FIXME)
1836  *
1837  * Lookup the FB given its ID and return info about it.
1838  *
1839  * Called by the user via ioctl.
1840  *
1841  * RETURNS:
1842  * Zero on success, errno on failure.
1843  */
1844 int drm_mode_getfb(struct drm_device *dev,
1845                    void *data, struct drm_file *file_priv)
1846 {
1847         struct drm_mode_fb_cmd *r = data;
1848         struct drm_framebuffer *fb;
1849         int ret = 0;
1850
1851         mutex_lock(&dev->mode_config.mutex);
1852         fb = idr_find(&dev->mode_config.crtc_idr, r->buffer_id);
1853         if (!fb || (r->buffer_id != fb->id)) {
1854                 DRM_ERROR("invalid framebuffer id\n");
1855                 ret = -EINVAL;
1856                 goto out;
1857         }
1858
1859         r->height = fb->height;
1860         r->width = fb->width;
1861         r->depth = fb->depth;
1862         r->bpp = fb->bits_per_pixel;
1863         r->handle = fb->bo->base.hash.key;
1864         r->pitch = fb->pitch;
1865
1866 out:
1867         mutex_unlock(&dev->mode_config.mutex);
1868         return ret;
1869 }
1870
1871 /**
1872  * drm_fb_release - remove and free the FBs on this file
1873  * @filp: file * from the ioctl
1874  *
1875  * LOCKING:
1876  * Takes mode config lock.
1877  *
1878  * Destroy all the FBs associated with @filp.
1879  *
1880  * Called by the user via ioctl.
1881  *
1882  * RETURNS:
1883  * Zero on success, errno on failure.
1884  */
1885 void drm_fb_release(struct file *filp)
1886 {
1887         struct drm_file *priv = filp->private_data;
1888         struct drm_device *dev = priv->minor->dev;
1889         struct drm_framebuffer *fb, *tfb;
1890
1891         mutex_lock(&dev->mode_config.mutex);
1892         list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
1893                 list_del(&fb->filp_head);
1894                 if (fb->bo->type == drm_bo_type_kernel)
1895                         DRM_ERROR("the bo type should not be of kernel_type, the kernel will probably explode, why Dave\n");
1896
1897                 drm_framebuffer_destroy(fb);
1898         }
1899         mutex_unlock(&dev->mode_config.mutex);
1900 }
1901
1902 /*
1903  *
1904  */
1905
1906 static int drm_mode_attachmode(struct drm_device *dev,
1907                                struct drm_output *output,
1908                                struct drm_display_mode *mode)
1909 {
1910         int ret = 0;
1911
1912         list_add_tail(&mode->head, &output->user_modes);
1913         return ret;
1914 }
1915
1916 int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc,
1917                              struct drm_display_mode *mode)
1918 {
1919         struct drm_output *output;
1920         int ret = 0;
1921         struct drm_display_mode *dup_mode;
1922         int need_dup = 0;
1923         list_for_each_entry(output, &dev->mode_config.output_list, head) {
1924                 if (output->crtc == crtc) {
1925                         if (need_dup)
1926                                 dup_mode = drm_mode_duplicate(dev, mode);
1927                         else
1928                                 dup_mode = mode;
1929                         ret = drm_mode_attachmode(dev, output, dup_mode); 
1930                         if (ret)
1931                                 return ret;
1932                         need_dup = 1;
1933                 }
1934         }
1935         return 0;
1936 }
1937 EXPORT_SYMBOL(drm_mode_attachmode_crtc);
1938
1939 static int drm_mode_detachmode(struct drm_device *dev,
1940                                struct drm_output *output,
1941                                struct drm_display_mode *mode)
1942 {
1943         int found = 0;
1944         int ret = 0;
1945         struct drm_display_mode *match_mode, *t;
1946
1947         list_for_each_entry_safe(match_mode, t, &output->user_modes, head) {
1948                 if (drm_mode_equal(match_mode, mode)) {
1949                         list_del(&match_mode->head);
1950                         drm_mode_destroy(dev, match_mode);
1951                         found = 1;
1952                         break;
1953                 }
1954         }
1955
1956         if (!found)
1957                 ret = -EINVAL;
1958
1959         return ret;
1960 }
1961
1962 int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode)
1963 {
1964         struct drm_output *output;
1965
1966         list_for_each_entry(output, &dev->mode_config.output_list, head) {
1967                 drm_mode_detachmode(dev, output, mode);
1968         }
1969         return 0;
1970 }
1971 EXPORT_SYMBOL(drm_mode_detachmode_crtc);
1972
1973 /**
1974  * drm_fb_attachmode - Attach a user mode to an output
1975  * @inode: inode from the ioctl
1976  * @filp: file * from the ioctl
1977  * @cmd: cmd from ioctl
1978  * @arg: arg from ioctl
1979  *
1980  * This attaches a user specified mode to an output.
1981  * Called by the user via ioctl.
1982  *
1983  * RETURNS:
1984  * Zero on success, errno on failure.
1985  */
1986 int drm_mode_attachmode_ioctl(struct drm_device *dev,
1987                               void *data, struct drm_file *file_priv)
1988 {
1989         struct drm_mode_mode_cmd *mode_cmd = data;
1990         struct drm_output *output;
1991         struct drm_display_mode *mode;
1992         struct drm_mode_modeinfo *umode = &mode_cmd->mode;
1993         int ret = 0;
1994
1995         mutex_lock(&dev->mode_config.mutex);
1996
1997         output = idr_find(&dev->mode_config.crtc_idr, mode_cmd->output_id);
1998         if (!output || (output->id != mode_cmd->output_id)) {
1999                 ret = -EINVAL;
2000                 goto out;
2001         }
2002
2003         mode = drm_mode_create(dev);
2004         if (!mode) {
2005                 ret = -ENOMEM;
2006                 goto out;
2007         }
2008         
2009         drm_crtc_convert_umode(mode, umode);
2010
2011         ret = drm_mode_attachmode(dev, output, mode);
2012 out:
2013         mutex_unlock(&dev->mode_config.mutex);
2014         return ret;
2015 }
2016
2017
2018 /**
2019  * drm_fb_detachmode - Detach a user specified mode from an output
2020  * @inode: inode from the ioctl
2021  * @filp: file * from the ioctl
2022  * @cmd: cmd from ioctl
2023  * @arg: arg from ioctl
2024  *
2025  * Called by the user via ioctl.
2026  *
2027  * RETURNS:
2028  * Zero on success, errno on failure.
2029  */
2030 int drm_mode_detachmode_ioctl(struct drm_device *dev,
2031                               void *data, struct drm_file *file_priv)
2032 {
2033         struct drm_mode_mode_cmd *mode_cmd = data;
2034         struct drm_output *output;
2035         struct drm_display_mode mode;
2036         struct drm_mode_modeinfo *umode = &mode_cmd->mode;
2037         int ret = 0;
2038
2039         mutex_lock(&dev->mode_config.mutex);
2040
2041         output = idr_find(&dev->mode_config.crtc_idr, mode_cmd->output_id);
2042         if (!output || (output->id != mode_cmd->output_id)) {
2043                 ret = -EINVAL;
2044                 goto out;
2045         }
2046         
2047         drm_crtc_convert_umode(&mode, umode);
2048         ret = drm_mode_detachmode(dev, output, &mode);
2049 out:           
2050         mutex_unlock(&dev->mode_config.mutex);
2051         return ret;
2052 }
2053
2054 struct drm_property *drm_property_create(struct drm_device *dev, int flags,
2055                                          const char *name, int num_values)
2056 {
2057         struct drm_property *property = NULL;
2058
2059         property = kzalloc(sizeof(struct drm_property), GFP_KERNEL);
2060         if (!property)
2061                 return NULL;
2062
2063         if (num_values) {
2064                 property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL);
2065                 if (!property->values)
2066                         goto fail;
2067         }
2068
2069         property->id = drm_idr_get(dev, property);
2070         property->flags = flags;
2071         property->num_values = num_values;
2072         INIT_LIST_HEAD(&property->enum_blob_list);
2073
2074         if (name)
2075                 strncpy(property->name, name, DRM_PROP_NAME_LEN);
2076
2077         list_add_tail(&property->head, &dev->mode_config.property_list);
2078         return property;
2079 fail:
2080         kfree(property);
2081         return NULL;
2082 }
2083 EXPORT_SYMBOL(drm_property_create);
2084
2085 int drm_property_add_enum(struct drm_property *property, int index,
2086                           uint64_t value, const char *name)
2087 {
2088         struct drm_property_enum *prop_enum;
2089
2090         if (!(property->flags & DRM_MODE_PROP_ENUM))
2091                 return -EINVAL;
2092
2093         if (!list_empty(&property->enum_blob_list)) {
2094                 list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
2095                         if (prop_enum->value == value) {
2096                                 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN); 
2097                                 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
2098                                 return 0;
2099                         }
2100                 }
2101         }
2102
2103         prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL);
2104         if (!prop_enum)
2105                 return -ENOMEM;
2106
2107         strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN); 
2108         prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
2109         prop_enum->value = value;
2110
2111         property->values[index] = value;
2112         list_add_tail(&prop_enum->head, &property->enum_blob_list);
2113         return 0;
2114 }
2115 EXPORT_SYMBOL(drm_property_add_enum);
2116
2117 void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
2118 {
2119         struct drm_property_enum *prop_enum, *pt;
2120
2121         list_for_each_entry_safe(prop_enum, pt, &property->enum_blob_list, head) {
2122                 list_del(&prop_enum->head);
2123                 kfree(prop_enum);
2124         }
2125
2126         if (property->num_values)
2127                 kfree(property->values);
2128         drm_idr_put(dev, property->id);
2129         list_del(&property->head);
2130         kfree(property);        
2131 }
2132 EXPORT_SYMBOL(drm_property_destroy);
2133
2134 int drm_output_attach_property(struct drm_output *output,
2135                                struct drm_property *property, uint64_t init_val)
2136 {
2137         int i;
2138
2139         for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) {
2140                 if (output->property_ids[i] == 0) {
2141                         output->property_ids[i] = property->id;
2142                         output->property_values[i] = init_val;
2143                         break;
2144                 }
2145         }
2146
2147         if (i == DRM_OUTPUT_MAX_PROPERTY)
2148                 return -EINVAL;
2149         return 0;
2150 }
2151 EXPORT_SYMBOL(drm_output_attach_property);
2152
2153 int drm_output_property_set_value(struct drm_output *output,
2154                                   struct drm_property *property, uint64_t value)
2155 {
2156         int i;
2157
2158         for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) {
2159                 if (output->property_ids[i] == property->id) {
2160                         output->property_values[i] = value;
2161                         break;
2162                 }
2163         }
2164
2165         if (i == DRM_OUTPUT_MAX_PROPERTY)
2166                 return -EINVAL;
2167         return 0;
2168 }
2169 EXPORT_SYMBOL(drm_output_property_set_value);
2170
2171 int drm_mode_getproperty_ioctl(struct drm_device *dev,
2172                                void *data, struct drm_file *file_priv)
2173 {
2174         struct drm_mode_get_property *out_resp = data;
2175         struct drm_property *property;
2176         int enum_count = 0;
2177         int blob_count = 0;
2178         int value_count = 0;
2179         int ret = 0, i;
2180         int copied;
2181         struct drm_property_enum *prop_enum;
2182         struct drm_mode_property_enum __user *enum_ptr;
2183         struct drm_property_blob *prop_blob;
2184         uint32_t *blob_id_ptr;
2185         uint64_t __user *values_ptr;
2186         uint32_t __user *blob_length_ptr;
2187
2188         mutex_lock(&dev->mode_config.mutex);
2189         property = idr_find(&dev->mode_config.crtc_idr, out_resp->prop_id);
2190         if (!property || (property->id != out_resp->prop_id)) {
2191                 ret = -EINVAL;
2192                 goto done;
2193         }
2194
2195         if (property->flags & DRM_MODE_PROP_ENUM) {
2196                 list_for_each_entry(prop_enum, &property->enum_blob_list, head)
2197                         enum_count++;
2198         } else if (property->flags & DRM_MODE_PROP_BLOB) {
2199                 list_for_each_entry(prop_blob, &property->enum_blob_list, head)
2200                         blob_count++;
2201         }
2202
2203         value_count = property->num_values;
2204
2205         strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN);
2206         out_resp->name[DRM_PROP_NAME_LEN-1] = 0;
2207         out_resp->flags = property->flags;
2208
2209         if ((out_resp->count_values >= value_count) && value_count) {
2210                 values_ptr = (uint64_t *)(unsigned long)out_resp->values_ptr;
2211                 for (i = 0; i < value_count; i++) {
2212                         if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) {
2213                                 ret = -EFAULT;
2214                                 goto done;
2215                         }
2216                 }
2217         }
2218         out_resp->count_values = value_count;
2219
2220         if (property->flags & DRM_MODE_PROP_ENUM) {
2221
2222                 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
2223                         copied = 0;
2224                         enum_ptr = (struct drm_mode_property_enum *)(unsigned long)out_resp->enum_blob_ptr;
2225                         list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
2226                                 
2227                                 if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {
2228                                         ret = -EFAULT;
2229                                         goto done;
2230                                 }
2231                                 
2232                                 if (copy_to_user(&enum_ptr[copied].name,
2233                                                  &prop_enum->name, DRM_PROP_NAME_LEN)) {
2234                                         ret = -EFAULT;
2235                                         goto done;
2236                                 }
2237                                 copied++;
2238                         }
2239                 }
2240                 out_resp->count_enum_blobs = enum_count;
2241         }
2242
2243         if (property->flags & DRM_MODE_PROP_BLOB) {
2244                 if ((out_resp->count_enum_blobs >= blob_count) && blob_count) {
2245                         copied = 0;
2246                         blob_id_ptr = (uint32_t *)(unsigned long)out_resp->enum_blob_ptr;
2247                         blob_length_ptr = (uint32_t *)(unsigned long)out_resp->values_ptr;
2248                         
2249                         list_for_each_entry(prop_blob, &property->enum_blob_list, head) {
2250                                 if (put_user(prop_blob->id, blob_id_ptr + copied)) {
2251                                         ret = -EFAULT;
2252                                         goto done;
2253                                 }
2254                                 
2255                                 if (put_user(prop_blob->length, blob_length_ptr + copied)) {
2256                                         ret = -EFAULT;
2257                                         goto done;
2258                                 }
2259                                 
2260                                 copied++;
2261                         }
2262                 }
2263                 out_resp->count_enum_blobs = enum_count;
2264         }
2265 done:
2266         mutex_unlock(&dev->mode_config.mutex);
2267         return ret;
2268 }
2269
2270 static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length,
2271                                                           void *data)
2272 {
2273         struct drm_property_blob *blob;
2274
2275         if (!length || !data)
2276                 return NULL;
2277
2278         blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
2279         if (!blob)
2280                 return NULL;
2281
2282         blob->data = (void *)((char *)blob + sizeof(struct drm_property_blob));
2283         blob->length = length;
2284
2285         memcpy(blob->data, data, length);
2286
2287         blob->id = drm_idr_get(dev, blob);
2288         
2289         list_add_tail(&blob->head, &dev->mode_config.property_blob_list);
2290         return blob;
2291 }
2292
2293 static void drm_property_destroy_blob(struct drm_device *dev,
2294                                struct drm_property_blob *blob)
2295 {
2296         drm_idr_put(dev, blob->id);
2297         list_del(&blob->head);
2298         kfree(blob);
2299 }
2300
2301 int drm_mode_getblob_ioctl(struct drm_device *dev,
2302                            void *data, struct drm_file *file_priv)
2303 {
2304         struct drm_mode_get_blob *out_resp = data;
2305         struct drm_property_blob *blob;
2306         int ret = 0;
2307         void *blob_ptr;
2308
2309         mutex_lock(&dev->mode_config.mutex);
2310         
2311         blob = idr_find(&dev->mode_config.crtc_idr, out_resp->blob_id);
2312         if (!blob || (blob->id != out_resp->blob_id)) {
2313                 ret = -EINVAL;
2314                 goto done;
2315         }
2316
2317         if (out_resp->length == blob->length) {
2318                 blob_ptr = (void *)(unsigned long)out_resp->data;
2319                 if (copy_to_user(blob_ptr, blob->data, blob->length)){
2320                         ret = -EFAULT;
2321                         goto done;
2322                 }
2323         }
2324         out_resp->length = blob->length;
2325
2326 done:
2327         mutex_unlock(&dev->mode_config.mutex);
2328         return ret;
2329 }
2330
2331 int drm_mode_output_update_edid_property(struct drm_output *output, struct edid *edid)
2332 {
2333         struct drm_device *dev = output->dev;
2334         int ret = 0;
2335         if (output->edid_blob_ptr)
2336                 drm_property_destroy_blob(dev, output->edid_blob_ptr);
2337
2338         output->edid_blob_ptr = drm_property_create_blob(output->dev, 128, edid);
2339         
2340         ret = drm_output_property_set_value(output, dev->mode_config.edid_property, output->edid_blob_ptr->id);
2341         return ret;
2342 }
2343 EXPORT_SYMBOL(drm_mode_output_update_edid_property);
2344
2345 int drm_mode_output_property_set_ioctl(struct drm_device *dev,
2346                                        void *data, struct drm_file *file_priv)
2347 {
2348         struct drm_mode_output_set_property *out_resp = data;
2349         struct drm_property *property;
2350         struct drm_output *output;
2351         int ret = -EINVAL;
2352         int i;
2353
2354         mutex_lock(&dev->mode_config.mutex);
2355         output = idr_find(&dev->mode_config.crtc_idr, out_resp->output_id);
2356         if (!output || (output->id != out_resp->output_id)) {
2357                 goto out;
2358         }
2359
2360         for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) {
2361                 if (output->property_ids[i] == out_resp->prop_id)
2362                         break;
2363         }
2364
2365         if (i == DRM_OUTPUT_MAX_PROPERTY) {
2366                 goto out;
2367         }
2368         
2369         property = idr_find(&dev->mode_config.crtc_idr, out_resp->prop_id);
2370         if (!property || (property->id != out_resp->prop_id)) {
2371                 goto out;
2372         }
2373
2374         if (property->flags & DRM_MODE_PROP_IMMUTABLE)
2375                 goto out;
2376
2377         if (property->flags & DRM_MODE_PROP_RANGE) {
2378                 if (out_resp->value < property->values[0])
2379                         goto out;
2380
2381                 if (out_resp->value > property->values[1])
2382                         goto out;
2383         } else {
2384                 int found = 0;
2385                 for (i = 0; i < property->num_values; i++) {
2386                         if (property->values[i] == out_resp->value) {
2387                                 found = 1;
2388                                 break;
2389                         }
2390                 }
2391                 if (!found) {
2392                         goto out;
2393                 }
2394         }
2395
2396         if (output->funcs->set_property)
2397                 ret = output->funcs->set_property(output, property, out_resp->value);
2398
2399 out:
2400         mutex_unlock(&dev->mode_config.mutex);
2401         return ret;
2402 }
2403