diff options
author | Noralf Trønnes <noralf@tronnes.org> | 2024-06-04 15:20:32 +0200 |
---|---|---|
committer | Noralf Trønnes <noralf@tronnes.org> | 2024-06-07 16:09:06 +0200 |
commit | aa61186951cc1fd302e7d2d180061a8d568dff90 (patch) | |
tree | 2148903a16de6baaac0b6eb0a465cd22ee8def00 /drivers/gpu/drm/tiny | |
parent | 4aebb79021f3e6c2b6fbb92a7d9c5d1e6ad0324a (diff) |
drm/tiny: panel-mipi-dbi: Support the pixel format property
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.
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20240604-panel-mipi-dbi-rgb666-v4-5-d7c2bcb9b78d@tronnes.org
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
Diffstat (limited to 'drivers/gpu/drm/tiny')
-rw-r--r-- | drivers/gpu/drm/tiny/panel-mipi-dbi.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/drivers/gpu/drm/tiny/panel-mipi-dbi.c b/drivers/gpu/drm/tiny/panel-mipi-dbi.c index b353a731f253..f753cdffe6f8 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; |