Commit cc431212 authored by Noralf Trønnes's avatar Noralf Trønnes
Browse files

drm/tinydrm/mipi-dbi: Add mipi_dbi_init_with_formats()



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.

v2: Forgot to remove the mipi->rotation assignment in st7586,
    mipi_dbi_init_with_formats() handles it.

Cc: David Lechner <david@lechnology.com>
Acked-by: default avatarDavid Lechner <david@lechnology.com>
Signed-off-by: default avatarNoralf Trønnes <noralf@tronnes.org>
Tested-by: default avatarDavid Lechner <david@lechnology.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190719155916.62465-11-noralf@tronnes.org
parent 1321db83
Loading
Loading
Loading
Loading
+48 −13
Original line number Diff line number Diff line
@@ -412,27 +412,34 @@ static const uint32_t mipi_dbi_formats[] = {
};

/**
 * mipi_dbi_init - MIPI DBI initialization
 * 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.
 * Additionally &mipi_dbi.tx_buf is allocated.
 *
 * Supported formats: Native RGB565 and emulated XRGB8888.
 * 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(struct mipi_dbi *mipi,
int mipi_dbi_init_with_formats(struct mipi_dbi *mipi,
			       const struct drm_simple_display_pipe_funcs *funcs,
		  const struct drm_display_mode *mode, unsigned int rotation)
			       const uint32_t *formats, unsigned int format_count,
			       const struct drm_display_mode *mode,
			       unsigned int rotation, size_t tx_buf_size)
{
	size_t bufsize = mode->vdisplay * mode->hdisplay * sizeof(u16);
	struct drm_device *drm = &mipi->drm;
	int ret;

@@ -441,14 +448,13 @@ int mipi_dbi_init(struct mipi_dbi *mipi,

	mutex_init(&mipi->cmdlock);

	mipi->tx_buf = devm_kmalloc(drm->dev, bufsize, GFP_KERNEL);
	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,
					mipi_dbi_formats,
					ARRAY_SIZE(mipi_dbi_formats), mode,
					formats, format_count, mode,
					rotation);
	if (ret)
		return ret;
@@ -456,14 +462,43 @@ int mipi_dbi_init(struct mipi_dbi *mipi,
	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);
	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
 * @funcs: Display pipe functions
 * @mode: Display mode
 * @rotation: Initial rotation in degrees Counter Clock Wise
 *
 * 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.
 * Additionally &mipi_dbi.tx_buf is allocated.
 *
 * Supported formats: Native RGB565 and emulated XRGB8888.
 *
 * Returns:
 * Zero on success, negative error code on failure.
 */
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)
{
	size_t bufsize = mode->vdisplay * mode->hdisplay * sizeof(u16);

	mipi->drm.mode_config.preferred_depth = 16;

	return mipi_dbi_init_with_formats(mipi, funcs, mipi_dbi_formats,
					  ARRAY_SIZE(mipi_dbi_formats), mode,
					  rotation, bufsize);
}
EXPORT_SYMBOL(mipi_dbi_init);

/**
+6 −27
Original line number Diff line number Diff line
@@ -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)) {
@@ -365,7 +351,6 @@ static int st7586_probe(struct spi_device *spi)
	}

	device_property_read_u32(dev, "rotation", &rotation);
	mipi->rotation = rotation;

	ret = mipi_dbi_spi_init(spi, mipi, a0);
	if (ret)
@@ -374,6 +359,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 +374,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 +382,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;
+5 −0
Original line number Diff line number Diff line
@@ -69,6 +69,11 @@ static inline struct mipi_dbi *drm_to_mipi_dbi(struct drm_device *drm)

int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *mipi,
		      struct gpio_desc *dc);
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);