Commit 99cfbed1 authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915/vrr: Relocate VRR enable/disable

Move VRR enabling/disabling into a place where it also works
for fastsets.

With this we always start the transcoder up in non-VRR mode.
Granted  we already did that but for a very short period of
time. But now that we might end up doing a bit more with the
transcoder in non-VRR mode it seems prudent to also update
the active timings as the transcoder changes its operating
mode.

crtc_state->vrr.enable still tracks whether VRR is actually
enabled or not, but now we configure all the other VRR timing
registers whenever VRR is possible (whether we actually enable
it or not). crtc_state->vrr.flipline can now serve as our
"is VRR possible" bit of state.

I decided to leave the MSA timing ignore bit set all the time
whether VRR is actually enabled or not. If the sink can figure
out the timings with that information when VRR is active then
surely it can also do it when VRR is inactive.

v2: Protect intel_vrr_set_transcoder_timings() with HAS_VRR()
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230321135615.27338-1-ville.syrjala@linux.intel.comReviewed-by: default avatarMitul Golani <mitulkumar.ajitkumar.golani@intel.com>
parent ecaeecea
...@@ -68,7 +68,6 @@ ...@@ -68,7 +68,6 @@
#include "intel_tc.h" #include "intel_tc.h"
#include "intel_vdsc.h" #include "intel_vdsc.h"
#include "intel_vdsc_regs.h" #include "intel_vdsc_regs.h"
#include "intel_vrr.h"
#include "skl_scaler.h" #include "skl_scaler.h"
#include "skl_universal_plane.h" #include "skl_universal_plane.h"
...@@ -2725,8 +2724,6 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state, ...@@ -2725,8 +2724,6 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) { if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) {
intel_crtc_vblank_off(old_crtc_state); intel_crtc_vblank_off(old_crtc_state);
intel_vrr_disable(old_crtc_state);
intel_disable_transcoder(old_crtc_state); intel_disable_transcoder(old_crtc_state);
intel_ddi_disable_transcoder_func(old_crtc_state); intel_ddi_disable_transcoder_func(old_crtc_state);
...@@ -2963,8 +2960,6 @@ static void intel_enable_ddi(struct intel_atomic_state *state, ...@@ -2963,8 +2960,6 @@ static void intel_enable_ddi(struct intel_atomic_state *state,
intel_enable_transcoder(crtc_state); intel_enable_transcoder(crtc_state);
intel_vrr_enable(crtc_state);
intel_crtc_vblank_on(crtc_state); intel_crtc_vblank_on(crtc_state);
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
......
...@@ -1088,6 +1088,18 @@ static bool planes_disabling(const struct intel_crtc_state *old_crtc_state, ...@@ -1088,6 +1088,18 @@ static bool planes_disabling(const struct intel_crtc_state *old_crtc_state,
return is_disabling(active_planes, old_crtc_state, new_crtc_state); return is_disabling(active_planes, old_crtc_state, new_crtc_state);
} }
static bool vrr_enabling(const struct intel_crtc_state *old_crtc_state,
const struct intel_crtc_state *new_crtc_state)
{
return is_enabling(vrr.enable, old_crtc_state, new_crtc_state);
}
static bool vrr_disabling(const struct intel_crtc_state *old_crtc_state,
const struct intel_crtc_state *new_crtc_state)
{
return is_disabling(vrr.enable, old_crtc_state, new_crtc_state);
}
#undef is_disabling #undef is_disabling
#undef is_enabling #undef is_enabling
...@@ -1204,6 +1216,11 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, ...@@ -1204,6 +1216,11 @@ static void intel_pre_plane_update(struct intel_atomic_state *state,
intel_atomic_get_new_crtc_state(state, crtc); intel_atomic_get_new_crtc_state(state, crtc);
enum pipe pipe = crtc->pipe; enum pipe pipe = crtc->pipe;
if (vrr_disabling(old_crtc_state, new_crtc_state)) {
intel_vrr_disable(old_crtc_state);
intel_crtc_update_active_timings(old_crtc_state, false);
}
intel_drrs_deactivate(old_crtc_state); intel_drrs_deactivate(old_crtc_state);
intel_psr_pre_plane_update(state, crtc); intel_psr_pre_plane_update(state, crtc);
...@@ -1684,6 +1701,8 @@ static void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_sta ...@@ -1684,6 +1701,8 @@ static void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_sta
} }
intel_set_transcoder_timings(crtc_state); intel_set_transcoder_timings(crtc_state);
if (HAS_VRR(dev_priv))
intel_vrr_set_transcoder_timings(crtc_state);
if (cpu_transcoder != TRANSCODER_EDP) if (cpu_transcoder != TRANSCODER_EDP)
intel_de_write(dev_priv, TRANS_MULT(cpu_transcoder), intel_de_write(dev_priv, TRANS_MULT(cpu_transcoder),
...@@ -6910,8 +6929,8 @@ static void intel_enable_crtc(struct intel_atomic_state *state, ...@@ -6910,8 +6929,8 @@ static void intel_enable_crtc(struct intel_atomic_state *state,
if (!intel_crtc_needs_modeset(new_crtc_state)) if (!intel_crtc_needs_modeset(new_crtc_state))
return; return;
intel_crtc_update_active_timings(new_crtc_state, /* VRR will be enable later, if required */
new_crtc_state->vrr.enable); intel_crtc_update_active_timings(new_crtc_state, false);
dev_priv->display.funcs.display->crtc_enable(state, crtc); dev_priv->display.funcs.display->crtc_enable(state, crtc);
...@@ -6938,6 +6957,12 @@ static void intel_update_crtc(struct intel_atomic_state *state, ...@@ -6938,6 +6957,12 @@ static void intel_update_crtc(struct intel_atomic_state *state,
intel_dpt_configure(crtc); intel_dpt_configure(crtc);
} }
if (vrr_enabling(old_crtc_state, new_crtc_state)) {
intel_vrr_enable(new_crtc_state);
intel_crtc_update_active_timings(new_crtc_state,
new_crtc_state->vrr.enable);
}
if (!modeset) { if (!modeset) {
if (new_crtc_state->preload_luts && if (new_crtc_state->preload_luts &&
intel_crtc_needs_color_update(new_crtc_state)) intel_crtc_needs_color_update(new_crtc_state))
......
...@@ -699,7 +699,7 @@ intel_dp_prepare_link_train(struct intel_dp *intel_dp, ...@@ -699,7 +699,7 @@ intel_dp_prepare_link_train(struct intel_dp *intel_dp,
drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_RATE_SET, drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_RATE_SET,
&rate_select, 1); &rate_select, 1);
link_config[0] = crtc_state->vrr.enable ? DP_MSA_TIMING_PAR_IGNORE_EN : 0; link_config[0] = crtc_state->vrr.flipline ? DP_MSA_TIMING_PAR_IGNORE_EN : 0;
link_config[1] = intel_dp_is_uhbr(crtc_state) ? link_config[1] = intel_dp_is_uhbr(crtc_state) ?
DP_SET_ANSI_128B132B : DP_SET_ANSI_8B10B; DP_SET_ANSI_128B132B : DP_SET_ANSI_8B10B;
drm_dp_dpcd_write(&intel_dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2); drm_dp_dpcd_write(&intel_dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2);
......
...@@ -114,9 +114,6 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state, ...@@ -114,9 +114,6 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
return; return;
if (!crtc_state->uapi.vrr_enabled)
return;
vmin = DIV_ROUND_UP(adjusted_mode->crtc_clock * 1000, vmin = DIV_ROUND_UP(adjusted_mode->crtc_clock * 1000,
adjusted_mode->crtc_htotal * info->monitor_range.max_vfreq); adjusted_mode->crtc_htotal * info->monitor_range.max_vfreq);
vmax = adjusted_mode->crtc_clock * 1000 / vmax = adjusted_mode->crtc_clock * 1000 /
...@@ -135,7 +132,6 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state, ...@@ -135,7 +132,6 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
*/ */
crtc_state->vrr.vmin = vmin - 1; crtc_state->vrr.vmin = vmin - 1;
crtc_state->vrr.vmax = vmax; crtc_state->vrr.vmax = vmax;
crtc_state->vrr.enable = true;
crtc_state->vrr.flipline = crtc_state->vrr.vmin + 1; crtc_state->vrr.flipline = crtc_state->vrr.vmin + 1;
...@@ -152,7 +148,10 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state, ...@@ -152,7 +148,10 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
crtc_state->framestart_delay - 1); crtc_state->framestart_delay - 1);
} }
crtc_state->mode_flags |= I915_MODE_FLAG_VRR; if (crtc_state->uapi.vrr_enabled) {
crtc_state->vrr.enable = true;
crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
}
} }
static u32 trans_vrr_ctl(const struct intel_crtc_state *crtc_state) static u32 trans_vrr_ctl(const struct intel_crtc_state *crtc_state)
...@@ -168,7 +167,7 @@ static u32 trans_vrr_ctl(const struct intel_crtc_state *crtc_state) ...@@ -168,7 +167,7 @@ static u32 trans_vrr_ctl(const struct intel_crtc_state *crtc_state)
VRR_CTL_PIPELINE_FULL_OVERRIDE; VRR_CTL_PIPELINE_FULL_OVERRIDE;
} }
void intel_vrr_enable(const struct intel_crtc_state *crtc_state) void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state)
{ {
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
...@@ -181,17 +180,15 @@ void intel_vrr_enable(const struct intel_crtc_state *crtc_state) ...@@ -181,17 +180,15 @@ void intel_vrr_enable(const struct intel_crtc_state *crtc_state)
intel_de_rmw(dev_priv, CHICKEN_TRANS(cpu_transcoder), intel_de_rmw(dev_priv, CHICKEN_TRANS(cpu_transcoder),
0, PIPE_VBLANK_WITH_DELAY); 0, PIPE_VBLANK_WITH_DELAY);
if (!crtc_state->vrr.enable) if (!crtc_state->vrr.flipline) {
intel_de_write(dev_priv, TRANS_VRR_CTL(cpu_transcoder), 0);
return; return;
}
intel_de_write(dev_priv, TRANS_VRR_VMIN(cpu_transcoder), crtc_state->vrr.vmin - 1); intel_de_write(dev_priv, TRANS_VRR_VMIN(cpu_transcoder), crtc_state->vrr.vmin - 1);
intel_de_write(dev_priv, TRANS_VRR_VMAX(cpu_transcoder), crtc_state->vrr.vmax - 1); intel_de_write(dev_priv, TRANS_VRR_VMAX(cpu_transcoder), crtc_state->vrr.vmax - 1);
intel_de_write(dev_priv, TRANS_VRR_CTL(cpu_transcoder), trans_vrr_ctl(crtc_state)); intel_de_write(dev_priv, TRANS_VRR_CTL(cpu_transcoder), trans_vrr_ctl(crtc_state));
intel_de_write(dev_priv, TRANS_VRR_FLIPLINE(cpu_transcoder), crtc_state->vrr.flipline - 1); intel_de_write(dev_priv, TRANS_VRR_FLIPLINE(cpu_transcoder), crtc_state->vrr.flipline - 1);
intel_de_write(dev_priv, TRANS_PUSH(cpu_transcoder), TRANS_PUSH_EN);
intel_de_write(dev_priv, TRANS_VRR_CTL(cpu_transcoder),
VRR_CTL_VRR_ENABLE | trans_vrr_ctl(crtc_state));
} }
void intel_vrr_send_push(const struct intel_crtc_state *crtc_state) void intel_vrr_send_push(const struct intel_crtc_state *crtc_state)
...@@ -219,6 +216,19 @@ bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state) ...@@ -219,6 +216,19 @@ bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state)
return intel_de_read(dev_priv, TRANS_PUSH(cpu_transcoder)) & TRANS_PUSH_SEND; return intel_de_read(dev_priv, TRANS_PUSH(cpu_transcoder)) & TRANS_PUSH_SEND;
} }
void intel_vrr_enable(const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
if (!crtc_state->vrr.enable)
return;
intel_de_write(dev_priv, TRANS_PUSH(cpu_transcoder), TRANS_PUSH_EN);
intel_de_write(dev_priv, TRANS_VRR_CTL(cpu_transcoder),
VRR_CTL_VRR_ENABLE | trans_vrr_ctl(crtc_state));
}
void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state) void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state)
{ {
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
...@@ -232,9 +242,7 @@ void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state) ...@@ -232,9 +242,7 @@ void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state)
trans_vrr_ctl(old_crtc_state)); trans_vrr_ctl(old_crtc_state));
intel_de_wait_for_clear(dev_priv, TRANS_VRR_STATUS(cpu_transcoder), intel_de_wait_for_clear(dev_priv, TRANS_VRR_STATUS(cpu_transcoder),
VRR_STATUS_VRR_EN_LIVE, 1000); VRR_STATUS_VRR_EN_LIVE, 1000);
intel_de_write(dev_priv, TRANS_PUSH(cpu_transcoder), 0); intel_de_write(dev_priv, TRANS_PUSH(cpu_transcoder), 0);
intel_de_write(dev_priv, TRANS_VRR_CTL(cpu_transcoder), 0);
} }
void intel_vrr_get_config(struct intel_crtc_state *crtc_state) void intel_vrr_get_config(struct intel_crtc_state *crtc_state)
...@@ -244,9 +252,8 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state) ...@@ -244,9 +252,8 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state)
u32 trans_vrr_ctl; u32 trans_vrr_ctl;
trans_vrr_ctl = intel_de_read(dev_priv, TRANS_VRR_CTL(cpu_transcoder)); trans_vrr_ctl = intel_de_read(dev_priv, TRANS_VRR_CTL(cpu_transcoder));
crtc_state->vrr.enable = trans_vrr_ctl & VRR_CTL_VRR_ENABLE; crtc_state->vrr.enable = trans_vrr_ctl & VRR_CTL_VRR_ENABLE;
if (!crtc_state->vrr.enable)
return;
if (DISPLAY_VER(dev_priv) >= 13) if (DISPLAY_VER(dev_priv) >= 13)
crtc_state->vrr.guardband = crtc_state->vrr.guardband =
...@@ -255,10 +262,13 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state) ...@@ -255,10 +262,13 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state)
if (trans_vrr_ctl & VRR_CTL_PIPELINE_FULL_OVERRIDE) if (trans_vrr_ctl & VRR_CTL_PIPELINE_FULL_OVERRIDE)
crtc_state->vrr.pipeline_full = crtc_state->vrr.pipeline_full =
REG_FIELD_GET(VRR_CTL_PIPELINE_FULL_MASK, trans_vrr_ctl); REG_FIELD_GET(VRR_CTL_PIPELINE_FULL_MASK, trans_vrr_ctl);
if (trans_vrr_ctl & VRR_CTL_FLIP_LINE_EN)
if (trans_vrr_ctl & VRR_CTL_FLIP_LINE_EN) {
crtc_state->vrr.flipline = intel_de_read(dev_priv, TRANS_VRR_FLIPLINE(cpu_transcoder)) + 1; crtc_state->vrr.flipline = intel_de_read(dev_priv, TRANS_VRR_FLIPLINE(cpu_transcoder)) + 1;
crtc_state->vrr.vmax = intel_de_read(dev_priv, TRANS_VRR_VMAX(cpu_transcoder)) + 1; crtc_state->vrr.vmax = intel_de_read(dev_priv, TRANS_VRR_VMAX(cpu_transcoder)) + 1;
crtc_state->vrr.vmin = intel_de_read(dev_priv, TRANS_VRR_VMIN(cpu_transcoder)) + 1; crtc_state->vrr.vmin = intel_de_read(dev_priv, TRANS_VRR_VMIN(cpu_transcoder)) + 1;
}
crtc_state->mode_flags |= I915_MODE_FLAG_VRR; if (crtc_state->vrr.enable)
crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
} }
...@@ -17,6 +17,7 @@ bool intel_vrr_is_capable(struct intel_connector *connector); ...@@ -17,6 +17,7 @@ bool intel_vrr_is_capable(struct intel_connector *connector);
void intel_vrr_check_modeset(struct intel_atomic_state *state); void intel_vrr_check_modeset(struct intel_atomic_state *state);
void intel_vrr_compute_config(struct intel_crtc_state *crtc_state, void intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
struct drm_connector_state *conn_state); struct drm_connector_state *conn_state);
void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state);
void intel_vrr_enable(const struct intel_crtc_state *crtc_state); void intel_vrr_enable(const struct intel_crtc_state *crtc_state);
void intel_vrr_send_push(const struct intel_crtc_state *crtc_state); void intel_vrr_send_push(const struct intel_crtc_state *crtc_state);
bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state); bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment