[Nouveau] [RFC v2 5/6] nouveau/debugfs: add interface for current load

Karol Herbst karolherbst at gmail.com
Sun May 7 22:46:47 UTC 2017


output of the file will be something like that:

core, mem,  vid,  pci
0xfd, 0x15, 0x00, 0xa2

v2: relayout the debugfs file

Signed-off-by: Karol Herbst <karolherbst at gmail.com>
---
 drm/nouveau/include/nvif/device.h     |  1 +
 drm/nouveau/include/nvkm/subdev/pmu.h | 10 ++++++++++
 drm/nouveau/nouveau_debugfs.c         | 23 +++++++++++++++++++++++
 drm/nouveau/nvkm/subdev/pmu/base.c    |  8 ++++++++
 drm/nouveau/nvkm/subdev/pmu/gf100.c   |  2 ++
 drm/nouveau/nvkm/subdev/pmu/gf119.c   |  2 ++
 drm/nouveau/nvkm/subdev/pmu/gk104.c   |  2 ++
 drm/nouveau/nvkm/subdev/pmu/gk110.c   |  2 ++
 drm/nouveau/nvkm/subdev/pmu/gk208.c   |  2 ++
 drm/nouveau/nvkm/subdev/pmu/gm107.c   |  2 ++
 drm/nouveau/nvkm/subdev/pmu/gt215.c   | 31 +++++++++++++++++++++++++++++++
 drm/nouveau/nvkm/subdev/pmu/priv.h    |  4 ++++
 12 files changed, 89 insertions(+)

diff --git a/drm/nouveau/include/nvif/device.h b/drm/nouveau/include/nvif/device.h
index bcb98171..2b9f725f 100644
--- a/drm/nouveau/include/nvif/device.h
+++ b/drm/nouveau/include/nvif/device.h
@@ -65,6 +65,7 @@ u64  nvif_device_time(struct nvif_device *);
 #define nvxx_iccsense(a) nvxx_device(a)->iccsense
 #define nvxx_therm(a) nvxx_device(a)->therm
 #define nvxx_volt(a) nvxx_device(a)->volt
+#define nvxx_pmu(a) nvxx_device(a)->pmu
 
 #include <core/device.h>
 #include <engine/fifo.h>
diff --git a/drm/nouveau/include/nvkm/subdev/pmu.h b/drm/nouveau/include/nvkm/subdev/pmu.h
index e7f04732..4c8157df 100644
--- a/drm/nouveau/include/nvkm/subdev/pmu.h
+++ b/drm/nouveau/include/nvkm/subdev/pmu.h
@@ -26,6 +26,13 @@ struct nvkm_pmu {
 	} recv;
 };
 
+struct nvkm_pmu_load_data {
+	u8 core;
+	u8 mem;
+	u8 video;
+	u8 pcie;
+};
+
 int nvkm_pmu_send(struct nvkm_pmu *, u32 reply[2], u32 process,
 		  u32 message, u32 data0, u32 data1);
 void nvkm_pmu_pgob(struct nvkm_pmu *, bool enable);
@@ -54,4 +61,7 @@ void nvkm_memx_train(struct nvkm_memx *);
 int  nvkm_memx_train_result(struct nvkm_pmu *, u32 *, int);
 void nvkm_memx_block(struct nvkm_memx *);
 void nvkm_memx_unblock(struct nvkm_memx *);
+
+/* interface to PERF process running on PMU */
+int nvkm_pmu_get_perf_data(struct nvkm_pmu *, struct nvkm_pmu_load_data *);
 #endif
diff --git a/drm/nouveau/nouveau_debugfs.c b/drm/nouveau/nouveau_debugfs.c
index fd64dfdc..5c7fa89c 100644
--- a/drm/nouveau/nouveau_debugfs.c
+++ b/drm/nouveau/nouveau_debugfs.c
@@ -31,6 +31,8 @@
 #include <linux/debugfs.h>
 #include <nvif/class.h>
 #include <nvif/if0001.h>
+#include <nvkm/subdev/pmu.h>
+
 #include "nouveau_debugfs.h"
 #include "nouveau_drv.h"
 
@@ -180,8 +182,29 @@ static const struct file_operations nouveau_pstate_fops = {
 	.write = nouveau_debugfs_pstate_set,
 };
 
+static int
+nouveau_debugfs_current_load(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct nouveau_drm *drm = nouveau_drm(node->minor->dev);
+	struct nvkm_pmu *pmu = nvxx_pmu(&drm->client.device);
+	struct nvkm_pmu_load_data load_data = { 0 };
+
+	if (!pm_runtime_suspended(drm->dev->dev)) {
+		int ret = nvkm_pmu_get_perf_data(pmu, &load_data);
+		if (ret < 0)
+			return ret;
+	}
+
+	seq_printf(m, "core, mem,  vid,  pci\n");
+	seq_printf(m, "0x%2.2x, 0x%2.2x, 0x%2.2x, 0x%2.2x\n", load_data.core,
+		   load_data.mem, load_data.video, load_data.pcie);
+	return 0;
+}
+
 static struct drm_info_list nouveau_debugfs_list[] = {
 	{ "vbios.rom", nouveau_debugfs_vbios_image, 0, NULL },
+	{ "current_load", nouveau_debugfs_current_load, 0, NULL },
 };
 #define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list)
 
diff --git a/drm/nouveau/nvkm/subdev/pmu/base.c b/drm/nouveau/nvkm/subdev/pmu/base.c
index 3306f9fe..0ef97ddd 100644
--- a/drm/nouveau/nvkm/subdev/pmu/base.c
+++ b/drm/nouveau/nvkm/subdev/pmu/base.c
@@ -49,6 +49,14 @@ nvkm_pmu_send(struct nvkm_pmu *pmu, u32 reply[2],
 	return pmu->func->send(pmu, reply, process, message, data0, data1);
 }
 
+int
+nvkm_pmu_get_perf_data(struct nvkm_pmu *pmu, struct nvkm_pmu_load_data *data)
+{
+	if (!pmu || !pmu->func->get_perf_data)
+		return -ENODEV;
+	return pmu->func->get_perf_data(pmu, data);
+}
+
 static void
 nvkm_pmu_intr(struct nvkm_subdev *subdev)
 {
diff --git a/drm/nouveau/nvkm/subdev/pmu/gf100.c b/drm/nouveau/nvkm/subdev/pmu/gf100.c
index 0e36d4cb..1c4986cb 100644
--- a/drm/nouveau/nvkm/subdev/pmu/gf100.c
+++ b/drm/nouveau/nvkm/subdev/pmu/gf100.c
@@ -30,12 +30,14 @@ gf100_pmu = {
 	.code.size = sizeof(gf100_pmu_code),
 	.data.data = gf100_pmu_data,
 	.data.size = sizeof(gf100_pmu_data),
+	.counter_slots = 8,
 	.reset = gt215_pmu_reset,
 	.init = gt215_pmu_init,
 	.fini = gt215_pmu_fini,
 	.intr = gt215_pmu_intr,
 	.send = gt215_pmu_send,
 	.recv = gt215_pmu_recv,
+	.get_perf_data = gt215_pmu_get_perf_data,
 };
 
 int
diff --git a/drm/nouveau/nvkm/subdev/pmu/gf119.c b/drm/nouveau/nvkm/subdev/pmu/gf119.c
index 0e4ba424..49d8fb22 100644
--- a/drm/nouveau/nvkm/subdev/pmu/gf119.c
+++ b/drm/nouveau/nvkm/subdev/pmu/gf119.c
@@ -30,12 +30,14 @@ gf119_pmu = {
 	.code.size = sizeof(gf119_pmu_code),
 	.data.data = gf119_pmu_data,
 	.data.size = sizeof(gf119_pmu_data),
+	.counter_slots = 8,
 	.reset = gt215_pmu_reset,
 	.init = gt215_pmu_init,
 	.fini = gt215_pmu_fini,
 	.intr = gt215_pmu_intr,
 	.send = gt215_pmu_send,
 	.recv = gt215_pmu_recv,
+	.get_perf_data = gt215_pmu_get_perf_data,
 };
 
 int
diff --git a/drm/nouveau/nvkm/subdev/pmu/gk104.c b/drm/nouveau/nvkm/subdev/pmu/gk104.c
index 2ad858d8..7ae36a78 100644
--- a/drm/nouveau/nvkm/subdev/pmu/gk104.c
+++ b/drm/nouveau/nvkm/subdev/pmu/gk104.c
@@ -109,6 +109,7 @@ gk104_pmu = {
 	.code.size = sizeof(gk104_pmu_code),
 	.data.data = gk104_pmu_data,
 	.data.size = sizeof(gk104_pmu_data),
+	.counter_slots = 8,
 	.reset = gt215_pmu_reset,
 	.init = gt215_pmu_init,
 	.fini = gt215_pmu_fini,
@@ -116,6 +117,7 @@ gk104_pmu = {
 	.send = gt215_pmu_send,
 	.recv = gt215_pmu_recv,
 	.pgob = gk104_pmu_pgob,
+	.get_perf_data = gt215_pmu_get_perf_data,
 };
 
 int
diff --git a/drm/nouveau/nvkm/subdev/pmu/gk110.c b/drm/nouveau/nvkm/subdev/pmu/gk110.c
index fc4b8ecf..84001c27 100644
--- a/drm/nouveau/nvkm/subdev/pmu/gk110.c
+++ b/drm/nouveau/nvkm/subdev/pmu/gk110.c
@@ -88,6 +88,7 @@ gk110_pmu = {
 	.code.size = sizeof(gk110_pmu_code),
 	.data.data = gk110_pmu_data,
 	.data.size = sizeof(gk110_pmu_data),
+	.counter_slots = 8,
 	.reset = gt215_pmu_reset,
 	.init = gt215_pmu_init,
 	.fini = gt215_pmu_fini,
@@ -95,6 +96,7 @@ gk110_pmu = {
 	.send = gt215_pmu_send,
 	.recv = gt215_pmu_recv,
 	.pgob = gk110_pmu_pgob,
+	.get_perf_data = gt215_pmu_get_perf_data,
 };
 
 int
diff --git a/drm/nouveau/nvkm/subdev/pmu/gk208.c b/drm/nouveau/nvkm/subdev/pmu/gk208.c
index e9a91277..f2d743e6 100644
--- a/drm/nouveau/nvkm/subdev/pmu/gk208.c
+++ b/drm/nouveau/nvkm/subdev/pmu/gk208.c
@@ -30,6 +30,7 @@ gk208_pmu = {
 	.code.size = sizeof(gk208_pmu_code),
 	.data.data = gk208_pmu_data,
 	.data.size = sizeof(gk208_pmu_data),
+	.counter_slots = 8,
 	.reset = gt215_pmu_reset,
 	.init = gt215_pmu_init,
 	.fini = gt215_pmu_fini,
@@ -37,6 +38,7 @@ gk208_pmu = {
 	.send = gt215_pmu_send,
 	.recv = gt215_pmu_recv,
 	.pgob = gk110_pmu_pgob,
+	.get_perf_data = gt215_pmu_get_perf_data,
 };
 
 int
diff --git a/drm/nouveau/nvkm/subdev/pmu/gm107.c b/drm/nouveau/nvkm/subdev/pmu/gm107.c
index 9a248ed7..f0a964ff 100644
--- a/drm/nouveau/nvkm/subdev/pmu/gm107.c
+++ b/drm/nouveau/nvkm/subdev/pmu/gm107.c
@@ -32,12 +32,14 @@ gm107_pmu = {
 	.code.size = sizeof(gm107_pmu_code),
 	.data.data = gm107_pmu_data,
 	.data.size = sizeof(gm107_pmu_data),
+	.counter_slots = 8,
 	.reset = gt215_pmu_reset,
 	.init = gt215_pmu_init,
 	.fini = gt215_pmu_fini,
 	.intr = gt215_pmu_intr,
 	.send = gt215_pmu_send,
 	.recv = gt215_pmu_recv,
+	.get_perf_data = gt215_pmu_get_perf_data,
 };
 
 int
diff --git a/drm/nouveau/nvkm/subdev/pmu/gt215.c b/drm/nouveau/nvkm/subdev/pmu/gt215.c
index 43ca70df..6ffd3cba 100644
--- a/drm/nouveau/nvkm/subdev/pmu/gt215.c
+++ b/drm/nouveau/nvkm/subdev/pmu/gt215.c
@@ -56,6 +56,35 @@ wait_for_pmu_reply(struct nvkm_pmu *pmu, u32 reply[2])
 	return 0;
 }
 
+enum nvkm_pmu_counter_slot {
+	NVKM_PMU_COUNTER_SLOT_TOTAL = 0,
+	NVKM_PMU_COUNTER_SLOT_CORE = 1,
+	NVKM_PMU_COUNTER_SLOT_MEMORY = 2,
+	NVKM_PMU_COUNTER_SLOT_VIDEO = 3,
+	NVKM_PMU_COUNTER_SLOT_PCIE = 4,
+	NVKM_PMU_COUNTER_SLOT_LAST,
+};
+
+int
+gt215_pmu_get_perf_data(struct nvkm_pmu *pmu, struct nvkm_pmu_load_data *data)
+{
+	int ret;
+	union {
+		u32 raw[2];
+		u8 slots[8];
+	} d;
+
+	ret = nvkm_pmu_send(pmu, d.raw, PROC_PERF, PERF_MSG_GET_SLOTS, 0, 0);
+	if (ret < 0)
+		return ret;
+
+	data->core = d.slots[NVKM_PMU_COUNTER_SLOT_CORE];
+	data->video = d.slots[NVKM_PMU_COUNTER_SLOT_VIDEO];
+	data->mem = d.slots[NVKM_PMU_COUNTER_SLOT_MEMORY];
+	data->pcie = d.slots[NVKM_PMU_COUNTER_SLOT_PCIE];
+	return 0;
+}
+
 int
 gt215_pmu_send(struct nvkm_pmu *pmu, u32 reply[2],
 	       u32 process, u32 message, u32 data0, u32 data1)
@@ -274,12 +303,14 @@ gt215_pmu = {
 	.code.size = sizeof(gt215_pmu_code),
 	.data.data = gt215_pmu_data,
 	.data.size = sizeof(gt215_pmu_data),
+	.counter_slots = 4,
 	.reset = gt215_pmu_reset,
 	.init = gt215_pmu_init,
 	.fini = gt215_pmu_fini,
 	.intr = gt215_pmu_intr,
 	.send = gt215_pmu_send,
 	.recv = gt215_pmu_recv,
+	.get_perf_data = gt215_pmu_get_perf_data,
 };
 
 int
diff --git a/drm/nouveau/nvkm/subdev/pmu/priv.h b/drm/nouveau/nvkm/subdev/pmu/priv.h
index 096cba06..4cd38b80 100644
--- a/drm/nouveau/nvkm/subdev/pmu/priv.h
+++ b/drm/nouveau/nvkm/subdev/pmu/priv.h
@@ -20,6 +20,8 @@ struct nvkm_pmu_func {
 		u32  size;
 	} data;
 
+	uint8_t counter_slots;
+
 	void (*reset)(struct nvkm_pmu *);
 	int (*init)(struct nvkm_pmu *);
 	void (*fini)(struct nvkm_pmu *);
@@ -28,6 +30,7 @@ struct nvkm_pmu_func {
 		    u32 message, u32 data0, u32 data1);
 	void (*recv)(struct nvkm_pmu *);
 	void (*pgob)(struct nvkm_pmu *, bool);
+	int (*get_perf_data)(struct nvkm_pmu *, struct nvkm_pmu_load_data *);
 };
 
 void gt215_pmu_reset(struct nvkm_pmu *);
@@ -36,6 +39,7 @@ void gt215_pmu_fini(struct nvkm_pmu *);
 void gt215_pmu_intr(struct nvkm_pmu *);
 void gt215_pmu_recv(struct nvkm_pmu *);
 int gt215_pmu_send(struct nvkm_pmu *, u32[2], u32, u32, u32, u32);
+int gt215_pmu_get_perf_data(struct nvkm_pmu *, struct nvkm_pmu_load_data *);
 
 void gk110_pmu_pgob(struct nvkm_pmu *, bool);
 #endif
-- 
2.12.2



More information about the Nouveau mailing list