Commit 358733e9 authored by Jesse Barnes's avatar Jesse Barnes Committed by Keith Packard

drm/i915: add GPU max frequency control file

Mainly for use in debugging and benchmarking, this file allows the user
to control the max frequency used by the GPU.  Frequency may still vary
based on workload (if the frequency is set to higher than the minimum)
but won't go over the newly set value.
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: default avatarKeith Packard <keithp@keithp.com>
parent b066254f
...@@ -1300,6 +1300,76 @@ static const struct file_operations i915_wedged_fops = { ...@@ -1300,6 +1300,76 @@ static const struct file_operations i915_wedged_fops = {
.llseek = default_llseek, .llseek = default_llseek,
}; };
static int
i915_max_freq_open(struct inode *inode,
struct file *filp)
{
filp->private_data = inode->i_private;
return 0;
}
static ssize_t
i915_max_freq_read(struct file *filp,
char __user *ubuf,
size_t max,
loff_t *ppos)
{
struct drm_device *dev = filp->private_data;
drm_i915_private_t *dev_priv = dev->dev_private;
char buf[80];
int len;
len = snprintf(buf, sizeof (buf),
"max freq: %d\n", dev_priv->max_delay * 50);
if (len > sizeof (buf))
len = sizeof (buf);
return simple_read_from_buffer(ubuf, max, ppos, buf, len);
}
static ssize_t
i915_max_freq_write(struct file *filp,
const char __user *ubuf,
size_t cnt,
loff_t *ppos)
{
struct drm_device *dev = filp->private_data;
struct drm_i915_private *dev_priv = dev->dev_private;
char buf[20];
int val = 1;
if (cnt > 0) {
if (cnt > sizeof (buf) - 1)
return -EINVAL;
if (copy_from_user(buf, ubuf, cnt))
return -EFAULT;
buf[cnt] = 0;
val = simple_strtoul(buf, NULL, 0);
}
DRM_DEBUG_DRIVER("Manually setting max freq to %d\n", val);
/*
* Turbo will still be enabled, but won't go above the set value.
*/
dev_priv->max_delay = val / 50;
gen6_set_rps(dev, val / 50);
return cnt;
}
static const struct file_operations i915_max_freq_fops = {
.owner = THIS_MODULE,
.open = i915_max_freq_open,
.read = i915_max_freq_read,
.write = i915_max_freq_write,
.llseek = default_llseek,
};
/* As the drm_debugfs_init() routines are called before dev->dev_private is /* As the drm_debugfs_init() routines are called before dev->dev_private is
* allocated we need to hook into the minor for release. */ * allocated we need to hook into the minor for release. */
static int static int
...@@ -1399,6 +1469,21 @@ static int i915_forcewake_create(struct dentry *root, struct drm_minor *minor) ...@@ -1399,6 +1469,21 @@ static int i915_forcewake_create(struct dentry *root, struct drm_minor *minor)
return drm_add_fake_info_node(minor, ent, &i915_forcewake_fops); return drm_add_fake_info_node(minor, ent, &i915_forcewake_fops);
} }
static int i915_max_freq_create(struct dentry *root, struct drm_minor *minor)
{
struct drm_device *dev = minor->dev;
struct dentry *ent;
ent = debugfs_create_file("i915_max_freq",
S_IRUGO | S_IWUSR,
root, dev,
&i915_max_freq_fops);
if (IS_ERR(ent))
return PTR_ERR(ent);
return drm_add_fake_info_node(minor, ent, &i915_max_freq_fops);
}
static struct drm_info_list i915_debugfs_list[] = { static struct drm_info_list i915_debugfs_list[] = {
{"i915_capabilities", i915_capabilities, 0}, {"i915_capabilities", i915_capabilities, 0},
{"i915_gem_objects", i915_gem_object_info, 0}, {"i915_gem_objects", i915_gem_object_info, 0},
...@@ -1449,6 +1534,9 @@ int i915_debugfs_init(struct drm_minor *minor) ...@@ -1449,6 +1534,9 @@ int i915_debugfs_init(struct drm_minor *minor)
return ret; return ret;
ret = i915_forcewake_create(minor->debugfs_root, minor); ret = i915_forcewake_create(minor->debugfs_root, minor);
if (ret)
return ret;
ret = i915_max_freq_create(minor->debugfs_root, minor);
if (ret) if (ret)
return ret; return ret;
...@@ -1465,6 +1553,8 @@ void i915_debugfs_cleanup(struct drm_minor *minor) ...@@ -1465,6 +1553,8 @@ void i915_debugfs_cleanup(struct drm_minor *minor)
1, minor); 1, minor);
drm_debugfs_remove_files((struct drm_info_list *) &i915_wedged_fops, drm_debugfs_remove_files((struct drm_info_list *) &i915_wedged_fops,
1, minor); 1, minor);
drm_debugfs_remove_files((struct drm_info_list *) &i915_max_freq_fops,
1, minor);
} }
#endif /* CONFIG_DEBUG_FS */ #endif /* CONFIG_DEBUG_FS */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment