From cdc07f918cec0d2bed86f0ac8d2c1848e9f9dceb Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sun, 9 Jul 2023 22:00:18 +0000 Subject: [PATCH] WIP: i915: Implement rotate and remap views. --- .../bsd/drm2/dist/drm/i915/gt/intel_ggtt.c | 186 ++++++++++++------ 1 file changed, 126 insertions(+), 60 deletions(-) diff --git a/sys/external/bsd/drm2/dist/drm/i915/gt/intel_ggtt.c b/sys/external/bsd/drm2/dist/drm/i915/gt/intel_ggtt.c index 4da9f00317c4..044d632a80cb 100644 --- a/sys/external/bsd/drm2/dist/drm/i915/gt/intel_ggtt.c +++ b/sys/external/bsd/drm2/dist/drm/i915/gt/intel_ggtt.c @@ -1433,7 +1433,30 @@ void i915_gem_restore_gtt_mappings(struct drm_i915_private *i915) setup_private_pat(ggtt->vm.gt->uncore); } -#ifndef __NetBSD__ +#ifdef __NetBSD__ +static int +ensure_view_dmamap(struct drm_i915_gem_object *obj, struct sg_table *st) +{ + int ret; + + /* XXX KASSERT? */ + if (obj->mm.pages->sgl->sg_dmamap == NULL) + return 0; + + /* XXX errno NetBSD->Linux */ + ret = -bus_dmamap_create(obj->base.dev->dmat, + (bus_size_t)st->nents << PAGE_SHIFT, + st->nents, PAGE_SIZE, 0, BUS_DMA_NOWAIT, + &st->sgl->sg_dmamap); + if (ret) { + st->sgl->sg_dmamap = NULL; + return ret; + } + + st->sgl->sg_dmat = obj->base.dev->dmat; + return 0; +} +#endif static struct scatterlist * rotate_pages(struct drm_i915_gem_object *obj, unsigned int offset, @@ -1447,18 +1470,43 @@ rotate_pages(struct drm_i915_gem_object *obj, unsigned int offset, for (column = 0; column < width; column++) { src_idx = stride * (height - 1) + column + offset; for (row = 0; row < height; row++) { +#ifdef __NetBSD__ + /* + * XXX Do we need to handle >1-page segments + * here? + */ + CTASSERT(PAGE_SIZE == I915_GTT_PAGE_SIZE); + KASSERTMSG(src_idx <= obj->mm.pages->sgl->sg_npgs, + "src_idx=%u npgs=%u", + src_idx, obj->mm.pages->sgl->sg_npgs); + sg->sg_pgs[st->nents] = + obj->mm.pages->sgl->sg_pgs[src_idx / PAGE_SIZE]; + if (obj->mm.pages->sgl->sg_dmamap) { + bus_dmamap_t m = obj->mm.pages->sgl->sg_dmamap; + + KASSERTMSG(src_idx <= m->dm_nsegs, + "src_idx=%u dm_nsegs=%d", + src_idx, m->dm_nsegs); + sg->sg_dmamap->dm_segs[st->nents].ds_addr = + m->dm_segs[src_idx / PAGE_SIZE].ds_addr; + sg->sg_dmamap->dm_segs[st->nents].ds_len = + PAGE_SIZE; + } +#endif st->nents++; /* * We don't need the pages, but need to initialize * the entries so the sg list can be happily traversed. * The only thing we need are DMA addresses. */ +#ifndef __NetBSD__ sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0); sg_dma_address(sg) = i915_gem_object_get_dma_address(obj, src_idx); sg_dma_len(sg) = I915_GTT_PAGE_SIZE; sg = sg_next(sg); src_idx -= stride; +#endif } } @@ -1484,6 +1532,14 @@ intel_rotate_pages(struct intel_rotation_info *rot_info, if (ret) goto err_sg_alloc; +#ifdef __NetBSD__ + ret = ensure_view_dmamap(obj, st); + if (ret) { + sg_free_table(st); + goto err_sg_alloc; + } +#endif + st->nents = 0; sg = st->sgl; @@ -1493,6 +1549,10 @@ intel_rotate_pages(struct intel_rotation_info *rot_info, rot_info->plane[i].stride, st, sg); } +#ifdef __NetBSD__ + KASSERTMSG(st->nents == size, "nents=%u size=%u", st->nents, size); +#endif + return st; err_sg_alloc: @@ -1513,6 +1573,7 @@ remap_pages(struct drm_i915_gem_object *obj, unsigned int offset, { unsigned int row; + /* height pages */ for (row = 0; row < height; row++) { unsigned int left = width * I915_GTT_PAGE_SIZE; @@ -1530,12 +1591,38 @@ remap_pages(struct drm_i915_gem_object *obj, unsigned int offset, length = min(left, length); +#ifdef __NetBSD__ + /* + * XXX Do we need to handle >1-page segments + * here? + */ + KASSERTMSG(length <= PAGE_SIZE, "length=%u", length); + KASSERTMSG(offset <= obj->mm.pages->sgl->sg_npgs, + "offset=%u npgs=%u", + offset, obj->mm.pages->sgl->sg_npgs); + sg->sg_pgs[st->nents] = + obj->mm.pages->sgl->sg_pgs[offset / PAGE_SIZE]; + if (obj->mm.pages->sgl->sg_dmamap) { + bus_dmamap_t m = obj->mm.pages->sgl->sg_dmamap; + + KASSERTMSG(offset <= m->dm_nsegs, + "offset=%u dm_nsegs=%d", + offset, m->dm_nsegs); + sg->sg_dmamap->dm_segs[st->nents].ds_addr = + addr; + sg->sg_dmamap->dm_segs[st->nents].ds_len = + length; + } +#endif + st->nents++; +#ifndef __NetBSD__ sg_set_page(sg, NULL, length, 0); sg_dma_address(sg) = addr; sg_dma_len(sg) = length; sg = sg_next(sg); +#endif offset += length / I915_GTT_PAGE_SIZE; left -= length; @@ -1566,6 +1653,14 @@ intel_remap_pages(struct intel_remapped_info *rem_info, if (ret) goto err_sg_alloc; +#ifdef __NetBSD__ + ret = ensure_view_dmamap(obj, st); + if (ret) { + sg_free_table(st); + goto err_sg_alloc; + } +#endif + st->nents = 0; sg = st->sgl; @@ -1575,6 +1670,10 @@ intel_remap_pages(struct intel_remapped_info *rem_info, rem_info->plane[i].stride, st, sg); } +#ifdef __NetBSD__ + KASSERTMSG(st->nents == size, "nents=%u size=%u", st->nents, size); +#endif + i915_sg_trim(st); return st; @@ -1589,15 +1688,36 @@ err_st_alloc: return ERR_PTR(ret); } -#endif /* __NetBSD__ */ - static noinline struct sg_table * intel_partial_pages(const struct i915_ggtt_view *view, struct drm_i915_gem_object *obj) { + struct sg_table *st; + struct scatterlist *sg, *iter; + unsigned int count = view->partial.size; + unsigned int offset; + int ret; + + st = kmalloc(sizeof(*st), GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto err_st_alloc; + } + + ret = sg_alloc_table(st, count, GFP_KERNEL); + if (ret) + goto err_sg_alloc; + #ifdef __NetBSD__ - struct sg_table *st = NULL; - int ret = -ENOMEM; + __USE(sg); + __USE(iter); + __USE(offset); + + ret = ensure_view_dmamap(obj, st); + if (ret) { + sg_free_table(st); + goto err_sg_alloc; + } KASSERTMSG(view->partial.offset <= obj->base.size >> PAGE_SHIFT, "obj=%p size=0x%zx; view offset=0x%zx size=0x%zx", @@ -1615,29 +1735,6 @@ intel_partial_pages(const struct i915_ggtt_view *view, KASSERTMSG(view->partial.size <= INT_MAX, "view size=0x%zx", (size_t)view->partial.size); - st = kmalloc(sizeof(*st), GFP_KERNEL); - if (st == NULL) - goto fail; - ret = sg_alloc_table(st, view->partial.size, GFP_KERNEL); - if (ret) { - kfree(st); - st = NULL; - goto fail; - } - - /* XXX errno NetBSD->Linux */ - if (obj->mm.pages->sgl->sg_dmamap) { /* XXX KASSERT? */ - ret = -bus_dmamap_create(obj->base.dev->dmat, - (bus_size_t)view->partial.size << PAGE_SHIFT, - view->partial.size, PAGE_SIZE, 0, BUS_DMA_NOWAIT, - &st->sgl->sg_dmamap); - if (ret) { - st->sgl->sg_dmamap = NULL; - goto fail; - } - st->sgl->sg_dmat = obj->base.dev->dmat; - } - /* * Copy over the pages. The view's offset and size are in * units of pages already. @@ -1690,31 +1787,8 @@ intel_partial_pages(const struct i915_ggtt_view *view, } } - /* Success! */ return st; - -fail: if (st) { - sg_free_table(st); - kfree(st); - } - return ERR_PTR(ret); #else - struct sg_table *st; - struct scatterlist *sg, *iter; - unsigned int count = view->partial.size; - unsigned int offset; - int ret; - - st = kmalloc(sizeof(*st), GFP_KERNEL); - if (!st) { - ret = -ENOMEM; - goto err_st_alloc; - } - - ret = sg_alloc_table(st, count, GFP_KERNEL); - if (ret) - goto err_sg_alloc; - iter = i915_gem_object_get_sg(obj, view->partial.offset, &offset); GEM_BUG_ON(!iter); @@ -1743,12 +1817,12 @@ fail: if (st) { iter = __sg_next(iter); offset = 0; } while (1); +#endif err_sg_alloc: kfree(st); err_st_alloc: return ERR_PTR(ret); -#endif /* __NetBSD__ */ } static int @@ -1773,21 +1847,13 @@ i915_get_ggtt_vma_pages(struct i915_vma *vma) return 0; case I915_GGTT_VIEW_ROTATED: -#ifdef __NetBSD__ - vma->pages = ERR_PTR(-ENODEV); -#else vma->pages = intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj); -#endif break; case I915_GGTT_VIEW_REMAPPED: -#ifdef __NetBSD__ - vma->pages = ERR_PTR(-ENODEV); -#else vma->pages = intel_remap_pages(&vma->ggtt_view.remapped, vma->obj); -#endif break; case I915_GGTT_VIEW_PARTIAL: