Can not setup dfp modes with xorg-server-1.1 also
[nouveau] / src / nv_accel_common.c
1 #include "nv_include.h"
2
3 static Bool
4 NVAccelInitNullObject(ScrnInfoPtr pScrn)
5 {
6         NVPtr pNv = NVPTR(pScrn);
7         static int have_object = FALSE;
8
9         if (!have_object) {
10                 if (!NVDmaCreateContextObject(pNv, NvNullObject,
11                                                    0x30))
12                         return FALSE;
13                 have_object = TRUE;
14         }
15
16         return TRUE;
17 }
18
19 uint32_t
20 NVAccelGetPixmapOffset(PixmapPtr pPix)
21 {
22         ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
23         NVPtr pNv = NVPTR(pScrn);
24         CARD32 offset;
25
26         if (pPix->drawable.type == DRAWABLE_WINDOW) {
27                 offset = pNv->FB->offset;
28         } else {
29                 offset  = (uint32_t)((unsigned long)pPix->devPrivate.ptr -
30                                 (unsigned long)pNv->FB->map);
31                 offset += pNv->FB->offset;
32         }
33
34         return offset;
35 }
36
37 static Bool
38 NVAccelInitDmaNotifier0(ScrnInfoPtr pScrn)
39 {
40         NVPtr pNv = NVPTR(pScrn);
41         static int have_object = FALSE;
42
43         if (!have_object) {
44                 pNv->Notifier0 = NVNotifierAlloc(pScrn, NvDmaNotifier0);
45                 if (!pNv->Notifier0)
46                         return FALSE;
47                 have_object = TRUE;
48         }
49
50         return TRUE;
51 }
52
53 /* FLAGS_ROP_AND, DmaFB, DmaFB, 0 */
54 static Bool
55 NVAccelInitContextSurfaces(ScrnInfoPtr pScrn)
56 {
57         NVPtr pNv = NVPTR(pScrn);
58         static int have_object = FALSE;
59         uint32_t   class;
60
61         class = (pNv->Architecture >= NV_10) ? NV10_CONTEXT_SURFACES_2D :
62                                                NV04_SURFACE;
63
64         if (!have_object) {
65                 if (!NVDmaCreateContextObject(pNv, NvContextSurfaces, class))
66                         return FALSE;
67                 have_object = TRUE;
68         }
69
70         NVDmaStart(pNv, NvContextSurfaces, NV04_SURFACE_DMA_NOTIFY, 1);
71         NVDmaNext (pNv, NvNullObject);
72         NVDmaStart(pNv, NvContextSurfaces, NV04_SURFACE_DMA_IMAGE_SOURCE, 2);
73         NVDmaNext (pNv, NvDmaFB);
74         NVDmaNext (pNv, NvDmaFB);
75
76         return TRUE;
77 }
78
79 Bool
80 NVAccelGetCtxSurf2DFormatFromPixmap(PixmapPtr pPix, int *fmt_ret)
81 {
82         switch (pPix->drawable.bitsPerPixel) {
83         case 32:
84                 *fmt_ret = SURFACE_FORMAT_A8R8G8B8;
85                 break;
86         case 24:
87                 *fmt_ret = SURFACE_FORMAT_X8R8G8B8;
88                 break;
89         case 16:
90                 *fmt_ret = SURFACE_FORMAT_R5G6B5;
91                 break;
92         case 8:
93                 *fmt_ret = SURFACE_FORMAT_Y8;
94                 break;
95         default:
96                 return FALSE;
97         }
98
99         return TRUE;
100 }
101
102 Bool
103 NVAccelGetCtxSurf2DFormatFromPicture(PicturePtr pPict, int *fmt_ret)
104 {
105         switch (pPict->format) {
106         case PICT_a8r8g8b8:
107                 *fmt_ret = SURFACE_FORMAT_A8R8G8B8;
108                 break;
109         case PICT_x8r8g8b8:
110                 *fmt_ret = SURFACE_FORMAT_X8R8G8B8;
111                 break;
112         case PICT_r5g6b5:
113                 *fmt_ret = SURFACE_FORMAT_R5G6B5;
114                 break;
115         case PICT_a8:
116                 *fmt_ret = SURFACE_FORMAT_Y8;
117                 break;
118         default:
119                 return FALSE;
120         }
121
122         return TRUE;
123 }
124
125 Bool
126 NVAccelSetCtxSurf2D(PixmapPtr psPix, PixmapPtr pdPix, int format)
127 {
128         ScrnInfoPtr pScrn = xf86Screens[psPix->drawable.pScreen->myNum];
129         NVPtr pNv = NVPTR(pScrn);
130
131         NVDmaStart(pNv, NvContextSurfaces, SURFACE_FORMAT, 4);
132         NVDmaNext (pNv, format);
133         NVDmaNext (pNv, ((uint32_t)exaGetPixmapPitch(pdPix) << 16) |
134                          (uint32_t)exaGetPixmapPitch(psPix));
135         NVDmaNext (pNv, NVAccelGetPixmapOffset(psPix));
136         NVDmaNext (pNv, NVAccelGetPixmapOffset(pdPix));
137
138         return TRUE;
139 }
140
141 /* FLAGS_ROP_AND|FLAGS_MONO, 0, 0, 0 */
142 static Bool
143 NVAccelInitImagePattern(ScrnInfoPtr pScrn)
144 {
145         NVPtr pNv = NVPTR(pScrn);
146         static int have_object = FALSE;
147         uint32_t   class;
148
149         class = NV04_IMAGE_PATTERN;
150
151         if (!have_object) {
152                 if (!NVDmaCreateContextObject(pNv, NvImagePattern, class))
153                         return FALSE;
154                 have_object = TRUE;
155         }
156
157         NVDmaStart(pNv, NvImagePattern,
158                         0x180, /*NV04_IMAGE_PATTERN_SET_DMA_NOTIFY*/ 1);
159         NVDmaNext (pNv, NvNullObject);
160         NVDmaStart(pNv, NvImagePattern, NV04_IMAGE_PATTERN_MONO_FORMAT, 3);
161 #if X_BYTE_ORDER == X_BIG_ENDIAN
162         NVDmaNext (pNv, 2 /* NV04_IMAGE_PATTERN_BIGENDIAN/LE_M1 */);
163 #else
164         NVDmaNext (pNv, 1 /* NV04_IMAGE_PATTERN_LOWENDIAN/CGA6_M1 */);
165 #endif
166         NVDmaNext (pNv, 0 /* NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_8X8 */);
167         NVDmaNext (pNv, 1 /* NV04_IMAGE_PATTERN_SELECT_MONOCHROME */);
168
169         return TRUE;
170 }
171
172 /* FLAGS_ROP_AND, 0, 0, 0 */
173 static Bool
174 NVAccelInitRasterOp(ScrnInfoPtr pScrn)
175 {
176         NVPtr pNv = NVPTR(pScrn);
177         static int have_object = FALSE;
178         uint32_t   class;
179
180         class = NV03_PRIMITIVE_RASTER_OP;
181
182         if (!have_object) {
183                 if (!NVDmaCreateContextObject(pNv, NvRop, class))
184                         return FALSE;
185                 have_object = TRUE;
186         }
187
188         NVDmaStart(pNv, NvRop, NV03_PRIMITIVE_RASTER_OP_DMA_NOTIFY, 1);
189         NVDmaNext (pNv, NvNullObject);
190
191         return TRUE;
192 }
193
194 /* FLAGS_ROP_AND | FLAGS_MONO, 0, 0, 0 */
195 static Bool
196 NVAccelInitRectangle(ScrnInfoPtr pScrn)
197 {
198         NVPtr pNv = NVPTR(pScrn);
199         static int have_object = FALSE;
200         uint32_t   class;
201
202         class = NV04_GDI_RECTANGLE_TEXT;
203
204         if (!have_object) {
205                 if (!NVDmaCreateContextObject(pNv, NvRectangle, class))
206                         return FALSE;
207                 have_object = TRUE;
208         }
209
210         NVDmaStart(pNv, NvRectangle,
211                         NV04_GDI_RECTANGLE_TEXT_SET_DMA_NOTIFY, 1);
212         NVDmaNext (pNv, NvDmaNotifier0);
213         NVDmaStart(pNv, NvRectangle,
214                         0x184 /*NV04_GDI_RECTANGLE_TEXT_SET_DMA_FONTS*/, 1);
215         NVDmaNext (pNv, NvNullObject);
216         NVDmaStart(pNv, NvRectangle, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1);
217         NVDmaNext (pNv, NvContextSurfaces);
218         NVDmaStart(pNv, NvRectangle, NV04_GDI_RECTANGLE_TEXT_ROP5, 1);
219         NVDmaNext (pNv, NvRop);
220         NVDmaStart(pNv, NvRectangle, NV04_GDI_RECTANGLE_TEXT_PATTERN, 1);
221         NVDmaNext (pNv, NvImagePattern);
222         NVDmaStart(pNv, NvRectangle, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
223         NVDmaNext (pNv, 1 /* ROP_AND */);
224         NVDmaStart(pNv, NvRectangle,
225                         0x304 /*NV04_GDI_RECTANGLE_TEXT_MONO_FORMAT*/, 1);
226         /* XXX why putting 1 like renouveau dump, swap the text */
227 #if 1 || X_BYTE_ORDER == X_BIG_ENDIAN
228         NVDmaNext (pNv, 2 /* NV04_GDI_RECTANGLE_BIGENDIAN/LE_M1 */);
229 #else
230         NVDmaNext (pNv, 1 /* NV04_GDI_RECTANGLE_LOWENDIAN/CGA6_M1 */);
231 #endif
232
233         return TRUE;
234 }
235
236 /* FLAGS_ROP_AND, DmaFB, DmaFB, 0 */
237 static Bool
238 NVAccelInitImageBlit(ScrnInfoPtr pScrn)
239 {
240         NVPtr pNv = NVPTR(pScrn);
241         static int have_object = FALSE;
242         uint32_t   class;
243
244         class = (pNv->WaitVSyncPossible) ? NV10_IMAGE_BLIT : NV_IMAGE_BLIT;
245
246         if (!have_object) {
247                 if (!NVDmaCreateContextObject(pNv, NvImageBlit, class))
248                         return FALSE;
249                 have_object = TRUE;
250         }
251
252         NVDmaStart(pNv, NvImageBlit, NV_IMAGE_BLIT_DMA_NOTIFY, 1);
253         NVDmaNext (pNv, NvDmaNotifier0);
254         NVDmaStart(pNv, NvImageBlit, NV_IMAGE_BLIT_COLOR_KEY, 1);
255         NVDmaNext (pNv, NvNullObject);
256         NVDmaStart(pNv, NvImageBlit, NV_IMAGE_BLIT_SURFACE, 1);
257         NVDmaNext (pNv, NvContextSurfaces);
258         NVDmaStart(pNv, NvImageBlit, NV_IMAGE_BLIT_CLIP_RECTANGLE, 3);
259         NVDmaNext (pNv, NvNullObject);
260         NVDmaNext (pNv, NvImagePattern);
261         NVDmaNext (pNv, NvRop);
262         NVDmaStart(pNv, NvImageBlit, NV_IMAGE_BLIT_OPERATION, 1);
263         NVDmaNext (pNv, 1 /* NV_IMAGE_BLIT_OPERATION_ROP_AND */);
264
265         if (pNv->WaitVSyncPossible) {
266                 NVDmaStart(pNv, NvImageBlit, 0x0120, 3);
267                 NVDmaNext (pNv, 0);
268                 NVDmaNext (pNv, 1);
269                 NVDmaNext (pNv, 2);
270         }
271
272         return TRUE;
273 }
274
275 /* FLAGS_SRCCOPY, DmaFB, DmaFB, 0 */
276 static Bool
277 NVAccelInitScaledImage(ScrnInfoPtr pScrn)
278 {
279         NVPtr pNv = NVPTR(pScrn);
280         static int have_object = FALSE;
281         uint32_t   class;
282
283         switch (pNv->Architecture) {
284         case NV_ARCH_04:
285                 class = NV04_SCALED_IMAGE_FROM_MEMORY;
286                 break;
287         case NV_ARCH_10:
288         case NV_ARCH_20:
289         case NV_ARCH_30:
290                 class = NV10_SCALED_IMAGE_FROM_MEMORY;
291                 break;
292         case NV_ARCH_40:
293         default:
294                 class = NV10_SCALED_IMAGE_FROM_MEMORY | 0x3000;
295                 break;
296         }
297
298         if (!have_object) {
299                 if (!NVDmaCreateContextObject(pNv, NvScaledImage, class))
300                         return FALSE;
301                 have_object = TRUE;
302         }
303
304         NVDmaStart(pNv, NvScaledImage,
305                         NV04_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY, 1);
306         NVDmaNext (pNv, NvDmaNotifier0);
307         NVDmaStart(pNv, NvScaledImage,
308                         NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1);
309         NVDmaNext (pNv, NvDmaFB); /* source object */
310         NVDmaStart(pNv, NvScaledImage,
311                         NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1);
312         NVDmaNext (pNv, NvContextSurfaces);
313         NVDmaStart(pNv, NvScaledImage, 0x188, 1); /* PATTERN */
314         NVDmaNext (pNv, NvNullObject);
315         NVDmaStart(pNv, NvScaledImage, 0x18c, 1); /* ROP */
316         NVDmaNext (pNv, NvNullObject);
317         NVDmaStart(pNv, NvScaledImage, 0x190, 1); /* BETA1 */
318         NVDmaNext (pNv, NvNullObject);
319         NVDmaStart(pNv, NvScaledImage, 0x194, 1); /* BETA4 */
320         NVDmaNext (pNv, NvNullObject);
321         NVDmaStart(pNv, NvScaledImage,
322                         NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION, 1);
323         NVDmaNext (pNv, 3 /* SRCCOPY */);
324
325         return TRUE;
326 }
327
328 /* FLAGS_NONE, 0, 0, 0 */
329 static Bool
330 NVAccelInitClipRectangle(ScrnInfoPtr pScrn)
331 {
332         NVPtr pNv = NVPTR(pScrn);
333         static int have_object = FALSE;
334         int class = NV01_CONTEXT_CLIP_RECTANGLE;
335
336         if (!have_object) {
337                 if (!NVDmaCreateContextObject(pNv, NvClipRectangle, class))
338                         return FALSE;
339                 have_object = TRUE;
340         }
341
342         NVDmaStart(pNv, NvClipRectangle, 0x180, 1); /* DMA_NOTIFY */
343         NVDmaNext (pNv, NvNullObject);
344
345         return TRUE;
346 }
347
348 /* FLAGS_ROP_AND | FLAGS_CLIP_ENABLE, 0, 0, 0 */
349 static Bool
350 NVAccelInitSolidLine(ScrnInfoPtr pScrn)
351 {
352         NVPtr pNv = NVPTR(pScrn);
353         static int have_object = FALSE;
354         int class = NV04_SOLID_LINE;
355
356         if (!have_object) {
357                 if (!NVDmaCreateContextObject(pNv, NvSolidLine, class))
358                         return FALSE;
359                 have_object = TRUE;
360         }
361
362         NVDmaStart(pNv, NvSolidLine, NV04_SOLID_LINE_CLIP_RECTANGLE, 3);
363         NVDmaNext (pNv, NvClipRectangle);
364         NVDmaNext (pNv, NvImagePattern);
365         NVDmaNext (pNv, NvRop);
366         NVDmaStart(pNv, NvSolidLine, NV04_SOLID_LINE_SURFACE, 1);
367         NVDmaNext (pNv, NvContextSurfaces);
368         NVDmaStart(pNv, NvSolidLine, NV04_SOLID_LINE_OPERATION, 1);
369         NVDmaNext (pNv, 1); /* ROP_AND */
370
371         return TRUE;
372 }
373
374 /* FLAGS_NONE, NvDmaFB, NvDmaAGP, NvDmaNotifier0 */
375 static Bool
376 NVAccelInitMemFormat(ScrnInfoPtr pScrn)
377 {
378         NVPtr pNv = NVPTR(pScrn);
379         static int have_object = FALSE;
380         uint32_t   class;
381
382         class = NV_MEMORY_TO_MEMORY_FORMAT;
383
384         if (!have_object) {
385                 if (!NVDmaCreateContextObject(pNv, NvMemFormat, class))
386                                 return FALSE;
387                 have_object = TRUE;
388         }
389
390         NVDmaStart(pNv, NvMemFormat,
391                         NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
392         NVDmaNext (pNv, NvDmaNotifier0);
393         NVDmaStart(pNv, NvMemFormat,
394                         NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_IN, 2);
395         NVDmaNext (pNv, NvDmaFB);
396         NVDmaNext (pNv, NvDmaFB);
397
398         pNv->M2MFDirection = -1;
399         return TRUE;
400 }
401
402 static Bool
403 NVAccelInitImageFromCpu(ScrnInfoPtr pScrn)
404 {
405         NVPtr pNv = NVPTR(pScrn);
406         static int have_object = FALSE;
407         uint32_t   class;
408
409         switch (pNv->Architecture) {
410         case NV_ARCH_04:
411                 class = NV05_IMAGE_FROM_CPU;
412                 break;
413         case NV_ARCH_10:
414         case NV_ARCH_20:
415         case NV_ARCH_30:
416         case NV_ARCH_40:
417         default:
418                 class = NV10_IMAGE_FROM_CPU;
419                 break;
420         }
421
422         if (!have_object) {
423                 if (!NVDmaCreateContextObject(pNv, NvImageFromCpu, class))
424                         return FALSE;
425                 have_object = TRUE;
426         }
427
428         NVDmaStart(pNv, NvImageFromCpu, NV05_IMAGE_FROM_CPU_DMA_NOTIFY, 1);
429         NVDmaNext (pNv, NvDmaNotifier0);
430         NVDmaStart(pNv, NvImageFromCpu, NV05_IMAGE_FROM_CPU_CLIP_RECTANGLE, 1);
431         NVDmaNext (pNv, NvNullObject);
432         NVDmaStart(pNv, NvImageFromCpu, NV05_IMAGE_FROM_CPU_PATTERN, 1); /* PATTERN */
433         NVDmaNext (pNv, NvNullObject);
434         NVDmaStart(pNv, NvImageFromCpu, NV05_IMAGE_FROM_CPU_ROP, 1); /* ROP */
435         NVDmaNext (pNv, NvNullObject);
436         NVDmaStart(pNv, NvImageFromCpu, 0x194, 1); /* BETA1 */
437         NVDmaNext (pNv, NvNullObject);
438         NVDmaStart(pNv, NvImageFromCpu, 0x198, 1); /* BETA4 */
439         NVDmaNext (pNv, NvNullObject);
440         NVDmaStart(pNv, NvImageFromCpu, NV05_IMAGE_FROM_CPU_SURFACE, 1);
441         NVDmaNext (pNv, NvContextSurfaces);
442         NVDmaStart(pNv, NvImageFromCpu, NV05_IMAGE_FROM_CPU_OPERATION, 1);
443         NVDmaNext (pNv, 3 /* SRCCOPY */);
444         return TRUE;
445 }
446
447 #define INIT_CONTEXT_OBJECT(name) do {                                        \
448         ret = NVAccelInit##name(pScrn);                                       \
449         if (!ret) {                                                           \
450                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,                         \
451                            "Failed to initialise context object: "#name       \
452                            " (%d)\n", ret);                                   \
453                 return FALSE;                                                 \
454         }                                                                     \
455 } while(0)
456
457 Bool
458 NVAccelCommonInit(ScrnInfoPtr pScrn)
459 {
460         NVPtr pNv = NVPTR(pScrn);
461         Bool ret;
462         if(pNv->NoAccel) return TRUE;
463
464         INIT_CONTEXT_OBJECT(NullObject);
465         INIT_CONTEXT_OBJECT(DmaNotifier0);
466
467         INIT_CONTEXT_OBJECT(ContextSurfaces);
468         INIT_CONTEXT_OBJECT(ImagePattern);
469         INIT_CONTEXT_OBJECT(RasterOp);
470         INIT_CONTEXT_OBJECT(Rectangle);
471         INIT_CONTEXT_OBJECT(ImageBlit);
472         INIT_CONTEXT_OBJECT(ScaledImage);
473
474         /* XAA-only */
475         INIT_CONTEXT_OBJECT(ClipRectangle);
476         INIT_CONTEXT_OBJECT(SolidLine);
477
478         /* EXA-only */
479         INIT_CONTEXT_OBJECT(MemFormat);
480         INIT_CONTEXT_OBJECT(ImageFromCpu);
481
482         /* 3D init */
483         switch (pNv->Architecture) {
484         case NV_ARCH_40:
485                 INIT_CONTEXT_OBJECT(NV40TCL);
486                 break;
487         default:
488                 break;
489         }
490
491         return TRUE;
492 }
493