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

📄 xllp_pm_sleepcontext.c

📁 PXA270硬件测试源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
**
** INTEL CONFIDENTIAL
** Copyright 2000-2004 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 Xllp_Store_All_WMMX_Regs(P_XLLP_UINT32_T);
extern Xllp_Restore_All_WMMX_Regs(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 ;

    // 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 ;

   // Clear registers now that will be used to report wakeup reasons.
   pPwrMgrRegs->PEDR = XLLP_PM_PEDR_VLD_MSK ;  // Clear all valid bits
   pPwrMgrRegs->PKSR = XLLP_PM_PKSR_VLD_MSK ;  // Clear all valid bits

    // Finish off the data storage that didn't need assembler
    // and place the checksum.
    XllpPmSleepCLevelSaveCksm (pSleepDataArea);

    // Call OS-specific late suspend function
    if (pSleepParam->pOsSuspendOptionalFn)
    {
        (*pSleepParam->pOsSuspendOptionalFn)();
    }

#if 0
    // Not needed for Bulverde.
    // Mask off the interrupts (must do as well as setting I+F bits in CPSR)
    pIntcRegs->icmr = XLLP_ICMRx_DISABLE_ALL;
#endif


#if 0
    // For Bvd B0, don't need to explicitly disable CKENs.

    // Set CKEN as specified (all disabled is lowest power, but can't kill memory clocks or OST? (not prob. for B0?)
    pClkRegs->cken  = ((pSleepParam->CKEN_vals &  pSleepParam->CKEN_msk) |
                       (pClkRegs->cken   & ~pSleepParam->CKEN_msk))
                      & XLLP_CLKEN_MASK;
#endif
    //
    // Set other sleep state and wake configuration in PCFR and PSLR

    pPwrMgrRegs->PCFR  = (pSleepParam->PCFR_vals &  pSleepParam->PCFR_msk) |
                         (pPwrMgrRegs->PCFR   & ~pSleepParam->PCFR_msk);
    dummyRegReadTarget = pPwrMgrRegs->PCFR ;

    pPwrMgrRegs->PSLR  = (pSleepParam->PSLR_vals &  pSleepParam->PSLR_msk) |
                         (pPwrMgrRegs->PSLR   & ~pSleepParam->PSLR_msk);
    dummyRegReadTarget = pPwrMgrRegs->PSLR ;

    // Make sure that the startup code can find the context.
    pPwrMgrRegs->PSPR = pSleepParam->SleepDataAreaPA;
    dummyRegReadTarget = pPwrMgrRegs->PSPR ;

#ifdef RECORD_TIME
    // Record sleep end time
    *(pSleepParam->Addr_EndSleepTime) = *(pSleepParam->OSCR_Addr);
#endif

    // Drain all buffers, flush all caches, etc. Must use OS-defined functions.
    // Surveys indicate that each OS has unique flushing approaches.

⌨️ 快捷键说明

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