Merge tag 'dt-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux-2.6-microblaze.git] / drivers / gpu / drm / drm_mipi_dbi.c
index 43a9b73..71b646c 100644 (file)
@@ -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);