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