Message ID | 20240512-panel-mipi-dbi-rgb666-v2-5-49dd266328a0@tronnes.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/tiny: panel-mipi-dbi: Support 18 bits per color RGB666 | expand |
On 12/05/2024 17:25, Noralf Trønnes via B4 Relay wrote: > From: Noralf Trønnes <noralf@tronnes.org> > > Add support for these pixel format property values: > - r5g6b5, RGB565 > - b6x2g6x2r6x2, BGR666 > > BGR666 is presented to userspace as RGB888. The 2 LSB in each color > are discarded by the controller. The pixel is sent on the wire using > 8 bits per word (little endian) so the controller sees it as BGR. > > RGB565 is the default if the property is not present. > > Signed-off-by: Noralf Trønnes <noralf@tronnes.org> > --- > drivers/gpu/drm/tiny/panel-mipi-dbi.c | 55 ++++++++++++++++++++++++++++++++++- > 1 file changed, 54 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/tiny/panel-mipi-dbi.c b/drivers/gpu/drm/tiny/panel-mipi-dbi.c > index f80a141fcf36..f3aa2abce314 100644 > --- a/drivers/gpu/drm/tiny/panel-mipi-dbi.c > +++ b/drivers/gpu/drm/tiny/panel-mipi-dbi.c > @@ -26,6 +26,49 @@ > > #include <video/mipi_display.h> > > +struct panel_mipi_dbi_format { > + const char *name; > + u32 fourcc; > + unsigned int bpp; > +}; > + > +static const struct panel_mipi_dbi_format panel_mipi_dbi_formats[] = { > + { "r5g6b5", DRM_FORMAT_RGB565, 16 }, > + { "b6x2g6x2r6x2", DRM_FORMAT_RGB888, 24 }, > +}; > + > +static int panel_mipi_dbi_get_format(struct device *dev, u32 *formats, unsigned int *bpp) > +{ > + const char *format_name; > + unsigned int i; > + int ret; > + > + formats[1] = DRM_FORMAT_XRGB8888; > + > + ret = device_property_read_string(dev, "format", &format_name); > + if (ret) { > + /* Old Device Trees don't have this property */ > + formats[0] = DRM_FORMAT_RGB565; > + *bpp = 16; > + return 0; > + } > + > + for (i = 0; i < ARRAY_SIZE(panel_mipi_dbi_formats); i++) { > + const struct panel_mipi_dbi_format *format = &panel_mipi_dbi_formats[i]; > + > + if (strcmp(format_name, format->name)) > + continue; > + > + formats[0] = format->fourcc; > + *bpp = format->bpp; > + return 0; > + } > + > + dev_err(dev, "Pixel format is not supported: '%s'\n", format_name); > + > + return -EINVAL; > +} > + > static const u8 panel_mipi_dbi_magic[15] = { 'M', 'I', 'P', 'I', ' ', 'D', 'B', 'I', > 0, 0, 0, 0, 0, 0, 0 }; > > @@ -276,6 +319,9 @@ static int panel_mipi_dbi_spi_probe(struct spi_device *spi) > struct drm_device *drm; > struct mipi_dbi *dbi; > struct gpio_desc *dc; > + unsigned int bpp; > + size_t buf_size; > + u32 formats[2]; > int ret; > > dbidev = devm_drm_dev_alloc(dev, &panel_mipi_dbi_driver, struct mipi_dbi_dev, drm); > @@ -323,7 +369,14 @@ static int panel_mipi_dbi_spi_probe(struct spi_device *spi) > if (IS_ERR(dbidev->driver_private)) > return PTR_ERR(dbidev->driver_private); > > - ret = mipi_dbi_dev_init(dbidev, &panel_mipi_dbi_pipe_funcs, &mode, 0); > + ret = panel_mipi_dbi_get_format(dev, formats, &bpp); > + if (ret) > + return ret; > + > + buf_size = DIV_ROUND_UP(mode.hdisplay * mode.vdisplay * bpp, 8); > + ret = mipi_dbi_dev_init_with_formats(dbidev, &panel_mipi_dbi_pipe_funcs, > + formats, ARRAY_SIZE(formats), > + &mode, 0, buf_size); > if (ret) > return ret; > > Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
diff --git a/drivers/gpu/drm/tiny/panel-mipi-dbi.c b/drivers/gpu/drm/tiny/panel-mipi-dbi.c index f80a141fcf36..f3aa2abce314 100644 --- a/drivers/gpu/drm/tiny/panel-mipi-dbi.c +++ b/drivers/gpu/drm/tiny/panel-mipi-dbi.c @@ -26,6 +26,49 @@ #include <video/mipi_display.h> +struct panel_mipi_dbi_format { + const char *name; + u32 fourcc; + unsigned int bpp; +}; + +static const struct panel_mipi_dbi_format panel_mipi_dbi_formats[] = { + { "r5g6b5", DRM_FORMAT_RGB565, 16 }, + { "b6x2g6x2r6x2", DRM_FORMAT_RGB888, 24 }, +}; + +static int panel_mipi_dbi_get_format(struct device *dev, u32 *formats, unsigned int *bpp) +{ + const char *format_name; + unsigned int i; + int ret; + + formats[1] = DRM_FORMAT_XRGB8888; + + ret = device_property_read_string(dev, "format", &format_name); + if (ret) { + /* Old Device Trees don't have this property */ + formats[0] = DRM_FORMAT_RGB565; + *bpp = 16; + return 0; + } + + for (i = 0; i < ARRAY_SIZE(panel_mipi_dbi_formats); i++) { + const struct panel_mipi_dbi_format *format = &panel_mipi_dbi_formats[i]; + + if (strcmp(format_name, format->name)) + continue; + + formats[0] = format->fourcc; + *bpp = format->bpp; + return 0; + } + + dev_err(dev, "Pixel format is not supported: '%s'\n", format_name); + + return -EINVAL; +} + static const u8 panel_mipi_dbi_magic[15] = { 'M', 'I', 'P', 'I', ' ', 'D', 'B', 'I', 0, 0, 0, 0, 0, 0, 0 }; @@ -276,6 +319,9 @@ static int panel_mipi_dbi_spi_probe(struct spi_device *spi) struct drm_device *drm; struct mipi_dbi *dbi; struct gpio_desc *dc; + unsigned int bpp; + size_t buf_size; + u32 formats[2]; int ret; dbidev = devm_drm_dev_alloc(dev, &panel_mipi_dbi_driver, struct mipi_dbi_dev, drm); @@ -323,7 +369,14 @@ static int panel_mipi_dbi_spi_probe(struct spi_device *spi) if (IS_ERR(dbidev->driver_private)) return PTR_ERR(dbidev->driver_private); - ret = mipi_dbi_dev_init(dbidev, &panel_mipi_dbi_pipe_funcs, &mode, 0); + ret = panel_mipi_dbi_get_format(dev, formats, &bpp); + if (ret) + return ret; + + buf_size = DIV_ROUND_UP(mode.hdisplay * mode.vdisplay * bpp, 8); + ret = mipi_dbi_dev_init_with_formats(dbidev, &panel_mipi_dbi_pipe_funcs, + formats, ARRAY_SIZE(formats), + &mode, 0, buf_size); if (ret) return ret;