From patchwork Tue Mar 15 19:47:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Srivatsa, Anusha" X-Patchwork-Id: 12781801 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 84842C433FE for ; Tue, 15 Mar 2022 19:50:17 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2D39D10E357; Tue, 15 Mar 2022 19:50:16 +0000 (UTC) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2E98E10E274 for ; Tue, 15 Mar 2022 19:50:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1647373814; x=1678909814; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=5zZMCAZfaXBTl8m1oGOBXYhJqnmEuR/WYiM8sbNPbMo=; b=fY5QU3pIC0si+x2Zo0c/A3khq8epTnSxfZY7J4cugHvDZ2NlEzpnRANi nrYrJf89VtfdwSx1YIsdA3E8+FHG7SPrn+VRPX5bX11VFD/GpjrbK65+/ ddz8W73jrVRKNFuno8v9hd3Ylzg7o4HH8tjeYXqKeNscB74ZHIxv/siY9 EKFztWoGJldb5aI5LP/7DnXvxDg/ge9AOOJqWE3sfLzJwcRPL4kZSI3Km 4NhSfs6VqqOGplrWIwfA4sxRpoCAgJGR4s7RHNwcvUaXHJSHOiW65CPDo btEfytvY+7kwrmukD9j5kPtb79eS5FWTss9q1MPkATXUgTqnEhNp9LVr8 A==; X-IronPort-AV: E=McAfee;i="6200,9189,10286"; a="319629261" X-IronPort-AV: E=Sophos;i="5.90,184,1643702400"; d="scan'208";a="319629261" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Mar 2022 12:50:14 -0700 X-IronPort-AV: E=Sophos;i="5.90,184,1643702400"; d="scan'208";a="714312412" Received: from anushasr-mobl6.jf.intel.com ([10.165.21.155]) by orsmga005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Mar 2022 12:50:13 -0700 From: Anusha Srivatsa To: intel-gfx@lists.freedesktop.org Date: Tue, 15 Mar 2022 12:47:12 -0700 Message-Id: <20220315194712.2113450-5-anusha.srivatsa@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220315194712.2113450-1-anusha.srivatsa@intel.com> References: <20220315194712.2113450-1-anusha.srivatsa@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH 4/4] drm/i915/display: Add cdclk checks to atomic check 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: Jani Nikula Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Checking cdclk conditions during atomic check and preparing for commit phase so we can have atomic commit as simple as possible. Add the specific steps to be taken during cdclk changes, prepare for squashing, crawling and modeset scenarios. v2: Add intel_cdclk_modeset() similar to intel_cdclk_squash() and intel_cdclk_crawl(). Cc: Jani Nikula Signed-off-by: Anusha Srivatsa Reported-by: kernel test robot --- drivers/gpu/drm/i915/display/intel_cdclk.c | 115 +++++++++++++++------ 1 file changed, 81 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 3007710984d4..1efeee4200f0 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1700,12 +1700,23 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) { + struct intel_atomic_state *state; + struct intel_cdclk_state *new_cdclk_state; + struct cdclk_step *cdclk_steps; + struct intel_cdclk_state *cdclk_state; int cdclk = cdclk_config->cdclk; int vco = cdclk_config->vco; + u32 squash_ctl = 0; u32 val; u16 waveform; int clock; int ret; + int i; + + cdclk_state = to_intel_cdclk_state(dev_priv->cdclk.obj.state); + state = cdclk_state->base.state; + new_cdclk_state = intel_atomic_get_new_cdclk_state(state); + cdclk_steps = new_cdclk_state->steps; /* Inform power controller of upcoming frequency change. */ if (DISPLAY_VER(dev_priv) >= 11) @@ -1728,45 +1739,48 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, return; } - if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->cdclk.hw.vco > 0 && vco > 0) { - if (dev_priv->cdclk.hw.vco != vco) + for (i = 0; i < MAX_CDCLK_ACTIONS; i++) { + switch (cdclk_steps[i].action) { + case INTEL_CDCLK_MODESET: + if (DISPLAY_VER(dev_priv) >= 11) { + if (dev_priv->cdclk.hw.vco != 0 && + dev_priv->cdclk.hw.vco != vco) + icl_cdclk_pll_disable(dev_priv); + + if (dev_priv->cdclk.hw.vco != vco) + icl_cdclk_pll_enable(dev_priv, vco); + } else { + if (dev_priv->cdclk.hw.vco != 0 && + dev_priv->cdclk.hw.vco != vco) + bxt_de_pll_disable(dev_priv); + + if (dev_priv->cdclk.hw.vco != vco) + bxt_de_pll_enable(dev_priv, vco); + } + clock = cdclk; + break; + case INTEL_CDCLK_CRAWL: adlp_cdclk_pll_crawl(dev_priv, vco); - } else if (DISPLAY_VER(dev_priv) >= 11) { - if (dev_priv->cdclk.hw.vco != 0 && - dev_priv->cdclk.hw.vco != vco) - icl_cdclk_pll_disable(dev_priv); - - if (dev_priv->cdclk.hw.vco != vco) - icl_cdclk_pll_enable(dev_priv, vco); - } else { - if (dev_priv->cdclk.hw.vco != 0 && - dev_priv->cdclk.hw.vco != vco) - bxt_de_pll_disable(dev_priv); - - if (dev_priv->cdclk.hw.vco != vco) - bxt_de_pll_enable(dev_priv, vco); - } - - waveform = cdclk_squash_waveform(dev_priv, cdclk); - - if (waveform) - clock = vco / 2; - else - clock = cdclk; - - if (has_cdclk_squasher(dev_priv)) { - u32 squash_ctl = 0; - - if (waveform) + clock = cdclk; + break; + case INTEL_CDCLK_SQUASH: + waveform = cdclk_squash_waveform(dev_priv, cdclk_steps[i].cdclk); + clock = vco / 2; squash_ctl = CDCLK_SQUASH_ENABLE | - CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform; - - intel_de_write(dev_priv, CDCLK_SQUASH_CTL, squash_ctl); + CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform; + intel_de_write(dev_priv, CDCLK_SQUASH_CTL, squash_ctl); + break; + case INTEL_CDCLK_NOOP: + break; + default: + MISSING_CASE(cdclk_steps[i].action); + break; + } } val = bxt_cdclk_cd2x_div_sel(dev_priv, clock, vco) | - bxt_cdclk_cd2x_pipe(dev_priv, pipe) | - skl_cdclk_decimal(cdclk); + bxt_cdclk_cd2x_pipe(dev_priv, pipe) | + skl_cdclk_decimal(cdclk); /* * Disable SSA Precharge when CD clock frequency < 500 MHz, @@ -1956,6 +1970,7 @@ static bool intel_cdclk_crawl(struct drm_i915_private *dev_priv, struct intel_cdclk_state *b) { int a_div, b_div; + struct cdclk_step *cdclk_transition = b->steps; if (!HAS_CDCLK_CRAWL(dev_priv)) return false; @@ -1967,6 +1982,11 @@ static bool intel_cdclk_crawl(struct drm_i915_private *dev_priv, a_div = DIV_ROUND_CLOSEST(a->actual.vco, a->actual.cdclk); b_div = DIV_ROUND_CLOSEST(b->actual.vco, b->actual.cdclk); + cdclk_transition[0].action = INTEL_CDCLK_CRAWL; + cdclk_transition[0].cdclk = b->actual.cdclk; + cdclk_transition[1].action = INTEL_CDCLK_NOOP; + cdclk_transition[1].cdclk = b->actual.cdclk; + return a->actual.vco != 0 && b->actual.vco != 0 && a->actual.vco != b->actual.vco && a_div == b_div && @@ -1978,6 +1998,7 @@ static bool intel_cdclk_squash(struct drm_i915_private *dev_priv, struct intel_cdclk_state *b) { + struct cdclk_step *cdclk_transition = b->steps; /* * FIXME should store a bit more state in intel_cdclk_config * to differentiate squasher vs. cd2x divider properly. For @@ -1987,12 +2008,35 @@ static bool intel_cdclk_squash(struct drm_i915_private *dev_priv, if (!has_cdclk_squasher(dev_priv)) return false; + cdclk_transition[0].action = INTEL_CDCLK_SQUASH; + cdclk_transition[0].cdclk = b->actual.cdclk; + cdclk_transition[1].action = INTEL_CDCLK_NOOP; + cdclk_transition[1].cdclk = b->actual.cdclk; + return a->actual.cdclk != b->actual.cdclk && a->actual.vco != 0 && a->actual.vco == b->actual.vco && a->actual.ref == b->actual.ref; } +static void intel_cdclk_modeset(struct drm_i915_private *i915, + const struct intel_cdclk_config *a, + const struct intel_cdclk_config *b) +{ + struct intel_cdclk_state *new_cdclk_state; + struct cdclk_step *cdclk_transition; + struct intel_cdclk_state *cdclk_state = to_intel_cdclk_state(i915->cdclk.obj.state); + struct intel_atomic_state *state = cdclk_state->base.state; + + new_cdclk_state = intel_atomic_get_new_cdclk_state(state); + cdclk_transition = new_cdclk_state->steps; + + cdclk_transition[0].action = INTEL_CDCLK_MODESET; + cdclk_transition[0].cdclk = b->cdclk; + cdclk_transition[1].action = INTEL_CDCLK_NOOP; + cdclk_transition[1].cdclk = b->cdclk; +} + /** * intel_cdclk_needs_modeset - Determine if changong between the CDCLK * configurations requires a modeset on all pipes @@ -2006,6 +2050,7 @@ static bool intel_cdclk_squash(struct drm_i915_private *dev_priv, bool intel_cdclk_needs_modeset(const struct intel_cdclk_config *a, const struct intel_cdclk_config *b) { + return a->cdclk != b->cdclk || a->vco != b->vco || a->ref != b->ref; @@ -2795,6 +2840,8 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) pipe_name(pipe)); } else if (intel_cdclk_needs_modeset(&old_cdclk_state->actual, &new_cdclk_state->actual)) { + intel_cdclk_modeset(dev_priv, &old_cdclk_state->actual, + &new_cdclk_state->actual); /* All pipes must be switched off while we change the cdclk. */ ret = intel_modeset_all_pipes(state); if (ret)