From: Noralf Trønnes <nor...@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 <nor...@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;
 

-- 
2.45.0


Reply via email to