Subversion Repositories Kolibri OS

Rev

Rev 2004 | Rev 3031 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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