diff options
author | Samuel Pitoiset <samuel.pitoiset@gmail.com> | 2015-06-07 22:40:24 +0200 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2015-08-28 12:39:59 +1000 |
commit | 6f99c84873f455a76a0356061b276bc0c89b5d92 (patch) | |
tree | fd5d422d7063241f9a3d73b19e043656c7c05281 /drivers/gpu | |
parent | 50d138d7528c3370ebf3a54079091a35a60a23be (diff) | |
download | blackbird-op-linux-6f99c84873f455a76a0356061b276bc0c89b5d92.tar.gz blackbird-op-linux-6f99c84873f455a76a0356061b276bc0c89b5d92.zip |
drm/nouveau/pm: implement NVIF_PERFMON_V0_QUERY_SOURCE method
This allows to query the ID, the mask and the user-readable name of
sources for each signal.
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvif/class.h | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c | 77 |
2 files changed, 89 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index caae193f354e..d85fb0d945e8 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -253,6 +253,7 @@ struct gf110_dma_v0 { #define NVIF_PERFMON_V0_QUERY_DOMAIN 0x00 #define NVIF_PERFMON_V0_QUERY_SIGNAL 0x01 +#define NVIF_PERFMON_V0_QUERY_SOURCE 0x02 struct nvif_perfmon_query_domain_v0 { __u8 version; @@ -273,6 +274,17 @@ struct nvif_perfmon_query_signal_v0 { char name[64]; }; +struct nvif_perfmon_query_source_v0 { + __u8 version; + __u8 domain; + __u8 signal; + __u8 iter; + __u8 pad04[4]; + __u32 source; + __u32 mask; + char name[64]; +}; + /******************************************************************************* * perfctr diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c index a9c57a20186a..ec02abfd86b0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c @@ -103,6 +103,31 @@ nvkm_perfsig_count_perfsrc(struct nvkm_perfsig *sig) return source_nr; } +static struct nvkm_perfsrc * +nvkm_perfsrc_find(struct nvkm_pm *ppm, struct nvkm_perfsig *sig, int si) +{ + struct nvkm_perfsrc *src; + bool found = false; + int tmp = 1; /* Sources ID start from 1 */ + u8 i; + + for (i = 0; i < ARRAY_SIZE(sig->source) && sig->source[i]; i++) { + if (sig->source[i] == si) { + found = true; + break; + } + } + + if (found) { + list_for_each_entry(src, &ppm->sources, head) { + if (tmp++ == si) + return src; + } + } + + return NULL; +} + /******************************************************************************* * Perfmon object classes ******************************************************************************/ @@ -204,6 +229,56 @@ nvkm_perfmon_mthd_query_signal(struct nvkm_object *object, void *data, u32 size) } static int +nvkm_perfmon_mthd_query_source(struct nvkm_object *object, void *data, u32 size) +{ + union { + struct nvif_perfmon_query_source_v0 v0; + } *args = data; + struct nvkm_pm *ppm = (void *)object->engine; + struct nvkm_perfdom *dom = NULL; + struct nvkm_perfsig *sig; + struct nvkm_perfsrc *src; + u8 source_nr = 0; + int si, ret; + + nv_ioctl(object, "perfmon query source size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, + "perfmon source vers %d dom %d sig %02x iter %02x\n", + args->v0.version, args->v0.domain, args->v0.signal, + args->v0.iter); + si = (args->v0.iter & 0xff) - 1; + } else + return ret; + + sig = nvkm_perfsig_find(ppm, args->v0.domain, args->v0.signal, &dom); + if (!sig) + return -EINVAL; + + source_nr = nvkm_perfsig_count_perfsrc(sig); + if (si >= (int)source_nr) + return -EINVAL; + + if (si >= 0) { + src = nvkm_perfsrc_find(ppm, sig, sig->source[si]); + if (!src) + return -EINVAL; + + args->v0.source = sig->source[si]; + args->v0.mask = src->mask; + strncpy(args->v0.name, src->name, sizeof(args->v0.name)); + } + + if (++si < source_nr) { + args->v0.iter = ++si; + return 0; + } + + args->v0.iter = 0xff; + return 0; +} + +static int nvkm_perfmon_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size) { switch (mthd) { @@ -211,6 +286,8 @@ nvkm_perfmon_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size) return nvkm_perfmon_mthd_query_domain(object, data, size); case NVIF_PERFMON_V0_QUERY_SIGNAL: return nvkm_perfmon_mthd_query_signal(object, data, size); + case NVIF_PERFMON_V0_QUERY_SOURCE: + return nvkm_perfmon_mthd_query_source(object, data, size); default: break; } |