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 Partial viadrm2 snapshot.



details:   https://anonhg.NetBSD.org/src/rev/46669ddc925a
branches:  trunk
changeset: 801990:46669ddc925a
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Tue Aug 26 17:28:14 2014 +0000

description:
Partial viadrm2 snapshot.

To do:

- autoconf attachment (shouldn't be hard)
- viafb (maybe steal unichromefb and adapt attachment structure)
- actually run it (no hardware here)

diffstat:

 sys/external/bsd/drm2/dist/drm/via/via_dma.c     |   12 +-
 sys/external/bsd/drm2/dist/drm/via/via_dmablit.c |  242 +++++++++++++++++++++-
 sys/external/bsd/drm2/dist/drm/via/via_dmablit.h |   20 +-
 sys/external/bsd/drm2/dist/drm/via/via_drv.h     |   14 +
 sys/external/bsd/drm2/dist/drm/via/via_irq.c     |   49 ++++
 sys/external/bsd/drm2/dist/drm/via/via_video.c   |   36 +++
 sys/external/bsd/drm2/via/files.via              |   22 ++
 7 files changed, 377 insertions(+), 18 deletions(-)

diffs (truncated from 823 to 300 lines):

diff -r af89ad5550cf -r 46669ddc925a sys/external/bsd/drm2/dist/drm/via/via_dma.c
--- a/sys/external/bsd/drm2/dist/drm/via/via_dma.c      Tue Aug 26 17:26:05 2014 +0000
+++ b/sys/external/bsd/drm2/dist/drm/via/via_dma.c      Tue Aug 26 17:28:14 2014 +0000
@@ -39,6 +39,8 @@
 #include "via_drv.h"
 #include "via_3d_reg.h"
 
+#include <linux/delay.h>
+
 #define CMDBUF_ALIGNMENT_SIZE   (0x100)
 #define CMDBUF_ALIGNMENT_MASK   (0x0ff)
 
@@ -234,13 +236,21 @@
 
        switch (init->func) {
        case VIA_INIT_DMA:
+#ifdef __NetBSD__
+               if (!DRM_SUSER())
+#else
                if (!capable(CAP_SYS_ADMIN))
+#endif
                        retcode = -EPERM;
                else
                        retcode = via_initialize(dev, dev_priv, init);
                break;
        case VIA_CLEANUP_DMA:
+#ifdef __NetBSD__
+               if (!DRM_SUSER())
+#else
                if (!capable(CAP_SYS_ADMIN))
+#endif
                        retcode = -EPERM;
                else
                        retcode = via_dma_cleanup(dev);
@@ -586,13 +596,11 @@
 
 static void via_cmdbuf_jump(drm_via_private_t *dev_priv)
 {
-       uint32_t agp_base;
        uint32_t pause_addr_lo, pause_addr_hi;
        uint32_t jump_addr_lo, jump_addr_hi;
        volatile uint32_t *last_pause_ptr;
        uint32_t dma_low_save1, dma_low_save2;
 
-       agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
        via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi,
                      &jump_addr_lo, 0);
 
diff -r af89ad5550cf -r 46669ddc925a sys/external/bsd/drm2/dist/drm/via/via_dmablit.c
--- a/sys/external/bsd/drm2/dist/drm/via/via_dmablit.c  Tue Aug 26 17:26:05 2014 +0000
+++ b/sys/external/bsd/drm2/dist/drm/via/via_dmablit.c  Tue Aug 26 17:28:14 2014 +0000
@@ -41,6 +41,7 @@
 
 #include <linux/pagemap.h>
 #include <linux/slab.h>
+#include <linux/timer.h>
 
 #define VIA_PGDN(x)         (((unsigned long)(x)) & PAGE_MASK)
 #define VIA_PGOFF(x)       (((unsigned long)(x)) & ~PAGE_MASK)
@@ -61,8 +62,12 @@
 
 
 static void
-via_unmap_blit_from_device(struct pci_dev *pdev, drm_via_sg_info_t *vsg)
+via_unmap_blit_from_device(struct drm_device *dev, struct pci_dev *pdev,
+    drm_via_sg_info_t *vsg)
 {
+#ifdef __NetBSD__
+       bus_dmamap_unload(dev->dmat, vsg->dmamap);
+#else
        int num_desc = vsg->num_desc;
        unsigned cur_descriptor_page = num_desc / vsg->descriptors_per_page;
        unsigned descriptor_this_page = num_desc % vsg->descriptors_per_page;
@@ -82,6 +87,7 @@
                next = (dma_addr_t) desc_ptr->next;
                desc_ptr--;
        }
+#endif
 }
 
 /*
@@ -101,7 +107,9 @@
        unsigned num_descriptors_this_page = 0;
        unsigned char *mem_addr = xfer->mem_addr;
        unsigned char *cur_mem;
+#ifndef __NetBSD__
        unsigned char *first_addr = (unsigned char *)VIA_PGDN(mem_addr);
+#endif
        uint32_t fb_addr = xfer->fb_addr;
        uint32_t cur_fb;
        unsigned long line_len;
@@ -126,18 +134,31 @@
                        line_len -= remaining_len;
 
                        if (mode == 1) {
+#ifdef __NetBSD__
+                               const bus_dma_segment_t *const seg =
+                                   &vsg->dmamap->dm_segs[atop(cur_mem)];
+                               desc_ptr->mem_addr =
+                                   seg->ds_addr + trunc_page((vaddr_t)cur_mem);
+#else
                                desc_ptr->mem_addr =
                                        dma_map_page(&pdev->dev,
                                                     vsg->pages[VIA_PFN(cur_mem) -
                                                                VIA_PFN(first_addr)],
                                                     VIA_PGOFF(cur_mem), remaining_len,
                                                     vsg->direction);
+#endif
                                desc_ptr->dev_addr = cur_fb;
 
                                desc_ptr->size = remaining_len;
                                desc_ptr->next = (uint32_t) next;
+#ifdef __NetBSD__
+                               next = vsg->desc_dmamap
+                                   ->dm_segs[cur_descriptor_page].ds_addr
+                                   + num_descriptors_this_page;
+#else
                                next = dma_map_single(&pdev->dev, desc_ptr, sizeof(*desc_ptr),
                                                      DMA_TO_DEVICE);
+#endif
                                desc_ptr++;
                                if (++num_descriptors_this_page >= vsg->descriptors_per_page) {
                                        num_descriptors_this_page = 0;
@@ -169,21 +190,40 @@
 
 
 static void
-via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg)
+via_free_sg_info(struct drm_device *dev, struct pci_dev *pdev,
+    drm_via_sg_info_t *vsg)
 {
+#ifndef __NetBSD__
        struct page *page;
        int i;
+#endif
 
        switch (vsg->state) {
        case dr_via_device_mapped:
-               via_unmap_blit_from_device(pdev, vsg);
+               via_unmap_blit_from_device(dev, pdev, vsg);
        case dr_via_desc_pages_alloc:
+#ifdef __NetBSD__
+               bus_dmamap_unload(dev->dmat, vsg->desc_dmamap);
+               bus_dmamap_destroy(dev->dmat, vsg->desc_dmamap);
+               bus_dmamem_unmap(dev->dmat, vsg->desc_kva,
+                   vsg->num_desc_pages << PAGE_SHIFT);
+               bus_dmamem_free(dev->dmat, vsg->desc_segs, vsg->num_desc_segs);
+               kfree(vsg->desc_segs);
+#else
                for (i = 0; i < vsg->num_desc_pages; ++i) {
                        if (vsg->desc_pages[i] != NULL)
                                free_page((unsigned long)vsg->desc_pages[i]);
                }
+#endif
                kfree(vsg->desc_pages);
        case dr_via_pages_locked:
+#ifdef __NetBSD__
+               /* Make sure any completed transfer is synced.  */
+               bus_dmamap_sync(dev->dmat, vsg->dmamap, 0,
+                   vsg->num_pages << PAGE_SHIFT,
+                   (vsg->direction == DMA_FROM_DEVICE?
+                       BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
+#else
                for (i = 0; i < vsg->num_pages; ++i) {
                        if (NULL != (page = vsg->pages[i])) {
                                if (!PageReserved(page) && (DMA_FROM_DEVICE == vsg->direction))
@@ -191,13 +231,16 @@
                                page_cache_release(page);
                        }
                }
+#endif
        case dr_via_pages_alloc:
+#ifdef __NetBSD__
+               bus_dmamap_destroy(dev->dmat, vsg->dmamap);
+#else
                vfree(vsg->pages);
+#endif
        default:
                vsg->state = dr_via_sg_init;
        }
-       vfree(vsg->bounce_buffer);
-       vsg->bounce_buffer = NULL;
        vsg->free_on_sequence = 0;
 }
 
@@ -228,9 +271,47 @@
  */
 
 static int
-via_lock_all_dma_pages(drm_via_sg_info_t *vsg,  drm_via_dmablit_t *xfer)
+via_lock_all_dma_pages(struct drm_device *dev, drm_via_sg_info_t *vsg,
+    drm_via_dmablit_t *xfer)
 {
        int ret;
+#ifdef __NetBSD__
+       const bus_size_t nbytes = roundup2(xfer->num_lines * xfer->mem_stride,
+           PAGE_SIZE);
+       const bus_size_t npages = nbytes >> PAGE_SHIFT;
+       struct iovec iov = {
+               .iov_base       = xfer->mem_addr,
+               .iov_len        = nbytes,
+       };
+       struct uio uio = {
+               .uio_iov        = &iov,
+               .uio_iovcnt     = 1,
+               .uio_offset     = 0,
+               .uio_resid      = nbytes,
+               .uio_rw         = xfer->to_fb ? UIO_WRITE : UIO_READ,
+               .uio_vmspace    = curproc->p_vmspace,
+       };
+
+       /*
+        * XXX Lock out anyone else from doing this?  Add a
+        * dr_via_pages_loading state?  Just rely on the giant lock?
+        */
+       /* XXX errno NetBSD->Linux */
+       ret = -bus_dmamap_create(dev->dmat, nbytes, npages, nbytes, PAGE_SIZE,
+           BUS_DMA_WAITOK, &vsg->dmamap);
+       if (ret) {
+               DRM_ERROR("bus_dmamap_create failed: %d\n", ret);
+               return ret;
+       }
+       ret = -bus_dmamap_load_uio(dev->dmat, vsg->dmamap, &uio,
+           BUS_DMA_WAITOK | (xfer->to_fb? BUS_DMA_WRITE : BUS_DMA_READ));
+       if (ret) {
+               DRM_ERROR("bus_dmamap_load failed: %d\n", ret);
+               bus_dmamap_destroy(dev->dmat, vsg->dmamap);
+               return ret;
+       }
+       vsg->num_pages = npages;
+#else
        unsigned long first_pfn = VIA_PFN(xfer->mem_addr);
        vsg->num_pages = VIA_PFN(xfer->mem_addr + (xfer->num_lines * xfer->mem_stride - 1)) -
                first_pfn + 1;
@@ -252,6 +333,7 @@
                vsg->state = dr_via_pages_locked;
                return -EINVAL;
        }
+#endif
        vsg->state = dr_via_pages_locked;
        DRM_DEBUG("DMA pages locked\n");
        return 0;
@@ -264,9 +346,12 @@
  */
 
 static int
-via_alloc_desc_pages(drm_via_sg_info_t *vsg)
+via_alloc_desc_pages(struct drm_device *dev, drm_via_sg_info_t *vsg)
 {
        int i;
+#ifdef __NetBSD__
+       int ret;
+#endif
 
        vsg->descriptors_per_page = PAGE_SIZE / sizeof(drm_via_descriptor_t);
        vsg->num_desc_pages = (vsg->num_desc + vsg->descriptors_per_page - 1) /
@@ -275,12 +360,67 @@
        if (NULL ==  (vsg->desc_pages = kcalloc(vsg->num_desc_pages, sizeof(void *), GFP_KERNEL)))
                return -ENOMEM;
 
+#ifdef __NetBSD__
+       vsg->desc_segs = kcalloc(vsg->num_desc_pages, sizeof(*vsg->desc_segs),
+           GFP_KERNEL);
+       if (vsg->desc_segs == NULL) {
+               kfree(vsg->desc_pages);
+               return -ENOMEM;
+       }
+       /* XXX errno NetBSD->Linux */
+       ret = -bus_dmamem_alloc(dev->dmat, vsg->num_desc_pages << PAGE_SHIFT,
+           PAGE_SIZE, 0, vsg->desc_segs, vsg->num_pages, &vsg->num_desc_segs,
+           BUS_DMA_WAITOK);
+       if (ret) {
+               kfree(vsg->desc_segs);
+               kfree(vsg->desc_pages);
+               return -ENOMEM;
+       }
+       /* XXX No nice way to scatter/gather map bus_dmamem.  */
+       /* XXX errno NetBSD->Linux */
+       ret = -bus_dmamem_map(dev->dmat, vsg->desc_segs, vsg->num_desc_segs,
+           vsg->num_desc_pages << PAGE_SHIFT, &vsg->desc_kva, BUS_DMA_WAITOK);
+       if (ret) {
+               bus_dmamem_free(dev->dmat, vsg->desc_segs, vsg->num_desc_segs);
+               kfree(vsg->desc_segs);
+               kfree(vsg->desc_pages);
+               return -ENOMEM;
+       }
+       /* XXX errno NetBSD->Linux */
+       ret = -bus_dmamap_create(dev->dmat, vsg->num_desc_pages << PAGE_SHIFT,
+           vsg->num_desc_pages, PAGE_SIZE, 0, BUS_DMA_WAITOK,
+           &vsg->desc_dmamap);
+       if (ret) {
+               bus_dmamem_unmap(dev->dmat, vsg->desc_kva,
+                   vsg->num_desc_pages << PAGE_SHIFT);
+               bus_dmamem_free(dev->dmat, vsg->desc_segs, vsg->num_desc_segs);
+               kfree(vsg->desc_segs);
+               kfree(vsg->desc_pages);
+               return -ENOMEM;
+       }
+       ret = -bus_dmamap_load(dev->dmat, vsg->desc_dmamap, vsg->desc_kva,
+           vsg->num_desc_pages << PAGE_SHIFT, NULL, BUS_DMA_WAITOK);



Home | Main Index | Thread Index | Old Index