summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2014-05-27 09:49:45 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:09:58 -0400
commitcd9f8553ad1e6e03e8a3a70cb8d08edd3513fb66 (patch)
treee934093697d0d849d1068aa4cb41653c521af6f7 /drivers/gpu/nvgpu
parent3f7be93dab3ccb5f1cfc2a65013ff8fefaa5bbbd (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>
Diffstat (limited to 'drivers/gpu/nvgpu')
-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 115cd7f4..6d3c8225 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -248,6 +248,7 @@ struct gk20a {
248 bool elcg_enabled; 248 bool elcg_enabled;
249 bool elpg_enabled; 249 bool elpg_enabled;
250 bool aelpg_enabled; 250 bool aelpg_enabled;
251 bool forced_idle;
251 252
252#ifdef CONFIG_DEBUG_FS 253#ifdef CONFIG_DEBUG_FS
253 spinlock_t debugfs_lock; 254 spinlock_t debugfs_lock;
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c
index 9ebc5bab..a9e7274e 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c
@@ -22,6 +22,7 @@
22#include <linux/pm_runtime.h> 22#include <linux/pm_runtime.h>
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/fb.h> 24#include <linux/fb.h>
25#include <linux/gk20a.h>
25 26
26#include <mach/clk.h> 27#include <mach/clk.h>
27 28
@@ -331,6 +332,55 @@ static ssize_t elpg_enable_read(struct device *device,
331 332
332static DEVICE_ATTR(elpg_enable, ROOTRW, elpg_enable_read, elpg_enable_store); 333static DEVICE_ATTR(elpg_enable, ROOTRW, elpg_enable_read, elpg_enable_store);
333 334
335static ssize_t force_idle_store(struct device *device,
336 struct device_attribute *attr, const char *buf, size_t count)
337{
338 struct platform_device *ndev = to_platform_device(device);
339 struct gk20a *g = get_gk20a(ndev);
340 unsigned long val = 0;
341 int err = 0;
342
343 if (kstrtoul(buf, 10, &val) < 0)
344 return -EINVAL;
345
346 if (val) {
347 if (g->forced_idle)
348 return count; /* do nothing */
349 else {
350 err = gk20a_do_idle();
351 if (!err) {
352 g->forced_idle = 1;
353 dev_info(device, "gpu is idle : %d\n",
354 g->forced_idle);
355 }
356 }
357 } else {
358 if (!g->forced_idle)
359 return count; /* do nothing */
360 else {
361 err = gk20a_do_unidle();
362 if (!err) {
363 g->forced_idle = 0;
364 dev_info(device, "gpu is idle : %d\n",
365 g->forced_idle);
366 }
367 }
368 }
369
370 return count;
371}
372
373static ssize_t force_idle_read(struct device *device,
374 struct device_attribute *attr, char *buf)
375{
376 struct platform_device *ndev = to_platform_device(device);
377 struct gk20a *g = get_gk20a(ndev);
378
379 return sprintf(buf, "%d\n", g->forced_idle ? 1 : 0);
380}
381
382static DEVICE_ATTR(force_idle, ROOTRW, force_idle_read, force_idle_store);
383
334void gk20a_remove_sysfs(struct device *dev) 384void gk20a_remove_sysfs(struct device *dev)
335{ 385{
336 struct gk20a *g = get_gk20a(to_platform_device(dev)); 386 struct gk20a *g = get_gk20a(to_platform_device(dev));
@@ -345,6 +395,7 @@ void gk20a_remove_sysfs(struct device *dev)
345 device_remove_file(dev, &dev_attr_load); 395 device_remove_file(dev, &dev_attr_load);
346 device_remove_file(dev, &dev_attr_railgate_delay); 396 device_remove_file(dev, &dev_attr_railgate_delay);
347 device_remove_file(dev, &dev_attr_clockgate_delay); 397 device_remove_file(dev, &dev_attr_clockgate_delay);
398 device_remove_file(dev, &dev_attr_force_idle);
348 399
349 if (g->host1x_dev && (dev->parent != &g->host1x_dev->dev)) 400 if (g->host1x_dev && (dev->parent != &g->host1x_dev->dev))
350 sysfs_remove_link(&dev->kobj, dev_name(dev)); 401 sysfs_remove_link(&dev->kobj, dev_name(dev));
@@ -365,6 +416,7 @@ void gk20a_create_sysfs(struct platform_device *dev)
365 error |= device_create_file(&dev->dev, &dev_attr_load); 416 error |= device_create_file(&dev->dev, &dev_attr_load);
366 error |= device_create_file(&dev->dev, &dev_attr_railgate_delay); 417 error |= device_create_file(&dev->dev, &dev_attr_railgate_delay);
367 error |= device_create_file(&dev->dev, &dev_attr_clockgate_delay); 418 error |= device_create_file(&dev->dev, &dev_attr_clockgate_delay);
419 error |= device_create_file(&dev->dev, &dev_attr_force_idle);
368 420
369 if (g->host1x_dev && (dev->dev.parent != &g->host1x_dev->dev)) 421 if (g->host1x_dev && (dev->dev.parent != &g->host1x_dev->dev))
370 error |= sysfs_create_link(&g->host1x_dev->dev.kobj, 422 error |= sysfs_create_link(&g->host1x_dev->dev.kobj,