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