|
@@ -2077,6 +2077,7 @@ EXPORT_SYMBOL(drm_atomic_helper_swap_state);
|
|
* @src_y: y offset of @fb for panning
|
|
* @src_y: y offset of @fb for panning
|
|
* @src_w: width of source rectangle in @fb
|
|
* @src_w: width of source rectangle in @fb
|
|
* @src_h: height of source rectangle in @fb
|
|
* @src_h: height of source rectangle in @fb
|
|
|
|
+ * @ctx: lock acquire context
|
|
*
|
|
*
|
|
* Provides a default plane update handler using the atomic driver interface.
|
|
* Provides a default plane update handler using the atomic driver interface.
|
|
*
|
|
*
|
|
@@ -2089,7 +2090,8 @@ int drm_atomic_helper_update_plane(struct drm_plane *plane,
|
|
int crtc_x, int crtc_y,
|
|
int crtc_x, int crtc_y,
|
|
unsigned int crtc_w, unsigned int crtc_h,
|
|
unsigned int crtc_w, unsigned int crtc_h,
|
|
uint32_t src_x, uint32_t src_y,
|
|
uint32_t src_x, uint32_t src_y,
|
|
- uint32_t src_w, uint32_t src_h)
|
|
|
|
|
|
+ uint32_t src_w, uint32_t src_h,
|
|
|
|
+ struct drm_modeset_acquire_ctx *ctx)
|
|
{
|
|
{
|
|
struct drm_atomic_state *state;
|
|
struct drm_atomic_state *state;
|
|
struct drm_plane_state *plane_state;
|
|
struct drm_plane_state *plane_state;
|
|
@@ -2099,8 +2101,7 @@ int drm_atomic_helper_update_plane(struct drm_plane *plane,
|
|
if (!state)
|
|
if (!state)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
|
|
|
|
- state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
|
|
|
|
-retry:
|
|
|
|
|
|
+ state->acquire_ctx = ctx;
|
|
plane_state = drm_atomic_get_plane_state(state, plane);
|
|
plane_state = drm_atomic_get_plane_state(state, plane);
|
|
if (IS_ERR(plane_state)) {
|
|
if (IS_ERR(plane_state)) {
|
|
ret = PTR_ERR(plane_state);
|
|
ret = PTR_ERR(plane_state);
|
|
@@ -2125,59 +2126,33 @@ retry:
|
|
|
|
|
|
ret = drm_atomic_commit(state);
|
|
ret = drm_atomic_commit(state);
|
|
fail:
|
|
fail:
|
|
- if (ret == -EDEADLK)
|
|
|
|
- goto backoff;
|
|
|
|
-
|
|
|
|
drm_atomic_state_put(state);
|
|
drm_atomic_state_put(state);
|
|
return ret;
|
|
return ret;
|
|
-
|
|
|
|
-backoff:
|
|
|
|
- drm_atomic_state_clear(state);
|
|
|
|
- drm_atomic_legacy_backoff(state);
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * Someone might have exchanged the framebuffer while we dropped locks
|
|
|
|
- * in the backoff code. We need to fix up the fb refcount tracking the
|
|
|
|
- * core does for us.
|
|
|
|
- */
|
|
|
|
- plane->old_fb = plane->fb;
|
|
|
|
-
|
|
|
|
- goto retry;
|
|
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(drm_atomic_helper_update_plane);
|
|
EXPORT_SYMBOL(drm_atomic_helper_update_plane);
|
|
|
|
|
|
/**
|
|
/**
|
|
* drm_atomic_helper_disable_plane - Helper for primary plane disable using * atomic
|
|
* drm_atomic_helper_disable_plane - Helper for primary plane disable using * atomic
|
|
* @plane: plane to disable
|
|
* @plane: plane to disable
|
|
|
|
+ * @ctx: lock acquire context
|
|
*
|
|
*
|
|
* Provides a default plane disable handler using the atomic driver interface.
|
|
* Provides a default plane disable handler using the atomic driver interface.
|
|
*
|
|
*
|
|
* RETURNS:
|
|
* RETURNS:
|
|
* Zero on success, error code on failure
|
|
* Zero on success, error code on failure
|
|
*/
|
|
*/
|
|
-int drm_atomic_helper_disable_plane(struct drm_plane *plane)
|
|
|
|
|
|
+int drm_atomic_helper_disable_plane(struct drm_plane *plane,
|
|
|
|
+ struct drm_modeset_acquire_ctx *ctx)
|
|
{
|
|
{
|
|
struct drm_atomic_state *state;
|
|
struct drm_atomic_state *state;
|
|
struct drm_plane_state *plane_state;
|
|
struct drm_plane_state *plane_state;
|
|
int ret = 0;
|
|
int ret = 0;
|
|
|
|
|
|
- /*
|
|
|
|
- * FIXME: Without plane->crtc set we can't get at the implicit legacy
|
|
|
|
- * acquire context. The real fix will be to wire the acquire ctx through
|
|
|
|
- * everywhere we need it, but meanwhile prevent chaos by just skipping
|
|
|
|
- * this noop. The critical case is the cursor ioctls which a) only grab
|
|
|
|
- * crtc/cursor-plane locks (so we need the crtc to get at the right
|
|
|
|
- * acquire context) and b) can try to disable the plane multiple times.
|
|
|
|
- */
|
|
|
|
- if (!plane->crtc)
|
|
|
|
- return 0;
|
|
|
|
-
|
|
|
|
state = drm_atomic_state_alloc(plane->dev);
|
|
state = drm_atomic_state_alloc(plane->dev);
|
|
if (!state)
|
|
if (!state)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
|
|
|
|
- state->acquire_ctx = drm_modeset_legacy_acquire_ctx(plane->crtc);
|
|
|
|
-retry:
|
|
|
|
|
|
+ state->acquire_ctx = ctx;
|
|
plane_state = drm_atomic_get_plane_state(state, plane);
|
|
plane_state = drm_atomic_get_plane_state(state, plane);
|
|
if (IS_ERR(plane_state)) {
|
|
if (IS_ERR(plane_state)) {
|
|
ret = PTR_ERR(plane_state);
|
|
ret = PTR_ERR(plane_state);
|
|
@@ -2193,24 +2168,8 @@ retry:
|
|
|
|
|
|
ret = drm_atomic_commit(state);
|
|
ret = drm_atomic_commit(state);
|
|
fail:
|
|
fail:
|
|
- if (ret == -EDEADLK)
|
|
|
|
- goto backoff;
|
|
|
|
-
|
|
|
|
drm_atomic_state_put(state);
|
|
drm_atomic_state_put(state);
|
|
return ret;
|
|
return ret;
|
|
-
|
|
|
|
-backoff:
|
|
|
|
- drm_atomic_state_clear(state);
|
|
|
|
- drm_atomic_legacy_backoff(state);
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * Someone might have exchanged the framebuffer while we dropped locks
|
|
|
|
- * in the backoff code. We need to fix up the fb refcount tracking the
|
|
|
|
- * core does for us.
|
|
|
|
- */
|
|
|
|
- plane->old_fb = plane->fb;
|
|
|
|
-
|
|
|
|
- goto retry;
|
|
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(drm_atomic_helper_disable_plane);
|
|
EXPORT_SYMBOL(drm_atomic_helper_disable_plane);
|
|
|
|
|
|
@@ -2306,6 +2265,7 @@ static int update_output_state(struct drm_atomic_state *state,
|
|
/**
|
|
/**
|
|
* drm_atomic_helper_set_config - set a new config from userspace
|
|
* drm_atomic_helper_set_config - set a new config from userspace
|
|
* @set: mode set configuration
|
|
* @set: mode set configuration
|
|
|
|
+ * @ctx: lock acquisition context
|
|
*
|
|
*
|
|
* Provides a default crtc set_config handler using the atomic driver interface.
|
|
* Provides a default crtc set_config handler using the atomic driver interface.
|
|
*
|
|
*
|
|
@@ -2318,7 +2278,8 @@ static int update_output_state(struct drm_atomic_state *state,
|
|
* Returns:
|
|
* Returns:
|
|
* Returns 0 on success, negative errno numbers on failure.
|
|
* Returns 0 on success, negative errno numbers on failure.
|
|
*/
|
|
*/
|
|
-int drm_atomic_helper_set_config(struct drm_mode_set *set)
|
|
|
|
|
|
+int drm_atomic_helper_set_config(struct drm_mode_set *set,
|
|
|
|
+ struct drm_modeset_acquire_ctx *ctx)
|
|
{
|
|
{
|
|
struct drm_atomic_state *state;
|
|
struct drm_atomic_state *state;
|
|
struct drm_crtc *crtc = set->crtc;
|
|
struct drm_crtc *crtc = set->crtc;
|
|
@@ -2329,32 +2290,16 @@ int drm_atomic_helper_set_config(struct drm_mode_set *set)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
|
|
|
|
state->legacy_set_config = true;
|
|
state->legacy_set_config = true;
|
|
- state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
|
|
|
|
-retry:
|
|
|
|
|
|
+ state->acquire_ctx = ctx;
|
|
ret = __drm_atomic_helper_set_config(set, state);
|
|
ret = __drm_atomic_helper_set_config(set, state);
|
|
if (ret != 0)
|
|
if (ret != 0)
|
|
goto fail;
|
|
goto fail;
|
|
|
|
|
|
ret = drm_atomic_commit(state);
|
|
ret = drm_atomic_commit(state);
|
|
-fail:
|
|
|
|
- if (ret == -EDEADLK)
|
|
|
|
- goto backoff;
|
|
|
|
|
|
|
|
|
|
+fail:
|
|
drm_atomic_state_put(state);
|
|
drm_atomic_state_put(state);
|
|
return ret;
|
|
return ret;
|
|
-
|
|
|
|
-backoff:
|
|
|
|
- drm_atomic_state_clear(state);
|
|
|
|
- drm_atomic_legacy_backoff(state);
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * Someone might have exchanged the framebuffer while we dropped locks
|
|
|
|
- * in the backoff code. We need to fix up the fb refcount tracking the
|
|
|
|
- * core does for us.
|
|
|
|
- */
|
|
|
|
- crtc->primary->old_fb = crtc->primary->fb;
|
|
|
|
-
|
|
|
|
- goto retry;
|
|
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(drm_atomic_helper_set_config);
|
|
EXPORT_SYMBOL(drm_atomic_helper_set_config);
|
|
|
|
|
|
@@ -2443,7 +2388,8 @@ commit:
|
|
* that they are connected to.
|
|
* that they are connected to.
|
|
*
|
|
*
|
|
* This is used for example in suspend/resume to disable all currently active
|
|
* This is used for example in suspend/resume to disable all currently active
|
|
- * functions when suspending.
|
|
|
|
|
|
+ * functions when suspending. If you just want to shut down everything at e.g.
|
|
|
|
+ * driver unload, look at drm_atomic_helper_shutdown().
|
|
*
|
|
*
|
|
* Note that if callers haven't already acquired all modeset locks this might
|
|
* Note that if callers haven't already acquired all modeset locks this might
|
|
* return -EDEADLK, which must be handled by calling drm_modeset_backoff().
|
|
* return -EDEADLK, which must be handled by calling drm_modeset_backoff().
|
|
@@ -2452,7 +2398,8 @@ commit:
|
|
* 0 on success or a negative error code on failure.
|
|
* 0 on success or a negative error code on failure.
|
|
*
|
|
*
|
|
* See also:
|
|
* See also:
|
|
- * drm_atomic_helper_suspend(), drm_atomic_helper_resume()
|
|
|
|
|
|
+ * drm_atomic_helper_suspend(), drm_atomic_helper_resume() and
|
|
|
|
+ * drm_atomic_helper_shutdown().
|
|
*/
|
|
*/
|
|
int drm_atomic_helper_disable_all(struct drm_device *dev,
|
|
int drm_atomic_helper_disable_all(struct drm_device *dev,
|
|
struct drm_modeset_acquire_ctx *ctx)
|
|
struct drm_modeset_acquire_ctx *ctx)
|
|
@@ -2516,6 +2463,42 @@ free:
|
|
|
|
|
|
EXPORT_SYMBOL(drm_atomic_helper_disable_all);
|
|
EXPORT_SYMBOL(drm_atomic_helper_disable_all);
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * drm_atomic_helper_shutdown - shutdown all CRTC
|
|
|
|
+ * @dev: DRM device
|
|
|
|
+ *
|
|
|
|
+ * This shuts down all CRTC, which is useful for driver unloading. Shutdown on
|
|
|
|
+ * suspend should instead be handled with drm_atomic_helper_suspend(), since
|
|
|
|
+ * that also takes a snapshot of the modeset state to be restored on resume.
|
|
|
|
+ *
|
|
|
|
+ * This is just a convenience wrapper around drm_atomic_helper_disable_all(),
|
|
|
|
+ * and it is the atomic version of drm_crtc_force_disable_all().
|
|
|
|
+ */
|
|
|
|
+void drm_atomic_helper_shutdown(struct drm_device *dev)
|
|
|
|
+{
|
|
|
|
+ struct drm_modeset_acquire_ctx ctx;
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ drm_modeset_acquire_init(&ctx, 0);
|
|
|
|
+ while (1) {
|
|
|
|
+ ret = drm_modeset_lock_all_ctx(dev, &ctx);
|
|
|
|
+ if (!ret)
|
|
|
|
+ ret = drm_atomic_helper_disable_all(dev, &ctx);
|
|
|
|
+
|
|
|
|
+ if (ret != -EDEADLK)
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ drm_modeset_backoff(&ctx);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (ret)
|
|
|
|
+ DRM_ERROR("Disabling all crtc's during unload failed with %i\n", ret);
|
|
|
|
+
|
|
|
|
+ drm_modeset_drop_locks(&ctx);
|
|
|
|
+ drm_modeset_acquire_fini(&ctx);
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL(drm_atomic_helper_shutdown);
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* drm_atomic_helper_suspend - subsystem-level suspend helper
|
|
* drm_atomic_helper_suspend - subsystem-level suspend helper
|
|
* @dev: DRM device
|
|
* @dev: DRM device
|
|
@@ -2862,6 +2845,7 @@ static int page_flip_common(
|
|
* @fb: DRM framebuffer
|
|
* @fb: DRM framebuffer
|
|
* @event: optional DRM event to signal upon completion
|
|
* @event: optional DRM event to signal upon completion
|
|
* @flags: flip flags for non-vblank sync'ed updates
|
|
* @flags: flip flags for non-vblank sync'ed updates
|
|
|
|
+ * @ctx: lock acquisition context
|
|
*
|
|
*
|
|
* Provides a default &drm_crtc_funcs.page_flip implementation
|
|
* Provides a default &drm_crtc_funcs.page_flip implementation
|
|
* using the atomic driver interface.
|
|
* using the atomic driver interface.
|
|
@@ -2875,7 +2859,8 @@ static int page_flip_common(
|
|
int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
|
|
int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
|
|
struct drm_framebuffer *fb,
|
|
struct drm_framebuffer *fb,
|
|
struct drm_pending_vblank_event *event,
|
|
struct drm_pending_vblank_event *event,
|
|
- uint32_t flags)
|
|
|
|
|
|
+ uint32_t flags,
|
|
|
|
+ struct drm_modeset_acquire_ctx *ctx)
|
|
{
|
|
{
|
|
struct drm_plane *plane = crtc->primary;
|
|
struct drm_plane *plane = crtc->primary;
|
|
struct drm_atomic_state *state;
|
|
struct drm_atomic_state *state;
|
|
@@ -2885,34 +2870,16 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
|
|
if (!state)
|
|
if (!state)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
|
|
|
|
- state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
|
|
|
|
|
|
+ state->acquire_ctx = ctx;
|
|
|
|
|
|
-retry:
|
|
|
|
ret = page_flip_common(state, crtc, fb, event, flags);
|
|
ret = page_flip_common(state, crtc, fb, event, flags);
|
|
if (ret != 0)
|
|
if (ret != 0)
|
|
goto fail;
|
|
goto fail;
|
|
|
|
|
|
ret = drm_atomic_nonblocking_commit(state);
|
|
ret = drm_atomic_nonblocking_commit(state);
|
|
-
|
|
|
|
fail:
|
|
fail:
|
|
- if (ret == -EDEADLK)
|
|
|
|
- goto backoff;
|
|
|
|
-
|
|
|
|
drm_atomic_state_put(state);
|
|
drm_atomic_state_put(state);
|
|
return ret;
|
|
return ret;
|
|
-
|
|
|
|
-backoff:
|
|
|
|
- drm_atomic_state_clear(state);
|
|
|
|
- drm_atomic_legacy_backoff(state);
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * Someone might have exchanged the framebuffer while we dropped locks
|
|
|
|
- * in the backoff code. We need to fix up the fb refcount tracking the
|
|
|
|
- * core does for us.
|
|
|
|
- */
|
|
|
|
- plane->old_fb = plane->fb;
|
|
|
|
-
|
|
|
|
- goto retry;
|
|
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(drm_atomic_helper_page_flip);
|
|
EXPORT_SYMBOL(drm_atomic_helper_page_flip);
|
|
|
|
|
|
@@ -2923,6 +2890,7 @@ EXPORT_SYMBOL(drm_atomic_helper_page_flip);
|
|
* @event: optional DRM event to signal upon completion
|
|
* @event: optional DRM event to signal upon completion
|
|
* @flags: flip flags for non-vblank sync'ed updates
|
|
* @flags: flip flags for non-vblank sync'ed updates
|
|
* @target: specifying the target vblank period when the flip to take effect
|
|
* @target: specifying the target vblank period when the flip to take effect
|
|
|
|
+ * @ctx: lock acquisition context
|
|
*
|
|
*
|
|
* Provides a default &drm_crtc_funcs.page_flip_target implementation.
|
|
* Provides a default &drm_crtc_funcs.page_flip_target implementation.
|
|
* Similar to drm_atomic_helper_page_flip() with extra parameter to specify
|
|
* Similar to drm_atomic_helper_page_flip() with extra parameter to specify
|
|
@@ -2936,7 +2904,8 @@ int drm_atomic_helper_page_flip_target(
|
|
struct drm_framebuffer *fb,
|
|
struct drm_framebuffer *fb,
|
|
struct drm_pending_vblank_event *event,
|
|
struct drm_pending_vblank_event *event,
|
|
uint32_t flags,
|
|
uint32_t flags,
|
|
- uint32_t target)
|
|
|
|
|
|
+ uint32_t target,
|
|
|
|
+ struct drm_modeset_acquire_ctx *ctx)
|
|
{
|
|
{
|
|
struct drm_plane *plane = crtc->primary;
|
|
struct drm_plane *plane = crtc->primary;
|
|
struct drm_atomic_state *state;
|
|
struct drm_atomic_state *state;
|
|
@@ -2947,9 +2916,8 @@ int drm_atomic_helper_page_flip_target(
|
|
if (!state)
|
|
if (!state)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
|
|
|
|
- state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
|
|
|
|
|
|
+ state->acquire_ctx = ctx;
|
|
|
|
|
|
-retry:
|
|
|
|
ret = page_flip_common(state, crtc, fb, event, flags);
|
|
ret = page_flip_common(state, crtc, fb, event, flags);
|
|
if (ret != 0)
|
|
if (ret != 0)
|
|
goto fail;
|
|
goto fail;
|
|
@@ -2962,26 +2930,9 @@ retry:
|
|
crtc_state->target_vblank = target;
|
|
crtc_state->target_vblank = target;
|
|
|
|
|
|
ret = drm_atomic_nonblocking_commit(state);
|
|
ret = drm_atomic_nonblocking_commit(state);
|
|
-
|
|
|
|
fail:
|
|
fail:
|
|
- if (ret == -EDEADLK)
|
|
|
|
- goto backoff;
|
|
|
|
-
|
|
|
|
drm_atomic_state_put(state);
|
|
drm_atomic_state_put(state);
|
|
return ret;
|
|
return ret;
|
|
-
|
|
|
|
-backoff:
|
|
|
|
- drm_atomic_state_clear(state);
|
|
|
|
- drm_atomic_legacy_backoff(state);
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * Someone might have exchanged the framebuffer while we dropped locks
|
|
|
|
- * in the backoff code. We need to fix up the fb refcount tracking the
|
|
|
|
- * core does for us.
|
|
|
|
- */
|
|
|
|
- plane->old_fb = plane->fb;
|
|
|
|
-
|
|
|
|
- goto retry;
|
|
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(drm_atomic_helper_page_flip_target);
|
|
EXPORT_SYMBOL(drm_atomic_helper_page_flip_target);
|
|
|
|
|