[PATCH v2] drm/ssd130x: Set the address window in ssd132x_clear_screen()

Fabio Piparo posted 1 patch 1 day, 14 hours ago
drivers/gpu/drm/solomon/ssd130x.c | 30 ++++++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)
[PATCH v2] drm/ssd130x: Set the address window in ssd132x_clear_screen()
Posted by Fabio Piparo 1 day, 14 hours ago
ssd132x_clear_screen() writes a full screen of data without setting
the column and row ranges first, unlike ssd130x_clear_screen(). The
clear is not reachable today: the plane disable returns before it,
and the encoder is powered down by then.

Factor the range commands into ssd132x_set_col_range() and
ssd132x_set_row_range() and use them from ssd132x_update_rect() and
ssd132x_clear_screen().

Assisted-by: LLM
Signed-off-by: Fabio Piparo <holofermes@gmail.com>
---
Changes since v1:
- Drop the Fixes tag and the stable Cc: the path is unreachable, so
  this is a cleanup (per Amit Barzilai, Javier Martinez Canillas).
- Factor the range commands into ssd132x_set_col_range() and
  ssd132x_set_row_range(), used by update_rect and clear_screen
  (per Amit Barzilai, naming per Javier Martinez Canillas).

The helpers do not keep the programmed range the way the ssd130x
ones do. That skip would change the commands sent on every update
on the SSD1325 and SSD1327, which I cannot test, so this v2 keeps
the wire traffic identical. Easy to add as a follow-up if wanted.

Compile-tested only; the clear path cannot run on hardware today.

v1: https://lore.kernel.org/dri-devel/20260817152500.703770-1-holofermes@gmail.com/

 drivers/gpu/drm/solomon/ssd130x.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c
index 324467ae930..8cbf1875448 100644
--- a/drivers/gpu/drm/solomon/ssd130x.c
+++ b/drivers/gpu/drm/solomon/ssd130x.c
@@ -415,6 +415,20 @@ static int ssd130x_set_page_range(struct ssd130x_device *ssd130x,
 	return 0;
 }
 
+static int ssd132x_set_col_range(struct ssd130x_device *ssd130x,
+				 u8 col_start, u8 cols)
+{
+	return ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_COL_RANGE,
+				 col_start, col_start + cols - 1);
+}
+
+static int ssd132x_set_row_range(struct ssd130x_device *ssd130x,
+				 u8 row_start, u8 rows)
+{
+	return ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_ROW_RANGE,
+				 row_start, row_start + rows - 1);
+}
+
 /* Set page and column start address for page addressing mode */
 static int ssd130x_set_page_pos(struct ssd130x_device *ssd130x,
 				u8 page_start, u8 col_start)
@@ -896,13 +910,12 @@ static int ssd132x_update_rect(struct ssd130x_device *ssd130x,
 	 * the second byte are SEG2 (D1[3:0]) and SEG3 (D1[7:4]) and so on.
 	 */
 
-	/* Set column start and end */
-	ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_COL_RANGE, col, col + columns - 1);
+	/* Set address range for horizontal addressing mode */
+	ret = ssd132x_set_col_range(ssd130x, col, columns);
 	if (ret < 0)
 		return ret;
 
-	/* Set row start and end */
-	ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_ROW_RANGE, row, row + rows - 1);
+	ret = ssd132x_set_row_range(ssd130x, row, rows);
 	if (ret < 0)
 		return ret;
 
@@ -1052,9 +1065,18 @@ static void ssd132x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array)
 {
 	unsigned int columns = DIV_ROUND_UP(ssd130x->width, SSD132X_SEGMENT_WIDTH);
 	unsigned int height = ssd130x->height;
+	int ret;
 
 	memset(data_array, 0, columns * height);
 
+	ret = ssd132x_set_col_range(ssd130x, 0, columns);
+	if (ret < 0)
+		return;
+
+	ret = ssd132x_set_row_range(ssd130x, 0, height);
+	if (ret < 0)
+		return;
+
 	/* Write out update in one go since horizontal addressing mode is used */
 	ssd130x_write_data(ssd130x, data_array, columns * height);
 }
-- 
2.43.0