Subversion Repositories Kolibri OS

Rev

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