📄 config.cpp
字号:
void
MQGC::WaitForNotBusy()
{
return;
}
int
MQGC::IsBusy()
{
return 0;
}
void
MQGC::WaitForVBlank()
{
VBlankReceived(); //Reset counters etc
}
//
// if bits 0 to 11 of VD1_COUNT (vertical display counter) are greater than
// bits 16 to 27 of VD1_CONTROL (vertical display 1 end) then we are in VBlank
// else we are not
//
int
MQGC::InVBlank()
{
DWORD val, val2;
do
{
val = gc1READ (VD1_COUNT); // have to read same value twice to be valid
val2 = gc1READ (VD1_COUNT);
} while(val != val2);
return ((val & 0x00000FFF) > ((gc1READ(VD1_CONTROL) >> 16) & 0x00000FFF));
}
int
MQGC::InDisplay(void)
{
return (!InVBlank());
}
///////////////////////////////////////////////////////////////////////
/// This is the s.o.b. that controls the PLLs and the assignment of ///
/// individual PLL to different module. The original MQ100 driver ///
/// sucked in the sense that it's fixed for GE, MIU, GC1 and GC2 ///
/// when assigning PLLs. The new logic is complicated by additional///
/// conditions: ///
/// 1. CPU Bus always on PLL1 (StrongARM and NEC). It has div-by-2 ///
/// bit that could be used to share a PLL (Pre-determined). ///
/// 2a.For Revision A, MIU always uses PLL1 (Pre-determined). ///
/// 2b.For Revision B, MIU could use PLL1 or PLL2 (Pre-determined). ///
/// 3. GE could be any. If CRT on, use/share higher PLL freq, else ///
/// if LCD-only, use/share lower PLL freq to save power. ///
/// 4. GC1 and GC2 is floating. They could use any of the PLLs ///
/// and/or share one/two PLLs through the 2 cascaded divisors. ///
///////////////////////////////////////////////////////////////////////
#ifdef FLEX_PLL
void
MQGC::SetMQPLL(
float fFreq,
ULONG ulRegType, //Indicate which module needs PLL
ULONG *ulPMMisc, //Return PMMisc
ULONG *ulGCCtrl ) //Return GC Control Reg
{
#define MAX_FD 7
float fFDs[MAX_FD] = {1.0F, 1.5F, 2.5F, 3.5F, 4.5F, 5.5F, 6.5F};
float fSD1, fFD1;
USHORT i, usMaxFD, usFDSelect;
BOOL bFound;
if ( ulPMMisc )
*ulPMMisc = 0UL;
if ( ulGCCtrl )
*ulGCCtrl = 0UL;
if ( 0.0F == fFreq )
return; //Don't do anything if no freq specified
for( i = FREQ_PLL1; i <= FREQ_PLL3; i++ )
if ( fFreq == fPLLs[i] )
break;
switch( ulRegType )
{
case PLL_GC1:
case PLL_GC2:
bFound = FALSE;
usFDSelect = 0;
fSD1 = 0.0F;
for( i = FREQ_PLL1; i <= FREQ_PLL3; i++ )
{
if ( fPLLs[i] )
{
if ( fFreq == fPLLs[i] )
bFound = TRUE;
else
{
//Step thru all combination of divisor to find
//exact match. Make sure the divide err is minimized.
for( ; usFDSelect < MAX_FD; usFDSelect++ )
{
for( ; fSD1 < 256.0F; fSD1 += 1.0F )
if ( fFreq ==
fPLLs[i] / fFDs[usFDSelect] / fSD1 )
{
bFound = TRUE;
break;
}
if ( bFound )
break;
}
}
if ( bFound )
break;
}
}
break;
case PLL_GE:
break;
//case PLL_BUS:
// break;
//case PLL_MIU:
// break;
}
}
#else //FLEX_PLL
void
MQGC::SetMQPLL(
float fFreq,
ULONG ulRegType, //Indicate which module needs PLL
ULONG *ulPLLData, //Return PLL val
ULONG *ulClockData ) //Return GC Control Reg divisor val
{
USHORT i;
if ( ulClockData )
*ulClockData = FDx_1 | (1UL << 24);
if ( ulPLLData )
{
*ulPLLData = 0UL;
for ( i = 0; i < MAX_MQPLL; i++ )
if ( fFreq == MQPLLParam[i].fFreq )
{
*ulPLLData = MQPLLParam[i].ulPLLData;
break;
}
}
#ifdef REV_0X
if ( ulRegType == PLL_GC1 || ulRegType == PLL_GC2 )
*ulPLLData = ((*ulPLLData & 0x70UL) >> 2)
| ((*ulPLLData & 0x1F00UL) >> 3)
| ((*ulPLLData & 0xFF0000UL) >> 5);
#endif
}
#endif //FLEX_PLL
void
MQGC::DetermineGE( ULONG *pulPMMisc )
{
#if 1 //def MIPS_NEC
//Assume the passed in data contains the most recently read
//and going to set PMMisc value
//PLL1 is always on with a value.
//PLL2 and PLL3 depends on the passed in PMMisc
float fGE = fDC0;
ULONG ulGESet = GE_BY_PLL1;
if ( (*pulPMMisc & PLL2_ENABLE) && ( fGE > fPLL2 ) )
{
ulGESet = GE_BY_PLL2;
fGE = fPLL2;
}
if ( (*pulPMMisc & PLL3_ENABLE) && ( fGE > fPLL3 ) )
{
ulGESet = GE_BY_PLL3;
}
*pulPMMisc &= ~GE_BY_MASK;
*pulPMMisc |= ulGESet;
#endif //MIPS_NEC
}
ULONG
DrvEnableDriverOpen( HKEY *phRegKey )
{
ULONG ulData, ulStatus, ulValType, ulValLen;
HKEY hRegKey;
ulStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, tcSubKey, 0, 0, phRegKey);
//PowerPointer Support flag
if ( ulStatus == ERROR_SUCCESS )
{
hRegKey = *phRegKey;
ulValLen =sizeof(ULONG);
REG_ASSIGN( PowerPointOn, tcPPSUPPORT, ulData, FALSE);
}
return ulStatus;
}
BOOL
DrvEnableDriverDone (
ULONG iEngineVersion,
ULONG cj,
DRVENABLEDATA *pded,
PENGCALLBACKS pEngCallbacks )
{
//Let GPE do what it ought to perform ...
return GPEEnableDriver( iEngineVersion, cj, pded, pEngCallbacks );
}
///////////////////////////////////////////////////////////////////////
//// Initialization sequence ...
//// 1. Setup DCR00R - use whatever is in the registry. ////
//// This is supposed to be required for NEC and StrongARM ////
//// 2. Enter D0 state from reset. ////
//// 3. Verify if right MediaQ chip ID. ////
//// 4. Setup PMU. ////
//// 5. Setup MIU. ////
///////////////////////////////////////////////////////////////////////
void
MQGC::SetMQMode(void)
{
USHORT us00At,x,y;
ULONG TmpX=0,TmpY=0;
DEBUGMSG (GPE_ZONE_INIT,( TEXT("MQGC::SetMQMode\r\n")));
dcREG(DC_0, ulDC0); //Always from OSC and used to drive MIU/GE
m_fPLLs[FREQ_PLL1] = fDC0;
Sleep(40);
pciREG(PCI_PM_CNTL_STATUS, ENTER_D0);
Sleep(80);
CHECK_IF_STATE_D(0); //Make sure in a stable state
//- shouldn't be necessary here !!!
DEBUGMSG (GPE_ZONE_INIT,( TEXT("MQGC::SetMQMode - in D0 state now ...\r\n")));
if ( pciREAD(PCI_VENDOR_DEVICE) != MQ200_DEVICE )
{
DEBUGMSG (GPE_ZONE_INIT,( TEXT("MQGC::ID=%08x ...\r\n"),pciREAD(PCI_VENDOR_DEVICE)));
DEBUGMSG (GPE_ZONE_INIT,( TEXT("MQGC::SetMQMode - invalid Device ID ...\r\n")));
return;
}
// Get Revision ID
ULONG ulClassRevID = pciREAD(PCI_REV_CLASS) & 0x000000FF;
DEBUGMSG (GPE_ZONE_INIT,( TEXT("MQGC::SetMQMode - Revision ID=%x ...\r\n"),ulClassRevID));
//Enable GE if >= 8bpp. Use PLL1 as initial clk src for GE.
if ( m_ulBPP >= 8UL )
{
// Max power seq interval for SA1110
if ((dcREAD(DC_1) & 0x3F) == BUS_MODE_SA1110)
pmuREG(PM_MISC,(GE_ENABLE|GE_BY_PLL1|PMCLK_2048CYCLE|FP_PMCLK_128K));
else
pmuREG(PM_MISC,(GE_ENABLE|GE_BY_PLL1));
}
//Set up PMU misc registers - to share OSC settle time
pmuREG(D1_STATE, OemInfo.ulD1State);
pmuREG(D2_STATE, OemInfo.ulD2State);
//To initialize MIU bloc,:
#ifdef REV_0X
//1. Enable MIU power down and reset, and DRAM reset.
//2. Wait at least 200ns.
//3. Disable DRAM reset.
//4. Disable MIU reset and enable MIU power up.
miuREG(MIU_CONTROL1, 0UL); //Step 1
Sleep(50); //Step 2
miuREG(MIU_CONTROL1, DRAM_RESET_DISABLE ); //Step 3
miuREG(MIU_CONTROL1, (DRAM_RESET_DISABLE
| MIU_ENABLE
| MIU_RESET_DISABLE) ); //Step 4
miuREG(MIU_CONTROL1, ulMIU1);
miuREG(MIU_CONTROL2, ulMIU2);
miuREG(MIU_CONTROL3, ulMIU3);
miuREG(MIU_CONTROL4, ulMIU4);
miuREG(MIU_CONTROL5, ulMIU5);
Sleep(50); //Step 2
#else
// Rev 1X
//
miuREG(MIU_CONTROL1, DRAM_RESET_DISABLE);
Sleep(100);
miuREG(MIU_CONTROL1, 0x00);
Sleep(50);
//ulMIU2 = 0x40EA0020; // PLL1=MIU,trun on bit 30 for rev1a
//ulMIU2 = 0x40EA0086; // PLL1=MIU,trun on bit 30 for rev1a
//ulMIU2 = 0x00EA0087; // PLL2=MIU,trun on bit 30 for rev1a
//ulMIU3 = 0x6d0ddc00;
//ulMIU3 = 0x6ce666bF;
ulMIU5 = 0x10d;
ulMIU4 = 0x00000001;
if (ulClassRevID != MQ200_REV_1A)
// Enable auto-refresh for 1B and above ...
ulMIU2 |= AUTO_REF_ENABLE;
miuREG(MIU_CONTROL2, ulMIU2);
miuREG(MIU_CONTROL3, ulMIU3);
// MIU REG 5 MUST BE PROGRAMMED BEFORE MIU REG 4
miuREG(MIU_CONTROL5, ulMIU5);
miuREG(MIU_CONTROL4, ulMIU4);
Sleep(10); //Step 2
miuREG(MIU_CONTROL1, MIU_ENABLE | MIU_RESET_DISABLE);
Sleep(50);
#endif
//Here, MIU is supposed to ready to serve ...
ULONG ulVal;
//Set up frame buffer base address register
geREG(BASE_ADDRESS, 0L);
//Set up destination stride
ulVal = m_ulScreenStride;
switch( m_ulBPP )
{
case 8UL:
ulVal |= GE_8BPP;
m_ulBPPShift = m_ulBPPSelect = 0UL;
break;
case 16UL:
ulVal |= GE_16BPP;
m_ulBPPShift = m_ulBPPSelect = 1UL;
break;
case 24UL:
ulVal |= GE_8BPP; //treat 24bpp as 8bpp in GE
m_ulBPPShift = 0UL;
m_ulBPPSelect = 2UL;
break;
case 32UL:
ulVal |= GE_32BPP;
m_ulBPPShift = 2UL;
m_ulBPPSelect = 3UL;
break;
}
geREG(DEST_STRIDE, ulVal);
m_ulDestStride = ulVal;
//Clear the primary screen. Use index 0 (black)
g1pREG(0, 0x00000000);
if ( m_ulBPP >= 4UL && m_ulBPP != 24UL )
{
// Use GE Rectangle Fill to clear frame buffer is much more efficient
//
geREG(WIDTH_HEIGHT, (ULONG)m_nActualHeight << 16 | m_nActualWidth);
TmpY = (ADDRESS)(m_pPrimarySurface->OffsetInVideoMemory()
/ m_ulScreenStride);
TmpX = (ULONG )(m_pPrimarySurface->OffsetInVideoMemory())
- (TmpY*m_ulScreenStride);
geREG(DEST_XY, (TmpY<<16) + TmpX);
geREG(FG_COLOR, 0x00000000UL); // clear it to black
SET_GE_DEST_STRIDE(m_ulDestStride);
geREG(DRAW_CMD, (DO_BITBLT | MONO_SOLID | MONO_PATTERN | 0xF0UL));
}
else
{
int fbrow,fbcol;
int wCount = m_ulScreenStride >> 2; // double word counter
ULONG *pBuf = (ULONG *)m_pPrimarySurface->Buffer();
for( fbrow = 0; fbrow < m_nScreenHeight; fbrow++ )
for( fbcol = 0; fbcol < wCount; fbcol++ )
*pBuf++=0x01; //HSU TMP
}
// For large desktop mode GC1 controls CRT and GC2 controls LCD
if (m_nMQFlag & LARGE_DESKTOP)
{
// Set up Window 1 & 2 according to user's layout request
us00At = AT_GC2;
CursorData.usCursorOn = AT_00_BY_GC2;
CursorData.usStatus = HOT_AT_GC1;
switch (m_nMQFlag & POSITION_MASK)
{
case HORI_CRT_LCD:
us00At = AT_GC1;
CursorData.usCursorOn = AT_00_BY_GC1;
CursorData.usStatus = HOT_AT_GC2;
case HORI_LCD_CRT:
x = m_nScreenWidth / 2;
y = 0;
break;
case VERT_CRT_LCD:
us00At = AT_GC1;
CursorData.usCursorOn = AT_00_BY_GC1;
CursorData.usStatus = HOT_AT_GC2;
case VERT_LCD_CRT:
x = 0;
y = m_nScreenHeight / 2;
break;
}
DEBUGMSG (GPE_ZONE_INIT,( TEXT("MQGC::SetMQMode - LargeDesktop\r\n")));
SetupGCs(USE_TwoGCs, us00At, x, y);
}
else
//Dual head but same image
if (m_nMQFlag & SAME_IMAGE)
{
DEBUGMSG (GPE_ZONE_INIT,( TEXT("MQGC::SetMQMode - SameImage\r\n")));
SetupGCs(USE_TwoGCs, AT_GC2, 0, 0);
CursorData.usCursorEnable = (ENABLE_GC1_CURSOR | ENABLE_GC2_CURSOR);
}
else
// LCD-only, CRT-only or Simultaneous
{
DEBUGMSG (GPE_ZONE_INIT,( TEXT("MQGC::SetMQMode - 1GC\r\n")));
SetupGCs(USE_OneGC, AT_GC1, 0, 0);
CursorData.usCursorEnable = ENABLE_GC1_CURSOR;
}
// Save flag for cursor routine
CursorData.ulFlag= m_nMQFlag;
if((m_nMQFlag & PROCESSOR_MASK) != IS_PCI)
{
// Turn on bit7 in CPU_CONTROL register to disable FB read cache on non-PCI systems
cpuREG(CPU_CONTROL, cpuREAD(CPU_CONTROL) | FBCACHE_DISABLE);
}
DumpReg(); // no op for normal case
DEBUGMSG (GPE_ZONE_INIT,( TEXT("MQGC::SetMQMode done!\r\n")));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -