Subversion Repositories Kolibri OS

Rev

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