aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Zabel <p.zabel@pengutronix.de>2016-10-18 06:31:40 -0400
committerPhilipp Zabel <p.zabel@pengutronix.de>2016-10-20 08:40:12 -0400
commiteae13c9337e2bba0f59b1723114e73be18499c5b (patch)
tree753c3cd25f585958f739bbdd9773f69d6292b280
parentc9d508c2df04af001c62e4fe86593aabe42ae718 (diff)
drm/imx: ipuv3-plane: add support for YUV 4:2:2 and 4:4:4, NV12, and NV16 formats
Hook up support for DRM_FORMAT_YUV422, DRM_FORMAT_YVU422, DRM_FORMAT_YUV444, DRM_FORMAT_YVU444, DRM_FORMAT_NV12, and DRM_FORMAT_NV16. Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> Acked-by: Liu Ying <gnuiyl@gmail.com>
-rw-r--r--drivers/gpu/drm/imx/ipuv3-plane.c60
1 files changed, 47 insertions, 13 deletions
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
index 52784cb6bee4..6a97e396fce3 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -50,6 +50,12 @@ static const uint32_t ipu_plane_formats[] = {
50 DRM_FORMAT_YVYU, 50 DRM_FORMAT_YVYU,
51 DRM_FORMAT_YUV420, 51 DRM_FORMAT_YUV420,
52 DRM_FORMAT_YVU420, 52 DRM_FORMAT_YVU420,
53 DRM_FORMAT_YUV422,
54 DRM_FORMAT_YVU422,
55 DRM_FORMAT_YUV444,
56 DRM_FORMAT_YVU444,
57 DRM_FORMAT_NV12,
58 DRM_FORMAT_NV16,
53 DRM_FORMAT_RGB565, 59 DRM_FORMAT_RGB565,
54}; 60};
55 61
@@ -292,6 +298,10 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
292 switch (fb->pixel_format) { 298 switch (fb->pixel_format) {
293 case DRM_FORMAT_YUV420: 299 case DRM_FORMAT_YUV420:
294 case DRM_FORMAT_YVU420: 300 case DRM_FORMAT_YVU420:
301 case DRM_FORMAT_YUV422:
302 case DRM_FORMAT_YVU422:
303 case DRM_FORMAT_YUV444:
304 case DRM_FORMAT_YVU444:
295 /* 305 /*
296 * Multiplanar formats have to meet the following restrictions: 306 * Multiplanar formats have to meet the following restrictions:
297 * - The (up to) three plane addresses are EBA, EBA+UBO, EBA+VBO 307 * - The (up to) three plane addresses are EBA, EBA+UBO, EBA+VBO
@@ -300,25 +310,34 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
300 * - Only EBA may be changed while scanout is active 310 * - Only EBA may be changed while scanout is active
301 * - The strides of U and V planes must be identical. 311 * - The strides of U and V planes must be identical.
302 */ 312 */
303 ubo = drm_plane_state_to_ubo(state);
304 vbo = drm_plane_state_to_vbo(state); 313 vbo = drm_plane_state_to_vbo(state);
305 314
306 if ((ubo & 0x7) || (vbo & 0x7)) 315 if (vbo & 0x7 || vbo > 0xfffff8)
307 return -EINVAL;
308
309 if ((ubo > 0xfffff8) || (vbo > 0xfffff8))
310 return -EINVAL; 316 return -EINVAL;
311 317
312 if (old_fb && (fb->pixel_format == old_fb->pixel_format)) { 318 if (old_fb && (fb->pixel_format == old_fb->pixel_format)) {
313 old_ubo = drm_plane_state_to_ubo(old_state);
314 old_vbo = drm_plane_state_to_vbo(old_state); 319 old_vbo = drm_plane_state_to_vbo(old_state);
315 if (ubo != old_ubo || vbo != old_vbo) 320 if (vbo != old_vbo)
316 crtc_state->mode_changed = true; 321 crtc_state->mode_changed = true;
317 } 322 }
318 323
319 if (fb->pitches[1] != fb->pitches[2]) 324 if (fb->pitches[1] != fb->pitches[2])
320 return -EINVAL; 325 return -EINVAL;
321 326
327 /* fall-through */
328 case DRM_FORMAT_NV12:
329 case DRM_FORMAT_NV16:
330 ubo = drm_plane_state_to_ubo(state);
331
332 if (ubo & 0x7 || ubo > 0xfffff8)
333 return -EINVAL;
334
335 if (old_fb && (fb->pixel_format == old_fb->pixel_format)) {
336 old_ubo = drm_plane_state_to_ubo(old_state);
337 if (ubo != old_ubo)
338 crtc_state->mode_changed = true;
339 }
340
322 if (fb->pitches[1] < 1 || fb->pitches[1] > 16384) 341 if (fb->pitches[1] < 1 || fb->pitches[1] > 16384)
323 return -EINVAL; 342 return -EINVAL;
324 343
@@ -409,20 +428,35 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
409 switch (fb->pixel_format) { 428 switch (fb->pixel_format) {
410 case DRM_FORMAT_YUV420: 429 case DRM_FORMAT_YUV420:
411 case DRM_FORMAT_YVU420: 430 case DRM_FORMAT_YVU420:
431 case DRM_FORMAT_YUV422:
432 case DRM_FORMAT_YVU422:
433 case DRM_FORMAT_YUV444:
434 case DRM_FORMAT_YVU444:
412 ubo = drm_plane_state_to_ubo(state); 435 ubo = drm_plane_state_to_ubo(state);
413 vbo = drm_plane_state_to_vbo(state); 436 vbo = drm_plane_state_to_vbo(state);
437 if (fb->pixel_format == DRM_FORMAT_YVU420 ||
438 fb->pixel_format == DRM_FORMAT_YVU422 ||
439 fb->pixel_format == DRM_FORMAT_YVU444)
440 swap(ubo, vbo);
414 441
415 if (fb->pixel_format == DRM_FORMAT_YUV420) 442 ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch,
416 ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch, 443 fb->pitches[1], ubo, vbo);
417 fb->pitches[1], ubo, vbo);
418 else
419 ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch,
420 fb->pitches[1], vbo, ubo);
421 444
422 dev_dbg(ipu_plane->base.dev->dev, 445 dev_dbg(ipu_plane->base.dev->dev,
423 "phy = %lu %lu %lu, x = %d, y = %d", eba, ubo, vbo, 446 "phy = %lu %lu %lu, x = %d, y = %d", eba, ubo, vbo,
424 state->src_x >> 16, state->src_y >> 16); 447 state->src_x >> 16, state->src_y >> 16);
425 break; 448 break;
449 case DRM_FORMAT_NV12:
450 case DRM_FORMAT_NV16:
451 ubo = drm_plane_state_to_ubo(state);
452
453 ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch,
454 fb->pitches[1], ubo, ubo);
455
456 dev_dbg(ipu_plane->base.dev->dev,
457 "phy = %lu %lu, x = %d, y = %d", eba, ubo,
458 state->src_x >> 16, state->src_y >> 16);
459 break;
426 default: 460 default:
427 dev_dbg(ipu_plane->base.dev->dev, "phys = %lu, x = %d, y = %d", 461 dev_dbg(ipu_plane->base.dev->dev, "phys = %lu, x = %d, y = %d",
428 eba, state->src_x >> 16, state->src_y >> 16); 462 eba, state->src_x >> 16, state->src_y >> 16);