From patchwork Thu Apr 21 23:17:05 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Roper X-Patchwork-Id: 8904891 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 EAE6EBF29F for ; Thu, 21 Apr 2016 23:19:23 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EE997202E9 for ; Thu, 21 Apr 2016 23:19:22 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id EA818201F2 for ; Thu, 21 Apr 2016 23:19:21 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 00F1D6EDD0; Thu, 21 Apr 2016 23:19:21 +0000 (UTC) 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 17B236EDCF for ; Thu, 21 Apr 2016 23:19:06 +0000 (UTC) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 21 Apr 2016 16:19:05 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,514,1455004800"; d="scan'208";a="937603334" Received: from mdroper-hswdev.fm.intel.com (HELO mdroper-hswdev) ([10.1.134.197]) by orsmga001.jf.intel.com with ESMTP; 21 Apr 2016 16:19:07 -0700 Received: from mattrope by mdroper-hswdev with local (Exim 4.84_2) (envelope-from ) id 1atNsH-0001yV-DX; Thu, 21 Apr 2016 16:19:05 -0700 From: Matt Roper To: intel-gfx@lists.freedesktop.org Date: Thu, 21 Apr 2016 16:17:05 -0700 Message-Id: <1461280630-7477-12-git-send-email-matthew.d.roper@intel.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1461280630-7477-1-git-send-email-matthew.d.roper@intel.com> References: <1461280630-7477-1-git-send-email-matthew.d.roper@intel.com> Subject: [Intel-gfx] [PATCH v3 11/16] drm/i915/gen9: Allow watermark calculation on in-flight atomic state (v3) 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=-5.2 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 In an upcoming patch we'll move this calculation to the atomic 'check' phase so that the display update can be rejected early if no valid watermark programming is possible. v2: - Drop intel_pstate_for_cstate_plane() helper and add note about how the code needs to evolve in the future if we start allowing more than one pending commit against a CRTC. (Maarten) v3: - Only have skl_compute_wm_level calculate watermarks for enabled planes; we can just set the other planes on a CRTC to disabled without having to look at the plane state. This is important because despite our CRTC lock we can still have racing commits that modify a disabled plane's property without turning it on. (Maarten) Signed-off-by: Matt Roper Reviewed-by: Maarten Lankhorst --- drivers/gpu/drm/i915/intel_pm.c | 61 ++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index c665f7e..083d1de 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3327,23 +3327,56 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, return true; } -static void skl_compute_wm_level(const struct drm_i915_private *dev_priv, - struct skl_ddb_allocation *ddb, - struct intel_crtc_state *cstate, - int level, - struct skl_wm_level *result) +static int +skl_compute_wm_level(const struct drm_i915_private *dev_priv, + struct skl_ddb_allocation *ddb, + struct intel_crtc_state *cstate, + int level, + struct skl_wm_level *result) { struct drm_device *dev = dev_priv->dev; + struct drm_atomic_state *state = cstate->base.state; struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); + struct drm_plane *plane; struct intel_plane *intel_plane; struct intel_plane_state *intel_pstate; uint16_t ddb_blocks; enum pipe pipe = intel_crtc->pipe; - for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { + /* + * We'll only calculate watermarks for planes that are actually + * enabled, so make sure all other planes are set as disabled. + */ + memset(result, 0, sizeof(*result)); + + for_each_intel_plane_mask(dev, intel_plane, cstate->base.plane_mask) { int i = skl_wm_plane_id(intel_plane); - intel_pstate = to_intel_plane_state(intel_plane->base.state); + plane = &intel_plane->base; + intel_pstate = NULL; + if (state) + intel_pstate = + intel_atomic_get_existing_plane_state(state, + intel_plane); + + /* + * Note: If we start supporting multiple pending atomic commits + * against the same planes/CRTC's in the future, plane->state + * will no longer be the correct pre-state to use for the + * calculations here and we'll need to change where we get the + * 'unchanged' plane data from. + * + * For now this is fine because we only allow one queued commit + * against a CRTC. Even if the plane isn't modified by this + * transaction and we don't have a plane lock, we still have + * the CRTC's lock, so we know that no other transactions are + * racing with us to update it. + */ + if (!intel_pstate) + intel_pstate = to_intel_plane_state(plane->state); + + WARN_ON(!intel_pstate->base.fb); + ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]); result->plane_en[i] = skl_compute_plane_wm(dev_priv, @@ -3354,6 +3387,8 @@ static void skl_compute_wm_level(const struct drm_i915_private *dev_priv, &result->plane_res_b[i], &result->plane_res_l[i]); } + + return 0; } static uint32_t @@ -3648,14 +3683,14 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv, } } -static bool skl_update_pipe_wm(struct drm_crtc *crtc, +static bool skl_update_pipe_wm(struct drm_crtc_state *cstate, struct skl_ddb_allocation *ddb, /* out */ struct skl_pipe_wm *pipe_wm /* out */) { - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); + struct intel_crtc *intel_crtc = to_intel_crtc(cstate->crtc); + struct intel_crtc_state *intel_cstate = to_intel_crtc_state(cstate); - skl_build_pipe_wm(cstate, ddb, pipe_wm); + skl_build_pipe_wm(intel_cstate, ddb, pipe_wm); if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm))) return false; @@ -3695,7 +3730,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev, if (!intel_crtc->active) continue; - wm_changed = skl_update_pipe_wm(&intel_crtc->base, + wm_changed = skl_update_pipe_wm(intel_crtc->base.state, &r->ddb, &pipe_wm); /* @@ -3804,7 +3839,7 @@ static void skl_update_wm(struct drm_crtc *crtc) skl_clear_wm(results, intel_crtc->pipe); - if (!skl_update_pipe_wm(crtc, &results->ddb, pipe_wm)) + if (!skl_update_pipe_wm(crtc->state, &results->ddb, pipe_wm)) return; skl_compute_wm_results(dev, pipe_wm, results, intel_crtc);