diff mbox series

[09/10] drm/tinydrm/mipi-dbi: Add mipi_dbi_init_with_formats()

Message ID 20190717115817.30110-10-noralf@tronnes.org (mailing list archive)
State New, archived
Headers show
Series drm/tinydrm: Remove tinydrm.ko | expand

Commit Message

Noralf Trønnes July 17, 2019, 11:58 a.m. UTC
The MIPI DBI standard support more pixel formats than what this helper
supports. Add an init function that lets the driver use different
format(s). This avoids open coding mipi_dbi_init() in st7586.

st7586 sets preferred_depth but this is not necessary since it only
supports one format.

Cc: David Lechner <david@lechnology.com>
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
---
 drivers/gpu/drm/tinydrm/mipi-dbi.c | 91 +++++++++++++++++++++---------
 drivers/gpu/drm/tinydrm/st7586.c   | 32 ++---------
 include/drm/tinydrm/mipi-dbi.h     |  5 ++
 3 files changed, 74 insertions(+), 54 deletions(-)

Comments

David Lechner July 17, 2019, 8:38 p.m. UTC | #1
On 7/17/19 6:58 AM, Noralf Trønnes wrote:
> The MIPI DBI standard support more pixel formats than what this helper
> supports. Add an init function that lets the driver use different
> format(s). This avoids open coding mipi_dbi_init() in st7586.
> 
> st7586 sets preferred_depth but this is not necessary since it only
> supports one format.

Although that might not always be the case. FYI, we are finding that
having XRGB8888 for a 2bpp grayscale display is not the greatest. When
we want to do direct drawing on the screen, we haven't found very good
support in existing graphics libraries for embedded systems for this
format. If I had more free time, I would like to look at adding
grayscale support to DRM.

> 
> Cc: David Lechner <david@lechnology.com>
> Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
> ---

Acked-by: David Lechner <david@lechnology.com>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/tinydrm/mipi-dbi.c b/drivers/gpu/drm/tinydrm/mipi-dbi.c
index 73db287e5c52..a264c0bb74b0 100644
--- a/drivers/gpu/drm/tinydrm/mipi-dbi.c
+++ b/drivers/gpu/drm/tinydrm/mipi-dbi.c
@@ -411,6 +411,65 @@  static const uint32_t mipi_dbi_formats[] = {
 	DRM_FORMAT_XRGB8888,
 };
 
+/**
+ * mipi_dbi_init_with_formats - MIPI DBI initialization with custom formats
+ * @mipi: &mipi_dbi structure to initialize
+ * @funcs: Display pipe functions
+ * @formats: Array of supported formats (DRM_FORMAT\_\*).
+ * @format_count: Number of elements in @formats
+ * @mode: Display mode
+ * @rotation: Initial rotation in degrees Counter Clock Wise
+ * @tx_buf_size: Allocate a transmit buffer of this size.
+ *
+ * This function sets up a &drm_simple_display_pipe with a &drm_connector that
+ * has one fixed &drm_display_mode which is rotated according to @rotation.
+ * This mode is used to set the mode config min/max width/height properties.
+ *
+ * Use mipi_dbi_init() if you don't need custom formats.
+ *
+ * Note:
+ * Some of the helper functions expects RGB565 to be the default format and the
+ * transmit buffer sized to fit that.
+ *
+ * Returns:
+ * Zero on success, negative error code on failure.
+ */
+int mipi_dbi_init_with_formats(struct mipi_dbi *mipi,
+			       const struct drm_simple_display_pipe_funcs *funcs,
+			       const uint32_t *formats, unsigned int format_count,
+			       const struct drm_display_mode *mode,
+			       unsigned int rotation, size_t tx_buf_size)
+{
+	struct drm_device *drm = &mipi->drm;
+	int ret;
+
+	if (!mipi->command)
+		return -EINVAL;
+
+	mutex_init(&mipi->cmdlock);
+
+	mipi->tx_buf = devm_kmalloc(drm->dev, tx_buf_size, GFP_KERNEL);
+	if (!mipi->tx_buf)
+		return -ENOMEM;
+
+	ret = tinydrm_display_pipe_init(drm, &mipi->pipe, funcs,
+					DRM_MODE_CONNECTOR_SPI,
+					formats, format_count, mode,
+					rotation);
+	if (ret)
+		return ret;
+
+	drm_plane_enable_fb_damage_clips(&mipi->pipe.plane);
+
+	drm->mode_config.funcs = &mipi_dbi_mode_config_funcs;
+	mipi->rotation = rotation;
+
+	DRM_DEBUG_KMS("rotation = %u\n", rotation);
+
+	return 0;
+}
+EXPORT_SYMBOL(mipi_dbi_init_with_formats);
+
 /**
  * mipi_dbi_init - MIPI DBI initialization
  * @mipi: &mipi_dbi structure to initialize
@@ -433,36 +492,12 @@  int mipi_dbi_init(struct mipi_dbi *mipi,
 		  const struct drm_display_mode *mode, unsigned int rotation)
 {
 	size_t bufsize = mode->vdisplay * mode->hdisplay * sizeof(u16);
-	struct drm_device *drm = &mipi->drm;
-	int ret;
 
-	if (!mipi->command)
-		return -EINVAL;
+	mipi->drm.mode_config.preferred_depth = 16;
 
-	mutex_init(&mipi->cmdlock);
-
-	mipi->tx_buf = devm_kmalloc(drm->dev, bufsize, GFP_KERNEL);
-	if (!mipi->tx_buf)
-		return -ENOMEM;
-
-	ret = tinydrm_display_pipe_init(drm, &mipi->pipe, funcs,
-					DRM_MODE_CONNECTOR_SPI,
-					mipi_dbi_formats,
-					ARRAY_SIZE(mipi_dbi_formats), mode,
-					rotation);
-	if (ret)
-		return ret;
-
-	drm_plane_enable_fb_damage_clips(&mipi->pipe.plane);
-
-	drm->mode_config.funcs = &mipi_dbi_mode_config_funcs;
-	drm->mode_config.preferred_depth = 16;
-	mipi->rotation = rotation;
-
-	DRM_DEBUG_KMS("preferred_depth=%u, rotation = %u\n",
-		      drm->mode_config.preferred_depth, rotation);
-
-	return 0;
+	return mipi_dbi_init_with_formats(mipi, funcs, mipi_dbi_formats,
+					  ARRAY_SIZE(mipi_dbi_formats), mode,
+					  rotation, bufsize);
 }
 EXPORT_SYMBOL(mipi_dbi_init);
 
diff --git a/drivers/gpu/drm/tinydrm/st7586.c b/drivers/gpu/drm/tinydrm/st7586.c
index 7ae39004aa88..650ca8d4732e 100644
--- a/drivers/gpu/drm/tinydrm/st7586.c
+++ b/drivers/gpu/drm/tinydrm/st7586.c
@@ -24,7 +24,6 @@ 
 #include <drm/drm_rect.h>
 #include <drm/drm_vblank.h>
 #include <drm/tinydrm/mipi-dbi.h>
-#include <drm/tinydrm/tinydrm-helpers.h>
 
 /* controller-specific commands */
 #define ST7586_DISP_MODE_GRAY	0x38
@@ -283,12 +282,6 @@  static const struct drm_simple_display_pipe_funcs st7586_pipe_funcs = {
 	.prepare_fb	= drm_gem_fb_simple_display_pipe_prepare_fb,
 };
 
-static const struct drm_mode_config_funcs st7586_mode_config_funcs = {
-	.fb_create = drm_gem_fb_create_with_dirty,
-	.atomic_check = drm_atomic_helper_check,
-	.atomic_commit = drm_atomic_helper_commit,
-};
-
 static const struct drm_display_mode st7586_mode = {
 	DRM_SIMPLE_MODE(178, 128, 37, 27),
 };
@@ -342,15 +335,8 @@  static int st7586_probe(struct spi_device *spi)
 	}
 
 	drm_mode_config_init(drm);
-	drm->mode_config.preferred_depth = 32;
-	drm->mode_config.funcs = &st7586_mode_config_funcs;
-
-	mutex_init(&mipi->cmdlock);
 
 	bufsize = (st7586_mode.vdisplay + 2) / 3 * st7586_mode.hdisplay;
-	mipi->tx_buf = devm_kmalloc(dev, bufsize, GFP_KERNEL);
-	if (!mipi->tx_buf)
-		return -ENOMEM;
 
 	mipi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
 	if (IS_ERR(mipi->reset)) {
@@ -374,6 +360,12 @@  static int st7586_probe(struct spi_device *spi)
 	/* Cannot read from this controller via SPI */
 	mipi->read_commands = NULL;
 
+	ret = mipi_dbi_init_with_formats(mipi, &st7586_pipe_funcs,
+					 st7586_formats, ARRAY_SIZE(st7586_formats),
+					 &st7586_mode, rotation, bufsize);
+	if (ret)
+		return ret;
+
 	/*
 	 * we are using 8-bit data, so we are not actually swapping anything,
 	 * but setting mipi->swap_bytes makes mipi_dbi_typec3_command() do the
@@ -383,15 +375,6 @@  static int st7586_probe(struct spi_device *spi)
 	 */
 	mipi->swap_bytes = true;
 
-	ret = tinydrm_display_pipe_init(drm, &mipi->pipe, &st7586_pipe_funcs,
-					DRM_MODE_CONNECTOR_SPI,
-					st7586_formats, ARRAY_SIZE(st7586_formats),
-					&st7586_mode, rotation);
-	if (ret)
-		return ret;
-
-	drm_plane_enable_fb_damage_clips(&mipi->pipe.plane);
-
 	drm_mode_config_reset(drm);
 
 	ret = drm_dev_register(drm, 0);
@@ -400,9 +383,6 @@  static int st7586_probe(struct spi_device *spi)
 
 	spi_set_drvdata(spi, drm);
 
-	DRM_DEBUG_KMS("preferred_depth=%u, rotation = %u\n",
-		      drm->mode_config.preferred_depth, rotation);
-
 	drm_fbdev_generic_setup(drm, 0);
 
 	return 0;
diff --git a/include/drm/tinydrm/mipi-dbi.h b/include/drm/tinydrm/mipi-dbi.h
index 576e9a7349ab..2f0119e2c47e 100644
--- a/include/drm/tinydrm/mipi-dbi.h
+++ b/include/drm/tinydrm/mipi-dbi.h
@@ -67,6 +67,11 @@  static inline struct mipi_dbi *drm_to_mipi_dbi(struct drm_device *drm)
 	return container_of(drm, struct mipi_dbi, drm);
 }
 
+int mipi_dbi_init_with_formats(struct mipi_dbi *mipi,
+			       const struct drm_simple_display_pipe_funcs *funcs,
+			       const uint32_t *formats, unsigned int format_count,
+			       const struct drm_display_mode *mode,
+			       unsigned int rotation, size_t tx_buf_size);
 int mipi_dbi_init(struct mipi_dbi *mipi,
 		  const struct drm_simple_display_pipe_funcs *funcs,
 		  const struct drm_display_mode *mode, unsigned int rotation);