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