summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordarktama_ <darktama_>2006-07-31 03:24:17 +0000
committerDave Airlie <airlied@linux.ie>2006-08-25 19:03:35 +1000
commit9a314361fd004afe7129ae2d41f58ddd7fe6f56a (patch)
tree54f69711b1889bb96f772b0e6d6092f1f892bb85
parent11fbb14876e7873a863de16b01fb5778e841b4bd (diff)
downloadxorg-driver-xf86-video-nouveau-9a314361fd004afe7129ae2d41f58ddd7fe6f56a.tar.gz
Updates for DRM changes, and a few cleanups
-rw-r--r--src/nv_dma.c133
-rw-r--r--src/nv_dma.h23
-rw-r--r--src/nv_dri.c19
-rw-r--r--src/nv_driver.c8
-rw-r--r--src/nv_exa.c5
-rw-r--r--src/nv_hw.c17
-rw-r--r--src/nv_include.h1
-rw-r--r--src/nv_local.h17
-rw-r--r--src/nv_proto.h3
-rw-r--r--src/nv_setup.c6
-rw-r--r--src/nv_type.h15
-rw-r--r--src/nv_xaa.c99
12 files changed, 214 insertions, 132 deletions
diff --git a/src/nv_dma.c b/src/nv_dma.c
index 8083d35..db84225 100644
--- a/src/nv_dma.c
+++ b/src/nv_dma.c
@@ -2,21 +2,18 @@
#include "nv_include.h"
#include "nvreg.h"
-CARD32 NVDmaCreateDMAObject(NVPtr pNv, int target, CARD32 base_address, CARD32 size, int access)
+void NVDmaCreateDMAObject(NVPtr pNv, int handle, int target, CARD32 base_address, CARD32 size, int access)
{
- drm_nouveau_dma_object_init_t dma;
- CARD32 object;
-
- dma.instance = &object;
- dma.access = access;
- dma.target = target;
- dma.size = size;
- dma.offset = base_address;
- if (target == NV_DMA_TARGET_AGP)
- dma.offset += pNv->agpPhysical;
- drmCommandWriteRead(pNv->drm_fd, DRM_NOUVEAU_DMA_OBJECT_INIT, &dma, sizeof(dma));
-
- return object;
+ drm_nouveau_dma_object_init_t dma;
+
+ dma.handle = handle;
+ dma.access = access;
+ dma.target = target;
+ dma.size = size;
+ dma.offset = base_address;
+ if (target == NV_DMA_TARGET_AGP)
+ dma.offset += pNv->agpPhysical;
+ drmCommandWrite(pNv->drm_fd, DRM_NOUVEAU_DMA_OBJECT_INIT, &dma, sizeof(dma));
}
/*
@@ -24,9 +21,9 @@ CARD32 NVDmaCreateDMAObject(NVPtr pNv, int target, CARD32 base_address, CARD32 s
seems, we use 256 for saftey) memory area that will be used by the HW to give feedback
about a DMA operation.
*/
-CARD32 NVDmaCreateNotifier(NVPtr pNv, int target, CARD32 base_address)
+void NVDmaCreateNotifier(NVPtr pNv, int handle, int target, CARD32 base_address)
{
- return NVDmaCreateDMAObject(pNv, target, base_address, 0x100, NV_DMA_ACCES_RW);
+ NVDmaCreateDMAObject(pNv, handle, target, base_address, 0x100, NV_DMA_ACCES_RW);
}
/*
@@ -37,7 +34,7 @@ CARD32 NVDmaCreateNotifier(NVPtr pNv, int target, CARD32 base_address)
the 'notify' field of the object in the channel. My guess is that
this causes an interrupt in PGRAPH/NOTIFY as soon as the transfer is
completed. Clients probably can use poll on the nv* devices to get this
- event. All this is a guess. I don't know any details, and I have not
+ event. All this is a guess. I don't know any details, and I have not
tested is. Also, I have no idea how the 'nvdriver' reacts if it gets
notify events that are not registered.
@@ -51,6 +48,7 @@ CARD32 NVDmaCreateNotifier(NVPtr pNv, int target, CARD32 base_address)
*/
Bool NVDmaWaitForNotifier(NVPtr pNv, int target, CARD32 base_address)
{
+ int t_start, timeout = 0;
volatile U032 *n;
unsigned char *notifier = (target == NV_DMA_TARGET_AGP)
? pNv->agpMemory
@@ -58,12 +56,29 @@ Bool NVDmaWaitForNotifier(NVPtr pNv, int target, CARD32 base_address)
notifier += base_address;
n = (volatile U032 *)notifier;
NVDEBUG("NVDmaWaitForNotifier @%p", n);
+ t_start = GetTimeInMillis();
while (1) {
U032 a = n[0];
U032 b = n[1];
U032 c = n[2];
U032 status = n[3];
NVDEBUG("status: n[0]=%x, n[1]=%x, n[2]=%x, n[3]=%x\n", a, b, c, status);
+ NVDEBUG("status: GET: 0x%08x\n", READ_GET(pNv));
+
+ if (GetTimeInMillis() - t_start >= 2000) {
+ /* We've timed out, call NVSync() to detect lockups */
+ if (timeout++ == 0) {
+ NVDoSync(pNv);
+ /* If we're still here, wait another second for notifier.. */
+ t_start = GetTimeInMillis() + 1000;
+ break;
+ }
+
+ /* Still haven't recieved notification, log error */
+ ErrorF("Notifier timeout\n");
+ return FALSE;
+ }
+
if (status == 0xffffffff)
continue;
if (!status)
@@ -77,7 +92,7 @@ Bool NVDmaWaitForNotifier(NVPtr pNv, int target, CARD32 base_address)
void NVDmaCreateContextObject(NVPtr pNv, int handle, int class, CARD32 flags,
CARD32 dma_in, CARD32 dma_out, CARD32 dma_notifier)
{
- drm_nouveau_object_init_t cto;
+ drm_nouveau_object_init_t cto;
CARD32 nv_flags0 = 0, nv_flags1 = 0, nv_flags2 = 0;
if (pNv->Architecture >= NV_ARCH_40) {
@@ -112,45 +127,52 @@ void NVDmaCreateContextObject(NVPtr pNv, int handle, int class, CARD32 flags,
#endif
}
- cto.handle = handle;
- cto.class = class;
- cto.flags0 = nv_flags0;
- cto.flags1 = nv_flags1;
- cto.flags2 = nv_flags2;
- cto.dma_in = dma_in;
- cto.dma_out = dma_out;
- cto.dma_notifier = dma_notifier;
- drmCommandWrite(pNv->drm_fd, DRM_NOUVEAU_OBJECT_INIT, &cto, sizeof(cto));
+ cto.handle = handle;
+ cto.class = class;
+ cto.flags0 = nv_flags0;
+ cto.flags1 = nv_flags1;
+ cto.flags2 = nv_flags2;
+ cto.dma0 = dma_in;
+ cto.dma1 = dma_out;
+ cto.dma_notifier = dma_notifier;
+ drmCommandWrite(pNv->drm_fd, DRM_NOUVEAU_OBJECT_INIT, &cto, sizeof(cto));
}
Bool NVInitDma(ScrnInfoPtr pScrn)
{
NVPtr pNv = NVPTR(pScrn);
- CARD32 dma_fb;
-#ifdef XF86DRI
- CARD32 dma_agp;
- CARD32 dma_notifier;
-#endif
- drm_nouveau_fifo_init_t fifo_init;
- unsigned int *fifo_regs, *fifo_cmdbuf;
- int fifo;
- int i;
+ drm_nouveau_fifo_init_t fifo;
- if (!NVDRIScreenInit(pScrn))
- return FALSE;
+ if (!NVDRIScreenInit(pScrn))
+ return FALSE;
- fifo_init.fifo_num = &fifo;
- if (drmCommandWriteRead(pNv->drm_fd, DRM_NOUVEAU_FIFO_INIT, &fifo_init, sizeof(fifo_init)) != 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not initialise kernel module\n");
- return FALSE;
- }
+ if (drmCommandWriteRead(pNv->drm_fd, DRM_NOUVEAU_FIFO_INIT, &pNv->fifo, sizeof(pNv->fifo)) != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not initialise kernel module\n");
+ return FALSE;
+ }
+
+ if (drmMap(pNv->drm_fd, pNv->fifo.cmdbuf, pNv->fifo.cmdbuf_size, (drmAddressPtr)&pNv->dmaBase)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to map DMA command buffer\n");
+ return FALSE;
+ }
- dma_fb = NVDmaCreateDMAObject(pNv, NV_DMA_TARGET_VIDMEM, 0, pNv->FbMapSize, NV_DMA_ACCES_RW);
+ if (drmMap(pNv->drm_fd, pNv->fifo.ctrl, pNv->fifo.ctrl_size, (drmAddressPtr)&pNv->FIFO)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to map FIFO control regs\n");
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using FIFO channel %d\n", pNv->fifo.channel);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, " Control registers : %p (0x%08x)\n", pNv->FIFO, pNv->fifo.ctrl);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, " DMA command buffer: %p (0x%08x)\n", pNv->dmaBase, pNv->fifo.cmdbuf);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, " DMA cmdbuf length : %d KiB\n", pNv->fifo.cmdbuf_size / 1024);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, " DMA base PUT : 0x%08x\n", pNv->fifo.put_base);
+
+ NVDmaCreateDMAObject(pNv, NvDmaFB, NV_DMA_TARGET_VIDMEM, 0, pNv->FbMapSize, NV_DMA_ACCES_RW);
NVDmaCreateContextObject (pNv, NvContextSurfaces,
(pNv->Architecture >= NV_ARCH_10) ? NV10_CONTEXT_SURFACES_2D : NV4_SURFACE,
NV_DMA_CONTEXT_FLAGS_PATCH_ROP_AND,
- dma_fb, dma_fb, 0);
+ NvDmaFB, NvDmaFB, 0);
NVDmaCreateContextObject (pNv, NvRop,
NV_ROP5_SOLID,
NV_DMA_CONTEXT_FLAGS_PATCH_ROP_AND,
@@ -170,7 +192,7 @@ Bool NVInitDma(ScrnInfoPtr pScrn)
NVDmaCreateContextObject (pNv, NvImageBlit,
pNv->WaitVSyncPossible ? NV12_IMAGE_BLIT : NV_IMAGE_BLIT,
NV_DMA_CONTEXT_FLAGS_PATCH_ROP_AND,
- dma_fb, dma_fb, 0);
+ NvDmaFB, NvDmaFB, 0);
NVDmaCreateContextObject (pNv, NvRectangle,
NV4_GDI_RECTANGLE_TEXT,
NV_DMA_CONTEXT_FLAGS_PATCH_ROP_AND|NV_DMA_CONTEXT_FLAGS_MONO,
@@ -178,32 +200,25 @@ Bool NVInitDma(ScrnInfoPtr pScrn)
NVDmaCreateContextObject (pNv, NvScaledImage,
NV_SCALED_IMAGE_FROM_MEMORY,
NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY,
- dma_fb, dma_fb, 0);
+ NvDmaFB, NvDmaFB, 0);
#ifdef XF86DRI
if (NVInitAGP(pScrn) && pNv->agpMemory) {
-
- dma_agp = NVDmaCreateDMAObject(pNv, NV_DMA_TARGET_AGP, 0x10000, pNv->agpSize - 0x10000,
+ NVDmaCreateDMAObject(pNv, NvDmaAGP, NV_DMA_TARGET_AGP, 0x10000, pNv->agpSize - 0x10000,
NV_DMA_ACCES_RW);
- dma_notifier = NVDmaCreateNotifier(pNv, NV_DMA_TARGET_AGP, 0);
+ NVDmaCreateNotifier(pNv, NvDmaNotifier0, NV_DMA_TARGET_AGP, 0);
NVDmaCreateContextObject (pNv, NvGraphicsToAGP,
NV_MEMORY_TO_MEMORY_FORMAT,
0,
- dma_fb, dma_agp, dma_notifier);
+ NvDmaFB, NvDmaAGP, NvDmaNotifier0);
NVDmaCreateContextObject (pNv, NvAGPToGraphics,
NV_MEMORY_TO_MEMORY_FORMAT,
0,
- dma_agp, dma_fb, dma_notifier);
+ NvDmaAGP, NvDmaFB, NvDmaNotifier0);
}
#endif
- fifo_regs = pNv->FIFO;
- fifo_cmdbuf = pNv->dmaBase;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using FIFO %d\n", fifo);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "FIFO control registers: %p\n", fifo_regs);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DMA command buffer : %p\n", fifo_cmdbuf);
- return TRUE;
+ return TRUE;
}
diff --git a/src/nv_dma.h b/src/nv_dma.h
index 88079db..100a3cb 100644
--- a/src/nv_dma.h
+++ b/src/nv_dma.h
@@ -42,12 +42,7 @@
#ifndef NV_DMA_H
#define NV_DMA_H
-#if 0
-#define NVDEBUG ErrorF
-#else
-#define NVDEBUG if (0) ErrorF
-#endif
-
+#define NVDEBUG if (NV_DMA_DEBUG) ErrorF
#define NV_DMA_ACCES_RW 0
#define NV_DMA_ACCES_RO 1
@@ -58,10 +53,10 @@
#define NV_DMA_TARGET_PCI 2
*/
#define NV_DMA_TARGET_AGP 3
-CARD32 NVDmaCreateDMAObject(NVPtr pNv, int target, CARD32 base_address, CARD32 size, int access);
+void NVDmaCreateDMAObject(NVPtr pNv, int handle, int target, CARD32 base_address, CARD32 size, int access);
Bool NVDmaWaitForNotifier(NVPtr pNv, int target, CARD32 base_address);
-CARD32 NVDmaCreateNotifier(NVPtr pNv, int target, CARD32 base_address);
+void NVDmaCreateNotifier(NVPtr pNv, int handle, int target, CARD32 base_address);
#define NV_DMA_CONTEXT_FLAGS_PATCH_ROP_AND 0x1
#define NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY 0x2
@@ -82,7 +77,10 @@ enum DMAObjects {
NvRectangle = 0x80000016,
NvScaledImage = 0x80000017,
NvGraphicsToAGP = 0x80000018,
- NvAGPToGraphics = 0x80000019
+ NvAGPToGraphics = 0x80000019,
+ NvDmaFB = 0xD8000001,
+ NvDmaAGP = 0xD8000002,
+ NvDmaNotifier0 = 0xD8000003
};
enum DMASubchannel {
NvSubContextSurfaces = 0,
@@ -96,12 +94,15 @@ enum DMASubchannel {
NvSubGraphicsToAGP = 7
};
-#define NVDmaNext(pNv, data) \
- (pNv)->dmaBase[(pNv)->dmaCurrent++] = (data)
+#define NVDmaNext(pNv, data) { \
+ (pNv)->dmaBase[(pNv)->dmaCurrent++] = (data); \
+ NVDEBUG("\tNVDmaNext: 0x%08x\n", (data)); \
+}
#define NVDmaStart(pNv, subchannel, tag, size) { \
if((pNv)->dmaFree <= (size)) \
NVDmaWait(pNv, size); \
+ NVDEBUG("NVDmaStart: subc=%d, cmd=%x, num=%d\n", (subchannel), (tag), (size)); \
NVDmaNext(pNv, ((size) << 18) | ((subchannel) << 13) | (tag)); \
(pNv)->dmaFree -= ((size) + 1); \
}
diff --git a/src/nv_dri.c b/src/nv_dri.c
index 9564c26..6206588 100644
--- a/src/nv_dri.c
+++ b/src/nv_dri.c
@@ -50,6 +50,7 @@ Bool NVDRIScreenInit(ScrnInfoPtr pScrn)
drmVersionPtr drm_version;
ScreenPtr pScreen;
pScreen = screenInfo.screens[pScrn->scrnIndex];
+ int irq;
if (!xf86LoadSubModule(pScrn, "dri")) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -103,6 +104,24 @@ Bool NVDRIScreenInit(ScrnInfoPtr pScrn)
drm_version->version_patchlevel,
drm_version->name);
+#if 1
+ pNv->IRQ = 0;
+#else
+ /* Ask DRM to install IRQ handler */
+ irq = drmGetInterruptFromBusID(pNv->drm_fd,
+ ((pciConfigPtr)pNv->PciInfo->thisCard)->busnum,
+ ((pciConfigPtr)pNv->PciInfo->thisCard)->devnum,
+ ((pciConfigPtr)pNv->PciInfo->thisCard)->funcnum);
+
+ if (drmCtlInstHandler(pNv->drm_fd, irq)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to install IRQ handler\n");
+ pNv->IRQ = 0;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "IRQ handler initialised. IRQ %d\n", irq);
+ pNv->IRQ = irq;
+ }
+#endif
+
return TRUE;
}
diff --git a/src/nv_driver.c b/src/nv_driver.c
index 2d0bccc..09c58f4 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -920,7 +920,7 @@ NVBlockHandler (
NVPtr pNv = NVPTR(pScrnInfo);
if (pNv->DMAKickoffCallback)
- (*pNv->DMAKickoffCallback)(pScrnInfo);
+ (*pNv->DMAKickoffCallback)(pNv);
pScreen->BlockHandler = pNv->BlockHandler;
(*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
@@ -1543,13 +1543,17 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
}
}
+ /*
+ * This is all generally bad.. We need to allocate these areas
+ */
if(pNv->Architecture >= NV_ARCH_40)
pNv->FbUsableSize = pNv->FbMapSize - (560 * 1024);
else
pNv->FbUsableSize = pNv->FbMapSize - (256 * 1024);
pNv->ScratchBufferSize = (pNv->Architecture < NV_ARCH_10) ? 8192 : 16384;
pNv->ScratchBufferStart = pNv->FbUsableSize - pNv->ScratchBufferSize;
- pNv->CursorStart = pNv->FbUsableSize + (32 * 1024);
+ pNv->CursorStart = pNv->ScratchBufferStart - (64*1024);
+ pNv->FbUsableSize -= pNv->ScratchBufferSize + (64*1024);
/*
* Setup the ClockRanges, which describe what clock ranges are available,
diff --git a/src/nv_exa.c b/src/nv_exa.c
index fd8fd0f..3d935ee 100644
--- a/src/nv_exa.c
+++ b/src/nv_exa.c
@@ -481,7 +481,10 @@ Bool NVExaInit(ScreenPtr pScreen)
pNv->EXADriverPtr->DownloadFromScreen = NVDownloadFromScreen;
pNv->EXADriverPtr->UploadToScreen = NVUploadToScreen;
}
- if (pNv->BlendingPossible) {
+ /*darktama: Hard-disabled these for now, I get lockups often when
+ * starting e17 with them enabled.
+ */
+ if (0 && pNv->BlendingPossible) {
/* install composite hooks */
pNv->EXADriverPtr->CheckComposite = NVCheckComposite;
pNv->EXADriverPtr->PrepareComposite = NVPrepareComposite;
diff --git a/src/nv_hw.c b/src/nv_hw.c
index cd66caa..64b8113 100644
--- a/src/nv_hw.c
+++ b/src/nv_hw.c
@@ -931,12 +931,14 @@ void NVLoadStateExt (
NVPtr pNv = NVPTR(pScrn);
int i, j;
- pNv->PMC[0x0140/4] = 0x00000000;
+ if (!pNv->IRQ)
+ pNv->PMC[0x0140/4] = 0x00000000;
pNv->PMC[0x0200/4] = 0xFFFF00FF;
pNv->PMC[0x0200/4] = 0xFFFFFFFF;
pNv->PTIMER[0x0200] = 0x00000008;
pNv->PTIMER[0x0210] = 0x00000003;
+ /*TODO: DRM handle PTIMER interrupts */
pNv->PTIMER[0x0140] = 0x00000000;
pNv->PTIMER[0x0100] = 0xFFFFFFFF;
@@ -989,8 +991,10 @@ void NVLoadStateExt (
pNv->PGRAPH[0x008C/4] = 0x0004FF31;
pNv->PGRAPH[0x008C/4] = 0x4004FF31;
- pNv->PGRAPH[0x0140/4] = 0x00000000;
- pNv->PGRAPH[0x0100/4] = 0xFFFFFFFF;
+ if (!pNv->IRQ) {
+ pNv->PGRAPH[0x0140/4] = 0x00000000;
+ pNv->PGRAPH[0x0100/4] = 0xFFFFFFFF;
+ }
pNv->PGRAPH[0x0170/4] = 0x10010100;
pNv->PGRAPH[0x0710/4] = 0xFFFFFFFF;
pNv->PGRAPH[0x0720/4] = 0x00000001;
@@ -1001,8 +1005,10 @@ void NVLoadStateExt (
pNv->PGRAPH[0x0080/4] = 0xFFFFFFFF;
pNv->PGRAPH[0x0080/4] = 0x00000000;
- pNv->PGRAPH[0x0140/4] = 0x00000000;
- pNv->PGRAPH[0x0100/4] = 0xFFFFFFFF;
+ if (!pNv->IRQ) {
+ pNv->PGRAPH[0x0140/4] = 0x00000000;
+ pNv->PGRAPH[0x0100/4] = 0xFFFFFFFF;
+ }
pNv->PGRAPH[0x0144/4] = 0x10010100;
pNv->PGRAPH[0x0714/4] = 0xFFFFFFFF;
pNv->PGRAPH[0x0720/4] = 0x00000001;
@@ -1092,7 +1098,6 @@ void NVLoadStateExt (
pNv->PGRAPH[0x0b38/4] = 0x2ffff800;
pNv->PGRAPH[0x0b3c/4] = 0x00006000;
pNv->PGRAPH[0x032C/4] = 0x01000000;
- pNv->PGRAPH[0x0220/4] = 0x00001200;
} else
if(pNv->Architecture == NV_ARCH_30) {
pNv->PGRAPH[0x0084/4] = 0x40108700;
diff --git a/src/nv_include.h b/src/nv_include.h
index c66cf14..4d1d0b3 100644
--- a/src/nv_include.h
+++ b/src/nv_include.h
@@ -67,6 +67,7 @@
#include <X11/extensions/randr.h>
#endif
+#define NV_DMA_DEBUG 0
#include "nv_local.h"
#include "nv_type.h"
#include "nv_proto.h"
diff --git a/src/nv_local.h b/src/nv_local.h
index 20fce24..0e8fade 100644
--- a/src/nv_local.h
+++ b/src/nv_local.h
@@ -79,15 +79,28 @@ typedef unsigned int U032;
#define _NV_FENCE() mem_barrier();
#endif
+#ifdef NV_DMA_DEBUG
+extern CARD32 READ_GET(void *);
+
#define WRITE_PUT(pNv, data) { \
volatile CARD8 scratch; \
_NV_FENCE() \
scratch = (pNv)->FbStart[0]; \
- (pNv)->FIFO[0x0010] = (data) << 2; \
+ (pNv)->FIFO[0x0010] = ((data) << 2) + pNv->fifo.put_base; \
+ xf86DrvMsg(0, X_INFO, "WRITE_PUT: 0x%08x\n", ((data) << 2) + pNv->fifo.put_base); \
mem_barrier(); \
}
+#else
+#define READ_GET(pNv) (((pNv)->FIFO[0x0011] - pNv->fifo.put_base) >> 2)
-#define READ_GET(pNv) ((pNv)->FIFO[0x0011] >> 2)
+#define WRITE_PUT(pNv, data) { \
+ volatile CARD8 scratch; \
+ _NV_FENCE() \
+ scratch = (pNv)->FbStart[0]; \
+ (pNv)->FIFO[0x0010] = ((data) << 2) + pNv->fifo.put_base; \
+ mem_barrier(); \
+}
+#endif
#endif /* __NV_LOCAL_H__ */
diff --git a/src/nv_proto.h b/src/nv_proto.h
index 5d97a70..64d163d 100644
--- a/src/nv_proto.h
+++ b/src/nv_proto.h
@@ -38,13 +38,14 @@ Bool NVCursorInit(ScreenPtr pScreen);
/* in nv_xaa.c */
Bool NVXaaInit(ScreenPtr pScreen);
+void NVDoSync(NVPtr pNv);
void NVSync(ScrnInfoPtr pScrn);
void NVResetGraphics(ScrnInfoPtr pScrn);
void NVDmaKickoff(NVPtr pNv);
void NVDmaWait(NVPtr pNv, int size);
void NVWaitVSync(NVPtr pNv);
void NVSetRopSolid(ScrnInfoPtr pScrn, CARD32 rop, CARD32 planemask);
-void NVDMAKickoffCallback (ScrnInfoPtr pScrn);
+void NVDMAKickoffCallback (NVPtr pNv);
/* in nv_dga.c */
Bool NVDGAInit(ScreenPtr pScreen);
diff --git a/src/nv_setup.c b/src/nv_setup.c
index 0f40f4d..a4bac32 100644
--- a/src/nv_setup.c
+++ b/src/nv_setup.c
@@ -373,7 +373,6 @@ NVCommonSetup(ScrnInfoPtr pScrn)
pNv->PEXTDEV = pNv->REGS + (NV_PEXTDEV_OFFSET/4);
pNv->PTIMER = pNv->REGS + (NV_PTIMER_OFFSET/4);
pNv->PMC = pNv->REGS + (NV_PMC_OFFSET/4);
- pNv->FIFO = pNv->REGS + (NV_FIFO_OFFSET/4);
/* 8 bit registers */
pNv->PCIO0 = (U008*)pNv->REGS + NV_PCIO0_OFFSET;
@@ -454,11 +453,12 @@ NVCommonSetup(ScrnInfoPtr pScrn)
}
/* Parse the bios to initialize the card */
+ NVSelectHeadRegisters(pScrn, 0);
NVParseBios(pScrn);
/* reset PFIFO and PGRAPH, then power up all the card units */
-/* pNv->PMC[0]=0x17110013;
+/* pNv->PMC[0x200]=0x17110013;
usleep(1000);*/
- pNv->PMC[0]=0x17111113;
+ pNv->PMC[0x200]=0x17111113;
if(pNv->Architecture == NV_ARCH_04)
nv4GetConfig(pNv);
diff --git a/src/nv_type.h b/src/nv_type.h
index b3799bd..c1584df 100644
--- a/src/nv_type.h
+++ b/src/nv_type.h
@@ -13,9 +13,11 @@
#define _XF86DRI_SERVER_
#include "xf86drm.h"
#include "dri.h"
+#include "nouveau_drm.h"
+#else
+#error "This driver requires a DRI-enabled X server"
#endif
-
#define NV_ARCH_04 0x04
#define NV_ARCH_10 0x10
#define NV_ARCH_20 0x20
@@ -108,7 +110,8 @@ typedef struct _riva_hw_state
} RIVA_HW_STATE, *NVRegPtr;
-typedef struct {
+typedef struct _NVRec *NVPtr;
+typedef struct _NVRec {
RIVA_HW_STATE SavedReg;
RIVA_HW_STATE ModeReg;
RIVA_HW_STATE *CurrentState;
@@ -190,7 +193,7 @@ typedef struct {
I2CBusPtr I2C;
xf86Int10InfoPtr pInt;
void (*VideoTimerCallback)(ScrnInfoPtr, Time);
- void (*DMAKickoffCallback)(ScrnInfoPtr);
+ void (*DMAKickoffCallback)(NVPtr pNv);
XF86VideoAdaptorPtr overlayAdaptor;
XF86VideoAdaptorPtr blitAdaptor;
int videoKey;
@@ -212,6 +215,10 @@ typedef struct {
int PanelTweak;
Bool LVDS;
+ int IRQ;
+ Bool LockedUp;
+
+ drm_nouveau_fifo_init_t fifo;
CARD32 dmaPut;
CARD32 dmaCurrent;
CARD32 dmaFree;
@@ -225,7 +232,7 @@ typedef struct {
#ifdef XF86DRI
DRIInfoPtr pDRIInfo;
#endif /* XF86DRI */
-} NVRec, *NVPtr;
+} NVRec;
#define NVPTR(p) ((NVPtr)((p)->driverPrivate))
diff --git a/src/nv_xaa.c b/src/nv_xaa.c
index 52b323c..fe4cdeb 100644
--- a/src/nv_xaa.c
+++ b/src/nv_xaa.c
@@ -121,24 +121,41 @@ NVDmaKickoff(NVPtr pNv)
to solve this problem */
#define SKIPS 8
+#ifdef NV_DMA_DEBUG
+CARD32 READ_GET(void *data) {
+ NVPtr pNv = data;
+
+ CARD32 getPtr = pNv->FIFO[0x44/4];
+ xf86DrvMsg(0, X_INFO, "READ_GET: 0x%08x\n", getPtr);
+ getPtr = (getPtr - pNv->fifo.put_base) >> 2;
+ xf86DrvMsg(0, X_INFO, "READ_GET retval: 0x%08x\n", getPtr);
+ return getPtr;
+}
+#endif
+
void
NVDmaWait (NVPtr pNv, int size){
+ int t_start;
int dmaGet;
size++;
+ t_start = GetTimeInMillis();
while(pNv->dmaFree < size) {
dmaGet = READ_GET(pNv);
if(pNv->dmaPut >= dmaGet) {
pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent;
if(pNv->dmaFree < size) {
- NVDmaNext(pNv, 0x20000000);
+ NVDmaNext(pNv, (0x20000000|pNv->fifo.put_base));
if(dmaGet <= SKIPS) {
if(pNv->dmaPut <= SKIPS) /* corner case - will be idle */
WRITE_PUT(pNv, SKIPS + 1);
- do { dmaGet = READ_GET(pNv); }
- while(dmaGet <= SKIPS);
+ do {
+ if (GetTimeInMillis() - t_start > 2000)
+ NVDoSync(pNv);
+ dmaGet = READ_GET(pNv);
+ } while(dmaGet <= SKIPS);
}
WRITE_PUT(pNv, SKIPS);
pNv->dmaCurrent = pNv->dmaPut = SKIPS;
@@ -146,6 +163,9 @@ NVDmaWait (NVPtr pNv, int size){
}
} else
pNv->dmaFree = dmaGet - pNv->dmaCurrent - 1;
+
+ if (GetTimeInMillis() - t_start > 2000)
+ NVDoSync(pNv);
}
}
@@ -219,34 +239,21 @@ void NVResetGraphics(ScrnInfoPtr pScrn)
pitch = pNv->CurrentLayout.displayWidth *
(pNv->CurrentLayout.bitsPerPixel >> 3);
- pNv->dmaBase = (CARD32*)(&pNv->FbStart[pNv->FbUsableSize]);
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "dmaBase at 0x%x\n",pNv->dmaBase);
- for(i = 0; i < SKIPS; i++)
- pNv->dmaBase[i] = 0x00000000;
-
- pNv->dmaBase[0x0 + SKIPS] = 0x00040000;
- pNv->dmaBase[0x1 + SKIPS] = NvContextSurfaces;
- pNv->dmaBase[0x2 + SKIPS] = 0x00042000;
- pNv->dmaBase[0x3 + SKIPS] = NvRop;
- pNv->dmaBase[0x4 + SKIPS] = 0x00044000;
- pNv->dmaBase[0x5 + SKIPS] = NvImagePattern;
- pNv->dmaBase[0x6 + SKIPS] = 0x00046000;
- pNv->dmaBase[0x7 + SKIPS] = NvClipRectangle;
- pNv->dmaBase[0x8 + SKIPS] = 0x00048000;
- pNv->dmaBase[0x9 + SKIPS] = NvSolidLine;
- pNv->dmaBase[0xA + SKIPS] = 0x0004A000;
- pNv->dmaBase[0xB + SKIPS] = NvImageBlit;
- pNv->dmaBase[0xC + SKIPS] = 0x0004C000;
- pNv->dmaBase[0xD + SKIPS] = NvRectangle;
- pNv->dmaBase[0xE + SKIPS] = 0x0004E000;
- pNv->dmaBase[0xF + SKIPS] = NvScaledImage;
-
- pNv->dmaPut = 0;
- pNv->dmaCurrent = 16 + SKIPS;
- pNv->dmaMax = 8191;
- pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent;
+ pNv->dmaPut = pNv->dmaCurrent = 0;
+ pNv->dmaMax = pNv->dmaFree = (pNv->fifo.cmdbuf_size >> 2) - 1;
+
+ for (i=0; i<SKIPS; i++)
+ NVDmaNext(pNv, 0);
+ pNv->dmaFree -= SKIPS;
+
+ NVDmaSetObjectOnSubchannel(pNv, NvSubContextSurfaces, NvContextSurfaces);
+ NVDmaSetObjectOnSubchannel(pNv, NvSubRop , NvRop );
+ NVDmaSetObjectOnSubchannel(pNv, NvSubImagePattern , NvImagePattern );
+ NVDmaSetObjectOnSubchannel(pNv, NvSubClipRectangle , NvClipRectangle );
+ NVDmaSetObjectOnSubchannel(pNv, NvSubSolidLine , NvSolidLine );
+ NVDmaSetObjectOnSubchannel(pNv, NvSubImageBlit , NvImageBlit );
+ NVDmaSetObjectOnSubchannel(pNv, NvSubRectangle , NvRectangle );
+ NVDmaSetObjectOnSubchannel(pNv, NvSubScaledImage , NvScaledImage );
switch(pNv->CurrentLayout.depth) {
case 24:
@@ -291,29 +298,35 @@ void NVResetGraphics(ScrnInfoPtr pScrn)
NVDmaKickoff(pNv);
}
-void NVSync(ScrnInfoPtr pScrn)
+void NVDoSync(NVPtr pNv)
{
- int i = 0;
- const int timeout = 0x10000;
- NVPtr pNv = NVPTR(pScrn);
+ int t_start, timeout = 2000;
if(pNv->DMAKickoffCallback)
- (*pNv->DMAKickoffCallback)(pScrn);
+ (*pNv->DMAKickoffCallback)(pNv);
- while((i++ < timeout) && (READ_GET(pNv) != pNv->dmaPut));
+ t_start = GetTimeInMillis();
+ while((GetTimeInMillis() - t_start) < timeout && (READ_GET(pNv) != pNv->dmaPut));
+ while((GetTimeInMillis() - t_start) < timeout && pNv->PGRAPH[NV_PGRAPH_STATUS/4]);
- while((i++ < timeout) && pNv->PGRAPH[NV_PGRAPH_STATUS/4]);
- if (i >= timeout) {
- ErrorF("DMA queue hang: dmaPut=%x, current=%x, status=%x\n",
+ if ((GetTimeInMillis() - t_start) >= timeout) {
+ if (pNv->LockedUp)
+ return;
+ pNv->LockedUp = TRUE; /* avoid re-entering FatalError on shutdown */
+ FatalError("DMA queue hang: dmaPut=%x, current=%x, status=%x\n",
pNv->dmaPut, READ_GET(pNv), pNv->PGRAPH[NV_PGRAPH_STATUS/4]);
}
}
-void
-NVDMAKickoffCallback (ScrnInfoPtr pScrn)
+void NVSync(ScrnInfoPtr pScrn)
{
- NVPtr pNv = NVPTR(pScrn);
+ NVPtr pNv = NVPTR(pScrn);
+ NVDoSync(pNv);
+}
+void
+NVDMAKickoffCallback (NVPtr pNv)
+{
NVDmaKickoff(pNv);
pNv->DMAKickoffCallback = NULL;
}