18665870eSFrançois Tigeot /*
28665870eSFrançois Tigeot * Copyright 2012 Red Hat Inc
38665870eSFrançois Tigeot *
48665870eSFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a
58665870eSFrançois Tigeot * copy of this software and associated documentation files (the "Software"),
68665870eSFrançois Tigeot * to deal in the Software without restriction, including without limitation
78665870eSFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense,
88665870eSFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the
98665870eSFrançois Tigeot * Software is furnished to do so, subject to the following conditions:
108665870eSFrançois Tigeot *
118665870eSFrançois Tigeot * The above copyright notice and this permission notice (including the next
128665870eSFrançois Tigeot * paragraph) shall be included in all copies or substantial portions of the
138665870eSFrançois Tigeot * Software.
148665870eSFrançois Tigeot *
158665870eSFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
168665870eSFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
178665870eSFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
188665870eSFrançois Tigeot * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
198665870eSFrançois Tigeot * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
208665870eSFrançois Tigeot * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
218665870eSFrançois Tigeot * DEALINGS IN THE SOFTWARE.
228665870eSFrançois Tigeot *
238665870eSFrançois Tigeot * Authors:
248665870eSFrançois Tigeot * Dave Airlie <airlied@redhat.com>
258665870eSFrançois Tigeot */
2671f41f3eSFrançois Tigeot
278665870eSFrançois Tigeot #include <linux/dma-buf.h>
2871f41f3eSFrançois Tigeot #include <linux/reservation.h>
2971f41f3eSFrançois Tigeot
3071f41f3eSFrançois Tigeot #include <drm/drmP.h>
3171f41f3eSFrançois Tigeot
3271f41f3eSFrançois Tigeot #include "i915_drv.h"
338665870eSFrançois Tigeot
dma_buf_to_obj(struct dma_buf * buf)348665870eSFrançois Tigeot static struct drm_i915_gem_object *dma_buf_to_obj(struct dma_buf *buf)
358665870eSFrançois Tigeot {
368665870eSFrançois Tigeot return to_intel_bo(buf->priv);
378665870eSFrançois Tigeot }
388665870eSFrançois Tigeot
i915_gem_map_dma_buf(struct dma_buf_attachment * attachment,enum dma_data_direction dir)398665870eSFrançois Tigeot static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachment,
408665870eSFrançois Tigeot enum dma_data_direction dir)
418665870eSFrançois Tigeot {
428665870eSFrançois Tigeot struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf);
438665870eSFrançois Tigeot struct sg_table *st;
448665870eSFrançois Tigeot struct scatterlist *src, *dst;
458665870eSFrançois Tigeot int ret, i;
468665870eSFrançois Tigeot
474be47400SFrançois Tigeot ret = i915_gem_object_pin_pages(obj);
488665870eSFrançois Tigeot if (ret)
498665870eSFrançois Tigeot goto err;
508665870eSFrançois Tigeot
518665870eSFrançois Tigeot /* Copy sg so that we make an independent mapping */
521487f786SFrançois Tigeot st = kmalloc(sizeof(struct sg_table), M_DRM, GFP_KERNEL);
538665870eSFrançois Tigeot if (st == NULL) {
548665870eSFrançois Tigeot ret = -ENOMEM;
554be47400SFrançois Tigeot goto err_unpin_pages;
568665870eSFrançois Tigeot }
578665870eSFrançois Tigeot
584be47400SFrançois Tigeot ret = sg_alloc_table(st, obj->mm.pages->nents, GFP_KERNEL);
598665870eSFrançois Tigeot if (ret)
608665870eSFrançois Tigeot goto err_free;
618665870eSFrançois Tigeot
624be47400SFrançois Tigeot src = obj->mm.pages->sgl;
638665870eSFrançois Tigeot dst = st->sgl;
644be47400SFrançois Tigeot for (i = 0; i < obj->mm.pages->nents; i++) {
658665870eSFrançois Tigeot sg_set_page(dst, sg_page(src), src->length, 0);
668665870eSFrançois Tigeot dst = sg_next(dst);
678665870eSFrançois Tigeot src = sg_next(src);
688665870eSFrançois Tigeot }
698665870eSFrançois Tigeot
708665870eSFrançois Tigeot if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) {
718665870eSFrançois Tigeot ret = -ENOMEM;
728665870eSFrançois Tigeot goto err_free_sg;
738665870eSFrançois Tigeot }
748665870eSFrançois Tigeot
758665870eSFrançois Tigeot return st;
768665870eSFrançois Tigeot
778665870eSFrançois Tigeot err_free_sg:
788665870eSFrançois Tigeot sg_free_table(st);
798665870eSFrançois Tigeot err_free:
808665870eSFrançois Tigeot kfree(st);
814be47400SFrançois Tigeot err_unpin_pages:
828665870eSFrançois Tigeot i915_gem_object_unpin_pages(obj);
838665870eSFrançois Tigeot err:
848665870eSFrançois Tigeot return ERR_PTR(ret);
858665870eSFrançois Tigeot }
868665870eSFrançois Tigeot
i915_gem_unmap_dma_buf(struct dma_buf_attachment * attachment,struct sg_table * sg,enum dma_data_direction dir)878665870eSFrançois Tigeot static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment,
888665870eSFrançois Tigeot struct sg_table *sg,
898665870eSFrançois Tigeot enum dma_data_direction dir)
908665870eSFrançois Tigeot {
918665870eSFrançois Tigeot struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf);
928665870eSFrançois Tigeot
938665870eSFrançois Tigeot dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, dir);
948665870eSFrançois Tigeot sg_free_table(sg);
958665870eSFrançois Tigeot kfree(sg);
968665870eSFrançois Tigeot
978665870eSFrançois Tigeot i915_gem_object_unpin_pages(obj);
988665870eSFrançois Tigeot }
998665870eSFrançois Tigeot
i915_gem_dmabuf_vmap(struct dma_buf * dma_buf)1008665870eSFrançois Tigeot static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
1018665870eSFrançois Tigeot {
1028665870eSFrançois Tigeot struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
1038665870eSFrançois Tigeot
1044be47400SFrançois Tigeot return i915_gem_object_pin_map(obj, I915_MAP_WB);
1058665870eSFrançois Tigeot }
1068665870eSFrançois Tigeot
i915_gem_dmabuf_vunmap(struct dma_buf * dma_buf,void * vaddr)1078665870eSFrançois Tigeot static void i915_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
1088665870eSFrançois Tigeot {
1098665870eSFrançois Tigeot struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
1108665870eSFrançois Tigeot
1118665870eSFrançois Tigeot i915_gem_object_unpin_map(obj);
1128665870eSFrançois Tigeot }
1138665870eSFrançois Tigeot
i915_gem_dmabuf_kmap_atomic(struct dma_buf * dma_buf,unsigned long page_num)1148665870eSFrançois Tigeot static void *i915_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf, unsigned long page_num)
1158665870eSFrançois Tigeot {
1168665870eSFrançois Tigeot return NULL;
1178665870eSFrançois Tigeot }
1188665870eSFrançois Tigeot
i915_gem_dmabuf_kunmap_atomic(struct dma_buf * dma_buf,unsigned long page_num,void * addr)1198665870eSFrançois Tigeot static void i915_gem_dmabuf_kunmap_atomic(struct dma_buf *dma_buf, unsigned long page_num, void *addr)
1208665870eSFrançois Tigeot {
1218665870eSFrançois Tigeot
1228665870eSFrançois Tigeot }
i915_gem_dmabuf_kmap(struct dma_buf * dma_buf,unsigned long page_num)1238665870eSFrançois Tigeot static void *i915_gem_dmabuf_kmap(struct dma_buf *dma_buf, unsigned long page_num)
1248665870eSFrançois Tigeot {
125*3f2dd94aSFrançois Tigeot struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
126*3f2dd94aSFrançois Tigeot struct page *page;
127*3f2dd94aSFrançois Tigeot
128*3f2dd94aSFrançois Tigeot if (page_num >= obj->base.size >> PAGE_SHIFT)
129*3f2dd94aSFrançois Tigeot return NULL;
130*3f2dd94aSFrançois Tigeot
131*3f2dd94aSFrançois Tigeot if (!i915_gem_object_has_struct_page(obj))
132*3f2dd94aSFrançois Tigeot return NULL;
133*3f2dd94aSFrançois Tigeot
134*3f2dd94aSFrançois Tigeot if (i915_gem_object_pin_pages(obj))
135*3f2dd94aSFrançois Tigeot return NULL;
136*3f2dd94aSFrançois Tigeot
137*3f2dd94aSFrançois Tigeot /* Synchronisation is left to the caller (via .begin_cpu_access()) */
138*3f2dd94aSFrançois Tigeot page = i915_gem_object_get_page(obj, page_num);
139*3f2dd94aSFrançois Tigeot if (IS_ERR(page))
140*3f2dd94aSFrançois Tigeot goto err_unpin;
141*3f2dd94aSFrançois Tigeot
142*3f2dd94aSFrançois Tigeot return kmap(page);
143*3f2dd94aSFrançois Tigeot
144*3f2dd94aSFrançois Tigeot err_unpin:
145*3f2dd94aSFrançois Tigeot i915_gem_object_unpin_pages(obj);
1468665870eSFrançois Tigeot return NULL;
1478665870eSFrançois Tigeot }
1488665870eSFrançois Tigeot
i915_gem_dmabuf_kunmap(struct dma_buf * dma_buf,unsigned long page_num,void * addr)1498665870eSFrançois Tigeot static void i915_gem_dmabuf_kunmap(struct dma_buf *dma_buf, unsigned long page_num, void *addr)
1508665870eSFrançois Tigeot {
151*3f2dd94aSFrançois Tigeot struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
1528665870eSFrançois Tigeot
153*3f2dd94aSFrançois Tigeot kunmap(virt_to_page(addr));
154*3f2dd94aSFrançois Tigeot i915_gem_object_unpin_pages(obj);
1558665870eSFrançois Tigeot }
1568665870eSFrançois Tigeot
i915_gem_dmabuf_mmap(struct dma_buf * dma_buf,struct vm_area_struct * vma)1578665870eSFrançois Tigeot static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
1588665870eSFrançois Tigeot {
1598665870eSFrançois Tigeot struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
1608665870eSFrançois Tigeot #if 0
1618665870eSFrançois Tigeot int ret;
1628665870eSFrançois Tigeot #endif
1638665870eSFrançois Tigeot
1648665870eSFrançois Tigeot if (obj->base.size < vma->vm_end - vma->vm_start)
1658665870eSFrançois Tigeot return -EINVAL;
1668665870eSFrançois Tigeot
1678665870eSFrançois Tigeot if (!obj->base.filp)
1688665870eSFrançois Tigeot return -ENODEV;
1698665870eSFrançois Tigeot
1708665870eSFrançois Tigeot #if 0
1718665870eSFrançois Tigeot ret = obj->base.filp->f_op->mmap(obj->base.filp, vma);
1728665870eSFrançois Tigeot if (ret)
1738665870eSFrançois Tigeot return ret;
1748665870eSFrançois Tigeot
1758665870eSFrançois Tigeot fput(vma->vm_file);
1768665870eSFrançois Tigeot vma->vm_file = get_file(obj->base.filp);
1778665870eSFrançois Tigeot #endif
1788665870eSFrançois Tigeot
1798665870eSFrançois Tigeot return 0;
1808665870eSFrançois Tigeot }
1818665870eSFrançois Tigeot
i915_gem_begin_cpu_access(struct dma_buf * dma_buf,enum dma_data_direction direction)1828665870eSFrançois Tigeot static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction)
1838665870eSFrançois Tigeot {
1848665870eSFrançois Tigeot struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
1858665870eSFrançois Tigeot struct drm_device *dev = obj->base.dev;
1868665870eSFrançois Tigeot bool write = (direction == DMA_BIDIRECTIONAL || direction == DMA_TO_DEVICE);
1874be47400SFrançois Tigeot int err;
1888665870eSFrançois Tigeot
1894be47400SFrançois Tigeot err = i915_gem_object_pin_pages(obj);
1904be47400SFrançois Tigeot if (err)
1914be47400SFrançois Tigeot return err;
1928665870eSFrançois Tigeot
1934be47400SFrançois Tigeot err = i915_mutex_lock_interruptible(dev);
1944be47400SFrançois Tigeot if (err)
1954be47400SFrançois Tigeot goto out;
1964be47400SFrançois Tigeot
1974be47400SFrançois Tigeot err = i915_gem_object_set_to_cpu_domain(obj, write);
1988665870eSFrançois Tigeot mutex_unlock(&dev->struct_mutex);
1994be47400SFrançois Tigeot
2004be47400SFrançois Tigeot out:
2014be47400SFrançois Tigeot i915_gem_object_unpin_pages(obj);
2024be47400SFrançois Tigeot return err;
2038665870eSFrançois Tigeot }
2048665870eSFrançois Tigeot
i915_gem_end_cpu_access(struct dma_buf * dma_buf,enum dma_data_direction direction)2058665870eSFrançois Tigeot static int i915_gem_end_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction)
2068665870eSFrançois Tigeot {
2078665870eSFrançois Tigeot struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
2088665870eSFrançois Tigeot struct drm_device *dev = obj->base.dev;
2094be47400SFrançois Tigeot int err;
2108665870eSFrançois Tigeot
2114be47400SFrançois Tigeot err = i915_gem_object_pin_pages(obj);
2124be47400SFrançois Tigeot if (err)
2134be47400SFrançois Tigeot return err;
2148665870eSFrançois Tigeot
2154be47400SFrançois Tigeot err = i915_mutex_lock_interruptible(dev);
2164be47400SFrançois Tigeot if (err)
2174be47400SFrançois Tigeot goto out;
2184be47400SFrançois Tigeot
2194be47400SFrançois Tigeot err = i915_gem_object_set_to_gtt_domain(obj, false);
2208665870eSFrançois Tigeot mutex_unlock(&dev->struct_mutex);
2218665870eSFrançois Tigeot
2224be47400SFrançois Tigeot out:
2234be47400SFrançois Tigeot i915_gem_object_unpin_pages(obj);
2244be47400SFrançois Tigeot return err;
2258665870eSFrançois Tigeot }
2268665870eSFrançois Tigeot
2278665870eSFrançois Tigeot static const struct dma_buf_ops i915_dmabuf_ops = {
2288665870eSFrançois Tigeot .map_dma_buf = i915_gem_map_dma_buf,
2298665870eSFrançois Tigeot .unmap_dma_buf = i915_gem_unmap_dma_buf,
2308665870eSFrançois Tigeot .release = drm_gem_dmabuf_release,
231a85cb24fSFrançois Tigeot .map = i915_gem_dmabuf_kmap,
232a85cb24fSFrançois Tigeot .map_atomic = i915_gem_dmabuf_kmap_atomic,
233a85cb24fSFrançois Tigeot .unmap = i915_gem_dmabuf_kunmap,
234a85cb24fSFrançois Tigeot .unmap_atomic = i915_gem_dmabuf_kunmap_atomic,
2358665870eSFrançois Tigeot .mmap = i915_gem_dmabuf_mmap,
2368665870eSFrançois Tigeot .vmap = i915_gem_dmabuf_vmap,
2378665870eSFrançois Tigeot .vunmap = i915_gem_dmabuf_vunmap,
2388665870eSFrançois Tigeot .begin_cpu_access = i915_gem_begin_cpu_access,
2398665870eSFrançois Tigeot .end_cpu_access = i915_gem_end_cpu_access,
2408665870eSFrançois Tigeot };
2418665870eSFrançois Tigeot
i915_gem_prime_export(struct drm_device * dev,struct drm_gem_object * gem_obj,int flags)2428665870eSFrançois Tigeot struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
2438665870eSFrançois Tigeot struct drm_gem_object *gem_obj, int flags)
2448665870eSFrançois Tigeot {
2458665870eSFrançois Tigeot struct drm_i915_gem_object *obj = to_intel_bo(gem_obj);
2468665870eSFrançois Tigeot DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
2478665870eSFrançois Tigeot
2488665870eSFrançois Tigeot exp_info.ops = &i915_dmabuf_ops;
2498665870eSFrançois Tigeot exp_info.size = gem_obj->size;
2508665870eSFrançois Tigeot exp_info.flags = flags;
2518665870eSFrançois Tigeot exp_info.priv = gem_obj;
2524be47400SFrançois Tigeot exp_info.resv = obj->resv;
2538665870eSFrançois Tigeot
2548665870eSFrançois Tigeot if (obj->ops->dmabuf_export) {
2558665870eSFrançois Tigeot int ret = obj->ops->dmabuf_export(obj);
2568665870eSFrançois Tigeot if (ret)
2578665870eSFrançois Tigeot return ERR_PTR(ret);
2588665870eSFrançois Tigeot }
2598665870eSFrançois Tigeot
2604be47400SFrançois Tigeot return drm_gem_dmabuf_export(dev, &exp_info);
2618665870eSFrançois Tigeot }
2628665870eSFrançois Tigeot
i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object * obj)263*3f2dd94aSFrançois Tigeot static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
2648665870eSFrançois Tigeot {
265*3f2dd94aSFrançois Tigeot struct sg_table *pages;
266*3f2dd94aSFrançois Tigeot unsigned int sg_page_sizes;
267*3f2dd94aSFrançois Tigeot
268*3f2dd94aSFrançois Tigeot pages = dma_buf_map_attachment(obj->base.import_attach,
2694be47400SFrançois Tigeot DMA_BIDIRECTIONAL);
270*3f2dd94aSFrançois Tigeot if (IS_ERR(pages))
271*3f2dd94aSFrançois Tigeot return PTR_ERR(pages);
272*3f2dd94aSFrançois Tigeot
273*3f2dd94aSFrançois Tigeot sg_page_sizes = i915_sg_page_sizes(pages->sgl);
274*3f2dd94aSFrançois Tigeot
275*3f2dd94aSFrançois Tigeot __i915_gem_object_set_pages(obj, pages, sg_page_sizes);
276*3f2dd94aSFrançois Tigeot
277*3f2dd94aSFrançois Tigeot return 0;
2788665870eSFrançois Tigeot }
2798665870eSFrançois Tigeot
i915_gem_object_put_pages_dmabuf(struct drm_i915_gem_object * obj,struct sg_table * pages)2804be47400SFrançois Tigeot static void i915_gem_object_put_pages_dmabuf(struct drm_i915_gem_object *obj,
2814be47400SFrançois Tigeot struct sg_table *pages)
2828665870eSFrançois Tigeot {
2834be47400SFrançois Tigeot dma_buf_unmap_attachment(obj->base.import_attach, pages,
2844be47400SFrançois Tigeot DMA_BIDIRECTIONAL);
2858665870eSFrançois Tigeot }
2868665870eSFrançois Tigeot
2878665870eSFrançois Tigeot static const struct drm_i915_gem_object_ops i915_gem_object_dmabuf_ops = {
2888665870eSFrançois Tigeot .get_pages = i915_gem_object_get_pages_dmabuf,
2898665870eSFrançois Tigeot .put_pages = i915_gem_object_put_pages_dmabuf,
2908665870eSFrançois Tigeot };
2918665870eSFrançois Tigeot
i915_gem_prime_import(struct drm_device * dev,struct dma_buf * dma_buf)2928665870eSFrançois Tigeot struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
2938665870eSFrançois Tigeot struct dma_buf *dma_buf)
2948665870eSFrançois Tigeot {
2958665870eSFrançois Tigeot struct dma_buf_attachment *attach;
2968665870eSFrançois Tigeot struct drm_i915_gem_object *obj;
2978665870eSFrançois Tigeot int ret;
2988665870eSFrançois Tigeot
2998665870eSFrançois Tigeot /* is this one of own objects? */
3008665870eSFrançois Tigeot if (dma_buf->ops == &i915_dmabuf_ops) {
3018665870eSFrançois Tigeot obj = dma_buf_to_obj(dma_buf);
3028665870eSFrançois Tigeot /* is it from our device? */
3038665870eSFrançois Tigeot if (obj->base.dev == dev) {
3048665870eSFrançois Tigeot /*
3058665870eSFrançois Tigeot * Importing dmabuf exported from out own gem increases
3068665870eSFrançois Tigeot * refcount on gem itself instead of f_count of dmabuf.
3078665870eSFrançois Tigeot */
30887df8fc6SFrançois Tigeot return &i915_gem_object_get(obj)->base;
3098665870eSFrançois Tigeot }
3108665870eSFrançois Tigeot }
3118665870eSFrançois Tigeot
3128665870eSFrançois Tigeot /* need to attach */
3138665870eSFrançois Tigeot attach = dma_buf_attach(dma_buf, dev->dev);
3148665870eSFrançois Tigeot if (IS_ERR(attach))
3158665870eSFrançois Tigeot return ERR_CAST(attach);
3168665870eSFrançois Tigeot
3178665870eSFrançois Tigeot #if 0
3188665870eSFrançois Tigeot get_dma_buf(dma_buf);
3198665870eSFrançois Tigeot #endif
3208665870eSFrançois Tigeot
321a85cb24fSFrançois Tigeot obj = i915_gem_object_alloc(to_i915(dev));
3228665870eSFrançois Tigeot if (obj == NULL) {
3238665870eSFrançois Tigeot ret = -ENOMEM;
3248665870eSFrançois Tigeot goto fail_detach;
3258665870eSFrançois Tigeot }
3268665870eSFrançois Tigeot
3278665870eSFrançois Tigeot drm_gem_private_object_init(dev, &obj->base, dma_buf->size);
3288665870eSFrançois Tigeot i915_gem_object_init(obj, &i915_gem_object_dmabuf_ops);
3298665870eSFrançois Tigeot obj->base.import_attach = attach;
3304be47400SFrançois Tigeot obj->resv = dma_buf->resv;
3318665870eSFrançois Tigeot
33287df8fc6SFrançois Tigeot /* We use GTT as shorthand for a coherent domain, one that is
33387df8fc6SFrançois Tigeot * neither in the GPU cache nor in the CPU cache, where all
33487df8fc6SFrançois Tigeot * writes are immediately visible in memory. (That's not strictly
33587df8fc6SFrançois Tigeot * true, but it's close! There are internal buffers such as the
33687df8fc6SFrançois Tigeot * write-combined buffer or a delay through the chipset for GTT
33787df8fc6SFrançois Tigeot * writes that do require us to treat GTT as a separate cache domain.)
33887df8fc6SFrançois Tigeot */
33987df8fc6SFrançois Tigeot obj->base.read_domains = I915_GEM_DOMAIN_GTT;
34087df8fc6SFrançois Tigeot obj->base.write_domain = 0;
34187df8fc6SFrançois Tigeot
3428665870eSFrançois Tigeot return &obj->base;
3438665870eSFrançois Tigeot
3448665870eSFrançois Tigeot fail_detach:
3458665870eSFrançois Tigeot #if 0
3468665870eSFrançois Tigeot dma_buf_detach(dma_buf, attach);
3478665870eSFrançois Tigeot dma_buf_put(dma_buf);
3488665870eSFrançois Tigeot #endif
3498665870eSFrançois Tigeot
3508665870eSFrançois Tigeot return ERR_PTR(ret);
3518665870eSFrançois Tigeot }
352a85cb24fSFrançois Tigeot
353a85cb24fSFrançois Tigeot #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
354a85cb24fSFrançois Tigeot #include "selftests/mock_dmabuf.c"
355a85cb24fSFrançois Tigeot #include "selftests/i915_gem_dmabuf.c"
356a85cb24fSFrançois Tigeot #endif
357