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