[PATCH 14/24] drm/i915/slpc: Add parameter set/unset/get functions

Sagar Arun Kamble sagar.a.kamble at intel.com
Wed Mar 8 09:42:54 UTC 2017


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 add parameter values and
events for setting/unsetting parameters.

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.

v7: Added definition of SLPC_KMD_MAX_PARAM. Explicit SLPC reset
    is needed on setting/unsetting some of the parameters.

Signed-off-by: Tom O'Rourke <Tom.O'Rourke at intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble at intel.com>
---
 drivers/gpu/drm/i915/intel_slpc.c | 106 ++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_slpc.h |  29 +++++++++++
 2 files changed, 135 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_slpc.c b/drivers/gpu/drm/i915/intel_slpc.c
index 10d9af2..f29e9b4 100644
--- a/drivers/gpu/drm/i915/intel_slpc.c
+++ b/drivers/gpu/drm/i915/intel_slpc.c
@@ -52,6 +52,23 @@ static unsigned int slpc_get_slice_count(struct drm_i915_private *dev_priv)
 	return slice_count;
 }
 
+void slpc_mem_set_param(struct slpc_shared_data *data,
+			      u32 id,
+			      u32 value)
+{
+	data->override_parameters_set_bits[id >> 5]
+						|= (1 << (id % 32));
+	data->override_parameters_values[id] = value;
+}
+
+void slpc_mem_unset_param(struct slpc_shared_data *data,
+				u32 id)
+{
+	data->override_parameters_set_bits[id >> 5]
+						&= (~(1 << (id % 32)));
+	data->override_parameters_values[id] = 0;
+}
+
 static void slpc_shared_data_init(struct drm_i915_private *dev_priv)
 {
 	struct page *page;
@@ -144,6 +161,29 @@ static void host2guc_slpc_shutdown(struct drm_i915_private *dev_priv)
 	host2guc_slpc(dev_priv, &data, 4);
 }
 
+static void host2guc_slpc_set_param(struct drm_i915_private *dev_priv,
+				    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;
+
+	host2guc_slpc(dev_priv, &data, 4);
+}
+
+static void host2guc_slpc_unset_param(struct drm_i915_private *dev_priv,
+				      u32 id)
+{
+	struct slpc_event_input data = {0};
+
+	data.header.value = SLPC_EVENT(SLPC_EVENT_PARAMETER_UNSET, 1);
+	data.args[0] = id;
+
+	host2guc_slpc(dev_priv, &data, 3);
+}
+
 void intel_slpc_query_task_state(struct drm_i915_private *dev_priv)
 {
 	if (dev_priv->guc.slpc.active)
@@ -221,6 +261,72 @@ bool intel_slpc_get_status(struct drm_i915_private *dev_priv)
 	return ret;
 }
 
+void intel_slpc_set_param(struct drm_i915_private *dev_priv,
+			  u32 id,
+			  u32 value)
+{
+	struct page *page;
+	struct slpc_shared_data *data = NULL;
+
+	WARN_ON(id >= SLPC_MAX_PARAM);
+
+	if (!dev_priv->guc.slpc.vma)
+		return;
+
+	page = i915_vma_first_page(dev_priv->guc.slpc.vma);
+	data = kmap_atomic(page);
+	slpc_mem_set_param(data, id, value);
+	kunmap_atomic(data);
+
+	host2guc_slpc_set_param(dev_priv, id, value);
+	host2guc_slpc_reset(dev_priv);
+}
+
+void intel_slpc_unset_param(struct drm_i915_private *dev_priv,
+			    u32 id)
+{
+	struct page *page;
+	struct slpc_shared_data *data = NULL;
+
+	WARN_ON(id >= SLPC_MAX_PARAM);
+
+	if (!dev_priv->guc.slpc.vma)
+		return;
+
+	page = i915_vma_first_page(dev_priv->guc.slpc.vma);
+	data = kmap_atomic(page);
+	slpc_mem_unset_param(data, id);
+	kunmap_atomic(data);
+
+	host2guc_slpc_unset_param(dev_priv, id);
+	host2guc_slpc_reset(dev_priv);
+}
+
+void intel_slpc_get_param(struct drm_i915_private *dev_priv,
+			  u32 id,
+			  int *overriding, u32 *value)
+{
+	struct page *page;
+	struct slpc_shared_data *data = NULL;
+	u32 bits;
+
+	WARN_ON(id >= SLPC_MAX_PARAM);
+
+	if (!dev_priv->guc.slpc.vma)
+		return;
+
+	page = i915_vma_first_page(dev_priv->guc.slpc.vma);
+	data = kmap_atomic(page);
+	if (overriding) {
+		bits = data->override_parameters_set_bits[id >> 5];
+		*overriding = (0 != (bits & (1 << (id % 32))));
+	}
+	if (value)
+		*value = data->override_parameters_values[id];
+
+	kunmap_atomic(data);
+}
+
 void intel_slpc_init(struct drm_i915_private *dev_priv)
 {
 	struct intel_guc *guc = &dev_priv->guc;
diff --git a/drivers/gpu/drm/i915/intel_slpc.h b/drivers/gpu/drm/i915/intel_slpc.h
index 567b9a3..360f3f2 100644
--- a/drivers/gpu/drm/i915/intel_slpc.h
+++ b/drivers/gpu/drm/i915/intel_slpc.h
@@ -194,11 +194,40 @@ enum slpc_status {
 	SLPC_STATUS_NO_LOCK = 22,
 };
 
+enum slpc_param_id {
+	SLPC_PARAM_TASK_ENABLE_GTPERF = 0,
+	SLPC_PARAM_TASK_DISABLE_GTPERF = 1,
+	SLPC_PARAM_TASK_ENABLE_BALANCER = 2,
+	SLPC_PARAM_TASK_DISABLE_BALANCER = 3,
+	SLPC_PARAM_TASK_ENABLE_DCC = 4,
+	SLPC_PARAM_TASK_DISABLE_DCC = 5,
+	SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ = 6,
+	SLPC_PARAM_GLOBAL_MAX_GT_UNSLICE_FREQ_MHZ = 7,
+	SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ = 8,
+	SLPC_PARAM_GLOBAL_MAX_GT_SLICE_FREQ_MHZ = 9,
+	SLPC_PARAM_GTPERF_THRESHOLD_MAX_FPS = 10,
+	SLPC_PARAM_GLOBAL_DISABLE_GT_FREQ_MANAGEMENT = 11,
+	SLPC_PARAM_GTPERF_ENABLE_FRAMERATE_STALLING = 12,
+	SLPC_PARAM_GLOBAL_DISABLE_RC6_MODE_CHANGE = 13,
+	SLPC_PARAM_GLOBAL_OC_UNSLICE_FREQ_MHZ = 14,
+	SLPC_PARAM_GLOBAL_OC_SLICE_FREQ_MHZ = 15,
+	SLPC_PARAM_GLOBAL_ENABLE_IA_GT_BALANCING = 16,
+	SLPC_PARAM_GLOBAL_ENABLE_ADAPTIVE_BURST_TURBO = 17,
+	SLPC_PARAM_GLOBAL_ENABLE_EVAL_MODE = 18,
+	SLPC_PARAM_GLOBAL_ENABLE_BALANCER_IN_NON_GAMING_MODE = 19,
+	SLPC_MAX_PARAM,
+	SLPC_KMD_MAX_PARAM = 32,
+};
+
 /* intel_slpc.c */
 void intel_slpc_read_shared_data(struct drm_i915_private *dev_priv,
 				struct slpc_shared_data *data);
 const char *intel_slpc_get_state_str(enum slpc_global_state state);
 bool intel_slpc_get_status(struct drm_i915_private *dev_priv);
+void intel_slpc_set_param(struct drm_i915_private *dev_priv, u32 id, u32 value);
+void intel_slpc_unset_param(struct drm_i915_private *dev_priv, u32 id);
+void intel_slpc_get_param(struct drm_i915_private *dev_priv, u32 id,
+			  int *overriding, u32 *value);
 void intel_slpc_init(struct drm_i915_private *dev_priv);
 void intel_slpc_cleanup(struct drm_i915_private *dev_priv);
 void intel_slpc_enable(struct drm_i915_private *dev_priv);
-- 
1.9.1



More information about the Intel-gfx-trybot mailing list