[Nouveau] [PATCH RFC 07/20] pm: implement NVIF_PERFMON_V0_QUERY_DOMAIN method

Samuel Pitoiset samuel.pitoiset at gmail.com
Sun Jun 7 13:40:17 PDT 2015


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 at 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



More information about the Nouveau mailing list