aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2008-11-07 17:05:41 -0500
committerDave Airlie <airlied@linux.ie>2008-12-29 02:47:23 -0500
commitf453ba0460742ad027ae0c4c7d61e62817b3e7ef (patch)
tree29e6ecacd6e8971aa62e1825d77f2c1876ac3eb2 /drivers/gpu
parentde151cf67ce52ed2d88083daa5e60c7858947329 (diff)
DRM: add mode setting support
Add mode setting support to the DRM layer. This is a fairly big chunk of work that allows DRM drivers to provide full output control and configuration capabilities to userspace. It was motivated by several factors: - the fb layer's APIs aren't suited for anything but simple configurations - coordination between the fb layer, DRM layer, and various userspace drivers is poor to non-existent (radeonfb excepted) - user level mode setting drivers makes displaying panic & oops messages more difficult - suspend/resume of graphics state is possible in many more configurations with kernel level support This commit just adds the core DRM part of the mode setting APIs. Driver specific commits using these new structure and APIs will follow. Co-authors: Jesse Barnes <jbarnes@virtuousgeek.org>, Jakob Bornecrantz <jakob@tungstengraphics.com> Contributors: Alan Hourihane <alanh@tungstengraphics.com>, Maarten Maathuis <madman2003@gmail.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-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
11 files changed, 5070 insertions, 40 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