[Nouveau] [PATCH v2 4/5] debugfs: add copy of sysfs pstate interface ported to debugfs

Karol Herbst nouveau at karolherbst.de
Mon Nov 9 07:11:27 PST 2015


Signed-off-by: Karol Herbst <nouveau at karolherbst.de>
---
 drm/nouveau/nouveau_debugfs.c | 146 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 144 insertions(+), 2 deletions(-)

diff --git a/drm/nouveau/nouveau_debugfs.c b/drm/nouveau/nouveau_debugfs.c
index 6f317a7..61134c8 100644
--- a/drm/nouveau/nouveau_debugfs.c
+++ b/drm/nouveau/nouveau_debugfs.c
@@ -45,6 +45,147 @@ nouveau_debugfs_vbios_image(struct seq_file *m, void *data)
 	return 0;
 }
 
+static int
+nouveau_debugfs_pstate_get(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct nouveau_debugfs *debugfs = nouveau_debugfs(node->minor->dev);
+	struct nvif_object *ctrl;
+	struct nvif_control_pstate_info_v0 info = {};
+	int ret, i;
+
+	if (!debugfs)
+		return -ENODEV;
+
+	ctrl = &debugfs->ctrl;
+
+	ret = nvif_mthd(ctrl, NVIF_CONTROL_PSTATE_INFO,
+			&info, sizeof(info));
+	if (ret)
+		return ret;
+
+	for (i = 0; i < info.count + 1; i++) {
+		const s32 state = i < info.count ? i :
+			NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT;
+		struct nvif_control_pstate_attr_v0 attr = {
+			.state = state,
+			.index = 0,
+		};
+
+		ret = nvif_mthd(ctrl, NVIF_CONTROL_PSTATE_ATTR,
+				&attr, sizeof(attr));
+		if (ret)
+			return ret;
+
+		if (i < info.count)
+			seq_printf(m, "%02x:", attr.state);
+		else
+			seq_printf(m, "%s:", info.pwrsrc == 0 ? "DC" :
+						   info.pwrsrc == 1 ? "AC" :
+						   "--");
+
+		attr.index = 0;
+		do {
+			attr.state = state;
+			ret = nvif_mthd(ctrl,
+					NVIF_CONTROL_PSTATE_ATTR,
+					&attr, sizeof(attr));
+			if (ret)
+				return ret;
+
+			seq_printf(m, " %s %d", attr.name, attr.min);
+			if (attr.min != attr.max)
+				seq_printf(m, "-%d", attr.max);
+			seq_printf(m, " %s", attr.unit);
+		} while (attr.index);
+
+		if (state >= 0) {
+			if (info.ustate_ac == state)
+				seq_printf(m, " AC");
+			if (info.ustate_dc == state)
+				seq_printf(m, " DC");
+			if (info.pstate == state)
+				seq_printf(m, " *");
+		} else {
+			if (info.ustate_ac < -1)
+				seq_printf(m, " AC");
+			if (info.ustate_dc < -1)
+				seq_printf(m, " DC");
+		}
+
+		seq_printf(m, "\n");
+	}
+
+	return 0;
+}
+
+static ssize_t
+nouveau_debugfs_pstate_set(struct file *file, const char __user *ubuf, size_t len, loff_t *offp)
+{
+	struct seq_file *m = file->private_data;
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct nouveau_debugfs *debugfs = nouveau_debugfs(node->minor->dev);
+	struct nvif_object *ctrl;
+	struct nvif_control_pstate_user_v0 args = { .pwrsrc = -EINVAL };
+	char buf[32] = {}, *tmp, *cur = buf;
+	long value, ret;
+
+	if (!debugfs)
+		return -ENODEV;
+
+	ctrl = &debugfs->ctrl;
+
+	if (len >= sizeof(buf))
+		return -EINVAL;
+
+	if (copy_from_user(buf, ubuf, len))
+		return -EFAULT;
+
+	if ((tmp = strchr(buf, '\n')))
+		*tmp = '\0';
+
+	if (!strncasecmp(cur, "dc:", 3)) {
+		args.pwrsrc = 0;
+		cur += 3;
+	} else
+	if (!strncasecmp(cur, "ac:", 3)) {
+		args.pwrsrc = 1;
+		cur += 3;
+	}
+
+	if (!strcasecmp(cur, "none"))
+		args.ustate = NVIF_CONTROL_PSTATE_USER_V0_STATE_UNKNOWN;
+	else
+	if (!strcasecmp(cur, "auto"))
+		args.ustate = NVIF_CONTROL_PSTATE_USER_V0_STATE_PERFMON;
+	else {
+		ret = kstrtol(cur, 16, &value);
+		if (ret)
+			return ret;
+		args.ustate = value;
+	}
+
+	ret = nvif_mthd(ctrl, NVIF_CONTROL_PSTATE_USER,
+			&args, sizeof(args));
+	if (ret < 0)
+		return ret;
+
+	return len;
+}
+
+static int
+nouveau_debugfs_pstate_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, nouveau_debugfs_pstate_get, inode->i_private);
+}
+
+static const struct file_operations nouveau_pstate_fops = {
+	.owner = THIS_MODULE,
+	.open = nouveau_debugfs_pstate_open,
+	.read = seq_read,
+	.write = nouveau_debugfs_pstate_set,
+};
+
 static struct drm_info_list nouveau_debugfs_list[] = {
 	{ "vbios.rom", nouveau_debugfs_vbios_image, 0, NULL },
 };
@@ -53,8 +194,9 @@ static struct drm_info_list nouveau_debugfs_list[] = {
 static const struct nouveau_debugfs_files {
 	const char *name;
 	const struct file_operations *fops;
-} nouveau_debugfs_files[] = {};
-
+} nouveau_debugfs_files[] = {
+	{"pstate", &nouveau_pstate_fops},
+};
 
 static int
 nouveau_debugfs_create_file(struct drm_minor *minor,
-- 
2.6.3



More information about the Nouveau mailing list