acrtc->enabled = false;
}
-static void prepare_flip_isr(struct amdgpu_crtc *acrtc)
-{
-
- assert_spin_locked(&acrtc->base.dev->event_lock);
- WARN_ON(acrtc->event);
-
- acrtc->event = acrtc->base.state->event;
-
- /* Set the flip status */
- acrtc->pflip_status = AMDGPU_FLIP_SUBMITTED;
-
- /* Mark this event as consumed */
- acrtc->base.state->event = NULL;
-
- drm_dbg_state(acrtc->base.dev,
- "crtc:%d, pflip_stat:AMDGPU_FLIP_SUBMITTED\n",
- acrtc->crtc_id);
-}
-
static void update_freesync_state_on_stream(
struct amdgpu_display_manager *dm,
struct dm_crtc_state *new_crtc_state,
return;
if (pflip_update) {
- drm_crtc_vblank_get(&acrtc->base);
WARN_ON(acrtc->pflip_status != AMDGPU_FLIP_NONE);
- /* Arm flip completion handling and event delivery after programming. */
- prepare_flip_isr(acrtc);
+ WARN_ON(acrtc->event);
+
+ acrtc->pflip_status = AMDGPU_FLIP_SUBMITTED;
+ acrtc->event = acrtc->base.state->event;
+ acrtc->base.state->event = NULL;
+
+ drm_dbg_state(acrtc->base.dev,
+ "crtc:%d, pflip_stat:AMDGPU_FLIP_SUBMITTED\n",
+ acrtc->crtc_id);
} else if (cursor_update) {
- drm_crtc_vblank_get(&acrtc->base);
acrtc->event = acrtc->base.state->event;
acrtc->base.state->event = NULL;
}
}
+/**
+ * dm_arm_vblank_event_pre_programming - Prepare for programming
+ * @acrtc: The amdgpu CRTC to prepare
+ * @acrtc_state: The new CRTC state
+ * @pflip_update: Whether a page flip is being programmed
+ * @cursor_update: Whether a cursor update is being programmed
+ *
+ * Grab a reference on the vblank counter if a page flip or cursor update is to
+ * be programmed. Do this before programming so the HW is not in any
+ * idle-optimized state (such as PSR).
+ */
+static void dm_arm_vblank_event_pre_programming(struct amdgpu_crtc *acrtc,
+ struct dm_crtc_state *acrtc_state,
+ bool pflip_update,
+ bool cursor_update)
+{
+ assert_spin_locked(&acrtc->base.dev->event_lock);
+
+ if (!acrtc->base.state->event || acrtc_state->active_planes == 0)
+ return;
+
+ if (pflip_update || cursor_update)
+ drm_crtc_vblank_get(&acrtc->base);
+}
+
static void amdgpu_dm_commit_planes(struct drm_atomic_commit *state,
struct drm_device *dev,
struct amdgpu_display_manager *dm,
}
}
- /*
- * DCE depends on a combination of GRPH_FLIP, VLINE0, and VUPDATE for
- * event delivery. Only GRPH_FLIP handler can send pflip events, and it
- * only fires if HW latched to the flip. Maintain legacy behavior by
- * arming event before programming.
- */
- if (amdgpu_ip_version(dm->adev, DCE_HWIP, 0) == 0) {
- scoped_guard(spinlock_irqsave, &pcrtc->dev->event_lock) {
+ scoped_guard(spinlock_irqsave, &pcrtc->dev->event_lock) {
+ dm_arm_vblank_event_pre_programming(acrtc_attach, acrtc_state,
+ pflip_present,
+ cursor_update);
+ /*
+ * DCE depends on a combination of GRPH_FLIP, VLINE0, and
+ * VUPDATE for event delivery. Only GRPH_FLIP handler can send
+ * pflip events, and it only fires if HW latched to the flip.
+ * Maintain legacy behavior by arming event before programming.
+ */
+ if (amdgpu_ip_version(dm->adev, DCE_HWIP, 0) == 0) {
dm_arm_vblank_event(acrtc_attach, acrtc_state,
- pflip_present, cursor_update);
+ pflip_present, cursor_update);
}
}