summaryrefslogtreecommitdiff
path: root/shared-core
diff options
context:
space:
mode:
authorFelix Kuehling <fxkuehl@gmx.de>2005-01-09 19:49:21 +0000
committerFelix Kuehling <fxkuehl@gmx.de>2005-01-09 19:49:21 +0000
commitd6af902ff74d4a384c2dd9acb9540d637f588bc6 (patch)
tree4a11147e9274649e91f640778f586219339b0813 /shared-core
parent6e38fd357625ef002cf1f4570296dc66ba2631c6 (diff)
Improved workaround for Savage3D DMA lockup to emit NOPs only before the
first indexed drawing command of a cmdbuf or if a wait command was emitted since the last indexed drawing command.
Diffstat (limited to 'shared-core')
-rw-r--r--shared-core/savage_drv.h7
-rw-r--r--shared-core/savage_state.c10
2 files changed, 14 insertions, 3 deletions
diff --git a/shared-core/savage_drv.h b/shared-core/savage_drv.h
index 9af12472..726c54fc 100644
--- a/shared-core/savage_drv.h
+++ b/shared-core/savage_drv.h
@@ -30,11 +30,11 @@
#define DRIVER_NAME "savage"
#define DRIVER_DESC "Savage3D/MX/IX, Savage4, SuperSavage, Twister, ProSavage[DDR]"
-#define DRIVER_DATE "20050106"
+#define DRIVER_DATE "20050109"
#define DRIVER_MAJOR 2
#define DRIVER_MINOR 1
-#define DRIVER_PATCHLEVEL 0
+#define DRIVER_PATCHLEVEL 1
/* Interface history:
*
* 1.x The DRM driver from the VIA/S3 code drop, basically a dummy
@@ -153,6 +153,9 @@ typedef struct drm_savage_private {
drm_savage_state_t state;
+ /* after emitting a wait cmd Savage3D needs 63 nops before next DMA */
+ unsigned int waiting;
+
/* config/hardware-dependent function pointers */
int (*wait_fifo)(struct drm_savage_private *dev_priv, unsigned int n);
int (*wait_evnt)(struct drm_savage_private *dev_priv, uint16_t e);
diff --git a/shared-core/savage_state.c b/shared-core/savage_state.c
index e623f805..44034a1c 100644
--- a/shared-core/savage_state.c
+++ b/shared-core/savage_state.c
@@ -47,6 +47,7 @@ void savage_emit_clip_rect_s3d(drm_savage_private_t *dev_priv,
BCI_WRITE(scend);
dev_priv->state.s3d.scstart = scstart;
dev_priv->state.s3d.scend = scend;
+ dev_priv->waiting = 1;
}
}
@@ -71,6 +72,7 @@ void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
BCI_WRITE(drawctrl1);
dev_priv->state.s4.drawctrl0 = drawctrl0;
dev_priv->state.s4.drawctrl1 = drawctrl1;
+ dev_priv->waiting = 1;
}
}
@@ -244,6 +246,7 @@ static int savage_dispatch_state(drm_savage_private_t *dev_priv,
if (cmd_header->state.global) {
BEGIN_BCI(bci_size+1);
BCI_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D);
+ dev_priv->waiting = 1;
} else {
BEGIN_BCI(bci_size);
}
@@ -338,7 +341,7 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
BCI_WRITE(dmabuf->bus_address | dev_priv->dma_type);
dev_priv->state.common.vbaddr = dmabuf->bus_address;
}
- if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
+ if (S3_SAVAGE3D_SERIES(dev_priv->chipset) && dev_priv->waiting) {
/* Workaround for what looks like a hardware bug. If a
* WAIT_3D_IDLE was emitted some time before the
* indexed drawing command then the engine will lock
@@ -347,6 +350,7 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
BEGIN_BCI(63);
for (i = 0; i < 63; ++i)
BCI_WRITE(BCI_CMD_WAIT);
+ dev_priv->waiting = 0;
}
prim <<= 25;
@@ -727,6 +731,10 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
* DMA commands to the graphics hardware. */
DRM_MEMORYBARRIER();
+ /* Coming from user space. Don't know if the Xserver has
+ * emitted wait commands. Assuming the worst. */
+ dev_priv->waiting = 1;
+
i = 0;
first_draw_cmd = NULL;
while (i < cmdbuf.size) {