aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_mipi_dbi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_mipi_dbi.c')
-rw-r--r--drivers/gpu/drm/drm_mipi_dbi.c75
1 files changed, 61 insertions, 14 deletions
diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
index 43a9b739bba7..71b646c4131f 100644
--- a/drivers/gpu/drm/drm_mipi_dbi.c
+++ b/drivers/gpu/drm/drm_mipi_dbi.c
@@ -7,7 +7,6 @@
#include <linux/debugfs.h>
#include <linux/delay.h>
-#include <linux/dma-buf.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/regulator/consumer.h>
@@ -202,21 +201,17 @@ int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb,
{
struct drm_gem_object *gem = drm_gem_fb_get_obj(fb, 0);
struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(gem);
- struct dma_buf_attachment *import_attach = gem->import_attach;
void *src = cma_obj->vaddr;
- int ret = 0;
+ int ret;
- if (import_attach) {
- ret = dma_buf_begin_cpu_access(import_attach->dmabuf,
- DMA_FROM_DEVICE);
- if (ret)
- return ret;
- }
+ ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
+ if (ret)
+ return ret;
switch (fb->format->format) {
case DRM_FORMAT_RGB565:
if (swap)
- drm_fb_swab(dst, src, fb, clip, !import_attach);
+ drm_fb_swab(dst, src, fb, clip, !gem->import_attach);
else
drm_fb_memcpy(dst, src, fb, clip);
break;
@@ -229,9 +224,8 @@ int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb,
return -EINVAL;
}
- if (import_attach)
- ret = dma_buf_end_cpu_access(import_attach->dmabuf,
- DMA_FROM_DEVICE);
+ drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
+
return ret;
}
EXPORT_SYMBOL(mipi_dbi_buf_copy);
@@ -928,6 +922,59 @@ static int mipi_dbi_spi1_transfer(struct mipi_dbi *dbi, int dc,
return 0;
}
+static int mipi_dbi_typec1_command_read(struct mipi_dbi *dbi, u8 *cmd,
+ u8 *data, size_t len)
+{
+ struct spi_device *spi = dbi->spi;
+ u32 speed_hz = min_t(u32, MIPI_DBI_MAX_SPI_READ_SPEED,
+ spi->max_speed_hz / 2);
+ struct spi_transfer tr[2] = {
+ {
+ .speed_hz = speed_hz,
+ .bits_per_word = 9,
+ .tx_buf = dbi->tx_buf9,
+ .len = 2,
+ }, {
+ .speed_hz = speed_hz,
+ .bits_per_word = 8,
+ .len = len,
+ .rx_buf = data,
+ },
+ };
+ struct spi_message m;
+ u16 *dst16;
+ int ret;
+
+ if (!len)
+ return -EINVAL;
+
+ if (!spi_is_bpw_supported(spi, 9)) {
+ /*
+ * FIXME: implement something like mipi_dbi_spi1e_transfer() but
+ * for reads using emulation.
+ */
+ dev_err(&spi->dev,
+ "reading on host not supporting 9 bpw not yet implemented\n");
+ return -EOPNOTSUPP;
+ }
+
+ /*
+ * Turn the 8bit command into a 16bit version of the command in the
+ * buffer. Only 9 bits of this will be used when executing the actual
+ * transfer.
+ */
+ dst16 = dbi->tx_buf9;
+ dst16[0] = *cmd;
+
+ spi_message_init_with_transfers(&m, tr, ARRAY_SIZE(tr));
+ ret = spi_sync(spi, &m);
+
+ if (!ret)
+ MIPI_DBI_DEBUG_COMMAND(*cmd, data, len);
+
+ return ret;
+}
+
static int mipi_dbi_typec1_command(struct mipi_dbi *dbi, u8 *cmd,
u8 *parameters, size_t num)
{
@@ -935,7 +982,7 @@ static int mipi_dbi_typec1_command(struct mipi_dbi *dbi, u8 *cmd,
int ret;
if (mipi_dbi_command_is_read(dbi, *cmd))
- return -EOPNOTSUPP;
+ return mipi_dbi_typec1_command_read(dbi, cmd, parameters, num);
MIPI_DBI_DEBUG_COMMAND(*cmd, parameters, num);