All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sagar Arun Kamble <sagar.a.kamble@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: Sujaritha Sundaresan <sujaritha.sundaresan@intel.com>
Subject: [PATCH v12 14/17] drm/i915/guc/slpc: Add debugfs support to read/write/revert the parameters
Date: Fri, 30 Mar 2018 14:01:59 +0530	[thread overview]
Message-ID: <1522398722-12161-15-git-send-email-sagar.a.kamble@intel.com> (raw)
In-Reply-To: <1522398722-12161-1-git-send-email-sagar.a.kamble@intel.com>

Add support to set/read parameters and unset the parameters which will
revert them to default SLPC internal values. Explicit SLPC reset is needed
on setting/unsetting some of the parameters.

This patch adds two debugfs interfaces:
1. i915_guc_slpc_params: List of all parameters that Host can configure.
   Currently listing id and description of each.
2. i915_guc_slpc_param_ctl: This allows to change the parameters.
   Syntax is:
   * Update parameter with id <id> with value <value>:
     echo "write <id> <value>" > i915_guc_slpc_param_ctl
   * Read parameter with id <id>
     echo "read <id>" > i915_guc_slpc_param_ctl
     cat i915_guc_slpc_param_ctl
   * Revert parameter with id <id> to default value
     echo "revert <id>" > i915_guc_slpc_param_ctl.

v2: Moved the SLPC interfaces to i915_debugfs.c. Added error handling to
the range of parameters and parsing. Making use of intel_guc_slpc_enabled
instead of accessing status variable. Optimized token parsing.
(Michal Wajdeczko) s/i915_slpc_paramlist/i915_guc_slpc_params and
s/i915_slpc_param_ctl/i915_guc_slpc_param_ctl

v3: Rebase.

Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@intel.com>
Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Sujaritha Sundaresan <sujaritha.sundaresan@intel.com>
Cc: Jeff McGee <jeff.mcgee@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c        | 156 +++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_guc_slpc.c      |  87 ++++++++++++++++
 drivers/gpu/drm/i915/intel_guc_slpc.h      |  18 ++++
 drivers/gpu/drm/i915/intel_guc_slpc_fwif.h |  23 +++++
 4 files changed, 284 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 5c1231f..f90ad52 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2777,6 +2777,160 @@ const struct file_operations i915_guc_slpc_dcc_fops = {
 	.llseek	 = seq_lseek
 };
 
+static int i915_guc_slpc_params_info(struct seq_file *m, void *data)
+{
+	struct drm_i915_private *dev_priv = node_to_i915(m->private);
+	struct drm_printer p = drm_seq_file_printer(m);
+
+	if (!USES_GUC_SLPC(dev_priv))
+		return -ENODEV;
+
+	intel_guc_slpc_params_print(&dev_priv->guc.slpc, &p);
+
+	return 0;
+}
+
+static int slpc_param_ctl_show(struct seq_file *m, void *data)
+{
+	struct drm_i915_private *dev_priv = m->private;
+	struct intel_guc_slpc *slpc = &dev_priv->guc.slpc;
+
+	if (!USES_GUC_SLPC(dev_priv))
+		return -ENODEV;
+
+	if (slpc->debug.param_id >= SLPC_MAX_PARAM)
+		return -EINVAL;
+
+	BUILD_BUG_ON(ARRAY_SIZE(slpc_params_desc) != SLPC_MAX_PARAM);
+
+	seq_printf(m, "%s=%u, override=%s\n",
+			slpc_params_desc[slpc->debug.param_id],
+			slpc->debug.param_value,
+			yesno(!!slpc->debug.param_override));
+
+	return 0;
+}
+
+static int slpc_param_ctl_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, slpc_param_ctl_show, inode->i_private);
+}
+
+/*
+ * Parse SLPC parameter control strings: (Similar to Pipe CRC handling)
+ *   command: wsp* op wsp+ param id wsp+ [value] wsp*
+ *   op: "read"/"write"/"revert"
+ *   param id: slpc_param_id
+ *   value: u32 value
+ *   wsp: (#0x20 | #0x9 | #0xA)+
+ *
+ * eg.:
+ *  "read 0"		-> read SLPC_PARAM_TASK_ENABLE_GTPERF
+ *  "write 7 500"	-> set SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ to 500MHz
+ *  "revert 7"		-> revert SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ to
+ *			   default value.
+ */
+static int slpc_param_ctl_parse(char *buf, size_t len, int *op,
+				u32 *id, u32 *value)
+{
+#define MAX_WORDS 3
+	int n_words;
+	char *words[MAX_WORDS];
+	ssize_t ret;
+
+	n_words = buffer_tokenize(buf, words, MAX_WORDS);
+	if (!(n_words == 3) && !(n_words == 2)) {
+		DRM_DEBUG_DRIVER("tokenize failed, a command is %d words\n",
+				 MAX_WORDS);
+		return -EINVAL;
+	}
+
+	if (!strcmp(words[0], "read"))
+		*op = READ_OP;
+	else if (!strcmp(words[0], "write"))
+		*op = WRITE_OP;
+	else if (!strcmp(words[0], "revert"))
+		*op = REVERT_OP;
+	else {
+		DRM_DEBUG_DRIVER("unknown operation\n");
+		return -EINVAL;
+	}
+
+	ret = kstrtou32(words[1], 0, id);
+	if (ret)
+		return ret;
+
+	if (n_words == 3) {
+		ret = kstrtou32(words[2], 0, value);
+		if (ret)
+			return ret;
+	}
+
+	return (n_words-1);
+}
+
+static ssize_t slpc_param_ctl_write(struct file *file, const char __user *ubuf,
+				     size_t len, loff_t *offp)
+{
+	struct seq_file *m = file->private_data;
+	struct drm_i915_private *dev_priv = m->private;
+	struct intel_guc_slpc *slpc = &dev_priv->guc.slpc;
+	char *tmpbuf;
+	u32 id, value;
+	int op, params;
+	int ret = 0;
+
+	if (len == 0)
+		return 0;
+
+	if (len > 40) {
+		DRM_DEBUG_DRIVER("expected <40 chars into slpc_param_ctl\n");
+		return -E2BIG;
+	}
+
+	tmpbuf = kmalloc(len + 1, GFP_KERNEL);
+	if (!tmpbuf)
+		return -ENOMEM;
+
+	if (copy_from_user(tmpbuf, ubuf, len)) {
+		ret = -EFAULT;
+		goto out;
+	}
+	tmpbuf[len] = '\0';
+
+	params = slpc_param_ctl_parse(tmpbuf, len, &op, &id, &value);
+
+	if (params < 0 || id >= SLPC_MAX_PARAM) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	intel_runtime_pm_get(dev_priv);
+	mutex_lock(&slpc->lock);
+
+	ret = intel_guc_slpc_param_control(slpc, params, op, id, value);
+
+	mutex_unlock(&slpc->lock);
+	intel_runtime_pm_put(dev_priv);
+
+out:
+	kfree(tmpbuf);
+	if (ret < 0)
+		return ret;
+
+	*offp += len;
+	return len;
+}
+
+const struct file_operations i915_guc_slpc_param_ctl_fops = {
+	.owner = THIS_MODULE,
+	.open = slpc_param_ctl_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+	.write = slpc_param_ctl_write
+};
+
 static const char *psr2_live_status(u32 val)
 {
 	static const char * const live_status[] = {
@@ -4942,6 +5096,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
 	{"i915_guc_log_dump", i915_guc_log_dump, 0},
 	{"i915_guc_load_err_log_dump", i915_guc_log_dump, 0, (void *)1},
 	{"i915_guc_stage_pool", i915_guc_stage_pool, 0},
+	{"i915_guc_slpc_params", i915_guc_slpc_params_info, 0},
 	{"i915_huc_load_status", i915_huc_load_status_info, 0},
 	{"i915_frequency_info", i915_frequency_info, 0},
 	{"i915_hangcheck_info", i915_hangcheck_info, 0},
@@ -5010,6 +5165,7 @@ static const struct i915_debugfs_files {
 	{"i915_guc_slpc_gtperf", &i915_guc_slpc_gtperf_fops},
 	{"i915_guc_slpc_balancer", &i915_guc_slpc_balancer_fops},
 	{"i915_guc_slpc_dcc", &i915_guc_slpc_dcc_fops},
+	{"i915_guc_slpc_param_ctl", &i915_guc_slpc_param_ctl_fops},
 	{"i915_hpd_storm_ctl", &i915_hpd_storm_ctl_fops},
 	{"i915_ipc_status", &i915_ipc_status_fops},
 	{"i915_drrs_ctl", &i915_drrs_ctl_fops}
diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.c b/drivers/gpu/drm/i915/intel_guc_slpc.c
index 34a5963..7bd5e3e 100644
--- a/drivers/gpu/drm/i915/intel_guc_slpc.c
+++ b/drivers/gpu/drm/i915/intel_guc_slpc.c
@@ -578,6 +578,93 @@ int intel_guc_slpc_task_status(struct intel_guc_slpc *slpc, u64 *val,
 }
 
 /**
+ * intel_guc_slpc_params_print() - print parameters list.
+ * @slpc: pointer to intel_guc_slpc.
+ * @p: drm printer
+ *
+ * This function will print SLPC parameters id and their description.
+ *
+ */
+void intel_guc_slpc_params_print(struct intel_guc_slpc *slpc,
+				 struct drm_printer *p)
+{
+	int i;
+
+	BUILD_BUG_ON(ARRAY_SIZE(slpc_params_desc) != SLPC_MAX_PARAM);
+
+	drm_printf(p, "Param id\tParam description\n");
+	for (i = 0; i < ARRAY_SIZE(slpc_params_desc); i++)
+		drm_printf(p, "%8d\t%s\n", i, slpc_params_desc[i]);
+}
+
+/**
+ * intel_guc_slpc_param_control() - read/write/revert parameter.
+ * @slpc: pointer to intel_guc_slpc.
+ * @params: number of parameters
+ * @op: operation (read, write, revert)
+ * @id: parameter id
+ * @value: parameter value
+ *
+ * This function will create object to be shared with GuC SLPC and
+ * initialize it with required initial parameter values for various
+ * SLPC knobs such as min frequency limit, enabling/disabling of SLPC
+ * tasks etc.
+ *
+ * Return: 0 on success, non-zero error code on failure.
+ */
+int intel_guc_slpc_param_control(struct intel_guc_slpc *slpc,
+				 u32 params, u32 op, u32 id, u32 value)
+{
+	int ret = 0;
+
+	GEM_BUG_ON(!slpc->vma);
+
+	lockdep_assert_held(&slpc->lock);
+
+	if (op == READ_OP) {
+		if (params != 1) {
+			ret = -EINVAL;
+			goto out;
+		}
+		slpc_get_param(slpc, id,
+			       &slpc->debug.param_override,
+			       &slpc->debug.param_value);
+		slpc->debug.param_id = id;
+	} else if ((op == WRITE_OP) || (op == REVERT_OP)) {
+		if ((id >= SLPC_PARAM_TASK_ENABLE_GTPERF) &&
+		    (id <= SLPC_PARAM_TASK_DISABLE_DCC)) {
+			DRM_DEBUG_DRIVER("Tasks are not controlled by "
+					 "this interface\n");
+			ret = -EINVAL;
+			goto out;
+		}
+
+		/*
+		 * After updating parameters, RESET event has to be sent to GuC
+		 * SLPC for ensuring parameters take effect.
+		 */
+		if (op == WRITE_OP) {
+			if (params != 2) {
+				ret = -EINVAL;
+				goto out;
+			}
+			slpc_set_param(slpc, id, value);
+		} else {
+			if (params != 1) {
+				ret = -EINVAL;
+				goto out;
+			}
+			slpc_unset_param(slpc, id);
+		}
+		host2guc_slpc_reset(slpc);
+	}
+
+out:
+
+	return ret;
+}
+
+/**
  * intel_guc_slpc_init() - Initialize the SLPC shared data structure.
  * @slpc: pointer to intel_guc_slpc.
  *
diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.h b/drivers/gpu/drm/i915/intel_guc_slpc.h
index 51189b3..693343e 100644
--- a/drivers/gpu/drm/i915/intel_guc_slpc.h
+++ b/drivers/gpu/drm/i915/intel_guc_slpc.h
@@ -8,6 +8,8 @@
 
 #include <intel_guc_slpc_fwif.h>
 
+struct drm_printer;
+
 struct intel_guc_slpc {
 	/* Protects access to vma and SLPC actions */
 	struct mutex lock;
@@ -16,12 +18,28 @@ struct intel_guc_slpc {
 	/* i915 cached SLPC frequency limits */
 	u32 min_unslice_freq;
 	u32 max_unslice_freq;
+
+	struct {
+		u32 param_id;
+		u32 param_value;
+		u32 param_override;
+	} debug;
+};
+
+enum {
+	READ_OP,
+	WRITE_OP,
+	REVERT_OP
 };
 
 int intel_guc_slpc_task_control(struct intel_guc_slpc *slpc, u64 val,
 				u32 enable_id, u32 disable_id);
 int intel_guc_slpc_task_status(struct intel_guc_slpc *slpc, u64 *val,
 			       u32 enable_id, u32 disable_id);
+void intel_guc_slpc_params_print(struct intel_guc_slpc *slpc,
+				 struct drm_printer *p);
+int intel_guc_slpc_param_control(struct intel_guc_slpc *slpc,
+				 u32 params, u32 op, u32 id, u32 value);
 
 int intel_guc_slpc_init(struct intel_guc_slpc *slpc);
 int intel_guc_slpc_enable(struct intel_guc_slpc *slpc);
diff --git a/drivers/gpu/drm/i915/intel_guc_slpc_fwif.h b/drivers/gpu/drm/i915/intel_guc_slpc_fwif.h
index 9400af4..65bbb03 100644
--- a/drivers/gpu/drm/i915/intel_guc_slpc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_slpc_fwif.h
@@ -71,6 +71,29 @@ enum slpc_param_id {
 	SLPC_KMD_MAX_PARAM = 32,
 };
 
+static const char * const slpc_params_desc[] = {
+	"Enable task GTPERF",
+	"Disable task GTPERF",
+	"Enable task BALANCER",
+	"Disable task BALANCER",
+	"Enable task DCC",
+	"Disable task DCC",
+	"Minimum GT frequency request for unslice",
+	"Maximum GT frequency request for unslice",
+	"Minimum GT frequency request for slice",
+	"Maximum GT frequency request for slice",
+	"If non-zero, will slow down frame-based apps to this frame-rate",
+	"Lock GT frequency request to RPe",
+	"Set to TRUE to enable slowing framerate",
+	"Prevent from changing the RC mode",
+	"Override fused value of unslice RP0",
+	"Override fused value of slice RP0",
+	"TRUE means enable Intelligent Bias Control",
+	"TRUE = enable eval mode when transitioning from idle to active.",
+	"FALSE = disable eval mode completely",
+	"Enable IBC when non-Gaming Mode is enabled"
+};
+
 enum slpc_global_state {
 	SLPC_GLOBAL_STATE_NOT_RUNNING = 0,
 	SLPC_GLOBAL_STATE_INITIALIZING = 1,
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2018-03-30  8:29 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-30  8:31 [PATCH v12 00/17] Add support for GuC-based SLPC Sagar Arun Kamble
2018-03-30  8:31 ` [PATCH v12 01/17] drm/i915/guc/slpc: Add SLPC control to enable_guc modparam Sagar Arun Kamble
2018-03-30 12:37   ` Michal Wajdeczko
2018-03-30 15:26     ` Sagar Arun Kamble
2018-03-30  8:31 ` [PATCH v12 02/17] drm/i915/guc/slpc: Disable host RPS Sagar Arun Kamble
2018-03-30  8:31 ` [PATCH v12 03/17] drm/i915/guc/slpc: Lay out SLPC init/enable/disable/fini helpers Sagar Arun Kamble
2018-05-10 20:16   ` Michal Wajdeczko
2018-03-30  8:31 ` [PATCH v12 04/17] drm/i915/guc/slpc: Enable SLPC in GuC load control params Sagar Arun Kamble
2018-03-30  8:31 ` [PATCH v12 05/17] drm/i915/guc/slpc: Add SLPC communication interfaces Sagar Arun Kamble
2018-03-30 13:37   ` Michal Wajdeczko
2018-03-30 15:57     ` Sagar Arun Kamble
2018-03-30  8:31 ` [PATCH v12 06/17] drm/i915/guc/slpc: Allocate/initialize/release SLPC shared data Sagar Arun Kamble
2018-05-10 20:51   ` Michal Wajdeczko
2018-03-30  8:31 ` [PATCH v12 07/17] drm/i915/guc/slpc: Send RESET event to restart/enable SLPC tasks Sagar Arun Kamble
2018-05-14 10:21   ` Michal Wajdeczko
2018-03-30  8:31 ` [PATCH v12 08/17] drm/i915/guc/slpc: Send SHUTDOWN event to stop " Sagar Arun Kamble
2018-05-14 10:29   ` Michal Wajdeczko
2018-03-30  8:31 ` [PATCH v12 09/17] drm/i915/guc/slpc: Reset SLPC on engine reset with flag TDR_OCCURRED Sagar Arun Kamble
2018-03-30  8:31 ` [PATCH v12 10/17] drm/i915/guc/slpc: Add parameter set/unset/get, task control/status functions Sagar Arun Kamble
2018-05-14 11:26   ` Michal Wajdeczko
2018-03-30  8:31 ` [PATCH v12 11/17] drm/i915/guc/slpc: Add support for sysfs min/max frequency control Sagar Arun Kamble
2018-03-30  8:31 ` [PATCH v12 12/17] drm/i915/guc/slpc: Add enable/disable controls for SLPC tasks Sagar Arun Kamble
2018-05-14 11:52   ` Michal Wajdeczko
2018-03-30  8:31 ` [PATCH v12 13/17] drm/i915/debugfs: Create generic string tokenize function and update CRC control parsing Sagar Arun Kamble
2018-03-30  8:31 ` Sagar Arun Kamble [this message]
2018-05-14 12:05   ` [PATCH v12 14/17] drm/i915/guc/slpc: Add debugfs support to read/write/revert the parameters Michal Wajdeczko
2018-03-30  8:32 ` [PATCH v12 15/17] drm/i915/guc/slpc: Add i915_guc_slpc_info to debugfs Sagar Arun Kamble
2018-03-30  8:32 ` [PATCH v12 16/17] drm/i915/guc/slpc: Add SLPC banner to RPS debugfs interfaces Sagar Arun Kamble
2018-05-14 12:15   ` Michal Wajdeczko
2018-03-30  8:32 ` [PATCH v12 17/17] HAX: drm/i915/guc: Enable GuC Sagar Arun Kamble
2018-03-30  8:43 ` ✗ Fi.CI.CHECKPATCH: warning for Add support for GuC-based SLPC (rev12) Patchwork
2018-03-30  8:48 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-03-30  9:00 ` ✗ Fi.CI.BAT: failure " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1522398722-12161-15-git-send-email-sagar.a.kamble@intel.com \
    --to=sagar.a.kamble@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=sujaritha.sundaresan@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.