Skip to content

Commit 846c7df

Browse files
committed
drm/atomic: Try to preserve the crtc enabled state in drm_atomic_remove_fb, v2.
This introduces a slight behavioral change to rmfb. Instead of disabling a crtc when the primary plane is disabled, we try to preserve it. Apart from old versions of the vmwgfx xorg driver, there is nothing depending on rmfb disabling a crtc. Vmwgfx' and simple kms helper atomic implementation rejects CRTC enabled without plane, so we can do this safely. If the atomic commit is rejected by the driver then we will still fall back to the old behavior and turn off the crtc. Changes since v1: - Restart completely when rmfb with crtc on fails (Sean Paul). Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Sean Paul <seanpaul@chromium.org> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@ubuntu.com> Link: https://patchwork.freedesktop.org/patch/msgid/20171101150433.10777-1-maarten.lankhorst@linux.intel.com Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
1 parent 79436a1 commit 846c7df

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed

drivers/gpu/drm/drm_framebuffer.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -765,14 +765,18 @@ static int atomic_remove_fb(struct drm_framebuffer *fb)
765765
struct drm_plane *plane;
766766
struct drm_connector *conn;
767767
struct drm_connector_state *conn_state;
768-
int i, ret = 0;
768+
int i, ret;
769769
unsigned plane_mask;
770+
bool disable_crtcs = false;
770771

771-
state = drm_atomic_state_alloc(dev);
772-
if (!state)
773-
return -ENOMEM;
774-
772+
retry_disable:
775773
drm_modeset_acquire_init(&ctx, 0);
774+
775+
state = drm_atomic_state_alloc(dev);
776+
if (!state) {
777+
ret = -ENOMEM;
778+
goto out;
779+
}
776780
state->acquire_ctx = &ctx;
777781

778782
retry:
@@ -793,7 +797,7 @@ static int atomic_remove_fb(struct drm_framebuffer *fb)
793797
goto unlock;
794798
}
795799

796-
if (plane_state->crtc->primary == plane) {
800+
if (disable_crtcs && plane_state->crtc->primary == plane) {
797801
struct drm_crtc_state *crtc_state;
798802

799803
crtc_state = drm_atomic_get_existing_crtc_state(state, plane_state->crtc);
@@ -818,6 +822,7 @@ static int atomic_remove_fb(struct drm_framebuffer *fb)
818822
plane->old_fb = plane->fb;
819823
}
820824

825+
/* This list is only filled when disable_crtcs is set. */
821826
for_each_new_connector_in_state(state, conn, conn_state, i) {
822827
ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
823828

@@ -840,9 +845,15 @@ static int atomic_remove_fb(struct drm_framebuffer *fb)
840845

841846
drm_atomic_state_put(state);
842847

848+
out:
843849
drm_modeset_drop_locks(&ctx);
844850
drm_modeset_acquire_fini(&ctx);
845851

852+
if (ret == -EINVAL && !disable_crtcs) {
853+
disable_crtcs = true;
854+
goto retry_disable;
855+
}
856+
846857
return ret;
847858
}
848859

0 commit comments

Comments
 (0)