[Intel-gfx] [PATCH v4 10/26] drm/i915/slpc: Allocate/Release/Initialize SLPC shared data
Chris Wilson
chris at chris-wilson.co.uk
Fri Sep 9 17:08:46 UTC 2016
On Fri, Sep 09, 2016 at 06:21:29PM +0530, Sagar Arun Kamble wrote:
> From: Tom O'Rourke <Tom.O'Rourke at intel.com>
>
> SLPC shared data is used to pass information
> to/from SLPC in GuC firmware.
>
> For Skylake, platform sku type and slice count
> are identified from device id and fuse values.
>
> Support for other platforms needs to be added.
>
> 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).
>
> Reviewed-by: David Weinehall <david.weinehall at linux.intel.com>
> 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 | 7 ++-
> drivers/gpu/drm/i915/intel_guc.h | 2 +
> drivers/gpu/drm/i915/intel_pm.c | 6 ++-
> drivers/gpu/drm/i915/intel_slpc.c | 88 ++++++++++++++++++++++++++++++++++
> drivers/gpu/drm/i915/intel_slpc.h | 99 +++++++++++++++++++++++++++++++++++++++
> 5 files changed, 199 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index cf9aa24..796c52f 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1707,7 +1707,12 @@ bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy,
>
I am going to need an idiot's guide here as to the difference between
enabled() and active().
> static inline int intel_slpc_active(struct drm_i915_private *dev_priv)
bool.
> {
> - return 0;
> + int ret = 0;
> +
> + if (dev_priv->guc.slpc.vma && dev_priv->guc.slpc.enabled)
> + ret = 1;
> +
> + return ret;
> }
>
> /* intel_pm.c */
> diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
> index 83dec66..6e24e60 100644
> --- a/drivers/gpu/drm/i915/intel_guc.h
> +++ b/drivers/gpu/drm/i915/intel_guc.h
> @@ -145,6 +145,8 @@ struct intel_guc {
>
> uint64_t submissions[I915_NUM_ENGINES];
> uint32_t last_seqno[I915_NUM_ENGINES];
> +
> + struct intel_slpc slpc;
> };
>
> static inline int intel_slpc_enabled(void)
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index d187066..2211f7b 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -6656,7 +6656,8 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
>
> void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv)
> {
> - if (intel_slpc_enabled())
> + if (intel_slpc_enabled() &&
> + dev_priv->guc.slpc.vma)
> intel_slpc_cleanup(dev_priv);
> else if (IS_VALLEYVIEW(dev_priv))
> valleyview_cleanup_gt_powersave(dev_priv);
> @@ -6746,7 +6747,8 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
>
> mutex_lock(&dev_priv->rps.hw_lock);
>
> - if (intel_slpc_enabled()) {
> + if (intel_slpc_enabled() &&
> + dev_priv->guc.slpc.vma) {
> gen9_enable_rc6(dev_priv);
> intel_slpc_enable(dev_priv);
> if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
> diff --git a/drivers/gpu/drm/i915/intel_slpc.c b/drivers/gpu/drm/i915/intel_slpc.c
> index be9e84c..972db18 100644
> --- a/drivers/gpu/drm/i915/intel_slpc.c
> +++ b/drivers/gpu/drm/i915/intel_slpc.c
> @@ -22,15 +22,103 @@
> *
> */
> #include <linux/firmware.h>
> +#include <asm/msr-index.h>
> #include "i915_drv.h"
> #include "intel_guc.h"
>
> +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 drm_i915_gem_object *obj;
> + struct page *page;
> + struct slpc_shared_data *data;
> + u64 msr_value;
> +
> + if (!dev_priv->guc.slpc.vma)
> + return;
> +
> + obj = dev_priv->guc.slpc.vma->obj;
> +
> + page = i915_gem_object_get_page(obj, 0);
page = i915_vma_first_pgae(dev_priv->guc.slpc.vma);
and cannot be NULL (by construction in guc_allocate_vma).
> + if (page) {
> + data = kmap_atomic(page);
> + memset(data, 0, sizeof(struct slpc_shared_data));
> +
> + data->shared_data_size = sizeof(struct slpc_shared_data);
> + data->global_state = (u32)SLPC_GLOBAL_STATE_NOT_RUNNING;
> + data->platform_info.platform_sku =
> + (u8)slpc_get_platform_sku(dev_priv);
> + data->platform_info.slice_count =
> + (u8)slpc_get_slice_count(dev_priv);
> + data->platform_info.power_plan_source =
> + (u8)SLPC_POWER_PLAN_SOURCE(SLPC_POWER_PLAN_BALANCED,
> + SLPC_POWER_SOURCE_AC);
> + rdmsrl(MSR_TURBO_RATIO_LIMIT, msr_value);
> + data->platform_info.P0_freq = (u8)msr_value;
> + rdmsrl(MSR_PLATFORM_INFO, msr_value);
> + data->platform_info.P1_freq = (u8)(msr_value >> 8);
> + data->platform_info.Pe_freq = (u8)(msr_value >> 40);
> + data->platform_info.Pn_freq = (u8)(msr_value >> 48);
The u8 et al are implied anyway, are they not?
> +
> + kunmap_atomic(data);
> + }
> +}
> +
> void intel_slpc_init(struct drm_i915_private *dev_priv)
> {
> + struct intel_guc *guc = &dev_priv->guc;
> + struct i915_vma *vma;
> +
> + /* Allocate shared data structure */
> + vma = dev_priv->guc.slpc.vma;
> + if (!vma) {
There's always something fishy about init routines called multiple
times.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
More information about the Intel-gfx
mailing list