diff options
author | Deepak Nibade <dnibade@nvidia.com> | 2014-05-27 19:19:45 +0530 |
---|---|---|
committer | Riham Haidar <rhaidar@nvidia.com> | 2014-06-12 17:33:31 -0700 |
commit | 7e921348b94ea0a45d94376cd3f15b4494de7477 (patch) | |
tree | 9a79457e853f1e93d82c66907c52f2b10adafa38 /drivers/gpu | |
parent | 9c5129e3c1ebf525f86ff4a6225403eb6b974293 (diff) |
gpu: nvgpu: sysfs to put gpu into idle
- Add a sysfs "force_idle" to forcibly idle the GPU
- read on this sysfs will return the current status
0 : not in idle (running)
1 : in forced idle state
"echo 1 > force_idle" will force the gpu into idle
"echo 0 > force_idle" will cause the gpu to resume
Bug 1376916
Bug 1487804
Change-Id: I48dfd52e0d14561220bc4baea0776d1bdfaa7ea5
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
(cherry picked from commit 44d89a68bf6c9034c8bf9f5111d733290e7cb71e)
Reviewed-on: http://git-master/r/421699
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
GVS: Gerrit_Virtual_Submit
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c | 52 |
2 files changed, 53 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 679398eedc40..ae4900722855 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -238,6 +238,7 @@ struct gk20a { bool elcg_enabled; bool elpg_enabled; bool aelpg_enabled; + bool forced_idle; #ifdef CONFIG_DEBUG_FS spinlock_t debugfs_lock; diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c index 335c3f3bba34..b318ee5eeae8 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c @@ -22,6 +22,7 @@ #include <linux/pm_runtime.h> #include <linux/kernel.h> #include <linux/fb.h> +#include <linux/gk20a.h> #include <mach/clk.h> @@ -309,6 +310,55 @@ static ssize_t elpg_enable_read(struct device *device, static DEVICE_ATTR(elpg_enable, ROOTRW, elpg_enable_read, elpg_enable_store); +static ssize_t force_idle_store(struct device *device, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct platform_device *ndev = to_platform_device(device); + struct gk20a *g = get_gk20a(ndev); + unsigned long val = 0; + int err = 0; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + if (val) { + if (g->forced_idle) + return count; /* do nothing */ + else { + err = gk20a_do_idle(); + if (!err) { + g->forced_idle = 1; + dev_info(device, "gpu is idle : %d\n", + g->forced_idle); + } + } + } else { + if (!g->forced_idle) + return count; /* do nothing */ + else { + err = gk20a_do_unidle(); + if (!err) { + g->forced_idle = 0; + dev_info(device, "gpu is idle : %d\n", + g->forced_idle); + } + } + } + + return count; +} + +static ssize_t force_idle_read(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct platform_device *ndev = to_platform_device(device); + struct gk20a *g = get_gk20a(ndev); + + return sprintf(buf, "%d\n", g->forced_idle ? 1 : 0); +} + +static DEVICE_ATTR(force_idle, ROOTRW, force_idle_read, force_idle_store); + void gk20a_remove_sysfs(struct device *dev) { device_remove_file(dev, &dev_attr_elcg_enable); @@ -320,6 +370,7 @@ void gk20a_remove_sysfs(struct device *dev) device_remove_file(dev, &dev_attr_counters_reset); device_remove_file(dev, &dev_attr_railgate_delay); device_remove_file(dev, &dev_attr_clockgate_delay); + device_remove_file(dev, &dev_attr_force_idle); } void gk20a_create_sysfs(struct platform_device *dev) @@ -335,6 +386,7 @@ void gk20a_create_sysfs(struct platform_device *dev) error |= device_create_file(&dev->dev, &dev_attr_counters_reset); error |= device_create_file(&dev->dev, &dev_attr_railgate_delay); error |= device_create_file(&dev->dev, &dev_attr_clockgate_delay); + error |= device_create_file(&dev->dev, &dev_attr_force_idle); if (error) dev_err(&dev->dev, "Failed to create sysfs attributes!\n"); |