summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2007-02-28 15:30:52 +1100
committerBen Skeggs <skeggsb@gmail.com>2007-02-28 15:30:52 +1100
commitda1dd87acb7061b4772c271dc3c9071a3b160e8a (patch)
tree220c07d3be22c5f7e821ec5fa7232818fc40b987
parent7e5f90b264fdb3081250ff16748164998b6461a6 (diff)
downloadxorg-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.am2
-rw-r--r--src/nv_accel_common.c384
-rw-r--r--src/nv_dma.c170
-rw-r--r--src/nv_dma.h1
-rw-r--r--src/nv_dri.c39
-rw-r--r--src/nv_driver.c93
-rw-r--r--src/nv_exa.c6
-rw-r--r--src/nv_hw.c11
-rw-r--r--src/nv_mem.c62
-rw-r--r--src/nv_proto.h14
-rw-r--r--src/nv_type.h22
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;