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