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" | |
23 | #include "rcar_du_kms.h" | |
24 | #include "rcar_du_plane.h" | |
25 | #include "rcar_du_regs.h" | |
26 | ||
27 | #define RCAR_DU_COLORKEY_NONE (0 << 24) | |
28 | #define RCAR_DU_COLORKEY_SOURCE (1 << 24) | |
29 | #define RCAR_DU_COLORKEY_MASK (1 << 24) | |
30 | ||
cb2025d2 | 31 | static u32 rcar_du_plane_read(struct rcar_du_group *rgrp, |
4bf8e196 LP |
32 | unsigned int index, u32 reg) |
33 | { | |
cb2025d2 LP |
34 | return rcar_du_read(rgrp->dev, |
35 | rgrp->mmio_offset + index * PLANE_OFF + reg); | |
4bf8e196 LP |
36 | } |
37 | ||
cb2025d2 | 38 | static void rcar_du_plane_write(struct rcar_du_group *rgrp, |
4bf8e196 LP |
39 | unsigned int index, u32 reg, u32 data) |
40 | { | |
cb2025d2 LP |
41 | rcar_du_write(rgrp->dev, rgrp->mmio_offset + index * PLANE_OFF + reg, |
42 | data); | |
4bf8e196 LP |
43 | } |
44 | ||
f398f344 | 45 | static void rcar_du_plane_setup_fb(struct rcar_du_plane *plane) |
4bf8e196 | 46 | { |
5bfcbce0 | 47 | struct rcar_du_plane_state *state = |
ec69a406 | 48 | to_rcar_plane_state(plane->plane.state); |
f398f344 | 49 | struct drm_framebuffer *fb = plane->plane.state->fb; |
cb2025d2 | 50 | struct rcar_du_group *rgrp = plane->group; |
5bfcbce0 LP |
51 | unsigned int src_x = state->state.src_x >> 16; |
52 | unsigned int src_y = state->state.src_y >> 16; | |
5ee5a81d | 53 | unsigned int index = state->hwindex; |
f398f344 | 54 | struct drm_gem_cma_object *gem; |
906eff7f | 55 | bool interlaced; |
eb86301f LP |
56 | u32 mwr; |
57 | ||
5bfcbce0 | 58 | interlaced = state->state.crtc->state->adjusted_mode.flags |
47094194 | 59 | & DRM_MODE_FLAG_INTERLACE; |
906eff7f LP |
60 | |
61 | /* Memory pitch (expressed in pixels). Must be doubled for interlaced | |
62 | * operation with 32bpp formats. | |
63 | */ | |
5bfcbce0 | 64 | if (state->format->planes == 2) |
f398f344 | 65 | mwr = fb->pitches[0]; |
eb86301f | 66 | else |
5bfcbce0 | 67 | mwr = fb->pitches[0] * 8 / state->format->bpp; |
eb86301f | 68 | |
5bfcbce0 | 69 | if (interlaced && state->format->bpp == 32) |
906eff7f LP |
70 | mwr *= 2; |
71 | ||
eb86301f | 72 | rcar_du_plane_write(rgrp, index, PnMWR, mwr); |
4bf8e196 | 73 | |
9e7db06d LP |
74 | /* The Y position is expressed in raster line units and must be doubled |
75 | * for 32bpp formats, according to the R8A7790 datasheet. No mention of | |
76 | * doubling the Y position is found in the R8A7779 datasheet, but the | |
77 | * rule seems to apply there as well. | |
78 | * | |
906eff7f LP |
79 | * Despite not being documented, doubling seem not to be needed when |
80 | * operating in interlaced mode. | |
81 | * | |
9e7db06d | 82 | * Similarly, for the second plane, NV12 and NV21 formats seem to |
906eff7f LP |
83 | * require a halved Y position value, in both progressive and interlaced |
84 | * modes. | |
4bf8e196 | 85 | */ |
287bdf03 LP |
86 | rcar_du_plane_write(rgrp, index, PnSPXR, src_x); |
87 | rcar_du_plane_write(rgrp, index, PnSPYR, src_y * | |
5bfcbce0 | 88 | (!interlaced && state->format->bpp == 32 ? 2 : 1)); |
f398f344 LP |
89 | |
90 | gem = drm_fb_cma_get_gem_obj(fb, 0); | |
91 | rcar_du_plane_write(rgrp, index, PnDSA0R, gem->paddr + fb->offsets[0]); | |
4bf8e196 | 92 | |
5bfcbce0 | 93 | if (state->format->planes == 2) { |
4bf8e196 LP |
94 | index = (index + 1) % 8; |
95 | ||
f398f344 | 96 | rcar_du_plane_write(rgrp, index, PnMWR, fb->pitches[0]); |
49785e25 | 97 | |
287bdf03 LP |
98 | rcar_du_plane_write(rgrp, index, PnSPXR, src_x); |
99 | rcar_du_plane_write(rgrp, index, PnSPYR, src_y * | |
5bfcbce0 | 100 | (state->format->bpp == 16 ? 2 : 1) / 2); |
eb86301f | 101 | |
4bf8e196 | 102 | gem = drm_fb_cma_get_gem_obj(fb, 1); |
f398f344 LP |
103 | rcar_du_plane_write(rgrp, index, PnDSA0R, |
104 | gem->paddr + fb->offsets[1]); | |
4bf8e196 LP |
105 | } |
106 | } | |
107 | ||
108 | static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane, | |
109 | unsigned int index) | |
110 | { | |
4407cc02 | 111 | struct rcar_du_plane_state *state = |
ec69a406 | 112 | to_rcar_plane_state(plane->plane.state); |
cb2025d2 | 113 | struct rcar_du_group *rgrp = plane->group; |
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 | ||
171 | static void __rcar_du_plane_setup(struct rcar_du_plane *plane, | |
172 | unsigned int index) | |
173 | { | |
5bfcbce0 | 174 | struct rcar_du_plane_state *state = |
ec69a406 | 175 | to_rcar_plane_state(plane->plane.state); |
cb2025d2 | 176 | struct rcar_du_group *rgrp = plane->group; |
4bf8e196 LP |
177 | u32 ddcr2 = PnDDCR2_CODE; |
178 | u32 ddcr4; | |
4bf8e196 LP |
179 | |
180 | /* Data format | |
181 | * | |
182 | * The data format is selected by the DDDF field in PnMR and the EDF | |
183 | * field in DDCR4. | |
184 | */ | |
cb2025d2 | 185 | ddcr4 = rcar_du_plane_read(rgrp, index, PnDDCR4); |
4bf8e196 | 186 | ddcr4 &= ~PnDDCR4_EDF_MASK; |
5bfcbce0 | 187 | ddcr4 |= state->format->edf | PnDDCR4_CODE; |
4bf8e196 LP |
188 | |
189 | rcar_du_plane_setup_mode(plane, index); | |
190 | ||
5bfcbce0 | 191 | if (state->format->planes == 2) { |
5ee5a81d | 192 | if (state->hwindex != index) { |
5bfcbce0 LP |
193 | if (state->format->fourcc == DRM_FORMAT_NV12 || |
194 | state->format->fourcc == DRM_FORMAT_NV21) | |
4bf8e196 LP |
195 | ddcr2 |= PnDDCR2_Y420; |
196 | ||
5bfcbce0 | 197 | if (state->format->fourcc == DRM_FORMAT_NV21) |
4bf8e196 LP |
198 | ddcr2 |= PnDDCR2_NV21; |
199 | ||
200 | ddcr2 |= PnDDCR2_DIVU; | |
201 | } else { | |
202 | ddcr2 |= PnDDCR2_DIVY; | |
203 | } | |
204 | } | |
205 | ||
cb2025d2 LP |
206 | rcar_du_plane_write(rgrp, index, PnDDCR2, ddcr2); |
207 | rcar_du_plane_write(rgrp, index, PnDDCR4, ddcr4); | |
4bf8e196 | 208 | |
4bf8e196 | 209 | /* Destination position and size */ |
287bdf03 LP |
210 | rcar_du_plane_write(rgrp, index, PnDSXR, plane->plane.state->crtc_w); |
211 | rcar_du_plane_write(rgrp, index, PnDSYR, plane->plane.state->crtc_h); | |
212 | rcar_du_plane_write(rgrp, index, PnDPXR, plane->plane.state->crtc_x); | |
213 | rcar_du_plane_write(rgrp, index, PnDPYR, plane->plane.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); |
5bfcbce0 | 226 | |
5ee5a81d | 227 | __rcar_du_plane_setup(plane, state->hwindex); |
5bfcbce0 | 228 | if (state->format->planes == 2) |
5ee5a81d | 229 | __rcar_du_plane_setup(plane, (state->hwindex + 1) % 8); |
4bf8e196 | 230 | |
f398f344 | 231 | rcar_du_plane_setup_fb(plane); |
4bf8e196 LP |
232 | } |
233 | ||
920888a2 LP |
234 | static int rcar_du_plane_atomic_check(struct drm_plane *plane, |
235 | struct drm_plane_state *state) | |
4bf8e196 | 236 | { |
ec69a406 | 237 | struct rcar_du_plane_state *rstate = to_rcar_plane_state(state); |
4bf8e196 | 238 | struct rcar_du_plane *rplane = to_rcar_plane(plane); |
cb2025d2 | 239 | struct rcar_du_device *rcdu = rplane->group->dev; |
4bf8e196 | 240 | |
5ee5a81d LP |
241 | if (!state->fb || !state->crtc) { |
242 | rstate->format = NULL; | |
920888a2 | 243 | return 0; |
5ee5a81d | 244 | } |
917de180 | 245 | |
920888a2 LP |
246 | if (state->src_w >> 16 != state->crtc_w || |
247 | state->src_h >> 16 != state->crtc_h) { | |
248 | dev_dbg(rcdu->dev, "%s: scaling not supported\n", __func__); | |
4bf8e196 LP |
249 | return -EINVAL; |
250 | } | |
251 | ||
5ee5a81d LP |
252 | rstate->format = rcar_du_format_info(state->fb->pixel_format); |
253 | if (rstate->format == NULL) { | |
920888a2 LP |
254 | dev_dbg(rcdu->dev, "%s: unsupported format %08x\n", __func__, |
255 | state->fb->pixel_format); | |
4bf8e196 LP |
256 | return -EINVAL; |
257 | } | |
258 | ||
4bf8e196 LP |
259 | return 0; |
260 | } | |
261 | ||
920888a2 LP |
262 | static void rcar_du_plane_atomic_update(struct drm_plane *plane, |
263 | struct drm_plane_state *old_state) | |
264 | { | |
265 | struct rcar_du_plane *rplane = to_rcar_plane(plane); | |
5bfcbce0 | 266 | |
5ee5a81d LP |
267 | if (plane->state->crtc) |
268 | rcar_du_plane_setup(rplane); | |
4bf8e196 LP |
269 | } |
270 | ||
920888a2 LP |
271 | static const struct drm_plane_helper_funcs rcar_du_plane_helper_funcs = { |
272 | .atomic_check = rcar_du_plane_atomic_check, | |
273 | .atomic_update = rcar_du_plane_atomic_update, | |
274 | }; | |
275 | ||
4407cc02 | 276 | static void rcar_du_plane_reset(struct drm_plane *plane) |
4bf8e196 | 277 | { |
4407cc02 LP |
278 | struct rcar_du_plane_state *state; |
279 | ||
280 | if (plane->state && plane->state->fb) | |
281 | drm_framebuffer_unreference(plane->state->fb); | |
4bf8e196 | 282 | |
4407cc02 LP |
283 | kfree(plane->state); |
284 | plane->state = NULL; | |
285 | ||
286 | state = kzalloc(sizeof(*state), GFP_KERNEL); | |
287 | if (state == NULL) | |
4bf8e196 LP |
288 | return; |
289 | ||
5ee5a81d | 290 | state->hwindex = -1; |
4407cc02 LP |
291 | state->alpha = 255; |
292 | state->colorkey = RCAR_DU_COLORKEY_NONE; | |
293 | state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1; | |
294 | ||
295 | plane->state = &state->state; | |
296 | plane->state->plane = plane; | |
4bf8e196 LP |
297 | } |
298 | ||
4407cc02 LP |
299 | static struct drm_plane_state * |
300 | rcar_du_plane_atomic_duplicate_state(struct drm_plane *plane) | |
4bf8e196 | 301 | { |
4407cc02 LP |
302 | struct rcar_du_plane_state *state; |
303 | struct rcar_du_plane_state *copy; | |
4bf8e196 | 304 | |
ec69a406 | 305 | state = to_rcar_plane_state(plane->state); |
4407cc02 LP |
306 | copy = kmemdup(state, sizeof(*state), GFP_KERNEL); |
307 | if (copy == NULL) | |
308 | return NULL; | |
309 | ||
310 | if (copy->state.fb) | |
311 | drm_framebuffer_reference(copy->state.fb); | |
4bf8e196 | 312 | |
4407cc02 | 313 | return ©->state; |
4bf8e196 LP |
314 | } |
315 | ||
4407cc02 LP |
316 | static void rcar_du_plane_atomic_destroy_state(struct drm_plane *plane, |
317 | struct drm_plane_state *state) | |
4bf8e196 | 318 | { |
de115fac LP |
319 | if (state->fb) |
320 | drm_framebuffer_unreference(state->fb); | |
321 | ||
ec69a406 | 322 | kfree(to_rcar_plane_state(state)); |
4407cc02 | 323 | } |
4bf8e196 | 324 | |
4407cc02 LP |
325 | static int rcar_du_plane_atomic_set_property(struct drm_plane *plane, |
326 | struct drm_plane_state *state, | |
327 | struct drm_property *property, | |
328 | uint64_t val) | |
329 | { | |
ec69a406 | 330 | struct rcar_du_plane_state *rstate = to_rcar_plane_state(state); |
9f6aee95 | 331 | struct rcar_du_device *rcdu = to_rcar_plane(plane)->group->dev; |
4bf8e196 | 332 | |
9f6aee95 | 333 | if (property == rcdu->props.alpha) |
4407cc02 | 334 | rstate->alpha = val; |
9f6aee95 | 335 | else if (property == rcdu->props.colorkey) |
4407cc02 | 336 | rstate->colorkey = val; |
9f6aee95 | 337 | else if (property == rcdu->props.zpos) |
4407cc02 LP |
338 | rstate->zpos = val; |
339 | else | |
340 | return -EINVAL; | |
4bf8e196 | 341 | |
4407cc02 | 342 | return 0; |
4bf8e196 LP |
343 | } |
344 | ||
4407cc02 LP |
345 | static int rcar_du_plane_atomic_get_property(struct drm_plane *plane, |
346 | const struct drm_plane_state *state, struct drm_property *property, | |
347 | uint64_t *val) | |
4bf8e196 | 348 | { |
4407cc02 LP |
349 | const struct rcar_du_plane_state *rstate = |
350 | container_of(state, const struct rcar_du_plane_state, state); | |
9f6aee95 | 351 | struct rcar_du_device *rcdu = to_rcar_plane(plane)->group->dev; |
4bf8e196 | 352 | |
9f6aee95 | 353 | if (property == rcdu->props.alpha) |
4407cc02 | 354 | *val = rstate->alpha; |
9f6aee95 | 355 | else if (property == rcdu->props.colorkey) |
4407cc02 | 356 | *val = rstate->colorkey; |
9f6aee95 | 357 | else if (property == rcdu->props.zpos) |
4407cc02 | 358 | *val = rstate->zpos; |
4bf8e196 LP |
359 | else |
360 | return -EINVAL; | |
361 | ||
362 | return 0; | |
363 | } | |
364 | ||
365 | static const struct drm_plane_funcs rcar_du_plane_funcs = { | |
336d04a1 LP |
366 | .update_plane = drm_atomic_helper_update_plane, |
367 | .disable_plane = drm_atomic_helper_disable_plane, | |
4407cc02 LP |
368 | .reset = rcar_du_plane_reset, |
369 | .set_property = drm_atomic_helper_plane_set_property, | |
4bf8e196 | 370 | .destroy = drm_plane_cleanup, |
4407cc02 LP |
371 | .atomic_duplicate_state = rcar_du_plane_atomic_duplicate_state, |
372 | .atomic_destroy_state = rcar_du_plane_atomic_destroy_state, | |
373 | .atomic_set_property = rcar_du_plane_atomic_set_property, | |
374 | .atomic_get_property = rcar_du_plane_atomic_get_property, | |
4bf8e196 LP |
375 | }; |
376 | ||
377 | static const uint32_t formats[] = { | |
378 | DRM_FORMAT_RGB565, | |
379 | DRM_FORMAT_ARGB1555, | |
380 | DRM_FORMAT_XRGB1555, | |
381 | DRM_FORMAT_XRGB8888, | |
382 | DRM_FORMAT_ARGB8888, | |
383 | DRM_FORMAT_UYVY, | |
384 | DRM_FORMAT_YUYV, | |
385 | DRM_FORMAT_NV12, | |
386 | DRM_FORMAT_NV21, | |
387 | DRM_FORMAT_NV16, | |
388 | }; | |
389 | ||
cb2025d2 | 390 | int rcar_du_planes_init(struct rcar_du_group *rgrp) |
4bf8e196 | 391 | { |
cb2025d2 | 392 | struct rcar_du_device *rcdu = rgrp->dev; |
917de180 | 393 | unsigned int crtcs; |
4bf8e196 | 394 | unsigned int i; |
917de180 | 395 | int ret; |
4bf8e196 | 396 | |
9f6aee95 | 397 | /* Create one primary plane per CRTC in this group and seven overlay |
917de180 LP |
398 | * planes. |
399 | */ | |
d6aed574 | 400 | rgrp->num_planes = rgrp->num_crtcs + 7; |
917de180 LP |
401 | |
402 | crtcs = ((1 << rcdu->num_crtcs) - 1) & (3 << (2 * rgrp->index)); | |
403 | ||
d6aed574 | 404 | for (i = 0; i < rgrp->num_planes; ++i) { |
fe6fbe9a | 405 | enum drm_plane_type type = i < rgrp->num_crtcs |
917de180 LP |
406 | ? DRM_PLANE_TYPE_PRIMARY |
407 | : DRM_PLANE_TYPE_OVERLAY; | |
99caede1 | 408 | struct rcar_du_plane *plane = &rgrp->planes[i]; |
4bf8e196 | 409 | |
cb2025d2 | 410 | plane->group = rgrp; |
4bf8e196 | 411 | |
917de180 LP |
412 | ret = drm_universal_plane_init(rcdu->ddev, &plane->plane, crtcs, |
413 | &rcar_du_plane_funcs, formats, | |
414 | ARRAY_SIZE(formats), type); | |
4bf8e196 LP |
415 | if (ret < 0) |
416 | return ret; | |
417 | ||
920888a2 LP |
418 | drm_plane_helper_add(&plane->plane, |
419 | &rcar_du_plane_helper_funcs); | |
420 | ||
917de180 LP |
421 | if (type == DRM_PLANE_TYPE_PRIMARY) |
422 | continue; | |
423 | ||
4bf8e196 | 424 | drm_object_attach_property(&plane->plane.base, |
9f6aee95 | 425 | rcdu->props.alpha, 255); |
4bf8e196 | 426 | drm_object_attach_property(&plane->plane.base, |
9f6aee95 | 427 | rcdu->props.colorkey, |
4bf8e196 LP |
428 | RCAR_DU_COLORKEY_NONE); |
429 | drm_object_attach_property(&plane->plane.base, | |
9f6aee95 | 430 | rcdu->props.zpos, 1); |
4bf8e196 LP |
431 | } |
432 | ||
433 | return 0; | |
434 | } |