diff options
author | darktama_ <darktama_> | 2006-07-31 03:24:17 +0000 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2006-08-25 19:03:35 +1000 |
commit | 9a314361fd004afe7129ae2d41f58ddd7fe6f56a (patch) | |
tree | 54f69711b1889bb96f772b0e6d6092f1f892bb85 | |
parent | 11fbb14876e7873a863de16b01fb5778e841b4bd (diff) | |
download | xorg-driver-xf86-video-nouveau-9a314361fd004afe7129ae2d41f58ddd7fe6f56a.tar.gz |
Updates for DRM changes, and a few cleanups
-rw-r--r-- | src/nv_dma.c | 133 | ||||
-rw-r--r-- | src/nv_dma.h | 23 | ||||
-rw-r--r-- | src/nv_dri.c | 19 | ||||
-rw-r--r-- | src/nv_driver.c | 8 | ||||
-rw-r--r-- | src/nv_exa.c | 5 | ||||
-rw-r--r-- | src/nv_hw.c | 17 | ||||
-rw-r--r-- | src/nv_include.h | 1 | ||||
-rw-r--r-- | src/nv_local.h | 17 | ||||
-rw-r--r-- | src/nv_proto.h | 3 | ||||
-rw-r--r-- | src/nv_setup.c | 6 | ||||
-rw-r--r-- | src/nv_type.h | 15 | ||||
-rw-r--r-- | src/nv_xaa.c | 99 |
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; } |