From patchwork Thu Oct 6 16:22:21 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ander Conselvan de Oliveira X-Patchwork-Id: 9365097 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 669B06075E for ; Thu, 6 Oct 2016 16:22:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 575922916F for ; Thu, 6 Oct 2016 16:22:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4C00629183; Thu, 6 Oct 2016 16:22:47 +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=-4.2 required=2.0 tests=BAYES_00, 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 B10DC2916F for ; Thu, 6 Oct 2016 16:22:46 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 33DD06EA18; Thu, 6 Oct 2016 16:22:46 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id 68ACB6EA18 for ; Thu, 6 Oct 2016 16:22:44 +0000 (UTC) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga105.jf.intel.com with ESMTP; 06 Oct 2016 09:22:43 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.31,454,1473145200"; d="scan'208";a="177094683" Received: from linux.intel.com ([10.54.29.200]) by fmsmga004.fm.intel.com with ESMTP; 06 Oct 2016 09:22:44 -0700 Received: from localhost (aconselv-mobl3.fi.intel.com [10.237.66.34]) by linux.intel.com (Postfix) with ESMTP id 39B456A4006; Thu, 6 Oct 2016 09:22:13 -0700 (PDT) From: Ander Conselvan de Oliveira To: intel-gfx@lists.freedesktop.org Date: Thu, 6 Oct 2016 19:22:21 +0300 Message-Id: <62d209950ad48484564f3e793cf247cf62572a39.1475770848.git-series.ander.conselvan.de.oliveira@intel.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: References: In-Reply-To: References: Cc: m.deepak@intel.com, Ander Conselvan de Oliveira Subject: [Intel-gfx] [PATCH v2 8/9] drm/i915: Add location of the Rcomp resistor to bxt_ddi_phy_info 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-Virus-Scanned: ClamAV using ClamSMTP Use struct bxt_ddi_phy_info to hold information of where the Rcomp resistor is located, instead of hard coding it in the init sequence. Note that this moves the enabling of the phy with the Rcomp resistor out of the power well enable code. That should be safe since bxt_ddi_phy_init() is called while the power domains lock is held, and that is the only way that function gets called, so there is no possibility of a concurrent phy enable caused by a power domain get call. v2: Replace comment about lock with lockdep_assert_held() (Imre) Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/intel_dpio_phy.c | 72 +++++++++++++++++++------- drivers/gpu/drm/i915/intel_runtime_pm.c | 15 +----- 2 files changed, 55 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dpio_phy.c b/drivers/gpu/drm/i915/intel_dpio_phy.c index 1b1fba1..6711e3a 100644 --- a/drivers/gpu/drm/i915/intel_dpio_phy.c +++ b/drivers/gpu/drm/i915/intel_dpio_phy.c @@ -124,6 +124,13 @@ struct bxt_ddi_phy_info { bool dual_channel; /** + * @rcomp_phy: If -1, indicates this phy has its own rcomp resistor. + * Otherwise the GRC value will be copied from the phy indicated by + * this field. + */ + enum dpio_phy rcomp_phy; + + /** * @channel: struct containing per channel information. */ struct { @@ -137,6 +144,7 @@ struct bxt_ddi_phy_info { static const struct bxt_ddi_phy_info bxt_ddi_phy_info[] = { [DPIO_PHY0] = { .dual_channel = true, + .rcomp_phy = DPIO_PHY1, .channel = { [DPIO_CH0] = { .port = PORT_B }, @@ -145,6 +153,7 @@ static const struct bxt_ddi_phy_info bxt_ddi_phy_info[] = { }, [DPIO_PHY1] = { .dual_channel = false, + .rcomp_phy = -1, .channel = { [DPIO_CH0] = { .port = PORT_A }, @@ -214,9 +223,10 @@ bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv, return false; } - if (phy == DPIO_PHY1 && - !(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE)) { - DRM_DEBUG_DRIVER("DDI PHY 1 powered, but GRC isn't done\n"); + if (phy_info->rcomp_phy == -1 && + !(I915_READ(BXT_PORT_REF_DW3(phy)) & GRC_DONE)) { + DRM_DEBUG_DRIVER("DDI PHY %d powered, but GRC isn't done\n", + phy); return false; } @@ -261,14 +271,15 @@ static void bxt_phy_wait_grc_done(struct drm_i915_private *dev_priv, DRM_ERROR("timeout waiting for PHY%d GRC\n", phy); } -void bxt_ddi_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy) +static void _bxt_ddi_phy_init(struct drm_i915_private *dev_priv, + enum dpio_phy phy) { const struct bxt_ddi_phy_info *phy_info = &bxt_ddi_phy_info[phy]; u32 val; if (bxt_ddi_phy_is_enabled(dev_priv, phy)) { /* Still read out the GRC value for state verification */ - if (phy == DPIO_PHY0) + if (phy_info->rcomp_phy != -1) dev_priv->bxt_phy_grc = bxt_get_grc(dev_priv, phy); if (bxt_ddi_phy_verify_state(dev_priv, phy)) { @@ -338,30 +349,32 @@ void bxt_ddi_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy) val |= OCL2_LDOFUSE_PWR_DIS; I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val); - if (phy == DPIO_PHY0) { + if (phy_info->rcomp_phy != -1) { uint32_t grc_code; /* * PHY0 isn't connected to an RCOMP resistor so copy over * the corresponding calibrated value from PHY1, and disable * the automatic calibration on PHY0. */ - val = dev_priv->bxt_phy_grc = bxt_get_grc(dev_priv, DPIO_PHY1); + val = dev_priv->bxt_phy_grc = bxt_get_grc(dev_priv, + phy_info->rcomp_phy); grc_code = val << GRC_CODE_FAST_SHIFT | val << GRC_CODE_SLOW_SHIFT | val; - I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code); + I915_WRITE(BXT_PORT_REF_DW6(phy), grc_code); - val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0)); + val = I915_READ(BXT_PORT_REF_DW8(phy)); val |= GRC_DIS | GRC_RDY_OVRD; - I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val); + I915_WRITE(BXT_PORT_REF_DW8(phy), val); } val = I915_READ(BXT_PHY_CTL_FAMILY(phy)); val |= COMMON_RESET_DIS; I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val); - if (phy == DPIO_PHY1) - bxt_phy_wait_grc_done(dev_priv, DPIO_PHY1); + if (phy_info->rcomp_phy == -1) + bxt_phy_wait_grc_done(dev_priv, phy); + } void bxt_ddi_phy_uninit(struct drm_i915_private *dev_priv, enum dpio_phy phy) @@ -377,6 +390,31 @@ void bxt_ddi_phy_uninit(struct drm_i915_private *dev_priv, enum dpio_phy phy) I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val); } +void bxt_ddi_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy) +{ + const struct bxt_ddi_phy_info *phy_info = &bxt_ddi_phy_info[phy]; + enum dpio_phy rcomp_phy = phy_info->rcomp_phy; + bool was_enabled; + + lockdep_assert_held(&dev_priv->power_domains.lock); + + if (rcomp_phy != -1) { + was_enabled = bxt_ddi_phy_is_enabled(dev_priv, rcomp_phy); + + /* + * We need to copy the GRC calibration value from rcomp_phy, + * so make sure it's powered up. + */ + if (!was_enabled) + _bxt_ddi_phy_init(dev_priv, rcomp_phy); + } + + _bxt_ddi_phy_init(dev_priv, phy); + + if (rcomp_phy != -1 && !was_enabled) + bxt_ddi_phy_uninit(dev_priv, phy_info->rcomp_phy); +} + static bool __printf(6, 7) __phy_reg_verify_state(struct drm_i915_private *dev_priv, enum dpio_phy phy, i915_reg_t reg, u32 mask, u32 expected, @@ -443,7 +481,7 @@ bool bxt_ddi_phy_verify_state(struct drm_i915_private *dev_priv, * at least on stepping A this bit is read-only and fixed at 0. */ - if (phy == DPIO_PHY0) { + if (phy_info->rcomp_phy != -1) { u32 grc_code = dev_priv->bxt_phy_grc; grc_code = grc_code << GRC_CODE_FAST_SHIFT | @@ -451,12 +489,12 @@ bool bxt_ddi_phy_verify_state(struct drm_i915_private *dev_priv, grc_code; mask = GRC_CODE_FAST_MASK | GRC_CODE_SLOW_MASK | GRC_CODE_NOM_MASK; - ok &= _CHK(BXT_PORT_REF_DW6(DPIO_PHY0), mask, grc_code, - "BXT_PORT_REF_DW6(%d)", DPIO_PHY0); + ok &= _CHK(BXT_PORT_REF_DW6(phy), mask, grc_code, + "BXT_PORT_REF_DW6(%d)", phy); mask = GRC_DIS | GRC_RDY_OVRD; - ok &= _CHK(BXT_PORT_REF_DW8(DPIO_PHY0), mask, mask, - "BXT_PORT_REF_DW8(%d)", DPIO_PHY0); + ok &= _CHK(BXT_PORT_REF_DW8(phy), mask, mask, + "BXT_PORT_REF_DW8(%d)", phy); } return ok; diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index d41fd46..3b38998 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -849,22 +849,7 @@ static void skl_power_well_disable(struct drm_i915_private *dev_priv, static void bxt_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { - enum skl_disp_power_wells power_well_id = power_well->id; - struct i915_power_well *cmn_a_well = NULL; - - if (power_well_id == BXT_DPIO_CMN_BC) { - /* - * We need to copy the GRC calibration value from the eDP PHY, - * so make sure it's powered up. - */ - cmn_a_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_A); - intel_power_well_get(dev_priv, cmn_a_well); - } - bxt_ddi_phy_init(dev_priv, power_well->data); - - if (cmn_a_well) - intel_power_well_put(dev_priv, cmn_a_well); } static void bxt_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,