drm/imx: atomic phase 2 step 1: Wire up state ->reset, ->duplicate and ->destroy
[linux-2.6-block.git] / drivers / gpu / drm / imx / ipuv3-plane.c
1 /*
2  * i.MX IPUv3 DP Overlay Planes
3  *
4  * Copyright (C) 2013 Philipp Zabel, Pengutronix
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  */
15
16 #include <drm/drmP.h>
17 #include <drm/drm_atomic_helper.h>
18 #include <drm/drm_fb_cma_helper.h>
19 #include <drm/drm_gem_cma_helper.h>
20 #include <drm/drm_plane_helper.h>
21
22 #include "video/imx-ipu-v3.h"
23 #include "ipuv3-plane.h"
24
25 #define to_ipu_plane(x) container_of(x, struct ipu_plane, base)
26
27 static const uint32_t ipu_plane_formats[] = {
28         DRM_FORMAT_ARGB1555,
29         DRM_FORMAT_XRGB1555,
30         DRM_FORMAT_ABGR1555,
31         DRM_FORMAT_XBGR1555,
32         DRM_FORMAT_RGBA5551,
33         DRM_FORMAT_BGRA5551,
34         DRM_FORMAT_ARGB4444,
35         DRM_FORMAT_ARGB8888,
36         DRM_FORMAT_XRGB8888,
37         DRM_FORMAT_ABGR8888,
38         DRM_FORMAT_XBGR8888,
39         DRM_FORMAT_RGBA8888,
40         DRM_FORMAT_RGBX8888,
41         DRM_FORMAT_BGRA8888,
42         DRM_FORMAT_BGRA8888,
43         DRM_FORMAT_UYVY,
44         DRM_FORMAT_VYUY,
45         DRM_FORMAT_YUYV,
46         DRM_FORMAT_YVYU,
47         DRM_FORMAT_YUV420,
48         DRM_FORMAT_YVU420,
49         DRM_FORMAT_RGB565,
50 };
51
52 int ipu_plane_irq(struct ipu_plane *ipu_plane)
53 {
54         return ipu_idmac_channel_irq(ipu_plane->ipu, ipu_plane->ipu_ch,
55                                      IPU_IRQ_EOF);
56 }
57
58 int ipu_plane_set_base(struct ipu_plane *ipu_plane, struct drm_framebuffer *fb)
59 {
60         struct drm_gem_cma_object *cma_obj[3], *old_cma_obj[3];
61         struct drm_plane_state *state = ipu_plane->base.state;
62         struct drm_framebuffer *old_fb = state->fb;
63         unsigned long eba, ubo, vbo, old_eba, old_ubo, old_vbo;
64         int active, i;
65         int x = state->src_x >> 16;
66         int y = state->src_y >> 16;
67
68         for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
69                 cma_obj[i] = drm_fb_cma_get_gem_obj(fb, i);
70                 if (!cma_obj[i]) {
71                         DRM_DEBUG_KMS("plane %d entry is null.\n", i);
72                         return -EFAULT;
73                 }
74         }
75
76         for (i = 0; i < drm_format_num_planes(old_fb->pixel_format); i++) {
77                 old_cma_obj[i] = drm_fb_cma_get_gem_obj(old_fb, i);
78                 if (!old_cma_obj[i]) {
79                         DRM_DEBUG_KMS("plane %d entry is null.\n", i);
80                         return -EFAULT;
81                 }
82         }
83
84         eba = cma_obj[0]->paddr + fb->offsets[0] +
85               fb->pitches[0] * y + (fb->bits_per_pixel >> 3) * x;
86
87         if (eba & 0x7) {
88                 DRM_DEBUG_KMS("base address must be a multiple of 8.\n");
89                 return -EINVAL;
90         }
91
92         if (fb->pitches[0] < 1 || fb->pitches[0] > 16384) {
93                 DRM_DEBUG_KMS("pitches out of range.\n");
94                 return -EINVAL;
95         }
96
97         if (fb->pitches[0] != old_fb->pitches[0]) {
98                 DRM_DEBUG_KMS("pitches must not change while plane is enabled.\n");
99                 return -EINVAL;
100         }
101
102         switch (fb->pixel_format) {
103         case DRM_FORMAT_YUV420:
104         case DRM_FORMAT_YVU420:
105                 /*
106                  * Multiplanar formats have to meet the following restrictions:
107                  * - The (up to) three plane addresses are EBA, EBA+UBO, EBA+VBO
108                  * - EBA, UBO and VBO are a multiple of 8
109                  * - UBO and VBO are unsigned and not larger than 0xfffff8
110                  * - Only EBA may be changed while scanout is active
111                  * - The strides of U and V planes must be identical.
112                  */
113                 ubo = cma_obj[1]->paddr + fb->offsets[1] +
114                       fb->pitches[1] * y / 2 + x / 2 - eba;
115                 vbo = cma_obj[2]->paddr + fb->offsets[2] +
116                       fb->pitches[2] * y / 2 + x / 2 - eba;
117
118                 old_eba = old_cma_obj[0]->paddr + old_fb->offsets[0] +
119                       old_fb->pitches[0] * y +
120                       (old_fb->bits_per_pixel >> 3) * x;
121                 old_ubo = old_cma_obj[1]->paddr + old_fb->offsets[1] +
122                       old_fb->pitches[1] * y / 2 + x / 2 - old_eba;
123                 old_vbo = old_cma_obj[2]->paddr + old_fb->offsets[2] +
124                       old_fb->pitches[2] * y / 2 + x / 2 - old_eba;
125
126                 if ((ubo & 0x7) || (vbo & 0x7)) {
127                         DRM_DEBUG_KMS("U/V buffer offsets must be a multiple of 8.\n");
128                         return -EINVAL;
129                 }
130
131                 if ((ubo > 0xfffff8) || (vbo > 0xfffff8)) {
132                         DRM_DEBUG_KMS("U/V buffer offsets must be positive and not larger than 0xfffff8.\n");
133                         return -EINVAL;
134                 }
135
136                 if (old_ubo != ubo || old_vbo != vbo) {
137                         DRM_DEBUG_KMS("U/V buffer offsets must not change while plane is enabled.\n");
138                         return -EINVAL;
139                 }
140
141                 if (fb->pitches[1] != fb->pitches[2]) {
142                         DRM_DEBUG_KMS("U/V pitches must be identical.\n");
143                         return -EINVAL;
144                 }
145
146                 if (fb->pitches[1] < 1 || fb->pitches[1] > 16384) {
147                         DRM_DEBUG_KMS("U/V pitches out of range.\n");
148                         return -EINVAL;
149                 }
150
151                 if (old_fb->pitches[1] != fb->pitches[1]) {
152                         DRM_DEBUG_KMS("U/V pitches must not change while plane is enabled.\n");
153                         return -EINVAL;
154                 }
155
156                 dev_dbg(ipu_plane->base.dev->dev,
157                         "phys = %pad %pad %pad, x = %d, y = %d",
158                         &cma_obj[0]->paddr, &cma_obj[1]->paddr,
159                         &cma_obj[2]->paddr, x, y);
160                 break;
161         default:
162                 dev_dbg(ipu_plane->base.dev->dev, "phys = %pad, x = %d, y = %d",
163                         &cma_obj[0]->paddr, x, y);
164                 break;
165         }
166
167         active = ipu_idmac_get_current_buffer(ipu_plane->ipu_ch);
168         ipu_cpmem_set_buffer(ipu_plane->ipu_ch, !active, eba);
169         ipu_idmac_select_buffer(ipu_plane->ipu_ch, !active);
170
171         return 0;
172 }
173
174 static inline unsigned long
175 drm_plane_state_to_eba(struct drm_plane_state *state)
176 {
177         struct drm_framebuffer *fb = state->fb;
178         struct drm_gem_cma_object *cma_obj;
179
180         cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
181         BUG_ON(!cma_obj);
182
183         return cma_obj->paddr + fb->offsets[0] +
184                fb->pitches[0] * (state->src_y >> 16) +
185                (fb->bits_per_pixel >> 3) * (state->src_x >> 16);
186 }
187
188 static inline unsigned long
189 drm_plane_state_to_ubo(struct drm_plane_state *state)
190 {
191         struct drm_framebuffer *fb = state->fb;
192         struct drm_gem_cma_object *cma_obj;
193         unsigned long eba = drm_plane_state_to_eba(state);
194
195         cma_obj = drm_fb_cma_get_gem_obj(fb, 1);
196         BUG_ON(!cma_obj);
197
198         return cma_obj->paddr + fb->offsets[1] +
199                fb->pitches[1] * (state->src_y >> 16) / 2 +
200                (state->src_x >> 16) / 2 - eba;
201 }
202
203 static inline unsigned long
204 drm_plane_state_to_vbo(struct drm_plane_state *state)
205 {
206         struct drm_framebuffer *fb = state->fb;
207         struct drm_gem_cma_object *cma_obj;
208         unsigned long eba = drm_plane_state_to_eba(state);
209
210         cma_obj = drm_fb_cma_get_gem_obj(fb, 2);
211         BUG_ON(!cma_obj);
212
213         return cma_obj->paddr + fb->offsets[2] +
214                fb->pitches[2] * (state->src_y >> 16) / 2 +
215                (state->src_x >> 16) / 2 - eba;
216 }
217
218 static void ipu_plane_atomic_set_base(struct ipu_plane *ipu_plane,
219                                       struct drm_plane_state *old_state)
220 {
221         struct drm_plane *plane = &ipu_plane->base;
222         struct drm_plane_state *state = plane->state;
223         struct drm_framebuffer *fb = state->fb;
224         unsigned long eba, ubo, vbo;
225         int active;
226
227         eba = drm_plane_state_to_eba(state);
228
229         switch (fb->pixel_format) {
230         case DRM_FORMAT_YUV420:
231         case DRM_FORMAT_YVU420:
232                 if (old_state->fb)
233                         break;
234
235                 /*
236                  * Multiplanar formats have to meet the following restrictions:
237                  * - The (up to) three plane addresses are EBA, EBA+UBO, EBA+VBO
238                  * - EBA, UBO and VBO are a multiple of 8
239                  * - UBO and VBO are unsigned and not larger than 0xfffff8
240                  * - Only EBA may be changed while scanout is active
241                  * - The strides of U and V planes must be identical.
242                  */
243                 ubo = drm_plane_state_to_ubo(state);
244                 vbo = drm_plane_state_to_vbo(state);
245
246                 if (fb->pixel_format == DRM_FORMAT_YUV420)
247                         ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch,
248                                                       fb->pitches[1], ubo, vbo);
249                 else
250                         ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch,
251                                                       fb->pitches[1], vbo, ubo);
252
253                 dev_dbg(ipu_plane->base.dev->dev,
254                         "phy = %lu %lu %lu, x = %d, y = %d", eba, ubo, vbo,
255                         state->src_x >> 16, state->src_y >> 16);
256                 break;
257         default:
258                 dev_dbg(ipu_plane->base.dev->dev, "phys = %lu, x = %d, y = %d",
259                         eba, state->src_x >> 16, state->src_y >> 16);
260
261                 break;
262         }
263
264         if (old_state->fb) {
265                 active = ipu_idmac_get_current_buffer(ipu_plane->ipu_ch);
266                 ipu_cpmem_set_buffer(ipu_plane->ipu_ch, !active, eba);
267                 ipu_idmac_select_buffer(ipu_plane->ipu_ch, !active);
268         } else {
269                 ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 0, eba);
270                 ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 1, eba);
271         }
272 }
273
274 void ipu_plane_put_resources(struct ipu_plane *ipu_plane)
275 {
276         if (!IS_ERR_OR_NULL(ipu_plane->dp))
277                 ipu_dp_put(ipu_plane->dp);
278         if (!IS_ERR_OR_NULL(ipu_plane->dmfc))
279                 ipu_dmfc_put(ipu_plane->dmfc);
280         if (!IS_ERR_OR_NULL(ipu_plane->ipu_ch))
281                 ipu_idmac_put(ipu_plane->ipu_ch);
282 }
283
284 int ipu_plane_get_resources(struct ipu_plane *ipu_plane)
285 {
286         int ret;
287
288         ipu_plane->ipu_ch = ipu_idmac_get(ipu_plane->ipu, ipu_plane->dma);
289         if (IS_ERR(ipu_plane->ipu_ch)) {
290                 ret = PTR_ERR(ipu_plane->ipu_ch);
291                 DRM_ERROR("failed to get idmac channel: %d\n", ret);
292                 return ret;
293         }
294
295         ipu_plane->dmfc = ipu_dmfc_get(ipu_plane->ipu, ipu_plane->dma);
296         if (IS_ERR(ipu_plane->dmfc)) {
297                 ret = PTR_ERR(ipu_plane->dmfc);
298                 DRM_ERROR("failed to get dmfc: ret %d\n", ret);
299                 goto err_out;
300         }
301
302         if (ipu_plane->dp_flow >= 0) {
303                 ipu_plane->dp = ipu_dp_get(ipu_plane->ipu, ipu_plane->dp_flow);
304                 if (IS_ERR(ipu_plane->dp)) {
305                         ret = PTR_ERR(ipu_plane->dp);
306                         DRM_ERROR("failed to get dp flow: %d\n", ret);
307                         goto err_out;
308                 }
309         }
310
311         return 0;
312 err_out:
313         ipu_plane_put_resources(ipu_plane);
314
315         return ret;
316 }
317
318 static void ipu_plane_enable(struct ipu_plane *ipu_plane)
319 {
320         if (ipu_plane->dp)
321                 ipu_dp_enable(ipu_plane->ipu);
322         ipu_dmfc_enable_channel(ipu_plane->dmfc);
323         ipu_idmac_enable_channel(ipu_plane->ipu_ch);
324         if (ipu_plane->dp)
325                 ipu_dp_enable_channel(ipu_plane->dp);
326 }
327
328 static void ipu_plane_disable(struct ipu_plane *ipu_plane)
329 {
330         ipu_idmac_wait_busy(ipu_plane->ipu_ch, 50);
331
332         if (ipu_plane->dp)
333                 ipu_dp_disable_channel(ipu_plane->dp);
334         ipu_idmac_disable_channel(ipu_plane->ipu_ch);
335         ipu_dmfc_disable_channel(ipu_plane->dmfc);
336         if (ipu_plane->dp)
337                 ipu_dp_disable(ipu_plane->ipu);
338 }
339
340 static int ipu_disable_plane(struct drm_plane *plane)
341 {
342         struct ipu_plane *ipu_plane = to_ipu_plane(plane);
343
344         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
345
346         ipu_plane_disable(ipu_plane);
347
348         return 0;
349 }
350
351 static void ipu_plane_destroy(struct drm_plane *plane)
352 {
353         struct ipu_plane *ipu_plane = to_ipu_plane(plane);
354
355         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
356
357         ipu_disable_plane(plane);
358         drm_plane_cleanup(plane);
359         kfree(ipu_plane);
360 }
361
362 static const struct drm_plane_funcs ipu_plane_funcs = {
363         .update_plane   = drm_plane_helper_update,
364         .disable_plane  = drm_plane_helper_disable,
365         .destroy        = ipu_plane_destroy,
366         .reset          = drm_atomic_helper_plane_reset,
367         .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
368         .atomic_destroy_state   = drm_atomic_helper_plane_destroy_state,
369 };
370
371 static int ipu_plane_atomic_check(struct drm_plane *plane,
372                                   struct drm_plane_state *state)
373 {
374         struct drm_plane_state *old_state = plane->state;
375         struct drm_crtc_state *crtc_state;
376         struct device *dev = plane->dev->dev;
377         struct drm_framebuffer *fb = state->fb;
378         struct drm_framebuffer *old_fb = old_state->fb;
379         unsigned long eba, ubo, vbo, old_ubo, old_vbo;
380
381         /* Ok to disable */
382         if (!fb)
383                 return old_fb ? 0 : -EINVAL;
384
385         /* CRTC should be enabled */
386         if (!state->crtc->enabled)
387                 return -EINVAL;
388
389         /* no scaling */
390         if (state->src_w >> 16 != state->crtc_w ||
391             state->src_h >> 16 != state->crtc_h)
392                 return -EINVAL;
393
394         crtc_state = state->crtc->state;
395
396         switch (plane->type) {
397         case DRM_PLANE_TYPE_PRIMARY:
398                 /* full plane doesn't support partial off screen */
399                 if (state->crtc_x || state->crtc_y ||
400                     state->crtc_w != crtc_state->adjusted_mode.hdisplay ||
401                     state->crtc_h != crtc_state->adjusted_mode.vdisplay)
402                         return -EINVAL;
403
404                 /* full plane minimum width is 13 pixels */
405                 if (state->crtc_w < 13)
406                         return -EINVAL;
407                 break;
408         case DRM_PLANE_TYPE_OVERLAY:
409                 if (state->crtc_x < 0 || state->crtc_y < 0)
410                         return -EINVAL;
411
412                 if (state->crtc_x + state->crtc_w >
413                     crtc_state->adjusted_mode.hdisplay)
414                         return -EINVAL;
415                 if (state->crtc_y + state->crtc_h >
416                     crtc_state->adjusted_mode.vdisplay)
417                         return -EINVAL;
418                 break;
419         default:
420                 dev_warn(dev, "Unsupported plane type\n");
421                 return -EINVAL;
422         }
423
424         if (state->crtc_h < 2)
425                 return -EINVAL;
426
427         /*
428          * since we cannot touch active IDMAC channels, we do not support
429          * resizing the enabled plane or changing its format
430          */
431         if (old_fb && (state->src_w != old_state->src_w ||
432                               state->src_h != old_state->src_h ||
433                               fb->pixel_format != old_fb->pixel_format))
434                 return -EINVAL;
435
436         eba = drm_plane_state_to_eba(state);
437
438         if (eba & 0x7)
439                 return -EINVAL;
440
441         if (fb->pitches[0] < 1 || fb->pitches[0] > 16384)
442                 return -EINVAL;
443
444         if (old_fb && fb->pitches[0] != old_fb->pitches[0])
445                 return -EINVAL;
446
447         switch (fb->pixel_format) {
448         case DRM_FORMAT_YUV420:
449         case DRM_FORMAT_YVU420:
450                 /*
451                  * Multiplanar formats have to meet the following restrictions:
452                  * - The (up to) three plane addresses are EBA, EBA+UBO, EBA+VBO
453                  * - EBA, UBO and VBO are a multiple of 8
454                  * - UBO and VBO are unsigned and not larger than 0xfffff8
455                  * - Only EBA may be changed while scanout is active
456                  * - The strides of U and V planes must be identical.
457                  */
458                 ubo = drm_plane_state_to_ubo(state);
459                 vbo = drm_plane_state_to_vbo(state);
460
461                 if ((ubo & 0x7) || (vbo & 0x7))
462                         return -EINVAL;
463
464                 if ((ubo > 0xfffff8) || (vbo > 0xfffff8))
465                         return -EINVAL;
466
467                 if (old_fb) {
468                         old_ubo = drm_plane_state_to_ubo(old_state);
469                         old_vbo = drm_plane_state_to_vbo(old_state);
470                         if (ubo != old_ubo || vbo != old_vbo)
471                                 return -EINVAL;
472                 }
473
474                 if (fb->pitches[1] != fb->pitches[2])
475                         return -EINVAL;
476
477                 if (fb->pitches[1] < 1 || fb->pitches[1] > 16384)
478                         return -EINVAL;
479
480                 if (old_fb && old_fb->pitches[1] != fb->pitches[1])
481                         return -EINVAL;
482         }
483
484         return 0;
485 }
486
487 static void ipu_plane_atomic_disable(struct drm_plane *plane,
488                                      struct drm_plane_state *old_state)
489 {
490         ipu_disable_plane(plane);
491 }
492
493 static void ipu_plane_atomic_update(struct drm_plane *plane,
494                                     struct drm_plane_state *old_state)
495 {
496         struct ipu_plane *ipu_plane = to_ipu_plane(plane);
497         struct drm_plane_state *state = plane->state;
498         enum ipu_color_space ics;
499
500         if (old_state->fb) {
501                 ipu_plane_atomic_set_base(ipu_plane, old_state);
502                 return;
503         }
504
505         switch (ipu_plane->dp_flow) {
506         case IPU_DP_FLOW_SYNC_BG:
507                 ipu_dp_setup_channel(ipu_plane->dp,
508                                         IPUV3_COLORSPACE_RGB,
509                                         IPUV3_COLORSPACE_RGB);
510                 ipu_dp_set_global_alpha(ipu_plane->dp, true, 0, true);
511                 break;
512         case IPU_DP_FLOW_SYNC_FG:
513                 ics = ipu_drm_fourcc_to_colorspace(state->fb->pixel_format);
514                 ipu_dp_setup_channel(ipu_plane->dp, ics,
515                                         IPUV3_COLORSPACE_UNKNOWN);
516                 ipu_dp_set_window_pos(ipu_plane->dp, state->crtc_x,
517                                         state->crtc_y);
518                 /* Enable local alpha on partial plane */
519                 switch (state->fb->pixel_format) {
520                 case DRM_FORMAT_ARGB1555:
521                 case DRM_FORMAT_ABGR1555:
522                 case DRM_FORMAT_RGBA5551:
523                 case DRM_FORMAT_BGRA5551:
524                 case DRM_FORMAT_ARGB4444:
525                 case DRM_FORMAT_ARGB8888:
526                 case DRM_FORMAT_ABGR8888:
527                 case DRM_FORMAT_RGBA8888:
528                 case DRM_FORMAT_BGRA8888:
529                         ipu_dp_set_global_alpha(ipu_plane->dp, false, 0, false);
530                         break;
531                 default:
532                         break;
533                 }
534         }
535
536         ipu_dmfc_config_wait4eot(ipu_plane->dmfc, state->crtc_w);
537
538         ipu_cpmem_zero(ipu_plane->ipu_ch);
539         ipu_cpmem_set_resolution(ipu_plane->ipu_ch, state->src_w >> 16,
540                                         state->src_h >> 16);
541         ipu_cpmem_set_fmt(ipu_plane->ipu_ch, state->fb->pixel_format);
542         ipu_cpmem_set_high_priority(ipu_plane->ipu_ch);
543         ipu_idmac_set_double_buffer(ipu_plane->ipu_ch, 1);
544         ipu_cpmem_set_stride(ipu_plane->ipu_ch, state->fb->pitches[0]);
545         ipu_plane_atomic_set_base(ipu_plane, old_state);
546         ipu_plane_enable(ipu_plane);
547 }
548
549 static const struct drm_plane_helper_funcs ipu_plane_helper_funcs = {
550         .atomic_check = ipu_plane_atomic_check,
551         .atomic_disable = ipu_plane_atomic_disable,
552         .atomic_update = ipu_plane_atomic_update,
553 };
554
555 struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
556                                  int dma, int dp, unsigned int possible_crtcs,
557                                  enum drm_plane_type type)
558 {
559         struct ipu_plane *ipu_plane;
560         int ret;
561
562         DRM_DEBUG_KMS("channel %d, dp flow %d, possible_crtcs=0x%x\n",
563                       dma, dp, possible_crtcs);
564
565         ipu_plane = kzalloc(sizeof(*ipu_plane), GFP_KERNEL);
566         if (!ipu_plane) {
567                 DRM_ERROR("failed to allocate plane\n");
568                 return ERR_PTR(-ENOMEM);
569         }
570
571         ipu_plane->ipu = ipu;
572         ipu_plane->dma = dma;
573         ipu_plane->dp_flow = dp;
574
575         ret = drm_universal_plane_init(dev, &ipu_plane->base, possible_crtcs,
576                                        &ipu_plane_funcs, ipu_plane_formats,
577                                        ARRAY_SIZE(ipu_plane_formats), type,
578                                        NULL);
579         if (ret) {
580                 DRM_ERROR("failed to initialize plane\n");
581                 kfree(ipu_plane);
582                 return ERR_PTR(ret);
583         }
584
585         drm_plane_helper_add(&ipu_plane->base, &ipu_plane_helper_funcs);
586
587         return ipu_plane;
588 }