1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/
4 * Author: Rob Clark <rob.clark@linaro.org>
7 #include <linux/dma-buf.h>
8 #include <linux/highmem.h>
10 #include <drm/drm_prime.h>
14 MODULE_IMPORT_NS("DMA_BUF");
16 /* -----------------------------------------------------------------------------
20 static struct sg_table
*omap_gem_map_dma_buf(
21 struct dma_buf_attachment
*attachment
,
22 enum dma_data_direction dir
)
24 struct drm_gem_object
*obj
= attachment
->dmabuf
->priv
;
26 sg
= omap_gem_get_sg(obj
, dir
);
33 static void omap_gem_unmap_dma_buf(struct dma_buf_attachment
*attachment
,
34 struct sg_table
*sg
, enum dma_data_direction dir
)
36 struct drm_gem_object
*obj
= attachment
->dmabuf
->priv
;
37 omap_gem_put_sg(obj
, sg
);
40 static int omap_gem_dmabuf_begin_cpu_access(struct dma_buf
*buffer
,
41 enum dma_data_direction dir
)
43 struct drm_gem_object
*obj
= buffer
->priv
;
45 if (omap_gem_flags(obj
) & OMAP_BO_TILED_MASK
) {
46 /* TODO we would need to pin at least part of the buffer to
47 * get de-tiled view. For now just reject it.
51 /* make sure we have the pages: */
52 return omap_gem_get_pages(obj
, &pages
, true);
55 static int omap_gem_dmabuf_end_cpu_access(struct dma_buf
*buffer
,
56 enum dma_data_direction dir
)
58 struct drm_gem_object
*obj
= buffer
->priv
;
59 omap_gem_put_pages(obj
);
63 static int omap_gem_dmabuf_mmap(struct dma_buf
*buffer
,
64 struct vm_area_struct
*vma
)
66 struct drm_gem_object
*obj
= buffer
->priv
;
68 return drm_gem_mmap_obj(obj
, omap_gem_mmap_size(obj
), vma
);
71 static const struct dma_buf_ops omap_dmabuf_ops
= {
72 .map_dma_buf
= omap_gem_map_dma_buf
,
73 .unmap_dma_buf
= omap_gem_unmap_dma_buf
,
74 .release
= drm_gem_dmabuf_release
,
75 .begin_cpu_access
= omap_gem_dmabuf_begin_cpu_access
,
76 .end_cpu_access
= omap_gem_dmabuf_end_cpu_access
,
77 .mmap
= omap_gem_dmabuf_mmap
,
80 struct dma_buf
*omap_gem_prime_export(struct drm_gem_object
*obj
, int flags
)
82 DEFINE_DMA_BUF_EXPORT_INFO(exp_info
);
84 exp_info
.ops
= &omap_dmabuf_ops
;
85 exp_info
.size
= omap_gem_mmap_size(obj
);
86 exp_info
.flags
= flags
;
88 exp_info
.resv
= obj
->resv
;
90 return drm_gem_dmabuf_export(obj
->dev
, &exp_info
);
93 /* -----------------------------------------------------------------------------
97 struct drm_gem_object
*omap_gem_prime_import(struct drm_device
*dev
,
98 struct dma_buf
*dma_buf
)
100 struct dma_buf_attachment
*attach
;
101 struct drm_gem_object
*obj
;
102 struct sg_table
*sgt
;
105 if (dma_buf
->ops
== &omap_dmabuf_ops
) {
107 if (obj
->dev
== dev
) {
109 * Importing dmabuf exported from out own gem increases
110 * refcount on gem itself instead of f_count of dmabuf.
112 drm_gem_object_get(obj
);
117 attach
= dma_buf_attach(dma_buf
, dev
->dev
);
119 return ERR_CAST(attach
);
121 get_dma_buf(dma_buf
);
123 sgt
= dma_buf_map_attachment_unlocked(attach
, DMA_TO_DEVICE
);
129 obj
= omap_gem_new_dmabuf(dev
, dma_buf
->size
, sgt
);
135 obj
->import_attach
= attach
;
140 dma_buf_unmap_attachment_unlocked(attach
, sgt
, DMA_TO_DEVICE
);
142 dma_buf_detach(dma_buf
, attach
);
143 dma_buf_put(dma_buf
);