Unverified Commit d619f38c authored by Dave Stevenson's avatar Dave Stevenson Committed by Maxime Ripard
Browse files

drm/vc4: plane: Add support for YUV color encodings and ranges



The BT601/BT709 color encoding and limited vs full
range properties were not being exposed, defaulting
always to BT601 limited range.

Expose the parameters and set the registers appropriately.

Signed-off-by: default avatarDave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
Acked-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Link: https://lore.kernel.org/r/20211215091739.135042-4-maxime@cerno.tech
parent 145b42fb
Loading
Loading
Loading
Loading
+68 −3
Original line number Diff line number Diff line
@@ -623,6 +623,51 @@ static int vc4_plane_allocate_lbm(struct drm_plane_state *state)
	return 0;
}

/*
 * The colorspace conversion matrices are held in 3 entries in the dlist.
 * Create an array of them, with entries for each full and limited mode, and
 * each supported colorspace.
 */
static const u32 colorspace_coeffs[2][DRM_COLOR_ENCODING_MAX][3] = {
	{
		/* Limited range */
		{
			/* BT601 */
			SCALER_CSC0_ITR_R_601_5,
			SCALER_CSC1_ITR_R_601_5,
			SCALER_CSC2_ITR_R_601_5,
		}, {
			/* BT709 */
			SCALER_CSC0_ITR_R_709_3,
			SCALER_CSC1_ITR_R_709_3,
			SCALER_CSC2_ITR_R_709_3,
		}, {
			/* BT2020 */
			SCALER_CSC0_ITR_R_2020,
			SCALER_CSC1_ITR_R_2020,
			SCALER_CSC2_ITR_R_2020,
		}
	}, {
		/* Full range */
		{
			/* JFIF */
			SCALER_CSC0_JPEG_JFIF,
			SCALER_CSC1_JPEG_JFIF,
			SCALER_CSC2_JPEG_JFIF,
		}, {
			/* BT709 */
			SCALER_CSC0_ITR_R_709_3_FR,
			SCALER_CSC1_ITR_R_709_3_FR,
			SCALER_CSC2_ITR_R_709_3_FR,
		}, {
			/* BT2020 */
			SCALER_CSC0_ITR_R_2020_FR,
			SCALER_CSC1_ITR_R_2020_FR,
			SCALER_CSC2_ITR_R_2020_FR,
		}
	}
};

/* Writes out a full display list for an active plane to the plane's
 * private dlist state.
 */
@@ -1017,9 +1062,20 @@ static int vc4_plane_mode_set(struct drm_plane *plane,

	/* Colorspace conversion words */
	if (vc4_state->is_yuv) {
		vc4_dlist_write(vc4_state, SCALER_CSC0_ITR_R_601_5);
		vc4_dlist_write(vc4_state, SCALER_CSC1_ITR_R_601_5);
		vc4_dlist_write(vc4_state, SCALER_CSC2_ITR_R_601_5);
		enum drm_color_encoding color_encoding = state->color_encoding;
		enum drm_color_range color_range = state->color_range;
		const u32 *ccm;

		if (color_encoding >= DRM_COLOR_ENCODING_MAX)
			color_encoding = DRM_COLOR_YCBCR_BT601;
		if (color_range >= DRM_COLOR_RANGE_MAX)
			color_range = DRM_COLOR_YCBCR_LIMITED_RANGE;

		ccm = colorspace_coeffs[color_range][color_encoding];

		vc4_dlist_write(vc4_state, ccm[0]);
		vc4_dlist_write(vc4_state, ccm[1]);
		vc4_dlist_write(vc4_state, ccm[2]);
	}

	vc4_state->lbm_offset = 0;
@@ -1448,6 +1504,15 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
					   DRM_MODE_REFLECT_X |
					   DRM_MODE_REFLECT_Y);

	drm_plane_create_color_properties(plane,
					  BIT(DRM_COLOR_YCBCR_BT601) |
					  BIT(DRM_COLOR_YCBCR_BT709) |
					  BIT(DRM_COLOR_YCBCR_BT2020),
					  BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
					  BIT(DRM_COLOR_YCBCR_FULL_RANGE),
					  DRM_COLOR_YCBCR_BT709,
					  DRM_COLOR_YCBCR_LIMITED_RANGE);

	return plane;
}

+14 −5
Original line number Diff line number Diff line
@@ -975,7 +975,10 @@ enum hvs_pixel_format {
#define SCALER_CSC0_COEF_CR_OFS_SHIFT		0
#define SCALER_CSC0_ITR_R_601_5			0x00f00000
#define SCALER_CSC0_ITR_R_709_3			0x00f00000
#define SCALER_CSC0_ITR_R_2020			0x00f00000
#define SCALER_CSC0_JPEG_JFIF			0x00000000
#define SCALER_CSC0_ITR_R_709_3_FR		0x00000000
#define SCALER_CSC0_ITR_R_2020_FR		0x00000000

/* S2.8 contribution of Cb to Green */
#define SCALER_CSC1_COEF_CB_GRN_MASK		VC4_MASK(31, 22)
@@ -990,8 +993,11 @@ enum hvs_pixel_format {
#define SCALER_CSC1_COEF_CR_BLU_MASK		VC4_MASK(1, 0)
#define SCALER_CSC1_COEF_CR_BLU_SHIFT		0
#define SCALER_CSC1_ITR_R_601_5			0xe73304a8
#define SCALER_CSC1_ITR_R_709_3			0xf2b784a8
#define SCALER_CSC1_JPEG_JFIF			0xea34a400
#define SCALER_CSC1_ITR_R_709_3			0xf27784a8
#define SCALER_CSC1_ITR_R_2020			0xf43594a8
#define SCALER_CSC1_JPEG_JFIF			0xea349400
#define SCALER_CSC1_ITR_R_709_3_FR		0xf4388400
#define SCALER_CSC1_ITR_R_2020_FR		0xf5b6d400

/* S2.8 contribution of Cb to Red */
#define SCALER_CSC2_COEF_CB_RED_MASK		VC4_MASK(29, 20)
@@ -1002,9 +1008,12 @@ enum hvs_pixel_format {
/* S2.8 contribution of Cb to Blue */
#define SCALER_CSC2_COEF_CB_BLU_MASK		VC4_MASK(19, 10)
#define SCALER_CSC2_COEF_CB_BLU_SHIFT		10
#define SCALER_CSC2_ITR_R_601_5			0x00066204
#define SCALER_CSC2_ITR_R_709_3			0x00072a1c
#define SCALER_CSC2_JPEG_JFIF			0x000599c5
#define SCALER_CSC2_ITR_R_601_5			0x00066604
#define SCALER_CSC2_ITR_R_709_3			0x00072e1d
#define SCALER_CSC2_ITR_R_2020			0x0006b624
#define SCALER_CSC2_JPEG_JFIF			0x00059dc6
#define SCALER_CSC2_ITR_R_709_3_FR		0x00064ddb
#define SCALER_CSC2_ITR_R_2020_FR		0x0005e5e2

#define SCALER_TPZ0_VERT_RECALC			BIT(31)
#define SCALER_TPZ0_SCALE_MASK			VC4_MASK(28, 8)