Add support for Sitronix ST7571 LCD controller
Marcus Folkesson
maintainerv3 cover Add support for Sitronix ST7571 LCD controller
This series add support for the ST7571 LCD Controller.
It is a 4 gray scale dot matrix LCD controller that supports several interfaces such as SPI, I2C and a 8bit parallell port.
This driver only supports the I2C interface, but all common parts could easily be put into a common file to be used with other interfaces. I only have I2C to test with.
The device is a little defiant, it tends to NAK some commands, but all commands takes effect, hence the I2C_M_IGNORE_NAK flag.
---
Changes in v3:
- (dt-binding) Use 'Controller' rather than 'Panel' in texts
- (dt-binding) Constrain the reg property
- (dt-binding) Remove panel-timing description
- (dt-binding) Change description
- Mostly cosmetic changes in the driver code
- Don't call drm_atomic_helper_shutdown() in remove()
- Link to v2: https://lore.kernel.org/r/[email protected]
Changes in v2:
- Reworked pretty much the whole driver to not use obsolete code.
- Use panel and timing bindings to specify resolution and panel size
- Link to v1: https://lore.kernel.org/r/[email protected]
---
Marcus Folkesson (3):
dt-bindings: display: Add Sitronix ST7571 LCD Controller drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
MAINTAINERS: add entry for Sitronix ST7571 LCD Controller
.../bindings/display/sitronix,st7571.yaml | 70 ++ MAINTAINERS | 6 + drivers/gpu/drm/tiny/Kconfig | 11 + drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/tiny/st7571-i2c.c | 721 +++++++++++++++++++++ 5 files changed, 809 insertions(+)
---
base-commit: 1e26c5e28ca5821a824e90dd359556f5e9e7b89f
change-id: 20250401-st7571-9382b9cfc03f
Best regards,
Signature · 1 line
Marcus Folkesson <[email protected]>
Marcus Folkesson
maintainerPATCH v3 1/3 dt-bindings: display: Add Sitronix ST7571 LCD Controller
Sitronix ST7571 is a 4bit gray scale dot matrix LCD controller.
--- .../bindings/display/sitronix,st7571.yaml | 70 ++++++++++++++++++++++ 1 file changed, 70 insertions(+)
Documentation/devicetree/bindings/display/sitronix,st7571.yaml new file +70 -0
@@ -0,0 +1,70 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/sitronix,st7571.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sitronix ST7571 Display Controller + +maintainers: + - Marcus Folkesson <[email protected]> + +description: + Sitronix ST7571 is a driver and controller for up to 4-level gray + scale dot matrix LCD panels. + The controller is designed for use with LCD panels that have + a resolution of up to 128x128 pixels. + +allOf: + - $ref: panel/panel-common.yaml# + +properties: + compatible: + const: sitronix,st7571 + + reg: + maxItems: 1 + + reset-gpios: true + width-mm: true + height-mm: true + panel-timing: true + +required: + - compatible + - reg + - reset-gpios + - width-mm + - height-mm + - panel-timing + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + display@3f { + compatible = "sitronix,st7571"; + reg = <0x3f>; + reset-gpios = <&gpio0 3 GPIO_ACTIVE_LOW>; + width-mm = <37>; + height-mm = <27>; + + panel-timing { + hactive = <128>; + vactive = <96>; + hback-porch = <0>; + vback-porch = <0>; + clock-frequency = <0>; + hfront-porch = <0>; + hsync-len = <0>; + vfront-porch = <0>; + vsync-len = <0>; + }; + }; + };
Signature · 1 line
2.49.0
Re: [PATCH v3 1/3] dt-bindings: display: Add Sitronix ST7571 LCD Controller
Quoted 3 lines · Marcus Folkesson
Sitronix ST7571 is a 4bit gray scale dot matrix LCD controller.
Signed-off-by Marcus Folkesson <[email protected]>
Marcus Folkesson
maintainerPATCH v3 2/3 drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
In reply to Marcus FolkessonSitronix ST7571 is a 4bit gray scale dot matrix LCD controller. The controller has a SPI, I2C and 8bit parallel interface, this driver is for the I2C interface only.
--- drivers/gpu/drm/tiny/Kconfig | 11 + drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/tiny/st7571-i2c.c | 721 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 733 insertions(+)
drivers/gpu/drm/tiny/Kconfig +11 -0
@@ -232,6 +232,17 @@ config TINYDRM_ST7586 If M is selected the module will be called st7586. +config DRM_ST7571_I2C + tristate "DRM support for Sitronix ST7571 display panels (I2C)" + depends on DRM && I2C + select DRM_GEM_SHMEM_HELPER + select DRM_KMS_HELPER + select REGMAP_I2C + help + DRM driver for Sitronix ST7571 panels controlled over I2C. + + if M is selected the module will be called st7571-i2c. + config TINYDRM_ST7735R tristate "DRM support for Sitronix ST7715R/ST7735R display panels" depends on DRM && SPI
drivers/gpu/drm/tiny/Makefile +1 -0
@@ -7,6 +7,7 @@ obj-$(CONFIG_DRM_GM12U320) += gm12u320.o obj-$(CONFIG_DRM_OFDRM) += ofdrm.o obj-$(CONFIG_DRM_PANEL_MIPI_DBI) += panel-mipi-dbi.o obj-$(CONFIG_DRM_SIMPLEDRM) += simpledrm.o +obj-$(CONFIG_DRM_ST7571_I2C) += st7571-i2c.o obj-$(CONFIG_TINYDRM_HX8357D) += hx8357d.o obj-$(CONFIG_TINYDRM_ILI9163) += ili9163.o obj-$(CONFIG_TINYDRM_ILI9225) += ili9225.o
drivers/gpu/drm/tiny/st7571-i2c.c new file +721 -0
721 lines not on this page · raw message
Signature · 1 line
2.49.0
Re: [PATCH v3 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
Marcus Folkesson <[email protected]> writes:
Hello Marcus,
Quoted 4 lines
Sitronix ST7571 is a 4bit gray scale dot matrix LCD controller. The controller has a SPI, I2C and 8bit parallel interface, this driver is for the I2C interface only.
I would structure the driver differently. For example, what was done for the Solomon SSD130X display controllers, that also support these three interfaces:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/solomon
Basically, it was split in a ssd130x.c module that's agnostic of the transport interface and implements all the core logic for the driver.
And a set of different modules that have the interface specific bits:ssd130x-i2c.c and ssd130x-spi.c.
That way, adding for example SPI support to your driver would be quite trivial and won't require any refactoring. Specially since you already are using regmap, which abstracts away the I2C interface bits.
Quoted 6 lines
Reviewed-by Thomas Zimmermann <[email protected]>Signed-off-by Marcus Folkesson <[email protected]>--- drivers/gpu/drm/tiny/Kconfig | 11 + drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/tiny/st7571-i2c.c | 721 ++++++++++++++++++++++++++++++++++++++
I personally think that the tiny sub-directory is slowly becoming a dumping ground for small drivers. Instead, maybe we should create a drivers/gpu/drm/sitronix/ sub-dir and put all Sitronix drivers there?
So far we have drivers in tiny for: ST7735R, ST7586 and ST7571 with your driver. And also have a few more Sitronix drivers in the panel sub-directory (although those likely should remain there).
I have a ST7565S and plan to write a driver for it. And I know someone who is working on a ST7920 driver. That would be 5 Sitronix drivers and the reason why I think that a dedicated sub-dir would be more organized.
Maybe there's even common code among these drivers and could be reused?
Just a thought though, it's OK to keep your driver as-is and we could do refactor / move drivers around as follow-up if agreed that is desirable.
Quoted 7 lines
3 files changed, 733 insertions(+)drivers/gpu/drm/tiny/Kconfig +0
-0
drivers/gpu/drm/tiny/Kconfig config TINYDRM_ST7586 · line 238
Quoted 7 lines
drivers/gpu/drm/tiny/Kconfig +4
-0@@ -232,6 +232,17 @@ config TINYDRM_ST7586 If M is selected the module will be called st7586. +config DRM_ST7571_I2C + tristate "DRM support for Sitronix ST7571 display panels (I2C)" + depends on DRM && I2C + select DRM_GEM_SHMEM_HELPER
DRM_GEM_SHMEM_HELPER depends on MMU and your driver is selecting it, so it should also depend on MMU, i.e: depends on DRM && MMU && I2C.
drivers/gpu/drm/tiny/Kconfig config TINYDRM_ST7586 · line 240
Quoted 2 lines
drivers/gpu/drm/tiny/Kconfig +2
-0+#define drm_to_st7571(_dev) container_of(_dev, struct st7571_device, dev) +
I usually prefer these to be static inline functions instead of a macro. That way you get type checking and the end result should be basically the same.
Quoted 4 lines
drivers/gpu/drm/tiny/Kconfig +4
-0+struct st7571_device { + struct drm_device dev; + + struct drm_plane primary_plane;
drivers/gpu/drm/tiny/Kconfig config TINYDRM_ST7586
Quoted 10 lines
drivers/gpu/drm/tiny/Kconfig +10
-0+ struct drm_crtc crtc; + struct drm_encoder encoder; + struct drm_connector connector; + + struct drm_display_mode mode; + + struct i2c_client *client; + struct regmap *regmap; + bool ignore_nak; +
I know you mentioned that the chip sometimes nacks some I2C messages but maybe we want to better understand why that is the case before adding a flag like this?
In particular, I see in the "6.4 MICROPROCESSOR INTERFACE" section of the datasheet the following note:
"By connecting SDA_OUT to SDA_IN externally, the SDA line becomes fully I2C interface compatible. Separating acknowledge-output from serial data input is advantageous for chip-on-glass (COG) applications. In COG applications, the ITO resistance and the pull-up resistor will form a voltage divider, which affects acknowledge-signal level. Larger ITO resistance will raise the acknowledged-signal level and system cannot recognize this level as a valid logic “0” level. By separating SDA_IN from SDA_OUT, the IC can be used in a mode that ignores the acknowledge-bit. For applications which check acknowledge-bit, it is necessary to minimize the ITO resistance of the SDA_OUT trace to guarantee a valid low level."
...
drivers/gpu/drm/tiny/Kconfig
Quoted 11 lines
drivers/gpu/drm/tiny/Kconfig +11
-0+static int st7571_set_pixel_format(struct st7571_device *st7571, + u32 pixel_format) +{ + switch (pixel_format) { + case DRM_FORMAT_C1: + return st7571_set_color_mode(st7571, ST7571_COLOR_MODE_BLACKWHITE); + case DRM_FORMAT_C2: + return st7571_set_color_mode(st7571, ST7571_COLOR_MODE_GRAY); + default: + return -EINVAL; + }
These should be DRM_FORMAT_R1 and DRM_FORMAT_R2 and not C{1,2}. The former is for displays have a single color (i.e: grey) while the latter is when a pixel can have different color, whose values are defined by a CLUT table.
...
drivers/gpu/drm/tiny/Kconfig
Quoted 6 lines
drivers/gpu/drm/tiny/Kconfig +6
-0+ +static const uint32_t st7571_primary_plane_formats[] = { + DRM_FORMAT_C1, + DRM_FORMAT_C2, +}; +
I would add a DRM_FORMAT_XRGB8888 format. This will allow your display to be compatible with any user-space. Your st7571_fb_blit_rect() can then do a pixel format conversion from XRGB8888 to the native pixel format.
...
Quoted 11 lines
drivers/gpu/drm/tiny/Kconfig +11
-0+static void st7571_primary_plane_helper_atomic_update(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane); + struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); + struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); + struct drm_framebuffer *fb = plane_state->fb; + struct drm_atomic_helper_damage_iter iter; + struct drm_device *dev = plane->dev; + struct drm_rect damage; + struct st7571_device *st7571 = drm_to_st7571(plane->dev);
drivers/gpu/drm/tiny/Kconfig
Quoted 10 lines
drivers/gpu/drm/tiny/Kconfig +10
-0+ int ret, idx; + + if (!fb) + return; /* no framebuffer; plane is disabled */ + + ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE); + if (ret) + return; + + if (!drm_dev_enter(dev, &idx))
Should do a drm_gem_fb_end_cpu_access() here before returning.
drivers/gpu/drm/tiny/Kconfig
Quoted 5 lines
drivers/gpu/drm/tiny/Kconfig +5
-0+ return; + + ret = st7571_set_pixel_format(st7571, fb->format->format); + if (ret) { + dev_err(dev->dev, "Failed to set pixel format: %d\n", ret);
And here I think you need to do both drm_gem_fb_end_cpu_access() and drm_dev_exit().
Quoted 7 lines
drivers/gpu/drm/tiny/Kconfig +7
-0+ return; + } + + drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state); + drm_atomic_for_each_plane_damage(&iter, &damage) { + st7571_fb_blit_rect(fb, &shadow_plane_state->data[0], &damage); + }
drivers/gpu/drm/tiny/Kconfig
Quoted 10 lines
drivers/gpu/drm/tiny/Kconfig +10
-0+ + drm_dev_exit(idx); + drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); +} + +static const struct drm_plane_helper_funcs st7571_primary_plane_helper_funcs = { + DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, + .atomic_check = st7571_primary_plane_helper_atomic_check, + .atomic_update = st7571_primary_plane_helper_atomic_update, +};
Maybe you want an .atomic_disable callback that clears your screen ?
drivers/gpu/drm/tiny/Kconfig
Quoted 7 lines
drivers/gpu/drm/tiny/Kconfig +7
-0+ +/* + * CRTC + */ + +static const struct drm_crtc_helper_funcs st7571_crtc_helper_funcs = { + .atomic_check = drm_crtc_helper_atomic_check,
I think you could have an .mode_valid callback that just checks the fixed mode.
drivers/gpu/drm/tiny/Kconfig
Quoted 7 lines
drivers/gpu/drm/tiny/Kconfig +7
-0+/* + * Encoder + */ + +static const struct drm_encoder_funcs st7571_encoder_funcs = { + .destroy = drm_encoder_cleanup, +};
I recommend to have an encoder .atomic_{en,dis}able callbacks to init and turn off your display respectively. That way, the driver can call st7571_lcd_init() only when the display is going to be used instead of at probe time.
...
drivers/gpu/drm/tiny/Kconfig
Quoted 7 lines
drivers/gpu/drm/tiny/Kconfig +7
-0+static enum drm_mode_status st7571_mode_config_mode_valid(struct drm_device *dev, + const struct drm_display_mode *mode) +{ + struct st7571_device *st7571 = drm_to_st7571(dev); + + return drm_crtc_helper_mode_valid_fixed(&st7571->crtc, mode, &st7571->mode); +}
The fact that you are calling a drm_crtc_helper here is an indication that probably this should be done in a struct drm_crtc_helper_funcs .mode_valid callback instead, as mentioned above.
drivers/gpu/drm/tiny/Kconfig
Quoted 4 lines
drivers/gpu/drm/tiny/Kconfig +4
-0+ +static const struct drm_mode_config_funcs st7571_mode_config_funcs = { + .fb_create = drm_gem_fb_create_with_dirty, + .mode_valid = st7571_mode_config_mode_valid,
And that way you could just drop this handler.
Quoted 4 lines
drivers/gpu/drm/tiny/Kconfig +4
-0+ .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, +}; +
...
Quoted 24 lines
drivers/gpu/drm/tiny/Kconfig +24
-0+static int st7571_probe(struct i2c_client *client) +{ + struct st7571_device *st7571; + struct drm_device *dev; + int ret; + + st7571 = devm_drm_dev_alloc(&client->dev, &st7571_driver, + struct st7571_device, dev); + if (IS_ERR(st7571)) + return PTR_ERR(st7571); + + dev = &st7571->dev; + st7571->client = client; + i2c_set_clientdata(client, st7571); + + ret = st7571_parse_dt(st7571); + if (ret) + return ret; + + st7571->mode = st7571_mode(st7571); + + /* + * The chip nacks some messages but still works as expected. + * If the adapter does not support protocol mangling do
drivers/gpu/drm/tiny/Kconfig
Quoted 10 lines
drivers/gpu/drm/tiny/Kconfig +10
-0+ * not set the I2C_M_IGNORE_NAK flag at the expense * of possible + * cruft in the logs. + */ + if (i2c_check_functionality(client->adapter, I2C_FUNC_PROTOCOL_MANGLING)) + st7571->ignore_nak = true; + + st7571->regmap = devm_regmap_init(&client->dev, &st7571_regmap_bus, + client, &st7571_regmap_config); + if (IS_ERR(st7571->regmap)) { + dev_err(&client->dev, "Failed to initialize regmap\n");
If you use dev_err_probe(), you can give some indication to users about what failed. It prints messages in the /sys/kernel/debug/devices_deferred debugfs entry.
drivers/gpu/drm/tiny/Kconfig
Quoted 6 lines
drivers/gpu/drm/tiny/Kconfig +6
-0+ +static void st7571_remove(struct i2c_client *client) +{ + struct st7571_device *st7571 = i2c_get_clientdata(client); + + drm_dev_unplug(&st7571->dev);
I think you are missing a drm_atomic_helper_shutdown() here.
And also a struct i2c_driver .shutdown callback to call to drm_atomic_helper_shutdown() as well.
Signature · 5 lines
Best regards, Javier Martinez Canillas Core Platforms Red Hat
Thomas Zimmermann
maintainerRe: [PATCH v3 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
Hi,
lots of good points in the review.
Am 08.04.25 um 12:44 schrieb Javier Martinez Canillas:
[...]
Quoted 14 lines
Quoted 6 lines
Reviewed-by Thomas Zimmermann <[email protected]>Signed-off-by Marcus Folkesson <[email protected]>--- drivers/gpu/drm/tiny/Kconfig | 11 + drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/tiny/st7571-i2c.c | 721 ++++++++++++++++++++++++++++++++++++++I personally think that the tiny sub-directory is slowly becoming a dumping ground for small drivers. Instead, maybe we should create a
drivers/gpu/drm/sitronix/sub-dir and put all Sitronix drivers there?So far we have drivers in tiny for: ST7735R, ST7586 and ST7571 with your driver. And also have a few more Sitronix drivers in the panel sub-directory (although those likely should remain there).
Quoted 8 lines
I have a ST7565S and plan to write a driver for it. And I know someone who is working on a ST7920 driver. That would be 5 Sitronix drivers and the reason why I think that a dedicated sub-dir would be more organized.
Maybe there's even common code among these drivers and could be reused?
Just a thought though, it's OK to keep your driver as-is and we could do refactor / move drivers around as follow-up if agreed that is desirable.
That sounds like a good idea. But the other existing drivers are based on mipi-dbi helpers, while this one isn't. Not sure if that's important somehow.
Quoted 9 lines
Quoted 9 lines
3 files changed, 733 insertions(+)drivers/gpu/drm/tiny/Kconfig +0
-0@@ -232,6 +232,17 @@ config TINYDRM_ST7586
[...]
Quoted 9 lines
drivers/gpu/drm/tiny/Kconfig
Quoted 6 lines
drivers/gpu/drm/tiny/Kconfig +6
-0+ +static const uint32_t st7571_primary_plane_formats[] = { + DRM_FORMAT_C1, + DRM_FORMAT_C2, +}; +I would add a
DRM_FORMAT_XRGB8888format. This will allow your display to be compatible with any user-space. Yourst7571_fb_blit_rect()can then do a pixel format conversion from XRGB8888 to the native pixel format.
It would be a starting point for XRGB8888 on C1/R1. I always wanted to reimplement drm_fb_xrgb8888_to_mono() [1] with the generic _xfrm_ helpers. Once the generic helpers can do such low-bit formats, C2 would also work easily.
[1] https://elixir.bootlin.com/linux/v6.14-rc6/source/drivers/gpu/drm/drm_format_helper.c#L1114
Best regards
Thomas
Quoted 147 lines
...
Quoted 11 lines
drivers/gpu/drm/tiny/Kconfig +11
-0+static void st7571_primary_plane_helper_atomic_update(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane); + struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); + struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); + struct drm_framebuffer *fb = plane_state->fb; + struct drm_atomic_helper_damage_iter iter; + struct drm_device *dev = plane->dev; + struct drm_rect damage; + struct st7571_device *st7571 = drm_to_st7571(plane->dev);drivers/gpu/drm/tiny/Kconfig
Quoted 10 lines
drivers/gpu/drm/tiny/Kconfig +10
-0+ int ret, idx; + + if (!fb) + return; /* no framebuffer; plane is disabled */ + + ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE); + if (ret) + return; + + if (!drm_dev_enter(dev, &idx))Should do a
drm_gem_fb_end_cpu_access()here before returning.drivers/gpu/drm/tiny/Kconfig
Quoted 5 lines
drivers/gpu/drm/tiny/Kconfig +5
-0+ return; + + ret = st7571_set_pixel_format(st7571, fb->format->format); + if (ret) { + dev_err(dev->dev, "Failed to set pixel format: %d\n", ret);And here I think you need to do both
drm_gem_fb_end_cpu_access()anddrm_dev_exit().Quoted 7 lines
drivers/gpu/drm/tiny/Kconfig +7
-0+ return; + } + + drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state); + drm_atomic_for_each_plane_damage(&iter, &damage) { + st7571_fb_blit_rect(fb, &shadow_plane_state->data[0], &damage); + }drivers/gpu/drm/tiny/Kconfig
Quoted 10 lines
drivers/gpu/drm/tiny/Kconfig +10
-0+ + drm_dev_exit(idx); + drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); +} + +static const struct drm_plane_helper_funcs st7571_primary_plane_helper_funcs = { + DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, + .atomic_check = st7571_primary_plane_helper_atomic_check, + .atomic_update = st7571_primary_plane_helper_atomic_update, +};Maybe you want an .atomic_disable callback that clears your screen ?
drivers/gpu/drm/tiny/Kconfig
Quoted 7 lines
drivers/gpu/drm/tiny/Kconfig +7
-0+ +/* + * CRTC + */ + +static const struct drm_crtc_helper_funcs st7571_crtc_helper_funcs = { + .atomic_check = drm_crtc_helper_atomic_check,I think you could have an .mode_valid callback that just checks the fixed mode.
drivers/gpu/drm/tiny/Kconfig
Quoted 7 lines
drivers/gpu/drm/tiny/Kconfig +7
-0+/* + * Encoder + */ + +static const struct drm_encoder_funcs st7571_encoder_funcs = { + .destroy = drm_encoder_cleanup, +};I recommend to have an encoder .atomic_{en,dis}able callbacks to init and turn off your display respectively. That way, the driver can call
st7571_lcd_init()only when the display is going to be used instead of at probe time....
drivers/gpu/drm/tiny/Kconfig
Quoted 7 lines
drivers/gpu/drm/tiny/Kconfig +7
-0+static enum drm_mode_status st7571_mode_config_mode_valid(struct drm_device *dev, + const struct drm_display_mode *mode) +{ + struct st7571_device *st7571 = drm_to_st7571(dev); + + return drm_crtc_helper_mode_valid_fixed(&st7571->crtc, mode, &st7571->mode); +}The fact that you are calling a
drm_crtc_helperhere is an indication that probably this should be done in a structdrm_crtc_helper_funcs.mode_valid callback instead, as mentioned above.drivers/gpu/drm/tiny/Kconfig
Quoted 4 lines
drivers/gpu/drm/tiny/Kconfig +4
-0+ +static const struct drm_mode_config_funcs st7571_mode_config_funcs = { + .fb_create = drm_gem_fb_create_with_dirty, + .mode_valid = st7571_mode_config_mode_valid,And that way you could just drop this handler.
Quoted 4 lines
drivers/gpu/drm/tiny/Kconfig +4
-0+ .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, +}; +...
Quoted 24 lines
drivers/gpu/drm/tiny/Kconfig +24
-0+static int st7571_probe(struct i2c_client *client) +{ + struct st7571_device *st7571; + struct drm_device *dev; + int ret; + + st7571 = devm_drm_dev_alloc(&client->dev, &st7571_driver, + struct st7571_device, dev); + if (IS_ERR(st7571)) + return PTR_ERR(st7571); + + dev = &st7571->dev; + st7571->client = client; + i2c_set_clientdata(client, st7571); + + ret = st7571_parse_dt(st7571); + if (ret) + return ret; + + st7571->mode = st7571_mode(st7571); + + /* + * The chip nacks some messages but still works as expected. + * If the adapter does not support protocol mangling dodrivers/gpu/drm/tiny/Kconfig
Quoted 10 lines
drivers/gpu/drm/tiny/Kconfig +10
-0+ * not set the I2C_M_IGNORE_NAK flag at the expense * of possible + * cruft in the logs. + */ + if (i2c_check_functionality(client->adapter, I2C_FUNC_PROTOCOL_MANGLING)) + st7571->ignore_nak = true; + + st7571->regmap = devm_regmap_init(&client->dev, &st7571_regmap_bus, + client, &st7571_regmap_config); + if (IS_ERR(st7571->regmap)) { + dev_err(&client->dev, "Failed to initialize regmap\n");If you use
dev_err_probe(), you can give some indication to users about what failed. It prints messages in the/sys/kernel/debug/devices_deferreddebugfs entry.drivers/gpu/drm/tiny/Kconfig
Quoted 6 lines
drivers/gpu/drm/tiny/Kconfig +6
-0+ +static void st7571_remove(struct i2c_client *client) +{ + struct st7571_device *st7571 = i2c_get_clientdata(client); + + drm_dev_unplug(&st7571->dev);I think you are missing a
drm_atomic_helper_shutdown()here.And also a struct
i2c_driver.shutdown callback to call todrm_atomic_helper_shutdown()as well.
Signature · 7 lines
-- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH v3 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
Quoted 24 lines · Thomas Zimmermann
Hi,
lots of good points in the review.
Am 08.04.25 um 12:44 schrieb Javier Martinez Canillas:
[...]Quoted 18 lines
Quoted 6 lines
Reviewed-by Thomas Zimmermann <[email protected]>Signed-off-by Marcus Folkesson <[email protected]>--- drivers/gpu/drm/tiny/Kconfig | 11 + drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/tiny/st7571-i2c.c | 721 ++++++++++++++++++++++++++++++++++++++I personally think that the tiny sub-directory is slowly becoming a dumping ground for small drivers. Instead, maybe we should create a
drivers/gpu/drm/sitronix/sub-dir and put all Sitronix drivers there?So far we have drivers in tiny for: ST7735R, ST7586 and ST7571 with your driver. And also have a few more Sitronix drivers in the panel sub-directory (although those likely should remain there).
I have a ST7565S and plan to write a driver for it. And I know someone who is working on a ST7920 driver. That would be 5 Sitronix drivers and the reason why I think that a dedicated sub-dir would be more organized.
Quoted 9 lines
Quoted 4 lines
Maybe there's even common code among these drivers and could be reused?
Just a thought though, it's OK to keep your driver as-is and we could do refactor / move drivers around as follow-up if agreed that is desirable.
That sounds like a good idea. But the other existing drivers are based on mipi-dbi helpers, while this one isn't. Not sure if that's important somehow.
Yeah, I don't know. In any case, the driver / module name is not an ABI so we can always move around the files later if needed.
Quoted 20 lines
Quoted 9 lines
Quoted 9 lines
3 files changed, 733 insertions(+)drivers/gpu/drm/tiny/Kconfig +0
-0@@ -232,6 +232,17 @@ config TINYDRM_ST7586[...]
Quoted 9 lines
drivers/gpu/drm/tiny/Kconfig
Quoted 6 lines
drivers/gpu/drm/tiny/Kconfig +6
-0+ +static const uint32_t st7571_primary_plane_formats[] = { + DRM_FORMAT_C1, + DRM_FORMAT_C2, +}; +I would add a
DRM_FORMAT_XRGB8888format. This will allow your display to be compatible with any user-space. Yourst7571_fb_blit_rect()can then do a pixel format conversion from XRGB8888 to the native pixel format.
Quoted 8 lines
It would be a starting point for XRGB8888 on C1/R1. I always wanted to reimplement
drm_fb_xrgb8888_to_mono()[1] with the generic _xfrm_ helpers. Once the generic helpers can do such low-bit formats, C2 would also work easily.[1]
https://elixir.bootlin.com/linux/v6.14-rc6/source/drivers/gpu/drm/drm_format_helper.c#L1114
Agreed. But even in its current form that helper is what I had in mind and what is used by the ssd130x driver too for XRGB8888 -> R1 conversion. There is no drm_fb_xrgb8888_to_gray2(), but that could be added as a part of this driver series.
Quoted 3 lines
Best regards
Thomas
Signature · 5 lines
Best regards, Javier Martinez Canillas Core Platforms Red Hat
Marcus Folkesson
maintainerRe: [PATCH v3 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
In reply to Javier Martinez CanillasHello Javier,
Thank you for your review and suggestions.
Quoted 18 lines · Javier Martinez Canillas
Marcus Folkesson <[email protected]> writes:
Hello Marcus,
Quoted 4 lines
Sitronix ST7571 is a 4bit gray scale dot matrix LCD controller. The controller has a SPI, I2C and 8bit parallel interface, this driver is for the I2C interface only.
I would structure the driver differently. For example, what was done for the Solomon SSD130X display controllers, that also support these three interfaces:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/solomon
Basically, it was split in a
ssd130x.cmodule that's agnostic of the transport interface and implements all the core logic for the driver.
Quoted 6 lines
And a set of different modules that have the interface specific bits:
ssd130x-i2c.candssd130x-spi.c.That way, adding for example SPI support to your driver would be quite trivial and won't require any refactoring. Specially since you already are using regmap, which abstracts away the I2C interface bits.
Yes, I had in mind to start looking into this after the initial version. The driver is writtin in this in mind, everything that is common for all interfaces is easy to move out.
Quoted 16 lines
Quoted 7 lines
Reviewed-by Thomas Zimmermann <[email protected]>Signed-off-by Marcus Folkesson <[email protected]>--- drivers/gpu/drm/tiny/Kconfig | 11 + drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/tiny/st7571-i2c.c | 721 ++++++++++++++++++++++++++++++++++++++I personally think that the tiny sub-directory is slowly becoming a dumping ground for small drivers. Instead, maybe we should create a
drivers/gpu/drm/sitronix/sub-dir and put all Sitronix drivers there?So far we have drivers in tiny for: ST7735R, ST7586 and ST7571 with your driver. And also have a few more Sitronix drivers in the panel sub-directory (although those likely should remain there).
Quoted 8 lines
I have a ST7565S and plan to write a driver for it. And I know someone who is working on a ST7920 driver. That would be 5 Sitronix drivers and the reason why I think that a dedicated sub-dir would be more organized.
Maybe there's even common code among these drivers and could be reused?
Just a thought though, it's OK to keep your driver as-is and we could do refactor / move drivers around as follow-up if agreed that is desirable.
That sounds like a good idea.
[...]
Quoted 7 lines
Review
Quoted 3 lines
(quoted diff) +2
-0+#define drm_to_st7571(_dev) container_of(_dev, struct st7571_device, dev) +I usually prefer these to be static inline functions instead of a macro. That way you get type checking and the end result should be basically the same.
I agree, I will change this to a static inline function.
Quoted 23 lines
Quoted 5 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +4
-0+struct st7571_device { +struct drm_device dev; + +struct drm_plane primary_plane;drivers/gpu/drm/tiny/st7571-i2c.c line 99
Quoted 10 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +10
-0+struct drm_crtc crtc; +struct drm_encoder encoder; +struct drm_connector connector; + +struct drm_display_mode mode; + +struct i2c_client *client; +struct regmap *regmap; +bool ignore_nak; +I know you mentioned that the chip sometimes nacks some I2C messages but maybe we want to better understand why that is the case before adding a flag like this?
In particular, I see in the "6.4 MICROPROCESSOR INTERFACE" section of the datasheet the following note:
Quoted 10 lines
"By connecting
SDA_OUTtoSDA_INexternally, the SDA line becomes fully I2C interface compatible. Separating acknowledge-output from serial data input is advantageous for chip-on-glass (COG) applications. In COG applications, the ITO resistance and the pull-up resistor will form a voltage divider, which affects acknowledge-signal level. Larger ITO resistance will raise the acknowledged-signal level and system cannot recognize this level as a valid logic “0” level. By separatingSDA_INfromSDA_OUT, the IC can be used in a mode that ignores the acknowledge-bit. For applications which check acknowledge-bit, it is necessary to minimize the ITO resistance of theSDA_OUTtrace to guarantee a valid low level."
This has completely flown under the radar, thank you for pointing it out.
I will put the text from the datasheet together with ignore_nak.
Quoted 19 lines
...
drivers/gpu/drm/tiny/st7571-i2c.c line 240
Quoted 11 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +11
-0+static int st7571_set_pixel_format (struct st7571_device *st7571, +u32 pixel_format) +{ +switch (pixel_format) { +case DRM_FORMAT_C1 : +return st7571_set_color_mode (st7571,ST7571_COLOR_MODE_BLACKWHITE ); +case DRM_FORMAT_C2 : +return st7571_set_color_mode (st7571,ST7571_COLOR_MODE_GRAY ); +default : +return -EINVAL ; + }These should be
DRM_FORMAT_R1andDRM_FORMAT_R2and not C{1,2}. The former is for displays have a single color (i.e: grey) while the latter is when a pixel can have different color, whose values are defined by a CLUT table.
I see.
Does fbdev only works with CLUT formats? I get this error when I switch to DRM_FORMAT_R{1,2}:
[drm] Initialized st7571 1.0.0 for 0-003f on minor 0
st7571 0-003f: [drm] format C1 little-endian (0x20203143) not supported
st7571 0-003f: [drm] No compatible format found
st7571 0-003f: [drm] *ERROR* fbdev: Failed to setup emulation (ret=-22)
Quoted 12 lines
...
drivers/gpu/drm/tiny/st7571-i2c.c line 258
Quoted 6 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +6
-0+ +static const uint32_t st7571_primary_plane_formats[] = { +DRM_FORMAT_C1 , +DRM_FORMAT_C2 , +}; +I would add a
DRM_FORMAT_XRGB8888format. This will allow your display to be compatible with any user-space. Yourst7571_fb_blit_rect()can then do a pixel format conversion from XRGB8888 to the native pixel format.
This were discussed in v2, but there were limitations in the helper functions that we currently have.
I will look into how this could be implemented in a generic way, but maybe that is something for a follow up patch?
[...]
Quoted 8 lines
drivers/gpu/drm/tiny/st7571-i2c.c line 322
Quoted 6 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +6
-0+ +static const struct drm_plane_helper_funcs st7571_primary_plane_helper_funcs = { +DRM_GEM_SHADOW_PLANE_HELPER_FUNCS , + .atomic_check = st7571_primary_plane_helper_atomic_check, + .atomic_update = st7571_primary_plane_helper_atomic_update, +};Maybe you want an .atomic_disable callback that clears your screen ?
Good point, yes, I will add that.
Quoted 11 lines
drivers/gpu/drm/tiny/st7571-i2c.c line 336
Quoted 9 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +7
-0+ +/* +* CRTC +*/ + +static const struct drm_crtc_helper_funcs st7571_crtc_helper_funcs = { + .atomic_check = drm_crtc_helper_atomic_check,I think you could have an .mode_valid callback that just checks the fixed mode.
Got it.
Quoted 12 lines
drivers/gpu/drm/tiny/st7571-i2c.c line 354
Quoted 8 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +7
-0+/* +* Encoder +*/ + +static const struct drm_encoder_funcs st7571_encoder_funcs = { + .destroy = drm_encoder_cleanup, +};I recommend to have an encoder .atomic_{en,dis}able callbacks to init and turn off your display respectively. That way, the driver can call
st7571_lcd_init()only when the display is going to be used instead of at probe time.
I will look into this as well.
Quoted 14 lines
...
drivers/gpu/drm/tiny/st7571-i2c.c line 374
Quoted 7 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +7
-0+static enum drm_mode_status st7571_mode_config_mode_valid (struct drm_device *dev, +const struct drm_display_mode *mode) +{ +struct st7571_device *st7571 =drm_to_st7571 (dev); + +return drm_crtc_helper_mode_valid_fixed (&st7571->crtc, mode, &st7571->mode); +}The fact that you are calling a
drm_crtc_helperhere is an indication that probably this should be done in a structdrm_crtc_helper_funcs.mode_valid callback instead, as mentioned above.
I will move it to drm_crtc_helper_funcs.
Quoted 7 lines
drivers/gpu/drm/tiny/st7571-i2c.c line 378
Quoted 5 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +4
-0+ +static const struct drm_mode_config_funcs st7571_mode_config_funcs = { + .fb_create = drm_gem_fb_create_with_dirty, + .mode_valid = st7571_mode_config_mode_valid,And that way you could just drop this handler.
Yep, thanks.
Quoted 38 lines
Quoted 5 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +4
-0+ .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, +}; +...
Quoted 30 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +30
-0+static int st7571_probe (struct i2c_client *client) +{ +struct st7571_device *st7571; +struct drm_device *dev; +int ret; + + st7571 =devm_drm_dev_alloc (&client->dev, &st7571_driver, + struct st7571_device, dev); +if (IS_ERR (st7571)) +return PTR_ERR (st7571); + + dev = &st7571->dev; + st7571->client = client; +i2c_set_clientdata (client, st7571); + + ret =st7571_parse_dt (st7571); +if (ret) +return ret; + + st7571->mode =st7571_mode (st7571); + +/* +* The chip nacks some messages but still works as expected. +* If the adapter does not support protocol mangling do +* not set the I2C_M_IGNORE_NAK flag at the expense * of possible +* cruft in the logs. +*/ +if (i2c_check_functionality (client->adapter,I2C_FUNC_PROTOCOL_MANGLING )) + st7571->ignore_nak = true; +
Quoted 8 lines
drivers/gpu/drm/tiny/st7571-i2c.c line 637
Quoted 4 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +4
-0+ st7571->regmap =devm_regmap_init (&client->dev, &st7571_regmap_bus, + client, &st7571_regmap_config); +if (IS_ERR (st7571->regmap)) { +dev_err (&client->dev,"Failed to initialize regmap\n" );If you use
dev_err_probe(), you can give some indication to users about what failed. It prints messages in the/sys/kernel/debug/devices_deferreddebugfs entry.
Got it, thanks.
Quoted 9 lines
drivers/gpu/drm/tiny/st7571-i2c.c line 691
Quoted 7 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +6
-0+ +static void st7571_remove (struct i2c_client *client) +{ +struct st7571_device *st7571 =i2c_get_clientdata (client); + +drm_dev_unplug (&st7571->dev);I think you are missing a
drm_atomic_helper_shutdown()here.
This is a change for v3. As the device has been unplugged already, it won't do anything, so I removed it.
Isn't it right to do so?
Quoted 11 lines
And also a struct
i2c_driver.shutdown callback to call todrm_atomic_helper_shutdown()as well.Signature · 5 lines
Best regards, Javier Martinez Canillas Core Platforms Red Hat
Best regards,
Marcus Folkesson
Thomas Zimmermann
maintainerRe: [PATCH v3 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
Hi
Am 08.04.25 um 15:20 schrieb Marcus Folkesson:
[...]
Quoted 16 lines
Quoted 16 lines
drivers/gpu/drm/tiny/st7571-i2c.c line 240
Quoted 12 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +11
-0+static int st7571_set_pixel_format (struct st7571_device *st7571, +u32 pixel_format) +{ +switch (pixel_format) { +case DRM_FORMAT_C1 : +return st7571_set_color_mode (st7571,ST7571_COLOR_MODE_BLACKWHITE ); +case DRM_FORMAT_C2 : +return st7571_set_color_mode (st7571,ST7571_COLOR_MODE_GRAY ); +default : +return -EINVAL ; + }These should be
DRM_FORMAT_R1andDRM_FORMAT_R2and not C{1,2}. The former is for displays have a single color (i.e: grey) while the latter is when a pixel can have different color, whose values are defined by a CLUT table.
Quoted 8 lines
I see.
Does fbdev only works with CLUT formats? I get this error when I switch to DRM_FORMAT_R{1,2}:[drm] Initialized st7571 1.0.0 for 0-003f on minor 0
st7571 0-003f: [drm] format C1 little-endian (0x20203143) not supported
st7571 0-003f: [drm] No compatible format found
st7571 0-003f: [drm] *ERROR* fbdev: Failed to setup emulation (ret=-22)
For testing purposes, you can add the _R formats to the switch case at
https://elixir.bootlin.com/linux/v6.13.7/source/drivers/gpu/drm/drm_fb_helper.c#L1246
and see how it goes.
Best regards
Thomas
Quoted 144 lines
Quoted 4 lines
...
Quoted 9 lines
drivers/gpu/drm/tiny/st7571-i2c.c line 258
Quoted 6 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +6
-0+ +static const uint32_t st7571_primary_plane_formats[] = { +DRM_FORMAT_C1 , +DRM_FORMAT_C2 , +}; +I would add a
DRM_FORMAT_XRGB8888format. This will allow your display to be compatible with any user-space. Yourst7571_fb_blit_rect()can then do a pixel format conversion from XRGB8888 to the native pixel format.This were discussed in v2, but there were limitations in the helper functions that we currently have.
I will look into how this could be implemented in a generic way, but maybe that is something for a follow up patch?
[...]
Quoted 7 lines
drivers/gpu/drm/tiny/st7571-i2c.c line 322
Quoted 6 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +6
-0+ +static const struct drm_plane_helper_funcs st7571_primary_plane_helper_funcs = { +DRM_GEM_SHADOW_PLANE_HELPER_FUNCS , + .atomic_check = st7571_primary_plane_helper_atomic_check, + .atomic_update = st7571_primary_plane_helper_atomic_update, +};Maybe you want an .atomic_disable callback that clears your screen ?
Good point, yes, I will add that.
Quoted 9 lines
drivers/gpu/drm/tiny/st7571-i2c.c line 336
Quoted 8 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +7
-0+ +/* +* CRTC +*/ + +static const struct drm_crtc_helper_funcs st7571_crtc_helper_funcs = { + .atomic_check = drm_crtc_helper_atomic_check,I think you could have an .mode_valid callback that just checks the fixed mode.
Got it.
Quoted 10 lines
drivers/gpu/drm/tiny/st7571-i2c.c line 354
Quoted 7 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +7
-0+/* +* Encoder +*/ + +static const struct drm_encoder_funcs st7571_encoder_funcs = { + .destroy = drm_encoder_cleanup, +};I recommend to have an encoder .atomic_{en,dis}able callbacks to init and turn off your display respectively. That way, the driver can call
st7571_lcd_init()only when the display is going to be used instead of at probe time.I will look into this as well.
Quoted 12 lines
...
drivers/gpu/drm/tiny/st7571-i2c.c line 374
Quoted 7 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +7
-0+static enum drm_mode_status st7571_mode_config_mode_valid (struct drm_device *dev, +const struct drm_display_mode *mode) +{ +struct st7571_device *st7571 =drm_to_st7571 (dev); + +return drm_crtc_helper_mode_valid_fixed (&st7571->crtc, mode, &st7571->mode); +}The fact that you are calling a
drm_crtc_helperhere is an indication that probably this should be done in a structdrm_crtc_helper_funcs.mode_valid callback instead, as mentioned above.I will move it to
drm_crtc_helper_funcs.Quoted 5 lines
drivers/gpu/drm/tiny/st7571-i2c.c line 378
Quoted 4 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +4
-0+ +static const struct drm_mode_config_funcs st7571_mode_config_funcs = { + .fb_create = drm_gem_fb_create_with_dirty, + .mode_valid = st7571_mode_config_mode_valid,And that way you could just drop this handler.
Yep, thanks.
Quoted 35 lines
Quoted 4 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +4
-0+ .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, +}; +...
Quoted 29 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +29
-0+static int st7571_probe (struct i2c_client *client) +{ +struct st7571_device *st7571; +struct drm_device *dev; +int ret; + + st7571 =devm_drm_dev_alloc (&client->dev, &st7571_driver, + struct st7571_device, dev); +if (IS_ERR (st7571)) +return PTR_ERR (st7571); + + dev = &st7571->dev; + st7571->client = client; +i2c_set_clientdata (client, st7571); + + ret =st7571_parse_dt (st7571); +if (ret) +return ret; + + st7571->mode =st7571_mode (st7571); + +/* +* The chip nacks some messages but still works as expected. +* If the adapter does not support protocol mangling do +* not set the I2C_M_IGNORE_NAK flag at the expense * of possible +* cruft in the logs. +*/ +if (i2c_check_functionality (client->adapter,I2C_FUNC_PROTOCOL_MANGLING )) + st7571->ignore_nak = true;Quoted 8 lines
drivers/gpu/drm/tiny/st7571-i2c.c line 637
Quoted 5 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +5
-0+ + st7571->regmap =devm_regmap_init (&client->dev, &st7571_regmap_bus, + client, &st7571_regmap_config); +if (IS_ERR (st7571->regmap)) { +dev_err (&client->dev,"Failed to initialize regmap\n" );If you use
dev_err_probe(), you can give some indication to users about what failed. It prints messages in the/sys/kernel/debug/devices_deferreddebugfs entry.Got it, thanks.
Quoted 7 lines
drivers/gpu/drm/tiny/st7571-i2c.c line 691
Quoted 6 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +6
-0+ +static void st7571_remove (struct i2c_client *client) +{ +struct st7571_device *st7571 =i2c_get_clientdata (client); + +drm_dev_unplug (&st7571->dev);I think you are missing a
drm_atomic_helper_shutdown()here.This is a change for v3. As the device has been unplugged already, it won't do anything, so I removed it.
Isn't it right to do so?
Quoted 10 lines
And also a struct
i2c_driver.shutdown callback to call todrm_atomic_helper_shutdown()as well.Signature · 5 lines
Best regards, Javier Martinez Canillas Core Platforms Red HatBest regards,
Marcus Folkesson
Signature · 7 lines
-- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Marcus Folkesson
maintainerRe: [PATCH v3 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
Hi,
Quoted 29 lines · Thomas Zimmermann
Hi
Am 08.04.25 um 15:20 schrieb Marcus Folkesson:
[...]Quoted 16 lines
Quoted 16 lines
drivers/gpu/drm/tiny/st7571-i2c.c line 240
Quoted 12 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +11
-0+static int st7571_set_pixel_format (struct st7571_device *st7571, +u32 pixel_format) +{ +switch (pixel_format) { +case DRM_FORMAT_C1 : +return st7571_set_color_mode (st7571,ST7571_COLOR_MODE_BLACKWHITE ); +case DRM_FORMAT_C2 : +return st7571_set_color_mode (st7571,ST7571_COLOR_MODE_GRAY ); +default : +return -EINVAL ; + }These should be
DRM_FORMAT_R1andDRM_FORMAT_R2and not C{1,2}. The former is for displays have a single color (i.e: grey) while the latter is when a pixel can have different color, whose values are defined by a CLUT table.Quoted 8 lines
I see.
Does fbdev only works with CLUT formats? I get this error when I switch to DRM_FORMAT_R{1,2}:[drm] Initialized st7571 1.0.0 for 0-003f on minor 0
st7571 0-003f: [drm] format C1 little-endian (0x20203143) not supported
st7571 0-003f: [drm] No compatible format found
st7571 0-003f: [drm] *ERROR* fbdev: Failed to setup emulation (ret=-22)
Quoted 5 lines
For testing purposes, you can add the _R formats to the switch case at
https://elixir.bootlin.com/linux/v6.13.7/source/drivers/gpu/drm/drm_fb_helper.c#L1246
and see how it goes.
Still no penguin (same error as above).
The problem is that drm_mode_legacy_fb_format(), which is called from drm_fbdev_shmem_driver_fbdev_probe -> drm_driver_legacy_fb_format -> drm_mode_legacy_fb_format
Sets the pixel format DRM_FORMAT_C{1,2} when bpp is 1 or 2. So I don't think it is possible to use the _R formats with fbdev. But I'm not sure?
Quoted 3 lines
Best regards
Thomas
Best regards,
Marcus Folkesson
Thomas Zimmermann
maintainerRe: [PATCH v3 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
Hi
Am 08.04.25 um 16:58 schrieb Marcus Folkesson:
Quoted 32 lines
Hi,
Quoted 29 lines · Thomas Zimmermann
Hi
Am 08.04.25 um 15:20 schrieb Marcus Folkesson:
[...]Quoted 15 lines
Quoted 6 lines
Quoted 6 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +6
-0+static int st7571_set_pixel_format (struct st7571_device *st7571, +u32 pixel_format) +{ +switch (pixel_format) { +case DRM_FORMAT_C1 : +return st7571_set_color_mode (st7571,ST7571_COLOR_MODE_BLACKWHITE );Quoted 9 lines
drivers/gpu/drm/tiny/st7571-i2c.c line 240
Quoted 5 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +5
-0+case DRM_FORMAT_C2 : +return st7571_set_color_mode (st7571,ST7571_COLOR_MODE_GRAY ); +default : +return -EINVAL ; + }These should be
DRM_FORMAT_R1andDRM_FORMAT_R2and not C{1,2}. The former is for displays have a single color (i.e: grey) while the latter is when a pixel can have different color, whose values are defined by a CLUT table.Quoted 8 lines
I see.
Does fbdev only works with CLUT formats? I get this error when I switch to DRM_FORMAT_R{1,2}:[drm] Initialized st7571 1.0.0 for 0-003f on minor 0
st7571 0-003f: [drm] format C1 little-endian (0x20203143) not supported
st7571 0-003f: [drm] No compatible format found
st7571 0-003f: [drm] *ERROR* fbdev: Failed to setup emulation (ret=-22)For testing purposes, you can add the _R formats to the switch case at
Quoted 7 lines
Quoted 3 lines
https://elixir.bootlin.com/linux/v6.13.7/source/drivers/gpu/drm/drm_fb_helper.c#L1246
and see how it goes.
Still no penguin (same error as above).
The problem is that
drm_mode_legacy_fb_format(), which is called fromdrm_fbdev_shmem_driver_fbdev_probe->drm_driver_legacy_fb_format->drm_mode_legacy_fb_format
In addition to the other change, you could change the _C formats to _R formats in that helper for testing.
Best regards
Thomas
Quoted 9 lines
Sets the pixel format DRM_FORMAT_C{1,2} when bpp is 1 or 2. So I don't think it is possible to use the _R formats with fbdev. But I'm not sure?
Quoted 2 lines
Best regards
ThomasBest regards,
Marcus Folkesson
Signature · 7 lines
-- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH v3 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
In reply to Marcus FolkessonQuoted 26 lines · Marcus Folkesson
Hello Javier,
Thank you for your review and suggestions.
Quoted 21 lines · Javier Martinez Canillas
Marcus Folkesson <[email protected]> writes:
Hello Marcus,
Quoted 4 lines
Sitronix ST7571 is a 4bit gray scale dot matrix LCD controller. The controller has a SPI, I2C and 8bit parallel interface, this driver is for the I2C interface only.
I would structure the driver differently. For example, what was done for the Solomon SSD130X display controllers, that also support these three interfaces:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/solomon
Basically, it was split in a
ssd130x.cmodule that's agnostic of the transport interface and implements all the core logic for the driver.And a set of different modules that have the interface specific bits:
ssd130x-i2c.candssd130x-spi.c.
Quoted 8 lines
Quoted 3 lines
That way, adding for example SPI support to your driver would be quite trivial and won't require any refactoring. Specially since you already are using regmap, which abstracts away the I2C interface bits.
Yes, I had in mind to start looking into this after the initial version. The driver is writtin in this in mind, everything that is common for all interfaces is easy to move out.
Yes, I noticed that and the reason why I mentioned the file layout used in the ssd130x driver. If was meant to only be an I2C driver then I think it would be a good candidate for the tiny sub-dir (that is for small drivers that can be implemented in a single file).
But as said, it's OK for me too if you start in tiny and then refactor it to be moved to a sitronix vendor sub-dir.
[...]
Quoted 17 lines
Quoted 7 lines
Quoted 7 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +7
-0+static int st7571_set_pixel_format (struct st7571_device *st7571, +u32 pixel_format) +{ +switch (pixel_format) { +case DRM_FORMAT_C1 : +return st7571_set_color_mode (st7571,ST7571_COLOR_MODE_BLACKWHITE ); +case DRM_FORMAT_C2 :Quoted 9 lines
drivers/gpu/drm/tiny/st7571-i2c.c line 240
Quoted 4 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +4
-0+return st7571_set_color_mode (st7571,ST7571_COLOR_MODE_GRAY ); +default : +return -EINVAL ; + }These should be
DRM_FORMAT_R1andDRM_FORMAT_R2and not C{1,2}. The former is for displays have a single color (i.e: grey) while the latter is when a pixel can have different color, whose values are defined by a CLUT table.
Quoted 10 lines
I see.
Does fbdev only works with CLUT formats? I get this error when I switch to DRM_FORMAT_R{1,2}:[drm] Initialized st7571 1.0.0 for 0-003f on minor 0
st7571 0-003f: [drm] format C1 little-endian (0x20203143) not supported
st7571 0-003f: [drm] No compatible format found
st7571 0-003f: [drm] *ERROR* fbdev: Failed to setup emulation (ret=-22)
That's a god question, I don't really know...
But fbdev does support XRGB8888, which may be another good reason to add it and make it the default format. Yes, it will cause an unnecessary pixel format conversion but the I2C transport is so slow anyways that compute is not the bottleneck when using these small displays.
Quoted 13 lines
Quoted 12 lines
...
drivers/gpu/drm/tiny/st7571-i2c.c line 258
Quoted 6 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +6
-0+ +static const uint32_t st7571_primary_plane_formats[] = { +DRM_FORMAT_C1 , +DRM_FORMAT_C2 , +}; +I would add a
DRM_FORMAT_XRGB8888format. This will allow your display to be compatible with any user-space. Yourst7571_fb_blit_rect()can then do a pixel format conversion from XRGB8888 to the native pixel format.
Quoted 3 lines
This were discussed in v2, but there were limitations in the helper functions that we currently have.
Indeed, will need a drm_fb_xrgb8888_to_gray2() for R2. There is already a drm_fb_xrgb8888_to_mono() as mentioned that you can use for R1.
Quoted 3 lines
I will look into how this could be implemented in a generic way, but maybe that is something for a follow up patch?
Yes, it could be a follow-up patch. It just helps to have XRGB8888 support for compatibility reasons (the fbdev issue you found is another example of this).
[...]
Quoted 9 lines
Quoted 8 lines
drivers/gpu/drm/tiny/st7571-i2c.c line 691
Quoted 6 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +6
-0+ +static void st7571_remove (struct i2c_client *client) +{ +struct st7571_device *st7571 =i2c_get_clientdata (client); + +drm_dev_unplug (&st7571->dev);I think you are missing a
drm_atomic_helper_shutdown()here.
Quoted 6 lines
This is a change for v3. As the device has been unplugged already, it won't do anything, so I removed it.
Isn't it right to do so?
It seems I was wrong on this and your implementation is correct. I talked with Thomas yesterday and he clarified it to me.
Signature · 5 lines
Best regards, Javier Martinez Canillas Core Platforms Red Hat
Marcus Folkesson
maintainerRe: [PATCH v3 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
Hello Javier,
On Wed, Apr 09, 2025 at 08:11:23AM +0200, Javier Martinez Canillas wrote:
[...]
Quoted 28 lines
Quoted 17 lines
Quoted 7 lines
Quoted 7 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +7
-0+static int st7571_set_pixel_format (struct st7571_device *st7571, +u32 pixel_format) +{ +switch (pixel_format) { +case DRM_FORMAT_C1 : +return st7571_set_color_mode (st7571,ST7571_COLOR_MODE_BLACKWHITE ); +case DRM_FORMAT_C2 :Quoted 9 lines
drivers/gpu/drm/tiny/st7571-i2c.c line 240
Quoted 4 lines
drivers/gpu/drm/tiny/st7571-i2c.c new file +4
-0+return st7571_set_color_mode (st7571,ST7571_COLOR_MODE_GRAY ); +default : +return -EINVAL ; + }These should be
DRM_FORMAT_R1andDRM_FORMAT_R2and not C{1,2}. The former is for displays have a single color (i.e: grey) while the latter is when a pixel can have different color, whose values are defined by a CLUT table.Quoted 10 lines
I see.
Does fbdev only works with CLUT formats? I get this error when I switch to DRM_FORMAT_R{1,2}:[drm] Initialized st7571 1.0.0 for 0-003f on minor 0
st7571 0-003f: [drm] format C1 little-endian (0x20203143) not supported
st7571 0-003f: [drm] No compatible format found
st7571 0-003f: [drm] *ERROR* fbdev: Failed to setup emulation (ret=-22)
Quoted 6 lines
That's a god question, I don't really know...
But fbdev does support XRGB8888, which may be another good reason to add it and make it the default format. Yes, it will cause an unnecessary pixel format conversion but the I2C transport is so slow anyways that compute is not the bottleneck when using these small displays.
Hrm, I now realised that I have another issue.
Not all LCDs that will be attached to the ST7571 controller will be grayscale.
The display I've attached to the ST7571 is a monochrome LCD for example.
Maybe the right way to do it is to only support XRGB8888 and specify if the display is monochrome or grayscale in the device tree.
Or do you have any good suggestions?
[...]
Quoted 8 lines
Signature · 6 lines
-- Best regards, Javier Martinez Canillas Core Platforms Red Hat
Best regards,
Marcus Folkesson
Re: [PATCH v3 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
Marcus Folkesson <[email protected]> writes:
Hello Marcus,
[...]
Quoted 8 lines
Quoted 7 lines
That's a god question, I don't really know...
But fbdev does support XRGB8888, which may be another good reason to add it and make it the default format. Yes, it will cause an unnecessary pixel format conversion but the I2C transport is so slow anyways that compute is not the bottleneck when using these small displays.
Quoted 5 lines
Hrm, I now realised that I have another issue.
Not all LCDs that will be attached to the ST7571 controller will be grayscale.
The display I've attached to the ST7571 is a monochrome LCD for example.
Oh, that's very interesting. This means that vendors are using a more capable IC (i.e: ST7571) for display controllers + LCD panels board designs, even where they could had used a less capable one (i.e: ST7765). That is, using an IC that supports 2-bit grayscale when they could just used one that only supported monochrome pixels.
From a quick search, I found for example this one from SinoCrystal:
https://displaysino.com/product_details/SC128128012-V01.html
Quoted 5 lines
Maybe the right way to do it is to only support XRGB8888 and specify if the display is monochrome or grayscale in the device tree.
Or do you have any good suggestions?
I don't know the proper way to handle this, but what I would do is to include the actual boards as entries in the OF device ID table instead of just the ICs.
And then for each entry you can specify what formats are supported, e.g:
static const uint32_t monochrome_formats[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_R1
};static const uint32_t grayscale_formats[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_R1
DRM_FORMAT_R2
};static const struct of_device_id st7571_of_match[] = {
/* monochrome displays */
{
.compatible = "sinocrystal,sc128128012-v01",
.data = monochrome_formats,
},
...
/* grayscale displays */
{
.compatible = "foo,bar",
.data = grayscale_formats,
},
};and then in your probe callback, you can get the correct format list for the device matched. Something like the following for example:
static int st7571_probe(struct i2c_client *client) {
const uint32_t *formats = device_get_match_data(client->dev);
...
ret = drm_universal_plane_init(..., formats, ...);
...
};Likely you will need to define more stuff to be specific for each entry, maybe you will need different primary plane update handlers too. Similar to how I had to do it the ssd130x driver to support all the Solomon OLED controller families:
https://elixir.bootlin.com/linux/v6.11/source/drivers/gpu/drm/solomon/ssd130x.c#L1439
Signature · 5 lines
Best regards, Javier Martinez Canillas Core Platforms Red Hat
Marcus Folkesson
maintainerRe: [PATCH v3 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
Hello Javier,
Quoted 76 lines · Javier Martinez Canillas
Marcus Folkesson <[email protected]> writes:
Hello Marcus,
[...]
Quoted 8 lines
Quoted 7 lines
That's a god question, I don't really know...
But fbdev does support XRGB8888, which may be another good reason to add it and make it the default format. Yes, it will cause an unnecessary pixel format conversion but the I2C transport is so slow anyways that compute is not the bottleneck when using these small displays.
Quoted 5 lines
Hrm, I now realised that I have another issue.
Not all LCDs that will be attached to the ST7571 controller will be grayscale.
The display I've attached to the ST7571 is a monochrome LCD for example.Oh, that's very interesting. This means that vendors are using a more capable IC (i.e: ST7571) for display controllers + LCD panels board designs, even where they could had used a less capable one (i.e: ST7765). That is, using an IC that supports 2-bit grayscale when they could just used one that only supported monochrome pixels.
From a quick search, I found for example this one from SinoCrystal:
https://displaysino.com/product_details/SC128128012-V01.html
Quoted 5 lines
Maybe the right way to do it is to only support XRGB8888 and specify if the display is monochrome or grayscale in the device tree.
Or do you have any good suggestions?
I don't know the proper way to handle this, but what I would do is to include the actual boards as entries in the OF device ID table instead of just the ICs.
And then for each entry you can specify what formats are supported, e.g:
static const uint32_t monochrome_formats[] = { DRM_FORMAT_XRGB8888, DRM_FORMAT_R1 };static const uint32_t grayscale_formats[] = { DRM_FORMAT_XRGB8888, DRM_FORMAT_R1 DRM_FORMAT_R2 };static const struct of_device_id st7571_of_match[] = { /* monochrome displays */ { .compatible = "sinocrystal,sc128128012-v01", .data = monochrome_formats, }, ... /* grayscale displays */ { .compatible = "foo,bar", .data = grayscale_formats, }, };and then in your probe callback, you can get the correct format list for the device matched. Something like the following for example:
static int st7571_probe(struct i2c_client *client) { const uint32_t *formats = device_get_match_data(client->dev); ... ret = drm_universal_plane_init(..., formats, ...); ... };
Quoted 5 lines
Likely you will need to define more stuff to be specific for each entry, maybe you will need different primary plane update handlers too. Similar to how I had to do it the ssd130x driver to support all the Solomon OLED controller families:
https://elixir.bootlin.com/linux/v6.11/source/drivers/gpu/drm/solomon/ssd130x.c#L1439
Thanks, that sounds like a good idea.
I've now experimenting with XRGB8888, and, well, it works. I guess.
The thresholds levels in the all conversion steps for XRGB8888 -> 8 bit grayscale -> monochrome makes my penguin look a bit boring.
But I guess that is expected.
Please compare
https://www.marcusfolkesson.se/xrgb8888.png
and
https://www.marcusfolkesson.se/c1.png
Quoted 7 lines
Signature · 5 lines
Best regards, Javier Martinez Canillas Core Platforms Red Hat
Best regards,
Marcus Folkesson
Re: [PATCH v3 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
Quoted 3 lines · Marcus Folkesson
Hello Javier,
On Wed, Apr 09, 2025 at 11:43:54AM +0200, Javier Martinez Canillas wrote:
[...]
Quoted 7 lines
Quoted 6 lines
Likely you will need to define more stuff to be specific for each entry, maybe you will need different primary plane update handlers too. Similar to how I had to do it the ssd130x driver to support all the Solomon OLED controller families:
https://elixir.bootlin.com/linux/v6.11/source/drivers/gpu/drm/solomon/ssd130x.c#L1439
Quoted 8 lines
Thanks, that sounds like a good idea.
I've now experimenting with XRGB8888, and, well, it works. I guess.
The thresholds levels in the all conversion steps for XRGB8888 -> 8 bit grayscale -> monochrome makes my penguin look a bit boring.But I guess that is expected.
Yeah, the XRGB8888 version is a boring indeed comparing with the C1 one...
The drm_fb_xrgb8888_to_mono() helper is very naive and just uses a very naive midpoint thresholding to choose if the pixel should be 1 or 0. So there is a lot of information lost there unfortunately.
But that's what I did for ssd130x, to at least have a working driver. Then support for R1 (for ssd130x family) and R4 (for the ssd132x family) could be added as follow-ups. I never did it but Geert has some patches for this.
Quoted 5 lines
Please compare
https://www.marcusfolkesson.se/xrgb8888.png
and
https://www.marcusfolkesson.se/c1.png
Nice pictures!
Quoted 10 lines
Quoted 7 lines
Signature · 5 lines
Best regards, Javier Martinez Canillas Core Platforms Red HatBest regards,
Marcus Folkesson
Signature · 5 lines
Best regards, Javier Martinez Canillas Core Platforms Red Hat
Re: [PATCH v3 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
Quoted 14 lines · Javier Martinez Canillas
Quoted 1 line · Marcus Folkesson
On Wed, Apr 09, 2025 at 11:43:54AM +0200, Javier Martinez Canillas wrote:
[...]
Quoted 9 lines
Quoted 6 lines
Likely you will need to define more stuff to be specific for each entry, maybe you will need different primary plane update handlers too. Similar to how I had to do it the ssd130x driver to support all the Solomon OLED controller families:
https://elixir.bootlin.com/linux/v6.11/source/drivers/gpu/drm/solomon/ssd130x.c#L1439
Thanks, that sounds like a good idea.
Quoted 7 lines
Quoted 5 lines
I've now experimenting with XRGB8888, and, well, it works. I guess.
The thresholds levels in the all conversion steps for XRGB8888 -> 8 bit grayscale -> monochrome makes my penguin look a bit boring.But I guess that is expected.
Yeah, the XRGB8888 version is a boring indeed comparing with the C1 one...
To see the nice monochrome penguin logo, fb-helper needs to gain support for R1 first...
Quoted 3 lines
The
drm_fb_xrgb8888_to_mono()helper is very naive and just uses a very naive midpoint thresholding to choose if the pixel should be 1 or 0. So there is a lot of information lost there unfortunately.
In theory, it could use Floyd–Steinberg dithering, like I did for modetest. However, given the display receives partial updates from damage clips, it will look ugly, and may flicker.
Quoted 3 lines
But that's what I did for ssd130x, to at least have a working driver. Then support for R1 (for ssd130x family) and R4 (for the ssd132x family) could be added as follow-ups. I never did it but Geert has some patches for this.
[1] needs an update, and still more rework to make them acceptable.
Quoted 4 lines
Quoted 4 lines
Please compare
https://www.marcusfolkesson.se/xrgb8888.png
and
https://www.marcusfolkesson.se/c1.png
Yep, the latter is using the correct logo.
[1] "[PATCH v2 0/8] drm: fb-helper/ssd130x: Add support for DRM_FORMAT_R1"
https://lore.kernel.org/all/[email protected]/
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Marcus Folkesson
maintainerRe: [PATCH v3 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
In reply to Javier Martinez CanillasHello,
Quoted 51 lines · Javier Martinez Canillas
Marcus Folkesson <[email protected]> writes:
Hello Marcus,
[...]
Quoted 8 lines
Quoted 7 lines
That's a god question, I don't really know...
But fbdev does support XRGB8888, which may be another good reason to add it and make it the default format. Yes, it will cause an unnecessary pixel format conversion but the I2C transport is so slow anyways that compute is not the bottleneck when using these small displays.
Quoted 5 lines
Hrm, I now realised that I have another issue.
Not all LCDs that will be attached to the ST7571 controller will be grayscale.
The display I've attached to the ST7571 is a monochrome LCD for example.Oh, that's very interesting. This means that vendors are using a more capable IC (i.e: ST7571) for display controllers + LCD panels board designs, even where they could had used a less capable one (i.e: ST7765). That is, using an IC that supports 2-bit grayscale when they could just used one that only supported monochrome pixels.
From a quick search, I found for example this one from SinoCrystal:
https://displaysino.com/product_details/SC128128012-V01.html
Quoted 5 lines
Maybe the right way to do it is to only support XRGB8888 and specify if the display is monochrome or grayscale in the device tree.
Or do you have any good suggestions?
I don't know the proper way to handle this, but what I would do is to include the actual boards as entries in the OF device ID table instead of just the ICs.
And then for each entry you can specify what formats are supported, e.g:
static const uint32_t monochrome_formats[] = { DRM_FORMAT_XRGB8888, DRM_FORMAT_R1 };static const uint32_t grayscale_formats[] = { DRM_FORMAT_XRGB8888, DRM_FORMAT_R1 DRM_FORMAT_R2 };
Quoted 13 lines
static const struct of_device_id st7571_of_match[] = {
/* monochrome displays */
{
.compatible = "sinocrystal,sc128128012-v01",
.data = monochrome_formats,
},
...
/* grayscale displays */
{
.compatible = "foo,bar",
.data = grayscale_formats,
},
};A comment for v4:
I think I will go for a property in the device tree. I've implemented board entries as above, but I'm not satisfied for two reasons:
1. All other properties like display size and resolution are already specified in the device tree. If I add entries for specific boards, these properties will be somehow redundant and not as generic.
2. I could not find a ST7571 with a grayscale display as a off-the-shelf product.
Quoted 7 lines
Signature · 6 lines
-- Best regards, Javier Martinez Canillas Core Platforms Red Hat
Best regards,
Marcus Folkesson
Re: [PATCH v3 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
Marcus Folkesson <[email protected]> writes:
Hello Marcus,
[...]
Quoted 19 lines
Quoted 5 lines
static const struct of_device_id st7571_of_match[] = { /* monochrome displays */ { .compatible = "sinocrystal,sc128128012-v01", .data = monochrome_formats,Quoted 8 lines
}, ... /* grayscale displays */ { .compatible = "foo,bar", .data = grayscale_formats, }, };A comment for v4:
I think I will go for a property in the device tree. I've implemented board entries as above, but I'm not satisfied for two reasons:
Quoted 6 lines
1. All other properties like display size and resolution are already specified in the device tree. If I add entries for specific boards, these properties will be somehow redundant and not as generic.
2. I could not find a ST7571 with a grayscale display as a off-the-shelf product.
Sure, that makes sense to me.
Can I ask if you could still add reasonable default values that could be set in the device ID .data fields ?
As mentioned, I've a ST7567 based LCD and a WIP driver for it. But I could just drop that and use your driver, since AFAICT the expected display data RAM format is exactly the same than when using monochrome for the ST7571.
But due the ST7567 only supporting R1, it would be silly to always have to define a property in the DT node given that does not support other format.
Signature · 5 lines
Best regards, Javier Martinez Canillas Core Platforms Red Hat
Marcus Folkesson
maintainerRe: [PATCH v3 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
Quoted 37 lines · Javier Martinez Canillas
Marcus Folkesson <[email protected]> writes:
Hello Marcus,
[...]
Quoted 19 lines
Quoted 5 lines
static const struct of_device_id st7571_of_match[] = { /* monochrome displays */ { .compatible = "sinocrystal,sc128128012-v01", .data = monochrome_formats,Quoted 8 lines
}, ... /* grayscale displays */ { .compatible = "foo,bar", .data = grayscale_formats, }, };A comment for v4:
I think I will go for a property in the device tree. I've implemented board entries as above, but I'm not satisfied for two reasons:
Quoted 6 lines
1. All other properties like display size and resolution are already specified in the device tree. If I add entries for specific boards, these properties will be somehow redundant and not as generic.
2. I could not find a ST7571 with a grayscale display as a off-the-shelf product.
Sure, that makes sense to me.
Can I ask if you could still add reasonable default values that could be set in the device ID .data fields ?
Quoted 6 lines
As mentioned, I've a ST7567 based LCD and a WIP driver for it. But I could just drop that and use your driver, since AFAICT the expected display data RAM format is exactly the same than when using monochrome for the ST7571.
But due the ST7567 only supporting R1, it would be silly to always have to define a property in the DT node given that does not support other format.
Sure!
I've looked at the ST7567 datasheet and it seems indeed to be a very similar. Both in pixel format and registers are the same.
I think specify a init-function (as those will differ) and constraints will be enough to handle both chips.
I will prepare .data with something like this
struct st7571_panel_constraints {
u32 min_nlines;
u32 max_nlines;
u32 min_ncols;
u32 max_ncols;
bool support_grayscale;
};struct st7571_panel_data {
int (*init)(struct st7571_device *st7571);
struct st7571_panel_constraints constraints;
};struct st7571_panel_data st7571_data = {
.init = st7571_lcd_init,
.constraints = {
.min_nlines = 1,
.max_nlines = 128,
.min_ncols = 128,
.max_ncols = 128,
.support_grayscale = true,
},
};static const struct of_device_id st7571_of_match[] = {
{ .compatible = "sitronix,st7571", .data = &st7571_data },
{},
};I can add an entry for the ST7567 when everything is in place. The chip does not support the I2C interface, so it has to wait until I've split up the driver though, which will be right after this series.
Quoted 7 lines
Signature · 6 lines
-- Best regards, Javier Martinez Canillas Core Platforms Red Hat
Best regards,
Marcus Folkesson
Quoted 1 line
Re: [PATCH v3 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
Marcus Folkesson <[email protected]> writes:
Hello Marcus,
[...]
Quoted 22 lines
Quoted 22 lines
Quoted 6 lines
A comment for v4:
I think I will go for a property in the device tree. I've implemented board entries as above, but I'm not satisfied for two reasons:
Quoted 6 lines
1. All other properties like display size and resolution are already specified in the device tree. If I add entries for specific boards, these properties will be somehow redundant and not as generic.
2. I could not find a ST7571 with a grayscale display as a off-the-shelf product.
Sure, that makes sense to me.
Can I ask if you could still add reasonable default values that could be set in the device ID .data fields ?
As mentioned, I've a ST7567 based LCD and a WIP driver for it. But I could just drop that and use your driver, since AFAICT the expected display data RAM format is exactly the same than when using monochrome for the ST7571.
Quoted 7 lines
Quoted 2 lines
But due the ST7567 only supporting R1, it would be silly to always have to define a property in the DT node given that does not support other format.
Sure!
I've looked at the ST7567 datasheet and it seems indeed to be a very similar. Both in pixel format and registers are the same.
Thanks for confirming, that was my understanding too.
Quoted 29 lines
I think specify a init-function (as those will differ) and constraints will be enough to handle both chips.
I will prepare .data with something like this
struct st7571_panel_constraints { u32 min_nlines; u32 max_nlines; u32 min_ncols; u32 max_ncols; bool support_grayscale; };struct st7571_panel_data { int (*init)(struct st7571_device *st7571); struct st7571_panel_constraints constraints; };struct st7571_panel_data st7571_data = { .init = st7571_lcd_init, .constraints = { .min_nlines = 1, .max_nlines = 128, .min_ncols = 128, .max_ncols = 128, .support_grayscale = true, }, };
Quoted 5 lines
static const struct of_device_id st7571_of_match[] = {
{ .compatible = "sitronix,st7571", .data = &st7571_data },
{},
};That's great! Exactly what I had in mind.
Quoted 3 lines
I can add an entry for the ST7567 when everything is in place. The chip does not support the I2C interface, so it has to wait until
Yes, but there are designs with carrier boards that support I2C. For example, I have [1] and [2]. The former comes with an I2C interface and uses the ST7567S IC variant, while the latter comes with a 4-wire SPI interface and uses a ST7567P IC variant.
But don't worry about it. Since I've these displays and your driver now allows for different IC families after adding the mentioned indirection layer, it should be very trivial for me to add support for these on top.
Quoted 2 lines
I've split up the driver though, which will be right after this series.
Nice, thanks again.
Signature · 5 lines
Best regards, Javier Martinez Canillas Core Platforms Red Hat
Marcus Folkesson
maintainerRe: [PATCH v3 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
In reply to Javier Martinez CanillasHello Javier,
Quoted 36 lines · Javier Martinez Canillas
Marcus Folkesson <[email protected]> writes:
Hello Marcus,
Quoted 4 lines
Sitronix ST7571 is a 4bit gray scale dot matrix LCD controller. The controller has a SPI, I2C and 8bit parallel interface, this driver is for the I2C interface only.
I would structure the driver differently. For example, what was done for the Solomon SSD130X display controllers, that also support these three interfaces:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/solomon
Basically, it was split in a
ssd130x.cmodule that's agnostic of the transport interface and implements all the core logic for the driver.And a set of different modules that have the interface specific bits:
ssd130x-i2c.candssd130x-spi.c.That way, adding for example SPI support to your driver would be quite trivial and won't require any refactoring. Specially since you already are using regmap, which abstracts away the I2C interface bits.
Quoted 6 lines
Reviewed-by Thomas Zimmermann <[email protected]>Signed-off-by Marcus Folkesson <[email protected]>--- drivers/gpu/drm/tiny/Kconfig | 11 + drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/tiny/st7571-i2c.c | 721 ++++++++++++++++++++++++++++++++++++++I personally think that the tiny sub-directory is slowly becoming a dumping ground for small drivers. Instead, maybe we should create a
drivers/gpu/drm/sitronix/sub-dir and put all Sitronix drivers there?
Quoted 7 lines
So far we have drivers in tiny for: ST7735R, ST7586 and ST7571 with your driver. And also have a few more Sitronix drivers in the panel sub-directory (although those likely should remain there).
I have a ST7565S and plan to write a driver for it. And I know someone who is working on a ST7920 driver. That would be 5 Sitronix drivers and the reason why I think that a dedicated sub-dir would be more organized.
I'm looking into moving all the (tiny) Sitronix drivers into their own subdirectory.
When doing that, should I replace the TINYDRM part with DRM for those drivers? E.g. CONFIG_TINYDRM_ST7735R -> CONFIG_DRM_ST7735R.
Or do we want to keep the config name intact?
Best regards,
Marcus Folkesson
Re: [PATCH v3 2/3] drm/st7571-i2c: add support for Sitronix ST7571 LCD controller
Quoted 43 lines · Marcus Folkesson
Hello Javier,
Quoted 40 lines · Javier Martinez Canillas
Marcus Folkesson <[email protected]> writes:
Hello Marcus,
Quoted 4 lines
Sitronix ST7571 is a 4bit gray scale dot matrix LCD controller. The controller has a SPI, I2C and 8bit parallel interface, this driver is for the I2C interface only.
I would structure the driver differently. For example, what was done for the Solomon SSD130X display controllers, that also support these three interfaces:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/solomon
Basically, it was split in a
ssd130x.cmodule that's agnostic of the transport interface and implements all the core logic for the driver.And a set of different modules that have the interface specific bits:
ssd130x-i2c.candssd130x-spi.c.That way, adding for example SPI support to your driver would be quite trivial and won't require any refactoring. Specially since you already are using regmap, which abstracts away the I2C interface bits.
Quoted 6 lines
Reviewed-by Thomas Zimmermann <[email protected]>Signed-off-by Marcus Folkesson <[email protected]>--- drivers/gpu/drm/tiny/Kconfig | 11 + drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/tiny/st7571-i2c.c | 721 ++++++++++++++++++++++++++++++++++++++I personally think that the tiny sub-directory is slowly becoming a dumping ground for small drivers. Instead, maybe we should create a
drivers/gpu/drm/sitronix/sub-dir and put all Sitronix drivers there?So far we have drivers in tiny for: ST7735R, ST7586 and ST7571 with your driver. And also have a few more Sitronix drivers in the panel sub-directory (although those likely should remain there).
Quoted 5 lines
Quoted 3 lines
I have a ST7565S and plan to write a driver for it. And I know someone who is working on a ST7920 driver. That would be 5 Sitronix drivers and the reason why I think that a dedicated sub-dir would be more organized.
I'm looking into moving all the (tiny) Sitronix drivers into their own
Great!
Quoted 4 lines
subdirectory.
When doing that, should I replace the TINYDRM part with DRM for those drivers? E.g.CONFIG_TINYDRM_ST7735R->CONFIG_DRM_ST7735R.
I would drop the TINY prefix. That's also why I thought that your new driver not having TINY in its Kconfig symbol name was the correct call.
Quoted 4 lines
Or do we want to keep the config name intact?
Best regards,
Marcus Folkesson
Signature · 5 lines
Best regards, Javier Martinez Canillas Core Platforms Red Hat
Marcus Folkesson
maintainerPATCH v3 3/3 MAINTAINERS: add entry for Sitronix ST7571 LCD Controller
In reply to Marcus FolkessonAdd MAINTAINERS entry for the Sitronix ST7571 dot matrix LCD controller.
--- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+)
MAINTAINERS +6 -0
@@ -7572,6 +7572,12 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: Documentation/devicetree/bindings/display/sitronix,st7586.txt F: drivers/gpu/drm/tiny/st7586.c +DRM DRIVER FOR SITRONIX ST7571 PANELS +M: Marcus Folkesson <[email protected]> +S: Maintained +F: Documentation/devicetree/bindings/display/sitronix,st7571.yaml +F: drivers/gpu/drm/tiny/st7571-i2c.c + DRM DRIVER FOR SITRONIX ST7701 PANELS M: Jagan Teki <[email protected]> S: Maintained
Signature · 1 line
2.49.0