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"
52 #include "via_context.h"
54 #include "via_driver.h"
55 #include "via_common.h"
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
);
65 static int VIADRIScreenInit(DRIDriverContext
* ctx
);
66 static void VIADRICloseScreen(DRIDriverContext
* ctx
);
67 static int VIADRIFinishScreenInit(DRIDriverContext
* ctx
);
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 uint8_t*)base)+(addr)))+0)
72 #define MMIO_OUT8(base, addr, val) ((*(((volatile uint8_t*)base)+(addr)))=((uint8_t)val))
73 #define MMIO_OUT16(base, addr, val) ((*(volatile uint16_t*)(((uint8_t*)base)+(addr)))=((uint16_t)val))
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 256
81 #define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES)
83 static char VIAKernelDriverName
[] = "via";
84 static char VIAClientDriverName
[] = "via";
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
);
92 static int VIADRIAgpInit(const DRIDriverContext
*ctx
, VIAPtr pVia
)
94 unsigned long agp_phys
;
97 pVIADRI
= pVia
->devPrivate
;
100 if (drmAgpAcquire(pVia
->drmFD
) < 0) {
101 xf86DrvMsg(pScreen
->myNum
, X_ERROR
, "[drm] drmAgpAcquire failed %d\n", errno
);
105 if (drmAgpEnable(pVia
->drmFD
, drmAgpGetMode(pVia
->drmFD
)&~0x0) < 0) {
106 xf86DrvMsg(pScreen
->myNum
, X_ERROR
, "[drm] drmAgpEnable failed\n");
110 xf86DrvMsg(pScreen
->myNum
, X_INFO
, "[drm] drmAgpEnabled succeeded\n");
112 if (drmAgpAlloc(pVia
->drmFD
, AGP_SIZE
, 0, &agp_phys
, &pVia
->agpHandle
) < 0) {
113 xf86DrvMsg(pScreen
->myNum
, X_ERROR
,
114 "[drm] drmAgpAlloc failed\n");
115 drmAgpRelease(pVia
->drmFD
);
119 if (drmAgpBind(pVia
->drmFD
, pVia
->agpHandle
, 0) < 0) {
120 xf86DrvMsg(pScreen
->myNum
, X_ERROR
,
121 "[drm] drmAgpBind failed\n");
122 drmAgpFree(pVia
->drmFD
, pVia
->agpHandle
);
123 drmAgpRelease(pVia
->drmFD
);
128 pVia
->agpSize
= AGP_SIZE
;
129 pVia
->agpAddr
= drmAgpBase(pVia
->drmFD
);
130 xf86DrvMsg(pScreen
->myNum
, X_INFO
,
131 "[drm] agpAddr = 0x%08lx\n",pVia
->agpAddr
);
133 pVIADRI
->agp
.size
= pVia
->agpSize
;
134 if (drmAddMap(pVia
->drmFD
, (drm_handle_t
)0,
135 pVIADRI
->agp
.size
, DRM_AGP
, 0,
136 &pVIADRI
->agp
.handle
) < 0) {
137 xf86DrvMsg(pScreen
->myNum
, X_ERROR
,
138 "[drm] Failed to map public agp area\n");
139 pVIADRI
->agp
.size
= 0;
142 /* Map AGP from kernel to Xserver - Not really needed */
143 drmMap(pVia
->drmFD
, pVIADRI
->agp
.handle
,pVIADRI
->agp
.size
,
144 (drmAddressPtr
)&agpaddr
);
147 xf86DrvMsg(pScreen
->myNum
, X_INFO
,
148 "[drm] agpBase = 0x%08lx\n", pVia
->agpBase
);
149 xf86DrvMsg(pScreen
->myNum
, X_INFO
,
150 "[drm] agpAddr = 0x%08lx\n", pVia
->agpAddr
);
152 xf86DrvMsg(pScreen
->myNum
, X_INFO
,
153 "[drm] agpSize = 0x%08lx\n", pVia
->agpSize
);
154 xf86DrvMsg(pScreen
->myNum
, X_INFO
,
155 "[drm] agp physical addr = 0x%08lx\n", agp_phys
);
157 drmVIAAgpInit(pVia
->drmFD
, 0, AGP_SIZE
);
162 static int VIADRIFBInit(DRIDriverContext
* ctx
, VIAPtr pVia
)
164 int FBSize
= pVia
->FBFreeEnd
-pVia
->FBFreeStart
;
165 int FBOffset
= pVia
->FBFreeStart
;
166 VIADRIPtr pVIADRI
= pVia
->devPrivate
;
167 pVIADRI
->fbOffset
= FBOffset
;
168 pVIADRI
->fbSize
= pVia
->videoRambytes
;
170 if (drmVIAFBInit(pVia
->drmFD
, FBOffset
, FBSize
) < 0) {
171 xf86DrvMsg(pScreen
->myNum
, X_ERROR
,"[drm] failed to init frame buffer area\n");
175 xf86DrvMsg(pScreen
->myNum
, X_INFO
,"[drm] FBFreeStart= 0x%08lx FBFreeEnd= 0x%08lx FBSize= 0x%08lx\n", pVia
->FBFreeStart
, pVia
->FBFreeEnd
, FBSize
);
180 static int VIADRIPciInit(DRIDriverContext
* ctx
, VIAPtr pVia
)
185 static int VIADRIScreenInit(DRIDriverContext
* ctx
)
187 VIAPtr pVia
= VIAPTR(ctx
);
192 ctx
->shared
.SAREASize
= ((sizeof(drm_sarea_t
) + 0xfff) & 0x1000);
194 if (sizeof(drm_sarea_t
)+sizeof(VIASAREAPriv
) > SAREA_MAX
) {
195 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
196 "Data does not fit in SAREA\n");
199 ctx
->shared
.SAREASize
= SAREA_MAX
;
202 ctx
->drmFD
= drmOpen(VIAKernelDriverName
, NULL
);
203 if (ctx
->drmFD
< 0) {
204 fprintf(stderr
, "[drm] drmOpen failed\n");
207 pVia
->drmFD
= ctx
->drmFD
;
209 err
= drmSetBusid(ctx
->drmFD
, ctx
->pciBusID
);
211 fprintf(stderr
, "[drm] drmSetBusid failed (%d, %s), %s\n",
212 ctx
->drmFD
, ctx
->pciBusID
, strerror(-err
));
216 err
= drmAddMap(ctx
->drmFD
, 0, ctx
->shared
.SAREASize
, DRM_SHM
,
217 DRM_CONTAINS_LOCK
, &ctx
->shared
.hSAREA
);
219 fprintf(stderr
, "[drm] drmAddMap failed\n");
222 fprintf(stderr
, "[drm] added %d byte SAREA at 0x%08lx\n",
223 ctx
->shared
.SAREASize
, ctx
->shared
.hSAREA
);
225 if (drmMap(ctx
->drmFD
,
227 ctx
->shared
.SAREASize
,
228 (drmAddressPtr
)(&ctx
->pSAREA
)) < 0)
230 fprintf(stderr
, "[drm] drmMap failed\n");
233 memset(ctx
->pSAREA
, 0, ctx
->shared
.SAREASize
);
234 fprintf(stderr
, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",
235 ctx
->shared
.hSAREA
, ctx
->pSAREA
, ctx
->shared
.SAREASize
);
237 /* Need to AddMap the framebuffer and mmio regions here:
239 if (drmAddMap(ctx
->drmFD
,
240 (drm_handle_t
)ctx
->FBStart
,
248 &ctx
->shared
.hFrameBuffer
) < 0)
250 fprintf(stderr
, "[drm] drmAddMap framebuffer failed\n");
254 fprintf(stderr
, "[drm] framebuffer handle = 0x%08lx\n",
255 ctx
->shared
.hFrameBuffer
);
257 pVIADRI
= (VIADRIPtr
) CALLOC(sizeof(VIADRIRec
));
259 drmClose(ctx
->drmFD
);
262 pVia
->devPrivate
= pVIADRI
;
263 ctx
->driverClientMsg
= pVIADRI
;
264 ctx
->driverClientMsgSize
= sizeof(*pVIADRI
);
266 pVia
->IsPCI
= !VIADRIAgpInit(ctx
, pVia
);
269 VIADRIPciInit(ctx
, pVia
);
270 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
, "[dri] use pci.\n" );
273 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
, "[dri] use agp.\n" );
275 if (!(VIADRIFBInit(ctx
, pVia
))) {
276 VIADRICloseScreen(ctx
);
277 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
, "[dri] frame buffer initialize fial .\n" );
281 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
, "[dri] frame buffer initialized.\n" );
283 /* DRIScreenInit doesn't add all the common mappings. Add additional mappings here. */
284 if (!VIADRIMapInit(ctx
, pVia
)) {
285 VIADRICloseScreen(ctx
);
288 pVIADRI
->regs
.size
= VIA_MMIO_REGSIZE
;
289 pVIADRI
->regs
.map
= 0;
290 pVIADRI
->regs
.handle
= pVia
->registerHandle
;
291 xf86DrvMsg(pScreen
->myNum
, X_INFO
, "[drm] mmio Registers = 0x%08lx\n",
292 pVIADRI
->regs
.handle
);
294 /*pVIADRI->drixinerama = pVia->drixinerama;*/
295 /*=* John Sheng [2003.12.9] Tuxracer & VQ *=*/
296 pVIADRI
->VQEnable
= pVia
->VQEnable
;
298 if (drmMap(pVia
->drmFD
,
299 pVIADRI
->regs
.handle
,
301 (drmAddress
*)&pVia
->MapBase
) != 0)
303 VIADRICloseScreen(ctx
);
307 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
, "[dri] mmio mapped.\n" );
309 return VIADRIFinishScreenInit(ctx
);
313 VIADRICloseScreen(DRIDriverContext
* ctx
)
315 VIAPtr pVia
= VIAPTR(ctx
);
316 VIADRIPtr pVIADRI
=(VIADRIPtr
)pVia
->devPrivate
;
319 xf86DrvMsg(pScreen
->myNum
, X_INFO
, "[drm] Unmapping MMIO registers\n");
320 drmUnmap(pVia
->MapBase
, pVIADRI
->regs
.size
);
324 xf86DrvMsg(pScreen
->myNum
, X_INFO
, "[drm] Freeing agp memory\n");
325 drmAgpFree(pVia
->drmFD
, pVia
->agpHandle
);
326 xf86DrvMsg(pScreen
->myNum
, X_INFO
, "[drm] Releasing agp module\n");
327 drmAgpRelease(pVia
->drmFD
);
332 VIADRIFinishScreenInit(DRIDriverContext
* ctx
)
334 VIAPtr pVia
= VIAPTR(ctx
);
338 err
= drmCreateContext(ctx
->drmFD
, &ctx
->serverContext
);
340 fprintf(stderr
, "%s: drmCreateContext failed %d\n", __FUNCTION__
, err
);
344 DRM_LOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
, 0);
347 if (!VIADRIKernelInit(ctx
, pVia
)) {
348 VIADRICloseScreen(ctx
);
351 xf86DrvMsg(pScreen
->myNum
, X_INFO
, "[dri] kernel data initialized.\n");
353 /* set SAREA value */
355 VIASAREAPriv
*saPriv
;
357 saPriv
=(VIASAREAPriv
*)(((char*)ctx
->pSAREA
) +
358 sizeof(drm_sarea_t
));
360 memset(saPriv
, 0, sizeof(*saPriv
));
361 saPriv
->CtxOwner
= -1;
363 pVIADRI
=(VIADRIPtr
)pVia
->devPrivate
;
364 pVIADRI
->deviceID
=pVia
->Chipset
;
365 pVIADRI
->width
=ctx
->shared
.virtualWidth
;
366 pVIADRI
->height
=ctx
->shared
.virtualHeight
;
367 pVIADRI
->mem
=ctx
->shared
.fbSize
;
368 pVIADRI
->bytesPerPixel
= (ctx
->bpp
+7) / 8;
369 pVIADRI
->sarea_priv_offset
= sizeof(drm_sarea_t
);
371 pVIADRI
->scrnX
=pVIADRI
->width
;
372 pVIADRI
->scrnY
=pVIADRI
->height
;
377 /* Initialize the kernel data structures. */
378 static int VIADRIKernelInit(DRIDriverContext
* ctx
, VIAPtr pVia
)
381 memset(&drmInfo
, 0, sizeof(drmVIAInit
));
382 drmInfo
.sarea_priv_offset
= sizeof(drm_sarea_t
);
383 drmInfo
.fb_offset
= pVia
->FrameBufferBase
;
384 drmInfo
.mmio_offset
= pVia
->registerHandle
;
386 drmInfo
.agpAddr
= (uint32_t)NULL
;
388 drmInfo
.agpAddr
= (uint32_t)pVia
->agpAddr
;
390 if (drmVIAInitMAP(pVia
->drmFD
, &drmInfo
) < 0) return GL_FALSE
;
394 /* Add a map for the MMIO registers */
395 static int VIADRIMapInit(DRIDriverContext
* ctx
, VIAPtr pVia
)
399 if (drmAddMap(pVia
->drmFD
, pVia
->MmioBase
, VIA_MMIO_REGSIZE
,
400 DRM_REGISTERS
, flags
, &pVia
->registerHandle
) < 0) {
404 xf86DrvMsg(pScreen
->myNum
, X_INFO
,
405 "[drm] register handle = 0x%08lx\n", pVia
->registerHandle
);
410 static int viaValidateMode(const DRIDriverContext
*ctx
)
412 VIAPtr pVia
= VIAPTR(ctx
);
417 static int viaPostValidateMode(const DRIDriverContext
*ctx
)
419 VIAPtr pVia
= VIAPTR(ctx
);
424 static void VIAEnableMMIO(DRIDriverContext
* ctx
)
426 /*vgaHWPtr hwp = VGAHWPTR(ctx);*/
427 VIAPtr pVia
= VIAPTR(ctx
);
431 if (xf86IsPrimaryPci(pVia
->PciInfo
)) {
432 /* If we are primary card, we still use std vga port. If we use
433 * MMIO, system will hang in vgaHWSave when our card used in
434 * PLE and KLE (integrated Trident MVP4)
436 vgaHWSetStdFuncs(hwp
);
439 vgaHWSetMmioFuncs(hwp
, pVia
->MapBase
, 0x8000);
444 VGAOUT8(0x3c3, val
| 0x01);
446 VGAOUT8(0x3c2, val
| 0x01);
448 /* Unlock Extended IO Space */
449 VGAOUT8(0x3c4, 0x10);
450 VGAOUT8(0x3c5, 0x01);
453 if(!pVia
->IsSecondary
) {
454 VGAOUT8(0x3c4, 0x1a);
457 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
, "primary val = %x\n", val
);
459 VGAOUT8(0x3c5, val
| 0x68);
462 VGAOUT8(0x3c4, 0x1a);
465 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
, "secondary val = %x\n", val
);
467 VGAOUT8(0x3c5, val
| 0x38);
470 /* Unlock CRTC registers */
471 VGAOUT8(0x3d4, 0x47);
472 VGAOUT8(0x3d5, 0x00);
477 static void VIADisableMMIO(DRIDriverContext
* ctx
)
479 VIAPtr pVia
= VIAPTR(ctx
);
482 VGAOUT8(0x3c4, 0x1a);
484 VGAOUT8(0x3c5, val
& 0x97);
489 static void VIADisableExtendedFIFO(DRIDriverContext
*ctx
)
491 VIAPtr pVia
= VIAPTR(ctx
);
492 uint32_t dwGE230
, dwGE298
;
494 /* Cause of exit XWindow will dump back register value, others chipset no
495 * need to set extended fifo value */
496 if (pVia
->Chipset
== VIA_CLE266
&& pVia
->ChipRev
< 15 &&
497 (ctx
->shared
.virtualWidth
> 1024 || pVia
->HasSecondary
)) {
498 /* Turn off Extend FIFO */
500 dwGE298
= VIAGETREG(0x298);
501 VIASETREG(0x298, dwGE298
| 0x20000000);
503 dwGE230
= VIAGETREG(0x230);
504 VIASETREG(0x230, dwGE230
& ~0x00200000);
506 dwGE298
= VIAGETREG(0x298);
507 VIASETREG(0x298, dwGE298
& ~0x20000000);
511 static void VIAEnableExtendedFIFO(DRIDriverContext
*ctx
)
513 VIAPtr pVia
= VIAPTR(ctx
);
515 uint32_t dwGE230
, dwGE298
;
517 switch (pVia
->Chipset
) {
519 if (pVia
->ChipRev
> 14) { /* For 3123Cx */
520 if (pVia
->HasSecondary
) { /* SAMM or DuoView case */
521 if (ctx
->shared
.virtualWidth
>= 1024)
524 VGAOUT8(0x3C4, 0x16);
525 bRegTemp
= VGAIN8(0x3C5);
528 VGAOUT8(0x3C5, bRegTemp
);
530 VGAOUT8(0x3C4, 0x17);
531 bRegTemp
= VGAIN8(0x3C5);
534 VGAOUT8(0x3C5, bRegTemp
);
535 pVia
->EnableExtendedFIFO
= GL_TRUE
;
538 else /* Single view or Simultaneoue case */
540 if (ctx
->shared
.virtualWidth
> 1024)
543 VGAOUT8(0x3C4, 0x16);
544 bRegTemp
= VGAIN8(0x3C5);
547 VGAOUT8(0x3C5, bRegTemp
);
549 VGAOUT8(0x3C4, 0x17);
550 bRegTemp
= VGAIN8(0x3C5);
553 VGAOUT8(0x3C5, bRegTemp
);
554 pVia
->EnableExtendedFIFO
= GL_TRUE
;
558 VGAOUT8(0x3C4, 0x18);
559 bRegTemp
= VGAIN8(0x3C5);
562 bRegTemp
|= 0x40; /* force the preq always higher than treq */
563 VGAOUT8(0x3C5, bRegTemp
);
565 else { /* for 3123Ax */
566 if (ctx
->shared
.virtualWidth
> 1024 || pVia
->HasSecondary
) {
567 /* Turn on Extend FIFO */
569 dwGE298
= VIAGETREG(0x298);
570 VIASETREG(0x298, dwGE298
| 0x20000000);
572 dwGE230
= VIAGETREG(0x230);
573 VIASETREG(0x230, dwGE230
| 0x00200000);
575 dwGE298
= VIAGETREG(0x298);
576 VIASETREG(0x298, dwGE298
& ~0x20000000);
579 VGAOUT8(0x3C4, 0x16);
580 bRegTemp
= VGAIN8(0x3C5);
583 /* bRegTemp |= 0x10; */
584 VGAOUT8(0x3C5, bRegTemp
);
586 VGAOUT8(0x3C4, 0x17);
587 bRegTemp
= VGAIN8(0x3C5);
590 /*bRegTemp |= 0x1F;*/
591 VGAOUT8(0x3C5, bRegTemp
);
593 VGAOUT8(0x3C4, 0x18);
594 bRegTemp
= VGAIN8(0x3C5);
597 bRegTemp
|= 0x40; /* force the preq always higher than treq */
598 VGAOUT8(0x3C5, bRegTemp
);
599 pVia
->EnableExtendedFIFO
= GL_TRUE
;
604 if (pVia
->HasSecondary
) { /* SAMM or DuoView case */
605 if ((ctx
->shared
.virtualWidth
>= 1600) &&
606 (pVia
->MemClk
<= VIA_MEM_DDR200
)) {
607 /* enable CRT extendded FIFO */
608 VGAOUT8(0x3C4, 0x17);
609 VGAOUT8(0x3C5, 0x1C);
610 /* revise second display queue depth and read threshold */
611 VGAOUT8(0x3C4, 0x16);
612 bRegTemp
= VGAIN8(0x3C5);
614 bRegTemp
= (bRegTemp
) | (0x09);
615 VGAOUT8(0x3C5, bRegTemp
);
618 /* enable CRT extendded FIFO */
619 VGAOUT8(0x3C4, 0x17);
621 /* revise second display queue depth and read threshold */
622 VGAOUT8(0x3C4, 0x16);
623 bRegTemp
= VGAIN8(0x3C5);
625 bRegTemp
= (bRegTemp
) | (0x1C);
626 VGAOUT8(0x3C5, bRegTemp
);
629 VGAOUT8(0x3C4, 0x18);
630 bRegTemp
= VGAIN8(0x3C5);
633 bRegTemp
|= 0x40; /* force the preq always higher than treq */
634 VGAOUT8(0x3C5, bRegTemp
);
635 pVia
->EnableExtendedFIFO
= GL_TRUE
;
638 if ( (ctx
->shared
.virtualWidth
> 1024) && (ctx
->shared
.virtualWidth
<= 1280) )
640 /* enable CRT extendded FIFO */
641 VGAOUT8(0x3C4, 0x17);
642 VGAOUT8(0x3C5, 0x3F);
643 /* revise second display queue depth and read threshold */
644 VGAOUT8(0x3C4, 0x16);
645 bRegTemp
= VGAIN8(0x3C5);
647 bRegTemp
= (bRegTemp
) | (0x17);
648 VGAOUT8(0x3C5, bRegTemp
);
649 pVia
->EnableExtendedFIFO
= GL_TRUE
;
651 else if ((ctx
->shared
.virtualWidth
> 1280))
653 /* enable CRT extendded FIFO */
654 VGAOUT8(0x3C4, 0x17);
655 VGAOUT8(0x3C5, 0x3F);
656 /* revise second display queue depth and read threshold */
657 VGAOUT8(0x3C4, 0x16);
658 bRegTemp
= VGAIN8(0x3C5);
660 bRegTemp
= (bRegTemp
) | (0x1C);
661 VGAOUT8(0x3C5, bRegTemp
);
662 pVia
->EnableExtendedFIFO
= GL_TRUE
;
666 /* enable CRT extendded FIFO */
667 VGAOUT8(0x3C4, 0x17);
668 VGAOUT8(0x3C5, 0x3F);
669 /* revise second display queue depth and read threshold */
670 VGAOUT8(0x3C4, 0x16);
671 bRegTemp
= VGAIN8(0x3C5);
673 bRegTemp
= (bRegTemp
) | (0x10);
674 VGAOUT8(0x3C5, bRegTemp
);
677 VGAOUT8(0x3C4, 0x18);
678 bRegTemp
= VGAIN8(0x3C5);
681 bRegTemp
|= 0x40; /* force the preq always higher than treq */
682 VGAOUT8(0x3C5, bRegTemp
);
686 /*=* R1 Display FIFO depth (384 /8 -1 -> 0xbf) SR17[7:0] (8bits) *=*/
687 VGAOUT8(0x3c4, 0x17);
688 VGAOUT8(0x3c5, 0xbf);
690 /*=* R2 Display fetch datum threshold value (328/4 -> 0x52)
691 SR16[5:0], SR16[7] (7bits) *=*/
692 VGAOUT8(0x3c4, 0x16);
693 bRegTemp
= VGAIN8(0x3c5) & ~0xBF;
694 bRegTemp
|= (0x52 & 0x3F);
695 bRegTemp
|= ((0x52 & 0x40) << 1);
696 VGAOUT8(0x3c5, bRegTemp
);
698 /*=* R3 Switch to the highest agent threshold value (74 -> 0x4a)
699 SR18[5:0], SR18[7] (7bits) *=*/
700 VGAOUT8(0x3c4, 0x18);
701 bRegTemp
= VGAIN8(0x3c5) & ~0xBF;
702 bRegTemp
|= (0x4a & 0x3F);
703 bRegTemp
|= ((0x4a & 0x40) << 1);
704 VGAOUT8(0x3c5, bRegTemp
);
706 /*=* R4 Fetch Number for a scan line (unit: 8 bytes)
707 SR1C[7:0], SR1D[1:0] (10bits) *=*/
708 wRegTemp
= (pBIOSInfo
->offsetWidthByQWord
>> 1) + 4;
709 VGAOUT8(0x3c4, 0x1c);
710 VGAOUT8(0x3c5, (uint8_t)(wRegTemp
& 0xFF));
711 VGAOUT8(0x3c4, 0x1d);
712 bRegTemp
= VGAIN8(0x3c5) & ~0x03;
713 VGAOUT8(0x3c5, bRegTemp
| ((wRegTemp
& 0x300) >> 8));
715 if (ctx
->shared
.virtualWidth
>= 1400 && ctx
->bpp
== 32)
717 /*=* Max. length for a request SR22[4:0] (64/4 -> 0x10) *=*/
718 VGAOUT8(0x3c4, 0x22);
719 bRegTemp
= VGAIN8(0x3c5) & ~0x1F;
720 VGAOUT8(0x3c5, bRegTemp
| 0x10);
724 /*=* Max. length for a request SR22[4:0]
725 (128/4 -> over flow 0x0) *=*/
726 VGAOUT8(0x3c4, 0x22);
727 bRegTemp
= VGAIN8(0x3c5) & ~0x1F;
728 VGAOUT8(0x3c5, bRegTemp
);
732 /*=* R1 Display FIFO depth (96-1 -> 0x5f) SR17[7:0] (8bits) *=*/
733 VGAOUT8(0x3c4, 0x17);
734 VGAOUT8(0x3c5, 0x5f);
736 /*=* R2 Display fetch datum threshold value (32 -> 0x20)
737 SR16[5:0], SR16[7] (7bits) *=*/
738 VGAOUT8(0x3c4, 0x16);
739 bRegTemp
= VGAIN8(0x3c5) & ~0xBF;
740 bRegTemp
|= (0x20 & 0x3F);
741 bRegTemp
|= ((0x20 & 0x40) << 1);
742 VGAOUT8(0x3c5, bRegTemp
);
744 /*=* R3 Switch to the highest agent threshold value (16 -> 0x10)
745 SR18[5:0], SR18[7] (7bits) *=*/
746 VGAOUT8(0x3c4, 0x18);
747 bRegTemp
= VGAIN8(0x3c5) & ~0xBF;
748 bRegTemp
|= (0x10 & 0x3F);
749 bRegTemp
|= ((0x10 & 0x40) << 1);
750 VGAOUT8(0x3c5, bRegTemp
);
752 /*=* R4 Fetch Number for a scan line (unit: 8 bytes)
753 SR1C[7:0], SR1D[1:0] (10bits) *=*/
754 wRegTemp
= (pBIOSInfo
->offsetWidthByQWord
>> 1) + 4;
755 VGAOUT8(0x3c4, 0x1c);
756 VGAOUT8(0x3c5, (uint8_t)(wRegTemp
& 0xFF));
757 VGAOUT8(0x3c4, 0x1d);
758 bRegTemp
= VGAIN8(0x3c5) & ~0x03;
759 VGAOUT8(0x3c5, bRegTemp
| ((wRegTemp
& 0x300) >> 8));
761 if (ctx
->shared
.virtualWidth
>= 1400 && ctx
->bpp
== 32)
763 /*=* Max. length for a request SR22[4:0] (64/4 -> 0x10) *=*/
764 VGAOUT8(0x3c4, 0x22);
765 bRegTemp
= VGAIN8(0x3c5) & ~0x1F;
766 VGAOUT8(0x3c5, bRegTemp
| 0x10);
770 /*=* Max. length for a request SR22[4:0] (0x1F) *=*/
771 VGAOUT8(0x3c4, 0x22);
772 bRegTemp
= VGAIN8(0x3c5) & ~0x1F;
773 VGAOUT8(0x3c5, bRegTemp
| 0x1F);
781 static void VIAInitialize2DEngine(DRIDriverContext
*ctx
)
783 VIAPtr pVia
= VIAPTR(ctx
);
784 uint32_t dwVQStartAddr
, dwVQEndAddr
;
785 uint32_t dwVQLen
, dwVQStartL
, dwVQEndL
, dwVQStartEndH
;
788 /* init 2D engine regs to reset 2D engine */
789 VIASETREG(0x04, 0x0);
790 VIASETREG(0x08, 0x0);
791 VIASETREG(0x0c, 0x0);
792 VIASETREG(0x10, 0x0);
793 VIASETREG(0x14, 0x0);
794 VIASETREG(0x18, 0x0);
795 VIASETREG(0x1c, 0x0);
796 VIASETREG(0x20, 0x0);
797 VIASETREG(0x24, 0x0);
798 VIASETREG(0x28, 0x0);
799 VIASETREG(0x2c, 0x0);
800 VIASETREG(0x30, 0x0);
801 VIASETREG(0x34, 0x0);
802 VIASETREG(0x38, 0x0);
803 VIASETREG(0x3c, 0x0);
804 VIASETREG(0x40, 0x0);
808 /* Init AGP and VQ regs */
809 VIASETREG(0x43c, 0x00100000);
810 VIASETREG(0x440, 0x00000000);
811 VIASETREG(0x440, 0x00333004);
812 VIASETREG(0x440, 0x60000000);
813 VIASETREG(0x440, 0x61000000);
814 VIASETREG(0x440, 0x62000000);
815 VIASETREG(0x440, 0x63000000);
816 VIASETREG(0x440, 0x64000000);
817 VIASETREG(0x440, 0x7D000000);
819 VIASETREG(0x43c, 0xfe020000);
820 VIASETREG(0x440, 0x00000000);
822 if (pVia
->VQStart
!= 0) {
824 dwVQStartAddr
= pVia
->VQStart
;
825 dwVQEndAddr
= pVia
->VQEnd
;
826 dwVQStartL
= 0x50000000 | (dwVQStartAddr
& 0xFFFFFF);
827 dwVQEndL
= 0x51000000 | (dwVQEndAddr
& 0xFFFFFF);
828 dwVQStartEndH
= 0x52000000 | ((dwVQStartAddr
& 0xFF000000) >> 24) |
829 ((dwVQEndAddr
& 0xFF000000) >> 16);
830 dwVQLen
= 0x53000000 | (VIA_VQ_SIZE
>> 3);
832 VIASETREG(0x43c, 0x00fe0000);
833 VIASETREG(0x440, 0x080003fe);
834 VIASETREG(0x440, 0x0a00027c);
835 VIASETREG(0x440, 0x0b000260);
836 VIASETREG(0x440, 0x0c000274);
837 VIASETREG(0x440, 0x0d000264);
838 VIASETREG(0x440, 0x0e000000);
839 VIASETREG(0x440, 0x0f000020);
840 VIASETREG(0x440, 0x1000027e);
841 VIASETREG(0x440, 0x110002fe);
842 VIASETREG(0x440, 0x200f0060);
844 VIASETREG(0x440, 0x00000006);
845 VIASETREG(0x440, 0x40008c0f);
846 VIASETREG(0x440, 0x44000000);
847 VIASETREG(0x440, 0x45080c04);
848 VIASETREG(0x440, 0x46800408);
850 VIASETREG(0x440, dwVQStartEndH
);
851 VIASETREG(0x440, dwVQStartL
);
852 VIASETREG(0x440, dwVQEndL
);
853 VIASETREG(0x440, dwVQLen
);
857 VIASETREG(0x43c, 0x00fe0000);
858 VIASETREG(0x440, 0x00000004);
859 VIASETREG(0x440, 0x40008c0f);
860 VIASETREG(0x440, 0x44000000);
861 VIASETREG(0x440, 0x45080c04);
862 VIASETREG(0x440, 0x46800408);
869 dwGEMode
|= VIA_GEM_16bpp
;
872 dwGEMode
|= VIA_GEM_32bpp
;
874 dwGEMode
|= VIA_GEM_8bpp
;
879 switch (ctx
->shared
.virtualWidth
) {
881 dwGEMode
|= VIA_GEM_800
;
884 dwGEMode
|= VIA_GEM_1024
;
887 dwGEMode
|= VIA_GEM_1280
;
890 dwGEMode
|= VIA_GEM_1600
;
893 dwGEMode
|= VIA_GEM_2048
;
896 dwGEMode
|= VIA_GEM_640
;
903 /* Set BPP and Pitch */
904 VIASETREG(VIA_REG_GEMODE
, dwGEMode
);
906 /* Set Src and Dst base address and pitch, pitch is qword */
907 VIASETREG(VIA_REG_SRCBASE
, 0x0);
908 VIASETREG(VIA_REG_DSTBASE
, 0x0);
909 VIASETREG(VIA_REG_PITCH
, VIA_PITCH_ENABLE
|
910 ((ctx
->shared
.virtualWidth
* ctx
->bpp
>> 3) >> 3) |
911 (((ctx
->shared
.virtualWidth
* ctx
->bpp
>> 3) >> 3) << 16));
914 static int b3DRegsInitialized
= 0;
916 static void VIAInitialize3DEngine(DRIDriverContext
*ctx
)
918 VIAPtr pVia
= VIAPTR(ctx
);
921 if (!b3DRegsInitialized
)
924 VIASETREG(0x43C, 0x00010000);
926 for (i
= 0; i
<= 0x7D; i
++)
928 VIASETREG(0x440, (uint32_t) i
<< 24);
931 VIASETREG(0x43C, 0x00020000);
933 for (i
= 0; i
<= 0x94; i
++)
935 VIASETREG(0x440, (uint32_t) i
<< 24);
938 VIASETREG(0x440, 0x82400000);
940 VIASETREG(0x43C, 0x01020000);
943 for (i
= 0; i
<= 0x94; i
++)
945 VIASETREG(0x440, (uint32_t) i
<< 24);
948 VIASETREG(0x440, 0x82400000);
949 VIASETREG(0x43C, 0xfe020000);
951 for (i
= 0; i
<= 0x03; i
++)
953 VIASETREG(0x440, (uint32_t) i
<< 24);
956 VIASETREG(0x43C, 0x00030000);
958 for (i
= 0; i
<= 0xff; i
++)
962 VIASETREG(0x43C, 0x00100000);
963 VIASETREG(0x440, 0x00333004);
964 VIASETREG(0x440, 0x10000002);
965 VIASETREG(0x440, 0x60000000);
966 VIASETREG(0x440, 0x61000000);
967 VIASETREG(0x440, 0x62000000);
968 VIASETREG(0x440, 0x63000000);
969 VIASETREG(0x440, 0x64000000);
971 VIASETREG(0x43C, 0x00fe0000);
973 if (pVia
->ChipRev
>= 3 )
974 VIASETREG(0x440,0x40008c0f);
976 VIASETREG(0x440,0x4000800f);
978 VIASETREG(0x440,0x44000000);
979 VIASETREG(0x440,0x45080C04);
980 VIASETREG(0x440,0x46800408);
981 VIASETREG(0x440,0x50000000);
982 VIASETREG(0x440,0x51000000);
983 VIASETREG(0x440,0x52000000);
984 VIASETREG(0x440,0x53000000);
986 b3DRegsInitialized
= 1;
987 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
,
988 "3D Engine has been initialized.\n");
991 VIASETREG(0x43C,0x00fe0000);
992 VIASETREG(0x440,0x08000001);
993 VIASETREG(0x440,0x0A000183);
994 VIASETREG(0x440,0x0B00019F);
995 VIASETREG(0x440,0x0C00018B);
996 VIASETREG(0x440,0x0D00019B);
997 VIASETREG(0x440,0x0E000000);
998 VIASETREG(0x440,0x0F000000);
999 VIASETREG(0x440,0x10000000);
1000 VIASETREG(0x440,0x11000000);
1001 VIASETREG(0x440,0x20000000);
1005 WaitIdleCLE266(VIAPtr pVia
)
1011 while (!(VIAGETREG(VIA_REG_STATUS
) & VIA_VR_QUEUE_BUSY
) && (loop
++ < MAXLOOP
))
1014 while ((VIAGETREG(VIA_REG_STATUS
) &
1015 (VIA_CMD_RGTR_BUSY
| VIA_2D_ENG_BUSY
| VIA_3D_ENG_BUSY
)) &&
1019 return loop
>= MAXLOOP
;
1022 static int viaInitFBDev(DRIDriverContext
*ctx
)
1024 VIAPtr pVia
= CALLOC(sizeof(*pVia
));
1026 ctx
->driverPrivate
= (void *)pVia
;
1028 switch (ctx
->chipset
) {
1029 case PCI_CHIP_CLE3122
:
1030 case PCI_CHIP_CLE3022
:
1031 pVia
->Chipset
= VIA_CLE266
;
1033 case PCI_CHIP_VT7205
:
1034 case PCI_CHIP_VT3205
:
1035 pVia
->Chipset
= VIA_KM400
;
1037 case PCI_CHIP_VT3204
:
1038 pVia
->Chipset
= VIA_K8M800
;
1040 case PCI_CHIP_VT3259
:
1041 pVia
->Chipset
= VIA_PM800
;
1044 xf86DrvMsg(0, X_ERROR
, "VIA: Unknown device ID (0x%x)\n", ctx
->chipset
);
1047 /* _SOLO TODO XXX need to read ChipRev too */
1050 pVia
->videoRambytes
= ctx
->shared
.fbSize
;
1051 pVia
->MmioBase
= ctx
->MMIOStart
;
1052 pVia
->FrameBufferBase
= ctx
->FBStart
& 0xfc000000;
1054 pVia
->FBFreeStart
= ctx
->shared
.virtualWidth
* ctx
->cpp
*
1055 ctx
->shared
.virtualHeight
;
1056 pVia
->FBFreeEnd
= pVia
->videoRambytes
;
1058 if (!VIADRIScreenInit(ctx
))
1063 /* Get video memory clock. */
1064 VGAOUT8(0x3D4, 0x3D);
1065 pVia
->MemClk
= (VGAIN8(0x3D5) & 0xF0) >> 4;
1066 xf86DrvMsg(0, X_INFO
, "[dri] MemClk (0x%x)\n", pVia
->MemClk
);
1068 /* 3D rendering has noise if not enabled. */
1069 VIAEnableExtendedFIFO(ctx
);
1071 VIAInitialize2DEngine(ctx
);
1073 /* Must disable MMIO or 3D won't work. */
1074 VIADisableMMIO(ctx
);
1076 VIAInitialize3DEngine(ctx
);
1081 static void viaHaltFBDev(DRIDriverContext
*ctx
)
1083 drmUnmap( ctx
->pSAREA
, ctx
->shared
.SAREASize
);
1084 drmClose(ctx
->drmFD
);
1086 if (ctx
->driverPrivate
) {
1087 free(ctx
->driverPrivate
);
1088 ctx
->driverPrivate
= 0;
1092 static int viaEngineShutdown(const DRIDriverContext
*ctx
)
1097 static int viaEngineRestore(const DRIDriverContext
*ctx
)
1102 const struct DRIDriverRec __driDriver
=
1105 viaPostValidateMode
,