blob: 8cd11a7f4010e8d186c6d1933a68bd5279eb8ebe [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"
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030026#include <errno.h>
27#include <stdbool.h>
28#include <stdio.h>
29#include <string.h>
30
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030031#include "intel_bufmgr.h"
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030032
Rodrigo Vivi99efdc02014-09-09 17:58:45 -040033bool running_with_psr_disabled;
34
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -040035#define CRC_BLACK "000000000000"
36
Rodrigo Vivi99efdc02014-09-09 17:58:45 -040037enum planes {
38 PRIMARY,
39 SPRITE,
40 CURSOR,
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030041};
42
Rodrigo Vivi99efdc02014-09-09 17:58:45 -040043enum operations {
44 PAGE_FLIP,
45 MMAP_GTT,
46 MMAP_GTT_WAITING,
47 MMAP_CPU,
48 BLT,
49 RENDER,
50 PLANE_MOVE,
51 PLANE_ONOFF,
52};
53
54static const char *op_str(enum operations op)
55{
56 static const char * const name[] = {
57 [PAGE_FLIP] = "page_flip",
58 [MMAP_GTT] = "mmap_gtt",
59 [MMAP_GTT_WAITING] = "mmap_gtt_waiting",
60 [MMAP_CPU] = "mmap_cpu",
61 [BLT] = "blt",
62 [RENDER] = "render",
63 [PLANE_MOVE] = "plane_move",
64 [PLANE_ONOFF] = "plane_onoff",
65 };
66
67 return name[op];
68}
Rodrigo Vivi1ab04452014-08-29 17:58:31 -040069
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030070typedef struct {
71 int drm_fd;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -040072 enum planes test_plane;
73 enum operations op;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030074 uint32_t devid;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030075 uint32_t crtc_id;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030076 igt_display_t display;
Rodrigo Vivid4e6a512014-08-29 19:12:54 -040077 drm_intel_bufmgr *bufmgr;
78 struct igt_fb fb_green, fb_white;
79 igt_plane_t *primary, *sprite, *cursor;
Rodrigo Vivi00992f72014-12-05 20:01:41 -050080 int mod_size;
Rodrigo Vivi36ecc312015-04-14 18:04:01 -070081 int mod_stride;
Rodrigo Vivi782d5e72015-03-13 12:10:20 -040082 drmModeModeInfo *mode;
83 igt_output_t *output;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030084} data_t;
85
Rodrigo Vivid4e6a512014-08-29 19:12:54 -040086static void create_cursor_fb(data_t *data)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030087{
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030088 cairo_t *cr;
Rodrigo Vivid4e6a512014-08-29 19:12:54 -040089 uint32_t fb_id;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030090
Rodrigo Vivid4e6a512014-08-29 19:12:54 -040091 fb_id = igt_create_fb(data->drm_fd, 64, 64,
Tvrtko Ursuline36091d2015-03-03 14:11:01 +000092 DRM_FORMAT_ARGB8888, LOCAL_DRM_FORMAT_MOD_NONE,
Rodrigo Vivid4e6a512014-08-29 19:12:54 -040093 &data->fb_white);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030094 igt_assert(fb_id);
95
Rodrigo Vivid4e6a512014-08-29 19:12:54 -040096 cr = igt_get_cairo_ctx(data->drm_fd, &data->fb_white);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030097 igt_paint_color_alpha(cr, 0, 0, 64, 64, 1.0, 1.0, 1.0, 1.0);
98 igt_assert(cairo_status(cr) == 0);
99}
100
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400101
102static void setup_output(data_t *data)
103{
104 igt_display_t *display = &data->display;
105 igt_output_t *output;
106
107 for_each_connected_output(display, output) {
108 drmModeConnectorPtr c = output->config.connector;
109
110 if (c->connector_type != DRM_MODE_CONNECTOR_eDP ||
111 c->connection != DRM_MODE_CONNECTED)
112 continue;
113
114 igt_output_set_pipe(output, PIPE_ANY);
115 data->crtc_id = output->config.crtc->crtc_id;
116 data->output = output;
117 data->mode = igt_output_get_mode(output);
118
119 return;
120 }
121}
122
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300123static void display_init(data_t *data)
124{
125 igt_display_init(&data->display, data->drm_fd);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400126 setup_output(data);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300127}
128
129static void display_fini(data_t *data)
130{
131 igt_display_fini(&data->display);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300132}
133
134static void fill_blt(data_t *data, uint32_t handle, unsigned char color)
135{
136 drm_intel_bo *dst = gem_handle_to_libdrm_bo(data->bufmgr,
137 data->drm_fd,
138 "", handle);
139 struct intel_batchbuffer *batch;
140
141 batch = intel_batchbuffer_alloc(data->bufmgr, data->devid);
142 igt_assert(batch);
143
Chris Wilson10552b52014-08-30 11:44:51 +0100144 COLOR_BLIT_COPY_BATCH_START(0);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300145 OUT_BATCH((1 << 24) | (0xf0 << 16) | 0);
Rodrigo Vivi1447d832014-09-03 18:18:15 -0400146 OUT_BATCH(0);
Rodrigo Vivi3cb21242014-12-05 19:43:34 -0500147 OUT_BATCH(0xfff << 16 | 0xfff);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300148 OUT_RELOC(dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
149 OUT_BATCH(color);
150 ADVANCE_BATCH();
151
152 intel_batchbuffer_flush(batch);
153 intel_batchbuffer_free(batch);
154
155 gem_bo_busy(data->drm_fd, handle);
156}
157
Rodrigo Vivi36ecc312015-04-14 18:04:01 -0700158static void scratch_buf_init(struct igt_buf *buf, drm_intel_bo *bo,
159 int size, int stride)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300160{
161 buf->bo = bo;
Rodrigo Vivi36ecc312015-04-14 18:04:01 -0700162 buf->stride = stride;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300163 buf->tiling = I915_TILING_X;
Rodrigo Vivi36ecc312015-04-14 18:04:01 -0700164 buf->size = size;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300165}
166
Rodrigo Vivifb004a62014-09-03 17:53:35 -0400167static void fill_render(data_t *data, uint32_t handle, unsigned char color)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300168{
169 drm_intel_bo *src, *dst;
170 struct intel_batchbuffer *batch;
171 struct igt_buf src_buf, dst_buf;
172 const uint8_t buf[4] = { color, color, color, color };
173 igt_render_copyfunc_t rendercopy = igt_get_render_copyfunc(data->devid);
174
175 igt_skip_on(!rendercopy);
176
177 dst = gem_handle_to_libdrm_bo(data->bufmgr, data->drm_fd, "", handle);
178 igt_assert(dst);
179
Rodrigo Vivi36ecc312015-04-14 18:04:01 -0700180 src = drm_intel_bo_alloc(data->bufmgr, "", data->mod_size, 4096);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300181 igt_assert(src);
182
183 gem_write(data->drm_fd, src->handle, 0, buf, 4);
184
Rodrigo Vivi36ecc312015-04-14 18:04:01 -0700185 scratch_buf_init(&src_buf, src, data->mod_size, data->mod_stride);
186 scratch_buf_init(&dst_buf, dst, data->mod_size, data->mod_stride);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300187
188 batch = intel_batchbuffer_alloc(data->bufmgr, data->devid);
189 igt_assert(batch);
190
Rodrigo Vivifb004a62014-09-03 17:53:35 -0400191 rendercopy(batch, NULL,
Rodrigo Vivif20690d2014-12-05 19:45:37 -0500192 &src_buf, 0, 0, 0xff, 0xff,
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300193 &dst_buf, 0, 0);
194
195 intel_batchbuffer_free(batch);
196
197 gem_bo_busy(data->drm_fd, handle);
198}
199
Paulo Zanoni75b286e2015-06-02 12:03:45 -0300200static bool psr_possible(data_t *data)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300201{
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300202 FILE *file;
Chris Wilsonf59935c2015-03-11 08:40:23 +0000203 char buf[4096];
204 int ret;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300205
Rodrigo Vivi1ab04452014-08-29 17:58:31 -0400206 if (running_with_psr_disabled)
207 return true;
208
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300209 file = igt_debugfs_fopen("i915_edp_psr_status", "r");
210 igt_require(file);
211
Chris Wilsonf59935c2015-03-11 08:40:23 +0000212 /* First dump the entire file into the debug log for later analysis
213 * if required.
214 */
215 ret = fread(buf, 1, 4095, file);
216 igt_require(ret > 0);
217 buf[ret] = '\0';
218 igt_debug("i915_edp_psr_status:\n%s", buf);
219 fseek(file, 0, SEEK_SET);
220
221 /* Now check that we have all the preconditions required for PSR */
222 ret = fscanf(file, "Sink_Support: %s\n", buf);
223 igt_require_f(ret == 1 && strcmp(buf, "yes") == 0,
224 "Sink_Support: %s\n", buf);
225
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300226 fclose(file);
Chris Wilsonf59935c2015-03-11 08:40:23 +0000227 return true;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300228}
229
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700230static bool psr_active(data_t *data)
231{
232 int ret;
233 FILE *file;
234 char str[4];
235
Rodrigo Vivi1ab04452014-08-29 17:58:31 -0400236 if (running_with_psr_disabled)
237 return true;
238
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700239 file = igt_debugfs_fopen("i915_edp_psr_status", "r");
240 igt_require(file);
241
242 ret = fscanf(file, "Sink_Support: %s\n", str);
Matt Roper07be8fe2015-03-05 15:01:00 -0800243 igt_assert_neq(ret, 0);
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700244 ret = fscanf(file, "Source_OK: %s\n", str);
Matt Roper07be8fe2015-03-05 15:01:00 -0800245 igt_assert_neq(ret, 0);
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700246 ret = fscanf(file, "Enabled: %s\n", str);
Matt Roper07be8fe2015-03-05 15:01:00 -0800247 igt_assert_neq(ret, 0);
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700248 ret = fscanf(file, "Active: %s\n", str);
Matt Roper07be8fe2015-03-05 15:01:00 -0800249 igt_assert_neq(ret, 0);
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700250 ret = fscanf(file, "Busy frontbuffer bits: %s\n", str);
Matt Roper07be8fe2015-03-05 15:01:00 -0800251 igt_assert_neq(ret, 0);
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700252 ret = fscanf(file, "Re-enable work scheduled: %s\n", str);
Matt Roper07be8fe2015-03-05 15:01:00 -0800253 igt_assert_neq(ret, 0);
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700254 ret = fscanf(file, "HW Enabled & Active bit: %s\n", str);
Matt Roper07be8fe2015-03-05 15:01:00 -0800255 igt_assert_neq(ret, 0);
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700256
257 fclose(file);
258 return strcmp(str, "yes") == 0;
259}
260
Rodrigo Vivifd9ef1b2015-03-13 12:28:07 -0400261static bool wait_psr_entry(data_t *data)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300262{
Rodrigo Vivi4a004d92015-12-07 01:26:17 -0800263 int timeout = 5;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300264 while (timeout--) {
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700265 if (psr_active(data))
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300266 return true;
267 sleep(1);
268 }
269 return false;
270}
271
272static void get_sink_crc(data_t *data, char *crc) {
273 int ret;
274 FILE *file;
275
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500276 if (igt_interactive_debug)
277 return;
278
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300279 file = igt_debugfs_fopen("i915_sink_crc_eDP1", "r");
280 igt_require(file);
281
282 ret = fscanf(file, "%s\n", crc);
Rodrigo Viviae9c6852014-12-09 20:44:11 -0500283 igt_require_f(ret > 0, "Sink CRC is unreliable on this machine. Try manual debug with --interactive-debug=no-crc\n");
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300284
285 fclose(file);
Rodrigo Vivi1ab04452014-08-29 17:58:31 -0400286
287 igt_debug("%s\n", crc);
288 igt_debug_wait_for_keypress("crc");
289
290 /* The important value was already taken.
291 * Now give a time for human eyes
292 */
293 usleep(300000);
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400294
295 /* Black screen is always invalid */
296 igt_assert(strcmp(crc, CRC_BLACK) != 0);
297}
298
299static bool is_green(char *crc)
300{
301 char color_mask[5] = "FFFF\0";
302 char rs[5], gs[5], bs[5];
303 unsigned int rh, gh, bh, mask;
304 int ret;
305
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500306 if (igt_interactive_debug)
307 return false;
308
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400309 sscanf(color_mask, "%4x", &mask);
310
311 memcpy(rs, &crc[0], 4);
312 rs[4] = '\0';
313 ret = sscanf(rs, "%4x", &rh);
314 igt_require(ret > 0);
315
316 memcpy(gs, &crc[4], 4);
317 gs[4] = '\0';
318 ret = sscanf(gs, "%4x", &gh);
319 igt_require(ret > 0);
320
321 memcpy(bs, &crc[8], 4);
322 bs[4] = '\0';
323 ret = sscanf(bs, "%4x", &bh);
324 igt_require(ret > 0);
325
326 return ((rh & mask) == 0 &&
327 (gh & mask) != 0 &&
328 (bh & mask) == 0);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300329}
330
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500331static void assert_or_manual(bool condition, const char *expected)
332{
Rodrigo Viviae9c6852014-12-09 20:44:11 -0500333 igt_debug_manual_check("no-crc", expected);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500334 igt_assert(igt_interactive_debug || condition);
335}
336
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400337static void run_test(data_t *data)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300338{
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400339 uint32_t handle = data->fb_white.gem_handle;
340 igt_plane_t *test_plane;
341 void *ptr;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300342 char ref_crc[12];
343 char crc[12];
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500344 const char *expected = "";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300345
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400346 /* Confirm that screen became Green */
347 get_sink_crc(data, ref_crc);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500348 assert_or_manual(is_green(ref_crc), "screen GREEN");
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400349
350 /* Confirm screen stays Green after PSR got active */
Rodrigo Vivifd9ef1b2015-03-13 12:28:07 -0400351 igt_assert(wait_psr_entry(data));
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400352 get_sink_crc(data, ref_crc);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500353 assert_or_manual(is_green(ref_crc), "screen GREEN");
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400354
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400355 /* Setting a secondary fb/plane */
356 switch (data->test_plane) {
357 case PRIMARY: default: test_plane = data->primary; break;
358 case SPRITE: test_plane = data->sprite; break;
359 case CURSOR: test_plane = data->cursor; break;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300360 }
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400361 igt_plane_set_fb(test_plane, &data->fb_white);
362 igt_display_commit(&data->display);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300363
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400364 /* Confirm it is not Green anymore */
Rodrigo Vivifd9ef1b2015-03-13 12:28:07 -0400365 igt_assert(wait_psr_entry(data));
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300366 get_sink_crc(data, ref_crc);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500367 if (data->test_plane == PRIMARY)
368 assert_or_manual(!is_green(ref_crc), "screen WHITE");
369 else
370 assert_or_manual(!is_green(ref_crc), "GREEN background with WHITE box");
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300371
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400372 switch (data->op) {
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400373 case PAGE_FLIP:
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400374 /* Only in use when testing primary plane */
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300375 igt_assert(drmModePageFlip(data->drm_fd, data->crtc_id,
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400376 data->fb_green.fb_id, 0, NULL) == 0);
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400377 get_sink_crc(data, crc);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500378 assert_or_manual(is_green(crc), "screen GREEN");
379 expected = "still GREEN";
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400380 break;
381 case MMAP_GTT:
Ville Syrjäläf52e7ec2015-10-09 19:11:39 +0300382 ptr = gem_mmap__gtt(data->drm_fd, handle, data->mod_size,
Rodrigo Vivi00992f72014-12-05 20:01:41 -0500383 PROT_WRITE);
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400384 gem_set_domain(data->drm_fd, handle,
385 I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
Rodrigo Vivi00992f72014-12-05 20:01:41 -0500386 memset(ptr, 0xcc, data->mod_size);
387 munmap(ptr, data->mod_size);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500388 expected = "BLACK or TRANSPARENT mark on top of plane in test";
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400389 break;
390 case MMAP_GTT_WAITING:
Ville Syrjäläf52e7ec2015-10-09 19:11:39 +0300391 ptr = gem_mmap__gtt(data->drm_fd, handle, data->mod_size,
Rodrigo Vivi00992f72014-12-05 20:01:41 -0500392 PROT_WRITE);
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400393 gem_set_domain(data->drm_fd, handle,
394 I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
395
396 /* Printing white on white so the screen shouldn't change */
Rodrigo Vivi00992f72014-12-05 20:01:41 -0500397 memset(ptr, 0xff, data->mod_size);
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400398 get_sink_crc(data, crc);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500399 if (data->test_plane == PRIMARY)
400 assert_or_manual(strcmp(ref_crc, crc) == 0, "screen WHITE");
401 else
402 assert_or_manual(strcmp(ref_crc, crc) == 0,
403 "GREEN background with WHITE box");
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400404
Daniel Vetter8b556f72014-10-23 17:54:44 +0200405 igt_info("Waiting 10s...\n");
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400406 sleep(10);
407
408 /* Now lets print black to change the screen */
Rodrigo Vivi00992f72014-12-05 20:01:41 -0500409 memset(ptr, 0, data->mod_size);
410 munmap(ptr, data->mod_size);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500411 expected = "BLACK or TRANSPARENT mark on top of plane in test";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300412 break;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400413 case MMAP_CPU:
Ville Syrjäläf52e7ec2015-10-09 19:11:39 +0300414 ptr = gem_mmap__cpu(data->drm_fd, handle, 0, data->mod_size,
415 PROT_WRITE);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300416 gem_set_domain(data->drm_fd, handle,
417 I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
Rodrigo Vivi00992f72014-12-05 20:01:41 -0500418 memset(ptr, 0, data->mod_size);
419 munmap(ptr, data->mod_size);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300420 gem_sw_finish(data->drm_fd, handle);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500421 expected = "BLACK or TRANSPARENT mark on top of plane in test";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300422 break;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400423 case BLT:
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400424 fill_blt(data, handle, 0);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500425 expected = "BLACK or TRANSPARENT mark on top of plane in test";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300426 break;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400427 case RENDER:
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400428 fill_render(data, handle, 0);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500429 expected = "BLACK or TRANSPARENT mark on top of plane in test";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300430 break;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400431 case PLANE_MOVE:
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400432 /* Only in use when testing Sprite and Cursor */
Rodrigo Vivib7b2ecb2014-12-05 20:03:31 -0500433 igt_plane_set_position(test_plane, 500, 500);
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400434 igt_display_commit(&data->display);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500435 expected = "White box moved to 500x500";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300436 break;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400437 case PLANE_ONOFF:
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400438 /* Only in use when testing Sprite and Cursor */
439 igt_plane_set_fb(test_plane, NULL);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300440 igt_display_commit(&data->display);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500441 expected = "screen GREEN";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300442 break;
443 }
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300444 get_sink_crc(data, crc);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500445 assert_or_manual(strcmp(ref_crc, crc) != 0, expected);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300446}
447
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400448static void test_cleanup(data_t *data) {
449 igt_plane_set_fb(data->primary, NULL);
450 if (data->test_plane == SPRITE)
451 igt_plane_set_fb(data->sprite, NULL);
452 if (data->test_plane == CURSOR)
453 igt_plane_set_fb(data->cursor, NULL);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300454
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400455 igt_display_commit(&data->display);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300456
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400457 igt_remove_fb(data->drm_fd, &data->fb_green);
458 igt_remove_fb(data->drm_fd, &data->fb_white);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300459}
460
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400461static void setup_test_plane(data_t *data)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300462{
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400463 uint32_t white_h, white_v;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300464
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400465 igt_create_color_fb(data->drm_fd,
466 data->mode->hdisplay, data->mode->vdisplay,
467 DRM_FORMAT_XRGB8888,
468 LOCAL_I915_FORMAT_MOD_X_TILED,
469 0.0, 1.0, 0.0,
470 &data->fb_green);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300471
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400472 data->primary = igt_output_get_plane(data->output, IGT_PLANE_PRIMARY);
473 igt_plane_set_fb(data->primary, NULL);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300474
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400475 white_h = data->mode->hdisplay;
476 white_v = data->mode->vdisplay;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300477
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400478 /* Ignoring pitch and bpp to avoid changing full screen */
479 data->mod_size = white_h * white_v;
Rodrigo Vivi36ecc312015-04-14 18:04:01 -0700480 data->mod_stride = white_h * 4;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300481
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400482 switch (data->test_plane) {
483 case SPRITE:
484 data->sprite = igt_output_get_plane(data->output,
485 IGT_PLANE_2);
486 igt_plane_set_fb(data->sprite, NULL);
487 /* To make it different for human eyes let's make
488 * sprite visible in only one quarter of the primary
489 */
490 white_h = white_h/2;
491 white_v = white_v/2;
492 case PRIMARY:
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300493 igt_create_color_fb(data->drm_fd,
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400494 white_h, white_v,
Tvrtko Ursuline36091d2015-03-03 14:11:01 +0000495 DRM_FORMAT_XRGB8888,
496 LOCAL_I915_FORMAT_MOD_X_TILED,
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400497 1.0, 1.0, 1.0,
498 &data->fb_white);
499 break;
500 case CURSOR:
501 data->cursor = igt_output_get_plane(data->output,
502 IGT_PLANE_CURSOR);
503 igt_plane_set_fb(data->cursor, NULL);
504 create_cursor_fb(data);
505 igt_plane_set_position(data->cursor, 0, 0);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300506
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400507 /* Cursor is 64 x 64, ignoring pitch and bbp again */
508 data->mod_size = 64 * 64;
509 break;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300510 }
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400511
512 igt_display_commit(&data->display);
513
514 igt_plane_set_fb(data->primary, &data->fb_green);
515 igt_display_commit(&data->display);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300516}
517
Rodrigo Vivic3524752015-03-13 12:11:54 -0400518static void dpms_off_on(data_t data)
519{
520 kmstest_set_connector_dpms(data.drm_fd, data.output->config.connector,
521 DRM_MODE_DPMS_OFF);
522 sleep(1);
523 kmstest_set_connector_dpms(data.drm_fd, data.output->config.connector,
524 DRM_MODE_DPMS_ON);
525}
526
Damien Lespiaufd6846c2015-05-14 14:19:01 +0100527static int opt_handler(int opt, int opt_index, void *data)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300528{
Daniel Vetter3205a912014-09-23 15:15:51 +0200529 switch (opt) {
530 case 'n':
531 running_with_psr_disabled = true;
532 break;
533 default:
534 igt_assert(0);
535 }
536
537 return 0;
538}
539
540int main(int argc, char *argv[])
541{
542 const char *help_str =
543 " --no-psr\tRun test without PSR to check the CRC test logic.";
544 static struct option long_options[] = {
545 {"no-psr", 0, 0, 'n'},
546 { 0, 0, 0, 0 }
547 };
Rodrigo Vivi1ab04452014-08-29 17:58:31 -0400548 data_t data = {};
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400549 enum operations op;
Rodrigo Vivi1ab04452014-08-29 17:58:31 -0400550
Thomas Wood8fb19782015-02-18 16:19:59 +0000551 igt_subtest_init_parse_opts(&argc, argv, "", long_options,
Damien Lespiaufd6846c2015-05-14 14:19:01 +0100552 help_str, opt_handler, NULL);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300553 igt_skip_on_simulation();
554
555 igt_fixture {
Micah Fedkec81d2932015-07-22 21:54:02 +0000556 data.drm_fd = drm_open_driver_master(DRIVER_INTEL);
Daniel Vetter33f08842014-08-12 11:23:09 +0200557 kmstest_set_vt_graphics_mode();
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300558 data.devid = intel_get_drm_devid(data.drm_fd);
559
Rodrigo Vivi63980ba2015-11-03 09:37:56 -0800560 igt_set_module_param_int("enable_psr", running_with_psr_disabled ?
561 0 : 1);
Paulo Zanoni75b286e2015-06-02 12:03:45 -0300562
563 igt_skip_on(!psr_possible(&data));
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300564
565 data.bufmgr = drm_intel_bufmgr_gem_init(data.drm_fd, 4096);
566 igt_assert(data.bufmgr);
567 drm_intel_bufmgr_gem_enable_reuse(data.bufmgr);
568
569 display_init(&data);
570 }
571
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400572 for (op = PAGE_FLIP; op <= RENDER; op++) {
573 igt_subtest_f("primary_%s", op_str(op)) {
574 data.test_plane = PRIMARY;
575 data.op = op;
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400576 setup_test_plane(&data);
577 igt_assert(wait_psr_entry(&data));
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400578 run_test(&data);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400579 test_cleanup(&data);
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400580 }
581 }
582
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400583 for (op = MMAP_GTT; op <= PLANE_ONOFF; op++) {
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400584 igt_subtest_f("sprite_%s", op_str(op)) {
585 data.test_plane = SPRITE;
586 data.op = op;
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400587 setup_test_plane(&data);
588 igt_assert(wait_psr_entry(&data));
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400589 run_test(&data);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400590 test_cleanup(&data);
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400591 }
592 }
593
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400594 for (op = MMAP_GTT; op <= PLANE_ONOFF; op++) {
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400595 igt_subtest_f("cursor_%s", op_str(op)) {
596 data.test_plane = CURSOR;
597 data.op = op;
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400598 setup_test_plane(&data);
599 igt_assert(wait_psr_entry(&data));
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300600 run_test(&data);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400601 test_cleanup(&data);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300602 }
603 }
604
Rodrigo Vivic3524752015-03-13 12:11:54 -0400605 igt_subtest_f("dpms_off_psr_active") {
606 data.test_plane = PRIMARY;
607 data.op = RENDER;
608 setup_test_plane(&data);
609 igt_assert(wait_psr_entry(&data));
610
611 dpms_off_on(data);
612
613 run_test(&data);
614 test_cleanup(&data);
615 }
616
617 igt_subtest_f("dpms_off_psr_exit") {
618 data.test_plane = SPRITE;
619 data.op = PLANE_ONOFF;
620 setup_test_plane(&data);
621
622 dpms_off_on(data);
623
624 igt_assert(wait_psr_entry(&data));
625 run_test(&data);
626 test_cleanup(&data);
627 }
628
Rodrigo Vivi7bd31d02015-11-03 10:02:14 -0800629 igt_subtest_f("suspend_psr_active") {
630 data.test_plane = PRIMARY;
631 data.op = PAGE_FLIP;
632 setup_test_plane(&data);
633 igt_assert(wait_psr_entry(&data));
634
635 igt_system_suspend_autoresume();
636
637 run_test(&data);
638 test_cleanup(&data);
639 }
640
641 igt_subtest_f("suspend_psr_exit") {
642 data.test_plane = CURSOR;
643 data.op = PLANE_ONOFF;
644 setup_test_plane(&data);
645
646 igt_system_suspend_autoresume();
647
648 igt_assert(wait_psr_entry(&data));
649 run_test(&data);
650 test_cleanup(&data);
651 }
652
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300653 igt_fixture {
654 drm_intel_bufmgr_destroy(data.bufmgr);
655 display_fini(&data);
656 }
Daniel Vetter3205a912014-09-23 15:15:51 +0200657
658 igt_exit();
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300659}