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 Fill out drm_prime_* API a little...



details:   https://anonhg.NetBSD.org/src/rev/b2327f4242bb
branches:  trunk
changeset: 835487:b2327f4242bb
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Mon Aug 27 15:26:00 2018 +0000

description:
Fill out drm_prime_* API a little more for NetBSD.

Add comment explaining our use of struct sg_table.

diffstat:

 sys/external/bsd/drm2/dist/drm/drm_prime.c    |  82 ++++++++++++++++++++++++++-
 sys/external/bsd/drm2/dist/include/drm/drmP.h |   5 +-
 2 files changed, 84 insertions(+), 3 deletions(-)

diffs (158 lines):

diff -r 1b269e6d9822 -r b2327f4242bb sys/external/bsd/drm2/dist/drm/drm_prime.c
--- a/sys/external/bsd/drm2/dist/drm/drm_prime.c        Mon Aug 27 15:25:43 2018 +0000
+++ b/sys/external/bsd/drm2/dist/drm/drm_prime.c        Mon Aug 27 15:26:00 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: drm_prime.c,v 1.3 2018/08/27 15:22:54 riastradh Exp $  */
+/*     $NetBSD: drm_prime.c,v 1.4 2018/08/27 15:26:00 riastradh Exp $  */
 
 /*
  * Copyright © 2012 Red Hat
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_prime.c,v 1.3 2018/08/27 15:22:54 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_prime.c,v 1.4 2018/08/27 15:26:00 riastradh Exp $");
 
 #include <linux/export.h>
 #include <linux/dma-buf.h>
@@ -38,6 +38,20 @@
 
 #include "drm_internal.h"
 
+#ifdef __NetBSD__
+
+/*
+ * We use struct sg_table just to pass around an array of
+ * bus_dma_segment_t from one device to another in drm prime.  Since
+ * this is _not_ a complete implementation of Linux's sg table
+ * abstraction (e.g., it does not remember DMA addresses and RAM pages
+ * separately, and it doesn't support the nested chained iteration of
+ * Linux scatterlists), we isolate it to this file and make all callers
+ * go through a few extra subroutines (drm_prime_sg_size,
+ * drm_prime_sg_free, &c.) to use it.  Don't use this outside drm
+ * prime!
+ */
+
 struct sg_table {
        bus_dma_segment_t       *sgt_segs;
        int                     sgt_nsegs;
@@ -94,6 +108,30 @@
        return 0;
 }
 
+static int
+sg_alloc_table_from_bus_dmamem(struct sg_table *sgt, bus_dma_segment_t *segs,
+    int nsegs, gfp_t gfp)
+{
+       int seg;
+
+       KASSERT(nsegs > 0);
+       sgt->sgt_segs = kcalloc(nsegs, sizeof(sgt->sgt_segs[0]), gfp);
+       if (sgt->sgt_segs == NULL)
+               return -ENOMEM;
+       sgt->sgt_nsegs = nsegs;
+       sgt->sgt_size = 0;
+
+       for (seg = 0; seg < nsegs; seg++) {
+               sgt->sgt_segs[seg].ds_addr = segs[seg].ds_addr;
+               sgt->sgt_segs[seg].ds_len = segs[seg].ds_len;
+               KASSERT(segs[seg].ds_len <= __type_max(bus_size_t) -
+                   sgt->sgt_size);
+               sgt->sgt_size += segs[seg].ds_len;
+       }
+
+       return 0;
+}
+
 static void
 sg_free_table(struct sg_table *sgt)
 {
@@ -104,6 +142,8 @@
        sgt->sgt_size = 0;
 }
 
+#endif /* __NetBSD__ */
+
 /*
  * DMA-BUF/GEM Object references and lifetime overview:
  *
@@ -795,6 +835,28 @@
 #ifdef __NetBSD__
 
 struct sg_table *
+drm_prime_bus_dmamem_to_sg(bus_dma_segment_t *segs, int nsegs)
+{
+       struct sg_table *sg;
+       int ret;
+
+       sg = kmalloc(sizeof(*sg), GFP_KERNEL);
+       if (sg == NULL) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ret = sg_alloc_table_from_bus_dmamem(sg, segs, nsegs, GFP_KERNEL);
+       if (ret)
+               goto out;
+
+       return sg;
+out:
+       kfree(sg);
+       return ERR_PTR(ret);
+}
+
+struct sg_table *
 drm_prime_pglist_to_sg(struct pglist *pglist, unsigned npages)
 {
        struct sg_table *sg;
@@ -818,6 +880,13 @@
        return ERR_PTR(ret);
 }
 
+bus_size_t
+drm_prime_sg_size(struct sg_table *sg)
+{
+
+       return sg->sgt_size;
+}
+
 void
 drm_prime_sg_free(struct sg_table *sg)
 {
@@ -836,6 +905,15 @@
            sgt->sgt_size, BUS_DMA_NOWAIT);
 }
 
+int
+drm_prime_bus_dmamem_map(bus_dma_tag_t dmat, struct sg_table *sgt, void **kvap,
+    int flags)
+{
+
+       return -bus_dmamem_map(dmat, sgt->sgt_segs, sgt->sgt_nsegs,
+           sgt->sgt_size, kvap, flags);
+}
+
 #else  /* !__NetBSD__ */
 
 /**
diff -r 1b269e6d9822 -r b2327f4242bb sys/external/bsd/drm2/dist/include/drm/drmP.h
--- a/sys/external/bsd/drm2/dist/include/drm/drmP.h     Mon Aug 27 15:25:43 2018 +0000
+++ b/sys/external/bsd/drm2/dist/include/drm/drmP.h     Mon Aug 27 15:26:00 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: drmP.h,v 1.27 2018/08/27 15:22:54 riastradh Exp $      */
+/*     $NetBSD: drmP.h,v 1.28 2018/08/27 15:26:00 riastradh Exp $      */
 
 /*
  * Internal Header for the Direct Rendering Manager
@@ -1183,7 +1183,10 @@
 
 #ifdef __NetBSD__
 extern int drm_prime_bus_dmamap_load_sgt(bus_dma_tag_t, bus_dmamap_t, struct sg_table *);
+extern int drm_prime_bus_dmamem_map(bus_dma_tag_t, struct sg_table *, void **, int);
+extern struct sg_table *drm_prime_bus_dmamem_to_sg(bus_dma_segment_t *, int);
 extern struct sg_table *drm_prime_pglist_to_sg(struct pglist *, unsigned);
+extern bus_size_t drm_prime_sg_size(struct sg_table *);
 extern void drm_prime_sg_free(struct sg_table *);
 #else
 extern int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,



Home | Main Index | Thread Index | Old Index