Fix type/flags usage problem to check for preferred modes.
[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 /**
37  * drm_idr_get - allocate a new identifier
38  * @dev: DRM device
39  * @ptr: object pointer, used to generate unique ID
40  *
41  * LOCKING:
42  * Caller must hold DRM mode_config lock.
43  *
44  * Create a unique identifier based on @ptr in @dev's identifier space.  Used
45  * for tracking modes, CRTCs and outputs.
46  *
47  * RETURNS:
48  * New unique (relative to other objects in @dev) integer identifier for the
49  * object.
50  */
51 int drm_idr_get(struct drm_device *dev, void *ptr)
52 {
53         int new_id = 0;
54         int ret;
55 again:
56         if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
57                 DRM_ERROR("Ran out memory getting a mode number\n");
58                 return 0;
59         }
60
61         ret = idr_get_new_above(&dev->mode_config.crtc_idr, ptr, 1, &new_id);
62         if (ret == -EAGAIN) {
63                 spin_unlock(&dev->mode_config.config_lock);
64                 goto again;
65         }       
66
67         return new_id;
68 }
69
70 /**
71  * drm_idr_put - free an identifer
72  * @dev: DRM device
73  * @id: ID to free
74  *
75  * LOCKING:
76  * Caller must hold DRM mode_config lock.
77  *
78  * Free @id from @dev's unique identifier pool.
79  */
80 void drm_idr_put(struct drm_device *dev, int id)
81 {
82         idr_remove(&dev->mode_config.crtc_idr, id);
83 }
84
85 /**
86  * drm_crtc_from_fb - find the CRTC structure associated with an fb
87  * @dev: DRM device
88  * @fb: framebuffer in question
89  *
90  * LOCKING:
91  * Caller must hold mode_config lock.
92  *
93  * Find CRTC in the mode_config structure that matches @fb.
94  *
95  * RETURNS:
96  * Pointer to the CRTC or NULL if it wasn't found.
97  */
98 struct drm_crtc *drm_crtc_from_fb(struct drm_device *dev,
99                                   struct drm_framebuffer *fb)
100 {
101         struct drm_crtc *crtc;
102
103         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
104                 if (crtc->fb == fb)
105                         return crtc;
106         }
107         return NULL;
108 }
109
110 /**
111  * drm_framebuffer_create - create a new framebuffer object
112  * @dev: DRM device
113  *
114  * LOCKING:
115  * Caller must hold mode config lock.
116  *
117  * Creates a new framebuffer objects and adds it to @dev's DRM mode_config.
118  *
119  * RETURNS:
120  * Pointer to new framebuffer or NULL on error.
121  */
122 struct drm_framebuffer *drm_framebuffer_create(drm_device_t *dev)
123 {
124         struct drm_framebuffer *fb;
125
126         /* Limit to single framebuffer for now */
127         if (dev->mode_config.num_fb > 1) {
128                 spin_unlock(&dev->mode_config.config_lock);
129                 DRM_ERROR("Attempt to add multiple framebuffers failed\n");
130                 return NULL;
131         }
132
133         fb = kzalloc(sizeof(struct drm_framebuffer), GFP_KERNEL);
134         if (!fb)
135                 return NULL;
136         
137         fb->id = drm_idr_get(dev, fb);
138         fb->dev = dev;
139         dev->mode_config.num_fb++;
140         list_add(&fb->head, &dev->mode_config.fb_list);
141
142         return fb;
143 }
144 EXPORT_SYMBOL(drm_framebuffer_create);
145
146 /**
147  * drm_framebuffer_destroy - remove a framebuffer object
148  * @fb: framebuffer to remove
149  *
150  * LOCKING:
151  * Caller must hold mode config lock.
152  *
153  * Scans all the CRTCs in @dev's mode_config.  If they're using @fb, removes
154  * it, setting it to NULL.
155  */
156 void drm_framebuffer_destroy(struct drm_framebuffer *fb)
157 {
158         drm_device_t *dev = fb->dev;
159         struct drm_crtc *crtc;
160
161         /* remove from any CRTC */
162         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
163                 if (crtc->fb == fb)
164                         crtc->fb = NULL;
165         }
166
167         drm_idr_put(dev, fb->id);
168         list_del(&fb->head);
169         dev->mode_config.num_fb--;
170
171         kfree(fb);
172 }
173 EXPORT_SYMBOL(drm_framebuffer_destroy);
174
175 /**
176  * drm_crtc_create - create a new CRTC object
177  * @dev: DRM device
178  * @funcs: callbacks for the new CRTC
179  *
180  * LOCKING:
181  * Caller must hold mode config lock.
182  *
183  * Creates a new CRTC object and adds it to @dev's mode_config structure.
184  *
185  * RETURNS:
186  * Pointer to new CRTC object or NULL on error.
187  */
188 struct drm_crtc *drm_crtc_create(drm_device_t *dev,
189                                  const struct drm_crtc_funcs *funcs)
190 {
191         struct drm_crtc *crtc;
192
193         crtc = kzalloc(sizeof(struct drm_crtc), GFP_KERNEL);
194         if (!crtc)
195                 return NULL;
196
197         crtc->dev = dev;
198         crtc->funcs = funcs;
199
200         crtc->id = drm_idr_get(dev, crtc);
201
202         list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
203         dev->mode_config.num_crtc++;
204
205         return crtc;
206 }
207 EXPORT_SYMBOL(drm_crtc_create);
208
209 /**
210  * drm_crtc_destroy - remove a CRTC object
211  * @crtc: CRTC to remove
212  *
213  * LOCKING:
214  * Caller must hold mode config lock.
215  *
216  * Cleanup @crtc.  Calls @crtc's cleanup function, then removes @crtc from
217  * its associated DRM device's mode_config.  Frees it afterwards.
218  */
219 void drm_crtc_destroy(struct drm_crtc *crtc)
220 {
221         drm_device_t *dev = crtc->dev;
222
223         if (crtc->funcs->cleanup)
224                 (*crtc->funcs->cleanup)(crtc);
225
226         drm_idr_put(dev, crtc->id);
227         list_del(&crtc->head);
228         dev->mode_config.num_crtc--;
229         kfree(crtc);
230 }
231 EXPORT_SYMBOL(drm_crtc_destroy);
232
233 /**
234  * drm_crtc_in_use - check if a given CRTC is in a mode_config
235  * @crtc: CRTC to check
236  *
237  * LOCKING:
238  * Caller must hold mode config lock.
239  *
240  * Walk @crtc's DRM device's mode_config and see if it's in use.
241  *
242  * RETURNS:
243  * True if @crtc is part of the mode_config, false otherwise.
244  */
245 bool drm_crtc_in_use(struct drm_crtc *crtc)
246 {
247         struct drm_output *output;
248         drm_device_t *dev = crtc->dev;
249         /* FIXME: Locking around list access? */
250         list_for_each_entry(output, &dev->mode_config.output_list, head)
251                 if (output->crtc == crtc)
252                         return true;
253         return false;
254 }
255 EXPORT_SYMBOL(drm_crtc_in_use);
256
257 /*
258  * Detailed mode info for a standard 640x480@60Hz monitor
259  */
260 static struct drm_display_mode std_mode[] = {
261         { DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 25200, 640, 656,
262                    752, 800, 0, 480, 490, 492, 525, 0,
263                    V_NHSYNC | V_NVSYNC) }, /* 640x480@60Hz */
264 };
265
266 /**
267  * drm_crtc_probe_output_modes - get complete set of display modes
268  * @dev: DRM device
269  * @maxX: max width for modes
270  * @maxY: max height for modes
271  *
272  * LOCKING:
273  * Caller must hold mode config lock.
274  *
275  * Based on @dev's mode_config layout, scan all the outputs and try to detect
276  * modes on them.  Modes will first be added to the output's probed_modes
277  * list, then culled (based on validity and the @maxX, @maxY parameters) and
278  * put into the normal modes list.
279  *
280  * Intended to be used either at bootup time or when major configuration
281  * changes have occurred.
282  *
283  * FIXME: take into account monitor limits
284  */
285 void drm_crtc_probe_output_modes(struct drm_device *dev, int maxX, int maxY)
286 {
287         struct drm_output *output;
288         struct drm_display_mode *mode, *t;
289         int ret;
290         //if (maxX == 0 || maxY == 0) 
291         // TODO
292
293         list_for_each_entry(output, &dev->mode_config.output_list, head) {
294
295                 /* set all modes to the unverified state */
296                 list_for_each_entry_safe(mode, t, &output->modes, head)
297                         mode->status = MODE_UNVERIFIED;
298                 
299                 output->status = (*output->funcs->detect)(output);
300
301                 if (output->status == output_status_disconnected) {
302                         DRM_DEBUG("%s is disconnected\n", output->name);
303                         /* TODO set EDID to NULL */
304                         continue;
305                 }
306
307                 ret = (*output->funcs->get_modes)(output);
308
309                 if (ret) {
310                         drm_mode_output_list_update(output);
311                 }
312
313                 if (maxX && maxY)
314                         drm_mode_validate_size(dev, &output->modes, maxX,
315                                                maxY, 0);
316                 list_for_each_entry_safe(mode, t, &output->modes, head) {
317                         if (mode->status == MODE_OK)
318                                 mode->status = (*output->funcs->mode_valid)(output,mode);
319                 }
320                 
321
322                 drm_mode_prune_invalid(dev, &output->modes, TRUE);
323
324                 if (list_empty(&output->modes)) {
325                         struct drm_display_mode *stdmode;
326
327                         DRM_DEBUG("No valid modes on %s\n", output->name);
328
329                         /* Should we do this here ???
330                          * When no valid EDID modes are available we end up
331                          * here and bailed in the past, now we add a standard
332                          * 640x480@60Hz mode and carry on.
333                          */
334                         stdmode = drm_mode_duplicate(dev, &std_mode[0]);
335                         drm_mode_probed_add(output, stdmode);
336                         drm_mode_list_concat(&output->probed_modes,
337                                              &output->modes);
338
339                         DRM_DEBUG("Adding standard 640x480 @ 60Hz to %s\n",
340                                                                 output->name);
341                 }
342
343                 drm_mode_sort(&output->modes);
344
345                 DRM_DEBUG("Probed modes for %s\n", output->name);
346                 list_for_each_entry_safe(mode, t, &output->modes, head) {
347                         mode->vrefresh = drm_mode_vrefresh(mode);
348
349                         drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
350                         drm_mode_debug_printmodeline(dev, mode);
351                 }
352         }
353 }
354
355 /**
356  * drm_crtc_set_mode - set a mode
357  * @crtc: CRTC to program
358  * @mode: mode to use
359  * @x: width of mode
360  * @y: height of mode
361  *
362  * LOCKING:
363  * Caller must hold mode config lock.
364  *
365  * Try to set @mode on @crtc.  Give @crtc and its associated outputs a chance
366  * to fixup or reject the mode prior to trying to set it.
367  *
368  * RETURNS:
369  * True if the mode was set successfully, or false otherwise.
370  */
371 bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
372                        int x, int y)
373 {
374         drm_device_t *dev = crtc->dev;
375         struct drm_display_mode *adjusted_mode, saved_mode;
376         int saved_x, saved_y;
377         bool didLock = false;
378         bool ret = false;
379         struct drm_output *output;
380
381         adjusted_mode = drm_mode_duplicate(dev, mode);
382
383         crtc->enabled = drm_crtc_in_use(crtc);
384
385         if (!crtc->enabled) {
386                 return true;
387         }
388
389         didLock = crtc->funcs->lock(crtc);
390
391         saved_mode = crtc->mode;
392         saved_x = crtc->x;
393         saved_y = crtc->y;
394         
395         /* Update crtc values up front so the driver can rely on them for mode
396          * setting.
397          */
398         crtc->mode = *mode;
399         crtc->x = x;
400         crtc->y = y;
401
402         /* XXX short-circuit changes to base location only */
403         
404         /* Pass our mode to the outputs and the CRTC to give them a chance to
405          * adjust it according to limitations or output properties, and also
406          * a chance to reject the mode entirely.
407          */
408         list_for_each_entry(output, &dev->mode_config.output_list, head) {
409                 
410                 if (output->crtc != crtc)
411                         continue;
412                 
413                 if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) {
414                         goto done;
415                 }
416         }
417         
418         if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) {
419                 goto done;
420         }
421
422         /* Prepare the outputs and CRTCs before setting the mode. */
423         list_for_each_entry(output, &dev->mode_config.output_list, head) {
424
425                 if (output->crtc != crtc)
426                         continue;
427                 
428                 /* Disable the output as the first thing we do. */
429                 output->funcs->prepare(output);
430         }
431         
432         crtc->funcs->prepare(crtc);
433         
434         /* Set up the DPLL and any output state that needs to adjust or depend
435          * on the DPLL.
436          */
437         crtc->funcs->mode_set(crtc, mode, adjusted_mode, x, y);
438         list_for_each_entry(output, &dev->mode_config.output_list, head) {
439                 if (output->crtc == crtc) {
440                         dev_warn(&output->dev->pdev->dev, "%s: set mode %s\n",
441                                 output->name, mode->name);
442                         output->funcs->mode_set(output, mode, adjusted_mode);
443                 }
444         }
445         
446         /* Now, enable the clocks, plane, pipe, and outputs that we set up. */
447         crtc->funcs->commit(crtc);
448         list_for_each_entry(output, &dev->mode_config.output_list, head) {
449                 if (output->crtc == crtc) {
450                         output->funcs->commit(output);
451 #if 0 // TODO def RANDR_12_INTERFACE
452                         if (output->randr_output)
453                                 RRPostPendingProperties (output->randr_output);
454 #endif
455                 }
456         }
457         
458         /* XXX free adjustedmode */
459         drm_mode_destroy(dev, adjusted_mode);
460         ret = TRUE;
461         /* TODO */
462 //      if (scrn->pScreen)
463 //              drm_crtc_set_screen_sub_pixel_order(dev);
464
465 done:
466         if (!ret) {
467                 crtc->x = saved_x;
468                 crtc->y = saved_y;
469                 crtc->mode = saved_mode;
470         }
471         
472         if (didLock)
473                 crtc->funcs->unlock (crtc);
474         
475         return ret;
476 }
477 EXPORT_SYMBOL(drm_crtc_set_mode);
478
479 /**
480  * drm_disable_unused_functions - disable unused objects
481  * @dev: DRM device
482  *
483  * LOCKING:
484  * Caller must hold mode config lock.
485  *
486  * If an output or CRTC isn't part of @dev's mode_config, it can be disabled
487  * by calling its dpms function, which should power it off.
488  */
489 void drm_disable_unused_functions(struct drm_device *dev)
490 {
491         struct drm_output *output;
492         struct drm_crtc *crtc;
493
494         list_for_each_entry(output, &dev->mode_config.output_list, head) {
495                 if (!output->crtc)
496                         (*output->funcs->dpms)(output, DPMSModeOff);
497         }
498
499         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
500                 if (!crtc->enabled)
501                         crtc->funcs->dpms(crtc, DPMSModeOff);
502         }
503 }
504         
505 /**
506  * drm_mode_probed_add - add a mode to the specified output's probed mode list
507  * @output: output the new mode
508  * @mode: mode data
509  *
510  * LOCKING:
511  * Caller must hold mode config lock.
512  * 
513  * Add @mode to @output's mode list for later use.
514  */
515 void drm_mode_probed_add(struct drm_output *output,
516                          struct drm_display_mode *mode)
517 {
518         list_add(&mode->head, &output->probed_modes);
519 }
520 EXPORT_SYMBOL(drm_mode_probed_add);
521
522 /**
523  * drm_mode_remove - remove and free a mode
524  * @output: output list to modify
525  * @mode: mode to remove
526  *
527  * LOCKING:
528  * Caller must hold mode config lock.
529  * 
530  * Remove @mode from @output's mode list, then free it.
531  */
532 void drm_mode_remove(struct drm_output *output, struct drm_display_mode *mode)
533 {
534         list_del(&mode->head);
535         kfree(mode);
536 }
537 EXPORT_SYMBOL(drm_mode_remove);
538
539 /**
540  * drm_output_create - create a new output
541  * @dev: DRM device
542  * @funcs: callbacks for this output
543  * @name: user visible name of the output
544  *
545  * LOCKING:
546  * Caller must hold @dev's mode_config lock.
547  *
548  * Creates a new drm_output structure and adds it to @dev's mode_config
549  * structure.
550  *
551  * RETURNS:
552  * Pointer to the new output or NULL on error.
553  */
554 struct drm_output *drm_output_create(drm_device_t *dev,
555                                      const struct drm_output_funcs *funcs,
556                                      const char *name)
557 {
558         struct drm_output *output = NULL;
559
560         output = kzalloc(sizeof(struct drm_output), GFP_KERNEL);
561         if (!output)
562                 return NULL;
563                 
564         output->dev = dev;
565         output->funcs = funcs;
566         output->id = drm_idr_get(dev, output);
567         if (name)
568                 strncpy(output->name, name, DRM_OUTPUT_LEN);
569         output->name[DRM_OUTPUT_LEN - 1] = 0;
570         output->subpixel_order = SubPixelUnknown;
571         INIT_LIST_HEAD(&output->probed_modes);
572         INIT_LIST_HEAD(&output->modes);
573         /* randr_output? */
574         /* output_set_monitor(output)? */
575         /* check for output_ignored(output)? */
576
577         spin_lock(&dev->mode_config.config_lock);
578         list_add_tail(&output->head, &dev->mode_config.output_list);
579         dev->mode_config.num_output++;
580
581         spin_unlock(&dev->mode_config.config_lock);
582
583         return output;
584
585 }
586 EXPORT_SYMBOL(drm_output_create);
587
588 /**
589  * drm_output_destroy - remove an output
590  * @output: output to remove
591  *
592  * LOCKING:
593  * Caller must hold @dev's mode_config lock.
594  *
595  * Call @output's cleanup function, then remove the output from the DRM
596  * mode_config after freeing @output's modes.
597  */
598 void drm_output_destroy(struct drm_output *output)
599 {
600         struct drm_device *dev = output->dev;
601         struct drm_display_mode *mode, *t;
602
603         if (*output->funcs->cleanup)
604                 (*output->funcs->cleanup)(output);
605
606         list_for_each_entry_safe(mode, t, &output->probed_modes, head)
607                 drm_mode_remove(output, mode);
608
609         list_for_each_entry_safe(mode, t, &output->modes, head)
610                 drm_mode_remove(output, mode);
611
612         spin_lock(&dev->mode_config.config_lock);
613         drm_idr_put(dev, output->id);
614         list_del(&output->head);
615         spin_unlock(&dev->mode_config.config_lock);
616         kfree(output);
617 }
618 EXPORT_SYMBOL(drm_output_destroy);
619
620 /**
621  * drm_output_rename - rename an output
622  * @output: output to rename
623  * @name: new user visible name
624  *
625  * LOCKING:
626  * None.
627  *
628  * Simply stuff a new name into @output's name field, based on @name.
629  *
630  * RETURNS:
631  * True if the name was changed, false otherwise.
632  */
633 bool drm_output_rename(struct drm_output *output, const char *name)
634 {
635         if (!name)
636                 return false;
637
638         strncpy(output->name, name, DRM_OUTPUT_LEN);
639         output->name[DRM_OUTPUT_LEN - 1] = 0;
640
641         DRM_DEBUG("Changed name to %s\n", output->name);
642 //      drm_output_set_monitor(output);
643 //      if (drm_output_ignored(output))
644 //              return FALSE;
645
646         return TRUE;
647 }
648 EXPORT_SYMBOL(drm_output_rename);
649
650 /**
651  * drm_mode_create - create a new display mode
652  * @dev: DRM device
653  *
654  * LOCKING:
655  * None.
656  *
657  * Create a new drm_display_mode, give it an ID, and return it.
658  *
659  * RETURNS:
660  * Pointer to new mode on success, NULL on error.
661  */
662 struct drm_display_mode *drm_mode_create(struct drm_device *dev)
663 {
664         struct drm_display_mode *nmode;
665
666         nmode = kzalloc(sizeof(struct drm_display_mode), GFP_KERNEL);
667         if (!nmode)
668                 return NULL;
669
670         nmode->mode_id = drm_idr_get(dev, nmode);
671         return nmode;
672 }
673 EXPORT_SYMBOL(drm_mode_create);
674
675 /**
676  * drm_mode_destroy - remove a mode
677  * @dev: DRM device
678  * @mode: mode to remove
679  *
680  * LOCKING:
681  * Caller must hold mode config lock.
682  *
683  * Free @mode's unique identifier, then free it.
684  */
685 void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
686 {
687         drm_idr_put(dev, mode->mode_id);
688
689         kfree(mode);
690 }
691 EXPORT_SYMBOL(drm_mode_destroy);
692
693 /**
694  * drm_mode_config_init - initialize DRM mode_configuration structure
695  * @dev: DRM device
696  *
697  * LOCKING:
698  * None, should happen single threaded at init time.
699  *
700  * Initialize @dev's mode_config structure, used for tracking the graphics
701  * configuration of @dev.
702  */
703 void drm_mode_config_init(drm_device_t *dev)
704 {
705         spin_lock_init(&dev->mode_config.config_lock);
706         INIT_LIST_HEAD(&dev->mode_config.fb_list);
707         INIT_LIST_HEAD(&dev->mode_config.crtc_list);
708         INIT_LIST_HEAD(&dev->mode_config.output_list);
709         INIT_LIST_HEAD(&dev->mode_config.usermode_list);
710         idr_init(&dev->mode_config.crtc_idr);
711 }
712 EXPORT_SYMBOL(drm_mode_config_init);
713
714 /**
715  * drm_get_buffer_object - find the buffer object for a given handle
716  * @dev: DRM device
717  * @bo: pointer to caller's buffer_object pointer
718  * @handle: handle to lookup
719  *
720  * LOCKING:
721  * Must take @dev's struct_mutex to protect buffer object lookup.
722  *
723  * Given @handle, lookup the buffer object in @dev and put it in the caller's
724  * @bo pointer.
725  *
726  * RETURNS:
727  * Zero on success, -EINVAL if the handle couldn't be found.
728  */
729 static int drm_get_buffer_object(drm_device_t *dev, struct drm_buffer_object **bo, unsigned long handle)
730 {
731         drm_user_object_t *uo;
732         drm_hash_item_t *hash;
733         int ret;
734
735         *bo = NULL;
736
737         mutex_lock(&dev->struct_mutex);
738         ret = drm_ht_find_item(&dev->object_hash, handle, &hash);
739         if (ret) {
740                 DRM_ERROR("Couldn't find handle.\n");
741                 ret = -EINVAL;
742                 goto out_err;
743         }
744
745         uo = drm_hash_entry(hash, drm_user_object_t, hash);
746         if (uo->type != drm_buffer_type) {
747                 ret = -EINVAL;
748                 goto out_err;
749         }
750         
751         *bo = drm_user_object_entry(uo, drm_buffer_object_t, base);
752         ret = 0;
753 out_err:
754         mutex_unlock(&dev->struct_mutex);
755         return ret;
756 }
757
758 /**
759  * drm_pick_crtcs - pick crtcs for output devices
760  * @dev: DRM device
761  *
762  * LOCKING:
763  * Caller must hold mode config lock.
764  */
765 static void drm_pick_crtcs (drm_device_t *dev)
766 {
767         int c, o;
768         struct drm_output *output, *output_equal;
769         struct drm_crtc   *crtc;
770         struct drm_display_mode *des_mode = NULL, *modes, *modes_equal;
771
772         list_for_each_entry(output, &dev->mode_config.output_list, head) {
773                 output->crtc = NULL;
774     
775                 /* Don't hook up outputs that are disconnected ??
776                  *
777                  * This is debateable. Do we want fixed /dev/fbX or
778                  * dynamic on hotplug (need mode code for that though) ?
779                  *
780                  * If we don't hook up outputs now, then we only create
781                  * /dev/fbX for the output that's enabled, that's good as
782                  * the users console will be on that output.
783                  *
784                  * If we do hook up outputs that are disconnected now, then
785                  * the user may end up having to muck about with the fbcon
786                  * map flags to assign his console to the enabled output. Ugh.
787                  */
788                 if (output->status != output_status_connected)
789                         continue;
790
791                 des_mode = NULL;
792                 list_for_each_entry(des_mode, &output->modes, head) {
793                         if (des_mode->type & DRM_MODE_TYPE_PREFERRED)
794                                 break;
795                 }
796
797                 /* No preferred mode, let's just select the first available */
798                 if (!des_mode || !(des_mode->type & DRM_MODE_TYPE_PREFERRED)) {
799                         list_for_each_entry(des_mode, &output->modes, head) {
800                                 if (des_mode)
801                                         break;
802                         }
803                 }
804
805                 c = -1;
806                 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
807                         c++;
808                         if ((output->possible_crtcs & (1 << c)) == 0)
809                                 continue;
810         
811 #if 0 /* should we try and clone ?? - code not tested - FIXME */
812                         o = -1;
813                         list_for_each_entry(output_equal, &dev->mode_config.output_list, head) {
814                                 o++;
815                                 if (output->id == output_equal->id)
816                                         continue;
817
818                                 list_for_each_entry(modes, &output->modes, head) {
819                                         list_for_each_entry(modes_equal, &output_equal->modes, head) {
820                                                 if (drm_mode_equal (modes, modes_equal)) {
821                                                         if ((output->possible_clones & (1 << o))) {
822                                                                 goto clone;
823                                                         }
824                                                 }
825                                         }
826                                 }
827                         }
828
829 clone:
830 #endif
831                         /* Found a CRTC to attach to, do it ! */
832                         output->crtc = crtc;
833                         output->crtc->desired_mode = des_mode;
834                         output->initial_x = 0;
835                         output->initial_y = 0;
836                         DRM_DEBUG("Desired mode for CRTC %d is %s\n",c,des_mode->name);
837                         break;
838                 }
839         }
840 }
841
842
843 /**
844  * drm_initial_config - setup a sane initial output configuration
845  * @dev: DRM device
846  * @can_grow: this configuration is growable
847  *
848  * LOCKING:
849  * Called at init time, must take mode config lock.
850  *
851  * Scan the CRTCs and outputs and try to put together an initial setup.
852  * At the moment, this is a cloned configuration across all heads with
853  * a new framebuffer object as the backing store.
854  *
855  * RETURNS:
856  * Zero if everything went ok, nonzero otherwise.
857  */
858 bool drm_initial_config(drm_device_t *dev, bool can_grow)
859 {
860         struct drm_output *output;
861         int ret = false;
862
863         spin_lock(&dev->mode_config.config_lock);
864
865         drm_crtc_probe_output_modes(dev, 2048, 2048);
866
867         drm_pick_crtcs(dev);
868
869         list_for_each_entry(output, &dev->mode_config.output_list, head) {
870
871                 /* can't setup the output if there's no assigned crtc or mode */
872                 if (!output->crtc || !output->crtc->desired_mode)
873                         continue;
874
875                 dev->driver->fb_probe(dev, output->crtc);
876         }
877         drm_disable_unused_functions(dev);
878
879         spin_unlock(&dev->mode_config.config_lock);
880         return ret;
881 }
882 EXPORT_SYMBOL(drm_initial_config);
883
884 /**
885  * drm_mode_config_cleanup - free up DRM mode_config info
886  * @dev: DRM device
887  *
888  * LOCKING:
889  * Caller must hold mode config lock.
890  *
891  * Free up all the outputs and CRTCs associated with this DRM device, then
892  * free up the framebuffers and associated buffer objects.
893  *
894  * FIXME: cleanup any dangling user buffer objects too
895  */
896 void drm_mode_config_cleanup(drm_device_t *dev)
897 {
898         struct drm_output *output, *ot;
899         struct drm_crtc *crtc, *ct;
900         struct drm_framebuffer *fb, *fbt;
901         struct drm_display_mode *mode, *mt;
902         list_for_each_entry_safe(output, ot, &dev->mode_config.output_list, head) {
903                 drm_output_destroy(output);
904         }
905
906         list_for_each_entry_safe(mode, mt, &dev->mode_config.usermode_list, head) {
907                 drm_mode_destroy(dev, mode);
908         }
909                 
910         list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
911                 dev->driver->fb_remove(dev, drm_crtc_from_fb(dev, fb));
912                 /* If this FB was the kernel one, free it */
913                 if (fb->bo->type == drm_bo_type_kernel) {
914                         mutex_lock(&dev->struct_mutex);
915                         drm_bo_usage_deref_locked(fb->bo);
916                         mutex_unlock(&dev->struct_mutex);
917                 }
918                 drm_framebuffer_destroy(fb);
919         }
920
921         list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
922                 drm_crtc_destroy(crtc);
923         }
924
925 }
926 EXPORT_SYMBOL(drm_mode_config_cleanup);
927
928 /**
929  * drm_crtc_set_config - set a new config from userspace
930  * @crtc: CRTC to setup
931  * @crtc_info: user provided configuration
932  * @new_mode: new mode to set
933  * @output_set: set of outputs for the new config
934  * @fb: new framebuffer
935  *
936  * LOCKING:
937  * Caller must hold mode config lock.
938  *
939  * Setup a new configuration, provided by the user in @crtc_info, and enable
940  * it.
941  *
942  * RETURNS:
943  * Zero. (FIXME)
944  */
945 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)
946 {
947         drm_device_t *dev = crtc->dev;
948         struct drm_crtc **save_crtcs, *new_crtc;
949         bool save_enabled = crtc->enabled;
950         bool changed;
951         struct drm_output *output;
952         int count = 0, ro;
953
954         save_crtcs = kzalloc(dev->mode_config.num_crtc * sizeof(struct drm_crtc *), GFP_KERNEL);
955         if (!save_crtcs)
956                 return -ENOMEM;
957
958         if (crtc->fb != fb)
959                 changed = true;
960
961         if (crtc_info->x != crtc->x || crtc_info->y != crtc->y)
962                 changed = true;
963
964         if (new_mode && (crtc->mode.mode_id != new_mode->mode_id))
965                 changed = true;
966
967         list_for_each_entry(output, &dev->mode_config.output_list, head) {
968                 save_crtcs[count++] = output->crtc;
969
970                 if (output->crtc == crtc)
971                         new_crtc = NULL;
972                 else
973                         new_crtc = output->crtc;
974
975                 for (ro = 0; ro < crtc_info->count_outputs; ro++) {
976                         if (output_set[ro] == output)
977                                 new_crtc = crtc;
978                 }
979                 if (new_crtc != output->crtc) {
980                         changed = true;
981                         output->crtc = new_crtc;
982                 }
983         }
984
985         if (changed) {
986                 crtc->fb = fb;
987                 crtc->enabled = (new_mode != NULL);
988                 if (new_mode != NULL) {
989                         DRM_DEBUG("attempting to set mode from userspace\n");
990                         drm_mode_debug_printmodeline(dev, new_mode);
991                         if (!drm_crtc_set_mode(crtc, new_mode, crtc_info->x,
992                                                crtc_info->y)) {
993                                 crtc->enabled = save_enabled;
994                                 count = 0;
995                                 list_for_each_entry(output, &dev->mode_config.output_list, head)
996                                         output->crtc = save_crtcs[count++];
997                                 kfree(save_crtcs);
998                                 return -EINVAL;
999                         }
1000                         crtc->desired_x = crtc_info->x;
1001                         crtc->desired_y = crtc_info->y;
1002                         crtc->desired_mode = new_mode;
1003                 }
1004                 drm_disable_unused_functions(dev);
1005         }
1006         kfree(save_crtcs);
1007         return 0;
1008 }
1009
1010 /**
1011  * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
1012  * @out: drm_mode_modeinfo struct to return to the user
1013  * @in: drm_display_mode to use
1014  *
1015  * LOCKING:
1016  * None.
1017  *
1018  * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
1019  * the user.
1020  */
1021 void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out, struct drm_display_mode *in)
1022 {
1023
1024         out->id = in->mode_id;
1025         out->clock = in->clock;
1026         out->hdisplay = in->hdisplay;
1027         out->hsync_start = in->hsync_start;
1028         out->hsync_end = in->hsync_end;
1029         out->htotal = in->htotal;
1030         out->hskew = in->hskew;
1031         out->vdisplay = in->vdisplay;
1032         out->vsync_start = in->vsync_start;
1033         out->vsync_end = in->vsync_end;
1034         out->vtotal = in->vtotal;
1035         out->vscan = in->vscan;
1036         out->vrefresh = in->vrefresh;
1037         out->flags = in->flags;
1038         strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
1039         out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1040 }
1041
1042 /**
1043  * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode
1044  * @out: drm_display_mode to return to the user
1045  * @in: drm_mode_modeinfo to use
1046  *
1047  * LOCKING:
1048  * None.
1049  *
1050  * Convert a drmo_mode_modeinfo into a drm_display_mode structure to return to
1051  * the caller.
1052  */
1053 void drm_crtc_convert_umode(struct drm_display_mode *out, struct drm_mode_modeinfo *in)
1054 {
1055         out->clock = in->clock;
1056         out->hdisplay = in->hdisplay;
1057         out->hsync_start = in->hsync_start;
1058         out->hsync_end = in->hsync_end;
1059         out->htotal = in->htotal;
1060         out->hskew = in->hskew;
1061         out->vdisplay = in->vdisplay;
1062         out->vsync_start = in->vsync_start;
1063         out->vsync_end = in->vsync_end;
1064         out->vtotal = in->vtotal;
1065         out->vscan = in->vscan;
1066         out->vrefresh = in->vrefresh;
1067         out->flags = in->flags;
1068         strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
1069         out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1070 }
1071         
1072 /**
1073  * drm_mode_getresources - get graphics configuration
1074  * @inode: inode from the ioctl
1075  * @filp: file * from the ioctl
1076  * @cmd: cmd from ioctl
1077  * @arg: arg from ioctl
1078  *
1079  * LOCKING:
1080  * Takes mode config lock.
1081  *
1082  * Construct a set of configuration description structures and return
1083  * them to the user, including CRTC, output and framebuffer configuration.
1084  *
1085  * Called by the user via ioctl.
1086  *
1087  * RETURNS:
1088  * Zero on success, errno on failure.
1089  */
1090 int drm_mode_getresources(struct inode *inode, struct file *filp,
1091                           unsigned int cmd, unsigned long arg)
1092 {
1093         drm_file_t *priv = filp->private_data;
1094         drm_device_t *dev = priv->head->dev;
1095         struct drm_mode_card_res __user *argp = (void __user *)arg;
1096         struct drm_mode_card_res card_res;
1097         struct list_head *lh;
1098         struct drm_framebuffer *fb;
1099         struct drm_output *output;
1100         struct drm_crtc *crtc;
1101         struct drm_mode_modeinfo u_mode;
1102         struct drm_display_mode *mode;
1103         int ret = 0;
1104         int mode_count= 0;
1105         int output_count = 0;
1106         int crtc_count = 0;
1107         int fb_count = 0;
1108         int copied = 0;
1109         
1110         memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
1111
1112         spin_lock(&dev->mode_config.config_lock);
1113
1114         list_for_each(lh, &dev->mode_config.fb_list)
1115                 fb_count++;
1116
1117         list_for_each(lh, &dev->mode_config.crtc_list)
1118                 crtc_count++;
1119
1120         list_for_each_entry(output, &dev->mode_config.output_list,
1121                             head) {
1122                 output_count++;
1123                 list_for_each(lh, &output->modes)
1124                         mode_count++;
1125         }
1126         list_for_each(lh, &dev->mode_config.usermode_list)
1127                 mode_count++;
1128
1129         if (copy_from_user(&card_res, argp, sizeof(card_res))) {
1130                 ret = -EFAULT;
1131                 goto out_unlock;
1132         }
1133
1134         if (card_res.count_modes == 0) {
1135                 DRM_DEBUG("probing modes %dx%d\n", dev->mode_config.max_width, dev->mode_config.max_height);
1136                 drm_crtc_probe_output_modes(dev, dev->mode_config.max_width, dev->mode_config.max_height);
1137                 mode_count = 0;
1138                 list_for_each_entry(output, &dev->mode_config.output_list, head) {
1139                         list_for_each(lh, &output->modes)
1140                                 mode_count++;
1141                 }
1142                 list_for_each(lh, &dev->mode_config.usermode_list)
1143                         mode_count++;
1144         }
1145
1146         /* handle this in 4 parts */
1147         /* FBs */
1148         if (card_res.count_fbs >= fb_count) {
1149                 copied = 0;
1150                 list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
1151                         if (put_user(fb->id, &card_res.fb_id[copied++])) {
1152                                 ret = -EFAULT;
1153                                 goto done;
1154                         }
1155                 }
1156         }
1157         card_res.count_fbs = fb_count;
1158
1159         /* CRTCs */
1160         if (card_res.count_crtcs >= crtc_count) {
1161                 copied = 0;
1162                 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head){
1163                         DRM_DEBUG("CRTC ID is %d\n", crtc->id);
1164                         if (put_user(crtc->id, &card_res.crtc_id[copied++])) {
1165                                 ret = -EFAULT;
1166                                 goto done;
1167                         }
1168                 }
1169         }
1170         card_res.count_crtcs = crtc_count;
1171
1172
1173         /* Outputs */
1174         if (card_res.count_outputs >= output_count) {
1175                 copied = 0;
1176                 list_for_each_entry(output, &dev->mode_config.output_list,
1177                                     head) {
1178                         DRM_DEBUG("OUTPUT ID is %d\n", output->id);
1179                         if (put_user(output->id, &card_res.output_id[copied++])) {
1180                                 ret = -EFAULT;
1181                                 goto done;
1182                         }
1183                 }
1184         }
1185         card_res.count_outputs = output_count;
1186         
1187         /* Modes */
1188         if (card_res.count_modes >= mode_count) {
1189                 copied = 0;
1190                 list_for_each_entry(output, &dev->mode_config.output_list,
1191                                     head) {
1192                         list_for_each_entry(mode, &output->modes, head) {
1193                                 drm_crtc_convert_to_umode(&u_mode, mode);
1194                                 if (copy_to_user(&card_res.modes[copied++], &u_mode, sizeof(struct drm_mode_modeinfo))) {
1195                                         ret = -EFAULT;
1196                                         goto done;
1197                                 }
1198                         }
1199                 }
1200                 /* add in user modes */
1201                 list_for_each_entry(mode, &dev->mode_config.usermode_list, head) {
1202                         drm_crtc_convert_to_umode(&u_mode, mode);
1203                         if (copy_to_user(&card_res.modes[copied++], &u_mode, sizeof(struct drm_mode_modeinfo))) {
1204                                 ret = -EFAULT;
1205                                 goto done;
1206                         }
1207                 }
1208         }
1209         card_res.count_modes = mode_count;
1210
1211 done:
1212         DRM_DEBUG("Counted %d %d %d\n", card_res.count_crtcs,
1213                   card_res.count_outputs,
1214                   card_res.count_modes);
1215         
1216         if (copy_to_user(argp, &card_res, sizeof(card_res)))
1217                 ret = -EFAULT;
1218
1219 out_unlock:
1220         spin_unlock(&dev->mode_config.config_lock);
1221         return ret;
1222 }
1223
1224 /**
1225  * drm_mode_getcrtc - get CRTC configuration
1226  * @inode: inode from the ioctl
1227  * @filp: file * from the ioctl
1228  * @cmd: cmd from ioctl
1229  * @arg: arg from ioctl
1230  *
1231  * LOCKING:
1232  * Caller? (FIXME)
1233  *
1234  * Construct a CRTC configuration structure to return to the user.
1235  *
1236  * Called by the user via ioctl.
1237  *
1238  * RETURNS:
1239  * Zero on success, errno on failure.
1240  */
1241 int drm_mode_getcrtc(struct inode *inode, struct file *filp,
1242                      unsigned int cmd, unsigned long arg)
1243 {
1244         drm_file_t *priv = filp->private_data;
1245         drm_device_t *dev = priv->head->dev;
1246         struct drm_mode_crtc __user *argp = (void __user *)arg;
1247         struct drm_mode_crtc crtc_resp;
1248         struct drm_crtc *crtc;
1249         struct drm_output *output;
1250         int ocount;
1251         int ret = 0;
1252
1253         if (copy_from_user(&crtc_resp, argp, sizeof(crtc_resp)))
1254                 return -EFAULT;
1255
1256         spin_lock(&dev->mode_config.config_lock);
1257         crtc = idr_find(&dev->mode_config.crtc_idr, crtc_resp.crtc_id);
1258         if (!crtc || (crtc->id != crtc_resp.crtc_id)) {
1259                 ret = -EINVAL;
1260                 goto out;
1261         }
1262
1263         crtc_resp.x = crtc->x;
1264         crtc_resp.y = crtc->y;
1265         crtc_resp.fb_id = 1;
1266
1267         crtc_resp.outputs = 0;
1268         if (crtc->enabled) {
1269
1270                 crtc_resp.mode = crtc->mode.mode_id;
1271                 ocount = 0;
1272                 list_for_each_entry(output, &dev->mode_config.output_list, head) {
1273                         if (output->crtc == crtc)
1274                                 crtc_resp.outputs |= 1 << (ocount++);
1275                 }
1276         } else {
1277                 crtc_resp.mode = 0;
1278         }
1279
1280         if (copy_to_user(argp, &crtc_resp, sizeof(crtc_resp)))
1281                 ret = -EFAULT;
1282
1283 out:
1284         spin_unlock(&dev->mode_config.config_lock);
1285         return ret;
1286 }
1287
1288 /**
1289  * drm_mode_getoutput - get output configuration
1290  * @inode: inode from the ioctl
1291  * @filp: file * from the ioctl
1292  * @cmd: cmd from ioctl
1293  * @arg: arg from ioctl
1294  *
1295  * LOCKING:
1296  * Caller? (FIXME)
1297  *
1298  * Construct a output configuration structure to return to the user.
1299  *
1300  * Called by the user via ioctl.
1301  *
1302  * RETURNS:
1303  * Zero on success, errno on failure.
1304  */
1305 int drm_mode_getoutput(struct inode *inode, struct file *filp,
1306                        unsigned int cmd, unsigned long arg)
1307 {
1308         drm_file_t *priv = filp->private_data;
1309         drm_device_t *dev = priv->head->dev;
1310         struct drm_mode_get_output __user *argp = (void __user *)arg;
1311         struct drm_mode_get_output out_resp;
1312         struct drm_output *output;
1313         struct drm_display_mode *mode;
1314         int mode_count = 0;
1315         int ret = 0;
1316         int copied = 0;
1317         int i;
1318
1319         if (copy_from_user(&out_resp, argp, sizeof(out_resp)))
1320                 return -EFAULT; 
1321
1322         DRM_DEBUG("output id %d:\n", out_resp.output);
1323
1324         spin_lock(&dev->mode_config.config_lock);
1325         output= idr_find(&dev->mode_config.crtc_idr, out_resp.output);
1326         if (!output || (output->id != out_resp.output)) {
1327                 ret = -EINVAL;
1328                 goto out_unlock;
1329         }
1330
1331         list_for_each_entry(mode, &output->modes, head)
1332                 mode_count++;
1333         
1334         for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++)
1335                 if (output->user_mode_ids[i] != 0)
1336                         mode_count++;
1337
1338         strncpy(out_resp.name, output->name, DRM_OUTPUT_NAME_LEN);
1339         out_resp.name[DRM_OUTPUT_NAME_LEN-1] = 0;
1340
1341         out_resp.mm_width = output->mm_width;
1342         out_resp.mm_height = output->mm_height;
1343         out_resp.subpixel = output->subpixel_order;
1344         out_resp.connection = output->status;
1345         if (output->crtc)
1346                 out_resp.crtc = output->crtc->id;
1347         else
1348                 out_resp.crtc = 0;
1349
1350         if ((out_resp.count_modes >= mode_count) && mode_count) {
1351                 copied = 0;
1352                 list_for_each_entry(mode, &output->modes, head) {
1353                         if (put_user(mode->mode_id, &out_resp.modes[copied++])) {
1354                                 ret = -EFAULT;
1355                                 goto done;
1356                         }
1357                 }
1358                 for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++) {
1359                         if (output->user_mode_ids[i] != 0)
1360                                 if (put_user(output->user_mode_ids[i], &out_resp.modes[copied++])) {
1361                                         ret = -EFAULT;
1362                                         goto done;
1363                                 }
1364                 }
1365                         
1366         }
1367         out_resp.count_modes = mode_count;
1368
1369 done:
1370         if (copy_to_user(argp, &out_resp, sizeof(out_resp)))
1371                 ret = -EFAULT;
1372
1373 out_unlock:
1374         spin_unlock(&dev->mode_config.config_lock);
1375         return ret;
1376 }
1377
1378 /**
1379  * drm_mode_setcrtc - set CRTC configuration
1380  * @inode: inode from the ioctl
1381  * @filp: file * from the ioctl
1382  * @cmd: cmd from ioctl
1383  * @arg: arg from ioctl
1384  *
1385  * LOCKING:
1386  * Caller? (FIXME)
1387  *
1388  * Build a new CRTC configuration based on user request.
1389  *
1390  * Called by the user via ioctl.
1391  *
1392  * RETURNS:
1393  * Zero on success, errno on failure.
1394  */
1395 int drm_mode_setcrtc(struct inode *inode, struct file *filp,
1396                      unsigned int cmd, unsigned long arg)
1397 {
1398         drm_file_t *priv = filp->private_data;
1399         drm_device_t *dev = priv->head->dev;
1400         struct drm_mode_crtc __user *argp = (void __user *)arg;
1401         struct drm_mode_crtc crtc_req;
1402         struct drm_crtc *crtc;
1403         struct drm_output **output_set = NULL, *output;
1404         struct drm_display_mode *mode;
1405         struct drm_framebuffer *fb = NULL;
1406         int ret = 0;
1407         int i;
1408
1409         if (copy_from_user(&crtc_req, argp, sizeof(crtc_req)))
1410                 return -EFAULT;
1411
1412         spin_lock(&dev->mode_config.config_lock);
1413         crtc = idr_find(&dev->mode_config.crtc_idr, crtc_req.crtc_id);
1414         if (!crtc || (crtc->id != crtc_req.crtc_id)) {
1415                 DRM_DEBUG("Unknown CRTC ID %d\n", crtc_req.crtc_id);
1416                 ret = -EINVAL;
1417                 goto out;
1418         }
1419
1420         if (crtc_req.mode) {
1421                 /* if we have a mode we need a framebuffer */
1422                 if (crtc_req.fb_id) {
1423                         fb = idr_find(&dev->mode_config.crtc_idr, crtc_req.fb_id);
1424                         if (!fb || (fb->id != crtc_req.fb_id)) {
1425                                 DRM_DEBUG("Unknown FB ID%d\n", crtc_req.fb_id);
1426                                 ret = -EINVAL;
1427                                 goto out;
1428                         }
1429                 }
1430                 mode = idr_find(&dev->mode_config.crtc_idr, crtc_req.mode);
1431                 if (!mode || (mode->mode_id != crtc_req.mode)) {
1432                         struct drm_output *output;
1433                         
1434                         list_for_each_entry(output, 
1435                                             &dev->mode_config.output_list,
1436                                             head) {
1437                                 list_for_each_entry(mode, &output->modes,
1438                                                     head) {
1439                                         drm_mode_debug_printmodeline(dev, 
1440                                                                      mode);
1441                                 }
1442                         }
1443
1444                         DRM_DEBUG("Unknown mode id %d, %p\n", crtc_req.mode, mode);
1445                         ret = -EINVAL;
1446                         goto out;
1447                 }
1448         } else
1449                 mode = NULL;
1450
1451         if (crtc_req.count_outputs == 0 && mode) {
1452                 DRM_DEBUG("Count outputs is 0 but mode set\n");
1453                 ret = -EINVAL;
1454                 goto out;
1455         }
1456
1457         if (crtc_req.count_outputs > 0 && !mode && !fb) {
1458                 DRM_DEBUG("Count outputs is %d but no mode or fb set\n", crtc_req.count_outputs);
1459                 ret = -EINVAL;
1460                 goto out;
1461         }
1462
1463         if (crtc_req.count_outputs > 0) {
1464                 u32 out_id;
1465                 output_set = kmalloc(crtc_req.count_outputs *
1466                                      sizeof(struct drm_output *), GFP_KERNEL);
1467                 if (!output_set) {
1468                         ret = -ENOMEM;
1469                         goto out;
1470                 }
1471
1472                 for (i = 0; i < crtc_req.count_outputs; i++) {
1473                         if (get_user(out_id, &crtc_req.set_outputs[i])) {
1474                                 ret = -EFAULT;
1475                                 goto out;
1476                         }
1477
1478                         output = idr_find(&dev->mode_config.crtc_idr, out_id);
1479                         if (!output || (out_id != output->id)) {
1480                                 DRM_DEBUG("Output id %d unknown\n", out_id);
1481                                 ret = -EINVAL;
1482                                 goto out;
1483                         }
1484
1485                         output_set[i] = output;
1486                 }
1487         }
1488                 
1489         ret = drm_crtc_set_config(crtc, &crtc_req, mode, output_set, fb);
1490
1491 out:
1492         spin_unlock(&dev->mode_config.config_lock);
1493         return ret;
1494 }
1495
1496 /**
1497  * drm_mode_addfb - add an FB to the graphics configuration
1498  * @inode: inode from the ioctl
1499  * @filp: file * from the ioctl
1500  * @cmd: cmd from ioctl
1501  * @arg: arg from ioctl
1502  *
1503  * LOCKING:
1504  * Takes mode config lock.
1505  *
1506  * Add a new FB to the specified CRTC, given a user request.
1507  *
1508  * Called by the user via ioctl.
1509  *
1510  * RETURNS:
1511  * Zero on success, errno on failure.
1512  */
1513 int drm_mode_addfb(struct inode *inode, struct file *filp,
1514                    unsigned int cmd, unsigned long arg)
1515 {
1516         struct drm_file *priv = filp->private_data;
1517         struct drm_device *dev = priv->head->dev;
1518         struct drm_mode_fb_cmd __user *argp = (void __user *)arg;
1519         struct drm_mode_fb_cmd r;
1520         struct drm_mode_config *config = &dev->mode_config;
1521         struct drm_framebuffer *fb;
1522         struct drm_buffer_object *bo;
1523         struct drm_crtc *crtc;
1524         int ret = 0;
1525
1526         if (copy_from_user(&r, argp, sizeof(r)))
1527                 return -EFAULT;
1528
1529         if ((config->min_width > r.width) || (r.width > config->max_width)) {
1530                 DRM_ERROR("mode new framebuffer width not within limits\n");
1531                 return -EINVAL;
1532         }
1533         if ((config->min_height > r.height) || (r.height > config->max_height)) {
1534                 DRM_ERROR("mode new framebuffer height not within limits\n");
1535                 return -EINVAL;
1536         }
1537
1538         spin_lock(&dev->mode_config.config_lock);
1539         /* TODO check limits are okay */
1540         ret = drm_get_buffer_object(dev, &bo, r.handle);
1541         if (ret || !bo) {
1542                 ret = -EINVAL;
1543                 goto out;
1544         }
1545
1546         /* TODO check buffer is sufficently large */
1547         /* TODO setup destructor callback */
1548
1549         fb = drm_framebuffer_create(dev);
1550         if (!fb) {
1551                 ret = -EINVAL;
1552                 goto out;
1553         }
1554
1555         fb->width = r.width;
1556         fb->height = r.height;
1557         fb->pitch = r.pitch;
1558         fb->bits_per_pixel = r.bpp;
1559         fb->depth = r.depth;
1560         fb->offset = bo->offset;
1561         fb->bo = bo;
1562
1563         r.buffer_id = fb->id;
1564
1565         list_add(&fb->filp_head, &priv->fbs);
1566
1567         if (copy_to_user(argp, &r, sizeof(r))) {
1568                 ret = -EFAULT;
1569                 goto out;
1570         }
1571                 
1572         /* FIXME: bind the fb to the right crtc */
1573         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
1574                 crtc->fb = fb;
1575                 dev->driver->fb_probe(dev, crtc);
1576         }
1577
1578 out:
1579         spin_unlock(&dev->mode_config.config_lock);
1580         return ret;
1581 }
1582
1583 /**
1584  * drm_mode_rmfb - remove an FB from the configuration
1585  * @inode: inode from the ioctl
1586  * @filp: file * from the ioctl
1587  * @cmd: cmd from ioctl
1588  * @arg: arg from ioctl
1589  *
1590  * LOCKING:
1591  * Takes mode config lock.
1592  *
1593  * Remove the FB specified by the user.
1594  *
1595  * Called by the user via ioctl.
1596  *
1597  * RETURNS:
1598  * Zero on success, errno on failure.
1599  */
1600 int drm_mode_rmfb(struct inode *inode, struct file *filp,
1601                    unsigned int cmd, unsigned long arg)
1602 {
1603         drm_file_t *priv = filp->private_data;
1604         drm_device_t *dev = priv->head->dev;
1605         struct drm_framebuffer *fb = 0;
1606         uint32_t id = arg;
1607         int ret = 0;
1608
1609         spin_lock(&dev->mode_config.config_lock);
1610         fb = idr_find(&dev->mode_config.crtc_idr, id);
1611         /* TODO check that we realy get a framebuffer back. */
1612         if (!fb || (id != fb->id)) {
1613                 DRM_ERROR("mode invalid framebuffer id\n");
1614                 ret = -EINVAL;
1615                 goto out;
1616         }
1617
1618         dev->driver->fb_remove(dev, drm_crtc_from_fb(dev, fb));
1619
1620         /* TODO check if we own the buffer */
1621         /* TODO release all crtc connected to the framebuffer */
1622         /* bind the fb to the crtc for now */
1623         /* TODO unhock the destructor from the buffer object */
1624
1625         drm_framebuffer_destroy(fb);
1626
1627 out:
1628         spin_unlock(&dev->mode_config.config_lock);
1629         return ret;
1630 }
1631
1632 /**
1633  * drm_mode_getfb - get FB info
1634  * @inode: inode from the ioctl
1635  * @filp: file * from the ioctl
1636  * @cmd: cmd from ioctl
1637  * @arg: arg from ioctl
1638  *
1639  * LOCKING:
1640  * Caller? (FIXME)
1641  *
1642  * Lookup the FB given its ID and return info about it.
1643  *
1644  * Called by the user via ioctl.
1645  *
1646  * RETURNS:
1647  * Zero on success, errno on failure.
1648  */
1649 int drm_mode_getfb(struct inode *inode, struct file *filp,
1650                    unsigned int cmd, unsigned long arg)
1651 {
1652         drm_file_t *priv = filp->private_data;
1653         drm_device_t *dev = priv->head->dev;    
1654         struct drm_mode_fb_cmd __user *argp = (void __user *)arg;
1655         struct drm_mode_fb_cmd r;
1656         struct drm_framebuffer *fb;
1657         int ret = 0;
1658
1659         if (copy_from_user(&r, argp, sizeof(r)))
1660                 return -EFAULT;
1661
1662         spin_lock(&dev->mode_config.config_lock);
1663         fb = idr_find(&dev->mode_config.crtc_idr, r.buffer_id);
1664         if (!fb || (r.buffer_id != fb->id)) {
1665                 DRM_ERROR("invalid framebuffer id\n");
1666                 ret = -EINVAL;
1667                 goto out;
1668         }
1669
1670         r.height = fb->height;
1671         r.width = fb->width;
1672         r.depth = fb->depth;
1673         r.bpp = fb->bits_per_pixel;
1674         r.handle = fb->bo->base.hash.key;
1675         r.pitch = fb->pitch;
1676
1677         if (copy_to_user(argp, &r, sizeof(r)))
1678                 ret = -EFAULT;
1679
1680 out:
1681         spin_unlock(&dev->mode_config.config_lock);
1682         return ret;
1683 }
1684
1685 /**
1686  * drm_fb_release - remove and free the FBs on this file
1687  * @filp: file * from the ioctl
1688  *
1689  * LOCKING:
1690  * Takes mode config lock.
1691  *
1692  * Destroy all the FBs associated with @filp.
1693  *
1694  * Called by the user via ioctl.
1695  *
1696  * RETURNS:
1697  * Zero on success, errno on failure.
1698  */
1699 void drm_fb_release(struct file *filp)
1700 {
1701         drm_file_t *priv = filp->private_data;
1702         drm_device_t *dev = priv->head->dev;
1703         struct drm_framebuffer *fb, *tfb;
1704
1705         spin_lock(&dev->mode_config.config_lock);
1706         list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
1707                 list_del(&fb->filp_head);
1708                 dev->driver->fb_remove(dev, drm_crtc_from_fb(dev, fb));
1709                 drm_framebuffer_destroy(fb);
1710         }
1711         spin_unlock(&dev->mode_config.config_lock);
1712 }
1713
1714 /**
1715  * drm_fb_newmode - adds a user defined mode
1716  * @inode: inode from the ioctl
1717  * @filp: file * from the ioctl
1718  * @cmd: cmd from ioctl
1719  * @arg: arg from ioctl
1720  *
1721  * Adds a user specified mode to the kernel.
1722  *
1723  * Called by the user via ioctl.
1724  *
1725  * RETURNS:
1726  * writes new mode id into arg.
1727  * Zero on success, errno on failure.
1728  */
1729 int drm_mode_addmode(struct inode *inode, struct file *filp,
1730                      unsigned int cmd, unsigned long arg)
1731 {
1732         drm_file_t *priv = filp->private_data;
1733         drm_device_t *dev = priv->head->dev;
1734         struct drm_mode_modeinfo __user *argp = (void __user *)arg;
1735         struct drm_mode_modeinfo new_mode;
1736         struct drm_display_mode *user_mode;
1737         int ret = 0;
1738
1739         if (copy_from_user(&new_mode, argp, sizeof(new_mode)))
1740                 return -EFAULT;
1741
1742         spin_lock(&dev->mode_config.config_lock);
1743         user_mode = drm_mode_create(dev);
1744         if (!user_mode) {
1745                 ret = -ENOMEM;
1746                 goto out;
1747         }
1748
1749         drm_crtc_convert_umode(user_mode, &new_mode);
1750         user_mode->type |= DRM_MODE_TYPE_USERDEF;
1751
1752         user_mode->output_count = 0;
1753
1754         list_add(&user_mode->head, &dev->mode_config.usermode_list);
1755
1756         new_mode.id = user_mode->mode_id;
1757         if (copy_to_user(argp, &new_mode, sizeof(new_mode)))
1758                 ret = -EFAULT;
1759
1760 out:
1761         spin_unlock(&dev->mode_config.config_lock);
1762         return ret;
1763 }
1764
1765 /**
1766  * drm_fb_rmmode - removes a user defined mode
1767  * @inode: inode from the ioctl
1768  * @filp: file * from the ioctl
1769  * @cmd: cmd from ioctl
1770  * @arg: arg from ioctl
1771  *
1772  * Remove the user defined mode specified by the user.
1773  *
1774  * Called by the user via ioctl
1775  *
1776  * RETURNS:
1777  * Zero on success, errno on failure.
1778  */
1779 int drm_mode_rmmode(struct inode *inode, struct file *filp,
1780                     unsigned int cmd, unsigned long arg)
1781 {
1782         drm_file_t *priv = filp->private_data;
1783         drm_device_t *dev = priv->head->dev;
1784         uint32_t id = arg;
1785         struct drm_display_mode *mode, *t;
1786         int ret = -EINVAL;
1787
1788         spin_lock(&dev->mode_config.config_lock);       
1789         mode = idr_find(&dev->mode_config.crtc_idr, id);
1790         if (!mode || (id != mode->mode_id)) {
1791                 ret = -EINVAL;
1792                 goto out;
1793         }
1794
1795         if (!(mode->type & DRM_MODE_TYPE_USERDEF)) {
1796                 ret = -EINVAL;
1797                 goto out;
1798         }
1799
1800         if (mode->output_count) {
1801                 ret = -EINVAL;
1802                 goto out;
1803         }
1804
1805         list_for_each_entry(t, &dev->mode_config.usermode_list, head) {
1806                 if (t == mode) {
1807                         list_del(&mode->head);
1808                         drm_mode_destroy(dev, mode);
1809                         ret = 0;
1810                         break;
1811                 }
1812         }
1813
1814 out:
1815         spin_unlock(&dev->mode_config.config_lock);
1816         return ret;
1817 }
1818
1819 /**
1820  * drm_fb_attachmode - Attach a user mode to an output
1821  * @inode: inode from the ioctl
1822  * @filp: file * from the ioctl
1823  * @cmd: cmd from ioctl
1824  * @arg: arg from ioctl
1825  *
1826  * This attaches a user specified mode to an output.
1827  * Called by the user via ioctl.
1828  *
1829  * RETURNS:
1830  * Zero on success, errno on failure.
1831  */
1832 int drm_mode_attachmode(struct inode *inode, struct file *filp,
1833                         unsigned int cmd, unsigned long arg)
1834 {
1835         drm_file_t *priv = filp->private_data;
1836         drm_device_t *dev = priv->head->dev;
1837         struct drm_mode_mode_cmd __user *argp = (void __user *)arg;
1838         struct drm_mode_mode_cmd mode_cmd;
1839         struct drm_output *output;
1840         struct drm_display_mode *mode;
1841         int i, ret = 0;
1842
1843         if (copy_from_user(&mode_cmd, argp, sizeof(mode_cmd)))
1844                 return -EFAULT;
1845
1846         spin_lock(&dev->mode_config.config_lock);
1847
1848         mode = idr_find(&dev->mode_config.crtc_idr, mode_cmd.mode_id);
1849         if (!mode || (mode->mode_id != mode_cmd.mode_id)) {
1850                 ret = -EINVAL;
1851                 goto out;
1852         }
1853
1854         output = idr_find(&dev->mode_config.crtc_idr, mode_cmd.output_id);
1855         if (!output || (output->id != mode_cmd.output_id)) {
1856                 ret = -EINVAL;
1857                 goto out;
1858         }
1859
1860         for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++) {
1861                 if (output->user_mode_ids[i] == 0) {
1862                         output->user_mode_ids[i] = mode->mode_id;
1863                         mode->output_count++;
1864                         break;
1865                 }
1866         }
1867
1868         if (i == DRM_OUTPUT_MAX_UMODES)
1869                 ret = -ENOSPC;
1870
1871 out:
1872         spin_unlock(&dev->mode_config.config_lock);
1873         return ret;
1874 }
1875
1876
1877 /**
1878  * drm_fb_detachmode - Detach a user specified mode from an output
1879  * @inode: inode from the ioctl
1880  * @filp: file * from the ioctl
1881  * @cmd: cmd from ioctl
1882  * @arg: arg from ioctl
1883  *
1884  * Called by the user via ioctl.
1885  *
1886  * RETURNS:
1887  * Zero on success, errno on failure.
1888  */
1889 int drm_mode_detachmode(struct inode *inode, struct file *filp,
1890                         unsigned int cmd, unsigned long arg)
1891 {
1892         drm_file_t *priv = filp->private_data;
1893         drm_device_t *dev = priv->head->dev;
1894         struct drm_mode_mode_cmd __user *argp = (void __user *)arg;
1895         struct drm_mode_mode_cmd mode_cmd;
1896         struct drm_output *output;
1897         struct drm_display_mode *mode;
1898         int i, found = 0, ret = 0;
1899
1900         if (copy_from_user(&mode_cmd, argp, sizeof(mode_cmd)))
1901                 return -EFAULT;
1902
1903         spin_lock(&dev->mode_config.config_lock);
1904
1905         mode = idr_find(&dev->mode_config.crtc_idr, mode_cmd.mode_id);
1906         if (!mode || (mode->mode_id != mode_cmd.mode_id)) {
1907                 ret = -EINVAL;
1908                 goto out;
1909         }
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
1918         for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++) {
1919                 if (output->user_mode_ids[i] == mode->mode_id) {
1920                         output->user_mode_ids[i] = 0;
1921                         mode->output_count--;
1922                         found = 1;
1923                 }
1924         }
1925
1926         if (!found)
1927                 ret = -EINVAL;
1928
1929 out:           
1930         spin_unlock(&dev->mode_config.config_lock);
1931         return ret;
1932 }