summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2014-05-27 19:19:45 +0530
committerRiham Haidar <rhaidar@nvidia.com>2014-06-12 17:33:31 -0700
commit7e921348b94ea0a45d94376cd3f15b4494de7477 (patch)
tree9a79457e853f1e93d82c66907c52f2b10adafa38 /drivers/gpu
parent9c5129e3c1ebf525f86ff4a6225403eb6b974293 (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.h1
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c52
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");