From patchwork Sun Dec 15 23:23:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Lisovskiy, Stanislav" X-Patchwork-Id: 11293221 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 613D714BD for ; Sun, 15 Dec 2019 23:26:02 +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 48C8E2467A for ; Sun, 15 Dec 2019 23:26:02 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 48C8E2467A 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 3FA6B6E17C; Sun, 15 Dec 2019 23:25:59 +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 0B2836E15A for ; Sun, 15 Dec 2019 23:25:58 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Dec 2019 15:25:57 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,319,1571727600"; d="scan'208";a="246825794" Received: from slisovsk-lenovo-ideapad-720s-13ikb.fi.intel.com ([10.237.72.89]) by fmsmga002.fm.intel.com with ESMTP; 15 Dec 2019 15:25:56 -0800 From: Stanislav Lisovskiy To: intel-gfx@lists.freedesktop.org Date: Mon, 16 Dec 2019 01:23:05 +0200 Message-Id: <20191215232308.14668-2-stanislav.lisovskiy@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191215232308.14668-1-stanislav.lisovskiy@intel.com> References: <20191215232308.14668-1-stanislav.lisovskiy@intel.com> Subject: [Intel-gfx] [PATCH v9 1/4] drm/i915: Remove skl_ddl_allocation struct 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: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Current consensus that it is redundant as we already have skl_ddb_values struct out there, also this struct contains only single member which makes it unnecessary. v2: As dirty_pipes soon going to be nuked away from skl_ddb_values, evacuating enabled_slices to safer in dev_priv. v3: Changed "enabled_slices" to be "enabled_dbuf_slices_num" (Matt Roper) v4: - Wrapped the line getting number of dbuf slices(Matt Roper) - Removed indeed redundant skl_ddb_values declaration(Matt Roper) Reviewed-by: Matt Roper Signed-off-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/display/intel_display.c | 16 +++---- .../drm/i915/display/intel_display_power.c | 8 ++-- .../drm/i915/display/intel_display_types.h | 3 ++ drivers/gpu/drm/i915/i915_drv.h | 7 +-- drivers/gpu/drm/i915/intel_pm.c | 45 +++++++++---------- drivers/gpu/drm/i915/intel_pm.h | 5 +-- 6 files changed, 39 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 64e4bfb0dfc9..d9ae9beb67df 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -13342,14 +13342,13 @@ static void verify_wm_state(struct intel_crtc *crtc, struct skl_hw_state { struct skl_ddb_entry ddb_y[I915_MAX_PLANES]; struct skl_ddb_entry ddb_uv[I915_MAX_PLANES]; - struct skl_ddb_allocation ddb; struct skl_pipe_wm wm; } *hw; - struct skl_ddb_allocation *sw_ddb; struct skl_pipe_wm *sw_wm; struct skl_ddb_entry *hw_ddb_entry, *sw_ddb_entry; const enum pipe pipe = crtc->pipe; int plane, level, max_level = ilk_wm_max_level(dev_priv); + u8 hw_enabled_slices; if (INTEL_GEN(dev_priv) < 9 || !new_crtc_state->hw.active) return; @@ -13363,14 +13362,13 @@ static void verify_wm_state(struct intel_crtc *crtc, skl_pipe_ddb_get_hw_state(crtc, hw->ddb_y, hw->ddb_uv); - skl_ddb_get_hw_state(dev_priv, &hw->ddb); - sw_ddb = &dev_priv->wm.skl_hw.ddb; + hw_enabled_slices = intel_enabled_dbuf_slices_num(dev_priv); if (INTEL_GEN(dev_priv) >= 11 && - hw->ddb.enabled_slices != sw_ddb->enabled_slices) + hw_enabled_slices != dev_priv->enabled_dbuf_slices_num) DRM_ERROR("mismatch in DBUF Slices (expected %u, got %u)\n", - sw_ddb->enabled_slices, - hw->ddb.enabled_slices); + dev_priv->enabled_dbuf_slices_num, + hw_enabled_slices); /* planes */ for_each_universal_plane(dev_priv, pipe, plane) { @@ -14556,8 +14554,8 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state) struct drm_i915_private *dev_priv = to_i915(state->base.dev); struct intel_crtc *crtc; struct intel_crtc_state *old_crtc_state, *new_crtc_state; - u8 hw_enabled_slices = dev_priv->wm.skl_hw.ddb.enabled_slices; - u8 required_slices = state->wm_results.ddb.enabled_slices; + u8 hw_enabled_slices = dev_priv->enabled_dbuf_slices_num; + u8 required_slices = state->enabled_dbuf_slices_num; struct skl_ddb_entry entries[I915_MAX_PIPES] = {}; u8 dirty_pipes = 0; int i; diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 679457156797..d8058cc61e45 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -4406,7 +4406,7 @@ static u8 intel_dbuf_max_slices(struct drm_i915_private *dev_priv) void icl_dbuf_slices_update(struct drm_i915_private *dev_priv, u8 req_slices) { - const u8 hw_enabled_slices = dev_priv->wm.skl_hw.ddb.enabled_slices; + const u8 hw_enabled_slices = dev_priv->enabled_dbuf_slices_num; bool ret; if (req_slices > intel_dbuf_max_slices(dev_priv)) { @@ -4423,7 +4423,7 @@ void icl_dbuf_slices_update(struct drm_i915_private *dev_priv, ret = intel_dbuf_slice_set(dev_priv, DBUF_CTL_S2, false); if (ret) - dev_priv->wm.skl_hw.ddb.enabled_slices = req_slices; + dev_priv->enabled_dbuf_slices_num = req_slices; } static void icl_dbuf_enable(struct drm_i915_private *dev_priv) @@ -4442,7 +4442,7 @@ static void icl_dbuf_enable(struct drm_i915_private *dev_priv) * FIXME: for now pretend that we only have 1 slice, see * intel_enabled_dbuf_slices_num(). */ - dev_priv->wm.skl_hw.ddb.enabled_slices = 1; + dev_priv->enabled_dbuf_slices_num = 1; } static void icl_dbuf_disable(struct drm_i915_private *dev_priv) @@ -4461,7 +4461,7 @@ static void icl_dbuf_disable(struct drm_i915_private *dev_priv) * FIXME: for now pretend that the first slice is always * enabled, see intel_enabled_dbuf_slices_num(). */ - dev_priv->wm.skl_hw.ddb.enabled_slices = 1; + dev_priv->enabled_dbuf_slices_num = 1; } static void icl_mbus_init(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 83ea04149b77..70e65c2d525d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -517,6 +517,9 @@ struct intel_atomic_state { /* Gen9+ only */ struct skl_ddb_values wm_results; + /* Number of enabled DBuf slices */ + u8 enabled_dbuf_slices_num; + struct i915_sw_fence commit_ready; struct llist_node freed; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0781b6326b8c..7a2d9fa5a9a6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -798,13 +798,8 @@ static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1, return false; } -struct skl_ddb_allocation { - u8 enabled_slices; /* GEN11 has configurable 2 slices */ -}; - struct skl_ddb_values { unsigned dirty_pipes; - struct skl_ddb_allocation ddb; }; struct skl_wm_level { @@ -1215,6 +1210,8 @@ struct drm_i915_private { bool distrust_bios_wm; } wm; + u8 enabled_dbuf_slices_num; /* GEN11 has configurable 2 slices */ + struct dram_info { bool valid; bool is_16gb_dimm; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index ccbbdf4a6aab..28a65b931de1 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3616,16 +3616,16 @@ bool ilk_disable_lp_wm(struct drm_i915_private *dev_priv) return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL); } -static u8 intel_enabled_dbuf_slices_num(struct drm_i915_private *dev_priv) +u8 intel_enabled_dbuf_slices_num(struct drm_i915_private *dev_priv) { - u8 enabled_slices; + u8 enabled_dbuf_slices_num; /* Slice 1 will always be enabled */ - enabled_slices = 1; + enabled_dbuf_slices_num = 1; /* Gen prior to GEN11 have only one DBuf slice */ if (INTEL_GEN(dev_priv) < 11) - return enabled_slices; + return enabled_dbuf_slices_num; /* * FIXME: for now we'll only ever use 1 slice; pretend that we have @@ -3633,9 +3633,9 @@ static u8 intel_enabled_dbuf_slices_num(struct drm_i915_private *dev_priv) * toggling of the second slice. */ if (0 && I915_READ(DBUF_CTL_S2) & DBUF_POWER_STATE) - enabled_slices++; + enabled_dbuf_slices_num++; - return enabled_slices; + return enabled_dbuf_slices_num; } /* @@ -3839,9 +3839,10 @@ bool intel_can_enable_sagv(struct intel_atomic_state *state) static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv, const struct intel_crtc_state *crtc_state, const u64 total_data_rate, - const int num_active, - struct skl_ddb_allocation *ddb) + const int num_active) { + struct drm_atomic_state *state = crtc_state->uapi.state; + struct intel_atomic_state *intel_state = to_intel_atomic_state(state); const struct drm_display_mode *adjusted_mode; u64 total_data_bw; u16 ddb_size = INTEL_INFO(dev_priv)->ddb_size; @@ -3863,9 +3864,9 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv, * - should validate we stay within the hw bandwidth limits */ if (0 && (num_active > 1 || total_data_bw >= GBps(12))) { - ddb->enabled_slices = 2; + intel_state->enabled_dbuf_slices_num = 2; } else { - ddb->enabled_slices = 1; + intel_state->enabled_dbuf_slices_num = 1; ddb_size /= 2; } @@ -3876,7 +3877,6 @@ static void skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv, const struct intel_crtc_state *crtc_state, const u64 total_data_rate, - struct skl_ddb_allocation *ddb, struct skl_ddb_entry *alloc, /* out */ int *num_active /* out */) { @@ -3902,7 +3902,7 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv, *num_active = hweight8(dev_priv->active_pipes); ddb_size = intel_get_ddb_size(dev_priv, crtc_state, total_data_rate, - *num_active, ddb); + *num_active); /* * If the state doesn't change the active CRTC's or there is no @@ -4063,10 +4063,10 @@ void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc, intel_display_power_put(dev_priv, power_domain, wakeref); } -void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, - struct skl_ddb_allocation *ddb /* out */) +void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv) { - ddb->enabled_slices = intel_enabled_dbuf_slices_num(dev_priv); + dev_priv->enabled_dbuf_slices_num = + intel_enabled_dbuf_slices_num(dev_priv); } /* @@ -4243,8 +4243,7 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state, } static int -skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state, - struct skl_ddb_allocation *ddb /* out */) +skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state) { struct drm_atomic_state *state = crtc_state->uapi.state; struct drm_crtc *crtc = crtc_state->uapi.crtc; @@ -4286,7 +4285,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state, skl_ddb_get_pipe_allocation_limits(dev_priv, crtc_state, total_data_rate, - ddb, alloc, &num_active); + alloc, &num_active); alloc_size = skl_ddb_entry_size(alloc); if (alloc_size == 0) return 0; @@ -5200,18 +5199,17 @@ skl_ddb_add_affected_planes(const struct intel_crtc_state *old_crtc_state, static int skl_compute_ddb(struct intel_atomic_state *state) { - const struct drm_i915_private *dev_priv = to_i915(state->base.dev); - struct skl_ddb_allocation *ddb = &state->wm_results.ddb; + struct drm_i915_private *dev_priv = to_i915(state->base.dev); struct intel_crtc_state *old_crtc_state; struct intel_crtc_state *new_crtc_state; struct intel_crtc *crtc; int ret, i; - memcpy(ddb, &dev_priv->wm.skl_hw.ddb, sizeof(*ddb)); + state->enabled_dbuf_slices_num = dev_priv->enabled_dbuf_slices_num; for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { - ret = skl_allocate_pipe_ddb(new_crtc_state, ddb); + ret = skl_allocate_pipe_ddb(new_crtc_state); if (ret) return ret; @@ -5683,11 +5681,10 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc, void skl_wm_get_hw_state(struct drm_i915_private *dev_priv) { struct skl_ddb_values *hw = &dev_priv->wm.skl_hw; - struct skl_ddb_allocation *ddb = &dev_priv->wm.skl_hw.ddb; struct intel_crtc *crtc; struct intel_crtc_state *crtc_state; - skl_ddb_get_hw_state(dev_priv, ddb); + skl_ddb_get_hw_state(dev_priv); for_each_intel_crtc(&dev_priv->drm, crtc) { crtc_state = to_intel_crtc_state(crtc->base.state); diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h index c06c6a846d9a..22fd2daf608e 100644 --- a/drivers/gpu/drm/i915/intel_pm.h +++ b/drivers/gpu/drm/i915/intel_pm.h @@ -17,7 +17,6 @@ struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; struct intel_plane; -struct skl_ddb_allocation; struct skl_ddb_entry; struct skl_pipe_wm; struct skl_wm_level; @@ -33,11 +32,11 @@ void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv); void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv); void ilk_wm_get_hw_state(struct drm_i915_private *dev_priv); void skl_wm_get_hw_state(struct drm_i915_private *dev_priv); +u8 intel_enabled_dbuf_slices_num(struct drm_i915_private *dev_priv); void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc, struct skl_ddb_entry *ddb_y, struct skl_ddb_entry *ddb_uv); -void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, - struct skl_ddb_allocation *ddb /* out */); +void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv); void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc, struct skl_pipe_wm *out); void g4x_wm_sanitize(struct drm_i915_private *dev_priv); From patchwork Sun Dec 15 23:23:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Lisovskiy, Stanislav" X-Patchwork-Id: 11293225 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 287E414B7 for ; Sun, 15 Dec 2019 23:26:06 +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 0F2332467A for ; Sun, 15 Dec 2019 23:26:06 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0F2332467A 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 3720C6E181; Sun, 15 Dec 2019 23:26:04 +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 D87CC6E17A for ; Sun, 15 Dec 2019 23:25:59 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Dec 2019 15:25:59 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,319,1571727600"; d="scan'208";a="246825798" Received: from slisovsk-lenovo-ideapad-720s-13ikb.fi.intel.com ([10.237.72.89]) by fmsmga002.fm.intel.com with ESMTP; 15 Dec 2019 15:25:57 -0800 From: Stanislav Lisovskiy To: intel-gfx@lists.freedesktop.org Date: Mon, 16 Dec 2019 01:23:06 +0200 Message-Id: <20191215232308.14668-3-stanislav.lisovskiy@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191215232308.14668-1-stanislav.lisovskiy@intel.com> References: <20191215232308.14668-1-stanislav.lisovskiy@intel.com> Subject: [Intel-gfx] [PATCH v9 2/4] drm/i915: Move dbuf slice update to proper place 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: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Current DBuf slices update wasn't done in proper place, especially its "post" part, which should disable those only once vblank had passed and all other changes are committed. v2: Fix to use dev_priv and intel_atomic_state instead of skl_ddb_values (to be nuked in Villes patch) v3: Renamed "enabled_slices" to "enabled_dbuf_slices_num" (Matt Roper) Reviewed-by: Matt Roper Signed-off-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/display/intel_display.c | 38 ++++++++++++++------ 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index d9ae9beb67df..73d9c275bc20 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -14549,13 +14549,33 @@ static void intel_update_trans_port_sync_crtcs(struct intel_crtc *crtc, state); } +static void icl_dbuf_slice_pre_update(struct intel_atomic_state *state) +{ + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + u8 hw_enabled_slices = dev_priv->enabled_dbuf_slices_num; + u8 required_slices = state->enabled_dbuf_slices_num; + + /* If 2nd DBuf slice required, enable it here */ + if (INTEL_GEN(dev_priv) >= 11 && required_slices > hw_enabled_slices) + icl_dbuf_slices_update(dev_priv, required_slices); +} + +static void icl_dbuf_slice_post_update(struct intel_atomic_state *state) +{ + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + u8 hw_enabled_slices = dev_priv->enabled_dbuf_slices_num; + u8 required_slices = state->enabled_dbuf_slices_num; + + /* If 2nd DBuf slice is no more required disable it */ + if (INTEL_GEN(dev_priv) >= 11 && required_slices < hw_enabled_slices) + icl_dbuf_slices_update(dev_priv, required_slices); +} + static void skl_commit_modeset_enables(struct intel_atomic_state *state) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); struct intel_crtc *crtc; struct intel_crtc_state *old_crtc_state, *new_crtc_state; - u8 hw_enabled_slices = dev_priv->enabled_dbuf_slices_num; - u8 required_slices = state->enabled_dbuf_slices_num; struct skl_ddb_entry entries[I915_MAX_PIPES] = {}; u8 dirty_pipes = 0; int i; @@ -14568,10 +14588,6 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state) dirty_pipes |= BIT(crtc->pipe); } - /* If 2nd DBuf slice required, enable it here */ - if (INTEL_GEN(dev_priv) >= 11 && required_slices > hw_enabled_slices) - icl_dbuf_slices_update(dev_priv, required_slices); - /* * Whenever the number of active pipes changes, we need to make sure we * update the pipes in the right order so that their ddb allocations @@ -14620,10 +14636,6 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state) intel_wait_for_vblank(dev_priv, pipe); } } - - /* If 2nd DBuf slice is no more required disable it */ - if (INTEL_GEN(dev_priv) >= 11 && required_slices < hw_enabled_slices) - icl_dbuf_slices_update(dev_priv, required_slices); } static void intel_atomic_helper_free_state(struct drm_i915_private *dev_priv) @@ -14753,6 +14765,9 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) if (state->modeset) intel_encoders_update_prepare(state); + /* Enable all new slices, we might need */ + icl_dbuf_slice_pre_update(state); + /* Now enable the clocks, plane, pipe, and connectors that we set up. */ dev_priv->display.commit_modeset_enables(state); @@ -14828,6 +14843,9 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) if (state->modeset && intel_can_enable_sagv(state)) intel_enable_sagv(dev_priv); + /* Disable all slices, we don't need */ + icl_dbuf_slice_post_update(state); + drm_atomic_helper_commit_hw_done(&state->base); if (state->modeset) { From patchwork Sun Dec 15 23:23:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Lisovskiy, Stanislav" X-Patchwork-Id: 11293223 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 A943614BD for ; Sun, 15 Dec 2019 23:26:04 +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 90AE02467A for ; Sun, 15 Dec 2019 23:26:04 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 90AE02467A 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 B9F646E2DF; Sun, 15 Dec 2019 23:26:03 +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 0A3006E17A for ; Sun, 15 Dec 2019 23:26:02 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Dec 2019 15:26:01 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,319,1571727600"; d="scan'208";a="246825811" Received: from slisovsk-lenovo-ideapad-720s-13ikb.fi.intel.com ([10.237.72.89]) by fmsmga002.fm.intel.com with ESMTP; 15 Dec 2019 15:25:59 -0800 From: Stanislav Lisovskiy To: intel-gfx@lists.freedesktop.org Date: Mon, 16 Dec 2019 01:23:07 +0200 Message-Id: <20191215232308.14668-4-stanislav.lisovskiy@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191215232308.14668-1-stanislav.lisovskiy@intel.com> References: <20191215232308.14668-1-stanislav.lisovskiy@intel.com> Subject: [Intel-gfx] [PATCH v9 3/4] drm/i915: Manipulate DBuf slices properly 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: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Start manipulating DBuf slices as a mask, but not as a total number, as current approach doesn't give us full control on all combinations of slices, which we might need(like enabling S2 only can't enabled by setting enabled_slices=1). Removed wrong code from intel_get_ddb_size as it doesn't match to BSpec. For now still just use DBuf slice until proper algorithm is implemented. Other minor code refactoring to get prepared for major DBuf assignment changes landed: - As now enabled slices contain a mask we still need some value which should reflect how much DBuf slices are supported by the platform, now device info contains num_supported_dbuf_slices. - Removed unneeded assertion as we are now manipulating slices in a more proper way. v2: Start using enabled_slices in dev_priv v3: "enabled_slices" is now "enabled_dbuf_slices_mask", as this now sits in dev_priv independently. v4: - Fixed debug print formatting to hex(Matt Roper) - Optimized dbuf slice updates to be used only if slice union is different from current conf(Matt Roper) - Fixed some functions to be static(Matt Roper) - Created a parameterized version for DBUF_CTL to simplify DBuf programming cycle(Matt Roper) - Removed unrequred field from GEN10_FEATURES(Matt Roper) Signed-off-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/display/intel_display.c | 23 ++--- .../drm/i915/display/intel_display_power.c | 86 +++++++------------ .../drm/i915/display/intel_display_power.h | 4 +- .../drm/i915/display/intel_display_types.h | 2 +- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_pci.c | 5 +- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_device_info.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 50 +++-------- drivers/gpu/drm/i915/intel_pm.h | 2 +- 10 files changed, 68 insertions(+), 108 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 73d9c275bc20..eeb11683702e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -13362,12 +13362,12 @@ static void verify_wm_state(struct intel_crtc *crtc, skl_pipe_ddb_get_hw_state(crtc, hw->ddb_y, hw->ddb_uv); - hw_enabled_slices = intel_enabled_dbuf_slices_num(dev_priv); + hw_enabled_slices = intel_enabled_dbuf_slices_mask(dev_priv); if (INTEL_GEN(dev_priv) >= 11 && - hw_enabled_slices != dev_priv->enabled_dbuf_slices_num) - DRM_ERROR("mismatch in DBUF Slices (expected %u, got %u)\n", - dev_priv->enabled_dbuf_slices_num, + hw_enabled_slices != dev_priv->enabled_dbuf_slices_mask) + DRM_ERROR("mismatch in DBUF Slices (expected 0x%x, got 0x%x)\n", + dev_priv->enabled_dbuf_slices_mask, hw_enabled_slices); /* planes */ @@ -14552,22 +14552,23 @@ static void intel_update_trans_port_sync_crtcs(struct intel_crtc *crtc, static void icl_dbuf_slice_pre_update(struct intel_atomic_state *state) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); - u8 hw_enabled_slices = dev_priv->enabled_dbuf_slices_num; - u8 required_slices = state->enabled_dbuf_slices_num; + u8 hw_enabled_slices = dev_priv->enabled_dbuf_slices_mask; + u8 required_slices = state->enabled_dbuf_slices_mask; + u8 slices_union = hw_enabled_slices | required_slices; /* If 2nd DBuf slice required, enable it here */ - if (INTEL_GEN(dev_priv) >= 11 && required_slices > hw_enabled_slices) - icl_dbuf_slices_update(dev_priv, required_slices); + if (INTEL_GEN(dev_priv) >= 11 && slices_union != hw_enabled_slices) + icl_dbuf_slices_update(dev_priv, slices_union); } static void icl_dbuf_slice_post_update(struct intel_atomic_state *state) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); - u8 hw_enabled_slices = dev_priv->enabled_dbuf_slices_num; - u8 required_slices = state->enabled_dbuf_slices_num; + u8 hw_enabled_slices = dev_priv->enabled_dbuf_slices_mask; + u8 required_slices = state->enabled_dbuf_slices_mask; /* If 2nd DBuf slice is no more required disable it */ - if (INTEL_GEN(dev_priv) >= 11 && required_slices < hw_enabled_slices) + if (INTEL_GEN(dev_priv) >= 11 && required_slices != hw_enabled_slices) icl_dbuf_slices_update(dev_priv, required_slices); } diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index d8058cc61e45..480bda51add3 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -1026,15 +1026,6 @@ static bool gen9_dc_off_power_well_enabled(struct drm_i915_private *dev_priv, (I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5_DC6_MASK) == 0); } -static void gen9_assert_dbuf_enabled(struct drm_i915_private *dev_priv) -{ - u32 tmp = I915_READ(DBUF_CTL); - - WARN((tmp & (DBUF_POWER_STATE | DBUF_POWER_REQUEST)) != - (DBUF_POWER_STATE | DBUF_POWER_REQUEST), - "Unexpected DBuf power power state (0x%08x)\n", tmp); -} - static void gen9_disable_dc_states(struct drm_i915_private *dev_priv) { struct intel_cdclk_state cdclk_state = {}; @@ -1050,8 +1041,6 @@ static void gen9_disable_dc_states(struct drm_i915_private *dev_priv) /* Can't read out voltage_level so can't use intel_cdclk_changed() */ WARN_ON(intel_cdclk_needs_modeset(&dev_priv->cdclk.hw, &cdclk_state)); - gen9_assert_dbuf_enabled(dev_priv); - if (IS_GEN9_LP(dev_priv)) bxt_verify_ddi_phy_power_wells(dev_priv); @@ -4396,72 +4385,57 @@ static void gen9_dbuf_disable(struct drm_i915_private *dev_priv) intel_dbuf_slice_set(dev_priv, DBUF_CTL, false); } -static u8 intel_dbuf_max_slices(struct drm_i915_private *dev_priv) +static int intel_dbuf_max_slices(struct drm_i915_private *dev_priv) { - if (INTEL_GEN(dev_priv) < 11) - return 1; - return 2; + return INTEL_INFO(dev_priv)->num_supported_dbuf_slices; +} + +static void icl_program_dbuf_slices(struct drm_i915_private *dev_priv) +{ + const u8 hw_enabled_slices = dev_priv->enabled_dbuf_slices_mask; + + icl_dbuf_slices_update(dev_priv, hw_enabled_slices); } void icl_dbuf_slices_update(struct drm_i915_private *dev_priv, u8 req_slices) { - const u8 hw_enabled_slices = dev_priv->enabled_dbuf_slices_num; - bool ret; + int i; + int max_slices = intel_dbuf_max_slices(dev_priv); - if (req_slices > intel_dbuf_max_slices(dev_priv)) { + if (hweight8(req_slices) > intel_dbuf_max_slices(dev_priv)) { DRM_ERROR("Invalid number of dbuf slices requested\n"); return; } - if (req_slices == hw_enabled_slices || req_slices == 0) - return; + DRM_DEBUG_KMS("Updating dbuf slices to 0x%x\n", req_slices); - if (req_slices > hw_enabled_slices) - ret = intel_dbuf_slice_set(dev_priv, DBUF_CTL_S2, true); - else - ret = intel_dbuf_slice_set(dev_priv, DBUF_CTL_S2, false); + for (i = 0; i < max_slices; i++) { + intel_dbuf_slice_set(dev_priv, + DBUF_CTL_S(BIT(i)), + req_slices & BIT(i)); + } - if (ret) - dev_priv->enabled_dbuf_slices_num = req_slices; + dev_priv->enabled_dbuf_slices_mask = req_slices; } static void icl_dbuf_enable(struct drm_i915_private *dev_priv) { - I915_WRITE(DBUF_CTL_S1, I915_READ(DBUF_CTL_S1) | DBUF_POWER_REQUEST); - I915_WRITE(DBUF_CTL_S2, I915_READ(DBUF_CTL_S2) | DBUF_POWER_REQUEST); - POSTING_READ(DBUF_CTL_S2); - - udelay(10); - - if (!(I915_READ(DBUF_CTL_S1) & DBUF_POWER_STATE) || - !(I915_READ(DBUF_CTL_S2) & DBUF_POWER_STATE)) - DRM_ERROR("DBuf power enable timeout\n"); - else - /* - * FIXME: for now pretend that we only have 1 slice, see - * intel_enabled_dbuf_slices_num(). - */ - dev_priv->enabled_dbuf_slices_num = 1; + /* + * Just power up 1 slice, we will + * figure out later which slices we have and what we need. + */ + dev_priv->enabled_dbuf_slices_mask = DBUF_S1_BIT; + icl_program_dbuf_slices(dev_priv); } static void icl_dbuf_disable(struct drm_i915_private *dev_priv) { - I915_WRITE(DBUF_CTL_S1, I915_READ(DBUF_CTL_S1) & ~DBUF_POWER_REQUEST); - I915_WRITE(DBUF_CTL_S2, I915_READ(DBUF_CTL_S2) & ~DBUF_POWER_REQUEST); - POSTING_READ(DBUF_CTL_S2); - - udelay(10); - - if ((I915_READ(DBUF_CTL_S1) & DBUF_POWER_STATE) || - (I915_READ(DBUF_CTL_S2) & DBUF_POWER_STATE)) - DRM_ERROR("DBuf power disable timeout!\n"); - else - /* - * FIXME: for now pretend that the first slice is always - * enabled, see intel_enabled_dbuf_slices_num(). - */ - dev_priv->enabled_dbuf_slices_num = 1; + /* + * Disable all slices + */ + dev_priv->enabled_dbuf_slices_mask = 0; + icl_program_dbuf_slices(dev_priv); } static void icl_mbus_init(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index 1da04f3e0fb3..ed694de48328 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -311,9 +311,11 @@ intel_display_power_put_async(struct drm_i915_private *i915, for ((wf) = intel_display_power_get((i915), (domain)); (wf); \ intel_display_power_put_async((i915), (domain), (wf)), (wf) = 0) +#define DBUF_S1_BIT BIT(0) +#define DBUF_S2_BIT BIT(1) + void icl_dbuf_slices_update(struct drm_i915_private *dev_priv, u8 req_slices); - void chv_phy_powergate_lanes(struct intel_encoder *encoder, bool override, unsigned int mask); bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy, diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 70e65c2d525d..ba2e41a03051 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -518,7 +518,7 @@ struct intel_atomic_state { struct skl_ddb_values wm_results; /* Number of enabled DBuf slices */ - u8 enabled_dbuf_slices_num; + u8 enabled_dbuf_slices_mask; struct i915_sw_fence commit_ready; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7a2d9fa5a9a6..ec4b9e3cef79 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1210,7 +1210,7 @@ struct drm_i915_private { bool distrust_bios_wm; } wm; - u8 enabled_dbuf_slices_num; /* GEN11 has configurable 2 slices */ + u8 enabled_dbuf_slices_mask; /* GEN11 has configurable 2 slices */ struct dram_info { bool valid; diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 9571611b4b16..62998cf1ce0a 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -615,7 +615,8 @@ static const struct intel_device_info intel_cherryview_info = { .has_gt_uc = 1, \ .display.has_hdcp = 1, \ .display.has_ipc = 1, \ - .ddb_size = 896 + .ddb_size = 896, \ + .num_supported_dbuf_slices = 1 #define SKL_PLATFORM \ GEN9_FEATURES, \ @@ -650,6 +651,7 @@ static const struct intel_device_info intel_skylake_gt4_info = { #define GEN9_LP_FEATURES \ GEN(9), \ .is_lp = 1, \ + .num_supported_dbuf_slices = 1, \ .display.has_hotplug = 1, \ .engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0), \ .pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), \ @@ -774,6 +776,7 @@ static const struct intel_device_info intel_cannonlake_info = { }, \ GEN(11), \ .ddb_size = 2048, \ + .num_supported_dbuf_slices = 2, \ .has_logical_ring_elsq = 1, \ .color = { .degamma_lut_size = 33, .gamma_lut_size = 262145 } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index cbb4689af432..62efd5ad07a7 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7760,6 +7760,7 @@ enum { #define DBUF_CTL _MMIO(0x45008) #define DBUF_CTL_S1 _MMIO(0x45008) #define DBUF_CTL_S2 _MMIO(0x44FE8) +#define DBUF_CTL_S(X) ((X) == 1 ? DBUF_CTL_S1 : DBUF_CTL_S2) #define DBUF_POWER_REQUEST (1 << 31) #define DBUF_POWER_STATE (1 << 30) #define GEN7_MSG_CTL _MMIO(0x45010) diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h index 2725cb7fc169..7d4d122d2182 100644 --- a/drivers/gpu/drm/i915/intel_device_info.h +++ b/drivers/gpu/drm/i915/intel_device_info.h @@ -180,6 +180,7 @@ struct intel_device_info { } display; u16 ddb_size; /* in blocks */ + u8 num_supported_dbuf_slices; /* number of DBuf slices */ /* Register offsets for the various display pipes and transcoders */ int pipe_offsets[I915_MAX_TRANSCODERS]; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 28a65b931de1..742aeb0b2a01 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3616,26 +3616,21 @@ bool ilk_disable_lp_wm(struct drm_i915_private *dev_priv) return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL); } -u8 intel_enabled_dbuf_slices_num(struct drm_i915_private *dev_priv) +u8 intel_enabled_dbuf_slices_mask(struct drm_i915_private *dev_priv) { - u8 enabled_dbuf_slices_num; - - /* Slice 1 will always be enabled */ - enabled_dbuf_slices_num = 1; + u8 enabled_slices_mask = 0; /* Gen prior to GEN11 have only one DBuf slice */ if (INTEL_GEN(dev_priv) < 11) - return enabled_dbuf_slices_num; + return DBUF_S1_BIT; - /* - * FIXME: for now we'll only ever use 1 slice; pretend that we have - * only that 1 slice enabled until we have a proper way for on-demand - * toggling of the second slice. - */ - if (0 && I915_READ(DBUF_CTL_S2) & DBUF_POWER_STATE) - enabled_dbuf_slices_num++; + if (I915_READ(DBUF_CTL_S1) & DBUF_POWER_STATE) + enabled_slices_mask |= DBUF_S1_BIT; - return enabled_dbuf_slices_num; + if (I915_READ(DBUF_CTL_S2) & DBUF_POWER_STATE) + enabled_slices_mask |= DBUF_S2_BIT; + + return enabled_slices_mask; } /* @@ -3843,8 +3838,6 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv, { struct drm_atomic_state *state = crtc_state->uapi.state; struct intel_atomic_state *intel_state = to_intel_atomic_state(state); - const struct drm_display_mode *adjusted_mode; - u64 total_data_bw; u16 ddb_size = INTEL_INFO(dev_priv)->ddb_size; WARN_ON(ddb_size == 0); @@ -3852,23 +3845,8 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv, if (INTEL_GEN(dev_priv) < 11) return ddb_size - 4; /* 4 blocks for bypass path allocation */ - adjusted_mode = &crtc_state->hw.adjusted_mode; - total_data_bw = total_data_rate * drm_mode_vrefresh(adjusted_mode); - - /* - * 12GB/s is maximum BW supported by single DBuf slice. - * - * FIXME dbuf slice code is broken: - * - must wait for planes to stop using the slice before powering it off - * - plane straddling both slices is illegal in multi-pipe scenarios - * - should validate we stay within the hw bandwidth limits - */ - if (0 && (num_active > 1 || total_data_bw >= GBps(12))) { - intel_state->enabled_dbuf_slices_num = 2; - } else { - intel_state->enabled_dbuf_slices_num = 1; - ddb_size /= 2; - } + intel_state->enabled_dbuf_slices_mask = DBUF_S1_BIT; + ddb_size /= 2; return ddb_size; } @@ -4065,8 +4043,8 @@ void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc, void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv) { - dev_priv->enabled_dbuf_slices_num = - intel_enabled_dbuf_slices_num(dev_priv); + dev_priv->enabled_dbuf_slices_mask = + intel_enabled_dbuf_slices_mask(dev_priv); } /* @@ -5205,7 +5183,7 @@ skl_compute_ddb(struct intel_atomic_state *state) struct intel_crtc *crtc; int ret, i; - state->enabled_dbuf_slices_num = dev_priv->enabled_dbuf_slices_num; + state->enabled_dbuf_slices_mask = dev_priv->enabled_dbuf_slices_mask; for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h index 22fd2daf608e..d60a85421c5a 100644 --- a/drivers/gpu/drm/i915/intel_pm.h +++ b/drivers/gpu/drm/i915/intel_pm.h @@ -32,7 +32,7 @@ void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv); void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv); void ilk_wm_get_hw_state(struct drm_i915_private *dev_priv); void skl_wm_get_hw_state(struct drm_i915_private *dev_priv); -u8 intel_enabled_dbuf_slices_num(struct drm_i915_private *dev_priv); +u8 intel_enabled_dbuf_slices_mask(struct drm_i915_private *dev_priv); void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc, struct skl_ddb_entry *ddb_y, struct skl_ddb_entry *ddb_uv); From patchwork Sun Dec 15 23:23:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Lisovskiy, Stanislav" X-Patchwork-Id: 11293227 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 7809B14B7 for ; Sun, 15 Dec 2019 23:26:09 +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 5F1CC2467A for ; Sun, 15 Dec 2019 23:26:09 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5F1CC2467A 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 BAF2A6E33E; Sun, 15 Dec 2019 23:26:08 +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 D6A836E33E for ; Sun, 15 Dec 2019 23:26:03 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Dec 2019 15:26:03 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,319,1571727600"; d="scan'208";a="246825828" Received: from slisovsk-lenovo-ideapad-720s-13ikb.fi.intel.com ([10.237.72.89]) by fmsmga002.fm.intel.com with ESMTP; 15 Dec 2019 15:26:01 -0800 From: Stanislav Lisovskiy To: intel-gfx@lists.freedesktop.org Date: Mon, 16 Dec 2019 01:23:08 +0200 Message-Id: <20191215232308.14668-5-stanislav.lisovskiy@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191215232308.14668-1-stanislav.lisovskiy@intel.com> References: <20191215232308.14668-1-stanislav.lisovskiy@intel.com> Subject: [Intel-gfx] [PATCH v9 4/4] drm/i915: Correctly map DBUF slices to pipes 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: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Added proper DBuf slice mapping to correspondent pipes, depending on pipe configuration as stated in BSpec. v2: - Remove unneeded braces - Stop using macro for DBuf assignments as it seems to reduce readability. v3: Start using enabled slices mask in dev_priv v4: Renamed "enabled_slices" used in dev_priv to "enabled_dbuf_slices_mask"(Matt Roper) v5: - Removed redundant parameters from intel_get_ddb_size function.(Matt Roper) - Made i915_possible_dbuf_slices static(Matt Roper) - Renamed total_width into total_width_in_range so that it now reflects that this is not a total pipe width but the one in current dbuf slice allowed range for pipe.(Matt Roper) - Removed 4th pipe for ICL in DBuf assignment table(Matt Roper) - Fixed wrong DBuf slice in DBuf table for TGL (Matt Roper) - Added comment regarding why we currently not using pipe ratio for DBuf assignment for ICL Signed-off-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/intel_pm.c | 252 +++++++++++++++++++++++++++++--- 1 file changed, 234 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 742aeb0b2a01..13986de52b5a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3831,13 +3831,27 @@ bool intel_can_enable_sagv(struct intel_atomic_state *state) return true; } -static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv, - const struct intel_crtc_state *crtc_state, - const u64 total_data_rate, - const int num_active) +/* + * Calculate initial DBuf slice offset, based on slice size + * and mask(i.e if slice size is 1024 and second slice is enabled + * offset would be 1024) + */ +static u32 icl_get_first_dbuf_slice_offset(u32 dbuf_slice_mask, + u32 slice_size, u32 ddb_size) +{ + u32 offset = 0; + + if (!dbuf_slice_mask) + return 0; + + offset = (ffs(dbuf_slice_mask) - 1) * slice_size; + + WARN_ON(offset >= ddb_size); + return offset; +} + +static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv) { - struct drm_atomic_state *state = crtc_state->uapi.state; - struct intel_atomic_state *intel_state = to_intel_atomic_state(state); u16 ddb_size = INTEL_INFO(dev_priv)->ddb_size; WARN_ON(ddb_size == 0); @@ -3845,12 +3859,13 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv, if (INTEL_GEN(dev_priv) < 11) return ddb_size - 4; /* 4 blocks for bypass path allocation */ - intel_state->enabled_dbuf_slices_mask = DBUF_S1_BIT; - ddb_size /= 2; - return ddb_size; } +static u32 i915_possible_dbuf_slices(struct drm_i915_private *dev_priv, + int pipe, u32 active_pipes, + const struct intel_crtc_state *crtc_state); + static void skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv, const struct intel_crtc_state *crtc_state, @@ -3862,10 +3877,17 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv, struct intel_atomic_state *intel_state = to_intel_atomic_state(state); struct drm_crtc *for_crtc = crtc_state->uapi.crtc; const struct intel_crtc *crtc; - u32 pipe_width = 0, total_width = 0, width_before_pipe = 0; + u32 pipe_width = 0, total_width_in_range = 0, width_before_pipe = 0; enum pipe for_pipe = to_intel_crtc(for_crtc)->pipe; u16 ddb_size; + u32 ddb_range_size; u32 i; + u32 dbuf_slice_mask; + u32 active_pipes; + u32 offset; + u32 slice_size; + u32 total_slice_mask; + u32 start, end; if (WARN_ON(!state) || !crtc_state->hw.active) { alloc->start = 0; @@ -3875,12 +3897,15 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv, } if (intel_state->active_pipe_changes) - *num_active = hweight8(intel_state->active_pipes); + active_pipes = intel_state->active_pipes; else - *num_active = hweight8(dev_priv->active_pipes); + active_pipes = dev_priv->active_pipes; - ddb_size = intel_get_ddb_size(dev_priv, crtc_state, total_data_rate, - *num_active); + *num_active = hweight8(active_pipes); + + ddb_size = intel_get_ddb_size(dev_priv); + + slice_size = ddb_size / INTEL_INFO(dev_priv)->num_supported_dbuf_slices; /* * If the state doesn't change the active CRTC's or there is no @@ -3899,22 +3924,74 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv, return; } + /* + * Get allowed DBuf slices for correspondent pipe and platform. + */ + dbuf_slice_mask = i915_possible_dbuf_slices(dev_priv, for_pipe, + active_pipes, crtc_state); + + DRM_DEBUG_KMS("DBuf slice mask %x pipe %d active pipes %x\n", + dbuf_slice_mask, + for_pipe, active_pipes); + + /* + * Figure out at which DBuf slice we start, i.e if we start at Dbuf S2 + * and slice size is 1024, the offset would be 1024 + */ + offset = icl_get_first_dbuf_slice_offset(dbuf_slice_mask, + slice_size, ddb_size); + + /* + * Figure out total size of allowed DBuf slices, which is basically + * a number of allowed slices for that pipe multiplied by slice size. + * Inside of this + * range ddb entries are still allocated in proportion to display width. + */ + ddb_range_size = hweight8(dbuf_slice_mask) * slice_size; + /* * Watermark/ddb requirement highly depends upon width of the * framebuffer, So instead of allocating DDB equally among pipes * distribute DDB based on resolution/width of the display. */ + total_slice_mask = dbuf_slice_mask; for_each_new_intel_crtc_in_state(intel_state, crtc, crtc_state, i) { const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; enum pipe pipe = crtc->pipe; int hdisplay, vdisplay; + u32 pipe_dbuf_slice_mask; - if (!crtc_state->hw.enable) + if (!crtc_state->hw.active) + continue; + + pipe_dbuf_slice_mask = i915_possible_dbuf_slices(dev_priv, + pipe, + active_pipes, + crtc_state); + + /* + * According to BSpec pipe can share one dbuf slice with another + * pipes or pipe can use multiple dbufs, in both cases we + * account for other pipes only if they have exactly same mask. + * However we need to account how many slices we should enable + * in total. + */ + total_slice_mask |= pipe_dbuf_slice_mask; + + /* + * Do not account pipes using other slice sets + * luckily as of current BSpec slice sets do not partially + * intersect(pipes share either same one slice or same slice set + * i.e no partial intersection), so it is enough to check for + * equality for now. + */ + if (dbuf_slice_mask != pipe_dbuf_slice_mask) continue; drm_mode_get_hv_timing(adjusted_mode, &hdisplay, &vdisplay); - total_width += hdisplay; + + total_width_in_range += hdisplay; if (pipe < for_pipe) width_before_pipe += hdisplay; @@ -3922,8 +3999,20 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv, pipe_width = hdisplay; } - alloc->start = ddb_size * width_before_pipe / total_width; - alloc->end = ddb_size * (width_before_pipe + pipe_width) / total_width; + intel_state->enabled_dbuf_slices_mask = total_slice_mask; + + start = ddb_range_size * width_before_pipe / total_width_in_range; + end = ddb_range_size * + (width_before_pipe + pipe_width) / total_width_in_range; + + alloc->start = offset + start; + alloc->end = offset + end; + + DRM_DEBUG_KMS("Pipe %d ddb %d-%d\n", for_pipe, + alloc->start, alloc->end); + DRM_DEBUG_KMS("Enabled ddb slices mask %x num supported %d\n", + intel_state->enabled_dbuf_slices_mask, + INTEL_INFO(dev_priv)->num_supported_dbuf_slices); } static int skl_compute_wm_params(const struct intel_crtc_state *crtc_state, @@ -4094,6 +4183,133 @@ skl_plane_downscale_amount(const struct intel_crtc_state *crtc_state, return mul_fixed16(downscale_w, downscale_h); } +struct dbuf_slice_conf_entry { + u32 active_pipes; + u32 dbuf_mask[I915_MAX_PIPES]; +}; + +/* + * Table taken from Bspec 12716 + * Pipes do have some preferred DBuf slice affinity, + * plus there are some hardcoded requirements on how + * those should be distributed for multipipe scenarios. + * For more DBuf slices algorithm can get even more messy + * and less readable, so decided to use a table almost + * as is from BSpec itself - that way it is at least easier + * to compare, change and check. + */ +static struct dbuf_slice_conf_entry icl_allowed_dbufs[] = { + { BIT(PIPE_A), { DBUF_S1_BIT, 0, 0 } }, + { BIT(PIPE_B), { 0, DBUF_S1_BIT, 0 } }, + { BIT(PIPE_C), { 0, 0, DBUF_S2_BIT } }, + { BIT(PIPE_A) | BIT(PIPE_B), { DBUF_S1_BIT, DBUF_S2_BIT, 0} }, + { BIT(PIPE_A) | BIT(PIPE_C), { DBUF_S1_BIT, 0, DBUF_S2_BIT } }, + { BIT(PIPE_B) | BIT(PIPE_C), { 0, DBUF_S1_BIT, DBUF_S2_BIT } }, + { BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), + { DBUF_S1_BIT, DBUF_S1_BIT, DBUF_S2_BIT } } +}; + +/* + * Table taken from Bspec 49255 + * Pipes do have some preferred DBuf slice affinity, + * plus there are some hardcoded requirements on how + * those should be distributed for multipipe scenarios. + * For more DBuf slices algorithm can get even more messy + * and less readable, so decided to use a table almost + * as is from BSpec itself - that way it is at least easier + * to compare, change and check. + */ +static struct dbuf_slice_conf_entry tgl_allowed_dbufs[] = { + { BIT(PIPE_A), { DBUF_S1_BIT | DBUF_S2_BIT, 0, 0, 0 } }, + { BIT(PIPE_B), { 0, DBUF_S1_BIT | DBUF_S2_BIT, 0, 0 } }, + { BIT(PIPE_C), { 0, 0, DBUF_S1_BIT | DBUF_S2_BIT, 0 } }, + { BIT(PIPE_D), { 0, 0, 0, DBUF_S1_BIT | DBUF_S2_BIT } }, + { BIT(PIPE_A) | BIT(PIPE_B), { DBUF_S2_BIT, DBUF_S1_BIT, 0, 0 } }, + { BIT(PIPE_A) | BIT(PIPE_C), { DBUF_S1_BIT, 0, DBUF_S2_BIT, 0 } }, + { BIT(PIPE_A) | BIT(PIPE_D), { DBUF_S1_BIT, 0, 0, DBUF_S2_BIT } }, + { BIT(PIPE_B) | BIT(PIPE_C), { 0, DBUF_S1_BIT, DBUF_S2_BIT, 0 } }, + { BIT(PIPE_B) | BIT(PIPE_D), { 0, DBUF_S1_BIT, 0, DBUF_S2_BIT } }, + { BIT(PIPE_C) | BIT(PIPE_D), { 0, 0, DBUF_S1_BIT, DBUF_S2_BIT } }, + { BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), + { DBUF_S1_BIT, DBUF_S1_BIT, DBUF_S2_BIT, 0 } }, + { BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_D), + { DBUF_S1_BIT, DBUF_S1_BIT, 0, DBUF_S2_BIT } }, + { BIT(PIPE_A) | BIT(PIPE_C) | BIT(PIPE_D), + { DBUF_S1_BIT, 0, DBUF_S2_BIT, DBUF_S2_BIT } }, + { BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), + { 0, DBUF_S1_BIT, DBUF_S2_BIT, DBUF_S2_BIT } }, + { BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), + { DBUF_S1_BIT, DBUF_S1_BIT, DBUF_S2_BIT, DBUF_S2_BIT } }, +}; + +static u32 i915_find_pipe_conf(int pipe, + u32 active_pipes, + const struct dbuf_slice_conf_entry *dbuf_slices, + int size) +{ + int i; + + for (i = 0; i < size; i++) { + if (dbuf_slices[i].active_pipes == active_pipes) + return dbuf_slices[i].dbuf_mask[pipe]; + } + return 0; +} + +/* + * This function finds an entry with same enabled pipe configuration and + * returns correspondent DBuf slice mask as stated in BSpec for particular + * platform. + */ +static u32 icl_possible_dbuf_slices(int pipe, + u32 active_pipes, + const struct intel_crtc_state *crtc_state) +{ + /* + * FIXME: For ICL this is still a bit unclear as prev BSpec revision + * required calculating "pipe ratio" in order to determine + * if one or two slices can be used for single pipe configurations + * as additional constraint to the existing table. + * However based on recent info, it should be not "pipe ratio" + * but rather ratio between pixel_rate and cdclk with additional + * constants, so for now we are using only table until this is + * clarified. Also this is the reason why crtc_state param is + * still here - we will need it once those additional constraints + * pop up. + */ + return i915_find_pipe_conf(pipe, active_pipes, + icl_allowed_dbufs, + ARRAY_SIZE(icl_allowed_dbufs)); +} + +static u32 tgl_possible_dbuf_slices(int pipe, + u32 active_pipes, + const struct intel_crtc_state *crtc_state) +{ + return i915_find_pipe_conf(pipe, active_pipes, + tgl_allowed_dbufs, + ARRAY_SIZE(tgl_allowed_dbufs)); +} + +static u32 i915_possible_dbuf_slices(struct drm_i915_private *dev_priv, + int pipe, u32 active_pipes, + const struct intel_crtc_state *crtc_state) +{ + if (IS_GEN(dev_priv, 11)) + return icl_possible_dbuf_slices(pipe, + active_pipes, + crtc_state); + else if (IS_GEN(dev_priv, 12)) + return tgl_possible_dbuf_slices(pipe, + active_pipes, + crtc_state); + /* + * For anything else just return one slice yet. + * Should be extended for other platforms. + */ + return DBUF_S1_BIT; +} + static u64 skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state,