diff mbox

[i-g-t,v2,CI] tests/psr: Test vblank continuity with PSR enabled

Message ID 20171213192345.5558-1-dhinakaran.pandiyan@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Dhinakaran Pandiyan Dec. 13, 2017, 7:23 p.m. UTC
PSR allows DMC to put the system to low power states when active, but
this can reset the frame counter on some platforms. The frame counter reset
leads to a negative diff applied to vblank count. This subtest checks
for that.

v2: Some optimizations and data type changes.
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
---
 tests/intel-ci/fast-feedback.testlist |  1 +
 tests/kms_psr_sink_crc.c              | 66 +++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

Comments

Rodrigo Vivi Dec. 19, 2017, 9:54 p.m. UTC | #1
On Wed, Dec 13, 2017 at 07:23:45PM +0000, Dhinakaran Pandiyan wrote:
> PSR allows DMC to put the system to low power states when active, but
> this can reset the frame counter on some platforms. The frame counter reset
> leads to a negative diff applied to vblank count. This subtest checks
> for that.
> 
> v2: Some optimizations and data type changes.
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> ---
>  tests/intel-ci/fast-feedback.testlist |  1 +
>  tests/kms_psr_sink_crc.c              | 66 +++++++++++++++++++++++++++++++++++
>  2 files changed, 67 insertions(+)
> 
> diff --git a/tests/intel-ci/fast-feedback.testlist b/tests/intel-ci/fast-feedback.testlist
> index f71a16bc..72338b72 100644
> --- a/tests/intel-ci/fast-feedback.testlist
> +++ b/tests/intel-ci/fast-feedback.testlist
> @@ -247,6 +247,7 @@ igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a
>  igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b
>  igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c
>  igt@kms_psr_sink_crc@psr_basic
> +igt@kms_psr_sink_crc@vblank

just a note that we need ack from CI devs
specially because it introduces some sleeps/waits below

>  igt@kms_setmode@basic-clone-single-crtc
>  igt@kms_sink_crc_basic
>  igt@pm_backlight@basic-brightness
> diff --git a/tests/kms_psr_sink_crc.c b/tests/kms_psr_sink_crc.c
> index 83a69f0b..831368b2 100644
> --- a/tests/kms_psr_sink_crc.c
> +++ b/tests/kms_psr_sink_crc.c
> @@ -69,6 +69,7 @@ typedef struct {
>  	enum operations op;
>  	uint32_t devid;
>  	uint32_t crtc_id;
> +	enum pipe pipe;
>  	igt_display_t display;
>  	drm_intel_bufmgr *bufmgr;
>  	struct igt_fb fb_green, fb_white;
> @@ -107,6 +108,7 @@ static void setup_output(data_t *data)
>  		if (c->connector_type != DRM_MODE_CONNECTOR_eDP)
>  			continue;
>  
> +		data->pipe = pipe;
>  		igt_output_set_pipe(output, pipe);
>  		data->crtc_id = output->config.crtc->crtc_id;
>  		data->output = output;
> @@ -285,6 +287,63 @@ static void assert_or_manual(bool condition, const char *expected)
>  	igt_assert(igt_interactive_debug || condition);
>  }
>  
> +static unsigned int get_vblank(int fd, unsigned int pipe)
> +{
> +	union drm_wait_vblank vbl;
> +
> +	memset(&vbl, 0, sizeof(vbl));
> +	vbl.request.type = DRM_VBLANK_RELATIVE | kmstest_get_vbl_flag(pipe);
> +	igt_ioctl(fd, DRM_IOCTL_WAIT_VBLANK, &vbl);
> +
> +	return vbl.reply.sequence;
> +}
> +
> +static void dmc_read_counts(unsigned int fd, unsigned int *count)
> +{
> +	char buf[512];
> +
> +	igt_debugfs_read(fd, "i915_dmc_info", buf);
> +	igt_assert_eq(sscanf(strstr(buf, "DC3 -> DC5"), "DC3 -> DC5 count: %u", &count[0]),
> +		      1);
> +	igt_assert_eq(sscanf(strstr(buf, "DC5 -> DC6"), "DC5 -> DC6 count: %u", &count[1]),
> +		      1);

we already have platforms where this counter doesn't exist. We might have platforms
where even DC3_TO_DC5 is not present or not reliable :/

> +	igt_debug("DC3->DC5 count=%u, DC5->DC6 count=%u\n", count[0], count[1]);
> +}
> +
> +static void check_vblanks(data_t *data)
> +{
> +	unsigned int first_vbl, second_vbl;
> +	int wait = 30; /* Takes about 2.5 seconds for DC_OFF disable */
> +	char buf[512];
> +	bool has_dmc;
> +
> +	first_vbl = get_vblank(data->drm_fd, data->pipe);
> +
> +	igt_debugfs_read(data->drm_fd, "i915_dmc_info", buf);
> +	has_dmc = strstr(buf, "fw loaded: yes");
> +
> +	if (has_dmc) {
> +		unsigned int new_dc[2], old_dc[2];
> +
> +		dmc_read_counts(data->drm_fd, new_dc);
> +		do {
> +			memcpy(old_dc, new_dc, sizeof(new_dc));
> +			usleep(100 * 1000);
> +			dmc_read_counts(data->drm_fd, new_dc);
> +		} while (!memcmp(old_dc, new_dc, sizeof(new_dc)) && --wait);
> +
> +		igt_assert_f(wait, "Timed out waiting for DC state transition 3s.\n");
> +	} else {
> +		sleep(3);
> +	}
> +
> +	second_vbl = get_vblank(data->drm_fd, data->pipe);
> +	igt_debug("vblank count went from %u to %u in %d ms.\n",
> +		  first_vbl, second_vbl, has_dmc ? (30 - wait) * 100 : 3000);
> +
> +	igt_assert_lt(first_vbl, second_vbl);
> +}
> +
>  static bool drrs_disabled(data_t *data)
>  {
>  	char buf[512];
> @@ -572,6 +631,13 @@ int main(int argc, char *argv[])
>  		}
>  	}
>  
> +	igt_subtest("vblank") {
> +		setup_test_plane(&data);
> +		igt_assert(wait_psr_entry(&data));
> +		check_vblanks(&data);
> +		test_cleanup(&data);
> +	}
> +
>  	igt_subtest_f("dpms_off_psr_active") {
>  		data.test_plane = DRM_PLANE_TYPE_PRIMARY;
>  		data.op = RENDER;
> -- 
> 2.11.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Dhinakaran Pandiyan Dec. 19, 2017, 10:02 p.m. UTC | #2
On Tue, 2017-12-19 at 13:54 -0800, Rodrigo Vivi wrote:
> On Wed, Dec 13, 2017 at 07:23:45PM +0000, Dhinakaran Pandiyan wrote:

> > PSR allows DMC to put the system to low power states when active, but

> > this can reset the frame counter on some platforms. The frame counter reset

> > leads to a negative diff applied to vblank count. This subtest checks

> > for that.

> > 

> > v2: Some optimizations and data type changes.

> > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>

> > Cc: Daniel Vetter <daniel.vetter@ffwll.ch>

> > Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>

> > ---

> >  tests/intel-ci/fast-feedback.testlist |  1 +

> >  tests/kms_psr_sink_crc.c              | 66 +++++++++++++++++++++++++++++++++++

> >  2 files changed, 67 insertions(+)

> > 

> > diff --git a/tests/intel-ci/fast-feedback.testlist b/tests/intel-ci/fast-feedback.testlist

> > index f71a16bc..72338b72 100644

> > --- a/tests/intel-ci/fast-feedback.testlist

> > +++ b/tests/intel-ci/fast-feedback.testlist

> > @@ -247,6 +247,7 @@ igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a

> >  igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b

> >  igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c

> >  igt@kms_psr_sink_crc@psr_basic

> > +igt@kms_psr_sink_crc@vblank

> 

> just a note that we need ack from CI devs

> specially because it introduces some sleeps/waits below

> 

> >  igt@kms_setmode@basic-clone-single-crtc

> >  igt@kms_sink_crc_basic

> >  igt@pm_backlight@basic-brightness

> > diff --git a/tests/kms_psr_sink_crc.c b/tests/kms_psr_sink_crc.c

> > index 83a69f0b..831368b2 100644

> > --- a/tests/kms_psr_sink_crc.c

> > +++ b/tests/kms_psr_sink_crc.c

> > @@ -69,6 +69,7 @@ typedef struct {

> >  	enum operations op;

> >  	uint32_t devid;

> >  	uint32_t crtc_id;

> > +	enum pipe pipe;

> >  	igt_display_t display;

> >  	drm_intel_bufmgr *bufmgr;

> >  	struct igt_fb fb_green, fb_white;

> > @@ -107,6 +108,7 @@ static void setup_output(data_t *data)

> >  		if (c->connector_type != DRM_MODE_CONNECTOR_eDP)

> >  			continue;

> >  

> > +		data->pipe = pipe;

> >  		igt_output_set_pipe(output, pipe);

> >  		data->crtc_id = output->config.crtc->crtc_id;

> >  		data->output = output;

> > @@ -285,6 +287,63 @@ static void assert_or_manual(bool condition, const char *expected)

> >  	igt_assert(igt_interactive_debug || condition);

> >  }

> >  

> > +static unsigned int get_vblank(int fd, unsigned int pipe)

> > +{

> > +	union drm_wait_vblank vbl;

> > +

> > +	memset(&vbl, 0, sizeof(vbl));

> > +	vbl.request.type = DRM_VBLANK_RELATIVE | kmstest_get_vbl_flag(pipe);

> > +	igt_ioctl(fd, DRM_IOCTL_WAIT_VBLANK, &vbl);

> > +

> > +	return vbl.reply.sequence;

> > +}

> > +

> > +static void dmc_read_counts(unsigned int fd, unsigned int *count)

> > +{

> > +	char buf[512];

> > +

> > +	igt_debugfs_read(fd, "i915_dmc_info", buf);

> > +	igt_assert_eq(sscanf(strstr(buf, "DC3 -> DC5"), "DC3 -> DC5 count: %u", &count[0]),

> > +		      1);

> > +	igt_assert_eq(sscanf(strstr(buf, "DC5 -> DC6"), "DC5 -> DC6 count: %u", &count[1]),

> > +		      1);

> 

> we already have platforms where this counter doesn't exist. We might have platforms

> where even DC3_TO_DC5 is not present or not reliable :/


I can check that the dc_off refcount has gone to zero (from
i915_power_domain_info) and then add a small delay after that.

> 

> > +	igt_debug("DC3->DC5 count=%u, DC5->DC6 count=%u\n", count[0], count[1]);

> > +}

> > +

> > +static void check_vblanks(data_t *data)

> > +{

> > +	unsigned int first_vbl, second_vbl;

> > +	int wait = 30; /* Takes about 2.5 seconds for DC_OFF disable */

> > +	char buf[512];

> > +	bool has_dmc;

> > +

> > +	first_vbl = get_vblank(data->drm_fd, data->pipe);

> > +

> > +	igt_debugfs_read(data->drm_fd, "i915_dmc_info", buf);

> > +	has_dmc = strstr(buf, "fw loaded: yes");

> > +

> > +	if (has_dmc) {

> > +		unsigned int new_dc[2], old_dc[2];

> > +

> > +		dmc_read_counts(data->drm_fd, new_dc);

> > +		do {

> > +			memcpy(old_dc, new_dc, sizeof(new_dc));

> > +			usleep(100 * 1000);

> > +			dmc_read_counts(data->drm_fd, new_dc);

> > +		} while (!memcmp(old_dc, new_dc, sizeof(new_dc)) && --wait);

> > +

> > +		igt_assert_f(wait, "Timed out waiting for DC state transition 3s.\n");

> > +	} else {

> > +		sleep(3);

> > +	}

> > +

> > +	second_vbl = get_vblank(data->drm_fd, data->pipe);

> > +	igt_debug("vblank count went from %u to %u in %d ms.\n",

> > +		  first_vbl, second_vbl, has_dmc ? (30 - wait) * 100 : 3000);

> > +

> > +	igt_assert_lt(first_vbl, second_vbl);

> > +}

> > +

> >  static bool drrs_disabled(data_t *data)

> >  {

> >  	char buf[512];

> > @@ -572,6 +631,13 @@ int main(int argc, char *argv[])

> >  		}

> >  	}

> >  

> > +	igt_subtest("vblank") {

> > +		setup_test_plane(&data);

> > +		igt_assert(wait_psr_entry(&data));

> > +		check_vblanks(&data);

> > +		test_cleanup(&data);

> > +	}

> > +

> >  	igt_subtest_f("dpms_off_psr_active") {

> >  		data.test_plane = DRM_PLANE_TYPE_PRIMARY;

> >  		data.op = RENDER;

> > -- 

> > 2.11.0

> > 

> > _______________________________________________

> > Intel-gfx mailing list

> > Intel-gfx@lists.freedesktop.org

> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
diff mbox

Patch

diff --git a/tests/intel-ci/fast-feedback.testlist b/tests/intel-ci/fast-feedback.testlist
index f71a16bc..72338b72 100644
--- a/tests/intel-ci/fast-feedback.testlist
+++ b/tests/intel-ci/fast-feedback.testlist
@@ -247,6 +247,7 @@  igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a
 igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b
 igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c
 igt@kms_psr_sink_crc@psr_basic
+igt@kms_psr_sink_crc@vblank
 igt@kms_setmode@basic-clone-single-crtc
 igt@kms_sink_crc_basic
 igt@pm_backlight@basic-brightness
diff --git a/tests/kms_psr_sink_crc.c b/tests/kms_psr_sink_crc.c
index 83a69f0b..831368b2 100644
--- a/tests/kms_psr_sink_crc.c
+++ b/tests/kms_psr_sink_crc.c
@@ -69,6 +69,7 @@  typedef struct {
 	enum operations op;
 	uint32_t devid;
 	uint32_t crtc_id;
+	enum pipe pipe;
 	igt_display_t display;
 	drm_intel_bufmgr *bufmgr;
 	struct igt_fb fb_green, fb_white;
@@ -107,6 +108,7 @@  static void setup_output(data_t *data)
 		if (c->connector_type != DRM_MODE_CONNECTOR_eDP)
 			continue;
 
+		data->pipe = pipe;
 		igt_output_set_pipe(output, pipe);
 		data->crtc_id = output->config.crtc->crtc_id;
 		data->output = output;
@@ -285,6 +287,63 @@  static void assert_or_manual(bool condition, const char *expected)
 	igt_assert(igt_interactive_debug || condition);
 }
 
+static unsigned int get_vblank(int fd, unsigned int pipe)
+{
+	union drm_wait_vblank vbl;
+
+	memset(&vbl, 0, sizeof(vbl));
+	vbl.request.type = DRM_VBLANK_RELATIVE | kmstest_get_vbl_flag(pipe);
+	igt_ioctl(fd, DRM_IOCTL_WAIT_VBLANK, &vbl);
+
+	return vbl.reply.sequence;
+}
+
+static void dmc_read_counts(unsigned int fd, unsigned int *count)
+{
+	char buf[512];
+
+	igt_debugfs_read(fd, "i915_dmc_info", buf);
+	igt_assert_eq(sscanf(strstr(buf, "DC3 -> DC5"), "DC3 -> DC5 count: %u", &count[0]),
+		      1);
+	igt_assert_eq(sscanf(strstr(buf, "DC5 -> DC6"), "DC5 -> DC6 count: %u", &count[1]),
+		      1);
+	igt_debug("DC3->DC5 count=%u, DC5->DC6 count=%u\n", count[0], count[1]);
+}
+
+static void check_vblanks(data_t *data)
+{
+	unsigned int first_vbl, second_vbl;
+	int wait = 30; /* Takes about 2.5 seconds for DC_OFF disable */
+	char buf[512];
+	bool has_dmc;
+
+	first_vbl = get_vblank(data->drm_fd, data->pipe);
+
+	igt_debugfs_read(data->drm_fd, "i915_dmc_info", buf);
+	has_dmc = strstr(buf, "fw loaded: yes");
+
+	if (has_dmc) {
+		unsigned int new_dc[2], old_dc[2];
+
+		dmc_read_counts(data->drm_fd, new_dc);
+		do {
+			memcpy(old_dc, new_dc, sizeof(new_dc));
+			usleep(100 * 1000);
+			dmc_read_counts(data->drm_fd, new_dc);
+		} while (!memcmp(old_dc, new_dc, sizeof(new_dc)) && --wait);
+
+		igt_assert_f(wait, "Timed out waiting for DC state transition 3s.\n");
+	} else {
+		sleep(3);
+	}
+
+	second_vbl = get_vblank(data->drm_fd, data->pipe);
+	igt_debug("vblank count went from %u to %u in %d ms.\n",
+		  first_vbl, second_vbl, has_dmc ? (30 - wait) * 100 : 3000);
+
+	igt_assert_lt(first_vbl, second_vbl);
+}
+
 static bool drrs_disabled(data_t *data)
 {
 	char buf[512];
@@ -572,6 +631,13 @@  int main(int argc, char *argv[])
 		}
 	}
 
+	igt_subtest("vblank") {
+		setup_test_plane(&data);
+		igt_assert(wait_psr_entry(&data));
+		check_vblanks(&data);
+		test_cleanup(&data);
+	}
+
 	igt_subtest_f("dpms_off_psr_active") {
 		data.test_plane = DRM_PLANE_TYPE_PRIMARY;
 		data.op = RENDER;