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