133
140
int gSavageEntityIndex = -1;
135
_X_EXPORT DriverRec SAVAGE =
141
SavageAvailableOptions,
142
#ifdef XSERVER_LIBPCIACCESS
143
#define SAVAGE_DEVICE_MATCH(d, i) \
144
{ 0x5333, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) }
146
static const struct pci_id_match savage_device_match[] = {
147
SAVAGE_DEVICE_MATCH(PCI_CHIP_SAVAGE4, S3_SAVAGE4),
148
SAVAGE_DEVICE_MATCH(PCI_CHIP_SAVAGE3D, S3_SAVAGE3D),
149
SAVAGE_DEVICE_MATCH(PCI_CHIP_SAVAGE3D_MV, S3_SAVAGE3D),
150
SAVAGE_DEVICE_MATCH(PCI_CHIP_SAVAGE2000, S3_SAVAGE2000),
151
SAVAGE_DEVICE_MATCH(PCI_CHIP_SAVAGE_MX_MV, S3_SAVAGE_MX),
152
SAVAGE_DEVICE_MATCH(PCI_CHIP_SAVAGE_MX, S3_SAVAGE_MX),
153
SAVAGE_DEVICE_MATCH(PCI_CHIP_SAVAGE_IX_MV, S3_SAVAGE_MX),
154
SAVAGE_DEVICE_MATCH(PCI_CHIP_SAVAGE_IX, S3_SAVAGE_MX),
155
SAVAGE_DEVICE_MATCH(PCI_CHIP_PROSAVAGE_PM, S3_PROSAVAGE),
156
SAVAGE_DEVICE_MATCH(PCI_CHIP_PROSAVAGE_KM, S3_PROSAVAGE),
157
SAVAGE_DEVICE_MATCH(PCI_CHIP_S3TWISTER_P, S3_TWISTER),
158
SAVAGE_DEVICE_MATCH(PCI_CHIP_S3TWISTER_K, S3_TWISTER),
159
SAVAGE_DEVICE_MATCH(PCI_CHIP_SUPSAV_MX128, S3_SUPERSAVAGE),
160
SAVAGE_DEVICE_MATCH(PCI_CHIP_SUPSAV_MX64, S3_SUPERSAVAGE),
161
SAVAGE_DEVICE_MATCH(PCI_CHIP_SUPSAV_MX64C, S3_SUPERSAVAGE),
162
SAVAGE_DEVICE_MATCH(PCI_CHIP_SUPSAV_IX128SDR, S3_SUPERSAVAGE),
163
SAVAGE_DEVICE_MATCH(PCI_CHIP_SUPSAV_IX128DDR, S3_SUPERSAVAGE),
164
SAVAGE_DEVICE_MATCH(PCI_CHIP_SUPSAV_IX64SDR, S3_SUPERSAVAGE),
165
SAVAGE_DEVICE_MATCH(PCI_CHIP_SUPSAV_IX64DDR, S3_SUPERSAVAGE),
166
SAVAGE_DEVICE_MATCH(PCI_CHIP_SUPSAV_IXCSDR, S3_SUPERSAVAGE),
167
SAVAGE_DEVICE_MATCH(PCI_CHIP_SUPSAV_IXCDDR, S3_SUPERSAVAGE),
168
SAVAGE_DEVICE_MATCH(PCI_CHIP_PROSAVAGE_DDR, S3_PROSAVAGEDDR),
169
SAVAGE_DEVICE_MATCH(PCI_CHIP_PROSAVAGE_DDRK, S3_PROSAVAGEDDR),
148
175
/* Supported chipsets */
842
#ifdef XSERVER_LIBPCIACCESS
843
static Bool SavagePciProbe(DriverPtr drv, int entity_num,
844
struct pci_device *dev, intptr_t match_data)
849
if ((match_data < S3_SAVAGE3D) || (match_data > S3_SAVAGE2000)) {
853
pScrn = xf86ConfigPciEntity(NULL, 0, entity_num, NULL,
854
RES_SHARED_VGA, NULL, NULL, NULL, NULL);
860
pScrn->driverVersion = SAVAGE_VERSION;
861
pScrn->driverName = SAVAGE_DRIVER_NAME;
862
pScrn->name = "SAVAGE";
864
pScrn->PreInit = SavagePreInit;
865
pScrn->ScreenInit = SavageScreenInit;
866
pScrn->SwitchMode = SavageSwitchMode;
867
pScrn->AdjustFrame = SavageAdjustFrame;
868
pScrn->EnterVT = SavageEnterVT;
869
pScrn->LeaveVT = SavageLeaveVT;
870
pScrn->FreeScreen = NULL;
871
pScrn->ValidMode = SavageValidMode;
873
if (!SavageGetRec(pScrn))
876
psav = SAVPTR(pScrn);
879
psav->Chipset = match_data;
881
pEnt = xf86GetEntityInfo(entity_num);
883
/* MX, IX, SuperSavage cards support Dual-Head, mark the entity as
886
if (pEnt->chipset == S3_SAVAGE_MX || pEnt->chipset == S3_SUPERSAVAGE) {
888
SavageEntPtr pSavageEnt;
890
xf86SetEntitySharable(entity_num);
892
if (gSavageEntityIndex == -1)
893
gSavageEntityIndex = xf86AllocateEntityPrivateIndex();
895
pPriv = xf86GetEntityPrivate(pEnt->index, gSavageEntityIndex);
898
int instance = xf86GetNumEntityInstances(pEnt->index);
900
for (j = 0; j < instance; j++)
901
xf86SetEntityInstanceForScreen(pScrn, pEnt->index, j);
903
pPriv->ptr = xnfcalloc(sizeof(SavageEntRec), 1);
904
pSavageEnt = pPriv->ptr;
905
pSavageEnt->HasSecondary = FALSE;
907
pSavageEnt = pPriv->ptr;
908
pSavageEnt->HasSecondary = TRUE;
913
return (pScrn != NULL);
791
918
static Bool SavageProbe(DriverPtr drv, int flags)
2908
3061
static Bool SavageMapMem(ScrnInfoPtr pScrn)
2910
3063
SavagePtr psav = SAVPTR(pScrn);
2914
3066
TRACE(("SavageMapMem()\n"));
2916
3068
if( S3_SAVAGE3D_SERIES(psav->Chipset) ) {
2917
psav->MmioRegion.bar = 0;
2918
psav->MmioRegion.offset = SAVAGE_NEWMMIO_REGBASE_S3;
2920
psav->FbRegion.bar = 0;
2921
psav->FbRegion.offset = 0;
3069
#ifdef XSERVER_LIBPCIACCESS
3070
psav->MmioRegion.base = SAVAGE_NEWMMIO_REGBASE_S3
3071
+ psav->PciInfo->regions[0].base_addr;
3072
psav->FbRegion.base = psav->PciInfo->regions[0].base_addr;
3074
psav->MmioRegion.base = SAVAGE_NEWMMIO_REGBASE_S3
3075
+ psav->PciInfo->memBase[0];
3076
psav->FbRegion.base = psav->PciInfo->memBase[0];
2925
psav->MmioRegion.bar = 0;
2926
psav->MmioRegion.offset = SAVAGE_NEWMMIO_REGBASE_S4;
2928
psav->FbRegion.bar = 1;
2929
psav->FbRegion.offset = 0;
3079
#ifdef XSERVER_LIBPCIACCESS
3080
psav->MmioRegion.base = SAVAGE_NEWMMIO_REGBASE_S4
3081
+ psav->PciInfo->regions[0].base_addr;
3082
psav->FbRegion.base = psav->PciInfo->regions[1].base_addr;
3084
psav->MmioRegion.base = SAVAGE_NEWMMIO_REGBASE_S4
3085
+ psav->PciInfo->memBase[0];
3086
psav->FbRegion.base = psav->PciInfo->memBase[1];
3090
psav->MmioRegion.size = SAVAGE_NEWMMIO_REGSIZE;
3091
psav->FbRegion.size = psav->videoRambytes;
2934
3093
/* On Paramount and Savage 2000, aperture 0 is PCI base 2. On other
2935
3094
* chipsets it's in the same BAR as the framebuffer.
2937
3096
if ((psav->Chipset == S3_SUPERSAVAGE)
2938
|| (psav->Chipset == S3_SAVAGE2000)) {
2939
psav->ApertureRegion.bar = 2;
2940
psav->ApertureRegion.offset = 0;
3097
|| (psav->Chipset == S3_SAVAGE2000)) {
3098
#ifdef XSERVER_LIBPCIACCESS
3099
psav->ApertureRegion.base = psav->PciInfo->regions[2].base_addr;
3101
psav->ApertureRegion.base = psav->PciInfo->memBase[2];
2944
psav->ApertureRegion.bar = psav->FbRegion.bar;
2945
psav->ApertureRegion.offset = 0x02000000;
2949
psav->MmioBase = psav->PciInfo->memBase[ psav->MmioRegion.bar ]
2950
+ psav->MmioRegion.offset;
2952
psav->FrameBufferBase = psav->PciInfo->memBase[ psav->FbRegion.bar ]
2953
+ psav->FbRegion.offset;
2955
psav->ApertureBase = psav->PciInfo->memBase[ psav->FbRegion.bar ]
2956
+ psav->ApertureRegion.offset;
2959
/* FIXME: This seems fine even on Savage3D where the same BAR contains the
2960
* FIXME: MMIO space and the framebuffer. Write-combining gets fixed up
2961
* FIXME: later. Someone should investigate this, though. And kick S3
2962
* FIXME: for doing something so silly.
2965
for (i = 0; i <= psav->last_bar; i++) {
2966
psav->bar_mappings[i] = xf86MapPciMem(pScrn->scrnIndex, mode,
2968
psav->PciInfo->memBase[i],
2969
(1U << psav->PciInfo->size[i]));
2970
if (!psav->bar_mappings[i]) {
2971
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2972
"Internal error: cound not map PCI region %u, last BAR = %u\n",
2977
mode = VIDMEM_FRAMEBUFFER;
2980
psav->MapBase = psav->bar_mappings[ psav->MmioRegion.bar ]
2981
+ psav->MmioRegion.offset;
2983
psav->BciMem = psav->MapBase + 0x10000;
2985
SavageEnableMMIO(pScrn);
2987
psav->FBBase = psav->bar_mappings[ psav->FbRegion.bar ]
2988
+ psav->FbRegion.offset;
2990
psav->FBStart = (psav->IsSecondary)
2991
? psav->FBBase + 0x1000000 : psav->FBBase;
2993
psav->ApertureMap = psav->bar_mappings[ psav->ApertureRegion.bar ]
2994
+ psav->ApertureRegion.offset;
2996
if (psav->IsSecondary) {
2997
psav->ApertureMap += 0x1000000;
3000
pScrn->memPhysBase = psav->PciInfo->memBase[0];
3104
psav->ApertureRegion.base = psav->FbRegion.base + 0x02000000;
3107
psav->ApertureRegion.size = (psav->IsPrimary || psav->IsSecondary)
3108
? (0x01000000 * 2) : (0x01000000 * 5);
3111
if (psav->FbRegion.size != 0) {
3112
#ifdef XSERVER_LIBPCIACCESS
3113
err = pci_device_map_range(psav->PciInfo, psav->FbRegion.base,
3114
psav->FbRegion.size,
3115
(PCI_DEV_MAP_FLAG_WRITABLE
3116
| PCI_DEV_MAP_FLAG_WRITE_COMBINE),
3117
& psav->FbRegion.memory);
3119
psav->FbRegion.memory =
3120
xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
3121
psav->PciTag, psav->FbRegion.base,
3122
psav->FbRegion.size);
3123
err = (psav->FbRegion.memory == NULL) ? errno : 0;
3126
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3127
"Internal error: cound not map framebuffer range (%d, %s).\n",
3128
err, strerror(err));
3132
psav->FBBase = psav->FbRegion.memory;
3133
psav->FBStart = (psav->IsSecondary)
3134
? psav->FBBase + 0x1000000 : psav->FBBase;
3137
if (psav->ApertureRegion.memory == NULL) {
3138
#ifdef XSERVER_LIBPCIACCESS
3139
err = pci_device_map_range(psav->PciInfo, psav->ApertureRegion.base,
3140
psav->ApertureRegion.size,
3141
(PCI_DEV_MAP_FLAG_WRITABLE
3142
| PCI_DEV_MAP_FLAG_WRITE_COMBINE),
3143
& psav->ApertureRegion.memory);
3145
psav->ApertureRegion.memory =
3146
xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
3147
psav->PciTag, psav->ApertureRegion.base,
3148
psav->ApertureRegion.size);
3149
err = (psav->ApertureRegion.memory == NULL) ? errno : 0;
3152
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3153
"Internal error: cound not map aperture range (%d, %s).\n",
3154
err, strerror(err));
3158
psav->ApertureMap = (psav->IsSecondary)
3159
? psav->ApertureRegion.memory
3160
: psav->ApertureRegion.memory + 0x1000000;
3163
if (psav->MmioRegion.memory == NULL) {
3164
#ifdef XSERVER_LIBPCIACCESS
3165
err = pci_device_map_range(psav->PciInfo, psav->MmioRegion.base,
3166
psav->MmioRegion.size,
3167
(PCI_DEV_MAP_FLAG_WRITABLE),
3168
& psav->MmioRegion.memory);
3170
psav->MmioRegion.memory =
3171
xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
3172
psav->PciTag, psav->MmioRegion.base,
3173
psav->MmioRegion.size);
3174
err = (psav->MmioRegion.memory == NULL) ? errno : 0;
3177
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3178
"Internal error: cound not map MMIO range (%d, %s).\n",
3179
err, strerror(err));
3183
psav->MapBase = psav->MmioRegion.memory;
3184
psav->BciMem = psav->MapBase + 0x10000;
3186
SavageEnableMMIO(pScrn);
3189
pScrn->memPhysBase = psav->FbRegion.base;
3006
3194
static void SavageUnmapMem(ScrnInfoPtr pScrn, int All)
3008
3196
SavagePtr psav = SAVPTR(pScrn);
3011
3198
TRACE(("SavageUnmapMem(%x,%x)\n", psav->MapBase, psav->FBBase));
3013
3200
if (psav->PrimaryVidMapped) {
3014
vgaHWUnmapMem(pScrn);
3015
psav->PrimaryVidMapped = FALSE;
3201
vgaHWUnmapMem(pScrn);
3202
psav->PrimaryVidMapped = FALSE;
3018
3205
SavageDisableMMIO(pScrn);
3020
for (i = (All) ? 0 : 1; i <= psav->last_bar; i++) {
3021
if (psav->bar_mappings[i]) {
3022
xf86UnMapVidMem(pScrn->scrnIndex, psav->bar_mappings[i],
3023
(1U << psav->PciInfo->size[i]));
3024
psav->bar_mappings[i] = NULL;
3207
if (All && (psav->MmioRegion.memory != NULL)) {
3208
#ifdef XSERVER_LIBPCIACCESS
3209
pci_device_unmap_range(psav->PciInfo,
3210
psav->MmioRegion.memory,
3211
psav->MmioRegion.size);
3213
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)psav->MapBase,
3214
SAVAGE_NEWMMIO_REGSIZE);
3217
psav->MmioRegion.memory = NULL;
3222
if (psav->FbRegion.memory != NULL) {
3223
#ifdef XSERVER_LIBPCIACCESS
3224
pci_device_unmap_range(psav->PciInfo,
3225
psav->FbRegion.memory,
3226
psav->FbRegion.size);
3228
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)psav->FbRegion.base,
3229
psav->FbRegion.size);
3233
if (psav->ApertureRegion.memory != NULL) {
3234
#ifdef XSERVER_LIBPCIACCESS
3235
pci_device_unmap_range(psav->PciInfo,
3236
psav->ApertureRegion.memory,
3237
psav->ApertureRegion.size);
3239
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)psav->ApertureRegion.base,
3240
psav->ApertureRegion.size);
3244
psav->FbRegion.memory = NULL;
3245
psav->ApertureRegion.memory = NULL;
3033
3246
psav->FBBase = 0;
3034
3247
psav->FBStart = 0;
3035
3248
psav->ApertureMap = 0;