📄 xllp_pm_sleepcontext.c
字号:
/******************************************************************************
**
** INTEL CONFIDENTIAL
** Copyright 2000-2003 Intel Corporation All Rights Reserved.
**
** The source code contained or described herein and all documents
** related to the source code (Material) are owned by Intel Corporation
** or its suppliers or licensors. Title to the Material remains with
** Intel Corporation or its suppliers and licensors. The Material contains
** trade secrets and proprietary and confidential information of Intel
** or its suppliers and licensors. The Material is protected by worldwide
** copyright and trade secret laws and treaty provisions. No part of the
** Material may be used, copied, reproduced, modified, published, uploaded,
** posted, transmitted, distributed, or disclosed in any way without Intel抯
** prior express written permission.
**
** No license under any patent, copyright, trade secret or other intellectual
** property right is granted to or conferred upon you by disclosure or
** delivery of the Materials, either expressly, by implication, inducement,
** estoppel or otherwise. Any license under such intellectual property rights
** must be express and approved by Intel in writing.
**
** FILENAME: xllp_Pm_SleepContext.c
**
** PURPOSE: contains XLLP RTC primitives.
**
******************************************************************************/
#include "xllp_defs.h"
#include "xllp_Pm_ProcRegInfo.h" // Defines register offsets from base address for specific processor
#include "xllp_Pm_OsSpecific.h" // Defines interesting virtual base addresses of interesting register sets on a per-OS basis
#include "xllp_clkmgr.h"
#include "xllp_gpio.h"
#include "xllp_intc.h"
#include "xllp_Pm.h"
#include "xllp_Pm_SleepContext.h"
// These should be turning into xllp functions real soon.
#ifdef USING_COPROCSUPPORT
extern BVDRestoreAllCoProcRegs(P_XLLP_UINT32_T);
extern BVDStoreAllCoProcRegs(P_XLLP_UINT32_T);
#endif // def USING_COPROCSUPPORT
// Local declarations
void XllpPmWakeCLevelProcessing(P_XLLP_PM_ENTER_SLEEP_PARAMS_T,
P_XLLP_PM_SLEEP_SAVE_DATA_T,
XLLP_UINT32_T);
void XllpPmSaveAllRegLists (P_XLLP_PM_SLEEP_SAVE_DATA_T );
void XllpPmRestoreAllRegLists (P_XLLP_PM_SLEEP_SAVE_DATA_T );
void XllpPmSleepCLevelSaveCksm (P_XLLP_PM_SLEEP_SAVE_DATA_T );
void XllpPmRestoreIM(P_XLLP_PM_SLEEP_SAVE_DATA_T pSleepSaveArea);
// PM regs may not latch 'til read back.
// Will not, starting with B0.
static XLLP_VUINT32_T dummyRegReadTarget;
void XllpPmWakeCLevelProcessing(P_XLLP_PM_ENTER_SLEEP_PARAMS_T pSleepParam,
P_XLLP_PM_SLEEP_SAVE_DATA_T pSleepDataArea,
XLLP_UINT32_T ulPackedWakeupInfo)
{
P_XLLP_PWRMGR_T pPwrMgrRegs = (P_XLLP_PWRMGR_T) XLLP_U_V_PWRMGR_BASE;
P_XLLP_CLKMGR_T pClkRegs = (P_XLLP_CLKMGR_T) XLLP_U_V_CLKMGR_BASE;
P_XLLP_GPIO_T pGpioRegs = (P_XLLP_GPIO_T) XLLP_U_V_GPIO_BASE;
// Report detailed wakeup info to caller, then clear
pSleepParam->PEDR = pPwrMgrRegs->PEDR ;
pSleepParam->PKSR = pPwrMgrRegs->PKSR ;
pPwrMgrRegs->PEDR = XLLP_PM_PEDR_VLD_MSK ; // Clear all valid bits
pPwrMgrRegs->PKSR = XLLP_PM_PKSR_VLD_MSK ; // Clear all valid bits
// Restore GPLRx (values restored via GPSR and GPCR regs)
pGpioRegs->GPSR0 = pSleepDataArea->GPLR0 ;
pGpioRegs->GPCR0 = ~(pSleepDataArea->GPLR0) ;
pGpioRegs->GPSR1 = pSleepDataArea->GPLR1 ;
pGpioRegs->GPCR1 = ~(pSleepDataArea->GPLR1) ;
pGpioRegs->GPSR2 = pSleepDataArea->GPLR2 ;
pGpioRegs->GPCR2 = ~(pSleepDataArea->GPLR2) ;
pGpioRegs->GPSR3 = pSleepDataArea->GPLR3 ;
pGpioRegs->GPCR3 = ~(pSleepDataArea->GPLR3) ;
// Restore Internal Memory here if not special case where it contains stacks
if (0 == pSleepDataArea->pTmpStack)
{
XllpPmRestoreIM(pSleepDataArea);
}
//- (Future: But special case to deal with this manual note:
// "PSSR[RDH] must be clear before the MBREQ alternate function
// is enabled. Otherwise, unpredictable MBGNT behavior will result. [...]"
// Must restore GPIO levels first
XllpPmRestoreAllRegLists (pSleepDataArea); // Includes CP0+1
// Reactivate all restored GPIO pin functions and clear obsolete
// status indications by resetting the PSSR. (This is currently
// done in the general reset code. Need to examine processing for sleep resets)
// At this time, it will be safe to enable the MBREQ alternate function when
// it is supported.
// Peripheral clock enables
pClkRegs->cken = pSleepDataArea->CKEN;
// Restore OSCR if PI domain was powered off during sleep
if (XLLP_PSLR_SL_PI_OFF==(pSleepParam->PSLR_vals & XLLP_PSLR_SL_PI_MSK))
{
XLLP_UINT32_T current, saved;
saved = pSleepDataArea->OSCR_val;
current = *(pSleepParam->OSCR_Addr);
pSleepParam->ChangeOfTime = saved - current;
*(pSleepParam->OSCR_Addr) = saved;
}
else
{
pSleepParam->ChangeOfTime = 0;
}
// Call OS-specific mid-resume function
if (pSleepParam->pOsResumeOptionalFn)
{
(*pSleepParam->pOsResumeOptionalFn)();
}
// Invalidate the checksum and zero the PSPR because the saved state
// is about to become obsolete.
pSleepDataArea->checksum++;
pPwrMgrRegs->PSPR = 0;
} // XllpPmWakeCLevelProcessing()
// Call only after all assembly language level data saving is finished.
void XllpPmSleepCLevelProcessing(P_XLLP_PM_ENTER_SLEEP_PARAMS_T pSleepParam)
{
P_XLLP_PWRMGR_T pPwrMgrRegs = (P_XLLP_PWRMGR_T) XLLP_U_V_PWRMGR_BASE;
P_XLLP_CLKMGR_T pClkRegs = (P_XLLP_CLKMGR_T) XLLP_U_V_CLKMGR_BASE;
P_XLLP_GPIO_T pGpioRegs = (P_XLLP_GPIO_T) XLLP_U_V_GPIO_BASE;
#if 0
P_XLLP_INTC_T pIntcRegs = (P_XLLP_INTC_T) XLLP_U_V_INTC_BASE;
#endif
P_XLLP_PM_SLEEP_SAVE_DATA_T pSleepDataArea;
// Will need after waking. Startup code only gets physical address.
// of saved data area, the restoration code needs the virtual addr.
pSleepDataArea = pSleepParam->SleepDataAreaVA;
pSleepDataArea->pSleepDataArea = pSleepDataArea;
// Restoration code needs this to report into return fields.
pSleepDataArea->pSleepParam = pSleepParam;
// Internal memory related info
pSleepDataArea->pTmpStack = pSleepParam->pTmpStack;
// Need impmcr info here in case early restore of IM.
pSleepDataArea->impmcr_va =
(P_XLLP_UINT32_T) (XLLP_U_V_IM_REGS_BASE + XLLP_OFFS_IMPMCR);
pSleepDataArea->impmcr =
(*pSleepDataArea->impmcr_va) & XLLP_VLD_MSK_IMPMCR;
pSleepDataArea->StoreAddrForIntlMem_0 = pSleepParam->StoreAddrForIntlMem_0;
pSleepDataArea->StoreAddrForIntlMem_1 = pSleepParam->StoreAddrForIntlMem_1;
pSleepDataArea->StoreAddrForIntlMem_2 = pSleepParam->StoreAddrForIntlMem_2;
pSleepDataArea->StoreAddrForIntlMem_3 = pSleepParam->StoreAddrForIntlMem_3;
pSleepDataArea->IntlMemVA_0 = pSleepParam->IntlMemVA_0;
pSleepDataArea->IntlMemVA_1 = pSleepParam->IntlMemVA_1;
pSleepDataArea->IntlMemVA_2 = pSleepParam->IntlMemVA_2;
pSleepDataArea->IntlMemVA_3 = pSleepParam->IntlMemVA_3;
// More setup information from param block
pSleepDataArea->pOptionalRegList = pSleepParam->pOptionalRegList;
pSleepDataArea->privateRegListCount = pSleepParam->privateRegListCount;
pSleepDataArea->pPrivateRegListStorage = pSleepParam->pPrivateRegListStorage;
pSleepDataArea->extendedChecksumWordCount = pSleepParam->extendedChecksumWordCount;
// Save OSCR if PI domain will be powered off during sleep
if (XLLP_PSLR_SL_PI_OFF==(pSleepParam->PSLR_vals & XLLP_PSLR_SL_PI_MSK))
{
pSleepDataArea->OSCR_val = *(pSleepParam->OSCR_Addr);
}
else
{
pSleepDataArea->OSCR_val = 0;
}
// Save registers that can't be restored from lists.
pSleepDataArea->GPLR0 = pGpioRegs->GPLR0;
pSleepDataArea->GPLR1 = pGpioRegs->GPLR1;
pSleepDataArea->GPLR2 = pGpioRegs->GPLR2;
pSleepDataArea->GPLR3 = pGpioRegs->GPLR3;
// Record peripheral clock enables
pSleepDataArea->CKEN = pClkRegs->cken;
// Set up power manager registers for wakeup criteria, GPIO sleep state, etc.
// (Do before end of data storage)
// Set sleep levels of GPIO pins
// Must do before register list processing.
// Include parameter bit vals selected by
// "1" in mask, exclude those bits from GPLR
pPwrMgrRegs->PGSR0 = ((pSleepParam->PGSR0_vals & pSleepParam->PGSR0_msk) |
(pGpioRegs->GPLR0 & ~pSleepParam->PGSR0_msk))
& XLLP_PM_PGSR0_VLD_MSK;
dummyRegReadTarget = pPwrMgrRegs->PGSR0 ;
pPwrMgrRegs->PGSR1 = ((pSleepParam->PGSR1_vals & pSleepParam->PGSR1_msk) |
(pGpioRegs->GPLR1 & ~pSleepParam->PGSR1_msk))
& XLLP_PM_PGSR1_VLD_MSK;
dummyRegReadTarget = pPwrMgrRegs->PGSR1 ;
pPwrMgrRegs->PGSR2 = ((pSleepParam->PGSR2_vals & pSleepParam->PGSR2_msk) |
(pGpioRegs->GPLR2 & ~pSleepParam->PGSR2_msk))
& XLLP_PM_PGSR2_VLD_MSK;
dummyRegReadTarget = pPwrMgrRegs->PGSR2 ;
pPwrMgrRegs->PGSR3 = ((pSleepParam->PGSR3_vals & pSleepParam->PGSR3_msk) |
(pGpioRegs->GPLR3 & ~pSleepParam->PGSR3_msk))
& XLLP_PM_PGSR3_VLD_MSK;
dummyRegReadTarget = pPwrMgrRegs->PGSR3;
// Set wakeup enable reasons and edge detect options.
// RTC and non-keypad GPIOs and edge detects
pPwrMgrRegs->PWER = pSleepParam->PWER;
dummyRegReadTarget = pPwrMgrRegs->PWER ;
pPwrMgrRegs->PRER = pSleepParam->PRER;
dummyRegReadTarget = pPwrMgrRegs->PRER ;
pPwrMgrRegs->PFER = pSleepParam->PFER;
dummyRegReadTarget = pPwrMgrRegs->PFER ;
// Keypad pins (level triggered)
pPwrMgrRegs->PKWR = pSleepParam->PKWR;
dummyRegReadTarget = pPwrMgrRegs->PKWR ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -