[go: nahoru, domu]

drm_crtc.c revision ad2563c2e42fc67b0976aeb70e9f3faf1c1196e8
1/*
2 * Copyright (c) 2006-2008 Intel Corporation
3 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
4 * Copyright (c) 2008 Red Hat Inc.
5 *
6 * DRM core CRTC related functions
7 *
8 * Permission to use, copy, modify, distribute, and sell this software and its
9 * documentation for any purpose is hereby granted without fee, provided that
10 * the above copyright notice appear in all copies and that both that copyright
11 * notice and this permission notice appear in supporting documentation, and
12 * that the name of the copyright holders not be used in advertising or
13 * publicity pertaining to distribution of the software without specific,
14 * written prior permission.  The copyright holders make no representations
15 * about the suitability of this software for any purpose.  It is provided "as
16 * is" without express or implied warranty.
17 *
18 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
20 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
21 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
23 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24 * OF THIS SOFTWARE.
25 *
26 * Authors:
27 *      Keith Packard
28 *	Eric Anholt <eric@anholt.net>
29 *      Dave Airlie <airlied@linux.ie>
30 *      Jesse Barnes <jesse.barnes@intel.com>
31 */
32#include <linux/list.h>
33#include "drm.h"
34#include "drmP.h"
35#include "drm_crtc.h"
36
37struct drm_prop_enum_list {
38	int type;
39	char *name;
40};
41
42/* Avoid boilerplate.  I'm tired of typing. */
43#define DRM_ENUM_NAME_FN(fnname, list)				\
44	char *fnname(int val)					\
45	{							\
46		int i;						\
47		for (i = 0; i < ARRAY_SIZE(list); i++) {	\
48			if (list[i].type == val)		\
49				return list[i].name;		\
50		}						\
51		return "(unknown)";				\
52	}
53
54/*
55 * Global properties
56 */
57static struct drm_prop_enum_list drm_dpms_enum_list[] =
58{	{ DRM_MODE_DPMS_ON, "On" },
59	{ DRM_MODE_DPMS_STANDBY, "Standby" },
60	{ DRM_MODE_DPMS_SUSPEND, "Suspend" },
61	{ DRM_MODE_DPMS_OFF, "Off" }
62};
63
64DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
65
66/*
67 * Optional properties
68 */
69static struct drm_prop_enum_list drm_scaling_mode_enum_list[] =
70{
71	{ DRM_MODE_SCALE_NON_GPU, "Non-GPU" },
72	{ DRM_MODE_SCALE_FULLSCREEN, "Fullscreen" },
73	{ DRM_MODE_SCALE_NO_SCALE, "No scale" },
74	{ DRM_MODE_SCALE_ASPECT, "Aspect" },
75};
76
77static struct drm_prop_enum_list drm_dithering_mode_enum_list[] =
78{
79	{ DRM_MODE_DITHERING_OFF, "Off" },
80	{ DRM_MODE_DITHERING_ON, "On" },
81};
82
83/*
84 * Non-global properties, but "required" for certain connectors.
85 */
86static struct drm_prop_enum_list drm_dvi_i_select_enum_list[] =
87{
88	{ DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
89	{ DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
90	{ DRM_MODE_SUBCONNECTOR_DVIA,      "DVI-A"     }, /* DVI-I  */
91};
92
93DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list)
94
95static struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] =
96{
97	{ DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I and TV-out */
98	{ DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
99	{ DRM_MODE_SUBCONNECTOR_DVIA,      "DVI-A"     }, /* DVI-I  */
100};
101
102DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name,
103		 drm_dvi_i_subconnector_enum_list)
104
105static struct drm_prop_enum_list drm_tv_select_enum_list[] =
106{
107	{ DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
108	{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
109	{ DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */
110	{ DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
111};
112
113DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)
114
115static struct drm_prop_enum_list drm_tv_subconnector_enum_list[] =
116{
117	{ DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I and TV-out */
118	{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
119	{ DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */
120	{ DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
121};
122
123DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
124		 drm_tv_subconnector_enum_list)
125
126struct drm_conn_prop_enum_list {
127	int type;
128	char *name;
129	int count;
130};
131
132/*
133 * Connector and encoder types.
134 */
135static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
136{	{ DRM_MODE_CONNECTOR_Unknown, "Unknown", 0 },
137	{ DRM_MODE_CONNECTOR_VGA, "VGA", 0 },
138	{ DRM_MODE_CONNECTOR_DVII, "DVI-I", 0 },
139	{ DRM_MODE_CONNECTOR_DVID, "DVI-D", 0 },
140	{ DRM_MODE_CONNECTOR_DVIA, "DVI-A", 0 },
141	{ DRM_MODE_CONNECTOR_Composite, "Composite", 0 },
142	{ DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 },
143	{ DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 },
144	{ DRM_MODE_CONNECTOR_Component, "Component", 0 },
145	{ DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN", 0 },
146	{ DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 },
147	{ DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 },
148	{ DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 },
149};
150
151static struct drm_prop_enum_list drm_encoder_enum_list[] =
152{	{ DRM_MODE_ENCODER_NONE, "None" },
153	{ DRM_MODE_ENCODER_DAC, "DAC" },
154	{ DRM_MODE_ENCODER_TMDS, "TMDS" },
155	{ DRM_MODE_ENCODER_LVDS, "LVDS" },
156	{ DRM_MODE_ENCODER_TVDAC, "TV" },
157};
158
159char *drm_get_encoder_name(struct drm_encoder *encoder)
160{
161	static char buf[32];
162
163	snprintf(buf, 32, "%s-%d",
164		 drm_encoder_enum_list[encoder->encoder_type].name,
165		 encoder->base.id);
166	return buf;
167}
168
169char *drm_get_connector_name(struct drm_connector *connector)
170{
171	static char buf[32];
172
173	snprintf(buf, 32, "%s-%d",
174		 drm_connector_enum_list[connector->connector_type].name,
175		 connector->connector_type_id);
176	return buf;
177}
178EXPORT_SYMBOL(drm_get_connector_name);
179
180char *drm_get_connector_status_name(enum drm_connector_status status)
181{
182	if (status == connector_status_connected)
183		return "connected";
184	else if (status == connector_status_disconnected)
185		return "disconnected";
186	else
187		return "unknown";
188}
189
190/**
191 * drm_mode_object_get - allocate a new identifier
192 * @dev: DRM device
193 * @ptr: object pointer, used to generate unique ID
194 * @type: object type
195 *
196 * LOCKING:
197 *
198 * Create a unique identifier based on @ptr in @dev's identifier space.  Used
199 * for tracking modes, CRTCs and connectors.
200 *
201 * RETURNS:
202 * New unique (relative to other objects in @dev) integer identifier for the
203 * object.
204 */
205static int drm_mode_object_get(struct drm_device *dev,
206			       struct drm_mode_object *obj, uint32_t obj_type)
207{
208	int new_id = 0;
209	int ret;
210
211again:
212	if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
213		DRM_ERROR("Ran out memory getting a mode number\n");
214		return -EINVAL;
215	}
216
217	mutex_lock(&dev->mode_config.idr_mutex);
218	ret = idr_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id);
219	mutex_unlock(&dev->mode_config.idr_mutex);
220	if (ret == -EAGAIN)
221		goto again;
222
223	obj->id = new_id;
224	obj->type = obj_type;
225	return 0;
226}
227
228/**
229 * drm_mode_object_put - free an identifer
230 * @dev: DRM device
231 * @id: ID to free
232 *
233 * LOCKING:
234 * Caller must hold DRM mode_config lock.
235 *
236 * Free @id from @dev's unique identifier pool.
237 */
238static void drm_mode_object_put(struct drm_device *dev,
239				struct drm_mode_object *object)
240{
241	mutex_lock(&dev->mode_config.idr_mutex);
242	idr_remove(&dev->mode_config.crtc_idr, object->id);
243	mutex_unlock(&dev->mode_config.idr_mutex);
244}
245
246void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type)
247{
248	struct drm_mode_object *obj = NULL;
249
250	mutex_lock(&dev->mode_config.idr_mutex);
251	obj = idr_find(&dev->mode_config.crtc_idr, id);
252	if (!obj || (obj->type != type) || (obj->id != id))
253		obj = NULL;
254	mutex_unlock(&dev->mode_config.idr_mutex);
255
256	return obj;
257}
258EXPORT_SYMBOL(drm_mode_object_find);
259
260/**
261 * drm_crtc_from_fb - find the CRTC structure associated with an fb
262 * @dev: DRM device
263 * @fb: framebuffer in question
264 *
265 * LOCKING:
266 * Caller must hold mode_config lock.
267 *
268 * Find CRTC in the mode_config structure that matches @fb.
269 *
270 * RETURNS:
271 * Pointer to the CRTC or NULL if it wasn't found.
272 */
273struct drm_crtc *drm_crtc_from_fb(struct drm_device *dev,
274				  struct drm_framebuffer *fb)
275{
276	struct drm_crtc *crtc;
277
278	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
279		if (crtc->fb == fb)
280			return crtc;
281	}
282	return NULL;
283}
284
285/**
286 * drm_framebuffer_init - initialize a framebuffer
287 * @dev: DRM device
288 *
289 * LOCKING:
290 * Caller must hold mode config lock.
291 *
292 * Allocates an ID for the framebuffer's parent mode object, sets its mode
293 * functions & device file and adds it to the master fd list.
294 *
295 * RETURNS:
296 * Zero on success, error code on falure.
297 */
298int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
299			 const struct drm_framebuffer_funcs *funcs)
300{
301	int ret;
302
303	ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
304	if (ret) {
305		return ret;
306	}
307
308	fb->dev = dev;
309	fb->funcs = funcs;
310	dev->mode_config.num_fb++;
311	list_add(&fb->head, &dev->mode_config.fb_list);
312
313	return 0;
314}
315EXPORT_SYMBOL(drm_framebuffer_init);
316
317/**
318 * drm_framebuffer_cleanup - remove a framebuffer object
319 * @fb: framebuffer to remove
320 *
321 * LOCKING:
322 * Caller must hold mode config lock.
323 *
324 * Scans all the CRTCs in @dev's mode_config.  If they're using @fb, removes
325 * it, setting it to NULL.
326 */
327void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
328{
329	struct drm_device *dev = fb->dev;
330	struct drm_crtc *crtc;
331
332	/* remove from any CRTC */
333	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
334		if (crtc->fb == fb)
335			crtc->fb = NULL;
336	}
337
338	drm_mode_object_put(dev, &fb->base);
339	list_del(&fb->head);
340	dev->mode_config.num_fb--;
341}
342EXPORT_SYMBOL(drm_framebuffer_cleanup);
343
344/**
345 * drm_crtc_init - Initialise a new CRTC object
346 * @dev: DRM device
347 * @crtc: CRTC object to init
348 * @funcs: callbacks for the new CRTC
349 *
350 * LOCKING:
351 * Caller must hold mode config lock.
352 *
353 * Inits a new object created as base part of an driver crtc object.
354 */
355void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
356		   const struct drm_crtc_funcs *funcs)
357{
358	crtc->dev = dev;
359	crtc->funcs = funcs;
360
361	mutex_lock(&dev->mode_config.mutex);
362	drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
363
364	list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
365	dev->mode_config.num_crtc++;
366	mutex_unlock(&dev->mode_config.mutex);
367}
368EXPORT_SYMBOL(drm_crtc_init);
369
370/**
371 * drm_crtc_cleanup - Cleans up the core crtc usage.
372 * @crtc: CRTC to cleanup
373 *
374 * LOCKING:
375 * Caller must hold mode config lock.
376 *
377 * Cleanup @crtc. Removes from drm modesetting space
378 * does NOT free object, caller does that.
379 */
380void drm_crtc_cleanup(struct drm_crtc *crtc)
381{
382	struct drm_device *dev = crtc->dev;
383
384	if (crtc->gamma_store) {
385		kfree(crtc->gamma_store);
386		crtc->gamma_store = NULL;
387	}
388
389	drm_mode_object_put(dev, &crtc->base);
390	list_del(&crtc->head);
391	dev->mode_config.num_crtc--;
392}
393EXPORT_SYMBOL(drm_crtc_cleanup);
394
395/**
396 * drm_mode_probed_add - add a mode to a connector's probed mode list
397 * @connector: connector the new mode
398 * @mode: mode data
399 *
400 * LOCKING:
401 * Caller must hold mode config lock.
402 *
403 * Add @mode to @connector's mode list for later use.
404 */
405void drm_mode_probed_add(struct drm_connector *connector,
406			 struct drm_display_mode *mode)
407{
408	list_add(&mode->head, &connector->probed_modes);
409}
410EXPORT_SYMBOL(drm_mode_probed_add);
411
412/**
413 * drm_mode_remove - remove and free a mode
414 * @connector: connector list to modify
415 * @mode: mode to remove
416 *
417 * LOCKING:
418 * Caller must hold mode config lock.
419 *
420 * Remove @mode from @connector's mode list, then free it.
421 */
422void drm_mode_remove(struct drm_connector *connector,
423		     struct drm_display_mode *mode)
424{
425	list_del(&mode->head);
426	kfree(mode);
427}
428EXPORT_SYMBOL(drm_mode_remove);
429
430/**
431 * drm_connector_init - Init a preallocated connector
432 * @dev: DRM device
433 * @connector: the connector to init
434 * @funcs: callbacks for this connector
435 * @name: user visible name of the connector
436 *
437 * LOCKING:
438 * Caller must hold @dev's mode_config lock.
439 *
440 * Initialises a preallocated connector. Connectors should be
441 * subclassed as part of driver connector objects.
442 */
443void drm_connector_init(struct drm_device *dev,
444		     struct drm_connector *connector,
445		     const struct drm_connector_funcs *funcs,
446		     int connector_type)
447{
448	mutex_lock(&dev->mode_config.mutex);
449
450	connector->dev = dev;
451	connector->funcs = funcs;
452	drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR);
453	connector->connector_type = connector_type;
454	connector->connector_type_id =
455		++drm_connector_enum_list[connector_type].count; /* TODO */
456	INIT_LIST_HEAD(&connector->user_modes);
457	INIT_LIST_HEAD(&connector->probed_modes);
458	INIT_LIST_HEAD(&connector->modes);
459	connector->edid_blob_ptr = NULL;
460
461	list_add_tail(&connector->head, &dev->mode_config.connector_list);
462	dev->mode_config.num_connector++;
463
464	drm_connector_attach_property(connector,
465				      dev->mode_config.edid_property, 0);
466
467	drm_connector_attach_property(connector,
468				      dev->mode_config.dpms_property, 0);
469
470	mutex_unlock(&dev->mode_config.mutex);
471}
472EXPORT_SYMBOL(drm_connector_init);
473
474/**
475 * drm_connector_cleanup - cleans up an initialised connector
476 * @connector: connector to cleanup
477 *
478 * LOCKING:
479 * Caller must hold @dev's mode_config lock.
480 *
481 * Cleans up the connector but doesn't free the object.
482 */
483void drm_connector_cleanup(struct drm_connector *connector)
484{
485	struct drm_device *dev = connector->dev;
486	struct drm_display_mode *mode, *t;
487
488	list_for_each_entry_safe(mode, t, &connector->probed_modes, head)
489		drm_mode_remove(connector, mode);
490
491	list_for_each_entry_safe(mode, t, &connector->modes, head)
492		drm_mode_remove(connector, mode);
493
494	list_for_each_entry_safe(mode, t, &connector->user_modes, head)
495		drm_mode_remove(connector, mode);
496
497	mutex_lock(&dev->mode_config.mutex);
498	drm_mode_object_put(dev, &connector->base);
499	list_del(&connector->head);
500	mutex_unlock(&dev->mode_config.mutex);
501}
502EXPORT_SYMBOL(drm_connector_cleanup);
503
504void drm_encoder_init(struct drm_device *dev,
505		      struct drm_encoder *encoder,
506		      const struct drm_encoder_funcs *funcs,
507		      int encoder_type)
508{
509	mutex_lock(&dev->mode_config.mutex);
510
511	encoder->dev = dev;
512
513	drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
514	encoder->encoder_type = encoder_type;
515	encoder->funcs = funcs;
516
517	list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
518	dev->mode_config.num_encoder++;
519
520	mutex_unlock(&dev->mode_config.mutex);
521}
522EXPORT_SYMBOL(drm_encoder_init);
523
524void drm_encoder_cleanup(struct drm_encoder *encoder)
525{
526	struct drm_device *dev = encoder->dev;
527	mutex_lock(&dev->mode_config.mutex);
528	drm_mode_object_put(dev, &encoder->base);
529	list_del(&encoder->head);
530	mutex_unlock(&dev->mode_config.mutex);
531}
532EXPORT_SYMBOL(drm_encoder_cleanup);
533
534/**
535 * drm_mode_create - create a new display mode
536 * @dev: DRM device
537 *
538 * LOCKING:
539 * Caller must hold DRM mode_config lock.
540 *
541 * Create a new drm_display_mode, give it an ID, and return it.
542 *
543 * RETURNS:
544 * Pointer to new mode on success, NULL on error.
545 */
546struct drm_display_mode *drm_mode_create(struct drm_device *dev)
547{
548	struct drm_display_mode *nmode;
549
550	nmode = kzalloc(sizeof(struct drm_display_mode), GFP_KERNEL);
551	if (!nmode)
552		return NULL;
553
554	drm_mode_object_get(dev, &nmode->base, DRM_MODE_OBJECT_MODE);
555	return nmode;
556}
557EXPORT_SYMBOL(drm_mode_create);
558
559/**
560 * drm_mode_destroy - remove a mode
561 * @dev: DRM device
562 * @mode: mode to remove
563 *
564 * LOCKING:
565 * Caller must hold mode config lock.
566 *
567 * Free @mode's unique identifier, then free it.
568 */
569void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
570{
571	drm_mode_object_put(dev, &mode->base);
572
573	kfree(mode);
574}
575EXPORT_SYMBOL(drm_mode_destroy);
576
577static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
578{
579	struct drm_property *edid;
580	struct drm_property *dpms;
581	int i;
582
583	/*
584	 * Standard properties (apply to all connectors)
585	 */
586	edid = drm_property_create(dev, DRM_MODE_PROP_BLOB |
587				   DRM_MODE_PROP_IMMUTABLE,
588				   "EDID", 0);
589	dev->mode_config.edid_property = edid;
590
591	dpms = drm_property_create(dev, DRM_MODE_PROP_ENUM,
592				   "DPMS", ARRAY_SIZE(drm_dpms_enum_list));
593	for (i = 0; i < ARRAY_SIZE(drm_dpms_enum_list); i++)
594		drm_property_add_enum(dpms, i, drm_dpms_enum_list[i].type,
595				      drm_dpms_enum_list[i].name);
596	dev->mode_config.dpms_property = dpms;
597
598	return 0;
599}
600
601/**
602 * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties
603 * @dev: DRM device
604 *
605 * Called by a driver the first time a DVI-I connector is made.
606 */
607int drm_mode_create_dvi_i_properties(struct drm_device *dev)
608{
609	struct drm_property *dvi_i_selector;
610	struct drm_property *dvi_i_subconnector;
611	int i;
612
613	if (dev->mode_config.dvi_i_select_subconnector_property)
614		return 0;
615
616	dvi_i_selector =
617		drm_property_create(dev, DRM_MODE_PROP_ENUM,
618				    "select subconnector",
619				    ARRAY_SIZE(drm_dvi_i_select_enum_list));
620	for (i = 0; i < ARRAY_SIZE(drm_dvi_i_select_enum_list); i++)
621		drm_property_add_enum(dvi_i_selector, i,
622				      drm_dvi_i_select_enum_list[i].type,
623				      drm_dvi_i_select_enum_list[i].name);
624	dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector;
625
626	dvi_i_subconnector =
627		drm_property_create(dev, DRM_MODE_PROP_ENUM |
628				    DRM_MODE_PROP_IMMUTABLE,
629				    "subconnector",
630				    ARRAY_SIZE(drm_dvi_i_subconnector_enum_list));
631	for (i = 0; i < ARRAY_SIZE(drm_dvi_i_subconnector_enum_list); i++)
632		drm_property_add_enum(dvi_i_subconnector, i,
633				      drm_dvi_i_subconnector_enum_list[i].type,
634				      drm_dvi_i_subconnector_enum_list[i].name);
635	dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector;
636
637	return 0;
638}
639EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);
640
641/**
642 * drm_create_tv_properties - create TV specific connector properties
643 * @dev: DRM device
644 * @num_modes: number of different TV formats (modes) supported
645 * @modes: array of pointers to strings containing name of each format
646 *
647 * Called by a driver's TV initialization routine, this function creates
648 * the TV specific connector properties for a given device.  Caller is
649 * responsible for allocating a list of format names and passing them to
650 * this routine.
651 */
652int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
653				  char *modes[])
654{
655	struct drm_property *tv_selector;
656	struct drm_property *tv_subconnector;
657	int i;
658
659	if (dev->mode_config.tv_select_subconnector_property)
660		return 0;
661
662	/*
663	 * Basic connector properties
664	 */
665	tv_selector = drm_property_create(dev, DRM_MODE_PROP_ENUM,
666					  "select subconnector",
667					  ARRAY_SIZE(drm_tv_select_enum_list));
668	for (i = 0; i < ARRAY_SIZE(drm_tv_select_enum_list); i++)
669		drm_property_add_enum(tv_selector, i,
670				      drm_tv_select_enum_list[i].type,
671				      drm_tv_select_enum_list[i].name);
672	dev->mode_config.tv_select_subconnector_property = tv_selector;
673
674	tv_subconnector =
675		drm_property_create(dev, DRM_MODE_PROP_ENUM |
676				    DRM_MODE_PROP_IMMUTABLE, "subconnector",
677				    ARRAY_SIZE(drm_tv_subconnector_enum_list));
678	for (i = 0; i < ARRAY_SIZE(drm_tv_subconnector_enum_list); i++)
679		drm_property_add_enum(tv_subconnector, i,
680				      drm_tv_subconnector_enum_list[i].type,
681				      drm_tv_subconnector_enum_list[i].name);
682	dev->mode_config.tv_subconnector_property = tv_subconnector;
683
684	/*
685	 * Other, TV specific properties: margins & TV modes.
686	 */
687	dev->mode_config.tv_left_margin_property =
688		drm_property_create(dev, DRM_MODE_PROP_RANGE,
689				    "left margin", 2);
690	dev->mode_config.tv_left_margin_property->values[0] = 0;
691	dev->mode_config.tv_left_margin_property->values[1] = 100;
692
693	dev->mode_config.tv_right_margin_property =
694		drm_property_create(dev, DRM_MODE_PROP_RANGE,
695				    "right margin", 2);
696	dev->mode_config.tv_right_margin_property->values[0] = 0;
697	dev->mode_config.tv_right_margin_property->values[1] = 100;
698
699	dev->mode_config.tv_top_margin_property =
700		drm_property_create(dev, DRM_MODE_PROP_RANGE,
701				    "top margin", 2);
702	dev->mode_config.tv_top_margin_property->values[0] = 0;
703	dev->mode_config.tv_top_margin_property->values[1] = 100;
704
705	dev->mode_config.tv_bottom_margin_property =
706		drm_property_create(dev, DRM_MODE_PROP_RANGE,
707				    "bottom margin", 2);
708	dev->mode_config.tv_bottom_margin_property->values[0] = 0;
709	dev->mode_config.tv_bottom_margin_property->values[1] = 100;
710
711	dev->mode_config.tv_mode_property =
712		drm_property_create(dev, DRM_MODE_PROP_ENUM,
713				    "mode", num_modes);
714	for (i = 0; i < num_modes; i++)
715		drm_property_add_enum(dev->mode_config.tv_mode_property, i,
716				      i, modes[i]);
717
718	return 0;
719}
720EXPORT_SYMBOL(drm_mode_create_tv_properties);
721
722/**
723 * drm_mode_create_scaling_mode_property - create scaling mode property
724 * @dev: DRM device
725 *
726 * Called by a driver the first time it's needed, must be attached to desired
727 * connectors.
728 */
729int drm_mode_create_scaling_mode_property(struct drm_device *dev)
730{
731	struct drm_property *scaling_mode;
732	int i;
733
734	if (dev->mode_config.scaling_mode_property)
735		return 0;
736
737	scaling_mode =
738		drm_property_create(dev, DRM_MODE_PROP_ENUM, "scaling mode",
739				    ARRAY_SIZE(drm_scaling_mode_enum_list));
740	for (i = 0; i < ARRAY_SIZE(drm_scaling_mode_enum_list); i++)
741		drm_property_add_enum(scaling_mode, i,
742				      drm_scaling_mode_enum_list[i].type,
743				      drm_scaling_mode_enum_list[i].name);
744
745	dev->mode_config.scaling_mode_property = scaling_mode;
746
747	return 0;
748}
749EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
750
751/**
752 * drm_mode_create_dithering_property - create dithering property
753 * @dev: DRM device
754 *
755 * Called by a driver the first time it's needed, must be attached to desired
756 * connectors.
757 */
758int drm_mode_create_dithering_property(struct drm_device *dev)
759{
760	struct drm_property *dithering_mode;
761	int i;
762
763	if (dev->mode_config.dithering_mode_property)
764		return 0;
765
766	dithering_mode =
767		drm_property_create(dev, DRM_MODE_PROP_ENUM, "dithering",
768				    ARRAY_SIZE(drm_dithering_mode_enum_list));
769	for (i = 0; i < ARRAY_SIZE(drm_dithering_mode_enum_list); i++)
770		drm_property_add_enum(dithering_mode, i,
771				      drm_dithering_mode_enum_list[i].type,
772				      drm_dithering_mode_enum_list[i].name);
773	dev->mode_config.dithering_mode_property = dithering_mode;
774
775	return 0;
776}
777EXPORT_SYMBOL(drm_mode_create_dithering_property);
778
779/**
780 * drm_mode_config_init - initialize DRM mode_configuration structure
781 * @dev: DRM device
782 *
783 * LOCKING:
784 * None, should happen single threaded at init time.
785 *
786 * Initialize @dev's mode_config structure, used for tracking the graphics
787 * configuration of @dev.
788 */
789void drm_mode_config_init(struct drm_device *dev)
790{
791	mutex_init(&dev->mode_config.mutex);
792	mutex_init(&dev->mode_config.idr_mutex);
793	INIT_LIST_HEAD(&dev->mode_config.fb_list);
794	INIT_LIST_HEAD(&dev->mode_config.fb_kernel_list);
795	INIT_LIST_HEAD(&dev->mode_config.crtc_list);
796	INIT_LIST_HEAD(&dev->mode_config.connector_list);
797	INIT_LIST_HEAD(&dev->mode_config.encoder_list);
798	INIT_LIST_HEAD(&dev->mode_config.property_list);
799	INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
800	idr_init(&dev->mode_config.crtc_idr);
801
802	mutex_lock(&dev->mode_config.mutex);
803	drm_mode_create_standard_connector_properties(dev);
804	mutex_unlock(&dev->mode_config.mutex);
805
806	/* Just to be sure */
807	dev->mode_config.num_fb = 0;
808	dev->mode_config.num_connector = 0;
809	dev->mode_config.num_crtc = 0;
810	dev->mode_config.num_encoder = 0;
811}
812EXPORT_SYMBOL(drm_mode_config_init);
813
814int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
815{
816	uint32_t total_objects = 0;
817
818	total_objects += dev->mode_config.num_crtc;
819	total_objects += dev->mode_config.num_connector;
820	total_objects += dev->mode_config.num_encoder;
821
822	if (total_objects == 0)
823		return -EINVAL;
824
825	group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
826	if (!group->id_list)
827		return -ENOMEM;
828
829	group->num_crtcs = 0;
830	group->num_connectors = 0;
831	group->num_encoders = 0;
832	return 0;
833}
834
835int drm_mode_group_init_legacy_group(struct drm_device *dev,
836				     struct drm_mode_group *group)
837{
838	struct drm_crtc *crtc;
839	struct drm_encoder *encoder;
840	struct drm_connector *connector;
841	int ret;
842
843	if ((ret = drm_mode_group_init(dev, group)))
844		return ret;
845
846	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
847		group->id_list[group->num_crtcs++] = crtc->base.id;
848
849	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
850		group->id_list[group->num_crtcs + group->num_encoders++] =
851		encoder->base.id;
852
853	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
854		group->id_list[group->num_crtcs + group->num_encoders +
855			       group->num_connectors++] = connector->base.id;
856
857	return 0;
858}
859
860/**
861 * drm_mode_config_cleanup - free up DRM mode_config info
862 * @dev: DRM device
863 *
864 * LOCKING:
865 * Caller must hold mode config lock.
866 *
867 * Free up all the connectors and CRTCs associated with this DRM device, then
868 * free up the framebuffers and associated buffer objects.
869 *
870 * FIXME: cleanup any dangling user buffer objects too
871 */
872void drm_mode_config_cleanup(struct drm_device *dev)
873{
874	struct drm_connector *connector, *ot;
875	struct drm_crtc *crtc, *ct;
876	struct drm_encoder *encoder, *enct;
877	struct drm_framebuffer *fb, *fbt;
878	struct drm_property *property, *pt;
879
880	list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
881				 head) {
882		encoder->funcs->destroy(encoder);
883	}
884
885	list_for_each_entry_safe(connector, ot,
886				 &dev->mode_config.connector_list, head) {
887		connector->funcs->destroy(connector);
888	}
889
890	list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
891				 head) {
892		drm_property_destroy(dev, property);
893	}
894
895	list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
896		fb->funcs->destroy(fb);
897	}
898
899	list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
900		crtc->funcs->destroy(crtc);
901	}
902
903}
904EXPORT_SYMBOL(drm_mode_config_cleanup);
905
906/**
907 * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
908 * @out: drm_mode_modeinfo struct to return to the user
909 * @in: drm_display_mode to use
910 *
911 * LOCKING:
912 * None.
913 *
914 * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
915 * the user.
916 */
917void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
918			       struct drm_display_mode *in)
919{
920	out->clock = in->clock;
921	out->hdisplay = in->hdisplay;
922	out->hsync_start = in->hsync_start;
923	out->hsync_end = in->hsync_end;
924	out->htotal = in->htotal;
925	out->hskew = in->hskew;
926	out->vdisplay = in->vdisplay;
927	out->vsync_start = in->vsync_start;
928	out->vsync_end = in->vsync_end;
929	out->vtotal = in->vtotal;
930	out->vscan = in->vscan;
931	out->vrefresh = in->vrefresh;
932	out->flags = in->flags;
933	out->type = in->type;
934	strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
935	out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
936}
937
938/**
939 * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode
940 * @out: drm_display_mode to return to the user
941 * @in: drm_mode_modeinfo to use
942 *
943 * LOCKING:
944 * None.
945 *
946 * Convert a drm_mode_modeinfo into a drm_display_mode structure to return to
947 * the caller.
948 */
949void drm_crtc_convert_umode(struct drm_display_mode *out,
950			    struct drm_mode_modeinfo *in)
951{
952	out->clock = in->clock;
953	out->hdisplay = in->hdisplay;
954	out->hsync_start = in->hsync_start;
955	out->hsync_end = in->hsync_end;
956	out->htotal = in->htotal;
957	out->hskew = in->hskew;
958	out->vdisplay = in->vdisplay;
959	out->vsync_start = in->vsync_start;
960	out->vsync_end = in->vsync_end;
961	out->vtotal = in->vtotal;
962	out->vscan = in->vscan;
963	out->vrefresh = in->vrefresh;
964	out->flags = in->flags;
965	out->type = in->type;
966	strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
967	out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
968}
969
970/**
971 * drm_mode_getresources - get graphics configuration
972 * @inode: inode from the ioctl
973 * @filp: file * from the ioctl
974 * @cmd: cmd from ioctl
975 * @arg: arg from ioctl
976 *
977 * LOCKING:
978 * Takes mode config lock.
979 *
980 * Construct a set of configuration description structures and return
981 * them to the user, including CRTC, connector and framebuffer configuration.
982 *
983 * Called by the user via ioctl.
984 *
985 * RETURNS:
986 * Zero on success, errno on failure.
987 */
988int drm_mode_getresources(struct drm_device *dev, void *data,
989			  struct drm_file *file_priv)
990{
991	struct drm_mode_card_res *card_res = data;
992	struct list_head *lh;
993	struct drm_framebuffer *fb;
994	struct drm_connector *connector;
995	struct drm_crtc *crtc;
996	struct drm_encoder *encoder;
997	int ret = 0;
998	int connector_count = 0;
999	int crtc_count = 0;
1000	int fb_count = 0;
1001	int encoder_count = 0;
1002	int copied = 0, i;
1003	uint32_t __user *fb_id;
1004	uint32_t __user *crtc_id;
1005	uint32_t __user *connector_id;
1006	uint32_t __user *encoder_id;
1007	struct drm_mode_group *mode_group;
1008
1009	mutex_lock(&dev->mode_config.mutex);
1010
1011	/*
1012	 * For the non-control nodes we need to limit the list of resources
1013	 * by IDs in the group list for this node
1014	 */
1015	list_for_each(lh, &file_priv->fbs)
1016		fb_count++;
1017
1018	mode_group = &file_priv->master->minor->mode_group;
1019	if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1020
1021		list_for_each(lh, &dev->mode_config.crtc_list)
1022			crtc_count++;
1023
1024		list_for_each(lh, &dev->mode_config.connector_list)
1025			connector_count++;
1026
1027		list_for_each(lh, &dev->mode_config.encoder_list)
1028			encoder_count++;
1029	} else {
1030
1031		crtc_count = mode_group->num_crtcs;
1032		connector_count = mode_group->num_connectors;
1033		encoder_count = mode_group->num_encoders;
1034	}
1035
1036	card_res->max_height = dev->mode_config.max_height;
1037	card_res->min_height = dev->mode_config.min_height;
1038	card_res->max_width = dev->mode_config.max_width;
1039	card_res->min_width = dev->mode_config.min_width;
1040
1041	/* handle this in 4 parts */
1042	/* FBs */
1043	if (card_res->count_fbs >= fb_count) {
1044		copied = 0;
1045		fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr;
1046		list_for_each_entry(fb, &file_priv->fbs, head) {
1047			if (put_user(fb->base.id, fb_id + copied)) {
1048				ret = -EFAULT;
1049				goto out;
1050			}
1051			copied++;
1052		}
1053	}
1054	card_res->count_fbs = fb_count;
1055
1056	/* CRTCs */
1057	if (card_res->count_crtcs >= crtc_count) {
1058		copied = 0;
1059		crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr;
1060		if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1061			list_for_each_entry(crtc, &dev->mode_config.crtc_list,
1062					    head) {
1063				DRM_DEBUG("CRTC ID is %d\n", crtc->base.id);
1064				if (put_user(crtc->base.id, crtc_id + copied)) {
1065					ret = -EFAULT;
1066					goto out;
1067				}
1068				copied++;
1069			}
1070		} else {
1071			for (i = 0; i < mode_group->num_crtcs; i++) {
1072				if (put_user(mode_group->id_list[i],
1073					     crtc_id + copied)) {
1074					ret = -EFAULT;
1075					goto out;
1076				}
1077				copied++;
1078			}
1079		}
1080	}
1081	card_res->count_crtcs = crtc_count;
1082
1083	/* Encoders */
1084	if (card_res->count_encoders >= encoder_count) {
1085		copied = 0;
1086		encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr;
1087		if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1088			list_for_each_entry(encoder,
1089					    &dev->mode_config.encoder_list,
1090					    head) {
1091				DRM_DEBUG("ENCODER ID is %d\n",
1092					  encoder->base.id);
1093				if (put_user(encoder->base.id, encoder_id +
1094					     copied)) {
1095					ret = -EFAULT;
1096					goto out;
1097				}
1098				copied++;
1099			}
1100		} else {
1101			for (i = mode_group->num_crtcs; i < mode_group->num_crtcs + mode_group->num_encoders; i++) {
1102				if (put_user(mode_group->id_list[i],
1103					     encoder_id + copied)) {
1104					ret = -EFAULT;
1105					goto out;
1106				}
1107				copied++;
1108			}
1109
1110		}
1111	}
1112	card_res->count_encoders = encoder_count;
1113
1114	/* Connectors */
1115	if (card_res->count_connectors >= connector_count) {
1116		copied = 0;
1117		connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr;
1118		if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1119			list_for_each_entry(connector,
1120					    &dev->mode_config.connector_list,
1121					    head) {
1122				DRM_DEBUG("CONNECTOR ID is %d\n",
1123					  connector->base.id);
1124				if (put_user(connector->base.id,
1125					     connector_id + copied)) {
1126					ret = -EFAULT;
1127					goto out;
1128				}
1129				copied++;
1130			}
1131		} else {
1132			int start = mode_group->num_crtcs +
1133				mode_group->num_encoders;
1134			for (i = start; i < start + mode_group->num_connectors; i++) {
1135				if (put_user(mode_group->id_list[i],
1136					     connector_id + copied)) {
1137					ret = -EFAULT;
1138					goto out;
1139				}
1140				copied++;
1141			}
1142		}
1143	}
1144	card_res->count_connectors = connector_count;
1145
1146	DRM_DEBUG("Counted %d %d %d\n", card_res->count_crtcs,
1147		  card_res->count_connectors, card_res->count_encoders);
1148
1149out:
1150	mutex_unlock(&dev->mode_config.mutex);
1151	return ret;
1152}
1153
1154/**
1155 * drm_mode_getcrtc - get CRTC configuration
1156 * @inode: inode from the ioctl
1157 * @filp: file * from the ioctl
1158 * @cmd: cmd from ioctl
1159 * @arg: arg from ioctl
1160 *
1161 * LOCKING:
1162 * Caller? (FIXME)
1163 *
1164 * Construct a CRTC configuration structure to return to the user.
1165 *
1166 * Called by the user via ioctl.
1167 *
1168 * RETURNS:
1169 * Zero on success, errno on failure.
1170 */
1171int drm_mode_getcrtc(struct drm_device *dev,
1172		     void *data, struct drm_file *file_priv)
1173{
1174	struct drm_mode_crtc *crtc_resp = data;
1175	struct drm_crtc *crtc;
1176	struct drm_mode_object *obj;
1177	int ret = 0;
1178
1179	mutex_lock(&dev->mode_config.mutex);
1180
1181	obj = drm_mode_object_find(dev, crtc_resp->crtc_id,
1182				   DRM_MODE_OBJECT_CRTC);
1183	if (!obj) {
1184		ret = -EINVAL;
1185		goto out;
1186	}
1187	crtc = obj_to_crtc(obj);
1188
1189	crtc_resp->x = crtc->x;
1190	crtc_resp->y = crtc->y;
1191	crtc_resp->gamma_size = crtc->gamma_size;
1192	if (crtc->fb)
1193		crtc_resp->fb_id = crtc->fb->base.id;
1194	else
1195		crtc_resp->fb_id = 0;
1196
1197	if (crtc->enabled) {
1198
1199		drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode);
1200		crtc_resp->mode_valid = 1;
1201
1202	} else {
1203		crtc_resp->mode_valid = 0;
1204	}
1205
1206out:
1207	mutex_unlock(&dev->mode_config.mutex);
1208	return ret;
1209}
1210
1211/**
1212 * drm_mode_getconnector - get connector configuration
1213 * @inode: inode from the ioctl
1214 * @filp: file * from the ioctl
1215 * @cmd: cmd from ioctl
1216 * @arg: arg from ioctl
1217 *
1218 * LOCKING:
1219 * Caller? (FIXME)
1220 *
1221 * Construct a connector configuration structure to return to the user.
1222 *
1223 * Called by the user via ioctl.
1224 *
1225 * RETURNS:
1226 * Zero on success, errno on failure.
1227 */
1228int drm_mode_getconnector(struct drm_device *dev, void *data,
1229			  struct drm_file *file_priv)
1230{
1231	struct drm_mode_get_connector *out_resp = data;
1232	struct drm_mode_object *obj;
1233	struct drm_connector *connector;
1234	struct drm_display_mode *mode;
1235	int mode_count = 0;
1236	int props_count = 0;
1237	int encoders_count = 0;
1238	int ret = 0;
1239	int copied = 0;
1240	int i;
1241	struct drm_mode_modeinfo u_mode;
1242	struct drm_mode_modeinfo __user *mode_ptr;
1243	uint32_t __user *prop_ptr;
1244	uint64_t __user *prop_values;
1245	uint32_t __user *encoder_ptr;
1246
1247	memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
1248
1249	DRM_DEBUG("connector id %d:\n", out_resp->connector_id);
1250
1251	mutex_lock(&dev->mode_config.mutex);
1252
1253	obj = drm_mode_object_find(dev, out_resp->connector_id,
1254				   DRM_MODE_OBJECT_CONNECTOR);
1255	if (!obj) {
1256		ret = -EINVAL;
1257		goto out;
1258	}
1259	connector = obj_to_connector(obj);
1260
1261	for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
1262		if (connector->property_ids[i] != 0) {
1263			props_count++;
1264		}
1265	}
1266
1267	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1268		if (connector->encoder_ids[i] != 0) {
1269			encoders_count++;
1270		}
1271	}
1272
1273	if (out_resp->count_modes == 0) {
1274		connector->funcs->fill_modes(connector,
1275					     dev->mode_config.max_width,
1276					     dev->mode_config.max_height);
1277	}
1278
1279	/* delayed so we get modes regardless of pre-fill_modes state */
1280	list_for_each_entry(mode, &connector->modes, head)
1281		mode_count++;
1282
1283	out_resp->connector_id = connector->base.id;
1284	out_resp->connector_type = connector->connector_type;
1285	out_resp->connector_type_id = connector->connector_type_id;
1286	out_resp->mm_width = connector->display_info.width_mm;
1287	out_resp->mm_height = connector->display_info.height_mm;
1288	out_resp->subpixel = connector->display_info.subpixel_order;
1289	out_resp->connection = connector->status;
1290	if (connector->encoder)
1291		out_resp->encoder_id = connector->encoder->base.id;
1292	else
1293		out_resp->encoder_id = 0;
1294
1295	/*
1296	 * This ioctl is called twice, once to determine how much space is
1297	 * needed, and the 2nd time to fill it.
1298	 */
1299	if ((out_resp->count_modes >= mode_count) && mode_count) {
1300		copied = 0;
1301		mode_ptr = (struct drm_mode_modeinfo *)(unsigned long)out_resp->modes_ptr;
1302		list_for_each_entry(mode, &connector->modes, head) {
1303			drm_crtc_convert_to_umode(&u_mode, mode);
1304			if (copy_to_user(mode_ptr + copied,
1305					 &u_mode, sizeof(u_mode))) {
1306				ret = -EFAULT;
1307				goto out;
1308			}
1309			copied++;
1310		}
1311	}
1312	out_resp->count_modes = mode_count;
1313
1314	if ((out_resp->count_props >= props_count) && props_count) {
1315		copied = 0;
1316		prop_ptr = (uint32_t *)(unsigned long)(out_resp->props_ptr);
1317		prop_values = (uint64_t *)(unsigned long)(out_resp->prop_values_ptr);
1318		for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
1319			if (connector->property_ids[i] != 0) {
1320				if (put_user(connector->property_ids[i],
1321					     prop_ptr + copied)) {
1322					ret = -EFAULT;
1323					goto out;
1324				}
1325
1326				if (put_user(connector->property_values[i],
1327					     prop_values + copied)) {
1328					ret = -EFAULT;
1329					goto out;
1330				}
1331				copied++;
1332			}
1333		}
1334	}
1335	out_resp->count_props = props_count;
1336
1337	if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
1338		copied = 0;
1339		encoder_ptr = (uint32_t *)(unsigned long)(out_resp->encoders_ptr);
1340		for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1341			if (connector->encoder_ids[i] != 0) {
1342				if (put_user(connector->encoder_ids[i],
1343					     encoder_ptr + copied)) {
1344					ret = -EFAULT;
1345					goto out;
1346				}
1347				copied++;
1348			}
1349		}
1350	}
1351	out_resp->count_encoders = encoders_count;
1352
1353out:
1354	mutex_unlock(&dev->mode_config.mutex);
1355	return ret;
1356}
1357
1358int drm_mode_getencoder(struct drm_device *dev, void *data,
1359			struct drm_file *file_priv)
1360{
1361	struct drm_mode_get_encoder *enc_resp = data;
1362	struct drm_mode_object *obj;
1363	struct drm_encoder *encoder;
1364	int ret = 0;
1365
1366	mutex_lock(&dev->mode_config.mutex);
1367	obj = drm_mode_object_find(dev, enc_resp->encoder_id,
1368				   DRM_MODE_OBJECT_ENCODER);
1369	if (!obj) {
1370		ret = -EINVAL;
1371		goto out;
1372	}
1373	encoder = obj_to_encoder(obj);
1374
1375	if (encoder->crtc)
1376		enc_resp->crtc_id = encoder->crtc->base.id;
1377	else
1378		enc_resp->crtc_id = 0;
1379	enc_resp->encoder_type = encoder->encoder_type;
1380	enc_resp->encoder_id = encoder->base.id;
1381	enc_resp->possible_crtcs = encoder->possible_crtcs;
1382	enc_resp->possible_clones = encoder->possible_clones;
1383
1384out:
1385	mutex_unlock(&dev->mode_config.mutex);
1386	return ret;
1387}
1388
1389/**
1390 * drm_mode_setcrtc - set CRTC configuration
1391 * @inode: inode from the ioctl
1392 * @filp: file * from the ioctl
1393 * @cmd: cmd from ioctl
1394 * @arg: arg from ioctl
1395 *
1396 * LOCKING:
1397 * Caller? (FIXME)
1398 *
1399 * Build a new CRTC configuration based on user request.
1400 *
1401 * Called by the user via ioctl.
1402 *
1403 * RETURNS:
1404 * Zero on success, errno on failure.
1405 */
1406int drm_mode_setcrtc(struct drm_device *dev, void *data,
1407		     struct drm_file *file_priv)
1408{
1409	struct drm_mode_config *config = &dev->mode_config;
1410	struct drm_mode_crtc *crtc_req = data;
1411	struct drm_mode_object *obj;
1412	struct drm_crtc *crtc, *crtcfb;
1413	struct drm_connector **connector_set = NULL, *connector;
1414	struct drm_framebuffer *fb = NULL;
1415	struct drm_display_mode *mode = NULL;
1416	struct drm_mode_set set;
1417	uint32_t __user *set_connectors_ptr;
1418	int ret = 0;
1419	int i;
1420
1421	mutex_lock(&dev->mode_config.mutex);
1422	obj = drm_mode_object_find(dev, crtc_req->crtc_id,
1423				   DRM_MODE_OBJECT_CRTC);
1424	if (!obj) {
1425		DRM_DEBUG("Unknown CRTC ID %d\n", crtc_req->crtc_id);
1426		ret = -EINVAL;
1427		goto out;
1428	}
1429	crtc = obj_to_crtc(obj);
1430
1431	if (crtc_req->mode_valid) {
1432		/* If we have a mode we need a framebuffer. */
1433		/* If we pass -1, set the mode with the currently bound fb */
1434		if (crtc_req->fb_id == -1) {
1435			list_for_each_entry(crtcfb,
1436					    &dev->mode_config.crtc_list, head) {
1437				if (crtcfb == crtc) {
1438					DRM_DEBUG("Using current fb for setmode\n");
1439					fb = crtc->fb;
1440				}
1441			}
1442		} else {
1443			obj = drm_mode_object_find(dev, crtc_req->fb_id,
1444						   DRM_MODE_OBJECT_FB);
1445			if (!obj) {
1446				DRM_DEBUG("Unknown FB ID%d\n", crtc_req->fb_id);
1447				ret = -EINVAL;
1448				goto out;
1449			}
1450			fb = obj_to_fb(obj);
1451		}
1452
1453		mode = drm_mode_create(dev);
1454		drm_crtc_convert_umode(mode, &crtc_req->mode);
1455		drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
1456	}
1457
1458	if (crtc_req->count_connectors == 0 && mode) {
1459		DRM_DEBUG("Count connectors is 0 but mode set\n");
1460		ret = -EINVAL;
1461		goto out;
1462	}
1463
1464	if (crtc_req->count_connectors > 0 && !mode && !fb) {
1465		DRM_DEBUG("Count connectors is %d but no mode or fb set\n",
1466			  crtc_req->count_connectors);
1467		ret = -EINVAL;
1468		goto out;
1469	}
1470
1471	if (crtc_req->count_connectors > 0) {
1472		u32 out_id;
1473
1474		/* Avoid unbounded kernel memory allocation */
1475		if (crtc_req->count_connectors > config->num_connector) {
1476			ret = -EINVAL;
1477			goto out;
1478		}
1479
1480		connector_set = kmalloc(crtc_req->count_connectors *
1481					sizeof(struct drm_connector *),
1482					GFP_KERNEL);
1483		if (!connector_set) {
1484			ret = -ENOMEM;
1485			goto out;
1486		}
1487
1488		for (i = 0; i < crtc_req->count_connectors; i++) {
1489			set_connectors_ptr = (uint32_t *)(unsigned long)crtc_req->set_connectors_ptr;
1490			if (get_user(out_id, &set_connectors_ptr[i])) {
1491				ret = -EFAULT;
1492				goto out;
1493			}
1494
1495			obj = drm_mode_object_find(dev, out_id,
1496						   DRM_MODE_OBJECT_CONNECTOR);
1497			if (!obj) {
1498				DRM_DEBUG("Connector id %d unknown\n", out_id);
1499				ret = -EINVAL;
1500				goto out;
1501			}
1502			connector = obj_to_connector(obj);
1503
1504			connector_set[i] = connector;
1505		}
1506	}
1507
1508	set.crtc = crtc;
1509	set.x = crtc_req->x;
1510	set.y = crtc_req->y;
1511	set.mode = mode;
1512	set.connectors = connector_set;
1513	set.num_connectors = crtc_req->count_connectors;
1514	set.fb =fb;
1515	ret = crtc->funcs->set_config(&set);
1516
1517out:
1518	kfree(connector_set);
1519	mutex_unlock(&dev->mode_config.mutex);
1520	return ret;
1521}
1522
1523int drm_mode_cursor_ioctl(struct drm_device *dev,
1524			void *data, struct drm_file *file_priv)
1525{
1526	struct drm_mode_cursor *req = data;
1527	struct drm_mode_object *obj;
1528	struct drm_crtc *crtc;
1529	int ret = 0;
1530
1531	DRM_DEBUG("\n");
1532
1533	if (!req->flags) {
1534		DRM_ERROR("no operation set\n");
1535		return -EINVAL;
1536	}
1537
1538	mutex_lock(&dev->mode_config.mutex);
1539	obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC);
1540	if (!obj) {
1541		DRM_DEBUG("Unknown CRTC ID %d\n", req->crtc_id);
1542		ret = -EINVAL;
1543		goto out;
1544	}
1545	crtc = obj_to_crtc(obj);
1546
1547	if (req->flags & DRM_MODE_CURSOR_BO) {
1548		if (!crtc->funcs->cursor_set) {
1549			DRM_ERROR("crtc does not support cursor\n");
1550			ret = -ENXIO;
1551			goto out;
1552		}
1553		/* Turns off the cursor if handle is 0 */
1554		ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
1555					      req->width, req->height);
1556	}
1557
1558	if (req->flags & DRM_MODE_CURSOR_MOVE) {
1559		if (crtc->funcs->cursor_move) {
1560			ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
1561		} else {
1562			DRM_ERROR("crtc does not support cursor\n");
1563			ret = -EFAULT;
1564			goto out;
1565		}
1566	}
1567out:
1568	mutex_unlock(&dev->mode_config.mutex);
1569	return ret;
1570}
1571
1572/**
1573 * drm_mode_addfb - add an FB to the graphics configuration
1574 * @inode: inode from the ioctl
1575 * @filp: file * from the ioctl
1576 * @cmd: cmd from ioctl
1577 * @arg: arg from ioctl
1578 *
1579 * LOCKING:
1580 * Takes mode config lock.
1581 *
1582 * Add a new FB to the specified CRTC, given a user request.
1583 *
1584 * Called by the user via ioctl.
1585 *
1586 * RETURNS:
1587 * Zero on success, errno on failure.
1588 */
1589int drm_mode_addfb(struct drm_device *dev,
1590		   void *data, struct drm_file *file_priv)
1591{
1592	struct drm_mode_fb_cmd *r = data;
1593	struct drm_mode_config *config = &dev->mode_config;
1594	struct drm_framebuffer *fb;
1595	int ret = 0;
1596
1597	if ((config->min_width > r->width) || (r->width > config->max_width)) {
1598		DRM_ERROR("mode new framebuffer width not within limits\n");
1599		return -EINVAL;
1600	}
1601	if ((config->min_height > r->height) || (r->height > config->max_height)) {
1602		DRM_ERROR("mode new framebuffer height not within limits\n");
1603		return -EINVAL;
1604	}
1605
1606	mutex_lock(&dev->mode_config.mutex);
1607
1608	/* TODO check buffer is sufficently large */
1609	/* TODO setup destructor callback */
1610
1611	fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
1612	if (!fb) {
1613		DRM_ERROR("could not create framebuffer\n");
1614		ret = -EINVAL;
1615		goto out;
1616	}
1617
1618	r->fb_id = fb->base.id;
1619	list_add(&fb->filp_head, &file_priv->fbs);
1620
1621out:
1622	mutex_unlock(&dev->mode_config.mutex);
1623	return ret;
1624}
1625
1626/**
1627 * drm_mode_rmfb - remove an FB from the configuration
1628 * @inode: inode from the ioctl
1629 * @filp: file * from the ioctl
1630 * @cmd: cmd from ioctl
1631 * @arg: arg from ioctl
1632 *
1633 * LOCKING:
1634 * Takes mode config lock.
1635 *
1636 * Remove the FB specified by the user.
1637 *
1638 * Called by the user via ioctl.
1639 *
1640 * RETURNS:
1641 * Zero on success, errno on failure.
1642 */
1643int drm_mode_rmfb(struct drm_device *dev,
1644		   void *data, struct drm_file *file_priv)
1645{
1646	struct drm_mode_object *obj;
1647	struct drm_framebuffer *fb = NULL;
1648	struct drm_framebuffer *fbl = NULL;
1649	uint32_t *id = data;
1650	int ret = 0;
1651	int found = 0;
1652
1653	mutex_lock(&dev->mode_config.mutex);
1654	obj = drm_mode_object_find(dev, *id, DRM_MODE_OBJECT_FB);
1655	/* TODO check that we realy get a framebuffer back. */
1656	if (!obj) {
1657		DRM_ERROR("mode invalid framebuffer id\n");
1658		ret = -EINVAL;
1659		goto out;
1660	}
1661	fb = obj_to_fb(obj);
1662
1663	list_for_each_entry(fbl, &file_priv->fbs, filp_head)
1664		if (fb == fbl)
1665			found = 1;
1666
1667	if (!found) {
1668		DRM_ERROR("tried to remove a fb that we didn't own\n");
1669		ret = -EINVAL;
1670		goto out;
1671	}
1672
1673	/* TODO release all crtc connected to the framebuffer */
1674	/* TODO unhock the destructor from the buffer object */
1675
1676	list_del(&fb->filp_head);
1677	fb->funcs->destroy(fb);
1678
1679out:
1680	mutex_unlock(&dev->mode_config.mutex);
1681	return ret;
1682}
1683
1684/**
1685 * drm_mode_getfb - get FB info
1686 * @inode: inode from the ioctl
1687 * @filp: file * from the ioctl
1688 * @cmd: cmd from ioctl
1689 * @arg: arg from ioctl
1690 *
1691 * LOCKING:
1692 * Caller? (FIXME)
1693 *
1694 * Lookup the FB given its ID and return info about it.
1695 *
1696 * Called by the user via ioctl.
1697 *
1698 * RETURNS:
1699 * Zero on success, errno on failure.
1700 */
1701int drm_mode_getfb(struct drm_device *dev,
1702		   void *data, struct drm_file *file_priv)
1703{
1704	struct drm_mode_fb_cmd *r = data;
1705	struct drm_mode_object *obj;
1706	struct drm_framebuffer *fb;
1707	int ret = 0;
1708
1709	mutex_lock(&dev->mode_config.mutex);
1710	obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB);
1711	if (!obj) {
1712		DRM_ERROR("invalid framebuffer id\n");
1713		ret = -EINVAL;
1714		goto out;
1715	}
1716	fb = obj_to_fb(obj);
1717
1718	r->height = fb->height;
1719	r->width = fb->width;
1720	r->depth = fb->depth;
1721	r->bpp = fb->bits_per_pixel;
1722	r->pitch = fb->pitch;
1723	fb->funcs->create_handle(fb, file_priv, &r->handle);
1724
1725out:
1726	mutex_unlock(&dev->mode_config.mutex);
1727	return ret;
1728}
1729
1730/**
1731 * drm_fb_release - remove and free the FBs on this file
1732 * @filp: file * from the ioctl
1733 *
1734 * LOCKING:
1735 * Takes mode config lock.
1736 *
1737 * Destroy all the FBs associated with @filp.
1738 *
1739 * Called by the user via ioctl.
1740 *
1741 * RETURNS:
1742 * Zero on success, errno on failure.
1743 */
1744void drm_fb_release(struct file *filp)
1745{
1746	struct drm_file *priv = filp->private_data;
1747	struct drm_device *dev = priv->minor->dev;
1748	struct drm_framebuffer *fb, *tfb;
1749
1750	mutex_lock(&dev->mode_config.mutex);
1751	list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
1752		list_del(&fb->filp_head);
1753		fb->funcs->destroy(fb);
1754	}
1755	mutex_unlock(&dev->mode_config.mutex);
1756}
1757
1758/**
1759 * drm_mode_attachmode - add a mode to the user mode list
1760 * @dev: DRM device
1761 * @connector: connector to add the mode to
1762 * @mode: mode to add
1763 *
1764 * Add @mode to @connector's user mode list.
1765 */
1766static int drm_mode_attachmode(struct drm_device *dev,
1767			       struct drm_connector *connector,
1768			       struct drm_display_mode *mode)
1769{
1770	int ret = 0;
1771
1772	list_add_tail(&mode->head, &connector->user_modes);
1773	return ret;
1774}
1775
1776int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc,
1777			     struct drm_display_mode *mode)
1778{
1779	struct drm_connector *connector;
1780	int ret = 0;
1781	struct drm_display_mode *dup_mode;
1782	int need_dup = 0;
1783	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1784		if (!connector->encoder)
1785			break;
1786		if (connector->encoder->crtc == crtc) {
1787			if (need_dup)
1788				dup_mode = drm_mode_duplicate(dev, mode);
1789			else
1790				dup_mode = mode;
1791			ret = drm_mode_attachmode(dev, connector, dup_mode);
1792			if (ret)
1793				return ret;
1794			need_dup = 1;
1795		}
1796	}
1797	return 0;
1798}
1799EXPORT_SYMBOL(drm_mode_attachmode_crtc);
1800
1801static int drm_mode_detachmode(struct drm_device *dev,
1802			       struct drm_connector *connector,
1803			       struct drm_display_mode *mode)
1804{
1805	int found = 0;
1806	int ret = 0;
1807	struct drm_display_mode *match_mode, *t;
1808
1809	list_for_each_entry_safe(match_mode, t, &connector->user_modes, head) {
1810		if (drm_mode_equal(match_mode, mode)) {
1811			list_del(&match_mode->head);
1812			drm_mode_destroy(dev, match_mode);
1813			found = 1;
1814			break;
1815		}
1816	}
1817
1818	if (!found)
1819		ret = -EINVAL;
1820
1821	return ret;
1822}
1823
1824int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode)
1825{
1826	struct drm_connector *connector;
1827
1828	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1829		drm_mode_detachmode(dev, connector, mode);
1830	}
1831	return 0;
1832}
1833EXPORT_SYMBOL(drm_mode_detachmode_crtc);
1834
1835/**
1836 * drm_fb_attachmode - Attach a user mode to an connector
1837 * @inode: inode from the ioctl
1838 * @filp: file * from the ioctl
1839 * @cmd: cmd from ioctl
1840 * @arg: arg from ioctl
1841 *
1842 * This attaches a user specified mode to an connector.
1843 * Called by the user via ioctl.
1844 *
1845 * RETURNS:
1846 * Zero on success, errno on failure.
1847 */
1848int drm_mode_attachmode_ioctl(struct drm_device *dev,
1849			      void *data, struct drm_file *file_priv)
1850{
1851	struct drm_mode_mode_cmd *mode_cmd = data;
1852	struct drm_connector *connector;
1853	struct drm_display_mode *mode;
1854	struct drm_mode_object *obj;
1855	struct drm_mode_modeinfo *umode = &mode_cmd->mode;
1856	int ret = 0;
1857
1858	mutex_lock(&dev->mode_config.mutex);
1859
1860	obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
1861	if (!obj) {
1862		ret = -EINVAL;
1863		goto out;
1864	}
1865	connector = obj_to_connector(obj);
1866
1867	mode = drm_mode_create(dev);
1868	if (!mode) {
1869		ret = -ENOMEM;
1870		goto out;
1871	}
1872
1873	drm_crtc_convert_umode(mode, umode);
1874
1875	ret = drm_mode_attachmode(dev, connector, mode);
1876out:
1877	mutex_unlock(&dev->mode_config.mutex);
1878	return ret;
1879}
1880
1881
1882/**
1883 * drm_fb_detachmode - Detach a user specified mode from an connector
1884 * @inode: inode from the ioctl
1885 * @filp: file * from the ioctl
1886 * @cmd: cmd from ioctl
1887 * @arg: arg from ioctl
1888 *
1889 * Called by the user via ioctl.
1890 *
1891 * RETURNS:
1892 * Zero on success, errno on failure.
1893 */
1894int drm_mode_detachmode_ioctl(struct drm_device *dev,
1895			      void *data, struct drm_file *file_priv)
1896{
1897	struct drm_mode_object *obj;
1898	struct drm_mode_mode_cmd *mode_cmd = data;
1899	struct drm_connector *connector;
1900	struct drm_display_mode mode;
1901	struct drm_mode_modeinfo *umode = &mode_cmd->mode;
1902	int ret = 0;
1903
1904	mutex_lock(&dev->mode_config.mutex);
1905
1906	obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
1907	if (!obj) {
1908		ret = -EINVAL;
1909		goto out;
1910	}
1911	connector = obj_to_connector(obj);
1912
1913	drm_crtc_convert_umode(&mode, umode);
1914	ret = drm_mode_detachmode(dev, connector, &mode);
1915out:
1916	mutex_unlock(&dev->mode_config.mutex);
1917	return ret;
1918}
1919
1920struct drm_property *drm_property_create(struct drm_device *dev, int flags,
1921					 const char *name, int num_values)
1922{
1923	struct drm_property *property = NULL;
1924
1925	property = kzalloc(sizeof(struct drm_property), GFP_KERNEL);
1926	if (!property)
1927		return NULL;
1928
1929	if (num_values) {
1930		property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL);
1931		if (!property->values)
1932			goto fail;
1933	}
1934
1935	drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY);
1936	property->flags = flags;
1937	property->num_values = num_values;
1938	INIT_LIST_HEAD(&property->enum_blob_list);
1939
1940	if (name)
1941		strncpy(property->name, name, DRM_PROP_NAME_LEN);
1942
1943	list_add_tail(&property->head, &dev->mode_config.property_list);
1944	return property;
1945fail:
1946	kfree(property);
1947	return NULL;
1948}
1949EXPORT_SYMBOL(drm_property_create);
1950
1951int drm_property_add_enum(struct drm_property *property, int index,
1952			  uint64_t value, const char *name)
1953{
1954	struct drm_property_enum *prop_enum;
1955
1956	if (!(property->flags & DRM_MODE_PROP_ENUM))
1957		return -EINVAL;
1958
1959	if (!list_empty(&property->enum_blob_list)) {
1960		list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
1961			if (prop_enum->value == value) {
1962				strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
1963				prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
1964				return 0;
1965			}
1966		}
1967	}
1968
1969	prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL);
1970	if (!prop_enum)
1971		return -ENOMEM;
1972
1973	strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
1974	prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
1975	prop_enum->value = value;
1976
1977	property->values[index] = value;
1978	list_add_tail(&prop_enum->head, &property->enum_blob_list);
1979	return 0;
1980}
1981EXPORT_SYMBOL(drm_property_add_enum);
1982
1983void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
1984{
1985	struct drm_property_enum *prop_enum, *pt;
1986
1987	list_for_each_entry_safe(prop_enum, pt, &property->enum_blob_list, head) {
1988		list_del(&prop_enum->head);
1989		kfree(prop_enum);
1990	}
1991
1992	if (property->num_values)
1993		kfree(property->values);
1994	drm_mode_object_put(dev, &property->base);
1995	list_del(&property->head);
1996	kfree(property);
1997}
1998EXPORT_SYMBOL(drm_property_destroy);
1999
2000int drm_connector_attach_property(struct drm_connector *connector,
2001			       struct drm_property *property, uint64_t init_val)
2002{
2003	int i;
2004
2005	for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
2006		if (connector->property_ids[i] == 0) {
2007			connector->property_ids[i] = property->base.id;
2008			connector->property_values[i] = init_val;
2009			break;
2010		}
2011	}
2012
2013	if (i == DRM_CONNECTOR_MAX_PROPERTY)
2014		return -EINVAL;
2015	return 0;
2016}
2017EXPORT_SYMBOL(drm_connector_attach_property);
2018
2019int drm_connector_property_set_value(struct drm_connector *connector,
2020				  struct drm_property *property, uint64_t value)
2021{
2022	int i;
2023
2024	for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
2025		if (connector->property_ids[i] == property->base.id) {
2026			connector->property_values[i] = value;
2027			break;
2028		}
2029	}
2030
2031	if (i == DRM_CONNECTOR_MAX_PROPERTY)
2032		return -EINVAL;
2033	return 0;
2034}
2035EXPORT_SYMBOL(drm_connector_property_set_value);
2036
2037int drm_connector_property_get_value(struct drm_connector *connector,
2038				  struct drm_property *property, uint64_t *val)
2039{
2040	int i;
2041
2042	for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
2043		if (connector->property_ids[i] == property->base.id) {
2044			*val = connector->property_values[i];
2045			break;
2046		}
2047	}
2048
2049	if (i == DRM_CONNECTOR_MAX_PROPERTY)
2050		return -EINVAL;
2051	return 0;
2052}
2053EXPORT_SYMBOL(drm_connector_property_get_value);
2054
2055int drm_mode_getproperty_ioctl(struct drm_device *dev,
2056			       void *data, struct drm_file *file_priv)
2057{
2058	struct drm_mode_object *obj;
2059	struct drm_mode_get_property *out_resp = data;
2060	struct drm_property *property;
2061	int enum_count = 0;
2062	int blob_count = 0;
2063	int value_count = 0;
2064	int ret = 0, i;
2065	int copied;
2066	struct drm_property_enum *prop_enum;
2067	struct drm_mode_property_enum __user *enum_ptr;
2068	struct drm_property_blob *prop_blob;
2069	uint32_t *blob_id_ptr;
2070	uint64_t __user *values_ptr;
2071	uint32_t __user *blob_length_ptr;
2072
2073	mutex_lock(&dev->mode_config.mutex);
2074	obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
2075	if (!obj) {
2076		ret = -EINVAL;
2077		goto done;
2078	}
2079	property = obj_to_property(obj);
2080
2081	if (property->flags & DRM_MODE_PROP_ENUM) {
2082		list_for_each_entry(prop_enum, &property->enum_blob_list, head)
2083			enum_count++;
2084	} else if (property->flags & DRM_MODE_PROP_BLOB) {
2085		list_for_each_entry(prop_blob, &property->enum_blob_list, head)
2086			blob_count++;
2087	}
2088
2089	value_count = property->num_values;
2090
2091	strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN);
2092	out_resp->name[DRM_PROP_NAME_LEN-1] = 0;
2093	out_resp->flags = property->flags;
2094
2095	if ((out_resp->count_values >= value_count) && value_count) {
2096		values_ptr = (uint64_t *)(unsigned long)out_resp->values_ptr;
2097		for (i = 0; i < value_count; i++) {
2098			if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) {
2099				ret = -EFAULT;
2100				goto done;
2101			}
2102		}
2103	}
2104	out_resp->count_values = value_count;
2105
2106	if (property->flags & DRM_MODE_PROP_ENUM) {
2107		if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
2108			copied = 0;
2109			enum_ptr = (struct drm_mode_property_enum *)(unsigned long)out_resp->enum_blob_ptr;
2110			list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
2111
2112				if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {
2113					ret = -EFAULT;
2114					goto done;
2115				}
2116
2117				if (copy_to_user(&enum_ptr[copied].name,
2118						 &prop_enum->name, DRM_PROP_NAME_LEN)) {
2119					ret = -EFAULT;
2120					goto done;
2121				}
2122				copied++;
2123			}
2124		}
2125		out_resp->count_enum_blobs = enum_count;
2126	}
2127
2128	if (property->flags & DRM_MODE_PROP_BLOB) {
2129		if ((out_resp->count_enum_blobs >= blob_count) && blob_count) {
2130			copied = 0;
2131			blob_id_ptr = (uint32_t *)(unsigned long)out_resp->enum_blob_ptr;
2132			blob_length_ptr = (uint32_t *)(unsigned long)out_resp->values_ptr;
2133
2134			list_for_each_entry(prop_blob, &property->enum_blob_list, head) {
2135				if (put_user(prop_blob->base.id, blob_id_ptr + copied)) {
2136					ret = -EFAULT;
2137					goto done;
2138				}
2139
2140				if (put_user(prop_blob->length, blob_length_ptr + copied)) {
2141					ret = -EFAULT;
2142					goto done;
2143				}
2144
2145				copied++;
2146			}
2147		}
2148		out_resp->count_enum_blobs = blob_count;
2149	}
2150done:
2151	mutex_unlock(&dev->mode_config.mutex);
2152	return ret;
2153}
2154
2155static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length,
2156							  void *data)
2157{
2158	struct drm_property_blob *blob;
2159
2160	if (!length || !data)
2161		return NULL;
2162
2163	blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
2164	if (!blob)
2165		return NULL;
2166
2167	blob->data = (void *)((char *)blob + sizeof(struct drm_property_blob));
2168	blob->length = length;
2169
2170	memcpy(blob->data, data, length);
2171
2172	drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB);
2173
2174	list_add_tail(&blob->head, &dev->mode_config.property_blob_list);
2175	return blob;
2176}
2177
2178static void drm_property_destroy_blob(struct drm_device *dev,
2179			       struct drm_property_blob *blob)
2180{
2181	drm_mode_object_put(dev, &blob->base);
2182	list_del(&blob->head);
2183	kfree(blob);
2184}
2185
2186int drm_mode_getblob_ioctl(struct drm_device *dev,
2187			   void *data, struct drm_file *file_priv)
2188{
2189	struct drm_mode_object *obj;
2190	struct drm_mode_get_blob *out_resp = data;
2191	struct drm_property_blob *blob;
2192	int ret = 0;
2193	void *blob_ptr;
2194
2195	mutex_lock(&dev->mode_config.mutex);
2196	obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB);
2197	if (!obj) {
2198		ret = -EINVAL;
2199		goto done;
2200	}
2201	blob = obj_to_blob(obj);
2202
2203	if (out_resp->length == blob->length) {
2204		blob_ptr = (void *)(unsigned long)out_resp->data;
2205		if (copy_to_user(blob_ptr, blob->data, blob->length)){
2206			ret = -EFAULT;
2207			goto done;
2208		}
2209	}
2210	out_resp->length = blob->length;
2211
2212done:
2213	mutex_unlock(&dev->mode_config.mutex);
2214	return ret;
2215}
2216
2217int drm_mode_connector_update_edid_property(struct drm_connector *connector,
2218					    struct edid *edid)
2219{
2220	struct drm_device *dev = connector->dev;
2221	int ret = 0;
2222
2223	if (connector->edid_blob_ptr)
2224		drm_property_destroy_blob(dev, connector->edid_blob_ptr);
2225
2226	/* Delete edid, when there is none. */
2227	if (!edid) {
2228		connector->edid_blob_ptr = NULL;
2229		ret = drm_connector_property_set_value(connector, dev->mode_config.edid_property, 0);
2230		return ret;
2231	}
2232
2233	connector->edid_blob_ptr = drm_property_create_blob(connector->dev, 128, edid);
2234
2235	ret = drm_connector_property_set_value(connector,
2236					       dev->mode_config.edid_property,
2237					       connector->edid_blob_ptr->base.id);
2238
2239	return ret;
2240}
2241EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
2242
2243int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
2244				       void *data, struct drm_file *file_priv)
2245{
2246	struct drm_mode_connector_set_property *out_resp = data;
2247	struct drm_mode_object *obj;
2248	struct drm_property *property;
2249	struct drm_connector *connector;
2250	int ret = -EINVAL;
2251	int i;
2252
2253	mutex_lock(&dev->mode_config.mutex);
2254
2255	obj = drm_mode_object_find(dev, out_resp->connector_id, DRM_MODE_OBJECT_CONNECTOR);
2256	if (!obj) {
2257		goto out;
2258	}
2259	connector = obj_to_connector(obj);
2260
2261	for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
2262		if (connector->property_ids[i] == out_resp->prop_id)
2263			break;
2264	}
2265
2266	if (i == DRM_CONNECTOR_MAX_PROPERTY) {
2267		goto out;
2268	}
2269
2270	obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
2271	if (!obj) {
2272		goto out;
2273	}
2274	property = obj_to_property(obj);
2275
2276	if (property->flags & DRM_MODE_PROP_IMMUTABLE)
2277		goto out;
2278
2279	if (property->flags & DRM_MODE_PROP_RANGE) {
2280		if (out_resp->value < property->values[0])
2281			goto out;
2282
2283		if (out_resp->value > property->values[1])
2284			goto out;
2285	} else {
2286		int found = 0;
2287		for (i = 0; i < property->num_values; i++) {
2288			if (property->values[i] == out_resp->value) {
2289				found = 1;
2290				break;
2291			}
2292		}
2293		if (!found) {
2294			goto out;
2295		}
2296	}
2297
2298	if (connector->funcs->set_property)
2299		ret = connector->funcs->set_property(connector, property, out_resp->value);
2300
2301	/* store the property value if succesful */
2302	if (!ret)
2303		drm_connector_property_set_value(connector, property, out_resp->value);
2304out:
2305	mutex_unlock(&dev->mode_config.mutex);
2306	return ret;
2307}
2308
2309int drm_mode_connector_attach_encoder(struct drm_connector *connector,
2310				      struct drm_encoder *encoder)
2311{
2312	int i;
2313
2314	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
2315		if (connector->encoder_ids[i] == 0) {
2316			connector->encoder_ids[i] = encoder->base.id;
2317			return 0;
2318		}
2319	}
2320	return -ENOMEM;
2321}
2322EXPORT_SYMBOL(drm_mode_connector_attach_encoder);
2323
2324void drm_mode_connector_detach_encoder(struct drm_connector *connector,
2325				    struct drm_encoder *encoder)
2326{
2327	int i;
2328	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
2329		if (connector->encoder_ids[i] == encoder->base.id) {
2330			connector->encoder_ids[i] = 0;
2331			if (connector->encoder == encoder)
2332				connector->encoder = NULL;
2333			break;
2334		}
2335	}
2336}
2337EXPORT_SYMBOL(drm_mode_connector_detach_encoder);
2338
2339bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
2340				  int gamma_size)
2341{
2342	crtc->gamma_size = gamma_size;
2343
2344	crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL);
2345	if (!crtc->gamma_store) {
2346		crtc->gamma_size = 0;
2347		return false;
2348	}
2349
2350	return true;
2351}
2352EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);
2353
2354int drm_mode_gamma_set_ioctl(struct drm_device *dev,
2355			     void *data, struct drm_file *file_priv)
2356{
2357	struct drm_mode_crtc_lut *crtc_lut = data;
2358	struct drm_mode_object *obj;
2359	struct drm_crtc *crtc;
2360	void *r_base, *g_base, *b_base;
2361	int size;
2362	int ret = 0;
2363
2364	mutex_lock(&dev->mode_config.mutex);
2365	obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
2366	if (!obj) {
2367		ret = -EINVAL;
2368		goto out;
2369	}
2370	crtc = obj_to_crtc(obj);
2371
2372	/* memcpy into gamma store */
2373	if (crtc_lut->gamma_size != crtc->gamma_size) {
2374		ret = -EINVAL;
2375		goto out;
2376	}
2377
2378	size = crtc_lut->gamma_size * (sizeof(uint16_t));
2379	r_base = crtc->gamma_store;
2380	if (copy_from_user(r_base, (void __user *)(unsigned long)crtc_lut->red, size)) {
2381		ret = -EFAULT;
2382		goto out;
2383	}
2384
2385	g_base = r_base + size;
2386	if (copy_from_user(g_base, (void __user *)(unsigned long)crtc_lut->green, size)) {
2387		ret = -EFAULT;
2388		goto out;
2389	}
2390
2391	b_base = g_base + size;
2392	if (copy_from_user(b_base, (void __user *)(unsigned long)crtc_lut->blue, size)) {
2393		ret = -EFAULT;
2394		goto out;
2395	}
2396
2397	crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, crtc->gamma_size);
2398
2399out:
2400	mutex_unlock(&dev->mode_config.mutex);
2401	return ret;
2402
2403}
2404
2405int drm_mode_gamma_get_ioctl(struct drm_device *dev,
2406			     void *data, struct drm_file *file_priv)
2407{
2408	struct drm_mode_crtc_lut *crtc_lut = data;
2409	struct drm_mode_object *obj;
2410	struct drm_crtc *crtc;
2411	void *r_base, *g_base, *b_base;
2412	int size;
2413	int ret = 0;
2414
2415	mutex_lock(&dev->mode_config.mutex);
2416	obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
2417	if (!obj) {
2418		ret = -EINVAL;
2419		goto out;
2420	}
2421	crtc = obj_to_crtc(obj);
2422
2423	/* memcpy into gamma store */
2424	if (crtc_lut->gamma_size != crtc->gamma_size) {
2425		ret = -EINVAL;
2426		goto out;
2427	}
2428
2429	size = crtc_lut->gamma_size * (sizeof(uint16_t));
2430	r_base = crtc->gamma_store;
2431	if (copy_to_user((void __user *)(unsigned long)crtc_lut->red, r_base, size)) {
2432		ret = -EFAULT;
2433		goto out;
2434	}
2435
2436	g_base = r_base + size;
2437	if (copy_to_user((void __user *)(unsigned long)crtc_lut->green, g_base, size)) {
2438		ret = -EFAULT;
2439		goto out;
2440	}
2441
2442	b_base = g_base + size;
2443	if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) {
2444		ret = -EFAULT;
2445		goto out;
2446	}
2447out:
2448	mutex_unlock(&dev->mode_config.mutex);
2449	return ret;
2450}
2451