blob: c038ad71640d8a898430b87d974c742bfae18c09 [file] [log] [blame]
Patrick Williams2194f502022-10-16 14:26:09 -05001From 3bfadb22e58bdf7691f80f403dd85794f2b86ad6 Mon Sep 17 00:00:00 2001
2From: Liviu Dudau <liviu.dudau@arm.com>
3Date: Fri, 8 Jul 2022 16:39:21 +0100
4Subject: [PATCH] drm/komeda: Fix handling of atomic commits in the
5 atomic_commit_tail hook
6
7Komeda driver relies on the generic DRM atomic helper functions to handle
8commits. It only implements an atomic_commit_tail hook for the
9mode_config_helper_funcs and even that one is pretty close to the generic
10implementation with the exception of additional dma_fence signalling.
11
12What the generic helper framework doesn't do is waiting for the actual
13hardware to signal that the commit parameters have been written into the
14appropriate registers. As we signal CRTC events only on the irq handlers,
15we need to flush the configuration and wait for the hardware to respond.
16
17Add the Komeda specific implementation for atomic_commit_hw_done() that
18flushes and waits for flip done before calling drm_atomic_helper_commit_hw_done().
19
20The fix was prompted by a patch from Carsten Haitzler where he was trying to
21solve the same issue but in a different way that I think can lead to wrong
22event signaling to userspace.
23
24Upstream-Status: Backport [https://patchwork.freedesktop.org/patch/msgid/20220722122139.288486-1-liviu.dudau@arm.com]
25Reported-by: Carsten Haitzler <carsten.haitzler@arm.com>
26Tested-by: Carsten Haitzler <carsten.haitzler@arm.com>
27Reviewed-by: Carsten Haitzler <carsten.haitzler@arm.com>
28Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
29Link: https://patchwork.freedesktop.org/patch/msgid/20220722122139.288486-1-liviu.dudau@arm.com
30Signed-off-by: Ben Horgan <ben.horgan@arm.com>
31Change-Id: I0bd92150120eb929692c1d38c4d1077d38401cdd
32Signed-off-by: Rupinderjit Singh <rupinderjit.singh@arm.com>
33---
34 .../gpu/drm/arm/display/komeda/komeda_crtc.c | 4 ++--
35 .../gpu/drm/arm/display/komeda/komeda_kms.c | 21 ++++++++++++++++++-
36 .../gpu/drm/arm/display/komeda/komeda_kms.h | 2 ++
37 3 files changed, 24 insertions(+), 3 deletions(-)
38
39diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
40index 59172acb9738..292f533d8cf0 100644
41--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
42+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
43@@ -235,7 +235,7 @@ void komeda_crtc_handle_event(struct komeda_crtc *kcrtc,
44 crtc->state->event = NULL;
45 drm_crtc_send_vblank_event(crtc, event);
46 } else {
47- DRM_WARN("CRTC[%d]: FLIP happen but no pending commit.\n",
48+ DRM_WARN("CRTC[%d]: FLIP happened but no pending commit.\n",
49 drm_crtc_index(&kcrtc->base));
50 }
51 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
52@@ -286,7 +286,7 @@ komeda_crtc_atomic_enable(struct drm_crtc *crtc,
53 komeda_crtc_do_flush(crtc, old);
54 }
55
56-static void
57+void
58 komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc *kcrtc,
59 struct completion *input_flip_done)
60 {
61diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
62index 8b2be8a9a27d..c434fb43d82c 100644
63--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
64+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
65@@ -69,6 +69,25 @@ static const struct drm_driver komeda_kms_driver = {
66 .minor = 1,
67 };
68
69+static void komeda_kms_atomic_commit_hw_done(struct drm_atomic_state *state)
70+{
71+ struct drm_device *dev = state->dev;
72+ struct komeda_kms_dev *kms = to_kdev(dev);
73+ int i;
74+
75+ for (i = 0; i < kms->n_crtcs; i++) {
76+ struct komeda_crtc *kcrtc = &kms->crtcs[i];
77+
78+ if (kcrtc->base.state->active) {
79+ struct completion *flip_done = NULL;
80+ if (kcrtc->base.state->event)
81+ flip_done = kcrtc->base.state->event->base.completion;
82+ komeda_crtc_flush_and_wait_for_flip_done(kcrtc, flip_done);
83+ }
84+ }
85+ drm_atomic_helper_commit_hw_done(state);
86+}
87+
88 static void komeda_kms_commit_tail(struct drm_atomic_state *old_state)
89 {
90 struct drm_device *dev = old_state->dev;
91@@ -81,7 +100,7 @@ static void komeda_kms_commit_tail(struct drm_atomic_state *old_state)
92
93 drm_atomic_helper_commit_modeset_enables(dev, old_state);
94
95- drm_atomic_helper_commit_hw_done(old_state);
96+ komeda_kms_atomic_commit_hw_done(old_state);
97
98 drm_atomic_helper_wait_for_flip_done(dev, old_state);
99
100diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
101index 456f3c435719..bf6e8fba5061 100644
102--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
103+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
104@@ -182,6 +182,8 @@ void komeda_kms_cleanup_private_objs(struct komeda_kms_dev *kms);
105
106 void komeda_crtc_handle_event(struct komeda_crtc *kcrtc,
107 struct komeda_events *evts);
108+void komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc *kcrtc,
109+ struct completion *input_flip_done);
110
111 struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev);
112 void komeda_kms_detach(struct komeda_kms_dev *kms);
113--
1142.25.1
115