All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Borah, Chaitanya Kumar" <chaitanya.kumar.borah@intel.com>
To: "Golani,
	Mitulkumar Ajitkumar" <mitulkumar.ajitkumar.golani@intel.com>,
	"Naladala, Ramanaidu" <ramanaidu.naladala@intel.com>,
	"igt-dev@lists.freedesktop.org" <igt-dev@lists.freedesktop.org>
Subject: Re: [PATCH i-g-t v4 2/2] tests/kms_vrr: add CMRR fixed and video mode subtests
Date: Thu, 20 Aug 2026 16:40:59 +0530	[thread overview]
Message-ID: <59150a2c-3219-45bd-861e-c7a01802bc94@intel.com> (raw)
In-Reply-To: <IA1PR11MB63486F731CF5A3EF585F3170B2A52@IA1PR11MB6348.namprd11.prod.outlook.com>



On 8/19/2026 10:30 PM, Golani, Mitulkumar Ajitkumar wrote:
> 
> 
>> -----Original Message-----
>> From: Naladala, Ramanaidu <ramanaidu.naladala@intel.com>
>> Sent: 12 August 2026 18:38
>> To: igt-dev@lists.freedesktop.org
>> Cc: Borah, Chaitanya Kumar <chaitanya.kumar.borah@intel.com>; Golani,
>> Mitulkumar Ajitkumar <mitulkumar.ajitkumar.golani@intel.com>; Naladala,
>> Ramanaidu <ramanaidu.naladala@intel.com>
>> Subject: [PATCH i-g-t v4 2/2] tests/kms_vrr: add CMRR fixed and video mode
>> subtests
>>
>> Add test coverage to validate Content Match Refresh Rate (CMRR) behavior
>> across both fixed and video timing display modes.
>>
>> This introduces a shared helper library to support refresh-rate mode selection
>> and parsing, along with two new test cases covering fixed-mode and video-
>> mode scenarios.
>>
>> The new tests measure actual display refresh timing during CMRR operation
>> and compare it against the expected target rate to verify correctness. Video
>> mode coverage validates behavior across standard video timing rates, while
>> fixed mode coverage targets display modes that fall outside the standard
>> video timing set.
>>
>> Each test cycles through the relevant refresh configurations, applying and
>> resetting the appropriate settings between measurement passes to ensure
>> consistent and isolated test results.
>>
>> v2: Fix test issue.
>> v3: Address review comments. (Mitul)
>> v4: Fix test issue.
>>
>> Signed-off-by: Naladala Ramanaidu <ramanaidu.naladala@intel.com>
>> ---
>>   tests/kms_vrr.c | 204
>> ++++++++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 204 insertions(+)
>>
>> diff --git a/tests/kms_vrr.c b/tests/kms_vrr.c index 27f18e8d0..ab6bc66d9
>> 100644
>> --- a/tests/kms_vrr.c
>> +++ b/tests/kms_vrr.c
>> @@ -32,6 +32,7 @@
>>   #include "igt_pm.h"
>>   #include "igt_psr.h"
>>   #include "i915/intel_drrs.h"
>> +#include "igt_vrr.h"
>>   #include "sw_sync.h"
>>   #include <fcntl.h>
>>   #include <signal.h>
>> @@ -80,6 +81,14 @@
>>    *
>>    * SUBTEST: lobf-dc3co
>>    * Description: Test DC3CO entry during LOBF.
>> + *
>> + * SUBTEST: cmrr-fixed-mode
>> + * Description: Test to set a fixed CMRR target refresh rate and verify it
>> + *              is correctly applied.
>> + *
>> + * SUBTEST: cmrr-video-mode
>> + * Description: Test to set standard video timing refresh rates via CMRR
>> + *              and verify each target rate is correctly applied.
>>    */
>>
>>   #define NSECS_PER_SEC (1000000000ull)
>> @@ -103,6 +112,8 @@ enum {
>>   	TEST_LINK_OFF = 1 << 10,
>>   	TEST_NEGATIVE = 1 << 11,
>>   	TEST_FORCE_RR = 1 << 12,
>> +	TEST_CMRR_FIXED_MODE = 1 << 13,
>> +	TEST_CMRR_VIDEO_MODE = 1 << 14,
>>   };
>>
>>   enum {
>> @@ -580,6 +591,184 @@ flip_and_measure(data_t *data, igt_output_t
>> *output,
>>   	return 0;
>>   }
>>
>> +static
>> +uint64_t wait_next_vblank_ts_ns(data_t *data, igt_crtc_t *crtc) {
>> +	union drm_wait_vblank vbl = {};
>> +
>> +	vbl.request.type = DRM_VBLANK_RELATIVE |
>> igt_crtc_get_vbl_flag(crtc);
>> +	vbl.request.sequence = 1;
>> +	do_or_die(igt_ioctl(data->drm_fd, DRM_IOCTL_WAIT_VBLANK,
>> &vbl));
>> +
>> +	return vbl.reply.tval_sec * NSECS_PER_SEC + vbl.reply.tval_usec *
>> +1000ull; }
>> +
>> +static void
>> +flip_and_measure_target_rr(data_t *data, igt_crtc_t *crtc,
>> +			   double vrefresh, uint32_t cmrr_mode) {
>> +	uint32_t i;
>> +	bool front = false;
>> +	uint64_t last_vblank_ns, vblank_ns;
>> +	uint32_t err_frames = 0;
>> +	uint64_t frame_times_ns[TARGET_RR_SAMP_COUNT];
>> +	uint64_t exp_time_ns;
>> +	uint64_t total_frame_time_ns = 0;
>> +	uint64_t avg_frame_time_ns;
>> +	double  avg_refresh_rate;
>> +	double  expected_rr;
>> +	uint32_t valid_frames = 0;
>> +
>> +	exp_time_ns = igt_kms_frame_time_from_vrefresh(vrefresh);
>> +
>> +	do_flip(data, &data->fb[0]);
>> +	(void)get_kernel_event_ns(data, DRM_EVENT_FLIP_COMPLETE);
>> +	last_vblank_ns = wait_next_vblank_ts_ns(data, crtc);
>> +
>> +	for (i = 0; i < TARGET_RR_SAMP_COUNT; i++) {
>> +		front = !front;
>> +
>> +		do_flip(data, front ? &data->fb[1] : &data->fb[0]);
>> +		vblank_ns = wait_next_vblank_ts_ns(data, crtc);
>> +		(void)get_kernel_event_ns(data,
>> DRM_EVENT_FLIP_COMPLETE);
>> +
>> +		frame_times_ns[i] = vblank_ns - last_vblank_ns;
>> +
>> +		if (frame_times_ns[i] > (exp_time_ns + (exp_time_ns / 2))) {
>> +			err_frames++;
>> +			last_vblank_ns = vblank_ns;
>> +			continue;
>> +		}
>> +
>> +		last_vblank_ns = vblank_ns;
>> +		total_frame_time_ns += frame_times_ns[i];
>> +	}
>> +
>> +	valid_frames = TARGET_RR_SAMP_COUNT - err_frames;
>> +	igt_assert_f(valid_frames > 0,
>> +		     "No valid frame samples collected\n");
>> +
>> +	avg_frame_time_ns = total_frame_time_ns / valid_frames;
>> +	avg_refresh_rate = (double)NSECS_PER_SEC /
>> (double)avg_frame_time_ns;
>> +
>> +	if (cmrr_mode == CMRR_VIDEO_MODE) {
>> +		expected_rr = (double)(vrefresh * CMRR_NUMERATOR) /
>> +			      (double)CMRR_VIDEO_MODE_DENOMINATOR;
>> +		igt_assert_f(fabs(avg_refresh_rate - expected_rr) <= 0.02,
> 
> Please confirm this bound holds on real hardware, or justify it.
> 
>> +			     "CMRR refresh rate mismatch: "
>> +			     "measured avg_rr = %.3f Hz, "
>> +			     "expected_rr = %.3f Hz\n",
>> +			     avg_refresh_rate, expected_rr);
>> +	}
>> +
>> +	if (cmrr_mode == CMRR_NON_VIDEO_MODE) {
>> +		expected_rr = (double)(vrefresh * CMRR_NUMERATOR) /
>> +			      (double)CMRR_DENOMINATOR;
>> +		igt_assert_f(fabs(avg_refresh_rate - expected_rr) <= 0.02,
>> +			     "CMRR refresh rate mismatch: "
>> +			     "measured avg_rr = %.3f Hz, "
>> +			     "expected_rr = %.3f Hz\n",
>> +			     avg_refresh_rate, expected_rr);
>> +	}
>> +
>> +	if (cmrr_mode == CMRR_DISABLE) {
>> +		expected_rr = vrefresh;
>> +		igt_assert_f(fabs(avg_refresh_rate - expected_rr) <= 0.02,
>> +			     "CMRR refresh rate mismatch: "
>> +			     "measured avg_rr = %.3f Hz, "
>> +			     "expected_rr = %.3f Hz\n",
>> +			     avg_refresh_rate, expected_rr);
>> +	}
>> +
>> +	igt_info("Average RR (Hz): %.2f , Expected RR (Hz): %.2f, error frames
>> = %d\n",
>> +		 avg_refresh_rate, expected_rr, err_frames); }
>> +
>> +static
>> +void test_cmrr(data_t *data, igt_crtc_t *crtc,
>> +	       igt_output_t *output, uint32_t flags) {
>> +	uint32_t found;
>> +	double rr_from_mode;
>> +	drmModeModeInfo mode;
>> +	drmModeConnectorPtr connector;
>> +	int j;
>> +
>> +	igt_require_f(cmrr_supported(data->drm_fd, crtc->crtc_index),
>> +		      "CMRR not supported\n");
>> +	prepare_test(data, output, crtc);
>> +	set_vrr_on_crtc(data, crtc, true, false);
>> +
>> +	if (flags & TEST_CMRR_VIDEO_MODE) {
>> +		for (j = 0; j < igt_vrr_standard_video_timing_fps_count; j++) {
> 
> compares int against size_t, Use size_t j (or unsigned).
> 
>> +			found =
>> igt_vrr_get_mode_with_video_timing(output,
>> +
>> 	igt_vrr_standard_video_timing_fps[j],
>> +							&mode);
>> +			if (found) {
>> +				rr_from_mode =
>> igt_vrr_mode_line_refresh_hz(&mode);
>> +				igt_output_override_mode(output, &mode);
>> +				igt_info("Override mode:");
>> +				kmstest_dump_mode(&mode);
>> +				igt_display_commit2(&data->display,
>> COMMIT_ATOMIC);
>> +				igt_target_rr_debugfs_write(data->drm_fd,
>> +							    crtc->crtc_index,
>> +							    mode.vrefresh,
>> +
>> CMRR_NUMERATOR,
>> +
>> CMRR_VIDEO_MODE_DENOMINATOR);
>> +
>> +				flip_and_measure_target_rr(data, crtc,
>> +							   mode.vrefresh,
>> +
>> CMRR_VIDEO_MODE);
>> +
>> +				igt_target_rr_debugfs_write(data->drm_fd,
>> +							    crtc->crtc_index,
>> +							    mode.vrefresh,
>> +							    0, 0);
>> +
>> +				flip_and_measure_target_rr(data, crtc,
>> +							   rr_from_mode,
>> +							   CMRR_DISABLE);
>> +			}
>> +		}
>> +	}
> 
> The TEST_CMRR_VIDEO_MODE loop reassigns found every iteration, so after the loop it only reflects the last fps in the array,
> which typically has no matching mode.
> 
> Two issues:
> 1. there is no post-loop guard, so on a panel with no standard-timing mode the
> subtest passes without testing anything, it should igt_require a skip instead;
> 2. you can't reuse found like below fixed-mode branch does, because here it's overwritten rather than latched,
> requiring on it would falsely skip even when earlier rates were tested.
> 
> Please add a dedicated "bool tested" latch set inside if (found) and igt_require_f(tested, "No standard video-timing mode found.\n") after the loop.
> 
> "bool tested = false;
> ...
>      if (found) {
>          tested = true;
>          ...
>      }
> ...
> igt_require_f(tested, "No standard video-timing mode found.\n");"
> 

Or just.

  if (igt_vrr_get_mode_with_video_timing(output,
                         igt_vrr_standard_video_timing_fps[j], &mode)) {
             found = true;

>> +
>> +	if (flags & TEST_CMRR_FIXED_MODE) {
>> +		found = 0;
>> +		connector = output->config.connector;
>> +		for (j = 0; j < connector->count_modes; j++) {
>> +			mode = connector->modes[j];
>> +			rr_from_mode =
>> igt_vrr_mode_line_refresh_hz(&mode);
>> +
>> +			if (rr_from_mode - mode.vrefresh > 0.04) {
>> +				found = 1;
>> +				igt_output_override_mode(output, &mode);
>> +				igt_info("Override mode:");
>> +				kmstest_dump_mode(&mode);
>> +				igt_display_commit2(&data->display,
>> COMMIT_ATOMIC);
>> +				igt_target_rr_debugfs_write(data->drm_fd,
>> +							    crtc->crtc_index,
>> +							    mode.vrefresh,
>> +
>> CMRR_NUMERATOR,
>> +
>> CMRR_DENOMINATOR);
>> +
>> +				flip_and_measure_target_rr(data, crtc,
>> +							   mode.vrefresh,
>> +
>> CMRR_NON_VIDEO_MODE);
>> +
>> +				igt_target_rr_debugfs_write(data->drm_fd,
>> +							    crtc->crtc_index,
>> +							    mode.vrefresh,
>> +							    0, 0);
>> +
>> +				flip_and_measure_target_rr(data, crtc,
>> +							   rr_from_mode,
>> +							   CMRR_DISABLE);
>> +			}
>> +		}
>> +		igt_require_f(found, "No non-video-timing mode found.\n");
>> +	}
>> +}
>> +
>>   /* Basic VRR flip functionality test - enable, measure, disable, measure */
>> static void  test_basic(data_t *data, igt_crtc_t *crtc, igt_output_t *output, @@
>> -591,6 +780,7 @@ test_basic(data_t *data, igt_crtc_t *crtc, igt_output_t
>> *output,
>>   	uint64_t rate[] = {0};
>>
>>   	prepare_test(data, output, crtc);
>> +
> 
> 	Please remove extra line.
> 
>>   	range = data->range;
>>   	vtest_ns = data->vtest_ns;
>>   	rate[0] = vtest_ns.rate_ns;
>> @@ -1147,6 +1337,20 @@ int igt_main_args("drs:", long_opts, help_str,
>> opt_handler, &data)
>>   		}
>>   	}
>>
>> +	igt_subtest_group() {
>> +		igt_fixture()
>> +			igt_require_intel(data.drm_fd);
>> +
>> +		igt_describe("Test to validate CMRR in fixed mode.");
>> +		igt_subtest_with_dynamic("cmrr-fixed-mode") {
>> +			run_vrr_test(&data, test_cmrr,
>> TEST_CMRR_FIXED_MODE);
>> +		}
>> +
>> +		igt_describe("Test to validate CMRR in video mode.");
>> +		igt_subtest_with_dynamic("cmrr-video-mode") {
>> +			run_vrr_test(&data, test_cmrr,
>> TEST_CMRR_VIDEO_MODE);
>> +		}
>> +	}
>>   	igt_fixture() {
>>   		close(data.debugfs_fd);
>>   		igt_display_fini(&data.display);
>> --
>> 2.43.0
> 


  reply	other threads:[~2026-08-20 11:11 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-12 13:07 [PATCH i-g-t v4 0/2] Add CMRR subtests Naladala Ramanaidu
2026-08-12 13:07 ` [PATCH i-g-t v4 1/2] lib/igt_vrr:Add VRR helper library for display refresh rate testing Naladala Ramanaidu
2026-08-19 16:03   ` Golani, Mitulkumar Ajitkumar
2026-08-20 11:08   ` Borah, Chaitanya Kumar
2026-08-12 13:07 ` [PATCH i-g-t v4 2/2] tests/kms_vrr: add CMRR fixed and video mode subtests Naladala Ramanaidu
2026-08-19 17:00   ` Golani, Mitulkumar Ajitkumar
2026-08-20 11:10     ` Borah, Chaitanya Kumar [this message]
2026-08-20 11:10   ` Borah, Chaitanya Kumar
2026-08-12 14:12 ` ✓ i915.CI.BAT: success for Add CMRR subtests (rev4) Patchwork
2026-08-12 14:14 ` ✓ Xe.CI.BAT: " Patchwork
2026-08-12 17:49 ` ✗ Xe.CI.FULL: failure " Patchwork
2026-08-12 18:01 ` ✗ i915.CI.Full: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=59150a2c-3219-45bd-861e-c7a01802bc94@intel.com \
    --to=chaitanya.kumar.borah@intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=mitulkumar.ajitkumar.golani@intel.com \
    --cc=ramanaidu.naladala@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.