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
This commit is contained in:
parent
3d890f3287
commit
131288c468
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user