From patchwork Thu Jan 21 02:26:10 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: tom.orourke@intel.com X-Patchwork-Id: 8076871 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 4CB1C9F9A0 for ; Thu, 21 Jan 2016 02:27:35 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 002A7205E7 for ; Thu, 21 Jan 2016 02:27:32 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id CB566205EA for ; Thu, 21 Jan 2016 02:27:30 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A22BB6E1DF; Wed, 20 Jan 2016 18:27:29 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id A3C136E1DA for ; Wed, 20 Jan 2016 18:27:19 -0800 (PST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga101.jf.intel.com with ESMTP; 20 Jan 2016 18:27:19 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,323,1449561600"; d="scan'208";a="897780434" Received: from torourke-desk.ra.intel.com (HELO localhost.localdomain) ([10.10.35.157]) by fmsmga002.fm.intel.com with ESMTP; 20 Jan 2016 18:27:19 -0800 From: tom.orourke@intel.com To: intel-gfx@lists.freedesktop.org Date: Wed, 20 Jan 2016 18:26:10 -0800 Message-Id: <1453343184-160456-9-git-send-email-tom.orourke@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1453343184-160456-1-git-send-email-tom.orourke@intel.com> References: <1453343184-160456-1-git-send-email-tom.orourke@intel.com> Cc: Tom O'Rourke Subject: [Intel-gfx] [RFC 08/22] drm/i915/slpc: Allocate/Release/Initialize SLPC shared data X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Tom O'Rourke SLPC shared data is used to pass information to/from SLPC 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. Signed-off-by: Tom O'Rourke --- drivers/gpu/drm/i915/intel_guc.h | 3 ++ drivers/gpu/drm/i915/intel_slpc.c | 93 ++++++++++++++++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_slpc.h | 69 +++++++++++++++++++++++++++++ 3 files changed, 163 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index e5de759..23cbcc1 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h @@ -26,6 +26,7 @@ #include "intel_guc_fwif.h" #include "i915_guc_reg.h" +#include "intel_slpc.h" struct i915_guc_client { struct drm_i915_gem_object *client_obj; @@ -108,6 +109,8 @@ struct intel_guc { uint64_t submissions[I915_NUM_RINGS]; uint32_t last_seqno[I915_NUM_RINGS]; + + struct intel_slpc slpc; }; /* intel_guc_loader.c */ diff --git a/drivers/gpu/drm/i915/intel_slpc.c b/drivers/gpu/drm/i915/intel_slpc.c index dcd237f..c298a6c 100644 --- a/drivers/gpu/drm/i915/intel_slpc.c +++ b/drivers/gpu/drm/i915/intel_slpc.c @@ -22,21 +22,110 @@ * */ #include +#include #include "i915_drv.h" #include "intel_guc.h" +static u8 slpc_get_platform_sku(struct drm_i915_gem_object *obj) +{ + struct drm_device *dev = obj->base.dev; + enum slpc_platform_sku platform_sku; + + if (IS_SKL_ULX(dev)) + platform_sku = SLPC_PLATFORM_SKU_ULX; + else if (IS_SKL_ULT(dev)) + platform_sku = SLPC_PLATFORM_SKU_ULT; + else + platform_sku = SLPC_PLATFORM_SKU_DT; + + return (u8) platform_sku; +} + +static u8 slpc_get_slice_count(struct drm_i915_gem_object *obj) +{ + struct drm_device *dev = obj->base.dev; + u8 slice_count = 1; + + if (IS_SKYLAKE(dev)) + slice_count = INTEL_INFO(dev)->slice_total; + + return slice_count; +} + +static int slpc_shared_data_init(struct drm_i915_gem_object *obj) +{ + struct page *page; + struct slpc_shared_data *data; + u64 msr_value; + int ret = 0; + + page = i915_gem_object_get_page(obj, 0); + if (page) { + data = kmap_atomic(page); + memset(data, 0, sizeof(struct slpc_shared_data)); + + data->slpc_version = SLPC_VERSION; + data->shared_data_size = sizeof(struct slpc_shared_data); + data->global_state = (u32) SLPC_GLOBAL_STATE_NOT_RUNNING; + data->platform_info.platform_sku = slpc_get_platform_sku(obj); + data->platform_info.slice_count = slpc_get_slice_count(obj); + 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); + rdmsrl(MSR_PKG_POWER_LIMIT, msr_value); + data->platform_info.package_rapl_limit_high = + (u32) (msr_value >> 32); + data->platform_info.package_rapl_limit_low = (u32) msr_value; + + kunmap_atomic(data); + } + + return ret; +} + int intel_slpc_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_gem_object *obj; + int ret = 0; - return 0; + /* Allocate shared data structure */ + obj = dev_priv->guc.slpc.shared_data_obj; + if (!obj) { + obj = gem_allocate_guc_obj(dev_priv->dev, + PAGE_ALIGN(sizeof(struct slpc_shared_data))); + dev_priv->guc.slpc.shared_data_obj = obj; + } + + if (!obj) { + ret = -ENOMEM; + } else { + ret = slpc_shared_data_init(obj); + } + + return ret; } int intel_slpc_cleanup(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_gem_object *obj; + int ret = 0; - return 0; + /* Release shared data sturcutre */ + obj = dev_priv->guc.slpc.shared_data_obj; + if (obj) { + gem_release_guc_obj(obj); + dev_priv->guc.slpc.shared_data_obj = NULL; + } + + return ret; } int intel_slpc_suspend(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_slpc.h b/drivers/gpu/drm/i915/intel_slpc.h index 8f13fb5..dceef7e 100644 --- a/drivers/gpu/drm/i915/intel_slpc.h +++ b/drivers/gpu/drm/i915/intel_slpc.h @@ -24,6 +24,75 @@ #ifndef _INTEL_SLPC_H_ #define _INTEL_SLPC_H_ +#define SLPC_MAJOR_VER 2 +#define SLPC_MINOR_VER 3 +#define SLPC_VERSION ((2015 << 16) | (SLPC_MAJOR_VER << 8) | (SLPC_MINOR_VER)) + +enum slpc_global_state { + SLPC_GLOBAL_STATE_NOT_RUNNING = 0, + SLPC_GLOBAL_STATE_INITIALIZING = 1, + SLPC_GLOBAL_STATE_RESETING = 2, + SLPC_GLOBAL_STATE_RUNNING = 3, + SLPC_GLOBAL_STATE_SHUTTING_DOWN = 4, + SLPC_GLOBAL_STATE_ERROR = 5 +}; + +enum slpc_platform_sku { + SLPC_PLATFORM_SKU_UNDEFINED = 0, + SLPC_PLATFORM_SKU_ULX = 1, + SLPC_PLATFORM_SKU_ULT = 2, + SLPC_PLATFORM_SKU_T = 3, + SLPC_PLATFORM_SKU_MOBL = 4, + SLPC_PLATFORM_SKU_DT = 5, + SLPC_PLATFORM_SKU_UNKNOWN = 6, +}; + +enum slpc_power_plan { + SLPC_POWER_PLAN_UNDEFINED = 0, + SLPC_POWER_PLAN_BATTERY_SAVER = 1, + SLPC_POWER_PLAN_BALANCED = 2, + SLPC_POWER_PLAN_PERFORMANCE = 3, + SLPC_POWER_PLAN_UNKNOWN = 4, +}; + +enum slpc_power_source { + SLPC_POWER_SOURCE_UNDEFINED = 0, + SLPC_POWER_SOURCE_AC = 1, + SLPC_POWER_SOURCE_DC = 2, + SLPC_POWER_SOURCE_UNKNOWN = 3, +}; + +#define SLPC_POWER_PLAN_SOURCE(plan, source) ((plan) | ((source) << 6)) + +struct slpc_platform_info { + u8 platform_sku; + u16 slice_count; + u8 power_plan_source; + u8 P0_freq; + u8 P1_freq; + u8 Pe_freq; + u8 Pn_freq; + u32 package_rapl_limit_high; + u32 package_rapl_limit_low; +} __packed; + +#define SLPC_MAX_OVERRIDE_PARAMETERS 128 +#define SLPC_OVERRIDE_BITFIELD_SIZE ((SLPC_MAX_OVERRIDE_PARAMETERS + 31) / 32) + +struct slpc_shared_data { + u32 slpc_version; + u32 shared_data_size; + u32 global_state; + struct slpc_platform_info platform_info; + u32 task_state_data; + u32 override_parameters_set_bits[SLPC_OVERRIDE_BITFIELD_SIZE]; + u32 override_parameters_values[SLPC_MAX_OVERRIDE_PARAMETERS]; +} __packed; + +struct intel_slpc { + struct drm_i915_gem_object *shared_data_obj; +}; + /* intel_slpc.c */ int intel_slpc_init(struct drm_device *dev); int intel_slpc_cleanup(struct drm_device *dev);