Commit | Line | Data |
---|---|---|
4bf8e196 LP |
1 | /* |
2 | * rcar_du_plane.c -- R-Car Display Unit Planes | |
3 | * | |
36d50464 | 4 | * Copyright (C) 2013-2014 Renesas Electronics Corporation |
4bf8e196 LP |
5 | * |
6 | * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License as published by | |
10 | * the Free Software Foundation; either version 2 of the License, or | |
11 | * (at your option) any later version. | |
12 | */ | |
13 | ||
14 | #include <drm/drmP.h> | |
3e8da87d | 15 | #include <drm/drm_atomic_helper.h> |
4bf8e196 LP |
16 | #include <drm/drm_crtc.h> |
17 | #include <drm/drm_crtc_helper.h> | |
18 | #include <drm/drm_fb_cma_helper.h> | |
19 | #include <drm/drm_gem_cma_helper.h> | |
920888a2 | 20 | #include <drm/drm_plane_helper.h> |
4bf8e196 LP |
21 | |
22 | #include "rcar_du_drv.h" | |
34a04f2b | 23 | #include "rcar_du_group.h" |
4bf8e196 LP |
24 | #include "rcar_du_kms.h" |
25 | #include "rcar_du_plane.h" | |
26 | #include "rcar_du_regs.h" | |
27 | ||
28 | #define RCAR_DU_COLORKEY_NONE (0 << 24) | |
29 | #define RCAR_DU_COLORKEY_SOURCE (1 << 24) | |
30 | #define RCAR_DU_COLORKEY_MASK (1 << 24) | |
31 | ||
cb2025d2 | 32 | static void rcar_du_plane_write(struct rcar_du_group *rgrp, |
4bf8e196 LP |
33 | unsigned int index, u32 reg, u32 data) |
34 | { | |
cb2025d2 LP |
35 | rcar_du_write(rgrp->dev, rgrp->mmio_offset + index * PLANE_OFF + reg, |
36 | data); | |
4bf8e196 LP |
37 | } |
38 | ||
34a04f2b LP |
39 | static void rcar_du_plane_setup_scanout(struct rcar_du_group *rgrp, |
40 | const struct rcar_du_plane_state *state) | |
4bf8e196 | 41 | { |
5bfcbce0 LP |
42 | unsigned int src_x = state->state.src_x >> 16; |
43 | unsigned int src_y = state->state.src_y >> 16; | |
5ee5a81d | 44 | unsigned int index = state->hwindex; |
2f13c529 | 45 | unsigned int pitch; |
906eff7f | 46 | bool interlaced; |
2f13c529 | 47 | u32 dma[2]; |
eb86301f | 48 | |
5bfcbce0 | 49 | interlaced = state->state.crtc->state->adjusted_mode.flags |
47094194 | 50 | & DRM_MODE_FLAG_INTERLACE; |
906eff7f | 51 | |
34a04f2b LP |
52 | if (state->source == RCAR_DU_PLANE_MEMORY) { |
53 | struct drm_framebuffer *fb = state->state.fb; | |
54 | struct drm_gem_cma_object *gem; | |
55 | unsigned int i; | |
56 | ||
57 | if (state->format->planes == 2) | |
58 | pitch = fb->pitches[0]; | |
59 | else | |
60 | pitch = fb->pitches[0] * 8 / state->format->bpp; | |
eb86301f | 61 | |
34a04f2b LP |
62 | for (i = 0; i < state->format->planes; ++i) { |
63 | gem = drm_fb_cma_get_gem_obj(fb, i); | |
64 | dma[i] = gem->paddr + fb->offsets[i]; | |
65 | } | |
66 | } else { | |
67 | pitch = state->state.src_w >> 16; | |
68 | dma[0] = 0; | |
69 | dma[1] = 0; | |
2f13c529 | 70 | } |
906eff7f | 71 | |
34a04f2b LP |
72 | /* Memory pitch (expressed in pixels). Must be doubled for interlaced |
73 | * operation with 32bpp formats. | |
74 | */ | |
2f13c529 LP |
75 | rcar_du_plane_write(rgrp, index, PnMWR, |
76 | (interlaced && state->format->bpp == 32) ? | |
77 | pitch * 2 : pitch); | |
4bf8e196 | 78 | |
9e7db06d LP |
79 | /* The Y position is expressed in raster line units and must be doubled |
80 | * for 32bpp formats, according to the R8A7790 datasheet. No mention of | |
81 | * doubling the Y position is found in the R8A7779 datasheet, but the | |
82 | * rule seems to apply there as well. | |
83 | * | |
906eff7f LP |
84 | * Despite not being documented, doubling seem not to be needed when |
85 | * operating in interlaced mode. | |
86 | * | |
9e7db06d | 87 | * Similarly, for the second plane, NV12 and NV21 formats seem to |
906eff7f LP |
88 | * require a halved Y position value, in both progressive and interlaced |
89 | * modes. | |
4bf8e196 | 90 | */ |
287bdf03 LP |
91 | rcar_du_plane_write(rgrp, index, PnSPXR, src_x); |
92 | rcar_du_plane_write(rgrp, index, PnSPYR, src_y * | |
5bfcbce0 | 93 | (!interlaced && state->format->bpp == 32 ? 2 : 1)); |
f398f344 | 94 | |
2f13c529 | 95 | rcar_du_plane_write(rgrp, index, PnDSA0R, dma[0]); |
4bf8e196 | 96 | |
5bfcbce0 | 97 | if (state->format->planes == 2) { |
4bf8e196 LP |
98 | index = (index + 1) % 8; |
99 | ||
2f13c529 | 100 | rcar_du_plane_write(rgrp, index, PnMWR, pitch); |
49785e25 | 101 | |
287bdf03 LP |
102 | rcar_du_plane_write(rgrp, index, PnSPXR, src_x); |
103 | rcar_du_plane_write(rgrp, index, PnSPYR, src_y * | |
5bfcbce0 | 104 | (state->format->bpp == 16 ? 2 : 1) / 2); |
eb86301f | 105 | |
2f13c529 | 106 | rcar_du_plane_write(rgrp, index, PnDSA0R, dma[1]); |
4bf8e196 LP |
107 | } |
108 | } | |
109 | ||
34a04f2b LP |
110 | static void rcar_du_plane_setup_mode(struct rcar_du_group *rgrp, |
111 | unsigned int index, | |
112 | const struct rcar_du_plane_state *state) | |
4bf8e196 | 113 | { |
4bf8e196 LP |
114 | u32 colorkey; |
115 | u32 pnmr; | |
116 | ||
117 | /* The PnALPHAR register controls alpha-blending in 16bpp formats | |
118 | * (ARGB1555 and XRGB1555). | |
119 | * | |
120 | * For ARGB, set the alpha value to 0, and enable alpha-blending when | |
121 | * the A bit is 0. This maps A=0 to alpha=0 and A=1 to alpha=255. | |
122 | * | |
123 | * For XRGB, set the alpha value to the plane-wide alpha value and | |
124 | * enable alpha-blending regardless of the X bit value. | |
125 | */ | |
5bfcbce0 | 126 | if (state->format->fourcc != DRM_FORMAT_XRGB1555) |
cb2025d2 | 127 | rcar_du_plane_write(rgrp, index, PnALPHAR, PnALPHAR_ABIT_0); |
4bf8e196 | 128 | else |
cb2025d2 | 129 | rcar_du_plane_write(rgrp, index, PnALPHAR, |
4407cc02 | 130 | PnALPHAR_ABIT_X | state->alpha); |
4bf8e196 | 131 | |
5bfcbce0 | 132 | pnmr = PnMR_BM_MD | state->format->pnmr; |
4bf8e196 LP |
133 | |
134 | /* Disable color keying when requested. YUV formats have the | |
135 | * PnMR_SPIM_TP_OFF bit set in their pnmr field, disabling color keying | |
136 | * automatically. | |
137 | */ | |
4407cc02 | 138 | if ((state->colorkey & RCAR_DU_COLORKEY_MASK) == RCAR_DU_COLORKEY_NONE) |
4bf8e196 LP |
139 | pnmr |= PnMR_SPIM_TP_OFF; |
140 | ||
141 | /* For packed YUV formats we need to select the U/V order. */ | |
5bfcbce0 | 142 | if (state->format->fourcc == DRM_FORMAT_YUYV) |
4bf8e196 LP |
143 | pnmr |= PnMR_YCDF_YUYV; |
144 | ||
cb2025d2 | 145 | rcar_du_plane_write(rgrp, index, PnMR, pnmr); |
4bf8e196 | 146 | |
5bfcbce0 | 147 | switch (state->format->fourcc) { |
4bf8e196 | 148 | case DRM_FORMAT_RGB565: |
4407cc02 LP |
149 | colorkey = ((state->colorkey & 0xf80000) >> 8) |
150 | | ((state->colorkey & 0x00fc00) >> 5) | |
151 | | ((state->colorkey & 0x0000f8) >> 3); | |
cb2025d2 | 152 | rcar_du_plane_write(rgrp, index, PnTC2R, colorkey); |
4bf8e196 LP |
153 | break; |
154 | ||
155 | case DRM_FORMAT_ARGB1555: | |
156 | case DRM_FORMAT_XRGB1555: | |
4407cc02 LP |
157 | colorkey = ((state->colorkey & 0xf80000) >> 9) |
158 | | ((state->colorkey & 0x00f800) >> 6) | |
159 | | ((state->colorkey & 0x0000f8) >> 3); | |
cb2025d2 | 160 | rcar_du_plane_write(rgrp, index, PnTC2R, colorkey); |
4bf8e196 LP |
161 | break; |
162 | ||
163 | case DRM_FORMAT_XRGB8888: | |
164 | case DRM_FORMAT_ARGB8888: | |
cb2025d2 | 165 | rcar_du_plane_write(rgrp, index, PnTC3R, |
4407cc02 | 166 | PnTC3R_CODE | (state->colorkey & 0xffffff)); |
4bf8e196 LP |
167 | break; |
168 | } | |
169 | } | |
170 | ||
34a04f2b LP |
171 | static void rcar_du_plane_setup_format(struct rcar_du_group *rgrp, |
172 | unsigned int index, | |
173 | const struct rcar_du_plane_state *state) | |
4bf8e196 | 174 | { |
4bf8e196 LP |
175 | u32 ddcr2 = PnDDCR2_CODE; |
176 | u32 ddcr4; | |
4bf8e196 LP |
177 | |
178 | /* Data format | |
179 | * | |
180 | * The data format is selected by the DDDF field in PnMR and the EDF | |
181 | * field in DDCR4. | |
182 | */ | |
4bf8e196 | 183 | |
34a04f2b | 184 | rcar_du_plane_setup_mode(rgrp, index, state); |
4bf8e196 | 185 | |
5bfcbce0 | 186 | if (state->format->planes == 2) { |
5ee5a81d | 187 | if (state->hwindex != index) { |
5bfcbce0 LP |
188 | if (state->format->fourcc == DRM_FORMAT_NV12 || |
189 | state->format->fourcc == DRM_FORMAT_NV21) | |
4bf8e196 LP |
190 | ddcr2 |= PnDDCR2_Y420; |
191 | ||
5bfcbce0 | 192 | if (state->format->fourcc == DRM_FORMAT_NV21) |
4bf8e196 LP |
193 | ddcr2 |= PnDDCR2_NV21; |
194 | ||
195 | ddcr2 |= PnDDCR2_DIVU; | |
196 | } else { | |
197 | ddcr2 |= PnDDCR2_DIVY; | |
198 | } | |
199 | } | |
200 | ||
cb2025d2 | 201 | rcar_du_plane_write(rgrp, index, PnDDCR2, ddcr2); |
ff967363 LP |
202 | |
203 | ddcr4 = state->format->edf | PnDDCR4_CODE; | |
34a04f2b LP |
204 | if (state->source != RCAR_DU_PLANE_MEMORY) |
205 | ddcr4 |= PnDDCR4_VSPS; | |
ff967363 | 206 | |
cb2025d2 | 207 | rcar_du_plane_write(rgrp, index, PnDDCR4, ddcr4); |
4bf8e196 | 208 | |
4bf8e196 | 209 | /* Destination position and size */ |
34a04f2b LP |
210 | rcar_du_plane_write(rgrp, index, PnDSXR, state->state.crtc_w); |
211 | rcar_du_plane_write(rgrp, index, PnDSYR, state->state.crtc_h); | |
212 | rcar_du_plane_write(rgrp, index, PnDPXR, state->state.crtc_x); | |
213 | rcar_du_plane_write(rgrp, index, PnDPYR, state->state.crtc_y); | |
4bf8e196 LP |
214 | |
215 | /* Wrap-around and blinking, disabled */ | |
cb2025d2 LP |
216 | rcar_du_plane_write(rgrp, index, PnWASPR, 0); |
217 | rcar_du_plane_write(rgrp, index, PnWAMWR, 4095); | |
218 | rcar_du_plane_write(rgrp, index, PnBTR, 0); | |
219 | rcar_du_plane_write(rgrp, index, PnMLR, 0); | |
4bf8e196 LP |
220 | } |
221 | ||
222 | void rcar_du_plane_setup(struct rcar_du_plane *plane) | |
223 | { | |
5bfcbce0 | 224 | struct rcar_du_plane_state *state = |
ec69a406 | 225 | to_rcar_plane_state(plane->plane.state); |
34a04f2b | 226 | struct rcar_du_group *rgrp = plane->group; |
5bfcbce0 | 227 | |
34a04f2b | 228 | rcar_du_plane_setup_format(rgrp, state->hwindex, state); |
5bfcbce0 | 229 | if (state->format->planes == 2) |
34a04f2b LP |
230 | rcar_du_plane_setup_format(rgrp, (state->hwindex + 1) % 8, |
231 | state); | |
232 | ||
233 | rcar_du_plane_setup_scanout(rgrp, state); | |
4bf8e196 | 234 | |
34a04f2b LP |
235 | if (state->source == RCAR_DU_PLANE_VSPD1) { |
236 | unsigned int vspd1_sink = rgrp->index ? 2 : 0; | |
237 | struct rcar_du_device *rcdu = rgrp->dev; | |
238 | ||
239 | if (rcdu->vspd1_sink != vspd1_sink) { | |
240 | rcdu->vspd1_sink = vspd1_sink; | |
241 | rcar_du_set_dpad0_vsp1_routing(rcdu); | |
242 | } | |
243 | } | |
4bf8e196 LP |
244 | } |
245 | ||
920888a2 LP |
246 | static int rcar_du_plane_atomic_check(struct drm_plane *plane, |
247 | struct drm_plane_state *state) | |
4bf8e196 | 248 | { |
ec69a406 | 249 | struct rcar_du_plane_state *rstate = to_rcar_plane_state(state); |
4bf8e196 | 250 | struct rcar_du_plane *rplane = to_rcar_plane(plane); |
cb2025d2 | 251 | struct rcar_du_device *rcdu = rplane->group->dev; |
4bf8e196 | 252 | |
5ee5a81d LP |
253 | if (!state->fb || !state->crtc) { |
254 | rstate->format = NULL; | |
920888a2 | 255 | return 0; |
5ee5a81d | 256 | } |
917de180 | 257 | |
920888a2 LP |
258 | if (state->src_w >> 16 != state->crtc_w || |
259 | state->src_h >> 16 != state->crtc_h) { | |
260 | dev_dbg(rcdu->dev, "%s: scaling not supported\n", __func__); | |
4bf8e196 LP |
261 | return -EINVAL; |
262 | } | |
263 | ||
5ee5a81d LP |
264 | rstate->format = rcar_du_format_info(state->fb->pixel_format); |
265 | if (rstate->format == NULL) { | |
920888a2 LP |
266 | dev_dbg(rcdu->dev, "%s: unsupported format %08x\n", __func__, |
267 | state->fb->pixel_format); | |
4bf8e196 LP |
268 | return -EINVAL; |
269 | } | |
270 | ||
4bf8e196 LP |
271 | return 0; |
272 | } | |
273 | ||
920888a2 LP |
274 | static void rcar_du_plane_atomic_update(struct drm_plane *plane, |
275 | struct drm_plane_state *old_state) | |
276 | { | |
277 | struct rcar_du_plane *rplane = to_rcar_plane(plane); | |
2af03944 LP |
278 | struct rcar_du_plane_state *old_rstate; |
279 | struct rcar_du_plane_state *new_rstate; | |
5bfcbce0 | 280 | |
2af03944 LP |
281 | if (!plane->state->crtc) |
282 | return; | |
283 | ||
284 | rcar_du_plane_setup(rplane); | |
285 | ||
286 | /* Check whether the source has changed from memory to live source or | |
287 | * from live source to memory. The source has been configured by the | |
288 | * VSPS bit in the PnDDCR4 register. Although the datasheet states that | |
289 | * the bit is updated during vertical blanking, it seems that updates | |
290 | * only occur when the DU group is held in reset through the DSYSR.DRES | |
291 | * bit. We thus need to restart the group if the source changes. | |
292 | */ | |
293 | old_rstate = to_rcar_plane_state(old_state); | |
294 | new_rstate = to_rcar_plane_state(plane->state); | |
295 | ||
296 | if ((old_rstate->source == RCAR_DU_PLANE_MEMORY) != | |
297 | (new_rstate->source == RCAR_DU_PLANE_MEMORY)) | |
298 | rplane->group->need_restart = true; | |
4bf8e196 LP |
299 | } |
300 | ||
920888a2 LP |
301 | static const struct drm_plane_helper_funcs rcar_du_plane_helper_funcs = { |
302 | .atomic_check = rcar_du_plane_atomic_check, | |
303 | .atomic_update = rcar_du_plane_atomic_update, | |
304 | }; | |
305 | ||
4407cc02 LP |
306 | static struct drm_plane_state * |
307 | rcar_du_plane_atomic_duplicate_state(struct drm_plane *plane) | |
4bf8e196 | 308 | { |
4407cc02 LP |
309 | struct rcar_du_plane_state *state; |
310 | struct rcar_du_plane_state *copy; | |
4bf8e196 | 311 | |
263b39fe LP |
312 | if (WARN_ON(!plane->state)) |
313 | return NULL; | |
314 | ||
ec69a406 | 315 | state = to_rcar_plane_state(plane->state); |
4407cc02 LP |
316 | copy = kmemdup(state, sizeof(*state), GFP_KERNEL); |
317 | if (copy == NULL) | |
318 | return NULL; | |
319 | ||
263b39fe | 320 | __drm_atomic_helper_plane_duplicate_state(plane, ©->state); |
4bf8e196 | 321 | |
4407cc02 | 322 | return ©->state; |
4bf8e196 LP |
323 | } |
324 | ||
4407cc02 LP |
325 | static void rcar_du_plane_atomic_destroy_state(struct drm_plane *plane, |
326 | struct drm_plane_state *state) | |
4bf8e196 | 327 | { |
263b39fe | 328 | __drm_atomic_helper_plane_destroy_state(plane, state); |
ec69a406 | 329 | kfree(to_rcar_plane_state(state)); |
4407cc02 | 330 | } |
4bf8e196 | 331 | |
a32a3c80 LP |
332 | static void rcar_du_plane_reset(struct drm_plane *plane) |
333 | { | |
334 | struct rcar_du_plane_state *state; | |
335 | ||
336 | if (plane->state) { | |
337 | rcar_du_plane_atomic_destroy_state(plane, plane->state); | |
338 | plane->state = NULL; | |
339 | } | |
340 | ||
341 | state = kzalloc(sizeof(*state), GFP_KERNEL); | |
342 | if (state == NULL) | |
343 | return; | |
344 | ||
345 | state->hwindex = -1; | |
af8ad962 | 346 | state->source = RCAR_DU_PLANE_MEMORY; |
a32a3c80 LP |
347 | state->alpha = 255; |
348 | state->colorkey = RCAR_DU_COLORKEY_NONE; | |
349 | state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1; | |
350 | ||
351 | plane->state = &state->state; | |
352 | plane->state->plane = plane; | |
353 | } | |
354 | ||
4407cc02 LP |
355 | static int rcar_du_plane_atomic_set_property(struct drm_plane *plane, |
356 | struct drm_plane_state *state, | |
357 | struct drm_property *property, | |
358 | uint64_t val) | |
359 | { | |
ec69a406 | 360 | struct rcar_du_plane_state *rstate = to_rcar_plane_state(state); |
9f6aee95 | 361 | struct rcar_du_device *rcdu = to_rcar_plane(plane)->group->dev; |
4bf8e196 | 362 | |
9f6aee95 | 363 | if (property == rcdu->props.alpha) |
4407cc02 | 364 | rstate->alpha = val; |
9f6aee95 | 365 | else if (property == rcdu->props.colorkey) |
4407cc02 | 366 | rstate->colorkey = val; |
9f6aee95 | 367 | else if (property == rcdu->props.zpos) |
4407cc02 LP |
368 | rstate->zpos = val; |
369 | else | |
370 | return -EINVAL; | |
4bf8e196 | 371 | |
4407cc02 | 372 | return 0; |
4bf8e196 LP |
373 | } |
374 | ||
4407cc02 LP |
375 | static int rcar_du_plane_atomic_get_property(struct drm_plane *plane, |
376 | const struct drm_plane_state *state, struct drm_property *property, | |
377 | uint64_t *val) | |
4bf8e196 | 378 | { |
4407cc02 LP |
379 | const struct rcar_du_plane_state *rstate = |
380 | container_of(state, const struct rcar_du_plane_state, state); | |
9f6aee95 | 381 | struct rcar_du_device *rcdu = to_rcar_plane(plane)->group->dev; |
4bf8e196 | 382 | |
9f6aee95 | 383 | if (property == rcdu->props.alpha) |
4407cc02 | 384 | *val = rstate->alpha; |
9f6aee95 | 385 | else if (property == rcdu->props.colorkey) |
4407cc02 | 386 | *val = rstate->colorkey; |
9f6aee95 | 387 | else if (property == rcdu->props.zpos) |
4407cc02 | 388 | *val = rstate->zpos; |
4bf8e196 LP |
389 | else |
390 | return -EINVAL; | |
391 | ||
392 | return 0; | |
393 | } | |
394 | ||
395 | static const struct drm_plane_funcs rcar_du_plane_funcs = { | |
336d04a1 LP |
396 | .update_plane = drm_atomic_helper_update_plane, |
397 | .disable_plane = drm_atomic_helper_disable_plane, | |
4407cc02 LP |
398 | .reset = rcar_du_plane_reset, |
399 | .set_property = drm_atomic_helper_plane_set_property, | |
4bf8e196 | 400 | .destroy = drm_plane_cleanup, |
4407cc02 LP |
401 | .atomic_duplicate_state = rcar_du_plane_atomic_duplicate_state, |
402 | .atomic_destroy_state = rcar_du_plane_atomic_destroy_state, | |
403 | .atomic_set_property = rcar_du_plane_atomic_set_property, | |
404 | .atomic_get_property = rcar_du_plane_atomic_get_property, | |
4bf8e196 LP |
405 | }; |
406 | ||
407 | static const uint32_t formats[] = { | |
408 | DRM_FORMAT_RGB565, | |
409 | DRM_FORMAT_ARGB1555, | |
410 | DRM_FORMAT_XRGB1555, | |
411 | DRM_FORMAT_XRGB8888, | |
412 | DRM_FORMAT_ARGB8888, | |
413 | DRM_FORMAT_UYVY, | |
414 | DRM_FORMAT_YUYV, | |
415 | DRM_FORMAT_NV12, | |
416 | DRM_FORMAT_NV21, | |
417 | DRM_FORMAT_NV16, | |
418 | }; | |
419 | ||
cb2025d2 | 420 | int rcar_du_planes_init(struct rcar_du_group *rgrp) |
4bf8e196 | 421 | { |
cb2025d2 | 422 | struct rcar_du_device *rcdu = rgrp->dev; |
917de180 | 423 | unsigned int crtcs; |
4bf8e196 | 424 | unsigned int i; |
917de180 | 425 | int ret; |
4bf8e196 | 426 | |
9f6aee95 | 427 | /* Create one primary plane per CRTC in this group and seven overlay |
917de180 LP |
428 | * planes. |
429 | */ | |
d6aed574 | 430 | rgrp->num_planes = rgrp->num_crtcs + 7; |
917de180 LP |
431 | |
432 | crtcs = ((1 << rcdu->num_crtcs) - 1) & (3 << (2 * rgrp->index)); | |
433 | ||
d6aed574 | 434 | for (i = 0; i < rgrp->num_planes; ++i) { |
fe6fbe9a | 435 | enum drm_plane_type type = i < rgrp->num_crtcs |
917de180 LP |
436 | ? DRM_PLANE_TYPE_PRIMARY |
437 | : DRM_PLANE_TYPE_OVERLAY; | |
99caede1 | 438 | struct rcar_du_plane *plane = &rgrp->planes[i]; |
4bf8e196 | 439 | |
cb2025d2 | 440 | plane->group = rgrp; |
4bf8e196 | 441 | |
917de180 LP |
442 | ret = drm_universal_plane_init(rcdu->ddev, &plane->plane, crtcs, |
443 | &rcar_du_plane_funcs, formats, | |
b0b3b795 VS |
444 | ARRAY_SIZE(formats), type, |
445 | NULL); | |
4bf8e196 LP |
446 | if (ret < 0) |
447 | return ret; | |
448 | ||
920888a2 LP |
449 | drm_plane_helper_add(&plane->plane, |
450 | &rcar_du_plane_helper_funcs); | |
451 | ||
917de180 LP |
452 | if (type == DRM_PLANE_TYPE_PRIMARY) |
453 | continue; | |
454 | ||
4bf8e196 | 455 | drm_object_attach_property(&plane->plane.base, |
9f6aee95 | 456 | rcdu->props.alpha, 255); |
4bf8e196 | 457 | drm_object_attach_property(&plane->plane.base, |
9f6aee95 | 458 | rcdu->props.colorkey, |
4bf8e196 LP |
459 | RCAR_DU_COLORKEY_NONE); |
460 | drm_object_attach_property(&plane->plane.base, | |
9f6aee95 | 461 | rcdu->props.zpos, 1); |
4bf8e196 LP |
462 | } |
463 | ||
464 | return 0; | |
465 | } |