1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2012 Russell King
4 * Rewritten from the dovefb driver, and Armada510 manuals.
7 #include <drm/armada_drm.h>
8 #include <drm/drm_atomic.h>
9 #include <drm/drm_atomic_helper.h>
10 #include <drm/drm_atomic_uapi.h>
11 #include <drm/drm_fourcc.h>
12 #include <drm/drm_plane_helper.h>
14 #include "armada_crtc.h"
15 #include "armada_drm.h"
16 #include "armada_fb.h"
17 #include "armada_gem.h"
18 #include "armada_hw.h"
19 #include "armada_ioctlP.h"
20 #include "armada_plane.h"
21 #include "armada_trace.h"
23 #define DEFAULT_BRIGHTNESS 0
24 #define DEFAULT_CONTRAST 0x4000
25 #define DEFAULT_SATURATION 0x4000
26 #define DEFAULT_ENCODING DRM_COLOR_YCBCR_BT601
28 struct armada_overlay_state
{
29 struct armada_plane_state base
;
39 #define drm_to_overlay_state(s) \
40 container_of(s, struct armada_overlay_state, base.base)
42 static inline u32
armada_spu_contrast(struct drm_plane_state
*state
)
44 return drm_to_overlay_state(state
)->brightness
<< 16 |
45 drm_to_overlay_state(state
)->contrast
;
48 static inline u32
armada_spu_saturation(struct drm_plane_state
*state
)
50 /* Docs say 15:0, but it seems to actually be 31:16 on Armada 510 */
51 return drm_to_overlay_state(state
)->saturation
<< 16;
54 static inline u32
armada_csc(struct drm_plane_state
*state
)
57 * The CFG_CSC_RGB_* settings control the output of the colour space
58 * converter, setting the range of output values it produces. Since
59 * we will be blending with the full-range graphics, we need to
60 * produce full-range RGB output from the conversion.
62 return CFG_CSC_RGB_COMPUTER
|
63 (state
->color_encoding
== DRM_COLOR_YCBCR_BT709
?
64 CFG_CSC_YUV_CCIR709
: CFG_CSC_YUV_CCIR601
);
67 /* === Plane support === */
68 static void armada_drm_overlay_plane_atomic_update(struct drm_plane
*plane
,
69 struct drm_plane_state
*old_state
)
71 struct drm_plane_state
*state
= plane
->state
;
72 struct armada_crtc
*dcrtc
;
73 struct armada_regs
*regs
;
75 u32 cfg
, cfg_mask
, val
;
77 DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane
->base
.id
, plane
->name
);
79 if (!state
->fb
|| WARN_ON(!state
->crtc
))
82 DRM_DEBUG_KMS("[PLANE:%d:%s] is on [CRTC:%d:%s] with [FB:%d] visible %u->%u\n",
83 plane
->base
.id
, plane
->name
,
84 state
->crtc
->base
.id
, state
->crtc
->name
,
86 old_state
->visible
, state
->visible
);
88 dcrtc
= drm_to_armada_crtc(state
->crtc
);
89 regs
= dcrtc
->regs
+ dcrtc
->regs_idx
;
92 if (!old_state
->visible
&& state
->visible
)
93 armada_reg_queue_mod(regs
, idx
,
94 0, CFG_PDWN16x66
| CFG_PDWN32x66
,
96 val
= armada_src_hw(state
);
97 if (armada_src_hw(old_state
) != val
)
98 armada_reg_queue_set(regs
, idx
, val
, LCD_SPU_DMA_HPXL_VLN
);
99 val
= armada_dst_yx(state
);
100 if (armada_dst_yx(old_state
) != val
)
101 armada_reg_queue_set(regs
, idx
, val
, LCD_SPU_DMA_OVSA_HPXL_VLN
);
102 val
= armada_dst_hw(state
);
103 if (armada_dst_hw(old_state
) != val
)
104 armada_reg_queue_set(regs
, idx
, val
, LCD_SPU_DZM_HPXL_VLN
);
105 /* FIXME: overlay on an interlaced display */
106 if (old_state
->src
.x1
!= state
->src
.x1
||
107 old_state
->src
.y1
!= state
->src
.y1
||
108 old_state
->fb
!= state
->fb
||
109 state
->crtc
->state
->mode_changed
) {
110 const struct drm_format_info
*format
;
113 armada_reg_queue_set(regs
, idx
, armada_addr(state
, 0, 0),
114 LCD_SPU_DMA_START_ADDR_Y0
);
115 armada_reg_queue_set(regs
, idx
, armada_addr(state
, 0, 1),
116 LCD_SPU_DMA_START_ADDR_U0
);
117 armada_reg_queue_set(regs
, idx
, armada_addr(state
, 0, 2),
118 LCD_SPU_DMA_START_ADDR_V0
);
119 armada_reg_queue_set(regs
, idx
, armada_addr(state
, 1, 0),
120 LCD_SPU_DMA_START_ADDR_Y1
);
121 armada_reg_queue_set(regs
, idx
, armada_addr(state
, 1, 1),
122 LCD_SPU_DMA_START_ADDR_U1
);
123 armada_reg_queue_set(regs
, idx
, armada_addr(state
, 1, 2),
124 LCD_SPU_DMA_START_ADDR_V1
);
126 val
= armada_pitch(state
, 0) << 16 | armada_pitch(state
, 0);
127 armada_reg_queue_set(regs
, idx
, val
, LCD_SPU_DMA_PITCH_YC
);
128 val
= armada_pitch(state
, 1) << 16 | armada_pitch(state
, 2);
129 armada_reg_queue_set(regs
, idx
, val
, LCD_SPU_DMA_PITCH_UV
);
131 cfg
= CFG_DMA_FMT(drm_fb_to_armada_fb(state
->fb
)->fmt
) |
132 CFG_DMA_MOD(drm_fb_to_armada_fb(state
->fb
)->mod
) |
138 * Shifting a YUV packed format image by one pixel causes the
139 * U/V planes to swap. Compensate for it by also toggling
142 format
= state
->fb
->format
;
143 src_x
= state
->src
.x1
>> 16;
144 if (format
->num_planes
== 1 && src_x
& (format
->hsub
- 1))
145 cfg
^= CFG_DMA_MOD(CFG_SWAPUV
);
146 if (to_armada_plane_state(state
)->interlace
)
147 cfg
|= CFG_DMA_FTOGGLE
;
148 cfg_mask
= CFG_CBSH_ENA
| CFG_DMAFORMAT
|
149 CFG_DMA_MOD(CFG_SWAPRB
| CFG_SWAPUV
|
150 CFG_SWAPYU
| CFG_YUV2RGB
) |
151 CFG_DMA_FTOGGLE
| CFG_DMA_TSTMODE
|
153 } else if (old_state
->visible
!= state
->visible
) {
154 cfg
= state
->visible
? CFG_DMA_ENA
: 0;
155 cfg_mask
= CFG_DMA_ENA
;
159 if (drm_rect_width(&old_state
->src
) != drm_rect_width(&state
->src
) ||
160 drm_rect_width(&old_state
->dst
) != drm_rect_width(&state
->dst
)) {
161 cfg_mask
|= CFG_DMA_HSMOOTH
;
162 if (drm_rect_width(&state
->src
) >> 16 !=
163 drm_rect_width(&state
->dst
))
164 cfg
|= CFG_DMA_HSMOOTH
;
168 armada_reg_queue_mod(regs
, idx
, cfg
, cfg_mask
,
171 val
= armada_spu_contrast(state
);
172 if ((!old_state
->visible
&& state
->visible
) ||
173 armada_spu_contrast(old_state
) != val
)
174 armada_reg_queue_set(regs
, idx
, val
, LCD_SPU_CONTRAST
);
175 val
= armada_spu_saturation(state
);
176 if ((!old_state
->visible
&& state
->visible
) ||
177 armada_spu_saturation(old_state
) != val
)
178 armada_reg_queue_set(regs
, idx
, val
, LCD_SPU_SATURATION
);
179 if (!old_state
->visible
&& state
->visible
)
180 armada_reg_queue_set(regs
, idx
, 0x00002000, LCD_SPU_CBSH_HUE
);
181 val
= armada_csc(state
);
182 if ((!old_state
->visible
&& state
->visible
) ||
183 armada_csc(old_state
) != val
)
184 armada_reg_queue_mod(regs
, idx
, val
, CFG_CSC_MASK
,
185 LCD_SPU_IOPAD_CONTROL
);
186 val
= drm_to_overlay_state(state
)->colorkey_yr
;
187 if ((!old_state
->visible
&& state
->visible
) ||
188 drm_to_overlay_state(old_state
)->colorkey_yr
!= val
)
189 armada_reg_queue_set(regs
, idx
, val
, LCD_SPU_COLORKEY_Y
);
190 val
= drm_to_overlay_state(state
)->colorkey_ug
;
191 if ((!old_state
->visible
&& state
->visible
) ||
192 drm_to_overlay_state(old_state
)->colorkey_ug
!= val
)
193 armada_reg_queue_set(regs
, idx
, val
, LCD_SPU_COLORKEY_U
);
194 val
= drm_to_overlay_state(state
)->colorkey_vb
;
195 if ((!old_state
->visible
&& state
->visible
) ||
196 drm_to_overlay_state(old_state
)->colorkey_vb
!= val
)
197 armada_reg_queue_set(regs
, idx
, val
, LCD_SPU_COLORKEY_V
);
198 val
= drm_to_overlay_state(state
)->colorkey_mode
;
199 if ((!old_state
->visible
&& state
->visible
) ||
200 drm_to_overlay_state(old_state
)->colorkey_mode
!= val
)
201 armada_reg_queue_mod(regs
, idx
, val
, CFG_CKMODE_MASK
|
202 CFG_ALPHAM_MASK
| CFG_ALPHA_MASK
,
204 val
= drm_to_overlay_state(state
)->colorkey_enable
;
205 if (((!old_state
->visible
&& state
->visible
) ||
206 drm_to_overlay_state(old_state
)->colorkey_enable
!= val
) &&
207 dcrtc
->variant
->has_spu_adv_reg
)
208 armada_reg_queue_mod(regs
, idx
, val
, ADV_GRACOLORKEY
|
209 ADV_VIDCOLORKEY
, LCD_SPU_ADV_REG
);
211 dcrtc
->regs_idx
+= idx
;
214 static void armada_drm_overlay_plane_atomic_disable(struct drm_plane
*plane
,
215 struct drm_plane_state
*old_state
)
217 struct armada_crtc
*dcrtc
;
218 struct armada_regs
*regs
;
219 unsigned int idx
= 0;
221 DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane
->base
.id
, plane
->name
);
223 if (!old_state
->crtc
)
226 DRM_DEBUG_KMS("[PLANE:%d:%s] was on [CRTC:%d:%s] with [FB:%d]\n",
227 plane
->base
.id
, plane
->name
,
228 old_state
->crtc
->base
.id
, old_state
->crtc
->name
,
229 old_state
->fb
->base
.id
);
231 dcrtc
= drm_to_armada_crtc(old_state
->crtc
);
232 regs
= dcrtc
->regs
+ dcrtc
->regs_idx
;
234 /* Disable plane and power down the YUV FIFOs */
235 armada_reg_queue_mod(regs
, idx
, 0, CFG_DMA_ENA
, LCD_SPU_DMA_CTRL0
);
236 armada_reg_queue_mod(regs
, idx
, CFG_PDWN16x66
| CFG_PDWN32x66
, 0,
239 dcrtc
->regs_idx
+= idx
;
242 static const struct drm_plane_helper_funcs armada_overlay_plane_helper_funcs
= {
243 .prepare_fb
= armada_drm_plane_prepare_fb
,
244 .cleanup_fb
= armada_drm_plane_cleanup_fb
,
245 .atomic_check
= armada_drm_plane_atomic_check
,
246 .atomic_update
= armada_drm_overlay_plane_atomic_update
,
247 .atomic_disable
= armada_drm_overlay_plane_atomic_disable
,
251 armada_overlay_plane_update(struct drm_plane
*plane
, struct drm_crtc
*crtc
,
252 struct drm_framebuffer
*fb
,
253 int crtc_x
, int crtc_y
, unsigned crtc_w
, unsigned crtc_h
,
254 uint32_t src_x
, uint32_t src_y
, uint32_t src_w
, uint32_t src_h
,
255 struct drm_modeset_acquire_ctx
*ctx
)
257 struct drm_atomic_state
*state
;
258 struct drm_plane_state
*plane_state
;
261 trace_armada_ovl_plane_update(plane
, crtc
, fb
,
262 crtc_x
, crtc_y
, crtc_w
, crtc_h
,
263 src_x
, src_y
, src_w
, src_h
);
265 state
= drm_atomic_state_alloc(plane
->dev
);
269 state
->acquire_ctx
= ctx
;
270 plane_state
= drm_atomic_get_plane_state(state
, plane
);
271 if (IS_ERR(plane_state
)) {
272 ret
= PTR_ERR(plane_state
);
276 ret
= drm_atomic_set_crtc_for_plane(plane_state
, crtc
);
280 drm_atomic_set_fb_for_plane(plane_state
, fb
);
281 plane_state
->crtc_x
= crtc_x
;
282 plane_state
->crtc_y
= crtc_y
;
283 plane_state
->crtc_h
= crtc_h
;
284 plane_state
->crtc_w
= crtc_w
;
285 plane_state
->src_x
= src_x
;
286 plane_state
->src_y
= src_y
;
287 plane_state
->src_h
= src_h
;
288 plane_state
->src_w
= src_w
;
290 ret
= drm_atomic_nonblocking_commit(state
);
292 drm_atomic_state_put(state
);
296 static void armada_ovl_plane_destroy(struct drm_plane
*plane
)
298 drm_plane_cleanup(plane
);
302 static void armada_overlay_reset(struct drm_plane
*plane
)
304 struct armada_overlay_state
*state
;
307 __drm_atomic_helper_plane_destroy_state(plane
->state
);
311 state
= kzalloc(sizeof(*state
), GFP_KERNEL
);
313 state
->colorkey_yr
= 0xfefefe00;
314 state
->colorkey_ug
= 0x01010100;
315 state
->colorkey_vb
= 0x01010100;
316 state
->colorkey_mode
= CFG_CKMODE(CKMODE_RGB
) |
317 CFG_ALPHAM_GRA
| CFG_ALPHA(0);
318 state
->colorkey_enable
= ADV_GRACOLORKEY
;
319 state
->brightness
= DEFAULT_BRIGHTNESS
;
320 state
->contrast
= DEFAULT_CONTRAST
;
321 state
->saturation
= DEFAULT_SATURATION
;
322 __drm_atomic_helper_plane_reset(plane
, &state
->base
.base
);
323 state
->base
.base
.color_encoding
= DEFAULT_ENCODING
;
324 state
->base
.base
.color_range
= DRM_COLOR_YCBCR_LIMITED_RANGE
;
328 static struct drm_plane_state
*
329 armada_overlay_duplicate_state(struct drm_plane
*plane
)
331 struct armada_overlay_state
*state
;
333 if (WARN_ON(!plane
->state
))
336 state
= kmemdup(plane
->state
, sizeof(*state
), GFP_KERNEL
);
338 __drm_atomic_helper_plane_duplicate_state(plane
,
340 return &state
->base
.base
;
343 static int armada_overlay_set_property(struct drm_plane
*plane
,
344 struct drm_plane_state
*state
, struct drm_property
*property
,
347 struct armada_private
*priv
= drm_to_armada_dev(plane
->dev
);
349 #define K2R(val) (((val) >> 0) & 0xff)
350 #define K2G(val) (((val) >> 8) & 0xff)
351 #define K2B(val) (((val) >> 16) & 0xff)
352 if (property
== priv
->colorkey_prop
) {
353 #define CCC(v) ((v) << 24 | (v) << 16 | (v) << 8)
354 drm_to_overlay_state(state
)->colorkey_yr
= CCC(K2R(val
));
355 drm_to_overlay_state(state
)->colorkey_ug
= CCC(K2G(val
));
356 drm_to_overlay_state(state
)->colorkey_vb
= CCC(K2B(val
));
358 } else if (property
== priv
->colorkey_min_prop
) {
359 drm_to_overlay_state(state
)->colorkey_yr
&= ~0x00ff0000;
360 drm_to_overlay_state(state
)->colorkey_yr
|= K2R(val
) << 16;
361 drm_to_overlay_state(state
)->colorkey_ug
&= ~0x00ff0000;
362 drm_to_overlay_state(state
)->colorkey_ug
|= K2G(val
) << 16;
363 drm_to_overlay_state(state
)->colorkey_vb
&= ~0x00ff0000;
364 drm_to_overlay_state(state
)->colorkey_vb
|= K2B(val
) << 16;
365 } else if (property
== priv
->colorkey_max_prop
) {
366 drm_to_overlay_state(state
)->colorkey_yr
&= ~0xff000000;
367 drm_to_overlay_state(state
)->colorkey_yr
|= K2R(val
) << 24;
368 drm_to_overlay_state(state
)->colorkey_ug
&= ~0xff000000;
369 drm_to_overlay_state(state
)->colorkey_ug
|= K2G(val
) << 24;
370 drm_to_overlay_state(state
)->colorkey_vb
&= ~0xff000000;
371 drm_to_overlay_state(state
)->colorkey_vb
|= K2B(val
) << 24;
372 } else if (property
== priv
->colorkey_val_prop
) {
373 drm_to_overlay_state(state
)->colorkey_yr
&= ~0x0000ff00;
374 drm_to_overlay_state(state
)->colorkey_yr
|= K2R(val
) << 8;
375 drm_to_overlay_state(state
)->colorkey_ug
&= ~0x0000ff00;
376 drm_to_overlay_state(state
)->colorkey_ug
|= K2G(val
) << 8;
377 drm_to_overlay_state(state
)->colorkey_vb
&= ~0x0000ff00;
378 drm_to_overlay_state(state
)->colorkey_vb
|= K2B(val
) << 8;
379 } else if (property
== priv
->colorkey_alpha_prop
) {
380 drm_to_overlay_state(state
)->colorkey_yr
&= ~0x000000ff;
381 drm_to_overlay_state(state
)->colorkey_yr
|= K2R(val
);
382 drm_to_overlay_state(state
)->colorkey_ug
&= ~0x000000ff;
383 drm_to_overlay_state(state
)->colorkey_ug
|= K2G(val
);
384 drm_to_overlay_state(state
)->colorkey_vb
&= ~0x000000ff;
385 drm_to_overlay_state(state
)->colorkey_vb
|= K2B(val
);
386 } else if (property
== priv
->colorkey_mode_prop
) {
387 if (val
== CKMODE_DISABLE
) {
388 drm_to_overlay_state(state
)->colorkey_mode
=
389 CFG_CKMODE(CKMODE_DISABLE
) |
390 CFG_ALPHAM_CFG
| CFG_ALPHA(255);
391 drm_to_overlay_state(state
)->colorkey_enable
= 0;
393 drm_to_overlay_state(state
)->colorkey_mode
=
395 CFG_ALPHAM_GRA
| CFG_ALPHA(0);
396 drm_to_overlay_state(state
)->colorkey_enable
=
399 } else if (property
== priv
->brightness_prop
) {
400 drm_to_overlay_state(state
)->brightness
= val
- 256;
401 } else if (property
== priv
->contrast_prop
) {
402 drm_to_overlay_state(state
)->contrast
= val
;
403 } else if (property
== priv
->saturation_prop
) {
404 drm_to_overlay_state(state
)->saturation
= val
;
411 static int armada_overlay_get_property(struct drm_plane
*plane
,
412 const struct drm_plane_state
*state
, struct drm_property
*property
,
415 struct armada_private
*priv
= drm_to_armada_dev(plane
->dev
);
417 #define C2K(c,s) (((c) >> (s)) & 0xff)
418 #define R2BGR(r,g,b,s) (C2K(r,s) << 0 | C2K(g,s) << 8 | C2K(b,s) << 16)
419 if (property
== priv
->colorkey_prop
) {
420 /* Do best-efforts here for this property */
421 *val
= R2BGR(drm_to_overlay_state(state
)->colorkey_yr
,
422 drm_to_overlay_state(state
)->colorkey_ug
,
423 drm_to_overlay_state(state
)->colorkey_vb
, 16);
424 /* If min != max, or min != val, error out */
425 if (*val
!= R2BGR(drm_to_overlay_state(state
)->colorkey_yr
,
426 drm_to_overlay_state(state
)->colorkey_ug
,
427 drm_to_overlay_state(state
)->colorkey_vb
, 24) ||
428 *val
!= R2BGR(drm_to_overlay_state(state
)->colorkey_yr
,
429 drm_to_overlay_state(state
)->colorkey_ug
,
430 drm_to_overlay_state(state
)->colorkey_vb
, 8))
432 } else if (property
== priv
->colorkey_min_prop
) {
433 *val
= R2BGR(drm_to_overlay_state(state
)->colorkey_yr
,
434 drm_to_overlay_state(state
)->colorkey_ug
,
435 drm_to_overlay_state(state
)->colorkey_vb
, 16);
436 } else if (property
== priv
->colorkey_max_prop
) {
437 *val
= R2BGR(drm_to_overlay_state(state
)->colorkey_yr
,
438 drm_to_overlay_state(state
)->colorkey_ug
,
439 drm_to_overlay_state(state
)->colorkey_vb
, 24);
440 } else if (property
== priv
->colorkey_val_prop
) {
441 *val
= R2BGR(drm_to_overlay_state(state
)->colorkey_yr
,
442 drm_to_overlay_state(state
)->colorkey_ug
,
443 drm_to_overlay_state(state
)->colorkey_vb
, 8);
444 } else if (property
== priv
->colorkey_alpha_prop
) {
445 *val
= R2BGR(drm_to_overlay_state(state
)->colorkey_yr
,
446 drm_to_overlay_state(state
)->colorkey_ug
,
447 drm_to_overlay_state(state
)->colorkey_vb
, 0);
448 } else if (property
== priv
->colorkey_mode_prop
) {
449 *val
= (drm_to_overlay_state(state
)->colorkey_mode
&
450 CFG_CKMODE_MASK
) >> ffs(CFG_CKMODE_MASK
);
451 } else if (property
== priv
->brightness_prop
) {
452 *val
= drm_to_overlay_state(state
)->brightness
+ 256;
453 } else if (property
== priv
->contrast_prop
) {
454 *val
= drm_to_overlay_state(state
)->contrast
;
455 } else if (property
== priv
->saturation_prop
) {
456 *val
= drm_to_overlay_state(state
)->saturation
;
463 static const struct drm_plane_funcs armada_ovl_plane_funcs
= {
464 .update_plane
= armada_overlay_plane_update
,
465 .disable_plane
= drm_atomic_helper_disable_plane
,
466 .destroy
= armada_ovl_plane_destroy
,
467 .reset
= armada_overlay_reset
,
468 .atomic_duplicate_state
= armada_overlay_duplicate_state
,
469 .atomic_destroy_state
= drm_atomic_helper_plane_destroy_state
,
470 .atomic_set_property
= armada_overlay_set_property
,
471 .atomic_get_property
= armada_overlay_get_property
,
474 static const uint32_t armada_ovl_formats
[] = {
495 static const struct drm_prop_enum_list armada_drm_colorkey_enum_list
[] = {
496 { CKMODE_DISABLE
, "disabled" },
497 { CKMODE_Y
, "Y component" },
498 { CKMODE_U
, "U component" },
499 { CKMODE_V
, "V component" },
500 { CKMODE_RGB
, "RGB" },
501 { CKMODE_R
, "R component" },
502 { CKMODE_G
, "G component" },
503 { CKMODE_B
, "B component" },
506 static int armada_overlay_create_properties(struct drm_device
*dev
)
508 struct armada_private
*priv
= drm_to_armada_dev(dev
);
510 if (priv
->colorkey_prop
)
513 priv
->colorkey_prop
= drm_property_create_range(dev
, 0,
514 "colorkey", 0, 0xffffff);
515 priv
->colorkey_min_prop
= drm_property_create_range(dev
, 0,
516 "colorkey_min", 0, 0xffffff);
517 priv
->colorkey_max_prop
= drm_property_create_range(dev
, 0,
518 "colorkey_max", 0, 0xffffff);
519 priv
->colorkey_val_prop
= drm_property_create_range(dev
, 0,
520 "colorkey_val", 0, 0xffffff);
521 priv
->colorkey_alpha_prop
= drm_property_create_range(dev
, 0,
522 "colorkey_alpha", 0, 0xffffff);
523 priv
->colorkey_mode_prop
= drm_property_create_enum(dev
, 0,
525 armada_drm_colorkey_enum_list
,
526 ARRAY_SIZE(armada_drm_colorkey_enum_list
));
527 priv
->brightness_prop
= drm_property_create_range(dev
, 0,
528 "brightness", 0, 256 + 255);
529 priv
->contrast_prop
= drm_property_create_range(dev
, 0,
530 "contrast", 0, 0x7fff);
531 priv
->saturation_prop
= drm_property_create_range(dev
, 0,
532 "saturation", 0, 0x7fff);
534 if (!priv
->colorkey_prop
)
540 int armada_overlay_plane_create(struct drm_device
*dev
, unsigned long crtcs
)
542 struct armada_private
*priv
= drm_to_armada_dev(dev
);
543 struct drm_mode_object
*mobj
;
544 struct drm_plane
*overlay
;
547 ret
= armada_overlay_create_properties(dev
);
551 overlay
= kzalloc(sizeof(*overlay
), GFP_KERNEL
);
555 drm_plane_helper_add(overlay
, &armada_overlay_plane_helper_funcs
);
557 ret
= drm_universal_plane_init(dev
, overlay
, crtcs
,
558 &armada_ovl_plane_funcs
,
560 ARRAY_SIZE(armada_ovl_formats
),
562 DRM_PLANE_TYPE_OVERLAY
, NULL
);
568 mobj
= &overlay
->base
;
569 drm_object_attach_property(mobj
, priv
->colorkey_prop
,
571 drm_object_attach_property(mobj
, priv
->colorkey_min_prop
,
573 drm_object_attach_property(mobj
, priv
->colorkey_max_prop
,
575 drm_object_attach_property(mobj
, priv
->colorkey_val_prop
,
577 drm_object_attach_property(mobj
, priv
->colorkey_alpha_prop
,
579 drm_object_attach_property(mobj
, priv
->colorkey_mode_prop
,
581 drm_object_attach_property(mobj
, priv
->brightness_prop
,
582 256 + DEFAULT_BRIGHTNESS
);
583 drm_object_attach_property(mobj
, priv
->contrast_prop
,
585 drm_object_attach_property(mobj
, priv
->saturation_prop
,
588 ret
= drm_plane_create_color_properties(overlay
,
589 BIT(DRM_COLOR_YCBCR_BT601
) |
590 BIT(DRM_COLOR_YCBCR_BT709
),
591 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE
),
593 DRM_COLOR_YCBCR_LIMITED_RANGE
);