Add a per-CRTC debugfs entry 'vrr/cmrr_scaling' to allow reading and writing the CMRR fraction level at runtime for debug and testing purposes.
The file accepts three string values: "Low" - Apply 1000/1001 fractional multiplier to vtotal "Default" - Use nominal fixed refresh rate vtotal as-is "High" - Apply 1001/1000 fractional multiplier to vtotal Signed-off-by: Mitul Golani <[email protected]> --- .../drm/i915/display/intel_display_debugfs.c | 2 + drivers/gpu/drm/i915/display/intel_vrr.c | 85 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_vrr.h | 1 + 3 files changed, 88 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 81bef000a4e3..ae698560f306 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -48,6 +48,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" @@ -1387,6 +1388,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_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index bbc68c614667..e31778367245 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -20,6 +20,8 @@ #include "skl_prefill.h" #include "skl_watermark.h" +#include "linux/debugfs.h" + #define FIXED_POINT_PRECISION 100 #define CMRR_PRECISION_TOLERANCE 10 @@ -1227,3 +1229,86 @@ char *intel_vrr_cmrr_level_to_string(enum cmrr_level level) return "Default"; } } + +static int string_to_cmrr(const char *str, enum cmrr_level *level) +{ + if (sysfs_streq(str, "Low")) + *level = CMRR_LOW; + else if (sysfs_streq(str, "High")) + *level = CMRR_HIGH; + else if (sysfs_streq(str, "Default")) + *level = CMRR_DEFAULT; + else + return -EINVAL; + + return 0; +} + +static ssize_t cmrr_write(struct file *file, + const char __user *buf, + size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + struct intel_crtc *crtc = s->private; + struct intel_crtc_state *crtc_state = + to_intel_crtc_state(crtc->base.state); + char kbuf[32]; + enum cmrr_level level; + int ret; + + if (count >= sizeof(kbuf)) + return -EINVAL; + + if (copy_from_user(kbuf, buf, count)) + return -EFAULT; + + kbuf[count] = '\0'; + + ret = string_to_cmrr(kbuf, &level); + if (ret) + return ret; + + crtc_state->vrr.cmrr.level = level; + + return count; +} + +static int cmrr_show(struct seq_file *s, void *data) +{ + struct intel_crtc *crtc = s->private; + struct intel_crtc_state *crtc_state = + to_intel_crtc_state(crtc->base.state); + + seq_printf(s, "%s\n", intel_vrr_cmrr_level_to_string(crtc_state->vrr.cmrr.level)); + + return 0; +} + +static int cmrr_open(struct inode *inode, struct file *file) +{ + return single_open(file, cmrr_show, inode->i_private); +} + +static const struct file_operations cmrr_fops = { + .owner = THIS_MODULE, + .open = cmrr_open, + .read = seq_read, + .write = cmrr_write, + .llseek = seq_lseek, + .release = single_release, +}; + +void intel_vrr_crtc_debugfs_add(struct intel_crtc *crtc) +{ + struct dentry *root = crtc->base.debugfs_entry; + struct dentry *dir; + + if (!root) + return; + + dir = debugfs_create_dir("vrr", root); + if (IS_ERR(dir)) + pr_err("debugfs creation : %ld\n", PTR_ERR(dir)); + + debugfs_create_file("cmrr_scaling", 0600, dir, crtc, &cmrr_fops); +} diff --git a/drivers/gpu/drm/i915/display/intel_vrr.h b/drivers/gpu/drm/i915/display/intel_vrr.h index 86707b8af2e3..9b52a0bf0e4f 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.h +++ b/drivers/gpu/drm/i915/display/intel_vrr.h @@ -55,5 +55,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); char *intel_vrr_cmrr_level_to_string(enum cmrr_level level); +void intel_vrr_crtc_debugfs_add(struct intel_crtc *crtc); #endif /* __INTEL_VRR_H__ */ -- 2.48.1
