Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.29-rc1 2446 lines 64 kB view raw
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", __func__); 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} 808EXPORT_SYMBOL(drm_mode_config_init); 809 810int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group) 811{ 812 uint32_t total_objects = 0; 813 814 total_objects += dev->mode_config.num_crtc; 815 total_objects += dev->mode_config.num_connector; 816 total_objects += dev->mode_config.num_encoder; 817 818 if (total_objects == 0) 819 return -EINVAL; 820 821 group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL); 822 if (!group->id_list) 823 return -ENOMEM; 824 825 group->num_crtcs = 0; 826 group->num_connectors = 0; 827 group->num_encoders = 0; 828 return 0; 829} 830 831int drm_mode_group_init_legacy_group(struct drm_device *dev, 832 struct drm_mode_group *group) 833{ 834 struct drm_crtc *crtc; 835 struct drm_encoder *encoder; 836 struct drm_connector *connector; 837 int ret; 838 839 if ((ret = drm_mode_group_init(dev, group))) 840 return ret; 841 842 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) 843 group->id_list[group->num_crtcs++] = crtc->base.id; 844 845 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) 846 group->id_list[group->num_crtcs + group->num_encoders++] = 847 encoder->base.id; 848 849 list_for_each_entry(connector, &dev->mode_config.connector_list, head) 850 group->id_list[group->num_crtcs + group->num_encoders + 851 group->num_connectors++] = connector->base.id; 852 853 return 0; 854} 855 856/** 857 * drm_mode_config_cleanup - free up DRM mode_config info 858 * @dev: DRM device 859 * 860 * LOCKING: 861 * Caller must hold mode config lock. 862 * 863 * Free up all the connectors and CRTCs associated with this DRM device, then 864 * free up the framebuffers and associated buffer objects. 865 * 866 * FIXME: cleanup any dangling user buffer objects too 867 */ 868void drm_mode_config_cleanup(struct drm_device *dev) 869{ 870 struct drm_connector *connector, *ot; 871 struct drm_crtc *crtc, *ct; 872 struct drm_encoder *encoder, *enct; 873 struct drm_framebuffer *fb, *fbt; 874 struct drm_property *property, *pt; 875 876 list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list, 877 head) { 878 encoder->funcs->destroy(encoder); 879 } 880 881 list_for_each_entry_safe(connector, ot, 882 &dev->mode_config.connector_list, head) { 883 connector->funcs->destroy(connector); 884 } 885 886 list_for_each_entry_safe(property, pt, &dev->mode_config.property_list, 887 head) { 888 drm_property_destroy(dev, property); 889 } 890 891 list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) { 892 fb->funcs->destroy(fb); 893 } 894 895 list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) { 896 crtc->funcs->destroy(crtc); 897 } 898 899} 900EXPORT_SYMBOL(drm_mode_config_cleanup); 901 902/** 903 * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo 904 * @out: drm_mode_modeinfo struct to return to the user 905 * @in: drm_display_mode to use 906 * 907 * LOCKING: 908 * None. 909 * 910 * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to 911 * the user. 912 */ 913void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out, 914 struct drm_display_mode *in) 915{ 916 out->clock = in->clock; 917 out->hdisplay = in->hdisplay; 918 out->hsync_start = in->hsync_start; 919 out->hsync_end = in->hsync_end; 920 out->htotal = in->htotal; 921 out->hskew = in->hskew; 922 out->vdisplay = in->vdisplay; 923 out->vsync_start = in->vsync_start; 924 out->vsync_end = in->vsync_end; 925 out->vtotal = in->vtotal; 926 out->vscan = in->vscan; 927 out->vrefresh = in->vrefresh; 928 out->flags = in->flags; 929 out->type = in->type; 930 strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN); 931 out->name[DRM_DISPLAY_MODE_LEN-1] = 0; 932} 933 934/** 935 * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode 936 * @out: drm_display_mode to return to the user 937 * @in: drm_mode_modeinfo to use 938 * 939 * LOCKING: 940 * None. 941 * 942 * Convert a drm_mode_modeinfo into a drm_display_mode structure to return to 943 * the caller. 944 */ 945void drm_crtc_convert_umode(struct drm_display_mode *out, 946 struct drm_mode_modeinfo *in) 947{ 948 out->clock = in->clock; 949 out->hdisplay = in->hdisplay; 950 out->hsync_start = in->hsync_start; 951 out->hsync_end = in->hsync_end; 952 out->htotal = in->htotal; 953 out->hskew = in->hskew; 954 out->vdisplay = in->vdisplay; 955 out->vsync_start = in->vsync_start; 956 out->vsync_end = in->vsync_end; 957 out->vtotal = in->vtotal; 958 out->vscan = in->vscan; 959 out->vrefresh = in->vrefresh; 960 out->flags = in->flags; 961 out->type = in->type; 962 strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN); 963 out->name[DRM_DISPLAY_MODE_LEN-1] = 0; 964} 965 966/** 967 * drm_mode_getresources - get graphics configuration 968 * @inode: inode from the ioctl 969 * @filp: file * from the ioctl 970 * @cmd: cmd from ioctl 971 * @arg: arg from ioctl 972 * 973 * LOCKING: 974 * Takes mode config lock. 975 * 976 * Construct a set of configuration description structures and return 977 * them to the user, including CRTC, connector and framebuffer configuration. 978 * 979 * Called by the user via ioctl. 980 * 981 * RETURNS: 982 * Zero on success, errno on failure. 983 */ 984int drm_mode_getresources(struct drm_device *dev, void *data, 985 struct drm_file *file_priv) 986{ 987 struct drm_mode_card_res *card_res = data; 988 struct list_head *lh; 989 struct drm_framebuffer *fb; 990 struct drm_connector *connector; 991 struct drm_crtc *crtc; 992 struct drm_encoder *encoder; 993 int ret = 0; 994 int connector_count = 0; 995 int crtc_count = 0; 996 int fb_count = 0; 997 int encoder_count = 0; 998 int copied = 0, i; 999 uint32_t __user *fb_id; 1000 uint32_t __user *crtc_id; 1001 uint32_t __user *connector_id; 1002 uint32_t __user *encoder_id; 1003 struct drm_mode_group *mode_group; 1004 1005 mutex_lock(&dev->mode_config.mutex); 1006 1007 /* 1008 * For the non-control nodes we need to limit the list of resources 1009 * by IDs in the group list for this node 1010 */ 1011 list_for_each(lh, &file_priv->fbs) 1012 fb_count++; 1013 1014 mode_group = &file_priv->master->minor->mode_group; 1015 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { 1016 1017 list_for_each(lh, &dev->mode_config.crtc_list) 1018 crtc_count++; 1019 1020 list_for_each(lh, &dev->mode_config.connector_list) 1021 connector_count++; 1022 1023 list_for_each(lh, &dev->mode_config.encoder_list) 1024 encoder_count++; 1025 } else { 1026 1027 crtc_count = mode_group->num_crtcs; 1028 connector_count = mode_group->num_connectors; 1029 encoder_count = mode_group->num_encoders; 1030 } 1031 1032 card_res->max_height = dev->mode_config.max_height; 1033 card_res->min_height = dev->mode_config.min_height; 1034 card_res->max_width = dev->mode_config.max_width; 1035 card_res->min_width = dev->mode_config.min_width; 1036 1037 /* handle this in 4 parts */ 1038 /* FBs */ 1039 if (card_res->count_fbs >= fb_count) { 1040 copied = 0; 1041 fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr; 1042 list_for_each_entry(fb, &file_priv->fbs, head) { 1043 if (put_user(fb->base.id, fb_id + copied)) { 1044 ret = -EFAULT; 1045 goto out; 1046 } 1047 copied++; 1048 } 1049 } 1050 card_res->count_fbs = fb_count; 1051 1052 /* CRTCs */ 1053 if (card_res->count_crtcs >= crtc_count) { 1054 copied = 0; 1055 crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr; 1056 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { 1057 list_for_each_entry(crtc, &dev->mode_config.crtc_list, 1058 head) { 1059 DRM_DEBUG("CRTC ID is %d\n", crtc->base.id); 1060 if (put_user(crtc->base.id, crtc_id + copied)) { 1061 ret = -EFAULT; 1062 goto out; 1063 } 1064 copied++; 1065 } 1066 } else { 1067 for (i = 0; i < mode_group->num_crtcs; i++) { 1068 if (put_user(mode_group->id_list[i], 1069 crtc_id + copied)) { 1070 ret = -EFAULT; 1071 goto out; 1072 } 1073 copied++; 1074 } 1075 } 1076 } 1077 card_res->count_crtcs = crtc_count; 1078 1079 /* Encoders */ 1080 if (card_res->count_encoders >= encoder_count) { 1081 copied = 0; 1082 encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr; 1083 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { 1084 list_for_each_entry(encoder, 1085 &dev->mode_config.encoder_list, 1086 head) { 1087 DRM_DEBUG("ENCODER ID is %d\n", 1088 encoder->base.id); 1089 if (put_user(encoder->base.id, encoder_id + 1090 copied)) { 1091 ret = -EFAULT; 1092 goto out; 1093 } 1094 copied++; 1095 } 1096 } else { 1097 for (i = mode_group->num_crtcs; i < mode_group->num_crtcs + mode_group->num_encoders; i++) { 1098 if (put_user(mode_group->id_list[i], 1099 encoder_id + copied)) { 1100 ret = -EFAULT; 1101 goto out; 1102 } 1103 copied++; 1104 } 1105 1106 } 1107 } 1108 card_res->count_encoders = encoder_count; 1109 1110 /* Connectors */ 1111 if (card_res->count_connectors >= connector_count) { 1112 copied = 0; 1113 connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr; 1114 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { 1115 list_for_each_entry(connector, 1116 &dev->mode_config.connector_list, 1117 head) { 1118 DRM_DEBUG("CONNECTOR ID is %d\n", 1119 connector->base.id); 1120 if (put_user(connector->base.id, 1121 connector_id + copied)) { 1122 ret = -EFAULT; 1123 goto out; 1124 } 1125 copied++; 1126 } 1127 } else { 1128 int start = mode_group->num_crtcs + 1129 mode_group->num_encoders; 1130 for (i = start; i < start + mode_group->num_connectors; i++) { 1131 if (put_user(mode_group->id_list[i], 1132 connector_id + copied)) { 1133 ret = -EFAULT; 1134 goto out; 1135 } 1136 copied++; 1137 } 1138 } 1139 } 1140 card_res->count_connectors = connector_count; 1141 1142 DRM_DEBUG("Counted %d %d %d\n", card_res->count_crtcs, 1143 card_res->count_connectors, card_res->count_encoders); 1144 1145out: 1146 mutex_unlock(&dev->mode_config.mutex); 1147 return ret; 1148} 1149 1150/** 1151 * drm_mode_getcrtc - get CRTC configuration 1152 * @inode: inode from the ioctl 1153 * @filp: file * from the ioctl 1154 * @cmd: cmd from ioctl 1155 * @arg: arg from ioctl 1156 * 1157 * LOCKING: 1158 * Caller? (FIXME) 1159 * 1160 * Construct a CRTC configuration structure to return to the user. 1161 * 1162 * Called by the user via ioctl. 1163 * 1164 * RETURNS: 1165 * Zero on success, errno on failure. 1166 */ 1167int drm_mode_getcrtc(struct drm_device *dev, 1168 void *data, struct drm_file *file_priv) 1169{ 1170 struct drm_mode_crtc *crtc_resp = data; 1171 struct drm_crtc *crtc; 1172 struct drm_mode_object *obj; 1173 int ret = 0; 1174 1175 mutex_lock(&dev->mode_config.mutex); 1176 1177 obj = drm_mode_object_find(dev, crtc_resp->crtc_id, 1178 DRM_MODE_OBJECT_CRTC); 1179 if (!obj) { 1180 ret = -EINVAL; 1181 goto out; 1182 } 1183 crtc = obj_to_crtc(obj); 1184 1185 crtc_resp->x = crtc->x; 1186 crtc_resp->y = crtc->y; 1187 crtc_resp->gamma_size = crtc->gamma_size; 1188 if (crtc->fb) 1189 crtc_resp->fb_id = crtc->fb->base.id; 1190 else 1191 crtc_resp->fb_id = 0; 1192 1193 if (crtc->enabled) { 1194 1195 drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode); 1196 crtc_resp->mode_valid = 1; 1197 1198 } else { 1199 crtc_resp->mode_valid = 0; 1200 } 1201 1202out: 1203 mutex_unlock(&dev->mode_config.mutex); 1204 return ret; 1205} 1206 1207/** 1208 * drm_mode_getconnector - get connector configuration 1209 * @inode: inode from the ioctl 1210 * @filp: file * from the ioctl 1211 * @cmd: cmd from ioctl 1212 * @arg: arg from ioctl 1213 * 1214 * LOCKING: 1215 * Caller? (FIXME) 1216 * 1217 * Construct a connector configuration structure to return to the user. 1218 * 1219 * Called by the user via ioctl. 1220 * 1221 * RETURNS: 1222 * Zero on success, errno on failure. 1223 */ 1224int drm_mode_getconnector(struct drm_device *dev, void *data, 1225 struct drm_file *file_priv) 1226{ 1227 struct drm_mode_get_connector *out_resp = data; 1228 struct drm_mode_object *obj; 1229 struct drm_connector *connector; 1230 struct drm_display_mode *mode; 1231 int mode_count = 0; 1232 int props_count = 0; 1233 int encoders_count = 0; 1234 int ret = 0; 1235 int copied = 0; 1236 int i; 1237 struct drm_mode_modeinfo u_mode; 1238 struct drm_mode_modeinfo __user *mode_ptr; 1239 uint32_t __user *prop_ptr; 1240 uint64_t __user *prop_values; 1241 uint32_t __user *encoder_ptr; 1242 1243 memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo)); 1244 1245 DRM_DEBUG("connector id %d:\n", out_resp->connector_id); 1246 1247 mutex_lock(&dev->mode_config.mutex); 1248 1249 obj = drm_mode_object_find(dev, out_resp->connector_id, 1250 DRM_MODE_OBJECT_CONNECTOR); 1251 if (!obj) { 1252 ret = -EINVAL; 1253 goto out; 1254 } 1255 connector = obj_to_connector(obj); 1256 1257 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { 1258 if (connector->property_ids[i] != 0) { 1259 props_count++; 1260 } 1261 } 1262 1263 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 1264 if (connector->encoder_ids[i] != 0) { 1265 encoders_count++; 1266 } 1267 } 1268 1269 if (out_resp->count_modes == 0) { 1270 connector->funcs->fill_modes(connector, 1271 dev->mode_config.max_width, 1272 dev->mode_config.max_height); 1273 } 1274 1275 /* delayed so we get modes regardless of pre-fill_modes state */ 1276 list_for_each_entry(mode, &connector->modes, head) 1277 mode_count++; 1278 1279 out_resp->connector_id = connector->base.id; 1280 out_resp->connector_type = connector->connector_type; 1281 out_resp->connector_type_id = connector->connector_type_id; 1282 out_resp->mm_width = connector->display_info.width_mm; 1283 out_resp->mm_height = connector->display_info.height_mm; 1284 out_resp->subpixel = connector->display_info.subpixel_order; 1285 out_resp->connection = connector->status; 1286 if (connector->encoder) 1287 out_resp->encoder_id = connector->encoder->base.id; 1288 else 1289 out_resp->encoder_id = 0; 1290 1291 /* 1292 * This ioctl is called twice, once to determine how much space is 1293 * needed, and the 2nd time to fill it. 1294 */ 1295 if ((out_resp->count_modes >= mode_count) && mode_count) { 1296 copied = 0; 1297 mode_ptr = (struct drm_mode_modeinfo *)(unsigned long)out_resp->modes_ptr; 1298 list_for_each_entry(mode, &connector->modes, head) { 1299 drm_crtc_convert_to_umode(&u_mode, mode); 1300 if (copy_to_user(mode_ptr + copied, 1301 &u_mode, sizeof(u_mode))) { 1302 ret = -EFAULT; 1303 goto out; 1304 } 1305 copied++; 1306 } 1307 } 1308 out_resp->count_modes = mode_count; 1309 1310 if ((out_resp->count_props >= props_count) && props_count) { 1311 copied = 0; 1312 prop_ptr = (uint32_t *)(unsigned long)(out_resp->props_ptr); 1313 prop_values = (uint64_t *)(unsigned long)(out_resp->prop_values_ptr); 1314 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { 1315 if (connector->property_ids[i] != 0) { 1316 if (put_user(connector->property_ids[i], 1317 prop_ptr + copied)) { 1318 ret = -EFAULT; 1319 goto out; 1320 } 1321 1322 if (put_user(connector->property_values[i], 1323 prop_values + copied)) { 1324 ret = -EFAULT; 1325 goto out; 1326 } 1327 copied++; 1328 } 1329 } 1330 } 1331 out_resp->count_props = props_count; 1332 1333 if ((out_resp->count_encoders >= encoders_count) && encoders_count) { 1334 copied = 0; 1335 encoder_ptr = (uint32_t *)(unsigned long)(out_resp->encoders_ptr); 1336 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 1337 if (connector->encoder_ids[i] != 0) { 1338 if (put_user(connector->encoder_ids[i], 1339 encoder_ptr + copied)) { 1340 ret = -EFAULT; 1341 goto out; 1342 } 1343 copied++; 1344 } 1345 } 1346 } 1347 out_resp->count_encoders = encoders_count; 1348 1349out: 1350 mutex_unlock(&dev->mode_config.mutex); 1351 return ret; 1352} 1353 1354int drm_mode_getencoder(struct drm_device *dev, void *data, 1355 struct drm_file *file_priv) 1356{ 1357 struct drm_mode_get_encoder *enc_resp = data; 1358 struct drm_mode_object *obj; 1359 struct drm_encoder *encoder; 1360 int ret = 0; 1361 1362 mutex_lock(&dev->mode_config.mutex); 1363 obj = drm_mode_object_find(dev, enc_resp->encoder_id, 1364 DRM_MODE_OBJECT_ENCODER); 1365 if (!obj) { 1366 ret = -EINVAL; 1367 goto out; 1368 } 1369 encoder = obj_to_encoder(obj); 1370 1371 if (encoder->crtc) 1372 enc_resp->crtc_id = encoder->crtc->base.id; 1373 else 1374 enc_resp->crtc_id = 0; 1375 enc_resp->encoder_type = encoder->encoder_type; 1376 enc_resp->encoder_id = encoder->base.id; 1377 enc_resp->possible_crtcs = encoder->possible_crtcs; 1378 enc_resp->possible_clones = encoder->possible_clones; 1379 1380out: 1381 mutex_unlock(&dev->mode_config.mutex); 1382 return ret; 1383} 1384 1385/** 1386 * drm_mode_setcrtc - set CRTC configuration 1387 * @inode: inode from the ioctl 1388 * @filp: file * from the ioctl 1389 * @cmd: cmd from ioctl 1390 * @arg: arg from ioctl 1391 * 1392 * LOCKING: 1393 * Caller? (FIXME) 1394 * 1395 * Build a new CRTC configuration based on user request. 1396 * 1397 * Called by the user via ioctl. 1398 * 1399 * RETURNS: 1400 * Zero on success, errno on failure. 1401 */ 1402int drm_mode_setcrtc(struct drm_device *dev, void *data, 1403 struct drm_file *file_priv) 1404{ 1405 struct drm_mode_config *config = &dev->mode_config; 1406 struct drm_mode_crtc *crtc_req = data; 1407 struct drm_mode_object *obj; 1408 struct drm_crtc *crtc, *crtcfb; 1409 struct drm_connector **connector_set = NULL, *connector; 1410 struct drm_framebuffer *fb = NULL; 1411 struct drm_display_mode *mode = NULL; 1412 struct drm_mode_set set; 1413 uint32_t __user *set_connectors_ptr; 1414 int ret = 0; 1415 int i; 1416 1417 mutex_lock(&dev->mode_config.mutex); 1418 obj = drm_mode_object_find(dev, crtc_req->crtc_id, 1419 DRM_MODE_OBJECT_CRTC); 1420 if (!obj) { 1421 DRM_DEBUG("Unknown CRTC ID %d\n", crtc_req->crtc_id); 1422 ret = -EINVAL; 1423 goto out; 1424 } 1425 crtc = obj_to_crtc(obj); 1426 1427 if (crtc_req->mode_valid) { 1428 /* If we have a mode we need a framebuffer. */ 1429 /* If we pass -1, set the mode with the currently bound fb */ 1430 if (crtc_req->fb_id == -1) { 1431 list_for_each_entry(crtcfb, 1432 &dev->mode_config.crtc_list, head) { 1433 if (crtcfb == crtc) { 1434 DRM_DEBUG("Using current fb for setmode\n"); 1435 fb = crtc->fb; 1436 } 1437 } 1438 } else { 1439 obj = drm_mode_object_find(dev, crtc_req->fb_id, 1440 DRM_MODE_OBJECT_FB); 1441 if (!obj) { 1442 DRM_DEBUG("Unknown FB ID%d\n", crtc_req->fb_id); 1443 ret = -EINVAL; 1444 goto out; 1445 } 1446 fb = obj_to_fb(obj); 1447 } 1448 1449 mode = drm_mode_create(dev); 1450 drm_crtc_convert_umode(mode, &crtc_req->mode); 1451 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); 1452 } 1453 1454 if (crtc_req->count_connectors == 0 && mode) { 1455 DRM_DEBUG("Count connectors is 0 but mode set\n"); 1456 ret = -EINVAL; 1457 goto out; 1458 } 1459 1460 if (crtc_req->count_connectors > 0 && !mode && !fb) { 1461 DRM_DEBUG("Count connectors is %d but no mode or fb set\n", 1462 crtc_req->count_connectors); 1463 ret = -EINVAL; 1464 goto out; 1465 } 1466 1467 if (crtc_req->count_connectors > 0) { 1468 u32 out_id; 1469 1470 /* Avoid unbounded kernel memory allocation */ 1471 if (crtc_req->count_connectors > config->num_connector) { 1472 ret = -EINVAL; 1473 goto out; 1474 } 1475 1476 connector_set = kmalloc(crtc_req->count_connectors * 1477 sizeof(struct drm_connector *), 1478 GFP_KERNEL); 1479 if (!connector_set) { 1480 ret = -ENOMEM; 1481 goto out; 1482 } 1483 1484 for (i = 0; i < crtc_req->count_connectors; i++) { 1485 set_connectors_ptr = (uint32_t *)(unsigned long)crtc_req->set_connectors_ptr; 1486 if (get_user(out_id, &set_connectors_ptr[i])) { 1487 ret = -EFAULT; 1488 goto out; 1489 } 1490 1491 obj = drm_mode_object_find(dev, out_id, 1492 DRM_MODE_OBJECT_CONNECTOR); 1493 if (!obj) { 1494 DRM_DEBUG("Connector id %d unknown\n", out_id); 1495 ret = -EINVAL; 1496 goto out; 1497 } 1498 connector = obj_to_connector(obj); 1499 1500 connector_set[i] = connector; 1501 } 1502 } 1503 1504 set.crtc = crtc; 1505 set.x = crtc_req->x; 1506 set.y = crtc_req->y; 1507 set.mode = mode; 1508 set.connectors = connector_set; 1509 set.num_connectors = crtc_req->count_connectors; 1510 set.fb =fb; 1511 ret = crtc->funcs->set_config(&set); 1512 1513out: 1514 kfree(connector_set); 1515 mutex_unlock(&dev->mode_config.mutex); 1516 return ret; 1517} 1518 1519int drm_mode_cursor_ioctl(struct drm_device *dev, 1520 void *data, struct drm_file *file_priv) 1521{ 1522 struct drm_mode_cursor *req = data; 1523 struct drm_mode_object *obj; 1524 struct drm_crtc *crtc; 1525 int ret = 0; 1526 1527 DRM_DEBUG("\n"); 1528 1529 if (!req->flags) { 1530 DRM_ERROR("no operation set\n"); 1531 return -EINVAL; 1532 } 1533 1534 mutex_lock(&dev->mode_config.mutex); 1535 obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC); 1536 if (!obj) { 1537 DRM_DEBUG("Unknown CRTC ID %d\n", req->crtc_id); 1538 ret = -EINVAL; 1539 goto out; 1540 } 1541 crtc = obj_to_crtc(obj); 1542 1543 if (req->flags & DRM_MODE_CURSOR_BO) { 1544 if (!crtc->funcs->cursor_set) { 1545 DRM_ERROR("crtc does not support cursor\n"); 1546 ret = -ENXIO; 1547 goto out; 1548 } 1549 /* Turns off the cursor if handle is 0 */ 1550 ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle, 1551 req->width, req->height); 1552 } 1553 1554 if (req->flags & DRM_MODE_CURSOR_MOVE) { 1555 if (crtc->funcs->cursor_move) { 1556 ret = crtc->funcs->cursor_move(crtc, req->x, req->y); 1557 } else { 1558 DRM_ERROR("crtc does not support cursor\n"); 1559 ret = -EFAULT; 1560 goto out; 1561 } 1562 } 1563out: 1564 mutex_unlock(&dev->mode_config.mutex); 1565 return ret; 1566} 1567 1568/** 1569 * drm_mode_addfb - add an FB to the graphics configuration 1570 * @inode: inode from the ioctl 1571 * @filp: file * from the ioctl 1572 * @cmd: cmd from ioctl 1573 * @arg: arg from ioctl 1574 * 1575 * LOCKING: 1576 * Takes mode config lock. 1577 * 1578 * Add a new FB to the specified CRTC, given a user request. 1579 * 1580 * Called by the user via ioctl. 1581 * 1582 * RETURNS: 1583 * Zero on success, errno on failure. 1584 */ 1585int drm_mode_addfb(struct drm_device *dev, 1586 void *data, struct drm_file *file_priv) 1587{ 1588 struct drm_mode_fb_cmd *r = data; 1589 struct drm_mode_config *config = &dev->mode_config; 1590 struct drm_framebuffer *fb; 1591 int ret = 0; 1592 1593 if ((config->min_width > r->width) || (r->width > config->max_width)) { 1594 DRM_ERROR("mode new framebuffer width not within limits\n"); 1595 return -EINVAL; 1596 } 1597 if ((config->min_height > r->height) || (r->height > config->max_height)) { 1598 DRM_ERROR("mode new framebuffer height not within limits\n"); 1599 return -EINVAL; 1600 } 1601 1602 mutex_lock(&dev->mode_config.mutex); 1603 1604 /* TODO check buffer is sufficently large */ 1605 /* TODO setup destructor callback */ 1606 1607 fb = dev->mode_config.funcs->fb_create(dev, file_priv, r); 1608 if (!fb) { 1609 DRM_ERROR("could not create framebuffer\n"); 1610 ret = -EINVAL; 1611 goto out; 1612 } 1613 1614 r->fb_id = fb->base.id; 1615 list_add(&fb->filp_head, &file_priv->fbs); 1616 1617out: 1618 mutex_unlock(&dev->mode_config.mutex); 1619 return ret; 1620} 1621 1622/** 1623 * drm_mode_rmfb - remove an FB from the configuration 1624 * @inode: inode from the ioctl 1625 * @filp: file * from the ioctl 1626 * @cmd: cmd from ioctl 1627 * @arg: arg from ioctl 1628 * 1629 * LOCKING: 1630 * Takes mode config lock. 1631 * 1632 * Remove the FB specified by the user. 1633 * 1634 * Called by the user via ioctl. 1635 * 1636 * RETURNS: 1637 * Zero on success, errno on failure. 1638 */ 1639int drm_mode_rmfb(struct drm_device *dev, 1640 void *data, struct drm_file *file_priv) 1641{ 1642 struct drm_mode_object *obj; 1643 struct drm_framebuffer *fb = NULL; 1644 struct drm_framebuffer *fbl = NULL; 1645 uint32_t *id = data; 1646 int ret = 0; 1647 int found = 0; 1648 1649 mutex_lock(&dev->mode_config.mutex); 1650 obj = drm_mode_object_find(dev, *id, DRM_MODE_OBJECT_FB); 1651 /* TODO check that we realy get a framebuffer back. */ 1652 if (!obj) { 1653 DRM_ERROR("mode invalid framebuffer id\n"); 1654 ret = -EINVAL; 1655 goto out; 1656 } 1657 fb = obj_to_fb(obj); 1658 1659 list_for_each_entry(fbl, &file_priv->fbs, filp_head) 1660 if (fb == fbl) 1661 found = 1; 1662 1663 if (!found) { 1664 DRM_ERROR("tried to remove a fb that we didn't own\n"); 1665 ret = -EINVAL; 1666 goto out; 1667 } 1668 1669 /* TODO release all crtc connected to the framebuffer */ 1670 /* TODO unhock the destructor from the buffer object */ 1671 1672 list_del(&fb->filp_head); 1673 fb->funcs->destroy(fb); 1674 1675out: 1676 mutex_unlock(&dev->mode_config.mutex); 1677 return ret; 1678} 1679 1680/** 1681 * drm_mode_getfb - get FB info 1682 * @inode: inode from the ioctl 1683 * @filp: file * from the ioctl 1684 * @cmd: cmd from ioctl 1685 * @arg: arg from ioctl 1686 * 1687 * LOCKING: 1688 * Caller? (FIXME) 1689 * 1690 * Lookup the FB given its ID and return info about it. 1691 * 1692 * Called by the user via ioctl. 1693 * 1694 * RETURNS: 1695 * Zero on success, errno on failure. 1696 */ 1697int drm_mode_getfb(struct drm_device *dev, 1698 void *data, struct drm_file *file_priv) 1699{ 1700 struct drm_mode_fb_cmd *r = data; 1701 struct drm_mode_object *obj; 1702 struct drm_framebuffer *fb; 1703 int ret = 0; 1704 1705 mutex_lock(&dev->mode_config.mutex); 1706 obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB); 1707 if (!obj) { 1708 DRM_ERROR("invalid framebuffer id\n"); 1709 ret = -EINVAL; 1710 goto out; 1711 } 1712 fb = obj_to_fb(obj); 1713 1714 r->height = fb->height; 1715 r->width = fb->width; 1716 r->depth = fb->depth; 1717 r->bpp = fb->bits_per_pixel; 1718 r->pitch = fb->pitch; 1719 fb->funcs->create_handle(fb, file_priv, &r->handle); 1720 1721out: 1722 mutex_unlock(&dev->mode_config.mutex); 1723 return ret; 1724} 1725 1726/** 1727 * drm_fb_release - remove and free the FBs on this file 1728 * @filp: file * from the ioctl 1729 * 1730 * LOCKING: 1731 * Takes mode config lock. 1732 * 1733 * Destroy all the FBs associated with @filp. 1734 * 1735 * Called by the user via ioctl. 1736 * 1737 * RETURNS: 1738 * Zero on success, errno on failure. 1739 */ 1740void drm_fb_release(struct file *filp) 1741{ 1742 struct drm_file *priv = filp->private_data; 1743 struct drm_device *dev = priv->minor->dev; 1744 struct drm_framebuffer *fb, *tfb; 1745 1746 mutex_lock(&dev->mode_config.mutex); 1747 list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) { 1748 list_del(&fb->filp_head); 1749 fb->funcs->destroy(fb); 1750 } 1751 mutex_unlock(&dev->mode_config.mutex); 1752} 1753 1754/** 1755 * drm_mode_attachmode - add a mode to the user mode list 1756 * @dev: DRM device 1757 * @connector: connector to add the mode to 1758 * @mode: mode to add 1759 * 1760 * Add @mode to @connector's user mode list. 1761 */ 1762static int drm_mode_attachmode(struct drm_device *dev, 1763 struct drm_connector *connector, 1764 struct drm_display_mode *mode) 1765{ 1766 int ret = 0; 1767 1768 list_add_tail(&mode->head, &connector->user_modes); 1769 return ret; 1770} 1771 1772int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc, 1773 struct drm_display_mode *mode) 1774{ 1775 struct drm_connector *connector; 1776 int ret = 0; 1777 struct drm_display_mode *dup_mode; 1778 int need_dup = 0; 1779 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 1780 if (!connector->encoder) 1781 break; 1782 if (connector->encoder->crtc == crtc) { 1783 if (need_dup) 1784 dup_mode = drm_mode_duplicate(dev, mode); 1785 else 1786 dup_mode = mode; 1787 ret = drm_mode_attachmode(dev, connector, dup_mode); 1788 if (ret) 1789 return ret; 1790 need_dup = 1; 1791 } 1792 } 1793 return 0; 1794} 1795EXPORT_SYMBOL(drm_mode_attachmode_crtc); 1796 1797static int drm_mode_detachmode(struct drm_device *dev, 1798 struct drm_connector *connector, 1799 struct drm_display_mode *mode) 1800{ 1801 int found = 0; 1802 int ret = 0; 1803 struct drm_display_mode *match_mode, *t; 1804 1805 list_for_each_entry_safe(match_mode, t, &connector->user_modes, head) { 1806 if (drm_mode_equal(match_mode, mode)) { 1807 list_del(&match_mode->head); 1808 drm_mode_destroy(dev, match_mode); 1809 found = 1; 1810 break; 1811 } 1812 } 1813 1814 if (!found) 1815 ret = -EINVAL; 1816 1817 return ret; 1818} 1819 1820int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode) 1821{ 1822 struct drm_connector *connector; 1823 1824 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 1825 drm_mode_detachmode(dev, connector, mode); 1826 } 1827 return 0; 1828} 1829EXPORT_SYMBOL(drm_mode_detachmode_crtc); 1830 1831/** 1832 * drm_fb_attachmode - Attach a user mode to an connector 1833 * @inode: inode from the ioctl 1834 * @filp: file * from the ioctl 1835 * @cmd: cmd from ioctl 1836 * @arg: arg from ioctl 1837 * 1838 * This attaches a user specified mode to an connector. 1839 * Called by the user via ioctl. 1840 * 1841 * RETURNS: 1842 * Zero on success, errno on failure. 1843 */ 1844int drm_mode_attachmode_ioctl(struct drm_device *dev, 1845 void *data, struct drm_file *file_priv) 1846{ 1847 struct drm_mode_mode_cmd *mode_cmd = data; 1848 struct drm_connector *connector; 1849 struct drm_display_mode *mode; 1850 struct drm_mode_object *obj; 1851 struct drm_mode_modeinfo *umode = &mode_cmd->mode; 1852 int ret = 0; 1853 1854 mutex_lock(&dev->mode_config.mutex); 1855 1856 obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR); 1857 if (!obj) { 1858 ret = -EINVAL; 1859 goto out; 1860 } 1861 connector = obj_to_connector(obj); 1862 1863 mode = drm_mode_create(dev); 1864 if (!mode) { 1865 ret = -ENOMEM; 1866 goto out; 1867 } 1868 1869 drm_crtc_convert_umode(mode, umode); 1870 1871 ret = drm_mode_attachmode(dev, connector, mode); 1872out: 1873 mutex_unlock(&dev->mode_config.mutex); 1874 return ret; 1875} 1876 1877 1878/** 1879 * drm_fb_detachmode - Detach a user specified mode from an connector 1880 * @inode: inode from the ioctl 1881 * @filp: file * from the ioctl 1882 * @cmd: cmd from ioctl 1883 * @arg: arg from ioctl 1884 * 1885 * Called by the user via ioctl. 1886 * 1887 * RETURNS: 1888 * Zero on success, errno on failure. 1889 */ 1890int drm_mode_detachmode_ioctl(struct drm_device *dev, 1891 void *data, struct drm_file *file_priv) 1892{ 1893 struct drm_mode_object *obj; 1894 struct drm_mode_mode_cmd *mode_cmd = data; 1895 struct drm_connector *connector; 1896 struct drm_display_mode mode; 1897 struct drm_mode_modeinfo *umode = &mode_cmd->mode; 1898 int ret = 0; 1899 1900 mutex_lock(&dev->mode_config.mutex); 1901 1902 obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR); 1903 if (!obj) { 1904 ret = -EINVAL; 1905 goto out; 1906 } 1907 connector = obj_to_connector(obj); 1908 1909 drm_crtc_convert_umode(&mode, umode); 1910 ret = drm_mode_detachmode(dev, connector, &mode); 1911out: 1912 mutex_unlock(&dev->mode_config.mutex); 1913 return ret; 1914} 1915 1916struct drm_property *drm_property_create(struct drm_device *dev, int flags, 1917 const char *name, int num_values) 1918{ 1919 struct drm_property *property = NULL; 1920 1921 property = kzalloc(sizeof(struct drm_property), GFP_KERNEL); 1922 if (!property) 1923 return NULL; 1924 1925 if (num_values) { 1926 property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL); 1927 if (!property->values) 1928 goto fail; 1929 } 1930 1931 drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY); 1932 property->flags = flags; 1933 property->num_values = num_values; 1934 INIT_LIST_HEAD(&property->enum_blob_list); 1935 1936 if (name) 1937 strncpy(property->name, name, DRM_PROP_NAME_LEN); 1938 1939 list_add_tail(&property->head, &dev->mode_config.property_list); 1940 return property; 1941fail: 1942 kfree(property); 1943 return NULL; 1944} 1945EXPORT_SYMBOL(drm_property_create); 1946 1947int drm_property_add_enum(struct drm_property *property, int index, 1948 uint64_t value, const char *name) 1949{ 1950 struct drm_property_enum *prop_enum; 1951 1952 if (!(property->flags & DRM_MODE_PROP_ENUM)) 1953 return -EINVAL; 1954 1955 if (!list_empty(&property->enum_blob_list)) { 1956 list_for_each_entry(prop_enum, &property->enum_blob_list, head) { 1957 if (prop_enum->value == value) { 1958 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN); 1959 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0'; 1960 return 0; 1961 } 1962 } 1963 } 1964 1965 prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL); 1966 if (!prop_enum) 1967 return -ENOMEM; 1968 1969 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN); 1970 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0'; 1971 prop_enum->value = value; 1972 1973 property->values[index] = value; 1974 list_add_tail(&prop_enum->head, &property->enum_blob_list); 1975 return 0; 1976} 1977EXPORT_SYMBOL(drm_property_add_enum); 1978 1979void drm_property_destroy(struct drm_device *dev, struct drm_property *property) 1980{ 1981 struct drm_property_enum *prop_enum, *pt; 1982 1983 list_for_each_entry_safe(prop_enum, pt, &property->enum_blob_list, head) { 1984 list_del(&prop_enum->head); 1985 kfree(prop_enum); 1986 } 1987 1988 if (property->num_values) 1989 kfree(property->values); 1990 drm_mode_object_put(dev, &property->base); 1991 list_del(&property->head); 1992 kfree(property); 1993} 1994EXPORT_SYMBOL(drm_property_destroy); 1995 1996int drm_connector_attach_property(struct drm_connector *connector, 1997 struct drm_property *property, uint64_t init_val) 1998{ 1999 int i; 2000 2001 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { 2002 if (connector->property_ids[i] == 0) { 2003 connector->property_ids[i] = property->base.id; 2004 connector->property_values[i] = init_val; 2005 break; 2006 } 2007 } 2008 2009 if (i == DRM_CONNECTOR_MAX_PROPERTY) 2010 return -EINVAL; 2011 return 0; 2012} 2013EXPORT_SYMBOL(drm_connector_attach_property); 2014 2015int drm_connector_property_set_value(struct drm_connector *connector, 2016 struct drm_property *property, uint64_t value) 2017{ 2018 int i; 2019 2020 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { 2021 if (connector->property_ids[i] == property->base.id) { 2022 connector->property_values[i] = value; 2023 break; 2024 } 2025 } 2026 2027 if (i == DRM_CONNECTOR_MAX_PROPERTY) 2028 return -EINVAL; 2029 return 0; 2030} 2031EXPORT_SYMBOL(drm_connector_property_set_value); 2032 2033int drm_connector_property_get_value(struct drm_connector *connector, 2034 struct drm_property *property, uint64_t *val) 2035{ 2036 int i; 2037 2038 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { 2039 if (connector->property_ids[i] == property->base.id) { 2040 *val = connector->property_values[i]; 2041 break; 2042 } 2043 } 2044 2045 if (i == DRM_CONNECTOR_MAX_PROPERTY) 2046 return -EINVAL; 2047 return 0; 2048} 2049EXPORT_SYMBOL(drm_connector_property_get_value); 2050 2051int drm_mode_getproperty_ioctl(struct drm_device *dev, 2052 void *data, struct drm_file *file_priv) 2053{ 2054 struct drm_mode_object *obj; 2055 struct drm_mode_get_property *out_resp = data; 2056 struct drm_property *property; 2057 int enum_count = 0; 2058 int blob_count = 0; 2059 int value_count = 0; 2060 int ret = 0, i; 2061 int copied; 2062 struct drm_property_enum *prop_enum; 2063 struct drm_mode_property_enum __user *enum_ptr; 2064 struct drm_property_blob *prop_blob; 2065 uint32_t *blob_id_ptr; 2066 uint64_t __user *values_ptr; 2067 uint32_t __user *blob_length_ptr; 2068 2069 mutex_lock(&dev->mode_config.mutex); 2070 obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY); 2071 if (!obj) { 2072 ret = -EINVAL; 2073 goto done; 2074 } 2075 property = obj_to_property(obj); 2076 2077 if (property->flags & DRM_MODE_PROP_ENUM) { 2078 list_for_each_entry(prop_enum, &property->enum_blob_list, head) 2079 enum_count++; 2080 } else if (property->flags & DRM_MODE_PROP_BLOB) { 2081 list_for_each_entry(prop_blob, &property->enum_blob_list, head) 2082 blob_count++; 2083 } 2084 2085 value_count = property->num_values; 2086 2087 strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN); 2088 out_resp->name[DRM_PROP_NAME_LEN-1] = 0; 2089 out_resp->flags = property->flags; 2090 2091 if ((out_resp->count_values >= value_count) && value_count) { 2092 values_ptr = (uint64_t *)(unsigned long)out_resp->values_ptr; 2093 for (i = 0; i < value_count; i++) { 2094 if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) { 2095 ret = -EFAULT; 2096 goto done; 2097 } 2098 } 2099 } 2100 out_resp->count_values = value_count; 2101 2102 if (property->flags & DRM_MODE_PROP_ENUM) { 2103 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) { 2104 copied = 0; 2105 enum_ptr = (struct drm_mode_property_enum *)(unsigned long)out_resp->enum_blob_ptr; 2106 list_for_each_entry(prop_enum, &property->enum_blob_list, head) { 2107 2108 if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) { 2109 ret = -EFAULT; 2110 goto done; 2111 } 2112 2113 if (copy_to_user(&enum_ptr[copied].name, 2114 &prop_enum->name, DRM_PROP_NAME_LEN)) { 2115 ret = -EFAULT; 2116 goto done; 2117 } 2118 copied++; 2119 } 2120 } 2121 out_resp->count_enum_blobs = enum_count; 2122 } 2123 2124 if (property->flags & DRM_MODE_PROP_BLOB) { 2125 if ((out_resp->count_enum_blobs >= blob_count) && blob_count) { 2126 copied = 0; 2127 blob_id_ptr = (uint32_t *)(unsigned long)out_resp->enum_blob_ptr; 2128 blob_length_ptr = (uint32_t *)(unsigned long)out_resp->values_ptr; 2129 2130 list_for_each_entry(prop_blob, &property->enum_blob_list, head) { 2131 if (put_user(prop_blob->base.id, blob_id_ptr + copied)) { 2132 ret = -EFAULT; 2133 goto done; 2134 } 2135 2136 if (put_user(prop_blob->length, blob_length_ptr + copied)) { 2137 ret = -EFAULT; 2138 goto done; 2139 } 2140 2141 copied++; 2142 } 2143 } 2144 out_resp->count_enum_blobs = blob_count; 2145 } 2146done: 2147 mutex_unlock(&dev->mode_config.mutex); 2148 return ret; 2149} 2150 2151static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length, 2152 void *data) 2153{ 2154 struct drm_property_blob *blob; 2155 2156 if (!length || !data) 2157 return NULL; 2158 2159 blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL); 2160 if (!blob) 2161 return NULL; 2162 2163 blob->data = (void *)((char *)blob + sizeof(struct drm_property_blob)); 2164 blob->length = length; 2165 2166 memcpy(blob->data, data, length); 2167 2168 drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB); 2169 2170 list_add_tail(&blob->head, &dev->mode_config.property_blob_list); 2171 return blob; 2172} 2173 2174static void drm_property_destroy_blob(struct drm_device *dev, 2175 struct drm_property_blob *blob) 2176{ 2177 drm_mode_object_put(dev, &blob->base); 2178 list_del(&blob->head); 2179 kfree(blob); 2180} 2181 2182int drm_mode_getblob_ioctl(struct drm_device *dev, 2183 void *data, struct drm_file *file_priv) 2184{ 2185 struct drm_mode_object *obj; 2186 struct drm_mode_get_blob *out_resp = data; 2187 struct drm_property_blob *blob; 2188 int ret = 0; 2189 void *blob_ptr; 2190 2191 mutex_lock(&dev->mode_config.mutex); 2192 obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB); 2193 if (!obj) { 2194 ret = -EINVAL; 2195 goto done; 2196 } 2197 blob = obj_to_blob(obj); 2198 2199 if (out_resp->length == blob->length) { 2200 blob_ptr = (void *)(unsigned long)out_resp->data; 2201 if (copy_to_user(blob_ptr, blob->data, blob->length)){ 2202 ret = -EFAULT; 2203 goto done; 2204 } 2205 } 2206 out_resp->length = blob->length; 2207 2208done: 2209 mutex_unlock(&dev->mode_config.mutex); 2210 return ret; 2211} 2212 2213int drm_mode_connector_update_edid_property(struct drm_connector *connector, 2214 struct edid *edid) 2215{ 2216 struct drm_device *dev = connector->dev; 2217 int ret = 0; 2218 2219 if (connector->edid_blob_ptr) 2220 drm_property_destroy_blob(dev, connector->edid_blob_ptr); 2221 2222 /* Delete edid, when there is none. */ 2223 if (!edid) { 2224 connector->edid_blob_ptr = NULL; 2225 ret = drm_connector_property_set_value(connector, dev->mode_config.edid_property, 0); 2226 return ret; 2227 } 2228 2229 connector->edid_blob_ptr = drm_property_create_blob(connector->dev, 128, edid); 2230 2231 ret = drm_connector_property_set_value(connector, 2232 dev->mode_config.edid_property, 2233 connector->edid_blob_ptr->base.id); 2234 2235 return ret; 2236} 2237EXPORT_SYMBOL(drm_mode_connector_update_edid_property); 2238 2239int drm_mode_connector_property_set_ioctl(struct drm_device *dev, 2240 void *data, struct drm_file *file_priv) 2241{ 2242 struct drm_mode_connector_set_property *out_resp = data; 2243 struct drm_mode_object *obj; 2244 struct drm_property *property; 2245 struct drm_connector *connector; 2246 int ret = -EINVAL; 2247 int i; 2248 2249 mutex_lock(&dev->mode_config.mutex); 2250 2251 obj = drm_mode_object_find(dev, out_resp->connector_id, DRM_MODE_OBJECT_CONNECTOR); 2252 if (!obj) { 2253 goto out; 2254 } 2255 connector = obj_to_connector(obj); 2256 2257 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { 2258 if (connector->property_ids[i] == out_resp->prop_id) 2259 break; 2260 } 2261 2262 if (i == DRM_CONNECTOR_MAX_PROPERTY) { 2263 goto out; 2264 } 2265 2266 obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY); 2267 if (!obj) { 2268 goto out; 2269 } 2270 property = obj_to_property(obj); 2271 2272 if (property->flags & DRM_MODE_PROP_IMMUTABLE) 2273 goto out; 2274 2275 if (property->flags & DRM_MODE_PROP_RANGE) { 2276 if (out_resp->value < property->values[0]) 2277 goto out; 2278 2279 if (out_resp->value > property->values[1]) 2280 goto out; 2281 } else { 2282 int found = 0; 2283 for (i = 0; i < property->num_values; i++) { 2284 if (property->values[i] == out_resp->value) { 2285 found = 1; 2286 break; 2287 } 2288 } 2289 if (!found) { 2290 goto out; 2291 } 2292 } 2293 2294 if (connector->funcs->set_property) 2295 ret = connector->funcs->set_property(connector, property, out_resp->value); 2296 2297 /* store the property value if succesful */ 2298 if (!ret) 2299 drm_connector_property_set_value(connector, property, out_resp->value); 2300out: 2301 mutex_unlock(&dev->mode_config.mutex); 2302 return ret; 2303} 2304 2305int drm_mode_connector_attach_encoder(struct drm_connector *connector, 2306 struct drm_encoder *encoder) 2307{ 2308 int i; 2309 2310 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 2311 if (connector->encoder_ids[i] == 0) { 2312 connector->encoder_ids[i] = encoder->base.id; 2313 return 0; 2314 } 2315 } 2316 return -ENOMEM; 2317} 2318EXPORT_SYMBOL(drm_mode_connector_attach_encoder); 2319 2320void drm_mode_connector_detach_encoder(struct drm_connector *connector, 2321 struct drm_encoder *encoder) 2322{ 2323 int i; 2324 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 2325 if (connector->encoder_ids[i] == encoder->base.id) { 2326 connector->encoder_ids[i] = 0; 2327 if (connector->encoder == encoder) 2328 connector->encoder = NULL; 2329 break; 2330 } 2331 } 2332} 2333EXPORT_SYMBOL(drm_mode_connector_detach_encoder); 2334 2335bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, 2336 int gamma_size) 2337{ 2338 crtc->gamma_size = gamma_size; 2339 2340 crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL); 2341 if (!crtc->gamma_store) { 2342 crtc->gamma_size = 0; 2343 return false; 2344 } 2345 2346 return true; 2347} 2348EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size); 2349 2350int drm_mode_gamma_set_ioctl(struct drm_device *dev, 2351 void *data, struct drm_file *file_priv) 2352{ 2353 struct drm_mode_crtc_lut *crtc_lut = data; 2354 struct drm_mode_object *obj; 2355 struct drm_crtc *crtc; 2356 void *r_base, *g_base, *b_base; 2357 int size; 2358 int ret = 0; 2359 2360 mutex_lock(&dev->mode_config.mutex); 2361 obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC); 2362 if (!obj) { 2363 ret = -EINVAL; 2364 goto out; 2365 } 2366 crtc = obj_to_crtc(obj); 2367 2368 /* memcpy into gamma store */ 2369 if (crtc_lut->gamma_size != crtc->gamma_size) { 2370 ret = -EINVAL; 2371 goto out; 2372 } 2373 2374 size = crtc_lut->gamma_size * (sizeof(uint16_t)); 2375 r_base = crtc->gamma_store; 2376 if (copy_from_user(r_base, (void __user *)(unsigned long)crtc_lut->red, size)) { 2377 ret = -EFAULT; 2378 goto out; 2379 } 2380 2381 g_base = r_base + size; 2382 if (copy_from_user(g_base, (void __user *)(unsigned long)crtc_lut->green, size)) { 2383 ret = -EFAULT; 2384 goto out; 2385 } 2386 2387 b_base = g_base + size; 2388 if (copy_from_user(b_base, (void __user *)(unsigned long)crtc_lut->blue, size)) { 2389 ret = -EFAULT; 2390 goto out; 2391 } 2392 2393 crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, crtc->gamma_size); 2394 2395out: 2396 mutex_unlock(&dev->mode_config.mutex); 2397 return ret; 2398 2399} 2400 2401int drm_mode_gamma_get_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_to_user((void __user *)(unsigned long)crtc_lut->red, r_base, size)) { 2428 ret = -EFAULT; 2429 goto out; 2430 } 2431 2432 g_base = r_base + size; 2433 if (copy_to_user((void __user *)(unsigned long)crtc_lut->green, g_base, size)) { 2434 ret = -EFAULT; 2435 goto out; 2436 } 2437 2438 b_base = g_base + size; 2439 if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) { 2440 ret = -EFAULT; 2441 goto out; 2442 } 2443out: 2444 mutex_unlock(&dev->mode_config.mutex); 2445 return ret; 2446}