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