xref: /aosp_15_r20/external/igt-gpu-tools/tests/kms_available_modes_crc.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2018 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker  *
4*d83cc019SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker  *
11*d83cc019SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker  * Software.
14*d83cc019SAndroid Build Coastguard Worker  *
15*d83cc019SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker  *
23*d83cc019SAndroid Build Coastguard Worker  */
24*d83cc019SAndroid Build Coastguard Worker 
25*d83cc019SAndroid Build Coastguard Worker #include "drm_mode.h"
26*d83cc019SAndroid Build Coastguard Worker #include "drm_fourcc.h"
27*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
28*d83cc019SAndroid Build Coastguard Worker 
29*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("CRC test all different plane modes which kernel advertises.");
30*d83cc019SAndroid Build Coastguard Worker 
31*d83cc019SAndroid Build Coastguard Worker typedef struct {
32*d83cc019SAndroid Build Coastguard Worker 	int gfx_fd;
33*d83cc019SAndroid Build Coastguard Worker 	igt_display_t display;
34*d83cc019SAndroid Build Coastguard Worker 	enum igt_commit_style commit;
35*d83cc019SAndroid Build Coastguard Worker 
36*d83cc019SAndroid Build Coastguard Worker 	struct igt_fb fb;
37*d83cc019SAndroid Build Coastguard Worker 	struct igt_fb primary_fb;
38*d83cc019SAndroid Build Coastguard Worker 
39*d83cc019SAndroid Build Coastguard Worker 	union {
40*d83cc019SAndroid Build Coastguard Worker 		char name[5];
41*d83cc019SAndroid Build Coastguard Worker 		uint32_t dword;
42*d83cc019SAndroid Build Coastguard Worker 	} format;
43*d83cc019SAndroid Build Coastguard Worker 	bool separateprimaryplane;
44*d83cc019SAndroid Build Coastguard Worker 
45*d83cc019SAndroid Build Coastguard Worker 	uint32_t gem_handle;
46*d83cc019SAndroid Build Coastguard Worker 	uint32_t gem_handle_yuv;
47*d83cc019SAndroid Build Coastguard Worker 	unsigned int size;
48*d83cc019SAndroid Build Coastguard Worker 	unsigned char* buf;
49*d83cc019SAndroid Build Coastguard Worker 
50*d83cc019SAndroid Build Coastguard Worker 	/*
51*d83cc019SAndroid Build Coastguard Worker 	 * comparison crcs
52*d83cc019SAndroid Build Coastguard Worker 	 */
53*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_crc_t *pipe_crc;
54*d83cc019SAndroid Build Coastguard Worker 
55*d83cc019SAndroid Build Coastguard Worker 	igt_crc_t cursor_crc;
56*d83cc019SAndroid Build Coastguard Worker 	igt_crc_t fullscreen_crc;
57*d83cc019SAndroid Build Coastguard Worker } data_t;
58*d83cc019SAndroid Build Coastguard Worker 
59*d83cc019SAndroid Build Coastguard Worker 
do_write(int fd,int handle,void * buf,int size)60*d83cc019SAndroid Build Coastguard Worker static void do_write(int fd, int handle, void *buf, int size)
61*d83cc019SAndroid Build Coastguard Worker {	void *screenbuf;
62*d83cc019SAndroid Build Coastguard Worker 
63*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
64*d83cc019SAndroid Build Coastguard Worker 	screenbuf = gem_mmap__gtt(fd, handle, size, PROT_WRITE);
65*d83cc019SAndroid Build Coastguard Worker 	memcpy(screenbuf, buf, size);
66*d83cc019SAndroid Build Coastguard Worker 	gem_munmap(screenbuf, size);
67*d83cc019SAndroid Build Coastguard Worker 	gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
68*d83cc019SAndroid Build Coastguard Worker 	gem_sync(fd, handle);
69*d83cc019SAndroid Build Coastguard Worker }
70*d83cc019SAndroid Build Coastguard Worker 
71*d83cc019SAndroid Build Coastguard Worker 
generate_comparison_crc_list(data_t * data,igt_output_t * output)72*d83cc019SAndroid Build Coastguard Worker static void generate_comparison_crc_list(data_t *data, igt_output_t *output)
73*d83cc019SAndroid Build Coastguard Worker {
74*d83cc019SAndroid Build Coastguard Worker 	drmModeModeInfo *mode;
75*d83cc019SAndroid Build Coastguard Worker 	uint64_t w, h;
76*d83cc019SAndroid Build Coastguard Worker 	int fbid;
77*d83cc019SAndroid Build Coastguard Worker 	cairo_t *cr;
78*d83cc019SAndroid Build Coastguard Worker 	igt_plane_t *primary;
79*d83cc019SAndroid Build Coastguard Worker 
80*d83cc019SAndroid Build Coastguard Worker 	mode = igt_output_get_mode(output);
81*d83cc019SAndroid Build Coastguard Worker 	fbid = igt_create_color_fb(data->gfx_fd,
82*d83cc019SAndroid Build Coastguard Worker 				   mode->hdisplay,
83*d83cc019SAndroid Build Coastguard Worker 				   mode->vdisplay,
84*d83cc019SAndroid Build Coastguard Worker 				   DRM_FORMAT_XRGB8888,
85*d83cc019SAndroid Build Coastguard Worker 				   LOCAL_DRM_FORMAT_MOD_NONE,
86*d83cc019SAndroid Build Coastguard Worker 				   0, 0, 0,
87*d83cc019SAndroid Build Coastguard Worker 				   &data->primary_fb);
88*d83cc019SAndroid Build Coastguard Worker 
89*d83cc019SAndroid Build Coastguard Worker 	igt_assert(fbid);
90*d83cc019SAndroid Build Coastguard Worker 
91*d83cc019SAndroid Build Coastguard Worker 	drmGetCap(data->gfx_fd, DRM_CAP_CURSOR_WIDTH, &w);
92*d83cc019SAndroid Build Coastguard Worker 	drmGetCap(data->gfx_fd, DRM_CAP_CURSOR_HEIGHT, &h);
93*d83cc019SAndroid Build Coastguard Worker 
94*d83cc019SAndroid Build Coastguard Worker 	cr = igt_get_cairo_ctx(data->gfx_fd, &data->primary_fb);
95*d83cc019SAndroid Build Coastguard Worker 	igt_paint_color(cr, 0, 0, mode->hdisplay, mode->vdisplay,
96*d83cc019SAndroid Build Coastguard Worker 			    0.0, 0.0, 0.0);
97*d83cc019SAndroid Build Coastguard Worker 	igt_paint_color(cr, 0, 0, w, h, 1.0, 1.0, 1.0);
98*d83cc019SAndroid Build Coastguard Worker 	igt_assert(cairo_status(cr) == 0);
99*d83cc019SAndroid Build Coastguard Worker 	igt_put_cairo_ctx(data->gfx_fd, &data->primary_fb, cr);
100*d83cc019SAndroid Build Coastguard Worker 
101*d83cc019SAndroid Build Coastguard Worker 	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
102*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_fb(primary, &data->primary_fb);
103*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit2(&data->display, data->commit);
104*d83cc019SAndroid Build Coastguard Worker 
105*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_crc_get_current(data->gfx_fd, data->pipe_crc, &data->cursor_crc);
106*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_fb(primary, NULL);
107*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit2(&data->display, data->commit);
108*d83cc019SAndroid Build Coastguard Worker 
109*d83cc019SAndroid Build Coastguard Worker 	cr = igt_get_cairo_ctx(data->gfx_fd, &data->primary_fb);
110*d83cc019SAndroid Build Coastguard Worker 	igt_paint_color(cr, 0, 0, mode->hdisplay, mode->vdisplay, 1.0, 1.0, 1.0);
111*d83cc019SAndroid Build Coastguard Worker 	igt_put_cairo_ctx(data->gfx_fd, &data->primary_fb, cr);
112*d83cc019SAndroid Build Coastguard Worker 
113*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_fb(primary, &data->primary_fb);
114*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit2(&data->display, data->commit);
115*d83cc019SAndroid Build Coastguard Worker 
116*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_crc_get_current(data->gfx_fd, data->pipe_crc, &data->fullscreen_crc);
117*d83cc019SAndroid Build Coastguard Worker 
118*d83cc019SAndroid Build Coastguard Worker 	igt_remove_fb(data->gfx_fd, &data->primary_fb);
119*d83cc019SAndroid Build Coastguard Worker }
120*d83cc019SAndroid Build Coastguard Worker 
121*d83cc019SAndroid Build Coastguard Worker static const struct {
122*d83cc019SAndroid Build Coastguard Worker 	uint32_t	fourcc;
123*d83cc019SAndroid Build Coastguard Worker 	char		zeropadding;
124*d83cc019SAndroid Build Coastguard Worker 	enum		{ BYTES_PP_1 = 1,
125*d83cc019SAndroid Build Coastguard Worker 				BYTES_PP_4 = 4} bpp;
126*d83cc019SAndroid Build Coastguard Worker 	uint32_t	value;
127*d83cc019SAndroid Build Coastguard Worker } fillers[] = {
128*d83cc019SAndroid Build Coastguard Worker 	{ DRM_FORMAT_XBGR2101010, 0, BYTES_PP_4, 0xffffffff},
129*d83cc019SAndroid Build Coastguard Worker 	{ 0, 0, 0, 0 }
130*d83cc019SAndroid Build Coastguard Worker };
131*d83cc019SAndroid Build Coastguard Worker 
132*d83cc019SAndroid Build Coastguard Worker /*
133*d83cc019SAndroid Build Coastguard Worker  * fill_in_fb tell in return value if selected mode should be
134*d83cc019SAndroid Build Coastguard Worker  * proceed to crc check
135*d83cc019SAndroid Build Coastguard Worker  */
fill_in_fb(data_t * data,igt_output_t * output,igt_plane_t * plane,uint32_t format)136*d83cc019SAndroid Build Coastguard Worker static bool fill_in_fb(data_t *data, igt_output_t *output, igt_plane_t *plane,
137*d83cc019SAndroid Build Coastguard Worker 		       uint32_t format)
138*d83cc019SAndroid Build Coastguard Worker {
139*d83cc019SAndroid Build Coastguard Worker 	signed i, c, writesize;
140*d83cc019SAndroid Build Coastguard Worker 	unsigned int* ptemp_32_buf;
141*d83cc019SAndroid Build Coastguard Worker 
142*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(fillers)-1; i++) {
143*d83cc019SAndroid Build Coastguard Worker 		if (fillers[i].fourcc == format)
144*d83cc019SAndroid Build Coastguard Worker 			break;
145*d83cc019SAndroid Build Coastguard Worker 	}
146*d83cc019SAndroid Build Coastguard Worker 
147*d83cc019SAndroid Build Coastguard Worker 	switch (fillers[i].bpp) {
148*d83cc019SAndroid Build Coastguard Worker 	case BYTES_PP_4:
149*d83cc019SAndroid Build Coastguard Worker 		ptemp_32_buf = (unsigned int*)data->buf;
150*d83cc019SAndroid Build Coastguard Worker 		for (c = 0; c < data->size/4; c++)
151*d83cc019SAndroid Build Coastguard Worker 			ptemp_32_buf[c] = fillers[i].value;
152*d83cc019SAndroid Build Coastguard Worker 		writesize = data->size;
153*d83cc019SAndroid Build Coastguard Worker 		break;
154*d83cc019SAndroid Build Coastguard Worker 	case BYTES_PP_1:
155*d83cc019SAndroid Build Coastguard Worker 		memset((void *)data->buf, fillers[i].value, data->size);
156*d83cc019SAndroid Build Coastguard Worker 		writesize = data->size;
157*d83cc019SAndroid Build Coastguard Worker 		break;
158*d83cc019SAndroid Build Coastguard Worker 	default:
159*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(0, "unknown bpp");
160*d83cc019SAndroid Build Coastguard Worker 	}
161*d83cc019SAndroid Build Coastguard Worker 
162*d83cc019SAndroid Build Coastguard Worker 	do_write(data->gfx_fd, data->gem_handle, (void*)data->buf, writesize);
163*d83cc019SAndroid Build Coastguard Worker 	return true;
164*d83cc019SAndroid Build Coastguard Worker }
165*d83cc019SAndroid Build Coastguard Worker 
166*d83cc019SAndroid Build Coastguard Worker 
setup_fb(data_t * data,igt_output_t * output,igt_plane_t * plane,uint32_t format)167*d83cc019SAndroid Build Coastguard Worker static bool setup_fb(data_t *data, igt_output_t *output, igt_plane_t *plane,
168*d83cc019SAndroid Build Coastguard Worker 		     uint32_t format)
169*d83cc019SAndroid Build Coastguard Worker {
170*d83cc019SAndroid Build Coastguard Worker 	drmModeModeInfo *mode;
171*d83cc019SAndroid Build Coastguard Worker 	uint64_t w, h;
172*d83cc019SAndroid Build Coastguard Worker 	signed ret, gemsize = 0;
173*d83cc019SAndroid Build Coastguard Worker 	unsigned tile_width, tile_height;
174*d83cc019SAndroid Build Coastguard Worker 	int num_planes = 1;
175*d83cc019SAndroid Build Coastguard Worker 	uint64_t tiling;
176*d83cc019SAndroid Build Coastguard Worker 	int bpp = 0;
177*d83cc019SAndroid Build Coastguard Worker 	int i;
178*d83cc019SAndroid Build Coastguard Worker 
179*d83cc019SAndroid Build Coastguard Worker 	mode = igt_output_get_mode(output);
180*d83cc019SAndroid Build Coastguard Worker 	if (plane->type != DRM_PLANE_TYPE_CURSOR) {
181*d83cc019SAndroid Build Coastguard Worker 		w = mode->hdisplay;
182*d83cc019SAndroid Build Coastguard Worker 		h = mode->vdisplay;
183*d83cc019SAndroid Build Coastguard Worker 		tiling = LOCAL_I915_FORMAT_MOD_X_TILED;
184*d83cc019SAndroid Build Coastguard Worker 	} else {
185*d83cc019SAndroid Build Coastguard Worker 		drmGetCap(data->gfx_fd, DRM_CAP_CURSOR_WIDTH, &w);
186*d83cc019SAndroid Build Coastguard Worker 		drmGetCap(data->gfx_fd, DRM_CAP_CURSOR_HEIGHT, &h);
187*d83cc019SAndroid Build Coastguard Worker 		tiling = LOCAL_DRM_FORMAT_MOD_NONE;
188*d83cc019SAndroid Build Coastguard Worker 	}
189*d83cc019SAndroid Build Coastguard Worker 
190*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(fillers)-1; i++) {
191*d83cc019SAndroid Build Coastguard Worker 		if (fillers[i].fourcc == format)
192*d83cc019SAndroid Build Coastguard Worker 			break;
193*d83cc019SAndroid Build Coastguard Worker 	}
194*d83cc019SAndroid Build Coastguard Worker 
195*d83cc019SAndroid Build Coastguard Worker 	switch (fillers[i].bpp) {
196*d83cc019SAndroid Build Coastguard Worker 	case BYTES_PP_1:
197*d83cc019SAndroid Build Coastguard Worker 		bpp = 8;
198*d83cc019SAndroid Build Coastguard Worker 		break;
199*d83cc019SAndroid Build Coastguard Worker 	case BYTES_PP_4:
200*d83cc019SAndroid Build Coastguard Worker 		bpp = 32;
201*d83cc019SAndroid Build Coastguard Worker 		break;
202*d83cc019SAndroid Build Coastguard Worker 	default:
203*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(0, "unknown bpp");
204*d83cc019SAndroid Build Coastguard Worker 	}
205*d83cc019SAndroid Build Coastguard Worker 
206*d83cc019SAndroid Build Coastguard Worker 	igt_get_fb_tile_size(data->gfx_fd, tiling, bpp,
207*d83cc019SAndroid Build Coastguard Worker 			     &tile_width, &tile_height);
208*d83cc019SAndroid Build Coastguard Worker 	data->fb.offsets[0] = 0;
209*d83cc019SAndroid Build Coastguard Worker 	data->fb.strides[0] = ALIGN(w * bpp / 8, tile_width);
210*d83cc019SAndroid Build Coastguard Worker 	gemsize = data->size = data->fb.strides[0] * ALIGN(h, tile_height);
211*d83cc019SAndroid Build Coastguard Worker 	data->buf = (unsigned char *)calloc(data->size*2, 1);
212*d83cc019SAndroid Build Coastguard Worker 
213*d83cc019SAndroid Build Coastguard Worker 	data->gem_handle = gem_create(data->gfx_fd, gemsize);
214*d83cc019SAndroid Build Coastguard Worker 	ret = __gem_set_tiling(data->gfx_fd, data->gem_handle,
215*d83cc019SAndroid Build Coastguard Worker 			       igt_fb_mod_to_tiling(tiling),
216*d83cc019SAndroid Build Coastguard Worker 			       data->fb.strides[0]);
217*d83cc019SAndroid Build Coastguard Worker 
218*d83cc019SAndroid Build Coastguard Worker 	data->fb.gem_handle = data->gem_handle;
219*d83cc019SAndroid Build Coastguard Worker 	data->fb.width = w;
220*d83cc019SAndroid Build Coastguard Worker 	data->fb.height = h;
221*d83cc019SAndroid Build Coastguard Worker 	fill_in_fb(data, output, plane, format);
222*d83cc019SAndroid Build Coastguard Worker 
223*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 0);
224*d83cc019SAndroid Build Coastguard Worker 
225*d83cc019SAndroid Build Coastguard Worker 	ret = __kms_addfb(data->gfx_fd, data->gem_handle, w, h,
226*d83cc019SAndroid Build Coastguard Worker 			  format, tiling, data->fb.strides, data->fb.offsets,
227*d83cc019SAndroid Build Coastguard Worker 			  num_planes, LOCAL_DRM_MODE_FB_MODIFIERS,
228*d83cc019SAndroid Build Coastguard Worker 			  &data->fb.fb_id);
229*d83cc019SAndroid Build Coastguard Worker 
230*d83cc019SAndroid Build Coastguard Worker 	if(ret < 0) {
231*d83cc019SAndroid Build Coastguard Worker 		igt_info("Creating fb for format %s failed, return code %d\n",
232*d83cc019SAndroid Build Coastguard Worker 			 (char*)&data->format.name, ret);
233*d83cc019SAndroid Build Coastguard Worker 
234*d83cc019SAndroid Build Coastguard Worker 		return false;
235*d83cc019SAndroid Build Coastguard Worker 	}
236*d83cc019SAndroid Build Coastguard Worker 
237*d83cc019SAndroid Build Coastguard Worker 	return true;
238*d83cc019SAndroid Build Coastguard Worker }
239*d83cc019SAndroid Build Coastguard Worker 
240*d83cc019SAndroid Build Coastguard Worker 
remove_fb(data_t * data,igt_output_t * output,igt_plane_t * plane)241*d83cc019SAndroid Build Coastguard Worker static void remove_fb(data_t* data, igt_output_t* output, igt_plane_t* plane)
242*d83cc019SAndroid Build Coastguard Worker {
243*d83cc019SAndroid Build Coastguard Worker 	if (data->separateprimaryplane) {
244*d83cc019SAndroid Build Coastguard Worker 		igt_plane_t* primary = igt_output_get_plane_type(output,
245*d83cc019SAndroid Build Coastguard Worker 								 DRM_PLANE_TYPE_PRIMARY);
246*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_fb(primary, NULL);
247*d83cc019SAndroid Build Coastguard Worker 		igt_remove_fb(data->gfx_fd, &data->primary_fb);
248*d83cc019SAndroid Build Coastguard Worker 		data->separateprimaryplane = false;
249*d83cc019SAndroid Build Coastguard Worker 	}
250*d83cc019SAndroid Build Coastguard Worker 
251*d83cc019SAndroid Build Coastguard Worker 	igt_remove_fb(data->gfx_fd, &data->fb);
252*d83cc019SAndroid Build Coastguard Worker 	free(data->buf);
253*d83cc019SAndroid Build Coastguard Worker 	data->buf = NULL;
254*d83cc019SAndroid Build Coastguard Worker }
255*d83cc019SAndroid Build Coastguard Worker 
256*d83cc019SAndroid Build Coastguard Worker 
prepare_crtc(data_t * data,igt_output_t * output,igt_plane_t * plane,uint32_t format)257*d83cc019SAndroid Build Coastguard Worker static bool prepare_crtc(data_t *data, igt_output_t *output,
258*d83cc019SAndroid Build Coastguard Worker 			 igt_plane_t *plane, uint32_t format)
259*d83cc019SAndroid Build Coastguard Worker {
260*d83cc019SAndroid Build Coastguard Worker 	drmModeModeInfo *mode;
261*d83cc019SAndroid Build Coastguard Worker 	igt_plane_t *primary;
262*d83cc019SAndroid Build Coastguard Worker 
263*d83cc019SAndroid Build Coastguard Worker 	if (plane->type != DRM_PLANE_TYPE_PRIMARY) {
264*d83cc019SAndroid Build Coastguard Worker 		mode = igt_output_get_mode(output);
265*d83cc019SAndroid Build Coastguard Worker 		igt_create_color_fb(data->gfx_fd,
266*d83cc019SAndroid Build Coastguard Worker 				    mode->hdisplay, mode->vdisplay,
267*d83cc019SAndroid Build Coastguard Worker 				    DRM_FORMAT_XRGB8888,
268*d83cc019SAndroid Build Coastguard Worker 				    LOCAL_DRM_FORMAT_MOD_NONE,
269*d83cc019SAndroid Build Coastguard Worker 				    0, 0, 0,
270*d83cc019SAndroid Build Coastguard Worker 				    &data->primary_fb);
271*d83cc019SAndroid Build Coastguard Worker 
272*d83cc019SAndroid Build Coastguard Worker 		primary = igt_output_get_plane_type(output,
273*d83cc019SAndroid Build Coastguard Worker 						    DRM_PLANE_TYPE_PRIMARY);
274*d83cc019SAndroid Build Coastguard Worker 
275*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_fb(primary, &data->primary_fb);
276*d83cc019SAndroid Build Coastguard Worker 		igt_display_commit2(&data->display, data->commit);
277*d83cc019SAndroid Build Coastguard Worker 		data->separateprimaryplane = true;
278*d83cc019SAndroid Build Coastguard Worker 	}
279*d83cc019SAndroid Build Coastguard Worker 
280*d83cc019SAndroid Build Coastguard Worker 	if (!setup_fb(data, output, plane, format))
281*d83cc019SAndroid Build Coastguard Worker 		return false;
282*d83cc019SAndroid Build Coastguard Worker 
283*d83cc019SAndroid Build Coastguard Worker 	return true;
284*d83cc019SAndroid Build Coastguard Worker }
285*d83cc019SAndroid Build Coastguard Worker 
286*d83cc019SAndroid Build Coastguard Worker 
287*d83cc019SAndroid Build Coastguard Worker static int
test_one_mode(data_t * data,igt_output_t * output,igt_plane_t * plane,int mode,enum pipe pipe)288*d83cc019SAndroid Build Coastguard Worker test_one_mode(data_t* data, igt_output_t *output, igt_plane_t* plane,
289*d83cc019SAndroid Build Coastguard Worker 	      int mode, enum pipe pipe)
290*d83cc019SAndroid Build Coastguard Worker {
291*d83cc019SAndroid Build Coastguard Worker 	igt_crc_t current_crc;
292*d83cc019SAndroid Build Coastguard Worker 	signed rVal = 0;
293*d83cc019SAndroid Build Coastguard Worker 	int i;
294*d83cc019SAndroid Build Coastguard Worker 
295*d83cc019SAndroid Build Coastguard Worker 	/*
296*d83cc019SAndroid Build Coastguard Worker 	 * Limit tests only to those fb formats listed in fillers table
297*d83cc019SAndroid Build Coastguard Worker 	 */
298*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(fillers)-1; i++) {
299*d83cc019SAndroid Build Coastguard Worker 		if (fillers[i].fourcc == mode)
300*d83cc019SAndroid Build Coastguard Worker 			break;
301*d83cc019SAndroid Build Coastguard Worker 	}
302*d83cc019SAndroid Build Coastguard Worker 
303*d83cc019SAndroid Build Coastguard Worker 	if (fillers[i].bpp == 0)
304*d83cc019SAndroid Build Coastguard Worker 		return false;
305*d83cc019SAndroid Build Coastguard Worker 
306*d83cc019SAndroid Build Coastguard Worker 	if (prepare_crtc(data, output, plane, mode)) {
307*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_fb(plane, &data->fb);
308*d83cc019SAndroid Build Coastguard Worker 		igt_fb_set_size(&data->fb, plane, data->fb.width, data->fb.height);
309*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_size(plane, data->fb.width, data->fb.height);
310*d83cc019SAndroid Build Coastguard Worker 		igt_fb_set_position(&data->fb, plane, 0, 0);
311*d83cc019SAndroid Build Coastguard Worker 		igt_display_commit2(&data->display, data->commit);
312*d83cc019SAndroid Build Coastguard Worker 
313*d83cc019SAndroid Build Coastguard Worker 		igt_wait_for_vblank(data->gfx_fd, pipe);
314*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_crc_get_current(data->gfx_fd, data->pipe_crc, &current_crc);
315*d83cc019SAndroid Build Coastguard Worker 
316*d83cc019SAndroid Build Coastguard Worker 		if (plane->type != DRM_PLANE_TYPE_CURSOR) {
317*d83cc019SAndroid Build Coastguard Worker 			if (!igt_check_crc_equal(&current_crc,
318*d83cc019SAndroid Build Coastguard Worker 				&data->fullscreen_crc)) {
319*d83cc019SAndroid Build Coastguard Worker 				igt_warn("crc mismatch. connector %s using pipe %s" \
320*d83cc019SAndroid Build Coastguard Worker 					" plane index %d mode %.4s\n",
321*d83cc019SAndroid Build Coastguard Worker 					igt_output_name(output),
322*d83cc019SAndroid Build Coastguard Worker 					kmstest_pipe_name(pipe),
323*d83cc019SAndroid Build Coastguard Worker 					plane->index,
324*d83cc019SAndroid Build Coastguard Worker 					(char *)&mode);
325*d83cc019SAndroid Build Coastguard Worker 				rVal++;
326*d83cc019SAndroid Build Coastguard Worker 			}
327*d83cc019SAndroid Build Coastguard Worker 		} else {
328*d83cc019SAndroid Build Coastguard Worker 			if (!igt_check_crc_equal(&current_crc,
329*d83cc019SAndroid Build Coastguard Worker 				&data->cursor_crc)) {
330*d83cc019SAndroid Build Coastguard Worker 				igt_warn("crc mismatch. connector %s using pipe %s" \
331*d83cc019SAndroid Build Coastguard Worker 					" plane index %d mode %.4s\n",
332*d83cc019SAndroid Build Coastguard Worker 					igt_output_name(output),
333*d83cc019SAndroid Build Coastguard Worker 					kmstest_pipe_name(pipe),
334*d83cc019SAndroid Build Coastguard Worker 					plane->index,
335*d83cc019SAndroid Build Coastguard Worker 					(char *)&mode);
336*d83cc019SAndroid Build Coastguard Worker 				rVal++;
337*d83cc019SAndroid Build Coastguard Worker 			}
338*d83cc019SAndroid Build Coastguard Worker 		}
339*d83cc019SAndroid Build Coastguard Worker 	}
340*d83cc019SAndroid Build Coastguard Worker 	remove_fb(data, output, plane);
341*d83cc019SAndroid Build Coastguard Worker 	return rVal;
342*d83cc019SAndroid Build Coastguard Worker }
343*d83cc019SAndroid Build Coastguard Worker 
344*d83cc019SAndroid Build Coastguard Worker 
345*d83cc019SAndroid Build Coastguard Worker static void
test_available_modes(data_t * data)346*d83cc019SAndroid Build Coastguard Worker test_available_modes(data_t* data)
347*d83cc019SAndroid Build Coastguard Worker {
348*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output;
349*d83cc019SAndroid Build Coastguard Worker 	igt_plane_t *plane;
350*d83cc019SAndroid Build Coastguard Worker 	int modeindex;
351*d83cc019SAndroid Build Coastguard Worker 	enum pipe pipe;
352*d83cc019SAndroid Build Coastguard Worker 	int invalids = 0, i, lut_size;
353*d83cc019SAndroid Build Coastguard Worker 	drmModePlane *modePlane;
354*d83cc019SAndroid Build Coastguard Worker 
355*d83cc019SAndroid Build Coastguard Worker 	struct {
356*d83cc019SAndroid Build Coastguard Worker 		uint16_t red;
357*d83cc019SAndroid Build Coastguard Worker 		uint16_t green;
358*d83cc019SAndroid Build Coastguard Worker 		uint16_t blue;
359*d83cc019SAndroid Build Coastguard Worker 		uint16_t reserved;
360*d83cc019SAndroid Build Coastguard Worker 	} *lut = NULL;
361*d83cc019SAndroid Build Coastguard Worker 
362*d83cc019SAndroid Build Coastguard Worker 	for_each_pipe_with_valid_output(&data->display, pipe, output) {
363*d83cc019SAndroid Build Coastguard Worker 		igt_output_set_pipe(output, pipe);
364*d83cc019SAndroid Build Coastguard Worker 		igt_display_commit2(&data->display, data->commit);
365*d83cc019SAndroid Build Coastguard Worker 
366*d83cc019SAndroid Build Coastguard Worker 		if (igt_pipe_obj_has_prop(&data->display.pipes[pipe], IGT_CRTC_GAMMA_LUT_SIZE)) {
367*d83cc019SAndroid Build Coastguard Worker 			lut_size = igt_pipe_get_prop(&data->display, pipe,
368*d83cc019SAndroid Build Coastguard Worker 						     IGT_CRTC_GAMMA_LUT_SIZE);
369*d83cc019SAndroid Build Coastguard Worker 
370*d83cc019SAndroid Build Coastguard Worker 			lut = calloc(sizeof(*lut), lut_size);
371*d83cc019SAndroid Build Coastguard Worker 
372*d83cc019SAndroid Build Coastguard Worker 			for (i = 0; i < lut_size; i++) {
373*d83cc019SAndroid Build Coastguard Worker 				lut[i].red = (i * 0xffff / (lut_size - 1)) & 0xfc00;
374*d83cc019SAndroid Build Coastguard Worker 				lut[i].green = (i * 0xffff / (lut_size - 1)) & 0xfc00;
375*d83cc019SAndroid Build Coastguard Worker 				lut[i].blue = (i * 0xffff / (lut_size - 1)) & 0xfc00;
376*d83cc019SAndroid Build Coastguard Worker 			}
377*d83cc019SAndroid Build Coastguard Worker 
378*d83cc019SAndroid Build Coastguard Worker 			igt_pipe_replace_prop_blob(&data->display, pipe,
379*d83cc019SAndroid Build Coastguard Worker 						   IGT_CRTC_GAMMA_LUT,
380*d83cc019SAndroid Build Coastguard Worker 						   lut, sizeof(*lut) * lut_size);
381*d83cc019SAndroid Build Coastguard Worker 			igt_display_commit2(&data->display, data->commit);
382*d83cc019SAndroid Build Coastguard Worker 
383*d83cc019SAndroid Build Coastguard Worker 			for (i = 0; i < lut_size; i++) {
384*d83cc019SAndroid Build Coastguard Worker 				lut[i].red = i * 0xffff / (lut_size - 1);
385*d83cc019SAndroid Build Coastguard Worker 				lut[i].green = i * 0xffff / (lut_size - 1);
386*d83cc019SAndroid Build Coastguard Worker 				lut[i].blue = i * 0xffff / (lut_size - 1);
387*d83cc019SAndroid Build Coastguard Worker 			}
388*d83cc019SAndroid Build Coastguard Worker 		}
389*d83cc019SAndroid Build Coastguard Worker 
390*d83cc019SAndroid Build Coastguard Worker 		data->pipe_crc = igt_pipe_crc_new(data->gfx_fd, pipe,
391*d83cc019SAndroid Build Coastguard Worker 						  INTEL_PIPE_CRC_SOURCE_AUTO);
392*d83cc019SAndroid Build Coastguard Worker 
393*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_crc_start(data->pipe_crc);
394*d83cc019SAndroid Build Coastguard Worker 
395*d83cc019SAndroid Build Coastguard Worker 		/*
396*d83cc019SAndroid Build Coastguard Worker 		 * regenerate comparison crcs for each pipe just in case.
397*d83cc019SAndroid Build Coastguard Worker 		 */
398*d83cc019SAndroid Build Coastguard Worker 		generate_comparison_crc_list(data, output);
399*d83cc019SAndroid Build Coastguard Worker 
400*d83cc019SAndroid Build Coastguard Worker 		for_each_plane_on_pipe(&data->display, pipe, plane) {
401*d83cc019SAndroid Build Coastguard Worker 			modePlane = drmModeGetPlane(data->gfx_fd,
402*d83cc019SAndroid Build Coastguard Worker 						    plane->drm_plane->plane_id);
403*d83cc019SAndroid Build Coastguard Worker 
404*d83cc019SAndroid Build Coastguard Worker 			if (plane->type == DRM_PLANE_TYPE_CURSOR)
405*d83cc019SAndroid Build Coastguard Worker 				continue;
406*d83cc019SAndroid Build Coastguard Worker 
407*d83cc019SAndroid Build Coastguard Worker 			for (modeindex = 0;
408*d83cc019SAndroid Build Coastguard Worker 			     modeindex < modePlane->count_formats;
409*d83cc019SAndroid Build Coastguard Worker 			     modeindex++) {
410*d83cc019SAndroid Build Coastguard Worker 				data->format.dword = modePlane->formats[modeindex];
411*d83cc019SAndroid Build Coastguard Worker 
412*d83cc019SAndroid Build Coastguard Worker 				invalids += test_one_mode(data, output,
413*d83cc019SAndroid Build Coastguard Worker 							  plane,
414*d83cc019SAndroid Build Coastguard Worker 							  modePlane->formats[modeindex],
415*d83cc019SAndroid Build Coastguard Worker 							  pipe);
416*d83cc019SAndroid Build Coastguard Worker 			}
417*d83cc019SAndroid Build Coastguard Worker 			drmModeFreePlane(modePlane);
418*d83cc019SAndroid Build Coastguard Worker 		}
419*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_crc_stop(data->pipe_crc);
420*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_crc_free(data->pipe_crc);
421*d83cc019SAndroid Build Coastguard Worker 
422*d83cc019SAndroid Build Coastguard Worker 		if (lut != NULL) {
423*d83cc019SAndroid Build Coastguard Worker 			igt_pipe_replace_prop_blob(&data->display, pipe,
424*d83cc019SAndroid Build Coastguard Worker 						   IGT_CRTC_GAMMA_LUT,
425*d83cc019SAndroid Build Coastguard Worker 						   lut, sizeof(*lut) * lut_size);
426*d83cc019SAndroid Build Coastguard Worker 			free(lut);
427*d83cc019SAndroid Build Coastguard Worker 			lut = NULL;
428*d83cc019SAndroid Build Coastguard Worker 		}
429*d83cc019SAndroid Build Coastguard Worker 
430*d83cc019SAndroid Build Coastguard Worker 		igt_output_set_pipe(output, PIPE_NONE);
431*d83cc019SAndroid Build Coastguard Worker 		igt_display_commit2(&data->display, data->commit);
432*d83cc019SAndroid Build Coastguard Worker 	}
433*d83cc019SAndroid Build Coastguard Worker 	igt_assert(invalids == 0);
434*d83cc019SAndroid Build Coastguard Worker }
435*d83cc019SAndroid Build Coastguard Worker 
436*d83cc019SAndroid Build Coastguard Worker 
437*d83cc019SAndroid Build Coastguard Worker igt_main
438*d83cc019SAndroid Build Coastguard Worker {
439*d83cc019SAndroid Build Coastguard Worker 	data_t data = {};
440*d83cc019SAndroid Build Coastguard Worker 
441*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on_simulation();
442*d83cc019SAndroid Build Coastguard Worker 
443*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
444*d83cc019SAndroid Build Coastguard Worker 		data.gfx_fd = drm_open_driver_master(DRIVER_INTEL);
445*d83cc019SAndroid Build Coastguard Worker 		kmstest_set_vt_graphics_mode();
446*d83cc019SAndroid Build Coastguard Worker 		igt_display_require(&data.display, data.gfx_fd);
447*d83cc019SAndroid Build Coastguard Worker 		igt_require_pipe_crc(data.gfx_fd);
448*d83cc019SAndroid Build Coastguard Worker 	}
449*d83cc019SAndroid Build Coastguard Worker 
450*d83cc019SAndroid Build Coastguard Worker 	data.commit = data.display.is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY;
451*d83cc019SAndroid Build Coastguard Worker 
452*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("available_mode_test_crc") {
453*d83cc019SAndroid Build Coastguard Worker 		test_available_modes(&data);
454*d83cc019SAndroid Build Coastguard Worker 	}
455*d83cc019SAndroid Build Coastguard Worker 
456*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
457*d83cc019SAndroid Build Coastguard Worker 		kmstest_restore_vt_mode();
458*d83cc019SAndroid Build Coastguard Worker 		igt_display_fini(&data.display);
459*d83cc019SAndroid Build Coastguard Worker 	}
460*d83cc019SAndroid Build Coastguard Worker }
461