⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ltlcd.c

📁 此代码为WCE5.0下显示器的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
            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 + -