summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/msm_atomic.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2023-08-30 16:06:38 -0700
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2023-08-30 16:06:38 -0700
commit1ac731c529cd4d6adbce134754b51ff7d822b145 (patch)
tree143ab3f35ca5f3b69f583c84e6964b17139c2ec1 /drivers/gpu/drm/msm/msm_atomic.c
parent07b4c950f27bef0362dc6ad7ee713aab61d58149 (diff)
parent54116d442e001e1b6bd482122043b1870998a1f3 (diff)
Merge branch 'next' into for-linus
Prepare input updates for 6.6 merge window.
Diffstat (limited to 'drivers/gpu/drm/msm/msm_atomic.c')
-rw-r--r--drivers/gpu/drm/msm/msm_atomic.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index 1686fbb611fd7..9c45d641b5212 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -155,6 +155,8 @@ static bool can_do_async(struct drm_atomic_state *state,
for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
if (drm_atomic_crtc_needs_modeset(crtc_state))
return false;
+ if (!crtc_state->active)
+ return false;
if (++num_crtcs > 1)
return false;
*async_crtc = crtc;
@@ -179,6 +181,24 @@ static unsigned get_crtc_mask(struct drm_atomic_state *state)
return mask;
}
+int msm_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)
+{
+ struct drm_crtc_state *old_crtc_state, *new_crtc_state;
+ struct drm_crtc *crtc;
+ int i;
+
+ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
+ new_crtc_state, i) {
+ if ((old_crtc_state->ctm && !new_crtc_state->ctm) ||
+ (!old_crtc_state->ctm && new_crtc_state->ctm)) {
+ new_crtc_state->mode_changed = true;
+ state->allow_modeset = true;
+ }
+ }
+
+ return drm_atomic_helper_check(dev, state);
+}
+
void msm_atomic_commit_tail(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
@@ -186,8 +206,7 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state)
struct msm_kms *kms = priv->kms;
struct drm_crtc *async_crtc = NULL;
unsigned crtc_mask = get_crtc_mask(state);
- bool async = kms->funcs->vsync_time &&
- can_do_async(state, &async_crtc);
+ bool async = can_do_async(state, &async_crtc);
trace_msm_atomic_commit_tail_start(async, crtc_mask);
@@ -206,7 +225,8 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state)
* Now that there is no in-progress flush, prepare the
* current update:
*/
- kms->funcs->prepare_commit(kms, state);
+ if (kms->funcs->prepare_commit)
+ kms->funcs->prepare_commit(kms, state);
/*
* Push atomic updates down to hardware:
@@ -231,7 +251,9 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state)
kms->pending_crtc_mask |= crtc_mask;
- vsync_time = kms->funcs->vsync_time(kms, async_crtc);
+ if (drm_crtc_next_vblank_start(async_crtc, &vsync_time))
+ goto fallback;
+
wakeup_time = ktime_sub(vsync_time, ms_to_ktime(1));
msm_hrtimer_queue_work(&timer->work, wakeup_time,
@@ -253,6 +275,7 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state)
return;
}
+fallback:
/*
* If there is any async flush pending on updated crtcs, fold
* them into the current flush.