blob: 1c25f2c81a34983420c0cba418d5f2df059f0ada [file] [log] [blame]
Rodrigo Vivi27d37a12014-03-19 22:43:51 -03001/*
2 * Copyright © 2013 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 */
24
Thomas Wood804e11f2015-08-17 17:57:43 +010025#include "igt.h"
Chris Wilsone08ed8a2017-03-24 20:52:44 +000026#include "igt_sysfs.h"
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030027#include <errno.h>
28#include <stdbool.h>
29#include <stdio.h>
30#include <string.h>
31
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030032#include "intel_bufmgr.h"
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030033
Rodrigo Vivi99efdc02014-09-09 17:58:45 -040034bool running_with_psr_disabled;
35
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -040036#define CRC_BLACK "000000000000"
37
Rodrigo Vivi99efdc02014-09-09 17:58:45 -040038enum operations {
39 PAGE_FLIP,
40 MMAP_GTT,
41 MMAP_GTT_WAITING,
42 MMAP_CPU,
43 BLT,
44 RENDER,
45 PLANE_MOVE,
46 PLANE_ONOFF,
47};
48
49static const char *op_str(enum operations op)
50{
51 static const char * const name[] = {
52 [PAGE_FLIP] = "page_flip",
53 [MMAP_GTT] = "mmap_gtt",
54 [MMAP_GTT_WAITING] = "mmap_gtt_waiting",
55 [MMAP_CPU] = "mmap_cpu",
56 [BLT] = "blt",
57 [RENDER] = "render",
58 [PLANE_MOVE] = "plane_move",
59 [PLANE_ONOFF] = "plane_onoff",
60 };
61
62 return name[op];
63}
Rodrigo Vivi1ab04452014-08-29 17:58:31 -040064
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030065typedef struct {
66 int drm_fd;
Robert Foss934062c2017-01-10 20:16:23 -050067 int test_plane;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -040068 enum operations op;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030069 uint32_t devid;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030070 uint32_t crtc_id;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030071 igt_display_t display;
Rodrigo Vivid4e6a512014-08-29 19:12:54 -040072 drm_intel_bufmgr *bufmgr;
73 struct igt_fb fb_green, fb_white;
74 igt_plane_t *primary, *sprite, *cursor;
Rodrigo Vivi00992f72014-12-05 20:01:41 -050075 int mod_size;
Rodrigo Vivi36ecc312015-04-14 18:04:01 -070076 int mod_stride;
Rodrigo Vivi782d5e72015-03-13 12:10:20 -040077 drmModeModeInfo *mode;
78 igt_output_t *output;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030079} data_t;
80
Rodrigo Vivid4e6a512014-08-29 19:12:54 -040081static void create_cursor_fb(data_t *data)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030082{
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030083 cairo_t *cr;
Rodrigo Vivid4e6a512014-08-29 19:12:54 -040084 uint32_t fb_id;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030085
Rodrigo Vivid4e6a512014-08-29 19:12:54 -040086 fb_id = igt_create_fb(data->drm_fd, 64, 64,
Tvrtko Ursuline36091d2015-03-03 14:11:01 +000087 DRM_FORMAT_ARGB8888, LOCAL_DRM_FORMAT_MOD_NONE,
Rodrigo Vivid4e6a512014-08-29 19:12:54 -040088 &data->fb_white);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030089 igt_assert(fb_id);
90
Rodrigo Vivid4e6a512014-08-29 19:12:54 -040091 cr = igt_get_cairo_ctx(data->drm_fd, &data->fb_white);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030092 igt_paint_color_alpha(cr, 0, 0, 64, 64, 1.0, 1.0, 1.0, 1.0);
93 igt_assert(cairo_status(cr) == 0);
94}
95
Rodrigo Vivi782d5e72015-03-13 12:10:20 -040096
97static void setup_output(data_t *data)
98{
99 igt_display_t *display = &data->display;
100 igt_output_t *output;
Maarten Lankhorstcd885952016-06-30 07:41:44 +0200101 enum pipe pipe;
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400102
Maarten Lankhorstcd885952016-06-30 07:41:44 +0200103 for_each_pipe_with_valid_output(display, pipe, output) {
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400104 drmModeConnectorPtr c = output->config.connector;
105
Maarten Lankhorstcd885952016-06-30 07:41:44 +0200106 if (c->connector_type != DRM_MODE_CONNECTOR_eDP)
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400107 continue;
108
Maarten Lankhorstcd885952016-06-30 07:41:44 +0200109 igt_output_set_pipe(output, pipe);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400110 data->crtc_id = output->config.crtc->crtc_id;
111 data->output = output;
112 data->mode = igt_output_get_mode(output);
113
114 return;
115 }
116}
117
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300118static void display_init(data_t *data)
119{
120 igt_display_init(&data->display, data->drm_fd);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400121 setup_output(data);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300122}
123
124static void display_fini(data_t *data)
125{
126 igt_display_fini(&data->display);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300127}
128
129static void fill_blt(data_t *data, uint32_t handle, unsigned char color)
130{
131 drm_intel_bo *dst = gem_handle_to_libdrm_bo(data->bufmgr,
132 data->drm_fd,
133 "", handle);
134 struct intel_batchbuffer *batch;
135
136 batch = intel_batchbuffer_alloc(data->bufmgr, data->devid);
137 igt_assert(batch);
138
Chris Wilson10552b52014-08-30 11:44:51 +0100139 COLOR_BLIT_COPY_BATCH_START(0);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300140 OUT_BATCH((1 << 24) | (0xf0 << 16) | 0);
Rodrigo Vivi1447d832014-09-03 18:18:15 -0400141 OUT_BATCH(0);
Rodrigo Vivi3cb21242014-12-05 19:43:34 -0500142 OUT_BATCH(0xfff << 16 | 0xfff);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300143 OUT_RELOC(dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
144 OUT_BATCH(color);
145 ADVANCE_BATCH();
146
147 intel_batchbuffer_flush(batch);
148 intel_batchbuffer_free(batch);
149
150 gem_bo_busy(data->drm_fd, handle);
151}
152
Rodrigo Vivi36ecc312015-04-14 18:04:01 -0700153static void scratch_buf_init(struct igt_buf *buf, drm_intel_bo *bo,
154 int size, int stride)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300155{
156 buf->bo = bo;
Rodrigo Vivi36ecc312015-04-14 18:04:01 -0700157 buf->stride = stride;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300158 buf->tiling = I915_TILING_X;
Rodrigo Vivi36ecc312015-04-14 18:04:01 -0700159 buf->size = size;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300160}
161
Rodrigo Vivifb004a62014-09-03 17:53:35 -0400162static void fill_render(data_t *data, uint32_t handle, unsigned char color)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300163{
164 drm_intel_bo *src, *dst;
165 struct intel_batchbuffer *batch;
166 struct igt_buf src_buf, dst_buf;
167 const uint8_t buf[4] = { color, color, color, color };
168 igt_render_copyfunc_t rendercopy = igt_get_render_copyfunc(data->devid);
169
170 igt_skip_on(!rendercopy);
171
172 dst = gem_handle_to_libdrm_bo(data->bufmgr, data->drm_fd, "", handle);
173 igt_assert(dst);
174
Rodrigo Vivi36ecc312015-04-14 18:04:01 -0700175 src = drm_intel_bo_alloc(data->bufmgr, "", data->mod_size, 4096);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300176 igt_assert(src);
177
178 gem_write(data->drm_fd, src->handle, 0, buf, 4);
179
Rodrigo Vivi36ecc312015-04-14 18:04:01 -0700180 scratch_buf_init(&src_buf, src, data->mod_size, data->mod_stride);
181 scratch_buf_init(&dst_buf, dst, data->mod_size, data->mod_stride);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300182
183 batch = intel_batchbuffer_alloc(data->bufmgr, data->devid);
184 igt_assert(batch);
185
Rodrigo Vivifb004a62014-09-03 17:53:35 -0400186 rendercopy(batch, NULL,
Rodrigo Vivif20690d2014-12-05 19:45:37 -0500187 &src_buf, 0, 0, 0xff, 0xff,
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300188 &dst_buf, 0, 0);
189
190 intel_batchbuffer_free(batch);
191
192 gem_bo_busy(data->drm_fd, handle);
193}
194
Paulo Zanoni75b286e2015-06-02 12:03:45 -0300195static bool psr_possible(data_t *data)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300196{
Rodrigo Vivi05ac6112016-01-08 07:40:45 -0800197 char buf[512];
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300198
Chris Wilson83884e92017-03-21 17:16:03 +0000199 igt_debugfs_read(data->drm_fd, "i915_edp_psr_status", buf);
Rodrigo Vivi1ab04452014-08-29 17:58:31 -0400200
Rodrigo Vivi05ac6112016-01-08 07:40:45 -0800201 return running_with_psr_disabled ||
202 strstr(buf, "Sink_Support: yes\n");
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300203}
204
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700205static bool psr_active(data_t *data)
206{
Rodrigo Vivi05ac6112016-01-08 07:40:45 -0800207 char buf[512];
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700208
Chris Wilson83884e92017-03-21 17:16:03 +0000209 igt_debugfs_read(data->drm_fd, "i915_edp_psr_status", buf);
Rodrigo Vivi1ab04452014-08-29 17:58:31 -0400210
Rodrigo Vivi05ac6112016-01-08 07:40:45 -0800211 return running_with_psr_disabled ||
212 strstr(buf, "HW Enabled & Active bit: yes\n");
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700213}
214
Rodrigo Vivifd9ef1b2015-03-13 12:28:07 -0400215static bool wait_psr_entry(data_t *data)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300216{
Rodrigo Vivi4a004d92015-12-07 01:26:17 -0800217 int timeout = 5;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300218 while (timeout--) {
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700219 if (psr_active(data))
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300220 return true;
221 sleep(1);
222 }
223 return false;
224}
225
226static void get_sink_crc(data_t *data, char *crc) {
Chris Wilsone08ed8a2017-03-24 20:52:44 +0000227 int dir;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300228
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500229 if (igt_interactive_debug)
230 return;
231
Chris Wilsone08ed8a2017-03-24 20:52:44 +0000232 dir = igt_debugfs_dir(data->drm_fd);
233 igt_require_f(igt_sysfs_scanf(dir, "i915_sink_crc_eDP1", "%s\n", crc),
234 "Sink CRC is unreliable on this machine. Try manual debug with --interactive-debug=no-crc\n");
235 close(dir);
Rodrigo Vivi1ab04452014-08-29 17:58:31 -0400236
237 igt_debug("%s\n", crc);
238 igt_debug_wait_for_keypress("crc");
239
240 /* The important value was already taken.
241 * Now give a time for human eyes
242 */
243 usleep(300000);
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400244
245 /* Black screen is always invalid */
246 igt_assert(strcmp(crc, CRC_BLACK) != 0);
247}
248
249static bool is_green(char *crc)
250{
251 char color_mask[5] = "FFFF\0";
252 char rs[5], gs[5], bs[5];
253 unsigned int rh, gh, bh, mask;
254 int ret;
255
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500256 if (igt_interactive_debug)
257 return false;
258
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400259 sscanf(color_mask, "%4x", &mask);
260
261 memcpy(rs, &crc[0], 4);
262 rs[4] = '\0';
263 ret = sscanf(rs, "%4x", &rh);
264 igt_require(ret > 0);
265
266 memcpy(gs, &crc[4], 4);
267 gs[4] = '\0';
268 ret = sscanf(gs, "%4x", &gh);
269 igt_require(ret > 0);
270
271 memcpy(bs, &crc[8], 4);
272 bs[4] = '\0';
273 ret = sscanf(bs, "%4x", &bh);
274 igt_require(ret > 0);
275
276 return ((rh & mask) == 0 &&
277 (gh & mask) != 0 &&
278 (bh & mask) == 0);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300279}
280
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500281static void assert_or_manual(bool condition, const char *expected)
282{
Rodrigo Viviae9c6852014-12-09 20:44:11 -0500283 igt_debug_manual_check("no-crc", expected);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500284 igt_assert(igt_interactive_debug || condition);
285}
286
Radhakrishna Sripada6dceb6f2017-09-15 17:00:08 -0700287static bool drrs_disabled(data_t *data)
288{
289 char buf[512];
290
291 igt_debugfs_read(data->drm_fd, "i915_drrs_status", buf);
292
293 return strstr(buf, "DRRS Support: No\n");
294}
295
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400296static void run_test(data_t *data)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300297{
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400298 uint32_t handle = data->fb_white.gem_handle;
299 igt_plane_t *test_plane;
300 void *ptr;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300301 char ref_crc[12];
302 char crc[12];
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500303 const char *expected = "";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300304
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400305 /* Confirm that screen became Green */
306 get_sink_crc(data, ref_crc);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500307 assert_or_manual(is_green(ref_crc), "screen GREEN");
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400308
309 /* Confirm screen stays Green after PSR got active */
Rodrigo Vivifd9ef1b2015-03-13 12:28:07 -0400310 igt_assert(wait_psr_entry(data));
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400311 get_sink_crc(data, ref_crc);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500312 assert_or_manual(is_green(ref_crc), "screen GREEN");
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400313
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400314 /* Setting a secondary fb/plane */
315 switch (data->test_plane) {
Robert Foss934062c2017-01-10 20:16:23 -0500316 case DRM_PLANE_TYPE_PRIMARY: default: test_plane = data->primary; break;
317 case DRM_PLANE_TYPE_OVERLAY: test_plane = data->sprite; break;
318 case DRM_PLANE_TYPE_CURSOR: test_plane = data->cursor; break;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300319 }
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400320 igt_plane_set_fb(test_plane, &data->fb_white);
321 igt_display_commit(&data->display);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300322
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400323 /* Confirm it is not Green anymore */
Rodrigo Vivifd9ef1b2015-03-13 12:28:07 -0400324 igt_assert(wait_psr_entry(data));
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300325 get_sink_crc(data, ref_crc);
Robert Foss934062c2017-01-10 20:16:23 -0500326 if (data->test_plane == DRM_PLANE_TYPE_PRIMARY)
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500327 assert_or_manual(!is_green(ref_crc), "screen WHITE");
328 else
329 assert_or_manual(!is_green(ref_crc), "GREEN background with WHITE box");
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300330
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400331 switch (data->op) {
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400332 case PAGE_FLIP:
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400333 /* Only in use when testing primary plane */
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300334 igt_assert(drmModePageFlip(data->drm_fd, data->crtc_id,
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400335 data->fb_green.fb_id, 0, NULL) == 0);
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400336 get_sink_crc(data, crc);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500337 assert_or_manual(is_green(crc), "screen GREEN");
338 expected = "still GREEN";
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400339 break;
340 case MMAP_GTT:
Ville Syrjäläf52e7ec2015-10-09 19:11:39 +0300341 ptr = gem_mmap__gtt(data->drm_fd, handle, data->mod_size,
Rodrigo Vivi00992f72014-12-05 20:01:41 -0500342 PROT_WRITE);
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400343 gem_set_domain(data->drm_fd, handle,
344 I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
Rodrigo Vivi00992f72014-12-05 20:01:41 -0500345 memset(ptr, 0xcc, data->mod_size);
346 munmap(ptr, data->mod_size);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500347 expected = "BLACK or TRANSPARENT mark on top of plane in test";
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400348 break;
349 case MMAP_GTT_WAITING:
Ville Syrjäläf52e7ec2015-10-09 19:11:39 +0300350 ptr = gem_mmap__gtt(data->drm_fd, handle, data->mod_size,
Rodrigo Vivi00992f72014-12-05 20:01:41 -0500351 PROT_WRITE);
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400352 gem_set_domain(data->drm_fd, handle,
353 I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
354
355 /* Printing white on white so the screen shouldn't change */
Rodrigo Vivi00992f72014-12-05 20:01:41 -0500356 memset(ptr, 0xff, data->mod_size);
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400357 get_sink_crc(data, crc);
Robert Foss934062c2017-01-10 20:16:23 -0500358 if (data->test_plane == DRM_PLANE_TYPE_PRIMARY)
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500359 assert_or_manual(strcmp(ref_crc, crc) == 0, "screen WHITE");
360 else
361 assert_or_manual(strcmp(ref_crc, crc) == 0,
362 "GREEN background with WHITE box");
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400363
Daniel Vetter8b556f72014-10-23 17:54:44 +0200364 igt_info("Waiting 10s...\n");
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400365 sleep(10);
366
367 /* Now lets print black to change the screen */
Rodrigo Vivi00992f72014-12-05 20:01:41 -0500368 memset(ptr, 0, data->mod_size);
369 munmap(ptr, data->mod_size);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500370 expected = "BLACK or TRANSPARENT mark on top of plane in test";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300371 break;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400372 case MMAP_CPU:
Ville Syrjäläf52e7ec2015-10-09 19:11:39 +0300373 ptr = gem_mmap__cpu(data->drm_fd, handle, 0, data->mod_size,
374 PROT_WRITE);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300375 gem_set_domain(data->drm_fd, handle,
376 I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
Rodrigo Vivi00992f72014-12-05 20:01:41 -0500377 memset(ptr, 0, data->mod_size);
378 munmap(ptr, data->mod_size);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300379 gem_sw_finish(data->drm_fd, handle);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500380 expected = "BLACK or TRANSPARENT mark on top of plane in test";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300381 break;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400382 case BLT:
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400383 fill_blt(data, handle, 0);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500384 expected = "BLACK or TRANSPARENT mark on top of plane in test";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300385 break;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400386 case RENDER:
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400387 fill_render(data, handle, 0);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500388 expected = "BLACK or TRANSPARENT mark on top of plane in test";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300389 break;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400390 case PLANE_MOVE:
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400391 /* Only in use when testing Sprite and Cursor */
Rodrigo Vivib7b2ecb2014-12-05 20:03:31 -0500392 igt_plane_set_position(test_plane, 500, 500);
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400393 igt_display_commit(&data->display);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500394 expected = "White box moved to 500x500";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300395 break;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400396 case PLANE_ONOFF:
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400397 /* Only in use when testing Sprite and Cursor */
398 igt_plane_set_fb(test_plane, NULL);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300399 igt_display_commit(&data->display);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500400 expected = "screen GREEN";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300401 break;
402 }
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300403 get_sink_crc(data, crc);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500404 assert_or_manual(strcmp(ref_crc, crc) != 0, expected);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300405}
406
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400407static void test_cleanup(data_t *data) {
408 igt_plane_set_fb(data->primary, NULL);
Robert Foss934062c2017-01-10 20:16:23 -0500409 if (data->test_plane == DRM_PLANE_TYPE_OVERLAY)
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400410 igt_plane_set_fb(data->sprite, NULL);
Robert Foss934062c2017-01-10 20:16:23 -0500411 if (data->test_plane == DRM_PLANE_TYPE_CURSOR)
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400412 igt_plane_set_fb(data->cursor, NULL);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300413
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400414 igt_display_commit(&data->display);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300415
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400416 igt_remove_fb(data->drm_fd, &data->fb_green);
417 igt_remove_fb(data->drm_fd, &data->fb_white);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300418}
419
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400420static void setup_test_plane(data_t *data)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300421{
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400422 uint32_t white_h, white_v;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300423
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400424 igt_create_color_fb(data->drm_fd,
425 data->mode->hdisplay, data->mode->vdisplay,
426 DRM_FORMAT_XRGB8888,
427 LOCAL_I915_FORMAT_MOD_X_TILED,
428 0.0, 1.0, 0.0,
429 &data->fb_green);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300430
Robert Foss934062c2017-01-10 20:16:23 -0500431 data->primary = igt_output_get_plane_type(data->output, DRM_PLANE_TYPE_PRIMARY);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400432 igt_plane_set_fb(data->primary, NULL);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300433
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400434 white_h = data->mode->hdisplay;
435 white_v = data->mode->vdisplay;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300436
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400437 /* Ignoring pitch and bpp to avoid changing full screen */
438 data->mod_size = white_h * white_v;
Rodrigo Vivi36ecc312015-04-14 18:04:01 -0700439 data->mod_stride = white_h * 4;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300440
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400441 switch (data->test_plane) {
Robert Foss934062c2017-01-10 20:16:23 -0500442 case DRM_PLANE_TYPE_OVERLAY:
443 data->sprite = igt_output_get_plane_type(data->output,
444 DRM_PLANE_TYPE_OVERLAY);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400445 igt_plane_set_fb(data->sprite, NULL);
446 /* To make it different for human eyes let's make
447 * sprite visible in only one quarter of the primary
448 */
449 white_h = white_h/2;
450 white_v = white_v/2;
Robert Foss934062c2017-01-10 20:16:23 -0500451 case DRM_PLANE_TYPE_PRIMARY:
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300452 igt_create_color_fb(data->drm_fd,
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400453 white_h, white_v,
Tvrtko Ursuline36091d2015-03-03 14:11:01 +0000454 DRM_FORMAT_XRGB8888,
455 LOCAL_I915_FORMAT_MOD_X_TILED,
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400456 1.0, 1.0, 1.0,
457 &data->fb_white);
458 break;
Robert Foss934062c2017-01-10 20:16:23 -0500459 case DRM_PLANE_TYPE_CURSOR:
460 data->cursor = igt_output_get_plane_type(data->output,
461 DRM_PLANE_TYPE_CURSOR);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400462 igt_plane_set_fb(data->cursor, NULL);
463 create_cursor_fb(data);
464 igt_plane_set_position(data->cursor, 0, 0);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300465
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400466 /* Cursor is 64 x 64, ignoring pitch and bbp again */
467 data->mod_size = 64 * 64;
468 break;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300469 }
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400470
471 igt_display_commit(&data->display);
472
473 igt_plane_set_fb(data->primary, &data->fb_green);
474 igt_display_commit(&data->display);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300475}
476
Rodrigo Vivic3524752015-03-13 12:11:54 -0400477static void dpms_off_on(data_t data)
478{
479 kmstest_set_connector_dpms(data.drm_fd, data.output->config.connector,
480 DRM_MODE_DPMS_OFF);
481 sleep(1);
482 kmstest_set_connector_dpms(data.drm_fd, data.output->config.connector,
483 DRM_MODE_DPMS_ON);
484}
485
Damien Lespiaufd6846c2015-05-14 14:19:01 +0100486static int opt_handler(int opt, int opt_index, void *data)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300487{
Daniel Vetter3205a912014-09-23 15:15:51 +0200488 switch (opt) {
489 case 'n':
490 running_with_psr_disabled = true;
491 break;
492 default:
493 igt_assert(0);
494 }
495
496 return 0;
497}
498
499int main(int argc, char *argv[])
500{
501 const char *help_str =
502 " --no-psr\tRun test without PSR to check the CRC test logic.";
503 static struct option long_options[] = {
504 {"no-psr", 0, 0, 'n'},
505 { 0, 0, 0, 0 }
506 };
Rodrigo Vivi1ab04452014-08-29 17:58:31 -0400507 data_t data = {};
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400508 enum operations op;
Rodrigo Vivi1ab04452014-08-29 17:58:31 -0400509
Thomas Wood8fb19782015-02-18 16:19:59 +0000510 igt_subtest_init_parse_opts(&argc, argv, "", long_options,
Damien Lespiaufd6846c2015-05-14 14:19:01 +0100511 help_str, opt_handler, NULL);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300512 igt_skip_on_simulation();
513
514 igt_fixture {
Micah Fedkec81d2932015-07-22 21:54:02 +0000515 data.drm_fd = drm_open_driver_master(DRIVER_INTEL);
Daniel Vetter33f08842014-08-12 11:23:09 +0200516 kmstest_set_vt_graphics_mode();
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300517 data.devid = intel_get_drm_devid(data.drm_fd);
518
Rodrigo Vivi63980ba2015-11-03 09:37:56 -0800519 igt_set_module_param_int("enable_psr", running_with_psr_disabled ?
520 0 : 1);
Paulo Zanoni75b286e2015-06-02 12:03:45 -0300521
522 igt_skip_on(!psr_possible(&data));
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300523
524 data.bufmgr = drm_intel_bufmgr_gem_init(data.drm_fd, 4096);
525 igt_assert(data.bufmgr);
526 drm_intel_bufmgr_gem_enable_reuse(data.bufmgr);
527
528 display_init(&data);
529 }
530
Rodrigo Vivi4aa1b992015-12-08 00:11:21 -0800531 igt_subtest("psr_basic") {
532 setup_test_plane(&data);
533 igt_assert(wait_psr_entry(&data));
534 }
535
Radhakrishna Sripada6dceb6f2017-09-15 17:00:08 -0700536 igt_subtest("psr_drrs") {
537 setup_test_plane(&data);
538 igt_assert(drrs_disabled(&data));
539 }
540
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400541 for (op = PAGE_FLIP; op <= RENDER; op++) {
542 igt_subtest_f("primary_%s", op_str(op)) {
Robert Foss934062c2017-01-10 20:16:23 -0500543 data.test_plane = DRM_PLANE_TYPE_PRIMARY;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400544 data.op = op;
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400545 setup_test_plane(&data);
546 igt_assert(wait_psr_entry(&data));
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400547 run_test(&data);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400548 test_cleanup(&data);
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400549 }
550 }
551
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400552 for (op = MMAP_GTT; op <= PLANE_ONOFF; op++) {
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400553 igt_subtest_f("sprite_%s", op_str(op)) {
Robert Foss934062c2017-01-10 20:16:23 -0500554 data.test_plane = DRM_PLANE_TYPE_OVERLAY;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400555 data.op = op;
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400556 setup_test_plane(&data);
557 igt_assert(wait_psr_entry(&data));
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400558 run_test(&data);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400559 test_cleanup(&data);
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400560 }
561 }
562
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400563 for (op = MMAP_GTT; op <= PLANE_ONOFF; op++) {
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400564 igt_subtest_f("cursor_%s", op_str(op)) {
Robert Foss934062c2017-01-10 20:16:23 -0500565 data.test_plane = DRM_PLANE_TYPE_CURSOR;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400566 data.op = op;
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400567 setup_test_plane(&data);
568 igt_assert(wait_psr_entry(&data));
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300569 run_test(&data);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400570 test_cleanup(&data);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300571 }
572 }
573
Rodrigo Vivic3524752015-03-13 12:11:54 -0400574 igt_subtest_f("dpms_off_psr_active") {
Robert Foss934062c2017-01-10 20:16:23 -0500575 data.test_plane = DRM_PLANE_TYPE_PRIMARY;
Rodrigo Vivic3524752015-03-13 12:11:54 -0400576 data.op = RENDER;
577 setup_test_plane(&data);
578 igt_assert(wait_psr_entry(&data));
579
580 dpms_off_on(data);
581
582 run_test(&data);
583 test_cleanup(&data);
584 }
585
586 igt_subtest_f("dpms_off_psr_exit") {
Robert Foss934062c2017-01-10 20:16:23 -0500587 data.test_plane = DRM_PLANE_TYPE_OVERLAY;
Rodrigo Vivic3524752015-03-13 12:11:54 -0400588 data.op = PLANE_ONOFF;
589 setup_test_plane(&data);
590
591 dpms_off_on(data);
592
593 igt_assert(wait_psr_entry(&data));
594 run_test(&data);
595 test_cleanup(&data);
596 }
597
Rodrigo Vivi7bd31d02015-11-03 10:02:14 -0800598 igt_subtest_f("suspend_psr_active") {
Robert Foss934062c2017-01-10 20:16:23 -0500599 data.test_plane = DRM_PLANE_TYPE_PRIMARY;
Rodrigo Vivi7bd31d02015-11-03 10:02:14 -0800600 data.op = PAGE_FLIP;
601 setup_test_plane(&data);
602 igt_assert(wait_psr_entry(&data));
603
Imre Deak022e6f82016-09-30 17:28:53 +0300604 igt_system_suspend_autoresume(SUSPEND_STATE_MEM,
605 SUSPEND_TEST_NONE);
Rodrigo Vivi7bd31d02015-11-03 10:02:14 -0800606
607 run_test(&data);
608 test_cleanup(&data);
609 }
610
611 igt_subtest_f("suspend_psr_exit") {
Robert Foss934062c2017-01-10 20:16:23 -0500612 data.test_plane = DRM_PLANE_TYPE_CURSOR;
Rodrigo Vivi7bd31d02015-11-03 10:02:14 -0800613 data.op = PLANE_ONOFF;
614 setup_test_plane(&data);
615
Imre Deak022e6f82016-09-30 17:28:53 +0300616 igt_system_suspend_autoresume(SUSPEND_STATE_MEM,
617 SUSPEND_TEST_NONE);
Rodrigo Vivi7bd31d02015-11-03 10:02:14 -0800618
619 igt_assert(wait_psr_entry(&data));
620 run_test(&data);
621 test_cleanup(&data);
622 }
623
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300624 igt_fixture {
625 drm_intel_bufmgr_destroy(data.bufmgr);
626 display_fini(&data);
627 }
Daniel Vetter3205a912014-09-23 15:15:51 +0200628
629 igt_exit();
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300630}