18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Test cases for the drm_framebuffer functions
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <linux/kernel.h>
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <drm/drm_device.h>
98c2ecf20Sopenharmony_ci#include <drm/drm_mode.h>
108c2ecf20Sopenharmony_ci#include <drm/drm_fourcc.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include "../drm_crtc_internal.h"
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include "test-drm_modeset_common.h"
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#define MIN_WIDTH 4
178c2ecf20Sopenharmony_ci#define MAX_WIDTH 4096
188c2ecf20Sopenharmony_ci#define MIN_HEIGHT 4
198c2ecf20Sopenharmony_ci#define MAX_HEIGHT 4096
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_cistruct drm_framebuffer_test {
228c2ecf20Sopenharmony_ci	int buffer_created;
238c2ecf20Sopenharmony_ci	struct drm_mode_fb_cmd2 cmd;
248c2ecf20Sopenharmony_ci	const char *name;
258c2ecf20Sopenharmony_ci};
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_cistatic struct drm_framebuffer_test createbuffer_tests[] = {
288c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "ABGR8888 normal sizes",
298c2ecf20Sopenharmony_ci	.cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_ABGR8888,
308c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .pitches = { 4 * 600, 0, 0 },
318c2ecf20Sopenharmony_ci	}
328c2ecf20Sopenharmony_ci},
338c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "ABGR8888 max sizes",
348c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888,
358c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 },
368c2ecf20Sopenharmony_ci	}
378c2ecf20Sopenharmony_ci},
388c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "ABGR8888 pitch greater than min required",
398c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888,
408c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .pitches = { 4 * MAX_WIDTH + 1, 0, 0 },
418c2ecf20Sopenharmony_ci	}
428c2ecf20Sopenharmony_ci},
438c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "ABGR8888 pitch less than min required",
448c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888,
458c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .pitches = { 4 * MAX_WIDTH - 1, 0, 0 },
468c2ecf20Sopenharmony_ci	}
478c2ecf20Sopenharmony_ci},
488c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "ABGR8888 Invalid width",
498c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH + 1, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888,
508c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .pitches = { 4 * (MAX_WIDTH + 1), 0, 0 },
518c2ecf20Sopenharmony_ci	}
528c2ecf20Sopenharmony_ci},
538c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "ABGR8888 Invalid buffer handle",
548c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888,
558c2ecf20Sopenharmony_ci		 .handles = { 0, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 },
568c2ecf20Sopenharmony_ci	}
578c2ecf20Sopenharmony_ci},
588c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "No pixel format",
598c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = 0,
608c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 },
618c2ecf20Sopenharmony_ci	}
628c2ecf20Sopenharmony_ci},
638c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "ABGR8888 Width 0",
648c2ecf20Sopenharmony_ci	.cmd = { .width = 0, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888,
658c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 },
668c2ecf20Sopenharmony_ci	}
678c2ecf20Sopenharmony_ci},
688c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "ABGR8888 Height 0",
698c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = 0, .pixel_format = DRM_FORMAT_ABGR8888,
708c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 },
718c2ecf20Sopenharmony_ci	}
728c2ecf20Sopenharmony_ci},
738c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "ABGR8888 Out of bound height * pitch combination",
748c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888,
758c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .offsets = { UINT_MAX - 1, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 },
768c2ecf20Sopenharmony_ci	}
778c2ecf20Sopenharmony_ci},
788c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "ABGR8888 Large buffer offset",
798c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888,
808c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 },
818c2ecf20Sopenharmony_ci	}
828c2ecf20Sopenharmony_ci},
838c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "ABGR8888 Set DRM_MODE_FB_MODIFIERS without modifiers",
848c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888,
858c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, 0, 0 },
868c2ecf20Sopenharmony_ci		 .pitches = { 4 * MAX_WIDTH, 0, 0 }, .flags = DRM_MODE_FB_MODIFIERS,
878c2ecf20Sopenharmony_ci	}
888c2ecf20Sopenharmony_ci},
898c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "ABGR8888 Valid buffer modifier",
908c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888,
918c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 },
928c2ecf20Sopenharmony_ci		 .flags = DRM_MODE_FB_MODIFIERS, .modifier = { AFBC_FORMAT_MOD_YTR, 0, 0 },
938c2ecf20Sopenharmony_ci	}
948c2ecf20Sopenharmony_ci},
958c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "ABGR8888 Invalid buffer modifier(DRM_FORMAT_MOD_SAMSUNG_64_32_TILE)",
968c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888,
978c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, 0, 0 },
988c2ecf20Sopenharmony_ci		 .pitches = { 4 * MAX_WIDTH, 0, 0 }, .flags = DRM_MODE_FB_MODIFIERS,
998c2ecf20Sopenharmony_ci		 .modifier = { DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, 0, 0 },
1008c2ecf20Sopenharmony_ci	}
1018c2ecf20Sopenharmony_ci},
1028c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "ABGR8888 Extra pitches without DRM_MODE_FB_MODIFIERS",
1038c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888,
1048c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, 0, 0 },
1058c2ecf20Sopenharmony_ci		 .pitches = { 4 * MAX_WIDTH, 4 * MAX_WIDTH, 0 },
1068c2ecf20Sopenharmony_ci	}
1078c2ecf20Sopenharmony_ci},
1088c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "ABGR8888 Extra pitches with DRM_MODE_FB_MODIFIERS",
1098c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888,
1108c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .flags = DRM_MODE_FB_MODIFIERS,
1118c2ecf20Sopenharmony_ci		 .pitches = { 4 * MAX_WIDTH, 4 * MAX_WIDTH, 0 },
1128c2ecf20Sopenharmony_ci	}
1138c2ecf20Sopenharmony_ci},
1148c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "NV12 Normal sizes",
1158c2ecf20Sopenharmony_ci	.cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_NV12,
1168c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 0 }, .pitches = { 600, 600, 0 },
1178c2ecf20Sopenharmony_ci	}
1188c2ecf20Sopenharmony_ci},
1198c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "NV12 Max sizes",
1208c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12,
1218c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 0 }, .pitches = { MAX_WIDTH, MAX_WIDTH, 0 },
1228c2ecf20Sopenharmony_ci	}
1238c2ecf20Sopenharmony_ci},
1248c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "NV12 Invalid pitch",
1258c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12,
1268c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 0 }, .pitches = { MAX_WIDTH, MAX_WIDTH - 1, 0 },
1278c2ecf20Sopenharmony_ci	}
1288c2ecf20Sopenharmony_ci},
1298c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "NV12 Invalid modifier/missing DRM_MODE_FB_MODIFIERS flag",
1308c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12,
1318c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 0 }, .modifier = { DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, 0, 0 },
1328c2ecf20Sopenharmony_ci		 .pitches = { MAX_WIDTH, MAX_WIDTH, 0 },
1338c2ecf20Sopenharmony_ci	}
1348c2ecf20Sopenharmony_ci},
1358c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "NV12 different  modifier per-plane",
1368c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12,
1378c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 0 }, .flags = DRM_MODE_FB_MODIFIERS,
1388c2ecf20Sopenharmony_ci		 .modifier = { DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, 0, 0 },
1398c2ecf20Sopenharmony_ci		 .pitches = { MAX_WIDTH, MAX_WIDTH, 0 },
1408c2ecf20Sopenharmony_ci	}
1418c2ecf20Sopenharmony_ci},
1428c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "NV12 with DRM_FORMAT_MOD_SAMSUNG_64_32_TILE",
1438c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12,
1448c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 0 }, .flags = DRM_MODE_FB_MODIFIERS,
1458c2ecf20Sopenharmony_ci		 .modifier = { DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, 0 },
1468c2ecf20Sopenharmony_ci		 .pitches = { MAX_WIDTH, MAX_WIDTH, 0 },
1478c2ecf20Sopenharmony_ci	}
1488c2ecf20Sopenharmony_ci},
1498c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "NV12 Valid modifiers without DRM_MODE_FB_MODIFIERS",
1508c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12,
1518c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 0 }, .modifier = { DRM_FORMAT_MOD_SAMSUNG_64_32_TILE,
1528c2ecf20Sopenharmony_ci						       DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, 0 },
1538c2ecf20Sopenharmony_ci		 .pitches = { MAX_WIDTH, MAX_WIDTH, 0 },
1548c2ecf20Sopenharmony_ci	}
1558c2ecf20Sopenharmony_ci},
1568c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "NV12 Modifier for inexistent plane",
1578c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12,
1588c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 0 }, .flags = DRM_MODE_FB_MODIFIERS,
1598c2ecf20Sopenharmony_ci		 .modifier = { DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, DRM_FORMAT_MOD_SAMSUNG_64_32_TILE,
1608c2ecf20Sopenharmony_ci			       DRM_FORMAT_MOD_SAMSUNG_64_32_TILE },
1618c2ecf20Sopenharmony_ci		 .pitches = { MAX_WIDTH, MAX_WIDTH, 0 },
1628c2ecf20Sopenharmony_ci	}
1638c2ecf20Sopenharmony_ci},
1648c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "NV12 Handle for inexistent plane",
1658c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12,
1668c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 1 }, .flags = DRM_MODE_FB_MODIFIERS, .pitches = { MAX_WIDTH, MAX_WIDTH, 0 },
1678c2ecf20Sopenharmony_ci	}
1688c2ecf20Sopenharmony_ci},
1698c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "NV12 Handle for inexistent plane without DRM_MODE_FB_MODIFIERS",
1708c2ecf20Sopenharmony_ci	.cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_NV12,
1718c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 1 }, .pitches = { 600, 600, 600 },
1728c2ecf20Sopenharmony_ci	}
1738c2ecf20Sopenharmony_ci},
1748c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "YVU420 Normal sizes",
1758c2ecf20Sopenharmony_ci	.cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_YVU420,
1768c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 1 }, .flags = DRM_MODE_FB_MODIFIERS,
1778c2ecf20Sopenharmony_ci		 .pitches = { 600, 300, 300 },
1788c2ecf20Sopenharmony_ci	}
1798c2ecf20Sopenharmony_ci},
1808c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "YVU420 DRM_MODE_FB_MODIFIERS set without modifier",
1818c2ecf20Sopenharmony_ci	.cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_YVU420,
1828c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 1 }, .pitches = { 600, 300, 300 },
1838c2ecf20Sopenharmony_ci	}
1848c2ecf20Sopenharmony_ci},
1858c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "YVU420 Max sizes",
1868c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420,
1878c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 1 }, .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2),
1888c2ecf20Sopenharmony_ci						      DIV_ROUND_UP(MAX_WIDTH, 2) },
1898c2ecf20Sopenharmony_ci	}
1908c2ecf20Sopenharmony_ci},
1918c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "YVU420 Invalid pitch",
1928c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420,
1938c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 1 }, .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2) - 1,
1948c2ecf20Sopenharmony_ci						      DIV_ROUND_UP(MAX_WIDTH, 2) },
1958c2ecf20Sopenharmony_ci	}
1968c2ecf20Sopenharmony_ci},
1978c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "YVU420 Different pitches",
1988c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420,
1998c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 1 }, .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2) + 1,
2008c2ecf20Sopenharmony_ci						      DIV_ROUND_UP(MAX_WIDTH, 2) + 7 },
2018c2ecf20Sopenharmony_ci	}
2028c2ecf20Sopenharmony_ci},
2038c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "YVU420 Different buffer offsets/pitches",
2048c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420,
2058c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 1 }, .offsets = { MAX_WIDTH, MAX_WIDTH  + MAX_WIDTH * MAX_HEIGHT,
2068c2ecf20Sopenharmony_ci						      MAX_WIDTH  + 2 * MAX_WIDTH * MAX_HEIGHT },
2078c2ecf20Sopenharmony_ci		 .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2) + 1, DIV_ROUND_UP(MAX_WIDTH, 2) + 7 },
2088c2ecf20Sopenharmony_ci	}
2098c2ecf20Sopenharmony_ci},
2108c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "YVU420 Modifier set just for plane 0, without DRM_MODE_FB_MODIFIERS",
2118c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420,
2128c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 1 }, .modifier = { AFBC_FORMAT_MOD_SPARSE, 0, 0 },
2138c2ecf20Sopenharmony_ci		 .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) },
2148c2ecf20Sopenharmony_ci	}
2158c2ecf20Sopenharmony_ci},
2168c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "YVU420 Modifier set just for planes 0, 1, without DRM_MODE_FB_MODIFIERS",
2178c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420,
2188c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 1 }, .modifier = { AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE, 0 },
2198c2ecf20Sopenharmony_ci		 .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) },
2208c2ecf20Sopenharmony_ci	}
2218c2ecf20Sopenharmony_ci},
2228c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "YVU420 Modifier set just for plane 0, 1, with DRM_MODE_FB_MODIFIERS",
2238c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420,
2248c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 1 }, .flags = DRM_MODE_FB_MODIFIERS,
2258c2ecf20Sopenharmony_ci		 .modifier = { AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE, 0 },
2268c2ecf20Sopenharmony_ci		 .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) },
2278c2ecf20Sopenharmony_ci	}
2288c2ecf20Sopenharmony_ci},
2298c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "YVU420 Valid modifier",
2308c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420,
2318c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 1 }, .flags = DRM_MODE_FB_MODIFIERS,
2328c2ecf20Sopenharmony_ci		 .modifier = { AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE },
2338c2ecf20Sopenharmony_ci		 .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) },
2348c2ecf20Sopenharmony_ci	}
2358c2ecf20Sopenharmony_ci},
2368c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "YVU420 Different modifiers per plane",
2378c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420,
2388c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 1 }, .flags = DRM_MODE_FB_MODIFIERS,
2398c2ecf20Sopenharmony_ci		 .modifier = { AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE | AFBC_FORMAT_MOD_YTR,
2408c2ecf20Sopenharmony_ci			       AFBC_FORMAT_MOD_SPARSE },
2418c2ecf20Sopenharmony_ci		 .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) },
2428c2ecf20Sopenharmony_ci	}
2438c2ecf20Sopenharmony_ci},
2448c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "YVU420 Modifier for inexistent plane",
2458c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420,
2468c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 1 }, .flags = DRM_MODE_FB_MODIFIERS,
2478c2ecf20Sopenharmony_ci		 .modifier = { AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE,
2488c2ecf20Sopenharmony_ci			       AFBC_FORMAT_MOD_SPARSE },
2498c2ecf20Sopenharmony_ci		 .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) },
2508c2ecf20Sopenharmony_ci	}
2518c2ecf20Sopenharmony_ci},
2528c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "X0L2 Normal sizes",
2538c2ecf20Sopenharmony_ci	.cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_X0L2,
2548c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .pitches = { 1200, 0, 0 }
2558c2ecf20Sopenharmony_ci	}
2568c2ecf20Sopenharmony_ci},
2578c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "X0L2 Max sizes",
2588c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2,
2598c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .pitches = { 2 * MAX_WIDTH, 0, 0 }
2608c2ecf20Sopenharmony_ci	}
2618c2ecf20Sopenharmony_ci},
2628c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "X0L2 Invalid pitch",
2638c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2,
2648c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .pitches = { 2 * MAX_WIDTH - 1, 0, 0 }
2658c2ecf20Sopenharmony_ci	}
2668c2ecf20Sopenharmony_ci},
2678c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "X0L2 Pitch greater than minimum required",
2688c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2,
2698c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .pitches = { 2 * MAX_WIDTH + 1, 0, 0 }
2708c2ecf20Sopenharmony_ci	}
2718c2ecf20Sopenharmony_ci},
2728c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "X0L2 Handle for inexistent plane",
2738c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2,
2748c2ecf20Sopenharmony_ci		 .handles = { 1, 1, 0 }, .flags = DRM_MODE_FB_MODIFIERS,
2758c2ecf20Sopenharmony_ci		 .pitches = { 2 * MAX_WIDTH + 1, 0, 0 }
2768c2ecf20Sopenharmony_ci	}
2778c2ecf20Sopenharmony_ci},
2788c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "X0L2 Offset for inexistent plane, without DRM_MODE_FB_MODIFIERS set",
2798c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2,
2808c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .offsets = { 0, 0, 3 },
2818c2ecf20Sopenharmony_ci		 .pitches = { 2 * MAX_WIDTH + 1, 0, 0 }
2828c2ecf20Sopenharmony_ci	}
2838c2ecf20Sopenharmony_ci},
2848c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "X0L2 Modifier without DRM_MODE_FB_MODIFIERS set",
2858c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2,
2868c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .pitches = { 2 * MAX_WIDTH + 1, 0, 0 },
2878c2ecf20Sopenharmony_ci		 .modifier = { AFBC_FORMAT_MOD_SPARSE, 0, 0 },
2888c2ecf20Sopenharmony_ci	}
2898c2ecf20Sopenharmony_ci},
2908c2ecf20Sopenharmony_ci{ .buffer_created = 1, .name = "X0L2 Valid modifier",
2918c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2,
2928c2ecf20Sopenharmony_ci		 .handles = { 1, 0, 0 }, .pitches = { 2 * MAX_WIDTH + 1, 0, 0 },
2938c2ecf20Sopenharmony_ci		 .modifier = { AFBC_FORMAT_MOD_SPARSE, 0, 0 }, .flags = DRM_MODE_FB_MODIFIERS,
2948c2ecf20Sopenharmony_ci	}
2958c2ecf20Sopenharmony_ci},
2968c2ecf20Sopenharmony_ci{ .buffer_created = 0, .name = "X0L2 Modifier for inexistent plane",
2978c2ecf20Sopenharmony_ci	.cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT,
2988c2ecf20Sopenharmony_ci		 .pixel_format = DRM_FORMAT_X0L2, .handles = { 1, 0, 0 },
2998c2ecf20Sopenharmony_ci		 .pitches = { 2 * MAX_WIDTH + 1, 0, 0 },
3008c2ecf20Sopenharmony_ci		 .modifier = { AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE, 0 },
3018c2ecf20Sopenharmony_ci		 .flags = DRM_MODE_FB_MODIFIERS,
3028c2ecf20Sopenharmony_ci	}
3038c2ecf20Sopenharmony_ci},
3048c2ecf20Sopenharmony_ci};
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_cistatic struct drm_framebuffer *fb_create_mock(struct drm_device *dev,
3078c2ecf20Sopenharmony_ci					      struct drm_file *file_priv,
3088c2ecf20Sopenharmony_ci					      const struct drm_mode_fb_cmd2 *mode_cmd)
3098c2ecf20Sopenharmony_ci{
3108c2ecf20Sopenharmony_ci	int *buffer_created = dev->dev_private;
3118c2ecf20Sopenharmony_ci	*buffer_created = 1;
3128c2ecf20Sopenharmony_ci	return ERR_PTR(-EINVAL);
3138c2ecf20Sopenharmony_ci}
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_cistatic struct drm_mode_config_funcs mock_config_funcs = {
3168c2ecf20Sopenharmony_ci	.fb_create = fb_create_mock,
3178c2ecf20Sopenharmony_ci};
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_cistatic struct drm_device mock_drm_device = {
3208c2ecf20Sopenharmony_ci	.mode_config = {
3218c2ecf20Sopenharmony_ci		.min_width = MIN_WIDTH,
3228c2ecf20Sopenharmony_ci		.max_width = MAX_WIDTH,
3238c2ecf20Sopenharmony_ci		.min_height = MIN_HEIGHT,
3248c2ecf20Sopenharmony_ci		.max_height = MAX_HEIGHT,
3258c2ecf20Sopenharmony_ci		.allow_fb_modifiers = true,
3268c2ecf20Sopenharmony_ci		.funcs = &mock_config_funcs,
3278c2ecf20Sopenharmony_ci	},
3288c2ecf20Sopenharmony_ci};
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_cistatic int execute_drm_mode_fb_cmd2(struct drm_mode_fb_cmd2 *r)
3318c2ecf20Sopenharmony_ci{
3328c2ecf20Sopenharmony_ci	int buffer_created = 0;
3338c2ecf20Sopenharmony_ci	struct drm_framebuffer *fb;
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_ci	mock_drm_device.dev_private = &buffer_created;
3368c2ecf20Sopenharmony_ci	fb = drm_internal_framebuffer_create(&mock_drm_device, r, NULL);
3378c2ecf20Sopenharmony_ci	return buffer_created;
3388c2ecf20Sopenharmony_ci}
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_ciint igt_check_drm_framebuffer_create(void *ignored)
3418c2ecf20Sopenharmony_ci{
3428c2ecf20Sopenharmony_ci	int i = 0;
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(createbuffer_tests); i++) {
3458c2ecf20Sopenharmony_ci		FAIL(createbuffer_tests[i].buffer_created !=
3468c2ecf20Sopenharmony_ci				execute_drm_mode_fb_cmd2(&createbuffer_tests[i].cmd),
3478c2ecf20Sopenharmony_ci		     "Test %d: \"%s\" failed\n", i, createbuffer_tests[i].name);
3488c2ecf20Sopenharmony_ci	}
3498c2ecf20Sopenharmony_ci
3508c2ecf20Sopenharmony_ci	return 0;
3518c2ecf20Sopenharmony_ci}
352