@@ -349,7 +349,7 @@ static const struct drm_plane_funcs sti_cursor_plane_helpers_funcs = {
.update_plane = sti_plane_update_plane,
.disable_plane = sti_plane_disable_plane,
.destroy = sti_cursor_destroy,
- .set_property = drm_atomic_helper_plane_set_property,
+ .set_property = sti_plane_set_property,
.reset = sti_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -885,7 +885,7 @@ static const struct drm_plane_funcs sti_gdp_plane_helpers_funcs = {
.update_plane = sti_plane_update_plane,
.disable_plane = sti_plane_disable_plane,
.destroy = sti_gdp_destroy,
- .set_property = drm_atomic_helper_plane_set_property,
+ .set_property = sti_plane_set_property,
.reset = sti_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -1255,7 +1255,7 @@ static const struct drm_plane_funcs sti_hqvdp_plane_helpers_funcs = {
.update_plane = sti_plane_update_plane,
.disable_plane = sti_plane_disable_plane,
.destroy = sti_hqvdp_destroy,
- .set_property = drm_atomic_helper_plane_set_property,
+ .set_property = sti_plane_set_property,
.reset = sti_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -132,6 +132,60 @@ void sti_plane_init_property(struct sti_plane *plane,
plane->drm_plane.base.id, sti_plane_to_str(plane));
}
+int sti_plane_set_property(struct drm_plane *plane,
+ struct drm_property *property, uint64_t val)
+{
+ /*
+ * Forked from drm_atomic_helper_plane_set_property().
+ * Here we do not wait for vblank if the client is not atomic, so
+ * DRM_IOCTL_MODE_OBJ_SETPROPERTY returns before vblank.
+ */
+ struct drm_atomic_state *state;
+ struct drm_plane_state *plane_state;
+ struct sti_private *private = plane->dev->dev_private;
+ int ret = 0;
+
+ state = drm_atomic_state_alloc(plane->dev);
+ if (!state)
+ return -ENOMEM;
+
+ /* ->set_property is always called with all locks held. */
+ state->acquire_ctx = plane->dev->mode_config.acquire_ctx;
+retry:
+ plane_state = drm_atomic_get_plane_state(state, plane);
+ if (IS_ERR(plane_state)) {
+ ret = PTR_ERR(plane_state);
+ goto fail;
+ }
+
+ ret = drm_atomic_plane_set_property(plane, plane_state,
+ property, val);
+ if (ret)
+ goto fail;
+
+ if (!private->filp->atomic)
+ state->legacy_cursor_update = true;
+
+ ret = drm_atomic_commit(state);
+ if (ret != 0)
+ goto fail;
+
+ /* Driver takes ownership of state on successful commit. */
+ return 0;
+fail:
+ if (ret == -EDEADLK)
+ goto backoff;
+
+ drm_atomic_state_free(state);
+
+ return ret;
+backoff:
+ drm_atomic_state_clear(state);
+ drm_atomic_legacy_backoff(state);
+
+ goto retry;
+}
+
int sti_plane_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb,
int crtc_x, int crtc_y,
@@ -82,6 +82,8 @@ void sti_plane_update_fps(struct sti_plane *plane,
void sti_plane_init_property(struct sti_plane *plane,
enum drm_plane_type type);
+int sti_plane_set_property(struct drm_plane *plane,
+ struct drm_property *property, uint64_t val);
void sti_plane_reset(struct drm_plane *plane);
int sti_plane_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
If the client does not set the ATOMIC capability, do not wait for vblank before returning an DRM_IOCTL_MODE_OBJ_SETPROPERTY call. In this way, a legacy framework (eg non-atomic Weston) can call several SETPROPERTY within the same Vsync cycle. This is implemented by setting the legacy_cursor_update flag, to behave the same way as DRM_IOCTL_MODE_CURSOR (not vblank synced). Change-Id: I6b6134eca57eca399bdda006ab1cb8280d4002d4 Signed-off-by: Fabien Dessenne <fabien.dessenne@st.com> --- drivers/gpu/drm/sti/sti_cursor.c | 2 +- drivers/gpu/drm/sti/sti_gdp.c | 2 +- drivers/gpu/drm/sti/sti_hqvdp.c | 2 +- drivers/gpu/drm/sti/sti_plane.c | 54 ++++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/sti/sti_plane.h | 2 ++ 5 files changed, 59 insertions(+), 3 deletions(-)