Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/external/bsd/drm2/dist/drm/i915 Implement a bus_dma vers...
details: https://anonhg.NetBSD.org/src/rev/e470cdf3ac77
branches: trunk
changeset: 365918:e470cdf3ac77
user: riastradh <riastradh%NetBSD.org@localhost>
date: Mon Aug 27 07:16:31 2018 +0000
description:
Implement a bus_dma version of Linux sg_pcopy_from_buffer.
diffstat:
sys/external/bsd/drm2/dist/drm/i915/i915_guc_submission.c | 118 +++++++++++++-
1 files changed, 116 insertions(+), 2 deletions(-)
diffs (178 lines):
diff -r 3d0eb8d1bc1f -r e470cdf3ac77 sys/external/bsd/drm2/dist/drm/i915/i915_guc_submission.c
--- a/sys/external/bsd/drm2/dist/drm/i915/i915_guc_submission.c Mon Aug 27 07:16:20 2018 +0000
+++ b/sys/external/bsd/drm2/dist/drm/i915/i915_guc_submission.c Mon Aug 27 07:16:31 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: i915_guc_submission.c,v 1.5 2018/08/27 07:16:20 riastradh Exp $ */
+/* $NetBSD: i915_guc_submission.c,v 1.6 2018/08/27 07:16:31 riastradh Exp $ */
/*
* Copyright © 2014 Intel Corporation
@@ -24,7 +24,7 @@
*
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: i915_guc_submission.c,v 1.5 2018/08/27 07:16:20 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i915_guc_submission.c,v 1.6 2018/08/27 07:16:31 riastradh Exp $");
#include <linux/bitmap.h>
#include <linux/firmware.h>
@@ -381,6 +381,90 @@
kunmap_atomic(base);
}
+#ifdef __NetBSD__
+/*
+ * bus_dmamem_move_atomic(dmat, seg, nseg, buf, nbytes, rw)
+ *
+ * Transfer nbytes of data between the bus_dma segments seg[0],
+ * seg[1], ..., seg[nseg-1] and buf, in the direction specified by
+ * rw: reading from or writing to the DMA segments.
+ *
+ * Cannot fail.
+ */
+static void
+bus_dmamem_move(bus_dma_tag_t dmat, bus_dma_segment_t *seg, int nseg,
+ bus_size_t skip, void *buf, size_t nbytes, enum uio_rw rw)
+{
+ char *ptr = buf;
+ void *kva;
+ int i;
+
+ /* Find the first segment that we need to copy from. */
+ for (i = 0; skip < seg[i].ds_len; skip -= seg[i].ds_len, i++)
+ KASSERT(i < nseg);
+
+ /* Copy as much as we requested from the segments. */
+ do {
+ paddr_t pa;
+ bus_size_t seglen;
+
+ KASSERT(i < nseg);
+ KASSERT(skip < seg[i].ds_len);
+ pa = seg[i].ds_addr;
+ seglen = MIN(seg[i].ds_len, nbytes);
+ i++;
+
+ while (seglen) {
+ struct vm_page *vm_page = PHYS_TO_VM_PAGE(pa);
+ struct page *page = container_of(vm_page, struct page,
+ p_vmp);
+ size_t copy = MIN(PAGE_SIZE - skip, seglen);
+ const char *src;
+ char *dst;
+
+ kva = kmap_atomic(page);
+ switch (rw) {
+ case UIO_READ:
+ src = kva;
+ src += skip;
+ dst = ptr;
+ case UIO_WRITE:
+ src = ptr;
+ dst = kva;
+ dst += skip;
+ }
+ memcpy(dst, src, copy);
+ kunmap_atomic(kva);
+
+ pa += PAGE_SIZE;
+ seglen -= copy;
+ ptr += copy;
+ nbytes -= copy;
+ skip = 0; /* after the first, we're page-aligned */
+ }
+ } while (nbytes);
+}
+
+static void
+bus_dmamem_write(bus_dma_tag_t dmat, bus_dma_segment_t *seg, int nseg,
+ bus_size_t skip, const void *buf, size_t nbytes)
+{
+
+ bus_dmamem_move(dmat, seg, nseg, skip, __UNCONST(buf), nbytes,
+ UIO_WRITE);
+}
+
+#if 0
+static void
+bus_dmamem_read(bus_dma_tag_t dmat, bus_dma_segment_t *seg, int nseg,
+ bus_size_t skip, void *buf, size_t nbytes)
+{
+
+ bus_dmamem_move(dmat, seg, nseg, skip, buf, nbytes, UIO_READ);
+}
+#endif
+#endif
+
/*
* Initialise/clear the context descriptor shared with the GuC firmware.
*
@@ -394,7 +478,9 @@
{
struct intel_context *ctx = client->owner;
struct guc_context_desc desc;
+#ifndef __NetBSD__
struct sg_table *sg;
+#endif
int i;
memset(&desc, 0, sizeof(desc));
@@ -452,8 +538,13 @@
desc.db_trigger_cpu = 0;
desc.db_trigger_uk = client->doorbell_offset +
i915_gem_obj_ggtt_offset(client->client_obj);
+#ifdef __NetBSD__
+ desc.db_trigger_phy = client->doorbell_offset +
+ client->client_obj->igo_dmamap->dm_segs[0].ds_addr;
+#else
desc.db_trigger_phy = client->doorbell_offset +
sg_dma_address(client->client_obj->pages->sgl);
+#endif
desc.process_desc = client->proc_desc_offset +
i915_gem_obj_ggtt_offset(client->client_obj);
@@ -470,14 +561,36 @@
desc.desc_private = (uintptr_t)client;
/* Pool context is pinned already */
+#ifdef __NetBSD__
+ bus_dma_tag_t dmat = guc->ctx_pool_obj->base.dev->dmat;
+ bus_dma_segment_t *seg = guc->ctx_pool_obj->pages;
+ int nseg = guc->ctx_pool_obj->igo_nsegs;
+ bus_size_t skip = sizeof(desc) * client->ctx_index;
+ size_t nbytes = sizeof(desc);
+
+ bus_dmamem_write(dmat, seg, nseg, skip, &desc, nbytes);
+#else
sg = guc->ctx_pool_obj->pages;
sg_pcopy_from_buffer(sg->sgl, sg->nents, &desc, sizeof(desc),
sizeof(desc) * client->ctx_index);
+#endif
}
static void guc_fini_ctx_desc(struct intel_guc *guc,
struct i915_guc_client *client)
{
+#ifdef __NetBSD__
+ struct guc_context_desc desc;
+ bus_dma_tag_t dmat = guc->ctx_pool_obj->base.dev->dmat;
+ bus_dma_segment_t *seg = guc->ctx_pool_obj->pages;
+ int nseg = guc->ctx_pool_obj->igo_nsegs;
+ bus_size_t skip = sizeof(desc) * client->ctx_index;
+ size_t nbytes = sizeof(desc);
+
+ memset(&desc, 0, sizeof(desc));
+
+ bus_dmamem_write(dmat, seg, nseg, skip, &desc, nbytes);
+#else
struct guc_context_desc desc;
struct sg_table *sg;
@@ -486,6 +599,7 @@
sg = guc->ctx_pool_obj->pages;
sg_pcopy_from_buffer(sg->sgl, sg->nents, &desc, sizeof(desc),
sizeof(desc) * client->ctx_index);
+#endif
}
/* Get valid workqueue item and return it back to offset */
Home |
Main Index |
Thread Index |
Old Index