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