aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 */