diff options
author | Suraj Kandpal <suraj.kandpal@intel.com> | 2024-02-19 09:36:38 +0300 |
---|---|---|
committer | Animesh Manna <animesh.manna@intel.com> | 2024-02-23 09:20:47 +0300 |
commit | 131288c4681bbc2727f20c4b31c89a93464aa9ca (patch) | |
tree | 151ae904cd88ebe03b7cc371c6900a3fa0d139d0 /drivers/gpu/drm/i915/display | |
parent | 3d890f32877376ac689f752d8b74ecaea0c42232 (diff) | |
download | linux-131288c4681bbc2727f20c4b31c89a93464aa9ca.tar.xz |
drm/i915/lnl: Program PKGC_LATENCY register
If fixed refresh rate program the PKGC_LATENCY register
with the highest latency from level 1 and above LP registers
and program ADDED_WAKE_TIME = DSB execution time.
else program PKGC_LATENCY with all 1's and ADDED_WAKE_TIME as 0.
This is used to improve package C residency by sending the highest
latency tolerance requirement (LTR) when the planes are done with the
frame until the next frame programming window (set context latency,
window 2) starts.
Bspec: 68986
--v2
-Fix indentation [Chaitanya]
--v3
-Take into account if fixed refrersh rate or not [Vinod]
-Added wake time dependengt on DSB execution time [Vinod]
-Use REG_FIELD_PREP [Jani]
-Call program_pkgc_latency from appropriate place [Jani]
-no need for the ~0 while setting max latency [Jani]
-change commit message to add the new changes made in.
--v4
-Remove extra blank line [Vinod]
-move the vrr.enable check to previous loop [Vinod]
Signed-off-by: Suraj Kandpal <suraj.kandpal@intel.com>
Reviewed-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Reviewed-by: Vinod Govindapillai <vinod.govindapillai@intel.com>
Signed-off-by: Animesh Manna <animesh.manna@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240219063638.1467114-1-suraj.kandpal@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/display')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_dsb.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/skl_watermark.c | 54 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/skl_watermark.h | 4 |
3 files changed, 55 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index a6c7122fd671..d62e050185e7 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -325,7 +325,7 @@ static int intel_dsb_dewake_scanline(const struct intel_crtc_state *crtc_state) { struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - unsigned int latency = skl_watermark_max_latency(i915); + unsigned int latency = skl_watermark_max_latency(i915, 0); int vblank_start; if (crtc_state->vrr.enable) { diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 614f319d754e..c6b9be80d83c 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -23,6 +23,12 @@ #include "skl_watermark.h" #include "skl_watermark_regs.h" +/*It is expected that DSB can do posted writes to every register in + * the pipe and planes within 100us. For flip queue use case, the + * recommended DSB execution time is 100us + one SAGV block time. + */ +#define DSB_EXE_TIME 100 + static void skl_sagv_disable(struct drm_i915_private *i915); /* Stores plane specific WM parameters */ @@ -2904,12 +2910,51 @@ static int skl_wm_add_affected_planes(struct intel_atomic_state *state, return 0; } +/* + * If Fixed Refresh Rate: + * Program DEEP PKG_C_LATENCY Pkg C with highest valid latency from + * watermark level1 and up and above. If watermark level 1 is + * invalid program it with all 1's. + * Program PKG_C_LATENCY Added Wake Time = DSB execution time + * If Variable Refresh Rate: + * Program DEEP PKG_C_LATENCY Pkg C with all 1's. + * Program PKG_C_LATENCY Added Wake Time = 0 + */ +static void +skl_program_dpkgc_latency(struct drm_i915_private *i915, bool vrr_enabled) +{ + u32 max_latency = 0; + u32 clear = 0, val = 0; + u32 added_wake_time = 0; + + if (DISPLAY_VER(i915) < 20) + return; + + if (vrr_enabled) { + max_latency = LNL_PKG_C_LATENCY_MASK; + added_wake_time = 0; + } else { + max_latency = skl_watermark_max_latency(i915, 1); + if (max_latency == 0) + max_latency = LNL_PKG_C_LATENCY_MASK; + added_wake_time = DSB_EXE_TIME + + i915->display.sagv.block_time_us; + } + + clear |= LNL_ADDED_WAKE_TIME_MASK | LNL_PKG_C_LATENCY_MASK; + val |= REG_FIELD_PREP(LNL_PKG_C_LATENCY_MASK, max_latency); + val |= REG_FIELD_PREP(LNL_ADDED_WAKE_TIME_MASK, added_wake_time); + + intel_uncore_rmw(&i915->uncore, LNL_PKG_C_LATENCY, clear, val); +} + static int skl_compute_wm(struct intel_atomic_state *state) { struct intel_crtc *crtc; struct intel_crtc_state __maybe_unused *new_crtc_state; int ret, i; + bool vrr_enabled = false; for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { ret = skl_build_pipe_wm(state, crtc); @@ -2934,8 +2979,13 @@ skl_compute_wm(struct intel_atomic_state *state) ret = skl_wm_add_affected_planes(state, crtc); if (ret) return ret; + + if (new_crtc_state->vrr.enable) + vrr_enabled = true; } + skl_program_dpkgc_latency(to_i915(state->base.dev), vrr_enabled); + skl_print_wm_changes(state); return 0; @@ -3731,11 +3781,11 @@ void skl_watermark_debugfs_register(struct drm_i915_private *i915) &intel_sagv_status_fops); } -unsigned int skl_watermark_max_latency(struct drm_i915_private *i915) +unsigned int skl_watermark_max_latency(struct drm_i915_private *i915, int initial_wm_level) { int level; - for (level = i915->display.wm.num_levels - 1; level >= 0; level--) { + for (level = i915->display.wm.num_levels - 1; level >= initial_wm_level; level--) { unsigned int latency = skl_wm_latency(i915, level, NULL); if (latency) diff --git a/drivers/gpu/drm/i915/display/skl_watermark.h b/drivers/gpu/drm/i915/display/skl_watermark.h index fb0da36fd3ec..e3d1d74a7b17 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.h +++ b/drivers/gpu/drm/i915/display/skl_watermark.h @@ -46,8 +46,8 @@ void skl_watermark_ipc_update(struct drm_i915_private *i915); bool skl_watermark_ipc_enabled(struct drm_i915_private *i915); void skl_watermark_debugfs_register(struct drm_i915_private *i915); -unsigned int skl_watermark_max_latency(struct drm_i915_private *i915); - +unsigned int skl_watermark_max_latency(struct drm_i915_private *i915, + int initial_wm_level); void skl_wm_init(struct drm_i915_private *i915); struct intel_dbuf_state { |