Commit Graph

137 Commits

Author SHA1 Message Date
Ville Syrjälä
237aab5496 drm/i915/vrr: Configure VRR timings after enabling TRANS_DDI_FUNC_CTL
Apparently ICL may hang with an MCE if we write TRANS_VRR_VMAX/FLIPLINE
before enabling TRANS_DDI_FUNC_CTL.

Personally I was only able to reproduce a hang (on an Dell XPS 7390
2-in-1) with an external display connected via a dock using a dodgy
type-C cable that made the link training fail. After the failed
link training the machine would hang. TGL seemed immune to the
problem for whatever reason.

BSpec does tell us to configure VRR after enabling TRANS_DDI_FUNC_CTL
as well. The DMC firmware also does the VRR restore in two stages:
- first stage seems to be unconditional and includes TRANS_VRR_CTL
  and a few other VRR registers, among other things
- second stage is conditional on the DDI being enabled,
  and includes TRANS_DDI_FUNC_CTL and TRANS_VRR_VMAX/VMIN/FLIPLINE,
  among other things

So let's reorder the steps to match to avoid the hang, and
toss in an extra WARN to make sure we don't screw this up later.

BSpec: 22243
Cc: stable@vger.kernel.org
Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reported-by: Benjamin Tissoires <bentiss@kernel.org>
Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15777
Tested-by: Benjamin Tissoires <bentiss@kernel.org>
Fixes: dda7dcd9da ("drm/i915/vrr: Use fixed timings for platforms that support VRR")
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patch.msgid.link/20260303095414.4331-1-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
(cherry picked from commit 93f3a267c3dd4d811b224bb9e179a10d81456a74)
Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
2026-03-10 08:11:29 +00:00
Mitul Golani
5558192707 drm/i915/vrr: Enable DC Balance
Enable DC Balance from vrr compute config and related hw flag.
Also to add pipe restrictions along with this.

--v2:
- Use dc balance check instead of source restriction.
--v3:
- Club pipe restriction check with dc balance enablement. (Ankit)
--v4:
- Separate out Pipe restrictions to patch#7

Signed-off-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Link: https://patch.msgid.link/20251223104542.2688548-19-mitulkumar.ajitkumar.golani@intel.com
2025-12-30 10:02:21 +05:30
Mitul Golani
5786499a42 drm/i915/display: Add function to configure event for dc balance
Configure pipe dmc event for dc balance enable/disable.

--v2:
- Keeping function and removing unnecessary comments. (Jani, Nikula)

Signed-off-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Link: https://patch.msgid.link/20251223104542.2688548-18-mitulkumar.ajitkumar.golani@intel.com
2025-12-30 10:02:21 +05:30
Ville Syrjälä
192bc98c6f drm/i915/vrr: Pause DC Balancing for DSB commits
Pause the DMC DC Balancing for the remainder of the
commit so that vmin/vmax won't change after we've baked
them into the DSB vblank evasion commands.

--v2:
- Remove typo. (Ankit)
- Separate vrr enable structuring. (Ankit)

--v3:
- Add gaurd before accessing DC balance bits.
- Remove redundancy checks.

--v4:
- Move events to separate function.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Link: https://patch.msgid.link/20251223104542.2688548-17-mitulkumar.ajitkumar.golani@intel.com
2025-12-30 10:02:21 +05:30
Mitul Golani
c4aba65c26 drm/i915/display: Wait for VRR PUSH status update
After VRR Push is sent, need to wait till flipline decision boundary
to get Push bit to get cleared.

--v2:
- Adjust delays to vrr vmin vblank delays. (Ankit)

--v3:
- Change intel_vrr_vmin_safe_window_end() so that
intel_dsb_wait_for_delayed_vblank() uses correct delay. (Ankit)

--v4:
- Simplify intel_vrr_vmin_safe_window_end implementation. (Ankit)

Signed-off-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Link: https://patch.msgid.link/20251223104542.2688548-15-mitulkumar.ajitkumar.golani@intel.com
2025-12-30 10:02:20 +05:30
Mitul Golani
4ca36702d8 drm/i915/vrr: Write DC balance params to hw registers
Write DC Balance parameters to hw registers.

--v2:
- Update commit header.
- Separate crtc_state params from this patch. (Ankit)

--v3:
- Write registers at compute config.
- Update condition for write.

--v4:
- Address issue with state checker.

--v5:
- Initialise some more dc balance register while enabling VRR.

--v6:
- FLIPLINE_CFG need to be configure at last, as it is double buffer
arming point.

--v7:
- Initialise and reset live value of vmax and vmin as well.

--v8:
- Add separate functions while writing hw registers. (Ankit)

--v9:
- Add DC Balance counter enable bit to this patch. (Ankit)

--v10:
- Add rigister writes to vrr_enable/disable. (Ankit)

Signed-off-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Link: https://patch.msgid.link/20251223104542.2688548-12-mitulkumar.ajitkumar.golani@intel.com
2025-12-30 10:02:20 +05:30
Mitul Golani
d780bbebaa drm/i915/display: Add DC Balance flip count operations
Track dc balance flip count with params per crtc. Increment
DC Balance Flip count before every flip to indicate DMC
firmware about new flip occurrence which needs to be adjusted
for dc balancing. This is tracked separately from legacy
FLIP_COUNT register also Reset DC balance flip count value
while disabling VRR adaptive mode, this is to start with
fresh counts when VRR adaptive refresh mode is triggered again.

--v2:
- Call during intel_update_crtc.(Ankit)

Signed-off-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Link: https://patch.msgid.link/20251223104542.2688548-11-mitulkumar.ajitkumar.golani@intel.com
2025-12-30 10:02:20 +05:30
Mitul Golani
80d1498359 drm/i915/vrr: Add function to reset DC balance accumulated params
Add function which resets all accumulated DC Balance parameters
whenever adaptive mode of VRR goes off. This helps to give a
fresh start when VRR is re-enabled.

--v2:
- Typo, change crtc_state to old_crtc_state. (Ankit)

Signed-off-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Link: https://patch.msgid.link/20251223104542.2688548-10-mitulkumar.ajitkumar.golani@intel.com
2025-12-30 10:02:20 +05:30
Mitul Golani
7bf11bc2f7 drm/i915/vrr: Add function to check if DC Balance Possible
Add a function that checks if DC Balance enabling is possible on the
requested PIPE. Apart from the DISPLAY_VER check, account for current
firmware limitations, which only allow DC Balance on PIPE A and PIPE B.

v2: Rephrased commit message. (Ankit)

Signed-off-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Link: https://patch.msgid.link/20251223104542.2688548-9-mitulkumar.ajitkumar.golani@intel.com
2025-12-30 10:00:25 +05:30
Mitul Golani
2873c8eaa1 drm/i915/vrr: Add compute config for DC Balance params
Compute DC Balance parameters and tunable params based on
experiments.

--v2:
- Document tunable params. (Ankit)

--v3:
- Add line spaces to compute config. (Ankit)
- Remove redundancy checks.

--v4:
- Separate out conpute config to separate function.
- As all the valuse are being computed in scanlines, and slope
is still in usec, convert and store it to scanlines.

--v5:
- Update and add comments for slope calculation. (Ankit)
- Update early return conditions for dc balance compute. (Ankit)

--v6:
- Early return condition simplified for dc balance compute config. (Ankit)
- Make use of pipe restrictions to this patch. (Ankit)

--v7:
- Separate out PIPE_A and PIPE_B restrictions to other patch.(Ankit)

Signed-off-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Link: https://patch.msgid.link/20251223104542.2688548-8-mitulkumar.ajitkumar.golani@intel.com
2025-12-30 09:59:11 +05:30
Mitul Golani
be843f3480 drm/i915/vrr: Add DC Balance params to crtc_state
Add DC Balance params to crtc_state, also add state checker
params for related properties.

--v3:
- Seggregate crtc_state params with this patch. (Ankit)

--v4:
- Update commit message and header. (Ankit)
- Add +1 to VMIN and VMAX only when it is non-zero. (Ankit)

--v5:
- Add headers in sorted order. (Jani Nikula)

--v6:
- Add a separate function to get and check dc_balance params.
- Avoid repeatative use of MMIO read. (Ankit)

Signed-off-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Link: https://patch.msgid.link/20251223104542.2688548-6-mitulkumar.ajitkumar.golani@intel.com
2025-12-30 09:59:09 +05:30
Ville Syrjälä
19467b46c2 drm/i915/vrr: Add functions to read out vmin/vmax stuff
Calculate delayed vblank start position with the help of added
vmin/vmax stuff for next frame and final computation.

--v2:
- Correct Author details.

--v3:
- Separate register details from this  patch.

--v4:
- Add mask macros.

--v5:
- As live prefix params indicate timings for current frame,
read just _live prefix values instead of next frame timings as
done previously.
- Squash Refactor vrr params patch.

--v6:
- Use error code while returning invalid values. (Jani, Nikula)

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Link: https://patch.msgid.link/20251223104542.2688548-5-mitulkumar.ajitkumar.golani@intel.com
2025-12-30 09:59:08 +05:30
Ville Syrjälä
93e0f7c8a9 drm/i915/de: Include units in intel_de_wait*() function names
intel_de_wait*() take the timeout in milliseconds. Include
that information in the function name to make life less
confusing. I'll also be introducing microsecond variants
of these later.

Done with cocci:
@@
@@
(
static int
- intel_de_wait
+ intel_de_wait_ms
 (...)
{
...
}
|
static int
- intel_de_wait_fw
+ intel_de_wait_fw_ms
 (...)
{
...
}
|
static int
- intel_de_wait_for_set
+ intel_de_wait_for_set_ms
 (...)
{
...
}
|
static int
- intel_de_wait_for_clear
+ intel_de_wait_for_clear_ms
 (...)
{
...
}
)

@@
@@
(
- intel_de_wait
+ intel_de_wait_ms
|
- intel_de_wait_fw
+ intel_de_wait_fw_ms
|
- intel_de_wait_for_set
+ intel_de_wait_for_set_ms
|
- intel_de_wait_for_clear
+ intel_de_wait_for_clear_ms
)

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patch.msgid.link/20251110172756.2132-4-ville.syrjala@linux.intel.com
Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
Acked-by: Jani Nikula <jani.nikula@intel.com>
2025-11-11 19:27:46 +02:00
Ville Syrjälä
4b274b0b61 drm/i915/vrr: Check HAS_VRR() first in intel_vrr_is_capable()
There's no point in doing all the other checks in
intel_vrr_is_capable() if the platform doesn't support VRR at all
Check HAS_VRR() before wasting time on the other checks.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-23-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-10-25 00:10:58 +03:00
Ville Syrjälä
be5fc552b3 drm/i915/vrr: Update the intel_vrr_extra_vblank_delay() comment
The coment in intel_vrr_extra_vblank_delay() is a bit outdated now
that we generally got rid of the "vblank delay" stuff. Update the
comment to better describe the current state of things.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-22-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-10-25 00:10:58 +03:00
Ville Syrjälä
0f4f31d79e drm/i915/vrr: Nuke intel_vrr_vmin_flipline()
Now that intel_vrr_flipline_offset() is completely hidden from the
higher level VRR code, intel_vrr_vmin_flipline() has become rather
pointless. Remove it.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-21-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-10-25 00:10:58 +03:00
Ville Syrjälä
24a23b39fd drm/i915/vrr: Nuke intel_vrr_vblank_exit_length()
Now that we always populate crtc_state->vrr.guardband even on
ICL/TGL intel_vrr_vblank_exit_length() has become rather pointless.
Get rid of it.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-20-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-10-25 00:10:58 +03:00
Ville Syrjälä
cbdf2a930b drm/i915/vrr: s/crtc_state/old_crtc_state/ in intel_vrr_transcoder_disable()
We generally use the 'old_crtc_state' in the disable functions to
make it clear these generally get called when the hardware is
still using the old crtc state rather than the new crtc state.
Rename the intel_vrr_transcoder_disable() 'crtc_state' parameter
to 'old_crtc_state' for consistency.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-19-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-10-25 00:10:58 +03:00
Ville Syrjälä
78ea8eb5b6 drm/i915/vrr: Move HAS_VRR() check into intel_vrr_set_transcoder_timings()
Reduce the clutter in hsw_configure_cpu_transcoder() a bit by moving
the HAS_VRR() check into intel_vrr_set_transcoder_timings().

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-18-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-10-25 00:10:58 +03:00
Ville Syrjälä
065d28dd32 drm/i915/vrr: Remove redundant HAS_VRR() checks
intel_vrr_transcoder_{enable,disable}() already check
for intel_vrr_possible(), so the extra HAS_VRR() checks are
redundant. Remove them.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-17-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-10-25 00:10:58 +03:00
Ville Syrjälä
9a78c6dfd1 drm/i915/vrr: Always write TRANS_VRR_CTL in intel_vrr_set_transcoder_timings() on !always_use_vrr_tg()
Currently, depending on vrr.enable, we may write TRANS_VRR_CTL from
both intel_vrr_set_transcoder_timings() and intel_vrr_transcoder_enable()
on !always_use_vrr_tg() platforms. Streamline this so that we just
always write it from intel_vrr_set_transcoder_timings(), and
never from intel_vrr_transcoder_enable().

The main benefit is that intel_vrr_transcoder_enable() becomes symmetric
to intel_vrr_transcoder_disable().

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-16-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-10-25 00:10:58 +03:00
Ville Syrjälä
b10e7c9255 drm/i915/vrr: Disable VRR TG in intel_vrr_transcoder_disable() only on always use_vrr_tg() platforms
Currently we always disable the VRR timing generator in
intel_vrr_transcoder_disable(). But doing so on !always_use_vrr_tg()
platforms is redundant since we've alreayd disabled the VRR timing
generator earlier in intel_vrr_disable(). Do the disable in
intel_vrr_transcoder_disable() only on always_on_vrr_tg() platforms.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-15-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-10-25 00:10:58 +03:00
Ville Syrjälä
eaa81a600a drm/i915/vrr: Extract intel_vrr_tg_enable()
Extract the VRR timing generator enable into intel_vrr_tg_enable(),
as a counterpart to intel_vrr_tg_disable().

Note that the CMRR part is probably broken, but so are other
things in the CMRR implementation, and thus it is currently
disabled.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-14-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-10-25 00:10:58 +03:00
Ville Syrjälä
c4b44d1820 drm/i915/vrr: Extract intel_vrr_tg_disable()
Now that we always disable the VRR timing generator the same way
we can extract the duplicated code into a helper.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-13-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-10-25 00:10:58 +03:00
Ville Syrjälä
60de042266 drm/i915/vrr: Use trans_vrr_ctl() in intel_vrr_transcoder_disable()
Currently intel_vrr_disable() writes TRANS_VRR_CTL() with
trans_vrr_ctl(), whereas intel_vrr_transcoder_disable() always
writes just a plain 0. Write trans_vrr_ctl() in both places to
unify the code, allowing for more shared code in the future.

Since the VRR timing generator will be disabled by the
TRANS_VRR_CTL write it doesn't really matter what we write to
the register (other than VRR_CTL_VRR_ENABLE that is).

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-12-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-10-25 00:10:58 +03:00
Ville Syrjälä
4353128252 drm/i915/vrr: Move EMP_AS_SDP_TL write into intel_vrr_set_transcoder_timings()
EMP_AS_SDL_TL replaces the TRANS_VRR_VSYNC for the purposes of
setting the AS SDP transmission line. Move the EMP_AS_SDL_TL into
intel_vrr_set_transcoder_timings() since that's where we write
TRANS_VRR_VSYNC as well.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-11-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-10-25 00:10:58 +03:00
Ville Syrjälä
587db4b310 drm/i915/vrr: Avoid redundant TRANS_PUSH write in intel_vrr_enable()
We keep TRANS_PUSH_EN always set for always_use_vrr_tg() platfforms,
so there is no need to write it again in  intel_vrr_enable().

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-10-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-10-25 00:10:58 +03:00
Ville Syrjälä
909cc33702 drm/i915/vrr: Extract intel_vrr_set_vrr_timings()
Extract intel_vrr_set_vrr_timings() as the counterpart to
intel_vrr_set_fixed_rr_timings().

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-9-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-10-25 00:10:58 +03:00
Ville Syrjälä
291119eb18 drm/i915/vrr: Move compute_fixed_rr_timings()
Relocate intel_vrr_compute_fixed_rr_timings() next to its
VRR and CMRR counterparts.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-8-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-10-25 00:10:58 +03:00
Ville Syrjälä
8a553374db drm/i195/vrr: Move crtc_state->vrr.{vmin,vmax} update into intel_vrr_compute_vrr_timings()
The way intel_vrr_compute_*_timings() works is rather confusing.
First intel_vrr_compute_config() assigns the computed vmin/vmax
into crtc_state->vrr.{vmin,vmax}, and then either
intel_vrr_compute_vrr_timings() leaves them untouched or
intel_vrr_compute_{cmrr,fixed_rr}_timings() overwrite them with
something else.

Clean this up by moving all crtc_state->vrr.{vmin,vmax} assignments
into intel_vrr_compute_*_timings().

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-7-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-10-25 00:10:58 +03:00
Ville Syrjälä
4082842e39 drm/i915/vrr: Reorganize intel_vrr_compute_cmrr_timings() a bit
Move the cmrr.enable assignment next to the mode_flags assignment
to keep things in a bit more logical order in
intel_vrr_compute_cmrr_timings().

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-6-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-10-25 00:10:58 +03:00
Ville Syrjälä
a5fac6761c drm/i915/vrr: Compute fixed refresh rate timings the same way as CMRR timings
Unify the VRR timing computation stuff a bit having both the
fixed refresh rate and CMRR cases assign the crtc_state->vrr
stuff in exactly the same way.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251020185038.4272-5-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-10-25 00:10:53 +03:00
Ankit Nautiyal
4ba596539e drm/i915/vrr: Use optimized guardband whenever VRR TG is active
Currently the guardband is optimized only for platforms where the
VRR timing generator is always ON.

Extend the usage of optimized guardband to all VRR supporting platforms.

v2: Drop check for `crtc_state->vrr.enable` and just return true
    unconditionally from intel_vrr_use_optimized_guardband(). (Ville)

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://lore.kernel.org/r/20251017123504.2247954-6-ankit.k.nautiyal@intel.com
2025-10-18 07:41:22 +05:30
Ankit Nautiyal
b2f88d7d5a drm/i915/vrr: Use the min static optimized guardband
In the current VRR implementation, vrr.vmin and vrr.guardband are set such
that they do not need to change when switching from fixed refresh rate to
variable refresh rate. Specifically, vrr.guardband is always set to match
the vblank length. This approach works for most cases, but not for LRR,
where the guardband would need to change while the VRR timing generator is
still active.

With the VRR TG always active, live updates to guardband are unsafe and not
recommended. To ensure hardware safety, guardband was moved out of the
!fastset block, meaning any change now requires a full modeset.
This breaks seamless LRR switching, which was previously supported.

Since the problem arises from guardband being matched to the vblank length,
solution is to use a minimal, sufficient static value, instead. So we use a
static guardband defined during mode-set that fits within the smallest
expected vblank and remains unchanged in case of features like LRR where
vtotal changes. To compute this minimum guardband we take into account
latencies/delays due to different features as mentioned in the Bspec.

Introduce a helper to compute the minimal sufficient guardband.
On platforms where the VRR timing generator is always ON, we optimize the
guardband regardless of whether the display is operating in fixed or
variable refresh rate mode.

v2:
- Use max of sagv latency and skl_wm_latency(1) for PM delay
  computation. (Ville)
- Avoid guardband optimization for HDMI for now. (Ville)
- Allow guardband optimization only for platforms with
  intel_vrr_always_use_vrr_tg = true. (Ville)
- Add comments for PM delay and a #TODO note for HDMI.

v3: Drop the variable prefill_min_guardband. (Ville)

Bspec: 70151
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://lore.kernel.org/r/20251017123504.2247954-5-ankit.k.nautiyal@intel.com
2025-10-18 07:41:21 +05:30
Ankit Nautiyal
5cb2cf6aa8 drm/i915/display: Add vblank_start adjustment logic for always-on VRR TG
As we move towards using a shorter, optimized guardband, we need to adjust
how the delayed vblank start is computed.

Adjust the crtc_vblank_start using Vmin Vtotal - guardband only when
intel_vrr_always_use_vrr_tg() is true. Also update the
pipe_mode->crtc_vblank_start which is derived from
adjusted_mode->crtc_vblank_start in intel_crtc_compute_pipe_mode().

To maintain consistency between the computed and readout paths, update
the readout logic in intel_vrr_get_config() to overwrite crtc_vblank_start
with the same value (vtotal - guardband) on platforms with always-on
VRR TG.

This also paves way for guardband optimization, by handling the movement of
the crtc_vblank_start for platforms that have VRR TG always active.

v2: Drop the helper and add the adjustment directly to
    intel_vrr_compute_guardband(). (Ville)
v3: Use adjusted_mode.crtc_vtotal instead of vmin and include the readout
    logic to keep the compute and readout paths in sync. (Ville)
v4: Also set pipe_mode->crtc_vblank_start as its derived from
    adjusted_mode. (Ville)
v5: Add a comment about rationale behind updating
    pipe_mode->crtc_vblank_start. (Ville)

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://lore.kernel.org/r/20251016055415.2101347-10-ankit.k.nautiyal@intel.com
2025-10-16 19:27:41 +05:30
Ankit Nautiyal
2cdcab0d3a drm/i915/vrr: s/intel_vrr_compute_config_late/intel_vrr_compute_guardband
The helper intel_vrr_compute_config_late() practically just computes the
guardband. Rename intel_vrr_compute_config_late() to
intel_vrr_compute_guardband().

Since we are going to compute the guardband and then move the
vblank_start for optmizing guardband move it to
intel_crtc_compute_config() which handles such changes.

v2: Move the function at the last after clocks, pipe_mode etc. are all
    set. (Ville)

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://lore.kernel.org/r/20251016055415.2101347-4-ankit.k.nautiyal@intel.com
2025-10-16 19:27:36 +05:30
Ankit Nautiyal
f71f86daa1 drm/i915/vrr: Use crtc_vsync_start/end for computing vrr.vsync_start/end
Use adjusted_mode->crtc_vsync_start/end instead of
adjusted_mode->vsync_start while computing vrr.vsync_start/end.
For most modes, these are same but for 3D/stereo modes the
crtc_vsync_start is different than vsync_start.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Link: https://lore.kernel.org/r/20251016055415.2101347-2-ankit.k.nautiyal@intel.com
2025-10-16 19:27:34 +05:30
Ankit Nautiyal
68f1d1764d drm/i915/display: Drop intel_vrr_vblank_delay and use set_context_latency
The helper intel_vrr_vblank_delay() was used to keep track of the SCL
lines + the extra vblank delay required for ICL/TGL.
This was used to wait for sufficient lines for:
-push send bit to clear for VRR case
-evasion to delay the commit.

For first case we are using safe window scanline wait and with that we
just need to wait for SCL lines, we do not need to wait for the extra
vblank delay required for ICL/TGL. For the second case, we actually
do not need to wait for extra lines before the undelayed vblank, if we
are already in the safe window.

To sum up, SCL lines is sufficient for both cases.

So drop the helper intel_vrr_vblank_delay and just use
crtc_state->set_context_latency instead.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://lore.kernel.org/r/20250924141542.3122126-10-ankit.k.nautiyal@intel.com
2025-09-25 18:38:20 +05:30
Ankit Nautiyal
5f9172bf6f drm/i915/vrr: Clamp guardband as per hardware and timing constraints
The maximum guardband value is constrained by two factors:
- The actual vblank length minus set context latency (SCL)
- The hardware register field width:
  - 8 bits for ICL/TGL (VRR_CTL_PIPELINE_FULL_MASK -> max 255)
  - 16 bits for ADL+ (XELPD_VRR_CTL_VRR_GUARDBAND_MASK -> max 65535)

Remove the #FIXME and clamp the guardband to the maximum allowed value.

v2:
- Use REG_FIELD_MAX(). (Ville)
- Separate out functions for intel_vrr_max_guardband(),
  intel_vrr_max_vblank_guardband(). (Ville)

v3:
- Fix Typo: Add the missing adjusted_mode->crtc_vdisplay in guardband
  computation. (Ville)
- Refactor intel_vrr_max_hw_guardband() and use else for consistency.
  (Ville)

v4:
- Drop max_guardband from intel_vrr_max_hw_guardband(). (Ville)

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> (#v2)
Link: https://lore.kernel.org/r/20250924141542.3122126-9-ankit.k.nautiyal@intel.com
2025-09-25 18:38:19 +05:30
Ankit Nautiyal
4e5c033cfe drm/i915/display: Wait for scl start instead of dsb_wait_vblanks
Until LNL, intel_dsb_wait_vblanks() used to wait for the undelayed vblank
start. However, from PTL onwards, it waits for the start of the
safe-window defined by the number of lines programmed in the register
TRANS_SET_CONTEXT_LATENCY. This change was introduced to move the SCL
window out of the vblank region, supporting modes with higher refresh
rates and smaller vblanks. This change introduces a "safe window" a
scanline range from (undelayed vblank - SCL) to (delayed vblank - SCL).

As a result, on PTL+ platforms, the DSB wait for vblank completes exactly
SCL lines earlier than the undelayed vblank start (safe window start).
If the flip occurs in the active region and the push happens before the
vmin decision boundary, the DSB wait fires early, and the push is sent
inside this safe window. In such cases, the push bit is cleared at the
delayed vblank, but our wait logic does not account for the early trigger,
leading to DSB poll errors.

To fix this, we add an explicit wait for the end of the safe window i.e.,
the scanline range from (undelayed vblank - SCL) to (delayed vblank - SCL).
Once past this window, we are exactly SCL lines away from the delayed
vblank, and our existing wait logic works as intended.

This additional wait is only effective if the push occurs before the vmin
decision boundary. If the push happens after the boundary, the hardware
already guarantees we're SCL lines away from the delayed vblank, and the
extra wait becomes a no-op.

v2:
- Use helpers for safe window start/end. (Ville)
- Move the extra wait inside the helper to wait for delayed vblank. (Ville)
- Update the commit message.

v3:
- Add more documentation for explanation for the wait. (Ville)
- Rename intel_vrr_vmin_safe_window_start/end as this is vmin safe
  window. (Ville)
- Minor refactoring to align with the code. (Ville)
- Update the commit message for more clarity.

v4:
- Retain name for intel_vrr_safe_window_start as it doesn't change with
  vmin/vmax etc. (Ville)

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://lore.kernel.org/r/20250924141542.3122126-7-ankit.k.nautiyal@intel.com
2025-09-25 18:38:18 +05:30
Ankit Nautiyal
b811a7635a drm/i915/vrr: Use SCL for computing guardband
For now guardband is equal to the vblank length so ideally it should be
computed as difference between the vmin vtotal and vactive. However
since we are having few lines as SCL, we need to account for this while
computing the guardband.

Since the vblank start is moved by SCL lines from the vactive, the delta
between the vmin vtotal and new vblank start was used to account for this.
Now that SCL is explicitly tracked using the `set_context_latency` member,
use it directly in the guardband calculation.

In the future, when the guardband is shortened or optimized, we may need
to factor in both the change in the vblank start and SCL lines. For now,
explicitly accounting for SCL is sufficient.

v2: Fix typo: replace adjusted_mode->vdisplay with
adjusted_mode->crtc_vdisplay. (Ville)

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://lore.kernel.org/r/20250924141542.3122126-5-ankit.k.nautiyal@intel.com
2025-09-25 18:38:16 +05:30
Ankit Nautiyal
6441d9038f drm/i915/vrr: Use set_context_latency instead of intel_vrr_real_vblank_delay()
The helper intel_vrr_real_vblank_delay() was added to account for the
SCL lines for TGL where we do not have the TRANS_SET_CONTEXT_LATENCY.

Now, since we already are tracking the SCL with new member
`set_context_latency` use it directly instead of the helper.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://lore.kernel.org/r/20250924141542.3122126-4-ankit.k.nautiyal@intel.com
2025-09-25 18:38:15 +05:30
Ankit Nautiyal
d90c0a5ccd drm/i915/vrr: Refactor VRR live status wait into common helper
Add a helper to consolidate timeout handling and error logging when waiting
for VRR live status to clear. Log an error message if the VRR live status
bit fails to clear within the timeout.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
Link: https://lore.kernel.org/r/20250902122850.3649828-1-ankit.k.nautiyal@intel.com
2025-09-24 16:30:58 +05:30
Ville Syrjälä
50720b6708 drm/i915/vrr: s/intel_vrr_flipline_offset/intel_vrr_vmin_flipline_offset/
Rename intel_vrr_flipline_offset() to intel_vrr_vmin_flipline_offset()
to better reflect the fact that it gives us the minimum offset allowed
between vmin and flipline.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250918232226.25295-3-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-09-20 03:58:52 +03:00
Ville Syrjälä
fab82f4724 drm/i915/vrr: Hide the ICL/TGL intel_vrr_flipline_offset() mangling better
ICL/TGL VRR hardware won't allow us to program flipline==vmin. If we do
that the actual effect will be the same as if we had programmed
flipline=vmin+1, which would make the minimum vtotal one scanline taller
than expected.

To compensate for this we reduce vmin by one, and then program
flipline=vmin+1. So we end up with a flipline value that matches
the expected minimum vtotal. Currently this adjustment happens
in intel_vrr_compute_config() which means that crtc_state->vrr.vmin
will no longer be directly usable for the remainder of the high
level VRR code. That is annoying at best, fragile at worst.

Hide the adjustment in low level code instead. This will allow most
of the higher level VRR code to remain blissfully ignorant about this
fact. Afterwards crtc_state->vrr.{vmin,flipline} will be equal
and match the minimum vtotal, exactly how things already work
on ADL+.

The only slight downside is that the actual register value will no
longer match crtc_state->vrr.vmin on ICL/TGL, but that may already
be the case on TGL because the register value will also have been
adjusted by the SCL.

Note that we must change the guardband calculation to account
for intel_vrr_extra_vblank_delay() explicitly. Previously that
was accidentally handled by the earlier vmin reduction by
intel_vrr_flipline_offset().

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250918232226.25295-2-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-09-20 03:58:33 +03:00
Ville Syrjälä
a58b9e3d6e drm/i915/vrr: Move the TGL SCL mangling of vmin/vmax/flipline deeper
Currently our crtc_state->vrr.{vmin.vmax,flipline} are mangled on
TGL to account for the SCL delay (the hardware requires this mangling
or the actual vtotals will become incorrect). Unfortunately this
means that one can't simply use these values directly in many places,
and instead we always have to go through functions that undo the
damage first. This is all rather fragile.

Simplify our lives a bit by hiding this mangling deeper inside
the low level VRR code, leaving the number stored in the crtc
state actually something that humans can use.

This does introduce a dependdency as intel_vrr_get_config()
will now need to know the SCL value, which is read out in
intel_get_transcoder_timings(). I suppose we could simply
duplicate the SCL readout in both places should this become
a real hinderance. For now just leave a note around the
intel_get_transcoder_timings() call to remind us.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250917203446.14374-6-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-09-18 23:43:07 +03:00
Ville Syrjälä
1e2266dc68 drm/i915/vrr: Annotate some functions with "hw"
intel_vrr_fixed_rr_*() return values that have had the TGL
SCL adjustment applied to them. So we should indicate that these
values are only really useful when fed to the hardware. Add
a "_hw_" indicator to the function names to reflect that fact.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250917203446.14374-5-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-09-18 23:42:52 +03:00
Ville Syrjälä
291ddb993a drm/i915/vrr: Store guardband in crtc state even for icl/tgl
While ICL/TGL VRR hardware doesn't have a register for the guardband
value, our lives will be simpler if we pretend that it does. Start
by computing the guardband the same as on ADL+ and storing it in
the state, and only then we convert it into the corresponding
pipeline_full value that the hardware can consume. During readout we
do the opposite.

I was debating whether to completely remove pipeline_full from the
crtc state, but decided to keep it for now. Mainly because we check
it in vrr_params_changed() and simply checking the guardband instead
isn't 100% equivalent; Theoretically, framestart_delay may have
changed in the opposite direction to pipeline_full, keeping the
derived guardband value unchaged. One solution would be to also check
framestart_delay, but that feels a bit leaky abstraction wise.

Also note that we don't currently handle the maximum limit of 255
scanlines for the pipeline_full in a very nice way. The actual
position of the delayed vblank will move because of that clamping,
and so some of our code may get confused. But fixing this shall
wait a for now.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250917203446.14374-4-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-09-18 23:42:15 +03:00
Ville Syrjälä
a0f8dd08a5 drm/i915/vrr: Extract helpers to convert between guardband and pipeline_full values
I'd like to move towards a world where we can't more or less
pretend that the ICl/TGL VRR hardware works the same way as
ADL+. To that end extract some helpers to convert between
the guardband and pipeline_full representations.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250917203446.14374-2-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
2025-09-18 23:41:23 +03:00
Jani Nikula
9d4e26042c drm/i915/display: drop i915_reg.h include where possible
A number of files have unnecessary i915_reg.h includes. Drop them.

Reviewed-by: Michał Grzelak <michal.grzelak@intel.com>
Link: https://lore.kernel.org/r/7c4002322f4d8132fd2eaa1a4d688539cdd043c3.1749469962.git.jani.nikula@intel.com
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2025-06-11 14:03:06 +03:00