📄 ltlcd.c
字号:
DDLRegisterAND(hGDORageLCD->hDDL, (ULONG)SCRATCH_REG3, (ULONG)(~SCRATCH_REG3__CRTC_LCD_ACTIVE));
}
else if (hGDORageLCD->ulController == SECONDARY_CONTROLLER)
{
DDLRegisterOR(hGDORageLCD->hDDL, (ULONG)SCRATCH_REG2, (ULONG)SCRATCH_REG2__CRTC_LCD);
DDLRegisterOR(hGDORageLCD->hDDL, (ULONG)SCRATCH_REG3, (ULONG)SCRATCH_REG3__CRTC_LCD_ACTIVE);
}
DDLRegisterOR(hGDORageLCD->hDDL, (ULONG)SCRATCH_REG2, (ULONG)SCRATCH_REG2__REQ_LCD);
DDLRegisterOR(hGDORageLCD->hDDL, (ULONG)SCRATCH_REG3, (ULONG)SCRATCH_REG3__LCD_ACTIVE);
}
if(hGDORageLCD->ulBiosSupportedFeatures & BIOS_SUPPORTS_SPREAD_SPECTRUM)
{
// Enable Spread spectrum clocking bit as LCD engine will be turned on. This
// allows to broadband the VCLK source frequency for reducing
// measured EMI
ucAddress = PM_DYN_CLK_CNTL;
ucData = PM_DYN_CLK_CNTL_SsEn;
GDOPLLWriteByte(hGDO, ucAddress, ucData, (UCHAR)(~(PM_DYN_CLK_CNTL_SsEn)));
}
//
// Turn on LCD
//
// Set LCD_DATA register to index 1( LCD_GEN_CTRL).
ulLCDIndex = MMREADULONG(hGDORageLCD->lpMMR, LCD_INDEX);
ulLCDIndex &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
ulLCDIndex |= LCD_INDEX_lcdGenCtrlReg;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_INDEX, ulLCDIndex);
// Read LCD GEN CTRL data from LCD data register first.
ulLCDGenCtrlData = MMREADULONG(hGDORageLCD->lpMMR, LCD_DATA);
if(!(ulLCDGenCtrlData & LCD_GEN_CTRL__LCD_ON))
{
// LCD is turned off.
if(hGDORageLCD->ulChipFamily == FAMILY_RAGE_MOBILITY)
{
// DSTN corruption in Rage Mobility
// As per Charles XBUF_SIZE should be set to 0xF before
// toggling the engine ON/OFF and it should be restored
// after it has been transistion. HW Bug. (4 May 99, sah)
/*
ulTemp1 = MMREADULONG(hGDORageLCD->lpMMR, LCD_INDEX);
ulTemp1 &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_INDEX, (ulTemp1 | LCD_INDEX_HfbPitchAddr));
ulTemp1 = MMREADULONG(hGDORageLCD->lpMMR, LCD_DATA);
// Set the XBUF_SIZE to 0xF.
ulTemp1 |= HFB_PITCH_ADDR_XbufSize;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_DATA, ulTemp1);
*/
// Fix EPR 33802
// Restore the original buffer size.
ulTemp1 = MMREADULONG(hGDORageLCD->lpMMR, LCD_INDEX);
ulTemp1 &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_INDEX, (ulTemp1 | LCD_INDEX_HfbPitchAddr));
ulTemp1 = MMREADULONG(hGDORageLCD->lpMMR, LCD_DATA);
// Zero out the buffer
ulTemp1 &= (~HFB_PITCH_ADDR_XbufSize);
// Restore the original XBUF_SIZE.
// Fix EPR 33018
ulTemp1 |= (ULONG)((hGDORageLCD->LcdGdoPanelInfo.ucXBufSize) << 8) ;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_DATA, ulTemp1);
// There is a problem in Rage Mobility that
// causes LCD panel to remain blank after
// LCD_ON is set. Originally this requires
// toggling of the LCD_ON to get back the
// display. Later HW found the problem and
// they advised to change the MCLK->XTAL
// to fix this problem.
ucAddress = PLL_GEN_CNTL;
ucTemp = GDOPLLReadByte(hGDO, ucAddress);
ucAddress = PLL_GEN_CNTL;
ucData = 0x70; // Set SCLK = PLLSCLK/8 to lower the MCLK
// wait if GUI engine is active
while((MMREADULONG(hGDORageLCD->lpMMR, LCD_INDEX)) & 0x800);
GDOPLLWriteByte(hGDO, ucAddress, ucData, 0x8F);
// Setup the delay
DELAY_MILLISECONDS(1);
// Fix EPR # 33802
ulLCDIndex = MMREADULONG(hGDORageLCD->lpMMR, LCD_INDEX);
ulLCDIndex &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
ulLCDIndex |= LCD_INDEX_lcdGenCtrlReg;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_INDEX, ulLCDIndex);
ulLCDGenCtrlData = MMREADULONG(hGDORageLCD->lpMMR, LCD_DATA);
// set LCD_ON bit to 1 which turns on the LCD display.
ulLCDGenCtrlData |= LCD_GEN_CTRL__LCD_ON;
// Write out LCD GEN CTRL data to LCD data register.
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_DATA, ulLCDGenCtrlData);
// Set up the delay as per Alex Miller
// DELAY_MILLISECONDS(100);
ucAddress = PLL_GEN_CNTL;
ucData = ucTemp; // Restore the old value
// wait if GUI engine is active
while((MMREADULONG(hGDORageLCD->lpMMR, LCD_INDEX)) & 0x800);
GDOPLLWriteByte(hGDO, ucAddress, ucData, 0x8F);
DELAY_MILLISECONDS(1);
}
else
{
// We need this delay here for certain panels.
DELAY_MILLISECONDS(100);
// set LCD_ON bit to 1 which turns on the LCD display.
ulLCDGenCtrlData |= LCD_GEN_CTRL__LCD_ON;
// Write out LCD GEN CTRL data to LCD data register.
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_DATA, ulLCDGenCtrlData);
if (hGDORageLCD->ulChipFamily == FAMILY_RAGE_XL)
{
// check if TMDS is enabled
ulLCDIndex = MMREADULONG(hGDORageLCD->lpMMR, LCD_INDEX);
ulLCDIndex &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
ulLCDIndex |= LCD_INDEX_LcdMiscCntl;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_INDEX, ulLCDIndex);
ulLCDData = MMREADULONG(hGDORageLCD->lpMMR, LCD_DATA);
if (!(ulLCDData & LCD_MISC_CTRL__PL_EN))
{
// TMDS is off so turn on TMDS
ulLCDIndex = MMREADULONG(hGDORageLCD->lpMMR, LCD_INDEX);
ulLCDIndex &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
ulLCDIndex |= LCD_INDEX_lcdGenCtrlReg;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_INDEX, ulLCDIndex);
ulLCDData = MMREADULONG(hGDORageLCD->lpMMR, LCD_DATA);
ulLCDData |= LCD_GEN_CTRL__LCD_ON;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_DATA, ulLCDData);
// Turn on digital voltage(Vcc) in panel digital power control
ulLCDIndex = MMREADULONG(hGDORageLCD->lpMMR, LCD_INDEX);
ulLCDIndex &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
ulLCDIndex |= LCD_INDEX_PowerManagement;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_INDEX, ulLCDIndex);
ulLCDData = MMREADULONG(hGDORageLCD->lpMMR, LCD_DATA);
ulLCDData |= POWER_MANAGEMENT__DIGON;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_DATA, ulLCDData);
// enable use of TMDS
ulLCDIndex = MMREADULONG(hGDORageLCD->lpMMR, LCD_INDEX);
ulLCDIndex &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
ulLCDIndex |= LCD_INDEX_LcdMiscCntl;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_INDEX, ulLCDIndex);
ulLCDData = MMREADULONG(hGDORageLCD->lpMMR, LCD_DATA);
ulLCDData |= LCD_MISC_CTRL__PL_EN;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_DATA, ulLCDData);
// Put transmitter under reset state
ulLCDIndex = MMREADULONG(hGDORageLCD->lpMMR, LCD_INDEX);
ulLCDIndex &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
ulLCDIndex |= LCD_INDEX_PLTransmitterCntl;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_INDEX, ulLCDIndex);
ulLCDData = MMREADULONG(hGDORageLCD->lpMMR, LCD_DATA);
ulLCDData |= PL_TRANSMITTER_CNTL__PPLLRST;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_DATA, ulLCDData);
// enable transmitter
ulLCDData |= PL_TRANSMITTER_CNTL__PPLLEN;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_DATA, ulLCDData);
// release transmitter from reset
ulLCDData &= (~PL_TRANSMITTER_CNTL__PPLLRST);
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_DATA, ulLCDData);
// Set up the delay as in BIOS
DELAY_MILLISECONDS(100);
// The following code can reduce noise on panels when using B21 chips
ulLCDIndex = MMREADULONG(hGDORageLCD->lpMMR, LCD_INDEX);
ulLCDIndex &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
ulLCDIndex |= LCD_INDEX_PlPllCntl;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_INDEX, ulLCDIndex);
ulLCDData = MMREADULONG(hGDORageLCD->lpMMR, LCD_DATA);
ulLCDData = (ulLCDData & 0xffff0000) | PL_PLL_CNTL_VAL;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_DATA, ulLCDData);
}
}
}
}
// EPR# 039124 IBM requires to turn off backlight
// during Fn+F7 and Fn+F8 for W9X and W2K
// Turn on backlight voltage(VB) in panel digital power control
ulLCDIndex = MMREADULONG(hGDORageLCD->lpMMR, LCD_INDEX);
ulLCDIndex &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
ulLCDIndex |= LCD_INDEX_PowerManagement;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_INDEX, ulLCDIndex);
ulLCDData = MMREADULONG(hGDORageLCD->lpMMR, LCD_DATA);
if((hGDORageLCD->LcdGdoPanelInfo.usBackLightDelay) &&
(!(ulLCDData & POWER_MANAGEMENT__BLON)))
{
DELAY_MILLISECONDS(hGDORageLCD->LcdGdoPanelInfo.usBackLightDelay);
}
ulLCDData |= POWER_MANAGEMENT__BLON;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_DATA, ulLCDData);
}
/******************************Public*Routine******************************\
* VOID LCDSetDisplayOff(HW_DISPAY_OBJECT hGDO, ULONG ulcontroller)
*
* LCDSetDisplayOff turns off a LCD panel on a specific graphics controller.
*
\**************************************************************************/
VOID FAR
LCDSetDisplayOff(
HGDO hGDO,
ULONG ulController
)
{
UCHAR ucAddress, ucTemp, ucData;
ULONG ulLCDIndex;
ULONG ulLCDGenCtrlData;
ULONG ulLCDData;
ULONG ulTemp1;
//ULONG ulScratch2_data;
ULONG ulTemp;
LPGDO_RAGE_LCD hGDORageLCD;
hGDORageLCD = (LPGDO_RAGE_LCD)hGDO;
DALDEBUG((DALDBG_NORMAL, "ATIRAGE.SYS! GDO-LCD: LCDSetDisplayOff - Entry"));
// Moved to RageProUpdateBIOSDisplayInfo function in GCO
// Reset LCD_REQ bit in scratch register 2 if LCD is attached to primary
// controller and it is turned off
if((hGDORageLCD->ulChipFamily == FAMILY_RAGE_MOBILITY) ||
(hGDORageLCD->ulChipFamily == FAMILY_LT_PRO))
{
// Reset LCD Request Bits and LCD CRTC Request bits
DDLRegisterAND(hGDORageLCD->hDDL,(ULONG)SCRATCH_REG2, (ULONG)(~SCRATCH_REG2__REQ_LCD));
DDLRegisterAND(hGDORageLCD->hDDL, (ULONG)SCRATCH_REG2, (ULONG)(~SCRATCH_REG2__CRTC_LCD));
// Reset LCD Active Bit and LCD CRTC Active bits
DDLRegisterAND(hGDORageLCD->hDDL, (ULONG)SCRATCH_REG3, (ULONG)(~SCRATCH_REG3__LCD_ACTIVE));
DDLRegisterAND(hGDORageLCD->hDDL, (ULONG)SCRATCH_REG3, (ULONG)(~SCRATCH_REG3__CRTC_LCD_ACTIVE));
}
// Check backlight voltage(VB) status in panel power control
ulLCDIndex = MMREADULONG(hGDORageLCD->lpMMR, LCD_INDEX);
ulLCDIndex &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
ulLCDIndex |= LCD_INDEX_PowerManagement;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_INDEX, ulLCDIndex);
ulLCDData = MMREADULONG(hGDORageLCD->lpMMR, LCD_DATA);
// if back light delay is defined in registry or BIOS
// turn off the back light if it is on before LCD_ON bit is reset.
if((hGDORageLCD->LcdGdoPanelInfo.usBackLightDelay) &&
(ulLCDData & POWER_MANAGEMENT__BLON))
{
ulLCDData &= ~POWER_MANAGEMENT__BLON;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_DATA, ulLCDData);
// Wait for back light delay before turn off the LCD_ON bit
DELAY_MILLISECONDS(hGDORageLCD->LcdGdoPanelInfo.usBackLightDelay);
}
if(hGDORageLCD->ulBiosSupportedFeatures & BIOS_SUPPORTS_SPREAD_SPECTRUM)
{
// Disable Spread spectrum clocking bit since we are going to disable LCD engine
ucAddress = PM_DYN_CLK_CNTL;
ucData = 0;
GDOPLLWriteByte(hGDO, ucAddress, ucData, (UCHAR)(~(PM_DYN_CLK_CNTL_SsEn)));
}
// Turn off LCD
// Set LCD_DATA register to index 1( LCD_GEN_CTRL).
ulLCDIndex = MMREADULONG(hGDORageLCD->lpMMR, LCD_INDEX);
ulLCDIndex &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
ulLCDIndex |= LCD_INDEX_lcdGenCtrlReg;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_INDEX, ulLCDIndex);
// Read LCD GEN CTRL data from LCD data register first.
ulLCDGenCtrlData = MMREADULONG(hGDORageLCD->lpMMR, LCD_DATA);
if(ulLCDGenCtrlData & LCD_GEN_CTRL__LCD_ON)
{
// LCD is turned on we are going to turn off check if we need
// to apply the patch.
if(hGDORageLCD->ulChipFamily == FAMILY_RAGE_MOBILITY)
{
// DSTN corruption in Rage Mobility
// As per Charles XBUF_SIZE should be set to 0xF before
// toggling the engine ON/OFF and it should be restored
// after it has been transistion. HW Bug. (4 May 99, sah)
/*
ulTemp1 = MMREADULONG(hGDORageLCD->lpMMR, LCD_INDEX);
ulTemp1 &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_INDEX, (ulTemp1 | LCD_INDEX_HfbPitchAddr));
ulTemp1 = MMREADULONG(hGDORageLCD->lpMMR, LCD_DATA);
// Set the XBUF_SIZE to 0xF.
ulTemp1 |= HFB_PITCH_ADDR_XbufSize;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_DATA, ulTemp1);
*/
// There is a problem in Rage Mobility that
// causes LCD panel to remain blank after
// LCD_ON is set. Originally this requires
// toggling of the LCD_ON to get back the
// display. Later HW found the problem and
// they advised to change the MCLK->XTAL
// to fix this problem.
ucAddress = PLL_GEN_CNTL;
ucTemp = GDOPLLReadByte(hGDO, ucAddress);
ucAddress = PLL_GEN_CNTL;
ucData = 0x70; // Set SCLK = PLLSCLK/8 to lower the MCLK
// wait if GUI engine is active
while((MMREADULONG(hGDORageLCD->lpMMR, LCD_INDEX)) & 0x800);
GDOPLLWriteByte(hGDO, ucAddress, ucData, 0x8F);
// Setup the delay
DELAY_MILLISECONDS(1);
// Fix EPR 33802
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -