summaryrefslogtreecommitdiff
path: root/tests/kms_vrr.c
diff options
context:
space:
mode:
authorBhanuprakash Modem <bhanuprakash.modem@intel.com>2020-09-24 20:18:02 +0530
committerPetri Latvala <petri.latvala@intel.com>2020-10-14 10:22:23 +0300
commit7671d004f4b86d45ae54ee6443b14a18552548bd (patch)
treef43e0878eda30ec9b2ff4a9c121fcaa35f0e275c /tests/kms_vrr.c
parentdff99bb41c5de33e8bb8381f8fe5dbc692f7c24a (diff)
tests/kms_vrr: Add new subtest to validate Flipline mode
Check flipline mode by making sure that flips happen at flipline decision boundary. Example: if monitor vrr range is 40 - 60Hz and * flip at refresh_rate > 60Hz: Flip should happen at the flipline boundary & returned refresh rate would be 60Hz. * flip at refresh_rate == 50Hz: Flip should happen right away so returned refresh rate is 50Hz. * flip at refresh_rate < 40Hz: Flip should happen at the vmax so the returned refresh rate would be 40Hz. v2: * s/*vblank_ns/*event_ns/ (Manasi) * Reset vrr_enabled state before enabling it (Manasi) Cc: Harry Wentland <harry.wentland@amd.com> Cc: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Cc: Manasi Navare <manasi.d.navare@intel.com> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com> Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Reviewed-by: Manasi Navare <manasi.d.navare@intel.com>
Diffstat (limited to 'tests/kms_vrr.c')
-rw-r--r--tests/kms_vrr.c113
1 files changed, 82 insertions, 31 deletions
diff --git a/tests/kms_vrr.c b/tests/kms_vrr.c
index 471d765d..ac42165b 100644
--- a/tests/kms_vrr.c
+++ b/tests/kms_vrr.c
@@ -37,6 +37,7 @@ enum {
TEST_NONE = 0,
TEST_DPMS = 1 << 0,
TEST_SUSPEND = 1 << 1,
+ TEST_FLIPLINE = 1 << 2,
};
typedef struct range {
@@ -52,6 +53,12 @@ typedef struct data {
igt_fb_t fb1;
} data_t;
+typedef struct vtest_ns {
+ uint64_t min;
+ uint64_t mid;
+ uint64_t max;
+} vtest_ns_t;
+
typedef void (*test_t)(data_t*, enum pipe, igt_output_t*, uint32_t);
/* Converts a timespec structure to nanoseconds. */
@@ -104,13 +111,18 @@ static uint64_t rate_from_refresh(uint64_t refresh)
return NSECS_PER_SEC / refresh;
}
-/* Returns the min and max vrr range from the connector debugfs. */
+/* Read min and max vrr range from the connector debugfs.
+ * - min range should be less than the current mode vfreq
+ * - if max range is grater than the current mode vfreq, consider
+ * current mode vfreq as the max range.
+ */
static range_t get_vrr_range(data_t *data, igt_output_t *output)
{
char buf[256];
char *start_loc;
int fd, res;
range_t range;
+ drmModeModeInfo *mode = igt_output_get_mode(output);
fd = igt_debugfs_connector_dir(data->drm_fd, output->name, O_RDONLY);
igt_assert(fd >= 0);
@@ -122,32 +134,28 @@ static range_t get_vrr_range(data_t *data, igt_output_t *output)
igt_assert(start_loc = strstr(buf, "Min: "));
igt_assert_eq(sscanf(start_loc, "Min: %u", &range.min), 1);
+ igt_require(mode->vrefresh > range.min);
igt_assert(start_loc = strstr(buf, "Max: "));
igt_assert_eq(sscanf(start_loc, "Max: %u", &range.max), 1);
+ range.max = (mode->vrefresh < range.max) ? mode->vrefresh : range.max;
+
return range;
}
-/* Returns a suitable vrr test frequency. */
-static uint64_t get_test_rate_ns(data_t *data, igt_output_t *output)
+/* Returns vrr test frequency for min, mid & max range. */
+static vtest_ns_t get_test_rate_ns(data_t *data, igt_output_t *output)
{
- drmModeModeInfo *mode = igt_output_get_mode(output);
range_t range;
- uint64_t vtest;
+ vtest_ns_t vtest_ns;
- /*
- * The frequency with the fastest convergence speed should be
- * the midpoint between the current mode vfreq and the min
- * supported vfreq.
- */
range = get_vrr_range(data, output);
- igt_require(mode->vrefresh > range.min);
-
- vtest = (mode->vrefresh - range.min) / 2 + range.min;
- igt_require(vtest < mode->vrefresh);
+ vtest_ns.min = rate_from_refresh(range.min);
+ vtest_ns.mid = rate_from_refresh(((range.max + range.min) / 2));
+ vtest_ns.max = rate_from_refresh(range.max);
- return rate_from_refresh(vtest);
+ return vtest_ns;
}
/* Returns true if an output supports VRR. */
@@ -195,6 +203,11 @@ static void prepare_test(data_t *data, igt_output_t *output, enum pipe pipe)
data->primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
igt_plane_set_fb(data->primary, &data->fb0);
+ /* Clear vrr_enabled state before enabling it, because
+ * it might be left enabled if the previous test fails.
+ */
+ igt_pipe_set_prop_value(&data->display, pipe, IGT_CRTC_VRR_ENABLED, 0);
+
igt_display_commit_atomic(&data->display,
DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
}
@@ -250,6 +263,7 @@ flip_and_measure(data_t *data, igt_output_t *output, enum pipe pipe,
uint64_t start_ns, last_event_ns;
uint32_t total_flip = 0, total_pass = 0;
bool front = false;
+ vtest_ns_t vtest_ns = get_test_rate_ns(data, output);
/* Align with the vblank region to speed up convergence. */
last_event_ns = wait_for_vblank(data, pipe);
@@ -268,10 +282,6 @@ flip_and_measure(data_t *data, igt_output_t *output, enum pipe pipe,
* that same frame.
*/
event_ns = get_kernel_event_ns(data, DRM_EVENT_FLIP_COMPLETE);
- diff_ns = rate_ns - (event_ns - last_event_ns);
- last_event_ns = event_ns;
-
- total_flip += 1;
/*
* Check if the difference between the two flip timestamps
@@ -281,9 +291,19 @@ flip_and_measure(data_t *data, igt_output_t *output, enum pipe pipe,
* difference between 144Hz and 143Hz which should give this
* enough accuracy for most use cases.
*/
+ if ((rate_ns <= vtest_ns.min) && (rate_ns >= vtest_ns.max))
+ diff_ns = rate_ns - (event_ns - last_event_ns);
+ else if (rate_ns > vtest_ns.min)
+ diff_ns = vtest_ns.min - (event_ns - last_event_ns);
+ else if (rate_ns < vtest_ns.max)
+ diff_ns = vtest_ns.max - (event_ns - last_event_ns);
+
if (llabs(diff_ns) < 50000ll)
total_pass += 1;
+ last_event_ns = event_ns;
+ total_flip += 1;
+
now_ns = get_time_ns();
if (now_ns - start_ns > duration_ns)
break;
@@ -310,10 +330,13 @@ flip_and_measure(data_t *data, igt_output_t *output, enum pipe pipe,
static void
test_basic(data_t *data, enum pipe pipe, igt_output_t *output, uint32_t flags)
{
- uint64_t rate;
uint32_t result;
+ vtest_ns_t vtest_ns = get_test_rate_ns(data, output);
+ range_t range = get_vrr_range(data, output);
+ uint64_t rate = vtest_ns.mid;
- rate = get_test_rate_ns(data, output);
+ igt_info("VRR Test execution on %s, PIPE_%s\n",
+ output->name, kmstest_pipe_name(pipe));
prepare_test(data, output, pipe);
@@ -339,21 +362,45 @@ test_basic(data_t *data, enum pipe pipe, igt_output_t *output, uint32_t flags)
igt_system_suspend_autoresume(SUSPEND_STATE_MEM,
SUSPEND_TEST_NONE);
- result = flip_and_measure(data, output, pipe, rate, TEST_DURATION_NS);
-
- set_vrr_on_pipe(data, pipe, 0);
+ /*
+ * Check flipline mode by making sure that flips happen at flipline
+ * decision boundary.
+ *
+ * Example: if range is 40 - 60Hz and
+ * if refresh_rate > 60Hz:
+ * Flip should happen at the flipline boundary & returned refresh rate
+ * would be 60Hz.
+ * if refresh_rate is 50Hz:
+ * Flip will happen right away so returned refresh rate is 50Hz.
+ * if refresh_rate < 40Hz:
+ * Flip should happen at the vmax so the returned refresh rate
+ * would be 40Hz.
+ */
+ if (flags & TEST_FLIPLINE) {
+ rate = rate_from_refresh(range.min - 5);
+ result = flip_and_measure(data, output, pipe, rate, TEST_DURATION_NS);
+ igt_assert_f(result > 75,
+ "Refresh rate %"PRIu64"ns: Target VRR on threshold not reached, result was %u%%\n",
+ rate, result);
+
+ rate = rate_from_refresh(range.max + 5);
+ result = flip_and_measure(data, output, pipe, rate, TEST_DURATION_NS);
+ igt_assert_f(result > 75,
+ "Refresh rate %"PRIu64"ns: Target VRR on threshold not reached, result was %u%%\n",
+ rate, result);
+ }
- /* This check is delayed until after VRR is disabled so it isn't
- * left enabled if the test fails. */
+ rate = vtest_ns.mid;
+ result = flip_and_measure(data, output, pipe, rate, TEST_DURATION_NS);
igt_assert_f(result > 75,
- "Target VRR on threshold not reached, result was %u%%\n",
- result);
+ "Refresh rate %"PRIu64"ns: Target VRR on threshold not reached, result was %u%%\n",
+ rate, result);
+ set_vrr_on_pipe(data, pipe, 0);
result = flip_and_measure(data, output, pipe, rate, TEST_DURATION_NS);
-
igt_assert_f(result < 10,
- "Target VRR off threshold exceeded, result was %u%%\n",
- result);
+ "Refresh rate %"PRIu64"ns: Target VRR off threshold exceeded, result was %u%%\n",
+ rate, result);
/* Clean-up */
igt_plane_set_fb(data->primary, NULL);
@@ -413,6 +460,10 @@ igt_main
igt_subtest("flip-suspend")
run_vrr_test(&data, test_basic, TEST_SUSPEND);
+ igt_describe("Make sure that flips happen at flipline decision boundary.");
+ igt_subtest("flipline")
+ run_vrr_test(&data, test_basic, TEST_FLIPLINE);
+
igt_fixture {
igt_display_fini(&data.display);
}