Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eae13c93 authored by Philipp Zabel's avatar Philipp Zabel
Browse files

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
Loading
Loading
Loading
Loading
+47 −13
Original line number Diff line number Diff line
@@ -50,6 +50,12 @@ static const uint32_t ipu_plane_formats[] = {
	DRM_FORMAT_YVYU,
	DRM_FORMAT_YUV420,
	DRM_FORMAT_YVU420,
	DRM_FORMAT_YUV422,
	DRM_FORMAT_YVU422,
	DRM_FORMAT_YUV444,
	DRM_FORMAT_YVU444,
	DRM_FORMAT_NV12,
	DRM_FORMAT_NV16,
	DRM_FORMAT_RGB565,
};

@@ -292,6 +298,10 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
	switch (fb->pixel_format) {
	case DRM_FORMAT_YUV420:
	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:
		 * - 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,
		 * - Only EBA may be changed while scanout is active
		 * - The strides of U and V planes must be identical.
		 */
		ubo = drm_plane_state_to_ubo(state);
		vbo = drm_plane_state_to_vbo(state);

		if ((ubo & 0x7) || (vbo & 0x7))
			return -EINVAL;

		if ((ubo > 0xfffff8) || (vbo > 0xfffff8))
		if (vbo & 0x7 || vbo > 0xfffff8)
			return -EINVAL;

		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);
			if (ubo != old_ubo || vbo != old_vbo)
			if (vbo != old_vbo)
				crtc_state->mode_changed = true;
		}

		if (fb->pitches[1] != fb->pitches[2])
			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)
			return -EINVAL;

@@ -409,20 +428,35 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
	switch (fb->pixel_format) {
	case DRM_FORMAT_YUV420:
	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);
		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,
					      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,
			"phy = %lu %lu %lu, x = %d, y = %d", eba, ubo, vbo,
			state->src_x >> 16, state->src_y >> 16);
		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:
		dev_dbg(ipu_plane->base.dev->dev, "phys = %lu, x = %d, y = %d",
			eba, state->src_x >> 16, state->src_y >> 16);