From: Ville Syrjälä ville.syrjala@linux.intel.com
Put the vblank timestamping constants update loop into its own function. It has no business living inside drm_atomic_helper_update_legacy_modeset_state() so we'll be wanting to move it out entirely. As a first step we'll still call it from drm_atomic_helper_update_legacy_modeset_state().
Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/drm_atomic_helper.c | 26 ++++++++++++++++++++++---- include/drm/drm_atomic_helper.h | 3 +++ 2 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 587052751b48..3773d74877e7 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1080,9 +1080,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) * @old_state: atomic state object with old state structures * * This function updates all the various legacy modeset state pointers in - * connectors, encoders and crtcs. It also updates the timestamping constants - * used for precise vblank timestamps by calling - * drm_calc_timestamping_constants(). + * connectors, encoders and crtcs. * * Drivers can use this for building their own atomic commit if they don't have * a pure helper-based modeset implementation. @@ -1151,13 +1149,33 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev, crtc->x = new_plane_state->src_x >> 16; crtc->y = new_plane_state->src_y >> 16; } + } + + drm_atomic_helper_calc_timestamping_constants(old_state); +} +EXPORT_SYMBOL(drm_atomic_helper_update_legacy_modeset_state);
+/** + * drm_atomic_helper_calc_timestamping_constants - update vblank timestamping constants + * @state: atomic state object + * + * Updates the timestamping constants used for precise vblank timestamps + * by calling drm_calc_timestamping_constants() for all enabled crtcs in @state. + */ +void drm_atomic_helper_calc_timestamping_constants(struct drm_atomic_state *state) +{ + struct drm_crtc_state *new_crtc_state; + struct drm_crtc *crtc; + int i; + + /* set legacy state in the crtc structure */ + for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { if (new_crtc_state->enable) drm_calc_timestamping_constants(crtc, &new_crtc_state->adjusted_mode); } } -EXPORT_SYMBOL(drm_atomic_helper_update_legacy_modeset_state); +EXPORT_SYMBOL(drm_atomic_helper_calc_timestamping_constants);
static void crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state) diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index bf4e07141d81..a60ea2cf36f0 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -74,6 +74,9 @@ void drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev, struct drm_atomic_state *old_state);
+void +drm_atomic_helper_calc_timestamping_constants(struct drm_atomic_state *state); + void drm_atomic_helper_commit_modeset_disables(struct drm_device *dev, struct drm_atomic_state *state); void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
From: Ville Syrjälä ville.syrjala@linux.intel.com
The timestamping constants have nothing to do with any legacy state so should not be updated from drm_atomic_helper_update_legacy_modeset_state().
Let's make everyone call drm_atomic_helper_calc_timestamping_constants() directly instead of relying on drm_atomic_helper_update_legacy_modeset_state() to call it.
@@ expression S; @@ - drm_atomic_helper_calc_timestamping_constants(S);
@@ expression D, S; @@ drm_atomic_helper_update_legacy_modeset_state(D, S); + drm_atomic_helper_calc_timestamping_constants(S);
Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 + drivers/gpu/drm/drm_atomic_helper.c | 3 +-- drivers/gpu/drm/i915/display/intel_display.c | 1 + drivers/gpu/drm/nouveau/dispnv50/disp.c | 1 + 4 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index c67d3c41db19..67cc606b3cac 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6145,6 +6145,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) int crtc_disable_count = 0;
drm_atomic_helper_update_legacy_modeset_state(dev, state); + drm_atomic_helper_calc_timestamping_constants(state);
dm_state = dm_atomic_get_new_state(state); if (dm_state && dm_state->context) { diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 3773d74877e7..12a625ab3fd4 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1150,8 +1150,6 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev, crtc->y = new_plane_state->src_y >> 16; } } - - drm_atomic_helper_calc_timestamping_constants(old_state); } EXPORT_SYMBOL(drm_atomic_helper_update_legacy_modeset_state);
@@ -1257,6 +1255,7 @@ void drm_atomic_helper_commit_modeset_disables(struct drm_device *dev, disable_outputs(dev, old_state);
drm_atomic_helper_update_legacy_modeset_state(dev, old_state); + drm_atomic_helper_calc_timestamping_constants(old_state);
crtc_set_mode(dev, old_state); } diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 05fb672a00b9..b80d864cc8f1 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -13980,6 +13980,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
if (state->modeset) { drm_atomic_helper_update_legacy_modeset_state(dev, &state->base); + drm_atomic_helper_calc_timestamping_constants(&state->base);
intel_set_cdclk_pre_plane_update(dev_priv, &state->cdclk.actual, diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index a13924ae1992..51e4055b5e02 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1820,6 +1820,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) drm_atomic_helper_wait_for_fences(dev, state, false); drm_atomic_helper_wait_for_dependencies(state); drm_atomic_helper_update_legacy_modeset_state(dev, state); + drm_atomic_helper_calc_timestamping_constants(state);
if (atom->lock_core) mutex_lock(&disp->mutex);
From: Ville Syrjälä ville.syrjala@linux.intel.com
Once we do the hw vs. uapi split we can no longer use drm_atomic_helper_calc_timestamping_constants() as it'll consult the uapi state instead of the hw state.
So let's just update the vblank timestamping constants whenever we update the scanline offset. We use both to convert the hw scanline count to something which matches the software timing values.
First I thought to put these into intel_crtc_vblank_on() but we may want to get the scanline counter value before that (eg. from some early tracepoints), so let's stick to updating them a bit earlier than intel_crtc_vblank_on().
Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index b80d864cc8f1..ae5fa584d9ae 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -13361,10 +13361,15 @@ intel_modeset_verify_disabled(struct drm_i915_private *dev_priv, verify_disabled_dpll_state(dev_priv); }
-static void update_scanline_offset(const struct intel_crtc_state *crtc_state) +static void +intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + const struct drm_display_mode *adjusted_mode = + &crtc_state->base.adjusted_mode; + + drm_calc_timestamping_constants(&crtc->base, adjusted_mode);
/* * The scanline counter increments at the leading edge of hsync. @@ -13394,7 +13399,6 @@ static void update_scanline_offset(const struct intel_crtc_state *crtc_state) * answer that's slightly in the future. */ if (IS_GEN(dev_priv, 2)) { - const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode; int vtotal;
vtotal = adjusted_mode->crtc_vtotal; @@ -13405,8 +13409,9 @@ static void update_scanline_offset(const struct intel_crtc_state *crtc_state) } else if (HAS_DDI(dev_priv) && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { crtc->scanline_offset = 2; - } else + } else { crtc->scanline_offset = 1; + } }
static void intel_modeset_clear_plls(struct intel_atomic_state *state) @@ -13707,7 +13712,8 @@ static void intel_update_crtc(struct intel_crtc *crtc, to_intel_plane(crtc->base.primary));
if (modeset) { - update_scanline_offset(new_crtc_state); + intel_crtc_update_active_timings(new_crtc_state); + dev_priv->display.crtc_enable(new_crtc_state, state);
/* vblanks work again, re-enable pipe CRC. */ @@ -13980,7 +13986,6 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
if (state->modeset) { drm_atomic_helper_update_legacy_modeset_state(dev, &state->base); - drm_atomic_helper_calc_timestamping_constants(&state->base);
intel_set_cdclk_pre_plane_update(dev_priv, &state->cdclk.actual, @@ -16787,9 +16792,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) min_cdclk = 0; }
- drm_calc_timestamping_constants(&crtc->base, - &crtc_state->base.adjusted_mode); - update_scanline_offset(crtc_state); + intel_crtc_update_active_timings(crtc_state); }
dev_priv->min_cdclk[crtc->pipe] = min_cdclk;
dri-devel@lists.freedesktop.org