blob: b18e426303e3c924c68bde82497330383612bfbc [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 Vivi05ac6112016-01-08 07:40:45 -0800202 char buf[512];
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300203
Rodrigo Vivi05ac6112016-01-08 07:40:45 -0800204 igt_debugfs_read("i915_edp_psr_status", buf);
Rodrigo Vivi1ab04452014-08-29 17:58:31 -0400205
Rodrigo Vivi05ac6112016-01-08 07:40:45 -0800206 return running_with_psr_disabled ||
207 strstr(buf, "Sink_Support: yes\n");
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300208}
209
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700210static bool psr_active(data_t *data)
211{
Rodrigo Vivi05ac6112016-01-08 07:40:45 -0800212 char buf[512];
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700213
Rodrigo Vivi05ac6112016-01-08 07:40:45 -0800214 igt_debugfs_read("i915_edp_psr_status", buf);
Rodrigo Vivi1ab04452014-08-29 17:58:31 -0400215
Rodrigo Vivi05ac6112016-01-08 07:40:45 -0800216 return running_with_psr_disabled ||
217 strstr(buf, "HW Enabled & Active bit: yes\n");
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700218}
219
Rodrigo Vivifd9ef1b2015-03-13 12:28:07 -0400220static bool wait_psr_entry(data_t *data)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300221{
Rodrigo Vivi4a004d92015-12-07 01:26:17 -0800222 int timeout = 5;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300223 while (timeout--) {
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700224 if (psr_active(data))
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300225 return true;
226 sleep(1);
227 }
228 return false;
229}
230
231static void get_sink_crc(data_t *data, char *crc) {
232 int ret;
233 FILE *file;
234
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500235 if (igt_interactive_debug)
236 return;
237
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300238 file = igt_debugfs_fopen("i915_sink_crc_eDP1", "r");
239 igt_require(file);
240
241 ret = fscanf(file, "%s\n", crc);
Rodrigo Viviae9c6852014-12-09 20:44:11 -0500242 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 -0300243
244 fclose(file);
Rodrigo Vivi1ab04452014-08-29 17:58:31 -0400245
246 igt_debug("%s\n", crc);
247 igt_debug_wait_for_keypress("crc");
248
249 /* The important value was already taken.
250 * Now give a time for human eyes
251 */
252 usleep(300000);
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400253
254 /* Black screen is always invalid */
255 igt_assert(strcmp(crc, CRC_BLACK) != 0);
256}
257
258static bool is_green(char *crc)
259{
260 char color_mask[5] = "FFFF\0";
261 char rs[5], gs[5], bs[5];
262 unsigned int rh, gh, bh, mask;
263 int ret;
264
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500265 if (igt_interactive_debug)
266 return false;
267
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400268 sscanf(color_mask, "%4x", &mask);
269
270 memcpy(rs, &crc[0], 4);
271 rs[4] = '\0';
272 ret = sscanf(rs, "%4x", &rh);
273 igt_require(ret > 0);
274
275 memcpy(gs, &crc[4], 4);
276 gs[4] = '\0';
277 ret = sscanf(gs, "%4x", &gh);
278 igt_require(ret > 0);
279
280 memcpy(bs, &crc[8], 4);
281 bs[4] = '\0';
282 ret = sscanf(bs, "%4x", &bh);
283 igt_require(ret > 0);
284
285 return ((rh & mask) == 0 &&
286 (gh & mask) != 0 &&
287 (bh & mask) == 0);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300288}
289
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500290static void assert_or_manual(bool condition, const char *expected)
291{
Rodrigo Viviae9c6852014-12-09 20:44:11 -0500292 igt_debug_manual_check("no-crc", expected);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500293 igt_assert(igt_interactive_debug || condition);
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) {
316 case PRIMARY: default: test_plane = data->primary; break;
317 case SPRITE: test_plane = data->sprite; break;
318 case 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);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500326 if (data->test_plane == PRIMARY)
327 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);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500358 if (data->test_plane == PRIMARY)
359 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);
409 if (data->test_plane == SPRITE)
410 igt_plane_set_fb(data->sprite, NULL);
411 if (data->test_plane == CURSOR)
412 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
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400431 data->primary = igt_output_get_plane(data->output, IGT_PLANE_PRIMARY);
432 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) {
442 case SPRITE:
443 data->sprite = igt_output_get_plane(data->output,
444 IGT_PLANE_2);
445 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;
451 case 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;
459 case CURSOR:
460 data->cursor = igt_output_get_plane(data->output,
461 IGT_PLANE_CURSOR);
462 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
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400536 for (op = PAGE_FLIP; op <= RENDER; op++) {
537 igt_subtest_f("primary_%s", op_str(op)) {
538 data.test_plane = PRIMARY;
539 data.op = op;
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400540 setup_test_plane(&data);
541 igt_assert(wait_psr_entry(&data));
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400542 run_test(&data);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400543 test_cleanup(&data);
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400544 }
545 }
546
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400547 for (op = MMAP_GTT; op <= PLANE_ONOFF; op++) {
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400548 igt_subtest_f("sprite_%s", op_str(op)) {
549 data.test_plane = SPRITE;
550 data.op = op;
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400551 setup_test_plane(&data);
552 igt_assert(wait_psr_entry(&data));
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400553 run_test(&data);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400554 test_cleanup(&data);
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400555 }
556 }
557
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400558 for (op = MMAP_GTT; op <= PLANE_ONOFF; op++) {
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400559 igt_subtest_f("cursor_%s", op_str(op)) {
560 data.test_plane = CURSOR;
561 data.op = op;
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400562 setup_test_plane(&data);
563 igt_assert(wait_psr_entry(&data));
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300564 run_test(&data);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400565 test_cleanup(&data);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300566 }
567 }
568
Rodrigo Vivic3524752015-03-13 12:11:54 -0400569 igt_subtest_f("dpms_off_psr_active") {
570 data.test_plane = PRIMARY;
571 data.op = RENDER;
572 setup_test_plane(&data);
573 igt_assert(wait_psr_entry(&data));
574
575 dpms_off_on(data);
576
577 run_test(&data);
578 test_cleanup(&data);
579 }
580
581 igt_subtest_f("dpms_off_psr_exit") {
582 data.test_plane = SPRITE;
583 data.op = PLANE_ONOFF;
584 setup_test_plane(&data);
585
586 dpms_off_on(data);
587
588 igt_assert(wait_psr_entry(&data));
589 run_test(&data);
590 test_cleanup(&data);
591 }
592
Rodrigo Vivi7bd31d02015-11-03 10:02:14 -0800593 igt_subtest_f("suspend_psr_active") {
594 data.test_plane = PRIMARY;
595 data.op = PAGE_FLIP;
596 setup_test_plane(&data);
597 igt_assert(wait_psr_entry(&data));
598
599 igt_system_suspend_autoresume();
600
601 run_test(&data);
602 test_cleanup(&data);
603 }
604
605 igt_subtest_f("suspend_psr_exit") {
606 data.test_plane = CURSOR;
607 data.op = PLANE_ONOFF;
608 setup_test_plane(&data);
609
610 igt_system_suspend_autoresume();
611
612 igt_assert(wait_psr_entry(&data));
613 run_test(&data);
614 test_cleanup(&data);
615 }
616
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300617 igt_fixture {
618 drm_intel_bufmgr_destroy(data.bufmgr);
619 display_fini(&data);
620 }
Daniel Vetter3205a912014-09-23 15:15:51 +0200621
622 igt_exit();
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300623}