@@ -33,8 +33,6 @@
bool running_with_psr_disabled;
-#define CRC_BLACK "000000000000"
-
enum operations {
PAGE_FLIP,
MMAP_GTT,
@@ -64,13 +62,15 @@ static const char *op_str(enum operations op)
typedef struct {
int drm_fd;
+ int debugfs_fd;
+ int crc_fd;
int test_plane;
enum operations op;
uint32_t devid;
uint32_t crtc_id;
igt_display_t display;
drm_intel_bufmgr *bufmgr;
- struct igt_fb fb_green, fb_white;
+ struct igt_fb fb_green, fb_white, fb_blue;
igt_plane_t *primary, *sprite, *cursor;
int mod_size;
int mod_stride;
@@ -98,6 +98,7 @@ static void setup_output(data_t *data)
{
igt_display_t *display = &data->display;
igt_output_t *output;
+ drmModeModeInfoPtr mode = NULL;
enum pipe pipe;
for_each_pipe_with_valid_output(display, pipe, output) {
@@ -106,10 +107,15 @@ static void setup_output(data_t *data)
if (c->connector_type != DRM_MODE_CONNECTOR_eDP)
continue;
+ if (!igt_psr_find_good_mode(c, &mode))
+ continue;
+
+ igt_assert(mode != NULL);
+ igt_output_override_mode(output, mode);
igt_output_set_pipe(output, pipe);
data->crtc_id = output->config.crtc->crtc_id;
data->output = output;
- data->mode = igt_output_get_mode(output);
+ data->mode = &output->override_mode;
return;
}
@@ -119,10 +125,33 @@ static void display_init(data_t *data)
{
igt_display_init(&data->display, data->drm_fd);
setup_output(data);
+
+ /* We need to be able to do a modeset before we enable PSR to
+ * ensure that we are running at a mode such that PSR setup can
+ * complete within a single vblank interval.
+ */
+ igt_debug("Selected mode:\n");
+ kmstest_dump_mode(data->mode);
+ igt_create_color_fb(data->drm_fd,
+ data->mode->hdisplay, data->mode->vdisplay,
+ DRM_FORMAT_XRGB8888,
+ LOCAL_I915_FORMAT_MOD_X_TILED,
+ 0.0, .0, 1.0,
+ &data->fb_blue);
+
+ data->primary = igt_output_get_plane_type(data->output,
+ DRM_PLANE_TYPE_PRIMARY);
+ igt_plane_set_fb(data->primary, &data->fb_blue);
+ igt_display_commit(&data->display);
+ igt_set_module_param_int("enable_psr", running_with_psr_disabled ?
+ 0 : 1);
}
static void display_fini(data_t *data)
{
+ close(data->crc_fd);
+ close(data->debugfs_fd);
+ igt_output_override_mode(data->output, NULL);
igt_display_fini(&data->display);
}
@@ -192,90 +221,59 @@ static void fill_render(data_t *data, uint32_t handle, unsigned char color)
gem_bo_busy(data->drm_fd, handle);
}
-static bool psr_possible(data_t *data)
+static inline bool psr_possible(data_t *data)
{
- char buf[512];
-
- igt_debugfs_read(data->drm_fd, "i915_edp_psr_status", buf);
-
return running_with_psr_disabled ||
- strstr(buf, "Sink_Support: yes\n");
+ igt_psr_sink_support(data->drm_fd);
}
-static bool psr_active(data_t *data)
+static inline bool psr_active(data_t *data)
{
- char buf[512];
-
- igt_debugfs_read(data->drm_fd, "i915_edp_psr_status", buf);
-
return running_with_psr_disabled ||
- strstr(buf, "HW Enabled & Active bit: yes\n");
+ igt_psr_active(data->drm_fd);
}
-static bool wait_psr_entry(data_t *data)
+static inline bool wait_psr_entry(data_t *data)
{
- int timeout = 5;
- while (timeout--) {
- if (psr_active(data))
- return true;
- sleep(1);
- }
- return false;
+ return running_with_psr_disabled ||
+ igt_psr_await_status(data->drm_fd, true);
}
static void get_sink_crc(data_t *data, char *crc) {
- int dir;
+ int rc, tries = 10;
+ memset(crc, 0, 6);
if (igt_interactive_debug)
return;
- dir = igt_debugfs_dir(data->drm_fd);
- igt_require_f(igt_sysfs_scanf(dir, "i915_sink_crc_eDP1", "%s\n", crc),
- "Sink CRC is unreliable on this machine. Try manual debug with --interactive-debug=no-crc\n");
- close(dir);
-
- igt_debug("%s\n", crc);
+ do {
+ rc = igt_psr_get_sink_crc(data->crc_fd, crc);
+ if (rc)
+ usleep(50000);
+ } while (rc && --tries);
+
+ if (rc)
+ igt_skip("Could not get sink CRC after ten tries.\n");
+
+ igt_debug("CRC: %hhx %hhx %hhx %hhx %hhx %hhx\n",
+ crc[0], crc[1], crc[2], crc[3], crc[4], crc[5]);
igt_debug_wait_for_keypress("crc");
/* The important value was already taken.
* Now give a time for human eyes
*/
usleep(300000);
-
- /* Black screen is always invalid */
- igt_assert(strcmp(crc, CRC_BLACK) != 0);
}
static bool is_green(char *crc)
{
- char color_mask[5] = "FFFF\0";
- char rs[5], gs[5], bs[5];
- unsigned int rh, gh, bh, mask;
- int ret;
+ unsigned int rh, gh, bh;
- if (igt_interactive_debug)
- return false;
+ rh = (crc[1] << 8) | crc[0];
+ gh = (crc[3] << 8) | crc[2];
+ bh = (crc[5] << 8) | crc[4];
- sscanf(color_mask, "%4x", &mask);
-
- memcpy(rs, &crc[0], 4);
- rs[4] = '\0';
- ret = sscanf(rs, "%4x", &rh);
- igt_require(ret > 0);
-
- memcpy(gs, &crc[4], 4);
- gs[4] = '\0';
- ret = sscanf(gs, "%4x", &gh);
- igt_require(ret > 0);
-
- memcpy(bs, &crc[8], 4);
- bs[4] = '\0';
- ret = sscanf(bs, "%4x", &bh);
- igt_require(ret > 0);
-
- return ((rh & mask) == 0 &&
- (gh & mask) != 0 &&
- (bh & mask) == 0);
+ return ((rh == 0) && (gh != 0) && (bh == 0));
}
#define assert_or_manual(condition, expected) \
@@ -289,8 +287,8 @@ static void run_test(data_t *data)
uint32_t handle = data->fb_white.gem_handle;
igt_plane_t *test_plane;
void *ptr;
- char ref_crc[12];
- char crc[12];
+ char ref_crc[6];
+ char crc[6];
const char *expected = "";
/* Confirm that screen became Green */
@@ -347,9 +345,9 @@ static void run_test(data_t *data)
memset(ptr, 0xff, data->mod_size);
get_sink_crc(data, crc);
if (data->test_plane == DRM_PLANE_TYPE_PRIMARY)
- assert_or_manual(strcmp(ref_crc, crc) == 0, "screen WHITE");
+ assert_or_manual(memcmp(ref_crc, crc, sizeof(crc)) == 0, "screen WHITE");
else
- assert_or_manual(strcmp(ref_crc, crc) == 0,
+ assert_or_manual(memcmp(ref_crc, crc, sizeof(crc)) == 0,
"GREEN background with WHITE box");
igt_info("Waiting 10s...\n");
@@ -392,7 +390,7 @@ static void run_test(data_t *data)
break;
}
get_sink_crc(data, crc);
- assert_or_manual(strcmp(ref_crc, crc) != 0, expected);
+ assert_or_manual(memcmp(ref_crc, crc, sizeof(crc)) != 0, expected);
}
static void test_cleanup(data_t *data) {
@@ -504,12 +502,11 @@ int main(int argc, char *argv[])
igt_fixture {
data.drm_fd = drm_open_driver_master(DRIVER_INTEL);
+ data.debugfs_fd = igt_debugfs_dir(data.drm_fd);
+ data.crc_fd = igt_psr_open_sink_crc(data.debugfs_fd);
kmstest_set_vt_graphics_mode();
data.devid = intel_get_drm_devid(data.drm_fd);
- igt_set_module_param_int("enable_psr", running_with_psr_disabled ?
- 0 : 1);
-
igt_skip_on(!psr_possible(&data));
data.bufmgr = drm_intel_bufmgr_gem_init(data.drm_fd, 4096);
@@ -517,6 +514,7 @@ int main(int argc, char *argv[])
drm_intel_bufmgr_gem_enable_reuse(data.bufmgr);
display_init(&data);
+ igt_skip_on(!psr_possible(&data));
}
igt_subtest("psr_basic") {
v2: * Minor functional tweaks & bug fixes * Rebase Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Jim Bride <jim.bride@linux.intel.com> --- tests/kms_psr_sink_crc.c | 134 +++++++++++++++++++++++------------------------ 1 file changed, 66 insertions(+), 68 deletions(-)