1 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/via/via_dri.c,v 1.4 2003/09/24 02:43:30 dawes Exp $ */
3 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
4 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
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:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
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.
27 #include "xf86_OSproc.h"
28 #include "xf86_ansic.h"
31 #include "xf86PciInfo.h"
34 #define _XF86DRI_SERVER_
35 #include "GL/glxtokens.h"
53 #include "via_context.h"
55 #include "via_driver.h"
56 #include "via_common.h"
59 static void VIAEnableMMIO(DRIDriverContext
* ctx
);
60 static void VIADisableMMIO(DRIDriverContext
* ctx
);
61 static void VIADisableExtendedFIFO(DRIDriverContext
*ctx
);
62 static void VIAEnableExtendedFIFO(DRIDriverContext
*ctx
);
63 static void VIAInitialize2DEngine(DRIDriverContext
*ctx
);
64 static void VIAInitialize3DEngine(DRIDriverContext
*ctx
);
66 static int VIADRIScreenInit(DRIDriverContext
* ctx
);
67 static void VIADRICloseScreen(DRIDriverContext
* ctx
);
68 static int VIADRIFinishScreenInit(DRIDriverContext
* ctx
);
70 /* _SOLO : missing macros normally defined by X code */
71 #define xf86DrvMsg(a, b, ...) fprintf(stderr, __VA_ARGS__)
72 #define MMIO_IN8(base, addr) ((*(((volatile CARD8*)base)+(addr)))+0)
73 #define MMIO_OUT8(base, addr, val) ((*(((volatile CARD8*)base)+(addr)))=((CARD8)val))
74 #define MMIO_OUT16(base, addr, val) ((*(volatile CARD16*)(((CARD8*)base)+(addr)))=((CARD16)val))
78 #define AGP_PAGE_SIZE 4096
79 #define AGP_PAGES 8192
80 #define AGP_SIZE (AGP_PAGE_SIZE * AGP_PAGES)
81 #define AGP_CMDBUF_PAGES 256
82 #define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES)
84 static char VIAKernelDriverName
[] = "via";
85 static char VIAClientDriverName
[] = "via";
87 static int VIADRIAgpInit(const DRIDriverContext
*ctx
, VIAPtr pVia
);
88 static int VIADRIPciInit(DRIDriverContext
* ctx
, VIAPtr pVia
);
89 static int VIADRIFBInit(DRIDriverContext
* ctx
, VIAPtr pVia
);
90 static int VIADRIKernelInit(DRIDriverContext
* ctx
, VIAPtr pVia
);
91 static int VIADRIMapInit(DRIDriverContext
* ctx
, VIAPtr pVia
);
93 static int VIADRIAgpInit(const DRIDriverContext
*ctx
, VIAPtr pVia
)
95 unsigned long agp_phys
;
98 pVIADRI
= pVia
->devPrivate
;
101 if (drmAgpAcquire(pVia
->drmFD
) < 0) {
102 xf86DrvMsg(pScreen
->myNum
, X_ERROR
, "[drm] drmAgpAcquire failed %d\n", errno
);
106 if (drmAgpEnable(pVia
->drmFD
, drmAgpGetMode(pVia
->drmFD
)&~0x0) < 0) {
107 xf86DrvMsg(pScreen
->myNum
, X_ERROR
, "[drm] drmAgpEnable failed\n");
111 xf86DrvMsg(pScreen
->myNum
, X_INFO
, "[drm] drmAgpEnabled succeeded\n");
113 if (drmAgpAlloc(pVia
->drmFD
, AGP_SIZE
, 0, &agp_phys
, &pVia
->agpHandle
) < 0) {
114 xf86DrvMsg(pScreen
->myNum
, X_ERROR
,
115 "[drm] drmAgpAlloc failed\n");
116 drmAgpRelease(pVia
->drmFD
);
120 if (drmAgpBind(pVia
->drmFD
, pVia
->agpHandle
, 0) < 0) {
121 xf86DrvMsg(pScreen
->myNum
, X_ERROR
,
122 "[drm] drmAgpBind failed\n");
123 drmAgpFree(pVia
->drmFD
, pVia
->agpHandle
);
124 drmAgpRelease(pVia
->drmFD
);
129 pVia
->agpSize
= AGP_SIZE
;
130 pVia
->agpAddr
= drmAgpBase(pVia
->drmFD
);
131 xf86DrvMsg(pScreen
->myNum
, X_INFO
,
132 "[drm] agpAddr = 0x%08lx\n",pVia
->agpAddr
);
134 pVIADRI
->agp
.size
= pVia
->agpSize
;
135 if (drmAddMap(pVia
->drmFD
, (drmHandle
)0,
136 pVIADRI
->agp
.size
, DRM_AGP
, 0,
137 &pVIADRI
->agp
.handle
) < 0) {
138 xf86DrvMsg(pScreen
->myNum
, X_ERROR
,
139 "[drm] Failed to map public agp area\n");
140 pVIADRI
->agp
.size
= 0;
143 /* Map AGP from kernel to Xserver - Not really needed */
144 drmMap(pVia
->drmFD
, pVIADRI
->agp
.handle
,pVIADRI
->agp
.size
,
145 (drmAddressPtr
)&agpaddr
);
148 xf86DrvMsg(pScreen
->myNum
, X_INFO
,
149 "[drm] agpBase = 0x%08lx\n", pVia
->agpBase
);
150 xf86DrvMsg(pScreen
->myNum
, X_INFO
,
151 "[drm] agpAddr = 0x%08lx\n", pVia
->agpAddr
);
153 xf86DrvMsg(pScreen
->myNum
, X_INFO
,
154 "[drm] agpSize = 0x%08lx\n", pVia
->agpSize
);
155 xf86DrvMsg(pScreen
->myNum
, X_INFO
,
156 "[drm] agp physical addr = 0x%08lx\n", agp_phys
);
158 drmVIAAgpInit(pVia
->drmFD
, 0, AGP_SIZE
);
163 static int VIADRIFBInit(DRIDriverContext
* ctx
, VIAPtr pVia
)
165 int FBSize
= pVia
->FBFreeEnd
-pVia
->FBFreeStart
;
166 int FBOffset
= pVia
->FBFreeStart
;
167 VIADRIPtr pVIADRI
= pVia
->devPrivate
;
168 pVIADRI
->fbOffset
= FBOffset
;
169 pVIADRI
->fbSize
= pVia
->videoRambytes
;
171 if (drmVIAFBInit(pVia
->drmFD
, FBOffset
, FBSize
) < 0) {
172 xf86DrvMsg(pScreen
->myNum
, X_ERROR
,"[drm] failed to init frame buffer area\n");
176 xf86DrvMsg(pScreen
->myNum
, X_INFO
,"[drm] FBFreeStart= 0x%08lx FBFreeEnd= 0x%08lx FBSize= 0x%08lx\n", pVia
->FBFreeStart
, pVia
->FBFreeEnd
, FBSize
);
181 static int VIADRIPciInit(DRIDriverContext
* ctx
, VIAPtr pVia
)
186 static int VIADRIScreenInit(DRIDriverContext
* ctx
)
188 VIAPtr pVia
= VIAPTR(ctx
);
193 ctx
->shared
.SAREASize
= ((sizeof(XF86DRISAREARec
) + 0xfff) & 0x1000);
195 if (sizeof(XF86DRISAREARec
)+sizeof(VIASAREAPriv
) > SAREA_MAX
) {
196 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
197 "Data does not fit in SAREA\n");
200 ctx
->shared
.SAREASize
= SAREA_MAX
;
203 ctx
->drmFD
= drmOpen(VIAKernelDriverName
, NULL
);
204 if (ctx
->drmFD
< 0) {
205 fprintf(stderr
, "[drm] drmOpen failed\n");
208 pVia
->drmFD
= ctx
->drmFD
;
210 err
= drmSetBusid(ctx
->drmFD
, ctx
->pciBusID
);
212 fprintf(stderr
, "[drm] drmSetBusid failed (%d, %s), %s\n",
213 ctx
->drmFD
, ctx
->pciBusID
, strerror(-err
));
217 err
= drmAddMap(ctx
->drmFD
, 0, ctx
->shared
.SAREASize
, DRM_SHM
,
218 DRM_CONTAINS_LOCK
, &ctx
->shared
.hSAREA
);
220 fprintf(stderr
, "[drm] drmAddMap failed\n");
223 fprintf(stderr
, "[drm] added %d byte SAREA at 0x%08lx\n",
224 ctx
->shared
.SAREASize
, ctx
->shared
.hSAREA
);
226 if (drmMap(ctx
->drmFD
,
228 ctx
->shared
.SAREASize
,
229 (drmAddressPtr
)(&ctx
->pSAREA
)) < 0)
231 fprintf(stderr
, "[drm] drmMap failed\n");
234 memset(ctx
->pSAREA
, 0, ctx
->shared
.SAREASize
);
235 fprintf(stderr
, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",
236 ctx
->shared
.hSAREA
, ctx
->pSAREA
, ctx
->shared
.SAREASize
);
238 /* Need to AddMap the framebuffer and mmio regions here:
240 if (drmAddMap(ctx
->drmFD
,
241 (drmHandle
)ctx
->FBStart
,
249 &ctx
->shared
.hFrameBuffer
) < 0)
251 fprintf(stderr
, "[drm] drmAddMap framebuffer failed\n");
255 fprintf(stderr
, "[drm] framebuffer handle = 0x%08lx\n",
256 ctx
->shared
.hFrameBuffer
);
258 pVIADRI
= (VIADRIPtr
) CALLOC(sizeof(VIADRIRec
));
260 drmClose(ctx
->drmFD
);
263 pVia
->devPrivate
= pVIADRI
;
264 ctx
->driverClientMsg
= pVIADRI
;
265 ctx
->driverClientMsgSize
= sizeof(*pVIADRI
);
267 pVia
->IsPCI
= !VIADRIAgpInit(ctx
, pVia
);
270 VIADRIPciInit(ctx
, pVia
);
271 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
, "[dri] use pci.\n" );
274 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
, "[dri] use agp.\n" );
276 if (!(VIADRIFBInit(ctx
, pVia
))) {
277 VIADRICloseScreen(ctx
);
278 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
, "[dri] frame buffer initialize fial .\n" );
282 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
, "[dri] frame buffer initialized.\n" );
284 /* DRIScreenInit doesn't add all the common mappings. Add additional mappings here. */
285 if (!VIADRIMapInit(ctx
, pVia
)) {
286 VIADRICloseScreen(ctx
);
289 pVIADRI
->regs
.size
= VIA_MMIO_REGSIZE
;
290 pVIADRI
->regs
.map
= 0;
291 pVIADRI
->regs
.handle
= pVia
->registerHandle
;
292 xf86DrvMsg(pScreen
->myNum
, X_INFO
, "[drm] mmio Registers = 0x%08lx\n",
293 pVIADRI
->regs
.handle
);
295 /*pVIADRI->drixinerama = pVia->drixinerama;*/
296 /*=* John Sheng [2003.12.9] Tuxracer & VQ *=*/
297 pVIADRI
->VQEnable
= pVia
->VQEnable
;
299 if (drmMap(pVia
->drmFD
,
300 pVIADRI
->regs
.handle
,
302 (drmAddress
*)&pVia
->MapBase
) != 0)
304 VIADRICloseScreen(ctx
);
308 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
, "[dri] mmio mapped.\n" );
310 return VIADRIFinishScreenInit(ctx
);
314 VIADRICloseScreen(DRIDriverContext
* ctx
)
316 VIAPtr pVia
= VIAPTR(ctx
);
317 VIADRIPtr pVIADRI
=(VIADRIPtr
)pVia
->devPrivate
;
320 xf86DrvMsg(pScreen
->myNum
, X_INFO
, "[drm] Unmapping MMIO registers\n");
321 drmUnmap(pVia
->MapBase
, pVIADRI
->regs
.size
);
325 xf86DrvMsg(pScreen
->myNum
, X_INFO
, "[drm] Freeing agp memory\n");
326 drmAgpFree(pVia
->drmFD
, pVia
->agpHandle
);
327 xf86DrvMsg(pScreen
->myNum
, X_INFO
, "[drm] Releasing agp module\n");
328 drmAgpRelease(pVia
->drmFD
);
333 VIADRIFinishScreenInit(DRIDriverContext
* ctx
)
335 VIAPtr pVia
= VIAPTR(ctx
);
339 err
= drmCreateContext(ctx
->drmFD
, &ctx
->serverContext
);
341 fprintf(stderr
, "%s: drmCreateContext failed %d\n", __FUNCTION__
, err
);
345 DRM_LOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
, 0);
348 if (!VIADRIKernelInit(ctx
, pVia
)) {
349 VIADRICloseScreen(ctx
);
352 xf86DrvMsg(pScreen
->myNum
, X_INFO
, "[dri] kernel data initialized.\n");
354 /* set SAREA value */
356 VIASAREAPriv
*saPriv
;
358 saPriv
=(VIASAREAPriv
*)(((char*)ctx
->pSAREA
) +
359 sizeof(XF86DRISAREARec
));
361 memset(saPriv
, 0, sizeof(*saPriv
));
362 saPriv
->CtxOwner
= -1;
364 pVIADRI
=(VIADRIPtr
)pVia
->devPrivate
;
365 pVIADRI
->deviceID
=pVia
->Chipset
;
366 pVIADRI
->width
=ctx
->shared
.virtualWidth
;
367 pVIADRI
->height
=ctx
->shared
.virtualHeight
;
368 pVIADRI
->mem
=ctx
->shared
.fbSize
;
369 pVIADRI
->bytesPerPixel
= (ctx
->bpp
+7) / 8;
370 pVIADRI
->sarea_priv_offset
= sizeof(XF86DRISAREARec
);
372 pVIADRI
->scrnX
=pVIADRI
->width
;
373 pVIADRI
->scrnY
=pVIADRI
->height
;
378 /* Initialize the kernel data structures. */
379 static int VIADRIKernelInit(DRIDriverContext
* ctx
, VIAPtr pVia
)
382 memset(&drmInfo
, 0, sizeof(drmVIAInit
));
383 drmInfo
.sarea_priv_offset
= sizeof(XF86DRISAREARec
);
384 drmInfo
.fb_offset
= pVia
->FrameBufferBase
;
385 drmInfo
.mmio_offset
= pVia
->registerHandle
;
387 drmInfo
.agpAddr
= (CARD32
)NULL
;
389 drmInfo
.agpAddr
= (CARD32
)pVia
->agpAddr
;
391 if (drmVIAInitMAP(pVia
->drmFD
, &drmInfo
) < 0) return FALSE
;
395 /* Add a map for the MMIO registers */
396 static int VIADRIMapInit(DRIDriverContext
* ctx
, VIAPtr pVia
)
400 if (drmAddMap(pVia
->drmFD
, pVia
->MmioBase
, VIA_MMIO_REGSIZE
,
401 DRM_REGISTERS
, flags
, &pVia
->registerHandle
) < 0) {
405 xf86DrvMsg(pScreen
->myNum
, X_INFO
,
406 "[drm] register handle = 0x%08lx\n", pVia
->registerHandle
);
411 const __GLcontextModes __glModes
[] =
413 /* 32 bit, RGBA Depth=16 Stencil=8 */
414 {.rgbMode
= GL_TRUE
, .colorIndexMode
= GL_FALSE
, .doubleBufferMode
= GL_TRUE
, .stereoMode
= GL_FALSE
,
415 .haveAccumBuffer
= GL_FALSE
, .haveDepthBuffer
= GL_TRUE
, .haveStencilBuffer
= GL_TRUE
,
416 .redBits
= 8, .greenBits
= 8, .blueBits
= 8, .alphaBits
= 8,
417 .redMask
= 0xff0000, .greenMask
= 0xff00, .blueMask
= 0xff, .alphaMask
= 0xff000000,
418 .rgbBits
= 32, .indexBits
= 0,
419 .accumRedBits
= 0, .accumGreenBits
= 0, .accumBlueBits
= 0, .accumAlphaBits
= 0,
420 .depthBits
= 16, .stencilBits
= 8,
421 .numAuxBuffers
= 0, .level
= 0, .pixmapMode
= GL_TRUE
, },
424 /* 16 bit, RGB Depth=16 */
425 {.rgbMode
= GL_TRUE
, .colorIndexMode
= GL_FALSE
, .doubleBufferMode
= GL_TRUE
, .stereoMode
= GL_FALSE
,
426 .haveAccumBuffer
= GL_FALSE
, .haveDepthBuffer
= GL_TRUE
, .haveStencilBuffer
= GL_FALSE
,
427 .redBits
= 5, .greenBits
= 6, .blueBits
= 5, .alphaBits
= 0,
428 .redMask
= 0xf800, .greenMask
= 0x07e0, .blueMask
= 0x001f, .alphaMask
= 0x0,
429 .rgbBits
= 16, .indexBits
= 0,
430 .accumRedBits
= 0, .accumGreenBits
= 0, .accumBlueBits
= 0, .accumAlphaBits
= 0,
431 .depthBits
= 16, .stencilBits
= 0,
432 .numAuxBuffers
= 0, .level
= 0, .pixmapMode
= GL_TRUE
, },
436 static int viaInitContextModes(const DRIDriverContext
*ctx
,
437 int *numModes
, const __GLcontextModes
**modes
)
439 *numModes
= sizeof(__glModes
)/sizeof(__GLcontextModes
*);
440 *modes
= &__glModes
[0];
444 static int viaValidateMode(const DRIDriverContext
*ctx
)
446 VIAPtr pVia
= VIAPTR(ctx
);
451 static int viaPostValidateMode(const DRIDriverContext
*ctx
)
453 VIAPtr pVia
= VIAPTR(ctx
);
458 static void VIAEnableMMIO(DRIDriverContext
* ctx
)
460 /*vgaHWPtr hwp = VGAHWPTR(ctx);*/
461 VIAPtr pVia
= VIAPTR(ctx
);
465 if (xf86IsPrimaryPci(pVia
->PciInfo
)) {
466 /* If we are primary card, we still use std vga port. If we use
467 * MMIO, system will hang in vgaHWSave when our card used in
468 * PLE and KLE (integrated Trident MVP4)
470 vgaHWSetStdFuncs(hwp
);
473 vgaHWSetMmioFuncs(hwp
, pVia
->MapBase
, 0x8000);
478 VGAOUT8(0x3c3, val
| 0x01);
480 VGAOUT8(0x3c2, val
| 0x01);
482 /* Unlock Extended IO Space */
483 VGAOUT8(0x3c4, 0x10);
484 VGAOUT8(0x3c5, 0x01);
487 if(!pVia
->IsSecondary
) {
488 VGAOUT8(0x3c4, 0x1a);
491 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
, "primary val = %x\n", val
);
493 VGAOUT8(0x3c5, val
| 0x68);
496 VGAOUT8(0x3c4, 0x1a);
499 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
, "secondary val = %x\n", val
);
501 VGAOUT8(0x3c5, val
| 0x38);
504 /* Unlock CRTC registers */
505 VGAOUT8(0x3d4, 0x47);
506 VGAOUT8(0x3d5, 0x00);
511 static void VIADisableMMIO(DRIDriverContext
* ctx
)
513 VIAPtr pVia
= VIAPTR(ctx
);
516 VGAOUT8(0x3c4, 0x1a);
518 VGAOUT8(0x3c5, val
& 0x97);
523 static void VIADisableExtendedFIFO(DRIDriverContext
*ctx
)
525 VIAPtr pVia
= VIAPTR(ctx
);
526 CARD32 dwGE230
, dwGE298
;
528 /* Cause of exit XWindow will dump back register value, others chipset no
529 * need to set extended fifo value */
530 if (pVia
->Chipset
== VIA_CLE266
&& pVia
->ChipRev
< 15 &&
531 (ctx
->shared
.virtualWidth
> 1024 || pVia
->HasSecondary
)) {
532 /* Turn off Extend FIFO */
534 dwGE298
= VIAGETREG(0x298);
535 VIASETREG(0x298, dwGE298
| 0x20000000);
537 dwGE230
= VIAGETREG(0x230);
538 VIASETREG(0x230, dwGE230
& ~0x00200000);
540 dwGE298
= VIAGETREG(0x298);
541 VIASETREG(0x298, dwGE298
& ~0x20000000);
545 static void VIAEnableExtendedFIFO(DRIDriverContext
*ctx
)
547 VIAPtr pVia
= VIAPTR(ctx
);
549 CARD32 dwGE230
, dwGE298
;
551 switch (pVia
->Chipset
) {
553 if (pVia
->ChipRev
> 14) { /* For 3123Cx */
554 if (pVia
->HasSecondary
) { /* SAMM or DuoView case */
555 if (ctx
->shared
.virtualWidth
>= 1024)
558 VGAOUT8(0x3C4, 0x16);
559 bRegTemp
= VGAIN8(0x3C5);
562 VGAOUT8(0x3C5, bRegTemp
);
564 VGAOUT8(0x3C4, 0x17);
565 bRegTemp
= VGAIN8(0x3C5);
568 VGAOUT8(0x3C5, bRegTemp
);
569 pVia
->EnableExtendedFIFO
= TRUE
;
572 else /* Single view or Simultaneoue case */
574 if (ctx
->shared
.virtualWidth
> 1024)
577 VGAOUT8(0x3C4, 0x16);
578 bRegTemp
= VGAIN8(0x3C5);
581 VGAOUT8(0x3C5, bRegTemp
);
583 VGAOUT8(0x3C4, 0x17);
584 bRegTemp
= VGAIN8(0x3C5);
587 VGAOUT8(0x3C5, bRegTemp
);
588 pVia
->EnableExtendedFIFO
= TRUE
;
592 VGAOUT8(0x3C4, 0x18);
593 bRegTemp
= VGAIN8(0x3C5);
596 bRegTemp
|= 0x40; /* force the preq always higher than treq */
597 VGAOUT8(0x3C5, bRegTemp
);
599 else { /* for 3123Ax */
600 if (ctx
->shared
.virtualWidth
> 1024 || pVia
->HasSecondary
) {
601 /* Turn on Extend FIFO */
603 dwGE298
= VIAGETREG(0x298);
604 VIASETREG(0x298, dwGE298
| 0x20000000);
606 dwGE230
= VIAGETREG(0x230);
607 VIASETREG(0x230, dwGE230
| 0x00200000);
609 dwGE298
= VIAGETREG(0x298);
610 VIASETREG(0x298, dwGE298
& ~0x20000000);
613 VGAOUT8(0x3C4, 0x16);
614 bRegTemp
= VGAIN8(0x3C5);
617 /* bRegTemp |= 0x10; */
618 VGAOUT8(0x3C5, bRegTemp
);
620 VGAOUT8(0x3C4, 0x17);
621 bRegTemp
= VGAIN8(0x3C5);
624 /*bRegTemp |= 0x1F;*/
625 VGAOUT8(0x3C5, bRegTemp
);
627 VGAOUT8(0x3C4, 0x18);
628 bRegTemp
= VGAIN8(0x3C5);
631 bRegTemp
|= 0x40; /* force the preq always higher than treq */
632 VGAOUT8(0x3C5, bRegTemp
);
633 pVia
->EnableExtendedFIFO
= TRUE
;
638 if (pVia
->HasSecondary
) { /* SAMM or DuoView case */
639 if ((ctx
->shared
.virtualWidth
>= 1600) &&
640 (pVia
->MemClk
<= VIA_MEM_DDR200
)) {
641 /* enable CRT extendded FIFO */
642 VGAOUT8(0x3C4, 0x17);
643 VGAOUT8(0x3C5, 0x1C);
644 /* revise second display queue depth and read threshold */
645 VGAOUT8(0x3C4, 0x16);
646 bRegTemp
= VGAIN8(0x3C5);
648 bRegTemp
= (bRegTemp
) | (0x09);
649 VGAOUT8(0x3C5, bRegTemp
);
652 /* enable CRT extendded FIFO */
653 VGAOUT8(0x3C4, 0x17);
655 /* revise second display queue depth and read threshold */
656 VGAOUT8(0x3C4, 0x16);
657 bRegTemp
= VGAIN8(0x3C5);
659 bRegTemp
= (bRegTemp
) | (0x1C);
660 VGAOUT8(0x3C5, bRegTemp
);
663 VGAOUT8(0x3C4, 0x18);
664 bRegTemp
= VGAIN8(0x3C5);
667 bRegTemp
|= 0x40; /* force the preq always higher than treq */
668 VGAOUT8(0x3C5, bRegTemp
);
669 pVia
->EnableExtendedFIFO
= TRUE
;
672 if ( (ctx
->shared
.virtualWidth
> 1024) && (ctx
->shared
.virtualWidth
<= 1280) )
674 /* enable CRT extendded FIFO */
675 VGAOUT8(0x3C4, 0x17);
676 VGAOUT8(0x3C5, 0x3F);
677 /* revise second display queue depth and read threshold */
678 VGAOUT8(0x3C4, 0x16);
679 bRegTemp
= VGAIN8(0x3C5);
681 bRegTemp
= (bRegTemp
) | (0x17);
682 VGAOUT8(0x3C5, bRegTemp
);
683 pVia
->EnableExtendedFIFO
= TRUE
;
685 else if ((ctx
->shared
.virtualWidth
> 1280))
687 /* enable CRT extendded FIFO */
688 VGAOUT8(0x3C4, 0x17);
689 VGAOUT8(0x3C5, 0x3F);
690 /* revise second display queue depth and read threshold */
691 VGAOUT8(0x3C4, 0x16);
692 bRegTemp
= VGAIN8(0x3C5);
694 bRegTemp
= (bRegTemp
) | (0x1C);
695 VGAOUT8(0x3C5, bRegTemp
);
696 pVia
->EnableExtendedFIFO
= TRUE
;
700 /* enable CRT extendded FIFO */
701 VGAOUT8(0x3C4, 0x17);
702 VGAOUT8(0x3C5, 0x3F);
703 /* revise second display queue depth and read threshold */
704 VGAOUT8(0x3C4, 0x16);
705 bRegTemp
= VGAIN8(0x3C5);
707 bRegTemp
= (bRegTemp
) | (0x10);
708 VGAOUT8(0x3C5, bRegTemp
);
711 VGAOUT8(0x3C4, 0x18);
712 bRegTemp
= VGAIN8(0x3C5);
715 bRegTemp
|= 0x40; /* force the preq always higher than treq */
716 VGAOUT8(0x3C5, bRegTemp
);
720 /*=* R1 Display FIFO depth (384 /8 -1 -> 0xbf) SR17[7:0] (8bits) *=*/
721 VGAOUT8(0x3c4, 0x17);
722 VGAOUT8(0x3c5, 0xbf);
724 /*=* R2 Display fetch datum threshold value (328/4 -> 0x52)
725 SR16[5:0], SR16[7] (7bits) *=*/
726 VGAOUT8(0x3c4, 0x16);
727 bRegTemp
= VGAIN8(0x3c5) & ~0xBF;
728 bRegTemp
|= (0x52 & 0x3F);
729 bRegTemp
|= ((0x52 & 0x40) << 1);
730 VGAOUT8(0x3c5, bRegTemp
);
732 /*=* R3 Switch to the highest agent threshold value (74 -> 0x4a)
733 SR18[5:0], SR18[7] (7bits) *=*/
734 VGAOUT8(0x3c4, 0x18);
735 bRegTemp
= VGAIN8(0x3c5) & ~0xBF;
736 bRegTemp
|= (0x4a & 0x3F);
737 bRegTemp
|= ((0x4a & 0x40) << 1);
738 VGAOUT8(0x3c5, bRegTemp
);
740 /*=* R4 Fetch Number for a scan line (unit: 8 bytes)
741 SR1C[7:0], SR1D[1:0] (10bits) *=*/
742 wRegTemp
= (pBIOSInfo
->offsetWidthByQWord
>> 1) + 4;
743 VGAOUT8(0x3c4, 0x1c);
744 VGAOUT8(0x3c5, (CARD8
)(wRegTemp
& 0xFF));
745 VGAOUT8(0x3c4, 0x1d);
746 bRegTemp
= VGAIN8(0x3c5) & ~0x03;
747 VGAOUT8(0x3c5, bRegTemp
| ((wRegTemp
& 0x300) >> 8));
749 if (ctx
->shared
.virtualWidth
>= 1400 && ctx
->bpp
== 32)
751 /*=* Max. length for a request SR22[4:0] (64/4 -> 0x10) *=*/
752 VGAOUT8(0x3c4, 0x22);
753 bRegTemp
= VGAIN8(0x3c5) & ~0x1F;
754 VGAOUT8(0x3c5, bRegTemp
| 0x10);
758 /*=* Max. length for a request SR22[4:0]
759 (128/4 -> over flow 0x0) *=*/
760 VGAOUT8(0x3c4, 0x22);
761 bRegTemp
= VGAIN8(0x3c5) & ~0x1F;
762 VGAOUT8(0x3c5, bRegTemp
);
766 /*=* R1 Display FIFO depth (96-1 -> 0x5f) SR17[7:0] (8bits) *=*/
767 VGAOUT8(0x3c4, 0x17);
768 VGAOUT8(0x3c5, 0x5f);
770 /*=* R2 Display fetch datum threshold value (32 -> 0x20)
771 SR16[5:0], SR16[7] (7bits) *=*/
772 VGAOUT8(0x3c4, 0x16);
773 bRegTemp
= VGAIN8(0x3c5) & ~0xBF;
774 bRegTemp
|= (0x20 & 0x3F);
775 bRegTemp
|= ((0x20 & 0x40) << 1);
776 VGAOUT8(0x3c5, bRegTemp
);
778 /*=* R3 Switch to the highest agent threshold value (16 -> 0x10)
779 SR18[5:0], SR18[7] (7bits) *=*/
780 VGAOUT8(0x3c4, 0x18);
781 bRegTemp
= VGAIN8(0x3c5) & ~0xBF;
782 bRegTemp
|= (0x10 & 0x3F);
783 bRegTemp
|= ((0x10 & 0x40) << 1);
784 VGAOUT8(0x3c5, bRegTemp
);
786 /*=* R4 Fetch Number for a scan line (unit: 8 bytes)
787 SR1C[7:0], SR1D[1:0] (10bits) *=*/
788 wRegTemp
= (pBIOSInfo
->offsetWidthByQWord
>> 1) + 4;
789 VGAOUT8(0x3c4, 0x1c);
790 VGAOUT8(0x3c5, (CARD8
)(wRegTemp
& 0xFF));
791 VGAOUT8(0x3c4, 0x1d);
792 bRegTemp
= VGAIN8(0x3c5) & ~0x03;
793 VGAOUT8(0x3c5, bRegTemp
| ((wRegTemp
& 0x300) >> 8));
795 if (ctx
->shared
.virtualWidth
>= 1400 && ctx
->bpp
== 32)
797 /*=* Max. length for a request SR22[4:0] (64/4 -> 0x10) *=*/
798 VGAOUT8(0x3c4, 0x22);
799 bRegTemp
= VGAIN8(0x3c5) & ~0x1F;
800 VGAOUT8(0x3c5, bRegTemp
| 0x10);
804 /*=* Max. length for a request SR22[4:0] (0x1F) *=*/
805 VGAOUT8(0x3c4, 0x22);
806 bRegTemp
= VGAIN8(0x3c5) & ~0x1F;
807 VGAOUT8(0x3c5, bRegTemp
| 0x1F);
815 static void VIAInitialize2DEngine(DRIDriverContext
*ctx
)
817 VIAPtr pVia
= VIAPTR(ctx
);
818 CARD32 dwVQStartAddr
, dwVQEndAddr
;
819 CARD32 dwVQLen
, dwVQStartL
, dwVQEndL
, dwVQStartEndH
;
822 /* init 2D engine regs to reset 2D engine */
823 VIASETREG(0x04, 0x0);
824 VIASETREG(0x08, 0x0);
825 VIASETREG(0x0c, 0x0);
826 VIASETREG(0x10, 0x0);
827 VIASETREG(0x14, 0x0);
828 VIASETREG(0x18, 0x0);
829 VIASETREG(0x1c, 0x0);
830 VIASETREG(0x20, 0x0);
831 VIASETREG(0x24, 0x0);
832 VIASETREG(0x28, 0x0);
833 VIASETREG(0x2c, 0x0);
834 VIASETREG(0x30, 0x0);
835 VIASETREG(0x34, 0x0);
836 VIASETREG(0x38, 0x0);
837 VIASETREG(0x3c, 0x0);
838 VIASETREG(0x40, 0x0);
842 /* Init AGP and VQ regs */
843 VIASETREG(0x43c, 0x00100000);
844 VIASETREG(0x440, 0x00000000);
845 VIASETREG(0x440, 0x00333004);
846 VIASETREG(0x440, 0x60000000);
847 VIASETREG(0x440, 0x61000000);
848 VIASETREG(0x440, 0x62000000);
849 VIASETREG(0x440, 0x63000000);
850 VIASETREG(0x440, 0x64000000);
851 VIASETREG(0x440, 0x7D000000);
853 VIASETREG(0x43c, 0xfe020000);
854 VIASETREG(0x440, 0x00000000);
856 if (pVia
->VQStart
!= 0) {
858 dwVQStartAddr
= pVia
->VQStart
;
859 dwVQEndAddr
= pVia
->VQEnd
;
860 dwVQStartL
= 0x50000000 | (dwVQStartAddr
& 0xFFFFFF);
861 dwVQEndL
= 0x51000000 | (dwVQEndAddr
& 0xFFFFFF);
862 dwVQStartEndH
= 0x52000000 | ((dwVQStartAddr
& 0xFF000000) >> 24) |
863 ((dwVQEndAddr
& 0xFF000000) >> 16);
864 dwVQLen
= 0x53000000 | (VIA_VQ_SIZE
>> 3);
866 VIASETREG(0x43c, 0x00fe0000);
867 VIASETREG(0x440, 0x080003fe);
868 VIASETREG(0x440, 0x0a00027c);
869 VIASETREG(0x440, 0x0b000260);
870 VIASETREG(0x440, 0x0c000274);
871 VIASETREG(0x440, 0x0d000264);
872 VIASETREG(0x440, 0x0e000000);
873 VIASETREG(0x440, 0x0f000020);
874 VIASETREG(0x440, 0x1000027e);
875 VIASETREG(0x440, 0x110002fe);
876 VIASETREG(0x440, 0x200f0060);
878 VIASETREG(0x440, 0x00000006);
879 VIASETREG(0x440, 0x40008c0f);
880 VIASETREG(0x440, 0x44000000);
881 VIASETREG(0x440, 0x45080c04);
882 VIASETREG(0x440, 0x46800408);
884 VIASETREG(0x440, dwVQStartEndH
);
885 VIASETREG(0x440, dwVQStartL
);
886 VIASETREG(0x440, dwVQEndL
);
887 VIASETREG(0x440, dwVQLen
);
891 VIASETREG(0x43c, 0x00fe0000);
892 VIASETREG(0x440, 0x00000004);
893 VIASETREG(0x440, 0x40008c0f);
894 VIASETREG(0x440, 0x44000000);
895 VIASETREG(0x440, 0x45080c04);
896 VIASETREG(0x440, 0x46800408);
903 dwGEMode
|= VIA_GEM_16bpp
;
906 dwGEMode
|= VIA_GEM_32bpp
;
908 dwGEMode
|= VIA_GEM_8bpp
;
913 switch (ctx
->shared
.virtualWidth
) {
915 dwGEMode
|= VIA_GEM_800
;
918 dwGEMode
|= VIA_GEM_1024
;
921 dwGEMode
|= VIA_GEM_1280
;
924 dwGEMode
|= VIA_GEM_1600
;
927 dwGEMode
|= VIA_GEM_2048
;
930 dwGEMode
|= VIA_GEM_640
;
937 /* Set BPP and Pitch */
938 VIASETREG(VIA_REG_GEMODE
, dwGEMode
);
940 /* Set Src and Dst base address and pitch, pitch is qword */
941 VIASETREG(VIA_REG_SRCBASE
, 0x0);
942 VIASETREG(VIA_REG_DSTBASE
, 0x0);
943 VIASETREG(VIA_REG_PITCH
, VIA_PITCH_ENABLE
|
944 ((ctx
->shared
.virtualWidth
* ctx
->bpp
>> 3) >> 3) |
945 (((ctx
->shared
.virtualWidth
* ctx
->bpp
>> 3) >> 3) << 16));
948 static int b3DRegsInitialized
= 0;
950 static void VIAInitialize3DEngine(DRIDriverContext
*ctx
)
952 VIAPtr pVia
= VIAPTR(ctx
);
955 if (!b3DRegsInitialized
)
958 VIASETREG(0x43C, 0x00010000);
960 for (i
= 0; i
<= 0x7D; i
++)
962 VIASETREG(0x440, (CARD32
) i
<< 24);
965 VIASETREG(0x43C, 0x00020000);
967 for (i
= 0; i
<= 0x94; i
++)
969 VIASETREG(0x440, (CARD32
) i
<< 24);
972 VIASETREG(0x440, 0x82400000);
974 VIASETREG(0x43C, 0x01020000);
977 for (i
= 0; i
<= 0x94; i
++)
979 VIASETREG(0x440, (CARD32
) i
<< 24);
982 VIASETREG(0x440, 0x82400000);
983 VIASETREG(0x43C, 0xfe020000);
985 for (i
= 0; i
<= 0x03; i
++)
987 VIASETREG(0x440, (CARD32
) i
<< 24);
990 VIASETREG(0x43C, 0x00030000);
992 for (i
= 0; i
<= 0xff; i
++)
996 VIASETREG(0x43C, 0x00100000);
997 VIASETREG(0x440, 0x00333004);
998 VIASETREG(0x440, 0x10000002);
999 VIASETREG(0x440, 0x60000000);
1000 VIASETREG(0x440, 0x61000000);
1001 VIASETREG(0x440, 0x62000000);
1002 VIASETREG(0x440, 0x63000000);
1003 VIASETREG(0x440, 0x64000000);
1005 VIASETREG(0x43C, 0x00fe0000);
1007 if (pVia
->ChipRev
>= 3 )
1008 VIASETREG(0x440,0x40008c0f);
1010 VIASETREG(0x440,0x4000800f);
1012 VIASETREG(0x440,0x44000000);
1013 VIASETREG(0x440,0x45080C04);
1014 VIASETREG(0x440,0x46800408);
1015 VIASETREG(0x440,0x50000000);
1016 VIASETREG(0x440,0x51000000);
1017 VIASETREG(0x440,0x52000000);
1018 VIASETREG(0x440,0x53000000);
1020 b3DRegsInitialized
= 1;
1021 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
,
1022 "3D Engine has been initialized.\n");
1025 VIASETREG(0x43C,0x00fe0000);
1026 VIASETREG(0x440,0x08000001);
1027 VIASETREG(0x440,0x0A000183);
1028 VIASETREG(0x440,0x0B00019F);
1029 VIASETREG(0x440,0x0C00018B);
1030 VIASETREG(0x440,0x0D00019B);
1031 VIASETREG(0x440,0x0E000000);
1032 VIASETREG(0x440,0x0F000000);
1033 VIASETREG(0x440,0x10000000);
1034 VIASETREG(0x440,0x11000000);
1035 VIASETREG(0x440,0x20000000);
1039 WaitIdleCLE266(VIAPtr pVia
)
1045 while (!(VIAGETREG(VIA_REG_STATUS
) & VIA_VR_QUEUE_BUSY
) && (loop
++ < MAXLOOP
))
1048 while ((VIAGETREG(VIA_REG_STATUS
) &
1049 (VIA_CMD_RGTR_BUSY
| VIA_2D_ENG_BUSY
| VIA_3D_ENG_BUSY
)) &&
1053 return loop
>= MAXLOOP
;
1056 static int viaInitFBDev(DRIDriverContext
*ctx
)
1058 VIAPtr pVia
= CALLOC(sizeof(*pVia
));
1060 ctx
->driverPrivate
= (void *)pVia
;
1062 switch (ctx
->chipset
) {
1063 case PCI_CHIP_CLE3122
:
1064 case PCI_CHIP_CLE3022
:
1065 pVia
->Chipset
= VIA_CLE266
;
1067 case PCI_CHIP_VT7205
:
1068 case PCI_CHIP_VT3205
:
1069 pVia
->Chipset
= VIA_KM400
;
1071 case PCI_CHIP_VT3204
:
1072 pVia
->Chipset
= VIA_K8M800
;
1074 case PCI_CHIP_VT3259
:
1075 pVia
->Chipset
= VIA_PM800
;
1078 xf86DrvMsg(0, X_ERROR
, "VIA: Unknown device ID (0x%x)\n", ctx
->chipset
);
1081 /* _SOLO TODO XXX need to read ChipRev too */
1084 pVia
->videoRambytes
= ctx
->shared
.fbSize
;
1085 pVia
->MmioBase
= ctx
->MMIOStart
;
1086 pVia
->FrameBufferBase
= ctx
->FBStart
& 0xfc000000;
1088 pVia
->FBFreeStart
= ctx
->shared
.virtualWidth
* ctx
->cpp
*
1089 ctx
->shared
.virtualHeight
;
1090 pVia
->FBFreeEnd
= pVia
->videoRambytes
;
1092 if (!VIADRIScreenInit(ctx
))
1097 /* Get video memory clock. */
1098 VGAOUT8(0x3D4, 0x3D);
1099 pVia
->MemClk
= (VGAIN8(0x3D5) & 0xF0) >> 4;
1100 xf86DrvMsg(0, X_INFO
, "[dri] MemClk (0x%x)\n", pVia
->MemClk
);
1102 /* 3D rendering has noise if not enabled. */
1103 VIAEnableExtendedFIFO(ctx
);
1105 VIAInitialize2DEngine(ctx
);
1107 /* Must disable MMIO or 3D won't work. */
1108 VIADisableMMIO(ctx
);
1110 VIAInitialize3DEngine(ctx
);
1115 static void viaHaltFBDev(DRIDriverContext
*ctx
)
1117 drmUnmap( ctx
->pSAREA
, ctx
->shared
.SAREASize
);
1118 drmClose(ctx
->drmFD
);
1120 if (ctx
->driverPrivate
) {
1121 free(ctx
->driverPrivate
);
1122 ctx
->driverPrivate
= 0;
1126 static int viaEngineShutdown(const DRIDriverContext
*ctx
)
1131 static int viaEngineRestore(const DRIDriverContext
*ctx
)
1136 const struct DRIDriverRec __driDriver
=
1138 viaInitContextModes
,
1140 viaPostValidateMode
,