gl: updated glxext.h to version 27
[mesa.git] / src / mesa / drivers / dri / unichrome / server / via_dri.c
1 /*
2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <unistd.h>
30
31 #include "driver.h"
32 #include "drm.h"
33 #include "imports.h"
34
35 #include "dri_util.h"
36
37 #include "via_context.h"
38 #include "via_dri.h"
39 #include "via_driver.h"
40 #include "xf86drm.h"
41
42 static void VIAEnableMMIO(DRIDriverContext * ctx);
43 static void VIADisableMMIO(DRIDriverContext * ctx);
44 static void VIADisableExtendedFIFO(DRIDriverContext *ctx);
45 static void VIAEnableExtendedFIFO(DRIDriverContext *ctx);
46 static void VIAInitialize2DEngine(DRIDriverContext *ctx);
47 static void VIAInitialize3DEngine(DRIDriverContext *ctx);
48
49 static int VIADRIScreenInit(DRIDriverContext * ctx);
50 static void VIADRICloseScreen(DRIDriverContext * ctx);
51 static int VIADRIFinishScreenInit(DRIDriverContext * ctx);
52
53 /* _SOLO : missing macros normally defined by X code */
54 #define xf86DrvMsg(a, b, ...) fprintf(stderr, __VA_ARGS__)
55 #define MMIO_IN8(base, addr) ((*(((volatile uint8_t*)base)+(addr)))+0)
56 #define MMIO_OUT8(base, addr, val) ((*(((volatile uint8_t*)base)+(addr)))=((uint8_t)val))
57 #define MMIO_OUT16(base, addr, val) ((*(volatile uint16_t*)(((uint8_t*)base)+(addr)))=((uint16_t)val))
58
59 #define VIDEO 0
60 #define AGP 1
61 #define AGP_PAGE_SIZE 4096
62 #define AGP_PAGES 8192
63 #define AGP_SIZE (AGP_PAGE_SIZE * AGP_PAGES)
64 #define AGP_CMDBUF_PAGES 512
65 #define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES)
66
67 static char VIAKernelDriverName[] = "via";
68 static char VIAClientDriverName[] = "unichrome";
69
70 static int VIADRIAgpInit(const DRIDriverContext *ctx, VIAPtr pVia);
71 static int VIADRIPciInit(DRIDriverContext * ctx, VIAPtr pVia);
72 static int VIADRIFBInit(DRIDriverContext * ctx, VIAPtr pVia);
73 static int VIADRIKernelInit(DRIDriverContext * ctx, VIAPtr pVia);
74 static int VIADRIMapInit(DRIDriverContext * ctx, VIAPtr pVia);
75
76 static void VIADRIIrqInit( DRIDriverContext *ctx )
77 {
78 VIAPtr pVia = VIAPTR(ctx);
79 VIADRIPtr pVIADRI = pVia->devPrivate;
80
81 pVIADRI->irqEnabled = drmGetInterruptFromBusID(pVia->drmFD,
82 ctx->pciBus,
83 ctx->pciDevice,
84 ctx->pciFunc);
85
86 if ((drmCtlInstHandler(pVia->drmFD, pVIADRI->irqEnabled))) {
87 xf86DrvMsg(pScreen->myNum, X_WARNING,
88 "[drm] Failure adding irq handler. "
89 "Falling back to irq-free operation.\n");
90 pVIADRI->irqEnabled = 0;
91 }
92
93 if (pVIADRI->irqEnabled)
94 xf86DrvMsg(pScreen->myNum, X_INFO,
95 "[drm] Irq handler installed, using IRQ %d.\n",
96 pVIADRI->irqEnabled);
97 }
98
99 static void VIADRIIrqExit( DRIDriverContext *ctx ) {
100 VIAPtr pVia = VIAPTR(ctx);
101 VIADRIPtr pVIADRI = pVia->devPrivate;
102
103 if (pVIADRI->irqEnabled) {
104 if (drmCtlUninstHandler(pVia->drmFD)) {
105 xf86DrvMsg(pScreen-myNum, X_INFO,"[drm] Irq handler uninstalled.\n");
106 } else {
107 xf86DrvMsg(pScreen->myNum, X_ERROR,
108 "[drm] Could not uninstall irq handler.\n");
109 }
110 }
111 }
112
113 static void VIADRIRingBufferCleanup(DRIDriverContext *ctx)
114 {
115 VIAPtr pVia = VIAPTR(ctx);
116 VIADRIPtr pVIADRI = pVia->devPrivate;
117 drm_via_dma_init_t ringBufInit;
118
119 if (pVIADRI->ringBufActive) {
120 xf86DrvMsg(pScreen->myNum, X_INFO,
121 "[drm] Cleaning up DMA ring-buffer.\n");
122 ringBufInit.func = VIA_CLEANUP_DMA;
123 if (drmCommandWrite(pVia->drmFD, DRM_VIA_DMA_INIT, &ringBufInit,
124 sizeof(ringBufInit))) {
125 xf86DrvMsg(pScreen->myNum, X_WARNING,
126 "[drm] Failed to clean up DMA ring-buffer: %d\n", errno);
127 }
128 pVIADRI->ringBufActive = 0;
129 }
130 }
131
132 static int VIADRIRingBufferInit(DRIDriverContext *ctx)
133 {
134 VIAPtr pVia = VIAPTR(ctx);
135 VIADRIPtr pVIADRI = pVia->devPrivate;
136 drm_via_dma_init_t ringBufInit;
137 drmVersionPtr drmVer;
138
139 pVIADRI->ringBufActive = 0;
140
141 if (NULL == (drmVer = drmGetVersion(pVia->drmFD))) {
142 return GL_FALSE;
143 }
144
145 if (((drmVer->version_major <= 1) && (drmVer->version_minor <= 3))) {
146 return GL_FALSE;
147 }
148
149 /*
150 * Info frome code-snippet on DRI-DEVEL list; Erdi Chen.
151 */
152
153 switch (pVia->ChipId) {
154 case PCI_CHIP_VT3259:
155 ringBufInit.reg_pause_addr = 0x40c;
156 break;
157 default:
158 ringBufInit.reg_pause_addr = 0x418;
159 break;
160 }
161
162 ringBufInit.offset = pVia->agpSize;
163 ringBufInit.size = AGP_CMDBUF_SIZE;
164 ringBufInit.func = VIA_INIT_DMA;
165 if (drmCommandWrite(pVia->drmFD, DRM_VIA_DMA_INIT, &ringBufInit,
166 sizeof(ringBufInit))) {
167 xf86DrvMsg(pScreen->myNum, X_ERROR,
168 "[drm] Failed to initialize DMA ring-buffer: %d\n", errno);
169 return GL_FALSE;
170 }
171 xf86DrvMsg(pScreen->myNum, X_INFO,
172 "[drm] Initialized AGP ring-buffer, size 0x%lx at AGP offset 0x%lx.\n",
173 ringBufInit.size, ringBufInit.offset);
174
175 pVIADRI->ringBufActive = 1;
176 return GL_TRUE;
177 }
178
179 static int VIADRIAgpInit(const DRIDriverContext *ctx, VIAPtr pVia)
180 {
181 unsigned long agp_phys;
182 drmAddress agpaddr;
183 VIADRIPtr pVIADRI;
184 pVIADRI = pVia->devPrivate;
185 pVia->agpSize = 0;
186
187 if (drmAgpAcquire(pVia->drmFD) < 0) {
188 xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpAcquire failed %d\n", errno);
189 return GL_FALSE;
190 }
191
192 if (drmAgpEnable(pVia->drmFD, drmAgpGetMode(pVia->drmFD)&~0x0) < 0) {
193 xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpEnable failed\n");
194 return GL_FALSE;
195 }
196
197 xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] drmAgpEnabled succeeded\n");
198
199 if (drmAgpAlloc(pVia->drmFD, AGP_SIZE, 0, &agp_phys, &pVia->agpHandle) < 0) {
200 xf86DrvMsg(pScreen->myNum, X_ERROR,
201 "[drm] drmAgpAlloc failed\n");
202 drmAgpRelease(pVia->drmFD);
203 return GL_FALSE;
204 }
205
206 if (drmAgpBind(pVia->drmFD, pVia->agpHandle, 0) < 0) {
207 xf86DrvMsg(pScreen->myNum, X_ERROR,
208 "[drm] drmAgpBind failed\n");
209 drmAgpFree(pVia->drmFD, pVia->agpHandle);
210 drmAgpRelease(pVia->drmFD);
211
212 return GL_FALSE;
213 }
214
215 /*
216 * Place the ring-buffer last in the AGP region, and restrict the
217 * public map not to include the buffer for security reasons.
218 */
219
220 pVia->agpSize = AGP_SIZE - AGP_CMDBUF_SIZE;
221 pVia->agpAddr = drmAgpBase(pVia->drmFD);
222 xf86DrvMsg(pScreen->myNum, X_INFO,
223 "[drm] agpAddr = 0x%08lx\n",pVia->agpAddr);
224
225 pVIADRI->agp.size = pVia->agpSize;
226 if (drmAddMap(pVia->drmFD, (drm_handle_t)0,
227 pVIADRI->agp.size, DRM_AGP, 0,
228 &pVIADRI->agp.handle) < 0) {
229 xf86DrvMsg(pScreen->myNum, X_ERROR,
230 "[drm] Failed to map public agp area\n");
231 pVIADRI->agp.size = 0;
232 return GL_FALSE;
233 }
234 /* Map AGP from kernel to Xserver - Not really needed */
235 drmMap(pVia->drmFD, pVIADRI->agp.handle,pVIADRI->agp.size, &agpaddr);
236
237 xf86DrvMsg(pScreen->myNum, X_INFO,
238 "[drm] agpAddr = 0x%08lx\n", pVia->agpAddr);
239 xf86DrvMsg(pScreen->myNum, X_INFO,
240 "[drm] agpSize = 0x%08lx\n", pVia->agpSize);
241 xf86DrvMsg(pScreen->myNum, X_INFO,
242 "[drm] agp physical addr = 0x%08lx\n", agp_phys);
243
244 {
245 drm_via_agp_t agp;
246 agp.offset = 0;
247 agp.size = AGP_SIZE-AGP_CMDBUF_SIZE;
248 if (drmCommandWrite(pVia->drmFD, DRM_VIA_AGP_INIT, &agp,
249 sizeof(drm_via_agp_t)) < 0) {
250 drmUnmap(&agpaddr,pVia->agpSize);
251 drmRmMap(pVia->drmFD,pVIADRI->agp.handle);
252 drmAgpUnbind(pVia->drmFD, pVia->agpHandle);
253 drmAgpFree(pVia->drmFD, pVia->agpHandle);
254 drmAgpRelease(pVia->drmFD);
255 return GL_FALSE;
256 }
257 }
258
259 return GL_TRUE;
260 }
261
262 static int VIADRIFBInit(DRIDriverContext * ctx, VIAPtr pVia)
263 {
264 int FBSize = pVia->FBFreeEnd-pVia->FBFreeStart;
265 int FBOffset = pVia->FBFreeStart;
266 VIADRIPtr pVIADRI = pVia->devPrivate;
267 pVIADRI->fbOffset = FBOffset;
268 pVIADRI->fbSize = pVia->videoRambytes;
269
270 {
271 drm_via_fb_t fb;
272 fb.offset = FBOffset;
273 fb.size = FBSize;
274
275 if (drmCommandWrite(pVia->drmFD, DRM_VIA_FB_INIT, &fb,
276 sizeof(drm_via_fb_t)) < 0) {
277 xf86DrvMsg(pScreen->myNum, X_ERROR,
278 "[drm] failed to init frame buffer area\n");
279 return GL_FALSE;
280 } else {
281 xf86DrvMsg(pScreen->myNum, X_INFO,
282 "[drm] FBFreeStart= 0x%08x FBFreeEnd= 0x%08x "
283 "FBSize= 0x%08x\n",
284 pVia->FBFreeStart, pVia->FBFreeEnd, FBSize);
285 return GL_TRUE;
286 }
287 }
288 }
289
290 static int VIADRIPciInit(DRIDriverContext * ctx, VIAPtr pVia)
291 {
292 return GL_TRUE;
293 }
294
295 static int VIADRIScreenInit(DRIDriverContext * ctx)
296 {
297 VIAPtr pVia = VIAPTR(ctx);
298 VIADRIPtr pVIADRI;
299 int err;
300
301 #if 0
302 ctx->shared.SAREASize = ((sizeof(drm_sarea_t) + 0xfff) & 0x1000);
303 #else
304 if (sizeof(drm_sarea_t)+sizeof(drm_via_sarea_t) > SAREA_MAX) {
305 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
306 "Data does not fit in SAREA\n");
307 return GL_FALSE;
308 }
309 ctx->shared.SAREASize = SAREA_MAX;
310 #endif
311
312 ctx->drmFD = drmOpen(VIAKernelDriverName, NULL);
313 if (ctx->drmFD < 0) {
314 fprintf(stderr, "[drm] drmOpen failed\n");
315 return 0;
316 }
317 pVia->drmFD = ctx->drmFD;
318
319 err = drmSetBusid(ctx->drmFD, ctx->pciBusID);
320 if (err < 0) {
321 fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n",
322 ctx->drmFD, ctx->pciBusID, strerror(-err));
323 return 0;
324 }
325
326 err = drmAddMap(ctx->drmFD, 0, ctx->shared.SAREASize, DRM_SHM,
327 DRM_CONTAINS_LOCK, &ctx->shared.hSAREA);
328 if (err < 0) {
329 fprintf(stderr, "[drm] drmAddMap failed\n");
330 return 0;
331 }
332 fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n",
333 ctx->shared.SAREASize, ctx->shared.hSAREA);
334
335 if (drmMap(ctx->drmFD,
336 ctx->shared.hSAREA,
337 ctx->shared.SAREASize,
338 (drmAddressPtr)(&ctx->pSAREA)) < 0)
339 {
340 fprintf(stderr, "[drm] drmMap failed\n");
341 return 0;
342 }
343 memset(ctx->pSAREA, 0, ctx->shared.SAREASize);
344 fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",
345 ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize);
346
347 /* Need to AddMap the framebuffer and mmio regions here:
348 */
349 if (drmAddMap(ctx->drmFD,
350 (drm_handle_t)ctx->FBStart,
351 ctx->FBSize,
352 DRM_FRAME_BUFFER,
353 #ifndef _EMBEDDED
354 0,
355 #else
356 DRM_READ_ONLY,
357 #endif
358 &ctx->shared.hFrameBuffer) < 0)
359 {
360 fprintf(stderr, "[drm] drmAddMap framebuffer failed\n");
361 return 0;
362 }
363
364 fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n",
365 ctx->shared.hFrameBuffer);
366
367 pVIADRI = (VIADRIPtr) CALLOC(sizeof(VIADRIRec));
368 if (!pVIADRI) {
369 drmClose(ctx->drmFD);
370 return GL_FALSE;
371 }
372 pVia->devPrivate = pVIADRI;
373 ctx->driverClientMsg = pVIADRI;
374 ctx->driverClientMsgSize = sizeof(*pVIADRI);
375
376 /* DRIScreenInit doesn't add all the common mappings. Add additional mappings here. */
377 if (!VIADRIMapInit(ctx, pVia)) {
378 VIADRICloseScreen(ctx);
379 return GL_FALSE;
380 }
381
382 pVIADRI->regs.size = VIA_MMIO_REGSIZE;
383 pVIADRI->regs.handle = pVia->registerHandle;
384 xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] mmio Registers = 0x%08lx\n",
385 pVIADRI->regs.handle);
386
387 if (drmMap(pVia->drmFD,
388 pVIADRI->regs.handle,
389 pVIADRI->regs.size,
390 (drmAddress *)&pVia->MapBase) != 0)
391 {
392 VIADRICloseScreen(ctx);
393 return GL_FALSE;
394 }
395
396 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] mmio mapped.\n" );
397
398 VIAEnableMMIO(ctx);
399
400 /* Get video memory clock. */
401 VGAOUT8(0x3D4, 0x3D);
402 pVia->MemClk = (VGAIN8(0x3D5) & 0xF0) >> 4;
403 xf86DrvMsg(0, X_INFO, "[dri] MemClk (0x%x)\n", pVia->MemClk);
404
405 /* 3D rendering has noise if not enabled. */
406 VIAEnableExtendedFIFO(ctx);
407
408 VIAInitialize2DEngine(ctx);
409
410 /* Must disable MMIO or 3D won't work. */
411 VIADisableMMIO(ctx);
412
413 VIAInitialize3DEngine(ctx);
414
415 pVia->IsPCI = !VIADRIAgpInit(ctx, pVia);
416
417 if (pVia->IsPCI) {
418 VIADRIPciInit(ctx, pVia);
419 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] use pci.\n" );
420 }
421 else
422 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] use agp.\n" );
423
424 if (!(VIADRIFBInit(ctx, pVia))) {
425 VIADRICloseScreen(ctx);
426 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[dri] frame buffer initialize fail .\n" );
427 return GL_FALSE;
428 }
429
430 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] frame buffer initialized.\n" );
431
432 return VIADRIFinishScreenInit(ctx);
433 }
434
435 static void
436 VIADRICloseScreen(DRIDriverContext * ctx)
437 {
438 VIAPtr pVia = VIAPTR(ctx);
439 VIADRIPtr pVIADRI=(VIADRIPtr)pVia->devPrivate;
440
441 VIADRIRingBufferCleanup(ctx);
442
443 if (pVia->MapBase) {
444 xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Unmapping MMIO registers\n");
445 drmUnmap(pVia->MapBase, pVIADRI->regs.size);
446 }
447
448 if (pVia->agpSize) {
449 xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Freeing agp memory\n");
450 drmAgpFree(pVia->drmFD, pVia->agpHandle);
451 xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Releasing agp module\n");
452 drmAgpRelease(pVia->drmFD);
453 }
454
455 #if 0
456 if (pVia->DRIIrqEnable)
457 #endif
458 VIADRIIrqExit(ctx);
459 }
460
461 static int
462 VIADRIFinishScreenInit(DRIDriverContext * ctx)
463 {
464 VIAPtr pVia = VIAPTR(ctx);
465 VIADRIPtr pVIADRI;
466 int err;
467
468 err = drmCreateContext(ctx->drmFD, &ctx->serverContext);
469 if (err != 0) {
470 fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err);
471 return GL_FALSE;
472 }
473
474 DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0);
475
476
477 if (!VIADRIKernelInit(ctx, pVia)) {
478 VIADRICloseScreen(ctx);
479 return GL_FALSE;
480 }
481 xf86DrvMsg(pScreen->myNum, X_INFO, "[dri] kernel data initialized.\n");
482
483 /* set SAREA value */
484 {
485 drm_via_sarea_t *saPriv;
486
487 saPriv=(drm_via_sarea_t*)(((char*)ctx->pSAREA) +
488 sizeof(drm_sarea_t));
489 assert(saPriv);
490 memset(saPriv, 0, sizeof(*saPriv));
491 saPriv->ctxOwner = -1;
492 }
493 pVIADRI=(VIADRIPtr)pVia->devPrivate;
494 pVIADRI->deviceID=pVia->Chipset;
495 pVIADRI->width=ctx->shared.virtualWidth;
496 pVIADRI->height=ctx->shared.virtualHeight;
497 pVIADRI->mem=ctx->shared.fbSize;
498 pVIADRI->bytesPerPixel= (ctx->bpp+7) / 8;
499 pVIADRI->sarea_priv_offset = sizeof(drm_sarea_t);
500 /* TODO */
501 pVIADRI->scrnX=pVIADRI->width;
502 pVIADRI->scrnY=pVIADRI->height;
503
504 /* Initialize IRQ */
505 #if 0
506 if (pVia->DRIIrqEnable)
507 #endif
508 VIADRIIrqInit(ctx);
509
510 pVIADRI->ringBufActive = 0;
511 VIADRIRingBufferInit(ctx);
512
513 return GL_TRUE;
514 }
515
516 /* Initialize the kernel data structures. */
517 static int VIADRIKernelInit(DRIDriverContext * ctx, VIAPtr pVia)
518 {
519 drm_via_init_t drmInfo;
520 memset(&drmInfo, 0, sizeof(drm_via_init_t));
521 drmInfo.sarea_priv_offset = sizeof(drm_sarea_t);
522 drmInfo.func = VIA_INIT_MAP;
523 drmInfo.fb_offset = pVia->FrameBufferBase;
524 drmInfo.mmio_offset = pVia->registerHandle;
525 if (pVia->IsPCI)
526 drmInfo.agpAddr = (uint32_t)NULL;
527 else
528 drmInfo.agpAddr = (uint32_t)pVia->agpAddr;
529
530 if ((drmCommandWrite(pVia->drmFD, DRM_VIA_MAP_INIT,&drmInfo,
531 sizeof(drm_via_init_t))) < 0)
532 return GL_FALSE;
533
534 return GL_TRUE;
535 }
536 /* Add a map for the MMIO registers */
537 static int VIADRIMapInit(DRIDriverContext * ctx, VIAPtr pVia)
538 {
539 int flags = 0;
540
541 if (drmAddMap(pVia->drmFD, pVia->MmioBase, VIA_MMIO_REGSIZE,
542 DRM_REGISTERS, flags, &pVia->registerHandle) < 0) {
543 return GL_FALSE;
544 }
545
546 xf86DrvMsg(pScreen->myNum, X_INFO,
547 "[drm] register handle = 0x%08lx\n", pVia->registerHandle);
548
549 return GL_TRUE;
550 }
551
552 static int viaValidateMode(const DRIDriverContext *ctx)
553 {
554 VIAPtr pVia = VIAPTR(ctx);
555
556 return 1;
557 }
558
559 static int viaPostValidateMode(const DRIDriverContext *ctx)
560 {
561 VIAPtr pVia = VIAPTR(ctx);
562
563 return 1;
564 }
565
566 static void VIAEnableMMIO(DRIDriverContext * ctx)
567 {
568 /*vgaHWPtr hwp = VGAHWPTR(ctx);*/
569 VIAPtr pVia = VIAPTR(ctx);
570 unsigned char val;
571
572 #if 0
573 if (xf86IsPrimaryPci(pVia->PciInfo)) {
574 /* If we are primary card, we still use std vga port. If we use
575 * MMIO, system will hang in vgaHWSave when our card used in
576 * PLE and KLE (integrated Trident MVP4)
577 */
578 vgaHWSetStdFuncs(hwp);
579 }
580 else {
581 vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000);
582 }
583 #endif
584
585 val = VGAIN8(0x3c3);
586 VGAOUT8(0x3c3, val | 0x01);
587 val = VGAIN8(0x3cc);
588 VGAOUT8(0x3c2, val | 0x01);
589
590 /* Unlock Extended IO Space */
591 VGAOUT8(0x3c4, 0x10);
592 VGAOUT8(0x3c5, 0x01);
593
594 /* Enable MMIO */
595 if(!pVia->IsSecondary) {
596 VGAOUT8(0x3c4, 0x1a);
597 val = VGAIN8(0x3c5);
598 #ifdef DEBUG
599 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "primary val = %x\n", val);
600 #endif
601 VGAOUT8(0x3c5, val | 0x68);
602 }
603 else {
604 VGAOUT8(0x3c4, 0x1a);
605 val = VGAIN8(0x3c5);
606 #ifdef DEBUG
607 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "secondary val = %x\n", val);
608 #endif
609 VGAOUT8(0x3c5, val | 0x38);
610 }
611
612 /* Unlock CRTC registers */
613 VGAOUT8(0x3d4, 0x47);
614 VGAOUT8(0x3d5, 0x00);
615
616 return;
617 }
618
619 static void VIADisableMMIO(DRIDriverContext * ctx)
620 {
621 VIAPtr pVia = VIAPTR(ctx);
622 unsigned char val;
623
624 VGAOUT8(0x3c4, 0x1a);
625 val = VGAIN8(0x3c5);
626 VGAOUT8(0x3c5, val & 0x97);
627
628 return;
629 }
630
631 static void VIADisableExtendedFIFO(DRIDriverContext *ctx)
632 {
633 VIAPtr pVia = VIAPTR(ctx);
634 uint32_t dwGE230, dwGE298;
635
636 /* Cause of exit XWindow will dump back register value, others chipset no
637 * need to set extended fifo value */
638 if (pVia->Chipset == VIA_CLE266 && pVia->ChipRev < 15 &&
639 (ctx->shared.virtualWidth > 1024 || pVia->HasSecondary)) {
640 /* Turn off Extend FIFO */
641 /* 0x298[29] */
642 dwGE298 = VIAGETREG(0x298);
643 VIASETREG(0x298, dwGE298 | 0x20000000);
644 /* 0x230[21] */
645 dwGE230 = VIAGETREG(0x230);
646 VIASETREG(0x230, dwGE230 & ~0x00200000);
647 /* 0x298[29] */
648 dwGE298 = VIAGETREG(0x298);
649 VIASETREG(0x298, dwGE298 & ~0x20000000);
650 }
651 }
652
653 static void VIAEnableExtendedFIFO(DRIDriverContext *ctx)
654 {
655 VIAPtr pVia = VIAPTR(ctx);
656 uint8_t bRegTemp;
657 uint32_t dwGE230, dwGE298;
658
659 switch (pVia->Chipset) {
660 case VIA_CLE266:
661 if (pVia->ChipRev > 14) { /* For 3123Cx */
662 if (pVia->HasSecondary) { /* SAMM or DuoView case */
663 if (ctx->shared.virtualWidth >= 1024)
664 {
665 /* 3c5.16[0:5] */
666 VGAOUT8(0x3C4, 0x16);
667 bRegTemp = VGAIN8(0x3C5);
668 bRegTemp &= ~0x3F;
669 bRegTemp |= 0x1C;
670 VGAOUT8(0x3C5, bRegTemp);
671 /* 3c5.17[0:6] */
672 VGAOUT8(0x3C4, 0x17);
673 bRegTemp = VGAIN8(0x3C5);
674 bRegTemp &= ~0x7F;
675 bRegTemp |= 0x3F;
676 VGAOUT8(0x3C5, bRegTemp);
677 pVia->EnableExtendedFIFO = GL_TRUE;
678 }
679 }
680 else /* Single view or Simultaneoue case */
681 {
682 if (ctx->shared.virtualWidth > 1024)
683 {
684 /* 3c5.16[0:5] */
685 VGAOUT8(0x3C4, 0x16);
686 bRegTemp = VGAIN8(0x3C5);
687 bRegTemp &= ~0x3F;
688 bRegTemp |= 0x17;
689 VGAOUT8(0x3C5, bRegTemp);
690 /* 3c5.17[0:6] */
691 VGAOUT8(0x3C4, 0x17);
692 bRegTemp = VGAIN8(0x3C5);
693 bRegTemp &= ~0x7F;
694 bRegTemp |= 0x2F;
695 VGAOUT8(0x3C5, bRegTemp);
696 pVia->EnableExtendedFIFO = GL_TRUE;
697 }
698 }
699 /* 3c5.18[0:5] */
700 VGAOUT8(0x3C4, 0x18);
701 bRegTemp = VGAIN8(0x3C5);
702 bRegTemp &= ~0x3F;
703 bRegTemp |= 0x17;
704 bRegTemp |= 0x40; /* force the preq always higher than treq */
705 VGAOUT8(0x3C5, bRegTemp);
706 }
707 else { /* for 3123Ax */
708 if (ctx->shared.virtualWidth > 1024 || pVia->HasSecondary) {
709 /* Turn on Extend FIFO */
710 /* 0x298[29] */
711 dwGE298 = VIAGETREG(0x298);
712 VIASETREG(0x298, dwGE298 | 0x20000000);
713 /* 0x230[21] */
714 dwGE230 = VIAGETREG(0x230);
715 VIASETREG(0x230, dwGE230 | 0x00200000);
716 /* 0x298[29] */
717 dwGE298 = VIAGETREG(0x298);
718 VIASETREG(0x298, dwGE298 & ~0x20000000);
719
720 /* 3c5.16[0:5] */
721 VGAOUT8(0x3C4, 0x16);
722 bRegTemp = VGAIN8(0x3C5);
723 bRegTemp &= ~0x3F;
724 bRegTemp |= 0x17;
725 /* bRegTemp |= 0x10; */
726 VGAOUT8(0x3C5, bRegTemp);
727 /* 3c5.17[0:6] */
728 VGAOUT8(0x3C4, 0x17);
729 bRegTemp = VGAIN8(0x3C5);
730 bRegTemp &= ~0x7F;
731 bRegTemp |= 0x2F;
732 /*bRegTemp |= 0x1F;*/
733 VGAOUT8(0x3C5, bRegTemp);
734 /* 3c5.18[0:5] */
735 VGAOUT8(0x3C4, 0x18);
736 bRegTemp = VGAIN8(0x3C5);
737 bRegTemp &= ~0x3F;
738 bRegTemp |= 0x17;
739 bRegTemp |= 0x40; /* force the preq always higher than treq */
740 VGAOUT8(0x3C5, bRegTemp);
741 pVia->EnableExtendedFIFO = GL_TRUE;
742 }
743 }
744 break;
745 case VIA_KM400:
746 if (pVia->HasSecondary) { /* SAMM or DuoView case */
747 if ((ctx->shared.virtualWidth >= 1600) &&
748 (pVia->MemClk <= VIA_MEM_DDR200)) {
749 /* enable CRT extendded FIFO */
750 VGAOUT8(0x3C4, 0x17);
751 VGAOUT8(0x3C5, 0x1C);
752 /* revise second display queue depth and read threshold */
753 VGAOUT8(0x3C4, 0x16);
754 bRegTemp = VGAIN8(0x3C5);
755 bRegTemp &= ~0x3F;
756 bRegTemp = (bRegTemp) | (0x09);
757 VGAOUT8(0x3C5, bRegTemp);
758 }
759 else {
760 /* enable CRT extendded FIFO */
761 VGAOUT8(0x3C4, 0x17);
762 VGAOUT8(0x3C5,0x3F);
763 /* revise second display queue depth and read threshold */
764 VGAOUT8(0x3C4, 0x16);
765 bRegTemp = VGAIN8(0x3C5);
766 bRegTemp &= ~0x3F;
767 bRegTemp = (bRegTemp) | (0x1C);
768 VGAOUT8(0x3C5, bRegTemp);
769 }
770 /* 3c5.18[0:5] */
771 VGAOUT8(0x3C4, 0x18);
772 bRegTemp = VGAIN8(0x3C5);
773 bRegTemp &= ~0x3F;
774 bRegTemp |= 0x17;
775 bRegTemp |= 0x40; /* force the preq always higher than treq */
776 VGAOUT8(0x3C5, bRegTemp);
777 pVia->EnableExtendedFIFO = GL_TRUE;
778 }
779 else {
780 if ( (ctx->shared.virtualWidth > 1024) && (ctx->shared.virtualWidth <= 1280) )
781 {
782 /* enable CRT extendded FIFO */
783 VGAOUT8(0x3C4, 0x17);
784 VGAOUT8(0x3C5, 0x3F);
785 /* revise second display queue depth and read threshold */
786 VGAOUT8(0x3C4, 0x16);
787 bRegTemp = VGAIN8(0x3C5);
788 bRegTemp &= ~0x3F;
789 bRegTemp = (bRegTemp) | (0x17);
790 VGAOUT8(0x3C5, bRegTemp);
791 pVia->EnableExtendedFIFO = GL_TRUE;
792 }
793 else if ((ctx->shared.virtualWidth > 1280))
794 {
795 /* enable CRT extendded FIFO */
796 VGAOUT8(0x3C4, 0x17);
797 VGAOUT8(0x3C5, 0x3F);
798 /* revise second display queue depth and read threshold */
799 VGAOUT8(0x3C4, 0x16);
800 bRegTemp = VGAIN8(0x3C5);
801 bRegTemp &= ~0x3F;
802 bRegTemp = (bRegTemp) | (0x1C);
803 VGAOUT8(0x3C5, bRegTemp);
804 pVia->EnableExtendedFIFO = GL_TRUE;
805 }
806 else
807 {
808 /* enable CRT extendded FIFO */
809 VGAOUT8(0x3C4, 0x17);
810 VGAOUT8(0x3C5, 0x3F);
811 /* revise second display queue depth and read threshold */
812 VGAOUT8(0x3C4, 0x16);
813 bRegTemp = VGAIN8(0x3C5);
814 bRegTemp &= ~0x3F;
815 bRegTemp = (bRegTemp) | (0x10);
816 VGAOUT8(0x3C5, bRegTemp);
817 }
818 /* 3c5.18[0:5] */
819 VGAOUT8(0x3C4, 0x18);
820 bRegTemp = VGAIN8(0x3C5);
821 bRegTemp &= ~0x3F;
822 bRegTemp |= 0x17;
823 bRegTemp |= 0x40; /* force the preq always higher than treq */
824 VGAOUT8(0x3C5, bRegTemp);
825 }
826 break;
827 case VIA_K8M800:
828 /*=* R1 Display FIFO depth (384 /8 -1 -> 0xbf) SR17[7:0] (8bits) *=*/
829 VGAOUT8(0x3c4, 0x17);
830 VGAOUT8(0x3c5, 0xbf);
831
832 /*=* R2 Display fetch datum threshold value (328/4 -> 0x52)
833 SR16[5:0], SR16[7] (7bits) *=*/
834 VGAOUT8(0x3c4, 0x16);
835 bRegTemp = VGAIN8(0x3c5) & ~0xBF;
836 bRegTemp |= (0x52 & 0x3F);
837 bRegTemp |= ((0x52 & 0x40) << 1);
838 VGAOUT8(0x3c5, bRegTemp);
839
840 /*=* R3 Switch to the highest agent threshold value (74 -> 0x4a)
841 SR18[5:0], SR18[7] (7bits) *=*/
842 VGAOUT8(0x3c4, 0x18);
843 bRegTemp = VGAIN8(0x3c5) & ~0xBF;
844 bRegTemp |= (0x4a & 0x3F);
845 bRegTemp |= ((0x4a & 0x40) << 1);
846 VGAOUT8(0x3c5, bRegTemp);
847 #if 0
848 /*=* R4 Fetch Number for a scan line (unit: 8 bytes)
849 SR1C[7:0], SR1D[1:0] (10bits) *=*/
850 wRegTemp = (pBIOSInfo->offsetWidthByQWord >> 1) + 4;
851 VGAOUT8(0x3c4, 0x1c);
852 VGAOUT8(0x3c5, (uint8_t)(wRegTemp & 0xFF));
853 VGAOUT8(0x3c4, 0x1d);
854 bRegTemp = VGAIN8(0x3c5) & ~0x03;
855 VGAOUT8(0x3c5, bRegTemp | ((wRegTemp & 0x300) >> 8));
856 #endif
857 if (ctx->shared.virtualWidth >= 1400 && ctx->bpp == 32)
858 {
859 /*=* Max. length for a request SR22[4:0] (64/4 -> 0x10) *=*/
860 VGAOUT8(0x3c4, 0x22);
861 bRegTemp = VGAIN8(0x3c5) & ~0x1F;
862 VGAOUT8(0x3c5, bRegTemp | 0x10);
863 }
864 else
865 {
866 /*=* Max. length for a request SR22[4:0]
867 (128/4 -> over flow 0x0) *=*/
868 VGAOUT8(0x3c4, 0x22);
869 bRegTemp = VGAIN8(0x3c5) & ~0x1F;
870 VGAOUT8(0x3c5, bRegTemp);
871 }
872 break;
873 case VIA_PM800:
874 /*=* R1 Display FIFO depth (96-1 -> 0x5f) SR17[7:0] (8bits) *=*/
875 VGAOUT8(0x3c4, 0x17);
876 VGAOUT8(0x3c5, 0x5f);
877
878 /*=* R2 Display fetch datum threshold value (32 -> 0x20)
879 SR16[5:0], SR16[7] (7bits) *=*/
880 VGAOUT8(0x3c4, 0x16);
881 bRegTemp = VGAIN8(0x3c5) & ~0xBF;
882 bRegTemp |= (0x20 & 0x3F);
883 bRegTemp |= ((0x20 & 0x40) << 1);
884 VGAOUT8(0x3c5, bRegTemp);
885
886 /*=* R3 Switch to the highest agent threshold value (16 -> 0x10)
887 SR18[5:0], SR18[7] (7bits) *=*/
888 VGAOUT8(0x3c4, 0x18);
889 bRegTemp = VGAIN8(0x3c5) & ~0xBF;
890 bRegTemp |= (0x10 & 0x3F);
891 bRegTemp |= ((0x10 & 0x40) << 1);
892 VGAOUT8(0x3c5, bRegTemp);
893 #if 0
894 /*=* R4 Fetch Number for a scan line (unit: 8 bytes)
895 SR1C[7:0], SR1D[1:0] (10bits) *=*/
896 wRegTemp = (pBIOSInfo->offsetWidthByQWord >> 1) + 4;
897 VGAOUT8(0x3c4, 0x1c);
898 VGAOUT8(0x3c5, (uint8_t)(wRegTemp & 0xFF));
899 VGAOUT8(0x3c4, 0x1d);
900 bRegTemp = VGAIN8(0x3c5) & ~0x03;
901 VGAOUT8(0x3c5, bRegTemp | ((wRegTemp & 0x300) >> 8));
902 #endif
903 if (ctx->shared.virtualWidth >= 1400 && ctx->bpp == 32)
904 {
905 /*=* Max. length for a request SR22[4:0] (64/4 -> 0x10) *=*/
906 VGAOUT8(0x3c4, 0x22);
907 bRegTemp = VGAIN8(0x3c5) & ~0x1F;
908 VGAOUT8(0x3c5, bRegTemp | 0x10);
909 }
910 else
911 {
912 /*=* Max. length for a request SR22[4:0] (0x1F) *=*/
913 VGAOUT8(0x3c4, 0x22);
914 bRegTemp = VGAIN8(0x3c5) & ~0x1F;
915 VGAOUT8(0x3c5, bRegTemp | 0x1F);
916 }
917 break;
918 default:
919 break;
920 }
921 }
922
923 static void VIAInitialize2DEngine(DRIDriverContext *ctx)
924 {
925 VIAPtr pVia = VIAPTR(ctx);
926 uint32_t dwVQStartAddr, dwVQEndAddr;
927 uint32_t dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH;
928 uint32_t dwGEMode;
929
930 /* init 2D engine regs to reset 2D engine */
931 VIASETREG(0x04, 0x0);
932 VIASETREG(0x08, 0x0);
933 VIASETREG(0x0c, 0x0);
934 VIASETREG(0x10, 0x0);
935 VIASETREG(0x14, 0x0);
936 VIASETREG(0x18, 0x0);
937 VIASETREG(0x1c, 0x0);
938 VIASETREG(0x20, 0x0);
939 VIASETREG(0x24, 0x0);
940 VIASETREG(0x28, 0x0);
941 VIASETREG(0x2c, 0x0);
942 VIASETREG(0x30, 0x0);
943 VIASETREG(0x34, 0x0);
944 VIASETREG(0x38, 0x0);
945 VIASETREG(0x3c, 0x0);
946 VIASETREG(0x40, 0x0);
947
948 VIADisableMMIO(ctx);
949
950 /* Init AGP and VQ regs */
951 VIASETREG(0x43c, 0x00100000);
952 VIASETREG(0x440, 0x00000000);
953 VIASETREG(0x440, 0x00333004);
954 VIASETREG(0x440, 0x60000000);
955 VIASETREG(0x440, 0x61000000);
956 VIASETREG(0x440, 0x62000000);
957 VIASETREG(0x440, 0x63000000);
958 VIASETREG(0x440, 0x64000000);
959 VIASETREG(0x440, 0x7D000000);
960
961 VIASETREG(0x43c, 0xfe020000);
962 VIASETREG(0x440, 0x00000000);
963
964 if (pVia->VQStart != 0) {
965 /* Enable VQ */
966 dwVQStartAddr = pVia->VQStart;
967 dwVQEndAddr = pVia->VQEnd;
968 dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF);
969 dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF);
970 dwVQStartEndH = 0x52000000 | ((dwVQStartAddr & 0xFF000000) >> 24) |
971 ((dwVQEndAddr & 0xFF000000) >> 16);
972 dwVQLen = 0x53000000 | (VIA_VQ_SIZE >> 3);
973
974 VIASETREG(0x43c, 0x00fe0000);
975 VIASETREG(0x440, 0x080003fe);
976 VIASETREG(0x440, 0x0a00027c);
977 VIASETREG(0x440, 0x0b000260);
978 VIASETREG(0x440, 0x0c000274);
979 VIASETREG(0x440, 0x0d000264);
980 VIASETREG(0x440, 0x0e000000);
981 VIASETREG(0x440, 0x0f000020);
982 VIASETREG(0x440, 0x1000027e);
983 VIASETREG(0x440, 0x110002fe);
984 VIASETREG(0x440, 0x200f0060);
985
986 VIASETREG(0x440, 0x00000006);
987 VIASETREG(0x440, 0x40008c0f);
988 VIASETREG(0x440, 0x44000000);
989 VIASETREG(0x440, 0x45080c04);
990 VIASETREG(0x440, 0x46800408);
991
992 VIASETREG(0x440, dwVQStartEndH);
993 VIASETREG(0x440, dwVQStartL);
994 VIASETREG(0x440, dwVQEndL);
995 VIASETREG(0x440, dwVQLen);
996 }
997 else {
998 /* Diable VQ */
999 VIASETREG(0x43c, 0x00fe0000);
1000 VIASETREG(0x440, 0x00000004);
1001 VIASETREG(0x440, 0x40008c0f);
1002 VIASETREG(0x440, 0x44000000);
1003 VIASETREG(0x440, 0x45080c04);
1004 VIASETREG(0x440, 0x46800408);
1005 }
1006
1007 dwGEMode = 0;
1008
1009 switch (ctx->bpp) {
1010 case 16:
1011 dwGEMode |= VIA_GEM_16bpp;
1012 break;
1013 case 32:
1014 dwGEMode |= VIA_GEM_32bpp;
1015 break;
1016 default:
1017 dwGEMode |= VIA_GEM_8bpp;
1018 break;
1019 }
1020
1021 #if 0
1022 switch (ctx->shared.virtualWidth) {
1023 case 800:
1024 dwGEMode |= VIA_GEM_800;
1025 break;
1026 case 1024:
1027 dwGEMode |= VIA_GEM_1024;
1028 break;
1029 case 1280:
1030 dwGEMode |= VIA_GEM_1280;
1031 break;
1032 case 1600:
1033 dwGEMode |= VIA_GEM_1600;
1034 break;
1035 case 2048:
1036 dwGEMode |= VIA_GEM_2048;
1037 break;
1038 default:
1039 dwGEMode |= VIA_GEM_640;
1040 break;
1041 }
1042 #endif
1043
1044 VIAEnableMMIO(ctx);
1045
1046 /* Set BPP and Pitch */
1047 VIASETREG(VIA_REG_GEMODE, dwGEMode);
1048
1049 /* Set Src and Dst base address and pitch, pitch is qword */
1050 VIASETREG(VIA_REG_SRCBASE, 0x0);
1051 VIASETREG(VIA_REG_DSTBASE, 0x0);
1052 VIASETREG(VIA_REG_PITCH, VIA_PITCH_ENABLE |
1053 ((ctx->shared.virtualWidth * ctx->bpp >> 3) >> 3) |
1054 (((ctx->shared.virtualWidth * ctx->bpp >> 3) >> 3) << 16));
1055 }
1056
1057 static int b3DRegsInitialized = 0;
1058
1059 static void VIAInitialize3DEngine(DRIDriverContext *ctx)
1060 {
1061 VIAPtr pVia = VIAPTR(ctx);
1062 int i;
1063
1064 if (!b3DRegsInitialized)
1065 {
1066
1067 VIASETREG(0x43C, 0x00010000);
1068
1069 for (i = 0; i <= 0x7D; i++)
1070 {
1071 VIASETREG(0x440, (uint32_t) i << 24);
1072 }
1073
1074 VIASETREG(0x43C, 0x00020000);
1075
1076 for (i = 0; i <= 0x94; i++)
1077 {
1078 VIASETREG(0x440, (uint32_t) i << 24);
1079 }
1080
1081 VIASETREG(0x440, 0x82400000);
1082
1083 VIASETREG(0x43C, 0x01020000);
1084
1085
1086 for (i = 0; i <= 0x94; i++)
1087 {
1088 VIASETREG(0x440, (uint32_t) i << 24);
1089 }
1090
1091 VIASETREG(0x440, 0x82400000);
1092 VIASETREG(0x43C, 0xfe020000);
1093
1094 for (i = 0; i <= 0x03; i++)
1095 {
1096 VIASETREG(0x440, (uint32_t) i << 24);
1097 }
1098
1099 VIASETREG(0x43C, 0x00030000);
1100
1101 for (i = 0; i <= 0xff; i++)
1102 {
1103 VIASETREG(0x440, 0);
1104 }
1105 VIASETREG(0x43C, 0x00100000);
1106 VIASETREG(0x440, 0x00333004);
1107 VIASETREG(0x440, 0x10000002);
1108 VIASETREG(0x440, 0x60000000);
1109 VIASETREG(0x440, 0x61000000);
1110 VIASETREG(0x440, 0x62000000);
1111 VIASETREG(0x440, 0x63000000);
1112 VIASETREG(0x440, 0x64000000);
1113
1114 VIASETREG(0x43C, 0x00fe0000);
1115
1116 if (pVia->ChipRev >= 3 )
1117 VIASETREG(0x440,0x40008c0f);
1118 else
1119 VIASETREG(0x440,0x4000800f);
1120
1121 VIASETREG(0x440,0x44000000);
1122 VIASETREG(0x440,0x45080C04);
1123 VIASETREG(0x440,0x46800408);
1124 VIASETREG(0x440,0x50000000);
1125 VIASETREG(0x440,0x51000000);
1126 VIASETREG(0x440,0x52000000);
1127 VIASETREG(0x440,0x53000000);
1128
1129 b3DRegsInitialized = 1;
1130 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1131 "3D Engine has been initialized.\n");
1132 }
1133
1134 VIASETREG(0x43C,0x00fe0000);
1135 VIASETREG(0x440,0x08000001);
1136 VIASETREG(0x440,0x0A000183);
1137 VIASETREG(0x440,0x0B00019F);
1138 VIASETREG(0x440,0x0C00018B);
1139 VIASETREG(0x440,0x0D00019B);
1140 VIASETREG(0x440,0x0E000000);
1141 VIASETREG(0x440,0x0F000000);
1142 VIASETREG(0x440,0x10000000);
1143 VIASETREG(0x440,0x11000000);
1144 VIASETREG(0x440,0x20000000);
1145 }
1146
1147 static int
1148 WaitIdleCLE266(VIAPtr pVia)
1149 {
1150 int loop = 0;
1151
1152 /*mem_barrier();*/
1153
1154 while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP))
1155 ;
1156
1157 while ((VIAGETREG(VIA_REG_STATUS) &
1158 (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
1159 (loop++ < MAXLOOP))
1160 ;
1161
1162 return loop >= MAXLOOP;
1163 }
1164
1165 static int viaInitFBDev(DRIDriverContext *ctx)
1166 {
1167 VIAPtr pVia = CALLOC(sizeof(*pVia));
1168
1169 ctx->driverPrivate = (void *)pVia;
1170
1171 switch (ctx->chipset) {
1172 case PCI_CHIP_CLE3122:
1173 case PCI_CHIP_CLE3022:
1174 pVia->Chipset = VIA_CLE266;
1175 break;
1176 case PCI_CHIP_VT7205:
1177 case PCI_CHIP_VT3205:
1178 pVia->Chipset = VIA_KM400;
1179 break;
1180 case PCI_CHIP_VT3204:
1181 case PCI_CHIP_VT3344:
1182 pVia->Chipset = VIA_K8M800;
1183 break;
1184 case PCI_CHIP_VT3259:
1185 pVia->Chipset = VIA_PM800;
1186 break;
1187 default:
1188 xf86DrvMsg(0, X_ERROR, "VIA: Unknown device ID (0x%x)\n", ctx->chipset);
1189 }
1190
1191 /* _SOLO TODO XXX need to read ChipRev too */
1192 pVia->ChipRev = 0;
1193
1194 pVia->videoRambytes = ctx->shared.fbSize;
1195 pVia->MmioBase = ctx->MMIOStart;
1196 pVia->FrameBufferBase = ctx->FBStart & 0xfc000000;
1197
1198 pVia->FBFreeStart = ctx->shared.virtualWidth * ctx->cpp *
1199 ctx->shared.virtualHeight;
1200
1201 #if 1
1202 /* Alloc a second framebuffer for the second head */
1203 pVia->FBFreeStart += ctx->shared.virtualWidth * ctx->cpp *
1204 ctx->shared.virtualHeight;
1205 #endif
1206
1207 pVia->VQStart = pVia->FBFreeStart;
1208 pVia->VQEnd = pVia->FBFreeStart + VIA_VQ_SIZE - 1;
1209
1210 pVia->FBFreeStart += VIA_VQ_SIZE;
1211
1212 pVia->FBFreeEnd = pVia->videoRambytes;
1213
1214 if (!VIADRIScreenInit(ctx))
1215 return 0;
1216
1217 return 1;
1218 }
1219
1220 static void viaHaltFBDev(DRIDriverContext *ctx)
1221 {
1222 drmUnmap( ctx->pSAREA, ctx->shared.SAREASize );
1223 drmClose(ctx->drmFD);
1224
1225 if (ctx->driverPrivate) {
1226 free(ctx->driverPrivate);
1227 ctx->driverPrivate = 0;
1228 }
1229 }
1230
1231 static int viaEngineShutdown(const DRIDriverContext *ctx)
1232 {
1233 return 1;
1234 }
1235
1236 static int viaEngineRestore(const DRIDriverContext *ctx)
1237 {
1238 return 1;
1239 }
1240
1241 const struct DRIDriverRec __driDriver =
1242 {
1243 viaValidateMode,
1244 viaPostValidateMode,
1245 viaInitFBDev,
1246 viaHaltFBDev,
1247 viaEngineShutdown,
1248 viaEngineRestore,
1249 0,
1250 };
1251