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.
main
Felix Kuehling 2005-01-09 19:49:21 +00:00
parent 6e38fd3576
commit d6af902ff7
2 changed files with 14 additions and 3 deletions

View File

@ -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);

View File

@ -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) {