diff options
Diffstat (limited to 'drivers')
-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"); |