All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 00/20] expose global performance counters
@ 2015-06-07 20:40 Samuel Pitoiset
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Hello,

This series exposes global performance counters (PCOUNTER) to the userspace
through the nvif interface by reworking most of the code related to the PM
engine.

This interface will allow the userspace to control and monitor complex hardware
events like the proprietary driver already does, for example with CUPTI and
PerfKit.

For now, this series only exposes performance counters on NV50, but this is
going to be pretty similar for other families. My plan is to submit more
patches for Fermi and Kepler after this series will be reviewed.

The code of this series can be found here:

http://cgit.freedesktop.org/~hakzsam/nouveau/log/?h=nouveau_perfmon

And the corresponding libdrm branch can be found here:

http://cgit.freedesktop.org/~hakzsam/drm/log/?h=nouveau_perfmon

A full example which exposes both compute and graphics hardware events on NV50
can be found here:

http://cgit.freedesktop.org/~hakzsam/perfevent

Most of the code will be implemented in mesa once the kernel interface is
going to be upstream and stable.

Below, you can find a summary of the series:

Patches 1-2:	fix a bug related to the PM engine context
Patches 3-4:	remove useless PMU signals and unused functions
Patches 5-6:	reorganize the nvif interface to expose more stuff
Patches 7-11:	expose PCOUNTER domains to the userspace
Patches 12-14:	implement concept of sources (ie. multiplexers)
Patches 15-17:	allow to monitor complex hardware events
Patches 18:	add compute/graphics signals/sources
Patches 19-20:  expose a software methods interface for controlling PM

Feel free to make a review.
Thanks in advance!

Samuel Pitoiset (20):
  pm: prevent freeing the wrong engine context
  pm: fix a potential race condition when creating an engine context
  pm: remove pmu signals
  pm: remove unused nvkm_perfsig_wrap() function
  pm: reorganize the nvif interface
  pm: prevent creating a perfctr object when signals are not found
  pm: implement NVIF_PERFMON_V0_QUERY_DOMAIN method
  pm: allow to query signals by domain
  pm: change signal iter to u16
  pm: use hardware signals indexes instead of user-readable names
  pm: allow to monitor hardware signal index 0x00
  pm: add concept of sources
  pm: allow to query the number of sources for a signal
  pm: implement NVIF_PERFMON_V0_QUERY_SOURCE method
  pm: allow the userspace to schedule hardware counters
  pm: allow to configure domains instead of simple counters
  pm: allow the userspace to configure sources
  pm/nv50: add compute and graphics signals/sources
  sw/nv50: add some private functions to factorize code
  sw/nv50: add and interface for controlling performance counters

 bin/nv_perfmon.c                      | 324 ++++++++++++----
 drm/nouveau/include/nvif/class.h      |  68 +++-
 drm/nouveau/include/nvif/ioctl.h      |   5 +-
 drm/nouveau/include/nvkm/engine/pm.h  |   6 +-
 drm/nouveau/nvkm/engine/device/nv50.c |   2 +-
 drm/nouveau/nvkm/engine/pm/Kbuild     |   2 +-
 drm/nouveau/nvkm/engine/pm/base.c     | 685 +++++++++++++++++++++++++---------
 drm/nouveau/nvkm/engine/pm/daemon.c   | 108 ------
 drm/nouveau/nvkm/engine/pm/g84.c      | 101 ++++-
 drm/nouveau/nvkm/engine/pm/gf100.c    |  13 +-
 drm/nouveau/nvkm/engine/pm/gk104.c    |   6 -
 drm/nouveau/nvkm/engine/pm/gk110.c    |   4 -
 drm/nouveau/nvkm/engine/pm/gt200.c    | 163 ++++++++
 drm/nouveau/nvkm/engine/pm/gt215.c    | 104 ++++--
 drm/nouveau/nvkm/engine/pm/nv40.c     |   8 +-
 drm/nouveau/nvkm/engine/pm/nv50.c     | 136 ++++++-
 drm/nouveau/nvkm/engine/pm/priv.h     |  53 ++-
 drm/nouveau/nvkm/engine/sw/nv50.c     | 216 ++++++++++-
 drm/nouveau/nvkm/engine/sw/nv50.h     |   6 +
 19 files changed, 1561 insertions(+), 449 deletions(-)
 delete mode 100644 drm/nouveau/nvkm/engine/pm/daemon.c
 create mode 100644 drm/nouveau/nvkm/engine/pm/gt200.c

-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH RFC 01/20] pm: prevent freeing the wrong engine context
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2015-06-07 20:40   ` Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 02/20] pm: fix a potential race condition when creating an " Samuel Pitoiset
                     ` (18 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

This fixes a crash when multiple PM engine contexts are created.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Martin Peres <martin.peres@free.fr>
---
 drm/nouveau/nvkm/engine/pm/base.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drm/nouveau/nvkm/engine/pm/base.c b/drm/nouveau/nvkm/engine/pm/base.c
index 2006c44..274457c 100644
--- a/drm/nouveau/nvkm/engine/pm/base.c
+++ b/drm/nouveau/nvkm/engine/pm/base.c
@@ -332,9 +332,12 @@ static void
 nvkm_perfctx_dtor(struct nvkm_object *object)
 {
 	struct nvkm_pm *ppm = (void *)object->engine;
+	struct nvkm_perfctx *ctx = (void *)object;
+
 	mutex_lock(&nv_subdev(ppm)->mutex);
-	nvkm_engctx_destroy(&ppm->context->base);
-	ppm->context = NULL;
+	nvkm_engctx_destroy(&ctx->base);
+	if (ppm->context == ctx)
+		ppm->context = NULL;
 	mutex_unlock(&nv_subdev(ppm)->mutex);
 }
 
-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH RFC 02/20] pm: fix a potential race condition when creating an engine context
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2015-06-07 20:40   ` [PATCH RFC 01/20] pm: prevent freeing the wrong engine context Samuel Pitoiset
@ 2015-06-07 20:40   ` Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 03/20] pm: remove pmu signals Samuel Pitoiset
                     ` (17 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

There is always the possiblity that the ppm->context pointer would get
partially updated and accidentally would equal ctx. This would allow two
contexts to co-exist, which is not acceptable. Moving the test to the
critical section takes care of this problem.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Signed-off-by: Martin Peres <martin.peres@free.fr>
---
 drm/nouveau/nvkm/engine/pm/base.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drm/nouveau/nvkm/engine/pm/base.c b/drm/nouveau/nvkm/engine/pm/base.c
index 274457c..4cf36a3 100644
--- a/drm/nouveau/nvkm/engine/pm/base.c
+++ b/drm/nouveau/nvkm/engine/pm/base.c
@@ -358,12 +358,11 @@ nvkm_perfctx_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	mutex_lock(&nv_subdev(ppm)->mutex);
 	if (ppm->context == NULL)
 		ppm->context = ctx;
-	mutex_unlock(&nv_subdev(ppm)->mutex);
-
 	if (ctx != ppm->context)
-		return -EBUSY;
+		ret = -EBUSY;
+	mutex_unlock(&nv_subdev(ppm)->mutex);
 
-	return 0;
+	return ret;
 }
 
 struct nvkm_oclass
-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH RFC 03/20] pm: remove pmu signals
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2015-06-07 20:40   ` [PATCH RFC 01/20] pm: prevent freeing the wrong engine context Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 02/20] pm: fix a potential race condition when creating an " Samuel Pitoiset
@ 2015-06-07 20:40   ` Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 04/20] pm: remove unused nvkm_perfsig_wrap() function Samuel Pitoiset
                     ` (16 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

PDAEMON signals don't have to be exposed by the perfmon engine.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Martin Peres <martin.peres@free.fr>
---
 drm/nouveau/include/nvkm/engine/pm.h |   4 --
 drm/nouveau/nvkm/engine/pm/Kbuild    |   1 -
 drm/nouveau/nvkm/engine/pm/daemon.c  | 108 -----------------------------------
 drm/nouveau/nvkm/engine/pm/gf100.c   |   5 --
 drm/nouveau/nvkm/engine/pm/gk104.c   |   6 --
 drm/nouveau/nvkm/engine/pm/gk110.c   |   4 --
 drm/nouveau/nvkm/engine/pm/gt215.c   |  20 +------
 drm/nouveau/nvkm/engine/pm/priv.h    |   4 --
 8 files changed, 1 insertion(+), 151 deletions(-)
 delete mode 100644 drm/nouveau/nvkm/engine/pm/daemon.c

diff --git a/drm/nouveau/include/nvkm/engine/pm.h b/drm/nouveau/include/nvkm/engine/pm.h
index 93181bb..6c2d057 100644
--- a/drm/nouveau/include/nvkm/engine/pm.h
+++ b/drm/nouveau/include/nvkm/engine/pm.h
@@ -12,10 +12,6 @@ struct nvkm_pm {
 
 	struct list_head domains;
 	u32 sequence;
-
-	/*XXX: temp for daemon backend */
-	u32 pwr[8];
-	u32 last;
 };
 
 static inline struct nvkm_pm *
diff --git a/drm/nouveau/nvkm/engine/pm/Kbuild b/drm/nouveau/nvkm/engine/pm/Kbuild
index 413b609..c5ee8d5 100644
--- a/drm/nouveau/nvkm/engine/pm/Kbuild
+++ b/drm/nouveau/nvkm/engine/pm/Kbuild
@@ -1,5 +1,4 @@
 nvkm-y += nvkm/engine/pm/base.o
-nvkm-y += nvkm/engine/pm/daemon.o
 nvkm-y += nvkm/engine/pm/nv40.o
 nvkm-y += nvkm/engine/pm/nv50.o
 nvkm-y += nvkm/engine/pm/g84.o
diff --git a/drm/nouveau/nvkm/engine/pm/daemon.c b/drm/nouveau/nvkm/engine/pm/daemon.c
deleted file mode 100644
index a7a5f3a..0000000
--- a/drm/nouveau/nvkm/engine/pm/daemon.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright 2013 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "priv.h"
-
-static void
-pwr_perfctr_init(struct nvkm_pm *ppm, struct nvkm_perfdom *dom,
-		 struct nvkm_perfctr *ctr)
-{
-	u32 mask = 0x00000000;
-	u32 ctrl = 0x00000001;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(ctr->signal) && ctr->signal[i]; i++)
-		mask |= 1 << (ctr->signal[i] - dom->signal);
-
-	nv_wr32(ppm, 0x10a504 + (ctr->slot * 0x10), mask);
-	nv_wr32(ppm, 0x10a50c + (ctr->slot * 0x10), ctrl);
-	nv_wr32(ppm, 0x10a50c + (ppm->last * 0x10), 0x00000003);
-}
-
-static void
-pwr_perfctr_read(struct nvkm_pm *ppm, struct nvkm_perfdom *dom,
-		 struct nvkm_perfctr *ctr)
-{
-	ctr->ctr = ppm->pwr[ctr->slot];
-	ctr->clk = ppm->pwr[ppm->last];
-}
-
-static void
-pwr_perfctr_next(struct nvkm_pm *ppm, struct nvkm_perfdom *dom)
-{
-	int i;
-
-	for (i = 0; i <= ppm->last; i++) {
-		ppm->pwr[i] = nv_rd32(ppm, 0x10a508 + (i * 0x10));
-		nv_wr32(ppm, 0x10a508 + (i * 0x10), 0x80000000);
-	}
-}
-
-static const struct nvkm_funcdom
-pwr_perfctr_func = {
-	.init = pwr_perfctr_init,
-	.read = pwr_perfctr_read,
-	.next = pwr_perfctr_next,
-};
-
-const struct nvkm_specdom
-gt215_pm_pwr[] = {
-	{ 0x20, (const struct nvkm_specsig[]) {
-			{ 0x00, "pwr_gr_idle" },
-			{ 0x04, "pwr_bsp_idle" },
-			{ 0x05, "pwr_vp_idle" },
-			{ 0x06, "pwr_ppp_idle" },
-			{ 0x13, "pwr_ce0_idle" },
-			{}
-		}, &pwr_perfctr_func },
-	{}
-};
-
-const struct nvkm_specdom
-gf100_pm_pwr[] = {
-	{ 0x20, (const struct nvkm_specsig[]) {
-			{ 0x00, "pwr_gr_idle" },
-			{ 0x04, "pwr_bsp_idle" },
-			{ 0x05, "pwr_vp_idle" },
-			{ 0x06, "pwr_ppp_idle" },
-			{ 0x13, "pwr_ce0_idle" },
-			{ 0x14, "pwr_ce1_idle" },
-			{}
-		}, &pwr_perfctr_func },
-	{}
-};
-
-const struct nvkm_specdom
-gk104_pm_pwr[] = {
-	{ 0x20, (const struct nvkm_specsig[]) {
-			{ 0x00, "pwr_gr_idle" },
-			{ 0x04, "pwr_bsp_idle" },
-			{ 0x05, "pwr_vp_idle" },
-			{ 0x06, "pwr_ppp_idle" },
-			{ 0x13, "pwr_ce0_idle" },
-			{ 0x14, "pwr_ce1_idle" },
-			{ 0x15, "pwr_ce2_idle" },
-			{}
-		}, &pwr_perfctr_func },
-	{}
-};
diff --git a/drm/nouveau/nvkm/engine/pm/gf100.c b/drm/nouveau/nvkm/engine/pm/gf100.c
index 008fed7..69303b5 100644
--- a/drm/nouveau/nvkm/engine/pm/gf100.c
+++ b/drm/nouveau/nvkm/engine/pm/gf100.c
@@ -111,10 +111,6 @@ gf100_pm_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	if (ret)
 		return ret;
 
-	ret = nvkm_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0, gf100_pm_pwr);
-	if (ret)
-		return ret;
-
 	/* HUB */
 	ret = nvkm_perfdom_new(&priv->base, "hub", 0, 0x1b0000, 0, 0x200,
 			       gf100_pm_hub);
@@ -143,7 +139,6 @@ gf100_pm_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 
 	nv_engine(priv)->cclass = &nvkm_pm_cclass;
 	nv_engine(priv)->sclass =  nvkm_pm_sclass;
-	priv->base.last = 7;
 	return 0;
 }
 
diff --git a/drm/nouveau/nvkm/engine/pm/gk104.c b/drm/nouveau/nvkm/engine/pm/gk104.c
index 75b9ff3..3565f29 100644
--- a/drm/nouveau/nvkm/engine/pm/gk104.c
+++ b/drm/nouveau/nvkm/engine/pm/gk104.c
@@ -99,11 +99,6 @@ gk104_pm_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	if (ret)
 		return ret;
 
-	/* PDAEMON */
-	ret = nvkm_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0, gk104_pm_pwr);
-	if (ret)
-		return ret;
-
 	/* HUB */
 	ret = nvkm_perfdom_new(&priv->base, "hub", 0, 0x1b0000, 0, 0x200,
 			       gk104_pm_hub);
@@ -132,7 +127,6 @@ gk104_pm_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 
 	nv_engine(priv)->cclass = &nvkm_pm_cclass;
 	nv_engine(priv)->sclass =  nvkm_pm_sclass;
-	priv->base.last = 7;
 	return 0;
 }
 
diff --git a/drm/nouveau/nvkm/engine/pm/gk110.c b/drm/nouveau/nvkm/engine/pm/gk110.c
index 6820176..8373cd8 100644
--- a/drm/nouveau/nvkm/engine/pm/gk110.c
+++ b/drm/nouveau/nvkm/engine/pm/gk110.c
@@ -36,10 +36,6 @@ gk110_pm_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	if (ret)
 		return ret;
 
-	ret = nvkm_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0, gk104_pm_pwr);
-	if (ret)
-		return ret;
-
 	nv_engine(priv)->cclass = &nvkm_pm_cclass;
 	nv_engine(priv)->sclass =  nvkm_pm_sclass;
 	return 0;
diff --git a/drm/nouveau/nvkm/engine/pm/gt215.c b/drm/nouveau/nvkm/engine/pm/gt215.c
index d065bfc..ab69ab5 100644
--- a/drm/nouveau/nvkm/engine/pm/gt215.c
+++ b/drm/nouveau/nvkm/engine/pm/gt215.c
@@ -52,29 +52,11 @@ gt215_pm[] = {
 	{}
 };
 
-static int
-gt215_pm_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
-	      struct nvkm_oclass *oclass, void *data, u32 size,
-	      struct nvkm_object **object)
-{
-	int ret = nv40_pm_ctor(parent, engine, oclass, data, size, object);
-	if (ret == 0) {
-		struct nv40_pm_priv *priv = (void *)*object;
-		ret = nvkm_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0,
-				       gt215_pm_pwr);
-		if (ret)
-			return ret;
-
-		priv->base.last = 3;
-	}
-	return ret;
-}
-
 struct nvkm_oclass *
 gt215_pm_oclass = &(struct nv40_pm_oclass) {
 	.base.handle = NV_ENGINE(PM, 0xa3),
 	.base.ofuncs = &(struct nvkm_ofuncs) {
-		.ctor = gt215_pm_ctor,
+		.ctor = nv40_pm_ctor,
 		.dtor = _nvkm_pm_dtor,
 		.init = _nvkm_pm_init,
 		.fini = _nvkm_pm_fini,
diff --git a/drm/nouveau/nvkm/engine/pm/priv.h b/drm/nouveau/nvkm/engine/pm/priv.h
index 1e6eff2..95796c7 100644
--- a/drm/nouveau/nvkm/engine/pm/priv.h
+++ b/drm/nouveau/nvkm/engine/pm/priv.h
@@ -41,10 +41,6 @@ struct nvkm_specdom {
 	const struct nvkm_funcdom *func;
 };
 
-extern const struct nvkm_specdom gt215_pm_pwr[];
-extern const struct nvkm_specdom gf100_pm_pwr[];
-extern const struct nvkm_specdom gk104_pm_pwr[];
-
 struct nvkm_perfdom {
 	struct list_head head;
 	struct list_head list;
-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH RFC 04/20] pm: remove unused nvkm_perfsig_wrap() function
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (2 preceding siblings ...)
  2015-06-07 20:40   ` [PATCH RFC 03/20] pm: remove pmu signals Samuel Pitoiset
@ 2015-06-07 20:40   ` Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 05/20] pm: reorganize the nvif interface Samuel Pitoiset
                     ` (15 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Martin Peres <martin.peres@free.fr>
---
 drm/nouveau/nvkm/engine/pm/base.c | 20 --------------------
 drm/nouveau/nvkm/engine/pm/priv.h |  4 ----
 2 files changed, 24 deletions(-)

diff --git a/drm/nouveau/nvkm/engine/pm/base.c b/drm/nouveau/nvkm/engine/pm/base.c
index 4cf36a3..7b07e8b 100644
--- a/drm/nouveau/nvkm/engine/pm/base.c
+++ b/drm/nouveau/nvkm/engine/pm/base.c
@@ -79,26 +79,6 @@ nvkm_perfsig_find(struct nvkm_pm *ppm, const char *name, u32 size,
 	return nvkm_perfsig_find_(dom, name, size);
 }
 
-struct nvkm_perfctr *
-nvkm_perfsig_wrap(struct nvkm_pm *ppm, const char *name,
-		  struct nvkm_perfdom **pdom)
-{
-	struct nvkm_perfsig *sig;
-	struct nvkm_perfctr *ctr;
-
-	sig = nvkm_perfsig_find(ppm, name, strlen(name), pdom);
-	if (!sig)
-		return NULL;
-
-	ctr = kzalloc(sizeof(*ctr), GFP_KERNEL);
-	if (ctr) {
-		ctr->signal[0] = sig;
-		ctr->logic_op = 0xaaaa;
-	}
-
-	return ctr;
-}
-
 /*******************************************************************************
  * Perfmon object classes
  ******************************************************************************/
diff --git a/drm/nouveau/nvkm/engine/pm/priv.h b/drm/nouveau/nvkm/engine/pm/priv.h
index 95796c7..06a6e60 100644
--- a/drm/nouveau/nvkm/engine/pm/priv.h
+++ b/drm/nouveau/nvkm/engine/pm/priv.h
@@ -31,10 +31,6 @@ struct nvkm_perfsig {
 	const char *name;
 };
 
-struct nvkm_perfdom;
-struct nvkm_perfctr *
-nvkm_perfsig_wrap(struct nvkm_pm *, const char *, struct nvkm_perfdom **);
-
 struct nvkm_specdom {
 	u16 signal_nr;
 	const struct nvkm_specsig *signal;
-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH RFC 05/20] pm: reorganize the nvif interface
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (3 preceding siblings ...)
  2015-06-07 20:40   ` [PATCH RFC 04/20] pm: remove unused nvkm_perfsig_wrap() function Samuel Pitoiset
@ 2015-06-07 20:40   ` Samuel Pitoiset
       [not found]     ` <1433709630-3293-6-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2015-06-07 20:40   ` [PATCH RFC 06/20] pm: prevent creating a perfctr object when signals are not found Samuel Pitoiset
                     ` (14 subsequent siblings)
  19 siblings, 1 reply; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

This commit introduces the NVIF_IOCTL_NEW_V0_PERFMON class which will be
used in order to query domains, signals and sources. This separates the
querying and the counting interface.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
---
 bin/nv_perfmon.c                  | 12 ++++++------
 drm/nouveau/include/nvif/class.h  | 26 ++++++++++++++++----------
 drm/nouveau/include/nvif/ioctl.h  |  5 +++--
 drm/nouveau/nvkm/engine/pm/base.c | 38 ++++++++++++++++++++++++++++++++------
 4 files changed, 57 insertions(+), 24 deletions(-)

diff --git a/bin/nv_perfmon.c b/bin/nv_perfmon.c
index a8c5838..30a3138 100644
--- a/bin/nv_perfmon.c
+++ b/bin/nv_perfmon.c
@@ -600,7 +600,7 @@ main(int argc, char **argv)
 	const char *cfg = NULL;
 	const char *dbg = "error";
 	u64 dev = ~0ULL;
-	struct nvif_perfctr_query_v0 args = {};
+	struct nvif_perfmon_query_signal_v0 args = {};
 	struct nvif_client *client;
 	struct nvif_object object;
 	int ret, c, k;
@@ -644,15 +644,14 @@ main(int argc, char **argv)
 	}
 
 	ret = nvif_object_init(nvif_object(device), NULL, 0xdeadbeef,
-			       NVIF_IOCTL_NEW_V0_PERFCTR,
-			       &(struct nvif_perfctr_v0) {
-			       }, sizeof(struct nvif_perfctr_v0), &object);
+			       NVIF_IOCTL_NEW_V0_PERFMON, NULL, 0, &object);
 	assert(ret == 0);
 	do {
 		u32 prev_iter = args.iter;
 
 		args.name[0] = '\0';
-		ret = nvif_mthd(&object, NVIF_PERFCTR_V0_QUERY, &args, sizeof(args));
+		ret = nvif_mthd(&object, NVIF_PERFMON_V0_QUERY_SIGNAL,
+				&args, sizeof(args));
 		assert(ret == 0);
 
 		if (prev_iter) {
@@ -663,7 +662,8 @@ main(int argc, char **argv)
 			args.iter = prev_iter;
 			strncpy(signals[nr_signals - 1], args.name,
 				sizeof(args.name));
-			ret = nvif_mthd(&object, NVIF_PERFCTR_V0_QUERY, &args, sizeof(args));
+			ret = nvif_mthd(&object, NVIF_PERFMON_V0_QUERY_SIGNAL,
+					&args, sizeof(args));
 			assert(ret == 0);
 		}
 	} while (args.iter != 0xffffffff);
diff --git a/drm/nouveau/include/nvif/class.h b/drm/nouveau/include/nvif/class.h
index 64f8b2f..11935a0 100644
--- a/drm/nouveau/include/nvif/class.h
+++ b/drm/nouveau/include/nvif/class.h
@@ -251,6 +251,20 @@ struct gf110_dma_v0 {
  * perfmon
  ******************************************************************************/
 
+#define NVIF_PERFMON_V0_QUERY_SIGNAL                                       0x00
+
+struct nvif_perfmon_query_signal_v0 {
+	__u8  version;
+	__u8  pad01[3];
+	__u32 iter;
+	char  name[64];
+};
+
+
+/*******************************************************************************
+ * perfctr
+ ******************************************************************************/
+
 struct nvif_perfctr_v0 {
 	__u8  version;
 	__u8  pad01[1];
@@ -259,16 +273,8 @@ struct nvif_perfctr_v0 {
 	char  name[4][64];
 };
 
-#define NVIF_PERFCTR_V0_QUERY                                              0x00
-#define NVIF_PERFCTR_V0_SAMPLE                                             0x01
-#define NVIF_PERFCTR_V0_READ                                               0x02
-
-struct nvif_perfctr_query_v0 {
-	__u8  version;
-	__u8  pad01[3];
-	__u32 iter;
-	char  name[64];
-};
+#define NVIF_PERFCTR_V0_SAMPLE                                             0x00
+#define NVIF_PERFCTR_V0_READ                                               0x01
 
 struct nvif_perfctr_sample {
 };
diff --git a/drm/nouveau/include/nvif/ioctl.h b/drm/nouveau/include/nvif/ioctl.h
index 4cd8e32..517cd27 100644
--- a/drm/nouveau/include/nvif/ioctl.h
+++ b/drm/nouveau/include/nvif/ioctl.h
@@ -49,8 +49,9 @@ struct nvif_ioctl_new_v0 {
 	__u64 token;
 	__u32 handle;
 /* these class numbers are made up by us, and not nvidia-assigned */
-#define NVIF_IOCTL_NEW_V0_PERFCTR                                    0x0000ffff
-#define NVIF_IOCTL_NEW_V0_CONTROL                                    0x0000fffe
+#define NVIF_IOCTL_NEW_V0_PERFMON                                    0x0000ffff
+#define NVIF_IOCTL_NEW_V0_PERFCTR                                    0x0000fffe
+#define NVIF_IOCTL_NEW_V0_CONTROL                                    0x0000fffd
 	__u32 oclass;
 	__u8  data[];		/* class data (class.h) */
 };
diff --git a/drm/nouveau/nvkm/engine/pm/base.c b/drm/nouveau/nvkm/engine/pm/base.c
index 7b07e8b..cb88170 100644
--- a/drm/nouveau/nvkm/engine/pm/base.c
+++ b/drm/nouveau/nvkm/engine/pm/base.c
@@ -83,10 +83,10 @@ nvkm_perfsig_find(struct nvkm_pm *ppm, const char *name, u32 size,
  * Perfmon object classes
  ******************************************************************************/
 static int
-nvkm_perfctr_query(struct nvkm_object *object, void *data, u32 size)
+nvkm_perfmon_mthd_query_signal(struct nvkm_object *object, void *data, u32 size)
 {
 	union {
-		struct nvif_perfctr_query_v0 v0;
+		struct nvif_perfmon_query_signal_v0 v0;
 	} *args = data;
 	struct nvkm_device *device = nv_device(object);
 	struct nvkm_pm *ppm = (void *)object->engine;
@@ -97,9 +97,9 @@ nvkm_perfctr_query(struct nvkm_object *object, void *data, u32 size)
 	int tmp = 0, di, si;
 	int ret;
 
-	nv_ioctl(object, "perfctr query size %d\n", size);
+	nv_ioctl(object, "perfmon query signal size %d\n", size);
 	if (nvif_unpack(args->v0, 0, 0, false)) {
-		nv_ioctl(object, "perfctr query vers %d iter %08x\n",
+		nv_ioctl(object, "perfmon query signal vers %d iter %08x\n",
 			 args->v0.version, args->v0.iter);
 		di = (args->v0.iter & 0xff000000) >> 24;
 		si = (args->v0.iter & 0x00ffffff) - 1;
@@ -142,6 +142,30 @@ nvkm_perfctr_query(struct nvkm_object *object, void *data, u32 size)
 }
 
 static int
+nvkm_perfmon_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
+{
+	switch (mthd) {
+	case NVIF_PERFMON_V0_QUERY_SIGNAL:
+		return nvkm_perfmon_mthd_query_signal(object, data, size);
+	default:
+		break;
+	}
+	return -EINVAL;
+}
+
+static struct nvkm_ofuncs
+nvkm_perfmon_ofuncs = {
+	.ctor = _nvkm_object_ctor,
+	.dtor = nvkm_object_destroy,
+	.init = nvkm_object_init,
+	.fini = nvkm_object_fini,
+	.mthd = nvkm_perfmon_mthd,
+};
+
+/*******************************************************************************
+ * Perfctr object classes
+ ******************************************************************************/
+static int
 nvkm_perfctr_sample(struct nvkm_object *object, void *data, u32 size)
 {
 	union {
@@ -221,8 +245,6 @@ static int
 nvkm_perfctr_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
 {
 	switch (mthd) {
-	case NVIF_PERFCTR_V0_QUERY:
-		return nvkm_perfctr_query(object, data, size);
 	case NVIF_PERFCTR_V0_SAMPLE:
 		return nvkm_perfctr_sample(object, data, size);
 	case NVIF_PERFCTR_V0_READ:
@@ -299,6 +321,10 @@ nvkm_perfctr_ofuncs = {
 
 struct nvkm_oclass
 nvkm_pm_sclass[] = {
+	{
+	  .handle = NVIF_IOCTL_NEW_V0_PERFMON,
+	  .ofuncs = &nvkm_perfmon_ofuncs,
+	},
 	{ .handle = NVIF_IOCTL_NEW_V0_PERFCTR,
 	  .ofuncs = &nvkm_perfctr_ofuncs,
 	},
-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH RFC 06/20] pm: prevent creating a perfctr object when signals are not found
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (4 preceding siblings ...)
  2015-06-07 20:40   ` [PATCH RFC 05/20] pm: reorganize the nvif interface Samuel Pitoiset
@ 2015-06-07 20:40   ` Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 07/20] pm: implement NVIF_PERFMON_V0_QUERY_DOMAIN method Samuel Pitoiset
                     ` (13 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Since a new class has been introduced to query signals, we can now
return an error when the userspace wants to monitor unknown signals.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
---
 drm/nouveau/nvkm/engine/pm/base.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drm/nouveau/nvkm/engine/pm/base.c b/drm/nouveau/nvkm/engine/pm/base.c
index cb88170..2f85147 100644
--- a/drm/nouveau/nvkm/engine/pm/base.c
+++ b/drm/nouveau/nvkm/engine/pm/base.c
@@ -294,6 +294,9 @@ nvkm_perfctr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 			return -EINVAL;
 	}
 
+	if (!dom)
+		return -EINVAL;
+
 	ret = nvkm_object_create(parent, engine, oclass, 0, &ctr);
 	*pobject = nv_object(ctr);
 	if (ret)
@@ -305,8 +308,7 @@ nvkm_perfctr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	ctr->signal[1] = sig[1];
 	ctr->signal[2] = sig[2];
 	ctr->signal[3] = sig[3];
-	if (dom)
-		list_add_tail(&ctr->head, &dom->list);
+	list_add_tail(&ctr->head, &dom->list);
 	return 0;
 }
 
-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH RFC 07/20] pm: implement NVIF_PERFMON_V0_QUERY_DOMAIN method
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (5 preceding siblings ...)
  2015-06-07 20:40   ` [PATCH RFC 06/20] pm: prevent creating a perfctr object when signals are not found Samuel Pitoiset
@ 2015-06-07 20:40   ` Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 08/20] pm: allow to query signals by domain Samuel Pitoiset
                     ` (12 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

This allows to query the number of available domains, including the
number of hardware counter and the number of signals per domain.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
---
 drm/nouveau/include/nvif/class.h  | 11 ++++-
 drm/nouveau/nvkm/engine/pm/base.c | 86 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 96 insertions(+), 1 deletion(-)

diff --git a/drm/nouveau/include/nvif/class.h b/drm/nouveau/include/nvif/class.h
index 11935a0..0b28929 100644
--- a/drm/nouveau/include/nvif/class.h
+++ b/drm/nouveau/include/nvif/class.h
@@ -251,7 +251,16 @@ struct gf110_dma_v0 {
  * perfmon
  ******************************************************************************/
 
-#define NVIF_PERFMON_V0_QUERY_SIGNAL                                       0x00
+#define NVIF_PERFMON_V0_QUERY_DOMAIN                                       0x00
+#define NVIF_PERFMON_V0_QUERY_SIGNAL                                       0x01
+
+struct nvif_perfmon_query_domain_v0 {
+	__u8  version;
+	__u8  id;
+	__u8  counter_nr;
+	__u8  iter;
+	__u32 signal_nr;
+};
 
 struct nvif_perfmon_query_signal_v0 {
 	__u8  version;
diff --git a/drm/nouveau/nvkm/engine/pm/base.c b/drm/nouveau/nvkm/engine/pm/base.c
index 2f85147..3d9bcbc 100644
--- a/drm/nouveau/nvkm/engine/pm/base.c
+++ b/drm/nouveau/nvkm/engine/pm/base.c
@@ -34,6 +34,45 @@
 #define QUAD_MASK 0x0f
 #define QUAD_FREE 0x01
 
+static u8
+nvkm_pm_count_perfdom(struct nvkm_pm *ppm)
+{
+	struct nvkm_perfdom *dom;
+	u8 domain_nr = 0;
+
+	list_for_each_entry(dom, &ppm->domains, head)
+		domain_nr++;
+	return domain_nr;
+}
+
+static u32
+nvkm_perfdom_count_perfsig(struct nvkm_perfdom *dom)
+{
+	u32 signal_nr = 0;
+	int i;
+
+	if (dom) {
+		for (i = 0; i < dom->signal_nr; i++) {
+			if (dom->signal[i].name)
+				signal_nr++;
+		}
+	}
+	return signal_nr;
+}
+
+static struct nvkm_perfdom *
+nvkm_perfdom_find(struct nvkm_pm *ppm, int di)
+{
+	struct nvkm_perfdom *dom;
+	int tmp = 0;
+
+	list_for_each_entry(dom, &ppm->domains, head) {
+		if (tmp++ == di)
+			return dom;
+	}
+	return NULL;
+}
+
 static struct nvkm_perfsig *
 nvkm_perfsig_find_(struct nvkm_perfdom *dom, const char *name, u32 size)
 {
@@ -83,6 +122,51 @@ nvkm_perfsig_find(struct nvkm_pm *ppm, const char *name, u32 size,
  * Perfmon object classes
  ******************************************************************************/
 static int
+nvkm_perfmon_mthd_query_domain(struct nvkm_object *object, void *data, u32 size)
+{
+	union {
+		struct nvif_perfmon_query_domain_v0 v0;
+	} *args = data;
+	struct nvkm_pm *ppm = (void *)object->engine;
+	struct nvkm_perfdom *dom;
+	u8 domain_nr;
+	int di, ret;
+
+	nv_ioctl(object, "perfmon query domain size %d\n", size);
+	if (nvif_unpack(args->v0, 0, 0, false)) {
+		nv_ioctl(object, "perfmon domain vers %d iter %02x\n",
+			 args->v0.version, args->v0.iter);
+		di = (args->v0.iter & 0xff) - 1;
+	} else
+		return ret;
+
+	domain_nr = nvkm_pm_count_perfdom(ppm);
+	if (di >= (int)domain_nr)
+		return -EINVAL;
+
+	if (di >= 0) {
+		dom = nvkm_perfdom_find(ppm, di);
+		if (dom == NULL)
+			return -EINVAL;
+
+		args->v0.id         = di;
+		args->v0.signal_nr  = nvkm_perfdom_count_perfsig(dom);
+
+		/* Currently only global counters (PCOUNTER) are implemented
+		 * but this will be different for local counters (MP). */
+		args->v0.counter_nr = 4;
+	}
+
+	if (++di < domain_nr) {
+		args->v0.iter = ++di;
+		return 0;
+	}
+
+	args->v0.iter = 0xff;
+	return 0;
+}
+
+static int
 nvkm_perfmon_mthd_query_signal(struct nvkm_object *object, void *data, u32 size)
 {
 	union {
@@ -145,6 +229,8 @@ static int
 nvkm_perfmon_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
 {
 	switch (mthd) {
+	case NVIF_PERFMON_V0_QUERY_DOMAIN:
+		return nvkm_perfmon_mthd_query_domain(object, data, size);
 	case NVIF_PERFMON_V0_QUERY_SIGNAL:
 		return nvkm_perfmon_mthd_query_signal(object, data, size);
 	default:
-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH RFC 08/20] pm: allow to query signals by domain
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (6 preceding siblings ...)
  2015-06-07 20:40   ` [PATCH RFC 07/20] pm: implement NVIF_PERFMON_V0_QUERY_DOMAIN method Samuel Pitoiset
@ 2015-06-07 20:40   ` Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 09/20] pm: change signal iter to u16 Samuel Pitoiset
                     ` (11 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

This will allow to configure performance counters with hardware signal
indexes instead of user-readable names in an upcoming patch.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
---
 bin/nv_perfmon.c                  | 185 ++++++++++++++++++++++++++++----------
 drm/nouveau/include/nvif/class.h  |   3 +-
 drm/nouveau/nvkm/engine/pm/base.c |  36 +++-----
 3 files changed, 150 insertions(+), 74 deletions(-)

diff --git a/bin/nv_perfmon.c b/bin/nv_perfmon.c
index 30a3138..958520e 100644
--- a/bin/nv_perfmon.c
+++ b/bin/nv_perfmon.c
@@ -36,8 +36,7 @@
 #include <sys/time.h>
 
 static struct nvif_device *device;
-static char **signals;
-static int nr_signals;
+static int nr_signals; /* number of signals for all domains */
 
 #define SEC_US  1000000
 #define REFRESH_PERIOD SEC_US
@@ -247,6 +246,17 @@ ui_menu_win = {
  *
  ******************************************************************************/
 
+struct ui_perfmon_dom {
+	struct list_head head;
+	struct list_head list;
+	u8 id;
+};
+
+struct ui_perfmon_sig {
+	struct list_head head;
+	char *name;
+};
+
 struct ui_main {
 	struct list_head head;
 	u32 handle;
@@ -258,6 +268,7 @@ struct ui_main {
 };
 
 static struct list_head ui_main_list = LIST_HEAD_INIT(ui_main_list);
+static struct list_head ui_doms_list = LIST_HEAD_INIT(ui_doms_list);
 static u32 ui_main_handle = 0xc0000000;
 
 static void
@@ -269,32 +280,134 @@ ui_main_remove(struct ui_main *item)
 }
 
 static void
+ui_perfmon_query_signals(struct nvif_object *perfmon,
+			 struct ui_perfmon_dom *dom)
+{
+	struct nvif_perfmon_query_signal_v0 args = {};
+	struct ui_perfmon_sig *sig;
+	int ret;
+
+	args.domain = dom->id;
+	do {
+		u32 prev_iter = args.iter;
+
+		args.name[0] = '\0';
+		ret = nvif_mthd(perfmon, NVIF_PERFMON_V0_QUERY_SIGNAL,
+				&args, sizeof(args));
+		assert(ret == 0);
+
+		if (prev_iter) {
+			nr_signals++;
+			sig = calloc(1, sizeof(*sig));
+			sig->name = malloc(sizeof(args.name));
+			strncpy(sig->name, args.name, sizeof(args.name));
+			list_add_tail(&sig->head, &dom->list);
+
+			args.iter = prev_iter;
+			ret = nvif_mthd(perfmon, NVIF_PERFMON_V0_QUERY_SIGNAL,
+					&args, sizeof(args));
+			assert(ret == 0);
+		}
+	} while (args.iter != 0xffffffff);
+}
+
+static void
+ui_perfmon_query_domains(struct nvif_object *perfmon)
+{
+	struct nvif_perfmon_query_domain_v0 args = {};
+	struct ui_perfmon_dom *dom;
+	int ret;
+
+	assert(ret == 0);
+	do {
+		u8 prev_iter = args.iter;
+
+		ret = nvif_mthd(perfmon, NVIF_PERFMON_V0_QUERY_DOMAIN,
+				&args, sizeof(args));
+		assert(ret == 0);
+
+		if (prev_iter) {
+			dom = calloc(1, sizeof(*dom));
+			dom->id = args.id;
+			INIT_LIST_HEAD(&dom->list);
+			list_add_tail(&dom->head, &ui_doms_list);
+
+			args.iter = prev_iter;
+			ret = nvif_mthd(perfmon, NVIF_PERFMON_V0_QUERY_DOMAIN,
+					&args, sizeof(args));
+			assert(ret == 0);
+
+			/* query available signals for the domain */
+			ui_perfmon_query_signals(perfmon, dom);
+		}
+	} while (args.iter != 0xff);
+}
+
+static void
+ui_perfmon_init(void)
+{
+	struct nvif_object perfmon;
+	int ret;
+
+	ret = nvif_object_init(nvif_object(device), NULL, 0xdeadbeef,
+			       NVIF_IOCTL_NEW_V0_PERFMON, NULL, 0, &perfmon);
+	assert(ret == 0);
+
+	/* query available domains for the device */
+	ui_perfmon_query_domains(&perfmon);
+
+	nvif_object_fini(&perfmon);
+}
+
+static void
+ui_perfmon_fini(void)
+{
+	struct ui_perfmon_dom *dom, *next_dom;
+	struct ui_perfmon_sig *sig, *next_sig;
+
+	list_for_each_entry_safe(dom, next_dom, &ui_doms_list, head) {
+		list_for_each_entry_safe(sig, next_sig, &dom->list, head) {
+			list_del(&sig->head);
+			free(sig->name);
+			free(sig);
+		}
+		list_del(&dom->head);
+		free(dom);
+	}
+}
+
+static void
 ui_main_select(void)
 {
 	struct ui_main *item, *temp;
-	int ret, i;
+	struct ui_perfmon_dom *dom;
+	struct ui_perfmon_sig *sig;
+	int ret;
 
 	list_for_each_entry_safe(item, temp, &ui_main_list, head) {
 		ui_main_remove(item);
 	}
 
-	for (i = 0; i < nr_signals; i++) {
-		struct nvif_perfctr_v0 args = {
-			.logic_op = 0xaaaa,
-		};
+	list_for_each_entry(dom, &ui_doms_list, head) {
+		list_for_each_entry(sig, &dom->list, head) {
+			struct nvif_perfctr_v0 args = {
+				.logic_op = 0xaaaa,
+			};
 
-		item = calloc(1, sizeof(*item));
-		item->handle = ui_main_handle++;
-		item->name = signals[i];
-		item->incr = 0;
+			item = calloc(1, sizeof(*item));
+			item->handle = ui_main_handle++;
+			item->name = sig->name;
 
-		strncpy(args.name[0], item->name, sizeof(args.name[0]));
+			strncpy(args.name[0], item->name, sizeof(args.name[0]));
 
-		ret = nvif_object_init(nvif_object(device), NULL, item->handle,
-				       NVIF_IOCTL_NEW_V0_PERFCTR, &args,
-				       sizeof(args), &item->object);
-		assert(ret == 0);
-		list_add_tail(&item->head, &ui_main_list);
+			ret = nvif_object_init(nvif_object(device), NULL,
+					       item->handle,
+					       NVIF_IOCTL_NEW_V0_PERFCTR,
+					       &args, sizeof(args),
+					       &item->object);
+			assert(ret == 0);
+			list_add_tail(&item->head, &ui_main_list);
+		}
 	}
 }
 
@@ -314,12 +427,14 @@ ui_main_alarm_handler(int signal)
 		if (!sampled) {
 			struct nvif_perfctr_sample args = {};
 
-			ret = nvif_mthd(&item->object, NVIF_PERFCTR_V0_SAMPLE, &args, sizeof(args));
+			ret = nvif_mthd(&item->object, NVIF_PERFCTR_V0_SAMPLE,
+					&args, sizeof(args));
 			assert(ret == 0);
 			sampled = true;
 		}
 
-		ret = nvif_mthd(&item->object, NVIF_PERFCTR_V0_READ, &args, sizeof(args));
+		ret = nvif_mthd(&item->object, NVIF_PERFCTR_V0_READ,
+				&args, sizeof(args));
 		assert(ret == 0 || ret == -EAGAIN);
 
 		if (ret == 0) {
@@ -600,9 +715,7 @@ main(int argc, char **argv)
 	const char *cfg = NULL;
 	const char *dbg = "error";
 	u64 dev = ~0ULL;
-	struct nvif_perfmon_query_signal_v0 args = {};
 	struct nvif_client *client;
-	struct nvif_object object;
 	int ret, c, k;
 	int scan = 0;
 
@@ -643,31 +756,7 @@ main(int argc, char **argv)
 		return 1;
 	}
 
-	ret = nvif_object_init(nvif_object(device), NULL, 0xdeadbeef,
-			       NVIF_IOCTL_NEW_V0_PERFMON, NULL, 0, &object);
-	assert(ret == 0);
-	do {
-		u32 prev_iter = args.iter;
-
-		args.name[0] = '\0';
-		ret = nvif_mthd(&object, NVIF_PERFMON_V0_QUERY_SIGNAL,
-				&args, sizeof(args));
-		assert(ret == 0);
-
-		if (prev_iter) {
-			nr_signals++;
-			signals = realloc(signals, nr_signals * sizeof(char*));
-			signals[nr_signals - 1] = malloc(sizeof(args.name));
-
-			args.iter = prev_iter;
-			strncpy(signals[nr_signals - 1], args.name,
-				sizeof(args.name));
-			ret = nvif_mthd(&object, NVIF_PERFMON_V0_QUERY_SIGNAL,
-					&args, sizeof(args));
-			assert(ret == 0);
-		}
-	} while (args.iter != 0xffffffff);
-	nvif_object_fini(&object);
+	ui_perfmon_init();
 
 	initscr();
 	keypad(stdscr, TRUE);
@@ -696,10 +785,8 @@ main(int argc, char **argv)
 
 	ui_destroy();
 	endwin();
+	ui_perfmon_fini();
 
-	while (nr_signals--)
-		free(signals[nr_signals]);
-	free(signals);
 	nvif_device_ref(NULL, &device);
 	return 0;
 }
diff --git a/drm/nouveau/include/nvif/class.h b/drm/nouveau/include/nvif/class.h
index 0b28929..cf2af89 100644
--- a/drm/nouveau/include/nvif/class.h
+++ b/drm/nouveau/include/nvif/class.h
@@ -264,7 +264,8 @@ struct nvif_perfmon_query_domain_v0 {
 
 struct nvif_perfmon_query_signal_v0 {
 	__u8  version;
-	__u8  pad01[3];
+	__u8  domain;
+	__u8  pad02[2];
 	__u32 iter;
 	char  name[64];
 };
diff --git a/drm/nouveau/nvkm/engine/pm/base.c b/drm/nouveau/nvkm/engine/pm/base.c
index 3d9bcbc..d61beff 100644
--- a/drm/nouveau/nvkm/engine/pm/base.c
+++ b/drm/nouveau/nvkm/engine/pm/base.c
@@ -174,29 +174,22 @@ nvkm_perfmon_mthd_query_signal(struct nvkm_object *object, void *data, u32 size)
 	} *args = data;
 	struct nvkm_device *device = nv_device(object);
 	struct nvkm_pm *ppm = (void *)object->engine;
-	struct nvkm_perfdom *dom = NULL, *chk;
+	struct nvkm_perfdom *dom;
 	const bool all = nvkm_boolopt(device->cfgopt, "NvPmShowAll", false);
 	const bool raw = nvkm_boolopt(device->cfgopt, "NvPmUnnamed", all);
 	const char *name;
-	int tmp = 0, di, si;
-	int ret;
+	int ret, si;
 
 	nv_ioctl(object, "perfmon query signal size %d\n", size);
 	if (nvif_unpack(args->v0, 0, 0, false)) {
-		nv_ioctl(object, "perfmon query signal vers %d iter %08x\n",
-			 args->v0.version, args->v0.iter);
-		di = (args->v0.iter & 0xff000000) >> 24;
-		si = (args->v0.iter & 0x00ffffff) - 1;
+		nv_ioctl(object,
+			 "perfmon query signal vers %d dom %d iter %08x\n",
+			 args->v0.version, args->v0.domain, args->v0.iter);
+		si = (args->v0.iter & 0xffffffff) - 1;
 	} else
 		return ret;
 
-	list_for_each_entry(chk, &ppm->domains, head) {
-		if (tmp++ == di) {
-			dom = chk;
-			break;
-		}
-	}
-
+	dom = nvkm_perfdom_find(ppm, args->v0.domain);
 	if (dom == NULL || si >= (int)dom->signal_nr)
 		return -EINVAL;
 
@@ -209,17 +202,12 @@ nvkm_perfmon_mthd_query_signal(struct nvkm_object *object, void *data, u32 size)
 		}
 	}
 
-	do {
-		while (++si < dom->signal_nr) {
-			if (all || dom->signal[si].name) {
-				args->v0.iter = (di << 24) | ++si;
-				return 0;
-			}
+	while (++si < dom->signal_nr) {
+		if (all || dom->signal[si].name) {
+			args->v0.iter = ++si;
+			return 0;
 		}
-		si = -1;
-		di = di + 1;
-		dom = list_entry(dom->head.next, typeof(*dom), head);
-	} while (&dom->head != &ppm->domains);
+	}
 
 	args->v0.iter = 0xffffffff;
 	return 0;
-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH RFC 09/20] pm: change signal iter to u16
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (7 preceding siblings ...)
  2015-06-07 20:40   ` [PATCH RFC 08/20] pm: allow to query signals by domain Samuel Pitoiset
@ 2015-06-07 20:40   ` Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 10/20] pm: use hardware signals indexes instead of user-readable names Samuel Pitoiset
                     ` (10 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

16 bits is large enough to store the maximum number of signals available
for one domain (i.e. 256).

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
---
 bin/nv_perfmon.c                  |  4 ++--
 drm/nouveau/include/nvif/class.h  |  7 ++++---
 drm/nouveau/nvkm/engine/pm/base.c | 10 +++++-----
 drm/nouveau/nvkm/engine/pm/priv.h |  2 +-
 4 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/bin/nv_perfmon.c b/bin/nv_perfmon.c
index 958520e..043d864 100644
--- a/bin/nv_perfmon.c
+++ b/bin/nv_perfmon.c
@@ -289,7 +289,7 @@ ui_perfmon_query_signals(struct nvif_object *perfmon,
 
 	args.domain = dom->id;
 	do {
-		u32 prev_iter = args.iter;
+		u16 prev_iter = args.iter;
 
 		args.name[0] = '\0';
 		ret = nvif_mthd(perfmon, NVIF_PERFMON_V0_QUERY_SIGNAL,
@@ -308,7 +308,7 @@ ui_perfmon_query_signals(struct nvif_object *perfmon,
 					&args, sizeof(args));
 			assert(ret == 0);
 		}
-	} while (args.iter != 0xffffffff);
+	} while (args.iter != 0xffff);
 }
 
 static void
diff --git a/drm/nouveau/include/nvif/class.h b/drm/nouveau/include/nvif/class.h
index cf2af89..871247c 100644
--- a/drm/nouveau/include/nvif/class.h
+++ b/drm/nouveau/include/nvif/class.h
@@ -259,14 +259,15 @@ struct nvif_perfmon_query_domain_v0 {
 	__u8  id;
 	__u8  counter_nr;
 	__u8  iter;
-	__u32 signal_nr;
+	__u16 signal_nr;
+	__u8  pad05[2];
 };
 
 struct nvif_perfmon_query_signal_v0 {
 	__u8  version;
 	__u8  domain;
-	__u8  pad02[2];
-	__u32 iter;
+	__u16 iter;
+	__u8  pad03[4];
 	char  name[64];
 };
 
diff --git a/drm/nouveau/nvkm/engine/pm/base.c b/drm/nouveau/nvkm/engine/pm/base.c
index d61beff..fab0598 100644
--- a/drm/nouveau/nvkm/engine/pm/base.c
+++ b/drm/nouveau/nvkm/engine/pm/base.c
@@ -45,10 +45,10 @@ nvkm_pm_count_perfdom(struct nvkm_pm *ppm)
 	return domain_nr;
 }
 
-static u32
+static u16
 nvkm_perfdom_count_perfsig(struct nvkm_perfdom *dom)
 {
-	u32 signal_nr = 0;
+	u16 signal_nr = 0;
 	int i;
 
 	if (dom) {
@@ -183,9 +183,9 @@ nvkm_perfmon_mthd_query_signal(struct nvkm_object *object, void *data, u32 size)
 	nv_ioctl(object, "perfmon query signal size %d\n", size);
 	if (nvif_unpack(args->v0, 0, 0, false)) {
 		nv_ioctl(object,
-			 "perfmon query signal vers %d dom %d iter %08x\n",
+			 "perfmon query signal vers %d dom %d iter %04x\n",
 			 args->v0.version, args->v0.domain, args->v0.iter);
-		si = (args->v0.iter & 0xffffffff) - 1;
+		si = (args->v0.iter & 0xffff) - 1;
 	} else
 		return ret;
 
@@ -209,7 +209,7 @@ nvkm_perfmon_mthd_query_signal(struct nvkm_object *object, void *data, u32 size)
 		}
 	}
 
-	args->v0.iter = 0xffffffff;
+	args->v0.iter = 0xffff;
 	return 0;
 }
 
diff --git a/drm/nouveau/nvkm/engine/pm/priv.h b/drm/nouveau/nvkm/engine/pm/priv.h
index 06a6e60..71667fc 100644
--- a/drm/nouveau/nvkm/engine/pm/priv.h
+++ b/drm/nouveau/nvkm/engine/pm/priv.h
@@ -44,7 +44,7 @@ struct nvkm_perfdom {
 	char name[32];
 	u32 addr;
 	u8  quad;
-	u32 signal_nr;
+	u16 signal_nr;
 	struct nvkm_perfsig signal[];
 };
 
-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH RFC 10/20] pm: use hardware signals indexes instead of user-readable names
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (8 preceding siblings ...)
  2015-06-07 20:40   ` [PATCH RFC 09/20] pm: change signal iter to u16 Samuel Pitoiset
@ 2015-06-07 20:40   ` Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 11/20] pm: allow to monitor hardware signal index 0x00 Samuel Pitoiset
                     ` (9 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
---
 bin/nv_perfmon.c                  |  6 +++--
 drm/nouveau/include/nvif/class.h  | 11 ++++++---
 drm/nouveau/nvkm/engine/pm/base.c | 52 +++++++++------------------------------
 3 files changed, 23 insertions(+), 46 deletions(-)

diff --git a/bin/nv_perfmon.c b/bin/nv_perfmon.c
index 043d864..50c7777 100644
--- a/bin/nv_perfmon.c
+++ b/bin/nv_perfmon.c
@@ -255,6 +255,7 @@ struct ui_perfmon_dom {
 struct ui_perfmon_sig {
 	struct list_head head;
 	char *name;
+	u8 signal;
 };
 
 struct ui_main {
@@ -299,6 +300,7 @@ ui_perfmon_query_signals(struct nvif_object *perfmon,
 		if (prev_iter) {
 			nr_signals++;
 			sig = calloc(1, sizeof(*sig));
+			sig->signal = args.signal;
 			sig->name = malloc(sizeof(args.name));
 			strncpy(sig->name, args.name, sizeof(args.name));
 			list_add_tail(&sig->head, &dom->list);
@@ -392,14 +394,14 @@ ui_main_select(void)
 		list_for_each_entry(sig, &dom->list, head) {
 			struct nvif_perfctr_v0 args = {
 				.logic_op = 0xaaaa,
+				.domain = dom->id,
 			};
 
 			item = calloc(1, sizeof(*item));
 			item->handle = ui_main_handle++;
 			item->name = sig->name;
 
-			strncpy(args.name[0], item->name, sizeof(args.name[0]));
-
+			args.signal[0] = sig->signal;
 			ret = nvif_object_init(nvif_object(device), NULL,
 					       item->handle,
 					       NVIF_IOCTL_NEW_V0_PERFCTR,
diff --git a/drm/nouveau/include/nvif/class.h b/drm/nouveau/include/nvif/class.h
index 871247c..9e4db3a 100644
--- a/drm/nouveau/include/nvif/class.h
+++ b/drm/nouveau/include/nvif/class.h
@@ -267,7 +267,8 @@ struct nvif_perfmon_query_signal_v0 {
 	__u8  version;
 	__u8  domain;
 	__u16 iter;
-	__u8  pad03[4];
+	__u8  signal;
+	__u8  pad04[3];
 	char  name[64];
 };
 
@@ -278,10 +279,12 @@ struct nvif_perfmon_query_signal_v0 {
 
 struct nvif_perfctr_v0 {
 	__u8  version;
-	__u8  pad01[1];
+	__u8  domain;
+	__u8  pad02[2];
 	__u16 logic_op;
-	__u8  pad04[4];
-	char  name[4][64];
+	__u8  pad04[2];
+	__u8  signal[4];
+	__u8  pad06[4];
 };
 
 #define NVIF_PERFCTR_V0_SAMPLE                                             0x00
diff --git a/drm/nouveau/nvkm/engine/pm/base.c b/drm/nouveau/nvkm/engine/pm/base.c
index fab0598..71834b9 100644
--- a/drm/nouveau/nvkm/engine/pm/base.c
+++ b/drm/nouveau/nvkm/engine/pm/base.c
@@ -73,49 +73,22 @@ nvkm_perfdom_find(struct nvkm_pm *ppm, int di)
 	return NULL;
 }
 
-static struct nvkm_perfsig *
-nvkm_perfsig_find_(struct nvkm_perfdom *dom, const char *name, u32 size)
-{
-	char path[64];
-	int i;
-
-	if (name[0] != '/') {
-		for (i = 0; i < dom->signal_nr; i++) {
-			if ( dom->signal[i].name &&
-			    !strncmp(name, dom->signal[i].name, size))
-				return &dom->signal[i];
-		}
-	} else {
-		for (i = 0; i < dom->signal_nr; i++) {
-			snprintf(path, sizeof(path), "/%s/%02x", dom->name, i);
-			if (!strncmp(name, path, size))
-				return &dom->signal[i];
-		}
-	}
-
-	return NULL;
-}
-
 struct nvkm_perfsig *
-nvkm_perfsig_find(struct nvkm_pm *ppm, const char *name, u32 size,
+nvkm_perfsig_find(struct nvkm_pm *ppm, uint8_t di, uint8_t si,
 		  struct nvkm_perfdom **pdom)
 {
 	struct nvkm_perfdom *dom = *pdom;
-	struct nvkm_perfsig *sig;
 
 	if (dom == NULL) {
-		list_for_each_entry(dom, &ppm->domains, head) {
-			sig = nvkm_perfsig_find_(dom, name, size);
-			if (sig) {
-				*pdom = dom;
-				return sig;
-			}
-		}
-
-		return NULL;
+		dom = nvkm_perfdom_find(ppm, di);
+		if (dom == NULL)
+			return NULL;
+		*pdom = dom;
 	}
 
-	return nvkm_perfsig_find_(dom, name, size);
+	if (!dom->signal[si].name)
+		return NULL;
+	return &dom->signal[si];
 }
 
 /*******************************************************************************
@@ -200,6 +173,7 @@ nvkm_perfmon_mthd_query_signal(struct nvkm_object *object, void *data, u32 size)
 		} else {
 			strncpy(args->v0.name, name, sizeof(args->v0.name));
 		}
+		args->v0.signal = si;
 	}
 
 	while (++si < dom->signal_nr) {
@@ -359,11 +333,9 @@ nvkm_perfctr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	} else
 		return ret;
 
-	for (i = 0; i < ARRAY_SIZE(args->v0.name) && args->v0.name[i][0]; i++) {
-		sig[i] = nvkm_perfsig_find(ppm, args->v0.name[i],
-					   strnlen(args->v0.name[i],
-						   sizeof(args->v0.name[i])),
-					   &dom);
+	for (i = 0; i < ARRAY_SIZE(args->v0.signal) && args->v0.signal[i]; i++) {
+		sig[i] = nvkm_perfsig_find(ppm, args->v0.domain,
+					   args->v0.signal[i], &dom);
 		if (!sig[i])
 			return -EINVAL;
 	}
-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH RFC 11/20] pm: allow to monitor hardware signal index 0x00
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (9 preceding siblings ...)
  2015-06-07 20:40   ` [PATCH RFC 10/20] pm: use hardware signals indexes instead of user-readable names Samuel Pitoiset
@ 2015-06-07 20:40   ` Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 12/20] pm: add concept of sources Samuel Pitoiset
                     ` (8 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

This signal index must be always allowed even if it's not clearly
defined in a domain in order to monitor a counter like 0x03020100
because it's the default value of signals.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
---
 drm/nouveau/nvkm/engine/pm/base.c  | 4 ++--
 drm/nouveau/nvkm/engine/pm/gf100.c | 6 ++++--
 drm/nouveau/nvkm/engine/pm/nv40.c  | 6 ++++--
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drm/nouveau/nvkm/engine/pm/base.c b/drm/nouveau/nvkm/engine/pm/base.c
index 71834b9..610c0ca 100644
--- a/drm/nouveau/nvkm/engine/pm/base.c
+++ b/drm/nouveau/nvkm/engine/pm/base.c
@@ -333,10 +333,10 @@ nvkm_perfctr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	} else
 		return ret;
 
-	for (i = 0; i < ARRAY_SIZE(args->v0.signal) && args->v0.signal[i]; i++) {
+	for (i = 0; i < ARRAY_SIZE(args->v0.signal); i++) {
 		sig[i] = nvkm_perfsig_find(ppm, args->v0.domain,
 					   args->v0.signal[i], &dom);
-		if (!sig[i])
+		if (args->v0.signal[i] && !sig[i])
 			return -EINVAL;
 	}
 
diff --git a/drm/nouveau/nvkm/engine/pm/gf100.c b/drm/nouveau/nvkm/engine/pm/gf100.c
index 69303b5..41350d6 100644
--- a/drm/nouveau/nvkm/engine/pm/gf100.c
+++ b/drm/nouveau/nvkm/engine/pm/gf100.c
@@ -48,8 +48,10 @@ gf100_perfctr_init(struct nvkm_pm *ppm, struct nvkm_perfdom *dom,
 	u32 src = 0x00000000;
 	int i;
 
-	for (i = 0; i < 4 && ctr->signal[i]; i++)
-		src |= (ctr->signal[i] - dom->signal) << (i * 8);
+	for (i = 0; i < 4; i++) {
+		if (ctr->signal[i])
+			src |= (ctr->signal[i] - dom->signal) << (i * 8);
+	}
 
 	nv_wr32(priv, dom->addr + 0x09c, 0x00040002);
 	nv_wr32(priv, dom->addr + 0x100, 0x00000000);
diff --git a/drm/nouveau/nvkm/engine/pm/nv40.c b/drm/nouveau/nvkm/engine/pm/nv40.c
index ff22f06..603874e 100644
--- a/drm/nouveau/nvkm/engine/pm/nv40.c
+++ b/drm/nouveau/nvkm/engine/pm/nv40.c
@@ -33,8 +33,10 @@ nv40_perfctr_init(struct nvkm_pm *ppm, struct nvkm_perfdom *dom,
 	u32 src = 0x00000000;
 	int i;
 
-	for (i = 0; i < 4 && ctr->signal[i]; i++)
-		src |= (ctr->signal[i] - dom->signal) << (i * 8);
+	for (i = 0; i < 4; i++) {
+		if (ctr->signal[i])
+			src |= (ctr->signal[i] - dom->signal) << (i * 8);
+	}
 
 	nv_wr32(priv, 0x00a7c0 + dom->addr, 0x00000001);
 	nv_wr32(priv, 0x00a400 + dom->addr + (cntr->base.slot * 0x40), src);
-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH RFC 12/20] pm: add concept of sources
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (10 preceding siblings ...)
  2015-06-07 20:40   ` [PATCH RFC 11/20] pm: allow to monitor hardware signal index 0x00 Samuel Pitoiset
@ 2015-06-07 20:40   ` Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 13/20] pm: allow to query the number of sources for a signal Samuel Pitoiset
                     ` (7 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

[-- Attachment #1: Type: text/plain, Size: 5096 bytes --]

From: Samuel Pitoiset <samuel.pitoisetœgmail.com>

A source (or multiplexer) is a tuple addr+mask+shift which allows to
control a block of signals. The maximum number of sources that a signal
can define is arbitrary limited to 8 and this should be large enough.
This patch allows to define multi-level of sources for a signal.

Each different sources are stored to a global list and will be exposed
to the userspace through the nvif interface in order to avoid conflicts.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
---
 drm/nouveau/include/nvkm/engine/pm.h |  1 +
 drm/nouveau/nvkm/engine/pm/base.c    | 82 ++++++++++++++++++++++++++++++++++--
 drm/nouveau/nvkm/engine/pm/priv.h    | 24 +++++++++++
 3 files changed, 103 insertions(+), 4 deletions(-)

diff --git a/drm/nouveau/include/nvkm/engine/pm.h b/drm/nouveau/include/nvkm/engine/pm.h
index 6c2d057..130b545 100644
--- a/drm/nouveau/include/nvkm/engine/pm.h
+++ b/drm/nouveau/include/nvkm/engine/pm.h
@@ -11,6 +11,7 @@ struct nvkm_pm {
 	void *profile_data;
 
 	struct list_head domains;
+	struct list_head sources;
 	u32 sequence;
 };
 
diff --git a/drm/nouveau/nvkm/engine/pm/base.c b/drm/nouveau/nvkm/engine/pm/base.c
index 610c0ca..dfafefd 100644
--- a/drm/nouveau/nvkm/engine/pm/base.c
+++ b/drm/nouveau/nvkm/engine/pm/base.c
@@ -434,6 +434,67 @@ nvkm_pm_cclass = {
  * PPM engine/subdev functions
  ******************************************************************************/
 int
+nvkm_perfsrc_new(struct nvkm_pm *ppm, struct nvkm_perfsig *sig,
+		 const struct nvkm_specsrc *spec)
+{
+	const struct nvkm_specsrc *ssrc;
+	const struct nvkm_specmux *smux;
+	struct nvkm_perfsrc *src;
+	u8 source_nr = 0;
+
+	if (!spec) {
+		/* No sources are defined for this signal. */
+		return 0;
+	}
+
+	ssrc = spec;
+	while (ssrc->name) {
+		smux = ssrc->mux;
+		while (smux->name) {
+			bool found = false;
+			u8 source_id = 0;
+			u32 len;
+
+			list_for_each_entry(src, &ppm->sources, head) {
+				if (src->addr == ssrc->addr &&
+				    src->shift == smux->shift) {
+					found = true;
+					break;
+				}
+				source_id++;
+			}
+
+			if (!found) {
+				src = kzalloc(sizeof(*src), GFP_KERNEL);
+				if (!src)
+					return -ENOMEM;
+
+				src->addr   = ssrc->addr;
+				src->mask   = smux->mask;
+				src->shift  = smux->shift;
+				src->enable = smux->enable;
+
+				len = strlen(ssrc->name) +
+				      strlen(smux->name) + 2;
+				src->name = kzalloc(len, GFP_KERNEL);
+				if (!src->name)
+					return -ENOMEM;
+				snprintf(src->name, len, "%s_%s", ssrc->name,
+					 smux->name);
+
+				list_add_tail(&src->head, &ppm->sources);
+			}
+
+			sig->source[source_nr++] = source_id + 1;
+			smux++;
+		}
+		ssrc++;
+	}
+
+	return 0;
+}
+
+int
 nvkm_perfdom_new(struct nvkm_pm *ppm, const char *name, u32 mask,
 		 u32 base, u32 size_unit, u32 size_domain,
 		 const struct nvkm_specdom *spec)
@@ -441,7 +502,7 @@ nvkm_perfdom_new(struct nvkm_pm *ppm, const char *name, u32 mask,
 	const struct nvkm_specdom *sdom;
 	const struct nvkm_specsig *ssig;
 	struct nvkm_perfdom *dom;
-	int i;
+	int ret, i;
 
 	for (i = 0; i == 0 || mask; i++) {
 		u32 addr = base + (i * size_unit);
@@ -473,7 +534,12 @@ nvkm_perfdom_new(struct nvkm_pm *ppm, const char *name, u32 mask,
 
 			ssig = (sdom++)->signal;
 			while (ssig->name) {
-				dom->signal[ssig->signal].name = ssig->name;
+				struct nvkm_perfsig *sig =
+					&dom->signal[ssig->signal];
+				sig->name = ssig->name;
+				ret = nvkm_perfsrc_new(ppm, sig, ssig->source);
+				if (ret)
+					return ret;
 				ssig++;
 			}
 
@@ -504,13 +570,20 @@ void
 _nvkm_pm_dtor(struct nvkm_object *object)
 {
 	struct nvkm_pm *ppm = (void *)object;
-	struct nvkm_perfdom *dom, *tmp;
+	struct nvkm_perfdom *dom, *next_dom;
+	struct nvkm_perfsrc *src, *next_src;
 
-	list_for_each_entry_safe(dom, tmp, &ppm->domains, head) {
+	list_for_each_entry_safe(dom, next_dom, &ppm->domains, head) {
 		list_del(&dom->head);
 		kfree(dom);
 	}
 
+	list_for_each_entry_safe(src, next_src, &ppm->sources, head) {
+		list_del(&src->head);
+		kfree(src->name);
+		kfree(src);
+	}
+
 	nvkm_engine_destroy(&ppm->base);
 }
 
@@ -528,5 +601,6 @@ nvkm_pm_create_(struct nvkm_object *parent, struct nvkm_object *engine,
 		return ret;
 
 	INIT_LIST_HEAD(&ppm->domains);
+	INIT_LIST_HEAD(&ppm->sources);
 	return 0;
 }
diff --git a/drm/nouveau/nvkm/engine/pm/priv.h b/drm/nouveau/nvkm/engine/pm/priv.h
index 71667fc..f954c98 100644
--- a/drm/nouveau/nvkm/engine/pm/priv.h
+++ b/drm/nouveau/nvkm/engine/pm/priv.h
@@ -22,13 +22,37 @@ struct nvkm_perfctx {
 
 extern struct nvkm_oclass nvkm_pm_cclass;
 
+struct nvkm_specmux {
+	u32 mask;
+	u8 shift;
+	const char *name;
+	bool enable;
+};
+
+struct nvkm_specsrc {
+	u32 addr;
+	const struct nvkm_specmux *mux;
+	const char *name;
+};
+
+struct nvkm_perfsrc {
+	struct list_head head;
+	char *name;
+	u32 addr;
+	u32 mask;
+	u8 shift;
+	bool enable;
+};
+
 struct nvkm_specsig {
 	u8 signal;
 	const char *name;
+	const struct nvkm_specsrc *source;
 };
 
 struct nvkm_perfsig {
 	const char *name;
+	u8 source[8];
 };
 
 struct nvkm_specdom {
-- 
2.4.2


[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH RFC 13/20] pm: allow to query the number of sources for a signal
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (11 preceding siblings ...)
  2015-06-07 20:40   ` [PATCH RFC 12/20] pm: add concept of sources Samuel Pitoiset
@ 2015-06-07 20:40   ` Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 14/20] pm: implement NVIF_PERFMON_V0_QUERY_SOURCE method Samuel Pitoiset
                     ` (6 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
---
 drm/nouveau/include/nvif/class.h  |  3 ++-
 drm/nouveau/nvkm/engine/pm/base.c | 22 +++++++++++++++++++---
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/drm/nouveau/include/nvif/class.h b/drm/nouveau/include/nvif/class.h
index 9e4db3a..caae193 100644
--- a/drm/nouveau/include/nvif/class.h
+++ b/drm/nouveau/include/nvif/class.h
@@ -268,7 +268,8 @@ struct nvif_perfmon_query_signal_v0 {
 	__u8  domain;
 	__u16 iter;
 	__u8  signal;
-	__u8  pad04[3];
+	__u8  source_nr;
+	__u8  pad05[2];
 	char  name[64];
 };
 
diff --git a/drm/nouveau/nvkm/engine/pm/base.c b/drm/nouveau/nvkm/engine/pm/base.c
index dfafefd..a9c57a2 100644
--- a/drm/nouveau/nvkm/engine/pm/base.c
+++ b/drm/nouveau/nvkm/engine/pm/base.c
@@ -91,6 +91,18 @@ nvkm_perfsig_find(struct nvkm_pm *ppm, uint8_t di, uint8_t si,
 	return &dom->signal[si];
 }
 
+static u8
+nvkm_perfsig_count_perfsrc(struct nvkm_perfsig *sig)
+{
+	u8 source_nr = 0, i;
+
+	for (i = 0; i < ARRAY_SIZE(sig->source); i++) {
+		if (sig->source[i])
+			source_nr++;
+	}
+	return source_nr;
+}
+
 /*******************************************************************************
  * Perfmon object classes
  ******************************************************************************/
@@ -148,9 +160,9 @@ nvkm_perfmon_mthd_query_signal(struct nvkm_object *object, void *data, u32 size)
 	struct nvkm_device *device = nv_device(object);
 	struct nvkm_pm *ppm = (void *)object->engine;
 	struct nvkm_perfdom *dom;
+	struct nvkm_perfsig *sig;
 	const bool all = nvkm_boolopt(device->cfgopt, "NvPmShowAll", false);
 	const bool raw = nvkm_boolopt(device->cfgopt, "NvPmUnnamed", all);
-	const char *name;
 	int ret, si;
 
 	nv_ioctl(object, "perfmon query signal size %d\n", size);
@@ -167,13 +179,17 @@ nvkm_perfmon_mthd_query_signal(struct nvkm_object *object, void *data, u32 size)
 		return -EINVAL;
 
 	if (si >= 0) {
-		if (raw || !(name = dom->signal[si].name)) {
+		sig = &dom->signal[si];
+		if (raw || !sig->name) {
 			snprintf(args->v0.name, sizeof(args->v0.name),
 				 "/%s/%02x", dom->name, si);
 		} else {
-			strncpy(args->v0.name, name, sizeof(args->v0.name));
+			strncpy(args->v0.name, sig->name,
+				sizeof(args->v0.name));
 		}
+
 		args->v0.signal = si;
+		args->v0.source_nr = nvkm_perfsig_count_perfsrc(sig);
 	}
 
 	while (++si < dom->signal_nr) {
-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH RFC 14/20] pm: implement NVIF_PERFMON_V0_QUERY_SOURCE method
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (12 preceding siblings ...)
  2015-06-07 20:40   ` [PATCH RFC 13/20] pm: allow to query the number of sources for a signal Samuel Pitoiset
@ 2015-06-07 20:40   ` Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 15/20] pm: allow the userspace to schedule hardware counters Samuel Pitoiset
                     ` (5 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

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>
---
 drm/nouveau/include/nvif/class.h  | 12 ++++++
 drm/nouveau/nvkm/engine/pm/base.c | 77 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+)

diff --git a/drm/nouveau/include/nvif/class.h b/drm/nouveau/include/nvif/class.h
index caae193..d85fb0d 100644
--- a/drm/nouveau/include/nvif/class.h
+++ b/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/drm/nouveau/nvkm/engine/pm/base.c b/drm/nouveau/nvkm/engine/pm/base.c
index a9c57a2..ec02abf 100644
--- a/drm/nouveau/nvkm/engine/pm/base.c
+++ b/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;
 	}
-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH RFC 15/20] pm: allow the userspace to schedule hardware counters
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (13 preceding siblings ...)
  2015-06-07 20:40   ` [PATCH RFC 14/20] pm: implement NVIF_PERFMON_V0_QUERY_SOURCE method Samuel Pitoiset
@ 2015-06-07 20:40   ` Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 16/20] pm: allow to configure domains instead of simple counters Samuel Pitoiset
                     ` (4 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

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>
---
 drm/nouveau/include/nvif/class.h  |  8 +++--
 drm/nouveau/nvkm/engine/pm/base.c | 64 +++++++++++++++++++++++++--------------
 drm/nouveau/nvkm/engine/pm/priv.h |  1 +
 3 files changed, 48 insertions(+), 25 deletions(-)

diff --git a/drm/nouveau/include/nvif/class.h b/drm/nouveau/include/nvif/class.h
index d85fb0d..528eac8 100644
--- a/drm/nouveau/include/nvif/class.h
+++ b/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/drm/nouveau/nvkm/engine/pm/base.c b/drm/nouveau/nvkm/engine/pm/base.c
index ec02abf..5dbb3b4 100644
--- a/drm/nouveau/nvkm/engine/pm/base.c
+++ b/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/drm/nouveau/nvkm/engine/pm/priv.h b/drm/nouveau/nvkm/engine/pm/priv.h
index f954c98..4ed77ff 100644
--- a/drm/nouveau/nvkm/engine/pm/priv.h
+++ b/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;
-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH RFC 16/20] pm: allow to configure domains instead of simple counters
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (14 preceding siblings ...)
  2015-06-07 20:40   ` [PATCH RFC 15/20] pm: allow the userspace to schedule hardware counters Samuel Pitoiset
@ 2015-06-07 20:40   ` Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 17/20] pm: allow the userspace to configure sources Samuel Pitoiset
                     ` (3 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Configuring counters from the userspace require the kernel to handle some
logic related to performance counters. Basically, it has to find a free
slot to assign a counter, to handle extra counting modes like B4/B6 and it
must return and error when it can't configure a counter.

In my opinion, the kernel should not handle all of that logic but it
should only write the configuration sent by the userspace without
checking anything. In other words, it should overwrite the configuration
even if it's already counting and do not return any errors.

This patch allows the userspace to configure a domain instead of
separate counters. This has the advantage to move all of the logic to
the userspace.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
---
 bin/nv_perfmon.c                   | 193 ++++++++++++++++++++++++++--------
 drm/nouveau/include/nvif/class.h   |  30 +++---
 drm/nouveau/include/nvif/ioctl.h   |   2 +-
 drm/nouveau/nvkm/engine/pm/base.c  | 208 +++++++++++++++++++++----------------
 drm/nouveau/nvkm/engine/pm/gf100.c |  10 +-
 drm/nouveau/nvkm/engine/pm/nv40.c  |  10 +-
 drm/nouveau/nvkm/engine/pm/priv.h  |  10 +-
 7 files changed, 293 insertions(+), 170 deletions(-)

diff --git a/bin/nv_perfmon.c b/bin/nv_perfmon.c
index 50c7777..47b2fef 100644
--- a/bin/nv_perfmon.c
+++ b/bin/nv_perfmon.c
@@ -248,7 +248,8 @@ ui_menu_win = {
 
 struct ui_perfmon_dom {
 	struct list_head head;
-	struct list_head list;
+	struct list_head signals;
+	struct list_head perfdoms;
 	u8 id;
 };
 
@@ -260,22 +261,27 @@ struct ui_perfmon_sig {
 
 struct ui_main {
 	struct list_head head;
-	u32 handle;
-	struct nvif_object object;
-	const char *name;
+	struct ui_perfmon_sig *sig;
 	u32 clk;
 	u32 ctr;
 	u64 incr;
 };
 
+struct ui_perfdom {
+	struct nvif_object object;
+	struct list_head head;
+	struct ui_main *ctr[4];
+	u32 handle;
+};
+
 static struct list_head ui_main_list = LIST_HEAD_INIT(ui_main_list);
 static struct list_head ui_doms_list = LIST_HEAD_INIT(ui_doms_list);
+static struct list_head ui_perfdom_list = LIST_HEAD_INIT(ui_perfdom_list);
 static u32 ui_main_handle = 0xc0000000;
 
 static void
 ui_main_remove(struct ui_main *item)
 {
-	nvif_object_fini(&item->object);
 	list_del(&item->head);
 	free(item);
 }
@@ -303,7 +309,7 @@ ui_perfmon_query_signals(struct nvif_object *perfmon,
 			sig->signal = args.signal;
 			sig->name = malloc(sizeof(args.name));
 			strncpy(sig->name, args.name, sizeof(args.name));
-			list_add_tail(&sig->head, &dom->list);
+			list_add_tail(&sig->head, &dom->signals);
 
 			args.iter = prev_iter;
 			ret = nvif_mthd(perfmon, NVIF_PERFMON_V0_QUERY_SIGNAL,
@@ -331,7 +337,8 @@ ui_perfmon_query_domains(struct nvif_object *perfmon)
 		if (prev_iter) {
 			dom = calloc(1, sizeof(*dom));
 			dom->id = args.id;
-			INIT_LIST_HEAD(&dom->list);
+			INIT_LIST_HEAD(&dom->signals);
+			INIT_LIST_HEAD(&dom->perfdoms);
 			list_add_tail(&dom->head, &ui_doms_list);
 
 			args.iter = prev_iter;
@@ -346,6 +353,49 @@ ui_perfmon_query_domains(struct nvif_object *perfmon)
 }
 
 static void
+ui_perfdom_init(struct ui_perfdom *dom)
+{
+	struct nvif_perfdom_init args = {};
+	int ret;
+
+	ret = nvif_mthd(&dom->object, NVIF_PERFDOM_V0_INIT,
+			&args, sizeof(args));
+	assert(ret == 0);
+}
+
+static void
+ui_perfdom_sample(struct ui_perfdom *dom)
+{
+	struct nvif_perfdom_sample args = {};
+	int ret;
+
+	ret = nvif_mthd(&dom->object, NVIF_PERFDOM_V0_SAMPLE,
+			&args, sizeof(args));
+	assert(ret == 0);
+}
+
+static void
+ui_perfdom_read(struct ui_perfdom *dom)
+{
+	struct nvif_perfdom_read_v0 args = {};
+	int ret, i;
+
+	ret = nvif_mthd(&dom->object, NVIF_PERFDOM_V0_READ,
+			&args, sizeof(args));
+	assert(ret == 0 || ret == -EAGAIN);
+
+	if (ret == 0) {
+		for (i = 0; i < 4; i++) {
+			if (!dom->ctr[i])
+				continue;
+			dom->ctr[i]->ctr   = args.ctr[i];
+			dom->ctr[i]->incr += args.ctr[i];
+			dom->ctr[i]->clk   = args.clk;
+		}
+	}
+}
+
+static void
 ui_perfmon_init(void)
 {
 	struct nvif_object perfmon;
@@ -362,17 +412,37 @@ ui_perfmon_init(void)
 }
 
 static void
+ui_perfmon_free_signals(struct ui_perfmon_dom *dom)
+{
+	struct ui_perfmon_sig *sig, *next;
+
+	list_for_each_entry_safe(sig, next, &dom->signals, head) {
+		list_del(&sig->head);
+		free(sig->name);
+		free(sig);
+	}
+}
+
+static void
+ui_perfmon_free_perfdoms(struct ui_perfmon_dom *dom)
+{
+	struct ui_perfdom *perfdom, *next;
+
+	list_for_each_entry_safe(perfdom, next, &dom->perfdoms, head) {
+		nvif_object_fini(&perfdom->object);
+		list_del(&perfdom->head);
+		free(perfdom);
+	}
+}
+
+static void
 ui_perfmon_fini(void)
 {
-	struct ui_perfmon_dom *dom, *next_dom;
-	struct ui_perfmon_sig *sig, *next_sig;
-
-	list_for_each_entry_safe(dom, next_dom, &ui_doms_list, head) {
-		list_for_each_entry_safe(sig, next_sig, &dom->list, head) {
-			list_del(&sig->head);
-			free(sig->name);
-			free(sig);
-		}
+	struct ui_perfmon_dom *dom, *next;
+
+	list_for_each_entry_safe(dom, next, &ui_doms_list, head) {
+		ui_perfmon_free_perfdoms(dom);
+		ui_perfmon_free_signals(dom);
 		list_del(&dom->head);
 		free(dom);
 	}
@@ -384,31 +454,62 @@ ui_main_select(void)
 	struct ui_main *item, *temp;
 	struct ui_perfmon_dom *dom;
 	struct ui_perfmon_sig *sig;
+	struct ui_perfdom *perfdom;
 	int ret;
+	int i;
 
 	list_for_each_entry_safe(item, temp, &ui_main_list, head) {
 		ui_main_remove(item);
 	}
 
 	list_for_each_entry(dom, &ui_doms_list, head) {
-		list_for_each_entry(sig, &dom->list, head) {
-			struct nvif_perfctr_v0 args = {
-				.logic_op = 0xaaaa,
-				.domain = dom->id,
-			};
+		list_for_each_entry(sig, &dom->signals, head) {
+			bool found = false;
 
 			item = calloc(1, sizeof(*item));
-			item->handle = ui_main_handle++;
-			item->name = sig->name;
+			item->sig = sig;
+			list_add_tail(&item->head, &ui_main_list);
+
+			/* find a slot */
+			list_for_each_entry(perfdom, &dom->perfdoms, head) {
+				for (i = 0; i < 4; i++) {
+					if (!perfdom->ctr[i]) {
+						perfdom->ctr[i] = item;
+						found = true;
+						break;
+					}
+				}
+			}
+
+			if (!found) {
+				/* no free slots, create a new perfdom */
+				perfdom = calloc(1, sizeof(*perfdom));
+				perfdom->handle = ui_main_handle++;
+				perfdom->ctr[0] = item;
+				list_add_tail(&perfdom->head, &dom->perfdoms);
+			}
+		}
+
+		/* init perfdom objects */
+		list_for_each_entry(perfdom, &dom->perfdoms, head) {
+			struct nvif_perfdom_v0 args = {};
+			int i;
+
+			args.domain = dom->id;
+			for (i = 0; i < 4; i++) {
+				struct ui_main *ctr = perfdom->ctr[i];
+				if (!ctr)
+					continue;
+				args.ctr[i].signal[0] = ctr->sig->signal;
+				args.ctr[i].logic_op  = 0xaaaa;
+			}
 
-			args.signal[0] = sig->signal;
 			ret = nvif_object_init(nvif_object(device), NULL,
-					       item->handle,
-					       NVIF_IOCTL_NEW_V0_PERFCTR,
+					       perfdom->handle,
+					       NVIF_IOCTL_NEW_V0_PERFDOM,
 					       &args, sizeof(args),
-					       &item->object);
+					       &perfdom->object);
 			assert(ret == 0);
-			list_add_tail(&item->head, &ui_main_list);
 		}
 	}
 }
@@ -416,34 +517,34 @@ ui_main_select(void)
 static void
 ui_main_alarm_handler(int signal)
 {
-	struct ui_main *item;
+	struct ui_perfmon_dom *dom;
+	struct ui_perfdom *perfdom;
 	bool sampled = false;
 
 	if (list_empty(&ui_main_list))
 		ui_main_select();
 
-	list_for_each_entry(item, &ui_main_list, head) {
-		struct nvif_perfctr_read_v0 args = {};
-		int ret;
+	list_for_each_entry(dom, &ui_doms_list, head) {
+		if (list_empty(&dom->perfdoms))
+			continue;
 
-		if (!sampled) {
-			struct nvif_perfctr_sample args = {};
+		perfdom = list_first_entry(&dom->perfdoms,
+					   typeof(*perfdom), head);
 
-			ret = nvif_mthd(&item->object, NVIF_PERFCTR_V0_SAMPLE,
-					&args, sizeof(args));
-			assert(ret == 0);
+		/* sample previous batch of counters */
+		if (!sampled) {
+			ui_perfdom_sample(perfdom);
 			sampled = true;
 		}
 
-		ret = nvif_mthd(&item->object, NVIF_PERFCTR_V0_READ,
-				&args, sizeof(args));
-		assert(ret == 0 || ret == -EAGAIN);
+		/* read previous batch of counters */
+		ui_perfdom_read(perfdom);
 
-		if (ret == 0) {
-			item->clk = args.clk;
-			item->ctr = args.ctr;
-		}
-		item->incr += item->ctr;
+		/* setup next batch of counters for sampling */
+		list_move_tail(&perfdom->head, &dom->perfdoms);
+		perfdom = list_first_entry(&dom->perfdoms,
+					   typeof(*perfdom), head);
+		ui_perfdom_init(perfdom);
 	}
 }
 
@@ -485,7 +586,7 @@ ui_main_redraw(struct ui_table *t)
 
 	y = 2;
 	list_for_each_entry_from(item, &ui_main_list, head) {
-		set_field_buffer(f[0], 0, item->name);
+		set_field_buffer(f[0], 0, item->sig->name);
 		set_field_userptr(f[0], item);
 		field_opts_on(f[0], O_VISIBLE | O_ACTIVE);
 
diff --git a/drm/nouveau/include/nvif/class.h b/drm/nouveau/include/nvif/class.h
index 528eac8..1a76a7f 100644
--- a/drm/nouveau/include/nvif/class.h
+++ b/drm/nouveau/include/nvif/class.h
@@ -287,34 +287,36 @@ struct nvif_perfmon_query_source_v0 {
 
 
 /*******************************************************************************
- * perfctr
+ * perfdom
  ******************************************************************************/
 
-struct nvif_perfctr_v0 {
+struct nvif_perfdom_v0 {
 	__u8  version;
 	__u8  domain;
-	__u8  pad02[2];
-	__u16 logic_op;
-	__u8  pad04[2];
-	__u8  signal[4];
-	__u8  pad06[4];
+	__u8  mode;
+	__u8  pad03[1];
+	struct {
+		__u8  signal[4];
+		__u16 logic_op;
+	} ctr[4];
 };
 
-#define NVIF_PERFCTR_V0_INIT                                               0x00
-#define NVIF_PERFCTR_V0_SAMPLE                                             0x01
-#define NVIF_PERFCTR_V0_READ                                               0x02
+#define NVIF_PERFDOM_V0_INIT                                               0x00
+#define NVIF_PERFDOM_V0_SAMPLE                                             0x01
+#define NVIF_PERFDOM_V0_READ                                               0x02
 
-struct nvif_perfctr_init {
+struct nvif_perfdom_init {
 };
 
-struct nvif_perfctr_sample {
+struct nvif_perfdom_sample {
 };
 
-struct nvif_perfctr_read_v0 {
+struct nvif_perfdom_read_v0 {
 	__u8  version;
 	__u8  pad01[7];
-	__u32 ctr;
+	__u32 ctr[4];
 	__u32 clk;
+	__u8  pad04[4];
 };
 
 
diff --git a/drm/nouveau/include/nvif/ioctl.h b/drm/nouveau/include/nvif/ioctl.h
index 517cd27..2eb9b89 100644
--- a/drm/nouveau/include/nvif/ioctl.h
+++ b/drm/nouveau/include/nvif/ioctl.h
@@ -50,7 +50,7 @@ struct nvif_ioctl_new_v0 {
 	__u32 handle;
 /* these class numbers are made up by us, and not nvidia-assigned */
 #define NVIF_IOCTL_NEW_V0_PERFMON                                    0x0000ffff
-#define NVIF_IOCTL_NEW_V0_PERFCTR                                    0x0000fffe
+#define NVIF_IOCTL_NEW_V0_PERFDOM                                    0x0000fffe
 #define NVIF_IOCTL_NEW_V0_CONTROL                                    0x0000fffd
 	__u32 oclass;
 	__u8  data[];		/* class data (class.h) */
diff --git a/drm/nouveau/nvkm/engine/pm/base.c b/drm/nouveau/nvkm/engine/pm/base.c
index 5dbb3b4..8960bf4 100644
--- a/drm/nouveau/nvkm/engine/pm/base.c
+++ b/drm/nouveau/nvkm/engine/pm/base.c
@@ -31,9 +31,6 @@
 #include <nvif/ioctl.h>
 #include <nvif/unpack.h>
 
-#define QUAD_MASK 0x0f
-#define QUAD_FREE 0x01
-
 static u8
 nvkm_pm_count_perfdom(struct nvkm_pm *ppm)
 {
@@ -304,32 +301,27 @@ nvkm_perfmon_ofuncs = {
 };
 
 /*******************************************************************************
- * Perfctr object classes
+ * Perfdom object classes
  ******************************************************************************/
 static int
-nvkm_perfctr_init(struct nvkm_object *object, void *data, u32 size)
+nvkm_perfdom_init(struct nvkm_object *object, void *data, u32 size)
 {
 	union {
-		struct nvif_perfctr_init none;
+		struct nvif_perfdom_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;
+	struct nvkm_perfdom *dom = (void *)object;
+	int ret, i;
 
-	nv_ioctl(object, "perfctr init size %d\n", size);
+	nv_ioctl(object, "perfdom init size %d\n", size);
 	if (nvif_unvers(args->none)) {
-		nv_ioctl(object, "perfctr init\n");
+		nv_ioctl(object, "perfdom 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);
+	for (i = 0; i < 4; i++)
+		if (dom->ctr[i])
+			dom->func->init(ppm, dom, dom->ctr[i]);
 
 	/* start next batch of counters for sampling */
 	dom->func->next(ppm, dom);
@@ -337,74 +329,70 @@ nvkm_perfctr_init(struct nvkm_object *object, void *data, u32 size)
 }
 
 static int
-nvkm_perfctr_sample(struct nvkm_object *object, void *data, u32 size)
+nvkm_perfdom_sample(struct nvkm_object *object, void *data, u32 size)
 {
 	union {
-		struct nvif_perfctr_sample none;
+		struct nvif_perfdom_sample none;
 	} *args = data;
 	struct nvkm_pm *ppm = (void *)object->engine;
-	struct nvkm_perfctr *ctr;
 	struct nvkm_perfdom *dom;
 	int ret;
 
-	nv_ioctl(object, "perfctr sample size %d\n", size);
+	nv_ioctl(object, "perfdom sample size %d\n", size);
 	if (nvif_unvers(args->none)) {
-		nv_ioctl(object, "perfctr sample\n");
+		nv_ioctl(object, "perfdom sample\n");
 	} else
 		return ret;
 	ppm->sequence++;
 
-	list_for_each_entry(dom, &ppm->domains, head) {
-		/* sample previous batch of counters */
-		if (dom->quad != QUAD_MASK) {
-			dom->func->next(ppm, dom);
-
-			/* read counter values */
-			list_for_each_entry(ctr, &dom->list, head) {
-				dom->func->read(ppm, dom, ctr);
-				ctr->slot = -1;
-			}
-
-			dom->quad = QUAD_MASK;
-		}
-	}
+	/* sample previous batch of counters */
+	list_for_each_entry(dom, &ppm->domains, head)
+		dom->func->next(ppm, dom);
 
 	return 0;
 }
 
 static int
-nvkm_perfctr_read(struct nvkm_object *object, void *data, u32 size)
+nvkm_perfdom_read(struct nvkm_object *object, void *data, u32 size)
 {
 	union {
-		struct nvif_perfctr_read_v0 v0;
+		struct nvif_perfdom_read_v0 v0;
 	} *args = data;
-	struct nvkm_perfctr *ctr = (void *)object;
-	int ret;
+	struct nvkm_pm *ppm = (void *)object->engine;
+	struct nvkm_perfdom *dom = (void *)object;
+	int ret, i;
 
-	nv_ioctl(object, "perfctr read size %d\n", size);
+	nv_ioctl(object, "perfdom read size %d\n", size);
 	if (nvif_unpack(args->v0, 0, 0, false)) {
-		nv_ioctl(object, "perfctr read vers %d\n", args->v0.version);
+		nv_ioctl(object, "perfdom read vers %d\n", args->v0.version);
 	} else
 		return ret;
 
-	if (!ctr->clk)
+	for (i = 0; i < 4; i++) {
+		if (dom->ctr[i])
+			dom->func->read(ppm, dom, dom->ctr[i]);
+	}
+
+	if (!dom->clk)
 		return -EAGAIN;
 
-	args->v0.clk = ctr->clk;
-	args->v0.ctr = ctr->ctr;
+	for (i = 0; i < 4; i++)
+		if (dom->ctr[i])
+			args->v0.ctr[i] = dom->ctr[i]->ctr;
+	args->v0.clk = dom->clk;
 	return 0;
 }
 
 static int
-nvkm_perfctr_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
+nvkm_perfdom_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:
-		return nvkm_perfctr_read(object, data, size);
+	case NVIF_PERFDOM_V0_INIT:
+		return nvkm_perfdom_init(object, data, size);
+	case NVIF_PERFDOM_V0_SAMPLE:
+		return nvkm_perfdom_sample(object, data, size);
+	case NVIF_PERFDOM_V0_READ:
+		return nvkm_perfdom_read(object, data, size);
 	default:
 		break;
 	}
@@ -412,70 +400,107 @@ nvkm_perfctr_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
 }
 
 static void
-nvkm_perfctr_dtor(struct nvkm_object *object)
+nvkm_perfdom_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);
+	struct nvkm_perfdom *dom = (void *)object;
+	int i;
+
+	for (i = 0; i < 4; i++) {
+		struct nvkm_perfctr *ctr = dom->ctr[i];
+		if (ctr && ctr->head.next)
+			list_del(&ctr->head);
+		kfree(ctr);
+	}
+	nvkm_object_destroy(&dom->base);
 }
 
 static int
-nvkm_perfctr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+nvkm_perfctr_new(struct nvkm_perfdom *dom, int slot,
+		 struct nvkm_perfsig *signal[4], uint16_t logic_op,
+		 struct nvkm_perfctr **pctr)
+{
+	struct nvkm_perfctr *ctr;
+	int i;
+
+	if (!dom)
+		return -EINVAL;
+
+	ctr = *pctr = kzalloc(sizeof(*ctr), GFP_KERNEL);
+	if (!ctr)
+		return -ENOMEM;
+
+	ctr->logic_op = logic_op;
+	ctr->slot     = slot;
+	for (i = 0; i < 4; i++) {
+		if (signal[i])
+			ctr->signal[i] = signal[i] - dom->signal;
+	}
+	list_add_tail(&ctr->head, &dom->list);
+
+	return 0;
+}
+
+static int
+nvkm_perfdom_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		  struct nvkm_oclass *oclass, void *data, u32 size,
 		  struct nvkm_object **pobject)
 {
 	union {
-		struct nvif_perfctr_v0 v0;
+		struct nvif_perfdom_v0 v0;
 	} *args = data;
 	struct nvkm_pm *ppm = (void *)engine;
-	struct nvkm_perfdom *dom = NULL;
-	struct nvkm_perfsig *sig[4] = {};
-	struct nvkm_perfctr *ctr;
-	int ret, i;
+	struct nvkm_perfdom *sdom = NULL;
+	struct nvkm_perfctr *ctr[4] = {};
+	struct nvkm_perfdom *dom;
+	int c, s;
+	int ret;
 
-	nv_ioctl(parent, "create perfctr size %d\n", size);
+	nv_ioctl(parent, "create perfdom size %d\n", size);
 	if (nvif_unpack(args->v0, 0, 0, false)) {
-		nv_ioctl(parent, "create perfctr vers %d logic_op %04x\n",
-			 args->v0.version, args->v0.logic_op);
+		nv_ioctl(parent, "create perfdom vers %d dom %d mode %02x\n",
+			 args->v0.version, args->v0.domain, args->v0.mode);
 	} else
 		return ret;
 
-	for (i = 0; i < ARRAY_SIZE(args->v0.signal); i++) {
-		sig[i] = nvkm_perfsig_find(ppm, args->v0.domain,
-					   args->v0.signal[i], &dom);
-		if (args->v0.signal[i] && !sig[i])
-			return -EINVAL;
+	for (c = 0; c < ARRAY_SIZE(args->v0.ctr); c++) {
+		struct nvkm_perfsig *sig[4] = {};
+		for (s = 0; s < ARRAY_SIZE(args->v0.ctr[c].signal); s++) {
+			sig[s] = nvkm_perfsig_find(ppm, args->v0.domain,
+						   args->v0.ctr[c].signal[s],
+						   &sdom);
+			if (args->v0.ctr[c].signal[s] && !sig[s])
+				return -EINVAL;
+		}
+
+		ret = nvkm_perfctr_new(sdom, c, sig,
+				       args->v0.ctr[c].logic_op, &ctr[c]);
+		if (ret)
+			return ret;
 	}
 
-	if (!dom)
+	if (!sdom)
 		return -EINVAL;
 
-	ret = nvkm_object_create(parent, engine, oclass, 0, &ctr);
-	*pobject = nv_object(ctr);
+	ret = nvkm_object_create(parent, engine, oclass, 0, &dom);
+	*pobject = nv_object(dom);
 	if (ret)
 		return ret;
 
-	ctr->dom = dom;
-	ctr->slot = -1;
-	ctr->logic_op = args->v0.logic_op;
-	ctr->signal[0] = sig[0];
-	ctr->signal[1] = sig[1];
-	ctr->signal[2] = sig[2];
-	ctr->signal[3] = sig[3];
-	list_add_tail(&ctr->head, &dom->list);
+	dom->func = sdom->func;
+	dom->addr = sdom->addr;
+	dom->mode = args->v0.mode;
+	for (c = 0; c < ARRAY_SIZE(ctr); c++)
+		dom->ctr[c] = ctr[c];
 	return 0;
 }
 
 static struct nvkm_ofuncs
-nvkm_perfctr_ofuncs = {
-	.ctor = nvkm_perfctr_ctor,
-	.dtor = nvkm_perfctr_dtor,
+nvkm_perfdom_ofuncs = {
+	.ctor = nvkm_perfdom_ctor,
+	.dtor = nvkm_perfdom_dtor,
 	.init = nvkm_object_init,
 	.fini = nvkm_object_fini,
-	.mthd = nvkm_perfctr_mthd,
+	.mthd = nvkm_perfdom_mthd,
 };
 
 struct nvkm_oclass
@@ -484,8 +509,8 @@ nvkm_pm_sclass[] = {
 	  .handle = NVIF_IOCTL_NEW_V0_PERFMON,
 	  .ofuncs = &nvkm_perfmon_ofuncs,
 	},
-	{ .handle = NVIF_IOCTL_NEW_V0_PERFCTR,
-	  .ofuncs = &nvkm_perfctr_ofuncs,
+	{ .handle = NVIF_IOCTL_NEW_V0_PERFDOM,
+	  .ofuncs = &nvkm_perfdom_ofuncs,
 	},
 	{},
 };
@@ -640,7 +665,6 @@ nvkm_perfdom_new(struct nvkm_pm *ppm, const char *name, u32 mask,
 			INIT_LIST_HEAD(&dom->list);
 			dom->func = sdom->func;
 			dom->addr = addr;
-			dom->quad = QUAD_MASK;
 			dom->signal_nr = sdom->signal_nr;
 
 			ssig = (sdom++)->signal;
diff --git a/drm/nouveau/nvkm/engine/pm/gf100.c b/drm/nouveau/nvkm/engine/pm/gf100.c
index 41350d6..edab97a 100644
--- a/drm/nouveau/nvkm/engine/pm/gf100.c
+++ b/drm/nouveau/nvkm/engine/pm/gf100.c
@@ -48,12 +48,10 @@ gf100_perfctr_init(struct nvkm_pm *ppm, struct nvkm_perfdom *dom,
 	u32 src = 0x00000000;
 	int i;
 
-	for (i = 0; i < 4; i++) {
-		if (ctr->signal[i])
-			src |= (ctr->signal[i] - dom->signal) << (i * 8);
-	}
+	for (i = 0; i < 4; i++)
+		src |= ctr->signal[i] << (i * 8);
 
-	nv_wr32(priv, dom->addr + 0x09c, 0x00040002);
+	nv_wr32(priv, dom->addr + 0x09c, 0x00040002 | (dom->mode << 3));
 	nv_wr32(priv, dom->addr + 0x100, 0x00000000);
 	nv_wr32(priv, dom->addr + 0x040 + (cntr->base.slot * 0x08), src);
 	nv_wr32(priv, dom->addr + 0x044 + (cntr->base.slot * 0x08), log);
@@ -72,7 +70,7 @@ gf100_perfctr_read(struct nvkm_pm *ppm, struct nvkm_perfdom *dom,
 	case 2: cntr->base.ctr = nv_rd32(priv, dom->addr + 0x080); break;
 	case 3: cntr->base.ctr = nv_rd32(priv, dom->addr + 0x090); break;
 	}
-	cntr->base.clk = nv_rd32(priv, dom->addr + 0x070);
+	dom->clk = nv_rd32(priv, dom->addr + 0x070);
 }
 
 static void
diff --git a/drm/nouveau/nvkm/engine/pm/nv40.c b/drm/nouveau/nvkm/engine/pm/nv40.c
index 603874e..1c6d1ca 100644
--- a/drm/nouveau/nvkm/engine/pm/nv40.c
+++ b/drm/nouveau/nvkm/engine/pm/nv40.c
@@ -33,12 +33,10 @@ nv40_perfctr_init(struct nvkm_pm *ppm, struct nvkm_perfdom *dom,
 	u32 src = 0x00000000;
 	int i;
 
-	for (i = 0; i < 4; i++) {
-		if (ctr->signal[i])
-			src |= (ctr->signal[i] - dom->signal) << (i * 8);
-	}
+	for (i = 0; i < 4; i++)
+		src |= ctr->signal[i] << (i * 8);
 
-	nv_wr32(priv, 0x00a7c0 + dom->addr, 0x00000001);
+	nv_wr32(priv, 0x00a7c0 + dom->addr, 0x00000001 | (dom->mode << 4));
 	nv_wr32(priv, 0x00a400 + dom->addr + (cntr->base.slot * 0x40), src);
 	nv_wr32(priv, 0x00a420 + dom->addr + (cntr->base.slot * 0x40), log);
 }
@@ -56,7 +54,7 @@ nv40_perfctr_read(struct nvkm_pm *ppm, struct nvkm_perfdom *dom,
 	case 2: cntr->base.ctr = nv_rd32(priv, 0x00a680 + dom->addr); break;
 	case 3: cntr->base.ctr = nv_rd32(priv, 0x00a740 + dom->addr); break;
 	}
-	cntr->base.clk = nv_rd32(priv, 0x00a600 + dom->addr);
+	dom->clk = nv_rd32(priv, 0x00a600 + dom->addr);
 }
 
 static void
diff --git a/drm/nouveau/nvkm/engine/pm/priv.h b/drm/nouveau/nvkm/engine/pm/priv.h
index 4ed77ff..38adeb7 100644
--- a/drm/nouveau/nvkm/engine/pm/priv.h
+++ b/drm/nouveau/nvkm/engine/pm/priv.h
@@ -3,13 +3,10 @@
 #include <engine/pm.h>
 
 struct nvkm_perfctr {
-	struct nvkm_object base;
 	struct list_head head;
-	struct nvkm_perfsig *signal[4];
-	struct nvkm_perfdom *dom;
+	u8  signal[4];
 	int slot;
 	u32 logic_op;
-	u32 clk;
 	u32 ctr;
 };
 
@@ -63,12 +60,15 @@ struct nvkm_specdom {
 };
 
 struct nvkm_perfdom {
+	struct nvkm_object base;
 	struct list_head head;
 	struct list_head list;
 	const struct nvkm_funcdom *func;
+	struct nvkm_perfctr *ctr[4];
 	char name[32];
 	u32 addr;
-	u8  quad;
+	u8  mode;
+	u32 clk;
 	u16 signal_nr;
 	struct nvkm_perfsig signal[];
 };
-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH RFC 17/20] pm: allow the userspace to configure sources
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (15 preceding siblings ...)
  2015-06-07 20:40   ` [PATCH RFC 16/20] pm: allow to configure domains instead of simple counters Samuel Pitoiset
@ 2015-06-07 20:40   ` Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 18/20] pm/nv50: add compute and graphics signals/sources Samuel Pitoiset
                     ` (2 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
---
 drm/nouveau/include/nvif/class.h  |   1 +
 drm/nouveau/nvkm/engine/pm/base.c | 102 ++++++++++++++++++++++++++++++++++----
 drm/nouveau/nvkm/engine/pm/priv.h |   2 +
 3 files changed, 95 insertions(+), 10 deletions(-)

diff --git a/drm/nouveau/include/nvif/class.h b/drm/nouveau/include/nvif/class.h
index 1a76a7f..3b7f49f 100644
--- a/drm/nouveau/include/nvif/class.h
+++ b/drm/nouveau/include/nvif/class.h
@@ -297,6 +297,7 @@ struct nvif_perfdom_v0 {
 	__u8  pad03[1];
 	struct {
 		__u8  signal[4];
+		__u64 source[4][8];
 		__u16 logic_op;
 	} ctr[4];
 };
diff --git a/drm/nouveau/nvkm/engine/pm/base.c b/drm/nouveau/nvkm/engine/pm/base.c
index 8960bf4..a4bb6fe 100644
--- a/drm/nouveau/nvkm/engine/pm/base.c
+++ b/drm/nouveau/nvkm/engine/pm/base.c
@@ -125,6 +125,66 @@ nvkm_perfsrc_find(struct nvkm_pm *ppm, struct nvkm_perfsig *sig, int si)
 	return NULL;
 }
 
+static int
+nvkm_perfsrc_enable(struct nvkm_pm *ppm, struct nvkm_perfctr *ctr)
+{
+	struct nvkm_perfdom *dom = NULL;
+	struct nvkm_perfsig *sig;
+	struct nvkm_perfsrc *src;
+	u32 mask, value;
+	int i, j;
+
+	for (i = 0; i < 4 && ctr->signal[i]; i++) {
+		for (j = 0; j < 8 && ctr->source[i][j]; j++) {
+			sig = nvkm_perfsig_find(ppm, ctr->domain,
+						ctr->signal[i], &dom);
+			if (!sig)
+				return -EINVAL;
+
+			src = nvkm_perfsrc_find(ppm, sig, ctr->source[i][j]);
+			if (!src)
+				return -EINVAL;
+
+			/* set enable bit if needed */
+			mask = value = 0x00000000;
+			if (src->enable)
+				mask = value = 0x80000000;
+			mask  |= (src->mask << src->shift);
+			value |= ((ctr->source[i][j] >> 32) << src->shift);
+
+			/* enable the source */
+			nv_mask(ppm, src->addr, mask, value);
+		}
+	}
+	return 0;
+}
+
+static int
+nvkm_perfsrc_disable(struct nvkm_pm *ppm, struct nvkm_perfctr *ctr)
+{
+	struct nvkm_perfdom *dom = NULL;
+	struct nvkm_perfsig *sig;
+	struct nvkm_perfsrc *src;
+	int i, j;
+
+	for (i = 0; i < 4 && ctr->signal[i]; i++) {
+		for (j = 0; j < 8 && ctr->source[i][j]; j++) {
+			sig = nvkm_perfsig_find(ppm, ctr->domain,
+						ctr->signal[i], &dom);
+			if (!sig)
+				return -EINVAL;
+
+			src = nvkm_perfsrc_find(ppm, sig, ctr->source[i][j]);
+			if (!src)
+				return -EINVAL;
+
+			/* disable the source */
+			nv_mask(ppm, src->addr, src->mask << src->shift, 0);
+		}
+	}
+	return 0;
+}
+
 /*******************************************************************************
  * Perfmon object classes
  ******************************************************************************/
@@ -319,10 +379,15 @@ nvkm_perfdom_init(struct nvkm_object *object, void *data, u32 size)
 	} else
 		return ret;
 
-	for (i = 0; i < 4; i++)
-		if (dom->ctr[i])
+	for (i = 0; i < 4; i++) {
+		if (dom->ctr[i]) {
 			dom->func->init(ppm, dom, dom->ctr[i]);
 
+			/* enable sources */
+			nvkm_perfsrc_enable(ppm, dom->ctr[i]);
+		}
+	}
+
 	/* start next batch of counters for sampling */
 	dom->func->next(ppm, dom);
 	return 0;
@@ -402,13 +467,17 @@ nvkm_perfdom_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
 static void
 nvkm_perfdom_dtor(struct nvkm_object *object)
 {
+	struct nvkm_pm *ppm = (void *)object->engine;
 	struct nvkm_perfdom *dom = (void *)object;
 	int i;
 
 	for (i = 0; i < 4; i++) {
 		struct nvkm_perfctr *ctr = dom->ctr[i];
-		if (ctr && ctr->head.next)
-			list_del(&ctr->head);
+		if (ctr) {
+			nvkm_perfsrc_disable(ppm, ctr);
+			if (ctr->head.next)
+				list_del(&ctr->head);
+		}
 		kfree(ctr);
 	}
 	nvkm_object_destroy(&dom->base);
@@ -416,11 +485,11 @@ nvkm_perfdom_dtor(struct nvkm_object *object)
 
 static int
 nvkm_perfctr_new(struct nvkm_perfdom *dom, int slot,
-		 struct nvkm_perfsig *signal[4], uint16_t logic_op,
-		 struct nvkm_perfctr **pctr)
+		 struct nvkm_perfsig *signal[4], uint64_t source[4][8],
+		 uint16_t logic_op, struct nvkm_perfctr **pctr)
 {
 	struct nvkm_perfctr *ctr;
-	int i;
+	int i, j;
 
 	if (!dom)
 		return -EINVAL;
@@ -432,8 +501,11 @@ nvkm_perfctr_new(struct nvkm_perfdom *dom, int slot,
 	ctr->logic_op = logic_op;
 	ctr->slot     = slot;
 	for (i = 0; i < 4; i++) {
-		if (signal[i])
+		if (signal[i]) {
 			ctr->signal[i] = signal[i] - dom->signal;
+			for (j = 0; j < 8; j++)
+				ctr->source[i][j] = source[i][j];
+		}
 	}
 	list_add_tail(&ctr->head, &dom->list);
 
@@ -452,7 +524,7 @@ nvkm_perfdom_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	struct nvkm_perfdom *sdom = NULL;
 	struct nvkm_perfctr *ctr[4] = {};
 	struct nvkm_perfdom *dom;
-	int c, s;
+	int c, s, m;
 	int ret;
 
 	nv_ioctl(parent, "create perfdom size %d\n", size);
@@ -464,18 +536,28 @@ nvkm_perfdom_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 
 	for (c = 0; c < ARRAY_SIZE(args->v0.ctr); c++) {
 		struct nvkm_perfsig *sig[4] = {};
+		u64 src[4][8];
+
 		for (s = 0; s < ARRAY_SIZE(args->v0.ctr[c].signal); s++) {
 			sig[s] = nvkm_perfsig_find(ppm, args->v0.domain,
 						   args->v0.ctr[c].signal[s],
 						   &sdom);
 			if (args->v0.ctr[c].signal[s] && !sig[s])
 				return -EINVAL;
+
+			for (m = 0; m < 8; m++) {
+				src[s][m] = args->v0.ctr[c].source[s][m];
+				if (src[s][m] && !nvkm_perfsrc_find(ppm, sig[s],
+							            src[s][m]))
+					return -EINVAL;
+			}
 		}
 
-		ret = nvkm_perfctr_new(sdom, c, sig,
+		ret = nvkm_perfctr_new(sdom, c, sig, src,
 				       args->v0.ctr[c].logic_op, &ctr[c]);
 		if (ret)
 			return ret;
+		ctr[c]->domain = args->v0.domain;
 	}
 
 	if (!sdom)
diff --git a/drm/nouveau/nvkm/engine/pm/priv.h b/drm/nouveau/nvkm/engine/pm/priv.h
index 38adeb7..da419c1 100644
--- a/drm/nouveau/nvkm/engine/pm/priv.h
+++ b/drm/nouveau/nvkm/engine/pm/priv.h
@@ -4,7 +4,9 @@
 
 struct nvkm_perfctr {
 	struct list_head head;
+	u8 domain;
 	u8  signal[4];
+	u64 source[4][8];
 	int slot;
 	u32 logic_op;
 	u32 ctr;
-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH RFC 18/20] pm/nv50: add compute and graphics signals/sources
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (16 preceding siblings ...)
  2015-06-07 20:40   ` [PATCH RFC 17/20] pm: allow the userspace to configure sources Samuel Pitoiset
@ 2015-06-07 20:40   ` Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 19/20] sw/nv50: add some private functions to factorize code Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 20/20] sw/nv50: add and interface for controlling performance counters Samuel Pitoiset
  19 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

These signals and sources have been reverse engineered from NVIDIA
PerfKit (Windows) and CUPTI (Linux), they will be used to build complex
hardware events from the userspace.

This commit also adds a new class for GT200.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
---
 drm/nouveau/include/nvkm/engine/pm.h  |   1 +
 drm/nouveau/nvkm/engine/device/nv50.c |   2 +-
 drm/nouveau/nvkm/engine/pm/Kbuild     |   1 +
 drm/nouveau/nvkm/engine/pm/g84.c      | 101 ++++++++++++++++++++-
 drm/nouveau/nvkm/engine/pm/gt200.c    | 163 ++++++++++++++++++++++++++++++++++
 drm/nouveau/nvkm/engine/pm/gt215.c    |  84 +++++++++++++++++-
 drm/nouveau/nvkm/engine/pm/nv50.c     | 136 ++++++++++++++++++++++++++--
 drm/nouveau/nvkm/engine/pm/priv.h     |   8 ++
 8 files changed, 485 insertions(+), 11 deletions(-)
 create mode 100644 drm/nouveau/nvkm/engine/pm/gt200.c

diff --git a/drm/nouveau/include/nvkm/engine/pm.h b/drm/nouveau/include/nvkm/engine/pm.h
index 130b545..82f1c7f 100644
--- a/drm/nouveau/include/nvkm/engine/pm.h
+++ b/drm/nouveau/include/nvkm/engine/pm.h
@@ -24,6 +24,7 @@ nvkm_pm(void *obj)
 extern struct nvkm_oclass *nv40_pm_oclass;
 extern struct nvkm_oclass *nv50_pm_oclass;
 extern struct nvkm_oclass *g84_pm_oclass;
+extern struct nvkm_oclass *gt200_pm_oclass;
 extern struct nvkm_oclass *gt215_pm_oclass;
 extern struct nvkm_oclass gf100_pm_oclass;
 extern struct nvkm_oclass gk104_pm_oclass;
diff --git a/drm/nouveau/nvkm/engine/device/nv50.c b/drm/nouveau/nvkm/engine/device/nv50.c
index 249b844..a2627ec 100644
--- a/drm/nouveau/nvkm/engine/device/nv50.c
+++ b/drm/nouveau/nvkm/engine/device/nv50.c
@@ -288,7 +288,7 @@ nv50_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_ENGINE_CIPHER ] = &g84_cipher_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &g84_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_DISP   ] =  gt200_disp_oclass;
-		device->oclass[NVDEV_ENGINE_PM     ] =  g84_pm_oclass;
+		device->oclass[NVDEV_ENGINE_PM     ] =  gt200_pm_oclass;
 		break;
 	case 0xaa:
 		device->cname = "MCP77/MCP78";
diff --git a/drm/nouveau/nvkm/engine/pm/Kbuild b/drm/nouveau/nvkm/engine/pm/Kbuild
index c5ee8d5..cc01048 100644
--- a/drm/nouveau/nvkm/engine/pm/Kbuild
+++ b/drm/nouveau/nvkm/engine/pm/Kbuild
@@ -2,6 +2,7 @@ nvkm-y += nvkm/engine/pm/base.o
 nvkm-y += nvkm/engine/pm/nv40.o
 nvkm-y += nvkm/engine/pm/nv50.o
 nvkm-y += nvkm/engine/pm/g84.o
+nvkm-y += nvkm/engine/pm/gt200.o
 nvkm-y += nvkm/engine/pm/gt215.o
 nvkm-y += nvkm/engine/pm/gf100.o
 nvkm-y += nvkm/engine/pm/gk104.o
diff --git a/drm/nouveau/nvkm/engine/pm/g84.c b/drm/nouveau/nvkm/engine/pm/g84.c
index d54c670..dda539c 100644
--- a/drm/nouveau/nvkm/engine/pm/g84.c
+++ b/drm/nouveau/nvkm/engine/pm/g84.c
@@ -23,15 +23,112 @@
  */
 #include "nv40.h"
 
+const struct nvkm_specsrc
+g84_vfetch_sources[] = {
+	{ 0x400c0c, (const struct nvkm_specmux[]) {
+			{ 0x3, 0, "unk0" },
+			{}
+		}, "pgraph_vfetch_unk0c" },
+	{}
+};
+
+static const struct nvkm_specsrc
+g84_crop_sources[] = {
+	{ 0x407008, (const struct nvkm_specmux[]) {
+			{ 0xf, 0, "sel0", true },
+			{ 0x7, 16, "sel1", true },
+			{}
+		}, "pgraph_rop0_crop_pm_mux" },
+	{}
+};
+
+static const struct nvkm_specsrc
+g84_tex_sources[] = {
+	{ 0x408808, (const struct nvkm_specmux[]) {
+			{ 0xfffff, 0, "unk0" },
+			{}
+		}, "pgraph_tpc0_tex_unk08" },
+	{}
+};
+
 static const struct nvkm_specdom
 g84_pm[] = {
 	{ 0x20, (const struct nvkm_specsig[]) {
 			{}
 		}, &nv40_perfctr_func },
-	{ 0x20, (const struct nvkm_specsig[]) {
+	{ 0xf0, (const struct nvkm_specsig[]) {
+			{ 0xbd, "pc01_gr_idle" },
+			{ 0x5e, "pc01_strmout_00" },
+			{ 0x5f, "pc01_strmout_01" },
+			{ 0xd2, "pc01_trast_00" },
+			{ 0xd3, "pc01_trast_01" },
+			{ 0xd4, "pc01_trast_02" },
+			{ 0xd5, "pc01_trast_03" },
+			{ 0xd8, "pc01_trast_04" },
+			{ 0xd9, "pc01_trast_05" },
+			{ 0x5c, "pc01_vattr_00" },
+			{ 0x5d, "pc01_vattr_01" },
+			{ 0x66, "pc01_vfetch_00", g84_vfetch_sources },
+			{ 0x67, "pc01_vfetch_01", g84_vfetch_sources },
+			{ 0x68, "pc01_vfetch_02", g84_vfetch_sources },
+			{ 0x69, "pc01_vfetch_03", g84_vfetch_sources },
+			{ 0x6a, "pc01_vfetch_04", g84_vfetch_sources },
+			{ 0x6b, "pc01_vfetch_05", g84_vfetch_sources },
+			{ 0x6c, "pc01_vfetch_06", g84_vfetch_sources },
+			{ 0x6d, "pc01_vfetch_07", g84_vfetch_sources },
+			{ 0x6e, "pc01_vfetch_08", g84_vfetch_sources },
+			{ 0x6f, "pc01_vfetch_09", g84_vfetch_sources },
+			{ 0x70, "pc01_vfetch_0a", g84_vfetch_sources },
+			{ 0x71, "pc01_vfetch_0b", g84_vfetch_sources },
+			{ 0x72, "pc01_vfetch_0c", g84_vfetch_sources },
+			{ 0x73, "pc01_vfetch_0d", g84_vfetch_sources },
+			{ 0x74, "pc01_vfetch_0e", g84_vfetch_sources },
+			{ 0x75, "pc01_vfetch_0f", g84_vfetch_sources },
+			{ 0x76, "pc01_vfetch_10", g84_vfetch_sources },
+			{ 0x77, "pc01_vfetch_11", g84_vfetch_sources },
+			{ 0x78, "pc01_vfetch_12", g84_vfetch_sources },
+			{ 0x79, "pc01_vfetch_13", g84_vfetch_sources },
+			{ 0x7a, "pc01_vfetch_14", g84_vfetch_sources },
+			{ 0x7b, "pc01_vfetch_15", g84_vfetch_sources },
+			{ 0x7c, "pc01_vfetch_16", g84_vfetch_sources },
+			{ 0x7d, "pc01_vfetch_17", g84_vfetch_sources },
+			{ 0x7e, "pc01_vfetch_18", g84_vfetch_sources },
+			{ 0x7f, "pc01_vfetch_19", g84_vfetch_sources },
+			{ 0x07, "pc01_zcull_00", nv50_zcull_sources },
+			{ 0x08, "pc01_zcull_01", nv50_zcull_sources },
+			{ 0x09, "pc01_zcull_02", nv50_zcull_sources },
+			{ 0x0a, "pc01_zcull_03", nv50_zcull_sources },
+			{ 0x0b, "pc01_zcull_04", nv50_zcull_sources },
+			{ 0x0c, "pc01_zcull_05", nv50_zcull_sources },
+			{ 0xa4, "pc01_unk00" },
+			{ 0xec, "pc01_trailer" },
 			{}
 		}, &nv40_perfctr_func },
-	{ 0x20, (const struct nvkm_specsig[]) {
+	{ 0xa0, (const struct nvkm_specsig[]) {
+			{ 0x30, "pc02_crop_00", g84_crop_sources },
+			{ 0x31, "pc02_crop_01", g84_crop_sources },
+			{ 0x32, "pc02_crop_02", g84_crop_sources },
+			{ 0x33, "pc02_crop_03", g84_crop_sources },
+			{ 0x00, "pc02_prop_00", nv50_prop_sources },
+			{ 0x01, "pc02_prop_01", nv50_prop_sources },
+			{ 0x02, "pc02_prop_02", nv50_prop_sources },
+			{ 0x03, "pc02_prop_03", nv50_prop_sources },
+			{ 0x04, "pc02_prop_04", nv50_prop_sources },
+			{ 0x05, "pc02_prop_05", nv50_prop_sources },
+			{ 0x06, "pc02_prop_06", nv50_prop_sources },
+			{ 0x07, "pc02_prop_07", nv50_prop_sources },
+			{ 0x48, "pc02_tex_00", g84_tex_sources },
+			{ 0x49, "pc02_tex_01", g84_tex_sources },
+			{ 0x4a, "pc02_tex_02", g84_tex_sources },
+			{ 0x4b, "pc02_tex_03", g84_tex_sources },
+			{ 0x1a, "pc02_tex_04", g84_tex_sources },
+			{ 0x1b, "pc02_tex_05", g84_tex_sources },
+			{ 0x1c, "pc02_tex_06", g84_tex_sources },
+			{ 0x44, "pc02_zrop_00", nv50_zrop_sources },
+			{ 0x45, "pc02_zrop_01", nv50_zrop_sources },
+			{ 0x46, "pc02_zrop_02", nv50_zrop_sources },
+			{ 0x47, "pc02_zrop_03", nv50_zrop_sources },
+			{ 0x8c, "pc02_trailer" },
 			{}
 		}, &nv40_perfctr_func },
 	{ 0x20, (const struct nvkm_specsig[]) {
diff --git a/drm/nouveau/nvkm/engine/pm/gt200.c b/drm/nouveau/nvkm/engine/pm/gt200.c
new file mode 100644
index 0000000..220a027
--- /dev/null
+++ b/drm/nouveau/nvkm/engine/pm/gt200.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2015 Nouveau project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Samuel Pitoiset
+ */
+#include "nv40.h"
+
+const struct nvkm_specsrc
+gt200_crop_sources[] = {
+	{ 0x407008, (const struct nvkm_specmux[]) {
+			{ 0x7, 0, "sel0", true },
+			{ 0x1f, 16, "sel1", true },
+			{}
+		}, "pgraph_rop0_crop_pm_mux" },
+	{}
+};
+
+const struct nvkm_specsrc
+gt200_prop_sources[] = {
+	{ 0x408750, (const struct nvkm_specmux[]) {
+			{ 0x3f, 0, "sel", true },
+			{}
+		}, "pgraph_tpc0_prop_pm_mux" },
+	{}
+};
+
+const struct nvkm_specsrc
+gt200_tex_sources[] = {
+	{ 0x408508, (const struct nvkm_specmux[]) {
+			{ 0x3fff, 0, "unk0" },
+			{}
+		}, "pgraph_tpc0_tex_unk08" },
+	{}
+};
+
+static const struct nvkm_specdom
+gt200_pm[] = {
+	{ 0x20, (const struct nvkm_specsig[]) {
+			{}
+		}, &nv40_perfctr_func },
+	{ 0xf0, (const struct nvkm_specsig[]) {
+			{ 0xc9, "pc01_gr_idle" },
+			{ 0x84, "pc01_strmout_00" },
+			{ 0x85, "pc01_strmout_01" },
+			{ 0xde, "pc01_trast_00" },
+			{ 0xdf, "pc01_trast_01" },
+			{ 0xe0, "pc01_trast_02" },
+			{ 0xe1, "pc01_trast_03" },
+			{ 0xe4, "pc01_trast_04" },
+			{ 0xe5, "pc01_trast_05" },
+			{ 0x82, "pc01_vattr_00" },
+			{ 0x83, "pc01_vattr_01" },
+			{ 0x46, "pc01_vfetch_00", g84_vfetch_sources },
+			{ 0x47, "pc01_vfetch_01", g84_vfetch_sources },
+			{ 0x48, "pc01_vfetch_02", g84_vfetch_sources },
+			{ 0x49, "pc01_vfetch_03", g84_vfetch_sources },
+			{ 0x4a, "pc01_vfetch_04", g84_vfetch_sources },
+			{ 0x4b, "pc01_vfetch_05", g84_vfetch_sources },
+			{ 0x4c, "pc01_vfetch_06", g84_vfetch_sources },
+			{ 0x4d, "pc01_vfetch_07", g84_vfetch_sources },
+			{ 0x4e, "pc01_vfetch_08", g84_vfetch_sources },
+			{ 0x4f, "pc01_vfetch_09", g84_vfetch_sources },
+			{ 0x50, "pc01_vfetch_0a", g84_vfetch_sources },
+			{ 0x51, "pc01_vfetch_0b", g84_vfetch_sources },
+			{ 0x52, "pc01_vfetch_0c", g84_vfetch_sources },
+			{ 0x53, "pc01_vfetch_0d", g84_vfetch_sources },
+			{ 0x54, "pc01_vfetch_0e", g84_vfetch_sources },
+			{ 0x55, "pc01_vfetch_0f", g84_vfetch_sources },
+			{ 0x56, "pc01_vfetch_10", g84_vfetch_sources },
+			{ 0x57, "pc01_vfetch_11", g84_vfetch_sources },
+			{ 0x58, "pc01_vfetch_12", g84_vfetch_sources },
+			{ 0x59, "pc01_vfetch_13", g84_vfetch_sources },
+			{ 0x5a, "pc01_vfetch_14", g84_vfetch_sources },
+			{ 0x5b, "pc01_vfetch_15", g84_vfetch_sources },
+			{ 0x5c, "pc01_vfetch_16", g84_vfetch_sources },
+			{ 0x5d, "pc01_vfetch_17", g84_vfetch_sources },
+			{ 0x5e, "pc01_vfetch_18", g84_vfetch_sources },
+			{ 0x5f, "pc01_vfetch_19", g84_vfetch_sources },
+         { 0x07, "pc01_zcull_00", nv50_zcull_sources },
+			{ 0x08, "pc01_zcull_01", nv50_zcull_sources },
+			{ 0x09, "pc01_zcull_02", nv50_zcull_sources },
+			{ 0x0a, "pc01_zcull_03", nv50_zcull_sources },
+			{ 0x0b, "pc01_zcull_04", nv50_zcull_sources },
+			{ 0x0c, "pc01_zcull_05", nv50_zcull_sources },
+
+			{ 0xb0, "pc01_unk00" },
+			{ 0xec, "pc01_trailer" },
+			{}
+		}, &nv40_perfctr_func },
+	{ 0xe0, (const struct nvkm_specsig[]) {
+			{ 0x55, "pc02_crop_00", gt200_crop_sources },
+			{ 0x56, "pc02_crop_01", gt200_crop_sources },
+			{ 0x57, "pc02_crop_02", gt200_crop_sources },
+			{ 0x58, "pc02_crop_03", gt200_crop_sources },
+			{ 0x00, "pc02_prop_00", gt200_prop_sources },
+			{ 0x01, "pc02_prop_01", gt200_prop_sources },
+			{ 0x02, "pc02_prop_02", gt200_prop_sources },
+			{ 0x03, "pc02_prop_03", gt200_prop_sources },
+			{ 0x04, "pc02_prop_04", gt200_prop_sources },
+			{ 0x05, "pc02_prop_05", gt200_prop_sources },
+			{ 0x06, "pc02_prop_06", gt200_prop_sources },
+			{ 0x07, "pc02_prop_07", gt200_prop_sources },
+			{ 0x78, "pc02_tex_00", gt200_tex_sources },
+			{ 0x79, "pc02_tex_01", gt200_tex_sources },
+			{ 0x7a, "pc02_tex_02", gt200_tex_sources },
+			{ 0x7b, "pc02_tex_03", gt200_tex_sources },
+			{ 0x32, "pc02_tex_04", gt200_tex_sources },
+			{ 0x33, "pc02_tex_05", gt200_tex_sources },
+			{ 0x34, "pc02_tex_06", gt200_tex_sources },
+			{ 0x74, "pc02_zrop_00", nv50_zrop_sources },
+			{ 0x75, "pc02_zrop_01", nv50_zrop_sources },
+			{ 0x76, "pc02_zrop_02", nv50_zrop_sources },
+			{ 0x77, "pc02_zrop_03", nv50_zrop_sources },
+			{ 0xec, "pc02_trailer" },
+			{}
+		}, &nv40_perfctr_func },
+	{ 0x20, (const struct nvkm_specsig[]) {
+			{}
+		}, &nv40_perfctr_func },
+	{ 0x20, (const struct nvkm_specsig[]) {
+			{}
+		}, &nv40_perfctr_func },
+	{ 0x20, (const struct nvkm_specsig[]) {
+			{}
+		}, &nv40_perfctr_func },
+	{ 0x20, (const struct nvkm_specsig[]) {
+			{}
+		}, &nv40_perfctr_func },
+	{ 0x20, (const struct nvkm_specsig[]) {
+			{}
+		}, &nv40_perfctr_func },
+	{}
+};
+
+struct nvkm_oclass *
+gt200_pm_oclass = &(struct nv40_pm_oclass) {
+	.base.handle = NV_ENGINE(PM, 0xa0),
+	.base.ofuncs = &(struct nvkm_ofuncs) {
+		.ctor = nv40_pm_ctor,
+		.dtor = _nvkm_pm_dtor,
+		.init = _nvkm_pm_init,
+		.fini = _nvkm_pm_fini,
+	},
+	.doms = gt200_pm,
+}.base;
diff --git a/drm/nouveau/nvkm/engine/pm/gt215.c b/drm/nouveau/nvkm/engine/pm/gt215.c
index ab69ab5..b5542dc 100644
--- a/drm/nouveau/nvkm/engine/pm/gt215.c
+++ b/drm/nouveau/nvkm/engine/pm/gt215.c
@@ -23,15 +23,95 @@
  */
 #include "nv40.h"
 
+// TODO: check for GT200
+static const struct nvkm_specsrc
+gt215_zcull_sources[] = {
+	{ 0x4002ca4, (const struct nvkm_specmux[]) {
+			{ 0x7fff, 0, "unk0" },
+			{ 0xff, 24, "unk24" },
+			{}
+		}, "pgraph_zcull_pm_unka4" },
+	{}
+};
+
 static const struct nvkm_specdom
 gt215_pm[] = {
 	{ 0x20, (const struct nvkm_specsig[]) {
 			{}
 		}, &nv40_perfctr_func },
-	{ 0x20, (const struct nvkm_specsig[]) {
+	{ 0xf0, (const struct nvkm_specsig[]) {
+			{ 0xcb, "pc01_gr_idle" },
+			{ 0x86, "pc01_strmout_00" },
+			{ 0x87, "pc01_strmout_01" },
+			{ 0xe0, "pc01_trast_00" },
+			{ 0xe1, "pc01_trast_01" },
+			{ 0xe2, "pc01_trast_02" },
+			{ 0xe3, "pc01_trast_03" },
+			{ 0xe6, "pc01_trast_04" },
+			{ 0xe7, "pc01_trast_05" },
+			{ 0x84, "pc01_vattr_00" },
+			{ 0x85, "pc01_vattr_01" },
+			{ 0x46, "pc01_vfetch_00", g84_vfetch_sources },
+			{ 0x47, "pc01_vfetch_01", g84_vfetch_sources },
+			{ 0x48, "pc01_vfetch_02", g84_vfetch_sources },
+			{ 0x49, "pc01_vfetch_03", g84_vfetch_sources },
+			{ 0x4a, "pc01_vfetch_04", g84_vfetch_sources },
+			{ 0x4b, "pc01_vfetch_05", g84_vfetch_sources },
+			{ 0x4c, "pc01_vfetch_06", g84_vfetch_sources },
+			{ 0x4d, "pc01_vfetch_07", g84_vfetch_sources },
+			{ 0x4e, "pc01_vfetch_08", g84_vfetch_sources },
+			{ 0x4f, "pc01_vfetch_09", g84_vfetch_sources },
+			{ 0x50, "pc01_vfetch_0a", g84_vfetch_sources },
+			{ 0x51, "pc01_vfetch_0b", g84_vfetch_sources },
+			{ 0x52, "pc01_vfetch_0c", g84_vfetch_sources },
+			{ 0x53, "pc01_vfetch_0d", g84_vfetch_sources },
+			{ 0x54, "pc01_vfetch_0e", g84_vfetch_sources },
+			{ 0x55, "pc01_vfetch_0f", g84_vfetch_sources },
+			{ 0x56, "pc01_vfetch_10", g84_vfetch_sources },
+			{ 0x57, "pc01_vfetch_11", g84_vfetch_sources },
+			{ 0x58, "pc01_vfetch_12", g84_vfetch_sources },
+			{ 0x59, "pc01_vfetch_13", g84_vfetch_sources },
+			{ 0x5a, "pc01_vfetch_14", g84_vfetch_sources },
+			{ 0x5b, "pc01_vfetch_15", g84_vfetch_sources },
+			{ 0x5c, "pc01_vfetch_16", g84_vfetch_sources },
+			{ 0x5d, "pc01_vfetch_17", g84_vfetch_sources },
+			{ 0x5e, "pc01_vfetch_18", g84_vfetch_sources },
+			{ 0x5f, "pc01_vfetch_19", g84_vfetch_sources },
+			{ 0x07, "pc01_zcull_00", gt215_zcull_sources },
+			{ 0x08, "pc01_zcull_01", gt215_zcull_sources },
+			{ 0x09, "pc01_zcull_02", gt215_zcull_sources },
+			{ 0x0a, "pc01_zcull_03", gt215_zcull_sources },
+			{ 0x0b, "pc01_zcull_04", gt215_zcull_sources },
+			{ 0x0c, "pc01_zcull_05", gt215_zcull_sources },
+			{ 0xb2, "pc01_unk00" },
+			{ 0xec, "pc01_trailer" },
 			{}
 		}, &nv40_perfctr_func },
-	{ 0x20, (const struct nvkm_specsig[]) {
+	{ 0xe0, (const struct nvkm_specsig[]) {
+			{ 0x64, "pc02_crop_00", gt200_crop_sources },
+			{ 0x65, "pc02_crop_01", gt200_crop_sources },
+			{ 0x66, "pc02_crop_02", gt200_crop_sources },
+			{ 0x67, "pc02_crop_03", gt200_crop_sources },
+			{ 0x00, "pc02_prop_00", gt200_prop_sources },
+			{ 0x01, "pc02_prop_01", gt200_prop_sources },
+			{ 0x02, "pc02_prop_02", gt200_prop_sources },
+			{ 0x03, "pc02_prop_03", gt200_prop_sources },
+			{ 0x04, "pc02_prop_04", gt200_prop_sources },
+			{ 0x05, "pc02_prop_05", gt200_prop_sources },
+			{ 0x06, "pc02_prop_06", gt200_prop_sources },
+			{ 0x07, "pc02_prop_07", gt200_prop_sources },
+			{ 0x80, "pc02_tex_00", gt200_tex_sources },
+			{ 0x81, "pc02_tex_01", gt200_tex_sources },
+			{ 0x82, "pc02_tex_02", gt200_tex_sources },
+			{ 0x83, "pc02_tex_03", gt200_tex_sources },
+			{ 0x3a, "pc02_tex_04", gt200_tex_sources },
+			{ 0x3b, "pc02_tex_05", gt200_tex_sources },
+			{ 0x3c, "pc02_tex_06", gt200_tex_sources },
+			{ 0x7c, "pc02_zrop_00", nv50_zrop_sources },
+			{ 0x7d, "pc02_zrop_01", nv50_zrop_sources },
+			{ 0x7e, "pc02_zrop_02", nv50_zrop_sources },
+			{ 0x7f, "pc02_zrop_03", nv50_zrop_sources },
+			{ 0xcc, "pc02_trailer" },
 			{}
 		}, &nv40_perfctr_func },
 	{ 0x20, (const struct nvkm_specsig[]) {
diff --git a/drm/nouveau/nvkm/engine/pm/nv50.c b/drm/nouveau/nvkm/engine/pm/nv50.c
index 6af83b5..a778bc7 100644
--- a/drm/nouveau/nvkm/engine/pm/nv50.c
+++ b/drm/nouveau/nvkm/engine/pm/nv50.c
@@ -23,22 +23,146 @@
  */
 #include "nv40.h"
 
+const struct nvkm_specsrc
+nv50_prop_sources[] = {
+	{ 0x408e50, (const struct nvkm_specmux[]) {
+			{ 0x1f, 0, "sel", true },
+			{}
+		}, "pgraph_tpc0_prop_pm_mux" },
+	{}
+};
+
+const struct nvkm_specsrc
+nv50_zcull_sources[] = {
+	{ 0x4002ca4, (const struct nvkm_specmux[]) {
+			{ 0x7fff, 0, "unk0" },
+			{}
+		}, "pgraph_zcull_pm_unka4" },
+	{}
+};
+
+const struct nvkm_specsrc
+nv50_zrop_sources[] = {
+	{ 0x40708c, (const struct nvkm_specmux[]) {
+			{ 0xf, 0, "sel0", true },
+			{ 0xf, 16, "sel1", true },
+			{}
+		}, "pgraph_rop0_zrop_pm_mux" },
+	{}
+};
+
+static const struct nvkm_specsrc
+nv50_crop_sources[] = {
+        { 0x407008, (const struct nvkm_specmux[]) {
+                        { 0x7, 0, "sel0", true },
+                        { 0x7, 16, "sel1", true },
+                        {}
+                }, "pgraph_rop0_crop_pm_mux" },
+        {}
+};
+
+static const struct nvkm_specsrc
+nv50_tex_sources[] = {
+	{ 0x408808, (const struct nvkm_specmux[]) {
+			{ 0x3fff, 0, "unk0" },
+			{}
+		}, "pgraph_tpc0_tex_unk08" },
+	{}
+};
+
+static const struct nvkm_specsrc
+nv50_vfetch_sources[] = {
+	{ 0x400c0c, (const struct nvkm_specmux[]) {
+			{ 0x1, 0, "unk0" },
+			{}
+		}, "pgraph_vfetch_unk0c" },
+	{}
+};
+
 static const struct nvkm_specdom
 nv50_pm[] = {
-	{ 0x040, (const struct nvkm_specsig[]) {
+	{ 0x20, (const struct nvkm_specsig[]) {
 			{}
 		}, &nv40_perfctr_func },
-	{ 0x100, (const struct nvkm_specsig[]) {
-			{ 0xc8, "gr_idle" },
+	{ 0xf0, (const struct nvkm_specsig[]) {
+			{ 0xc8, "pc01_gr_idle" },
+			{ 0x7f, "pc01_strmout_00" },
+			{ 0x80, "pc01_strmout_01" },
+			{ 0xdc, "pc01_trast_00" },
+			{ 0xdd, "pc01_trast_01" },
+			{ 0xde, "pc01_trast_02" },
+			{ 0xdf, "pc01_trast_03" },
+			{ 0xe2, "pc01_trast_04" },
+			{ 0xe3, "pc01_trast_05" },
+			{ 0x7c, "pc01_vattr_00" },
+			{ 0x7d, "pc01_vattr_01" },
+			{ 0x26, "pc01_vfetch_00", nv50_vfetch_sources },
+			{ 0x27, "pc01_vfetch_01", nv50_vfetch_sources },
+			{ 0x28, "pc01_vfetch_02", nv50_vfetch_sources },
+			{ 0x29, "pc01_vfetch_03", nv50_vfetch_sources },
+			{ 0x2a, "pc01_vfetch_04", nv50_vfetch_sources },
+			{ 0x2b, "pc01_vfetch_05", nv50_vfetch_sources },
+			{ 0x2c, "pc01_vfetch_06", nv50_vfetch_sources },
+			{ 0x2d, "pc01_vfetch_07", nv50_vfetch_sources },
+			{ 0x2e, "pc01_vfetch_08", nv50_vfetch_sources },
+			{ 0x2f, "pc01_vfetch_09", nv50_vfetch_sources },
+			{ 0x30, "pc01_vfetch_0a", nv50_vfetch_sources },
+			{ 0x31, "pc01_vfetch_0b", nv50_vfetch_sources },
+			{ 0x32, "pc01_vfetch_0c", nv50_vfetch_sources },
+			{ 0x33, "pc01_vfetch_0d", nv50_vfetch_sources },
+			{ 0x34, "pc01_vfetch_0e", nv50_vfetch_sources },
+			{ 0x35, "pc01_vfetch_0f", nv50_vfetch_sources },
+			{ 0x36, "pc01_vfetch_10", nv50_vfetch_sources },
+			{ 0x37, "pc01_vfetch_11", nv50_vfetch_sources },
+			{ 0x38, "pc01_vfetch_12", nv50_vfetch_sources },
+			{ 0x39, "pc01_vfetch_13", nv50_vfetch_sources },
+			{ 0x3a, "pc01_vfetch_14", nv50_vfetch_sources },
+			{ 0x3b, "pc01_vfetch_15", nv50_vfetch_sources },
+			{ 0x3c, "pc01_vfetch_16", nv50_vfetch_sources },
+			{ 0x3d, "pc01_vfetch_17", nv50_vfetch_sources },
+			{ 0x3e, "pc01_vfetch_18", nv50_vfetch_sources },
+			{ 0x3f, "pc01_vfetch_19", nv50_vfetch_sources },
+			{ 0x20, "pc01_zcull_00", nv50_zcull_sources },
+			{ 0x21, "pc01_zcull_01", nv50_zcull_sources },
+			{ 0x22, "pc01_zcull_02", nv50_zcull_sources },
+			{ 0x23, "pc01_zcull_03", nv50_zcull_sources },
+			{ 0x24, "pc01_zcull_04", nv50_zcull_sources },
+			{ 0x25, "pc01_zcull_05", nv50_zcull_sources },
+			{ 0xae, "pc01_unk00" },
+			{ 0xee, "pc01_trailer" },
 			{}
 		}, &nv40_perfctr_func },
-	{ 0x100, (const struct nvkm_specsig[]) {
+	{ 0xf0, (const struct nvkm_specsig[]) {
+			{ 0x52, "pc02_crop_00", nv50_crop_sources },
+			{ 0x53, "pc02_crop_01", nv50_crop_sources },
+			{ 0x54, "pc02_crop_02", nv50_crop_sources },
+			{ 0x55, "pc02_crop_03", nv50_crop_sources },
+			{ 0x00, "pc02_prop_00", nv50_prop_sources },
+			{ 0x01, "pc02_prop_01", nv50_prop_sources },
+			{ 0x02, "pc02_prop_02", nv50_prop_sources },
+			{ 0x03, "pc02_prop_03", nv50_prop_sources },
+			{ 0x04, "pc02_prop_04", nv50_prop_sources },
+			{ 0x05, "pc02_prop_05", nv50_prop_sources },
+			{ 0x06, "pc02_prop_06", nv50_prop_sources },
+			{ 0x07, "pc02_prop_07", nv50_prop_sources },
+			{ 0x70, "pc02_tex_00", nv50_tex_sources },
+			{ 0x71, "pc02_tex_01", nv50_tex_sources },
+			{ 0x72, "pc02_tex_02", nv50_tex_sources },
+			{ 0x73, "pc02_tex_03", nv50_tex_sources },
+			{ 0x40, "pc02_tex_04", nv50_tex_sources },
+			{ 0x41, "pc02_tex_05", nv50_tex_sources },
+			{ 0x42, "pc02_tex_06", nv50_tex_sources },
+			{ 0x6c, "pc02_zrop_00", nv50_zrop_sources },
+			{ 0x6d, "pc02_zrop_01", nv50_zrop_sources },
+			{ 0x6e, "pc02_zrop_02", nv50_zrop_sources },
+			{ 0x6f, "pc02_zrop_03", nv50_zrop_sources },
+			{ 0xee, "pc02_trailer" },
 			{}
 		}, &nv40_perfctr_func },
-	{ 0x020, (const struct nvkm_specsig[]) {
+	{ 0x20, (const struct nvkm_specsig[]) {
 			{}
 		}, &nv40_perfctr_func },
-	{ 0x040, (const struct nvkm_specsig[]) {
+	{ 0x20, (const struct nvkm_specsig[]) {
 			{}
 		}, &nv40_perfctr_func },
 	{}
diff --git a/drm/nouveau/nvkm/engine/pm/priv.h b/drm/nouveau/nvkm/engine/pm/priv.h
index da419c1..5bcc739 100644
--- a/drm/nouveau/nvkm/engine/pm/priv.h
+++ b/drm/nouveau/nvkm/engine/pm/priv.h
@@ -44,6 +44,14 @@ struct nvkm_perfsrc {
 	bool enable;
 };
 
+extern const struct nvkm_specsrc nv50_prop_sources[];
+extern const struct nvkm_specsrc nv50_zcull_sources[];
+extern const struct nvkm_specsrc nv50_zrop_sources[];
+extern const struct nvkm_specsrc g84_vfetch_sources[];
+extern const struct nvkm_specsrc gt200_crop_sources[];
+extern const struct nvkm_specsrc gt200_prop_sources[];
+extern const struct nvkm_specsrc gt200_tex_sources[];
+
 struct nvkm_specsig {
 	u8 signal;
 	const char *name;
-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH RFC 19/20] sw/nv50: add some private functions to factorize code
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (17 preceding siblings ...)
  2015-06-07 20:40   ` [PATCH RFC 18/20] pm/nv50: add compute and graphics signals/sources Samuel Pitoiset
@ 2015-06-07 20:40   ` Samuel Pitoiset
  2015-06-07 20:40   ` [PATCH RFC 20/20] sw/nv50: add and interface for controlling performance counters Samuel Pitoiset
  19 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

These functions will be also used by the interface for controlling
performance counters.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
---
 drm/nouveau/nvkm/engine/sw/nv50.c | 56 ++++++++++++++++++++++++++-------------
 1 file changed, 38 insertions(+), 18 deletions(-)

diff --git a/drm/nouveau/nvkm/engine/sw/nv50.c b/drm/nouveau/nvkm/engine/sw/nv50.c
index 401fcd7..b7c0227 100644
--- a/drm/nouveau/nvkm/engine/sw/nv50.c
+++ b/drm/nouveau/nvkm/engine/sw/nv50.c
@@ -36,27 +36,58 @@
  ******************************************************************************/
 
 static int
-nv50_sw_mthd_dma_vblsem(struct nvkm_object *object, u32 mthd,
-			void *args, u32 size)
+nv50_priv_ctxdma_get(struct nv50_sw_chan *chan, u32 name, u32 *ctxdma)
 {
-	struct nv50_sw_chan *chan = (void *)nv_engctx(object->parent);
 	struct nvkm_fifo_chan *fifo = (void *)nv_object(chan)->parent;
 	struct nvkm_handle *handle;
 	int ret = -EINVAL;
 
-	handle = nvkm_namedb_get(nv_namedb(fifo), *(u32 *)args);
+	handle = nvkm_namedb_get(nv_namedb(fifo), name);
 	if (!handle)
 		return -ENOENT;
 
 	if (nv_iclass(handle->object, NV_GPUOBJ_CLASS)) {
 		struct nvkm_gpuobj *gpuobj = nv_gpuobj(handle->object);
-		chan->vblank.ctxdma = gpuobj->node->offset >> 4;
+		*ctxdma = gpuobj->node->offset >> 4;
 		ret = 0;
 	}
 	nvkm_namedb_put(handle);
 	return ret;
 }
 
+static void
+nv50_priv_ctxdma_flush(struct nv50_sw_chan *chan, u32 channel, u32 ctxdma)
+{
+	struct nv50_sw_priv *priv = (void *)nv_object(chan)->engine;
+	struct nvkm_bar *bar = nvkm_bar(priv);
+
+	nv_wr32(priv, 0x001704, channel);
+	nv_wr32(priv, 0x001710, 0x80000000 | ctxdma);
+	bar->flush(bar);
+}
+
+static void
+nv50_priv_ctxdma_wr32(struct nv50_sw_chan *chan, u64 offset, u32 value)
+{
+	struct nv50_sw_priv *priv = (void *)nv_object(chan)->engine;
+
+	if (nv_device(priv)->chipset == 0x50) {
+		nv_wr32(priv, 0x001570, offset);
+		nv_wr32(priv, 0x001574, value);
+	} else {
+		nv_wr32(priv, 0x060010, offset);
+		nv_wr32(priv, 0x060014, value);
+	}
+}
+
+static int
+nv50_sw_mthd_dma_vblsem(struct nvkm_object *object, u32 mthd,
+			void *args, u32 size)
+{
+	struct nv50_sw_chan *chan = (void *)nv_engctx(object->parent);
+	return nv50_priv_ctxdma_get(chan, *(u32 *)args, &chan->vblank.ctxdma);
+}
+
 static int
 nv50_sw_mthd_vblsem_offset(struct nvkm_object *object, u32 mthd,
 			   void *args, u32 size)
@@ -122,20 +153,9 @@ nv50_sw_vblsem_release(struct nvkm_notify *notify)
 {
 	struct nv50_sw_chan *chan =
 		container_of(notify, typeof(*chan), vblank.notify[notify->index]);
-	struct nv50_sw_priv *priv = (void *)nv_object(chan)->engine;
-	struct nvkm_bar *bar = nvkm_bar(priv);
-
-	nv_wr32(priv, 0x001704, chan->vblank.channel);
-	nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
-	bar->flush(bar);
 
-	if (nv_device(priv)->chipset == 0x50) {
-		nv_wr32(priv, 0x001570, chan->vblank.offset);
-		nv_wr32(priv, 0x001574, chan->vblank.value);
-	} else {
-		nv_wr32(priv, 0x060010, chan->vblank.offset);
-		nv_wr32(priv, 0x060014, chan->vblank.value);
-	}
+	nv50_priv_ctxdma_flush(chan, chan->vblank.channel, chan->vblank.ctxdma);
+	nv50_priv_ctxdma_wr32(chan, chan->vblank.offset, chan->vblank.value);
 
 	return NVKM_NOTIFY_DROP;
 }
-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH RFC 20/20] sw/nv50: add and interface for controlling performance counters
       [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (18 preceding siblings ...)
  2015-06-07 20:40   ` [PATCH RFC 19/20] sw/nv50: add some private functions to factorize code Samuel Pitoiset
@ 2015-06-07 20:40   ` Samuel Pitoiset
  19 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-07 20:40 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

This software methods interface will allow the userspace to tie
monitoring of performance counters to the command stream.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
---
 drm/nouveau/nvkm/engine/sw/nv50.c | 160 ++++++++++++++++++++++++++++++++++++++
 drm/nouveau/nvkm/engine/sw/nv50.h |   6 ++
 2 files changed, 166 insertions(+)

diff --git a/drm/nouveau/nvkm/engine/sw/nv50.c b/drm/nouveau/nvkm/engine/sw/nv50.c
index b7c0227..b5f8263 100644
--- a/drm/nouveau/nvkm/engine/sw/nv50.c
+++ b/drm/nouveau/nvkm/engine/sw/nv50.c
@@ -29,7 +29,9 @@
 #include <engine/disp.h>
 #include <subdev/bar.h>
 
+#include <nvif/class.h>
 #include <nvif/event.h>
+#include <nvif/ioctl.h>
 
 /*******************************************************************************
  * software object classes
@@ -80,6 +82,14 @@ nv50_priv_ctxdma_wr32(struct nv50_sw_chan *chan, u64 offset, u32 value)
 	}
 }
 
+static u64
+nv50_priv_pm_get_offset(struct nv50_sw_chan *chan, u32 sequence)
+{
+	u32 max_queries = chan->pm.max_queries;
+	u32 ring_size = chan->pm.ring_size;
+	return (1 + (sequence % ring_size) * max_queries * 3) * 4;
+}
+
 static int
 nv50_sw_mthd_dma_vblsem(struct nvkm_object *object, u32 mthd,
 			void *args, u32 size)
@@ -128,13 +138,163 @@ nv50_sw_mthd_flip(struct nvkm_object *object, u32 mthd, void *args, u32 size)
 	return -EINVAL;
 }
 
+static int
+nv50_sw_mthd_dma_pm(struct nvkm_object *object, u32 mthd,
+		    void *args, u32 size)
+{
+	struct nv50_sw_chan *chan = (void *)nv_engctx(object->parent);
+	return nv50_priv_ctxdma_get(chan, *(u32 *)args, &chan->pm.ctxdma);
+}
+
+static int
+nv50_sw_mthd_pm_ring_size(struct nvkm_object *object, u32 mthd,
+			  void *args, u32 size)
+{
+	struct nv50_sw_chan *chan = (void *)nv_engctx(object->parent);
+	chan->pm.ring_size = *(u32 *)args;
+	return 0;
+}
+
+static int
+nv50_sw_mthd_pm_max_queries(struct nvkm_object *object, u32 mthd,
+			    void *args, u32 size)
+{
+	struct nv50_sw_chan *chan = (void *)nv_engctx(object->parent);
+	chan->pm.max_queries = *(u32 *)args;
+	return 0;
+}
+
+static int
+nv50_sw_mthd_pm_mthd_init(struct nvkm_object *object, u32 mthd,
+			  void *args, u32 size)
+{
+	struct nv50_sw_chan *chan = (void *)nv_engctx(object->parent);
+	struct nvkm_fifo_chan *fifo = (void *)nv_object(chan)->parent;
+	struct nvkm_handle *handle;
+	struct nvkm_object *namedb;
+	int ret = -EINVAL;
+
+	namedb = nv_object(fifo)->parent;
+	while (!nv_iclass(namedb, NV_NAMEDB_CLASS))
+		namedb = namedb->parent;
+
+	handle = nvkm_namedb_get(nv_namedb(namedb), *(u32 *)args);
+	if (!handle)
+		return -ENOENT;
+
+	if (nv_iclass(handle->object, NVIF_IOCTL_NEW_V0_PERFMON)) {
+		struct nvkm_object *object = handle->object;
+		struct nvkm_ofuncs *ofuncs = object->oclass->ofuncs;
+		struct nvif_perfdom_init args = {};
+
+		ret = ofuncs->mthd(object, NVIF_PERFDOM_V0_INIT,
+				   &args, sizeof(args));
+	}
+	nvkm_namedb_put(handle);
+	return ret;
+}
+
+static int
+nv50_sw_mthd_pm_mthd_sample(struct nvkm_object *object, u32 mthd,
+			    void *args, u32 size)
+{
+	struct nv50_sw_chan *chan = (void *)nv_engctx(object->parent);
+	struct nvkm_fifo_chan *fifo = (void *)nv_object(chan)->parent;
+	struct nvkm_handle *handle;
+	struct nvkm_object *namedb;
+	int ret = -EINVAL;
+
+	namedb = nv_object(fifo)->parent;
+	while (!nv_iclass(namedb, NV_NAMEDB_CLASS))
+		namedb = namedb->parent;
+
+	handle = nvkm_namedb_get(nv_namedb(namedb), *(u32 *)args);
+	if (!handle)
+		return -ENOENT;
+
+	if (nv_iclass(handle->object, NVIF_IOCTL_NEW_V0_PERFMON)) {
+		struct nvkm_object *object = handle->object;
+		struct nvkm_ofuncs *ofuncs = object->oclass->ofuncs;
+		struct nvif_perfdom_sample args = {};
+
+		ret = ofuncs->mthd(object, NVIF_PERFDOM_V0_SAMPLE,
+				   &args, sizeof(args));
+	}
+	nvkm_namedb_put(handle);
+	return ret;
+}
+
+static int
+nv50_sw_mthd_pm_mthd_read(struct nvkm_object *object, u32 mthd,
+			  void *args, u32 size)
+{
+	struct nv50_sw_chan *chan = (void *)nv_engctx(object->parent);
+	struct nvkm_fifo_chan *fifo = (void *)nv_object(chan)->parent;
+	struct nvkm_handle *handle;
+	struct nvkm_object *namedb;
+	u32 seq = *(u32 *)args;
+	int ret = -ENOENT;
+	u64 offset;
+	int i;
+
+	nv50_priv_ctxdma_flush(chan, chan->vblank.channel, chan->pm.ctxdma);
+	offset = nv50_priv_pm_get_offset(chan, seq);
+
+	namedb = nv_object(fifo)->parent;
+	while (!nv_iclass(namedb, NV_NAMEDB_CLASS))
+		namedb = namedb->parent;
+
+	/* XXX: Any ideas to improve this ? */
+	read_lock(&nv_namedb(namedb)->lock);
+	list_for_each_entry(handle, &nv_namedb(namedb)->list, node) {
+		struct nvif_perfdom_read_v0 args = {};
+		struct nvkm_object *object;
+		struct nvkm_ofuncs *ofuncs;
+
+		if (handle == NULL)
+			break;
+
+		if (nv_iclass(handle->object, NVIF_IOCTL_NEW_V0_PERFMON)
+		    != NVIF_IOCTL_NEW_V0_PERFMON)
+			continue;
+
+		object = handle->object;
+		ofuncs = object->oclass->ofuncs;
+		ret = ofuncs->mthd(object, NVIF_PERFDOM_V0_READ,
+				   &args, sizeof(args));
+		if (ret && ret != -EAGAIN) {
+			nv_error(object, "failed to read perfdom object: %x\n",
+				 handle->name);
+			break;
+		}
+
+		nv50_priv_ctxdma_wr32(chan, offset, handle->name);
+		for (i = 0; i < 4; i++) {
+			nv50_priv_ctxdma_wr32(chan, offset + 4 * (i + 1),
+					      args.ctr[i]);
+		}
+		nv50_priv_ctxdma_wr32(chan, offset + 20, args.clk);
+		offset += 24;
+	}
+	read_unlock(&nv_namedb(namedb)->lock);
+
+	nv50_priv_ctxdma_wr32(chan, 0x0, seq);
+	return ret;
+}
+
 static struct nvkm_omthds
 nv50_sw_omthds[] = {
 	{ 0x018c, 0x018c, nv50_sw_mthd_dma_vblsem },
+	{ 0x0190, 0x0190, nv50_sw_mthd_dma_pm },
 	{ 0x0400, 0x0400, nv50_sw_mthd_vblsem_offset },
 	{ 0x0404, 0x0404, nv50_sw_mthd_vblsem_value },
 	{ 0x0408, 0x0408, nv50_sw_mthd_vblsem_release },
 	{ 0x0500, 0x0500, nv50_sw_mthd_flip },
+	{ 0x0600, 0x0600, nv50_sw_mthd_pm_ring_size },
+	{ 0x0604, 0x0604, nv50_sw_mthd_pm_max_queries },
+	{ 0x0608, 0x0608, nv50_sw_mthd_pm_mthd_init },
+	{ 0x060c, 0x060c, nv50_sw_mthd_pm_mthd_sample },
+	{ 0x0700, 0x0700, nv50_sw_mthd_pm_mthd_read },
 	{}
 };
 
diff --git a/drm/nouveau/nvkm/engine/sw/nv50.h b/drm/nouveau/nvkm/engine/sw/nv50.h
index d8adc11..48860d3 100644
--- a/drm/nouveau/nvkm/engine/sw/nv50.h
+++ b/drm/nouveau/nvkm/engine/sw/nv50.h
@@ -31,6 +31,12 @@ struct nv50_sw_chan {
 		u64 offset;
 		u32 value;
 	} vblank;
+
+	struct {
+		u32 ctxdma;
+		u32 ring_size;
+		u32 max_queries;
+	} pm;
 };
 
 int  nv50_sw_context_ctor(struct nvkm_object *,
-- 
2.4.2

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH RFC 05/20] pm: reorganize the nvif interface
       [not found]     ` <1433709630-3293-6-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2015-06-08 22:02       ` Ben Skeggs
       [not found]         ` <CACAvsv4x2vcWND6bE1tGSDQMy_doysboV7O8551CfGKz4MwcMA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 25+ messages in thread
From: Ben Skeggs @ 2015-06-08 22:02 UTC (permalink / raw)
  To: Samuel Pitoiset; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On 8 June 2015 at 06:40, Samuel Pitoiset <samuel.pitoiset@gmail.com> wrote:
> This commit introduces the NVIF_IOCTL_NEW_V0_PERFMON class which will be
> used in order to query domains, signals and sources. This separates the
> querying and the counting interface.
Hey Samuel,

I've merged patches 1-4 already, I've got some comments on this one,
but after they're solved I'm happy to merge up to (and including)
patch 18.  Patches 19/20, I need to think about some more.

>
> Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
> ---
>  bin/nv_perfmon.c                  | 12 ++++++------
>  drm/nouveau/include/nvif/class.h  | 26 ++++++++++++++++----------
>  drm/nouveau/include/nvif/ioctl.h  |  5 +++--
>  drm/nouveau/nvkm/engine/pm/base.c | 38 ++++++++++++++++++++++++++++++++------
>  4 files changed, 57 insertions(+), 24 deletions(-)
>
> diff --git a/bin/nv_perfmon.c b/bin/nv_perfmon.c
> index a8c5838..30a3138 100644
> --- a/bin/nv_perfmon.c
> +++ b/bin/nv_perfmon.c
> @@ -600,7 +600,7 @@ main(int argc, char **argv)
>         const char *cfg = NULL;
>         const char *dbg = "error";
>         u64 dev = ~0ULL;
> -       struct nvif_perfctr_query_v0 args = {};
> +       struct nvif_perfmon_query_signal_v0 args = {};
>         struct nvif_client *client;
>         struct nvif_object object;
>         int ret, c, k;
> @@ -644,15 +644,14 @@ main(int argc, char **argv)
>         }
>
>         ret = nvif_object_init(nvif_object(device), NULL, 0xdeadbeef,
> -                              NVIF_IOCTL_NEW_V0_PERFCTR,
> -                              &(struct nvif_perfctr_v0) {
> -                              }, sizeof(struct nvif_perfctr_v0), &object);
> +                              NVIF_IOCTL_NEW_V0_PERFMON, NULL, 0, &object);
>         assert(ret == 0);
>         do {
>                 u32 prev_iter = args.iter;
>
>                 args.name[0] = '\0';
> -               ret = nvif_mthd(&object, NVIF_PERFCTR_V0_QUERY, &args, sizeof(args));
> +               ret = nvif_mthd(&object, NVIF_PERFMON_V0_QUERY_SIGNAL,
> +                               &args, sizeof(args));
>                 assert(ret == 0);
>
>                 if (prev_iter) {
> @@ -663,7 +662,8 @@ main(int argc, char **argv)
>                         args.iter = prev_iter;
>                         strncpy(signals[nr_signals - 1], args.name,
>                                 sizeof(args.name));
> -                       ret = nvif_mthd(&object, NVIF_PERFCTR_V0_QUERY, &args, sizeof(args));
> +                       ret = nvif_mthd(&object, NVIF_PERFMON_V0_QUERY_SIGNAL,
> +                                       &args, sizeof(args));
>                         assert(ret == 0);
>                 }
>         } while (args.iter != 0xffffffff);
> diff --git a/drm/nouveau/include/nvif/class.h b/drm/nouveau/include/nvif/class.h
> index 64f8b2f..11935a0 100644
> --- a/drm/nouveau/include/nvif/class.h
> +++ b/drm/nouveau/include/nvif/class.h
> @@ -251,6 +251,20 @@ struct gf110_dma_v0 {
>   * perfmon
>   ******************************************************************************/
>
> +#define NVIF_PERFMON_V0_QUERY_SIGNAL                                       0x00
> +
> +struct nvif_perfmon_query_signal_v0 {
> +       __u8  version;
> +       __u8  pad01[3];
> +       __u32 iter;
> +       char  name[64];
> +};
> +
> +
> +/*******************************************************************************
> + * perfctr
> + ******************************************************************************/
> +
>  struct nvif_perfctr_v0 {
>         __u8  version;
>         __u8  pad01[1];
> @@ -259,16 +273,8 @@ struct nvif_perfctr_v0 {
>         char  name[4][64];
>  };
>
> -#define NVIF_PERFCTR_V0_QUERY                                              0x00
> -#define NVIF_PERFCTR_V0_SAMPLE                                             0x01
> -#define NVIF_PERFCTR_V0_READ                                               0x02
> -
> -struct nvif_perfctr_query_v0 {
> -       __u8  version;
> -       __u8  pad01[3];
> -       __u32 iter;
> -       char  name[64];
> -};
> +#define NVIF_PERFCTR_V0_SAMPLE                                             0x00
> +#define NVIF_PERFCTR_V0_READ                                               0x01
>
>  struct nvif_perfctr_sample {
>  };
> diff --git a/drm/nouveau/include/nvif/ioctl.h b/drm/nouveau/include/nvif/ioctl.h
> index 4cd8e32..517cd27 100644
> --- a/drm/nouveau/include/nvif/ioctl.h
> +++ b/drm/nouveau/include/nvif/ioctl.h
> @@ -49,8 +49,9 @@ struct nvif_ioctl_new_v0 {
>         __u64 token;
>         __u32 handle;
>  /* these class numbers are made up by us, and not nvidia-assigned */
> -#define NVIF_IOCTL_NEW_V0_PERFCTR                                    0x0000ffff
> -#define NVIF_IOCTL_NEW_V0_CONTROL                                    0x0000fffe
> +#define NVIF_IOCTL_NEW_V0_PERFMON                                    0x0000ffff
> +#define NVIF_IOCTL_NEW_V0_PERFCTR                                    0x0000fffe
> +#define NVIF_IOCTL_NEW_V0_CONTROL                                    0x0000fffd
It doesn't matter this time, because we're technically breaking ABI
already anyway and current userspace won't be effected, but best to
avoid changing class numbers like this :)  It's fine this time though.

>         __u32 oclass;
>         __u8  data[];           /* class data (class.h) */
>  };
> diff --git a/drm/nouveau/nvkm/engine/pm/base.c b/drm/nouveau/nvkm/engine/pm/base.c
> index 7b07e8b..cb88170 100644
> --- a/drm/nouveau/nvkm/engine/pm/base.c
> +++ b/drm/nouveau/nvkm/engine/pm/base.c
> @@ -83,10 +83,10 @@ nvkm_perfsig_find(struct nvkm_pm *ppm, const char *name, u32 size,
>   * Perfmon object classes
>   ******************************************************************************/
>  static int
> -nvkm_perfctr_query(struct nvkm_object *object, void *data, u32 size)
> +nvkm_perfmon_mthd_query_signal(struct nvkm_object *object, void *data, u32 size)
>  {
>         union {
> -               struct nvif_perfctr_query_v0 v0;
> +               struct nvif_perfmon_query_signal_v0 v0;
>         } *args = data;
>         struct nvkm_device *device = nv_device(object);
>         struct nvkm_pm *ppm = (void *)object->engine;
> @@ -97,9 +97,9 @@ nvkm_perfctr_query(struct nvkm_object *object, void *data, u32 size)
>         int tmp = 0, di, si;
>         int ret;
>
> -       nv_ioctl(object, "perfctr query size %d\n", size);
> +       nv_ioctl(object, "perfmon query signal size %d\n", size);
>         if (nvif_unpack(args->v0, 0, 0, false)) {
> -               nv_ioctl(object, "perfctr query vers %d iter %08x\n",
> +               nv_ioctl(object, "perfmon query signal vers %d iter %08x\n",
>                          args->v0.version, args->v0.iter);
>                 di = (args->v0.iter & 0xff000000) >> 24;
>                 si = (args->v0.iter & 0x00ffffff) - 1;
> @@ -142,6 +142,30 @@ nvkm_perfctr_query(struct nvkm_object *object, void *data, u32 size)
>  }
>
>  static int
> +nvkm_perfmon_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
> +{
> +       switch (mthd) {
> +       case NVIF_PERFMON_V0_QUERY_SIGNAL:
> +               return nvkm_perfmon_mthd_query_signal(object, data, size);
> +       default:
> +               break;
> +       }
> +       return -EINVAL;
> +}
> +
> +static struct nvkm_ofuncs
> +nvkm_perfmon_ofuncs = {
> +       .ctor = _nvkm_object_ctor,
> +       .dtor = nvkm_object_destroy,
> +       .init = nvkm_object_init,
> +       .fini = nvkm_object_fini,
> +       .mthd = nvkm_perfmon_mthd,
> +};
> +
> +/*******************************************************************************
> + * Perfctr object classes
> + ******************************************************************************/
> +static int
>  nvkm_perfctr_sample(struct nvkm_object *object, void *data, u32 size)
>  {
>         union {
> @@ -221,8 +245,6 @@ static int
>  nvkm_perfctr_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
>  {
>         switch (mthd) {
> -       case NVIF_PERFCTR_V0_QUERY:
> -               return nvkm_perfctr_query(object, data, size);
>         case NVIF_PERFCTR_V0_SAMPLE:
>                 return nvkm_perfctr_sample(object, data, size);
>         case NVIF_PERFCTR_V0_READ:
> @@ -299,6 +321,10 @@ nvkm_perfctr_ofuncs = {
>
>  struct nvkm_oclass
>  nvkm_pm_sclass[] = {
> +       {
> +         .handle = NVIF_IOCTL_NEW_V0_PERFMON,
> +         .ofuncs = &nvkm_perfmon_ofuncs,
> +       },
>         { .handle = NVIF_IOCTL_NEW_V0_PERFCTR,
>           .ofuncs = &nvkm_perfctr_ofuncs,
>         },
What I'd like to see here is that nvkm_pm_sclass() only has PERFMON,
and PERFCTR is created as a child of it (like how all the PDISP
channel objects are children of the main disp class).  To do this, you
need to create PERFMON as a nvkm_parent instead of an nvkm_object, and
have its parent.sclass contain PERFMON.  This will perhaps look a bit
yucky for the moment, but I'm working on making things cleaner so I'll
fix it later.  Feel free to ping me on IRC if you need a hand making
the change though.

I actually have a large patch series with the first part of this
cleanup work queued up, but if you can make the above change first,
I'll rebase my work on yours so you don't have to deal with that.

Thanks,
Ben.

> --
> 2.4.2
>
> _______________________________________________
> Nouveau mailing list
> Nouveau@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/nouveau
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH RFC 05/20] pm: reorganize the nvif interface
       [not found]         ` <CACAvsv4x2vcWND6bE1tGSDQMy_doysboV7O8551CfGKz4MwcMA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2015-06-09 21:53           ` Samuel Pitoiset
       [not found]             ` <55776056.9010302-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-09 21:53 UTC (permalink / raw)
  To: Ben Skeggs; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW



On 06/09/2015 12:02 AM, Ben Skeggs wrote:
> On 8 June 2015 at 06:40, Samuel Pitoiset <samuel.pitoiset@gmail.com> wrote:
>> This commit introduces the NVIF_IOCTL_NEW_V0_PERFMON class which will be
>> used in order to query domains, signals and sources. This separates the
>> querying and the counting interface.
> Hey Samuel,
>
> I've merged patches 1-4 already, I've got some comments on this one,
> but after they're solved I'm happy to merge up to (and including)
> patch 18.  Patches 19/20, I need to think about some more.
>

Hey Ben,

Thanks for reviewing this series so quickly. :-)

>> Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
>> ---
>>   bin/nv_perfmon.c                  | 12 ++++++------
>>   drm/nouveau/include/nvif/class.h  | 26 ++++++++++++++++----------
>>   drm/nouveau/include/nvif/ioctl.h  |  5 +++--
>>   drm/nouveau/nvkm/engine/pm/base.c | 38 ++++++++++++++++++++++++++++++++------
>>   4 files changed, 57 insertions(+), 24 deletions(-)
>>
>> diff --git a/bin/nv_perfmon.c b/bin/nv_perfmon.c
>> index a8c5838..30a3138 100644
>> --- a/bin/nv_perfmon.c
>> +++ b/bin/nv_perfmon.c
>> @@ -600,7 +600,7 @@ main(int argc, char **argv)
>>          const char *cfg = NULL;
>>          const char *dbg = "error";
>>          u64 dev = ~0ULL;
>> -       struct nvif_perfctr_query_v0 args = {};
>> +       struct nvif_perfmon_query_signal_v0 args = {};
>>          struct nvif_client *client;
>>          struct nvif_object object;
>>          int ret, c, k;
>> @@ -644,15 +644,14 @@ main(int argc, char **argv)
>>          }
>>
>>          ret = nvif_object_init(nvif_object(device), NULL, 0xdeadbeef,
>> -                              NVIF_IOCTL_NEW_V0_PERFCTR,
>> -                              &(struct nvif_perfctr_v0) {
>> -                              }, sizeof(struct nvif_perfctr_v0), &object);
>> +                              NVIF_IOCTL_NEW_V0_PERFMON, NULL, 0, &object);
>>          assert(ret == 0);
>>          do {
>>                  u32 prev_iter = args.iter;
>>
>>                  args.name[0] = '\0';
>> -               ret = nvif_mthd(&object, NVIF_PERFCTR_V0_QUERY, &args, sizeof(args));
>> +               ret = nvif_mthd(&object, NVIF_PERFMON_V0_QUERY_SIGNAL,
>> +                               &args, sizeof(args));
>>                  assert(ret == 0);
>>
>>                  if (prev_iter) {
>> @@ -663,7 +662,8 @@ main(int argc, char **argv)
>>                          args.iter = prev_iter;
>>                          strncpy(signals[nr_signals - 1], args.name,
>>                                  sizeof(args.name));
>> -                       ret = nvif_mthd(&object, NVIF_PERFCTR_V0_QUERY, &args, sizeof(args));
>> +                       ret = nvif_mthd(&object, NVIF_PERFMON_V0_QUERY_SIGNAL,
>> +                                       &args, sizeof(args));
>>                          assert(ret == 0);
>>                  }
>>          } while (args.iter != 0xffffffff);
>> diff --git a/drm/nouveau/include/nvif/class.h b/drm/nouveau/include/nvif/class.h
>> index 64f8b2f..11935a0 100644
>> --- a/drm/nouveau/include/nvif/class.h
>> +++ b/drm/nouveau/include/nvif/class.h
>> @@ -251,6 +251,20 @@ struct gf110_dma_v0 {
>>    * perfmon
>>    ******************************************************************************/
>>
>> +#define NVIF_PERFMON_V0_QUERY_SIGNAL                                       0x00
>> +
>> +struct nvif_perfmon_query_signal_v0 {
>> +       __u8  version;
>> +       __u8  pad01[3];
>> +       __u32 iter;
>> +       char  name[64];
>> +};
>> +
>> +
>> +/*******************************************************************************
>> + * perfctr
>> + ******************************************************************************/
>> +
>>   struct nvif_perfctr_v0 {
>>          __u8  version;
>>          __u8  pad01[1];
>> @@ -259,16 +273,8 @@ struct nvif_perfctr_v0 {
>>          char  name[4][64];
>>   };
>>
>> -#define NVIF_PERFCTR_V0_QUERY                                              0x00
>> -#define NVIF_PERFCTR_V0_SAMPLE                                             0x01
>> -#define NVIF_PERFCTR_V0_READ                                               0x02
>> -
>> -struct nvif_perfctr_query_v0 {
>> -       __u8  version;
>> -       __u8  pad01[3];
>> -       __u32 iter;
>> -       char  name[64];
>> -};
>> +#define NVIF_PERFCTR_V0_SAMPLE                                             0x00
>> +#define NVIF_PERFCTR_V0_READ                                               0x01
>>
>>   struct nvif_perfctr_sample {
>>   };
>> diff --git a/drm/nouveau/include/nvif/ioctl.h b/drm/nouveau/include/nvif/ioctl.h
>> index 4cd8e32..517cd27 100644
>> --- a/drm/nouveau/include/nvif/ioctl.h
>> +++ b/drm/nouveau/include/nvif/ioctl.h
>> @@ -49,8 +49,9 @@ struct nvif_ioctl_new_v0 {
>>          __u64 token;
>>          __u32 handle;
>>   /* these class numbers are made up by us, and not nvidia-assigned */
>> -#define NVIF_IOCTL_NEW_V0_PERFCTR                                    0x0000ffff
>> -#define NVIF_IOCTL_NEW_V0_CONTROL                                    0x0000fffe
>> +#define NVIF_IOCTL_NEW_V0_PERFMON                                    0x0000ffff
>> +#define NVIF_IOCTL_NEW_V0_PERFCTR                                    0x0000fffe
>> +#define NVIF_IOCTL_NEW_V0_CONTROL                                    0x0000fffd
> It doesn't matter this time, because we're technically breaking ABI
> already anyway and current userspace won't be effected, but best to
> avoid changing class numbers like this :)  It's fine this time though.

Sure, since the nvif interface is still not exposed through libdrm, this 
is not going to affect userspace.
Btw, what is your plan about this? Are you going to merge nvif support 
to libdrm ?

>
>>          __u32 oclass;
>>          __u8  data[];           /* class data (class.h) */
>>   };
>> diff --git a/drm/nouveau/nvkm/engine/pm/base.c b/drm/nouveau/nvkm/engine/pm/base.c
>> index 7b07e8b..cb88170 100644
>> --- a/drm/nouveau/nvkm/engine/pm/base.c
>> +++ b/drm/nouveau/nvkm/engine/pm/base.c
>> @@ -83,10 +83,10 @@ nvkm_perfsig_find(struct nvkm_pm *ppm, const char *name, u32 size,
>>    * Perfmon object classes
>>    ******************************************************************************/
>>   static int
>> -nvkm_perfctr_query(struct nvkm_object *object, void *data, u32 size)
>> +nvkm_perfmon_mthd_query_signal(struct nvkm_object *object, void *data, u32 size)
>>   {
>>          union {
>> -               struct nvif_perfctr_query_v0 v0;
>> +               struct nvif_perfmon_query_signal_v0 v0;
>>          } *args = data;
>>          struct nvkm_device *device = nv_device(object);
>>          struct nvkm_pm *ppm = (void *)object->engine;
>> @@ -97,9 +97,9 @@ nvkm_perfctr_query(struct nvkm_object *object, void *data, u32 size)
>>          int tmp = 0, di, si;
>>          int ret;
>>
>> -       nv_ioctl(object, "perfctr query size %d\n", size);
>> +       nv_ioctl(object, "perfmon query signal size %d\n", size);
>>          if (nvif_unpack(args->v0, 0, 0, false)) {
>> -               nv_ioctl(object, "perfctr query vers %d iter %08x\n",
>> +               nv_ioctl(object, "perfmon query signal vers %d iter %08x\n",
>>                           args->v0.version, args->v0.iter);
>>                  di = (args->v0.iter & 0xff000000) >> 24;
>>                  si = (args->v0.iter & 0x00ffffff) - 1;
>> @@ -142,6 +142,30 @@ nvkm_perfctr_query(struct nvkm_object *object, void *data, u32 size)
>>   }
>>
>>   static int
>> +nvkm_perfmon_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
>> +{
>> +       switch (mthd) {
>> +       case NVIF_PERFMON_V0_QUERY_SIGNAL:
>> +               return nvkm_perfmon_mthd_query_signal(object, data, size);
>> +       default:
>> +               break;
>> +       }
>> +       return -EINVAL;
>> +}
>> +
>> +static struct nvkm_ofuncs
>> +nvkm_perfmon_ofuncs = {
>> +       .ctor = _nvkm_object_ctor,
>> +       .dtor = nvkm_object_destroy,
>> +       .init = nvkm_object_init,
>> +       .fini = nvkm_object_fini,
>> +       .mthd = nvkm_perfmon_mthd,
>> +};
>> +
>> +/*******************************************************************************
>> + * Perfctr object classes
>> + ******************************************************************************/
>> +static int
>>   nvkm_perfctr_sample(struct nvkm_object *object, void *data, u32 size)
>>   {
>>          union {
>> @@ -221,8 +245,6 @@ static int
>>   nvkm_perfctr_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
>>   {
>>          switch (mthd) {
>> -       case NVIF_PERFCTR_V0_QUERY:
>> -               return nvkm_perfctr_query(object, data, size);
>>          case NVIF_PERFCTR_V0_SAMPLE:
>>                  return nvkm_perfctr_sample(object, data, size);
>>          case NVIF_PERFCTR_V0_READ:
>> @@ -299,6 +321,10 @@ nvkm_perfctr_ofuncs = {
>>
>>   struct nvkm_oclass
>>   nvkm_pm_sclass[] = {
>> +       {
>> +         .handle = NVIF_IOCTL_NEW_V0_PERFMON,
>> +         .ofuncs = &nvkm_perfmon_ofuncs,
>> +       },
>>          { .handle = NVIF_IOCTL_NEW_V0_PERFCTR,
>>            .ofuncs = &nvkm_perfctr_ofuncs,
>>          },
> What I'd like to see here is that nvkm_pm_sclass() only has PERFMON,
> and PERFCTR is created as a child of it (like how all the PDISP
> channel objects are children of the main disp class).  To do this, you
> need to create PERFMON as a nvkm_parent instead of an nvkm_object, and
> have its parent.sclass contain PERFMON.  This will perhaps look a bit
> yucky for the moment, but I'm working on making things cleaner so I'll
> fix it later.  Feel free to ping me on IRC if you need a hand making
> the change though.
>
> I actually have a large patch series with the first part of this
> cleanup work queued up, but if you can make the above change first,
> I'll rebase my work on yours so you don't have to deal with that.

Okay, I'll take a look at the PDISP engine and make this change for the 
PM engine this week.
And if I have some other questions, I'll ping you on IRC.

Thanks,
Samuel.

>
> Thanks,
> Ben.
>
>> --
>> 2.4.2
>>
>> _______________________________________________
>> Nouveau mailing list
>> Nouveau@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/nouveau

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH RFC 05/20] pm: reorganize the nvif interface
       [not found]             ` <55776056.9010302-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2015-06-14  2:32               ` Ben Skeggs
       [not found]                 ` <CACAvsv6+xYKtqFQ5HW3vp7yJ1D+puJS7k8TgfxhLO9aY0tzHtA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 25+ messages in thread
From: Ben Skeggs @ 2015-06-14  2:32 UTC (permalink / raw)
  To: Samuel Pitoiset; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On 10 June 2015 at 07:53, Samuel Pitoiset <samuel.pitoiset@gmail.com> wrote:
>
>
> On 06/09/2015 12:02 AM, Ben Skeggs wrote:
>>
>> On 8 June 2015 at 06:40, Samuel Pitoiset <samuel.pitoiset@gmail.com>
>> wrote:
>>>
>>> This commit introduces the NVIF_IOCTL_NEW_V0_PERFMON class which will be
>>> used in order to query domains, signals and sources. This separates the
>>> querying and the counting interface.
>>
>> Hey Samuel,
>>
>> I've merged patches 1-4 already, I've got some comments on this one,
>> but after they're solved I'm happy to merge up to (and including)
>> patch 18.  Patches 19/20, I need to think about some more.
>>
>
> Hey Ben,
>
> Thanks for reviewing this series so quickly. :-)
>
>
>>> Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
>>> ---
>>>   bin/nv_perfmon.c                  | 12 ++++++------
>>>   drm/nouveau/include/nvif/class.h  | 26 ++++++++++++++++----------
>>>   drm/nouveau/include/nvif/ioctl.h  |  5 +++--
>>>   drm/nouveau/nvkm/engine/pm/base.c | 38
>>> ++++++++++++++++++++++++++++++++------
>>>   4 files changed, 57 insertions(+), 24 deletions(-)
>>>
>>> diff --git a/bin/nv_perfmon.c b/bin/nv_perfmon.c
>>> index a8c5838..30a3138 100644
>>> --- a/bin/nv_perfmon.c
>>> +++ b/bin/nv_perfmon.c
>>> @@ -600,7 +600,7 @@ main(int argc, char **argv)
>>>          const char *cfg = NULL;
>>>          const char *dbg = "error";
>>>          u64 dev = ~0ULL;
>>> -       struct nvif_perfctr_query_v0 args = {};
>>> +       struct nvif_perfmon_query_signal_v0 args = {};
>>>          struct nvif_client *client;
>>>          struct nvif_object object;
>>>          int ret, c, k;
>>> @@ -644,15 +644,14 @@ main(int argc, char **argv)
>>>          }
>>>
>>>          ret = nvif_object_init(nvif_object(device), NULL, 0xdeadbeef,
>>> -                              NVIF_IOCTL_NEW_V0_PERFCTR,
>>> -                              &(struct nvif_perfctr_v0) {
>>> -                              }, sizeof(struct nvif_perfctr_v0),
>>> &object);
>>> +                              NVIF_IOCTL_NEW_V0_PERFMON, NULL, 0,
>>> &object);
>>>          assert(ret == 0);
>>>          do {
>>>                  u32 prev_iter = args.iter;
>>>
>>>                  args.name[0] = '\0';
>>> -               ret = nvif_mthd(&object, NVIF_PERFCTR_V0_QUERY, &args,
>>> sizeof(args));
>>> +               ret = nvif_mthd(&object, NVIF_PERFMON_V0_QUERY_SIGNAL,
>>> +                               &args, sizeof(args));
>>>                  assert(ret == 0);
>>>
>>>                  if (prev_iter) {
>>> @@ -663,7 +662,8 @@ main(int argc, char **argv)
>>>                          args.iter = prev_iter;
>>>                          strncpy(signals[nr_signals - 1], args.name,
>>>                                  sizeof(args.name));
>>> -                       ret = nvif_mthd(&object, NVIF_PERFCTR_V0_QUERY,
>>> &args, sizeof(args));
>>> +                       ret = nvif_mthd(&object,
>>> NVIF_PERFMON_V0_QUERY_SIGNAL,
>>> +                                       &args, sizeof(args));
>>>                          assert(ret == 0);
>>>                  }
>>>          } while (args.iter != 0xffffffff);
>>> diff --git a/drm/nouveau/include/nvif/class.h
>>> b/drm/nouveau/include/nvif/class.h
>>> index 64f8b2f..11935a0 100644
>>> --- a/drm/nouveau/include/nvif/class.h
>>> +++ b/drm/nouveau/include/nvif/class.h
>>> @@ -251,6 +251,20 @@ struct gf110_dma_v0 {
>>>    * perfmon
>>>
>>> ******************************************************************************/
>>>
>>> +#define NVIF_PERFMON_V0_QUERY_SIGNAL
>>> 0x00
>>> +
>>> +struct nvif_perfmon_query_signal_v0 {
>>> +       __u8  version;
>>> +       __u8  pad01[3];
>>> +       __u32 iter;
>>> +       char  name[64];
>>> +};
>>> +
>>> +
>>>
>>> +/*******************************************************************************
>>> + * perfctr
>>> +
>>> ******************************************************************************/
>>> +
>>>   struct nvif_perfctr_v0 {
>>>          __u8  version;
>>>          __u8  pad01[1];
>>> @@ -259,16 +273,8 @@ struct nvif_perfctr_v0 {
>>>          char  name[4][64];
>>>   };
>>>
>>> -#define NVIF_PERFCTR_V0_QUERY
>>> 0x00
>>> -#define NVIF_PERFCTR_V0_SAMPLE
>>> 0x01
>>> -#define NVIF_PERFCTR_V0_READ
>>> 0x02
>>> -
>>> -struct nvif_perfctr_query_v0 {
>>> -       __u8  version;
>>> -       __u8  pad01[3];
>>> -       __u32 iter;
>>> -       char  name[64];
>>> -};
>>> +#define NVIF_PERFCTR_V0_SAMPLE
>>> 0x00
>>> +#define NVIF_PERFCTR_V0_READ
>>> 0x01
>>>
>>>   struct nvif_perfctr_sample {
>>>   };
>>> diff --git a/drm/nouveau/include/nvif/ioctl.h
>>> b/drm/nouveau/include/nvif/ioctl.h
>>> index 4cd8e32..517cd27 100644
>>> --- a/drm/nouveau/include/nvif/ioctl.h
>>> +++ b/drm/nouveau/include/nvif/ioctl.h
>>> @@ -49,8 +49,9 @@ struct nvif_ioctl_new_v0 {
>>>          __u64 token;
>>>          __u32 handle;
>>>   /* these class numbers are made up by us, and not nvidia-assigned */
>>> -#define NVIF_IOCTL_NEW_V0_PERFCTR
>>> 0x0000ffff
>>> -#define NVIF_IOCTL_NEW_V0_CONTROL
>>> 0x0000fffe
>>> +#define NVIF_IOCTL_NEW_V0_PERFMON
>>> 0x0000ffff
>>> +#define NVIF_IOCTL_NEW_V0_PERFCTR
>>> 0x0000fffe
>>> +#define NVIF_IOCTL_NEW_V0_CONTROL
>>> 0x0000fffd
>>
>> It doesn't matter this time, because we're technically breaking ABI
>> already anyway and current userspace won't be effected, but best to
>> avoid changing class numbers like this :)  It's fine this time though.
>
>
> Sure, since the nvif interface is still not exposed through libdrm, this is
> not going to affect userspace.
> Btw, what is your plan about this? Are you going to merge nvif support to
> libdrm ?
Well, Ilia hasn't quite reviewed the patches yet still ;)  But, you've
been using them successfully so far, so that counts as review.

I have some changes that I haven't quite pushed yet that'll need some
slight re-jigging of the libdrm series, but I'll push to merge it
(finally) once that's done.

>
>
>>
>>>          __u32 oclass;
>>>          __u8  data[];           /* class data (class.h) */
>>>   };
>>> diff --git a/drm/nouveau/nvkm/engine/pm/base.c
>>> b/drm/nouveau/nvkm/engine/pm/base.c
>>> index 7b07e8b..cb88170 100644
>>> --- a/drm/nouveau/nvkm/engine/pm/base.c
>>> +++ b/drm/nouveau/nvkm/engine/pm/base.c
>>> @@ -83,10 +83,10 @@ nvkm_perfsig_find(struct nvkm_pm *ppm, const char
>>> *name, u32 size,
>>>    * Perfmon object classes
>>>
>>> ******************************************************************************/
>>>   static int
>>> -nvkm_perfctr_query(struct nvkm_object *object, void *data, u32 size)
>>> +nvkm_perfmon_mthd_query_signal(struct nvkm_object *object, void *data,
>>> u32 size)
>>>   {
>>>          union {
>>> -               struct nvif_perfctr_query_v0 v0;
>>> +               struct nvif_perfmon_query_signal_v0 v0;
>>>          } *args = data;
>>>          struct nvkm_device *device = nv_device(object);
>>>          struct nvkm_pm *ppm = (void *)object->engine;
>>> @@ -97,9 +97,9 @@ nvkm_perfctr_query(struct nvkm_object *object, void
>>> *data, u32 size)
>>>          int tmp = 0, di, si;
>>>          int ret;
>>>
>>> -       nv_ioctl(object, "perfctr query size %d\n", size);
>>> +       nv_ioctl(object, "perfmon query signal size %d\n", size);
>>>          if (nvif_unpack(args->v0, 0, 0, false)) {
>>> -               nv_ioctl(object, "perfctr query vers %d iter %08x\n",
>>> +               nv_ioctl(object, "perfmon query signal vers %d iter
>>> %08x\n",
>>>                           args->v0.version, args->v0.iter);
>>>                  di = (args->v0.iter & 0xff000000) >> 24;
>>>                  si = (args->v0.iter & 0x00ffffff) - 1;
>>> @@ -142,6 +142,30 @@ nvkm_perfctr_query(struct nvkm_object *object, void
>>> *data, u32 size)
>>>   }
>>>
>>>   static int
>>> +nvkm_perfmon_mthd(struct nvkm_object *object, u32 mthd, void *data, u32
>>> size)
>>> +{
>>> +       switch (mthd) {
>>> +       case NVIF_PERFMON_V0_QUERY_SIGNAL:
>>> +               return nvkm_perfmon_mthd_query_signal(object, data,
>>> size);
>>> +       default:
>>> +               break;
>>> +       }
>>> +       return -EINVAL;
>>> +}
>>> +
>>> +static struct nvkm_ofuncs
>>> +nvkm_perfmon_ofuncs = {
>>> +       .ctor = _nvkm_object_ctor,
>>> +       .dtor = nvkm_object_destroy,
>>> +       .init = nvkm_object_init,
>>> +       .fini = nvkm_object_fini,
>>> +       .mthd = nvkm_perfmon_mthd,
>>> +};
>>> +
>>>
>>> +/*******************************************************************************
>>> + * Perfctr object classes
>>> +
>>> ******************************************************************************/
>>> +static int
>>>   nvkm_perfctr_sample(struct nvkm_object *object, void *data, u32 size)
>>>   {
>>>          union {
>>> @@ -221,8 +245,6 @@ static int
>>>   nvkm_perfctr_mthd(struct nvkm_object *object, u32 mthd, void *data, u32
>>> size)
>>>   {
>>>          switch (mthd) {
>>> -       case NVIF_PERFCTR_V0_QUERY:
>>> -               return nvkm_perfctr_query(object, data, size);
>>>          case NVIF_PERFCTR_V0_SAMPLE:
>>>                  return nvkm_perfctr_sample(object, data, size);
>>>          case NVIF_PERFCTR_V0_READ:
>>> @@ -299,6 +321,10 @@ nvkm_perfctr_ofuncs = {
>>>
>>>   struct nvkm_oclass
>>>   nvkm_pm_sclass[] = {
>>> +       {
>>> +         .handle = NVIF_IOCTL_NEW_V0_PERFMON,
>>> +         .ofuncs = &nvkm_perfmon_ofuncs,
>>> +       },
>>>          { .handle = NVIF_IOCTL_NEW_V0_PERFCTR,
>>>            .ofuncs = &nvkm_perfctr_ofuncs,
>>>          },
>>
>> What I'd like to see here is that nvkm_pm_sclass() only has PERFMON,
>> and PERFCTR is created as a child of it (like how all the PDISP
>> channel objects are children of the main disp class).  To do this, you
>> need to create PERFMON as a nvkm_parent instead of an nvkm_object, and
>> have its parent.sclass contain PERFMON.  This will perhaps look a bit
>> yucky for the moment, but I'm working on making things cleaner so I'll
>> fix it later.  Feel free to ping me on IRC if you need a hand making
>> the change though.
>>
>> I actually have a large patch series with the first part of this
>> cleanup work queued up, but if you can make the above change first,
>> I'll rebase my work on yours so you don't have to deal with that.
>
>
> Okay, I'll take a look at the PDISP engine and make this change for the PM
> engine this week.
> And if I have some other questions, I'll ping you on IRC.
Some work I've got queued up would conflict with these, so I've merged
your patches ahead of time and made that change myself to avoid you
having to rebase your whole series.  Any fixes etc that'd been done
since can be done as separate patches before going to Linus.

Thanks,
Ben.

>
> Thanks,
> Samuel.
>
>
>>
>> Thanks,
>> Ben.
>>
>>> --
>>> 2.4.2
>>>
>>> _______________________________________________
>>> Nouveau mailing list
>>> Nouveau@lists.freedesktop.org
>>> http://lists.freedesktop.org/mailman/listinfo/nouveau
>
>
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH RFC 05/20] pm: reorganize the nvif interface
       [not found]                 ` <CACAvsv6+xYKtqFQ5HW3vp7yJ1D+puJS7k8TgfxhLO9aY0tzHtA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2015-06-14 11:54                   ` Samuel Pitoiset
  0 siblings, 0 replies; 25+ messages in thread
From: Samuel Pitoiset @ 2015-06-14 11:54 UTC (permalink / raw)
  To: Ben Skeggs; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW



On 06/14/2015 04:32 AM, Ben Skeggs wrote:
> On 10 June 2015 at 07:53, Samuel Pitoiset <samuel.pitoiset@gmail.com> wrote:
>>
>> On 06/09/2015 12:02 AM, Ben Skeggs wrote:
>>> On 8 June 2015 at 06:40, Samuel Pitoiset <samuel.pitoiset@gmail.com>
>>> wrote:
>>>> This commit introduces the NVIF_IOCTL_NEW_V0_PERFMON class which will be
>>>> used in order to query domains, signals and sources. This separates the
>>>> querying and the counting interface.
>>> Hey Samuel,
>>>
>>> I've merged patches 1-4 already, I've got some comments on this one,
>>> but after they're solved I'm happy to merge up to (and including)
>>> patch 18.  Patches 19/20, I need to think about some more.
>>>
>> Hey Ben,
>>
>> Thanks for reviewing this series so quickly. :-)
>>
>>
>>>> Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
>>>> ---
>>>>    bin/nv_perfmon.c                  | 12 ++++++------
>>>>    drm/nouveau/include/nvif/class.h  | 26 ++++++++++++++++----------
>>>>    drm/nouveau/include/nvif/ioctl.h  |  5 +++--
>>>>    drm/nouveau/nvkm/engine/pm/base.c | 38
>>>> ++++++++++++++++++++++++++++++++------
>>>>    4 files changed, 57 insertions(+), 24 deletions(-)
>>>>
>>>> diff --git a/bin/nv_perfmon.c b/bin/nv_perfmon.c
>>>> index a8c5838..30a3138 100644
>>>> --- a/bin/nv_perfmon.c
>>>> +++ b/bin/nv_perfmon.c
>>>> @@ -600,7 +600,7 @@ main(int argc, char **argv)
>>>>           const char *cfg = NULL;
>>>>           const char *dbg = "error";
>>>>           u64 dev = ~0ULL;
>>>> -       struct nvif_perfctr_query_v0 args = {};
>>>> +       struct nvif_perfmon_query_signal_v0 args = {};
>>>>           struct nvif_client *client;
>>>>           struct nvif_object object;
>>>>           int ret, c, k;
>>>> @@ -644,15 +644,14 @@ main(int argc, char **argv)
>>>>           }
>>>>
>>>>           ret = nvif_object_init(nvif_object(device), NULL, 0xdeadbeef,
>>>> -                              NVIF_IOCTL_NEW_V0_PERFCTR,
>>>> -                              &(struct nvif_perfctr_v0) {
>>>> -                              }, sizeof(struct nvif_perfctr_v0),
>>>> &object);
>>>> +                              NVIF_IOCTL_NEW_V0_PERFMON, NULL, 0,
>>>> &object);
>>>>           assert(ret == 0);
>>>>           do {
>>>>                   u32 prev_iter = args.iter;
>>>>
>>>>                   args.name[0] = '\0';
>>>> -               ret = nvif_mthd(&object, NVIF_PERFCTR_V0_QUERY, &args,
>>>> sizeof(args));
>>>> +               ret = nvif_mthd(&object, NVIF_PERFMON_V0_QUERY_SIGNAL,
>>>> +                               &args, sizeof(args));
>>>>                   assert(ret == 0);
>>>>
>>>>                   if (prev_iter) {
>>>> @@ -663,7 +662,8 @@ main(int argc, char **argv)
>>>>                           args.iter = prev_iter;
>>>>                           strncpy(signals[nr_signals - 1], args.name,
>>>>                                   sizeof(args.name));
>>>> -                       ret = nvif_mthd(&object, NVIF_PERFCTR_V0_QUERY,
>>>> &args, sizeof(args));
>>>> +                       ret = nvif_mthd(&object,
>>>> NVIF_PERFMON_V0_QUERY_SIGNAL,
>>>> +                                       &args, sizeof(args));
>>>>                           assert(ret == 0);
>>>>                   }
>>>>           } while (args.iter != 0xffffffff);
>>>> diff --git a/drm/nouveau/include/nvif/class.h
>>>> b/drm/nouveau/include/nvif/class.h
>>>> index 64f8b2f..11935a0 100644
>>>> --- a/drm/nouveau/include/nvif/class.h
>>>> +++ b/drm/nouveau/include/nvif/class.h
>>>> @@ -251,6 +251,20 @@ struct gf110_dma_v0 {
>>>>     * perfmon
>>>>
>>>> ******************************************************************************/
>>>>
>>>> +#define NVIF_PERFMON_V0_QUERY_SIGNAL
>>>> 0x00
>>>> +
>>>> +struct nvif_perfmon_query_signal_v0 {
>>>> +       __u8  version;
>>>> +       __u8  pad01[3];
>>>> +       __u32 iter;
>>>> +       char  name[64];
>>>> +};
>>>> +
>>>> +
>>>>
>>>> +/*******************************************************************************
>>>> + * perfctr
>>>> +
>>>> ******************************************************************************/
>>>> +
>>>>    struct nvif_perfctr_v0 {
>>>>           __u8  version;
>>>>           __u8  pad01[1];
>>>> @@ -259,16 +273,8 @@ struct nvif_perfctr_v0 {
>>>>           char  name[4][64];
>>>>    };
>>>>
>>>> -#define NVIF_PERFCTR_V0_QUERY
>>>> 0x00
>>>> -#define NVIF_PERFCTR_V0_SAMPLE
>>>> 0x01
>>>> -#define NVIF_PERFCTR_V0_READ
>>>> 0x02
>>>> -
>>>> -struct nvif_perfctr_query_v0 {
>>>> -       __u8  version;
>>>> -       __u8  pad01[3];
>>>> -       __u32 iter;
>>>> -       char  name[64];
>>>> -};
>>>> +#define NVIF_PERFCTR_V0_SAMPLE
>>>> 0x00
>>>> +#define NVIF_PERFCTR_V0_READ
>>>> 0x01
>>>>
>>>>    struct nvif_perfctr_sample {
>>>>    };
>>>> diff --git a/drm/nouveau/include/nvif/ioctl.h
>>>> b/drm/nouveau/include/nvif/ioctl.h
>>>> index 4cd8e32..517cd27 100644
>>>> --- a/drm/nouveau/include/nvif/ioctl.h
>>>> +++ b/drm/nouveau/include/nvif/ioctl.h
>>>> @@ -49,8 +49,9 @@ struct nvif_ioctl_new_v0 {
>>>>           __u64 token;
>>>>           __u32 handle;
>>>>    /* these class numbers are made up by us, and not nvidia-assigned */
>>>> -#define NVIF_IOCTL_NEW_V0_PERFCTR
>>>> 0x0000ffff
>>>> -#define NVIF_IOCTL_NEW_V0_CONTROL
>>>> 0x0000fffe
>>>> +#define NVIF_IOCTL_NEW_V0_PERFMON
>>>> 0x0000ffff
>>>> +#define NVIF_IOCTL_NEW_V0_PERFCTR
>>>> 0x0000fffe
>>>> +#define NVIF_IOCTL_NEW_V0_CONTROL
>>>> 0x0000fffd
>>> It doesn't matter this time, because we're technically breaking ABI
>>> already anyway and current userspace won't be effected, but best to
>>> avoid changing class numbers like this :)  It's fine this time though.
>>
>> Sure, since the nvif interface is still not exposed through libdrm, this is
>> not going to affect userspace.
>> Btw, what is your plan about this? Are you going to merge nvif support to
>> libdrm ?
> Well, Ilia hasn't quite reviewed the patches yet still ;)  But, you've
> been using them successfully so far, so that counts as review.
>
> I have some changes that I haven't quite pushed yet that'll need some
> slight re-jigging of the libdrm series, but I'll push to merge it
> (finally) once that's done.

Sounds good to me. :-)

>
>>
>>>>           __u32 oclass;
>>>>           __u8  data[];           /* class data (class.h) */
>>>>    };
>>>> diff --git a/drm/nouveau/nvkm/engine/pm/base.c
>>>> b/drm/nouveau/nvkm/engine/pm/base.c
>>>> index 7b07e8b..cb88170 100644
>>>> --- a/drm/nouveau/nvkm/engine/pm/base.c
>>>> +++ b/drm/nouveau/nvkm/engine/pm/base.c
>>>> @@ -83,10 +83,10 @@ nvkm_perfsig_find(struct nvkm_pm *ppm, const char
>>>> *name, u32 size,
>>>>     * Perfmon object classes
>>>>
>>>> ******************************************************************************/
>>>>    static int
>>>> -nvkm_perfctr_query(struct nvkm_object *object, void *data, u32 size)
>>>> +nvkm_perfmon_mthd_query_signal(struct nvkm_object *object, void *data,
>>>> u32 size)
>>>>    {
>>>>           union {
>>>> -               struct nvif_perfctr_query_v0 v0;
>>>> +               struct nvif_perfmon_query_signal_v0 v0;
>>>>           } *args = data;
>>>>           struct nvkm_device *device = nv_device(object);
>>>>           struct nvkm_pm *ppm = (void *)object->engine;
>>>> @@ -97,9 +97,9 @@ nvkm_perfctr_query(struct nvkm_object *object, void
>>>> *data, u32 size)
>>>>           int tmp = 0, di, si;
>>>>           int ret;
>>>>
>>>> -       nv_ioctl(object, "perfctr query size %d\n", size);
>>>> +       nv_ioctl(object, "perfmon query signal size %d\n", size);
>>>>           if (nvif_unpack(args->v0, 0, 0, false)) {
>>>> -               nv_ioctl(object, "perfctr query vers %d iter %08x\n",
>>>> +               nv_ioctl(object, "perfmon query signal vers %d iter
>>>> %08x\n",
>>>>                            args->v0.version, args->v0.iter);
>>>>                   di = (args->v0.iter & 0xff000000) >> 24;
>>>>                   si = (args->v0.iter & 0x00ffffff) - 1;
>>>> @@ -142,6 +142,30 @@ nvkm_perfctr_query(struct nvkm_object *object, void
>>>> *data, u32 size)
>>>>    }
>>>>
>>>>    static int
>>>> +nvkm_perfmon_mthd(struct nvkm_object *object, u32 mthd, void *data, u32
>>>> size)
>>>> +{
>>>> +       switch (mthd) {
>>>> +       case NVIF_PERFMON_V0_QUERY_SIGNAL:
>>>> +               return nvkm_perfmon_mthd_query_signal(object, data,
>>>> size);
>>>> +       default:
>>>> +               break;
>>>> +       }
>>>> +       return -EINVAL;
>>>> +}
>>>> +
>>>> +static struct nvkm_ofuncs
>>>> +nvkm_perfmon_ofuncs = {
>>>> +       .ctor = _nvkm_object_ctor,
>>>> +       .dtor = nvkm_object_destroy,
>>>> +       .init = nvkm_object_init,
>>>> +       .fini = nvkm_object_fini,
>>>> +       .mthd = nvkm_perfmon_mthd,
>>>> +};
>>>> +
>>>>
>>>> +/*******************************************************************************
>>>> + * Perfctr object classes
>>>> +
>>>> ******************************************************************************/
>>>> +static int
>>>>    nvkm_perfctr_sample(struct nvkm_object *object, void *data, u32 size)
>>>>    {
>>>>           union {
>>>> @@ -221,8 +245,6 @@ static int
>>>>    nvkm_perfctr_mthd(struct nvkm_object *object, u32 mthd, void *data, u32
>>>> size)
>>>>    {
>>>>           switch (mthd) {
>>>> -       case NVIF_PERFCTR_V0_QUERY:
>>>> -               return nvkm_perfctr_query(object, data, size);
>>>>           case NVIF_PERFCTR_V0_SAMPLE:
>>>>                   return nvkm_perfctr_sample(object, data, size);
>>>>           case NVIF_PERFCTR_V0_READ:
>>>> @@ -299,6 +321,10 @@ nvkm_perfctr_ofuncs = {
>>>>
>>>>    struct nvkm_oclass
>>>>    nvkm_pm_sclass[] = {
>>>> +       {
>>>> +         .handle = NVIF_IOCTL_NEW_V0_PERFMON,
>>>> +         .ofuncs = &nvkm_perfmon_ofuncs,
>>>> +       },
>>>>           { .handle = NVIF_IOCTL_NEW_V0_PERFCTR,
>>>>             .ofuncs = &nvkm_perfctr_ofuncs,
>>>>           },
>>> What I'd like to see here is that nvkm_pm_sclass() only has PERFMON,
>>> and PERFCTR is created as a child of it (like how all the PDISP
>>> channel objects are children of the main disp class).  To do this, you
>>> need to create PERFMON as a nvkm_parent instead of an nvkm_object, and
>>> have its parent.sclass contain PERFMON.  This will perhaps look a bit
>>> yucky for the moment, but I'm working on making things cleaner so I'll
>>> fix it later.  Feel free to ping me on IRC if you need a hand making
>>> the change though.
>>>
>>> I actually have a large patch series with the first part of this
>>> cleanup work queued up, but if you can make the above change first,
>>> I'll rebase my work on yours so you don't have to deal with that.
>>
>> Okay, I'll take a look at the PDISP engine and make this change for the PM
>> engine this week.
>> And if I have some other questions, I'll ping you on IRC.
> Some work I've got queued up would conflict with these, so I've merged
> your patches ahead of time and made that change myself to avoid you
> having to rebase your whole series.  Any fixes etc that'd been done
> since can be done as separate patches before going to Linus.

Well, I submitted two patches which fix some minor stuff to the series.
Let met know if they are okay for you.

By the way, I also submitted a patch which adds compute signals/sources 
on Fermi.

Thanks,
Samuel.

>
> Thanks,
> Ben.
>
>> Thanks,
>> Samuel.
>>
>>
>>> Thanks,
>>> Ben.
>>>
>>>> --
>>>> 2.4.2
>>>>
>>>> _______________________________________________
>>>> Nouveau mailing list
>>>> Nouveau@lists.freedesktop.org
>>>> http://lists.freedesktop.org/mailman/listinfo/nouveau
>>

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2015-06-14 11:54 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-07 20:40 [PATCH RFC 00/20] expose global performance counters Samuel Pitoiset
     [not found] ` <1433709630-3293-1-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-06-07 20:40   ` [PATCH RFC 01/20] pm: prevent freeing the wrong engine context Samuel Pitoiset
2015-06-07 20:40   ` [PATCH RFC 02/20] pm: fix a potential race condition when creating an " Samuel Pitoiset
2015-06-07 20:40   ` [PATCH RFC 03/20] pm: remove pmu signals Samuel Pitoiset
2015-06-07 20:40   ` [PATCH RFC 04/20] pm: remove unused nvkm_perfsig_wrap() function Samuel Pitoiset
2015-06-07 20:40   ` [PATCH RFC 05/20] pm: reorganize the nvif interface Samuel Pitoiset
     [not found]     ` <1433709630-3293-6-git-send-email-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-06-08 22:02       ` Ben Skeggs
     [not found]         ` <CACAvsv4x2vcWND6bE1tGSDQMy_doysboV7O8551CfGKz4MwcMA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-06-09 21:53           ` Samuel Pitoiset
     [not found]             ` <55776056.9010302-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-06-14  2:32               ` Ben Skeggs
     [not found]                 ` <CACAvsv6+xYKtqFQ5HW3vp7yJ1D+puJS7k8TgfxhLO9aY0tzHtA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-06-14 11:54                   ` Samuel Pitoiset
2015-06-07 20:40   ` [PATCH RFC 06/20] pm: prevent creating a perfctr object when signals are not found Samuel Pitoiset
2015-06-07 20:40   ` [PATCH RFC 07/20] pm: implement NVIF_PERFMON_V0_QUERY_DOMAIN method Samuel Pitoiset
2015-06-07 20:40   ` [PATCH RFC 08/20] pm: allow to query signals by domain Samuel Pitoiset
2015-06-07 20:40   ` [PATCH RFC 09/20] pm: change signal iter to u16 Samuel Pitoiset
2015-06-07 20:40   ` [PATCH RFC 10/20] pm: use hardware signals indexes instead of user-readable names Samuel Pitoiset
2015-06-07 20:40   ` [PATCH RFC 11/20] pm: allow to monitor hardware signal index 0x00 Samuel Pitoiset
2015-06-07 20:40   ` [PATCH RFC 12/20] pm: add concept of sources Samuel Pitoiset
2015-06-07 20:40   ` [PATCH RFC 13/20] pm: allow to query the number of sources for a signal Samuel Pitoiset
2015-06-07 20:40   ` [PATCH RFC 14/20] pm: implement NVIF_PERFMON_V0_QUERY_SOURCE method Samuel Pitoiset
2015-06-07 20:40   ` [PATCH RFC 15/20] pm: allow the userspace to schedule hardware counters Samuel Pitoiset
2015-06-07 20:40   ` [PATCH RFC 16/20] pm: allow to configure domains instead of simple counters Samuel Pitoiset
2015-06-07 20:40   ` [PATCH RFC 17/20] pm: allow the userspace to configure sources Samuel Pitoiset
2015-06-07 20:40   ` [PATCH RFC 18/20] pm/nv50: add compute and graphics signals/sources Samuel Pitoiset
2015-06-07 20:40   ` [PATCH RFC 19/20] sw/nv50: add some private functions to factorize code Samuel Pitoiset
2015-06-07 20:40   ` [PATCH RFC 20/20] sw/nv50: add and interface for controlling performance counters Samuel Pitoiset

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.