Subversion Repositories Kolibri OS

Rev

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

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