[PATCH v12 10/17] drm/i915/guc/slpc: Add parameter set/unset/get, task control/status functions

Sagar Arun Kamble sagar.a.kamble at intel.com
Thu Mar 29 18:59:30 UTC 2018


SLPC behavior can be changed through set of parameters. These parameters
can be updated and queried from i915 though Host to GuC SLPC events. This
patch adds parameter update events for setting/unsetting/getting params.
Setting parameter leads to overridding of default parameter value. Unset
leads to restoring of default value by communicating with GuC SLPC through
parameter updates in the shared data.
i915 can only query/get parameters that it overrides, so getting parameter
value is done by only reading from the shared data.

SLPC has various tasks, GTPERF, BALANCER and DCC. These can be controlled
through pair of GuC SLPC parameters. Enable/disable of these tasks require
combined update to both parameters hence new actions are added to control
and query the status of tasks.

v1: Use host2guc_slpc. Update slcp_param_id enum values for SLPC 2015.2.4
    Return void instead of ignored error code (Paulo)

v2: Checkpatch update.

v3: Rebase.

v4: Updated with GuC firmware v9.

v5: Updated input structure to host2guc_slpc. Added functions to update
    only parameters in the SLPC shared memory. This will allow to setup
    shared data with all parameters and send single event to SLPC take
    them into effect. Commit message update. (Sagar)

v6: Rearranged helpers to use them in slpc_shared_data_init. Added defn.
    of SLPC_KMD_MAX_PARAM.

v7: Added definition of host2guc_slpc with rearrangement of patches. Added
    task control/status functions.

v8: Rebase w.r.t s/intel_guc_send/intel_guc_send_mmio.

v9: Created intel_guc_slpc_send_mmio with SLPC specific H2G action send
    function. Rebase. Defined slpc_statuslist and using the same in
    intel_guc_slpc_send_mmio. (Michal Wajdeczko)

v10: Rebase. Added kernel documentation to the task control functions.

Signed-off-by: Tom O'Rourke <Tom.O'Rourke at intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble at intel.com>
Cc: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
Cc: Radoslaw Szwichtenberg <radoslaw.szwichtenberg at intel.com>
Cc: Michal Wajdeczko <michal.wajdeczko at intel.com>
Cc: Sujaritha Sundaresan <sujaritha.sundaresan at intel.com>
Cc: Jeff McGee <jeff.mcgee at intel.com>
---
 drivers/gpu/drm/i915/intel_guc_slpc.c | 173 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_guc_slpc.h |   5 +
 2 files changed, 178 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.c b/drivers/gpu/drm/i915/intel_guc_slpc.c
index c465aac..8932659 100644
--- a/drivers/gpu/drm/i915/intel_guc_slpc.c
+++ b/drivers/gpu/drm/i915/intel_guc_slpc.c
@@ -323,6 +323,179 @@ static void host2guc_slpc_tdr_reset(struct intel_guc_slpc *slpc)
 	slpc_send(slpc, &data, 5);
 }
 
+static void host2guc_slpc_set_param(struct intel_guc_slpc *slpc,
+				    u32 id, u32 value)
+{
+	struct slpc_event_input data = {0};
+
+	data.header.value = SLPC_EVENT(SLPC_EVENT_PARAMETER_SET, 2);
+	data.args[0] = id;
+	data.args[1] = value;
+
+	slpc_send(slpc, &data, 4);
+}
+
+static void host2guc_slpc_unset_param(struct intel_guc_slpc *slpc,
+				      u32 id)
+{
+	struct slpc_event_input data = {0};
+
+	data.header.value = SLPC_EVENT(SLPC_EVENT_PARAMETER_UNSET, 1);
+	data.args[0] = id;
+
+	slpc_send(slpc, &data, 3);
+}
+
+static void slpc_set_param(struct intel_guc_slpc *slpc, u32 id, u32 value)
+{
+	struct slpc_shared_data *data = NULL;
+	struct page *page;
+
+	GEM_BUG_ON(id >= SLPC_MAX_PARAM);
+	GEM_BUG_ON(!slpc->vma);
+
+	lockdep_assert_held(&slpc->lock);
+
+	page = i915_vma_first_page(slpc->vma);
+	data = kmap_atomic(page);
+	slpc_mem_set_param(data, id, value);
+	kunmap_atomic(data);
+
+	host2guc_slpc_set_param(slpc, id, value);
+}
+
+static void slpc_unset_param(struct intel_guc_slpc *slpc, u32 id)
+{
+	struct slpc_shared_data *data = NULL;
+	struct page *page;
+
+	GEM_BUG_ON(id >= SLPC_MAX_PARAM);
+	GEM_BUG_ON(!slpc->vma);
+
+	lockdep_assert_held(&slpc->lock);
+
+	page = i915_vma_first_page(slpc->vma);
+	data = kmap_atomic(page);
+	slpc_mem_unset_param(data, id);
+	kunmap_atomic(data);
+
+	host2guc_slpc_unset_param(slpc, id);
+}
+
+static void slpc_get_param(struct intel_guc_slpc *slpc, u32 id,
+			   int *overriding, u32 *value)
+{
+	struct slpc_shared_data *data = NULL;
+	struct page *page;
+	u32 bits;
+
+	GEM_BUG_ON(id >= SLPC_MAX_PARAM);
+	GEM_BUG_ON(!slpc->vma);
+
+	lockdep_assert_held(&slpc->lock);
+
+	page = i915_vma_first_page(slpc->vma);
+	data = kmap_atomic(page);
+	if (overriding) {
+		bits = data->override_params_set_bits[id >> 5];
+		*overriding = (0 != (bits & (1 << (id % 32))));
+	}
+	if (value)
+		*value = data->override_params_values[id];
+
+	kunmap_atomic(data);
+}
+
+/**
+ * intel_guc_slpc_task_control() - Update status of SLPC task.
+ * @slpc: pointer to intel_guc_slpc.
+ *
+ * This function will update status of task in SLPC shared data.
+ * Then it invokes SLPC Host to GuC action to communicate the
+ * required task status.
+ *
+ * Return: 0 on success, non-zero error code on failure.
+ */
+int intel_guc_slpc_task_control(struct intel_guc_slpc *slpc, u64 val,
+				u32 enable_id, u32 disable_id)
+{
+	int ret = 0;
+
+	GEM_BUG_ON(!slpc->vma);
+
+	lockdep_assert_held(&slpc->lock);
+
+	if (val == SLPC_PARAM_TASK_DEFAULT) {
+		/* set default */
+		slpc_unset_param(slpc, enable_id);
+		slpc_unset_param(slpc, disable_id);
+	} else if (val == SLPC_PARAM_TASK_ENABLED) {
+		/* set enable */
+		slpc_set_param(slpc, enable_id, 1);
+		slpc_unset_param(slpc, disable_id);
+	} else if (val == SLPC_PARAM_TASK_DISABLED) {
+		/* set disable */
+		slpc_set_param(slpc, disable_id, 1);
+		slpc_unset_param(slpc, enable_id);
+	} else {
+		ret = -EINVAL;
+	}
+
+	host2guc_slpc_reset(slpc);
+
+	return ret;
+}
+
+/**
+ * intel_guc_slpc_task_status() - gets the status of SLPC task.
+ * @slpc: pointer to intel_guc_slpc.
+ *
+ * This function will read status of task from SLPC shared data.
+ * Task could be in either "enabled", "disabled", "default" or
+ * "unknown" state.
+ *
+ * Return: 0 on success, non-zero error code on failure.
+ */
+int intel_guc_slpc_task_status(struct intel_guc_slpc *slpc, u64 *val,
+			       u32 enable_id, u32 disable_id)
+{
+	int override_enable, override_disable;
+	u32 value_enable, value_disable;
+	int ret = 0;
+
+	GEM_BUG_ON(!slpc->vma);
+
+	lockdep_assert_held(&slpc->lock);
+
+	if (val) {
+		slpc_get_param(slpc, enable_id,
+			       &override_enable, &value_enable);
+		slpc_get_param(slpc, disable_id,
+			       &override_disable, &value_disable);
+
+		/*
+		 * Set the output value:
+		 * 0: default
+		 * 1: enabled
+		 * 2: disabled
+		 * 3: unknown (should not happen)
+		 */
+		if (override_disable && value_disable == 1)
+			*val = SLPC_PARAM_TASK_DISABLED;
+		else if (override_enable && value_enable == 1)
+			*val = SLPC_PARAM_TASK_ENABLED;
+		else if (!override_enable && !override_disable)
+			*val = SLPC_PARAM_TASK_DEFAULT;
+		else
+			*val = SLPC_PARAM_TASK_UNKNOWN;
+
+	} else {
+		ret = -EINVAL;
+	}
+
+	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 75f0b5d..87b504d 100644
--- a/drivers/gpu/drm/i915/intel_guc_slpc.h
+++ b/drivers/gpu/drm/i915/intel_guc_slpc.h
@@ -14,6 +14,11 @@ struct intel_guc_slpc {
 	struct i915_vma *vma;
 };
 
+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);
+
 int intel_guc_slpc_init(struct intel_guc_slpc *slpc);
 int intel_guc_slpc_enable(struct intel_guc_slpc *slpc);
 void intel_guc_slpc_handle_engine_reset(struct intel_guc_slpc *slpc);
-- 
2.7.4



More information about the Intel-gfx-trybot mailing list