]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/mipi-dbi: Only modify planes on enabled CRTCs
authorThomas Zimmermann <tzimmermann@suse.de>
Thu, 19 Mar 2026 15:59:37 +0000 (16:59 +0100)
committerThomas Zimmermann <tzimmermann@suse.de>
Wed, 25 Mar 2026 14:04:24 +0000 (15:04 +0100)
Use drm_atomic_helper_commit_tail_rpm() as commit tail to update the
plane after enabling the CRTC. Then remove the plane-update code from
mipi_dbi_enable_flush() and inline the remaining backlight code where
necessary.

Mipi-dbi's current commit tail drm_atomic_helper_commit_tail() first
updates the plane and then enables the CRTC. But the CRTC enablement
includes power management that prevents the initial plane update from
working. Hence, each mipi-dbi driver includes a plane update in their
CRTC enablement; in the form of mipi_dbi_enable_flush() or custom code.

Using drm_atomic_helper_commit_tail_rpm() enables the CRTC before any
plane updates. Hence the additional plane update can be removed from
mipi_dbi_enable_flush() and a number of drivers.

This leaves backlight_enable() in the helper, which can now be inlined
into affected drivers. Drivers now enable the CRTC plus an optional
backlight and then automatically update the plane.

In the case of disabling the display, drm_atomic_helper_commit_tail_rpm()
only disables the CRTC without touching the plane at all. Mipi-dbi's
mipi_dbi_pipe_disable() already contains the necessary logic.

Removing the plane update from the CRTC enablement will also help with
converting mipi-dbi from simple-pipe helpers to regular atomic helpers.

v3:
- st7586: remove unused variable
v2:
- ili9225: remove unused variables (David)
- st7586: remove unused variables (David)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Acked-by: David Lechner <david@lechnology.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Link: https://patch.msgid.link/20260319160110.109610-2-tzimmermann@suse.de
drivers/gpu/drm/drm_mipi_dbi.c
drivers/gpu/drm/sitronix/st7586.c
drivers/gpu/drm/sitronix/st7735r.c
drivers/gpu/drm/tiny/hx8357d.c
drivers/gpu/drm/tiny/ili9163.c
drivers/gpu/drm/tiny/ili9225.c
drivers/gpu/drm/tiny/ili9341.c
drivers/gpu/drm/tiny/ili9486.c
drivers/gpu/drm/tiny/mi0283qt.c
drivers/gpu/drm/tiny/panel-mipi-dbi.c
include/drm/drm_mipi_dbi.h

index 00482227a9cd92920a651c74997f59b6f6577a04..bb6cebc583be702bb51097a0c65f7eba6bff4efe 100644 (file)
@@ -368,44 +368,6 @@ void mipi_dbi_pipe_update(struct drm_simple_display_pipe *pipe,
 }
 EXPORT_SYMBOL(mipi_dbi_pipe_update);
 
-/**
- * mipi_dbi_enable_flush - MIPI DBI enable helper
- * @dbidev: MIPI DBI device structure
- * @crtc_state: CRTC state
- * @plane_state: Plane state
- *
- * Flushes the whole framebuffer and enables the backlight. Drivers can use this
- * in their &drm_simple_display_pipe_funcs->enable callback.
- *
- * Note: Drivers which don't use mipi_dbi_pipe_update() because they have custom
- * framebuffer flushing, can't use this function since they both use the same
- * flushing code.
- */
-void mipi_dbi_enable_flush(struct mipi_dbi_dev *dbidev,
-                          struct drm_crtc_state *crtc_state,
-                          struct drm_plane_state *plane_state)
-{
-       struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
-       struct drm_framebuffer *fb = plane_state->fb;
-       struct drm_rect rect = {
-               .x1 = 0,
-               .x2 = fb->width,
-               .y1 = 0,
-               .y2 = fb->height,
-       };
-       int idx;
-
-       if (!drm_dev_enter(&dbidev->drm, &idx))
-               return;
-
-       mipi_dbi_fb_dirty(&shadow_plane_state->data[0], fb, &rect,
-                         &shadow_plane_state->fmtcnv_state);
-       backlight_enable(dbidev->backlight);
-
-       drm_dev_exit(idx);
-}
-EXPORT_SYMBOL(mipi_dbi_enable_flush);
-
 static void mipi_dbi_blank(struct mipi_dbi_dev *dbidev)
 {
        struct drm_device *drm = &dbidev->drm;
@@ -577,6 +539,10 @@ static int mipi_dbi_rotate_mode(struct drm_display_mode *mode,
        }
 }
 
+static const struct drm_mode_config_helper_funcs mipi_dbi_mode_config_helper_funcs = {
+       .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
+};
+
 static const struct drm_mode_config_funcs mipi_dbi_mode_config_funcs = {
        .fb_create = drm_gem_fb_create_with_dirty,
        .atomic_check = drm_atomic_helper_check,
@@ -660,6 +626,8 @@ int mipi_dbi_dev_init_with_formats(struct mipi_dbi_dev *dbidev,
        drm->mode_config.max_width = dbidev->mode.hdisplay;
        drm->mode_config.min_height = dbidev->mode.vdisplay;
        drm->mode_config.max_height = dbidev->mode.vdisplay;
+       drm->mode_config.helper_private = &mipi_dbi_mode_config_helper_funcs;
+
        dbidev->rotation = rotation;
        dbidev->pixel_format = formats[0];
        if (formats[0] == DRM_FORMAT_RGB888)
index b57ebf37a664c92652141715a7387273b7df34b2..0fce12a09be064c607eba8d2aeba2216ca7008b0 100644 (file)
@@ -174,15 +174,7 @@ static void st7586_pipe_enable(struct drm_simple_display_pipe *pipe,
                               struct drm_plane_state *plane_state)
 {
        struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev);
-       struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
-       struct drm_framebuffer *fb = plane_state->fb;
        struct mipi_dbi *dbi = &dbidev->dbi;
-       struct drm_rect rect = {
-               .x1 = 0,
-               .x2 = fb->width,
-               .y1 = 0,
-               .y2 = fb->height,
-       };
        int idx, ret;
        u8 addr_mode;
 
@@ -242,9 +234,6 @@ static void st7586_pipe_enable(struct drm_simple_display_pipe *pipe,
 
        msleep(100);
 
-       st7586_fb_dirty(&shadow_plane_state->data[0], fb, &rect,
-                       &shadow_plane_state->fmtcnv_state);
-
        mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON);
 out_exit:
        drm_dev_exit(idx);
index c1f8228495f6e16047f4f19b330f59b7d5f07d27..1a34c7ba460bc52da8ebf308617e32ef4c530e16 100644 (file)
@@ -129,7 +129,7 @@ static void st7735r_pipe_enable(struct drm_simple_display_pipe *pipe,
 
        msleep(20);
 
-       mipi_dbi_enable_flush(dbidev, crtc_state, plane_state);
+       backlight_enable(dbidev->backlight);
 out_exit:
        drm_dev_exit(idx);
 }
index 9f26aaca0bfa5ffa5d20fbc1011a24f910eceb90..5115be8854bba85760265fde6ff17f96feddbb96 100644 (file)
@@ -177,7 +177,8 @@ out_enable:
                break;
        }
        mipi_dbi_command(dbi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
-       mipi_dbi_enable_flush(dbidev, crtc_state, plane_state);
+
+       backlight_enable(dbidev->backlight);
 out_exit:
        drm_dev_exit(idx);
 }
index 7c154c0083441ed8ee183d311a0998665cb7680c..c616f56af5b584e231c0dc6384f12f11eb065035 100644 (file)
@@ -96,7 +96,8 @@ out_enable:
        }
        addr_mode |= ILI9163_MADCTL_BGR;
        mipi_dbi_command(dbi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
-       mipi_dbi_enable_flush(dbidev, crtc_state, plane_state);
+
+       backlight_enable(dbidev->backlight);
 out_exit:
        drm_dev_exit(idx);
 }
index d32538b1eb0949d769d24df3f227aac07399fb20..3eaf6b3a055ae44113b013153416551f1fefcefa 100644 (file)
@@ -184,16 +184,8 @@ static void ili9225_pipe_enable(struct drm_simple_display_pipe *pipe,
                                struct drm_plane_state *plane_state)
 {
        struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev);
-       struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
-       struct drm_framebuffer *fb = plane_state->fb;
        struct device *dev = pipe->crtc.dev->dev;
        struct mipi_dbi *dbi = &dbidev->dbi;
-       struct drm_rect rect = {
-               .x1 = 0,
-               .x2 = fb->width,
-               .y1 = 0,
-               .y2 = fb->height,
-       };
        int ret, idx;
        u8 am_id;
 
@@ -284,9 +276,6 @@ static void ili9225_pipe_enable(struct drm_simple_display_pipe *pipe,
 
        ili9225_command(dbi, ILI9225_DISPLAY_CONTROL_1, 0x1017);
 
-       ili9225_fb_dirty(&shadow_plane_state->data[0], fb, &rect,
-                        &shadow_plane_state->fmtcnv_state);
-
 out_exit:
        drm_dev_exit(idx);
 }
index 2ab750cba505f7dc85b8d8c13b8130f62f223de0..972811564d6a04d377640a3ac3012f0464efbebe 100644 (file)
@@ -133,7 +133,8 @@ out_enable:
        }
        addr_mode |= ILI9341_MADCTL_BGR;
        mipi_dbi_command(dbi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
-       mipi_dbi_enable_flush(dbidev, crtc_state, plane_state);
+
+       backlight_enable(dbidev->backlight);
 out_exit:
        drm_dev_exit(idx);
 }
index 1e411a0f456726cadf63c48038e1fd9c9b7bbaf9..52b14f2cb0e18a98fd99d8c85961744f5d545899 100644 (file)
@@ -155,7 +155,8 @@ static void waveshare_enable(struct drm_simple_display_pipe *pipe,
        }
        addr_mode |= ILI9486_MADCTL_BGR;
        mipi_dbi_command(dbi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
-       mipi_dbi_enable_flush(dbidev, crtc_state, plane_state);
+
+       backlight_enable(dbidev->backlight);
  out_exit:
        drm_dev_exit(idx);
 }
index a063eff77624f4b105c1cff1db39e7362fe740f8..f121e1a8a30376768ca6703af686b7a5226dfa36 100644 (file)
@@ -137,7 +137,8 @@ out_enable:
        }
        addr_mode |= ILI9341_MADCTL_BGR;
        mipi_dbi_command(dbi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
-       mipi_dbi_enable_flush(dbidev, crtc_state, plane_state);
+
+       backlight_enable(dbidev->backlight);
 out_exit:
        drm_dev_exit(idx);
 }
index 82dfa169f762530767a088bed1c452b182fd3014..4907945ab5079e64f38b8ef01dc01c1ab5b950c9 100644 (file)
@@ -252,7 +252,7 @@ static void panel_mipi_dbi_enable(struct drm_simple_display_pipe *pipe,
        if (!ret)
                panel_mipi_dbi_commands_execute(dbi, dbidev->driver_private);
 
-       mipi_dbi_enable_flush(dbidev, crtc_state, plane_state);
+       backlight_enable(dbidev->backlight);
 out_exit:
        drm_dev_exit(idx);
 }
index f45f9612c0bc49b3ae50b3f8f891d1913103a116..637be84d3d5ae1ed529242d82c1a4e131bed87eb 100644 (file)
@@ -176,9 +176,6 @@ enum drm_mode_status mipi_dbi_pipe_mode_valid(struct drm_simple_display_pipe *pi
                                              const struct drm_display_mode *mode);
 void mipi_dbi_pipe_update(struct drm_simple_display_pipe *pipe,
                          struct drm_plane_state *old_state);
-void mipi_dbi_enable_flush(struct mipi_dbi_dev *dbidev,
-                          struct drm_crtc_state *crtc_state,
-                          struct drm_plane_state *plan_state);
 void mipi_dbi_pipe_disable(struct drm_simple_display_pipe *pipe);
 int mipi_dbi_pipe_begin_fb_access(struct drm_simple_display_pipe *pipe,
                                  struct drm_plane_state *plane_state);