From 630390dc5b892941ed6609ca5c35b90be53333f7 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Wed, 28 Mar 2007 11:07:49 -0400 Subject: Fix various timing bugs on the G200SE. --- src/mga.h | 29 ++++++++ src/mga_dacG.c | 13 ++-- src/mga_driver.c | 63 ++++++++++++++--- src/mga_vga.c | 207 +++++++++++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 269 insertions(+), 43 deletions(-) diff --git a/src/mga.h b/src/mga.h index 61e8729..156ac81 100644 --- a/src/mga.h +++ b/src/mga.h @@ -147,6 +147,32 @@ void MGAdbg_outreg32(ScrnInfoPtr, int,int, char*); outMGAdreg(MGA1064_DATA, tmp | (val)); \ } while (0) +#define MGAWAITVSYNC() \ + do { \ + unsigned int count = 0; \ + unsigned int status = 0; \ + do { \ + status = INREG( MGAREG_Status ); \ + count++; \ + } while( ( status & 0x08 ) && (count < 250000) );\ + count = 0; \ + status = 0; \ + do { \ + status = INREG( MGAREG_Status ); \ + count++; \ + } while( !( status & 0x08 ) && (count < 250000) );\ + } while (0) + +#define MGAWAITBUSY() \ + do { \ + unsigned int count = 0; \ + unsigned int status = 0; \ + do { \ + status = INREG8( MGAREG_Status + 2 ); \ + count++; \ + } while( ( status & 0x01 ) && (count < 500000) ); \ + } while (0) + #define PORT_OFFSET (0x1F00 - 0x300) #define MGA_VERSION 4000 @@ -693,6 +719,9 @@ long MGAG450SavePLLFreq(ScrnInfoPtr pScrn); void MGAprintDac(ScrnInfoPtr pScrn); void MGAG200SESaveFonts(ScrnInfoPtr, vgaRegPtr); void MGAG200SERestoreFonts(ScrnInfoPtr, vgaRegPtr); +void MGAG200SESaveMode(ScrnInfoPtr, vgaRegPtr); +void MGAG200SERestoreMode(ScrnInfoPtr, vgaRegPtr); +void MGAG200SEHWProtect(ScrnInfoPtr, Bool); #ifdef USEMGAHAL /************ ESC Call Definition ***************/ diff --git a/src/mga_dacG.c b/src/mga_dacG.c index 168959b..99eff18 100644 --- a/src/mga_dacG.c +++ b/src/mga_dacG.c @@ -422,11 +422,9 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode) MGA1064_MISC_CTL_VGA8 | MGA1064_MISC_CTL_DAC_RAM_CS; - if(pMga->HasSDRAM) - pReg->Option = 0x40499121; - else - pReg->Option = 0x4049cd21; - pReg->Option2 = 0x00008000; + if (pMga->HasSDRAM) + pReg->Option = 0x40049120; + pReg->Option2 = 0x00008000; break; case PCI_CHIP_MGAG200: case PCI_CHIP_MGAG200_PCI: @@ -810,7 +808,7 @@ MGA_NOT_HAL( /* This handles restoring the generic VGA registers. */ if (pMga->is_G200SE) { - vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); + MGAG200SERestoreMode(pScrn, vgaReg); if (restoreFonts) MGAG200SERestoreFonts(pScrn, vgaReg); } else { @@ -910,7 +908,7 @@ MGAGSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, * in the generic VGA portion. */ if (pMga->is_G200SE) { - vgaHWSave(pScrn, vgaReg, VGA_SR_MODE); + MGAG200SESaveMode(pScrn, vgaReg); if (saveFonts) MGAG200SESaveFonts(pScrn, vgaReg); } else { @@ -962,6 +960,7 @@ MGAGSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, OUTREG8(MGAREG_CRTCEXT_INDEX, i); mgaReg->ExtVga[i] = INREG8(MGAREG_CRTCEXT_DATA); } + #ifdef DEBUG ErrorF("Saved values:\nDAC:"); for (i=0; iFbBase; + if (pMga->is_G200SE) { + OUTREG8(MGAREG_SEQ_INDEX, 0x01); + seq1 = INREG8(MGAREG_SEQ_DATA); + seq1 |= 0x20; + MGAWAITVSYNC(); + MGAWAITBUSY(); + OUTREG8(MGAREG_SEQ_DATA, seq1); + usleep(20000); + } + /* turn MGA mode on - enable linear frame buffer (CRTCEXT3) */ OUTREG8(MGAREG_CRTCEXT_INDEX, 3); tmp = INREG8(MGAREG_CRTCEXT_DATA); @@ -841,7 +852,7 @@ MGACountRam(ScrnInfoPtr pScrn) base[1] = 0; for (Offset = 0x100000; Offset < (ProbeSize * 1024); - Offset += 0x1000) { + Offset += 0x1000) { FirstMemoryVal1 = base[Offset]; FirstMemoryVal2 = base[Offset+1]; SecondMemoryVal1 = base[Offset+0x100]; @@ -896,8 +907,17 @@ MGACountRam(ScrnInfoPtr pScrn) OUTREG8(MGAREG_CRTCEXT_INDEX, 3); OUTREG8(MGAREG_CRTCEXT_DATA, tmp); + if (pMga->is_G200SE) { + OUTREG8(MGAREG_SEQ_INDEX, 0x01); + seq1 = INREG8(MGAREG_SEQ_DATA); + seq1 &= ~0x20; + MGAWAITVSYNC(); + MGAWAITBUSY(); + OUTREG8(MGAREG_SEQ_DATA, seq1); + usleep(20000); + } MGAUnmapMem(pScrn); - } + } return SizeFound; } @@ -2787,7 +2807,11 @@ MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) return FALSE; /* Program the registers */ - vgaHWProtect(pScrn, TRUE); + if (pMga->is_G200SE) { + MGAG200SEHWProtect(pScrn, TRUE); + } else { + vgaHWProtect(pScrn, TRUE); + } vgaReg = &hwp->ModeReg; mgaReg = &pMga->ModeReg; #ifdef USEMGAHAL @@ -2903,7 +2927,11 @@ MGA_HAL( MGAStormSync(pScrn); MGAStormEngineInit(pScrn); - vgaHWProtect(pScrn, FALSE); + if (pMga->is_G200SE) { + MGAG200SEHWProtect(pScrn,FALSE); + } else { + vgaHWProtect(pScrn, FALSE); + } if (xf86IsPc98()) { if (pMga->Chipset == PCI_CHIP_MGA2064) @@ -2912,6 +2940,13 @@ MGA_HAL( outb(0xfac, 0x02); } + MGA_NOT_HAL( + if (pMga->is_G200SE) { + OUTREG8(0x1FDE, 0x06); + OUTREG8(0x1FDF, 0x14); + } + ); + pMga->CurrentLayout.mode = mode; if(pMga->MergedFB && mode->Private && (mode->PrivSize == 0)) { @@ -3008,7 +3043,11 @@ MGARestore(ScrnInfoPtr pScrn) } /* Only restore text mode fonts/text for the primary card */ - vgaHWProtect(pScrn, TRUE); + if (pMga->is_G200SE) { + MGAG200SEHWProtect(pScrn,TRUE); + } else { + vgaHWProtect(pScrn, TRUE); + } if (pMga->Primary) { #ifdef USEMGAHAL MGA_HAL( @@ -3022,7 +3061,12 @@ MGARestore(ScrnInfoPtr pScrn) } else { vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); } - vgaHWProtect(pScrn, FALSE); + + if (pMga->is_G200SE) { + MGAG200SEHWProtect(pScrn,FALSE); + } else { + vgaHWProtect(pScrn,FALSE); + } } @@ -3313,8 +3357,7 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) * InitGLXVisuals call back. * The DRI does not work when textured video is enabled at this time. */ - if ((pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) || - (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI)) { + if (pMga->is_G200SE) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Not supported by hardware, not initializing the DRI\n"); pMga->directRenderingEnabled = FALSE; @@ -4060,10 +4103,14 @@ MGADisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, crtcext1 = 0x30; break; } + /* XXX Prefer an implementation that doesn't depend on VGA specifics */ OUTREG8(MGAREG_SEQ_INDEX, 0x01); /* Select SEQ1 */ seq1 |= INREG8(MGAREG_SEQ_DATA) & ~0x20; + MGAWAITVSYNC(); + MGAWAITBUSY(); OUTREG8(MGAREG_SEQ_DATA, seq1); + usleep(20000); OUTREG8(MGAREG_CRTCEXT_INDEX, 0x01); /* Select CRTCEXT1 */ crtcext1 |= INREG8(MGAREG_CRTCEXT_DATA) & ~0x30; OUTREG8(MGAREG_CRTCEXT_DATA, crtcext1); diff --git a/src/mga_vga.c b/src/mga_vga.c index fbbfc60..8dfc08f 100644 --- a/src/mga_vga.c +++ b/src/mga_vga.c @@ -4,6 +4,8 @@ #include "vgaHW.h" #include "compiler.h" #include "xf86cmap.h" +#include "mga.h" +#include "mga_reg.h" #define TEXT_AMOUNT 16384 #define FONT_AMOUNT (8*8192) @@ -12,9 +14,11 @@ void MGAG200SERestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore) { vgaHWPtr hwp = VGAHWPTR(scrninfp); + MGAPtr pMga = MGAPTR(scrninfp); int savedIOBase; unsigned char miscOut, attr10, gr1, gr3, gr4, gr5, gr6, gr8, seq2, seq4; Bool doMap = FALSE; + unsigned char scrn; /* If nothing to do, return now */ if (!hwp->FontInfo1 && !hwp->FontInfo2 && !hwp->TextInfo) @@ -48,7 +52,14 @@ MGAG200SERestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore) /* Force into colour mode */ hwp->writeMiscOut(hwp, miscOut | 0x01); - vgaHWBlankScreen(scrninfp, FALSE); + scrn = hwp->readSeq(hwp, 0x01); + scrn |= 0x20;/* blank screen */ + vgaHWSeqReset(hwp, TRUE); + MGAWAITVSYNC(); + MGAWAITBUSY(); + hwp->writeSeq(hwp, 0x01, scrn);/* change mode */ + usleep(20000); + vgaHWSeqReset(hwp, FALSE); /* * here we temporarily switch to 16 colour planar mode, to simply @@ -66,36 +77,28 @@ MGAG200SERestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore) hwp->writeGr(hwp, 0x01, 0x00); /* all planes come from CPU */ } + hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ + hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ + hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ + if (hwp->FontInfo1) { hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */ - hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */ - hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ - hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ slowbcopy_tobus(hwp->FontInfo1, hwp->Base, FONT_AMOUNT); } if (hwp->FontInfo2) { hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */ - hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */ - hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ - hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ slowbcopy_tobus(hwp->FontInfo2, hwp->Base, FONT_AMOUNT); } if (hwp->TextInfo) { hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */ - hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */ - hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ - hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ slowbcopy_tobus(hwp->TextInfo, hwp->Base, TEXT_AMOUNT); hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */ - hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */ - hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ - hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ slowbcopy_tobus((unsigned char *)hwp->TextInfo + TEXT_AMOUNT, hwp->Base, TEXT_AMOUNT); } @@ -113,7 +116,14 @@ MGAG200SERestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore) hwp->writeSeq(hwp, 0x04, seq4); hwp->IOBase = savedIOBase; - vgaHWBlankScreen(scrninfp, TRUE); + scrn = hwp->readSeq(hwp, 0x01); + scrn &= ~0x20;/* enable screen */ + vgaHWSeqReset(hwp, TRUE); + MGAWAITVSYNC(); + MGAWAITBUSY(); + hwp->writeSeq(hwp, 0x01, scrn);/* change mode */ + usleep(20000); + vgaHWSeqReset(hwp, FALSE); if (doMap) vgaHWUnmapMem(scrninfp); @@ -124,9 +134,11 @@ void MGAG200SESaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save) { vgaHWPtr hwp = VGAHWPTR(scrninfp); + MGAPtr pMga = MGAPTR(scrninfp); int savedIOBase; unsigned char miscOut, attr10, gr4, gr5, gr6, seq2, seq4; Bool doMap = FALSE; + unsigned char scrn; if (hwp->Base == NULL) { doMap = TRUE; @@ -157,7 +169,14 @@ MGAG200SESaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save) /* Force into colour mode */ hwp->writeMiscOut(hwp, miscOut | 0x01); - vgaHWBlankScreen(scrninfp, FALSE); + scrn = hwp->readSeq(hwp, 0x01); + scrn |= 0x20;/* blank screen */ + vgaHWSeqReset(hwp, TRUE); + MGAWAITVSYNC(); + MGAWAITBUSY(); + hwp->writeSeq(hwp, 0x01, scrn);/* change mode */ + usleep(20000); + vgaHWSeqReset(hwp, FALSE); /* * get the character sets, and text screen if required @@ -171,34 +190,25 @@ MGAG200SESaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save) #if 0 hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */ #endif + hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ + hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ + hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ if (hwp->FontInfo1 || (hwp->FontInfo1 = xalloc(FONT_AMOUNT))) { hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */ - hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */ - hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ - hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ slowbcopy_frombus(hwp->Base, hwp->FontInfo1, FONT_AMOUNT); } if (hwp->FontInfo2 || (hwp->FontInfo2 = xalloc(FONT_AMOUNT))) { hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */ - hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */ - hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ - hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ slowbcopy_frombus(hwp->Base, hwp->FontInfo2, FONT_AMOUNT); } if (hwp->TextInfo || (hwp->TextInfo = xalloc(2 * TEXT_AMOUNT))) { hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */ - hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */ - hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ - hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ slowbcopy_frombus(hwp->Base, hwp->TextInfo, TEXT_AMOUNT); hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */ - hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */ - hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ - hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ slowbcopy_frombus(hwp->Base, (unsigned char *)hwp->TextInfo + TEXT_AMOUNT, TEXT_AMOUNT); } @@ -213,8 +223,149 @@ MGAG200SESaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save) hwp->writeMiscOut(hwp, miscOut); hwp->IOBase = savedIOBase; - vgaHWBlankScreen(scrninfp, TRUE); + scrn = hwp->readSeq(hwp, 0x01); + scrn &= ~0x20;/* enable screen */ + vgaHWSeqReset(hwp, TRUE); + MGAWAITVSYNC(); + MGAWAITBUSY(); + hwp->writeSeq(hwp, 0x01, scrn);/* change mode */ + usleep(20000); + vgaHWSeqReset(hwp, FALSE); if (doMap) vgaHWUnmapMem(scrninfp); } + +void +MGAG200SERestoreMode(ScrnInfoPtr scrninfp, vgaRegPtr restore) +{ + vgaHWPtr hwp = VGAHWPTR(scrninfp); + MGAPtr pMga = MGAPTR(scrninfp); + int i; + unsigned char scrn; + + if (restore->MiscOutReg & 0x01) + hwp->IOBase = VGA_IOBASE_COLOR; + else + hwp->IOBase = VGA_IOBASE_MONO; + + hwp->writeMiscOut(hwp, restore->MiscOutReg); + + + for (i = 1; i < restore->numSequencer; i++) + { + MGAWAITVSYNC(); + MGAWAITBUSY(); + hwp->writeSeq(hwp, i, restore->Sequencer[i]); + usleep(20000); + } + + scrn = hwp->readSeq(hwp, 0x01); + scrn |= 0x20;/* blank screen */ + vgaHWSeqReset(hwp, TRUE); + MGAWAITVSYNC(); + MGAWAITBUSY(); + hwp->writeSeq(hwp, 0x01, scrn);/* change mode */ + usleep(20000); + + /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */ + hwp->writeCrtc(hwp, 17, restore->CRTC[17] & ~0x80); + + for (i = 0; i < restore->numCRTC; i++) + hwp->writeCrtc(hwp, i, restore->CRTC[i]); + + for (i = 0; i < restore->numGraphics; i++) + hwp->writeGr(hwp, i, restore->Graphics[i]); + + hwp->enablePalette(hwp); + for (i = 0; i < restore->numAttribute; i++) + hwp->writeAttr(hwp, i, restore->Attribute[i]); + hwp->disablePalette(hwp); + + MGAWAITVSYNC(); + MGAWAITBUSY(); + hwp->writeSeq(hwp, 1, restore->Sequencer[1]); + usleep(20000); +} + +void +MGAG200SESaveMode(ScrnInfoPtr scrninfp, vgaRegPtr save) +{ + vgaHWPtr hwp = VGAHWPTR(scrninfp); + int i; + + save->MiscOutReg = hwp->readMiscOut(hwp); + if (save->MiscOutReg & 0x01) + hwp->IOBase = VGA_IOBASE_COLOR; + else + hwp->IOBase = VGA_IOBASE_MONO; + + for (i = 0; i < save->numCRTC; i++) { + save->CRTC[i] = hwp->readCrtc(hwp, i); +#ifdef DEBUG + ErrorF("CRTC[0x%02x] = 0x%02x\n", i, save->CRTC[i]); +#endif + } + + hwp->enablePalette(hwp); + for (i = 0; i < save->numAttribute; i++) { + save->Attribute[i] = hwp->readAttr(hwp, i); +#ifdef DEBUG + ErrorF("Attribute[0x%02x] = 0x%02x\n", i, save->Attribute[i]); +#endif + } + hwp->disablePalette(hwp); + + for (i = 0; i < save->numGraphics; i++) { + save->Graphics[i] = hwp->readGr(hwp, i); +#ifdef DEBUG + ErrorF("Graphics[0x%02x] = 0x%02x\n", i, save->Graphics[i]); +#endif + } + + for (i = 1; i < save->numSequencer; i++) { + save->Sequencer[i] = hwp->readSeq(hwp, i); +#ifdef DEBUG + ErrorF("Sequencer[0x%02x] = 0x%02x\n", i, save->Sequencer[i]); +#endif + } +} + +void +MGAG200SEHWProtect(ScrnInfoPtr pScrn, Bool on) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + MGAPtr pMga = MGAPTR(pScrn); + + unsigned char tmp; + + if (pScrn->vtSema) { + if (on) { + /* + * Turn off screen and disable sequencer. + */ + tmp = hwp->readSeq(hwp, 0x01); + + vgaHWSeqReset(hwp, TRUE); /* start synchronous reset */ + MGAWAITVSYNC(); + MGAWAITBUSY(); + hwp->writeSeq(hwp, 0x01, tmp | 0x20); /* disable the display */ + usleep(20000); + hwp->enablePalette(hwp); + } else { + /* + * Reenable sequencer, then turn on screen. + */ + + tmp = hwp->readSeq(hwp, 0x01); + + MGAWAITVSYNC(); + MGAWAITBUSY(); + hwp->writeSeq(hwp, 0x01, tmp & ~0x20); /* reenable display */ + usleep(20000); + vgaHWSeqReset(hwp, FALSE); /* clear synchronousreset */ + + hwp->disablePalette(hwp); + } + } +} -- cgit v1.2.3