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