summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYannick Henault <yheneaul@matrox.com>2008-06-30 17:00:16 -0400
committerAdam Jackson <ajax@redhat.com>2008-06-30 17:00:16 -0400
commit62c8f0ad5bb3dd23226a6b481ed4f260c6770f55 (patch)
tree69b4aaeaf24fb6d836e7ea61aac5a74d13609573
parent32d50fca615af2c49914dd88c9da0f21b868b172 (diff)
Bug #16545: Add G200WB support.
-rw-r--r--src/mga.h11
-rw-r--r--src/mga_dacG.c272
-rw-r--r--src/mga_driver.c47
-rw-r--r--src/mga_merge.c2
-rw-r--r--src/mga_reg.h18
-rw-r--r--src/mga_storm.c1
6 files changed, 335 insertions, 16 deletions
diff --git a/src/mga.h b/src/mga.h
index 2469554..a831862 100644
--- a/src/mga.h
+++ b/src/mga.h
@@ -85,7 +85,8 @@ typedef enum {
OPTION_METAMODES,
OPTION_OLDDMA,
OPTION_PCIDMA,
- OPTION_ACCELMETHOD
+ OPTION_ACCELMETHOD,
+ OPTION_KVM
} MGAOpts;
@@ -124,6 +125,10 @@ void MGAdbg_outreg32(ScrnInfoPtr, int,int, char*);
#define PCI_CHIP_MGAG200_SE_B_PCI 0x0524
#endif
+#ifndef PCI_CHIP_MGAG200_WINBOND_PCI
+#define PCI_CHIP_MGAG200_WINBOND_PCI 0x0532
+#endif
+
#ifndef PCI_CHIP_MGAG200_EV_PCI
#define PCI_CHIP_MGAG200_EV_PCI 0x0530
#endif
@@ -467,7 +472,11 @@ typedef struct {
int is_Gx50:1;
int is_G200SE:1;
+ int is_G200WB:1;
int is_G200EV:1;
+
+ int KVM;
+
CARD32 reg_1e24; /* model revision on g200se */
Bool Primary;
diff --git a/src/mga_dacG.c b/src/mga_dacG.c
index d80b84d..af5d1d9 100644
--- a/src/mga_dacG.c
+++ b/src/mga_dacG.c
@@ -70,6 +70,7 @@ MGAG200IPComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
unsigned int ulTestPStart;
unsigned int ulTestNStart;
unsigned int ulTestNEnd;
+ unsigned int ulTestMStart;
unsigned int ulTestMEnd;
if (pMga->is_G200SE) {
@@ -79,8 +80,8 @@ MGAG200IPComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
ulTestPStart = 8;
ulTestNStart = 17;
ulTestNEnd = 32;
+ ulTestMStart = 1;
ulTestMEnd = 32;
-
} else if (pMga->is_G200EV) {
ulVCOMax = 550000;
ulVCOMin = 150000;
@@ -88,7 +89,17 @@ MGAG200IPComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
ulTestPStart = 16;
ulTestNStart = 1;
ulTestNEnd = 256;
+ ulTestMStart = 1;
ulTestMEnd = 16;
+ } else if (pMga->is_G200WB) {
+ ulVCOMax = 680000;
+ ulVCOMin = 150000;
+ ulPLLFreqRef = 48000;
+ ulTestPStart = 8;
+ ulTestNStart = 1;
+ ulTestNEnd = 512;
+ ulTestMStart = 3;
+ ulTestMEnd = 25;
}
ulFDelta = 0xFFFFFFFF;
@@ -101,7 +112,7 @@ MGAG200IPComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
if ((lFo * ulTestP) < ulVCOMin) continue;
for (ulTestN = ulTestNStart; ulTestN <= ulTestNEnd; ulTestN++) {
- for (ulTestM = 1; ulTestM <= ulTestMEnd; ulTestM++) {
+ for (ulTestM = ulTestMStart; ulTestM <= ulTestMEnd; ulTestM++) {
ulComputedFo = (ulPLLFreqRef * ulTestN) / (ulTestM * ulTestP);
if (ulComputedFo > lFo)
ulFTmpDelta = ulComputedFo - lFo;
@@ -109,8 +120,12 @@ MGAG200IPComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
ulFTmpDelta = lFo - ulComputedFo;
if (ulFTmpDelta < ulFDelta) {
- ulFDelta = ulFTmpDelta;
- *M = ulTestM - 1;
+ ulFDelta = ulFTmpDelta;
+ if (pMga->is_G200WB) {
+ *M = (ulTestM - 1) | (((ulTestN -1) >> 1) & 0x80);
+ } else {
+ *M = ulTestM - 1;
+ }
*N = ulTestN - 1;
*P = ulTestP - 1;
}
@@ -194,6 +209,199 @@ MGAG200EVPIXPLLSET(ScrnInfoPtr pScrn, MGARegPtr mgaReg)
outMGAdac(MGA1064_PIX_CLK_CTL, ucTempByte);
}
+static void
+MGAG200WBPIXPLLSET(ScrnInfoPtr pScrn, MGARegPtr mgaReg)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ unsigned long ulFallBackCounter;
+ unsigned char ucTempByte, ucPixCtrl;
+ unsigned char ucM;
+ unsigned char ucN;
+ unsigned char ucP;
+ unsigned char ucS;
+
+ // Set pixclkdis to 1
+ ucPixCtrl = inMGAdac(MGA1064_PIX_CLK_CTL);
+ ucPixCtrl |= MGA1064_PIX_CLK_CTL_CLK_DIS;
+ outMGAdac(MGA1064_PIX_CLK_CTL, ucPixCtrl);
+
+ ucTempByte = inMGAdac(MGA1064_REMHEADCTL);
+ ucTempByte |= MGA1064_REMHEADCTL_CLKDIS;
+ outMGAdac(MGA1064_REMHEADCTL, ucTempByte);
+
+ // Select PLL Set C
+ ucTempByte = INREG8(MGAREG_MISC_READ);
+ ucTempByte |= 0x3<<2; //select MGA pixel clock
+ OUTREG8(MGAREG_MISC_WRITE, ucTempByte);
+
+ // Set pixlock to 0
+ ucTempByte = inMGAdac(MGA1064_PIX_PLL_STAT);
+ outMGAdac(MGA1064_PIX_PLL_STAT, ucTempByte & ~0x40);
+
+ ucPixCtrl |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN | 0x80;
+ outMGAdac(MGA1064_PIX_CLK_CTL, ucPixCtrl);
+
+ // Wait 500 us
+ usleep(500);
+
+ // Reset the PLL
+ // When we are varying the output frequency by more than
+ // 10%, we must reset the PLL. However to be prudent, we
+ // will reset it each time that we are changing it.
+ ucTempByte = inMGAdac(MGA1064_VREF_CTL);
+ ucTempByte &= ~0x04;
+ outMGAdac(MGA1064_VREF_CTL, ucTempByte );
+
+ // Wait 50 us
+ usleep(50);
+
+ // Program the Pixel PLL Register
+ outMGAdac(MGA1064_WB_PIX_PLLC_M, mgaReg->PllM);
+ outMGAdac(MGA1064_WB_PIX_PLLC_N, mgaReg->PllN);
+ outMGAdac(MGA1064_WB_PIX_PLLC_P, mgaReg->PllP);
+
+ // Wait 50 us
+ usleep(50);
+
+ ucTempByte = INREG8(MGAREG_MISC_READ);
+ OUTREG8(MGAREG_MISC_WRITE, ucTempByte & ~0x08);
+
+ // Wait 50 us
+ usleep(50);
+
+ OUTREG8(MGAREG_MISC_WRITE, ucTempByte);
+
+ // Wait 500 us
+ usleep(500);
+
+ // Turning the PLL on
+ ucTempByte = inMGAdac(MGA1064_VREF_CTL);
+ ucTempByte |= 0x04;
+ outMGAdac(MGA1064_VREF_CTL, ucTempByte );
+
+ // Wait 500 us
+ usleep(500);
+
+ // Select the pixel PLL by setting pixclksel to 1
+ ucTempByte = inMGAdac(MGA1064_PIX_CLK_CTL);
+ ucTempByte &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
+ ucTempByte |= MGA1064_PIX_CLK_CTL_SEL_PLL;
+ outMGAdac(MGA1064_PIX_CLK_CTL, ucTempByte);
+
+ ucTempByte = inMGAdac(MGA1064_REMHEADCTL);
+ ucTempByte &= ~MGA1064_REMHEADCTL_CLKSL_MSK;
+ ucTempByte |= MGA1064_REMHEADCTL_CLKSL_PLL;
+ outMGAdac(MGA1064_REMHEADCTL, ucTempByte);
+
+ // Set pixlock to 1
+ ucTempByte = inMGAdac(MGA1064_PIX_PLL_STAT);
+ outMGAdac(MGA1064_PIX_PLL_STAT, ucTempByte | 0x40);
+
+ // Reset dotclock rate bit.
+ OUTREG8(MGAREG_SEQ_INDEX, 1);
+ ucTempByte = INREG8(MGAREG_SEQ_DATA);
+ OUTREG8(MGAREG_SEQ_DATA, ucTempByte & ~0x8);
+
+ // Set pixclkdis to 0
+ ucTempByte = inMGAdac(MGA1064_PIX_CLK_CTL);
+ ucTempByte &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
+ outMGAdac(MGA1064_PIX_CLK_CTL, ucTempByte);
+
+ // Set remclkdis to 0
+ ucTempByte = inMGAdac(MGA1064_REMHEADCTL);
+ ucTempByte &= ~MGA1064_REMHEADCTL_CLKDIS;
+ outMGAdac(MGA1064_REMHEADCTL, ucTempByte);
+}
+
+static void
+MGAG200WBPrepareForModeSwitch(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ unsigned char ucTmpData = 0;
+ int ulIterationMax = 0;
+ // 1- The first step is to warn the BMC of an upcoming mode change.
+ // We are putting the misc<0> to output.
+ ucTmpData = inMGAdac(MGA1064_GEN_IO_CTL);
+ ucTmpData |= 0x10;
+ outMGAdac(MGA1064_GEN_IO_CTL, ucTmpData);
+
+ // We are putting a 1 on the misc<0> line.
+ ucTmpData = inMGAdac(MGA1064_GEN_IO_DATA);
+ ucTmpData |= 0x10;
+ outMGAdac(MGA1064_GEN_IO_DATA, ucTmpData);
+
+ // 2- The second step is to mask any further scan request
+ // This will be done by asserting the remfreqmsk bit (XSPAREREG<7>)
+ ucTmpData = inMGAdac(MGA1064_SPAREREG);
+ ucTmpData |= 0x80;
+ outMGAdac(MGA1064_SPAREREG, ucTmpData);
+
+ // 3a- The third step is to verify if there is an active scan
+ // We are searching for a 0 on remhsyncsts (XSPAREREG<0>)
+ ulIterationMax = 300;
+ while (!(ucTmpData & 0x01) && ulIterationMax)
+ {
+ ucTmpData = inMGAdac(MGA1064_SPAREREG);
+ usleep(1000);
+ ulIterationMax--;
+ }
+
+ // 3b- This step occurs only if the remote is actually scanning
+ // We are waiting for the end of the frame which is a 1 on
+ // remvsyncsts (XSPAREREG<1>)
+ if (ulIterationMax)
+ {
+ ulIterationMax = 300;
+ while ((ucTmpData & 0x02) && ulIterationMax)
+ {
+ ucTmpData = inMGAdac(MGA1064_SPAREREG);
+ usleep(1000);
+ ulIterationMax--;
+ }
+ }
+}
+
+static void
+MGAG200WBRestoreFromModeSwitch(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ unsigned char ucTmpData = 0;
+
+ // 1- The first step is to ensure that the vrsten and hrsten are set
+ OUTREG8(MGAREG_CRTCEXT_INDEX, 0x01);
+ ucTmpData = INREG8(MGAREG_CRTCEXT_DATA);
+ OUTREG8(MGAREG_CRTCEXT_DATA, ucTmpData | 0x88);
+
+ // 2- The second step is is to assert the rstlvl2
+ ucTmpData = inMGAdac(MGA1064_REMHEADCTL2);
+ ucTmpData |= 0x08;
+ outMGAdac(MGA1064_REMHEADCTL2, ucTmpData);
+
+ // - Wait for 10 us
+ usleep(10);
+
+ // 3- The next step is is to deassert the rstlvl2
+ ucTmpData &= ~0x08;
+ outMGAdac(MGA1064_REMHEADCTL2, ucTmpData);
+
+ // - Wait for 10 us
+ usleep(10);
+
+ // 4- The fourth step is to remove the mask of scan request
+ // This will be done by deasserting the remfreqmsk bit (XSPAREREG<7>)
+ ucTmpData = inMGAdac(MGA1064_SPAREREG);
+ ucTmpData &= ~0x80;
+ outMGAdac(MGA1064_SPAREREG, ucTmpData);
+
+ // 5- Finally, we are putting back a 0 on the misc<0> line.
+ ucTmpData = inMGAdac(MGA1064_GEN_IO_DATA);
+ ucTmpData &= ~0x10;
+ outMGAdac(MGA1064_GEN_IO_DATA, ucTmpData);
+}
+
/**
* Calculate the PLL settings (m, n, p, s).
*
@@ -329,12 +537,12 @@ MGAGSetPCLK( ScrnInfoPtr pScrn, long f_out )
pReg->DacRegs[ MGA1064_PIX_PLLC_M ] = m;
pReg->DacRegs[ MGA1064_PIX_PLLC_N ] = n;
pReg->DacRegs[ MGA1064_PIX_PLLC_P ] = p;
- } else if (pMga->is_G200EV) {
+ } else if (pMga->is_G200EV || pMga->is_G200WB) {
MGAG200IPComputePLLParam(pScrn, f_out, &m, &n, &p);
pReg->PllM = m;
pReg->PllN = n;
pReg->PllP = p;
- } else {
+ } else {
/* Do the calculations for m, n, p and s */
MGAGCalcClock( pScrn, f_out, &m, &n, &p, &s );
@@ -512,6 +720,13 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
pReg->Option = 0x40049120;
pReg->Option2 = 0x00008000;
break;
+
+ case PCI_CHIP_MGAG200_WINBOND_PCI:
+ pReg->DacRegs[MGA1064_VREF_CTL] = 0x07;
+ pReg->Option = 0x41049120;
+ pReg->Option2 = 0x0000b000;
+ break;
+
case PCI_CHIP_MGAG200_EV_PCI:
pReg->DacRegs[MGA1064_PIX_CLK_CTL] =
MGA1064_PIX_CLK_CTL_SEL_PLL;
@@ -523,6 +738,7 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
pReg->Option = 0x00000120;
pReg->Option2 = 0x0000b000;
break;
+
case PCI_CHIP_MGAG200:
case PCI_CHIP_MGAG200_PCI:
default:
@@ -631,7 +847,11 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
else
pReg->ExtVga[3] = ((1 << BppShift) - 1) | 0x80;
- pReg->ExtVga[4] = 0;
+ pReg->ExtVga[4] = 0;
+
+ if (pMga->is_G200WB){
+ pReg->ExtVga[1] |= 0x88;
+ }
pVga->CRTC[0] = ht - 4;
pVga->CRTC[1] = hd;
@@ -813,6 +1033,13 @@ MGAGRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg,
MGAPtr pMga = MGAPTR(pScrn);
CARD32 optionMask;
+MGA_NOT_HAL(
+ if (pMga->is_G200WB)
+ {
+ MGAG200WBPrepareForModeSwitch(pScrn);
+ }
+);
+
/*
* Pixel Clock needs to be restored regardless if we use
* HALLib or not. HALlib doesn't do a good job restoring
@@ -861,7 +1088,7 @@ MGA_NOT_HAL(
if (pMga->is_G200SE
&& ((i == 0x2C) || (i == 0x2D) || (i == 0x2E)))
continue;
- if ( (pMga->is_G200EV) &&
+ if ( (pMga->is_G200EV || pMga->is_G200WB) &&
(i >= 0x44) && (i <= 0x4E))
continue;
@@ -900,6 +1127,8 @@ MGA_NOT_HAL(
if (pMga->is_G200EV) {
MGAG200EVPIXPLLSET(pScrn, mgaReg);
+ } else if (pMga->is_G200WB) {
+ MGAG200WBPIXPLLSET(pScrn, mgaReg);
}
); /* MGA_NOT_HAL */
#ifdef USEMGAHAL
@@ -942,6 +1171,14 @@ MGA_NOT_HAL(
* this is needed to properly restore start address
*/
OUTREG16(MGAREG_CRTCEXT_INDEX, (mgaReg->ExtVga[0] << 8) | 0);
+
+MGA_NOT_HAL(
+ if (pMga->is_G200WB)
+ {
+ MGAG200WBRestoreFromModeSwitch(pScrn);
+ }
+);
+
} else {
/* Second Crtc */
xMODEINFO ModeInfo;
@@ -960,6 +1197,7 @@ MGA_NOT_HAL(
}
outMGAdac(i, mgaReg->dac2[ i - 0x80]);
}
+
); /* MGA_NOT_HAL */
}
@@ -1067,7 +1305,11 @@ MGAGSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg,
for (i = 0; i < DACREGSIZE; i++)
mgaReg->DacRegs[i] = inMGAdac(i);
- if (pMga->is_G200EV) {
+ if (pMga->is_G200WB) {
+ mgaReg->PllM = inMGAdac(MGA1064_WB_PIX_PLLC_M);
+ mgaReg->PllN = inMGAdac(MGA1064_WB_PIX_PLLC_N);
+ mgaReg->PllP = inMGAdac(MGA1064_WB_PIX_PLLC_P);
+ } else if (pMga->is_G200EV) {
mgaReg->PllM = inMGAdac(MGA1064_EV_PIX_PLLC_M);
mgaReg->PllN = inMGAdac(MGA1064_EV_PIX_PLLC_N);
mgaReg->PllP = inMGAdac(MGA1064_EV_PIX_PLLC_P);
@@ -1252,7 +1494,7 @@ static const struct mgag_i2c_private {
{ (1 << 1), (1 << 3) },
{ (1 << 0), (1 << 2) },
{ (1 << 4), (1 << 5) },
- { (1 << 0), (1 << 1) }, /* G200SE and G200EV I2C bits */
+ { (1 << 0), (1 << 1) }, /* G200SE, G200EV and G200WB I2C bits */
};
@@ -1353,9 +1595,15 @@ MGAG_i2cInit(ScrnInfoPtr pScrn)
I2CBusPtr I2CPtr;
if (pMga->SecondCrtc == FALSE) {
+ int i2c_index;
+
+ if (pMga->is_G200SE || pMga->is_G200WB || pMga->is_G200EV)
+ i2c_index = 3;
+ else
+ i2c_index = 0;
+
pMga->DDC_Bus1 = mgag_create_i2c_bus("DDC P1",
- (pMga->is_G200EV || pMga->is_G200SE) ? 3 : 0,
- pScrn->scrnIndex);
+ i2c_index, pScrn->scrnIndex);
return (pMga->DDC_Bus1 != NULL);
} else {
/* We have a dual head setup on G-series, set up DDC #2. */
diff --git a/src/mga_driver.c b/src/mga_driver.c
index 82239be..6f55e63 100644
--- a/src/mga_driver.c
+++ b/src/mga_driver.c
@@ -367,6 +367,23 @@ static const struct mga_device_attributes attribs[] = {
8192, 0x4000, /* Memory probe size & offset values */
},
+
+ /* G200WB */
+ [13] = { 0, 1, 0, 0, 1, 0, 0, 0, new_BARs,
+ (TRANSC_SOLID_FILL | TWO_PASS_COLOR_EXPAND | USE_LINEAR_EXPANSION),
+ {
+ { 50000, 230000 }, /* System VCO frequencies */
+ { 50000, 203400 }, /* Pixel VCO frequencies */
+ { 0, 0 }, /* Video VCO frequencies */
+ 45000, /* Memory clock */
+ 27050, /* PLL reference frequency */
+ 0, /* Supports fast bitblt? */
+ MGA_HOST_PCI /* Host interface */
+ },
+
+ 8192, 0x4000, /* Memory probe size & offset values */
+ },
+
};
#ifdef XSERVER_LIBPCIACCESS
@@ -392,6 +409,8 @@ static const struct pci_id_match mga_device_match[] = {
MGA_DEVICE_MATCH(PCI_CHIP_MGAG200_EV_PCI, 12),
+ MGA_DEVICE_MATCH( PCI_CHIP_MGAG200_WINBOND_PCI, 13 ),
+
{ 0, 0, 0 },
};
#endif
@@ -409,6 +428,7 @@ static SymTabRec MGAChipsets[] = {
{ PCI_CHIP_MGAG200_SE_A_PCI, "mgag200 SE A PCI" },
{ PCI_CHIP_MGAG200_SE_B_PCI, "mgag200 SE B PCI" },
{ PCI_CHIP_MGAG200_EV_PCI, "mgag200 Maxim" },
+ { PCI_CHIP_MGAG200_WINBOND_PCI, "mgag200 Winbond" },
{ PCI_CHIP_MGAG400, "mgag400" },
{ PCI_CHIP_MGAG550, "mgag550" },
{-1, NULL }
@@ -429,6 +449,8 @@ static PciChipsets MGAPciChipsets[] = {
(resRange*)RES_SHARED_VGA },
{ PCI_CHIP_MGAG200_EV_PCI, PCI_CHIP_MGAG200_EV_PCI,
(resRange*)RES_SHARED_VGA },
+ { PCI_CHIP_MGAG200_WINBOND_PCI, PCI_CHIP_MGAG200_WINBOND_PCI,
+ (resRange*)RES_SHARED_VGA },
{ PCI_CHIP_MGAG400, PCI_CHIP_MGAG400, (resRange*)RES_SHARED_VGA },
{ PCI_CHIP_MGAG550, PCI_CHIP_MGAG550, (resRange*)RES_SHARED_VGA },
{ -1, -1, (resRange*)RES_UNDEFINED }
@@ -501,6 +523,7 @@ static const OptionInfoRec MGAOptions[] = {
{ OPTION_OLDDMA, "OldDmaInit", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_PCIDMA, "ForcePciDma", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_ACCELMETHOD, "AccelMethod", OPTV_ANYSTR, {0}, FALSE },
+ { OPTION_KVM, "KVM", OPTV_BOOLEAN, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
@@ -1071,6 +1094,10 @@ MGAProbe(DriverPtr drv, int flags)
attrib_no = 12;
break;
+ case PCI_CHIP_MGAG200_WINBOND_PCI:
+ attrib_no = 13;
+ break;
+
default:
return FALSE;
}
@@ -1262,8 +1289,8 @@ MGACountRam(ScrnInfoPtr pScrn)
tmp = INREG8(MGAREG_CRTCEXT_DATA);
OUTREG8(MGAREG_CRTCEXT_DATA, tmp | 0x80);
- /* apparently the G200SE doesn't have a BIOS to read */
- if (pMga->is_G200SE || pMga->is_G200EV) {
+ /* apparently the G200 IP don't have a BIOS to read */
+ if (pMga->is_G200SE || pMga->is_G200EV || pMga->is_G200WB) {
CARD32 MemoryAt0, MemoryAt1, Offset;
CARD32 FirstMemoryVal1, FirstMemoryVal2;
CARD32 SecondMemoryVal1, SecondMemoryVal2;
@@ -1757,6 +1784,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
pMga->is_G200SE = (pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI)
|| (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI);
pMga->is_G200EV = (pMga->Chipset == PCI_CHIP_MGAG200_EV_PCI);
+ pMga->is_G200WB = (pMga->Chipset == PCI_CHIP_MGAG200_WINBOND_PCI);
#ifdef USEMGAHAL
if (pMga->chip_attribs->HAL_chipset) {
@@ -1942,6 +1970,11 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
pScrn->options = xf86ReplaceBoolOption(pScrn->options, "MTRR", FALSE);
}
}
+
+ if (pMga->is_G200WB && xf86ReturnOptValBool(pMga->Options, OPTION_KVM, TRUE)) {
+ pMga->KVM = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Enabling KVM\n");
+ }
#if !defined(__powerpc__)
pMga->softbooted = FALSE;
@@ -2171,6 +2204,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
case PCI_CHIP_MGAG200_PCI:
case PCI_CHIP_MGAG200_SE_A_PCI:
case PCI_CHIP_MGAG200_SE_B_PCI:
+ case PCI_CHIP_MGAG200_WINBOND_PCI:
case PCI_CHIP_MGAG200_EV_PCI:
case PCI_CHIP_MGAG400:
case PCI_CHIP_MGAG550:
@@ -2395,6 +2429,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
case PCI_CHIP_MGAG200_PCI:
case PCI_CHIP_MGAG200_SE_A_PCI:
case PCI_CHIP_MGAG200_SE_B_PCI:
+ case PCI_CHIP_MGAG200_WINBOND_PCI:
case PCI_CHIP_MGAG200_EV_PCI:
pMga->SrcOrg = 0;
pMga->DstOrg = 0;
@@ -2573,6 +2608,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
case PCI_CHIP_MGAG200_PCI:
case PCI_CHIP_MGAG200_SE_A_PCI:
case PCI_CHIP_MGAG200_SE_B_PCI:
+ case PCI_CHIP_MGAG200_WINBOND_PCI:
case PCI_CHIP_MGAG200_EV_PCI:
case PCI_CHIP_MGAG400:
case PCI_CHIP_MGAG550:
@@ -4468,6 +4504,13 @@ MGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
if (pMga->reg_1e24 == 0x01 &&
xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 256)
return MODE_BANDWIDTH;
+ } else if (pMga->is_G200WB){
+ if (pMga->KVM && mode->HDisplay > 1280)
+ return MODE_VIRTUAL_X;
+ if (pMga->KVM && mode->VDisplay > 1024)
+ return MODE_VIRTUAL_Y;
+ if (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 315)
+ return MODE_BANDWIDTH;
} else if (pMga->is_G200EV
&& (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 327)) {
return MODE_BANDWIDTH;
diff --git a/src/mga_merge.c b/src/mga_merge.c
index 3ba3f43..24bcbc1 100644
--- a/src/mga_merge.c
+++ b/src/mga_merge.c
@@ -361,6 +361,7 @@ MGAPreInitMergedFB(ScrnInfoPtr pScrn1, int flags)
case PCI_CHIP_MGAG200_PCI:
case PCI_CHIP_MGAG200_SE_A_PCI:
case PCI_CHIP_MGAG200_SE_B_PCI:
+ case PCI_CHIP_MGAG200_WINBOND_PCI:
case PCI_CHIP_MGAG200_EV_PCI:
case PCI_CHIP_MGAG400:
case PCI_CHIP_MGAG550:
@@ -514,6 +515,7 @@ MGAPreInitMergedFB(ScrnInfoPtr pScrn1, int flags)
case PCI_CHIP_MGAG200_PCI:
case PCI_CHIP_MGAG200_SE_A_PCI:
case PCI_CHIP_MGAG200_SE_B_PCI:
+ case PCI_CHIP_MGAG200_WINBOND_PCI:
case PCI_CHIP_MGAG200_EV_PCI:
case PCI_CHIP_MGAG400:
case PCI_CHIP_MGAG550:
diff --git a/src/mga_reg.h b/src/mga_reg.h
index 16df6c1..6450e2f 100644
--- a/src/mga_reg.h
+++ b/src/mga_reg.h
@@ -319,6 +319,7 @@
#define MGA1064_INDEX 0x00
#define MGA1064_WADR_PAL 0x00
+#define MGA1064_SPAREREG 0x00
#define MGA1064_COL_PAL 0x01
#define MGA1064_PIX_RD_MSK 0x02
#define MGA1064_RADR_PAL 0x03
@@ -382,6 +383,16 @@
#define MGA1064_SYS_PLL_N 0x2d
#define MGA1064_SYS_PLL_P 0x2e
#define MGA1064_SYS_PLL_STAT 0x2f
+
+#define MGA1064_REMHEADCTL 0x30
+#define MGA1064_REMHEADCTL_CLKDIS ( 0x01 << 0 )
+#define MGA1064_REMHEADCTL_CLKSL_OFF ( 0x00 << 1 )
+#define MGA1064_REMHEADCTL_CLKSL_PLL ( 0x01 << 1 )
+#define MGA1064_REMHEADCTL_CLKSL_PCI ( 0x02 << 1 )
+#define MGA1064_REMHEADCTL_CLKSL_MSK ( 0x03 << 1 )
+
+#define MGA1064_REMHEADCTL2 0x31
+
#define MGA1064_ZOOM_CTL 0x38
#define MGA1064_SENSE_TST 0x3a
@@ -411,7 +422,12 @@
#define MGA1064_VID_PLL_M 0x8E
#define MGA1064_VID_PLL_N 0x8F
-/* Modified for G200 Maxim (G200EV) */
+/* Modified PLL for G200 Winbond (G200WB) */
+#define MGA1064_WB_PIX_PLLC_M 0xb7
+#define MGA1064_WB_PIX_PLLC_N 0xb6
+#define MGA1064_WB_PIX_PLLC_P 0xb8
+
+/* Modified PLL for G200 Maxim (G200EV) */
#define MGA1064_EV_PIX_PLLC_M 0xb6
#define MGA1064_EV_PIX_PLLC_N 0xb7
#define MGA1064_EV_PIX_PLLC_P 0xb8
diff --git a/src/mga_storm.c b/src/mga_storm.c
index 076b2f0..aa6ad82 100644
--- a/src/mga_storm.c
+++ b/src/mga_storm.c
@@ -1128,6 +1128,7 @@ void MGAStormEngineInit( ScrnInfoPtr pScrn )
case PCI_CHIP_MGAG200_PCI:
case PCI_CHIP_MGAG200_SE_A_PCI:
case PCI_CHIP_MGAG200_SE_B_PCI:
+ case PCI_CHIP_MGAG200_WINBOND_PCI:
case PCI_CHIP_MGAG200_EV_PCI:
pMga->SrcOrg = 0;
OUTREG(MGAREG_SRCORG, pMga->realSrcOrg);