Module Name:    src
Committed By:   riastradh
Date:           Tue Aug 26 17:28:15 UTC 2014

Modified Files:
        src/sys/external/bsd/drm2/dist/drm/via: via_dma.c via_dmablit.c
            via_dmablit.h via_drv.h via_irq.c via_video.c
Added Files:
        src/sys/external/bsd/drm2/via: files.via

Log Message:
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)


To generate a diff of this commit:
cvs rdiff -u -r1.1.1.2 -r1.2 src/sys/external/bsd/drm2/dist/drm/via/via_dma.c \
    src/sys/external/bsd/drm2/dist/drm/via/via_dmablit.c \
    src/sys/external/bsd/drm2/dist/drm/via/via_drv.h \
    src/sys/external/bsd/drm2/dist/drm/via/via_irq.c \
    src/sys/external/bsd/drm2/dist/drm/via/via_video.c
cvs rdiff -u -r1.1.1.1 -r1.2 \
    src/sys/external/bsd/drm2/dist/drm/via/via_dmablit.h
cvs rdiff -u -r0 -r1.1 src/sys/external/bsd/drm2/via/files.via

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/external/bsd/drm2/dist/drm/via/via_dma.c
diff -u src/sys/external/bsd/drm2/dist/drm/via/via_dma.c:1.1.1.2 src/sys/external/bsd/drm2/dist/drm/via/via_dma.c:1.2
--- src/sys/external/bsd/drm2/dist/drm/via/via_dma.c:1.1.1.2	Wed Jul 16 19:35:29 2014
+++ src/sys/external/bsd/drm2/dist/drm/via/via_dma.c	Tue Aug 26 17:28:14 2014
@@ -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 @@ static int via_dma_init(struct drm_devic
 
 	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 inline void via_dummy_bitblt(drm_
 
 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);
 
Index: src/sys/external/bsd/drm2/dist/drm/via/via_dmablit.c
diff -u src/sys/external/bsd/drm2/dist/drm/via/via_dmablit.c:1.1.1.2 src/sys/external/bsd/drm2/dist/drm/via/via_dmablit.c:1.2
--- src/sys/external/bsd/drm2/dist/drm/via/via_dmablit.c:1.1.1.2	Wed Jul 16 19:35:29 2014
+++ src/sys/external/bsd/drm2/dist/drm/via/via_dmablit.c	Tue Aug 26 17:28:14 2014
@@ -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 @@ typedef struct _drm_via_descriptor {
 
 
 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 @@ via_unmap_blit_from_device(struct pci_de
 		next = (dma_addr_t) desc_ptr->next;
 		desc_ptr--;
 	}
+#endif
 }
 
 /*
@@ -101,7 +107,9 @@ via_map_blit_for_device(struct pci_dev *
 	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 @@ via_map_blit_for_device(struct pci_dev *
 			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 @@ via_map_blit_for_device(struct pci_dev *
 
 
 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 @@ via_free_sg_info(struct pci_dev *pdev, d
 				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 @@ via_fire_dmablit(struct drm_device *dev,
  */
 
 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 @@ via_lock_all_dma_pages(drm_via_sg_info_t
 		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 @@ via_lock_all_dma_pages(drm_via_sg_info_t
  */
 
 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 @@ via_alloc_desc_pages(drm_via_sg_info_t *
 	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);
+	if (ret) {
+		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);
+		kfree(vsg->desc_pages);
+		return -ENOMEM;
+	}
+	for (i = 0; i < vsg->num_desc_pages; i++)
+		vsg->desc_pages[i] = (void *)
+		    ((char *)vsg->desc_kva + (i * PAGE_SIZE));
+	vsg->state = dr_via_desc_pages_alloc;
+#else
 	vsg->state = dr_via_desc_pages_alloc;
 	for (i = 0; i < vsg->num_desc_pages; ++i) {
 		if (NULL == (vsg->desc_pages[i] =
 			     (drm_via_descriptor_t *) __get_free_page(GFP_KERNEL)))
 			return -ENOMEM;
 	}
+#endif
 	DRM_DEBUG("Allocated %d pages for %d descriptors.\n", vsg->num_desc_pages,
 		  vsg->num_desc);
 	return 0;
@@ -338,7 +478,12 @@ via_dmablit_handler(struct drm_device *d
 
 		blitq->blits[cur]->aborted = blitq->aborting;
 		blitq->done_blit_handle++;
+#ifdef __NetBSD__
+		DRM_SPIN_WAKEUP_ALL(&blitq->blit_queue[cur],
+		    &blitq->blit_lock);
+#else
 		wake_up(blitq->blit_queue + cur);
+#endif
 
 		cur++;
 		if (cur >= VIA_NUM_BLIT_SLOTS)
@@ -363,7 +508,7 @@ via_dmablit_handler(struct drm_device *d
 
 		via_abort_dmablit(dev, engine);
 		blitq->aborting = 1;
-		blitq->end = jiffies + HZ;
+		blitq->end = jiffies + DRM_HZ;
 	}
 
 	if (!blitq->is_active) {
@@ -372,7 +517,7 @@ via_dmablit_handler(struct drm_device *d
 			blitq->is_active = 1;
 			blitq->cur = cur;
 			blitq->num_outstanding--;
-			blitq->end = jiffies + HZ;
+			blitq->end = jiffies + DRM_HZ;
 			if (!timer_pending(&blitq->poll_timer))
 				mod_timer(&blitq->poll_timer, jiffies + 1);
 		} else {
@@ -395,13 +540,21 @@ via_dmablit_handler(struct drm_device *d
  */
 
 static int
+#ifdef __NetBSD__
+via_dmablit_active(drm_via_blitq_t *blitq, int engine, uint32_t handle, drm_waitqueue_t **queue)
+#else
 via_dmablit_active(drm_via_blitq_t *blitq, int engine, uint32_t handle, wait_queue_head_t **queue)
+#endif
 {
+#ifndef __NetBSD__
 	unsigned long irqsave;
+#endif
 	uint32_t slot;
 	int active;
 
+#ifndef __NetBSD__
 	spin_lock_irqsave(&blitq->blit_lock, irqsave);
+#endif
 
 	/*
 	 * Allow for handle wraparounds.
@@ -417,7 +570,9 @@ via_dmablit_active(drm_via_blitq_t *blit
 		*queue = blitq->blit_queue + slot;
 	}
 
+#ifndef __NetBSD__
 	spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
+#endif
 
 	return active;
 }
@@ -432,13 +587,27 @@ via_dmablit_sync(struct drm_device *dev,
 
 	drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
 	drm_via_blitq_t *blitq = dev_priv->blit_queues + engine;
+#ifdef __NetBSD__
+	drm_waitqueue_t *queue;
+#else
 	wait_queue_head_t *queue;
+#endif
 	int ret = 0;
 
+#ifdef __NetBSD__
+	spin_lock(&blitq->blit_lock);
+	if (via_dmablit_active(blitq, engine, handle, &queue)) {
+		DRM_SPIN_TIMED_WAIT_UNTIL(ret, queue, &blitq->blit_lock,
+		    3*DRM_HZ,
+		    !via_dmablit_active(blitq, engine, handle, NULL));
+	}
+	spin_unlock(&blitq->blit_lock);
+#else
 	if (via_dmablit_active(blitq, engine, handle, &queue)) {
 		DRM_WAIT_ON(ret, *queue, 3 * HZ,
 			    !via_dmablit_active(blitq, engine, handle, NULL));
 	}
+#endif
 	DRM_DEBUG("DMA blit sync handle 0x%x engine %d returned %d\n",
 		  handle, engine, ret);
 
@@ -519,11 +688,25 @@ via_dmablit_workqueue(struct work_struct
 		cur_sg = blitq->blits[cur_released];
 		blitq->num_free++;
 
+#ifdef __NetBSD__
+		DRM_SPIN_WAKEUP_ONE(&blitq->busy_queue, &blitq->blit_lock);
+#endif
+
 		spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
 
+#ifndef __NetBSD__
 		wake_up(&blitq->busy_queue);
+#endif
 
-		via_free_sg_info(dev->pdev, cur_sg);
+#ifdef __NetBSD__
+		/* Transfer completed.  Sync it.  */
+		bus_dmamap_sync(dev->dmat, cur_sg->dmamap, 0,
+		    cur_sg->num_pages << PAGE_SHIFT,
+		    (cur_sg->direction == DMA_FROM_DEVICE
+			? BUS_DMASYNC_POSTREAD
+			: BUS_DMASYNC_POSTWRITE));
+#endif
+		via_free_sg_info(dev, dev->pdev, cur_sg);
 		kfree(cur_sg);
 
 		spin_lock_irqsave(&blitq->blit_lock, irqsave);
@@ -560,9 +743,15 @@ via_init_dmablit(struct drm_device *dev)
 		blitq->is_active = 0;
 		blitq->aborting = 0;
 		spin_lock_init(&blitq->blit_lock);
+#ifdef __NetBSD__
+		for (j = 0; j < VIA_NUM_BLIT_SLOTS; ++j)
+			DRM_INIT_WAITQUEUE(blitq->blit_queue + j, "viablt");
+		DRM_INIT_WAITQUEUE(&blitq->busy_queue, "viabusy");
+#else
 		for (j = 0; j < VIA_NUM_BLIT_SLOTS; ++j)
 			init_waitqueue_head(blitq->blit_queue + j);
 		init_waitqueue_head(&blitq->busy_queue);
+#endif
 		INIT_WORK(&blitq->wq, via_dmablit_workqueue);
 		setup_timer(&blitq->poll_timer, via_dmablit_timer,
 				(unsigned long)blitq);
@@ -581,7 +770,6 @@ via_build_sg_info(struct drm_device *dev
 	int ret = 0;
 
 	vsg->direction = (draw) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
-	vsg->bounce_buffer = NULL;
 
 	vsg->state = dr_via_sg_init;
 
@@ -654,16 +842,16 @@ via_build_sg_info(struct drm_device *dev
 	}
 #endif
 
-	if (0 != (ret = via_lock_all_dma_pages(vsg, xfer))) {
+	if (0 != (ret = via_lock_all_dma_pages(dev, vsg, xfer))) {
 		DRM_ERROR("Could not lock DMA pages.\n");
-		via_free_sg_info(dev->pdev, vsg);
+		via_free_sg_info(dev, dev->pdev, vsg);
 		return ret;
 	}
 
 	via_map_blit_for_device(dev->pdev, xfer, vsg, 0);
-	if (0 != (ret = via_alloc_desc_pages(vsg))) {
+	if (0 != (ret = via_alloc_desc_pages(dev, vsg))) {
 		DRM_ERROR("Could not allocate DMA descriptor pages.\n");
-		via_free_sg_info(dev->pdev, vsg);
+		via_free_sg_info(dev, dev->pdev, vsg);
 		return ret;
 	}
 	via_map_blit_for_device(dev->pdev, xfer, vsg, 1);
@@ -686,6 +874,16 @@ via_dmablit_grab_slot(drm_via_blitq_t *b
 	DRM_DEBUG("Num free is %d\n", blitq->num_free);
 	spin_lock_irqsave(&blitq->blit_lock, irqsave);
 	while (blitq->num_free == 0) {
+#ifdef __NetBSD__
+		DRM_SPIN_TIMED_WAIT_UNTIL(ret, &blitq->busy_queue,
+		    &blitq->blit_lock, DRM_HZ,
+		    blitq->num_free > 0);
+		if (ret) {
+			if (ret == -EINTR)
+				ret = -EAGAIN;
+			return ret;
+		}
+#else
 		spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
 
 		DRM_WAIT_ON(ret, blitq->busy_queue, HZ, blitq->num_free > 0);
@@ -693,6 +891,7 @@ via_dmablit_grab_slot(drm_via_blitq_t *b
 			return (-EINTR == ret) ? -EAGAIN : ret;
 
 		spin_lock_irqsave(&blitq->blit_lock, irqsave);
+#endif
 	}
 
 	blitq->num_free--;
@@ -712,8 +911,13 @@ via_dmablit_release_slot(drm_via_blitq_t
 
 	spin_lock_irqsave(&blitq->blit_lock, irqsave);
 	blitq->num_free++;
+#ifdef __NetBSD__
+	DRM_SPIN_WAKEUP_ONE(&blitq->busy_queue, &blitq->blit_lock);
+#endif
 	spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
+#ifndef __NetBSD__
 	wake_up(&blitq->busy_queue);
+#endif
 }
 
 /*
@@ -749,6 +953,14 @@ via_dmablit(struct drm_device *dev, drm_
 		kfree(vsg);
 		return ret;
 	}
+#ifdef __NetBSD__
+	/* Prepare to begin a DMA transfer.  */
+	bus_dmamap_sync(dev->dmat, vsg->dmamap, 0,
+	    vsg->num_pages << PAGE_SHIFT,
+	    (vsg->direction == DMA_FROM_DEVICE
+		? BUS_DMASYNC_PREREAD
+		: BUS_DMASYNC_PREWRITE));
+#endif
 	spin_lock_irqsave(&blitq->blit_lock, irqsave);
 
 	blitq->blits[blitq->head++] = vsg;
Index: src/sys/external/bsd/drm2/dist/drm/via/via_drv.h
diff -u src/sys/external/bsd/drm2/dist/drm/via/via_drv.h:1.1.1.2 src/sys/external/bsd/drm2/dist/drm/via/via_drv.h:1.2
--- src/sys/external/bsd/drm2/dist/drm/via/via_drv.h:1.1.1.2	Wed Jul 16 19:35:29 2014
+++ src/sys/external/bsd/drm2/dist/drm/via/via_drv.h	Tue Aug 26 17:28:14 2014
@@ -51,10 +51,19 @@ typedef struct drm_via_ring_buffer {
 typedef uint32_t maskarray_t[5];
 
 typedef struct drm_via_irq {
+#ifdef __NetBSD__
+	spinlock_t irq_lock;
+	unsigned irq_received;
+#else
 	atomic_t irq_received;
+#endif
 	uint32_t pending_mask;
 	uint32_t enable_mask;
+#ifdef __NetBSD__
+	drm_waitqueue_t irq_queue;
+#else
 	wait_queue_head_t irq_queue;
+#endif
 } drm_via_irq_t;
 
 typedef struct drm_via_private {
@@ -63,7 +72,12 @@ typedef struct drm_via_private {
 	drm_local_map_t *fb;
 	drm_local_map_t *mmio;
 	unsigned long agpAddr;
+#ifdef __NetBSD__
+	struct mutex decoder_lock[VIA_NR_XVMC_LOCKS];
+	drm_waitqueue_t decoder_queue[VIA_NR_XVMC_LOCKS];
+#else
 	wait_queue_head_t decoder_queue[VIA_NR_XVMC_LOCKS];
+#endif
 	char *dma_ptr;
 	unsigned int dma_low;
 	unsigned int dma_high;
Index: src/sys/external/bsd/drm2/dist/drm/via/via_irq.c
diff -u src/sys/external/bsd/drm2/dist/drm/via/via_irq.c:1.1.1.2 src/sys/external/bsd/drm2/dist/drm/via/via_irq.c:1.2
--- src/sys/external/bsd/drm2/dist/drm/via/via_irq.c:1.1.1.2	Wed Jul 16 19:35:29 2014
+++ src/sys/external/bsd/drm2/dist/drm/via/via_irq.c	Tue Aug 26 17:28:14 2014
@@ -137,8 +137,16 @@ irqreturn_t via_driver_irq_handler(int i
 
 	for (i = 0; i < dev_priv->num_irqs; ++i) {
 		if (status & cur_irq->pending_mask) {
+#ifdef __NetBSD__
+			spin_lock(&cur_irq->irq_lock);
+			cur_irq->irq_received++;
+			DRM_SPIN_WAKEUP_ONE(&cur_irq->irq_queue,
+			    &cur_irq->irq_lock);
+			spin_unlock(&cur_irq->irq_lock);
+#else
 			atomic_inc(&cur_irq->irq_received);
 			wake_up(&cur_irq->irq_queue);
+#endif
 			handled = 1;
 			if (dev_priv->irq_map[drm_via_irq_dma0_td] == i)
 				via_dmablit_handler(dev, 0, 1);
@@ -238,6 +246,22 @@ via_driver_irq_wait(struct drm_device *d
 	masks = dev_priv->irq_masks;
 	cur_irq = dev_priv->via_irqs + real_irq;
 
+#ifdef __NetBSD__
+	spin_lock(&cur_irq->irq_lock);
+	if (masks[real_irq][2] && !force_sequence) {
+		DRM_SPIN_TIMED_WAIT_UNTIL(ret, &cur_irq->irq_queue,
+		    &cur_irq->irq_lock, 3 * DRM_HZ,
+		    ((VIA_READ(masks[irq][2]) & masks[irq][3]) ==
+			masks[irq][4]));
+		cur_irq_sequence = cur_irq->irq_received;
+	} else {
+		DRM_SPIN_TIMED_WAIT_UNTIL(ret, &cur_irq->irq_queue,
+		    &cur_irq->irq_lock, 3 * DRM_HZ,
+		    (((cur_irq_sequence = cur_irq->irq_received) -
+			*sequence) <= (1 << 23)));
+	}
+	spin_unlock(&cur_irq->irq_lock);
+#else
 	if (masks[real_irq][2] && !force_sequence) {
 		DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * HZ,
 			    ((VIA_READ(masks[irq][2]) & masks[irq][3]) ==
@@ -249,6 +273,7 @@ via_driver_irq_wait(struct drm_device *d
 			       atomic_read(&cur_irq->irq_received)) -
 			      *sequence) <= (1 << 23)));
 	}
+#endif
 	*sequence = cur_irq_sequence;
 	return ret;
 }
@@ -284,10 +309,19 @@ void via_driver_irq_preinstall(struct dr
 		}
 
 		for (i = 0; i < dev_priv->num_irqs; ++i) {
+#ifdef __NetBSD__
+			spin_lock_init(&cur_irq->irq_lock);
+			cur_irq->irq_received = 0;
+#else
 			atomic_set(&cur_irq->irq_received, 0);
+#endif
 			cur_irq->enable_mask = dev_priv->irq_masks[i][0];
 			cur_irq->pending_mask = dev_priv->irq_masks[i][1];
+#ifdef __NetBSD__
+			DRM_INIT_WAITQUEUE(&cur_irq->irq_queue, "viairq");
+#else
 			init_waitqueue_head(&cur_irq->irq_queue);
+#endif
 			dev_priv->irq_enable_mask |= cur_irq->enable_mask;
 			dev_priv->irq_pending_mask |= cur_irq->pending_mask;
 			cur_irq++;
@@ -343,6 +377,17 @@ void via_driver_irq_uninstall(struct drm
 		status = VIA_READ(VIA_REG_INTERRUPT);
 		VIA_WRITE(VIA_REG_INTERRUPT, status &
 			  ~(VIA_IRQ_VBLANK_ENABLE | dev_priv->irq_enable_mask));
+
+#ifdef __NetBSD__
+	    {
+		int i;
+
+		for (i = 0; i < dev_priv->num_irqs; i++) {
+			DRM_DESTROY_WAITQUEUE(&dev_priv->via_irqs[i].irq_queue);
+			spin_lock_destroy(&dev_priv->via_irqs[i].irq_lock);
+		}
+	    }
+#endif
 	}
 }
 
@@ -365,8 +410,12 @@ int via_wait_irq(struct drm_device *dev,
 
 	switch (irqwait->request.type & ~VIA_IRQ_FLAGS_MASK) {
 	case VIA_IRQ_RELATIVE:
+#ifdef __NetBSD__
+		irqwait->request.sequence += cur_irq->irq_received;
+#else
 		irqwait->request.sequence +=
 			atomic_read(&cur_irq->irq_received);
+#endif
 		irqwait->request.type &= ~_DRM_VBLANK_RELATIVE;
 	case VIA_IRQ_ABSOLUTE:
 		break;
Index: src/sys/external/bsd/drm2/dist/drm/via/via_video.c
diff -u src/sys/external/bsd/drm2/dist/drm/via/via_video.c:1.1.1.2 src/sys/external/bsd/drm2/dist/drm/via/via_video.c:1.2
--- src/sys/external/bsd/drm2/dist/drm/via/via_video.c:1.1.1.2	Wed Jul 16 19:35:29 2014
+++ src/sys/external/bsd/drm2/dist/drm/via/via_video.c	Tue Aug 26 17:28:14 2014
@@ -36,13 +36,26 @@ void via_init_futex(drm_via_private_t *d
 	DRM_DEBUG("\n");
 
 	for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) {
+#ifdef __NetBSD__
+		linux_mutex_init(&dev_priv->decoder_lock[i]);
+		DRM_INIT_WAITQUEUE(&dev_priv->decoder_queue[i], "viadec");
+#else
 		init_waitqueue_head(&(dev_priv->decoder_queue[i]));
+#endif
 		XVMCLOCKPTR(dev_priv->sarea_priv, i)->lock = 0;
 	}
 }
 
 void via_cleanup_futex(drm_via_private_t *dev_priv)
 {
+#ifdef __NetBSD__
+	unsigned i;
+
+	for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) {
+		DRM_DESTROY_WAITQUEUE(&dev_priv->decoder_queue[i]);
+		linux_mutex_destroy(&dev_priv->decoder_lock[i]);
+	}
+#endif
 }
 
 void via_release_futex(drm_via_private_t *dev_priv, int context)
@@ -58,7 +71,14 @@ void via_release_futex(drm_via_private_t
 		if ((_DRM_LOCKING_CONTEXT(*lock) == context)) {
 			if (_DRM_LOCK_IS_HELD(*lock)
 			    && (*lock & _DRM_LOCK_CONT)) {
+#ifdef __NetBSD__
+				mutex_lock(&dev_priv->decoder_lock[i]);
+				DRM_WAKEUP_ALL(&dev_priv->decoder_queue[i],
+				    &dev_priv->decoder_lock[i]);
+				mutex_unlock(&dev_priv->decoder_lock[i]);
+#else
 				wake_up(&(dev_priv->decoder_queue[i]));
+#endif
 			}
 			*lock = 0;
 		}
@@ -82,11 +102,27 @@ int via_decoder_futex(struct drm_device 
 
 	switch (fx->func) {
 	case VIA_FUTEX_WAIT:
+#ifdef __NetBSD__
+		mutex_lock(&dev_priv->decoder_lock[fx->lock]);
+		DRM_TIMED_WAIT_UNTIL(ret, &dev_priv->decoder_queue[fx->lock],
+		    &dev_priv->decoder_lock[fx->lock],
+		    (fx->ms / 10) * (DRM_HZ / 100),
+		    *lock != fx->val);
+		mutex_unlock(&dev_priv->decoder_lock[fx->lock]);
+#else
 		DRM_WAIT_ON(ret, dev_priv->decoder_queue[fx->lock],
 			    (fx->ms / 10) * (HZ / 100), *lock != fx->val);
+#endif
 		return ret;
 	case VIA_FUTEX_WAKE:
+#ifdef __NetBSD__
+		mutex_lock(&dev_priv->decoder_lock[fx->lock]);
+		DRM_WAKEUP_ALL(&dev_priv->decoder_queue[fx->lock],
+		    &dev_priv->decoder_lock[fx->lock]);
+		mutex_unlock(&dev_priv->decoder_lock[fx->lock]);
+#else
 		wake_up(&(dev_priv->decoder_queue[fx->lock]));
+#endif
 		return 0;
 	}
 	return 0;

Index: src/sys/external/bsd/drm2/dist/drm/via/via_dmablit.h
diff -u src/sys/external/bsd/drm2/dist/drm/via/via_dmablit.h:1.1.1.1 src/sys/external/bsd/drm2/dist/drm/via/via_dmablit.h:1.2
--- src/sys/external/bsd/drm2/dist/drm/via/via_dmablit.h:1.1.1.1	Tue Jul 23 02:13:27 2013
+++ src/sys/external/bsd/drm2/dist/drm/via/via_dmablit.h	Tue Aug 26 17:28:14 2014
@@ -38,13 +38,26 @@
 struct _drm_via_descriptor;
 
 typedef struct _drm_via_sg_info {
+#ifdef __NetBSD__
+	bus_dmamap_t dmamap;
+#else
 	struct page **pages;
+#endif
 	unsigned long num_pages;
+#ifdef __NetBSD__
+	bus_dma_segment_t *desc_segs;
+	int num_desc_segs;
+	void *desc_kva;
+	bus_dmamap_t desc_dmamap;
+#endif
 	struct _drm_via_descriptor **desc_pages;
 	int num_desc_pages;
 	int num_desc;
+#ifdef __NetBSD__
+	enum { DMA_FROM_DEVICE, DMA_TO_DEVICE } direction;
+#else
 	enum dma_data_direction direction;
-	unsigned char *bounce_buffer;
+#endif
 	dma_addr_t chain_start;
 	uint32_t free_on_sequence;
 	unsigned int descriptors_per_page;
@@ -72,8 +85,13 @@ typedef struct _drm_via_blitq {
 	int is_active;
 	drm_via_sg_info_t *blits[VIA_NUM_BLIT_SLOTS];
 	spinlock_t blit_lock;
+#ifdef __NetBSD__
+	drm_waitqueue_t blit_queue[VIA_NUM_BLIT_SLOTS];
+	drm_waitqueue_t busy_queue;
+#else
 	wait_queue_head_t blit_queue[VIA_NUM_BLIT_SLOTS];
 	wait_queue_head_t busy_queue;
+#endif
 	struct work_struct wq;
 	struct timer_list poll_timer;
 } drm_via_blitq_t;

Added files:

Index: src/sys/external/bsd/drm2/via/files.via
diff -u /dev/null src/sys/external/bsd/drm2/via/files.via:1.1
--- /dev/null	Tue Aug 26 17:28:15 2014
+++ src/sys/external/bsd/drm2/via/files.via	Tue Aug 26 17:28:14 2014
@@ -0,0 +1,22 @@
+#	$NetBSD: files.via,v 1.1 2014/08/26 17:28:14 riastradh Exp $
+
+define	viafbbus	{ }
+device	viadrmums: drmkms, drmkms_pci, viafbbus
+attach	viadrmums at pci
+
+device	viafb: viafbbus, genfb, wsemuldisplaydev
+attach	viafb at viafbbus
+
+makeoptions	viadrmums	CPPFLAGS+="-I$S/external/bsd/drm2/dist/drm/via"
+makeoptions	viadrmums	CPPFLAGS+="-I$S/external/bsd/drm2/via"
+
+makeoptions	viadrmums	"CWARNFLAGS.via_verifier.c"+="-Wno-shadow"
+
+file	external/bsd/drm2/dist/drm/via/via_dma.c		viadrmums
+file	external/bsd/drm2/dist/drm/via/via_dmablit.c		viadrmums
+file	external/bsd/drm2/dist/drm/via/via_drv.c		viadrmums
+file	external/bsd/drm2/dist/drm/via/via_irq.c		viadrmums
+file	external/bsd/drm2/dist/drm/via/via_map.c		viadrmums
+file	external/bsd/drm2/dist/drm/via/via_mm.c			viadrmums
+file	external/bsd/drm2/dist/drm/via/via_verifier.c		viadrmums
+file	external/bsd/drm2/dist/drm/via/via_video.c		viadrmums

Reply via email to