summaryrefslogtreecommitdiff
path: root/src/CInt10.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/CInt10.c')
-rw-r--r--src/CInt10.c4021
1 files changed, 4021 insertions, 0 deletions
diff --git a/src/CInt10.c b/src/CInt10.c
new file mode 100644
index 0000000..1510ce8
--- /dev/null
+++ b/src/CInt10.c
@@ -0,0 +1,4021 @@
+/*
+ * Copyright (C) 2009 RDC Semiconductor Co.,Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * For technical support :
+ * <jason.lin@rdc.com.tw>
+ */
+
+#include <string.h>
+
+#ifndef XFree86Module
+#include "compiler.h"
+#else
+#include "xf86_ansic.h"
+#endif
+
+#include "typedef.h"
+#include "CInt10.h"
+#include "CInt10FunProto.h"
+#include "CInt10Tbl.h"
+
+
+/* Global for related IO address */
+USHORT Relocate_IOAddress;
+
+/*--------------------------------------------------------------------------
+;
+; IO port function replace
+;
+;---------------------------------------------------------------------------*/
+__inline void OutPort(UCHAR Index,UCHAR Value)
+{
+
+ outb(Relocate_IOAddress+Index, Value);
+
+ return;
+}
+
+__inline UCHAR InPort(UCHAR Index)
+{
+ UCHAR bInVal = 0x0;
+
+ bInVal = inb(Relocate_IOAddress+Index);
+
+ return bInVal;
+}
+
+/*----------------------------------------------------------------------------
+;
+; SetVBERerurnStatus
+;
+; in:
+; VBEReturnStatus =
+; VBEFunctionCallSuccessful 0x004F
+; VBEFunctionCallFail 0x014F
+; VBEFunctionCallNotSupported 0x024F
+; VBEFunctionCallInvalid 0x034F
+; out:
+; pCBiosArguments->Eax
+;---------------------------------------------------------------------------*/
+void SetVBERerurnStatus(USHORT VBEReturnStatus, CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ pCBiosArguments->reg.x.AX = VBEReturnStatus;
+}
+
+/*----------------------------------------------------------------------------
+;
+; SetTimingRegs
+;
+; in:
+; bDisplayPath = display path
+; pMODE_INFO = pointer to MODE_INFO
+; pRRATE_TABLE = pointer to RRATE_TABLE
+;
+;---------------------------------------------------------------------------*/
+void SetTimingRegs(UCHAR ucDisplayPath, MODE_INFO *pModeInfo, RRATE_TABLE *pRRateTable)
+{
+ USHORT usHBorder = 0, usVBorder = 0;
+ USHORT usHtotal, usHDispEnd, usHBlankStart, usHBlankEnd, usHSyncStart, usHSyncEnd;
+ USHORT usVtotal, usVDispEnd, usVBlankStart, usVBlankEnd, usVSyncStart, usVSyncEnd;
+ ULONG ulPixelClock;
+
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Enter SetTimingRegs()==\n");
+
+ if (pRRateTable->Attribute & HB)
+ {
+ usHBorder = 8;
+ }
+
+ if (pRRateTable->Attribute & VB)
+ {
+ usVBorder = 8;
+ }
+
+ usHtotal = pModeInfo->H_Size + usHBorder*2 + pRRateTable->H_Blank_Time;
+ usHDispEnd = pModeInfo->H_Size;
+ usHBlankStart = pModeInfo->H_Size + usHBorder;
+ usHBlankEnd = pModeInfo->H_Size + usHBorder + pRRateTable->H_Blank_Time;
+ usHSyncStart = pRRateTable->H_Sync_Start;
+ usHSyncEnd = pRRateTable->H_Sync_Start + pRRateTable->H_Sync_Time;
+
+ usVtotal = pModeInfo->V_Size + usVBorder*2 + pRRateTable->V_Blank_Time;
+ usVDispEnd = pModeInfo->V_Size;
+ usVBlankStart = pModeInfo->V_Size + usVBorder;
+ usVBlankEnd = pModeInfo->V_Size + usVBorder + pRRateTable->V_Blank_Time;
+ usVSyncStart = pRRateTable->V_Sync_Start;
+ usVSyncEnd = pRRateTable->V_Sync_Start + pRRateTable->V_Sync_Time;
+
+ ulPixelClock = pRRateTable->Clock;
+
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "H total = %d\n", usHtotal);
+ SetHTotal(ucDisplayPath, usHtotal);
+
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "H disp end = %d\n", usHDispEnd);
+ SetHDisplayEnd(ucDisplayPath, usHDispEnd);
+
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "H blank start = %d\n", usHBlankStart);
+ SetHBlankingStart(ucDisplayPath, usHBlankStart);
+
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "H blank end = %d\n", usHBlankEnd);
+ SetHBlankingEnd(ucDisplayPath, usHBlankEnd);
+
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "H sync start = %d\n", usHSyncStart);
+ SetHSyncStart(ucDisplayPath, usHSyncStart);
+
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "H sync end = %d\n", usHSyncEnd);
+ SetHSyncEnd(ucDisplayPath, usHSyncEnd);
+
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "V total = %d\n", usVtotal);
+ SetVTotal(ucDisplayPath, usVtotal);
+
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "V disp end = %d\n", usVDispEnd);
+ SetVDisplayEnd(ucDisplayPath, usVDispEnd);
+
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "V blank start = %d\n", usVBlankStart);
+ SetVBlankingStart(ucDisplayPath, usVBlankStart);
+
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "V blank end = %d\n", usVBlankEnd);
+ SetVBlankingEnd(ucDisplayPath, usVBlankEnd);
+
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "V sync start = %d\n", usVSyncStart);
+ SetVSyncStart(ucDisplayPath, usVSyncStart);
+
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "V sync end = %d\n", usVSyncEnd);
+ SetVSyncEnd(ucDisplayPath, usVSyncEnd);
+
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "Pixel clock = %d\n", ulPixelClock);
+ SetPixelClock(ucDisplayPath, ulPixelClock);
+
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit SetTimingRegs()==\n");
+}
+
+/*-------------------------------------------------------------------
+;
+; SetHTotal()
+;
+; in:
+; DisplayPath = display path
+; Value = H total in pixel
+;
+;------------------------------------------------------------------*/
+void SetHTotal(UCHAR DisplayPath, USHORT Value)
+{
+ /* Subtract the 40 pixels for setting HW */
+ Value -= 40;
+
+ /* low-3-bits of H total has bug, HW will remove it. So the value have to align to 8*/
+ Value += 7;
+
+ if(DisplayPath == DISP1)
+ {
+ WriteRegToHW(HTotal1, Value);
+ }
+ else
+ {
+ WriteRegToHW(HTotal2, Value);
+ }
+
+ return;
+}
+
+/*-------------------------------------------------------------------
+;
+; SetHDisplayEnd()
+;
+; in:
+; DisplayPath = display path
+; Value = H display end in pixel
+;
+;------------------------------------------------------------------*/
+void SetHDisplayEnd(UCHAR DisplayPath, USHORT Value)
+{
+ /* Subtract the 8 pixels for setting HW */
+ Value -= 8;
+
+ if(DisplayPath == DISP1)
+ {
+ WriteRegToHW(HDispEnd1, Value);
+ }
+ else
+ {
+ WriteRegToHW(HDispEnd2, Value);
+ }
+
+ return;
+
+}
+
+/*-------------------------------------------------------------------
+;
+; SetHBlankingStart()
+;
+; in:
+; DisplayPath = display path
+; Value = H blanking start in pixel
+;
+;------------------------------------------------------------------*/
+void SetHBlankingStart(UCHAR DisplayPath, USHORT Value)
+{
+ /* Subtract the 8 pixels for setting HW */
+ Value -= 8;
+
+ if(DisplayPath == DISP1)
+ {
+ WriteRegToHW(HBnkSt1, Value);
+ }
+ else
+ {
+ WriteRegToHW(HBnkSt2, Value);
+ }
+
+ return;
+
+}
+
+/*-------------------------------------------------------------------
+;
+; SetHBlankingEnd()
+;
+; in:
+; DisplayPath = display path
+; Value = H blanking end in pixel
+;
+;------------------------------------------------------------------*/
+void SetHBlankingEnd(UCHAR DisplayPath, USHORT Value)
+{
+ /* Subtract the 8 pixels for setting HW */
+ Value -= 8;
+
+ if(DisplayPath == DISP1)
+ {
+ WriteRegToHW(HBnkEnd1, Value);
+ }
+ else
+ {
+ WriteRegToHW(HBnkEnd2, Value);
+ }
+
+ return;
+
+}
+
+/*-------------------------------------------------------------------
+;
+; SetHSyncStart()
+;
+; in:
+; DisplayPath = display path
+; Value = H Sync start in pixel
+;
+;------------------------------------------------------------------*/
+void SetHSyncStart(UCHAR DisplayPath, USHORT Value)
+{
+ /* Subtract the 0 pixels for setting HW */
+ Value -= 0;
+
+ if(DisplayPath == DISP1)
+ {
+ WriteRegToHW(HSyncSt1, Value);
+ }
+ else
+ {
+ WriteRegToHW(HSyncSt2, Value);
+ }
+
+ return;
+
+}
+
+/*-------------------------------------------------------------------
+;
+; SetHSyncEnd()
+;
+; in:
+; DisplayPath = display path
+; Value = H Sync end in pixel
+;
+;------------------------------------------------------------------*/
+void SetHSyncEnd(UCHAR DisplayPath, USHORT Value)
+{
+ /* Subtract the 0 pixels for setting HW */
+ Value -= 0;
+
+ if(DisplayPath == DISP1)
+ {
+ WriteRegToHW(HSyncEnd1, Value);
+ }
+ else
+ {
+ WriteRegToHW(HSyncEnd2, Value);
+ }
+
+ return;
+
+}
+
+/*-------------------------------------------------------------------
+;
+; SetVTotal()
+;
+; in:
+; DisplayPath = display path
+; Value = V total
+;
+;------------------------------------------------------------------*/
+void SetVTotal(UCHAR DisplayPath, USHORT Value)
+{
+ /* Subtract the 2 line for setting HW */
+ Value -= 2;
+
+ if(DisplayPath == DISP1)
+ {
+ WriteRegToHW(VTotal1, Value);
+ }
+ else
+ {
+ WriteRegToHW(VTotal2, Value);
+ }
+
+ return;
+
+}
+
+/*-------------------------------------------------------------------
+;
+; SetVDisplayEnd()
+;
+; in:
+; DisplayPath = display path
+; Value = V display end
+;
+;------------------------------------------------------------------*/
+void SetVDisplayEnd(UCHAR DisplayPath, USHORT Value)
+{
+ /* Subtract the 1 line for setting HW */
+ Value -= 1;
+
+ if(DisplayPath == DISP1)
+ {
+ WriteRegToHW(VDispEnd1, Value);
+ }
+ else
+ {
+ WriteRegToHW(VDispEnd2, Value);
+ }
+
+ return;
+
+}
+
+/*-------------------------------------------------------------------
+;
+; SetVBlankingStart()
+;
+; in:
+; DisplayPath = display path
+; Value = V blanking start
+;
+;------------------------------------------------------------------*/
+void SetVBlankingStart(UCHAR DisplayPath, USHORT Value)
+{
+ /* Subtract the 1 line for setting HW */
+ Value -= 1;
+
+ if(DisplayPath == DISP1)
+ {
+ WriteRegToHW(VBnkSt1, Value);
+ }
+ else
+ {
+ WriteRegToHW(VBnkSt2, Value);
+ }
+
+ return;
+
+}
+
+/*-------------------------------------------------------------------
+;
+; SetVBlankingEnd()
+;
+; in:
+; DisplayPath = display path
+; Value = V blanking end
+;
+;------------------------------------------------------------------*/
+void SetVBlankingEnd(UCHAR DisplayPath, USHORT Value)
+{
+ /* Subtract the 1 line for setting HW */
+ Value -= 1;
+
+ if(DisplayPath == DISP1)
+ {
+ WriteRegToHW(VBnkEnd1, Value);
+ }
+ else
+ {
+ WriteRegToHW(VBnkEnd2, Value);
+ }
+
+ return;
+
+}
+
+/*-------------------------------------------------------------------
+;
+; SetVSyncStart()
+;
+; in:
+; DisplayPath = display path
+; Value = V sync start
+;
+;------------------------------------------------------------------*/
+void SetVSyncStart(UCHAR DisplayPath, USHORT Value)
+{
+ /* Subtract the 1 line for setting HW */
+ Value -= 1;
+
+ if(DisplayPath == DISP1)
+ {
+ WriteRegToHW(VSyncSt1, Value);
+ }
+ else
+ {
+ WriteRegToHW(VSyncSt2, Value);
+ }
+
+ return;
+
+}
+
+/*-------------------------------------------------------------------
+;
+; SetVSyncEnd()
+;
+; in:
+; DisplayPath = display path
+; Value = V sync end
+;
+;------------------------------------------------------------------*/
+void SetVSyncEnd(UCHAR DisplayPath, USHORT Value)
+{
+ /* Subtract the 1 line for setting HW */
+ Value -= 1;
+
+ if(DisplayPath == DISP1)
+ {
+ WriteRegToHW(VSyncEnd1, Value);
+ }
+ else
+ {
+ WriteRegToHW(VSyncEnd2, Value);
+ }
+
+ return;
+
+}
+
+/*-------------------------------------------------------------------
+;
+; SetPixelClock()
+;
+; in:
+; DisplayPath = display path
+; Clock = pixel clock in khz
+;
+;------------------------------------------------------------------*/
+void SetPixelClock(UCHAR bDisplayPath, ULONG dwClock)
+{
+ PLL_Info PLLInfo;
+
+ PLLInfo = ClockToPLLF9003A(dwClock);
+ SetDPLL(bDisplayPath, PLLInfo);
+}
+/*-------------------------------------------------------------------
+;
+; SetHSource()
+;
+; in:
+; DisplayPath = display path
+; wValue = number of pixels of source data
+;
+;------------------------------------------------------------------*/
+void SetHSource(UCHAR bDisplayPath, USHORT wValue)
+{
+ wValue -= 1;
+
+ if(bDisplayPath == DISP1)
+ {
+ WriteRegToHW(HSource1, wValue);
+ }
+ else
+ {
+ WriteRegToHW(HSource2, wValue);
+ }
+}
+
+
+/*-------------------------------------------------------------------
+;
+; ClockToPLLF9003A()
+;
+; in:
+; Clock = pixel clock in khz
+; return:
+; PLL_Info = PLL value
+;
+;------------------------------------------------------------------*/
+PLL_Info ClockToPLLF9003A(ULONG Clock)
+{
+ ULONG MSCount, NSCount, RSCount, FCKVCO, FCKOUT; /*defined in PLL module */
+ ULONG NearestClock = 0xFFFFFFFF;
+ PLL_Info PLLInfo;
+
+ for (MSCount = 3; MSCount < 6; MSCount++)
+ {
+ for (NSCount = 1; NSCount < 256; NSCount++)
+ {
+ FCKVCO = PLLReferenceClock * NSCount / MSCount;
+
+ if ( (MaxFCKVCO9003A >= FCKVCO) && (FCKVCO >= MinFCKVCO9003A) )
+ {
+ for (RSCount = 1; RSCount < 6; RSCount++)
+ {
+ FCKOUT = FCKVCO >> RSCount;
+ if ( Difference(FCKOUT, Clock) < Difference(NearestClock, Clock) )
+ {
+ NearestClock = FCKOUT;
+ if (MSCount == 3)
+ PLLInfo.MS = 0x00;
+ if (MSCount == 4)
+ PLLInfo.MS = BIT3;
+ if (MSCount == 5)
+ PLLInfo.MS = BIT4+BIT3;
+ PLLInfo.NS = (UCHAR)NSCount;
+ PLLInfo.RS = (UCHAR)RSCount-1;
+ }
+ }
+ }
+ }
+
+ }
+
+ return PLLInfo;
+
+}
+
+/*-------------------------------------------------------------------
+;
+; SetDPLL() - set display PLL
+;
+; in:
+; DisplayPath = display path
+; PLLInfo: PLL value
+;
+;------------------------------------------------------------------*/
+void SetDPLL(UCHAR DisplayPath, PLL_Info PLLInfo)
+{
+ UCHAR RetValue;
+
+ if (DisplayPath == DISP1)
+ {
+ SetCRReg(0xC1, PLLInfo.MS, BIT4+BIT3);
+ SetCRReg(0xC0, PLLInfo.NS, 0xFF);
+ SetCRReg(0xCF, PLLInfo.RS, BIT2+BIT1+BIT0);
+ }
+ else
+ {
+ SetCRReg(0xBF, PLLInfo.MS, BIT4+BIT3);
+ SetCRReg(0xBE, PLLInfo.NS, 0xFF);
+ SetCRReg(0xCE, PLLInfo.RS, BIT2+BIT1+BIT0);
+ }
+
+ /* Fire the PLL setting */
+ RetValue = GetCRReg(0xBB);
+ SetCRReg(0xBB, RetValue, 0xFF);
+
+}
+
+/*-------------------------------------------------------------------
+;
+; SetPolarity()
+;
+; in:
+; DisplayPath = display path
+; Value: bit1 = 1 for positive H sync
+; = 0 for negative H sync
+; bit2 = 1 for positive V sync
+; = 0 for negative V sync
+;------------------------------------------------------------------*/
+void SetPolarity(UCHAR DevicePort, UCHAR Value)
+{
+ Value ^= BIT2+BIT1; /* invert Bit[2:1] */
+
+ switch (DevicePort)
+ {
+ case CRT_PORT:
+ OutPort(MISC_WRITE, ((Value<<5) & 0xC0) | (InPort(MISC_READ) & 0x3F));
+ break;
+
+ case DVP1:
+ case DVP12:
+ SetSRReg(0x20, Value>>1, BIT1+BIT0);
+ break;
+
+ case DVP2:
+ SetSRReg(0x20, Value<<2, BIT4+BIT3);
+ break;
+ }
+}
+
+/*-------------------------------------------------------------------
+;
+; SetFIFO()
+;
+; in:
+; DisplayPath = display path
+; out:
+; none
+;------------------------------------------------------------------*/
+void SetFIFO(UCHAR DisplayPath)
+{
+ if (DisplayPath == DISP1)
+ {
+ SetCRReg(0xA7, 0x3F, 0xFF);
+ SetCRReg(0xA6, 0x3F, 0xFF);
+ }
+ else if (DisplayPath == DISP2)
+ {
+ SetCRReg(0x35, 0x3F, 0xFF);
+ SetCRReg(0x34, 0x3F, 0xFF);
+ }
+}
+
+/*-------------------------------------------------------------------
+;
+; SetPitch()
+;
+; in:
+; DisplayPath = display path
+; Value = Pitch in byte
+;
+;------------------------------------------------------------------*/
+void SetPitch(UCHAR DisplayPath, USHORT Value)
+{
+ /* adjust pitch in 8 byte alignment */
+ Value += 7;
+ Value >>= 3;
+
+ if(DisplayPath == DISP1)
+ {
+ WriteRegToHW(Pitch1, Value);
+ }
+ else
+ {
+ WriteRegToHW(Pitch2, Value);
+ }
+
+ return;
+
+}
+
+/*-------------------------------------------------------------------
+;
+; GetPitch()
+;
+; in:
+; DisplayPath = display path
+; out:
+; return pitch in byte
+;
+;------------------------------------------------------------------*/
+USHORT GetPitch(UCHAR DisplayPath)
+{
+ USHORT wPitch;
+
+ if(DisplayPath == DISP1)
+ {
+ wPitch = ReadRegFromHW(Pitch1);
+ }
+ else
+ {
+ wPitch = ReadRegFromHW(Pitch2);
+ }
+
+ wPitch <<= 3;
+
+ return wPitch;
+}
+
+/*-------------------------------------------------------------------
+;
+; GetVDisplayEnd()
+;
+; in:
+; DisplayPath = display path
+; out:
+; return V disp end
+;
+;------------------------------------------------------------------*/
+USHORT GetVDisplayEnd(UCHAR DisplayPath)
+{
+ USHORT wDisplayEnd = 0x0;
+
+ if(DisplayPath == DISP1)
+ {
+ wDisplayEnd = ReadRegFromHW(VDispEnd1);
+ }
+ else
+ {
+ wDisplayEnd = ReadRegFromHW(VDispEnd2);
+ }
+
+ /* Add 1 for query value. */
+ wDisplayEnd += 1;
+
+ return wDisplayEnd;
+}
+
+/*-------------------------------------------------------------------
+;
+; SetColorDepth()
+;
+; in:
+; DisplayPath = display path
+; Value = color depth (8/16/32)
+;
+;------------------------------------------------------------------*/
+void SetColorDepth(UCHAR DisplayPath, UCHAR Value)
+{
+ UCHAR bSetBit = 0x0;
+
+ switch(Value)
+ {
+ case 8:
+ bSetBit = (UCHAR)BIT0;
+ break;
+ case 16:
+ bSetBit = (UCHAR)BIT2;
+ break;
+ case 32:
+ bSetBit = (UCHAR)BIT3;
+ break;
+ default:
+ return;
+ }
+
+ if(DisplayPath == DISP1)
+ {
+ SetCRReg(0xA3, bSetBit, 0x0F);
+ }
+ else
+ {
+ /* Display2 would not support 8bit color depth */
+ if(Value == 8)
+ return;
+
+ SetCRReg(0x33, bSetBit, 0x0F);
+ }
+
+}
+
+/*-------------------------------------------------------------------
+;
+; ConfigDigitalPort()
+;
+; in:
+; bDisplayPath = display path
+;
+;------------------------------------------------------------------*/
+void ConfigDigitalPort(UCHAR bDisplayPath)
+{
+ PORT_CONFIG *pDevicePortConfig;
+ UCHAR bDeviceIndex;
+ UCHAR bRegValue;
+
+ bDeviceIndex = Get_DEV_ID(bDisplayPath);
+
+ if(bDisplayPath == DISP1)
+ {
+ bRegValue = 0x3;
+ }
+ else
+ {
+ bRegValue = 0x4;
+ }
+
+ if (GetDevicePortConfig(bDeviceIndex, &pDevicePortConfig))
+ {
+ switch(pDevicePortConfig->PortID)
+ {
+ case CRT_PORT:
+ SetSRReg(0x1F, bRegValue, BIT2);
+ break;
+
+ case DVP1:
+ Set12BitDVP();
+ SetSRReg(0x1F, bRegValue, BIT0);
+ break;
+
+ case DVP2:
+ Set12BitDVP();
+ SetSRReg(0x1F, bRegValue, BIT1);
+ break;
+
+ case DVP12:
+ Set24BitDVP();
+ SetSRReg(0x1F, bRegValue, BIT0);
+ break;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+;
+; LoadTiming
+;
+; in:
+; bDisplayPath = display path
+; wModeNum = mode no.
+;
+;---------------------------------------------------------------------------*/
+void LoadTiming(UCHAR bDisplayPath, USHORT wModeNum)
+{
+ UCHAR bDeviceIndex = Get_DEV_ID(bDisplayPath);
+
+ /* Obtain the display device */
+
+ switch(bDeviceIndex)
+ {
+ case CRT_ID:
+ case CRT2_ID:
+ case DVI_ID:
+ case DVI2_ID:
+ LoadVESATiming(bDisplayPath, wModeNum);
+ break;
+
+ case LCD_ID:
+ case LCD2_ID:
+ LoadLCDTiming(bDisplayPath, wModeNum);
+ break;
+ }
+
+}
+
+/*----------------------------------------------------------------------------
+;
+; LoadVESATiming
+;
+; in:
+; bDisplayPath = display path
+; wModeNum = mode no.
+;
+;---------------------------------------------------------------------------*/
+void LoadVESATiming(UCHAR bDisplayPath, USHORT wModeNum)
+{
+ UCHAR bR_Rate_value = 0x0;
+ MODE_INFO *pModeInfo = NULL;
+ RRATE_TABLE *pRRateTable = NULL;
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Enter LoadVESATiming()==\n");
+ bR_Rate_value = Get_RRATE_ID(bDisplayPath);
+
+ if(GetModePointerFromVESATable(wModeNum, bR_Rate_value, &pModeInfo, &pRRateTable))
+ {
+ SetTimingRegs(bDisplayPath, pModeInfo, pRRateTable);
+ }
+ else
+ {
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "Mode not found!!\n");
+ /*ASSERT(true); */
+ }
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit LoadVESATiming()==\n");
+}
+/*----------------------------------------------------------------------------
+;
+; LoadLCDTiming
+;
+; in:
+; bDisplayPath = display path
+; wModeNum = mode no.
+;
+;---------------------------------------------------------------------------*/
+void LoadLCDTiming(UCHAR bDisplayPath, USHORT wModeNum)
+{
+ UCHAR bDeviceIndex = Get_DEV_ID(bDisplayPath);
+ MODE_INFO *pPanelModeInfo, *pUserModeInfo;
+ PANEL_TABLE *pPanelTable;
+
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Enter LoadLCDTiming()==\n");
+
+ if(GetModePointerFromLCDTable(bDeviceIndex, &pPanelModeInfo, &pPanelTable))
+ {
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "&pPanelTable->Timing = 0x%x\n", &pPanelTable->Timing);
+ SetTimingRegs(bDisplayPath, pPanelModeInfo, &pPanelTable->Timing);
+ Get_MODE_INFO(wModeNum, &pUserModeInfo);
+ SetScalingFactor(bDisplayPath, pUserModeInfo, pPanelModeInfo);
+ }
+ else
+ {
+ /*ASSERT(true); */
+ }
+
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit LoadLCDTiming()==\n");
+}
+/*----------------------------------------------------------------------------
+;
+; SetScalingFactor
+;
+; in:
+; pUserModeInfo = pointer to MODE_INFO of user mode
+; pPanelModeInfo = pointer to LCD MODE_INFO of panel
+;
+;---------------------------------------------------------------------------*/
+void SetScalingFactor(UCHAR bDisplayPath, MODE_INFO *pUserModeInfo, MODE_INFO *pPanelModeInfo)
+{
+ ULONG dwScalingFactor;
+
+ USHORT usUserModeHSize, usUserModeVSize;
+ USHORT usPanelModeHSize, usPanelModeVSize;
+
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Enter SetScalingFactor()==\n");
+ usUserModeHSize = pUserModeInfo->H_Size;
+
+ usUserModeVSize = pUserModeInfo->V_Size;
+
+ usPanelModeHSize = pPanelModeInfo->H_Size;
+
+ usPanelModeVSize = pPanelModeInfo->V_Size;
+
+
+ TurnOffHorScaler(bDisplayPath);
+
+ TurnOffVerScaler(bDisplayPath);
+
+ SetHSource(bDisplayPath, usUserModeHSize);
+
+
+ if (usPanelModeHSize > usUserModeHSize)
+ {
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "Enable H scaler\n");
+ dwScalingFactor = ((ULONG)usUserModeHSize << 12) / usPanelModeHSize;
+ SetHorScalingFactor(bDisplayPath, dwScalingFactor);
+ TurnOnHorScaler(bDisplayPath);
+ TurnOnScaler(bDisplayPath);
+ }
+
+ if (usPanelModeVSize > usUserModeVSize)
+ {
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "Enable V scaler\n");
+ dwScalingFactor = ((ULONG)usUserModeVSize << 11) / usPanelModeVSize;
+ SetVerScalingFactor(bDisplayPath, dwScalingFactor);
+ TurnOnVerScaler(bDisplayPath);
+ TurnOnScaler(bDisplayPath);
+ }
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit SetScalingFactor()==\n");
+}
+/*-------------------------------------------------------------------
+;
+; SetHorScalingFactor()
+;
+; in:
+; DisplayPath = display path
+; wValue = scaling factor
+;
+;------------------------------------------------------------------*/
+void SetHorScalingFactor(UCHAR bDisplayPath, USHORT wValue)
+{
+ if(bDisplayPath == DISP1)
+ {
+ WriteRegToHW(HScalingFactor1, wValue);
+ }
+ else
+ {
+ WriteRegToHW(HScalingFactor2, wValue);
+ }
+}
+/*-------------------------------------------------------------------
+;
+; SetVerScalingFactor()
+;
+; in:
+; DisplayPath = display path
+; wValue = scaling factor
+;
+;------------------------------------------------------------------*/
+void SetVerScalingFactor(UCHAR bDisplayPath, USHORT wValue)
+{
+ if(bDisplayPath == DISP1)
+ {
+ WriteRegToHW(VScalingFactor1, wValue);
+ }
+ else
+ {
+ WriteRegToHW(VScalingFactor2, wValue);
+ }
+}
+/*-------------------------------------------------------------------
+;
+; isLCDFitMode() -
+;
+; Input:
+; bDeviceIndex = LCD/LCD2
+; wModeNom = mode number
+; return:
+; true if wModeNom is LCD fit mode
+;
+;------------------------------------------------------------------*/
+CI_STATUS isLCDFitMode(UCHAR bDeviceIndex, USHORT wModeNum)
+{
+ MODE_INFO *pModeInfo;
+
+ if (Get_MODE_INFO_From_LCD_Table(bDeviceIndex, &pModeInfo))
+ {
+ if ((wModeNum == pModeInfo->Mode_ID_8bpp) ||
+ (wModeNum == pModeInfo->Mode_ID_16bpp) ||
+ (wModeNum == pModeInfo->Mode_ID_32bpp))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+}
+/*----------------------------------------------------------------------------
+;
+; GetModePointerFromVESATable
+;
+; in:
+; wModeNum = mode no.
+; bRRIndex = refresh rate index
+; out:
+; return = true, pModeInfo = pointer to MODE_INFO
+; pRRateTable = pointer to RRATE_TABLE
+; = false, fail
+;
+;---------------------------------------------------------------------------*/
+CI_STATUS GetModePointerFromVESATable(USHORT wModeNum, UCHAR ucRRIndex, MODE_INFO **ppModeInfo, RRATE_TABLE **ppRRateTable)
+{
+ int iRRateTableIndex;
+
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Enter GetModePointerFromVESATable()==\n");
+
+ /* Don't find out any fit mode table in the vesa table */
+ if(Get_MODE_INFO_From_VESA_Table(wModeNum, ppModeInfo))
+ {
+ /* Obtain the frequence table. */
+ *ppRRateTable = (RRATE_TABLE*)((int)(*ppModeInfo) + sizeof(MODE_INFO));
+
+ for(iRRateTableIndex = 0; iRRateTableIndex < (*ppModeInfo)->RRTableCount; iRRateTableIndex++, (*ppRRateTable)++)
+ {
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "*ppRRateTable = 0x%x\n", *ppRRateTable);
+
+ if(((*ppRRateTable)->RRate_ID == ucRRIndex) && (!((*ppRRateTable)->Attribute & DISABLE)))
+ {
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "*ppRRateTable = 0x%x\n", *ppRRateTable);
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, " Exit1 GetModePointerFromVESATable()== return success\n");
+ return true;
+ }
+ }
+ }
+
+ /* Can't find any fresh rate be conformed */
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, " Exit2 GetModePointerFromVESATable()== return fail!!\n");
+ return false;
+}
+
+/*----------------------------------------------------------------------------
+;
+; GetModePointerFromLCDTable
+;
+; in:
+; bDeviceIndex = device index
+; out:
+; return = true, ppPanelInfo = pointer to PANEL_INFO
+; pPanelTable = pointerto PANEL_TABLE
+; = false, fail
+;
+;---------------------------------------------------------------------------*/
+CI_STATUS GetModePointerFromLCDTable(UCHAR bDeviceIndex, MODE_INFO **ppModeInfo, PANEL_TABLE **ppPanelTable)
+{
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Enter GetModePointerFromLCDTable()==\n");
+ if (Get_MODE_INFO_From_LCD_Table(bDeviceIndex, ppModeInfo))
+ {
+ *ppPanelTable = (PANEL_TABLE*)((int)(*ppModeInfo) + sizeof(MODE_INFO));
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "*ppPanelTable = 0x%x\n", *ppPanelTable);
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit1 GetModePointerFromLCDTable()== return success\n");
+ return true;
+ }
+ else
+ {
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit1 GetModePointerFromLCDTable()== return fail\n");
+ return false;
+ }
+}
+/*----------------------------------------------------------------------------
+;
+; Get_MODE_INFO
+;
+; in:
+; wModeNum = mode no.
+; out:
+; return = true, pModeInfo = pointer to MODE_INFO
+; = false, fail
+;
+;---------------------------------------------------------------------------*/
+CI_STATUS Get_MODE_INFO(USHORT wModeNum, MODE_INFO **ppModeInfo)
+{
+ if (Get_MODE_INFO_From_VESA_Table(wModeNum, ppModeInfo))
+ {
+ return true;
+ }
+ else if(isLCDFitMode(LCD_ID, wModeNum))
+ {
+ Get_MODE_INFO_From_LCD_Table(LCD_ID, ppModeInfo);
+ return true;
+ }
+ else if(isLCDFitMode(LCD2_ID, wModeNum))
+ {
+ Get_MODE_INFO_From_LCD_Table(LCD2_ID, ppModeInfo);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+/*----------------------------------------------------------------------------
+;
+; Get_MODE_INFO_From_LCD_Table
+;
+; in:
+; bDeviceIndex = device index.
+; out:
+; return = true, pModeInfo = pointer to PANEL_INFO
+; = false, fail
+;
+;---------------------------------------------------------------------------*/
+CI_STATUS Get_MODE_INFO_From_LCD_Table(UCHAR bDeviceIndex, MODE_INFO **ppModeInfo)
+{
+ int i;
+ UCHAR bLCDTableIndex;
+
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Enter Get_MODE_INFO_From_LCD_Table()==\n");
+
+ *ppModeInfo = pLCDTable;
+
+ if (bDeviceIndex == LCD_ID)
+ {
+ bLCDTableIndex = Get_LCD_TABLE_INDEX();
+ }
+ else if (bDeviceIndex == LCD2_ID)
+ {
+ bLCDTableIndex = Get_LCD2_TABLE_INDEX();
+ }
+ else
+ {
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit1 Get_MODE_INFO_From_LCD_Table()== return fail!!\n");
+ return false;
+ }
+
+
+ if (bLCDTableIndex == 0)
+ {
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "LCD Index = 0\n");
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit2 Get_MODE_INFO_From_LCD_Table()== return fail!!\n");
+ return false;
+ }
+
+ while ((*ppModeInfo)->H_Size != 0xFFFF)
+ {
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "(*ppModeInfo)->H_Size = %d\n", (*ppModeInfo)->H_Size);
+
+ if (bLCDTableIndex == 1)
+ {
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit3 Get_MODE_INFO_From_LCD_Table()== return success\n");
+ return true;
+ }
+ (*ppModeInfo) = (MODE_INFO*)((int)*ppModeInfo + sizeof(MODE_INFO) + sizeof(PANEL_TABLE));
+ bLCDTableIndex--;
+ }
+
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit4 Get_MODE_INFO_From_LCD_Table()== return fail!!\n");
+
+ return false;
+
+}
+/*----------------------------------------------------------------------------
+;
+; Get_MODE_INFO_From_VESA_Table
+;
+; in:
+; wModeNum = mode no.
+; out:
+; return = true, pModeInfo = pointer to MODE_INFO
+; = false, fail
+;
+;---------------------------------------------------------------------------*/
+#if 0
+CI_STATUS Get_MODE_INFO_From_VESA_Table(USHORT wModeNum, MODE_INFO **ppModeInfo)
+{
+ int i;
+ VESA_TABLE *pVESATable = VESATable;
+
+ for( i = 0; i < (sizeof(VESATable)/sizeof(VESA_TABLE)); i++, pVESATable++)
+ {
+ if((pVESATable->ModeInfo.Mode_ID_8bpp == wModeNum) || (pVESATable->ModeInfo.Mode_ID_16bpp == wModeNum)|| (pVESATable->ModeInfo.Mode_ID_32bpp == wModeNum))
+ {
+ *ppModeInfo = &(pVESATable->ModeInfo);
+ return true;
+ }
+ }
+
+ return false;
+}
+#else
+CI_STATUS Get_MODE_INFO_From_VESA_Table(USHORT wModeNum, MODE_INFO **ppModeInfo)
+{
+ UCHAR ucColorDepth;
+
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Enter Get_MODE_INFO_From_VESA_Table()==\n");
+
+ *ppModeInfo = pVESATable;
+
+ while((*ppModeInfo)->H_Size != 0xFFFF)
+ {
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "*ppModeInfo = 0x%x\n", *ppModeInfo);
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "(*ppModeInfo)->H_Size = %d\n", (*ppModeInfo)->H_Size);
+
+ if (GetModeColorDepth(wModeNum, *ppModeInfo, &ucColorDepth))
+ {
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "*ppModeInfo = 0x%x\n", *ppModeInfo);
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, " Exit1 Get_MODE_INFO_From_VESA_Table()== return success\n");
+ return true;
+ }
+
+ *ppModeInfo = (MODE_INFO*)((*ppModeInfo)->RRTableCount * sizeof(RRATE_TABLE) + sizeof(MODE_INFO) + (void*)(*ppModeInfo));
+ }
+
+ *ppModeInfo = (MODE_INFO*)(&CInt10VESATable);
+
+ while((*ppModeInfo)->H_Size != 0xFFFF)
+ {
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "*ppModeInfo = 0x%x\n", *ppModeInfo);
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "(*ppModeInfo)->H_Size = %d\n", (*ppModeInfo)->H_Size);
+
+ if (GetModeColorDepth(wModeNum, *ppModeInfo, &ucColorDepth))
+ {
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "*ppModeInfo = 0x%x\n", *ppModeInfo);
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, " Exit1 Get_MODE_INFO_From_VESA_Table()== return success\n");
+ return true;
+ }
+
+ *ppModeInfo = (MODE_INFO*)((*ppModeInfo)->RRTableCount * sizeof(RRATE_TABLE) + sizeof(MODE_INFO) + (void*)(*ppModeInfo));
+ }
+
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, " Exit2 Get_MODE_INFO_From_VESA_Table()== return fail!!\n");
+ return false;
+}
+#endif
+/*----------------------------------------------------------------------------
+;
+; GetModeColorDepth
+;
+; in:
+; wModeNum = mode no.
+; pMODE_INFO = pointer to MODE_INFO
+; out:
+; return = true, *pbColorDepth = color depth
+; = false, fail
+;
+;---------------------------------------------------------------------------*/
+CI_STATUS GetModeColorDepth(USHORT wModeNum, MODE_INFO *pModeInfo, UCHAR *pucColorDepth)
+{
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Enter GetModeColorDepth()==\n");
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "pModeInfo->Mode_ID_8bpp = 0x%x\n", pModeInfo->Mode_ID_8bpp);
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "pModeInfo->Mode_ID_16bpp = 0x%x\n", pModeInfo->Mode_ID_16bpp);
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "pModeInfo->Mode_ID_32bpp = 0x%x\n", pModeInfo->Mode_ID_32bpp);
+#endif
+ if(pModeInfo->Mode_ID_8bpp == wModeNum)
+ {
+ *pucColorDepth = 8;
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit1 GetModeColorDepth()== *pucColorDepth = %d\n", *pucColorDepth);
+#endif
+ return true;
+ }
+ else if(pModeInfo->Mode_ID_16bpp == wModeNum)
+ {
+ *pucColorDepth = 16;
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit2 GetModeColorDepth()== *pucColorDepth = %d\n", *pucColorDepth);
+#endif
+ return true;
+ }
+ else if(pModeInfo->Mode_ID_32bpp == wModeNum)
+ {
+ *pucColorDepth = 32;
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit3 GetModeColorDepth()== *pucColorDepth = %d\n", *pucColorDepth);
+#endif
+ return true;
+ }
+ else
+ {
+ *pucColorDepth = 0;
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit4 GetModeColorDepth()== *pucColorDepth = %d\n", *pucColorDepth);
+#endif
+ return false;
+ }
+}
+/*----------------------------------------------------------------------------
+;
+; GetModePitch()
+;
+; In:
+; ModeNum = mode no
+; Out:
+; return = true, *pPitch = pitch in byte
+; = false, fail
+;
+;---------------------------------------------------------------------------*/
+CI_STATUS GetModePitch(USHORT ModeNum, USHORT *pPitch)
+{
+ MODE_INFO *pModeInfo = NULL;
+ UCHAR ucColorDepth = 0;
+
+ /* Don't find out any fit mode table in the vesa table */
+ if(!Get_MODE_INFO(ModeNum, &pModeInfo))
+ {
+ return false;
+ }
+ else
+ {
+ if(!GetModeColorDepth(ModeNum, pModeInfo, &ucColorDepth))
+ {
+ return false;
+ }
+ else
+ {
+ ucColorDepth = ucColorDepth >> 4;
+ *pPitch = ((pModeInfo->H_Size << ucColorDepth)+0x7)&0xFFF8;
+ }
+ }
+
+ return true;
+}
+/*----------------------------------------------------------------------------
+;
+; ReadRegFromHW
+;
+; in:
+; pRegOp = pointer to REG_OP table
+; out:
+; return = register value
+;
+;---------------------------------------------------------------------------*/
+USHORT ReadRegFromHW(REG_OP *pRegOp)
+{
+ USHORT wValue = 0x0;
+ UCHAR btemp = 0x0, bMasktemp = 0x0;
+
+ while((pRegOp->RegGroup)!= NR)
+ {
+ if(pRegOp->RegGroup == CR)
+ {
+ /*CR */
+ OutPort(COLOR_CRTC_INDEX,(pRegOp->RegIndex));
+ btemp = (UCHAR)InPort(COLOR_CRTC_DATA);
+ }
+ else
+ {
+ /*SR */
+ OutPort(SEQ_INDEX,(pRegOp->RegIndex));
+ btemp = (UCHAR)InPort(SEQ_DATA);
+ }
+
+ bMasktemp = (pRegOp->RegMask);
+
+ /* Mask the bit that we need. */
+ btemp &= bMasktemp;
+
+ /* Shift all register into LSB. */
+ while(!(bMasktemp & BIT0))
+ {
+ bMasktemp = bMasktemp >> 1;
+ btemp = btemp >> 1;
+ }
+
+ /* Shift the register and add in the value. */
+ wValue |= (((USHORT)btemp) << (pRegOp->RegShiftBit));
+
+ /* Next register. */
+ pRegOp++;
+
+ }
+
+ return wValue;
+}
+
+/*----------------------------------------------------------------------------
+;
+; WriteRegToHW
+;
+; in:
+; pRegOp = pointer to REG_OP table
+; value = value to be written
+;
+;---------------------------------------------------------------------------*/
+void WriteRegToHW(REG_OP *pRegOp, USHORT value)
+{
+ UCHAR btemp, btemp1;
+ UCHAR bCount;
+ UCHAR bMasktemp;
+
+ while((pRegOp->RegGroup)!= NR)
+ {
+ btemp = 0x0; btemp1 = 0x0;
+ bCount = 0x0; bMasktemp = 0x0;
+
+ bMasktemp = (pRegOp->RegMask);
+
+ /* Shift all register into LSB. */
+ while(!(bMasktemp & BIT0))
+ {
+ bMasktemp = bMasktemp >> 1;
+ bCount ++;
+ }
+
+ /* Calculate the value that we need to set into register. */
+ btemp = value >> (pRegOp->RegShiftBit);
+ btemp &= (bMasktemp);
+
+ /* Shift the data bit into right position. */
+ if(!(pRegOp->RegMask & BIT0))
+ {
+ btemp = btemp << bCount;
+ }
+
+ if(pRegOp->RegGroup == CR)
+ {
+ /*CR */
+ OutPort(COLOR_CRTC_INDEX,(pRegOp->RegIndex));
+ btemp1 = (UCHAR)InPort(COLOR_CRTC_DATA);
+ btemp1 &= ~(pRegOp->RegMask);
+ btemp1 |= btemp;
+ OutPort(COLOR_CRTC_DATA,btemp1);
+ }
+ else
+ {
+ /*SR */
+ OutPort(SEQ_INDEX,(pRegOp->RegIndex));
+ btemp1 = (UCHAR)InPort(SEQ_DATA);
+ btemp1 &= ~(pRegOp->RegMask);
+ btemp1 |= btemp;
+ OutPort(SEQ_DATA,btemp1);
+ }
+
+ pRegOp++;
+
+ }
+
+}
+
+/*----------------------------------------------------------------------------
+;
+; UnLockCR0ToCR7
+;
+; in:
+; none
+; out:
+; none
+;
+;---------------------------------------------------------------------------*/
+void UnLockCR0ToCR7()
+{
+ /* CR11[7] = 0 */
+ SetCRReg(0x11, 0x00, BIT7);
+}
+
+/*----------------------------------------------------------------------------
+;
+; LockCR0ToCR7
+;
+; in:
+; none
+; out:
+; none
+;
+;---------------------------------------------------------------------------*/
+void LockCR0ToCR7()
+{
+ /* CR11[7] = 1 */
+ SetCRReg(0x11, 0x80, BIT7);
+}
+
+/*----------------------------------------------------------------------------
+;
+; CheckForModeAvailable
+;
+; in:
+; ModeNum = mode no.
+; out:
+; return = true, if mode is available. Else, return false
+;
+;---------------------------------------------------------------------------*/
+CI_STATUS CheckForModeAvailable(USHORT ModeNum)
+{
+ MODE_INFO *pModeInfo = NULL;
+ return Get_MODE_INFO_From_VESA_Table(ModeNum, &pModeInfo);
+}
+/*--------------------------------------------------------------------
+;
+; CheckForNewDeviceAvailable() -
+;
+; Input:
+; bDeviceIndex = device index
+; return:
+; true if device is supported
+;--------------------------------------------------------------------*/
+CI_STATUS CheckForNewDeviceAvailable(UCHAR bDeviceIndex)
+{
+ PORT_CONFIG *pDevicePortConfig;
+
+ return GetDevicePortConfig(bDeviceIndex, &pDevicePortConfig);
+}
+
+void Display1TurnOnTX()
+{
+
+}
+
+void Display1TurnOffTX()
+{
+
+}
+
+void Display2TurnOnTX()
+{
+
+}
+
+void Display2TurnOffTX()
+{
+
+}
+
+/*----------------------------------------------------------------------------
+;
+; TurnOnDigitalPort
+;
+; in:
+; DisplayPath = device index
+;
+;---------------------------------------------------------------------------*/
+void TurnOnDigitalPort(UCHAR bDeviceIndex)
+{
+ PORT_CONFIG *pDevicePortConfig;
+
+ if (GetDevicePortConfig(bDeviceIndex, &pDevicePortConfig))
+ {
+ switch(pDevicePortConfig->PortID)
+ {
+ case CRT_PORT:
+ TurnOnDAC();
+ TurnOnCRTPad();
+ break;
+
+ case DVP1:
+ TurnOnDVP1Pad();
+ break;
+
+ case DVP2:
+ TurnOnDVP2Pad();
+ break;
+
+ case DVP12:
+ TurnOnDVP12Pad();
+ break;
+ }
+ }
+}
+/*----------------------------------------------------------------------------
+;
+; TurnOffDigitalPort
+;
+; in:
+; bDeviceIndex = device index
+;
+;---------------------------------------------------------------------------*/
+void TurnOffDigitalPort(UCHAR bDeviceIndex)
+{
+ PORT_CONFIG *pDevicePortConfig;
+
+ if (GetDevicePortConfig(bDeviceIndex, &pDevicePortConfig))
+
+ switch(pDevicePortConfig->PortID)
+ {
+ case CRT_PORT:
+ TurnOffCRTPad();
+// TurnOffDAC();
+ break;
+
+ case DVP1:
+ TurnOffDVP1Pad();
+ break;
+
+ case DVP2:
+ TurnOffDVP2Pad();
+ break;
+
+ case DVP12:
+ TurnOffDVP12Pad();
+ break;
+ }
+}
+
+/*-----------------------------------------------------------------------------
+;
+; GetPortConnectPath
+;
+; in:
+; PortType = 0: CRT port, 1: DVP1, 2: DVP2, 3: 24-bit DVP1+2
+; out:
+; return = 0 if port connecting on display1
+; = 1 if port connecting on display2
+;
+;-----------------------------------------------------------------------------*/
+UCHAR GetPortConnectPath(UCHAR PortType)
+{
+ UCHAR SR1F, PortMask;
+
+ SR1F = GetSRReg(0x1F);
+ SR1F ^= 0x03;
+
+ switch(PortType)
+ {
+ case CRT_PORT:
+ PortMask = BIT2;
+ break;
+
+ case DVP1:
+ case DVP12:
+ PortMask = BIT0;
+ break;
+
+ case DVP2:
+ PortMask = BIT1;
+ break;
+ }
+
+ return ((SR1F & PortMask) ? 1 : 0);
+
+}
+
+/*----------------------------------------------------------------------------
+;
+; TransDevIDtoBit
+;
+; in:
+; DeviceIndex = device index
+; out:
+; return device bit
+;
+;---------------------------------------------------------------------------*/
+USHORT TransDevIDtoBit(UCHAR DeviceIndex)
+{
+ return (1 << (DeviceIndex - 1));
+}
+
+void TurnOnCRTPad()
+{
+ SetCRReg(0xA8, 0x00, BIT7);
+}
+
+void TurnOffCRTPad()
+{
+ SetCRReg(0xA8, 0x80, BIT7);
+}
+
+void TurnOnDVP1Pad()
+{
+ SetCRReg(0xA3, 0x80, BIT7);
+}
+
+void TurnOffDVP1Pad()
+{
+ SetCRReg(0xA3, 0x00, BIT7);
+}
+
+void TurnOnDVP2Pad()
+{
+ SetCRReg(0xA3, 0x40, BIT6);
+}
+
+void TurnOffDVP2Pad()
+{
+ SetCRReg(0xA3, 0x00, BIT6);
+}
+
+void TurnOnDVP12Pad()
+{
+ TurnOnDVP1Pad();
+ TurnOnDVP2Pad();
+}
+
+void TurnOffDVP12Pad()
+{
+ TurnOffDVP1Pad();
+ TurnOffDVP2Pad();
+}
+
+void TurnOnScaler(UCHAR bDisplayPath)
+{
+ if (bDisplayPath == DISP1)
+ SetSRReg(0x58, BIT0, BIT0);
+ else
+ SetSRReg(0x50, BIT0, BIT0);
+}
+
+void TurnOffScaler(UCHAR bDisplayPath)
+{
+ if (bDisplayPath == DISP1)
+ SetSRReg(0x58, 0, BIT0);
+ else
+ SetSRReg(0x50, 0, BIT0);
+}
+
+void TurnOnHorScaler(UCHAR bDisplayPath)
+{
+ if (bDisplayPath == DISP1)
+ SetSRReg(0x58, BIT2, BIT2);
+ else
+ SetSRReg(0x50, BIT2, BIT2);
+}
+
+void TurnOffHorScaler(UCHAR bDisplayPath)
+{
+ if (bDisplayPath == DISP1)
+ SetSRReg(0x58, 0, BIT2);
+ else
+ SetSRReg(0x50, 0, BIT2);
+}
+
+void TurnOnVerScaler(UCHAR bDisplayPath)
+{
+ if (bDisplayPath == DISP1)
+ SetSRReg(0x58, BIT1, BIT1);
+ else
+ SetSRReg(0x50, BIT1, BIT1);
+}
+
+void TurnOffVerScaler(UCHAR bDisplayPath)
+{
+ if (bDisplayPath == DISP1)
+ SetSRReg(0x58, 0, BIT1);
+ else
+ SetSRReg(0x50, 0, BIT1);
+}
+
+
+void Set12BitDVP()
+{
+ SetSRReg(0x1E, 0x00, BIT3);
+}
+
+void Set24BitDVP()
+{
+ SetSRReg(0x1E, 0x08, BIT3);
+}
+
+void TurnOnDAC()
+{
+ SetCRReg(0xDF, 0x00, BIT2);
+}
+void TurnOffDAC()
+{
+ SetCRReg(0xDF, 0x04, BIT2);
+}
+
+#if 0
+void Display1HWResetOn()
+{
+ SetCRReg(0x17, 0x00, BIT7);
+}
+void Display1HWResetOff()
+{
+ SetCRReg(0x17, 0x80, BIT7);
+}
+
+void Display2HWResetOn()
+{
+ SetCRReg(0x33, 0x00, BIT4);
+}
+void Display2HWResetOn()
+{
+ SetCRReg(0x33, 0x10, BIT4);
+}
+#endif
+
+/*----------------------------------------------------------------------------
+;
+; SerialLoadTable
+;
+; in:
+; pucDisplay1VESAModeInitRegs = pointer to start of table
+; (ucI2Cport = I2C port)
+; (ucI2CAddr = I2C address)
+; out:
+; *ppucTablePointer = table end + 1
+;
+;---------------------------------------------------------------------------*/
+void SerialLoadTable(UCHAR **ppucTablePointer, UCHAR ucI2Cport, UCHAR ucI2CAddr)
+{
+ UCHAR ucRegGroup;
+
+ while (**ppucTablePointer != 0xFF)
+ {
+ ucRegGroup = **ppucTablePointer;
+ (*ppucTablePointer)++;
+ if (ucRegGroup & BITS)
+ {
+ SerialLoadRegBits(ppucTablePointer, ucRegGroup, 0, 0);
+ }
+ else
+ {
+ SerialLoadReg(ppucTablePointer, ucRegGroup, 0, 0);
+ }
+ }
+ (*ppucTablePointer)++;
+}
+
+/*---------------------
+;
+; SerialLoadRegBits
+;
+; in:
+; pucDisplay1VESAModeInitRegs = pointer to start of table
+; ucRegGroup = register group
+; (ucI2Cport = I2C device address)
+; (ucI2CAddr = I2C port)
+; out:
+; *ppucTablePointer = pointer to end of table +1
+;
+;----------------------*/
+void SerialLoadRegBits(UCHAR **ppucTablePointer, UCHAR ucRegGroup, UCHAR ucI2Cport, UCHAR ucI2CAddr)
+{
+ UCHAR ucRegIndex, ucRegValue, ucMask;
+ ucRegGroup &= 0x7F;
+
+ while (**ppucTablePointer != 0xFF)
+ {
+ ucRegIndex = **ppucTablePointer;
+ (*ppucTablePointer)++;
+
+ ucRegValue = **ppucTablePointer;
+ (*ppucTablePointer)++;
+
+ ucMask = **ppucTablePointer;
+ (*ppucTablePointer)++;
+
+ switch(ucRegGroup)
+ {
+ case SR:
+ SetSRReg(ucRegIndex, ucRegValue, ucMask);
+ break;
+
+ case CR:
+ SetCRReg(ucRegIndex, ucRegValue, ucMask);
+ break;
+
+ case I2C:
+ break;
+ }
+ }
+ (*ppucTablePointer)++;
+}
+
+/*---------------------
+;
+; SerialLoadReg
+;
+; in:
+; pucDisplay1VESAModeInitRegs = pointer to start of table
+; ucRegGroup = register group
+; (ucI2Cport = I2C device address)
+; (ucI2CAddr = I2C port)
+; out:
+; *ppucTablePointer = pointer to end of table +1
+;
+;----------------------*/
+void SerialLoadReg(UCHAR **ppucTablePointer, UCHAR ucRegGroup, UCHAR ucI2Cport, UCHAR ucI2CAddr)
+{
+ UCHAR ucRegIndex, ucRegValue;
+
+ while (**ppucTablePointer != 0xFF)
+ {
+ ucRegIndex = **ppucTablePointer;
+ (*ppucTablePointer)++;
+
+ ucRegValue = **ppucTablePointer;
+ (*ppucTablePointer)++;
+
+ switch(ucRegGroup)
+ {
+ case SR:
+ SetSRReg(ucRegIndex, ucRegValue, 0xFF);
+ break;
+
+ case CR:
+ SetCRReg(ucRegIndex, ucRegValue, 0xFF);
+ break;
+
+ case GR:
+ SetGRReg(ucRegIndex, ucRegValue, 0xFF);
+ break;
+
+ case I2C:
+ break;
+ }
+ }
+ (*ppucTablePointer)++;
+}
+
+
+void LoadDisplay1VESAModeInitRegs()
+{
+ UCHAR *pucDisplay1VESAModeInitRegs = (UCHAR*)Display1VESAModeInitRegs;
+
+ OutPort(MISC_WRITE, 0x2F);
+
+ UnLockCR0ToCR7();
+
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "&pucDisplay1VESAModeInitRegs = 0x%x\n", &pucDisplay1VESAModeInitRegs);
+ SerialLoadTable(&pucDisplay1VESAModeInitRegs, 0, 0);
+
+ ResetATTR();
+
+ SetARReg(0x10, *pucDisplay1VESAModeInitRegs);
+ pucDisplay1VESAModeInitRegs++;
+ SetARReg(0x11, *pucDisplay1VESAModeInitRegs);
+ pucDisplay1VESAModeInitRegs++;
+ SetARReg(0x12, *pucDisplay1VESAModeInitRegs);
+ pucDisplay1VESAModeInitRegs++;
+ SetARReg(0x13, *pucDisplay1VESAModeInitRegs);
+ pucDisplay1VESAModeInitRegs++;
+ SetARReg(0x14, *pucDisplay1VESAModeInitRegs);
+
+ EnableATTR();
+}
+
+void VESASetBIOSData(USHORT ModeNum)
+{
+ /* no need to implement */
+}
+
+/*----------------------------------------------------------------------------
+;
+; DisableDisplayPathAndDevice
+;
+; in:
+; bDisplayPath = display path
+;
+;---------------------------------------------------------------------------*/
+void DisableDisplayPathAndDevice(UCHAR bDisplayPath)
+{
+ UCHAR bDeviceIndex = Get_DEV_ID(bDisplayPath);
+
+ /* disable device */
+ ControlPwrSeqOff(bDeviceIndex);
+
+ /* turn off TX */
+
+ /* disable port */
+ TurnOffDigitalPort(bDeviceIndex);
+
+ /* disable display path */
+ SequencerOff(bDisplayPath);
+}
+
+CI_STATUS GetDevicePortConfig(UCHAR bDeviceIndex, PORT_CONFIG **ppDevicePortConfig)
+{
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Enter GetDevicePortConfig()==\n");
+
+ *ppDevicePortConfig = pPortConfig;
+
+ while(((*ppDevicePortConfig)->DevID != 0xFF) && ((*ppDevicePortConfig)->Attribute & Dev_SUPPORT))
+ {
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "(*ppDevicePortConfig)->DevID = %x\n", (*ppDevicePortConfig)->DevID);
+
+ if (bDeviceIndex == (*ppDevicePortConfig)->DevID)
+ {
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, " Exit1 GetDevicePortConfig()== return success\n");
+ return true;
+ }
+ (*ppDevicePortConfig)++;
+ }
+
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, " Exit1 GetDevicePortConfig()== return fail!!\n");
+ return false;
+}
+
+void PowerSequenceOn()
+{
+ /* check if power sequence already on */
+ if (!(GetSRReg(0x11) & BIT0))
+ {
+ /* Power Sequence Control Pad Output Enable */
+ SetSRReg(0x32, BIT1, BIT1);
+
+ /* panel on */
+ SetSRReg(0x11, BIT0, BIT0);
+
+ /* delay for power sequence done */
+ WaitPowerSequenceDone();
+ }
+}
+
+void PowerSequenceOff()
+{
+ /* check if power sequence already off */
+ if (GetSRReg(0x11) & BIT0)
+ {
+ /* panel off */
+ SetSRReg(0x11, 0, BIT0);
+
+ /* wait power sequence done */
+ WaitPowerSequenceDone();
+
+ /* Power Sequence Control Pad Output Disable */
+ SetSRReg(0x32, 0, BIT1);
+ }
+}
+
+void SequencerOn(UCHAR DisplayPath)
+{
+ if (DisplayPath == DISP1)
+ SetSRReg(0x01, 0, BIT5);
+ else
+ SetCRReg(0x33, 0, BIT0);
+}
+
+void SequencerOff(UCHAR bDisplayPath)
+{
+ if (bDisplayPath == DISP1)
+ {
+ if (!(GetSRReg(0x01) & BIT5))
+ {
+ LongWait();
+ }
+ SetSRReg(0x01, BIT5, BIT5);
+ }
+ else
+ SetCRReg(0x33, BIT0, BIT0);
+}
+
+void ControlPwrSeqOn(UCHAR bDeviceIndex)
+{
+ PORT_CONFIG *pDevicePortConfig;
+ /* check if LCD or LCD2 */
+ if ((TransDevIDtoBit(bDeviceIndex) & (B_LCD+B_LCD2)) && (GetDevicePortConfig(bDeviceIndex, &pDevicePortConfig)))
+ {
+ if (pDevicePortConfig->Attribute & TX_PS)
+ {
+ if (pDevicePortConfig->TX_Enc_ID == TX_VT1636)
+ {
+/* VT1636PowerSequenceOnOn();*/
+ }
+ }
+ else if ((pDevicePortConfig->PortID == DVP1) || (pDevicePortConfig->PortID == DVP12))
+ {
+ PowerSequenceOn();
+ }
+ }
+}
+
+void ControlPwrSeqOff(UCHAR bDeviceIndex)
+{
+ PORT_CONFIG *pDevicePortConfig;
+ /* check if LCD or LCD2 */
+ if ((TransDevIDtoBit(bDeviceIndex) & (B_LCD+B_LCD2)) && (GetDevicePortConfig(bDeviceIndex, &pDevicePortConfig)))
+ {
+ if (pDevicePortConfig->Attribute & TX_PS)
+ {
+ if (pDevicePortConfig->TX_Enc_ID == TX_VT1636)
+ {
+/* VT1636PowerSequenceOnOff();*/
+ }
+ }
+ else if ((pDevicePortConfig->PortID == DVP1) || (pDevicePortConfig->PortID == DVP12))
+ {
+ PowerSequenceOff();
+ }
+ }
+}
+/*----------------------------------------------------------------------------
+;
+; LongWait() - wait V sync of display1
+;
+; in:
+; none
+; out:
+; none
+;
+;---------------------------------------------------------------------------*/
+void LongWait()
+{
+ while (GetIS1Reg() & BIT3);
+
+ while (!(GetIS1Reg() & BIT3));
+}
+
+UCHAR Get_DEV_ID(UCHAR DisplayPath)
+{
+ return ((DisplayPath == DISP1) ? ReadScratch(IDX_IGA1_DEV_ID) : ReadScratch(IDX_IGA2_DEV_ID));
+}
+
+
+void Set_DEV_ID(UCHAR DeviceID, UCHAR DisplayPath)
+{
+ if (DisplayPath == DISP1)
+ WriteScratch(IDX_IGA1_DEV_ID, DeviceID);
+ else
+ WriteScratch(IDX_IGA2_DEV_ID, DeviceID);
+}
+
+
+UCHAR Get_NEW_DEV_ID(UCHAR DisplayPath)
+{
+ return ((DisplayPath == DISP1) ? ReadScratch(IDX_NEW_IGA1_DEV_ID) : ReadScratch(IDX_NEW_IGA2_DEV_ID));
+}
+
+void Set_NEW_DEV_ID(UCHAR DeviceID, UCHAR DisplayPath)
+{
+ if (DisplayPath == DISP1)
+ WriteScratch(IDX_NEW_IGA1_DEV_ID, DeviceID);
+ else
+ WriteScratch(IDX_NEW_IGA2_DEV_ID, DeviceID);
+}
+
+USHORT Get_LCD_H_SIZE()
+{
+ USHORT wValue;
+
+ wValue = (USHORT)ReadScratch(IDX_LCD_H_SIZE_OVERFLOW);
+ wValue <<= 8;
+ wValue |= (USHORT)ReadScratch(IDX_LCD_H_SIZE);
+
+ return wValue;
+}
+
+USHORT Get_LCD_V_SIZE()
+{
+ USHORT wValue;
+
+ wValue = (USHORT)ReadScratch(IDX_LCD_V_SIZE_OVERFLOW);
+ wValue <<= 8;
+ wValue |= (USHORT)ReadScratch(IDX_LCD_V_SIZE);
+
+ return wValue;
+}
+
+ULONG Get_LCD_SIZE()
+{
+ ULONG dwValue;
+
+ dwValue = (ULONG)Get_LCD_V_SIZE();
+ dwValue <<= 16;
+ dwValue |= (ULONG)Get_LCD_H_SIZE();
+
+ return dwValue;
+}
+
+USHORT Get_LCD2_H_SIZE()
+{
+ USHORT wValue;
+
+ wValue = (USHORT)ReadScratch(IDX_LCD2_H_SIZE_OVERFLOW);
+ wValue <<= 8;
+ wValue |= (USHORT)ReadScratch(IDX_LCD2_H_SIZE);
+
+ return wValue;
+}
+
+USHORT Get_LCD2_V_SIZE()
+{
+ USHORT wValue;
+
+ wValue = (USHORT)ReadScratch(IDX_LCD2_V_SIZE_OVERFLOW);
+ wValue <<= 8;
+ wValue |= (USHORT)ReadScratch(IDX_LCD2_V_SIZE);
+
+ return wValue;
+}
+
+ULONG Get_LCD2_SIZE()
+{
+ ULONG dwValue;
+
+ dwValue = (ULONG)Get_LCD2_V_SIZE();
+ dwValue <<= 16;
+ dwValue |= (ULONG)Get_LCD2_H_SIZE();
+
+ return dwValue;
+}
+
+UCHAR Get_RRATE_ID(UCHAR DisplayPath)
+{
+ return ((DisplayPath == DISP1) ? ReadScratch(IDX_IGA1_RRATE_ID) : ReadScratch(IDX_IGA2_RRATE_ID));
+}
+
+void Set_RRATE_ID(UCHAR RRateID, UCHAR DisplayPath)
+{
+ if (DisplayPath == DISP1)
+ WriteScratch(IDX_IGA1_RRATE_ID, RRateID);
+ else
+ WriteScratch(IDX_IGA2_RRATE_ID, RRateID);
+}
+
+UCHAR Get_LCD_TABLE_INDEX(void)
+{
+ return ReadScratch(IDX_LCD1_TABLE_INDEX);
+}
+
+UCHAR Get_LCD2_TABLE_INDEX(void)
+{
+ return ReadScratch(IDX_LCD2_TABLE_INDEX);
+}
+
+void Set_LCD_TABLE_INDEX(UCHAR bLCDIndex)
+{
+ WriteScratch(IDX_LCD1_TABLE_INDEX, bLCDIndex);
+}
+
+
+USHORT Get_VESA_MODE(UCHAR DisplayPath)
+{
+ UCHAR VESAMode, VESAModeOver;
+
+ if (DisplayPath == DISP1)
+ {
+ VESAMode = ReadScratch(IDX_IGA1_VESA_MODE);
+ VESAModeOver = ReadScratch(IDX_IGA1_VESA_MODE_OVERFLOW);
+ }
+ else
+ {
+ VESAMode = ReadScratch(IDX_IGA2_VESA_MODE);
+ VESAModeOver = ReadScratch(IDX_IGA2_VESA_MODE_OVERFLOW);
+ }
+
+ return ((USHORT)VESAModeOver) << 8 | (USHORT)VESAMode;
+}
+
+void Set_VESA_MODE(USHORT ModeNum, UCHAR DisplayPath)
+{
+ if (DisplayPath == DISP1)
+ {
+ WriteScratch(IDX_IGA1_VESA_MODE, (UCHAR)ModeNum);
+ WriteScratch(IDX_IGA1_VESA_MODE_OVERFLOW, (UCHAR)(ModeNum >> 8));
+ }
+ else
+ {
+ WriteScratch(IDX_IGA2_VESA_MODE, (UCHAR)ModeNum);
+ WriteScratch(IDX_IGA2_VESA_MODE_OVERFLOW, (UCHAR)(ModeNum >> 8));
+ }
+}
+
+void ResetATTR()
+{
+ InPort(COLOR_INPUT_STATUS1_READ);
+ InPort(MONO_INPUT_STATUS1_READ);
+}
+
+void EnableATTR()
+{
+ ResetATTR();
+ OutPort(ATTR_DATA_WRITE, 0x20);
+}
+
+/* Set Cr register value with Mask */
+void SetCRReg(UCHAR bRegIndex, UCHAR bRegValue, UCHAR bMask)
+{
+ UCHAR btemp = 0x0;
+
+ if(bMask != 0xFF)
+ {
+ OutPort(COLOR_CRTC_INDEX,bRegIndex);
+ btemp = (UCHAR)InPort(COLOR_CRTC_DATA);
+ bRegValue &= bMask;
+ btemp &=~(bMask);
+ btemp |= bRegValue;
+ OutPort(COLOR_CRTC_DATA,btemp);
+ }
+ else
+ {
+ OutPort(COLOR_CRTC_INDEX,bRegIndex);
+ OutPort(COLOR_CRTC_DATA,bRegValue);
+ }
+
+ return;
+}
+
+/* Get Cr register value */
+UCHAR GetCRReg(UCHAR bRegIndex)
+{
+ UCHAR btemp = 0x0;
+
+ OutPort(COLOR_CRTC_INDEX,bRegIndex);
+ btemp = (UCHAR)InPort(COLOR_CRTC_DATA);
+
+ return btemp;
+}
+
+/* Set Sr register value with Mask */
+void SetSRReg(UCHAR bRegIndex, UCHAR bRegValue, UCHAR bMask)
+{
+ UCHAR btemp = 0x0;
+
+ if(bMask != 0xFF)
+ {
+ OutPort(SEQ_INDEX,bRegIndex);
+ btemp = (UCHAR)InPort(SEQ_DATA);
+ bRegValue &= bMask;
+ btemp &=~(bMask);
+ btemp |= bRegValue;
+ OutPort(SEQ_DATA,btemp);
+ }
+ else
+ {
+ OutPort(SEQ_INDEX,bRegIndex);
+ OutPort(SEQ_DATA,bRegValue);
+ }
+
+ return;
+}
+
+/* Get Sr register value */
+UCHAR GetSRReg(UCHAR bRegIndex)
+{
+ UCHAR btemp = 0x0;
+
+ OutPort(SEQ_INDEX,bRegIndex);
+ btemp = (UCHAR)InPort(SEQ_DATA);
+
+ return btemp;
+}
+
+void SetARReg(UCHAR index,UCHAR value)
+{
+ OutPort(ATTR_DATA_WRITE,index);
+ OutPort(ATTR_DATA_WRITE,value);
+}
+
+UCHAR GetARReg(UCHAR index)
+{
+ UCHAR bTmp;
+ InPort(COLOR_INPUT_STATUS1_READ);
+ OutPort(ATTR_DATA_WRITE,index);
+ bTmp = (UCHAR)InPort(ATTR_DATA_READ);
+ InPort(COLOR_INPUT_STATUS1_READ);
+ OutPort(ATTR_DATA_WRITE,BIT5);
+ return bTmp;
+}
+
+/* Set Gr register value with Mask */
+void SetGRReg(UCHAR bRegIndex, UCHAR bRegValue, UCHAR bMask)
+{
+ UCHAR btemp = 0x0;
+
+ if(bMask != 0xFF)
+ {
+ OutPort(GRAPH_INDEX,bRegIndex);
+ btemp = (UCHAR)InPort(GRAPH_DATA);
+ bRegValue &= bMask;
+ btemp &=~(bMask);
+ btemp |= bRegValue;
+ OutPort(GRAPH_DATA,btemp);
+ }
+ else
+ {
+ OutPort(GRAPH_INDEX,bRegIndex);
+ OutPort(GRAPH_DATA,bRegValue);
+ }
+
+ return;
+}
+
+void SetMSReg(UCHAR bRegValue)
+{
+ OutPort(MISC_WRITE,bRegValue);
+}
+
+UCHAR GetIS1Reg()
+{
+ return InPort(COLOR_INPUT_STATUS1_READ);
+}
+
+/* Clear frame buffer */
+void ClearFrameBuffer(UCHAR DisplayPath,ULONG *pFrameBufferBase, MODE_INFO *pModeInfo, UCHAR ucColorDepth)
+{
+ ULONG dwWidth = (ULONG)pModeInfo->H_Size, dwHeight = (ULONG)pModeInfo->V_Size, dwFactor = 0;
+ ULONG i = 0;
+
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Enter ClearFrameBuffer()==\n");
+ /* get display1/2 starting address */
+
+ /* Check the color depth */
+ switch(ucColorDepth)
+ {
+ case 8:
+ case 16:
+ case 32:
+ dwFactor = 32 / ucColorDepth;
+ break;
+
+ default:
+ return;
+ }
+
+ /* Clear */
+ for(i = 0;i<((dwWidth*dwHeight)/dwFactor);i++)
+ {
+ *(pFrameBufferBase+i) = 0x00000000;
+ }
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit ClearFrameBuffer()==\n");
+
+}
+
+ULONG Difference(ULONG Value1, ULONG Value2)
+{
+ if (Value1 > Value2)
+ return (Value1 - Value2);
+ else
+ return (Value2 - Value1);
+}
+
+/*----------------------------------------------------------------------------
+;
+; ReadScratch()
+;
+; in:
+; Index = scratch index
+; out:
+; return = scratch data aligned to LSB
+;
+;---------------------------------------------------------------------------*/
+UCHAR ReadScratch(USHORT IndexMask)
+{
+ UCHAR Index = (UCHAR)(IndexMask >> 8);
+ UCHAR Mask = (UCHAR)IndexMask;
+ UCHAR RetValue;
+
+ RetValue = GetCRReg(Index);
+ RetValue &= Mask;
+
+ RetValue = AlignDataToLSB(RetValue, Mask);
+
+ return RetValue;
+}
+
+/*----------------------------------------------------------------------------
+;
+; WriteScratch()
+;
+; in:
+; Index = scratch index
+; Data = data to be written
+; out:
+; none
+;---------------------------------------------------------------------------*/
+void WriteScratch(USHORT IndexMask, UCHAR Data)
+{
+ UCHAR Index = (UCHAR)(IndexMask >> 8);
+ UCHAR Mask = (UCHAR)IndexMask;
+
+ Data = AlignDataToMask(Data, Mask);
+ Data &= Mask;
+ SetCRReg(Index, Data, Mask);
+}
+
+/*----------------------------------------------------------------------------
+;
+; AlignDataToLSB()
+;
+; in:
+; Data = data to be aligned
+; Mask = mask of data
+; out:
+; return = aligned data
+;
+;---------------------------------------------------------------------------*/
+UCHAR AlignDataToLSB(UCHAR bData, UCHAR bMask)
+{
+ bData &= bMask;
+
+ while ((bMask & BIT0) == 0)
+ {
+ bData >>= 1;
+ bMask >>= 1;
+ }
+
+ return bData;
+}
+
+/*----------------------------------------------------------------------------
+;
+; AlignDataToMask()
+;
+; in:
+; Data = data to be aligned
+; Mask = mask of data
+; out:
+; return = aligned data
+;
+;---------------------------------------------------------------------------*/
+UCHAR AlignDataToMask(UCHAR bData, UCHAR bMask)
+{
+ while ((bMask & BIT0) == 0)
+ {
+ bData <<= 1;
+ bMask >>= 1;
+ }
+
+ return bData;
+}
+
+/*----------------------------------------------------------------------------
+;
+; SetDPMS -
+; Input:
+; DPMSState = DPMS_ON, DPMS_STANDBY, DPMS_SUSPEND, DPMS_OFF
+; DisplayPath
+; Output:
+; none
+;
+;---------------------------------------------------------------------------*/
+void SetDPMS(UCHAR DPMSState, UCHAR DisplayPath)
+{
+ UCHAR RegValue;
+
+ if (DPMSState > DPMS__OFF)
+ RegValue = 3;
+ else if (DPMSState <= DPMS__SUSPEND)
+ RegValue = DPMSState;
+
+ if (DisplayPath == DISP1)
+ SetCRReg(0xB6, RegValue, BIT1+BIT0);
+ else if (DisplayPath == DISP2)
+ SetCRReg(0x3E, RegValue, BIT1+BIT0);
+
+}
+/*----------------------------------------------------------------------------
+;
+; DetectMonitor()
+;
+; in:
+; none
+; out:
+; return = true if CRT connected
+;
+;---------------------------------------------------------------------------*/
+CI_STATUS DetectMonitor()
+{
+ CI_STATUS ConnectStatus;
+
+ /* CRA9 = sense data = 0x80 */
+ SetCRReg(0xA9, 0x80, 0xFF);
+
+ /* CRA8[6] = 1, start DAC sense */
+ SetCRReg(0xA8, BIT6, BIT6);
+
+ /* wait H sync */
+ WaitDisplayPeriod();
+
+ /* ISR0[4] = 1, CRT attached */
+ ConnectStatus = ((InPort(INPUT_STATUS_0_READ) & BIT4) ? true : false);
+
+ SetCRReg(0xA8, 0x00, BIT6);
+
+ return ConnectStatus;
+}
+/*----------------------------------------------------------------------------
+;
+; WaitDisplayPeriod() - wait H sync of display1
+;
+; in:
+; none
+; out:
+; none
+;
+;---------------------------------------------------------------------------*/
+void WaitDisplayPeriod()
+{
+ while ((InPort(COLOR_INPUT_STATUS1_READ)&BIT0) == 1);
+
+ while ((InPort(COLOR_INPUT_STATUS1_READ)&BIT0) == 0);
+}
+
+/*----------------------------------------------------------------------------
+;
+; WaitPowerSequenceDone() - SR32[2] = 1, power sequence on complete
+; = 0, power sequence off complete
+;
+; Input:
+; none
+; Output:
+; none
+;
+;---------------------------------------------------------------------------*/
+void WaitPowerSequenceDone()
+{
+ UCHAR SR32;
+
+ SR32 = GetSRReg(0x32);
+
+ /* loop while power sequence status not changed */
+ while(SR32 == GetSRReg(0x32));
+}
+/*--------------------------------------------------------------------
+;
+; CheckForDSTNPanel() -
+;
+; Input:
+; bDeviceIndex = device index
+; return:
+; true if device is DSTN panel
+;
+;--------------------------------------------------------------------*/
+CI_STATUS CheckForDSTNPanel(UCHAR bDeviceIndex)
+{
+ PORT_CONFIG *pDevicePortConfig;
+
+ if (GetDevicePortConfig(bDeviceIndex, &pDevicePortConfig))
+ {
+ if ((pDevicePortConfig->TX_Enc_ID == DSTN) &&
+ ((pDevicePortConfig->PortID == DVP1) || (pDevicePortConfig->PortID == DVP12)))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+}
+/*-------------------------------------------------------------------
+;
+; GetVESAMEMSize()
+; Input:
+; none
+; Output:
+; return VESA Memory Size (Unit: MB)
+;
+;------------------------------------------------------------------*/
+USHORT GetVESAMEMSize()
+{
+ UCHAR bHWStrapping;
+ bHWStrapping = (GetCRReg(0xAA) & (BIT2+BIT1+BIT0));
+
+ return (2 << (bHWStrapping+3));
+}
+
+void SetDeviceSupport()
+{
+ PORT_CONFIG *pDevicePortConfig = pPortConfig;
+
+ if (GetDevicePortConfig(CRT_ID, &pDevicePortConfig))
+ {
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "CRT supported\n");
+ bCRTSUPPORT = true;
+ }
+
+ if (GetDevicePortConfig(LCD_ID, &pDevicePortConfig))
+ {
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "LCD supported\n");
+ bLCDSUPPORT = true;
+ }
+
+ if (GetDevicePortConfig(DVI_ID, &pDevicePortConfig))
+ {
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "DVI supported\n");
+ bDVISUPPORT = true;
+ }
+
+ if (GetDevicePortConfig(TV_ID, &pDevicePortConfig))
+ {
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "TV supported\n");
+ bTVSUPPORT = true;
+ }
+}
+
+CI_STATUS VBE_SetMode(CBIOS_Extension *pCBIOSExtension)
+{
+ USHORT wModeNum = pCBIOSExtension->pCBiosArguments->reg.x.BX & 0x01FF;
+ USHORT wPitch = 0;
+ MODE_INFO *pModeInfo = NULL;
+ UCHAR bColorDepth = 0;
+ UCHAR bCurDeviceID, bNewDeviceID;
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Entry VBE_SetMode Mode number 0x%x== \n",wModeNum);
+#endif
+ if (wModeNum < 0x100)
+ {
+ SetVBERerurnStatus(VBEFunctionCallFail, pCBIOSExtension->pCBiosArguments);
+ return true;
+ }
+
+ bCurDeviceID = Get_DEV_ID(DISP1);
+ bNewDeviceID = Get_NEW_DEV_ID(DISP1);
+
+ if(!Get_MODE_INFO(wModeNum, &pModeInfo))
+ {
+ SetVBERerurnStatus(VBEFunctionCallFail, pCBIOSExtension->pCBiosArguments);
+ #if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit1 VBE_SetMode return 0x%x== \n",VBEFunctionCallFail);
+ #endif
+ return true;
+ }
+ /* update mode no */
+ Set_VESA_MODE(wModeNum, DISP1);
+
+ /* cut data */
+ SequencerOff(DISP1);
+
+ /* disable scaler */
+ TurnOffScaler(DISP1);
+
+ if (bCurDeviceID != bNewDeviceID)
+ {
+ /* control power sequence off */
+ ControlPwrSeqOff(bCurDeviceID);
+
+ /* turn off TX if necessary */
+
+ /* turn off digital port */
+ TurnOffDigitalPort(bCurDeviceID);
+
+ /* update scratch IDX_IGA1_DEV_ID */
+ Set_DEV_ID(bNewDeviceID, DISP1);
+ }
+
+ /* update BDA? */
+
+ /* load Display1 VESA Mode init registers */
+ LoadDisplay1VESAModeInitRegs();
+
+ /* load timing on display1 */
+ LoadTiming(DISP1, wModeNum);
+
+ /* set pitch */
+ GetModePitch(wModeNum, &wPitch);
+ SetPitch(DISP1, wPitch);
+
+ /* set color depth */
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, " /* set color depth */\n");
+ Get_MODE_INFO(wModeNum, &pModeInfo);
+ GetModeColorDepth(wModeNum, pModeInfo, &bColorDepth);
+ SetColorDepth(DISP1, bColorDepth);
+
+ /* load font */
+
+ /* load LUT */
+
+ /* clear FB */
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, " /* clear FB */\n");
+ if(!(pCBIOSExtension->pCBiosArguments->reg.x.BX & BIT15))
+ {
+ ClearFrameBuffer(DISP1,(ULONG*)(pCBIOSExtension->VideoVirtualAddress),pModeInfo,bColorDepth);
+ }
+
+ /* set FIFO */
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, " /* set FIFO */\n");
+ SetFIFO(DISP1);
+
+ /* config digital port */
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, " /* config difital port */\n");
+ ConfigDigitalPort(DISP1);
+
+ TurnOnDigitalPort(bNewDeviceID);
+
+ /* Turu on TX */
+
+ /* turn on power sequence if necessary */
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, " /* turn on power sequence if necessary */\n");
+ ControlPwrSeqOn(bNewDeviceID);
+
+ /* turn on sequencer */
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, " /* turn on sequencer */\n");
+ SequencerOn(DISP1);
+
+ SetVBERerurnStatus(VBEFunctionCallSuccessful, pCBIOSExtension->pCBiosArguments);
+
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit2 VBE_SetMode return 0x%x== \n",VBEFunctionCallSuccessful);
+#endif
+ return true;
+}
+/*-------------------------------------------------------------------
+;
+; VBE_SetGetScanLineLength()
+;
+; Input1: set/get display2 pitch
+; pCBiosArguments->AX = 0x4F06
+; BL = 0x00: Set Scan Line Length in Pixels
+; 0x01: Get Scan Line Length
+; 0x02: Set Scan Line Length in Bytes
+; 0x03: Get Maximum Scan Line Length
+; CX = Desired Width in Pixels if BL = 00
+; Desired Width in Bytes if BL = 02
+;
+; Input2: set/get display2 pitch
+; pCBiosArguments->AX = 0x4F14
+; BL = 0x00: Set Scan Line Length in Pixels
+; 0x01: Get Scan Line Length
+; 0x02: Set Scan Line in Bytes
+; 0x03: Get Maximum Scan Line Length
+; CX = Desired Width in Pixels if BL = 00
+; Desired Width in Bytes if BL = 02
+;
+; Output:
+; pCBiosArguments->AX = VBE Return Status
+; BX = Bytes Per Scan Line
+; CX = Actual Pixels Pet Scan Line (truncated to nearest complete pixel)
+; DX = Maximum Number of Scan Lines
+;
+;------------------------------------------------------------------*/
+CI_STATUS VBE_SetGetScanLineLength (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ USHORT wModeNum;
+ MODE_INFO *pModeInfo = NULL;
+ UCHAR bColorDepth;
+ UCHAR bDispalyPath;
+ ULONG dwVESAMemSizeInBytes;
+ USHORT wMaxPitchInBytes, wCurrentVDispEnd;
+ USHORT VBEReturnStatus = VBEFunctionCallFail;
+ USHORT wPitchToBeSet = pCBiosArguments->reg.x.CX; /* maybe in pixel or in byte */
+
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Entry VBE_SetGetScanLineLength== \n");
+#endif
+ if (pCBiosArguments->reg.x.AX == 0x4f06)
+ {
+ bDispalyPath = DISP1;
+ }
+ else if ((pCBiosArguments->reg.x.AX == 0x4f14) && ((pCBiosArguments->reg.lh.BH == 0x87)||(pCBiosArguments->reg.lh.BH == 0x08)))
+ {
+ bDispalyPath = DISP2;
+ }
+ else
+ {
+ SetVBERerurnStatus(VBEFunctionCallFail, pCBiosArguments);
+ #if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit1 VBE_SetGetScanLineLength return 0x%x== \n",VBEFunctionCallFail);
+ #endif
+ return true;
+ }
+
+ if (pCBiosArguments->reg.lh.BL <=3)
+ {
+ wModeNum = Get_VESA_MODE(bDispalyPath);
+
+ Get_MODE_INFO(wModeNum, &pModeInfo);
+
+ if (GetModeColorDepth(wModeNum, pModeInfo, &bColorDepth))
+ {
+ VBEReturnStatus = VBEFunctionCallNotSupported;
+
+ dwVESAMemSizeInBytes = ((ULONG)GetVESAMEMSize()) << 20;
+
+ wCurrentVDispEnd = GetVDisplayEnd(bDispalyPath);
+
+ /* align pitch to 8-byte */
+ if (((ULONG)(dwVESAMemSizeInBytes / (ULONG)wCurrentVDispEnd) & 0xFFFF0000) == 0)
+ {
+ wMaxPitchInBytes = (USHORT)(dwVESAMemSizeInBytes / (ULONG)wCurrentVDispEnd) & 0xFFF8;
+ }
+ else
+ {
+ wMaxPitchInBytes = 0xFFF8;
+ }
+ #if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "==VBE_SetGetScanLineLength Color Depth = 0x%x== \n",bColorDepth);
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "==VBE_SetGetScanLineLength Mem Size = 0x%x== \n",dwVESAMemSizeInBytes);
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "==VBE_SetGetScanLineLength Current Disp End = 0x%x== \n",wCurrentVDispEnd);
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "==VBE_SetGetScanLineLength Max Pitch = 0x%x== \n",wMaxPitchInBytes);
+ #endif
+ if ((pCBiosArguments->reg.lh.BL == 0) || (pCBiosArguments->reg.lh.BL == 2))
+ {
+ if (pCBiosArguments->reg.lh.BL == 0)
+ {
+ /* transform pitch size from pixels to bytes */
+ wPitchToBeSet <<= (bColorDepth >> 4);
+ }
+
+ if (wPitchToBeSet <= wMaxPitchInBytes)
+ {
+ SetPitch(bDispalyPath, wPitchToBeSet);
+ }
+ else
+ {
+ SetVBERerurnStatus(VBEReturnStatus, pCBiosArguments);
+ return true;
+ }
+ }
+
+ if (pCBiosArguments->reg.lh.BL == 3)
+ {
+ /* get maximum pitch in bytes */
+ pCBiosArguments->reg.x.BX = wMaxPitchInBytes;
+ }
+ else
+ {
+ /* get current pitch in bytes */
+ pCBiosArguments->reg.x.BX =GetPitch(bDispalyPath);
+ }
+
+ /* get current pitch in pixels */
+
+ pCBiosArguments->reg.x.CX = pCBiosArguments->reg.x.BX >> (bColorDepth >> 4);
+ pCBiosArguments->reg.x.DX = (dwVESAMemSizeInBytes / (USHORT)pCBiosArguments->reg.x.BX);
+ }
+ }
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit2 VBE_SetGetScanLineLength return 0x%x== \n",VBEReturnStatus);
+#endif
+ SetVBERerurnStatus(VBEReturnStatus, pCBiosArguments);
+ return true;
+}
+
+CI_STATUS OEM_QueryBiosInfo (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ USHORT VBEReturnStatus = VBEFunctionCallFail;
+
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Entry OEM_QueryBiosInfo()== \n");
+#endif
+
+ /* bx[15:0] = version number */
+
+ /*-------------------EBX PART--------------------;
+ ; ;
+ ;[31:24] : Branch version number
+ ;[23:8] : Customer Index
+ ;[7:0] : Release version number
+ */
+
+
+ /*-------------------ECX PART--------------------;
+ ; ;
+ ; [31:18] : Reserved
+ ; [17:16] : DRAM bus width
+ ; 00 : 16bit
+ ; 01 : 32bit
+ ; 10 : 64bit
+ ; 11 : reserved
+ ; [15:4] : memory size in 256k unit
+ ; [3:0] : Memory data rate
+ ; 000 : DDR333
+ ; 001 : DDR400
+ ; 010 : DDR533
+ ; 011 : DDR667
+ ; 100 : DDR800
+ ; xxx : Reserved
+ */
+
+
+ /*-------------------EDX PART--------------------;
+ ; ;
+ ; VGA BIOS Build TIME ;
+ ;[31:16] : Year
+ ;[15: 8] : Month
+ ;[ 7: 0] : Day
+ */
+
+
+
+ /*-------------------SI PART--------------------;
+ ; ;
+ ; SI = supported device
+ */
+ pCBiosArguments->reg.x.SI = 0;
+ if(bCRTSUPPORT)
+ {
+ pCBiosArguments->reg.x.SI |= B_CRT;
+ }
+ if(bLCDSUPPORT)
+ {
+ pCBiosArguments->reg.x.SI |= B_LCD;
+ }
+ if(bTVSUPPORT)
+ {
+ pCBiosArguments->reg.x.SI |= B_TV;
+ }
+ if(bDVISUPPORT)
+ {
+ pCBiosArguments->reg.x.SI |= B_DVI;
+ }
+
+ /*-------------------EAX PART--------------------;
+ ; ;
+ */
+
+ VBEReturnStatus = VBEFunctionCallSuccessful;
+ SetVBERerurnStatus(VBEReturnStatus, pCBiosArguments);
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit OEM_QueryBiosInfo()== \n");
+#endif
+ return true;
+}
+CI_STATUS OEM_QueryBiosCaps (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ /* VBIOS not implemented */
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Entry OEM_QueryBiosCaps()== \n");
+#endif
+
+
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit OEM_QueryBiosCaps()== \n");
+#endif
+ return true;
+}
+
+CI_STATUS OEM_QueryExternalDeviceInfo (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Entry OEM_QueryExternalDeviceInfo()== \n");
+#endif
+
+ pCBiosArguments->reg.lh.BL = ReadScratch(IDX_SCRATCH_20);
+ pCBiosArguments->reg.ex.EBX <<= 16;
+
+ pCBiosArguments->reg.lh.BH = ReadScratch(IDX_SCRATCH_21);
+
+ pCBiosArguments->reg.lh.BL = ReadScratch(IDX_SCRATCH_22);
+
+ pCBiosArguments->reg.ex.ECX = BIT16;
+
+ pCBiosArguments->reg.x.DX = 0xFFFF;
+
+ SetVBERerurnStatus(VBEFunctionCallSuccessful, pCBiosArguments);
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit OEM_QueryExternalDeviceInfo()== \n");
+#endif
+ return true;
+}
+
+CI_STATUS OEM_QueryDisplayPathInfo (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ UCHAR ScratchTempData;
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Entry OEM_QueryDisplayPathInfo()== \n");
+#endif
+ pCBiosArguments->reg.ex.EBX = 0;
+
+ pCBiosArguments->reg.lh.BL |= Get_NEW_DEV_ID(DISP1);
+
+ pCBiosArguments->reg.ex.EBX <<= 2;
+ ScratchTempData = GetSRReg(0x58); /* First Display scaling control */
+ if (ScratchTempData & BIT0)
+ {
+ ScratchTempData &= (BIT2 + BIT1); /* reserve H and V scaling control bits */
+ ScratchTempData >>= 1;
+ pCBiosArguments->reg.lh.BL |= ScratchTempData;
+ }
+
+ pCBiosArguments->reg.ex.EBX <<= 4;
+ pCBiosArguments->reg.lh.BL |= Get_DEV_ID(DISP1);
+
+ pCBiosArguments->reg.ex.EBX <<= 7;
+ pCBiosArguments->reg.lh.BL |= Get_RRATE_ID(DISP1);
+
+ pCBiosArguments->reg.ex.EBX <<= 9;
+ pCBiosArguments->reg.x.BX |= Get_VESA_MODE(DISP1);
+
+
+ pCBiosArguments->reg.ex.ECX = 0;
+
+ pCBiosArguments->reg.lh.CL |= Get_NEW_DEV_ID(DISP1);
+
+ pCBiosArguments->reg.ex.ECX <<= 2;
+ ScratchTempData = GetSRReg(0x50); /* Second Display scaling control */
+ if (ScratchTempData & BIT0)
+ {
+ ScratchTempData &= (BIT2 + BIT1); /* reserve H and V scaling control bits */
+ ScratchTempData >>= 1;
+ pCBiosArguments->reg.lh.BL |= ScratchTempData;
+ }
+
+ pCBiosArguments->reg.ex.ECX <<= 4;
+ pCBiosArguments->reg.lh.CL |= Get_DEV_ID(DISP2);
+
+ pCBiosArguments->reg.ex.ECX <<= 7;
+ pCBiosArguments->reg.lh.CL |= Get_RRATE_ID(DISP2);
+
+ pCBiosArguments->reg.ex.ECX <<= 9;
+ pCBiosArguments->reg.x.CX |= Get_VESA_MODE(DISP2);
+
+ SetVBERerurnStatus(VBEFunctionCallSuccessful, pCBiosArguments);
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit OEM_QueryDisplayPathInfo()== \n");
+#endif
+ return true;
+
+}
+
+CI_STATUS OEM_QueryDeviceConnectStatus (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ UCHAR *pucPCIDataStruct = (UCHAR*)PCIDataStruct;
+
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Entry OEM_QueryDeviceConnectStatus()== \n");
+#endif
+ pCBiosArguments->reg.x.BX = 0;
+
+ if (*(USHORT*)(pucPCIDataStruct + OFF_DID) == 0x2010)
+ {
+ if (GetSRReg(0x3c) & BIT0)
+ {
+ pCBiosArguments->reg.x.BX |= B_CRT;
+ }
+ }
+ else
+ {
+ /* Detect Monitor From EDID */
+ }
+
+ if (bLCDSUPPORT)
+ {
+ pCBiosArguments->reg.x.BX |= B_LCD;
+ }
+
+ if (bDVISUPPORT)
+ {
+ if (*(USHORT*)(((UCHAR*)PCIDataStruct) + OFF_DID) == 0x2010)
+ {
+ if (GetSRReg(0x3c) & BIT1)
+ {
+ pCBiosArguments->reg.x.BX |= B_DVI;
+ }
+ }
+ else
+ {
+ /* Query DVI Connect Status */
+ }
+ }
+
+ if (bTVSUPPORT)
+ {
+ /* TV DAC Sense */
+ }
+
+ SetVBERerurnStatus(VBEFunctionCallSuccessful, pCBiosArguments);
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit OEM_QueryDeviceConnectStatus()== \n");
+#endif
+ return true;
+}
+
+CI_STATUS OEM_QuerySupportedMode (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ MODE_INFO *pModeInfo;
+ RRATE_TABLE *pRRateTable;
+ int RRateTableIndex = 0;
+ int ModeNumIndex;
+ USHORT wModeNum;
+ USHORT wSerialNumber;
+
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Enter OEM_QuerySupportedMode()== \n");
+#endif
+ wSerialNumber = pCBiosArguments->reg.x.CX;
+ pModeInfo = (MODE_INFO*)pVESATable;
+
+ while (pModeInfo->H_Size != 0xFFFF)
+ {
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "pModeInfo->H_Size = %d \n", pModeInfo->H_Size);
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "pModeInfo->V_Size = %d \n", pModeInfo->V_Size);
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "sizeof(RRATE_TABLE) = %d \n", sizeof(RRATE_TABLE));
+#endif
+ for (ModeNumIndex = 0; ModeNumIndex < 3; ModeNumIndex++)
+ {
+ switch (ModeNumIndex)
+ {
+ case 0:
+ wModeNum = pModeInfo->Mode_ID_8bpp;
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "case 0: wModeNum = 0x%x \n", wModeNum);
+ break;
+ case 1:
+ wModeNum = pModeInfo->Mode_ID_16bpp;
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "case 1: wModeNum = 0x%x \n", wModeNum);
+ break;
+ case 2:
+ wModeNum = pModeInfo->Mode_ID_32bpp;
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "case 2: wModeNum = 0x%x \n", wModeNum);
+ break;
+ }
+
+ pRRateTable = (RRATE_TABLE*)((int)pModeInfo + sizeof(MODE_INFO));
+
+ for (RRateTableIndex = 0; RRateTableIndex < pModeInfo->RRTableCount; RRateTableIndex++, pRRateTable++)
+ {
+
+ xf86DrvMsgVerb(0, X_INFO, 5, "pRRateTable = 0x%x \n", pRRateTable);
+
+ if ((pRRateTable->Attribute & DISABLE) == 0)
+ {
+ if (wSerialNumber == 0)
+ {
+ /* BX = VESA mode number */
+ pCBiosArguments->reg.x.BX = wModeNum;
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "mode num = 0x%x \n", pCBiosArguments->reg.x.BX);
+
+ /* CL = Color depth */
+ GetModeColorDepth(wModeNum, pModeInfo, &pCBiosArguments->reg.lh.CL);
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "color depth = %d \n", pCBiosArguments->reg.lh.CL);
+
+ /* CH = Refresh rate index */
+ pCBiosArguments->reg.lh.CH = pRRateTable->RRate_ID;
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "RRate ID = %d \n", pCBiosArguments->reg.lh.CH);
+
+ /* EDX = mode resolution */
+ pCBiosArguments->reg.ex.EDX = (((ULONG)pModeInfo->V_Size) << 16) | (ULONG)pModeInfo->H_Size;
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "H x V = %d x %d \n", pCBiosArguments->reg.x.DX, pCBiosArguments->reg.ex.EDX>>16);
+
+ /* ESI = attribute */
+ pCBiosArguments->reg.x.SI = pRRateTable->Attribute;
+
+ /* EDI = pixel clock */
+ pCBiosArguments->reg.ex.EDI = pRRateTable->Clock;
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "dot clk = %dkhz \n", pCBiosArguments->reg.ex.EDI);
+
+ SetVBERerurnStatus (VBEFunctionCallSuccessful, pCBiosArguments);
+
+ #if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, " Exit1 OEM_QuerySupportedMode() return 0x%x== \n", VBEFunctionCallSuccessful);
+ #endif
+ return true;
+ }
+ else
+ {
+ wSerialNumber--;
+ }
+ }
+ }
+ }
+ pModeInfo = (MODE_INFO*)((int)pModeInfo + sizeof(MODE_INFO) + pModeInfo->RRTableCount*sizeof(RRATE_TABLE));
+ }
+
+ pModeInfo = (MODE_INFO*)(&CInt10VESATable);
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "*pModeInfo = %X \n", *pModeInfo);
+
+ while (pModeInfo->H_Size != 0xFFFF)
+ {
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "pModeInfo->H_Size = %d \n", pModeInfo->H_Size);
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "pModeInfo->V_Size = %d \n", pModeInfo->V_Size);
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "sizeof(RRATE_TABLE) = %d \n", sizeof(RRATE_TABLE));
+#endif
+ for (ModeNumIndex = 0; ModeNumIndex < 3; ModeNumIndex++)
+ {
+ switch (ModeNumIndex)
+ {
+ case 0:
+ wModeNum = pModeInfo->Mode_ID_8bpp;
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "case 0: wModeNum = 0x%x \n", wModeNum);
+ break;
+ case 1:
+ wModeNum = pModeInfo->Mode_ID_16bpp;
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "case 1: wModeNum = 0x%x \n", wModeNum);
+ break;
+ case 2:
+ wModeNum = pModeInfo->Mode_ID_32bpp;
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "case 2: wModeNum = 0x%x \n", wModeNum);
+ break;
+ }
+
+ pRRateTable = (RRATE_TABLE*)((int)pModeInfo + sizeof(MODE_INFO));
+
+ for (RRateTableIndex = 0; RRateTableIndex < pModeInfo->RRTableCount; RRateTableIndex++, pRRateTable++)
+ {
+
+ xf86DrvMsgVerb(0, X_INFO, 5, "pRRateTable = 0x%x \n", pRRateTable);
+
+ if ((pRRateTable->Attribute & DISABLE) == 0)
+ {
+ if (wSerialNumber == 0)
+ {
+ /* BX = VESA mode number */
+ pCBiosArguments->reg.x.BX = wModeNum;
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "mode num = 0x%x \n", pCBiosArguments->reg.x.BX);
+
+ /* CL = Color depth */
+ GetModeColorDepth(wModeNum, pModeInfo, &pCBiosArguments->reg.lh.CL);
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "color depth = %d \n", pCBiosArguments->reg.lh.CL);
+
+ /* CH = Refresh rate index */
+ pCBiosArguments->reg.lh.CH = pRRateTable->RRate_ID;
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "RRate ID = %d \n", pCBiosArguments->reg.lh.CH);
+
+ /* EDX = mode resolution */
+ pCBiosArguments->reg.ex.EDX = (((ULONG)pModeInfo->V_Size) << 16) | (ULONG)pModeInfo->H_Size;
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "H x V = %d x %d \n", pCBiosArguments->reg.x.DX, pCBiosArguments->reg.ex.EDX>>16);
+
+ /* ESI = attribute */
+ pCBiosArguments->reg.x.SI = pRRateTable->Attribute;
+
+ /* EDI = pixel clock */
+ pCBiosArguments->reg.ex.EDI = pRRateTable->Clock;
+ xf86DrvMsgVerb(0, X_INFO, InternalLevel, "dot clk = %dkhz \n", pCBiosArguments->reg.ex.EDI);
+
+ SetVBERerurnStatus (VBEFunctionCallSuccessful, pCBiosArguments);
+
+ #if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, " Exit1 OEM_QuerySupportedMode() return 0x%x== \n", VBEFunctionCallSuccessful);
+ #endif
+ return true;
+ }
+ else
+ {
+ wSerialNumber--;
+ }
+ }
+ }
+ }
+ pModeInfo = (MODE_INFO*)((int)pModeInfo + sizeof(MODE_INFO) + pModeInfo->RRTableCount*sizeof(RRATE_TABLE));
+ }
+
+ SetVBERerurnStatus (VBEFunctionCallFail, pCBiosArguments);
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, " Exit2 OEM_QuerySupportedMode() return 0x%x== \n", VBEFunctionCallFail);
+#endif
+ return true;
+
+}
+
+CI_STATUS OEM_QueryLCDPanelSizeMode (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ MODE_INFO *pModeInfo;
+ PANEL_TABLE *pPanelTable;
+ UCHAR bColorDepth = pCBiosArguments->reg.lh.CL;
+ USHORT wModeNum;
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Enter OEM_QueryLCDPanelSizeMode()== \n");
+#endif
+
+ SetVBERerurnStatus (VBEFunctionCallFail, pCBiosArguments);
+
+ if (!bLCDSUPPORT)
+ return true;
+
+ if (!GetModePointerFromLCDTable(LCD_ID, &pModeInfo, &pPanelTable))
+ return true;
+
+ switch (bColorDepth)
+ {
+ case 0:
+ wModeNum = pModeInfo->Mode_ID_8bpp;
+ pCBiosArguments->reg.lh.CL = 8;
+ break;
+ case 1:
+ wModeNum = pModeInfo->Mode_ID_16bpp;
+ pCBiosArguments->reg.lh.CL = 16;
+ break;
+ case 2:
+ wModeNum = pModeInfo->Mode_ID_32bpp;
+ pCBiosArguments->reg.lh.CL = 32;
+ break;
+ default:
+ SetVBERerurnStatus (VBEFunctionCallFail, pCBiosArguments);
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit2 OEM_QueryLCDPanelSizeMode() return 0x%x== \n", VBEFunctionCallFail);
+#endif
+ return true;
+ }
+
+ /* BX = VESA mode number */
+ pCBiosArguments->reg.x.BX = wModeNum;
+
+ /* CH = Refresh rate index */
+ pCBiosArguments->reg.lh.CH = pPanelTable->Timing.RRate_ID;
+
+ /* EDX = mode resolution */
+ pCBiosArguments->reg.ex.EDX = (ULONG)pModeInfo->H_Size | ((ULONG)pModeInfo->V_Size) << 16;
+
+ /* SI = attribute */
+ pCBiosArguments->reg.x.SI = pPanelTable->Timing.Attribute;
+
+ /* EDI = pixel clock */
+ pCBiosArguments->reg.ex.EDI = pPanelTable->Timing.Clock;
+
+ SetVBERerurnStatus (VBEFunctionCallSuccessful, pCBiosArguments);
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit1 OEM_QueryLCDPanelSizeMode() return 0x%x== \n", VBEFunctionCallSuccessful);
+#endif
+ return true;
+}
+
+CI_STATUS OEM_QueryLCDPWMLevel(CBIOS_ARGUMENTS *pCBiosArguments)
+{
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Entry OEM_QueryLCDPWMLevel()== \n");
+#endif
+ SetVBERerurnStatus (VBEFunctionCallFail, pCBiosArguments);
+
+ if (!bLCDSUPPORT)
+ return true;
+
+ if ((GetSRReg(0x30)&0x03) == 0x03 )
+ pCBiosArguments->reg.lh.BL = GetSRReg(0x30);
+ else
+ pCBiosArguments->reg.lh.BL = 0;
+
+ SetVBERerurnStatus (VBEFunctionCallSuccessful, pCBiosArguments);
+
+ return true;
+}
+
+CI_STATUS OEM_QueryTVConfiguration (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ return true;
+}
+CI_STATUS OEM_QueryTV2Configuration (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ return true;
+}
+CI_STATUS OEM_QueryHDTVConfiguration (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ return true;
+}
+CI_STATUS OEM_QueryHDTV2Configuration (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ return true;
+}
+CI_STATUS OEM_QueryHDMIConfiguration (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ return true;
+}
+CI_STATUS OEM_QueryHDMI2Configuration (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ return true;
+}
+CI_STATUS OEM_SetActiveDisplayDevice (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ UCHAR bDeviceIndex1 = Get_DEV_ID(DISP1);
+ UCHAR bDeviceIndex2 = Get_DEV_ID(DISP2);
+ UCHAR bNewDeviceIndex1 = pCBiosArguments->reg.lh.CL & 0x0F;
+ UCHAR bNewDeviceIndex2 = (pCBiosArguments->reg.lh.CL >> 4) & 0x0F;
+
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Entry OEM_SetActiveDisplayDevice()== \n");
+#endif
+
+ /* check if new device is available */
+ if ((!CheckForNewDeviceAvailable(bNewDeviceIndex1)&& (bNewDeviceIndex1!=0)) || (!CheckForNewDeviceAvailable(bNewDeviceIndex2)&& (bNewDeviceIndex2!=0)))
+ {
+ SetVBERerurnStatus(VBEFunctionCallFail, pCBiosArguments);
+ #if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit1 OEM_SetActiveDisplayDevice() return 0x%x== \n", VBEFunctionCallFail);
+ #endif
+ return true;
+ }
+
+ if(CheckForDSTNPanel(bNewDeviceIndex1) || CheckForDSTNPanel(bNewDeviceIndex2))
+ {
+ bNewDeviceIndex1 = 0;
+ }
+
+ if (bDeviceIndex1 != bNewDeviceIndex1)
+ {
+ if (bNewDeviceIndex1 == 0)
+ {
+ DisableDisplayPathAndDevice(DISP1);
+ Set_DEV_ID(bNewDeviceIndex1, DISP1);
+ }
+ Set_NEW_DEV_ID(bNewDeviceIndex1, DISP1);
+ }
+
+ if (bDeviceIndex2 != bNewDeviceIndex2)
+ {
+ if (bNewDeviceIndex2 == 0)
+ {
+ DisableDisplayPathAndDevice(DISP2);
+ Set_DEV_ID(bNewDeviceIndex2, DISP2);
+ }
+ Set_NEW_DEV_ID(bNewDeviceIndex2, DISP2);
+ }
+
+ SetVBERerurnStatus(VBEFunctionCallSuccessful, pCBiosArguments);
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit2 OEM_SetActiveDisplayDevice() return 0x%x== \n", VBEFunctionCallSuccessful);
+#endif
+ return true;
+}
+CI_STATUS OEM_SetVESAModeForDisplay2 (CBIOS_Extension *pCBIOSExtension)
+{
+ USHORT wModeNum = pCBIOSExtension->pCBiosArguments->reg.x.CX & 0x01FF;
+ USHORT wPitch = 0;
+ MODE_INFO *pModeInfo = NULL;
+ UCHAR bColorDepth = 0;
+ UCHAR bCurDeviceID, bNewDeviceID;
+
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Entry OEM_SetVESAModeForDisplay2()== \n");
+#endif
+
+ if (wModeNum < 0x100)
+ {
+ SetVBERerurnStatus(VBEFunctionCallFail, pCBIOSExtension->pCBiosArguments);
+ #if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit1 OEM_SetVESAModeForDisplay2() return 0x%x== \n", VBEFunctionCallFail);
+ #endif
+ return true;
+ }
+
+ bCurDeviceID = Get_DEV_ID(DISP2);
+ bNewDeviceID = Get_NEW_DEV_ID(DISP2);
+
+ /* check if mode is supported no matter which device is preferred */
+ if(!Get_MODE_INFO(wModeNum, &pModeInfo))
+ {
+ SetVBERerurnStatus(VBEFunctionCallFail, pCBIOSExtension->pCBiosArguments);
+ #if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit2 OEM_SetVESAModeForDisplay2() return 0x%x== \n", VBEFunctionCallFail);
+ #endif
+ return true;
+ }
+ /* update mode no */
+ Set_VESA_MODE(wModeNum, DISP2);
+
+ /* cut data */
+ SequencerOff(DISP2);
+
+ /* disable scaler */
+ TurnOffScaler(DISP2);
+
+ if (bCurDeviceID != bNewDeviceID)
+ {
+ /* control power sequence off */
+ ControlPwrSeqOff(bCurDeviceID);
+
+ /* turn off TX if necessary */
+
+ /* turn off digital port */
+ TurnOffDigitalPort(bCurDeviceID);
+
+ /* update scratch IDX_IGA2_DEV_ID */
+ Set_DEV_ID(bNewDeviceID, DISP2);
+ }
+
+ /* load Display2 VESA Mode init registers??*/
+
+ /* load timing on display2 */
+ LoadTiming(DISP2, wModeNum);
+
+ /* set pitch */
+ GetModePitch(wModeNum, &wPitch);
+ SetPitch(DISP2, wPitch);
+
+ /* set color depth */
+ Get_MODE_INFO(wModeNum, &pModeInfo);
+ GetModeColorDepth(wModeNum, pModeInfo, &bColorDepth);
+ SetColorDepth(DISP2, bColorDepth);
+
+ /* load font */
+
+ /* load LUT */
+
+ /* clear FB */
+ if(!(pCBIOSExtension->pCBiosArguments->reg.x.CX & BIT15))
+ {
+ ClearFrameBuffer(DISP2,(ULONG*)(pCBIOSExtension->VideoVirtualAddress),pModeInfo,bColorDepth);
+ }
+
+ /* set FIFO */
+ SetFIFO(DISP2);
+
+ /* config digital port */
+ ConfigDigitalPort(DISP2);
+
+ TurnOnDigitalPort(bNewDeviceID);
+
+ /* Turu on TX */
+
+ /* turn on power sequence if necessary */
+ ControlPwrSeqOn(bNewDeviceID);
+
+ SequencerOn(DISP2);
+
+ SetVBERerurnStatus(VBEFunctionCallSuccessful, pCBIOSExtension->pCBiosArguments);
+
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit3 OEM_SetVESAModeForDisplay2() return 0x%x== \n", VBEFunctionCallSuccessful);
+#endif
+ return true;
+}
+
+CI_STATUS OEM_SetDevicePowerState (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ UCHAR display1DeviceID, display2DeviceID, TargetDevice, DMPSState;
+ USHORT VBEReturnStatus = VBEFunctionCallFail;
+
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Entry OEM_SetDevicePowerState()== \n");
+#endif
+
+ TargetDevice = pCBiosArguments->reg.lh.CL & 0x0F;
+ DMPSState = pCBiosArguments->reg.lh.CL & (BIT1+BIT0);
+ display1DeviceID = Get_DEV_ID(DISP1);
+ display2DeviceID = Get_DEV_ID(DISP2);
+
+ if (display1DeviceID == TargetDevice)
+ {
+ SetDPMS(DMPSState, DISP1);
+ VBEReturnStatus = VBEFunctionCallSuccessful;
+ }
+ else if (display2DeviceID == TargetDevice)
+ {
+ SetDPMS(DMPSState, DISP2);
+ VBEReturnStatus = VBEFunctionCallSuccessful;
+ }
+
+ SetVBERerurnStatus(VBEReturnStatus, pCBiosArguments);
+
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit OEM_SetDevicePowerState() return 0x%x== \n", VBEFunctionCallSuccessful);
+#endif
+ return true;
+}
+
+CI_STATUS OEM_SetRefreshRate (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ UCHAR bRRateID, bDisplayPath;
+ bRRateID = pCBiosArguments->reg.lh.CL & 0x7F;
+
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Entry OEM_SetRefreshRate()== \n");
+#endif
+
+ if ( pCBiosArguments->reg.x.BX == SetDisplay1RefreshRate)
+ bDisplayPath = DISP1;
+ else
+ bDisplayPath = DISP2;
+
+ Set_RRATE_ID(bRRateID, bDisplayPath);
+
+ SetVBERerurnStatus(VBEFunctionCallSuccessful, pCBiosArguments);
+
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit OEM_SetRefreshRate() return 0x%x== \n", VBEFunctionCallSuccessful);
+#endif
+ return true;
+}
+
+CI_STATUS OEM_SetLCDPWMLevel (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ SetSRReg(0x2F,7,0xFF);
+ SetSRReg(0x30,pCBiosArguments->reg.lh.CL,0xFF);
+ return true;
+}
+
+CI_STATUS OEM_SetTVType (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ return true;
+}
+CI_STATUS OEM_SetTV2Type (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ return true;
+}
+CI_STATUS OEM_SetTVConnectType (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ return true;
+}
+CI_STATUS OEM_SetTV2ConnectType (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ return true;
+}
+CI_STATUS OEM_SetHDTVConnectType (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ return true;
+}
+CI_STATUS OEM_SetHDTV2ConnectType (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ return true;
+}
+CI_STATUS OEM_SetHDMIType (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ return true;
+}
+CI_STATUS OEM_SetHDMIOutputSignal (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ return true;
+}
+CI_STATUS OEM_SetHDMI2OutputSignal (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ return true;
+}
+
+CI_STATUS OEM_VideoPOST (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ UCHAR i = 0,btemp = 0x0,btemp1 = 0x0;
+ CI_STATUS bDDRII400 = true;
+ UCHAR *pucPOSTInItRegs = POSTInItRegs;
+ UCHAR *pucDDRII400Tbl = DDRII400Tbl;
+ UCHAR *pucDDRII533Tbl = DDRII533Tbl;
+ UCHAR *pucExtendRegs2 = ExtendRegs2;
+
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Entry OEM_VideoPOST()== \n");
+#endif
+
+ /* Enable VGA */
+ btemp = InPort(RIO_VGA_ENABLE);
+ btemp |= 1;
+ OutPort(RIO_VGA_ENABLE,btemp);
+
+ /* Select 3D4 as CRTC I/O base & Add memory access */
+ btemp = InPort(MISC_READ);
+ btemp |= 3;
+ OutPort(MISC_WRITE,btemp);
+
+ /* Open write key */
+ SetCRReg(0x80, 0xA8, 0xFF);
+
+ /* Clear Scratch pad */
+ for(i = 0x81;i < 0x9F;i++)
+ {
+ SetCRReg(i, 0x00, 0xFF);
+ }
+
+ /* Load DRAM timing */
+ /* Get HW Trapping */
+ btemp = GetCRReg(0xAB);
+ if((btemp & 0x3) == 0x3)
+ {
+ bDDRII400 = false;
+ }
+
+ if(bDDRII400)
+ {
+ /* Set memory PLL(Memory clock:200MHz NS:0x1B, MS:0x00, RS:0x02) */
+ SetCRReg(0xD9, 0x00, 0x80);
+ SetCRReg(0xD8, 0x9B, 0xFF);
+ }
+ else
+ {
+ /* Set memory PLL(Memory clock:266MHz NS:0x38, MS:0x00, RS:0x01) */
+ SetCRReg(0xD9, 0x80, 0x80);
+ SetCRReg(0xD8, 0x78, 0xFF);
+ }
+
+ /* Fire memory PLL timing setting */
+ /* btemp = GetCRReg(0xBB); */
+ btemp = 0x00;
+ SetCRReg(0xBB, btemp, 0xFF);
+
+ /* Open LCK PLL */
+ /* SetCRReg(0xB4, 0x01, 0x01); */
+
+ /* Load extend table */
+ SerialLoadTable(&pucPOSTInItRegs, 0, 0);
+
+ /* Write the default disp1 scratch pad as CRT */
+ Set_NEW_DEV_ID(0, DISP1);
+
+ if(bDDRII400)
+ {
+ /* Load DDRII400 timing table. */
+ SerialLoadTable(&pucDDRII400Tbl, 0, 0);
+ }
+ else
+ {
+ /* Load DDRII533 timing table. */
+ SerialLoadTable(&pucDDRII533Tbl, 0, 0);
+ }
+
+ /* Wait for DDRII setting */
+ do{
+ btemp = GetCRReg(0x5D);
+ btemp &= 0x80;
+ btemp1 = GetCRReg(0x5E);
+ btemp1 &= 0x01;
+ }while((btemp != 0x80)||(btemp1 != 0x01));
+
+ /* Set the other registers */
+ SerialLoadTable(&pucExtendRegs2, 0, 0);
+ /* SetDCC */
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit OEM_VideoPOST()== \n");
+#endif
+ return true;
+}
+
+void* SearchString(char *pcKeyWord, UCHAR *from)
+{
+ int i, lenKeyWord;
+
+ lenKeyWord = strlen(pcKeyWord);
+ for(i = 0; i < BIOS_ROM_SIZE; i++)
+ {
+ if ((*pcKeyWord == *(from+i)) && !memcmp(pcKeyWord, from+i, lenKeyWord))
+ {
+ return from+i;
+ }
+ }
+
+ return NULL;
+}
+
+void ParseTable(char* pcKeyWord, UCHAR *from, UCHAR **pointer)
+{
+ *pointer = (UCHAR*)SearchString(pcKeyWord, from);
+ *pointer += strlen(pcKeyWord);
+}
+
+CI_STATUS OEM_CINT10DataInit (CBIOS_ARGUMENTS *pCBiosArguments)
+{
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "BIOS virtual = %x", pCBiosArguments->reg.ex.ECX);
+
+ ParseTable("PCFG", (UCHAR*)pCBiosArguments->reg.ex.ECX, (UCHAR**)(&pPortConfig));
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "Port Config = %x", pPortConfig);
+
+ ParseTable("VPIT", (UCHAR*)pCBiosArguments->reg.ex.ECX, (UCHAR**)(&pVESATable));
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "VESA Table = %x", pVESATable);
+
+ ParseTable("LCDTBL", (UCHAR*)pCBiosArguments->reg.ex.ECX, (UCHAR**)(&pLCDTable));
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "LCD Table = %x", pLCDTable);
+
+ ParseTable("PCIR", (UCHAR*)pCBiosArguments->reg.ex.ECX, (UCHAR**)(&PCIDataStruct));
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "PCI Data Struct = %x", PCIDataStruct);
+
+ ParseTable("D1INIT", (UCHAR*)pCBiosArguments->reg.ex.ECX, (UCHAR**)(&Display1VESAModeInitRegs));
+ xf86DrvMsgVerb(0, X_INFO, InfoLevel, "Display1 VESA Mode Init Regs = %x", Display1VESAModeInitRegs);
+
+ SetDeviceSupport();
+#if 0
+ ParseTable("??????", &ExtendRegs); // POST init table
+ ParseTable("??????", &ExtendRegs2); // POST init table
+ ParseTable("??????", &DDRII400Tbl); // DDR400 DRAM table
+ ParseTable("??????", &DDRII533Tbl); // DDR533 DRAM table
+#endif
+ SetVBERerurnStatus(VBEFunctionCallSuccessful, pCBiosArguments);
+}
+
+CI_STATUS CInt10(CBIOS_Extension *pCBIOSExtension)
+{
+ CI_STATUS CInt10_Status = false;
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Enter CInt10(EAX = %x, EBX = %x, ECX = %x, EDX = %x, ESI = %x, EDI = %x)==\n",
+ pCBIOSExtension->pCBiosArguments->reg.ex.EAX, pCBIOSExtension->pCBiosArguments->reg.ex.EBX,
+ pCBIOSExtension->pCBiosArguments->reg.ex.ECX, pCBIOSExtension->pCBiosArguments->reg.ex.EDX,
+ pCBIOSExtension->pCBiosArguments->reg.ex.ESI, pCBIOSExtension->pCBiosArguments->reg.ex.EDI);
+#endif
+
+
+ /* Fill related IO address */
+ Relocate_IOAddress = pCBIOSExtension->IOAddress;
+
+ switch(pCBIOSExtension->pCBiosArguments->reg.x.AX)
+ {
+ case VBESetMode:
+ CInt10_Status = VBE_SetMode(pCBIOSExtension);
+ break;
+
+ case VBESetGetScanLineLength:
+ CInt10_Status = VBE_SetGetScanLineLength(pCBIOSExtension->pCBiosArguments);
+ break;
+
+ case OEMFunction:
+ switch(pCBIOSExtension->pCBiosArguments->reg.x.BX)
+ {
+ case QueryBiosInfo: /* 0000 */
+ CInt10_Status = OEM_QueryBiosInfo(pCBIOSExtension->pCBiosArguments);
+ break;
+ case QueryBiosCaps: /* 0001 */
+ CInt10_Status = OEM_QueryBiosCaps(pCBIOSExtension->pCBiosArguments);
+ break;
+ case QueryExternalDeviceInfo: /* 0100 */
+ CInt10_Status = OEM_QueryExternalDeviceInfo(pCBIOSExtension->pCBiosArguments);
+ break;
+ case QueryDisplayPathInfo: /* 0200 */
+ CInt10_Status = OEM_QueryDisplayPathInfo(pCBIOSExtension->pCBiosArguments);
+ break;
+ case QueryDeviceConnectStatus: /* 0201 */
+ CInt10_Status = OEM_QueryDeviceConnectStatus(pCBIOSExtension->pCBiosArguments);
+ break;
+ case QuerySupportedMode: /* 0202 */
+ CInt10_Status = OEM_QuerySupportedMode(pCBIOSExtension->pCBiosArguments);
+ break;
+ case QueryLCDPanelSizeMode: /* 0203 */
+ CInt10_Status = OEM_QueryLCDPanelSizeMode(pCBIOSExtension->pCBiosArguments);
+ break;
+ case QueryLCDPWMLevel: /* 0301 */
+ CInt10_Status = OEM_QueryLCDPWMLevel(pCBIOSExtension->pCBiosArguments);
+ break;
+ case QueryTVConfiguration:
+ break;
+ case QueryTV2Configuration:
+ break;
+ case QueryHDTVConfiguration:
+ break;
+ case QueryHDTV2Configuration:
+ break;
+ case QueryHDMIConfiguration:
+ break;
+ case QueryHDMI2Configuration:
+ break;
+ case QueryDisplay2Pitch:
+ case GetDisplay2MaxPitch:
+ CInt10_Status = VBE_SetGetScanLineLength(pCBIOSExtension->pCBiosArguments);
+ break;
+
+ case SetActiveDisplayDevice: /* 8200 */
+ CInt10_Status = OEM_SetActiveDisplayDevice(pCBIOSExtension->pCBiosArguments);
+ break;
+ case SetVESAModeForDisplay2:
+ CInt10_Status = OEM_SetVESAModeForDisplay2(pCBIOSExtension);
+ break;
+ case SetDevicePowerState: /* 8203 */
+ CInt10_Status = OEM_SetDevicePowerState(pCBIOSExtension->pCBiosArguments);
+ break;
+ case SetDisplay1RefreshRate: /* 8301 */
+ case SetDisplay2RefreshRate: /* 8381 */
+ CInt10_Status = OEM_SetRefreshRate(pCBIOSExtension->pCBiosArguments);
+ break;
+ case SetLCDPWMLevel: /* 8302 */
+ CInt10_Status = OEM_SetLCDPWMLevel(pCBIOSExtension->pCBiosArguments);
+ break;
+ case SetTVType:
+ break;
+ case SetTV2Type:
+ break;
+ case SetTVConnectType:
+ break;
+ case SetTV2ConnectType:
+ break;
+ case SetHDTVConnectType:
+ break;
+ case SetHDTV2ConnectType:
+ break;
+ case SetHDMIType:
+ break;
+ case SetHDMI2Type:
+ break;
+ case SetHDMIOutputSignal:
+ break;
+ case SetHDMI2OutputSignal:
+ break;
+ case SetDisplay2PitchInPixels:
+ case SetDisplay2PitchInBytes:
+ CInt10_Status = VBE_SetGetScanLineLength(pCBIOSExtension->pCBiosArguments);
+ break;
+ case SetVideoPOST:
+ CInt10_Status = OEM_VideoPOST(pCBIOSExtension->pCBiosArguments);
+ break;
+ case CINT10DataInit:
+ CInt10_Status = OEM_CINT10DataInit(pCBIOSExtension->pCBiosArguments);
+ break;
+ default:
+ pCBIOSExtension->pCBiosArguments->reg.x.AX = 0x014F;
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+#if CBIOS_DEBUG
+ xf86DrvMsgVerb(0, X_INFO, DefaultLevel, "==Exit CInt10(EAX = %x, EBX = %x, ECX = %x, EDX = %x, ESI = %x, EDI = %x)== \n",
+ pCBIOSExtension->pCBiosArguments->reg.ex.EAX, pCBIOSExtension->pCBiosArguments->reg.ex.EBX,
+ pCBIOSExtension->pCBiosArguments->reg.ex.ECX, pCBIOSExtension->pCBiosArguments->reg.ex.EDX,
+ pCBIOSExtension->pCBiosArguments->reg.ex.ESI, pCBIOSExtension->pCBiosArguments->reg.ex.EDI);
+#endif
+
+ return CInt10_Status;
+} /* end CInt10() */
+