mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
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>
This commit is contained in:
committed by
Dan Willemsen
parent
3f7be93dab
commit
cd9f8553ad
@@ -248,6 +248,7 @@ struct gk20a {
|
|||||||
bool elcg_enabled;
|
bool elcg_enabled;
|
||||||
bool elpg_enabled;
|
bool elpg_enabled;
|
||||||
bool aelpg_enabled;
|
bool aelpg_enabled;
|
||||||
|
bool forced_idle;
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
spinlock_t debugfs_lock;
|
spinlock_t debugfs_lock;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/fb.h>
|
#include <linux/fb.h>
|
||||||
|
#include <linux/gk20a.h>
|
||||||
|
|
||||||
#include <mach/clk.h>
|
#include <mach/clk.h>
|
||||||
|
|
||||||
@@ -331,6 +332,55 @@ static ssize_t elpg_enable_read(struct device *device,
|
|||||||
|
|
||||||
static DEVICE_ATTR(elpg_enable, ROOTRW, elpg_enable_read, elpg_enable_store);
|
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)
|
void gk20a_remove_sysfs(struct device *dev)
|
||||||
{
|
{
|
||||||
struct gk20a *g = get_gk20a(to_platform_device(dev));
|
struct gk20a *g = get_gk20a(to_platform_device(dev));
|
||||||
@@ -345,6 +395,7 @@ void gk20a_remove_sysfs(struct device *dev)
|
|||||||
device_remove_file(dev, &dev_attr_load);
|
device_remove_file(dev, &dev_attr_load);
|
||||||
device_remove_file(dev, &dev_attr_railgate_delay);
|
device_remove_file(dev, &dev_attr_railgate_delay);
|
||||||
device_remove_file(dev, &dev_attr_clockgate_delay);
|
device_remove_file(dev, &dev_attr_clockgate_delay);
|
||||||
|
device_remove_file(dev, &dev_attr_force_idle);
|
||||||
|
|
||||||
if (g->host1x_dev && (dev->parent != &g->host1x_dev->dev))
|
if (g->host1x_dev && (dev->parent != &g->host1x_dev->dev))
|
||||||
sysfs_remove_link(&dev->kobj, dev_name(dev));
|
sysfs_remove_link(&dev->kobj, dev_name(dev));
|
||||||
@@ -365,6 +416,7 @@ void gk20a_create_sysfs(struct platform_device *dev)
|
|||||||
error |= device_create_file(&dev->dev, &dev_attr_load);
|
error |= device_create_file(&dev->dev, &dev_attr_load);
|
||||||
error |= device_create_file(&dev->dev, &dev_attr_railgate_delay);
|
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_clockgate_delay);
|
||||||
|
error |= device_create_file(&dev->dev, &dev_attr_force_idle);
|
||||||
|
|
||||||
if (g->host1x_dev && (dev->dev.parent != &g->host1x_dev->dev))
|
if (g->host1x_dev && (dev->dev.parent != &g->host1x_dev->dev))
|
||||||
error |= sysfs_create_link(&g->host1x_dev->dev.kobj,
|
error |= sysfs_create_link(&g->host1x_dev->dev.kobj,
|
||||||
|
|||||||
Reference in New Issue
Block a user