Subversion Repositories Kolibri OS

Rev

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

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