#include "vs_drv.h"
#include "vs_gem.h"
+#ifdef CONFIG_SIFIVE_FLUSH
+#include <soc/sifive/sifive_ccache.h>
+#endif
+
static const struct drm_gem_object_funcs vs_gem_default_funcs;
static int vs_gem_alloc_buf(struct vs_gem_object *vs_obj)
return ret;
}
+static int vs_gem_prime_end_cpu_access(struct dma_buf *buf,
+ enum dma_data_direction direction)
+{
+#ifdef CONFIG_SIFIVE_FLUSH
+ struct drm_gem_object *obj = buf->priv;
+ struct vs_gem_object *vs_obj = to_vs_gem_object(obj);
+
+ starfive_flush_dcache(vs_obj->dma_addr, vs_obj->size);
+#endif
+
+ return 0;
+}
+
+static struct dma_buf_ops vs_gem_prime_dmabuf_ops = {
+ .cache_sgt_mapping = true,
+ .attach = drm_gem_map_attach,
+ .detach = drm_gem_map_detach,
+ .map_dma_buf = drm_gem_map_dma_buf,
+ .unmap_dma_buf = drm_gem_unmap_dma_buf,
+ .release = drm_gem_dmabuf_release,
+ .mmap = drm_gem_dmabuf_mmap,
+ .vmap = drm_gem_dmabuf_vmap,
+ .vunmap = drm_gem_dmabuf_vunmap,
+ .end_cpu_access = vs_gem_prime_end_cpu_access,
+};
+
+static struct dma_buf *vs_gem_prime_export(struct drm_gem_object *obj, int flags)
+{
+ struct dma_buf *dmabuf;
+
+ dmabuf = drm_gem_prime_export(obj, flags);
+ if (!IS_ERR(dmabuf))
+ dmabuf->ops = &vs_gem_prime_dmabuf_ops;
+
+ return dmabuf;
+}
+
struct sg_table *vs_gem_prime_get_sg_table(struct drm_gem_object *obj)
{
struct vs_gem_object *vs_obj = to_vs_gem_object(obj);
static const struct drm_gem_object_funcs vs_gem_default_funcs = {
.free = vs_gem_free_object,
+ .export = vs_gem_prime_export,
.get_sg_table = vs_gem_prime_get_sg_table,
.vmap = vs_gem_prime_vmap,
.vunmap = vs_gem_prime_vunmap,
struct drm_gem_object *vs_gem_prime_import(struct drm_device *dev,
struct dma_buf *dma_buf)
{
+ struct drm_gem_object *obj;
+
+ if (dma_buf->ops == &vs_gem_prime_dmabuf_ops) {
+ obj = dma_buf->priv;
+ if (obj->dev == dev) {
+ drm_gem_object_get(obj);
+ return obj;
+ }
+ }
+
return drm_gem_prime_import_dev(dev, dma_buf, to_dma_dev(dev));
}