📄 ltlcd.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*****************************************************************************\
*
* Module Name LTLCD.C
* Project LT Rage Pro/ Rage Mobility/ Rage XC/ Rage XL
*
* Description Contains the functions required for implementation of
* a LCD Graphics Display Object (GDO) for the Display
* Abstraction Layer.
*
* (c) 1997 ATI Technologies Inc. (unpublished)
*
* All rights reserved. This notice is intended as a precaution against
* inadvertent publication and does not imply publication or any waiver
* of confidentiality. The year included in the foregoing notice is the
* year of creation of the work.
*
* Programmer's Note:
* Great care was taken and considerable effort was expended to make the
* code in this file 100% BIOS independant. This has been done so that in
* an OS that supports multiple displays and multiple adapters the problems
* multiple BIOSes raise totally disappear. Since this effort has been made
* it follows that further modifications to this file should NOT include ANY
* calls to the BIOS. The sole purpose of the code in this file is to avoid
* any reliance on the BIOS.
*
*
\*****************************************************************************/
#include "dal.h"
#include "ltlcdl.h"
#include "lcdddc.h"
#include "rprod.h"
/******************************Public*Routine******************************\
* BOOL LCDEnable(HW_DEVICE_EXTENSION* phde, HGDO hGDO,
* HW_ASIC_ID phasicid, HW_DISPLAY_ENABLEDATE FAR* lpEnableData)
*
*
* CRTEnable determines if the graphics adapter is supported, and if the
* graphics adapter's hardware has support for a DAC type supported by
* the object. GDOEnable is the initial entry point exported by the graphics
* display object. It fills a HW_DISPLAY_ENABLEDATA structure with
* information, and calling addresses of functions supported by the graphics
* display object.
*
*
\**************************************************************************/
BOOL FAR
LCDEnable(
HDDL hDDL,
HGDO hGDO,
LPHW_ASIC_ID lpHwAsicID,
LPHW_DISPLAY_ENABLEDATA lpEnableData
)
{
UCHAR ucIndex;
UCHAR ucAddress, ucTemp, ucData;
LPGDO_RAGE_LCD hGDORageLCD;
ULONG ulTemp;
ULONG ulTemp1;
ULONG ulLCDIndex;
ULONG ulLCDData;
ULONG ulLCDGenCtrlData;
hGDORageLCD = (LPGDO_RAGE_LCD)hGDO;
DALDEBUG((DALDBG_NORMAL, "ATIRAGE.SYS! GDO-LCD: LCDEnable - Entry"));
DALASSERT(HW_DISPLAY_EXTENSION_SIZE >= sizeof(GDO_RAGE_LCD),
"Size of GDO structure is too large!");
if (lpEnableData->ulSize != sizeof(HW_DISPLAY_ENABLEDATA))
{
DALASSERT(FALSE, "Hardware Enable Data structure mismatch w/ DAL!");
return(FALSE);
}
hGDORageLCD->lpLibVersionString = (LPVOID)R3LCDGDOLIB;
lpEnableData->ulDisplayVersion = R3LIB_VERSION;
// lpEnableData->ulDisplayVersion = RAGELCD_VERSION;
lpEnableData->ulDisplayType = HW_DISPLAY_TYPE_LCD;
lpEnableData->lpDisplayName = RAGELCD_NAME;
lpEnableData->pfnDisable = LCDDisable;
lpEnableData->pfnEnable = LCDEnable;
lpEnableData->pfnSetDisplayOff = LCDSetDisplayOff;
lpEnableData->pfnSetDisplayOn = LCDSetDisplayOn;
lpEnableData->pfnBlanking = LCDBlank;
lpEnableData->pfnSetDPMS = LCDSetDPMS;
lpEnableData->pfnIsDisplayPhysicallyConnected =
LCDIsDisplayPhysicallyConnected;
lpEnableData->pfnIsModeSupported = LCDIsModeSupported;
lpEnableData->pfnGetEdidData = LCDGetEdidData;
lpEnableData->pfnSetMode = LCDSetMode;
lpEnableData->pfnPreModeChange = LCDPreModeChange;
lpEnableData->pfnPostModeChange = LCDPostModeChange;
lpEnableData->pfnGetContrastAdjustment = LCDGetContrastAdjustment;
lpEnableData->pfnSetContrastAdjustment = LCDSetContrastAdjustment;
lpEnableData->pfnInitializeDevice = LCDInitializeDevice;
lpEnableData->pfnIsDeviceHotPluggable = LCDIsDeviceHotPluggable;
hGDORageLCD->ulChipFamily = lpHwAsicID->ulChipFamily;
hGDORageLCD->ulChipID = lpHwAsicID->ulChipID;
hGDORageLCD->ulVRamInstalled = lpHwAsicID->ulVRamInstalled;
hGDORageLCD->ulVRamType = lpHwAsicID->ulVRamType;
hGDORageLCD->ulVRamBitWidth = lpHwAsicID->ulVRamBitWidth;
hGDORageLCD->lpIO = lpHwAsicID->lpIO;
hGDORageLCD->lpMMR = lpHwAsicID->lpMMR;
hGDORageLCD->lpRomBaseAddress = lpHwAsicID->lpRomBaseAddress;
hGDORageLCD->lpRomHeader = lpHwAsicID->lpRomHeader;
hGDORageLCD->lpucVgaBuffer = lpHwAsicID->lpucVgaBuffer;
hGDORageLCD->usRealSegment = lpHwAsicID->usRealSegment;
hGDORageLCD->ulReferenceFrequency = lpHwAsicID->ulReferenceFrequency;
hGDORageLCD->hDDL = hDDL;
hGDORageLCD->ulLCDSupportsDDC = 0;
hGDORageLCD->ulLCDTimingsInBIOS = 0;
hGDORageLCD->ulBiosSupportedFeatures = 0;
hGDORageLCD->usOffsetToPanelScalingAdjustTable = 0;
hGDORageLCD->ulEDIDMfgProductID = 0;
hGDORageLCD->bRageXLUseInfoTable = FALSE;
// Get registry based information.
vGetLCDGDORegFlag(hDDL, hGDO);
// GDO only supports the following ASICS
if(hGDORageLCD->ulChipFamily == FAMILY_LT_PRO)
{
hGDORageLCD->ulBiosInfoTableSiganture = LTPRO_BIOS_INFO_TABLE_SIGNATURE;
if(!(MMREADULONG(hGDORageLCD->lpMMR, CONFIG_STAT0) & CONFIG_STAT0_PanelID_Mask))
{
return (FALSE);
}
}
else if(hGDORageLCD->ulChipFamily == FAMILY_RAGE_MOBILITY)
{
hGDORageLCD->ulBiosInfoTableSiganture = RAGEMOBILITY_BIOS_INFO_TABLE_SIGNATURE;
// read panel id scratch register. If panel id is zero (no LCD support), return FALSE.
ulTemp = MMREADULONG(hGDORageLCD->lpMMR, LCD_INDEX);
ulTemp &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
ulTemp |= LCD_INDEX_Scratch_Pad4;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_INDEX, ulTemp);
if(!(MMREADULONG(hGDORageLCD->lpMMR, LCD_DATA) & LCD_INDEX_Scratch_Pad4_PanelID_Mask))
{
return (FALSE);
}
}
else if(hGDORageLCD->ulChipFamily == FAMILY_RAGE_XL)
{
hGDORageLCD->ulBiosInfoTableSiganture = RAGEXL_BIOS_INFO_TABLE_SIGNATURE;
}
else
{
// This GDO does not support DFP + LCD for any other asic
// so fail the call.
hGDORageLCD->ulBiosInfoTableSiganture = 0;
return (FALSE);
}
// initialize the panel info structure if the right BIOS exist
// else intialize every thing to zero
if( InitializePanelInfoStruc(hGDO) == FALSE )
{
hGDORageLCD->ulLCDTimingsInBIOS = 0;
hGDORageLCD->LcdGdoPanelInfo.usHorizontalSize = 0;
hGDORageLCD->LcdGdoPanelInfo.usVerticalSize = 0;
hGDORageLCD->LcdGdoPanelInfo.usFlatPanelType = 0;
hGDORageLCD->LcdGdoPanelInfo.ucPanelRefreshRateData = 0;
hGDORageLCD->LcdGdoPanelInfo.usSupportedRefreshRate = 0;
hGDORageLCD->usOffsetToLcdParameterTable = 0;
hGDORageLCD->LcdGdoPanelInfo.usBackLightDelay = 0;
hGDORageLCD->LcdGdoPanelInfo.usOffDelay = 0;
for( ucIndex = 0; ucIndex <17; ucIndex++ )
{
hGDORageLCD->LcdGdoPanelInfo.ausModeTableOffset[ucIndex] = 0;
}
if(hGDORageLCD->ulChipFamily == FAMILY_RAGE_XL)
{
// As per BIOS, this XL board does not support DFP
// or does not have DFP connector. Fail the enable
// for DFP.
return (FALSE);
}
}
else
{
//
// For Rage XL, hard-coded panel info table in BIOS should
// be used when bRageXLUseInfoTable is set to TRUE .
//
if(hGDORageLCD->ulChipFamily == FAMILY_RAGE_XL)
{
if(hGDORageLCD->bRageXLUseInfoTable == TRUE)
{
hGDORageLCD->ulLCDTimingsInBIOS = 1;
}
else
{
hGDORageLCD->ulLCDTimingsInBIOS = 0;
}
}
else
{
hGDORageLCD->ulLCDTimingsInBIOS = 1;
}
}
if(hGDORageLCD->ulChipFamily == FAMILY_RAGE_XL)
{
// This will show a DFP picture instead of an LCD
// in the property pages. WOW thats perfect.
lpEnableData->ulDisplayType |= HW_DISPLAY_DFP;
// hook up functions for hot plug and initialization for DFP
// to support hot plug panels for XL only
lpEnableData->ulFunctionHooks = (GDO_HOOK_HOTPLUGABLEDEVICE |
GDO_HOOK_INITIALIZE_DEVICE);
}
// bit 0 is set: Color, bit 1 is set: Dual (split) panel
// bit 2 -7 = 0: STN (passive matrix)
if ((hGDORageLCD->LcdGdoPanelInfo.usFlatPanelType & 0x0001) &&
(hGDORageLCD->LcdGdoPanelInfo.usFlatPanelType & 0x0002) &&
(!(hGDORageLCD->LcdGdoPanelInfo.usFlatPanelType & 0x00fc)))
{ // If DSTN panel is attached, hook contrast adjustment function.
lpEnableData->ulFunctionHooks |= (GDO_HOOK_DPMS |
GDO_HOOK_CONTRAST_ADJUSTMENT |
GDO_HOOK_BLANKING);
} else { // If non DSTN panel is attached, don't hook contrast
// adjustment function.
lpEnableData->ulFunctionHooks |= (GDO_HOOK_DPMS |
GDO_HOOK_BLANKING);
}
lpEnableData->ulFunctionHooks |= GDO_HOOK_GET_EDID_DATA |
GDO_HOOK_MODE_CHANGES;
lpEnableData->ulDisplayCaps &= (~GDO_CAPS_ACTIVATE_BEFORE_DETECT);
lpEnableData->ulDisplayCaps |= GDO_CAPS_GDO_WITH_LID;
// Call the DDL Get Driver Options call to
// set up the INF based options for GCOs and GDOs
// Save the return in the local structure.
hGDORageLCD->ulDriverOptions = DDLGetDriverOptions(hDDL);
// save the XBUF_SIZE for DSTN panel
if(hGDORageLCD->ulChipFamily == FAMILY_RAGE_MOBILITY)
{
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);
ulTemp1 = (ulTemp1 & HFB_PITCH_ADDR_XbufSize) >> 8;
hGDORageLCD->LcdGdoPanelInfo.ucXBufSize = (UCHAR)ulTemp1;
}
// if back light delay is defined in registry or BIOS
// turn off the back light before LCD_ON bit is reset.
if(hGDORageLCD->LcdGdoPanelInfo.usBackLightDelay)
{
// Turn off backlight voltage(VB) 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);
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);
}
/*
// Registry option to turn off back light is enabled
if(hGDORageLCD->ulLCDGDORegOptionFlag & RPRO_REG_OPTION_LCDGDO_BACKLIGHTOFFONENABLE)
{
// Read the Engine ON bit to check if LCD is ON at boot
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.
ulLCDData = MMREADULONG(hGDORageLCD->lpMMR, LCD_DATA);
if (ulLCDData & LCD_GEN_CTRL__LCD_ON)
{
// LCD is ON Turn off 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);
ulLCDData &= ~POWER_MANAGEMENT__BLON;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_DATA, ulLCDData);
}
}
*/
// At boot when going VGA -> ACC we will make sure the
// LCD is off to ensure we don't get fading out effects
// when CRT and TV detection are being done.
// Read the Engine ON bit to check if LCD is ON at boot
ulTemp = MMREADULONG(hGDORageLCD->lpMMR, LCD_INDEX);
ulTemp &= (~LCD_INDEX__LCD_REG_INDEX_MASK);
ulTemp |= LCD_INDEX_lcdGenCtrlReg;
MMWRITEULONG(hGDORageLCD->lpMMR, LCD_INDEX, ulTemp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -