diff options
author | Philipp Zabel <p.zabel@pengutronix.de> | 2016-10-18 06:31:40 -0400 |
---|---|---|
committer | Philipp Zabel <p.zabel@pengutronix.de> | 2016-10-20 08:40:12 -0400 |
commit | eae13c9337e2bba0f59b1723114e73be18499c5b (patch) | |
tree | 753c3cd25f585958f739bbdd9773f69d6292b280 | |
parent | c9d508c2df04af001c62e4fe86593aabe42ae718 (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.c | 60 |
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); |