From ee2862aadb05a7cfaf584fafbe3c0e92c7798a0d Mon Sep 17 00:00:00 2001
From: Rohit Visavalia <rohit.visavalia@xilinx.com>
Date: Thu, 17 Mar 2022 08:21:41 -0700
Subject: [PATCH 1/6] headers: Sync with HDR from v5.15

Sync drm_mode.h with linux-xlnx/include/uapi/drm/drm_mode.h for HDR

Signed-off-by: Rohit Visavalia <rohit.visavalia@xilinx.com>
---
 include/drm/drm_mode.h | 129 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 125 insertions(+), 4 deletions(-)

diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index 9b6722d..bbce882 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -312,16 +312,48 @@ struct drm_mode_set_plane {
 	__u32 src_w;
 };
 
+/**
+ * struct drm_mode_get_plane - Get plane metadata.
+ *
+ * Userspace can perform a GETPLANE ioctl to retrieve information about a
+ * plane.
+ *
+ * To retrieve the number of formats supported, set @count_format_types to zero
+ * and call the ioctl. @count_format_types will be updated with the value.
+ *
+ * To retrieve these formats, allocate an array with the memory needed to store
+ * @count_format_types formats. Point @format_type_ptr to this array and call
+ * the ioctl again (with @count_format_types still set to the value returned in
+ * the first ioctl call).
+ */
 struct drm_mode_get_plane {
+	/**
+	 * @plane_id: Object ID of the plane whose information should be
+	 * retrieved. Set by caller.
+	 */
 	__u32 plane_id;
 
+	/** @crtc_id: Object ID of the current CRTC. */
 	__u32 crtc_id;
+	/** @fb_id: Object ID of the current fb. */
 	__u32 fb_id;
 
+	/**
+	 * @possible_crtcs: Bitmask of CRTC's compatible with the plane. CRTC's
+	 * are created and they receive an index, which corresponds to their
+	 * position in the bitmask. Bit N corresponds to
+	 * :ref:`CRTC index<crtc_index>` N.
+	 */
 	__u32 possible_crtcs;
+	/** @gamma_size: Never used. */
 	__u32 gamma_size;
 
+	/** @count_format_types: Number of formats. */
 	__u32 count_format_types;
+	/**
+	 * @format_type_ptr: Pointer to ``__u32`` array of formats that are
+	 * supported by the plane. These formats do not require modifiers.
+	 */
 	__u64 format_type_ptr;
 };
 
@@ -509,22 +541,74 @@ struct drm_mode_get_connector {
  */
 #define DRM_MODE_PROP_ATOMIC        0x80000000
 
+/**
+ * struct drm_mode_property_enum - Description for an enum/bitfield entry.
+ * @value: numeric value for this enum entry.
+ * @name: symbolic name for this enum entry.
+ *
+ * See struct drm_property_enum for details.
+ */
 struct drm_mode_property_enum {
 	__u64 value;
 	char name[DRM_PROP_NAME_LEN];
 };
 
+/**
+ * struct drm_mode_get_property - Get property metadata.
+ *
+ * User-space can perform a GETPROPERTY ioctl to retrieve information about a
+ * property. The same property may be attached to multiple objects, see
+ * "Modeset Base Object Abstraction".
+ *
+ * The meaning of the @values_ptr field changes depending on the property type.
+ * See &drm_property.flags for more details.
+ *
+ * The @enum_blob_ptr and @count_enum_blobs fields are only meaningful when the
+ * property has the type &DRM_MODE_PROP_ENUM or &DRM_MODE_PROP_BITMASK. For
+ * backwards compatibility, the kernel will always set @count_enum_blobs to
+ * zero when the property has the type &DRM_MODE_PROP_BLOB. User-space must
+ * ignore these two fields if the property has a different type.
+ *
+ * User-space is expected to retrieve values and enums by performing this ioctl
+ * at least twice: the first time to retrieve the number of elements, the
+ * second time to retrieve the elements themselves.
+ *
+ * To retrieve the number of elements, set @count_values and @count_enum_blobs
+ * to zero, then call the ioctl. @count_values will be updated with the number
+ * of elements. If the property has the type &DRM_MODE_PROP_ENUM or
+ * &DRM_MODE_PROP_BITMASK, @count_enum_blobs will be updated as well.
+ *
+ * To retrieve the elements themselves, allocate an array for @values_ptr and
+ * set @count_values to its capacity. If the property has the type
+ * &DRM_MODE_PROP_ENUM or &DRM_MODE_PROP_BITMASK, allocate an array for
+ * @enum_blob_ptr and set @count_enum_blobs to its capacity. Calling the ioctl
+ * again will fill the arrays.
+ */
 struct drm_mode_get_property {
-	__u64 values_ptr; /* values and blob lengths */
-	__u64 enum_blob_ptr; /* enum and blob id ptrs */
+	/** @values_ptr: Pointer to a ``__u64`` array. */
+	__u64 values_ptr;
+	/** @enum_blob_ptr: Pointer to a struct drm_mode_property_enum array. */
+	__u64 enum_blob_ptr;
 
+	/**
+	 * @prop_id: Object ID of the property which should be retrieved. Set
+	 * by the caller.
+	 */
 	__u32 prop_id;
+	/**
+	 * @flags: ``DRM_MODE_PROP_*`` bitfield. See &drm_property.flags for
+	 * a definition of the flags.
+	 */
 	__u32 flags;
+	/**
+	 * @name: Symbolic property name. User-space should use this field to
+	 * recognize properties.
+	 */
 	char name[DRM_PROP_NAME_LEN];
 
+	/** @count_values: Number of elements in @values_ptr. */
 	__u32 count_values;
-	/* This is only used to count enum values, not blobs. The _blobs is
-	 * simply because of a historical reason, i.e. backwards compat. */
+	/** @count_enum_blobs: Number of elements in @enum_blob_ptr. */
 	__u32 count_enum_blobs;
 };
 
@@ -578,6 +662,8 @@ struct drm_mode_fb_cmd {
 
 #define DRM_MODE_FB_INTERLACED	(1<<0) /* for interlaced framebuffers */
 #define DRM_MODE_FB_MODIFIERS	(1<<1) /* enables ->modifer[] */
+#define DRM_MODE_FB_ALTERNATE_TOP	(1<<2) /* for alternate top field */
+#define DRM_MODE_FB_ALTERNATE_BOTTOM	(1<<3) /* for alternate bottom field */
 
 struct drm_mode_fb_cmd2 {
 	__u32 fb_id;
@@ -733,6 +819,20 @@ struct drm_color_lut {
 	__u16 reserved;
 };
 
+enum drm_hdr_type {
+	/*
+	 * This is for the gen_hdr_output_metadata structure.
+	 * MSB differentiates static (0) or dynamic (1) metadata.
+	 * Other 15 bits represent specific HDR standards.
+	 */
+
+	/* static HDR */
+	DRM_HDR_TYPE_HDR10     = 0x0000,
+
+	/* dynamic HDR */
+	DRM_HDR_TYPE_HDR10P    = 1 << 15 | DRM_HDR_TYPE_HDR10,
+};
+
 /**
  * struct hdr_metadata_infoframe - HDR Metadata Infoframe Data.
  *
@@ -819,6 +919,27 @@ struct hdr_output_metadata {
 	};
 };
 
+/**
+ * struct gen_hdr_output_metadata - Generic HDR output metadata
+ *
+ * Generic HDR Metadata Information to be passed from userspace
+ */
+struct gen_hdr_output_metadata {
+	/**
+	 * @metadata_type: HDR type.
+	 */
+	__u16 metadata_type;
+	/**
+	 * @size: size of payload/metadata.
+	 */
+	__u16 size;
+	/**
+	 * @payload: Actual metadata - HDR Metadata Infoframe.
+	 * Currently the largest extended HDR infoframe is 4000 bytes.
+	 */
+	__u8 payload[4000];
+};
+
 #define DRM_MODE_PAGE_FLIP_EVENT 0x01
 #define DRM_MODE_PAGE_FLIP_ASYNC 0x02
 #define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4
-- 
2.25.1


From e01940493905aa658400ef09b24632c99ea7f96f Mon Sep 17 00:00:00 2001
From: Anil Kumar M <amamidal@xilinx.com>
Date: Fri, 10 Apr 2020 21:35:47 +0530
Subject: [PATCH 2/6] modetest: Add semiplanar 10bit pattern support for
 modetest

Add XV15 and XV20 10 bit semiplanar formats support for
generating color bar pattern while running modetest command.

Signed-off-by: Anil Kumar M <amamidal@xilinx.com>
---
 tests/modetest/buffers.c |  24 ++-
 tests/util/format.c      |   3 +
 tests/util/pattern.c     | 455 ++++++++++++++++++++++++++++++++++++++-
 3 files changed, 473 insertions(+), 9 deletions(-)

diff --git a/tests/modetest/buffers.c b/tests/modetest/buffers.c
index 0b55aed..6a226be 100644
--- a/tests/modetest/buffers.c
+++ b/tests/modetest/buffers.c
@@ -116,7 +116,7 @@ bo_create(int fd, unsigned int format,
 	  unsigned int handles[4], unsigned int pitches[4],
 	  unsigned int offsets[4], enum util_fill_pattern pattern)
 {
-	unsigned int virtual_height;
+	unsigned int virtual_height, virtual_width;
 	struct bo *bo;
 	unsigned int bpp;
 	void *planes[3] = { 0, };
@@ -134,6 +134,11 @@ bo_create(int fd, unsigned int format,
 		bpp = 8;
 		break;
 
+	case DRM_FORMAT_XV15:
+	case DRM_FORMAT_XV20:
+		bpp = 10;
+		break;
+
 	case DRM_FORMAT_ARGB4444:
 	case DRM_FORMAT_XRGB4444:
 	case DRM_FORMAT_ABGR4444:
@@ -200,20 +205,33 @@ bo_create(int fd, unsigned int format,
 	case DRM_FORMAT_NV21:
 	case DRM_FORMAT_YUV420:
 	case DRM_FORMAT_YVU420:
+		virtual_width = width;
+		virtual_height = height * 3 / 2;
+		break;
+
+	case DRM_FORMAT_XV15:
+		virtual_width = (width * 32) / 30;
 		virtual_height = height * 3 / 2;
 		break;
 
+	case DRM_FORMAT_XV20:
+		virtual_width = (width * 32) / 30;
+		virtual_height = height * 2;
+		break;
+
 	case DRM_FORMAT_NV16:
 	case DRM_FORMAT_NV61:
+		virtual_width = width;
 		virtual_height = height * 2;
 		break;
 
 	default:
+		virtual_width = width;
 		virtual_height = height;
 		break;
 	}
 
-	bo = bo_create_dumb(fd, width, virtual_height, bpp);
+	bo = bo_create_dumb(fd, virtual_width, virtual_height, bpp);
 	if (!bo)
 		return NULL;
 
@@ -244,6 +262,8 @@ bo_create(int fd, unsigned int format,
 	case DRM_FORMAT_NV21:
 	case DRM_FORMAT_NV16:
 	case DRM_FORMAT_NV61:
+	case DRM_FORMAT_XV15:
+	case DRM_FORMAT_XV20:
 		offsets[0] = 0;
 		handles[0] = bo->handle;
 		pitches[0] = bo->pitch;
diff --git a/tests/util/format.c b/tests/util/format.c
index 1ca1b82..e4b612b 100644
--- a/tests/util/format.c
+++ b/tests/util/format.c
@@ -51,6 +51,9 @@ static const struct util_format_info format_info[] = {
 	{ DRM_FORMAT_NV21, "NV21", MAKE_YUV_INFO(YUV_YCrCb, 2, 2, 2) },
 	{ DRM_FORMAT_NV16, "NV16", MAKE_YUV_INFO(YUV_YCbCr, 2, 1, 2) },
 	{ DRM_FORMAT_NV61, "NV61", MAKE_YUV_INFO(YUV_YCrCb, 2, 1, 2) },
+	{ DRM_FORMAT_XV15, "XV15", MAKE_YUV_INFO(YUV_YCbCr, 2, 2, 2) },
+	{ DRM_FORMAT_XV20, "XV20", MAKE_YUV_INFO(YUV_YCbCr, 2, 1, 2) },
+
 	/* YUV planar */
 	{ DRM_FORMAT_YUV420, "YU12", MAKE_YUV_INFO(YUV_YCbCr, 2, 2, 1) },
 	{ DRM_FORMAT_YVU420, "YV12", MAKE_YUV_INFO(YUV_YCrCb, 2, 2, 1) },
diff --git a/tests/util/pattern.c b/tests/util/pattern.c
index 158c0b1..e29d160 100644
--- a/tests/util/pattern.c
+++ b/tests/util/pattern.c
@@ -260,6 +260,432 @@ static void fill_smpte_yuv_planar(const struct util_yuv_info *yuv,
 	}
 }
 
+static void fill_smpte_yuv_semiplanar_10b(
+				const struct util_yuv_info *yuv,
+				unsigned char *y_mem, unsigned char *uv_mem,
+				unsigned int width,
+				unsigned int height, unsigned int stride)
+{
+	const struct color_yuv colors_top[] = {
+		MAKE_YUV_601(191, 192, 192),	/* grey */
+		MAKE_YUV_601(192, 192, 0),	/* yellow */
+		MAKE_YUV_601(0, 192, 192),	/* cyan */
+		MAKE_YUV_601(0, 192, 0),	/* green */
+		MAKE_YUV_601(192, 0, 192),	/* magenta */
+		MAKE_YUV_601(192, 0, 0),	/* red */
+		MAKE_YUV_601(0, 0, 192),	/* blue */
+	};
+	const struct color_yuv colors_middle[] = {
+		MAKE_YUV_601(0, 0, 192),	/* blue */
+		MAKE_YUV_601(19, 19, 19),	/* black */
+		MAKE_YUV_601(192, 0, 192),	/* magenta */
+		MAKE_YUV_601(19, 19, 19),	/* black */
+		MAKE_YUV_601(0, 192, 192),	/* cyan */
+		MAKE_YUV_601(19, 19, 19),	/* black */
+		MAKE_YUV_601(192, 192, 192),	/* grey */
+	};
+	const struct color_yuv colors_bottom[] = {
+		MAKE_YUV_601(0, 33, 76),	/* in-phase */
+		MAKE_YUV_601(255, 255, 255),	/* super white */
+		MAKE_YUV_601(50, 0, 106),	/* quadrature */
+		MAKE_YUV_601(19, 19, 19),	/* black */
+		MAKE_YUV_601(9, 9, 9),		/* 3.5% */
+		MAKE_YUV_601(19, 19, 19),	/* 7.5% */
+		MAKE_YUV_601(29, 29, 29),	/* 11.5% */
+		MAKE_YUV_601(19, 19, 19),	/* black */
+	};
+	unsigned int cs = yuv->chroma_stride;
+	unsigned int xsub = yuv->xsub;
+	unsigned int ysub = yuv->ysub;
+	unsigned int x;
+	unsigned int y;
+	unsigned int cval = 0;
+
+	for (y = 0; y < height * 6 / 9; ++y) {
+		for (x = 0; x < width; x += 3)
+			((unsigned int *)y_mem)[x/3] =
+				colors_top[x * 7 / width].y << 2 |
+				colors_top[(x+1) * 7 / width].y << 12 |
+				colors_top[(x+2) * 7 / width].y << 22;
+		y_mem += stride;
+	}
+
+	for (; y < height * 7 / 9; ++y) {
+		for (x = 0; x < width; x += 3)
+			((unsigned int *)y_mem)[x/3] =
+				colors_middle[x * 7 / width].y << 2 |
+				colors_middle[(x+1) * 7 / width].y << 12 |
+				colors_middle[(x+2) * 7 / width].y << 22;
+		y_mem += stride;
+	}
+
+	for (; y < height; ++y) {
+		for (x = 0; x < width * 5 / 7; x += 3)
+			((unsigned int *)y_mem)[x/3] =
+				colors_bottom[x * 4 / (width * 5 / 7)].y << 2 |
+				colors_bottom[(x + 1) * 4 / (width * 5 / 7)]
+				.y << 12 | colors_bottom[(x + 2) * 4 /
+				(width * 5 / 7)].y << 22;
+
+		for (; x < width * 6 / 7; x += 3)
+			((unsigned int *)y_mem)[x/3] =
+				colors_bottom[(x - width * 5 / 7) * 3 /
+				(width / 7) + 4].y << 2 |
+				colors_bottom[((x + 1) - width * 5 / 7) * 3 /
+				(width / 7) + 4].y << 12 |
+				colors_bottom[((x + 2) - width * 5 / 7) * 3 /
+				(width / 7) + 4].y << 22;
+
+		for (; x < width; x += 3)
+			((unsigned int *)y_mem)[x/3] = colors_bottom[7].y << 2 |
+				colors_bottom[7].y << 12 |
+				colors_bottom[7].y << 22;
+		y_mem += stride;
+	}
+
+	/* Chroma */
+	unsigned int *c_mem = (unsigned int *)uv_mem;
+
+	for (y = 0; y < height / ysub * 6 / 9; ++y) {
+		for (x = 0; x < width; x += 6) {
+			cval = (colors_top[x * 7 / width].u << 2) |
+				(colors_top[x * 7 / width].v << 12) |
+				(colors_top[(x + 2) * 7 / width].u << 22);
+			c_mem[x/3] = cval;
+			cval = (colors_top[(x + 2) * 7 / width].v << 2) |
+				(colors_top[(x + 4) * 7 / width].u << 12) |
+				(colors_top[(x + 4) * 7 / width].v << 22);
+			c_mem[x/3 + 1] = cval;
+		}
+		c_mem += (stride/4) * cs / xsub;
+	}
+
+	for (; y < height / ysub * 7 / 9; ++y) {
+		for (x = 0; x < width; x += 6) {
+			cval =  (colors_middle[x * 7 / width].u << 2) |
+				(colors_middle[x * 7 / width].v << 12) |
+				(colors_middle[(x + 2) * 7 / width].u << 22);
+			c_mem[x/3] = cval;
+			cval = (colors_middle[(x + 2) * 7 / width].v << 2) |
+				(colors_middle[(x + 4) * 7 / width].u << 12) |
+				(colors_middle[(x + 4) * 7 / width].v << 22);
+			c_mem[x/3 + 1] = cval;
+		}
+		c_mem += (stride/4) * cs / xsub;
+	}
+
+	for (; y < height / ysub; ++y) {
+		for (x = 0; x < width * 5 / 7; x += 6) {
+			cval = colors_bottom[x * 4 /
+				(width * 5 / 7)].u << 2 |
+				colors_bottom[x * 4 /
+				(width * 5 / 7)].v << 12 |
+				colors_bottom[(x + 2) * 4 /
+				(width * 5 / 7)]. u << 22;
+
+			c_mem[x/3] = cval;
+
+			cval = colors_bottom[(x + 2) * 4 /
+				(width * 5 / 7)].v << 2 |
+				colors_bottom[(x + 4) * 4 /
+				(width * 5 / 7)].u << 12 |
+				colors_bottom[(x + 4) * 4 /
+				(width * 5 / 7)].v << 22;
+
+			c_mem[x/3 + 1] = cval;
+		}
+		for (; x < width * 6 / 7; x += 6) {
+			cval = colors_bottom[(x - width * 5 / 7) * 3 /
+				(width / 7) + 4].u << 2 |
+				colors_bottom[(x - width * 5 / 7) * 3 /
+				(width / 7) + 4].v << 12 |
+				colors_bottom[((x + 2) - width * 5 / 7) * 3 /
+				(width / 7) + 4].u << 22;
+
+			c_mem[x/3] = cval;
+
+			cval = colors_bottom[((x + 2) - width * 5 / 7) * 3 /
+				(width / 7) + 4].v << 2 |
+				colors_bottom[((x + 4) - width * 5 / 7) * 3 /
+				(width / 7) + 4].u << 12 |
+				colors_bottom[((x + 4) - width * 5 / 7) * 3 /
+				(width / 7) + 4].v << 22;
+			c_mem[x/3 + 1] = cval;
+		}
+		for (; x < width; x += 6) {
+			cval = colors_bottom[7].u << 2 |
+				colors_bottom[7].v << 12 |
+				colors_bottom[7].u << 22;
+			c_mem[x/3] = cval;
+			cval = colors_bottom[7].v << 2 |
+				colors_bottom[7].u << 12 |
+				colors_bottom[7].v << 22;
+			c_mem[x/3 + 1] = cval;
+		}
+		c_mem += (stride/4) * cs / xsub;
+	}
+}
+
+static void fill_smpte_yuv_planar_10b(
+				const struct util_yuv_info *yuv,
+				unsigned char *y_mem, unsigned char *u_mem,
+				unsigned char *v_mem, unsigned int width,
+				unsigned int height, unsigned int stride)
+{
+	const struct color_yuv colors_top[] = {
+		MAKE_YUV_601(191, 192, 192),	/* grey */
+		MAKE_YUV_601(192, 192, 0),	/* yellow */
+		MAKE_YUV_601(0, 192, 192),	/* cyan */
+		MAKE_YUV_601(0, 192, 0),	/* green */
+		MAKE_YUV_601(192, 0, 192),	/* magenta */
+		MAKE_YUV_601(192, 0, 0),	/* red */
+		MAKE_YUV_601(0, 0, 192),	/* blue */
+	};
+	const struct color_yuv colors_middle[] = {
+		MAKE_YUV_601(0, 0, 192),	/* blue */
+		MAKE_YUV_601(19, 19, 19),	/* black */
+		MAKE_YUV_601(192, 0, 192),	/* magenta */
+		MAKE_YUV_601(19, 19, 19),	/* black */
+		MAKE_YUV_601(0, 192, 192),	/* cyan */
+		MAKE_YUV_601(19, 19, 19),	/* black */
+		MAKE_YUV_601(192, 192, 192),	/* grey */
+	};
+	const struct color_yuv colors_bottom[] = {
+		MAKE_YUV_601(0, 33, 76),	/* in-phase */
+		MAKE_YUV_601(255, 255, 255),	/* super white */
+		MAKE_YUV_601(50, 0, 106),	/* quadrature */
+		MAKE_YUV_601(19, 19, 19),	/* black */
+		MAKE_YUV_601(9, 9, 9),		/* 3.5% */
+		MAKE_YUV_601(19, 19, 19),	/* 7.5% */
+		MAKE_YUV_601(29, 29, 29),	/* 11.5% */
+		MAKE_YUV_601(19, 19, 19),	/* black */
+	};
+	unsigned int cs = yuv->chroma_stride;
+	unsigned int xsub = yuv->xsub;
+	unsigned int ysub = yuv->ysub;
+	unsigned int x;
+	unsigned int y;
+
+	/* Luma */
+	for (y = 0; y < height * 6 / 9; ++y) {
+		for (x = 0; x < width; ++x)
+			y_mem[x] = colors_top[x * 7 / width].y;
+		y_mem += stride;
+	}
+
+	for (; y < height * 7 / 9; ++y) {
+		for (x = 0; x < width; ++x)
+			y_mem[x] = colors_middle[x * 7 / width].y;
+		y_mem += stride;
+	}
+
+	for (; y < height; ++y) {
+		for (x = 0; x < width * 5 / 7; ++x)
+			y_mem[x] = colors_bottom[x * 4 / (width * 5 / 7)].y;
+		for (; x < width * 6 / 7; ++x)
+			y_mem[x] = colors_bottom[(x - width * 5 / 7) * 3 /
+			(width / 7) + 4].y;
+		for (; x < width; ++x)
+			y_mem[x] = colors_bottom[7].y;
+		y_mem += stride;
+	}
+
+	/* Chroma */
+	for (y = 0; y < height / ysub * 6 / 9; ++y) {
+		for (x = 0; x < width; x += xsub) {
+			u_mem[x*cs/xsub] = colors_top[x * 7 / width].u;
+			v_mem[x*cs/xsub] = colors_top[x * 7 / width].v;
+		}
+		u_mem += stride * cs / xsub;
+		v_mem += stride * cs / xsub;
+	}
+
+	for (; y < height / ysub * 7 / 9; ++y) {
+		for (x = 0; x < width; x += xsub) {
+			u_mem[x*cs/xsub] = colors_middle[x * 7 / width].u;
+			v_mem[x*cs/xsub] = colors_middle[x * 7 / width].v;
+		}
+		u_mem += stride * cs / xsub;
+		v_mem += stride * cs / xsub;
+	}
+
+	for (; y < height / ysub; ++y) {
+		for (x = 0; x < width * 5 / 7; x += xsub) {
+			u_mem[x*cs/xsub] =
+		colors_bottom[x * 4 / (width * 5 / 7)].u;
+			v_mem[x*cs/xsub] =
+		colors_bottom[x * 4 / (width * 5 / 7)].v;
+		}
+		for (; x < width * 6 / 7; x += xsub) {
+			u_mem[x*cs/xsub] =
+		colors_bottom[(x - width * 5 / 7) * 3 / (width / 7) + 4].u;
+			v_mem[x*cs/xsub] =
+		colors_bottom[(x - width * 5 / 7) * 3 / (width / 7) + 4].v;
+		}
+		for (; x < width; x += xsub) {
+			u_mem[x*cs/xsub] = colors_bottom[7].u;
+			v_mem[x*cs/xsub] = colors_bottom[7].v;
+		}
+		u_mem += stride * cs / xsub;
+		v_mem += stride * cs / xsub;
+	}
+}
+
+static void fill_tiles_xv15(
+				const struct util_format_info *info,
+				unsigned char *y_mem, unsigned char *u_mem,
+				unsigned char *v_mem, uint32_t width,
+				uint32_t height, uint32_t stride)
+{
+	const struct util_yuv_info *yuv = &info->yuv;
+	unsigned int cs = yuv->chroma_stride;
+	unsigned int x;
+	unsigned int y;
+	uint32_t shifter = 0, LumVal = 0;
+	uint32_t lumIndex = 0;
+	uint32_t *Lum;
+	uint32_t *Chrom;
+	uint32_t ChromVal = 0;
+	uint32_t chromIndex = 0;
+
+	/* preparing 10 bit Luma */
+	Lum = (uint32_t *)y_mem;
+	for (y = 0; y < height; ++y) {
+		for (x = 0; x < width; x++) {
+			div_t d  = div(x+y, width);
+			uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
+				+ 0x000a1120 * (d.rem >> 6);
+			struct color_yuv color =
+				MAKE_YUV_601((rgb32 >> 16) & 0xff,
+				(rgb32 >> 8) & 0xff, rgb32 & 0xff);
+			//Checking if we got 3 components to pack in 4 bytes
+			if (shifter == 30) {
+				Lum[lumIndex] = LumVal;
+				lumIndex++; shifter = 0; LumVal = 0;
+			}
+			LumVal  = (LumVal | ((color.y << 2) << shifter));
+			shifter += 10; //10 bit precision
+		}
+		lumIndex = 0; shifter = 0; LumVal = 0;
+		y_mem += stride;
+		Lum = (uint32_t *)y_mem;
+	}
+
+	/* Preparing 10 bit Chroma */
+	Chrom = (uint32_t *)u_mem;
+	for (y = 0; y < height / 2; ++y) {
+		for (x = 0; x < width; x = x + 6) {
+			div_t d  = div(x+(2 * y), width);
+			uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
+				+ 0x000a1120 * (d.rem >> 6);
+			struct color_yuv color =
+				 MAKE_YUV_601((rgb32 >> 16) & 0xff,
+				(rgb32 >> 8) & 0xff, rgb32 & 0xff);
+			div_t d2  = div(x + 2 + (2*y), width);
+			uint32_t rgb32_2 = 0x00130502 * (d2.quot >> 6)
+					+ 0x000a1120 * (d2.rem >> 6);
+			struct color_yuv color_2 =
+				MAKE_YUV_601((rgb32_2 >> 16) & 0xff,
+				(rgb32_2 >> 8) & 0xff, rgb32_2 & 0xff);
+
+			div_t d3  = div(x + 4 + (2*y), width);
+			uint32_t rgb32_3 = 0x00130502 * (d3.quot >> 6)
+					+ 0x000a1120 * (d3.rem >> 6);
+			struct color_yuv color_3 =
+				MAKE_YUV_601((rgb32_3 >> 16) & 0xff,
+				(rgb32_3 >> 8) & 0xff, rgb32_3 & 0xff);
+
+			ChromVal = ((color_2.u << 2) << 20)
+				| ((color.v << 2) << 10) | (color.u << 2);
+			Chrom[chromIndex++] = ChromVal;
+
+			ChromVal = ((color_3.v << 2) << 20)
+				| ((color_3.u << 2) << 10) | (color_2.v << 2);
+			Chrom[chromIndex++] = ChromVal;
+		}
+	chromIndex = 0; ChromVal = 0;
+	u_mem += stride;
+	Chrom = (uint32_t *)u_mem;
+	}
+}
+
+static void fill_tiles_xv20(
+				const struct util_format_info *info,
+				unsigned char *y_mem, unsigned char *u_mem,
+				unsigned char *v_mem, uint32_t width,
+				uint32_t height, uint32_t stride)
+{
+	const struct util_yuv_info *yuv = &info->yuv;
+	unsigned int cs = yuv->chroma_stride;
+	unsigned int x;
+	unsigned int y;
+	uint32_t shifter = 0, LumVal = 0;
+	uint32_t lumIndex = 0;
+	uint32_t *Lum;
+	uint32_t *Chrom;
+	uint32_t ChromVal = 0;
+	uint32_t chromIndex = 0;
+
+	/* preparing 10 bit Luma */
+	Lum = (uint32_t *)y_mem;
+	for (y = 0; y < height; ++y) {
+		for (x = 0; x < width; x++) {
+			div_t d  = div(x+y, width);
+			uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
+					+ 0x000a1120 * (d.rem >> 6);
+			struct color_yuv color =
+					MAKE_YUV_601((rgb32 >> 16) & 0xff,
+					(rgb32 >> 8) & 0xff, rgb32 & 0xff);
+			//Checking if we got 3 components to pack in 4 bytes
+			if (shifter == 30) {
+				Lum[lumIndex] = LumVal;
+				lumIndex++; shifter = 0; LumVal = 0;
+			}
+			LumVal  = (LumVal | ((color.y << 2) << shifter));
+			shifter += 10; //10 bit precision
+		}
+		lumIndex = 0; shifter = 0; LumVal = 0;
+		y_mem += stride;
+		Lum = (uint32_t *)y_mem;
+	}
+
+	/* Preparing 10 bit Chroma */
+	Chrom = (uint32_t *)u_mem;
+	for (y = 0; y < height; ++y) {
+		for (x = 0; x < width; x = x + 6) {
+			div_t d  = div(x+y, width);
+			uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
+					+ 0x000a1120 * (d.rem >> 6);
+			struct color_yuv color =
+					MAKE_YUV_601((rgb32 >> 16) & 0xff,
+					(rgb32 >> 8) & 0xff, rgb32 & 0xff);
+			div_t d2  = div(x + 2 + y, width);
+			uint32_t rgb32_2 = 0x00130502 * (d2.quot >> 6)
+						+ 0x000a1120 * (d2.rem >> 6);
+			struct color_yuv color_2 =
+					MAKE_YUV_601((rgb32_2 >> 16) & 0xff,
+				       (rgb32_2 >> 8) & 0xff, rgb32_2 & 0xff);
+			div_t d3  = div(x + 4 + y, width);
+			uint32_t rgb32_3 = 0x00130502 * (d3.quot >> 6)
+					+ 0x000a1120 * (d3.rem >> 6);
+			struct color_yuv color_3 =
+					MAKE_YUV_601((rgb32_3 >> 16) & 0xff,
+					(rgb32_3 >> 8) & 0xff, rgb32_3 & 0xff);
+
+			ChromVal = ((color_2.u << 2) << 20)
+				| ((color.v << 2) << 10) | (color.u << 2);
+			Chrom[chromIndex++] = ChromVal;
+
+			ChromVal = ((color_3.v << 2) << 20)
+				| ((color_3.u << 2) << 10) | (color_2.v << 2);
+			Chrom[chromIndex++] = ChromVal;
+		}
+		chromIndex = 0; ChromVal = 0;
+		u_mem += stride;
+		Chrom = (uint32_t *)u_mem;
+	}
+}
+
 static void fill_smpte_yuv_packed(const struct util_yuv_info *yuv, void *mem,
 				  unsigned int width, unsigned int height,
 				  unsigned int stride)
@@ -678,9 +1104,10 @@ void util_smpte_c8_gamma(unsigned size, struct drm_color_lut *lut)
 #undef FILL_COLOR
 }
 
-static void fill_smpte(const struct util_format_info *info, void *planes[3],
-		       unsigned int width, unsigned int height,
-		       unsigned int stride)
+static void fill_smpte(const struct util_format_info *info,
+				void *planes[3],
+				unsigned int width, unsigned int height,
+				unsigned int stride)
 {
 	unsigned char *u, *v;
 
@@ -693,7 +1120,12 @@ static void fill_smpte(const struct util_format_info *info, void *planes[3],
 	case DRM_FORMAT_YVYU:
 		return fill_smpte_yuv_packed(&info->yuv, planes[0], width,
 					     height, stride);
-
+	case DRM_FORMAT_XV20:
+		return fill_tiles_xv20(info, planes[0], planes[1], planes[1],
+		       width, height, stride);
+	case DRM_FORMAT_XV15:
+		return fill_tiles_xv15(info, planes[0], planes[1], planes[2],
+		       width, height, stride);
 	case DRM_FORMAT_NV12:
 	case DRM_FORMAT_NV21:
 	case DRM_FORMAT_NV16:
@@ -1005,9 +1437,10 @@ static void fill_tiles_rgb16fp(const struct util_format_info *info, void *mem,
 	}
 }
 
-static void fill_tiles(const struct util_format_info *info, void *planes[3],
-		       unsigned int width, unsigned int height,
-		       unsigned int stride)
+static void fill_tiles(const struct util_format_info *info,
+				void *planes[3],
+				unsigned int width, unsigned int height,
+				unsigned int stride)
 {
 	unsigned char *u, *v;
 
@@ -1036,6 +1469,14 @@ static void fill_tiles(const struct util_format_info *info, void *planes[3],
 		return fill_tiles_yuv_planar(info, planes[0], planes[2],
 					     planes[1], width, height, stride);
 
+	case DRM_FORMAT_XV20:
+		return fill_tiles_xv20(info, planes[0], planes[1],
+			 planes[1], width, height, stride);
+
+	case DRM_FORMAT_XV15:
+		return fill_tiles_xv15(info, planes[0], planes[1],
+			 planes[2], width, height, stride);
+
 	case DRM_FORMAT_ARGB4444:
 	case DRM_FORMAT_XRGB4444:
 	case DRM_FORMAT_ABGR4444:
-- 
2.25.1


From 7fa737b1b8b425689244771ea55849652d3d725a Mon Sep 17 00:00:00 2001
From: Anil Kumar Mamidala <anil.mamidala@xilinx.com>
Date: Wed, 27 Oct 2021 16:04:47 +0530
Subject: [PATCH 3/6] modetest: Add YUV444 and X403 format support for modetest

Add YUV44 8-bit and X403 10-bit formats support to modetest
for generating color bar pattern.

Signed-off-by: Anil Kumar Mamidala <anil.mamidala@xilinx.com>
---
 include/drm/drm_fourcc.h |   7 +
 tests/modetest/buffers.c |  32 +++++
 tests/util/format.c      |   4 +
 tests/util/pattern.c     | 270 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 313 insertions(+)

diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 2c9051f..24a5fda 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -357,6 +357,13 @@ extern "C" {
 #define DRM_FORMAT_YUV444	fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */
 #define DRM_FORMAT_YVU444	fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */
 
+/* 3 plane non-subsampled (444) YCbCr
+ * 10 bits per component
+ * index 0: Y plane, [31:0] x:Y2:Y1:Y0 [2:10:10:10] little endian
+ * index 1: Cb plane, [31:0] x:Cb2:Cb1:Cb0 [2:10:10:10] little endian
+ * index 2: Cr plane, [31:0] x:Cr2:Cr1:Cr0 [2:10:10:10] little endian
+ */
+#define DRM_FORMAT_X403		fourcc_code('X', '4', '0', '3') /* non-subsampled Cb:Cr plane, 10 bit per channel */
 
 /*
  * Format Modifiers:
diff --git a/tests/modetest/buffers.c b/tests/modetest/buffers.c
index 6a226be..2f7c919 100644
--- a/tests/modetest/buffers.c
+++ b/tests/modetest/buffers.c
@@ -131,11 +131,13 @@ bo_create(int fd, unsigned int format,
 	case DRM_FORMAT_NV61:
 	case DRM_FORMAT_YUV420:
 	case DRM_FORMAT_YVU420:
+	case DRM_FORMAT_YUV444:
 		bpp = 8;
 		break;
 
 	case DRM_FORMAT_XV15:
 	case DRM_FORMAT_XV20:
+	case DRM_FORMAT_X403:
 		bpp = 10;
 		break;
 
@@ -219,12 +221,24 @@ bo_create(int fd, unsigned int format,
 		virtual_height = height * 2;
 		break;
 
+	case DRM_FORMAT_X403:
+		virtual_width = (width * 32) / 30;
+		virtual_height = height * 3;
+		break;
+
+
 	case DRM_FORMAT_NV16:
 	case DRM_FORMAT_NV61:
 		virtual_width = width;
 		virtual_height = height * 2;
 		break;
 
+	case DRM_FORMAT_YUV444:
+		virtual_width = width;
+		virtual_height = height * 3;
+		break;
+
+
 	default:
 		virtual_width = width;
 		virtual_height = height;
@@ -275,6 +289,24 @@ bo_create(int fd, unsigned int format,
 		planes[1] = virtual + offsets[1];
 		break;
 
+	case DRM_FORMAT_X403:
+	case DRM_FORMAT_YUV444:
+		offsets[0] = 0;
+		handles[0] = bo->handle;
+		pitches[0] = bo->pitch;
+		pitches[1] = pitches[0];
+		offsets[1] = pitches[0] * height;
+		handles[1] = bo->handle;
+		pitches[2] = pitches[1];
+		offsets[2] = offsets[1] + pitches[1] * height;
+		handles[2] = bo->handle;
+
+
+		planes[0] = virtual;
+		planes[1] = virtual + offsets[1];
+		planes[2] = virtual + offsets[2];
+		break;
+
 	case DRM_FORMAT_YUV420:
 	case DRM_FORMAT_YVU420:
 		offsets[0] = 0;
diff --git a/tests/util/format.c b/tests/util/format.c
index e4b612b..ba7267f 100644
--- a/tests/util/format.c
+++ b/tests/util/format.c
@@ -57,6 +57,10 @@ static const struct util_format_info format_info[] = {
 	/* YUV planar */
 	{ DRM_FORMAT_YUV420, "YU12", MAKE_YUV_INFO(YUV_YCbCr, 2, 2, 1) },
 	{ DRM_FORMAT_YVU420, "YV12", MAKE_YUV_INFO(YUV_YCrCb, 2, 2, 1) },
+	{ DRM_FORMAT_YUV444, "YU24", MAKE_YUV_INFO(YUV_YCbCr, 1, 1, 1) },
+	{ DRM_FORMAT_YVU444, "YV24", MAKE_YUV_INFO(YUV_YCrCb, 1, 1, 1) },
+	{ DRM_FORMAT_X403, "X403", MAKE_YUV_INFO(YUV_YCbCr, 1, 1, 1) },
+
 	/* RGB16 */
 	{ DRM_FORMAT_ARGB4444, "AR12", MAKE_RGB_INFO(4, 8, 4, 4, 4, 0, 4, 12) },
 	{ DRM_FORMAT_XRGB4444, "XR12", MAKE_RGB_INFO(4, 8, 4, 4, 4, 0, 0, 0) },
diff --git a/tests/util/pattern.c b/tests/util/pattern.c
index e29d160..50d0ca9 100644
--- a/tests/util/pattern.c
+++ b/tests/util/pattern.c
@@ -426,6 +426,175 @@ static void fill_smpte_yuv_semiplanar_10b(
 	}
 }
 
+static void fill_smpte_yuv_planar_x403(
+				const struct util_yuv_info *yuv,
+				unsigned char *y_mem, unsigned char *u_mem,
+				unsigned char *v_mem,
+				unsigned int width,
+				unsigned int height, unsigned int stride)
+{
+	const struct color_yuv colors_top[] = {
+		MAKE_YUV_601(191, 192, 192),	/* grey */
+		MAKE_YUV_601(192, 192, 0),	/* yellow */
+		MAKE_YUV_601(0, 192, 192),	/* cyan */
+		MAKE_YUV_601(0, 192, 0),	/* green */
+		MAKE_YUV_601(192, 0, 192),	/* magenta */
+		MAKE_YUV_601(192, 0, 0),	/* red */
+		MAKE_YUV_601(0, 0, 192),	/* blue */
+	};
+	const struct color_yuv colors_middle[] = {
+		MAKE_YUV_601(0, 0, 192),	/* blue */
+		MAKE_YUV_601(19, 19, 19),	/* black */
+		MAKE_YUV_601(192, 0, 192),	/* magenta */
+		MAKE_YUV_601(19, 19, 19),	/* black */
+		MAKE_YUV_601(0, 192, 192),	/* cyan */
+		MAKE_YUV_601(19, 19, 19),	/* black */
+		MAKE_YUV_601(192, 192, 192),	/* grey */
+	};
+	const struct color_yuv colors_bottom[] = {
+		MAKE_YUV_601(0, 33, 76),	/* in-phase */
+		MAKE_YUV_601(255, 255, 255),	/* super white */
+		MAKE_YUV_601(50, 0, 106),	/* quadrature */
+		MAKE_YUV_601(19, 19, 19),	/* black */
+		MAKE_YUV_601(9, 9, 9),		/* 3.5% */
+		MAKE_YUV_601(19, 19, 19),	/* 7.5% */
+		MAKE_YUV_601(29, 29, 29),	/* 11.5% */
+		MAKE_YUV_601(19, 19, 19),	/* black */
+	};
+	unsigned int cs = yuv->chroma_stride;
+	unsigned int xsub = yuv->xsub;
+	unsigned int ysub = yuv->ysub;
+	unsigned int x;
+	unsigned int y;
+	unsigned int cval = 0;
+
+	for (y = 0; y < height * 6 / 9; ++y) {
+		for (x = 0; x < width; x += 3)
+			((unsigned int *)y_mem)[x/3] =
+				colors_top[x * 7 / width].y << 2 |
+				colors_top[(x+1) * 7 / width].y << 12 |
+				colors_top[(x+2) * 7 / width].y << 22;
+		y_mem += stride;
+	}
+
+	for (; y < height * 7 / 9; ++y) {
+		for (x = 0; x < width; x += 3)
+			((unsigned int *)y_mem)[x/3] =
+				colors_middle[x * 7 / width].y << 2 |
+				colors_middle[(x+1) * 7 / width].y << 12 |
+				colors_middle[(x+2) * 7 / width].y << 22;
+		y_mem += stride;
+	}
+
+	for (; y < height; ++y) {
+		for (x = 0; x < width * 5 / 7; x += 3)
+			((unsigned int *)y_mem)[x/3] =
+				colors_bottom[x * 4 / (width * 5 / 7)].y << 2 |
+				colors_bottom[(x + 1) * 4 / (width * 5 / 7)]
+				.y << 12 | colors_bottom[(x + 2) * 4 /
+				(width * 5 / 7)].y << 22;
+
+		for (; x < width * 6 / 7; x += 3)
+			((unsigned int *)y_mem)[x/3] =
+				colors_bottom[(x - width * 5 / 7) * 3 /
+				(width / 7) + 4].y << 2 |
+				colors_bottom[((x + 1) - width * 5 / 7) * 3 /
+				(width / 7) + 4].y << 12 |
+				colors_bottom[((x + 2) - width * 5 / 7) * 3 /
+				(width / 7) + 4].y << 22;
+
+		for (; x < width; x += 3)
+			((unsigned int *)y_mem)[x/3] = colors_bottom[7].y << 2 |
+				colors_bottom[7].y << 12 |
+				colors_bottom[7].y << 22;
+		y_mem += stride;
+	}
+
+	/* Chroma */
+	unsigned int *cb_mem = (unsigned int *)u_mem;
+	unsigned int *cr_mem = (unsigned int *)v_mem;
+
+	for (y = 0; y < height / ysub * 6 / 9; ++y) {
+		for (x = 0; x < width; x += 3) {
+			cval = (colors_top[x * 7 / width].u << 2) |
+				(colors_top[(x + 1) * 7 / width].u << 12) |
+				(colors_top[(x + 2) * 7 / width].u << 22);
+			cb_mem[x/3] = cval;
+			cval = (colors_top[(x) * 7 / width].v << 2) |
+				(colors_top[(x + 1) * 7 / width].v << 12) |
+				(colors_top[(x + 2) * 7 / width].v << 22);
+			cr_mem[x/3] = cval;
+		}
+		cb_mem += stride/4;
+		cr_mem += stride/4;
+	}
+
+	for (; y < height / ysub * 7 / 9; ++y) {
+		for (x = 0; x < width; x += 3) {
+			cval =  (colors_middle[x * 7 / width].u << 2) |
+				(colors_middle[(x + 1) * 7 / width].u << 12) |
+				(colors_middle[(x + 2) * 7 / width].u << 22);
+			cb_mem[x/3] = cval;
+			cval = (colors_middle[x * 7 / width].v << 2) |
+				(colors_middle[(x + 1) * 7 / width].v << 12) |
+				(colors_middle[(x + 2) * 7 / width].v << 22);
+			cr_mem[x/3] = cval;
+		}
+		cb_mem += stride/4;
+		cr_mem += stride/4;
+	}
+
+	for (; y < height / ysub; ++y) {
+		for (x = 0; x < width * 5 / 7; x += 3) {
+			cval = colors_bottom[x * 4 /
+				(width * 5 / 7)].u << 2 |
+				colors_bottom[(x + 2) * 4 /
+				(width * 5 / 7)].u << 12 |
+				colors_bottom[(x + 4) * 4 /
+				(width * 5 / 7)]. u << 22;
+			cb_mem[x/3] = cval;
+
+			cval = colors_bottom[(x) * 4 /
+				(width * 5 / 7)].v << 2 |
+				colors_bottom[(x + 2) * 4 /
+				(width * 5 / 7)].v << 12 |
+				colors_bottom[(x + 4) * 4 /
+				(width * 5 / 7)].v << 22;
+
+			cr_mem[x/3] = cval;
+		}
+		for (; x < width * 6 / 7; x += 3) {
+			cval = colors_bottom[(x - width * 5 / 7) * 3 /
+				(width / 7) + 4].u << 2 |
+				colors_bottom[((x + 2)- width * 5 / 7) * 3 /
+				(width / 7) + 4].u << 12 |
+				colors_bottom[((x + 4) - width * 5 / 7) * 3 /
+				(width / 7) + 4].u << 22;
+			cb_mem[x/3] = cval;
+
+			cval = colors_bottom[((x) - width * 5 / 7) * 3 /
+				(width / 7) + 4].v << 2 |
+				colors_bottom[((x + 2) - width * 5 / 7) * 3 /
+				(width / 7) + 4].v << 12 |
+				colors_bottom[((x + 4) - width * 5 / 7) * 3 /
+				(width / 7) + 4].v << 22;
+			cr_mem[x/3] = cval;
+		}
+		for (; x < width; x += 3) {
+			cval = colors_bottom[7].u << 2 |
+				colors_bottom[7].u << 12 |
+				colors_bottom[7].u << 22;
+			cb_mem[x/3] = cval;
+			cval = colors_bottom[7].v << 2 |
+				colors_bottom[7].v << 12 |
+				colors_bottom[7].v << 22;
+			cr_mem[x/3] = cval;
+		}
+		cb_mem += stride/4;
+		cr_mem += stride/4;
+	}
+}
+
 static void fill_smpte_yuv_planar_10b(
 				const struct util_yuv_info *yuv,
 				unsigned char *y_mem, unsigned char *u_mem,
@@ -686,6 +855,88 @@ static void fill_tiles_xv20(
 	}
 }
 
+static void fill_tiles_x403(
+				const struct util_format_info *info,
+				unsigned char *y_mem, unsigned char *u_mem,
+				unsigned char *v_mem, uint32_t width,
+				uint32_t height, uint32_t stride)
+{
+	const struct util_yuv_info *yuv = &info->yuv;
+	unsigned int cs = yuv->chroma_stride;
+	unsigned int x;
+	unsigned int y;
+	uint32_t shifter = 0, LumVal = 0;
+	uint32_t lumIndex = 0;
+	uint32_t *Lum;
+	uint32_t *uChrom;
+	uint32_t *vChrom;
+	uint32_t ChromVal = 0;
+	uint32_t uchromIndex = 0;
+	uint32_t vchromIndex = 0;
+
+	/* preparing 10 bit Luma */
+	Lum = (uint32_t *)y_mem;
+	for (y = 0; y < height; ++y) {
+		for (x = 0; x < width; x++) {
+			div_t d  = div(x+y, width);
+			uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
+					+ 0x000a1120 * (d.rem >> 6);
+			struct color_yuv color =
+					MAKE_YUV_601((rgb32 >> 16) & 0xff,
+					(rgb32 >> 8) & 0xff, rgb32 & 0xff);
+			//Checking if we got 3 components to pack in 4 bytes
+			if (shifter == 30) {
+				Lum[lumIndex] = LumVal;
+				lumIndex++; shifter = 0; LumVal = 0;
+			}
+			LumVal  = (LumVal | ((color.y << 2) << shifter));
+			shifter += 10; //10 bit precision
+		}
+		lumIndex = 0; shifter = 0; LumVal = 0;
+		y_mem += stride;
+		Lum = (uint32_t *)y_mem;
+	}
+
+	/* Preparing 10 bit Chroma */
+	uChrom = (uint32_t *)u_mem;
+	vChrom = (uint32_t *)v_mem;
+
+	for (y = 0; y < height; ++y) {
+		for (x = 0; x < width; x = x + 3) {
+			div_t d  = div(x+y, width);
+			uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
+					+ 0x000a1120 * (d.rem >> 6);
+			struct color_yuv color =
+					MAKE_YUV_601((rgb32 >> 16) & 0xff,
+					(rgb32 >> 8) & 0xff, rgb32 & 0xff);
+			uint32_t rgb32_2 = 0x00130502 * (d.quot >> 6)
+						+ 0x000a1120 * (d.rem >> 6);
+			struct color_yuv color_2 =
+					MAKE_YUV_601((rgb32_2 >> 16) & 0xff,
+				       (rgb32_2 >> 8) & 0xff, rgb32_2 & 0xff);
+			uint32_t rgb32_3 = 0x00130502 * (d.quot >> 6)
+					+ 0x000a1120 * (d.rem >> 6);
+			struct color_yuv color_3 =
+					MAKE_YUV_601((rgb32_3 >> 16) & 0xff,
+					(rgb32_3 >> 8) & 0xff, rgb32_3 & 0xff);
+
+			ChromVal = ((color.u << 2) << 20)
+				| ((color_2.u << 2) << 10) | (color_3.u << 2);
+			uChrom[uchromIndex++] = ChromVal;
+
+			ChromVal = ((color.v << 2) << 20)
+				| ((color_2.v << 2) << 10) | (color_3.v << 2);
+			vChrom[vchromIndex++] = ChromVal;
+		}
+		uchromIndex = 0; vchromIndex = 0; ChromVal = 0;
+		u_mem += stride;
+		v_mem += stride;
+		uChrom = (uint32_t *)u_mem;
+		vChrom = (uint32_t *)v_mem;
+	}
+}
+
+
 static void fill_smpte_yuv_packed(const struct util_yuv_info *yuv, void *mem,
 				  unsigned int width, unsigned int height,
 				  unsigned int stride)
@@ -1135,10 +1386,19 @@ static void fill_smpte(const struct util_format_info *info,
 		return fill_smpte_yuv_planar(&info->yuv, planes[0], u, v,
 					     width, height, stride);
 
+	case DRM_FORMAT_X403:
+			return fill_smpte_yuv_planar_x403(&info->yuv, planes[0], planes[1],
+					     planes[2], width, height, stride);
+
+
 	case DRM_FORMAT_YUV420:
 		return fill_smpte_yuv_planar(&info->yuv, planes[0], planes[1],
 					     planes[2], width, height, stride);
 
+	case DRM_FORMAT_YUV444:
+		return fill_smpte_yuv_planar(&info->yuv, planes[0], planes[1],
+					     planes[2], width, height, stride);
+
 	case DRM_FORMAT_YVU420:
 		return fill_smpte_yuv_planar(&info->yuv, planes[0], planes[2],
 					     planes[1], width, height, stride);
@@ -1465,6 +1725,11 @@ static void fill_tiles(const struct util_format_info *info,
 		return fill_tiles_yuv_planar(info, planes[0], planes[1],
 					     planes[2], width, height, stride);
 
+	case DRM_FORMAT_YUV444:
+		return fill_tiles_yuv_planar(info, planes[0], planes[1],
+					     planes[2], width, height, stride);
+
+
 	case DRM_FORMAT_YVU420:
 		return fill_tiles_yuv_planar(info, planes[0], planes[2],
 					     planes[1], width, height, stride);
@@ -1473,6 +1738,11 @@ static void fill_tiles(const struct util_format_info *info,
 		return fill_tiles_xv20(info, planes[0], planes[1],
 			 planes[1], width, height, stride);
 
+	case DRM_FORMAT_X403:
+		return fill_tiles_x403(info, planes[0], planes[1],
+			 planes[2], width, height, stride);
+
+
 	case DRM_FORMAT_XV15:
 		return fill_tiles_xv15(info, planes[0], planes[1],
 			 planes[2], width, height, stride);
-- 
2.25.1


From c9c5ad3d631ae1578d3653ba24fde145d6e20a72 Mon Sep 17 00:00:00 2001
From: Rohit Visavalia <rohit.visavalia@xilinx.com>
Date: Mon, 24 Feb 2020 03:35:58 -0800
Subject: [PATCH 4/6] modetest: call drmModeCrtcSetGamma() only if
 add_property_optional returns true

gamma is a optional property then also it prints error message, so
set gamma only if add_property_optional() returns true.

Upstream-Status: Pending

Signed-off-by: Rohit Visavalia <rohit.visavalia@xilinx.com>
---
 tests/modetest/modetest.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
index 42e2d1f..3b49f49 100644
--- a/tests/modetest/modetest.c
+++ b/tests/modetest/modetest.c
@@ -1134,7 +1134,7 @@ static void set_gamma(struct device *dev, unsigned crtc_id, unsigned fourcc)
 
 	add_property_optional(dev, crtc_id, "DEGAMMA_LUT", 0);
 	add_property_optional(dev, crtc_id, "CTM", 0);
-	if (!add_property_optional(dev, crtc_id, "GAMMA_LUT", blob_id)) {
+	if (add_property_optional(dev, crtc_id, "GAMMA_LUT", blob_id)) {
 		uint16_t r[256], g[256], b[256];
 
 		for (i = 0; i < 256; i++) {
-- 
2.25.1


From 2852abc5143ddf7673734a68796fcc38a8cae709 Mon Sep 17 00:00:00 2001
From: Anil Kumar M <amamidal@xilinx.com>
Date: Wed, 16 Sep 2020 22:42:47 +0530
Subject: [PATCH 5/6] modetest: fix smpte colour pattern issue for XV20 and
 XV15 formats

Fix smpte colour issue for XV15 and XV20 formats.

Signed-off-by: Anil Kumar M <amamidal@xilinx.com>
---
 tests/util/pattern.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tests/util/pattern.c b/tests/util/pattern.c
index 50d0ca9..83049eb 100644
--- a/tests/util/pattern.c
+++ b/tests/util/pattern.c
@@ -1372,11 +1372,11 @@ static void fill_smpte(const struct util_format_info *info,
 		return fill_smpte_yuv_packed(&info->yuv, planes[0], width,
 					     height, stride);
 	case DRM_FORMAT_XV20:
-		return fill_tiles_xv20(info, planes[0], planes[1], planes[1],
-		       width, height, stride);
+		return fill_smpte_yuv_semiplanar_10b(&info->yuv, planes[0], planes[1],
+					     width, height, stride);
 	case DRM_FORMAT_XV15:
-		return fill_tiles_xv15(info, planes[0], planes[1], planes[2],
-		       width, height, stride);
+		return fill_smpte_yuv_semiplanar_10b(&info->yuv, planes[0], planes[1],
+					     width, height, stride);
 	case DRM_FORMAT_NV12:
 	case DRM_FORMAT_NV21:
 	case DRM_FORMAT_NV16:
-- 
2.25.1


From 70e33e7b49e361689576904ed53400b967cecb00 Mon Sep 17 00:00:00 2001
From: Sai Hari Chandana Kalluri <chandana.kalluri@xilinx.com>
Date: Mon, 1 Nov 2021 12:59:36 -0700
Subject: [PATCH 6/6] libdrm: Update drm header file with XV15 and XV20

This patch updates drm header file with YUV 420 and
YUV422 10 bit formats.

Signed-off-by: Satish Kumar Nagireddy <satish.nagireddy.nagireddy@xilinx.com>
Upstream-Status: Pending
Signed-off-by: Sai Hari Chandana Kalluri <chandana.kalluri@xilinx.com>
---
 include/drm/drm_fourcc.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 24a5fda..ba51a5b 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -337,6 +337,14 @@ extern "C" {
  */
 #define DRM_FORMAT_Q401		fourcc_code('Q', '4', '0', '1')
 
+/*
+ * 2 plane 10 bit per component YCbCr
+ * index 0 = Y plane, [31:0] x:Y2:Y1:Y0 2:10:10:10 little endian
+ * index 1 = Cb:Cr plane, [63:0] x:Cb2:Cr2:Cb1:x:Cr1:Cb0:Cr0 2:10:10:10:2:10:10:10 little endian
+ */
+#define DRM_FORMAT_XV15                fourcc_code('X', 'V', '1', '5') /* 2x2 subsampled Cb:Cr plane 2:10:10:10 */
+#define DRM_FORMAT_XV20                fourcc_code('X', 'V', '2', '0') /* 2x1 subsampled Cb:Cr plane 2:10:10:10 */
+
 /*
  * 3 plane YCbCr
  * index 0: Y plane, [7:0] Y
-- 
2.25.1

