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