Merge tag 'sunxi-fixes-for-5.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[platform/kernel/linux-starfive.git] / drivers / gpu / drm / kmb / kmb_plane.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright © 2018-2020 Intel Corporation
4  */
5
6 #include <drm/drm_atomic.h>
7 #include <drm/drm_atomic_helper.h>
8 #include <drm/drm_crtc.h>
9 #include <drm/drm_crtc_helper.h>
10 #include <drm/drm_fb_cma_helper.h>
11 #include <drm/drm_fb_helper.h>
12 #include <drm/drm_fourcc.h>
13 #include <drm/drm_gem_cma_helper.h>
14 #include <drm/drm_managed.h>
15 #include <drm/drm_plane_helper.h>
16
17 #include "kmb_drv.h"
18 #include "kmb_plane.h"
19 #include "kmb_regs.h"
20
21 const u32 layer_irqs[] = {
22         LCD_INT_VL0,
23         LCD_INT_VL1,
24         LCD_INT_GL0,
25         LCD_INT_GL1
26 };
27
28 /* Conversion (yuv->rgb) matrix from myriadx */
29 static const u32 csc_coef_lcd[] = {
30         1024, 0, 1436,
31         1024, -352, -731,
32         1024, 1814, 0,
33         -179, 125, -226
34 };
35
36 /* Graphics layer (layers 2 & 3) formats, only packed formats  are supported */
37 static const u32 kmb_formats_g[] = {
38         DRM_FORMAT_RGB332,
39         DRM_FORMAT_XRGB4444, DRM_FORMAT_XBGR4444,
40         DRM_FORMAT_ARGB4444, DRM_FORMAT_ABGR4444,
41         DRM_FORMAT_XRGB1555, DRM_FORMAT_XBGR1555,
42         DRM_FORMAT_ARGB1555, DRM_FORMAT_ABGR1555,
43         DRM_FORMAT_RGB565, DRM_FORMAT_BGR565,
44         DRM_FORMAT_RGB888, DRM_FORMAT_BGR888,
45         DRM_FORMAT_XRGB8888, DRM_FORMAT_XBGR8888,
46         DRM_FORMAT_ARGB8888, DRM_FORMAT_ABGR8888,
47 };
48
49 /* Video layer ( 0 & 1) formats, packed and planar formats are supported */
50 static const u32 kmb_formats_v[] = {
51         /* packed formats */
52         DRM_FORMAT_RGB332,
53         DRM_FORMAT_XRGB4444, DRM_FORMAT_XBGR4444,
54         DRM_FORMAT_ARGB4444, DRM_FORMAT_ABGR4444,
55         DRM_FORMAT_XRGB1555, DRM_FORMAT_XBGR1555,
56         DRM_FORMAT_ARGB1555, DRM_FORMAT_ABGR1555,
57         DRM_FORMAT_RGB565, DRM_FORMAT_BGR565,
58         DRM_FORMAT_RGB888, DRM_FORMAT_BGR888,
59         DRM_FORMAT_XRGB8888, DRM_FORMAT_XBGR8888,
60         DRM_FORMAT_ARGB8888, DRM_FORMAT_ABGR8888,
61         /*planar formats */
62         DRM_FORMAT_YUV420, DRM_FORMAT_YVU420,
63         DRM_FORMAT_YUV422, DRM_FORMAT_YVU422,
64         DRM_FORMAT_YUV444, DRM_FORMAT_YVU444,
65         DRM_FORMAT_NV12, DRM_FORMAT_NV21,
66 };
67
68 static unsigned int check_pixel_format(struct drm_plane *plane, u32 format)
69 {
70         int i;
71
72         for (i = 0; i < plane->format_count; i++) {
73                 if (plane->format_types[i] == format)
74                         return 0;
75         }
76         return -EINVAL;
77 }
78
79 static int kmb_plane_atomic_check(struct drm_plane *plane,
80                                   struct drm_atomic_state *state)
81 {
82         struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
83                                                                                  plane);
84         struct drm_framebuffer *fb;
85         int ret;
86         struct drm_crtc_state *crtc_state;
87         bool can_position;
88
89         fb = new_plane_state->fb;
90         if (!fb || !new_plane_state->crtc)
91                 return 0;
92
93         ret = check_pixel_format(plane, fb->format->format);
94         if (ret)
95                 return ret;
96
97         if (new_plane_state->crtc_w > KMB_FB_MAX_WIDTH ||
98             new_plane_state->crtc_h > KMB_FB_MAX_HEIGHT ||
99             new_plane_state->crtc_w < KMB_FB_MIN_WIDTH ||
100             new_plane_state->crtc_h < KMB_FB_MIN_HEIGHT)
101                 return -EINVAL;
102         can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY);
103         crtc_state =
104                 drm_atomic_get_existing_crtc_state(state,
105                                                    new_plane_state->crtc);
106         return drm_atomic_helper_check_plane_state(new_plane_state,
107                                                    crtc_state,
108                                                    DRM_PLANE_HELPER_NO_SCALING,
109                                                    DRM_PLANE_HELPER_NO_SCALING,
110                                                    can_position, true);
111 }
112
113 static void kmb_plane_atomic_disable(struct drm_plane *plane,
114                                      struct drm_atomic_state *state)
115 {
116         struct kmb_plane *kmb_plane = to_kmb_plane(plane);
117         int plane_id = kmb_plane->id;
118         struct kmb_drm_private *kmb;
119
120         kmb = to_kmb(plane->dev);
121
122         if (WARN_ON(plane_id >= KMB_MAX_PLANES))
123                 return;
124
125         switch (plane_id) {
126         case LAYER_0:
127                 kmb->plane_status[plane_id].ctrl = LCD_CTRL_VL1_ENABLE;
128                 break;
129         case LAYER_1:
130                 kmb->plane_status[plane_id].ctrl = LCD_CTRL_VL2_ENABLE;
131                 break;
132         case LAYER_2:
133                 kmb->plane_status[plane_id].ctrl = LCD_CTRL_GL1_ENABLE;
134                 break;
135         case LAYER_3:
136                 kmb->plane_status[plane_id].ctrl = LCD_CTRL_GL2_ENABLE;
137                 break;
138         }
139
140         kmb->plane_status[plane_id].disable = true;
141 }
142
143 static unsigned int get_pixel_format(u32 format)
144 {
145         unsigned int val = 0;
146
147         switch (format) {
148                 /* planar formats */
149         case DRM_FORMAT_YUV444:
150                 val = LCD_LAYER_FORMAT_YCBCR444PLAN | LCD_LAYER_PLANAR_STORAGE;
151                 break;
152         case DRM_FORMAT_YVU444:
153                 val = LCD_LAYER_FORMAT_YCBCR444PLAN | LCD_LAYER_PLANAR_STORAGE
154                     | LCD_LAYER_CRCB_ORDER;
155                 break;
156         case DRM_FORMAT_YUV422:
157                 val = LCD_LAYER_FORMAT_YCBCR422PLAN | LCD_LAYER_PLANAR_STORAGE;
158                 break;
159         case DRM_FORMAT_YVU422:
160                 val = LCD_LAYER_FORMAT_YCBCR422PLAN | LCD_LAYER_PLANAR_STORAGE
161                     | LCD_LAYER_CRCB_ORDER;
162                 break;
163         case DRM_FORMAT_YUV420:
164                 val = LCD_LAYER_FORMAT_YCBCR420PLAN | LCD_LAYER_PLANAR_STORAGE;
165                 break;
166         case DRM_FORMAT_YVU420:
167                 val = LCD_LAYER_FORMAT_YCBCR420PLAN | LCD_LAYER_PLANAR_STORAGE
168                     | LCD_LAYER_CRCB_ORDER;
169                 break;
170         case DRM_FORMAT_NV12:
171                 val = LCD_LAYER_FORMAT_NV12 | LCD_LAYER_PLANAR_STORAGE;
172                 break;
173         case DRM_FORMAT_NV21:
174                 val = LCD_LAYER_FORMAT_NV12 | LCD_LAYER_PLANAR_STORAGE
175                     | LCD_LAYER_CRCB_ORDER;
176                 break;
177                 /* packed formats */
178                 /* looks hw requires B & G to be swapped when RGB */
179         case DRM_FORMAT_RGB332:
180                 val = LCD_LAYER_FORMAT_RGB332 | LCD_LAYER_BGR_ORDER;
181                 break;
182         case DRM_FORMAT_XBGR4444:
183                 val = LCD_LAYER_FORMAT_RGBX4444;
184                 break;
185         case DRM_FORMAT_ARGB4444:
186                 val = LCD_LAYER_FORMAT_RGBA4444 | LCD_LAYER_BGR_ORDER;
187                 break;
188         case DRM_FORMAT_ABGR4444:
189                 val = LCD_LAYER_FORMAT_RGBA4444;
190                 break;
191         case DRM_FORMAT_XRGB1555:
192                 val = LCD_LAYER_FORMAT_XRGB1555 | LCD_LAYER_BGR_ORDER;
193                 break;
194         case DRM_FORMAT_XBGR1555:
195                 val = LCD_LAYER_FORMAT_XRGB1555;
196                 break;
197         case DRM_FORMAT_ARGB1555:
198                 val = LCD_LAYER_FORMAT_RGBA1555 | LCD_LAYER_BGR_ORDER;
199                 break;
200         case DRM_FORMAT_ABGR1555:
201                 val = LCD_LAYER_FORMAT_RGBA1555;
202                 break;
203         case DRM_FORMAT_RGB565:
204                 val = LCD_LAYER_FORMAT_RGB565 | LCD_LAYER_BGR_ORDER;
205                 break;
206         case DRM_FORMAT_BGR565:
207                 val = LCD_LAYER_FORMAT_RGB565;
208                 break;
209         case DRM_FORMAT_RGB888:
210                 val = LCD_LAYER_FORMAT_RGB888 | LCD_LAYER_BGR_ORDER;
211                 break;
212         case DRM_FORMAT_BGR888:
213                 val = LCD_LAYER_FORMAT_RGB888;
214                 break;
215         case DRM_FORMAT_XRGB8888:
216                 val = LCD_LAYER_FORMAT_RGBX8888 | LCD_LAYER_BGR_ORDER;
217                 break;
218         case DRM_FORMAT_XBGR8888:
219                 val = LCD_LAYER_FORMAT_RGBX8888;
220                 break;
221         case DRM_FORMAT_ARGB8888:
222                 val = LCD_LAYER_FORMAT_RGBA8888 | LCD_LAYER_BGR_ORDER;
223                 break;
224         case DRM_FORMAT_ABGR8888:
225                 val = LCD_LAYER_FORMAT_RGBA8888;
226                 break;
227         }
228         DRM_INFO_ONCE("%s : %d format=0x%x val=0x%x\n",
229                       __func__, __LINE__, format, val);
230         return val;
231 }
232
233 static unsigned int get_bits_per_pixel(const struct drm_format_info *format)
234 {
235         u32 bpp = 0;
236         unsigned int val = 0;
237
238         if (format->num_planes > 1) {
239                 val = LCD_LAYER_8BPP;
240                 return val;
241         }
242
243         bpp += 8 * format->cpp[0];
244
245         switch (bpp) {
246         case 8:
247                 val = LCD_LAYER_8BPP;
248                 break;
249         case 16:
250                 val = LCD_LAYER_16BPP;
251                 break;
252         case 24:
253                 val = LCD_LAYER_24BPP;
254                 break;
255         case 32:
256                 val = LCD_LAYER_32BPP;
257                 break;
258         }
259
260         DRM_DEBUG("bpp=%d val=0x%x\n", bpp, val);
261         return val;
262 }
263
264 static void config_csc(struct kmb_drm_private *kmb, int plane_id)
265 {
266         /* YUV to RGB conversion using the fixed matrix csc_coef_lcd */
267         kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF11(plane_id), csc_coef_lcd[0]);
268         kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF12(plane_id), csc_coef_lcd[1]);
269         kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF13(plane_id), csc_coef_lcd[2]);
270         kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF21(plane_id), csc_coef_lcd[3]);
271         kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF22(plane_id), csc_coef_lcd[4]);
272         kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF23(plane_id), csc_coef_lcd[5]);
273         kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF31(plane_id), csc_coef_lcd[6]);
274         kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF32(plane_id), csc_coef_lcd[7]);
275         kmb_write_lcd(kmb, LCD_LAYERn_CSC_COEFF33(plane_id), csc_coef_lcd[8]);
276         kmb_write_lcd(kmb, LCD_LAYERn_CSC_OFF1(plane_id), csc_coef_lcd[9]);
277         kmb_write_lcd(kmb, LCD_LAYERn_CSC_OFF2(plane_id), csc_coef_lcd[10]);
278         kmb_write_lcd(kmb, LCD_LAYERn_CSC_OFF3(plane_id), csc_coef_lcd[11]);
279 }
280
281 static void kmb_plane_set_alpha(struct kmb_drm_private *kmb,
282                                 const struct drm_plane_state *state,
283                                 unsigned char plane_id,
284                                 unsigned int *val)
285 {
286         u16 plane_alpha = state->alpha;
287         u16 pixel_blend_mode = state->pixel_blend_mode;
288         int has_alpha = state->fb->format->has_alpha;
289
290         if (plane_alpha != DRM_BLEND_ALPHA_OPAQUE)
291                 *val |= LCD_LAYER_ALPHA_STATIC;
292
293         if (has_alpha) {
294                 switch (pixel_blend_mode) {
295                 case DRM_MODE_BLEND_PIXEL_NONE:
296                         break;
297                 case DRM_MODE_BLEND_PREMULTI:
298                         *val |= LCD_LAYER_ALPHA_EMBED | LCD_LAYER_ALPHA_PREMULT;
299                         break;
300                 case DRM_MODE_BLEND_COVERAGE:
301                         *val |= LCD_LAYER_ALPHA_EMBED;
302                         break;
303                 default:
304                         DRM_DEBUG("Missing pixel blend mode case (%s == %ld)\n",
305                                   __stringify(pixel_blend_mode),
306                                   (long)pixel_blend_mode);
307                         break;
308                 }
309         }
310
311         if (plane_alpha == DRM_BLEND_ALPHA_OPAQUE && !has_alpha) {
312                 *val &= LCD_LAYER_ALPHA_DISABLED;
313                 return;
314         }
315
316         kmb_write_lcd(kmb, LCD_LAYERn_ALPHA(plane_id), plane_alpha);
317 }
318
319 static void kmb_plane_atomic_update(struct drm_plane *plane,
320                                     struct drm_atomic_state *state)
321 {
322         struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state,
323                                                                                  plane);
324         struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
325                                                                                  plane);
326         struct drm_framebuffer *fb;
327         struct kmb_drm_private *kmb;
328         unsigned int width;
329         unsigned int height;
330         unsigned int dma_len;
331         struct kmb_plane *kmb_plane;
332         unsigned int dma_cfg;
333         unsigned int ctrl = 0, val = 0, out_format = 0;
334         unsigned int src_w, src_h, crtc_x, crtc_y;
335         unsigned char plane_id;
336         int num_planes;
337         static dma_addr_t addr[MAX_SUB_PLANES];
338
339         if (!plane || !new_plane_state || !old_plane_state)
340                 return;
341
342         fb = new_plane_state->fb;
343         if (!fb)
344                 return;
345
346         num_planes = fb->format->num_planes;
347         kmb_plane = to_kmb_plane(plane);
348
349         kmb = to_kmb(plane->dev);
350         plane_id = kmb_plane->id;
351
352         spin_lock_irq(&kmb->irq_lock);
353         if (kmb->kmb_under_flow || kmb->kmb_flush_done) {
354                 spin_unlock_irq(&kmb->irq_lock);
355                 drm_dbg(&kmb->drm, "plane_update:underflow!!!! returning");
356                 return;
357         }
358         spin_unlock_irq(&kmb->irq_lock);
359
360         src_w = (new_plane_state->src_w >> 16);
361         src_h = new_plane_state->src_h >> 16;
362         crtc_x = new_plane_state->crtc_x;
363         crtc_y = new_plane_state->crtc_y;
364
365         drm_dbg(&kmb->drm,
366                 "src_w=%d src_h=%d, fb->format->format=0x%x fb->flags=0x%x\n",
367                   src_w, src_h, fb->format->format, fb->flags);
368
369         width = fb->width;
370         height = fb->height;
371         dma_len = (width * height * fb->format->cpp[0]);
372         drm_dbg(&kmb->drm, "dma_len=%d ", dma_len);
373         kmb_write_lcd(kmb, LCD_LAYERn_DMA_LEN(plane_id), dma_len);
374         kmb_write_lcd(kmb, LCD_LAYERn_DMA_LEN_SHADOW(plane_id), dma_len);
375         kmb_write_lcd(kmb, LCD_LAYERn_DMA_LINE_VSTRIDE(plane_id),
376                       fb->pitches[0]);
377         kmb_write_lcd(kmb, LCD_LAYERn_DMA_LINE_WIDTH(plane_id),
378                       (width * fb->format->cpp[0]));
379
380         addr[Y_PLANE] = drm_fb_cma_get_gem_addr(fb, new_plane_state, 0);
381         kmb_write_lcd(kmb, LCD_LAYERn_DMA_START_ADDR(plane_id),
382                       addr[Y_PLANE] + fb->offsets[0]);
383         val = get_pixel_format(fb->format->format);
384         val |= get_bits_per_pixel(fb->format);
385         /* Program Cb/Cr for planar formats */
386         if (num_planes > 1) {
387                 kmb_write_lcd(kmb, LCD_LAYERn_DMA_CB_LINE_VSTRIDE(plane_id),
388                               width * fb->format->cpp[0]);
389                 kmb_write_lcd(kmb, LCD_LAYERn_DMA_CB_LINE_WIDTH(plane_id),
390                               (width * fb->format->cpp[0]));
391
392                 addr[U_PLANE] = drm_fb_cma_get_gem_addr(fb, new_plane_state,
393                                                         U_PLANE);
394                 /* check if Cb/Cr is swapped*/
395                 if (num_planes == 3 && (val & LCD_LAYER_CRCB_ORDER))
396                         kmb_write_lcd(kmb,
397                                       LCD_LAYERn_DMA_START_CR_ADR(plane_id),
398                                         addr[U_PLANE]);
399                 else
400                         kmb_write_lcd(kmb,
401                                       LCD_LAYERn_DMA_START_CB_ADR(plane_id),
402                                         addr[U_PLANE]);
403
404                 if (num_planes == 3) {
405                         kmb_write_lcd(kmb,
406                                       LCD_LAYERn_DMA_CR_LINE_VSTRIDE(plane_id),
407                                       ((width) * fb->format->cpp[0]));
408
409                         kmb_write_lcd(kmb,
410                                       LCD_LAYERn_DMA_CR_LINE_WIDTH(plane_id),
411                                       ((width) * fb->format->cpp[0]));
412
413                         addr[V_PLANE] = drm_fb_cma_get_gem_addr(fb,
414                                                                 new_plane_state,
415                                                                 V_PLANE);
416
417                         /* check if Cb/Cr is swapped*/
418                         if (val & LCD_LAYER_CRCB_ORDER)
419                                 kmb_write_lcd(kmb,
420                                               LCD_LAYERn_DMA_START_CB_ADR(plane_id),
421                                               addr[V_PLANE]);
422                         else
423                                 kmb_write_lcd(kmb,
424                                               LCD_LAYERn_DMA_START_CR_ADR(plane_id),
425                                               addr[V_PLANE]);
426                 }
427         }
428
429         kmb_write_lcd(kmb, LCD_LAYERn_WIDTH(plane_id), src_w - 1);
430         kmb_write_lcd(kmb, LCD_LAYERn_HEIGHT(plane_id), src_h - 1);
431         kmb_write_lcd(kmb, LCD_LAYERn_COL_START(plane_id), crtc_x);
432         kmb_write_lcd(kmb, LCD_LAYERn_ROW_START(plane_id), crtc_y);
433
434         val |= LCD_LAYER_FIFO_100;
435
436         if (val & LCD_LAYER_PLANAR_STORAGE) {
437                 val |= LCD_LAYER_CSC_EN;
438
439                 /* Enable CSC if input is planar and output is RGB */
440                 config_csc(kmb, plane_id);
441         }
442
443         kmb_plane_set_alpha(kmb, plane->state, plane_id, &val);
444
445         kmb_write_lcd(kmb, LCD_LAYERn_CFG(plane_id), val);
446
447         /* Configure LCD_CONTROL */
448         ctrl = kmb_read_lcd(kmb, LCD_CONTROL);
449
450         /* Set layer blending config */
451         ctrl &= ~LCD_CTRL_ALPHA_ALL;
452         ctrl |= LCD_CTRL_ALPHA_BOTTOM_VL1 |
453                 LCD_CTRL_ALPHA_BLEND_VL2;
454
455         ctrl &= ~LCD_CTRL_ALPHA_BLEND_BKGND_DISABLE;
456
457         switch (plane_id) {
458         case LAYER_0:
459                 ctrl |= LCD_CTRL_VL1_ENABLE;
460                 break;
461         case LAYER_1:
462                 ctrl |= LCD_CTRL_VL2_ENABLE;
463                 break;
464         case LAYER_2:
465                 ctrl |= LCD_CTRL_GL1_ENABLE;
466                 break;
467         case LAYER_3:
468                 ctrl |= LCD_CTRL_GL2_ENABLE;
469                 break;
470         }
471
472         ctrl |= LCD_CTRL_PROGRESSIVE | LCD_CTRL_TIM_GEN_ENABLE
473             | LCD_CTRL_CONTINUOUS | LCD_CTRL_OUTPUT_ENABLED;
474
475         /* LCD is connected to MIPI on kmb
476          * Therefore this bit is required for DSI Tx
477          */
478         ctrl |= LCD_CTRL_VHSYNC_IDLE_LVL;
479
480         kmb_write_lcd(kmb, LCD_CONTROL, ctrl);
481
482         /* Enable pipeline AXI read transactions for the DMA
483          * after setting graphics layers. This must be done
484          * in a separate write cycle.
485          */
486         kmb_set_bitmask_lcd(kmb, LCD_CONTROL, LCD_CTRL_PIPELINE_DMA);
487
488         /* FIXME no doc on how to set output format, these values are taken
489          * from the Myriadx tests
490          */
491         out_format |= LCD_OUTF_FORMAT_RGB888;
492
493         /* Leave RGB order,conversion mode and clip mode to default */
494         /* do not interleave RGB channels for mipi Tx compatibility */
495         out_format |= LCD_OUTF_MIPI_RGB_MODE;
496         kmb_write_lcd(kmb, LCD_OUT_FORMAT_CFG, out_format);
497
498         dma_cfg = LCD_DMA_LAYER_ENABLE | LCD_DMA_LAYER_VSTRIDE_EN |
499             LCD_DMA_LAYER_CONT_UPDATE | LCD_DMA_LAYER_AXI_BURST_16;
500
501         /* Enable DMA */
502         kmb_write_lcd(kmb, LCD_LAYERn_DMA_CFG(plane_id), dma_cfg);
503         drm_dbg(&kmb->drm, "dma_cfg=0x%x LCD_DMA_CFG=0x%x\n", dma_cfg,
504                 kmb_read_lcd(kmb, LCD_LAYERn_DMA_CFG(plane_id)));
505
506         kmb_set_bitmask_lcd(kmb, LCD_INT_CLEAR, LCD_INT_EOF |
507                         LCD_INT_DMA_ERR);
508         kmb_set_bitmask_lcd(kmb, LCD_INT_ENABLE, LCD_INT_EOF |
509                         LCD_INT_DMA_ERR);
510 }
511
512 static const struct drm_plane_helper_funcs kmb_plane_helper_funcs = {
513         .atomic_check = kmb_plane_atomic_check,
514         .atomic_update = kmb_plane_atomic_update,
515         .atomic_disable = kmb_plane_atomic_disable
516 };
517
518 void kmb_plane_destroy(struct drm_plane *plane)
519 {
520         struct kmb_plane *kmb_plane = to_kmb_plane(plane);
521
522         drm_plane_cleanup(plane);
523         kfree(kmb_plane);
524 }
525
526 static const struct drm_plane_funcs kmb_plane_funcs = {
527         .update_plane = drm_atomic_helper_update_plane,
528         .disable_plane = drm_atomic_helper_disable_plane,
529         .destroy = kmb_plane_destroy,
530         .reset = drm_atomic_helper_plane_reset,
531         .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
532         .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
533 };
534
535 struct kmb_plane *kmb_plane_init(struct drm_device *drm)
536 {
537         struct kmb_drm_private *kmb = to_kmb(drm);
538         struct kmb_plane *plane = NULL;
539         struct kmb_plane *primary = NULL;
540         int i = 0;
541         int ret = 0;
542         enum drm_plane_type plane_type;
543         const u32 *plane_formats;
544         int num_plane_formats;
545         unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
546                                   BIT(DRM_MODE_BLEND_PREMULTI)   |
547                                   BIT(DRM_MODE_BLEND_COVERAGE);
548
549         for (i = 0; i < KMB_MAX_PLANES; i++) {
550                 plane = drmm_kzalloc(drm, sizeof(*plane), GFP_KERNEL);
551
552                 if (!plane) {
553                         drm_err(drm, "Failed to allocate plane\n");
554                         return ERR_PTR(-ENOMEM);
555                 }
556
557                 plane_type = (i == 0) ? DRM_PLANE_TYPE_PRIMARY :
558                     DRM_PLANE_TYPE_OVERLAY;
559                 if (i < 2) {
560                         plane_formats = kmb_formats_v;
561                         num_plane_formats = ARRAY_SIZE(kmb_formats_v);
562                 } else {
563                         plane_formats = kmb_formats_g;
564                         num_plane_formats = ARRAY_SIZE(kmb_formats_g);
565                 }
566
567                 ret = drm_universal_plane_init(drm, &plane->base_plane,
568                                                POSSIBLE_CRTCS, &kmb_plane_funcs,
569                                                plane_formats, num_plane_formats,
570                                                NULL, plane_type, "plane %d", i);
571                 if (ret < 0) {
572                         drm_err(drm, "drm_universal_plane_init failed (ret=%d)",
573                                 ret);
574                         goto cleanup;
575                 }
576                 drm_dbg(drm, "%s : %d i=%d type=%d",
577                         __func__, __LINE__,
578                           i, plane_type);
579                 drm_plane_create_alpha_property(&plane->base_plane);
580
581                 drm_plane_create_blend_mode_property(&plane->base_plane,
582                                                      blend_caps);
583
584                 drm_plane_create_zpos_immutable_property(&plane->base_plane, i);
585
586                 drm_plane_helper_add(&plane->base_plane,
587                                      &kmb_plane_helper_funcs);
588
589                 if (plane_type == DRM_PLANE_TYPE_PRIMARY) {
590                         primary = plane;
591                         kmb->plane = plane;
592                 }
593                 drm_dbg(drm, "%s : %d primary=%p\n", __func__, __LINE__,
594                         &primary->base_plane);
595                 plane->id = i;
596         }
597
598         /* Disable pipeline AXI read transactions for the DMA
599          * prior to setting graphics layers
600          */
601         kmb_clr_bitmask_lcd(kmb, LCD_CONTROL, LCD_CTRL_PIPELINE_DMA);
602
603         return primary;
604 cleanup:
605         drmm_kfree(drm, plane);
606         return ERR_PTR(ret);
607 }