diff options
author | Samuel Pitoiset <samuel.pitoiset@gmail.com> | 2015-06-07 22:40:25 +0200 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2015-08-28 04:39:59 +0200 |
commit | 3bfdde178a959cb5e490e4a3a2433c95a9a1af26 (patch) | |
tree | 9f7bb0ae54cae0241b1908dc0af87dcdd3ffc677 /drivers/gpu | |
parent | drm/nouveau/pm: implement NVIF_PERFMON_V0_QUERY_SOURCE method (diff) | |
download | linux-3bfdde178a959cb5e490e4a3a2433c95a9a1af26.tar.xz linux-3bfdde178a959cb5e490e4a3a2433c95a9a1af26.zip |
drm/nouveau/pm: allow the userspace to schedule hardware counters
This adds a new method NVIF_PERFCTR_V0_INIT which starts a batch of
hardware counters for sampling. This will allow the userspace to start
a monitoring session using the INIT method and to stop it with SAMPLE,
for example before and after a frame is rendered.
This commit temporarily breaks nv_perfmon but this is going to be fixed
with the upcoming patch.
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 | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c | 64 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h | 1 |
3 files changed, 48 insertions, 25 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index d85fb0d945e8..528eac8c8403 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -300,8 +300,12 @@ struct nvif_perfctr_v0 { __u8 pad06[4]; }; -#define NVIF_PERFCTR_V0_SAMPLE 0x00 -#define NVIF_PERFCTR_V0_READ 0x01 +#define NVIF_PERFCTR_V0_INIT 0x00 +#define NVIF_PERFCTR_V0_SAMPLE 0x01 +#define NVIF_PERFCTR_V0_READ 0x02 + +struct nvif_perfctr_init { +}; struct nvif_perfctr_sample { }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c index ec02abfd86b0..5dbb3b4e2ebb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c @@ -307,13 +307,43 @@ nvkm_perfmon_ofuncs = { * Perfctr object classes ******************************************************************************/ static int +nvkm_perfctr_init(struct nvkm_object *object, void *data, u32 size) +{ + union { + struct nvif_perfctr_init none; + } *args = data; + struct nvkm_pm *ppm = (void *)object->engine; + struct nvkm_perfctr *ctr = (void *)object; + struct nvkm_perfdom *dom = ctr->dom; + int ret; + + nv_ioctl(object, "perfctr init size %d\n", size); + if (nvif_unvers(args->none)) { + nv_ioctl(object, "perfctr init\n"); + } else + return ret; + + ctr->slot = ffs(dom->quad) - 1; + if (ctr->slot < 0) { + /* no free slots are available */ + return -EINVAL; + } + dom->quad &= ~(QUAD_FREE << ctr->slot); + dom->func->init(ppm, dom, ctr); + + /* start next batch of counters for sampling */ + dom->func->next(ppm, dom); + return 0; +} + +static int nvkm_perfctr_sample(struct nvkm_object *object, void *data, u32 size) { union { struct nvif_perfctr_sample none; } *args = data; struct nvkm_pm *ppm = (void *)object->engine; - struct nvkm_perfctr *ctr, *tmp; + struct nvkm_perfctr *ctr; struct nvkm_perfdom *dom; int ret; @@ -328,32 +358,15 @@ nvkm_perfctr_sample(struct nvkm_object *object, void *data, u32 size) /* sample previous batch of counters */ if (dom->quad != QUAD_MASK) { dom->func->next(ppm, dom); - tmp = NULL; - while (!list_empty(&dom->list)) { - ctr = list_first_entry(&dom->list, - typeof(*ctr), head); - if (ctr->slot < 0) break; - if ( tmp && tmp == ctr) break; - if (!tmp) tmp = ctr; + + /* read counter values */ + list_for_each_entry(ctr, &dom->list, head) { dom->func->read(ppm, dom, ctr); - ctr->slot = -1; - list_move_tail(&ctr->head, &dom->list); + ctr->slot = -1; } - } - - dom->quad = QUAD_MASK; - /* setup next batch of counters for sampling */ - list_for_each_entry(ctr, &dom->list, head) { - ctr->slot = ffs(dom->quad) - 1; - if (ctr->slot < 0) - break; - dom->quad &= ~(QUAD_FREE << ctr->slot); - dom->func->init(ppm, dom, ctr); + dom->quad = QUAD_MASK; } - - if (dom->quad != QUAD_MASK) - dom->func->next(ppm, dom); } return 0; @@ -386,6 +399,8 @@ static int nvkm_perfctr_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size) { switch (mthd) { + case NVIF_PERFCTR_V0_INIT: + return nvkm_perfctr_init(object, data, size); case NVIF_PERFCTR_V0_SAMPLE: return nvkm_perfctr_sample(object, data, size); case NVIF_PERFCTR_V0_READ: @@ -400,6 +415,8 @@ static void nvkm_perfctr_dtor(struct nvkm_object *object) { struct nvkm_perfctr *ctr = (void *)object; + if (ctr->dom) + ctr->dom->quad |= (QUAD_FREE << ctr->slot); if (ctr->head.next) list_del(&ctr->head); nvkm_object_destroy(&ctr->base); @@ -441,6 +458,7 @@ nvkm_perfctr_ctor(struct nvkm_object *parent, struct nvkm_object *engine, if (ret) return ret; + ctr->dom = dom; ctr->slot = -1; ctr->logic_op = args->v0.logic_op; ctr->signal[0] = sig[0]; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h index f954c9868594..4ed77ff4922c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h @@ -6,6 +6,7 @@ struct nvkm_perfctr { struct nvkm_object base; struct list_head head; struct nvkm_perfsig *signal[4]; + struct nvkm_perfdom *dom; int slot; u32 logic_op; u32 clk; |