diff options
author | Philipp Zabel <p.zabel@pengutronix.de> | 2017-02-24 12:31:05 -0500 |
---|---|---|
committer | Philipp Zabel <p.zabel@pengutronix.de> | 2017-03-15 10:42:29 -0400 |
commit | eb8c88808c8307b05ce42e101753cb2518c6d14e (patch) | |
tree | 611b38e501938c45ff62972b62f480838f057213 /drivers/gpu/drm/imx/imx-drm-core.c | |
parent | cf92fefd040e6117fbcd4ce2baa9c54ae515e0c6 (diff) |
drm/imx: add deferred plane disabling
The DP (display processor) channel disable code tried to busy wait for
the DP sync flow end interrupt status bit when disabling the partial
plane without a full modeset. That never worked reliably, and it was
disabled completely by the recent "gpu: ipu-v3: remove IRQ dance on DC
channel disable" patch, causing ipu_wait_interrupt to always time out
after 50 ms, which in turn would trigger a timeout in
drm_atomic_helper_wait_for_vblanks.
This patch changes ipu_plane_atomic_disable to only queue a DP channel
register update at the next frame boundary and set a flag, which can be
done without any waiting whatsoever. The imx_drm_atomic_commit_tail then
calls a new ipu_plane_disable_deferred function that does the actual
IDMAC teardown of the planes that are flagged for deferred disabling,
after waiting for the vblank.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
Diffstat (limited to 'drivers/gpu/drm/imx/imx-drm-core.c')
-rw-r--r-- | drivers/gpu/drm/imx/imx-drm-core.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index 2566e4dbe92e..cd3c2013ea70 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <video/imx-ipu-v3.h> | 30 | #include <video/imx-ipu-v3.h> |
31 | 31 | ||
32 | #include "imx-drm.h" | 32 | #include "imx-drm.h" |
33 | #include "ipuv3-plane.h" | ||
33 | 34 | ||
34 | #define MAX_CRTC 4 | 35 | #define MAX_CRTC 4 |
35 | 36 | ||
@@ -122,6 +123,10 @@ static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = { | |||
122 | static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state) | 123 | static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state) |
123 | { | 124 | { |
124 | struct drm_device *dev = state->dev; | 125 | struct drm_device *dev = state->dev; |
126 | struct drm_plane *plane; | ||
127 | struct drm_plane_state *old_plane_state; | ||
128 | bool plane_disabling = false; | ||
129 | int i; | ||
125 | 130 | ||
126 | drm_atomic_helper_commit_modeset_disables(dev, state); | 131 | drm_atomic_helper_commit_modeset_disables(dev, state); |
127 | 132 | ||
@@ -131,6 +136,19 @@ static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state) | |||
131 | 136 | ||
132 | drm_atomic_helper_commit_modeset_enables(dev, state); | 137 | drm_atomic_helper_commit_modeset_enables(dev, state); |
133 | 138 | ||
139 | for_each_plane_in_state(state, plane, old_plane_state, i) { | ||
140 | if (drm_atomic_plane_disabling(old_plane_state, plane->state)) | ||
141 | plane_disabling = true; | ||
142 | } | ||
143 | |||
144 | if (plane_disabling) { | ||
145 | drm_atomic_helper_wait_for_vblanks(dev, state); | ||
146 | |||
147 | for_each_plane_in_state(state, plane, old_plane_state, i) | ||
148 | ipu_plane_disable_deferred(plane); | ||
149 | |||
150 | } | ||
151 | |||
134 | drm_atomic_helper_commit_hw_done(state); | 152 | drm_atomic_helper_commit_hw_done(state); |
135 | } | 153 | } |
136 | 154 | ||