aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2008-11-07 17:05:41 -0500
committerDave Airlie <airlied@linux.ie>2008-12-29 02:47:23 -0500
commitf453ba0460742ad027ae0c4c7d61e62817b3e7ef (patch)
tree29e6ecacd6e8971aa62e1825d77f2c1876ac3eb2
parentde151cf67ce52ed2d88083daa5e60c7858947329 (diff)
DRM: add mode setting support
Add mode setting support to the DRM layer. This is a fairly big chunk of work that allows DRM drivers to provide full output control and configuration capabilities to userspace. It was motivated by several factors: - the fb layer's APIs aren't suited for anything but simple configurations - coordination between the fb layer, DRM layer, and various userspace drivers is poor to non-existent (radeonfb excepted) - user level mode setting drivers makes displaying panic & oops messages more difficult - suspend/resume of graphics state is possible in many more configurations with kernel level support This commit just adds the core DRM part of the mode setting APIs. Driver specific commits using these new structure and APIs will follow. Co-authors: Jesse Barnes <jbarnes@virtuousgeek.org>, Jakob Bornecrantz <jakob@tungstengraphics.com> Contributors: Alan Hourihane <alanh@tungstengraphics.com>, Maarten Maathuis <madman2003@gmail.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/Makefile3
-rw-r--r--drivers/gpu/drm/drm_crtc.c2497
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c822
-rw-r--r--drivers/gpu/drm/drm_drv.c34
-rw-r--r--drivers/gpu/drm/drm_edid.c732
-rw-r--r--drivers/gpu/drm/drm_fops.c22
-rw-r--r--drivers/gpu/drm/drm_irq.c64
-rw-r--r--drivers/gpu/drm/drm_mm.c1
-rw-r--r--drivers/gpu/drm/drm_modes.c576
-rw-r--r--drivers/gpu/drm/drm_stub.c30
-rw-r--r--drivers/gpu/drm/drm_sysfs.c329
-rw-r--r--drivers/video/console/vgacon.c17
-rw-r--r--include/drm/Kbuild2
-rw-r--r--include/drm/drm.h21
-rw-r--r--include/drm/drmP.h18
-rw-r--r--include/drm/drm_crtc.h737
-rw-r--r--include/drm/drm_crtc_helper.h121
-rw-r--r--include/drm/drm_edid.h202
-rw-r--r--include/drm/drm_mode.h278
-rw-r--r--include/linux/console.h4
20 files changed, 6469 insertions, 41 deletions
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 74da99495e21..30022c4a5c12 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -9,7 +9,8 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \
9 drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ 9 drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
10 drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ 10 drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
11 drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ 11 drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
12 drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o 12 drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \
13 drm_crtc.o drm_crtc_helper.o drm_modes.o drm_edid.o
13 14
14drm-$(CONFIG_COMPAT) += drm_ioc32.o 15drm-$(CONFIG_COMPAT) += drm_ioc32.o
15 16
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
new file mode 100644
index 000000000000..2e880240477e
--- /dev/null
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -0,0 +1,2497 @@
1/*
2 * Copyright (c) 2006-2008 Intel Corporation
3 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
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 <eric@anholt.net>
29 * Dave Airlie <airlied@linux.ie>
30 * Jesse Barnes <jesse.barnes@intel.com>
31 */
32#include <linux/list.h>
33#include "drm.h"
34#include "drmP.h"
35#include "drm_crtc.h"
36
37struct drm_prop_enum_list {
38 int type;
39 char *name;
40};
41
42/* Avoid boilerplate. I'm tired of typing. */
43#define DRM_ENUM_NAME_FN(fnname, list) \
44 char *fnname(int val) \
45 { \
46 int i; \
47 for (i = 0; i < ARRAY_SIZE(list); i++) { \
48 if (list[i].type == val) \
49 return list[i].name; \
50 } \
51 return "(unknown)"; \
52 }
53
54/*
55 * Global properties
56 */
57static struct drm_prop_enum_list drm_dpms_enum_list[] =
58{ { DRM_MODE_DPMS_ON, "On" },
59 { DRM_MODE_DPMS_STANDBY, "Standby" },
60 { DRM_MODE_DPMS_SUSPEND, "Suspend" },
61 { DRM_MODE_DPMS_OFF, "Off" }
62};
63
64DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
65
66/*
67 * Optional properties
68 */
69static struct drm_prop_enum_list drm_scaling_mode_enum_list[] =
70{
71 { DRM_MODE_SCALE_NON_GPU, "Non-GPU" },
72 { DRM_MODE_SCALE_FULLSCREEN, "Fullscreen" },
73 { DRM_MODE_SCALE_NO_SCALE, "No scale" },
74 { DRM_MODE_SCALE_ASPECT, "Aspect" },
75};
76
77static struct drm_prop_enum_list drm_dithering_mode_enum_list[] =
78{
79 { DRM_MODE_DITHERING_OFF, "Off" },
80 { DRM_MODE_DITHERING_ON, "On" },
81};
82
83/*
84 * Non-global properties, but "required" for certain connectors.
85 */
86static struct drm_prop_enum_list drm_dvi_i_select_enum_list[] =
87{
88 { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
89 { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */
90 { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */
91};
92
93DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list)
94
95static struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] =
96{
97 { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */
98 { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */
99 { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */
100};
101
102DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name,
103 drm_dvi_i_subconnector_enum_list)
104
105static struct drm_prop_enum_list drm_tv_select_enum_list[] =
106{
107 { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
108 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
109 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */
110 { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
111};
112
113DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)
114
115static struct drm_prop_enum_list drm_tv_subconnector_enum_list[] =
116{
117 { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */
118 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
119 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */
120 { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
121};
122
123DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
124 drm_tv_subconnector_enum_list)
125
126struct drm_conn_prop_enum_list {
127 int type;
128 char *name;
129 int count;
130};
131
132/*
133 * Connector and encoder types.
134 */
135static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
136{ { DRM_MODE_CONNECTOR_Unknown, "Unknown", 0 },
137 { DRM_MODE_CONNECTOR_VGA, "VGA", 0 },
138 { DRM_MODE_CONNECTOR_DVII, "DVI-I", 0 },
139 { DRM_MODE_CONNECTOR_DVID, "DVI-D", 0 },
140 { DRM_MODE_CONNECTOR_DVIA, "DVI-A", 0 },
141 { DRM_MODE_CONNECTOR_Composite, "Composite", 0 },
142 { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 },
143 { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 },
144 { DRM_MODE_CONNECTOR_Component, "Component", 0 },
145 { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN", 0 },
146 { DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 },
147 { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 },
148 { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 },
149};
150
151static struct drm_prop_enum_list drm_encoder_enum_list[] =
152{ { DRM_MODE_ENCODER_NONE, "None" },
153 { DRM_MODE_ENCODER_DAC, "DAC" },
154 { DRM_MODE_ENCODER_TMDS, "TMDS" },
155 { DRM_MODE_ENCODER_LVDS, "LVDS" },
156 { DRM_MODE_ENCODER_TVDAC, "TV" },
157};
158
159char *drm_get_encoder_name(struct drm_encoder *encoder)
160{
161 static char buf[32];
162
163 snprintf(buf, 32, "%s-%d",
164 drm_encoder_enum_list[encoder->encoder_type].name,
165 encoder->base.id);
166 return buf;
167}
168
169char *drm_get_connector_name(struct drm_connector *connector)
170{
171 static char buf[32];
172
173 snprintf(buf, 32, "%s-%d",
174 drm_connector_enum_list[connector->connector_type].name,
175 connector->connector_type_id);
176 return buf;
177}
178EXPORT_SYMBOL(drm_get_connector_name);
179
180char *drm_get_connector_status_name(enum drm_connector_status status)
181{
182 if (status == connector_status_connected)
183 return "connected";
184 else if (status == connector_status_disconnected)
185 return "disconnected";
186 else
187 return "unknown";
188}
189
190/**
191 * drm_mode_object_get - allocate a new identifier
192 * @dev: DRM device
193 * @ptr: object pointer, used to generate unique ID
194 * @type: object type
195 *
196 * LOCKING:
197 * Caller must hold DRM mode_config lock.
198 *
199 * Create a unique identifier based on @ptr in @dev's identifier space. Used
200 * for tracking modes, CRTCs and connectors.
201 *
202 * RETURNS:
203 * New unique (relative to other objects in @dev) integer identifier for the
204 * object.
205 */
206static int drm_mode_object_get(struct drm_device *dev,
207 struct drm_mode_object *obj, uint32_t obj_type)
208{
209 int new_id = 0;
210 int ret;
211
212 WARN(!mutex_is_locked(&dev->mode_config.mutex),
213 "%s called w/o mode_config lock\n", __FUNCTION__);
214again:
215 if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
216 DRM_ERROR("Ran out memory getting a mode number\n");
217 return -EINVAL;
218 }
219
220 ret = idr_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id);
221 if (ret == -EAGAIN)
222 goto again;
223
224 obj->id = new_id;
225 obj->type = obj_type;
226 return 0;
227}
228
229/**
230 * drm_mode_object_put - free an identifer
231 * @dev: DRM device
232 * @id: ID to free
233 *
234 * LOCKING:
235 * Caller must hold DRM mode_config lock.
236 *
237 * Free @id from @dev's unique identifier pool.
238 */
239static void drm_mode_object_put(struct drm_device *dev,
240 struct drm_mode_object *object)
241{
242 idr_remove(&dev->mode_config.crtc_idr, object->id);
243}
244
245void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type)
246{
247 struct drm_mode_object *obj;
248
249 obj = idr_find(&dev->mode_config.crtc_idr, id);
250 if (!obj || (obj->type != type) || (obj->id != id))
251 return NULL;
252
253 return obj;
254}
255EXPORT_SYMBOL(drm_mode_object_find);
256
257/**
258 * drm_crtc_from_fb - find the CRTC structure associated with an fb
259 * @dev: DRM device
260 * @fb: framebuffer in question
261 *
262 * LOCKING:
263 * Caller must hold mode_config lock.
264 *
265 * Find CRTC in the mode_config structure that matches @fb.
266 *
267 * RETURNS:
268 * Pointer to the CRTC or NULL if it wasn't found.
269 */
270struct drm_crtc *drm_crtc_from_fb(struct drm_device *dev,
271 struct drm_framebuffer *fb)
272{
273 struct drm_crtc *crtc;
274
275 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
276 if (crtc->fb == fb)
277 return crtc;
278 }
279 return NULL;
280}
281
282/**
283 * drm_framebuffer_init - initialize a framebuffer
284 * @dev: DRM device
285 *
286 * LOCKING:
287 * Caller must hold mode config lock.
288 *
289 * Allocates an ID for the framebuffer's parent mode object, sets its mode
290 * functions & device file and adds it to the master fd list.
291 *
292 * RETURNS:
293 * Zero on success, error code on falure.
294 */
295int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
296 const struct drm_framebuffer_funcs *funcs)
297{
298 int ret;
299
300 ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
301 if (ret) {
302 return ret;
303 }
304
305 fb->dev = dev;
306 fb->funcs = funcs;
307 dev->mode_config.num_fb++;
308 list_add(&fb->head, &dev->mode_config.fb_list);
309
310 return 0;
311}
312EXPORT_SYMBOL(drm_framebuffer_init);
313
314/**
315 * drm_framebuffer_cleanup - remove a framebuffer object
316 * @fb: framebuffer to remove
317 *
318 * LOCKING:
319 * Caller must hold mode config lock.
320 *
321 * Scans all the CRTCs in @dev's mode_config. If they're using @fb, removes
322 * it, setting it to NULL.
323 */
324void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
325{
326 struct drm_device *dev = fb->dev;
327 struct drm_crtc *crtc;
328
329 /* remove from any CRTC */
330 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
331 if (crtc->fb == fb)
332 crtc->fb = NULL;
333 }
334
335 drm_mode_object_put(dev, &fb->base);
336 list_del(&fb->head);
337 dev->mode_config.num_fb--;
338}
339EXPORT_SYMBOL(drm_framebuffer_cleanup);
340
341/**
342 * drm_crtc_init - Initialise a new CRTC object
343 * @dev: DRM device
344 * @crtc: CRTC object to init
345 * @funcs: callbacks for the new CRTC
346 *
347 * LOCKING:
348 * Caller must hold mode config lock.
349 *
350 * Inits a new object created as base part of an driver crtc object.
351 */
352void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
353 const struct drm_crtc_funcs *funcs)
354{
355 crtc->dev = dev;
356 crtc->funcs = funcs;
357
358 mutex_lock(&dev->mode_config.mutex);
359 drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
360
361 list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
362 dev->mode_config.num_crtc++;
363 mutex_unlock(&dev->mode_config.mutex);
364}
365EXPORT_SYMBOL(drm_crtc_init);
366
367/**
368 * drm_crtc_cleanup - Cleans up the core crtc usage.
369 * @crtc: CRTC to cleanup
370 *
371 * LOCKING:
372 * Caller must hold mode config lock.
373 *
374 * Cleanup @crtc. Removes from drm modesetting space
375 * does NOT free object, caller does that.
376 */
377void drm_crtc_cleanup(struct drm_crtc *crtc)
378{
379 struct drm_device *dev = crtc->dev;
380
381 if (crtc->gamma_store) {
382 kfree(crtc->gamma_store);
383 crtc->gamma_store = NULL;
384 }
385
386 drm_mode_object_put(dev, &crtc->base);
387 list_del(&crtc->head);
388 dev->mode_config.num_crtc--;
389}
390EXPORT_SYMBOL(drm_crtc_cleanup);
391
392/**
393 * drm_mode_probed_add - add a mode to a connector's probed mode list
394 * @connector: connector the new mode
395 * @mode: mode data
396 *
397 * LOCKING:
398 * Caller must hold mode config lock.
399 *
400 * Add @mode to @connector's mode list for later use.
401 */
402void drm_mode_probed_add(struct drm_connector *connector,
403 struct drm_display_mode *mode)
404{
405 list_add(&mode->head, &connector->probed_modes);
406}
407EXPORT_SYMBOL(drm_mode_probed_add);
408
409/**
410 * drm_mode_remove - remove and free a mode
411 * @connector: connector list to modify
412 * @mode: mode to remove
413 *
414 * LOCKING:
415 * Caller must hold mode config lock.
416 *
417 * Remove @mode from @connector's mode list, then free it.
418 */
419void drm_mode_remove(struct drm_connector *connector,
420 struct drm_display_mode *mode)
421{
422 list_del(&mode->head);
423 kfree(mode);
424}
425EXPORT_SYMBOL(drm_mode_remove);
426
427/**
428 * drm_connector_init - Init a preallocated connector
429 * @dev: DRM device
430 * @connector: the connector to init
431 * @funcs: callbacks for this connector
432 * @name: user visible name of the connector
433 *
434 * LOCKING:
435 * Caller must hold @dev's mode_config lock.
436 *
437 * Initialises a preallocated connector. Connectors should be
438 * subclassed as part of driver connector objects.
439 */
440void drm_connector_init(struct drm_device *dev,
441 struct drm_connector *connector,
442 const struct drm_connector_funcs *funcs,
443 int connector_type)
444{
445 mutex_lock(&dev->mode_config.mutex);
446
447 connector->dev = dev;
448 connector->funcs = funcs;
449 drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR);
450 connector->connector_type = connector_type;
451 connector->connector_type_id =
452 ++drm_connector_enum_list[connector_type].count; /* TODO */
453 INIT_LIST_HEAD(&connector->user_modes);
454 INIT_LIST_HEAD(&connector->probed_modes);
455 INIT_LIST_HEAD(&connector->modes);
456 connector->edid_blob_ptr = NULL;
457
458 list_add_tail(&connector->head, &dev->mode_config.connector_list);
459 dev->mode_config.num_connector++;
460
461 drm_connector_attach_property(connector,
462 dev->mode_config.edid_property, 0);
463
464 drm_connector_attach_property(connector,
465 dev->mode_config.dpms_property, 0);
466
467 mutex_unlock(&dev->mode_config.mutex);
468}
469EXPORT_SYMBOL(drm_connector_init);
470
471/**
472 * drm_connector_cleanup - cleans up an initialised connector
473 * @connector: connector to cleanup
474 *
475 * LOCKING:
476 * Caller must hold @dev's mode_config lock.
477 *
478 * Cleans up the connector but doesn't free the object.
479 */
480void drm_connector_cleanup(struct drm_connector *connector)
481{
482 struct drm_device *dev = connector->dev;
483 struct drm_display_mode *mode, *t;
484
485 list_for_each_entry_safe(mode, t, &connector->probed_modes, head)
486 drm_mode_remove(connector, mode);
487
488 list_for_each_entry_safe(mode, t, &connector->modes, head)
489 drm_mode_remove(connector, mode);
490
491 list_for_each_entry_safe(mode, t, &connector->user_modes, head)
492 drm_mode_remove(connector, mode);
493
494 mutex_lock(&dev->mode_config.mutex);
495 drm_mode_object_put(dev, &connector->base);
496 list_del(&connector->head);
497 mutex_unlock(&dev->mode_config.mutex);
498}
499EXPORT_SYMBOL(drm_connector_cleanup);
500
501void drm_encoder_init(struct drm_device *dev,
502 struct drm_encoder *encoder,
503 const struct drm_encoder_funcs *funcs,
504 int encoder_type)
505{
506 mutex_lock(&dev->mode_config.mutex);
507
508 encoder->dev = dev;
509
510 drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
511 encoder->encoder_type = encoder_type;
512 encoder->funcs = funcs;
513
514 list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
515 dev->mode_config.num_encoder++;
516
517 mutex_unlock(&dev->mode_config.mutex);
518}
519EXPORT_SYMBOL(drm_encoder_init);
520
521void drm_encoder_cleanup(struct drm_encoder *encoder)
522{
523 struct drm_device *dev = encoder->dev;
524 mutex_lock(&dev->mode_config.mutex);
525 drm_mode_object_put(dev, &encoder->base);
526 list_del(&encoder->head);
527 mutex_unlock(&dev->mode_config.mutex);
528}
529EXPORT_SYMBOL(drm_encoder_cleanup);
530
531/**
532 * drm_mode_create - create a new display mode
533 * @dev: DRM device
534 *
535 * LOCKING:
536 * Caller must hold DRM mode_config lock.
537 *
538 * Create a new drm_display_mode, give it an ID, and return it.
539 *
540 * RETURNS:
541 * Pointer to new mode on success, NULL on error.
542 */
543struct drm_display_mode *drm_mode_create(struct drm_device *dev)
544{
545 struct drm_display_mode *nmode;
546
547 nmode = kzalloc(sizeof(struct drm_display_mode), GFP_KERNEL);
548 if (!nmode)
549 return NULL;
550
551 drm_mode_object_get(dev, &nmode->base, DRM_MODE_OBJECT_MODE);
552 return nmode;
553}
554EXPORT_SYMBOL(drm_mode_create);
555
556/**
557 * drm_mode_destroy - remove a mode
558 * @dev: DRM device
559 * @mode: mode to remove
560 *
561 * LOCKING:
562 * Caller must hold mode config lock.
563 *
564 * Free @mode's unique identifier, then free it.
565 */
566void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
567{
568 drm_mode_object_put(dev, &mode->base);
569
570 kfree(mode);
571}
572EXPORT_SYMBOL(drm_mode_destroy);
573
574static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
575{
576 struct drm_property *edid;
577 struct drm_property *dpms;
578 int i;
579
580 /*
581 * Standard properties (apply to all connectors)
582 */
583 edid = drm_property_create(dev, DRM_MODE_PROP_BLOB |
584 DRM_MODE_PROP_IMMUTABLE,
585 "EDID", 0);
586 dev->mode_config.edid_property = edid;
587
588 dpms = drm_property_create(dev, DRM_MODE_PROP_ENUM,
589 "DPMS", ARRAY_SIZE(drm_dpms_enum_list));
590 for (i = 0; i < ARRAY_SIZE(drm_dpms_enum_list); i++)
591 drm_property_add_enum(dpms, i, drm_dpms_enum_list[i].type,
592 drm_dpms_enum_list[i].name);
593 dev->mode_config.dpms_property = dpms;
594
595 return 0;
596}
597
598/**
599 * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties
600 * @dev: DRM device
601 *
602 * Called by a driver the first time a DVI-I connector is made.
603 */
604int drm_mode_create_dvi_i_properties(struct drm_device *dev)
605{
606 struct drm_property *dvi_i_selector;
607 struct drm_property *dvi_i_subconnector;
608 int i;
609
610 if (dev->mode_config.dvi_i_select_subconnector_property)
611 return 0;
612
613 dvi_i_selector =
614 drm_property_create(dev, DRM_MODE_PROP_ENUM,
615 "select subconnector",
616 ARRAY_SIZE(drm_dvi_i_select_enum_list));
617 for (i = 0; i < ARRAY_SIZE(drm_dvi_i_select_enum_list); i++)
618 drm_property_add_enum(dvi_i_selector, i,
619 drm_dvi_i_select_enum_list[i].type,
620 drm_dvi_i_select_enum_list[i].name);
621 dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector;
622
623 dvi_i_subconnector =
624 drm_property_create(dev, DRM_MODE_PROP_ENUM |
625 DRM_MODE_PROP_IMMUTABLE,
626 "subconnector",
627 ARRAY_SIZE(drm_dvi_i_subconnector_enum_list));
628 for (i = 0; i < ARRAY_SIZE(drm_dvi_i_subconnector_enum_list); i++)
629 drm_property_add_enum(dvi_i_subconnector, i,
630 drm_dvi_i_subconnector_enum_list[i].type,
631 drm_dvi_i_subconnector_enum_list[i].name);
632 dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector;
633
634 return 0;
635}
636EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);
637
638/**
639 * drm_create_tv_properties - create TV specific connector properties
640 * @dev: DRM device
641 * @num_modes: number of different TV formats (modes) supported
642 * @modes: array of pointers to strings containing name of each format
643 *
644 * Called by a driver's TV initialization routine, this function creates
645 * the TV specific connector properties for a given device. Caller is
646 * responsible for allocating a list of format names and passing them to
647 * this routine.
648 */
649int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
650 char *modes[])
651{
652 struct drm_property *tv_selector;
653 struct drm_property *tv_subconnector;
654 int i;
655
656 if (dev->mode_config.tv_select_subconnector_property)
657 return 0;
658
659 /*
660 * Basic connector properties
661 */
662 tv_selector = drm_property_create(dev, DRM_MODE_PROP_ENUM,
663 "select subconnector",
664 ARRAY_SIZE(drm_tv_select_enum_list));
665 for (i = 0; i < ARRAY_SIZE(drm_tv_select_enum_list); i++)
666 drm_property_add_enum(tv_selector, i,
667 drm_tv_select_enum_list[i].type,
668 drm_tv_select_enum_list[i].name);
669 dev->mode_config.tv_select_subconnector_property = tv_selector;
670
671 tv_subconnector =
672 drm_property_create(dev, DRM_MODE_PROP_ENUM |
673 DRM_MODE_PROP_IMMUTABLE, "subconnector",
674 ARRAY_SIZE(drm_tv_subconnector_enum_list));
675 for (i = 0; i < ARRAY_SIZE(drm_tv_subconnector_enum_list); i++)
676 drm_property_add_enum(tv_subconnector, i,
677 drm_tv_subconnector_enum_list[i].type,
678 drm_tv_subconnector_enum_list[i].name);
679 dev->mode_config.tv_subconnector_property = tv_subconnector;
680
681 /*
682 * Other, TV specific properties: margins & TV modes.
683 */
684 dev->mode_config.tv_left_margin_property =
685 drm_property_create(dev, DRM_MODE_PROP_RANGE,
686 "left margin", 2);
687 dev->mode_config.tv_left_margin_property->values[0] = 0;
688 dev->mode_config.tv_left_margin_property->values[1] = 100;
689
690 dev->mode_config.tv_right_margin_property =
691 drm_property_create(dev, DRM_MODE_PROP_RANGE,
692 "right margin", 2);
693 dev->mode_config.tv_right_margin_property->values[0] = 0;
694 dev->mode_config.tv_right_margin_property->values[1] = 100;
695
696 dev->mode_config.tv_top_margin_property =
697 drm_property_create(dev, DRM_MODE_PROP_RANGE,
698 "top margin", 2);
699 dev->mode_config.tv_top_margin_property->values[0] = 0;
700 dev->mode_config.tv_top_margin_property->values[1] = 100;
701
702 dev->mode_config.tv_bottom_margin_property =
703 drm_property_create(dev, DRM_MODE_PROP_RANGE,
704 "bottom margin", 2);
705 dev->mode_config.tv_bottom_margin_property->values[0] = 0;
706 dev->mode_config.tv_bottom_margin_property->values[1] = 100;
707
708 dev->mode_config.tv_mode_property =
709 drm_property_create(dev, DRM_MODE_PROP_ENUM,
710 "mode", num_modes);
711 for (i = 0; i < num_modes; i++)
712 drm_property_add_enum(dev->mode_config.tv_mode_property, i,
713 i, modes[i]);
714
715 return 0;
716}
717EXPORT_SYMBOL(drm_mode_create_tv_properties);
718
719/**
720 * drm_mode_create_scaling_mode_property - create scaling mode property
721 * @dev: DRM device
722 *
723 * Called by a driver the first time it's needed, must be attached to desired
724 * connectors.
725 */
726int drm_mode_create_scaling_mode_property(struct drm_device *dev)
727{
728 struct drm_property *scaling_mode;
729 int i;
730
731 if (dev->mode_config.scaling_mode_property)
732 return 0;
733
734 scaling_mode =
735 drm_property_create(dev, DRM_MODE_PROP_ENUM, "scaling mode",
736 ARRAY_SIZE(drm_scaling_mode_enum_list));
737 for (i = 0; i < ARRAY_SIZE(drm_scaling_mode_enum_list); i++)
738 drm_property_add_enum(scaling_mode, i,
739 drm_scaling_mode_enum_list[i].type,
740 drm_scaling_mode_enum_list[i].name);
741
742 dev->mode_config.scaling_mode_property = scaling_mode;
743
744 return 0;
745}
746EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
747
748/**
749 * drm_mode_create_dithering_property - create dithering property
750 * @dev: DRM device
751 *
752 * Called by a driver the first time it's needed, must be attached to desired
753 * connectors.
754 */
755int drm_mode_create_dithering_property(struct drm_device *dev)
756{
757 struct drm_property *dithering_mode;
758 int i;
759
760 if (dev->mode_config.dithering_mode_property)
761 return 0;
762
763 dithering_mode =
764 drm_property_create(dev, DRM_MODE_PROP_ENUM, "dithering",
765 ARRAY_SIZE(drm_dithering_mode_enum_list));
766 for (i = 0; i < ARRAY_SIZE(drm_dithering_mode_enum_list); i++)
767 drm_property_add_enum(dithering_mode, i,
768 drm_dithering_mode_enum_list[i].type,
769 drm_dithering_mode_enum_list[i].name);
770 dev->mode_config.dithering_mode_property = dithering_mode;
771
772 return 0;
773}
774EXPORT_SYMBOL(drm_mode_create_dithering_property);
775
776/**
777 * drm_mode_config_init - initialize DRM mode_configuration structure
778 * @dev: DRM device
779 *
780 * LOCKING:
781 * None, should happen single threaded at init time.
782 *
783 * Initialize @dev's mode_config structure, used for tracking the graphics
784 * configuration of @dev.
785 */
786void drm_mode_config_init(struct drm_device *dev)
787{
788 mutex_init(&dev->mode_config.mutex);
789 INIT_LIST_HEAD(&dev->mode_config.fb_list);
790 INIT_LIST_HEAD(&dev->mode_config.fb_kernel_list);
791 INIT_LIST_HEAD(&dev->mode_config.crtc_list);
792 INIT_LIST_HEAD(&dev->mode_config.connector_list);
793 INIT_LIST_HEAD(&dev->mode_config.encoder_list);
794 INIT_LIST_HEAD(&dev->mode_config.property_list);
795 INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
796 idr_init(&dev->mode_config.crtc_idr);
797
798 mutex_lock(&dev->mode_config.mutex);
799 drm_mode_create_standard_connector_properties(dev);
800 mutex_unlock(&dev->mode_config.mutex);
801
802 /* Just to be sure */
803 dev->mode_config.num_fb = 0;
804 dev->mode_config.num_connector = 0;
805 dev->mode_config.num_crtc = 0;
806 dev->mode_config.num_encoder = 0;
807 dev->mode_config.hotplug_counter = 0;
808}
809EXPORT_SYMBOL(drm_mode_config_init);
810
811int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
812{
813 uint32_t total_objects = 0;
814
815 total_objects += dev->mode_config.num_crtc;
816 total_objects += dev->mode_config.num_connector;
817 total_objects += dev->mode_config.num_encoder;
818
819 if (total_objects == 0)
820 return -EINVAL;
821
822 group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
823 if (!group->id_list)
824 return -ENOMEM;
825
826 group->num_crtcs = 0;
827 group->num_connectors = 0;
828 group->num_encoders = 0;
829 return 0;
830}
831
832int drm_mode_group_init_legacy_group(struct drm_device *dev,
833 struct drm_mode_group *group)
834{
835 struct drm_crtc *crtc;
836 struct drm_encoder *encoder;
837 struct drm_connector *connector;
838 int ret;
839
840 if ((ret = drm_mode_group_init(dev, group)))
841 return ret;
842
843 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
844 group->id_list[group->num_crtcs++] = crtc->base.id;
845
846 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
847 group->id_list[group->num_crtcs + group->num_encoders++] =
848 encoder->base.id;
849
850 list_for_each_entry(connector, &dev->mode_config.connector_list, head)
851 group->id_list[group->num_crtcs + group->num_encoders +
852 group->num_connectors++] = connector->base.id;
853
854 return 0;
855}
856
857/**
858 * drm_mode_config_cleanup - free up DRM mode_config info
859 * @dev: DRM device
860 *
861 * LOCKING:
862 * Caller must hold mode config lock.
863 *
864 * Free up all the connectors and CRTCs associated with this DRM device, then
865 * free up the framebuffers and associated buffer objects.
866 *
867 * FIXME: cleanup any dangling user buffer objects too
868 */
869void drm_mode_config_cleanup(struct drm_device *dev)
870{
871 struct drm_connector *connector, *ot;
872 struct drm_crtc *crtc, *ct;
873 struct drm_encoder *encoder, *enct;
874 struct drm_framebuffer *fb, *fbt;
875 struct drm_property *property, *pt;
876
877 list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
878 head) {
879 encoder->funcs->destroy(encoder);
880 }
881
882 list_for_each_entry_safe(connector, ot,
883 &dev->mode_config.connector_list, head) {
884 connector->funcs->destroy(connector);
885 }
886
887 list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
888 head) {
889 drm_property_destroy(dev, property);
890 }
891
892 list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
893 fb->funcs->destroy(fb);
894 }
895
896 list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
897 crtc->funcs->destroy(crtc);
898 }
899
900}
901EXPORT_SYMBOL(drm_mode_config_cleanup);
902
903int drm_mode_hotplug_ioctl(struct drm_device *dev,
904 void *data, struct drm_file *file_priv)
905{
906 struct drm_mode_hotplug *arg = data;
907
908 arg->counter = dev->mode_config.hotplug_counter;
909
910 return 0;
911}
912
913/**
914 * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
915 * @out: drm_mode_modeinfo struct to return to the user
916 * @in: drm_display_mode to use
917 *
918 * LOCKING:
919 * None.
920 *
921 * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
922 * the user.
923 */
924void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
925 struct drm_display_mode *in)
926{
927 out->clock = in->clock;
928 out->hdisplay = in->hdisplay;
929 out->hsync_start = in->hsync_start;
930 out->hsync_end = in->hsync_end;
931 out->htotal = in->htotal;
932 out->hskew = in->hskew;
933 out->vdisplay = in->vdisplay;
934 out->vsync_start = in->vsync_start;
935 out->vsync_end = in->vsync_end;
936 out->vtotal = in->vtotal;
937 out->vscan = in->vscan;
938 out->vrefresh = in->vrefresh;
939 out->flags = in->flags;
940 out->type = in->type;
941 strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
942 out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
943}
944
945/**
946 * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode
947 * @out: drm_display_mode to return to the user
948 * @in: drm_mode_modeinfo to use
949 *
950 * LOCKING:
951 * None.
952 *
953 * Convert a drm_mode_modeinfo into a drm_display_mode structure to return to
954 * the caller.
955 */
956void drm_crtc_convert_umode(struct drm_display_mode *out,
957 struct drm_mode_modeinfo *in)
958{
959 out->clock = in->clock;
960 out->hdisplay = in->hdisplay;
961 out->hsync_start = in->hsync_start;
962 out->hsync_end = in->hsync_end;
963 out->htotal = in->htotal;
964 out->hskew = in->hskew;
965 out->vdisplay = in->vdisplay;
966 out->vsync_start = in->vsync_start;
967 out->vsync_end = in->vsync_end;
968 out->vtotal = in->vtotal;
969 out->vscan = in->vscan;
970 out->vrefresh = in->vrefresh;
971 out->flags = in->flags;
972 out->type = in->type;
973 strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
974 out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
975}
976
977/**
978 * drm_mode_getresources - get graphics configuration
979 * @inode: inode from the ioctl
980 * @filp: file * from the ioctl
981 * @cmd: cmd from ioctl
982 * @arg: arg from ioctl
983 *
984 * LOCKING:
985 * Takes mode config lock.
986 *
987 * Construct a set of configuration description structures and return
988 * them to the user, including CRTC, connector and framebuffer configuration.
989 *
990 * Called by the user via ioctl.
991 *
992 * RETURNS:
993 * Zero on success, errno on failure.
994 */
995int drm_mode_getresources(struct drm_device *dev, void *data,
996 struct drm_file *file_priv)
997{
998 struct drm_mode_card_res *card_res = data;
999 struct list_head *lh;
1000 struct drm_framebuffer *fb;
1001 struct drm_connector *connector;
1002 struct drm_crtc *crtc;
1003 struct drm_encoder *encoder;
1004 int ret = 0;
1005 int connector_count = 0;
1006 int crtc_count = 0;
1007 int fb_count = 0;
1008 int encoder_count = 0;
1009 int copied = 0, i;
1010 uint32_t __user *fb_id;
1011 uint32_t __user *crtc_id;
1012 uint32_t __user *connector_id;
1013 uint32_t __user *encoder_id;
1014 struct drm_mode_group *mode_group;
1015
1016 mutex_lock(&dev->mode_config.mutex);
1017
1018 /*
1019 * For the non-control nodes we need to limit the list of resources
1020 * by IDs in the group list for this node
1021 */
1022 list_for_each(lh, &file_priv->fbs)
1023 fb_count++;
1024
1025 mode_group = &file_priv->master->minor->mode_group;
1026 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1027
1028 list_for_each(lh, &dev->mode_config.crtc_list)
1029 crtc_count++;
1030
1031 list_for_each(lh, &dev->mode_config.connector_list)
1032 connector_count++;
1033
1034 list_for_each(lh, &dev->mode_config.encoder_list)
1035 encoder_count++;
1036 } else {
1037
1038 crtc_count = mode_group->num_crtcs;
1039 connector_count = mode_group->num_connectors;
1040 encoder_count = mode_group->num_encoders;
1041 }
1042
1043 card_res->max_height = dev->mode_config.max_height;
1044 card_res->min_height = dev->mode_config.min_height;
1045 card_res->max_width = dev->mode_config.max_width;
1046 card_res->min_width = dev->mode_config.min_width;
1047
1048 /* handle this in 4 parts */
1049 /* FBs */
1050 if (card_res->count_fbs >= fb_count) {
1051 copied = 0;
1052 fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr;
1053 list_for_each_entry(fb, &file_priv->fbs, head) {
1054 if (put_user(fb->base.id, fb_id + copied)) {
1055 ret = -EFAULT;
1056 goto out;
1057 }
1058 copied++;
1059 }
1060 }
1061 card_res->count_fbs = fb_count;
1062
1063 /* CRTCs */
1064 if (card_res->count_crtcs >= crtc_count) {
1065 copied = 0;
1066 crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr;
1067 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1068 list_for_each_entry(crtc, &dev->mode_config.crtc_list,
1069 head) {
1070 DRM_DEBUG("CRTC ID is %d\n", crtc->base.id);
1071 if (put_user(crtc->base.id, crtc_id + copied)) {
1072 ret = -EFAULT;
1073 goto out;
1074 }
1075 copied++;
1076 }
1077 } else {
1078 for (i = 0; i < mode_group->num_crtcs; i++) {
1079 if (put_user(mode_group->id_list[i],
1080 crtc_id + copied)) {
1081 ret = -EFAULT;
1082 goto out;
1083 }
1084 copied++;
1085 }
1086 }
1087 }
1088 card_res->count_crtcs = crtc_count;
1089
1090 /* Encoders */
1091 if (card_res->count_encoders >= encoder_count) {
1092 copied = 0;
1093 encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr;
1094 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1095 list_for_each_entry(encoder,
1096 &dev->mode_config.encoder_list,
1097 head) {
1098 DRM_DEBUG("ENCODER ID is %d\n",
1099 encoder->base.id);
1100 if (put_user(encoder->base.id, encoder_id +
1101 copied)) {
1102 ret = -EFAULT;
1103 goto out;
1104 }
1105 copied++;
1106 }
1107 } else {
1108 for (i = mode_group->num_crtcs; i < mode_group->num_crtcs + mode_group->num_encoders; i++) {
1109 if (put_user(mode_group->id_list[i],
1110 encoder_id + copied)) {
1111 ret = -EFAULT;
1112 goto out;
1113 }
1114 copied++;
1115 }
1116
1117 }
1118 }
1119 card_res->count_encoders = encoder_count;
1120
1121 /* Connectors */
1122 if (card_res->count_connectors >= connector_count) {
1123 copied = 0;
1124 connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr;
1125 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1126 list_for_each_entry(connector,
1127 &dev->mode_config.connector_list,
1128 head) {
1129 DRM_DEBUG("CONNECTOR ID is %d\n",
1130 connector->base.id);
1131 if (put_user(connector->base.id,
1132 connector_id + copied)) {
1133 ret = -EFAULT;
1134 goto out;
1135 }
1136 copied++;
1137 }
1138 } else {
1139 int start = mode_group->num_crtcs +
1140 mode_group->num_encoders;
1141 for (i = start; i < start + mode_group->num_connectors; i++) {
1142 if (put_user(mode_group->id_list[i],
1143 connector_id + copied)) {
1144 ret = -EFAULT;
1145 goto out;
1146 }
1147 copied++;
1148 }
1149 }
1150 }
1151 card_res->count_connectors = connector_count;
1152
1153 DRM_DEBUG("Counted %d %d %d\n", card_res->count_crtcs,
1154 card_res->count_connectors, card_res->count_encoders);
1155
1156out:
1157 mutex_unlock(&dev->mode_config.mutex);
1158 return ret;
1159}
1160
1161/**
1162 * drm_mode_getcrtc - get CRTC configuration
1163 * @inode: inode from the ioctl
1164 * @filp: file * from the ioctl
1165 * @cmd: cmd from ioctl
1166 * @arg: arg from ioctl
1167 *
1168 * LOCKING:
1169 * Caller? (FIXME)
1170 *
1171 * Construct a CRTC configuration structure to return to the user.
1172 *
1173 * Called by the user via ioctl.
1174 *
1175 * RETURNS:
1176 * Zero on success, errno on failure.
1177 */
1178int drm_mode_getcrtc(struct drm_device *dev,
1179 void *data, struct drm_file *file_priv)
1180{
1181 struct drm_mode_crtc *crtc_resp = data;
1182 struct drm_crtc *crtc;
1183 struct drm_mode_object *obj;
1184 int ret = 0;
1185
1186 mutex_lock(&dev->mode_config.mutex);
1187
1188 obj = drm_mode_object_find(dev, crtc_resp->crtc_id,
1189 DRM_MODE_OBJECT_CRTC);
1190 if (!obj) {
1191 ret = -EINVAL;
1192 goto out;
1193 }
1194 crtc = obj_to_crtc(obj);
1195
1196 crtc_resp->x = crtc->x;
1197 crtc_resp->y = crtc->y;
1198 crtc_resp->gamma_size = crtc->gamma_size;
1199 if (crtc->fb)
1200 crtc_resp->fb_id = crtc->fb->base.id;
1201 else
1202 crtc_resp->fb_id = 0;
1203
1204 if (crtc->enabled) {
1205
1206 drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode);
1207 crtc_resp->mode_valid = 1;
1208
1209 } else {
1210 crtc_resp->mode_valid = 0;
1211 }
1212
1213out:
1214 mutex_unlock(&dev->mode_config.mutex);
1215 return ret;
1216}
1217
1218/**
1219 * drm_mode_getconnector - get connector configuration
1220 * @inode: inode from the ioctl
1221 * @filp: file * from the ioctl
1222 * @cmd: cmd from ioctl
1223 * @arg: arg from ioctl
1224 *
1225 * LOCKING:
1226 * Caller? (FIXME)
1227 *
1228 * Construct a connector configuration structure to return to the user.
1229 *
1230 * Called by the user via ioctl.
1231 *
1232 * RETURNS:
1233 * Zero on success, errno on failure.
1234 */
1235int drm_mode_getconnector(struct drm_device *dev, void *data,
1236 struct drm_file *file_priv)
1237{
1238 struct drm_mode_get_connector *out_resp = data;
1239 struct drm_mode_object *obj;
1240 struct drm_connector *connector;
1241 struct drm_display_mode *mode;
1242 int mode_count = 0;
1243 int props_count = 0;
1244 int encoders_count = 0;
1245 int ret = 0;
1246 int copied = 0;
1247 int i;
1248 struct drm_mode_modeinfo u_mode;
1249 struct drm_mode_modeinfo __user *mode_ptr;
1250 uint32_t __user *prop_ptr;
1251 uint64_t __user *prop_values;
1252 uint32_t __user *encoder_ptr;
1253
1254 memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
1255
1256 DRM_DEBUG("connector id %d:\n", out_resp->connector_id);
1257
1258 mutex_lock(&dev->mode_config.mutex);
1259
1260 obj = drm_mode_object_find(dev, out_resp->connector_id,
1261 DRM_MODE_OBJECT_CONNECTOR);
1262 if (!obj) {
1263 ret = -EINVAL;
1264 goto out;
1265 }
1266 connector = obj_to_connector(obj);
1267
1268 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
1269 if (connector->property_ids[i] != 0) {
1270 props_count++;
1271 }
1272 }
1273
1274 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1275 if (connector->encoder_ids[i] != 0) {
1276 encoders_count++;
1277 }
1278 }
1279
1280 if (out_resp->count_modes == 0) {
1281 connector->funcs->fill_modes(connector,
1282 dev->mode_config.max_width,
1283 dev->mode_config.max_height);
1284 }
1285
1286 /* delayed so we get modes regardless of pre-fill_modes state */
1287 list_for_each_entry(mode, &connector->modes, head)
1288 mode_count++;
1289
1290 out_resp->connector_id = connector->base.id;
1291 out_resp->connector_type = connector->connector_type;
1292 out_resp->connector_type_id = connector->connector_type_id;
1293 out_resp->mm_width = connector->display_info.width_mm;
1294 out_resp->mm_height = connector->display_info.height_mm;
1295 out_resp->subpixel = connector->display_info.subpixel_order;
1296 out_resp->connection = connector->status;
1297 if (connector->encoder)
1298 out_resp->encoder_id = connector->encoder->base.id;
1299 else
1300 out_resp->encoder_id = 0;
1301
1302 /*
1303 * This ioctl is called twice, once to determine how much space is
1304 * needed, and the 2nd time to fill it.
1305 */
1306 if ((out_resp->count_modes >= mode_count) && mode_count) {
1307 copied = 0;
1308 mode_ptr = (struct drm_mode_modeinfo *)(unsigned long)out_resp->modes_ptr;
1309 list_for_each_entry(mode, &connector->modes, head) {
1310 drm_crtc_convert_to_umode(&u_mode, mode);
1311 if (copy_to_user(mode_ptr + copied,
1312 &u_mode, sizeof(u_mode))) {
1313 ret = -EFAULT;
1314 goto out;
1315 }
1316 copied++;
1317 }
1318 }
1319 out_resp->count_modes = mode_count;
1320
1321 if ((out_resp->count_props >= props_count) && props_count) {
1322 copied = 0;
1323 prop_ptr = (uint32_t *)(unsigned long)(out_resp->props_ptr);
1324 prop_values = (uint64_t *)(unsigned long)(out_resp->prop_values_ptr);
1325 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
1326 if (connector->property_ids[i] != 0) {
1327 if (put_user(connector->property_ids[i],
1328 prop_ptr + copied)) {
1329 ret = -EFAULT;
1330 goto out;
1331 }
1332
1333 if (put_user(connector->property_values[i],
1334 prop_values + copied)) {
1335 ret = -EFAULT;
1336 goto out;
1337 }
1338 copied++;
1339 }
1340 }
1341 }
1342 out_resp->count_props = props_count;
1343
1344 if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
1345 copied = 0;
1346 encoder_ptr = (uint32_t *)(unsigned long)(out_resp->encoders_ptr);
1347 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1348 if (connector->encoder_ids[i] != 0) {
1349 if (put_user(connector->encoder_ids[i],
1350 encoder_ptr + copied)) {
1351 ret = -EFAULT;
1352 goto out;
1353 }
1354 copied++;
1355 }
1356 }
1357 }
1358 out_resp->count_encoders = encoders_count;
1359
1360out:
1361 mutex_unlock(&dev->mode_config.mutex);
1362 return ret;
1363}
1364
1365int drm_mode_getencoder(struct drm_device *dev, void *data,
1366 struct drm_file *file_priv)
1367{
1368 struct drm_mode_get_encoder *enc_resp = data;
1369 struct drm_mode_object *obj;
1370 struct drm_encoder *encoder;
1371 int ret = 0;
1372
1373 mutex_lock(&dev->mode_config.mutex);
1374 obj = drm_mode_object_find(dev, enc_resp->encoder_id,
1375 DRM_MODE_OBJECT_ENCODER);
1376 if (!obj) {
1377 ret = -EINVAL;
1378 goto out;
1379 }
1380 encoder = obj_to_encoder(obj);
1381
1382 if (encoder->crtc)
1383 enc_resp->crtc_id = encoder->crtc->base.id;
1384 else
1385 enc_resp->crtc_id = 0;
1386 enc_resp->encoder_type = encoder->encoder_type;
1387 enc_resp->encoder_id = encoder->base.id;
1388 enc_resp->possible_crtcs = encoder->possible_crtcs;
1389 enc_resp->possible_clones = encoder->possible_clones;
1390
1391out:
1392 mutex_unlock(&dev->mode_config.mutex);
1393 return ret;
1394}
1395
1396/**
1397 * drm_mode_setcrtc - set CRTC configuration
1398 * @inode: inode from the ioctl
1399 * @filp: file * from the ioctl
1400 * @cmd: cmd from ioctl
1401 * @arg: arg from ioctl
1402 *
1403 * LOCKING:
1404 * Caller? (FIXME)
1405 *
1406 * Build a new CRTC configuration based on user request.
1407 *
1408 * Called by the user via ioctl.
1409 *
1410 * RETURNS:
1411 * Zero on success, errno on failure.
1412 */
1413int drm_mode_setcrtc(struct drm_device *dev, void *data,
1414 struct drm_file *file_priv)
1415{
1416 struct drm_mode_config *config = &dev->mode_config;
1417 struct drm_mode_crtc *crtc_req = data;
1418 struct drm_mode_object *obj;
1419 struct drm_crtc *crtc, *crtcfb;
1420 struct drm_connector **connector_set = NULL, *connector;
1421 struct drm_framebuffer *fb = NULL;
1422 struct drm_display_mode *mode = NULL;
1423 struct drm_mode_set set;
1424 uint32_t __user *set_connectors_ptr;
1425 int ret = 0;
1426 int i;
1427
1428 mutex_lock(&dev->mode_config.mutex);
1429 obj = drm_mode_object_find(dev, crtc_req->crtc_id,
1430 DRM_MODE_OBJECT_CRTC);
1431 if (!obj) {
1432 DRM_DEBUG("Unknown CRTC ID %d\n", crtc_req->crtc_id);
1433 ret = -EINVAL;
1434 goto out;
1435 }
1436 crtc = obj_to_crtc(obj);
1437
1438 if (crtc_req->mode_valid) {
1439 /* If we have a mode we need a framebuffer. */
1440 /* If we pass -1, set the mode with the currently bound fb */
1441 if (crtc_req->fb_id == -1) {
1442 list_for_each_entry(crtcfb,
1443 &dev->mode_config.crtc_list, head) {
1444 if (crtcfb == crtc) {
1445 DRM_DEBUG("Using current fb for setmode\n");
1446 fb = crtc->fb;
1447 }
1448 }
1449 } else {
1450 obj = drm_mode_object_find(dev, crtc_req->fb_id,
1451 DRM_MODE_OBJECT_FB);
1452 if (!obj) {
1453 DRM_DEBUG("Unknown FB ID%d\n", crtc_req->fb_id);
1454 ret = -EINVAL;
1455 goto out;
1456 }
1457 fb = obj_to_fb(obj);
1458 }
1459
1460 mode = drm_mode_create(dev);
1461 drm_crtc_convert_umode(mode, &crtc_req->mode);
1462 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
1463 }
1464
1465 if (crtc_req->count_connectors == 0 && mode) {
1466 DRM_DEBUG("Count connectors is 0 but mode set\n");
1467 ret = -EINVAL;
1468 goto out;
1469 }
1470
1471 if (crtc_req->count_connectors > 0 && !mode && !fb) {
1472 DRM_DEBUG("Count connectors is %d but no mode or fb set\n",
1473 crtc_req->count_connectors);
1474 ret = -EINVAL;
1475 goto out;
1476 }
1477
1478 if (crtc_req->count_connectors > 0) {
1479 u32 out_id;
1480
1481 /* Avoid unbounded kernel memory allocation */
1482 if (crtc_req->count_connectors > config->num_connector) {
1483 ret = -EINVAL;
1484 goto out;
1485 }
1486
1487 connector_set = kmalloc(crtc_req->count_connectors *
1488 sizeof(struct drm_connector *),
1489 GFP_KERNEL);
1490 if (!connector_set) {
1491 ret = -ENOMEM;
1492 goto out;
1493 }
1494
1495 for (i = 0; i < crtc_req->count_connectors; i++) {
1496 set_connectors_ptr = (uint32_t *)(unsigned long)crtc_req->set_connectors_ptr;
1497 if (get_user(out_id, &set_connectors_ptr[i])) {
1498 ret = -EFAULT;
1499 goto out;
1500 }
1501
1502 obj = drm_mode_object_find(dev, out_id,
1503 DRM_MODE_OBJECT_CONNECTOR);
1504 if (!obj) {
1505 DRM_DEBUG("Connector id %d unknown\n", out_id);
1506 ret = -EINVAL;
1507 goto out;
1508 }
1509 connector = obj_to_connector(obj);
1510
1511 connector_set[i] = connector;
1512 }
1513 }
1514
1515 set.crtc = crtc;
1516 set.x = crtc_req->x;
1517 set.y = crtc_req->y;
1518 set.mode = mode;
1519 set.connectors = connector_set;
1520 set.num_connectors = crtc_req->count_connectors;
1521 set.fb =fb;
1522 ret = crtc->funcs->set_config(&set);
1523
1524out:
1525 kfree(connector_set);
1526 mutex_unlock(&dev->mode_config.mutex);
1527 return ret;
1528}
1529
1530int drm_mode_cursor_ioctl(struct drm_device *dev,
1531 void *data, struct drm_file *file_priv)
1532{
1533 struct drm_mode_cursor *req = data;
1534 struct drm_mode_object *obj;
1535 struct drm_crtc *crtc;
1536 int ret = 0;
1537
1538 DRM_DEBUG("\n");
1539
1540 if (!req->flags) {
1541 DRM_ERROR("no operation set\n");
1542 return -EINVAL;
1543 }
1544
1545 mutex_lock(&dev->mode_config.mutex);
1546 obj = drm_mode_object_find(dev, req->crtc, DRM_MODE_OBJECT_CRTC);
1547 if (!obj) {
1548 DRM_DEBUG("Unknown CRTC ID %d\n", req->crtc);
1549 ret = -EINVAL;
1550 goto out;
1551 }
1552 crtc = obj_to_crtc(obj);
1553
1554 if (req->flags & DRM_MODE_CURSOR_BO) {
1555 if (!crtc->funcs->cursor_set) {
1556 DRM_ERROR("crtc does not support cursor\n");
1557 ret = -ENXIO;
1558 goto out;
1559 }
1560 /* Turns off the cursor if handle is 0 */
1561 ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
1562 req->width, req->height);
1563 }
1564
1565 if (req->flags & DRM_MODE_CURSOR_MOVE) {
1566 if (crtc->funcs->cursor_move) {
1567 ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
1568 } else {
1569 DRM_ERROR("crtc does not support cursor\n");
1570 ret = -EFAULT;
1571 goto out;
1572 }
1573 }
1574out:
1575 mutex_unlock(&dev->mode_config.mutex);
1576 return ret;
1577}
1578
1579/**
1580 * drm_mode_addfb - add an FB to the graphics configuration
1581 * @inode: inode from the ioctl
1582 * @filp: file * from the ioctl
1583 * @cmd: cmd from ioctl
1584 * @arg: arg from ioctl
1585 *
1586 * LOCKING:
1587 * Takes mode config lock.
1588 *
1589 * Add a new FB to the specified CRTC, given a user request.
1590 *
1591 * Called by the user via ioctl.
1592 *
1593 * RETURNS:
1594 * Zero on success, errno on failure.
1595 */
1596int drm_mode_addfb(struct drm_device *dev,
1597 void *data, struct drm_file *file_priv)
1598{
1599 struct drm_mode_fb_cmd *r = data;
1600 struct drm_mode_config *config = &dev->mode_config;
1601 struct drm_framebuffer *fb;
1602 int ret = 0;
1603
1604 if ((config->min_width > r->width) || (r->width > config->max_width)) {
1605 DRM_ERROR("mode new framebuffer width not within limits\n");
1606 return -EINVAL;
1607 }
1608 if ((config->min_height > r->height) || (r->height > config->max_height)) {
1609 DRM_ERROR("mode new framebuffer height not within limits\n");
1610 return -EINVAL;
1611 }
1612
1613 mutex_lock(&dev->mode_config.mutex);
1614
1615 /* TODO check buffer is sufficently large */
1616 /* TODO setup destructor callback */
1617
1618 fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
1619 if (!fb) {
1620 DRM_ERROR("could not create framebuffer\n");
1621 ret = -EINVAL;
1622 goto out;
1623 }
1624
1625 r->buffer_id = fb->base.id;
1626 list_add(&fb->filp_head, &file_priv->fbs);
1627
1628out:
1629 mutex_unlock(&dev->mode_config.mutex);
1630 return ret;
1631}
1632
1633/**
1634 * drm_mode_rmfb - remove an FB from the configuration
1635 * @inode: inode from the ioctl
1636 * @filp: file * from the ioctl
1637 * @cmd: cmd from ioctl
1638 * @arg: arg from ioctl
1639 *
1640 * LOCKING:
1641 * Takes mode config lock.
1642 *
1643 * Remove the FB specified by the user.
1644 *
1645 * Called by the user via ioctl.
1646 *
1647 * RETURNS:
1648 * Zero on success, errno on failure.
1649 */
1650int drm_mode_rmfb(struct drm_device *dev,
1651 void *data, struct drm_file *file_priv)
1652{
1653 struct drm_mode_object *obj;
1654 struct drm_framebuffer *fb = NULL;
1655 struct drm_framebuffer *fbl = NULL;
1656 uint32_t *id = data;
1657 int ret = 0;
1658 int found = 0;
1659
1660 mutex_lock(&dev->mode_config.mutex);
1661 obj = drm_mode_object_find(dev, *id, DRM_MODE_OBJECT_FB);
1662 /* TODO check that we realy get a framebuffer back. */
1663 if (!obj) {
1664 DRM_ERROR("mode invalid framebuffer id\n");
1665 ret = -EINVAL;
1666 goto out;
1667 }
1668 fb = obj_to_fb(obj);
1669
1670 list_for_each_entry(fbl, &file_priv->fbs, filp_head)
1671 if (fb == fbl)
1672 found = 1;
1673
1674 if (!found) {
1675 DRM_ERROR("tried to remove a fb that we didn't own\n");
1676 ret = -EINVAL;
1677 goto out;
1678 }
1679
1680 /* TODO release all crtc connected to the framebuffer */
1681 /* TODO unhock the destructor from the buffer object */
1682
1683 list_del(&fb->filp_head);
1684 fb->funcs->destroy(fb);
1685
1686out:
1687 mutex_unlock(&dev->mode_config.mutex);
1688 return ret;
1689}
1690
1691/**
1692 * drm_mode_getfb - get FB info
1693 * @inode: inode from the ioctl
1694 * @filp: file * from the ioctl
1695 * @cmd: cmd from ioctl
1696 * @arg: arg from ioctl
1697 *
1698 * LOCKING:
1699 * Caller? (FIXME)
1700 *
1701 * Lookup the FB given its ID and return info about it.
1702 *
1703 * Called by the user via ioctl.
1704 *
1705 * RETURNS:
1706 * Zero on success, errno on failure.
1707 */
1708int drm_mode_getfb(struct drm_device *dev,
1709 void *data, struct drm_file *file_priv)
1710{
1711 struct drm_mode_fb_cmd *r = data;
1712 struct drm_mode_object *obj;
1713 struct drm_framebuffer *fb;
1714 int ret = 0;
1715
1716 mutex_lock(&dev->mode_config.mutex);
1717 obj = drm_mode_object_find(dev, r->buffer_id, DRM_MODE_OBJECT_FB);
1718 if (!obj) {
1719 DRM_ERROR("invalid framebuffer id\n");
1720 ret = -EINVAL;
1721 goto out;
1722 }
1723 fb = obj_to_fb(obj);
1724
1725 r->height = fb->height;
1726 r->width = fb->width;
1727 r->depth = fb->depth;
1728 r->bpp = fb->bits_per_pixel;
1729 r->pitch = fb->pitch;
1730 fb->funcs->create_handle(fb, file_priv, &r->handle);
1731
1732out:
1733 mutex_unlock(&dev->mode_config.mutex);
1734 return ret;
1735}
1736
1737/**
1738 * drm_fb_release - remove and free the FBs on this file
1739 * @filp: file * from the ioctl
1740 *
1741 * LOCKING:
1742 * Takes mode config lock.
1743 *
1744 * Destroy all the FBs associated with @filp.
1745 *
1746 * Called by the user via ioctl.
1747 *
1748 * RETURNS:
1749 * Zero on success, errno on failure.
1750 */
1751void drm_fb_release(struct file *filp)
1752{
1753 struct drm_file *priv = filp->private_data;
1754 struct drm_device *dev = priv->minor->dev;
1755 struct drm_framebuffer *fb, *tfb;
1756
1757 mutex_lock(&dev->mode_config.mutex);
1758 list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
1759 list_del(&fb->filp_head);
1760 fb->funcs->destroy(fb);
1761 }
1762 mutex_unlock(&dev->mode_config.mutex);
1763}
1764
1765/**
1766 * drm_mode_attachmode - add a mode to the user mode list
1767 * @dev: DRM device
1768 * @connector: connector to add the mode to
1769 * @mode: mode to add
1770 *
1771 * Add @mode to @connector's user mode list.
1772 */
1773static int drm_mode_attachmode(struct drm_device *dev,
1774 struct drm_connector *connector,
1775 struct drm_display_mode *mode)
1776{
1777 int ret = 0;
1778
1779 list_add_tail(&mode->head, &connector->user_modes);
1780 return ret;
1781}
1782
1783int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc,
1784 struct drm_display_mode *mode)
1785{
1786 struct drm_connector *connector;
1787 int ret = 0;
1788 struct drm_display_mode *dup_mode;
1789 int need_dup = 0;
1790 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1791 if (!connector->encoder)
1792 break;
1793 if (connector->encoder->crtc == crtc) {
1794 if (need_dup)
1795 dup_mode = drm_mode_duplicate(dev, mode);
1796 else
1797 dup_mode = mode;
1798 ret = drm_mode_attachmode(dev, connector, dup_mode);
1799 if (ret)
1800 return ret;
1801 need_dup = 1;
1802 }
1803 }
1804 return 0;
1805}
1806EXPORT_SYMBOL(drm_mode_attachmode_crtc);
1807
1808static int drm_mode_detachmode(struct drm_device *dev,
1809 struct drm_connector *connector,
1810 struct drm_display_mode *mode)
1811{
1812 int found = 0;
1813 int ret = 0;
1814 struct drm_display_mode *match_mode, *t;
1815
1816 list_for_each_entry_safe(match_mode, t, &connector->user_modes, head) {
1817 if (drm_mode_equal(match_mode, mode)) {
1818 list_del(&match_mode->head);
1819 drm_mode_destroy(dev, match_mode);
1820 found = 1;
1821 break;
1822 }
1823 }
1824
1825 if (!found)
1826 ret = -EINVAL;
1827
1828 return ret;
1829}
1830
1831int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode)
1832{
1833 struct drm_connector *connector;
1834
1835 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1836 drm_mode_detachmode(dev, connector, mode);
1837 }
1838 return 0;
1839}
1840EXPORT_SYMBOL(drm_mode_detachmode_crtc);
1841
1842/**
1843 * drm_fb_attachmode - Attach a user mode to an connector
1844 * @inode: inode from the ioctl
1845 * @filp: file * from the ioctl
1846 * @cmd: cmd from ioctl
1847 * @arg: arg from ioctl
1848 *
1849 * This attaches a user specified mode to an connector.
1850 * Called by the user via ioctl.
1851 *
1852 * RETURNS:
1853 * Zero on success, errno on failure.
1854 */
1855int drm_mode_attachmode_ioctl(struct drm_device *dev,
1856 void *data, struct drm_file *file_priv)
1857{
1858 struct drm_mode_mode_cmd *mode_cmd = data;
1859 struct drm_connector *connector;
1860 struct drm_display_mode *mode;
1861 struct drm_mode_object *obj;
1862 struct drm_mode_modeinfo *umode = &mode_cmd->mode;
1863 int ret = 0;
1864
1865 mutex_lock(&dev->mode_config.mutex);
1866
1867 obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
1868 if (!obj) {
1869 ret = -EINVAL;
1870 goto out;
1871 }
1872 connector = obj_to_connector(obj);
1873
1874 mode = drm_mode_create(dev);
1875 if (!mode) {
1876 ret = -ENOMEM;
1877 goto out;
1878 }
1879
1880 drm_crtc_convert_umode(mode, umode);
1881
1882 ret = drm_mode_attachmode(dev, connector, mode);
1883out:
1884 mutex_unlock(&dev->mode_config.mutex);
1885 return ret;
1886}
1887
1888
1889/**
1890 * drm_fb_detachmode - Detach a user specified mode from an connector
1891 * @inode: inode from the ioctl
1892 * @filp: file * from the ioctl
1893 * @cmd: cmd from ioctl
1894 * @arg: arg from ioctl
1895 *
1896 * Called by the user via ioctl.
1897 *
1898 * RETURNS:
1899 * Zero on success, errno on failure.
1900 */
1901int drm_mode_detachmode_ioctl(struct drm_device *dev,
1902 void *data, struct drm_file *file_priv)
1903{
1904 struct drm_mode_object *obj;
1905 struct drm_mode_mode_cmd *mode_cmd = data;
1906 struct drm_connector *connector;
1907 struct drm_display_mode mode;
1908 struct drm_mode_modeinfo *umode = &mode_cmd->mode;
1909 int ret = 0;
1910
1911 mutex_lock(&dev->mode_config.mutex);
1912
1913 obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
1914 if (!obj) {
1915 ret = -EINVAL;
1916 goto out;
1917 }
1918 connector = obj_to_connector(obj);
1919
1920 drm_crtc_convert_umode(&mode, umode);
1921 ret = drm_mode_detachmode(dev, connector, &mode);
1922out:
1923 mutex_unlock(&dev->mode_config.mutex);
1924 return ret;
1925}
1926
1927struct drm_property *drm_property_create(struct drm_device *dev, int flags,
1928 const char *name, int num_values)
1929{
1930 struct drm_property *property = NULL;
1931
1932 property = kzalloc(sizeof(struct drm_property), GFP_KERNEL);
1933 if (!property)
1934 return NULL;
1935
1936 if (num_values) {
1937 property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL);
1938 if (!property->values)
1939 goto fail;
1940 }
1941
1942 drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY);
1943 property->flags = flags;
1944 property->num_values = num_values;
1945 INIT_LIST_HEAD(&property->enum_blob_list);
1946
1947 if (name)
1948 strncpy(property->name, name, DRM_PROP_NAME_LEN);
1949
1950 list_add_tail(&property->head, &dev->mode_config.property_list);
1951 return property;
1952fail:
1953 kfree(property);
1954 return NULL;
1955}
1956EXPORT_SYMBOL(drm_property_create);
1957
1958int drm_property_add_enum(struct drm_property *property, int index,
1959 uint64_t value, const char *name)
1960{
1961 struct drm_property_enum *prop_enum;
1962
1963 if (!(property->flags & DRM_MODE_PROP_ENUM))
1964 return -EINVAL;
1965
1966 if (!list_empty(&property->enum_blob_list)) {
1967 list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
1968 if (prop_enum->value == value) {
1969 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
1970 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
1971 return 0;
1972 }
1973 }
1974 }
1975
1976 prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL);
1977 if (!prop_enum)
1978 return -ENOMEM;
1979
1980 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
1981 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
1982 prop_enum->value = value;
1983
1984 property->values[index] = value;
1985 list_add_tail(&prop_enum->head, &property->enum_blob_list);
1986 return 0;
1987}
1988EXPORT_SYMBOL(drm_property_add_enum);
1989
1990void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
1991{
1992 struct drm_property_enum *prop_enum, *pt;
1993
1994 list_for_each_entry_safe(prop_enum, pt, &property->enum_blob_list, head) {
1995 list_del(&prop_enum->head);
1996 kfree(prop_enum);
1997 }
1998
1999 if (property->num_values)
2000 kfree(property->values);
2001 drm_mode_object_put(dev, &property->base);
2002 list_del(&property->head);
2003 kfree(property);
2004}
2005EXPORT_SYMBOL(drm_property_destroy);
2006
2007int drm_connector_attach_property(struct drm_connector *connector,
2008 struct drm_property *property, uint64_t init_val)
2009{
2010 int i;
2011
2012 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
2013 if (connector->property_ids[i] == 0) {
2014 connector->property_ids[i] = property->base.id;
2015 connector->property_values[i] = init_val;
2016 break;
2017 }
2018 }
2019
2020 if (i == DRM_CONNECTOR_MAX_PROPERTY)
2021 return -EINVAL;
2022 return 0;
2023}
2024EXPORT_SYMBOL(drm_connector_attach_property);
2025
2026int drm_connector_property_set_value(struct drm_connector *connector,
2027 struct drm_property *property, uint64_t value)
2028{
2029 int i;
2030
2031 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
2032 if (connector->property_ids[i] == property->base.id) {
2033 connector->property_values[i] = value;
2034 break;
2035 }
2036 }
2037
2038 if (i == DRM_CONNECTOR_MAX_PROPERTY)
2039 return -EINVAL;
2040 return 0;
2041}
2042EXPORT_SYMBOL(drm_connector_property_set_value);
2043
2044int drm_connector_property_get_value(struct drm_connector *connector,
2045 struct drm_property *property, uint64_t *val)
2046{
2047 int i;
2048
2049 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
2050 if (connector->property_ids[i] == property->base.id) {
2051 *val = connector->property_values[i];
2052 break;
2053 }
2054 }
2055
2056 if (i == DRM_CONNECTOR_MAX_PROPERTY)
2057 return -EINVAL;
2058 return 0;
2059}
2060EXPORT_SYMBOL(drm_connector_property_get_value);
2061
2062int drm_mode_getproperty_ioctl(struct drm_device *dev,
2063 void *data, struct drm_file *file_priv)
2064{
2065 struct drm_mode_object *obj;
2066 struct drm_mode_get_property *out_resp = data;
2067 struct drm_property *property;
2068 int enum_count = 0;
2069 int blob_count = 0;
2070 int value_count = 0;
2071 int ret = 0, i;
2072 int copied;
2073 struct drm_property_enum *prop_enum;
2074 struct drm_mode_property_enum __user *enum_ptr;
2075 struct drm_property_blob *prop_blob;
2076 uint32_t *blob_id_ptr;
2077 uint64_t __user *values_ptr;
2078 uint32_t __user *blob_length_ptr;
2079
2080 mutex_lock(&dev->mode_config.mutex);
2081 obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
2082 if (!obj) {
2083 ret = -EINVAL;
2084 goto done;
2085 }
2086 property = obj_to_property(obj);
2087
2088 if (property->flags & DRM_MODE_PROP_ENUM) {
2089 list_for_each_entry(prop_enum, &property->enum_blob_list, head)
2090 enum_count++;
2091 } else if (property->flags & DRM_MODE_PROP_BLOB) {
2092 list_for_each_entry(prop_blob, &property->enum_blob_list, head)
2093 blob_count++;
2094 }
2095
2096 value_count = property->num_values;
2097
2098 strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN);
2099 out_resp->name[DRM_PROP_NAME_LEN-1] = 0;
2100 out_resp->flags = property->flags;
2101
2102 if ((out_resp->count_values >= value_count) && value_count) {
2103 values_ptr = (uint64_t *)(unsigned long)out_resp->values_ptr;
2104 for (i = 0; i < value_count; i++) {
2105 if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) {
2106 ret = -EFAULT;
2107 goto done;
2108 }
2109 }
2110 }
2111 out_resp->count_values = value_count;
2112
2113 if (property->flags & DRM_MODE_PROP_ENUM) {
2114 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
2115 copied = 0;
2116 enum_ptr = (struct drm_mode_property_enum *)(unsigned long)out_resp->enum_blob_ptr;
2117 list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
2118
2119 if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {
2120 ret = -EFAULT;
2121 goto done;
2122 }
2123
2124 if (copy_to_user(&enum_ptr[copied].name,
2125 &prop_enum->name, DRM_PROP_NAME_LEN)) {
2126 ret = -EFAULT;
2127 goto done;
2128 }
2129 copied++;
2130 }
2131 }
2132 out_resp->count_enum_blobs = enum_count;
2133 }
2134
2135 if (property->flags & DRM_MODE_PROP_BLOB) {
2136 if ((out_resp->count_enum_blobs >= blob_count) && blob_count) {
2137 copied = 0;
2138 blob_id_ptr = (uint32_t *)(unsigned long)out_resp->enum_blob_ptr;
2139 blob_length_ptr = (uint32_t *)(unsigned long)out_resp->values_ptr;
2140
2141 list_for_each_entry(prop_blob, &property->enum_blob_list, head) {
2142 if (put_user(prop_blob->base.id, blob_id_ptr + copied)) {
2143 ret = -EFAULT;
2144 goto done;
2145 }
2146
2147 if (put_user(prop_blob->length, blob_length_ptr + copied)) {
2148 ret = -EFAULT;
2149 goto done;
2150 }
2151
2152 copied++;
2153 }
2154 }
2155 out_resp->count_enum_blobs = blob_count;
2156 }
2157done:
2158 mutex_unlock(&dev->mode_config.mutex);
2159 return ret;
2160}
2161
2162static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length,
2163 void *data)
2164{
2165 struct drm_property_blob *blob;
2166
2167 if (!length || !data)
2168 return NULL;
2169
2170 blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
2171 if (!blob)
2172 return NULL;
2173
2174 blob->data = (void *)((char *)blob + sizeof(struct drm_property_blob));
2175 blob->length = length;
2176
2177 memcpy(blob->data, data, length);
2178
2179 drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB);
2180
2181 list_add_tail(&blob->head, &dev->mode_config.property_blob_list);
2182 return blob;
2183}
2184
2185static void drm_property_destroy_blob(struct drm_device *dev,
2186 struct drm_property_blob *blob)
2187{
2188 drm_mode_object_put(dev, &blob->base);
2189 list_del(&blob->head);
2190 kfree(blob);
2191}
2192
2193int drm_mode_getblob_ioctl(struct drm_device *dev,
2194 void *data, struct drm_file *file_priv)
2195{
2196 struct drm_mode_object *obj;
2197 struct drm_mode_get_blob *out_resp = data;
2198 struct drm_property_blob *blob;
2199 int ret = 0;
2200 void *blob_ptr;
2201
2202 mutex_lock(&dev->mode_config.mutex);
2203 obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB);
2204 if (!obj) {
2205 ret = -EINVAL;
2206 goto done;
2207 }
2208 blob = obj_to_blob(obj);
2209
2210 if (out_resp->length == blob->length) {
2211 blob_ptr = (void *)(unsigned long)out_resp->data;
2212 if (copy_to_user(blob_ptr, blob->data, blob->length)){
2213 ret = -EFAULT;
2214 goto done;
2215 }
2216 }
2217 out_resp->length = blob->length;
2218
2219done:
2220 mutex_unlock(&dev->mode_config.mutex);
2221 return ret;
2222}
2223
2224int drm_mode_connector_update_edid_property(struct drm_connector *connector,
2225 struct edid *edid)
2226{
2227 struct drm_device *dev = connector->dev;
2228 int ret = 0;
2229
2230 if (connector->edid_blob_ptr)
2231 drm_property_destroy_blob(dev, connector->edid_blob_ptr);
2232
2233 /* Delete edid, when there is none. */
2234 if (!edid) {
2235 connector->edid_blob_ptr = NULL;
2236 ret = drm_connector_property_set_value(connector, dev->mode_config.edid_property, 0);
2237 return ret;
2238 }
2239
2240 connector->edid_blob_ptr = drm_property_create_blob(connector->dev, 128, edid);
2241
2242 ret = drm_connector_property_set_value(connector,
2243 dev->mode_config.edid_property,
2244 connector->edid_blob_ptr->base.id);
2245
2246 return ret;
2247}
2248EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
2249
2250int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
2251 void *data, struct drm_file *file_priv)
2252{
2253 struct drm_mode_connector_set_property *out_resp = data;
2254 struct drm_mode_object *obj;
2255 struct drm_property *property;
2256 struct drm_connector *connector;
2257 int ret = -EINVAL;
2258 int i;
2259
2260 mutex_lock(&dev->mode_config.mutex);
2261
2262 obj = drm_mode_object_find(dev, out_resp->connector_id, DRM_MODE_OBJECT_CONNECTOR);
2263 if (!obj) {
2264 goto out;
2265 }
2266 connector = obj_to_connector(obj);
2267
2268 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
2269 if (connector->property_ids[i] == out_resp->prop_id)
2270 break;
2271 }
2272
2273 if (i == DRM_CONNECTOR_MAX_PROPERTY) {
2274 goto out;
2275 }
2276
2277 obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
2278 if (!obj) {
2279 goto out;
2280 }
2281 property = obj_to_property(obj);
2282
2283 if (property->flags & DRM_MODE_PROP_IMMUTABLE)
2284 goto out;
2285
2286 if (property->flags & DRM_MODE_PROP_RANGE) {
2287 if (out_resp->value < property->values[0])
2288 goto out;
2289
2290 if (out_resp->value > property->values[1])
2291 goto out;
2292 } else {
2293 int found = 0;
2294 for (i = 0; i < property->num_values; i++) {
2295 if (property->values[i] == out_resp->value) {
2296 found = 1;
2297 break;
2298 }
2299 }
2300 if (!found) {
2301 goto out;
2302 }
2303 }
2304
2305 if (connector->funcs->set_property)
2306 ret = connector->funcs->set_property(connector, property, out_resp->value);
2307
2308 /* store the property value if succesful */
2309 if (!ret)
2310 drm_connector_property_set_value(connector, property, out_resp->value);
2311out:
2312 mutex_unlock(&dev->mode_config.mutex);
2313 return ret;
2314}
2315
2316
2317int drm_mode_replacefb(struct drm_device *dev,
2318 void *data, struct drm_file *file_priv)
2319{
2320 struct drm_mode_fb_cmd *r = data;
2321 struct drm_mode_object *obj;
2322 struct drm_framebuffer *fb;
2323 int found = 0;
2324 struct drm_framebuffer *fbl = NULL;
2325 int ret = 0;
2326
2327 /* right replace the current bo attached to this fb with a new bo */
2328 mutex_lock(&dev->mode_config.mutex);
2329 obj = drm_mode_object_find(dev, r->buffer_id, DRM_MODE_OBJECT_FB);
2330 if (!obj) {
2331 ret = -EINVAL;
2332 goto out;
2333 }
2334 fb = obj_to_fb(obj);
2335
2336 list_for_each_entry(fbl, &file_priv->fbs, filp_head)
2337 if (fb == fbl)
2338 found = 1;
2339
2340 if (!found) {
2341 DRM_ERROR("tried to replace an fb we didn't own\n");
2342 ret = -EINVAL;
2343 goto out;
2344 }
2345
2346 if (dev->mode_config.funcs->resize_fb)
2347 ret = dev->mode_config.funcs->resize_fb(dev, file_priv, fb, r);
2348 else
2349 ret = -EINVAL;
2350out:
2351 mutex_unlock(&dev->mode_config.mutex);
2352 return ret;
2353
2354}
2355
2356int drm_mode_connector_attach_encoder(struct drm_connector *connector,
2357 struct drm_encoder *encoder)
2358{
2359 int i;
2360
2361 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
2362 if (connector->encoder_ids[i] == 0) {
2363 connector->encoder_ids[i] = encoder->base.id;
2364 return 0;
2365 }
2366 }
2367 return -ENOMEM;
2368}
2369EXPORT_SYMBOL(drm_mode_connector_attach_encoder);
2370
2371void drm_mode_connector_detach_encoder(struct drm_connector *connector,
2372 struct drm_encoder *encoder)
2373{
2374 int i;
2375 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
2376 if (connector->encoder_ids[i] == encoder->base.id) {
2377 connector->encoder_ids[i] = 0;
2378 if (connector->encoder == encoder)
2379 connector->encoder = NULL;
2380 break;
2381 }
2382 }
2383}
2384EXPORT_SYMBOL(drm_mode_connector_detach_encoder);
2385
2386bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
2387 int gamma_size)
2388{
2389 crtc->gamma_size = gamma_size;
2390
2391 crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL);
2392 if (!crtc->gamma_store) {
2393 crtc->gamma_size = 0;
2394 return false;
2395 }
2396
2397 return true;
2398}
2399EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);
2400
2401int drm_mode_gamma_set_ioctl(struct drm_device *dev,
2402 void *data, struct drm_file *file_priv)
2403{
2404 struct drm_mode_crtc_lut *crtc_lut = data;
2405 struct drm_mode_object *obj;
2406 struct drm_crtc *crtc;
2407 void *r_base, *g_base, *b_base;
2408 int size;
2409 int ret = 0;
2410
2411 mutex_lock(&dev->mode_config.mutex);
2412 obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
2413 if (!obj) {
2414 ret = -EINVAL;
2415 goto out;
2416 }
2417 crtc = obj_to_crtc(obj);
2418
2419 /* memcpy into gamma store */
2420 if (crtc_lut->gamma_size != crtc->gamma_size) {
2421 ret = -EINVAL;
2422 goto out;
2423 }
2424
2425 size = crtc_lut->gamma_size * (sizeof(uint16_t));
2426 r_base = crtc->gamma_store;
2427 if (copy_from_user(r_base, (void __user *)(unsigned long)crtc_lut->red, size)) {
2428 ret = -EFAULT;
2429 goto out;
2430 }
2431
2432 g_base = r_base + size;
2433 if (copy_from_user(g_base, (void __user *)(unsigned long)crtc_lut->green, size)) {
2434 ret = -EFAULT;
2435 goto out;
2436 }
2437
2438 b_base = g_base + size;
2439 if (copy_from_user(b_base, (void __user *)(unsigned long)crtc_lut->blue, size)) {
2440 ret = -EFAULT;
2441 goto out;
2442 }
2443
2444 crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, crtc->gamma_size);
2445
2446out:
2447 mutex_unlock(&dev->mode_config.mutex);
2448 return ret;
2449
2450}
2451
2452int drm_mode_gamma_get_ioctl(struct drm_device *dev,
2453 void *data, struct drm_file *file_priv)
2454{
2455 struct drm_mode_crtc_lut *crtc_lut = data;
2456 struct drm_mode_object *obj;
2457 struct drm_crtc *crtc;
2458 void *r_base, *g_base, *b_base;
2459 int size;
2460 int ret = 0;
2461
2462 mutex_lock(&dev->mode_config.mutex);
2463 obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
2464 if (!obj) {
2465 ret = -EINVAL;
2466 goto out;
2467 }
2468 crtc = obj_to_crtc(obj);
2469
2470 /* memcpy into gamma store */
2471 if (crtc_lut->gamma_size != crtc->gamma_size) {
2472 ret = -EINVAL;
2473 goto out;
2474 }
2475
2476 size = crtc_lut->gamma_size * (sizeof(uint16_t));
2477 r_base = crtc->gamma_store;
2478 if (copy_to_user((void __user *)(unsigned long)crtc_lut->red, r_base, size)) {
2479 ret = -EFAULT;
2480 goto out;
2481 }
2482
2483 g_base = r_base + size;
2484 if (copy_to_user((void __user *)(unsigned long)crtc_lut->green, g_base, size)) {
2485 ret = -EFAULT;
2486 goto out;
2487 }
2488
2489 b_base = g_base + size;
2490 if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) {
2491 ret = -EFAULT;
2492 goto out;
2493 }
2494out:
2495 mutex_unlock(&dev->mode_config.mutex);
2496 return ret;
2497}
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
new file mode 100644
index 000000000000..887ed33b0694
--- /dev/null
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -0,0 +1,822 @@
1/*
2 * Copyright (c) 2006-2008 Intel Corporation
3 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
4 *
5 * DRM core CRTC related functions
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that copyright
10 * notice and this permission notice appear in supporting documentation, and
11 * that the name of the copyright holders not be used in advertising or
12 * publicity pertaining to distribution of the software without specific,
13 * written prior permission. The copyright holders make no representations
14 * about the suitability of this software for any purpose. It is provided "as
15 * is" without express or implied warranty.
16 *
17 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
23 * OF THIS SOFTWARE.
24 *
25 * Authors:
26 * Keith Packard
27 * Eric Anholt <eric@anholt.net>
28 * Dave Airlie <airlied@linux.ie>
29 * Jesse Barnes <jesse.barnes@intel.com>
30 */
31
32#include "drmP.h"
33#include "drm_crtc.h"
34#include "drm_crtc_helper.h"
35
36/*
37 * Detailed mode info for a standard 640x480@60Hz monitor
38 */
39static struct drm_display_mode std_mode[] = {
40 { DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 25200, 640, 656,
41 752, 800, 0, 480, 490, 492, 525, 0,
42 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
43};
44
45/**
46 * drm_helper_probe_connector_modes - get complete set of display modes
47 * @dev: DRM device
48 * @maxX: max width for modes
49 * @maxY: max height for modes
50 *
51 * LOCKING:
52 * Caller must hold mode config lock.
53 *
54 * Based on @dev's mode_config layout, scan all the connectors and try to detect
55 * modes on them. Modes will first be added to the connector's probed_modes
56 * list, then culled (based on validity and the @maxX, @maxY parameters) and
57 * put into the normal modes list.
58 *
59 * Intended to be used either at bootup time or when major configuration
60 * changes have occurred.
61 *
62 * FIXME: take into account monitor limits
63 */
64void drm_helper_probe_single_connector_modes(struct drm_connector *connector,
65 uint32_t maxX, uint32_t maxY)
66{
67 struct drm_device *dev = connector->dev;
68 struct drm_display_mode *mode, *t;
69 struct drm_connector_helper_funcs *connector_funcs =
70 connector->helper_private;
71 int ret;
72
73 DRM_DEBUG("%s\n", drm_get_connector_name(connector));
74 /* set all modes to the unverified state */
75 list_for_each_entry_safe(mode, t, &connector->modes, head)
76 mode->status = MODE_UNVERIFIED;
77
78 connector->status = connector->funcs->detect(connector);
79
80 if (connector->status == connector_status_disconnected) {
81 DRM_DEBUG("%s is disconnected\n",
82 drm_get_connector_name(connector));
83 /* TODO set EDID to NULL */
84 return;
85 }
86
87 ret = (*connector_funcs->get_modes)(connector);
88
89 if (ret) {
90 drm_mode_connector_list_update(connector);
91 }
92
93 if (maxX && maxY)
94 drm_mode_validate_size(dev, &connector->modes, maxX,
95 maxY, 0);
96 list_for_each_entry_safe(mode, t, &connector->modes, head) {
97 if (mode->status == MODE_OK)
98 mode->status = connector_funcs->mode_valid(connector,
99 mode);
100 }
101
102
103 drm_mode_prune_invalid(dev, &connector->modes, true);
104
105 if (list_empty(&connector->modes)) {
106 struct drm_display_mode *stdmode;
107
108 DRM_DEBUG("No valid modes on %s\n",
109 drm_get_connector_name(connector));
110
111 /* Should we do this here ???
112 * When no valid EDID modes are available we end up
113 * here and bailed in the past, now we add a standard
114 * 640x480@60Hz mode and carry on.
115 */
116 stdmode = drm_mode_duplicate(dev, &std_mode[0]);
117 drm_mode_probed_add(connector, stdmode);
118 drm_mode_list_concat(&connector->probed_modes,
119 &connector->modes);
120
121 DRM_DEBUG("Adding standard 640x480 @ 60Hz to %s\n",
122 drm_get_connector_name(connector));
123 }
124
125 drm_mode_sort(&connector->modes);
126
127 DRM_DEBUG("Probed modes for %s\n", drm_get_connector_name(connector));
128 list_for_each_entry_safe(mode, t, &connector->modes, head) {
129 mode->vrefresh = drm_mode_vrefresh(mode);
130
131 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
132 drm_mode_debug_printmodeline(mode);
133 }
134}
135EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
136
137void drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX,
138 uint32_t maxY)
139{
140 struct drm_connector *connector;
141
142 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
143 drm_helper_probe_single_connector_modes(connector, maxX, maxY);
144 }
145}
146EXPORT_SYMBOL(drm_helper_probe_connector_modes);
147
148
149/**
150 * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config
151 * @crtc: CRTC to check
152 *
153 * LOCKING:
154 * Caller must hold mode config lock.
155 *
156 * Walk @crtc's DRM device's mode_config and see if it's in use.
157 *
158 * RETURNS:
159 * True if @crtc is part of the mode_config, false otherwise.
160 */
161bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
162{
163 struct drm_encoder *encoder;
164 struct drm_device *dev = crtc->dev;
165 /* FIXME: Locking around list access? */
166 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
167 if (encoder->crtc == crtc)
168 return true;
169 return false;
170}
171EXPORT_SYMBOL(drm_helper_crtc_in_use);
172
173/**
174 * drm_disable_unused_functions - disable unused objects
175 * @dev: DRM device
176 *
177 * LOCKING:
178 * Caller must hold mode config lock.
179 *
180 * If an connector or CRTC isn't part of @dev's mode_config, it can be disabled
181 * by calling its dpms function, which should power it off.
182 */
183void drm_helper_disable_unused_functions(struct drm_device *dev)
184{
185 struct drm_encoder *encoder;
186 struct drm_encoder_helper_funcs *encoder_funcs;
187 struct drm_crtc *crtc;
188
189 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
190 encoder_funcs = encoder->helper_private;
191 if (!encoder->crtc)
192 (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
193 }
194
195 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
196 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
197 crtc->enabled = drm_helper_crtc_in_use(crtc);
198 if (!crtc->enabled) {
199 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
200 crtc->fb = NULL;
201 }
202 }
203}
204EXPORT_SYMBOL(drm_helper_disable_unused_functions);
205
206static struct drm_display_mode *drm_has_preferred_mode(struct drm_connector *connector, int width, int height)
207{
208 struct drm_display_mode *mode;
209
210 list_for_each_entry(mode, &connector->modes, head) {
211 if (drm_mode_width(mode) > width ||
212 drm_mode_height(mode) > height)
213 continue;
214 if (mode->type & DRM_MODE_TYPE_PREFERRED)
215 return mode;
216 }
217 return NULL;
218}
219
220static bool drm_connector_enabled(struct drm_connector *connector, bool strict)
221{
222 bool enable;
223
224 if (strict) {
225 enable = connector->status == connector_status_connected;
226 } else {
227 enable = connector->status != connector_status_disconnected;
228 }
229 return enable;
230}
231
232static void drm_enable_connectors(struct drm_device *dev, bool *enabled)
233{
234 bool any_enabled = false;
235 struct drm_connector *connector;
236 int i = 0;
237
238 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
239 enabled[i] = drm_connector_enabled(connector, true);
240 any_enabled |= enabled[i];
241 i++;
242 }
243
244 if (any_enabled)
245 return;
246
247 i = 0;
248 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
249 enabled[i] = drm_connector_enabled(connector, false);
250 i++;
251 }
252}
253
254static bool drm_target_preferred(struct drm_device *dev,
255 struct drm_display_mode **modes,
256 bool *enabled, int width, int height)
257{
258 struct drm_connector *connector;
259 int i = 0;
260
261 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
262
263 if (enabled[i] == false) {
264 i++;
265 continue;
266 }
267
268 modes[i] = drm_has_preferred_mode(connector, width, height);
269 if (!modes[i]) {
270 list_for_each_entry(modes[i], &connector->modes, head)
271 break;
272 }
273 i++;
274 }
275 return true;
276}
277
278static int drm_pick_crtcs(struct drm_device *dev,
279 struct drm_crtc **best_crtcs,
280 struct drm_display_mode **modes,
281 int n, int width, int height)
282{
283 int c, o;
284 struct drm_connector *connector;
285 struct drm_connector_helper_funcs *connector_funcs;
286 struct drm_encoder *encoder;
287 struct drm_crtc *best_crtc;
288 int my_score, best_score, score;
289 struct drm_crtc **crtcs, *crtc;
290
291 if (n == dev->mode_config.num_connector)
292 return 0;
293 c = 0;
294 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
295 if (c == n)
296 break;
297 c++;
298 }
299
300 best_crtcs[n] = NULL;
301 best_crtc = NULL;
302 best_score = drm_pick_crtcs(dev, best_crtcs, modes, n+1, width, height);
303 if (modes[n] == NULL)
304 return best_score;
305
306 crtcs = kmalloc(dev->mode_config.num_connector *
307 sizeof(struct drm_crtc *), GFP_KERNEL);
308 if (!crtcs)
309 return best_score;
310
311 my_score = 1;
312 if (connector->status == connector_status_connected)
313 my_score++;
314 if (drm_has_preferred_mode(connector, width, height))
315 my_score++;
316
317 connector_funcs = connector->helper_private;
318 encoder = connector_funcs->best_encoder(connector);
319 if (!encoder)
320 goto out;
321
322 connector->encoder = encoder;
323
324 /* select a crtc for this connector and then attempt to configure
325 remaining connectors */
326 c = 0;
327 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
328
329 if ((connector->encoder->possible_crtcs & (1 << c)) == 0) {
330 c++;
331 continue;
332 }
333
334 for (o = 0; o < n; o++)
335 if (best_crtcs[o] == crtc)
336 break;
337
338 if (o < n) {
339 /* ignore cloning for now */
340 c++;
341 continue;
342 }
343
344 crtcs[n] = crtc;
345 memcpy(crtcs, best_crtcs, n * sizeof(struct drm_crtc *));
346 score = my_score + drm_pick_crtcs(dev, crtcs, modes, n + 1,
347 width, height);
348 if (score > best_score) {
349 best_crtc = crtc;
350 best_score = score;
351 memcpy(best_crtcs, crtcs,
352 dev->mode_config.num_connector *
353 sizeof(struct drm_crtc *));
354 }
355 c++;
356 }
357out:
358 kfree(crtcs);
359 return best_score;
360}
361
362static void drm_setup_crtcs(struct drm_device *dev)
363{
364 struct drm_crtc **crtcs;
365 struct drm_display_mode **modes;
366 struct drm_encoder *encoder;
367 struct drm_connector *connector;
368 bool *enabled;
369 int width, height;
370 int i, ret;
371
372 width = dev->mode_config.max_width;
373 height = dev->mode_config.max_height;
374
375 /* clean out all the encoder/crtc combos */
376 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
377 encoder->crtc = NULL;
378 }
379
380 crtcs = kcalloc(dev->mode_config.num_connector,
381 sizeof(struct drm_crtc *), GFP_KERNEL);
382 modes = kcalloc(dev->mode_config.num_connector,
383 sizeof(struct drm_display_mode *), GFP_KERNEL);
384 enabled = kcalloc(dev->mode_config.num_connector,
385 sizeof(bool), GFP_KERNEL);
386
387 drm_enable_connectors(dev, enabled);
388
389 ret = drm_target_preferred(dev, modes, enabled, width, height);
390 if (!ret)
391 DRM_ERROR("Unable to find initial modes\n");
392
393 drm_pick_crtcs(dev, crtcs, modes, 0, width, height);
394
395 i = 0;
396 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
397 struct drm_display_mode *mode = modes[i];
398 struct drm_crtc *crtc = crtcs[i];
399
400 if (connector->encoder == NULL) {
401 i++;
402 continue;
403 }
404
405 if (mode && crtc) {
406 crtc->desired_mode = mode;
407 connector->encoder->crtc = crtc;
408 } else
409 connector->encoder->crtc = NULL;
410 i++;
411 }
412
413 kfree(crtcs);
414 kfree(modes);
415 kfree(enabled);
416}
417/**
418 * drm_crtc_set_mode - set a mode
419 * @crtc: CRTC to program
420 * @mode: mode to use
421 * @x: width of mode
422 * @y: height of mode
423 *
424 * LOCKING:
425 * Caller must hold mode config lock.
426 *
427 * Try to set @mode on @crtc. Give @crtc and its associated connectors a chance
428 * to fixup or reject the mode prior to trying to set it.
429 *
430 * RETURNS:
431 * True if the mode was set successfully, or false otherwise.
432 */
433bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
434 struct drm_display_mode *mode,
435 int x, int y)
436{
437 struct drm_device *dev = crtc->dev;
438 struct drm_display_mode *adjusted_mode, saved_mode;
439 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
440 struct drm_encoder_helper_funcs *encoder_funcs;
441 int saved_x, saved_y;
442 struct drm_encoder *encoder;
443 bool ret = true;
444
445 adjusted_mode = drm_mode_duplicate(dev, mode);
446
447 crtc->enabled = drm_helper_crtc_in_use(crtc);
448
449 if (!crtc->enabled)
450 return true;
451
452 saved_mode = crtc->mode;
453 saved_x = crtc->x;
454 saved_y = crtc->y;
455
456 /* Update crtc values up front so the driver can rely on them for mode
457 * setting.
458 */
459 crtc->mode = *mode;
460 crtc->x = x;
461 crtc->y = y;
462
463 if (drm_mode_equal(&saved_mode, &crtc->mode)) {
464 if (saved_x != crtc->x || saved_y != crtc->y) {
465 crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y);
466 goto done;
467 }
468 }
469
470 /* Pass our mode to the connectors and the CRTC to give them a chance to
471 * adjust it according to limitations or connector properties, and also
472 * a chance to reject the mode entirely.
473 */
474 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
475
476 if (encoder->crtc != crtc)
477 continue;
478 encoder_funcs = encoder->helper_private;
479 if (!(ret = encoder_funcs->mode_fixup(encoder, mode,
480 adjusted_mode))) {
481 goto done;
482 }
483 }
484
485 if (!(ret = crtc_funcs->mode_fixup(crtc, mode, adjusted_mode))) {
486 goto done;
487 }
488
489 /* Prepare the encoders and CRTCs before setting the mode. */
490 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
491
492 if (encoder->crtc != crtc)
493 continue;
494 encoder_funcs = encoder->helper_private;
495 /* Disable the encoders as the first thing we do. */
496 encoder_funcs->prepare(encoder);
497 }
498
499 crtc_funcs->prepare(crtc);
500
501 /* Set up the DPLL and any encoders state that needs to adjust or depend
502 * on the DPLL.
503 */
504 crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y);
505
506 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
507
508 if (encoder->crtc != crtc)
509 continue;
510
511 DRM_INFO("%s: set mode %s %x\n", drm_get_encoder_name(encoder),
512 mode->name, mode->base.id);
513 encoder_funcs = encoder->helper_private;
514 encoder_funcs->mode_set(encoder, mode, adjusted_mode);
515 }
516
517 /* Now enable the clocks, plane, pipe, and connectors that we set up. */
518 crtc_funcs->commit(crtc);
519
520 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
521
522 if (encoder->crtc != crtc)
523 continue;
524
525 encoder_funcs = encoder->helper_private;
526 encoder_funcs->commit(encoder);
527
528 }
529
530 /* XXX free adjustedmode */
531 drm_mode_destroy(dev, adjusted_mode);
532 /* FIXME: add subpixel order */
533done:
534 if (!ret) {
535 crtc->mode = saved_mode;
536 crtc->x = saved_x;
537 crtc->y = saved_y;
538 }
539
540 return ret;
541}
542EXPORT_SYMBOL(drm_crtc_helper_set_mode);
543
544
545/**
546 * drm_crtc_helper_set_config - set a new config from userspace
547 * @crtc: CRTC to setup
548 * @crtc_info: user provided configuration
549 * @new_mode: new mode to set
550 * @connector_set: set of connectors for the new config
551 * @fb: new framebuffer
552 *
553 * LOCKING:
554 * Caller must hold mode config lock.
555 *
556 * Setup a new configuration, provided by the user in @crtc_info, and enable
557 * it.
558 *
559 * RETURNS:
560 * Zero. (FIXME)
561 */
562int drm_crtc_helper_set_config(struct drm_mode_set *set)
563{
564 struct drm_device *dev;
565 struct drm_crtc **save_crtcs, *new_crtc;
566 struct drm_encoder **save_encoders, *new_encoder;
567 bool save_enabled;
568 bool changed = false;
569 bool flip_or_move = false;
570 struct drm_connector *connector;
571 int count = 0, ro, fail = 0;
572 struct drm_crtc_helper_funcs *crtc_funcs;
573 int ret = 0;
574
575 DRM_DEBUG("\n");
576
577 if (!set)
578 return -EINVAL;
579
580 if (!set->crtc)
581 return -EINVAL;
582
583 if (!set->crtc->helper_private)
584 return -EINVAL;
585
586 crtc_funcs = set->crtc->helper_private;
587
588 DRM_DEBUG("crtc: %p %d fb: %p connectors: %p num_connectors: %d (x, y) (%i, %i)\n",
589 set->crtc, set->crtc->base.id, set->fb, set->connectors,
590 (int)set->num_connectors, set->x, set->y);
591
592 dev = set->crtc->dev;
593
594 /* save previous config */
595 save_enabled = set->crtc->enabled;
596
597 /* this is meant to be num_connector not num_crtc */
598 save_crtcs = kzalloc(dev->mode_config.num_connector *
599 sizeof(struct drm_crtc *), GFP_KERNEL);
600 if (!save_crtcs)
601 return -ENOMEM;
602
603 save_encoders = kzalloc(dev->mode_config.num_connector *
604 sizeof(struct drm_encoders *), GFP_KERNEL);
605 if (!save_encoders) {
606 kfree(save_crtcs);
607 return -ENOMEM;
608 }
609
610 /* We should be able to check here if the fb has the same properties
611 * and then just flip_or_move it */
612 if (set->crtc->fb != set->fb) {
613 /* if we have no fb then its a change not a flip */
614 if (set->crtc->fb == NULL)
615 changed = true;
616 else
617 flip_or_move = true;
618 }
619
620 if (set->x != set->crtc->x || set->y != set->crtc->y)
621 flip_or_move = true;
622
623 if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) {
624 DRM_DEBUG("modes are different\n");
625 drm_mode_debug_printmodeline(&set->crtc->mode);
626 drm_mode_debug_printmodeline(set->mode);
627 changed = true;
628 }
629
630 /* a) traverse passed in connector list and get encoders for them */
631 count = 0;
632 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
633 struct drm_connector_helper_funcs *connector_funcs =
634 connector->helper_private;
635 save_encoders[count++] = connector->encoder;
636 new_encoder = connector->encoder;
637 for (ro = 0; ro < set->num_connectors; ro++) {
638 if (set->connectors[ro] == connector) {
639 new_encoder = connector_funcs->best_encoder(connector);
640 /* if we can't get an encoder for a connector
641 we are setting now - then fail */
642 if (new_encoder == NULL)
643 /* don't break so fail path works correct */
644 fail = 1;
645 break;
646 }
647 }
648
649 if (new_encoder != connector->encoder) {
650 changed = true;
651 connector->encoder = new_encoder;
652 }
653 }
654
655 if (fail) {
656 ret = -EINVAL;
657 goto fail_no_encoder;
658 }
659
660 count = 0;
661 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
662 if (!connector->encoder)
663 continue;
664
665 save_crtcs[count++] = connector->encoder->crtc;
666
667 if (connector->encoder->crtc == set->crtc)
668 new_crtc = NULL;
669 else
670 new_crtc = connector->encoder->crtc;
671
672 for (ro = 0; ro < set->num_connectors; ro++) {
673 if (set->connectors[ro] == connector)
674 new_crtc = set->crtc;
675 }
676 if (new_crtc != connector->encoder->crtc) {
677 changed = true;
678 connector->encoder->crtc = new_crtc;
679 }
680 }
681
682 /* mode_set_base is not a required function */
683 if (flip_or_move && !crtc_funcs->mode_set_base)
684 changed = true;
685
686 if (changed) {
687 set->crtc->fb = set->fb;
688 set->crtc->enabled = (set->mode != NULL);
689 if (set->mode != NULL) {
690 DRM_DEBUG("attempting to set mode from userspace\n");
691 drm_mode_debug_printmodeline(set->mode);
692 if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
693 set->x, set->y)) {
694 ret = -EINVAL;
695 goto fail_set_mode;
696 }
697 /* TODO are these needed? */
698 set->crtc->desired_x = set->x;
699 set->crtc->desired_y = set->y;
700 set->crtc->desired_mode = set->mode;
701 }
702 drm_helper_disable_unused_functions(dev);
703 } else if (flip_or_move) {
704 if (set->crtc->fb != set->fb)
705 set->crtc->fb = set->fb;
706 crtc_funcs->mode_set_base(set->crtc, set->x, set->y);
707 }
708
709 kfree(save_encoders);
710 kfree(save_crtcs);
711 return 0;
712
713fail_set_mode:
714 set->crtc->enabled = save_enabled;
715 count = 0;
716 list_for_each_entry(connector, &dev->mode_config.connector_list, head)
717 connector->encoder->crtc = save_crtcs[count++];
718fail_no_encoder:
719 kfree(save_crtcs);
720 count = 0;
721 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
722 connector->encoder = save_encoders[count++];
723 }
724 kfree(save_encoders);
725 return ret;
726}
727EXPORT_SYMBOL(drm_crtc_helper_set_config);
728
729bool drm_helper_plugged_event(struct drm_device *dev)
730{
731 DRM_DEBUG("\n");
732
733 drm_helper_probe_connector_modes(dev, dev->mode_config.max_width,
734 dev->mode_config.max_height);
735
736 drm_setup_crtcs(dev);
737
738 /* alert the driver fb layer */
739 dev->mode_config.funcs->fb_changed(dev);
740
741 /* FIXME: send hotplug event */
742 return true;
743}
744/**
745 * drm_initial_config - setup a sane initial connector configuration
746 * @dev: DRM device
747 * @can_grow: this configuration is growable
748 *
749 * LOCKING:
750 * Called at init time, must take mode config lock.
751 *
752 * Scan the CRTCs and connectors and try to put together an initial setup.
753 * At the moment, this is a cloned configuration across all heads with
754 * a new framebuffer object as the backing store.
755 *
756 * RETURNS:
757 * Zero if everything went ok, nonzero otherwise.
758 */
759bool drm_helper_initial_config(struct drm_device *dev, bool can_grow)
760{
761 int ret = false;
762
763 drm_helper_plugged_event(dev);
764 return ret;
765}
766EXPORT_SYMBOL(drm_helper_initial_config);
767
768/**
769 * drm_hotplug_stage_two
770 * @dev DRM device
771 * @connector hotpluged connector
772 *
773 * LOCKING.
774 * Caller must hold mode config lock, function might grab struct lock.
775 *
776 * Stage two of a hotplug.
777 *
778 * RETURNS:
779 * Zero on success, errno on failure.
780 */
781int drm_helper_hotplug_stage_two(struct drm_device *dev)
782{
783 dev->mode_config.hotplug_counter++;
784
785 drm_helper_plugged_event(dev);
786
787 return 0;
788}
789EXPORT_SYMBOL(drm_helper_hotplug_stage_two);
790
791int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
792 struct drm_mode_fb_cmd *mode_cmd)
793{
794 fb->width = mode_cmd->width;
795 fb->height = mode_cmd->height;
796 fb->pitch = mode_cmd->pitch;
797 fb->bits_per_pixel = mode_cmd->bpp;
798 fb->depth = mode_cmd->depth;
799
800 return 0;
801}
802EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct);
803
804int drm_helper_resume_force_mode(struct drm_device *dev)
805{
806 struct drm_crtc *crtc;
807 int ret;
808
809 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
810
811 if (!crtc->enabled)
812 continue;
813
814 ret = drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x,
815 crtc->y);
816
817 if (ret == false)
818 DRM_ERROR("failed to set mode on crtc %p\n", crtc);
819 }
820 return 0;
821}
822EXPORT_SYMBOL(drm_helper_resume_force_mode);
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 98a781375f60..0b9f3164a3b2 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -126,6 +126,26 @@ static struct drm_ioctl_desc drm_ioctls[] = {
126 DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, 0), 126 DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, 0),
127 DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH), 127 DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH),
128 DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH), 128 DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH),
129
130 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW),
131 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW),
132 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_MASTER|DRM_CONTROL_ALLOW),
133 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW),
134 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
135 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW),
136 DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW),
137 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW),
138
139 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
140 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
141 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
142 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
143 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW),
144
145 DRM_IOCTL_DEF(DRM_IOCTL_MODE_REPLACEFB, drm_mode_replacefb, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),
146 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_MASTER|DRM_CONTROL_ALLOW),
147 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER),
148 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER),
129}; 149};
130 150
131#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) 151#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
@@ -150,7 +170,7 @@ int drm_lastclose(struct drm_device * dev)
150 dev->driver->lastclose(dev); 170 dev->driver->lastclose(dev);
151 DRM_DEBUG("driver lastclose completed\n"); 171 DRM_DEBUG("driver lastclose completed\n");
152 172
153 if (dev->irq_enabled) 173 if (dev->irq_enabled && !drm_core_check_feature(dev, DRIVER_MODESET))
154 drm_irq_uninstall(dev); 174 drm_irq_uninstall(dev);
155 175
156 mutex_lock(&dev->struct_mutex); 176 mutex_lock(&dev->struct_mutex);
@@ -160,7 +180,8 @@ int drm_lastclose(struct drm_device * dev)
160 del_timer(&dev->timer); 180 del_timer(&dev->timer);
161 181
162 /* Clear AGP information */ 182 /* Clear AGP information */
163 if (drm_core_has_AGP(dev) && dev->agp) { 183 if (drm_core_has_AGP(dev) && dev->agp &&
184 !drm_core_check_feature(dev, DRIVER_MODESET)) {
164 struct drm_agp_mem *entry, *tempe; 185 struct drm_agp_mem *entry, *tempe;
165 186
166 /* Remove AGP resources, but leave dev->agp 187 /* Remove AGP resources, but leave dev->agp
@@ -179,7 +200,8 @@ int drm_lastclose(struct drm_device * dev)
179 dev->agp->acquired = 0; 200 dev->agp->acquired = 0;
180 dev->agp->enabled = 0; 201 dev->agp->enabled = 0;
181 } 202 }
182 if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) { 203 if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg &&
204 !drm_core_check_feature(dev, DRIVER_MODESET)) {
183 drm_sg_cleanup(dev->sg); 205 drm_sg_cleanup(dev->sg);
184 dev->sg = NULL; 206 dev->sg = NULL;
185 } 207 }
@@ -206,7 +228,8 @@ int drm_lastclose(struct drm_device * dev)
206 } 228 }
207 dev->queue_count = 0; 229 dev->queue_count = 0;
208 230
209 if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) 231 if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) &&
232 !drm_core_check_feature(dev, DRIVER_MODESET))
210 drm_dma_takedown(dev); 233 drm_dma_takedown(dev);
211 234
212 dev->dev_mapping = NULL; 235 dev->dev_mapping = NULL;
@@ -307,6 +330,9 @@ static void drm_cleanup(struct drm_device * dev)
307 drm_ht_remove(&dev->map_hash); 330 drm_ht_remove(&dev->map_hash);
308 drm_ctxbitmap_cleanup(dev); 331 drm_ctxbitmap_cleanup(dev);
309 332
333 if (drm_core_check_feature(dev, DRIVER_MODESET))
334 drm_put_minor(&dev->control);
335
310 if (driver->driver_features & DRIVER_GEM) 336 if (driver->driver_features & DRIVER_GEM)
311 drm_gem_destroy(dev); 337 drm_gem_destroy(dev);
312 338
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
new file mode 100644
index 000000000000..681753e57dc7
--- /dev/null
+++ b/drivers/gpu/drm/drm_edid.c
@@ -0,0 +1,732 @@
1/*
2 * Copyright (c) 2006 Luc Verhaegen (quirks list)
3 * Copyright (c) 2007-2008 Intel Corporation
4 * Jesse Barnes <jesse.barnes@intel.com>
5 *
6 * DDC probing routines (drm_ddc_read & drm_do_probe_ddc_edid) originally from
7 * FB layer.
8 * Copyright (C) 2006 Dennis Munsie <dmunsie@cecropia.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sub license,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice (including the
18 * next paragraph) shall be included in all copies or substantial portions
19 * of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
24 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 * DEALINGS IN THE SOFTWARE.
28 */
29#include <linux/kernel.h>
30#include <linux/i2c.h>
31#include <linux/i2c-algo-bit.h>
32#include "drmP.h"
33#include "drm_edid.h"
34
35/*
36 * TODO:
37 * - support EDID 1.4 (incl. CE blocks)
38 */
39
40/*
41 * EDID blocks out in the wild have a variety of bugs, try to collect
42 * them here (note that userspace may work around broken monitors first,
43 * but fixes should make their way here so that the kernel "just works"
44 * on as many displays as possible).
45 */
46
47/* First detailed mode wrong, use largest 60Hz mode */
48#define EDID_QUIRK_PREFER_LARGE_60 (1 << 0)
49/* Reported 135MHz pixel clock is too high, needs adjustment */
50#define EDID_QUIRK_135_CLOCK_TOO_HIGH (1 << 1)
51/* Prefer the largest mode at 75 Hz */
52#define EDID_QUIRK_PREFER_LARGE_75 (1 << 2)
53/* Detail timing is in cm not mm */
54#define EDID_QUIRK_DETAILED_IN_CM (1 << 3)
55/* Detailed timing descriptors have bogus size values, so just take the
56 * maximum size and use that.
57 */
58#define EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE (1 << 4)
59/* Monitor forgot to set the first detailed is preferred bit. */
60#define EDID_QUIRK_FIRST_DETAILED_PREFERRED (1 << 5)
61/* use +hsync +vsync for detailed mode */
62#define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6)
63
64static struct edid_quirk {
65 char *vendor;
66 int product_id;
67 u32 quirks;
68} edid_quirk_list[] = {
69 /* Acer AL1706 */
70 { "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 },
71 /* Acer F51 */
72 { "API", 0x7602, EDID_QUIRK_PREFER_LARGE_60 },
73 /* Unknown Acer */
74 { "ACR", 2423, EDID_QUIRK_FIRST_DETAILED_PREFERRED },
75
76 /* Belinea 10 15 55 */
77 { "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
78 { "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
79
80 /* Envision Peripherals, Inc. EN-7100e */
81 { "EPI", 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH },
82
83 /* Funai Electronics PM36B */
84 { "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 |
85 EDID_QUIRK_DETAILED_IN_CM },
86
87 /* LG Philips LCD LP154W01-A5 */
88 { "LPL", 0, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE },
89 { "LPL", 0x2a00, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE },
90
91 /* Philips 107p5 CRT */
92 { "PHL", 57364, EDID_QUIRK_FIRST_DETAILED_PREFERRED },
93
94 /* Proview AY765C */
95 { "PTS", 765, EDID_QUIRK_FIRST_DETAILED_PREFERRED },
96
97 /* Samsung SyncMaster 205BW. Note: irony */
98 { "SAM", 541, EDID_QUIRK_DETAILED_SYNC_PP },
99 /* Samsung SyncMaster 22[5-6]BW */
100 { "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 },
101 { "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 },
102};
103
104
105/* Valid EDID header has these bytes */
106static u8 edid_header[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
107
108/**
109 * edid_is_valid - sanity check EDID data
110 * @edid: EDID data
111 *
112 * Sanity check the EDID block by looking at the header, the version number
113 * and the checksum. Return 0 if the EDID doesn't check out, or 1 if it's
114 * valid.
115 */
116static bool edid_is_valid(struct edid *edid)
117{
118 int i;
119 u8 csum = 0;
120 u8 *raw_edid = (u8 *)edid;
121
122 if (memcmp(edid->header, edid_header, sizeof(edid_header)))
123 goto bad;
124 if (edid->version != 1) {
125 DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version);
126 goto bad;
127 }
128 if (edid->revision <= 0 || edid->revision > 3) {
129 DRM_ERROR("EDID has minor version %d, which is not between 0-3\n", edid->revision);
130 goto bad;
131 }
132
133 for (i = 0; i < EDID_LENGTH; i++)
134 csum += raw_edid[i];
135 if (csum) {
136 DRM_ERROR("EDID checksum is invalid, remainder is %d\n", csum);
137 goto bad;
138 }
139
140 return 1;
141
142bad:
143 if (raw_edid) {
144 DRM_ERROR("Raw EDID:\n");
145 print_hex_dump_bytes(KERN_ERR, DUMP_PREFIX_NONE, raw_edid, EDID_LENGTH);
146 printk("\n");
147 }
148 return 0;
149}
150
151/**
152 * edid_vendor - match a string against EDID's obfuscated vendor field
153 * @edid: EDID to match
154 * @vendor: vendor string
155 *
156 * Returns true if @vendor is in @edid, false otherwise
157 */
158static bool edid_vendor(struct edid *edid, char *vendor)
159{
160 char edid_vendor[3];
161
162 edid_vendor[0] = ((edid->mfg_id[0] & 0x7c) >> 2) + '@';
163 edid_vendor[1] = (((edid->mfg_id[0] & 0x3) << 3) |
164 ((edid->mfg_id[1] & 0xe0) >> 5)) + '@';
165 edid_vendor[2] = (edid->mfg_id[2] & 0x1f) + '@';
166
167 return !strncmp(edid_vendor, vendor, 3);
168}
169
170/**
171 * edid_get_quirks - return quirk flags for a given EDID
172 * @edid: EDID to process
173 *
174 * This tells subsequent routines what fixes they need to apply.
175 */
176static u32 edid_get_quirks(struct edid *edid)
177{
178 struct edid_quirk *quirk;
179 int i;
180
181 for (i = 0; i < ARRAY_SIZE(edid_quirk_list); i++) {
182 quirk = &edid_quirk_list[i];
183
184 if (edid_vendor(edid, quirk->vendor) &&
185 (EDID_PRODUCT_ID(edid) == quirk->product_id))
186 return quirk->quirks;
187 }
188
189 return 0;
190}
191
192#define MODE_SIZE(m) ((m)->hdisplay * (m)->vdisplay)
193#define MODE_REFRESH_DIFF(m,r) (abs((m)->vrefresh - target_refresh))
194
195
196/**
197 * edid_fixup_preferred - set preferred modes based on quirk list
198 * @connector: has mode list to fix up
199 * @quirks: quirks list
200 *
201 * Walk the mode list for @connector, clearing the preferred status
202 * on existing modes and setting it anew for the right mode ala @quirks.
203 */
204static void edid_fixup_preferred(struct drm_connector *connector,
205 u32 quirks)
206{
207 struct drm_display_mode *t, *cur_mode, *preferred_mode;
208 int target_refresh;
209
210 if (list_empty(&connector->probed_modes))
211 return;
212
213 if (quirks & EDID_QUIRK_PREFER_LARGE_60)
214 target_refresh = 60;
215 if (quirks & EDID_QUIRK_PREFER_LARGE_75)
216 target_refresh = 75;
217
218 preferred_mode = list_first_entry(&connector->probed_modes,
219 struct drm_display_mode, head);
220
221 list_for_each_entry_safe(cur_mode, t, &connector->probed_modes, head) {
222 cur_mode->type &= ~DRM_MODE_TYPE_PREFERRED;
223
224 if (cur_mode == preferred_mode)
225 continue;
226
227 /* Largest mode is preferred */
228 if (MODE_SIZE(cur_mode) > MODE_SIZE(preferred_mode))
229 preferred_mode = cur_mode;
230
231 /* At a given size, try to get closest to target refresh */
232 if ((MODE_SIZE(cur_mode) == MODE_SIZE(preferred_mode)) &&
233 MODE_REFRESH_DIFF(cur_mode, target_refresh) <
234 MODE_REFRESH_DIFF(preferred_mode, target_refresh)) {
235 preferred_mode = cur_mode;
236 }
237 }
238
239 preferred_mode->type |= DRM_MODE_TYPE_PREFERRED;
240}
241
242/**
243 * drm_mode_std - convert standard mode info (width, height, refresh) into mode
244 * @t: standard timing params
245 *
246 * Take the standard timing params (in this case width, aspect, and refresh)
247 * and convert them into a real mode using CVT.
248 *
249 * Punts for now, but should eventually use the FB layer's CVT based mode
250 * generation code.
251 */
252struct drm_display_mode *drm_mode_std(struct drm_device *dev,
253 struct std_timing *t)
254{
255 struct drm_display_mode *mode;
256 int hsize = t->hsize * 8 + 248, vsize;
257
258 mode = drm_mode_create(dev);
259 if (!mode)
260 return NULL;
261
262 if (t->aspect_ratio == 0)
263 vsize = (hsize * 10) / 16;
264 else if (t->aspect_ratio == 1)
265 vsize = (hsize * 3) / 4;
266 else if (t->aspect_ratio == 2)
267 vsize = (hsize * 4) / 5;
268 else
269 vsize = (hsize * 9) / 16;
270
271 drm_mode_set_name(mode);
272
273 return mode;
274}
275
276/**
277 * drm_mode_detailed - create a new mode from an EDID detailed timing section
278 * @dev: DRM device (needed to create new mode)
279 * @edid: EDID block
280 * @timing: EDID detailed timing info
281 * @quirks: quirks to apply
282 *
283 * An EDID detailed timing block contains enough info for us to create and
284 * return a new struct drm_display_mode.
285 */
286static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
287 struct edid *edid,
288 struct detailed_timing *timing,
289 u32 quirks)
290{
291 struct drm_display_mode *mode;
292 struct detailed_pixel_timing *pt = &timing->data.pixel_data;
293
294 if (pt->stereo) {
295 printk(KERN_WARNING "stereo mode not supported\n");
296 return NULL;
297 }
298 if (!pt->separate_sync) {
299 printk(KERN_WARNING "integrated sync not supported\n");
300 return NULL;
301 }
302
303 mode = drm_mode_create(dev);
304 if (!mode)
305 return NULL;
306
307 mode->type = DRM_MODE_TYPE_DRIVER;
308
309 if (quirks & EDID_QUIRK_135_CLOCK_TOO_HIGH)
310 timing->pixel_clock = 1088;
311
312 mode->clock = timing->pixel_clock * 10;
313
314 mode->hdisplay = (pt->hactive_hi << 8) | pt->hactive_lo;
315 mode->hsync_start = mode->hdisplay + ((pt->hsync_offset_hi << 8) |
316 pt->hsync_offset_lo);
317 mode->hsync_end = mode->hsync_start +
318 ((pt->hsync_pulse_width_hi << 8) |
319 pt->hsync_pulse_width_lo);
320 mode->htotal = mode->hdisplay + ((pt->hblank_hi << 8) | pt->hblank_lo);
321
322 mode->vdisplay = (pt->vactive_hi << 8) | pt->vactive_lo;
323 mode->vsync_start = mode->vdisplay + ((pt->vsync_offset_hi << 8) |
324 pt->vsync_offset_lo);
325 mode->vsync_end = mode->vsync_start +
326 ((pt->vsync_pulse_width_hi << 8) |
327 pt->vsync_pulse_width_lo);
328 mode->vtotal = mode->vdisplay + ((pt->vblank_hi << 8) | pt->vblank_lo);
329
330 drm_mode_set_name(mode);
331
332 if (pt->interlaced)
333 mode->flags |= DRM_MODE_FLAG_INTERLACE;
334
335 if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) {
336 pt->hsync_positive = 1;
337 pt->vsync_positive = 1;
338 }
339
340 mode->flags |= pt->hsync_positive ? DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC;
341 mode->flags |= pt->vsync_positive ? DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
342
343 mode->width_mm = pt->width_mm_lo | (pt->width_mm_hi << 8);
344 mode->height_mm = pt->height_mm_lo | (pt->height_mm_hi << 8);
345
346 if (quirks & EDID_QUIRK_DETAILED_IN_CM) {
347 mode->width_mm *= 10;
348 mode->height_mm *= 10;
349 }
350
351 if (quirks & EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE) {
352 mode->width_mm = edid->width_cm * 10;
353 mode->height_mm = edid->height_cm * 10;
354 }
355
356 return mode;
357}
358
359/*
360 * Detailed mode info for the EDID "established modes" data to use.
361 */
362static struct drm_display_mode edid_est_modes[] = {
363 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
364 968, 1056, 0, 600, 601, 605, 628, 0,
365 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@60Hz */
366 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
367 896, 1024, 0, 600, 601, 603, 625, 0,
368 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@56Hz */
369 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
370 720, 840, 0, 480, 481, 484, 500, 0,
371 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@75Hz */
372 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
373 704, 832, 0, 480, 489, 491, 520, 0,
374 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@72Hz */
375 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 30240, 640, 704,
376 768, 864, 0, 480, 483, 486, 525, 0,
377 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@67Hz */
378 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25200, 640, 656,
379 752, 800, 0, 480, 490, 492, 525, 0,
380 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@60Hz */
381 { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 738,
382 846, 900, 0, 400, 421, 423, 449, 0,
383 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 720x400@88Hz */
384 { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 28320, 720, 738,
385 846, 900, 0, 400, 412, 414, 449, 0,
386 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 720x400@70Hz */
387 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
388 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
389 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1280x1024@75Hz */
390 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78800, 1024, 1040,
391 1136, 1312, 0, 768, 769, 772, 800, 0,
392 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1024x768@75Hz */
393 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
394 1184, 1328, 0, 768, 771, 777, 806, 0,
395 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@70Hz */
396 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
397 1184, 1344, 0, 768, 771, 777, 806, 0,
398 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@60Hz */
399 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER,44900, 1024, 1032,
400 1208, 1264, 0, 768, 768, 776, 817, 0,
401 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_INTERLACE) }, /* 1024x768@43Hz */
402 { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 57284, 832, 864,
403 928, 1152, 0, 624, 625, 628, 667, 0,
404 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 832x624@75Hz */
405 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
406 896, 1056, 0, 600, 601, 604, 625, 0,
407 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@75Hz */
408 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
409 976, 1040, 0, 600, 637, 643, 666, 0,
410 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@72Hz */
411 { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
412 1344, 1600, 0, 864, 865, 868, 900, 0,
413 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1152x864@75Hz */
414};
415
416#define EDID_EST_TIMINGS 16
417#define EDID_STD_TIMINGS 8
418#define EDID_DETAILED_TIMINGS 4
419
420/**
421 * add_established_modes - get est. modes from EDID and add them
422 * @edid: EDID block to scan
423 *
424 * Each EDID block contains a bitmap of the supported "established modes" list
425 * (defined above). Tease them out and add them to the global modes list.
426 */
427static int add_established_modes(struct drm_connector *connector, struct edid *edid)
428{
429 struct drm_device *dev = connector->dev;
430 unsigned long est_bits = edid->established_timings.t1 |
431 (edid->established_timings.t2 << 8) |
432 ((edid->established_timings.mfg_rsvd & 0x80) << 9);
433 int i, modes = 0;
434
435 for (i = 0; i <= EDID_EST_TIMINGS; i++)
436 if (est_bits & (1<<i)) {
437 struct drm_display_mode *newmode;
438 newmode = drm_mode_duplicate(dev, &edid_est_modes[i]);
439 if (newmode) {
440 drm_mode_probed_add(connector, newmode);
441 modes++;
442 }
443 }
444
445 return modes;
446}
447
448/**
449 * add_standard_modes - get std. modes from EDID and add them
450 * @edid: EDID block to scan
451 *
452 * Standard modes can be calculated using the CVT standard. Grab them from
453 * @edid, calculate them, and add them to the list.
454 */
455static int add_standard_modes(struct drm_connector *connector, struct edid *edid)
456{
457 struct drm_device *dev = connector->dev;
458 int i, modes = 0;
459
460 for (i = 0; i < EDID_STD_TIMINGS; i++) {
461 struct std_timing *t = &edid->standard_timings[i];
462 struct drm_display_mode *newmode;
463
464 /* If std timings bytes are 1, 1 it's empty */
465 if (t->hsize == 1 && (t->aspect_ratio | t->vfreq) == 1)
466 continue;
467
468 newmode = drm_mode_std(dev, &edid->standard_timings[i]);
469 if (newmode) {
470 drm_mode_probed_add(connector, newmode);
471 modes++;
472 }
473 }
474
475 return modes;
476}
477
478/**
479 * add_detailed_modes - get detailed mode info from EDID data
480 * @connector: attached connector
481 * @edid: EDID block to scan
482 * @quirks: quirks to apply
483 *
484 * Some of the detailed timing sections may contain mode information. Grab
485 * it and add it to the list.
486 */
487static int add_detailed_info(struct drm_connector *connector,
488 struct edid *edid, u32 quirks)
489{
490 struct drm_device *dev = connector->dev;
491 int i, j, modes = 0;
492
493 for (i = 0; i < EDID_DETAILED_TIMINGS; i++) {
494 struct detailed_timing *timing = &edid->detailed_timings[i];
495 struct detailed_non_pixel *data = &timing->data.other_data;
496 struct drm_display_mode *newmode;
497
498 /* EDID up to and including 1.2 may put monitor info here */
499 if (edid->version == 1 && edid->revision < 3)
500 continue;
501
502 /* Detailed mode timing */
503 if (timing->pixel_clock) {
504 newmode = drm_mode_detailed(dev, edid, timing, quirks);
505 if (!newmode)
506 continue;
507
508 /* First detailed mode is preferred */
509 if (i == 0 && edid->preferred_timing)
510 newmode->type |= DRM_MODE_TYPE_PREFERRED;
511 drm_mode_probed_add(connector, newmode);
512
513 modes++;
514 continue;
515 }
516
517 /* Other timing or info */
518 switch (data->type) {
519 case EDID_DETAIL_MONITOR_SERIAL:
520 break;
521 case EDID_DETAIL_MONITOR_STRING:
522 break;
523 case EDID_DETAIL_MONITOR_RANGE:
524 /* Get monitor range data */
525 break;
526 case EDID_DETAIL_MONITOR_NAME:
527 break;
528 case EDID_DETAIL_MONITOR_CPDATA:
529 break;
530 case EDID_DETAIL_STD_MODES:
531 /* Five modes per detailed section */
532 for (j = 0; j < 5; i++) {
533 struct std_timing *std;
534 struct drm_display_mode *newmode;
535
536 std = &data->data.timings[j];
537 newmode = drm_mode_std(dev, std);
538 if (newmode) {
539 drm_mode_probed_add(connector, newmode);
540 modes++;
541 }
542 }
543 break;
544 default:
545 break;
546 }
547 }
548
549 return modes;
550}
551
552#define DDC_ADDR 0x50
553
554unsigned char *drm_do_probe_ddc_edid(struct i2c_adapter *adapter)
555{
556 unsigned char start = 0x0;
557 unsigned char *buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
558 struct i2c_msg msgs[] = {
559 {
560 .addr = DDC_ADDR,
561 .flags = 0,
562 .len = 1,
563 .buf = &start,
564 }, {
565 .addr = DDC_ADDR,
566 .flags = I2C_M_RD,
567 .len = EDID_LENGTH,
568 .buf = buf,
569 }
570 };
571
572 if (!buf) {
573 dev_warn(&adapter->dev, "unable to allocate memory for EDID "
574 "block.\n");
575 return NULL;
576 }
577
578 if (i2c_transfer(adapter, msgs, 2) == 2)
579 return buf;
580
581 dev_info(&adapter->dev, "unable to read EDID block.\n");
582 kfree(buf);
583 return NULL;
584}
585EXPORT_SYMBOL(drm_do_probe_ddc_edid);
586
587static unsigned char *drm_ddc_read(struct i2c_adapter *adapter)
588{
589 struct i2c_algo_bit_data *algo_data = adapter->algo_data;
590 unsigned char *edid = NULL;
591 int i, j;
592
593 algo_data->setscl(algo_data->data, 1);
594
595 for (i = 0; i < 1; i++) {
596 /* For some old monitors we need the
597 * following process to initialize/stop DDC
598 */
599 algo_data->setsda(algo_data->data, 1);
600 msleep(13);
601
602 algo_data->setscl(algo_data->data, 1);
603 for (j = 0; j < 5; j++) {
604 msleep(10);
605 if (algo_data->getscl(algo_data->data))
606 break;
607 }
608 if (j == 5)
609 continue;
610
611 algo_data->setsda(algo_data->data, 0);
612 msleep(15);
613 algo_data->setscl(algo_data->data, 0);
614 msleep(15);
615 algo_data->setsda(algo_data->data, 1);
616 msleep(15);
617
618 /* Do the real work */
619 edid = drm_do_probe_ddc_edid(adapter);
620 algo_data->setsda(algo_data->data, 0);
621 algo_data->setscl(algo_data->data, 0);
622 msleep(15);
623
624 algo_data->setscl(algo_data->data, 1);
625 for (j = 0; j < 10; j++) {
626 msleep(10);
627 if (algo_data->getscl(algo_data->data))
628 break;
629 }
630
631 algo_data->setsda(algo_data->data, 1);
632 msleep(15);
633 algo_data->setscl(algo_data->data, 0);
634 algo_data->setsda(algo_data->data, 0);
635 if (edid)
636 break;
637 }
638 /* Release the DDC lines when done or the Apple Cinema HD display
639 * will switch off
640 */
641 algo_data->setsda(algo_data->data, 1);
642 algo_data->setscl(algo_data->data, 1);
643
644 return edid;
645}
646
647/**
648 * drm_get_edid - get EDID data, if available
649 * @connector: connector we're probing
650 * @adapter: i2c adapter to use for DDC
651 *
652 * Poke the given connector's i2c channel to grab EDID data if possible.
653 *
654 * Return edid data or NULL if we couldn't find any.
655 */
656struct edid *drm_get_edid(struct drm_connector *connector,
657 struct i2c_adapter *adapter)
658{
659 struct edid *edid;
660
661 edid = (struct edid *)drm_ddc_read(adapter);
662 if (!edid) {
663 dev_warn(&connector->dev->pdev->dev, "%s: no EDID data\n",
664 drm_get_connector_name(connector));
665 return NULL;
666 }
667 if (!edid_is_valid(edid)) {
668 dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
669 drm_get_connector_name(connector));
670 kfree(edid);
671 return NULL;
672 }
673
674 connector->display_info.raw_edid = (char *)edid;
675
676 return edid;
677}
678EXPORT_SYMBOL(drm_get_edid);
679
680/**
681 * drm_add_edid_modes - add modes from EDID data, if available
682 * @connector: connector we're probing
683 * @edid: edid data
684 *
685 * Add the specified modes to the connector's mode list.
686 *
687 * Return number of modes added or 0 if we couldn't find any.
688 */
689int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
690{
691 int num_modes = 0;
692 u32 quirks;
693
694 if (edid == NULL) {
695 return 0;
696 }
697 if (!edid_is_valid(edid)) {
698 dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
699 drm_get_connector_name(connector));
700 return 0;
701 }
702
703 quirks = edid_get_quirks(edid);
704
705 num_modes += add_established_modes(connector, edid);
706 num_modes += add_standard_modes(connector, edid);
707 num_modes += add_detailed_info(connector, edid, quirks);
708
709 if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
710 edid_fixup_preferred(connector, quirks);
711
712 connector->display_info.serration_vsync = edid->serration_vsync;
713 connector->display_info.sync_on_green = edid->sync_on_green;
714 connector->display_info.composite_sync = edid->composite_sync;
715 connector->display_info.separate_syncs = edid->separate_syncs;
716 connector->display_info.blank_to_black = edid->blank_to_black;
717 connector->display_info.video_level = edid->video_level;
718 connector->display_info.digital = edid->digital;
719 connector->display_info.width_mm = edid->width_cm * 10;
720 connector->display_info.height_mm = edid->height_cm * 10;
721 connector->display_info.gamma = edid->gamma;
722 connector->display_info.gtf_supported = edid->default_gtf;
723 connector->display_info.standard_color = edid->standard_color;
724 connector->display_info.display_type = edid->display_type;
725 connector->display_info.active_off_supported = edid->pm_active_off;
726 connector->display_info.suspend_supported = edid->pm_suspend;
727 connector->display_info.standby_supported = edid->pm_standby;
728 connector->display_info.gamma = edid->gamma;
729
730 return num_modes;
731}
732EXPORT_SYMBOL(drm_add_edid_modes);
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 3a6c439652a5..3733e36d135e 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -35,7 +35,6 @@
35 */ 35 */
36 36
37#include "drmP.h" 37#include "drmP.h"
38#include "drm_sarea.h"
39#include <linux/poll.h> 38#include <linux/poll.h>
40#include <linux/smp_lock.h> 39#include <linux/smp_lock.h>
41 40
@@ -55,10 +54,12 @@ static int drm_setup(struct drm_device * dev)
55 54
56 atomic_set(&dev->ioctl_count, 0); 55 atomic_set(&dev->ioctl_count, 0);
57 atomic_set(&dev->vma_count, 0); 56 atomic_set(&dev->vma_count, 0);
58 dev->buf_use = 0;
59 atomic_set(&dev->buf_alloc, 0);
60 57
61 if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) { 58 if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) &&
59 !drm_core_check_feature(dev, DRIVER_MODESET)) {
60 dev->buf_use = 0;
61 atomic_set(&dev->buf_alloc, 0);
62
62 i = drm_dma_setup(dev); 63 i = drm_dma_setup(dev);
63 if (i < 0) 64 if (i < 0)
64 return i; 65 return i;
@@ -138,14 +139,14 @@ int drm_open(struct inode *inode, struct file *filp)
138 } 139 }
139 spin_unlock(&dev->count_lock); 140 spin_unlock(&dev->count_lock);
140 } 141 }
141
142out: 142out:
143 mutex_lock(&dev->struct_mutex); 143 mutex_lock(&dev->struct_mutex);
144 if (dev->dev_mapping == NULL) 144 if (minor->type == DRM_MINOR_LEGACY) {
145 dev->dev_mapping = inode->i_mapping; 145 BUG_ON((dev->dev_mapping != NULL) &&
146 else if (dev->dev_mapping != inode->i_mapping) 146 (dev->dev_mapping != inode->i_mapping));
147 WARN(1, "dev->dev_mapping not inode mapping (%p expected %p)\n", 147 if (dev->dev_mapping == NULL)
148 dev->dev_mapping, inode->i_mapping); 148 dev->dev_mapping = inode->i_mapping;
149 }
149 mutex_unlock(&dev->struct_mutex); 150 mutex_unlock(&dev->struct_mutex);
150 151
151 return retcode; 152 return retcode;
@@ -251,6 +252,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
251 priv->lock_count = 0; 252 priv->lock_count = 0;
252 253
253 INIT_LIST_HEAD(&priv->lhead); 254 INIT_LIST_HEAD(&priv->lhead);
255 INIT_LIST_HEAD(&priv->fbs);
254 256
255 if (dev->driver->driver_features & DRIVER_GEM) 257 if (dev->driver->driver_features & DRIVER_GEM)
256 drm_gem_open(dev, priv); 258 drm_gem_open(dev, priv);
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 1e787f894b3c..1608f8dbfda0 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -305,6 +305,8 @@ int drm_control(struct drm_device *dev, void *data,
305 case DRM_INST_HANDLER: 305 case DRM_INST_HANDLER:
306 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) 306 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
307 return 0; 307 return 0;
308 if (drm_core_check_feature(dev, DRIVER_MODESET))
309 return 0;
308 if (dev->if_version < DRM_IF_VERSION(1, 2) && 310 if (dev->if_version < DRM_IF_VERSION(1, 2) &&
309 ctl->irq != dev->pdev->irq) 311 ctl->irq != dev->pdev->irq)
310 return -EINVAL; 312 return -EINVAL;
@@ -312,6 +314,8 @@ int drm_control(struct drm_device *dev, void *data,
312 case DRM_UNINST_HANDLER: 314 case DRM_UNINST_HANDLER:
313 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) 315 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
314 return 0; 316 return 0;
317 if (drm_core_check_feature(dev, DRIVER_MODESET))
318 return 0;
315 return drm_irq_uninstall(dev); 319 return drm_irq_uninstall(dev);
316 default: 320 default:
317 return -EINVAL; 321 return -EINVAL;
@@ -427,6 +431,45 @@ void drm_vblank_put(struct drm_device *dev, int crtc)
427EXPORT_SYMBOL(drm_vblank_put); 431EXPORT_SYMBOL(drm_vblank_put);
428 432
429/** 433/**
434 * drm_vblank_pre_modeset - account for vblanks across mode sets
435 * @dev: DRM device
436 * @crtc: CRTC in question
437 * @post: post or pre mode set?
438 *
439 * Account for vblank events across mode setting events, which will likely
440 * reset the hardware frame counter.
441 */
442void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
443{
444 /*
445 * To avoid all the problems that might happen if interrupts
446 * were enabled/disabled around or between these calls, we just
447 * have the kernel take a reference on the CRTC (just once though
448 * to avoid corrupting the count if multiple, mismatch calls occur),
449 * so that interrupts remain enabled in the interim.
450 */
451 if (!dev->vblank_inmodeset[crtc]) {
452 dev->vblank_inmodeset[crtc] = 1;
453 drm_vblank_get(dev, crtc);
454 }
455}
456EXPORT_SYMBOL(drm_vblank_pre_modeset);
457
458void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
459{
460 unsigned long irqflags;
461
462 if (dev->vblank_inmodeset[crtc]) {
463 spin_lock_irqsave(&dev->vbl_lock, irqflags);
464 dev->vblank_disable_allowed = 1;
465 dev->vblank_inmodeset[crtc] = 0;
466 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
467 drm_vblank_put(dev, crtc);
468 }
469}
470EXPORT_SYMBOL(drm_vblank_post_modeset);
471
472/**
430 * drm_modeset_ctl - handle vblank event counter changes across mode switch 473 * drm_modeset_ctl - handle vblank event counter changes across mode switch
431 * @DRM_IOCTL_ARGS: standard ioctl arguments 474 * @DRM_IOCTL_ARGS: standard ioctl arguments
432 * 475 *
@@ -441,7 +484,6 @@ int drm_modeset_ctl(struct drm_device *dev, void *data,
441 struct drm_file *file_priv) 484 struct drm_file *file_priv)
442{ 485{
443 struct drm_modeset_ctl *modeset = data; 486 struct drm_modeset_ctl *modeset = data;
444 unsigned long irqflags;
445 int crtc, ret = 0; 487 int crtc, ret = 0;
446 488
447 /* If drm_vblank_init() hasn't been called yet, just no-op */ 489 /* If drm_vblank_init() hasn't been called yet, just no-op */
@@ -454,28 +496,12 @@ int drm_modeset_ctl(struct drm_device *dev, void *data,
454 goto out; 496 goto out;
455 } 497 }
456 498
457 /*
458 * To avoid all the problems that might happen if interrupts
459 * were enabled/disabled around or between these calls, we just
460 * have the kernel take a reference on the CRTC (just once though
461 * to avoid corrupting the count if multiple, mismatch calls occur),
462 * so that interrupts remain enabled in the interim.
463 */
464 switch (modeset->cmd) { 499 switch (modeset->cmd) {
465 case _DRM_PRE_MODESET: 500 case _DRM_PRE_MODESET:
466 if (!dev->vblank_inmodeset[crtc]) { 501 drm_vblank_pre_modeset(dev, crtc);
467 dev->vblank_inmodeset[crtc] = 1;
468 drm_vblank_get(dev, crtc);
469 }
470 break; 502 break;
471 case _DRM_POST_MODESET: 503 case _DRM_POST_MODESET:
472 if (dev->vblank_inmodeset[crtc]) { 504 drm_vblank_post_modeset(dev, crtc);
473 spin_lock_irqsave(&dev->vbl_lock, irqflags);
474 dev->vblank_disable_allowed = 1;
475 dev->vblank_inmodeset[crtc] = 0;
476 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
477 drm_vblank_put(dev, crtc);
478 }
479 break; 505 break;
480 default: 506 default:
481 ret = -EINVAL; 507 ret = -EINVAL;
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 217ad7dc7076..367c590ffbba 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -296,3 +296,4 @@ void drm_mm_takedown(struct drm_mm * mm)
296 296
297 drm_free(entry, sizeof(*entry), DRM_MEM_MM); 297 drm_free(entry, sizeof(*entry), DRM_MEM_MM);
298} 298}
299EXPORT_SYMBOL(drm_mm_takedown);
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
new file mode 100644
index 000000000000..c9b80fdd4630
--- /dev/null
+++ b/drivers/gpu/drm/drm_modes.c
@@ -0,0 +1,576 @@
1/*
2 * The list_sort function is (presumably) licensed under the GPL (see the
3 * top level "COPYING" file for details).
4 *
5 * The remainder of this file is:
6 *
7 * Copyright © 1997-2003 by The XFree86 Project, Inc.
8 * Copyright © 2007 Dave Airlie
9 * Copyright © 2007-2008 Intel Corporation
10 * Jesse Barnes <jesse.barnes@intel.com>
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
18 *
19 * The above copyright notice and this permission notice shall be included in
20 * all copies or substantial portions of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
26 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 *
30 * Except as contained in this notice, the name of the copyright holder(s)
31 * and author(s) shall not be used in advertising or otherwise to promote
32 * the sale, use or other dealings in this Software without prior written
33 * authorization from the copyright holder(s) and author(s).
34 */
35
36#include <linux/list.h>
37#include "drmP.h"
38#include "drm.h"
39#include "drm_crtc.h"
40
41/**
42 * drm_mode_debug_printmodeline - debug print a mode
43 * @dev: DRM device
44 * @mode: mode to print
45 *
46 * LOCKING:
47 * None.
48 *
49 * Describe @mode using DRM_DEBUG.
50 */
51void drm_mode_debug_printmodeline(struct drm_display_mode *mode)
52{
53 DRM_DEBUG("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n",
54 mode->base.id, mode->name, mode->vrefresh, mode->clock,
55 mode->hdisplay, mode->hsync_start,
56 mode->hsync_end, mode->htotal,
57 mode->vdisplay, mode->vsync_start,
58 mode->vsync_end, mode->vtotal, mode->type, mode->flags);
59}
60EXPORT_SYMBOL(drm_mode_debug_printmodeline);
61
62/**
63 * drm_mode_set_name - set the name on a mode
64 * @mode: name will be set in this mode
65 *
66 * LOCKING:
67 * None.
68 *
69 * Set the name of @mode to a standard format.
70 */
71void drm_mode_set_name(struct drm_display_mode *mode)
72{
73 snprintf(mode->name, DRM_DISPLAY_MODE_LEN, "%dx%d", mode->hdisplay,
74 mode->vdisplay);
75}
76EXPORT_SYMBOL(drm_mode_set_name);
77
78/**
79 * drm_mode_list_concat - move modes from one list to another
80 * @head: source list
81 * @new: dst list
82 *
83 * LOCKING:
84 * Caller must ensure both lists are locked.
85 *
86 * Move all the modes from @head to @new.
87 */
88void drm_mode_list_concat(struct list_head *head, struct list_head *new)
89{
90
91 struct list_head *entry, *tmp;
92
93 list_for_each_safe(entry, tmp, head) {
94 list_move_tail(entry, new);
95 }
96}
97EXPORT_SYMBOL(drm_mode_list_concat);
98
99/**
100 * drm_mode_width - get the width of a mode
101 * @mode: mode
102 *
103 * LOCKING:
104 * None.
105 *
106 * Return @mode's width (hdisplay) value.
107 *
108 * FIXME: is this needed?
109 *
110 * RETURNS:
111 * @mode->hdisplay
112 */
113int drm_mode_width(struct drm_display_mode *mode)
114{
115 return mode->hdisplay;
116
117}
118EXPORT_SYMBOL(drm_mode_width);
119
120/**
121 * drm_mode_height - get the height of a mode
122 * @mode: mode
123 *
124 * LOCKING:
125 * None.
126 *
127 * Return @mode's height (vdisplay) value.
128 *
129 * FIXME: is this needed?
130 *
131 * RETURNS:
132 * @mode->vdisplay
133 */
134int drm_mode_height(struct drm_display_mode *mode)
135{
136 return mode->vdisplay;
137}
138EXPORT_SYMBOL(drm_mode_height);
139
140/**
141 * drm_mode_vrefresh - get the vrefresh of a mode
142 * @mode: mode
143 *
144 * LOCKING:
145 * None.
146 *
147 * Return @mode's vrefresh rate or calculate it if necessary.
148 *
149 * FIXME: why is this needed? shouldn't vrefresh be set already?
150 *
151 * RETURNS:
152 * Vertical refresh rate of @mode x 1000. For precision reasons.
153 */
154int drm_mode_vrefresh(struct drm_display_mode *mode)
155{
156 int refresh = 0;
157 unsigned int calc_val;
158
159 if (mode->vrefresh > 0)
160 refresh = mode->vrefresh;
161 else if (mode->htotal > 0 && mode->vtotal > 0) {
162 /* work out vrefresh the value will be x1000 */
163 calc_val = (mode->clock * 1000);
164
165 calc_val /= mode->htotal;
166 calc_val *= 1000;
167 calc_val /= mode->vtotal;
168
169 refresh = calc_val;
170 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
171 refresh *= 2;
172 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
173 refresh /= 2;
174 if (mode->vscan > 1)
175 refresh /= mode->vscan;
176 }
177 return refresh;
178}
179EXPORT_SYMBOL(drm_mode_vrefresh);
180
181/**
182 * drm_mode_set_crtcinfo - set CRTC modesetting parameters
183 * @p: mode
184 * @adjust_flags: unused? (FIXME)
185 *
186 * LOCKING:
187 * None.
188 *
189 * Setup the CRTC modesetting parameters for @p, adjusting if necessary.
190 */
191void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags)
192{
193 if ((p == NULL) || ((p->type & DRM_MODE_TYPE_CRTC_C) == DRM_MODE_TYPE_BUILTIN))
194 return;
195
196 p->crtc_hdisplay = p->hdisplay;
197 p->crtc_hsync_start = p->hsync_start;
198 p->crtc_hsync_end = p->hsync_end;
199 p->crtc_htotal = p->htotal;
200 p->crtc_hskew = p->hskew;
201 p->crtc_vdisplay = p->vdisplay;
202 p->crtc_vsync_start = p->vsync_start;
203 p->crtc_vsync_end = p->vsync_end;
204 p->crtc_vtotal = p->vtotal;
205
206 if (p->flags & DRM_MODE_FLAG_INTERLACE) {
207 if (adjust_flags & CRTC_INTERLACE_HALVE_V) {
208 p->crtc_vdisplay /= 2;
209 p->crtc_vsync_start /= 2;
210 p->crtc_vsync_end /= 2;
211 p->crtc_vtotal /= 2;
212 }
213
214 p->crtc_vtotal |= 1;
215 }
216
217 if (p->flags & DRM_MODE_FLAG_DBLSCAN) {
218 p->crtc_vdisplay *= 2;
219 p->crtc_vsync_start *= 2;
220 p->crtc_vsync_end *= 2;
221 p->crtc_vtotal *= 2;
222 }
223
224 if (p->vscan > 1) {
225 p->crtc_vdisplay *= p->vscan;
226 p->crtc_vsync_start *= p->vscan;
227 p->crtc_vsync_end *= p->vscan;
228 p->crtc_vtotal *= p->vscan;
229 }
230
231 p->crtc_vblank_start = min(p->crtc_vsync_start, p->crtc_vdisplay);
232 p->crtc_vblank_end = max(p->crtc_vsync_end, p->crtc_vtotal);
233 p->crtc_hblank_start = min(p->crtc_hsync_start, p->crtc_hdisplay);
234 p->crtc_hblank_end = max(p->crtc_hsync_end, p->crtc_htotal);
235
236 p->crtc_hadjusted = false;
237 p->crtc_vadjusted = false;
238}
239EXPORT_SYMBOL(drm_mode_set_crtcinfo);
240
241
242/**
243 * drm_mode_duplicate - allocate and duplicate an existing mode
244 * @m: mode to duplicate
245 *
246 * LOCKING:
247 * None.
248 *
249 * Just allocate a new mode, copy the existing mode into it, and return
250 * a pointer to it. Used to create new instances of established modes.
251 */
252struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
253 struct drm_display_mode *mode)
254{
255 struct drm_display_mode *nmode;
256 int new_id;
257
258 nmode = drm_mode_create(dev);
259 if (!nmode)
260 return NULL;
261
262 new_id = nmode->base.id;
263 *nmode = *mode;
264 nmode->base.id = new_id;
265 INIT_LIST_HEAD(&nmode->head);
266 return nmode;
267}
268EXPORT_SYMBOL(drm_mode_duplicate);
269
270/**
271 * drm_mode_equal - test modes for equality
272 * @mode1: first mode
273 * @mode2: second mode
274 *
275 * LOCKING:
276 * None.
277 *
278 * Check to see if @mode1 and @mode2 are equivalent.
279 *
280 * RETURNS:
281 * True if the modes are equal, false otherwise.
282 */
283bool drm_mode_equal(struct drm_display_mode *mode1, struct drm_display_mode *mode2)
284{
285 /* do clock check convert to PICOS so fb modes get matched
286 * the same */
287 if (mode1->clock && mode2->clock) {
288 if (KHZ2PICOS(mode1->clock) != KHZ2PICOS(mode2->clock))
289 return false;
290 } else if (mode1->clock != mode2->clock)
291 return false;
292
293 if (mode1->hdisplay == mode2->hdisplay &&
294 mode1->hsync_start == mode2->hsync_start &&
295 mode1->hsync_end == mode2->hsync_end &&
296 mode1->htotal == mode2->htotal &&
297 mode1->hskew == mode2->hskew &&
298 mode1->vdisplay == mode2->vdisplay &&
299 mode1->vsync_start == mode2->vsync_start &&
300 mode1->vsync_end == mode2->vsync_end &&
301 mode1->vtotal == mode2->vtotal &&
302 mode1->vscan == mode2->vscan &&
303 mode1->flags == mode2->flags)
304 return true;
305
306 return false;
307}
308EXPORT_SYMBOL(drm_mode_equal);
309
310/**
311 * drm_mode_validate_size - make sure modes adhere to size constraints
312 * @dev: DRM device
313 * @mode_list: list of modes to check
314 * @maxX: maximum width
315 * @maxY: maximum height
316 * @maxPitch: max pitch
317 *
318 * LOCKING:
319 * Caller must hold a lock protecting @mode_list.
320 *
321 * The DRM device (@dev) has size and pitch limits. Here we validate the
322 * modes we probed for @dev against those limits and set their status as
323 * necessary.
324 */
325void drm_mode_validate_size(struct drm_device *dev,
326 struct list_head *mode_list,
327 int maxX, int maxY, int maxPitch)
328{
329 struct drm_display_mode *mode;
330
331 list_for_each_entry(mode, mode_list, head) {
332 if (maxPitch > 0 && mode->hdisplay > maxPitch)
333 mode->status = MODE_BAD_WIDTH;
334
335 if (maxX > 0 && mode->hdisplay > maxX)
336 mode->status = MODE_VIRTUAL_X;
337
338 if (maxY > 0 && mode->vdisplay > maxY)
339 mode->status = MODE_VIRTUAL_Y;
340 }
341}
342EXPORT_SYMBOL(drm_mode_validate_size);
343
344/**
345 * drm_mode_validate_clocks - validate modes against clock limits
346 * @dev: DRM device
347 * @mode_list: list of modes to check
348 * @min: minimum clock rate array
349 * @max: maximum clock rate array
350 * @n_ranges: number of clock ranges (size of arrays)
351 *
352 * LOCKING:
353 * Caller must hold a lock protecting @mode_list.
354 *
355 * Some code may need to check a mode list against the clock limits of the
356 * device in question. This function walks the mode list, testing to make
357 * sure each mode falls within a given range (defined by @min and @max
358 * arrays) and sets @mode->status as needed.
359 */
360void drm_mode_validate_clocks(struct drm_device *dev,
361 struct list_head *mode_list,
362 int *min, int *max, int n_ranges)
363{
364 struct drm_display_mode *mode;
365 int i;
366
367 list_for_each_entry(mode, mode_list, head) {
368 bool good = false;
369 for (i = 0; i < n_ranges; i++) {
370 if (mode->clock >= min[i] && mode->clock <= max[i]) {
371 good = true;
372 break;
373 }
374 }
375 if (!good)
376 mode->status = MODE_CLOCK_RANGE;
377 }
378}
379EXPORT_SYMBOL(drm_mode_validate_clocks);
380
381/**
382 * drm_mode_prune_invalid - remove invalid modes from mode list
383 * @dev: DRM device
384 * @mode_list: list of modes to check
385 * @verbose: be verbose about it
386 *
387 * LOCKING:
388 * Caller must hold a lock protecting @mode_list.
389 *
390 * Once mode list generation is complete, a caller can use this routine to
391 * remove invalid modes from a mode list. If any of the modes have a
392 * status other than %MODE_OK, they are removed from @mode_list and freed.
393 */
394void drm_mode_prune_invalid(struct drm_device *dev,
395 struct list_head *mode_list, bool verbose)
396{
397 struct drm_display_mode *mode, *t;
398
399 list_for_each_entry_safe(mode, t, mode_list, head) {
400 if (mode->status != MODE_OK) {
401 list_del(&mode->head);
402 if (verbose) {
403 drm_mode_debug_printmodeline(mode);
404 DRM_DEBUG("Not using %s mode %d\n", mode->name, mode->status);
405 }
406 drm_mode_destroy(dev, mode);
407 }
408 }
409}
410EXPORT_SYMBOL(drm_mode_prune_invalid);
411
412/**
413 * drm_mode_compare - compare modes for favorability
414 * @lh_a: list_head for first mode
415 * @lh_b: list_head for second mode
416 *
417 * LOCKING:
418 * None.
419 *
420 * Compare two modes, given by @lh_a and @lh_b, returning a value indicating
421 * which is better.
422 *
423 * RETURNS:
424 * Negative if @lh_a is better than @lh_b, zero if they're equivalent, or
425 * positive if @lh_b is better than @lh_a.
426 */
427static int drm_mode_compare(struct list_head *lh_a, struct list_head *lh_b)
428{
429 struct drm_display_mode *a = list_entry(lh_a, struct drm_display_mode, head);
430 struct drm_display_mode *b = list_entry(lh_b, struct drm_display_mode, head);
431 int diff;
432
433 diff = ((b->type & DRM_MODE_TYPE_PREFERRED) != 0) -
434 ((a->type & DRM_MODE_TYPE_PREFERRED) != 0);
435 if (diff)
436 return diff;
437 diff = b->hdisplay * b->vdisplay - a->hdisplay * a->vdisplay;
438 if (diff)
439 return diff;
440 diff = b->clock - a->clock;
441 return diff;
442}
443
444/* FIXME: what we don't have a list sort function? */
445/* list sort from Mark J Roberts (mjr@znex.org) */
446void list_sort(struct list_head *head,
447 int (*cmp)(struct list_head *a, struct list_head *b))
448{
449 struct list_head *p, *q, *e, *list, *tail, *oldhead;
450 int insize, nmerges, psize, qsize, i;
451
452 list = head->next;
453 list_del(head);
454 insize = 1;
455 for (;;) {
456 p = oldhead = list;
457 list = tail = NULL;
458 nmerges = 0;
459
460 while (p) {
461 nmerges++;
462 q = p;
463 psize = 0;
464 for (i = 0; i < insize; i++) {
465 psize++;
466 q = q->next == oldhead ? NULL : q->next;
467 if (!q)
468 break;
469 }
470
471 qsize = insize;
472 while (psize > 0 || (qsize > 0 && q)) {
473 if (!psize) {
474 e = q;
475 q = q->next;
476 qsize--;
477 if (q == oldhead)
478 q = NULL;
479 } else if (!qsize || !q) {
480 e = p;
481 p = p->next;
482 psize--;
483 if (p == oldhead)
484 p = NULL;
485 } else if (cmp(p, q) <= 0) {
486 e = p;
487 p = p->next;
488 psize--;
489 if (p == oldhead)
490 p = NULL;
491 } else {
492 e = q;
493 q = q->next;
494 qsize--;
495 if (q == oldhead)
496 q = NULL;
497 }
498 if (tail)
499 tail->next = e;
500 else
501 list = e;
502 e->prev = tail;
503 tail = e;
504 }
505 p = q;
506 }
507
508 tail->next = list;
509 list->prev = tail;
510
511 if (nmerges <= 1)
512 break;
513
514 insize *= 2;
515 }
516
517 head->next = list;
518 head->prev = list->prev;
519 list->prev->next = head;
520 list->prev = head;
521}
522
523/**
524 * drm_mode_sort - sort mode list
525 * @mode_list: list to sort
526 *
527 * LOCKING:
528 * Caller must hold a lock protecting @mode_list.
529 *
530 * Sort @mode_list by favorability, putting good modes first.
531 */
532void drm_mode_sort(struct list_head *mode_list)
533{
534 list_sort(mode_list, drm_mode_compare);
535}
536EXPORT_SYMBOL(drm_mode_sort);
537
538/**
539 * drm_mode_connector_list_update - update the mode list for the connector
540 * @connector: the connector to update
541 *
542 * LOCKING:
543 * Caller must hold a lock protecting @mode_list.
544 *
545 * This moves the modes from the @connector probed_modes list
546 * to the actual mode list. It compares the probed mode against the current
547 * list and only adds different modes. All modes unverified after this point
548 * will be removed by the prune invalid modes.
549 */
550void drm_mode_connector_list_update(struct drm_connector *connector)
551{
552 struct drm_display_mode *mode;
553 struct drm_display_mode *pmode, *pt;
554 int found_it;
555
556 list_for_each_entry_safe(pmode, pt, &connector->probed_modes,
557 head) {
558 found_it = 0;
559 /* go through current modes checking for the new probed mode */
560 list_for_each_entry(mode, &connector->modes, head) {
561 if (drm_mode_equal(pmode, mode)) {
562 found_it = 1;
563 /* if equal delete the probed mode */
564 mode->status = pmode->status;
565 list_del(&pmode->head);
566 drm_mode_destroy(connector->dev, pmode);
567 break;
568 }
569 }
570
571 if (!found_it) {
572 list_move_tail(&pmode->head, &connector->modes);
573 }
574 }
575}
576EXPORT_SYMBOL(drm_mode_connector_list_update);
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index ea7f9e5d47fa..5ca132afa4f2 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -57,6 +57,14 @@ static int drm_minor_get_id(struct drm_device *dev, int type)
57 int ret; 57 int ret;
58 int base = 0, limit = 63; 58 int base = 0, limit = 63;
59 59
60 if (type == DRM_MINOR_CONTROL) {
61 base += 64;
62 limit = base + 127;
63 } else if (type == DRM_MINOR_RENDER) {
64 base += 128;
65 limit = base + 255;
66 }
67
60again: 68again:
61 if (idr_pre_get(&drm_minors_idr, GFP_KERNEL) == 0) { 69 if (idr_pre_get(&drm_minors_idr, GFP_KERNEL) == 0) {
62 DRM_ERROR("Out of memory expanding drawable idr\n"); 70 DRM_ERROR("Out of memory expanding drawable idr\n");
@@ -362,12 +370,28 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
362 printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); 370 printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
363 goto err_g2; 371 goto err_g2;
364 } 372 }
373
374 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
375 ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
376 if (ret)
377 goto err_g2;
378 }
379
365 if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) 380 if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY)))
366 goto err_g2; 381 goto err_g3;
367 382
368 if (dev->driver->load) 383 if (dev->driver->load) {
369 if ((ret = dev->driver->load(dev, ent->driver_data))) 384 ret = dev->driver->load(dev, ent->driver_data);
385 if (ret)
370 goto err_g3; 386 goto err_g3;
387 }
388
389 /* setup the grouping for the legacy output */
390 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
391 ret = drm_mode_group_init_legacy_group(dev, &dev->primary->mode_group);
392 if (ret)
393 goto err_g3;
394 }
371 395
372 list_add_tail(&dev->driver_item, &driver->device_list); 396 list_add_tail(&dev->driver_item, &driver->device_list);
373 397
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 1611b9bcbe7f..65d72d094c81 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -20,6 +20,7 @@
20#include "drmP.h" 20#include "drmP.h"
21 21
22#define to_drm_minor(d) container_of(d, struct drm_minor, kdev) 22#define to_drm_minor(d) container_of(d, struct drm_minor, kdev)
23#define to_drm_connector(d) container_of(d, struct drm_connector, kdev)
23 24
24/** 25/**
25 * drm_sysfs_suspend - DRM class suspend hook 26 * drm_sysfs_suspend - DRM class suspend hook
@@ -34,7 +35,7 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state)
34 struct drm_minor *drm_minor = to_drm_minor(dev); 35 struct drm_minor *drm_minor = to_drm_minor(dev);
35 struct drm_device *drm_dev = drm_minor->dev; 36 struct drm_device *drm_dev = drm_minor->dev;
36 37
37 if (drm_dev->driver->suspend) 38 if (drm_minor->type == DRM_MINOR_LEGACY && drm_dev->driver->suspend)
38 return drm_dev->driver->suspend(drm_dev, state); 39 return drm_dev->driver->suspend(drm_dev, state);
39 40
40 return 0; 41 return 0;
@@ -52,7 +53,7 @@ static int drm_sysfs_resume(struct device *dev)
52 struct drm_minor *drm_minor = to_drm_minor(dev); 53 struct drm_minor *drm_minor = to_drm_minor(dev);
53 struct drm_device *drm_dev = drm_minor->dev; 54 struct drm_device *drm_dev = drm_minor->dev;
54 55
55 if (drm_dev->driver->resume) 56 if (drm_minor->type == DRM_MINOR_LEGACY && drm_dev->driver->resume)
56 return drm_dev->driver->resume(drm_dev); 57 return drm_dev->driver->resume(drm_dev);
57 58
58 return 0; 59 return 0;
@@ -144,6 +145,323 @@ static void drm_sysfs_device_release(struct device *dev)
144 return; 145 return;
145} 146}
146 147
148/*
149 * Connector properties
150 */
151static ssize_t status_show(struct device *device,
152 struct device_attribute *attr,
153 char *buf)
154{
155 struct drm_connector *connector = to_drm_connector(device);
156 enum drm_connector_status status;
157
158 status = connector->funcs->detect(connector);
159 return snprintf(buf, PAGE_SIZE, "%s",
160 drm_get_connector_status_name(status));
161}
162
163static ssize_t dpms_show(struct device *device,
164 struct device_attribute *attr,
165 char *buf)
166{
167 struct drm_connector *connector = to_drm_connector(device);
168 struct drm_device *dev = connector->dev;
169 uint64_t dpms_status;
170 int ret;
171
172 ret = drm_connector_property_get_value(connector,
173 dev->mode_config.dpms_property,
174 &dpms_status);
175 if (ret)
176 return 0;
177
178 return snprintf(buf, PAGE_SIZE, "%s",
179 drm_get_dpms_name((int)dpms_status));
180}
181
182static ssize_t enabled_show(struct device *device,
183 struct device_attribute *attr,
184 char *buf)
185{
186 struct drm_connector *connector = to_drm_connector(device);
187
188 return snprintf(buf, PAGE_SIZE, connector->encoder ? "enabled" :
189 "disabled");
190}
191
192static ssize_t edid_show(struct kobject *kobj, struct bin_attribute *attr,
193 char *buf, loff_t off, size_t count)
194{
195 struct device *connector_dev = container_of(kobj, struct device, kobj);
196 struct drm_connector *connector = to_drm_connector(connector_dev);
197 unsigned char *edid;
198 size_t size;
199
200 if (!connector->edid_blob_ptr)
201 return 0;
202
203 edid = connector->edid_blob_ptr->data;
204 size = connector->edid_blob_ptr->length;
205 if (!edid)
206 return 0;
207
208 if (off >= size)
209 return 0;
210
211 if (off + count > size)
212 count = size - off;
213 memcpy(buf, edid + off, count);
214
215 return count;
216}
217
218static ssize_t modes_show(struct device *device,
219 struct device_attribute *attr,
220 char *buf)
221{
222 struct drm_connector *connector = to_drm_connector(device);
223 struct drm_display_mode *mode;
224 int written = 0;
225
226 list_for_each_entry(mode, &connector->modes, head) {
227 written += snprintf(buf + written, PAGE_SIZE - written, "%s\n",
228 mode->name);
229 }
230
231 return written;
232}
233
234static ssize_t subconnector_show(struct device *device,
235 struct device_attribute *attr,
236 char *buf)
237{
238 struct drm_connector *connector = to_drm_connector(device);
239 struct drm_device *dev = connector->dev;
240 struct drm_property *prop = NULL;
241 uint64_t subconnector;
242 int is_tv = 0;
243 int ret;
244
245 switch (connector->connector_type) {
246 case DRM_MODE_CONNECTOR_DVII:
247 prop = dev->mode_config.dvi_i_subconnector_property;
248 break;
249 case DRM_MODE_CONNECTOR_Composite:
250 case DRM_MODE_CONNECTOR_SVIDEO:
251 case DRM_MODE_CONNECTOR_Component:
252 prop = dev->mode_config.tv_subconnector_property;
253 is_tv = 1;
254 break;
255 default:
256 DRM_ERROR("Wrong connector type for this property\n");
257 return 0;
258 }
259
260 if (!prop) {
261 DRM_ERROR("Unable to find subconnector property\n");
262 return 0;
263 }
264
265 ret = drm_connector_property_get_value(connector, prop, &subconnector);
266 if (ret)
267 return 0;
268
269 return snprintf(buf, PAGE_SIZE, "%s", is_tv ?
270 drm_get_tv_subconnector_name((int)subconnector) :
271 drm_get_dvi_i_subconnector_name((int)subconnector));
272}
273
274static ssize_t select_subconnector_show(struct device *device,
275 struct device_attribute *attr,
276 char *buf)
277{
278 struct drm_connector *connector = to_drm_connector(device);
279 struct drm_device *dev = connector->dev;
280 struct drm_property *prop = NULL;
281 uint64_t subconnector;
282 int is_tv = 0;
283 int ret;
284
285 switch (connector->connector_type) {
286 case DRM_MODE_CONNECTOR_DVII:
287 prop = dev->mode_config.dvi_i_select_subconnector_property;
288 break;
289 case DRM_MODE_CONNECTOR_Composite:
290 case DRM_MODE_CONNECTOR_SVIDEO:
291 case DRM_MODE_CONNECTOR_Component:
292 prop = dev->mode_config.tv_select_subconnector_property;
293 is_tv = 1;
294 break;
295 default:
296 DRM_ERROR("Wrong connector type for this property\n");
297 return 0;
298 }
299
300 if (!prop) {
301 DRM_ERROR("Unable to find select subconnector property\n");
302 return 0;
303 }
304
305 ret = drm_connector_property_get_value(connector, prop, &subconnector);
306 if (ret)
307 return 0;
308
309 return snprintf(buf, PAGE_SIZE, "%s", is_tv ?
310 drm_get_tv_select_name((int)subconnector) :
311 drm_get_dvi_i_select_name((int)subconnector));
312}
313
314static struct device_attribute connector_attrs[] = {
315 __ATTR_RO(status),
316 __ATTR_RO(enabled),
317 __ATTR_RO(dpms),
318 __ATTR_RO(modes),
319};
320
321/* These attributes are for both DVI-I connectors and all types of tv-out. */
322static struct device_attribute connector_attrs_opt1[] = {
323 __ATTR_RO(subconnector),
324 __ATTR_RO(select_subconnector),
325};
326
327static struct bin_attribute edid_attr = {
328 .attr.name = "edid",
329 .size = 128,
330 .read = edid_show,
331};
332
333/**
334 * drm_sysfs_connector_add - add an connector to sysfs
335 * @connector: connector to add
336 *
337 * Create an connector device in sysfs, along with its associated connector
338 * properties (so far, connection status, dpms, mode list & edid) and
339 * generate a hotplug event so userspace knows there's a new connector
340 * available.
341 *
342 * Note:
343 * This routine should only be called *once* for each DRM minor registered.
344 * A second call for an already registered device will trigger the BUG_ON
345 * below.
346 */
347int drm_sysfs_connector_add(struct drm_connector *connector)
348{
349 struct drm_device *dev = connector->dev;
350 int ret = 0, i, j;
351
352 /* We shouldn't get called more than once for the same connector */
353 BUG_ON(device_is_registered(&connector->kdev));
354
355 connector->kdev.parent = &dev->primary->kdev;
356 connector->kdev.class = drm_class;
357 connector->kdev.release = drm_sysfs_device_release;
358
359 DRM_DEBUG("adding \"%s\" to sysfs\n",
360 drm_get_connector_name(connector));
361
362 snprintf(connector->kdev.bus_id, BUS_ID_SIZE, "card%d-%s",
363 dev->primary->index, drm_get_connector_name(connector));
364 ret = device_register(&connector->kdev);
365
366 if (ret) {
367 DRM_ERROR("failed to register connector device: %d\n", ret);
368 goto out;
369 }
370
371 /* Standard attributes */
372
373 for (i = 0; i < ARRAY_SIZE(connector_attrs); i++) {
374 ret = device_create_file(&connector->kdev, &connector_attrs[i]);
375 if (ret)
376 goto err_out_files;
377 }
378
379 /* Optional attributes */
380 /*
381 * In the long run it maybe a good idea to make one set of
382 * optionals per connector type.
383 */
384 switch (connector->connector_type) {
385 case DRM_MODE_CONNECTOR_DVII:
386 case DRM_MODE_CONNECTOR_Composite:
387 case DRM_MODE_CONNECTOR_SVIDEO:
388 case DRM_MODE_CONNECTOR_Component:
389 for (i = 0; i < ARRAY_SIZE(connector_attrs_opt1); i++) {
390 ret = device_create_file(&connector->kdev, &connector_attrs_opt1[i]);
391 if (ret)
392 goto err_out_files;
393 }
394 break;
395 default:
396 break;
397 }
398
399 ret = sysfs_create_bin_file(&connector->kdev.kobj, &edid_attr);
400 if (ret)
401 goto err_out_files;
402
403 /* Let userspace know we have a new connector */
404 drm_sysfs_hotplug_event(dev);
405
406 return 0;
407
408err_out_files:
409 if (i > 0)
410 for (j = 0; j < i; j++)
411 device_remove_file(&connector->kdev,
412 &connector_attrs[i]);
413 device_unregister(&connector->kdev);
414
415out:
416 return ret;
417}
418EXPORT_SYMBOL(drm_sysfs_connector_add);
419
420/**
421 * drm_sysfs_connector_remove - remove an connector device from sysfs
422 * @connector: connector to remove
423 *
424 * Remove @connector and its associated attributes from sysfs. Note that
425 * the device model core will take care of sending the "remove" uevent
426 * at this time, so we don't need to do it.
427 *
428 * Note:
429 * This routine should only be called if the connector was previously
430 * successfully registered. If @connector hasn't been registered yet,
431 * you'll likely see a panic somewhere deep in sysfs code when called.
432 */
433void drm_sysfs_connector_remove(struct drm_connector *connector)
434{
435 int i;
436
437 DRM_DEBUG("removing \"%s\" from sysfs\n",
438 drm_get_connector_name(connector));
439
440 for (i = 0; i < ARRAY_SIZE(connector_attrs); i++)
441 device_remove_file(&connector->kdev, &connector_attrs[i]);
442 sysfs_remove_bin_file(&connector->kdev.kobj, &edid_attr);
443 device_unregister(&connector->kdev);
444}
445EXPORT_SYMBOL(drm_sysfs_connector_remove);
446
447/**
448 * drm_sysfs_hotplug_event - generate a DRM uevent
449 * @dev: DRM device
450 *
451 * Send a uevent for the DRM device specified by @dev. Currently we only
452 * set HOTPLUG=1 in the uevent environment, but this could be expanded to
453 * deal with other types of events.
454 */
455void drm_sysfs_hotplug_event(struct drm_device *dev)
456{
457 char *event_string = "HOTPLUG=1";
458 char *envp[] = { event_string, NULL };
459
460 DRM_DEBUG("generating hotplug event\n");
461
462 kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, envp);
463}
464
147/** 465/**
148 * drm_sysfs_device_add - adds a class device to sysfs for a character driver 466 * drm_sysfs_device_add - adds a class device to sysfs for a character driver
149 * @dev: DRM device to be added 467 * @dev: DRM device to be added
@@ -163,7 +481,12 @@ int drm_sysfs_device_add(struct drm_minor *minor)
163 minor->kdev.class = drm_class; 481 minor->kdev.class = drm_class;
164 minor->kdev.release = drm_sysfs_device_release; 482 minor->kdev.release = drm_sysfs_device_release;
165 minor->kdev.devt = minor->device; 483 minor->kdev.devt = minor->device;
166 minor_str = "card%d"; 484 if (minor->type == DRM_MINOR_CONTROL)
485 minor_str = "controlD%d";
486 else if (minor->type == DRM_MINOR_RENDER)
487 minor_str = "renderD%d";
488 else
489 minor_str = "card%d";
167 490
168 snprintf(minor->kdev.bus_id, BUS_ID_SIZE, minor_str, minor->index); 491 snprintf(minor->kdev.bus_id, BUS_ID_SIZE, minor_str, minor->index);
169 492
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 448d209a0bf2..e6210725b9ab 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -112,6 +112,23 @@ static int vga_video_font_height;
112static int vga_scan_lines __read_mostly; 112static int vga_scan_lines __read_mostly;
113static unsigned int vga_rolled_over; 113static unsigned int vga_rolled_over;
114 114
115int vgacon_text_mode_force = 0;
116
117bool vgacon_text_force(void)
118{
119 return vgacon_text_mode_force ? true : false;
120}
121EXPORT_SYMBOL(vgacon_text_force);
122
123static int __init text_mode(char *str)
124{
125 vgacon_text_mode_force = 1;
126 return 1;
127}
128
129/* force text mode - used by kernel modesetting */
130__setup("nomodeset", text_mode);
131
115static int __init no_scroll(char *str) 132static int __init no_scroll(char *str)
116{ 133{
117 /* 134 /*
diff --git a/include/drm/Kbuild b/include/drm/Kbuild
index 82b6983b7fbb..b940fdfa3b25 100644
--- a/include/drm/Kbuild
+++ b/include/drm/Kbuild
@@ -1,4 +1,4 @@
1unifdef-y += drm.h drm_sarea.h 1unifdef-y += drm.h drm_sarea.h drm_mode.h
2unifdef-y += i810_drm.h 2unifdef-y += i810_drm.h
3unifdef-y += i830_drm.h 3unifdef-y += i830_drm.h
4unifdef-y += i915_drm.h 4unifdef-y += i915_drm.h
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 3a66252456ba..76ce6fe300b7 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -599,6 +599,8 @@ struct drm_gem_open {
599 uint64_t size; 599 uint64_t size;
600}; 600};
601 601
602#include "drm_mode.h"
603
602#define DRM_IOCTL_BASE 'd' 604#define DRM_IOCTL_BASE 'd'
603#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) 605#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
604#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) 606#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type)
@@ -668,6 +670,25 @@ struct drm_gem_open {
668 670
669#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw) 671#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw)
670 672
673#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res)
674#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc)
675#define DRM_IOCTL_MODE_SETCRTC DRM_IOWR(0xA2, struct drm_mode_crtc)
676#define DRM_IOCTL_MODE_CURSOR DRM_IOWR(0xA3, struct drm_mode_cursor)
677#define DRM_IOCTL_MODE_GETGAMMA DRM_IOWR(0xA4, struct drm_mode_crtc_lut)
678#define DRM_IOCTL_MODE_SETGAMMA DRM_IOWR(0xA5, struct drm_mode_crtc_lut)
679#define DRM_IOCTL_MODE_GETENCODER DRM_IOWR(0xA6, struct drm_mode_get_encoder)
680#define DRM_IOCTL_MODE_GETCONNECTOR DRM_IOWR(0xA7, struct drm_mode_get_connector)
681#define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA8, struct drm_mode_mode_cmd)
682#define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd)
683
684#define DRM_IOCTL_MODE_GETPROPERTY DRM_IOWR(0xAA, struct drm_mode_get_property)
685#define DRM_IOCTL_MODE_SETPROPERTY DRM_IOWR(0xAB, struct drm_mode_connector_set_property)
686#define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xAC, struct drm_mode_get_blob)
687#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd)
688#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd)
689#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int)
690#define DRM_IOCTL_MODE_REPLACEFB DRM_IOWR(0xB0, struct drm_mode_fb_cmd)
691
671/** 692/**
672 * Device specific ioctls should only be in their respective headers 693 * Device specific ioctls should only be in their respective headers
673 * The device specific ioctl range is from 0x40 to 0x99. 694 * The device specific ioctl range is from 0x40 to 0x99.
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index ae42a6a5c24e..7802c80f2b23 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -105,6 +105,7 @@ struct drm_device;
105#define DRIVER_FB_DMA 0x400 105#define DRIVER_FB_DMA 0x400
106#define DRIVER_IRQ_VBL2 0x800 106#define DRIVER_IRQ_VBL2 0x800
107#define DRIVER_GEM 0x1000 107#define DRIVER_GEM 0x1000
108#define DRIVER_MODESET 0x2000
108 109
109/***********************************************************************/ 110/***********************************************************************/
110/** \name Begin the DRM... */ 111/** \name Begin the DRM... */
@@ -276,6 +277,7 @@ typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
276#define DRM_AUTH 0x1 277#define DRM_AUTH 0x1
277#define DRM_MASTER 0x2 278#define DRM_MASTER 0x2
278#define DRM_ROOT_ONLY 0x4 279#define DRM_ROOT_ONLY 0x4
280#define DRM_CONTROL_ALLOW 0x8
279 281
280struct drm_ioctl_desc { 282struct drm_ioctl_desc {
281 unsigned int cmd; 283 unsigned int cmd;
@@ -398,6 +400,7 @@ struct drm_file {
398 int is_master; /* this file private is a master for a minor */ 400 int is_master; /* this file private is a master for a minor */
399 struct drm_master *master; /* master this node is currently associated with 401 struct drm_master *master; /* master this node is currently associated with
400 N.B. not always minor->master */ 402 N.B. not always minor->master */
403 struct list_head fbs;
401}; 404};
402 405
403/** Wait queue */ 406/** Wait queue */
@@ -629,6 +632,8 @@ struct drm_gem_object {
629 void *driver_private; 632 void *driver_private;
630}; 633};
631 634
635#include "drm_crtc.h"
636
632/* per-master structure */ 637/* per-master structure */
633struct drm_master { 638struct drm_master {
634 639
@@ -792,6 +797,8 @@ struct drm_driver {
792 797
793#define DRM_MINOR_UNASSIGNED 0 798#define DRM_MINOR_UNASSIGNED 0
794#define DRM_MINOR_LEGACY 1 799#define DRM_MINOR_LEGACY 1
800#define DRM_MINOR_CONTROL 2
801#define DRM_MINOR_RENDER 3
795 802
796/** 803/**
797 * DRM minor structure. This structure represents a drm minor number. 804 * DRM minor structure. This structure represents a drm minor number.
@@ -805,6 +812,7 @@ struct drm_minor {
805 struct proc_dir_entry *dev_root; /**< proc directory entry */ 812 struct proc_dir_entry *dev_root; /**< proc directory entry */
806 struct drm_master *master; /* currently active master for this node */ 813 struct drm_master *master; /* currently active master for this node */
807 struct list_head master_list; 814 struct list_head master_list;
815 struct drm_mode_group mode_group;
808}; 816};
809 817
810/** 818/**
@@ -855,6 +863,7 @@ struct drm_device {
855 struct idr ctx_idr; 863 struct idr ctx_idr;
856 864
857 struct list_head vmalist; /**< List of vmas (for debugging) */ 865 struct list_head vmalist; /**< List of vmas (for debugging) */
866
858 /*@} */ 867 /*@} */
859 868
860 /** \name DMA queues (contexts) */ 869 /** \name DMA queues (contexts) */
@@ -933,6 +942,7 @@ struct drm_device {
933 struct drm_driver *driver; 942 struct drm_driver *driver;
934 drm_local_map_t *agp_buffer_map; 943 drm_local_map_t *agp_buffer_map;
935 unsigned int agp_buffer_token; 944 unsigned int agp_buffer_token;
945 struct drm_minor *control; /**< Control node for card */
936 struct drm_minor *primary; /**< render type primary screen head */ 946 struct drm_minor *primary; /**< render type primary screen head */
937 947
938 /** \name Drawable information */ 948 /** \name Drawable information */
@@ -941,6 +951,8 @@ struct drm_device {
941 struct idr drw_idr; 951 struct idr drw_idr;
942 /*@} */ 952 /*@} */
943 953
954 struct drm_mode_config mode_config; /**< Current mode config */
955
944 /** \name GEM information */ 956 /** \name GEM information */
945 /*@{ */ 957 /*@{ */
946 spinlock_t object_name_lock; 958 spinlock_t object_name_lock;
@@ -1201,6 +1213,8 @@ extern int drm_vblank_get(struct drm_device *dev, int crtc);
1201extern void drm_vblank_put(struct drm_device *dev, int crtc); 1213extern void drm_vblank_put(struct drm_device *dev, int crtc);
1202extern void drm_vblank_cleanup(struct drm_device *dev); 1214extern void drm_vblank_cleanup(struct drm_device *dev);
1203/* Modesetting support */ 1215/* Modesetting support */
1216extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc);
1217extern void drm_vblank_post_modeset(struct drm_device *dev, int crtc);
1204extern int drm_modeset_ctl(struct drm_device *dev, void *data, 1218extern int drm_modeset_ctl(struct drm_device *dev, void *data,
1205 struct drm_file *file_priv); 1219 struct drm_file *file_priv);
1206 1220
@@ -1286,7 +1300,11 @@ struct drm_sysfs_class;
1286extern struct class *drm_sysfs_create(struct module *owner, char *name); 1300extern struct class *drm_sysfs_create(struct module *owner, char *name);
1287extern void drm_sysfs_destroy(void); 1301extern void drm_sysfs_destroy(void);
1288extern int drm_sysfs_device_add(struct drm_minor *minor); 1302extern int drm_sysfs_device_add(struct drm_minor *minor);
1303extern void drm_sysfs_hotplug_event(struct drm_device *dev);
1289extern void drm_sysfs_device_remove(struct drm_minor *minor); 1304extern void drm_sysfs_device_remove(struct drm_minor *minor);
1305extern char *drm_get_connector_status_name(enum drm_connector_status status);
1306extern int drm_sysfs_connector_add(struct drm_connector *connector);
1307extern void drm_sysfs_connector_remove(struct drm_connector *connector);
1290 1308
1291/* 1309/*
1292 * Basic memory manager support (drm_mm.c) 1310 * Basic memory manager support (drm_mm.c)
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
new file mode 100644
index 000000000000..08a884bea446
--- /dev/null
+++ b/include/drm/drm_crtc.h
@@ -0,0 +1,737 @@
1/*
2 * Copyright © 2006 Keith Packard
3 * Copyright © 2007-2008 Dave Airlie
4 * Copyright © 2007-2008 Intel Corporation
5 * Jesse Barnes <jesse.barnes@intel.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25#ifndef __DRM_CRTC_H__
26#define __DRM_CRTC_H__
27
28#include <linux/i2c.h>
29#include <linux/spinlock.h>
30#include <linux/types.h>
31#include <linux/idr.h>
32
33#include <linux/fb.h>
34
35struct drm_device;
36struct drm_mode_set;
37struct drm_framebuffer;
38
39
40#define DRM_MODE_OBJECT_CRTC 0xcccccccc
41#define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0
42#define DRM_MODE_OBJECT_ENCODER 0xe0e0e0e0
43#define DRM_MODE_OBJECT_MODE 0xdededede
44#define DRM_MODE_OBJECT_PROPERTY 0xb0b0b0b0
45#define DRM_MODE_OBJECT_FB 0xfbfbfbfb
46#define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb
47
48struct drm_mode_object {
49 uint32_t id;
50 uint32_t type;
51};
52
53/*
54 * Note on terminology: here, for brevity and convenience, we refer to connector
55 * control chips as 'CRTCs'. They can control any type of connector, VGA, LVDS,
56 * DVI, etc. And 'screen' refers to the whole of the visible display, which
57 * may span multiple monitors (and therefore multiple CRTC and connector
58 * structures).
59 */
60
61enum drm_mode_status {
62 MODE_OK = 0, /* Mode OK */
63 MODE_HSYNC, /* hsync out of range */
64 MODE_VSYNC, /* vsync out of range */
65 MODE_H_ILLEGAL, /* mode has illegal horizontal timings */
66 MODE_V_ILLEGAL, /* mode has illegal horizontal timings */
67 MODE_BAD_WIDTH, /* requires an unsupported linepitch */
68 MODE_NOMODE, /* no mode with a maching name */
69 MODE_NO_INTERLACE, /* interlaced mode not supported */
70 MODE_NO_DBLESCAN, /* doublescan mode not supported */
71 MODE_NO_VSCAN, /* multiscan mode not supported */
72 MODE_MEM, /* insufficient video memory */
73 MODE_VIRTUAL_X, /* mode width too large for specified virtual size */
74 MODE_VIRTUAL_Y, /* mode height too large for specified virtual size */
75 MODE_MEM_VIRT, /* insufficient video memory given virtual size */
76 MODE_NOCLOCK, /* no fixed clock available */
77 MODE_CLOCK_HIGH, /* clock required is too high */
78 MODE_CLOCK_LOW, /* clock required is too low */
79 MODE_CLOCK_RANGE, /* clock/mode isn't in a ClockRange */
80 MODE_BAD_HVALUE, /* horizontal timing was out of range */
81 MODE_BAD_VVALUE, /* vertical timing was out of range */
82 MODE_BAD_VSCAN, /* VScan value out of range */
83 MODE_HSYNC_NARROW, /* horizontal sync too narrow */
84 MODE_HSYNC_WIDE, /* horizontal sync too wide */
85 MODE_HBLANK_NARROW, /* horizontal blanking too narrow */
86 MODE_HBLANK_WIDE, /* horizontal blanking too wide */
87 MODE_VSYNC_NARROW, /* vertical sync too narrow */
88 MODE_VSYNC_WIDE, /* vertical sync too wide */
89 MODE_VBLANK_NARROW, /* vertical blanking too narrow */
90 MODE_VBLANK_WIDE, /* vertical blanking too wide */
91 MODE_PANEL, /* exceeds panel dimensions */
92 MODE_INTERLACE_WIDTH, /* width too large for interlaced mode */
93 MODE_ONE_WIDTH, /* only one width is supported */
94 MODE_ONE_HEIGHT, /* only one height is supported */
95 MODE_ONE_SIZE, /* only one resolution is supported */
96 MODE_NO_REDUCED, /* monitor doesn't accept reduced blanking */
97 MODE_UNVERIFIED = -3, /* mode needs to reverified */
98 MODE_BAD = -2, /* unspecified reason */
99 MODE_ERROR = -1 /* error condition */
100};
101
102#define DRM_MODE_TYPE_CLOCK_CRTC_C (DRM_MODE_TYPE_CLOCK_C | \
103 DRM_MODE_TYPE_CRTC_C)
104
105#define DRM_MODE(nm, t, c, hd, hss, hse, ht, hsk, vd, vss, vse, vt, vs, f) \
106 .name = nm, .status = 0, .type = (t), .clock = (c), \
107 .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \
108 .htotal = (ht), .hskew = (hsk), .vdisplay = (vd), \
109 .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \
110 .vscan = (vs), .flags = (f), .vrefresh = 0
111
112#define CRTC_INTERLACE_HALVE_V 0x1 /* halve V values for interlacing */
113
114struct drm_display_mode {
115 /* Header */
116 struct list_head head;
117 struct drm_mode_object base;
118
119 char name[DRM_DISPLAY_MODE_LEN];
120
121 int connector_count;
122 enum drm_mode_status status;
123 int type;
124
125 /* Proposed mode values */
126 int clock;
127 int hdisplay;
128 int hsync_start;
129 int hsync_end;
130 int htotal;
131 int hskew;
132 int vdisplay;
133 int vsync_start;
134 int vsync_end;
135 int vtotal;
136 int vscan;
137 unsigned int flags;
138
139 /* Addressable image size (may be 0 for projectors, etc.) */
140 int width_mm;
141 int height_mm;
142
143 /* Actual mode we give to hw */
144 int clock_index;
145 int synth_clock;
146 int crtc_hdisplay;
147 int crtc_hblank_start;
148 int crtc_hblank_end;
149 int crtc_hsync_start;
150 int crtc_hsync_end;
151 int crtc_htotal;
152 int crtc_hskew;
153 int crtc_vdisplay;
154 int crtc_vblank_start;
155 int crtc_vblank_end;
156 int crtc_vsync_start;
157 int crtc_vsync_end;
158 int crtc_vtotal;
159 int crtc_hadjusted;
160 int crtc_vadjusted;
161
162 /* Driver private mode info */
163 int private_size;
164 int *private;
165 int private_flags;
166
167 int vrefresh;
168 float hsync;
169};
170
171enum drm_connector_status {
172 connector_status_connected = 1,
173 connector_status_disconnected = 2,
174 connector_status_unknown = 3,
175};
176
177enum subpixel_order {
178 SubPixelUnknown = 0,
179 SubPixelHorizontalRGB,
180 SubPixelHorizontalBGR,
181 SubPixelVerticalRGB,
182 SubPixelVerticalBGR,
183 SubPixelNone,
184};
185
186
187/*
188 * Describes a given display (e.g. CRT or flat panel) and its limitations.
189 */
190struct drm_display_info {
191 char name[DRM_DISPLAY_INFO_LEN];
192 /* Input info */
193 bool serration_vsync;
194 bool sync_on_green;
195 bool composite_sync;
196 bool separate_syncs;
197 bool blank_to_black;
198 unsigned char video_level;
199 bool digital;
200 /* Physical size */
201 unsigned int width_mm;
202 unsigned int height_mm;
203
204 /* Display parameters */
205 unsigned char gamma; /* FIXME: storage format */
206 bool gtf_supported;
207 bool standard_color;
208 enum {
209 monochrome = 0,
210 rgb,
211 other,
212 unknown,
213 } display_type;
214 bool active_off_supported;
215 bool suspend_supported;
216 bool standby_supported;
217
218 /* Color info FIXME: storage format */
219 unsigned short redx, redy;
220 unsigned short greenx, greeny;
221 unsigned short bluex, bluey;
222 unsigned short whitex, whitey;
223
224 /* Clock limits FIXME: storage format */
225 unsigned int min_vfreq, max_vfreq;
226 unsigned int min_hfreq, max_hfreq;
227 unsigned int pixel_clock;
228
229 /* White point indices FIXME: storage format */
230 unsigned int wpx1, wpy1;
231 unsigned int wpgamma1;
232 unsigned int wpx2, wpy2;
233 unsigned int wpgamma2;
234
235 enum subpixel_order subpixel_order;
236
237 char *raw_edid; /* if any */
238};
239
240struct drm_framebuffer_funcs {
241 void (*destroy)(struct drm_framebuffer *framebuffer);
242 int (*create_handle)(struct drm_framebuffer *fb,
243 struct drm_file *file_priv,
244 unsigned int *handle);
245};
246
247struct drm_framebuffer {
248 struct drm_device *dev;
249 struct list_head head;
250 struct drm_mode_object base;
251 const struct drm_framebuffer_funcs *funcs;
252 unsigned int pitch;
253 unsigned int width;
254 unsigned int height;
255 /* depth can be 15 or 16 */
256 unsigned int depth;
257 int bits_per_pixel;
258 int flags;
259 void *fbdev;
260 u32 pseudo_palette[17];
261 struct list_head filp_head;
262};
263
264struct drm_property_blob {
265 struct drm_mode_object base;
266 struct list_head head;
267 unsigned int length;
268 void *data;
269};
270
271struct drm_property_enum {
272 uint64_t value;
273 struct list_head head;
274 char name[DRM_PROP_NAME_LEN];
275};
276
277struct drm_property {
278 struct list_head head;
279 struct drm_mode_object base;
280 uint32_t flags;
281 char name[DRM_PROP_NAME_LEN];
282 uint32_t num_values;
283 uint64_t *values;
284
285 struct list_head enum_blob_list;
286};
287
288struct drm_crtc;
289struct drm_connector;
290struct drm_encoder;
291
292/**
293 * drm_crtc_funcs - control CRTCs for a given device
294 * @dpms: control display power levels
295 * @save: save CRTC state
296 * @resore: restore CRTC state
297 * @lock: lock the CRTC
298 * @unlock: unlock the CRTC
299 * @shadow_allocate: allocate shadow pixmap
300 * @shadow_create: create shadow pixmap for rotation support
301 * @shadow_destroy: free shadow pixmap
302 * @mode_fixup: fixup proposed mode
303 * @mode_set: set the desired mode on the CRTC
304 * @gamma_set: specify color ramp for CRTC
305 * @destroy: deinit and free object.
306 *
307 * The drm_crtc_funcs structure is the central CRTC management structure
308 * in the DRM. Each CRTC controls one or more connectors (note that the name
309 * CRTC is simply historical, a CRTC may control LVDS, VGA, DVI, TV out, etc.
310 * connectors, not just CRTs).
311 *
312 * Each driver is responsible for filling out this structure at startup time,
313 * in addition to providing other modesetting features, like i2c and DDC
314 * bus accessors.
315 */
316struct drm_crtc_funcs {
317 /* Save CRTC state */
318 void (*save)(struct drm_crtc *crtc); /* suspend? */
319 /* Restore CRTC state */
320 void (*restore)(struct drm_crtc *crtc); /* resume? */
321
322 /* cursor controls */
323 int (*cursor_set)(struct drm_crtc *crtc, struct drm_file *file_priv,
324 uint32_t handle, uint32_t width, uint32_t height);
325 int (*cursor_move)(struct drm_crtc *crtc, int x, int y);
326
327 /* Set gamma on the CRTC */
328 void (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
329 uint32_t size);
330 /* Object destroy routine */
331 void (*destroy)(struct drm_crtc *crtc);
332
333 int (*set_config)(struct drm_mode_set *set);
334};
335
336/**
337 * drm_crtc - central CRTC control structure
338 * @enabled: is this CRTC enabled?
339 * @x: x position on screen
340 * @y: y position on screen
341 * @desired_mode: new desired mode
342 * @desired_x: desired x for desired_mode
343 * @desired_y: desired y for desired_mode
344 * @funcs: CRTC control functions
345 *
346 * Each CRTC may have one or more connectors associated with it. This structure
347 * allows the CRTC to be controlled.
348 */
349struct drm_crtc {
350 struct drm_device *dev;
351 struct list_head head;
352
353 struct drm_mode_object base;
354
355 /* framebuffer the connector is currently bound to */
356 struct drm_framebuffer *fb;
357
358 bool enabled;
359
360 struct drm_display_mode mode;
361
362 int x, y;
363 struct drm_display_mode *desired_mode;
364 int desired_x, desired_y;
365 const struct drm_crtc_funcs *funcs;
366
367 /* CRTC gamma size for reporting to userspace */
368 uint32_t gamma_size;
369 uint16_t *gamma_store;
370
371 /* if you are using the helper */
372 void *helper_private;
373};
374
375
376/**
377 * drm_connector_funcs - control connectors on a given device
378 * @dpms: set power state (see drm_crtc_funcs above)
379 * @save: save connector state
380 * @restore: restore connector state
381 * @mode_valid: is this mode valid on the given connector?
382 * @mode_fixup: try to fixup proposed mode for this connector
383 * @mode_set: set this mode
384 * @detect: is this connector active?
385 * @get_modes: get mode list for this connector
386 * @set_property: property for this connector may need update
387 * @destroy: make object go away
388 *
389 * Each CRTC may have one or more connectors attached to it. The functions
390 * below allow the core DRM code to control connectors, enumerate available modes,
391 * etc.
392 */
393struct drm_connector_funcs {
394 void (*dpms)(struct drm_connector *connector, int mode);
395 void (*save)(struct drm_connector *connector);
396 void (*restore)(struct drm_connector *connector);
397 enum drm_connector_status (*detect)(struct drm_connector *connector);
398 void (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height);
399 int (*set_property)(struct drm_connector *connector, struct drm_property *property,
400 uint64_t val);
401 void (*destroy)(struct drm_connector *connector);
402};
403
404struct drm_encoder_funcs {
405 void (*destroy)(struct drm_encoder *encoder);
406};
407
408#define DRM_CONNECTOR_MAX_UMODES 16
409#define DRM_CONNECTOR_MAX_PROPERTY 16
410#define DRM_CONNECTOR_LEN 32
411#define DRM_CONNECTOR_MAX_ENCODER 2
412
413/**
414 * drm_encoder - central DRM encoder structure
415 */
416struct drm_encoder {
417 struct drm_device *dev;
418 struct list_head head;
419
420 struct drm_mode_object base;
421 int encoder_type;
422 uint32_t possible_crtcs;
423 uint32_t possible_clones;
424
425 struct drm_crtc *crtc;
426 const struct drm_encoder_funcs *funcs;
427 void *helper_private;
428};
429
430/**
431 * drm_connector - central DRM connector control structure
432 * @crtc: CRTC this connector is currently connected to, NULL if none
433 * @interlace_allowed: can this connector handle interlaced modes?
434 * @doublescan_allowed: can this connector handle doublescan?
435 * @available_modes: modes available on this connector (from get_modes() + user)
436 * @initial_x: initial x position for this connector
437 * @initial_y: initial y position for this connector
438 * @status: connector connected?
439 * @funcs: connector control functions
440 *
441 * Each connector may be connected to one or more CRTCs, or may be clonable by
442 * another connector if they can share a CRTC. Each connector also has a specific
443 * position in the broader display (referred to as a 'screen' though it could
444 * span multiple monitors).
445 */
446struct drm_connector {
447 struct drm_device *dev;
448 struct device kdev;
449 struct device_attribute *attr;
450 struct list_head head;
451
452 struct drm_mode_object base;
453
454 int connector_type;
455 int connector_type_id;
456 bool interlace_allowed;
457 bool doublescan_allowed;
458 struct list_head modes; /* list of modes on this connector */
459
460 int initial_x, initial_y;
461 enum drm_connector_status status;
462
463 /* these are modes added by probing with DDC or the BIOS */
464 struct list_head probed_modes;
465
466 struct drm_display_info display_info;
467 const struct drm_connector_funcs *funcs;
468
469 struct list_head user_modes;
470 struct drm_property_blob *edid_blob_ptr;
471 u32 property_ids[DRM_CONNECTOR_MAX_PROPERTY];
472 uint64_t property_values[DRM_CONNECTOR_MAX_PROPERTY];
473
474 void *helper_private;
475
476 uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
477 uint32_t force_encoder_id;
478 struct drm_encoder *encoder; /* currently active encoder */
479};
480
481/**
482 * struct drm_mode_set
483 *
484 * Represents a single crtc the connectors that it drives with what mode
485 * and from which framebuffer it scans out from.
486 *
487 * This is used to set modes.
488 */
489struct drm_mode_set {
490 struct list_head head;
491
492 struct drm_framebuffer *fb;
493 struct drm_crtc *crtc;
494 struct drm_display_mode *mode;
495
496 uint32_t x;
497 uint32_t y;
498
499 struct drm_connector **connectors;
500 size_t num_connectors;
501};
502
503/**
504 * struct drm_mode_config_funcs - configure CRTCs for a given screen layout
505 * @resize: adjust CRTCs as necessary for the proposed layout
506 *
507 * Currently only a resize hook is available. DRM will call back into the
508 * driver with a new screen width and height. If the driver can't support
509 * the proposed size, it can return false. Otherwise it should adjust
510 * the CRTC<->connector mappings as needed and update its view of the screen.
511 */
512struct drm_mode_config_funcs {
513 int (*resize_fb)(struct drm_device *dev, struct drm_file *file_priv, struct drm_framebuffer *fb, struct drm_mode_fb_cmd *mode_cmd);
514 struct drm_framebuffer *(*fb_create)(struct drm_device *dev, struct drm_file *file_priv, struct drm_mode_fb_cmd *mode_cmd);
515 int (*fb_changed)(struct drm_device *dev);
516};
517
518struct drm_mode_group {
519 uint32_t num_crtcs;
520 uint32_t num_encoders;
521 uint32_t num_connectors;
522
523 /* list of object IDs for this group */
524 uint32_t *id_list;
525};
526
527/**
528 * drm_mode_config - Mode configuration control structure
529 *
530 */
531struct drm_mode_config {
532 struct mutex mutex; /* protects configuration and IDR */
533 struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */
534 /* this is limited to one for now */
535 int num_fb;
536 struct list_head fb_list;
537 int num_connector;
538 struct list_head connector_list;
539 int num_encoder;
540 struct list_head encoder_list;
541
542 int num_crtc;
543 struct list_head crtc_list;
544
545 struct list_head property_list;
546
547 /* in-kernel framebuffers - hung of filp_head in drm_framebuffer */
548 struct list_head fb_kernel_list;
549
550 int min_width, min_height;
551 int max_width, max_height;
552 struct drm_mode_config_funcs *funcs;
553 unsigned long fb_base;
554
555 /* pointers to standard properties */
556 struct list_head property_blob_list;
557 struct drm_property *edid_property;
558 struct drm_property *dpms_property;
559
560 /* DVI-I properties */
561 struct drm_property *dvi_i_subconnector_property;
562 struct drm_property *dvi_i_select_subconnector_property;
563
564 /* TV properties */
565 struct drm_property *tv_subconnector_property;
566 struct drm_property *tv_select_subconnector_property;
567 struct drm_property *tv_mode_property;
568 struct drm_property *tv_left_margin_property;
569 struct drm_property *tv_right_margin_property;
570 struct drm_property *tv_top_margin_property;
571 struct drm_property *tv_bottom_margin_property;
572
573 /* Optional properties */
574 struct drm_property *scaling_mode_property;
575 struct drm_property *dithering_mode_property;
576
577 /* hotplug */
578 uint32_t hotplug_counter;
579};
580
581#define obj_to_crtc(x) container_of(x, struct drm_crtc, base)
582#define obj_to_connector(x) container_of(x, struct drm_connector, base)
583#define obj_to_encoder(x) container_of(x, struct drm_encoder, base)
584#define obj_to_mode(x) container_of(x, struct drm_display_mode, base)
585#define obj_to_fb(x) container_of(x, struct drm_framebuffer, base)
586#define obj_to_property(x) container_of(x, struct drm_property, base)
587#define obj_to_blob(x) container_of(x, struct drm_property_blob, base)
588
589
590extern void drm_crtc_init(struct drm_device *dev,
591 struct drm_crtc *crtc,
592 const struct drm_crtc_funcs *funcs);
593extern void drm_crtc_cleanup(struct drm_crtc *crtc);
594
595extern void drm_connector_init(struct drm_device *dev,
596 struct drm_connector *connector,
597 const struct drm_connector_funcs *funcs,
598 int connector_type);
599
600extern void drm_connector_cleanup(struct drm_connector *connector);
601
602extern void drm_encoder_init(struct drm_device *dev,
603 struct drm_encoder *encoder,
604 const struct drm_encoder_funcs *funcs,
605 int encoder_type);
606
607extern void drm_encoder_cleanup(struct drm_encoder *encoder);
608
609extern char *drm_get_connector_name(struct drm_connector *connector);
610extern char *drm_get_dpms_name(int val);
611extern char *drm_get_dvi_i_subconnector_name(int val);
612extern char *drm_get_dvi_i_select_name(int val);
613extern char *drm_get_tv_subconnector_name(int val);
614extern char *drm_get_tv_select_name(int val);
615extern void drm_fb_release(struct file *filp);
616extern int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_group *group);
617extern struct edid *drm_get_edid(struct drm_connector *connector,
618 struct i2c_adapter *adapter);
619extern unsigned char *drm_do_probe_ddc_edid(struct i2c_adapter *adapter);
620extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid);
621extern void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode);
622extern void drm_mode_remove(struct drm_connector *connector, struct drm_display_mode *mode);
623extern struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
624 struct drm_display_mode *mode);
625extern void drm_mode_debug_printmodeline(struct drm_display_mode *mode);
626extern void drm_mode_config_init(struct drm_device *dev);
627extern void drm_mode_config_cleanup(struct drm_device *dev);
628extern void drm_mode_set_name(struct drm_display_mode *mode);
629extern bool drm_mode_equal(struct drm_display_mode *mode1, struct drm_display_mode *mode2);
630extern int drm_mode_width(struct drm_display_mode *mode);
631extern int drm_mode_height(struct drm_display_mode *mode);
632
633/* for us by fb module */
634extern int drm_mode_attachmode_crtc(struct drm_device *dev,
635 struct drm_crtc *crtc,
636 struct drm_display_mode *mode);
637extern int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode);
638
639extern struct drm_display_mode *drm_mode_create(struct drm_device *dev);
640extern void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode);
641extern void drm_mode_list_concat(struct list_head *head,
642 struct list_head *new);
643extern void drm_mode_validate_size(struct drm_device *dev,
644 struct list_head *mode_list,
645 int maxX, int maxY, int maxPitch);
646extern void drm_mode_prune_invalid(struct drm_device *dev,
647 struct list_head *mode_list, bool verbose);
648extern void drm_mode_sort(struct list_head *mode_list);
649extern int drm_mode_vrefresh(struct drm_display_mode *mode);
650extern void drm_mode_set_crtcinfo(struct drm_display_mode *p,
651 int adjust_flags);
652extern void drm_mode_connector_list_update(struct drm_connector *connector);
653extern int drm_mode_connector_update_edid_property(struct drm_connector *connector,
654 struct edid *edid);
655extern int drm_connector_property_set_value(struct drm_connector *connector,
656 struct drm_property *property,
657 uint64_t value);
658extern int drm_connector_property_get_value(struct drm_connector *connector,
659 struct drm_property *property,
660 uint64_t *value);
661extern struct drm_display_mode *drm_crtc_mode_create(struct drm_device *dev);
662extern void drm_framebuffer_set_object(struct drm_device *dev,
663 unsigned long handle);
664extern int drm_framebuffer_init(struct drm_device *dev,
665 struct drm_framebuffer *fb,
666 const struct drm_framebuffer_funcs *funcs);
667extern void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
668extern int drmfb_probe(struct drm_device *dev, struct drm_crtc *crtc);
669extern int drmfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
670extern void drm_crtc_probe_connector_modes(struct drm_device *dev, int maxX, int maxY);
671extern bool drm_crtc_in_use(struct drm_crtc *crtc);
672
673extern int drm_connector_attach_property(struct drm_connector *connector,
674 struct drm_property *property, uint64_t init_val);
675extern struct drm_property *drm_property_create(struct drm_device *dev, int flags,
676 const char *name, int num_values);
677extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property);
678extern int drm_property_add_enum(struct drm_property *property, int index,
679 uint64_t value, const char *name);
680extern int drm_mode_create_dvi_i_properties(struct drm_device *dev);
681extern int drm_mode_create_tv_properties(struct drm_device *dev, int num_formats,
682 char *formats[]);
683extern int drm_mode_create_scaling_mode_property(struct drm_device *dev);
684extern int drm_mode_create_dithering_property(struct drm_device *dev);
685extern char *drm_get_encoder_name(struct drm_encoder *encoder);
686
687extern int drm_mode_connector_attach_encoder(struct drm_connector *connector,
688 struct drm_encoder *encoder);
689extern void drm_mode_connector_detach_encoder(struct drm_connector *connector,
690 struct drm_encoder *encoder);
691extern bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
692 int gamma_size);
693extern void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type);
694/* IOCTLs */
695extern int drm_mode_getresources(struct drm_device *dev,
696 void *data, struct drm_file *file_priv);
697
698extern int drm_mode_getcrtc(struct drm_device *dev,
699 void *data, struct drm_file *file_priv);
700extern int drm_mode_getconnector(struct drm_device *dev,
701 void *data, struct drm_file *file_priv);
702extern int drm_mode_setcrtc(struct drm_device *dev,
703 void *data, struct drm_file *file_priv);
704extern int drm_mode_cursor_ioctl(struct drm_device *dev,
705 void *data, struct drm_file *file_priv);
706extern int drm_mode_addfb(struct drm_device *dev,
707 void *data, struct drm_file *file_priv);
708extern int drm_mode_rmfb(struct drm_device *dev,
709 void *data, struct drm_file *file_priv);
710extern int drm_mode_getfb(struct drm_device *dev,
711 void *data, struct drm_file *file_priv);
712extern int drm_mode_addmode_ioctl(struct drm_device *dev,
713 void *data, struct drm_file *file_priv);
714extern int drm_mode_rmmode_ioctl(struct drm_device *dev,
715 void *data, struct drm_file *file_priv);
716extern int drm_mode_attachmode_ioctl(struct drm_device *dev,
717 void *data, struct drm_file *file_priv);
718extern int drm_mode_detachmode_ioctl(struct drm_device *dev,
719 void *data, struct drm_file *file_priv);
720
721extern int drm_mode_getproperty_ioctl(struct drm_device *dev,
722 void *data, struct drm_file *file_priv);
723extern int drm_mode_getblob_ioctl(struct drm_device *dev,
724 void *data, struct drm_file *file_priv);
725extern int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
726 void *data, struct drm_file *file_priv);
727extern int drm_mode_hotplug_ioctl(struct drm_device *dev,
728 void *data, struct drm_file *file_priv);
729extern int drm_mode_replacefb(struct drm_device *dev,
730 void *data, struct drm_file *file_priv);
731extern int drm_mode_getencoder(struct drm_device *dev,
732 void *data, struct drm_file *file_priv);
733extern int drm_mode_gamma_get_ioctl(struct drm_device *dev,
734 void *data, struct drm_file *file_priv);
735extern int drm_mode_gamma_set_ioctl(struct drm_device *dev,
736 void *data, struct drm_file *file_priv);
737#endif /* __DRM_CRTC_H__ */
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
new file mode 100644
index 000000000000..a341828d1d15
--- /dev/null
+++ b/include/drm/drm_crtc_helper.h
@@ -0,0 +1,121 @@
1/*
2 * Copyright © 2006 Keith Packard
3 * Copyright © 2007-2008 Dave Airlie
4 * Copyright © 2007-2008 Intel Corporation
5 * Jesse Barnes <jesse.barnes@intel.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26/*
27 * The DRM mode setting helper functions are common code for drivers to use if
28 * they wish. Drivers are not forced to use this code in their
29 * implementations but it would be useful if they code they do use at least
30 * provides a consistent interface and operation to userspace
31 */
32
33#ifndef __DRM_CRTC_HELPER_H__
34#define __DRM_CRTC_HELPER_H__
35
36#include <linux/i2c.h>
37#include <linux/spinlock.h>
38#include <linux/types.h>
39#include <linux/idr.h>
40
41#include <linux/fb.h>
42
43struct drm_crtc_helper_funcs {
44 /*
45 * Control power levels on the CRTC. If the mode passed in is
46 * unsupported, the provider must use the next lowest power level.
47 */
48 void (*dpms)(struct drm_crtc *crtc, int mode);
49 void (*prepare)(struct drm_crtc *crtc);
50 void (*commit)(struct drm_crtc *crtc);
51
52 /* Provider can fixup or change mode timings before modeset occurs */
53 bool (*mode_fixup)(struct drm_crtc *crtc,
54 struct drm_display_mode *mode,
55 struct drm_display_mode *adjusted_mode);
56 /* Actually set the mode */
57 void (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode,
58 struct drm_display_mode *adjusted_mode, int x, int y);
59
60 /* Move the crtc on the current fb to the given position *optional* */
61 void (*mode_set_base)(struct drm_crtc *crtc, int x, int y);
62};
63
64struct drm_encoder_helper_funcs {
65 void (*dpms)(struct drm_encoder *encoder, int mode);
66 void (*save)(struct drm_encoder *encoder);
67 void (*restore)(struct drm_encoder *encoder);
68
69 bool (*mode_fixup)(struct drm_encoder *encoder,
70 struct drm_display_mode *mode,
71 struct drm_display_mode *adjusted_mode);
72 void (*prepare)(struct drm_encoder *encoder);
73 void (*commit)(struct drm_encoder *encoder);
74 void (*mode_set)(struct drm_encoder *encoder,
75 struct drm_display_mode *mode,
76 struct drm_display_mode *adjusted_mode);
77 /* detect for DAC style encoders */
78 enum drm_connector_status (*detect)(struct drm_encoder *encoder,
79 struct drm_connector *connector);
80};
81
82struct drm_connector_helper_funcs {
83 int (*get_modes)(struct drm_connector *connector);
84 int (*mode_valid)(struct drm_connector *connector,
85 struct drm_display_mode *mode);
86 struct drm_encoder *(*best_encoder)(struct drm_connector *connector);
87};
88
89extern void drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY);
90extern void drm_helper_disable_unused_functions(struct drm_device *dev);
91extern int drm_helper_hotplug_stage_two(struct drm_device *dev);
92extern bool drm_helper_initial_config(struct drm_device *dev, bool can_grow);
93extern int drm_crtc_helper_set_config(struct drm_mode_set *set);
94extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
95 struct drm_display_mode *mode,
96 int x, int y);
97extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc);
98
99extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
100 struct drm_mode_fb_cmd *mode_cmd);
101
102static inline void drm_crtc_helper_add(struct drm_crtc *crtc,
103 const struct drm_crtc_helper_funcs *funcs)
104{
105 crtc->helper_private = (void *)funcs;
106}
107
108static inline void drm_encoder_helper_add(struct drm_encoder *encoder,
109 const struct drm_encoder_helper_funcs *funcs)
110{
111 encoder->helper_private = (void *)funcs;
112}
113
114static inline void drm_connector_helper_add(struct drm_connector *connector,
115 const struct drm_connector_helper_funcs *funcs)
116{
117 connector->helper_private = (void *)funcs;
118}
119
120extern int drm_helper_resume_force_mode(struct drm_device *dev);
121#endif
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
new file mode 100644
index 000000000000..c707c15f5164
--- /dev/null
+++ b/include/drm/drm_edid.h
@@ -0,0 +1,202 @@
1/*
2 * Copyright © 2007-2008 Intel Corporation
3 * Jesse Barnes <jesse.barnes@intel.com>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 */
23#ifndef __DRM_EDID_H__
24#define __DRM_EDID_H__
25
26#include <linux/types.h>
27
28#define EDID_LENGTH 128
29#define DDC_ADDR 0x50
30
31#ifdef BIG_ENDIAN
32#error "EDID structure is little endian, need big endian versions"
33#else
34
35struct est_timings {
36 u8 t1;
37 u8 t2;
38 u8 mfg_rsvd;
39} __attribute__((packed));
40
41struct std_timing {
42 u8 hsize; /* need to multiply by 8 then add 248 */
43 u8 vfreq:6; /* need to add 60 */
44 u8 aspect_ratio:2; /* 00=16:10, 01=4:3, 10=5:4, 11=16:9 */
45} __attribute__((packed));
46
47/* If detailed data is pixel timing */
48struct detailed_pixel_timing {
49 u8 hactive_lo;
50 u8 hblank_lo;
51 u8 hblank_hi:4;
52 u8 hactive_hi:4;
53 u8 vactive_lo;
54 u8 vblank_lo;
55 u8 vblank_hi:4;
56 u8 vactive_hi:4;
57 u8 hsync_offset_lo;
58 u8 hsync_pulse_width_lo;
59 u8 vsync_pulse_width_lo:4;
60 u8 vsync_offset_lo:4;
61 u8 hsync_pulse_width_hi:2;
62 u8 hsync_offset_hi:2;
63 u8 vsync_pulse_width_hi:2;
64 u8 vsync_offset_hi:2;
65 u8 width_mm_lo;
66 u8 height_mm_lo;
67 u8 height_mm_hi:4;
68 u8 width_mm_hi:4;
69 u8 hborder;
70 u8 vborder;
71 u8 unknown0:1;
72 u8 vsync_positive:1;
73 u8 hsync_positive:1;
74 u8 separate_sync:2;
75 u8 stereo:1;
76 u8 unknown6:1;
77 u8 interlaced:1;
78} __attribute__((packed));
79
80/* If it's not pixel timing, it'll be one of the below */
81struct detailed_data_string {
82 u8 str[13];
83} __attribute__((packed));
84
85struct detailed_data_monitor_range {
86 u8 min_vfreq;
87 u8 max_vfreq;
88 u8 min_hfreq_khz;
89 u8 max_hfreq_khz;
90 u8 pixel_clock_mhz; /* need to multiply by 10 */
91 u16 sec_gtf_toggle; /* A000=use above, 20=use below */ /* FIXME: byte order */
92 u8 hfreq_start_khz; /* need to multiply by 2 */
93 u8 c; /* need to divide by 2 */
94 u16 m; /* FIXME: byte order */
95 u8 k;
96 u8 j; /* need to divide by 2 */
97} __attribute__((packed));
98
99struct detailed_data_wpindex {
100 u8 white_y_lo:2;
101 u8 white_x_lo:2;
102 u8 pad:4;
103 u8 white_x_hi;
104 u8 white_y_hi;
105 u8 gamma; /* need to divide by 100 then add 1 */
106} __attribute__((packed));
107
108struct detailed_data_color_point {
109 u8 windex1;
110 u8 wpindex1[3];
111 u8 windex2;
112 u8 wpindex2[3];
113} __attribute__((packed));
114
115struct detailed_non_pixel {
116 u8 pad1;
117 u8 type; /* ff=serial, fe=string, fd=monitor range, fc=monitor name
118 fb=color point data, fa=standard timing data,
119 f9=undefined, f8=mfg. reserved */
120 u8 pad2;
121 union {
122 struct detailed_data_string str;
123 struct detailed_data_monitor_range range;
124 struct detailed_data_wpindex color;
125 struct std_timing timings[5];
126 } data;
127} __attribute__((packed));
128
129#define EDID_DETAIL_STD_MODES 0xfa
130#define EDID_DETAIL_MONITOR_CPDATA 0xfb
131#define EDID_DETAIL_MONITOR_NAME 0xfc
132#define EDID_DETAIL_MONITOR_RANGE 0xfd
133#define EDID_DETAIL_MONITOR_STRING 0xfe
134#define EDID_DETAIL_MONITOR_SERIAL 0xff
135
136struct detailed_timing {
137 u16 pixel_clock; /* need to multiply by 10 KHz */ /* FIXME: byte order */
138 union {
139 struct detailed_pixel_timing pixel_data;
140 struct detailed_non_pixel other_data;
141 } data;
142} __attribute__((packed));
143
144struct edid {
145 u8 header[8];
146 /* Vendor & product info */
147 u8 mfg_id[2];
148 u8 prod_code[2];
149 u32 serial; /* FIXME: byte order */
150 u8 mfg_week;
151 u8 mfg_year;
152 /* EDID version */
153 u8 version;
154 u8 revision;
155 /* Display info: */
156 /* input definition */
157 u8 serration_vsync:1;
158 u8 sync_on_green:1;
159 u8 composite_sync:1;
160 u8 separate_syncs:1;
161 u8 blank_to_black:1;
162 u8 video_level:2;
163 u8 digital:1; /* bits below must be zero if set */
164 u8 width_cm;
165 u8 height_cm;
166 u8 gamma;
167 /* feature support */
168 u8 default_gtf:1;
169 u8 preferred_timing:1;
170 u8 standard_color:1;
171 u8 display_type:2; /* 00=mono, 01=rgb, 10=non-rgb, 11=unknown */
172 u8 pm_active_off:1;
173 u8 pm_suspend:1;
174 u8 pm_standby:1;
175 /* Color characteristics */
176 u8 red_green_lo;
177 u8 black_white_lo;
178 u8 red_x;
179 u8 red_y;
180 u8 green_x;
181 u8 green_y;
182 u8 blue_x;
183 u8 blue_y;
184 u8 white_x;
185 u8 white_y;
186 /* Est. timings and mfg rsvd timings*/
187 struct est_timings established_timings;
188 /* Standard timings 1-8*/
189 struct std_timing standard_timings[8];
190 /* Detailing timings 1-4 */
191 struct detailed_timing detailed_timings[4];
192 /* Number of 128 byte ext. blocks */
193 u8 extensions;
194 /* Checksum */
195 u8 checksum;
196} __attribute__((packed));
197
198#endif /* little endian structs */
199
200#define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8))
201
202#endif /* __DRM_EDID_H__ */
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
new file mode 100644
index 000000000000..d2e791920aba
--- /dev/null
+++ b/include/drm/drm_mode.h
@@ -0,0 +1,278 @@
1/*
2 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
3 * Copyright (c) 2007 Jakob Bornecrantz <wallbraker@gmail.com>
4 * Copyright (c) 2008 Red Hat Inc.
5 * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
6 * Copyright (c) 2007-2008 Intel Corporation
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 * IN THE SOFTWARE.
25 */
26
27#ifndef _DRM_MODE_H
28#define _DRM_MODE_H
29
30#if !defined(__KERNEL__) && !defined(_KERNEL)
31#include <stdint.h>
32#else
33#include <linux/kernel.h>
34#endif
35
36#define DRM_DISPLAY_INFO_LEN 32
37#define DRM_CONNECTOR_NAME_LEN 32
38#define DRM_DISPLAY_MODE_LEN 32
39#define DRM_PROP_NAME_LEN 32
40
41#define DRM_MODE_TYPE_BUILTIN (1<<0)
42#define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN)
43#define DRM_MODE_TYPE_CRTC_C ((1<<2) | DRM_MODE_TYPE_BUILTIN)
44#define DRM_MODE_TYPE_PREFERRED (1<<3)
45#define DRM_MODE_TYPE_DEFAULT (1<<4)
46#define DRM_MODE_TYPE_USERDEF (1<<5)
47#define DRM_MODE_TYPE_DRIVER (1<<6)
48
49/* Video mode flags */
50/* bit compatible with the xorg definitions. */
51#define DRM_MODE_FLAG_PHSYNC (1<<0)
52#define DRM_MODE_FLAG_NHSYNC (1<<1)
53#define DRM_MODE_FLAG_PVSYNC (1<<2)
54#define DRM_MODE_FLAG_NVSYNC (1<<3)
55#define DRM_MODE_FLAG_INTERLACE (1<<4)
56#define DRM_MODE_FLAG_DBLSCAN (1<<5)
57#define DRM_MODE_FLAG_CSYNC (1<<6)
58#define DRM_MODE_FLAG_PCSYNC (1<<7)
59#define DRM_MODE_FLAG_NCSYNC (1<<8)
60#define DRM_MODE_FLAG_HSKEW (1<<9) /* hskew provided */
61#define DRM_MODE_FLAG_BCAST (1<<10)
62#define DRM_MODE_FLAG_PIXMUX (1<<11)
63#define DRM_MODE_FLAG_DBLCLK (1<<12)
64#define DRM_MODE_FLAG_CLKDIV2 (1<<13)
65
66/* DPMS flags */
67/* bit compatible with the xorg definitions. */
68#define DRM_MODE_DPMS_ON 0
69#define DRM_MODE_DPMS_STANDBY 1
70#define DRM_MODE_DPMS_SUSPEND 2
71#define DRM_MODE_DPMS_OFF 3
72
73/* Scaling mode options */
74#define DRM_MODE_SCALE_NON_GPU 0
75#define DRM_MODE_SCALE_FULLSCREEN 1
76#define DRM_MODE_SCALE_NO_SCALE 2
77#define DRM_MODE_SCALE_ASPECT 3
78
79/* Dithering mode options */
80#define DRM_MODE_DITHERING_OFF 0
81#define DRM_MODE_DITHERING_ON 1
82
83struct drm_mode_modeinfo {
84 unsigned int clock;
85 unsigned short hdisplay, hsync_start, hsync_end, htotal, hskew;
86 unsigned short vdisplay, vsync_start, vsync_end, vtotal, vscan;
87
88 unsigned int vrefresh; /* vertical refresh * 1000 */
89
90 unsigned int flags;
91 unsigned int type;
92 char name[DRM_DISPLAY_MODE_LEN];
93};
94
95struct drm_mode_card_res {
96 uint64_t fb_id_ptr;
97 uint64_t crtc_id_ptr;
98 uint64_t connector_id_ptr;
99 uint64_t encoder_id_ptr;
100 int count_fbs;
101 int count_crtcs;
102 int count_connectors;
103 int count_encoders;
104 int min_width, max_width;
105 int min_height, max_height;
106};
107
108struct drm_mode_crtc {
109 uint64_t set_connectors_ptr;
110 int count_connectors;
111
112 unsigned int crtc_id; /**< Id */
113 unsigned int fb_id; /**< Id of framebuffer */
114
115 int x, y; /**< Position on the frameuffer */
116
117 uint32_t gamma_size;
118 int mode_valid;
119 struct drm_mode_modeinfo mode;
120};
121
122#define DRM_MODE_ENCODER_NONE 0
123#define DRM_MODE_ENCODER_DAC 1
124#define DRM_MODE_ENCODER_TMDS 2
125#define DRM_MODE_ENCODER_LVDS 3
126#define DRM_MODE_ENCODER_TVDAC 4
127
128struct drm_mode_get_encoder {
129 unsigned int encoder_id;
130 unsigned int encoder_type;
131
132 unsigned int crtc_id; /**< Id of crtc */
133
134 uint32_t possible_crtcs;
135 uint32_t possible_clones;
136};
137
138/* This is for connectors with multiple signal types. */
139/* Try to match DRM_MODE_CONNECTOR_X as closely as possible. */
140#define DRM_MODE_SUBCONNECTOR_Automatic 0
141#define DRM_MODE_SUBCONNECTOR_Unknown 0
142#define DRM_MODE_SUBCONNECTOR_DVID 3
143#define DRM_MODE_SUBCONNECTOR_DVIA 4
144#define DRM_MODE_SUBCONNECTOR_Composite 5
145#define DRM_MODE_SUBCONNECTOR_SVIDEO 6
146#define DRM_MODE_SUBCONNECTOR_Component 8
147
148#define DRM_MODE_CONNECTOR_Unknown 0
149#define DRM_MODE_CONNECTOR_VGA 1
150#define DRM_MODE_CONNECTOR_DVII 2
151#define DRM_MODE_CONNECTOR_DVID 3
152#define DRM_MODE_CONNECTOR_DVIA 4
153#define DRM_MODE_CONNECTOR_Composite 5
154#define DRM_MODE_CONNECTOR_SVIDEO 6
155#define DRM_MODE_CONNECTOR_LVDS 7
156#define DRM_MODE_CONNECTOR_Component 8
157#define DRM_MODE_CONNECTOR_9PinDIN 9
158#define DRM_MODE_CONNECTOR_DisplayPort 10
159#define DRM_MODE_CONNECTOR_HDMIA 11
160#define DRM_MODE_CONNECTOR_HDMIB 12
161
162struct drm_mode_get_connector {
163
164 uint64_t encoders_ptr;
165 uint64_t modes_ptr;
166 uint64_t props_ptr;
167 uint64_t prop_values_ptr;
168
169 int count_modes;
170 int count_props;
171 int count_encoders;
172
173 unsigned int encoder_id; /**< Current Encoder */
174 unsigned int connector_id; /**< Id */
175 unsigned int connector_type;
176 unsigned int connector_type_id;
177
178 unsigned int connection;
179 unsigned int mm_width, mm_height; /**< HxW in millimeters */
180 unsigned int subpixel;
181};
182
183#define DRM_MODE_PROP_PENDING (1<<0)
184#define DRM_MODE_PROP_RANGE (1<<1)
185#define DRM_MODE_PROP_IMMUTABLE (1<<2)
186#define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */
187#define DRM_MODE_PROP_BLOB (1<<4)
188
189struct drm_mode_property_enum {
190 uint64_t value;
191 unsigned char name[DRM_PROP_NAME_LEN];
192};
193
194struct drm_mode_get_property {
195 uint64_t values_ptr; /* values and blob lengths */
196 uint64_t enum_blob_ptr; /* enum and blob id ptrs */
197
198 unsigned int prop_id;
199 unsigned int flags;
200 unsigned char name[DRM_PROP_NAME_LEN];
201
202 int count_values;
203 int count_enum_blobs;
204};
205
206struct drm_mode_connector_set_property {
207 uint64_t value;
208 unsigned int prop_id;
209 unsigned int connector_id;
210};
211
212struct drm_mode_get_blob {
213 uint32_t blob_id;
214 uint32_t length;
215 uint64_t data;
216};
217
218struct drm_mode_fb_cmd {
219 unsigned int buffer_id;
220 unsigned int width, height;
221 unsigned int pitch;
222 unsigned int bpp;
223 unsigned int depth;
224
225 unsigned int handle;
226};
227
228struct drm_mode_mode_cmd {
229 unsigned int connector_id;
230 struct drm_mode_modeinfo mode;
231};
232
233#define DRM_MODE_CURSOR_BO 0x01
234#define DRM_MODE_CURSOR_MOVE 0x02
235
236/*
237 * depending on the value in flags diffrent members are used.
238 *
239 * CURSOR_BO uses
240 * crtc
241 * width
242 * height
243 * handle - if 0 turns the cursor of
244 *
245 * CURSOR_MOVE uses
246 * crtc
247 * x
248 * y
249 */
250struct drm_mode_cursor {
251 unsigned int flags;
252 unsigned int crtc;
253 int x;
254 int y;
255 uint32_t width;
256 uint32_t height;
257 unsigned int handle;
258};
259
260/*
261 * oh so ugly hotplug
262 */
263struct drm_mode_hotplug {
264 uint32_t counter;
265};
266
267struct drm_mode_crtc_lut {
268
269 uint32_t crtc_id;
270 uint32_t gamma_size;
271
272 /* pointers to arrays */
273 uint64_t red;
274 uint64_t green;
275 uint64_t blue;
276};
277
278#endif
diff --git a/include/linux/console.h b/include/linux/console.h
index 248e6e3b9b73..a67a90cf8268 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -153,4 +153,8 @@ void vcs_remove_sysfs(struct tty_struct *tty);
153#define VESA_HSYNC_SUSPEND 2 153#define VESA_HSYNC_SUSPEND 2
154#define VESA_POWERDOWN 3 154#define VESA_POWERDOWN 3
155 155
156#ifdef CONFIG_VGA_CONSOLE
157extern bool vgacon_text_force(void);
158#endif
159
156#endif /* _LINUX_CONSOLE_H */ 160#endif /* _LINUX_CONSOLE_H */