blob: 2b60acf34e77acf4617c4f5cc2cb049aa9c2d513 [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"
Dhinakaran Pandiyanb94a17d2017-09-18 18:55:09 -070037#define CRC_LEN 12
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -040038
Rodrigo Vivi99efdc02014-09-09 17:58:45 -040039enum operations {
40 PAGE_FLIP,
41 MMAP_GTT,
42 MMAP_GTT_WAITING,
43 MMAP_CPU,
44 BLT,
45 RENDER,
46 PLANE_MOVE,
47 PLANE_ONOFF,
48};
49
50static const char *op_str(enum operations op)
51{
52 static const char * const name[] = {
53 [PAGE_FLIP] = "page_flip",
54 [MMAP_GTT] = "mmap_gtt",
55 [MMAP_GTT_WAITING] = "mmap_gtt_waiting",
56 [MMAP_CPU] = "mmap_cpu",
57 [BLT] = "blt",
58 [RENDER] = "render",
59 [PLANE_MOVE] = "plane_move",
60 [PLANE_ONOFF] = "plane_onoff",
61 };
62
63 return name[op];
64}
Rodrigo Vivi1ab04452014-08-29 17:58:31 -040065
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030066typedef struct {
67 int drm_fd;
Robert Foss934062c2017-01-10 20:16:23 -050068 int test_plane;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -040069 enum operations op;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030070 uint32_t devid;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030071 uint32_t crtc_id;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030072 igt_display_t display;
Rodrigo Vivid4e6a512014-08-29 19:12:54 -040073 drm_intel_bufmgr *bufmgr;
74 struct igt_fb fb_green, fb_white;
75 igt_plane_t *primary, *sprite, *cursor;
Rodrigo Vivi00992f72014-12-05 20:01:41 -050076 int mod_size;
Rodrigo Vivi36ecc312015-04-14 18:04:01 -070077 int mod_stride;
Rodrigo Vivi782d5e72015-03-13 12:10:20 -040078 drmModeModeInfo *mode;
79 igt_output_t *output;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030080} data_t;
81
Rodrigo Vivid4e6a512014-08-29 19:12:54 -040082static void create_cursor_fb(data_t *data)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030083{
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030084 cairo_t *cr;
Rodrigo Vivid4e6a512014-08-29 19:12:54 -040085 uint32_t fb_id;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030086
Rodrigo Vivid4e6a512014-08-29 19:12:54 -040087 fb_id = igt_create_fb(data->drm_fd, 64, 64,
Tvrtko Ursuline36091d2015-03-03 14:11:01 +000088 DRM_FORMAT_ARGB8888, LOCAL_DRM_FORMAT_MOD_NONE,
Rodrigo Vivid4e6a512014-08-29 19:12:54 -040089 &data->fb_white);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030090 igt_assert(fb_id);
91
Rodrigo Vivid4e6a512014-08-29 19:12:54 -040092 cr = igt_get_cairo_ctx(data->drm_fd, &data->fb_white);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030093 igt_paint_color_alpha(cr, 0, 0, 64, 64, 1.0, 1.0, 1.0, 1.0);
Maarten Lankhorstbe2f6fc2018-02-01 12:48:45 +010094 igt_put_cairo_ctx(data->drm_fd, &data->fb_white, cr);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -030095}
96
Rodrigo Vivi782d5e72015-03-13 12:10:20 -040097
98static void setup_output(data_t *data)
99{
100 igt_display_t *display = &data->display;
101 igt_output_t *output;
Maarten Lankhorstcd885952016-06-30 07:41:44 +0200102 enum pipe pipe;
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400103
Maarten Lankhorstcd885952016-06-30 07:41:44 +0200104 for_each_pipe_with_valid_output(display, pipe, output) {
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400105 drmModeConnectorPtr c = output->config.connector;
106
Maarten Lankhorstcd885952016-06-30 07:41:44 +0200107 if (c->connector_type != DRM_MODE_CONNECTOR_eDP)
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400108 continue;
109
Maarten Lankhorstcd885952016-06-30 07:41:44 +0200110 igt_output_set_pipe(output, pipe);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400111 data->crtc_id = output->config.crtc->crtc_id;
112 data->output = output;
113 data->mode = igt_output_get_mode(output);
114
115 return;
116 }
117}
118
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300119static void display_init(data_t *data)
120{
121 igt_display_init(&data->display, data->drm_fd);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400122 setup_output(data);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300123}
124
125static void display_fini(data_t *data)
126{
127 igt_display_fini(&data->display);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300128}
129
130static void fill_blt(data_t *data, uint32_t handle, unsigned char color)
131{
132 drm_intel_bo *dst = gem_handle_to_libdrm_bo(data->bufmgr,
133 data->drm_fd,
134 "", handle);
135 struct intel_batchbuffer *batch;
136
137 batch = intel_batchbuffer_alloc(data->bufmgr, data->devid);
138 igt_assert(batch);
139
Chris Wilson10552b52014-08-30 11:44:51 +0100140 COLOR_BLIT_COPY_BATCH_START(0);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300141 OUT_BATCH((1 << 24) | (0xf0 << 16) | 0);
Rodrigo Vivi1447d832014-09-03 18:18:15 -0400142 OUT_BATCH(0);
Rodrigo Vivi3cb21242014-12-05 19:43:34 -0500143 OUT_BATCH(0xfff << 16 | 0xfff);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300144 OUT_RELOC(dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
145 OUT_BATCH(color);
146 ADVANCE_BATCH();
147
148 intel_batchbuffer_flush(batch);
149 intel_batchbuffer_free(batch);
150
151 gem_bo_busy(data->drm_fd, handle);
152}
153
Rodrigo Vivi36ecc312015-04-14 18:04:01 -0700154static void scratch_buf_init(struct igt_buf *buf, drm_intel_bo *bo,
155 int size, int stride)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300156{
157 buf->bo = bo;
Rodrigo Vivi36ecc312015-04-14 18:04:01 -0700158 buf->stride = stride;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300159 buf->tiling = I915_TILING_X;
Rodrigo Vivi36ecc312015-04-14 18:04:01 -0700160 buf->size = size;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300161}
162
Rodrigo Vivifb004a62014-09-03 17:53:35 -0400163static void fill_render(data_t *data, uint32_t handle, unsigned char color)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300164{
165 drm_intel_bo *src, *dst;
166 struct intel_batchbuffer *batch;
167 struct igt_buf src_buf, dst_buf;
168 const uint8_t buf[4] = { color, color, color, color };
169 igt_render_copyfunc_t rendercopy = igt_get_render_copyfunc(data->devid);
170
171 igt_skip_on(!rendercopy);
172
173 dst = gem_handle_to_libdrm_bo(data->bufmgr, data->drm_fd, "", handle);
174 igt_assert(dst);
175
Rodrigo Vivi36ecc312015-04-14 18:04:01 -0700176 src = drm_intel_bo_alloc(data->bufmgr, "", data->mod_size, 4096);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300177 igt_assert(src);
178
179 gem_write(data->drm_fd, src->handle, 0, buf, 4);
180
Rodrigo Vivi36ecc312015-04-14 18:04:01 -0700181 scratch_buf_init(&src_buf, src, data->mod_size, data->mod_stride);
182 scratch_buf_init(&dst_buf, dst, data->mod_size, data->mod_stride);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300183
184 batch = intel_batchbuffer_alloc(data->bufmgr, data->devid);
185 igt_assert(batch);
186
Rodrigo Vivifb004a62014-09-03 17:53:35 -0400187 rendercopy(batch, NULL,
Rodrigo Vivif20690d2014-12-05 19:45:37 -0500188 &src_buf, 0, 0, 0xff, 0xff,
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300189 &dst_buf, 0, 0);
190
191 intel_batchbuffer_free(batch);
192
193 gem_bo_busy(data->drm_fd, handle);
194}
195
Paulo Zanoni75b286e2015-06-02 12:03:45 -0300196static bool psr_possible(data_t *data)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300197{
Rodrigo Vivi05ac6112016-01-08 07:40:45 -0800198 char buf[512];
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300199
Chris Wilson83884e92017-03-21 17:16:03 +0000200 igt_debugfs_read(data->drm_fd, "i915_edp_psr_status", buf);
Rodrigo Vivi1ab04452014-08-29 17:58:31 -0400201
Rodrigo Vivi05ac6112016-01-08 07:40:45 -0800202 return running_with_psr_disabled ||
203 strstr(buf, "Sink_Support: yes\n");
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300204}
205
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700206static bool psr_active(data_t *data)
207{
Rodrigo Vivi05ac6112016-01-08 07:40:45 -0800208 char buf[512];
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700209
Chris Wilson83884e92017-03-21 17:16:03 +0000210 igt_debugfs_read(data->drm_fd, "i915_edp_psr_status", buf);
Rodrigo Vivi1ab04452014-08-29 17:58:31 -0400211
Rodrigo Vivi05ac6112016-01-08 07:40:45 -0800212 return running_with_psr_disabled ||
213 strstr(buf, "HW Enabled & Active bit: yes\n");
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700214}
215
Rodrigo Vivifd9ef1b2015-03-13 12:28:07 -0400216static bool wait_psr_entry(data_t *data)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300217{
Rodrigo Vivi4a004d92015-12-07 01:26:17 -0800218 int timeout = 5;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300219 while (timeout--) {
Rodrigo Vivie90847f2014-08-22 09:37:08 -0700220 if (psr_active(data))
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300221 return true;
222 sleep(1);
223 }
224 return false;
225}
226
227static void get_sink_crc(data_t *data, char *crc) {
Chris Wilsone08ed8a2017-03-24 20:52:44 +0000228 int dir;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300229
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500230 if (igt_interactive_debug)
231 return;
232
Chris Wilsone08ed8a2017-03-24 20:52:44 +0000233 dir = igt_debugfs_dir(data->drm_fd);
234 igt_require_f(igt_sysfs_scanf(dir, "i915_sink_crc_eDP1", "%s\n", crc),
235 "Sink CRC is unreliable on this machine. Try manual debug with --interactive-debug=no-crc\n");
236 close(dir);
Rodrigo Vivi1ab04452014-08-29 17:58:31 -0400237
238 igt_debug("%s\n", crc);
239 igt_debug_wait_for_keypress("crc");
240
241 /* The important value was already taken.
242 * Now give a time for human eyes
243 */
244 usleep(300000);
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400245
246 /* Black screen is always invalid */
Dhinakaran Pandiyanb94a17d2017-09-18 18:55:09 -0700247 igt_assert(strncmp(crc, CRC_BLACK, CRC_LEN) != 0);
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400248}
249
250static bool is_green(char *crc)
251{
252 char color_mask[5] = "FFFF\0";
253 char rs[5], gs[5], bs[5];
254 unsigned int rh, gh, bh, mask;
255 int ret;
256
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500257 if (igt_interactive_debug)
258 return false;
259
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400260 sscanf(color_mask, "%4x", &mask);
261
262 memcpy(rs, &crc[0], 4);
263 rs[4] = '\0';
264 ret = sscanf(rs, "%4x", &rh);
265 igt_require(ret > 0);
266
267 memcpy(gs, &crc[4], 4);
268 gs[4] = '\0';
269 ret = sscanf(gs, "%4x", &gh);
270 igt_require(ret > 0);
271
272 memcpy(bs, &crc[8], 4);
273 bs[4] = '\0';
274 ret = sscanf(bs, "%4x", &bh);
275 igt_require(ret > 0);
276
277 return ((rh & mask) == 0 &&
278 (gh & mask) != 0 &&
279 (bh & mask) == 0);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300280}
281
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500282static void assert_or_manual(bool condition, const char *expected)
283{
Rodrigo Viviae9c6852014-12-09 20:44:11 -0500284 igt_debug_manual_check("no-crc", expected);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500285 igt_assert(igt_interactive_debug || condition);
286}
287
Radhakrishna Sripada6dceb6f2017-09-15 17:00:08 -0700288static bool drrs_disabled(data_t *data)
289{
290 char buf[512];
291
292 igt_debugfs_read(data->drm_fd, "i915_drrs_status", buf);
293
Radhakrishna Sripada7c79e2c2017-09-21 17:21:46 -0700294 return !strstr(buf, "DRRS Supported: Yes\n");
Radhakrishna Sripada6dceb6f2017-09-15 17:00:08 -0700295}
296
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400297static void run_test(data_t *data)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300298{
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400299 uint32_t handle = data->fb_white.gem_handle;
300 igt_plane_t *test_plane;
301 void *ptr;
Dhinakaran Pandiyanb94a17d2017-09-18 18:55:09 -0700302 char ref_crc[CRC_LEN];
303 char crc[CRC_LEN];
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500304 const char *expected = "";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300305
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400306 /* Confirm that screen became Green */
307 get_sink_crc(data, ref_crc);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500308 assert_or_manual(is_green(ref_crc), "screen GREEN");
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400309
310 /* Confirm screen stays Green after PSR got active */
Rodrigo Vivifd9ef1b2015-03-13 12:28:07 -0400311 igt_assert(wait_psr_entry(data));
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400312 get_sink_crc(data, ref_crc);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500313 assert_or_manual(is_green(ref_crc), "screen GREEN");
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400314
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400315 /* Setting a secondary fb/plane */
316 switch (data->test_plane) {
Robert Foss934062c2017-01-10 20:16:23 -0500317 case DRM_PLANE_TYPE_PRIMARY: default: test_plane = data->primary; break;
318 case DRM_PLANE_TYPE_OVERLAY: test_plane = data->sprite; break;
319 case DRM_PLANE_TYPE_CURSOR: test_plane = data->cursor; break;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300320 }
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400321 igt_plane_set_fb(test_plane, &data->fb_white);
322 igt_display_commit(&data->display);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300323
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400324 /* Confirm it is not Green anymore */
Rodrigo Vivifd9ef1b2015-03-13 12:28:07 -0400325 igt_assert(wait_psr_entry(data));
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300326 get_sink_crc(data, ref_crc);
Robert Foss934062c2017-01-10 20:16:23 -0500327 if (data->test_plane == DRM_PLANE_TYPE_PRIMARY)
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500328 assert_or_manual(!is_green(ref_crc), "screen WHITE");
329 else
330 assert_or_manual(!is_green(ref_crc), "GREEN background with WHITE box");
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300331
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400332 switch (data->op) {
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400333 case PAGE_FLIP:
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400334 /* Only in use when testing primary plane */
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300335 igt_assert(drmModePageFlip(data->drm_fd, data->crtc_id,
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400336 data->fb_green.fb_id, 0, NULL) == 0);
Rodrigo Vivi25aa69d2014-09-09 13:10:51 -0400337 get_sink_crc(data, crc);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500338 assert_or_manual(is_green(crc), "screen GREEN");
339 expected = "still GREEN";
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400340 break;
341 case MMAP_GTT:
Ville Syrjäläf52e7ec2015-10-09 19:11:39 +0300342 ptr = gem_mmap__gtt(data->drm_fd, handle, data->mod_size,
Rodrigo Vivi00992f72014-12-05 20:01:41 -0500343 PROT_WRITE);
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400344 gem_set_domain(data->drm_fd, handle,
345 I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
Rodrigo Vivi00992f72014-12-05 20:01:41 -0500346 memset(ptr, 0xcc, data->mod_size);
347 munmap(ptr, data->mod_size);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500348 expected = "BLACK or TRANSPARENT mark on top of plane in test";
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400349 break;
350 case MMAP_GTT_WAITING:
Ville Syrjäläf52e7ec2015-10-09 19:11:39 +0300351 ptr = gem_mmap__gtt(data->drm_fd, handle, data->mod_size,
Rodrigo Vivi00992f72014-12-05 20:01:41 -0500352 PROT_WRITE);
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400353 gem_set_domain(data->drm_fd, handle,
354 I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
355
356 /* Printing white on white so the screen shouldn't change */
Rodrigo Vivi00992f72014-12-05 20:01:41 -0500357 memset(ptr, 0xff, data->mod_size);
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400358 get_sink_crc(data, crc);
Robert Foss934062c2017-01-10 20:16:23 -0500359 if (data->test_plane == DRM_PLANE_TYPE_PRIMARY)
Dhinakaran Pandiyanb94a17d2017-09-18 18:55:09 -0700360 assert_or_manual(strncmp(ref_crc, crc, CRC_LEN) == 0, "screen WHITE");
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500361 else
Dhinakaran Pandiyanb94a17d2017-09-18 18:55:09 -0700362 assert_or_manual(strncmp(ref_crc, crc, CRC_LEN) == 0,
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500363 "GREEN background with WHITE box");
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400364
Daniel Vetter8b556f72014-10-23 17:54:44 +0200365 igt_info("Waiting 10s...\n");
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400366 sleep(10);
367
368 /* Now lets print black to change the screen */
Rodrigo Vivi00992f72014-12-05 20:01:41 -0500369 memset(ptr, 0, data->mod_size);
370 munmap(ptr, data->mod_size);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500371 expected = "BLACK or TRANSPARENT mark on top of plane in test";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300372 break;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400373 case MMAP_CPU:
Ville Syrjäläf52e7ec2015-10-09 19:11:39 +0300374 ptr = gem_mmap__cpu(data->drm_fd, handle, 0, data->mod_size,
375 PROT_WRITE);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300376 gem_set_domain(data->drm_fd, handle,
377 I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
Rodrigo Vivi00992f72014-12-05 20:01:41 -0500378 memset(ptr, 0, data->mod_size);
379 munmap(ptr, data->mod_size);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300380 gem_sw_finish(data->drm_fd, handle);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500381 expected = "BLACK or TRANSPARENT mark on top of plane in test";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300382 break;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400383 case BLT:
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400384 fill_blt(data, handle, 0);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500385 expected = "BLACK or TRANSPARENT mark on top of plane in test";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300386 break;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400387 case RENDER:
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400388 fill_render(data, handle, 0);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500389 expected = "BLACK or TRANSPARENT mark on top of plane in test";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300390 break;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400391 case PLANE_MOVE:
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400392 /* Only in use when testing Sprite and Cursor */
Rodrigo Vivib7b2ecb2014-12-05 20:03:31 -0500393 igt_plane_set_position(test_plane, 500, 500);
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400394 igt_display_commit(&data->display);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500395 expected = "White box moved to 500x500";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300396 break;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400397 case PLANE_ONOFF:
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400398 /* Only in use when testing Sprite and Cursor */
399 igt_plane_set_fb(test_plane, NULL);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300400 igt_display_commit(&data->display);
Rodrigo Vivie1ac0442014-12-05 20:03:43 -0500401 expected = "screen GREEN";
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300402 break;
403 }
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300404 get_sink_crc(data, crc);
Dhinakaran Pandiyanb94a17d2017-09-18 18:55:09 -0700405 assert_or_manual(strncmp(ref_crc, crc, CRC_LEN) != 0, expected);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300406}
407
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400408static void test_cleanup(data_t *data) {
409 igt_plane_set_fb(data->primary, NULL);
Robert Foss934062c2017-01-10 20:16:23 -0500410 if (data->test_plane == DRM_PLANE_TYPE_OVERLAY)
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400411 igt_plane_set_fb(data->sprite, NULL);
Robert Foss934062c2017-01-10 20:16:23 -0500412 if (data->test_plane == DRM_PLANE_TYPE_CURSOR)
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400413 igt_plane_set_fb(data->cursor, NULL);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300414
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400415 igt_display_commit(&data->display);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300416
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400417 igt_remove_fb(data->drm_fd, &data->fb_green);
418 igt_remove_fb(data->drm_fd, &data->fb_white);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300419}
420
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400421static void setup_test_plane(data_t *data)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300422{
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400423 uint32_t white_h, white_v;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300424
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400425 igt_create_color_fb(data->drm_fd,
426 data->mode->hdisplay, data->mode->vdisplay,
427 DRM_FORMAT_XRGB8888,
428 LOCAL_I915_FORMAT_MOD_X_TILED,
429 0.0, 1.0, 0.0,
430 &data->fb_green);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300431
Robert Foss934062c2017-01-10 20:16:23 -0500432 data->primary = igt_output_get_plane_type(data->output, DRM_PLANE_TYPE_PRIMARY);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400433 igt_plane_set_fb(data->primary, NULL);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300434
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400435 white_h = data->mode->hdisplay;
436 white_v = data->mode->vdisplay;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300437
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400438 /* Ignoring pitch and bpp to avoid changing full screen */
439 data->mod_size = white_h * white_v;
Rodrigo Vivi36ecc312015-04-14 18:04:01 -0700440 data->mod_stride = white_h * 4;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300441
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400442 switch (data->test_plane) {
Robert Foss934062c2017-01-10 20:16:23 -0500443 case DRM_PLANE_TYPE_OVERLAY:
444 data->sprite = igt_output_get_plane_type(data->output,
445 DRM_PLANE_TYPE_OVERLAY);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400446 igt_plane_set_fb(data->sprite, NULL);
447 /* To make it different for human eyes let's make
448 * sprite visible in only one quarter of the primary
449 */
450 white_h = white_h/2;
451 white_v = white_v/2;
Robert Foss934062c2017-01-10 20:16:23 -0500452 case DRM_PLANE_TYPE_PRIMARY:
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300453 igt_create_color_fb(data->drm_fd,
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400454 white_h, white_v,
Tvrtko Ursuline36091d2015-03-03 14:11:01 +0000455 DRM_FORMAT_XRGB8888,
456 LOCAL_I915_FORMAT_MOD_X_TILED,
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400457 1.0, 1.0, 1.0,
458 &data->fb_white);
459 break;
Robert Foss934062c2017-01-10 20:16:23 -0500460 case DRM_PLANE_TYPE_CURSOR:
461 data->cursor = igt_output_get_plane_type(data->output,
462 DRM_PLANE_TYPE_CURSOR);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400463 igt_plane_set_fb(data->cursor, NULL);
464 create_cursor_fb(data);
465 igt_plane_set_position(data->cursor, 0, 0);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300466
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400467 /* Cursor is 64 x 64, ignoring pitch and bbp again */
468 data->mod_size = 64 * 64;
469 break;
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300470 }
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400471
472 igt_display_commit(&data->display);
473
474 igt_plane_set_fb(data->primary, &data->fb_green);
475 igt_display_commit(&data->display);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300476}
477
Rodrigo Vivic3524752015-03-13 12:11:54 -0400478static void dpms_off_on(data_t data)
479{
480 kmstest_set_connector_dpms(data.drm_fd, data.output->config.connector,
481 DRM_MODE_DPMS_OFF);
482 sleep(1);
483 kmstest_set_connector_dpms(data.drm_fd, data.output->config.connector,
484 DRM_MODE_DPMS_ON);
485}
486
Damien Lespiaufd6846c2015-05-14 14:19:01 +0100487static int opt_handler(int opt, int opt_index, void *data)
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300488{
Daniel Vetter3205a912014-09-23 15:15:51 +0200489 switch (opt) {
490 case 'n':
491 running_with_psr_disabled = true;
492 break;
493 default:
494 igt_assert(0);
495 }
496
497 return 0;
498}
499
500int main(int argc, char *argv[])
501{
502 const char *help_str =
503 " --no-psr\tRun test without PSR to check the CRC test logic.";
504 static struct option long_options[] = {
505 {"no-psr", 0, 0, 'n'},
506 { 0, 0, 0, 0 }
507 };
Rodrigo Vivi1ab04452014-08-29 17:58:31 -0400508 data_t data = {};
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400509 enum operations op;
Rodrigo Vivi1ab04452014-08-29 17:58:31 -0400510
Thomas Wood8fb19782015-02-18 16:19:59 +0000511 igt_subtest_init_parse_opts(&argc, argv, "", long_options,
Damien Lespiaufd6846c2015-05-14 14:19:01 +0100512 help_str, opt_handler, NULL);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300513 igt_skip_on_simulation();
514
515 igt_fixture {
Micah Fedkec81d2932015-07-22 21:54:02 +0000516 data.drm_fd = drm_open_driver_master(DRIVER_INTEL);
Daniel Vetter33f08842014-08-12 11:23:09 +0200517 kmstest_set_vt_graphics_mode();
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300518 data.devid = intel_get_drm_devid(data.drm_fd);
519
Rodrigo Vivi63980ba2015-11-03 09:37:56 -0800520 igt_set_module_param_int("enable_psr", running_with_psr_disabled ?
521 0 : 1);
Paulo Zanoni75b286e2015-06-02 12:03:45 -0300522
523 igt_skip_on(!psr_possible(&data));
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300524
525 data.bufmgr = drm_intel_bufmgr_gem_init(data.drm_fd, 4096);
526 igt_assert(data.bufmgr);
527 drm_intel_bufmgr_gem_enable_reuse(data.bufmgr);
528
529 display_init(&data);
530 }
531
Rodrigo Vivi4aa1b992015-12-08 00:11:21 -0800532 igt_subtest("psr_basic") {
533 setup_test_plane(&data);
534 igt_assert(wait_psr_entry(&data));
Marta Lofstedt472ecd32018-01-05 11:04:13 +0200535 test_cleanup(&data);
Rodrigo Vivi4aa1b992015-12-08 00:11:21 -0800536 }
537
Radhakrishna Sripada6dceb6f2017-09-15 17:00:08 -0700538 igt_subtest("psr_drrs") {
539 setup_test_plane(&data);
540 igt_assert(drrs_disabled(&data));
Marta Lofstedt472ecd32018-01-05 11:04:13 +0200541 test_cleanup(&data);
Radhakrishna Sripada6dceb6f2017-09-15 17:00:08 -0700542 }
543
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400544 for (op = PAGE_FLIP; op <= RENDER; op++) {
545 igt_subtest_f("primary_%s", op_str(op)) {
Robert Foss934062c2017-01-10 20:16:23 -0500546 data.test_plane = DRM_PLANE_TYPE_PRIMARY;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400547 data.op = op;
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400548 setup_test_plane(&data);
549 igt_assert(wait_psr_entry(&data));
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400550 run_test(&data);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400551 test_cleanup(&data);
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400552 }
553 }
554
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400555 for (op = MMAP_GTT; op <= PLANE_ONOFF; op++) {
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400556 igt_subtest_f("sprite_%s", op_str(op)) {
Robert Foss934062c2017-01-10 20:16:23 -0500557 data.test_plane = DRM_PLANE_TYPE_OVERLAY;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400558 data.op = op;
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400559 setup_test_plane(&data);
560 igt_assert(wait_psr_entry(&data));
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400561 run_test(&data);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400562 test_cleanup(&data);
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400563 }
564 }
565
Rodrigo Vivid4e6a512014-08-29 19:12:54 -0400566 for (op = MMAP_GTT; op <= PLANE_ONOFF; op++) {
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400567 igt_subtest_f("cursor_%s", op_str(op)) {
Robert Foss934062c2017-01-10 20:16:23 -0500568 data.test_plane = DRM_PLANE_TYPE_CURSOR;
Rodrigo Vivi99efdc02014-09-09 17:58:45 -0400569 data.op = op;
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400570 setup_test_plane(&data);
571 igt_assert(wait_psr_entry(&data));
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300572 run_test(&data);
Rodrigo Vivi782d5e72015-03-13 12:10:20 -0400573 test_cleanup(&data);
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300574 }
575 }
576
Rodrigo Vivic3524752015-03-13 12:11:54 -0400577 igt_subtest_f("dpms_off_psr_active") {
Robert Foss934062c2017-01-10 20:16:23 -0500578 data.test_plane = DRM_PLANE_TYPE_PRIMARY;
Rodrigo Vivic3524752015-03-13 12:11:54 -0400579 data.op = RENDER;
580 setup_test_plane(&data);
581 igt_assert(wait_psr_entry(&data));
582
583 dpms_off_on(data);
584
585 run_test(&data);
586 test_cleanup(&data);
587 }
588
589 igt_subtest_f("dpms_off_psr_exit") {
Robert Foss934062c2017-01-10 20:16:23 -0500590 data.test_plane = DRM_PLANE_TYPE_OVERLAY;
Rodrigo Vivic3524752015-03-13 12:11:54 -0400591 data.op = PLANE_ONOFF;
592 setup_test_plane(&data);
593
594 dpms_off_on(data);
595
596 igt_assert(wait_psr_entry(&data));
597 run_test(&data);
598 test_cleanup(&data);
599 }
600
Rodrigo Vivi7bd31d02015-11-03 10:02:14 -0800601 igt_subtest_f("suspend_psr_active") {
Robert Foss934062c2017-01-10 20:16:23 -0500602 data.test_plane = DRM_PLANE_TYPE_PRIMARY;
Rodrigo Vivi7bd31d02015-11-03 10:02:14 -0800603 data.op = PAGE_FLIP;
604 setup_test_plane(&data);
605 igt_assert(wait_psr_entry(&data));
606
Imre Deak022e6f82016-09-30 17:28:53 +0300607 igt_system_suspend_autoresume(SUSPEND_STATE_MEM,
608 SUSPEND_TEST_NONE);
Rodrigo Vivi7bd31d02015-11-03 10:02:14 -0800609
610 run_test(&data);
611 test_cleanup(&data);
612 }
613
614 igt_subtest_f("suspend_psr_exit") {
Robert Foss934062c2017-01-10 20:16:23 -0500615 data.test_plane = DRM_PLANE_TYPE_CURSOR;
Rodrigo Vivi7bd31d02015-11-03 10:02:14 -0800616 data.op = PLANE_ONOFF;
617 setup_test_plane(&data);
618
Imre Deak022e6f82016-09-30 17:28:53 +0300619 igt_system_suspend_autoresume(SUSPEND_STATE_MEM,
620 SUSPEND_TEST_NONE);
Rodrigo Vivi7bd31d02015-11-03 10:02:14 -0800621
622 igt_assert(wait_psr_entry(&data));
623 run_test(&data);
624 test_cleanup(&data);
625 }
626
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300627 igt_fixture {
628 drm_intel_bufmgr_destroy(data.bufmgr);
629 display_fini(&data);
630 }
Daniel Vetter3205a912014-09-23 15:15:51 +0200631
632 igt_exit();
Rodrigo Vivi27d37a12014-03-19 22:43:51 -0300633}