2 * Copyright (c) 2006-2007 Intel Corporation
3 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
5 * DRM core CRTC related functions
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.
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
27 * Eric Anholt <eric@anholt.net>
28 * Dave Airlie <airlied@linux.ie>
29 * Jesse Barnes <jesse.barnes@intel.com>
31 #include <linux/list.h>
37 * drm_idr_get - allocate a new identifier
39 * @ptr: object pointer, used to generate unique ID
42 * Process context (either init or calling process). Must take DRM mode_config
43 * lock around IDR allocation.
45 * Create a unique identifier based on @ptr in @dev's identifier space. Used
46 * for tracking modes, CRTCs and outputs.
49 * New unique (relative to other objects in @dev) integer identifier for the
52 int drm_idr_get(struct drm_device *dev, void *ptr)
57 if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
58 DRM_ERROR("Ran out memory getting a mode number\n");
62 spin_lock(&dev->mode_config.config_lock);
64 ret = idr_get_new_above(&dev->mode_config.crtc_idr, ptr, 1, &new_id);
66 spin_unlock(&dev->mode_config.config_lock);
70 spin_unlock(&dev->mode_config.config_lock);
75 * drm_idr_put - free an identifer
80 * Caller must hold DRM mode_config lock.
82 * Free @id from @dev's unique identifier pool.
84 void drm_idr_put(struct drm_device *dev, int id)
86 idr_remove(&dev->mode_config.crtc_idr, id);
90 * drm_framebuffer_create - create a new framebuffer object
94 * Process context (either init or calling process). Must take DRM mode_config
95 * lock around mode_config manipulation.
97 * Creates a new framebuffer objects and adds it to @dev's DRM mode_config.
100 * Pointer to new framebuffer or NULL on error.
102 struct drm_framebuffer *drm_framebuffer_create(drm_device_t *dev)
104 struct drm_framebuffer *fb;
106 spin_lock(&dev->mode_config.config_lock);
107 /* Limit to single framebuffer for now */
108 if (dev->mode_config.num_fb > 1) {
109 spin_unlock(&dev->mode_config.config_lock);
110 DRM_ERROR("Attempt to add multiple framebuffers failed\n");
113 spin_unlock(&dev->mode_config.config_lock);
115 fb = kzalloc(sizeof(struct drm_framebuffer), GFP_KERNEL);
121 fb->id = drm_idr_get(dev, fb);
123 spin_lock(&dev->mode_config.config_lock);
124 dev->mode_config.num_fb++;
125 list_add(&fb->head, &dev->mode_config.fb_list);
126 spin_unlock(&dev->mode_config.config_lock);
130 EXPORT_SYMBOL(drm_framebuffer_create);
133 * drm_framebuffer_destroy - remove a framebuffer object
134 * @fb: framebuffer to remove
137 * Process context (either init or calling process). Must take DRM mode_config
138 * lock around mode_config manipulation.
140 * Scans all the CRTCs in @dev's mode_config. If they're using @fb, removes
141 * it, setting it to NULL.
143 void drm_framebuffer_destroy(struct drm_framebuffer *fb)
145 drm_device_t *dev = fb->dev;
146 struct drm_crtc *crtc;
148 /* remove from any CRTC */
149 spin_lock(&dev->mode_config.config_lock);
150 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
155 drm_idr_put(dev, fb->id);
157 dev->mode_config.num_fb--;
158 spin_unlock(&dev->mode_config.config_lock);
164 * drm_crtc_create - create a new CRTC object
166 * @funcs: callbacks for the new CRTC
169 * Process context (either init or calling process). Must take DRM mode_config
170 * lock around mode_config manipulation.
172 * Creates a new CRTC object and adds it to @dev's mode_config structure.
175 * Pointer to new CRTC object or NULL on error.
177 struct drm_crtc *drm_crtc_create(drm_device_t *dev,
178 const struct drm_crtc_funcs *funcs)
180 struct drm_crtc *crtc;
182 crtc = kzalloc(sizeof(struct drm_crtc), GFP_KERNEL);
189 crtc->id = drm_idr_get(dev, crtc);
191 spin_lock(&dev->mode_config.config_lock);
192 list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
193 dev->mode_config.num_crtc++;
194 spin_unlock(&dev->mode_config.config_lock);
198 EXPORT_SYMBOL(drm_crtc_create);
201 * drm_crtc_destroy - remove a CRTC object
202 * @crtc: CRTC to remove
205 * Process context (either init or calling process). Must take DRM mode_config
206 * lock around mode_config traversal.
208 * Cleanup @crtc. Calls @crtc's cleanup function, then removes @crtc from
209 * its associated DRM device's mode_config. Frees it afterwards.
211 void drm_crtc_destroy(struct drm_crtc *crtc)
213 drm_device_t *dev = crtc->dev;
215 if (crtc->funcs->cleanup)
216 (*crtc->funcs->cleanup)(crtc);
218 spin_lock(&dev->mode_config.config_lock);
219 drm_idr_put(dev, crtc->id);
220 list_del(&crtc->head);
221 dev->mode_config.num_crtc--;
222 spin_unlock(&dev->mode_config.config_lock);
225 EXPORT_SYMBOL(drm_crtc_destroy);
228 * drm_crtc_in_use - check if a given CRTC is in a mode_config
229 * @crtc: CRTC to check
234 * Walk @crtc's DRM device's mode_config and see if it's in use.
237 * True if @crtc is part of the mode_config, false otherwise.
239 bool drm_crtc_in_use(struct drm_crtc *crtc)
241 struct drm_output *output;
242 drm_device_t *dev = crtc->dev;
243 /* FIXME: Locking around list access? */
244 list_for_each_entry(output, &dev->mode_config.output_list, head)
245 if (output->crtc == crtc)
249 EXPORT_SYMBOL(drm_crtc_in_use);
252 * Detailed mode info for a standard 640x480@60Hz monitor
254 static struct drm_display_mode std_mode[] = {
255 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25200, 640, 656,
256 752, 800, 0, 480, 490, 492, 525, 0,
257 V_NHSYNC | V_NVSYNC) }, /* 640x480@60Hz */
261 * drm_crtc_probe_output_modes - get complete set of display modes
263 * @maxX: max width for modes
264 * @maxY: max height for modes
269 * Based on @dev's mode_config layout, scan all the outputs and try to detect
270 * modes on them. Modes will first be added to the output's probed_modes
271 * list, then culled (based on validity and the @maxX, @maxY parameters) and
272 * put into the normal modes list.
274 * Intended to be used either at bootup time or when major configuration
275 * changes have occurred.
277 * FIXME: take into account monitor limits
279 void drm_crtc_probe_output_modes(struct drm_device *dev, int maxX, int maxY)
281 struct drm_output *output;
282 struct drm_display_mode *mode, *t;
284 //if (maxX == 0 || maxY == 0)
287 list_for_each_entry(output, &dev->mode_config.output_list, head) {
289 /* set all modes to the unverified state */
290 list_for_each_entry_safe(mode, t, &output->modes, head)
291 mode->status = MODE_UNVERIFIED;
293 output->status = (*output->funcs->detect)(output);
295 if (output->status == output_status_disconnected) {
296 DRM_DEBUG("%s is disconnected\n", output->name);
297 /* TODO set EDID to NULL */
301 ret = (*output->funcs->get_modes)(output);
304 drm_mode_output_list_update(output);
308 drm_mode_validate_size(dev, &output->modes, maxX,
310 list_for_each_entry_safe(mode, t, &output->modes, head) {
311 if (mode->status == MODE_OK)
312 mode->status = (*output->funcs->mode_valid)(output,mode);
316 drm_mode_prune_invalid(dev, &output->modes, TRUE);
318 if (list_empty(&output->modes)) {
319 struct drm_display_mode *stdmode;
321 DRM_DEBUG("No valid modes on %s\n", output->name);
323 /* Should we do this here ???
324 * When no valid EDID modes are available we end up
325 * here and bailed in the past, now we add a standard
326 * 640x480@60Hz mode and carry on.
328 stdmode = drm_mode_duplicate(dev, &std_mode[0]);
329 drm_mode_probed_add(output, stdmode);
330 drm_mode_list_concat(&output->probed_modes,
333 DRM_DEBUG("Adding standard 640x480 @ 60Hz to %s\n",
337 drm_mode_sort(&output->modes);
339 DRM_DEBUG("Probed modes for %s\n", output->name);
340 list_for_each_entry_safe(mode, t, &output->modes, head) {
341 mode->vrefresh = drm_mode_vrefresh(mode);
343 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
344 drm_mode_debug_printmodeline(dev, mode);
350 * drm_crtc_set_mode - set a mode
351 * @crtc: CRTC to program
359 * Try to set @mode on @crtc. Give @crtc and its associated outputs a chance
360 * to fixup or reject the mode prior to trying to set it.
363 * True if the mode was set successfully, or false otherwise.
365 bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
368 drm_device_t *dev = crtc->dev;
369 struct drm_display_mode *adjusted_mode, saved_mode;
370 int saved_x, saved_y;
371 bool didLock = false;
373 struct drm_output *output;
375 adjusted_mode = drm_mode_duplicate(dev, mode);
377 crtc->enabled = drm_crtc_in_use(crtc);
379 if (!crtc->enabled) {
383 didLock = crtc->funcs->lock(crtc);
385 saved_mode = crtc->mode;
389 /* Update crtc values up front so the driver can rely on them for mode
396 /* XXX short-circuit changes to base location only */
398 /* Pass our mode to the outputs and the CRTC to give them a chance to
399 * adjust it according to limitations or output properties, and also
400 * a chance to reject the mode entirely.
402 list_for_each_entry(output, &dev->mode_config.output_list, head) {
404 if (output->crtc != crtc)
407 if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) {
412 if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) {
416 /* Prepare the outputs and CRTCs before setting the mode. */
417 list_for_each_entry(output, &dev->mode_config.output_list, head) {
419 if (output->crtc != crtc)
422 /* Disable the output as the first thing we do. */
423 output->funcs->prepare(output);
426 crtc->funcs->prepare(crtc);
428 /* Set up the DPLL and any output state that needs to adjust or depend
431 crtc->funcs->mode_set(crtc, mode, adjusted_mode, x, y);
432 list_for_each_entry(output, &dev->mode_config.output_list, head) {
433 if (output->crtc == crtc)
434 output->funcs->mode_set(output, mode, adjusted_mode);
437 /* Now, enable the clocks, plane, pipe, and outputs that we set up. */
438 crtc->funcs->commit(crtc);
439 list_for_each_entry(output, &dev->mode_config.output_list, head) {
440 if (output->crtc == crtc) {
441 output->funcs->commit(output);
442 #if 0 // TODO def RANDR_12_INTERFACE
443 if (output->randr_output)
444 RRPostPendingProperties (output->randr_output);
449 /* XXX free adjustedmode */
450 drm_mode_destroy(dev, adjusted_mode);
453 // if (scrn->pScreen)
454 // drm_crtc_set_screen_sub_pixel_order(dev);
460 crtc->mode = saved_mode;
464 crtc->funcs->unlock (crtc);
470 * drm_set_desired_modes - set a good mode on every CRTC & output
476 * Each CRTC may have a desired mode associated with it. This routine simply
477 * walks @dev's mode_config and sets the desired mode on every CRTC. Intended
478 * for use at startup time.
481 * True if modes were set, false otherwise.
483 bool drm_set_desired_modes(struct drm_device *dev)
485 struct drm_crtc *crtc;
486 struct drm_output *output, *list_output;
488 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
491 list_for_each_entry(list_output, &dev->mode_config.output_list,
493 if (list_output->crtc == crtc) {
494 output = list_output;
498 /* Skip disabled crtcs */
500 DRM_DEBUG("skipping disabled crtc\n");
504 if (!drm_crtc_set_mode(crtc, crtc->desired_mode,
505 crtc->desired_x, crtc->desired_y))
509 drm_disable_unused_functions(dev);
512 EXPORT_SYMBOL(drm_set_desired_modes);
515 * drm_disable_unused_functions - disable unused objects
521 * If an output or CRTC isn't part of @dev's mode_config, it can be disabled
522 * by calling its dpms function, which should power it off.
524 void drm_disable_unused_functions(struct drm_device *dev)
526 struct drm_output *output;
527 struct drm_crtc *crtc;
529 list_for_each_entry(output, &dev->mode_config.output_list, head) {
531 (*output->funcs->dpms)(output, DPMSModeOff);
534 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
536 crtc->funcs->dpms(crtc, DPMSModeOff);
541 * drm_mode_probed_add - add a mode to the specified output's probed mode list
542 * @output: output the new mode
546 * Process context (either init or calling process). Must take @output's
547 * mode_lock around mode list manipulation.
549 * Add @mode to @output's mode list for later use.
551 void drm_mode_probed_add(struct drm_output *output,
552 struct drm_display_mode *mode)
554 spin_lock(&output->modes_lock);
555 list_add(&mode->head, &output->probed_modes);
556 spin_unlock(&output->modes_lock);
558 EXPORT_SYMBOL(drm_mode_probed_add);
561 * drm_mode_remove - remove and free a mode
562 * @output: output list to modify
563 * @mode: mode to remove
566 * Process context (either init or calling process). Must take @output's
567 * mode_lock around mode list manipulation.
569 * Remove @mode from @output's mode list, then free it.
571 void drm_mode_remove(struct drm_output *output, struct drm_display_mode *mode)
573 spin_lock(&output->modes_lock);
574 list_del(&mode->head);
575 spin_unlock(&output->modes_lock);
578 EXPORT_SYMBOL(drm_mode_remove);
581 * drm_output_create - create a new output
583 * @funcs: callbacks for this output
584 * @name: user visible name of the output
587 * Process context (either init or calling process). Must take @dev's
588 * mode_config lock around mode list manipulation.
590 * Creates a new drm_output structure and adds it to @dev's mode_config
594 * Pointer to the new output or NULL on error.
596 struct drm_output *drm_output_create(drm_device_t *dev,
597 const struct drm_output_funcs *funcs,
600 struct drm_output *output = NULL;
602 output = kzalloc(sizeof(struct drm_output), GFP_KERNEL);
607 output->funcs = funcs;
608 output->id = drm_idr_get(dev, output);
610 strncpy(output->name, name, DRM_OUTPUT_LEN);
611 output->name[DRM_OUTPUT_LEN - 1] = 0;
612 output->subpixel_order = SubPixelUnknown;
613 INIT_LIST_HEAD(&output->probed_modes);
614 INIT_LIST_HEAD(&output->modes);
615 spin_lock_init(&output->modes_lock);
617 /* output_set_monitor(output)? */
618 /* check for output_ignored(output)? */
620 spin_lock(&dev->mode_config.config_lock);
621 list_add_tail(&output->head, &dev->mode_config.output_list);
622 dev->mode_config.num_output++;
624 spin_unlock(&dev->mode_config.config_lock);
629 EXPORT_SYMBOL(drm_output_create);
632 * drm_output_destroy - remove an output
633 * @output: output to remove
636 * Process context (either init or calling process). Must take @dev's
637 * mode_config lock around mode list manipulation. Caller must hold
638 * modes lock? (FIXME)
640 * Call @output's cleanup function, then remove the output from the DRM
641 * mode_config after freeing @output's modes.
643 void drm_output_destroy(struct drm_output *output)
645 struct drm_device *dev = output->dev;
646 struct drm_display_mode *mode, *t;
648 if (*output->funcs->cleanup)
649 (*output->funcs->cleanup)(output);
651 list_for_each_entry_safe(mode, t, &output->probed_modes, head)
652 drm_mode_remove(output, mode);
654 list_for_each_entry_safe(mode, t, &output->modes, head)
655 drm_mode_remove(output, mode);
657 spin_lock(&dev->mode_config.config_lock);
658 drm_idr_put(dev, output->id);
659 list_del(&output->head);
660 spin_unlock(&dev->mode_config.config_lock);
663 EXPORT_SYMBOL(drm_output_destroy);
666 * drm_output_rename - rename an output
667 * @output: output to rename
668 * @name: new user visible name
673 * Simply stuff a new name into @output's name field, based on @name.
676 * True if the name was changed, false otherwise.
678 bool drm_output_rename(struct drm_output *output, const char *name)
683 strncpy(output->name, name, DRM_OUTPUT_LEN);
684 output->name[DRM_OUTPUT_LEN - 1] = 0;
686 DRM_DEBUG("Changed name to %s\n", output->name);
687 // drm_output_set_monitor(output);
688 // if (drm_output_ignored(output))
693 EXPORT_SYMBOL(drm_output_rename);
696 * drm_mode_create - create a new display mode
702 * Create a new drm_display_mode, give it an ID, and return it.
705 * Pointer to new mode on success, NULL on error.
707 struct drm_display_mode *drm_mode_create(struct drm_device *dev)
709 struct drm_display_mode *nmode;
711 nmode = kzalloc(sizeof(struct drm_display_mode), GFP_KERNEL);
715 nmode->mode_id = drm_idr_get(dev, nmode);
720 * drm_mode_destroy - remove a mode
722 * @mode: mode to remove
727 * Free @mode's unique identifier, then free it.
729 void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
731 drm_idr_put(dev, mode->mode_id);
737 * drm_mode_config_init - initialize DRM mode_configuration structure
741 * None, should happen single threaded at init time.
743 * Initialize @dev's mode_config structure, used for tracking the graphics
744 * configuration of @dev.
746 void drm_mode_config_init(drm_device_t *dev)
748 spin_lock_init(&dev->mode_config.config_lock);
749 INIT_LIST_HEAD(&dev->mode_config.fb_list);
750 INIT_LIST_HEAD(&dev->mode_config.crtc_list);
751 INIT_LIST_HEAD(&dev->mode_config.output_list);
752 idr_init(&dev->mode_config.crtc_idr);
754 EXPORT_SYMBOL(drm_mode_config_init);
757 * drm_get_buffer_object - find the buffer object for a given handle
759 * @bo: pointer to caller's buffer_object pointer
760 * @handle: handle to lookup
763 * Must take @dev's struct_mutex to protect buffer object lookup.
765 * Given @handle, lookup the buffer object in @dev and put it in the caller's
769 * Zero on success, -EINVAL if the handle couldn't be found.
771 static int drm_get_buffer_object(drm_device_t *dev, struct drm_buffer_object **bo, unsigned long handle)
773 drm_user_object_t *uo;
774 drm_hash_item_t *hash;
779 mutex_lock(&dev->struct_mutex);
780 ret = drm_ht_find_item(&dev->object_hash, handle, &hash);
782 DRM_ERROR("Couldn't find handle.\n");
787 uo = drm_hash_entry(hash, drm_user_object_t, hash);
788 if (uo->type != drm_buffer_type) {
793 *bo = drm_user_object_entry(uo, drm_buffer_object_t, base);
796 mutex_unlock(&dev->struct_mutex);
801 * drm_setup_output - setup an output structure
802 * @output: output to setup
803 * @crtc: CRTC this output belongs to
804 * @mode: desired mode for this output
809 * Setup @output with the parameters given, with its initial coordinates set
812 static void drm_setup_output(struct drm_output *output, struct drm_crtc *crtc,
813 struct drm_display_mode *mode)
816 output->crtc->desired_mode = mode;
817 output->initial_x = 0;
818 output->initial_y = 0;
822 * drm_initial_config - setup a sane initial output configuration
824 * @can_grow: this configuration is growable
827 * Must take various locks. (FIXME)
829 * Scan the CRTCs and outputs and try to put together an initial setup.
830 * At the moment, this is a cloned configuration across all heads with
831 * a new framebuffer object as the backing store.
833 * FIXME: return value and better initial config.
836 * Zero if everything went ok, nonzero otherwise.
838 bool drm_initial_config(drm_device_t *dev, bool can_grow)
840 /* do a hardcoded initial configuration here */
841 struct drm_crtc *crtc, *vga_crtc = NULL, *tmds_crtc = NULL,
843 struct drm_output *output;
844 struct drm_framebuffer *fb;
845 drm_buffer_object_t *fbo;
846 unsigned long size, bytes_per_pixel;
848 fb = drm_framebuffer_create(dev);
850 DRM_ERROR("failed to allocate fb.\n");
854 /* bind both CRTCs to this fb */
855 /* only initialise one crtc to enabled state */
856 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
879 drm_crtc_probe_output_modes(dev, 2048, 2048);
881 /* hard bind the CRTCS */
883 /* bind analog output to one crtc */
884 list_for_each_entry(output, &dev->mode_config.output_list, head) {
885 struct drm_display_mode *des_mode = NULL;
887 if (list_empty(&output->modes))
890 /* Get the first preferred moded */
891 list_for_each_entry(des_mode, &output->modes, head) {
892 if (des_mode->flags & DRM_MODE_TYPE_PREFERRED)
899 if (!strncmp(output->name, "VGA", 3)) {
900 DRM_DEBUG("VGA preferred mode: %s\n", des_mode->name);
901 drm_setup_output(output, vga_crtc, des_mode);
902 } else if (!strncmp(output->name, "TMDS", 4)) {
903 DRM_DEBUG("TMDS preferred mode: %s\n", des_mode->name);
904 drm_setup_output(output, tmds_crtc, des_mode);
905 } else if (!strncmp(output->name, "LVDS", 3)) {
906 DRM_DEBUG("LVDS preferred mode: %s\n", des_mode->name);
907 drm_setup_output(output, lvds_crtc, des_mode);
911 /* FB config is max of above desired resolutions */
912 /* FIXME: per-output FBs/CRTCs */
913 if (des_mode->hdisplay > fb->width) {
914 fb->width = des_mode->hdisplay;
915 fb->pitch = fb->width;
917 if (des_mode->vdisplay > fb->height)
918 fb->height = des_mode->vdisplay;
921 /* FIXME: multiple depths */
923 fb->bits_per_pixel = bytes_per_pixel * 8;
924 fb->depth = bytes_per_pixel * 8;
925 size = fb->width * fb->height * bytes_per_pixel;
926 drm_buffer_object_create(dev, size, drm_bo_type_kernel,
927 DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
928 DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE,
931 DRM_DEBUG("allocated %dx%d fb: 0x%08lx, bo %p\n", fb->width,
932 fb->height, fbo->offset, fbo);
933 fb->offset = fbo->offset;
935 drmfb_probe(dev, fb);
939 EXPORT_SYMBOL(drm_initial_config);
942 * drm_mode_config_cleanup - free up DRM mode_config info
948 * Free up all the outputs and CRTCs associated with this DRM device, then
949 * free up the framebuffers and associated buffer objects.
951 * FIXME: cleanup any dangling user buffer objects too
953 void drm_mode_config_cleanup(drm_device_t *dev)
955 struct drm_output *output, *ot;
956 struct drm_crtc *crtc, *ct;
957 struct drm_framebuffer *fb, *fbt;
958 list_for_each_entry_safe(output, ot, &dev->mode_config.output_list, head) {
959 drm_output_destroy(output);
962 list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
963 drm_crtc_destroy(crtc);
966 list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
967 drmfb_remove(dev, fb);
968 /* If this FB was the kernel one, free it */
969 if (fb->bo->type == drm_bo_type_kernel) {
970 mutex_lock(&dev->struct_mutex);
971 drm_bo_usage_deref_locked(fb->bo);
972 mutex_unlock(&dev->struct_mutex);
974 drm_framebuffer_destroy(fb);
977 EXPORT_SYMBOL(drm_mode_config_cleanup);
980 * drm_crtc_set_config - set a new config from userspace
981 * @crtc: CRTC to setup
982 * @crtc_info: user provided configuration
983 * @new_mode: new mode to set
984 * @output_set: set of outputs for the new config
985 * @fb: new framebuffer
990 * Setup a new configuration, provided by the user in @crtc_info, and enable
996 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)
998 drm_device_t *dev = crtc->dev;
999 struct drm_crtc **save_crtcs, *new_crtc;
1000 bool save_enabled = crtc->enabled;
1002 struct drm_output *output;
1005 save_crtcs = kzalloc(dev->mode_config.num_crtc * sizeof(struct drm_crtc *), GFP_KERNEL);
1012 if (crtc_info->x != crtc->x || crtc_info->y != crtc->y)
1015 if (new_mode && (crtc->mode.mode_id != new_mode->mode_id))
1018 list_for_each_entry(output, &dev->mode_config.output_list, head) {
1019 save_crtcs[count++] = output->crtc;
1021 if (output->crtc == crtc)
1024 new_crtc = output->crtc;
1026 for (ro = 0; ro < crtc_info->count_outputs; ro++) {
1027 if (output_set[ro] == output)
1030 if (new_crtc != output->crtc) {
1032 output->crtc = new_crtc;
1038 crtc->enabled = (new_mode != NULL);
1039 if (new_mode != NULL) {
1040 DRM_DEBUG("attempting to set mode from userspace\n");
1041 drm_mode_debug_printmodeline(dev, new_mode);
1042 if (!drm_crtc_set_mode(crtc, new_mode, crtc_info->x,
1044 crtc->enabled = save_enabled;
1046 list_for_each_entry(output, &dev->mode_config.output_list, head)
1047 output->crtc = save_crtcs[count++];
1051 crtc->desired_x = crtc_info->x;
1052 crtc->desired_y = crtc_info->y;
1053 crtc->desired_mode = new_mode;
1055 drm_disable_unused_functions(dev);
1062 * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
1063 * @out: drm_mode_modeinfo struct to return to the user
1064 * @in: drm_display_mode to use
1069 * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
1072 void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out, struct drm_display_mode *in)
1075 out->id = in->mode_id;
1076 out->clock = in->clock;
1077 out->hdisplay = in->hdisplay;
1078 out->hsync_start = in->hsync_start;
1079 out->hsync_end = in->hsync_end;
1080 out->htotal = in->htotal;
1081 out->hskew = in->hskew;
1082 out->vdisplay = in->vdisplay;
1083 out->vsync_start = in->vsync_start;
1084 out->vsync_end = in->vsync_end;
1085 out->vtotal = in->vtotal;
1086 out->vscan = in->vscan;
1087 out->vrefresh = in->vrefresh;
1088 out->flags = in->flags;
1089 strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
1090 out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1095 * drm_mode_getresources - get graphics configuration
1096 * @inode: inode from the ioctl
1097 * @filp: file * from the ioctl
1098 * @cmd: cmd from ioctl
1099 * @arg: arg from ioctl
1104 * Construct a set of configuration description structures and return
1105 * them to the user, including CRTC, output and framebuffer configuration.
1107 * Called by the user via ioctl.
1110 * Zero on success, errno on failure.
1112 int drm_mode_getresources(struct inode *inode, struct file *filp,
1113 unsigned int cmd, unsigned long arg)
1115 drm_file_t *priv = filp->private_data;
1116 drm_device_t *dev = priv->head->dev;
1117 struct drm_mode_card_res __user *argp = (void __user *)arg;
1118 struct drm_mode_card_res card_res;
1119 struct list_head *lh;
1120 struct drm_framebuffer *fb;
1121 struct drm_output *output;
1122 struct drm_crtc *crtc;
1123 struct drm_mode_modeinfo u_mode;
1124 struct drm_display_mode *mode;
1127 int output_count = 0;
1132 memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
1134 list_for_each(lh, &dev->mode_config.fb_list)
1137 list_for_each(lh, &dev->mode_config.crtc_list)
1140 list_for_each_entry(output, &dev->mode_config.output_list,
1143 list_for_each(lh, &output->modes)
1147 if (copy_from_user(&card_res, argp, sizeof(card_res)))
1150 if (card_res.count_modes == 0) {
1151 DRM_DEBUG("probing modes %dx%d\n", dev->mode_config.max_width, dev->mode_config.max_height);
1152 drm_crtc_probe_output_modes(dev, dev->mode_config.max_width, dev->mode_config.max_height);
1154 list_for_each_entry(output, &dev->mode_config.output_list, head) {
1155 list_for_each(lh, &output->modes)
1160 /* handle this in 4 parts */
1162 if (card_res.count_fbs >= fb_count) {
1164 list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
1165 if (put_user(fb->id, &card_res.fb_id[copied++])) {
1171 card_res.count_fbs = fb_count;
1174 if (card_res.count_crtcs >= crtc_count) {
1176 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head){
1177 DRM_DEBUG("CRTC ID is %d\n", crtc->id);
1178 if (put_user(crtc->id, &card_res.crtc_id[copied++])) {
1184 card_res.count_crtcs = crtc_count;
1188 if (card_res.count_outputs >= output_count) {
1190 list_for_each_entry(output, &dev->mode_config.output_list,
1192 DRM_DEBUG("OUTPUT ID is %d\n", output->id);
1193 if (put_user(output->id, &card_res.output_id[copied++])) {
1199 card_res.count_outputs = output_count;
1202 if (card_res.count_modes >= mode_count) {
1204 list_for_each_entry(output, &dev->mode_config.output_list,
1206 list_for_each_entry(mode, &output->modes, head) {
1207 drm_crtc_convert_to_umode(&u_mode, mode);
1208 if (copy_to_user(&card_res.modes[copied++], &u_mode, sizeof(struct drm_mode_modeinfo))) {
1215 card_res.count_modes = mode_count;
1218 DRM_DEBUG("Counted %d %d %d\n", card_res.count_crtcs,
1219 card_res.count_outputs,
1220 card_res.count_modes);
1222 if (copy_to_user(argp, &card_res, sizeof(card_res)))
1229 * drm_mode_getcrtc - get CRTC configuration
1230 * @inode: inode from the ioctl
1231 * @filp: file * from the ioctl
1232 * @cmd: cmd from ioctl
1233 * @arg: arg from ioctl
1238 * Construct a CRTC configuration structure to return to the user.
1240 * Called by the user via ioctl.
1243 * Zero on success, errno on failure.
1245 int drm_mode_getcrtc(struct inode *inode, struct file *filp,
1246 unsigned int cmd, unsigned long arg)
1248 drm_file_t *priv = filp->private_data;
1249 drm_device_t *dev = priv->head->dev;
1250 struct drm_mode_crtc __user *argp = (void __user *)arg;
1251 struct drm_mode_crtc crtc_resp;
1252 struct drm_crtc *crtc;
1253 struct drm_output *output;
1257 if (copy_from_user(&crtc_resp, argp, sizeof(crtc_resp)))
1260 crtc = idr_find(&dev->mode_config.crtc_idr, crtc_resp.crtc_id);
1261 if (!crtc || (crtc->id != crtc_resp.crtc_id))
1263 crtc_resp.x = crtc->x;
1264 crtc_resp.y = crtc->y;
1265 crtc_resp.fb_id = 1;
1267 crtc_resp.outputs = 0;
1268 if (crtc->enabled) {
1270 crtc_resp.mode = crtc->mode.mode_id;
1272 list_for_each_entry(output, &dev->mode_config.output_list, head) {
1273 if (output->crtc == crtc)
1274 crtc_resp.outputs |= 1 << (ocount++);
1280 if (copy_to_user(argp, &crtc_resp, sizeof(crtc_resp)))
1287 * drm_mode_getoutput - get output configuration
1288 * @inode: inode from the ioctl
1289 * @filp: file * from the ioctl
1290 * @cmd: cmd from ioctl
1291 * @arg: arg from ioctl
1296 * Construct a output configuration structure to return to the user.
1298 * Called by the user via ioctl.
1301 * Zero on success, errno on failure.
1303 int drm_mode_getoutput(struct inode *inode, struct file *filp,
1304 unsigned int cmd, unsigned long arg)
1306 drm_file_t *priv = filp->private_data;
1307 drm_device_t *dev = priv->head->dev;
1308 struct drm_mode_get_output __user *argp = (void __user *)arg;
1309 struct drm_mode_get_output out_resp;
1310 struct drm_output *output;
1311 struct drm_display_mode *mode;
1316 if (copy_from_user(&out_resp, argp, sizeof(out_resp)))
1319 DRM_DEBUG("output id %d:\n", out_resp.output);
1320 output= idr_find(&dev->mode_config.crtc_idr, out_resp.output);
1321 if (!output || (output->id != out_resp.output))
1324 list_for_each_entry(mode, &output->modes, head)
1327 strncpy(out_resp.name, output->name, DRM_OUTPUT_NAME_LEN);
1328 out_resp.name[DRM_OUTPUT_NAME_LEN-1] = 0;
1330 out_resp.mm_width = output->mm_width;
1331 out_resp.mm_height = output->mm_height;
1332 out_resp.subpixel = output->subpixel_order;
1333 out_resp.connection = output->status;
1335 out_resp.crtc = output->crtc->id;
1339 if ((out_resp.count_modes >= mode_count) && mode_count) {
1341 list_for_each_entry(mode, &output->modes, head) {
1342 if (put_user(mode->mode_id, &out_resp.modes[copied++])) {
1348 out_resp.count_modes = mode_count;
1351 if (copy_to_user(argp, &out_resp, sizeof(out_resp)))
1358 * drm_mode_setcrtc - set CRTC configuration
1359 * @inode: inode from the ioctl
1360 * @filp: file * from the ioctl
1361 * @cmd: cmd from ioctl
1362 * @arg: arg from ioctl
1367 * Build a new CRTC configuration based on user request.
1369 * Called by the user via ioctl.
1372 * Zero on success, errno on failure.
1374 int drm_mode_setcrtc(struct inode *inode, struct file *filp,
1375 unsigned int cmd, unsigned long arg)
1377 drm_file_t *priv = filp->private_data;
1378 drm_device_t *dev = priv->head->dev;
1379 struct drm_mode_crtc __user *argp = (void __user *)arg;
1380 struct drm_mode_crtc crtc_req;
1381 struct drm_crtc *crtc;
1382 struct drm_output **output_set = NULL, *output;
1383 struct drm_display_mode *mode;
1384 struct drm_framebuffer *fb = NULL;
1388 if (copy_from_user(&crtc_req, argp, sizeof(crtc_req)))
1391 crtc = idr_find(&dev->mode_config.crtc_idr, crtc_req.crtc_id);
1392 if (!crtc || (crtc->id != crtc_req.crtc_id)) {
1393 DRM_DEBUG("Unknown CRTC ID %d\n", crtc_req.crtc_id);
1397 if (crtc_req.mode) {
1399 /* if we have a mode we need a framebuffer */
1400 if (crtc_req.fb_id) {
1401 fb = idr_find(&dev->mode_config.crtc_idr, crtc_req.fb_id);
1402 if (!fb || (fb->id != crtc_req.fb_id)) {
1403 DRM_DEBUG("Unknown FB ID%d\n", crtc_req.fb_id);
1407 mode = idr_find(&dev->mode_config.crtc_idr, crtc_req.mode);
1408 if (!mode || (mode->mode_id != crtc_req.mode)) {
1409 struct drm_output *output;
1411 list_for_each_entry(output, &dev->mode_config.output_list, head) {
1412 list_for_each_entry(mode, &output->modes, head) {
1413 drm_mode_debug_printmodeline(dev, mode);
1417 DRM_DEBUG("Unknown mode id %d, %p\n", crtc_req.mode, mode);
1423 if (crtc_req.count_outputs == 0 && mode) {
1424 DRM_DEBUG("Count outputs is 0 but mode set\n");
1428 if (crtc_req.count_outputs > 0 && !mode && !fb) {
1429 DRM_DEBUG("Count outputs is %d but no mode or fb set\n", crtc_req.count_outputs);
1433 if (crtc_req.count_outputs > 0) {
1435 output_set = kmalloc(crtc_req.count_outputs * sizeof(struct drm_output *), GFP_KERNEL);
1439 for (i = 0; i < crtc_req.count_outputs; i++) {
1440 if (get_user(out_id, &crtc_req.set_outputs[i]))
1443 output = idr_find(&dev->mode_config.crtc_idr, out_id);
1444 if (!output || (out_id != output->id)) {
1445 DRM_DEBUG("Output id %d unknown\n", out_id);
1449 output_set[i] = output;
1453 retcode = drm_crtc_set_config(crtc, &crtc_req, mode, output_set, fb);
1458 * drm_mode_addfb - add an FB to the graphics configuration
1459 * @inode: inode from the ioctl
1460 * @filp: file * from the ioctl
1461 * @cmd: cmd from ioctl
1462 * @arg: arg from ioctl
1467 * Add a new FB to the specified CRTC, given a user request.
1469 * Called by the user via ioctl.
1472 * Zero on success, errno on failure.
1474 int drm_mode_addfb(struct inode *inode, struct file *filp,
1475 unsigned int cmd, unsigned long arg)
1477 struct drm_file *priv = filp->private_data;
1478 struct drm_device *dev = priv->head->dev;
1479 struct drm_mode_fb_cmd __user *argp = (void __user *)arg;
1480 struct drm_mode_fb_cmd r;
1481 struct drm_mode_config *config = &dev->mode_config;
1482 struct drm_framebuffer *fb;
1483 struct drm_buffer_object *bo;
1486 if (copy_from_user(&r, argp, sizeof(r)))
1489 if ((config->min_width > r.width) || (r.width > config->max_width)) {
1490 DRM_ERROR("mode new framebuffer width not within limits\n");
1493 if ((config->min_height > r.height) || (r.height > config->max_height)) {
1494 DRM_ERROR("mode new framebuffer height not within limits\n");
1498 /* TODO check limits are okay */
1499 ret = drm_get_buffer_object(dev, &bo, r.handle);
1503 /* TODO check buffer is sufficently large */
1504 /* TODO setup destructor callback */
1506 fb = drm_framebuffer_create(dev);
1510 fb->width = r.width;
1511 fb->height = r.height;
1512 fb->pitch = r.pitch;
1513 fb->bits_per_pixel = r.bpp;
1514 fb->depth = r.depth;
1515 fb->offset = bo->offset;
1518 r.buffer_id = fb->id;
1520 list_add(&fb->filp_head, &priv->fbs);
1521 /* bind the fb to the crtc for now */
1523 struct drm_crtc *crtc;
1524 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
1528 if (copy_to_user(argp, &r, sizeof(r)))
1531 drmfb_probe(dev, fb);
1536 * drm_mode_rmfb - remove an FB from the configuration
1537 * @inode: inode from the ioctl
1538 * @filp: file * from the ioctl
1539 * @cmd: cmd from ioctl
1540 * @arg: arg from ioctl
1545 * Remove the FB specified by the user.
1547 * Called by the user via ioctl.
1550 * Zero on success, errno on failure.
1552 int drm_mode_rmfb(struct inode *inode, struct file *filp,
1553 unsigned int cmd, unsigned long arg)
1555 drm_file_t *priv = filp->private_data;
1556 drm_device_t *dev = priv->head->dev;
1557 struct drm_framebuffer *fb = 0;
1560 fb = idr_find(&dev->mode_config.crtc_idr, id);
1561 /* TODO check that we realy get a framebuffer back. */
1562 if (!fb || (id != fb->id)) {
1563 DRM_ERROR("mode invalid framebuffer id\n");
1567 drmfb_remove(dev, fb);
1568 /* TODO check if we own the buffer */
1569 /* TODO release all crtc connected to the framebuffer */
1570 /* bind the fb to the crtc for now */
1571 /* TODO unhock the destructor from the buffer object */
1573 drm_framebuffer_destroy(fb);
1579 * drm_mode_getfb - get FB info
1580 * @inode: inode from the ioctl
1581 * @filp: file * from the ioctl
1582 * @cmd: cmd from ioctl
1583 * @arg: arg from ioctl
1588 * Lookup the FB given its ID and return info about it.
1590 * Called by the user via ioctl.
1593 * Zero on success, errno on failure.
1595 int drm_mode_getfb(struct inode *inode, struct file *filp,
1596 unsigned int cmd, unsigned long arg)
1598 drm_file_t *priv = filp->private_data;
1599 drm_device_t *dev = priv->head->dev;
1600 struct drm_mode_fb_cmd __user *argp = (void __user *)arg;
1601 struct drm_mode_fb_cmd r;
1602 struct drm_framebuffer *fb;
1604 if (copy_from_user(&r, argp, sizeof(r)))
1607 fb = idr_find(&dev->mode_config.crtc_idr, r.buffer_id);
1608 if (!fb || (r.buffer_id != fb->id)) {
1609 DRM_ERROR("invalid framebuffer id\n");
1613 r.height = fb->height;
1614 r.width = fb->width;
1615 r.depth = fb->depth;
1616 r.bpp = fb->bits_per_pixel;
1617 r.handle = fb->bo->base.hash.key;
1618 r.pitch = fb->pitch;
1620 if (copy_to_user(argp, &r, sizeof(r)))
1627 * drm_fb_release - remove and free the FBs on this file
1628 * @filp: file * from the ioctl
1633 * Destroy all the FBs associated with @filp.
1635 * Called by the user via ioctl.
1638 * Zero on success, errno on failure.
1640 void drm_fb_release(struct file *filp)
1642 drm_file_t *priv = filp->private_data;
1643 drm_device_t *dev = priv->head->dev;
1644 struct drm_framebuffer *fb, *tfb;
1646 list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
1647 list_del(&fb->filp_head);
1648 drmfb_remove(dev, fb);
1649 drm_framebuffer_destroy(fb);