diff options
author | Brian Paul <brian.paul@tungstengraphics.com> | 2004-01-30 23:26:19 +0000 |
---|---|---|
committer | Brian Paul <brian.paul@tungstengraphics.com> | 2004-01-30 23:26:19 +0000 |
commit | f18598cbd2802e61c2cbb1d610630da9b5951169 (patch) | |
tree | 2d59e9eff59e0fe08abfe4d7a1c4977fa35d202e /src/mesa/drivers/dri/unichrome/server/via_dri.c | |
parent | 2726d77b2e0610c45019d0070ba21ee8ff47668d (diff) |
Via Unichrome/cle266 driver (Erdi Chen)
Diffstat (limited to 'src/mesa/drivers/dri/unichrome/server/via_dri.c')
-rw-r--r-- | src/mesa/drivers/dri/unichrome/server/via_dri.c | 876 |
1 files changed, 876 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/unichrome/server/via_dri.c b/src/mesa/drivers/dri/unichrome/server/via_dri.c new file mode 100644 index 0000000000..db661b4056 --- /dev/null +++ b/src/mesa/drivers/dri/unichrome/server/via_dri.c @@ -0,0 +1,876 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/via/via_dri.c,v 1.4 2003/09/24 02:43:30 dawes Exp $ */ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#if 0 +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Priv.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#define _XF86DRI_SERVER_ +#include "GL/glxtokens.h" + +#else + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> + +#include "driver.h" +#include "drm.h" +#endif + +#include "dri_util.h" +#include "sarea.h" + +#include "via_context.h" +#include "via_dri.h" +#include "via_driver.h" +#include "via_common.h" +#include "xf86drm.h" + +static void VIAEnableMMIO(DRIDriverContext * ctx); +static void VIADisableMMIO(DRIDriverContext * ctx); +static void VIADisableExtendedFIFO(DRIDriverContext *ctx); +static void VIAEnableExtendedFIFO(DRIDriverContext *ctx); +static void VIAInitialize2DEngine(DRIDriverContext *ctx); +static void VIAInitialize3DEngine(DRIDriverContext *ctx); + +static int VIADRIScreenInit(DRIDriverContext * ctx); +static void VIADRICloseScreen(DRIDriverContext * ctx); +static int VIADRIFinishScreenInit(DRIDriverContext * ctx); + +/* TODO XXX _SOLO temp macros */ +typedef unsigned char CARD8; +typedef unsigned short CARD16; +#define xf86DrvMsg(a, b, ...) fprintf(stderr, __VA_ARGS__) +#define MMIO_IN8(base, addr) ((*(((volatile CARD8*)base)+(addr)))+0) +#define MMIO_OUT8(base, addr, val) ((*(((volatile CARD8*)base)+(addr)))=((CARD8)val)) +#define MMIO_OUT16(base, addr, val) ((*(volatile CARD16*)(((CARD8*)base)+(addr)))=((CARD16)val)) +#define VGA_MISC_OUT_R 0x3cc +#define VGA_MISC_OUT_W 0x3c2 + +#define VIDEO 0 +#define AGP 1 +#define AGP_PAGE_SIZE 4096 +#define AGP_PAGES 8192 +#define AGP_SIZE (AGP_PAGE_SIZE * AGP_PAGES) +#define AGP_CMDBUF_PAGES 256 +#define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES) + +static char VIAKernelDriverName[] = "via"; +static char VIAClientDriverName[] = "via"; + +static int VIADRIAgpInit(const DRIDriverContext *ctx, VIAPtr pVia); +static int VIADRIPciInit(DRIDriverContext * ctx, VIAPtr pVia); +static int VIADRIFBInit(DRIDriverContext * ctx, VIAPtr pVia); +static int VIADRIKernelInit(DRIDriverContext * ctx, VIAPtr pVia); +static int VIADRIMapInit(DRIDriverContext * ctx, VIAPtr pVia); + +static int VIADRIAgpInit(const DRIDriverContext *ctx, VIAPtr pVia) +{ + unsigned long agp_phys; + unsigned int agpaddr; + VIADRIPtr pVIADRI; + pVIADRI = pVia->devPrivate; + pVia->agpSize = 0; + + if (drmAgpAcquire(pVia->drmFD) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpAcquire failed %d\n", errno); + return FALSE; + } + + if (drmAgpEnable(pVia->drmFD, drmAgpGetMode(pVia->drmFD)&~0x0) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpEnable failed\n"); + return FALSE; + } + + xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] drmAgpEnabled succeeded\n"); + + if (drmAgpAlloc(pVia->drmFD, AGP_SIZE, 0, &agp_phys, &pVia->agpHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] drmAgpAlloc failed\n"); + drmAgpRelease(pVia->drmFD); + return FALSE; + } + + if (drmAgpBind(pVia->drmFD, pVia->agpHandle, 0) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] drmAgpBind failed\n"); + drmAgpFree(pVia->drmFD, pVia->agpHandle); + drmAgpRelease(pVia->drmFD); + + return FALSE; + } + + pVia->agpSize = AGP_SIZE; + pVia->agpAddr = drmAgpBase(pVia->drmFD); + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] agpAddr = 0x%08lx\n",pVia->agpAddr); + + pVIADRI->agp.size = pVia->agpSize; + if (drmAddMap(pVia->drmFD, (drmHandle)0, + pVIADRI->agp.size, DRM_AGP, 0, + &pVIADRI->agp.handle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] Failed to map public agp area\n"); + pVIADRI->agp.size = 0; + return FALSE; + } + /* Map AGP from kernel to Xserver - Not really needed */ + drmMap(pVia->drmFD, pVIADRI->agp.handle,pVIADRI->agp.size, + (drmAddressPtr)&agpaddr); + +#if 0 + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] agpBase = %p\n", pVia->agpBase); + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] agpAddr = 0x%08lx\n", pVia->agpAddr); +#endif + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] agpSize = 0x%08x\n", pVia->agpSize); + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] agp physical addr = 0x%08lx\n", agp_phys); + + { + drm_via_agp_t agp; + agp.offset = 0; + agp.size = AGP_SIZE; + if (drmCommandWrite(pVia->drmFD, DRM_VIA_AGP_INIT, &agp, + sizeof(drm_via_agp_t)) < 0) + return FALSE; + } + + return TRUE; +} + +static int VIADRIFBInit(DRIDriverContext * ctx, VIAPtr pVia) +{ + int FBSize = pVia->FBFreeEnd-pVia->FBFreeStart; + int FBOffset = pVia->FBFreeStart; + VIADRIPtr pVIADRI = pVia->devPrivate; + pVIADRI->fbOffset = FBOffset; + pVIADRI->fbSize = pVia->videoRambytes; + + { + drm_via_fb_t fb; + fb.offset = FBOffset; + fb.size = FBSize; + + if (drmCommandWrite(pVia->drmFD, DRM_VIA_FB_INIT, &fb, + sizeof(drm_via_fb_t)) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] failed to init frame buffer area\n"); + return FALSE; + } else { + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] FBFreeStart= 0x%08x FBFreeEnd= 0x%08x " + "FBSize= 0x%08x\n", + pVia->FBFreeStart, pVia->FBFreeEnd, FBSize); + return TRUE; + } + } +} + +static int VIADRIPciInit(DRIDriverContext * ctx, VIAPtr pVia) +{ + return TRUE; +} + +static int VIADRIScreenInit(DRIDriverContext * ctx) +{ + VIAPtr pVia = VIAPTR(ctx); + VIADRIPtr pVIADRI; + int err; + +#if 0 + ctx->shared.SAREASize = ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); +#else + if (sizeof(XF86DRISAREARec)+sizeof(VIASAREAPriv) > SAREA_MAX) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Data does not fit in SAREA\n"); + return FALSE; + } + ctx->shared.SAREASize = SAREA_MAX; +#endif + + ctx->drmFD = drmOpen(VIAKernelDriverName, NULL); + if (ctx->drmFD < 0) { + fprintf(stderr, "[drm] drmOpen failed\n"); + return 0; + } + pVia->drmFD = ctx->drmFD; + + err = drmSetBusid(ctx->drmFD, ctx->pciBusID); + if (err < 0) { + fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", + ctx->drmFD, ctx->pciBusID, strerror(-err)); + return 0; + } + + err = drmAddMap(ctx->drmFD, 0, ctx->shared.SAREASize, DRM_SHM, + DRM_CONTAINS_LOCK, &ctx->shared.hSAREA); + if (err < 0) { + fprintf(stderr, "[drm] drmAddMap failed\n"); + return 0; + } + fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n", + ctx->shared.SAREASize, ctx->shared.hSAREA); + + if (drmMap(ctx->drmFD, + ctx->shared.hSAREA, + ctx->shared.SAREASize, + (drmAddressPtr)(&ctx->pSAREA)) < 0) + { + fprintf(stderr, "[drm] drmMap failed\n"); + return 0; + } + memset(ctx->pSAREA, 0, ctx->shared.SAREASize); + fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n", + ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); + + /* Need to AddMap the framebuffer and mmio regions here: + */ + if (drmAddMap(ctx->drmFD, + (drmHandle)ctx->FBStart, + ctx->FBSize, + DRM_FRAME_BUFFER, +#ifndef _EMBEDDED + 0, +#else + DRM_READ_ONLY, +#endif + &ctx->shared.hFrameBuffer) < 0) + { + fprintf(stderr, "[drm] drmAddMap framebuffer failed\n"); + return 0; + } + + fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n", + ctx->shared.hFrameBuffer); + + pVIADRI = (VIADRIPtr) calloc(1, sizeof(VIADRIRec)); + if (!pVIADRI) { + drmClose(ctx->drmFD); + return FALSE; + } + pVia->devPrivate = pVIADRI; + ctx->driverClientMsg = pVIADRI; + ctx->driverClientMsgSize = sizeof(*pVIADRI); + + pVia->IsPCI = !VIADRIAgpInit(ctx, pVia); + + if (pVia->IsPCI) { + VIADRIPciInit(ctx, pVia); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] use pci.\n" ); + } + else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] use agp.\n" ); + + if (!(VIADRIFBInit(ctx, pVia))) { + VIADRICloseScreen(ctx); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[dri] frame buffer initialize fial .\n" ); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] frame buffer initialized.\n" ); + + /* DRIScreenInit doesn't add all the common mappings. Add additional mappings here. */ + if (!VIADRIMapInit(ctx, pVia)) { + VIADRICloseScreen(ctx); + return FALSE; + } + pVIADRI->regs.size = VIA_MMIO_REGSIZE; + pVIADRI->regs.map = 0; + pVIADRI->regs.handle = pVia->registerHandle; + xf86DrvMsg(ctx->myNum, X_INFO, "[drm] mmio Registers = 0x%08lx\n", + pVIADRI->regs.handle); + + if (drmMap(pVia->drmFD, + pVIADRI->regs.handle, + pVIADRI->regs.size, + (drmAddress *)&pVia->MapBase) != 0) + { + VIADRICloseScreen(ctx); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] mmio mapped.\n" ); + + return VIADRIFinishScreenInit(ctx); +} + +static void +VIADRICloseScreen(DRIDriverContext * ctx) +{ + VIAPtr pVia = VIAPTR(ctx); + VIADRIPtr pVIADRI=(VIADRIPtr)pVia->devPrivate; + + if (pVia->MapBase) { + xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Unmapping MMIO registers\n"); + drmUnmap(pVia->MapBase, pVIADRI->regs.size); + } + + if (pVia->agpSize) { + xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Freeing agp memory\n"); + drmAgpFree(pVia->drmFD, pVia->agpHandle); + xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Releasing agp module\n"); + drmAgpRelease(pVia->drmFD); + } +} + +static int +VIADRIFinishScreenInit(DRIDriverContext * ctx) +{ + VIAPtr pVia = VIAPTR(ctx); + VIADRIPtr pVIADRI; + int err; + + err = drmCreateContext(ctx->drmFD, &ctx->serverContext); + if (err != 0) { + fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); + return FALSE; + } + + DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); + + + if (!VIADRIKernelInit(ctx, pVia)) { + VIADRICloseScreen(ctx); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, "[dri] kernel data initialized.\n"); + + /* set SAREA value */ + { + VIASAREAPriv *saPriv; + + saPriv=(VIASAREAPriv*)(((char*)ctx->pSAREA) + + sizeof(XF86DRISAREARec)); + assert(saPriv); + memset(saPriv, 0, sizeof(*saPriv)); + saPriv->CtxOwner = -1; + } + pVIADRI=(VIADRIPtr)pVia->devPrivate; + pVIADRI->deviceID=pVia->Chipset; + pVIADRI->width=ctx->shared.virtualWidth; + pVIADRI->height=ctx->shared.virtualHeight; + pVIADRI->mem=ctx->shared.fbSize; + pVIADRI->bytesPerPixel= (ctx->bpp+7) / 8; + pVIADRI->sarea_priv_offset = sizeof(XF86DRISAREARec); + /* TODO */ + pVIADRI->scrnX=pVIADRI->width; + pVIADRI->scrnY=pVIADRI->height; + + return TRUE; +} + +/* Initialize the kernel data structures. */ +static int VIADRIKernelInit(DRIDriverContext * ctx, VIAPtr pVia) +{ + drm_via_init_t drmInfo; + memset(&drmInfo, 0, sizeof(drm_via_init_t)); + drmInfo.func = VIA_INIT_MAP; + drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec); + drmInfo.fb_offset = pVia->FrameBufferBase; + drmInfo.mmio_offset = pVia->registerHandle; + if (pVia->IsPCI) + drmInfo.agpAddr = (CARD32)NULL; + else + drmInfo.agpAddr = (CARD32)pVia->agpAddr; + + if ((drmCommandWrite(pVia->drmFD, DRM_VIA_MAP_INIT,&drmInfo, + sizeof(drm_via_init_t))) < 0) + return FALSE; + + return TRUE; +} +/* Add a map for the MMIO registers */ +static int VIADRIMapInit(DRIDriverContext * ctx, VIAPtr pVia) +{ + int flags = 0; + + if (drmAddMap(pVia->drmFD, pVia->MmioBase, VIA_MMIO_REGSIZE, + DRM_REGISTERS, flags, &pVia->registerHandle) < 0) { + return FALSE; + } + + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] register handle = 0x%08lx\n", pVia->registerHandle); + + return TRUE; +} + +const __GLcontextModes __glModes[] = +{ + /* 32 bit, RGBA Depth=24 Stencil=8 */ + {.rgbMode = GL_TRUE, .colorIndexMode = GL_FALSE, .doubleBufferMode = GL_TRUE, .stereoMode = GL_FALSE, + .haveAccumBuffer = GL_FALSE, .haveDepthBuffer = GL_TRUE, .haveStencilBuffer = GL_TRUE, + .redBits = 8, .greenBits = 8, .blueBits = 8, .alphaBits = 8, + .redMask = 0xff0000, .greenMask = 0xff00, .blueMask = 0xff, .alphaMask = 0xff000000, + .rgbBits = 32, .indexBits = 0, + .accumRedBits = 0, .accumGreenBits = 0, .accumBlueBits = 0, .accumAlphaBits = 0, + .depthBits = 16, .stencilBits = 8, + .numAuxBuffers= 0, .level = 0, .pixmapMode = GL_FALSE, }, + + /* 16 bit, RGB Depth=16 */ + {.rgbMode = GL_TRUE, .colorIndexMode = GL_FALSE, .doubleBufferMode = GL_TRUE, .stereoMode = GL_FALSE, + .haveAccumBuffer = GL_FALSE, .haveDepthBuffer = GL_TRUE, .haveStencilBuffer = GL_FALSE, + .redBits = 5, .greenBits = 6, .blueBits = 5, .alphaBits = 0, + .redMask = 0xf800, .greenMask = 0x07e0, .blueMask = 0x001f, .alphaMask = 0x0, + .rgbBits = 16, .indexBits = 0, + .accumRedBits = 0, .accumGreenBits = 0, .accumBlueBits = 0, .accumAlphaBits = 0, + .depthBits = 16, .stencilBits = 0, + .numAuxBuffers= 0, .level = 0, .pixmapMode = GL_FALSE, }, +}; + +static int viaInitContextModes(const DRIDriverContext *ctx, + int *numModes, const __GLcontextModes **modes) +{ + *numModes = sizeof(__glModes)/sizeof(__GLcontextModes *); + *modes = &__glModes[0]; + return 1; +} + +static int viaValidateMode(const DRIDriverContext *ctx) +{ + VIAPtr pVia = VIAPTR(ctx); + + return 1; +} + +static int viaPostValidateMode(const DRIDriverContext *ctx) +{ + VIAPtr pVia = VIAPTR(ctx); + + return 1; +} + +static void VIAEnableMMIO(DRIDriverContext * ctx) +{ + /*vgaHWPtr hwp = VGAHWPTR(ctx);*/ + VIAPtr pVia = VIAPTR(ctx); + unsigned char val; + +#if 0 + if (xf86IsPrimaryPci(pVia->PciInfo)) { + /* If we are primary card, we still use std vga port. If we use + * MMIO, system will hang in vgaHWSave when our card used in + * PLE and KLE (integrated Trident MVP4) + */ + vgaHWSetStdFuncs(hwp); + } + else { + vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000); + } +#endif + + val = VGAIN8(0x3c3); + VGAOUT8(0x3c3, val | 0x01); + val = VGAIN8(VGA_MISC_OUT_R); + VGAOUT8(VGA_MISC_OUT_W, val | 0x01); + + /* Unlock Extended IO Space */ + VGAOUT8(0x3c4, 0x10); + VGAOUT8(0x3c5, 0x01); + + /* Enable MMIO */ + if(!pVia->IsSecondary) { + VGAOUT8(0x3c4, 0x1a); + val = VGAIN8(0x3c5); +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "primary val = %x\n", val); +#endif + VGAOUT8(0x3c5, val | 0x68); + } + else { + VGAOUT8(0x3c4, 0x1a); + val = VGAIN8(0x3c5); +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "secondary val = %x\n", val); +#endif + VGAOUT8(0x3c5, val | 0x38); + } + + return; +} + +static void VIADisableMMIO(DRIDriverContext * ctx) +{ + VIAPtr pVia = VIAPTR(ctx); + unsigned char val; + + VGAOUT8(0x3c4, 0x1a); + val = VGAIN8(0x3c5); + VGAOUT8(0x3c5, val & 0x97); + + return; +} + +static void VIADisableExtendedFIFO(DRIDriverContext *ctx) +{ + VIAPtr pVia = VIAPTR(ctx); + CARD32 dwTemp; + + dwTemp = (CARD32)VIAGETREG(0x298); + dwTemp |= 0x20000000; + VIASETREG(0x298, dwTemp); + + dwTemp = (CARD32)VIAGETREG(0x230); + dwTemp &= ~0x00200000; + VIASETREG(0x230, dwTemp); + + dwTemp = (CARD32)VIAGETREG(0x298); + dwTemp &= ~0x20000000; + VIASETREG(0x298, dwTemp); +} + +static void VIAEnableExtendedFIFO(DRIDriverContext *ctx) +{ + VIAPtr pVia = VIAPTR(ctx); + CARD32 dwTemp; + CARD8 bTemp; + + dwTemp = (CARD32)VIAGETREG(0x298); + dwTemp |= 0x20000000; + VIASETREG(0x298, dwTemp); + + dwTemp = (CARD32)VIAGETREG(0x230); + dwTemp |= 0x00200000; + VIASETREG(0x230, dwTemp); + + dwTemp = (CARD32)VIAGETREG(0x298); + dwTemp &= ~0x20000000; + VIASETREG(0x298, dwTemp); + + VGAOUT8(0x3C4, 0x17); + bTemp = VGAIN8(0x3C5); + bTemp &= ~0x7F; + bTemp |= 0x2F; + VGAOUT8(0x3C5, bTemp); + + VGAOUT8(0x3C4, 0x16); + bTemp = VGAIN8(0x3C5); + bTemp &= ~0x3F; + bTemp |= 0x17; + VGAOUT8(0x3C5, bTemp); + + VGAOUT8(0x3C4, 0x18); + bTemp = VGAIN8(0x3C5); + bTemp &= ~0x3F; + bTemp |= 0x17; + bTemp |= 0x40; /* force the preq always higher than treq */ + VGAOUT8(0x3C5, bTemp); +} + +static void VIAInitialize2DEngine(DRIDriverContext *ctx) +{ + VIAPtr pVia = VIAPTR(ctx); + CARD32 dwVQStartAddr, dwVQEndAddr; + CARD32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH; + CARD32 dwGEMode; + + /* init 2D engine regs to reset 2D engine */ + VIASETREG(0x04, 0x0); + VIASETREG(0x08, 0x0); + VIASETREG(0x0c, 0x0); + VIASETREG(0x10, 0x0); + VIASETREG(0x14, 0x0); + VIASETREG(0x18, 0x0); + VIASETREG(0x1c, 0x0); + VIASETREG(0x20, 0x0); + VIASETREG(0x24, 0x0); + VIASETREG(0x28, 0x0); + VIASETREG(0x2c, 0x0); + VIASETREG(0x30, 0x0); + VIASETREG(0x34, 0x0); + VIASETREG(0x38, 0x0); + VIASETREG(0x3c, 0x0); + VIASETREG(0x40, 0x0); + + /* Init AGP and VQ regs */ + VIASETREG(0x43c, 0x00100000); + VIASETREG(0x440, 0x00000000); + VIASETREG(0x440, 0x00333004); + VIASETREG(0x440, 0x60000000); + VIASETREG(0x440, 0x61000000); + VIASETREG(0x440, 0x62000000); + VIASETREG(0x440, 0x63000000); + VIASETREG(0x440, 0x64000000); + VIASETREG(0x440, 0x7D000000); + + VIASETREG(0x43c, 0xfe020000); + VIASETREG(0x440, 0x00000000); + + if (pVia->VQStart != 0) { + /* Enable VQ */ + dwVQStartAddr = pVia->VQStart; + dwVQEndAddr = pVia->VQEnd; + dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF); + dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF); + dwVQStartEndH = 0x52000000 | ((dwVQStartAddr & 0xFF000000) >> 24) | + ((dwVQEndAddr & 0xFF000000) >> 16); + dwVQLen = 0x53000000 | (VIA_VQ_SIZE >> 3); + + VIASETREG(0x43c, 0x00fe0000); + VIASETREG(0x440, 0x080003fe); + VIASETREG(0x440, 0x0a00027c); + VIASETREG(0x440, 0x0b000260); + VIASETREG(0x440, 0x0c000274); + VIASETREG(0x440, 0x0d000264); + VIASETREG(0x440, 0x0e000000); + VIASETREG(0x440, 0x0f000020); + VIASETREG(0x440, 0x1000027e); + VIASETREG(0x440, 0x110002fe); + VIASETREG(0x440, 0x200f0060); + + VIASETREG(0x440, 0x00000006); + VIASETREG(0x440, 0x40008c0f); + VIASETREG(0x440, 0x44000000); + VIASETREG(0x440, 0x45080c04); + VIASETREG(0x440, 0x46800408); + + VIASETREG(0x440, dwVQStartEndH); + VIASETREG(0x440, dwVQStartL); + VIASETREG(0x440, dwVQEndL); + VIASETREG(0x440, dwVQLen); + } + else { + /* Diable VQ */ + VIASETREG(0x43c, 0x00fe0000); + VIASETREG(0x440, 0x00000004); + VIASETREG(0x440, 0x40008c0f); + VIASETREG(0x440, 0x44000000); + VIASETREG(0x440, 0x45080c04); + VIASETREG(0x440, 0x46800408); + } + + dwGEMode = 0; + + switch (ctx->bpp) { + case 16: + dwGEMode |= VIA_GEM_16bpp; + break; + case 32: + dwGEMode |= VIA_GEM_32bpp; + default: + dwGEMode |= VIA_GEM_8bpp; + break; + } + +#if 0 + switch (ctx->shared.virtualWidth) { + case 800: + dwGEMode |= VIA_GEM_800; + break; + case 1024: + dwGEMode |= VIA_GEM_1024; + break; + case 1280: + dwGEMode |= VIA_GEM_1280; + break; + case 1600: + dwGEMode |= VIA_GEM_1600; + break; + case 2048: + dwGEMode |= VIA_GEM_2048; + break; + default: + dwGEMode |= VIA_GEM_640; + break; + } +#endif + + /* Set BPP and Pitch */ + VIASETREG(VIA_REG_GEMODE, dwGEMode); + + /* Set Src and Dst base address and pitch, pitch is qword */ + VIASETREG(VIA_REG_SRCBASE, 0x0); + VIASETREG(VIA_REG_DSTBASE, 0x0); + VIASETREG(VIA_REG_PITCH, VIA_PITCH_ENABLE | + ((ctx->shared.virtualWidth * ctx->bpp >> 3) >> 3) | + (((ctx->shared.virtualWidth * ctx->bpp >> 3) >> 3) << 16)); +} + +static void VIAInitialize3DEngine(DRIDriverContext *ctx) +{ + VIAPtr pVia = VIAPTR(ctx); + int i; + + if (!pVia->sharedData->b3DRegsInitialized) + { + + VIASETREG(0x43C, 0x00010000); + + for (i = 0; i <= 0x7D; i++) + { + VIASETREG(0x440, (CARD32) i << 24); + } + + VIASETREG(0x43C, 0x00020000); + + for (i = 0; i <= 0x94; i++) + { + VIASETREG(0x440, (CARD32) i << 24); + } + + VIASETREG(0x440, 0x82400000); + + VIASETREG(0x43C, 0x01020000); + + + for (i = 0; i <= 0x94; i++) + { + VIASETREG(0x440, (CARD32) i << 24); + } + + VIASETREG(0x440, 0x82400000); + VIASETREG(0x43C, 0xfe020000); + + for (i = 0; i <= 0x03; i++) + { + VIASETREG(0x440, (CARD32) i << 24); + } + + VIASETREG(0x43C, 0x00030000); + + for (i = 0; i <= 0xff; i++) + { + VIASETREG(0x440, 0); + } + VIASETREG(0x43C, 0x00100000); + VIASETREG(0x440, 0x00333004); + VIASETREG(0x440, 0x10000002); + VIASETREG(0x440, 0x60000000); + VIASETREG(0x440, 0x61000000); + VIASETREG(0x440, 0x62000000); + VIASETREG(0x440, 0x63000000); + VIASETREG(0x440, 0x64000000); + + VIASETREG(0x43C, 0x00fe0000); + + if (pVia->ChipRev >= 3 ) + VIASETREG(0x440,0x40008c0f); + else + VIASETREG(0x440,0x4000800f); + + VIASETREG(0x440,0x44000000); + VIASETREG(0x440,0x45080C04); + VIASETREG(0x440,0x46800408); + VIASETREG(0x440,0x50000000); + VIASETREG(0x440,0x51000000); + VIASETREG(0x440,0x52000000); + VIASETREG(0x440,0x53000000); + + pVia->sharedData->b3DRegsInitialized = 1; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "3D Engine has been initialized.\n"); + } + + VIASETREG(0x43C,0x00fe0000); + VIASETREG(0x440,0x08000001); + VIASETREG(0x440,0x0A000183); + VIASETREG(0x440,0x0B00019F); + VIASETREG(0x440,0x0C00018B); + VIASETREG(0x440,0x0D00019B); + VIASETREG(0x440,0x0E000000); + VIASETREG(0x440,0x0F000000); + VIASETREG(0x440,0x10000000); + VIASETREG(0x440,0x11000000); + VIASETREG(0x440,0x20000000); +} + +static int viaInitFBDev(DRIDriverContext *ctx) +{ + VIAPtr pVia = calloc(1, sizeof(*pVia)); + + ctx->driverPrivate = (void *)pVia; + + pVia->Chipset = ctx->chipset; + + pVia->videoRambytes = ctx->shared.fbSize; + pVia->MmioBase = ctx->MMIOStart; + pVia->FrameBufferBase = ctx->FBStart & 0xfc000000; + + pVia->FBFreeStart = ctx->shared.virtualWidth * ctx->cpp * + ctx->shared.virtualHeight; + pVia->FBFreeEnd = pVia->videoRambytes; + + pVia->sharedData = (ViaSharedPtr) calloc(1, sizeof(ViaSharedRec)); + + if (!VIADRIScreenInit(ctx)) + return 0; + + VIAEnableMMIO(ctx); + + /* 3D rendering has noise if not enabled. */ + VIAEnableExtendedFIFO(ctx); + + VIAInitialize2DEngine(ctx); + VIAInitialize3DEngine(ctx); + + /* Must disable MMIO or 3D won't work. */ + VIADisableMMIO(ctx); + + return 1; +} + +static void viaHaltFBDev(DRIDriverContext *ctx) +{ + drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); + drmClose(ctx->drmFD); + + if (ctx->driverPrivate) { + free(ctx->driverPrivate); + ctx->driverPrivate = 0; + } +} + +static int viaEngineShutdown(const DRIDriverContext *ctx) +{ + return 1; +} + +static int viaEngineRestore(const DRIDriverContext *ctx) +{ + return 1; +} + +const struct DRIDriverRec __driDriver = +{ + viaInitContextModes, + viaValidateMode, + viaPostValidateMode, + viaInitFBDev, + viaHaltFBDev, + viaEngineShutdown, + viaEngineRestore, + 0, +}; + |