blob: afa7ded3ae31df68a406da0bba045a6d87f0bce6 [file] [log] [blame]
Russell King96f60e32012-08-15 13:59:49 +01001/*
2 * Copyright (C) 2012 Russell King
3 * Rewritten from the dovefb driver, and Armada510 manuals.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9#include <drm/drmP.h>
Dave Airliebcd21a42018-01-05 09:43:46 +100010#include <drm/drm_atomic_helper.h>
Russell King96f60e32012-08-15 13:59:49 +010011#include "armada_crtc.h"
12#include "armada_drm.h"
13#include "armada_fb.h"
14#include "armada_gem.h"
15#include "armada_hw.h"
16#include <drm/armada_drm.h>
17#include "armada_ioctlP.h"
Russell Kingc8a220c2016-05-17 13:51:08 +010018#include "armada_trace.h"
Russell King96f60e32012-08-15 13:59:49 +010019
Russell King28a2aeb2015-07-15 18:11:23 +010020struct armada_ovl_plane_properties {
Russell King96f60e32012-08-15 13:59:49 +010021 uint32_t colorkey_yr;
22 uint32_t colorkey_ug;
23 uint32_t colorkey_vb;
24#define K2R(val) (((val) >> 0) & 0xff)
25#define K2G(val) (((val) >> 8) & 0xff)
26#define K2B(val) (((val) >> 16) & 0xff)
27 int16_t brightness;
28 uint16_t contrast;
29 uint16_t saturation;
30 uint32_t colorkey_mode;
Russell Kingd3788592018-06-24 14:35:10 +010031 uint32_t colorkey_enable;
Russell King96f60e32012-08-15 13:59:49 +010032};
33
Russell King28a2aeb2015-07-15 18:11:23 +010034struct armada_ovl_plane {
Russell King561f60b2015-07-15 18:11:24 +010035 struct armada_plane base;
Russell King28a2aeb2015-07-15 18:11:23 +010036 struct armada_ovl_plane_properties prop;
Russell King96f60e32012-08-15 13:59:49 +010037};
Russell King561f60b2015-07-15 18:11:24 +010038#define drm_to_armada_ovl_plane(p) \
39 container_of(p, struct armada_ovl_plane, base.base)
Russell King96f60e32012-08-15 13:59:49 +010040
41
42static void
Russell King28a2aeb2015-07-15 18:11:23 +010043armada_ovl_update_attr(struct armada_ovl_plane_properties *prop,
Russell King96f60e32012-08-15 13:59:49 +010044 struct armada_crtc *dcrtc)
45{
46 writel_relaxed(prop->colorkey_yr, dcrtc->base + LCD_SPU_COLORKEY_Y);
47 writel_relaxed(prop->colorkey_ug, dcrtc->base + LCD_SPU_COLORKEY_U);
48 writel_relaxed(prop->colorkey_vb, dcrtc->base + LCD_SPU_COLORKEY_V);
49
50 writel_relaxed(prop->brightness << 16 | prop->contrast,
51 dcrtc->base + LCD_SPU_CONTRAST);
52 /* Docs say 15:0, but it seems to actually be 31:16 on Armada 510 */
53 writel_relaxed(prop->saturation << 16,
54 dcrtc->base + LCD_SPU_SATURATION);
55 writel_relaxed(0x00002000, dcrtc->base + LCD_SPU_CBSH_HUE);
56
57 spin_lock_irq(&dcrtc->irq_lock);
Russell Kingd3788592018-06-24 14:35:10 +010058 armada_updatel(prop->colorkey_mode,
59 CFG_CKMODE_MASK | CFG_ALPHAM_MASK | CFG_ALPHA_MASK,
60 dcrtc->base + LCD_SPU_DMA_CTRL1);
61 if (dcrtc->variant->has_spu_adv_reg)
62 armada_updatel(prop->colorkey_enable,
63 ADV_GRACOLORKEY | ADV_VIDCOLORKEY,
64 dcrtc->base + LCD_SPU_ADV_REG);
Russell King96f60e32012-08-15 13:59:49 +010065 spin_unlock_irq(&dcrtc->irq_lock);
66}
67
68/* === Plane support === */
Russell King4a8506d2015-08-07 09:33:05 +010069static void armada_ovl_plane_work(struct armada_crtc *dcrtc,
Russell Kingeaab0132017-07-07 15:55:53 +010070 struct armada_plane_work *work)
Russell King96f60e32012-08-15 13:59:49 +010071{
Russell Kinga3f6a182017-07-08 10:16:48 +010072 unsigned long flags;
Russell King96f60e32012-08-15 13:59:49 +010073
Russell Kingeaab0132017-07-07 15:55:53 +010074 trace_armada_ovl_plane_work(&dcrtc->crtc, work->plane);
Russell Kingc8a220c2016-05-17 13:51:08 +010075
Russell Kinga3f6a182017-07-08 10:16:48 +010076 spin_lock_irqsave(&dcrtc->irq_lock, flags);
Russell Kingeaa66272017-07-08 10:22:10 +010077 armada_drm_crtc_update_regs(dcrtc, work->regs);
Russell Kinga3f6a182017-07-08 10:16:48 +010078 spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
Russell King96f60e32012-08-15 13:59:49 +010079}
80
Russell King65843e9a2017-07-08 10:22:33 +010081static void armada_ovl_plane_update_state(struct drm_plane_state *state,
82 struct armada_regs *regs)
83{
84 struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(state->plane);
85 struct armada_framebuffer *dfb = drm_fb_to_armada_fb(state->fb);
86 const struct drm_format_info *format;
87 unsigned int idx = 0;
88 bool fb_changed;
89 u32 val, ctrl0;
90 u16 src_x, src_y;
91
92 ctrl0 = CFG_DMA_FMT(dfb->fmt) | CFG_DMA_MOD(dfb->mod) | CFG_CBSH_ENA;
93 if (state->visible)
94 ctrl0 |= CFG_DMA_ENA;
95 if (drm_rect_width(&state->src) >> 16 != drm_rect_width(&state->dst))
96 ctrl0 |= CFG_DMA_HSMOOTH;
97
98 /*
99 * Shifting a YUV packed format image by one pixel causes the U/V
100 * planes to swap. Compensate for it by also toggling the UV swap.
101 */
102 format = dfb->fb.format;
103 if (format->num_planes == 1 && state->src.x1 >> 16 & (format->hsub - 1))
104 ctrl0 ^= CFG_DMA_MOD(CFG_SWAPUV);
105
106 if (~dplane->base.state.ctrl0 & ctrl0 & CFG_DMA_ENA) {
107 /* Power up the Y/U/V FIFOs on ENA 0->1 transitions */
108 armada_reg_queue_mod(regs, idx,
109 0, CFG_PDWN16x66 | CFG_PDWN32x66,
110 LCD_SPU_SRAM_PARA1);
111 }
112
113 fb_changed = dplane->base.base.fb != &dfb->fb ||
114 dplane->base.state.src_x != state->src.x1 >> 16 ||
115 dplane->base.state.src_y != state->src.y1 >> 16;
116
117 dplane->base.state.vsync_update = fb_changed;
118
119 /* FIXME: overlay on an interlaced display */
120 if (fb_changed) {
121 u32 addrs[3];
122
123 dplane->base.state.src_y = src_y = state->src.y1 >> 16;
124 dplane->base.state.src_x = src_x = state->src.x1 >> 16;
125
126 armada_drm_plane_calc_addrs(addrs, &dfb->fb, src_x, src_y);
127
128 armada_reg_queue_set(regs, idx, addrs[0],
129 LCD_SPU_DMA_START_ADDR_Y0);
130 armada_reg_queue_set(regs, idx, addrs[1],
131 LCD_SPU_DMA_START_ADDR_U0);
132 armada_reg_queue_set(regs, idx, addrs[2],
133 LCD_SPU_DMA_START_ADDR_V0);
134 armada_reg_queue_set(regs, idx, addrs[0],
135 LCD_SPU_DMA_START_ADDR_Y1);
136 armada_reg_queue_set(regs, idx, addrs[1],
137 LCD_SPU_DMA_START_ADDR_U1);
138 armada_reg_queue_set(regs, idx, addrs[2],
139 LCD_SPU_DMA_START_ADDR_V1);
140
141 val = dfb->fb.pitches[0] << 16 | dfb->fb.pitches[0];
142 armada_reg_queue_set(regs, idx, val,
143 LCD_SPU_DMA_PITCH_YC);
144 val = dfb->fb.pitches[1] << 16 | dfb->fb.pitches[2];
145 armada_reg_queue_set(regs, idx, val,
146 LCD_SPU_DMA_PITCH_UV);
147 }
148
149 val = (drm_rect_height(&state->src) & 0xffff0000) |
150 drm_rect_width(&state->src) >> 16;
151 if (dplane->base.state.src_hw != val) {
152 dplane->base.state.src_hw = val;
153 armada_reg_queue_set(regs, idx, val,
154 LCD_SPU_DMA_HPXL_VLN);
155 }
156
157 val = drm_rect_height(&state->dst) << 16 | drm_rect_width(&state->dst);
158 if (dplane->base.state.dst_hw != val) {
159 dplane->base.state.dst_hw = val;
160 armada_reg_queue_set(regs, idx, val,
161 LCD_SPU_DZM_HPXL_VLN);
162 }
163
164 val = state->dst.y1 << 16 | state->dst.x1;
165 if (dplane->base.state.dst_yx != val) {
166 dplane->base.state.dst_yx = val;
167 armada_reg_queue_set(regs, idx, val,
168 LCD_SPU_DMA_OVSA_HPXL_VLN);
169 }
170
171 if (dplane->base.state.ctrl0 != ctrl0) {
172 dplane->base.state.ctrl0 = ctrl0;
173 armada_reg_queue_mod(regs, idx, ctrl0,
174 CFG_CBSH_ENA | CFG_DMAFORMAT | CFG_DMA_FTOGGLE |
175 CFG_DMA_HSMOOTH | CFG_DMA_TSTMODE |
176 CFG_DMA_MOD(CFG_SWAPRB | CFG_SWAPUV | CFG_SWAPYU |
177 CFG_YUV2RGB) | CFG_DMA_ENA,
178 LCD_SPU_DMA_CTRL0);
179 dplane->base.state.vsync_update = true;
180 }
181
182 dplane->base.state.changed = idx != 0;
183
184 armada_reg_queue_end(regs, idx);
Russell King96f60e32012-08-15 13:59:49 +0100185}
186
Russell King96f60e32012-08-15 13:59:49 +0100187static int
Russell King28a2aeb2015-07-15 18:11:23 +0100188armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
Russell King96f60e32012-08-15 13:59:49 +0100189 struct drm_framebuffer *fb,
190 int crtc_x, int crtc_y, unsigned crtc_w, unsigned crtc_h,
Daniel Vetter34a2ab52017-03-22 22:50:41 +0100191 uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h,
192 struct drm_modeset_acquire_ctx *ctx)
Russell King96f60e32012-08-15 13:59:49 +0100193{
Russell King28a2aeb2015-07-15 18:11:23 +0100194 struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
Russell King96f60e32012-08-15 13:59:49 +0100195 struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
Russell Kingd9241552017-07-08 10:22:25 +0100196 struct armada_plane_work *work;
Russell King7bfab1e2017-07-08 10:22:20 +0100197 struct drm_plane_state state = {
198 .plane = plane,
199 .crtc = crtc,
200 .fb = fb,
201 .src_x = src_x,
202 .src_y = src_y,
203 .src_w = src_w,
204 .src_h = src_h,
205 .crtc_x = crtc_x,
206 .crtc_y = crtc_y,
207 .crtc_w = crtc_w,
208 .crtc_h = crtc_h,
209 .rotation = DRM_MODE_ROTATE_0,
Russell King98fb74f2015-06-15 10:17:57 +0100210 };
Ville Syrjälä57270b82018-01-23 19:08:55 +0200211 struct drm_crtc_state crtc_state = {
212 .crtc = crtc,
213 .enable = crtc->enabled,
Ville Syrjälä81af63a2018-01-23 19:08:57 +0200214 .mode = crtc->mode,
Ville Syrjälä57270b82018-01-23 19:08:55 +0200215 };
Russell King96f60e32012-08-15 13:59:49 +0100216 int ret;
217
Russell Kingc8a220c2016-05-17 13:51:08 +0100218 trace_armada_ovl_plane_update(plane, crtc, fb,
219 crtc_x, crtc_y, crtc_w, crtc_h,
220 src_x, src_y, src_w, src_h);
221
Ville Syrjälä81af63a2018-01-23 19:08:57 +0200222 ret = drm_atomic_helper_check_plane_state(&state, &crtc_state, 0,
Dave Airliebcd21a42018-01-05 09:43:46 +1000223 INT_MAX, true, false);
Russell King98fb74f2015-06-15 10:17:57 +0100224 if (ret)
225 return ret;
226
Russell Kingd9241552017-07-08 10:22:25 +0100227 work = &dplane->base.works[dplane->base.next_work];
Russell King96f60e32012-08-15 13:59:49 +0100228
Russell King65843e9a2017-07-08 10:22:33 +0100229 if (plane->fb != fb) {
Russell King96f60e32012-08-15 13:59:49 +0100230 /*
231 * Take a reference on the new framebuffer - we want to
232 * hold on to it while the hardware is displaying it.
233 */
Russell King65843e9a2017-07-08 10:22:33 +0100234 drm_framebuffer_reference(fb);
Russell King96f60e32012-08-15 13:59:49 +0100235
Russell Kingeaa66272017-07-08 10:22:10 +0100236 work->old_fb = plane->fb;
Russell Kingb972a802017-07-08 10:16:52 +0100237 } else {
Russell Kingeaa66272017-07-08 10:22:10 +0100238 work->old_fb = NULL;
Russell King96f60e32012-08-15 13:59:49 +0100239 }
240
Russell King65843e9a2017-07-08 10:22:33 +0100241 armada_ovl_plane_update_state(&state, work->regs);
Russell King98fb74f2015-06-15 10:17:57 +0100242
Russell King65843e9a2017-07-08 10:22:33 +0100243 if (!dplane->base.state.changed)
244 return 0;
Russell Kingd19f6ee2017-07-08 10:22:31 +0100245
Russell King07da3c72017-07-08 10:22:34 +0100246 /* Wait for pending work to complete */
247 if (armada_drm_plane_work_wait(&dplane->base, HZ / 25) == 0)
248 armada_drm_plane_work_cancel(dcrtc, &dplane->base);
249
Russell Kingd19f6ee2017-07-08 10:22:31 +0100250 /* Just updating the position/size? */
Russell King65843e9a2017-07-08 10:22:33 +0100251 if (!dplane->base.state.vsync_update) {
Russell Kingd19f6ee2017-07-08 10:22:31 +0100252 armada_ovl_plane_work(dcrtc, work);
253 return 0;
254 }
Russell King96f60e32012-08-15 13:59:49 +0100255
256 if (!dcrtc->plane) {
257 dcrtc->plane = plane;
258 armada_ovl_update_attr(&dplane->prop, dcrtc);
259 }
260
Russell King65843e9a2017-07-08 10:22:33 +0100261 /* Queue it for update on the next interrupt if we are enabled */
262 ret = armada_drm_plane_work_queue(dcrtc, work);
263 if (ret)
264 DRM_ERROR("failed to queue plane work: %d\n", ret);
Russell King96f60e32012-08-15 13:59:49 +0100265
Russell King65843e9a2017-07-08 10:22:33 +0100266 dplane->base.next_work = !dplane->base.next_work;
Russell King96f60e32012-08-15 13:59:49 +0100267
268 return 0;
269}
270
Russell King28a2aeb2015-07-15 18:11:23 +0100271static void armada_ovl_plane_destroy(struct drm_plane *plane)
Russell King96f60e32012-08-15 13:59:49 +0100272{
Russell King28a2aeb2015-07-15 18:11:23 +0100273 struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
Russell King41dbb2d2015-06-15 10:13:30 +0100274
275 drm_plane_cleanup(plane);
276
277 kfree(dplane);
Russell King96f60e32012-08-15 13:59:49 +0100278}
279
Russell King28a2aeb2015-07-15 18:11:23 +0100280static int armada_ovl_plane_set_property(struct drm_plane *plane,
Russell King96f60e32012-08-15 13:59:49 +0100281 struct drm_property *property, uint64_t val)
282{
283 struct armada_private *priv = plane->dev->dev_private;
Russell King28a2aeb2015-07-15 18:11:23 +0100284 struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
Russell King96f60e32012-08-15 13:59:49 +0100285 bool update_attr = false;
286
287 if (property == priv->colorkey_prop) {
288#define CCC(v) ((v) << 24 | (v) << 16 | (v) << 8)
289 dplane->prop.colorkey_yr = CCC(K2R(val));
290 dplane->prop.colorkey_ug = CCC(K2G(val));
291 dplane->prop.colorkey_vb = CCC(K2B(val));
292#undef CCC
293 update_attr = true;
294 } else if (property == priv->colorkey_min_prop) {
295 dplane->prop.colorkey_yr &= ~0x00ff0000;
296 dplane->prop.colorkey_yr |= K2R(val) << 16;
297 dplane->prop.colorkey_ug &= ~0x00ff0000;
298 dplane->prop.colorkey_ug |= K2G(val) << 16;
299 dplane->prop.colorkey_vb &= ~0x00ff0000;
300 dplane->prop.colorkey_vb |= K2B(val) << 16;
301 update_attr = true;
302 } else if (property == priv->colorkey_max_prop) {
303 dplane->prop.colorkey_yr &= ~0xff000000;
304 dplane->prop.colorkey_yr |= K2R(val) << 24;
305 dplane->prop.colorkey_ug &= ~0xff000000;
306 dplane->prop.colorkey_ug |= K2G(val) << 24;
307 dplane->prop.colorkey_vb &= ~0xff000000;
308 dplane->prop.colorkey_vb |= K2B(val) << 24;
309 update_attr = true;
310 } else if (property == priv->colorkey_val_prop) {
311 dplane->prop.colorkey_yr &= ~0x0000ff00;
312 dplane->prop.colorkey_yr |= K2R(val) << 8;
313 dplane->prop.colorkey_ug &= ~0x0000ff00;
314 dplane->prop.colorkey_ug |= K2G(val) << 8;
315 dplane->prop.colorkey_vb &= ~0x0000ff00;
316 dplane->prop.colorkey_vb |= K2B(val) << 8;
317 update_attr = true;
318 } else if (property == priv->colorkey_alpha_prop) {
319 dplane->prop.colorkey_yr &= ~0x000000ff;
320 dplane->prop.colorkey_yr |= K2R(val);
321 dplane->prop.colorkey_ug &= ~0x000000ff;
322 dplane->prop.colorkey_ug |= K2G(val);
323 dplane->prop.colorkey_vb &= ~0x000000ff;
324 dplane->prop.colorkey_vb |= K2B(val);
325 update_attr = true;
326 } else if (property == priv->colorkey_mode_prop) {
Russell Kingd3788592018-06-24 14:35:10 +0100327 if (val == CKMODE_DISABLE) {
328 dplane->prop.colorkey_mode =
329 CFG_CKMODE(CKMODE_DISABLE) |
330 CFG_ALPHAM_CFG | CFG_ALPHA(255);
331 dplane->prop.colorkey_enable = 0;
332 } else {
333 dplane->prop.colorkey_mode =
334 CFG_CKMODE(val) |
335 CFG_ALPHAM_GRA | CFG_ALPHA(0);
336 dplane->prop.colorkey_enable = ADV_GRACOLORKEY;
337 }
Russell King96f60e32012-08-15 13:59:49 +0100338 update_attr = true;
339 } else if (property == priv->brightness_prop) {
340 dplane->prop.brightness = val - 256;
341 update_attr = true;
342 } else if (property == priv->contrast_prop) {
343 dplane->prop.contrast = val;
344 update_attr = true;
345 } else if (property == priv->saturation_prop) {
346 dplane->prop.saturation = val;
347 update_attr = true;
348 }
349
Russell King561f60b2015-07-15 18:11:24 +0100350 if (update_attr && dplane->base.base.crtc)
Russell King96f60e32012-08-15 13:59:49 +0100351 armada_ovl_update_attr(&dplane->prop,
Russell King561f60b2015-07-15 18:11:24 +0100352 drm_to_armada_crtc(dplane->base.base.crtc));
Russell King96f60e32012-08-15 13:59:49 +0100353
354 return 0;
355}
356
Russell King28a2aeb2015-07-15 18:11:23 +0100357static const struct drm_plane_funcs armada_ovl_plane_funcs = {
358 .update_plane = armada_ovl_plane_update,
Russell King890ca8d2017-07-08 10:22:27 +0100359 .disable_plane = armada_drm_plane_disable,
Russell King28a2aeb2015-07-15 18:11:23 +0100360 .destroy = armada_ovl_plane_destroy,
361 .set_property = armada_ovl_plane_set_property,
Russell King96f60e32012-08-15 13:59:49 +0100362};
363
Russell King28a2aeb2015-07-15 18:11:23 +0100364static const uint32_t armada_ovl_formats[] = {
Russell King96f60e32012-08-15 13:59:49 +0100365 DRM_FORMAT_UYVY,
366 DRM_FORMAT_YUYV,
367 DRM_FORMAT_YUV420,
368 DRM_FORMAT_YVU420,
369 DRM_FORMAT_YUV422,
370 DRM_FORMAT_YVU422,
371 DRM_FORMAT_VYUY,
372 DRM_FORMAT_YVYU,
373 DRM_FORMAT_ARGB8888,
374 DRM_FORMAT_ABGR8888,
375 DRM_FORMAT_XRGB8888,
376 DRM_FORMAT_XBGR8888,
377 DRM_FORMAT_RGB888,
378 DRM_FORMAT_BGR888,
379 DRM_FORMAT_ARGB1555,
380 DRM_FORMAT_ABGR1555,
381 DRM_FORMAT_RGB565,
382 DRM_FORMAT_BGR565,
383};
384
Arvind Yadav8a63ca52017-07-01 16:24:42 +0530385static const struct drm_prop_enum_list armada_drm_colorkey_enum_list[] = {
Russell King96f60e32012-08-15 13:59:49 +0100386 { CKMODE_DISABLE, "disabled" },
387 { CKMODE_Y, "Y component" },
388 { CKMODE_U, "U component" },
389 { CKMODE_V, "V component" },
390 { CKMODE_RGB, "RGB" },
391 { CKMODE_R, "R component" },
392 { CKMODE_G, "G component" },
393 { CKMODE_B, "B component" },
394};
395
396static int armada_overlay_create_properties(struct drm_device *dev)
397{
398 struct armada_private *priv = dev->dev_private;
399
400 if (priv->colorkey_prop)
401 return 0;
402
403 priv->colorkey_prop = drm_property_create_range(dev, 0,
404 "colorkey", 0, 0xffffff);
405 priv->colorkey_min_prop = drm_property_create_range(dev, 0,
406 "colorkey_min", 0, 0xffffff);
407 priv->colorkey_max_prop = drm_property_create_range(dev, 0,
408 "colorkey_max", 0, 0xffffff);
409 priv->colorkey_val_prop = drm_property_create_range(dev, 0,
410 "colorkey_val", 0, 0xffffff);
411 priv->colorkey_alpha_prop = drm_property_create_range(dev, 0,
412 "colorkey_alpha", 0, 0xffffff);
413 priv->colorkey_mode_prop = drm_property_create_enum(dev, 0,
414 "colorkey_mode",
415 armada_drm_colorkey_enum_list,
416 ARRAY_SIZE(armada_drm_colorkey_enum_list));
417 priv->brightness_prop = drm_property_create_range(dev, 0,
418 "brightness", 0, 256 + 255);
419 priv->contrast_prop = drm_property_create_range(dev, 0,
420 "contrast", 0, 0x7fff);
421 priv->saturation_prop = drm_property_create_range(dev, 0,
422 "saturation", 0, 0x7fff);
423
424 if (!priv->colorkey_prop)
425 return -ENOMEM;
426
427 return 0;
428}
429
430int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
431{
432 struct armada_private *priv = dev->dev_private;
433 struct drm_mode_object *mobj;
Russell King28a2aeb2015-07-15 18:11:23 +0100434 struct armada_ovl_plane *dplane;
Russell King96f60e32012-08-15 13:59:49 +0100435 int ret;
436
437 ret = armada_overlay_create_properties(dev);
438 if (ret)
439 return ret;
440
441 dplane = kzalloc(sizeof(*dplane), GFP_KERNEL);
442 if (!dplane)
443 return -ENOMEM;
444
Russell King5740d272015-07-15 18:11:25 +0100445 ret = armada_drm_plane_init(&dplane->base);
446 if (ret) {
447 kfree(dplane);
448 return ret;
449 }
450
Russell Kingd9241552017-07-08 10:22:25 +0100451 dplane->base.works[0].fn = armada_ovl_plane_work;
452 dplane->base.works[1].fn = armada_ovl_plane_work;
Russell King96f60e32012-08-15 13:59:49 +0100453
Russell King561f60b2015-07-15 18:11:24 +0100454 ret = drm_universal_plane_init(dev, &dplane->base.base, crtcs,
Russell Kingd563c242015-07-15 18:11:24 +0100455 &armada_ovl_plane_funcs,
456 armada_ovl_formats,
457 ARRAY_SIZE(armada_ovl_formats),
Ben Widawskye6fc3b62017-07-23 20:46:38 -0700458 NULL,
Ville Syrjäläb0b3b792015-12-09 16:19:55 +0200459 DRM_PLANE_TYPE_OVERLAY, NULL);
Russell King28a2aeb2015-07-15 18:11:23 +0100460 if (ret) {
461 kfree(dplane);
462 return ret;
463 }
Russell King96f60e32012-08-15 13:59:49 +0100464
465 dplane->prop.colorkey_yr = 0xfefefe00;
466 dplane->prop.colorkey_ug = 0x01010100;
467 dplane->prop.colorkey_vb = 0x01010100;
Russell Kingd3788592018-06-24 14:35:10 +0100468 dplane->prop.colorkey_mode = CFG_CKMODE(CKMODE_RGB) |
469 CFG_ALPHAM_GRA | CFG_ALPHA(0);
470 dplane->prop.colorkey_enable = ADV_GRACOLORKEY;
Russell King96f60e32012-08-15 13:59:49 +0100471 dplane->prop.brightness = 0;
472 dplane->prop.contrast = 0x4000;
473 dplane->prop.saturation = 0x4000;
474
Russell King561f60b2015-07-15 18:11:24 +0100475 mobj = &dplane->base.base.base;
Russell King96f60e32012-08-15 13:59:49 +0100476 drm_object_attach_property(mobj, priv->colorkey_prop,
477 0x0101fe);
478 drm_object_attach_property(mobj, priv->colorkey_min_prop,
479 0x0101fe);
480 drm_object_attach_property(mobj, priv->colorkey_max_prop,
481 0x0101fe);
482 drm_object_attach_property(mobj, priv->colorkey_val_prop,
483 0x0101fe);
484 drm_object_attach_property(mobj, priv->colorkey_alpha_prop,
485 0x000000);
486 drm_object_attach_property(mobj, priv->colorkey_mode_prop,
487 CKMODE_RGB);
488 drm_object_attach_property(mobj, priv->brightness_prop, 256);
489 drm_object_attach_property(mobj, priv->contrast_prop,
490 dplane->prop.contrast);
491 drm_object_attach_property(mobj, priv->saturation_prop,
492 dplane->prop.saturation);
493
494 return 0;
495}