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