/*
 * Copyright (c) 2016 Intel Corporation
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that copyright
 * notice and this permission notice appear in supporting documentation, and
 * that the name of the copyright holders not be used in advertising or
 * publicity pertaining to distribution of the software without specific,
 * written prior permission.  The copyright holders make no representations
 * about the suitability of this software for any purpose.  It is provided "as
 * is" without express or implied warranty.
 *
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 * OF THIS SOFTWARE.
 */

#include <linux/export.h>
#include <linux/uaccess.h>

#include <drm/drm_drv.h>
#include <drm/drm_encoder.h>
#include <drm/drm_file.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_managed.h>
#include <drm/drm_mode_config.h>
#include <drm/drm_print.h>
#include <drm/drm_colorop.h>
#include <linux/dma-resv.h>

#include "drm_crtc_internal.h"
#include "drm_internal.h"

int drm_modeset_register_all(struct drm_device *dev)
{
	int ret;

	ret = drm_plane_register_all(dev);
	if (ret)
		goto err_plane;

	ret = drm_crtc_register_all(dev);
	if  (ret)
		goto err_crtc;

	ret = drm_encoder_register_all(dev);
	if (ret)
		goto err_encoder;

	ret = drm_connector_register_all(dev);
	if (ret)
		goto err_connector;

	return 0;

err_connector:
	drm_encoder_unregister_all(dev);
err_encoder:
	drm_crtc_unregister_all(dev);
err_crtc:
	drm_plane_unregister_all(dev);
err_plane:
	return ret;
}

void drm_modeset_unregister_all(struct drm_device *dev)
{
	drm_connector_unregister_all(dev);
	drm_encoder_unregister_all(dev);
	drm_crtc_unregister_all(dev);
	drm_plane_unregister_all(dev);
}

/**
 * drm_mode_getresources - get graphics configuration
 * @dev: drm device for the ioctl
 * @data: data pointer for the ioctl
 * @file_priv: drm file for the ioctl call
 *
 * Construct a set of configuration description structures and return
 * them to the user, including CRTC, connector and framebuffer configuration.
 *
 * Called by the user via ioctl.
 *
 * Returns:
 * Zero on success, negative errno on failure.
 */
int drm_mode_getresources(struct drm_device *dev, void *data,
			  struct drm_file *file_priv)
{
	struct drm_mode_card_res *card_res = data;
	struct drm_framebuffer *fb;
	struct drm_connector *connector;
	struct drm_crtc *crtc;
	struct drm_encoder *encoder;
	int count, ret = 0;
	uint32_t __user *fb_id;
	uint32_t __user *crtc_id;
	uint32_t __user *connector_id;
	uint32_t __user *encoder_id;
	struct drm_connector_list_iter conn_iter;

	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		return -EOPNOTSUPP;

	mutex_lock(&file_priv->fbs_lock);
	count = 0;
	fb_id = u64_to_user_ptr(card_res->fb_id_ptr);
	list_for_each_entry(fb, &file_priv->fbs, filp_head) {
		if (count < card_res->count_fbs &&
		    put_user(fb->base.id, fb_id + count)) {
			mutex_unlock(&file_priv->fbs_lock);
			return -EFAULT;
		}
		count++;
	}
	card_res->count_fbs = count;
	mutex_unlock(&file_priv->fbs_lock);

	card_res->max_height = dev->mode_config.max_height;
	card_res->min_height = dev->mode_config.min_height;
	card_res->max_width = dev->mode_config.max_width;
	card_res->min_width = dev->mode_config.min_width;

	count = 0;
	crtc_id = u64_to_user_ptr(card_res->crtc_id_ptr);
	drm_for_each_crtc(crtc, dev) {
		if (drm_lease_held(file_priv, crtc->base.id)) {
			if (count < card_res->count_crtcs &&
			    put_user(crtc->base.id, crtc_id + count))
				return -EFAULT;
			count++;
		}
	}
	card_res->count_crtcs = count;

	count = 0;
	encoder_id = u64_to_user_ptr(card_res->encoder_id_ptr);
	drm_for_each_encoder(encoder, dev) {
		if (count < card_res->count_encoders &&
		    put_user(encoder->base.id, encoder_id + count))
			return -EFAULT;
		count++;
	}
	card_res->count_encoders = count;

	drm_connector_list_iter_begin(dev, &conn_iter);
	count = 0;
	connector_id = u64_to_user_ptr(card_res->connector_id_ptr);
	/*
	 * FIXME: the connectors on the list may not be fully initialized yet,
	 * if the ioctl is called before the connectors are registered. (See
	 * drm_dev_register()->drm_modeset_register_all() for static and
	 * drm_connector_dynamic_register() for dynamic connectors.)
	 * The driver should only get registered after static connectors are
	 * fully initialized and dynamic connectors should be added to the
	 * connector list only after fully initializing them.
	 */
	drm_for_each_connector_iter(connector, &conn_iter) {
		/* only expose writeback connectors if userspace understands them */
		if (!file_priv->writeback_connectors &&
		    (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK))
			continue;

		if (drm_lease_held(file_priv, connector->base.id)) {
			if (count < card_res->count_connectors &&
			    put_user(connector->base.id, connector_id + count)) {
				drm_connector_list_iter_end(&conn_iter);
				return -EFAULT;
			}
			count++;
		}
	}
	card_res->count_connectors = count;
	drm_connector_list_iter_end(&conn_iter);

	return ret;
}

/**
 * drm_mode_config_reset - call ->reset callbacks
 * @dev: drm device
 *
 * This functions calls all the crtc's, encoder's and connector's ->reset
 * callback. Drivers can use this in e.g. their driver load or resume code to
 * reset hardware and software state.
 */
void drm_mode_config_reset(struct drm_device *dev)
{
	struct drm_crtc *crtc;
	struct drm_colorop *colorop;
	struct drm_plane *plane;
	struct drm_encoder *encoder;
	struct drm_connector *connector;
	struct drm_connector_list_iter conn_iter;

	drm_for_each_colorop(colorop, dev)
		drm_colorop_reset(colorop);

	drm_for_each_plane(plane, dev)
		if (plane->funcs->reset)
			plane->funcs->reset(plane);

	drm_for_each_crtc(crtc, dev)
		if (crtc->funcs->reset)
			crtc->funcs->reset(crtc);

	drm_for_each_encoder(encoder, dev)
		if (encoder->funcs && encoder->funcs->reset)
			encoder->funcs->reset(encoder);

	drm_connector_list_iter_begin(dev, &conn_iter);
	drm_for_each_connector_iter(connector, &conn_iter)
		if (connector->funcs->reset)
			connector->funcs->reset(connector);
	drm_connector_list_iter_end(&conn_iter);
}
EXPORT_SYMBOL(drm_mode_config_reset);

/*
 * Global properties
 */
static const struct drm_prop_enum_list drm_plane_type_enum_list[] = {
	{ DRM_PLANE_TYPE_OVERLAY, "Overlay" },
	{ DRM_PLANE_TYPE_PRIMARY, "Primary" },
	{ DRM_PLANE_TYPE_CURSOR, "Cursor" },
};

static int drm_mode_create_standard_properties(struct drm_device *dev)
{
	struct drm_property *prop;
	int ret;

	ret = drm_connector_create_standard_properties(dev);
	if (ret)
		return ret;

	prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
					"type", drm_plane_type_enum_list,
					ARRAY_SIZE(drm_plane_type_enum_list));
	if (!prop)
		return -ENOMEM;
	dev->mode_config.plane_type_property = prop;

	prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
			"SRC_X", 0, UINT_MAX);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.prop_src_x = prop;

	prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
			"SRC_Y", 0, UINT_MAX);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.prop_src_y = prop;

	prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
			"SRC_W", 0, UINT_MAX);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.prop_src_w = prop;

	prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
			"SRC_H", 0, UINT_MAX);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.prop_src_h = prop;

	prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
			"CRTC_X", INT_MIN, INT_MAX);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.prop_crtc_x = prop;

	prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
			"CRTC_Y", INT_MIN, INT_MAX);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.prop_crtc_y = prop;

	prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
			"CRTC_W", 0, INT_MAX);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.prop_crtc_w = prop;

	prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
			"CRTC_H", 0, INT_MAX);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.prop_crtc_h = prop;

	prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
			"FB_ID", DRM_MODE_OBJECT_FB);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.prop_fb_id = prop;

	prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
			"IN_FENCE_FD", -1, INT_MAX);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.prop_in_fence_fd = prop;

	prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
			"OUT_FENCE_PTR", 0, U64_MAX);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.prop_out_fence_ptr = prop;

	prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
			"CRTC_ID", DRM_MODE_OBJECT_CRTC);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.prop_crtc_id = prop;

	prop = drm_property_create(dev,
			DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
			"FB_DAMAGE_CLIPS", 0);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.prop_fb_damage_clips = prop;

	prop = drm_property_create_bool(dev, DRM_MODE_PROP_ATOMIC,
			"ACTIVE");
	if (!prop)
		return -ENOMEM;
	dev->mode_config.prop_active = prop;

	prop = drm_property_create(dev,
			DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
			"MODE_ID", 0);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.prop_mode_id = prop;

	prop = drm_property_create_bool(dev, 0,
			"VRR_ENABLED");
	if (!prop)
		return -ENOMEM;
	dev->mode_config.prop_vrr_enabled = prop;

	prop = drm_property_create(dev,
			DRM_MODE_PROP_BLOB,
			"DEGAMMA_LUT", 0);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.degamma_lut_property = prop;

	prop = drm_property_create_range(dev,
			DRM_MODE_PROP_IMMUTABLE,
			"DEGAMMA_LUT_SIZE", 0, UINT_MAX);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.degamma_lut_size_property = prop;

	prop = drm_property_create(dev,
			DRM_MODE_PROP_BLOB,
			"CTM", 0);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.ctm_property = prop;

	prop = drm_property_create(dev,
			DRM_MODE_PROP_BLOB,
			"GAMMA_LUT", 0);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.gamma_lut_property = prop;

	prop = drm_property_create_range(dev,
			DRM_MODE_PROP_IMMUTABLE,
			"GAMMA_LUT_SIZE", 0, UINT_MAX);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.gamma_lut_size_property = prop;

	prop = drm_property_create(dev,
				   DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB,
				   "IN_FORMATS", 0);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.modifiers_property = prop;

	prop = drm_property_create(dev,
				   DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB,
				   "IN_FORMATS_ASYNC", 0);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.async_modifiers_property = prop;

	prop = drm_property_create(dev,
				   DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB,
				   "SIZE_HINTS", 0);
	if (!prop)
		return -ENOMEM;
	dev->mode_config.size_hints_property = prop;

	return 0;
}

static void drm_mode_config_init_release(struct drm_device *dev, void *ptr)
{
	drm_mode_config_cleanup(dev);
}

/**
 * drmm_mode_config_init - managed DRM mode_configuration structure
 * 	initialization
 * @dev: DRM device
 *
 * Initialize @dev's mode_config structure, used for tracking the graphics
 * configuration of @dev.
 *
 * Since this initializes the modeset locks, no locking is possible. Which is no
 * problem, since this should happen single threaded at init time. It is the
 * driver's problem to ensure this guarantee.
 *
 * Cleanup is automatically handled through registering drm_mode_config_cleanup
 * with drmm_add_action().
 *
 * Returns: 0 on success, negative error value on failure.
 */
int drmm_mode_config_init(struct drm_device *dev)
{
	int ret;

	mutex_init(&dev->mode_config.mutex);
	drm_modeset_lock_init(&dev->mode_config.connection_mutex);
	mutex_init(&dev->mode_config.idr_mutex);
	mutex_init(&dev->mode_config.fb_lock);
	mutex_init(&dev->mode_config.blob_lock);
	INIT_LIST_HEAD(&dev->mode_config.fb_list);
	INIT_LIST_HEAD(&dev->mode_config.crtc_list);
	INIT_LIST_HEAD(&dev->mode_config.connector_list);
	INIT_LIST_HEAD(&dev->mode_config.encoder_list);
	INIT_LIST_HEAD(&dev->mode_config.property_list);
	INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
	INIT_LIST_HEAD(&dev->mode_config.plane_list);
	INIT_LIST_HEAD(&dev->mode_config.colorop_list);
	INIT_LIST_HEAD(&dev->mode_config.privobj_list);
	idr_init_base(&dev->mode_config.object_idr, 1);
	idr_init_base(&dev->mode_config.tile_idr, 1);
	ida_init(&dev->mode_config.connector_ida);
	spin_lock_init(&dev->mode_config.connector_list_lock);

	init_llist_head(&dev->mode_config.connector_free_list);
	INIT_WORK(&dev->mode_config.connector_free_work, drm_connector_free_work_fn);

	ret = drm_mode_create_standard_properties(dev);
	if (ret) {
		drm_mode_config_cleanup(dev);
		return ret;
	}

	/* Just to be sure */
	dev->mode_config.num_fb = 0;
	dev->mode_config.num_connector = 0;
	dev->mode_config.num_crtc = 0;
	dev->mode_config.num_encoder = 0;
	dev->mode_config.num_total_plane = 0;
	dev->mode_config.num_colorop = 0;

	if (IS_ENABLED(CONFIG_LOCKDEP)) {
		struct drm_modeset_acquire_ctx modeset_ctx;
		struct ww_acquire_ctx resv_ctx;
		struct dma_resv resv;
		int ret;

		dma_resv_init(&resv);

		drm_modeset_acquire_init(&modeset_ctx, 0);
		ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
				       &modeset_ctx);
		if (ret == -EDEADLK)
			ret = drm_modeset_backoff(&modeset_ctx);

		might_fault();

		ww_acquire_init(&resv_ctx, &reservation_ww_class);
		ret = dma_resv_lock(&resv, &resv_ctx);
		if (ret == -EDEADLK)
			dma_resv_lock_slow(&resv, &resv_ctx);

		dma_resv_unlock(&resv);
		ww_acquire_fini(&resv_ctx);

		drm_modeset_drop_locks(&modeset_ctx);
		drm_modeset_acquire_fini(&modeset_ctx);
		dma_resv_fini(&resv);
	}

	return drmm_add_action_or_reset(dev, drm_mode_config_init_release,
					NULL);
}
EXPORT_SYMBOL(drmm_mode_config_init);

/**
 * drm_mode_config_cleanup - free up DRM mode_config info
 * @dev: DRM device
 *
 * Free up all the connectors and CRTCs associated with this DRM device, then
 * free up the framebuffers and associated buffer objects.
 *
 * Note that since this /should/ happen single-threaded at driver/device
 * teardown time, no locking is required. It's the driver's job to ensure that
 * this guarantee actually holds true.
 *
 * FIXME: With the managed drmm_mode_config_init() it is no longer necessary for
 * drivers to explicitly call this function.
 */
void drm_mode_config_cleanup(struct drm_device *dev)
{
	struct drm_connector *connector;
	struct drm_connector_list_iter conn_iter;
	struct drm_crtc *crtc, *ct;
	struct drm_encoder *encoder, *enct;
	struct drm_framebuffer *fb, *fbt;
	struct drm_property *property, *pt;
	struct drm_property_blob *blob, *bt;
	struct drm_plane *plane, *plt;

	list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
				 head) {
		encoder->funcs->destroy(encoder);
	}

	drm_connector_list_iter_begin(dev, &conn_iter);
	drm_for_each_connector_iter(connector, &conn_iter) {
		/* drm_connector_list_iter holds an full reference to the
		 * current connector itself, which means it is inherently safe
		 * against unreferencing the current connector - but not against
		 * deleting it right away. */
		drm_connector_put(connector);
	}
	drm_connector_list_iter_end(&conn_iter);
	/* connector_iter drops references in a work item. */
	flush_work(&dev->mode_config.connector_free_work);
	if (WARN_ON(!list_empty(&dev->mode_config.connector_list))) {
		drm_connector_list_iter_begin(dev, &conn_iter);
		drm_for_each_connector_iter(connector, &conn_iter)
			DRM_ERROR("connector %s leaked!\n", connector->name);
		drm_connector_list_iter_end(&conn_iter);
	}

	list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
				 head) {
		drm_property_destroy(dev, property);
	}

	list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
				 head) {
		plane->funcs->destroy(plane);
	}

	list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
		crtc->funcs->destroy(crtc);
	}

	list_for_each_entry_safe(blob, bt, &dev->mode_config.property_blob_list,
				 head_global) {
		drm_property_blob_put(blob);
	}

	/*
	 * Single-threaded teardown context, so it's not required to grab the
	 * fb_lock to protect against concurrent fb_list access. Contrary, it
	 * would actually deadlock with the drm_framebuffer_cleanup function.
	 *
	 * Also, if there are any framebuffers left, that's a driver leak now,
	 * so politely WARN about this.
	 */
	WARN_ON(!list_empty(&dev->mode_config.fb_list));
	list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
		struct drm_printer p = drm_dbg_printer(dev, DRM_UT_KMS, "[leaked fb]");

		drm_printf(&p, "framebuffer[%u]:\n", fb->base.id);
		drm_framebuffer_print_info(&p, 1, fb);
		drm_framebuffer_free(&fb->base.refcount);
	}

	ida_destroy(&dev->mode_config.connector_ida);
	idr_destroy(&dev->mode_config.tile_idr);
	idr_destroy(&dev->mode_config.object_idr);
	drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
}
EXPORT_SYMBOL(drm_mode_config_cleanup);

static u32 full_encoder_mask(struct drm_device *dev)
{
	struct drm_encoder *encoder;
	u32 encoder_mask = 0;

	drm_for_each_encoder(encoder, dev)
		encoder_mask |= drm_encoder_mask(encoder);

	return encoder_mask;
}

/*
 * For some reason we want the encoder itself included in
 * possible_clones. Make life easy for drivers by allowing them
 * to leave possible_clones unset if no cloning is possible.
 */
static void fixup_encoder_possible_clones(struct drm_encoder *encoder)
{
	if (encoder->possible_clones == 0)
		encoder->possible_clones = drm_encoder_mask(encoder);
}

static void validate_encoder_possible_clones(struct drm_encoder *encoder)
{
	struct drm_device *dev = encoder->dev;
	u32 encoder_mask = full_encoder_mask(dev);
	struct drm_encoder *other;

	drm_for_each_encoder(other, dev) {
		WARN(!!(encoder->possible_clones & drm_encoder_mask(other)) !=
		     !!(other->possible_clones & drm_encoder_mask(encoder)),
		     "possible_clones mismatch: "
		     "[ENCODER:%d:%s] mask=0x%x possible_clones=0x%x vs. "
		     "[ENCODER:%d:%s] mask=0x%x possible_clones=0x%x\n",
		     encoder->base.id, encoder->name,
		     drm_encoder_mask(encoder), encoder->possible_clones,
		     other->base.id, other->name,
		     drm_encoder_mask(other), other->possible_clones);
	}

	WARN((encoder->possible_clones & drm_encoder_mask(encoder)) == 0 ||
	     (encoder->possible_clones & ~encoder_mask) != 0,
	     "Bogus possible_clones: "
	     "[ENCODER:%d:%s] possible_clones=0x%x (full encoder mask=0x%x)\n",
	     encoder->base.id, encoder->name,
	     encoder->possible_clones, encoder_mask);
}

static u32 full_crtc_mask(struct drm_device *dev)
{
	struct drm_crtc *crtc;
	u32 crtc_mask = 0;

	drm_for_each_crtc(crtc, dev)
		crtc_mask |= drm_crtc_mask(crtc);

	return crtc_mask;
}

static void validate_encoder_possible_crtcs(struct drm_encoder *encoder)
{
	u32 crtc_mask = full_crtc_mask(encoder->dev);

	WARN((encoder->possible_crtcs & crtc_mask) == 0 ||
	     (encoder->possible_crtcs & ~crtc_mask) != 0,
	     "Bogus possible_crtcs: "
	     "[ENCODER:%d:%s] possible_crtcs=0x%x (full crtc mask=0x%x)\n",
	     encoder->base.id, encoder->name,
	     encoder->possible_crtcs, crtc_mask);
}

void drm_mode_config_validate(struct drm_device *dev)
{
	struct drm_encoder *encoder;
	struct drm_crtc *crtc;
	struct drm_plane *plane;
	u32 primary_with_crtc = 0, cursor_with_crtc = 0;
	unsigned int num_primary = 0;

	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		return;

	drm_for_each_encoder(encoder, dev)
		fixup_encoder_possible_clones(encoder);

	drm_for_each_encoder(encoder, dev) {
		validate_encoder_possible_clones(encoder);
		validate_encoder_possible_crtcs(encoder);
	}

	drm_for_each_crtc(crtc, dev) {
		WARN(!crtc->primary, "Missing primary plane on [CRTC:%d:%s]\n",
		     crtc->base.id, crtc->name);

		WARN(crtc->cursor && crtc->funcs->cursor_set,
		     "[CRTC:%d:%s] must not have both a cursor plane and a cursor_set func",
		     crtc->base.id, crtc->name);
		WARN(crtc->cursor && crtc->funcs->cursor_set2,
		     "[CRTC:%d:%s] must not have both a cursor plane and a cursor_set2 func",
		     crtc->base.id, crtc->name);
		WARN(crtc->cursor && crtc->funcs->cursor_move,
		     "[CRTC:%d:%s] must not have both a cursor plane and a cursor_move func",
		     crtc->base.id, crtc->name);

		if (crtc->primary) {
			WARN(!(crtc->primary->possible_crtcs & drm_crtc_mask(crtc)),
			     "Bogus primary plane possible_crtcs: [PLANE:%d:%s] must be compatible with [CRTC:%d:%s]\n",
			     crtc->primary->base.id, crtc->primary->name,
			     crtc->base.id, crtc->name);
			WARN(primary_with_crtc & drm_plane_mask(crtc->primary),
			     "Primary plane [PLANE:%d:%s] used for multiple CRTCs",
			     crtc->primary->base.id, crtc->primary->name);
			primary_with_crtc |= drm_plane_mask(crtc->primary);
		}
		if (crtc->cursor) {
			WARN(!(crtc->cursor->possible_crtcs & drm_crtc_mask(crtc)),
			     "Bogus cursor plane possible_crtcs: [PLANE:%d:%s] must be compatible with [CRTC:%d:%s]\n",
			     crtc->cursor->base.id, crtc->cursor->name,
			     crtc->base.id, crtc->name);
			WARN(cursor_with_crtc & drm_plane_mask(crtc->cursor),
			     "Cursor plane [PLANE:%d:%s] used for multiple CRTCs",
			     crtc->cursor->base.id, crtc->cursor->name);
			cursor_with_crtc |= drm_plane_mask(crtc->cursor);
		}
	}

	drm_for_each_plane(plane, dev) {
		if (plane->type == DRM_PLANE_TYPE_PRIMARY)
			num_primary++;
	}

	WARN(num_primary != dev->mode_config.num_crtc,
	     "Must have as many primary planes as there are CRTCs, but have %u primary planes and %u CRTCs",
	     num_primary, dev->mode_config.num_crtc);
}
