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