From patchwork Tue Mar 24 20:14:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Souza, Jose" X-Patchwork-Id: 11456355 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CD75214B4 for ; Tue, 24 Mar 2020 20:13:17 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B780F208CA for ; Tue, 24 Mar 2020 20:13:17 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B780F208CA Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id CE1C06E22C; Tue, 24 Mar 2020 20:13:16 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by gabe.freedesktop.org (Postfix) with ESMTPS id AC02E6E52C for ; Tue, 24 Mar 2020 20:13:15 +0000 (UTC) IronPort-SDR: v+DNTuUP9gbA/NAcZCByRdSQCVsEowR8+PamQm4GZB26YK8T6nnTwUx0vhR4zScyRHwk39+zGO x41HsWbgNpMw== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Mar 2020 13:13:14 -0700 IronPort-SDR: g0o68J/UOx/khWufhiWZagAPiMZVn/Fvo1C86Fo9c4WMb4qEEyASEc+xiljm6ekyDtAwcyER9B eOpEjHzfTD3w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.72,301,1580803200"; d="scan'208";a="235700549" Received: from josouza-mobl2.jf.intel.com (HELO josouza-MOBL2.intel.com) ([10.24.15.8]) by orsmga007.jf.intel.com with ESMTP; 24 Mar 2020 13:13:14 -0700 From: =?utf-8?q?Jos=C3=A9_Roberto_de_Souza?= To: intel-gfx@lists.freedesktop.org Date: Tue, 24 Mar 2020 13:14:24 -0700 Message-Id: <20200324201429.29153-1-jose.souza@intel.com> X-Mailer: git-send-email 2.26.0 MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v3 1/6] drm/i915/tc/tgl: Implement TCCOLD sequences X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Cooper Chiou , Kai-Heng Feng Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" TC ports can enter in TCCOLD to save power and is required to request to PCODE to exit this state before use or read to TC registers. For TGL there is a new MBOX command to do that with a parameter to ask PCODE to exit and block TCCOLD entry or unblock TCCOLD entry. For GEN11 the sequence is more complex and will be handled in a separated patch. BSpec: 49294 Cc: Imre Deak Cc: Cooper Chiou Cc: Kai-Heng Feng Signed-off-by: José Roberto de Souza Tested-by: You-Sheng Yang --- drivers/gpu/drm/i915/display/intel_tc.c | 61 ++++++++++++++++++++++++- drivers/gpu/drm/i915/i915_reg.h | 3 ++ drivers/gpu/drm/i915/intel_sideband.c | 22 +++++++++ drivers/gpu/drm/i915/intel_sideband.h | 4 ++ 4 files changed, 88 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 9b850c11aa78..e4c5de5ce874 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -7,6 +7,7 @@ #include "intel_display.h" #include "intel_display_types.h" #include "intel_dp_mst.h" +#include "intel_sideband.h" #include "intel_tc.h" static const char *tc_port_mode_name(enum tc_port_mode mode) @@ -496,6 +497,55 @@ bool intel_tc_port_connected(struct intel_digital_port *dig_port) return is_connected; } +static inline int tgl_tc_cold_request(struct intel_digital_port *dig_port, + bool block) +{ + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + u32 low_val, high_val; + u8 tries = 0; + int ret; + + do { + low_val = 0; + high_val = block ? 0 : TGL_PCODE_EXIT_TCCOLD_DATA_H_UNBLOCK_REQ; + + ret = sandybridge_pcode_write_read_timeout(i915, + TGL_PCODE_TCCOLD, + &low_val, &high_val, + 150, 1); + if (ret == 0) { + if (block && + low_val & TGL_PCODE_EXIT_TCCOLD_DATA_L_EXIT_FAILED) + ret = -EIO; + else + break; + } + + if (ret != -EAGAIN) + tries++; + } while (tries < 3); + + return ret; +} + +static int tc_cold_request(struct intel_digital_port *dig_port, bool block) +{ + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + int ret; + + if (INTEL_GEN(i915) >= 12) + ret = tgl_tc_cold_request(dig_port, block); + else + /* TODO: implement GEN11 TCCOLD sequences */ + ret = 0; + + drm_dbg_kms(&i915->drm, "Port %s: TCCOLD %sblock %s\n", + dig_port->tc_port_name, (block ? "" : "un"), + (ret == 0 ? "succeeded" : "failed")); + + return ret; +} + static void __intel_tc_port_lock(struct intel_digital_port *dig_port, int required_lanes) { @@ -506,9 +556,11 @@ static void __intel_tc_port_lock(struct intel_digital_port *dig_port, mutex_lock(&dig_port->tc_lock); - if (!dig_port->tc_link_refcount && - intel_tc_port_needs_reset(dig_port)) + if (dig_port->tc_link_refcount == 0) { + tc_cold_request(dig_port, true); + intel_tc_port_needs_reset(dig_port); intel_tc_port_reset_mode(dig_port, required_lanes); + } drm_WARN_ON(&i915->drm, dig_port->tc_lock_wakeref); dig_port->tc_lock_wakeref = wakeref; @@ -524,6 +576,9 @@ void intel_tc_port_unlock(struct intel_digital_port *dig_port) struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); intel_wakeref_t wakeref = fetch_and_zero(&dig_port->tc_lock_wakeref); + if (dig_port->tc_link_refcount == 0) + tc_cold_request(dig_port, false); + mutex_unlock(&dig_port->tc_lock); intel_display_power_put_async(i915, POWER_DOMAIN_DISPLAY_CORE, @@ -548,6 +603,8 @@ void intel_tc_port_put_link(struct intel_digital_port *dig_port) { mutex_lock(&dig_port->tc_lock); dig_port->tc_link_refcount--; + if (dig_port->tc_link_refcount == 0) + tc_cold_request(dig_port, false); mutex_unlock(&dig_port->tc_lock); } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 9c53fe918be6..7e341d9945b3 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -9019,6 +9019,9 @@ enum { #define GEN6_PCODE_WRITE_D_COMP 0x11 #define HSW_PCODE_DE_WRITE_FREQ_REQ 0x17 #define DISPLAY_IPS_CONTROL 0x19 +#define TGL_PCODE_TCCOLD 0x26 +#define TGL_PCODE_EXIT_TCCOLD_DATA_L_EXIT_FAILED REG_BIT(0) +#define TGL_PCODE_EXIT_TCCOLD_DATA_H_UNBLOCK_REQ REG_BIT(0) /* See also IPS_CTL */ #define IPS_PCODE_CONTROL (1 << 30) #define HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL 0x1A diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c index 1447e7516cb7..20a9d3970930 100644 --- a/drivers/gpu/drm/i915/intel_sideband.c +++ b/drivers/gpu/drm/i915/intel_sideband.c @@ -463,6 +463,28 @@ int sandybridge_pcode_write_timeout(struct drm_i915_private *i915, return err; } +int sandybridge_pcode_write_read_timeout(struct drm_i915_private *i915, + u32 mbox, u32 *val, u32 *val1, + int fast_timeout_us, + int slow_timeout_ms) +{ + int err; + + mutex_lock(&i915->sb_lock); + err = __sandybridge_pcode_rw(i915, mbox, val, val1, + fast_timeout_us, slow_timeout_ms, + true); + mutex_unlock(&i915->sb_lock); + + if (err) { + drm_dbg(&i915->drm, + "warning: pcode (write of 0x%08x to mbox %x) mailbox access failed for %ps: %d\n", + *val, mbox, __builtin_return_address(0), err); + } + + return err; +} + static bool skl_pcode_try_request(struct drm_i915_private *i915, u32 mbox, u32 request, u32 reply_mask, u32 reply, u32 *status) diff --git a/drivers/gpu/drm/i915/intel_sideband.h b/drivers/gpu/drm/i915/intel_sideband.h index 7fb95745a444..1939bebb4e67 100644 --- a/drivers/gpu/drm/i915/intel_sideband.h +++ b/drivers/gpu/drm/i915/intel_sideband.h @@ -132,6 +132,10 @@ int sandybridge_pcode_read(struct drm_i915_private *i915, u32 mbox, int sandybridge_pcode_write_timeout(struct drm_i915_private *i915, u32 mbox, u32 val, int fast_timeout_us, int slow_timeout_ms); +int sandybridge_pcode_write_read_timeout(struct drm_i915_private *i915, + u32 mbox, u32 *val, u32 *val1, + int fast_timeout_us, + int slow_timeout_ms); #define sandybridge_pcode_write(i915, mbox, val) \ sandybridge_pcode_write_timeout(i915, mbox, val, 500, 0)