@@ -2,7 +2,7 @@ menuconfig DRM_TINYDRM
tristate "Support for simple displays"
depends on DRM
select DRM_KMS_HELPER
- select DRM_KMS_CMA_HELPER
+ select DRM_GEM_SHMEM_HELPER
help
Choose this option if you have a tinydrm supported display.
If M is selected the module will be called tinydrm.
@@ -12,6 +12,7 @@
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_gem_shmem_helper.h>
#include <drm/tinydrm/tinydrm.h>
#include <linux/device.h>
#include <linux/dma-buf.h>
@@ -23,7 +24,7 @@
*
* It is based on &drm_simple_display_pipe coupled with a &drm_connector which
* has only one fixed &drm_display_mode. The framebuffers are backed by the
- * cma helper and have support for framebuffer flushing (dirty).
+ * shmem buffers and have support for framebuffer flushing (dirty).
* fbdev support is also included.
*
*/
@@ -37,84 +38,41 @@
*/
/**
- * tinydrm_gem_cma_prime_import_sg_table - Produce a CMA GEM object from
- * another driver's scatter/gather table of pinned pages
- * @drm: DRM device to import into
- * @attach: DMA-BUF attachment
- * @sgt: Scatter/gather table of pinned pages
+ * tinydrm_fb_destroy - Destroy framebuffer
+ * @fb: Framebuffer
*
- * This function imports a scatter/gather table exported via DMA-BUF by
- * another driver using drm_gem_cma_prime_import_sg_table(). It sets the
- * kernel virtual address on the CMA object. Drivers should use this as their
- * &drm_driver->gem_prime_import_sg_table callback if they need the virtual
- * address. tinydrm_gem_cma_free_object() should be used in combination with
- * this function.
- *
- * Returns:
- * A pointer to a newly created GEM object or an ERR_PTR-encoded negative
- * error code on failure.
+ * This function unmaps the virtual address on the backing buffer and destroys the framebuffer.
+ * Drivers should use this as their &drm_framebuffer_funcs->destroy callback.
*/
-struct drm_gem_object *
-tinydrm_gem_cma_prime_import_sg_table(struct drm_device *drm,
- struct dma_buf_attachment *attach,
- struct sg_table *sgt)
+void tinydrm_fb_destroy(struct drm_framebuffer *fb)
{
- struct drm_gem_cma_object *cma_obj;
- struct drm_gem_object *obj;
- void *vaddr;
+ struct drm_gem_object *gem = drm_gem_fb_get_obj(fb, 0);
+ struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(gem);
- vaddr = dma_buf_vmap(attach->dmabuf);
- if (!vaddr) {
- DRM_ERROR("Failed to vmap PRIME buffer\n");
- return ERR_PTR(-ENOMEM);
- }
-
- obj = drm_gem_cma_prime_import_sg_table(drm, attach, sgt);
- if (IS_ERR(obj)) {
- dma_buf_vunmap(attach->dmabuf, vaddr);
- return obj;
- }
-
- cma_obj = to_drm_gem_cma_obj(obj);
- cma_obj->vaddr = vaddr;
-
- return obj;
+ drm_gem_vunmap(gem, shmem->vaddr);
+ drm_gem_fb_destroy(fb);
}
-EXPORT_SYMBOL(tinydrm_gem_cma_prime_import_sg_table);
-
-/**
- * tinydrm_gem_cma_free_object - Free resources associated with a CMA GEM
- * object
- * @gem_obj: GEM object to free
- *
- * This function frees the backing memory of the CMA GEM object, cleans up the
- * GEM object state and frees the memory used to store the object itself using
- * drm_gem_cma_free_object(). It also handles PRIME buffers which has the kernel
- * virtual address set by tinydrm_gem_cma_prime_import_sg_table(). Drivers
- * can use this as their &drm_driver->gem_free_object_unlocked callback.
- */
-void tinydrm_gem_cma_free_object(struct drm_gem_object *gem_obj)
-{
- if (gem_obj->import_attach) {
- struct drm_gem_cma_object *cma_obj;
-
- cma_obj = to_drm_gem_cma_obj(gem_obj);
- dma_buf_vunmap(gem_obj->import_attach->dmabuf, cma_obj->vaddr);
- cma_obj->vaddr = NULL;
- }
-
- drm_gem_cma_free_object(gem_obj);
-}
-EXPORT_SYMBOL_GPL(tinydrm_gem_cma_free_object);
+EXPORT_SYMBOL(tinydrm_fb_destroy);
static struct drm_framebuffer *
tinydrm_fb_create(struct drm_device *drm, struct drm_file *file_priv,
const struct drm_mode_fb_cmd2 *mode_cmd)
{
struct tinydrm_device *tdev = drm->dev_private;
+ struct drm_framebuffer *fb;
+ void *vaddr;
- return drm_gem_fb_create_with_funcs(drm, file_priv, mode_cmd,
- tdev->fb_funcs);
+ fb = drm_gem_fb_create_with_funcs(drm, file_priv, mode_cmd, tdev->fb_funcs);
+ if (IS_ERR(fb))
+ return fb;
+
+ vaddr = drm_gem_vmap(drm_gem_fb_get_obj(fb, 0));
+ if (IS_ERR(vaddr)) {
+ drm_gem_fb_destroy(fb);
+ return ERR_CAST(vaddr);
+ }
+
+ return fb;
}
static const struct drm_mode_config_funcs tinydrm_mode_config_funcs = {
@@ -9,12 +9,17 @@
#include <linux/backlight.h>
#include <linux/dma-buf.h>
+#include <linux/module.h>
#include <linux/pm.h>
#include <linux/spi/spi.h>
#include <linux/swab.h>
+#include <drm/drm_device.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_fourcc.h>
#include <drm/tinydrm/tinydrm.h>
#include <drm/tinydrm/tinydrm-helpers.h>
+#include <drm/drm_print.h>
static unsigned int spi_max;
module_param(spi_max, uint, 0400);
@@ -20,8 +20,11 @@
#include <linux/spi/spi.h>
#include <video/mipi_display.h>
+#include <drm/drm_drv.h>
#include <drm/drm_fb_helper.h>
+#include <drm/drm_fourcc.h>
#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_gem_shmem_helper.h>
#include <drm/tinydrm/mipi-dbi.h>
#include <drm/tinydrm/tinydrm-helpers.h>
@@ -77,7 +80,8 @@ static int ili9225_fb_dirty(struct drm_framebuffer *fb,
unsigned int color, struct drm_clip_rect *clips,
unsigned int num_clips)
{
- struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
+ struct drm_gem_object *gem = drm_gem_fb_get_obj(fb, 0);
+ struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(gem);
struct tinydrm_device *tdev = fb->dev->dev_private;
struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
bool swap = mipi->swap_bytes;
@@ -104,7 +108,7 @@ static int ili9225_fb_dirty(struct drm_framebuffer *fb,
if (ret)
return ret;
} else {
- tr = cma_obj->vaddr;
+ tr = shmem->vaddr;
}
switch (mipi->rotation) {
@@ -157,7 +161,7 @@ static int ili9225_fb_dirty(struct drm_framebuffer *fb,
}
static const struct drm_framebuffer_funcs ili9225_fb_funcs = {
- .destroy = drm_gem_fb_destroy,
+ .destroy = tinydrm_fb_destroy,
.create_handle = drm_gem_fb_create_handle,
.dirty = tinydrm_fb_dirty,
};
@@ -361,13 +365,13 @@ static const struct drm_display_mode ili9225_mode = {
TINYDRM_MODE(176, 220, 35, 44),
};
-DEFINE_DRM_GEM_CMA_FOPS(ili9225_fops);
+DEFINE_DRM_GEM_SHMEM_FOPS(ili9225_fops);
static struct drm_driver ili9225_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
DRIVER_ATOMIC,
.fops = &ili9225_fops,
- TINYDRM_GEM_DRIVER_OPS,
+ DRM_GEM_SHMEM_DRIVER_OPS,
.name = "ili9225",
.desc = "Ilitek ILI9225",
.date = "20171106",
@@ -15,8 +15,10 @@
#include <linux/property.h>
#include <linux/spi/spi.h>
+#include <drm/drm_drv.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_gem_shmem_helper.h>
#include <drm/drm_modeset_helper.h>
#include <drm/tinydrm/mipi-dbi.h>
#include <drm/tinydrm/tinydrm-helpers.h>
@@ -139,12 +141,12 @@ static const struct drm_display_mode yx240qv29_mode = {
TINYDRM_MODE(240, 320, 37, 49),
};
-DEFINE_DRM_GEM_CMA_FOPS(ili9341_fops);
+DEFINE_DRM_GEM_SHMEM_FOPS(ili9341_fops);
static struct drm_driver ili9341_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_ATOMIC,
.fops = &ili9341_fops,
- TINYDRM_GEM_DRIVER_OPS,
+ DRM_GEM_SHMEM_DRIVER_OPS,
.debugfs_init = mipi_dbi_debugfs_init,
.name = "ili9341",
.desc = "Ilitek ILI9341",
@@ -17,9 +17,11 @@
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
+#include <drm/drm_drv.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_modeset_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_gem_shmem_helper.h>
#include <drm/tinydrm/mipi-dbi.h>
#include <drm/tinydrm/tinydrm-helpers.h>
#include <video/mipi_display.h>
@@ -147,13 +149,13 @@ static const struct drm_display_mode mi0283qt_mode = {
TINYDRM_MODE(320, 240, 58, 43),
};
-DEFINE_DRM_GEM_CMA_FOPS(mi0283qt_fops);
+DEFINE_DRM_GEM_SHMEM_FOPS(mi0283qt_fops);
static struct drm_driver mi0283qt_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
DRIVER_ATOMIC,
.fops = &mi0283qt_fops,
- TINYDRM_GEM_DRIVER_OPS,
+ DRM_GEM_SHMEM_DRIVER_OPS,
.debugfs_init = mipi_dbi_debugfs_init,
.name = "mi0283qt",
.desc = "Multi-Inno MI0283QT",
@@ -9,10 +9,15 @@
* (at your option) any later version.
*/
+#include <drm/drm_device.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_fourcc.h>
#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_gem_shmem_helper.h>
#include <drm/tinydrm/mipi-dbi.h>
#include <drm/tinydrm/tinydrm-helpers.h>
#include <linux/debugfs.h>
+#include <linux/delay.h>
#include <linux/dma-buf.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
@@ -167,10 +172,11 @@ EXPORT_SYMBOL(mipi_dbi_command_buf);
int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb,
struct drm_clip_rect *clip, bool swap)
{
- struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
- struct dma_buf_attachment *import_attach = cma_obj->base.import_attach;
+ struct drm_gem_object *gem = drm_gem_fb_get_obj(fb, 0);
+ struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(gem);
+ struct dma_buf_attachment *import_attach = gem->import_attach;
struct drm_format_name_buf format_name;
- void *src = cma_obj->vaddr;
+ void *src = shmem->vaddr;
int ret = 0;
if (import_attach) {
@@ -210,7 +216,8 @@ static int mipi_dbi_fb_dirty(struct drm_framebuffer *fb,
struct drm_clip_rect *clips,
unsigned int num_clips)
{
- struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
+ struct drm_gem_object *gem = drm_gem_fb_get_obj(fb, 0);
+ struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(gem);
struct tinydrm_device *tdev = fb->dev->dev_private;
struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
bool swap = mipi->swap_bytes;
@@ -235,7 +242,7 @@ static int mipi_dbi_fb_dirty(struct drm_framebuffer *fb,
if (ret)
return ret;
} else {
- tr = cma_obj->vaddr;
+ tr = shmem->vaddr;
}
mipi_dbi_command(mipi, MIPI_DCS_SET_COLUMN_ADDRESS,
@@ -252,7 +259,7 @@ static int mipi_dbi_fb_dirty(struct drm_framebuffer *fb,
}
static const struct drm_framebuffer_funcs mipi_dbi_fb_funcs = {
- .destroy = drm_gem_fb_destroy,
+ .destroy = tinydrm_fb_destroy,
.create_handle = drm_gem_fb_create_handle,
.dirty = tinydrm_fb_dirty,
};
@@ -882,31 +889,12 @@ int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *mipi,
{
size_t tx_size = tinydrm_spi_max_transfer_size(spi, 0);
struct device *dev = &spi->dev;
- int ret;
if (tx_size < 16) {
DRM_ERROR("SPI transmit buffer too small: %zu\n", tx_size);
return -EINVAL;
}
- /*
- * Even though it's not the SPI device that does DMA (the master does),
- * the dma mask is necessary for the dma_alloc_wc() in
- * drm_gem_cma_create(). The dma_addr returned will be a physical
- * adddress which might be different from the bus address, but this is
- * not a problem since the address will not be used.
- * The virtual address is used in the transfer and the SPI core
- * re-maps it on the SPI master device using the DMA streaming API
- * (spi_map_buf()).
- */
- if (!dev->coherent_dma_mask) {
- ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
- if (ret) {
- dev_warn(dev, "Failed to set dma mask %d\n", ret);
- return ret;
- }
- }
-
mipi->spi = spi;
mipi->read_commands = mipi_dbi_dcs_read_commands;
@@ -26,7 +26,9 @@
#include <linux/spi/spi.h>
#include <linux/thermal.h>
+#include <drm/drm_drv.h>
#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_gem_shmem_helper.h>
#include <drm/tinydrm/tinydrm.h>
#include <drm/tinydrm/tinydrm-helpers.h>
@@ -526,8 +528,9 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb,
struct drm_clip_rect *clips,
unsigned int num_clips)
{
- struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
- struct dma_buf_attachment *import_attach = cma_obj->base.import_attach;
+ struct drm_gem_object *gem = drm_gem_fb_get_obj(fb, 0);
+ struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(gem);
+ struct dma_buf_attachment *import_attach = gem->import_attach;
struct tinydrm_device *tdev = fb->dev->dev_private;
struct repaper_epd *epd = epd_from_tinydrm(tdev);
struct drm_clip_rect clip;
@@ -559,7 +562,7 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb,
goto out_free;
}
- tinydrm_xrgb8888_to_gray8(buf, cma_obj->vaddr, fb, &clip);
+ tinydrm_xrgb8888_to_gray8(buf, shmem->vaddr, fb, &clip);
if (import_attach) {
ret = dma_buf_end_cpu_access(import_attach->dmabuf,
@@ -624,7 +627,7 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb,
}
static const struct drm_framebuffer_funcs repaper_fb_funcs = {
- .destroy = drm_gem_fb_destroy,
+ .destroy = tinydrm_fb_destroy,
.create_handle = drm_gem_fb_create_handle,
.dirty = tinydrm_fb_dirty,
};
@@ -876,13 +879,13 @@ static const struct drm_display_mode repaper_e2271cs021_mode = {
static const u8 repaper_e2271cs021_cs[] = { 0x00, 0x00, 0x00, 0x7f,
0xff, 0xfe, 0x00, 0x00 };
-DEFINE_DRM_GEM_CMA_FOPS(repaper_fops);
+DEFINE_DRM_GEM_SHMEM_FOPS(repaper_fops);
static struct drm_driver repaper_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
DRIVER_ATOMIC,
.fops = &repaper_fops,
- TINYDRM_GEM_DRIVER_OPS,
+ DRM_GEM_SHMEM_DRIVER_OPS,
.name = "repaper",
.desc = "Pervasive Displays RePaper e-ink panels",
.date = "20170405",
@@ -929,15 +932,6 @@ static int repaper_probe(struct spi_device *spi)
model = spi_id->driver_data;
}
- /* The SPI device is used to allocate dma memory */
- if (!dev->coherent_dma_mask) {
- ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
- if (ret) {
- dev_warn(dev, "Failed to set dma mask %d\n", ret);
- return ret;
- }
- }
-
epd = devm_kzalloc(dev, sizeof(*epd), GFP_KERNEL);
if (!epd)
return -ENOMEM;
@@ -17,8 +17,10 @@
#include <linux/spi/spi.h>
#include <video/mipi_display.h>
+#include <drm/drm_drv.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_gem_shmem_helper.h>
#include <drm/tinydrm/mipi-dbi.h>
#include <drm/tinydrm/tinydrm-helpers.h>
@@ -88,9 +90,10 @@ static void st7586_xrgb8888_to_gray332(u8 *dst, void *vaddr,
static int st7586_buf_copy(void *dst, struct drm_framebuffer *fb,
struct drm_clip_rect *clip)
{
- struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
- struct dma_buf_attachment *import_attach = cma_obj->base.import_attach;
- void *src = cma_obj->vaddr;
+ struct drm_gem_object *gem = drm_gem_fb_get_obj(fb, 0);
+ struct dma_buf_attachment *import_attach = gem->import_attach;
+ struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(gem);
+ void *src = shmem->vaddr;
int ret = 0;
if (import_attach) {
@@ -156,7 +159,7 @@ static int st7586_fb_dirty(struct drm_framebuffer *fb,
}
static const struct drm_framebuffer_funcs st7586_fb_funcs = {
- .destroy = drm_gem_fb_destroy,
+ .destroy = tinydrm_fb_destroy,
.create_handle = drm_gem_fb_create_handle,
.dirty = tinydrm_fb_dirty,
};
@@ -297,13 +300,13 @@ static const struct drm_display_mode st7586_mode = {
TINYDRM_MODE(178, 128, 37, 27),
};
-DEFINE_DRM_GEM_CMA_FOPS(st7586_fops);
+DEFINE_DRM_GEM_SHMEM_FOPS(st7586_fops);
static struct drm_driver st7586_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
DRIVER_ATOMIC,
.fops = &st7586_fops,
- TINYDRM_GEM_DRIVER_OPS,
+ DRM_GEM_SHMEM_DRIVER_OPS,
.debugfs_init = mipi_dbi_debugfs_init,
.name = "st7586",
.desc = "Sitronix ST7586",
@@ -14,8 +14,10 @@
#include <linux/spi/spi.h>
#include <video/mipi_display.h>
+#include <drm/drm_drv.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_gem_shmem_helper.h>
#include <drm/tinydrm/mipi-dbi.h>
#include <drm/tinydrm/tinydrm-helpers.h>
@@ -113,13 +115,13 @@ static const struct drm_display_mode jd_t18003_t01_mode = {
TINYDRM_MODE(128, 160, 28, 35),
};
-DEFINE_DRM_GEM_CMA_FOPS(st7735r_fops);
+DEFINE_DRM_GEM_SHMEM_FOPS(st7735r_fops);
static struct drm_driver st7735r_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
DRIVER_ATOMIC,
.fops = &st7735r_fops,
- TINYDRM_GEM_DRIVER_OPS,
+ DRM_GEM_SHMEM_DRIVER_OPS,
.debugfs_init = mipi_dbi_debugfs_init,
.name = "st7735r",
.desc = "Sitronix ST7735R",
@@ -10,10 +10,15 @@
#ifndef __LINUX_TINYDRM_H
#define __LINUX_TINYDRM_H
-#include <drm/drm_gem_cma_helper.h>
-#include <drm/drm_fb_cma_helper.h>
+#include <linux/mutex.h>
#include <drm/drm_simple_kms_helper.h>
+struct drm_driver;
+struct drm_framebuffer;
+struct drm_file;
+struct drm_clip_rect;
+struct drm_framebuffer_funcs;
+
/**
* struct tinydrm_device - tinydrm device
*/
@@ -53,27 +58,6 @@ pipe_to_tinydrm(struct drm_simple_display_pipe *pipe)
return container_of(pipe, struct tinydrm_device, pipe);
}
-/**
- * TINYDRM_GEM_DRIVER_OPS - default tinydrm gem operations
- *
- * This macro provides a shortcut for setting the tinydrm GEM operations in
- * the &drm_driver structure.
- */
-#define TINYDRM_GEM_DRIVER_OPS \
- .gem_free_object_unlocked = tinydrm_gem_cma_free_object, \
- .gem_print_info = drm_gem_cma_print_info, \
- .gem_vm_ops = &drm_gem_cma_vm_ops, \
- .prime_handle_to_fd = drm_gem_prime_handle_to_fd, \
- .prime_fd_to_handle = drm_gem_prime_fd_to_handle, \
- .gem_prime_import = drm_gem_prime_import, \
- .gem_prime_export = drm_gem_prime_export, \
- .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, \
- .gem_prime_import_sg_table = tinydrm_gem_cma_prime_import_sg_table, \
- .gem_prime_vmap = drm_gem_cma_prime_vmap, \
- .gem_prime_vunmap = drm_gem_cma_prime_vunmap, \
- .gem_prime_mmap = drm_gem_cma_prime_mmap, \
- .dumb_create = drm_gem_cma_dumb_create
-
/**
* TINYDRM_MODE - tinydrm display mode
* @hd: Horizontal resolution, width
@@ -97,11 +81,7 @@ pipe_to_tinydrm(struct drm_simple_display_pipe *pipe)
.type = DRM_MODE_TYPE_DRIVER, \
.clock = 1 /* pass validation */
-void tinydrm_gem_cma_free_object(struct drm_gem_object *gem_obj);
-struct drm_gem_object *
-tinydrm_gem_cma_prime_import_sg_table(struct drm_device *drm,
- struct dma_buf_attachment *attach,
- struct sg_table *sgt);
+void tinydrm_fb_destroy(struct drm_framebuffer *fb);
int devm_tinydrm_init(struct device *parent, struct tinydrm_device *tdev,
const struct drm_framebuffer_funcs *fb_funcs,
struct drm_driver *driver);