📄 power.cpp
字号:
#include "precomp.h"
#include "mqmacro.h"
#ifdef MIPS_NEC
#ifdef ENABLE_PCI
#include <vr4122io.h>
#endif // ENABLE_PCI
#endif // MIPS_NEC
#define CONTRAST_CMD_GET 0
#define CONTRAST_CMD_SET 1
#define CONTRAST_CMD_INCREASE 2
#define CONTRAST_CMD_DECREASE 3
#define CONTRAST_CMD_DEFAULT 4
extern BOOL OemEnterPowerSave(int);
extern BOOL OemSetContrast(int);
extern BOOL OemSetBacklight(int);
extern OEM_INFO OemInfo;
#ifdef DDIDUMP // Stub function to make it happy
void MQGC::PowerHandler(BOOL bOff) { }
BOOL MQGC::ContrastControl(ULONG Cmd, ULONG *pValue) { return TRUE; }
#else // DDI Driver
//DispDrvrPowerHandler:
//Routine to power on/off the display hardware. Note that this
//function is called in kernel context, and may not make any
//system calls. So, implement delays as spin loops instead of
//using Sleep().
#ifdef MIPS_NEC
#ifdef ENABLE_PCI
void RtcWait(unsigned int etime);
#define KnlSleep(x) RtcWait(x) // NEC-specific delay ...
#define VR4122REG32(x) (*(volatile unsigned long *)(x))
#else
VOID RtcWait( UINT16 etime );
#define KnlSleep(x) RtcWait(x) // NEC-specific delay ...
#define REG16(base, id) (*((USHORT *)(((char*)(base))+(id))))
#define RTC_BASE 0x00c0
#define RTCL2REG_OFFSET (RTC_BASE + 0x1c)
#define RTC_INTERVAL 0xffff
#endif // ENABLE_PCI
typedef volatile BYTE *PVBYTE;
PVBYTE v_pIoRegs = NULL;
ULONG ulIORegs = IOREGS_BASE;
#else // Other processors ...
void LoopWait(void)
{
for (int i=0; i<10000; i++)
;
}
#define KnlSleep(x) LoopWait() // Generic delay ...
#endif // MIPS_NEC
#ifdef POWER_DOWN_SAVE_RESTORE
extern OEM_INFO OemInfo;
extern FRC_CONTROL_STRUC FRCControlData[];
extern USHORT usBPP;
extern PALETTEENTRY _rgbIdentity256[];
//Data Structure for Save/Restore data
//
typedef struct MEDIAQ_REGS_STRUC
{
ULONG ulOffset; // Register Offset
ULONG ulData; // Register content
} MEDIAQ_REGS, *PMEDIAQ_REGS;
MEDIAQ_REGS MediaQRegs[] =
{
{0x14000, 0}, // DCR0
// MIU registers ...
{0x04004, 0}, // MIU2
{0x04008, 0}, // MIU3
{0x04010, 0}, // MIU5
{0x0400c, 0}, // MIU4
// PMU registers ...
{0x00004, 0}, // D1_STATE
{0x00008, 0}, // D2_STATE
{0x00018, 0}, // PLL2_CONTROL
{0x0001c, 0}, // PLL3_CONTROL
// 2D registers ...
{0x0c028, 0}, // GE DEST_STRIDE
{0x0c02c, 0}, // GE BASE_ADDRESS
{0x0c228, 0}, // GE2 DEST_STRIDE
{0x0c22c, 0}, // GE2 BASE_ADDRESS
// FPI registers ...
{0x0e014, 0}, // DSTN_FB_CONTROL
{0x0e03c, 0}, // PWM_CONTROL
// GC1 registers ...
{0x0a008, 0}, // HD1_CONTROL
{0x0a00c, 0}, // VD1_CONTROL
{0x0a010, 0}, // HS1_CONTROL
{0x0a014, 0}, // VS1_CONTROL
{0x0a020, 0}, // HW1_CONTROL
{0x0a024, 0}, // VW1_CONTROL
{0x0a028, 0}, // AHW1_CONTROL
{0x0a02c, 0}, // AVW1_CONTROL
{0x0a030, 0}, // IW1_START_ADDR
{0x0a034, 0}, // AIW1_START_ADDR
{0x0a038, 0}, // IW1_STRIDE
{0x0a040, 0}, // HW_CURSOR1_POS
{0x0a044, 0}, // HW_CURSOR1_ADDR
{0x0a048, 0}, // HW_CURSOR1_FGCLR
{0x0a04c, 0}, // HW_CURSOR1_BGCLR
// GC2 registers ...
{0x0a088, 0}, // HD2_CONTROL
{0x0a08c, 0}, // VD2_CONTROL
{0x0a090, 0}, // HS2_CONTROL
{0x0a094, 0}, // VS2_CONTROL
{0x0a0a0, 0}, // HW2_CONTROL
{0x0a0a4, 0}, // VW2_CONTROL
{0x0a0a8, 0}, // AHW2_CONTROL
{0x0a0ac, 0}, // AVW2_CONTROL
{0x0a0b0, 0}, // IW2_START_ADDR
{0x0a0b4, 0}, // AIW2_START_ADDR
{0x0a0b8, 0}, // IW2_STRIDE
{0x0a0c0, 0}, // HW_CURSOR2_POS
{0x0a0c4, 0}, // HW_CURSOR2_ADDR
{0x0a0c8, 0}, // HW_CURSOR2_FGCLR
{0x0a0cc, 0}, // HW_CURSOR2_BGCLR
// Restored at the end ...
{0x00000, 0}, // PM_MISC
{0x0a000, 0}, // GC1_CONTROL
{0x0a080, 0}, // GC2_CONTROL
{0x0e000, 0}, // FP_CONTROL
{0x0a004, 0}, // GC1_CRT_CONTROL
{0xffffffff, 0} // that's it.
};
ULONG ulHWCursorArea[256]; // To save hw cursor - 1KB
#endif // POWER_DOWN_SAVE_RESTORE
void
MQGC::PowerHandler(BOOL bOff)
{
//bOff = TRUE : power off
//bOff = FALSE : power on
//
//MQx00 implements D0 to D3 state for power management. However, since CE
//has not adapted OnNow/ACPI initiative, D1 and D2 state will not be used
//here. However, OEM can use them in system-wide power management routine
//controlled by either hard botton or software.
#ifdef POWER_DOWN_SAVE_RESTORE
int i=0,j=0;
if (bOff)
{
#ifdef ENABLE_2D
// Make sure GE is not busy ...
geWAITNOTBUSY;
#endif // ENABLE_2D
// Save required registers ...
while (MediaQRegs[i].ulOffset != 0xffffffff)
{
MediaQRegs[i].ulData =
*((PLONG)(m_pMMIO + MediaQRegs[i].ulOffset));
i++;
}
// Save hw cursor
ULONG *pULONG = (ULONG *)(&m_pLAW[m_nCursorStart << 10]);
for (i = 0; i < 256; i++)
{
ulHWCursorArea[i] = *pULONG++;
}
}
else
{
// Restore registers ...
dcREG(DC_0, MediaQRegs[0].ulData);
KnlSleep(1);
pciREG(PCI_PM_CNTL_STATUS, ENTER_D0);
KnlSleep(40);
CHECK_IF_STATE_D(0); //Make sure in a stable state
// This will fail resume if not doing this ...
pmuREG(PM_MISC, (GE_ENABLE | GE_BY_PLL1) );
miuREG(MIU_CONTROL1, DRAM_RESET_DISABLE);
KnlSleep(5);
miuREG(MIU_CONTROL1, 0x00);
KnlSleep(5);
miuREG(MIU_CONTROL2, MediaQRegs[1].ulData);
miuREG(MIU_CONTROL3, MediaQRegs[2].ulData);
miuREG(MIU_CONTROL4, MediaQRegs[3].ulData);
miuREG(MIU_CONTROL5, MediaQRegs[4].ulData);
KnlSleep(1);
miuREG(MIU_CONTROL1, MIU_ENABLE | MIU_RESET_DISABLE);
KnlSleep(5);
// Restore FPI from pre-defined table ...
fpREG(FP_PIN_CONTROL, m_pFPControl->ulFPPinControl);
fpREG(FP_GPO_CONTROL, OemInfo.ulFPGPO);
fpREG(FP_GPIO_CONTROL, OemInfo.ulFPGPIO);
fpREG(STN_CONTROL, m_pFPControl->ulSTNControl);
for ( i = j = 0; i < FRC_PATTERN_CNT; i++, j+=4 )
fpREG((FRC_PATTERN + j), FRCControlData[0].ulFRCPattern[i]);
for ( i = j = 0; i < FRC_WEIGHT_CNT; i++, j+=4 )
fpREG((FRC_WEIGHT + j), FRCControlData[0].ulFRCWeight[i]);
// Restore hw cursor
ULONG *pULONG = (ULONG *)(&m_pLAW[m_nCursorStart << 10]);
for (i = 0; i < 256; i++)
{
*pULONG++ = ulHWCursorArea[i];
}
i=5; // Start from index 5 ...
while (MediaQRegs[i].ulOffset != 0xffffffff)
{
*((PLONG)(m_pMMIO + MediaQRegs[i].ulOffset)) =
MediaQRegs[i].ulData;
i++;
}
// Reload DAC if palette is used ...
if (usBPP == 8)
SetPalette(_rgbIdentity256, 0, 256);
}
#else // Simple power state switch only ...
if (bOff)
{
pciREG(PCI_PM_CNTL_STATUS, ENTER_D3);
KnlSleep(40);
//OemEnterPowerSave(ENTER_D3);
}
else
{
//- since chip was properly initialized during reset, entering D0 state
//is enough to get it back to normal operation mode.
//
pciREG(PCI_PM_CNTL_STATUS, ENTER_D0);
KnlSleep(40);
//OemEnterPowerSave(ENTER_D0);
}
#endif // POWER_DOWN_SAVE_RESTORE
}
#ifdef MIPS_NEC
#ifdef ENABLE_PCI // for 4122 RTC
void RtcWait(unsigned int etime)
{
unsigned int BaseRTC, CurrRTC, SignBit, tmp;
etime = (etime << 12) / 125; /* etime *= 32.768 */
do {
BaseRTC = VR4122REG32(v_pIoRegs+ETIMELREG);
tmp = VR4122REG32(v_pIoRegs+ETIMELREG);
} while (BaseRTC != tmp);
SignBit = BaseRTC & 0x80000000;
BaseRTC ^= SignBit;
do {
do {
CurrRTC = VR4122REG32(v_pIoRegs+ETIMELREG);
tmp = VR4122REG32(v_pIoRegs+ETIMELREG);
} while (CurrRTC != tmp);
CurrRTC ^= SignBit;
} while (CurrRTC < (BaseRTC+etime));
}
#else
UINT16 ReadRtc(void)
{
UINT16 Rtc;
while (TRUE) {
Rtc = REG16(v_pIoRegs, RTCL2REG_OFFSET);
if ( Rtc == REG16(v_pIoRegs, RTCL2REG_OFFSET))
break;
}
return Rtc;
}
VOID RtcWait( UINT16 etime )
{
UINT16 t = 0;
UINT16 PrevRtc, CurrRtc;
int delta;
PrevRtc = ReadRtc();
while (TRUE) {
CurrRtc = ReadRtc();
if (CurrRtc > PrevRtc) {
delta = RTC_INTERVAL - CurrRtc + PrevRtc;
}
else {
delta = PrevRtc - CurrRtc;
}
if (delta >= 32) {
if (++t > etime) {
break;
}
PrevRtc = CurrRtc;
}
}
}
#endif // ENABLE_PCI
#endif // MIPS_NEC
//DispDrvrContrastControl:
//
//Modify the contrast according to the Cmd parameter.
//
//Notes:
//
//The perp display driver has a controller w/ 64 steps. This driver keeps
//track of them as 0-63. At reset, the hardware selects the middle setting,
//32 steps from the maximum. The stepper can only go forward, so to back up
//one, it is necessary to step forward 63 times. (The hardware controller
//wraps at the maximum.)
BOOL
MQGC::ContrastControl(
ULONG Cmd,
ULONG *pValue
)
{
if ( pValue == NULL )
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
switch ( Cmd )
{
case CONTRAST_CMD_GET:
*pValue = m_nContrast;
return TRUE;
case CONTRAST_CMD_SET:
m_nContrast = *pValue;
OemSetContrast(m_nContrast);
return TRUE;
case CONTRAST_CMD_INCREASE:
if (m_nContrast < (ULONG)(OemInfo.usContrast + 15))
{
m_nContrast++;
OemSetContrast(m_nContrast);
}
*pValue = m_nContrast;
return TRUE;
case CONTRAST_CMD_DECREASE:
if (m_nContrast > (ULONG)(OemInfo.usContrast - 15))
{
m_nContrast--;
OemSetContrast(m_nContrast);
}
*pValue = m_nContrast;
return TRUE;
case CONTRAST_CMD_DEFAULT:
m_nContrast = OemInfo.usContrast;
return TRUE;
default:
SetLastError(ERROR_INVALID_PARAMETER);
}
return FALSE;
}
#endif // DDIDUMP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -