summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Peres <martin.peres@labri.fr>2014-06-15 21:34:38 +0200
committerMartin Peres <martin.peres@labri.fr>2014-06-15 23:25:01 +0200
commitc79744f19e8ff656b7c372c08b5ed89724d2a2a6 (patch)
tree999b4d64c6cf476fddc905c09113badf0bbc01ea
parent27310fa8fdc39e54a3f4383fada96a3562c5a022 (diff)
pwr: expose ppwr's performance counters to the userspaceppwr_rework
-rw-r--r--drm/Kbuild1
-rw-r--r--drm/nouveau_hwmon.c2
-rw-r--r--drm/nouveau_sysfs.c95
-rw-r--r--nvkm/include/subdev/pwr.h6
-rw-r--r--nvkm/subdev/pwr/Makefile.am1
5 files changed, 105 insertions, 0 deletions
diff --git a/drm/Kbuild b/drm/Kbuild
index e2933db5..67ef9012 100644
--- a/drm/Kbuild
+++ b/drm/Kbuild
@@ -166,6 +166,7 @@ nouveau-y += core/subdev/mxm/mxms.o
nouveau-y += core/subdev/mxm/nv50.o
nouveau-y += core/subdev/pwr/base.o
nouveau-y += core/subdev/pwr/memx.o
+nouveau-y += core/subdev/pwr/perf.o
nouveau-y += core/subdev/pwr/nva3.o
nouveau-y += core/subdev/pwr/nvc0.o
nouveau-y += core/subdev/pwr/nvd0.o
diff --git a/drm/nouveau_hwmon.c b/drm/nouveau_hwmon.c
index 19fd767b..34f6f5b4 100644
--- a/drm/nouveau_hwmon.c
+++ b/drm/nouveau_hwmon.c
@@ -516,6 +516,8 @@ static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR,
nouveau_hwmon_get_pwm1_max,
nouveau_hwmon_set_pwm1_max, 0);
+
+
static struct attribute *hwmon_default_attributes[] = {
&sensor_dev_attr_name.dev_attr.attr,
&sensor_dev_attr_update_rate.dev_attr.attr,
diff --git a/drm/nouveau_sysfs.c b/drm/nouveau_sysfs.c
index ab5afc50..8a83ab82 100644
--- a/drm/nouveau_sysfs.c
+++ b/drm/nouveau_sysfs.c
@@ -26,6 +26,7 @@
#include <core/object.h>
#include <core/class.h>
+#include <subdev/pwr.h>
static inline struct drm_device *
drm_device(struct device *d)
@@ -149,6 +150,87 @@ nouveau_sysfs_pstate_set(struct device *d, struct device_attribute *a,
static DEVICE_ATTR(pstate, S_IRUGO | S_IWUSR,
nouveau_sysfs_pstate_get, nouveau_sysfs_pstate_set);
+static ssize_t
+nouveau_sysfs_get_ppwr_polling_period_us(struct device *d,
+ struct device_attribute *a, char *buf)
+{
+ struct nouveau_pwr *ppwr = nouveau_pwr(drm_device(d));
+ uint32_t period_us;
+ int ret;
+
+ ret = nouveau_pwr_perf_get_polling_period(ppwr, &period_us);
+ if (ret)
+ return ret;
+
+ return sprintf(buf, "%u\n", period_us);
+}
+
+static ssize_t
+nouveau_sysfs_set_ppwr_polling_period_us(struct device *d,
+ struct device_attribute *a,
+ const char *buf, size_t count)
+{
+ struct nouveau_pwr *ppwr = nouveau_pwr(drm_device(d));
+ uint32_t period_us;
+ int ret;
+
+ if (kstrtou32(buf, 10, &period_us) == -EINVAL)
+ return -EINVAL;
+
+ ret = nouveau_pwr_perf_set_polling_period(ppwr, period_us);
+ if (ret)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(usage_polling_period_us, S_IRUGO | S_IWUSR,
+ nouveau_sysfs_get_ppwr_polling_period_us,
+ nouveau_sysfs_set_ppwr_polling_period_us);
+
+static ssize_t
+nouveau_sysfs_gr_usage(struct device *d, struct device_attribute *attr,
+ char *buf)
+{
+ struct drm_device *dev = dev_get_drvdata(d);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_pwr *ppwr = nouveau_pwr(drm);
+
+ int usage = nouveau_pwr_perf_get_gr_usage(ppwr);
+ if (usage < 0)
+ return usage;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", usage);
+}
+static DEVICE_ATTR(gr_usage, S_IRUGO, nouveau_sysfs_gr_usage, NULL);
+
+static ssize_t
+nouveau_sysfs_vdec_usage(struct device *d, struct device_attribute *attr,
+ char *buf)
+{
+ struct nouveau_pwr *ppwr = nouveau_pwr(drm_device(d));
+ int usage = nouveau_pwr_perf_get_vdec_usage(ppwr);
+
+ if (usage < 0)
+ return usage;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", usage);
+}
+static DEVICE_ATTR(vdec_usage, S_IRUGO, nouveau_sysfs_vdec_usage, NULL);
+
+static ssize_t
+nouveau_sysfs_mc_usage(struct device *d, struct device_attribute *attr,
+ char *buf)
+{
+ struct nouveau_pwr *ppwr = nouveau_pwr(drm_device(d));
+ int usage = nouveau_pwr_perf_get_mc_usage(ppwr);
+
+ if (usage < 0)
+ return usage;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", usage);
+}
+static DEVICE_ATTR(mc_usage, S_IRUGO, nouveau_sysfs_mc_usage, NULL);
void
nouveau_sysfs_fini(struct drm_device *dev)
{
@@ -161,6 +243,11 @@ nouveau_sysfs_fini(struct drm_device *dev)
nouveau_object_del(nv_object(drm), NVDRM_DEVICE, NVDRM_CONTROL);
}
+ device_remove_file(nv_device_base(device), &dev_attr_usage_polling_period_us);
+ device_remove_file(nv_device_base(device), &dev_attr_gr_usage);
+ device_remove_file(nv_device_base(device), &dev_attr_vdec_usage);
+ device_remove_file(nv_device_base(device), &dev_attr_mc_usage);
+
drm->sysfs = NULL;
kfree(sysfs);
}
@@ -170,6 +257,7 @@ nouveau_sysfs_init(struct drm_device *dev)
{
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_device *device = nv_device(drm->device);
+ struct nouveau_pwr *ppwr = nouveau_pwr(drm->device);
struct nouveau_sysfs *sysfs;
int ret;
@@ -182,5 +270,12 @@ nouveau_sysfs_init(struct drm_device *dev)
if (ret == 0)
device_create_file(nv_device_base(device), &dev_attr_pstate);
+ if (ppwr) {
+ ret = device_create_file(nv_device_base(device), &dev_attr_usage_polling_period_us);
+ device_create_file(nv_device_base(device), &dev_attr_gr_usage);
+ device_create_file(nv_device_base(device), &dev_attr_vdec_usage);
+ device_create_file(nv_device_base(device), &dev_attr_mc_usage);
+ }
+
return 0;
}
diff --git a/nvkm/include/subdev/pwr.h b/nvkm/include/subdev/pwr.h
index f73feec1..ee4b8db2 100644
--- a/nvkm/include/subdev/pwr.h
+++ b/nvkm/include/subdev/pwr.h
@@ -48,4 +48,10 @@ void nouveau_memx_wait(struct nouveau_memx *,
u32 addr, u32 mask, u32 data, u32 nsec);
void nouveau_memx_nsec(struct nouveau_memx *, u32 nsec);
+/* interface to PERF process running on PPWR */
+int nouveau_pwr_perf_set_polling_period(struct nouveau_pwr *, uint32_t us);
+int nouveau_pwr_perf_get_polling_period(struct nouveau_pwr *, uint32_t *us);
+int nouveau_pwr_perf_get_gr_usage(struct nouveau_pwr *);
+int nouveau_pwr_perf_get_vdec_usage(struct nouveau_pwr *);
+int nouveau_pwr_perf_get_mc_usage(struct nouveau_pwr *);
#endif
diff --git a/nvkm/subdev/pwr/Makefile.am b/nvkm/subdev/pwr/Makefile.am
index 2bb4ca66..fde071b8 100644
--- a/nvkm/subdev/pwr/Makefile.am
+++ b/nvkm/subdev/pwr/Makefile.am
@@ -8,6 +8,7 @@ CLEANFILES = ${BUILT_SOURCES}
libpwr_la_SOURCES = base.c \
memx.c \
+ perf.c \
nva3.c \
nvc0.c \
nvd0.c \