xref: /openbmc/linux/drivers/gpu/drm/kmb/kmb_plane.c (revision b9221f71)
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 }
608