Message ID | 20171212020657.2181-1-dhinakaran.pandiyan@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Mon, Dec 11, 2017 at 06:06:57PM -0800, 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. I don't think the frame counter issues are limited to DMC. I expect that the frame counter would stop (at least when we shut off the main link) even on HSW. So I think the test should actually sleep for some suitable long period and make sure the vblank counter has progressed appropriately during that time. Checking the DC and PSR counters around the wait does seem like a good idea. > > 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/kms_psr_sink_crc.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 66 insertions(+) > > 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; > -- > 2.11.0 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
On Tue, 2017-12-12 at 09:10 +0200, Ville Syrjälä wrote: > On Mon, Dec 11, 2017 at 06:06:57PM -0800, 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. > > I don't think the frame counter issues are limited to DMC. I expect that > the frame counter would stop (at least when we shut off the main link) > even on HSW. So I think the test should actually sleep for some > suitable long period and make sure the vblank counter has progressed > appropriately during that time. Yeah, I'd guess the frame counter would be stuck on HSW as opposed to being reset, like on DMC platforms. This patch already tests the vblank count after a delay of 3 seconds on non-DMC platforms. But, I'm not entirely sure if that's enough for the link to turn off, will see if I can find a HSW here. -DK > > Checking the DC and PSR counters around the wait does seem like a > good idea. > > > > > 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/kms_psr_sink_crc.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 66 insertions(+) > > > > 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; > > -- > > 2.11.0 > > > > _______________________________________________ > > Intel-gfx mailing list > > Intel-gfx@lists.freedesktop.org > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx >
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;
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/kms_psr_sink_crc.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+)