[PATCH 19/29] drm/i915/slpc: Add parameter set/unset/get functions

Sagar Arun Kamble sagar.a.kamble at intel.com
Fri Mar 3 18:11:08 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.

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 | 104 ++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_slpc.h |  28 ++++++++++
 2 files changed, 132 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_slpc.c b/drivers/gpu/drm/i915/intel_slpc.c
index 496cb25..e061ecb 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;
@@ -148,6 +165,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)
@@ -225,6 +265,70 @@ 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);
+}
+
+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);
+}
+
+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..ff9b228 100644
--- a/drivers/gpu/drm/i915/intel_slpc.h
+++ b/drivers/gpu/drm/i915/intel_slpc.h
@@ -194,11 +194,39 @@ 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,
+};
+
 /* 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