mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-22 07:27:12 +08:00
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>
This commit is contained in:
@@ -3891,6 +3891,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
|
||||
intel_joiner_get_config(pipe_config);
|
||||
intel_dsc_get_config(pipe_config);
|
||||
|
||||
/* intel_vrr_get_config() depends on .framestart_delay */
|
||||
if (!transcoder_is_dsi(pipe_config->cpu_transcoder)) {
|
||||
tmp = intel_de_read(display, CHICKEN_TRANS(display, pipe_config->cpu_transcoder));
|
||||
|
||||
|
||||
@@ -151,13 +151,7 @@ static int intel_vrr_pipeline_full_to_guardband(const struct intel_crtc_state *c
|
||||
*/
|
||||
static int intel_vrr_vblank_exit_length(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
|
||||
if (DISPLAY_VER(display) >= 13)
|
||||
return crtc_state->vrr.guardband;
|
||||
else
|
||||
return intel_vrr_pipeline_full_to_guardband(crtc_state,
|
||||
crtc_state->vrr.pipeline_full);
|
||||
return crtc_state->vrr.guardband;
|
||||
}
|
||||
|
||||
int intel_vrr_vmin_vtotal(const struct intel_crtc_state *crtc_state)
|
||||
@@ -431,18 +425,22 @@ void intel_vrr_compute_config_late(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
|
||||
int guardband;
|
||||
|
||||
if (!intel_vrr_possible(crtc_state))
|
||||
return;
|
||||
|
||||
guardband = crtc_state->vrr.vmin - adjusted_mode->crtc_vblank_start;
|
||||
crtc_state->vrr.guardband =
|
||||
crtc_state->vrr.vmin - adjusted_mode->crtc_vblank_start;
|
||||
|
||||
if (DISPLAY_VER(display) < 13) {
|
||||
/* FIXME handle the limit in a proper way */
|
||||
crtc_state->vrr.guardband =
|
||||
min(crtc_state->vrr.guardband,
|
||||
intel_vrr_pipeline_full_to_guardband(crtc_state, 255));
|
||||
|
||||
if (DISPLAY_VER(display) >= 13) {
|
||||
crtc_state->vrr.guardband = guardband;
|
||||
} else {
|
||||
crtc_state->vrr.pipeline_full =
|
||||
min(255, intel_vrr_guardband_to_pipeline_full(crtc_state, guardband));
|
||||
intel_vrr_guardband_to_pipeline_full(crtc_state,
|
||||
crtc_state->vrr.guardband);
|
||||
|
||||
/*
|
||||
* vmin/vmax/flipline also need to be adjusted by
|
||||
@@ -734,14 +732,20 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state)
|
||||
TRANS_CMRR_M_HI(display, cpu_transcoder));
|
||||
}
|
||||
|
||||
if (DISPLAY_VER(display) >= 13)
|
||||
if (DISPLAY_VER(display) >= 13) {
|
||||
crtc_state->vrr.guardband =
|
||||
REG_FIELD_GET(XELPD_VRR_CTL_VRR_GUARDBAND_MASK, trans_vrr_ctl);
|
||||
else
|
||||
if (trans_vrr_ctl & VRR_CTL_PIPELINE_FULL_OVERRIDE)
|
||||
} else {
|
||||
if (trans_vrr_ctl & VRR_CTL_PIPELINE_FULL_OVERRIDE) {
|
||||
crtc_state->vrr.pipeline_full =
|
||||
REG_FIELD_GET(VRR_CTL_PIPELINE_FULL_MASK, trans_vrr_ctl);
|
||||
|
||||
crtc_state->vrr.guardband =
|
||||
intel_vrr_pipeline_full_to_guardband(crtc_state,
|
||||
crtc_state->vrr.pipeline_full);
|
||||
}
|
||||
}
|
||||
|
||||
if (trans_vrr_ctl & VRR_CTL_FLIP_LINE_EN) {
|
||||
crtc_state->vrr.flipline = intel_de_read(display,
|
||||
TRANS_VRR_FLIPLINE(display, cpu_transcoder)) + 1;
|
||||
|
||||
Reference in New Issue
Block a user