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__ */