summaryrefslogtreecommitdiffstats
path: root/sys/dev/drm
diff options
context:
space:
mode:
authoranholt <anholt@FreeBSD.org>2003-08-19 02:57:31 +0000
committeranholt <anholt@FreeBSD.org>2003-08-19 02:57:31 +0000
commit55fc74037ce1fed2313813918c5380b1c642828e (patch)
treee45c260fa868be8644bf3d316e3c7cc3cdc5a0eb /sys/dev/drm
parentf9627255eea8f589c728f37d9a3a6e0040a24291 (diff)
downloadFreeBSD-src-55fc74037ce1fed2313813918c5380b1c642828e.zip
FreeBSD-src-55fc74037ce1fed2313813918c5380b1c642828e.tar.gz
Update DRM from DRI CVS as of today. Notable changes include Radeon
suspend/resume support and Rage 128 pageflipping support (both of which require XFree86 from CVS), along with miscellaneous cleanups.
Diffstat (limited to 'sys/dev/drm')
-rw-r--r--sys/dev/drm/ati_pcigart.h2
-rw-r--r--sys/dev/drm/drm.h2
-rw-r--r--sys/dev/drm/drmP.h21
-rw-r--r--sys/dev/drm/drm_agpsupport.h20
-rw-r--r--sys/dev/drm/drm_auth.h1
-rw-r--r--sys/dev/drm/drm_bufs.h158
-rw-r--r--sys/dev/drm/drm_context.h1
-rw-r--r--sys/dev/drm/drm_dma.h42
-rw-r--r--sys/dev/drm/drm_drv.h2
-rw-r--r--sys/dev/drm/drm_memory.h361
-rw-r--r--sys/dev/drm/drm_memory_debug.h413
-rw-r--r--sys/dev/drm/drm_os_freebsd.h70
-rw-r--r--sys/dev/drm/drm_pci.h67
-rw-r--r--sys/dev/drm/drm_sarea.h29
-rw-r--r--sys/dev/drm/drm_scatter.h1
-rw-r--r--sys/dev/drm/drm_sysctl.h28
-rw-r--r--sys/dev/drm/mga.h2
-rw-r--r--sys/dev/drm/mga_dma.c22
-rw-r--r--sys/dev/drm/mga_drv.h12
-rw-r--r--sys/dev/drm/mga_irq.c13
-rw-r--r--sys/dev/drm/mga_warp.c1
-rw-r--r--sys/dev/drm/r128.h14
-rw-r--r--sys/dev/drm/r128_cce.c96
-rw-r--r--sys/dev/drm/r128_drm.h5
-rw-r--r--sys/dev/drm/r128_drv.c1
-rw-r--r--sys/dev/drm/r128_drv.h10
-rw-r--r--sys/dev/drm/r128_irq.c13
-rw-r--r--sys/dev/drm/r128_state.c89
-rw-r--r--sys/dev/drm/radeon.h5
-rw-r--r--sys/dev/drm/radeon_cp.c153
-rw-r--r--sys/dev/drm/radeon_drm.h19
-rw-r--r--sys/dev/drm/radeon_drv.c1
-rw-r--r--sys/dev/drm/radeon_drv.h8
-rw-r--r--sys/dev/drm/radeon_irq.c14
-rw-r--r--sys/dev/drm/radeon_state.c48
35 files changed, 1061 insertions, 683 deletions
diff --git a/sys/dev/drm/ati_pcigart.h b/sys/dev/drm/ati_pcigart.h
index 0eafcc0..c37c95f 100644
--- a/sys/dev/drm/ati_pcigart.h
+++ b/sys/dev/drm/ati_pcigart.h
@@ -86,6 +86,8 @@ int DRM(ati_pcigart_init)( drm_device_t *dev,
}
}
+ DRM_MEMORYBARRIER();
+
ret = 1;
done:
diff --git a/sys/dev/drm/drm.h b/sys/dev/drm/drm.h
index 4a51aba..8430e1d 100644
--- a/sys/dev/drm/drm.h
+++ b/sys/dev/drm/drm.h
@@ -45,7 +45,7 @@
#define DRM_IOC_WRITE _IOC_WRITE
#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE
#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
-#elif defined(__FreeBSD__) || defined(__NetBSD__)
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#if defined(__FreeBSD__) && defined(XFree86Server)
/* Prevent name collision when including sys/ioccom.h */
#undef ioctl
diff --git a/sys/dev/drm/drmP.h b/sys/dev/drm/drmP.h
index 83c0285..c91d33c 100644
--- a/sys/dev/drm/drmP.h
+++ b/sys/dev/drm/drmP.h
@@ -27,6 +27,7 @@
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com>
+ *
* $FreeBSD$
*/
@@ -101,13 +102,13 @@ typedef struct drm_file drm_file_t;
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
/* Mapping helper macros */
-#define DRM_IOREMAP(map) \
+#define DRM_IOREMAP(map, dev) \
(map)->handle = DRM(ioremap)( dev, map )
-#define DRM_IOREMAP_NOCACHE(map) \
+#define DRM_IOREMAP_NOCACHE(map, dev) \
(map)->handle = DRM(ioremap_nocache)( dev, map )
-#define DRM_IOREMAPFREE(map) \
+#define DRM_IOREMAPFREE(map, dev) \
do { \
if ( (map)->handle && (map)->size ) \
DRM(ioremapfree)( map ); \
@@ -196,7 +197,8 @@ typedef struct drm_buf_entry {
drm_buf_t *buflist;
int seg_count;
int page_order;
- unsigned long *seglist;
+ vm_offset_t *seglist;
+ dma_addr_t *seglist_bus;
drm_freelist_t freelist;
} drm_buf_entry_t;
@@ -402,11 +404,8 @@ extern void DRM(mem_uninit)(void);
extern void *DRM(alloc)(size_t size, int area);
extern void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size,
int area);
-extern char *DRM(strdup)(const char *s, int area);
-extern void DRM(strfree)(char *s, int area);
extern void DRM(free)(void *pt, size_t size, int area);
extern void *DRM(ioremap)(drm_device_t *dev, drm_local_map_t *map);
-extern void *DRM(ioremap_nocache)(drm_device_t *dev, drm_local_map_t *map);
extern void DRM(ioremapfree)(drm_local_map_t *map);
#if __REALLY_HAVE_AGP
@@ -448,7 +447,7 @@ extern void DRM(reclaim_buffers)(drm_device_t *dev, DRMFILE filp);
#if __HAVE_DMA_IRQ
extern int DRM(irq_install)( drm_device_t *dev, int irq );
extern int DRM(irq_uninstall)( drm_device_t *dev );
-extern void DRM(dma_service)( DRM_IRQ_ARGS );
+extern irqreturn_t DRM(dma_service)( DRM_IRQ_ARGS );
extern void DRM(driver_irq_preinstall)( drm_device_t *dev );
extern void DRM(driver_irq_postinstall)( drm_device_t *dev );
extern void DRM(driver_irq_uninstall)( drm_device_t *dev );
@@ -565,6 +564,12 @@ extern int DRM(sg_alloc)(DRM_IOCTL_ARGS);
extern int DRM(sg_free)(DRM_IOCTL_ARGS);
#endif
+/* consistent PCI memory functions (drm_pci.h) */
+extern void *DRM(pci_alloc)(drm_device_t *dev, size_t size,
+ size_t align, dma_addr_t maxaddr,
+ dma_addr_t *busaddr);
+extern void DRM(pci_free)(drm_device_t *dev, size_t size,
+ void *vaddr, dma_addr_t busaddr);
#endif /* __KERNEL__ */
#endif /* _DRM_P_H_ */
diff --git a/sys/dev/drm/drm_agpsupport.h b/sys/dev/drm/drm_agpsupport.h
index df9ce0a..fc2f4d1 100644
--- a/sys/dev/drm/drm_agpsupport.h
+++ b/sys/dev/drm/drm_agpsupport.h
@@ -27,6 +27,7 @@
* Author:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com>
+ *
* $FreeBSD$
*/
@@ -255,25 +256,6 @@ drm_agp_head_t *DRM(agp_init)(void)
head->agpdev = agpdev;
agp_get_info(agpdev, &head->info);
head->memory = NULL;
-#if 0 /* bogus */
- switch (head->agp_info.chipset) {
- case INTEL_GENERIC: head->chipset = "Intel"; break;
- case INTEL_LX: head->chipset = "Intel 440LX"; break;
- case INTEL_BX: head->chipset = "Intel 440BX"; break;
- case INTEL_GX: head->chipset = "Intel 440GX"; break;
- case INTEL_I810: head->chipset = "Intel i810"; break;
- case VIA_GENERIC: head->chipset = "VIA"; break;
- case VIA_VP3: head->chipset = "VIA VP3"; break;
- case VIA_MVP3: head->chipset = "VIA MVP3"; break;
- case VIA_APOLLO_PRO: head->chipset = "VIA Apollo Pro"; break;
- case SIS_GENERIC: head->chipset = "SiS"; break;
- case AMD_GENERIC: head->chipset = "AMD"; break;
- case AMD_IRONGATE: head->chipset = "AMD Irongate"; break;
- case ALI_GENERIC: head->chipset = "ALi"; break;
- case ALI_M1541: head->chipset = "ALi M1541"; break;
- default:
- }
-#endif
DRM_INFO("AGP at 0x%08lx %dMB\n",
(long)head->info.ai_aperture_base,
(int)(head->info.ai_aperture_size >> 20));
diff --git a/sys/dev/drm/drm_auth.h b/sys/dev/drm/drm_auth.h
index 1e08b05..03986c5 100644
--- a/sys/dev/drm/drm_auth.h
+++ b/sys/dev/drm/drm_auth.h
@@ -27,6 +27,7 @@
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com>
+ *
* $FreeBSD$
*/
diff --git a/sys/dev/drm/drm_bufs.h b/sys/dev/drm/drm_bufs.h
index 9fab73f..e77b3bf 100644
--- a/sys/dev/drm/drm_bufs.h
+++ b/sys/dev/drm/drm_bufs.h
@@ -27,6 +27,7 @@
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com>
+ *
* $FreeBSD$
*/
@@ -136,12 +137,12 @@ int DRM(addmap)( DRM_IOCTL_ARGS )
#endif
}
#endif /* __REALLY_HAVE_MTRR */
- DRM_IOREMAP(map);
+ DRM_IOREMAP(map, dev);
break;
case _DRM_SHM:
map->handle = (void *)DRM(alloc)(map->size, DRM_MEM_SAREA);
- DRM_DEBUG( "%ld %d %p\n",
+ DRM_DEBUG( "%lu %d %p\n",
map->size, DRM(order)( map->size ), map->handle );
if ( !map->handle ) {
DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
@@ -279,31 +280,33 @@ int DRM(rmmap)( DRM_IOCTL_ARGS )
#if __HAVE_DMA
-static void DRM(cleanup_buf_error)(drm_buf_entry_t *entry)
+static void DRM(cleanup_buf_error)(drm_device_t *dev, drm_buf_entry_t *entry)
{
int i;
+#if __HAVE_PCI_DMA
if (entry->seg_count) {
for (i = 0; i < entry->seg_count; i++) {
- DRM(free)((void *)entry->seglist[i],
- entry->buf_size,
- DRM_MEM_DMA);
+ if (entry->seglist[i] != NULL)
+ DRM(pci_free)(dev, entry->buf_size,
+ (void *)entry->seglist[i],
+ entry->seglist_bus[i]);
}
DRM(free)(entry->seglist,
entry->seg_count *
sizeof(*entry->seglist),
DRM_MEM_SEGS);
+ DRM(free)(entry->seglist_bus, entry->seg_count *
+ sizeof(*entry->seglist_bus), DRM_MEM_SEGS);
entry->seg_count = 0;
}
+#endif /* __HAVE_PCI_DMA */
- if(entry->buf_count) {
- for(i = 0; i < entry->buf_count; i++) {
- if(entry->buflist[i].dev_private) {
- DRM(free)(entry->buflist[i].dev_private,
- entry->buflist[i].dev_priv_size,
- DRM_MEM_BUFS);
- }
+ if (entry->buf_count) {
+ for (i = 0; i < entry->buf_count; i++) {
+ DRM(free)(entry->buflist[i].dev_private,
+ entry->buflist[i].dev_priv_size, DRM_MEM_BUFS);
}
DRM(free)(entry->buflist,
entry->buf_count *
@@ -395,7 +398,9 @@ static int DRM(addbufs_agp)(drm_device_t *dev, drm_buf_desc_t *request)
if(!buf->dev_private) {
/* Set count correctly so we free the proper amount. */
entry->buf_count = count;
- DRM(cleanup_buf_error)(entry);
+ DRM(cleanup_buf_error)(dev, entry);
+ DRM_UNLOCK;
+ return DRM_ERR(ENOMEM);
}
memset( buf->dev_private, 0, buf->dev_priv_size );
@@ -413,7 +418,7 @@ static int DRM(addbufs_agp)(drm_device_t *dev, drm_buf_desc_t *request)
DRM_MEM_BUFS );
if(!temp_buflist) {
/* Free the entry because it isn't valid */
- DRM(cleanup_buf_error)(entry);
+ DRM(cleanup_buf_error)(dev, entry);
DRM_UNLOCK;
return DRM_ERR(ENOMEM);
}
@@ -450,7 +455,7 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request)
int total;
int page_order;
drm_buf_entry_t *entry;
- unsigned long page;
+ vm_offset_t vaddr;
drm_buf_t *buf;
int alignment;
unsigned long offset;
@@ -459,6 +464,7 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request)
int page_count;
unsigned long *temp_pagelist;
drm_buf_t **temp_buflist;
+ dma_addr_t bus_addr;
count = request->count;
order = DRM(order)(request->size);
@@ -482,42 +488,37 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request)
return DRM_ERR(ENOMEM); /* May only call once for each order */
}
- entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist),
- DRM_MEM_BUFS );
- if ( !entry->buflist ) {
- DRM_UNLOCK;
- return DRM_ERR(ENOMEM);
- }
- memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
+ entry->buflist = DRM(alloc)(count * sizeof(*entry->buflist),
+ DRM_MEM_BUFS);
+ entry->seglist = DRM(alloc)(count * sizeof(*entry->seglist),
+ DRM_MEM_SEGS);
+ entry->seglist_bus = DRM(alloc)(count * sizeof(*entry->seglist_bus),
+ DRM_MEM_SEGS);
- entry->seglist = DRM(alloc)( count * sizeof(*entry->seglist),
- DRM_MEM_SEGS );
- if ( !entry->seglist ) {
- DRM(free)( entry->buflist,
- count * sizeof(*entry->buflist),
- DRM_MEM_BUFS );
- DRM_UNLOCK;
- return DRM_ERR(ENOMEM);
- }
- memset( entry->seglist, 0, count * sizeof(*entry->seglist) );
-
- temp_pagelist = DRM(realloc)( dma->pagelist,
- dma->page_count * sizeof(*dma->pagelist),
- (dma->page_count + (count << page_order))
- * sizeof(*dma->pagelist),
- DRM_MEM_PAGES );
- if(!temp_pagelist) {
- DRM(free)( entry->buflist,
- count * sizeof(*entry->buflist),
- DRM_MEM_BUFS );
- DRM(free)( entry->seglist,
- count * sizeof(*entry->seglist),
- DRM_MEM_SEGS );
+ /* Keep the original pagelist until we know all the allocations
+ * have succeeded
+ */
+ temp_pagelist = DRM(alloc)((dma->page_count + (count << page_order)) *
+ sizeof(*dma->pagelist), DRM_MEM_PAGES);
+
+ if (entry->buflist == NULL || entry->seglist == NULL ||
+ temp_pagelist == NULL) {
+ DRM(free)(entry->buflist, count * sizeof(*entry->buflist),
+ DRM_MEM_BUFS);
+ DRM(free)(entry->seglist, count * sizeof(*entry->seglist),
+ DRM_MEM_SEGS);
+ DRM(free)(entry->seglist_bus, count *
+ sizeof(*entry->seglist_bus), DRM_MEM_SEGS);
DRM_UNLOCK;
return DRM_ERR(ENOMEM);
}
- dma->pagelist = temp_pagelist;
+ bzero(entry->buflist, count * sizeof(*entry->buflist));
+ bzero(entry->seglist, count * sizeof(*entry->seglist));
+
+ memcpy(temp_pagelist, dma->pagelist, dma->page_count *
+ sizeof(*dma->pagelist));
+
DRM_DEBUG( "pagelist: %d entries\n",
dma->page_count + (count << page_order) );
@@ -527,15 +528,28 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request)
page_count = 0;
while ( entry->buf_count < count ) {
- page = (unsigned long)DRM(alloc)( size, DRM_MEM_DMA );
- if ( !page ) break;
- entry->seglist[entry->seg_count++] = page;
+ vaddr = (vm_offset_t) DRM(pci_alloc)(dev, size, alignment,
+ 0xfffffffful, &bus_addr);
+ if (vaddr == NULL) {
+ /* Set count correctly so we free the proper amount. */
+ entry->buf_count = count;
+ entry->seg_count = count;
+ DRM(cleanup_buf_error)(dev, entry);
+ DRM(free)(temp_pagelist, (dma->page_count +
+ (count << page_order)) * sizeof(*dma->pagelist),
+ DRM_MEM_PAGES);
+ DRM_UNLOCK;
+ return DRM_ERR(ENOMEM);
+ }
+
+ entry->seglist_bus[entry->seg_count] = bus_addr;
+ entry->seglist[entry->seg_count++] = vaddr;
for ( i = 0 ; i < (1 << page_order) ; i++ ) {
DRM_DEBUG( "page %d @ 0x%08lx\n",
dma->page_count + page_count,
- page + PAGE_SIZE * i );
- dma->pagelist[dma->page_count + page_count++]
- = page + PAGE_SIZE * i;
+ (long)vaddr + PAGE_SIZE * i );
+ temp_pagelist[dma->page_count + page_count++] =
+ vaddr + PAGE_SIZE * i;
}
for ( offset = 0 ;
offset + size <= total && entry->buf_count < count ;
@@ -546,10 +560,28 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request)
buf->order = order;
buf->used = 0;
buf->offset = (dma->byte_count + byte_count + offset);
- buf->address = (void *)(page + offset);
+ buf->address = (void *)(vaddr + offset);
+ buf->bus_address = bus_addr + offset;
buf->next = NULL;
buf->pending = 0;
buf->filp = NULL;
+
+ buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T);
+ buf->dev_private = DRM(alloc)(sizeof(DRIVER_BUF_PRIV_T),
+ DRM_MEM_BUFS);
+ if (buf->dev_private == NULL) {
+ /* Set count correctly so we free the proper amount. */
+ entry->buf_count = count;
+ entry->seg_count = count;
+ DRM(cleanup_buf_error)(dev, entry);
+ DRM(free)(temp_pagelist, (dma->page_count +
+ (count << page_order)) *
+ sizeof(*dma->pagelist), DRM_MEM_PAGES );
+ DRM_UNLOCK;
+ return DRM_ERR(ENOMEM);
+ }
+ bzero(buf->dev_private, buf->dev_priv_size);
+
DRM_DEBUG( "buffer %d @ %p\n",
entry->buf_count, buf->address );
}
@@ -561,9 +593,12 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request)
(dma->buf_count + entry->buf_count)
* sizeof(*dma->buflist),
DRM_MEM_BUFS );
- if(!temp_buflist) {
+ if (temp_buflist == NULL) {
/* Free the entry because it isn't valid */
- DRM(cleanup_buf_error)(entry);
+ DRM(cleanup_buf_error)(dev, entry);
+ DRM(free)(temp_pagelist, (dma->page_count +
+ (count << page_order)) * sizeof(*dma->pagelist),
+ DRM_MEM_PAGES);
DRM_UNLOCK;
return DRM_ERR(ENOMEM);
}
@@ -573,6 +608,13 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request)
dma->buflist[i + dma->buf_count] = &entry->buflist[i];
}
+ /* No allocations failed, so now we can replace the orginal pagelist
+ * with the new one.
+ */
+ DRM(free)(dma->pagelist, dma->page_count * sizeof(*dma->pagelist),
+ DRM_MEM_PAGES);
+ dma->pagelist = temp_pagelist;
+
dma->buf_count += entry->buf_count;
dma->seg_count += entry->seg_count;
dma->page_count += entry->seg_count << page_order;
@@ -669,7 +711,7 @@ static int DRM(addbufs_sg)(drm_device_t *dev, drm_buf_desc_t *request)
if(!buf->dev_private) {
/* Set count correctly so we free the proper amount. */
entry->buf_count = count;
- DRM(cleanup_buf_error)(entry);
+ DRM(cleanup_buf_error)(dev, entry);
DRM_UNLOCK;
return DRM_ERR(ENOMEM);
}
@@ -693,7 +735,7 @@ static int DRM(addbufs_sg)(drm_device_t *dev, drm_buf_desc_t *request)
DRM_MEM_BUFS );
if(!temp_buflist) {
/* Free the entry because it isn't valid */
- DRM(cleanup_buf_error)(entry);
+ DRM(cleanup_buf_error)(dev, entry);
DRM_UNLOCK;
return DRM_ERR(ENOMEM);
}
diff --git a/sys/dev/drm/drm_context.h b/sys/dev/drm/drm_context.h
index 4e26d7c..3cedfc8 100644
--- a/sys/dev/drm/drm_context.h
+++ b/sys/dev/drm/drm_context.h
@@ -27,6 +27,7 @@
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com>
+ *
* $FreeBSD$
*/
diff --git a/sys/dev/drm/drm_dma.h b/sys/dev/drm/drm_dma.h
index 99cabba..b4bf9e4 100644
--- a/sys/dev/drm/drm_dma.h
+++ b/sys/dev/drm/drm_dma.h
@@ -70,6 +70,7 @@ void DRM(dma_takedown)(drm_device_t *dev)
/* Clear dma buffers */
for (i = 0; i <= DRM_MAX_ORDER; i++) {
+#if __HAVE_PCI_DMA
if (dma->bufs[i].seg_count) {
DRM_DEBUG("order %d: buf_count = %d,"
" seg_count = %d\n",
@@ -77,22 +78,27 @@ void DRM(dma_takedown)(drm_device_t *dev)
dma->bufs[i].buf_count,
dma->bufs[i].seg_count);
for (j = 0; j < dma->bufs[i].seg_count; j++) {
- DRM(free)((void *)dma->bufs[i].seglist[j],
- dma->bufs[i].buf_size,
- DRM_MEM_DMA);
+ if (dma->bufs[i].seglist[j] != NULL)
+ DRM(pci_free)(dev, dma->bufs[i].buf_size,
+ (void *)dma->bufs[i].seglist[j],
+ dma->bufs[i].seglist_bus[j]);
}
DRM(free)(dma->bufs[i].seglist,
dma->bufs[i].seg_count
* sizeof(*dma->bufs[0].seglist),
DRM_MEM_SEGS);
+ DRM(free)(dma->bufs[i].seglist_bus,
+ dma->bufs[i].seg_count
+ * sizeof(*dma->bufs[0].seglist_bus),
+ DRM_MEM_SEGS);
}
- if(dma->bufs[i].buf_count) {
- for(j = 0; j < dma->bufs[i].buf_count; j++) {
- if(dma->bufs[i].buflist[j].dev_private) {
- DRM(free)(dma->bufs[i].buflist[j].dev_private,
+#endif /* __HAVE_PCI_DMA */
+
+ if (dma->bufs[i].buf_count) {
+ for (j = 0; j < dma->bufs[i].buf_count; j++) {
+ DRM(free)(dma->bufs[i].buflist[j].dev_private,
dma->bufs[i].buflist[j].dev_priv_size,
DRM_MEM_BUFS);
- }
}
DRM(free)(dma->bufs[i].buflist,
dma->bufs[i].buf_count *
@@ -101,17 +107,10 @@ void DRM(dma_takedown)(drm_device_t *dev)
}
}
- if (dma->buflist) {
- DRM(free)(dma->buflist,
- dma->buf_count * sizeof(*dma->buflist),
- DRM_MEM_BUFS);
- }
-
- if (dma->pagelist) {
- DRM(free)(dma->pagelist,
- dma->page_count * sizeof(*dma->pagelist),
- DRM_MEM_PAGES);
- }
+ DRM(free)(dma->buflist, dma->buf_count * sizeof(*dma->buflist),
+ DRM_MEM_BUFS);
+ DRM(free)(dma->pagelist, dma->page_count * sizeof(*dma->pagelist),
+ DRM_MEM_PAGES);
DRM(free)(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER);
dev->dma = NULL;
}
@@ -161,6 +160,9 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
if ( !irq )
return DRM_ERR(EINVAL);
+ if (dev->dev_private == NULL)
+ return DRM_ERR(EINVAL);
+
DRM_LOCK;
if ( dev->irq ) {
DRM_UNLOCK;
@@ -215,7 +217,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
if ( retcode ) {
#elif defined(__NetBSD__)
dev->irqh = pci_intr_establish(&dev->pa.pa_pc, dev->ih, IPL_TTY,
- (int (*)(DRM_IRQ_ARGS))DRM(dma_service), dev);
+ (irqreturn_t (*)(DRM_IRQ_ARGS))DRM(dma_service), dev);
if ( !dev->irqh ) {
#endif
DRM_LOCK;
diff --git a/sys/dev/drm/drm_drv.h b/sys/dev/drm/drm_drv.h
index 464a856..6f8f8f4 100644
--- a/sys/dev/drm/drm_drv.h
+++ b/sys/dev/drm/drm_drv.h
@@ -567,7 +567,7 @@ static int DRM(takedown)( drm_device_t *dev )
mrdesc.mr_base = map->offset;
mrdesc.mr_len = map->size;
mrdesc.mr_flags = MDF_WRITECOMBINE;
- act = MEMRANGE_SET_UPDATE;
+ act = MEMRANGE_SET_REMOVE;
bcopy(DRIVER_NAME, &mrdesc.mr_owner, strlen(DRIVER_NAME));
retcode = mem_range_attr_set(&mrdesc, &act);
map->mtrr=1;
diff --git a/sys/dev/drm/drm_memory.h b/sys/dev/drm/drm_memory.h
index 0c1f91c..f4e1133 100644
--- a/sys/dev/drm/drm_memory.h
+++ b/sys/dev/drm/drm_memory.h
@@ -36,408 +36,89 @@
#if defined(__FreeBSD__) || defined(__NetBSD__)
#define malloctype DRM(M_DRM)
/* The macros conflicted in the MALLOC_DEFINE */
-
MALLOC_DEFINE(malloctype, "drm", "DRM Data Structures");
-
#undef malloctype
#endif
-typedef struct drm_mem_stats {
- const char *name;
- int succeed_count;
- int free_count;
- int fail_count;
- unsigned long bytes_allocated;
- unsigned long bytes_freed;
-} drm_mem_stats_t;
-
-static DRM_SPINTYPE DRM(mem_lock);
-static unsigned long DRM(ram_available) = 0; /* In pages */
-static unsigned long DRM(ram_used) = 0;
-static drm_mem_stats_t DRM(mem_stats)[] = {
- [DRM_MEM_DMA] = { "dmabufs" },
- [DRM_MEM_SAREA] = { "sareas" },
- [DRM_MEM_DRIVER] = { "driver" },
- [DRM_MEM_MAGIC] = { "magic" },
- [DRM_MEM_IOCTLS] = { "ioctltab" },
- [DRM_MEM_MAPS] = { "maplist" },
- [DRM_MEM_BUFS] = { "buflist" },
- [DRM_MEM_SEGS] = { "seglist" },
- [DRM_MEM_PAGES] = { "pagelist" },
- [DRM_MEM_FILES] = { "files" },
- [DRM_MEM_QUEUES] = { "queues" },
- [DRM_MEM_CMDS] = { "commands" },
- [DRM_MEM_MAPPINGS] = { "mappings" },
- [DRM_MEM_BUFLISTS] = { "buflists" },
- [DRM_MEM_AGPLISTS] = { "agplist" },
- [DRM_MEM_SGLISTS] = { "sglist" },
- [DRM_MEM_TOTALAGP] = { "totalagp" },
- [DRM_MEM_BOUNDAGP] = { "boundagp" },
- [DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
- [DRM_MEM_STUB] = { "stub" },
- { NULL, 0, } /* Last entry must be null */
-};
-
+#ifdef DEBUG_MEMORY
+#include "drm_memory_debug.h"
+#else
void DRM(mem_init)(void)
{
- drm_mem_stats_t *mem;
-
#ifdef __NetBSD__
malloc_type_attach(DRM(M_DRM));
#endif
-
- DRM_SPININIT(DRM(mem_lock), "drm memory");
-
- for (mem = DRM(mem_stats); mem->name; ++mem) {
- mem->succeed_count = 0;
- mem->free_count = 0;
- mem->fail_count = 0;
- mem->bytes_allocated = 0;
- mem->bytes_freed = 0;
- }
-
- DRM(ram_available) = 0; /* si.totalram */
- DRM(ram_used) = 0;
}
void DRM(mem_uninit)(void)
{
- DRM_SPINUNINIT(DRM(mem_lock));
}
-#ifdef __FreeBSD__
-/* drm_mem_info is called whenever a process reads /dev/drm/mem. */
-static int
-DRM(_mem_info)(drm_mem_stats_t *stats, struct sysctl_oid *oidp, void *arg1,
- int arg2, struct sysctl_req *req)
-{
- drm_mem_stats_t *pt;
- char buf[128];
- int error;
-
- DRM_SYSCTL_PRINT(" total counts "
- " | outstanding \n");
- DRM_SYSCTL_PRINT("type alloc freed fail bytes freed"
- " | allocs bytes\n\n");
- DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu |\n",
- "system", 0, 0, 0, DRM(ram_available));
- DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu |\n",
- "locked", 0, 0, 0, DRM(ram_used));
- DRM_SYSCTL_PRINT("\n");
- for (pt = stats; pt->name; pt++) {
- DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
- pt->name,
- pt->succeed_count,
- pt->free_count,
- pt->fail_count,
- pt->bytes_allocated,
- pt->bytes_freed,
- pt->succeed_count - pt->free_count,
- (long)pt->bytes_allocated
- - (long)pt->bytes_freed);
- }
- SYSCTL_OUT(req, "", 1);
-
- return 0;
-}
-
-int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS
-{
- int ret;
- drm_mem_stats_t *stats;
-
- stats = malloc(sizeof(DRM(mem_stats)), DRM(M_DRM), M_NOWAIT);
- if (stats == NULL)
- return ENOMEM;
-
- DRM_SPINLOCK(&DRM(mem_lock));
- bcopy(DRM(mem_stats), stats, sizeof(DRM(mem_stats)));
- DRM_SPINUNLOCK(&DRM(mem_lock));
-
- ret = DRM(_mem_info)(stats, oidp, arg1, arg2, req);
-
- free(stats, DRM(M_DRM));
- return ret;
-}
-#endif /* __FreeBSD__ */
-
void *DRM(alloc)(size_t size, int area)
{
- void *pt;
-
- if (!size) {
- DRM_MEM_ERROR(area, "Allocating 0 bytes\n");
- return NULL;
- }
-
- if (!(pt = malloc(size, DRM(M_DRM), M_NOWAIT))) {
- DRM_SPINLOCK(&DRM(mem_lock));
- ++DRM(mem_stats)[area].fail_count;
- DRM_SPINUNLOCK(&DRM(mem_lock));
- return NULL;
- }
- DRM_SPINLOCK(&DRM(mem_lock));
- ++DRM(mem_stats)[area].succeed_count;
- DRM(mem_stats)[area].bytes_allocated += size;
- DRM_SPINUNLOCK(&DRM(mem_lock));
- return pt;
+ return malloc(size, DRM(M_DRM), M_NOWAIT);
}
void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area)
{
void *pt;
- if (!(pt = DRM(alloc)(size, area))) return NULL;
+ pt = malloc(size, DRM(M_DRM), M_NOWAIT);
+ if (pt == NULL)
+ return NULL;
if (oldpt && oldsize) {
memcpy(pt, oldpt, oldsize);
- DRM(free)(oldpt, oldsize, area);
+ free(oldpt, DRM(M_DRM));
}
return pt;
}
-char *DRM(strdup)(const char *s, int area)
-{
- char *pt;
- int length = s ? strlen(s) : 0;
-
- if (!(pt = DRM(alloc)(length+1, area))) return NULL;
- strcpy(pt, s);
- return pt;
-}
-
-void DRM(strfree)(char *s, int area)
-{
- unsigned int size;
-
- if (!s) return;
-
- size = 1 + strlen(s);
- DRM(free)((void *)s, size, area);
-}
-
void DRM(free)(void *pt, size_t size, int area)
{
- int alloc_count;
- int free_count;
-
- if (!pt)
- DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
- else
- free(pt, DRM(M_DRM));
- DRM_SPINLOCK(&DRM(mem_lock));
- DRM(mem_stats)[area].bytes_freed += size;
- free_count = ++DRM(mem_stats)[area].free_count;
- alloc_count = DRM(mem_stats)[area].succeed_count;
- DRM_SPINUNLOCK(&DRM(mem_lock));
- if (free_count > alloc_count) {
- DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n",
- free_count, alloc_count);
- }
+ free(pt, DRM(M_DRM));
}
void *DRM(ioremap)( drm_device_t *dev, drm_local_map_t *map )
{
- void *pt;
-
- if (!map->size) {
- DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
- "Mapping 0 bytes at 0x%08lx\n", map->offset);
- return NULL;
- }
-#ifdef __NetBSD__
- map->iot = dev->pa.pa_memt;
-#endif
-
#ifdef __FreeBSD__
- if (!(pt = pmap_mapdev(map->offset, map->size))) {
+ return pmap_mapdev(map->offset, map->size);
#elif defined(__NetBSD__)
+ map->iot = dev->pa.pa_memt;
if (bus_space_map(map->iot, map->offset, map->size,
- BUS_SPACE_MAP_LINEAR, &map->ioh)) {
-#endif
- DRM_SPINLOCK(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
- DRM_SPINUNLOCK(&DRM(mem_lock));
+ BUS_SPACE_MAP_LINEAR, &map->ioh))
return NULL;
- }
-#ifdef __NetBSD__
- pt = bus_space_vaddr(map->iot, map->ioh);
+ return bus_space_vaddr(map->iot, map->ioh);
#endif
- DRM_SPINLOCK(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
- DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += map->size;
- DRM_SPINUNLOCK(&DRM(mem_lock));
- return pt;
-}
-
-/* unused so far */
-#if 0
-void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size)
-{
- void *pt;
-
- if (!size) {
- DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
- "Mapping 0 bytes at 0x%08lx\n", offset);
- return NULL;
- }
-
- /* FIXME FOR BSD */
- if (!(pt = ioremap_nocache(offset, size))) {
- DRM_SPINLOCK(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
- DRM_SPINUNLOCK(&DRM(mem_lock));
- return NULL;
- }
- DRM_SPINLOCK(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
- DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size;
- DRM_SPINUNLOCK(&DRM(mem_lock));
- return pt;
}
-#endif
void DRM(ioremapfree)(drm_local_map_t *map)
{
- int alloc_count;
- int free_count;
-
- if (map->handle == NULL)
- DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
- "Attempt to free NULL pointer\n");
- else
#ifdef __FreeBSD__
- pmap_unmapdev((vm_offset_t) map->handle, map->size);
+ pmap_unmapdev((vm_offset_t) map->handle, map->size);
#elif defined(__NetBSD__)
- bus_space_unmap(map->iot, map->ioh, map->size);
+ bus_space_unmap(map->iot, map->ioh, map->size);
#endif
-
- DRM_SPINLOCK(&DRM(mem_lock));
- DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += map->size;
- free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
- alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
- DRM_SPINUNLOCK(&DRM(mem_lock));
- if (free_count > alloc_count) {
- DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
- "Excess frees: %d frees, %d allocs\n",
- free_count, alloc_count);
- }
}
#if __REALLY_HAVE_AGP
agp_memory *DRM(alloc_agp)(int pages, u32 type)
{
- agp_memory *handle;
-
- if (!pages) {
- DRM_MEM_ERROR(DRM_MEM_TOTALAGP, "Allocating 0 pages\n");
- return NULL;
- }
-
- if ((handle = DRM(agp_allocate_memory)(pages, type))) {
- DRM_SPINLOCK(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
- DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated
- += pages << PAGE_SHIFT;
- DRM_SPINUNLOCK(&DRM(mem_lock));
- return handle;
- }
- DRM_SPINLOCK(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_TOTALAGP].fail_count;
- DRM_SPINUNLOCK(&DRM(mem_lock));
- return NULL;
+ return DRM(agp_allocate_memory)(pages, type);
}
int DRM(free_agp)(agp_memory *handle, int pages)
{
- int alloc_count;
- int free_count;
-
- if (!handle) {
- DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
- "Attempt to free NULL AGP handle\n");
- return DRM_ERR(EINVAL);
- }
-
- if (DRM(agp_free_memory)(handle)) {
- DRM_SPINLOCK(&DRM(mem_lock));
- free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count;
- alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
- DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_freed
- += pages << PAGE_SHIFT;
- DRM_SPINUNLOCK(&DRM(mem_lock));
- if (free_count > alloc_count) {
- DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
- "Excess frees: %d frees, %d allocs\n",
- free_count, alloc_count);
- }
- return 0;
- }
- return DRM_ERR(EINVAL);
+ return DRM(agp_free_memory)(handle);
}
int DRM(bind_agp)(agp_memory *handle, unsigned int start)
{
- int retcode;
- device_t dev = DRM_AGP_FIND_DEVICE();
- struct agp_memory_info info;
-
- if (!dev)
- return EINVAL;
-
- if (!handle) {
- DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
- "Attempt to bind NULL AGP handle\n");
- return DRM_ERR(EINVAL);
- }
-
- if (!(retcode = DRM(agp_bind_memory)(handle, start))) {
- DRM_SPINLOCK(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
- agp_memory_info(dev, handle, &info);
- DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated
- += info.ami_size;
- DRM_SPINUNLOCK(&DRM(mem_lock));
- return DRM_ERR(0);
- }
- DRM_SPINLOCK(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].fail_count;
- DRM_SPINUNLOCK(&DRM(mem_lock));
- return DRM_ERR(retcode);
+ return DRM(agp_bind_memory)(handle, start);
}
int DRM(unbind_agp)(agp_memory *handle)
{
- int alloc_count;
- int free_count;
- int retcode = EINVAL;
- device_t dev = DRM_AGP_FIND_DEVICE();
- struct agp_memory_info info;
-
- if (!dev)
- return EINVAL;
-
- if (!handle) {
- DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
- "Attempt to unbind NULL AGP handle\n");
- return DRM_ERR(retcode);
- }
-
- agp_memory_info(dev, handle, &info);
-
- if ((retcode = DRM(agp_unbind_memory)(handle)))
- return DRM_ERR(retcode);
-
- DRM_SPINLOCK(&DRM(mem_lock));
- free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count;
- alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
- DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed
- += info.ami_size;
- DRM_SPINUNLOCK(&DRM(mem_lock));
- if (free_count > alloc_count) {
- DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
- "Excess frees: %d frees, %d allocs\n",
- free_count, alloc_count);
- }
- return DRM_ERR(retcode);
+ return DRM(agp_unbind_memory)(handle);
}
-#endif
+#endif /* __REALLY_HAVE_AGP */
+#endif /* DEBUG_MEMORY */
diff --git a/sys/dev/drm/drm_memory_debug.h b/sys/dev/drm/drm_memory_debug.h
new file mode 100644
index 0000000..3047f92
--- /dev/null
+++ b/sys/dev/drm/drm_memory_debug.h
@@ -0,0 +1,413 @@
+/* drm_memory.h -- Memory management wrappers for DRM -*- linux-c -*-
+ * Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ * $FreeBSD$
+ */
+
+#include "drmP.h"
+
+typedef struct drm_mem_stats {
+ const char *name;
+ int succeed_count;
+ int free_count;
+ int fail_count;
+ unsigned long bytes_allocated;
+ unsigned long bytes_freed;
+} drm_mem_stats_t;
+
+static DRM_SPINTYPE DRM(mem_lock);
+static unsigned long DRM(ram_available) = 0; /* In pages */
+static unsigned long DRM(ram_used) = 0;
+static drm_mem_stats_t DRM(mem_stats)[] = {
+ [DRM_MEM_DMA] = { "dmabufs" },
+ [DRM_MEM_SAREA] = { "sareas" },
+ [DRM_MEM_DRIVER] = { "driver" },
+ [DRM_MEM_MAGIC] = { "magic" },
+ [DRM_MEM_IOCTLS] = { "ioctltab" },
+ [DRM_MEM_MAPS] = { "maplist" },
+ [DRM_MEM_BUFS] = { "buflist" },
+ [DRM_MEM_SEGS] = { "seglist" },
+ [DRM_MEM_PAGES] = { "pagelist" },
+ [DRM_MEM_FILES] = { "files" },
+ [DRM_MEM_QUEUES] = { "queues" },
+ [DRM_MEM_CMDS] = { "commands" },
+ [DRM_MEM_MAPPINGS] = { "mappings" },
+ [DRM_MEM_BUFLISTS] = { "buflists" },
+ [DRM_MEM_AGPLISTS] = { "agplist" },
+ [DRM_MEM_SGLISTS] = { "sglist" },
+ [DRM_MEM_TOTALAGP] = { "totalagp" },
+ [DRM_MEM_BOUNDAGP] = { "boundagp" },
+ [DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
+ [DRM_MEM_STUB] = { "stub" },
+ { NULL, 0, } /* Last entry must be null */
+};
+
+void DRM(mem_init)(void)
+{
+ drm_mem_stats_t *mem;
+
+#ifdef __NetBSD__
+ malloc_type_attach(DRM(M_DRM));
+#endif
+
+ DRM_SPININIT(DRM(mem_lock), "drm memory");
+
+ for (mem = DRM(mem_stats); mem->name; ++mem) {
+ mem->succeed_count = 0;
+ mem->free_count = 0;
+ mem->fail_count = 0;
+ mem->bytes_allocated = 0;
+ mem->bytes_freed = 0;
+ }
+
+ DRM(ram_available) = 0; /* si.totalram */
+ DRM(ram_used) = 0;
+}
+
+void DRM(mem_uninit)(void)
+{
+ DRM_SPINUNINIT(DRM(mem_lock));
+}
+
+#ifdef __FreeBSD__
+/* drm_mem_info is called whenever a process reads /dev/drm/mem. */
+static int
+DRM(_mem_info)(drm_mem_stats_t *stats, struct sysctl_oid *oidp, void *arg1,
+ int arg2, struct sysctl_req *req)
+{
+ drm_mem_stats_t *pt;
+ char buf[128];
+ int error;
+
+ DRM_SYSCTL_PRINT(" total counts "
+ " | outstanding \n");
+ DRM_SYSCTL_PRINT("type alloc freed fail bytes freed"
+ " | allocs bytes\n\n");
+ DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu |\n",
+ "system", 0, 0, 0, DRM(ram_available));
+ DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu |\n",
+ "locked", 0, 0, 0, DRM(ram_used));
+ DRM_SYSCTL_PRINT("\n");
+ for (pt = stats; pt->name; pt++) {
+ DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
+ pt->name,
+ pt->succeed_count,
+ pt->free_count,
+ pt->fail_count,
+ pt->bytes_allocated,
+ pt->bytes_freed,
+ pt->succeed_count - pt->free_count,
+ (long)pt->bytes_allocated
+ - (long)pt->bytes_freed);
+ }
+ SYSCTL_OUT(req, "", 1);
+
+ return 0;
+}
+
+int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS
+{
+ int ret;
+ drm_mem_stats_t *stats;
+
+ stats = malloc(sizeof(DRM(mem_stats)), DRM(M_DRM), M_NOWAIT);
+ if (stats == NULL)
+ return ENOMEM;
+
+ DRM_SPINLOCK(&DRM(mem_lock));
+ bcopy(DRM(mem_stats), stats, sizeof(DRM(mem_stats)));
+ DRM_SPINUNLOCK(&DRM(mem_lock));
+
+ ret = DRM(_mem_info)(stats, oidp, arg1, arg2, req);
+
+ free(stats, DRM(M_DRM));
+ return ret;
+}
+#endif /* __FreeBSD__ */
+
+void *DRM(alloc)(size_t size, int area)
+{
+ void *pt;
+
+ if (!size) {
+ DRM_MEM_ERROR(area, "Allocating 0 bytes\n");
+ return NULL;
+ }
+
+ if (!(pt = malloc(size, DRM(M_DRM), M_NOWAIT))) {
+ DRM_SPINLOCK(&DRM(mem_lock));
+ ++DRM(mem_stats)[area].fail_count;
+ DRM_SPINUNLOCK(&DRM(mem_lock));
+ return NULL;
+ }
+ DRM_SPINLOCK(&DRM(mem_lock));
+ ++DRM(mem_stats)[area].succeed_count;
+ DRM(mem_stats)[area].bytes_allocated += size;
+ DRM_SPINUNLOCK(&DRM(mem_lock));
+ return pt;
+}
+
+void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area)
+{
+ void *pt;
+
+ if (!(pt = DRM(alloc)(size, area))) return NULL;
+ if (oldpt && oldsize) {
+ memcpy(pt, oldpt, oldsize);
+ DRM(free)(oldpt, oldsize, area);
+ }
+ return pt;
+}
+
+void DRM(free)(void *pt, size_t size, int area)
+{
+ int alloc_count;
+ int free_count;
+
+ if (pt == NULL)
+ return;
+ free(pt, DRM(M_DRM));
+ DRM_SPINLOCK(&DRM(mem_lock));
+ DRM(mem_stats)[area].bytes_freed += size;
+ free_count = ++DRM(mem_stats)[area].free_count;
+ alloc_count = DRM(mem_stats)[area].succeed_count;
+ DRM_SPINUNLOCK(&DRM(mem_lock));
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+}
+
+void *DRM(ioremap)( drm_device_t *dev, drm_local_map_t *map )
+{
+ void *pt;
+
+ if (!map->size) {
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+ "Mapping 0 bytes at 0x%08lx\n", map->offset);
+ return NULL;
+ }
+#ifdef __NetBSD__
+ map->iot = dev->pa.pa_memt;
+#endif
+
+#ifdef __FreeBSD__
+ if (!(pt = pmap_mapdev(map->offset, map->size))) {
+#elif defined(__NetBSD__)
+ if (bus_space_map(map->iot, map->offset, map->size,
+ BUS_SPACE_MAP_LINEAR, &map->ioh)) {
+#endif
+ DRM_SPINLOCK(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
+ DRM_SPINUNLOCK(&DRM(mem_lock));
+ return NULL;
+ }
+#ifdef __NetBSD__
+ pt = bus_space_vaddr(map->iot, map->ioh);
+#endif
+ DRM_SPINLOCK(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
+ DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += map->size;
+ DRM_SPINUNLOCK(&DRM(mem_lock));
+ return pt;
+}
+
+/* unused so far */
+#if 0
+void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size)
+{
+ void *pt;
+
+ if (!size) {
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+ "Mapping 0 bytes at 0x%08lx\n", offset);
+ return NULL;
+ }
+
+ /* FIXME FOR BSD */
+ if (!(pt = ioremap_nocache(offset, size))) {
+ DRM_SPINLOCK(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
+ DRM_SPINUNLOCK(&DRM(mem_lock));
+ return NULL;
+ }
+ DRM_SPINLOCK(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
+ DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size;
+ DRM_SPINUNLOCK(&DRM(mem_lock));
+ return pt;
+}
+#endif
+
+void DRM(ioremapfree)(drm_local_map_t *map)
+{
+ int alloc_count;
+ int free_count;
+
+ if (map->handle == NULL)
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+ "Attempt to free NULL pointer\n");
+ else
+#ifdef __FreeBSD__
+ pmap_unmapdev((vm_offset_t) map->handle, map->size);
+#elif defined(__NetBSD__)
+ bus_space_unmap(map->iot, map->ioh, map->size);
+#endif
+
+ DRM_SPINLOCK(&DRM(mem_lock));
+ DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += map->size;
+ free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
+ alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
+ DRM_SPINUNLOCK(&DRM(mem_lock));
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+ "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+}
+
+#if __REALLY_HAVE_AGP
+agp_memory *DRM(alloc_agp)(int pages, u32 type)
+{
+ agp_memory *handle;
+
+ if (!pages) {
+ DRM_MEM_ERROR(DRM_MEM_TOTALAGP, "Allocating 0 pages\n");
+ return NULL;
+ }
+
+ if ((handle = DRM(agp_allocate_memory)(pages, type))) {
+ DRM_SPINLOCK(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
+ DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated
+ += pages << PAGE_SHIFT;
+ DRM_SPINUNLOCK(&DRM(mem_lock));
+ return handle;
+ }
+ DRM_SPINLOCK(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_TOTALAGP].fail_count;
+ DRM_SPINUNLOCK(&DRM(mem_lock));
+ return NULL;
+}
+
+int DRM(free_agp)(agp_memory *handle, int pages)
+{
+ int alloc_count;
+ int free_count;
+
+ if (!handle) {
+ DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
+ "Attempt to free NULL AGP handle\n");
+ return DRM_ERR(EINVAL);
+ }
+
+ if (DRM(agp_free_memory)(handle)) {
+ DRM_SPINLOCK(&DRM(mem_lock));
+ free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count;
+ alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
+ DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_freed
+ += pages << PAGE_SHIFT;
+ DRM_SPINUNLOCK(&DRM(mem_lock));
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
+ "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+ return 0;
+ }
+ return DRM_ERR(EINVAL);
+}
+
+int DRM(bind_agp)(agp_memory *handle, unsigned int start)
+{
+ int retcode;
+ device_t dev = DRM_AGP_FIND_DEVICE();
+ struct agp_memory_info info;
+
+ if (!dev)
+ return EINVAL;
+
+ if (!handle) {
+ DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
+ "Attempt to bind NULL AGP handle\n");
+ return DRM_ERR(EINVAL);
+ }
+
+ if (!(retcode = DRM(agp_bind_memory)(handle, start))) {
+ DRM_SPINLOCK(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
+ agp_memory_info(dev, handle, &info);
+ DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated
+ += info.ami_size;
+ DRM_SPINUNLOCK(&DRM(mem_lock));
+ return DRM_ERR(0);
+ }
+ DRM_SPINLOCK(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].fail_count;
+ DRM_SPINUNLOCK(&DRM(mem_lock));
+ return DRM_ERR(retcode);
+}
+
+int DRM(unbind_agp)(agp_memory *handle)
+{
+ int alloc_count;
+ int free_count;
+ int retcode = EINVAL;
+ device_t dev = DRM_AGP_FIND_DEVICE();
+ struct agp_memory_info info;
+
+ if (!dev)
+ return EINVAL;
+
+ if (!handle) {
+ DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
+ "Attempt to unbind NULL AGP handle\n");
+ return DRM_ERR(retcode);
+ }
+
+ agp_memory_info(dev, handle, &info);
+
+ if ((retcode = DRM(agp_unbind_memory)(handle)))
+ return DRM_ERR(retcode);
+
+ DRM_SPINLOCK(&DRM(mem_lock));
+ free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count;
+ alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
+ DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed
+ += info.ami_size;
+ DRM_SPINUNLOCK(&DRM(mem_lock));
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
+ "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+ return DRM_ERR(retcode);
+}
+#endif
diff --git a/sys/dev/drm/drm_os_freebsd.h b/sys/dev/drm/drm_os_freebsd.h
index 7acc59f..745b4e7 100644
--- a/sys/dev/drm/drm_os_freebsd.h
+++ b/sys/dev/drm/drm_os_freebsd.h
@@ -1,6 +1,36 @@
+/**
+ * \file drm_os_freebsd.h
+ * OS-specific #defines for FreeBSD
+ *
+ * \author Eric Anholt <anholt@FreeBSD.org>
+ */
+
/*
+ * Copyright 2003 Eric Anholt
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
* $FreeBSD$
*/
+
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/malloc.h>
@@ -27,6 +57,7 @@
#include <machine/pmap.h>
#include <machine/bus.h>
#include <machine/resource.h>
+#include <sys/endian.h>
#include <sys/mman.h>
#include <sys/rman.h>
#include <sys/memrange.h>
@@ -111,10 +142,12 @@
#define DRM_SUSER(p) suser(p)
#define DRM_TASKQUEUE_ARGS void *arg, int pending
#define DRM_IRQ_ARGS void *arg
+typedef void irqreturn_t;
+#define IRQ_HANDLED /* nothing */
+#define IRQ_NONE /* nothing */
#define DRM_DEVICE drm_device_t *dev = kdev->si_drv1
#define DRM_MALLOC(size) malloc( size, DRM(M_DRM), M_NOWAIT )
#define DRM_FREE(pt,size) free( pt, DRM(M_DRM) )
-#define DRM_VTOPHYS(addr) vtophys(addr)
/* Read/write from bus space, with byteswapping to le if necessary */
#define DRM_READ8(map, offset) *(volatile u_int8_t *) (((unsigned long)(map)->handle) + (offset))
@@ -206,10 +239,21 @@ while (!condition) { \
#define DRM_GET_USER_UNCHECKED(val, uaddr) \
((val) = fuword(uaddr), 0)
-#define DRM_WRITEMEMORYBARRIER( map ) \
- bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, 0);
-#define DRM_READMEMORYBARRIER( map ) \
- bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, BUS_SPACE_BARRIER_READ);
+/* DRM_READMEMORYBARRIER() prevents reordering of reads.
+ * DRM_WRITEMEMORYBARRIER() prevents reordering of writes.
+ * DRM_MEMORYBARRIER() prevents reordering of reads and writes.
+ */
+#if defined(__i386__)
+#define DRM_READMEMORYBARRIER() __asm __volatile( \
+ "lock; addl $0,0(%%esp)" : : : "memory");
+#define DRM_WRITEMEMORYBARRIER() __asm __volatile("" : : : "memory");
+#define DRM_MEMORYBARRIER() __asm __volatile( \
+ "lock; addl $0,0(%%esp)" : : : "memory");
+#elif defined(__alpha__)
+#define DRM_READMEMORYBARRIER() alpha_mb();
+#define DRM_WRITEMEMORYBARRIER() alpha_wmb();
+#define DRM_MEMORYBARRIER() alpha_mb();
+#endif
#define PAGE_ALIGN(addr) round_page(addr)
@@ -230,7 +274,8 @@ typedef struct drm_chipinfo
char *name;
} drm_chipinfo_t;
-#define cpu_to_le32(x) (x) /* FIXME */
+#define cpu_to_le32(x) htole32(x)
+#define le32_to_cpu(x) le32toh(x)
typedef unsigned long dma_addr_t;
typedef u_int32_t atomic_t;
@@ -356,14 +401,11 @@ find_first_zero_bit(volatile void *p, int max)
#endif
#define DRM_SYSCTL_PRINT(fmt, arg...) \
+do { \
snprintf(buf, sizeof(buf), fmt, ##arg); \
error = SYSCTL_OUT(req, buf, strlen(buf)); \
- if (error) return error;
-
-#define DRM_SYSCTL_PRINT_RET(ret, fmt, arg...) \
- snprintf(buf, sizeof(buf), fmt, ##arg); \
- error = SYSCTL_OUT(req, buf, strlen(buf)); \
- if (error) { ret; return error; }
+ if (error) return error; \
+} while (0)
#define DRM_FIND_MAP(dest, o) \
@@ -396,5 +438,7 @@ extern drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev,
extern int DRM(sysctl_init)(drm_device_t *dev);
extern int DRM(sysctl_cleanup)(drm_device_t *dev);
-/* Memory info sysctl (drm_memory.h) */
+/* Memory info sysctl (drm_memory_debug.h) */
+#ifdef DEBUG_MEMORY
extern int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS;
+#endif
diff --git a/sys/dev/drm/drm_pci.h b/sys/dev/drm/drm_pci.h
new file mode 100644
index 0000000..b853c2a
--- /dev/null
+++ b/sys/dev/drm/drm_pci.h
@@ -0,0 +1,67 @@
+/**
+ * \file drm_pci.h
+ * \brief PCI consistent, DMA-accessible memory functions.
+ *
+ * \author Eric Anholt <anholt@FreeBSD.org>
+ */
+
+/*
+ * Copyright 2003 Eric Anholt.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#include "dev/drm/drmP.h"
+
+/**********************************************************************/
+/** \name PCI memory */
+/*@{*/
+
+/**
+ * \brief Allocate a physically contiguous DMA-accessible consistent
+ * memory block.
+ */
+void *
+DRM(pci_alloc)(drm_device_t *dev, size_t size, size_t align, dma_addr_t maxaddr,
+ dma_addr_t *busaddr)
+{
+ void *vaddr;
+
+ vaddr = contigmalloc(size, DRM(M_DRM), M_WAITOK, 0ul, maxaddr, align,
+ 0);
+ *busaddr = vtophys(vaddr);
+
+ return vaddr;
+}
+
+/**
+ * \brief Free a DMA-accessible consistent memory block.
+ */
+void
+DRM(pci_free)(drm_device_t *dev, size_t size, void *vaddr, dma_addr_t busaddr)
+{
+#if __FreeBSD_version > 500000
+ contigfree(vaddr, size, DRM(M_DRM)); /* Not available on 4.x */
+#endif
+}
+
+/*@}*/
diff --git a/sys/dev/drm/drm_sarea.h b/sys/dev/drm/drm_sarea.h
index f3dc820..093aca6 100644
--- a/sys/dev/drm/drm_sarea.h
+++ b/sys/dev/drm/drm_sarea.h
@@ -1,5 +1,11 @@
-/* sarea.h -- SAREA definitions -*- linux-c -*-
+/**
+ * \file drm_sarea.h
+ * \brief SAREA definitions
*
+ * \author Michel Dänzer <michel@daenzer.net>
+ */
+
+/*
* Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
@@ -22,23 +28,23 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
- * Authors:
- * Michel Dänzer <michel@daenzer.net>
- *
* $FreeBSD$
*/
#ifndef _DRM_SAREA_H_
#define _DRM_SAREA_H_
+/** Maximum number of drawables in the SAREA */
#define SAREA_MAX_DRAWABLES 256
-typedef struct _drm_sarea_drawable_t {
+/** SAREA drawable */
+typedef struct drm_sarea_drawable {
unsigned int stamp;
unsigned int flags;
} drm_sarea_drawable_t;
-typedef struct _dri_sarea_frame_t {
+/** SAREA frame */
+typedef struct drm_sarea_frame {
unsigned int x;
unsigned int y;
unsigned int width;
@@ -46,13 +52,14 @@ typedef struct _dri_sarea_frame_t {
unsigned int fullscreen;
} drm_sarea_frame_t;
-typedef struct _drm_sarea_t {
- /* first thing is always the drm locking structure */
+/** SAREA */
+typedef struct drm_sarea {
+ /** first thing is always the DRM locking structure */
drm_hw_lock_t lock;
- /* NOT_DONE: Use readers/writer lock for drawable_lock */
+ /** \todo Use readers/writer lock for drm_sarea::drawable_lock */
drm_hw_lock_t drawable_lock;
- drm_sarea_drawable_t drawableTable[SAREA_MAX_DRAWABLES];
- drm_sarea_frame_t frame;
+ drm_sarea_drawable_t drawableTable[SAREA_MAX_DRAWABLES]; /**< drawables */
+ drm_sarea_frame_t frame; /**< frame */
drm_context_t dummy_context;
} drm_sarea_t;
diff --git a/sys/dev/drm/drm_scatter.h b/sys/dev/drm/drm_scatter.h
index 244c9ff..4da0a1b 100644
--- a/sys/dev/drm/drm_scatter.h
+++ b/sys/dev/drm/drm_scatter.h
@@ -25,6 +25,7 @@
*
* Authors:
* Gareth Hughes <gareth@valinux.com>
+ * Eric Anholt <anholt@FreeBSD.org>
*
* $FreeBSD$
*/
diff --git a/sys/dev/drm/drm_sysctl.h b/sys/dev/drm/drm_sysctl.h
index 9d47d24..aae8fc0 100644
--- a/sys/dev/drm/drm_sysctl.h
+++ b/sys/dev/drm/drm_sysctl.h
@@ -16,7 +16,9 @@ struct DRM(sysctl_list) {
int (*f) DRM_SYSCTL_HANDLER_ARGS;
} DRM(sysctl_list)[] = {
{ "name", DRM(name_info) },
+#ifdef DEBUG_MEMORY
{ "mem", DRM(mem_info) },
+#endif
{ "vm", DRM(vm_info) },
{ "clients", DRM(clients_info) },
{ "bufs", DRM(bufs_info) },
@@ -97,10 +99,10 @@ static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS
int error;
if (dev->unique) {
- DRM_SYSCTL_PRINT("%s 0x%x %s\n",
+ DRM_SYSCTL_PRINT("%s 0x%x %s",
dev->name, dev2udev(dev->devnode), dev->unique);
} else {
- DRM_SYSCTL_PRINT("%s 0x%x\n", dev->name, dev2udev(dev->devnode));
+ DRM_SYSCTL_PRINT("%s 0x%x", dev->name, dev2udev(dev->devnode));
}
SYSCTL_OUT(req, "", 1);
@@ -113,22 +115,22 @@ static int DRM(_vm_info)DRM_SYSCTL_HANDLER_ARGS
drm_device_t *dev = arg1;
drm_local_map_t *map;
drm_map_list_entry_t *listentry;
- const char *types[] = { "FB", "REG", "SHM" };
+ const char *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
const char *type;
int i=0;
char buf[128];
int error;
- DRM_SYSCTL_PRINT("slot offset size type flags "
- "address mtrr\n\n");
- error = SYSCTL_OUT(req, buf, strlen(buf));
- if (error) return error;
+ DRM_SYSCTL_PRINT("\nslot offset size type flags "
+ "address mtrr\n");
if (dev->maplist != NULL) {
TAILQ_FOREACH(listentry, dev->maplist, link) {
map = listentry->map;
- if (map->type < 0 || map->type > 2) type = "??";
- else type = types[map->type];
+ if (map->type < 0 || map->type > 4)
+ type = "??";
+ else
+ type = types[map->type];
DRM_SYSCTL_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
i,
map->offset,
@@ -137,9 +139,9 @@ static int DRM(_vm_info)DRM_SYSCTL_HANDLER_ARGS
map->flags,
(unsigned long)map->handle);
if (map->mtrr < 0) {
- DRM_SYSCTL_PRINT("none\n");
+ DRM_SYSCTL_PRINT("no\n");
} else {
- DRM_SYSCTL_PRINT("%4d\n", map->mtrr);
+ DRM_SYSCTL_PRINT("yes\n");
}
i++;
}
@@ -174,7 +176,7 @@ static int DRM(_bufs_info) DRM_SYSCTL_HANDLER_ARGS
int error;
if (!dma) return 0;
- DRM_SYSCTL_PRINT(" o size count free segs pages kB\n\n");
+ DRM_SYSCTL_PRINT("\n o size count free segs pages kB\n");
for (i = 0; i <= DRM_MAX_ORDER; i++) {
if (dma->bufs[i].buf_count)
DRM_SYSCTL_PRINT("%2d %8d %5d %5d %5d %5d %5d\n",
@@ -220,7 +222,7 @@ static int DRM(_clients_info) DRM_SYSCTL_HANDLER_ARGS
char buf[128];
int error;
- DRM_SYSCTL_PRINT("a dev pid uid magic ioctls\n\n");
+ DRM_SYSCTL_PRINT("\na dev pid uid magic ioctls\n");
TAILQ_FOREACH(priv, &dev->files, link) {
DRM_SYSCTL_PRINT("%c %3d %5d %5d %10u %10lu\n",
priv->authenticated ? 'y' : 'n',
diff --git a/sys/dev/drm/mga.h b/sys/dev/drm/mga.h
index 2ee2c3f..5a4bec9 100644
--- a/sys/dev/drm/mga.h
+++ b/sys/dev/drm/mga.h
@@ -74,7 +74,7 @@
/* Driver customization:
*/
#define DRIVER_PRETAKEDOWN() do { \
- if ( dev->dev_private ) mga_do_cleanup_dma( dev ); \
+ mga_do_cleanup_dma( dev ); \
} while (0)
/* DMA customization:
diff --git a/sys/dev/drm/mga_dma.c b/sys/dev/drm/mga_dma.c
index 5020f1e..45e6406 100644
--- a/sys/dev/drm/mga_dma.c
+++ b/sys/dev/drm/mga_dma.c
@@ -556,9 +556,9 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
(drm_mga_sarea_t *)((u8 *)dev_priv->sarea->handle +
init->sarea_priv_offset);
- DRM_IOREMAP( dev_priv->warp );
- DRM_IOREMAP( dev_priv->primary );
- DRM_IOREMAP( dev_priv->buffers );
+ DRM_IOREMAP( dev_priv->warp, dev );
+ DRM_IOREMAP( dev_priv->primary, dev );
+ DRM_IOREMAP( dev_priv->buffers, dev );
if(!dev_priv->warp->handle ||
!dev_priv->primary->handle ||
@@ -641,15 +641,23 @@ int mga_do_cleanup_dma( drm_device_t *dev )
{
DRM_DEBUG( "\n" );
+#if _HAVE_DMA_IRQ
+ /* Make sure interrupts are disabled here because the uninstall ioctl
+ * may not have been called from userspace and after dev_private
+ * is freed, it's too late.
+ */
+ if ( dev->irq ) DRM(irq_uninstall)(dev);
+#endif
+
if ( dev->dev_private ) {
drm_mga_private_t *dev_priv = dev->dev_private;
if ( dev_priv->warp != NULL )
- DRM_IOREMAPFREE( dev_priv->warp );
+ DRM_IOREMAPFREE( dev_priv->warp, dev );
if ( dev_priv->primary != NULL )
- DRM_IOREMAPFREE( dev_priv->primary );
+ DRM_IOREMAPFREE( dev_priv->primary, dev );
if ( dev_priv->buffers != NULL )
- DRM_IOREMAPFREE( dev_priv->buffers );
+ DRM_IOREMAPFREE( dev_priv->buffers, dev );
if ( dev_priv->head != NULL ) {
mga_freelist_cleanup( dev );
@@ -668,6 +676,8 @@ int mga_dma_init( DRM_IOCTL_ARGS )
DRM_DEVICE;
drm_mga_init_t init;
+ LOCK_TEST_WITH_RETURN( dev, filp );
+
DRM_COPY_FROM_USER_IOCTL( init, (drm_mga_init_t *)data, sizeof(init) );
switch ( init.func ) {
diff --git a/sys/dev/drm/mga_drv.h b/sys/dev/drm/mga_drv.h
index b3ebaf6..54c6926 100644
--- a/sys/dev/drm/mga_drv.h
+++ b/sys/dev/drm/mga_drv.h
@@ -133,7 +133,7 @@ extern int mga_getparam( DRM_IOCTL_ARGS );
extern int mga_warp_install_microcode( drm_mga_private_t *dev_priv );
extern int mga_warp_init( drm_mga_private_t *dev_priv );
-#define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER(dev_priv->primary)
+#define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER()
#if defined(__linux__) && defined(__alpha__)
#define MGA_BASE( reg ) ((unsigned long)(dev_priv->mmio->handle))
@@ -144,12 +144,12 @@ extern int mga_warp_init( drm_mga_private_t *dev_priv );
#define MGA_READ( reg ) (_MGA_READ((u32 *)MGA_ADDR(reg)))
#define MGA_READ8( reg ) (_MGA_READ((u8 *)MGA_ADDR(reg)))
-#define MGA_WRITE( reg, val ) do { DRM_WRITEMEMORYBARRIER(dev_priv->mmio); MGA_DEREF( reg ) = val; } while (0)
-#define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(dev_priv->mmio); MGA_DEREF8( reg ) = val; } while (0)
+#define MGA_WRITE( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF( reg ) = val; } while (0)
+#define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0)
static inline u32 _MGA_READ(u32 *addr)
{
- DRM_READMEMORYBARRIER(dev_priv->mmio);
+ DRM_MEMORYBARRIER();
return *(volatile u32 *)addr;
}
#else
@@ -228,7 +228,7 @@ do { \
if ( MGA_VERBOSE ) { \
DRM_INFO( "BEGIN_DMA( %d ) in %s\n", \
(n), __FUNCTION__ ); \
- DRM_INFO( " space=0x%x req=0x%x\n", \
+ DRM_INFO( " space=0x%x req=0x%Zx\n", \
dev_priv->prim.space, (n) * DMA_BLOCK_SIZE ); \
} \
prim = dev_priv->prim.start; \
@@ -278,7 +278,7 @@ do { \
#define DMA_WRITE( offset, val ) \
do { \
if ( MGA_VERBOSE ) { \
- DRM_INFO( " DMA_WRITE( 0x%08x ) at 0x%04x\n", \
+ DRM_INFO( " DMA_WRITE( 0x%08x ) at 0x%04Zx\n", \
(u32)(val), write + (offset) * sizeof(u32) ); \
} \
*(volatile u32 *)(prim + write + (offset) * sizeof(u32)) = val; \
diff --git a/sys/dev/drm/mga_irq.c b/sys/dev/drm/mga_irq.c
index 9b2b691..1f8f2c8 100644
--- a/sys/dev/drm/mga_irq.c
+++ b/sys/dev/drm/mga_irq.c
@@ -38,7 +38,7 @@
#include "dev/drm/mga_drm.h"
#include "dev/drm/mga_drv.h"
-void mga_dma_service( DRM_IRQ_ARGS )
+irqreturn_t mga_dma_service( DRM_IRQ_ARGS )
{
drm_device_t *dev = (drm_device_t *) arg;
drm_mga_private_t *dev_priv =
@@ -53,7 +53,9 @@ void mga_dma_service( DRM_IRQ_ARGS )
atomic_inc(&dev->vbl_received);
DRM_WAKEUP(&dev->vbl_queue);
DRM(vbl_send_signals)( dev );
+ return IRQ_HANDLED;
}
+ return IRQ_NONE;
}
int mga_vblank_wait(drm_device_t *dev, unsigned int *sequence)
@@ -95,8 +97,9 @@ void mga_driver_irq_postinstall( drm_device_t *dev ) {
void mga_driver_irq_uninstall( drm_device_t *dev ) {
drm_mga_private_t *dev_priv =
(drm_mga_private_t *)dev->dev_private;
- if ( dev_priv ) {
- /* Disable *all* interrupts */
- MGA_WRITE( MGA_IEN, 0 );
- }
+ if (!dev_priv)
+ return;
+
+ /* Disable *all* interrupts */
+ MGA_WRITE( MGA_IEN, 0 );
}
diff --git a/sys/dev/drm/mga_warp.c b/sys/dev/drm/mga_warp.c
index 06aa833..035d045 100644
--- a/sys/dev/drm/mga_warp.c
+++ b/sys/dev/drm/mga_warp.c
@@ -29,7 +29,6 @@
* $FreeBSD$
*/
-#define __NO_VERSION__
#include "dev/drm/mga.h"
#include "dev/drm/drmP.h"
#include "dev/drm/drm.h"
diff --git a/sys/dev/drm/r128.h b/sys/dev/drm/r128.h
index 29ca828..6d616d5 100644
--- a/sys/dev/drm/r128.h
+++ b/sys/dev/drm/r128.h
@@ -49,13 +49,18 @@
#define DRIVER_NAME "r128"
#define DRIVER_DESC "ATI Rage 128"
-#define DRIVER_DATE "20021029"
+#define DRIVER_DATE "20030725"
#define DRIVER_MAJOR 2
-#define DRIVER_MINOR 3
+#define DRIVER_MINOR 5
#define DRIVER_PATCHLEVEL 0
-
+/* Interface history:
+ *
+ * ?? - ??
+ * 2.4 - Add support for ycbcr textures (no new ioctls)
+ * 2.5 - Add FLIP ioctl, disable FULLSCREEN.
+ */
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { r128_cce_buffers, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 }, \
@@ -66,6 +71,7 @@
[DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)] = { r128_fullscreen, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_FLIP)] = { r128_cce_flip, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 }, \
@@ -87,7 +93,7 @@
} while (0)
#define DRIVER_PRETAKEDOWN() do { \
- if ( dev->dev_private ) r128_do_cleanup_cce( dev ); \
+ r128_do_cleanup_cce( dev ); \
} while (0)
/* DMA customization:
diff --git a/sys/dev/drm/r128_cce.c b/sys/dev/drm/r128_cce.c
index e97fece..bec4e23 100644
--- a/sys/dev/drm/r128_cce.c
+++ b/sys/dev/drm/r128_cce.c
@@ -83,8 +83,6 @@ static u32 r128_cce_microcode[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
-int r128_do_wait_for_idle( drm_r128_private_t *dev_priv );
-
int R128_READ_PLL(drm_device_t *dev, int addr)
{
drm_r128_private_t *dev_priv = dev->dev_private;
@@ -153,7 +151,7 @@ static int r128_do_wait_for_fifo( drm_r128_private_t *dev_priv, int entries )
return DRM_ERR(EBUSY);
}
-int r128_do_wait_for_idle( drm_r128_private_t *dev_priv )
+static int r128_do_wait_for_idle( drm_r128_private_t *dev_priv )
{
int i, ret;
@@ -353,7 +351,7 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev,
R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
entry->busaddr[page_ofs]);
DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n",
- entry->busaddr[page_ofs],
+ (unsigned long) entry->busaddr[page_ofs],
entry->handle + tmp_ofs );
}
@@ -541,10 +539,11 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
(drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle +
init->sarea_priv_offset);
+#if __REALLY_HAVE_AGP
if ( !dev_priv->is_pci ) {
- DRM_IOREMAP( dev_priv->cce_ring );
- DRM_IOREMAP( dev_priv->ring_rptr );
- DRM_IOREMAP( dev_priv->buffers );
+ DRM_IOREMAP( dev_priv->cce_ring, dev );
+ DRM_IOREMAP( dev_priv->ring_rptr, dev );
+ DRM_IOREMAP( dev_priv->buffers, dev );
if(!dev_priv->cce_ring->handle ||
!dev_priv->ring_rptr->handle ||
!dev_priv->buffers->handle) {
@@ -553,7 +552,9 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
r128_do_cleanup_cce( dev );
return DRM_ERR(ENOMEM);
}
- } else {
+ } else
+#endif
+ {
dev_priv->cce_ring->handle =
(void *)dev_priv->cce_ring->offset;
dev_priv->ring_rptr->handle =
@@ -615,26 +616,34 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
int r128_do_cleanup_cce( drm_device_t *dev )
{
+
+#if _HAVE_DMA_IRQ
+ /* Make sure interrupts are disabled here because the uninstall ioctl
+ * may not have been called from userspace and after dev_private
+ * is freed, it's too late.
+ */
+ if ( dev->irq ) DRM(irq_uninstall)(dev);
+#endif
+
if ( dev->dev_private ) {
drm_r128_private_t *dev_priv = dev->dev_private;
-#if __REALLY_HAVE_SG
+#if __REALLY_HAVE_AGP
if ( !dev_priv->is_pci ) {
-#endif
if ( dev_priv->cce_ring != NULL )
- DRM_IOREMAPFREE( dev_priv->cce_ring );
+ DRM_IOREMAPFREE( dev_priv->cce_ring, dev );
if ( dev_priv->ring_rptr != NULL )
- DRM_IOREMAPFREE( dev_priv->ring_rptr );
+ DRM_IOREMAPFREE( dev_priv->ring_rptr, dev );
if ( dev_priv->buffers != NULL )
- DRM_IOREMAPFREE( dev_priv->buffers );
-#if __REALLY_HAVE_SG
- } else {
+ DRM_IOREMAPFREE( dev_priv->buffers, dev );
+ } else
+#endif
+ {
if (!DRM(ati_pcigart_cleanup)( dev,
dev_priv->phys_pci_gart,
dev_priv->bus_pci_gart ))
DRM_ERROR( "failed to cleanup PCI GART!\n" );
}
-#endif
DRM(free)( dev->dev_private, sizeof(drm_r128_private_t),
DRM_MEM_DRIVER );
@@ -651,6 +660,8 @@ int r128_cce_init( DRM_IOCTL_ARGS )
DRM_DEBUG( "\n" );
+ LOCK_TEST_WITH_RETURN( dev, filp );
+
DRM_COPY_FROM_USER_IOCTL( init, (drm_r128_init_t *)data, sizeof(init) );
switch ( init.func ) {
@@ -771,59 +782,8 @@ int r128_engine_reset( DRM_IOCTL_ARGS )
return r128_do_engine_reset( dev );
}
-
-/* ================================================================
- * Fullscreen mode
- */
-
-static int r128_do_init_pageflip( drm_device_t *dev )
-{
- drm_r128_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG( "\n" );
-
- dev_priv->crtc_offset = R128_READ( R128_CRTC_OFFSET );
- dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL );
-
- R128_WRITE( R128_CRTC_OFFSET, dev_priv->front_offset );
- R128_WRITE( R128_CRTC_OFFSET_CNTL,
- dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL );
-
- dev_priv->page_flipping = 1;
- dev_priv->current_page = 0;
-
- return 0;
-}
-
-int r128_do_cleanup_pageflip( drm_device_t *dev )
-{
- drm_r128_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG( "\n" );
-
- R128_WRITE( R128_CRTC_OFFSET, dev_priv->crtc_offset );
- R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
-
- dev_priv->page_flipping = 0;
- dev_priv->current_page = 0;
-
- return 0;
-}
-
int r128_fullscreen( DRM_IOCTL_ARGS )
{
- DRM_DEVICE;
- drm_r128_fullscreen_t fs;
-
- LOCK_TEST_WITH_RETURN( dev, filp );
-
- DRM_COPY_FROM_USER_IOCTL( fs, (drm_r128_fullscreen_t *)data, sizeof(fs) );
-
- switch ( fs.func ) {
- case R128_INIT_FULLSCREEN:
- return r128_do_init_pageflip( dev );
- case R128_CLEANUP_FULLSCREEN:
- return r128_do_cleanup_pageflip( dev );
- }
-
return DRM_ERR(EINVAL);
}
@@ -916,7 +876,7 @@ drm_buf_t *r128_freelist_get( drm_device_t *dev )
DRM_UDELAY( 1 );
}
- DRM_ERROR( "returning NULL!\n" );
+ DRM_DEBUG( "returning NULL!\n" );
return NULL;
}
diff --git a/sys/dev/drm/r128_drm.h b/sys/dev/drm/r128_drm.h
index be26ca4..45c6bf6 100644
--- a/sys/dev/drm/r128_drm.h
+++ b/sys/dev/drm/r128_drm.h
@@ -164,8 +164,10 @@ typedef struct drm_r128_sarea {
unsigned int last_dispatch;
drm_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1];
- int tex_age[R128_NR_TEX_HEAPS];
+ unsigned int tex_age[R128_NR_TEX_HEAPS];
int ctx_owner;
+ int pfAllowPageFlip; /* number of 3d windows (0,1,2 or more) */
+ int pfCurrentPage; /* which buffer is being displayed? */
} drm_r128_sarea_t;
@@ -193,6 +195,7 @@ typedef struct drm_r128_sarea {
#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t)
#define DRM_IOCTL_R128_CLEAR2 DRM_IOW( 0x51, drm_r128_clear2_t)
#define DRM_IOCTL_R128_GETPARAM DRM_IOW( 0x52, drm_r128_getparam_t)
+#define DRM_IOCTL_R128_FLIP DRM_IO( 0x53)
typedef struct drm_r128_init {
enum {
diff --git a/sys/dev/drm/r128_drv.c b/sys/dev/drm/r128_drv.c
index 622190a..b2d6fbc 100644
--- a/sys/dev/drm/r128_drv.c
+++ b/sys/dev/drm/r128_drv.c
@@ -75,6 +75,7 @@ drm_chipinfo_t DRM(devicelist)[] = {
#include "dev/drm/drm_ioctl.h"
#include "dev/drm/drm_lock.h"
#include "dev/drm/drm_memory.h"
+#include "dev/drm/drm_pci.h"
#include "dev/drm/drm_sysctl.h"
#include "dev/drm/drm_vm.h"
#if __HAVE_SG
diff --git a/sys/dev/drm/r128_drv.h b/sys/dev/drm/r128_drv.h
index 6252838..14118ff 100644
--- a/sys/dev/drm/r128_drv.h
+++ b/sys/dev/drm/r128_drv.h
@@ -149,6 +149,7 @@ extern int r128_do_cleanup_pageflip( drm_device_t *dev );
/* r128_state.c */
extern int r128_cce_clear( DRM_IOCTL_ARGS );
extern int r128_cce_swap( DRM_IOCTL_ARGS );
+extern int r128_cce_flip( DRM_IOCTL_ARGS );
extern int r128_cce_vertex( DRM_IOCTL_ARGS );
extern int r128_cce_indices( DRM_IOCTL_ARGS );
extern int r128_cce_blit( DRM_IOCTL_ARGS );
@@ -345,13 +346,20 @@ extern int r128_cce_indirect( DRM_IOCTL_ARGS );
#define R128_CCE_VC_CNTL_PRIM_WALK_RING 0x00000030
#define R128_CCE_VC_CNTL_NUM_SHIFT 16
+#define R128_DATATYPE_VQ 0
+#define R128_DATATYPE_CI4 1
#define R128_DATATYPE_CI8 2
#define R128_DATATYPE_ARGB1555 3
#define R128_DATATYPE_RGB565 4
#define R128_DATATYPE_RGB888 5
#define R128_DATATYPE_ARGB8888 6
#define R128_DATATYPE_RGB332 7
+#define R128_DATATYPE_Y8 8
#define R128_DATATYPE_RGB8 9
+#define R128_DATATYPE_CI16 10
+#define R128_DATATYPE_YVYU422 11
+#define R128_DATATYPE_VYUY422 12
+#define R128_DATATYPE_AYUV444 14
#define R128_DATATYPE_ARGB4444 15
/* Constants */
@@ -442,7 +450,7 @@ do { \
#if defined(__powerpc__)
#define r128_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring )
#else
-#define r128_flush_write_combine() DRM_WRITEMEMORYBARRIER(dev_priv->ring_rptr)
+#define r128_flush_write_combine() DRM_WRITEMEMORYBARRIER()
#endif
diff --git a/sys/dev/drm/r128_irq.c b/sys/dev/drm/r128_irq.c
index 5fb8f22..df82942 100644
--- a/sys/dev/drm/r128_irq.c
+++ b/sys/dev/drm/r128_irq.c
@@ -38,7 +38,7 @@
#include "dev/drm/r128_drm.h"
#include "dev/drm/r128_drv.h"
-void r128_dma_service( DRM_IRQ_ARGS )
+irqreturn_t r128_dma_service( DRM_IRQ_ARGS )
{
drm_device_t *dev = (drm_device_t *) arg;
drm_r128_private_t *dev_priv =
@@ -53,7 +53,9 @@ void r128_dma_service( DRM_IRQ_ARGS )
atomic_inc(&dev->vbl_received);
DRM_WAKEUP(&dev->vbl_queue);
DRM(vbl_send_signals)( dev );
+ return IRQ_HANDLED;
}
+ return IRQ_NONE;
}
int DRM(vblank_wait)(drm_device_t *dev, unsigned int *sequence)
@@ -95,8 +97,9 @@ void r128_driver_irq_postinstall( drm_device_t *dev ) {
void r128_driver_irq_uninstall( drm_device_t *dev ) {
drm_r128_private_t *dev_priv =
(drm_r128_private_t *)dev->dev_private;
- if ( dev_priv ) {
- /* Disable *all* interrupts */
- R128_WRITE( R128_GEN_INT_CNTL, 0 );
- }
+ if (!dev_priv)
+ return;
+
+ /* Disable *all* interrupts */
+ R128_WRITE( R128_GEN_INT_CNTL, 0 );
}
diff --git a/sys/dev/drm/r128_state.c b/sys/dev/drm/r128_state.c
index 9f22104..b7b05e2 100644
--- a/sys/dev/drm/r128_state.c
+++ b/sys/dev/drm/r128_state.c
@@ -502,8 +502,16 @@ static void r128_cce_dispatch_swap( drm_device_t *dev )
R128_GMC_AUX_CLIP_DIS |
R128_GMC_WR_MSK_DIS );
- OUT_RING( dev_priv->back_pitch_offset_c );
- OUT_RING( dev_priv->front_pitch_offset_c );
+ /* Make this work even if front & back are flipped:
+ */
+ if (dev_priv->current_page == 0) {
+ OUT_RING( dev_priv->back_pitch_offset_c );
+ OUT_RING( dev_priv->front_pitch_offset_c );
+ }
+ else {
+ OUT_RING( dev_priv->front_pitch_offset_c );
+ OUT_RING( dev_priv->back_pitch_offset_c );
+ }
OUT_RING( (x << 16) | y );
OUT_RING( (x << 16) | y );
@@ -530,7 +538,10 @@ static void r128_cce_dispatch_flip( drm_device_t *dev )
{
drm_r128_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
- DRM_DEBUG( "page=%d\n", dev_priv->current_page );
+ DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
+ __FUNCTION__,
+ dev_priv->current_page,
+ dev_priv->sarea_priv->pfCurrentPage);
#if R128_PERFORMANCE_BOXES
/* Do some trivial performance monitoring...
@@ -545,10 +556,8 @@ static void r128_cce_dispatch_flip( drm_device_t *dev )
if ( dev_priv->current_page == 0 ) {
OUT_RING( dev_priv->back_offset );
- dev_priv->current_page = 1;
} else {
OUT_RING( dev_priv->front_offset );
- dev_priv->current_page = 0;
}
ADVANCE_RING();
@@ -558,6 +567,8 @@ static void r128_cce_dispatch_flip( drm_device_t *dev )
* performing the swapbuffer ioctl.
*/
dev_priv->sarea_priv->last_frame++;
+ dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page =
+ 1 - dev_priv->current_page;
BEGIN_RING( 2 );
@@ -804,6 +815,8 @@ static int r128_cce_dispatch_blit( DRMFILE filp,
case R128_DATATYPE_ARGB1555:
case R128_DATATYPE_RGB565:
case R128_DATATYPE_ARGB4444:
+ case R128_DATATYPE_YVYU422:
+ case R128_DATATYPE_VYUY422:
dword_shift = 1;
break;
case R128_DATATYPE_CI8:
@@ -1266,6 +1279,62 @@ int r128_cce_clear( DRM_IOCTL_ARGS )
return 0;
}
+static int r128_do_init_pageflip( drm_device_t *dev )
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ DRM_DEBUG( "\n" );
+
+ dev_priv->crtc_offset = R128_READ( R128_CRTC_OFFSET );
+ dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL );
+
+ R128_WRITE( R128_CRTC_OFFSET, dev_priv->front_offset );
+ R128_WRITE( R128_CRTC_OFFSET_CNTL,
+ dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL );
+
+ dev_priv->page_flipping = 1;
+ dev_priv->current_page = 0;
+ dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page;
+
+ return 0;
+}
+
+int r128_do_cleanup_pageflip( drm_device_t *dev )
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ DRM_DEBUG( "\n" );
+
+ R128_WRITE( R128_CRTC_OFFSET, dev_priv->crtc_offset );
+ R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
+
+ if (dev_priv->current_page != 0)
+ r128_cce_dispatch_flip( dev );
+
+ dev_priv->page_flipping = 0;
+ return 0;
+}
+
+/* Swapping and flipping are different operations, need different ioctls.
+ * They can & should be intermixed to support multiple 3d windows.
+ */
+
+int r128_cce_flip( DRM_IOCTL_ARGS )
+{
+ DRM_DEVICE;
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+ LOCK_TEST_WITH_RETURN( dev, filp );
+
+ RING_SPACE_TEST_WITH_RETURN( dev_priv );
+
+ if (!dev_priv->page_flipping)
+ r128_do_init_pageflip( dev );
+
+ r128_cce_dispatch_flip( dev );
+
+ return 0;
+}
+
int r128_cce_swap( DRM_IOCTL_ARGS )
{
DRM_DEVICE;
@@ -1280,13 +1349,9 @@ int r128_cce_swap( DRM_IOCTL_ARGS )
if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
- if ( !dev_priv->page_flipping ) {
- r128_cce_dispatch_swap( dev );
- dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT |
- R128_UPLOAD_MASKS);
- } else {
- r128_cce_dispatch_flip( dev );
- }
+ r128_cce_dispatch_swap( dev );
+ dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT |
+ R128_UPLOAD_MASKS);
return 0;
}
diff --git a/sys/dev/drm/radeon.h b/sys/dev/drm/radeon.h
index eaff6cd..c0af52b 100644
--- a/sys/dev/drm/radeon.h
+++ b/sys/dev/drm/radeon.h
@@ -53,7 +53,7 @@
#define DRIVER_DATE "20020828"
#define DRIVER_MAJOR 1
-#define DRIVER_MINOR 8
+#define DRIVER_MINOR 9
#define DRIVER_PATCHLEVEL 0
/* Interface history:
@@ -81,6 +81,8 @@
* R200_EMIT_PP_CUBIC_OFFSETS_[0..5]. (brian)
* 1.8 - Remove need to call cleanup ioctls on last client exit (keith)
* Add 'GET' queries for starting additional clients on different VT's.
+ * 1.9 - Add DRM_IOCTL_RADEON_CP_RESUME ioctl.
+ * Add texture rectangle support for r100.
*/
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \
@@ -89,6 +91,7 @@
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)] = { radeon_cp_stop, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)] = { radeon_cp_reset, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESUME)] = { radeon_cp_resume, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)] = { radeon_engine_reset, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 }, \
diff --git a/sys/dev/drm/radeon_cp.c b/sys/dev/drm/radeon_cp.c
index ba3aa99..4cabde8 100644
--- a/sys/dev/drm/radeon_cp.c
+++ b/sys/dev/drm/radeon_cp.c
@@ -906,7 +906,7 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
entry->busaddr[page_ofs]);
DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n",
- entry->busaddr[page_ofs],
+ (unsigned long) entry->busaddr[page_ofs],
entry->handle + tmp_ofs );
}
@@ -977,10 +977,36 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
RADEON_ISYNC_CPSCRATCH_IDLEGUI) );
}
+/* Enable or disable PCI GART on the chip */
+static void radeon_set_pcigart( drm_radeon_private_t *dev_priv, int on )
+{
+ u32 tmp = RADEON_READ( RADEON_AIC_CNTL );
+
+ if ( on ) {
+ RADEON_WRITE( RADEON_AIC_CNTL, tmp | RADEON_PCIGART_TRANSLATE_EN );
+
+ /* set PCI GART page-table base address
+ */
+ RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart );
+
+ /* set address range for PCI address translate
+ */
+ RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->agp_vm_start );
+ RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->agp_vm_start
+ + dev_priv->agp_size - 1);
+
+ /* Turn off AGP aperture -- is this required for PCIGART?
+ */
+ RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */
+ RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */
+ } else {
+ RADEON_WRITE( RADEON_AIC_CNTL, tmp & ~RADEON_PCIGART_TRANSLATE_EN );
+ }
+}
+
static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
{
drm_radeon_private_t *dev_priv;
- u32 tmp;
DRM_DEBUG( "\n" );
dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
@@ -1153,10 +1179,11 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
(drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle +
init->sarea_priv_offset);
+#if __REALLY_HAVE_AGP
if ( !dev_priv->is_pci ) {
- DRM_IOREMAP( dev_priv->cp_ring );
- DRM_IOREMAP( dev_priv->ring_rptr );
- DRM_IOREMAP( dev_priv->buffers );
+ DRM_IOREMAP( dev_priv->cp_ring, dev );
+ DRM_IOREMAP( dev_priv->ring_rptr, dev );
+ DRM_IOREMAP( dev_priv->buffers, dev );
if(!dev_priv->cp_ring->handle ||
!dev_priv->ring_rptr->handle ||
!dev_priv->buffers->handle) {
@@ -1165,7 +1192,9 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
radeon_do_cleanup_cp(dev);
return DRM_ERR(EINVAL);
}
- } else {
+ } else
+#endif
+ {
dev_priv->cp_ring->handle =
(void *)dev_priv->cp_ring->offset;
dev_priv->ring_rptr->handle =
@@ -1212,8 +1241,13 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
-#if __REALLY_HAVE_SG
- if ( dev_priv->is_pci ) {
+#if __REALLY_HAVE_AGP
+ if ( !dev_priv->is_pci ) {
+ /* Turn off PCI GART */
+ radeon_set_pcigart( dev_priv, 0 );
+ } else
+#endif
+ {
if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,
&dev_priv->bus_pci_gart)) {
DRM_ERROR( "failed to init PCI GART!\n" );
@@ -1221,36 +1255,10 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
radeon_do_cleanup_cp(dev);
return DRM_ERR(ENOMEM);
}
- /* Turn on PCI GART
- */
- tmp = RADEON_READ( RADEON_AIC_CNTL )
- | RADEON_PCIGART_TRANSLATE_EN;
- RADEON_WRITE( RADEON_AIC_CNTL, tmp );
-
- /* set PCI GART page-table base address
- */
- RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart );
- /* set address range for PCI address translate
- */
- RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->agp_vm_start );
- RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->agp_vm_start
- + dev_priv->agp_size - 1);
-
- /* Turn off AGP aperture -- is this required for PCIGART?
- */
- RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */
- RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */
- } else {
-#endif /* __REALLY_HAVE_SG */
- /* Turn off PCI GART
- */
- tmp = RADEON_READ( RADEON_AIC_CNTL )
- & ~RADEON_PCIGART_TRANSLATE_EN;
- RADEON_WRITE( RADEON_AIC_CNTL, tmp );
-#if __REALLY_HAVE_SG
+ /* Turn on PCI GART */
+ radeon_set_pcigart( dev_priv, 1 );
}
-#endif /* __REALLY_HAVE_SG */
radeon_cp_load_microcode( dev_priv );
radeon_cp_init_ring_buffer( dev, dev_priv );
@@ -1268,23 +1276,32 @@ int radeon_do_cleanup_cp( drm_device_t *dev )
{
DRM_DEBUG( "\n" );
+#if _HAVE_DMA_IRQ
+ /* Make sure interrupts are disabled here because the uninstall ioctl
+ * may not have been called from userspace and after dev_private
+ * is freed, it's too late.
+ */
+ if ( dev->irq ) DRM(irq_uninstall)(dev);
+#endif
+
if ( dev->dev_private ) {
drm_radeon_private_t *dev_priv = dev->dev_private;
+#if __REALLY_HAVE_AGP
if ( !dev_priv->is_pci ) {
if ( dev_priv->cp_ring != NULL )
- DRM_IOREMAPFREE( dev_priv->cp_ring );
+ DRM_IOREMAPFREE( dev_priv->cp_ring, dev );
if ( dev_priv->ring_rptr != NULL )
- DRM_IOREMAPFREE( dev_priv->ring_rptr );
+ DRM_IOREMAPFREE( dev_priv->ring_rptr, dev );
if ( dev_priv->buffers != NULL )
- DRM_IOREMAPFREE( dev_priv->buffers );
- } else {
-#if __REALLY_HAVE_SG
+ DRM_IOREMAPFREE( dev_priv->buffers, dev );
+ } else
+#endif
+ {
if (!DRM(ati_pcigart_cleanup)( dev,
dev_priv->phys_pci_gart,
dev_priv->bus_pci_gart ))
DRM_ERROR( "failed to cleanup PCI GART!\n" );
-#endif /* __REALLY_HAVE_SG */
}
DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t),
@@ -1295,11 +1312,53 @@ int radeon_do_cleanup_cp( drm_device_t *dev )
return 0;
}
+/* This code will reinit the Radeon CP hardware after a resume from disc.
+ * AFAIK, it would be very difficult to pickle the state at suspend time, so
+ * here we make sure that all Radeon hardware initialisation is re-done without
+ * affecting running applications.
+ *
+ * Charl P. Botha <http://cpbotha.net>
+ */
+static int radeon_do_resume_cp( drm_device_t *dev )
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ if ( !dev_priv ) {
+ DRM_ERROR( "Called with no initialization\n" );
+ return DRM_ERR( EINVAL );
+ }
+
+ DRM_DEBUG("Starting radeon_do_resume_cp()\n");
+
+#if __REALLY_HAVE_AGP
+ if ( !dev_priv->is_pci ) {
+ /* Turn off PCI GART */
+ radeon_set_pcigart( dev_priv, 0 );
+ } else
+#endif
+ {
+ /* Turn on PCI GART */
+ radeon_set_pcigart( dev_priv, 1 );
+ }
+
+ radeon_cp_load_microcode( dev_priv );
+ radeon_cp_init_ring_buffer( dev, dev_priv );
+
+ radeon_do_engine_reset( dev );
+
+ DRM_DEBUG("radeon_do_resume_cp() complete\n");
+
+ return 0;
+}
+
+
int radeon_cp_init( DRM_IOCTL_ARGS )
{
DRM_DEVICE;
drm_radeon_init_t init;
+ LOCK_TEST_WITH_RETURN( dev, filp );
+
DRM_COPY_FROM_USER_IOCTL( init, (drm_radeon_init_t *)data, sizeof(init) );
switch ( init.func ) {
@@ -1448,6 +1507,16 @@ int radeon_cp_idle( DRM_IOCTL_ARGS )
return radeon_do_cp_idle( dev_priv );
}
+/* Added by Charl P. Botha to call radeon_do_resume_cp().
+ */
+int radeon_cp_resume( DRM_IOCTL_ARGS )
+{
+ DRM_DEVICE;
+
+ return radeon_do_resume_cp(dev);
+}
+
+
int radeon_engine_reset( DRM_IOCTL_ARGS )
{
DRM_DEVICE;
diff --git a/sys/dev/drm/radeon_drm.h b/sys/dev/drm/radeon_drm.h
index 4ee73e5..c228c9e 100644
--- a/sys/dev/drm/radeon_drm.h
+++ b/sys/dev/drm/radeon_drm.h
@@ -143,7 +143,10 @@
#define R200_EMIT_PP_CUBIC_OFFSETS_4 70
#define R200_EMIT_PP_CUBIC_FACES_5 71
#define R200_EMIT_PP_CUBIC_OFFSETS_5 72
-#define RADEON_MAX_STATE_PACKETS 73
+#define RADEON_EMIT_PP_TEX_SIZE_0 73
+#define RADEON_EMIT_PP_TEX_SIZE_1 74
+#define RADEON_EMIT_PP_TEX_SIZE_2 75
+#define RADEON_MAX_STATE_PACKETS 76
/* Commands understood by cmd_buffer ioctl. More can be added but
@@ -325,12 +328,6 @@ typedef struct {
typedef struct {
- unsigned char next, prev;
- unsigned char in_use;
- int age;
-} drm_radeon_tex_region_t;
-
-typedef struct {
/* The channel for communication of state information to the
* kernel on firing a vertex buffer with either of the
* obsoleted vertex/index ioctls.
@@ -352,8 +349,8 @@ typedef struct {
unsigned int last_dispatch;
unsigned int last_clear;
- drm_radeon_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1];
- int tex_age[RADEON_NR_TEX_HEAPS];
+ drm_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1];
+ unsigned int tex_age[RADEON_NR_TEX_HEAPS];
int ctx_owner;
int pfState; /* number of 3d windows (0,1,2ormore) */
int pfCurrentPage; /* which buffer is being displayed? */
@@ -393,6 +390,8 @@ typedef struct {
#define DRM_IOCTL_RADEON_INIT_HEAP DRM_IOW( 0x55, drm_radeon_mem_init_heap_t)
#define DRM_IOCTL_RADEON_IRQ_EMIT DRM_IOWR( 0x56, drm_radeon_irq_emit_t)
#define DRM_IOCTL_RADEON_IRQ_WAIT DRM_IOW( 0x57, drm_radeon_irq_wait_t)
+/* added by Charl P. Botha - see radeon_cp.c for details */
+#define DRM_IOCTL_RADEON_CP_RESUME DRM_IO(0x58)
typedef struct drm_radeon_init {
enum {
@@ -532,8 +531,10 @@ typedef struct drm_radeon_indirect {
#define RADEON_PARAM_LAST_FRAME 2
#define RADEON_PARAM_LAST_DISPATCH 3
#define RADEON_PARAM_LAST_CLEAR 4
+/* Added with DRM version 1.6. */
#define RADEON_PARAM_IRQ_NR 5
#define RADEON_PARAM_AGP_BASE 6 /* card offset of agp base */
+/* Added with DRM version 1.8. */
#define RADEON_PARAM_REGISTER_HANDLE 7 /* for drmMap() */
#define RADEON_PARAM_STATUS_HANDLE 8
#define RADEON_PARAM_SAREA_HANDLE 9
diff --git a/sys/dev/drm/radeon_drv.c b/sys/dev/drm/radeon_drv.c
index 3d83e01..115dab5 100644
--- a/sys/dev/drm/radeon_drv.c
+++ b/sys/dev/drm/radeon_drv.c
@@ -88,6 +88,7 @@ drm_chipinfo_t DRM(devicelist)[] = {
#include "dev/drm/drm_ioctl.h"
#include "dev/drm/drm_lock.h"
#include "dev/drm/drm_memory.h"
+#include "dev/drm/drm_pci.h"
#include "dev/drm/drm_vm.h"
#include "dev/drm/drm_sysctl.h"
#if __HAVE_SG
diff --git a/sys/dev/drm/radeon_drv.h b/sys/dev/drm/radeon_drv.h
index 0276ebd..e23ec0f 100644
--- a/sys/dev/drm/radeon_drv.h
+++ b/sys/dev/drm/radeon_drv.h
@@ -161,6 +161,7 @@ extern int radeon_cp_start( DRM_IOCTL_ARGS );
extern int radeon_cp_stop( DRM_IOCTL_ARGS );
extern int radeon_cp_reset( DRM_IOCTL_ARGS );
extern int radeon_cp_idle( DRM_IOCTL_ARGS );
+extern int radeon_cp_resume( DRM_IOCTL_ARGS );
extern int radeon_engine_reset( DRM_IOCTL_ARGS );
extern int radeon_fullscreen( DRM_IOCTL_ARGS );
extern int radeon_cp_buffers( DRM_IOCTL_ARGS );
@@ -583,6 +584,7 @@ extern void radeon_do_release(drm_device_t *dev);
#define RADEON_TXFORMAT_ARGB4444 5
#define RADEON_TXFORMAT_ARGB8888 6
#define RADEON_TXFORMAT_RGBA8888 7
+#define RADEON_TXFORMAT_Y8 8
#define RADEON_TXFORMAT_VYUY422 10
#define RADEON_TXFORMAT_YVYU422 11
#define RADEON_TXFORMAT_DXT1 12
@@ -669,6 +671,10 @@ extern void radeon_do_release(drm_device_t *dev);
#define R200_RE_POINTSIZE 0x2648
#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0 0x2254
+#define RADEON_PP_TEX_SIZE_0 0x1d04 /* NPOT */
+#define RADEON_PP_TEX_SIZE_1 0x1d0c
+#define RADEON_PP_TEX_SIZE_2 0x1d14
+
#define SE_VAP_CNTL__TCL_ENA_MASK 0x00000001
#define SE_VAP_CNTL__FORCE_W_TO_ONE_MASK 0x00010000
@@ -854,7 +860,7 @@ do { \
#define COMMIT_RING() do { \
/* Flush writes to ring */ \
- DRM_READMEMORYBARRIER( dev_priv->mmio ); \
+ DRM_MEMORYBARRIER(); \
GET_RING_HEAD( dev_priv ); \
RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \
/* read from PCI bus to ensure correct posting */ \
diff --git a/sys/dev/drm/radeon_irq.c b/sys/dev/drm/radeon_irq.c
index 51e0edb..bd35bf4 100644
--- a/sys/dev/drm/radeon_irq.c
+++ b/sys/dev/drm/radeon_irq.c
@@ -56,7 +56,7 @@
* tied to dma at all, this is just a hangover from dri prehistory.
*/
-void DRM(dma_service)( DRM_IRQ_ARGS )
+irqreturn_t DRM(dma_service)( DRM_IRQ_ARGS )
{
drm_device_t *dev = (drm_device_t *) arg;
drm_radeon_private_t *dev_priv =
@@ -69,7 +69,7 @@ void DRM(dma_service)( DRM_IRQ_ARGS )
stat = RADEON_READ(RADEON_GEN_INT_STATUS)
& (RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT);
if (!stat)
- return;
+ return IRQ_NONE;
/* SW interrupt */
if (stat & RADEON_SW_INT_TEST) {
@@ -85,6 +85,7 @@ void DRM(dma_service)( DRM_IRQ_ARGS )
/* Acknowledge interrupts we handle */
RADEON_WRITE(RADEON_GEN_INT_STATUS, stat);
+ return IRQ_HANDLED;
}
static __inline__ void radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv)
@@ -251,8 +252,9 @@ void DRM(driver_irq_postinstall)( drm_device_t *dev ) {
void DRM(driver_irq_uninstall)( drm_device_t *dev ) {
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *)dev->dev_private;
- if ( dev_priv ) {
- /* Disable *all* interrupts */
- RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
- }
+ if (!dev_priv)
+ return;
+
+ /* Disable *all* interrupts */
+ RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
}
diff --git a/sys/dev/drm/radeon_state.c b/sys/dev/drm/radeon_state.c
index f038250..235fa17 100644
--- a/sys/dev/drm/radeon_state.c
+++ b/sys/dev/drm/radeon_state.c
@@ -294,6 +294,9 @@ static struct {
{ R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4" },
{ R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5" },
{ R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5" },
+ { RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0" },
+ { RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1" },
+ { RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_1" },
};
@@ -887,15 +890,14 @@ typedef struct {
static void radeon_cp_dispatch_vertex( drm_device_t *dev,
drm_buf_t *buf,
- drm_radeon_tcl_prim_t *prim,
- drm_clip_rect_t *boxes,
- int nbox )
+ drm_radeon_tcl_prim_t *prim )
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_clip_rect_t box;
+ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
int offset = dev_priv->agp_buffers_offset + buf->offset + prim->start;
int numverts = (int)prim->numverts;
+ int nbox = sarea_priv->nbox;
int i = 0;
RING_LOCALS;
@@ -915,10 +917,8 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev,
do {
/* Emit the next cliprect */
if ( i < nbox ) {
- if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) ))
- return;
-
- radeon_emit_clip_rect( dev_priv, &box );
+ radeon_emit_clip_rect( dev_priv,
+ &sarea_priv->boxes[i] );
}
/* Emit the vertex buffer rendering commands */
@@ -997,18 +997,17 @@ static void radeon_cp_dispatch_indirect( drm_device_t *dev,
static void radeon_cp_dispatch_indices( drm_device_t *dev,
drm_buf_t *elt_buf,
- drm_radeon_tcl_prim_t *prim,
- drm_clip_rect_t *boxes,
- int nbox )
+ drm_radeon_tcl_prim_t *prim )
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_clip_rect_t box;
+ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
int offset = dev_priv->agp_buffers_offset + prim->offset;
u32 *data;
int dwords;
int i = 0;
int start = prim->start + RADEON_INDEX_PRIM_OFFSET;
int count = (prim->finish - start) / sizeof(u16);
+ int nbox = sarea_priv->nbox;
DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n",
prim->prim,
@@ -1047,12 +1046,9 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev,
(count << RADEON_NUM_VERTICES_SHIFT) );
do {
- if ( i < nbox ) {
- if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) ))
- return;
-
- radeon_emit_clip_rect( dev_priv, &box );
- }
+ if ( i < nbox )
+ radeon_emit_clip_rect( dev_priv,
+ &sarea_priv->boxes[i] );
radeon_cp_dispatch_indirect( dev, elt_buf,
prim->start,
@@ -1452,9 +1448,7 @@ int radeon_cp_vertex( DRM_IOCTL_ARGS )
prim.numverts = vertex.count;
prim.vc_format = dev_priv->sarea_priv->vc_format;
- radeon_cp_dispatch_vertex( dev, buf, &prim,
- dev_priv->sarea_priv->boxes,
- dev_priv->sarea_priv->nbox );
+ radeon_cp_dispatch_vertex( dev, buf, &prim );
}
if (vertex.discard) {
@@ -1552,9 +1546,7 @@ int radeon_cp_indices( DRM_IOCTL_ARGS )
prim.numverts = RADEON_MAX_VB_VERTS; /* duh */
prim.vc_format = dev_priv->sarea_priv->vc_format;
- radeon_cp_dispatch_indices( dev, buf, &prim,
- dev_priv->sarea_priv->boxes,
- dev_priv->sarea_priv->nbox );
+ radeon_cp_dispatch_indices( dev, buf, &prim );
if (elts.discard) {
radeon_cp_discard_buffer( dev, buf );
}
@@ -1771,16 +1763,12 @@ int radeon_cp_vertex2( DRM_IOCTL_ARGS )
tclprim.offset = prim.numverts * 64;
tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */
- radeon_cp_dispatch_indices( dev, buf, &tclprim,
- sarea_priv->boxes,
- sarea_priv->nbox);
+ radeon_cp_dispatch_indices( dev, buf, &tclprim );
} else {
tclprim.numverts = prim.numverts;
tclprim.offset = 0; /* not used */
- radeon_cp_dispatch_vertex( dev, buf, &tclprim,
- sarea_priv->boxes,
- sarea_priv->nbox);
+ radeon_cp_dispatch_vertex( dev, buf, &tclprim );
}
if (sarea_priv->nbox == 1)
OpenPOWER on IntegriCloud