Skip to content

Commit 9367e41

Browse files
committed
drm/i915: Try to program PKG_C_LATENCY more correctly
The current PKG_C_LATENCY stuff looks busted in several ways: - doesn't account for multiple pipes from different commits correctly - WM_LINETIME is in units of 0.125usec, PKG_C_LATENCY wants units on 1 usec - weird VRR state stuff being checked - use of pointless RMW Fix it all up. Note that it's still a bit unclear how all this works, especially how the added_wake_time ties into the flipq triggers in DMC, and how we need to sequence updates to PKG_C_LATENCY when enabling/disabling pipes/etc. We may also need to think what to about the WM1+ disabling and the related PSR chicken bits when we can use PKG_C_LATENCY for early wake... Signed-off-by: Ville Syrjälä <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Reviewed-by: Uma Shankar <[email protected]>
1 parent 4e3f3ad commit 9367e41

File tree

3 files changed

+61
-43
lines changed

3 files changed

+61
-43
lines changed

drivers/gpu/drm/i915/display/intel_display.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7393,6 +7393,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
73937393
/* Now enable the clocks, plane, pipe, and connectors that we set up. */
73947394
display->funcs.display->commit_modeset_enables(state);
73957395

7396+
/* FIXME probably need to sequence this properly */
73967397
intel_program_dpkgc_latency(state);
73977398

73987399
intel_wait_for_vblank_workers(state);

drivers/gpu/drm/i915/display/intel_display_core.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,12 @@ struct intel_display {
479479
u32 pipestat_irq_mask[I915_MAX_PIPES];
480480
} irq;
481481

482+
struct {
483+
/* protected by wm.wm_mutex */
484+
u16 linetime[I915_MAX_PIPES];
485+
bool disable[I915_MAX_PIPES];
486+
} pkgc;
487+
482488
struct {
483489
wait_queue_head_t waitqueue;
484490

drivers/gpu/drm/i915/display/skl_watermark.c

Lines changed: 54 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2857,64 +2857,75 @@ static int skl_wm_add_affected_planes(struct intel_atomic_state *state,
28572857
return 0;
28582858
}
28592859

2860-
/*
2861-
* If Fixed Refresh Rate or For VRR case Vmin = Vmax = Flipline:
2862-
* Program DEEP PKG_C_LATENCY Pkg C with highest valid latency from
2863-
* watermark level1 and up and above. If watermark level 1 is
2864-
* invalid program it with all 1's.
2865-
* Program PKG_C_LATENCY Added Wake Time = DSB execution time
2866-
* If Variable Refresh Rate where Vmin != Vmax != Flipline:
2867-
* Program DEEP PKG_C_LATENCY Pkg C with all 1's.
2868-
* Program PKG_C_LATENCY Added Wake Time = 0
2869-
*/
2860+
static int pkgc_max_linetime(struct intel_atomic_state *state)
2861+
{
2862+
struct intel_display *display = to_intel_display(state);
2863+
const struct intel_crtc_state *crtc_state;
2864+
struct intel_crtc *crtc;
2865+
int i, max_linetime;
2866+
2867+
/*
2868+
* Apparenty the hardware uses WM_LINETIME internally for
2869+
* this stuff, compute everything based on that.
2870+
*/
2871+
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
2872+
display->pkgc.disable[crtc->pipe] = crtc_state->vrr.enable;
2873+
display->pkgc.linetime[crtc->pipe] = DIV_ROUND_UP(crtc_state->linetime, 8);
2874+
}
2875+
2876+
max_linetime = 0;
2877+
for_each_intel_crtc(display->drm, crtc) {
2878+
if (display->pkgc.disable[crtc->pipe])
2879+
return 0;
2880+
2881+
max_linetime = max(display->pkgc.linetime[crtc->pipe], max_linetime);
2882+
}
2883+
2884+
return max_linetime;
2885+
}
2886+
28702887
void
28712888
intel_program_dpkgc_latency(struct intel_atomic_state *state)
28722889
{
28732890
struct intel_display *display = to_intel_display(state);
2874-
struct intel_crtc *crtc;
2875-
struct intel_crtc_state *new_crtc_state;
2876-
u32 latency = LNL_PKG_C_LATENCY_MASK;
2877-
u32 added_wake_time = 0;
2878-
u32 max_linetime = 0;
2879-
u32 clear, val;
2880-
bool fixed_refresh_rate = false;
2881-
int i;
2891+
int max_linetime, latency, added_wake_time = 0;
28822892

28832893
if (DISPLAY_VER(display) < 20)
28842894
return;
28852895

2886-
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
2887-
if (!new_crtc_state->vrr.enable ||
2888-
(new_crtc_state->vrr.vmin == new_crtc_state->vrr.vmax &&
2889-
new_crtc_state->vrr.vmin == new_crtc_state->vrr.flipline))
2890-
fixed_refresh_rate = true;
2896+
mutex_lock(&display->wm.wm_mutex);
28912897

2892-
max_linetime = max(new_crtc_state->linetime, max_linetime);
2893-
}
2898+
latency = skl_watermark_max_latency(display, 1);
28942899

2895-
if (fixed_refresh_rate) {
2896-
latency = skl_watermark_max_latency(display, 1);
2900+
/*
2901+
* Wa_22020432604
2902+
* "PKG_C_LATENCY Added Wake Time field is not working"
2903+
*/
2904+
if (latency && (DISPLAY_VER(display) == 20 || DISPLAY_VER(display) == 30)) {
2905+
latency += added_wake_time;
2906+
added_wake_time = 0;
2907+
}
28972908

2898-
/* Wa_22020432604 */
2899-
if ((DISPLAY_VER(display) == 20 || DISPLAY_VER(display) == 30) && !latency) {
2900-
latency += added_wake_time;
2901-
added_wake_time = 0;
2902-
}
2909+
max_linetime = pkgc_max_linetime(state);
29032910

2904-
/* Wa_22020299601 */
2905-
if ((latency && max_linetime) &&
2906-
(DISPLAY_VER(display) == 20 || DISPLAY_VER(display) == 30)) {
2907-
latency = max_linetime * DIV_ROUND_UP(latency, max_linetime);
2908-
} else if (!latency) {
2909-
latency = LNL_PKG_C_LATENCY_MASK;
2910-
}
2911+
if (max_linetime == 0 || latency == 0) {
2912+
latency = REG_FIELD_GET(LNL_PKG_C_LATENCY_MASK,
2913+
LNL_PKG_C_LATENCY_MASK);
2914+
added_wake_time = 0;
2915+
} else {
2916+
/*
2917+
* Wa_22020299601
2918+
* "Increase the latency programmed in PKG_C_LATENCY Pkg C Latency to be a
2919+
* multiple of the pipeline time from WM_LINETIME"
2920+
*/
2921+
latency = roundup(latency, max_linetime);
29112922
}
29122923

2913-
clear = LNL_ADDED_WAKE_TIME_MASK | LNL_PKG_C_LATENCY_MASK;
2914-
val = REG_FIELD_PREP(LNL_PKG_C_LATENCY_MASK, latency) |
2915-
REG_FIELD_PREP(LNL_ADDED_WAKE_TIME_MASK, added_wake_time);
2924+
intel_de_write(display, LNL_PKG_C_LATENCY,
2925+
REG_FIELD_PREP(LNL_ADDED_WAKE_TIME_MASK, added_wake_time) |
2926+
REG_FIELD_PREP(LNL_PKG_C_LATENCY_MASK, latency));
29162927

2917-
intel_de_rmw(display, LNL_PKG_C_LATENCY, clear, val);
2928+
mutex_unlock(&display->wm.wm_mutex);
29182929
}
29192930

29202931
static int

0 commit comments

Comments
 (0)