mirror of
https://github.com/torvalds/linux.git
synced 2026-11-13 05:04:29 +01:00
drm/i915/vrr: Add per-CRTC vrr/cmrr debugfs control
Add a per-CRTC debugfs file 'intel_vrr_target_refresh_rate' 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)
--v3:
- Rename debugfs function and file name (Chaitanya)
- Remove railing new line at EOF (Chaitanya)
- Update CMRR guard conditions (Chaitanya)
- Add 0/0 default case. (Ramanaidu)
--v4:
- Correct CMRR guard check while creating debugfs
--v5:
- Commit message update (Chaitanya)
- Add support for 0/0 writing (Validation)
Signed-off-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
Reviewed-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Signed-off-by: Suraj Kandpal <suraj.kandpal@intel.com>
Link: https://patch.msgid.link/20260730105919.3913412-4-mitulkumar.ajitkumar.golani@intel.com
This commit is contained in:
parent
dfd1495664
commit
9edafeb040
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -1553,6 +1553,11 @@ struct intel_crtc {
|
|||
u64 flip_count;
|
||||
} dc_balance;
|
||||
|
||||
struct {
|
||||
u32 numerator;
|
||||
u32 denominator;
|
||||
} force_cmrr;
|
||||
|
||||
int scanline_offset;
|
||||
|
||||
struct {
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
@ -1237,3 +1241,111 @@ 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;
|
||||
/*
|
||||
* "0/0" clears any previously configured CMRR override.
|
||||
* A zero numerator already means "CMRR not requested" in
|
||||
* intel_vrr_cmrr_compute_config(), so just let it through.
|
||||
*/
|
||||
if (*numerator == 0 && *denominator == 0)
|
||||
return 0;
|
||||
|
||||
if (*numerator == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (*denominator != 1000 && *denominator != 1001)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intel_vrr_debugfs_target_rr_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_target_rr_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, intel_vrr_debugfs_target_rr_show, inode->i_private);
|
||||
}
|
||||
|
||||
static ssize_t intel_vrr_debugfs_target_rr_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;
|
||||
|
||||
if (crtc->force_cmrr.numerator == numerator &&
|
||||
crtc->force_cmrr.denominator == denominator)
|
||||
return len;
|
||||
|
||||
crtc->force_cmrr.numerator = numerator;
|
||||
crtc->force_cmrr.denominator = denominator;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static const struct file_operations intel_vrr_debugfs_target_rr_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = intel_vrr_debugfs_target_rr_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.write = intel_vrr_debugfs_target_rr_write,
|
||||
};
|
||||
|
||||
void intel_vrr_crtc_debugfs_add(struct intel_crtc *crtc)
|
||||
{
|
||||
struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state);
|
||||
|
||||
if (!intel_vrr_cmrr_possible(crtc_state))
|
||||
return;
|
||||
|
||||
debugfs_create_file("intel_vrr_target_refresh_rate", 0600, crtc->base.debugfs_entry,
|
||||
crtc, &intel_vrr_debugfs_target_rr_fops);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user