Subversion Repositories Kolibri OS

Rev

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

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