brintos

brintos / linux-shallow public Read only

0
0
Text · 20.2 KiB · 3b9bd8e Raw
598 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2012 Russell King4 *  Rewritten from the dovefb driver, and Armada510 manuals.5 */6 7#include <linux/bitfield.h>8 9#include <drm/armada_drm.h>10#include <drm/drm_atomic.h>11#include <drm/drm_atomic_helper.h>12#include <drm/drm_atomic_uapi.h>13#include <drm/drm_fourcc.h>14#include <drm/drm_plane_helper.h>15 16#include "armada_crtc.h"17#include "armada_drm.h"18#include "armada_fb.h"19#include "armada_gem.h"20#include "armada_hw.h"21#include "armada_ioctlP.h"22#include "armada_plane.h"23#include "armada_trace.h"24 25#define DEFAULT_BRIGHTNESS	026#define DEFAULT_CONTRAST	0x400027#define DEFAULT_SATURATION	0x400028#define DEFAULT_ENCODING	DRM_COLOR_YCBCR_BT60129 30struct armada_overlay_state {31	struct armada_plane_state base;32	u32 colorkey_yr;33	u32 colorkey_ug;34	u32 colorkey_vb;35	u32 colorkey_mode;36	u32 colorkey_enable;37	s16 brightness;38	u16 contrast;39	u16 saturation;40};41#define drm_to_overlay_state(s) \42	container_of(s, struct armada_overlay_state, base.base)43 44static inline u32 armada_spu_contrast(struct drm_plane_state *state)45{46	return drm_to_overlay_state(state)->brightness << 16 |47	       drm_to_overlay_state(state)->contrast;48}49 50static inline u32 armada_spu_saturation(struct drm_plane_state *state)51{52	/* Docs say 15:0, but it seems to actually be 31:16 on Armada 510 */53	return drm_to_overlay_state(state)->saturation << 16;54}55 56static inline u32 armada_csc(struct drm_plane_state *state)57{58	/*59	 * The CFG_CSC_RGB_* settings control the output of the colour space60	 * converter, setting the range of output values it produces.  Since61	 * we will be blending with the full-range graphics, we need to62	 * produce full-range RGB output from the conversion.63	 */64	return CFG_CSC_RGB_COMPUTER |65	       (state->color_encoding == DRM_COLOR_YCBCR_BT709 ?66			CFG_CSC_YUV_CCIR709 : CFG_CSC_YUV_CCIR601);67}68 69/* === Plane support === */70static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane,71	struct drm_atomic_state *state)72{73	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,74									   plane);75	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,76									   plane);77	struct armada_crtc *dcrtc;78	struct armada_regs *regs;79	unsigned int idx;80	u32 cfg, cfg_mask, val;81 82	DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name);83 84	if (!new_state->fb || WARN_ON(!new_state->crtc))85		return;86 87	DRM_DEBUG_KMS("[PLANE:%d:%s] is on [CRTC:%d:%s] with [FB:%d] visible %u->%u\n",88		plane->base.id, plane->name,89		new_state->crtc->base.id, new_state->crtc->name,90		new_state->fb->base.id,91		old_state->visible, new_state->visible);92 93	dcrtc = drm_to_armada_crtc(new_state->crtc);94	regs = dcrtc->regs + dcrtc->regs_idx;95 96	idx = 0;97	if (!old_state->visible && new_state->visible)98		armada_reg_queue_mod(regs, idx,99				     0, CFG_PDWN16x66 | CFG_PDWN32x66,100				     LCD_SPU_SRAM_PARA1);101	val = armada_src_hw(new_state);102	if (armada_src_hw(old_state) != val)103		armada_reg_queue_set(regs, idx, val, LCD_SPU_DMA_HPXL_VLN);104	val = armada_dst_yx(new_state);105	if (armada_dst_yx(old_state) != val)106		armada_reg_queue_set(regs, idx, val, LCD_SPU_DMA_OVSA_HPXL_VLN);107	val = armada_dst_hw(new_state);108	if (armada_dst_hw(old_state) != val)109		armada_reg_queue_set(regs, idx, val, LCD_SPU_DZM_HPXL_VLN);110	/* FIXME: overlay on an interlaced display */111	if (old_state->src.x1 != new_state->src.x1 ||112	    old_state->src.y1 != new_state->src.y1 ||113	    old_state->fb != new_state->fb ||114	    new_state->crtc->state->mode_changed) {115		const struct drm_format_info *format;116		u16 src_x;117 118		armada_reg_queue_set(regs, idx, armada_addr(new_state, 0, 0),119				     LCD_SPU_DMA_START_ADDR_Y0);120		armada_reg_queue_set(regs, idx, armada_addr(new_state, 0, 1),121				     LCD_SPU_DMA_START_ADDR_U0);122		armada_reg_queue_set(regs, idx, armada_addr(new_state, 0, 2),123				     LCD_SPU_DMA_START_ADDR_V0);124		armada_reg_queue_set(regs, idx, armada_addr(new_state, 1, 0),125				     LCD_SPU_DMA_START_ADDR_Y1);126		armada_reg_queue_set(regs, idx, armada_addr(new_state, 1, 1),127				     LCD_SPU_DMA_START_ADDR_U1);128		armada_reg_queue_set(regs, idx, armada_addr(new_state, 1, 2),129				     LCD_SPU_DMA_START_ADDR_V1);130 131		val = armada_pitch(new_state, 0) << 16 | armada_pitch(new_state,132								      0);133		armada_reg_queue_set(regs, idx, val, LCD_SPU_DMA_PITCH_YC);134		val = armada_pitch(new_state, 1) << 16 | armada_pitch(new_state,135								      2);136		armada_reg_queue_set(regs, idx, val, LCD_SPU_DMA_PITCH_UV);137 138		cfg = CFG_DMA_FMT(drm_fb_to_armada_fb(new_state->fb)->fmt) |139		      CFG_DMA_MOD(drm_fb_to_armada_fb(new_state->fb)->mod) |140		      CFG_CBSH_ENA;141		if (new_state->visible)142			cfg |= CFG_DMA_ENA;143 144		/*145		 * Shifting a YUV packed format image by one pixel causes the146		 * U/V planes to swap.  Compensate for it by also toggling147		 * the UV swap.148		 */149		format = new_state->fb->format;150		src_x = new_state->src.x1 >> 16;151		if (format->num_planes == 1 && src_x & (format->hsub - 1))152			cfg ^= CFG_DMA_MOD(CFG_SWAPUV);153		if (to_armada_plane_state(new_state)->interlace)154			cfg |= CFG_DMA_FTOGGLE;155		cfg_mask = CFG_CBSH_ENA | CFG_DMAFORMAT |156			   CFG_DMA_MOD(CFG_SWAPRB | CFG_SWAPUV |157				       CFG_SWAPYU | CFG_YUV2RGB) |158			   CFG_DMA_FTOGGLE | CFG_DMA_TSTMODE |159			   CFG_DMA_ENA;160	} else if (old_state->visible != new_state->visible) {161		cfg = new_state->visible ? CFG_DMA_ENA : 0;162		cfg_mask = CFG_DMA_ENA;163	} else {164		cfg = cfg_mask = 0;165	}166	if (drm_rect_width(&old_state->src) != drm_rect_width(&new_state->src) ||167	    drm_rect_width(&old_state->dst) != drm_rect_width(&new_state->dst)) {168		cfg_mask |= CFG_DMA_HSMOOTH;169		if (drm_rect_width(&new_state->src) >> 16 !=170		    drm_rect_width(&new_state->dst))171			cfg |= CFG_DMA_HSMOOTH;172	}173 174	if (cfg_mask)175		armada_reg_queue_mod(regs, idx, cfg, cfg_mask,176				     LCD_SPU_DMA_CTRL0);177 178	val = armada_spu_contrast(new_state);179	if ((!old_state->visible && new_state->visible) ||180	    armada_spu_contrast(old_state) != val)181		armada_reg_queue_set(regs, idx, val, LCD_SPU_CONTRAST);182	val = armada_spu_saturation(new_state);183	if ((!old_state->visible && new_state->visible) ||184	    armada_spu_saturation(old_state) != val)185		armada_reg_queue_set(regs, idx, val, LCD_SPU_SATURATION);186	if (!old_state->visible && new_state->visible)187		armada_reg_queue_set(regs, idx, 0x00002000, LCD_SPU_CBSH_HUE);188	val = armada_csc(new_state);189	if ((!old_state->visible && new_state->visible) ||190	    armada_csc(old_state) != val)191		armada_reg_queue_mod(regs, idx, val, CFG_CSC_MASK,192				     LCD_SPU_IOPAD_CONTROL);193	val = drm_to_overlay_state(new_state)->colorkey_yr;194	if ((!old_state->visible && new_state->visible) ||195	    drm_to_overlay_state(old_state)->colorkey_yr != val)196		armada_reg_queue_set(regs, idx, val, LCD_SPU_COLORKEY_Y);197	val = drm_to_overlay_state(new_state)->colorkey_ug;198	if ((!old_state->visible && new_state->visible) ||199	    drm_to_overlay_state(old_state)->colorkey_ug != val)200		armada_reg_queue_set(regs, idx, val, LCD_SPU_COLORKEY_U);201	val = drm_to_overlay_state(new_state)->colorkey_vb;202	if ((!old_state->visible && new_state->visible) ||203	    drm_to_overlay_state(old_state)->colorkey_vb != val)204		armada_reg_queue_set(regs, idx, val, LCD_SPU_COLORKEY_V);205	val = drm_to_overlay_state(new_state)->colorkey_mode;206	if ((!old_state->visible && new_state->visible) ||207	    drm_to_overlay_state(old_state)->colorkey_mode != val)208		armada_reg_queue_mod(regs, idx, val, CFG_CKMODE_MASK |209				     CFG_ALPHAM_MASK | CFG_ALPHA_MASK,210				     LCD_SPU_DMA_CTRL1);211	val = drm_to_overlay_state(new_state)->colorkey_enable;212	if (((!old_state->visible && new_state->visible) ||213	     drm_to_overlay_state(old_state)->colorkey_enable != val) &&214	    dcrtc->variant->has_spu_adv_reg)215		armada_reg_queue_mod(regs, idx, val, ADV_GRACOLORKEY |216				     ADV_VIDCOLORKEY, LCD_SPU_ADV_REG);217 218	dcrtc->regs_idx += idx;219}220 221static void armada_drm_overlay_plane_atomic_disable(struct drm_plane *plane,222	struct drm_atomic_state *state)223{224	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,225									   plane);226	struct armada_crtc *dcrtc;227	struct armada_regs *regs;228	unsigned int idx = 0;229 230	DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name);231 232	if (!old_state->crtc)233		return;234 235	DRM_DEBUG_KMS("[PLANE:%d:%s] was on [CRTC:%d:%s] with [FB:%d]\n",236		plane->base.id, plane->name,237		old_state->crtc->base.id, old_state->crtc->name,238		old_state->fb->base.id);239 240	dcrtc = drm_to_armada_crtc(old_state->crtc);241	regs = dcrtc->regs + dcrtc->regs_idx;242 243	/* Disable plane and power down the YUV FIFOs */244	armada_reg_queue_mod(regs, idx, 0, CFG_DMA_ENA, LCD_SPU_DMA_CTRL0);245	armada_reg_queue_mod(regs, idx, CFG_PDWN16x66 | CFG_PDWN32x66, 0,246			     LCD_SPU_SRAM_PARA1);247 248	dcrtc->regs_idx += idx;249}250 251static const struct drm_plane_helper_funcs armada_overlay_plane_helper_funcs = {252	.atomic_check	= armada_drm_plane_atomic_check,253	.atomic_update	= armada_drm_overlay_plane_atomic_update,254	.atomic_disable	= armada_drm_overlay_plane_atomic_disable,255};256 257static int258armada_overlay_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,259	struct drm_framebuffer *fb,260	int crtc_x, int crtc_y, unsigned crtc_w, unsigned crtc_h,261	uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h,262	struct drm_modeset_acquire_ctx *ctx)263{264	struct drm_atomic_state *state;265	struct drm_plane_state *plane_state;266	int ret = 0;267 268	trace_armada_ovl_plane_update(plane, crtc, fb,269				 crtc_x, crtc_y, crtc_w, crtc_h,270				 src_x, src_y, src_w, src_h);271 272	state = drm_atomic_state_alloc(plane->dev);273	if (!state)274		return -ENOMEM;275 276	state->acquire_ctx = ctx;277	plane_state = drm_atomic_get_plane_state(state, plane);278	if (IS_ERR(plane_state)) {279		ret = PTR_ERR(plane_state);280		goto fail;281	}282 283	ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);284	if (ret != 0)285		goto fail;286 287	drm_atomic_set_fb_for_plane(plane_state, fb);288	plane_state->crtc_x = crtc_x;289	plane_state->crtc_y = crtc_y;290	plane_state->crtc_h = crtc_h;291	plane_state->crtc_w = crtc_w;292	plane_state->src_x = src_x;293	plane_state->src_y = src_y;294	plane_state->src_h = src_h;295	plane_state->src_w = src_w;296 297	ret = drm_atomic_nonblocking_commit(state);298fail:299	drm_atomic_state_put(state);300	return ret;301}302 303static void armada_overlay_reset(struct drm_plane *plane)304{305	struct armada_overlay_state *state;306 307	if (plane->state)308		__drm_atomic_helper_plane_destroy_state(plane->state);309	kfree(plane->state);310	plane->state = NULL;311 312	state = kzalloc(sizeof(*state), GFP_KERNEL);313	if (state) {314		state->colorkey_yr = 0xfefefe00;315		state->colorkey_ug = 0x01010100;316		state->colorkey_vb = 0x01010100;317		state->colorkey_mode = CFG_CKMODE(CKMODE_RGB) |318				       CFG_ALPHAM_GRA | CFG_ALPHA(0);319		state->colorkey_enable = ADV_GRACOLORKEY;320		state->brightness = DEFAULT_BRIGHTNESS;321		state->contrast = DEFAULT_CONTRAST;322		state->saturation = DEFAULT_SATURATION;323		__drm_atomic_helper_plane_reset(plane, &state->base.base);324		state->base.base.color_encoding = DEFAULT_ENCODING;325		state->base.base.color_range = DRM_COLOR_YCBCR_LIMITED_RANGE;326	}327}328 329static struct drm_plane_state *330armada_overlay_duplicate_state(struct drm_plane *plane)331{332	struct armada_overlay_state *state;333 334	if (WARN_ON(!plane->state))335		return NULL;336 337	state = kmemdup(plane->state, sizeof(*state), GFP_KERNEL);338	if (state)339		__drm_atomic_helper_plane_duplicate_state(plane,340							  &state->base.base);341	return &state->base.base;342}343 344static int armada_overlay_set_property(struct drm_plane *plane,345	struct drm_plane_state *state, struct drm_property *property,346	uint64_t val)347{348	struct armada_private *priv = drm_to_armada_dev(plane->dev);349 350#define K2R(val) (((val) >> 0) & 0xff)351#define K2G(val) (((val) >> 8) & 0xff)352#define K2B(val) (((val) >> 16) & 0xff)353	if (property == priv->colorkey_prop) {354#define CCC(v) ((v) << 24 | (v) << 16 | (v) << 8)355		drm_to_overlay_state(state)->colorkey_yr = CCC(K2R(val));356		drm_to_overlay_state(state)->colorkey_ug = CCC(K2G(val));357		drm_to_overlay_state(state)->colorkey_vb = CCC(K2B(val));358#undef CCC359	} else if (property == priv->colorkey_min_prop) {360		drm_to_overlay_state(state)->colorkey_yr &= ~0x00ff0000;361		drm_to_overlay_state(state)->colorkey_yr |= K2R(val) << 16;362		drm_to_overlay_state(state)->colorkey_ug &= ~0x00ff0000;363		drm_to_overlay_state(state)->colorkey_ug |= K2G(val) << 16;364		drm_to_overlay_state(state)->colorkey_vb &= ~0x00ff0000;365		drm_to_overlay_state(state)->colorkey_vb |= K2B(val) << 16;366	} else if (property == priv->colorkey_max_prop) {367		drm_to_overlay_state(state)->colorkey_yr &= ~0xff000000;368		drm_to_overlay_state(state)->colorkey_yr |= K2R(val) << 24;369		drm_to_overlay_state(state)->colorkey_ug &= ~0xff000000;370		drm_to_overlay_state(state)->colorkey_ug |= K2G(val) << 24;371		drm_to_overlay_state(state)->colorkey_vb &= ~0xff000000;372		drm_to_overlay_state(state)->colorkey_vb |= K2B(val) << 24;373	} else if (property == priv->colorkey_val_prop) {374		drm_to_overlay_state(state)->colorkey_yr &= ~0x0000ff00;375		drm_to_overlay_state(state)->colorkey_yr |= K2R(val) << 8;376		drm_to_overlay_state(state)->colorkey_ug &= ~0x0000ff00;377		drm_to_overlay_state(state)->colorkey_ug |= K2G(val) << 8;378		drm_to_overlay_state(state)->colorkey_vb &= ~0x0000ff00;379		drm_to_overlay_state(state)->colorkey_vb |= K2B(val) << 8;380	} else if (property == priv->colorkey_alpha_prop) {381		drm_to_overlay_state(state)->colorkey_yr &= ~0x000000ff;382		drm_to_overlay_state(state)->colorkey_yr |= K2R(val);383		drm_to_overlay_state(state)->colorkey_ug &= ~0x000000ff;384		drm_to_overlay_state(state)->colorkey_ug |= K2G(val);385		drm_to_overlay_state(state)->colorkey_vb &= ~0x000000ff;386		drm_to_overlay_state(state)->colorkey_vb |= K2B(val);387	} else if (property == priv->colorkey_mode_prop) {388		if (val == CKMODE_DISABLE) {389			drm_to_overlay_state(state)->colorkey_mode =390				CFG_CKMODE(CKMODE_DISABLE) |391				CFG_ALPHAM_CFG | CFG_ALPHA(255);392			drm_to_overlay_state(state)->colorkey_enable = 0;393		} else {394			drm_to_overlay_state(state)->colorkey_mode =395				CFG_CKMODE(val) |396				CFG_ALPHAM_GRA | CFG_ALPHA(0);397			drm_to_overlay_state(state)->colorkey_enable =398				ADV_GRACOLORKEY;399		}400	} else if (property == priv->brightness_prop) {401		drm_to_overlay_state(state)->brightness = val - 256;402	} else if (property == priv->contrast_prop) {403		drm_to_overlay_state(state)->contrast = val;404	} else if (property == priv->saturation_prop) {405		drm_to_overlay_state(state)->saturation = val;406	} else {407		return -EINVAL;408	}409	return 0;410}411 412static int armada_overlay_get_property(struct drm_plane *plane,413	const struct drm_plane_state *state, struct drm_property *property,414	uint64_t *val)415{416	struct armada_private *priv = drm_to_armada_dev(plane->dev);417 418#define C2K(c,s)	(((c) >> (s)) & 0xff)419#define R2BGR(r,g,b,s)	(C2K(r,s) << 0 | C2K(g,s) << 8 | C2K(b,s) << 16)420	if (property == priv->colorkey_prop) {421		/* Do best-efforts here for this property */422		*val = R2BGR(drm_to_overlay_state(state)->colorkey_yr,423			     drm_to_overlay_state(state)->colorkey_ug,424			     drm_to_overlay_state(state)->colorkey_vb, 16);425		/* If min != max, or min != val, error out */426		if (*val != R2BGR(drm_to_overlay_state(state)->colorkey_yr,427				  drm_to_overlay_state(state)->colorkey_ug,428				  drm_to_overlay_state(state)->colorkey_vb, 24) ||429		    *val != R2BGR(drm_to_overlay_state(state)->colorkey_yr,430				  drm_to_overlay_state(state)->colorkey_ug,431				  drm_to_overlay_state(state)->colorkey_vb, 8))432			return -EINVAL;433	} else if (property == priv->colorkey_min_prop) {434		*val = R2BGR(drm_to_overlay_state(state)->colorkey_yr,435			     drm_to_overlay_state(state)->colorkey_ug,436			     drm_to_overlay_state(state)->colorkey_vb, 16);437	} else if (property == priv->colorkey_max_prop) {438		*val = R2BGR(drm_to_overlay_state(state)->colorkey_yr,439			     drm_to_overlay_state(state)->colorkey_ug,440			     drm_to_overlay_state(state)->colorkey_vb, 24);441	} else if (property == priv->colorkey_val_prop) {442		*val = R2BGR(drm_to_overlay_state(state)->colorkey_yr,443			     drm_to_overlay_state(state)->colorkey_ug,444			     drm_to_overlay_state(state)->colorkey_vb, 8);445	} else if (property == priv->colorkey_alpha_prop) {446		*val = R2BGR(drm_to_overlay_state(state)->colorkey_yr,447			     drm_to_overlay_state(state)->colorkey_ug,448			     drm_to_overlay_state(state)->colorkey_vb, 0);449	} else if (property == priv->colorkey_mode_prop) {450		*val = FIELD_GET(CFG_CKMODE_MASK,451				 drm_to_overlay_state(state)->colorkey_mode);452	} else if (property == priv->brightness_prop) {453		*val = drm_to_overlay_state(state)->brightness + 256;454	} else if (property == priv->contrast_prop) {455		*val = drm_to_overlay_state(state)->contrast;456	} else if (property == priv->saturation_prop) {457		*val = drm_to_overlay_state(state)->saturation;458	} else {459		return -EINVAL;460	}461	return 0;462}463 464static const struct drm_plane_funcs armada_ovl_plane_funcs = {465	.update_plane	= armada_overlay_plane_update,466	.disable_plane	= drm_atomic_helper_disable_plane,467	.destroy	= drm_plane_helper_destroy,468	.reset		= armada_overlay_reset,469	.atomic_duplicate_state = armada_overlay_duplicate_state,470	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,471	.atomic_set_property = armada_overlay_set_property,472	.atomic_get_property = armada_overlay_get_property,473};474 475static const uint32_t armada_ovl_formats[] = {476	DRM_FORMAT_UYVY,477	DRM_FORMAT_YUYV,478	DRM_FORMAT_YUV420,479	DRM_FORMAT_YVU420,480	DRM_FORMAT_YUV422,481	DRM_FORMAT_YVU422,482	DRM_FORMAT_VYUY,483	DRM_FORMAT_YVYU,484	DRM_FORMAT_ARGB8888,485	DRM_FORMAT_ABGR8888,486	DRM_FORMAT_XRGB8888,487	DRM_FORMAT_XBGR8888,488	DRM_FORMAT_RGB888,489	DRM_FORMAT_BGR888,490	DRM_FORMAT_ARGB1555,491	DRM_FORMAT_ABGR1555,492	DRM_FORMAT_RGB565,493	DRM_FORMAT_BGR565,494};495 496static const struct drm_prop_enum_list armada_drm_colorkey_enum_list[] = {497	{ CKMODE_DISABLE, "disabled" },498	{ CKMODE_Y,       "Y component" },499	{ CKMODE_U,       "U component" },500	{ CKMODE_V,       "V component" },501	{ CKMODE_RGB,     "RGB" },502	{ CKMODE_R,       "R component" },503	{ CKMODE_G,       "G component" },504	{ CKMODE_B,       "B component" },505};506 507static int armada_overlay_create_properties(struct drm_device *dev)508{509	struct armada_private *priv = drm_to_armada_dev(dev);510 511	if (priv->colorkey_prop)512		return 0;513 514	priv->colorkey_prop = drm_property_create_range(dev, 0,515				"colorkey", 0, 0xffffff);516	priv->colorkey_min_prop = drm_property_create_range(dev, 0,517				"colorkey_min", 0, 0xffffff);518	priv->colorkey_max_prop = drm_property_create_range(dev, 0,519				"colorkey_max", 0, 0xffffff);520	priv->colorkey_val_prop = drm_property_create_range(dev, 0,521				"colorkey_val", 0, 0xffffff);522	priv->colorkey_alpha_prop = drm_property_create_range(dev, 0,523				"colorkey_alpha", 0, 0xffffff);524	priv->colorkey_mode_prop = drm_property_create_enum(dev, 0,525				"colorkey_mode",526				armada_drm_colorkey_enum_list,527				ARRAY_SIZE(armada_drm_colorkey_enum_list));528	priv->brightness_prop = drm_property_create_range(dev, 0,529				"brightness", 0, 256 + 255);530	priv->contrast_prop = drm_property_create_range(dev, 0,531				"contrast", 0, 0x7fff);532	priv->saturation_prop = drm_property_create_range(dev, 0,533				"saturation", 0, 0x7fff);534 535	if (!priv->colorkey_prop)536		return -ENOMEM;537 538	return 0;539}540 541int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)542{543	struct armada_private *priv = drm_to_armada_dev(dev);544	struct drm_mode_object *mobj;545	struct drm_plane *overlay;546	int ret;547 548	ret = armada_overlay_create_properties(dev);549	if (ret)550		return ret;551 552	overlay = kzalloc(sizeof(*overlay), GFP_KERNEL);553	if (!overlay)554		return -ENOMEM;555 556	drm_plane_helper_add(overlay, &armada_overlay_plane_helper_funcs);557 558	ret = drm_universal_plane_init(dev, overlay, crtcs,559				       &armada_ovl_plane_funcs,560				       armada_ovl_formats,561				       ARRAY_SIZE(armada_ovl_formats),562				       NULL,563				       DRM_PLANE_TYPE_OVERLAY, NULL);564	if (ret) {565		kfree(overlay);566		return ret;567	}568 569	mobj = &overlay->base;570	drm_object_attach_property(mobj, priv->colorkey_prop,571				   0x0101fe);572	drm_object_attach_property(mobj, priv->colorkey_min_prop,573				   0x0101fe);574	drm_object_attach_property(mobj, priv->colorkey_max_prop,575				   0x0101fe);576	drm_object_attach_property(mobj, priv->colorkey_val_prop,577				   0x0101fe);578	drm_object_attach_property(mobj, priv->colorkey_alpha_prop,579				   0x000000);580	drm_object_attach_property(mobj, priv->colorkey_mode_prop,581				   CKMODE_RGB);582	drm_object_attach_property(mobj, priv->brightness_prop,583				   256 + DEFAULT_BRIGHTNESS);584	drm_object_attach_property(mobj, priv->contrast_prop,585				   DEFAULT_CONTRAST);586	drm_object_attach_property(mobj, priv->saturation_prop,587				   DEFAULT_SATURATION);588 589	ret = drm_plane_create_color_properties(overlay,590						BIT(DRM_COLOR_YCBCR_BT601) |591						BIT(DRM_COLOR_YCBCR_BT709),592						BIT(DRM_COLOR_YCBCR_LIMITED_RANGE),593						DEFAULT_ENCODING,594						DRM_COLOR_YCBCR_LIMITED_RANGE);595 596	return ret;597}598