xref: /aosp_15_r20/external/igt-gpu-tools/tests/kms_psr.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2013 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 "igt.h"
26*d83cc019SAndroid Build Coastguard Worker #include "igt_sysfs.h"
27*d83cc019SAndroid Build Coastguard Worker #include "igt_psr.h"
28*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
29*d83cc019SAndroid Build Coastguard Worker #include <stdbool.h>
30*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
31*d83cc019SAndroid Build Coastguard Worker #include <string.h>
32*d83cc019SAndroid Build Coastguard Worker #include "intel_bufmgr.h"
33*d83cc019SAndroid Build Coastguard Worker 
34*d83cc019SAndroid Build Coastguard Worker enum operations {
35*d83cc019SAndroid Build Coastguard Worker 	PAGE_FLIP,
36*d83cc019SAndroid Build Coastguard Worker 	MMAP_GTT,
37*d83cc019SAndroid Build Coastguard Worker 	MMAP_CPU,
38*d83cc019SAndroid Build Coastguard Worker 	BLT,
39*d83cc019SAndroid Build Coastguard Worker 	RENDER,
40*d83cc019SAndroid Build Coastguard Worker 	PLANE_MOVE,
41*d83cc019SAndroid Build Coastguard Worker 	PLANE_ONOFF,
42*d83cc019SAndroid Build Coastguard Worker };
43*d83cc019SAndroid Build Coastguard Worker 
op_str(enum operations op)44*d83cc019SAndroid Build Coastguard Worker static const char *op_str(enum operations op)
45*d83cc019SAndroid Build Coastguard Worker {
46*d83cc019SAndroid Build Coastguard Worker 	static const char * const name[] = {
47*d83cc019SAndroid Build Coastguard Worker 		[PAGE_FLIP] = "page_flip",
48*d83cc019SAndroid Build Coastguard Worker 		[MMAP_GTT] = "mmap_gtt",
49*d83cc019SAndroid Build Coastguard Worker 		[MMAP_CPU] = "mmap_cpu",
50*d83cc019SAndroid Build Coastguard Worker 		[BLT] = "blt",
51*d83cc019SAndroid Build Coastguard Worker 		[RENDER] = "render",
52*d83cc019SAndroid Build Coastguard Worker 		[PLANE_MOVE] = "plane_move",
53*d83cc019SAndroid Build Coastguard Worker 		[PLANE_ONOFF] = "plane_onoff",
54*d83cc019SAndroid Build Coastguard Worker 	};
55*d83cc019SAndroid Build Coastguard Worker 
56*d83cc019SAndroid Build Coastguard Worker 	return name[op];
57*d83cc019SAndroid Build Coastguard Worker }
58*d83cc019SAndroid Build Coastguard Worker 
59*d83cc019SAndroid Build Coastguard Worker typedef struct {
60*d83cc019SAndroid Build Coastguard Worker 	int drm_fd;
61*d83cc019SAndroid Build Coastguard Worker 	int debugfs_fd;
62*d83cc019SAndroid Build Coastguard Worker 	enum operations op;
63*d83cc019SAndroid Build Coastguard Worker 	int test_plane_id;
64*d83cc019SAndroid Build Coastguard Worker 	enum psr_mode op_psr_mode;
65*d83cc019SAndroid Build Coastguard Worker 	uint32_t devid;
66*d83cc019SAndroid Build Coastguard Worker 	uint32_t crtc_id;
67*d83cc019SAndroid Build Coastguard Worker 	igt_display_t display;
68*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bufmgr *bufmgr;
69*d83cc019SAndroid Build Coastguard Worker 	struct igt_fb fb_green, fb_white;
70*d83cc019SAndroid Build Coastguard Worker 	igt_plane_t *test_plane;
71*d83cc019SAndroid Build Coastguard Worker 	int mod_size;
72*d83cc019SAndroid Build Coastguard Worker 	int mod_stride;
73*d83cc019SAndroid Build Coastguard Worker 	drmModeModeInfo *mode;
74*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output;
75*d83cc019SAndroid Build Coastguard Worker 	bool with_psr_disabled;
76*d83cc019SAndroid Build Coastguard Worker 	bool supports_psr2;
77*d83cc019SAndroid Build Coastguard Worker } data_t;
78*d83cc019SAndroid Build Coastguard Worker 
create_cursor_fb(data_t * data)79*d83cc019SAndroid Build Coastguard Worker static void create_cursor_fb(data_t *data)
80*d83cc019SAndroid Build Coastguard Worker {
81*d83cc019SAndroid Build Coastguard Worker 	cairo_t *cr;
82*d83cc019SAndroid Build Coastguard Worker 	uint32_t fb_id;
83*d83cc019SAndroid Build Coastguard Worker 
84*d83cc019SAndroid Build Coastguard Worker 	fb_id = igt_create_fb(data->drm_fd, 64, 64,
85*d83cc019SAndroid Build Coastguard Worker 			      DRM_FORMAT_ARGB8888, LOCAL_DRM_FORMAT_MOD_NONE,
86*d83cc019SAndroid Build Coastguard Worker 			      &data->fb_white);
87*d83cc019SAndroid Build Coastguard Worker 	igt_assert(fb_id);
88*d83cc019SAndroid Build Coastguard Worker 
89*d83cc019SAndroid Build Coastguard Worker 	cr = igt_get_cairo_ctx(data->drm_fd, &data->fb_white);
90*d83cc019SAndroid Build Coastguard Worker 	igt_paint_color_alpha(cr, 0, 0, 64, 64, 1.0, 1.0, 1.0, 1.0);
91*d83cc019SAndroid Build Coastguard Worker 	igt_put_cairo_ctx(data->drm_fd, &data->fb_white, cr);
92*d83cc019SAndroid Build Coastguard Worker }
93*d83cc019SAndroid Build Coastguard Worker 
setup_output(data_t * data)94*d83cc019SAndroid Build Coastguard Worker static void setup_output(data_t *data)
95*d83cc019SAndroid Build Coastguard Worker {
96*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = &data->display;
97*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output;
98*d83cc019SAndroid Build Coastguard Worker 	enum pipe pipe;
99*d83cc019SAndroid Build Coastguard Worker 
100*d83cc019SAndroid Build Coastguard Worker 	for_each_pipe_with_valid_output(display, pipe, output) {
101*d83cc019SAndroid Build Coastguard Worker 		drmModeConnectorPtr c = output->config.connector;
102*d83cc019SAndroid Build Coastguard Worker 
103*d83cc019SAndroid Build Coastguard Worker 		if (c->connector_type != DRM_MODE_CONNECTOR_eDP)
104*d83cc019SAndroid Build Coastguard Worker 			continue;
105*d83cc019SAndroid Build Coastguard Worker 
106*d83cc019SAndroid Build Coastguard Worker 		igt_output_set_pipe(output, pipe);
107*d83cc019SAndroid Build Coastguard Worker 		data->crtc_id = output->config.crtc->crtc_id;
108*d83cc019SAndroid Build Coastguard Worker 		data->output = output;
109*d83cc019SAndroid Build Coastguard Worker 		data->mode = igt_output_get_mode(output);
110*d83cc019SAndroid Build Coastguard Worker 
111*d83cc019SAndroid Build Coastguard Worker 		return;
112*d83cc019SAndroid Build Coastguard Worker 	}
113*d83cc019SAndroid Build Coastguard Worker }
114*d83cc019SAndroid Build Coastguard Worker 
display_init(data_t * data)115*d83cc019SAndroid Build Coastguard Worker static void display_init(data_t *data)
116*d83cc019SAndroid Build Coastguard Worker {
117*d83cc019SAndroid Build Coastguard Worker 	igt_display_require(&data->display, data->drm_fd);
118*d83cc019SAndroid Build Coastguard Worker 	setup_output(data);
119*d83cc019SAndroid Build Coastguard Worker }
120*d83cc019SAndroid Build Coastguard Worker 
display_fini(data_t * data)121*d83cc019SAndroid Build Coastguard Worker static void display_fini(data_t *data)
122*d83cc019SAndroid Build Coastguard Worker {
123*d83cc019SAndroid Build Coastguard Worker 	igt_display_fini(&data->display);
124*d83cc019SAndroid Build Coastguard Worker }
125*d83cc019SAndroid Build Coastguard Worker 
fill_blt(data_t * data,uint32_t handle,unsigned char color)126*d83cc019SAndroid Build Coastguard Worker static void fill_blt(data_t *data, uint32_t handle, unsigned char color)
127*d83cc019SAndroid Build Coastguard Worker {
128*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo *dst = gem_handle_to_libdrm_bo(data->bufmgr,
129*d83cc019SAndroid Build Coastguard Worker 						    data->drm_fd,
130*d83cc019SAndroid Build Coastguard Worker 						    "", handle);
131*d83cc019SAndroid Build Coastguard Worker 	struct intel_batchbuffer *batch;
132*d83cc019SAndroid Build Coastguard Worker 
133*d83cc019SAndroid Build Coastguard Worker 	batch = intel_batchbuffer_alloc(data->bufmgr, data->devid);
134*d83cc019SAndroid Build Coastguard Worker 	igt_assert(batch);
135*d83cc019SAndroid Build Coastguard Worker 
136*d83cc019SAndroid Build Coastguard Worker 	COLOR_BLIT_COPY_BATCH_START(0);
137*d83cc019SAndroid Build Coastguard Worker 	OUT_BATCH((1 << 24) | (0xf0 << 16) | 0);
138*d83cc019SAndroid Build Coastguard Worker 	OUT_BATCH(0);
139*d83cc019SAndroid Build Coastguard Worker 	OUT_BATCH(0xfff << 16 | 0xfff);
140*d83cc019SAndroid Build Coastguard Worker 	OUT_RELOC(dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
141*d83cc019SAndroid Build Coastguard Worker 	OUT_BATCH(color);
142*d83cc019SAndroid Build Coastguard Worker 	ADVANCE_BATCH();
143*d83cc019SAndroid Build Coastguard Worker 
144*d83cc019SAndroid Build Coastguard Worker 	intel_batchbuffer_flush(batch);
145*d83cc019SAndroid Build Coastguard Worker 	intel_batchbuffer_free(batch);
146*d83cc019SAndroid Build Coastguard Worker 
147*d83cc019SAndroid Build Coastguard Worker 	gem_bo_busy(data->drm_fd, handle);
148*d83cc019SAndroid Build Coastguard Worker }
149*d83cc019SAndroid Build Coastguard Worker 
scratch_buf_init(struct igt_buf * buf,drm_intel_bo * bo,int size,int stride)150*d83cc019SAndroid Build Coastguard Worker static void scratch_buf_init(struct igt_buf *buf, drm_intel_bo *bo,
151*d83cc019SAndroid Build Coastguard Worker 			     int size, int stride)
152*d83cc019SAndroid Build Coastguard Worker {
153*d83cc019SAndroid Build Coastguard Worker 	memset(buf, 0, sizeof(*buf));
154*d83cc019SAndroid Build Coastguard Worker 
155*d83cc019SAndroid Build Coastguard Worker 	buf->bo = bo;
156*d83cc019SAndroid Build Coastguard Worker 	buf->stride = stride;
157*d83cc019SAndroid Build Coastguard Worker 	buf->tiling = I915_TILING_X;
158*d83cc019SAndroid Build Coastguard Worker 	buf->size = size;
159*d83cc019SAndroid Build Coastguard Worker 	buf->bpp = 32;
160*d83cc019SAndroid Build Coastguard Worker }
161*d83cc019SAndroid Build Coastguard Worker 
fill_render(data_t * data,uint32_t handle,unsigned char color)162*d83cc019SAndroid Build Coastguard Worker static void fill_render(data_t *data, uint32_t handle, unsigned char color)
163*d83cc019SAndroid Build Coastguard Worker {
164*d83cc019SAndroid Build Coastguard Worker 	drm_intel_bo *src, *dst;
165*d83cc019SAndroid Build Coastguard Worker 	struct intel_batchbuffer *batch;
166*d83cc019SAndroid Build Coastguard Worker 	struct igt_buf src_buf, dst_buf;
167*d83cc019SAndroid Build Coastguard Worker 	const uint8_t buf[4] = { color, color, color, color };
168*d83cc019SAndroid Build Coastguard Worker 	igt_render_copyfunc_t rendercopy = igt_get_render_copyfunc(data->devid);
169*d83cc019SAndroid Build Coastguard Worker 
170*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on(!rendercopy);
171*d83cc019SAndroid Build Coastguard Worker 
172*d83cc019SAndroid Build Coastguard Worker 	dst = gem_handle_to_libdrm_bo(data->bufmgr, data->drm_fd, "", handle);
173*d83cc019SAndroid Build Coastguard Worker 	igt_assert(dst);
174*d83cc019SAndroid Build Coastguard Worker 
175*d83cc019SAndroid Build Coastguard Worker 	src = drm_intel_bo_alloc(data->bufmgr, "", data->mod_size, 4096);
176*d83cc019SAndroid Build Coastguard Worker 	igt_assert(src);
177*d83cc019SAndroid Build Coastguard Worker 
178*d83cc019SAndroid Build Coastguard Worker 	gem_write(data->drm_fd, src->handle, 0, buf, 4);
179*d83cc019SAndroid Build Coastguard Worker 
180*d83cc019SAndroid Build Coastguard Worker 	scratch_buf_init(&src_buf, src, data->mod_size, data->mod_stride);
181*d83cc019SAndroid Build Coastguard Worker 	scratch_buf_init(&dst_buf, dst, data->mod_size, data->mod_stride);
182*d83cc019SAndroid Build Coastguard Worker 
183*d83cc019SAndroid Build Coastguard Worker 	batch = intel_batchbuffer_alloc(data->bufmgr, data->devid);
184*d83cc019SAndroid Build Coastguard Worker 	igt_assert(batch);
185*d83cc019SAndroid Build Coastguard Worker 
186*d83cc019SAndroid Build Coastguard Worker 	rendercopy(batch, NULL,
187*d83cc019SAndroid Build Coastguard Worker 		   &src_buf, 0, 0, 0xff, 0xff,
188*d83cc019SAndroid Build Coastguard Worker 		   &dst_buf, 0, 0);
189*d83cc019SAndroid Build Coastguard Worker 
190*d83cc019SAndroid Build Coastguard Worker 	intel_batchbuffer_free(batch);
191*d83cc019SAndroid Build Coastguard Worker 
192*d83cc019SAndroid Build Coastguard Worker 	gem_bo_busy(data->drm_fd, handle);
193*d83cc019SAndroid Build Coastguard Worker }
194*d83cc019SAndroid Build Coastguard Worker 
sink_support(data_t * data,enum psr_mode mode)195*d83cc019SAndroid Build Coastguard Worker static bool sink_support(data_t *data, enum psr_mode mode)
196*d83cc019SAndroid Build Coastguard Worker {
197*d83cc019SAndroid Build Coastguard Worker 	return data->with_psr_disabled ||
198*d83cc019SAndroid Build Coastguard Worker 	       psr_sink_support(data->debugfs_fd, mode);
199*d83cc019SAndroid Build Coastguard Worker }
200*d83cc019SAndroid Build Coastguard Worker 
psr_wait_entry_if_enabled(data_t * data)201*d83cc019SAndroid Build Coastguard Worker static bool psr_wait_entry_if_enabled(data_t *data)
202*d83cc019SAndroid Build Coastguard Worker {
203*d83cc019SAndroid Build Coastguard Worker 	if (data->with_psr_disabled)
204*d83cc019SAndroid Build Coastguard Worker 		return true;
205*d83cc019SAndroid Build Coastguard Worker 
206*d83cc019SAndroid Build Coastguard Worker 	return psr_wait_entry(data->debugfs_fd, data->op_psr_mode);
207*d83cc019SAndroid Build Coastguard Worker }
208*d83cc019SAndroid Build Coastguard Worker 
psr_wait_update_if_enabled(data_t * data)209*d83cc019SAndroid Build Coastguard Worker static bool psr_wait_update_if_enabled(data_t *data)
210*d83cc019SAndroid Build Coastguard Worker {
211*d83cc019SAndroid Build Coastguard Worker 	if (data->with_psr_disabled)
212*d83cc019SAndroid Build Coastguard Worker 		return true;
213*d83cc019SAndroid Build Coastguard Worker 
214*d83cc019SAndroid Build Coastguard Worker 	return psr_wait_update(data->debugfs_fd, data->op_psr_mode);
215*d83cc019SAndroid Build Coastguard Worker }
216*d83cc019SAndroid Build Coastguard Worker 
psr_enable_if_enabled(data_t * data)217*d83cc019SAndroid Build Coastguard Worker static bool psr_enable_if_enabled(data_t *data)
218*d83cc019SAndroid Build Coastguard Worker {
219*d83cc019SAndroid Build Coastguard Worker 	if (data->with_psr_disabled)
220*d83cc019SAndroid Build Coastguard Worker 		return true;
221*d83cc019SAndroid Build Coastguard Worker 
222*d83cc019SAndroid Build Coastguard Worker 	return psr_enable(data->debugfs_fd, data->op_psr_mode);
223*d83cc019SAndroid Build Coastguard Worker }
224*d83cc019SAndroid Build Coastguard Worker 
manual(const char * expected)225*d83cc019SAndroid Build Coastguard Worker static inline void manual(const char *expected)
226*d83cc019SAndroid Build Coastguard Worker {
227*d83cc019SAndroid Build Coastguard Worker 	igt_debug_manual_check("all", expected);
228*d83cc019SAndroid Build Coastguard Worker }
229*d83cc019SAndroid Build Coastguard Worker 
drrs_disabled(data_t * data)230*d83cc019SAndroid Build Coastguard Worker static bool drrs_disabled(data_t *data)
231*d83cc019SAndroid Build Coastguard Worker {
232*d83cc019SAndroid Build Coastguard Worker 	char buf[512];
233*d83cc019SAndroid Build Coastguard Worker 
234*d83cc019SAndroid Build Coastguard Worker 	igt_debugfs_simple_read(data->debugfs_fd, "i915_drrs_status",
235*d83cc019SAndroid Build Coastguard Worker 			 buf, sizeof(buf));
236*d83cc019SAndroid Build Coastguard Worker 
237*d83cc019SAndroid Build Coastguard Worker 	return !strstr(buf, "DRRS Supported: Yes\n");
238*d83cc019SAndroid Build Coastguard Worker }
239*d83cc019SAndroid Build Coastguard Worker 
run_test(data_t * data)240*d83cc019SAndroid Build Coastguard Worker static void run_test(data_t *data)
241*d83cc019SAndroid Build Coastguard Worker {
242*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle = data->fb_white.gem_handle;
243*d83cc019SAndroid Build Coastguard Worker 	igt_plane_t *test_plane = data->test_plane;
244*d83cc019SAndroid Build Coastguard Worker 	void *ptr;
245*d83cc019SAndroid Build Coastguard Worker 	const char *expected = "";
246*d83cc019SAndroid Build Coastguard Worker 
247*d83cc019SAndroid Build Coastguard Worker 	/* Confirm that screen became Green */
248*d83cc019SAndroid Build Coastguard Worker 	manual("screen GREEN");
249*d83cc019SAndroid Build Coastguard Worker 
250*d83cc019SAndroid Build Coastguard Worker 	/* Confirm screen stays Green after PSR got active */
251*d83cc019SAndroid Build Coastguard Worker 	igt_assert(psr_wait_entry_if_enabled(data));
252*d83cc019SAndroid Build Coastguard Worker 	manual("screen GREEN");
253*d83cc019SAndroid Build Coastguard Worker 
254*d83cc019SAndroid Build Coastguard Worker 	/* Setting a secondary fb/plane */
255*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_fb(test_plane, &data->fb_white);
256*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit(&data->display);
257*d83cc019SAndroid Build Coastguard Worker 
258*d83cc019SAndroid Build Coastguard Worker 	/* Confirm it is not Green anymore */
259*d83cc019SAndroid Build Coastguard Worker 	if (test_plane->type == DRM_PLANE_TYPE_PRIMARY)
260*d83cc019SAndroid Build Coastguard Worker 		manual("screen WHITE");
261*d83cc019SAndroid Build Coastguard Worker 	else
262*d83cc019SAndroid Build Coastguard Worker 		manual("GREEN background with WHITE box");
263*d83cc019SAndroid Build Coastguard Worker 
264*d83cc019SAndroid Build Coastguard Worker 	igt_assert(psr_wait_entry_if_enabled(data));
265*d83cc019SAndroid Build Coastguard Worker 	switch (data->op) {
266*d83cc019SAndroid Build Coastguard Worker 	case PAGE_FLIP:
267*d83cc019SAndroid Build Coastguard Worker 		/* Only in use when testing primary plane */
268*d83cc019SAndroid Build Coastguard Worker 		igt_assert(drmModePageFlip(data->drm_fd, data->crtc_id,
269*d83cc019SAndroid Build Coastguard Worker 					   data->fb_green.fb_id, 0, NULL) == 0);
270*d83cc019SAndroid Build Coastguard Worker 		expected = "GREEN";
271*d83cc019SAndroid Build Coastguard Worker 		break;
272*d83cc019SAndroid Build Coastguard Worker 	case MMAP_GTT:
273*d83cc019SAndroid Build Coastguard Worker 		ptr = gem_mmap__gtt(data->drm_fd, handle, data->mod_size,
274*d83cc019SAndroid Build Coastguard Worker 				    PROT_WRITE);
275*d83cc019SAndroid Build Coastguard Worker 		gem_set_domain(data->drm_fd, handle,
276*d83cc019SAndroid Build Coastguard Worker 			       I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
277*d83cc019SAndroid Build Coastguard Worker 		memset(ptr, 0xcc, data->mod_size);
278*d83cc019SAndroid Build Coastguard Worker 		munmap(ptr, data->mod_size);
279*d83cc019SAndroid Build Coastguard Worker 		expected = "BLACK or TRANSPARENT mark on top of plane in test";
280*d83cc019SAndroid Build Coastguard Worker 		break;
281*d83cc019SAndroid Build Coastguard Worker 	case MMAP_CPU:
282*d83cc019SAndroid Build Coastguard Worker 		ptr = gem_mmap__cpu(data->drm_fd, handle, 0, data->mod_size,
283*d83cc019SAndroid Build Coastguard Worker 				    PROT_WRITE);
284*d83cc019SAndroid Build Coastguard Worker 		gem_set_domain(data->drm_fd, handle,
285*d83cc019SAndroid Build Coastguard Worker 			       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
286*d83cc019SAndroid Build Coastguard Worker 		memset(ptr, 0, data->mod_size);
287*d83cc019SAndroid Build Coastguard Worker 		munmap(ptr, data->mod_size);
288*d83cc019SAndroid Build Coastguard Worker 		gem_sw_finish(data->drm_fd, handle);
289*d83cc019SAndroid Build Coastguard Worker 		expected = "BLACK or TRANSPARENT mark on top of plane in test";
290*d83cc019SAndroid Build Coastguard Worker 		break;
291*d83cc019SAndroid Build Coastguard Worker 	case BLT:
292*d83cc019SAndroid Build Coastguard Worker 		fill_blt(data, handle, 0);
293*d83cc019SAndroid Build Coastguard Worker 		expected = "BLACK or TRANSPARENT mark on top of plane in test";
294*d83cc019SAndroid Build Coastguard Worker 		break;
295*d83cc019SAndroid Build Coastguard Worker 	case RENDER:
296*d83cc019SAndroid Build Coastguard Worker 		fill_render(data, handle, 0);
297*d83cc019SAndroid Build Coastguard Worker 		expected = "BLACK or TRANSPARENT mark on top of plane in test";
298*d83cc019SAndroid Build Coastguard Worker 		break;
299*d83cc019SAndroid Build Coastguard Worker 	case PLANE_MOVE:
300*d83cc019SAndroid Build Coastguard Worker 		/* Only in use when testing Sprite and Cursor */
301*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_position(test_plane, 500, 500);
302*d83cc019SAndroid Build Coastguard Worker 		igt_display_commit(&data->display);
303*d83cc019SAndroid Build Coastguard Worker 		expected = "White box moved to 500x500";
304*d83cc019SAndroid Build Coastguard Worker 		break;
305*d83cc019SAndroid Build Coastguard Worker 	case PLANE_ONOFF:
306*d83cc019SAndroid Build Coastguard Worker 		/* Only in use when testing Sprite and Cursor */
307*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_fb(test_plane, NULL);
308*d83cc019SAndroid Build Coastguard Worker 		igt_display_commit(&data->display);
309*d83cc019SAndroid Build Coastguard Worker 		expected = "screen GREEN";
310*d83cc019SAndroid Build Coastguard Worker 		break;
311*d83cc019SAndroid Build Coastguard Worker 	}
312*d83cc019SAndroid Build Coastguard Worker 	igt_assert(psr_wait_update_if_enabled(data));
313*d83cc019SAndroid Build Coastguard Worker 	manual(expected);
314*d83cc019SAndroid Build Coastguard Worker }
315*d83cc019SAndroid Build Coastguard Worker 
test_cleanup(data_t * data)316*d83cc019SAndroid Build Coastguard Worker static void test_cleanup(data_t *data) {
317*d83cc019SAndroid Build Coastguard Worker 	igt_plane_t *primary;
318*d83cc019SAndroid Build Coastguard Worker 
319*d83cc019SAndroid Build Coastguard Worker 	primary = igt_output_get_plane_type(data->output,
320*d83cc019SAndroid Build Coastguard Worker 					    DRM_PLANE_TYPE_PRIMARY);
321*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_fb(primary, NULL);
322*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_fb(data->test_plane, NULL);
323*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit(&data->display);
324*d83cc019SAndroid Build Coastguard Worker 
325*d83cc019SAndroid Build Coastguard Worker 	igt_remove_fb(data->drm_fd, &data->fb_green);
326*d83cc019SAndroid Build Coastguard Worker 	igt_remove_fb(data->drm_fd, &data->fb_white);
327*d83cc019SAndroid Build Coastguard Worker }
328*d83cc019SAndroid Build Coastguard Worker 
setup_test_plane(data_t * data,int test_plane)329*d83cc019SAndroid Build Coastguard Worker static void setup_test_plane(data_t *data, int test_plane)
330*d83cc019SAndroid Build Coastguard Worker {
331*d83cc019SAndroid Build Coastguard Worker 	uint32_t white_h, white_v;
332*d83cc019SAndroid Build Coastguard Worker 	igt_plane_t *primary, *sprite, *cursor;
333*d83cc019SAndroid Build Coastguard Worker 
334*d83cc019SAndroid Build Coastguard Worker 	igt_create_color_fb(data->drm_fd,
335*d83cc019SAndroid Build Coastguard Worker 			    data->mode->hdisplay, data->mode->vdisplay,
336*d83cc019SAndroid Build Coastguard Worker 			    DRM_FORMAT_XRGB8888,
337*d83cc019SAndroid Build Coastguard Worker 			    LOCAL_I915_FORMAT_MOD_X_TILED,
338*d83cc019SAndroid Build Coastguard Worker 			    0.0, 1.0, 0.0,
339*d83cc019SAndroid Build Coastguard Worker 			    &data->fb_green);
340*d83cc019SAndroid Build Coastguard Worker 
341*d83cc019SAndroid Build Coastguard Worker 	primary = igt_output_get_plane_type(data->output,
342*d83cc019SAndroid Build Coastguard Worker 					    DRM_PLANE_TYPE_PRIMARY);
343*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_fb(primary, NULL);
344*d83cc019SAndroid Build Coastguard Worker 	data->test_plane = primary;
345*d83cc019SAndroid Build Coastguard Worker 
346*d83cc019SAndroid Build Coastguard Worker 	white_h = data->mode->hdisplay;
347*d83cc019SAndroid Build Coastguard Worker 	white_v = data->mode->vdisplay;
348*d83cc019SAndroid Build Coastguard Worker 
349*d83cc019SAndroid Build Coastguard Worker 	/* Ignoring pitch and bpp to avoid changing full screen */
350*d83cc019SAndroid Build Coastguard Worker 	data->mod_size = white_h * white_v;
351*d83cc019SAndroid Build Coastguard Worker 	data->mod_stride = white_h * 4;
352*d83cc019SAndroid Build Coastguard Worker 
353*d83cc019SAndroid Build Coastguard Worker 	switch (test_plane) {
354*d83cc019SAndroid Build Coastguard Worker 	case DRM_PLANE_TYPE_OVERLAY:
355*d83cc019SAndroid Build Coastguard Worker 		sprite = igt_output_get_plane_type(data->output,
356*d83cc019SAndroid Build Coastguard Worker 						   DRM_PLANE_TYPE_OVERLAY);
357*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_fb(sprite, NULL);
358*d83cc019SAndroid Build Coastguard Worker 		white_h = white_h/2;
359*d83cc019SAndroid Build Coastguard Worker 		white_v = white_v/2;
360*d83cc019SAndroid Build Coastguard Worker 		data->test_plane = sprite;
361*d83cc019SAndroid Build Coastguard Worker 	case DRM_PLANE_TYPE_PRIMARY:
362*d83cc019SAndroid Build Coastguard Worker 		igt_create_color_fb(data->drm_fd,
363*d83cc019SAndroid Build Coastguard Worker 				    white_h, white_v,
364*d83cc019SAndroid Build Coastguard Worker 				    DRM_FORMAT_XRGB8888,
365*d83cc019SAndroid Build Coastguard Worker 				    LOCAL_I915_FORMAT_MOD_X_TILED,
366*d83cc019SAndroid Build Coastguard Worker 				    1.0, 1.0, 1.0,
367*d83cc019SAndroid Build Coastguard Worker 				    &data->fb_white);
368*d83cc019SAndroid Build Coastguard Worker 		break;
369*d83cc019SAndroid Build Coastguard Worker 	case DRM_PLANE_TYPE_CURSOR:
370*d83cc019SAndroid Build Coastguard Worker 		cursor = igt_output_get_plane_type(data->output,
371*d83cc019SAndroid Build Coastguard Worker 						   DRM_PLANE_TYPE_CURSOR);
372*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_fb(cursor, NULL);
373*d83cc019SAndroid Build Coastguard Worker 		create_cursor_fb(data);
374*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_position(cursor, 0, 0);
375*d83cc019SAndroid Build Coastguard Worker 
376*d83cc019SAndroid Build Coastguard Worker 		/* Cursor is 64 x 64, ignoring pitch and bbp again */
377*d83cc019SAndroid Build Coastguard Worker 		data->mod_size = 64 * 64;
378*d83cc019SAndroid Build Coastguard Worker 		data->test_plane = cursor;
379*d83cc019SAndroid Build Coastguard Worker 		break;
380*d83cc019SAndroid Build Coastguard Worker 	}
381*d83cc019SAndroid Build Coastguard Worker 
382*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit(&data->display);
383*d83cc019SAndroid Build Coastguard Worker 
384*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_fb(primary, &data->fb_green);
385*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit(&data->display);
386*d83cc019SAndroid Build Coastguard Worker }
387*d83cc019SAndroid Build Coastguard Worker 
test_setup(data_t * data)388*d83cc019SAndroid Build Coastguard Worker static void test_setup(data_t *data)
389*d83cc019SAndroid Build Coastguard Worker {
390*d83cc019SAndroid Build Coastguard Worker 	if (data->op_psr_mode == PSR_MODE_2)
391*d83cc019SAndroid Build Coastguard Worker 		igt_require(data->supports_psr2);
392*d83cc019SAndroid Build Coastguard Worker 	psr_enable_if_enabled(data);
393*d83cc019SAndroid Build Coastguard Worker 	setup_test_plane(data, data->test_plane_id);
394*d83cc019SAndroid Build Coastguard Worker 	igt_assert(psr_wait_entry_if_enabled(data));
395*d83cc019SAndroid Build Coastguard Worker }
396*d83cc019SAndroid Build Coastguard Worker 
dpms_off_on(data_t * data)397*d83cc019SAndroid Build Coastguard Worker static void dpms_off_on(data_t *data)
398*d83cc019SAndroid Build Coastguard Worker {
399*d83cc019SAndroid Build Coastguard Worker 	kmstest_set_connector_dpms(data->drm_fd, data->output->config.connector,
400*d83cc019SAndroid Build Coastguard Worker 				   DRM_MODE_DPMS_OFF);
401*d83cc019SAndroid Build Coastguard Worker 	kmstest_set_connector_dpms(data->drm_fd, data->output->config.connector,
402*d83cc019SAndroid Build Coastguard Worker 				   DRM_MODE_DPMS_ON);
403*d83cc019SAndroid Build Coastguard Worker }
404*d83cc019SAndroid Build Coastguard Worker 
opt_handler(int opt,int opt_index,void * _data)405*d83cc019SAndroid Build Coastguard Worker static int opt_handler(int opt, int opt_index, void *_data)
406*d83cc019SAndroid Build Coastguard Worker {
407*d83cc019SAndroid Build Coastguard Worker 	data_t *data = _data;
408*d83cc019SAndroid Build Coastguard Worker 
409*d83cc019SAndroid Build Coastguard Worker 	switch (opt) {
410*d83cc019SAndroid Build Coastguard Worker 	case 'n':
411*d83cc019SAndroid Build Coastguard Worker 		data->with_psr_disabled = true;
412*d83cc019SAndroid Build Coastguard Worker 		break;
413*d83cc019SAndroid Build Coastguard Worker 	default:
414*d83cc019SAndroid Build Coastguard Worker 		return IGT_OPT_HANDLER_ERROR;
415*d83cc019SAndroid Build Coastguard Worker 	}
416*d83cc019SAndroid Build Coastguard Worker 
417*d83cc019SAndroid Build Coastguard Worker 	return IGT_OPT_HANDLER_SUCCESS;
418*d83cc019SAndroid Build Coastguard Worker }
419*d83cc019SAndroid Build Coastguard Worker 
420*d83cc019SAndroid Build Coastguard Worker const char *help_str =
421*d83cc019SAndroid Build Coastguard Worker 	"  --no-psr\tRun test without PSR/PSR2.";
422*d83cc019SAndroid Build Coastguard Worker static struct option long_options[] = {
423*d83cc019SAndroid Build Coastguard Worker 	{"no-psr", 0, 0, 'n'},
424*d83cc019SAndroid Build Coastguard Worker 	{ 0, 0, 0, 0 }
425*d83cc019SAndroid Build Coastguard Worker };
426*d83cc019SAndroid Build Coastguard Worker data_t data = {};
427*d83cc019SAndroid Build Coastguard Worker 
428*d83cc019SAndroid Build Coastguard Worker igt_main_args("", long_options, help_str, opt_handler, &data)
429*d83cc019SAndroid Build Coastguard Worker {
430*d83cc019SAndroid Build Coastguard Worker 	enum operations op;
431*d83cc019SAndroid Build Coastguard Worker 	const char *append_subtest_name[2] = {
432*d83cc019SAndroid Build Coastguard Worker 		"",
433*d83cc019SAndroid Build Coastguard Worker 		"psr2_"
434*d83cc019SAndroid Build Coastguard Worker 	};
435*d83cc019SAndroid Build Coastguard Worker 
436*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on_simulation();
437*d83cc019SAndroid Build Coastguard Worker 
438*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
439*d83cc019SAndroid Build Coastguard Worker 		data.drm_fd = drm_open_driver_master(DRIVER_INTEL);
440*d83cc019SAndroid Build Coastguard Worker 		data.debugfs_fd = igt_debugfs_dir(data.drm_fd);
441*d83cc019SAndroid Build Coastguard Worker 		kmstest_set_vt_graphics_mode();
442*d83cc019SAndroid Build Coastguard Worker 		data.devid = intel_get_drm_devid(data.drm_fd);
443*d83cc019SAndroid Build Coastguard Worker 
444*d83cc019SAndroid Build Coastguard Worker 		igt_require_f(sink_support(&data, PSR_MODE_1),
445*d83cc019SAndroid Build Coastguard Worker 			      "Sink does not support PSR\n");
446*d83cc019SAndroid Build Coastguard Worker 
447*d83cc019SAndroid Build Coastguard Worker 		data.supports_psr2 = sink_support(&data, PSR_MODE_2);
448*d83cc019SAndroid Build Coastguard Worker 
449*d83cc019SAndroid Build Coastguard Worker 		data.bufmgr = drm_intel_bufmgr_gem_init(data.drm_fd, 4096);
450*d83cc019SAndroid Build Coastguard Worker 		igt_assert(data.bufmgr);
451*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bufmgr_gem_enable_reuse(data.bufmgr);
452*d83cc019SAndroid Build Coastguard Worker 
453*d83cc019SAndroid Build Coastguard Worker 		display_init(&data);
454*d83cc019SAndroid Build Coastguard Worker 	}
455*d83cc019SAndroid Build Coastguard Worker 
456*d83cc019SAndroid Build Coastguard Worker 	for (data.op_psr_mode = PSR_MODE_1; data.op_psr_mode <= PSR_MODE_2;
457*d83cc019SAndroid Build Coastguard Worker 	     data.op_psr_mode++) {
458*d83cc019SAndroid Build Coastguard Worker 
459*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("%sbasic", append_subtest_name[data.op_psr_mode]) {
460*d83cc019SAndroid Build Coastguard Worker 			data.test_plane_id = DRM_PLANE_TYPE_PRIMARY;
461*d83cc019SAndroid Build Coastguard Worker 			test_setup(&data);
462*d83cc019SAndroid Build Coastguard Worker 			test_cleanup(&data);
463*d83cc019SAndroid Build Coastguard Worker 		}
464*d83cc019SAndroid Build Coastguard Worker 
465*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("%sno_drrs", append_subtest_name[data.op_psr_mode]) {
466*d83cc019SAndroid Build Coastguard Worker 			data.test_plane_id = DRM_PLANE_TYPE_PRIMARY;
467*d83cc019SAndroid Build Coastguard Worker 			test_setup(&data);
468*d83cc019SAndroid Build Coastguard Worker 			igt_assert(drrs_disabled(&data));
469*d83cc019SAndroid Build Coastguard Worker 			test_cleanup(&data);
470*d83cc019SAndroid Build Coastguard Worker 		}
471*d83cc019SAndroid Build Coastguard Worker 
472*d83cc019SAndroid Build Coastguard Worker 		for (op = PAGE_FLIP; op <= RENDER; op++) {
473*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_f("%sprimary_%s",
474*d83cc019SAndroid Build Coastguard Worker 				      append_subtest_name[data.op_psr_mode],
475*d83cc019SAndroid Build Coastguard Worker 				      op_str(op)) {
476*d83cc019SAndroid Build Coastguard Worker 				data.op = op;
477*d83cc019SAndroid Build Coastguard Worker 				data.test_plane_id = DRM_PLANE_TYPE_PRIMARY;
478*d83cc019SAndroid Build Coastguard Worker 				test_setup(&data);
479*d83cc019SAndroid Build Coastguard Worker 				run_test(&data);
480*d83cc019SAndroid Build Coastguard Worker 				test_cleanup(&data);
481*d83cc019SAndroid Build Coastguard Worker 			}
482*d83cc019SAndroid Build Coastguard Worker 		}
483*d83cc019SAndroid Build Coastguard Worker 
484*d83cc019SAndroid Build Coastguard Worker 		for (op = MMAP_GTT; op <= PLANE_ONOFF; op++) {
485*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_f("%ssprite_%s",
486*d83cc019SAndroid Build Coastguard Worker 				      append_subtest_name[data.op_psr_mode],
487*d83cc019SAndroid Build Coastguard Worker 				      op_str(op)) {
488*d83cc019SAndroid Build Coastguard Worker 				data.op = op;
489*d83cc019SAndroid Build Coastguard Worker 				data.test_plane_id = DRM_PLANE_TYPE_OVERLAY;
490*d83cc019SAndroid Build Coastguard Worker 				test_setup(&data);
491*d83cc019SAndroid Build Coastguard Worker 				run_test(&data);
492*d83cc019SAndroid Build Coastguard Worker 				test_cleanup(&data);
493*d83cc019SAndroid Build Coastguard Worker 			}
494*d83cc019SAndroid Build Coastguard Worker 
495*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_f("%scursor_%s",
496*d83cc019SAndroid Build Coastguard Worker 				      append_subtest_name[data.op_psr_mode],
497*d83cc019SAndroid Build Coastguard Worker 				      op_str(op)) {
498*d83cc019SAndroid Build Coastguard Worker 				data.op = op;
499*d83cc019SAndroid Build Coastguard Worker 				data.test_plane_id = DRM_PLANE_TYPE_CURSOR;
500*d83cc019SAndroid Build Coastguard Worker 				test_setup(&data);
501*d83cc019SAndroid Build Coastguard Worker 				run_test(&data);
502*d83cc019SAndroid Build Coastguard Worker 				test_cleanup(&data);
503*d83cc019SAndroid Build Coastguard Worker 			}
504*d83cc019SAndroid Build Coastguard Worker 		}
505*d83cc019SAndroid Build Coastguard Worker 
506*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("%sdpms", append_subtest_name[data.op_psr_mode]) {
507*d83cc019SAndroid Build Coastguard Worker 			data.op = RENDER;
508*d83cc019SAndroid Build Coastguard Worker 			data.test_plane_id = DRM_PLANE_TYPE_PRIMARY;
509*d83cc019SAndroid Build Coastguard Worker 			test_setup(&data);
510*d83cc019SAndroid Build Coastguard Worker 			dpms_off_on(&data);
511*d83cc019SAndroid Build Coastguard Worker 			run_test(&data);
512*d83cc019SAndroid Build Coastguard Worker 			test_cleanup(&data);
513*d83cc019SAndroid Build Coastguard Worker 		}
514*d83cc019SAndroid Build Coastguard Worker 
515*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("%ssuspend", append_subtest_name[data.op_psr_mode]) {
516*d83cc019SAndroid Build Coastguard Worker 			data.op = PLANE_ONOFF;
517*d83cc019SAndroid Build Coastguard Worker 			data.test_plane_id = DRM_PLANE_TYPE_CURSOR;
518*d83cc019SAndroid Build Coastguard Worker 			test_setup(&data);
519*d83cc019SAndroid Build Coastguard Worker 			igt_system_suspend_autoresume(SUSPEND_STATE_MEM,
520*d83cc019SAndroid Build Coastguard Worker 						      SUSPEND_TEST_NONE);
521*d83cc019SAndroid Build Coastguard Worker 			igt_assert(psr_wait_entry_if_enabled(&data));
522*d83cc019SAndroid Build Coastguard Worker 			run_test(&data);
523*d83cc019SAndroid Build Coastguard Worker 			test_cleanup(&data);
524*d83cc019SAndroid Build Coastguard Worker 		}
525*d83cc019SAndroid Build Coastguard Worker 	}
526*d83cc019SAndroid Build Coastguard Worker 
527*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
528*d83cc019SAndroid Build Coastguard Worker 		if (!data.with_psr_disabled)
529*d83cc019SAndroid Build Coastguard Worker 			psr_disable(data.debugfs_fd);
530*d83cc019SAndroid Build Coastguard Worker 
531*d83cc019SAndroid Build Coastguard Worker 		close(data.debugfs_fd);
532*d83cc019SAndroid Build Coastguard Worker 		drm_intel_bufmgr_destroy(data.bufmgr);
533*d83cc019SAndroid Build Coastguard Worker 		display_fini(&data);
534*d83cc019SAndroid Build Coastguard Worker 	}
535*d83cc019SAndroid Build Coastguard Worker }
536