Commit Graph

125 Commits

Author SHA1 Message Date
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
Jani Nikula
188bdfb776 drm/i915: split out display register macros to a separate file
This is a scripted split of the display related register macros from
i915_reg.h to display/intel_display_regs.h. As a starting point, move
all the macros that are only used in display code (or GVT). If there are
users in core i915 code or soc/, or no users anywhere, keep the macros
in i915_reg.h. This is done in groups of macros separated by blank
lines, moving the comments along with the groups.

Some manually picked macro groups are kept/moved regardless of the
heuristics above.

This is obviously a very crude approach. It's not perfect. But there are
4.2k lines in i915_reg.h, and its refactoring has ground to a halt. This
is the big hammer that splits the file to two, and enables further
cleanup.

Cc: Suraj Kandpal <suraj.kandpal@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com> # v2
Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
Link: https://lore.kernel.org/r/20250606102256.2080073-1-jani.nikula@intel.com
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2025-06-09 13:25:10 +03:00
Ankit Nautiyal
e1123e617e drm/i915/vrr: Program EMP_AS_SDP_TL for DP AS SDP
The register EMP_AS_SDP_TL (MTL) was introduced for configuring the
double buffering point and transmission line for all
HDMI2.1 Extended Metadata Packets (VT-EMP for VRR, CVT-EMP for DSC etc).
This was also intended to be configured for DP to HDMI2.1 PCON to
support VRR.

From BMG and LNL+ onwards, this register was extended to Display Port
Adaptive Sync SDP to have a common register to configure double
buffering point and transmission line for both HDMI EMPs and DP VRR related
packets.

Currently, we do not support VRR for either native HDMI or via PCON.
However we need to configure this for DP SDP case. As per the spec,
program the register to set Vsync start as the double buffering point
for DP AS SDP.

v2:
-Make the helper more readable. (Jani)
-Add more information in commit message and comment.

Bspec:70984, 71197
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Tested-by: Jouni Högander <jouni.hogander@intel.com>
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
Link: https://lore.kernel.org/r/20250505033911.393628-1-ankit.k.nautiyal@intel.com
2025-05-19 15:08:22 +05:30
Jouni Högander
7a429a14f8 drm/i915/vrr: Stop writing VRR_CTL_IGN_MAX_SHIFT for MTL onwards
According to Bspec VRR_CTL_IGN_MAX_SHIFT doesn't exist for MTL and
onwards. On LunarLake and onwards Bit 30 is "Mask Block PkgC" instead. Stop
writing the bit for MeteorLake and onwards

v2: "Ignore Max Shift" bit doesn't exist on MeteorLake either

Bspec: 50508, 68925
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Link: https://lore.kernel.org/r/20250409054909.968531-1-jouni.hogander@intel.com
2025-04-14 08:13:59 +03:00
Jani Nikula
513c1a2ec4 drm/i915: reduce intel_wakeref.h dependencies
Forward declare struct drm_printer instead of including drm/drm_print.h,
as we only need the pointer. Turns out quite a few places depend on this
include implicitly. Make them explicit.

Some of the includes are just stale and unnecessary. Group the forward
declarations together while at it.

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://lore.kernel.org/r/20250326115452.2090275-1-jani.nikula@intel.com
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2025-04-01 11:48:18 +03:00
Ankit Nautiyal
94f608992f drm/i915/display: Avoid use of VTOTAL.Vtotal bits
For platforms that always use VRR Timing Generator, the VTOTAL.Vtotal
bits are not required. Since the support for these bits is going to
be deprecated in upcoming platforms, avoid writing these bits for the
platforms that do not use legacy Timing Generator.

Since for these platforms vrr.vmin is always filled with crtc_vtotal,
use TRAN_VRR_VMIN to get the vtotal for adjusted_mode.

v2: Avoid having a helper for manipulating VTOTAL register, and instead
just make the change where required. (Ville)
v3: Set crtc_vtotal instead of working with the bits directly (Ville).
Use intel_vrr_vmin_vtotal() to set the vtotal during readout. (Ville)
v4: Keep the reading part unchanged, and let it get overwritten for
cases where we use vrr.vmin. (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/20250327144629.648306-3-ankit.k.nautiyal@intel.com
2025-03-31 09:28:28 +05:30
Ankit Nautiyal
e2b1dd430d drm/i915/vrr: Set trans_vrr_ctl in intel_vrr_set_transcoder_timings()
We now always set vrr.flipline, vmin, and vmax for all platforms that
support VRR. Therefore, we should set all TRANS_VRR_CTL bits except
VRR_ENABLE. Without this, the readback for these bits will fail because we
only read vrr.flipline, vmin, and vmax if TRANS_VRR_CTL has the
FLIPLINE_EN bit set.

For platforms that always have the VRR Timing Generator enabled,
the FLIPLINE_EN bit is always set in TRANS_VRR_CTL during
intel_transcoder_vrr_enable(). However, for the remaining platforms
(that do not always have the VRR Timing Generator enabled) if a full
modeset doesn't occur and VRR is not enabled, the bit is not set.

This results in a mismatch between the software state and hardware state
because the software state expects VRR timings like flipline, vmin, and
vmax to be set, but the readout for these doesn't happen since the
FLIPLINE_EN bit is not set in TRANS_VRR_CTL.

To avoid this mismatch, write trans_vrr_ctl in
intel_vrr_set_transcoder_timings() even when VRR is not enabled
for platforms that do not have the VRR Timing Generator always enabled.

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/20250324133248.4071909-15-ankit.k.nautiyal@intel.com
2025-03-25 21:17:25 +05:30
Ankit Nautiyal
cfd51309f8 drm/i915/vrr: Always use VRR timing generator for PTL+
Currently, the VRR timing generator is used only when VRR is enabled by
userspace for sinks that support VRR. Starting with PTL+, gradually move
away from the legacy timing generator and use the VRR timing generator
for both variable and fixed timings.

Note: For platforms where we always enable the VRR timing generator,
the LRR fastset is not allowed to avoid live programming of vrr.guardband
with VRR TG enabled. This effectively breaks the LRR fastset functionality
for these platforms and needs to be addressed.

v2: Use this for PTL for now to avoid losing LRR fastset for older
platforms. (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/20250324133248.4071909-14-ankit.k.nautiyal@intel.com
2025-03-25 21:17:25 +05:30
Ankit Nautiyal
0ec46988ae drm/i915/vrr: Allow fixed_rr with pipe joiner
VRR with joiner is currently disabled as it still needs some work to
correctly sequence the primary and secondary transcoders. However, we can
still use VRR Timing generator in fixed refresh rate for joiner and since
it just need to program vrr timings once and does not involve changing
timings on the fly. We still need to skip the VRR and LRR for joiner.

To achieve this set vrr.in_range to 0 for joiner case, so that we do not
try VRR and LRR for the joiner case.

v2: Avoid checks for secondary pipes, where not required. (Ville)
v3: Remove a redundant check and reset vrr.in_range to false. (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/20250324133248.4071909-13-ankit.k.nautiyal@intel.com
2025-03-25 21:17:25 +05:30
Ankit Nautiyal
423f9d7c52 drm/i915/display: Move vrr.guardband/pipeline_full out of !fastset block
Since the vrr.guardband can now change for platforms that always use the
VRR Timing Generator, and it is unsafe to reprogram the guardband on the
fly, move the guardband and pipeline_full checks from the pure !fastboot
path and add a check for intel_vrr_always_use_vrr_tg().

For older platforms the vrr.guardband change happens when VRR Timing
generator is off. For the platforms that always use the VRR Timing
Generator, this will prevent reprogramming the vrr.guardband without a
full modeset. However, this will disrupt LRR functionality for these
platforms.

v2: Modify the check to avoid breaking the LRR on older platform.
(Ville)
v3: Correct the oversight of not removing the lines from the original
location. (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/20250324133248.4071909-12-ankit.k.nautiyal@intel.com
2025-03-25 21:17:25 +05:30
Ankit Nautiyal
704bd24d01 drm/i915/display: Use fixed rr timings in intel_set_transcoder_timings_lrr()
Update the intel_set_transcoder_timings_lrr() function to use
fixed refresh rate timings.

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/20250324133248.4071909-11-ankit.k.nautiyal@intel.com
2025-03-25 21:17:25 +05:30
Ankit Nautiyal
dda7dcd9da drm/i915/vrr: Use fixed timings for platforms that support VRR
For fixed refresh rate use fixed timings for all platforms that support
VRR. For this add checks to avoid computing and reading VRR for
platforms that do not support VRR.

v2: Avoid touching check for VRR_CTL_FLIP_LINE_EN. (Ville)
v3: Avoid redundant statements in vrr_{compute/get}_config. (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/20250324133248.4071909-10-ankit.k.nautiyal@intel.com
2025-03-25 21:17:25 +05:30
Ankit Nautiyal
7895991a29 drm/i915/display: Use fixed_rr timings in modeset sequence
During modeset enable sequence, program the fixed timings, and turn on the
VRR Timing Generator (VRR TG) for platforms that always use VRR TG.

For this intel_vrr_set_transcoder now always programs fixed timings.
Later if vrr timings are required, vrr_enable() will switch
to the real VRR timings.

For platforms that will always use VRR TG, the VRR_CTL Enable bit is set
and reset in the transcoder enable/disable path.

v2: Update intel_vrr_set_transcoder_timings for fixed_rr.
v3: Update intel_set_transcoder_timings_lrr for fixed_rr. (Ville)
v4: Have separate functions to enable/disable VRR CTL
v5:
-For platforms that do not always have VRRTG on, do write bits other
than enable bit and also use write the TRANS_VRR_PUSH register. (Ville)
-Avoid writing trans_ctl_vrr if !vrr_possible().
v6:
-Disable VRR just before intel_ddi_disable_transcoder_func(). (Ville)
-Correct the sequence of configuring PUSH and VRR Enable/Disable. (Ville)
v7: Reset trans_vrr_ctl to 0 unconditionally in
intel_vrr_transcoder_disable(). (Ville)
v8: Reset trans_vrr_ctl if flipline is not 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/20250324133248.4071909-9-ankit.k.nautiyal@intel.com
2025-03-25 21:17:25 +05:30