1caab277bSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
28bb0daffSRob Clark /*
31b409fdaSAlexander A. Klimov  * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/
48bb0daffSRob Clark  * Author: Rob Clark <rob.clark@linaro.org>
58bb0daffSRob Clark  */
68bb0daffSRob Clark 
7c423bc85STomi Valkeinen #include <drm/drm_atomic.h>
869a12263SLaurent Pinchart #include <drm/drm_atomic_helper.h>
9942d8344SDaniel Vetter #include <drm/drm_gem_atomic_helper.h>
10de8e4100SLaurent Pinchart #include <drm/drm_plane_helper.h>
1169a12263SLaurent Pinchart 
128bb0daffSRob Clark #include "omap_dmm_tiler.h"
132d278f54SLaurent Pinchart #include "omap_drv.h"
148bb0daffSRob Clark 
158bb0daffSRob Clark /*
168bb0daffSRob Clark  * plane funcs
178bb0daffSRob Clark  */
188bb0daffSRob Clark 
198bb0daffSRob Clark #define to_omap_plane(x) container_of(x, struct omap_plane, base)
208bb0daffSRob Clark 
218bb0daffSRob Clark struct omap_plane {
228bb0daffSRob Clark 	struct drm_plane base;
23694c99cfSJyri Sarha 	enum omap_plane_id id;
24*c8fa1e73SBenoit Parrot 
25*c8fa1e73SBenoit Parrot 	struct omap_hw_overlay *overlay;
268bb0daffSRob Clark };
278bb0daffSRob Clark 
2811ffd031STomi Valkeinen static int omap_plane_prepare_fb(struct drm_plane *plane,
291832040dSChris Wilson 				 struct drm_plane_state *new_state)
3011ffd031STomi Valkeinen {
31844f9111SMaarten Lankhorst 	if (!new_state->fb)
32844f9111SMaarten Lankhorst 		return 0;
33844f9111SMaarten Lankhorst 
34942d8344SDaniel Vetter 	drm_gem_plane_helper_prepare_fb(plane, new_state);
35942d8344SDaniel Vetter 
36844f9111SMaarten Lankhorst 	return omap_framebuffer_pin(new_state->fb);
3711ffd031STomi Valkeinen }
3811ffd031STomi Valkeinen 
3911ffd031STomi Valkeinen static void omap_plane_cleanup_fb(struct drm_plane *plane,
401832040dSChris Wilson 				  struct drm_plane_state *old_state)
4111ffd031STomi Valkeinen {
42844f9111SMaarten Lankhorst 	if (old_state->fb)
43844f9111SMaarten Lankhorst 		omap_framebuffer_unpin(old_state->fb);
4411ffd031STomi Valkeinen }
4511ffd031STomi Valkeinen 
4611ffd031STomi Valkeinen static void omap_plane_atomic_update(struct drm_plane *plane,
47977697e2SMaxime Ripard 				     struct drm_atomic_state *state)
48afc34932SLaurent Pinchart {
499f759225STomi Valkeinen 	struct omap_drm_private *priv = plane->dev->dev_private;
50edc72557SLaurent Pinchart 	struct omap_plane *omap_plane = to_omap_plane(plane);
5137418bf1SMaxime Ripard 	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
5237418bf1SMaxime Ripard 									   plane);
53*c8fa1e73SBenoit Parrot 	enum omap_plane_id ovl_id = omap_plane->overlay->id;
54fb730c9bSLaurent Pinchart 	struct omap_overlay_info info;
558bb0daffSRob Clark 	int ret;
568bb0daffSRob Clark 
57*c8fa1e73SBenoit Parrot 	DBG("%s, crtc=%p fb=%p", plane->name, new_state->crtc,
5841016fe1SMaxime Ripard 	    new_state->fb);
598bb0daffSRob Clark 
60fb730c9bSLaurent Pinchart 	memset(&info, 0, sizeof(info));
61517a8a95STomi Valkeinen 	info.rotation_type = OMAP_DSS_ROT_NONE;
620bd97c42STomi Valkeinen 	info.rotation = DRM_MODE_ROTATE_0;
6341016fe1SMaxime Ripard 	info.global_alpha = new_state->alpha >> 8;
6441016fe1SMaxime Ripard 	info.zorder = new_state->normalized_zpos;
6541016fe1SMaxime Ripard 	if (new_state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
663037e0c5SJean-Jacques Hiblot 		info.pre_mult_alpha = 1;
673037e0c5SJean-Jacques Hiblot 	else
683037e0c5SJean-Jacques Hiblot 		info.pre_mult_alpha = 0;
6941016fe1SMaxime Ripard 	info.color_encoding = new_state->color_encoding;
7041016fe1SMaxime Ripard 	info.color_range = new_state->color_range;
71fb730c9bSLaurent Pinchart 
728bb0daffSRob Clark 	/* update scanout: */
7341016fe1SMaxime Ripard 	omap_framebuffer_update_scanout(new_state->fb, new_state, &info);
748bb0daffSRob Clark 
75fb730c9bSLaurent Pinchart 	DBG("%dx%d -> %dx%d (%d)", info.width, info.height,
76fb730c9bSLaurent Pinchart 			info.out_width, info.out_height,
77fb730c9bSLaurent Pinchart 			info.screen_width);
78fb730c9bSLaurent Pinchart 	DBG("%d,%d %pad %pad", info.pos_x, info.pos_y,
79fb730c9bSLaurent Pinchart 			&info.paddr, &info.p_uv_addr);
808bb0daffSRob Clark 
818bb0daffSRob Clark 	/* and finally, update omapdss: */
82*c8fa1e73SBenoit Parrot 	ret = dispc_ovl_setup(priv->dispc, ovl_id, &info,
8341016fe1SMaxime Ripard 			      omap_crtc_timings(new_state->crtc), false,
8441016fe1SMaxime Ripard 			      omap_crtc_channel(new_state->crtc));
85cfb73f20STomi Valkeinen 	if (ret) {
86cfb73f20STomi Valkeinen 		dev_err(plane->dev->dev, "Failed to setup plane %s\n",
87*c8fa1e73SBenoit Parrot 			plane->name);
88*c8fa1e73SBenoit Parrot 		dispc_ovl_enable(priv->dispc, ovl_id, false);
89d9157dfdSTomi Valkeinen 		return;
90794a65ffSTomi Valkeinen 	}
918bb0daffSRob Clark 
92*c8fa1e73SBenoit Parrot 	dispc_ovl_enable(priv->dispc, ovl_id, true);
93de8e4100SLaurent Pinchart }
94de8e4100SLaurent Pinchart 
95de8e4100SLaurent Pinchart static void omap_plane_atomic_disable(struct drm_plane *plane,
96977697e2SMaxime Ripard 				      struct drm_atomic_state *state)
978bb0daffSRob Clark {
9837418bf1SMaxime Ripard 	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
9937418bf1SMaxime Ripard 									   plane);
1009f759225STomi Valkeinen 	struct omap_drm_private *priv = plane->dev->dev_private;
1018bb0daffSRob Clark 	struct omap_plane *omap_plane = to_omap_plane(plane);
102*c8fa1e73SBenoit Parrot 	enum omap_plane_id ovl_id = omap_plane->overlay->id;
1032debab97SLaurent Pinchart 
104e05162c0SMaxime Ripard 	new_state->rotation = DRM_MODE_ROTATE_0;
105e05162c0SMaxime Ripard 	new_state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : omap_plane->id;
10682e58855SLaurent Pinchart 
107*c8fa1e73SBenoit Parrot 	dispc_ovl_enable(priv->dispc, ovl_id, false);
1088bb0daffSRob Clark }
1098bb0daffSRob Clark 
110c21134b0SNeil Armstrong #define FRAC_16_16(mult, div)    (((mult) << 16) / (div))
111c21134b0SNeil Armstrong 
112c423bc85STomi Valkeinen static int omap_plane_atomic_check(struct drm_plane *plane,
1137c11b99aSMaxime Ripard 				   struct drm_atomic_state *state)
114c423bc85STomi Valkeinen {
1157c11b99aSMaxime Ripard 	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
1167c11b99aSMaxime Ripard 										 plane);
117d484c20dSBenoit Parrot 	struct omap_drm_private *priv = plane->dev->dev_private;
118c423bc85STomi Valkeinen 	struct drm_crtc_state *crtc_state;
119d484c20dSBenoit Parrot 	u32 max_width, max_height;
120d484c20dSBenoit Parrot 	u16 width, height;
121c21134b0SNeil Armstrong 	int ret;
122c423bc85STomi Valkeinen 
123ba5c1649SMaxime Ripard 	if (!new_plane_state->fb)
124c423bc85STomi Valkeinen 		return 0;
125c423bc85STomi Valkeinen 
126d484c20dSBenoit Parrot 	dispc_ovl_get_max_size(priv->dispc, &width, &height);
127d484c20dSBenoit Parrot 	max_width = width << 16;
128d484c20dSBenoit Parrot 	max_height = height << 16;
129d484c20dSBenoit Parrot 
130ba5c1649SMaxime Ripard 	/* crtc should only be NULL when disabling (i.e., !new_plane_state->fb) */
131ba5c1649SMaxime Ripard 	if (WARN_ON(!new_plane_state->crtc))
13270dd2a62STomi Valkeinen 		return 0;
13370dd2a62STomi Valkeinen 
134dec92020SMaxime Ripard 	crtc_state = drm_atomic_get_existing_crtc_state(state,
135ba5c1649SMaxime Ripard 							new_plane_state->crtc);
13670dd2a62STomi Valkeinen 	/* we should have a crtc state if the plane is attached to a crtc */
13770dd2a62STomi Valkeinen 	if (WARN_ON(!crtc_state))
13870dd2a62STomi Valkeinen 		return 0;
139c423bc85STomi Valkeinen 
140aaf7642eSTomi Valkeinen 	if (!crtc_state->enable)
141aaf7642eSTomi Valkeinen 		return 0;
142aaf7642eSTomi Valkeinen 
143c21134b0SNeil Armstrong 	/*
144c21134b0SNeil Armstrong 	 * Note: these are just sanity checks to filter out totally bad scaling
145c21134b0SNeil Armstrong 	 * factors. The real limits must be calculated case by case, and
146c21134b0SNeil Armstrong 	 * unfortunately we currently do those checks only at the commit
147c21134b0SNeil Armstrong 	 * phase in dispc.
148c21134b0SNeil Armstrong 	 */
149c21134b0SNeil Armstrong 	ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
150c21134b0SNeil Armstrong 						  FRAC_16_16(1, 8), FRAC_16_16(8, 1),
151c21134b0SNeil Armstrong 						  true, true);
152c21134b0SNeil Armstrong 	if (ret)
153c21134b0SNeil Armstrong 		return ret;
154c21134b0SNeil Armstrong 
155ba5c1649SMaxime Ripard 	if (new_plane_state->crtc_x < 0 || new_plane_state->crtc_y < 0)
156c423bc85STomi Valkeinen 		return -EINVAL;
157c423bc85STomi Valkeinen 
158ba5c1649SMaxime Ripard 	if (new_plane_state->crtc_x + new_plane_state->crtc_w > crtc_state->adjusted_mode.hdisplay)
159c423bc85STomi Valkeinen 		return -EINVAL;
160c423bc85STomi Valkeinen 
161ba5c1649SMaxime Ripard 	if (new_plane_state->crtc_y + new_plane_state->crtc_h > crtc_state->adjusted_mode.vdisplay)
162c423bc85STomi Valkeinen 		return -EINVAL;
163c423bc85STomi Valkeinen 
164d484c20dSBenoit Parrot 	/* Make sure dimensions are within bounds. */
165d484c20dSBenoit Parrot 	if (new_plane_state->src_h > max_height || new_plane_state->crtc_h > height)
166d484c20dSBenoit Parrot 		return -EINVAL;
167d484c20dSBenoit Parrot 
168d484c20dSBenoit Parrot 	if (new_plane_state->src_w > max_width || new_plane_state->crtc_w > width)
169d484c20dSBenoit Parrot 		return -EINVAL;
170d484c20dSBenoit Parrot 
171ba5c1649SMaxime Ripard 	if (new_plane_state->rotation != DRM_MODE_ROTATE_0 &&
172ba5c1649SMaxime Ripard 	    !omap_framebuffer_supports_rotation(new_plane_state->fb))
173bfeece55STomi Valkeinen 		return -EINVAL;
174bfeece55STomi Valkeinen 
175c423bc85STomi Valkeinen 	return 0;
176c423bc85STomi Valkeinen }
177c423bc85STomi Valkeinen 
178de8e4100SLaurent Pinchart static const struct drm_plane_helper_funcs omap_plane_helper_funcs = {
179de8e4100SLaurent Pinchart 	.prepare_fb = omap_plane_prepare_fb,
180de8e4100SLaurent Pinchart 	.cleanup_fb = omap_plane_cleanup_fb,
181c423bc85STomi Valkeinen 	.atomic_check = omap_plane_atomic_check,
182de8e4100SLaurent Pinchart 	.atomic_update = omap_plane_atomic_update,
183de8e4100SLaurent Pinchart 	.atomic_disable = omap_plane_atomic_disable,
184de8e4100SLaurent Pinchart };
185de8e4100SLaurent Pinchart 
1868bb0daffSRob Clark static void omap_plane_destroy(struct drm_plane *plane)
1878bb0daffSRob Clark {
1888bb0daffSRob Clark 	struct omap_plane *omap_plane = to_omap_plane(plane);
1898bb0daffSRob Clark 
190*c8fa1e73SBenoit Parrot 	DBG("%s", plane->name);
1918bb0daffSRob Clark 
1928bb0daffSRob Clark 	drm_plane_cleanup(plane);
1938bb0daffSRob Clark 
1948bb0daffSRob Clark 	kfree(omap_plane);
1958bb0daffSRob Clark }
1968bb0daffSRob Clark 
1978bb0daffSRob Clark /* helper to install properties which are common to planes and crtcs */
1988bb0daffSRob Clark void omap_plane_install_properties(struct drm_plane *plane,
1998bb0daffSRob Clark 		struct drm_mode_object *obj)
2008bb0daffSRob Clark {
2018bb0daffSRob Clark 	struct drm_device *dev = plane->dev;
2028bb0daffSRob Clark 	struct omap_drm_private *priv = dev->dev_private;
2038bb0daffSRob Clark 
2048bb0daffSRob Clark 	if (priv->has_dmm) {
2050da88db1SVille Syrjälä 		if (!plane->rotation_property)
2060da88db1SVille Syrjälä 			drm_plane_create_rotation_property(plane,
207c2c446adSRobert Foss 							   DRM_MODE_ROTATE_0,
208c2c446adSRobert Foss 							   DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
209c2c446adSRobert Foss 							   DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270 |
210c2c446adSRobert Foss 							   DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y);
211e2cd09b2SLaurent Pinchart 
2120da88db1SVille Syrjälä 		/* Attach the rotation property also to the crtc object */
2130da88db1SVille Syrjälä 		if (plane->rotation_property && obj != &plane->base)
2140da88db1SVille Syrjälä 			drm_object_attach_property(obj, plane->rotation_property,
215c2c446adSRobert Foss 						   DRM_MODE_ROTATE_0);
2168bb0daffSRob Clark 	}
2178bb0daffSRob Clark 
218e2cd09b2SLaurent Pinchart 	drm_object_attach_property(obj, priv->zorder_prop, 0);
2198bb0daffSRob Clark }
2208bb0daffSRob Clark 
221e07323cfSTomi Valkeinen static void omap_plane_reset(struct drm_plane *plane)
222e07323cfSTomi Valkeinen {
223e07323cfSTomi Valkeinen 	struct omap_plane *omap_plane = to_omap_plane(plane);
224e07323cfSTomi Valkeinen 
225d980278bSLaurent Pinchart 	drm_atomic_helper_plane_reset(plane);
226d980278bSLaurent Pinchart 	if (!plane->state)
227e07323cfSTomi Valkeinen 		return;
228e07323cfSTomi Valkeinen 
229e07323cfSTomi Valkeinen 	/*
230ba527c13SLaurent Pinchart 	 * Set the zpos default depending on whether we are a primary or overlay
231e07323cfSTomi Valkeinen 	 * plane.
232e07323cfSTomi Valkeinen 	 */
233d980278bSLaurent Pinchart 	plane->state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY
234e07323cfSTomi Valkeinen 			   ? 0 : omap_plane->id;
23564ff1891SJyri Sarha 	plane->state->color_encoding = DRM_COLOR_YCBCR_BT601;
23664ff1891SJyri Sarha 	plane->state->color_range = DRM_COLOR_YCBCR_FULL_RANGE;
237e07323cfSTomi Valkeinen }
238e07323cfSTomi Valkeinen 
239afc34932SLaurent Pinchart static int omap_plane_atomic_set_property(struct drm_plane *plane,
240afc34932SLaurent Pinchart 					  struct drm_plane_state *state,
241afc34932SLaurent Pinchart 					  struct drm_property *property,
242dfe9cfccSLaurent Pinchart 					  u64 val)
243afc34932SLaurent Pinchart {
244afc34932SLaurent Pinchart 	struct omap_drm_private *priv = plane->dev->dev_private;
245afc34932SLaurent Pinchart 
246afc34932SLaurent Pinchart 	if (property == priv->zorder_prop)
247ba527c13SLaurent Pinchart 		state->zpos = val;
248afc34932SLaurent Pinchart 	else
249afc34932SLaurent Pinchart 		return -EINVAL;
250afc34932SLaurent Pinchart 
251a42133a7SLaurent Pinchart 	return 0;
252afc34932SLaurent Pinchart }
253a42133a7SLaurent Pinchart 
254afc34932SLaurent Pinchart static int omap_plane_atomic_get_property(struct drm_plane *plane,
255afc34932SLaurent Pinchart 					  const struct drm_plane_state *state,
256afc34932SLaurent Pinchart 					  struct drm_property *property,
257dfe9cfccSLaurent Pinchart 					  u64 *val)
258afc34932SLaurent Pinchart {
259afc34932SLaurent Pinchart 	struct omap_drm_private *priv = plane->dev->dev_private;
260a42133a7SLaurent Pinchart 
261afc34932SLaurent Pinchart 	if (property == priv->zorder_prop)
262ba527c13SLaurent Pinchart 		*val = state->zpos;
263afc34932SLaurent Pinchart 	else
264afc34932SLaurent Pinchart 		return -EINVAL;
265afc34932SLaurent Pinchart 
266afc34932SLaurent Pinchart 	return 0;
2678bb0daffSRob Clark }
2688bb0daffSRob Clark 
2698bb0daffSRob Clark static const struct drm_plane_funcs omap_plane_funcs = {
270cef77d40SLaurent Pinchart 	.update_plane = drm_atomic_helper_update_plane,
271cef77d40SLaurent Pinchart 	.disable_plane = drm_atomic_helper_disable_plane,
272afc34932SLaurent Pinchart 	.reset = omap_plane_reset,
2738bb0daffSRob Clark 	.destroy = omap_plane_destroy,
274d980278bSLaurent Pinchart 	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
275d980278bSLaurent Pinchart 	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
276afc34932SLaurent Pinchart 	.atomic_set_property = omap_plane_atomic_set_property,
277afc34932SLaurent Pinchart 	.atomic_get_property = omap_plane_atomic_get_property,
2788bb0daffSRob Clark };
2798bb0daffSRob Clark 
28064ff1891SJyri Sarha static bool omap_plane_supports_yuv(struct drm_plane *plane)
28164ff1891SJyri Sarha {
28264ff1891SJyri Sarha 	struct omap_drm_private *priv = plane->dev->dev_private;
28364ff1891SJyri Sarha 	struct omap_plane *omap_plane = to_omap_plane(plane);
284dac62bcaSTomi Valkeinen 	const u32 *formats = dispc_ovl_get_color_modes(priv->dispc, omap_plane->id);
28564ff1891SJyri Sarha 	u32 i;
28664ff1891SJyri Sarha 
28764ff1891SJyri Sarha 	for (i = 0; formats[i]; i++)
28864ff1891SJyri Sarha 		if (formats[i] == DRM_FORMAT_YUYV ||
28964ff1891SJyri Sarha 		    formats[i] == DRM_FORMAT_UYVY ||
29064ff1891SJyri Sarha 		    formats[i] == DRM_FORMAT_NV12)
29164ff1891SJyri Sarha 			return true;
29264ff1891SJyri Sarha 
29364ff1891SJyri Sarha 	return false;
29464ff1891SJyri Sarha }
29564ff1891SJyri Sarha 
2968bb0daffSRob Clark /* initialize plane */
2978bb0daffSRob Clark struct drm_plane *omap_plane_init(struct drm_device *dev,
298e8e13b15SJyri Sarha 		int idx, enum drm_plane_type type,
299e43f2c33STomi Valkeinen 		u32 possible_crtcs)
3008bb0daffSRob Clark {
3019f759225STomi Valkeinen 	struct omap_drm_private *priv = dev->dev_private;
302dac62bcaSTomi Valkeinen 	unsigned int num_planes = dispc_get_num_ovls(priv->dispc);
303ef6b0e02SLaurent Pinchart 	struct drm_plane *plane;
3048bb0daffSRob Clark 	struct omap_plane *omap_plane;
305ef6b0e02SLaurent Pinchart 	int ret;
306eecad437STomi Valkeinen 	u32 nformats;
307eecad437STomi Valkeinen 	const u32 *formats;
3088bb0daffSRob Clark 
309*c8fa1e73SBenoit Parrot 	if (WARN_ON(idx >= num_planes))
310e8e13b15SJyri Sarha 		return ERR_PTR(-EINVAL);
311e8e13b15SJyri Sarha 
3128bb0daffSRob Clark 	omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL);
313fffddfd6SLinus Torvalds 	if (!omap_plane)
314fb9a35f8SLaurent Pinchart 		return ERR_PTR(-ENOMEM);
3158bb0daffSRob Clark 
316*c8fa1e73SBenoit Parrot 	omap_plane->id = idx;
317*c8fa1e73SBenoit Parrot 	omap_plane->overlay = priv->overlays[idx];
318*c8fa1e73SBenoit Parrot 
319*c8fa1e73SBenoit Parrot 	DBG("%d: type=%d", omap_plane->id, type);
320*c8fa1e73SBenoit Parrot 	DBG("	crtc_mask: 0x%04x", possible_crtcs);
321*c8fa1e73SBenoit Parrot 
322*c8fa1e73SBenoit Parrot 	formats = dispc_ovl_get_color_modes(priv->dispc, omap_plane->overlay->id);
323eecad437STomi Valkeinen 	for (nformats = 0; formats[nformats]; ++nformats)
324eecad437STomi Valkeinen 		;
3258bb0daffSRob Clark 
3268bb0daffSRob Clark 	plane = &omap_plane->base;
3278bb0daffSRob Clark 
328e43f2c33STomi Valkeinen 	ret = drm_universal_plane_init(dev, plane, possible_crtcs,
329eecad437STomi Valkeinen 				       &omap_plane_funcs, formats,
330e6fc3b68SBen Widawsky 				       nformats, NULL, type, NULL);
331ef6b0e02SLaurent Pinchart 	if (ret < 0)
332ef6b0e02SLaurent Pinchart 		goto error;
3338bb0daffSRob Clark 
334de8e4100SLaurent Pinchart 	drm_plane_helper_add(plane, &omap_plane_helper_funcs);
335de8e4100SLaurent Pinchart 
3368bb0daffSRob Clark 	omap_plane_install_properties(plane, &plane->base);
337dff6c246SLaurent Pinchart 	drm_plane_create_zpos_property(plane, 0, 0, num_planes - 1);
3383037e0c5SJean-Jacques Hiblot 	drm_plane_create_alpha_property(plane);
3393037e0c5SJean-Jacques Hiblot 	drm_plane_create_blend_mode_property(plane, BIT(DRM_MODE_BLEND_PREMULTI) |
3403037e0c5SJean-Jacques Hiblot 					     BIT(DRM_MODE_BLEND_COVERAGE));
3418bb0daffSRob Clark 
34264ff1891SJyri Sarha 	if (omap_plane_supports_yuv(plane))
34364ff1891SJyri Sarha 		drm_plane_create_color_properties(plane,
34464ff1891SJyri Sarha 						  BIT(DRM_COLOR_YCBCR_BT601) |
34564ff1891SJyri Sarha 						  BIT(DRM_COLOR_YCBCR_BT709),
34664ff1891SJyri Sarha 						  BIT(DRM_COLOR_YCBCR_FULL_RANGE) |
34764ff1891SJyri Sarha 						  BIT(DRM_COLOR_YCBCR_LIMITED_RANGE),
34864ff1891SJyri Sarha 						  DRM_COLOR_YCBCR_BT601,
34964ff1891SJyri Sarha 						  DRM_COLOR_YCBCR_FULL_RANGE);
35064ff1891SJyri Sarha 
3518bb0daffSRob Clark 	return plane;
352ef6b0e02SLaurent Pinchart 
353ef6b0e02SLaurent Pinchart error:
354*c8fa1e73SBenoit Parrot 	dev_err(dev->dev, "%s(): could not create plane: %d\n",
355*c8fa1e73SBenoit Parrot 		__func__, omap_plane->id);
356e8e13b15SJyri Sarha 
357ef6b0e02SLaurent Pinchart 	kfree(omap_plane);
358ef6b0e02SLaurent Pinchart 	return NULL;
3598bb0daffSRob Clark }
360