linux/drivers/gpu/drm/drm_crtc_helper.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2006-2008 Intel Corporation
   3 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
   4 *
   5 * DRM core CRTC related functions
   6 *
   7 * Permission to use, copy, modify, distribute, and sell this software and its
   8 * documentation for any purpose is hereby granted without fee, provided that
   9 * the above copyright notice appear in all copies and that both that copyright
  10 * notice and this permission notice appear in supporting documentation, and
  11 * that the name of the copyright holders not be used in advertising or
  12 * publicity pertaining to distribution of the software without specific,
  13 * written prior permission.  The copyright holders make no representations
  14 * about the suitability of this software for any purpose.  It is provided "as
  15 * is" without express or implied warranty.
  16 *
  17 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  19 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  23 * OF THIS SOFTWARE.
  24 *
  25 * Authors:
  26 *      Keith Packard
  27 *      Eric Anholt <eric@anholt.net>
  28 *      Dave Airlie <airlied@linux.ie>
  29 *      Jesse Barnes <jesse.barnes@intel.com>
  30 */
  31
  32#include "drmP.h"
  33#include "drm_crtc.h"
  34#include "drm_crtc_helper.h"
  35#include "drm_fb_helper.h"
  36
  37static bool drm_kms_helper_poll = true;
  38module_param_named(poll, drm_kms_helper_poll, bool, 0600);
  39
  40static void drm_mode_validate_flag(struct drm_connector *connector,
  41                                   int flags)
  42{
  43        struct drm_display_mode *mode, *t;
  44
  45        if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE))
  46                return;
  47
  48        list_for_each_entry_safe(mode, t, &connector->modes, head) {
  49                if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
  50                                !(flags & DRM_MODE_FLAG_INTERLACE))
  51                        mode->status = MODE_NO_INTERLACE;
  52                if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
  53                                !(flags & DRM_MODE_FLAG_DBLSCAN))
  54                        mode->status = MODE_NO_DBLESCAN;
  55        }
  56
  57        return;
  58}
  59
  60/**
  61 * drm_helper_probe_single_connector_modes - get complete set of display modes
  62 * @dev: DRM device
  63 * @maxX: max width for modes
  64 * @maxY: max height for modes
  65 *
  66 * LOCKING:
  67 * Caller must hold mode config lock.
  68 *
  69 * Based on @dev's mode_config layout, scan all the connectors and try to detect
  70 * modes on them.  Modes will first be added to the connector's probed_modes
  71 * list, then culled (based on validity and the @maxX, @maxY parameters) and
  72 * put into the normal modes list.
  73 *
  74 * Intended to be used either at bootup time or when major configuration
  75 * changes have occurred.
  76 *
  77 * FIXME: take into account monitor limits
  78 *
  79 * RETURNS:
  80 * Number of modes found on @connector.
  81 */
  82int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
  83                                            uint32_t maxX, uint32_t maxY)
  84{
  85        struct drm_device *dev = connector->dev;
  86        struct drm_display_mode *mode, *t;
  87        struct drm_connector_helper_funcs *connector_funcs =
  88                connector->helper_private;
  89        int count = 0;
  90        int mode_flags = 0;
  91
  92        DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
  93                        drm_get_connector_name(connector));
  94        /* set all modes to the unverified state */
  95        list_for_each_entry_safe(mode, t, &connector->modes, head)
  96                mode->status = MODE_UNVERIFIED;
  97
  98        if (connector->force) {
  99                if (connector->force == DRM_FORCE_ON)
 100                        connector->status = connector_status_connected;
 101                else
 102                        connector->status = connector_status_disconnected;
 103                if (connector->funcs->force)
 104                        connector->funcs->force(connector);
 105        } else {
 106                connector->status = connector->funcs->detect(connector, true);
 107                drm_kms_helper_poll_enable(dev);
 108        }
 109
 110        if (connector->status == connector_status_disconnected) {
 111                DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
 112                        connector->base.id, drm_get_connector_name(connector));
 113                drm_mode_connector_update_edid_property(connector, NULL);
 114                goto prune;
 115        }
 116
 117        count = (*connector_funcs->get_modes)(connector);
 118        if (count == 0 && connector->status == connector_status_connected)
 119                count = drm_add_modes_noedid(connector, 1024, 768);
 120        if (count == 0)
 121                goto prune;
 122
 123        drm_mode_connector_list_update(connector);
 124
 125        if (maxX && maxY)
 126                drm_mode_validate_size(dev, &connector->modes, maxX,
 127                                       maxY, 0);
 128
 129        if (connector->interlace_allowed)
 130                mode_flags |= DRM_MODE_FLAG_INTERLACE;
 131        if (connector->doublescan_allowed)
 132                mode_flags |= DRM_MODE_FLAG_DBLSCAN;
 133        drm_mode_validate_flag(connector, mode_flags);
 134
 135        list_for_each_entry_safe(mode, t, &connector->modes, head) {
 136                if (mode->status == MODE_OK)
 137                        mode->status = connector_funcs->mode_valid(connector,
 138                                                                   mode);
 139        }
 140
 141prune:
 142        drm_mode_prune_invalid(dev, &connector->modes, true);
 143
 144        if (list_empty(&connector->modes))
 145                return 0;
 146
 147        drm_mode_sort(&connector->modes);
 148
 149        DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
 150                        drm_get_connector_name(connector));
 151        list_for_each_entry_safe(mode, t, &connector->modes, head) {
 152                mode->vrefresh = drm_mode_vrefresh(mode);
 153
 154                drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
 155                drm_mode_debug_printmodeline(mode);
 156        }
 157
 158        return count;
 159}
 160EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
 161
 162/**
 163 * drm_helper_encoder_in_use - check if a given encoder is in use
 164 * @encoder: encoder to check
 165 *
 166 * LOCKING:
 167 * Caller must hold mode config lock.
 168 *
 169 * Walk @encoders's DRM device's mode_config and see if it's in use.
 170 *
 171 * RETURNS:
 172 * True if @encoder is part of the mode_config, false otherwise.
 173 */
 174bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
 175{
 176        struct drm_connector *connector;
 177        struct drm_device *dev = encoder->dev;
 178        list_for_each_entry(connector, &dev->mode_config.connector_list, head)
 179                if (connector->encoder == encoder)
 180                        return true;
 181        return false;
 182}
 183EXPORT_SYMBOL(drm_helper_encoder_in_use);
 184
 185/**
 186 * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config
 187 * @crtc: CRTC to check
 188 *
 189 * LOCKING:
 190 * Caller must hold mode config lock.
 191 *
 192 * Walk @crtc's DRM device's mode_config and see if it's in use.
 193 *
 194 * RETURNS:
 195 * True if @crtc is part of the mode_config, false otherwise.
 196 */
 197bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
 198{
 199        struct drm_encoder *encoder;
 200        struct drm_device *dev = crtc->dev;
 201        /* FIXME: Locking around list access? */
 202        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
 203                if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder))
 204                        return true;
 205        return false;
 206}
 207EXPORT_SYMBOL(drm_helper_crtc_in_use);
 208
 209static void
 210drm_encoder_disable(struct drm_encoder *encoder)
 211{
 212        struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
 213
 214        if (encoder_funcs->disable)
 215                (*encoder_funcs->disable)(encoder);
 216        else
 217                (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
 218}
 219
 220/**
 221 * drm_helper_disable_unused_functions - disable unused objects
 222 * @dev: DRM device
 223 *
 224 * LOCKING:
 225 * Caller must hold mode config lock.
 226 *
 227 * If an connector or CRTC isn't part of @dev's mode_config, it can be disabled
 228 * by calling its dpms function, which should power it off.
 229 */
 230void drm_helper_disable_unused_functions(struct drm_device *dev)
 231{
 232        struct drm_encoder *encoder;
 233        struct drm_connector *connector;
 234        struct drm_crtc *crtc;
 235
 236        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 237                if (!connector->encoder)
 238                        continue;
 239                if (connector->status == connector_status_disconnected)
 240                        connector->encoder = NULL;
 241        }
 242
 243        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 244                if (!drm_helper_encoder_in_use(encoder)) {
 245                        drm_encoder_disable(encoder);
 246                        /* disconnector encoder from any connector */
 247                        encoder->crtc = NULL;
 248                }
 249        }
 250
 251        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 252                struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 253                crtc->enabled = drm_helper_crtc_in_use(crtc);
 254                if (!crtc->enabled) {
 255                        if (crtc_funcs->disable)
 256                                (*crtc_funcs->disable)(crtc);
 257                        else
 258                                (*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
 259                        crtc->fb = NULL;
 260                }
 261        }
 262}
 263EXPORT_SYMBOL(drm_helper_disable_unused_functions);
 264
 265/**
 266 * drm_encoder_crtc_ok - can a given crtc drive a given encoder?
 267 * @encoder: encoder to test
 268 * @crtc: crtc to test
 269 *
 270 * Return false if @encoder can't be driven by @crtc, true otherwise.
 271 */
 272static bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
 273                                struct drm_crtc *crtc)
 274{
 275        struct drm_device *dev;
 276        struct drm_crtc *tmp;
 277        int crtc_mask = 1;
 278
 279        WARN(!crtc, "checking null crtc?\n");
 280
 281        dev = crtc->dev;
 282
 283        list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) {
 284                if (tmp == crtc)
 285                        break;
 286                crtc_mask <<= 1;
 287        }
 288
 289        if (encoder->possible_crtcs & crtc_mask)
 290                return true;
 291        return false;
 292}
 293
 294/*
 295 * Check the CRTC we're going to map each output to vs. its current
 296 * CRTC.  If they don't match, we have to disable the output and the CRTC
 297 * since the driver will have to re-route things.
 298 */
 299static void
 300drm_crtc_prepare_encoders(struct drm_device *dev)
 301{
 302        struct drm_encoder_helper_funcs *encoder_funcs;
 303        struct drm_encoder *encoder;
 304
 305        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 306                encoder_funcs = encoder->helper_private;
 307                /* Disable unused encoders */
 308                if (encoder->crtc == NULL)
 309                        drm_encoder_disable(encoder);
 310                /* Disable encoders whose CRTC is about to change */
 311                if (encoder_funcs->get_crtc &&
 312                    encoder->crtc != (*encoder_funcs->get_crtc)(encoder))
 313                        drm_encoder_disable(encoder);
 314        }
 315}
 316
 317/**
 318 * drm_crtc_set_mode - set a mode
 319 * @crtc: CRTC to program
 320 * @mode: mode to use
 321 * @x: width of mode
 322 * @y: height of mode
 323 *
 324 * LOCKING:
 325 * Caller must hold mode config lock.
 326 *
 327 * Try to set @mode on @crtc.  Give @crtc and its associated connectors a chance
 328 * to fixup or reject the mode prior to trying to set it.
 329 *
 330 * RETURNS:
 331 * True if the mode was set successfully, or false otherwise.
 332 */
 333bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
 334                              struct drm_display_mode *mode,
 335                              int x, int y,
 336                              struct drm_framebuffer *old_fb)
 337{
 338        struct drm_device *dev = crtc->dev;
 339        struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
 340        struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 341        struct drm_encoder_helper_funcs *encoder_funcs;
 342        int saved_x, saved_y;
 343        struct drm_encoder *encoder;
 344        bool ret = true;
 345
 346        crtc->enabled = drm_helper_crtc_in_use(crtc);
 347        if (!crtc->enabled)
 348                return true;
 349
 350        adjusted_mode = drm_mode_duplicate(dev, mode);
 351
 352        saved_hwmode = crtc->hwmode;
 353        saved_mode = crtc->mode;
 354        saved_x = crtc->x;
 355        saved_y = crtc->y;
 356
 357        /* Update crtc values up front so the driver can rely on them for mode
 358         * setting.
 359         */
 360        crtc->mode = *mode;
 361        crtc->x = x;
 362        crtc->y = y;
 363
 364        /* Pass our mode to the connectors and the CRTC to give them a chance to
 365         * adjust it according to limitations or connector properties, and also
 366         * a chance to reject the mode entirely.
 367         */
 368        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 369
 370                if (encoder->crtc != crtc)
 371                        continue;
 372                encoder_funcs = encoder->helper_private;
 373                if (!(ret = encoder_funcs->mode_fixup(encoder, mode,
 374                                                      adjusted_mode))) {
 375                        goto done;
 376                }
 377        }
 378
 379        if (!(ret = crtc_funcs->mode_fixup(crtc, mode, adjusted_mode))) {
 380                goto done;
 381        }
 382        DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
 383
 384        /* Prepare the encoders and CRTCs before setting the mode. */
 385        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 386
 387                if (encoder->crtc != crtc)
 388                        continue;
 389                encoder_funcs = encoder->helper_private;
 390                /* Disable the encoders as the first thing we do. */
 391                encoder_funcs->prepare(encoder);
 392        }
 393
 394        drm_crtc_prepare_encoders(dev);
 395
 396        crtc_funcs->prepare(crtc);
 397
 398        /* Set up the DPLL and any encoders state that needs to adjust or depend
 399         * on the DPLL.
 400         */
 401        ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
 402        if (!ret)
 403            goto done;
 404
 405        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 406
 407                if (encoder->crtc != crtc)
 408                        continue;
 409
 410                DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n",
 411                        encoder->base.id, drm_get_encoder_name(encoder),
 412                        mode->base.id, mode->name);
 413                encoder_funcs = encoder->helper_private;
 414                encoder_funcs->mode_set(encoder, mode, adjusted_mode);
 415        }
 416
 417        /* Now enable the clocks, plane, pipe, and connectors that we set up. */
 418        crtc_funcs->commit(crtc);
 419
 420        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 421
 422                if (encoder->crtc != crtc)
 423                        continue;
 424
 425                encoder_funcs = encoder->helper_private;
 426                encoder_funcs->commit(encoder);
 427
 428        }
 429
 430        /* Store real post-adjustment hardware mode. */
 431        crtc->hwmode = *adjusted_mode;
 432
 433        /* Calculate and store various constants which
 434         * are later needed by vblank and swap-completion
 435         * timestamping. They are derived from true hwmode.
 436         */
 437        drm_calc_timestamping_constants(crtc);
 438
 439        /* FIXME: add subpixel order */
 440done:
 441        drm_mode_destroy(dev, adjusted_mode);
 442        if (!ret) {
 443                crtc->hwmode = saved_hwmode;
 444                crtc->mode = saved_mode;
 445                crtc->x = saved_x;
 446                crtc->y = saved_y;
 447        }
 448
 449        return ret;
 450}
 451EXPORT_SYMBOL(drm_crtc_helper_set_mode);
 452
 453
 454/**
 455 * drm_crtc_helper_set_config - set a new config from userspace
 456 * @crtc: CRTC to setup
 457 * @crtc_info: user provided configuration
 458 * @new_mode: new mode to set
 459 * @connector_set: set of connectors for the new config
 460 * @fb: new framebuffer
 461 *
 462 * LOCKING:
 463 * Caller must hold mode config lock.
 464 *
 465 * Setup a new configuration, provided by the user in @crtc_info, and enable
 466 * it.
 467 *
 468 * RETURNS:
 469 * Zero. (FIXME)
 470 */
 471int drm_crtc_helper_set_config(struct drm_mode_set *set)
 472{
 473        struct drm_device *dev;
 474        struct drm_crtc *save_crtcs, *new_crtc, *crtc;
 475        struct drm_encoder *save_encoders, *new_encoder, *encoder;
 476        struct drm_framebuffer *old_fb = NULL;
 477        bool mode_changed = false; /* if true do a full mode set */
 478        bool fb_changed = false; /* if true and !mode_changed just do a flip */
 479        struct drm_connector *save_connectors, *connector;
 480        int count = 0, ro, fail = 0;
 481        struct drm_crtc_helper_funcs *crtc_funcs;
 482        int ret = 0;
 483        int i;
 484
 485        DRM_DEBUG_KMS("\n");
 486
 487        if (!set)
 488                return -EINVAL;
 489
 490        if (!set->crtc)
 491                return -EINVAL;
 492
 493        if (!set->crtc->helper_private)
 494                return -EINVAL;
 495
 496        crtc_funcs = set->crtc->helper_private;
 497
 498        if (!set->mode)
 499                set->fb = NULL;
 500
 501        if (set->fb) {
 502                DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n",
 503                                set->crtc->base.id, set->fb->base.id,
 504                                (int)set->num_connectors, set->x, set->y);
 505        } else {
 506                DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id);
 507                set->mode = NULL;
 508                set->num_connectors = 0;
 509        }
 510
 511        dev = set->crtc->dev;
 512
 513        /* Allocate space for the backup of all (non-pointer) crtc, encoder and
 514         * connector data. */
 515        save_crtcs = kzalloc(dev->mode_config.num_crtc *
 516                             sizeof(struct drm_crtc), GFP_KERNEL);
 517        if (!save_crtcs)
 518                return -ENOMEM;
 519
 520        save_encoders = kzalloc(dev->mode_config.num_encoder *
 521                                sizeof(struct drm_encoder), GFP_KERNEL);
 522        if (!save_encoders) {
 523                kfree(save_crtcs);
 524                return -ENOMEM;
 525        }
 526
 527        save_connectors = kzalloc(dev->mode_config.num_connector *
 528                                sizeof(struct drm_connector), GFP_KERNEL);
 529        if (!save_connectors) {
 530                kfree(save_crtcs);
 531                kfree(save_encoders);
 532                return -ENOMEM;
 533        }
 534
 535        /* Copy data. Note that driver private data is not affected.
 536         * Should anything bad happen only the expected state is
 537         * restored, not the drivers personal bookkeeping.
 538         */
 539        count = 0;
 540        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 541                save_crtcs[count++] = *crtc;
 542        }
 543
 544        count = 0;
 545        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 546                save_encoders[count++] = *encoder;
 547        }
 548
 549        count = 0;
 550        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 551                save_connectors[count++] = *connector;
 552        }
 553
 554        /* We should be able to check here if the fb has the same properties
 555         * and then just flip_or_move it */
 556        if (set->crtc->fb != set->fb) {
 557                /* If we have no fb then treat it as a full mode set */
 558                if (set->crtc->fb == NULL) {
 559                        DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
 560                        mode_changed = true;
 561                } else if (set->fb == NULL) {
 562                        mode_changed = true;
 563                } else
 564                        fb_changed = true;
 565        }
 566
 567        if (set->x != set->crtc->x || set->y != set->crtc->y)
 568                fb_changed = true;
 569
 570        if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) {
 571                DRM_DEBUG_KMS("modes are different, full mode set\n");
 572                drm_mode_debug_printmodeline(&set->crtc->mode);
 573                drm_mode_debug_printmodeline(set->mode);
 574                mode_changed = true;
 575        }
 576
 577        /* a) traverse passed in connector list and get encoders for them */
 578        count = 0;
 579        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 580                struct drm_connector_helper_funcs *connector_funcs =
 581                        connector->helper_private;
 582                new_encoder = connector->encoder;
 583                for (ro = 0; ro < set->num_connectors; ro++) {
 584                        if (set->connectors[ro] == connector) {
 585                                new_encoder = connector_funcs->best_encoder(connector);
 586                                /* if we can't get an encoder for a connector
 587                                   we are setting now - then fail */
 588                                if (new_encoder == NULL)
 589                                        /* don't break so fail path works correct */
 590                                        fail = 1;
 591                                break;
 592                        }
 593                }
 594
 595                if (new_encoder != connector->encoder) {
 596                        DRM_DEBUG_KMS("encoder changed, full mode switch\n");
 597                        mode_changed = true;
 598                        /* If the encoder is reused for another connector, then
 599                         * the appropriate crtc will be set later.
 600                         */
 601                        if (connector->encoder)
 602                                connector->encoder->crtc = NULL;
 603                        connector->encoder = new_encoder;
 604                }
 605        }
 606
 607        if (fail) {
 608                ret = -EINVAL;
 609                goto fail;
 610        }
 611
 612        count = 0;
 613        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 614                if (!connector->encoder)
 615                        continue;
 616
 617                if (connector->encoder->crtc == set->crtc)
 618                        new_crtc = NULL;
 619                else
 620                        new_crtc = connector->encoder->crtc;
 621
 622                for (ro = 0; ro < set->num_connectors; ro++) {
 623                        if (set->connectors[ro] == connector)
 624                                new_crtc = set->crtc;
 625                }
 626
 627                /* Make sure the new CRTC will work with the encoder */
 628                if (new_crtc &&
 629                    !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
 630                        ret = -EINVAL;
 631                        goto fail;
 632                }
 633                if (new_crtc != connector->encoder->crtc) {
 634                        DRM_DEBUG_KMS("crtc changed, full mode switch\n");
 635                        mode_changed = true;
 636                        connector->encoder->crtc = new_crtc;
 637                }
 638                if (new_crtc) {
 639                        DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n",
 640                                connector->base.id, drm_get_connector_name(connector),
 641                                new_crtc->base.id);
 642                } else {
 643                        DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
 644                                connector->base.id, drm_get_connector_name(connector));
 645                }
 646        }
 647
 648        /* mode_set_base is not a required function */
 649        if (fb_changed && !crtc_funcs->mode_set_base)
 650                mode_changed = true;
 651
 652        if (mode_changed) {
 653                set->crtc->enabled = drm_helper_crtc_in_use(set->crtc);
 654                if (set->crtc->enabled) {
 655                        DRM_DEBUG_KMS("attempting to set mode from"
 656                                        " userspace\n");
 657                        drm_mode_debug_printmodeline(set->mode);
 658                        old_fb = set->crtc->fb;
 659                        set->crtc->fb = set->fb;
 660                        if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
 661                                                      set->x, set->y,
 662                                                      old_fb)) {
 663                                DRM_ERROR("failed to set mode on [CRTC:%d]\n",
 664                                          set->crtc->base.id);
 665                                set->crtc->fb = old_fb;
 666                                ret = -EINVAL;
 667                                goto fail;
 668                        }
 669                        DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
 670                        for (i = 0; i < set->num_connectors; i++) {
 671                                DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id,
 672                                              drm_get_connector_name(set->connectors[i]));
 673                                set->connectors[i]->dpms = DRM_MODE_DPMS_ON;
 674                        }
 675                }
 676                drm_helper_disable_unused_functions(dev);
 677        } else if (fb_changed) {
 678                set->crtc->x = set->x;
 679                set->crtc->y = set->y;
 680
 681                old_fb = set->crtc->fb;
 682                if (set->crtc->fb != set->fb)
 683                        set->crtc->fb = set->fb;
 684                ret = crtc_funcs->mode_set_base(set->crtc,
 685                                                set->x, set->y, old_fb);
 686                if (ret != 0) {
 687                        set->crtc->fb = old_fb;
 688                        goto fail;
 689                }
 690        }
 691
 692        kfree(save_connectors);
 693        kfree(save_encoders);
 694        kfree(save_crtcs);
 695        return 0;
 696
 697fail:
 698        /* Restore all previous data. */
 699        count = 0;
 700        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 701                *crtc = save_crtcs[count++];
 702        }
 703
 704        count = 0;
 705        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 706                *encoder = save_encoders[count++];
 707        }
 708
 709        count = 0;
 710        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 711                *connector = save_connectors[count++];
 712        }
 713
 714        kfree(save_connectors);
 715        kfree(save_encoders);
 716        kfree(save_crtcs);
 717        return ret;
 718}
 719EXPORT_SYMBOL(drm_crtc_helper_set_config);
 720
 721static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
 722{
 723        int dpms = DRM_MODE_DPMS_OFF;
 724        struct drm_connector *connector;
 725        struct drm_device *dev = encoder->dev;
 726
 727        list_for_each_entry(connector, &dev->mode_config.connector_list, head)
 728                if (connector->encoder == encoder)
 729                        if (connector->dpms < dpms)
 730                                dpms = connector->dpms;
 731        return dpms;
 732}
 733
 734static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
 735{
 736        int dpms = DRM_MODE_DPMS_OFF;
 737        struct drm_connector *connector;
 738        struct drm_device *dev = crtc->dev;
 739
 740        list_for_each_entry(connector, &dev->mode_config.connector_list, head)
 741                if (connector->encoder && connector->encoder->crtc == crtc)
 742                        if (connector->dpms < dpms)
 743                                dpms = connector->dpms;
 744        return dpms;
 745}
 746
 747/**
 748 * drm_helper_connector_dpms
 749 * @connector affected connector
 750 * @mode DPMS mode
 751 *
 752 * Calls the low-level connector DPMS function, then
 753 * calls appropriate encoder and crtc DPMS functions as well
 754 */
 755void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
 756{
 757        struct drm_encoder *encoder = connector->encoder;
 758        struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
 759        int old_dpms;
 760
 761        if (mode == connector->dpms)
 762                return;
 763
 764        old_dpms = connector->dpms;
 765        connector->dpms = mode;
 766
 767        /* from off to on, do crtc then encoder */
 768        if (mode < old_dpms) {
 769                if (crtc) {
 770                        struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 771                        if (crtc_funcs->dpms)
 772                                (*crtc_funcs->dpms) (crtc,
 773                                                     drm_helper_choose_crtc_dpms(crtc));
 774                }
 775                if (encoder) {
 776                        struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
 777                        if (encoder_funcs->dpms)
 778                                (*encoder_funcs->dpms) (encoder,
 779                                                        drm_helper_choose_encoder_dpms(encoder));
 780                }
 781        }
 782
 783        /* from on to off, do encoder then crtc */
 784        if (mode > old_dpms) {
 785                if (encoder) {
 786                        struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
 787                        if (encoder_funcs->dpms)
 788                                (*encoder_funcs->dpms) (encoder,
 789                                                        drm_helper_choose_encoder_dpms(encoder));
 790                }
 791                if (crtc) {
 792                        struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 793                        if (crtc_funcs->dpms)
 794                                (*crtc_funcs->dpms) (crtc,
 795                                                     drm_helper_choose_crtc_dpms(crtc));
 796                }
 797        }
 798
 799        return;
 800}
 801EXPORT_SYMBOL(drm_helper_connector_dpms);
 802
 803int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
 804                                   struct drm_mode_fb_cmd *mode_cmd)
 805{
 806        fb->width = mode_cmd->width;
 807        fb->height = mode_cmd->height;
 808        fb->pitch = mode_cmd->pitch;
 809        fb->bits_per_pixel = mode_cmd->bpp;
 810        fb->depth = mode_cmd->depth;
 811
 812        return 0;
 813}
 814EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct);
 815
 816int drm_helper_resume_force_mode(struct drm_device *dev)
 817{
 818        struct drm_crtc *crtc;
 819        struct drm_encoder *encoder;
 820        struct drm_encoder_helper_funcs *encoder_funcs;
 821        struct drm_crtc_helper_funcs *crtc_funcs;
 822        int ret;
 823
 824        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 825
 826                if (!crtc->enabled)
 827                        continue;
 828
 829                ret = drm_crtc_helper_set_mode(crtc, &crtc->mode,
 830                                               crtc->x, crtc->y, crtc->fb);
 831
 832                if (ret == false)
 833                        DRM_ERROR("failed to set mode on crtc %p\n", crtc);
 834
 835                /* Turn off outputs that were already powered off */
 836                if (drm_helper_choose_crtc_dpms(crtc)) {
 837                        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 838
 839                                if(encoder->crtc != crtc)
 840                                        continue;
 841
 842                                encoder_funcs = encoder->helper_private;
 843                                if (encoder_funcs->dpms)
 844                                        (*encoder_funcs->dpms) (encoder,
 845                                                                drm_helper_choose_encoder_dpms(encoder));
 846                        }
 847
 848                        crtc_funcs = crtc->helper_private;
 849                        if (crtc_funcs->dpms)
 850                                (*crtc_funcs->dpms) (crtc,
 851                                                     drm_helper_choose_crtc_dpms(crtc));
 852                }
 853        }
 854        /* disable the unused connectors while restoring the modesetting */
 855        drm_helper_disable_unused_functions(dev);
 856        return 0;
 857}
 858EXPORT_SYMBOL(drm_helper_resume_force_mode);
 859
 860#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
 861static void output_poll_execute(struct work_struct *work)
 862{
 863        struct delayed_work *delayed_work = to_delayed_work(work);
 864        struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
 865        struct drm_connector *connector;
 866        enum drm_connector_status old_status;
 867        bool repoll = false, changed = false;
 868
 869        if (!drm_kms_helper_poll)
 870                return;
 871
 872        mutex_lock(&dev->mode_config.mutex);
 873        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 874
 875                /* if this is HPD or polled don't check it -
 876                   TV out for instance */
 877                if (!connector->polled)
 878                        continue;
 879
 880                else if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT))
 881                        repoll = true;
 882
 883                old_status = connector->status;
 884                /* if we are connected and don't want to poll for disconnect
 885                   skip it */
 886                if (old_status == connector_status_connected &&
 887                    !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT) &&
 888                    !(connector->polled & DRM_CONNECTOR_POLL_HPD))
 889                        continue;
 890
 891                connector->status = connector->funcs->detect(connector, false);
 892                DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
 893                              connector->base.id,
 894                              drm_get_connector_name(connector),
 895                              old_status, connector->status);
 896                if (old_status != connector->status)
 897                        changed = true;
 898        }
 899
 900        mutex_unlock(&dev->mode_config.mutex);
 901
 902        if (changed) {
 903                /* send a uevent + call fbdev */
 904                drm_sysfs_hotplug_event(dev);
 905                if (dev->mode_config.funcs->output_poll_changed)
 906                        dev->mode_config.funcs->output_poll_changed(dev);
 907        }
 908
 909        if (repoll)
 910                queue_delayed_work(system_nrt_wq, delayed_work, DRM_OUTPUT_POLL_PERIOD);
 911}
 912
 913void drm_kms_helper_poll_disable(struct drm_device *dev)
 914{
 915        if (!dev->mode_config.poll_enabled)
 916                return;
 917        cancel_delayed_work_sync(&dev->mode_config.output_poll_work);
 918}
 919EXPORT_SYMBOL(drm_kms_helper_poll_disable);
 920
 921void drm_kms_helper_poll_enable(struct drm_device *dev)
 922{
 923        bool poll = false;
 924        struct drm_connector *connector;
 925
 926        if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
 927                return;
 928
 929        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 930                if (connector->polled)
 931                        poll = true;
 932        }
 933
 934        if (poll)
 935                queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD);
 936}
 937EXPORT_SYMBOL(drm_kms_helper_poll_enable);
 938
 939void drm_kms_helper_poll_init(struct drm_device *dev)
 940{
 941        INIT_DELAYED_WORK(&dev->mode_config.output_poll_work, output_poll_execute);
 942        dev->mode_config.poll_enabled = true;
 943
 944        drm_kms_helper_poll_enable(dev);
 945}
 946EXPORT_SYMBOL(drm_kms_helper_poll_init);
 947
 948void drm_kms_helper_poll_fini(struct drm_device *dev)
 949{
 950        drm_kms_helper_poll_disable(dev);
 951}
 952EXPORT_SYMBOL(drm_kms_helper_poll_fini);
 953
 954void drm_helper_hpd_irq_event(struct drm_device *dev)
 955{
 956        if (!dev->mode_config.poll_enabled)
 957                return;
 958
 959        /* kill timer and schedule immediate execution, this doesn't block */
 960        cancel_delayed_work(&dev->mode_config.output_poll_work);
 961        if (drm_kms_helper_poll)
 962                queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0);
 963}
 964EXPORT_SYMBOL(drm_helper_hpd_irq_event);
 965