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

📄 power.cpp

📁 Sm501 VGA芯片wince下驱动代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				// Turn on CRT and panel
				setDPMS(DPMS_ON);
				panelPowerSequence(PANEL_ON, 4);
			}
			break;

		case VGXPowerMinimal:
			MESSAGE(MESSAGE_ZONE, (TEXT("[SMI::SetVGXPowerManagement] VGXPowerMinimal\r\n")));

			// Fail under high power consumption circumstances
			if (IsHighPowerConsumption())
			{
				dwResult = VGXPM_RET_HIGH_CONSUMPTION;
			}
			else
			{
				// Reduce the memory and engine clocks
				if (SetClockMode(VGXPowerMinimal))
				{
					// Reduce the voltage from 1.8V to 1.35V
					ReduceVoltage();

					m_PowerState = VGXPowerMinimal;
				}

				// Turn on CRT and panel
				setDPMS(DPMS_ON);
				panelPowerSequence(PANEL_ON, 4);
			}
			break;

		case VGXPowerStandBy:
			MESSAGE(MESSAGE_ZONE, (TEXT("[SMI::SetVGXPowerManagement] VGXPowerStandBy\r\n")));

            // Turn off CRT and panel
            setDPMS(DPMS_OFF);
            panelPowerSequence(PANEL_OFF, 4);

            // By definition, don't put VGX to sleep when in Standby mode.
			m_PowerState = VGXPowerStandBy;
			break;

		case VGXPowerSuspend:
			MESSAGE(MESSAGE_ZONE, (TEXT("[SMI::SetVGXPowerManagement] VGXPowerSuspend\r\n")));

			// Put the chip into slip.
			m_PowerState = VGXPowerSuspend;
			pokeRegisterDWord(POWER_MODE_CTRL, POWER_MODE_CTRL_MODE_SLEEP);
			break;

		case VGXPowerOff:
			MESSAGE(MESSAGE_ZONE, (TEXT("[SMI::SetVGXPowerManagement] VGXPowerOff\r\n")));

            // Turn off CRT and panel
            setDPMS(DPMS_OFF);
            panelPowerSequence(PANEL_OFF, 4);
			if (m_SMISettings.m_nSaveRestoreEnabled)
			{
				// Save VGX registers and memory
				SaveRestore(TRUE);
				m_bVgxRegsMemorySaved = TRUE;
			}

			m_PowerState = VGXPowerOff;


#ifndef USI
			// Put the chip into sleep.
			pokeRegisterDWord(POWER_MODE_CTRL, POWER_MODE_CTRL_MODE_SLEEP);
#endif
            for (j = 0; j < 0x70; j+=4)
                MESSAGE(MESSAGE_ZONE, (TEXT("PowerOff Reg[0x%08X] = 0x%08X\r\n"), j, peekRegisterDWord(j)));
			break;

		default:
			MESSAGE(MESSAGE_ZONE, (TEXT("[SMI::SetVGXPowerManagement] Invalid power mode!\r\n")));

			// Unknown Powerstate
			dwResult = VGXPM_RET_INVALID_PARAMETER;
		}
	}

	MESSAGE(MESSAGE_ZONE, (TEXT("-SMI::SetVGXPowerManagement\r\n")));

	LeaveCriticalSection(&m_PowerCriticalSection);

	return dwResult;
}


///////////////////////////////////////////////////////////////////////////////
// Makes sure that the current power mode is at least the specified.
// If necessary, the current mode is adjusted.

VOID SMI::EnsureAtLeast(VGX_POWER_STATE MinimalPowerState)
{
#ifdef ENABLE_ALL_MESSAGES
	MESSAGE(MESSAGE_ZONE, (TEXT("+SMI::EnsureAtLeast\r\n")));
#endif

	if (GetCurrentPowerState() < VGXPowerStandBy)
	{
		DWORD dwCurrentTick = GetTickCountSafe();

		switch (MinimalPowerState)
		{
		case VGXPowerOn:
			m_dwPowerOnLastRequested = dwCurrentTick;
			// Fall through...

		case VGXPowerReduced:
			m_dwReducedLastRequested = dwCurrentTick;
			// Fall through...

		case VGXPowerMinimal:
			m_dwMinimalLastRequested = dwCurrentTick;
			break;

		default:
			MESSAGE(MESSAGE_ZONE, (TEXT("SMI::EnsureAtLeast: invalid request\r\n")));
			return;
		}

		if (GetCurrentPowerState() > MinimalPowerState)
			SetVGXPowerManagement(MinimalPowerState);
	}

#ifdef ENABLE_ALL_MESSAGES
	MESSAGE(MESSAGE_ZONE, (TEXT("-SMI::EnsureAtLeast\r\n")));
#endif
}


///////////////////////////////////////////////////////////////////////////////
// Virtual API function. Can be called by WinCE.

void SMI::PowerHandler(BOOL bOff)
{
	MESSAGE(MESSAGE_ZONE, (TEXT("+SMI::PowerHandler\r\n")));
	m_bInPowerHandler = TRUE;

	SetVGXPowerManagement(bOff? VGXPowerOff : VGXPowerOn);

	m_bInPowerHandler = FALSE;
	MESSAGE(MESSAGE_ZONE, (TEXT("-SMI::PowerHandler\r\n")));
}


///////////////////////////////////////////////////////////////////////////////
// Reduces the memory and engine clocks.

BOOL SMI::SetClockMode(VGX_POWER_STATE PowerState)
{
	EnterCriticalSection(&m_PowerCriticalSection);

	MESSAGE(MESSAGE_ZONE, (TEXT("+SMI::SetClockMode\r\n")));

	BOOL bResult = FALSE;
	TCHAR* lpszError = TEXT("clock settings do not exist for the mode\r\n");

	__try
	{
		// Scan the clock table for the matching entry
		for (INT i = 0; i < sizeof(m_ClockInfo) / sizeof(MODE_CLOCK); i++)
		{
			if ((m_ClockInfo[i].ScreenWidth  == m_nScreenWidthSave)  &&
				(m_ClockInfo[i].ScreenHeigth == m_nScreenHeightSave) &&
				(m_ClockInfo[i].ScreenBpp    == m_nScreenBpp))
			{
				if (m_ClockInfo[i].ClockValue[PowerState].PowerState == PowerState)
				{
					MESSAGE(MESSAGE_ZONE, (TEXT("SMI::SetClockMode: reducing...\r\n")));

					// Determine the current clock register
					DWORD control_value = FIELD_GET(
						peekRegisterDWord(POWER_MODE_CTRL), POWER_MODE_CTRL, MODE);

					DWORD clock_reg;
					switch (control_value)
					{
					case POWER_MODE_CTRL_MODE_MODE0:
						clock_reg = POWER_MODE0_CLOCK;
						break;

					case POWER_MODE_CTRL_MODE_MODE1:
						clock_reg = POWER_MODE1_CLOCK;
						break;

					default:
						lpszError = TEXT("cannot reduce clock - the chip is in sleep mode\r\n");
						__leave;
					}

					// Program the clock
					DWORD Clock = peekRegisterDWord(clock_reg);
					Clock = FIELD_VALUE(Clock, CURRENT_POWER_CLOCK, MCLK_SELECT,
						m_ClockInfo[i].ClockValue[PowerState].MCLKSelect);
					Clock = FIELD_VALUE(Clock, CURRENT_POWER_CLOCK, MCLK_DIVIDER,
						m_ClockInfo[i].ClockValue[PowerState].MCLKDivider);
					Clock = FIELD_VALUE(Clock, CURRENT_POWER_CLOCK, MCLK_SHIFT,
						m_ClockInfo[i].ClockValue[PowerState].MCLKShift);
					Clock = FIELD_VALUE(Clock, CURRENT_POWER_CLOCK, M2XCLK_SELECT,
						m_ClockInfo[i].ClockValue[PowerState].M2XCLKSelect);
					Clock = FIELD_VALUE(Clock, CURRENT_POWER_CLOCK, M2XCLK_DIVIDER,
						m_ClockInfo[i].ClockValue[PowerState].M2XCLKDivider);
					Clock = FIELD_VALUE(Clock, CURRENT_POWER_CLOCK, M2XCLK_SHIFT,
						m_ClockInfo[i].ClockValue[PowerState].M2XCLKShift);
					pokeRegisterDWord(clock_reg, Clock);

					if (!m_bProtectClockSource)
					{
						// Program the output frequency of PLL2
						DWORD DRAMCtrl = peekRegisterDWord(SYSTEM_DRAM_CTRL);
						DRAMCtrl = FIELD_VALUE(DRAMCtrl, SYSTEM_DRAM_CTRL, PLL2_OUTPUT,
							m_ClockInfo[i].ClockValue[PowerState].PLL2Output);
						pokeRegisterDWord(SYSTEM_DRAM_CTRL, DRAMCtrl);
					}

					lpszError = NULL;
					__leave;
				}
				else
				{
					lpszError = TEXT("the specified power state is not supported\r\n");
					__leave;
				}
			}
		}
	}

	__finally
	{
		if (lpszError)
			MESSAGE(MESSAGE_ZONE, (TEXT("SMI::SetClockMode: %s\r\n"), lpszError));
		else
			bResult = TRUE;
	}

	MESSAGE(MESSAGE_ZONE, (TEXT("-SMI::SetClockMode\r\n")));

	LeaveCriticalSection(&m_PowerCriticalSection);

	return bResult;
}


///////////////////////////////////////////////////////////////////////////////
// Reduces the voltage.

void SMI::ReduceVoltage(BOOL bReduce)
{
	EnterCriticalSection(&m_PowerCriticalSection);

	MESSAGE(MESSAGE_ZONE, (TEXT("+SMI::ReduceVoltage(%d)\r\n"), bReduce));

	// Configure PWM2's pin to act as a GPIO's pin
	pokeRegisterDWord(GPIO_MUX_LOW, FIELD_SET(
		peekRegisterDWord(GPIO_MUX_LOW),
		GPIO_MUX_LOW, 31, GPIO));

	// Program the direction of the pin
	pokeRegisterDWord(GPIO_DATA_DIRECTION_LOW, FIELD_SET(
		peekRegisterDWord(GPIO_DATA_DIRECTION_LOW),
		GPIO_DATA_DIRECTION_LOW, 31, OUTPUT));

	if (bReduce)
	{
		// Reduce the voltage to 1.35V
		pokeRegisterDWord(GPIO_DATA_LOW,
			peekRegisterDWord(GPIO_DATA_LOW) | 0x80000000);
	}
	else
	{
		// Restore the full voltage to 1.8V
		pokeRegisterDWord(GPIO_DATA_LOW,
			peekRegisterDWord(GPIO_DATA_LOW) & ~0x80000000);
	}

	MESSAGE(MESSAGE_ZONE, (TEXT("-SMI::ReduceVoltage\r\n")));

	LeaveCriticalSection(&m_PowerCriticalSection);
}


///////////////////////////////////////////////////////////////////////////////
// Returns the handle of the Power Management message queue.

HANDLE SMI::GetPMMessageQueue()
{
	return m_hPMMessageQueue;
}


///////////////////////////////////////////////////////////////////////////////
// Returns the current video power state.

VGX_POWER_STATE SMI::GetCurrentPowerState()
{
	return m_PowerState;
}


///////////////////////////////////////////////////////////////////////////////
// Returns the number of ticks since the last request for full power mode.

DWORD SMI::GetPowerOnLastRequested()
{
	return m_dwPowerOnLastRequested;
}


///////////////////////////////////////////////////////////////////////////////
// Returns the number of ticks since the last request for reduced power mode.

DWORD SMI::GetReducedLastRequested()
{
	return m_dwReducedLastRequested;
}


///////////////////////////////////////////////////////////////////////////////
// Returns the number of ticks since the last request for minimal power mode.

DWORD SMI::GetMinimalLastRequested()
{
	return m_dwMinimalLastRequested;
}


///////////////////////////////////////////////////////////////////////////////
// Initializes the message queue and creates a thread.

DWORD SMI::GetTicksToReduced()
{
	return m_dwTicksToReduced;
}


///////////////////////////////////////////////////////////////////////////////
// Initializes the message queue and creates a thread.

DWORD SMI::SetIdle(DWORD TicksToReduced, DWORD TicksToMinimal)
{
	EnterCriticalSection(&m_PowerCriticalSection);

	ResetPowerManagement();
	m_dwTicksToReduced = TicksToReduced;
	m_dwTicksToMinimal = TicksToMinimal;

	LeaveCriticalSection(&m_PowerCriticalSection);

	return VGXPM_RET_SUCCESS;
}


///////////////////////////////////////////////////////////////////////////////
// Initializes the message queue and creates a thread.

DWORD SMI::GetTicksToMinimal()
{
	return m_dwTicksToMinimal;
}


///////////////////////////////////////////////////////////////////////////////
// Returnes the current activity state for the Power Monitor.

BOOL SMI::IsPowerStateLocked()
{
	return m_bPowerStateLocked;
}

	
///////////////////////////////////////////////////////////////////////////////
// Returnes the current activity state for the Power Monitor.

void SMI::LockPowerState(BOOL bLock)
{
	ResetPowerManagement();
	m_bPowerStateLocked = bLock;
}


///////////////////////////////////////////////////////////////////////////////
// Returnes the current activity state for the Power Monitor.

BOOL SMI::IsMonitorEnabled()
{
	return m_bMonitorEnabled;
}


///////////////////////////////////////////////////////////////////////////////
// Sets the current activity state for the Power Monitor.

void SMI::SetMonitorEnabled(BOOL bEnabled)
{
	EnterCriticalSection(&m_PowerCriticalSection);

	ResetPowerManagement();
	m_bMonitorEnabled = bEnabled;

	LeaveCriticalSection(&m_PowerCriticalSection);
}


///////////////////////////////////////////////////////////////////////////////
// Sets the state of the monitor relative to the module.

DWORD SMI::SetModuleMonitorEnabled(VGXPM_MODULES Module, BOOL bEnabled)
{
	EnterCriticalSection(&m_PowerCriticalSection);

	DWORD dwResult = VGXPM_RET_INVALID_PARAMETER;

	// Make sure we are within range
	if (Module < VGXPM_MODULE_COUNT)
	{
		m_PowerInfo[Module].dwLastCallTickCount = GetTickCountSafe();
		m_PowerInfo[Module].bMonitorEnabled     = bEnabled;
		dwResult = VGXPM_RET_SUCCESS;
	}
	else
	{
		MESSAGE(MESSAGE_ZONE, (TEXT("SMI::SetModuleMonitorEnabled: invalid module has been specified\r\n")));
	}

	LeaveCriticalSection(&m_PowerCriticalSection);

	return dwResult;
}


///////////////////////////////////////////////////////////////////////////////
// Turns the specified module on/off.
// Allowed VGX_POWER_STATE constants are VGXPowerOn and VGXPowerOff.

DWORD SMI::SetModulePower(VGXPM_MODULES Module, VGX_POWER_STATE State)
{
	EnterCriticalSection(&m_PowerCriticalSection);

	MESSAGE(MESSAGE_ZONE, (TEXT("+SMI::SetModulePower\r\n")));

	DWORD dwResult = VGXPM_RET_INVALID_PARAMETER;

	// Make sure we are within range.
	if (Module < VGXPM_MODULE_COUNT)
	{
		// Get current power mode.
		DWORD control_value = FIELD_GET(
			peekRegisterDWord(POWER_MODE_CTRL), POWER_MODE_CTRL, MODE);

		DWORD gate_reg = 0;
		switch (control_value)
		{
		case POWER_MODE_CTRL_MODE_MODE0:
			gate_reg = POWER_MODE0_GATE;
			break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -