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/133869aedb0a
branches: trunk
changeset: 331848:133869aedb0a
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 929d917fadb9 -r 133869aedb0a 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 929d917fadb9 -r 133869aedb0a 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