From: Tom O'Rourke <Tom.O'Rourke@xxxxxxxxx> 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) Signed-off-by: Tom O'Rourke <Tom.O'Rourke@xxxxxxxxx> Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@xxxxxxxxx> --- 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 5f37bbc..9120571 100644 --- a/drivers/gpu/drm/i915/intel_slpc.c +++ b/drivers/gpu/drm/i915/intel_slpc.c @@ -112,6 +112,110 @@ static void host2guc_slpc(struct drm_i915_private *dev_priv, DRM_ERROR("event 0x%x status %d\n", (data[1] >> 8), ret); } +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); +} + +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 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); +} + +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 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; +} + +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 a777b57..c83b737 100644 --- a/drivers/gpu/drm/i915/intel_slpc.h +++ b/drivers/gpu/drm/i915/intel_slpc.h @@ -194,6 +194,30 @@ 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_init(struct drm_i915_private *dev_priv); void intel_slpc_cleanup(struct drm_i915_private *dev_priv); @@ -204,5 +228,9 @@ 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_unset_param(struct drm_i915_private *dev_priv, u32 id); +void intel_slpc_set_param(struct drm_i915_private *dev_priv, u32 id, u32 value); +void intel_slpc_get_param(struct drm_i915_private *dev_priv, u32 id, + int *overriding, u32 *value); #endif -- 1.9.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx