summaryrefslogtreecommitdiff
path: root/sys/external
diff options
context:
space:
mode:
authorriastradh <riastradh@NetBSD.org>2021-12-19 01:38:51 +0000
committerriastradh <riastradh@NetBSD.org>2021-12-19 01:38:51 +0000
commite048324761dfca71b7d07eb2d1d9a135a17acc1e (patch)
treec6f7c4cc1a4585fa973f8584ad059f07349ca9e8 /sys/external
parent136db9ec84df8ffd5a9854e58985f8d132d6875a (diff)
Tell i915_gem_internal.c the good news about bus_dma.
Diffstat (limited to 'sys/external')
-rw-r--r--sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_internal.c76
-rw-r--r--sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object_types.h11
2 files changed, 84 insertions, 3 deletions
diff --git a/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_internal.c b/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_internal.c
index 28e4112c77d..b01bd75bc1c 100644
--- a/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_internal.c
+++ b/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_internal.c
@@ -1,4 +1,4 @@
-/* $NetBSD: i915_gem_internal.c,v 1.2 2021/12/18 23:45:30 riastradh Exp $ */
+/* $NetBSD: i915_gem_internal.c,v 1.3 2021/12/19 01:38:51 riastradh Exp $ */
/*
* SPDX-License-Identifier: MIT
@@ -7,7 +7,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: i915_gem_internal.c,v 1.2 2021/12/18 23:45:30 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i915_gem_internal.c,v 1.3 2021/12/19 01:38:51 riastradh Exp $");
#include <linux/scatterlist.h>
#include <linux/slab.h>
@@ -21,6 +21,7 @@ __KERNEL_RCSID(0, "$NetBSD: i915_gem_internal.c,v 1.2 2021/12/18 23:45:30 riastr
#include "i915_scatterlist.h"
#include "i915_utils.h"
+#ifndef __NetBSD__
#define QUIET (__GFP_NORETRY | __GFP_NOWARN)
#define MAYFAIL (__GFP_RETRY_MAYFAIL | __GFP_NOWARN)
@@ -36,10 +37,64 @@ static void internal_free_pages(struct sg_table *st)
sg_free_table(st);
kfree(st);
}
+#endif
static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
{
struct drm_i915_private *i915 = to_i915(obj->base.dev);
+#ifdef __NetBSD__
+ bus_dma_tag_t dmat = i915->drm.dmat;
+ bus_dmamap_t map;
+ size_t nsegs;
+ unsigned sizes, seg;
+ int ret;
+
+ KASSERT(obj->mm.segs == NULL);
+ nsegs = obj->mm.nsegs = obj->base.size/PAGE_SIZE;
+ if (nsegs > UINT_MAX || nsegs > SIZE_MAX/sizeof(obj->mm.segs[0]))
+ return -ENOMEM;
+ obj->mm.segs = kmem_alloc(nsegs * sizeof(obj->mm.segs[0]), KM_NOSLEEP);
+ if (obj->mm.segs == NULL)
+ return -ENOMEM;
+
+ /* XXX errno NetBSD->Linux */
+ ret = -bus_dmamem_alloc(dmat, obj->base.size, PAGE_SIZE, 0,
+ obj->mm.segs, nsegs, &obj->mm.rsegs, BUS_DMA_NOWAIT);
+ if (ret)
+ goto out0;
+
+ /* XXX errno NetBSD->Linux */
+ ret = -bus_dmamap_create(dmat, obj->base.size, obj->mm.rsegs,
+ obj->base.size, 0, BUS_DMA_NOWAIT, &map);
+ if (ret)
+ goto out1;
+
+ /* XXX errno NetBSD->Linux */
+ ret = -bus_dmamap_load_raw(dmat, map, obj->mm.segs, obj->mm.rsegs,
+ obj->base.size, BUS_DMA_NOWAIT);
+ if (ret)
+ goto out2;
+
+ ret = i915_gem_gtt_prepare_pages(obj, map);
+ if (ret)
+ goto out3;
+
+ for (sizes = 0, seg = 0; seg < map->dm_nsegs; seg++)
+ sizes |= map->dm_segs[seg].ds_len;
+
+ obj->mm.madv = I915_MADV_DONTNEED;
+ __i915_gem_object_set_pages(obj, map, sizes);
+
+ return 0;
+
+out4: __unused
+ i915_gem_gtt_finish_pages(obj, map);
+out3: bus_dmamap_unload(dmat, obj->mm.pages);
+out2: bus_dmamap_destroy(dmat, obj->mm.pages);
+out1: bus_dmamem_free(dmat, obj->mm.segs, obj->mm.rsegs);
+out0: kmem_free(obj->mm.segs, nsegs * sizeof(obj->mm.segs[0]));
+ return ret;
+#else
struct sg_table *st;
struct scatterlist *sg;
unsigned int sg_page_sizes;
@@ -132,13 +187,30 @@ err:
internal_free_pages(st);
return -ENOMEM;
+#endif
}
+#ifdef __NetBSD__
+static void i915_gem_object_put_pages_internal(struct drm_i915_gem_object *obj,
+ bus_dmamap_t pages)
+#else
static void i915_gem_object_put_pages_internal(struct drm_i915_gem_object *obj,
struct sg_table *pages)
+#endif
{
i915_gem_gtt_finish_pages(obj, pages);
+#ifdef __NetBSD__
+ bus_dma_tag_t dmat = obj->base.dev->dmat;
+ bus_dmamap_unload(dmat, pages);
+ bus_dmamap_destroy(dmat, pages);
+ bus_dmamem_free(dmat, obj->mm.segs, obj->mm.rsegs);
+ obj->mm.rsegs = 0;
+ kmem_free(obj->mm.segs, obj->mm.nsegs * sizeof(obj->mm.segs[0]));
+ obj->mm.segs = NULL;
+ obj->mm.nsegs = 0;
+#else
internal_free_pages(pages);
+#endif
obj->mm.dirty = false;
}
diff --git a/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object_types.h b/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object_types.h
index 2da83c03883..1ce0de06e7e 100644
--- a/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object_types.h
+++ b/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object_types.h
@@ -1,4 +1,4 @@
-/* $NetBSD: i915_gem_object_types.h,v 1.2 2021/12/18 23:45:30 riastradh Exp $ */
+/* $NetBSD: i915_gem_object_types.h,v 1.3 2021/12/19 01:38:51 riastradh Exp $ */
/*
* SPDX-License-Identifier: MIT
@@ -208,7 +208,16 @@ struct drm_i915_gem_object {
*/
struct list_head region_link;
+#ifdef __NetBSD__
+ struct pglist pageq; /* wired pages of normal objects */
+ struct sg_table *sg; /* drm prime objects */
+ bus_dma_segment_t *segs;/* internal objects */
+ unsigned nsegs;
+ int rsegs;
+ bus_dmamap_t pages; /* expedient misnomer */
+#else
struct sg_table *pages;
+#endif
void *mapping;
struct i915_page_sizes {