All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] drm/i915: VRR with the pipe joiner
@ 2026-11-14  1:43 ElXreno
  2026-11-14  1:43 ` [PATCH 1/7] drm/i915/panel: Fix the pixel clock overflow in the VRR vtotal ElXreno
                   ` (6 more replies)
  0 siblings, 7 replies; 15+ messages in thread
From: ElXreno @ 2026-11-14  1:43 UTC (permalink / raw)
  To: intel-gfx, intel-xe
  Cc: jani.nikula, rodrigo.vivi, joonas.lahtinen, tursulin,
	ville.syrjala, ankit.k.nautiyal, mitulkumar.ajitkumar.golani,
	airlied, simona, dri-devel, linux-kernel, ElXreno

This series allows VRR on modes that need the pipe joiner, such as
3840x2400@240 on the eDP panels of current 18" laptops. So far such
modes are kept on the fixed refresh rate timing generator.

What was missing is the sequencing of the transcoder level VRR
operations (timings, enable, disable, push) against the pipe level
updates of the joined pipes [1][2]; joiner + fixed_rr went in as the
first step [3], commit 0ec46988ae6c ("drm/i915/vrr: Allow fixed_rr
with pipe joiner"). Here the sequencing is done on the MMIO path: all
joined pipes are armed inside one vblank evasion critical section on
the primary, which then sends the push.

Tested on one machine (BOE NE180QA1-MM1 on Arrow Lake-HX, DSC, pipes
A+B) with a backport to 7.3.4. On drm-tip it is build tested only.

 - patches 1 and 2 fix two int overflows that a 2342.4 MHz pixel
   clock runs into
 - patch 3 leaves the VRR timings, enable, disable and push to the
   joiner primary
 - patches 4 and 5 arm all joined pipes inside one vblank evasion
   critical section when VRR is in use, with the push at its end
 - patch 6 makes the per pipe vblank evasion that is left look at the
   scanline counter of the primary
 - patch 7 allows VRR with the joiner and keeps such commits off the
   DSB

Why not the DSB: each pipe runs its own DSB and nothing orders them
against the push. A port that only skips the push on the secondaries
gave "DSB 0 timed out waiting for idle" on the secondary 13 times in
27 minutes, details in patch 7. I don't know whether the DSB of the
primary could write the plane registers of the other pipes, which
would allow one DSB for all joined pipes. If it can, that is the
better end state and I'd be glad to hear it.

Why one critical section: with one evasion per pipe the secondary can
latch at the vmax boundary a frame ahead of the primary. Sampling
PLANE_SURFLIVE of both pipes through MMIO, the halves of the screen
showed different frames for one frame in 9 of 20777 frames over
three runs with the per pipe sections forced.

With the series, same machine and method:

 - no such frame in 18028 frames of plain flips with VRR on, no DSB,
   vblank evasion or push errors
 - the joined critical section takes 15 us on average for the two
   pipes, against the 100 us the evasion allows; 49 of 71983 took 60
   to 188 us on a stalled MMIO write, which the per pipe sections
   without VRR show as well (patch 5)
 - the flip event follows the new surface going live by a median
   12 us, and content at a steady 240 fps is paced at 4.17 ms at p50,
   p95 and p99
 - VRR can be toggled at run time. With LUTs loaded, as here, turning
   it off is a joined commit with the colour DSBs, turning it on
   takes the per pipe sections with the vblank worker

Still on the per pipe sections with VRR and the joiner, and so still
able to latch the pipes a frame apart: modesets, the atomic fallback
of a legacy cursor update, async flips, DDB changes, and commits that
need the vblank worker for the LUT load. On the platforms with double
buffered LUTs the latter stay joined and load the LUTs of all joined
pipes with MMIO inside the critical section, which I could not
measure. LRR and DC balance are kept off with the joiner. The commit
sequence of a joined configuration without VRR and the guardband
computation are not changed.

Not tested: IGT, anything on drm-tip beyond the build (i915 and xe),
LNL and later (PSR/Panel Replay with VRR and their guardband terms,
double buffered LUTs, the always on VRR timing generator), PSR2/Panel
Replay with the joiner, the ultrajoiner, anything but eDP, a colour
update that changes the LUTs while VRR stays on, and the refresh
rate change that patch 1 fixes. Suspend/resume was only run on an
earlier version.

The base EDID range of the panel ends at 120 Hz, 240 Hz is only in
its DisplayID Adaptive-Sync block, so testing this needs "drm/edid:
Read the monitor range from the DisplayID Adaptive-Sync block", sent
separately to dri-devel [4].

On tooling, per Documentation/process/generated-content.rst: this
series was written with an LLM coding assistant (Claude Code). It did
the source and mailing list archive analysis, wrote the patches, the
changelogs and the measurement scripts, and ran the measurements on my
machine under my direction. The scripts are in [5]. I have reviewed
all of it and take responsibility for the result.

[1] https://lore.kernel.org/intel-gfx/20250224061717.1095226-14-ankit.k.nautiyal@intel.com/
[2] https://lore.kernel.org/intel-gfx/Z7N9RHhQDltsygA_@intel.com/
[3] https://lore.kernel.org/intel-gfx/Z78vx24DwelqHTc9@intel.com/
[4] https://lore.kernel.org/r/20261114010749.1949247-1-elxreno@gmail.com
[5] https://gist.github.com/ElXreno/c2e6e6f34b056efaf99c238772cf74a3

ElXreno (7):
  drm/i915/panel: Fix the pixel clock overflow in the VRR vtotal
  drm/i915/vrr: Fix the pixel clock overflow in the vmax computation
  drm/i915/vrr: Leave the transcoder to the joiner primary
  drm/i915: Split intel_update_crtc() into its stages
  drm/i915: Arm joined pipes within one vblank evasion for VRR
  drm/i915: Evade the vblank on the scanline of the joiner primary
  drm/i915/vrr: Allow VRR with the pipe joiner

 drivers/gpu/drm/i915/display/intel_color.c   |   4 +
 drivers/gpu/drm/i915/display/intel_crtc.c    |   2 +-
 drivers/gpu/drm/i915/display/intel_crtc.h    |   1 +
 drivers/gpu/drm/i915/display/intel_display.c | 189 +++++++++++++++----
 drivers/gpu/drm/i915/display/intel_panel.c   |   4 +-
 drivers/gpu/drm/i915/display/intel_vblank.c  |  12 +-
 drivers/gpu/drm/i915/display/intel_vblank.h  |   2 +-
 drivers/gpu/drm/i915/display/intel_vrr.c     |  56 ++++--
 drivers/gpu/drm/i915/display/intel_vrr.h     |   1 +
 9 files changed, 217 insertions(+), 54 deletions(-)


base-commit: f40cc5e715fe9e7a5e61f7cd44f63f68c1625f2c
prerequisite-patch-id: c7f9956bca76130b71364377ca611051a16f466c
-- 
2.56.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2026-11-14  2:24 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-14  1:43 [PATCH 0/7] drm/i915: VRR with the pipe joiner ElXreno
2026-11-14  1:43 ` [PATCH 1/7] drm/i915/panel: Fix the pixel clock overflow in the VRR vtotal ElXreno
2026-11-14  1:54   ` sashiko-bot
2026-11-14  1:43 ` [PATCH 2/7] drm/i915/vrr: Fix the pixel clock overflow in the vmax computation ElXreno
2026-11-14  1:52   ` sashiko-bot
2026-11-14  1:43 ` [PATCH 3/7] drm/i915/vrr: Leave the transcoder to the joiner primary ElXreno
2026-11-14  1:56   ` sashiko-bot
2026-11-14  1:43 ` [PATCH 4/7] drm/i915: Split intel_update_crtc() into its stages ElXreno
2026-11-14  1:48   ` sashiko-bot
2026-11-14  1:43 ` [PATCH 5/7] drm/i915: Arm joined pipes within one vblank evasion for VRR ElXreno
2026-11-14  2:02   ` sashiko-bot
2026-11-14  1:43 ` [PATCH 6/7] drm/i915: Evade the vblank on the scanline of the joiner primary ElXreno
2026-11-14  1:53   ` sashiko-bot
2026-11-14  1:43 ` [PATCH 7/7] drm/i915/vrr: Allow VRR with the pipe joiner ElXreno
2026-11-14  2:24   ` sashiko-bot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.