Skip to content

Commit 21bb041

Browse files
committed
drm/i915/dsb: Convert dewake_scanline to a hw scanline number earlier
Currently we switch from out software idea of a scanline to the hw's idea of a scanline during the commit phase in _intel_dsb_commit(). While that is slightly easier due to fastsets fiddling with the timings, we'll also need to generate proper hw scanline numbers already when emitting DSB scanline wait instructions. So this approach won't do in the future. Switch to hw scanline numbers earlier. Also intel_dsb_dewake_scanline() itself already makes some assumptions about VRR that don't take into account VRR toggling during fastsets, so technically delaying the sw->hw conversion doesn't even help us. The other reason for delaying the conversion was that we are using intel_get_crtc_scanline() during intel_dsb_commit() which gives us the current sw scanline. But this is pretty low level stuff anyway so just using raw PIPEDSL reads seems fine here, and that of course gives us the hw scanline directly, reducing the need to do so many conversions. v2: Return the non-hw scanline from intel_dsb_dewake_scanline() Reviewed-by: Jani Nikula <[email protected]> Signed-off-by: Ville Syrjälä <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 81a1c37 commit 21bb041

File tree

3 files changed

+18
-15
lines changed

3 files changed

+18
-15
lines changed

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

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "i915_drv.h"
88
#include "i915_irq.h"
9+
#include "i915_reg.h"
910
#include "intel_crtc.h"
1011
#include "intel_de.h"
1112
#include "intel_display_types.h"
@@ -42,7 +43,7 @@ struct intel_dsb {
4243
*/
4344
unsigned int ins_start_offset;
4445

45-
int dewake_scanline;
46+
int hw_dewake_scanline;
4647
};
4748

4849
/**
@@ -374,7 +375,7 @@ static u32 dsb_error_int_en(struct intel_display *display)
374375
}
375376

376377
static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl,
377-
int dewake_scanline)
378+
int hw_dewake_scanline)
378379
{
379380
struct intel_crtc *crtc = dsb->crtc;
380381
struct intel_display *display = to_intel_display(crtc->base.dev);
@@ -404,10 +405,8 @@ static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl,
404405
intel_de_write_fw(display, DSB_HEAD(pipe, dsb->id),
405406
intel_dsb_buffer_ggtt_offset(&dsb->dsb_buf));
406407

407-
if (dewake_scanline >= 0) {
408-
int diff, hw_dewake_scanline;
409-
410-
hw_dewake_scanline = intel_crtc_scanline_to_hw(crtc, dewake_scanline);
408+
if (hw_dewake_scanline >= 0) {
409+
int diff, position;
411410

412411
intel_de_write_fw(display, DSB_PMCTRL(pipe, dsb->id),
413412
DSB_ENABLE_DEWAKE |
@@ -417,7 +416,9 @@ static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl,
417416
* Force DEwake immediately if we're already past
418417
* or close to racing past the target scanline.
419418
*/
420-
diff = dewake_scanline - intel_get_crtc_scanline(crtc);
419+
position = intel_de_read_fw(display, PIPEDSL(display, pipe)) & PIPEDSL_LINE_MASK;
420+
421+
diff = hw_dewake_scanline - position;
421422
intel_de_write_fw(display, DSB_PMCTRL_2(pipe, dsb->id),
422423
(diff >= 0 && diff < 5 ? DSB_FORCE_DEWAKE : 0) |
423424
DSB_BLOCK_DEWAKE_EXTENSION);
@@ -439,7 +440,7 @@ void intel_dsb_commit(struct intel_dsb *dsb,
439440
{
440441
_intel_dsb_commit(dsb,
441442
wait_for_vblank ? DSB_WAIT_FOR_VBLANK : 0,
442-
wait_for_vblank ? dsb->dewake_scanline : -1);
443+
wait_for_vblank ? dsb->hw_dewake_scanline : -1);
443444
}
444445

445446
void intel_dsb_wait(struct intel_dsb *dsb)
@@ -527,7 +528,9 @@ struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state,
527528
dsb->size = size / 4; /* in dwords */
528529
dsb->free_pos = 0;
529530
dsb->ins_start_offset = 0;
530-
dsb->dewake_scanline = intel_dsb_dewake_scanline(crtc_state);
531+
532+
dsb->hw_dewake_scanline =
533+
intel_crtc_scanline_to_hw(crtc_state, intel_dsb_dewake_scanline(crtc_state));
531534

532535
return dsb;
533536

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -284,13 +284,12 @@ 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(struct intel_crtc *crtc, int scanline)
287+
int intel_crtc_scanline_to_hw(const struct intel_crtc_state *crtc_state,
288+
int scanline)
288289
{
289-
const struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base);
290-
const struct drm_display_mode *mode = &vblank->hwmode;
291-
int vtotal = intel_mode_vtotal(mode);
290+
int vtotal = intel_mode_vtotal(&crtc_state->hw.adjusted_mode);
292291

293-
return (scanline + vtotal - crtc->scanline_offset) % vtotal;
292+
return (scanline + vtotal - intel_crtc_scanline_offset(crtc_state)) % vtotal;
294293
}
295294

296295
/*

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ 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(struct intel_crtc *crtc, int scanline);
43+
int intel_crtc_scanline_to_hw(const struct intel_crtc_state *crtc_state,
44+
int scanline);
4445

4546
#endif /* __INTEL_VBLANK_H__ */

0 commit comments

Comments
 (0)