Igt-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Naladala, Ramanaidu" <Ramanaidu.naladala@intel.com>
To: "Borah, Chaitanya Kumar" <chaitanya.kumar.borah@intel.com>,
	<igt-dev@lists.freedesktop.org>
Cc: <mitulkumar.ajitkumar.golani@intel.com>, <karthik.b.s@intel.com>
Subject: Re: [PATCH i-g-t v6 3/3] tests/kms_vrr: Add CMRR fixed and video mode subtests
Date: Sun, 13 Sep 2026 01:22:16 +0530	[thread overview]
Message-ID: <c24dd279-531a-4f9a-b3f1-d13bfd65fca5@intel.com> (raw)
In-Reply-To: <e7bc3094-7254-4482-a17b-de4487b1cdf4@intel.com>

[-- Attachment #1: Type: text/plain, Size: 14047 bytes --]

Hi Chitanya,

On 9/10/2026 3:55 PM, Borah, Chaitanya Kumar wrote:
>
>
> On 9/7/2026 11:18 PM, Naladala Ramanaidu wrote:
>> 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.
>> v5: Address below review comments:
>>      - Rename CMRR fixed/non-video mode references to desktop
>>        mode. (Chaitanya)
>>      - Factor out vblank timestamp/sequence retrieval into
>>        helper. (Chaitanya)
>>      - Simplify CMRR tests by extracting common mode logic. (Chaitanya,
>>        Mitul)
>>      - Refactor CMRR refresh-rate verification and frame filtering.
>> v6: Address below review comments:
>>      - Document skipped vblank intervals and fix seq_delta
>>        format. (Chaitanya)
>>      - Fix minor style issues in CMRR tests. (Chaitanya, Mitul)
>>      - Add mode existence checks for CMRR test paths. (Chaitanya)
>>
>> Assisted-by: GitHub Copilot:Claude Opus 4.6
>> Signed-off-by: Naladala Ramanaidu <ramanaidu.naladala@intel.com>
>> ---
>>   tests/kms_vrr.c | 240 ++++++++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 240 insertions(+)
>>
>> diff --git a/tests/kms_vrr.c b/tests/kms_vrr.c
>> index 27f18e8d0..109b4629d 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,9 +81,22 @@
>>    *
>>    * SUBTEST: lobf-dc3co
>>    * Description: Test DC3CO entry during LOBF.
>> + *
>> + * SUBTEST: cmrr-desktop-mode
>> + * Description: Test to set a desktop mode 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)
>> +#define CMRR_NUMERATOR 1000ULL
>> +#define CMRR_DENOMINATOR 1000ULL
>> +#define CMRR_VIDEO_MODE_DENOMINATOR 1001ULL
>> +#define TARGET_RR_SAMP_COUNT 100
>> +#define CMRR_RR_TOLERANCE_HZ 0.02
>>     /*
>>    * Each test measurement step runs for ~5 seconds.
>> @@ -103,6 +117,14 @@ enum {
>>       TEST_LINK_OFF = 1 << 10,
>>       TEST_NEGATIVE = 1 << 11,
>>       TEST_FORCE_RR = 1 << 12,
>> +    TEST_CMRR_DESKTOP_MODE = 1 << 13,
>> +    TEST_CMRR_VIDEO_MODE = 1 << 14,
>> +};
>> +
>> +enum {
>> +    CMRR_VIDEO_MODE,
>> +    CMRR_DESKTOP_MODE,
>> +    CMRR_DISABLE,
>>   };
>>     enum {
>> @@ -221,6 +243,38 @@ output_mode_with_maxrate(igt_output_t *output, 
>> unsigned int vrr_max)
>>       return mode;
>>   }
>>   +/**
>> + * get_mode_with_video_timing:
>> + * @output: Display output containing connector mode list
>> + * @fps: Requested integer refresh rate in Hz
>> + * @matched_mode: Returned mode that matches @fps
>> + *
>> + * Find and return a connector mode that matches the requested
>> + * video timing refresh rate in Hz.
>> + *
>> + * Returns: true when a mode is found, false otherwise
>> + */
>> +
>> +static bool
>> +get_mode_with_video_timing(igt_output_t *output, uint32_t fps,
>> +               drmModeModeInfo *matched_mode)
>> +{
>> +    drmModeConnectorPtr connector;
>> +
>> +    connector = output->config.connector;
>> +    if (!connector)
>> +        return false;
>> +
>> +    for (int i = 0; i < connector->count_modes; i++) {
>> +        if (connector->modes[i].vrefresh == fps) {
>> +            *matched_mode = connector->modes[i];
>> +            return true;
>> +        }
>> +    }
>> +
>> +    return false;
>> +}
>> +
>>   static drmModeModeInfo
>>   low_rr_mode_with_same_res(igt_output_t *output, unsigned int vrr_min)
>>   {
>> @@ -580,6 +634,177 @@ flip_and_measure(data_t *data, igt_output_t 
>> *output,
>>       return 0;
>>   }
>>   +/* Measure and verify the effective refresh rate against the 
>> expected CMRR target rate. */
>> +static void
>> +flip_and_measure_target_rr(data_t *data, igt_crtc_t *crtc,
>> +               double vrefresh, uint32_t cmrr_mode)
>> +{
>> +    uint64_t last_vblank_ns, vblank_ns, frame_time_ns;
>> +    uint64_t total_frame_time_ns = 0;
>> +    uint32_t last_seq, seq, seq_delta;
>> +    uint32_t err_frames = 0, valid_frames;
>> +    double avg_frame_time_ns, avg_refresh_rate;
>> +    double  expected_rr = 0;
>
> double space.
>
>> +    bool front = false;
>> +    uint32_t i;
>> +
>> +    switch (cmrr_mode) {
>> +    case CMRR_VIDEO_MODE:
>> +        expected_rr = (vrefresh * CMRR_NUMERATOR) /
>> +                  (double)CMRR_VIDEO_MODE_DENOMINATOR;
>> +        break;
>> +    case CMRR_DESKTOP_MODE:
>> +        expected_rr = (vrefresh * CMRR_NUMERATOR) /
>> +                  (double)CMRR_DENOMINATOR;
>> +        break;
>> +    case CMRR_DISABLE:
>> +        expected_rr = vrefresh;
>> +        break;
>> +    default:
>> +        igt_assert_f(0, "Invalid CMRR mode %u\n", cmrr_mode);
>> +    }
>> +
>> +    do_flip(data, &data->fb[0]);
>> +    (void)get_kernel_event_ns(data, DRM_EVENT_FLIP_COMPLETE);
>> +    igt_wait_for_vblank_ts_seq(crtc, &last_vblank_ns, &last_seq);
>> +
>> +    for (i = 0; i < TARGET_RR_SAMP_COUNT; i++) {
>> +        front = !front;
>> +
>> +        do_flip(data, front ? &data->fb[1] : &data->fb[0]);
>> +        igt_wait_for_vblank_ts_seq(crtc, &vblank_ns, &seq);
>> +        (void)get_kernel_event_ns(data, DRM_EVENT_FLIP_COMPLETE);
>> +
>> +        frame_time_ns = vblank_ns - last_vblank_ns;
>> +        seq_delta = seq - last_seq;
>> +
>> +        last_vblank_ns = vblank_ns;
>> +        last_seq = seq;
>> +
>> +        /*
>> +         * Use only single-frame intervals. If delta > 1, one or
>> +         * more vblanks were missed, so the interval is not valid
>> +         * for calculating the average frame time.
>> +         */
>> +        if (seq_delta != 1) {
>> +            igt_debug("vblank seq delta = %u\n", seq_delta);
>> +            err_frames++;
>> +            continue;
>> +        }
>> +
>> +        total_frame_time_ns += frame_time_ns;
>> +    }
>> +
>> +    valid_frames = TARGET_RR_SAMP_COUNT - err_frames;
>> +
>> +    igt_assert_f(valid_frames >= 90,
>> +             "Valid frames below threshold (90): valid_frames=%u, 
>> err_frames=%u\n",
>> +             valid_frames, err_frames);
>> +
>> +    avg_frame_time_ns = (double)total_frame_time_ns / valid_frames;
>> +    avg_refresh_rate = (double)NSECS_PER_SEC / avg_frame_time_ns;
>> +
>> +    igt_assert_f(fabs(avg_refresh_rate - expected_rr) <= 
>> CMRR_RR_TOLERANCE_HZ,
>> +             "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 = %u\n",
>> +         avg_refresh_rate, expected_rr, err_frames);
>> +}
>> +
>> +/**
>
> Did you intend it to be a doc style comment? 
Yes, it was intended to be a doc style comment.
>
>> + * Programs the requested CMRR target refresh rate for @mode, 
>> verifies that the measured
>> + * refresh rate matches the expected CMRR behavior,then disables 
>> CMRR and verifies that
>
> nit: behaviour, then
>
>> + * the refresh rate returns to the mode's nominal refresh rate. The 
>> function asserts that
>> + * all target refresh rate programming operations succeed.
>> + */
>> +static void
>> +run_cmrr(data_t *data, igt_crtc_t *crtc, igt_output_t *output,
>> +     const drmModeModeInfo *mode, uint32_t cmrr_mode)
>> +{
>> +    uint32_t numerator, denominator;
>> +    bool ret;
>> +    double rr_from_mode = igt_vrr_mode_line_refresh_hz(mode);
>> +
>> +    switch (cmrr_mode) {
>> +    case CMRR_VIDEO_MODE:
>> +        numerator = mode->vrefresh * CMRR_NUMERATOR;
>> +        denominator = CMRR_VIDEO_MODE_DENOMINATOR;
>> +        break;
>> +    case CMRR_DESKTOP_MODE:
>> +        numerator = mode->vrefresh * CMRR_NUMERATOR;
>> +        denominator = CMRR_DENOMINATOR;
>> +        break;
>> +    default:
>> +        igt_assert_f(0, "Unsupported CMRR mode %u\n",
>> +                 cmrr_mode);
>> +    }
>> +
>> +    igt_output_override_mode(output, mode);
>> +    igt_info("Override mode:");
>> +    kmstest_dump_mode((drmModeModeInfo *)mode);
>> +    igt_display_commit2(&data->display, COMMIT_ATOMIC);
>> +
>> +    ret = igt_vrr_target_rr_debugfs_write(data->drm_fd,
>> +                          crtc->crtc_index,
>> +                          numerator,
>> +                          denominator);
>> +    igt_assert_f(ret, "Failed to program CMRR target RR (%u/%u)\n",
>> +             numerator, denominator);
>> +
>> +    flip_and_measure_target_rr(data, crtc, mode->vrefresh, cmrr_mode);
>> +
>> +    ret = igt_vrr_target_rr_debugfs_write(data->drm_fd, 
>> crtc->crtc_index, 0, 0);
>> +
>> +    igt_assert_f(ret, "Failed to disable CMRR target RR\n");
>> +
>> +    flip_and_measure_target_rr(data, crtc, rr_from_mode, CMRR_DISABLE);
>> +}
>> +
>> +/* Validate CMRR behavior for supported video and desktop display 
>> modes. */
>> +static
>> +void test_cmrr(data_t *data, igt_crtc_t *crtc,
>> +           igt_output_t *output, uint32_t flags)
>> +{
>> +    drmModeModeInfo mode;
>> +    bool found = false;
>> +    drmModeConnectorPtr connector = output->config.connector;
>> +    uint32_t j;
>> +
>> + igt_require_f(igt_vrr_target_refresh_rate_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) {
>> +        found = false;
>> +        for (j = 0; j < igt_vrr_standard_video_timing_fps_count; j++) {
>> +            if (!get_mode_with_video_timing(output,
>> + igt_vrr_standard_video_timing_fps[j],
>> +                            &mode))
>> +                continue;
>> +
>> +            found = true;
>> +            run_cmrr(data, crtc, output, &mode, CMRR_VIDEO_MODE);
>> +        }
>> +        igt_require_f(found, "No video mode found.\n");
>> +    }
>> +
>> +    if (flags & TEST_CMRR_DESKTOP_MODE) {
>> +        found = false;
>> +        for (j = 0; j < connector->count_modes; j++) {
>> +            mode = connector->modes[j];
>> +            if (igt_vrr_mode_line_refresh_hz(&mode) - mode.vrefresh 
>> <= 0.04)
>> +                continue;
>> +
>> +            found = true;
>> +            run_cmrr(data, crtc, output, &mode, CMRR_DESKTOP_MODE);
>> +        }
>> +        igt_require_f(found, "No desktop 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 +816,7 @@ test_basic(data_t *data, igt_crtc_t *crtc, 
>> igt_output_t *output,
>>       uint64_t rate[] = {0};
>>         prepare_test(data, output, crtc);
>> +
>
> unintentional new line.
Sure. I will fix all review minor comments in next revision.
>
> With these LGTM
> Reviewed-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>v
>
>>       range = data->range;
>>       vtest_ns = data->vtest_ns;
>>       rate[0] = vtest_ns.rate_ns;
>> @@ -1147,6 +1373,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 desktop mode.");
>> +        igt_subtest_with_dynamic("cmrr-desktop-mode") {
>> +            run_vrr_test(&data, test_cmrr, TEST_CMRR_DESKTOP_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);
>

[-- Attachment #2: Type: text/html, Size: 27020 bytes --]

  reply	other threads:[~2026-09-12 19:53 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-07 17:48 [PATCH i-g-t v6 0/3] Add CMRR subtests Naladala Ramanaidu
2026-09-07 17:48 ` [PATCH i-g-t v6 1/3] lib/igt_vrr: Add VRR helper library for display refresh rate testing Naladala Ramanaidu
2026-09-09 16:33   ` Golani, Mitulkumar Ajitkumar
2026-09-10 10:14   ` Borah, Chaitanya Kumar
2026-09-07 17:48 ` [PATCH i-g-t v6 2/3] lib/igt_kms: Add helper to return vblank timestamp and sequence Naladala Ramanaidu
2026-09-09 16:22   ` Golani, Mitulkumar Ajitkumar
2026-09-07 17:48 ` [PATCH i-g-t v6 3/3] tests/kms_vrr: Add CMRR fixed and video mode subtests Naladala Ramanaidu
2026-09-10  8:46   ` Golani, Mitulkumar Ajitkumar
2026-09-10 10:25   ` Borah, Chaitanya Kumar
2026-09-12 19:52     ` Naladala, Ramanaidu [this message]
2026-09-07 20:28 ` ✓ Xe.CI.BAT: success for Add CMRR subtests (rev6) Patchwork
2026-09-07 20:42 ` ✓ i915.CI.BAT: " Patchwork
2026-09-08  0:58 ` ✗ Xe.CI.FULL: failure " Patchwork
2026-09-08  7:42 ` ✗ 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=c24dd279-531a-4f9a-b3f1-d13bfd65fca5@intel.com \
    --to=ramanaidu.naladala@intel.com \
    --cc=chaitanya.kumar.borah@intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=karthik.b.s@intel.com \
    --cc=mitulkumar.ajitkumar.golani@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox