From patchwork Thu Nov 12 00:41:00 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wayne Boyer X-Patchwork-Id: 7598811 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 706D6BF90C for ; Thu, 12 Nov 2015 00:41:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7E158207D8 for ; Thu, 12 Nov 2015 00:41:18 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 78863207D7 for ; Thu, 12 Nov 2015 00:41:17 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 428536E368; Wed, 11 Nov 2015 16:41:16 -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 78DF96E368 for ; Wed, 11 Nov 2015 16:41:15 -0800 (PST) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga101.jf.intel.com with ESMTP; 11 Nov 2015 16:41:15 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,279,1444719600"; d="scan'208";a="683362484" Received: from wboyerdev.jf.intel.com ([10.7.197.85]) by orsmga003.jf.intel.com with ESMTP; 11 Nov 2015 16:41:15 -0800 From: Wayne Boyer To: intel-gfx@lists.freedesktop.org Date: Wed, 11 Nov 2015 16:41:00 -0800 Message-Id: <1447288860-2498-1-git-send-email-wayne.boyer@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1447268743-2328-6-git-send-email-rodrigo.vivi@intel.com> References: <1447268743-2328-6-git-send-email-rodrigo.vivi@intel.com> Subject: [Intel-gfx] [PATCH] drm/i915/skl: Implement DP Aux Mutex framework 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.5 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: "Boyer, Wayne" Beginning with SKL the DP Aux channel communication can be protected using a built in HW mutex. When PSR is enabled the HW takes control on AUX and uses it to control panel exit/entry states. When validating PSR with automated tests, grabbing CRC from sink revealed strange aux communication issues. Aux reads were returning a message read size equal to 0 and 0 is a forbidden message. By using the HW mutex the HW is blocked from using aux when running the automated PSR tests. This patch provides an initial implementation for using that mutex. The use is currently limited to protecting the sink crc request based on feedback from the H/W designers indicating that using the mutex for all aux channel communication is not recommended. v2: Improved commit message to explain the case where the HW mutex is helpful. Also added bug reference. v3: Fix typos in commit message. Signed-off-by: Wayne Boyer Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91437 Reviewed-by: Rodrigo Vivi Tested-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_reg.h | 5 ++++ drivers/gpu/drm/i915/intel_dp.c | 52 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d5cf30b..ac7ed0d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2585,6 +2585,7 @@ struct drm_i915_cmd_table { #define HAS_DDI(dev) (INTEL_INFO(dev)->has_ddi) #define HAS_FPGA_DBG_UNCLAIMED(dev) (INTEL_INFO(dev)->has_fpga_dbg) +#define HAS_AUX_MUTEX(dev) (INTEL_INFO(dev)->gen >= 9) #define HAS_PSR(dev) (IS_HASWELL(dev) || IS_BROADWELL(dev) || \ IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev) || \ IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 8bd2699..f9ee874 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4288,6 +4288,11 @@ enum skl_disp_power_wells { #define DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(c) (((c) - 1) << 5) #define DP_AUX_CH_CTL_SYNC_PULSE_SKL(c) ((c) - 1) +#define DP_AUX_MUTEX_A 0x6402C +#define DP_AUX_MUTEX_B 0x6412C +#define DP_AUX_MUTEX_ENABLE (1 << 31) +#define DP_AUX_MUTEX_STATUS (1 << 30) + /* * Computing GMCH M and N values for the Display Port link * diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index da02ed7..b3c7d82 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -781,6 +781,47 @@ static uint32_t skl_get_aux_send_ctl(struct intel_dp *intel_dp, DP_AUX_CH_CTL_SYNC_PULSE_SKL(32); } +static bool skl_aux_mutex(struct intel_dp *intel_dp, bool get) +{ + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t aux_ch_mutex, status; + int count = 0; + + if (!HAS_AUX_MUTEX(dev)) + return false; + + /* + * FIXME: determine actual aux channel + * Hard coded to channel A for now to protect sink crc requests on eDP. + */ + aux_ch_mutex = DP_AUX_MUTEX_A; + + if (!get) { + I915_WRITE(aux_ch_mutex, DP_AUX_MUTEX_ENABLE | DP_AUX_MUTEX_STATUS); + return false; + } + + /* + * The Bspec specifies waiting 500us between attempts to acquire the + * mutex. Ten retries should be adequate to balance successfully + * acquirng the mutex and spending too much time trying. + */ + while (count++ < 10) { + I915_WRITE(aux_ch_mutex, DP_AUX_MUTEX_ENABLE); + status = I915_READ(aux_ch_mutex); + if (!(status & DP_AUX_MUTEX_STATUS)) + return true; + udelay(500); + } + + return false; +} + +#define skl_aux_mutex_get(dev) skl_aux_mutex(dev, true) +#define skl_aux_mutex_put(dev) skl_aux_mutex(dev, false) + static int intel_dp_aux_ch(struct intel_dp *intel_dp, const uint8_t *send, int send_bytes, @@ -3927,10 +3968,14 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) u8 buf; int count, ret; int attempts = 6; + bool aux_mutex_acquired = false; + + aux_mutex_acquired = skl_aux_mutex_get(intel_dp); ret = intel_dp_sink_crc_start(intel_dp); + if (ret) - return ret; + goto release; do { intel_wait_for_vblank(dev, intel_crtc->pipe); @@ -3957,6 +4002,11 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) stop: intel_dp_sink_crc_stop(intel_dp); + +release: + if (aux_mutex_acquired) + aux_mutex_acquired = skl_aux_mutex_put(intel_dp); + return ret; }