Subversion Repositories Kolibri OS

Rev

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