summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/drm_ioctl.c17
-rw-r--r--linux-core/drm_os_linux.h2
-rw-r--r--linux-core/drm_vm.c6
-rw-r--r--linux-core/i810_dma.c50
-rw-r--r--linux-core/i810_drv.h2
-rw-r--r--linux-core/i830_dma.c33
-rw-r--r--linux-core/i830_drv.h2
-rw-r--r--linux/Makefile.linux6
-rw-r--r--linux/drm_ioctl.h17
-rw-r--r--linux/drm_os_linux.h2
-rw-r--r--linux/drm_vm.h6
-rw-r--r--linux/i810_dma.c50
-rw-r--r--linux/i810_drv.h2
-rw-r--r--linux/i830_dma.c33
-rw-r--r--linux/i830_drv.h2
-rw-r--r--shared-core/drm_sarea.h57
-rw-r--r--shared-core/mga_dma.c13
-rw-r--r--shared-core/mga_drm.h13
-rw-r--r--shared-core/mga_drv.h12
-rw-r--r--shared-core/mga_irq.c99
-rw-r--r--shared-core/mga_state.c35
-rw-r--r--shared-core/r128_drm.h11
-rw-r--r--shared-core/r128_drv.h6
-rw-r--r--shared-core/r128_irq.c99
-rw-r--r--shared-core/r128_state.c33
-rw-r--r--shared-core/radeon_drm.h17
-rw-r--r--shared-core/radeon_drv.h45
-rw-r--r--shared-core/radeon_state.c59
-rw-r--r--shared/drm_sarea.h57
-rw-r--r--shared/mga.h12
-rw-r--r--shared/mga_dma.c13
-rw-r--r--shared/mga_drm.h13
-rw-r--r--shared/mga_drv.h12
-rw-r--r--shared/mga_irq.c99
-rw-r--r--shared/mga_state.c35
-rw-r--r--shared/r128.h10
-rw-r--r--shared/r128_drm.h11
-rw-r--r--shared/r128_drv.h6
-rw-r--r--shared/r128_irq.c99
-rw-r--r--shared/r128_state.c33
-rw-r--r--shared/radeon.h6
-rw-r--r--shared/radeon_drm.h17
-rw-r--r--shared/radeon_drv.h45
-rw-r--r--shared/radeon_state.c59
44 files changed, 1039 insertions, 217 deletions
diff --git a/linux-core/drm_ioctl.c b/linux-core/drm_ioctl.c
index 0d8a1259..01604e75 100644
--- a/linux-core/drm_ioctl.c
+++ b/linux-core/drm_ioctl.c
@@ -32,6 +32,7 @@
#define __NO_VERSION__
#include "drmP.h"
+
int DRM(irq_busid)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@@ -41,8 +42,20 @@ int DRM(irq_busid)(struct inode *inode, struct file *filp,
if (copy_from_user(&p, (drm_irq_busid_t *)arg, sizeof(p)))
return -EFAULT;
dev = pci_find_slot(p.busnum, PCI_DEVFN(p.devnum, p.funcnum));
- if (dev) p.irq = dev->irq;
- else p.irq = 0;
+ if (!dev) {
+ DRM_ERROR("pci_find_slot failed for %d:%d:%d\n",
+ p.busnum, p.devnum, p.funcnum);
+ p.irq = 0;
+ goto out;
+ }
+ if (pci_enable_device(dev) != 0) {
+ DRM_ERROR("pci_enable_device failed for %d:%d:%d\n",
+ p.busnum, p.devnum, p.funcnum);
+ p.irq = 0;
+ goto out;
+ }
+ p.irq = dev->irq;
+ out:
DRM_DEBUG("%d:%d:%d => IRQ %d\n",
p.busnum, p.devnum, p.funcnum, p.irq);
if (copy_to_user((drm_irq_busid_t *)arg, &p, sizeof(p)))
diff --git a/linux-core/drm_os_linux.h b/linux-core/drm_os_linux.h
index cf003137..e9b24356 100644
--- a/linux-core/drm_os_linux.h
+++ b/linux-core/drm_os_linux.h
@@ -74,7 +74,7 @@ do { \
ret = -EBUSY; \
break; \
} \
- schedule_timeout(max(HZ/100,1)); \
+ schedule_timeout((HZ/100 > 1) ? HZ/100 : 1); \
if (signal_pending(current)) { \
ret = -EINTR; \
break; \
diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c
index 52dfd594..683c0857 100644
--- a/linux-core/drm_vm.c
+++ b/linux-core/drm_vm.c
@@ -71,7 +71,7 @@ struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
* Find the right map
*/
- if(!dev->agp->cant_use_aperture) goto vm_nopage_error;
+ if(!dev->agp || !dev->agp->cant_use_aperture) goto vm_nopage_error;
list_for_each(list, &dev->maplist->head) {
r_list = (drm_map_list_t *)list;
@@ -408,7 +408,7 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) {
vma->vm_flags &= VM_MAYWRITE;
-#if defined(__i386__)
+#if defined(__i386__) || defined(__x86_64__)
pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
#else
/* Ye gads this is ugly. With more thought
@@ -435,7 +435,7 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
case _DRM_FRAME_BUFFER:
case _DRM_REGISTERS:
if (VM_OFFSET(vma) >= __pa(high_memory)) {
-#if defined(__i386__)
+#if defined(__i386__) || defined(__x86_64__)
if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
diff --git a/linux-core/i810_dma.c b/linux-core/i810_dma.c
index 94379bb7..13f5f64f 100644
--- a/linux-core/i810_dma.c
+++ b/linux-core/i810_dma.c
@@ -26,7 +26,7 @@
*
* Authors: Rickard E. (Rik) Faith <faith@valinux.com>
* Jeff Hartmann <jhartmann@valinux.com>
- * Keith Whitwell <keith_whitwell@yahoo.com>
+ * Keith Whitwell <keith@tungstengraphics.com>
*
*/
@@ -269,44 +269,6 @@ static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d,
return retcode;
}
-static unsigned long i810_alloc_page(drm_device_t *dev)
-{
- unsigned long address;
-
- address = __get_free_page(GFP_KERNEL);
- if(address == 0UL)
- return 0;
-
-#if LINUX_VERSION_CODE < 0x020409
- atomic_inc(&virt_to_page(address)->count);
- set_bit(PG_locked, &virt_to_page(address)->flags);
-#else
- get_page(virt_to_page(address));
-#if LINUX_VERSION_CODE < 0x020500
- LockPage(virt_to_page(address));
-#else
- SetPageLocked(virt_to_page(address));
-#endif
-#endif
- return address;
-}
-
-static void i810_free_page(drm_device_t *dev, unsigned long page)
-{
- if (page) {
-#if LINUX_VERSION_CODE < 0x020409
- atomic_dec(&virt_to_page(page)->count);
- clear_bit(PG_locked, &virt_to_page(page)->flags);
- wake_up(&virt_to_page(page)->wait);
-#else
- struct page *p = virt_to_page(page);
- put_page(p);
- unlock_page(p);
-#endif
- free_page(page);
- }
-}
-
static int i810_dma_cleanup(drm_device_t *dev)
{
drm_device_dma_t *dma = dev->dma;
@@ -321,7 +283,9 @@ static int i810_dma_cleanup(drm_device_t *dev)
dev_priv->ring.Size);
}
if(dev_priv->hw_status_page != 0UL) {
- i810_free_page(dev, dev_priv->hw_status_page);
+ pci_free_consistent(dev->pdev, PAGE_SIZE,
+ (void *)dev_priv->hw_status_page,
+ dev_priv->dma_status_page);
/* Need to rewrite hardware status page */
I810_WRITE(0x02080, 0x1ffff000);
}
@@ -481,7 +445,9 @@ static int i810_dma_initialize(drm_device_t *dev,
dev_priv->zi1 = init->depth_offset | init->pitch_bits;
/* Program Hardware Status Page */
- dev_priv->hw_status_page = i810_alloc_page(dev);
+ dev_priv->hw_status_page =
+ (unsigned long) pci_alloc_consistent(dev->pdev, PAGE_SIZE,
+ &dev_priv->dma_status_page);
if(dev_priv->hw_status_page == 0UL) {
dev->dev_private = (void *)dev_priv;
i810_dma_cleanup(dev);
@@ -491,7 +457,7 @@ static int i810_dma_initialize(drm_device_t *dev,
memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE);
DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page);
- I810_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page));
+ I810_WRITE(0x02080, dev_priv->dma_status_page);
DRM_DEBUG("Enabled hardware status page\n");
/* Now we need to init our freelist */
diff --git a/linux-core/i810_drv.h b/linux-core/i810_drv.h
index 99165cf8..106abf56 100644
--- a/linux-core/i810_drv.h
+++ b/linux-core/i810_drv.h
@@ -64,6 +64,8 @@ typedef struct drm_i810_private {
unsigned long hw_status_page;
unsigned long counter;
+ dma_addr_t dma_status_page;
+
drm_buf_t *mmap_buffer;
diff --git a/linux-core/i830_dma.c b/linux-core/i830_dma.c
index 70884373..d29e21cb 100644
--- a/linux-core/i830_dma.c
+++ b/linux-core/i830_dma.c
@@ -272,29 +272,6 @@ static int i830_dma_get_buffer(drm_device_t *dev, drm_i830_dma_t *d,
return retcode;
}
-static unsigned long i830_alloc_page(drm_device_t *dev)
-{
- unsigned long address;
-
- address = __get_free_page(GFP_KERNEL);
- if(address == 0UL)
- return 0;
-
- get_page(virt_to_page(address));
- LockPage(virt_to_page(address));
- return address;
-}
-
-static void i830_free_page(drm_device_t *dev, unsigned long page)
-{
- if (page) {
- struct page *p = virt_to_page(page);
- put_page(p);
- UnlockPage(p);
- free_page(page);
- }
-}
-
static int i830_dma_cleanup(drm_device_t *dev)
{
drm_device_dma_t *dma = dev->dma;
@@ -309,7 +286,9 @@ static int i830_dma_cleanup(drm_device_t *dev)
dev_priv->ring.Size);
}
if(dev_priv->hw_status_page != 0UL) {
- i830_free_page(dev, dev_priv->hw_status_page);
+ pci_free_consistent(dev->pdev, PAGE_SIZE,
+ (void *)dev_priv->hw_status_page,
+ dev_priv->dma_status_page);
/* Need to rewrite hardware status page */
I830_WRITE(0x02080, 0x1ffff000);
}
@@ -483,7 +462,9 @@ static int i830_dma_initialize(drm_device_t *dev,
dev_priv->depth_pitch = init->depth_pitch;
/* Program Hardware Status Page */
- dev_priv->hw_status_page = i830_alloc_page(dev);
+ dev_priv->hw_status_page =
+ (unsigned long) pci_alloc_consistent(dev->pdev, PAGE_SIZE,
+ &dev_priv->dma_status_page);
if(dev_priv->hw_status_page == 0UL) {
dev->dev_private = (void *)dev_priv;
i830_dma_cleanup(dev);
@@ -493,7 +474,7 @@ static int i830_dma_initialize(drm_device_t *dev,
memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE);
DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page);
- I830_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page));
+ I830_WRITE(0x02080, dev_priv->dma_status_page);
DRM_DEBUG("Enabled hardware status page\n");
/* Now we need to init our freelist */
diff --git a/linux-core/i830_drv.h b/linux-core/i830_drv.h
index 527d0ce3..eec640ca 100644
--- a/linux-core/i830_drv.h
+++ b/linux-core/i830_drv.h
@@ -64,6 +64,8 @@ typedef struct drm_i830_private {
unsigned long hw_status_page;
unsigned long counter;
+ dma_addr_t dma_status_page;
+
drm_buf_t *mmap_buffer;
u32 front_di1, back_di1, zi1;
diff --git a/linux/Makefile.linux b/linux/Makefile.linux
index 7c3f1db9..4505e6c1 100644
--- a/linux/Makefile.linux
+++ b/linux/Makefile.linux
@@ -44,7 +44,7 @@ LIBS =
DRMTEMPLATES = drm_auth.h drm_bufs.h drm_context.h drm_dma.h drm_drawable.h \
drm_drv.h drm_fops.h drm_init.h drm_ioctl.h drm_lists.h \
drm_lock.h drm_memory.h drm_proc.h drm_stub.h drm_vm.h
-DRMHEADERS = drm.h drmP.h
+DRMHEADERS = drm.h drmP.h drm_sarea.h
GAMMAOBJS = gamma_drv.o gamma_dma.o
GAMMAHEADERS = gamma_drv.h $(DRMHEADERS) $(DRMTEMPLATES)
@@ -52,7 +52,7 @@ GAMMAHEADERS = gamma_drv.h $(DRMHEADERS) $(DRMTEMPLATES)
TDFXOBJS = tdfx_drv.o
TDFXHEADERS = tdfx.h $(DRMHEADERS) $(DRMTEMPLATES)
-R128OBJS = r128_drv.o r128_cce.o r128_state.o
+R128OBJS = r128_drv.o r128_cce.o r128_state.o r128_irq.o
R128HEADERS = r128.h r128_drv.h r128_drm.h $(DRMHEADERS) $(DRMTEMPLATES)
RADEONOBJS = radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o
@@ -158,7 +158,7 @@ MODS += i810.o
MODS += i830.o
endif
-MGAOBJS = mga_drv.o mga_dma.o mga_state.o mga_warp.o
+MGAOBJS = mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o
MGAHEADERS = mga.h mga_drv.h mga_drm.h $(DRMHEADERS) $(DRMTEMPLATES)
I810OBJS = i810_drv.o i810_dma.o
diff --git a/linux/drm_ioctl.h b/linux/drm_ioctl.h
index 0d8a1259..01604e75 100644
--- a/linux/drm_ioctl.h
+++ b/linux/drm_ioctl.h
@@ -32,6 +32,7 @@
#define __NO_VERSION__
#include "drmP.h"
+
int DRM(irq_busid)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@@ -41,8 +42,20 @@ int DRM(irq_busid)(struct inode *inode, struct file *filp,
if (copy_from_user(&p, (drm_irq_busid_t *)arg, sizeof(p)))
return -EFAULT;
dev = pci_find_slot(p.busnum, PCI_DEVFN(p.devnum, p.funcnum));
- if (dev) p.irq = dev->irq;
- else p.irq = 0;
+ if (!dev) {
+ DRM_ERROR("pci_find_slot failed for %d:%d:%d\n",
+ p.busnum, p.devnum, p.funcnum);
+ p.irq = 0;
+ goto out;
+ }
+ if (pci_enable_device(dev) != 0) {
+ DRM_ERROR("pci_enable_device failed for %d:%d:%d\n",
+ p.busnum, p.devnum, p.funcnum);
+ p.irq = 0;
+ goto out;
+ }
+ p.irq = dev->irq;
+ out:
DRM_DEBUG("%d:%d:%d => IRQ %d\n",
p.busnum, p.devnum, p.funcnum, p.irq);
if (copy_to_user((drm_irq_busid_t *)arg, &p, sizeof(p)))
diff --git a/linux/drm_os_linux.h b/linux/drm_os_linux.h
index cf003137..e9b24356 100644
--- a/linux/drm_os_linux.h
+++ b/linux/drm_os_linux.h
@@ -74,7 +74,7 @@ do { \
ret = -EBUSY; \
break; \
} \
- schedule_timeout(max(HZ/100,1)); \
+ schedule_timeout((HZ/100 > 1) ? HZ/100 : 1); \
if (signal_pending(current)) { \
ret = -EINTR; \
break; \
diff --git a/linux/drm_vm.h b/linux/drm_vm.h
index 52dfd594..683c0857 100644
--- a/linux/drm_vm.h
+++ b/linux/drm_vm.h
@@ -71,7 +71,7 @@ struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
* Find the right map
*/
- if(!dev->agp->cant_use_aperture) goto vm_nopage_error;
+ if(!dev->agp || !dev->agp->cant_use_aperture) goto vm_nopage_error;
list_for_each(list, &dev->maplist->head) {
r_list = (drm_map_list_t *)list;
@@ -408,7 +408,7 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) {
vma->vm_flags &= VM_MAYWRITE;
-#if defined(__i386__)
+#if defined(__i386__) || defined(__x86_64__)
pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
#else
/* Ye gads this is ugly. With more thought
@@ -435,7 +435,7 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
case _DRM_FRAME_BUFFER:
case _DRM_REGISTERS:
if (VM_OFFSET(vma) >= __pa(high_memory)) {
-#if defined(__i386__)
+#if defined(__i386__) || defined(__x86_64__)
if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
diff --git a/linux/i810_dma.c b/linux/i810_dma.c
index 94379bb7..13f5f64f 100644
--- a/linux/i810_dma.c
+++ b/linux/i810_dma.c
@@ -26,7 +26,7 @@
*
* Authors: Rickard E. (Rik) Faith <faith@valinux.com>
* Jeff Hartmann <jhartmann@valinux.com>
- * Keith Whitwell <keith_whitwell@yahoo.com>
+ * Keith Whitwell <keith@tungstengraphics.com>
*
*/
@@ -269,44 +269,6 @@ static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d,
return retcode;
}
-static unsigned long i810_alloc_page(drm_device_t *dev)
-{
- unsigned long address;
-
- address = __get_free_page(GFP_KERNEL);
- if(address == 0UL)
- return 0;
-
-#if LINUX_VERSION_CODE < 0x020409
- atomic_inc(&virt_to_page(address)->count);
- set_bit(PG_locked, &virt_to_page(address)->flags);
-#else
- get_page(virt_to_page(address));
-#if LINUX_VERSION_CODE < 0x020500
- LockPage(virt_to_page(address));
-#else
- SetPageLocked(virt_to_page(address));
-#endif
-#endif
- return address;
-}
-
-static void i810_free_page(drm_device_t *dev, unsigned long page)
-{
- if (page) {
-#if LINUX_VERSION_CODE < 0x020409
- atomic_dec(&virt_to_page(page)->count);
- clear_bit(PG_locked, &virt_to_page(page)->flags);
- wake_up(&virt_to_page(page)->wait);
-#else
- struct page *p = virt_to_page(page);
- put_page(p);
- unlock_page(p);
-#endif
- free_page(page);
- }
-}
-
static int i810_dma_cleanup(drm_device_t *dev)
{
drm_device_dma_t *dma = dev->dma;
@@ -321,7 +283,9 @@ static int i810_dma_cleanup(drm_device_t *dev)
dev_priv->ring.Size);
}
if(dev_priv->hw_status_page != 0UL) {
- i810_free_page(dev, dev_priv->hw_status_page);
+ pci_free_consistent(dev->pdev, PAGE_SIZE,
+ (void *)dev_priv->hw_status_page,
+ dev_priv->dma_status_page);
/* Need to rewrite hardware status page */
I810_WRITE(0x02080, 0x1ffff000);
}
@@ -481,7 +445,9 @@ static int i810_dma_initialize(drm_device_t *dev,
dev_priv->zi1 = init->depth_offset | init->pitch_bits;
/* Program Hardware Status Page */
- dev_priv->hw_status_page = i810_alloc_page(dev);
+ dev_priv->hw_status_page =
+ (unsigned long) pci_alloc_consistent(dev->pdev, PAGE_SIZE,
+ &dev_priv->dma_status_page);
if(dev_priv->hw_status_page == 0UL) {
dev->dev_private = (void *)dev_priv;
i810_dma_cleanup(dev);
@@ -491,7 +457,7 @@ static int i810_dma_initialize(drm_device_t *dev,
memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE);
DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page);
- I810_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page));
+ I810_WRITE(0x02080, dev_priv->dma_status_page);
DRM_DEBUG("Enabled hardware status page\n");
/* Now we need to init our freelist */
diff --git a/linux/i810_drv.h b/linux/i810_drv.h
index 99165cf8..106abf56 100644
--- a/linux/i810_drv.h
+++ b/linux/i810_drv.h
@@ -64,6 +64,8 @@ typedef struct drm_i810_private {
unsigned long hw_status_page;
unsigned long counter;
+ dma_addr_t dma_status_page;
+
drm_buf_t *mmap_buffer;
diff --git a/linux/i830_dma.c b/linux/i830_dma.c
index 70884373..d29e21cb 100644
--- a/linux/i830_dma.c
+++ b/linux/i830_dma.c
@@ -272,29 +272,6 @@ static int i830_dma_get_buffer(drm_device_t *dev, drm_i830_dma_t *d,
return retcode;
}
-static unsigned long i830_alloc_page(drm_device_t *dev)
-{
- unsigned long address;
-
- address = __get_free_page(GFP_KERNEL);
- if(address == 0UL)
- return 0;
-
- get_page(virt_to_page(address));
- LockPage(virt_to_page(address));
- return address;
-}
-
-static void i830_free_page(drm_device_t *dev, unsigned long page)
-{
- if (page) {
- struct page *p = virt_to_page(page);
- put_page(p);
- UnlockPage(p);
- free_page(page);
- }
-}
-
static int i830_dma_cleanup(drm_device_t *dev)
{
drm_device_dma_t *dma = dev->dma;
@@ -309,7 +286,9 @@ static int i830_dma_cleanup(drm_device_t *dev)
dev_priv->ring.Size);
}
if(dev_priv->hw_status_page != 0UL) {
- i830_free_page(dev, dev_priv->hw_status_page);
+ pci_free_consistent(dev->pdev, PAGE_SIZE,
+ (void *)dev_priv->hw_status_page,
+ dev_priv->dma_status_page);
/* Need to rewrite hardware status page */
I830_WRITE(0x02080, 0x1ffff000);
}
@@ -483,7 +462,9 @@ static int i830_dma_initialize(drm_device_t *dev,
dev_priv->depth_pitch = init->depth_pitch;
/* Program Hardware Status Page */
- dev_priv->hw_status_page = i830_alloc_page(dev);
+ dev_priv->hw_status_page =
+ (unsigned long) pci_alloc_consistent(dev->pdev, PAGE_SIZE,
+ &dev_priv->dma_status_page);
if(dev_priv->hw_status_page == 0UL) {
dev->dev_private = (void *)dev_priv;
i830_dma_cleanup(dev);
@@ -493,7 +474,7 @@ static int i830_dma_initialize(drm_device_t *dev,
memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE);
DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page);
- I830_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page));
+ I830_WRITE(0x02080, dev_priv->dma_status_page);
DRM_DEBUG("Enabled hardware status page\n");
/* Now we need to init our freelist */
diff --git a/linux/i830_drv.h b/linux/i830_drv.h
index 527d0ce3..eec640ca 100644
--- a/linux/i830_drv.h
+++ b/linux/i830_drv.h
@@ -64,6 +64,8 @@ typedef struct drm_i830_private {
unsigned long hw_status_page;
unsigned long counter;
+ dma_addr_t dma_status_page;
+
drm_buf_t *mmap_buffer;
u32 front_di1, back_di1, zi1;
diff --git a/shared-core/drm_sarea.h b/shared-core/drm_sarea.h
new file mode 100644
index 00000000..cee48eee
--- /dev/null
+++ b/shared-core/drm_sarea.h
@@ -0,0 +1,57 @@
+/* sarea.h -- SAREA definitions -*- linux-c -*-
+ *
+ * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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
+ * TUNGSTEN GRAPHICS 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:
+ * Michel Dänzer <michel@daenzer.net>
+ */
+
+#ifndef _DRM_SAREA_H_
+#define _DRM_SAREA_H_
+
+#define SAREA_MAX_DRAWABLES 256
+
+typedef struct _drm_sarea_drawable_t {
+ unsigned int stamp;
+ unsigned int flags;
+} drm_sarea_drawable_t;
+
+typedef struct _dri_sarea_frame_t {
+ unsigned int x;
+ unsigned int y;
+ unsigned int width;
+ unsigned int height;
+ unsigned int fullscreen;
+} drm_sarea_frame_t;
+
+typedef struct _drm_sarea_t {
+ /* first thing is always the drm locking structure */
+ drm_hw_lock_t lock;
+ /* NOT_DONE: Use readers/writer lock for drawable_lock */
+ drm_hw_lock_t drawable_lock;
+ drm_sarea_drawable_t drawableTable[SAREA_MAX_DRAWABLES];
+ drm_sarea_frame_t frame;
+ drm_context_t dummy_context;
+} drm_sarea_t;
+
+#endif /* _DRM_SAREA_H_ */
diff --git a/shared-core/mga_dma.c b/shared-core/mga_dma.c
index a0ad70e9..22bd61f0 100644
--- a/shared-core/mga_dma.c
+++ b/shared-core/mga_dma.c
@@ -27,7 +27,7 @@
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Jeff Hartmann <jhartmann@valinux.com>
- * Keith Whitwell <keithw@valinux.com>
+ * Keith Whitwell <keith@tungstengraphics.com>
*
* Rewritten by:
* Gareth Hughes <gareth@valinux.com>
@@ -157,9 +157,18 @@ void mga_do_dma_flush( drm_mga_private_t *dev_priv )
{
drm_mga_primary_buffer_t *primary = &dev_priv->prim;
u32 head, tail;
- DMA_LOCALS;
+ u32 status = 0;
+ int i;
+ DMA_LOCALS;
DRM_DEBUG( "\n" );
+ /* We need to wait so that we can do an safe flush */
+ for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
+ status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK;
+ if ( status == MGA_ENDPRDMASTS ) break;
+ DRM_UDELAY( 1 );
+ }
+
if ( primary->tail == primary->last_flush ) {
DRM_DEBUG( " bailing out...\n" );
return;
diff --git a/shared-core/mga_drm.h b/shared-core/mga_drm.h
index 8f56beed..b19bc011 100644
--- a/shared-core/mga_drm.h
+++ b/shared-core/mga_drm.h
@@ -26,7 +26,7 @@
*
* Authors:
* Jeff Hartmann <jhartmann@valinux.com>
- * Keith Whitwell <keithw@valinux.com>
+ * Keith Whitwell <keith@tungstengraphics.com>
*
* Rewritten by:
* Gareth Hughes <gareth@valinux.com>
@@ -239,6 +239,7 @@ typedef struct _drm_mga_sarea {
#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t)
#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x47, drm_mga_iload_t)
#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x48, drm_mga_blit_t)
+#define DRM_IOCTL_MGA_GETPARAM DRM_IOWR(0x49, drm_mga_getparam_t)
typedef struct _drm_mga_warp_index {
int installed;
@@ -322,4 +323,14 @@ typedef struct _drm_mga_blit {
int source_pitch, dest_pitch;
} drm_mga_blit_t;
+/* 3.1: An ioctl to get parameters that aren't available to the 3d
+ * client any other way.
+ */
+#define MGA_PARAM_IRQ_NR 1
+
+typedef struct drm_mga_getparam {
+ int param;
+ int *value;
+} drm_mga_getparam_t;
+
#endif
diff --git a/shared-core/mga_drv.h b/shared-core/mga_drv.h
index b5f16ae2..a5085b06 100644
--- a/shared-core/mga_drv.h
+++ b/shared-core/mga_drv.h
@@ -125,6 +125,7 @@ extern int mga_dma_vertex( DRM_IOCTL_ARGS );
extern int mga_dma_indices( DRM_IOCTL_ARGS );
extern int mga_dma_iload( DRM_IOCTL_ARGS );
extern int mga_dma_blit( DRM_IOCTL_ARGS );
+extern int mga_getparam( DRM_IOCTL_ARGS );
/* mga_warp.c */
extern int mga_warp_install_microcode( drm_mga_private_t *dev_priv );
@@ -141,6 +142,7 @@ extern int mga_warp_init( drm_mga_private_t *dev_priv );
#ifdef __alpha__
#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(); MGA_DEREF( reg ) = val; } while (0)
#define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0)
@@ -152,6 +154,7 @@ static inline u32 _MGA_READ(u32 *addr)
#else
#define MGA_READ( reg ) MGA_DEREF( reg )
+#define MGA_READ8( reg ) MGA_DEREF8( reg )
#define MGA_WRITE( reg, val ) do { MGA_DEREF( reg ) = val; } while (0)
#define MGA_WRITE8( reg, val ) do { MGA_DEREF8( reg ) = val; } while (0)
#endif
@@ -345,6 +348,11 @@ do { \
/* A reduced set of the mga registers.
*/
#define MGA_CRTC_INDEX 0x1fd4
+#define MGA_CRTC_DATA 0x1fd5
+
+/* CRTC11 */
+#define MGA_VINTCLR (1 << 4)
+#define MGA_VINTEN (1 << 5)
#define MGA_ALPHACTRL 0x2c7c
#define MGA_AR0 0x1c60
@@ -416,8 +424,10 @@ do { \
#define MGA_ICLEAR 0x1e18
# define MGA_SOFTRAPICLR (1 << 0)
+# define MGA_VLINEICLR (1 << 5)
#define MGA_IEN 0x1e1c
# define MGA_SOFTRAPIEN (1 << 0)
+# define MGA_VLINEIEN (1 << 5)
#define MGA_LEN 0x1c5c
@@ -456,6 +466,8 @@ do { \
# define MGA_SRCACC_AGP (1 << 1)
#define MGA_STATUS 0x1e14
# define MGA_SOFTRAPEN (1 << 0)
+# define MGA_VSYNCPEN (1 << 4)
+# define MGA_VLINEPEN (1 << 5)
# define MGA_DWGENGSTS (1 << 16)
# define MGA_ENDPRDMASTS (1 << 17)
#define MGA_STENCIL 0x2cc8
diff --git a/shared-core/mga_irq.c b/shared-core/mga_irq.c
new file mode 100644
index 00000000..568d193f
--- /dev/null
+++ b/shared-core/mga_irq.c
@@ -0,0 +1,99 @@
+/* mga_irq.c -- IRQ handling for radeon -*- linux-c -*-
+ *
+ * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
+ *
+ * The Weather Channel (TM) funded Tungsten Graphics to develop the
+ * initial release of the Radeon 8500 driver under the XFree86 license.
+ * This notice must be preserved.
+ *
+ * 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
+ * PRECISION INSIGHT 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:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#include "mga.h"
+#include "drmP.h"
+#include "drm.h"
+#include "mga_drm.h"
+#include "mga_drv.h"
+
+void mga_dma_service( DRM_IRQ_ARGS )
+{
+ drm_device_t *dev = (drm_device_t *) arg;
+ drm_mga_private_t *dev_priv =
+ (drm_mga_private_t *)dev->dev_private;
+ int status;
+
+ status = MGA_READ( MGA_STATUS );
+
+ /* VBLANK interrupt */
+ if ( status & MGA_VLINEPEN ) {
+ MGA_WRITE( MGA_ICLEAR, MGA_VLINEICLR );
+ atomic_inc(&dev->vbl_received);
+ DRM_WAKEUP(&dev->vbl_queue);
+ }
+}
+
+int mga_vblank_wait(drm_device_t *dev, unsigned int *sequence)
+{
+ unsigned int cur_vblank;
+ int ret = 0;
+
+ /* Assume that the user has missed the current sequence number
+ * by about a day rather than she wants to wait for years
+ * using vertical blanks...
+ */
+ DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ,
+ ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) )
+ + ~*sequence + 1 ) <= (1<<23) ) );
+
+ *sequence = cur_vblank;
+
+ return ret;
+}
+
+void mga_driver_irq_preinstall( drm_device_t *dev ) {
+ drm_mga_private_t *dev_priv =
+ (drm_mga_private_t *)dev->dev_private;
+
+ /* Disable *all* interrupts */
+ MGA_WRITE( MGA_IEN, 0 );
+ /* Clear bits if they're already high */
+ MGA_WRITE( MGA_ICLEAR, ~0 );
+}
+
+void mga_driver_irq_postinstall( drm_device_t *dev ) {
+ drm_mga_private_t *dev_priv =
+ (drm_mga_private_t *)dev->dev_private;
+
+ /* Turn on VBL interrupt */
+ MGA_WRITE( MGA_IEN, MGA_VLINEIEN );
+}
+
+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 );
+ }
+}
diff --git a/shared-core/mga_state.c b/shared-core/mga_state.c
index 5e5b594a..61077220 100644
--- a/shared-core/mga_state.c
+++ b/shared-core/mga_state.c
@@ -26,7 +26,7 @@
*
* Authors:
* Jeff Hartmann <jhartmann@valinux.com>
- * Keith Whitwell <keithw@valinux.com>
+ * Keith Whitwell <keith@tungstengraphics.com>
*
* Rewritten by:
* Gareth Hughes <gareth@valinux.com>
@@ -1075,3 +1075,36 @@ int mga_dma_blit( DRM_IOCTL_ARGS )
return 0;
}
+
+int mga_getparam( DRM_IOCTL_ARGS )
+{
+ DRM_DEVICE;
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ drm_mga_getparam_t param;
+ int value;
+
+ if ( !dev_priv ) {
+ DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ return DRM_ERR(EINVAL);
+ }
+
+ DRM_COPY_FROM_USER_IOCTL( param, (drm_mga_getparam_t *)data,
+ sizeof(param) );
+
+ DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID );
+
+ switch( param.param ) {
+ case MGA_PARAM_IRQ_NR:
+ value = dev->irq;
+ break;
+ default:
+ return DRM_ERR(EINVAL);
+ }
+
+ if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) {
+ DRM_ERROR( "copy_to_user\n" );
+ return DRM_ERR(EFAULT);
+ }
+
+ return 0;
+}
diff --git a/shared-core/r128_drm.h b/shared-core/r128_drm.h
index a8d23008..bbb1a93b 100644
--- a/shared-core/r128_drm.h
+++ b/shared-core/r128_drm.h
@@ -190,6 +190,7 @@ typedef struct drm_r128_sarea {
#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
#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)
typedef struct drm_r128_init {
enum {
@@ -305,4 +306,14 @@ typedef struct drm_r128_fullscreen {
} func;
} drm_r128_fullscreen_t;
+/* 2.3: An ioctl to get parameters that aren't available to the 3d
+ * client any other way.
+ */
+#define R128_PARAM_IRQ_NR 1
+
+typedef struct drm_r128_getparam {
+ int param;
+ int *value;
+} drm_r128_getparam_t;
+
#endif
diff --git a/shared-core/r128_drv.h b/shared-core/r128_drv.h
index aeb73e08..763fcb3a 100644
--- a/shared-core/r128_drv.h
+++ b/shared-core/r128_drv.h
@@ -124,6 +124,7 @@ extern int r128_cce_idle( DRM_IOCTL_ARGS );
extern int r128_engine_reset( DRM_IOCTL_ARGS );
extern int r128_fullscreen( DRM_IOCTL_ARGS );
extern int r128_cce_buffers( DRM_IOCTL_ARGS );
+extern int r128_getparam( DRM_IOCTL_ARGS );
extern void r128_freelist_reset( drm_device_t *dev );
extern drm_buf_t *r128_freelist_get( drm_device_t *dev );
@@ -213,6 +214,11 @@ extern int r128_cce_indirect( DRM_IOCTL_ARGS );
#define R128_DST_PITCH_OFFSET_C 0x1c80
# define R128_DST_TILE (1 << 31)
+#define R128_GEN_INT_CNTL 0x0040
+# define R128_CRTC_VBLANK_INT_EN (1 << 0)
+#define R128_GEN_INT_STATUS 0x0044
+# define R128_CRTC_VBLANK_INT (1 << 0)
+# define R128_CRTC_VBLANK_INT_AK (1 << 0)
#define R128_GEN_RESET_CNTL 0x00f0
# define R128_SOFT_RESET_GUI (1 << 0)
diff --git a/shared-core/r128_irq.c b/shared-core/r128_irq.c
new file mode 100644
index 00000000..a29a81b5
--- /dev/null
+++ b/shared-core/r128_irq.c
@@ -0,0 +1,99 @@
+/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*-
+ *
+ * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
+ *
+ * The Weather Channel (TM) funded Tungsten Graphics to develop the
+ * initial release of the Radeon 8500 driver under the XFree86 license.
+ * This notice must be preserved.
+ *
+ * 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
+ * PRECISION INSIGHT 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:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#include "r128.h"
+#include "drmP.h"
+#include "drm.h"
+#include "r128_drm.h"
+#include "r128_drv.h"
+
+void r128_dma_service( DRM_IRQ_ARGS )
+{
+ drm_device_t *dev = (drm_device_t *) arg;
+ drm_r128_private_t *dev_priv =
+ (drm_r128_private_t *)dev->dev_private;
+ int status;
+
+ status = R128_READ( R128_GEN_INT_STATUS );
+
+ /* VBLANK interrupt */
+ if ( status & R128_CRTC_VBLANK_INT ) {
+ R128_WRITE( R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK );
+ atomic_inc(&dev->vbl_received);
+ DRM_WAKEUP(&dev->vbl_queue);
+ }
+}
+
+int DRM(vblank_wait)(drm_device_t *dev, unsigned int *sequence)
+{
+ unsigned int cur_vblank;
+ int ret = 0;
+
+ /* Assume that the user has missed the current sequence number
+ * by about a day rather than she wants to wait for years
+ * using vertical blanks...
+ */
+ DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ,
+ ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) )
+ + ~*sequence + 1 ) <= (1<<23) ) );
+
+ *sequence = cur_vblank;
+
+ return ret;
+}
+
+void r128_driver_irq_preinstall( drm_device_t *dev ) {
+ drm_r128_private_t *dev_priv =
+ (drm_r128_private_t *)dev->dev_private;
+
+ /* Disable *all* interrupts */
+ R128_WRITE( R128_GEN_INT_CNTL, 0 );
+ /* Clear vblank bit if it's already high */
+ R128_WRITE( R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK );
+}
+
+void r128_driver_irq_postinstall( drm_device_t *dev ) {
+ drm_r128_private_t *dev_priv =
+ (drm_r128_private_t *)dev->dev_private;
+
+ /* Turn on VBL interrupt */
+ R128_WRITE( R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN );
+}
+
+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 );
+ }
+}
diff --git a/shared-core/r128_state.c b/shared-core/r128_state.c
index 6ae58639..68f73061 100644
--- a/shared-core/r128_state.c
+++ b/shared-core/r128_state.c
@@ -1564,3 +1564,36 @@ int r128_cce_indirect( DRM_IOCTL_ARGS )
return 0;
}
+
+int r128_getparam( DRM_IOCTL_ARGS )
+{
+ DRM_DEVICE;
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_r128_getparam_t param;
+ int value;
+
+ if ( !dev_priv ) {
+ DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ return DRM_ERR(EINVAL);
+ }
+
+ DRM_COPY_FROM_USER_IOCTL( param, (drm_r128_getparam_t *)data,
+ sizeof(param) );
+
+ DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID );
+
+ switch( param.param ) {
+ case R128_PARAM_IRQ_NR:
+ value = dev->irq;
+ break;
+ default:
+ return DRM_ERR(EINVAL);
+ }
+
+ if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) {
+ DRM_ERROR( "copy_to_user\n" );
+ return DRM_ERR(EFAULT);
+ }
+
+ return 0;
+}
diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h
index 7c45898a..f05507e2 100644
--- a/shared-core/radeon_drm.h
+++ b/shared-core/radeon_drm.h
@@ -27,7 +27,7 @@
* Authors:
* Kevin E. Martin <martin@valinux.com>
* Gareth Hughes <gareth@valinux.com>
- * Keith Whitwell <keith_whitwell@yahoo.com>
+ * Keith Whitwell <keith@tungstengraphics.com>
*/
#ifndef __RADEON_DRM_H__
@@ -129,7 +129,19 @@
#define R200_EMIT_SE_VTX_STATE_CNTL 58 /* cst/1 */
#define R200_EMIT_RE_POINTSIZE 59 /* cst/1 */
#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0 60 /* cst/4 */
-#define RADEON_MAX_STATE_PACKETS 61
+#define R200_EMIT_PP_CUBIC_FACES_0 61
+#define R200_EMIT_PP_CUBIC_OFFSETS_0 62
+#define R200_EMIT_PP_CUBIC_FACES_1 63
+#define R200_EMIT_PP_CUBIC_OFFSETS_1 64
+#define R200_EMIT_PP_CUBIC_FACES_2 65
+#define R200_EMIT_PP_CUBIC_OFFSETS_2 66
+#define R200_EMIT_PP_CUBIC_FACES_3 67
+#define R200_EMIT_PP_CUBIC_OFFSETS_3 68
+#define R200_EMIT_PP_CUBIC_FACES_4 69
+#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
/* Commands understood by cmd_buffer ioctl. More can be added but
@@ -343,6 +355,7 @@ typedef struct {
int ctx_owner;
int pfState; /* number of 3d windows (0,1,2ormore) */
int pfCurrentPage; /* which buffer is being displayed? */
+ int crtc2_base; /* CRTC2 frame offset */
} drm_radeon_sarea_t;
diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h
index 40c4d9fe..65f3c926 100644
--- a/shared-core/radeon_drv.h
+++ b/shared-core/radeon_drv.h
@@ -109,8 +109,6 @@ typedef struct drm_radeon_private {
int do_boxes;
int page_flipping;
int current_page;
- u32 crtc_offset;
- u32 crtc_offset_cntl;
u32 color_fmt;
unsigned int front_offset;
@@ -230,6 +228,8 @@ extern int radeon_emit_irq(drm_device_t *dev);
#define RADEON_CRTC_OFFSET_CNTL 0x0228
# define RADEON_CRTC_TILE_EN (1 << 15)
# define RADEON_CRTC_OFFSET_FLIP_CNTL (1 << 16)
+#define RADEON_CRTC2_OFFSET 0x0324
+#define RADEON_CRTC2_OFFSET_CNTL 0x0328
#define RADEON_RB3D_COLORPITCH 0x1c48
@@ -574,6 +574,9 @@ extern int radeon_emit_irq(drm_device_t *dev);
#define RADEON_TXFORMAT_RGBA8888 7
#define RADEON_TXFORMAT_VYUY422 10
#define RADEON_TXFORMAT_YVYU422 11
+#define RADEON_TXFORMAT_DXT1 12
+#define RADEON_TXFORMAT_DXT23 14
+#define RADEON_TXFORMAT_DXT45 15
#define R200_PP_TXCBLEND_0 0x2f00
#define R200_PP_TXCBLEND_1 0x2f10
@@ -602,6 +605,44 @@ extern int radeon_emit_irq(drm_device_t *dev);
#define R200_PP_TXOFFSET_2 0x2d30
#define R200_PP_TXOFFSET_1 0x2d18
#define R200_PP_TXOFFSET_0 0x2d00
+
+#define R200_PP_CUBIC_FACES_0 0x2c18
+#define R200_PP_CUBIC_FACES_1 0x2c38
+#define R200_PP_CUBIC_FACES_2 0x2c58
+#define R200_PP_CUBIC_FACES_3 0x2c78
+#define R200_PP_CUBIC_FACES_4 0x2c98
+#define R200_PP_CUBIC_FACES_5 0x2cb8
+#define R200_PP_CUBIC_OFFSET_F1_0 0x2d04
+#define R200_PP_CUBIC_OFFSET_F2_0 0x2d08
+#define R200_PP_CUBIC_OFFSET_F3_0 0x2d0c
+#define R200_PP_CUBIC_OFFSET_F4_0 0x2d10
+#define R200_PP_CUBIC_OFFSET_F5_0 0x2d14
+#define R200_PP_CUBIC_OFFSET_F1_1 0x2d1c
+#define R200_PP_CUBIC_OFFSET_F2_1 0x2d20
+#define R200_PP_CUBIC_OFFSET_F3_1 0x2d24
+#define R200_PP_CUBIC_OFFSET_F4_1 0x2d28
+#define R200_PP_CUBIC_OFFSET_F5_1 0x2d2c
+#define R200_PP_CUBIC_OFFSET_F1_2 0x2d34
+#define R200_PP_CUBIC_OFFSET_F2_2 0x2d38
+#define R200_PP_CUBIC_OFFSET_F3_2 0x2d3c
+#define R200_PP_CUBIC_OFFSET_F4_2 0x2d40
+#define R200_PP_CUBIC_OFFSET_F5_2 0x2d44
+#define R200_PP_CUBIC_OFFSET_F1_3 0x2d4c
+#define R200_PP_CUBIC_OFFSET_F2_3 0x2d50
+#define R200_PP_CUBIC_OFFSET_F3_3 0x2d54
+#define R200_PP_CUBIC_OFFSET_F4_3 0x2d58
+#define R200_PP_CUBIC_OFFSET_F5_3 0x2d5c
+#define R200_PP_CUBIC_OFFSET_F1_4 0x2d64
+#define R200_PP_CUBIC_OFFSET_F2_4 0x2d68
+#define R200_PP_CUBIC_OFFSET_F3_4 0x2d6c
+#define R200_PP_CUBIC_OFFSET_F4_4 0x2d70
+#define R200_PP_CUBIC_OFFSET_F5_4 0x2d74
+#define R200_PP_CUBIC_OFFSET_F1_5 0x2d7c
+#define R200_PP_CUBIC_OFFSET_F2_5 0x2d80
+#define R200_PP_CUBIC_OFFSET_F3_5 0x2d84
+#define R200_PP_CUBIC_OFFSET_F4_5 0x2d88
+#define R200_PP_CUBIC_OFFSET_F5_5 0x2d8c
+
#define R200_RE_AUX_SCISSOR_CNTL 0x26f0
#define R200_SE_VTE_CNTL 0x20b0
#define R200_SE_TCL_OUTPUT_VTX_COMP_SEL 0x2250
diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c
index 179a2202..7b480a7e 100644
--- a/shared-core/radeon_state.c
+++ b/shared-core/radeon_state.c
@@ -30,6 +30,7 @@
#include "radeon.h"
#include "drmP.h"
#include "drm.h"
+#include "drm_sarea.h"
#include "radeon_drm.h"
#include "radeon_drv.h"
@@ -279,6 +280,18 @@ static struct {
{ R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL" },
{ R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE" },
{ R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0" },
+ { R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0" }, /* 61 */
+ { R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0" }, /* 62 */
+ { R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1" },
+ { R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1" },
+ { R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2" },
+ { R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2" },
+ { R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3" },
+ { R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3" },
+ { R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4" },
+ { 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" },
};
@@ -791,6 +804,9 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev )
static void radeon_cp_dispatch_flip( drm_device_t *dev )
{
drm_radeon_private_t *dev_priv = dev->dev_private;
+ drm_sarea_t *sarea = (drm_sarea_t *)dev_priv->sarea->handle;
+ int offset = (dev_priv->current_page == 1)
+ ? dev_priv->front_offset : dev_priv->back_offset;
RING_LOCALS;
DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n",
__FUNCTION__,
@@ -804,18 +820,17 @@ static void radeon_cp_dispatch_flip( drm_device_t *dev )
radeon_cp_performance_boxes( dev_priv );
}
- BEGIN_RING( 4 );
+ /* Update the frame offsets for both CRTCs
+ */
+ BEGIN_RING( 6 );
RADEON_WAIT_UNTIL_3D_IDLE();
- OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET, 0 ) );
-
- 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;
- }
+ OUT_RING_REG( RADEON_CRTC_OFFSET, ( ( sarea->frame.y * dev_priv->front_pitch
+ + sarea->frame.x
+ * ( dev_priv->color_fmt - 2 ) ) & ~7 )
+ + offset );
+ OUT_RING_REG( RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base
+ + offset );
ADVANCE_RING();
@@ -824,7 +839,8 @@ static void radeon_cp_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;
+ dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page =
+ 1 - dev_priv->current_page;
BEGIN_RING( 2 );
@@ -1292,12 +1308,12 @@ static int radeon_do_init_pageflip( drm_device_t *dev )
DRM_DEBUG( "\n" );
- dev_priv->crtc_offset_cntl = RADEON_READ( RADEON_CRTC_OFFSET_CNTL );
-
- BEGIN_RING( 4 );
+ BEGIN_RING( 6 );
RADEON_WAIT_UNTIL_3D_IDLE();
OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET_CNTL, 0 ) );
- OUT_RING( dev_priv->crtc_offset_cntl | RADEON_CRTC_OFFSET_FLIP_CNTL );
+ OUT_RING( RADEON_READ( RADEON_CRTC_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL );
+ OUT_RING( CP_PACKET0( RADEON_CRTC2_OFFSET_CNTL, 0 ) );
+ OUT_RING( RADEON_READ( RADEON_CRTC2_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL );
ADVANCE_RING();
dev_priv->page_flipping = 1;
@@ -1318,10 +1334,6 @@ int radeon_do_cleanup_pageflip( drm_device_t *dev )
if (dev_priv->current_page != 0)
radeon_cp_dispatch_flip( dev );
- /* FIXME: If the X server changes screen resolution, it
- * clobbers the value of RADEON_CRTC_OFFSET_CNTL, above,
- * leading to a flashing efect.
- */
dev_priv->page_flipping = 0;
return 0;
}
@@ -1792,11 +1804,16 @@ static int radeon_emit_packets(
drm_radeon_cmd_buffer_t *cmdbuf )
{
int id = (int)header.packet.packet_id;
- int sz = packet[id].len;
- int reg = packet[id].start;
+ int sz, reg;
int *data = (int *)cmdbuf->buf;
RING_LOCALS;
+ if (id >= RADEON_MAX_STATE_PACKETS)
+ return DRM_ERR(EINVAL);
+
+ sz = packet[id].len;
+ reg = packet[id].start;
+
if (sz * sizeof(int) > cmdbuf->bufsz)
return DRM_ERR(EINVAL);
diff --git a/shared/drm_sarea.h b/shared/drm_sarea.h
new file mode 100644
index 00000000..cee48eee
--- /dev/null
+++ b/shared/drm_sarea.h
@@ -0,0 +1,57 @@
+/* sarea.h -- SAREA definitions -*- linux-c -*-
+ *
+ * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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
+ * TUNGSTEN GRAPHICS 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:
+ * Michel Dänzer <michel@daenzer.net>
+ */
+
+#ifndef _DRM_SAREA_H_
+#define _DRM_SAREA_H_
+
+#define SAREA_MAX_DRAWABLES 256
+
+typedef struct _drm_sarea_drawable_t {
+ unsigned int stamp;
+ unsigned int flags;
+} drm_sarea_drawable_t;
+
+typedef struct _dri_sarea_frame_t {
+ unsigned int x;
+ unsigned int y;
+ unsigned int width;
+ unsigned int height;
+ unsigned int fullscreen;
+} drm_sarea_frame_t;
+
+typedef struct _drm_sarea_t {
+ /* first thing is always the drm locking structure */
+ drm_hw_lock_t lock;
+ /* NOT_DONE: Use readers/writer lock for drawable_lock */
+ drm_hw_lock_t drawable_lock;
+ drm_sarea_drawable_t drawableTable[SAREA_MAX_DRAWABLES];
+ drm_sarea_frame_t frame;
+ drm_context_t dummy_context;
+} drm_sarea_t;
+
+#endif /* _DRM_SAREA_H_ */
diff --git a/shared/mga.h b/shared/mga.h
index 5380cb0d..49530442 100644
--- a/shared/mga.h
+++ b/shared/mga.h
@@ -45,11 +45,11 @@
#define DRIVER_NAME "mga"
#define DRIVER_DESC "Matrox G200/G400"
-#define DRIVER_DATE "20010321"
+#define DRIVER_DATE "20021029"
#define DRIVER_MAJOR 3
-#define DRIVER_MINOR 0
-#define DRIVER_PATCHLEVEL 2
+#define DRIVER_MINOR 1
+#define DRIVER_PATCHLEVEL 0
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 }, \
@@ -61,7 +61,8 @@
[DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_dma_iload, 1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)] = { mga_dma_blit, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)] = { mga_dma_blit, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_GETPARAM)]= { mga_getparam, 1, 0 },
#define __HAVE_COUNTERS 3
#define __HAVE_COUNTER6 _DRM_STAT_IRQ
@@ -77,6 +78,9 @@
/* DMA customization:
*/
#define __HAVE_DMA 1
+#define __HAVE_DMA_IRQ 1
+#define __HAVE_VBL_IRQ 1
+#define __HAVE_SHARED_IRQ 1
#define __HAVE_DMA_QUIESCENT 1
#define DRIVER_DMA_QUIESCENT() do { \
diff --git a/shared/mga_dma.c b/shared/mga_dma.c
index a0ad70e9..22bd61f0 100644
--- a/shared/mga_dma.c
+++ b/shared/mga_dma.c
@@ -27,7 +27,7 @@
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Jeff Hartmann <jhartmann@valinux.com>
- * Keith Whitwell <keithw@valinux.com>
+ * Keith Whitwell <keith@tungstengraphics.com>
*
* Rewritten by:
* Gareth Hughes <gareth@valinux.com>
@@ -157,9 +157,18 @@ void mga_do_dma_flush( drm_mga_private_t *dev_priv )
{
drm_mga_primary_buffer_t *primary = &dev_priv->prim;
u32 head, tail;
- DMA_LOCALS;
+ u32 status = 0;
+ int i;
+ DMA_LOCALS;
DRM_DEBUG( "\n" );
+ /* We need to wait so that we can do an safe flush */
+ for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
+ status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK;
+ if ( status == MGA_ENDPRDMASTS ) break;
+ DRM_UDELAY( 1 );
+ }
+
if ( primary->tail == primary->last_flush ) {
DRM_DEBUG( " bailing out...\n" );
return;
diff --git a/shared/mga_drm.h b/shared/mga_drm.h
index 8f56beed..b19bc011 100644
--- a/shared/mga_drm.h
+++ b/shared/mga_drm.h
@@ -26,7 +26,7 @@
*
* Authors:
* Jeff Hartmann <jhartmann@valinux.com>
- * Keith Whitwell <keithw@valinux.com>
+ * Keith Whitwell <keith@tungstengraphics.com>
*
* Rewritten by:
* Gareth Hughes <gareth@valinux.com>
@@ -239,6 +239,7 @@ typedef struct _drm_mga_sarea {
#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t)
#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x47, drm_mga_iload_t)
#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x48, drm_mga_blit_t)
+#define DRM_IOCTL_MGA_GETPARAM DRM_IOWR(0x49, drm_mga_getparam_t)
typedef struct _drm_mga_warp_index {
int installed;
@@ -322,4 +323,14 @@ typedef struct _drm_mga_blit {
int source_pitch, dest_pitch;
} drm_mga_blit_t;
+/* 3.1: An ioctl to get parameters that aren't available to the 3d
+ * client any other way.
+ */
+#define MGA_PARAM_IRQ_NR 1
+
+typedef struct drm_mga_getparam {
+ int param;
+ int *value;
+} drm_mga_getparam_t;
+
#endif
diff --git a/shared/mga_drv.h b/shared/mga_drv.h
index b5f16ae2..a5085b06 100644
--- a/shared/mga_drv.h
+++ b/shared/mga_drv.h
@@ -125,6 +125,7 @@ extern int mga_dma_vertex( DRM_IOCTL_ARGS );
extern int mga_dma_indices( DRM_IOCTL_ARGS );
extern int mga_dma_iload( DRM_IOCTL_ARGS );
extern int mga_dma_blit( DRM_IOCTL_ARGS );
+extern int mga_getparam( DRM_IOCTL_ARGS );
/* mga_warp.c */
extern int mga_warp_install_microcode( drm_mga_private_t *dev_priv );
@@ -141,6 +142,7 @@ extern int mga_warp_init( drm_mga_private_t *dev_priv );
#ifdef __alpha__
#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(); MGA_DEREF( reg ) = val; } while (0)
#define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0)
@@ -152,6 +154,7 @@ static inline u32 _MGA_READ(u32 *addr)
#else
#define MGA_READ( reg ) MGA_DEREF( reg )
+#define MGA_READ8( reg ) MGA_DEREF8( reg )
#define MGA_WRITE( reg, val ) do { MGA_DEREF( reg ) = val; } while (0)
#define MGA_WRITE8( reg, val ) do { MGA_DEREF8( reg ) = val; } while (0)
#endif
@@ -345,6 +348,11 @@ do { \
/* A reduced set of the mga registers.
*/
#define MGA_CRTC_INDEX 0x1fd4
+#define MGA_CRTC_DATA 0x1fd5
+
+/* CRTC11 */
+#define MGA_VINTCLR (1 << 4)
+#define MGA_VINTEN (1 << 5)
#define MGA_ALPHACTRL 0x2c7c
#define MGA_AR0 0x1c60
@@ -416,8 +424,10 @@ do { \
#define MGA_ICLEAR 0x1e18
# define MGA_SOFTRAPICLR (1 << 0)
+# define MGA_VLINEICLR (1 << 5)
#define MGA_IEN 0x1e1c
# define MGA_SOFTRAPIEN (1 << 0)
+# define MGA_VLINEIEN (1 << 5)
#define MGA_LEN 0x1c5c
@@ -456,6 +466,8 @@ do { \
# define MGA_SRCACC_AGP (1 << 1)
#define MGA_STATUS 0x1e14
# define MGA_SOFTRAPEN (1 << 0)
+# define MGA_VSYNCPEN (1 << 4)
+# define MGA_VLINEPEN (1 << 5)
# define MGA_DWGENGSTS (1 << 16)
# define MGA_ENDPRDMASTS (1 << 17)
#define MGA_STENCIL 0x2cc8
diff --git a/shared/mga_irq.c b/shared/mga_irq.c
new file mode 100644
index 00000000..568d193f
--- /dev/null
+++ b/shared/mga_irq.c
@@ -0,0 +1,99 @@
+/* mga_irq.c -- IRQ handling for radeon -*- linux-c -*-
+ *
+ * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
+ *
+ * The Weather Channel (TM) funded Tungsten Graphics to develop the
+ * initial release of the Radeon 8500 driver under the XFree86 license.
+ * This notice must be preserved.
+ *
+ * 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
+ * PRECISION INSIGHT 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:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#include "mga.h"
+#include "drmP.h"
+#include "drm.h"
+#include "mga_drm.h"
+#include "mga_drv.h"
+
+void mga_dma_service( DRM_IRQ_ARGS )
+{
+ drm_device_t *dev = (drm_device_t *) arg;
+ drm_mga_private_t *dev_priv =
+ (drm_mga_private_t *)dev->dev_private;
+ int status;
+
+ status = MGA_READ( MGA_STATUS );
+
+ /* VBLANK interrupt */
+ if ( status & MGA_VLINEPEN ) {
+ MGA_WRITE( MGA_ICLEAR, MGA_VLINEICLR );
+ atomic_inc(&dev->vbl_received);
+ DRM_WAKEUP(&dev->vbl_queue);
+ }
+}
+
+int mga_vblank_wait(drm_device_t *dev, unsigned int *sequence)
+{
+ unsigned int cur_vblank;
+ int ret = 0;
+
+ /* Assume that the user has missed the current sequence number
+ * by about a day rather than she wants to wait for years
+ * using vertical blanks...
+ */
+ DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ,
+ ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) )
+ + ~*sequence + 1 ) <= (1<<23) ) );
+
+ *sequence = cur_vblank;
+
+ return ret;
+}
+
+void mga_driver_irq_preinstall( drm_device_t *dev ) {
+ drm_mga_private_t *dev_priv =
+ (drm_mga_private_t *)dev->dev_private;
+
+ /* Disable *all* interrupts */
+ MGA_WRITE( MGA_IEN, 0 );
+ /* Clear bits if they're already high */
+ MGA_WRITE( MGA_ICLEAR, ~0 );
+}
+
+void mga_driver_irq_postinstall( drm_device_t *dev ) {
+ drm_mga_private_t *dev_priv =
+ (drm_mga_private_t *)dev->dev_private;
+
+ /* Turn on VBL interrupt */
+ MGA_WRITE( MGA_IEN, MGA_VLINEIEN );
+}
+
+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 );
+ }
+}
diff --git a/shared/mga_state.c b/shared/mga_state.c
index 5e5b594a..61077220 100644
--- a/shared/mga_state.c
+++ b/shared/mga_state.c
@@ -26,7 +26,7 @@
*
* Authors:
* Jeff Hartmann <jhartmann@valinux.com>
- * Keith Whitwell <keithw@valinux.com>
+ * Keith Whitwell <keith@tungstengraphics.com>
*
* Rewritten by:
* Gareth Hughes <gareth@valinux.com>
@@ -1075,3 +1075,36 @@ int mga_dma_blit( DRM_IOCTL_ARGS )
return 0;
}
+
+int mga_getparam( DRM_IOCTL_ARGS )
+{
+ DRM_DEVICE;
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ drm_mga_getparam_t param;
+ int value;
+
+ if ( !dev_priv ) {
+ DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ return DRM_ERR(EINVAL);
+ }
+
+ DRM_COPY_FROM_USER_IOCTL( param, (drm_mga_getparam_t *)data,
+ sizeof(param) );
+
+ DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID );
+
+ switch( param.param ) {
+ case MGA_PARAM_IRQ_NR:
+ value = dev->irq;
+ break;
+ default:
+ return DRM_ERR(EINVAL);
+ }
+
+ if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) {
+ DRM_ERROR( "copy_to_user\n" );
+ return DRM_ERR(EFAULT);
+ }
+
+ return 0;
+}
diff --git a/shared/r128.h b/shared/r128.h
index 472a8014..cdf18ffb 100644
--- a/shared/r128.h
+++ b/shared/r128.h
@@ -47,10 +47,10 @@
#define DRIVER_NAME "r128"
#define DRIVER_DESC "ATI Rage 128"
-#define DRIVER_DATE "20010917"
+#define DRIVER_DATE "20021029"
#define DRIVER_MAJOR 2
-#define DRIVER_MINOR 2
+#define DRIVER_MINOR 3
#define DRIVER_PATCHLEVEL 0
@@ -70,7 +70,8 @@
[DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_GETPARAM)] = { r128_getparam, 1, 1 },
/* Driver customization:
*/
@@ -90,6 +91,9 @@
/* DMA customization:
*/
#define __HAVE_DMA 1
+#define __HAVE_DMA_IRQ 1
+#define __HAVE_VBL_IRQ 1
+#define __HAVE_SHARED_IRQ 1
#if 0
/* GH: Remove this for now... */
diff --git a/shared/r128_drm.h b/shared/r128_drm.h
index a8d23008..bbb1a93b 100644
--- a/shared/r128_drm.h
+++ b/shared/r128_drm.h
@@ -190,6 +190,7 @@ typedef struct drm_r128_sarea {
#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
#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)
typedef struct drm_r128_init {
enum {
@@ -305,4 +306,14 @@ typedef struct drm_r128_fullscreen {
} func;
} drm_r128_fullscreen_t;
+/* 2.3: An ioctl to get parameters that aren't available to the 3d
+ * client any other way.
+ */
+#define R128_PARAM_IRQ_NR 1
+
+typedef struct drm_r128_getparam {
+ int param;
+ int *value;
+} drm_r128_getparam_t;
+
#endif
diff --git a/shared/r128_drv.h b/shared/r128_drv.h
index aeb73e08..763fcb3a 100644
--- a/shared/r128_drv.h
+++ b/shared/r128_drv.h
@@ -124,6 +124,7 @@ extern int r128_cce_idle( DRM_IOCTL_ARGS );
extern int r128_engine_reset( DRM_IOCTL_ARGS );
extern int r128_fullscreen( DRM_IOCTL_ARGS );
extern int r128_cce_buffers( DRM_IOCTL_ARGS );
+extern int r128_getparam( DRM_IOCTL_ARGS );
extern void r128_freelist_reset( drm_device_t *dev );
extern drm_buf_t *r128_freelist_get( drm_device_t *dev );
@@ -213,6 +214,11 @@ extern int r128_cce_indirect( DRM_IOCTL_ARGS );
#define R128_DST_PITCH_OFFSET_C 0x1c80
# define R128_DST_TILE (1 << 31)
+#define R128_GEN_INT_CNTL 0x0040
+# define R128_CRTC_VBLANK_INT_EN (1 << 0)
+#define R128_GEN_INT_STATUS 0x0044
+# define R128_CRTC_VBLANK_INT (1 << 0)
+# define R128_CRTC_VBLANK_INT_AK (1 << 0)
#define R128_GEN_RESET_CNTL 0x00f0
# define R128_SOFT_RESET_GUI (1 << 0)
diff --git a/shared/r128_irq.c b/shared/r128_irq.c
new file mode 100644
index 00000000..a29a81b5
--- /dev/null
+++ b/shared/r128_irq.c
@@ -0,0 +1,99 @@
+/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*-
+ *
+ * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
+ *
+ * The Weather Channel (TM) funded Tungsten Graphics to develop the
+ * initial release of the Radeon 8500 driver under the XFree86 license.
+ * This notice must be preserved.
+ *
+ * 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
+ * PRECISION INSIGHT 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:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#include "r128.h"
+#include "drmP.h"
+#include "drm.h"
+#include "r128_drm.h"
+#include "r128_drv.h"
+
+void r128_dma_service( DRM_IRQ_ARGS )
+{
+ drm_device_t *dev = (drm_device_t *) arg;
+ drm_r128_private_t *dev_priv =
+ (drm_r128_private_t *)dev->dev_private;
+ int status;
+
+ status = R128_READ( R128_GEN_INT_STATUS );
+
+ /* VBLANK interrupt */
+ if ( status & R128_CRTC_VBLANK_INT ) {
+ R128_WRITE( R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK );
+ atomic_inc(&dev->vbl_received);
+ DRM_WAKEUP(&dev->vbl_queue);
+ }
+}
+
+int DRM(vblank_wait)(drm_device_t *dev, unsigned int *sequence)
+{
+ unsigned int cur_vblank;
+ int ret = 0;
+
+ /* Assume that the user has missed the current sequence number
+ * by about a day rather than she wants to wait for years
+ * using vertical blanks...
+ */
+ DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ,
+ ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) )
+ + ~*sequence + 1 ) <= (1<<23) ) );
+
+ *sequence = cur_vblank;
+
+ return ret;
+}
+
+void r128_driver_irq_preinstall( drm_device_t *dev ) {
+ drm_r128_private_t *dev_priv =
+ (drm_r128_private_t *)dev->dev_private;
+
+ /* Disable *all* interrupts */
+ R128_WRITE( R128_GEN_INT_CNTL, 0 );
+ /* Clear vblank bit if it's already high */
+ R128_WRITE( R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK );
+}
+
+void r128_driver_irq_postinstall( drm_device_t *dev ) {
+ drm_r128_private_t *dev_priv =
+ (drm_r128_private_t *)dev->dev_private;
+
+ /* Turn on VBL interrupt */
+ R128_WRITE( R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN );
+}
+
+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 );
+ }
+}
diff --git a/shared/r128_state.c b/shared/r128_state.c
index 6ae58639..68f73061 100644
--- a/shared/r128_state.c
+++ b/shared/r128_state.c
@@ -1564,3 +1564,36 @@ int r128_cce_indirect( DRM_IOCTL_ARGS )
return 0;
}
+
+int r128_getparam( DRM_IOCTL_ARGS )
+{
+ DRM_DEVICE;
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_r128_getparam_t param;
+ int value;
+
+ if ( !dev_priv ) {
+ DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ return DRM_ERR(EINVAL);
+ }
+
+ DRM_COPY_FROM_USER_IOCTL( param, (drm_r128_getparam_t *)data,
+ sizeof(param) );
+
+ DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID );
+
+ switch( param.param ) {
+ case R128_PARAM_IRQ_NR:
+ value = dev->irq;
+ break;
+ default:
+ return DRM_ERR(EINVAL);
+ }
+
+ if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) {
+ DRM_ERROR( "copy_to_user\n" );
+ return DRM_ERR(EFAULT);
+ }
+
+ return 0;
+}
diff --git a/shared/radeon.h b/shared/radeon.h
index 05760855..fe71687a 100644
--- a/shared/radeon.h
+++ b/shared/radeon.h
@@ -51,7 +51,7 @@
#define DRIVER_DATE "20020828"
#define DRIVER_MAJOR 1
-#define DRIVER_MINOR 6
+#define DRIVER_MINOR 7
#define DRIVER_PATCHLEVEL 0
/* Interface history:
@@ -73,6 +73,10 @@
* Add irq ioctls and irq_active getparam.
* Add wait command for cmdbuf ioctl
* Add agp offset query for getparam
+ * 1.7 - Add support for cube map registers: R200_PP_CUBIC_FACES_[0..5]
+ * and R200_PP_CUBIC_OFFSET_F1_[0..5].
+ * Added packets R200_EMIT_PP_CUBIC_FACES_[0..5] and
+ * R200_EMIT_PP_CUBIC_OFFSETS_[0..5]. (brian)
*/
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \
diff --git a/shared/radeon_drm.h b/shared/radeon_drm.h
index 7c45898a..f05507e2 100644
--- a/shared/radeon_drm.h
+++ b/shared/radeon_drm.h
@@ -27,7 +27,7 @@
* Authors:
* Kevin E. Martin <martin@valinux.com>
* Gareth Hughes <gareth@valinux.com>
- * Keith Whitwell <keith_whitwell@yahoo.com>
+ * Keith Whitwell <keith@tungstengraphics.com>
*/
#ifndef __RADEON_DRM_H__
@@ -129,7 +129,19 @@
#define R200_EMIT_SE_VTX_STATE_CNTL 58 /* cst/1 */
#define R200_EMIT_RE_POINTSIZE 59 /* cst/1 */
#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0 60 /* cst/4 */
-#define RADEON_MAX_STATE_PACKETS 61
+#define R200_EMIT_PP_CUBIC_FACES_0 61
+#define R200_EMIT_PP_CUBIC_OFFSETS_0 62
+#define R200_EMIT_PP_CUBIC_FACES_1 63
+#define R200_EMIT_PP_CUBIC_OFFSETS_1 64
+#define R200_EMIT_PP_CUBIC_FACES_2 65
+#define R200_EMIT_PP_CUBIC_OFFSETS_2 66
+#define R200_EMIT_PP_CUBIC_FACES_3 67
+#define R200_EMIT_PP_CUBIC_OFFSETS_3 68
+#define R200_EMIT_PP_CUBIC_FACES_4 69
+#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
/* Commands understood by cmd_buffer ioctl. More can be added but
@@ -343,6 +355,7 @@ typedef struct {
int ctx_owner;
int pfState; /* number of 3d windows (0,1,2ormore) */
int pfCurrentPage; /* which buffer is being displayed? */
+ int crtc2_base; /* CRTC2 frame offset */
} drm_radeon_sarea_t;
diff --git a/shared/radeon_drv.h b/shared/radeon_drv.h
index 40c4d9fe..65f3c926 100644
--- a/shared/radeon_drv.h
+++ b/shared/radeon_drv.h
@@ -109,8 +109,6 @@ typedef struct drm_radeon_private {
int do_boxes;
int page_flipping;
int current_page;
- u32 crtc_offset;
- u32 crtc_offset_cntl;
u32 color_fmt;
unsigned int front_offset;
@@ -230,6 +228,8 @@ extern int radeon_emit_irq(drm_device_t *dev);
#define RADEON_CRTC_OFFSET_CNTL 0x0228
# define RADEON_CRTC_TILE_EN (1 << 15)
# define RADEON_CRTC_OFFSET_FLIP_CNTL (1 << 16)
+#define RADEON_CRTC2_OFFSET 0x0324
+#define RADEON_CRTC2_OFFSET_CNTL 0x0328
#define RADEON_RB3D_COLORPITCH 0x1c48
@@ -574,6 +574,9 @@ extern int radeon_emit_irq(drm_device_t *dev);
#define RADEON_TXFORMAT_RGBA8888 7
#define RADEON_TXFORMAT_VYUY422 10
#define RADEON_TXFORMAT_YVYU422 11
+#define RADEON_TXFORMAT_DXT1 12
+#define RADEON_TXFORMAT_DXT23 14
+#define RADEON_TXFORMAT_DXT45 15
#define R200_PP_TXCBLEND_0 0x2f00
#define R200_PP_TXCBLEND_1 0x2f10
@@ -602,6 +605,44 @@ extern int radeon_emit_irq(drm_device_t *dev);
#define R200_PP_TXOFFSET_2 0x2d30
#define R200_PP_TXOFFSET_1 0x2d18
#define R200_PP_TXOFFSET_0 0x2d00
+
+#define R200_PP_CUBIC_FACES_0 0x2c18
+#define R200_PP_CUBIC_FACES_1 0x2c38
+#define R200_PP_CUBIC_FACES_2 0x2c58
+#define R200_PP_CUBIC_FACES_3 0x2c78
+#define R200_PP_CUBIC_FACES_4 0x2c98
+#define R200_PP_CUBIC_FACES_5 0x2cb8
+#define R200_PP_CUBIC_OFFSET_F1_0 0x2d04
+#define R200_PP_CUBIC_OFFSET_F2_0 0x2d08
+#define R200_PP_CUBIC_OFFSET_F3_0 0x2d0c
+#define R200_PP_CUBIC_OFFSET_F4_0 0x2d10
+#define R200_PP_CUBIC_OFFSET_F5_0 0x2d14
+#define R200_PP_CUBIC_OFFSET_F1_1 0x2d1c
+#define R200_PP_CUBIC_OFFSET_F2_1 0x2d20
+#define R200_PP_CUBIC_OFFSET_F3_1 0x2d24
+#define R200_PP_CUBIC_OFFSET_F4_1 0x2d28
+#define R200_PP_CUBIC_OFFSET_F5_1 0x2d2c
+#define R200_PP_CUBIC_OFFSET_F1_2 0x2d34
+#define R200_PP_CUBIC_OFFSET_F2_2 0x2d38
+#define R200_PP_CUBIC_OFFSET_F3_2 0x2d3c
+#define R200_PP_CUBIC_OFFSET_F4_2 0x2d40
+#define R200_PP_CUBIC_OFFSET_F5_2 0x2d44
+#define R200_PP_CUBIC_OFFSET_F1_3 0x2d4c
+#define R200_PP_CUBIC_OFFSET_F2_3 0x2d50
+#define R200_PP_CUBIC_OFFSET_F3_3 0x2d54
+#define R200_PP_CUBIC_OFFSET_F4_3 0x2d58
+#define R200_PP_CUBIC_OFFSET_F5_3 0x2d5c
+#define R200_PP_CUBIC_OFFSET_F1_4 0x2d64
+#define R200_PP_CUBIC_OFFSET_F2_4 0x2d68
+#define R200_PP_CUBIC_OFFSET_F3_4 0x2d6c
+#define R200_PP_CUBIC_OFFSET_F4_4 0x2d70
+#define R200_PP_CUBIC_OFFSET_F5_4 0x2d74
+#define R200_PP_CUBIC_OFFSET_F1_5 0x2d7c
+#define R200_PP_CUBIC_OFFSET_F2_5 0x2d80
+#define R200_PP_CUBIC_OFFSET_F3_5 0x2d84
+#define R200_PP_CUBIC_OFFSET_F4_5 0x2d88
+#define R200_PP_CUBIC_OFFSET_F5_5 0x2d8c
+
#define R200_RE_AUX_SCISSOR_CNTL 0x26f0
#define R200_SE_VTE_CNTL 0x20b0
#define R200_SE_TCL_OUTPUT_VTX_COMP_SEL 0x2250
diff --git a/shared/radeon_state.c b/shared/radeon_state.c
index 179a2202..7b480a7e 100644
--- a/shared/radeon_state.c
+++ b/shared/radeon_state.c
@@ -30,6 +30,7 @@
#include "radeon.h"
#include "drmP.h"
#include "drm.h"
+#include "drm_sarea.h"
#include "radeon_drm.h"
#include "radeon_drv.h"
@@ -279,6 +280,18 @@ static struct {
{ R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL" },
{ R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE" },
{ R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0" },
+ { R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0" }, /* 61 */
+ { R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0" }, /* 62 */
+ { R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1" },
+ { R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1" },
+ { R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2" },
+ { R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2" },
+ { R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3" },
+ { R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3" },
+ { R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4" },
+ { 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" },
};
@@ -791,6 +804,9 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev )
static void radeon_cp_dispatch_flip( drm_device_t *dev )
{
drm_radeon_private_t *dev_priv = dev->dev_private;
+ drm_sarea_t *sarea = (drm_sarea_t *)dev_priv->sarea->handle;
+ int offset = (dev_priv->current_page == 1)
+ ? dev_priv->front_offset : dev_priv->back_offset;
RING_LOCALS;
DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n",
__FUNCTION__,
@@ -804,18 +820,17 @@ static void radeon_cp_dispatch_flip( drm_device_t *dev )
radeon_cp_performance_boxes( dev_priv );
}
- BEGIN_RING( 4 );
+ /* Update the frame offsets for both CRTCs
+ */
+ BEGIN_RING( 6 );
RADEON_WAIT_UNTIL_3D_IDLE();
- OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET, 0 ) );
-
- 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;
- }
+ OUT_RING_REG( RADEON_CRTC_OFFSET, ( ( sarea->frame.y * dev_priv->front_pitch
+ + sarea->frame.x
+ * ( dev_priv->color_fmt - 2 ) ) & ~7 )
+ + offset );
+ OUT_RING_REG( RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base
+ + offset );
ADVANCE_RING();
@@ -824,7 +839,8 @@ static void radeon_cp_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;
+ dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page =
+ 1 - dev_priv->current_page;
BEGIN_RING( 2 );
@@ -1292,12 +1308,12 @@ static int radeon_do_init_pageflip( drm_device_t *dev )
DRM_DEBUG( "\n" );
- dev_priv->crtc_offset_cntl = RADEON_READ( RADEON_CRTC_OFFSET_CNTL );
-
- BEGIN_RING( 4 );
+ BEGIN_RING( 6 );
RADEON_WAIT_UNTIL_3D_IDLE();
OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET_CNTL, 0 ) );
- OUT_RING( dev_priv->crtc_offset_cntl | RADEON_CRTC_OFFSET_FLIP_CNTL );
+ OUT_RING( RADEON_READ( RADEON_CRTC_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL );
+ OUT_RING( CP_PACKET0( RADEON_CRTC2_OFFSET_CNTL, 0 ) );
+ OUT_RING( RADEON_READ( RADEON_CRTC2_OFFSET_CNTL ) | RADEON_CRTC_OFFSET_FLIP_CNTL );
ADVANCE_RING();
dev_priv->page_flipping = 1;
@@ -1318,10 +1334,6 @@ int radeon_do_cleanup_pageflip( drm_device_t *dev )
if (dev_priv->current_page != 0)
radeon_cp_dispatch_flip( dev );
- /* FIXME: If the X server changes screen resolution, it
- * clobbers the value of RADEON_CRTC_OFFSET_CNTL, above,
- * leading to a flashing efect.
- */
dev_priv->page_flipping = 0;
return 0;
}
@@ -1792,11 +1804,16 @@ static int radeon_emit_packets(
drm_radeon_cmd_buffer_t *cmdbuf )
{
int id = (int)header.packet.packet_id;
- int sz = packet[id].len;
- int reg = packet[id].start;
+ int sz, reg;
int *data = (int *)cmdbuf->buf;
RING_LOCALS;
+ if (id >= RADEON_MAX_STATE_PACKETS)
+ return DRM_ERR(EINVAL);
+
+ sz = packet[id].len;
+ reg = packet[id].start;
+
if (sz * sizeof(int) > cmdbuf->bufsz)
return DRM_ERR(EINVAL);