linux/drivers/gpu/drm/drm_crtc.c
<<
>>
Prefs
   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 "drm.h"
  34#include "drmP.h"
  35#include "drm_crtc.h"
  36
  37struct drm_prop_enum_list {
  38        int type;
  39        char *name;
  40};
  41
  42/* Avoid boilerplate.  I'm tired of typing. */
  43#define DRM_ENUM_NAME_FN(fnname, list)                          \
  44        char *fnname(int val)                                   \
  45        {                                                       \
  46                int i;                                          \
  47                for (i = 0; i < ARRAY_SIZE(list); i++) {        \
  48                        if (list[i].type == val)                \
  49                                return list[i].name;            \
  50                }                                               \
  51                return "(unknown)";                             \
  52        }
  53
  54/*
  55 * Global properties
  56 */
  57static struct drm_prop_enum_list drm_dpms_enum_list[] =
  58{       { DRM_MODE_DPMS_ON, "On" },
  59        { DRM_MODE_DPMS_STANDBY, "Standby" },
  60        { DRM_MODE_DPMS_SUSPEND, "Suspend" },
  61        { DRM_MODE_DPMS_OFF, "Off" }
  62};
  63
  64DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
  65
  66/*
  67 * Optional properties
  68 */
  69static struct drm_prop_enum_list drm_scaling_mode_enum_list[] =
  70{
  71        { DRM_MODE_SCALE_NONE, "None" },
  72        { DRM_MODE_SCALE_FULLSCREEN, "Full" },
  73        { DRM_MODE_SCALE_CENTER, "Center" },
  74        { DRM_MODE_SCALE_ASPECT, "Full aspect" },
  75};
  76
  77static struct drm_prop_enum_list drm_dithering_mode_enum_list[] =
  78{
  79        { DRM_MODE_DITHERING_OFF, "Off" },
  80        { DRM_MODE_DITHERING_ON, "On" },
  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
 128struct drm_conn_prop_enum_list {
 129        int type;
 130        char *name;
 131        int count;
 132};
 133
 134/*
 135 * Connector and encoder types.
 136 */
 137static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
 138{       { DRM_MODE_CONNECTOR_Unknown, "Unknown", 0 },
 139        { DRM_MODE_CONNECTOR_VGA, "VGA", 0 },
 140        { DRM_MODE_CONNECTOR_DVII, "DVI-I", 0 },
 141        { DRM_MODE_CONNECTOR_DVID, "DVI-D", 0 },
 142        { DRM_MODE_CONNECTOR_DVIA, "DVI-A", 0 },
 143        { DRM_MODE_CONNECTOR_Composite, "Composite", 0 },
 144        { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 },
 145        { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 },
 146        { DRM_MODE_CONNECTOR_Component, "Component", 0 },
 147        { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN", 0 },
 148        { DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 },
 149        { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 },
 150        { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 },
 151        { DRM_MODE_CONNECTOR_TV, "TV", 0 },
 152};
 153
 154static struct drm_prop_enum_list drm_encoder_enum_list[] =
 155{       { DRM_MODE_ENCODER_NONE, "None" },
 156        { DRM_MODE_ENCODER_DAC, "DAC" },
 157        { DRM_MODE_ENCODER_TMDS, "TMDS" },
 158        { DRM_MODE_ENCODER_LVDS, "LVDS" },
 159        { DRM_MODE_ENCODER_TVDAC, "TV" },
 160};
 161
 162char *drm_get_encoder_name(struct drm_encoder *encoder)
 163{
 164        static char buf[32];
 165
 166        snprintf(buf, 32, "%s-%d",
 167                 drm_encoder_enum_list[encoder->encoder_type].name,
 168                 encoder->base.id);
 169        return buf;
 170}
 171EXPORT_SYMBOL(drm_get_encoder_name);
 172
 173char *drm_get_connector_name(struct drm_connector *connector)
 174{
 175        static char buf[32];
 176
 177        snprintf(buf, 32, "%s-%d",
 178                 drm_connector_enum_list[connector->connector_type].name,
 179                 connector->connector_type_id);
 180        return buf;
 181}
 182EXPORT_SYMBOL(drm_get_connector_name);
 183
 184char *drm_get_connector_status_name(enum drm_connector_status status)
 185{
 186        if (status == connector_status_connected)
 187                return "connected";
 188        else if (status == connector_status_disconnected)
 189                return "disconnected";
 190        else
 191                return "unknown";
 192}
 193
 194/**
 195 * drm_mode_object_get - allocate a new identifier
 196 * @dev: DRM device
 197 * @ptr: object pointer, used to generate unique ID
 198 * @type: object type
 199 *
 200 * LOCKING:
 201 *
 202 * Create a unique identifier based on @ptr in @dev's identifier space.  Used
 203 * for tracking modes, CRTCs and connectors.
 204 *
 205 * RETURNS:
 206 * New unique (relative to other objects in @dev) integer identifier for the
 207 * object.
 208 */
 209static int drm_mode_object_get(struct drm_device *dev,
 210                               struct drm_mode_object *obj, uint32_t obj_type)
 211{
 212        int new_id = 0;
 213        int ret;
 214
 215again:
 216        if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
 217                DRM_ERROR("Ran out memory getting a mode number\n");
 218                return -EINVAL;
 219        }
 220
 221        mutex_lock(&dev->mode_config.idr_mutex);
 222        ret = idr_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id);
 223        mutex_unlock(&dev->mode_config.idr_mutex);
 224        if (ret == -EAGAIN)
 225                goto again;
 226
 227        obj->id = new_id;
 228        obj->type = obj_type;
 229        return 0;
 230}
 231
 232/**
 233 * drm_mode_object_put - free an identifer
 234 * @dev: DRM device
 235 * @id: ID to free
 236 *
 237 * LOCKING:
 238 * Caller must hold DRM mode_config lock.
 239 *
 240 * Free @id from @dev's unique identifier pool.
 241 */
 242static void drm_mode_object_put(struct drm_device *dev,
 243                                struct drm_mode_object *object)
 244{
 245        mutex_lock(&dev->mode_config.idr_mutex);
 246        idr_remove(&dev->mode_config.crtc_idr, object->id);
 247        mutex_unlock(&dev->mode_config.idr_mutex);
 248}
 249
 250void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type)
 251{
 252        struct drm_mode_object *obj = NULL;
 253
 254        mutex_lock(&dev->mode_config.idr_mutex);
 255        obj = idr_find(&dev->mode_config.crtc_idr, id);
 256        if (!obj || (obj->type != type) || (obj->id != id))
 257                obj = NULL;
 258        mutex_unlock(&dev->mode_config.idr_mutex);
 259
 260        return obj;
 261}
 262EXPORT_SYMBOL(drm_mode_object_find);
 263
 264/**
 265 * drm_framebuffer_init - initialize a framebuffer
 266 * @dev: DRM device
 267 *
 268 * LOCKING:
 269 * Caller must hold mode config lock.
 270 *
 271 * Allocates an ID for the framebuffer's parent mode object, sets its mode
 272 * functions & device file and adds it to the master fd list.
 273 *
 274 * RETURNS:
 275 * Zero on success, error code on falure.
 276 */
 277int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
 278                         const struct drm_framebuffer_funcs *funcs)
 279{
 280        int ret;
 281
 282        ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
 283        if (ret) {
 284                return ret;
 285        }
 286
 287        fb->dev = dev;
 288        fb->funcs = funcs;
 289        dev->mode_config.num_fb++;
 290        list_add(&fb->head, &dev->mode_config.fb_list);
 291
 292        return 0;
 293}
 294EXPORT_SYMBOL(drm_framebuffer_init);
 295
 296/**
 297 * drm_framebuffer_cleanup - remove a framebuffer object
 298 * @fb: framebuffer to remove
 299 *
 300 * LOCKING:
 301 * Caller must hold mode config lock.
 302 *
 303 * Scans all the CRTCs in @dev's mode_config.  If they're using @fb, removes
 304 * it, setting it to NULL.
 305 */
 306void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
 307{
 308        struct drm_device *dev = fb->dev;
 309        struct drm_crtc *crtc;
 310        struct drm_mode_set set;
 311        int ret;
 312
 313        /* remove from any CRTC */
 314        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 315                if (crtc->fb == fb) {
 316                        /* should turn off the crtc */
 317                        memset(&set, 0, sizeof(struct drm_mode_set));
 318                        set.crtc = crtc;
 319                        set.fb = NULL;
 320                        ret = crtc->funcs->set_config(&set);
 321                        if (ret)
 322                                DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc);
 323                }
 324        }
 325
 326        drm_mode_object_put(dev, &fb->base);
 327        list_del(&fb->head);
 328        dev->mode_config.num_fb--;
 329}
 330EXPORT_SYMBOL(drm_framebuffer_cleanup);
 331
 332/**
 333 * drm_crtc_init - Initialise a new CRTC object
 334 * @dev: DRM device
 335 * @crtc: CRTC object to init
 336 * @funcs: callbacks for the new CRTC
 337 *
 338 * LOCKING:
 339 * Caller must hold mode config lock.
 340 *
 341 * Inits a new object created as base part of an driver crtc object.
 342 */
 343void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
 344                   const struct drm_crtc_funcs *funcs)
 345{
 346        crtc->dev = dev;
 347        crtc->funcs = funcs;
 348
 349        mutex_lock(&dev->mode_config.mutex);
 350        drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
 351
 352        list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
 353        dev->mode_config.num_crtc++;
 354        mutex_unlock(&dev->mode_config.mutex);
 355}
 356EXPORT_SYMBOL(drm_crtc_init);
 357
 358/**
 359 * drm_crtc_cleanup - Cleans up the core crtc usage.
 360 * @crtc: CRTC to cleanup
 361 *
 362 * LOCKING:
 363 * Caller must hold mode config lock.
 364 *
 365 * Cleanup @crtc. Removes from drm modesetting space
 366 * does NOT free object, caller does that.
 367 */
 368void drm_crtc_cleanup(struct drm_crtc *crtc)
 369{
 370        struct drm_device *dev = crtc->dev;
 371
 372        if (crtc->gamma_store) {
 373                kfree(crtc->gamma_store);
 374                crtc->gamma_store = NULL;
 375        }
 376
 377        drm_mode_object_put(dev, &crtc->base);
 378        list_del(&crtc->head);
 379        dev->mode_config.num_crtc--;
 380}
 381EXPORT_SYMBOL(drm_crtc_cleanup);
 382
 383/**
 384 * drm_mode_probed_add - add a mode to a connector's probed mode list
 385 * @connector: connector the new mode
 386 * @mode: mode data
 387 *
 388 * LOCKING:
 389 * Caller must hold mode config lock.
 390 *
 391 * Add @mode to @connector's mode list for later use.
 392 */
 393void drm_mode_probed_add(struct drm_connector *connector,
 394                         struct drm_display_mode *mode)
 395{
 396        list_add(&mode->head, &connector->probed_modes);
 397}
 398EXPORT_SYMBOL(drm_mode_probed_add);
 399
 400/**
 401 * drm_mode_remove - remove and free a mode
 402 * @connector: connector list to modify
 403 * @mode: mode to remove
 404 *
 405 * LOCKING:
 406 * Caller must hold mode config lock.
 407 *
 408 * Remove @mode from @connector's mode list, then free it.
 409 */
 410void drm_mode_remove(struct drm_connector *connector,
 411                     struct drm_display_mode *mode)
 412{
 413        list_del(&mode->head);
 414        kfree(mode);
 415}
 416EXPORT_SYMBOL(drm_mode_remove);
 417
 418/**
 419 * drm_connector_init - Init a preallocated connector
 420 * @dev: DRM device
 421 * @connector: the connector to init
 422 * @funcs: callbacks for this connector
 423 * @name: user visible name of the connector
 424 *
 425 * LOCKING:
 426 * Caller must hold @dev's mode_config lock.
 427 *
 428 * Initialises a preallocated connector. Connectors should be
 429 * subclassed as part of driver connector objects.
 430 */
 431void drm_connector_init(struct drm_device *dev,
 432                     struct drm_connector *connector,
 433                     const struct drm_connector_funcs *funcs,
 434                     int connector_type)
 435{
 436        mutex_lock(&dev->mode_config.mutex);
 437
 438        connector->dev = dev;
 439        connector->funcs = funcs;
 440        drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR);
 441        connector->connector_type = connector_type;
 442        connector->connector_type_id =
 443                ++drm_connector_enum_list[connector_type].count; /* TODO */
 444        INIT_LIST_HEAD(&connector->user_modes);
 445        INIT_LIST_HEAD(&connector->probed_modes);
 446        INIT_LIST_HEAD(&connector->modes);
 447        connector->edid_blob_ptr = NULL;
 448
 449        list_add_tail(&connector->head, &dev->mode_config.connector_list);
 450        dev->mode_config.num_connector++;
 451
 452        drm_connector_attach_property(connector,
 453                                      dev->mode_config.edid_property, 0);
 454
 455        drm_connector_attach_property(connector,
 456                                      dev->mode_config.dpms_property, 0);
 457
 458        mutex_unlock(&dev->mode_config.mutex);
 459}
 460EXPORT_SYMBOL(drm_connector_init);
 461
 462/**
 463 * drm_connector_cleanup - cleans up an initialised connector
 464 * @connector: connector to cleanup
 465 *
 466 * LOCKING:
 467 * Caller must hold @dev's mode_config lock.
 468 *
 469 * Cleans up the connector but doesn't free the object.
 470 */
 471void drm_connector_cleanup(struct drm_connector *connector)
 472{
 473        struct drm_device *dev = connector->dev;
 474        struct drm_display_mode *mode, *t;
 475
 476        list_for_each_entry_safe(mode, t, &connector->probed_modes, head)
 477                drm_mode_remove(connector, mode);
 478
 479        list_for_each_entry_safe(mode, t, &connector->modes, head)
 480                drm_mode_remove(connector, mode);
 481
 482        list_for_each_entry_safe(mode, t, &connector->user_modes, head)
 483                drm_mode_remove(connector, mode);
 484
 485        kfree(connector->fb_helper_private);
 486        mutex_lock(&dev->mode_config.mutex);
 487        drm_mode_object_put(dev, &connector->base);
 488        list_del(&connector->head);
 489        mutex_unlock(&dev->mode_config.mutex);
 490}
 491EXPORT_SYMBOL(drm_connector_cleanup);
 492
 493void drm_encoder_init(struct drm_device *dev,
 494                      struct drm_encoder *encoder,
 495                      const struct drm_encoder_funcs *funcs,
 496                      int encoder_type)
 497{
 498        mutex_lock(&dev->mode_config.mutex);
 499
 500        encoder->dev = dev;
 501
 502        drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
 503        encoder->encoder_type = encoder_type;
 504        encoder->funcs = funcs;
 505
 506        list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
 507        dev->mode_config.num_encoder++;
 508
 509        mutex_unlock(&dev->mode_config.mutex);
 510}
 511EXPORT_SYMBOL(drm_encoder_init);
 512
 513void drm_encoder_cleanup(struct drm_encoder *encoder)
 514{
 515        struct drm_device *dev = encoder->dev;
 516        mutex_lock(&dev->mode_config.mutex);
 517        drm_mode_object_put(dev, &encoder->base);
 518        list_del(&encoder->head);
 519        mutex_unlock(&dev->mode_config.mutex);
 520}
 521EXPORT_SYMBOL(drm_encoder_cleanup);
 522
 523/**
 524 * drm_mode_create - create a new display mode
 525 * @dev: DRM device
 526 *
 527 * LOCKING:
 528 * Caller must hold DRM mode_config lock.
 529 *
 530 * Create a new drm_display_mode, give it an ID, and return it.
 531 *
 532 * RETURNS:
 533 * Pointer to new mode on success, NULL on error.
 534 */
 535struct drm_display_mode *drm_mode_create(struct drm_device *dev)
 536{
 537        struct drm_display_mode *nmode;
 538
 539        nmode = kzalloc(sizeof(struct drm_display_mode), GFP_KERNEL);
 540        if (!nmode)
 541                return NULL;
 542
 543        drm_mode_object_get(dev, &nmode->base, DRM_MODE_OBJECT_MODE);
 544        return nmode;
 545}
 546EXPORT_SYMBOL(drm_mode_create);
 547
 548/**
 549 * drm_mode_destroy - remove a mode
 550 * @dev: DRM device
 551 * @mode: mode to remove
 552 *
 553 * LOCKING:
 554 * Caller must hold mode config lock.
 555 *
 556 * Free @mode's unique identifier, then free it.
 557 */
 558void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
 559{
 560        drm_mode_object_put(dev, &mode->base);
 561
 562        kfree(mode);
 563}
 564EXPORT_SYMBOL(drm_mode_destroy);
 565
 566static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
 567{
 568        struct drm_property *edid;
 569        struct drm_property *dpms;
 570        int i;
 571
 572        /*
 573         * Standard properties (apply to all connectors)
 574         */
 575        edid = drm_property_create(dev, DRM_MODE_PROP_BLOB |
 576                                   DRM_MODE_PROP_IMMUTABLE,
 577                                   "EDID", 0);
 578        dev->mode_config.edid_property = edid;
 579
 580        dpms = drm_property_create(dev, DRM_MODE_PROP_ENUM,
 581                                   "DPMS", ARRAY_SIZE(drm_dpms_enum_list));
 582        for (i = 0; i < ARRAY_SIZE(drm_dpms_enum_list); i++)
 583                drm_property_add_enum(dpms, i, drm_dpms_enum_list[i].type,
 584                                      drm_dpms_enum_list[i].name);
 585        dev->mode_config.dpms_property = dpms;
 586
 587        return 0;
 588}
 589
 590/**
 591 * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties
 592 * @dev: DRM device
 593 *
 594 * Called by a driver the first time a DVI-I connector is made.
 595 */
 596int drm_mode_create_dvi_i_properties(struct drm_device *dev)
 597{
 598        struct drm_property *dvi_i_selector;
 599        struct drm_property *dvi_i_subconnector;
 600        int i;
 601
 602        if (dev->mode_config.dvi_i_select_subconnector_property)
 603                return 0;
 604
 605        dvi_i_selector =
 606                drm_property_create(dev, DRM_MODE_PROP_ENUM,
 607                                    "select subconnector",
 608                                    ARRAY_SIZE(drm_dvi_i_select_enum_list));
 609        for (i = 0; i < ARRAY_SIZE(drm_dvi_i_select_enum_list); i++)
 610                drm_property_add_enum(dvi_i_selector, i,
 611                                      drm_dvi_i_select_enum_list[i].type,
 612                                      drm_dvi_i_select_enum_list[i].name);
 613        dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector;
 614
 615        dvi_i_subconnector =
 616                drm_property_create(dev, DRM_MODE_PROP_ENUM |
 617                                    DRM_MODE_PROP_IMMUTABLE,
 618                                    "subconnector",
 619                                    ARRAY_SIZE(drm_dvi_i_subconnector_enum_list));
 620        for (i = 0; i < ARRAY_SIZE(drm_dvi_i_subconnector_enum_list); i++)
 621                drm_property_add_enum(dvi_i_subconnector, i,
 622                                      drm_dvi_i_subconnector_enum_list[i].type,
 623                                      drm_dvi_i_subconnector_enum_list[i].name);
 624        dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector;
 625
 626        return 0;
 627}
 628EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);
 629
 630/**
 631 * drm_create_tv_properties - create TV specific connector properties
 632 * @dev: DRM device
 633 * @num_modes: number of different TV formats (modes) supported
 634 * @modes: array of pointers to strings containing name of each format
 635 *
 636 * Called by a driver's TV initialization routine, this function creates
 637 * the TV specific connector properties for a given device.  Caller is
 638 * responsible for allocating a list of format names and passing them to
 639 * this routine.
 640 */
 641int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
 642                                  char *modes[])
 643{
 644        struct drm_property *tv_selector;
 645        struct drm_property *tv_subconnector;
 646        int i;
 647
 648        if (dev->mode_config.tv_select_subconnector_property)
 649                return 0;
 650
 651        /*
 652         * Basic connector properties
 653         */
 654        tv_selector = drm_property_create(dev, DRM_MODE_PROP_ENUM,
 655                                          "select subconnector",
 656                                          ARRAY_SIZE(drm_tv_select_enum_list));
 657        for (i = 0; i < ARRAY_SIZE(drm_tv_select_enum_list); i++)
 658                drm_property_add_enum(tv_selector, i,
 659                                      drm_tv_select_enum_list[i].type,
 660                                      drm_tv_select_enum_list[i].name);
 661        dev->mode_config.tv_select_subconnector_property = tv_selector;
 662
 663        tv_subconnector =
 664                drm_property_create(dev, DRM_MODE_PROP_ENUM |
 665                                    DRM_MODE_PROP_IMMUTABLE, "subconnector",
 666                                    ARRAY_SIZE(drm_tv_subconnector_enum_list));
 667        for (i = 0; i < ARRAY_SIZE(drm_tv_subconnector_enum_list); i++)
 668                drm_property_add_enum(tv_subconnector, i,
 669                                      drm_tv_subconnector_enum_list[i].type,
 670                                      drm_tv_subconnector_enum_list[i].name);
 671        dev->mode_config.tv_subconnector_property = tv_subconnector;
 672
 673        /*
 674         * Other, TV specific properties: margins & TV modes.
 675         */
 676        dev->mode_config.tv_left_margin_property =
 677                drm_property_create(dev, DRM_MODE_PROP_RANGE,
 678                                    "left margin", 2);
 679        dev->mode_config.tv_left_margin_property->values[0] = 0;
 680        dev->mode_config.tv_left_margin_property->values[1] = 100;
 681
 682        dev->mode_config.tv_right_margin_property =
 683                drm_property_create(dev, DRM_MODE_PROP_RANGE,
 684                                    "right margin", 2);
 685        dev->mode_config.tv_right_margin_property->values[0] = 0;
 686        dev->mode_config.tv_right_margin_property->values[1] = 100;
 687
 688        dev->mode_config.tv_top_margin_property =
 689                drm_property_create(dev, DRM_MODE_PROP_RANGE,
 690                                    "top margin", 2);
 691        dev->mode_config.tv_top_margin_property->values[0] = 0;
 692        dev->mode_config.tv_top_margin_property->values[1] = 100;
 693
 694        dev->mode_config.tv_bottom_margin_property =
 695                drm_property_create(dev, DRM_MODE_PROP_RANGE,
 696                                    "bottom margin", 2);
 697        dev->mode_config.tv_bottom_margin_property->values[0] = 0;
 698        dev->mode_config.tv_bottom_margin_property->values[1] = 100;
 699
 700        dev->mode_config.tv_mode_property =
 701                drm_property_create(dev, DRM_MODE_PROP_ENUM,
 702                                    "mode", num_modes);
 703        for (i = 0; i < num_modes; i++)
 704                drm_property_add_enum(dev->mode_config.tv_mode_property, i,
 705                                      i, modes[i]);
 706
 707        dev->mode_config.tv_brightness_property =
 708                drm_property_create(dev, DRM_MODE_PROP_RANGE,
 709                                    "brightness", 2);
 710        dev->mode_config.tv_brightness_property->values[0] = 0;
 711        dev->mode_config.tv_brightness_property->values[1] = 100;
 712
 713        dev->mode_config.tv_contrast_property =
 714                drm_property_create(dev, DRM_MODE_PROP_RANGE,
 715                                    "contrast", 2);
 716        dev->mode_config.tv_contrast_property->values[0] = 0;
 717        dev->mode_config.tv_contrast_property->values[1] = 100;
 718
 719        dev->mode_config.tv_flicker_reduction_property =
 720                drm_property_create(dev, DRM_MODE_PROP_RANGE,
 721                                    "flicker reduction", 2);
 722        dev->mode_config.tv_flicker_reduction_property->values[0] = 0;
 723        dev->mode_config.tv_flicker_reduction_property->values[1] = 100;
 724
 725        dev->mode_config.tv_overscan_property =
 726                drm_property_create(dev, DRM_MODE_PROP_RANGE,
 727                                    "overscan", 2);
 728        dev->mode_config.tv_overscan_property->values[0] = 0;
 729        dev->mode_config.tv_overscan_property->values[1] = 100;
 730
 731        dev->mode_config.tv_saturation_property =
 732                drm_property_create(dev, DRM_MODE_PROP_RANGE,
 733                                    "saturation", 2);
 734        dev->mode_config.tv_saturation_property->values[0] = 0;
 735        dev->mode_config.tv_saturation_property->values[1] = 100;
 736
 737        dev->mode_config.tv_hue_property =
 738                drm_property_create(dev, DRM_MODE_PROP_RANGE,
 739                                    "hue", 2);
 740        dev->mode_config.tv_hue_property->values[0] = 0;
 741        dev->mode_config.tv_hue_property->values[1] = 100;
 742
 743        return 0;
 744}
 745EXPORT_SYMBOL(drm_mode_create_tv_properties);
 746
 747/**
 748 * drm_mode_create_scaling_mode_property - create scaling mode property
 749 * @dev: DRM device
 750 *
 751 * Called by a driver the first time it's needed, must be attached to desired
 752 * connectors.
 753 */
 754int drm_mode_create_scaling_mode_property(struct drm_device *dev)
 755{
 756        struct drm_property *scaling_mode;
 757        int i;
 758
 759        if (dev->mode_config.scaling_mode_property)
 760                return 0;
 761
 762        scaling_mode =
 763                drm_property_create(dev, DRM_MODE_PROP_ENUM, "scaling mode",
 764                                    ARRAY_SIZE(drm_scaling_mode_enum_list));
 765        for (i = 0; i < ARRAY_SIZE(drm_scaling_mode_enum_list); i++)
 766                drm_property_add_enum(scaling_mode, i,
 767                                      drm_scaling_mode_enum_list[i].type,
 768                                      drm_scaling_mode_enum_list[i].name);
 769
 770        dev->mode_config.scaling_mode_property = scaling_mode;
 771
 772        return 0;
 773}
 774EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
 775
 776/**
 777 * drm_mode_create_dithering_property - create dithering property
 778 * @dev: DRM device
 779 *
 780 * Called by a driver the first time it's needed, must be attached to desired
 781 * connectors.
 782 */
 783int drm_mode_create_dithering_property(struct drm_device *dev)
 784{
 785        struct drm_property *dithering_mode;
 786        int i;
 787
 788        if (dev->mode_config.dithering_mode_property)
 789                return 0;
 790
 791        dithering_mode =
 792                drm_property_create(dev, DRM_MODE_PROP_ENUM, "dithering",
 793                                    ARRAY_SIZE(drm_dithering_mode_enum_list));
 794        for (i = 0; i < ARRAY_SIZE(drm_dithering_mode_enum_list); i++)
 795                drm_property_add_enum(dithering_mode, i,
 796                                      drm_dithering_mode_enum_list[i].type,
 797                                      drm_dithering_mode_enum_list[i].name);
 798        dev->mode_config.dithering_mode_property = dithering_mode;
 799
 800        return 0;
 801}
 802EXPORT_SYMBOL(drm_mode_create_dithering_property);
 803
 804/**
 805 * drm_mode_config_init - initialize DRM mode_configuration structure
 806 * @dev: DRM device
 807 *
 808 * LOCKING:
 809 * None, should happen single threaded at init time.
 810 *
 811 * Initialize @dev's mode_config structure, used for tracking the graphics
 812 * configuration of @dev.
 813 */
 814void drm_mode_config_init(struct drm_device *dev)
 815{
 816        mutex_init(&dev->mode_config.mutex);
 817        mutex_init(&dev->mode_config.idr_mutex);
 818        INIT_LIST_HEAD(&dev->mode_config.fb_list);
 819        INIT_LIST_HEAD(&dev->mode_config.fb_kernel_list);
 820        INIT_LIST_HEAD(&dev->mode_config.crtc_list);
 821        INIT_LIST_HEAD(&dev->mode_config.connector_list);
 822        INIT_LIST_HEAD(&dev->mode_config.encoder_list);
 823        INIT_LIST_HEAD(&dev->mode_config.property_list);
 824        INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
 825        idr_init(&dev->mode_config.crtc_idr);
 826
 827        mutex_lock(&dev->mode_config.mutex);
 828        drm_mode_create_standard_connector_properties(dev);
 829        mutex_unlock(&dev->mode_config.mutex);
 830
 831        /* Just to be sure */
 832        dev->mode_config.num_fb = 0;
 833        dev->mode_config.num_connector = 0;
 834        dev->mode_config.num_crtc = 0;
 835        dev->mode_config.num_encoder = 0;
 836}
 837EXPORT_SYMBOL(drm_mode_config_init);
 838
 839int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
 840{
 841        uint32_t total_objects = 0;
 842
 843        total_objects += dev->mode_config.num_crtc;
 844        total_objects += dev->mode_config.num_connector;
 845        total_objects += dev->mode_config.num_encoder;
 846
 847        if (total_objects == 0)
 848                return -EINVAL;
 849
 850        group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
 851        if (!group->id_list)
 852                return -ENOMEM;
 853
 854        group->num_crtcs = 0;
 855        group->num_connectors = 0;
 856        group->num_encoders = 0;
 857        return 0;
 858}
 859
 860int drm_mode_group_init_legacy_group(struct drm_device *dev,
 861                                     struct drm_mode_group *group)
 862{
 863        struct drm_crtc *crtc;
 864        struct drm_encoder *encoder;
 865        struct drm_connector *connector;
 866        int ret;
 867
 868        if ((ret = drm_mode_group_init(dev, group)))
 869                return ret;
 870
 871        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
 872                group->id_list[group->num_crtcs++] = crtc->base.id;
 873
 874        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
 875                group->id_list[group->num_crtcs + group->num_encoders++] =
 876                encoder->base.id;
 877
 878        list_for_each_entry(connector, &dev->mode_config.connector_list, head)
 879                group->id_list[group->num_crtcs + group->num_encoders +
 880                               group->num_connectors++] = connector->base.id;
 881
 882        return 0;
 883}
 884
 885/**
 886 * drm_mode_config_cleanup - free up DRM mode_config info
 887 * @dev: DRM device
 888 *
 889 * LOCKING:
 890 * Caller must hold mode config lock.
 891 *
 892 * Free up all the connectors and CRTCs associated with this DRM device, then
 893 * free up the framebuffers and associated buffer objects.
 894 *
 895 * FIXME: cleanup any dangling user buffer objects too
 896 */
 897void drm_mode_config_cleanup(struct drm_device *dev)
 898{
 899        struct drm_connector *connector, *ot;
 900        struct drm_crtc *crtc, *ct;
 901        struct drm_encoder *encoder, *enct;
 902        struct drm_framebuffer *fb, *fbt;
 903        struct drm_property *property, *pt;
 904
 905        list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
 906                                 head) {
 907                encoder->funcs->destroy(encoder);
 908        }
 909
 910        list_for_each_entry_safe(connector, ot,
 911                                 &dev->mode_config.connector_list, head) {
 912                connector->funcs->destroy(connector);
 913        }
 914
 915        list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
 916                                 head) {
 917                drm_property_destroy(dev, property);
 918        }
 919
 920        list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
 921                fb->funcs->destroy(fb);
 922        }
 923
 924        list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
 925                crtc->funcs->destroy(crtc);
 926        }
 927
 928}
 929EXPORT_SYMBOL(drm_mode_config_cleanup);
 930
 931/**
 932 * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
 933 * @out: drm_mode_modeinfo struct to return to the user
 934 * @in: drm_display_mode to use
 935 *
 936 * LOCKING:
 937 * None.
 938 *
 939 * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
 940 * the user.
 941 */
 942void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
 943                               struct drm_display_mode *in)
 944{
 945        out->clock = in->clock;
 946        out->hdisplay = in->hdisplay;
 947        out->hsync_start = in->hsync_start;
 948        out->hsync_end = in->hsync_end;
 949        out->htotal = in->htotal;
 950        out->hskew = in->hskew;
 951        out->vdisplay = in->vdisplay;
 952        out->vsync_start = in->vsync_start;
 953        out->vsync_end = in->vsync_end;
 954        out->vtotal = in->vtotal;
 955        out->vscan = in->vscan;
 956        out->vrefresh = in->vrefresh;
 957        out->flags = in->flags;
 958        out->type = in->type;
 959        strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
 960        out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
 961}
 962
 963/**
 964 * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode
 965 * @out: drm_display_mode to return to the user
 966 * @in: drm_mode_modeinfo to use
 967 *
 968 * LOCKING:
 969 * None.
 970 *
 971 * Convert a drm_mode_modeinfo into a drm_display_mode structure to return to
 972 * the caller.
 973 */
 974void drm_crtc_convert_umode(struct drm_display_mode *out,
 975                            struct drm_mode_modeinfo *in)
 976{
 977        out->clock = in->clock;
 978        out->hdisplay = in->hdisplay;
 979        out->hsync_start = in->hsync_start;
 980        out->hsync_end = in->hsync_end;
 981        out->htotal = in->htotal;
 982        out->hskew = in->hskew;
 983        out->vdisplay = in->vdisplay;
 984        out->vsync_start = in->vsync_start;
 985        out->vsync_end = in->vsync_end;
 986        out->vtotal = in->vtotal;
 987        out->vscan = in->vscan;
 988        out->vrefresh = in->vrefresh;
 989        out->flags = in->flags;
 990        out->type = in->type;
 991        strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
 992        out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
 993}
 994
 995/**
 996 * drm_mode_getresources - get graphics configuration
 997 * @inode: inode from the ioctl
 998 * @filp: file * from the ioctl
 999 * @cmd: cmd from ioctl
1000 * @arg: arg from ioctl
1001 *
1002 * LOCKING:
1003 * Takes mode config lock.
1004 *
1005 * Construct a set of configuration description structures and return
1006 * them to the user, including CRTC, connector and framebuffer configuration.
1007 *
1008 * Called by the user via ioctl.
1009 *
1010 * RETURNS:
1011 * Zero on success, errno on failure.
1012 */
1013int drm_mode_getresources(struct drm_device *dev, void *data,
1014                          struct drm_file *file_priv)
1015{
1016        struct drm_mode_card_res *card_res = data;
1017        struct list_head *lh;
1018        struct drm_framebuffer *fb;
1019        struct drm_connector *connector;
1020        struct drm_crtc *crtc;
1021        struct drm_encoder *encoder;
1022        int ret = 0;
1023        int connector_count = 0;
1024        int crtc_count = 0;
1025        int fb_count = 0;
1026        int encoder_count = 0;
1027        int copied = 0, i;
1028        uint32_t __user *fb_id;
1029        uint32_t __user *crtc_id;
1030        uint32_t __user *connector_id;
1031        uint32_t __user *encoder_id;
1032        struct drm_mode_group *mode_group;
1033
1034        mutex_lock(&dev->mode_config.mutex);
1035
1036        /*
1037         * For the non-control nodes we need to limit the list of resources
1038         * by IDs in the group list for this node
1039         */
1040        list_for_each(lh, &file_priv->fbs)
1041                fb_count++;
1042
1043        mode_group = &file_priv->master->minor->mode_group;
1044        if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1045
1046                list_for_each(lh, &dev->mode_config.crtc_list)
1047                        crtc_count++;
1048
1049                list_for_each(lh, &dev->mode_config.connector_list)
1050                        connector_count++;
1051
1052                list_for_each(lh, &dev->mode_config.encoder_list)
1053                        encoder_count++;
1054        } else {
1055
1056                crtc_count = mode_group->num_crtcs;
1057                connector_count = mode_group->num_connectors;
1058                encoder_count = mode_group->num_encoders;
1059        }
1060
1061        card_res->max_height = dev->mode_config.max_height;
1062        card_res->min_height = dev->mode_config.min_height;
1063        card_res->max_width = dev->mode_config.max_width;
1064        card_res->min_width = dev->mode_config.min_width;
1065
1066        /* handle this in 4 parts */
1067        /* FBs */
1068        if (card_res->count_fbs >= fb_count) {
1069                copied = 0;
1070                fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr;
1071                list_for_each_entry(fb, &file_priv->fbs, head) {
1072                        if (put_user(fb->base.id, fb_id + copied)) {
1073                                ret = -EFAULT;
1074                                goto out;
1075                        }
1076                        copied++;
1077                }
1078        }
1079        card_res->count_fbs = fb_count;
1080
1081        /* CRTCs */
1082        if (card_res->count_crtcs >= crtc_count) {
1083                copied = 0;
1084                crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr;
1085                if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1086                        list_for_each_entry(crtc, &dev->mode_config.crtc_list,
1087                                            head) {
1088                                DRM_DEBUG_KMS("CRTC ID is %d\n", crtc->base.id);
1089                                if (put_user(crtc->base.id, crtc_id + copied)) {
1090                                        ret = -EFAULT;
1091                                        goto out;
1092                                }
1093                                copied++;
1094                        }
1095                } else {
1096                        for (i = 0; i < mode_group->num_crtcs; i++) {
1097                                if (put_user(mode_group->id_list[i],
1098                                             crtc_id + copied)) {
1099                                        ret = -EFAULT;
1100                                        goto out;
1101                                }
1102                                copied++;
1103                        }
1104                }
1105        }
1106        card_res->count_crtcs = crtc_count;
1107
1108        /* Encoders */
1109        if (card_res->count_encoders >= encoder_count) {
1110                copied = 0;
1111                encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr;
1112                if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1113                        list_for_each_entry(encoder,
1114                                            &dev->mode_config.encoder_list,
1115                                            head) {
1116                                DRM_DEBUG_KMS("ENCODER ID is %d\n",
1117                                          encoder->base.id);
1118                                if (put_user(encoder->base.id, encoder_id +
1119                                             copied)) {
1120                                        ret = -EFAULT;
1121                                        goto out;
1122                                }
1123                                copied++;
1124                        }
1125                } else {
1126                        for (i = mode_group->num_crtcs; i < mode_group->num_crtcs + mode_group->num_encoders; i++) {
1127                                if (put_user(mode_group->id_list[i],
1128                                             encoder_id + copied)) {
1129                                        ret = -EFAULT;
1130                                        goto out;
1131                                }
1132                                copied++;
1133                        }
1134
1135                }
1136        }
1137        card_res->count_encoders = encoder_count;
1138
1139        /* Connectors */
1140        if (card_res->count_connectors >= connector_count) {
1141                copied = 0;
1142                connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr;
1143                if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1144                        list_for_each_entry(connector,
1145                                            &dev->mode_config.connector_list,
1146                                            head) {
1147                                DRM_DEBUG_KMS("CONNECTOR ID is %d\n",
1148                                          connector->base.id);
1149                                if (put_user(connector->base.id,
1150                                             connector_id + copied)) {
1151                                        ret = -EFAULT;
1152                                        goto out;
1153                                }
1154                                copied++;
1155                        }
1156                } else {
1157                        int start = mode_group->num_crtcs +
1158                                mode_group->num_encoders;
1159                        for (i = start; i < start + mode_group->num_connectors; i++) {
1160                                if (put_user(mode_group->id_list[i],
1161                                             connector_id + copied)) {
1162                                        ret = -EFAULT;
1163                                        goto out;
1164                                }
1165                                copied++;
1166                        }
1167                }
1168        }
1169        card_res->count_connectors = connector_count;
1170
1171        DRM_DEBUG_KMS("Counted %d %d %d\n", card_res->count_crtcs,
1172                  card_res->count_connectors, card_res->count_encoders);
1173
1174out:
1175        mutex_unlock(&dev->mode_config.mutex);
1176        return ret;
1177}
1178
1179/**
1180 * drm_mode_getcrtc - get CRTC configuration
1181 * @inode: inode from the ioctl
1182 * @filp: file * from the ioctl
1183 * @cmd: cmd from ioctl
1184 * @arg: arg from ioctl
1185 *
1186 * LOCKING:
1187 * Caller? (FIXME)
1188 *
1189 * Construct a CRTC configuration structure to return to the user.
1190 *
1191 * Called by the user via ioctl.
1192 *
1193 * RETURNS:
1194 * Zero on success, errno on failure.
1195 */
1196int drm_mode_getcrtc(struct drm_device *dev,
1197                     void *data, struct drm_file *file_priv)
1198{
1199        struct drm_mode_crtc *crtc_resp = data;
1200        struct drm_crtc *crtc;
1201        struct drm_mode_object *obj;
1202        int ret = 0;
1203
1204        mutex_lock(&dev->mode_config.mutex);
1205
1206        obj = drm_mode_object_find(dev, crtc_resp->crtc_id,
1207                                   DRM_MODE_OBJECT_CRTC);
1208        if (!obj) {
1209                ret = -EINVAL;
1210                goto out;
1211        }
1212        crtc = obj_to_crtc(obj);
1213
1214        crtc_resp->x = crtc->x;
1215        crtc_resp->y = crtc->y;
1216        crtc_resp->gamma_size = crtc->gamma_size;
1217        if (crtc->fb)
1218                crtc_resp->fb_id = crtc->fb->base.id;
1219        else
1220                crtc_resp->fb_id = 0;
1221
1222        if (crtc->enabled) {
1223
1224                drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode);
1225                crtc_resp->mode_valid = 1;
1226
1227        } else {
1228                crtc_resp->mode_valid = 0;
1229        }
1230
1231out:
1232        mutex_unlock(&dev->mode_config.mutex);
1233        return ret;
1234}
1235
1236/**
1237 * drm_mode_getconnector - get connector configuration
1238 * @inode: inode from the ioctl
1239 * @filp: file * from the ioctl
1240 * @cmd: cmd from ioctl
1241 * @arg: arg from ioctl
1242 *
1243 * LOCKING:
1244 * Caller? (FIXME)
1245 *
1246 * Construct a connector configuration structure to return to the user.
1247 *
1248 * Called by the user via ioctl.
1249 *
1250 * RETURNS:
1251 * Zero on success, errno on failure.
1252 */
1253int drm_mode_getconnector(struct drm_device *dev, void *data,
1254                          struct drm_file *file_priv)
1255{
1256        struct drm_mode_get_connector *out_resp = data;
1257        struct drm_mode_object *obj;
1258        struct drm_connector *connector;
1259        struct drm_display_mode *mode;
1260        int mode_count = 0;
1261        int props_count = 0;
1262        int encoders_count = 0;
1263        int ret = 0;
1264        int copied = 0;
1265        int i;
1266        struct drm_mode_modeinfo u_mode;
1267        struct drm_mode_modeinfo __user *mode_ptr;
1268        uint32_t __user *prop_ptr;
1269        uint64_t __user *prop_values;
1270        uint32_t __user *encoder_ptr;
1271
1272        memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
1273
1274        DRM_DEBUG_KMS("connector id %d:\n", out_resp->connector_id);
1275
1276        mutex_lock(&dev->mode_config.mutex);
1277
1278        obj = drm_mode_object_find(dev, out_resp->connector_id,
1279                                   DRM_MODE_OBJECT_CONNECTOR);
1280        if (!obj) {
1281                ret = -EINVAL;
1282                goto out;
1283        }
1284        connector = obj_to_connector(obj);
1285
1286        for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
1287                if (connector->property_ids[i] != 0) {
1288                        props_count++;
1289                }
1290        }
1291
1292        for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1293                if (connector->encoder_ids[i] != 0) {
1294                        encoders_count++;
1295                }
1296        }
1297
1298        if (out_resp->count_modes == 0) {
1299                connector->funcs->fill_modes(connector,
1300                                             dev->mode_config.max_width,
1301                                             dev->mode_config.max_height);
1302        }
1303
1304        /* delayed so we get modes regardless of pre-fill_modes state */
1305        list_for_each_entry(mode, &connector->modes, head)
1306                mode_count++;
1307
1308        out_resp->connector_id = connector->base.id;
1309        out_resp->connector_type = connector->connector_type;
1310        out_resp->connector_type_id = connector->connector_type_id;
1311        out_resp->mm_width = connector->display_info.width_mm;
1312        out_resp->mm_height = connector->display_info.height_mm;
1313        out_resp->subpixel = connector->display_info.subpixel_order;
1314        out_resp->connection = connector->status;
1315        if (connector->encoder)
1316                out_resp->encoder_id = connector->encoder->base.id;
1317        else
1318                out_resp->encoder_id = 0;
1319
1320        /*
1321         * This ioctl is called twice, once to determine how much space is
1322         * needed, and the 2nd time to fill it.
1323         */
1324        if ((out_resp->count_modes >= mode_count) && mode_count) {
1325                copied = 0;
1326                mode_ptr = (struct drm_mode_modeinfo *)(unsigned long)out_resp->modes_ptr;
1327                list_for_each_entry(mode, &connector->modes, head) {
1328                        drm_crtc_convert_to_umode(&u_mode, mode);
1329                        if (copy_to_user(mode_ptr + copied,
1330                                         &u_mode, sizeof(u_mode))) {
1331                                ret = -EFAULT;
1332                                goto out;
1333                        }
1334                        copied++;
1335                }
1336        }
1337        out_resp->count_modes = mode_count;
1338
1339        if ((out_resp->count_props >= props_count) && props_count) {
1340                copied = 0;
1341                prop_ptr = (uint32_t *)(unsigned long)(out_resp->props_ptr);
1342                prop_values = (uint64_t *)(unsigned long)(out_resp->prop_values_ptr);
1343                for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
1344                        if (connector->property_ids[i] != 0) {
1345                                if (put_user(connector->property_ids[i],
1346                                             prop_ptr + copied)) {
1347                                        ret = -EFAULT;
1348                                        goto out;
1349                                }
1350
1351                                if (put_user(connector->property_values[i],
1352                                             prop_values + copied)) {
1353                                        ret = -EFAULT;
1354                                        goto out;
1355                                }
1356                                copied++;
1357                        }
1358                }
1359        }
1360        out_resp->count_props = props_count;
1361
1362        if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
1363                copied = 0;
1364                encoder_ptr = (uint32_t *)(unsigned long)(out_resp->encoders_ptr);
1365                for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1366                        if (connector->encoder_ids[i] != 0) {
1367                                if (put_user(connector->encoder_ids[i],
1368                                             encoder_ptr + copied)) {
1369                                        ret = -EFAULT;
1370                                        goto out;
1371                                }
1372                                copied++;
1373                        }
1374                }
1375        }
1376        out_resp->count_encoders = encoders_count;
1377
1378out:
1379        mutex_unlock(&dev->mode_config.mutex);
1380        return ret;
1381}
1382
1383int drm_mode_getencoder(struct drm_device *dev, void *data,
1384                        struct drm_file *file_priv)
1385{
1386        struct drm_mode_get_encoder *enc_resp = data;
1387        struct drm_mode_object *obj;
1388        struct drm_encoder *encoder;
1389        int ret = 0;
1390
1391        mutex_lock(&dev->mode_config.mutex);
1392        obj = drm_mode_object_find(dev, enc_resp->encoder_id,
1393                                   DRM_MODE_OBJECT_ENCODER);
1394        if (!obj) {
1395                ret = -EINVAL;
1396                goto out;
1397        }
1398        encoder = obj_to_encoder(obj);
1399
1400        if (encoder->crtc)
1401                enc_resp->crtc_id = encoder->crtc->base.id;
1402        else
1403                enc_resp->crtc_id = 0;
1404        enc_resp->encoder_type = encoder->encoder_type;
1405        enc_resp->encoder_id = encoder->base.id;
1406        enc_resp->possible_crtcs = encoder->possible_crtcs;
1407        enc_resp->possible_clones = encoder->possible_clones;
1408
1409out:
1410        mutex_unlock(&dev->mode_config.mutex);
1411        return ret;
1412}
1413
1414/**
1415 * drm_mode_setcrtc - set CRTC configuration
1416 * @inode: inode from the ioctl
1417 * @filp: file * from the ioctl
1418 * @cmd: cmd from ioctl
1419 * @arg: arg from ioctl
1420 *
1421 * LOCKING:
1422 * Caller? (FIXME)
1423 *
1424 * Build a new CRTC configuration based on user request.
1425 *
1426 * Called by the user via ioctl.
1427 *
1428 * RETURNS:
1429 * Zero on success, errno on failure.
1430 */
1431int drm_mode_setcrtc(struct drm_device *dev, void *data,
1432                     struct drm_file *file_priv)
1433{
1434        struct drm_mode_config *config = &dev->mode_config;
1435        struct drm_mode_crtc *crtc_req = data;
1436        struct drm_mode_object *obj;
1437        struct drm_crtc *crtc, *crtcfb;
1438        struct drm_connector **connector_set = NULL, *connector;
1439        struct drm_framebuffer *fb = NULL;
1440        struct drm_display_mode *mode = NULL;
1441        struct drm_mode_set set;
1442        uint32_t __user *set_connectors_ptr;
1443        int ret = 0;
1444        int i;
1445
1446        mutex_lock(&dev->mode_config.mutex);
1447        obj = drm_mode_object_find(dev, crtc_req->crtc_id,
1448                                   DRM_MODE_OBJECT_CRTC);
1449        if (!obj) {
1450                DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
1451                ret = -EINVAL;
1452                goto out;
1453        }
1454        crtc = obj_to_crtc(obj);
1455
1456        if (crtc_req->mode_valid) {
1457                /* If we have a mode we need a framebuffer. */
1458                /* If we pass -1, set the mode with the currently bound fb */
1459                if (crtc_req->fb_id == -1) {
1460                        list_for_each_entry(crtcfb,
1461                                            &dev->mode_config.crtc_list, head) {
1462                                if (crtcfb == crtc) {
1463                                        DRM_DEBUG_KMS("Using current fb for "
1464                                                        "setmode\n");
1465                                        fb = crtc->fb;
1466                                }
1467                        }
1468                } else {
1469                        obj = drm_mode_object_find(dev, crtc_req->fb_id,
1470                                                   DRM_MODE_OBJECT_FB);
1471                        if (!obj) {
1472                                DRM_DEBUG_KMS("Unknown FB ID%d\n",
1473                                                crtc_req->fb_id);
1474                                ret = -EINVAL;
1475                                goto out;
1476                        }
1477                        fb = obj_to_fb(obj);
1478                }
1479
1480                mode = drm_mode_create(dev);
1481                drm_crtc_convert_umode(mode, &crtc_req->mode);
1482                drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
1483        }
1484
1485        if (crtc_req->count_connectors == 0 && mode) {
1486                DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
1487                ret = -EINVAL;
1488                goto out;
1489        }
1490
1491        if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
1492                DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
1493                          crtc_req->count_connectors);
1494                ret = -EINVAL;
1495                goto out;
1496        }
1497
1498        if (crtc_req->count_connectors > 0) {
1499                u32 out_id;
1500
1501                /* Avoid unbounded kernel memory allocation */
1502                if (crtc_req->count_connectors > config->num_connector) {
1503                        ret = -EINVAL;
1504                        goto out;
1505                }
1506
1507                connector_set = kmalloc(crtc_req->count_connectors *
1508                                        sizeof(struct drm_connector *),
1509                                        GFP_KERNEL);
1510                if (!connector_set) {
1511                        ret = -ENOMEM;
1512                        goto out;
1513                }
1514
1515                for (i = 0; i < crtc_req->count_connectors; i++) {
1516                        set_connectors_ptr = (uint32_t *)(unsigned long)crtc_req->set_connectors_ptr;
1517                        if (get_user(out_id, &set_connectors_ptr[i])) {
1518                                ret = -EFAULT;
1519                                goto out;
1520                        }
1521
1522                        obj = drm_mode_object_find(dev, out_id,
1523                                                   DRM_MODE_OBJECT_CONNECTOR);
1524                        if (!obj) {
1525                                DRM_DEBUG_KMS("Connector id %d unknown\n",
1526                                                out_id);
1527                                ret = -EINVAL;
1528                                goto out;
1529                        }
1530                        connector = obj_to_connector(obj);
1531
1532                        connector_set[i] = connector;
1533                }
1534        }
1535
1536        set.crtc = crtc;
1537        set.x = crtc_req->x;
1538        set.y = crtc_req->y;
1539        set.mode = mode;
1540        set.connectors = connector_set;
1541        set.num_connectors = crtc_req->count_connectors;
1542        set.fb = fb;
1543        ret = crtc->funcs->set_config(&set);
1544
1545out:
1546        kfree(connector_set);
1547        mutex_unlock(&dev->mode_config.mutex);
1548        return ret;
1549}
1550
1551int drm_mode_cursor_ioctl(struct drm_device *dev,
1552                        void *data, struct drm_file *file_priv)
1553{
1554        struct drm_mode_cursor *req = data;
1555        struct drm_mode_object *obj;
1556        struct drm_crtc *crtc;
1557        int ret = 0;
1558
1559        if (!req->flags) {
1560                DRM_ERROR("no operation set\n");
1561                return -EINVAL;
1562        }
1563
1564        mutex_lock(&dev->mode_config.mutex);
1565        obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC);
1566        if (!obj) {
1567                DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
1568                ret = -EINVAL;
1569                goto out;
1570        }
1571        crtc = obj_to_crtc(obj);
1572
1573        if (req->flags & DRM_MODE_CURSOR_BO) {
1574                if (!crtc->funcs->cursor_set) {
1575                        DRM_ERROR("crtc does not support cursor\n");
1576                        ret = -ENXIO;
1577                        goto out;
1578                }
1579                /* Turns off the cursor if handle is 0 */
1580                ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
1581                                              req->width, req->height);
1582        }
1583
1584        if (req->flags & DRM_MODE_CURSOR_MOVE) {
1585                if (crtc->funcs->cursor_move) {
1586                        ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
1587                } else {
1588                        DRM_ERROR("crtc does not support cursor\n");
1589                        ret = -EFAULT;
1590                        goto out;
1591                }
1592        }
1593out:
1594        mutex_unlock(&dev->mode_config.mutex);
1595        return ret;
1596}
1597
1598/**
1599 * drm_mode_addfb - add an FB to the graphics configuration
1600 * @inode: inode from the ioctl
1601 * @filp: file * from the ioctl
1602 * @cmd: cmd from ioctl
1603 * @arg: arg from ioctl
1604 *
1605 * LOCKING:
1606 * Takes mode config lock.
1607 *
1608 * Add a new FB to the specified CRTC, given a user request.
1609 *
1610 * Called by the user via ioctl.
1611 *
1612 * RETURNS:
1613 * Zero on success, errno on failure.
1614 */
1615int drm_mode_addfb(struct drm_device *dev,
1616                   void *data, struct drm_file *file_priv)
1617{
1618        struct drm_mode_fb_cmd *r = data;
1619        struct drm_mode_config *config = &dev->mode_config;
1620        struct drm_framebuffer *fb;
1621        int ret = 0;
1622
1623        if ((config->min_width > r->width) || (r->width > config->max_width)) {
1624                DRM_ERROR("mode new framebuffer width not within limits\n");
1625                return -EINVAL;
1626        }
1627        if ((config->min_height > r->height) || (r->height > config->max_height)) {
1628                DRM_ERROR("mode new framebuffer height not within limits\n");
1629                return -EINVAL;
1630        }
1631
1632        mutex_lock(&dev->mode_config.mutex);
1633
1634        /* TODO check buffer is sufficently large */
1635        /* TODO setup destructor callback */
1636
1637        fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
1638        if (!fb) {
1639                DRM_ERROR("could not create framebuffer\n");
1640                ret = -EINVAL;
1641                goto out;
1642        }
1643
1644        r->fb_id = fb->base.id;
1645        list_add(&fb->filp_head, &file_priv->fbs);
1646
1647out:
1648        mutex_unlock(&dev->mode_config.mutex);
1649        return ret;
1650}
1651
1652/**
1653 * drm_mode_rmfb - remove an FB from the configuration
1654 * @inode: inode from the ioctl
1655 * @filp: file * from the ioctl
1656 * @cmd: cmd from ioctl
1657 * @arg: arg from ioctl
1658 *
1659 * LOCKING:
1660 * Takes mode config lock.
1661 *
1662 * Remove the FB specified by the user.
1663 *
1664 * Called by the user via ioctl.
1665 *
1666 * RETURNS:
1667 * Zero on success, errno on failure.
1668 */
1669int drm_mode_rmfb(struct drm_device *dev,
1670                   void *data, struct drm_file *file_priv)
1671{
1672        struct drm_mode_object *obj;
1673        struct drm_framebuffer *fb = NULL;
1674        struct drm_framebuffer *fbl = NULL;
1675        uint32_t *id = data;
1676        int ret = 0;
1677        int found = 0;
1678
1679        mutex_lock(&dev->mode_config.mutex);
1680        obj = drm_mode_object_find(dev, *id, DRM_MODE_OBJECT_FB);
1681        /* TODO check that we realy get a framebuffer back. */
1682        if (!obj) {
1683                DRM_ERROR("mode invalid framebuffer id\n");
1684                ret = -EINVAL;
1685                goto out;
1686        }
1687        fb = obj_to_fb(obj);
1688
1689        list_for_each_entry(fbl, &file_priv->fbs, filp_head)
1690                if (fb == fbl)
1691                        found = 1;
1692
1693        if (!found) {
1694                DRM_ERROR("tried to remove a fb that we didn't own\n");
1695                ret = -EINVAL;
1696                goto out;
1697        }
1698
1699        /* TODO release all crtc connected to the framebuffer */
1700        /* TODO unhock the destructor from the buffer object */
1701
1702        list_del(&fb->filp_head);
1703        fb->funcs->destroy(fb);
1704
1705out:
1706        mutex_unlock(&dev->mode_config.mutex);
1707        return ret;
1708}
1709
1710/**
1711 * drm_mode_getfb - get FB info
1712 * @inode: inode from the ioctl
1713 * @filp: file * from the ioctl
1714 * @cmd: cmd from ioctl
1715 * @arg: arg from ioctl
1716 *
1717 * LOCKING:
1718 * Caller? (FIXME)
1719 *
1720 * Lookup the FB given its ID and return info about it.
1721 *
1722 * Called by the user via ioctl.
1723 *
1724 * RETURNS:
1725 * Zero on success, errno on failure.
1726 */
1727int drm_mode_getfb(struct drm_device *dev,
1728                   void *data, struct drm_file *file_priv)
1729{
1730        struct drm_mode_fb_cmd *r = data;
1731        struct drm_mode_object *obj;
1732        struct drm_framebuffer *fb;
1733        int ret = 0;
1734
1735        mutex_lock(&dev->mode_config.mutex);
1736        obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB);
1737        if (!obj) {
1738                DRM_ERROR("invalid framebuffer id\n");
1739                ret = -EINVAL;
1740                goto out;
1741        }
1742        fb = obj_to_fb(obj);
1743
1744        r->height = fb->height;
1745        r->width = fb->width;
1746        r->depth = fb->depth;
1747        r->bpp = fb->bits_per_pixel;
1748        r->pitch = fb->pitch;
1749        fb->funcs->create_handle(fb, file_priv, &r->handle);
1750
1751out:
1752        mutex_unlock(&dev->mode_config.mutex);
1753        return ret;
1754}
1755
1756/**
1757 * drm_fb_release - remove and free the FBs on this file
1758 * @filp: file * from the ioctl
1759 *
1760 * LOCKING:
1761 * Takes mode config lock.
1762 *
1763 * Destroy all the FBs associated with @filp.
1764 *
1765 * Called by the user via ioctl.
1766 *
1767 * RETURNS:
1768 * Zero on success, errno on failure.
1769 */
1770void drm_fb_release(struct drm_file *priv)
1771{
1772        struct drm_device *dev = priv->minor->dev;
1773        struct drm_framebuffer *fb, *tfb;
1774
1775        mutex_lock(&dev->mode_config.mutex);
1776        list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
1777                list_del(&fb->filp_head);
1778                fb->funcs->destroy(fb);
1779        }
1780        mutex_unlock(&dev->mode_config.mutex);
1781}
1782
1783/**
1784 * drm_mode_attachmode - add a mode to the user mode list
1785 * @dev: DRM device
1786 * @connector: connector to add the mode to
1787 * @mode: mode to add
1788 *
1789 * Add @mode to @connector's user mode list.
1790 */
1791static int drm_mode_attachmode(struct drm_device *dev,
1792                               struct drm_connector *connector,
1793                               struct drm_display_mode *mode)
1794{
1795        int ret = 0;
1796
1797        list_add_tail(&mode->head, &connector->user_modes);
1798        return ret;
1799}
1800
1801int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc,
1802                             struct drm_display_mode *mode)
1803{
1804        struct drm_connector *connector;
1805        int ret = 0;
1806        struct drm_display_mode *dup_mode;
1807        int need_dup = 0;
1808        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1809                if (!connector->encoder)
1810                        break;
1811                if (connector->encoder->crtc == crtc) {
1812                        if (need_dup)
1813                                dup_mode = drm_mode_duplicate(dev, mode);
1814                        else
1815                                dup_mode = mode;
1816                        ret = drm_mode_attachmode(dev, connector, dup_mode);
1817                        if (ret)
1818                                return ret;
1819                        need_dup = 1;
1820                }
1821        }
1822        return 0;
1823}
1824EXPORT_SYMBOL(drm_mode_attachmode_crtc);
1825
1826static int drm_mode_detachmode(struct drm_device *dev,
1827                               struct drm_connector *connector,
1828                               struct drm_display_mode *mode)
1829{
1830        int found = 0;
1831        int ret = 0;
1832        struct drm_display_mode *match_mode, *t;
1833
1834        list_for_each_entry_safe(match_mode, t, &connector->user_modes, head) {
1835                if (drm_mode_equal(match_mode, mode)) {
1836                        list_del(&match_mode->head);
1837                        drm_mode_destroy(dev, match_mode);
1838                        found = 1;
1839                        break;
1840                }
1841        }
1842
1843        if (!found)
1844                ret = -EINVAL;
1845
1846        return ret;
1847}
1848
1849int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode)
1850{
1851        struct drm_connector *connector;
1852
1853        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1854                drm_mode_detachmode(dev, connector, mode);
1855        }
1856        return 0;
1857}
1858EXPORT_SYMBOL(drm_mode_detachmode_crtc);
1859
1860/**
1861 * drm_fb_attachmode - Attach a user mode to an connector
1862 * @inode: inode from the ioctl
1863 * @filp: file * from the ioctl
1864 * @cmd: cmd from ioctl
1865 * @arg: arg from ioctl
1866 *
1867 * This attaches a user specified mode to an connector.
1868 * Called by the user via ioctl.
1869 *
1870 * RETURNS:
1871 * Zero on success, errno on failure.
1872 */
1873int drm_mode_attachmode_ioctl(struct drm_device *dev,
1874                              void *data, struct drm_file *file_priv)
1875{
1876        struct drm_mode_mode_cmd *mode_cmd = data;
1877        struct drm_connector *connector;
1878        struct drm_display_mode *mode;
1879        struct drm_mode_object *obj;
1880        struct drm_mode_modeinfo *umode = &mode_cmd->mode;
1881        int ret = 0;
1882
1883        mutex_lock(&dev->mode_config.mutex);
1884
1885        obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
1886        if (!obj) {
1887                ret = -EINVAL;
1888                goto out;
1889        }
1890        connector = obj_to_connector(obj);
1891
1892        mode = drm_mode_create(dev);
1893        if (!mode) {
1894                ret = -ENOMEM;
1895                goto out;
1896        }
1897
1898        drm_crtc_convert_umode(mode, umode);
1899
1900        ret = drm_mode_attachmode(dev, connector, mode);
1901out:
1902        mutex_unlock(&dev->mode_config.mutex);
1903        return ret;
1904}
1905
1906
1907/**
1908 * drm_fb_detachmode - Detach a user specified mode from an connector
1909 * @inode: inode from the ioctl
1910 * @filp: file * from the ioctl
1911 * @cmd: cmd from ioctl
1912 * @arg: arg from ioctl
1913 *
1914 * Called by the user via ioctl.
1915 *
1916 * RETURNS:
1917 * Zero on success, errno on failure.
1918 */
1919int drm_mode_detachmode_ioctl(struct drm_device *dev,
1920                              void *data, struct drm_file *file_priv)
1921{
1922        struct drm_mode_object *obj;
1923        struct drm_mode_mode_cmd *mode_cmd = data;
1924        struct drm_connector *connector;
1925        struct drm_display_mode mode;
1926        struct drm_mode_modeinfo *umode = &mode_cmd->mode;
1927        int ret = 0;
1928
1929        mutex_lock(&dev->mode_config.mutex);
1930
1931        obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
1932        if (!obj) {
1933                ret = -EINVAL;
1934                goto out;
1935        }
1936        connector = obj_to_connector(obj);
1937
1938        drm_crtc_convert_umode(&mode, umode);
1939        ret = drm_mode_detachmode(dev, connector, &mode);
1940out:
1941        mutex_unlock(&dev->mode_config.mutex);
1942        return ret;
1943}
1944
1945struct drm_property *drm_property_create(struct drm_device *dev, int flags,
1946                                         const char *name, int num_values)
1947{
1948        struct drm_property *property = NULL;
1949
1950        property = kzalloc(sizeof(struct drm_property), GFP_KERNEL);
1951        if (!property)
1952                return NULL;
1953
1954        if (num_values) {
1955                property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL);
1956                if (!property->values)
1957                        goto fail;
1958        }
1959
1960        drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY);
1961        property->flags = flags;
1962        property->num_values = num_values;
1963        INIT_LIST_HEAD(&property->enum_blob_list);
1964
1965        if (name)
1966                strncpy(property->name, name, DRM_PROP_NAME_LEN);
1967
1968        list_add_tail(&property->head, &dev->mode_config.property_list);
1969        return property;
1970fail:
1971        kfree(property);
1972        return NULL;
1973}
1974EXPORT_SYMBOL(drm_property_create);
1975
1976int drm_property_add_enum(struct drm_property *property, int index,
1977                          uint64_t value, const char *name)
1978{
1979        struct drm_property_enum *prop_enum;
1980
1981        if (!(property->flags & DRM_MODE_PROP_ENUM))
1982                return -EINVAL;
1983
1984        if (!list_empty(&property->enum_blob_list)) {
1985                list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
1986                        if (prop_enum->value == value) {
1987                                strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
1988                                prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
1989                                return 0;
1990                        }
1991                }
1992        }
1993
1994        prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL);
1995        if (!prop_enum)
1996                return -ENOMEM;
1997
1998        strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
1999        prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
2000        prop_enum->value = value;
2001
2002        property->values[index] = value;
2003        list_add_tail(&prop_enum->head, &property->enum_blob_list);
2004        return 0;
2005}
2006EXPORT_SYMBOL(drm_property_add_enum);
2007
2008void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
2009{
2010        struct drm_property_enum *prop_enum, *pt;
2011
2012        list_for_each_entry_safe(prop_enum, pt, &property->enum_blob_list, head) {
2013                list_del(&prop_enum->head);
2014                kfree(prop_enum);
2015        }
2016
2017        if (property->num_values)
2018                kfree(property->values);
2019        drm_mode_object_put(dev, &property->base);
2020        list_del(&property->head);
2021        kfree(property);
2022}
2023EXPORT_SYMBOL(drm_property_destroy);
2024
2025int drm_connector_attach_property(struct drm_connector *connector,
2026                               struct drm_property *property, uint64_t init_val)
2027{
2028        int i;
2029
2030        for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
2031                if (connector->property_ids[i] == 0) {
2032                        connector->property_ids[i] = property->base.id;
2033                        connector->property_values[i] = init_val;
2034                        break;
2035                }
2036        }
2037
2038        if (i == DRM_CONNECTOR_MAX_PROPERTY)
2039                return -EINVAL;
2040        return 0;
2041}
2042EXPORT_SYMBOL(drm_connector_attach_property);
2043
2044int drm_connector_property_set_value(struct drm_connector *connector,
2045                                  struct drm_property *property, uint64_t value)
2046{
2047        int i;
2048
2049        for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
2050                if (connector->property_ids[i] == property->base.id) {
2051                        connector->property_values[i] = value;
2052                        break;
2053                }
2054        }
2055
2056        if (i == DRM_CONNECTOR_MAX_PROPERTY)
2057                return -EINVAL;
2058        return 0;
2059}
2060EXPORT_SYMBOL(drm_connector_property_set_value);
2061
2062int drm_connector_property_get_value(struct drm_connector *connector,
2063                                  struct drm_property *property, uint64_t *val)
2064{
2065        int i;
2066
2067        for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
2068                if (connector->property_ids[i] == property->base.id) {
2069                        *val = connector->property_values[i];
2070                        break;
2071                }
2072        }
2073
2074        if (i == DRM_CONNECTOR_MAX_PROPERTY)
2075                return -EINVAL;
2076        return 0;
2077}
2078EXPORT_SYMBOL(drm_connector_property_get_value);
2079
2080int drm_mode_getproperty_ioctl(struct drm_device *dev,
2081                               void *data, struct drm_file *file_priv)
2082{
2083        struct drm_mode_object *obj;
2084        struct drm_mode_get_property *out_resp = data;
2085        struct drm_property *property;
2086        int enum_count = 0;
2087        int blob_count = 0;
2088        int value_count = 0;
2089        int ret = 0, i;
2090        int copied;
2091        struct drm_property_enum *prop_enum;
2092        struct drm_mode_property_enum __user *enum_ptr;
2093        struct drm_property_blob *prop_blob;
2094        uint32_t *blob_id_ptr;
2095        uint64_t __user *values_ptr;
2096        uint32_t __user *blob_length_ptr;
2097
2098        mutex_lock(&dev->mode_config.mutex);
2099        obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
2100        if (!obj) {
2101                ret = -EINVAL;
2102                goto done;
2103        }
2104        property = obj_to_property(obj);
2105
2106        if (property->flags & DRM_MODE_PROP_ENUM) {
2107                list_for_each_entry(prop_enum, &property->enum_blob_list, head)
2108                        enum_count++;
2109        } else if (property->flags & DRM_MODE_PROP_BLOB) {
2110                list_for_each_entry(prop_blob, &property->enum_blob_list, head)
2111                        blob_count++;
2112        }
2113
2114        value_count = property->num_values;
2115
2116        strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN);
2117        out_resp->name[DRM_PROP_NAME_LEN-1] = 0;
2118        out_resp->flags = property->flags;
2119
2120        if ((out_resp->count_values >= value_count) && value_count) {
2121                values_ptr = (uint64_t *)(unsigned long)out_resp->values_ptr;
2122                for (i = 0; i < value_count; i++) {
2123                        if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) {
2124                                ret = -EFAULT;
2125                                goto done;
2126                        }
2127                }
2128        }
2129        out_resp->count_values = value_count;
2130
2131        if (property->flags & DRM_MODE_PROP_ENUM) {
2132                if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
2133                        copied = 0;
2134                        enum_ptr = (struct drm_mode_property_enum *)(unsigned long)out_resp->enum_blob_ptr;
2135                        list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
2136
2137                                if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {
2138                                        ret = -EFAULT;
2139                                        goto done;
2140                                }
2141
2142                                if (copy_to_user(&enum_ptr[copied].name,
2143                                                 &prop_enum->name, DRM_PROP_NAME_LEN)) {
2144                                        ret = -EFAULT;
2145                                        goto done;
2146                                }
2147                                copied++;
2148                        }
2149                }
2150                out_resp->count_enum_blobs = enum_count;
2151        }
2152
2153        if (property->flags & DRM_MODE_PROP_BLOB) {
2154                if ((out_resp->count_enum_blobs >= blob_count) && blob_count) {
2155                        copied = 0;
2156                        blob_id_ptr = (uint32_t *)(unsigned long)out_resp->enum_blob_ptr;
2157                        blob_length_ptr = (uint32_t *)(unsigned long)out_resp->values_ptr;
2158
2159                        list_for_each_entry(prop_blob, &property->enum_blob_list, head) {
2160                                if (put_user(prop_blob->base.id, blob_id_ptr + copied)) {
2161                                        ret = -EFAULT;
2162                                        goto done;
2163                                }
2164
2165                                if (put_user(prop_blob->length, blob_length_ptr + copied)) {
2166                                        ret = -EFAULT;
2167                                        goto done;
2168                                }
2169
2170                                copied++;
2171                        }
2172                }
2173                out_resp->count_enum_blobs = blob_count;
2174        }
2175done:
2176        mutex_unlock(&dev->mode_config.mutex);
2177        return ret;
2178}
2179
2180static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length,
2181                                                          void *data)
2182{
2183        struct drm_property_blob *blob;
2184
2185        if (!length || !data)
2186                return NULL;
2187
2188        blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
2189        if (!blob)
2190                return NULL;
2191
2192        blob->data = (void *)((char *)blob + sizeof(struct drm_property_blob));
2193        blob->length = length;
2194
2195        memcpy(blob->data, data, length);
2196
2197        drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB);
2198
2199        list_add_tail(&blob->head, &dev->mode_config.property_blob_list);
2200        return blob;
2201}
2202
2203static void drm_property_destroy_blob(struct drm_device *dev,
2204                               struct drm_property_blob *blob)
2205{
2206        drm_mode_object_put(dev, &blob->base);
2207        list_del(&blob->head);
2208        kfree(blob);
2209}
2210
2211int drm_mode_getblob_ioctl(struct drm_device *dev,
2212                           void *data, struct drm_file *file_priv)
2213{
2214        struct drm_mode_object *obj;
2215        struct drm_mode_get_blob *out_resp = data;
2216        struct drm_property_blob *blob;
2217        int ret = 0;
2218        void *blob_ptr;
2219
2220        mutex_lock(&dev->mode_config.mutex);
2221        obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB);
2222        if (!obj) {
2223                ret = -EINVAL;
2224                goto done;
2225        }
2226        blob = obj_to_blob(obj);
2227
2228        if (out_resp->length == blob->length) {
2229                blob_ptr = (void *)(unsigned long)out_resp->data;
2230                if (copy_to_user(blob_ptr, blob->data, blob->length)){
2231                        ret = -EFAULT;
2232                        goto done;
2233                }
2234        }
2235        out_resp->length = blob->length;
2236
2237done:
2238        mutex_unlock(&dev->mode_config.mutex);
2239        return ret;
2240}
2241
2242int drm_mode_connector_update_edid_property(struct drm_connector *connector,
2243                                            struct edid *edid)
2244{
2245        struct drm_device *dev = connector->dev;
2246        int ret = 0;
2247
2248        if (connector->edid_blob_ptr)
2249                drm_property_destroy_blob(dev, connector->edid_blob_ptr);
2250
2251        /* Delete edid, when there is none. */
2252        if (!edid) {
2253                connector->edid_blob_ptr = NULL;
2254                ret = drm_connector_property_set_value(connector, dev->mode_config.edid_property, 0);
2255                return ret;
2256        }
2257
2258        connector->edid_blob_ptr = drm_property_create_blob(connector->dev, 128, edid);
2259
2260        ret = drm_connector_property_set_value(connector,
2261                                               dev->mode_config.edid_property,
2262                                               connector->edid_blob_ptr->base.id);
2263
2264        return ret;
2265}
2266EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
2267
2268int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
2269                                       void *data, struct drm_file *file_priv)
2270{
2271        struct drm_mode_connector_set_property *out_resp = data;
2272        struct drm_mode_object *obj;
2273        struct drm_property *property;
2274        struct drm_connector *connector;
2275        int ret = -EINVAL;
2276        int i;
2277
2278        mutex_lock(&dev->mode_config.mutex);
2279
2280        obj = drm_mode_object_find(dev, out_resp->connector_id, DRM_MODE_OBJECT_CONNECTOR);
2281        if (!obj) {
2282                goto out;
2283        }
2284        connector = obj_to_connector(obj);
2285
2286        for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
2287                if (connector->property_ids[i] == out_resp->prop_id)
2288                        break;
2289        }
2290
2291        if (i == DRM_CONNECTOR_MAX_PROPERTY) {
2292                goto out;
2293        }
2294
2295        obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
2296        if (!obj) {
2297                goto out;
2298        }
2299        property = obj_to_property(obj);
2300
2301        if (property->flags & DRM_MODE_PROP_IMMUTABLE)
2302                goto out;
2303
2304        if (property->flags & DRM_MODE_PROP_RANGE) {
2305                if (out_resp->value < property->values[0])
2306                        goto out;
2307
2308                if (out_resp->value > property->values[1])
2309                        goto out;
2310        } else {
2311                int found = 0;
2312                for (i = 0; i < property->num_values; i++) {
2313                        if (property->values[i] == out_resp->value) {
2314                                found = 1;
2315                                break;
2316                        }
2317                }
2318                if (!found) {
2319                        goto out;
2320                }
2321        }
2322
2323        /* Do DPMS ourselves */
2324        if (property == connector->dev->mode_config.dpms_property) {
2325                if (connector->funcs->dpms)
2326                        (*connector->funcs->dpms)(connector, (int) out_resp->value);
2327                ret = 0;
2328        } else if (connector->funcs->set_property)
2329                ret = connector->funcs->set_property(connector, property, out_resp->value);
2330
2331        /* store the property value if succesful */
2332        if (!ret)
2333                drm_connector_property_set_value(connector, property, out_resp->value);
2334out:
2335        mutex_unlock(&dev->mode_config.mutex);
2336        return ret;
2337}
2338
2339int drm_mode_connector_attach_encoder(struct drm_connector *connector,
2340                                      struct drm_encoder *encoder)
2341{
2342        int i;
2343
2344        for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
2345                if (connector->encoder_ids[i] == 0) {
2346                        connector->encoder_ids[i] = encoder->base.id;
2347                        return 0;
2348                }
2349        }
2350        return -ENOMEM;
2351}
2352EXPORT_SYMBOL(drm_mode_connector_attach_encoder);
2353
2354void drm_mode_connector_detach_encoder(struct drm_connector *connector,
2355                                    struct drm_encoder *encoder)
2356{
2357        int i;
2358        for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
2359                if (connector->encoder_ids[i] == encoder->base.id) {
2360                        connector->encoder_ids[i] = 0;
2361                        if (connector->encoder == encoder)
2362                                connector->encoder = NULL;
2363                        break;
2364                }
2365        }
2366}
2367EXPORT_SYMBOL(drm_mode_connector_detach_encoder);
2368
2369bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
2370                                  int gamma_size)
2371{
2372        crtc->gamma_size = gamma_size;
2373
2374        crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL);
2375        if (!crtc->gamma_store) {
2376                crtc->gamma_size = 0;
2377                return false;
2378        }
2379
2380        return true;
2381}
2382EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);
2383
2384int drm_mode_gamma_set_ioctl(struct drm_device *dev,
2385                             void *data, struct drm_file *file_priv)
2386{
2387        struct drm_mode_crtc_lut *crtc_lut = data;
2388        struct drm_mode_object *obj;
2389        struct drm_crtc *crtc;
2390        void *r_base, *g_base, *b_base;
2391        int size;
2392        int ret = 0;
2393
2394        mutex_lock(&dev->mode_config.mutex);
2395        obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
2396        if (!obj) {
2397                ret = -EINVAL;
2398                goto out;
2399        }
2400        crtc = obj_to_crtc(obj);
2401
2402        /* memcpy into gamma store */
2403        if (crtc_lut->gamma_size != crtc->gamma_size) {
2404                ret = -EINVAL;
2405                goto out;
2406        }
2407
2408        size = crtc_lut->gamma_size * (sizeof(uint16_t));
2409        r_base = crtc->gamma_store;
2410        if (copy_from_user(r_base, (void __user *)(unsigned long)crtc_lut->red, size)) {
2411                ret = -EFAULT;
2412                goto out;
2413        }
2414
2415        g_base = r_base + size;
2416        if (copy_from_user(g_base, (void __user *)(unsigned long)crtc_lut->green, size)) {
2417                ret = -EFAULT;
2418                goto out;
2419        }
2420
2421        b_base = g_base + size;
2422        if (copy_from_user(b_base, (void __user *)(unsigned long)crtc_lut->blue, size)) {
2423                ret = -EFAULT;
2424                goto out;
2425        }
2426
2427        crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, crtc->gamma_size);
2428
2429out:
2430        mutex_unlock(&dev->mode_config.mutex);
2431        return ret;
2432
2433}
2434
2435int drm_mode_gamma_get_ioctl(struct drm_device *dev,
2436                             void *data, struct drm_file *file_priv)
2437{
2438        struct drm_mode_crtc_lut *crtc_lut = data;
2439        struct drm_mode_object *obj;
2440        struct drm_crtc *crtc;
2441        void *r_base, *g_base, *b_base;
2442        int size;
2443        int ret = 0;
2444
2445        mutex_lock(&dev->mode_config.mutex);
2446        obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
2447        if (!obj) {
2448                ret = -EINVAL;
2449                goto out;
2450        }
2451        crtc = obj_to_crtc(obj);
2452
2453        /* memcpy into gamma store */
2454        if (crtc_lut->gamma_size != crtc->gamma_size) {
2455                ret = -EINVAL;
2456                goto out;
2457        }
2458
2459        size = crtc_lut->gamma_size * (sizeof(uint16_t));
2460        r_base = crtc->gamma_store;
2461        if (copy_to_user((void __user *)(unsigned long)crtc_lut->red, r_base, size)) {
2462                ret = -EFAULT;
2463                goto out;
2464        }
2465
2466        g_base = r_base + size;
2467        if (copy_to_user((void __user *)(unsigned long)crtc_lut->green, g_base, size)) {
2468                ret = -EFAULT;
2469                goto out;
2470        }
2471
2472        b_base = g_base + size;
2473        if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) {
2474                ret = -EFAULT;
2475                goto out;
2476        }
2477out:
2478        mutex_unlock(&dev->mode_config.mutex);
2479        return ret;
2480}
2481