diff options
author | Adam Jackson <ajax@nwnk.net> | 2006-04-02 01:03:50 +0000 |
---|---|---|
committer | Adam Jackson <ajax@nwnk.net> | 2006-04-02 01:03:50 +0000 |
commit | 07373669514b104a11fb1b4ed5214f3764c83a2f (patch) | |
tree | 79180b5c1bb8ee011b4bf7a829f57ae55f832c59 /src/mga_dacG.c | |
parent | 88ece3c37c4ed529686b6cdea1bf9b6eed8fceea (diff) |
Bug #6328: Add support for Matrox G200SE chips. (Matrox)
Diffstat (limited to 'src/mga_dacG.c')
-rw-r--r-- | src/mga_dacG.c | 120 |
1 files changed, 107 insertions, 13 deletions
diff --git a/src/mga_dacG.c b/src/mga_dacG.c index 728dd89..9d10811 100644 --- a/src/mga_dacG.c +++ b/src/mga_dacG.c @@ -60,6 +60,52 @@ static Bool MGAGInit(ScrnInfoPtr, DisplayModePtr); static void MGAGLoadPalette(ScrnInfoPtr, int, int*, LOCO*, VisualPtr); static Bool MGAG_i2cInit(ScrnInfoPtr pScrn); +static void +MGAG200SEComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P) +{ + unsigned int ulComputedFo; + unsigned int ulFDelta; + unsigned int ulFPermitedDelta; + unsigned int ulFTmpDelta; + unsigned int ulVCOMax, ulVCOMin; + unsigned int ulTestP; + unsigned int ulTestM; + unsigned int ulTestN; + unsigned int ulPLLFreqRef; + + ulVCOMax = 320000; + ulVCOMin = 160000; + ulPLLFreqRef = 25000; + + ulFDelta = 0xFFFFFFFF; + /* Permited delta is 0.5% as VESA Specification */ + ulFPermitedDelta = lFo * 5 / 1000; + + /* Then we need to minimize the M while staying within 0.5% */ + for (ulTestP = 8; ulTestP > 0; ulTestP >>= 1) { + if ((lFo * ulTestP) > ulVCOMax) continue; + if ((lFo * ulTestP) < ulVCOMin) continue; + + for (ulTestN = 17; ulTestN <= 256; ulTestN++) { + for (ulTestM = 1; ulTestM <= 32; ulTestM++) { + ulComputedFo = (ulPLLFreqRef * ulTestN) / (ulTestM * ulTestP); + if (ulComputedFo > lFo) + ulFTmpDelta = ulComputedFo - lFo; + else + ulFTmpDelta = lFo - ulComputedFo; + + if (ulFTmpDelta < ulFDelta) { + ulFDelta = ulFTmpDelta; + *M = ulTestM - 1; + *N = ulTestN - 1; + *P = ulTestP - 1; + } + } + } + } +} + + /** * Calculate the PLL settings (m, n, p, s). * @@ -104,6 +150,8 @@ MGAGCalcClock ( ScrnInfoPtr pScrn, long f_out, in_div_max = 31; post_div_max = 7; break; + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: case PCI_CHIP_MGAG100: case PCI_CHIP_MGAG100_PCI: case PCI_CHIP_MGAG200: @@ -193,13 +241,23 @@ MGAGSetPCLK( ScrnInfoPtr pScrn, long f_out ) return; } - /* Do the calculations for m, n, p and s */ - MGAGCalcClock( pScrn, f_out, &m, &n, &p, &s ); + if ((pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) || + (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI)) { + MGAG200SEComputePLLParam(pScrn, f_out, &m, &n, &p); - /* Values for the pixel clock PLL registers */ - pReg->DacRegs[ MGA1064_PIX_PLLC_M ] = m & 0x1F; - pReg->DacRegs[ MGA1064_PIX_PLLC_N ] = n & 0x7F; - pReg->DacRegs[ MGA1064_PIX_PLLC_P ] = (p & 0x07) | ((s & 0x03) << 3); + pReg->DacRegs[ MGA1064_PIX_PLLC_M ] = m; + pReg->DacRegs[ MGA1064_PIX_PLLC_N ] = n; + pReg->DacRegs[ MGA1064_PIX_PLLC_P ] = p; + } else { + /* Do the calculations for m, n, p and s */ + MGAGCalcClock( pScrn, f_out, &m, &n, &p, &s ); + + /* Values for the pixel clock PLL registers */ + pReg->DacRegs[ MGA1064_PIX_PLLC_M ] = m & 0x1F; + pReg->DacRegs[ MGA1064_PIX_PLLC_N ] = n & 0x7F; + pReg->DacRegs[ MGA1064_PIX_PLLC_P ] = (p & 0x07) | + ((s & 0x03) << 3); + } } /* @@ -349,6 +407,20 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode) pReg->Option &= ~(1 << 14); pReg->Option2 = 0x01003000; break; + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: +#ifdef USEMGAHAL + MGA_HAL(break;); +#endif + pReg->DacRegs[ MGA1064_VREF_CTL ] = 0x03; + pReg->DacRegs[ MGA1064_PIX_CLK_CTL ] = 0x01; + pReg->DacRegs[ MGA1064_MISC_CTL ] = 0x19; + if(pMga->HasSDRAM) + pReg->Option = 0x40499121; + else + pReg->Option = 0x4049cd21; + pReg->Option2 = 0x00008000; + break; case PCI_CHIP_MGAG200: case PCI_CHIP_MGAG200_PCI: default: @@ -688,6 +760,10 @@ MGA_NOT_HAL( ((i == 0x2c) || (i == 0x2d) || (i == 0x2e) || (i == 0x4c) || (i == 0x4d) || (i == 0x4e)))) continue; + if (((pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) || + (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI)) && + (i == 0x2C) || (i == 0x2D) || (i == 0x2E)) + continue; outMGAdac(i, mgaReg->DacRegs[i]); } @@ -722,11 +798,16 @@ MGA_NOT_HAL( for (i = 0; i < 6; i++) OUTREG16(0x1FDE, (mgaReg->ExtVga[i] << 8) | i); - /* - * This function handles restoring the generic VGA registers. - */ - vgaHWRestore(pScrn, vgaReg, + /* This handles restoring the generic VGA registers. */ + if ((pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) || + (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI)) { + vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); + if (restoreFonts) + MGAG200SERestoreFonts(pScrn, vgaReg); + } else { + vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE | (restoreFonts ? VGA_SR_FONTS : 0)); + } MGAGRestorePalette(pScrn, vgaReg->DAC); /* @@ -819,7 +900,15 @@ MGAGSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, * This function will handle creating the data structure and filling * in the generic VGA portion. */ - vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | (saveFonts ? VGA_SR_FONTS : 0)); + if ((pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) || + (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI)) { + vgaHWSave(pScrn, vgaReg, VGA_SR_MODE); + if (saveFonts) + MGAG200SESaveFonts(pScrn, vgaReg); + } else { + vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | + (saveFonts ? VGA_SR_FONTS : 0)); + } MGAGSavePalette(pScrn, vgaReg->DAC); /* * Work around another bug in HALlib: it doesn't restore the @@ -1024,8 +1113,13 @@ MGAG_ddc1Read(ScrnInfoPtr pScrn) outMGAdacmsk(MGA1064_GEN_IO_CTL, ~(DDC_P1_SCL_MASK | DDC_P1_SDA_MASK), 0); /* wait for Vsync */ - while( INREG( MGAREG_Status ) & 0x08 ); - while( ! (INREG( MGAREG_Status ) & 0x08) ); + if ((pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) || + (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI)) { + usleep(4); + } else { + while( INREG( MGAREG_Status ) & 0x08 ); + while( ! (INREG( MGAREG_Status ) & 0x08) ); + } /* Get the result */ val = (inMGAdac(MGA1064_GEN_IO_DATA) & DDC_P1_SDA_MASK); |