📄 power.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
// File: power.c
//
#include <windows.h>
#include <nkintr.h>
#include <oal.h>
#include <omap730.h>
//------------------------------------------------------------------------------
// External functions
BOOL OALIntrIsIrqPending(UINT32 irq);
//------------------------------------------------------------------------------
//
// Function: OEMInterruptPending
//
// This function returns true when given sysIntr interrupt is pending.
//
BOOL OEMInterruptPending(DWORD sysIntr)
{
BOOL pending = FALSE;
const UINT32 *pIrqs;
UINT32 ix, count;
OALMSG(OAL_INTR&&OAL_VERBOSE, (
L"+OEMInterruptPending(%d)\r\n", sysIntr
));
if (OALIntrTranslateSysIntr(sysIntr, &count, &pIrqs)) {
for (ix = 0; ix < count; ix++ && !pending) {
pending = OALIntrIsIrqPending(pIrqs[ix]);
}
}
OALMSG(OAL_INTR&&OAL_VERBOSE, (
L"-OEMInterruptPending(rc = %d)\r\n", pending
));
return pending;
}
//------------------------------------------------------------------------------
//
// Function: OEMPowerOff
//
// Called when the system is to transition to it's lowest power mode (off).
//
void OEMPowerOff(void)
{
OMAP730_INTC_REGS *pIntcL1Regs = OALPAtoUA(OMAP730_INTC_L1_REGS_PA);
OMAP730_INTC_REGS *pIntcL2ARegs = OALPAtoUA(OMAP730_INTC_L2A_REGS_PA);
OMAP730_INTC_REGS *pIntcL2BRegs = OALPAtoUA(OMAP730_INTC_L2B_REGS_PA);
OMAP730_GPIO_REGS *pGPIO1Regs = OALPAtoUA(OMAP730_GPIO1_REGS_PA);
OMAP730_GPIO_REGS *pGPIO2Regs = OALPAtoUA(OMAP730_GPIO2_REGS_PA);
OMAP730_GPIO_REGS *pGPIO3Regs = OALPAtoUA(OMAP730_GPIO3_REGS_PA);
OMAP730_GPIO_REGS *pGPIO4Regs = OALPAtoUA(OMAP730_GPIO4_REGS_PA);
OMAP730_GPIO_REGS *pGPIO5Regs = OALPAtoUA(OMAP730_GPIO5_REGS_PA);
OMAP730_GPIO_REGS *pGPIO6Regs = OALPAtoUA(OMAP730_GPIO6_REGS_PA);
OMAP730_ULPD_REGS *pULPDRegs = OALPAtoUA(OMAP730_ULPD_REGS_PA);
OMAP730_ICR_REGS *pICRRegs = OALPAtoUA(OMAP730_ICR_REGS_PA);
UINT32 intcL1, intcL2A, intcL2B;
UINT32 gpio1, gpio2, gpio3, gpio4, gpio5, gpio6;
UINT32 sysIntr;
BOOL fullOff = TRUE;
// Make sure that KITL is powered off
OALKitlPowerOff();
// Give chance to do board specific stuff
BSPPowerOff();
// Save existing interrupt masks
intcL1 = INREG32(&pIntcL1Regs->MIR);
intcL2A = INREG32(&pIntcL2ARegs->MIR);
intcL2B = INREG32(&pIntcL2BRegs->MIR);
gpio1 = INREG32(&pGPIO1Regs->INTMASK);
gpio2 = INREG32(&pGPIO2Regs->INTMASK);
gpio3 = INREG32(&pGPIO3Regs->INTMASK);
gpio4 = INREG32(&pGPIO4Regs->INTMASK);
gpio5 = INREG32(&pGPIO5Regs->INTMASK);
gpio6 = INREG32(&pGPIO6Regs->INTMASK);
// Disable most interrupts (left IRQ_L2FIQ/IRQ_L2IRQ enabled)
OUTREG32(&pIntcL1Regs->MIR, 0xFFFFFFFC);
OUTREG32(&pIntcL2ARegs->MIR, 0xFFFFFFFF);
OUTREG32(&pIntcL2BRegs->MIR, 0xFFFFFFFF);
OUTREG32(&pGPIO1Regs->INTMASK, 0xFFFFFFFF);
OUTREG32(&pGPIO2Regs->INTMASK, 0xFFFFFFFF);
OUTREG32(&pGPIO3Regs->INTMASK, 0xFFFFFFFF);
OUTREG32(&pGPIO4Regs->INTMASK, 0xFFFFFFFF);
OUTREG32(&pGPIO5Regs->INTMASK, 0xFFFFFFFF);
OUTREG32(&pGPIO6Regs->INTMASK, 0xFFFFFFFF);
// Enable wake sources interrupts
for (sysIntr = SYSINTR_FIRMWARE; sysIntr < SYSINTR_MAXIMUM; sysIntr++) {
// Skip if sysIntr isn't allowed as wake source
if (!OALPowerWakeSource(sysIntr)) continue;
// Enable it as interrupt
OEMInterruptEnable(sysIntr, NULL, 0);
// There is wakeup source, don't do full power off
fullOff = FALSE;
}
// Enable deep sleep
SETREG16(&pULPDRegs->POWER_CTRL, POWER_CTRL_DEEP_SLEEP_EN);
// If we should do full off
if (fullOff) {
// Disable interrupt from GSM
CLRREG16(
&pICRRegs->MCTL, OMAP730_ICR_MCTL_M_INTEN|OMAP730_ICR_MCTL_G_INTEN
);
// Let GSM subsystem power off all...
OUTREG16(&pICRRegs->MFLAGS, 2);
// We should not be there for long time...
while (TRUE);
}
// Move SoC/CPU to idle mode, there is no special power-off
// mode on OMAP730 (but deep sleep is very similar to it)
OALCPUIdle();
// Find wakeup source
for (sysIntr = SYSINTR_FIRMWARE; sysIntr < SYSINTR_MAXIMUM; sysIntr++) {
// Skip if sysIntr isn't allowed as wake source
if (!OALPowerWakeSource(sysIntr)) continue;
// When this sysIntr is pending we find wake source
if (OEMInterruptPending(sysIntr)) {
g_oalWakeSource = sysIntr;
break;
}
}
// Do board specific stuff
BSPPowerOn();
// Reinitialize KITL
OALKitlPowerOn();
// Restore interrupt masks
OUTREG32(&pIntcL1Regs->MIR, intcL1);
OUTREG32(&pIntcL2ARegs->MIR, intcL2A);
OUTREG32(&pIntcL2BRegs->MIR, intcL2B);
OUTREG32(&pGPIO1Regs->INTMASK, gpio1);
OUTREG32(&pGPIO2Regs->INTMASK, gpio2);
OUTREG32(&pGPIO3Regs->INTMASK, gpio3);
OUTREG32(&pGPIO4Regs->INTMASK, gpio4);
OUTREG32(&pGPIO5Regs->INTMASK, gpio5);
OUTREG32(&pGPIO6Regs->INTMASK, gpio6);
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -