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