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