]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/appletbdrm: Allocate request/response buffers in begin_fb_access
authorThomas Zimmermann <tzimmermann@suse.de>
Wed, 10 Jun 2026 15:18:21 +0000 (17:18 +0200)
committerThomas Zimmermann <tzimmermann@suse.de>
Fri, 17 Jul 2026 15:15:49 +0000 (17:15 +0200)
In atomic_check, damage handling is not fully evaluated. Another
atomic_check helper could trigger a full modeset and thus invalidate
damage clips.

Allocation of the request/response buffers in appletbdrm depends on
correct damage information. Otherwise it might allocate incorrectly
sized buffers. Allocate the buffers in the driver's begin_fb_access
helper. It runs early during the commit when damage clipping has been
fully evaluated.

v5:
- pass plane state as the old damage-iterator state
v2:
- allocate before drm_gem_begin_shadow_fb_access() to avoid leak on error

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Acked-by: Aditya Garg <gargaditya08@proton.me>
Acked-by: Zack Rusin <zack.rusin@broadcom.com>
Link: https://patch.msgid.link/20260610152505.260172-6-tzimmermann@suse.de
drivers/gpu/drm/tiny/appletbdrm.c

index cdd35af4989207a533d77009ca5bdadebf3f8c99..ef71b9957961949b8e9be45018fdd99c438b0c7a 100644 (file)
@@ -315,33 +315,16 @@ static const u32 appletbdrm_primary_plane_formats[] = {
        DRM_FORMAT_XRGB8888, /* emulated */
 };
 
-static int appletbdrm_primary_plane_helper_atomic_check(struct drm_plane *plane,
-                                                  struct drm_atomic_commit *state)
+static int appletbdrm_primary_plane_helper_begin_fb_access(struct drm_plane *plane,
+                                                          struct drm_plane_state *new_plane_state)
 {
-       struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane);
-       struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
-       struct drm_crtc *new_crtc = new_plane_state->crtc;
-       struct drm_crtc_state *new_crtc_state = NULL;
        struct appletbdrm_plane_state *appletbdrm_state = to_appletbdrm_plane_state(new_plane_state);
+       size_t frames_size = 0;
        struct drm_atomic_helper_damage_iter iter;
        struct drm_rect damage;
-       size_t frames_size = 0;
        size_t request_size;
-       int ret;
-
-       if (new_crtc)
-               new_crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc);
 
-       ret = drm_atomic_helper_check_plane_state(new_plane_state, new_crtc_state,
-                                                 DRM_PLANE_NO_SCALING,
-                                                 DRM_PLANE_NO_SCALING,
-                                                 false, false);
-       if (ret)
-               return ret;
-       else if (!new_plane_state->visible)
-               return 0;
-
-       drm_atomic_helper_damage_iter_init(&iter, old_plane_state, new_plane_state);
+       drm_atomic_helper_damage_iter_init(&iter, plane->state, new_plane_state);
        drm_atomic_for_each_plane_damage(&iter, &damage) {
                frames_size += struct_size((struct appletbdrm_frame *)0, buf, rect_size(&damage));
        }
@@ -366,6 +349,29 @@ static int appletbdrm_primary_plane_helper_atomic_check(struct drm_plane *plane,
        appletbdrm_state->request_size = request_size;
        appletbdrm_state->frames_size = frames_size;
 
+       return drm_gem_begin_shadow_fb_access(plane, new_plane_state);
+}
+
+static int appletbdrm_primary_plane_helper_atomic_check(struct drm_plane *plane,
+                                                       struct drm_atomic_commit *state)
+{
+       struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane);
+       struct drm_crtc *new_crtc = new_plane_state->crtc;
+       struct drm_crtc_state *new_crtc_state = NULL;
+       int ret;
+
+       if (new_crtc)
+               new_crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc);
+
+       ret = drm_atomic_helper_check_plane_state(new_plane_state, new_crtc_state,
+                                                 DRM_PLANE_NO_SCALING,
+                                                 DRM_PLANE_NO_SCALING,
+                                                 false, false);
+       if (ret)
+               return ret;
+       else if (!new_plane_state->visible)
+               return 0;
+
        return 0;
 }
 
@@ -468,7 +474,7 @@ end_fb_cpu_access:
 }
 
 static void appletbdrm_primary_plane_helper_atomic_update(struct drm_plane *plane,
-                                                    struct drm_atomic_commit *old_state)
+                                                         struct drm_atomic_commit *old_state)
 {
        struct appletbdrm_device *adev = drm_to_adev(plane->dev);
        struct drm_device *drm = plane->dev;
@@ -552,7 +558,8 @@ static void appletbdrm_primary_plane_destroy_state(struct drm_plane *plane,
 }
 
 static const struct drm_plane_helper_funcs appletbdrm_primary_plane_helper_funcs = {
-       DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
+       .begin_fb_access = appletbdrm_primary_plane_helper_begin_fb_access,
+       .end_fb_access = drm_gem_end_shadow_fb_access,
        .atomic_check = appletbdrm_primary_plane_helper_atomic_check,
        .atomic_update = appletbdrm_primary_plane_helper_atomic_update,
        .atomic_disable = appletbdrm_primary_plane_helper_atomic_disable,