[Intel-gfx] [PATCH v7 10/21] drm/i915/slpc: Allocate/Release/Initialize SLPC shared data

Sagar Arun Kamble sagar.a.kamble at intel.com
Wed Mar 22 10:03:43 UTC 2017


Populate SLPC shared data with required default values for
Slice count, Power source/plan, IA Perf MSRs.

v1: Update for SLPC interface version 2015.2.4
    intel_slpc_active() returns 1 if slpc initialized (Paulo)
    change default host_os to "Windows"
    Spelling fixes (Sagar Kamble and Nick Hoath)
    Added WARN for checking if upper 32bits of GTT offset
    of shared object are zero. (ChrisW)
    Changed function call from gem_allocate/release_guc_obj to
    i915_guc_allocate/release_gem_obj. (Sagar)
    Updated commit message and moved POWER_PLAN and POWER_SOURCE
    definition from later patch. (Akash)
    Add struct_mutex locking while allocating/releasing slpc shared
    object. This was caught by CI BAT. Adding SLPC state variable
    to determine if it is active as it not just dependent on shared
    data setup.
    Rebase with guc_allocate_vma related changes.

v2: WARN_ON for platform_sku validity and space changes.(David)
    Checkpatch update.

v3: Fixing WARNING in igt at drv_module_reload_basic found in trybot BAT
    with SLPC Enabled.

v4: Updated support for GuC v9. s/slice_total/hweight8(slice_mask)/(Dave).

v5: SLPC vma mapping changes and removed explicit type conversions.(Chris).
    s/freq_unslice_max|min/unslice__max|min_freq.

v6: Commit message update. s/msr_value/val for reuse later.

v7: Set default values for tasks and min frequency parameters.
    Moved initialization with allocation of data so that post GuC load
    earlier parameters persist.

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_drv.h  |   1 +
 drivers/gpu/drm/i915/intel_pm.c   |   2 +-
 drivers/gpu/drm/i915/intel_slpc.c | 126 ++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_slpc.h |   1 +
 4 files changed, 129 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 51228fe..f2fc0fe 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1816,6 +1816,7 @@ bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy,
 void gen6_rps_boost(struct drm_i915_private *dev_priv,
 		    struct intel_rps_client *rps,
 		    unsigned long submitted);
+void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv);
 void intel_queue_rps_boost_for_request(struct drm_i915_gem_request *req);
 void vlv_wm_get_hw_state(struct drm_device *dev);
 void ilk_wm_get_hw_state(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 76d98bd..798656b 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5555,7 +5555,7 @@ int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6)
 	return INTEL_RC6_ENABLE;
 }
 
-static void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv)
+void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv)
 {
 	/* All of these values are in units of 50MHz */
 
diff --git a/drivers/gpu/drm/i915/intel_slpc.c b/drivers/gpu/drm/i915/intel_slpc.c
index c893db0..5df8793 100644
--- a/drivers/gpu/drm/i915/intel_slpc.c
+++ b/drivers/gpu/drm/i915/intel_slpc.c
@@ -22,6 +22,7 @@
  *
  */
 #include <linux/firmware.h>
+#include <asm/msr-index.h>
 #include "i915_drv.h"
 #include "intel_uc.h"
 
@@ -288,12 +289,137 @@ int intel_slpc_task_status(struct drm_i915_private *dev_priv, u64 *val,
 	return ret;
 }
 
+static unsigned int slpc_get_platform_sku(struct drm_i915_private *dev_priv)
+{
+	enum slpc_platform_sku platform_sku;
+
+	if (IS_SKL_ULX(dev_priv))
+		platform_sku = SLPC_PLATFORM_SKU_ULX;
+	else if (IS_SKL_ULT(dev_priv))
+		platform_sku = SLPC_PLATFORM_SKU_ULT;
+	else
+		platform_sku = SLPC_PLATFORM_SKU_DT;
+
+	WARN_ON(platform_sku > 0xFF);
+
+	return platform_sku;
+}
+
+static unsigned int slpc_get_slice_count(struct drm_i915_private *dev_priv)
+{
+	unsigned int slice_count = 1;
+
+	if (IS_SKYLAKE(dev_priv))
+		slice_count = hweight8(INTEL_INFO(dev_priv)->sseu.slice_mask);
+
+	return slice_count;
+}
+
+static void slpc_shared_data_init(struct drm_i915_private *dev_priv)
+{
+	struct page *page;
+	struct slpc_shared_data *data;
+	u64 val;
+
+	page = i915_vma_first_page(dev_priv->guc.slpc.vma);
+	data = kmap_atomic(page);
+
+	memset(data, 0, sizeof(struct slpc_shared_data));
+
+	data->shared_data_size = sizeof(struct slpc_shared_data);
+	data->global_state = SLPC_GLOBAL_STATE_NOT_RUNNING;
+	data->platform_info.platform_sku =
+				slpc_get_platform_sku(dev_priv);
+	data->platform_info.slice_count =
+				slpc_get_slice_count(dev_priv);
+	data->platform_info.power_plan_source =
+		SLPC_POWER_PLAN_SOURCE(SLPC_POWER_PLAN_BALANCED,
+					    SLPC_POWER_SOURCE_AC);
+	rdmsrl(MSR_TURBO_RATIO_LIMIT, val);
+	data->platform_info.P0_freq = val;
+	rdmsrl(MSR_PLATFORM_INFO, val);
+	data->platform_info.P1_freq = val >> 8;
+	data->platform_info.Pe_freq = val >> 40;
+	data->platform_info.Pn_freq = val >> 48;
+
+	/* Enable only GTPERF task, Disable others */
+	val = SLPC_PARAM_TASK_ENABLED;
+	slpc_mem_task_control(data, val,
+			      SLPC_PARAM_TASK_ENABLE_GTPERF,
+			      SLPC_PARAM_TASK_DISABLE_GTPERF);
+
+	val = SLPC_PARAM_TASK_DISABLED;
+	slpc_mem_task_control(data, val,
+			      SLPC_PARAM_TASK_ENABLE_BALANCER,
+			      SLPC_PARAM_TASK_DISABLE_BALANCER);
+
+	slpc_mem_task_control(data, val,
+			      SLPC_PARAM_TASK_ENABLE_DCC,
+			      SLPC_PARAM_TASK_DISABLE_DCC);
+
+	slpc_mem_set_param(data, SLPC_PARAM_GTPERF_THRESHOLD_MAX_FPS, 0);
+
+	slpc_mem_set_param(data, SLPC_PARAM_GTPERF_ENABLE_FRAMERATE_STALLING,
+			   0);
+
+	slpc_mem_set_param(data, SLPC_PARAM_GLOBAL_ENABLE_IA_GT_BALANCING,
+			   0);
+
+	slpc_mem_set_param(data,
+			   SLPC_PARAM_GLOBAL_ENABLE_ADAPTIVE_BURST_TURBO,
+			   0);
+
+	slpc_mem_set_param(data, SLPC_PARAM_GLOBAL_ENABLE_EVAL_MODE, 0);
+
+	slpc_mem_set_param(data,
+			   SLPC_PARAM_GLOBAL_ENABLE_BALANCER_IN_NON_GAMING_MODE,
+			   0);
+
+	slpc_mem_set_param(data,
+			   SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ,
+			   intel_gpu_freq(dev_priv,
+				dev_priv->rps.efficient_freq));
+	slpc_mem_set_param(data,
+			   SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ,
+			   intel_gpu_freq(dev_priv,
+				dev_priv->rps.efficient_freq));
+
+	kunmap_atomic(data);
+}
+
 void intel_slpc_init(struct drm_i915_private *dev_priv)
 {
+	struct intel_guc *guc = &dev_priv->guc;
+	struct i915_vma *vma;
+
+	dev_priv->guc.slpc.active = false;
+
+	mutex_lock(&dev_priv->rps.hw_lock);
+	gen6_init_rps_frequencies(dev_priv);
+	mutex_unlock(&dev_priv->rps.hw_lock);
+
+	/* Allocate shared data structure */
+	vma = dev_priv->guc.slpc.vma;
+	if (!vma) {
+		vma = intel_guc_allocate_vma(guc,
+			       PAGE_ALIGN(sizeof(struct slpc_shared_data)));
+		if (IS_ERR(vma)) {
+			DRM_ERROR("slpc_shared_data allocation failed\n");
+			i915.enable_slpc = 0;
+			return;
+		}
+
+		dev_priv->guc.slpc.vma = vma;
+		slpc_shared_data_init(dev_priv);
+	}
 }
 
 void intel_slpc_cleanup(struct drm_i915_private *dev_priv)
 {
+	struct intel_guc *guc = &dev_priv->guc;
+
+	/* Release shared data structure */
+	i915_vma_unpin_and_release(&guc->slpc.vma);
 }
 
 void intel_slpc_enable(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/intel_slpc.h b/drivers/gpu/drm/i915/intel_slpc.h
index 4e41a17..96e15a9 100644
--- a/drivers/gpu/drm/i915/intel_slpc.h
+++ b/drivers/gpu/drm/i915/intel_slpc.h
@@ -26,6 +26,7 @@
 
 struct intel_slpc {
 	bool active;
+	struct i915_vma *vma;
 };
 
 enum slpc_status {
-- 
1.9.1



More information about the Intel-gfx mailing list