via_ums.c revision 4dc64ea9
190b17f1bSmrg/*
2963d66acSmrg * Copyright 2011-2015 The Openchrome Project
3963d66acSmrg *                     [http://www.freedesktop.org/wiki/Openchrome]
490b17f1bSmrg *
590b17f1bSmrg * Permission is hereby granted, free of charge, to any person obtaining a
690b17f1bSmrg * copy of this software and associated documentation files (the "Software"),
790b17f1bSmrg * to deal in the Software without restriction, including without limitation
890b17f1bSmrg * the rights to use, copy, modify, merge, publish, distribute, sub license,
990b17f1bSmrg * and/or sell copies of the Software, and to permit persons to whom the
1090b17f1bSmrg * Software is furnished to do so, subject to the following conditions:
1190b17f1bSmrg *
1290b17f1bSmrg * The above copyright notice and this permission notice (including the
1390b17f1bSmrg * next paragraph) shall be included in all copies or substantial portions
1490b17f1bSmrg * of the Software.
1590b17f1bSmrg *
1690b17f1bSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1790b17f1bSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1890b17f1bSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
1990b17f1bSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2090b17f1bSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2190b17f1bSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2290b17f1bSmrg * DEALINGS IN THE SOFTWARE.
2390b17f1bSmrg */
2490b17f1bSmrg
2590b17f1bSmrg#ifdef HAVE_CONFIG_H
2690b17f1bSmrg#include "config.h"
2790b17f1bSmrg#endif
2890b17f1bSmrg
2990b17f1bSmrg#include "globals.h"
3090b17f1bSmrg#include "via_driver.h"
314dc64ea9Smrg#include "xf86fbman.h"
3290b17f1bSmrg
3390b17f1bSmrgstatic void
3490b17f1bSmrgViaMMIODisable(ScrnInfoPtr pScrn)
3590b17f1bSmrg{
3690b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
3790b17f1bSmrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
3890b17f1bSmrg
3990b17f1bSmrg    switch (pVia->Chipset) {
4090b17f1bSmrg        case VIA_CX700:
41963d66acSmrg        case VIA_K8M890:
4290b17f1bSmrg        case VIA_P4M900:
4390b17f1bSmrg        case VIA_VX800:
4490b17f1bSmrg        case VIA_VX855:
4590b17f1bSmrg        case VIA_VX900:
4690b17f1bSmrg            ViaSeqMask(hwp, 0x1A, 0x00, 0x08);
4790b17f1bSmrg            break;
4890b17f1bSmrg        default:
4990b17f1bSmrg            ViaSeqMask(hwp, 0x1A, 0x00, 0x60);
5090b17f1bSmrg            break;
5190b17f1bSmrg    }
5290b17f1bSmrg}
5390b17f1bSmrg
5490b17f1bSmrgvoid
55963d66acSmrgVIAUnmapMMIO(ScrnInfoPtr pScrn)
5690b17f1bSmrg{
5790b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
5890b17f1bSmrg
59963d66acSmrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
60963d66acSmrg                        "Entered VIAUnmapMMIO.\n"));
6190b17f1bSmrg
6290b17f1bSmrg    ViaMMIODisable(pScrn);
6390b17f1bSmrg
6490b17f1bSmrg#ifdef HAVE_PCIACCESS
6590b17f1bSmrg    if (pVia->MapBase)
6690b17f1bSmrg        pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->MapBase,
6790b17f1bSmrg                               VIA_MMIO_REGSIZE);
6890b17f1bSmrg
6990b17f1bSmrg    if (pVia->BltBase)
7090b17f1bSmrg        pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->BltBase,
7190b17f1bSmrg                               VIA_MMIO_BLTSIZE);
7290b17f1bSmrg
7390b17f1bSmrg    if (pVia->FBBase)
7490b17f1bSmrg        pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->FBBase,
7590b17f1bSmrg                               pVia->videoRambytes);
7690b17f1bSmrg#else
7790b17f1bSmrg    if (pVia->MapBase)
7890b17f1bSmrg        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->MapBase,
7990b17f1bSmrg                        VIA_MMIO_REGSIZE);
8090b17f1bSmrg
8190b17f1bSmrg    if (pVia->BltBase)
8290b17f1bSmrg        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->BltBase,
8390b17f1bSmrg                        VIA_MMIO_BLTSIZE);
8490b17f1bSmrg
8590b17f1bSmrg    if (pVia->FBBase)
8690b17f1bSmrg        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->FBBase,
8790b17f1bSmrg                        pVia->videoRambytes);
8890b17f1bSmrg#endif
89963d66acSmrg
90963d66acSmrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
91963d66acSmrg                        "Exiting VIAUnmapMMIO.\n"));
9290b17f1bSmrg}
9390b17f1bSmrg
9490b17f1bSmrgstatic void
9590b17f1bSmrgViaMMIOEnable(ScrnInfoPtr pScrn)
9690b17f1bSmrg{
9790b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
9890b17f1bSmrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
9990b17f1bSmrg
10090b17f1bSmrg    switch (pVia->Chipset) {
10190b17f1bSmrg        case VIA_CX700:
102963d66acSmrg        case VIA_K8M890:
10390b17f1bSmrg        case VIA_P4M900:
10490b17f1bSmrg        case VIA_VX800:
10590b17f1bSmrg        case VIA_VX855:
10690b17f1bSmrg        case VIA_VX900:
10790b17f1bSmrg            ViaSeqMask(hwp, 0x1A, 0x08, 0x08);
10890b17f1bSmrg            break;
10990b17f1bSmrg        default:
11090b17f1bSmrg            if (pVia->IsSecondary)
11190b17f1bSmrg                ViaSeqMask(hwp, 0x1A, 0x38, 0x38);
11290b17f1bSmrg            else
11390b17f1bSmrg                ViaSeqMask(hwp, 0x1A, 0x68, 0x68);
11490b17f1bSmrg            break;
11590b17f1bSmrg    }
11690b17f1bSmrg}
11790b17f1bSmrg
11890b17f1bSmrgstatic Bool
11990b17f1bSmrgVIAMapMMIO(ScrnInfoPtr pScrn)
12090b17f1bSmrg{
12190b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
12290b17f1bSmrg
12390b17f1bSmrg#ifdef HAVE_PCIACCESS
12490b17f1bSmrg    pVia->MmioBase = pVia->PciInfo->regions[1].base_addr;
12590b17f1bSmrg    int err;
12690b17f1bSmrg#else
12790b17f1bSmrg    pVia->MmioBase = pVia->PciInfo->memBase[1];
12890b17f1bSmrg#endif
12990b17f1bSmrg
13090b17f1bSmrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAMapMMIO\n"));
13190b17f1bSmrg
13290b17f1bSmrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
13390b17f1bSmrg               "mapping MMIO @ 0x%lx with size 0x%x\n",
13490b17f1bSmrg               pVia->MmioBase, VIA_MMIO_REGSIZE);
13590b17f1bSmrg
13690b17f1bSmrg#ifdef HAVE_PCIACCESS
13790b17f1bSmrg    err = pci_device_map_range(pVia->PciInfo,
13890b17f1bSmrg                               pVia->MmioBase,
13990b17f1bSmrg                               VIA_MMIO_REGSIZE,
14090b17f1bSmrg                               PCI_DEV_MAP_FLAG_WRITABLE,
14190b17f1bSmrg                               (void **)&pVia->MapBase);
14290b17f1bSmrg
14390b17f1bSmrg    if (err) {
14490b17f1bSmrg        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
14590b17f1bSmrg                   "Unable to map mmio BAR. %s (%d)\n", strerror(err), err);
14690b17f1bSmrg        return FALSE;
14790b17f1bSmrg    }
14890b17f1bSmrg#else
14990b17f1bSmrg    pVia->MapBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag,
15090b17f1bSmrg                                  pVia->MmioBase, VIA_MMIO_REGSIZE);
15190b17f1bSmrg    if (!pVia->MapBase)
15290b17f1bSmrg        return FALSE;
15390b17f1bSmrg#endif
15490b17f1bSmrg
15590b17f1bSmrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
15690b17f1bSmrg               "mapping BitBlt MMIO @ 0x%lx with size 0x%x\n",
15790b17f1bSmrg               pVia->MmioBase + VIA_MMIO_BLTBASE, VIA_MMIO_BLTSIZE);
15890b17f1bSmrg
15990b17f1bSmrg#ifdef HAVE_PCIACCESS
16090b17f1bSmrg    err = pci_device_map_range(pVia->PciInfo,
16190b17f1bSmrg                               pVia->MmioBase + VIA_MMIO_BLTBASE,
16290b17f1bSmrg                               VIA_MMIO_BLTSIZE,
16390b17f1bSmrg                               PCI_DEV_MAP_FLAG_WRITABLE,
16490b17f1bSmrg                               (void **)&pVia->BltBase);
16590b17f1bSmrg
16690b17f1bSmrg    if (err) {
16790b17f1bSmrg        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
16890b17f1bSmrg                   "Unable to map blt BAR. %s (%d)\n", strerror(err), err);
16990b17f1bSmrg        return FALSE;
17090b17f1bSmrg    }
17190b17f1bSmrg#else
17290b17f1bSmrg    pVia->BltBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag,
17390b17f1bSmrg                                  pVia->MmioBase + VIA_MMIO_BLTBASE,
17490b17f1bSmrg                                  VIA_MMIO_BLTSIZE);
17590b17f1bSmrg    if (!pVia->BltBase)
17690b17f1bSmrg        return FALSE;
17790b17f1bSmrg#endif
17890b17f1bSmrg
17990b17f1bSmrg    if (!pVia->MapBase || !pVia->BltBase) {
18090b17f1bSmrg        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
18190b17f1bSmrg                   "BitBlit could not be mapped.\n");
18290b17f1bSmrg        return FALSE;
18390b17f1bSmrg    }
18490b17f1bSmrg
18590b17f1bSmrg    /* Memory mapped IO for mpeg engine. */
18690b17f1bSmrg    pVia->MpegMapBase = pVia->MapBase + 0xc00;
18790b17f1bSmrg
18890b17f1bSmrg    /* Set up MMIO vgaHW. */
18990b17f1bSmrg    {
19090b17f1bSmrg        vgaHWPtr hwp = VGAHWPTR(pScrn);
19190b17f1bSmrg        CARD8 val;
19290b17f1bSmrg
19390b17f1bSmrg        vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000);
19490b17f1bSmrg
19590b17f1bSmrg        val = hwp->readEnable(hwp);
19690b17f1bSmrg        hwp->writeEnable(hwp, val | 0x01);
19790b17f1bSmrg
19890b17f1bSmrg        val = hwp->readMiscOut(hwp);
19990b17f1bSmrg        hwp->writeMiscOut(hwp, val | 0x01);
20090b17f1bSmrg
20190b17f1bSmrg        /* Unlock extended IO space. */
20290b17f1bSmrg        ViaSeqMask(hwp, 0x10, 0x01, 0x01);
20390b17f1bSmrg
20490b17f1bSmrg        ViaMMIOEnable(pScrn);
20590b17f1bSmrg
20690b17f1bSmrg        vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000);
20790b17f1bSmrg
20890b17f1bSmrg        /* Unlock CRTC. */
20990b17f1bSmrg        ViaCrtcMask(hwp, 0x47, 0x00, 0x01);
21090b17f1bSmrg
21190b17f1bSmrg        vgaHWGetIOBase(hwp);
21290b17f1bSmrg    }
21390b17f1bSmrg    return TRUE;
21490b17f1bSmrg}
21590b17f1bSmrg
21690b17f1bSmrgstatic Bool
21790b17f1bSmrgVIAMapFB(ScrnInfoPtr pScrn)
21890b17f1bSmrg{
21990b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
22090b17f1bSmrg
22190b17f1bSmrg#ifdef HAVE_PCIACCESS
22290b17f1bSmrg    if (pVia->Chipset == VIA_VX900) {
22390b17f1bSmrg        pVia->FrameBufferBase = pVia->PciInfo->regions[2].base_addr;
22490b17f1bSmrg    } else {
22590b17f1bSmrg        pVia->FrameBufferBase = pVia->PciInfo->regions[0].base_addr;
22690b17f1bSmrg    }
22790b17f1bSmrg    int err;
22890b17f1bSmrg#else
22990b17f1bSmrg    if (pVia->Chipset == VIA_VX900) {
23090b17f1bSmrg        pVia->FrameBufferBase = pVia->PciInfo->memBase[2];
23190b17f1bSmrg    } else {
23290b17f1bSmrg        pVia->FrameBufferBase = pVia->PciInfo->memBase[0];
23390b17f1bSmrg    }
23490b17f1bSmrg#endif
23590b17f1bSmrg
23690b17f1bSmrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAMapFB\n"));
23790b17f1bSmrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
23890b17f1bSmrg               "mapping framebuffer @ 0x%lx with size 0x%lx\n",
23990b17f1bSmrg               pVia->FrameBufferBase, pVia->videoRambytes);
24090b17f1bSmrg
24190b17f1bSmrg    if (pVia->videoRambytes) {
24290b17f1bSmrg
24390b17f1bSmrg#ifndef HAVE_PCIACCESS
24490b17f1bSmrg        /*
24590b17f1bSmrg         * FIXME: This is a hack to get rid of offending wrongly sized
24690b17f1bSmrg         * MTRR regions set up by the VIA BIOS. Should be taken care of
24790b17f1bSmrg         * in the OS support layer.
24890b17f1bSmrg         */
24990b17f1bSmrg        unsigned char *tmp;
25090b17f1bSmrg
25190b17f1bSmrg        tmp = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag,
25290b17f1bSmrg                            pVia->FrameBufferBase, pVia->videoRambytes);
25390b17f1bSmrg        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) tmp, pVia->videoRambytes);
25490b17f1bSmrg
25590b17f1bSmrg        /*
25690b17f1bSmrg         * And, as if this wasn't enough, 2.6 series kernels don't
25790b17f1bSmrg         * remove MTRR regions on the first attempt. So try again.
25890b17f1bSmrg         */
25990b17f1bSmrg
26090b17f1bSmrg        tmp = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag,
26190b17f1bSmrg                            pVia->FrameBufferBase, pVia->videoRambytes);
26290b17f1bSmrg        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) tmp, pVia->videoRambytes);
26390b17f1bSmrg
26490b17f1bSmrg        /*
26590b17f1bSmrg         * End of hack.
26690b17f1bSmrg         */
26790b17f1bSmrg#endif
26890b17f1bSmrg
26990b17f1bSmrg#ifdef HAVE_PCIACCESS
27090b17f1bSmrg        err = pci_device_map_range(pVia->PciInfo, pVia->FrameBufferBase,
27190b17f1bSmrg                                   pVia->videoRambytes,
27290b17f1bSmrg                                   (PCI_DEV_MAP_FLAG_WRITABLE |
27390b17f1bSmrg                                    PCI_DEV_MAP_FLAG_WRITE_COMBINE),
27490b17f1bSmrg                                   (void **)&pVia->FBBase);
27590b17f1bSmrg        if (err) {
27690b17f1bSmrg            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
27790b17f1bSmrg                       "Unable to map mmio BAR. %s (%d)\n", strerror(err), err);
27890b17f1bSmrg            return FALSE;
27990b17f1bSmrg        }
28090b17f1bSmrg#else
28190b17f1bSmrg        pVia->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
28290b17f1bSmrg                                     pVia->PciTag, pVia->FrameBufferBase,
28390b17f1bSmrg                                     pVia->videoRambytes);
28490b17f1bSmrg
28590b17f1bSmrg        if (!pVia->FBBase) {
28690b17f1bSmrg            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
28790b17f1bSmrg                       "Internal error: could not map framebuffer\n");
28890b17f1bSmrg            return FALSE;
28990b17f1bSmrg        }
29090b17f1bSmrg#endif
29190b17f1bSmrg
29290b17f1bSmrg        pVia->FBFreeStart = 0;
29390b17f1bSmrg        pVia->FBFreeEnd = pVia->videoRambytes;
29490b17f1bSmrg
29590b17f1bSmrg        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
29690b17f1bSmrg                   "Frame buffer start: %p, free start: 0x%x end: 0x%x\n",
29790b17f1bSmrg                   pVia->FBBase, pVia->FBFreeStart, pVia->FBFreeEnd);
29890b17f1bSmrg    }
29990b17f1bSmrg
30090b17f1bSmrg#ifdef HAVE_PCIACCESS
30190b17f1bSmrg    pScrn->memPhysBase = pVia->PciInfo->regions[0].base_addr;
30290b17f1bSmrg#else
30390b17f1bSmrg    pScrn->memPhysBase = pVia->PciInfo->memBase[0];
30490b17f1bSmrg#endif
30590b17f1bSmrg    pScrn->fbOffset = 0;
30690b17f1bSmrg    if (pVia->IsSecondary)
30790b17f1bSmrg        pScrn->fbOffset = pScrn->videoRam << 10;
30890b17f1bSmrg
30990b17f1bSmrg    return TRUE;
31090b17f1bSmrg}
31190b17f1bSmrg
31290b17f1bSmrg/*
31390b17f1bSmrg * Leftover from VIA's code.
31490b17f1bSmrg */
31590b17f1bSmrgstatic void
31690b17f1bSmrgviaInitPCIe(VIAPtr pVia)
31790b17f1bSmrg{
31890b17f1bSmrg    VIASETREG(0x41c, 0x00100000);
31990b17f1bSmrg    VIASETREG(0x420, 0x680A0000);
32090b17f1bSmrg    VIASETREG(0x420, 0x02000000);
32190b17f1bSmrg}
32290b17f1bSmrg
32390b17f1bSmrgstatic void
32490b17f1bSmrgviaInitAgp(VIAPtr pVia)
32590b17f1bSmrg{
32690b17f1bSmrg    VIASETREG(VIA_REG_TRANSET, 0x00100000);
32790b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x00000000);
32890b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x00333004);
32990b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x60000000);
33090b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x61000000);
33190b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x62000000);
33290b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x63000000);
33390b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x64000000);
33490b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x7D000000);
33590b17f1bSmrg
33690b17f1bSmrg    VIASETREG(VIA_REG_TRANSET, 0xfe020000);
33790b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x00000000);
33890b17f1bSmrg}
33990b17f1bSmrg
34090b17f1bSmrg/*
34190b17f1bSmrg * Initialize the virtual command queue. Header-2 commands can be put
34290b17f1bSmrg * in this queue for buffering. AFAIK it doesn't handle Header-1
34390b17f1bSmrg * commands, which is really a pity, since it has to be idled before
34490b17f1bSmrg * issuing a Header-1 command.
34590b17f1bSmrg */
34690b17f1bSmrgstatic void
34790b17f1bSmrgviaEnableAgpVQ(VIAPtr pVia)
34890b17f1bSmrg{
34990b17f1bSmrg   CARD32
35090b17f1bSmrg       vqStartAddr = pVia->VQStart,
35190b17f1bSmrg       vqEndAddr = pVia->VQEnd,
35290b17f1bSmrg       vqStartL = 0x50000000 | (vqStartAddr & 0xFFFFFF),
35390b17f1bSmrg       vqEndL = 0x51000000 | (vqEndAddr & 0xFFFFFF),
35490b17f1bSmrg       vqStartEndH = 0x52000000 | ((vqStartAddr & 0xFF000000) >> 24) |
35590b17f1bSmrg       ((vqEndAddr & 0xFF000000) >> 16),
35690b17f1bSmrg       vqLen = 0x53000000 | (VIA_VQ_SIZE >> 3);
35790b17f1bSmrg
35890b17f1bSmrg    VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
35990b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x080003fe);
36090b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x0a00027c);
36190b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x0b000260);
36290b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x0c000274);
36390b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x0d000264);
36490b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x0e000000);
36590b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x0f000020);
36690b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x1000027e);
36790b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x110002fe);
36890b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x200f0060);
36990b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x00000006);
37090b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f);
37190b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x44000000);
37290b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x45080c04);
37390b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x46800408);
37490b17f1bSmrg
37590b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, vqStartEndH);
37690b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, vqStartL);
37790b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, vqEndL);
37890b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, vqLen);
37990b17f1bSmrg}
38090b17f1bSmrg
38190b17f1bSmrgstatic void
38290b17f1bSmrgviaEnablePCIeVQ(VIAPtr pVia)
38390b17f1bSmrg{
38490b17f1bSmrg   CARD32
38590b17f1bSmrg       vqStartAddr = pVia->VQStart,
38690b17f1bSmrg       vqEndAddr = pVia->VQEnd,
38790b17f1bSmrg       vqStartL = 0x70000000 | (vqStartAddr & 0xFFFFFF),
38890b17f1bSmrg       vqEndL = 0x71000000 | (vqEndAddr & 0xFFFFFF),
38990b17f1bSmrg       vqStartEndH = 0x72000000 | ((vqStartAddr & 0xFF000000) >> 24) |
39090b17f1bSmrg       ((vqEndAddr & 0xFF000000) >> 16),
39190b17f1bSmrg       vqLen = 0x73000000 | (VIA_VQ_SIZE >> 3);
39290b17f1bSmrg
39390b17f1bSmrg    VIASETREG(0x41c, 0x00100000);
39490b17f1bSmrg    VIASETREG(0x420, vqStartEndH);
39590b17f1bSmrg    VIASETREG(0x420, vqStartL);
39690b17f1bSmrg    VIASETREG(0x420, vqEndL);
39790b17f1bSmrg    VIASETREG(0x420, vqLen);
39890b17f1bSmrg    VIASETREG(0x420, 0x74301001);
39990b17f1bSmrg    VIASETREG(0x420, 0x00000000);
40090b17f1bSmrg}
40190b17f1bSmrg
40290b17f1bSmrg/*
40390b17f1bSmrg * Disable the virtual command queue.
40490b17f1bSmrg */
40590b17f1bSmrgvoid
40690b17f1bSmrgviaDisableVQ(ScrnInfoPtr pScrn)
40790b17f1bSmrg{
40890b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
40990b17f1bSmrg
41090b17f1bSmrg    switch (pVia->Chipset) {
41190b17f1bSmrg        case VIA_K8M890:
41290b17f1bSmrg        case VIA_P4M900:
41390b17f1bSmrg        case VIA_VX800:
41490b17f1bSmrg        case VIA_VX855:
41590b17f1bSmrg        case VIA_VX900:
41690b17f1bSmrg            VIASETREG(0x41c, 0x00100000);
41790b17f1bSmrg            VIASETREG(0x420, 0x74301000);
41890b17f1bSmrg            break;
41990b17f1bSmrg        default:
42090b17f1bSmrg            VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
42190b17f1bSmrg            VIASETREG(VIA_REG_TRANSPACE, 0x00000004);
42290b17f1bSmrg            VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f);
42390b17f1bSmrg            VIASETREG(VIA_REG_TRANSPACE, 0x44000000);
42490b17f1bSmrg            VIASETREG(VIA_REG_TRANSPACE, 0x45080c04);
42590b17f1bSmrg            VIASETREG(VIA_REG_TRANSPACE, 0x46800408);
42690b17f1bSmrg            break;
42790b17f1bSmrg    }
42890b17f1bSmrg}
42990b17f1bSmrg
43090b17f1bSmrg/*
43190b17f1bSmrg * Initialize the 2D engine and set the 2D context mode to the
43290b17f1bSmrg * current screen depth. Also enable the virtual queue.
43390b17f1bSmrg */
43490b17f1bSmrgstatic void
43590b17f1bSmrgVIAInitialize2DEngine(ScrnInfoPtr pScrn)
43690b17f1bSmrg{
43790b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
43890b17f1bSmrg    ViaTwodContext *tdc = &pVia->td;
43990b17f1bSmrg    int i;
44090b17f1bSmrg
44190b17f1bSmrg    /* Initialize the 2D engine registers to reset the 2D engine. */
44290b17f1bSmrg    for (i = 0x04; i <= 0x40; i += 4) {
44390b17f1bSmrg        VIASETREG(i, 0x0);
44490b17f1bSmrg    }
44590b17f1bSmrg
44690b17f1bSmrg    if (pVia->Chipset == VIA_VX800 ||
44790b17f1bSmrg        pVia->Chipset == VIA_VX855 ||
44890b17f1bSmrg        pVia->Chipset == VIA_VX900) {
44990b17f1bSmrg        for (i = 0x44; i <= 0x5c; i += 4) {
45090b17f1bSmrg            VIASETREG(i, 0x0);
45190b17f1bSmrg        }
45290b17f1bSmrg    }
45390b17f1bSmrg
45490b17f1bSmrg    if (pVia->Chipset == VIA_VX900)
45590b17f1bSmrg    {
45690b17f1bSmrg        /*410 redefine 0x30 34 38*/
45790b17f1bSmrg        VIASETREG(0x60, 0x0); /*already useable here*/
45890b17f1bSmrg    }
45990b17f1bSmrg
46090b17f1bSmrg    switch (pVia->Chipset) {
46190b17f1bSmrg        case VIA_K8M890:
46290b17f1bSmrg        case VIA_P4M900:
46390b17f1bSmrg        case VIA_VX800:
46490b17f1bSmrg        case VIA_VX855:
46590b17f1bSmrg        case VIA_VX900:
46690b17f1bSmrg            viaInitPCIe(pVia);
46790b17f1bSmrg            break;
46890b17f1bSmrg        default:
46990b17f1bSmrg            viaInitAgp(pVia);
47090b17f1bSmrg            break;
47190b17f1bSmrg    }
47290b17f1bSmrg
47390b17f1bSmrg    if (pVia->VQStart != 0) {
47490b17f1bSmrg        switch (pVia->Chipset) {
47590b17f1bSmrg            case VIA_K8M890:
47690b17f1bSmrg            case VIA_P4M900:
47790b17f1bSmrg            case VIA_VX800:
47890b17f1bSmrg            case VIA_VX855:
47990b17f1bSmrg            case VIA_VX900:
48090b17f1bSmrg                viaEnablePCIeVQ(pVia);
48190b17f1bSmrg                break;
48290b17f1bSmrg            default:
48390b17f1bSmrg                viaEnableAgpVQ(pVia);
48490b17f1bSmrg                break;
48590b17f1bSmrg        }
48690b17f1bSmrg    } else {
48790b17f1bSmrg        viaDisableVQ(pScrn);
48890b17f1bSmrg    }
48990b17f1bSmrg
49090b17f1bSmrg    viaAccelSetMode(pScrn->bitsPerPixel, tdc);
49190b17f1bSmrg}
49290b17f1bSmrg
49390b17f1bSmrgstatic void
49490b17f1bSmrgVIAInitialize3DEngine(ScrnInfoPtr pScrn)
49590b17f1bSmrg{
49690b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
49790b17f1bSmrg    int i;
49890b17f1bSmrg
49990b17f1bSmrg    VIASETREG(VIA_REG_TRANSET, 0x00010000);
50090b17f1bSmrg    for (i = 0; i <= 0x7D; i++)
50190b17f1bSmrg        VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
50290b17f1bSmrg
50390b17f1bSmrg    VIASETREG(VIA_REG_TRANSET, 0x00020000);
50490b17f1bSmrg    for (i = 0; i <= 0x94; i++)
50590b17f1bSmrg        VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
50690b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x82400000);
50790b17f1bSmrg
50890b17f1bSmrg    VIASETREG(VIA_REG_TRANSET, 0x01020000);
50990b17f1bSmrg    for (i = 0; i <= 0x94; i++)
51090b17f1bSmrg        VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
51190b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x82400000);
51290b17f1bSmrg
51390b17f1bSmrg    VIASETREG(VIA_REG_TRANSET, 0xfe020000);
51490b17f1bSmrg    for (i = 0; i <= 0x03; i++)
51590b17f1bSmrg        VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
51690b17f1bSmrg
51790b17f1bSmrg    VIASETREG(VIA_REG_TRANSET, 0x00030000);
51890b17f1bSmrg    for (i = 0; i <= 0xff; i++)
51990b17f1bSmrg        VIASETREG(VIA_REG_TRANSPACE, 0);
52090b17f1bSmrg
52190b17f1bSmrg    VIASETREG(VIA_REG_TRANSET, 0x00100000);
52290b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x00333004);
52390b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x10000002);
52490b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x60000000);
52590b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x61000000);
52690b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x62000000);
52790b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x63000000);
52890b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x64000000);
52990b17f1bSmrg
53090b17f1bSmrg    VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
53190b17f1bSmrg    if (pVia->Chipset == VIA_CLE266 && pVia->ChipRev >= 3)
53290b17f1bSmrg        VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f);
53390b17f1bSmrg    else
53490b17f1bSmrg        VIASETREG(VIA_REG_TRANSPACE, 0x4000800f);
53590b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x44000000);
53690b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x45080C04);
53790b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x46800408);
53890b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x50000000);
53990b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x51000000);
54090b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x52000000);
54190b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x53000000);
54290b17f1bSmrg
54390b17f1bSmrg    VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
54490b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x08000001);
54590b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x0A000183);
54690b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x0B00019F);
54790b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x0C00018B);
54890b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x0D00019B);
54990b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x0E000000);
55090b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x0F000000);
55190b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x10000000);
55290b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x11000000);
55390b17f1bSmrg    VIASETREG(VIA_REG_TRANSPACE, 0x20000000);
55490b17f1bSmrg}
55590b17f1bSmrg
55690b17f1bSmrg/*
55790b17f1bSmrg * Acceleration initialization function. Sets up offscreen memory disposition,
55890b17f1bSmrg * and initializes engines and acceleration method.
55990b17f1bSmrg */
56090b17f1bSmrgBool
56190b17f1bSmrgUMSAccelInit(ScreenPtr pScreen)
56290b17f1bSmrg{
56390b17f1bSmrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
56490b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
56590b17f1bSmrg    Bool ret = FALSE;
56690b17f1bSmrg
56790b17f1bSmrg    pVia->VQStart = 0;
56890b17f1bSmrg    pVia->vq_bo = drm_bo_alloc(pScrn, VIA_VQ_SIZE, 16, TTM_PL_FLAG_VRAM);
56990b17f1bSmrg    if (!pVia->vq_bo)
57090b17f1bSmrg        goto err;
57190b17f1bSmrg
57290b17f1bSmrg    pVia->VQStart = pVia->vq_bo->offset;
57390b17f1bSmrg    pVia->VQEnd = pVia->vq_bo->offset + pVia->vq_bo->size;
57490b17f1bSmrg
57590b17f1bSmrg    VIAInitialize2DEngine(pScrn);
57690b17f1bSmrg    VIAInitialize3DEngine(pScrn);
57790b17f1bSmrg
57890b17f1bSmrg    pVia->exa_sync_bo = drm_bo_alloc(pScrn, 32, 32, TTM_PL_FLAG_VRAM);
57990b17f1bSmrg    if (!pVia->exa_sync_bo)
58090b17f1bSmrg        goto err;
58190b17f1bSmrg
58290b17f1bSmrg    /* Sync marker space. */
58390b17f1bSmrg    pVia->exa_sync_bo = drm_bo_alloc(pScrn, 32, 32, TTM_PL_FLAG_VRAM);
58490b17f1bSmrg    if (!pVia->exa_sync_bo)
58590b17f1bSmrg        goto err;
58690b17f1bSmrg
58790b17f1bSmrg    pVia->markerOffset = pVia->exa_sync_bo->offset;
58890b17f1bSmrg    pVia->markerBuf = drm_bo_map(pScrn, pVia->exa_sync_bo);
58990b17f1bSmrg    if (!pVia->markerBuf)
59090b17f1bSmrg        goto err;
59190b17f1bSmrg    pVia->curMarker = 0;
59290b17f1bSmrg    pVia->lastMarkerRead = 0;
59390b17f1bSmrg
59490b17f1bSmrg#ifdef HAVE_DRI
59590b17f1bSmrg    pVia->dBounce = NULL;
59690b17f1bSmrg    pVia->scratchAddr = NULL;
59790b17f1bSmrg#endif /* HAVE_DRI */
59890b17f1bSmrg    ret = TRUE;
59990b17f1bSmrgerr:
60090b17f1bSmrg    if (!ret) {
60190b17f1bSmrg        if (pVia->markerBuf) {
60290b17f1bSmrg            drm_bo_unmap(pScrn, pVia->exa_sync_bo);
60390b17f1bSmrg            pVia->markerBuf = NULL;
60490b17f1bSmrg        }
60590b17f1bSmrg        if (pVia->exa_sync_bo)
60690b17f1bSmrg            drm_bo_free(pScrn, pVia->exa_sync_bo);
60790b17f1bSmrg        if (pVia->vq_bo)
60890b17f1bSmrg            drm_bo_free(pScrn, pVia->vq_bo);
60990b17f1bSmrg    }
61090b17f1bSmrg    return ret;
61190b17f1bSmrg}
61290b17f1bSmrg
61390b17f1bSmrgBool
61490b17f1bSmrgums_create(ScrnInfoPtr pScrn)
61590b17f1bSmrg{
61690b17f1bSmrg    ScreenPtr pScreen = pScrn->pScreen;
61790b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
61890b17f1bSmrg    unsigned long offset;
61990b17f1bSmrg    BoxRec AvailFBArea;
62090b17f1bSmrg    Bool ret = TRUE;
62190b17f1bSmrg    long size;
62290b17f1bSmrg    int maxY;
62390b17f1bSmrg
62490b17f1bSmrg#ifdef HAVE_DRI
62590b17f1bSmrg    if (pVia->directRenderingType == DRI_1) {
62690b17f1bSmrg        pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart) >> 2;
62790b17f1bSmrg        if ((pVia->driSize > (pVia->maxDriSize * 1024)) && pVia->maxDriSize > 0)
62890b17f1bSmrg            pVia->driSize = pVia->maxDriSize * 1024;
62990b17f1bSmrg
63090b17f1bSmrg        /* In the case of DRI we handle all VRAM by the DRI ioctls */
63190b17f1bSmrg        if (pVia->useEXA)
63290b17f1bSmrg            return TRUE;
63390b17f1bSmrg
63490b17f1bSmrg        /* XAA has to use FBManager so we have to split the space with DRI */
63590b17f1bSmrg        maxY = pScrn->virtualY + (pVia->driSize / pVia->Bpl);
63690b17f1bSmrg    } else
63790b17f1bSmrg#endif
63890b17f1bSmrg        maxY = pVia->FBFreeEnd / pVia->Bpl;
63990b17f1bSmrg
64090b17f1bSmrg    /* FBManager can't handle more than 32767 scan lines */
64190b17f1bSmrg    if (maxY > 32767)
64290b17f1bSmrg        maxY = 32767;
64390b17f1bSmrg
64490b17f1bSmrg    AvailFBArea.x1 = 0;
64590b17f1bSmrg    AvailFBArea.y1 = 0;
64690b17f1bSmrg    AvailFBArea.x2 = pScrn->displayWidth;
64790b17f1bSmrg    AvailFBArea.y2 = maxY;
64890b17f1bSmrg    pVia->FBFreeStart = (AvailFBArea.y2 + 1) * pVia->Bpl;
64990b17f1bSmrg
65090b17f1bSmrg    /*
65190b17f1bSmrg     *   Initialization of the XFree86 framebuffer manager is done via
65290b17f1bSmrg     *   Bool xf86InitFBManager(ScreenPtr pScreen, BoxPtr FullBox)
65390b17f1bSmrg     *   FullBox represents the area of the framebuffer that the manager
65490b17f1bSmrg     *   is allowed to manage. This is typically a box with a width
65590b17f1bSmrg     *   of pScrn->displayWidth and a height of as many lines as can be fit
65690b17f1bSmrg     *   within the total video memory
65790b17f1bSmrg     */
65890b17f1bSmrg    ret = xf86InitFBManager(pScreen, &AvailFBArea);
65990b17f1bSmrg    if (ret != TRUE)
66090b17f1bSmrg        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86InitFBManager init failed\n");
66190b17f1bSmrg
66290b17f1bSmrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
66390b17f1bSmrg            "Frame Buffer From (%d,%d) To (%d,%d)\n",
66490b17f1bSmrg            AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, AvailFBArea.y2));
66590b17f1bSmrg
66690b17f1bSmrg    offset = (pVia->FBFreeStart + pVia->Bpp - 1) / pVia->Bpp;
66790b17f1bSmrg    size = pVia->FBFreeEnd / pVia->Bpp - offset;
66890b17f1bSmrg    if (size > 0)
66990b17f1bSmrg        xf86InitFBManagerLinear(pScreen, offset, size);
67090b17f1bSmrg
67190b17f1bSmrg    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
67290b17f1bSmrg            "Using %d lines for offscreen memory.\n",
67390b17f1bSmrg            AvailFBArea.y2 - pScrn->virtualY));
67490b17f1bSmrg    return TRUE;
67590b17f1bSmrg}
67690b17f1bSmrg
67790b17f1bSmrgBool
67890b17f1bSmrgUMSPreInit(ScrnInfoPtr pScrn)
67990b17f1bSmrg{
68090b17f1bSmrg    MessageType from = X_PROBED;
68190b17f1bSmrg    VIAPtr pVia = VIAPTR(pScrn);
68290b17f1bSmrg    CARD8 videoRam;
68390b17f1bSmrg    vgaHWPtr hwp;
68490b17f1bSmrg#ifdef HAVE_PCIACCESS
68590b17f1bSmrg    struct pci_device *vgaDevice = pci_device_find_by_slot(0, 0, 0, 3);
68690b17f1bSmrg    struct pci_device *bridge = pci_device_find_by_slot(0, 0, 0, 0);
68790b17f1bSmrg#endif
68890b17f1bSmrg    int bMemSize = 0;
68990b17f1bSmrg
69090b17f1bSmrg    if (!xf86LoadSubModule(pScrn, "vgahw"))
69190b17f1bSmrg        return FALSE;
69290b17f1bSmrg
69390b17f1bSmrg    if (!vgaHWGetHWRec(pScrn))
69490b17f1bSmrg        return FALSE;
69590b17f1bSmrg
69690b17f1bSmrg#if 0
69790b17f1bSmrg    /* Here we can alter the number of registers saved and restored by the
69890b17f1bSmrg     * standard vgaHWSave and Restore routines.
69990b17f1bSmrg     */
70090b17f1bSmrg    vgaHWSetRegCounts(pScrn, VGA_NUM_CRTC, VGA_NUM_SEQ, VGA_NUM_GFX,
70190b17f1bSmrg                      VGA_NUM_ATTR);
70290b17f1bSmrg#endif
70390b17f1bSmrg    hwp = VGAHWPTR(pScrn);
70490b17f1bSmrg
70590b17f1bSmrg    switch (pVia->Chipset) {
70690b17f1bSmrg        case VIA_CLE266:
70790b17f1bSmrg#ifdef HAVE_PCIACCESS
70890b17f1bSmrg            pci_device_cfg_read_u8(bridge, &videoRam, 0xE1);
70990b17f1bSmrg#else
71090b17f1bSmrg            videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70;
71190b17f1bSmrg#endif
71290b17f1bSmrg            pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10;
71390b17f1bSmrg            break;
71490b17f1bSmrg        case VIA_KM400:
71590b17f1bSmrg#ifdef HAVE_PCIACCESS
716963d66acSmrg            /* P4M800 Host Bridge PCI Device ID */
717963d66acSmrg            if (DEVICE_ID(bridge) == 0x0296) {
71890b17f1bSmrg                pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1);
71990b17f1bSmrg            } else {
72090b17f1bSmrg                pci_device_cfg_read_u8(bridge, &videoRam, 0xE1);
721963d66acSmrg            }
72290b17f1bSmrg#else
723963d66acSmrg            /* P4M800 Host Bridge PCI Device ID */
724963d66acSmrg            if (pciReadWord(pciTag(0, 0, 0), 0x02) == 0x0296) {
725963d66acSmrg                videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70;
726963d66acSmrg            } else {
72790b17f1bSmrg                videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70;
72890b17f1bSmrg            }
729963d66acSmrg#endif
73090b17f1bSmrg            pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10;
73190b17f1bSmrg            break;
73290b17f1bSmrg        case VIA_PM800:
733963d66acSmrg        case VIA_P4M800PRO:
73490b17f1bSmrg        case VIA_K8M800:
73590b17f1bSmrg#ifdef HAVE_PCIACCESS
73690b17f1bSmrg            pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1);
73790b17f1bSmrg#else
73890b17f1bSmrg            videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70;
73990b17f1bSmrg#endif
74090b17f1bSmrg            pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10;
74190b17f1bSmrg            break;
74290b17f1bSmrg        case VIA_P4M890:
743963d66acSmrg        case VIA_K8M890:
74490b17f1bSmrg        case VIA_P4M900:
74590b17f1bSmrg        case VIA_CX700:
74690b17f1bSmrg        case VIA_VX800:
74790b17f1bSmrg        case VIA_VX855:
74890b17f1bSmrg        case VIA_VX900:
74990b17f1bSmrg#ifdef HAVE_PCIACCESS
75090b17f1bSmrg            pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1);
75190b17f1bSmrg#else
75290b17f1bSmrg            videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70;
75390b17f1bSmrg#endif
75490b17f1bSmrg            pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 12;
75590b17f1bSmrg            break;
75690b17f1bSmrg        default:
75790b17f1bSmrg            if (pScrn->videoRam < 16384 || pScrn->videoRam > 65536) {
75890b17f1bSmrg                xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
75990b17f1bSmrg                           "Using old memory-detection method.\n");
76090b17f1bSmrg                bMemSize = hwp->readSeq(hwp, 0x39);
76190b17f1bSmrg                if (bMemSize > 16 && bMemSize <= 128)
76290b17f1bSmrg                    pScrn->videoRam = (bMemSize + 1) << 9;
76390b17f1bSmrg                else if (bMemSize > 0 && bMemSize < 31)
76490b17f1bSmrg                    pScrn->videoRam = bMemSize << 12;
76590b17f1bSmrg                else {
76690b17f1bSmrg                    from = X_DEFAULT;
76790b17f1bSmrg                    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
76890b17f1bSmrg                               "Memory size detection failed: using 16 MB.\n");
76990b17f1bSmrg                    pScrn->videoRam = 16 << 10;
77090b17f1bSmrg                }
77190b17f1bSmrg            } else {
77290b17f1bSmrg                from = X_DEFAULT;
77390b17f1bSmrg                xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
77490b17f1bSmrg                           "No memory-detection done. Use VideoRAM option.\n");
77590b17f1bSmrg            }
77690b17f1bSmrg    }
77790b17f1bSmrg
77890b17f1bSmrg    /*
77990b17f1bSmrg     * PCI BAR are limited to 256 MB.
78090b17f1bSmrg     */
78190b17f1bSmrg    if (pScrn->videoRam > (256 << 10)) {
78290b17f1bSmrg        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
78390b17f1bSmrg                    "Cannot use more than 256 MB of VRAM.\n");
78490b17f1bSmrg                    pScrn->videoRam = (256 << 10);
78590b17f1bSmrg    }
78690b17f1bSmrg
78790b17f1bSmrg    if (from == X_PROBED) {
78890b17f1bSmrg        xf86DrvMsg(pScrn->scrnIndex, from,
78990b17f1bSmrg                   "Probed amount of VideoRAM = %d kB\n", pScrn->videoRam);
79090b17f1bSmrg    }
79190b17f1bSmrg
79290b17f1bSmrg    /* Split the FB for SAMM. */
79390b17f1bSmrg    /* FIXME: For now, split the FB into two equal sections.
79490b17f1bSmrg     * This should be user-adjustable via a config option. */
79590b17f1bSmrg    if (pVia->IsSecondary) {
79690b17f1bSmrg        DevUnion *pPriv;
79790b17f1bSmrg        VIAEntPtr pVIAEnt;
79890b17f1bSmrg        VIAPtr pVia1;
79990b17f1bSmrg
80090b17f1bSmrg        pPriv = xf86GetEntityPrivate(pScrn->entityList[0], gVIAEntityIndex);
80190b17f1bSmrg        pVIAEnt = pPriv->ptr;
80290b17f1bSmrg        pScrn->videoRam = pScrn->videoRam >> 1;
80390b17f1bSmrg        pVIAEnt->pPrimaryScrn->videoRam = pScrn->videoRam;
80490b17f1bSmrg        pVia1 = VIAPTR(pVIAEnt->pPrimaryScrn);
80590b17f1bSmrg        pVia1->videoRambytes = pScrn->videoRam << 10;
80690b17f1bSmrg        pVia->FrameBufferBase += (pScrn->videoRam << 10);
80790b17f1bSmrg    }
80890b17f1bSmrg
80990b17f1bSmrg    pVia->videoRambytes = pScrn->videoRam << 10;
81090b17f1bSmrg
81190b17f1bSmrg    /* maybe throw in some more sanity checks here */
81290b17f1bSmrg#ifndef HAVE_PCIACCESS
81390b17f1bSmrg    pVia->PciTag = pciTag(pVia->PciInfo->bus, pVia->PciInfo->device,
81490b17f1bSmrg                          pVia->PciInfo->func);
81590b17f1bSmrg#endif
81690b17f1bSmrg
81790b17f1bSmrg    /* Detect the amount of installed RAM */
81890b17f1bSmrg    if (!VIAMapMMIO(pScrn))
81990b17f1bSmrg        return FALSE;
82090b17f1bSmrg
82190b17f1bSmrg    if (!VIAMapFB(pScrn))
82290b17f1bSmrg        return FALSE;
82390b17f1bSmrg    return TRUE;
82490b17f1bSmrg}
825