// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2012 Russell King
 *  Rewritten from the dovefb driver, and Armada510 manuals.
 */
#include <drm/drmP.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_uapi.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_plane_helper.h>
#include <drm/armada_drm.h>
#include "armada_crtc.h"
#include "armada_drm.h"
#include "armada_fb.h"
#include "armada_gem.h"
#include "armada_hw.h"
#include "armada_ioctlP.h"
#include "armada_plane.h"
#include "armada_trace.h"

#define DEFAULT_BRIGHTNESS	0
#define DEFAULT_CONTRAST	0x4000
#define DEFAULT_SATURATION	0x4000
#define DEFAULT_ENCODING	DRM_COLOR_YCBCR_BT601

struct armada_overlay_state {
	struct armada_plane_state base;
	u32 colorkey_yr;
	u32 colorkey_ug;
	u32 colorkey_vb;
	u32 colorkey_mode;
	u32 colorkey_enable;
	s16 brightness;
	u16 contrast;
	u16 saturation;
};
#define drm_to_overlay_state(s) \
	container_of(s, struct armada_overlay_state, base.base)

static inline u32 armada_spu_contrast(struct drm_plane_state *state)
{
	return drm_to_overlay_state(state)->brightness << 16 |
	       drm_to_overlay_state(state)->contrast;
}

static inline u32 armada_spu_saturation(struct drm_plane_state *state)
{
	/* Docs say 15:0, but it seems to actually be 31:16 on Armada 510 */
	return drm_to_overlay_state(state)->saturation << 16;
}

static inline u32 armada_csc(struct drm_plane_state *state)
{
	/*
	 * The CFG_CSC_RGB_* settings control the output of the colour space
	 * converter, setting the range of output values it produces.  Since
	 * we will be blending with the full-range graphics, we need to
	 * produce full-range RGB output from the conversion.
	 */
	return CFG_CSC_RGB_COMPUTER |
	       (state->color_encoding == DRM_COLOR_YCBCR_BT709 ?
			CFG_CSC_YUV_CCIR709 : CFG_CSC_YUV_CCIR601);
}

/* === Plane support === */
static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane,
	struct drm_plane_state *old_state)
{
	struct drm_plane_state *state = plane->state;
	struct armada_crtc *dcrtc;
	struct armada_regs *regs;
	unsigned int idx;
	u32 cfg, cfg_mask, val;

	DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name);

	if (!state->fb || WARN_ON(!state->crtc))
		return;

	DRM_DEBUG_KMS("[PLANE:%d:%s] is on [CRTC:%d:%s] with [FB:%d] visible %u->%u\n",
		plane->base.id, plane->name,
		state->crtc->base.id, state->crtc->name,
		state->fb->base.id,
		old_state->visible, state->visible);

	dcrtc = drm_to_armada_crtc(state->crtc);
	regs = dcrtc->regs + dcrtc->regs_idx;

	idx = 0;
	if (!old_state->visible && state->visible)
		armada_reg_queue_mod(regs, idx,
				     0, CFG_PDWN16x66 | CFG_PDWN32x66,
				     LCD_SPU_SRAM_PARA1);
	val = armada_src_hw(state);
	if (armada_src_hw(old_state) != val)
		armada_reg_queue_set(regs, idx, val, LCD_SPU_DMA_HPXL_VLN);
	val = armada_dst_yx(state);
	if (armada_dst_yx(old_state) != val)
		armada_reg_queue_set(regs, idx, val, LCD_SPU_DMA_OVSA_HPXL_VLN);
	val = armada_dst_hw(state);
	if (armada_dst_hw(old_state) != val)
		armada_reg_queue_set(regs, idx, val, LCD_SPU_DZM_HPXL_VLN);
	/* FIXME: overlay on an interlaced display */
	if (old_state->src.x1 != state->src.x1 ||
	    old_state->src.y1 != state->src.y1 ||
	    old_state->fb != state->fb ||
	    state->crtc->state->mode_changed) {
		const struct drm_format_info *format;
		u16 src_x;

		armada_reg_queue_set(regs, idx, armada_addr(state, 0, 0),
				     LCD_SPU_DMA_START_ADDR_Y0);
		armada_reg_queue_set(regs, idx, armada_addr(state, 0, 1),
				     LCD_SPU_DMA_START_ADDR_U0);
		armada_reg_queue_set(regs, idx, armada_addr(state, 0, 2),
				     LCD_SPU_DMA_START_ADDR_V0);
		armada_reg_queue_set(regs, idx, armada_addr(state, 1, 0),
				     LCD_SPU_DMA_START_ADDR_Y1);
		armada_reg_queue_set(regs, idx, armada_addr(state, 1, 1),
				     LCD_SPU_DMA_START_ADDR_U1);
		armada_reg_queue_set(regs, idx, armada_addr(state, 1, 2),
				     LCD_SPU_DMA_START_ADDR_V1);

		val = armada_pitch(state, 0) << 16 | armada_pitch(state, 0);
		armada_reg_queue_set(regs, idx, val, LCD_SPU_DMA_PITCH_YC);
		val = armada_pitch(state, 1) << 16 | armada_pitch(state, 2);
		armada_reg_queue_set(regs, idx, val, LCD_SPU_DMA_PITCH_UV);

		cfg = CFG_DMA_FMT(drm_fb_to_armada_fb(state->fb)->fmt) |
		      CFG_DMA_MOD(drm_fb_to_armada_fb(state->fb)->mod) |
		      CFG_CBSH_ENA;
		if (state->visible)
			cfg |= CFG_DMA_ENA;

		/*
		 * Shifting a YUV packed format image by one pixel causes the
		 * U/V planes to swap.  Compensate for it by also toggling
		 * the UV swap.
		 */
		format = state->fb->format;
		src_x = state->src.x1 >> 16;
		if (format->num_planes == 1 && src_x & (format->hsub - 1))
			cfg ^= CFG_DMA_MOD(CFG_SWAPUV);
		if (to_armada_plane_state(state)->interlace)
			cfg |= CFG_DMA_FTOGGLE;
		cfg_mask = CFG_CBSH_ENA | CFG_DMAFORMAT |
			   CFG_DMA_MOD(CFG_SWAPRB | CFG_SWAPUV |
				       CFG_SWAPYU | CFG_YUV2RGB) |
			   CFG_DMA_FTOGGLE | CFG_DMA_TSTMODE |
			   CFG_DMA_ENA;
	} else if (old_state->visible != state->visible) {
		cfg = state->visible ? CFG_DMA_ENA : 0;
		cfg_mask = CFG_DMA_ENA;
	} else {
		cfg = cfg_mask = 0;
	}
	if (drm_rect_width(&old_state->src) != drm_rect_width(&state->src) ||
	    drm_rect_width(&old_state->dst) != drm_rect_width(&state->dst)) {
		cfg_mask |= CFG_DMA_HSMOOTH;
		if (drm_rect_width(&state->src) >> 16 !=
		    drm_rect_width(&state->dst))
			cfg |= CFG_DMA_HSMOOTH;
	}

	if (cfg_mask)
		armada_reg_queue_mod(regs, idx, cfg, cfg_mask,
				     LCD_SPU_DMA_CTRL0);

	val = armada_spu_contrast(state);
	if ((!old_state->visible && state->visible) ||
	    armada_spu_contrast(old_state) != val)
		armada_reg_queue_set(regs, idx, val, LCD_SPU_CONTRAST);
	val = armada_spu_saturation(state);
	if ((!old_state->visible && state->visible) ||
	    armada_spu_saturation(old_state) != val)
		armada_reg_queue_set(regs, idx, val, LCD_SPU_SATURATION);
	if (!old_state->visible && state->visible)
		armada_reg_queue_set(regs, idx, 0x00002000, LCD_SPU_CBSH_HUE);
	val = armada_csc(state);
	if ((!old_state->visible && state->visible) ||
	    armada_csc(old_state) != val)
		armada_reg_queue_mod(regs, idx, val, CFG_CSC_MASK,
				     LCD_SPU_IOPAD_CONTROL);
	val = drm_to_overlay_state(state)->colorkey_yr;
	if ((!old_state->visible && state->visible) ||
	    drm_to_overlay_state(old_state)->colorkey_yr != val)
		armada_reg_queue_set(regs, idx, val, LCD_SPU_COLORKEY_Y);
	val = drm_to_overlay_state(state)->colorkey_ug;
	if ((!old_state->visible && state->visible) ||
	    drm_to_overlay_state(old_state)->colorkey_ug != val)
		armada_reg_queue_set(regs, idx, val, LCD_SPU_COLORKEY_U);
	val = drm_to_overlay_state(state)->colorkey_vb;
	if ((!old_state->visible && state->visible) ||
	    drm_to_overlay_state(old_state)->colorkey_vb != val)
		armada_reg_queue_set(regs, idx, val, LCD_SPU_COLORKEY_V);
	val = drm_to_overlay_state(state)->colorkey_mode;
	if ((!old_state->visible && state->visible) ||
	    drm_to_overlay_state(old_state)->colorkey_mode != val)
		armada_reg_queue_mod(regs, idx, val, CFG_CKMODE_MASK |
				     CFG_ALPHAM_MASK | CFG_ALPHA_MASK,
				     LCD_SPU_DMA_CTRL1);
	val = drm_to_overlay_state(state)->colorkey_enable;
	if (((!old_state->visible && state->visible) ||
	     drm_to_overlay_state(old_state)->colorkey_enable != val) &&
	    dcrtc->variant->has_spu_adv_reg)
		armada_reg_queue_mod(regs, idx, val, ADV_GRACOLORKEY |
				     ADV_VIDCOLORKEY, LCD_SPU_ADV_REG);

	dcrtc->regs_idx += idx;
}

static void armada_drm_overlay_plane_atomic_disable(struct drm_plane *plane,
	struct drm_plane_state *old_state)
{
	struct armada_crtc *dcrtc;
	struct armada_regs *regs;
	unsigned int idx = 0;

	DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name);

	if (!old_state->crtc)
		return;

	DRM_DEBUG_KMS("[PLANE:%d:%s] was on [CRTC:%d:%s] with [FB:%d]\n",
		plane->base.id, plane->name,
		old_state->crtc->base.id, old_state->crtc->name,
		old_state->fb->base.id);

	dcrtc = drm_to_armada_crtc(old_state->crtc);
	regs = dcrtc->regs + dcrtc->regs_idx;

	/* Disable plane and power down the YUV FIFOs */
	armada_reg_queue_mod(regs, idx, 0, CFG_DMA_ENA, LCD_SPU_DMA_CTRL0);
	armada_reg_queue_mod(regs, idx, CFG_PDWN16x66 | CFG_PDWN32x66, 0,
			     LCD_SPU_SRAM_PARA1);

	dcrtc->regs_idx += idx;
}

static const struct drm_plane_helper_funcs armada_overlay_plane_helper_funcs = {
	.prepare_fb	= armada_drm_plane_prepare_fb,
	.cleanup_fb	= armada_drm_plane_cleanup_fb,
	.atomic_check	= armada_drm_plane_atomic_check,
	.atomic_update	= armada_drm_overlay_plane_atomic_update,
	.atomic_disable	= armada_drm_overlay_plane_atomic_disable,
};

static int
armada_overlay_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
	struct drm_framebuffer *fb,
	int crtc_x, int crtc_y, unsigned crtc_w, unsigned crtc_h,
	uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h,
	struct drm_modeset_acquire_ctx *ctx)
{
	struct drm_atomic_state *state;
	struct drm_plane_state *plane_state;
	int ret = 0;

	trace_armada_ovl_plane_update(plane, crtc, fb,
				 crtc_x, crtc_y, crtc_w, crtc_h,
				 src_x, src_y, src_w, src_h);

	state = drm_atomic_state_alloc(plane->dev);
	if (!state)
		return -ENOMEM;

	state->acquire_ctx = ctx;
	plane_state = drm_atomic_get_plane_state(state, plane);
	if (IS_ERR(plane_state)) {
		ret = PTR_ERR(plane_state);
		goto fail;
	}

	ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
	if (ret != 0)
		goto fail;

	drm_atomic_set_fb_for_plane(plane_state, fb);
	plane_state->crtc_x = crtc_x;
	plane_state->crtc_y = crtc_y;
	plane_state->crtc_h = crtc_h;
	plane_state->crtc_w = crtc_w;
	plane_state->src_x = src_x;
	plane_state->src_y = src_y;
	plane_state->src_h = src_h;
	plane_state->src_w = src_w;

	ret = drm_atomic_nonblocking_commit(state);
fail:
	drm_atomic_state_put(state);
	return ret;
}

static void armada_ovl_plane_destroy(struct drm_plane *plane)
{
	drm_plane_cleanup(plane);
	kfree(plane);
}

static void armada_overlay_reset(struct drm_plane *plane)
{
	struct armada_overlay_state *state;

	if (plane->state)
		__drm_atomic_helper_plane_destroy_state(plane->state);
	kfree(plane->state);
	plane->state = NULL;

	state = kzalloc(sizeof(*state), GFP_KERNEL);
	if (state) {
		state->colorkey_yr = 0xfefefe00;
		state->colorkey_ug = 0x01010100;
		state->colorkey_vb = 0x01010100;
		state->colorkey_mode = CFG_CKMODE(CKMODE_RGB) |
				       CFG_ALPHAM_GRA | CFG_ALPHA(0);
		state->colorkey_enable = ADV_GRACOLORKEY;
		state->brightness = DEFAULT_BRIGHTNESS;
		state->contrast = DEFAULT_CONTRAST;
		state->saturation = DEFAULT_SATURATION;
		__drm_atomic_helper_plane_reset(plane, &state->base.base);
		state->base.base.color_encoding = DEFAULT_ENCODING;
		state->base.base.color_range = DRM_COLOR_YCBCR_LIMITED_RANGE;
	}
}

struct drm_plane_state *
armada_overlay_duplicate_state(struct drm_plane *plane)
{
	struct armada_overlay_state *state;

	if (WARN_ON(!plane->state))
		return NULL;

	state = kmemdup(plane->state, sizeof(*state), GFP_KERNEL);
	if (state)
		__drm_atomic_helper_plane_duplicate_state(plane,
							  &state->base.base);
	return &state->base.base;
}

static int armada_overlay_set_property(struct drm_plane *plane,
	struct drm_plane_state *state, struct drm_property *property,
	uint64_t val)
{
	struct armada_private *priv = plane->dev->dev_private;

#define K2R(val) (((val) >> 0) & 0xff)
#define K2G(val) (((val) >> 8) & 0xff)
#define K2B(val) (((val) >> 16) & 0xff)
	if (property == priv->colorkey_prop) {
#define CCC(v) ((v) << 24 | (v) << 16 | (v) << 8)
		drm_to_overlay_state(state)->colorkey_yr = CCC(K2R(val));
		drm_to_overlay_state(state)->colorkey_ug = CCC(K2G(val));
		drm_to_overlay_state(state)->colorkey_vb = CCC(K2B(val));
#undef CCC
	} else if (property == priv->colorkey_min_prop) {
		drm_to_overlay_state(state)->colorkey_yr &= ~0x00ff0000;
		drm_to_overlay_state(state)->colorkey_yr |= K2R(val) << 16;
		drm_to_overlay_state(state)->colorkey_ug &= ~0x00ff0000;
		drm_to_overlay_state(state)->colorkey_ug |= K2G(val) << 16;
		drm_to_overlay_state(state)->colorkey_vb &= ~0x00ff0000;
		drm_to_overlay_state(state)->colorkey_vb |= K2B(val) << 16;
	} else if (property == priv->colorkey_max_prop) {
		drm_to_overlay_state(state)->colorkey_yr &= ~0xff000000;
		drm_to_overlay_state(state)->colorkey_yr |= K2R(val) << 24;
		drm_to_overlay_state(state)->colorkey_ug &= ~0xff000000;
		drm_to_overlay_state(state)->colorkey_ug |= K2G(val) << 24;
		drm_to_overlay_state(state)->colorkey_vb &= ~0xff000000;
		drm_to_overlay_state(state)->colorkey_vb |= K2B(val) << 24;
	} else if (property == priv->colorkey_val_prop) {
		drm_to_overlay_state(state)->colorkey_yr &= ~0x0000ff00;
		drm_to_overlay_state(state)->colorkey_yr |= K2R(val) << 8;
		drm_to_overlay_state(state)->colorkey_ug &= ~0x0000ff00;
		drm_to_overlay_state(state)->colorkey_ug |= K2G(val) << 8;
		drm_to_overlay_state(state)->colorkey_vb &= ~0x0000ff00;
		drm_to_overlay_state(state)->colorkey_vb |= K2B(val) << 8;
	} else if (property == priv->colorkey_alpha_prop) {
		drm_to_overlay_state(state)->colorkey_yr &= ~0x000000ff;
		drm_to_overlay_state(state)->colorkey_yr |= K2R(val);
		drm_to_overlay_state(state)->colorkey_ug &= ~0x000000ff;
		drm_to_overlay_state(state)->colorkey_ug |= K2G(val);
		drm_to_overlay_state(state)->colorkey_vb &= ~0x000000ff;
		drm_to_overlay_state(state)->colorkey_vb |= K2B(val);
	} else if (property == priv->colorkey_mode_prop) {
		if (val == CKMODE_DISABLE) {
			drm_to_overlay_state(state)->colorkey_mode =
				CFG_CKMODE(CKMODE_DISABLE) |
				CFG_ALPHAM_CFG | CFG_ALPHA(255);
			drm_to_overlay_state(state)->colorkey_enable = 0;
		} else {
			drm_to_overlay_state(state)->colorkey_mode =
				CFG_CKMODE(val) |
				CFG_ALPHAM_GRA | CFG_ALPHA(0);
			drm_to_overlay_state(state)->colorkey_enable =
				ADV_GRACOLORKEY;
		}
	} else if (property == priv->brightness_prop) {
		drm_to_overlay_state(state)->brightness = val - 256;
	} else if (property == priv->contrast_prop) {
		drm_to_overlay_state(state)->contrast = val;
	} else if (property == priv->saturation_prop) {
		drm_to_overlay_state(state)->saturation = val;
	} else {
		return -EINVAL;
	}
	return 0;
}

static int armada_overlay_get_property(struct drm_plane *plane,
	const struct drm_plane_state *state, struct drm_property *property,
	uint64_t *val)
{
	struct armada_private *priv = plane->dev->dev_private;

#define C2K(c,s)	(((c) >> (s)) & 0xff)
#define R2BGR(r,g,b,s)	(C2K(r,s) << 0 | C2K(g,s) << 8 | C2K(b,s) << 16)
	if (property == priv->colorkey_prop) {
		/* Do best-efforts here for this property */
		*val = R2BGR(drm_to_overlay_state(state)->colorkey_yr,
			     drm_to_overlay_state(state)->colorkey_ug,
			     drm_to_overlay_state(state)->colorkey_vb, 16);
		/* If min != max, or min != val, error out */
		if (*val != R2BGR(drm_to_overlay_state(state)->colorkey_yr,
				  drm_to_overlay_state(state)->colorkey_ug,
				  drm_to_overlay_state(state)->colorkey_vb, 24) ||
		    *val != R2BGR(drm_to_overlay_state(state)->colorkey_yr,
				  drm_to_overlay_state(state)->colorkey_ug,
				  drm_to_overlay_state(state)->colorkey_vb, 8))
			return -EINVAL;
	} else if (property == priv->colorkey_min_prop) {
		*val = R2BGR(drm_to_overlay_state(state)->colorkey_yr,
			     drm_to_overlay_state(state)->colorkey_ug,
			     drm_to_overlay_state(state)->colorkey_vb, 16);
	} else if (property == priv->colorkey_max_prop) {
		*val = R2BGR(drm_to_overlay_state(state)->colorkey_yr,
			     drm_to_overlay_state(state)->colorkey_ug,
			     drm_to_overlay_state(state)->colorkey_vb, 24);
	} else if (property == priv->colorkey_val_prop) {
		*val = R2BGR(drm_to_overlay_state(state)->colorkey_yr,
			     drm_to_overlay_state(state)->colorkey_ug,
			     drm_to_overlay_state(state)->colorkey_vb, 8);
	} else if (property == priv->colorkey_alpha_prop) {
		*val = R2BGR(drm_to_overlay_state(state)->colorkey_yr,
			     drm_to_overlay_state(state)->colorkey_ug,
			     drm_to_overlay_state(state)->colorkey_vb, 0);
	} else if (property == priv->colorkey_mode_prop) {
		*val = (drm_to_overlay_state(state)->colorkey_mode &
			CFG_CKMODE_MASK) >> ffs(CFG_CKMODE_MASK);
	} else if (property == priv->brightness_prop) {
		*val = drm_to_overlay_state(state)->brightness + 256;
	} else if (property == priv->contrast_prop) {
		*val = drm_to_overlay_state(state)->contrast;
	} else if (property == priv->saturation_prop) {
		*val = drm_to_overlay_state(state)->saturation;
	} else {
		return -EINVAL;
	}
	return 0;
}

static const struct drm_plane_funcs armada_ovl_plane_funcs = {
	.update_plane	= armada_overlay_plane_update,
	.disable_plane	= drm_atomic_helper_disable_plane,
	.destroy	= armada_ovl_plane_destroy,
	.reset		= armada_overlay_reset,
	.atomic_duplicate_state = armada_overlay_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
	.atomic_set_property = armada_overlay_set_property,
	.atomic_get_property = armada_overlay_get_property,
};

static const uint32_t armada_ovl_formats[] = {
	DRM_FORMAT_UYVY,
	DRM_FORMAT_YUYV,
	DRM_FORMAT_YUV420,
	DRM_FORMAT_YVU420,
	DRM_FORMAT_YUV422,
	DRM_FORMAT_YVU422,
	DRM_FORMAT_VYUY,
	DRM_FORMAT_YVYU,
	DRM_FORMAT_ARGB8888,
	DRM_FORMAT_ABGR8888,
	DRM_FORMAT_XRGB8888,
	DRM_FORMAT_XBGR8888,
	DRM_FORMAT_RGB888,
	DRM_FORMAT_BGR888,
	DRM_FORMAT_ARGB1555,
	DRM_FORMAT_ABGR1555,
	DRM_FORMAT_RGB565,
	DRM_FORMAT_BGR565,
};

static const struct drm_prop_enum_list armada_drm_colorkey_enum_list[] = {
	{ CKMODE_DISABLE, "disabled" },
	{ CKMODE_Y,       "Y component" },
	{ CKMODE_U,       "U component" },
	{ CKMODE_V,       "V component" },
	{ CKMODE_RGB,     "RGB" },
	{ CKMODE_R,       "R component" },
	{ CKMODE_G,       "G component" },
	{ CKMODE_B,       "B component" },
};

static int armada_overlay_create_properties(struct drm_device *dev)
{
	struct armada_private *priv = dev->dev_private;

	if (priv->colorkey_prop)
		return 0;

	priv->colorkey_prop = drm_property_create_range(dev, 0,
				"colorkey", 0, 0xffffff);
	priv->colorkey_min_prop = drm_property_create_range(dev, 0,
				"colorkey_min", 0, 0xffffff);
	priv->colorkey_max_prop = drm_property_create_range(dev, 0,
				"colorkey_max", 0, 0xffffff);
	priv->colorkey_val_prop = drm_property_create_range(dev, 0,
				"colorkey_val", 0, 0xffffff);
	priv->colorkey_alpha_prop = drm_property_create_range(dev, 0,
				"colorkey_alpha", 0, 0xffffff);
	priv->colorkey_mode_prop = drm_property_create_enum(dev, 0,
				"colorkey_mode",
				armada_drm_colorkey_enum_list,
				ARRAY_SIZE(armada_drm_colorkey_enum_list));
	priv->brightness_prop = drm_property_create_range(dev, 0,
				"brightness", 0, 256 + 255);
	priv->contrast_prop = drm_property_create_range(dev, 0,
				"contrast", 0, 0x7fff);
	priv->saturation_prop = drm_property_create_range(dev, 0,
				"saturation", 0, 0x7fff);

	if (!priv->colorkey_prop)
		return -ENOMEM;

	return 0;
}

int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
{
	struct armada_private *priv = dev->dev_private;
	struct drm_mode_object *mobj;
	struct drm_plane *overlay;
	int ret;

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

	overlay = kzalloc(sizeof(*overlay), GFP_KERNEL);
	if (!overlay)
		return -ENOMEM;

	drm_plane_helper_add(overlay, &armada_overlay_plane_helper_funcs);

	ret = drm_universal_plane_init(dev, overlay, crtcs,
				       &armada_ovl_plane_funcs,
				       armada_ovl_formats,
				       ARRAY_SIZE(armada_ovl_formats),
				       NULL,
				       DRM_PLANE_TYPE_OVERLAY, NULL);
	if (ret) {
		kfree(overlay);
		return ret;
	}

	mobj = &overlay->base;
	drm_object_attach_property(mobj, priv->colorkey_prop,
				   0x0101fe);
	drm_object_attach_property(mobj, priv->colorkey_min_prop,
				   0x0101fe);
	drm_object_attach_property(mobj, priv->colorkey_max_prop,
				   0x0101fe);
	drm_object_attach_property(mobj, priv->colorkey_val_prop,
				   0x0101fe);
	drm_object_attach_property(mobj, priv->colorkey_alpha_prop,
				   0x000000);
	drm_object_attach_property(mobj, priv->colorkey_mode_prop,
				   CKMODE_RGB);
	drm_object_attach_property(mobj, priv->brightness_prop,
				   256 + DEFAULT_BRIGHTNESS);
	drm_object_attach_property(mobj, priv->contrast_prop,
				   DEFAULT_CONTRAST);
	drm_object_attach_property(mobj, priv->saturation_prop,
				   DEFAULT_SATURATION);

	ret = drm_plane_create_color_properties(overlay,
						BIT(DRM_COLOR_YCBCR_BT601) |
						BIT(DRM_COLOR_YCBCR_BT709),
						BIT(DRM_COLOR_YCBCR_LIMITED_RANGE),
						DEFAULT_ENCODING,
						DRM_COLOR_YCBCR_LIMITED_RANGE);

	return ret;
}
