From patchwork Thu Jun 20 14:05:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 11006753 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 981EF1395 for ; Thu, 20 Jun 2019 14:06:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 89BC8285C7 for ; Thu, 20 Jun 2019 14:06:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7DF32287B5; Thu, 20 Jun 2019 14:06:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0290928688 for ; Thu, 20 Jun 2019 14:06:40 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 747EA6E5A6; Thu, 20 Jun 2019 14:06:37 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by gabe.freedesktop.org (Postfix) with ESMTPS id 536206E599 for ; Thu, 20 Jun 2019 14:06:30 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Jun 2019 07:06:30 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.63,397,1557212400"; d="scan'208";a="162531304" Received: from ideak-desk.fi.intel.com ([10.237.72.204]) by orsmga003.jf.intel.com with ESMTP; 20 Jun 2019 07:06:28 -0700 From: Imre Deak To: intel-gfx@lists.freedesktop.org Date: Thu, 20 Jun 2019 17:05:51 +0300 Message-Id: <20190620140600.11357-15-imre.deak@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190620140600.11357-1-imre.deak@intel.com> References: <20190620140600.11357-1-imre.deak@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v2 14/23] drm/i915: Keep the TypeC port mode fixed for detect/AUX transfers X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Paulo Zanoni Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP We must keep the TypeC port mode fixed for the duration of the connector detection and each AUX transfers. Add a new TypeC lock holding it around these two sequences. For consistency also hold the lock during the port mode sanitization. Whenever resetting the port mode (only during the detection for now) the port's AUX power domain must be disabled already. Flush the async power domain disabling work to ensure this. A follow-up patch will make the port mode changing more robust by postponing the change for active ports. v2: - Fix checkpatch issue: missing annotation for tc_lock. Cc: José Roberto de Souza Cc: Rodrigo Vivi Cc: Paulo Zanoni Cc: Ville Syrjälä Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_dp.c | 7 ++++++ drivers/gpu/drm/i915/display/intel_tc.c | 30 ++++++++++++++++++++++++- drivers/gpu/drm/i915/display/intel_tc.h | 2 ++ drivers/gpu/drm/i915/intel_drv.h | 1 + 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 0c6afec78f93..8f7188d71d08 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1192,6 +1192,7 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp, struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev); struct intel_uncore *uncore = &i915->uncore; + bool is_tc_port = intel_port_is_tc(i915, intel_dig_port->base.port); i915_reg_t ch_ctl, ch_data[5]; u32 aux_clock_divider; enum intel_display_power_domain aux_domain = @@ -1207,6 +1208,9 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp, for (i = 0; i < ARRAY_SIZE(ch_data); i++) ch_data[i] = intel_dp->aux_ch_data_reg(intel_dp, i); + if (is_tc_port) + intel_tc_port_lock(intel_dig_port); + aux_wakeref = intel_display_power_get(i915, aux_domain); pps_wakeref = pps_lock(intel_dp); @@ -1359,6 +1363,9 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp, pps_unlock(intel_dp, pps_wakeref); intel_display_power_put_async(i915, aux_domain, aux_wakeref); + if (is_tc_port) + intel_tc_port_unlock(intel_dig_port); + return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 81b0d5676108..019bc53af28b 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -296,8 +296,11 @@ intel_tc_port_get_target_mode(struct intel_digital_port *dig_port) static void intel_tc_port_reset_mode(struct intel_digital_port *dig_port) { + struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); enum tc_port_mode old_tc_mode = dig_port->tc_mode; + intel_display_power_flush_work(dev_priv); + icl_tc_phy_disconnect(dig_port); icl_tc_phy_connect(dig_port); @@ -312,6 +315,8 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port) struct intel_encoder *encoder = &dig_port->base; int active_links = 0; + mutex_lock(&dig_port->tc_lock); + dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port); if (dig_port->dp.is_mst) active_links = intel_dp_mst_encoder_active_links(dig_port); @@ -332,6 +337,8 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port) DRM_DEBUG_KMS("Port %s: sanitize mode (%s)\n", dig_port->tc_port_name, tc_port_mode_name(dig_port->tc_mode)); + + mutex_unlock(&dig_port->tc_lock); } static bool intel_tc_port_needs_reset(struct intel_digital_port *dig_port) @@ -351,10 +358,30 @@ static bool intel_tc_port_needs_reset(struct intel_digital_port *dig_port) */ bool intel_tc_port_connected(struct intel_digital_port *dig_port) { + bool is_connected; + + mutex_lock(&dig_port->tc_lock); + if (intel_tc_port_needs_reset(dig_port)) intel_tc_port_reset_mode(dig_port); - return tc_port_live_status_mask(dig_port) & BIT(dig_port->tc_mode); + is_connected = tc_port_live_status_mask(dig_port) & + BIT(dig_port->tc_mode); + + mutex_unlock(&dig_port->tc_lock); + + return is_connected; +} + +void intel_tc_port_lock(struct intel_digital_port *dig_port) +{ + mutex_lock(&dig_port->tc_lock); + /* TODO: reset the TypeC port mode if needed */ +} + +void intel_tc_port_unlock(struct intel_digital_port *dig_port) +{ + mutex_unlock(&dig_port->tc_lock); } void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) @@ -369,5 +396,6 @@ void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) snprintf(dig_port->tc_port_name, sizeof(dig_port->tc_port_name), "%c/TC#%d", port_name(port), tc_port + 1); + mutex_init(&dig_port->tc_lock); dig_port->tc_legacy_port = is_legacy; } diff --git a/drivers/gpu/drm/i915/display/intel_tc.h b/drivers/gpu/drm/i915/display/intel_tc.h index 5a7876a74522..b5af2fe60b22 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.h +++ b/drivers/gpu/drm/i915/display/intel_tc.h @@ -17,6 +17,8 @@ u32 intel_tc_port_get_lane_mask(struct intel_digital_port *dig_port); int intel_tc_port_fia_max_lane_count(struct intel_digital_port *dig_port); void intel_tc_port_sanitize(struct intel_digital_port *dig_port); +void intel_tc_port_lock(struct intel_digital_port *dig_port); +void intel_tc_port_unlock(struct intel_digital_port *dig_port); void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 19f6a360acde..d9e7d011ed4a 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1224,6 +1224,7 @@ struct intel_digital_port { /* Used for DP and ICL+ TypeC/DP and TypeC/HDMI ports. */ enum aux_ch aux_ch; enum intel_display_power_domain ddi_io_power_domain; + struct mutex tc_lock; /* protects the TypeC port mode */ bool tc_legacy_port:1; char tc_port_name[8]; enum tc_port_mode tc_mode;