diff options
author | Ben Skeggs <skeggsb@gmail.com> | 2007-02-28 15:30:52 +1100 |
---|---|---|
committer | Ben Skeggs <skeggsb@gmail.com> | 2007-02-28 15:30:52 +1100 |
commit | da1dd87acb7061b4772c271dc3c9071a3b160e8a (patch) | |
tree | 220c07d3be22c5f7e821ec5fa7232818fc40b987 | |
parent | 7e5f90b264fdb3081250ff16748164998b6461a6 (diff) | |
download | xorg-driver-xf86-video-nouveau-da1dd87acb7061b4772c271dc3c9071a3b160e8a.tar.gz |
match drm v4 interface changes
context (gr/dma) object handling:
- remove use of flags/dmaobj when creating objects
- move object creation/setup into nv_accel_common.c
- NV04: make PGRAPH complain a bit more if we program the hardware
incorrectly.
- NV04/NV10: enable PGRAPH_DEBUG_3_CTX_METHODS
This bit seems to enable the use of SET_* methods.
- NV04/NV10/NV40: enable PGRAPH_DEBUG_3_IGNORE_PATCHVALID
Objects no longer get PATCH_CONFIG_VALID set in their context.
Not sure how to get this set other than to intercept the
PATCH_EXCEPTION error and enable the flag. I opted for the
same method NVIDIA use, which makes PGRAPH ignore it.
misc:
- use NV04_SCALED_IMAGE_FROM_MEMORY on all NV_ARCH_04 cards
- fix offScreenBase calculation (EXA)
- move mem alloc/free helpers into nv_mem.c
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/nv_accel_common.c | 384 | ||||
-rw-r--r-- | src/nv_dma.c | 170 | ||||
-rw-r--r-- | src/nv_dma.h | 1 | ||||
-rw-r--r-- | src/nv_dri.c | 39 | ||||
-rw-r--r-- | src/nv_driver.c | 93 | ||||
-rw-r--r-- | src/nv_exa.c | 6 | ||||
-rw-r--r-- | src/nv_hw.c | 11 | ||||
-rw-r--r-- | src/nv_mem.c | 62 | ||||
-rw-r--r-- | src/nv_proto.h | 14 | ||||
-rw-r--r-- | src/nv_type.h | 22 |
11 files changed, 568 insertions, 236 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index dffe591..a2d939c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,6 +29,7 @@ nouveau_drv_la_LDFLAGS = -module -avoid-version nouveau_drv_ladir = @moduledir@/drivers nouveau_drv_la_SOURCES = \ + nv_accel_common.c \ nv_bios.c \ nv_const.h \ nv_cursor.c \ @@ -42,6 +43,7 @@ nouveau_drv_la_SOURCES = \ nv_hw.c \ nv_include.h \ nv_local.h \ + nv_mem.c \ nv_proto.h \ nvreg.h \ nv_setup.c \ diff --git a/src/nv_accel_common.c b/src/nv_accel_common.c new file mode 100644 index 0000000..83d8264 --- /dev/null +++ b/src/nv_accel_common.c @@ -0,0 +1,384 @@ +#include "nv_include.h" + +static Bool +NVAccelInitNullObject(NVPtr pNv) +{ + static int have_object = FALSE; + + if (!have_object) { + if (!NVDmaCreateContextObject(pNv, NvNullObject, + 0x30)) + return FALSE; + have_object = TRUE; + } + + return TRUE; +} + +static Bool +NVAccelInitDmaFB(NVPtr pNv) +{ + static int have_object = FALSE; + + if (!have_object) { + if (!NVDmaCreateDMAObject(pNv, NvDmaFB, NV_DMA_IN_MEMORY, + NOUVEAU_MEM_FB, 0, + pNv->VRAMSize, + NOUVEAU_MEM_ACCESS_RW)) + return FALSE; + have_object = TRUE; + } + + return TRUE; +} + +static Bool +NVAccelInitDmaAGP(NVPtr pNv) +{ + static int have_object = FALSE; + + if (!pNv->AGPSize) + return TRUE; + + if (!have_object) { + if (!NVDmaCreateDMAObject(pNv, NvDmaAGP, NV_DMA_IN_MEMORY, + NOUVEAU_MEM_AGP, 0, + pNv->AGPSize, + NOUVEAU_MEM_ACCESS_RW)) { + ErrorF("Couldn't create AGP object, disabling AGP\n"); + NVFreeMemory(pNv, pNv->AGPScratch); + pNv->AGPScratch = NULL; + } + have_object = TRUE; + } + + return TRUE; +} + +static Bool +NVAccelInitDmaNotifier0(NVPtr pNv) +{ + static int have_object = FALSE; + + if (!have_object) { + pNv->Notifier0 = NVDmaCreateNotifier(pNv, NvDmaNotifier0); + if (!pNv->Notifier0) + return FALSE; + have_object = TRUE; + } + + return TRUE; +} + +/* FLAGS_ROP_AND, DmaFB, DmaFB, 0 */ +static Bool +NVAccelInitContextSurfaces(NVPtr pNv) +{ + static int have_object = FALSE; + uint32_t class; + + class = (pNv->Architecture >= NV_10) ? NV10_CONTEXT_SURFACES_2D : + NV04_SURFACE; + + if (!have_object) { + if (!NVDmaCreateContextObject(pNv, NvContextSurfaces, class)) + return FALSE; + have_object = TRUE; + } + + NVDmaSetObjectOnSubchannel(pNv, NvSubContextSurfaces, + NvContextSurfaces); + NVDmaStart(pNv, NvSubContextSurfaces, NV04_SURFACE_DMA_NOTIFY, 1); + NVDmaNext (pNv, NvNullObject); + NVDmaStart(pNv, NvSubContextSurfaces, NV04_SURFACE_DMA_IMAGE_SOURCE, 2); + NVDmaNext (pNv, NvDmaFB); + NVDmaNext (pNv, NvDmaFB); + + return TRUE; +} + +/* FLAGS_ROP_AND|FLAGS_MONO, 0, 0, 0 */ +static Bool +NVAccelInitImagePattern(NVPtr pNv) +{ + static int have_object = FALSE; + uint32_t class; + + class = NV04_IMAGE_PATTERN; + + if (!have_object) { + if (!NVDmaCreateContextObject(pNv, NvImagePattern, class)) + return FALSE; + have_object = TRUE; + } + + NVDmaSetObjectOnSubchannel(pNv, NvSubImagePattern, + NvImagePattern); + NVDmaStart(pNv, NvSubImagePattern, + 0x180, /*NV04_IMAGE_PATTERN_SET_DMA_NOTIFY*/ 1); + NVDmaNext (pNv, NvNullObject); + NVDmaStart(pNv, NvSubImagePattern, NV04_IMAGE_PATTERN_MONO_FORMAT, 3); +#if X_BYTE_ORDER == X_BIG_ENDIAN + NVDmaNext (pNv, 2 /* NV04_IMAGE_PATTERN_BIGENDIAN/LE_M1 */); +#else + NVDmaNext (pNv, 1 /* NV04_IMAGE_PATTERN_LOWENDIAN/CGA6_M1 */); +#endif + NVDmaNext (pNv, 0 /* NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_8X8 */); + NVDmaNext (pNv, 1 /* NV04_IMAGE_PATTERN_SELECT_MONOCHROME */); + + return TRUE; +} + +/* FLAGS_ROP_AND, 0, 0, 0 */ +static Bool +NVAccelInitRasterOp(NVPtr pNv) +{ + static int have_object = FALSE; + uint32_t class; + + class = NV03_PRIMITIVE_RASTER_OP; + + if (!have_object) { + if (!NVDmaCreateContextObject(pNv, NvRop, class)) + return FALSE; + have_object = TRUE; + } + + NVDmaSetObjectOnSubchannel(pNv, NvSubRop, NvRop); + NVDmaStart(pNv, NvSubRop, NV03_PRIMITIVE_RASTER_OP_DMA_NOTIFY, 1); + NVDmaNext (pNv, NvNullObject); + + return TRUE; +} + +/* FLAGS_ROP_AND | FLAGS_MONO, 0, 0, 0 */ +static Bool +NVAccelInitRectangle(NVPtr pNv) +{ + static int have_object = FALSE; + uint32_t class; + + class = NV04_GDI_RECTANGLE_TEXT; + + if (!have_object) { + if (!NVDmaCreateContextObject(pNv, NvRectangle, class)) + return FALSE; + have_object = TRUE; + } + + NVDmaSetObjectOnSubchannel(pNv, NvSubRectangle, NvRectangle); + NVDmaStart(pNv, NvSubRectangle, + NV04_GDI_RECTANGLE_TEXT_SET_DMA_NOTIFY, 1); + NVDmaNext (pNv, NvDmaNotifier0); + NVDmaStart(pNv, NvSubRectangle, + 0x184 /*NV04_GDI_RECTANGLE_TEXT_SET_DMA_FONTS*/, 1); + NVDmaNext (pNv, NvNullObject); + NVDmaStart(pNv, NvSubRectangle, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); + NVDmaNext (pNv, NvContextSurfaces); + NVDmaStart(pNv, NvSubRectangle, NV04_GDI_RECTANGLE_TEXT_ROP5, 1); + NVDmaNext (pNv, NvRop); + NVDmaStart(pNv, NvSubRectangle, NV04_GDI_RECTANGLE_TEXT_PATTERN, 1); + NVDmaNext (pNv, NvImagePattern); + NVDmaStart(pNv, NvSubRectangle, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); + NVDmaNext (pNv, 1 /* ROP_AND */); + + return TRUE; +} + +/* FLAGS_ROP_AND, DmaFB, DmaFB, 0 */ +static Bool +NVAccelInitImageBlit(NVPtr pNv) +{ + static int have_object = FALSE; + uint32_t class; + + class = (pNv->WaitVSyncPossible) ? NV10_IMAGE_BLIT : NV_IMAGE_BLIT; + + if (!have_object) { + if (!NVDmaCreateContextObject(pNv, NvImageBlit, class)) + return FALSE; + have_object = TRUE; + } + + NVDmaSetObjectOnSubchannel(pNv, NvSubImageBlit, NvImageBlit); + NVDmaStart(pNv, NvSubImageBlit, NV_IMAGE_BLIT_DMA_NOTIFY, 1); + NVDmaNext (pNv, NvDmaNotifier0); + NVDmaStart(pNv, NvSubImageBlit, NV_IMAGE_BLIT_COLOR_KEY, 1); + NVDmaNext (pNv, NvNullObject); + NVDmaStart(pNv, NvSubImageBlit, NV_IMAGE_BLIT_SURFACE, 1); + NVDmaNext (pNv, NvContextSurfaces); + NVDmaStart(pNv, NvSubImageBlit, NV_IMAGE_BLIT_CLIP_RECTANGLE, 3); + NVDmaNext (pNv, NvNullObject); + NVDmaNext (pNv, NvImagePattern); + NVDmaNext (pNv, NvRop); + NVDmaStart(pNv, NvSubImageBlit, NV_IMAGE_BLIT_OPERATION, 1); + NVDmaNext (pNv, 1 /* NV_IMAGE_BLIT_OPERATION_ROP_AND */); + + return TRUE; +} + +/* FLAGS_SRCCOPY, DmaFB, DmaFB, 0 */ +static Bool +NVAccelInitScaledImage(NVPtr pNv) +{ + static int have_object = FALSE; + uint32_t class; + + switch (pNv->Architecture) { + case NV_ARCH_04: + class = NV04_SCALED_IMAGE_FROM_MEMORY; + break; + case NV_ARCH_10: + case NV_ARCH_20: + case NV_ARCH_30: + class = NV10_SCALED_IMAGE_FROM_MEMORY; + break; + case NV_ARCH_40: + default: + class = NV10_SCALED_IMAGE_FROM_MEMORY | 0x3000; + break; + } + + if (!have_object) { + if (!NVDmaCreateContextObject(pNv, NvScaledImage, class)) + return FALSE; + have_object = TRUE; + } + + NVDmaSetObjectOnSubchannel(pNv, NvSubScaledImage, NvScaledImage); + NVDmaStart(pNv, NvSubScaledImage, + NV04_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY, 1); + NVDmaNext (pNv, NvDmaNotifier0); + NVDmaStart(pNv, NvSubScaledImage, + NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); + NVDmaNext (pNv, NvDmaFB); /* source object */ + NVDmaStart(pNv, NvSubScaledImage, + NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); + NVDmaNext (pNv, NvContextSurfaces); + NVDmaStart(pNv, NvSubScaledImage, 0x188, 1); /* PATTERN */ + NVDmaNext (pNv, NvNullObject); + NVDmaStart(pNv, NvSubScaledImage, 0x18c, 1); /* ROP */ + NVDmaNext (pNv, NvNullObject); + NVDmaStart(pNv, NvSubScaledImage, 0x190, 1); /* BETA1 */ + NVDmaNext (pNv, NvNullObject); + NVDmaStart(pNv, NvSubScaledImage, 0x194, 1); /* BETA4 */ + NVDmaNext (pNv, NvNullObject); + NVDmaStart(pNv, NvSubScaledImage, + NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION, 1); + NVDmaNext (pNv, 3 /* SRCCOPY */); + + return TRUE; +} + +/* FLAGS_NONE, 0, 0, 0 */ +static Bool +NVAccelInitClipRectangle(NVPtr pNv) +{ + static int have_object = FALSE; + int class = NV01_CONTEXT_CLIP_RECTANGLE; + + if (!have_object) { + if (!NVDmaCreateContextObject(pNv, NvClipRectangle, class)) + return FALSE; + have_object = TRUE; + } + + NVDmaSetObjectOnSubchannel(pNv, NvSubClipRectangle, NvClipRectangle); + NVDmaStart(pNv, NvSubClipRectangle, 0x180, 1); /* DMA_NOTIFY */ + NVDmaNext (pNv, NvNullObject); + + return TRUE; +} + +/* FLAGS_ROP_AND | FLAGS_CLIP_ENABLE, 0, 0, 0 */ +static Bool +NVAccelInitSolidLine(NVPtr pNv) +{ + static int have_object = FALSE; + int class = NV04_SOLID_LINE; + + if (!have_object) { + if (!NVDmaCreateContextObject(pNv, NvSolidLine, class)) + return FALSE; + have_object = TRUE; + } + + NVDmaSetObjectOnSubchannel(pNv, NvSubSolidLine, NvSolidLine); + NVDmaStart(pNv, NvSubSolidLine, NV04_SOLID_LINE_CLIP_RECTANGLE, 3); + NVDmaNext (pNv, NvClipRectangle); + NVDmaNext (pNv, NvImagePattern); + NVDmaNext (pNv, NvRop); + NVDmaStart(pNv, NvSubSolidLine, NV04_SOLID_LINE_SURFACE, 1); + NVDmaNext (pNv, NvContextSurfaces); + NVDmaStart(pNv, NvSubSolidLine, NV04_SOLID_LINE_OPERATION, 1); + NVDmaNext (pNv, 1); /* ROP_AND */ + + return TRUE; +} + +/* FLAGS_NONE, NvDmaFB, NvDmaAGP, NvDmaNotifier0 */ +static Bool +NVAccelInitMemFormat(NVPtr pNv) +{ + static int have_object = FALSE; + uint32_t class; + + class = NV_MEMORY_TO_MEMORY_FORMAT; + + if (!have_object) { + if (!NVDmaCreateContextObject(pNv, NvMemFormat, class)) + return FALSE; + have_object = TRUE; + } + + NVDmaSetObjectOnSubchannel(pNv, NvSubMemFormat, NvMemFormat); + NVDmaStart(pNv, NvSubMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); + NVDmaNext (pNv, NvDmaNotifier0); + NVDmaStart(pNv, NvSubMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_IN, 2); + NVDmaNext (pNv, NvDmaFB); + NVDmaNext (pNv, NvDmaFB); + + pNv->M2MFDirection = -1; + return TRUE; +} + +#define INIT_CONTEXT_OBJECT(name) do { \ + ret = NVAccelInit##name(pNv); \ + if (!ret) { \ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ + "Failed to initialise context object: "#name \ + " (%d)\n", ret); \ + return FALSE; \ + } \ +} while(0) + +Bool +NVAccelCommonInit(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + Bool ret; + + INIT_CONTEXT_OBJECT(NullObject); + INIT_CONTEXT_OBJECT(DmaFB); + INIT_CONTEXT_OBJECT(DmaAGP); + INIT_CONTEXT_OBJECT(DmaNotifier0); + + INIT_CONTEXT_OBJECT(ContextSurfaces); + INIT_CONTEXT_OBJECT(ImagePattern); + INIT_CONTEXT_OBJECT(RasterOp); + INIT_CONTEXT_OBJECT(Rectangle); + INIT_CONTEXT_OBJECT(ImageBlit); + INIT_CONTEXT_OBJECT(ScaledImage); + + /* XAA-only */ + INIT_CONTEXT_OBJECT(ClipRectangle); + INIT_CONTEXT_OBJECT(SolidLine); + + /* EXA-only */ + INIT_CONTEXT_OBJECT(MemFormat); + + return TRUE; +} + diff --git a/src/nv_dma.c b/src/nv_dma.c index 8b53e72..8bfc234 100644 --- a/src/nv_dma.c +++ b/src/nv_dma.c @@ -123,6 +123,8 @@ void NVResetGraphics(ScrnInfoPtr pScrn) } pNv->dmaFree -= SKIPS; + NVAccelCommonInit(pScrn); + /* EXA + XAA + Xv */ NVDmaSetObjectOnSubchannel(pNv, NvSubContextSurfaces, NvContextSurfaces); NVDmaSetObjectOnSubchannel(pNv, NvSubRectangle , NvRectangle ); @@ -189,21 +191,44 @@ void NVResetGraphics(ScrnInfoPtr pScrn) /*NVDmaKickoff(pNv);*/ } -Bool NVDmaCreateDMAObject(NVPtr pNv, int handle, int target, CARD32 base_address, CARD32 size, int access) +Bool NVDmaCreateDMAObject(NVPtr pNv, uint32_t handle, int class, + int target, + CARD32 offset, CARD32 size, int access) { drm_nouveau_dma_object_init_t dma; int ret; dma.handle = handle; + dma.class = class; dma.access = access; dma.target = target; - dma.size= size; - dma.offset = base_address; - ret = drmCommandWrite(pNv->drm_fd, DRM_NOUVEAU_DMA_OBJECT_INIT, &dma, sizeof(dma)); + dma.size = size; + dma.offset = offset; + ret = drmCommandWrite(pNv->drm_fd, DRM_NOUVEAU_DMA_OBJECT_INIT, + &dma, sizeof(dma)); return ret == 0; } +Bool NVDmaCreateDMAObjectFromMem(NVPtr pNv, uint32_t handle, int class, + NVAllocRec *mem, int access) +{ + uint32_t offset = mem->offset; + int target; + + target = mem->type & (NOUVEAU_MEM_FB | NOUVEAU_MEM_AGP); + if (!target) + return FALSE; + + if (target & NOUVEAU_MEM_FB) + offset -= pNv->VRAMPhysical; + else if (target & NOUVEAU_MEM_AGP) + offset -= pNv->AGPPhysical; + + return NVDmaCreateDMAObject(pNv, handle, class, target, + offset, mem->size, access); +} + /* A DMA notifier is a DMA object that references a small (32 byte it seems, we use 256 for saftey) memory area that will be used by the HW to give feedback @@ -219,12 +244,9 @@ NVAllocRec *NVDmaCreateNotifier(NVPtr pNv, int handle) if (!notifier) notifier = NVAllocateMemory(pNv, NOUVEAU_MEM_FB, 256); - if (!NVDmaCreateDMAObject(pNv, handle, - notifier->type & NOUVEAU_MEM_AGP ? - NV_DMA_TARGET_AGP : NV_DMA_TARGET_VIDMEM, - notifier->offset, - notifier->size, - NV_DMA_ACCES_RW)) { + if (!NVDmaCreateDMAObjectFromMem(pNv, handle, NV_DMA_IN_MEMORY, + notifier, + NOUVEAU_MEM_ACCESS_RW)) { NVFreeMemory(pNv, notifier); return NULL; } @@ -291,20 +313,15 @@ Bool NVDmaWaitForNotifier(NVPtr pNv, void *notifier) return TRUE; } -Bool NVDmaCreateContextObject(NVPtr pNv, int handle, int class, CARD32 flags, - CARD32 dma_in, CARD32 dma_out, CARD32 dma_notifier) +Bool NVDmaCreateContextObject(NVPtr pNv, int handle, int class) { drm_nouveau_object_init_t cto; int ret; cto.handle = handle; cto.class = class; - cto.flags = flags; - cto.dma0= dma_in; - cto.dma1= dma_out; - cto.dma_notifier = dma_notifier; - ret = drmCommandWrite(pNv->drm_fd, DRM_NOUVEAU_OBJECT_INIT, &cto, sizeof(cto)); - + ret = drmCommandWrite(pNv->drm_fd, DRM_NOUVEAU_OBJECT_INIT, + &cto, sizeof(cto)); return ret == 0; } @@ -342,6 +359,7 @@ static void NVInitDmaCB(ScrnInfoPtr pScrn) Bool NVInitDma(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); + int i; NVInitDmaCB(pScrn); @@ -368,117 +386,13 @@ Bool NVInitDma(ScrnInfoPtr pScrn) 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->VRAMPhysicalSize, NV_DMA_ACCES_RW); - - /* EXA + XAA + Xv */ - NVDmaCreateContextObject(pNv, NvContextSurfaces, - (pNv->Architecture >= NV_ARCH_10) ? NV10_CONTEXT_SURFACES_2D : NV04_SURFACE, - NV_DMA_CONTEXT_FLAGS_PATCH_ROP_AND, - NvDmaFB, NvDmaFB, 0); - NVDmaCreateContextObject(pNv, NvRectangle, - NV04_GDI_RECTANGLE_TEXT, - NV_DMA_CONTEXT_FLAGS_PATCH_ROP_AND|NV_DMA_CONTEXT_FLAGS_MONO, - 0, 0, 0); - if (pNv->Chipset<=CHIPSET_NV04) - NVDmaCreateContextObject(pNv, NvScaledImage, - NV04_SCALED_IMAGE_FROM_MEMORY, - NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, - NvDmaFB, NvDmaFB, 0); - else if (pNv->Architecture==NV_ARCH_04) - NVDmaCreateContextObject(pNv, NvScaledImage, - NV05_SCALED_IMAGE_FROM_MEMORY, - NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, - NvDmaFB, NvDmaFB, 0); - else - NVDmaCreateContextObject(pNv, NvScaledImage, - NV10_SCALED_IMAGE_FROM_MEMORY, - NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, - NvDmaFB, NvDmaFB, 0); - /* EXA + XAA */ - NVDmaCreateContextObject(pNv, NvRop, - NV03_PRIMITIVE_RASTER_OP, - NV_DMA_CONTEXT_FLAGS_PATCH_ROP_AND, - 0, 0, 0); - NVDmaCreateContextObject(pNv, NvImagePattern, - NV04_IMAGE_PATTERN, - NV_DMA_CONTEXT_FLAGS_PATCH_ROP_AND|NV_DMA_CONTEXT_FLAGS_MONO, - 0, 0, 0); - NVDmaCreateContextObject(pNv, NvImageBlit, - pNv->WaitVSyncPossible ? NV10_IMAGE_BLIT : NV_IMAGE_BLIT, - NV_DMA_CONTEXT_FLAGS_PATCH_ROP_AND, - NvDmaFB, NvDmaFB, 0); - if (pNv->useEXA) { - unsigned int class_3d = 0; - -#ifdef NV_ENABLE_3D - switch (pNv->Architecture) { - case NV_ARCH_30: - case NV_ARCH_40: - if (!NV30EXAPreInit(pScrn)) - break; - pNv->Reset3D = NV30EXAResetGraphics; - pNv->InitEXA3D = NV30EXAInstallHooks; - switch (pNv->Chipset & 0xff0) { - case CHIPSET_NV40: - class_3d = NV30_TCL_PRIMITIVE_3D|0x4000; - break; - case CHIPSET_C51: - case CHIPSET_NV44A: - class_3d = NV30_TCL_PRIMITIVE_3D|0x4400; - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "3D: Unknown chipset=0x%x\n", - pNv->Chipset); - break; - } - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "3D: Unknown arch=0x%x\n",\ - pNv->Architecture); - break; - } - - if (class_3d) { - NVDmaCreateContextObject(pNv, Nv3D, class_3d, - 0, - 0, 0, 0); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Enabled experimental EXA-on-3D code\n"); - pNv->use3D = 1; - } -#endif - } else { - NVDmaCreateContextObject(pNv, NvClipRectangle, - NV01_CONTEXT_CLIP_RECTANGLE, - NV_DMA_CONTEXT_FLAGS_PATCH_ROP_AND, - 0, 0, 0); - NVDmaCreateContextObject(pNv, NvSolidLine, - NV04_SOLID_LINE, - NV_DMA_CONTEXT_FLAGS_PATCH_ROP_AND|NV_DMA_CONTEXT_FLAGS_CLIP_ENABLE, - 0, 0, 0); - } + pNv->dmaPut = pNv->dmaCurrent = READ_GET(pNv); + pNv->dmaMax = (pNv->fifo.cmdbuf_size >> 2) - 1; + pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent; - if (pNv->useEXA && NVInitAGP(pScrn) && pNv->AGPScratch) { - pNv->Notifier0 = NVDmaCreateNotifier(pNv, NvDmaNotifier0); - if (pNv->Notifier0) { - NVDmaCreateDMAObject(pNv, NvDmaAGP, NV_DMA_TARGET_AGP, - pNv->AGPScratch->offset, - pNv->AGPScratch->size, - NV_DMA_ACCES_RW); - - NVDmaCreateContextObject(pNv, NvMemFormat, - NV_MEMORY_TO_MEMORY_FORMAT, - 0, - 0, 0, NvDmaNotifier0); - } else { - /* FIXME */ - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to create DMA notifier - DMA transfers disabled\n"); - NVFreeMemory(pNv, pNv->AGPScratch); - pNv->AGPScratch = NULL; - } - } + for (i=0; i<SKIPS; i++) + NVDmaNext(pNv,0); + pNv->dmaFree -= SKIPS; return TRUE; } diff --git a/src/nv_dma.h b/src/nv_dma.h index d89486d..3d43fcd 100644 --- a/src/nv_dma.h +++ b/src/nv_dma.h @@ -55,6 +55,7 @@ #define NV_DMA_TARGET_AGP 3 enum DMAObjects { + NvNullObject = 0x00000000, NvContextSurfaces = 0x80000010, NvRop = 0x80000011, NvImagePattern = 0x80000012, diff --git a/src/nv_dri.c b/src/nv_dri.c index 3257f31..ec9f129 100644 --- a/src/nv_dri.c +++ b/src/nv_dri.c @@ -244,7 +244,11 @@ Bool NVDRIGetVersion(ScrnInfoPtr pScrn) } /* temporary lock step versioning */ - if (pNv->pKernelDRMVersion->version_patchlevel != 3) { +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 4 +#error nouveau_drm.h doesn't match expected patchlevel, update libdrm. +#endif + if (pNv->pKernelDRMVersion->version_patchlevel != + NOUVEAU_DRM_HEADER_PATCHLEVEL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "wrong DRM version\n"); return FALSE; @@ -387,36 +391,3 @@ Bool NVDRIFinishScreenInit(ScrnInfoPtr pScrn) return TRUE; } -Bool NVInitAGP(ScrnInfoPtr pScrn) -{ - NVPtr pNv = NVPTR(pScrn); - unsigned long agp_size; - - agp_size = drmAgpSize(pNv->drm_fd); - if (agp_size==0) - return FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "AGP: aperture is %dMB\n", (unsigned int)(agp_size>>20)); - - if (agp_size > 16*1024*1024) - agp_size = 16*1024*1024; - - pNv->AGPScratch = NVAllocateMemory(pNv, NOUVEAU_MEM_AGP, agp_size); - if (!pNv->AGPScratch) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Unable to alloc AGP memory - DMA transfers disabled\n"); - return FALSE; - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "AGP: mapped %dMB at %p\n", - (unsigned int)(pNv->AGPScratch->size>>20), - pNv->AGPScratch->map); - - return TRUE; -} - - - - - diff --git a/src/nv_driver.c b/src/nv_driver.c index 7ddd9e2..24564e8 100644 --- a/src/nv_driver.c +++ b/src/nv_driver.c @@ -514,62 +514,6 @@ _X_EXPORT XF86ModuleData nouveauModuleData = { &nouveauVersRec, nouveauSetup, NU */ static int pix24bpp = 0; -NVAllocRec *NVAllocateMemory(NVPtr pNv, int type, int size) -{ - drm_nouveau_mem_alloc_t memalloc; - NVAllocRec *mem; - - mem = malloc(sizeof(NVAllocRec)); - if (!mem) - return NULL; - mem->type = type | NOUVEAU_MEM_MAPPED; - mem->size = size; - - memalloc.flags = mem->type; - memalloc.size = mem->size; - memalloc.alignment = 0; - memalloc.region_offset = 0; - if (drmCommandWriteRead(pNv->drm_fd, DRM_NOUVEAU_MEM_ALLOC, &memalloc, - sizeof(memalloc))) { - ErrorF("NOUVEAU_MEM_ALLOC failed. flags=0x%08x, size=%lld (%d)\n", - mem->type, mem->size, errno); - free(mem); - return NULL; - } - mem->offset=memalloc.region_offset; - - if (drmMap(pNv->drm_fd, mem->offset, mem->size, &mem->map)) { - ErrorF("drmMap() failed. offset=0x%llx, size=%lld (%d)\n", - mem->offset, mem->size, errno); - mem->map = NULL; - NVFreeMemory(pNv, mem); - return NULL; - } - - return mem; -} - -void NVFreeMemory(NVPtr pNv, NVAllocRec *mem) -{ - drm_nouveau_mem_free_t memfree; - - if (mem) { - if (mem->map) { - if (drmUnmap(mem->map, mem->size)) - ErrorF("drmUnmap() failed. map=%p, size=%lld\n", mem->map, mem->size); - } - - memfree.flags = mem->type; - memfree.region_offset = mem->offset; - if (drmCommandWriteRead(pNv->drm_fd, DRM_NOUVEAU_MEM_FREE, &memfree, - sizeof(memfree))) { - ErrorF("NOUVEAU_MEM_FREE failed. flags=0x%08x, offset=0x%llx (%d)\n", - mem->type, mem->size, errno); - } - free(mem); - } -} - static Bool NVGetRec(ScrnInfoPtr pScrn) { @@ -1739,6 +1683,37 @@ NVMapMem(ScrnInfoPtr pScrn) pNv->FB->size >> 20 ); + /*XXX: have to get these after we've allocated something, otherwise + * they're uninitialised in the DRM! + */ + pNv->VRAMSize = NVDRMGetParam(pNv, NOUVEAU_GETPARAM_FB_SIZE); + pNv->VRAMPhysical = NVDRMGetParam(pNv, NOUVEAU_GETPARAM_FB_PHYSICAL); + pNv->AGPSize = NVDRMGetParam(pNv, NOUVEAU_GETPARAM_AGP_SIZE); + pNv->AGPPhysical = NVDRMGetParam(pNv, NOUVEAU_GETPARAM_AGP_PHYSICAL); + + if (pNv->AGPSize) { + int gart_scratch_size; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "AGP: %dMiB available\n", + (unsigned int)pNv->AGPSize >> 20); + + if (pNv->AGPSize > (16*1024*1024)) + gart_scratch_size = 16*1024*1024; + else + gart_scratch_size = pNv->AGPSize; + + pNv->AGPScratch = NVAllocateMemory(pNv, NOUVEAU_MEM_AGP, + gart_scratch_size); + if (!pNv->AGPScratch) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Unable to allocate AGP memory\n"); + else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "AGP: mapped %dMiB at %p\n", + (unsigned int)pNv->AGPScratch->size>>20, + pNv->AGPScratch->map); + } + pNv->Cursor = NVAllocateMemory(pNv, NOUVEAU_MEM_FB, 64*1024); if (!pNv->Cursor) { ErrorF("Failed to allocate memory for hardware cursor\n"); @@ -1987,10 +1962,14 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (!NVMapMem(pScrn)) return FALSE; - /* Init DRM - Alloc FIFO, setup graphics objects */ + /* Init DRM - Alloc FIFO */ if (!NVInitDma(pScrn)) return FALSE; + /* setup graphics objects */ + if (!NVAccelCommonInit(pScrn)) + return FALSE; + /* Save the current state */ NVSave(pScrn); /* Initialise the first mode */ diff --git a/src/nv_exa.c b/src/nv_exa.c index 59ccc3d..3c74e32 100644 --- a/src/nv_exa.c +++ b/src/nv_exa.c @@ -314,7 +314,7 @@ static Bool NVDownloadFromScreen(PixmapPtr pSrc, NVDmaStart(pNv, NvSubMemFormat, MEMFORMAT_OFFSET_IN, 8); NVDmaNext (pNv, offset_in); - NVDmaNext (pNv, 0); + NVDmaNext (pNv, (uint32_t)(pNv->AGPScratch->offset - pNv->AGPPhysical)); NVDmaNext (pNv, pitch_in); NVDmaNext (pNv, dst_pitch); NVDmaNext (pNv, line_length); @@ -376,7 +376,7 @@ static Bool NVUploadToScreen(PixmapPtr pDst, NVDmaNext (pNv, 0); NVDmaStart(pNv, NvSubMemFormat, MEMFORMAT_OFFSET_IN, 8); - NVDmaNext (pNv, 0); + NVDmaNext (pNv, (uint32_t)(pNv->AGPScratch->offset - pNv->AGPPhysical)); NVDmaNext (pNv, offset_out); NVDmaNext (pNv, src_pitch); NVDmaNext (pNv, pitch_out); @@ -551,7 +551,7 @@ Bool NVExaInit(ScreenPtr pScreen) pNv->EXADriverPtr->memoryBase = pNv->FB->map; pNv->EXADriverPtr->offScreenBase = - pScrn->virtualX * pScrn->virtualY*pScrn->depth; + pScrn->virtualX * pScrn->virtualY*(pScrn->bitsPerPixel/8); pNv->EXADriverPtr->memorySize = pNv->FB->size; pNv->EXADriverPtr->pixmapOffsetAlign = 256; pNv->EXADriverPtr->pixmapPitchAlign = 64; diff --git a/src/nv_hw.c b/src/nv_hw.c index c5f0159..7ec9d11 100644 --- a/src/nv_hw.c +++ b/src/nv_hw.c @@ -1016,7 +1016,10 @@ void NVLoadStateExt ( nvWriteGRAPH(pNv, NV_PGRAPH_DEBUG_1, 0x72111101); nvWriteGRAPH(pNv, NV_PGRAPH_DEBUG_2_NV04, 0x11D5F071); nvWriteGRAPH(pNv, NV_PGRAPH_DEBUG_3, 0x0004FF31); - nvWriteGRAPH(pNv, NV_PGRAPH_DEBUG_3, 0x4004FF31); + nvWriteGRAPH(pNv, NV_PGRAPH_DEBUG_3, 0x4004FF31 | + 0x00d00000 | /* DATA_CHECK/DATA_CHECK_FAIL/DMA_CHECK */ + (1<<29) /* CTX_METHODS_ENABLED */ | + (1<<31) /* IGNORE_PATCHVALID_ENABLED */); if (!pNv->IRQ) { nvWriteGRAPH(pNv, NV_PGRAPH_INTR_EN, 0x0); @@ -1047,7 +1050,9 @@ void NVLoadStateExt ( if(pNv->Architecture == NV_ARCH_10) { nvWriteGRAPH(pNv, NV_PGRAPH_DEBUG_1, 0x00118700); nvWriteGRAPH(pNv, 0x0088, 0x24E00810); - nvWriteGRAPH(pNv, NV_PGRAPH_DEBUG_3, 0x55DE0030); + nvWriteGRAPH(pNv, NV_PGRAPH_DEBUG_3, 0x55DE0030 | + (1<<29) /* CTX_METHODS_ENABLED */ | + (1<<31) /* IGNORE_PATCHVALID_ENABLED */); /* nv10 second surfaces */ /* this is a copy of the surfaces. What is it for ? */ @@ -1065,7 +1070,7 @@ void NVLoadStateExt ( } else { if(pNv->Architecture >= NV_ARCH_40) { nvWriteGRAPH(pNv, NV_PGRAPH_DEBUG_1, 0x401287c0); - nvWriteGRAPH(pNv, NV_PGRAPH_DEBUG_3, 0x60de8055); + nvWriteGRAPH(pNv, NV_PGRAPH_DEBUG_3, 0xe0de8055); nvWriteGRAPH(pNv, NV_PGRAPH_DEBUG_4, 0x00008000); nvWriteGRAPH(pNv, NV_PGRAPH_LIMIT_VIOL_PIX, 0x00be3c5f); diff --git a/src/nv_mem.c b/src/nv_mem.c new file mode 100644 index 0000000..32dc25f --- /dev/null +++ b/src/nv_mem.c @@ -0,0 +1,62 @@ +#include "nv_include.h" + +NVAllocRec *NVAllocateMemory(NVPtr pNv, int type, int size) +{ + drm_nouveau_mem_alloc_t memalloc; + NVAllocRec *mem; + + mem = malloc(sizeof(NVAllocRec)); + if (!mem) + return NULL; + + memalloc.flags = type | NOUVEAU_MEM_MAPPED; + memalloc.size = size; + memalloc.alignment = 0; + if (drmCommandWriteRead(pNv->drm_fd, DRM_NOUVEAU_MEM_ALLOC, &memalloc, + sizeof(memalloc))) { + ErrorF("NOUVEAU_MEM_ALLOC failed. " + "flags=0x%08x, size=%lld (%d)\n", + mem->type, mem->size, errno); + free(mem); + return NULL; + } + mem->type = memalloc.flags; + mem->size = memalloc.size; + mem->offset = memalloc.region_offset; + + if (drmMap(pNv->drm_fd, mem->offset, mem->size, &mem->map)) { + ErrorF("drmMap() failed. offset=0x%llx, size=%lld (%d)\n", + mem->offset, mem->size, errno); + mem->map = NULL; + NVFreeMemory(pNv, mem); + return NULL; + } + + return mem; +} + +void NVFreeMemory(NVPtr pNv, NVAllocRec *mem) +{ + drm_nouveau_mem_free_t memfree; + + if (mem) { + if (mem->map) { + if (drmUnmap(mem->map, mem->size)) + ErrorF("drmUnmap() failed. " + "map=%p, size=%lld\n", + mem->map, mem->size); + } + + memfree.flags = mem->type; + memfree.region_offset = mem->offset; + if (drmCommandWriteRead(pNv->drm_fd, + DRM_NOUVEAU_MEM_FREE, &memfree, + sizeof(memfree))) { + ErrorF("NOUVEAU_MEM_FREE failed. " + "flags=0x%08x, offset=0x%llx (%d)\n", + mem->type, mem->size, errno); + } + free(mem); + } +} + diff --git a/src/nv_proto.h b/src/nv_proto.h index f943a22..4db79bd 100644 --- a/src/nv_proto.h +++ b/src/nv_proto.h @@ -3,17 +3,21 @@ #ifndef __NV_PROTO_H__ #define __NV_PROTO_H__ +/* in nv_accel_common.c */ +Bool NVAccelCommonInit(ScrnInfoPtr pScrn); + /* in nv_driver.c */ Bool NVSwitchMode(int scrnIndex, DisplayModePtr mode, int flags); void NVAdjustFrame(int scrnIndex, int x, int y, int flags); Bool NVI2CInit(ScrnInfoPtr pScrn); + +/* in nv_mem.c */ NVAllocRec *NVAllocateMemory(NVPtr pNv, int type, int size); void NVFreeMemory(NVPtr pNv, NVAllocRec *mem); /* in nv_dri.c */ unsigned int NVDRMGetParam(NVPtr pNv, unsigned int param); Bool NVDRMSetParam(NVPtr pNv, unsigned int param, unsigned int value); -Bool NVInitAGP(ScrnInfoPtr pScrn); Bool NVDRIScreenInit(ScrnInfoPtr pScrn); Bool NVDRIFinishScreenInit(ScrnInfoPtr pScrn); extern const char *drmSymbols[], *driSymbols[]; @@ -48,13 +52,13 @@ void NVDmaWait(NVPtr pNv, int size); void NVDoSync(NVPtr pNv); void NVSync(ScrnInfoPtr pScrn); void NVResetGraphics(ScrnInfoPtr pScrn); -Bool NVDmaCreateDMAObject(NVPtr pNv, int handle, int target, +Bool NVDmaCreateDMAObject(NVPtr pNv, uint32_t handle, int class, int target, CARD32 base_address, CARD32 size, int access); +Bool NVDmaCreateDMAObjectFromMem(NVPtr pNv, uint32_t handle, int class, + NVAllocRec *mem, int access); NVAllocRec *NVDmaCreateNotifier(NVPtr pNv, int handle); Bool NVDmaWaitForNotifier(NVPtr pNv, void *notifier); -Bool NVDmaCreateContextObject(NVPtr pNv, int handle, int class, CARD32 flags, - CARD32 dma_in, CARD32 dma_out, - CARD32 dma_notifier); +Bool NVDmaCreateContextObject(NVPtr pNv, int handle, int class); Bool NVInitDma(ScrnInfoPtr pScrn); /* in nv_xaa.c */ diff --git a/src/nv_type.h b/src/nv_type.h index 0827b9a..ec54053 100644 --- a/src/nv_type.h +++ b/src/nv_type.h @@ -136,12 +136,22 @@ typedef struct _NVRec { int ChipRev; Bool Primary; CARD32 IOAddress; - unsigned long VRAMPhysical; - unsigned long VRAMPhysicalSize; - NVAllocRec * FB; - NVAllocRec * Cursor; - NVAllocRec * ScratchBuffer; - NVAllocRec * AGPScratch; + + /* VRAM physical address */ + unsigned long VRAMPhysical; + /* Size of VRAM BAR */ + unsigned long VRAMPhysicalSize; + /* Accesible VRAM size (by the GPU) */ + unsigned long VRAMSize; + /* AGP physical address */ + unsigned long AGPPhysical; + /* Accesible AGP size */ + unsigned long AGPSize; + + NVAllocRec * FB; + NVAllocRec * Cursor; + NVAllocRec * ScratchBuffer; + NVAllocRec * AGPScratch; Bool NoAccel; Bool HWCursor; Bool FpScale; |