]> Git Repo - linux.git/commitdiff
drm/ssd130x: Fix screen clearing
authorGeert Uytterhoeven <[email protected]>
Thu, 24 Aug 2023 15:08:40 +0000 (17:08 +0200)
committerJavier Martinez Canillas <[email protected]>
Sun, 10 Sep 2023 07:05:19 +0000 (09:05 +0200)
Due to the reuse of buffers, ssd130x_clear_screen() no longers clears
the screen, but merely redraws the last image that is residing in the
intermediate buffer.

As there is no point in clearing the intermediate buffer and transposing
an all-black image, fix this by just clearing the HW format buffer, and
writing it to the panel.

Fixes: 49d7d581ceaf4cf8 ("drm/ssd130x: Don't allocate buffers on each plane update")
Signed-off-by: Geert Uytterhoeven <[email protected]>
Reviewed-by: Javier Martinez Canillas <[email protected]>
Tested-by: Javier Martinez Canillas <[email protected]>
Signed-off-by: Javier Martinez Canillas <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/c19cd5a57205597bb38a446c3871092993498f01.1692888745.git.geert@linux-m68k.org
drivers/gpu/drm/solomon/ssd130x.c

index c8860718ffb5e12b302f905a1a09766813e1cb64..3b4dde09538a805fd092b63f21389c2b915c12a5 100644 (file)
@@ -553,14 +553,45 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x,
 static void ssd130x_clear_screen(struct ssd130x_device *ssd130x,
                                 struct ssd130x_plane_state *ssd130x_state)
 {
-       struct drm_rect fullscreen = {
-               .x1 = 0,
-               .x2 = ssd130x->width,
-               .y1 = 0,
-               .y2 = ssd130x->height,
-       };
-
-       ssd130x_update_rect(ssd130x, ssd130x_state, &fullscreen);
+       unsigned int page_height = ssd130x->device_info->page_height;
+       unsigned int pages = DIV_ROUND_UP(ssd130x->height, page_height);
+       u8 *data_array = ssd130x_state->data_array;
+       unsigned int width = ssd130x->width;
+       int ret, i;
+
+       if (!ssd130x->page_address_mode) {
+               memset(data_array, 0, width * pages);
+
+               /* Set address range for horizontal addressing mode */
+               ret = ssd130x_set_col_range(ssd130x, ssd130x->col_offset, width);
+               if (ret < 0)
+                       return;
+
+               ret = ssd130x_set_page_range(ssd130x, ssd130x->page_offset, pages);
+               if (ret < 0)
+                       return;
+
+               /* Write out update in one go if we aren't using page addressing mode */
+               ssd130x_write_data(ssd130x, data_array, width * pages);
+       } else {
+               /*
+                * In page addressing mode, the start address needs to be reset,
+                * and each page then needs to be written out separately.
+                */
+               memset(data_array, 0, width);
+
+               for (i = 0; i < pages; i++) {
+                       ret = ssd130x_set_page_pos(ssd130x,
+                                                  ssd130x->page_offset + i,
+                                                  ssd130x->col_offset);
+                       if (ret < 0)
+                               return;
+
+                       ret = ssd130x_write_data(ssd130x, data_array, width);
+                       if (ret < 0)
+                               return;
+               }
+       }
 }
 
 static int ssd130x_fb_blit_rect(struct drm_plane_state *state,
This page took 0.059396 seconds and 4 git commands to generate.