cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

drm_crtc_helper.c (31182B)


      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 <linux/export.h>
     33#include <linux/kernel.h>
     34#include <linux/moduleparam.h>
     35
     36#include <drm/drm_atomic.h>
     37#include <drm/drm_atomic_helper.h>
     38#include <drm/drm_atomic_uapi.h>
     39#include <drm/drm_bridge.h>
     40#include <drm/drm_crtc.h>
     41#include <drm/drm_crtc_helper.h>
     42#include <drm/drm_drv.h>
     43#include <drm/drm_edid.h>
     44#include <drm/drm_encoder.h>
     45#include <drm/drm_fb_helper.h>
     46#include <drm/drm_fourcc.h>
     47#include <drm/drm_plane_helper.h>
     48#include <drm/drm_print.h>
     49#include <drm/drm_vblank.h>
     50
     51#include "drm_crtc_helper_internal.h"
     52
     53/**
     54 * DOC: overview
     55 *
     56 * The CRTC modeset helper library provides a default set_config implementation
     57 * in drm_crtc_helper_set_config(). Plus a few other convenience functions using
     58 * the same callbacks which drivers can use to e.g. restore the modeset
     59 * configuration on resume with drm_helper_resume_force_mode().
     60 *
     61 * Note that this helper library doesn't track the current power state of CRTCs
     62 * and encoders. It can call callbacks like &drm_encoder_helper_funcs.dpms even
     63 * though the hardware is already in the desired state. This deficiency has been
     64 * fixed in the atomic helpers.
     65 *
     66 * The driver callbacks are mostly compatible with the atomic modeset helpers,
     67 * except for the handling of the primary plane: Atomic helpers require that the
     68 * primary plane is implemented as a real standalone plane and not directly tied
     69 * to the CRTC state. For easier transition this library provides functions to
     70 * implement the old semantics required by the CRTC helpers using the new plane
     71 * and atomic helper callbacks.
     72 *
     73 * Drivers are strongly urged to convert to the atomic helpers (by way of first
     74 * converting to the plane helpers). New drivers must not use these functions
     75 * but need to implement the atomic interface instead, potentially using the
     76 * atomic helpers for that.
     77 *
     78 * These legacy modeset helpers use the same function table structures as
     79 * all other modesetting helpers. See the documentation for struct
     80 * &drm_crtc_helper_funcs, &struct drm_encoder_helper_funcs and struct
     81 * &drm_connector_helper_funcs.
     82 */
     83
     84/**
     85 * drm_helper_encoder_in_use - check if a given encoder is in use
     86 * @encoder: encoder to check
     87 *
     88 * Checks whether @encoder is with the current mode setting output configuration
     89 * in use by any connector. This doesn't mean that it is actually enabled since
     90 * the DPMS state is tracked separately.
     91 *
     92 * Returns:
     93 * True if @encoder is used, false otherwise.
     94 */
     95bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
     96{
     97	struct drm_connector *connector;
     98	struct drm_connector_list_iter conn_iter;
     99	struct drm_device *dev = encoder->dev;
    100
    101	WARN_ON(drm_drv_uses_atomic_modeset(dev));
    102
    103	/*
    104	 * We can expect this mutex to be locked if we are not panicking.
    105	 * Locking is currently fubar in the panic handler.
    106	 */
    107	if (!oops_in_progress) {
    108		WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
    109		WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
    110	}
    111
    112
    113	drm_connector_list_iter_begin(dev, &conn_iter);
    114	drm_for_each_connector_iter(connector, &conn_iter) {
    115		if (connector->encoder == encoder) {
    116			drm_connector_list_iter_end(&conn_iter);
    117			return true;
    118		}
    119	}
    120	drm_connector_list_iter_end(&conn_iter);
    121	return false;
    122}
    123EXPORT_SYMBOL(drm_helper_encoder_in_use);
    124
    125/**
    126 * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config
    127 * @crtc: CRTC to check
    128 *
    129 * Checks whether @crtc is with the current mode setting output configuration
    130 * in use by any connector. This doesn't mean that it is actually enabled since
    131 * the DPMS state is tracked separately.
    132 *
    133 * Returns:
    134 * True if @crtc is used, false otherwise.
    135 */
    136bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
    137{
    138	struct drm_encoder *encoder;
    139	struct drm_device *dev = crtc->dev;
    140
    141	WARN_ON(drm_drv_uses_atomic_modeset(dev));
    142
    143	/*
    144	 * We can expect this mutex to be locked if we are not panicking.
    145	 * Locking is currently fubar in the panic handler.
    146	 */
    147	if (!oops_in_progress)
    148		WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
    149
    150	drm_for_each_encoder(encoder, dev)
    151		if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder))
    152			return true;
    153	return false;
    154}
    155EXPORT_SYMBOL(drm_helper_crtc_in_use);
    156
    157static void
    158drm_encoder_disable(struct drm_encoder *encoder)
    159{
    160	const struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
    161
    162	if (!encoder_funcs)
    163		return;
    164
    165	if (encoder_funcs->disable)
    166		(*encoder_funcs->disable)(encoder);
    167	else if (encoder_funcs->dpms)
    168		(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
    169}
    170
    171static void __drm_helper_disable_unused_functions(struct drm_device *dev)
    172{
    173	struct drm_encoder *encoder;
    174	struct drm_crtc *crtc;
    175
    176	drm_warn_on_modeset_not_all_locked(dev);
    177
    178	drm_for_each_encoder(encoder, dev) {
    179		if (!drm_helper_encoder_in_use(encoder)) {
    180			drm_encoder_disable(encoder);
    181			/* disconnect encoder from any connector */
    182			encoder->crtc = NULL;
    183		}
    184	}
    185
    186	drm_for_each_crtc(crtc, dev) {
    187		const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
    188
    189		crtc->enabled = drm_helper_crtc_in_use(crtc);
    190		if (!crtc->enabled) {
    191			if (crtc_funcs->disable)
    192				(*crtc_funcs->disable)(crtc);
    193			else
    194				(*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
    195			crtc->primary->fb = NULL;
    196		}
    197	}
    198}
    199
    200/**
    201 * drm_helper_disable_unused_functions - disable unused objects
    202 * @dev: DRM device
    203 *
    204 * This function walks through the entire mode setting configuration of @dev. It
    205 * will remove any CRTC links of unused encoders and encoder links of
    206 * disconnected connectors. Then it will disable all unused encoders and CRTCs
    207 * either by calling their disable callback if available or by calling their
    208 * dpms callback with DRM_MODE_DPMS_OFF.
    209 *
    210 * NOTE:
    211 *
    212 * This function is part of the legacy modeset helper library and will cause
    213 * major confusion with atomic drivers. This is because atomic helpers guarantee
    214 * to never call ->disable() hooks on a disabled function, or ->enable() hooks
    215 * on an enabled functions. drm_helper_disable_unused_functions() on the other
    216 * hand throws such guarantees into the wind and calls disable hooks
    217 * unconditionally on unused functions.
    218 */
    219void drm_helper_disable_unused_functions(struct drm_device *dev)
    220{
    221	WARN_ON(drm_drv_uses_atomic_modeset(dev));
    222
    223	drm_modeset_lock_all(dev);
    224	__drm_helper_disable_unused_functions(dev);
    225	drm_modeset_unlock_all(dev);
    226}
    227EXPORT_SYMBOL(drm_helper_disable_unused_functions);
    228
    229/*
    230 * Check the CRTC we're going to map each output to vs. its current
    231 * CRTC.  If they don't match, we have to disable the output and the CRTC
    232 * since the driver will have to re-route things.
    233 */
    234static void
    235drm_crtc_prepare_encoders(struct drm_device *dev)
    236{
    237	const struct drm_encoder_helper_funcs *encoder_funcs;
    238	struct drm_encoder *encoder;
    239
    240	drm_for_each_encoder(encoder, dev) {
    241		encoder_funcs = encoder->helper_private;
    242		if (!encoder_funcs)
    243			continue;
    244
    245		/* Disable unused encoders */
    246		if (encoder->crtc == NULL)
    247			drm_encoder_disable(encoder);
    248	}
    249}
    250
    251/**
    252 * drm_crtc_helper_set_mode - internal helper to set a mode
    253 * @crtc: CRTC to program
    254 * @mode: mode to use
    255 * @x: horizontal offset into the surface
    256 * @y: vertical offset into the surface
    257 * @old_fb: old framebuffer, for cleanup
    258 *
    259 * Try to set @mode on @crtc.  Give @crtc and its associated connectors a chance
    260 * to fixup or reject the mode prior to trying to set it. This is an internal
    261 * helper that drivers could e.g. use to update properties that require the
    262 * entire output pipe to be disabled and re-enabled in a new configuration. For
    263 * example for changing whether audio is enabled on a hdmi link or for changing
    264 * panel fitter or dither attributes. It is also called by the
    265 * drm_crtc_helper_set_config() helper function to drive the mode setting
    266 * sequence.
    267 *
    268 * Returns:
    269 * True if the mode was set successfully, false otherwise.
    270 */
    271bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
    272			      struct drm_display_mode *mode,
    273			      int x, int y,
    274			      struct drm_framebuffer *old_fb)
    275{
    276	struct drm_device *dev = crtc->dev;
    277	struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
    278	const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
    279	const struct drm_encoder_helper_funcs *encoder_funcs;
    280	int saved_x, saved_y;
    281	bool saved_enabled;
    282	struct drm_encoder *encoder;
    283	bool ret = true;
    284
    285	WARN_ON(drm_drv_uses_atomic_modeset(dev));
    286
    287	drm_warn_on_modeset_not_all_locked(dev);
    288
    289	saved_enabled = crtc->enabled;
    290	crtc->enabled = drm_helper_crtc_in_use(crtc);
    291	if (!crtc->enabled)
    292		return true;
    293
    294	adjusted_mode = drm_mode_duplicate(dev, mode);
    295	if (!adjusted_mode) {
    296		crtc->enabled = saved_enabled;
    297		return false;
    298	}
    299
    300	drm_mode_init(&saved_mode, &crtc->mode);
    301	drm_mode_init(&saved_hwmode, &crtc->hwmode);
    302	saved_x = crtc->x;
    303	saved_y = crtc->y;
    304
    305	/* Update crtc values up front so the driver can rely on them for mode
    306	 * setting.
    307	 */
    308	drm_mode_copy(&crtc->mode, mode);
    309	crtc->x = x;
    310	crtc->y = y;
    311
    312	/* Pass our mode to the connectors and the CRTC to give them a chance to
    313	 * adjust it according to limitations or connector properties, and also
    314	 * a chance to reject the mode entirely.
    315	 */
    316	drm_for_each_encoder(encoder, dev) {
    317
    318		if (encoder->crtc != crtc)
    319			continue;
    320
    321		encoder_funcs = encoder->helper_private;
    322		if (!encoder_funcs)
    323			continue;
    324
    325		encoder_funcs = encoder->helper_private;
    326		if (encoder_funcs->mode_fixup) {
    327			if (!(ret = encoder_funcs->mode_fixup(encoder, mode,
    328							      adjusted_mode))) {
    329				DRM_DEBUG_KMS("Encoder fixup failed\n");
    330				goto done;
    331			}
    332		}
    333	}
    334
    335	if (crtc_funcs->mode_fixup) {
    336		if (!(ret = crtc_funcs->mode_fixup(crtc, mode,
    337						adjusted_mode))) {
    338			DRM_DEBUG_KMS("CRTC fixup failed\n");
    339			goto done;
    340		}
    341	}
    342	DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
    343
    344	drm_mode_copy(&crtc->hwmode, adjusted_mode);
    345
    346	/* Prepare the encoders and CRTCs before setting the mode. */
    347	drm_for_each_encoder(encoder, dev) {
    348
    349		if (encoder->crtc != crtc)
    350			continue;
    351
    352		encoder_funcs = encoder->helper_private;
    353		if (!encoder_funcs)
    354			continue;
    355
    356		/* Disable the encoders as the first thing we do. */
    357		if (encoder_funcs->prepare)
    358			encoder_funcs->prepare(encoder);
    359	}
    360
    361	drm_crtc_prepare_encoders(dev);
    362
    363	crtc_funcs->prepare(crtc);
    364
    365	/* Set up the DPLL and any encoders state that needs to adjust or depend
    366	 * on the DPLL.
    367	 */
    368	ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
    369	if (!ret)
    370	    goto done;
    371
    372	drm_for_each_encoder(encoder, dev) {
    373
    374		if (encoder->crtc != crtc)
    375			continue;
    376
    377		encoder_funcs = encoder->helper_private;
    378		if (!encoder_funcs)
    379			continue;
    380
    381		DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%s]\n",
    382			encoder->base.id, encoder->name, mode->name);
    383		if (encoder_funcs->mode_set)
    384			encoder_funcs->mode_set(encoder, mode, adjusted_mode);
    385	}
    386
    387	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
    388	crtc_funcs->commit(crtc);
    389
    390	drm_for_each_encoder(encoder, dev) {
    391
    392		if (encoder->crtc != crtc)
    393			continue;
    394
    395		encoder_funcs = encoder->helper_private;
    396		if (!encoder_funcs)
    397			continue;
    398
    399		if (encoder_funcs->commit)
    400			encoder_funcs->commit(encoder);
    401	}
    402
    403	/* Calculate and store various constants which
    404	 * are later needed by vblank and swap-completion
    405	 * timestamping. They are derived from true hwmode.
    406	 */
    407	drm_calc_timestamping_constants(crtc, &crtc->hwmode);
    408
    409	/* FIXME: add subpixel order */
    410done:
    411	drm_mode_destroy(dev, adjusted_mode);
    412	if (!ret) {
    413		crtc->enabled = saved_enabled;
    414		drm_mode_copy(&crtc->mode, &saved_mode);
    415		drm_mode_copy(&crtc->hwmode, &saved_hwmode);
    416		crtc->x = saved_x;
    417		crtc->y = saved_y;
    418	}
    419
    420	return ret;
    421}
    422EXPORT_SYMBOL(drm_crtc_helper_set_mode);
    423
    424static void
    425drm_crtc_helper_disable(struct drm_crtc *crtc)
    426{
    427	struct drm_device *dev = crtc->dev;
    428	struct drm_connector *connector;
    429	struct drm_encoder *encoder;
    430
    431	/* Decouple all encoders and their attached connectors from this crtc */
    432	drm_for_each_encoder(encoder, dev) {
    433		struct drm_connector_list_iter conn_iter;
    434
    435		if (encoder->crtc != crtc)
    436			continue;
    437
    438		drm_connector_list_iter_begin(dev, &conn_iter);
    439		drm_for_each_connector_iter(connector, &conn_iter) {
    440			if (connector->encoder != encoder)
    441				continue;
    442
    443			connector->encoder = NULL;
    444
    445			/*
    446			 * drm_helper_disable_unused_functions() ought to be
    447			 * doing this, but since we've decoupled the encoder
    448			 * from the connector above, the required connection
    449			 * between them is henceforth no longer available.
    450			 */
    451			connector->dpms = DRM_MODE_DPMS_OFF;
    452
    453			/* we keep a reference while the encoder is bound */
    454			drm_connector_put(connector);
    455		}
    456		drm_connector_list_iter_end(&conn_iter);
    457	}
    458
    459	__drm_helper_disable_unused_functions(dev);
    460}
    461
    462/*
    463 * For connectors that support multiple encoders, either the
    464 * .atomic_best_encoder() or .best_encoder() operation must be implemented.
    465 */
    466struct drm_encoder *
    467drm_connector_get_single_encoder(struct drm_connector *connector)
    468{
    469	struct drm_encoder *encoder;
    470
    471	WARN_ON(hweight32(connector->possible_encoders) > 1);
    472	drm_connector_for_each_possible_encoder(connector, encoder)
    473		return encoder;
    474
    475	return NULL;
    476}
    477
    478/**
    479 * drm_crtc_helper_set_config - set a new config from userspace
    480 * @set: mode set configuration
    481 * @ctx: lock acquire context, not used here
    482 *
    483 * The drm_crtc_helper_set_config() helper function implements the of
    484 * &drm_crtc_funcs.set_config callback for drivers using the legacy CRTC
    485 * helpers.
    486 *
    487 * It first tries to locate the best encoder for each connector by calling the
    488 * connector @drm_connector_helper_funcs.best_encoder helper operation.
    489 *
    490 * After locating the appropriate encoders, the helper function will call the
    491 * mode_fixup encoder and CRTC helper operations to adjust the requested mode,
    492 * or reject it completely in which case an error will be returned to the
    493 * application. If the new configuration after mode adjustment is identical to
    494 * the current configuration the helper function will return without performing
    495 * any other operation.
    496 *
    497 * If the adjusted mode is identical to the current mode but changes to the
    498 * frame buffer need to be applied, the drm_crtc_helper_set_config() function
    499 * will call the CRTC &drm_crtc_helper_funcs.mode_set_base helper operation.
    500 *
    501 * If the adjusted mode differs from the current mode, or if the
    502 * ->mode_set_base() helper operation is not provided, the helper function
    503 * performs a full mode set sequence by calling the ->prepare(), ->mode_set()
    504 * and ->commit() CRTC and encoder helper operations, in that order.
    505 * Alternatively it can also use the dpms and disable helper operations. For
    506 * details see &struct drm_crtc_helper_funcs and struct
    507 * &drm_encoder_helper_funcs.
    508 *
    509 * This function is deprecated.  New drivers must implement atomic modeset
    510 * support, for which this function is unsuitable. Instead drivers should use
    511 * drm_atomic_helper_set_config().
    512 *
    513 * Returns:
    514 * Returns 0 on success, negative errno numbers on failure.
    515 */
    516int drm_crtc_helper_set_config(struct drm_mode_set *set,
    517			       struct drm_modeset_acquire_ctx *ctx)
    518{
    519	struct drm_device *dev;
    520	struct drm_crtc **save_encoder_crtcs, *new_crtc;
    521	struct drm_encoder **save_connector_encoders, *new_encoder, *encoder;
    522	bool mode_changed = false; /* if true do a full mode set */
    523	bool fb_changed = false; /* if true and !mode_changed just do a flip */
    524	struct drm_connector *connector;
    525	struct drm_connector_list_iter conn_iter;
    526	int count = 0, ro, fail = 0;
    527	const struct drm_crtc_helper_funcs *crtc_funcs;
    528	struct drm_mode_set save_set;
    529	int ret;
    530	int i;
    531
    532	DRM_DEBUG_KMS("\n");
    533
    534	BUG_ON(!set);
    535	BUG_ON(!set->crtc);
    536	BUG_ON(!set->crtc->helper_private);
    537
    538	/* Enforce sane interface api - has been abused by the fb helper. */
    539	BUG_ON(!set->mode && set->fb);
    540	BUG_ON(set->fb && set->num_connectors == 0);
    541
    542	crtc_funcs = set->crtc->helper_private;
    543
    544	dev = set->crtc->dev;
    545	WARN_ON(drm_drv_uses_atomic_modeset(dev));
    546
    547	if (!set->mode)
    548		set->fb = NULL;
    549
    550	if (set->fb) {
    551		DRM_DEBUG_KMS("[CRTC:%d:%s] [FB:%d] #connectors=%d (x y) (%i %i)\n",
    552			      set->crtc->base.id, set->crtc->name,
    553			      set->fb->base.id,
    554			      (int)set->num_connectors, set->x, set->y);
    555	} else {
    556		DRM_DEBUG_KMS("[CRTC:%d:%s] [NOFB]\n",
    557			      set->crtc->base.id, set->crtc->name);
    558		drm_crtc_helper_disable(set->crtc);
    559		return 0;
    560	}
    561
    562	drm_warn_on_modeset_not_all_locked(dev);
    563
    564	/*
    565	 * Allocate space for the backup of all (non-pointer) encoder and
    566	 * connector data.
    567	 */
    568	save_encoder_crtcs = kcalloc(dev->mode_config.num_encoder,
    569				sizeof(struct drm_crtc *), GFP_KERNEL);
    570	if (!save_encoder_crtcs)
    571		return -ENOMEM;
    572
    573	save_connector_encoders = kcalloc(dev->mode_config.num_connector,
    574				sizeof(struct drm_encoder *), GFP_KERNEL);
    575	if (!save_connector_encoders) {
    576		kfree(save_encoder_crtcs);
    577		return -ENOMEM;
    578	}
    579
    580	/*
    581	 * Copy data. Note that driver private data is not affected.
    582	 * Should anything bad happen only the expected state is
    583	 * restored, not the drivers personal bookkeeping.
    584	 */
    585	count = 0;
    586	drm_for_each_encoder(encoder, dev) {
    587		save_encoder_crtcs[count++] = encoder->crtc;
    588	}
    589
    590	count = 0;
    591	drm_connector_list_iter_begin(dev, &conn_iter);
    592	drm_for_each_connector_iter(connector, &conn_iter)
    593		save_connector_encoders[count++] = connector->encoder;
    594	drm_connector_list_iter_end(&conn_iter);
    595
    596	save_set.crtc = set->crtc;
    597	save_set.mode = &set->crtc->mode;
    598	save_set.x = set->crtc->x;
    599	save_set.y = set->crtc->y;
    600	save_set.fb = set->crtc->primary->fb;
    601
    602	/* We should be able to check here if the fb has the same properties
    603	 * and then just flip_or_move it */
    604	if (set->crtc->primary->fb != set->fb) {
    605		/* If we have no fb then treat it as a full mode set */
    606		if (set->crtc->primary->fb == NULL) {
    607			DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
    608			mode_changed = true;
    609		} else if (set->fb->format != set->crtc->primary->fb->format) {
    610			mode_changed = true;
    611		} else
    612			fb_changed = true;
    613	}
    614
    615	if (set->x != set->crtc->x || set->y != set->crtc->y)
    616		fb_changed = true;
    617
    618	if (!drm_mode_equal(set->mode, &set->crtc->mode)) {
    619		DRM_DEBUG_KMS("modes are different, full mode set\n");
    620		drm_mode_debug_printmodeline(&set->crtc->mode);
    621		drm_mode_debug_printmodeline(set->mode);
    622		mode_changed = true;
    623	}
    624
    625	/* take a reference on all unbound connectors in set, reuse the
    626	 * already taken reference for bound connectors
    627	 */
    628	for (ro = 0; ro < set->num_connectors; ro++) {
    629		if (set->connectors[ro]->encoder)
    630			continue;
    631		drm_connector_get(set->connectors[ro]);
    632	}
    633
    634	/* a) traverse passed in connector list and get encoders for them */
    635	count = 0;
    636	drm_connector_list_iter_begin(dev, &conn_iter);
    637	drm_for_each_connector_iter(connector, &conn_iter) {
    638		const struct drm_connector_helper_funcs *connector_funcs =
    639			connector->helper_private;
    640		new_encoder = connector->encoder;
    641		for (ro = 0; ro < set->num_connectors; ro++) {
    642			if (set->connectors[ro] == connector) {
    643				if (connector_funcs->best_encoder)
    644					new_encoder = connector_funcs->best_encoder(connector);
    645				else
    646					new_encoder = drm_connector_get_single_encoder(connector);
    647
    648				/* if we can't get an encoder for a connector
    649				   we are setting now - then fail */
    650				if (new_encoder == NULL)
    651					/* don't break so fail path works correct */
    652					fail = 1;
    653
    654				if (connector->dpms != DRM_MODE_DPMS_ON) {
    655					DRM_DEBUG_KMS("connector dpms not on, full mode switch\n");
    656					mode_changed = true;
    657				}
    658
    659				break;
    660			}
    661		}
    662
    663		if (new_encoder != connector->encoder) {
    664			DRM_DEBUG_KMS("encoder changed, full mode switch\n");
    665			mode_changed = true;
    666			/* If the encoder is reused for another connector, then
    667			 * the appropriate crtc will be set later.
    668			 */
    669			if (connector->encoder)
    670				connector->encoder->crtc = NULL;
    671			connector->encoder = new_encoder;
    672		}
    673	}
    674	drm_connector_list_iter_end(&conn_iter);
    675
    676	if (fail) {
    677		ret = -EINVAL;
    678		goto fail;
    679	}
    680
    681	count = 0;
    682	drm_connector_list_iter_begin(dev, &conn_iter);
    683	drm_for_each_connector_iter(connector, &conn_iter) {
    684		if (!connector->encoder)
    685			continue;
    686
    687		if (connector->encoder->crtc == set->crtc)
    688			new_crtc = NULL;
    689		else
    690			new_crtc = connector->encoder->crtc;
    691
    692		for (ro = 0; ro < set->num_connectors; ro++) {
    693			if (set->connectors[ro] == connector)
    694				new_crtc = set->crtc;
    695		}
    696
    697		/* Make sure the new CRTC will work with the encoder */
    698		if (new_crtc &&
    699		    !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
    700			ret = -EINVAL;
    701			drm_connector_list_iter_end(&conn_iter);
    702			goto fail;
    703		}
    704		if (new_crtc != connector->encoder->crtc) {
    705			DRM_DEBUG_KMS("crtc changed, full mode switch\n");
    706			mode_changed = true;
    707			connector->encoder->crtc = new_crtc;
    708		}
    709		if (new_crtc) {
    710			DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d:%s]\n",
    711				      connector->base.id, connector->name,
    712				      new_crtc->base.id, new_crtc->name);
    713		} else {
    714			DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
    715				      connector->base.id, connector->name);
    716		}
    717	}
    718	drm_connector_list_iter_end(&conn_iter);
    719
    720	/* mode_set_base is not a required function */
    721	if (fb_changed && !crtc_funcs->mode_set_base)
    722		mode_changed = true;
    723
    724	if (mode_changed) {
    725		if (drm_helper_crtc_in_use(set->crtc)) {
    726			DRM_DEBUG_KMS("attempting to set mode from"
    727					" userspace\n");
    728			drm_mode_debug_printmodeline(set->mode);
    729			set->crtc->primary->fb = set->fb;
    730			if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
    731						      set->x, set->y,
    732						      save_set.fb)) {
    733				DRM_ERROR("failed to set mode on [CRTC:%d:%s]\n",
    734					  set->crtc->base.id, set->crtc->name);
    735				set->crtc->primary->fb = save_set.fb;
    736				ret = -EINVAL;
    737				goto fail;
    738			}
    739			DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
    740			for (i = 0; i < set->num_connectors; i++) {
    741				DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id,
    742					      set->connectors[i]->name);
    743				set->connectors[i]->funcs->dpms(set->connectors[i], DRM_MODE_DPMS_ON);
    744			}
    745		}
    746		__drm_helper_disable_unused_functions(dev);
    747	} else if (fb_changed) {
    748		set->crtc->x = set->x;
    749		set->crtc->y = set->y;
    750		set->crtc->primary->fb = set->fb;
    751		ret = crtc_funcs->mode_set_base(set->crtc,
    752						set->x, set->y, save_set.fb);
    753		if (ret != 0) {
    754			set->crtc->x = save_set.x;
    755			set->crtc->y = save_set.y;
    756			set->crtc->primary->fb = save_set.fb;
    757			goto fail;
    758		}
    759	}
    760
    761	kfree(save_connector_encoders);
    762	kfree(save_encoder_crtcs);
    763	return 0;
    764
    765fail:
    766	/* Restore all previous data. */
    767	count = 0;
    768	drm_for_each_encoder(encoder, dev) {
    769		encoder->crtc = save_encoder_crtcs[count++];
    770	}
    771
    772	count = 0;
    773	drm_connector_list_iter_begin(dev, &conn_iter);
    774	drm_for_each_connector_iter(connector, &conn_iter)
    775		connector->encoder = save_connector_encoders[count++];
    776	drm_connector_list_iter_end(&conn_iter);
    777
    778	/* after fail drop reference on all unbound connectors in set, let
    779	 * bound connectors keep their reference
    780	 */
    781	for (ro = 0; ro < set->num_connectors; ro++) {
    782		if (set->connectors[ro]->encoder)
    783			continue;
    784		drm_connector_put(set->connectors[ro]);
    785	}
    786
    787	/* Try to restore the config */
    788	if (mode_changed &&
    789	    !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x,
    790				      save_set.y, save_set.fb))
    791		DRM_ERROR("failed to restore config after modeset failure\n");
    792
    793	kfree(save_connector_encoders);
    794	kfree(save_encoder_crtcs);
    795	return ret;
    796}
    797EXPORT_SYMBOL(drm_crtc_helper_set_config);
    798
    799static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
    800{
    801	int dpms = DRM_MODE_DPMS_OFF;
    802	struct drm_connector *connector;
    803	struct drm_connector_list_iter conn_iter;
    804	struct drm_device *dev = encoder->dev;
    805
    806	drm_connector_list_iter_begin(dev, &conn_iter);
    807	drm_for_each_connector_iter(connector, &conn_iter)
    808		if (connector->encoder == encoder)
    809			if (connector->dpms < dpms)
    810				dpms = connector->dpms;
    811	drm_connector_list_iter_end(&conn_iter);
    812
    813	return dpms;
    814}
    815
    816/* Helper which handles bridge ordering around encoder dpms */
    817static void drm_helper_encoder_dpms(struct drm_encoder *encoder, int mode)
    818{
    819	const struct drm_encoder_helper_funcs *encoder_funcs;
    820
    821	encoder_funcs = encoder->helper_private;
    822	if (!encoder_funcs)
    823		return;
    824
    825	if (encoder_funcs->dpms)
    826		encoder_funcs->dpms(encoder, mode);
    827}
    828
    829static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
    830{
    831	int dpms = DRM_MODE_DPMS_OFF;
    832	struct drm_connector *connector;
    833	struct drm_connector_list_iter conn_iter;
    834	struct drm_device *dev = crtc->dev;
    835
    836	drm_connector_list_iter_begin(dev, &conn_iter);
    837	drm_for_each_connector_iter(connector, &conn_iter)
    838		if (connector->encoder && connector->encoder->crtc == crtc)
    839			if (connector->dpms < dpms)
    840				dpms = connector->dpms;
    841	drm_connector_list_iter_end(&conn_iter);
    842
    843	return dpms;
    844}
    845
    846/**
    847 * drm_helper_connector_dpms() - connector dpms helper implementation
    848 * @connector: affected connector
    849 * @mode: DPMS mode
    850 *
    851 * The drm_helper_connector_dpms() helper function implements the
    852 * &drm_connector_funcs.dpms callback for drivers using the legacy CRTC
    853 * helpers.
    854 *
    855 * This is the main helper function provided by the CRTC helper framework for
    856 * implementing the DPMS connector attribute. It computes the new desired DPMS
    857 * state for all encoders and CRTCs in the output mesh and calls the
    858 * &drm_crtc_helper_funcs.dpms and &drm_encoder_helper_funcs.dpms callbacks
    859 * provided by the driver.
    860 *
    861 * This function is deprecated.  New drivers must implement atomic modeset
    862 * support, where DPMS is handled in the DRM core.
    863 *
    864 * Returns:
    865 * Always returns 0.
    866 */
    867int drm_helper_connector_dpms(struct drm_connector *connector, int mode)
    868{
    869	struct drm_encoder *encoder = connector->encoder;
    870	struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
    871	int old_dpms, encoder_dpms = DRM_MODE_DPMS_OFF;
    872
    873	WARN_ON(drm_drv_uses_atomic_modeset(connector->dev));
    874
    875	if (mode == connector->dpms)
    876		return 0;
    877
    878	old_dpms = connector->dpms;
    879	connector->dpms = mode;
    880
    881	if (encoder)
    882		encoder_dpms = drm_helper_choose_encoder_dpms(encoder);
    883
    884	/* from off to on, do crtc then encoder */
    885	if (mode < old_dpms) {
    886		if (crtc) {
    887			const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
    888
    889			if (crtc_funcs->dpms)
    890				(*crtc_funcs->dpms) (crtc,
    891						     drm_helper_choose_crtc_dpms(crtc));
    892		}
    893		if (encoder)
    894			drm_helper_encoder_dpms(encoder, encoder_dpms);
    895	}
    896
    897	/* from on to off, do encoder then crtc */
    898	if (mode > old_dpms) {
    899		if (encoder)
    900			drm_helper_encoder_dpms(encoder, encoder_dpms);
    901		if (crtc) {
    902			const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
    903
    904			if (crtc_funcs->dpms)
    905				(*crtc_funcs->dpms) (crtc,
    906						     drm_helper_choose_crtc_dpms(crtc));
    907		}
    908	}
    909
    910	return 0;
    911}
    912EXPORT_SYMBOL(drm_helper_connector_dpms);
    913
    914/**
    915 * drm_helper_resume_force_mode - force-restore mode setting configuration
    916 * @dev: drm_device which should be restored
    917 *
    918 * Drivers which use the mode setting helpers can use this function to
    919 * force-restore the mode setting configuration e.g. on resume or when something
    920 * else might have trampled over the hw state (like some overzealous old BIOSen
    921 * tended to do).
    922 *
    923 * This helper doesn't provide a error return value since restoring the old
    924 * config should never fail due to resource allocation issues since the driver
    925 * has successfully set the restored configuration already. Hence this should
    926 * boil down to the equivalent of a few dpms on calls, which also don't provide
    927 * an error code.
    928 *
    929 * Drivers where simply restoring an old configuration again might fail (e.g.
    930 * due to slight differences in allocating shared resources when the
    931 * configuration is restored in a different order than when userspace set it up)
    932 * need to use their own restore logic.
    933 *
    934 * This function is deprecated. New drivers should implement atomic mode-
    935 * setting and use the atomic suspend/resume helpers.
    936 *
    937 * See also:
    938 * drm_atomic_helper_suspend(), drm_atomic_helper_resume()
    939 */
    940void drm_helper_resume_force_mode(struct drm_device *dev)
    941{
    942	struct drm_crtc *crtc;
    943	struct drm_encoder *encoder;
    944	const struct drm_crtc_helper_funcs *crtc_funcs;
    945	int encoder_dpms;
    946	bool ret;
    947
    948	WARN_ON(drm_drv_uses_atomic_modeset(dev));
    949
    950	drm_modeset_lock_all(dev);
    951	drm_for_each_crtc(crtc, dev) {
    952
    953		if (!crtc->enabled)
    954			continue;
    955
    956		ret = drm_crtc_helper_set_mode(crtc, &crtc->mode,
    957					       crtc->x, crtc->y, crtc->primary->fb);
    958
    959		/* Restoring the old config should never fail! */
    960		if (ret == false)
    961			DRM_ERROR("failed to set mode on crtc %p\n", crtc);
    962
    963		/* Turn off outputs that were already powered off */
    964		if (drm_helper_choose_crtc_dpms(crtc)) {
    965			drm_for_each_encoder(encoder, dev) {
    966
    967				if(encoder->crtc != crtc)
    968					continue;
    969
    970				encoder_dpms = drm_helper_choose_encoder_dpms(
    971							encoder);
    972
    973				drm_helper_encoder_dpms(encoder, encoder_dpms);
    974			}
    975
    976			crtc_funcs = crtc->helper_private;
    977			if (crtc_funcs->dpms)
    978				(*crtc_funcs->dpms) (crtc,
    979						     drm_helper_choose_crtc_dpms(crtc));
    980		}
    981	}
    982
    983	/* disable the unused connectors while restoring the modesetting */
    984	__drm_helper_disable_unused_functions(dev);
    985	drm_modeset_unlock_all(dev);
    986}
    987EXPORT_SYMBOL(drm_helper_resume_force_mode);
    988
    989/**
    990 * drm_helper_force_disable_all - Forcibly turn off all enabled CRTCs
    991 * @dev: DRM device whose CRTCs to turn off
    992 *
    993 * Drivers may want to call this on unload to ensure that all displays are
    994 * unlit and the GPU is in a consistent, low power state. Takes modeset locks.
    995 *
    996 * Note: This should only be used by non-atomic legacy drivers. For an atomic
    997 * version look at drm_atomic_helper_shutdown().
    998 *
    999 * Returns:
   1000 * Zero on success, error code on failure.
   1001 */
   1002int drm_helper_force_disable_all(struct drm_device *dev)
   1003{
   1004	struct drm_crtc *crtc;
   1005	int ret = 0;
   1006
   1007	drm_modeset_lock_all(dev);
   1008	drm_for_each_crtc(crtc, dev)
   1009		if (crtc->enabled) {
   1010			struct drm_mode_set set = {
   1011				.crtc = crtc,
   1012			};
   1013
   1014			ret = drm_mode_set_config_internal(&set);
   1015			if (ret)
   1016				goto out;
   1017		}
   1018out:
   1019	drm_modeset_unlock_all(dev);
   1020	return ret;
   1021}
   1022EXPORT_SYMBOL(drm_helper_force_disable_all);