Hello,
While working on adding support for the SSD132X family of 4-bit grayscale
Solomon OLED panel controllers, I noticed a few things in the driver that
can be improved and make extending to support other chip families easier.
I've split the preparatory patches in this series and will post the actual
SSD132X support as a separate patch-set once this one is merged.
Best regards,
Javier
Javier Martinez Canillas (5):
drm/ssd130x: Make default width and height to be controller dependent
dt-bindings: display: ssd1307fb: Remove default width and height
values
drm/ssd130x: Set the page height value in the device info data
drm/ssd130x: Don't allocate buffers on each plane update
drm/ssd130x: Remove hardcoded bits-per-pixel in ssd130x_buf_alloc()
.../bindings/display/solomon,ssd1307fb.yaml | 8 +-
drivers/gpu/drm/solomon/ssd130x.c | 124 ++++++++++++------
drivers/gpu/drm/solomon/ssd130x.h | 6 +
3 files changed, 93 insertions(+), 45 deletions(-)
--
2.40.1
Currently the driver hardcodes the default values to 96x16 pixels but this
default resolution depends on the controller. The datasheets for the chips
describes the following display controller resolutions:
- SH1106: 132 x 64 Dot Matrix OLED/PLED
- SSD1306: 128 x 64 Dot Matrix OLED/PLED
- SSD1307: 128 x 39 Dot Matrix OLED/PLED
- SSD1309: 128 x 64 Dot Matrix OLED/PLED
Add this information to the devices' info structures, and use it set as a
default if not defined in DT rather than hardcoding to an arbitrary value.
Signed-off-by: Javier Martinez Canillas <[email protected]>
---
drivers/gpu/drm/solomon/ssd130x.c | 14 ++++++++++++--
drivers/gpu/drm/solomon/ssd130x.h | 2 ++
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c
index 8cbf5aa66e19..a0e5e26c0bc9 100644
--- a/drivers/gpu/drm/solomon/ssd130x.c
+++ b/drivers/gpu/drm/solomon/ssd130x.c
@@ -99,29 +99,39 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = {
.default_vcomh = 0x40,
.default_dclk_div = 1,
.default_dclk_frq = 5,
+ .default_width = 132,
+ .default_height = 64,
.page_mode_only = 1,
},
[SSD1305_ID] = {
.default_vcomh = 0x34,
.default_dclk_div = 1,
.default_dclk_frq = 7,
+ .default_width = 132,
+ .default_height = 64,
},
[SSD1306_ID] = {
.default_vcomh = 0x20,
.default_dclk_div = 1,
.default_dclk_frq = 8,
.need_chargepump = 1,
+ .default_width = 128,
+ .default_height = 64,
},
[SSD1307_ID] = {
.default_vcomh = 0x20,
.default_dclk_div = 2,
.default_dclk_frq = 12,
.need_pwm = 1,
+ .default_width = 128,
+ .default_height = 39,
},
[SSD1309_ID] = {
.default_vcomh = 0x34,
.default_dclk_div = 1,
.default_dclk_frq = 10,
+ .default_width = 128,
+ .default_height = 64,
}
};
EXPORT_SYMBOL_NS_GPL(ssd130x_variants, DRM_SSD130X);
@@ -798,10 +808,10 @@ static void ssd130x_parse_properties(struct ssd130x_device *ssd130x)
struct device *dev = ssd130x->dev;
if (device_property_read_u32(dev, "solomon,width", &ssd130x->width))
- ssd130x->width = 96;
+ ssd130x->width = ssd130x->device_info->default_width;
if (device_property_read_u32(dev, "solomon,height", &ssd130x->height))
- ssd130x->height = 16;
+ ssd130x->height = ssd130x->device_info->default_height;
if (device_property_read_u32(dev, "solomon,page-offset", &ssd130x->page_offset))
ssd130x->page_offset = 1;
diff --git a/drivers/gpu/drm/solomon/ssd130x.h b/drivers/gpu/drm/solomon/ssd130x.h
index db03ee5db392..a2bc8d75078b 100644
--- a/drivers/gpu/drm/solomon/ssd130x.h
+++ b/drivers/gpu/drm/solomon/ssd130x.h
@@ -37,6 +37,8 @@ struct ssd130x_deviceinfo {
u32 default_vcomh;
u32 default_dclk_div;
u32 default_dclk_frq;
+ u32 default_width;
+ u32 default_height;
int need_pwm;
int need_chargepump;
bool page_mode_only;
--
2.40.1
The driver only supports OLED controllers that have a native DRM_FORMAT_C1
pixel format and that is why it has harcoded a division of the width by 8.
But the driver might be extended to support devices that have a different
pixel format. So it's better to use the struct drm_format_info helpers to
compute the size of the buffer, used to store the pixels in native format.
Signed-off-by: Javier Martinez Canillas <[email protected]>
---
drivers/gpu/drm/solomon/ssd130x.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c
index 0be3b476dc60..b3dc1ca9dc10 100644
--- a/drivers/gpu/drm/solomon/ssd130x.c
+++ b/drivers/gpu/drm/solomon/ssd130x.c
@@ -150,9 +150,16 @@ static int ssd130x_buf_alloc(struct ssd130x_device *ssd130x)
{
unsigned int page_height = ssd130x->device_info->page_height;
unsigned int pages = DIV_ROUND_UP(ssd130x->height, page_height);
+ const struct drm_format_info *fi;
+ unsigned int pitch;
- ssd130x->buffer = kcalloc(DIV_ROUND_UP(ssd130x->width, 8),
- ssd130x->height, GFP_KERNEL);
+ fi = drm_format_info(DRM_FORMAT_C1);
+ if (!fi)
+ return -EINVAL;
+
+ pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width);
+
+ ssd130x->buffer = kcalloc(pitch, ssd130x->height, GFP_KERNEL);
if (!ssd130x->buffer)
return -ENOMEM;
--
2.40.1
Hi Javierm,
I've read through the patches and they look correct to me.
Reviewed-by: Thomas Zimmermann <[email protected]>
But I had one question about the page size. You round up to multiples of
page_size in several places. That could lead to an out-of-bounds access.
Do you need to allocate GEM buffers to be multiples of page_size as well?
Best regards
Thomas
Am 05.06.23 um 09:47 schrieb Javier Martinez Canillas:
> Hello,
>
> While working on adding support for the SSD132X family of 4-bit grayscale
> Solomon OLED panel controllers, I noticed a few things in the driver that
> can be improved and make extending to support other chip families easier.
>
> I've split the preparatory patches in this series and will post the actual
> SSD132X support as a separate patch-set once this one is merged.
>
> Best regards,
> Javier
>
>
> Javier Martinez Canillas (5):
> drm/ssd130x: Make default width and height to be controller dependent
> dt-bindings: display: ssd1307fb: Remove default width and height
> values
> drm/ssd130x: Set the page height value in the device info data
> drm/ssd130x: Don't allocate buffers on each plane update
> drm/ssd130x: Remove hardcoded bits-per-pixel in ssd130x_buf_alloc()
>
> .../bindings/display/solomon,ssd1307fb.yaml | 8 +-
> drivers/gpu/drm/solomon/ssd130x.c | 124 ++++++++++++------
> drivers/gpu/drm/solomon/ssd130x.h | 6 +
> 3 files changed, 93 insertions(+), 45 deletions(-)
>
--
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)
Thomas Zimmermann <[email protected]> writes:
Hello Thomas,
> Hi Javierm,
>
> I've read through the patches and they look correct to me.
>
> Reviewed-by: Thomas Zimmermann <[email protected]>
>
Thanks a lot for your review!
> But I had one question about the page size. You round up to multiples of
> page_size in several places. That could lead to an out-of-bounds access.
> Do you need to allocate GEM buffers to be multiples of page_size as well?
>
That's a good point and I would need to have a closer look to the driver
to determine if that's needed or not as well. If that's the case though,
the issue is already present in the driver. We could fix it as follow-up.
> Best regards
> Thomas
>
--
Best regards,
Javier Martinez Canillas
Core Platforms
Red Hat