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