1
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c,v 1.48tsi Exp $ */
3
* vim: sw=4 ts=8 ai ic:
5
* XFree86 4.0 S3 Savage driver
7
* Tim Roberts <timr@probo.com>
8
* Ani Joshi <ajoshi@unixbox.com>
10
* TODO: add credits for the 3.3.x authors...
2
* Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
3
* Copyright (c) 2003-2006, X.Org Foundation
5
* Permission is hereby granted, free of charge, to any person obtaining a
6
* copy of this software and associated documentation files (the "Software"),
7
* to deal in the Software without restriction, including without limitation
8
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
* and/or sell copies of the Software, and to permit persons to whom the
10
* Software is furnished to do so, subject to the following conditions:
12
* The above copyright notice and this permission notice shall be included in
13
* all copies or substantial portions of the Software.
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
* COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
* DEALINGS IN THE SOFTWARE.
23
* Except as contained in this notice, the name of the copyright holder(s)
24
* and author(s) shall not be used in advertising or otherwise to promote
25
* the sale, use or other dealings in this Software without prior written
26
* authorization from the copyright holder(s) and author(s).
30
* \file savage_driver.c
32
* \author Tim Roberts <timr@probo.com>
33
* \author Ani Joshi <ajoshi@unixbox.com>
35
* \todo Add credits for the 3.3.x authors.
14
38
#ifdef HAVE_CONFIG_H
244
269
{ OPTION_DISABLE_XVMC, "DisableXVMC", OPTV_BOOLEAN, {0}, FALSE },
245
270
{ OPTION_DISABLE_TILE, "DisableTile", OPTV_BOOLEAN, {0}, FALSE },
246
271
{ OPTION_DISABLE_COB, "DisableCOB", OPTV_BOOLEAN, {0}, FALSE },
247
{ OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE },
248
{ OPTION_BCI_FOR_XV, "BCIforXv", OPTV_BOOLEAN, {0}, FALSE },
249
{ OPTION_DVI, "DVI", OPTV_BOOLEAN, {0}, FALSE },
272
{ OPTION_BCI_FOR_XV, "BCIforXv", OPTV_BOOLEAN, {0}, FALSE },
273
{ OPTION_DVI, "DVI", OPTV_BOOLEAN, {0}, FALSE },
251
275
{ OPTION_BUS_TYPE, "BusType", OPTV_ANYSTR, {0}, FALSE },
252
276
{ OPTION_DMA_TYPE, "DmaType", OPTV_ANYSTR, {0}, FALSE },
1552
1604
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1553
1605
"Option: %s the COB\n",(psav->disableCOB?"Disable":"Enable"));
1557
psav->directRenderingEnabled =
1558
!xf86ReturnOptValBool(psav->Options, OPTION_DRI, FALSE);
1560
/* Disable DRI by default on the following Savage chipsets for the following
1563
* https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=196011
1564
* https://bugs.freedesktop.org/show_bug.cgi?id=6357
1567
if (psav->directRenderingEnabled) {
1568
if (psav->ChipId == PCI_CHIP_SUPSAV_IXCSDR ||
1569
psav->ChipId == PCI_CHIP_SUPSAV_IXCDDR ||
1570
psav->ChipId == PCI_CHIP_PROSAVAGE_DDRK ||
1571
psav->ChipId == PCI_CHIP_SAVAGE_IX_MV) {
1572
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled by default "
1573
"on this chipset as it is experimental and unstable.\n"
1574
"Please refer to https://bugs.freedesktop.org/show_bug.cgi?id=6357 for more\n"
1576
psav->directRenderingEnabled=FALSE;
1581
1607
if (psav->Chipset == S3_PROSAVAGE ||
1582
1608
psav->Chipset == S3_TWISTER ||
1583
1609
psav->Chipset == S3_PROSAVAGEDDR)
1686
1722
/* Compute the amount of video memory and offscreen memory. */
1688
1724
if (!pScrn->videoRam) {
1689
static unsigned char RamSavage3D[] = { 8, 4, 4, 2 };
1725
static const unsigned char RamSavage3D[] = { 8, 4, 4, 2 };
1690
1726
static unsigned char RamSavage4[] = { 2, 4, 8, 12, 16, 32, 64, 32 };
1691
static unsigned char RamSavageMX[] = { 2, 8, 4, 16, 8, 16, 4, 16 };
1692
static unsigned char RamSavageNB[] = { 0, 2, 4, 8, 16, 32, 16, 2 };
1727
static const unsigned char RamSavageMX[] = { 2, 8, 4, 16, 8, 16, 4, 16 };
1728
static const unsigned char RamSavageNB[] = { 0, 2, 4, 8, 16, 32, 16, 2 };
1694
1730
switch( psav->Chipset ) {
1695
1731
case S3_SAVAGE3D:
2771
static Bool SavageMapMMIO(ScrnInfoPtr pScrn)
2838
static Bool SavageMapMem(ScrnInfoPtr pScrn)
2775
TRACE(("SavageMapMMIO()\n"));
2777
psav = SAVPTR(pScrn);
2840
SavagePtr psav = SAVPTR(pScrn);
2844
TRACE(("SavageMapMem()\n"));
2779
2846
if( S3_SAVAGE3D_SERIES(psav->Chipset) ) {
2780
psav->MmioBase = psav->PciInfo->memBase[0] + SAVAGE_NEWMMIO_REGBASE_S3;
2781
psav->FrameBufferBase = psav->PciInfo->memBase[0];
2784
psav->MmioBase = psav->PciInfo->memBase[0] + SAVAGE_NEWMMIO_REGBASE_S4;
2785
psav->FrameBufferBase = psav->PciInfo->memBase[1];
2788
xf86DrvMsg( pScrn->scrnIndex, X_INFO,
2789
"mapping MMIO @ 0x%lx with size 0x%x\n",
2790
psav->MmioBase, SAVAGE_NEWMMIO_REGSIZE);
2792
psav->MapBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, psav->PciTag,
2794
SAVAGE_NEWMMIO_REGSIZE);
2796
psav->MapBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT,
2798
psav->PciInfo->memBase[0],
2801
if (!psav->MapBase) {
2802
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2803
"Internal error: cound not map registers\n");
2847
psav->MmioRegion.bar = 0;
2848
psav->MmioRegion.offset = SAVAGE_NEWMMIO_REGBASE_S3;
2850
psav->FbRegion.bar = 0;
2851
psav->FbRegion.offset = 0;
2855
psav->MmioRegion.bar = 0;
2856
psav->MmioRegion.offset = SAVAGE_NEWMMIO_REGBASE_S4;
2858
psav->FbRegion.bar = 1;
2859
psav->FbRegion.offset = 0;
2864
/* On Paramount and Savage 2000, aperture 0 is PCI base 2. On other
2865
* chipsets it's in the same BAR as the framebuffer.
2867
if ((psav->Chipset == S3_SUPERSAVAGE)
2868
|| (psav->Chipset == S3_SAVAGE2000)) {
2869
psav->ApertureRegion.bar = 2;
2870
psav->ApertureRegion.offset = 0;
2874
psav->ApertureRegion.bar = psav->FbRegion.bar;
2875
psav->ApertureRegion.offset = 0x02000000;
2879
psav->MmioBase = psav->PciInfo->memBase[ psav->MmioRegion.bar ]
2880
+ psav->MmioRegion.offset;
2882
psav->FrameBufferBase = psav->PciInfo->memBase[ psav->FbRegion.bar ]
2883
+ psav->FbRegion.offset;
2885
psav->ApertureBase = psav->PciInfo->memBase[ psav->FbRegion.bar ]
2886
+ psav->ApertureRegion.offset;
2889
/* FIXME: This seems fine even on Savage3D where the same BAR contains the
2890
* FIXME: MMIO space and the framebuffer. Write-combining gets fixed up
2891
* FIXME: later. Someone should investigate this, though. And kick S3
2892
* FIXME: for doing something so silly.
2895
for (i = 0; i <= psav->last_bar; i++) {
2896
psav->bar_mappings[i] = xf86MapPciMem(pScrn->scrnIndex, mode,
2898
psav->PciInfo->memBase[i],
2899
(1U << psav->PciInfo->size[i]));
2900
if (!psav->bar_mappings[i]) {
2901
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2902
"Internal error: cound not map PCI region %u, last BAR = %u\n",
2907
mode = VIDMEM_FRAMEBUFFER;
2910
psav->MapBase = psav->bar_mappings[ psav->MmioRegion.bar ]
2911
+ psav->MmioRegion.offset;
2807
2913
psav->BciMem = psav->MapBase + 0x10000;
2809
2915
SavageEnableMMIO(pScrn);
2814
#define TRANSPARENCY_KEY 0xff;
2816
static Bool SavageMapFB(ScrnInfoPtr pScrn)
2818
SavagePtr psav = SAVPTR(pScrn);
2820
TRACE(("SavageMapFB()\n"));
2822
xf86DrvMsg( pScrn->scrnIndex, X_PROBED,
2823
"mapping framebuffer @ 0x%lx with size 0x%x\n",
2824
psav->FrameBufferBase, psav->videoRambytes);
2826
if (psav->videoRambytes) {
2827
psav->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
2828
psav->PciTag, psav->FrameBufferBase,
2829
psav->videoRambytes);
2830
if (!psav->FBBase) {
2831
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2832
"Internal error: could not map framebuffer\n");
2835
if (psav->IsSecondary)
2836
psav->FBStart = psav->FBBase + 0x1000000;
2838
psav->FBStart = psav->FBBase;
2841
if ((psav->Chipset == S3_SUPERSAVAGE) || (psav->Chipset == S3_SAVAGE2000))
2842
/* paramount, savage2000 aperture 0 is pci base 2 */
2843
psav->ApertureBase = psav->PciInfo->memBase[2];
2845
psav->ApertureBase = psav->FrameBufferBase + 0x02000000;
2917
psav->FBBase = psav->bar_mappings[ psav->FbRegion.bar ]
2918
+ psav->FbRegion.offset;
2920
psav->FBStart = (psav->IsSecondary)
2921
? psav->FBBase + 0x1000000 : psav->FBBase;
2923
psav->ApertureMap = psav->bar_mappings[ psav->ApertureRegion.bar ]
2924
+ psav->ApertureRegion.offset;
2847
2926
if (psav->IsSecondary) {
2848
psav->ApertureMap = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
2849
psav->PciTag, psav->ApertureBase,
2851
2927
psav->ApertureMap += 0x1000000;
2852
} else if (psav->IsPrimary) {
2853
psav->ApertureMap = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
2854
psav->PciTag, psav->ApertureBase,
2857
psav->ApertureMap = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
2858
psav->PciTag, psav->ApertureBase,
2862
if (!psav->ApertureMap) {
2863
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2864
"Internal error: could not map aperture\n");
2869
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2870
"map aperture:%p\n",psav->ApertureMap);
2874
if (psav->IsSecondary)
2875
pScrn->fbOffset = pScrn->videoRam * 1024;
2877
pScrn->fbOffset = 0;
2879
pScrn->memPhysBase = psav->PciInfo->memBase[0] + pScrn->fbOffset;
2930
pScrn->memPhysBase = psav->PciInfo->memBase[0];