2 #include "nv_include.h"
5 void NVDmaKickoff(NVPtr pNv)
7 if(pNv->dmaCurrent != pNv->dmaPut) {
8 pNv->dmaPut = pNv->dmaCurrent;
9 WRITE_PUT(pNv, pNv->dmaPut);
13 void NVDmaKickoffCallback(NVPtr pNv)
16 pNv->DMAKickoffCallback = NULL;
19 /* There is a HW race condition with videoram command buffers.
20 * You can't jump to the location of your put offset. We write put
21 * at the jump offset + SKIPS dwords with noop padding in between
22 * to solve this problem
26 void NVDmaWait (ScrnInfoPtr pScrn, int size)
28 NVPtr pNv = NVPTR(pScrn);
34 t_start = GetTimeInMillis();
35 while(pNv->dmaFree < size) {
36 dmaGet = READ_GET(pNv);
38 if(pNv->dmaPut >= dmaGet) {
39 pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent;
40 if(pNv->dmaFree < size) {
41 NVDmaNext(pNv, (0x20000000|pNv->fifo.put_base));
43 if(pNv->dmaPut <= SKIPS) /* corner case - will be idle */
44 WRITE_PUT(pNv, SKIPS + 1);
46 if (GetTimeInMillis() - t_start > 2000)
48 dmaGet = READ_GET(pNv);
49 } while(dmaGet <= SKIPS);
51 WRITE_PUT(pNv, SKIPS);
52 pNv->dmaCurrent = pNv->dmaPut = SKIPS;
53 pNv->dmaFree = dmaGet - (SKIPS + 1);
56 pNv->dmaFree = dmaGet - pNv->dmaCurrent - 1;
58 if (GetTimeInMillis() - t_start > 2000)
63 static void NVDumpLockupInfo(NVPtr pNv)
66 start=READ_GET(pNv)-20;
68 xf86DrvMsg(0, X_INFO, "Fifo dump (lockup 0x%04x,0x%04x):\n",READ_GET(pNv),pNv->dmaPut);
69 for(i=start;i<pNv->dmaPut+10;i++)
70 xf86DrvMsg(0, X_INFO, "[0x%04x] 0x%08x\n", i, pNv->dmaBase[i]);
71 xf86DrvMsg(0, X_INFO, "End of fifo dump\n");
75 NVLockedUp(ScrnInfoPtr pScrn)
77 NVPtr pNv = NVPTR(pScrn);
79 /* avoid re-entering FatalError on shutdown */
84 NVDumpLockupInfo(pNv);
86 FatalError("DMA queue hang: dmaPut=%x, current=%x, status=%x\n",
87 pNv->dmaPut, READ_GET(pNv), pNv->PGRAPH[NV_PGRAPH_STATUS/4]);
90 void NVSync(ScrnInfoPtr pScrn)
92 NVPtr pNv = NVPTR(pScrn);
93 int t_start, timeout = 2000;
98 if(pNv->DMAKickoffCallback)
99 (*pNv->DMAKickoffCallback)(pNv);
101 /* Wait for entire FIFO to be processed */
102 t_start = GetTimeInMillis();
103 while((GetTimeInMillis() - t_start) < timeout &&
104 (READ_GET(pNv) != pNv->dmaPut));
105 if ((GetTimeInMillis() - t_start) >= timeout) {
110 /* Wait for channel to go completely idle */
111 NVNotifierReset(pScrn, pNv->Notifier0);
112 NVDmaStart(pNv, NvSubImageBlit, 0x104, 1);
114 NVDmaStart(pNv, NvSubImageBlit, 0x100, 1);
117 if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, timeout))
121 void NVResetGraphics(ScrnInfoPtr pScrn)
123 NVPtr pNv = NVPTR(pScrn);
124 CARD32 surfaceFormat, patternFormat, rectFormat, lineFormat;
127 if(pNv->NoAccel) return;
129 pitch = pNv->CurrentLayout.displayWidth * (pNv->CurrentLayout.bitsPerPixel >> 3);
131 pNv->dmaPut = pNv->dmaCurrent = READ_GET(pNv);
132 pNv->dmaMax = (pNv->fifo.cmdbuf_size >> 2) - 1;
133 pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent;
135 /* assert there's enough room for the skips */
136 if(pNv->dmaFree <= SKIPS)
137 NVDmaWait(pScrn, SKIPS);
138 for (i=0; i<SKIPS; i++) {
142 pNv->dmaFree -= SKIPS;
144 NVAccelCommonInit(pScrn);
147 NVDmaSetObjectOnSubchannel(pNv, NvSubContextSurfaces, NvContextSurfaces);
148 NVDmaSetObjectOnSubchannel(pNv, NvSubRectangle , NvRectangle );
149 NVDmaSetObjectOnSubchannel(pNv, NvSubScaledImage , NvScaledImage );
151 NVDmaSetObjectOnSubchannel(pNv, NvSubRop , NvRop );
152 NVDmaSetObjectOnSubchannel(pNv, NvSubImagePattern, NvImagePattern );
153 NVDmaSetObjectOnSubchannel(pNv, NvSubImageBlit , NvImageBlit );
155 if (pNv->GARTScratch)
156 NVDmaSetObjectOnSubchannel(pNv, NvSubMemFormat, NvMemFormat);
157 } else if (!pNv->useEXA) {
158 NVDmaSetObjectOnSubchannel(pNv, NvSubClipRectangle, NvClipRectangle);
159 NVDmaSetObjectOnSubchannel(pNv, NvSubSolidLine, NvSolidLine);
162 switch(pNv->CurrentLayout.depth) {
164 surfaceFormat = SURFACE_FORMAT_X8R8G8B8;
165 patternFormat = PATTERN_FORMAT_DEPTH24;
166 rectFormat = RECT_FORMAT_DEPTH24;
167 lineFormat = LINE_FORMAT_DEPTH24;
171 surfaceFormat = SURFACE_FORMAT_R5G6B5;
172 patternFormat = PATTERN_FORMAT_DEPTH16;
173 rectFormat = RECT_FORMAT_DEPTH16;
174 lineFormat = LINE_FORMAT_DEPTH16;
177 surfaceFormat = SURFACE_FORMAT_Y8;
178 patternFormat = PATTERN_FORMAT_DEPTH8;
179 rectFormat = RECT_FORMAT_DEPTH8;
180 lineFormat = LINE_FORMAT_DEPTH8;
184 NVDmaStart(pNv, NvSubContextSurfaces, SURFACE_FORMAT, 4);
185 NVDmaNext (pNv, surfaceFormat);
186 NVDmaNext (pNv, pitch | (pitch << 16));
187 NVDmaNext (pNv, (uint32_t)pNv->FB->offset);
188 NVDmaNext (pNv, (uint32_t)pNv->FB->offset);
190 NVDmaStart(pNv, NvSubImagePattern, PATTERN_FORMAT, 1);
191 NVDmaNext (pNv, patternFormat);
193 NVDmaStart(pNv, NvSubRectangle, RECT_FORMAT, 1);
194 NVDmaNext (pNv, rectFormat);
197 NVDmaStart(pNv, NvSubSolidLine, LINE_FORMAT, 1);
198 NVDmaNext (pNv, lineFormat);
201 pNv->currentRop = ~0; /* set to something invalid */
202 NVSetRopSolid(pScrn, GXcopy, ~0);
204 pNv->M2MFDirection = -1; /* invalid */
205 /*NVDmaKickoff(pNv);*/
208 Bool NVDmaCreateContextObject(NVPtr pNv, int handle, int class)
210 struct drm_nouveau_grobj_alloc cto;
213 cto.channel = pNv->fifo.channel;
216 ret = drmCommandWrite(pNv->drm_fd, DRM_NOUVEAU_GROBJ_ALLOC,
221 static void NVInitDmaCB(ScrnInfoPtr pScrn)
223 NVPtr pNv = NVPTR(pScrn);
224 unsigned int cb_location;
228 /* I'm not bothering to check for failures here, the DRM will fall back
229 * on defaults if anything's wrong (ie. out of AGP, invalid sizes)
232 if (pNv->GARTScratch)
233 cb_location = NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI_ACCEPTABLE;
236 cb_location = NOUVEAU_MEM_FB;
237 if((s = (char *)xf86GetOptValString(pNv->Options, OPTION_CMDBUF_LOCATION))) {
238 if(!xf86NameCmp(s, "AGP"))
239 cb_location = NOUVEAU_MEM_AGP;
240 else if (!xf86NameCmp(s, "VRAM"))
241 cb_location = NOUVEAU_MEM_FB;
242 else if (!xf86NameCmp(s, "PCI"))
243 cb_location = NOUVEAU_MEM_PCI;
245 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid value \"%s\" for CBLocation\n", s);
247 NVDRMSetParam(pNv, NOUVEAU_SETPARAM_CMDBUF_LOCATION, cb_location);
249 /* CBSize == size of space reserved for *all* FIFOs in MiB */
250 if (xf86GetOptValInteger(pNv->Options, OPTION_CMDBUF_SIZE, &cb_size))
251 NVDRMSetParam(pNv, NOUVEAU_SETPARAM_CMDBUF_SIZE, (cb_size<<20));
254 Bool NVInitDma(ScrnInfoPtr pScrn)
256 NVPtr pNv = NVPTR(pScrn);
264 pNv->fifo.fb_ctxdma_handle = NvDmaFB;
265 pNv->fifo.tt_ctxdma_handle = NvDmaTT;
266 ret = drmCommandWriteRead(pNv->drm_fd, DRM_NOUVEAU_FIFO_ALLOC,
267 &pNv->fifo, sizeof(pNv->fifo));
269 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
270 "Could not allocate GPU channel: %d\n", ret);
274 ret = drmMap(pNv->drm_fd, pNv->fifo.cmdbuf, pNv->fifo.cmdbuf_size,
275 (drmAddressPtr)&pNv->dmaBase);
277 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
278 "Failed to map DMA push buffer: %d\n", ret);
282 ret = drmMap(pNv->drm_fd, pNv->fifo.ctrl, pNv->fifo.ctrl_size,
283 (drmAddressPtr)&pNv->FIFO);
285 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
286 "Failed to map FIFO control regs: %d\n", ret);
290 ret = drmMap(pNv->drm_fd, pNv->fifo.notifier, pNv->fifo.notifier_size,
291 (drmAddressPtr)&pNv->NotifierBlock);
293 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
294 "Failed to map notifier block: %d\n", ret);
298 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
299 "Using FIFO channel %d\n", pNv->fifo.channel);
300 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
301 " Control registers : %p (0x%08x)\n",
302 pNv->FIFO, pNv->fifo.ctrl);
303 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
304 " DMA command buffer: %p (0x%08x)\n",
305 pNv->dmaBase, pNv->fifo.cmdbuf);
306 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
307 " DMA cmdbuf length : %d KiB\n",
308 pNv->fifo.cmdbuf_size / 1024);
309 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
310 " DMA base PUT : 0x%08x\n", pNv->fifo.put_base);
312 pNv->dmaPut = pNv->dmaCurrent = READ_GET(pNv);
313 pNv->dmaMax = (pNv->fifo.cmdbuf_size >> 2) - 1;
314 pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent;
316 for (i=0; i<SKIPS; i++)
318 pNv->dmaFree -= SKIPS;