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