Subversion Repositories Kolibri OS

Rev

Rev 4104 | Rev 5060 | 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
 */
4075 Serge 32
#include 
1179 serge 33
#include 
1963 serge 34
#include 
3031 serge 35
#include 
36
#include 
37
#include 
38
#include 
39
#include 
1123 serge 40
 
3480 Serge 41
/**
42
 * drm_modeset_lock_all - take all modeset locks
43
 * @dev: drm device
44
 *
45
 * This function takes all modeset locks, suitable where a more fine-grained
46
 * scheme isn't (yet) implemented.
47
 */
48
void drm_modeset_lock_all(struct drm_device *dev)
49
{
50
	struct drm_crtc *crtc;
51
 
52
	mutex_lock(&dev->mode_config.mutex);
53
 
54
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
55
		mutex_lock_nest_lock(&crtc->mutex, &dev->mode_config.mutex);
56
}
57
EXPORT_SYMBOL(drm_modeset_lock_all);
58
 
59
/**
60
 * drm_modeset_unlock_all - drop all modeset locks
61
 * @dev: device
62
 */
63
void drm_modeset_unlock_all(struct drm_device *dev)
64
{
65
	struct drm_crtc *crtc;
66
 
67
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
68
		mutex_unlock(&crtc->mutex);
69
 
70
	mutex_unlock(&dev->mode_config.mutex);
71
}
72
EXPORT_SYMBOL(drm_modeset_unlock_all);
73
 
74
/**
75
 * drm_warn_on_modeset_not_all_locked - check that all modeset locks are locked
76
 * @dev: device
77
 */
78
void drm_warn_on_modeset_not_all_locked(struct drm_device *dev)
79
{
80
	struct drm_crtc *crtc;
81
 
82
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
83
		WARN_ON(!mutex_is_locked(&crtc->mutex));
84
 
85
	WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
86
}
87
EXPORT_SYMBOL(drm_warn_on_modeset_not_all_locked);
88
 
1123 serge 89
/* Avoid boilerplate.  I'm tired of typing. */
90
#define DRM_ENUM_NAME_FN(fnname, list)				\
4075 Serge 91
	const char *fnname(int val)				\
1123 serge 92
	{							\
93
		int i;						\
94
		for (i = 0; i < ARRAY_SIZE(list); i++) {	\
95
			if (list[i].type == val)		\
96
				return list[i].name;		\
97
		}						\
98
		return "(unknown)";				\
99
	}
100
 
101
/*
102
 * Global properties
103
 */
4075 Serge 104
static const struct drm_prop_enum_list drm_dpms_enum_list[] =
1123 serge 105
{	{ DRM_MODE_DPMS_ON, "On" },
106
	{ DRM_MODE_DPMS_STANDBY, "Standby" },
107
	{ DRM_MODE_DPMS_SUSPEND, "Suspend" },
108
	{ DRM_MODE_DPMS_OFF, "Off" }
109
};
110
 
111
DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
112
 
113
/*
114
 * Optional properties
115
 */
4075 Serge 116
static const struct drm_prop_enum_list drm_scaling_mode_enum_list[] =
1123 serge 117
{
1179 serge 118
	{ DRM_MODE_SCALE_NONE, "None" },
119
	{ DRM_MODE_SCALE_FULLSCREEN, "Full" },
120
	{ DRM_MODE_SCALE_CENTER, "Center" },
121
	{ DRM_MODE_SCALE_ASPECT, "Full aspect" },
1123 serge 122
};
123
 
124
/*
125
 * Non-global properties, but "required" for certain connectors.
126
 */
4075 Serge 127
static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] =
1123 serge 128
{
129
	{ DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
130
	{ DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
131
	{ DRM_MODE_SUBCONNECTOR_DVIA,      "DVI-A"     }, /* DVI-I  */
132
};
133
 
134
DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list)
135
 
4075 Serge 136
static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] =
1123 serge 137
{
138
	{ DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I and TV-out */
139
	{ DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
140
	{ DRM_MODE_SUBCONNECTOR_DVIA,      "DVI-A"     }, /* DVI-I  */
141
};
142
 
143
DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name,
144
		 drm_dvi_i_subconnector_enum_list)
145
 
4075 Serge 146
static const struct drm_prop_enum_list drm_tv_select_enum_list[] =
1123 serge 147
{
148
	{ DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
149
	{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
150
	{ DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */
151
	{ DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
1179 serge 152
	{ DRM_MODE_SUBCONNECTOR_SCART,     "SCART"     }, /* TV-out */
1123 serge 153
};
154
 
155
DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)
156
 
4075 Serge 157
static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] =
1123 serge 158
{
159
	{ DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I and TV-out */
160
	{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
161
	{ DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */
162
	{ DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
1179 serge 163
	{ DRM_MODE_SUBCONNECTOR_SCART,     "SCART"     }, /* TV-out */
1123 serge 164
};
165
 
166
DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
167
		 drm_tv_subconnector_enum_list)
168
 
4075 Serge 169
static const struct drm_prop_enum_list drm_dirty_info_enum_list[] = {
1321 serge 170
	{ DRM_MODE_DIRTY_OFF,      "Off"      },
171
	{ DRM_MODE_DIRTY_ON,       "On"       },
172
	{ DRM_MODE_DIRTY_ANNOTATE, "Annotate" },
173
};
174
 
1123 serge 175
struct drm_conn_prop_enum_list {
176
	int type;
4075 Serge 177
	const char *name;
4104 Serge 178
	struct ida ida;
1123 serge 179
};
180
 
181
/*
182
 * Connector and encoder types.
183
 */
184
static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
4104 Serge 185
{	{ DRM_MODE_CONNECTOR_Unknown, "Unknown" },
186
	{ DRM_MODE_CONNECTOR_VGA, "VGA" },
187
	{ DRM_MODE_CONNECTOR_DVII, "DVI-I" },
188
	{ DRM_MODE_CONNECTOR_DVID, "DVI-D" },
189
	{ DRM_MODE_CONNECTOR_DVIA, "DVI-A" },
190
	{ DRM_MODE_CONNECTOR_Composite, "Composite" },
191
	{ DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO" },
192
	{ DRM_MODE_CONNECTOR_LVDS, "LVDS" },
193
	{ DRM_MODE_CONNECTOR_Component, "Component" },
194
	{ DRM_MODE_CONNECTOR_9PinDIN, "DIN" },
195
	{ DRM_MODE_CONNECTOR_DisplayPort, "DP" },
196
	{ DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" },
197
	{ DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" },
198
	{ DRM_MODE_CONNECTOR_TV, "TV" },
199
	{ DRM_MODE_CONNECTOR_eDP, "eDP" },
200
	{ DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
4560 Serge 201
	{ DRM_MODE_CONNECTOR_DSI, "DSI" },
1123 serge 202
};
203
 
4075 Serge 204
static const struct drm_prop_enum_list drm_encoder_enum_list[] =
1123 serge 205
{	{ DRM_MODE_ENCODER_NONE, "None" },
206
	{ DRM_MODE_ENCODER_DAC, "DAC" },
207
	{ DRM_MODE_ENCODER_TMDS, "TMDS" },
208
	{ DRM_MODE_ENCODER_LVDS, "LVDS" },
209
	{ DRM_MODE_ENCODER_TVDAC, "TV" },
3031 serge 210
	{ DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
4560 Serge 211
	{ DRM_MODE_ENCODER_DSI, "DSI" },
1123 serge 212
};
213
 
4104 Serge 214
void drm_connector_ida_init(void)
215
{
216
	int i;
217
 
218
	for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++)
219
		ida_init(&drm_connector_enum_list[i].ida);
220
}
221
 
222
void drm_connector_ida_destroy(void)
223
{
224
	int i;
225
 
226
	for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++)
227
		ida_destroy(&drm_connector_enum_list[i].ida);
228
}
229
 
4075 Serge 230
const char *drm_get_encoder_name(const struct drm_encoder *encoder)
1123 serge 231
{
232
	static char buf[32];
233
 
234
	snprintf(buf, 32, "%s-%d",
235
		 drm_encoder_enum_list[encoder->encoder_type].name,
236
		 encoder->base.id);
237
	return buf;
238
}
1179 serge 239
EXPORT_SYMBOL(drm_get_encoder_name);
1123 serge 240
 
4075 Serge 241
const char *drm_get_connector_name(const struct drm_connector *connector)
1123 serge 242
{
243
	static char buf[32];
244
 
245
	snprintf(buf, 32, "%s-%d",
246
		 drm_connector_enum_list[connector->connector_type].name,
247
		 connector->connector_type_id);
248
	return buf;
249
}
250
EXPORT_SYMBOL(drm_get_connector_name);
251
 
4075 Serge 252
const char *drm_get_connector_status_name(enum drm_connector_status status)
1123 serge 253
{
254
	if (status == connector_status_connected)
255
		return "connected";
256
	else if (status == connector_status_disconnected)
257
		return "disconnected";
258
	else
259
		return "unknown";
260
}
3764 Serge 261
EXPORT_SYMBOL(drm_get_connector_status_name);
1123 serge 262
 
4075 Serge 263
static char printable_char(int c)
264
{
265
	return isascii(c) && isprint(c) ? c : '?';
266
}
267
 
268
const char *drm_get_format_name(uint32_t format)
269
{
270
	static char buf[32];
271
 
272
	snprintf(buf, sizeof(buf),
273
		 "%c%c%c%c %s-endian (0x%08x)",
274
		 printable_char(format & 0xff),
275
		 printable_char((format >> 8) & 0xff),
276
		 printable_char((format >> 16) & 0xff),
277
		 printable_char((format >> 24) & 0x7f),
278
		 format & DRM_FORMAT_BIG_ENDIAN ? "big" : "little",
279
		 format);
280
 
281
	return buf;
282
}
283
EXPORT_SYMBOL(drm_get_format_name);
284
 
1123 serge 285
/**
3480 Serge 286
 * drm_mode_object_get - allocate a new modeset identifier
1123 serge 287
 * @dev: DRM device
3480 Serge 288
 * @obj: object pointer, used to generate unique ID
289
 * @obj_type: object type
1123 serge 290
 *
291
 * Create a unique identifier based on @ptr in @dev's identifier space.  Used
292
 * for tracking modes, CRTCs and connectors.
293
 *
294
 * RETURNS:
295
 * New unique (relative to other objects in @dev) integer identifier for the
296
 * object.
297
 */
298
static int drm_mode_object_get(struct drm_device *dev,
299
			       struct drm_mode_object *obj, uint32_t obj_type)
300
{
301
	int ret;
302
 
3480 Serge 303
	mutex_lock(&dev->mode_config.idr_mutex);
304
	ret = idr_alloc(&dev->mode_config.crtc_idr, obj, 1, 0, GFP_KERNEL);
305
	if (ret >= 0) {
306
		/*
307
		 * Set up the object linking under the protection of the idr
308
		 * lock so that other users can't see inconsistent state.
309
		 */
310
		obj->id = ret;
311
		obj->type = obj_type;
1123 serge 312
	}
1179 serge 313
	mutex_unlock(&dev->mode_config.idr_mutex);
1123 serge 314
 
3480 Serge 315
	return ret < 0 ? ret : 0;
1123 serge 316
}
317
 
318
/**
3480 Serge 319
 * drm_mode_object_put - free a modeset identifer
1123 serge 320
 * @dev: DRM device
3480 Serge 321
 * @object: object to free
1123 serge 322
 *
323
 * Free @id from @dev's unique identifier pool.
324
 */
325
static void drm_mode_object_put(struct drm_device *dev,
326
				struct drm_mode_object *object)
327
{
1179 serge 328
	mutex_lock(&dev->mode_config.idr_mutex);
1123 serge 329
	idr_remove(&dev->mode_config.crtc_idr, object->id);
1179 serge 330
	mutex_unlock(&dev->mode_config.idr_mutex);
1123 serge 331
}
332
 
3480 Serge 333
/**
334
 * drm_mode_object_find - look up a drm object with static lifetime
335
 * @dev: drm device
336
 * @id: id of the mode object
337
 * @type: type of the mode object
338
 *
339
 * Note that framebuffers cannot be looked up with this functions - since those
340
 * are reference counted, they need special treatment.
341
 */
1321 serge 342
struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
343
		uint32_t id, uint32_t type)
1123 serge 344
{
345
	struct drm_mode_object *obj = NULL;
346
 
3480 Serge 347
	/* Framebuffers are reference counted and need their own lookup
348
	 * function.*/
349
	WARN_ON(type == DRM_MODE_OBJECT_FB);
350
 
1179 serge 351
	mutex_lock(&dev->mode_config.idr_mutex);
1123 serge 352
	obj = idr_find(&dev->mode_config.crtc_idr, id);
353
	if (!obj || (obj->type != type) || (obj->id != id))
354
		obj = NULL;
1179 serge 355
	mutex_unlock(&dev->mode_config.idr_mutex);
1123 serge 356
 
357
	return obj;
358
}
359
EXPORT_SYMBOL(drm_mode_object_find);
360
 
361
/**
362
 * drm_framebuffer_init - initialize a framebuffer
363
 * @dev: DRM device
3480 Serge 364
 * @fb: framebuffer to be initialized
365
 * @funcs: ... with these functions
1123 serge 366
 *
367
 * Allocates an ID for the framebuffer's parent mode object, sets its mode
368
 * functions & device file and adds it to the master fd list.
369
 *
3480 Serge 370
 * IMPORTANT:
371
 * This functions publishes the fb and makes it available for concurrent access
372
 * by other users. Which means by this point the fb _must_ be fully set up -
373
 * since all the fb attributes are invariant over its lifetime, no further
374
 * locking but only correct reference counting is required.
375
 *
1123 serge 376
 * RETURNS:
1321 serge 377
 * Zero on success, error code on failure.
1123 serge 378
 */
379
int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
380
			 const struct drm_framebuffer_funcs *funcs)
381
{
382
	int ret;
1963 serge 383
 
3480 Serge 384
	mutex_lock(&dev->mode_config.fb_lock);
385
	kref_init(&fb->refcount);
386
	INIT_LIST_HEAD(&fb->filp_head);
387
	fb->dev = dev;
388
	fb->funcs = funcs;
389
 
1123 serge 390
	ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
3031 serge 391
	if (ret)
3480 Serge 392
		goto out;
1123 serge 393
 
3480 Serge 394
	/* Grab the idr reference. */
395
	drm_framebuffer_reference(fb);
396
 
1123 serge 397
	dev->mode_config.num_fb++;
398
	list_add(&fb->head, &dev->mode_config.fb_list);
3480 Serge 399
out:
400
	mutex_unlock(&dev->mode_config.fb_lock);
1123 serge 401
 
402
	return 0;
403
}
404
EXPORT_SYMBOL(drm_framebuffer_init);
405
 
3480 Serge 406
static void drm_framebuffer_free(struct kref *kref)
407
{
408
	struct drm_framebuffer *fb =
409
			container_of(kref, struct drm_framebuffer, refcount);
410
	fb->funcs->destroy(fb);
411
}
412
 
413
static struct drm_framebuffer *__drm_framebuffer_lookup(struct drm_device *dev,
414
							uint32_t id)
415
{
416
	struct drm_mode_object *obj = NULL;
417
	struct drm_framebuffer *fb;
418
 
419
	mutex_lock(&dev->mode_config.idr_mutex);
420
	obj = idr_find(&dev->mode_config.crtc_idr, id);
421
	if (!obj || (obj->type != DRM_MODE_OBJECT_FB) || (obj->id != id))
422
		fb = NULL;
423
	else
424
		fb = obj_to_fb(obj);
425
	mutex_unlock(&dev->mode_config.idr_mutex);
426
 
427
	return fb;
428
}
429
 
1123 serge 430
/**
3480 Serge 431
 * drm_framebuffer_lookup - look up a drm framebuffer and grab a reference
432
 * @dev: drm device
433
 * @id: id of the fb object
434
 *
435
 * If successful, this grabs an additional reference to the framebuffer -
436
 * callers need to make sure to eventually unreference the returned framebuffer
437
 * again.
438
 */
439
struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
440
					       uint32_t id)
441
{
442
	struct drm_framebuffer *fb;
443
 
444
	mutex_lock(&dev->mode_config.fb_lock);
445
	fb = __drm_framebuffer_lookup(dev, id);
446
	if (fb)
4075 Serge 447
		drm_framebuffer_reference(fb);
3480 Serge 448
	mutex_unlock(&dev->mode_config.fb_lock);
449
 
450
	return fb;
451
}
452
EXPORT_SYMBOL(drm_framebuffer_lookup);
453
 
454
/**
455
 * drm_framebuffer_unreference - unref a framebuffer
456
 * @fb: framebuffer to unref
457
 *
458
 * This functions decrements the fb's refcount and frees it if it drops to zero.
459
 */
460
void drm_framebuffer_unreference(struct drm_framebuffer *fb)
461
{
462
	DRM_DEBUG("FB ID: %d\n", fb->base.id);
463
	kref_put(&fb->refcount, drm_framebuffer_free);
464
}
465
EXPORT_SYMBOL(drm_framebuffer_unreference);
466
 
467
/**
468
 * drm_framebuffer_reference - incr the fb refcnt
469
 * @fb: framebuffer
470
 */
471
void drm_framebuffer_reference(struct drm_framebuffer *fb)
472
{
473
	DRM_DEBUG("FB ID: %d\n", fb->base.id);
474
	kref_get(&fb->refcount);
475
}
476
EXPORT_SYMBOL(drm_framebuffer_reference);
477
 
478
static void drm_framebuffer_free_bug(struct kref *kref)
479
{
480
	BUG();
481
}
482
 
483
static void __drm_framebuffer_unreference(struct drm_framebuffer *fb)
484
{
485
	DRM_DEBUG("FB ID: %d\n", fb->base.id);
486
	kref_put(&fb->refcount, drm_framebuffer_free_bug);
487
}
488
 
489
/* dev->mode_config.fb_lock must be held! */
490
static void __drm_framebuffer_unregister(struct drm_device *dev,
491
					 struct drm_framebuffer *fb)
492
{
493
	mutex_lock(&dev->mode_config.idr_mutex);
494
	idr_remove(&dev->mode_config.crtc_idr, fb->base.id);
495
	mutex_unlock(&dev->mode_config.idr_mutex);
496
 
497
	fb->base.id = 0;
498
 
499
	__drm_framebuffer_unreference(fb);
500
}
501
 
502
/**
503
 * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr
504
 * @fb: fb to unregister
505
 *
506
 * Drivers need to call this when cleaning up driver-private framebuffers, e.g.
507
 * those used for fbdev. Note that the caller must hold a reference of it's own,
508
 * i.e. the object may not be destroyed through this call (since it'll lead to a
509
 * locking inversion).
510
 */
511
void drm_framebuffer_unregister_private(struct drm_framebuffer *fb)
512
{
513
	struct drm_device *dev = fb->dev;
514
 
515
	mutex_lock(&dev->mode_config.fb_lock);
516
	/* Mark fb as reaped and drop idr ref. */
517
	__drm_framebuffer_unregister(dev, fb);
518
	mutex_unlock(&dev->mode_config.fb_lock);
519
}
520
EXPORT_SYMBOL(drm_framebuffer_unregister_private);
521
 
522
/**
1123 serge 523
 * drm_framebuffer_cleanup - remove a framebuffer object
524
 * @fb: framebuffer to remove
525
 *
3480 Serge 526
 * Cleanup references to a user-created framebuffer. This function is intended
527
 * to be used from the drivers ->destroy callback.
1123 serge 528
 *
3480 Serge 529
 * Note that this function does not remove the fb from active usuage - if it is
530
 * still used anywhere, hilarity can ensue since userspace could call getfb on
531
 * the id and get back -EINVAL. Obviously no concern at driver unload time.
532
 *
533
 * Also, the framebuffer will not be removed from the lookup idr - for
534
 * user-created framebuffers this will happen in in the rmfb ioctl. For
535
 * driver-private objects (e.g. for fbdev) drivers need to explicitly call
536
 * drm_framebuffer_unregister_private.
1123 serge 537
 */
538
void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
539
{
540
	struct drm_device *dev = fb->dev;
3480 Serge 541
 
542
	mutex_lock(&dev->mode_config.fb_lock);
1123 serge 543
	list_del(&fb->head);
544
	dev->mode_config.num_fb--;
3480 Serge 545
	mutex_unlock(&dev->mode_config.fb_lock);
1123 serge 546
}
547
EXPORT_SYMBOL(drm_framebuffer_cleanup);
548
 
3480 Serge 549
/**
550
 * drm_framebuffer_remove - remove and unreference a framebuffer object
551
 * @fb: framebuffer to remove
552
 *
553
 * Scans all the CRTCs and planes in @dev's mode_config.  If they're
554
 * using @fb, removes it, setting it to NULL. Then drops the reference to the
555
 * passed-in framebuffer. Might take the modeset locks.
556
 *
557
 * Note that this function optimizes the cleanup away if the caller holds the
558
 * last reference to the framebuffer. It is also guaranteed to not take the
559
 * modeset locks in this case.
560
 */
561
void drm_framebuffer_remove(struct drm_framebuffer *fb)
562
{
563
	struct drm_device *dev = fb->dev;
564
	struct drm_crtc *crtc;
565
	struct drm_plane *plane;
566
	struct drm_mode_set set;
567
	int ret;
3031 serge 568
 
3480 Serge 569
	WARN_ON(!list_empty(&fb->filp_head));
3031 serge 570
 
3480 Serge 571
	/*
572
	 * drm ABI mandates that we remove any deleted framebuffers from active
573
	 * useage. But since most sane clients only remove framebuffers they no
574
	 * longer need, try to optimize this away.
575
	 *
576
	 * Since we're holding a reference ourselves, observing a refcount of 1
577
	 * means that we're the last holder and can skip it. Also, the refcount
578
	 * can never increase from 1 again, so we don't need any barriers or
579
	 * locks.
580
	 *
581
	 * Note that userspace could try to race with use and instate a new
582
	 * usage _after_ we've cleared all current ones. End result will be an
583
	 * in-use fb with fb-id == 0. Userspace is allowed to shoot its own foot
584
	 * in this manner.
585
	 */
586
	if (atomic_read(&fb->refcount.refcount) > 1) {
587
		drm_modeset_lock_all(dev);
588
		/* remove from any CRTC */
589
		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
590
			if (crtc->fb == fb) {
591
				/* should turn off the crtc */
592
				memset(&set, 0, sizeof(struct drm_mode_set));
593
				set.crtc = crtc;
594
				set.fb = NULL;
595
				ret = drm_mode_set_config_internal(&set);
596
				if (ret)
597
					DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc);
598
			}
599
		}
3031 serge 600
 
3480 Serge 601
		list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
4075 Serge 602
			if (plane->fb == fb)
603
				drm_plane_force_disable(plane);
3480 Serge 604
		}
605
		drm_modeset_unlock_all(dev);
606
	}
3031 serge 607
 
3480 Serge 608
	drm_framebuffer_unreference(fb);
609
}
610
EXPORT_SYMBOL(drm_framebuffer_remove);
611
 
1123 serge 612
/**
613
 * drm_crtc_init - Initialise a new CRTC object
614
 * @dev: DRM device
615
 * @crtc: CRTC object to init
616
 * @funcs: callbacks for the new CRTC
617
 *
4075 Serge 618
 * Inits a new object created as base part of a driver crtc object.
3031 serge 619
 *
620
 * RETURNS:
621
 * Zero on success, error code on failure.
1123 serge 622
 */
3031 serge 623
int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
1123 serge 624
		   const struct drm_crtc_funcs *funcs)
625
{
3031 serge 626
	int ret;
627
 
1123 serge 628
	crtc->dev = dev;
629
	crtc->funcs = funcs;
3031 serge 630
	crtc->invert_dimensions = false;
1123 serge 631
 
3480 Serge 632
	drm_modeset_lock_all(dev);
633
	mutex_init(&crtc->mutex);
634
	mutex_lock_nest_lock(&crtc->mutex, &dev->mode_config.mutex);
1123 serge 635
 
3031 serge 636
	ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
637
	if (ret)
638
		goto out;
639
 
640
	crtc->base.properties = &crtc->properties;
641
 
1123 serge 642
	list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
643
	dev->mode_config.num_crtc++;
3031 serge 644
 
645
 out:
3480 Serge 646
	drm_modeset_unlock_all(dev);
3031 serge 647
 
648
	return ret;
1123 serge 649
}
650
EXPORT_SYMBOL(drm_crtc_init);
651
 
652
/**
4075 Serge 653
 * drm_crtc_cleanup - Clean up the core crtc usage
1123 serge 654
 * @crtc: CRTC to cleanup
655
 *
4075 Serge 656
 * This function cleans up @crtc and removes it from the DRM mode setting
657
 * core. Note that the function does *not* free the crtc structure itself,
658
 * this is the responsibility of the caller.
1123 serge 659
 */
660
void drm_crtc_cleanup(struct drm_crtc *crtc)
661
{
662
	struct drm_device *dev = crtc->dev;
663
 
664
		kfree(crtc->gamma_store);
665
		crtc->gamma_store = NULL;
666
 
667
	drm_mode_object_put(dev, &crtc->base);
668
	list_del(&crtc->head);
669
	dev->mode_config.num_crtc--;
670
}
671
EXPORT_SYMBOL(drm_crtc_cleanup);
672
 
673
/**
4560 Serge 674
 * drm_crtc_index - find the index of a registered CRTC
675
 * @crtc: CRTC to find index for
676
 *
677
 * Given a registered CRTC, return the index of that CRTC within a DRM
678
 * device's list of CRTCs.
679
 */
680
unsigned int drm_crtc_index(struct drm_crtc *crtc)
681
{
682
	unsigned int index = 0;
683
	struct drm_crtc *tmp;
684
 
685
	list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) {
686
		if (tmp == crtc)
687
			return index;
688
 
689
		index++;
690
	}
691
 
692
	BUG();
693
}
694
EXPORT_SYMBOL(drm_crtc_index);
695
 
696
/**
1123 serge 697
 * drm_mode_probed_add - add a mode to a connector's probed mode list
698
 * @connector: connector the new mode
699
 * @mode: mode data
700
 *
701
 * Add @mode to @connector's mode list for later use.
702
 */
703
void drm_mode_probed_add(struct drm_connector *connector,
704
			 struct drm_display_mode *mode)
705
{
4075 Serge 706
	list_add_tail(&mode->head, &connector->probed_modes);
1123 serge 707
}
708
EXPORT_SYMBOL(drm_mode_probed_add);
709
 
4104 Serge 710
/*
1123 serge 711
 * drm_mode_remove - remove and free a mode
712
 * @connector: connector list to modify
713
 * @mode: mode to remove
714
 *
715
 * Remove @mode from @connector's mode list, then free it.
716
 */
4104 Serge 717
static void drm_mode_remove(struct drm_connector *connector,
1123 serge 718
		     struct drm_display_mode *mode)
719
{
720
	list_del(&mode->head);
3031 serge 721
	drm_mode_destroy(connector->dev, mode);
1123 serge 722
}
723
 
724
/**
725
 * drm_connector_init - Init a preallocated connector
726
 * @dev: DRM device
727
 * @connector: the connector to init
728
 * @funcs: callbacks for this connector
3480 Serge 729
 * @connector_type: user visible type of the connector
1123 serge 730
 *
731
 * Initialises a preallocated connector. Connectors should be
732
 * subclassed as part of driver connector objects.
3031 serge 733
 *
734
 * RETURNS:
735
 * Zero on success, error code on failure.
1123 serge 736
 */
3031 serge 737
int drm_connector_init(struct drm_device *dev,
1123 serge 738
		     struct drm_connector *connector,
739
		     const struct drm_connector_funcs *funcs,
740
		     int connector_type)
741
{
3031 serge 742
	int ret;
4104 Serge 743
	struct ida *connector_ida =
744
		&drm_connector_enum_list[connector_type].ida;
3031 serge 745
 
3480 Serge 746
	drm_modeset_lock_all(dev);
1123 serge 747
 
3031 serge 748
	ret = drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR);
749
	if (ret)
750
		goto out;
751
 
752
	connector->base.properties = &connector->properties;
1123 serge 753
	connector->dev = dev;
754
	connector->funcs = funcs;
755
	connector->connector_type = connector_type;
756
	connector->connector_type_id =
4104 Serge 757
		ida_simple_get(connector_ida, 1, 0, GFP_KERNEL);
758
	if (connector->connector_type_id < 0) {
759
		ret = connector->connector_type_id;
760
		drm_mode_object_put(dev, &connector->base);
761
		goto out;
762
	}
1123 serge 763
	INIT_LIST_HEAD(&connector->probed_modes);
764
	INIT_LIST_HEAD(&connector->modes);
765
	connector->edid_blob_ptr = NULL;
3192 Serge 766
	connector->status = connector_status_unknown;
1123 serge 767
 
768
	list_add_tail(&connector->head, &dev->mode_config.connector_list);
769
	dev->mode_config.num_connector++;
770
 
3031 serge 771
	if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL)
3192 Serge 772
		drm_object_attach_property(&connector->base,
3031 serge 773
					      dev->mode_config.edid_property,
774
					      0);
1123 serge 775
 
3192 Serge 776
	drm_object_attach_property(&connector->base,
1123 serge 777
				      dev->mode_config.dpms_property, 0);
778
 
3031 serge 779
 out:
3480 Serge 780
	drm_modeset_unlock_all(dev);
3031 serge 781
 
782
	return ret;
1123 serge 783
}
784
EXPORT_SYMBOL(drm_connector_init);
785
 
786
/**
787
 * drm_connector_cleanup - cleans up an initialised connector
788
 * @connector: connector to cleanup
789
 *
790
 * Cleans up the connector but doesn't free the object.
791
 */
792
void drm_connector_cleanup(struct drm_connector *connector)
793
{
794
	struct drm_device *dev = connector->dev;
795
	struct drm_display_mode *mode, *t;
796
 
797
	list_for_each_entry_safe(mode, t, &connector->probed_modes, head)
798
		drm_mode_remove(connector, mode);
799
 
800
	list_for_each_entry_safe(mode, t, &connector->modes, head)
801
		drm_mode_remove(connector, mode);
802
 
4104 Serge 803
	ida_remove(&drm_connector_enum_list[connector->connector_type].ida,
804
		   connector->connector_type_id);
805
 
1123 serge 806
	drm_mode_object_put(dev, &connector->base);
807
	list_del(&connector->head);
2160 serge 808
	dev->mode_config.num_connector--;
1123 serge 809
}
810
EXPORT_SYMBOL(drm_connector_cleanup);
811
 
3031 serge 812
void drm_connector_unplug_all(struct drm_device *dev)
813
{
814
	struct drm_connector *connector;
815
 
816
	/* taking the mode config mutex ends up in a clash with sysfs */
817
//   list_for_each_entry(connector, &dev->mode_config.connector_list, head)
818
//       drm_sysfs_connector_remove(connector);
819
 
820
}
821
EXPORT_SYMBOL(drm_connector_unplug_all);
822
 
4104 Serge 823
int drm_bridge_init(struct drm_device *dev, struct drm_bridge *bridge,
824
		const struct drm_bridge_funcs *funcs)
825
{
826
	int ret;
827
 
828
	drm_modeset_lock_all(dev);
829
 
830
	ret = drm_mode_object_get(dev, &bridge->base, DRM_MODE_OBJECT_BRIDGE);
831
	if (ret)
832
		goto out;
833
 
834
	bridge->dev = dev;
835
	bridge->funcs = funcs;
836
 
837
	list_add_tail(&bridge->head, &dev->mode_config.bridge_list);
838
	dev->mode_config.num_bridge++;
839
 
840
 out:
841
	drm_modeset_unlock_all(dev);
842
	return ret;
843
}
844
EXPORT_SYMBOL(drm_bridge_init);
845
 
846
void drm_bridge_cleanup(struct drm_bridge *bridge)
847
{
848
	struct drm_device *dev = bridge->dev;
849
 
850
	drm_modeset_lock_all(dev);
851
	drm_mode_object_put(dev, &bridge->base);
852
	list_del(&bridge->head);
853
	dev->mode_config.num_bridge--;
854
	drm_modeset_unlock_all(dev);
855
}
856
EXPORT_SYMBOL(drm_bridge_cleanup);
857
 
3031 serge 858
int drm_encoder_init(struct drm_device *dev,
1123 serge 859
		      struct drm_encoder *encoder,
860
		      const struct drm_encoder_funcs *funcs,
861
		      int encoder_type)
862
{
3031 serge 863
	int ret;
864
 
3480 Serge 865
	drm_modeset_lock_all(dev);
1123 serge 866
 
3031 serge 867
	ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
868
	if (ret)
869
		goto out;
870
 
1123 serge 871
	encoder->dev = dev;
872
	encoder->encoder_type = encoder_type;
873
	encoder->funcs = funcs;
874
 
875
	list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
876
	dev->mode_config.num_encoder++;
877
 
3031 serge 878
 out:
3480 Serge 879
	drm_modeset_unlock_all(dev);
3031 serge 880
 
881
	return ret;
1123 serge 882
}
883
EXPORT_SYMBOL(drm_encoder_init);
884
 
885
void drm_encoder_cleanup(struct drm_encoder *encoder)
886
{
887
	struct drm_device *dev = encoder->dev;
3480 Serge 888
	drm_modeset_lock_all(dev);
1123 serge 889
	drm_mode_object_put(dev, &encoder->base);
890
	list_del(&encoder->head);
2160 serge 891
	dev->mode_config.num_encoder--;
3480 Serge 892
	drm_modeset_unlock_all(dev);
1123 serge 893
}
894
EXPORT_SYMBOL(drm_encoder_cleanup);
895
 
4075 Serge 896
/**
897
 * drm_plane_init - Initialise a new plane object
898
 * @dev: DRM device
899
 * @plane: plane object to init
900
 * @possible_crtcs: bitmask of possible CRTCs
901
 * @funcs: callbacks for the new plane
902
 * @formats: array of supported formats (%DRM_FORMAT_*)
903
 * @format_count: number of elements in @formats
904
 * @priv: plane is private (hidden from userspace)?
905
 *
906
 * Inits a new object created as base part of a driver plane object.
907
 *
908
 * RETURNS:
909
 * Zero on success, error code on failure.
910
 */
3031 serge 911
int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
912
		   unsigned long possible_crtcs,
913
		   const struct drm_plane_funcs *funcs,
914
		   const uint32_t *formats, uint32_t format_count,
915
		   bool priv)
916
{
917
	int ret;
918
 
3480 Serge 919
	drm_modeset_lock_all(dev);
3031 serge 920
 
921
	ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
922
	if (ret)
923
		goto out;
924
 
925
	plane->base.properties = &plane->properties;
926
	plane->dev = dev;
927
	plane->funcs = funcs;
928
	plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
929
				      GFP_KERNEL);
930
	if (!plane->format_types) {
931
		DRM_DEBUG_KMS("out of memory when allocating plane\n");
932
		drm_mode_object_put(dev, &plane->base);
933
		ret = -ENOMEM;
934
		goto out;
935
	}
936
 
937
	memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
938
	plane->format_count = format_count;
939
	plane->possible_crtcs = possible_crtcs;
940
 
941
	/* private planes are not exposed to userspace, but depending on
942
	 * display hardware, might be convenient to allow sharing programming
943
	 * for the scanout engine with the crtc implementation.
944
	 */
945
	if (!priv) {
946
		list_add_tail(&plane->head, &dev->mode_config.plane_list);
947
		dev->mode_config.num_plane++;
948
	} else {
949
		INIT_LIST_HEAD(&plane->head);
950
	}
951
 
952
 out:
3480 Serge 953
	drm_modeset_unlock_all(dev);
3031 serge 954
 
955
	return ret;
956
}
957
EXPORT_SYMBOL(drm_plane_init);
958
 
4075 Serge 959
/**
960
 * drm_plane_cleanup - Clean up the core plane usage
961
 * @plane: plane to cleanup
962
 *
963
 * This function cleans up @plane and removes it from the DRM mode setting
964
 * core. Note that the function does *not* free the plane structure itself,
965
 * this is the responsibility of the caller.
966
 */
3031 serge 967
void drm_plane_cleanup(struct drm_plane *plane)
968
{
969
	struct drm_device *dev = plane->dev;
970
 
3480 Serge 971
	drm_modeset_lock_all(dev);
3031 serge 972
	kfree(plane->format_types);
973
	drm_mode_object_put(dev, &plane->base);
974
	/* if not added to a list, it must be a private plane */
975
	if (!list_empty(&plane->head)) {
976
		list_del(&plane->head);
977
		dev->mode_config.num_plane--;
978
	}
3480 Serge 979
	drm_modeset_unlock_all(dev);
3031 serge 980
}
981
EXPORT_SYMBOL(drm_plane_cleanup);
982
 
1123 serge 983
/**
4075 Serge 984
 * drm_plane_force_disable - Forcibly disable a plane
985
 * @plane: plane to disable
986
 *
987
 * Forces the plane to be disabled.
988
 *
989
 * Used when the plane's current framebuffer is destroyed,
990
 * and when restoring fbdev mode.
991
 */
992
void drm_plane_force_disable(struct drm_plane *plane)
993
{
994
	int ret;
995
 
996
	if (!plane->fb)
997
		return;
998
 
999
	ret = plane->funcs->disable_plane(plane);
1000
	if (ret)
1001
		DRM_ERROR("failed to disable plane with busy fb\n");
1002
	/* disconnect the plane from the fb and crtc: */
1003
	__drm_framebuffer_unreference(plane->fb);
1004
	plane->fb = NULL;
1005
	plane->crtc = NULL;
1006
}
1007
EXPORT_SYMBOL(drm_plane_force_disable);
1008
 
1009
/**
1123 serge 1010
 * drm_mode_create - create a new display mode
1011
 * @dev: DRM device
1012
 *
1013
 * Create a new drm_display_mode, give it an ID, and return it.
1014
 *
1015
 * RETURNS:
1016
 * Pointer to new mode on success, NULL on error.
1017
 */
1018
struct drm_display_mode *drm_mode_create(struct drm_device *dev)
1019
{
1020
	struct drm_display_mode *nmode;
1021
 
1022
	nmode = kzalloc(sizeof(struct drm_display_mode), GFP_KERNEL);
1023
	if (!nmode)
1024
		return NULL;
1025
 
3031 serge 1026
	if (drm_mode_object_get(dev, &nmode->base, DRM_MODE_OBJECT_MODE)) {
1027
		kfree(nmode);
1028
		return NULL;
1029
	}
1030
 
1123 serge 1031
	return nmode;
1032
}
1033
EXPORT_SYMBOL(drm_mode_create);
1034
 
1035
/**
1036
 * drm_mode_destroy - remove a mode
1037
 * @dev: DRM device
1038
 * @mode: mode to remove
1039
 *
1040
 * Free @mode's unique identifier, then free it.
1041
 */
1042
void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
1043
{
3031 serge 1044
	if (!mode)
1045
		return;
1046
 
1123 serge 1047
	drm_mode_object_put(dev, &mode->base);
1048
 
1049
	kfree(mode);
1050
}
1051
EXPORT_SYMBOL(drm_mode_destroy);
1052
 
1053
static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
1054
{
1055
	struct drm_property *edid;
1056
	struct drm_property *dpms;
1057
 
1058
	/*
1059
	 * Standard properties (apply to all connectors)
1060
	 */
1061
	edid = drm_property_create(dev, DRM_MODE_PROP_BLOB |
1062
				   DRM_MODE_PROP_IMMUTABLE,
1063
				   "EDID", 0);
1064
	dev->mode_config.edid_property = edid;
1065
 
3031 serge 1066
	dpms = drm_property_create_enum(dev, 0,
1067
				   "DPMS", drm_dpms_enum_list,
1068
				   ARRAY_SIZE(drm_dpms_enum_list));
1123 serge 1069
	dev->mode_config.dpms_property = dpms;
1070
 
1071
	return 0;
1072
}
1073
 
1074
/**
1075
 * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties
1076
 * @dev: DRM device
1077
 *
1078
 * Called by a driver the first time a DVI-I connector is made.
1079
 */
1080
int drm_mode_create_dvi_i_properties(struct drm_device *dev)
1081
{
1082
	struct drm_property *dvi_i_selector;
1083
	struct drm_property *dvi_i_subconnector;
1084
 
1085
	if (dev->mode_config.dvi_i_select_subconnector_property)
1086
		return 0;
1087
 
1088
	dvi_i_selector =
3031 serge 1089
		drm_property_create_enum(dev, 0,
1123 serge 1090
				    "select subconnector",
3031 serge 1091
				    drm_dvi_i_select_enum_list,
1123 serge 1092
				    ARRAY_SIZE(drm_dvi_i_select_enum_list));
1093
	dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector;
1094
 
3031 serge 1095
	dvi_i_subconnector = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
1123 serge 1096
				    "subconnector",
3031 serge 1097
				    drm_dvi_i_subconnector_enum_list,
1123 serge 1098
				    ARRAY_SIZE(drm_dvi_i_subconnector_enum_list));
1099
	dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector;
1100
 
1101
	return 0;
1102
}
1103
EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);
1104
 
1105
/**
1106
 * drm_create_tv_properties - create TV specific connector properties
1107
 * @dev: DRM device
1108
 * @num_modes: number of different TV formats (modes) supported
1109
 * @modes: array of pointers to strings containing name of each format
1110
 *
1111
 * Called by a driver's TV initialization routine, this function creates
1112
 * the TV specific connector properties for a given device.  Caller is
1113
 * responsible for allocating a list of format names and passing them to
1114
 * this routine.
1115
 */
1116
int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
1117
				  char *modes[])
1118
{
1119
	struct drm_property *tv_selector;
1120
	struct drm_property *tv_subconnector;
1121
	int i;
1122
 
1123
	if (dev->mode_config.tv_select_subconnector_property)
1124
		return 0;
1125
 
1126
	/*
1127
	 * Basic connector properties
1128
	 */
3031 serge 1129
	tv_selector = drm_property_create_enum(dev, 0,
1123 serge 1130
					  "select subconnector",
3031 serge 1131
					  drm_tv_select_enum_list,
1123 serge 1132
					  ARRAY_SIZE(drm_tv_select_enum_list));
1133
	dev->mode_config.tv_select_subconnector_property = tv_selector;
1134
 
1135
	tv_subconnector =
3031 serge 1136
		drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
1137
				    "subconnector",
1138
				    drm_tv_subconnector_enum_list,
1123 serge 1139
				    ARRAY_SIZE(drm_tv_subconnector_enum_list));
1140
	dev->mode_config.tv_subconnector_property = tv_subconnector;
1141
 
1142
	/*
1143
	 * Other, TV specific properties: margins & TV modes.
1144
	 */
1145
	dev->mode_config.tv_left_margin_property =
3031 serge 1146
		drm_property_create_range(dev, 0, "left margin", 0, 100);
1123 serge 1147
 
1148
	dev->mode_config.tv_right_margin_property =
3031 serge 1149
		drm_property_create_range(dev, 0, "right margin", 0, 100);
1123 serge 1150
 
1151
	dev->mode_config.tv_top_margin_property =
3031 serge 1152
		drm_property_create_range(dev, 0, "top margin", 0, 100);
1123 serge 1153
 
1154
	dev->mode_config.tv_bottom_margin_property =
3031 serge 1155
		drm_property_create_range(dev, 0, "bottom margin", 0, 100);
1123 serge 1156
 
1157
	dev->mode_config.tv_mode_property =
1158
		drm_property_create(dev, DRM_MODE_PROP_ENUM,
1159
				    "mode", num_modes);
1160
	for (i = 0; i < num_modes; i++)
1161
		drm_property_add_enum(dev->mode_config.tv_mode_property, i,
1162
				      i, modes[i]);
1163
 
1179 serge 1164
	dev->mode_config.tv_brightness_property =
3031 serge 1165
		drm_property_create_range(dev, 0, "brightness", 0, 100);
1179 serge 1166
 
1167
	dev->mode_config.tv_contrast_property =
3031 serge 1168
		drm_property_create_range(dev, 0, "contrast", 0, 100);
1179 serge 1169
 
1170
	dev->mode_config.tv_flicker_reduction_property =
3031 serge 1171
		drm_property_create_range(dev, 0, "flicker reduction", 0, 100);
1179 serge 1172
 
1173
	dev->mode_config.tv_overscan_property =
3031 serge 1174
		drm_property_create_range(dev, 0, "overscan", 0, 100);
1179 serge 1175
 
1176
	dev->mode_config.tv_saturation_property =
3031 serge 1177
		drm_property_create_range(dev, 0, "saturation", 0, 100);
1179 serge 1178
 
1179
	dev->mode_config.tv_hue_property =
3031 serge 1180
		drm_property_create_range(dev, 0, "hue", 0, 100);
1179 serge 1181
 
1123 serge 1182
	return 0;
1183
}
1184
EXPORT_SYMBOL(drm_mode_create_tv_properties);
1185
 
1186
/**
1187
 * drm_mode_create_scaling_mode_property - create scaling mode property
1188
 * @dev: DRM device
1189
 *
1190
 * Called by a driver the first time it's needed, must be attached to desired
1191
 * connectors.
1192
 */
1193
int drm_mode_create_scaling_mode_property(struct drm_device *dev)
1194
{
1195
	struct drm_property *scaling_mode;
1196
 
1197
	if (dev->mode_config.scaling_mode_property)
1198
		return 0;
1199
 
1200
	scaling_mode =
3031 serge 1201
		drm_property_create_enum(dev, 0, "scaling mode",
1202
				drm_scaling_mode_enum_list,
1123 serge 1203
				    ARRAY_SIZE(drm_scaling_mode_enum_list));
1204
 
1205
	dev->mode_config.scaling_mode_property = scaling_mode;
1206
 
1207
	return 0;
1208
}
1209
EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
1210
 
1211
/**
1321 serge 1212
 * drm_mode_create_dirty_property - create dirty property
1213
 * @dev: DRM device
1214
 *
1215
 * Called by a driver the first time it's needed, must be attached to desired
1216
 * connectors.
1217
 */
1218
int drm_mode_create_dirty_info_property(struct drm_device *dev)
1219
{
1220
	struct drm_property *dirty_info;
1221
 
1222
	if (dev->mode_config.dirty_info_property)
1223
		return 0;
1224
 
1225
	dirty_info =
3031 serge 1226
		drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
1321 serge 1227
				    "dirty",
3031 serge 1228
				    drm_dirty_info_enum_list,
1321 serge 1229
				    ARRAY_SIZE(drm_dirty_info_enum_list));
1230
	dev->mode_config.dirty_info_property = dirty_info;
1231
 
1232
	return 0;
1233
}
1234
EXPORT_SYMBOL(drm_mode_create_dirty_info_property);
1235
 
3746 Serge 1236
static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
1123 serge 1237
{
1238
	uint32_t total_objects = 0;
1239
 
1240
	total_objects += dev->mode_config.num_crtc;
1241
	total_objects += dev->mode_config.num_connector;
1242
	total_objects += dev->mode_config.num_encoder;
4104 Serge 1243
	total_objects += dev->mode_config.num_bridge;
1123 serge 1244
 
1245
	group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
1246
	if (!group->id_list)
1247
		return -ENOMEM;
1248
 
1249
	group->num_crtcs = 0;
1250
	group->num_connectors = 0;
1251
	group->num_encoders = 0;
4104 Serge 1252
	group->num_bridges = 0;
1123 serge 1253
	return 0;
1254
}
1255
 
1256
int drm_mode_group_init_legacy_group(struct drm_device *dev,
1257
				     struct drm_mode_group *group)
1258
{
1259
	struct drm_crtc *crtc;
1260
	struct drm_encoder *encoder;
1261
	struct drm_connector *connector;
4104 Serge 1262
	struct drm_bridge *bridge;
1123 serge 1263
	int ret;
1264
 
1265
	if ((ret = drm_mode_group_init(dev, group)))
1266
		return ret;
1267
 
1268
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
1269
		group->id_list[group->num_crtcs++] = crtc->base.id;
1270
 
1271
	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
1272
		group->id_list[group->num_crtcs + group->num_encoders++] =
1273
		encoder->base.id;
1274
 
1275
	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
1276
		group->id_list[group->num_crtcs + group->num_encoders +
1277
			       group->num_connectors++] = connector->base.id;
1278
 
4104 Serge 1279
	list_for_each_entry(bridge, &dev->mode_config.bridge_list, head)
1280
		group->id_list[group->num_crtcs + group->num_encoders +
1281
			       group->num_connectors + group->num_bridges++] =
1282
					bridge->base.id;
1283
 
1123 serge 1284
	return 0;
1285
}
3031 serge 1286
EXPORT_SYMBOL(drm_mode_group_init_legacy_group);
1123 serge 1287
 
1288
/**
1289
 * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
1290
 * @out: drm_mode_modeinfo struct to return to the user
1291
 * @in: drm_display_mode to use
1292
 *
1293
 * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
1294
 * the user.
1295
 */
3031 serge 1296
static void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
1297
				      const struct drm_display_mode *in)
1123 serge 1298
{
3031 serge 1299
	WARN(in->hdisplay > USHRT_MAX || in->hsync_start > USHRT_MAX ||
1300
	     in->hsync_end > USHRT_MAX || in->htotal > USHRT_MAX ||
1301
	     in->hskew > USHRT_MAX || in->vdisplay > USHRT_MAX ||
1302
	     in->vsync_start > USHRT_MAX || in->vsync_end > USHRT_MAX ||
1303
	     in->vtotal > USHRT_MAX || in->vscan > USHRT_MAX,
1304
	     "timing values too large for mode info\n");
1305
 
1123 serge 1306
	out->clock = in->clock;
1307
	out->hdisplay = in->hdisplay;
1308
	out->hsync_start = in->hsync_start;
1309
	out->hsync_end = in->hsync_end;
1310
	out->htotal = in->htotal;
1311
	out->hskew = in->hskew;
1312
	out->vdisplay = in->vdisplay;
1313
	out->vsync_start = in->vsync_start;
1314
	out->vsync_end = in->vsync_end;
1315
	out->vtotal = in->vtotal;
1316
	out->vscan = in->vscan;
1317
	out->vrefresh = in->vrefresh;
1318
	out->flags = in->flags;
1319
	out->type = in->type;
1320
	strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
1321
	out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1322
}
1323
 
1324
/**
4560 Serge 1325
 * drm_crtc_convert_umode - convert a modeinfo into a drm_display_mode
1123 serge 1326
 * @out: drm_display_mode to return to the user
1327
 * @in: drm_mode_modeinfo to use
1328
 *
1329
 * Convert a drm_mode_modeinfo into a drm_display_mode structure to return to
1330
 * the caller.
3031 serge 1331
 *
1332
 * RETURNS:
1333
 * Zero on success, errno on failure.
1123 serge 1334
 */
3031 serge 1335
static int drm_crtc_convert_umode(struct drm_display_mode *out,
1336
				  const struct drm_mode_modeinfo *in)
1123 serge 1337
{
3031 serge 1338
	if (in->clock > INT_MAX || in->vrefresh > INT_MAX)
1339
		return -ERANGE;
1340
 
4560 Serge 1341
	if ((in->flags & DRM_MODE_FLAG_3D_MASK) > DRM_MODE_FLAG_3D_MAX)
1342
		return -EINVAL;
1343
 
1123 serge 1344
	out->clock = in->clock;
1345
	out->hdisplay = in->hdisplay;
1346
	out->hsync_start = in->hsync_start;
1347
	out->hsync_end = in->hsync_end;
1348
	out->htotal = in->htotal;
1349
	out->hskew = in->hskew;
1350
	out->vdisplay = in->vdisplay;
1351
	out->vsync_start = in->vsync_start;
1352
	out->vsync_end = in->vsync_end;
1353
	out->vtotal = in->vtotal;
1354
	out->vscan = in->vscan;
1355
	out->vrefresh = in->vrefresh;
1356
	out->flags = in->flags;
1357
	out->type = in->type;
1358
	strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
1359
	out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
3031 serge 1360
 
1361
	return 0;
1123 serge 1362
}
1363
 
1364
 
1365
#if 0
1366
/**
1367
 * drm_mode_getresources - get graphics configuration
3480 Serge 1368
 * @dev: drm device for the ioctl
1369
 * @data: data pointer for the ioctl
1370
 * @file_priv: drm file for the ioctl call
1123 serge 1371
 *
1372
 * Construct a set of configuration description structures and return
1373
 * them to the user, including CRTC, connector and framebuffer configuration.
1374
 *
1375
 * Called by the user via ioctl.
1376
 *
1377
 * RETURNS:
1378
 * Zero on success, errno on failure.
1379
 */
1380
int drm_mode_getresources(struct drm_device *dev, void *data,
1381
			  struct drm_file *file_priv)
1382
{
1383
	struct drm_mode_card_res *card_res = data;
1384
	struct list_head *lh;
1385
	struct drm_framebuffer *fb;
1386
	struct drm_connector *connector;
1387
	struct drm_crtc *crtc;
1388
	struct drm_encoder *encoder;
1389
	int ret = 0;
1390
	int connector_count = 0;
1391
	int crtc_count = 0;
1392
	int fb_count = 0;
1393
	int encoder_count = 0;
1394
	int copied = 0, i;
1395
	uint32_t __user *fb_id;
1396
	uint32_t __user *crtc_id;
1397
	uint32_t __user *connector_id;
1398
	uint32_t __user *encoder_id;
1399
	struct drm_mode_group *mode_group;
1400
 
1963 serge 1401
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
1402
		return -EINVAL;
1403
 
1123 serge 1404
 
3480 Serge 1405
	mutex_lock(&file_priv->fbs_lock);
1123 serge 1406
	/*
1407
	 * For the non-control nodes we need to limit the list of resources
1408
	 * by IDs in the group list for this node
1409
	 */
1410
	list_for_each(lh, &file_priv->fbs)
1411
		fb_count++;
1412
 
3480 Serge 1413
	/* handle this in 4 parts */
1414
	/* FBs */
1415
	if (card_res->count_fbs >= fb_count) {
1416
		copied = 0;
1417
		fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr;
1418
		list_for_each_entry(fb, &file_priv->fbs, filp_head) {
1419
			if (put_user(fb->base.id, fb_id + copied)) {
1420
				mutex_unlock(&file_priv->fbs_lock);
1421
				return -EFAULT;
1422
			}
1423
			copied++;
1424
		}
1425
	}
1426
	card_res->count_fbs = fb_count;
1427
	mutex_unlock(&file_priv->fbs_lock);
1428
 
1429
	drm_modeset_lock_all(dev);
1123 serge 1430
	mode_group = &file_priv->master->minor->mode_group;
1431
	if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1432
 
1433
		list_for_each(lh, &dev->mode_config.crtc_list)
1434
			crtc_count++;
1435
 
1436
		list_for_each(lh, &dev->mode_config.connector_list)
1437
			connector_count++;
1438
 
1439
		list_for_each(lh, &dev->mode_config.encoder_list)
1440
			encoder_count++;
1441
	} else {
1442
 
1443
		crtc_count = mode_group->num_crtcs;
1444
		connector_count = mode_group->num_connectors;
1445
		encoder_count = mode_group->num_encoders;
1446
	}
1447
 
1448
	card_res->max_height = dev->mode_config.max_height;
1449
	card_res->min_height = dev->mode_config.min_height;
1450
	card_res->max_width = dev->mode_config.max_width;
1451
	card_res->min_width = dev->mode_config.min_width;
1452
 
1453
	/* CRTCs */
1454
	if (card_res->count_crtcs >= crtc_count) {
1455
		copied = 0;
1456
		crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr;
1457
		if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1458
			list_for_each_entry(crtc, &dev->mode_config.crtc_list,
1459
					    head) {
1963 serge 1460
				DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
1123 serge 1461
				if (put_user(crtc->base.id, crtc_id + copied)) {
1462
					ret = -EFAULT;
1463
					goto out;
1464
				}
1465
				copied++;
1466
			}
1467
		} else {
1468
			for (i = 0; i < mode_group->num_crtcs; i++) {
1469
				if (put_user(mode_group->id_list[i],
1470
					     crtc_id + copied)) {
1471
					ret = -EFAULT;
1472
					goto out;
1473
				}
1474
				copied++;
1475
			}
1476
		}
1477
	}
1478
	card_res->count_crtcs = crtc_count;
1479
 
1480
	/* Encoders */
1481
	if (card_res->count_encoders >= encoder_count) {
1482
		copied = 0;
1483
		encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr;
1484
		if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1485
			list_for_each_entry(encoder,
1486
					    &dev->mode_config.encoder_list,
1487
					    head) {
1963 serge 1488
				DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", encoder->base.id,
1489
						drm_get_encoder_name(encoder));
1123 serge 1490
				if (put_user(encoder->base.id, encoder_id +
1491
					     copied)) {
1492
					ret = -EFAULT;
1493
					goto out;
1494
				}
1495
				copied++;
1496
			}
1497
		} else {
1498
			for (i = mode_group->num_crtcs; i < mode_group->num_crtcs + mode_group->num_encoders; i++) {
1499
				if (put_user(mode_group->id_list[i],
1500
					     encoder_id + copied)) {
1501
					ret = -EFAULT;
1502
					goto out;
1503
				}
1504
				copied++;
1505
			}
1506
 
1507
		}
1508
	}
1509
	card_res->count_encoders = encoder_count;
1510
 
1511
	/* Connectors */
1512
	if (card_res->count_connectors >= connector_count) {
1513
		copied = 0;
1514
		connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr;
1515
		if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1516
			list_for_each_entry(connector,
1517
					    &dev->mode_config.connector_list,
1518
					    head) {
1963 serge 1519
				DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
1520
					connector->base.id,
1521
					drm_get_connector_name(connector));
1123 serge 1522
				if (put_user(connector->base.id,
1523
					     connector_id + copied)) {
1524
					ret = -EFAULT;
1525
					goto out;
1526
				}
1527
				copied++;
1528
			}
1529
		} else {
1530
			int start = mode_group->num_crtcs +
1531
				mode_group->num_encoders;
1532
			for (i = start; i < start + mode_group->num_connectors; i++) {
1533
				if (put_user(mode_group->id_list[i],
1534
					     connector_id + copied)) {
1535
					ret = -EFAULT;
1536
					goto out;
1537
				}
1538
				copied++;
1539
			}
1540
		}
1541
	}
1542
	card_res->count_connectors = connector_count;
1543
 
1963 serge 1544
	DRM_DEBUG_KMS("CRTC[%d] CONNECTORS[%d] ENCODERS[%d]\n", card_res->count_crtcs,
1123 serge 1545
		  card_res->count_connectors, card_res->count_encoders);
1546
 
1547
out:
3480 Serge 1548
	drm_modeset_unlock_all(dev);
1123 serge 1549
	return ret;
1550
}
1551
 
1552
/**
1553
 * drm_mode_getcrtc - get CRTC configuration
3480 Serge 1554
 * @dev: drm device for the ioctl
1555
 * @data: data pointer for the ioctl
1556
 * @file_priv: drm file for the ioctl call
1123 serge 1557
 *
1558
 * Construct a CRTC configuration structure to return to the user.
1559
 *
1560
 * Called by the user via ioctl.
1561
 *
1562
 * RETURNS:
1563
 * Zero on success, errno on failure.
1564
 */
1565
int drm_mode_getcrtc(struct drm_device *dev,
1566
		     void *data, struct drm_file *file_priv)
1567
{
1568
	struct drm_mode_crtc *crtc_resp = data;
1569
	struct drm_crtc *crtc;
1570
	struct drm_mode_object *obj;
1571
	int ret = 0;
1572
 
1963 serge 1573
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
1574
		return -EINVAL;
1575
 
3480 Serge 1576
	drm_modeset_lock_all(dev);
1123 serge 1577
 
1578
	obj = drm_mode_object_find(dev, crtc_resp->crtc_id,
1579
				   DRM_MODE_OBJECT_CRTC);
1580
	if (!obj) {
4560 Serge 1581
		ret = -ENOENT;
1123 serge 1582
		goto out;
1583
	}
1584
	crtc = obj_to_crtc(obj);
1585
 
1586
	crtc_resp->x = crtc->x;
1587
	crtc_resp->y = crtc->y;
1588
	crtc_resp->gamma_size = crtc->gamma_size;
1589
	if (crtc->fb)
1590
		crtc_resp->fb_id = crtc->fb->base.id;
1591
	else
1592
		crtc_resp->fb_id = 0;
1593
 
1594
	if (crtc->enabled) {
1595
 
1596
		drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode);
1597
		crtc_resp->mode_valid = 1;
1598
 
1599
	} else {
1600
		crtc_resp->mode_valid = 0;
1601
	}
1602
 
1603
out:
3480 Serge 1604
	drm_modeset_unlock_all(dev);
1123 serge 1605
	return ret;
1606
}
1607
 
4560 Serge 1608
static bool drm_mode_expose_to_userspace(const struct drm_display_mode *mode,
1609
					 const struct drm_file *file_priv)
1610
{
1611
	/*
1612
	 * If user-space hasn't configured the driver to expose the stereo 3D
1613
	 * modes, don't expose them.
1614
	 */
1615
	if (!file_priv->stereo_allowed && drm_mode_is_stereo(mode))
1616
		return false;
1617
 
1618
	return true;
1619
}
1620
 
1123 serge 1621
/**
1622
 * drm_mode_getconnector - get connector configuration
3480 Serge 1623
 * @dev: drm device for the ioctl
1624
 * @data: data pointer for the ioctl
1625
 * @file_priv: drm file for the ioctl call
1123 serge 1626
 *
1627
 * Construct a connector configuration structure to return to the user.
1628
 *
1629
 * Called by the user via ioctl.
1630
 *
1631
 * RETURNS:
1632
 * Zero on success, errno on failure.
1633
 */
1634
int drm_mode_getconnector(struct drm_device *dev, void *data,
1635
			  struct drm_file *file_priv)
1636
{
1637
	struct drm_mode_get_connector *out_resp = data;
1638
	struct drm_mode_object *obj;
1639
	struct drm_connector *connector;
1640
	struct drm_display_mode *mode;
1641
	int mode_count = 0;
1642
	int props_count = 0;
1643
	int encoders_count = 0;
1644
	int ret = 0;
1645
	int copied = 0;
1646
	int i;
1647
	struct drm_mode_modeinfo u_mode;
1648
	struct drm_mode_modeinfo __user *mode_ptr;
1649
	uint32_t __user *prop_ptr;
1650
	uint64_t __user *prop_values;
1651
	uint32_t __user *encoder_ptr;
1652
 
1963 serge 1653
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
1654
		return -EINVAL;
1655
 
1123 serge 1656
	memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
1657
 
1963 serge 1658
	DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id);
1123 serge 1659
 
1660
	mutex_lock(&dev->mode_config.mutex);
1661
 
1662
	obj = drm_mode_object_find(dev, out_resp->connector_id,
1663
				   DRM_MODE_OBJECT_CONNECTOR);
1664
	if (!obj) {
4560 Serge 1665
		ret = -ENOENT;
1123 serge 1666
		goto out;
1667
	}
1668
	connector = obj_to_connector(obj);
1669
 
3031 serge 1670
	props_count = connector->properties.count;
1123 serge 1671
 
1672
	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1673
		if (connector->encoder_ids[i] != 0) {
1674
			encoders_count++;
1675
		}
1676
	}
1677
 
1678
	if (out_resp->count_modes == 0) {
1679
		connector->funcs->fill_modes(connector,
1680
					     dev->mode_config.max_width,
1681
					     dev->mode_config.max_height);
1682
	}
1683
 
1684
	/* delayed so we get modes regardless of pre-fill_modes state */
1685
	list_for_each_entry(mode, &connector->modes, head)
4560 Serge 1686
		if (drm_mode_expose_to_userspace(mode, file_priv))
1123 serge 1687
		mode_count++;
1688
 
1689
	out_resp->connector_id = connector->base.id;
1690
	out_resp->connector_type = connector->connector_type;
1691
	out_resp->connector_type_id = connector->connector_type_id;
1692
	out_resp->mm_width = connector->display_info.width_mm;
1693
	out_resp->mm_height = connector->display_info.height_mm;
1694
	out_resp->subpixel = connector->display_info.subpixel_order;
1695
	out_resp->connection = connector->status;
1696
	if (connector->encoder)
1697
		out_resp->encoder_id = connector->encoder->base.id;
1698
	else
1699
		out_resp->encoder_id = 0;
1700
 
1701
	/*
1702
	 * This ioctl is called twice, once to determine how much space is
1703
	 * needed, and the 2nd time to fill it.
1704
	 */
1705
	if ((out_resp->count_modes >= mode_count) && mode_count) {
1706
		copied = 0;
3031 serge 1707
		mode_ptr = (struct drm_mode_modeinfo __user *)(unsigned long)out_resp->modes_ptr;
1123 serge 1708
		list_for_each_entry(mode, &connector->modes, head) {
4560 Serge 1709
			if (!drm_mode_expose_to_userspace(mode, file_priv))
1710
				continue;
1711
 
1123 serge 1712
			drm_crtc_convert_to_umode(&u_mode, mode);
1713
			if (copy_to_user(mode_ptr + copied,
1714
					 &u_mode, sizeof(u_mode))) {
1715
				ret = -EFAULT;
1716
				goto out;
1717
			}
1718
			copied++;
1719
		}
1720
	}
1721
	out_resp->count_modes = mode_count;
1722
 
1723
	if ((out_resp->count_props >= props_count) && props_count) {
1724
		copied = 0;
3031 serge 1725
		prop_ptr = (uint32_t __user *)(unsigned long)(out_resp->props_ptr);
1726
		prop_values = (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr);
1727
		for (i = 0; i < connector->properties.count; i++) {
1728
			if (put_user(connector->properties.ids[i],
1123 serge 1729
					     prop_ptr + copied)) {
1730
					ret = -EFAULT;
1731
					goto out;
1732
				}
1733
 
3031 serge 1734
			if (put_user(connector->properties.values[i],
1123 serge 1735
					     prop_values + copied)) {
1736
					ret = -EFAULT;
1737
					goto out;
1738
				}
1739
				copied++;
1740
			}
1741
		}
1742
	out_resp->count_props = props_count;
1743
 
1744
	if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
1745
		copied = 0;
3031 serge 1746
		encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr);
1123 serge 1747
		for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1748
			if (connector->encoder_ids[i] != 0) {
1749
				if (put_user(connector->encoder_ids[i],
1750
					     encoder_ptr + copied)) {
1751
					ret = -EFAULT;
1752
					goto out;
1753
				}
1754
				copied++;
1755
			}
1756
		}
1757
	}
1758
	out_resp->count_encoders = encoders_count;
1759
 
1760
out:
1761
	mutex_unlock(&dev->mode_config.mutex);
3480 Serge 1762
 
1123 serge 1763
	return ret;
1764
}
1765
 
1766
int drm_mode_getencoder(struct drm_device *dev, void *data,
1767
			struct drm_file *file_priv)
1768
{
1769
	struct drm_mode_get_encoder *enc_resp = data;
1770
	struct drm_mode_object *obj;
1771
	struct drm_encoder *encoder;
1772
	int ret = 0;
1773
 
1963 serge 1774
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
1775
		return -EINVAL;
1776
 
3480 Serge 1777
	drm_modeset_lock_all(dev);
1123 serge 1778
	obj = drm_mode_object_find(dev, enc_resp->encoder_id,
1779
				   DRM_MODE_OBJECT_ENCODER);
1780
	if (!obj) {
4560 Serge 1781
		ret = -ENOENT;
1123 serge 1782
		goto out;
1783
	}
1784
	encoder = obj_to_encoder(obj);
1785
 
1786
	if (encoder->crtc)
1787
		enc_resp->crtc_id = encoder->crtc->base.id;
1788
	else
1789
		enc_resp->crtc_id = 0;
1790
	enc_resp->encoder_type = encoder->encoder_type;
1791
	enc_resp->encoder_id = encoder->base.id;
1792
	enc_resp->possible_crtcs = encoder->possible_crtcs;
1793
	enc_resp->possible_clones = encoder->possible_clones;
1794
 
1795
out:
3480 Serge 1796
	drm_modeset_unlock_all(dev);
1123 serge 1797
	return ret;
1798
}
1799
 
1800
/**
3031 serge 1801
 * drm_mode_getplane_res - get plane info
1802
 * @dev: DRM device
1803
 * @data: ioctl data
1804
 * @file_priv: DRM file info
1805
 *
1806
 * Return an plane count and set of IDs.
1807
 */
1808
int drm_mode_getplane_res(struct drm_device *dev, void *data,
1809
			    struct drm_file *file_priv)
1810
{
1811
	struct drm_mode_get_plane_res *plane_resp = data;
1812
	struct drm_mode_config *config;
1813
	struct drm_plane *plane;
1814
	uint32_t __user *plane_ptr;
1815
	int copied = 0, ret = 0;
1816
 
1817
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
1818
		return -EINVAL;
1819
 
3480 Serge 1820
	drm_modeset_lock_all(dev);
3031 serge 1821
	config = &dev->mode_config;
1822
 
1823
	/*
1824
	 * This ioctl is called twice, once to determine how much space is
1825
	 * needed, and the 2nd time to fill it.
1826
	 */
1827
	if (config->num_plane &&
1828
	    (plane_resp->count_planes >= config->num_plane)) {
1829
		plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr;
1830
 
1831
		list_for_each_entry(plane, &config->plane_list, head) {
1832
			if (put_user(plane->base.id, plane_ptr + copied)) {
1833
				ret = -EFAULT;
1834
				goto out;
1835
			}
1836
			copied++;
1837
		}
1838
	}
1839
	plane_resp->count_planes = config->num_plane;
1840
 
1841
out:
3480 Serge 1842
	drm_modeset_unlock_all(dev);
3031 serge 1843
	return ret;
1844
}
1845
 
1846
/**
1847
 * drm_mode_getplane - get plane info
1848
 * @dev: DRM device
1849
 * @data: ioctl data
1850
 * @file_priv: DRM file info
1851
 *
1852
 * Return plane info, including formats supported, gamma size, any
1853
 * current fb, etc.
1854
 */
1855
int drm_mode_getplane(struct drm_device *dev, void *data,
1856
			struct drm_file *file_priv)
1857
{
1858
	struct drm_mode_get_plane *plane_resp = data;
1859
	struct drm_mode_object *obj;
1860
	struct drm_plane *plane;
1861
	uint32_t __user *format_ptr;
1862
	int ret = 0;
1863
 
1864
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
1865
		return -EINVAL;
1866
 
3480 Serge 1867
	drm_modeset_lock_all(dev);
3031 serge 1868
	obj = drm_mode_object_find(dev, plane_resp->plane_id,
1869
				   DRM_MODE_OBJECT_PLANE);
1870
	if (!obj) {
1871
		ret = -ENOENT;
1872
		goto out;
1873
	}
1874
	plane = obj_to_plane(obj);
1875
 
1876
	if (plane->crtc)
1877
		plane_resp->crtc_id = plane->crtc->base.id;
1878
	else
1879
		plane_resp->crtc_id = 0;
1880
 
1881
	if (plane->fb)
1882
		plane_resp->fb_id = plane->fb->base.id;
1883
	else
1884
		plane_resp->fb_id = 0;
1885
 
1886
	plane_resp->plane_id = plane->base.id;
1887
	plane_resp->possible_crtcs = plane->possible_crtcs;
4075 Serge 1888
	plane_resp->gamma_size = 0;
3031 serge 1889
 
1890
	/*
1891
	 * This ioctl is called twice, once to determine how much space is
1892
	 * needed, and the 2nd time to fill it.
1893
	 */
1894
	if (plane->format_count &&
1895
	    (plane_resp->count_format_types >= plane->format_count)) {
1896
		format_ptr = (uint32_t __user *)(unsigned long)plane_resp->format_type_ptr;
1897
		if (copy_to_user(format_ptr,
1898
				 plane->format_types,
1899
				 sizeof(uint32_t) * plane->format_count)) {
1900
			ret = -EFAULT;
1901
			goto out;
1902
		}
1903
	}
1904
	plane_resp->count_format_types = plane->format_count;
1905
 
1906
out:
3480 Serge 1907
	drm_modeset_unlock_all(dev);
3031 serge 1908
	return ret;
1909
}
1910
 
1911
/**
1912
 * drm_mode_setplane - set up or tear down an plane
1913
 * @dev: DRM device
1914
 * @data: ioctl data*
3480 Serge 1915
 * @file_priv: DRM file info
3031 serge 1916
 *
1917
 * Set plane info, including placement, fb, scaling, and other factors.
1918
 * Or pass a NULL fb to disable.
1919
 */
1920
int drm_mode_setplane(struct drm_device *dev, void *data,
1921
			struct drm_file *file_priv)
1922
{
1923
	struct drm_mode_set_plane *plane_req = data;
1924
	struct drm_mode_object *obj;
1925
	struct drm_plane *plane;
1926
	struct drm_crtc *crtc;
3480 Serge 1927
	struct drm_framebuffer *fb = NULL, *old_fb = NULL;
3031 serge 1928
	int ret = 0;
1929
	unsigned int fb_width, fb_height;
1930
	int i;
1931
 
1932
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
1933
		return -EINVAL;
1934
 
1935
	/*
1936
	 * First, find the plane, crtc, and fb objects.  If not available,
1937
	 * we don't bother to call the driver.
1938
	 */
1939
	obj = drm_mode_object_find(dev, plane_req->plane_id,
1940
				   DRM_MODE_OBJECT_PLANE);
1941
	if (!obj) {
1942
		DRM_DEBUG_KMS("Unknown plane ID %d\n",
1943
			      plane_req->plane_id);
3480 Serge 1944
		return -ENOENT;
3031 serge 1945
	}
1946
	plane = obj_to_plane(obj);
1947
 
1948
	/* No fb means shut it down */
1949
	if (!plane_req->fb_id) {
3480 Serge 1950
		drm_modeset_lock_all(dev);
1951
		old_fb = plane->fb;
3031 serge 1952
		plane->funcs->disable_plane(plane);
1953
		plane->crtc = NULL;
1954
		plane->fb = NULL;
3480 Serge 1955
		drm_modeset_unlock_all(dev);
3031 serge 1956
		goto out;
1957
	}
1958
 
1959
	obj = drm_mode_object_find(dev, plane_req->crtc_id,
1960
				   DRM_MODE_OBJECT_CRTC);
1961
	if (!obj) {
1962
		DRM_DEBUG_KMS("Unknown crtc ID %d\n",
1963
			      plane_req->crtc_id);
1964
		ret = -ENOENT;
1965
		goto out;
1966
	}
1967
	crtc = obj_to_crtc(obj);
1968
 
3480 Serge 1969
	fb = drm_framebuffer_lookup(dev, plane_req->fb_id);
1970
	if (!fb) {
3031 serge 1971
		DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
1972
			      plane_req->fb_id);
1973
		ret = -ENOENT;
1974
		goto out;
1975
	}
1976
 
1977
	/* Check whether this plane supports the fb pixel format. */
1978
	for (i = 0; i < plane->format_count; i++)
1979
		if (fb->pixel_format == plane->format_types[i])
1980
			break;
1981
	if (i == plane->format_count) {
4075 Serge 1982
		DRM_DEBUG_KMS("Invalid pixel format %s\n",
1983
			      drm_get_format_name(fb->pixel_format));
3031 serge 1984
		ret = -EINVAL;
1985
		goto out;
1986
	}
1987
 
1988
	fb_width = fb->width << 16;
1989
	fb_height = fb->height << 16;
1990
 
1991
	/* Make sure source coordinates are inside the fb. */
1992
	if (plane_req->src_w > fb_width ||
1993
	    plane_req->src_x > fb_width - plane_req->src_w ||
1994
	    plane_req->src_h > fb_height ||
1995
	    plane_req->src_y > fb_height - plane_req->src_h) {
1996
		DRM_DEBUG_KMS("Invalid source coordinates "
1997
			      "%u.%06ux%u.%06u+%u.%06u+%u.%06u\n",
1998
			      plane_req->src_w >> 16,
1999
			      ((plane_req->src_w & 0xffff) * 15625) >> 10,
2000
			      plane_req->src_h >> 16,
2001
			      ((plane_req->src_h & 0xffff) * 15625) >> 10,
2002
			      plane_req->src_x >> 16,
2003
			      ((plane_req->src_x & 0xffff) * 15625) >> 10,
2004
			      plane_req->src_y >> 16,
2005
			      ((plane_req->src_y & 0xffff) * 15625) >> 10);
2006
		ret = -ENOSPC;
2007
		goto out;
2008
	}
2009
 
2010
	/* Give drivers some help against integer overflows */
2011
	if (plane_req->crtc_w > INT_MAX ||
2012
	    plane_req->crtc_x > INT_MAX - (int32_t) plane_req->crtc_w ||
2013
	    plane_req->crtc_h > INT_MAX ||
2014
	    plane_req->crtc_y > INT_MAX - (int32_t) plane_req->crtc_h) {
2015
		DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n",
2016
			      plane_req->crtc_w, plane_req->crtc_h,
2017
			      plane_req->crtc_x, plane_req->crtc_y);
2018
		ret = -ERANGE;
2019
		goto out;
2020
	}
2021
 
3480 Serge 2022
	drm_modeset_lock_all(dev);
3031 serge 2023
	ret = plane->funcs->update_plane(plane, crtc, fb,
2024
					 plane_req->crtc_x, plane_req->crtc_y,
2025
					 plane_req->crtc_w, plane_req->crtc_h,
2026
					 plane_req->src_x, plane_req->src_y,
2027
					 plane_req->src_w, plane_req->src_h);
2028
	if (!ret) {
3480 Serge 2029
		old_fb = plane->fb;
3031 serge 2030
		plane->crtc = crtc;
2031
		plane->fb = fb;
3480 Serge 2032
		fb = NULL;
3031 serge 2033
	}
3480 Serge 2034
	drm_modeset_unlock_all(dev);
3031 serge 2035
 
2036
out:
3480 Serge 2037
	if (fb)
2038
		drm_framebuffer_unreference(fb);
2039
	if (old_fb)
2040
		drm_framebuffer_unreference(old_fb);
3031 serge 2041
 
2042
	return ret;
2043
}
3480 Serge 2044
#endif
3031 serge 2045
 
2046
/**
3480 Serge 2047
 * drm_mode_set_config_internal - helper to call ->set_config
2048
 * @set: modeset config to set
2049
 *
2050
 * This is a little helper to wrap internal calls to the ->set_config driver
2051
 * interface. The only thing it adds is correct refcounting dance.
2052
 */
2053
int drm_mode_set_config_internal(struct drm_mode_set *set)
2054
{
2055
	struct drm_crtc *crtc = set->crtc;
4075 Serge 2056
	struct drm_framebuffer *fb;
2057
	struct drm_crtc *tmp;
3480 Serge 2058
	int ret;
2059
 
4075 Serge 2060
	/*
2061
	 * NOTE: ->set_config can also disable other crtcs (if we steal all
2062
	 * connectors from it), hence we need to refcount the fbs across all
2063
	 * crtcs. Atomic modeset will have saner semantics ...
2064
	 */
2065
	list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head)
2066
		tmp->old_fb = tmp->fb;
2067
 
3480 Serge 2068
	fb = set->fb;
2069
 
2070
	ret = crtc->funcs->set_config(set);
2071
	if (ret == 0) {
4075 Serge 2072
		/* crtc->fb must be updated by ->set_config, enforces this. */
2073
		WARN_ON(fb != crtc->fb);
3480 Serge 2074
	}
2075
 
4075 Serge 2076
	list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) {
2077
		if (tmp->fb)
2078
			drm_framebuffer_reference(tmp->fb);
2079
//		if (tmp->old_fb)
2080
//			drm_framebuffer_unreference(tmp->old_fb);
2081
	}
2082
 
3480 Serge 2083
	return ret;
2084
}
2085
EXPORT_SYMBOL(drm_mode_set_config_internal);
2086
 
2087
#if 0
4560 Serge 2088
/*
2089
 * Checks that the framebuffer is big enough for the CRTC viewport
2090
 * (x, y, hdisplay, vdisplay)
2091
 */
2092
static int drm_crtc_check_viewport(const struct drm_crtc *crtc,
2093
				   int x, int y,
2094
				   const struct drm_display_mode *mode,
2095
				   const struct drm_framebuffer *fb)
2096
 
2097
{
2098
	int hdisplay, vdisplay;
2099
 
2100
	hdisplay = mode->hdisplay;
2101
	vdisplay = mode->vdisplay;
2102
 
2103
	if (drm_mode_is_stereo(mode)) {
2104
		struct drm_display_mode adjusted = *mode;
2105
 
2106
		drm_mode_set_crtcinfo(&adjusted, CRTC_STEREO_DOUBLE);
2107
		hdisplay = adjusted.crtc_hdisplay;
2108
		vdisplay = adjusted.crtc_vdisplay;
2109
	}
2110
 
2111
	if (crtc->invert_dimensions)
2112
		swap(hdisplay, vdisplay);
2113
 
2114
	if (hdisplay > fb->width ||
2115
	    vdisplay > fb->height ||
2116
	    x > fb->width - hdisplay ||
2117
	    y > fb->height - vdisplay) {
2118
		DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
2119
			      fb->width, fb->height, hdisplay, vdisplay, x, y,
2120
			      crtc->invert_dimensions ? " (inverted)" : "");
2121
		return -ENOSPC;
2122
	}
2123
 
2124
	return 0;
2125
}
2126
 
3480 Serge 2127
/**
1123 serge 2128
 * drm_mode_setcrtc - set CRTC configuration
3480 Serge 2129
 * @dev: drm device for the ioctl
2130
 * @data: data pointer for the ioctl
2131
 * @file_priv: drm file for the ioctl call
1123 serge 2132
 *
2133
 * Build a new CRTC configuration based on user request.
2134
 *
2135
 * Called by the user via ioctl.
2136
 *
2137
 * RETURNS:
2138
 * Zero on success, errno on failure.
2139
 */
2140
int drm_mode_setcrtc(struct drm_device *dev, void *data,
2141
		     struct drm_file *file_priv)
2142
{
2143
	struct drm_mode_config *config = &dev->mode_config;
2144
	struct drm_mode_crtc *crtc_req = data;
2145
	struct drm_mode_object *obj;
3031 serge 2146
	struct drm_crtc *crtc;
1123 serge 2147
	struct drm_connector **connector_set = NULL, *connector;
2148
	struct drm_framebuffer *fb = NULL;
2149
	struct drm_display_mode *mode = NULL;
2150
	struct drm_mode_set set;
2151
	uint32_t __user *set_connectors_ptr;
3031 serge 2152
	int ret;
1123 serge 2153
	int i;
2154
 
1963 serge 2155
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
2156
		return -EINVAL;
2157
 
3031 serge 2158
	/* For some reason crtc x/y offsets are signed internally. */
2159
	if (crtc_req->x > INT_MAX || crtc_req->y > INT_MAX)
2160
		return -ERANGE;
2161
 
3480 Serge 2162
	drm_modeset_lock_all(dev);
1123 serge 2163
	obj = drm_mode_object_find(dev, crtc_req->crtc_id,
2164
				   DRM_MODE_OBJECT_CRTC);
2165
	if (!obj) {
1179 serge 2166
		DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
4560 Serge 2167
		ret = -ENOENT;
1123 serge 2168
		goto out;
2169
	}
2170
	crtc = obj_to_crtc(obj);
1963 serge 2171
	DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
1123 serge 2172
 
2173
	if (crtc_req->mode_valid) {
2174
		/* If we have a mode we need a framebuffer. */
2175
		/* If we pass -1, set the mode with the currently bound fb */
2176
		if (crtc_req->fb_id == -1) {
3031 serge 2177
			if (!crtc->fb) {
2178
				DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
2179
				ret = -EINVAL;
2180
				goto out;
2181
			}
1123 serge 2182
					fb = crtc->fb;
3480 Serge 2183
			/* Make refcounting symmetric with the lookup path. */
2184
			drm_framebuffer_reference(fb);
1123 serge 2185
		} else {
3480 Serge 2186
			fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);
2187
			if (!fb) {
1179 serge 2188
				DRM_DEBUG_KMS("Unknown FB ID%d\n",
2189
						crtc_req->fb_id);
4560 Serge 2190
				ret = -ENOENT;
1123 serge 2191
				goto out;
2192
			}
2193
		}
2194
 
2195
		mode = drm_mode_create(dev);
3031 serge 2196
		if (!mode) {
2197
			ret = -ENOMEM;
2198
			goto out;
2199
		}
2200
 
2201
		ret = drm_crtc_convert_umode(mode, &crtc_req->mode);
2202
		if (ret) {
2203
			DRM_DEBUG_KMS("Invalid mode\n");
2204
			goto out;
2205
		}
2206
 
1123 serge 2207
		drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
3031 serge 2208
 
4560 Serge 2209
		ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,
2210
					      mode, fb);
2211
		if (ret)
2212
			goto out;
3031 serge 2213
 
1123 serge 2214
	}
2215
 
2216
	if (crtc_req->count_connectors == 0 && mode) {
1179 serge 2217
		DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
1123 serge 2218
		ret = -EINVAL;
2219
		goto out;
2220
	}
2221
 
1179 serge 2222
	if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
2223
		DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
1123 serge 2224
			  crtc_req->count_connectors);
2225
		ret = -EINVAL;
2226
		goto out;
2227
	}
2228
 
2229
	if (crtc_req->count_connectors > 0) {
2230
		u32 out_id;
2231
 
2232
		/* Avoid unbounded kernel memory allocation */
2233
		if (crtc_req->count_connectors > config->num_connector) {
2234
			ret = -EINVAL;
2235
			goto out;
2236
		}
2237
 
2238
		connector_set = kmalloc(crtc_req->count_connectors *
2239
					sizeof(struct drm_connector *),
2240
					GFP_KERNEL);
2241
		if (!connector_set) {
2242
			ret = -ENOMEM;
2243
			goto out;
2244
		}
2245
 
2246
		for (i = 0; i < crtc_req->count_connectors; i++) {
3031 serge 2247
			set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr;
1123 serge 2248
			if (get_user(out_id, &set_connectors_ptr[i])) {
2249
				ret = -EFAULT;
2250
				goto out;
2251
			}
2252
 
2253
			obj = drm_mode_object_find(dev, out_id,
2254
						   DRM_MODE_OBJECT_CONNECTOR);
2255
			if (!obj) {
1179 serge 2256
				DRM_DEBUG_KMS("Connector id %d unknown\n",
2257
						out_id);
4560 Serge 2258
				ret = -ENOENT;
1123 serge 2259
				goto out;
2260
			}
2261
			connector = obj_to_connector(obj);
1963 serge 2262
			DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
2263
					connector->base.id,
2264
					drm_get_connector_name(connector));
1123 serge 2265
 
2266
			connector_set[i] = connector;
2267
		}
2268
	}
2269
 
2270
	set.crtc = crtc;
2271
	set.x = crtc_req->x;
2272
	set.y = crtc_req->y;
2273
	set.mode = mode;
2274
	set.connectors = connector_set;
2275
	set.num_connectors = crtc_req->count_connectors;
1179 serge 2276
	set.fb = fb;
3480 Serge 2277
	ret = drm_mode_set_config_internal(&set);
1123 serge 2278
 
2279
out:
3480 Serge 2280
	if (fb)
2281
		drm_framebuffer_unreference(fb);
2282
 
1123 serge 2283
	kfree(connector_set);
3031 serge 2284
	drm_mode_destroy(dev, mode);
3480 Serge 2285
	drm_modeset_unlock_all(dev);
1123 serge 2286
	return ret;
2287
}
2288
 
4075 Serge 2289
static int drm_mode_cursor_common(struct drm_device *dev,
2290
				  struct drm_mode_cursor2 *req,
2291
				  struct drm_file *file_priv)
1123 serge 2292
{
2293
	struct drm_mode_object *obj;
2294
	struct drm_crtc *crtc;
2295
	int ret = 0;
2296
 
1963 serge 2297
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
2298
		return -EINVAL;
2299
 
3031 serge 2300
	if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags))
1123 serge 2301
		return -EINVAL;
2302
 
2303
	obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC);
2304
	if (!obj) {
1179 serge 2305
		DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
4560 Serge 2306
		return -ENOENT;
1123 serge 2307
	}
2308
	crtc = obj_to_crtc(obj);
2309
 
3480 Serge 2310
	mutex_lock(&crtc->mutex);
1123 serge 2311
	if (req->flags & DRM_MODE_CURSOR_BO) {
4075 Serge 2312
		if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) {
1123 serge 2313
			ret = -ENXIO;
2314
			goto out;
2315
		}
2316
		/* Turns off the cursor if handle is 0 */
4075 Serge 2317
		if (crtc->funcs->cursor_set2)
2318
			ret = crtc->funcs->cursor_set2(crtc, file_priv, req->handle,
2319
						      req->width, req->height, req->hot_x, req->hot_y);
2320
		else
1123 serge 2321
		ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
2322
					      req->width, req->height);
2323
	}
2324
 
2325
	if (req->flags & DRM_MODE_CURSOR_MOVE) {
2326
		if (crtc->funcs->cursor_move) {
2327
			ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
2328
		} else {
2329
			ret = -EFAULT;
2330
			goto out;
2331
		}
2332
	}
2333
out:
3480 Serge 2334
	mutex_unlock(&crtc->mutex);
2335
 
1123 serge 2336
	return ret;
4075 Serge 2337
 
1123 serge 2338
}
4075 Serge 2339
int drm_mode_cursor_ioctl(struct drm_device *dev,
2340
			void *data, struct drm_file *file_priv)
2341
{
2342
	struct drm_mode_cursor *req = data;
2343
	struct drm_mode_cursor2 new_req;
2344
 
2345
	memcpy(&new_req, req, sizeof(struct drm_mode_cursor));
2346
	new_req.hot_x = new_req.hot_y = 0;
2347
 
2348
	return drm_mode_cursor_common(dev, &new_req, file_priv);
2349
}
2350
 
2351
int drm_mode_cursor2_ioctl(struct drm_device *dev,
2352
			   void *data, struct drm_file *file_priv)
2353
{
2354
	struct drm_mode_cursor2 *req = data;
2355
	return drm_mode_cursor_common(dev, req, file_priv);
2356
}
3031 serge 2357
#endif
4560 Serge 2358
 
3031 serge 2359
/* Original addfb only supported RGB formats, so figure out which one */
2360
uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)
2361
{
2362
	uint32_t fmt;
1123 serge 2363
 
3031 serge 2364
	switch (bpp) {
2365
	case 8:
3480 Serge 2366
		fmt = DRM_FORMAT_C8;
3031 serge 2367
		break;
2368
	case 16:
2369
		if (depth == 15)
2370
			fmt = DRM_FORMAT_XRGB1555;
2371
		else
2372
			fmt = DRM_FORMAT_RGB565;
2373
		break;
2374
	case 24:
2375
		fmt = DRM_FORMAT_RGB888;
2376
		break;
2377
	case 32:
2378
		if (depth == 24)
2379
			fmt = DRM_FORMAT_XRGB8888;
2380
		else if (depth == 30)
2381
			fmt = DRM_FORMAT_XRGB2101010;
2382
		else
2383
			fmt = DRM_FORMAT_ARGB8888;
2384
		break;
2385
	default:
2386
		DRM_ERROR("bad bpp, assuming x8r8g8b8 pixel format\n");
2387
		fmt = DRM_FORMAT_XRGB8888;
2388
		break;
2389
	}
2390
 
2391
	return fmt;
2392
}
2393
EXPORT_SYMBOL(drm_mode_legacy_fb_format);
2394
#if 0
1123 serge 2395
/**
2396
 * drm_mode_addfb - add an FB to the graphics configuration
3480 Serge 2397
 * @dev: drm device for the ioctl
2398
 * @data: data pointer for the ioctl
2399
 * @file_priv: drm file for the ioctl call
1123 serge 2400
 *
2401
 * Add a new FB to the specified CRTC, given a user request.
2402
 *
2403
 * Called by the user via ioctl.
2404
 *
2405
 * RETURNS:
2406
 * Zero on success, errno on failure.
2407
 */
2408
int drm_mode_addfb(struct drm_device *dev,
2409
		   void *data, struct drm_file *file_priv)
2410
{
3031 serge 2411
	struct drm_mode_fb_cmd *or = data;
2412
	struct drm_mode_fb_cmd2 r = {};
1123 serge 2413
	struct drm_mode_config *config = &dev->mode_config;
2414
	struct drm_framebuffer *fb;
2415
	int ret = 0;
2416
 
3031 serge 2417
	/* Use new struct with format internally */
2418
	r.fb_id = or->fb_id;
2419
	r.width = or->width;
2420
	r.height = or->height;
2421
	r.pitches[0] = or->pitch;
2422
	r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
2423
	r.handles[0] = or->handle;
2424
 
1963 serge 2425
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
2426
		return -EINVAL;
2427
 
3031 serge 2428
	if ((config->min_width > r.width) || (r.width > config->max_width))
2429
		return -EINVAL;
2430
 
2431
	if ((config->min_height > r.height) || (r.height > config->max_height))
2432
		return -EINVAL;
2433
 
2434
	fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r);
2435
	if (IS_ERR(fb)) {
2436
		DRM_DEBUG_KMS("could not create framebuffer\n");
3480 Serge 2437
		return PTR_ERR(fb);
3031 serge 2438
	}
2439
 
3480 Serge 2440
	mutex_lock(&file_priv->fbs_lock);
3031 serge 2441
	or->fb_id = fb->base.id;
2442
	list_add(&fb->filp_head, &file_priv->fbs);
2443
	DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
3480 Serge 2444
	mutex_unlock(&file_priv->fbs_lock);
3031 serge 2445
 
2446
	return ret;
2447
}
2448
 
2449
static int format_check(const struct drm_mode_fb_cmd2 *r)
2450
{
2451
	uint32_t format = r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN;
2452
 
2453
	switch (format) {
2454
	case DRM_FORMAT_C8:
2455
	case DRM_FORMAT_RGB332:
2456
	case DRM_FORMAT_BGR233:
2457
	case DRM_FORMAT_XRGB4444:
2458
	case DRM_FORMAT_XBGR4444:
2459
	case DRM_FORMAT_RGBX4444:
2460
	case DRM_FORMAT_BGRX4444:
2461
	case DRM_FORMAT_ARGB4444:
2462
	case DRM_FORMAT_ABGR4444:
2463
	case DRM_FORMAT_RGBA4444:
2464
	case DRM_FORMAT_BGRA4444:
2465
	case DRM_FORMAT_XRGB1555:
2466
	case DRM_FORMAT_XBGR1555:
2467
	case DRM_FORMAT_RGBX5551:
2468
	case DRM_FORMAT_BGRX5551:
2469
	case DRM_FORMAT_ARGB1555:
2470
	case DRM_FORMAT_ABGR1555:
2471
	case DRM_FORMAT_RGBA5551:
2472
	case DRM_FORMAT_BGRA5551:
2473
	case DRM_FORMAT_RGB565:
2474
	case DRM_FORMAT_BGR565:
2475
	case DRM_FORMAT_RGB888:
2476
	case DRM_FORMAT_BGR888:
2477
	case DRM_FORMAT_XRGB8888:
2478
	case DRM_FORMAT_XBGR8888:
2479
	case DRM_FORMAT_RGBX8888:
2480
	case DRM_FORMAT_BGRX8888:
2481
	case DRM_FORMAT_ARGB8888:
2482
	case DRM_FORMAT_ABGR8888:
2483
	case DRM_FORMAT_RGBA8888:
2484
	case DRM_FORMAT_BGRA8888:
2485
	case DRM_FORMAT_XRGB2101010:
2486
	case DRM_FORMAT_XBGR2101010:
2487
	case DRM_FORMAT_RGBX1010102:
2488
	case DRM_FORMAT_BGRX1010102:
2489
	case DRM_FORMAT_ARGB2101010:
2490
	case DRM_FORMAT_ABGR2101010:
2491
	case DRM_FORMAT_RGBA1010102:
2492
	case DRM_FORMAT_BGRA1010102:
2493
	case DRM_FORMAT_YUYV:
2494
	case DRM_FORMAT_YVYU:
2495
	case DRM_FORMAT_UYVY:
2496
	case DRM_FORMAT_VYUY:
2497
	case DRM_FORMAT_AYUV:
2498
	case DRM_FORMAT_NV12:
2499
	case DRM_FORMAT_NV21:
2500
	case DRM_FORMAT_NV16:
2501
	case DRM_FORMAT_NV61:
2502
	case DRM_FORMAT_NV24:
2503
	case DRM_FORMAT_NV42:
2504
	case DRM_FORMAT_YUV410:
2505
	case DRM_FORMAT_YVU410:
2506
	case DRM_FORMAT_YUV411:
2507
	case DRM_FORMAT_YVU411:
2508
	case DRM_FORMAT_YUV420:
2509
	case DRM_FORMAT_YVU420:
2510
	case DRM_FORMAT_YUV422:
2511
	case DRM_FORMAT_YVU422:
2512
	case DRM_FORMAT_YUV444:
2513
	case DRM_FORMAT_YVU444:
2514
		return 0;
2515
	default:
4560 Serge 2516
		DRM_DEBUG_KMS("invalid pixel format %s\n",
2517
			      drm_get_format_name(r->pixel_format));
3031 serge 2518
		return -EINVAL;
2519
	}
2520
}
2521
 
2522
static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
2523
{
2524
	int ret, hsub, vsub, num_planes, i;
2525
 
2526
	ret = format_check(r);
2527
	if (ret) {
4075 Serge 2528
		DRM_DEBUG_KMS("bad framebuffer format %s\n",
2529
			      drm_get_format_name(r->pixel_format));
3031 serge 2530
		return ret;
2531
	}
2532
 
2533
	hsub = drm_format_horz_chroma_subsampling(r->pixel_format);
2534
	vsub = drm_format_vert_chroma_subsampling(r->pixel_format);
2535
	num_planes = drm_format_num_planes(r->pixel_format);
2536
 
2537
	if (r->width == 0 || r->width % hsub) {
2538
		DRM_DEBUG_KMS("bad framebuffer width %u\n", r->height);
2539
		return -EINVAL;
2540
	}
2541
 
2542
	if (r->height == 0 || r->height % vsub) {
2543
		DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height);
2544
		return -EINVAL;
2545
	}
2546
 
2547
	for (i = 0; i < num_planes; i++) {
2548
		unsigned int width = r->width / (i != 0 ? hsub : 1);
3192 Serge 2549
		unsigned int height = r->height / (i != 0 ? vsub : 1);
2550
		unsigned int cpp = drm_format_plane_cpp(r->pixel_format, i);
3031 serge 2551
 
2552
		if (!r->handles[i]) {
2553
			DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i);
2554
			return -EINVAL;
2555
		}
2556
 
3192 Serge 2557
		if ((uint64_t) width * cpp > UINT_MAX)
2558
			return -ERANGE;
2559
 
2560
		if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX)
2561
			return -ERANGE;
2562
 
2563
		if (r->pitches[i] < width * cpp) {
3031 serge 2564
			DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i);
2565
			return -EINVAL;
2566
		}
2567
	}
2568
 
2569
	return 0;
2570
}
2571
 
2572
/**
2573
 * drm_mode_addfb2 - add an FB to the graphics configuration
3480 Serge 2574
 * @dev: drm device for the ioctl
2575
 * @data: data pointer for the ioctl
2576
 * @file_priv: drm file for the ioctl call
3031 serge 2577
 *
2578
 * Add a new FB to the specified CRTC, given a user request with format.
2579
 *
2580
 * Called by the user via ioctl.
2581
 *
2582
 * RETURNS:
2583
 * Zero on success, errno on failure.
2584
 */
2585
int drm_mode_addfb2(struct drm_device *dev,
2586
		    void *data, struct drm_file *file_priv)
2587
{
2588
	struct drm_mode_fb_cmd2 *r = data;
2589
	struct drm_mode_config *config = &dev->mode_config;
2590
	struct drm_framebuffer *fb;
2591
	int ret;
2592
 
2593
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
2594
		return -EINVAL;
2595
 
3192 Serge 2596
	if (r->flags & ~DRM_MODE_FB_INTERLACED) {
2597
		DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags);
2598
		return -EINVAL;
2599
	}
2600
 
1123 serge 2601
	if ((config->min_width > r->width) || (r->width > config->max_width)) {
3031 serge 2602
		DRM_DEBUG_KMS("bad framebuffer width %d, should be >= %d && <= %d\n",
2603
			  r->width, config->min_width, config->max_width);
1123 serge 2604
		return -EINVAL;
2605
	}
2606
	if ((config->min_height > r->height) || (r->height > config->max_height)) {
3031 serge 2607
		DRM_DEBUG_KMS("bad framebuffer height %d, should be >= %d && <= %d\n",
2608
			  r->height, config->min_height, config->max_height);
1123 serge 2609
		return -EINVAL;
2610
	}
2611
 
3031 serge 2612
	ret = framebuffer_check(r);
2613
	if (ret)
2614
		return ret;
2615
 
1123 serge 2616
	fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
1963 serge 2617
	if (IS_ERR(fb)) {
3031 serge 2618
		DRM_DEBUG_KMS("could not create framebuffer\n");
3480 Serge 2619
		return PTR_ERR(fb);
1123 serge 2620
	}
2621
 
3480 Serge 2622
	mutex_lock(&file_priv->fbs_lock);
1123 serge 2623
	r->fb_id = fb->base.id;
2624
	list_add(&fb->filp_head, &file_priv->fbs);
1963 serge 2625
	DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
3480 Serge 2626
	mutex_unlock(&file_priv->fbs_lock);
1123 serge 2627
 
3480 Serge 2628
 
1123 serge 2629
	return ret;
2630
}
2631
 
2632
/**
2633
 * drm_mode_rmfb - remove an FB from the configuration
3480 Serge 2634
 * @dev: drm device for the ioctl
2635
 * @data: data pointer for the ioctl
2636
 * @file_priv: drm file for the ioctl call
1123 serge 2637
 *
2638
 * Remove the FB specified by the user.
2639
 *
2640
 * Called by the user via ioctl.
2641
 *
2642
 * RETURNS:
2643
 * Zero on success, errno on failure.
2644
 */
2645
int drm_mode_rmfb(struct drm_device *dev,
2646
		   void *data, struct drm_file *file_priv)
2647
{
2648
	struct drm_framebuffer *fb = NULL;
2649
	struct drm_framebuffer *fbl = NULL;
2650
	uint32_t *id = data;
2651
	int found = 0;
2652
 
1963 serge 2653
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
2654
		return -EINVAL;
2655
 
3480 Serge 2656
	mutex_lock(&file_priv->fbs_lock);
2657
	mutex_lock(&dev->mode_config.fb_lock);
2658
	fb = __drm_framebuffer_lookup(dev, *id);
2659
	if (!fb)
2660
		goto fail_lookup;
1123 serge 2661
 
2662
	list_for_each_entry(fbl, &file_priv->fbs, filp_head)
2663
		if (fb == fbl)
2664
			found = 1;
3480 Serge 2665
	if (!found)
2666
		goto fail_lookup;
1123 serge 2667
 
3480 Serge 2668
	/* Mark fb as reaped, we still have a ref from fpriv->fbs. */
2669
	__drm_framebuffer_unregister(dev, fb);
1123 serge 2670
 
3480 Serge 2671
	list_del_init(&fb->filp_head);
2672
	mutex_unlock(&dev->mode_config.fb_lock);
2673
	mutex_unlock(&file_priv->fbs_lock);
2674
 
3031 serge 2675
	drm_framebuffer_remove(fb);
1123 serge 2676
 
3480 Serge 2677
	return 0;
2678
 
2679
fail_lookup:
2680
	mutex_unlock(&dev->mode_config.fb_lock);
2681
	mutex_unlock(&file_priv->fbs_lock);
2682
 
4560 Serge 2683
	return -ENOENT;
1123 serge 2684
}
2685
 
2686
/**
2687
 * drm_mode_getfb - get FB info
3480 Serge 2688
 * @dev: drm device for the ioctl
2689
 * @data: data pointer for the ioctl
2690
 * @file_priv: drm file for the ioctl call
1123 serge 2691
 *
2692
 * Lookup the FB given its ID and return info about it.
2693
 *
2694
 * Called by the user via ioctl.
2695
 *
2696
 * RETURNS:
2697
 * Zero on success, errno on failure.
2698
 */
2699
int drm_mode_getfb(struct drm_device *dev,
2700
		   void *data, struct drm_file *file_priv)
2701
{
2702
	struct drm_mode_fb_cmd *r = data;
2703
	struct drm_framebuffer *fb;
3480 Serge 2704
	int ret;
1123 serge 2705
 
1963 serge 2706
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
2707
		return -EINVAL;
2708
 
3480 Serge 2709
	fb = drm_framebuffer_lookup(dev, r->fb_id);
2710
	if (!fb)
4560 Serge 2711
		return -ENOENT;
1123 serge 2712
 
2713
	r->height = fb->height;
2714
	r->width = fb->width;
2715
	r->depth = fb->depth;
2716
	r->bpp = fb->bits_per_pixel;
3031 serge 2717
	r->pitch = fb->pitches[0];
4104 Serge 2718
	if (fb->funcs->create_handle) {
2719
		if (file_priv->is_master || capable(CAP_SYS_ADMIN)) {
2720
			ret = fb->funcs->create_handle(fb, file_priv,
2721
						       &r->handle);
2722
		} else {
2723
			/* GET_FB() is an unprivileged ioctl so we must not
2724
			 * return a buffer-handle to non-master processes! For
2725
			 * backwards-compatibility reasons, we cannot make
2726
			 * GET_FB() privileged, so just return an invalid handle
2727
			 * for non-masters. */
2728
			r->handle = 0;
2729
			ret = 0;
2730
		}
2731
	} else {
3480 Serge 2732
		ret = -ENODEV;
4104 Serge 2733
	}
1123 serge 2734
 
3480 Serge 2735
	drm_framebuffer_unreference(fb);
2736
 
1123 serge 2737
	return ret;
2738
}
2739
 
1412 serge 2740
int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
2741
			   void *data, struct drm_file *file_priv)
2742
{
2743
	struct drm_clip_rect __user *clips_ptr;
2744
	struct drm_clip_rect *clips = NULL;
2745
	struct drm_mode_fb_dirty_cmd *r = data;
2746
	struct drm_framebuffer *fb;
2747
	unsigned flags;
2748
	int num_clips;
3031 serge 2749
	int ret;
1412 serge 2750
 
1963 serge 2751
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
2752
		return -EINVAL;
2753
 
3480 Serge 2754
	fb = drm_framebuffer_lookup(dev, r->fb_id);
2755
	if (!fb)
4560 Serge 2756
		return -ENOENT;
1412 serge 2757
 
2758
	num_clips = r->num_clips;
3031 serge 2759
	clips_ptr = (struct drm_clip_rect __user *)(unsigned long)r->clips_ptr;
1412 serge 2760
 
2761
	if (!num_clips != !clips_ptr) {
2762
		ret = -EINVAL;
2763
		goto out_err1;
2764
	}
2765
 
2766
	flags = DRM_MODE_FB_DIRTY_FLAGS & r->flags;
2767
 
2768
	/* If userspace annotates copy, clips must come in pairs */
2769
	if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY && (num_clips % 2)) {
2770
		ret = -EINVAL;
2771
		goto out_err1;
2772
	}
2773
 
2774
	if (num_clips && clips_ptr) {
3031 serge 2775
		if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) {
2776
			ret = -EINVAL;
2777
			goto out_err1;
2778
		}
1412 serge 2779
		clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL);
2780
		if (!clips) {
2781
			ret = -ENOMEM;
2782
			goto out_err1;
2783
		}
2784
 
2785
		ret = copy_from_user(clips, clips_ptr,
2786
				     num_clips * sizeof(*clips));
1963 serge 2787
		if (ret) {
2788
			ret = -EFAULT;
1412 serge 2789
			goto out_err2;
2790
	}
1963 serge 2791
	}
1412 serge 2792
 
2793
	if (fb->funcs->dirty) {
1963 serge 2794
		ret = fb->funcs->dirty(fb, file_priv, flags, r->color,
2795
				       clips, num_clips);
1412 serge 2796
	} else {
2797
		ret = -ENOSYS;
2798
	}
2799
 
2800
out_err2:
2801
	kfree(clips);
2802
out_err1:
3480 Serge 2803
	drm_framebuffer_unreference(fb);
2804
 
1412 serge 2805
	return ret;
2806
}
2807
 
2808
 
1123 serge 2809
/**
2810
 * drm_fb_release - remove and free the FBs on this file
3480 Serge 2811
 * @priv: drm file for the ioctl
1123 serge 2812
 *
2813
 * Destroy all the FBs associated with @filp.
2814
 *
2815
 * Called by the user via ioctl.
2816
 *
2817
 * RETURNS:
2818
 * Zero on success, errno on failure.
2819
 */
2820
void drm_fb_release(struct drm_file *priv)
2821
{
2822
	struct drm_device *dev = priv->minor->dev;
2823
	struct drm_framebuffer *fb, *tfb;
2824
 
3480 Serge 2825
	mutex_lock(&priv->fbs_lock);
1123 serge 2826
	list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
3480 Serge 2827
 
2828
		mutex_lock(&dev->mode_config.fb_lock);
2829
		/* Mark fb as reaped, we still have a ref from fpriv->fbs. */
2830
		__drm_framebuffer_unregister(dev, fb);
2831
		mutex_unlock(&dev->mode_config.fb_lock);
2832
 
2833
		list_del_init(&fb->filp_head);
2834
 
2835
		/* This will also drop the fpriv->fbs reference. */
3031 serge 2836
		drm_framebuffer_remove(fb);
1123 serge 2837
	}
3480 Serge 2838
	mutex_unlock(&priv->fbs_lock);
1123 serge 2839
}
2840
#endif
2841
 
2842
 
2843
struct drm_property *drm_property_create(struct drm_device *dev, int flags,
2844
					 const char *name, int num_values)
2845
{
2846
	struct drm_property *property = NULL;
3031 serge 2847
	int ret;
1123 serge 2848
 
2849
	property = kzalloc(sizeof(struct drm_property), GFP_KERNEL);
2850
	if (!property)
2851
		return NULL;
2852
 
2853
	if (num_values) {
2854
		property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL);
2855
		if (!property->values)
2856
			goto fail;
2857
	}
2858
 
3031 serge 2859
	ret = drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY);
2860
	if (ret)
2861
		goto fail;
2862
 
1123 serge 2863
	property->flags = flags;
2864
	property->num_values = num_values;
2865
	INIT_LIST_HEAD(&property->enum_blob_list);
2866
 
3031 serge 2867
	if (name) {
1123 serge 2868
		strncpy(property->name, name, DRM_PROP_NAME_LEN);
3031 serge 2869
		property->name[DRM_PROP_NAME_LEN-1] = '\0';
2870
	}
1123 serge 2871
 
2872
	list_add_tail(&property->head, &dev->mode_config.property_list);
2873
	return property;
2874
fail:
3031 serge 2875
	kfree(property->values);
1123 serge 2876
	kfree(property);
2877
	return NULL;
2878
}
2879
EXPORT_SYMBOL(drm_property_create);
2880
 
3031 serge 2881
struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
2882
					 const char *name,
2883
					 const struct drm_prop_enum_list *props,
2884
					 int num_values)
2885
{
2886
	struct drm_property *property;
2887
	int i, ret;
2888
 
2889
	flags |= DRM_MODE_PROP_ENUM;
2890
 
2891
	property = drm_property_create(dev, flags, name, num_values);
2892
	if (!property)
2893
		return NULL;
2894
 
2895
	for (i = 0; i < num_values; i++) {
2896
		ret = drm_property_add_enum(property, i,
2897
				      props[i].type,
2898
				      props[i].name);
2899
		if (ret) {
2900
			drm_property_destroy(dev, property);
2901
			return NULL;
2902
		}
2903
	}
2904
 
2905
	return property;
2906
}
2907
EXPORT_SYMBOL(drm_property_create_enum);
2908
 
2909
struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
2910
					 int flags, const char *name,
2911
					 const struct drm_prop_enum_list *props,
2912
					 int num_values)
2913
{
2914
	struct drm_property *property;
2915
	int i, ret;
2916
 
2917
	flags |= DRM_MODE_PROP_BITMASK;
2918
 
2919
	property = drm_property_create(dev, flags, name, num_values);
2920
	if (!property)
2921
		return NULL;
2922
 
2923
	for (i = 0; i < num_values; i++) {
2924
		ret = drm_property_add_enum(property, i,
2925
				      props[i].type,
2926
				      props[i].name);
2927
		if (ret) {
2928
			drm_property_destroy(dev, property);
2929
			return NULL;
2930
		}
2931
	}
2932
 
2933
	return property;
2934
}
2935
EXPORT_SYMBOL(drm_property_create_bitmask);
2936
 
2937
struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
2938
					 const char *name,
2939
					 uint64_t min, uint64_t max)
2940
{
2941
	struct drm_property *property;
2942
 
2943
	flags |= DRM_MODE_PROP_RANGE;
2944
 
2945
	property = drm_property_create(dev, flags, name, 2);
2946
	if (!property)
2947
		return NULL;
2948
 
2949
	property->values[0] = min;
2950
	property->values[1] = max;
2951
 
2952
	return property;
2953
}
2954
EXPORT_SYMBOL(drm_property_create_range);
2955
 
1123 serge 2956
int drm_property_add_enum(struct drm_property *property, int index,
2957
			  uint64_t value, const char *name)
2958
{
2959
	struct drm_property_enum *prop_enum;
2960
 
3031 serge 2961
	if (!(property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)))
1123 serge 2962
		return -EINVAL;
2963
 
3031 serge 2964
	/*
2965
	 * Bitmask enum properties have the additional constraint of values
2966
	 * from 0 to 63
2967
	 */
2968
	if ((property->flags & DRM_MODE_PROP_BITMASK) && (value > 63))
2969
		return -EINVAL;
2970
 
1123 serge 2971
	if (!list_empty(&property->enum_blob_list)) {
2972
		list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
2973
			if (prop_enum->value == value) {
2974
				strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
2975
				prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
2976
				return 0;
2977
			}
2978
		}
2979
	}
2980
 
2981
	prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL);
2982
	if (!prop_enum)
2983
		return -ENOMEM;
2984
 
2985
	strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
2986
	prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
2987
	prop_enum->value = value;
2988
 
2989
	property->values[index] = value;
2990
	list_add_tail(&prop_enum->head, &property->enum_blob_list);
2991
	return 0;
2992
}
2993
EXPORT_SYMBOL(drm_property_add_enum);
2994
 
2995
void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
2996
{
2997
	struct drm_property_enum *prop_enum, *pt;
2998
 
2999
	list_for_each_entry_safe(prop_enum, pt, &property->enum_blob_list, head) {
3000
		list_del(&prop_enum->head);
3001
		kfree(prop_enum);
3002
	}
3003
 
3004
	if (property->num_values)
3005
		kfree(property->values);
3006
	drm_mode_object_put(dev, &property->base);
3007
	list_del(&property->head);
3008
	kfree(property);
3009
}
3010
EXPORT_SYMBOL(drm_property_destroy);
3011
 
3031 serge 3012
void drm_object_attach_property(struct drm_mode_object *obj,
3013
				struct drm_property *property,
3014
				uint64_t init_val)
3015
{
3016
	int count = obj->properties->count;
3017
 
3018
	if (count == DRM_OBJECT_MAX_PROPERTY) {
3019
		WARN(1, "Failed to attach object property (type: 0x%x). Please "
3020
			"increase DRM_OBJECT_MAX_PROPERTY by 1 for each time "
3021
			"you see this message on the same object type.\n",
3022
			obj->type);
3023
		return;
3024
	}
3025
 
3026
	obj->properties->ids[count] = property->base.id;
3027
	obj->properties->values[count] = init_val;
3028
	obj->properties->count++;
3029
}
3030
EXPORT_SYMBOL(drm_object_attach_property);
3031
 
3032
int drm_object_property_set_value(struct drm_mode_object *obj,
3033
				  struct drm_property *property, uint64_t val)
3034
{
1123 serge 3035
	int i;
3036
 
3031 serge 3037
	for (i = 0; i < obj->properties->count; i++) {
3038
		if (obj->properties->ids[i] == property->base.id) {
3039
			obj->properties->values[i] = val;
3040
			return 0;
1123 serge 3041
		}
3042
	}
3043
 
3044
		return -EINVAL;
3045
}
3031 serge 3046
EXPORT_SYMBOL(drm_object_property_set_value);
1123 serge 3047
 
3031 serge 3048
int drm_object_property_get_value(struct drm_mode_object *obj,
1123 serge 3049
				  struct drm_property *property, uint64_t *val)
3050
{
3051
	int i;
3052
 
3031 serge 3053
	for (i = 0; i < obj->properties->count; i++) {
3054
		if (obj->properties->ids[i] == property->base.id) {
3055
			*val = obj->properties->values[i];
3056
			return 0;
1123 serge 3057
		}
3058
	}
3059
 
3060
		return -EINVAL;
3061
}
3031 serge 3062
EXPORT_SYMBOL(drm_object_property_get_value);
1123 serge 3063
 
3064
#if 0
3065
int drm_mode_getproperty_ioctl(struct drm_device *dev,
3066
			       void *data, struct drm_file *file_priv)
3067
{
3068
	struct drm_mode_object *obj;
3069
	struct drm_mode_get_property *out_resp = data;
3070
	struct drm_property *property;
3071
	int enum_count = 0;
3072
	int blob_count = 0;
3073
	int value_count = 0;
3074
	int ret = 0, i;
3075
	int copied;
3076
	struct drm_property_enum *prop_enum;
3077
	struct drm_mode_property_enum __user *enum_ptr;
3078
	struct drm_property_blob *prop_blob;
3031 serge 3079
	uint32_t __user *blob_id_ptr;
1123 serge 3080
	uint64_t __user *values_ptr;
3081
	uint32_t __user *blob_length_ptr;
3082
 
1963 serge 3083
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
3084
		return -EINVAL;
3085
 
3480 Serge 3086
	drm_modeset_lock_all(dev);
1123 serge 3087
	obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
3088
	if (!obj) {
4560 Serge 3089
		ret = -ENOENT;
1123 serge 3090
		goto done;
3091
	}
3092
	property = obj_to_property(obj);
3093
 
3031 serge 3094
	if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) {
1123 serge 3095
		list_for_each_entry(prop_enum, &property->enum_blob_list, head)
3096
			enum_count++;
3097
	} else if (property->flags & DRM_MODE_PROP_BLOB) {
3098
		list_for_each_entry(prop_blob, &property->enum_blob_list, head)
3099
			blob_count++;
3100
	}
3101
 
3102
	value_count = property->num_values;
3103
 
3104
	strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN);
3105
	out_resp->name[DRM_PROP_NAME_LEN-1] = 0;
3106
	out_resp->flags = property->flags;
3107
 
3108
	if ((out_resp->count_values >= value_count) && value_count) {
3031 serge 3109
		values_ptr = (uint64_t __user *)(unsigned long)out_resp->values_ptr;
1123 serge 3110
		for (i = 0; i < value_count; i++) {
3111
			if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) {
3112
				ret = -EFAULT;
3113
				goto done;
3114
			}
3115
		}
3116
	}
3117
	out_resp->count_values = value_count;
3118
 
3031 serge 3119
	if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) {
1123 serge 3120
		if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
3121
			copied = 0;
3031 serge 3122
			enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr;
1123 serge 3123
			list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
3124
 
3125
				if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {
3126
					ret = -EFAULT;
3127
					goto done;
3128
				}
3129
 
3130
				if (copy_to_user(&enum_ptr[copied].name,
3131
						 &prop_enum->name, DRM_PROP_NAME_LEN)) {
3132
					ret = -EFAULT;
3133
					goto done;
3134
				}
3135
				copied++;
3136
			}
3137
		}
3138
		out_resp->count_enum_blobs = enum_count;
3139
	}
3140
 
3141
	if (property->flags & DRM_MODE_PROP_BLOB) {
3142
		if ((out_resp->count_enum_blobs >= blob_count) && blob_count) {
3143
			copied = 0;
3031 serge 3144
			blob_id_ptr = (uint32_t __user *)(unsigned long)out_resp->enum_blob_ptr;
3145
			blob_length_ptr = (uint32_t __user *)(unsigned long)out_resp->values_ptr;
1123 serge 3146
 
3147
			list_for_each_entry(prop_blob, &property->enum_blob_list, head) {
3148
				if (put_user(prop_blob->base.id, blob_id_ptr + copied)) {
3149
					ret = -EFAULT;
3150
					goto done;
3151
				}
3152
 
3153
				if (put_user(prop_blob->length, blob_length_ptr + copied)) {
3154
					ret = -EFAULT;
3155
					goto done;
3156
				}
3157
 
3158
				copied++;
3159
			}
3160
		}
3161
		out_resp->count_enum_blobs = blob_count;
3162
	}
3163
done:
3480 Serge 3164
	drm_modeset_unlock_all(dev);
1123 serge 3165
	return ret;
3166
}
3167
#endif
3168
 
3169
static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length,
3170
							  void *data)
3171
{
3172
	struct drm_property_blob *blob;
3031 serge 3173
	int ret;
1123 serge 3174
 
3175
	if (!length || !data)
3176
		return NULL;
3177
 
3178
	blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
3179
	if (!blob)
3180
		return NULL;
3181
 
3031 serge 3182
	ret = drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB);
3183
	if (ret) {
3184
		kfree(blob);
3185
		return NULL;
3186
	}
3187
 
1123 serge 3188
	blob->length = length;
3189
 
3190
	memcpy(blob->data, data, length);
3191
 
3192
	list_add_tail(&blob->head, &dev->mode_config.property_blob_list);
3193
	return blob;
3194
}
3195
 
3196
static void drm_property_destroy_blob(struct drm_device *dev,
3197
			       struct drm_property_blob *blob)
3198
{
3199
	drm_mode_object_put(dev, &blob->base);
3200
	list_del(&blob->head);
3201
	kfree(blob);
3202
}
3203
 
3204
#if 0
3205
int drm_mode_getblob_ioctl(struct drm_device *dev,
3206
			   void *data, struct drm_file *file_priv)
3207
{
3208
	struct drm_mode_object *obj;
3209
	struct drm_mode_get_blob *out_resp = data;
3210
	struct drm_property_blob *blob;
3211
	int ret = 0;
3031 serge 3212
	void __user *blob_ptr;
1123 serge 3213
 
1963 serge 3214
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
3215
		return -EINVAL;
3216
 
3480 Serge 3217
	drm_modeset_lock_all(dev);
1123 serge 3218
	obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB);
3219
	if (!obj) {
4560 Serge 3220
		ret = -ENOENT;
1123 serge 3221
		goto done;
3222
	}
3223
	blob = obj_to_blob(obj);
3224
 
3225
	if (out_resp->length == blob->length) {
3031 serge 3226
		blob_ptr = (void __user *)(unsigned long)out_resp->data;
1123 serge 3227
		if (copy_to_user(blob_ptr, blob->data, blob->length)){
3228
			ret = -EFAULT;
3229
			goto done;
3230
		}
3231
	}
3232
	out_resp->length = blob->length;
3233
 
3234
done:
3480 Serge 3235
	drm_modeset_unlock_all(dev);
1123 serge 3236
	return ret;
3237
}
3238
#endif
3239
 
3240
int drm_mode_connector_update_edid_property(struct drm_connector *connector,
3241
					    struct edid *edid)
3242
{
3243
	struct drm_device *dev = connector->dev;
3031 serge 3244
	int ret, size;
1123 serge 3245
 
3246
	if (connector->edid_blob_ptr)
3247
		drm_property_destroy_blob(dev, connector->edid_blob_ptr);
3248
 
3249
	/* Delete edid, when there is none. */
3250
	if (!edid) {
3251
		connector->edid_blob_ptr = NULL;
3192 Serge 3252
		ret = drm_object_property_set_value(&connector->base, dev->mode_config.edid_property, 0);
1123 serge 3253
		return ret;
3254
	}
3255
 
1963 serge 3256
	size = EDID_LENGTH * (1 + edid->extensions);
3257
	connector->edid_blob_ptr = drm_property_create_blob(connector->dev,
3258
							    size, edid);
3192 Serge 3259
	if (!connector->edid_blob_ptr)
3260
		return -EINVAL;
1123 serge 3261
 
3192 Serge 3262
	ret = drm_object_property_set_value(&connector->base,
1123 serge 3263
					       dev->mode_config.edid_property,
3264
					       connector->edid_blob_ptr->base.id);
3265
 
3266
	return ret;
3267
}
3268
EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
3269
 
3270
#if 0
3031 serge 3271
 
3272
static int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
3273
					   struct drm_property *property,
3274
					   uint64_t value)
1123 serge 3275
{
3031 serge 3276
	int ret = -EINVAL;
3277
	struct drm_connector *connector = obj_to_connector(obj);
3278
 
3279
	/* Do DPMS ourselves */
3280
	if (property == connector->dev->mode_config.dpms_property) {
3281
		if (connector->funcs->dpms)
3282
			(*connector->funcs->dpms)(connector, (int)value);
3283
		ret = 0;
3284
	} else if (connector->funcs->set_property)
3285
		ret = connector->funcs->set_property(connector, property, value);
3286
 
3287
	/* store the property value if successful */
3288
	if (!ret)
3192 Serge 3289
		drm_object_property_set_value(&connector->base, property, value);
3031 serge 3290
	return ret;
3291
}
3292
 
3293
static int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
3294
				      struct drm_property *property,
3295
				      uint64_t value)
3296
{
3297
	int ret = -EINVAL;
3298
	struct drm_crtc *crtc = obj_to_crtc(obj);
3299
 
3300
	if (crtc->funcs->set_property)
3301
		ret = crtc->funcs->set_property(crtc, property, value);
3302
	if (!ret)
3303
		drm_object_property_set_value(obj, property, value);
3304
 
3305
	return ret;
3306
}
3307
 
3308
static int drm_mode_plane_set_obj_prop(struct drm_mode_object *obj,
3309
				      struct drm_property *property,
3310
				      uint64_t value)
3311
{
3312
	int ret = -EINVAL;
3313
	struct drm_plane *plane = obj_to_plane(obj);
3314
 
3315
	if (plane->funcs->set_property)
3316
		ret = plane->funcs->set_property(plane, property, value);
3317
	if (!ret)
3318
		drm_object_property_set_value(obj, property, value);
3319
 
3320
	return ret;
3321
}
3322
 
3323
int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
3324
				      struct drm_file *file_priv)
3325
{
3326
	struct drm_mode_obj_get_properties *arg = data;
1123 serge 3327
	struct drm_mode_object *obj;
3031 serge 3328
	int ret = 0;
1123 serge 3329
	int i;
3031 serge 3330
	int copied = 0;
3331
	int props_count = 0;
3332
	uint32_t __user *props_ptr;
3333
	uint64_t __user *prop_values_ptr;
1123 serge 3334
 
1963 serge 3335
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
3336
		return -EINVAL;
3337
 
3480 Serge 3338
	drm_modeset_lock_all(dev);
1123 serge 3339
 
3031 serge 3340
	obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
1123 serge 3341
	if (!obj) {
4560 Serge 3342
		ret = -ENOENT;
1123 serge 3343
		goto out;
3344
	}
3031 serge 3345
	if (!obj->properties) {
3346
		ret = -EINVAL;
3347
		goto out;
3348
	}
1123 serge 3349
 
3031 serge 3350
	props_count = obj->properties->count;
3351
 
3352
	/* This ioctl is called twice, once to determine how much space is
3353
	 * needed, and the 2nd time to fill it. */
3354
	if ((arg->count_props >= props_count) && props_count) {
3355
		copied = 0;
3356
		props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr);
3357
		prop_values_ptr = (uint64_t __user *)(unsigned long)
3358
				  (arg->prop_values_ptr);
3359
		for (i = 0; i < props_count; i++) {
3360
			if (put_user(obj->properties->ids[i],
3361
				     props_ptr + copied)) {
3362
				ret = -EFAULT;
3363
				goto out;
1123 serge 3364
	}
3031 serge 3365
			if (put_user(obj->properties->values[i],
3366
				     prop_values_ptr + copied)) {
3367
				ret = -EFAULT;
1123 serge 3368
		goto out;
3369
	}
3031 serge 3370
			copied++;
3371
		}
3372
	}
3373
	arg->count_props = props_count;
3374
out:
3480 Serge 3375
	drm_modeset_unlock_all(dev);
3031 serge 3376
	return ret;
3377
}
1123 serge 3378
 
3031 serge 3379
int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
3380
				    struct drm_file *file_priv)
3381
{
3382
	struct drm_mode_obj_set_property *arg = data;
3383
	struct drm_mode_object *arg_obj;
3384
	struct drm_mode_object *prop_obj;
3385
	struct drm_property *property;
3386
	int ret = -EINVAL;
3387
	int i;
3388
 
3389
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
3390
		return -EINVAL;
3391
 
3480 Serge 3392
	drm_modeset_lock_all(dev);
3031 serge 3393
 
3394
	arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
4560 Serge 3395
	if (!arg_obj) {
3396
		ret = -ENOENT;
1123 serge 3397
		goto out;
4560 Serge 3398
	}
3031 serge 3399
	if (!arg_obj->properties)
3400
		goto out;
1123 serge 3401
 
3031 serge 3402
	for (i = 0; i < arg_obj->properties->count; i++)
3403
		if (arg_obj->properties->ids[i] == arg->prop_id)
3404
			break;
3405
 
3406
	if (i == arg_obj->properties->count)
1123 serge 3407
		goto out;
3408
 
3031 serge 3409
	prop_obj = drm_mode_object_find(dev, arg->prop_id,
3410
					DRM_MODE_OBJECT_PROPERTY);
4560 Serge 3411
	if (!prop_obj) {
3412
		ret = -ENOENT;
1123 serge 3413
			goto out;
4560 Serge 3414
	}
3031 serge 3415
	property = obj_to_property(prop_obj);
1123 serge 3416
 
3031 serge 3417
	if (!drm_property_change_is_valid(property, arg->value))
1123 serge 3418
			goto out;
3031 serge 3419
 
3420
	switch (arg_obj->type) {
3421
	case DRM_MODE_OBJECT_CONNECTOR:
3422
		ret = drm_mode_connector_set_obj_prop(arg_obj, property,
3423
						      arg->value);
3424
		break;
3425
	case DRM_MODE_OBJECT_CRTC:
3426
		ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value);
3427
		break;
3428
	case DRM_MODE_OBJECT_PLANE:
3429
		ret = drm_mode_plane_set_obj_prop(arg_obj, property, arg->value);
1123 serge 3430
				break;
3431
			}
3432
 
3433
out:
3480 Serge 3434
	drm_modeset_unlock_all(dev);
1123 serge 3435
	return ret;
3436
}
3437
#endif
3438
 
3439
int drm_mode_connector_attach_encoder(struct drm_connector *connector,
3440
				      struct drm_encoder *encoder)
3441
{
3442
	int i;
3443
 
3444
	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
3445
		if (connector->encoder_ids[i] == 0) {
3446
			connector->encoder_ids[i] = encoder->base.id;
3447
			return 0;
3448
		}
3449
	}
3450
	return -ENOMEM;
3451
}
3452
EXPORT_SYMBOL(drm_mode_connector_attach_encoder);
3453
 
3454
void drm_mode_connector_detach_encoder(struct drm_connector *connector,
3455
				    struct drm_encoder *encoder)
3456
{
3457
	int i;
3458
	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
3459
		if (connector->encoder_ids[i] == encoder->base.id) {
3460
			connector->encoder_ids[i] = 0;
3461
			if (connector->encoder == encoder)
3462
				connector->encoder = NULL;
3463
			break;
3464
		}
3465
	}
3466
}
3467
EXPORT_SYMBOL(drm_mode_connector_detach_encoder);
3468
 
3031 serge 3469
int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
1123 serge 3470
				  int gamma_size)
3471
{
3472
	crtc->gamma_size = gamma_size;
3473
 
3474
	crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL);
3475
	if (!crtc->gamma_store) {
3476
		crtc->gamma_size = 0;
3031 serge 3477
		return -ENOMEM;
1123 serge 3478
	}
3479
 
3031 serge 3480
	return 0;
1123 serge 3481
}
3482
EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);
3483
 
3484
#if 0
3485
int drm_mode_gamma_set_ioctl(struct drm_device *dev,
3486
			     void *data, struct drm_file *file_priv)
3487
{
3488
	struct drm_mode_crtc_lut *crtc_lut = data;
3489
	struct drm_mode_object *obj;
3490
	struct drm_crtc *crtc;
3491
	void *r_base, *g_base, *b_base;
3492
	int size;
3493
	int ret = 0;
3494
 
1963 serge 3495
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
3496
		return -EINVAL;
3497
 
3480 Serge 3498
	drm_modeset_lock_all(dev);
1123 serge 3499
	obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
3500
	if (!obj) {
4560 Serge 3501
		ret = -ENOENT;
1123 serge 3502
		goto out;
3503
	}
3504
	crtc = obj_to_crtc(obj);
3505
 
3031 serge 3506
	if (crtc->funcs->gamma_set == NULL) {
3507
		ret = -ENOSYS;
3508
		goto out;
3509
	}
3510
 
1123 serge 3511
	/* memcpy into gamma store */
3512
	if (crtc_lut->gamma_size != crtc->gamma_size) {
3513
		ret = -EINVAL;
3514
		goto out;
3515
	}
3516
 
3517
	size = crtc_lut->gamma_size * (sizeof(uint16_t));
3518
	r_base = crtc->gamma_store;
3519
	if (copy_from_user(r_base, (void __user *)(unsigned long)crtc_lut->red, size)) {
3520
		ret = -EFAULT;
3521
		goto out;
3522
	}
3523
 
3524
	g_base = r_base + size;
3525
	if (copy_from_user(g_base, (void __user *)(unsigned long)crtc_lut->green, size)) {
3526
		ret = -EFAULT;
3527
		goto out;
3528
	}
3529
 
3530
	b_base = g_base + size;
3531
	if (copy_from_user(b_base, (void __user *)(unsigned long)crtc_lut->blue, size)) {
3532
		ret = -EFAULT;
3533
		goto out;
3534
	}
3535
 
1963 serge 3536
	crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size);
1123 serge 3537
 
3538
out:
3480 Serge 3539
	drm_modeset_unlock_all(dev);
1123 serge 3540
	return ret;
3541
 
3542
}
3543
 
3544
int drm_mode_gamma_get_ioctl(struct drm_device *dev,
3545
			     void *data, struct drm_file *file_priv)
3546
{
3547
	struct drm_mode_crtc_lut *crtc_lut = data;
3548
	struct drm_mode_object *obj;
3549
	struct drm_crtc *crtc;
3550
	void *r_base, *g_base, *b_base;
3551
	int size;
3552
	int ret = 0;
3553
 
1963 serge 3554
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
3555
		return -EINVAL;
3556
 
3480 Serge 3557
	drm_modeset_lock_all(dev);
1123 serge 3558
	obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
3559
	if (!obj) {
4560 Serge 3560
		ret = -ENOENT;
1123 serge 3561
		goto out;
3562
	}
3563
	crtc = obj_to_crtc(obj);
3564
 
3565
	/* memcpy into gamma store */
3566
	if (crtc_lut->gamma_size != crtc->gamma_size) {
3567
		ret = -EINVAL;
3568
		goto out;
3569
	}
3570
 
3571
	size = crtc_lut->gamma_size * (sizeof(uint16_t));
3572
	r_base = crtc->gamma_store;
3573
	if (copy_to_user((void __user *)(unsigned long)crtc_lut->red, r_base, size)) {
3574
		ret = -EFAULT;
3575
		goto out;
3576
	}
3577
 
3578
	g_base = r_base + size;
3579
	if (copy_to_user((void __user *)(unsigned long)crtc_lut->green, g_base, size)) {
3580
		ret = -EFAULT;
3581
		goto out;
3582
	}
3583
 
3584
	b_base = g_base + size;
3585
	if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) {
3586
		ret = -EFAULT;
3587
		goto out;
3588
	}
3589
out:
3480 Serge 3590
	drm_modeset_unlock_all(dev);
1123 serge 3591
	return ret;
3592
}
3593
 
3594
#endif
1179 serge 3595
 
3596
 
1963 serge 3597
void drm_mode_config_reset(struct drm_device *dev)
3598
{
3599
	struct drm_crtc *crtc;
3600
	struct drm_encoder *encoder;
3601
	struct drm_connector *connector;
3602
 
3603
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
3604
		if (crtc->funcs->reset)
3605
			crtc->funcs->reset(crtc);
3606
 
3607
	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
3608
		if (encoder->funcs->reset)
3609
			encoder->funcs->reset(encoder);
3610
 
3192 Serge 3611
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
3612
		connector->status = connector_status_unknown;
3613
 
1963 serge 3614
		if (connector->funcs->reset)
3615
			connector->funcs->reset(connector);
3192 Serge 3616
	}
1963 serge 3617
}
3618
EXPORT_SYMBOL(drm_mode_config_reset);
3031 serge 3619
/*
3620
 * Just need to support RGB formats here for compat with code that doesn't
3621
 * use pixel formats directly yet.
3622
 */
3623
void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth,
3624
			  int *bpp)
3625
{
3626
	switch (format) {
3480 Serge 3627
	case DRM_FORMAT_C8:
3031 serge 3628
	case DRM_FORMAT_RGB332:
3629
	case DRM_FORMAT_BGR233:
3630
		*depth = 8;
3631
		*bpp = 8;
3632
		break;
3633
	case DRM_FORMAT_XRGB1555:
3634
	case DRM_FORMAT_XBGR1555:
3635
	case DRM_FORMAT_RGBX5551:
3636
	case DRM_FORMAT_BGRX5551:
3637
	case DRM_FORMAT_ARGB1555:
3638
	case DRM_FORMAT_ABGR1555:
3639
	case DRM_FORMAT_RGBA5551:
3640
	case DRM_FORMAT_BGRA5551:
3641
		*depth = 15;
3642
		*bpp = 16;
3643
		break;
3644
	case DRM_FORMAT_RGB565:
3645
	case DRM_FORMAT_BGR565:
3646
		*depth = 16;
3647
		*bpp = 16;
3648
		break;
3649
	case DRM_FORMAT_RGB888:
3650
	case DRM_FORMAT_BGR888:
3651
		*depth = 24;
3652
		*bpp = 24;
3653
		break;
3654
	case DRM_FORMAT_XRGB8888:
3655
	case DRM_FORMAT_XBGR8888:
3656
	case DRM_FORMAT_RGBX8888:
3657
	case DRM_FORMAT_BGRX8888:
3658
		*depth = 24;
3659
		*bpp = 32;
3660
		break;
3661
	case DRM_FORMAT_XRGB2101010:
3662
	case DRM_FORMAT_XBGR2101010:
3663
	case DRM_FORMAT_RGBX1010102:
3664
	case DRM_FORMAT_BGRX1010102:
3665
	case DRM_FORMAT_ARGB2101010:
3666
	case DRM_FORMAT_ABGR2101010:
3667
	case DRM_FORMAT_RGBA1010102:
3668
	case DRM_FORMAT_BGRA1010102:
3669
		*depth = 30;
3670
		*bpp = 32;
3671
		break;
3672
	case DRM_FORMAT_ARGB8888:
3673
	case DRM_FORMAT_ABGR8888:
3674
	case DRM_FORMAT_RGBA8888:
3675
	case DRM_FORMAT_BGRA8888:
3676
		*depth = 32;
3677
		*bpp = 32;
3678
		break;
3679
	default:
4560 Serge 3680
		DRM_DEBUG_KMS("unsupported pixel format %s\n",
3681
			      drm_get_format_name(format));
3031 serge 3682
		*depth = 0;
3683
		*bpp = 0;
3684
		break;
3685
	}
3686
}
3687
EXPORT_SYMBOL(drm_fb_get_bpp_depth);
3688
 
3689
/**
3690
 * drm_format_num_planes - get the number of planes for format
3691
 * @format: pixel format (DRM_FORMAT_*)
3692
 *
3693
 * RETURNS:
3694
 * The number of planes used by the specified pixel format.
3695
 */
3696
int drm_format_num_planes(uint32_t format)
3697
{
3698
	switch (format) {
3699
	case DRM_FORMAT_YUV410:
3700
	case DRM_FORMAT_YVU410:
3701
	case DRM_FORMAT_YUV411:
3702
	case DRM_FORMAT_YVU411:
3703
	case DRM_FORMAT_YUV420:
3704
	case DRM_FORMAT_YVU420:
3705
	case DRM_FORMAT_YUV422:
3706
	case DRM_FORMAT_YVU422:
3707
	case DRM_FORMAT_YUV444:
3708
	case DRM_FORMAT_YVU444:
3709
		return 3;
3710
	case DRM_FORMAT_NV12:
3711
	case DRM_FORMAT_NV21:
3712
	case DRM_FORMAT_NV16:
3713
	case DRM_FORMAT_NV61:
3714
	case DRM_FORMAT_NV24:
3715
	case DRM_FORMAT_NV42:
3716
		return 2;
3717
	default:
3718
		return 1;
3719
	}
3720
}
3721
EXPORT_SYMBOL(drm_format_num_planes);
3722
 
3723
/**
3724
 * drm_format_plane_cpp - determine the bytes per pixel value
3725
 * @format: pixel format (DRM_FORMAT_*)
3726
 * @plane: plane index
3727
 *
3728
 * RETURNS:
3729
 * The bytes per pixel value for the specified plane.
3730
 */
3731
int drm_format_plane_cpp(uint32_t format, int plane)
3732
{
3733
	unsigned int depth;
3734
	int bpp;
3735
 
3736
	if (plane >= drm_format_num_planes(format))
3737
		return 0;
3738
 
3739
	switch (format) {
3740
	case DRM_FORMAT_YUYV:
3741
	case DRM_FORMAT_YVYU:
3742
	case DRM_FORMAT_UYVY:
3743
	case DRM_FORMAT_VYUY:
3744
		return 2;
3745
	case DRM_FORMAT_NV12:
3746
	case DRM_FORMAT_NV21:
3747
	case DRM_FORMAT_NV16:
3748
	case DRM_FORMAT_NV61:
3749
	case DRM_FORMAT_NV24:
3750
	case DRM_FORMAT_NV42:
3751
		return plane ? 2 : 1;
3752
	case DRM_FORMAT_YUV410:
3753
	case DRM_FORMAT_YVU410:
3754
	case DRM_FORMAT_YUV411:
3755
	case DRM_FORMAT_YVU411:
3756
	case DRM_FORMAT_YUV420:
3757
	case DRM_FORMAT_YVU420:
3758
	case DRM_FORMAT_YUV422:
3759
	case DRM_FORMAT_YVU422:
3760
	case DRM_FORMAT_YUV444:
3761
	case DRM_FORMAT_YVU444:
3762
		return 1;
3763
	default:
3764
		drm_fb_get_bpp_depth(format, &depth, &bpp);
3765
		return bpp >> 3;
3766
	}
3767
}
3768
EXPORT_SYMBOL(drm_format_plane_cpp);
3769
 
3770
/**
3771
 * drm_format_horz_chroma_subsampling - get the horizontal chroma subsampling factor
3772
 * @format: pixel format (DRM_FORMAT_*)
3773
 *
3774
 * RETURNS:
3775
 * The horizontal chroma subsampling factor for the
3776
 * specified pixel format.
3777
 */
3778
int drm_format_horz_chroma_subsampling(uint32_t format)
3779
{
3780
	switch (format) {
3781
	case DRM_FORMAT_YUV411:
3782
	case DRM_FORMAT_YVU411:
3783
	case DRM_FORMAT_YUV410:
3784
	case DRM_FORMAT_YVU410:
3785
		return 4;
3786
	case DRM_FORMAT_YUYV:
3787
	case DRM_FORMAT_YVYU:
3788
	case DRM_FORMAT_UYVY:
3789
	case DRM_FORMAT_VYUY:
3790
	case DRM_FORMAT_NV12:
3791
	case DRM_FORMAT_NV21:
3792
	case DRM_FORMAT_NV16:
3793
	case DRM_FORMAT_NV61:
3794
	case DRM_FORMAT_YUV422:
3795
	case DRM_FORMAT_YVU422:
3796
	case DRM_FORMAT_YUV420:
3797
	case DRM_FORMAT_YVU420:
3798
		return 2;
3799
	default:
3800
		return 1;
3801
	}
3802
}
3803
EXPORT_SYMBOL(drm_format_horz_chroma_subsampling);
3804
 
3805
/**
3806
 * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling factor
3807
 * @format: pixel format (DRM_FORMAT_*)
3808
 *
3809
 * RETURNS:
3810
 * The vertical chroma subsampling factor for the
3811
 * specified pixel format.
3812
 */
3813
int drm_format_vert_chroma_subsampling(uint32_t format)
3814
{
3815
	switch (format) {
3816
	case DRM_FORMAT_YUV410:
3817
	case DRM_FORMAT_YVU410:
3818
		return 4;
3819
	case DRM_FORMAT_YUV420:
3820
	case DRM_FORMAT_YVU420:
3821
	case DRM_FORMAT_NV12:
3822
	case DRM_FORMAT_NV21:
3823
		return 2;
3824
	default:
3825
		return 1;
3826
	}
3827
}
3828
EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
3746 Serge 3829
 
3830
/**
3831
 * drm_mode_config_init - initialize DRM mode_configuration structure
3832
 * @dev: DRM device
3833
 *
3834
 * Initialize @dev's mode_config structure, used for tracking the graphics
3835
 * configuration of @dev.
3836
 *
3837
 * Since this initializes the modeset locks, no locking is possible. Which is no
3838
 * problem, since this should happen single threaded at init time. It is the
3839
 * driver's problem to ensure this guarantee.
3840
 *
3841
 */
3842
void drm_mode_config_init(struct drm_device *dev)
3843
{
3844
	mutex_init(&dev->mode_config.mutex);
3845
	mutex_init(&dev->mode_config.idr_mutex);
3846
	mutex_init(&dev->mode_config.fb_lock);
3847
	INIT_LIST_HEAD(&dev->mode_config.fb_list);
3848
	INIT_LIST_HEAD(&dev->mode_config.crtc_list);
3849
	INIT_LIST_HEAD(&dev->mode_config.connector_list);
4104 Serge 3850
	INIT_LIST_HEAD(&dev->mode_config.bridge_list);
3746 Serge 3851
	INIT_LIST_HEAD(&dev->mode_config.encoder_list);
3852
	INIT_LIST_HEAD(&dev->mode_config.property_list);
3853
	INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
3854
	INIT_LIST_HEAD(&dev->mode_config.plane_list);
3855
	idr_init(&dev->mode_config.crtc_idr);
3856
 
3857
	drm_modeset_lock_all(dev);
3858
	drm_mode_create_standard_connector_properties(dev);
3859
	drm_modeset_unlock_all(dev);
3860
 
3861
	/* Just to be sure */
3862
	dev->mode_config.num_fb = 0;
3863
	dev->mode_config.num_connector = 0;
3864
	dev->mode_config.num_crtc = 0;
3865
	dev->mode_config.num_encoder = 0;
3866
}
3867
EXPORT_SYMBOL(drm_mode_config_init);
3868