Skip to content

Commit a69dcaf

Browse files
committed
drm/i915/dsb: Account for VRR properly in DSB scanline stuff
When determining various scanlines for DSB use we should take into account whether VRR is active at the time when the DSB uses said scanline information. For now all DSB scanline usage occurs prior to the actual commit, so we only need to care about the state of VRR at that time. I've decided to move intel_crtc_scanline_to_hw() in its entirety to the DSB code as it will also need to know the actual state of VRR in order to do its job 100% correctly. TODO: figure out how much of this could be moved to some more generic place and perhaps be shared with the CPU vblank evasion code/etc... Signed-off-by: Ville Syrjälä <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Reviewed-by: Animesh Manna <[email protected]>
1 parent eb4556f commit a69dcaf

File tree

5 files changed

+67
-18
lines changed

5 files changed

+67
-18
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,8 +1032,8 @@ static bool intel_crtc_vrr_enabling(struct intel_atomic_state *state,
10321032
vrr_params_changed(old_crtc_state, new_crtc_state)));
10331033
}
10341034

1035-
static bool intel_crtc_vrr_disabling(struct intel_atomic_state *state,
1036-
struct intel_crtc *crtc)
1035+
bool intel_crtc_vrr_disabling(struct intel_atomic_state *state,
1036+
struct intel_crtc *crtc)
10371037
{
10381038
const struct intel_crtc_state *old_crtc_state =
10391039
intel_atomic_get_old_crtc_state(state, crtc);

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,9 @@ void intel_plane_fixup_bitmasks(struct intel_crtc_state *crtc_state);
532532

533533
void intel_update_watermarks(struct drm_i915_private *i915);
534534

535+
bool intel_crtc_vrr_disabling(struct intel_atomic_state *state,
536+
struct intel_crtc *crtc);
537+
535538
/* modesetting */
536539
int intel_modeset_pipes_in_mask_early(struct intel_atomic_state *state,
537540
const char *reason, u8 pipe_mask);

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

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,72 @@ struct intel_dsb {
8383
#define DSB_OPCODE_POLL 0xA
8484
/* see DSB_REG_VALUE_MASK */
8585

86-
static int dsb_dewake_scanline(const struct intel_crtc_state *crtc_state)
86+
static bool pre_commit_is_vrr_active(struct intel_atomic_state *state,
87+
struct intel_crtc *crtc)
8788
{
88-
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
89+
const struct intel_crtc_state *old_crtc_state =
90+
intel_atomic_get_old_crtc_state(state, crtc);
91+
const struct intel_crtc_state *new_crtc_state =
92+
intel_atomic_get_new_crtc_state(state, crtc);
93+
94+
/* VRR will be enabled afterwards, if necessary */
95+
if (intel_crtc_needs_modeset(new_crtc_state))
96+
return false;
97+
98+
/* VRR will have been disabled during intel_pre_plane_update() */
99+
return old_crtc_state->vrr.enable && !intel_crtc_vrr_disabling(state, crtc);
100+
}
101+
102+
static const struct intel_crtc_state *
103+
pre_commit_crtc_state(struct intel_atomic_state *state,
104+
struct intel_crtc *crtc)
105+
{
106+
const struct intel_crtc_state *old_crtc_state =
107+
intel_atomic_get_old_crtc_state(state, crtc);
108+
const struct intel_crtc_state *new_crtc_state =
109+
intel_atomic_get_new_crtc_state(state, crtc);
110+
111+
/*
112+
* During fastsets/etc. the transcoder is still
113+
* running with the old timings at this point.
114+
*/
115+
if (intel_crtc_needs_modeset(new_crtc_state))
116+
return new_crtc_state;
117+
else
118+
return old_crtc_state;
119+
}
120+
121+
static int dsb_vtotal(struct intel_atomic_state *state,
122+
struct intel_crtc *crtc)
123+
{
124+
const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc);
125+
126+
if (pre_commit_is_vrr_active(state, crtc))
127+
return crtc_state->vrr.vmax;
128+
else
129+
return intel_mode_vtotal(&crtc_state->hw.adjusted_mode);
130+
}
131+
132+
static int dsb_dewake_scanline(struct intel_atomic_state *state,
133+
struct intel_crtc *crtc)
134+
{
135+
const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc);
136+
struct drm_i915_private *i915 = to_i915(state->base.dev);
89137
unsigned int latency = skl_watermark_max_latency(i915, 0);
90138

91139
return intel_mode_vdisplay(&crtc_state->hw.adjusted_mode) -
92140
intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, latency);
93141
}
94142

143+
static int dsb_scanline_to_hw(struct intel_atomic_state *state,
144+
struct intel_crtc *crtc, int scanline)
145+
{
146+
const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc);
147+
int vtotal = dsb_vtotal(state, crtc);
148+
149+
return (scanline + vtotal - intel_crtc_scanline_offset(crtc_state)) % vtotal;
150+
}
151+
95152
static u32 dsb_chicken(struct intel_crtc *crtc)
96153
{
97154
if (crtc->mode_flags & I915_MODE_FLAG_VRR)
@@ -487,8 +544,6 @@ struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state,
487544
unsigned int max_cmds)
488545
{
489546
struct drm_i915_private *i915 = to_i915(state->base.dev);
490-
const struct intel_crtc_state *crtc_state =
491-
intel_atomic_get_new_crtc_state(state, crtc);
492547
intel_wakeref_t wakeref;
493548
struct intel_dsb *dsb;
494549
unsigned int size;
@@ -524,7 +579,7 @@ struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state,
524579
dsb->ins_start_offset = 0;
525580

526581
dsb->hw_dewake_scanline =
527-
intel_crtc_scanline_to_hw(crtc_state, dsb_dewake_scanline(crtc_state));
582+
dsb_scanline_to_hw(state, crtc, dsb_dewake_scanline(state, crtc));
528583

529584
return dsb;
530585

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

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ static u32 __intel_get_crtc_scanline_from_timestamp(struct intel_crtc *crtc)
190190
return scanline;
191191
}
192192

193-
static int intel_crtc_scanline_offset(const struct intel_crtc_state *crtc_state)
193+
int intel_crtc_scanline_offset(const struct intel_crtc_state *crtc_state)
194194
{
195195
struct intel_display *display = to_intel_display(crtc_state);
196196
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
@@ -284,14 +284,6 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc)
284284
return (position + vtotal + crtc->scanline_offset) % vtotal;
285285
}
286286

287-
int intel_crtc_scanline_to_hw(const struct intel_crtc_state *crtc_state,
288-
int scanline)
289-
{
290-
int vtotal = intel_mode_vtotal(&crtc_state->hw.adjusted_mode);
291-
292-
return (scanline + vtotal - intel_crtc_scanline_offset(crtc_state)) % vtotal;
293-
}
294-
295287
/*
296288
* The uncore version of the spin lock functions is used to decide
297289
* whether we need to lock the uncore lock or not. This is only

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ void intel_wait_for_pipe_scanline_stopped(struct intel_crtc *crtc);
4040
void intel_wait_for_pipe_scanline_moving(struct intel_crtc *crtc);
4141
void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state,
4242
bool vrr_enable);
43-
int intel_crtc_scanline_to_hw(const struct intel_crtc_state *crtc_state,
44-
int scanline);
43+
int intel_crtc_scanline_offset(const struct intel_crtc_state *crtc_state);
4544

4645
#endif /* __INTEL_VBLANK_H__ */

0 commit comments

Comments
 (0)