Re: [PATCH v3 1/8] drm/i915/vrr: Add per-CRTC vrr/cmrr debugfs control

"Borah, Chaitanya Kumar" <[email protected]>
Newsgroups org.freedesktop.lists.intel-gfx,org.freedesktop.lists.intel-xe
Message-ID <[email protected]>

On 7/16/2026 8:07 PM, Naladala, Ramanaidu wrote:
> Hi Mitul,
> 
> Resending this, as it was previously sent only to i915 by mistake.
> 
>> Add a per-CRTC debugfs file 'intel_vrr_cmrr' that lets the user force a
>> CMRR target refresh rate and video-mode requirement.
>>
>> The file uses a "numerator/denominator" format:
>>    - numerator:   requested refresh rate in milli-Hz
>>                   (refresh rate in Hz * 1000, e.g. 60000 for 60 Hz)
>>    - denominator: 1000 for a 1:1 ratio (no video timing) or
>>                   1001 for the 1000/1001 video timing
>>
>> Reading the file reports the currently stored values; writing updates
>> them. The file is created only on platforms with VRR and CMRR support.
>>
>> --v2:
>> - Drop the "vrr" debugfs subdirectory and expose a single flat,
>>    intel_-prefixed "intel_vrr_cmrr" file (Jani, Nikula)
>> - Rename struct intel_crtc.cmrr to force_cmrr to make its purpose
>>    explicit (Chaitanya)
>> - Fix parse comment: numerator unit is milli-Hz, not KHz (Chaitanya)
>> - Add debugfs/intel_ prefixes to the debugfs handler functions 
>> (Chaitanya)
>> - Expand commit message with debugfs entry semantics (Chaitanya)
>>
>> Signed-off-by: Mitul Golani <[email protected]>
>> ---
>>   .../drm/i915/display/intel_display_debugfs.c  |   2 +
>>   .../drm/i915/display/intel_display_types.h    |   5 +
>>   drivers/gpu/drm/i915/display/intel_vrr.c      | 103 ++++++++++++++++++
>>   drivers/gpu/drm/i915/display/intel_vrr.h      |   2 +
>>   4 files changed, 112 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/ 
>> drivers/gpu/drm/i915/display/intel_display_debugfs.c
>> index 3f02868ef105..2bbf4760dc30 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
>> +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
>> @@ -49,6 +49,7 @@
>>   #include "intel_psr.h"
>>   #include "intel_psr_regs.h"
>>   #include "intel_vdsc.h"
>> +#include "intel_vrr.h"
>>   #include "intel_wm.h"
>>   #include "intel_tc.h"
>> @@ -1395,6 +1396,7 @@ void intel_crtc_debugfs_add(struct intel_crtc 
>> *crtc)
>>       intel_drrs_crtc_debugfs_add(crtc);
>>       intel_fbc_crtc_debugfs_add(crtc);
>>       hsw_ips_crtc_debugfs_add(crtc);
>> +    intel_vrr_crtc_debugfs_add(crtc);
>>       debugfs_create_file("i915_current_bpc", 0444, root, crtc,
>>                   &i915_current_bpc_fops);
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/ 
>> drivers/gpu/drm/i915/display/intel_display_types.h
>> index c048da7d6fea..84a6d016e226 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
>> @@ -1546,6 +1546,11 @@ struct intel_crtc {
>>           u64 flip_count;
>>       } dc_balance;
>> +    struct {
>> +        u32 numerator;
>> +        u32 denominator;
>> +    } force_cmrr;
>> +
>>       int scanline_offset;
>>       struct {
>> diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/ 
>> drm/i915/display/intel_vrr.c
>> index 51e4f3309b8b..8b6e36ee9f55 100644
>> --- a/drivers/gpu/drm/i915/display/intel_vrr.c
>> +++ b/drivers/gpu/drm/i915/display/intel_vrr.c
>> @@ -4,6 +4,10 @@
>>    *
>>    */
>> +#include <linux/debugfs.h>
>> +#include <linux/seq_file.h>
>> +#include <linux/string.h>
>> +
>>   #include <drm/drm_print.h>
>>   #include <drm/intel/step.h>
>> @@ -1231,3 +1235,102 @@ int 
>> intel_vrr_dcb_vmax_vblank_start_final(const struct intel_crtc_state 
>> *crtc_st
>>       return intel_vrr_vblank_start(crtc_state, VRR_DCB_VMAX(tmp) + 1);
>>   }
>> +
>> +static
>> +int intel_vrr_cmrr_parse_ratio(char *str, u32 *numerator, u32 
>> *denominator)
>> +{
>> +    char *sep;
>> +    int ret;
>> +
>> +    /*
>> +     * Parse a "numerator/denominator" CMRR ratio string. The numerator
>> +     * is the requested refresh rate in milli-Hz (refresh rate in Hz 
>> * 1000)
>> +     * and the denominator selects the timing: 1000 for a 1:1 ratio
>> +     * (no video timing) or 1001 for the 1000/1001 video timing.
>> +     */
>> +
>> +    sep = strchr(str, '/');
>> +    if (!sep)
>> +        return -EINVAL;
>> +
>> +    *sep = '\0';
>> +
>> +    ret = kstrtou32(strim(str), 10, numerator);
>> +    if (ret)
>> +        return ret;
>> +
>> +    ret = kstrtou32(strim(sep + 1), 10, denominator);
>> +    if (ret)
>> +        return ret;
>> +
>> +    if (*numerator == 0)
>> +        return -EINVAL;
>> +
>> +    if (*denominator != 1000 && *denominator != 1001)
>> +        return -EINVAL;
>> +
>> +    return 0;
>> +}
>> +
>> +static int intel_vrr_debugfs_cmrr_show(struct seq_file *m, void *data)
>> +{
>> +    struct intel_crtc *crtc = m->private;
>> +
>> +    seq_printf(m, "%u/%u\n", crtc->force_cmrr.numerator, crtc- 
>> >force_cmrr.denominator);
>> +
>> +    return 0;
>> +}
>> +
>> +static int intel_vrr_debugfs_cmrr_open(struct inode *inode, struct 
>> file *file)
>> +{
>> +    return single_open(file, intel_vrr_debugfs_cmrr_show, inode- 
>> >i_private);
>> +}
>> +
>> +static ssize_t intel_vrr_debugfs_cmrr_write(struct file *file, const 
>> char __user *ubuf,
>> +                        size_t len, loff_t *offp)
>> +{
>> +    struct seq_file *m = file->private_data;
>> +    struct intel_crtc *crtc = m->private;
>> +    u32 numerator, denominator;
>> +    char kbuf[32];
>> +    int ret;
>> +
>> +    if (len >= sizeof(kbuf))
>> +        return -EINVAL;
>> +
>> +    if (copy_from_user(kbuf, ubuf, len))
>> +        return -EFAULT;
>> +
>> +    kbuf[len] = '\0';
>> +
>> +    ret = intel_vrr_cmrr_parse_ratio(kbuf, &numerator, &denominator);
>> +    if (ret)
>> +        return ret;
>> +
>> +    crtc->force_cmrr.numerator = numerator;
>> +    crtc->force_cmrr.denominator = denominator;
>> +
>> +    return len;
>> +}
>> +
>> +static const struct file_operations intel_vrr_debugfs_cmrr_fops = {
>> +    .owner = THIS_MODULE,
>> +    .open = intel_vrr_debugfs_cmrr_open,
>> +    .read = seq_read,
>> +    .llseek = seq_lseek,
>> +    .release = single_release,
>> +    .write = intel_vrr_debugfs_cmrr_write,
>> +};
>> +
>> +void intel_vrr_crtc_debugfs_add(struct intel_crtc *crtc)
>> +{
>> +    struct intel_display *display = to_intel_display(crtc);
>> +
>> +    if (!HAS_VRR(display))
>> +        return;
>> +
>> +    if (HAS_CMRR(display))
>> +        debugfs_create_file("intel_vrr_cmrr", 0600, crtc- 
>> >base.debugfs_entry,
>> +                    crtc, &intel_vrr_debugfs_cmrr_fops);
>> +}
> 
> The debugfs interface accepts non-zero values, but fails to reset the 
> value to zero.
> 

Yeah I think we will also need some magic value to let the driver know 
to disable the feature. Since 0/0 is the default value shown by the 
debugfs entry that makes the most sense.

echo '0/0' > <file name>

to disable the CMRR. IGT can use it restore the state after testing is done.

>> +
>> diff --git a/drivers/gpu/drm/i915/display/intel_vrr.h b/drivers/gpu/ 
>> drm/i915/display/intel_vrr.h
>> index 55e9c429f579..19c7990be1b2 100644
>> --- a/drivers/gpu/drm/i915/display/intel_vrr.h
>> +++ b/drivers/gpu/drm/i915/display/intel_vrr.h
>> @@ -56,4 +56,6 @@ int intel_vrr_dcb_vmax_vblank_start_next(const 
>> struct intel_crtc_state *crtc_sta
>>   int intel_vrr_dcb_vmin_vblank_start_final(const struct 
>> intel_crtc_state *crtc_state);
>>   int intel_vrr_dcb_vmax_vblank_start_final(const struct 
>> intel_crtc_state *crtc_state);
>> +void intel_vrr_crtc_debugfs_add(struct intel_crtc *crtc);
>> +
>>   #endif /* __INTEL_VRR_H__ */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.