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