📄 s3ramdacs.c
字号:
} else if (s3InfoRec.bitsPerPixel == 16) { /* 5-6-5 */ s3OutTiIndReg(TI_OUTPUT_CLOCK_SELECT, 0x00, TI_OCLK_S_V2_R4); } else { s3OutTiIndReg(TI_OUTPUT_CLOCK_SELECT, 0x00, TI_OCLK_S_V4_R8); } } /* * set the serial access mode 256 words control */ outb(vgaCRIndex, 0x58); tmp = inb(vgaCRReg); outb(vgaCRReg, (tmp & 0xbf) | s3SAM256); if (s3InfoRec.depth == 24 || s3InfoRec.depth == 32) { /* 24bpp */ if (DAC_IS_TI3025) { s3OutTiIndReg(TI_MUX_CONTROL_1, 0x00, TI_MUX1_3025T_888); s3OutTiIndReg(TI_MUX_CONTROL_2, 0x00, TI_MUX2_BUS_TC_D24P64); s3OutTiIndReg(TI_COLOR_KEY_CONTROL, 0x00, 0x01); } else { s3OutTiIndReg(TI_MUX_CONTROL_1, 0x00, TI_MUX1_DIRECT_888); s3OutTiIndReg(TI_MUX_CONTROL_2, 0x00, TI_MUX2_BUS_DC_D24P64); s3OutTiIndReg(TI_COLOR_KEY_CONTROL, 0x00, 0x00); } } else if (s3InfoRec.depth == 16) { /* 5-6-5 */ if (DAC_IS_TI3025) { s3OutTiIndReg(TI_MUX_CONTROL_1, 0x00, TI_MUX1_3025T_565); s3OutTiIndReg(TI_MUX_CONTROL_2, 0x00, TI_MUX2_BUS_TC_D16P64); s3OutTiIndReg(TI_COLOR_KEY_CONTROL, 0x00, 0x01); } else { s3OutTiIndReg(TI_MUX_CONTROL_1, 0x00, TI_MUX1_DIRECT_565); s3OutTiIndReg(TI_MUX_CONTROL_2, 0x00, TI_MUX2_BUS_DC_D16P64); s3OutTiIndReg(TI_COLOR_KEY_CONTROL, 0x00, 0x00); } } else if (s3InfoRec.depth == 15) { /* 5-5-5 */ if (DAC_IS_TI3025) { s3OutTiIndReg(TI_MUX_CONTROL_1, 0x00, TI_MUX1_3025T_555); s3OutTiIndReg(TI_MUX_CONTROL_2, 0x00, TI_MUX2_BUS_TC_D15P64); s3OutTiIndReg(TI_COLOR_KEY_CONTROL, 0x00, 0x01); } else { s3OutTiIndReg(TI_MUX_CONTROL_1, 0x00, TI_MUX1_DIRECT_555); s3OutTiIndReg(TI_MUX_CONTROL_2, 0x00, TI_MUX2_BUS_DC_D15P64); s3OutTiIndReg(TI_COLOR_KEY_CONTROL, 0x00, 0x00); } } else { /* set mux control 1 and 2 to provide pseudocolor sub-mode 4 */ /* this provides a 64-bit pixel bus with 8:1 multiplexing */ s3OutTiIndReg(TI_MUX_CONTROL_1, 0x00, TI_MUX1_PSEUDO_COLOR); s3OutTiIndReg(TI_MUX_CONTROL_2, 0x00, TI_MUX2_BUS_PC_D8P64); } /* change to 8-bit DAC and re-route the data path and clocking */ s3OutTiIndReg(TI_GENERAL_IO_CONTROL, 0x00, TI_GIC_ALL_BITS); if (s3DAC8Bit) { if (DAC_IS_TI3025) { s3OutTiIndReg(TI_GENERAL_IO_DATA , 0x00, TI_GID_N9_964); s3OutTiIndReg(TI_GENERAL_IO_CONTROL, 0x00, 0x00); s3OutTiIndReg(TI_MISC_CONTROL , 0xF0, TI_MC_INT_6_8_CONTROL | TI_MC_8_BPP); } else if(OFLG_ISSET(OPTION_ELSA_W2000PRO,&s3InfoRec.options)) s3OutTiIndReg(TI_GENERAL_IO_DATA , 0x00 , TI_GID_W2000_8BIT); else s3OutTiIndReg(TI_GENERAL_IO_DATA, 0x00, TI_GID_TI_DAC_8BIT); } else { if (DAC_IS_TI3025) { s3OutTiIndReg(TI_GENERAL_IO_DATA , 0x00, TI_GID_N9_964); s3OutTiIndReg(TI_GENERAL_IO_CONTROL, 0x00, 0x00); s3OutTiIndReg(TI_MISC_CONTROL , 0xF0, TI_MC_INT_6_8_CONTROL); } else if(OFLG_ISSET(OPTION_ELSA_W2000PRO,&s3InfoRec.options)) s3OutTiIndReg( TI_GENERAL_IO_DATA , 0x00 , TI_GID_W2000_6BIT ); else s3OutTiIndReg(TI_GENERAL_IO_DATA, 0x00, TI_GID_TI_DAC_6BIT); } if (DAC_IS_TI3025) { outb(vgaCRIndex, 0x6D); if (s3Bpp == 1) if (mode->Flags & V_DBLCLK) outb(vgaCRReg, 0x02); else outb(vgaCRReg, 0x03); else if (s3Bpp == 2) if (mode->Flags & V_DBLCLK) outb(vgaCRReg, 0x00); else outb(vgaCRReg, 0x01); else /* (s3Bpp == 4) */ outb(vgaCRReg, 0x00); } } else { /* set s3 reg53 to non-parallel addressing by and'ing 0xDF */ outb(vgaCRIndex, 0x53); tmp = inb(vgaCRReg); outb(vgaCRReg, tmp & 0xDF); /* set s3 reg55 to non-external serial by and'ing 0xF7 */ outb(vgaCRIndex, 0x55); tmp = inb(vgaCRReg); outb(vgaCRReg, tmp & 0xF7); /* the input clock is already set to clk1 or clk1double (s3.c) */ if (DAC_IS_TI3025) { if (s3InfoRec.bitsPerPixel > 8) s3OutTiIndReg(TI_AUXILIARY_CONTROL, 0, 0); else s3OutTiIndReg(TI_AUXILIARY_CONTROL, 0, TI_AUX_W_CMPL); } else { /* set aux control to self clocked only */ s3OutTiIndReg(TI_AUXILIARY_CONTROL, 0, TI_AUX_SELF_CLOCK); } /* * set output clocking to default of VGA. */ s3OutTiIndReg(TI_OUTPUT_CLOCK_SELECT, 0x00, TI_OCLK_VGA); /* set mux control 1 and 2 to provide pseudocolor VGA */ s3OutTiIndReg(TI_MUX_CONTROL_1, 0x00, TI_MUX1_PSEUDO_COLOR); s3OutTiIndReg(TI_MUX_CONTROL_2, 0x00, TI_MUX2_BUS_VGA); /* change to 8-bit DAC and re-route the data path and clocking */ s3OutTiIndReg(TI_GENERAL_IO_CONTROL, 0x00, TI_GIC_ALL_BITS); if (s3DAC8Bit) s3OutTiIndReg(TI_GENERAL_IO_DATA, 0x00, TI_GID_S3_DAC_8BIT); else s3OutTiIndReg(TI_GENERAL_IO_DATA, 0x00, TI_GID_S3_DAC_6BIT); } /* end of s3PixelMultiplexing */ /* for some reason the bios doesn't set this properly */ s3OutTiIndReg(TI_SENSE_TEST, 0x00, 0x00); outb(0x3C4, 1); outb(0x3C5, tmp2); /* unblank the screen */ return 1;}/***********************************************************\ ATT498_DAC ATT20C498_DAC ATT22C498_DAC ATT20C409_DAC\***********************************************************/static Bool ATT409_498_Probe(int type){ int found = 0; int dir, mir, olddaccomm; /*quick check*/ if (!S3_86x_SERIES(s3ChipId) && !S3_805_I_SERIES(s3ChipId)) return FALSE; xf86dactopel(); xf86dactocomm(); (void)inb(0x3C6); mir = inb(0x3C6); dir = inb(0x3C6); xf86dactopel(); if ((mir == 0x84) && (dir == 0x98)) { olddaccomm = xf86getdaccomm(); xf86setdaccomm(0x0a); if (xf86getdaccomm() == 0) found = ATT22C498_DAC; else found = ATT498_DAC; xf86setdaccomm(olddaccomm); } else if ((mir == 0x84) && (dir == 0x09)) { found = ATT20C409_DAC; if (!OFLG_ISSET(CLOCK_OPTION_ATT409, &s3InfoRec.clockOptions)) { OFLG_SET(CLOCK_OPTION_PROGRAMABLE, &s3InfoRec.clockOptions); OFLG_SET(CLOCK_OPTION_ATT409, &s3InfoRec.clockOptions); clockchip_probed = XCONFIG_PROBED; } } else if ((mir == 0x84) && (dir == 0x99)) { /* * according to the 21C499 data sheet it is fully compatible * with the 22C409. So we will only miss its new features * this way, but in theory things might work. */ found = ATT20C409_DAC; if(type == ATT20C409_DAC) { ErrorF("%s %s: Detected an ATT 21C499 RAMDAC\n", XCONFIG_PROBED, s3InfoRec.name); ErrorF("%s %s: support for this RAMDAC is untested. " "Please report to XFree86@XFree86.Org\n", XCONFIG_PROBED, s3InfoRec.name); } if (!OFLG_ISSET(CLOCK_OPTION_ATT409, &s3InfoRec.clockOptions)) { OFLG_SET(CLOCK_OPTION_PROGRAMABLE, &s3InfoRec.clockOptions); OFLG_SET(CLOCK_OPTION_ATT409, &s3InfoRec.clockOptions); clockchip_probed = XCONFIG_PROBED; } } return (found == type);}static Bool ATT498_Probe(){ if(ATT409_498_Probe(ATT498_DAC)) { ErrorF("%s %s: Detected an ATT 20C498/21C498 RAMDAC\n", XCONFIG_PROBED, s3InfoRec.name); return TRUE; } else return FALSE;}static Bool ATT22C498_Probe(){ if(ATT409_498_Probe(ATT22C498_DAC)) { ErrorF("%s %s: Detected an ATT 22C498 RAMDAC\n", XCONFIG_PROBED, s3InfoRec.name); return TRUE; } else return FALSE;}static Bool ATT20C409_Probe(){ if(ATT409_498_Probe(ATT20C409_DAC)) { ErrorF("%s %s: Detected an ATT 20C409 RAMDAC\n", XCONFIG_PROBED, s3InfoRec.name); return TRUE; } else return FALSE;}static int ATT409_498_PreInit(){ /* Verify that depth is supported by ramdac */ /* all are supported */ /* Set cursor options */ /* none */ /* Check if PixMux is supported and set the PixMux related flags and variables */ if((xf86bpp <= 8) && (S3_x64_SERIES(s3ChipId) || S3_805_I_SERIES(s3ChipId))) { s3ATT498PixMux = TRUE; pixMuxPossible = TRUE; if (DAC_IS_ATT20C498) { if (S3_866_SERIES(s3ChipId) || S3_868_SERIES(s3ChipId)) { nonMuxMaxClock = 100000; /* 866/868 DCLK limit */ pixMuxMinClock = 67500; } else if (S3_864_SERIES(s3ChipId)) { nonMuxMaxClock = 95000; /* 864 DCLK limit */ pixMuxMinClock = 67500; } else if (S3_805_I_SERIES(s3ChipId)) { nonMuxMaxClock = 80000; /* XXXX just a guess, who has 805i docs? */ pixMuxMinClock = 67500; } else { nonMuxMaxClock = 67500; pixMuxMinClock = 67500; } } else { nonMuxMaxClock = 67500; pixMuxMinClock = 67500; } allowPixMuxInterlace = TRUE; allowPixMuxSwitching = TRUE; pixMuxLimitedWidths = FALSE; pixMuxMinWidth = 0; } /* 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() */ if (DAC_IS_ATT20C409 && !OFLG_ISSET(CLOCK_OPTION_PROGRAMABLE, &s3InfoRec.clockOptions)) { OFLG_SET(CLOCK_OPTION_ATT409, &s3InfoRec.clockOptions); OFLG_SET(CLOCK_OPTION_PROGRAMABLE, &s3InfoRec.clockOptions); clockchip_probed = XCONFIG_PROBED; } if (OFLG_ISSET(CLOCK_OPTION_ATT409, &s3InfoRec.clockOptions)) { s3ClockSelectFunc = att409ClockSelect; numClocks = 3; maxRawClock = s3InfoRec.dacSpeeds[0]; /* Is this right?? */ if (xf86Verbose) ErrorF("%s %s: Using ATT20C409/ATT20C499 programmable clock\n", clockchip_probed, s3InfoRec.name); } else OtherClocksSetup(); if (s3ATT498PixMux) { s3InfoRec.maxClock = s3InfoRec.dacSpeeds[0]; if (s3Bpp == 1) /* XXXX is this right?? */ clockDoublingPossible = TRUE; } else { if (s3InfoRec.dacSpeeds[0] >= 135000) /* 20C498 -13, -15, -17 */ s3InfoRec.maxClock = 110000; else /* 20C498 -11 */ s3InfoRec.maxClock = 80000; /* Halve it for 32bpp */ if (s3Bpp == 4) { s3InfoRec.maxClock /= 2; maxRawClock /= 2; } } return 1;}static void ATT409_498_Restore(){ xf86setdaccomm(s3DacRegs[0]);}static void ATT409_498_Save(){ s3DacRegs[0] = xf86getdaccomm();}static int ATT409_498_Init(DisplayModePtr mode){ unsigned char tmp,tmp2; if (s3DAC8Bit) xf86setdaccommbit(0x02); else xf86clrdaccommbit(0x02); outb(0x3C4, 1); tmp2 = inb(0x3C5); outb(0x3C5, tmp2 | 0x20); /* blank the screen */ if (s3PixelMultiplexing) { /* x64:pixmux */ /* pixmux with 16/32 bpp not possible for 864 ==> only 8bit mode */ int daccomm; tmp = xf86getdaccomm(); if (DAC_IS_ATT22C498) { if (s3InfoRec.clock[mode->Clock]/2 < 22500) daccomm = 0x20; else if (s3InfoRec.clock[mode->Clock]/2 < 45000) daccomm = 0x21; else daccomm = 0x24;#if 0 /* using digital clock doubler; 20C498 compatible */ daccomm = 0x25;#endif } else daccomm = 0x20;#ifdef EXTENDED_DEBUG ErrorF("Putting AT&T 2xC4[09][89] RAMDAC into pixmux\n");#endif xf86setdaccomm( (tmp&0x02) | daccomm ); /* set mode 2, pixel multiplexing on */ if ( ! DAC_IS_ATT20C409 ) { outb(vgaCRIndex, 0x33); /* set VCLK = -DCLK */ tmp = inb(vgaCRReg); outb(vgaCRReg, tmp | 0x08 ); } if (S3_x64_SERIES(s3ChipId) || S3_805_I_SERIES(s3ChipId)) { outb(vgaCRIndex, 0x67); /* set Mode 8: Two 8-bit color 1 VCLK / 2 pixels */ if ( OFLG_ISSET(OPTION_NUMBER_NINE, &s3InfoRec.options) || DAC_IS_ATT20C409 ) outb(vgaCRReg, 0x10 ); /* VCLK is out of phase with DCLK */ else outb(vgaCRReg, 0x11 ); /* VCLK is in phase with DCLK */ outb(vgaCRIndex, 0x6d); outb(vgaCRReg, 2 ); /* delay -BLANK pulse by 2 DCLKs */ } else { /* don't know */ } } else { /* !s3PixelMultiplexing */ outb(vgaCRIndex, 0x33); tmp = inb(vgaCRReg); outb(vgaCRReg, tmp & ~0x08 ); tmp = xf86getdaccomm() & 0x0f; if (S3_x64_SERIES(s3ChipId) || S3_805_I_SERIES(s3ChipId)) { int invert_vclk = 0; int delay_blank = 0; outb(vgaCRIndex, 0x67); switch (s3InfoRec.bitsPerPixel) { case 8: /* set Mode 0: 8-bit color, 1 VCLK/pixel */ outb(vgaCRReg, 0x00 | invert_vclk); xf86setdaccomm(tmp | 0x00); /* set mode 0 */ break; case 16: if (s3Weight == RGB16_555) { outb(vgaCRReg, 0x30 | invert_vclk); /* set Mode 9: 15-bit color, 1 VCLK/pixel */ xf86setdaccomm(tmp | 0x10); /* set mode 1 */ } else { outb(vgaCRReg, 0x50 | invert_vclk); /* set Mode 10:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -