diff options
author | Dave Airlie <airlied@redhat.com> | 2017-02-15 22:27:55 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-02-15 22:27:55 -0500 |
commit | b7bc0daa889e65db202f3222f5b69b5c80d4070f (patch) | |
tree | 733f6ebe15dc5d53441e6fe21e464ba39b3e6b31 | |
parent | 1e9d996645401f1a5bd6473e229a4d41575fc478 (diff) | |
parent | 1592364de3912dad264262f4bcc61552984c9523 (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.c | 106 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_crtc_internal.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_framebuffer.c | 7 | ||||
-rw-r--r-- | include/uapi/linux/Kbuild | 1 |
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 | ||
2049 | int 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 | |||
2067 | retry: | ||
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 | |||
2127 | unlock: | ||
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 | |||
2049 | int drm_mode_atomic_ioctl(struct drm_device *dev, | 2155 | int 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); |
184 | int drm_mode_atomic_ioctl(struct drm_device *dev, | 184 | int drm_mode_atomic_ioctl(struct drm_device *dev, |
185 | void *data, struct drm_file *file_priv); | 185 | void *data, struct drm_file *file_priv); |
186 | int 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 | ||
799 | out: | ||
793 | drm_framebuffer_unreference(fb); | 800 | drm_framebuffer_unreference(fb); |
794 | } | 801 | } |
795 | EXPORT_SYMBOL(drm_framebuffer_remove); | 802 | EXPORT_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 | |||
109 | header-y += dlm_plock.h | 109 | header-y += dlm_plock.h |
110 | header-y += dm-ioctl.h | 110 | header-y += dm-ioctl.h |
111 | header-y += dm-log-userspace.h | 111 | header-y += dm-log-userspace.h |
112 | header-y += dma-buf.h | ||
112 | header-y += dn.h | 113 | header-y += dn.h |
113 | header-y += dqblk_xfs.h | 114 | header-y += dqblk_xfs.h |
114 | header-y += edd.h | 115 | header-y += edd.h |