drm_crtc.c revision 90367bf6e98352520d15634ac4e79f0d4598cff1
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 if (!mode) 647 return; 648 649 drm_mode_object_put(dev, &mode->base); 650 651 kfree(mode); 652} 653EXPORT_SYMBOL(drm_mode_destroy); 654 655static int drm_mode_create_standard_connector_properties(struct drm_device *dev) 656{ 657 struct drm_property *edid; 658 struct drm_property *dpms; 659 660 /* 661 * Standard properties (apply to all connectors) 662 */ 663 edid = drm_property_create(dev, DRM_MODE_PROP_BLOB | 664 DRM_MODE_PROP_IMMUTABLE, 665 "EDID", 0); 666 dev->mode_config.edid_property = edid; 667 668 dpms = drm_property_create_enum(dev, 0, 669 "DPMS", drm_dpms_enum_list, 670 ARRAY_SIZE(drm_dpms_enum_list)); 671 dev->mode_config.dpms_property = dpms; 672 673 return 0; 674} 675 676/** 677 * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties 678 * @dev: DRM device 679 * 680 * Called by a driver the first time a DVI-I connector is made. 681 */ 682int drm_mode_create_dvi_i_properties(struct drm_device *dev) 683{ 684 struct drm_property *dvi_i_selector; 685 struct drm_property *dvi_i_subconnector; 686 687 if (dev->mode_config.dvi_i_select_subconnector_property) 688 return 0; 689 690 dvi_i_selector = 691 drm_property_create_enum(dev, 0, 692 "select subconnector", 693 drm_dvi_i_select_enum_list, 694 ARRAY_SIZE(drm_dvi_i_select_enum_list)); 695 dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector; 696 697 dvi_i_subconnector = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, 698 "subconnector", 699 drm_dvi_i_subconnector_enum_list, 700 ARRAY_SIZE(drm_dvi_i_subconnector_enum_list)); 701 dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector; 702 703 return 0; 704} 705EXPORT_SYMBOL(drm_mode_create_dvi_i_properties); 706 707/** 708 * drm_create_tv_properties - create TV specific connector properties 709 * @dev: DRM device 710 * @num_modes: number of different TV formats (modes) supported 711 * @modes: array of pointers to strings containing name of each format 712 * 713 * Called by a driver's TV initialization routine, this function creates 714 * the TV specific connector properties for a given device. Caller is 715 * responsible for allocating a list of format names and passing them to 716 * this routine. 717 */ 718int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes, 719 char *modes[]) 720{ 721 struct drm_property *tv_selector; 722 struct drm_property *tv_subconnector; 723 int i; 724 725 if (dev->mode_config.tv_select_subconnector_property) 726 return 0; 727 728 /* 729 * Basic connector properties 730 */ 731 tv_selector = drm_property_create_enum(dev, 0, 732 "select subconnector", 733 drm_tv_select_enum_list, 734 ARRAY_SIZE(drm_tv_select_enum_list)); 735 dev->mode_config.tv_select_subconnector_property = tv_selector; 736 737 tv_subconnector = 738 drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, 739 "subconnector", 740 drm_tv_subconnector_enum_list, 741 ARRAY_SIZE(drm_tv_subconnector_enum_list)); 742 dev->mode_config.tv_subconnector_property = tv_subconnector; 743 744 /* 745 * Other, TV specific properties: margins & TV modes. 746 */ 747 dev->mode_config.tv_left_margin_property = 748 drm_property_create_range(dev, 0, "left margin", 0, 100); 749 750 dev->mode_config.tv_right_margin_property = 751 drm_property_create_range(dev, 0, "right margin", 0, 100); 752 753 dev->mode_config.tv_top_margin_property = 754 drm_property_create_range(dev, 0, "top margin", 0, 100); 755 756 dev->mode_config.tv_bottom_margin_property = 757 drm_property_create_range(dev, 0, "bottom margin", 0, 100); 758 759 dev->mode_config.tv_mode_property = 760 drm_property_create(dev, DRM_MODE_PROP_ENUM, 761 "mode", num_modes); 762 for (i = 0; i < num_modes; i++) 763 drm_property_add_enum(dev->mode_config.tv_mode_property, i, 764 i, modes[i]); 765 766 dev->mode_config.tv_brightness_property = 767 drm_property_create_range(dev, 0, "brightness", 0, 100); 768 769 dev->mode_config.tv_contrast_property = 770 drm_property_create_range(dev, 0, "contrast", 0, 100); 771 772 dev->mode_config.tv_flicker_reduction_property = 773 drm_property_create_range(dev, 0, "flicker reduction", 0, 100); 774 775 dev->mode_config.tv_overscan_property = 776 drm_property_create_range(dev, 0, "overscan", 0, 100); 777 778 dev->mode_config.tv_saturation_property = 779 drm_property_create_range(dev, 0, "saturation", 0, 100); 780 781 dev->mode_config.tv_hue_property = 782 drm_property_create_range(dev, 0, "hue", 0, 100); 783 784 return 0; 785} 786EXPORT_SYMBOL(drm_mode_create_tv_properties); 787 788/** 789 * drm_mode_create_scaling_mode_property - create scaling mode property 790 * @dev: DRM device 791 * 792 * Called by a driver the first time it's needed, must be attached to desired 793 * connectors. 794 */ 795int drm_mode_create_scaling_mode_property(struct drm_device *dev) 796{ 797 struct drm_property *scaling_mode; 798 799 if (dev->mode_config.scaling_mode_property) 800 return 0; 801 802 scaling_mode = 803 drm_property_create_enum(dev, 0, "scaling mode", 804 drm_scaling_mode_enum_list, 805 ARRAY_SIZE(drm_scaling_mode_enum_list)); 806 807 dev->mode_config.scaling_mode_property = scaling_mode; 808 809 return 0; 810} 811EXPORT_SYMBOL(drm_mode_create_scaling_mode_property); 812 813/** 814 * drm_mode_create_dithering_property - create dithering property 815 * @dev: DRM device 816 * 817 * Called by a driver the first time it's needed, must be attached to desired 818 * connectors. 819 */ 820int drm_mode_create_dithering_property(struct drm_device *dev) 821{ 822 struct drm_property *dithering_mode; 823 824 if (dev->mode_config.dithering_mode_property) 825 return 0; 826 827 dithering_mode = 828 drm_property_create_enum(dev, 0, "dithering", 829 drm_dithering_mode_enum_list, 830 ARRAY_SIZE(drm_dithering_mode_enum_list)); 831 dev->mode_config.dithering_mode_property = dithering_mode; 832 833 return 0; 834} 835EXPORT_SYMBOL(drm_mode_create_dithering_property); 836 837/** 838 * drm_mode_create_dirty_property - create dirty property 839 * @dev: DRM device 840 * 841 * Called by a driver the first time it's needed, must be attached to desired 842 * connectors. 843 */ 844int drm_mode_create_dirty_info_property(struct drm_device *dev) 845{ 846 struct drm_property *dirty_info; 847 848 if (dev->mode_config.dirty_info_property) 849 return 0; 850 851 dirty_info = 852 drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, 853 "dirty", 854 drm_dirty_info_enum_list, 855 ARRAY_SIZE(drm_dirty_info_enum_list)); 856 dev->mode_config.dirty_info_property = dirty_info; 857 858 return 0; 859} 860EXPORT_SYMBOL(drm_mode_create_dirty_info_property); 861 862/** 863 * drm_mode_config_init - initialize DRM mode_configuration structure 864 * @dev: DRM device 865 * 866 * LOCKING: 867 * None, should happen single threaded at init time. 868 * 869 * Initialize @dev's mode_config structure, used for tracking the graphics 870 * configuration of @dev. 871 */ 872void drm_mode_config_init(struct drm_device *dev) 873{ 874 mutex_init(&dev->mode_config.mutex); 875 mutex_init(&dev->mode_config.idr_mutex); 876 INIT_LIST_HEAD(&dev->mode_config.fb_list); 877 INIT_LIST_HEAD(&dev->mode_config.crtc_list); 878 INIT_LIST_HEAD(&dev->mode_config.connector_list); 879 INIT_LIST_HEAD(&dev->mode_config.encoder_list); 880 INIT_LIST_HEAD(&dev->mode_config.property_list); 881 INIT_LIST_HEAD(&dev->mode_config.property_blob_list); 882 INIT_LIST_HEAD(&dev->mode_config.plane_list); 883 idr_init(&dev->mode_config.crtc_idr); 884 885 mutex_lock(&dev->mode_config.mutex); 886 drm_mode_create_standard_connector_properties(dev); 887 mutex_unlock(&dev->mode_config.mutex); 888 889 /* Just to be sure */ 890 dev->mode_config.num_fb = 0; 891 dev->mode_config.num_connector = 0; 892 dev->mode_config.num_crtc = 0; 893 dev->mode_config.num_encoder = 0; 894} 895EXPORT_SYMBOL(drm_mode_config_init); 896 897int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group) 898{ 899 uint32_t total_objects = 0; 900 901 total_objects += dev->mode_config.num_crtc; 902 total_objects += dev->mode_config.num_connector; 903 total_objects += dev->mode_config.num_encoder; 904 905 group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL); 906 if (!group->id_list) 907 return -ENOMEM; 908 909 group->num_crtcs = 0; 910 group->num_connectors = 0; 911 group->num_encoders = 0; 912 return 0; 913} 914 915int drm_mode_group_init_legacy_group(struct drm_device *dev, 916 struct drm_mode_group *group) 917{ 918 struct drm_crtc *crtc; 919 struct drm_encoder *encoder; 920 struct drm_connector *connector; 921 int ret; 922 923 if ((ret = drm_mode_group_init(dev, group))) 924 return ret; 925 926 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) 927 group->id_list[group->num_crtcs++] = crtc->base.id; 928 929 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) 930 group->id_list[group->num_crtcs + group->num_encoders++] = 931 encoder->base.id; 932 933 list_for_each_entry(connector, &dev->mode_config.connector_list, head) 934 group->id_list[group->num_crtcs + group->num_encoders + 935 group->num_connectors++] = connector->base.id; 936 937 return 0; 938} 939 940/** 941 * drm_mode_config_cleanup - free up DRM mode_config info 942 * @dev: DRM device 943 * 944 * LOCKING: 945 * Caller must hold mode config lock. 946 * 947 * Free up all the connectors and CRTCs associated with this DRM device, then 948 * free up the framebuffers and associated buffer objects. 949 * 950 * FIXME: cleanup any dangling user buffer objects too 951 */ 952void drm_mode_config_cleanup(struct drm_device *dev) 953{ 954 struct drm_connector *connector, *ot; 955 struct drm_crtc *crtc, *ct; 956 struct drm_encoder *encoder, *enct; 957 struct drm_framebuffer *fb, *fbt; 958 struct drm_property *property, *pt; 959 struct drm_plane *plane, *plt; 960 961 list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list, 962 head) { 963 encoder->funcs->destroy(encoder); 964 } 965 966 list_for_each_entry_safe(connector, ot, 967 &dev->mode_config.connector_list, head) { 968 connector->funcs->destroy(connector); 969 } 970 971 list_for_each_entry_safe(property, pt, &dev->mode_config.property_list, 972 head) { 973 drm_property_destroy(dev, property); 974 } 975 976 list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) { 977 fb->funcs->destroy(fb); 978 } 979 980 list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) { 981 crtc->funcs->destroy(crtc); 982 } 983 984 list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list, 985 head) { 986 plane->funcs->destroy(plane); 987 } 988 989 idr_remove_all(&dev->mode_config.crtc_idr); 990 idr_destroy(&dev->mode_config.crtc_idr); 991} 992EXPORT_SYMBOL(drm_mode_config_cleanup); 993 994/** 995 * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo 996 * @out: drm_mode_modeinfo struct to return to the user 997 * @in: drm_display_mode to use 998 * 999 * LOCKING: 1000 * None. 1001 * 1002 * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to 1003 * the user. 1004 */ 1005void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out, 1006 struct drm_display_mode *in) 1007{ 1008 WARN(in->hdisplay > USHRT_MAX || in->hsync_start > USHRT_MAX || 1009 in->hsync_end > USHRT_MAX || in->htotal > USHRT_MAX || 1010 in->hskew > USHRT_MAX || in->vdisplay > USHRT_MAX || 1011 in->vsync_start > USHRT_MAX || in->vsync_end > USHRT_MAX || 1012 in->vtotal > USHRT_MAX || in->vscan > USHRT_MAX, 1013 "timing values too large for mode info\n"); 1014 1015 out->clock = in->clock; 1016 out->hdisplay = in->hdisplay; 1017 out->hsync_start = in->hsync_start; 1018 out->hsync_end = in->hsync_end; 1019 out->htotal = in->htotal; 1020 out->hskew = in->hskew; 1021 out->vdisplay = in->vdisplay; 1022 out->vsync_start = in->vsync_start; 1023 out->vsync_end = in->vsync_end; 1024 out->vtotal = in->vtotal; 1025 out->vscan = in->vscan; 1026 out->vrefresh = in->vrefresh; 1027 out->flags = in->flags; 1028 out->type = in->type; 1029 strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN); 1030 out->name[DRM_DISPLAY_MODE_LEN-1] = 0; 1031} 1032 1033/** 1034 * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode 1035 * @out: drm_display_mode to return to the user 1036 * @in: drm_mode_modeinfo to use 1037 * 1038 * LOCKING: 1039 * None. 1040 * 1041 * Convert a drm_mode_modeinfo into a drm_display_mode structure to return to 1042 * the caller. 1043 * 1044 * RETURNS: 1045 * Zero on success, errno on failure. 1046 */ 1047int drm_crtc_convert_umode(struct drm_display_mode *out, 1048 struct drm_mode_modeinfo *in) 1049{ 1050 if (in->clock > INT_MAX || in->vrefresh > INT_MAX) 1051 return -ERANGE; 1052 1053 out->clock = in->clock; 1054 out->hdisplay = in->hdisplay; 1055 out->hsync_start = in->hsync_start; 1056 out->hsync_end = in->hsync_end; 1057 out->htotal = in->htotal; 1058 out->hskew = in->hskew; 1059 out->vdisplay = in->vdisplay; 1060 out->vsync_start = in->vsync_start; 1061 out->vsync_end = in->vsync_end; 1062 out->vtotal = in->vtotal; 1063 out->vscan = in->vscan; 1064 out->vrefresh = in->vrefresh; 1065 out->flags = in->flags; 1066 out->type = in->type; 1067 strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN); 1068 out->name[DRM_DISPLAY_MODE_LEN-1] = 0; 1069 1070 return 0; 1071} 1072 1073/** 1074 * drm_mode_getresources - get graphics configuration 1075 * @inode: inode from the ioctl 1076 * @filp: file * from the ioctl 1077 * @cmd: cmd from ioctl 1078 * @arg: arg from ioctl 1079 * 1080 * LOCKING: 1081 * Takes mode config lock. 1082 * 1083 * Construct a set of configuration description structures and return 1084 * them to the user, including CRTC, connector and framebuffer configuration. 1085 * 1086 * Called by the user via ioctl. 1087 * 1088 * RETURNS: 1089 * Zero on success, errno on failure. 1090 */ 1091int drm_mode_getresources(struct drm_device *dev, void *data, 1092 struct drm_file *file_priv) 1093{ 1094 struct drm_mode_card_res *card_res = data; 1095 struct list_head *lh; 1096 struct drm_framebuffer *fb; 1097 struct drm_connector *connector; 1098 struct drm_crtc *crtc; 1099 struct drm_encoder *encoder; 1100 int ret = 0; 1101 int connector_count = 0; 1102 int crtc_count = 0; 1103 int fb_count = 0; 1104 int encoder_count = 0; 1105 int copied = 0, i; 1106 uint32_t __user *fb_id; 1107 uint32_t __user *crtc_id; 1108 uint32_t __user *connector_id; 1109 uint32_t __user *encoder_id; 1110 struct drm_mode_group *mode_group; 1111 1112 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1113 return -EINVAL; 1114 1115 mutex_lock(&dev->mode_config.mutex); 1116 1117 /* 1118 * For the non-control nodes we need to limit the list of resources 1119 * by IDs in the group list for this node 1120 */ 1121 list_for_each(lh, &file_priv->fbs) 1122 fb_count++; 1123 1124 mode_group = &file_priv->master->minor->mode_group; 1125 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { 1126 1127 list_for_each(lh, &dev->mode_config.crtc_list) 1128 crtc_count++; 1129 1130 list_for_each(lh, &dev->mode_config.connector_list) 1131 connector_count++; 1132 1133 list_for_each(lh, &dev->mode_config.encoder_list) 1134 encoder_count++; 1135 } else { 1136 1137 crtc_count = mode_group->num_crtcs; 1138 connector_count = mode_group->num_connectors; 1139 encoder_count = mode_group->num_encoders; 1140 } 1141 1142 card_res->max_height = dev->mode_config.max_height; 1143 card_res->min_height = dev->mode_config.min_height; 1144 card_res->max_width = dev->mode_config.max_width; 1145 card_res->min_width = dev->mode_config.min_width; 1146 1147 /* handle this in 4 parts */ 1148 /* FBs */ 1149 if (card_res->count_fbs >= fb_count) { 1150 copied = 0; 1151 fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr; 1152 list_for_each_entry(fb, &file_priv->fbs, filp_head) { 1153 if (put_user(fb->base.id, fb_id + copied)) { 1154 ret = -EFAULT; 1155 goto out; 1156 } 1157 copied++; 1158 } 1159 } 1160 card_res->count_fbs = fb_count; 1161 1162 /* CRTCs */ 1163 if (card_res->count_crtcs >= crtc_count) { 1164 copied = 0; 1165 crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr; 1166 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { 1167 list_for_each_entry(crtc, &dev->mode_config.crtc_list, 1168 head) { 1169 DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); 1170 if (put_user(crtc->base.id, crtc_id + copied)) { 1171 ret = -EFAULT; 1172 goto out; 1173 } 1174 copied++; 1175 } 1176 } else { 1177 for (i = 0; i < mode_group->num_crtcs; i++) { 1178 if (put_user(mode_group->id_list[i], 1179 crtc_id + copied)) { 1180 ret = -EFAULT; 1181 goto out; 1182 } 1183 copied++; 1184 } 1185 } 1186 } 1187 card_res->count_crtcs = crtc_count; 1188 1189 /* Encoders */ 1190 if (card_res->count_encoders >= encoder_count) { 1191 copied = 0; 1192 encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr; 1193 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { 1194 list_for_each_entry(encoder, 1195 &dev->mode_config.encoder_list, 1196 head) { 1197 DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", encoder->base.id, 1198 drm_get_encoder_name(encoder)); 1199 if (put_user(encoder->base.id, encoder_id + 1200 copied)) { 1201 ret = -EFAULT; 1202 goto out; 1203 } 1204 copied++; 1205 } 1206 } else { 1207 for (i = mode_group->num_crtcs; i < mode_group->num_crtcs + mode_group->num_encoders; i++) { 1208 if (put_user(mode_group->id_list[i], 1209 encoder_id + copied)) { 1210 ret = -EFAULT; 1211 goto out; 1212 } 1213 copied++; 1214 } 1215 1216 } 1217 } 1218 card_res->count_encoders = encoder_count; 1219 1220 /* Connectors */ 1221 if (card_res->count_connectors >= connector_count) { 1222 copied = 0; 1223 connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr; 1224 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { 1225 list_for_each_entry(connector, 1226 &dev->mode_config.connector_list, 1227 head) { 1228 DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", 1229 connector->base.id, 1230 drm_get_connector_name(connector)); 1231 if (put_user(connector->base.id, 1232 connector_id + copied)) { 1233 ret = -EFAULT; 1234 goto out; 1235 } 1236 copied++; 1237 } 1238 } else { 1239 int start = mode_group->num_crtcs + 1240 mode_group->num_encoders; 1241 for (i = start; i < start + mode_group->num_connectors; i++) { 1242 if (put_user(mode_group->id_list[i], 1243 connector_id + copied)) { 1244 ret = -EFAULT; 1245 goto out; 1246 } 1247 copied++; 1248 } 1249 } 1250 } 1251 card_res->count_connectors = connector_count; 1252 1253 DRM_DEBUG_KMS("CRTC[%d] CONNECTORS[%d] ENCODERS[%d]\n", card_res->count_crtcs, 1254 card_res->count_connectors, card_res->count_encoders); 1255 1256out: 1257 mutex_unlock(&dev->mode_config.mutex); 1258 return ret; 1259} 1260 1261/** 1262 * drm_mode_getcrtc - get CRTC configuration 1263 * @inode: inode from the ioctl 1264 * @filp: file * from the ioctl 1265 * @cmd: cmd from ioctl 1266 * @arg: arg from ioctl 1267 * 1268 * LOCKING: 1269 * Takes mode config lock. 1270 * 1271 * Construct a CRTC configuration structure to return to the user. 1272 * 1273 * Called by the user via ioctl. 1274 * 1275 * RETURNS: 1276 * Zero on success, errno on failure. 1277 */ 1278int drm_mode_getcrtc(struct drm_device *dev, 1279 void *data, struct drm_file *file_priv) 1280{ 1281 struct drm_mode_crtc *crtc_resp = data; 1282 struct drm_crtc *crtc; 1283 struct drm_mode_object *obj; 1284 int ret = 0; 1285 1286 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1287 return -EINVAL; 1288 1289 mutex_lock(&dev->mode_config.mutex); 1290 1291 obj = drm_mode_object_find(dev, crtc_resp->crtc_id, 1292 DRM_MODE_OBJECT_CRTC); 1293 if (!obj) { 1294 ret = -EINVAL; 1295 goto out; 1296 } 1297 crtc = obj_to_crtc(obj); 1298 1299 crtc_resp->x = crtc->x; 1300 crtc_resp->y = crtc->y; 1301 crtc_resp->gamma_size = crtc->gamma_size; 1302 if (crtc->fb) 1303 crtc_resp->fb_id = crtc->fb->base.id; 1304 else 1305 crtc_resp->fb_id = 0; 1306 1307 if (crtc->enabled) { 1308 1309 drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode); 1310 crtc_resp->mode_valid = 1; 1311 1312 } else { 1313 crtc_resp->mode_valid = 0; 1314 } 1315 1316out: 1317 mutex_unlock(&dev->mode_config.mutex); 1318 return ret; 1319} 1320 1321/** 1322 * drm_mode_getconnector - get connector configuration 1323 * @inode: inode from the ioctl 1324 * @filp: file * from the ioctl 1325 * @cmd: cmd from ioctl 1326 * @arg: arg from ioctl 1327 * 1328 * LOCKING: 1329 * Takes mode config lock. 1330 * 1331 * Construct a connector configuration structure to return to the user. 1332 * 1333 * Called by the user via ioctl. 1334 * 1335 * RETURNS: 1336 * Zero on success, errno on failure. 1337 */ 1338int drm_mode_getconnector(struct drm_device *dev, void *data, 1339 struct drm_file *file_priv) 1340{ 1341 struct drm_mode_get_connector *out_resp = data; 1342 struct drm_mode_object *obj; 1343 struct drm_connector *connector; 1344 struct drm_display_mode *mode; 1345 int mode_count = 0; 1346 int props_count = 0; 1347 int encoders_count = 0; 1348 int ret = 0; 1349 int copied = 0; 1350 int i; 1351 struct drm_mode_modeinfo u_mode; 1352 struct drm_mode_modeinfo __user *mode_ptr; 1353 uint32_t __user *prop_ptr; 1354 uint64_t __user *prop_values; 1355 uint32_t __user *encoder_ptr; 1356 1357 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1358 return -EINVAL; 1359 1360 memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo)); 1361 1362 DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id); 1363 1364 mutex_lock(&dev->mode_config.mutex); 1365 1366 obj = drm_mode_object_find(dev, out_resp->connector_id, 1367 DRM_MODE_OBJECT_CONNECTOR); 1368 if (!obj) { 1369 ret = -EINVAL; 1370 goto out; 1371 } 1372 connector = obj_to_connector(obj); 1373 1374 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { 1375 if (connector->property_ids[i] != 0) { 1376 props_count++; 1377 } 1378 } 1379 1380 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 1381 if (connector->encoder_ids[i] != 0) { 1382 encoders_count++; 1383 } 1384 } 1385 1386 if (out_resp->count_modes == 0) { 1387 connector->funcs->fill_modes(connector, 1388 dev->mode_config.max_width, 1389 dev->mode_config.max_height); 1390 } 1391 1392 /* delayed so we get modes regardless of pre-fill_modes state */ 1393 list_for_each_entry(mode, &connector->modes, head) 1394 mode_count++; 1395 1396 out_resp->connector_id = connector->base.id; 1397 out_resp->connector_type = connector->connector_type; 1398 out_resp->connector_type_id = connector->connector_type_id; 1399 out_resp->mm_width = connector->display_info.width_mm; 1400 out_resp->mm_height = connector->display_info.height_mm; 1401 out_resp->subpixel = connector->display_info.subpixel_order; 1402 out_resp->connection = connector->status; 1403 if (connector->encoder) 1404 out_resp->encoder_id = connector->encoder->base.id; 1405 else 1406 out_resp->encoder_id = 0; 1407 1408 /* 1409 * This ioctl is called twice, once to determine how much space is 1410 * needed, and the 2nd time to fill it. 1411 */ 1412 if ((out_resp->count_modes >= mode_count) && mode_count) { 1413 copied = 0; 1414 mode_ptr = (struct drm_mode_modeinfo __user *)(unsigned long)out_resp->modes_ptr; 1415 list_for_each_entry(mode, &connector->modes, head) { 1416 drm_crtc_convert_to_umode(&u_mode, mode); 1417 if (copy_to_user(mode_ptr + copied, 1418 &u_mode, sizeof(u_mode))) { 1419 ret = -EFAULT; 1420 goto out; 1421 } 1422 copied++; 1423 } 1424 } 1425 out_resp->count_modes = mode_count; 1426 1427 if ((out_resp->count_props >= props_count) && props_count) { 1428 copied = 0; 1429 prop_ptr = (uint32_t __user *)(unsigned long)(out_resp->props_ptr); 1430 prop_values = (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr); 1431 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { 1432 if (connector->property_ids[i] != 0) { 1433 if (put_user(connector->property_ids[i], 1434 prop_ptr + copied)) { 1435 ret = -EFAULT; 1436 goto out; 1437 } 1438 1439 if (put_user(connector->property_values[i], 1440 prop_values + copied)) { 1441 ret = -EFAULT; 1442 goto out; 1443 } 1444 copied++; 1445 } 1446 } 1447 } 1448 out_resp->count_props = props_count; 1449 1450 if ((out_resp->count_encoders >= encoders_count) && encoders_count) { 1451 copied = 0; 1452 encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr); 1453 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 1454 if (connector->encoder_ids[i] != 0) { 1455 if (put_user(connector->encoder_ids[i], 1456 encoder_ptr + copied)) { 1457 ret = -EFAULT; 1458 goto out; 1459 } 1460 copied++; 1461 } 1462 } 1463 } 1464 out_resp->count_encoders = encoders_count; 1465 1466out: 1467 mutex_unlock(&dev->mode_config.mutex); 1468 return ret; 1469} 1470 1471int drm_mode_getencoder(struct drm_device *dev, void *data, 1472 struct drm_file *file_priv) 1473{ 1474 struct drm_mode_get_encoder *enc_resp = data; 1475 struct drm_mode_object *obj; 1476 struct drm_encoder *encoder; 1477 int ret = 0; 1478 1479 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1480 return -EINVAL; 1481 1482 mutex_lock(&dev->mode_config.mutex); 1483 obj = drm_mode_object_find(dev, enc_resp->encoder_id, 1484 DRM_MODE_OBJECT_ENCODER); 1485 if (!obj) { 1486 ret = -EINVAL; 1487 goto out; 1488 } 1489 encoder = obj_to_encoder(obj); 1490 1491 if (encoder->crtc) 1492 enc_resp->crtc_id = encoder->crtc->base.id; 1493 else 1494 enc_resp->crtc_id = 0; 1495 enc_resp->encoder_type = encoder->encoder_type; 1496 enc_resp->encoder_id = encoder->base.id; 1497 enc_resp->possible_crtcs = encoder->possible_crtcs; 1498 enc_resp->possible_clones = encoder->possible_clones; 1499 1500out: 1501 mutex_unlock(&dev->mode_config.mutex); 1502 return ret; 1503} 1504 1505/** 1506 * drm_mode_getplane_res - get plane info 1507 * @dev: DRM device 1508 * @data: ioctl data 1509 * @file_priv: DRM file info 1510 * 1511 * LOCKING: 1512 * Takes mode config lock. 1513 * 1514 * Return an plane count and set of IDs. 1515 */ 1516int drm_mode_getplane_res(struct drm_device *dev, void *data, 1517 struct drm_file *file_priv) 1518{ 1519 struct drm_mode_get_plane_res *plane_resp = data; 1520 struct drm_mode_config *config; 1521 struct drm_plane *plane; 1522 uint32_t __user *plane_ptr; 1523 int copied = 0, ret = 0; 1524 1525 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1526 return -EINVAL; 1527 1528 mutex_lock(&dev->mode_config.mutex); 1529 config = &dev->mode_config; 1530 1531 /* 1532 * This ioctl is called twice, once to determine how much space is 1533 * needed, and the 2nd time to fill it. 1534 */ 1535 if (config->num_plane && 1536 (plane_resp->count_planes >= config->num_plane)) { 1537 plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr; 1538 1539 list_for_each_entry(plane, &config->plane_list, head) { 1540 if (put_user(plane->base.id, plane_ptr + copied)) { 1541 ret = -EFAULT; 1542 goto out; 1543 } 1544 copied++; 1545 } 1546 } 1547 plane_resp->count_planes = config->num_plane; 1548 1549out: 1550 mutex_unlock(&dev->mode_config.mutex); 1551 return ret; 1552} 1553 1554/** 1555 * drm_mode_getplane - get plane info 1556 * @dev: DRM device 1557 * @data: ioctl data 1558 * @file_priv: DRM file info 1559 * 1560 * LOCKING: 1561 * Takes mode config lock. 1562 * 1563 * Return plane info, including formats supported, gamma size, any 1564 * current fb, etc. 1565 */ 1566int drm_mode_getplane(struct drm_device *dev, void *data, 1567 struct drm_file *file_priv) 1568{ 1569 struct drm_mode_get_plane *plane_resp = data; 1570 struct drm_mode_object *obj; 1571 struct drm_plane *plane; 1572 uint32_t __user *format_ptr; 1573 int ret = 0; 1574 1575 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1576 return -EINVAL; 1577 1578 mutex_lock(&dev->mode_config.mutex); 1579 obj = drm_mode_object_find(dev, plane_resp->plane_id, 1580 DRM_MODE_OBJECT_PLANE); 1581 if (!obj) { 1582 ret = -ENOENT; 1583 goto out; 1584 } 1585 plane = obj_to_plane(obj); 1586 1587 if (plane->crtc) 1588 plane_resp->crtc_id = plane->crtc->base.id; 1589 else 1590 plane_resp->crtc_id = 0; 1591 1592 if (plane->fb) 1593 plane_resp->fb_id = plane->fb->base.id; 1594 else 1595 plane_resp->fb_id = 0; 1596 1597 plane_resp->plane_id = plane->base.id; 1598 plane_resp->possible_crtcs = plane->possible_crtcs; 1599 plane_resp->gamma_size = plane->gamma_size; 1600 1601 /* 1602 * This ioctl is called twice, once to determine how much space is 1603 * needed, and the 2nd time to fill it. 1604 */ 1605 if (plane->format_count && 1606 (plane_resp->count_format_types >= plane->format_count)) { 1607 format_ptr = (uint32_t __user *)(unsigned long)plane_resp->format_type_ptr; 1608 if (copy_to_user(format_ptr, 1609 plane->format_types, 1610 sizeof(uint32_t) * plane->format_count)) { 1611 ret = -EFAULT; 1612 goto out; 1613 } 1614 } 1615 plane_resp->count_format_types = plane->format_count; 1616 1617out: 1618 mutex_unlock(&dev->mode_config.mutex); 1619 return ret; 1620} 1621 1622/** 1623 * drm_mode_setplane - set up or tear down an plane 1624 * @dev: DRM device 1625 * @data: ioctl data* 1626 * @file_prive: DRM file info 1627 * 1628 * LOCKING: 1629 * Takes mode config lock. 1630 * 1631 * Set plane info, including placement, fb, scaling, and other factors. 1632 * Or pass a NULL fb to disable. 1633 */ 1634int drm_mode_setplane(struct drm_device *dev, void *data, 1635 struct drm_file *file_priv) 1636{ 1637 struct drm_mode_set_plane *plane_req = data; 1638 struct drm_mode_object *obj; 1639 struct drm_plane *plane; 1640 struct drm_crtc *crtc; 1641 struct drm_framebuffer *fb; 1642 int ret = 0; 1643 unsigned int fb_width, fb_height; 1644 int i; 1645 1646 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1647 return -EINVAL; 1648 1649 mutex_lock(&dev->mode_config.mutex); 1650 1651 /* 1652 * First, find the plane, crtc, and fb objects. If not available, 1653 * we don't bother to call the driver. 1654 */ 1655 obj = drm_mode_object_find(dev, plane_req->plane_id, 1656 DRM_MODE_OBJECT_PLANE); 1657 if (!obj) { 1658 DRM_DEBUG_KMS("Unknown plane ID %d\n", 1659 plane_req->plane_id); 1660 ret = -ENOENT; 1661 goto out; 1662 } 1663 plane = obj_to_plane(obj); 1664 1665 /* No fb means shut it down */ 1666 if (!plane_req->fb_id) { 1667 plane->funcs->disable_plane(plane); 1668 plane->crtc = NULL; 1669 plane->fb = NULL; 1670 goto out; 1671 } 1672 1673 obj = drm_mode_object_find(dev, plane_req->crtc_id, 1674 DRM_MODE_OBJECT_CRTC); 1675 if (!obj) { 1676 DRM_DEBUG_KMS("Unknown crtc ID %d\n", 1677 plane_req->crtc_id); 1678 ret = -ENOENT; 1679 goto out; 1680 } 1681 crtc = obj_to_crtc(obj); 1682 1683 obj = drm_mode_object_find(dev, plane_req->fb_id, 1684 DRM_MODE_OBJECT_FB); 1685 if (!obj) { 1686 DRM_DEBUG_KMS("Unknown framebuffer ID %d\n", 1687 plane_req->fb_id); 1688 ret = -ENOENT; 1689 goto out; 1690 } 1691 fb = obj_to_fb(obj); 1692 1693 /* Check whether this plane supports the fb pixel format. */ 1694 for (i = 0; i < plane->format_count; i++) 1695 if (fb->pixel_format == plane->format_types[i]) 1696 break; 1697 if (i == plane->format_count) { 1698 DRM_DEBUG_KMS("Invalid pixel format 0x%08x\n", fb->pixel_format); 1699 ret = -EINVAL; 1700 goto out; 1701 } 1702 1703 fb_width = fb->width << 16; 1704 fb_height = fb->height << 16; 1705 1706 /* Make sure source coordinates are inside the fb. */ 1707 if (plane_req->src_w > fb_width || 1708 plane_req->src_x > fb_width - plane_req->src_w || 1709 plane_req->src_h > fb_height || 1710 plane_req->src_y > fb_height - plane_req->src_h) { 1711 DRM_DEBUG_KMS("Invalid source coordinates " 1712 "%u.%06ux%u.%06u+%u.%06u+%u.%06u\n", 1713 plane_req->src_w >> 16, 1714 ((plane_req->src_w & 0xffff) * 15625) >> 10, 1715 plane_req->src_h >> 16, 1716 ((plane_req->src_h & 0xffff) * 15625) >> 10, 1717 plane_req->src_x >> 16, 1718 ((plane_req->src_x & 0xffff) * 15625) >> 10, 1719 plane_req->src_y >> 16, 1720 ((plane_req->src_y & 0xffff) * 15625) >> 10); 1721 ret = -ENOSPC; 1722 goto out; 1723 } 1724 1725 /* Give drivers some help against integer overflows */ 1726 if (plane_req->crtc_w > INT_MAX || 1727 plane_req->crtc_x > INT_MAX - (int32_t) plane_req->crtc_w || 1728 plane_req->crtc_h > INT_MAX || 1729 plane_req->crtc_y > INT_MAX - (int32_t) plane_req->crtc_h) { 1730 DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n", 1731 plane_req->crtc_w, plane_req->crtc_h, 1732 plane_req->crtc_x, plane_req->crtc_y); 1733 ret = -ERANGE; 1734 goto out; 1735 } 1736 1737 ret = plane->funcs->update_plane(plane, crtc, fb, 1738 plane_req->crtc_x, plane_req->crtc_y, 1739 plane_req->crtc_w, plane_req->crtc_h, 1740 plane_req->src_x, plane_req->src_y, 1741 plane_req->src_w, plane_req->src_h); 1742 if (!ret) { 1743 plane->crtc = crtc; 1744 plane->fb = fb; 1745 } 1746 1747out: 1748 mutex_unlock(&dev->mode_config.mutex); 1749 1750 return ret; 1751} 1752 1753/** 1754 * drm_mode_setcrtc - set CRTC configuration 1755 * @inode: inode from the ioctl 1756 * @filp: file * from the ioctl 1757 * @cmd: cmd from ioctl 1758 * @arg: arg from ioctl 1759 * 1760 * LOCKING: 1761 * Takes mode config lock. 1762 * 1763 * Build a new CRTC configuration based on user request. 1764 * 1765 * Called by the user via ioctl. 1766 * 1767 * RETURNS: 1768 * Zero on success, errno on failure. 1769 */ 1770int drm_mode_setcrtc(struct drm_device *dev, void *data, 1771 struct drm_file *file_priv) 1772{ 1773 struct drm_mode_config *config = &dev->mode_config; 1774 struct drm_mode_crtc *crtc_req = data; 1775 struct drm_mode_object *obj; 1776 struct drm_crtc *crtc; 1777 struct drm_connector **connector_set = NULL, *connector; 1778 struct drm_framebuffer *fb = NULL; 1779 struct drm_display_mode *mode = NULL; 1780 struct drm_mode_set set; 1781 uint32_t __user *set_connectors_ptr; 1782 int ret = 0; 1783 int i; 1784 1785 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1786 return -EINVAL; 1787 1788 /* For some reason crtc x/y offsets are signed internally. */ 1789 if (crtc_req->x > INT_MAX || crtc_req->y > INT_MAX) 1790 return -ERANGE; 1791 1792 mutex_lock(&dev->mode_config.mutex); 1793 obj = drm_mode_object_find(dev, crtc_req->crtc_id, 1794 DRM_MODE_OBJECT_CRTC); 1795 if (!obj) { 1796 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id); 1797 ret = -EINVAL; 1798 goto out; 1799 } 1800 crtc = obj_to_crtc(obj); 1801 DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); 1802 1803 if (crtc_req->mode_valid) { 1804 /* If we have a mode we need a framebuffer. */ 1805 /* If we pass -1, set the mode with the currently bound fb */ 1806 if (crtc_req->fb_id == -1) { 1807 if (!crtc->fb) { 1808 DRM_DEBUG_KMS("CRTC doesn't have current FB\n"); 1809 ret = -EINVAL; 1810 goto out; 1811 } 1812 fb = crtc->fb; 1813 } else { 1814 obj = drm_mode_object_find(dev, crtc_req->fb_id, 1815 DRM_MODE_OBJECT_FB); 1816 if (!obj) { 1817 DRM_DEBUG_KMS("Unknown FB ID%d\n", 1818 crtc_req->fb_id); 1819 ret = -EINVAL; 1820 goto out; 1821 } 1822 fb = obj_to_fb(obj); 1823 } 1824 1825 mode = drm_mode_create(dev); 1826 if (!mode) { 1827 ret = -ENOMEM; 1828 goto out; 1829 } 1830 1831 ret = drm_crtc_convert_umode(mode, &crtc_req->mode); 1832 if (ret) { 1833 DRM_DEBUG_KMS("Invalid mode\n"); 1834 goto out; 1835 } 1836 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 drm_mode_destroy(dev, mode); 1906 mutex_unlock(&dev->mode_config.mutex); 1907 return ret; 1908} 1909 1910int drm_mode_cursor_ioctl(struct drm_device *dev, 1911 void *data, struct drm_file *file_priv) 1912{ 1913 struct drm_mode_cursor *req = data; 1914 struct drm_mode_object *obj; 1915 struct drm_crtc *crtc; 1916 int ret = 0; 1917 1918 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 1919 return -EINVAL; 1920 1921 if (!req->flags) 1922 return -EINVAL; 1923 1924 mutex_lock(&dev->mode_config.mutex); 1925 obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC); 1926 if (!obj) { 1927 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id); 1928 ret = -EINVAL; 1929 goto out; 1930 } 1931 crtc = obj_to_crtc(obj); 1932 1933 if (req->flags & DRM_MODE_CURSOR_BO) { 1934 if (!crtc->funcs->cursor_set) { 1935 ret = -ENXIO; 1936 goto out; 1937 } 1938 /* Turns off the cursor if handle is 0 */ 1939 ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle, 1940 req->width, req->height); 1941 } 1942 1943 if (req->flags & DRM_MODE_CURSOR_MOVE) { 1944 if (crtc->funcs->cursor_move) { 1945 ret = crtc->funcs->cursor_move(crtc, req->x, req->y); 1946 } else { 1947 ret = -EFAULT; 1948 goto out; 1949 } 1950 } 1951out: 1952 mutex_unlock(&dev->mode_config.mutex); 1953 return ret; 1954} 1955 1956/* Original addfb only supported RGB formats, so figure out which one */ 1957uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth) 1958{ 1959 uint32_t fmt; 1960 1961 switch (bpp) { 1962 case 8: 1963 fmt = DRM_FORMAT_RGB332; 1964 break; 1965 case 16: 1966 if (depth == 15) 1967 fmt = DRM_FORMAT_XRGB1555; 1968 else 1969 fmt = DRM_FORMAT_RGB565; 1970 break; 1971 case 24: 1972 fmt = DRM_FORMAT_RGB888; 1973 break; 1974 case 32: 1975 if (depth == 24) 1976 fmt = DRM_FORMAT_XRGB8888; 1977 else if (depth == 30) 1978 fmt = DRM_FORMAT_XRGB2101010; 1979 else 1980 fmt = DRM_FORMAT_ARGB8888; 1981 break; 1982 default: 1983 DRM_ERROR("bad bpp, assuming x8r8g8b8 pixel format\n"); 1984 fmt = DRM_FORMAT_XRGB8888; 1985 break; 1986 } 1987 1988 return fmt; 1989} 1990EXPORT_SYMBOL(drm_mode_legacy_fb_format); 1991 1992/** 1993 * drm_mode_addfb - add an FB to the graphics configuration 1994 * @inode: inode from the ioctl 1995 * @filp: file * from the ioctl 1996 * @cmd: cmd from ioctl 1997 * @arg: arg from ioctl 1998 * 1999 * LOCKING: 2000 * Takes mode config lock. 2001 * 2002 * Add a new FB to the specified CRTC, given a user request. 2003 * 2004 * Called by the user via ioctl. 2005 * 2006 * RETURNS: 2007 * Zero on success, errno on failure. 2008 */ 2009int drm_mode_addfb(struct drm_device *dev, 2010 void *data, struct drm_file *file_priv) 2011{ 2012 struct drm_mode_fb_cmd *or = data; 2013 struct drm_mode_fb_cmd2 r = {}; 2014 struct drm_mode_config *config = &dev->mode_config; 2015 struct drm_framebuffer *fb; 2016 int ret = 0; 2017 2018 /* Use new struct with format internally */ 2019 r.fb_id = or->fb_id; 2020 r.width = or->width; 2021 r.height = or->height; 2022 r.pitches[0] = or->pitch; 2023 r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth); 2024 r.handles[0] = or->handle; 2025 2026 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 2027 return -EINVAL; 2028 2029 if ((config->min_width > r.width) || (r.width > config->max_width)) 2030 return -EINVAL; 2031 2032 if ((config->min_height > r.height) || (r.height > config->max_height)) 2033 return -EINVAL; 2034 2035 mutex_lock(&dev->mode_config.mutex); 2036 2037 /* TODO check buffer is sufficiently large */ 2038 /* TODO setup destructor callback */ 2039 2040 fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r); 2041 if (IS_ERR(fb)) { 2042 DRM_ERROR("could not create framebuffer\n"); 2043 ret = PTR_ERR(fb); 2044 goto out; 2045 } 2046 2047 or->fb_id = fb->base.id; 2048 list_add(&fb->filp_head, &file_priv->fbs); 2049 DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); 2050 2051out: 2052 mutex_unlock(&dev->mode_config.mutex); 2053 return ret; 2054} 2055 2056static int format_check(struct drm_mode_fb_cmd2 *r) 2057{ 2058 uint32_t format = r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN; 2059 2060 switch (format) { 2061 case DRM_FORMAT_C8: 2062 case DRM_FORMAT_RGB332: 2063 case DRM_FORMAT_BGR233: 2064 case DRM_FORMAT_XRGB4444: 2065 case DRM_FORMAT_XBGR4444: 2066 case DRM_FORMAT_RGBX4444: 2067 case DRM_FORMAT_BGRX4444: 2068 case DRM_FORMAT_ARGB4444: 2069 case DRM_FORMAT_ABGR4444: 2070 case DRM_FORMAT_RGBA4444: 2071 case DRM_FORMAT_BGRA4444: 2072 case DRM_FORMAT_XRGB1555: 2073 case DRM_FORMAT_XBGR1555: 2074 case DRM_FORMAT_RGBX5551: 2075 case DRM_FORMAT_BGRX5551: 2076 case DRM_FORMAT_ARGB1555: 2077 case DRM_FORMAT_ABGR1555: 2078 case DRM_FORMAT_RGBA5551: 2079 case DRM_FORMAT_BGRA5551: 2080 case DRM_FORMAT_RGB565: 2081 case DRM_FORMAT_BGR565: 2082 case DRM_FORMAT_RGB888: 2083 case DRM_FORMAT_BGR888: 2084 case DRM_FORMAT_XRGB8888: 2085 case DRM_FORMAT_XBGR8888: 2086 case DRM_FORMAT_RGBX8888: 2087 case DRM_FORMAT_BGRX8888: 2088 case DRM_FORMAT_ARGB8888: 2089 case DRM_FORMAT_ABGR8888: 2090 case DRM_FORMAT_RGBA8888: 2091 case DRM_FORMAT_BGRA8888: 2092 case DRM_FORMAT_XRGB2101010: 2093 case DRM_FORMAT_XBGR2101010: 2094 case DRM_FORMAT_RGBX1010102: 2095 case DRM_FORMAT_BGRX1010102: 2096 case DRM_FORMAT_ARGB2101010: 2097 case DRM_FORMAT_ABGR2101010: 2098 case DRM_FORMAT_RGBA1010102: 2099 case DRM_FORMAT_BGRA1010102: 2100 case DRM_FORMAT_YUYV: 2101 case DRM_FORMAT_YVYU: 2102 case DRM_FORMAT_UYVY: 2103 case DRM_FORMAT_VYUY: 2104 case DRM_FORMAT_AYUV: 2105 case DRM_FORMAT_NV12: 2106 case DRM_FORMAT_NV21: 2107 case DRM_FORMAT_NV16: 2108 case DRM_FORMAT_NV61: 2109 case DRM_FORMAT_YUV410: 2110 case DRM_FORMAT_YVU410: 2111 case DRM_FORMAT_YUV411: 2112 case DRM_FORMAT_YVU411: 2113 case DRM_FORMAT_YUV420: 2114 case DRM_FORMAT_YVU420: 2115 case DRM_FORMAT_YUV422: 2116 case DRM_FORMAT_YVU422: 2117 case DRM_FORMAT_YUV444: 2118 case DRM_FORMAT_YVU444: 2119 return 0; 2120 default: 2121 return -EINVAL; 2122 } 2123} 2124 2125/** 2126 * drm_mode_addfb2 - add an FB to the graphics configuration 2127 * @inode: inode from the ioctl 2128 * @filp: file * from the ioctl 2129 * @cmd: cmd from ioctl 2130 * @arg: arg from ioctl 2131 * 2132 * LOCKING: 2133 * Takes mode config lock. 2134 * 2135 * Add a new FB to the specified CRTC, given a user request with format. 2136 * 2137 * Called by the user via ioctl. 2138 * 2139 * RETURNS: 2140 * Zero on success, errno on failure. 2141 */ 2142int drm_mode_addfb2(struct drm_device *dev, 2143 void *data, struct drm_file *file_priv) 2144{ 2145 struct drm_mode_fb_cmd2 *r = data; 2146 struct drm_mode_config *config = &dev->mode_config; 2147 struct drm_framebuffer *fb; 2148 int ret = 0; 2149 2150 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 2151 return -EINVAL; 2152 2153 if ((config->min_width > r->width) || (r->width > config->max_width)) { 2154 DRM_ERROR("bad framebuffer width %d, should be >= %d && <= %d\n", 2155 r->width, config->min_width, config->max_width); 2156 return -EINVAL; 2157 } 2158 if ((config->min_height > r->height) || (r->height > config->max_height)) { 2159 DRM_ERROR("bad framebuffer height %d, should be >= %d && <= %d\n", 2160 r->height, config->min_height, config->max_height); 2161 return -EINVAL; 2162 } 2163 2164 ret = format_check(r); 2165 if (ret) { 2166 DRM_ERROR("bad framebuffer format 0x%08x\n", r->pixel_format); 2167 return ret; 2168 } 2169 2170 mutex_lock(&dev->mode_config.mutex); 2171 2172 fb = dev->mode_config.funcs->fb_create(dev, file_priv, r); 2173 if (IS_ERR(fb)) { 2174 DRM_ERROR("could not create framebuffer\n"); 2175 ret = PTR_ERR(fb); 2176 goto out; 2177 } 2178 2179 r->fb_id = fb->base.id; 2180 list_add(&fb->filp_head, &file_priv->fbs); 2181 DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); 2182 2183out: 2184 mutex_unlock(&dev->mode_config.mutex); 2185 return ret; 2186} 2187 2188/** 2189 * drm_mode_rmfb - remove an FB from the configuration 2190 * @inode: inode from the ioctl 2191 * @filp: file * from the ioctl 2192 * @cmd: cmd from ioctl 2193 * @arg: arg from ioctl 2194 * 2195 * LOCKING: 2196 * Takes mode config lock. 2197 * 2198 * Remove the FB specified by the user. 2199 * 2200 * Called by the user via ioctl. 2201 * 2202 * RETURNS: 2203 * Zero on success, errno on failure. 2204 */ 2205int drm_mode_rmfb(struct drm_device *dev, 2206 void *data, struct drm_file *file_priv) 2207{ 2208 struct drm_mode_object *obj; 2209 struct drm_framebuffer *fb = NULL; 2210 struct drm_framebuffer *fbl = NULL; 2211 uint32_t *id = data; 2212 int ret = 0; 2213 int found = 0; 2214 2215 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 2216 return -EINVAL; 2217 2218 mutex_lock(&dev->mode_config.mutex); 2219 obj = drm_mode_object_find(dev, *id, DRM_MODE_OBJECT_FB); 2220 /* TODO check that we really get a framebuffer back. */ 2221 if (!obj) { 2222 ret = -EINVAL; 2223 goto out; 2224 } 2225 fb = obj_to_fb(obj); 2226 2227 list_for_each_entry(fbl, &file_priv->fbs, filp_head) 2228 if (fb == fbl) 2229 found = 1; 2230 2231 if (!found) { 2232 ret = -EINVAL; 2233 goto out; 2234 } 2235 2236 /* TODO release all crtc connected to the framebuffer */ 2237 /* TODO unhock the destructor from the buffer object */ 2238 2239 list_del(&fb->filp_head); 2240 fb->funcs->destroy(fb); 2241 2242out: 2243 mutex_unlock(&dev->mode_config.mutex); 2244 return ret; 2245} 2246 2247/** 2248 * drm_mode_getfb - get FB info 2249 * @inode: inode from the ioctl 2250 * @filp: file * from the ioctl 2251 * @cmd: cmd from ioctl 2252 * @arg: arg from ioctl 2253 * 2254 * LOCKING: 2255 * Takes mode config lock. 2256 * 2257 * Lookup the FB given its ID and return info about it. 2258 * 2259 * Called by the user via ioctl. 2260 * 2261 * RETURNS: 2262 * Zero on success, errno on failure. 2263 */ 2264int drm_mode_getfb(struct drm_device *dev, 2265 void *data, struct drm_file *file_priv) 2266{ 2267 struct drm_mode_fb_cmd *r = data; 2268 struct drm_mode_object *obj; 2269 struct drm_framebuffer *fb; 2270 int ret = 0; 2271 2272 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 2273 return -EINVAL; 2274 2275 mutex_lock(&dev->mode_config.mutex); 2276 obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB); 2277 if (!obj) { 2278 ret = -EINVAL; 2279 goto out; 2280 } 2281 fb = obj_to_fb(obj); 2282 2283 r->height = fb->height; 2284 r->width = fb->width; 2285 r->depth = fb->depth; 2286 r->bpp = fb->bits_per_pixel; 2287 r->pitch = fb->pitches[0]; 2288 fb->funcs->create_handle(fb, file_priv, &r->handle); 2289 2290out: 2291 mutex_unlock(&dev->mode_config.mutex); 2292 return ret; 2293} 2294 2295int drm_mode_dirtyfb_ioctl(struct drm_device *dev, 2296 void *data, struct drm_file *file_priv) 2297{ 2298 struct drm_clip_rect __user *clips_ptr; 2299 struct drm_clip_rect *clips = NULL; 2300 struct drm_mode_fb_dirty_cmd *r = data; 2301 struct drm_mode_object *obj; 2302 struct drm_framebuffer *fb; 2303 unsigned flags; 2304 int num_clips; 2305 int ret = 0; 2306 2307 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 2308 return -EINVAL; 2309 2310 mutex_lock(&dev->mode_config.mutex); 2311 obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB); 2312 if (!obj) { 2313 ret = -EINVAL; 2314 goto out_err1; 2315 } 2316 fb = obj_to_fb(obj); 2317 2318 num_clips = r->num_clips; 2319 clips_ptr = (struct drm_clip_rect __user *)(unsigned long)r->clips_ptr; 2320 2321 if (!num_clips != !clips_ptr) { 2322 ret = -EINVAL; 2323 goto out_err1; 2324 } 2325 2326 flags = DRM_MODE_FB_DIRTY_FLAGS & r->flags; 2327 2328 /* If userspace annotates copy, clips must come in pairs */ 2329 if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY && (num_clips % 2)) { 2330 ret = -EINVAL; 2331 goto out_err1; 2332 } 2333 2334 if (num_clips && clips_ptr) { 2335 if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) { 2336 ret = -EINVAL; 2337 goto out_err1; 2338 } 2339 clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); 2340 if (!clips) { 2341 ret = -ENOMEM; 2342 goto out_err1; 2343 } 2344 2345 ret = copy_from_user(clips, clips_ptr, 2346 num_clips * sizeof(*clips)); 2347 if (ret) { 2348 ret = -EFAULT; 2349 goto out_err2; 2350 } 2351 } 2352 2353 if (fb->funcs->dirty) { 2354 ret = fb->funcs->dirty(fb, file_priv, flags, r->color, 2355 clips, num_clips); 2356 } else { 2357 ret = -ENOSYS; 2358 goto out_err2; 2359 } 2360 2361out_err2: 2362 kfree(clips); 2363out_err1: 2364 mutex_unlock(&dev->mode_config.mutex); 2365 return ret; 2366} 2367 2368 2369/** 2370 * drm_fb_release - remove and free the FBs on this file 2371 * @filp: file * from the ioctl 2372 * 2373 * LOCKING: 2374 * Takes mode config lock. 2375 * 2376 * Destroy all the FBs associated with @filp. 2377 * 2378 * Called by the user via ioctl. 2379 * 2380 * RETURNS: 2381 * Zero on success, errno on failure. 2382 */ 2383void drm_fb_release(struct drm_file *priv) 2384{ 2385 struct drm_device *dev = priv->minor->dev; 2386 struct drm_framebuffer *fb, *tfb; 2387 2388 mutex_lock(&dev->mode_config.mutex); 2389 list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) { 2390 list_del(&fb->filp_head); 2391 fb->funcs->destroy(fb); 2392 } 2393 mutex_unlock(&dev->mode_config.mutex); 2394} 2395 2396/** 2397 * drm_mode_attachmode - add a mode to the user mode list 2398 * @dev: DRM device 2399 * @connector: connector to add the mode to 2400 * @mode: mode to add 2401 * 2402 * Add @mode to @connector's user mode list. 2403 */ 2404static void drm_mode_attachmode(struct drm_device *dev, 2405 struct drm_connector *connector, 2406 struct drm_display_mode *mode) 2407{ 2408 list_add_tail(&mode->head, &connector->user_modes); 2409} 2410 2411int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc, 2412 struct drm_display_mode *mode) 2413{ 2414 struct drm_connector *connector; 2415 struct drm_display_mode *dup_mode; 2416 int need_dup = 0; 2417 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 2418 if (!connector->encoder) 2419 break; 2420 if (connector->encoder->crtc == crtc) { 2421 if (need_dup) 2422 dup_mode = drm_mode_duplicate(dev, mode); 2423 else 2424 dup_mode = mode; 2425 drm_mode_attachmode(dev, connector, dup_mode); 2426 need_dup = 1; 2427 } 2428 } 2429 return 0; 2430} 2431EXPORT_SYMBOL(drm_mode_attachmode_crtc); 2432 2433static int drm_mode_detachmode(struct drm_device *dev, 2434 struct drm_connector *connector, 2435 struct drm_display_mode *mode) 2436{ 2437 int found = 0; 2438 int ret = 0; 2439 struct drm_display_mode *match_mode, *t; 2440 2441 list_for_each_entry_safe(match_mode, t, &connector->user_modes, head) { 2442 if (drm_mode_equal(match_mode, mode)) { 2443 list_del(&match_mode->head); 2444 drm_mode_destroy(dev, match_mode); 2445 found = 1; 2446 break; 2447 } 2448 } 2449 2450 if (!found) 2451 ret = -EINVAL; 2452 2453 return ret; 2454} 2455 2456int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode) 2457{ 2458 struct drm_connector *connector; 2459 2460 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 2461 drm_mode_detachmode(dev, connector, mode); 2462 } 2463 return 0; 2464} 2465EXPORT_SYMBOL(drm_mode_detachmode_crtc); 2466 2467/** 2468 * drm_fb_attachmode - Attach a user mode to an connector 2469 * @inode: inode from the ioctl 2470 * @filp: file * from the ioctl 2471 * @cmd: cmd from ioctl 2472 * @arg: arg from ioctl 2473 * 2474 * This attaches a user specified mode to an connector. 2475 * Called by the user via ioctl. 2476 * 2477 * RETURNS: 2478 * Zero on success, errno on failure. 2479 */ 2480int drm_mode_attachmode_ioctl(struct drm_device *dev, 2481 void *data, struct drm_file *file_priv) 2482{ 2483 struct drm_mode_mode_cmd *mode_cmd = data; 2484 struct drm_connector *connector; 2485 struct drm_display_mode *mode; 2486 struct drm_mode_object *obj; 2487 struct drm_mode_modeinfo *umode = &mode_cmd->mode; 2488 int ret = 0; 2489 2490 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 2491 return -EINVAL; 2492 2493 mutex_lock(&dev->mode_config.mutex); 2494 2495 obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR); 2496 if (!obj) { 2497 ret = -EINVAL; 2498 goto out; 2499 } 2500 connector = obj_to_connector(obj); 2501 2502 mode = drm_mode_create(dev); 2503 if (!mode) { 2504 ret = -ENOMEM; 2505 goto out; 2506 } 2507 2508 ret = drm_crtc_convert_umode(mode, umode); 2509 if (ret) { 2510 DRM_DEBUG_KMS("Invalid mode\n"); 2511 drm_mode_destroy(dev, mode); 2512 goto out; 2513 } 2514 2515 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 ret = drm_crtc_convert_umode(&mode, umode); 2557 if (ret) { 2558 DRM_DEBUG_KMS("Invalid mode\n"); 2559 goto out; 2560 } 2561 2562 ret = drm_mode_detachmode(dev, connector, &mode); 2563out: 2564 mutex_unlock(&dev->mode_config.mutex); 2565 return ret; 2566} 2567 2568struct drm_property *drm_property_create(struct drm_device *dev, int flags, 2569 const char *name, int num_values) 2570{ 2571 struct drm_property *property = NULL; 2572 2573 property = kzalloc(sizeof(struct drm_property), GFP_KERNEL); 2574 if (!property) 2575 return NULL; 2576 2577 if (num_values) { 2578 property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL); 2579 if (!property->values) 2580 goto fail; 2581 } 2582 2583 drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY); 2584 property->flags = flags; 2585 property->num_values = num_values; 2586 INIT_LIST_HEAD(&property->enum_blob_list); 2587 2588 if (name) { 2589 strncpy(property->name, name, DRM_PROP_NAME_LEN); 2590 property->name[DRM_PROP_NAME_LEN-1] = '\0'; 2591 } 2592 2593 list_add_tail(&property->head, &dev->mode_config.property_list); 2594 return property; 2595fail: 2596 kfree(property); 2597 return NULL; 2598} 2599EXPORT_SYMBOL(drm_property_create); 2600 2601struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, 2602 const char *name, 2603 const struct drm_prop_enum_list *props, 2604 int num_values) 2605{ 2606 struct drm_property *property; 2607 int i, ret; 2608 2609 flags |= DRM_MODE_PROP_ENUM; 2610 2611 property = drm_property_create(dev, flags, name, num_values); 2612 if (!property) 2613 return NULL; 2614 2615 for (i = 0; i < num_values; i++) { 2616 ret = drm_property_add_enum(property, i, 2617 props[i].type, 2618 props[i].name); 2619 if (ret) { 2620 drm_property_destroy(dev, property); 2621 return NULL; 2622 } 2623 } 2624 2625 return property; 2626} 2627EXPORT_SYMBOL(drm_property_create_enum); 2628 2629struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, 2630 const char *name, 2631 uint64_t min, uint64_t max) 2632{ 2633 struct drm_property *property; 2634 2635 flags |= DRM_MODE_PROP_RANGE; 2636 2637 property = drm_property_create(dev, flags, name, 2); 2638 if (!property) 2639 return NULL; 2640 2641 property->values[0] = min; 2642 property->values[1] = max; 2643 2644 return property; 2645} 2646EXPORT_SYMBOL(drm_property_create_range); 2647 2648int drm_property_add_enum(struct drm_property *property, int index, 2649 uint64_t value, const char *name) 2650{ 2651 struct drm_property_enum *prop_enum; 2652 2653 if (!(property->flags & DRM_MODE_PROP_ENUM)) 2654 return -EINVAL; 2655 2656 if (!list_empty(&property->enum_blob_list)) { 2657 list_for_each_entry(prop_enum, &property->enum_blob_list, head) { 2658 if (prop_enum->value == value) { 2659 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN); 2660 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0'; 2661 return 0; 2662 } 2663 } 2664 } 2665 2666 prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL); 2667 if (!prop_enum) 2668 return -ENOMEM; 2669 2670 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN); 2671 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0'; 2672 prop_enum->value = value; 2673 2674 property->values[index] = value; 2675 list_add_tail(&prop_enum->head, &property->enum_blob_list); 2676 return 0; 2677} 2678EXPORT_SYMBOL(drm_property_add_enum); 2679 2680void drm_property_destroy(struct drm_device *dev, struct drm_property *property) 2681{ 2682 struct drm_property_enum *prop_enum, *pt; 2683 2684 list_for_each_entry_safe(prop_enum, pt, &property->enum_blob_list, head) { 2685 list_del(&prop_enum->head); 2686 kfree(prop_enum); 2687 } 2688 2689 if (property->num_values) 2690 kfree(property->values); 2691 drm_mode_object_put(dev, &property->base); 2692 list_del(&property->head); 2693 kfree(property); 2694} 2695EXPORT_SYMBOL(drm_property_destroy); 2696 2697int drm_connector_attach_property(struct drm_connector *connector, 2698 struct drm_property *property, uint64_t init_val) 2699{ 2700 int i; 2701 2702 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { 2703 if (connector->property_ids[i] == 0) { 2704 connector->property_ids[i] = property->base.id; 2705 connector->property_values[i] = init_val; 2706 break; 2707 } 2708 } 2709 2710 if (i == DRM_CONNECTOR_MAX_PROPERTY) 2711 return -EINVAL; 2712 return 0; 2713} 2714EXPORT_SYMBOL(drm_connector_attach_property); 2715 2716int drm_connector_property_set_value(struct drm_connector *connector, 2717 struct drm_property *property, uint64_t value) 2718{ 2719 int i; 2720 2721 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { 2722 if (connector->property_ids[i] == property->base.id) { 2723 connector->property_values[i] = value; 2724 break; 2725 } 2726 } 2727 2728 if (i == DRM_CONNECTOR_MAX_PROPERTY) 2729 return -EINVAL; 2730 return 0; 2731} 2732EXPORT_SYMBOL(drm_connector_property_set_value); 2733 2734int drm_connector_property_get_value(struct drm_connector *connector, 2735 struct drm_property *property, uint64_t *val) 2736{ 2737 int i; 2738 2739 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { 2740 if (connector->property_ids[i] == property->base.id) { 2741 *val = connector->property_values[i]; 2742 break; 2743 } 2744 } 2745 2746 if (i == DRM_CONNECTOR_MAX_PROPERTY) 2747 return -EINVAL; 2748 return 0; 2749} 2750EXPORT_SYMBOL(drm_connector_property_get_value); 2751 2752int drm_mode_getproperty_ioctl(struct drm_device *dev, 2753 void *data, struct drm_file *file_priv) 2754{ 2755 struct drm_mode_object *obj; 2756 struct drm_mode_get_property *out_resp = data; 2757 struct drm_property *property; 2758 int enum_count = 0; 2759 int blob_count = 0; 2760 int value_count = 0; 2761 int ret = 0, i; 2762 int copied; 2763 struct drm_property_enum *prop_enum; 2764 struct drm_mode_property_enum __user *enum_ptr; 2765 struct drm_property_blob *prop_blob; 2766 uint32_t __user *blob_id_ptr; 2767 uint64_t __user *values_ptr; 2768 uint32_t __user *blob_length_ptr; 2769 2770 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 2771 return -EINVAL; 2772 2773 mutex_lock(&dev->mode_config.mutex); 2774 obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY); 2775 if (!obj) { 2776 ret = -EINVAL; 2777 goto done; 2778 } 2779 property = obj_to_property(obj); 2780 2781 if (property->flags & DRM_MODE_PROP_ENUM) { 2782 list_for_each_entry(prop_enum, &property->enum_blob_list, head) 2783 enum_count++; 2784 } else if (property->flags & DRM_MODE_PROP_BLOB) { 2785 list_for_each_entry(prop_blob, &property->enum_blob_list, head) 2786 blob_count++; 2787 } 2788 2789 value_count = property->num_values; 2790 2791 strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN); 2792 out_resp->name[DRM_PROP_NAME_LEN-1] = 0; 2793 out_resp->flags = property->flags; 2794 2795 if ((out_resp->count_values >= value_count) && value_count) { 2796 values_ptr = (uint64_t __user *)(unsigned long)out_resp->values_ptr; 2797 for (i = 0; i < value_count; i++) { 2798 if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) { 2799 ret = -EFAULT; 2800 goto done; 2801 } 2802 } 2803 } 2804 out_resp->count_values = value_count; 2805 2806 if (property->flags & DRM_MODE_PROP_ENUM) { 2807 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) { 2808 copied = 0; 2809 enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr; 2810 list_for_each_entry(prop_enum, &property->enum_blob_list, head) { 2811 2812 if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) { 2813 ret = -EFAULT; 2814 goto done; 2815 } 2816 2817 if (copy_to_user(&enum_ptr[copied].name, 2818 &prop_enum->name, DRM_PROP_NAME_LEN)) { 2819 ret = -EFAULT; 2820 goto done; 2821 } 2822 copied++; 2823 } 2824 } 2825 out_resp->count_enum_blobs = enum_count; 2826 } 2827 2828 if (property->flags & DRM_MODE_PROP_BLOB) { 2829 if ((out_resp->count_enum_blobs >= blob_count) && blob_count) { 2830 copied = 0; 2831 blob_id_ptr = (uint32_t __user *)(unsigned long)out_resp->enum_blob_ptr; 2832 blob_length_ptr = (uint32_t __user *)(unsigned long)out_resp->values_ptr; 2833 2834 list_for_each_entry(prop_blob, &property->enum_blob_list, head) { 2835 if (put_user(prop_blob->base.id, blob_id_ptr + copied)) { 2836 ret = -EFAULT; 2837 goto done; 2838 } 2839 2840 if (put_user(prop_blob->length, blob_length_ptr + copied)) { 2841 ret = -EFAULT; 2842 goto done; 2843 } 2844 2845 copied++; 2846 } 2847 } 2848 out_resp->count_enum_blobs = blob_count; 2849 } 2850done: 2851 mutex_unlock(&dev->mode_config.mutex); 2852 return ret; 2853} 2854 2855static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length, 2856 void *data) 2857{ 2858 struct drm_property_blob *blob; 2859 2860 if (!length || !data) 2861 return NULL; 2862 2863 blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL); 2864 if (!blob) 2865 return NULL; 2866 2867 blob->data = (void *)((char *)blob + sizeof(struct drm_property_blob)); 2868 blob->length = length; 2869 2870 memcpy(blob->data, data, length); 2871 2872 drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB); 2873 2874 list_add_tail(&blob->head, &dev->mode_config.property_blob_list); 2875 return blob; 2876} 2877 2878static void drm_property_destroy_blob(struct drm_device *dev, 2879 struct drm_property_blob *blob) 2880{ 2881 drm_mode_object_put(dev, &blob->base); 2882 list_del(&blob->head); 2883 kfree(blob); 2884} 2885 2886int drm_mode_getblob_ioctl(struct drm_device *dev, 2887 void *data, struct drm_file *file_priv) 2888{ 2889 struct drm_mode_object *obj; 2890 struct drm_mode_get_blob *out_resp = data; 2891 struct drm_property_blob *blob; 2892 int ret = 0; 2893 void __user *blob_ptr; 2894 2895 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 2896 return -EINVAL; 2897 2898 mutex_lock(&dev->mode_config.mutex); 2899 obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB); 2900 if (!obj) { 2901 ret = -EINVAL; 2902 goto done; 2903 } 2904 blob = obj_to_blob(obj); 2905 2906 if (out_resp->length == blob->length) { 2907 blob_ptr = (void __user *)(unsigned long)out_resp->data; 2908 if (copy_to_user(blob_ptr, blob->data, blob->length)){ 2909 ret = -EFAULT; 2910 goto done; 2911 } 2912 } 2913 out_resp->length = blob->length; 2914 2915done: 2916 mutex_unlock(&dev->mode_config.mutex); 2917 return ret; 2918} 2919 2920int drm_mode_connector_update_edid_property(struct drm_connector *connector, 2921 struct edid *edid) 2922{ 2923 struct drm_device *dev = connector->dev; 2924 int ret = 0, size; 2925 2926 if (connector->edid_blob_ptr) 2927 drm_property_destroy_blob(dev, connector->edid_blob_ptr); 2928 2929 /* Delete edid, when there is none. */ 2930 if (!edid) { 2931 connector->edid_blob_ptr = NULL; 2932 ret = drm_connector_property_set_value(connector, dev->mode_config.edid_property, 0); 2933 return ret; 2934 } 2935 2936 size = EDID_LENGTH * (1 + edid->extensions); 2937 connector->edid_blob_ptr = drm_property_create_blob(connector->dev, 2938 size, edid); 2939 2940 ret = drm_connector_property_set_value(connector, 2941 dev->mode_config.edid_property, 2942 connector->edid_blob_ptr->base.id); 2943 2944 return ret; 2945} 2946EXPORT_SYMBOL(drm_mode_connector_update_edid_property); 2947 2948int drm_mode_connector_property_set_ioctl(struct drm_device *dev, 2949 void *data, struct drm_file *file_priv) 2950{ 2951 struct drm_mode_connector_set_property *out_resp = data; 2952 struct drm_mode_object *obj; 2953 struct drm_property *property; 2954 struct drm_connector *connector; 2955 int ret = -EINVAL; 2956 int i; 2957 2958 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 2959 return -EINVAL; 2960 2961 mutex_lock(&dev->mode_config.mutex); 2962 2963 obj = drm_mode_object_find(dev, out_resp->connector_id, DRM_MODE_OBJECT_CONNECTOR); 2964 if (!obj) { 2965 goto out; 2966 } 2967 connector = obj_to_connector(obj); 2968 2969 for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { 2970 if (connector->property_ids[i] == out_resp->prop_id) 2971 break; 2972 } 2973 2974 if (i == DRM_CONNECTOR_MAX_PROPERTY) { 2975 goto out; 2976 } 2977 2978 obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY); 2979 if (!obj) { 2980 goto out; 2981 } 2982 property = obj_to_property(obj); 2983 2984 if (property->flags & DRM_MODE_PROP_IMMUTABLE) 2985 goto out; 2986 2987 if (property->flags & DRM_MODE_PROP_RANGE) { 2988 if (out_resp->value < property->values[0]) 2989 goto out; 2990 2991 if (out_resp->value > property->values[1]) 2992 goto out; 2993 } else { 2994 int found = 0; 2995 for (i = 0; i < property->num_values; i++) { 2996 if (property->values[i] == out_resp->value) { 2997 found = 1; 2998 break; 2999 } 3000 } 3001 if (!found) { 3002 goto out; 3003 } 3004 } 3005 3006 /* Do DPMS ourselves */ 3007 if (property == connector->dev->mode_config.dpms_property) { 3008 if (connector->funcs->dpms) 3009 (*connector->funcs->dpms)(connector, (int) out_resp->value); 3010 ret = 0; 3011 } else if (connector->funcs->set_property) 3012 ret = connector->funcs->set_property(connector, property, out_resp->value); 3013 3014 /* store the property value if successful */ 3015 if (!ret) 3016 drm_connector_property_set_value(connector, property, out_resp->value); 3017out: 3018 mutex_unlock(&dev->mode_config.mutex); 3019 return ret; 3020} 3021 3022int drm_mode_connector_attach_encoder(struct drm_connector *connector, 3023 struct drm_encoder *encoder) 3024{ 3025 int i; 3026 3027 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 3028 if (connector->encoder_ids[i] == 0) { 3029 connector->encoder_ids[i] = encoder->base.id; 3030 return 0; 3031 } 3032 } 3033 return -ENOMEM; 3034} 3035EXPORT_SYMBOL(drm_mode_connector_attach_encoder); 3036 3037void drm_mode_connector_detach_encoder(struct drm_connector *connector, 3038 struct drm_encoder *encoder) 3039{ 3040 int i; 3041 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 3042 if (connector->encoder_ids[i] == encoder->base.id) { 3043 connector->encoder_ids[i] = 0; 3044 if (connector->encoder == encoder) 3045 connector->encoder = NULL; 3046 break; 3047 } 3048 } 3049} 3050EXPORT_SYMBOL(drm_mode_connector_detach_encoder); 3051 3052int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, 3053 int gamma_size) 3054{ 3055 crtc->gamma_size = gamma_size; 3056 3057 crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL); 3058 if (!crtc->gamma_store) { 3059 crtc->gamma_size = 0; 3060 return -ENOMEM; 3061 } 3062 3063 return 0; 3064} 3065EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size); 3066 3067int drm_mode_gamma_set_ioctl(struct drm_device *dev, 3068 void *data, struct drm_file *file_priv) 3069{ 3070 struct drm_mode_crtc_lut *crtc_lut = data; 3071 struct drm_mode_object *obj; 3072 struct drm_crtc *crtc; 3073 void *r_base, *g_base, *b_base; 3074 int size; 3075 int ret = 0; 3076 3077 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 3078 return -EINVAL; 3079 3080 mutex_lock(&dev->mode_config.mutex); 3081 obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC); 3082 if (!obj) { 3083 ret = -EINVAL; 3084 goto out; 3085 } 3086 crtc = obj_to_crtc(obj); 3087 3088 /* memcpy into gamma store */ 3089 if (crtc_lut->gamma_size != crtc->gamma_size) { 3090 ret = -EINVAL; 3091 goto out; 3092 } 3093 3094 size = crtc_lut->gamma_size * (sizeof(uint16_t)); 3095 r_base = crtc->gamma_store; 3096 if (copy_from_user(r_base, (void __user *)(unsigned long)crtc_lut->red, size)) { 3097 ret = -EFAULT; 3098 goto out; 3099 } 3100 3101 g_base = r_base + size; 3102 if (copy_from_user(g_base, (void __user *)(unsigned long)crtc_lut->green, size)) { 3103 ret = -EFAULT; 3104 goto out; 3105 } 3106 3107 b_base = g_base + size; 3108 if (copy_from_user(b_base, (void __user *)(unsigned long)crtc_lut->blue, size)) { 3109 ret = -EFAULT; 3110 goto out; 3111 } 3112 3113 crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size); 3114 3115out: 3116 mutex_unlock(&dev->mode_config.mutex); 3117 return ret; 3118 3119} 3120 3121int drm_mode_gamma_get_ioctl(struct drm_device *dev, 3122 void *data, struct drm_file *file_priv) 3123{ 3124 struct drm_mode_crtc_lut *crtc_lut = data; 3125 struct drm_mode_object *obj; 3126 struct drm_crtc *crtc; 3127 void *r_base, *g_base, *b_base; 3128 int size; 3129 int ret = 0; 3130 3131 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 3132 return -EINVAL; 3133 3134 mutex_lock(&dev->mode_config.mutex); 3135 obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC); 3136 if (!obj) { 3137 ret = -EINVAL; 3138 goto out; 3139 } 3140 crtc = obj_to_crtc(obj); 3141 3142 /* memcpy into gamma store */ 3143 if (crtc_lut->gamma_size != crtc->gamma_size) { 3144 ret = -EINVAL; 3145 goto out; 3146 } 3147 3148 size = crtc_lut->gamma_size * (sizeof(uint16_t)); 3149 r_base = crtc->gamma_store; 3150 if (copy_to_user((void __user *)(unsigned long)crtc_lut->red, r_base, size)) { 3151 ret = -EFAULT; 3152 goto out; 3153 } 3154 3155 g_base = r_base + size; 3156 if (copy_to_user((void __user *)(unsigned long)crtc_lut->green, g_base, size)) { 3157 ret = -EFAULT; 3158 goto out; 3159 } 3160 3161 b_base = g_base + size; 3162 if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) { 3163 ret = -EFAULT; 3164 goto out; 3165 } 3166out: 3167 mutex_unlock(&dev->mode_config.mutex); 3168 return ret; 3169} 3170 3171int drm_mode_page_flip_ioctl(struct drm_device *dev, 3172 void *data, struct drm_file *file_priv) 3173{ 3174 struct drm_mode_crtc_page_flip *page_flip = data; 3175 struct drm_mode_object *obj; 3176 struct drm_crtc *crtc; 3177 struct drm_framebuffer *fb; 3178 struct drm_pending_vblank_event *e = NULL; 3179 unsigned long flags; 3180 int ret = -EINVAL; 3181 3182 if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS || 3183 page_flip->reserved != 0) 3184 return -EINVAL; 3185 3186 mutex_lock(&dev->mode_config.mutex); 3187 obj = drm_mode_object_find(dev, page_flip->crtc_id, DRM_MODE_OBJECT_CRTC); 3188 if (!obj) 3189 goto out; 3190 crtc = obj_to_crtc(obj); 3191 3192 if (crtc->fb == NULL) { 3193 /* The framebuffer is currently unbound, presumably 3194 * due to a hotplug event, that userspace has not 3195 * yet discovered. 3196 */ 3197 ret = -EBUSY; 3198 goto out; 3199 } 3200 3201 if (crtc->funcs->page_flip == NULL) 3202 goto out; 3203 3204 obj = drm_mode_object_find(dev, page_flip->fb_id, DRM_MODE_OBJECT_FB); 3205 if (!obj) 3206 goto out; 3207 fb = obj_to_fb(obj); 3208 3209 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { 3210 ret = -ENOMEM; 3211 spin_lock_irqsave(&dev->event_lock, flags); 3212 if (file_priv->event_space < sizeof e->event) { 3213 spin_unlock_irqrestore(&dev->event_lock, flags); 3214 goto out; 3215 } 3216 file_priv->event_space -= sizeof e->event; 3217 spin_unlock_irqrestore(&dev->event_lock, flags); 3218 3219 e = kzalloc(sizeof *e, GFP_KERNEL); 3220 if (e == NULL) { 3221 spin_lock_irqsave(&dev->event_lock, flags); 3222 file_priv->event_space += sizeof e->event; 3223 spin_unlock_irqrestore(&dev->event_lock, flags); 3224 goto out; 3225 } 3226 3227 e->event.base.type = DRM_EVENT_FLIP_COMPLETE; 3228 e->event.base.length = sizeof e->event; 3229 e->event.user_data = page_flip->user_data; 3230 e->base.event = &e->event.base; 3231 e->base.file_priv = file_priv; 3232 e->base.destroy = 3233 (void (*) (struct drm_pending_event *)) kfree; 3234 } 3235 3236 ret = crtc->funcs->page_flip(crtc, fb, e); 3237 if (ret) { 3238 spin_lock_irqsave(&dev->event_lock, flags); 3239 file_priv->event_space += sizeof e->event; 3240 spin_unlock_irqrestore(&dev->event_lock, flags); 3241 kfree(e); 3242 } 3243 3244out: 3245 mutex_unlock(&dev->mode_config.mutex); 3246 return ret; 3247} 3248 3249void drm_mode_config_reset(struct drm_device *dev) 3250{ 3251 struct drm_crtc *crtc; 3252 struct drm_encoder *encoder; 3253 struct drm_connector *connector; 3254 3255 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) 3256 if (crtc->funcs->reset) 3257 crtc->funcs->reset(crtc); 3258 3259 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) 3260 if (encoder->funcs->reset) 3261 encoder->funcs->reset(encoder); 3262 3263 list_for_each_entry(connector, &dev->mode_config.connector_list, head) 3264 if (connector->funcs->reset) 3265 connector->funcs->reset(connector); 3266} 3267EXPORT_SYMBOL(drm_mode_config_reset); 3268 3269int drm_mode_create_dumb_ioctl(struct drm_device *dev, 3270 void *data, struct drm_file *file_priv) 3271{ 3272 struct drm_mode_create_dumb *args = data; 3273 3274 if (!dev->driver->dumb_create) 3275 return -ENOSYS; 3276 return dev->driver->dumb_create(file_priv, dev, args); 3277} 3278 3279int drm_mode_mmap_dumb_ioctl(struct drm_device *dev, 3280 void *data, struct drm_file *file_priv) 3281{ 3282 struct drm_mode_map_dumb *args = data; 3283 3284 /* call driver ioctl to get mmap offset */ 3285 if (!dev->driver->dumb_map_offset) 3286 return -ENOSYS; 3287 3288 return dev->driver->dumb_map_offset(file_priv, dev, args->handle, &args->offset); 3289} 3290 3291int drm_mode_destroy_dumb_ioctl(struct drm_device *dev, 3292 void *data, struct drm_file *file_priv) 3293{ 3294 struct drm_mode_destroy_dumb *args = data; 3295 3296 if (!dev->driver->dumb_destroy) 3297 return -ENOSYS; 3298 3299 return dev->driver->dumb_destroy(file_priv, dev, args->handle); 3300} 3301 3302/* 3303 * Just need to support RGB formats here for compat with code that doesn't 3304 * use pixel formats directly yet. 3305 */ 3306void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, 3307 int *bpp) 3308{ 3309 switch (format) { 3310 case DRM_FORMAT_RGB332: 3311 case DRM_FORMAT_BGR233: 3312 *depth = 8; 3313 *bpp = 8; 3314 break; 3315 case DRM_FORMAT_XRGB1555: 3316 case DRM_FORMAT_XBGR1555: 3317 case DRM_FORMAT_RGBX5551: 3318 case DRM_FORMAT_BGRX5551: 3319 case DRM_FORMAT_ARGB1555: 3320 case DRM_FORMAT_ABGR1555: 3321 case DRM_FORMAT_RGBA5551: 3322 case DRM_FORMAT_BGRA5551: 3323 *depth = 15; 3324 *bpp = 16; 3325 break; 3326 case DRM_FORMAT_RGB565: 3327 case DRM_FORMAT_BGR565: 3328 *depth = 16; 3329 *bpp = 16; 3330 break; 3331 case DRM_FORMAT_RGB888: 3332 case DRM_FORMAT_BGR888: 3333 *depth = 24; 3334 *bpp = 24; 3335 break; 3336 case DRM_FORMAT_XRGB8888: 3337 case DRM_FORMAT_XBGR8888: 3338 case DRM_FORMAT_RGBX8888: 3339 case DRM_FORMAT_BGRX8888: 3340 *depth = 24; 3341 *bpp = 32; 3342 break; 3343 case DRM_FORMAT_XRGB2101010: 3344 case DRM_FORMAT_XBGR2101010: 3345 case DRM_FORMAT_RGBX1010102: 3346 case DRM_FORMAT_BGRX1010102: 3347 case DRM_FORMAT_ARGB2101010: 3348 case DRM_FORMAT_ABGR2101010: 3349 case DRM_FORMAT_RGBA1010102: 3350 case DRM_FORMAT_BGRA1010102: 3351 *depth = 30; 3352 *bpp = 32; 3353 break; 3354 case DRM_FORMAT_ARGB8888: 3355 case DRM_FORMAT_ABGR8888: 3356 case DRM_FORMAT_RGBA8888: 3357 case DRM_FORMAT_BGRA8888: 3358 *depth = 32; 3359 *bpp = 32; 3360 break; 3361 default: 3362 DRM_DEBUG_KMS("unsupported pixel format\n"); 3363 *depth = 0; 3364 *bpp = 0; 3365 break; 3366 } 3367} 3368EXPORT_SYMBOL(drm_fb_get_bpp_depth); 3369