summaryrefslogtreecommitdiff
path: root/shared
diff options
context:
space:
mode:
Diffstat (limited to 'shared')
-rw-r--r--shared/via_dma.c89
1 files changed, 57 insertions, 32 deletions
diff --git a/shared/via_dma.c b/shared/via_dma.c
index 000d4b0c..c559f931 100644
--- a/shared/via_dma.c
+++ b/shared/via_dma.c
@@ -1,6 +1,4 @@
/* via_dma.c -- DMA support for the VIA Unichrome/Pro
- */
-/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
@@ -11,7 +9,27 @@
* Copyright 2004 The Unichrome project.
* 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS 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: Various
+ */
#include "via.h"
#include "drmP.h"
@@ -20,6 +38,28 @@
#include "via_drv.h"
#include "via_3d_reg.h"
+#define PCI_BUF_SIZE 512000
+#define CMDBUF_ALIGNMENT_SIZE (0x100)
+#define CMDBUF_ALIGNMENT_MASK (0xff)
+
+/* defines for VIA 3D registers */
+#define VIA_REG_STATUS 0x400
+#define VIA_REG_TRANSET 0x43C
+#define VIA_REG_TRANSPACE 0x440
+
+/* VIA_REG_STATUS(0x400): Engine Status */
+#define VIA_CMD_RGTR_BUSY 0x00000080 /* Command Regulator is busy */
+#define VIA_2D_ENG_BUSY 0x00000001 /* 2D Engine is busy */
+#define VIA_3D_ENG_BUSY 0x00000002 /* 3D Engine is busy */
+#define VIA_VR_QUEUE_BUSY 0x00020000 /* Virtual Queue is busy */
+
+#define SetReg2DAGP(nReg, nData) { \
+ *((uint32_t *)(vb)) = ((nReg) >> 2) | HALCYON_HEADER1; \
+ *((uint32_t *)(vb) + 1) = (nData); \
+ vb = ((uint32_t *)vb) + 2; \
+ dev_priv->dma_low +=8; \
+}
+
#define via_flush_write_combine() DRM_MEMORYBARRIER()
#define VIA_OUT_RING_QW(w1,w2) \
@@ -27,12 +67,10 @@
*vb++ = (w2); \
dev_priv->dma_low += 8;
-#define PCI_BUF_SIZE 512000
static char pci_buf[PCI_BUF_SIZE];
static unsigned long pci_bufsiz = PCI_BUF_SIZE;
-
static void via_cmdbuf_start(drm_via_private_t * dev_priv);
static void via_cmdbuf_pause(drm_via_private_t * dev_priv);
static void via_cmdbuf_reset(drm_via_private_t * dev_priv);
@@ -107,7 +145,7 @@ via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size)
static inline uint32_t *via_check_dma(drm_via_private_t * dev_priv,
unsigned int size)
{
- if ((dev_priv->dma_low + size + 0x400) > dev_priv->dma_high) {
+ if ((dev_priv->dma_low + size + 4*CMDBUF_ALIGNMENT_SIZE) > dev_priv->dma_high) {
via_cmdbuf_rewind(dev_priv);
}
if (via_cmdbuf_wait(dev_priv, size) != 0) {
@@ -379,28 +417,6 @@ int via_pci_cmdbuffer(DRM_IOCTL_ARGS)
return 0;
}
-/************************************************************************/
-
-#define CMDBUF_ALIGNMENT_SIZE (0x100)
-#define CMDBUF_ALIGNMENT_MASK (0xff)
-
-/* defines for VIA 3D registers */
-#define VIA_REG_STATUS 0x400
-#define VIA_REG_TRANSET 0x43C
-#define VIA_REG_TRANSPACE 0x440
-
-/* VIA_REG_STATUS(0x400): Engine Status */
-#define VIA_CMD_RGTR_BUSY 0x00000080 /* Command Regulator is busy */
-#define VIA_2D_ENG_BUSY 0x00000001 /* 2D Engine is busy */
-#define VIA_3D_ENG_BUSY 0x00000002 /* 3D Engine is busy */
-#define VIA_VR_QUEUE_BUSY 0x00020000 /* Virtual Queue is busy */
-
-#define SetReg2DAGP(nReg, nData) { \
- *((uint32_t *)(vb)) = ((nReg) >> 2) | HALCYON_HEADER1; \
- *((uint32_t *)(vb) + 1) = (nData); \
- vb = ((uint32_t *)vb) + 2; \
- dev_priv->dma_low +=8; \
-}
static inline uint32_t *via_align_buffer(drm_via_private_t * dev_priv,
uint32_t * vb, int qw_count)
@@ -448,6 +464,7 @@ static int via_hook_segment(drm_via_private_t *dev_priv,
dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1;
while(! *dev_priv->last_pause_ptr);
+
paused = 0;
count = 20;
@@ -456,7 +473,8 @@ static int via_hook_segment(drm_via_private_t *dev_priv,
uint32_t rgtr, ptr;
rgtr = *(dev_priv->hw_addr_ptr);
ptr = ((char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) +
- dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4 - 0x100;
+ dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4 -
+ CMDBUF_ALIGNMENT_SIZE;
if (rgtr <= ptr) {
DRM_ERROR("Command regulator\npaused at count %d, address %x, "
"while current pause address is %x.\n"
@@ -468,16 +486,23 @@ static int via_hook_segment(drm_via_private_t *dev_priv,
if (paused && !no_pci_fire) {
uint32_t rgtr,ptr;
+ uint32_t ptr_low;
+ count = 1000000;
+ while ((VIA_READ(VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY) && count--);
+
rgtr = *(dev_priv->hw_addr_ptr);
ptr = ((char *)paused_at - dev_priv->dma_ptr) +
dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
+
- if (rgtr <= ptr && rgtr >= ptr - 0x100) {
+ ptr_low = (ptr > 3*CMDBUF_ALIGNMENT_SIZE) ?
+ ptr - 3*CMDBUF_ALIGNMENT_SIZE : 0;
+ if (rgtr <= ptr && rgtr >= ptr_low) {
VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi);
VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo);
- }
+ }
}
return paused;
}
@@ -660,7 +685,7 @@ static void via_cmdbuf_reset(drm_via_private_t * dev_priv)
}
/*
- * User interface to the space and lag function.
+ * User interface to the space and lag functions.
*/
int