aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-02-15 22:27:55 -0500
committerDave Airlie <airlied@redhat.com>2017-02-15 22:27:55 -0500
commitb7bc0daa889e65db202f3222f5b69b5c80d4070f (patch)
tree733f6ebe15dc5d53441e6fe21e464ba39b3e6b31
parent1e9d996645401f1a5bd6473e229a4d41575fc478 (diff)
parent1592364de3912dad264262f4bcc61552984c9523 (diff)
Merge tag 'drm-misc-next-fixes-2017-02-15' of git://anongit.freedesktop.org/git/drm-misc into drm-next
Fixes for the v4.11 merge window. * tag 'drm-misc-next-fixes-2017-02-15' of git://anongit.freedesktop.org/git/drm-misc: drm: Resurrect atomic rmfb code, v3 uapi: add missing install of dma-buf.h
-rw-r--r--drivers/gpu/drm/drm_atomic.c106
-rw-r--r--drivers/gpu/drm/drm_crtc_internal.h1
-rw-r--r--drivers/gpu/drm/drm_framebuffer.c7
-rw-r--r--include/uapi/linux/Kbuild1
4 files changed, 115 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index c97588a28216..11f102e7ddfd 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -2046,6 +2046,112 @@ static void complete_crtc_signaling(struct drm_device *dev,
2046 kfree(fence_state); 2046 kfree(fence_state);
2047} 2047}
2048 2048
2049int drm_atomic_remove_fb(struct drm_framebuffer *fb)
2050{
2051 struct drm_modeset_acquire_ctx ctx;
2052 struct drm_device *dev = fb->dev;
2053 struct drm_atomic_state *state;
2054 struct drm_plane *plane;
2055 struct drm_connector *conn;
2056 struct drm_connector_state *conn_state;
2057 int i, ret = 0;
2058 unsigned plane_mask, disable_crtcs = false;
2059
2060 state = drm_atomic_state_alloc(dev);
2061 if (!state)
2062 return -ENOMEM;
2063
2064 drm_modeset_acquire_init(&ctx, 0);
2065 state->acquire_ctx = &ctx;
2066
2067retry:
2068 plane_mask = 0;
2069 ret = drm_modeset_lock_all_ctx(dev, &ctx);
2070 if (ret)
2071 goto unlock;
2072
2073 drm_for_each_plane(plane, dev) {
2074 struct drm_plane_state *plane_state;
2075
2076 if (plane->state->fb != fb)
2077 continue;
2078
2079 plane_state = drm_atomic_get_plane_state(state, plane);
2080 if (IS_ERR(plane_state)) {
2081 ret = PTR_ERR(plane_state);
2082 goto unlock;
2083 }
2084
2085 /*
2086 * Some drivers do not support keeping crtc active with the
2087 * primary plane disabled. If we fail to commit with -EINVAL
2088 * then we will try to perform the same commit but with all
2089 * crtc's disabled for primary planes as well.
2090 */
2091 if (disable_crtcs && plane_state->crtc->primary == plane) {
2092 struct drm_crtc_state *crtc_state;
2093
2094 crtc_state = drm_atomic_get_existing_crtc_state(state, plane_state->crtc);
2095
2096 ret = drm_atomic_add_affected_connectors(state, plane_state->crtc);
2097 if (ret)
2098 goto unlock;
2099
2100 crtc_state->active = false;
2101 ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL);
2102 if (ret)
2103 goto unlock;
2104 }
2105
2106 drm_atomic_set_fb_for_plane(plane_state, NULL);
2107 ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
2108 if (ret)
2109 goto unlock;
2110
2111 plane_mask |= BIT(drm_plane_index(plane));
2112
2113 plane->old_fb = plane->fb;
2114 }
2115
2116 /* This list is only not empty when disable_crtcs is set. */
2117 for_each_connector_in_state(state, conn, conn_state, i) {
2118 ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
2119
2120 if (ret)
2121 goto unlock;
2122 }
2123
2124 if (plane_mask)
2125 ret = drm_atomic_commit(state);
2126
2127unlock:
2128 if (plane_mask)
2129 drm_atomic_clean_old_fb(dev, plane_mask, ret);
2130
2131 if (ret == -EDEADLK) {
2132 drm_modeset_backoff(&ctx);
2133 goto retry;
2134 }
2135
2136 drm_atomic_state_put(state);
2137
2138 if (ret == -EINVAL && !disable_crtcs) {
2139 disable_crtcs = true;
2140
2141 state = drm_atomic_state_alloc(dev);
2142 if (state) {
2143 state->acquire_ctx = &ctx;
2144 goto retry;
2145 }
2146 ret = -ENOMEM;
2147 }
2148
2149 drm_modeset_drop_locks(&ctx);
2150 drm_modeset_acquire_fini(&ctx);
2151
2152 return ret;
2153}
2154
2049int drm_mode_atomic_ioctl(struct drm_device *dev, 2155int drm_mode_atomic_ioctl(struct drm_device *dev,
2050 void *data, struct drm_file *file_priv) 2156 void *data, struct drm_file *file_priv)
2051{ 2157{
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index 955c5690bf64..e0678f8a51cf 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -183,6 +183,7 @@ int drm_atomic_get_property(struct drm_mode_object *obj,
183 struct drm_property *property, uint64_t *val); 183 struct drm_property *property, uint64_t *val);
184int drm_mode_atomic_ioctl(struct drm_device *dev, 184int drm_mode_atomic_ioctl(struct drm_device *dev,
185 void *data, struct drm_file *file_priv); 185 void *data, struct drm_file *file_priv);
186int drm_atomic_remove_fb(struct drm_framebuffer *fb);
186 187
187 188
188/* drm_plane.c */ 189/* drm_plane.c */
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index 28a0108a1ab8..c0e593a7f9b4 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -773,6 +773,12 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb)
773 * in this manner. 773 * in this manner.
774 */ 774 */
775 if (drm_framebuffer_read_refcount(fb) > 1) { 775 if (drm_framebuffer_read_refcount(fb) > 1) {
776 if (drm_drv_uses_atomic_modeset(dev)) {
777 int ret = drm_atomic_remove_fb(fb);
778 WARN(ret, "atomic remove_fb failed with %i\n", ret);
779 goto out;
780 }
781
776 drm_modeset_lock_all(dev); 782 drm_modeset_lock_all(dev);
777 /* remove from any CRTC */ 783 /* remove from any CRTC */
778 drm_for_each_crtc(crtc, dev) { 784 drm_for_each_crtc(crtc, dev) {
@@ -790,6 +796,7 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb)
790 drm_modeset_unlock_all(dev); 796 drm_modeset_unlock_all(dev);
791 } 797 }
792 798
799out:
793 drm_framebuffer_unreference(fb); 800 drm_framebuffer_unreference(fb);
794} 801}
795EXPORT_SYMBOL(drm_framebuffer_remove); 802EXPORT_SYMBOL(drm_framebuffer_remove);
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index f330ba4547cf..900129c8f6cf 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -109,6 +109,7 @@ header-y += dlm_netlink.h
109header-y += dlm_plock.h 109header-y += dlm_plock.h
110header-y += dm-ioctl.h 110header-y += dm-ioctl.h
111header-y += dm-log-userspace.h 111header-y += dm-log-userspace.h
112header-y += dma-buf.h
112header-y += dn.h 113header-y += dn.h
113header-y += dqblk_xfs.h 114header-y += dqblk_xfs.h
114header-y += edd.h 115header-y += edd.h