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