diff options
| author | riastradh <riastradh@NetBSD.org> | 2021-12-19 01:38:51 +0000 |
|---|---|---|
| committer | riastradh <riastradh@NetBSD.org> | 2021-12-19 01:38:51 +0000 |
| commit | e048324761dfca71b7d07eb2d1d9a135a17acc1e (patch) | |
| tree | c6f7c4cc1a4585fa973f8584ad059f07349ca9e8 /sys/external | |
| parent | 136db9ec84df8ffd5a9854e58985f8d132d6875a (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.c | 76 | ||||
| -rw-r--r-- | sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object_types.h | 11 |
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 { |
