diff options
author | Martin Peres <martin.peres@labri.fr> | 2014-06-15 21:34:38 +0200 |
---|---|---|
committer | Martin Peres <martin.peres@labri.fr> | 2014-06-15 23:25:01 +0200 |
commit | c79744f19e8ff656b7c372c08b5ed89724d2a2a6 (patch) | |
tree | 999b4d64c6cf476fddc905c09113badf0bbc01ea | |
parent | 27310fa8fdc39e54a3f4383fada96a3562c5a022 (diff) |
pwr: expose ppwr's performance counters to the userspaceppwr_rework
-rw-r--r-- | drm/Kbuild | 1 | ||||
-rw-r--r-- | drm/nouveau_hwmon.c | 2 | ||||
-rw-r--r-- | drm/nouveau_sysfs.c | 95 | ||||
-rw-r--r-- | nvkm/include/subdev/pwr.h | 6 | ||||
-rw-r--r-- | nvkm/subdev/pwr/Makefile.am | 1 |
5 files changed, 105 insertions, 0 deletions
@@ -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 \ |