📄 s3ramdacs.c
字号:
} } else if (S3_964_SERIES(s3ChipId) || S3_968_SERIES(s3ChipId)) { nonMuxMaxClock = 0; /* 964 can only be in pixmux mode when */ pixMuxMinWidth = 0; /* working in enhanced mode */ pixMuxLimitedWidths = FALSE; pixMuxNeeded = TRUE; } else { nonMuxMaxClock = 85000; } } /* If there is an internal clock, set s3ClockSelectFunc, maxRawClock numClocks and whatever options need to be set. For external clocks, pass the job to OtherClocksSetup() */ /* Diamond Stealth 64 VRAM uses an ICD2061A */ if (!OFLG_ISSET(CLOCK_OPTION_PROGRAMABLE, &s3InfoRec.clockOptions) && (s3BiosVendor == DIAMOND_BIOS) && S3_964_ONLY(s3ChipId)) { OFLG_SET(CLOCK_OPTION_ICD2061A, &s3InfoRec.clockOptions); OFLG_SET(CLOCK_OPTION_PROGRAMABLE, &s3InfoRec.clockOptions); clockchip_probed = XCONFIG_PROBED; } OtherClocksSetup(); /* setup clock */ /* Make any necessary clock alterations due to multiplexing, clock doubling, etc... s3Probe will do some last minute clock sanity checks when we return */ if(s3RamdacType == BT485_DAC) { if (maxRawClock > 67500) clockDoublingPossible = TRUE; /* These limits are based on the LCLK rating, and may be too high */ if (s3Bt485PixMux && s3Bpp < 4) s3InfoRec.maxClock = s3InfoRec.dacSpeeds[0]; else { if (s3InfoRec.dacSpeeds[0] < 150000) /* 110 and 135 */ s3InfoRec.maxClock = 90000; else /* 150 and 170 (if they exist) */ s3InfoRec.maxClock = 110000; } } else { /* ATT20C505_DAC */ if (maxRawClock > 90000) clockDoublingPossible = TRUE; /* These limits are based on the LCLK rating, and may be too high */ if (s3Bt485PixMux && s3Bpp < 4) s3InfoRec.maxClock = s3InfoRec.dacSpeeds[0]; else { if (s3InfoRec.dacSpeeds[0] < 110000) /* 85 */ s3InfoRec.maxClock = 85000; else if (s3InfoRec.dacSpeeds[0] < 135000) /* 110 */ s3InfoRec.maxClock = 90000; else /* 135, 150, 170 */ s3InfoRec.maxClock = 110000; } } return 1;}static void BT485_Restore(){ unsigned char tmp; /* Turn off parallel mode explicitly here */ if (s3Bt485PixMux) { if (OFLG_ISSET(OPTION_SPEA_MERCURY, &s3InfoRec.options) && S3_928_ONLY(s3ChipId)) { outb(vgaCRIndex, 0x5C); outb(vgaCRReg, 0x20); outb(0x3C7, 0x00); /* set s3 reg53 to non-parallel addressing by and'ing 0xDF */ outb(vgaCRIndex, 0x53); tmp = inb(vgaCRReg); outb(vgaCRReg, tmp & 0xDF); outb(vgaCRIndex, 0x5C); outb(vgaCRReg, 0x00); } if (OFLG_ISSET(OPTION_MIRO_MAGIC_S4, &s3InfoRec.options) && S3_928_ONLY(s3ChipId)) { outb(vgaCRIndex, 0x5C); outb(vgaCRReg, 0x40); /* XXXXXXXXXXXXXXXXXXXXX */ outb(0x3C7, 0x00); /* set s3 reg53 to non-parallel addressing by and'ing 0xDF */ outb(vgaCRIndex, 0x53); tmp = inb(vgaCRReg); outb(vgaCRReg, tmp & 0xDF); } } s3OutBtReg(BT_COMMAND_REG_0, 0xFE, 0x01); s3OutBtRegCom3(0x00, s3DacRegs[3]); if (s3Bt485PixMux) { s3OutBtReg(BT_COMMAND_REG_2, 0x00, s3DacRegs[2]); s3OutBtReg(BT_COMMAND_REG_1, 0x00, s3DacRegs[1]); } s3OutBtReg(BT_COMMAND_REG_0, 0x00, s3DacRegs[0]); }static void BT485_Save(){ s3DacRegs[0] = s3InBtReg(BT_COMMAND_REG_0); if (s3Bt485PixMux) { s3DacRegs[1] = s3InBtReg(BT_COMMAND_REG_1); s3DacRegs[2] = s3InBtReg(BT_COMMAND_REG_2); } s3DacRegs[3] = s3InBtRegCom3();}static int BT485_Init(DisplayModePtr mode){ register unsigned char tmp, tmp2 = 0; outb(0x3C4, 1); tmp = inb(0x3C5); outb(0x3C5, tmp | 0x20); /* blank the screen */ s3OutBtReg(BT_COMMAND_REG_0, 0xFE, 0x01); /* sleep mode */ if (s3Bt485PixMux) { if (s3PixelMultiplexing) { /* fun timing mods for pixel-multiplexing! Pixel Multiplexing is selected for 16bpp, 32bpp, or 8bpp with Width > 1024. Pixel Multiplexing requires we also Select Parallel VRAM Addressing (CR53.5), and Parallel VRAM Addressing also requires a line width of 1024 or 2048, external SID enabled (CR55.3), and split transfers disabled (CR51.6). */ if (OFLG_ISSET(OPTION_STB_PEGASUS, &s3InfoRec.options) || OFLG_ISSET(OPTION_MIRO_MAGIC_S4, &s3InfoRec.options)) { outb(vgaCRIndex, 0x53); tmp = inb(vgaCRReg); outb(vgaCRReg, tmp | 0x20); } if (OFLG_ISSET(OPTION_SPEA_MERCURY, &s3InfoRec.options) && S3_928_ONLY(s3ChipId)) { outb(vgaCRIndex, 0x5C); outb(vgaCRReg, 0x20); outb(0x3C7, 0x21); /* set s3 reg53 to parallel addressing by or'ing 0x20 */ outb(vgaCRIndex, 0x53); tmp = inb(vgaCRReg); outb(vgaCRReg, tmp | 0x20); outb(vgaCRIndex, 0x5C); outb(vgaCRReg, 0x00); } /* set s3 reg55 to external serial by or'ing 0x08 */ outb(vgaCRIndex, 0x55); tmp = inb(vgaCRReg); /* XXXX Something should be masked here */ if (s3InfoRec.bitsPerPixel == 32 && !OFLG_ISSET(OPTION_MIRO_MAGIC_S4,&s3InfoRec.options)) /* 24bpp truecolor */ tmp |= 0x48; else tmp |= 0x08; outb(vgaCRReg, tmp); if (S3_964_SERIES(s3ChipId) || S3_968_SERIES(s3ChipId)) { /* Stealth 64 and Miro Crystal 20SV */ outb(vgaCRIndex, 0x66); tmp = inb(vgaCRReg) & 0xc0; if (mode->Flags & V_DBLCLK) { /* Set VCLK = DCLCK/2 */ /* And set up a 32 bit interleaved bus */ if (s3Bpp == 1) tmp |= 0x11; else tmp |= 0x10; /* 16bpp */ } else { if (s3Bpp == 1) tmp |= 0x12; else if (s3Bpp == 2) tmp |= 0x11; else tmp |= 0x10; /* for 20SV, Stealth needs 0x10 ? */ } outb(vgaCRReg, tmp); /* blank_delay = 0 (at least for Miro Crystal 20SV) */ outb(vgaCRIndex, 0x6d); if ((mode->Flags & V_DBLCLK) || s3Bpp > 1) outb(vgaCRReg, 0); else outb(vgaCRReg, 1); /* or 2; needed for 20SV with ATT 20C505 */ } outb(vgaCRIndex, 0x65); tmp = inb(vgaCRReg); if (OFLG_ISSET(OPTION_STB_PEGASUS, &s3InfoRec.options)) /* Setting this register non-zero on the Pegasus causes a wrap of the rightmost pixels back to the left of the display. */ outb(vgaCRReg, 0x00); else if (!(OFLG_ISSET(OPTION_SPEA_MERCURY, &s3InfoRec.options) && S3_928_ONLY(s3ChipId))) { outb(vgaCRReg, tmp | 0x20); /* set s3 reg65 for some unknown reason */ /* Setting this for the SPEA Mercury affects clocks > 120MHz */ } else if (OFLG_ISSET(OPTION_MIRO_MAGIC_S4, &s3InfoRec.options)) { /* do nothing */ ; } else if ((s3DisplayWidth >= 1024) || (s3InfoRec.depth == 24) || (s3InfoRec.depth == 32)) {#ifndef PC98_PW outb(vgaCRReg, tmp | 0x40);#else outb(vgaCRReg, tmp | 0x08);#endif /* remove horizontal stripes in 1600/8bpp and 1152/16bpp */ /* 800/32bpp linewidth pixmux modes */ /* someone should check this for other 928 + Bt485 cards */ } else outb(vgaCRReg, tmp & 0xBF); /* * set output clocking to 4:1 multiplexing */ if (s3InfoRec.depth == 24 || s3InfoRec.depth == 32) /* 24bpp */ tmp = 0x10; else if (s3InfoRec.depth == 16) /* 5-6-5 */ tmp = 0x38; else if (s3InfoRec.depth == 15) /* 5-5-5 */ tmp = 0x30; else tmp = 0x40; /* 8bpp */ s3OutBtReg(BT_COMMAND_REG_1, 0x00, tmp); /* SCLK enable,pclk1,pixport */ if (mode->Flags & V_INTERLACE) s3OutBtReg(BT_COMMAND_REG_2, 0x00, 0x30 | 0x08); else s3OutBtReg(BT_COMMAND_REG_2, 0x00, 0x30); } else { if (OFLG_ISSET(OPTION_SPEA_MERCURY, &s3InfoRec.options) && S3_928_ONLY(s3ChipId)) { outb(vgaCRIndex, 0x5C); outb(vgaCRReg, 0x20); outb(0x3C7, 0x00); } if (OFLG_ISSET(OPTION_MIRO_MAGIC_S4, &s3InfoRec.options) && S3_928_ONLY(s3ChipId)) { outb(vgaCRIndex, 0x5C); outb(vgaCRReg, 0x20); outb(0x3C7, 0x00); } /* set s3 reg53 to non-parallel addressing by and'ing 0xDF */ outb(vgaCRIndex, 0x53); tmp = inb(vgaCRReg); if (OFLG_ISSET(OPTION_SPEA_MERCURY, &s3InfoRec.options) && S3_928_ONLY(s3ChipId) && (s3Bpp != 1)) { outb(vgaCRReg, tmp | 0x20); } else { outb(vgaCRReg, tmp & 0xDF); } /* set s3 reg65 for some unknown reason */ outb(vgaCRIndex, 0x65); tmp = inb(vgaCRReg); outb(vgaCRReg, tmp & 0xDF); if (OFLG_ISSET(OPTION_SPEA_MERCURY, &s3InfoRec.options) && S3_928_ONLY(s3ChipId)) { outb(vgaCRIndex, 0x5C); outb(vgaCRReg, 0x00); } if (OFLG_ISSET(OPTION_MIRO_MAGIC_S4, &s3InfoRec.options)) { outb(vgaCRIndex, 0x5C); outb(vgaCRReg, 0x00); outb(vgaCRIndex, 0x55); outb(vgaCRReg, 0x20); } else { /* set s3 reg55 to non-external serial by and'ing 0xF7 */ outb(vgaCRIndex, 0x55); tmp = inb(vgaCRReg); outb(vgaCRReg, tmp & 0xF7); } if (s3InfoRec.depth == 24 || s3InfoRec.depth == 32) /* 24bpp */ tmp = 0x10; else if (s3InfoRec.depth == 16) /* 5-6-5 */ tmp = 0x3c; /* 1:1 MUX */ else if (s3InfoRec.depth == 15) /* 5-5-5 */ tmp = 0x34; /* 1:1 MUX */ else tmp = 0x00; s3OutBtReg(BT_COMMAND_REG_1, 0x00, tmp); if (s3InfoRec.bitsPerPixel > 8) tmp = 0x30; else tmp = 0x10; /* pclk1,vgaport */ if (mode->Flags & V_INTERLACE) s3OutBtReg(BT_COMMAND_REG_2, 0x00, tmp | 0x08); else s3OutBtReg(BT_COMMAND_REG_2, 0x00, tmp); } /* end of s3PixelMultiplexing */ } /* Set 6/8 bit mode and sync-on-green if required */ s3OutBtReg(BT_COMMAND_REG_0, 0x00, 0x01 | (s3DAC8Bit ? 0x02 : 0) | (s3DACSyncOnGreen ? 0x08 : 0x00));#ifdef CLOCKDEBUG if (mode->Flags & V_DBLCLK) { ErrorF("Setting clock doubler in s3Init(), freq = %.3f\n", s3InfoRec.clock[mode->Clock] / 1000.0); }#endif /* Use Bt485 clock doubler - Bit 3 of Command Reg 3 */ s3OutBtRegCom3(0xF7, (mode->Flags & V_DBLCLK ? 0x08 : 0x00)); s3OutBtReg(BT_COMMAND_REG_0, 0xFE, 0x00); /* wake up */ outb(0x3C4, 1); outb(0x3C5, tmp2); /* unblank the screen */ return 1;}/************************************************************\ ATT20C505_DAC\************************************************************/static Bool ATT20C505_Probe(){ Bool found = FALSE; unsigned char tmp,tmp2; /*quick check*/ if (!S3_928_ONLY(s3ChipId) && !S3_964_SERIES(s3ChipId)) return FALSE; tmp = inb(0x3C6); outb(0x3C6, 0x0F); if (((tmp2 = s3InBtStatReg()) & 0x80) == 0x80) { /* * Found either a BrookTree Bt485 or AT&T 20C505. */ if ((tmp2 & 0xF0) == 0xD0) { found = TRUE; ErrorF("%s %s: Detected an AT&T 20C505 RAMDAC\n", XCONFIG_PROBED, s3InfoRec.name); } } outb(0x3C6, tmp); return found;}/*******************************************************\ TI3020_DAC TI3025_DAC \*******************************************************/static Bool TI3020_3025_Probe(int type){ int found = 0; unsigned char saveCR55, saveCR45, saveCR43, saveCR5C; unsigned char saveTIndx,saveTIndx2,saveTIdata; outb(vgaCRIndex, 0x43); saveCR43 = inb(vgaCRReg); outb(vgaCRReg, saveCR43 & ~0x02); outb(vgaCRIndex, 0x45); saveCR45 = inb(vgaCRReg); outb(vgaCRReg, saveCR45 & ~0x20); outb(vgaCRIndex, 0x55); saveCR55 = inb(vgaCRReg); /* toggle to upper 4 direct registers */ outb(vgaCRReg, (saveCR55 & 0xFC) | 0x01); saveTIndx = inb(TI_INDEX_REG); outb(TI_INDEX_REG, TI_ID); if (inb(TI_DATA_REG) == TI_VIEWPOINT20_ID) { /* * Found TI ViewPoint 3020 DAC */ found = TI3020_DAC; saveCR43 &= ~0x02; saveCR45 &= ~0x20;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -