Commit eae13c93 authored by Philipp Zabel's avatar Philipp Zabel

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: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
Acked-by: default avatarLiu Ying <gnuiyl@gmail.com>
parent c9d508c2
...@@ -50,6 +50,12 @@ static const uint32_t ipu_plane_formats[] = { ...@@ -50,6 +50,12 @@ static const uint32_t ipu_plane_formats[] = {
DRM_FORMAT_YVYU, DRM_FORMAT_YVYU,
DRM_FORMAT_YUV420, DRM_FORMAT_YUV420,
DRM_FORMAT_YVU420, DRM_FORMAT_YVU420,
DRM_FORMAT_YUV422,
DRM_FORMAT_YVU422,
DRM_FORMAT_YUV444,
DRM_FORMAT_YVU444,
DRM_FORMAT_NV12,
DRM_FORMAT_NV16,
DRM_FORMAT_RGB565, DRM_FORMAT_RGB565,
}; };
...@@ -292,6 +298,10 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, ...@@ -292,6 +298,10 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
switch (fb->pixel_format) { switch (fb->pixel_format) {
case DRM_FORMAT_YUV420: case DRM_FORMAT_YUV420:
case DRM_FORMAT_YVU420: case DRM_FORMAT_YVU420:
case DRM_FORMAT_YUV422:
case DRM_FORMAT_YVU422:
case DRM_FORMAT_YUV444:
case DRM_FORMAT_YVU444:
/* /*
* Multiplanar formats have to meet the following restrictions: * Multiplanar formats have to meet the following restrictions:
* - The (up to) three plane addresses are EBA, EBA+UBO, EBA+VBO * - 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,25 +310,34 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
* - Only EBA may be changed while scanout is active * - Only EBA may be changed while scanout is active
* - The strides of U and V planes must be identical. * - The strides of U and V planes must be identical.
*/ */
ubo = drm_plane_state_to_ubo(state);
vbo = drm_plane_state_to_vbo(state); vbo = drm_plane_state_to_vbo(state);
if ((ubo & 0x7) || (vbo & 0x7)) if (vbo & 0x7 || vbo > 0xfffff8)
return -EINVAL;
if ((ubo > 0xfffff8) || (vbo > 0xfffff8))
return -EINVAL; return -EINVAL;
if (old_fb && (fb->pixel_format == old_fb->pixel_format)) { if (old_fb && (fb->pixel_format == old_fb->pixel_format)) {
old_ubo = drm_plane_state_to_ubo(old_state);
old_vbo = drm_plane_state_to_vbo(old_state); old_vbo = drm_plane_state_to_vbo(old_state);
if (ubo != old_ubo || vbo != old_vbo) if (vbo != old_vbo)
crtc_state->mode_changed = true; crtc_state->mode_changed = true;
} }
if (fb->pitches[1] != fb->pitches[2]) if (fb->pitches[1] != fb->pitches[2])
return -EINVAL; return -EINVAL;
/* fall-through */
case DRM_FORMAT_NV12:
case DRM_FORMAT_NV16:
ubo = drm_plane_state_to_ubo(state);
if (ubo & 0x7 || ubo > 0xfffff8)
return -EINVAL;
if (old_fb && (fb->pixel_format == old_fb->pixel_format)) {
old_ubo = drm_plane_state_to_ubo(old_state);
if (ubo != old_ubo)
crtc_state->mode_changed = true;
}
if (fb->pitches[1] < 1 || fb->pitches[1] > 16384) if (fb->pitches[1] < 1 || fb->pitches[1] > 16384)
return -EINVAL; return -EINVAL;
...@@ -409,20 +428,35 @@ static void ipu_plane_atomic_update(struct drm_plane *plane, ...@@ -409,20 +428,35 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
switch (fb->pixel_format) { switch (fb->pixel_format) {
case DRM_FORMAT_YUV420: case DRM_FORMAT_YUV420:
case DRM_FORMAT_YVU420: case DRM_FORMAT_YVU420:
case DRM_FORMAT_YUV422:
case DRM_FORMAT_YVU422:
case DRM_FORMAT_YUV444:
case DRM_FORMAT_YVU444:
ubo = drm_plane_state_to_ubo(state); ubo = drm_plane_state_to_ubo(state);
vbo = drm_plane_state_to_vbo(state); vbo = drm_plane_state_to_vbo(state);
if (fb->pixel_format == DRM_FORMAT_YVU420 ||
fb->pixel_format == DRM_FORMAT_YVU422 ||
fb->pixel_format == DRM_FORMAT_YVU444)
swap(ubo, vbo);
if (fb->pixel_format == DRM_FORMAT_YUV420) ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch,
ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch, fb->pitches[1], ubo, vbo);
fb->pitches[1], ubo, vbo);
else
ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch,
fb->pitches[1], vbo, ubo);
dev_dbg(ipu_plane->base.dev->dev, dev_dbg(ipu_plane->base.dev->dev,
"phy = %lu %lu %lu, x = %d, y = %d", eba, ubo, vbo, "phy = %lu %lu %lu, x = %d, y = %d", eba, ubo, vbo,
state->src_x >> 16, state->src_y >> 16); state->src_x >> 16, state->src_y >> 16);
break; break;
case DRM_FORMAT_NV12:
case DRM_FORMAT_NV16:
ubo = drm_plane_state_to_ubo(state);
ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch,
fb->pitches[1], ubo, ubo);
dev_dbg(ipu_plane->base.dev->dev,
"phy = %lu %lu, x = %d, y = %d", eba, ubo,
state->src_x >> 16, state->src_y >> 16);
break;
default: default:
dev_dbg(ipu_plane->base.dev->dev, "phys = %lu, x = %d, y = %d", dev_dbg(ipu_plane->base.dev->dev, "phys = %lu, x = %d, y = %d",
eba, state->src_x >> 16, state->src_y >> 16); eba, state->src_x >> 16, state->src_y >> 16);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment