示例#1
0
//------------------------------------------------------------------------------
//
// Function:     OEMPowerOff
//
// Description:  Called when the system is to transition to it's lowest  power mode (off)
//
//
void OEMPowerOff()
{
    volatile S3C6410_SYSCON_REG *pSysConReg;
    volatile S3C6410_GPIO_REG *pGPIOReg;
    volatile S3C6410_VIC_REG *pVIC0Reg;
    volatile S3C6410_VIC_REG *pVIC1Reg;
    volatile S3C6410_DMAC_REG *pDMAC0Reg;
    volatile S3C6410_DMAC_REG *pDMAC1Reg;
    volatile OTG_PHY_REG *pOtgPhyReg;
    
    OAL_KITL_ARGS *pArgs;
    BOOL PowerStateOn;
    int nIndex = 0;

    OALMSG(TRUE, (L"[OEM] ++OEMPowerOff()"));

    // Make sure that KITL is powered off
    pArgs = (OAL_KITL_ARGS*)OALArgsQuery(OAL_ARGS_QUERY_KITL);
    if (pArgs && ((pArgs->flags & OAL_KITL_FLAGS_ENABLED) != 0))
    {
        PowerStateOn = FALSE;
        KITLIoctl (IOCTL_KITL_POWER_CALL, &PowerStateOn, sizeof(PowerStateOn), NULL, 0, NULL);

        OALMSG(OAL_VERBOSE, (L"OEMPowerOff: KITL Disabled\r\n"));
    }

    //-----------------------------
    // Prepare Specific Actions for Sleep
    //-----------------------------
    BSPPowerOff();

    //------------------------------
    // Prepare CPU Entering Sleep Mode
    //------------------------------

    //----------------
    // Map SFR Address
    //----------------
    pSysConReg = (S3C6410_SYSCON_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_SYSCON, FALSE);
    pGPIOReg = (S3C6410_GPIO_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_GPIO, FALSE);
    pVIC0Reg = (S3C6410_VIC_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_VIC0, FALSE);
    pVIC1Reg = (S3C6410_VIC_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_VIC1, FALSE);
    pDMAC0Reg = (S3C6410_DMAC_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_DMA0, FALSE);
    pDMAC1Reg = (S3C6410_DMAC_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_DMA1, FALSE);
    pOtgPhyReg = (OTG_PHY_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_USBOTG_PHY, FALSE);

    //------------------
    // Save VIC Registers
    //------------------
    S3C6410_SaveState_VIC((void *)pVIC0Reg, (void *)pVIC1Reg, g_aSleepSave_VIC);

    // Disable All Interrupt
    pVIC0Reg->VICINTENCLEAR = 0xFFFFFFFF;
    pVIC1Reg->VICINTENCLEAR = 0xFFFFFFFF;
    pVIC0Reg->VICSOFTINTCLEAR = 0xFFFFFFFF;
    pVIC1Reg->VICSOFTINTCLEAR = 0xFFFFFFFF;

    //--------------------
    // Save DMAC Registers
    //--------------------
    S3C6410_SaveState_DMACon((void *)pDMAC0Reg, g_aSleepSave_DMACon0);
    S3C6410_SaveState_DMACon((void *)pDMAC1Reg, g_aSleepSave_DMACon1);

    //------------------
    // Save GPIO Register
    //------------------
    S3C6410_SaveState_GPIO((void *)pGPIOReg, g_aSleepSave_GPIO);

    //--------------------
    // Save SysCon Register
    //--------------------
    S3C6410_SaveState_SysCon((void *)pSysConReg, g_aSleepSave_SysCon);

    //---------------------------------------------------------------------------
    // Unmask Clock Gating for All IPsand Block Power turn On for the IPs not going to sleep
    //---------------------------------------------------------------------------
    // HCLK_IROM, HCLK_MEM1, HCLK_MEM0, HCLK_MFC Should be Always On for power Mode (Something coupled with BUS operation)
    //pSysConReg->HCLK_GATE |= ((1<<25)|(1<<22)|(1<<21)|(1<<0));
    pSysConReg->HCLK_GATE = 0xFFFFFFFF;
    pSysConReg->PCLK_GATE = 0xFFFFFFFF;
    pSysConReg->SCLK_GATE = 0xFFFFFFFF;
    // Turn On All Block Block Power
    pSysConReg->NORMAL_CFG = 0xFFFFFF00;

    // Wait for Block Power Stable
    while((pSysConReg->BLK_PWR_STAT & 0x7E) != 0x7E);

    //----------------------------
    // Wake Up Source Configuration
    //----------------------------
//    S3C6410_WakeUpSource_Configure();

    //-------------------------------
    // Extra work for Entering Sleep Mode
    //-------------------------------

    // USB Power Control
    pSysConReg->OTHERS &= ~(1<<16);    // USB Signal Mask Clear
    pGPIOReg->SPCON |= (1<<3);            // USB Tranceiver PAD to Suspend

    #ifdef _IROM_SDMMC_
    // Sleep Mode Pad Configuration. HSJANG 070926. SLPEN must be 0 to change cpcon value for reading OM.
    #else
    // Sleep Mode Pad Configuration
    pGPIOReg->SLPEN = 0x2;    // Controlled by SLPEN Bit (You Should Clear SLPEN Bit in Wake Up Process...)
    #endif

    //-----------------------
    // CPU Entering Sleep Mode
    //-----------------------

    OALCPUPowerOff();    // Now in Sleep

    //----------------------------
    // CPU Wake Up from Sleep Mode
    //----------------------------

    // Restore SysCon Register
    S3C6410_RestoreState_SysCon((void *)pSysConReg, g_aSleepSave_SysCon);

    // Restore GPIO Register
    S3C6410_RestoreState_GPIO((void *)pGPIOReg, g_aSleepSave_GPIO);

    #ifdef _IROM_SDMMC_
    // Sleep Mode Pad Configuration. HSJANG 070926. SLPEN must be 0 to change cpcon value for reading OM.
    #else
    // Sleep Mode Pad Configuration
    pGPIOReg->SLPEN = 0x2;    // Clear SLPEN Bit for Pad back to Normal Mode
    #endif

    //-----------------------
    // Restore DMAC Registers
    //-----------------------
    S3C6410_RestoreState_DMACon((void *)pDMAC0Reg, g_aSleepSave_DMACon0);
    S3C6410_RestoreState_DMACon((void *)pDMAC1Reg, g_aSleepSave_DMACon1);

    // Restore VIC Registers
    S3C6410_RestoreState_VIC((void *)pVIC0Reg, (void *)pVIC1Reg, g_aSleepSave_VIC);

    // UART Debug Port Initialize
    OEMInitDebugSerial();

    // Disable Vectored Interrupt Mode on CP15
    System_DisableVIC();

    // Enable Branch Prediction on CP15
    System_EnableBP();

    // Enable IRQ Interrupt on CP15
    System_EnableIRQ();

    // Enable FIQ Interrupt on CP15
    System_EnableFIQ();

    // Initialize System Timer
    OEMInitializeSystemTimer(RESCHED_PERIOD, OEM_COUNT_1MS, 0);

    // USB Power Control
    InitializeOTGCLK();              // pll_powerdown, suspend mode

    pGPIOReg->SPCON &= ~(1<<3);        // USB Tranceiver PAD to Normal

    //--------------------------------------
    // Post Processing Specific Actions for Wake Up
    //--------------------------------------
    BSPPowerOn();

    // Reinitialize KITL
    if (pArgs && ((pArgs->flags & OAL_KITL_FLAGS_ENABLED) != 0))
    {
        PowerStateOn = TRUE;
        KITLIoctl (IOCTL_KITL_POWER_CALL, &PowerStateOn, sizeof(PowerStateOn), NULL, 0, NULL);
    }

    OALMSG(TRUE, (L"[OEM] --OEMPowerOff()"));
}
示例#2
0
//------------------------------------------------------------------------------
//
// Function:     OEMPowerOff
//
// Description:  Called when the system is to transition to it's lowest  power mode (off)
//
//
void OEMPowerOff()
{
	volatile S3C6400_SYSCON_REG *pSysConReg;
	volatile S3C6400_GPIO_REG *pGPIOReg;
	volatile S3C6400_VIC_REG *pVIC0Reg;
	volatile S3C6400_VIC_REG *pVIC1Reg;
	volatile S3C6400_DMAC_REG *pDMAC0Reg;
	volatile S3C6400_DMAC_REG *pDMAC1Reg;

 	int nIndex = 0;

	OALMSG(TRUE, (L"[OEM] ++OEMPowerOff()"));

#if	0	// KITL can not support Sleep
	// Make sure that KITL is powered off
	pArgs = (OAL_KITL_ARGS*)OALArgsQuery(OAL_ARGS_QUERY_KITL);
	if ((pArgs->flags & OAL_KITL_FLAGS_ENABLED) != 0)
	{
		OALKitlPowerOff();
		OALMSG(1, (L"OEMPowerOff: KITL Disabled\r\n"));
	}
#endif

	//-----------------------------
	// Disable DVS and Set to Full Speed
	//-----------------------------
#ifdef DVS_EN
	ChangeDVSLevel(SYS_L0);
#endif

	//-----------------------------
	// Prepare Specific Actions for Sleep
	//-----------------------------
	BSPPowerOff();

	//------------------------------
	// Prepare CPU Entering Sleep Mode
	//------------------------------

	//----------------
	// Map SFR Address
	//----------------
	pSysConReg = (S3C6400_SYSCON_REG *)OALPAtoVA(S3C6400_BASE_REG_PA_SYSCON, FALSE);
	pGPIOReg = (S3C6400_GPIO_REG *)OALPAtoVA(S3C6400_BASE_REG_PA_GPIO, FALSE);
	pVIC0Reg = (S3C6400_VIC_REG *)OALPAtoVA(S3C6400_BASE_REG_PA_VIC0, FALSE);
	pVIC1Reg = (S3C6400_VIC_REG *)OALPAtoVA(S3C6400_BASE_REG_PA_VIC1, FALSE);
	pDMAC0Reg = (S3C6400_DMAC_REG *)OALPAtoVA(S3C6400_BASE_REG_PA_DMA0, FALSE);
	pDMAC1Reg = (S3C6400_DMAC_REG *)OALPAtoVA(S3C6400_BASE_REG_PA_DMA1, FALSE);

	//------------------
	// Save VIC Registers
	//------------------
	S3C6400_SaveState_VIC((void *)pVIC0Reg, (void *)pVIC1Reg, g_aSleepSave_VIC);

	// Disable All Interrupt
	pVIC0Reg->VICINTENCLEAR = 0xFFFFFFFF;
	pVIC1Reg->VICINTENCLEAR = 0xFFFFFFFF;
	pVIC0Reg->VICSOFTINTCLEAR = 0xFFFFFFFF;
	pVIC1Reg->VICSOFTINTCLEAR = 0xFFFFFFFF;

	//--------------------
	// Save DMAC Registers
	//--------------------
	S3C6400_SaveState_DMACon((void *)pDMAC0Reg, g_aSleepSave_DMACon0);
	S3C6400_SaveState_DMACon((void *)pDMAC1Reg, g_aSleepSave_DMACon1);

	//------------------
	// Save GPIO Register
	//------------------
	S3C6400_SaveState_GPIO((void *)pGPIOReg, g_aSleepSave_GPIO);

	//--------------------
	// Save SysCon Register
	//--------------------
	S3C6400_SaveState_SysCon((void *)pSysConReg, g_aSleepSave_SysCon);

	//-------------------------------------------------------
	// Unmask Clock Gating and Block Power turn On (SW workaround)
	//-------------------------------------------------------

	// HCLK_IROM, HCLK_MEM1, HCLK_MEM0, HCLK_MFC Should be Always On for power Mode (Something coupled with BUS operation)
	//pSysConReg->HCLK_GATE |= ((1<<25)|(1<<22)|(1<<21)|(1<<0));
	pSysConReg->HCLK_GATE = 0xFFFFFFFF;
	pSysConReg->PCLK_GATE = 0xFFFFFFFF;
	pSysConReg->SCLK_GATE = 0xFFFFFFFF;
	// Turn On All Block Block Power
	pSysConReg->NORMAL_CFG = 0xFFFFFF00;

	// Wait for Block Power Stable
	while((pSysConReg->BLK_PWR_STAT & 0x7E) != 0x7E);

	//----------------------------
	// Wake Up Source Configuration
	//----------------------------
 	S3C6400_WakeUpSource_Configure();

	//-------------------------------
	// Extra work for Entering Sleep Mode
	//-------------------------------

	// USB Power Control
	pSysConReg->OTHERS &= ~(1<<16);	// USB Signal Mask Clear
	pGPIOReg->SPCON |= (1<<3);			// USB Tranceiver PAD to Suspend

	// TODO: SPCONSLP ???
	//pGPIOReg->SPCONSLP;	// Use Default Valie

	//-------------------------------
	// GPIO Configuration for Sleep State
	//-------------------------------
	// TODO: Configure GPIO at Sleep
	//BSPConfigGPIOforPowerOff();

	// Sleep Mode Pad Configuration
	pGPIOReg->SLPEN = 0x2;	// Controlled by SLPEN Bit (You Should Clear SLPEN Bit in Wake Up Process...)

	//-----------------------
	// CPU Entering Sleep Mode
	//-----------------------

	OALCPUPowerOff();	// Now in Sleep

	//----------------------------
	// CPU Wake Up from Sleep Mode
	//----------------------------

	//----------------------------
	// Wake Up Source Determine
	//----------------------------
 	S3C6400_WakeUpSource_Detect();

	// USB Power Control
	pSysConReg->OTHERS |= (1<<16);		// TODO: USB Signal Mask Set (Device must handle it...)
	pGPIOReg->SPCON &= ~(1<<3);		// USB Tranceiver PAD to Normal

	// Restore SysCon Register
	S3C6400_RestoreState_SysCon((void *)pSysConReg, g_aSleepSave_SysCon);

	// Restore GPIO Register
	S3C6400_RestoreState_GPIO((void *)pGPIOReg, g_aSleepSave_GPIO);

	// Sleep Mode Pad Configuration
	pGPIOReg->SLPEN = 0x2;	// Clear SLPEN Bit for Pad back to Normal Mode

	//-----------------------
	// Restore DMAC Registers
	//-----------------------
	S3C6400_RestoreState_DMACon((void *)pDMAC0Reg, g_aSleepSave_DMACon0);
	S3C6400_RestoreState_DMACon((void *)pDMAC1Reg, g_aSleepSave_DMACon1);

	// Restore VIC Registers
	S3C6400_RestoreState_VIC((void *)pVIC0Reg, (void *)pVIC1Reg, g_aSleepSave_VIC);
	//pVIC0Reg->VICADDRESS = 0x0;
	//pVIC1Reg->VICADDRESS = 0x0;

	// UART Debug Port Initialize
	OEMInitDebugSerial();

	// Disable Vectored Interrupt Mode on CP15
	System_DisableVIC();

	// Enable Branch Prediction on CP15
	System_EnableBP();

	// Enable IRQ Interrupt on CP15
	System_EnableIRQ();

	// Enable FIQ Interrupt on CP15
	System_EnableFIQ();

	if (g_oalWakeSource == SYSWAKE_UNKNOWN)
	{
		OALMSG(TRUE, (L"[OEM:ERR] OEMPowerOff() : SYSWAKE_UNKNOWN , WAKEUP_STAT = 0x%08x", g_LastWakeupStatus));
	}

	// Initialize System Timer
	OEMInitializeSystemTimer(RESCHED_PERIOD, OEM_COUNT_1MS, 0);

#if	0	// KITL can not support Sleep
	// Reinitialize KITL
	if ((pArgs->flags & OAL_KITL_FLAGS_ENABLED) != 0)
	{
		OALKitlPowerOn();
	}
#endif

	//--------------------------------------
	// Post Processing Specific Actions for Wake Up
	//--------------------------------------
	BSPPowerOn();

	OALMSG(TRUE, (L"[OEM] --OEMPowerOff()"));
}
示例#3
0
//------------------------------------------------------------------------------
//
//  Function:  OEMPowerOff
//
//  Called when the system is to transition to it's lowest power mode (off)
//
VOID
OEMPowerOff(
    )
{
    DWORD i;
    UINT32 sysIntr;
    UINT intr[3];
    BOOL bPowerOn;
    BOOL bPrevIntrState;
    UINT irq = 0;
    UINT32 mask = 0;
	
    // disable interrupts (note: this should not be needed)
    bPrevIntrState = INTERRUPTS_ENABLE(FALSE);

    // UNDONE: verify if this is still necessary
    // Disable hardware watchdog
    OALWatchdogEnable(FALSE);
    
    // Make sure that KITL is powered off
    bPowerOn = FALSE;
    KITLIoctl(IOCTL_KITL_POWER_CALL, &bPowerOn, sizeof(bPowerOn), NULL, 0, NULL);    

	
    //Save Perf Timer
    OALContextSavePerfTimer();
    // Disable GPTimer2 (used for high perf/monte carlo profiling)
    EnableDeviceClocks(BSPGetGPTPerfDevice(), FALSE);

    // Give chance to do board specific stuff
    BSPPowerOff();

    //----------------------------------------------
    // capture all enabled interrupts and disable interrupts
    intr[0] = INREG32(&g_pIntr->pICLRegs->INTC_MIR0);
    intr[1] = INREG32(&g_pIntr->pICLRegs->INTC_MIR1);
    intr[2] = INREG32(&g_pIntr->pICLRegs->INTC_MIR2);

    OUTREG32(&g_pIntr->pICLRegs->INTC_MIR_SET0, OMAP_MPUIC_MASKALL);
    OUTREG32(&g_pIntr->pICLRegs->INTC_MIR_SET1, OMAP_MPUIC_MASKALL);
    OUTREG32(&g_pIntr->pICLRegs->INTC_MIR_SET2, OMAP_MPUIC_MASKALL);

    //----------------------------------------------
    // Context Save/Restore       
	// Save state then mask all GPIO interrupts
	for (i=0; i<g_pIntr->nbGpioBank; i++)
    {
		INTR_GPIO_CTXT* pCurrGpioCtxt = &g_pIntr->pGpioCtxt[i];

		// Save current state
		pCurrGpioCtxt->restoreCtxt.IRQENABLE1 = INREG32(&pCurrGpioCtxt->pRegs->IRQENABLE1);
		pCurrGpioCtxt->restoreCtxt.WAKEUPENABLE = INREG32(&pCurrGpioCtxt->pRegs->WAKEUPENABLE);

		// Disable all GPIO interrupts in the bank
        OUTREG32(&pCurrGpioCtxt->pRegs->IRQENABLE1, 0);
        OUTREG32(&pCurrGpioCtxt->pRegs->WAKEUPENABLE, 0);

		OALIntrEnableIrqs(1,&pCurrGpioCtxt->bank_irq);

	}

    //----------------------------------------------
    // Clear all enabled IO PAD wakeups for GPIOs
    for (i = 0; i < g_pIntr->nbGpioBank; ++i) 
    {
		INTR_GPIO_CTXT* pCurrGpioCtxt = &g_pIntr->pGpioCtxt[i];

        irq = BSPGetGpioIrq(0) + (i * 32);
        mask = pCurrGpioCtxt->restoreCtxt.WAKEUPENABLE;
        while (mask != 0)
        {
            // If a GPIO was wakeup enabled, then clear the wakeup
            if (mask & 0x1)
            {
                OEMEnableIOPadWakeup((irq - BSPGetGpioIrq(0)), FALSE);
            }
            
            irq++;
            mask >>= 1;    
        }
    }

    //----------------------------------------------
    // Enable wake sources interrupts
    for (sysIntr = SYSINTR_DEVICES; 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);
        }

    // enter full retention
    PrcmSuspend();
    
    //----------------------------------------------
    // Find wakeup source
    for (sysIntr = SYSINTR_DEVICES; 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;
            }
        }
  
    //----------------------------------------------
    // Context Save/Restore
    // Put GPIO interrupt state back to the way it was before suspend
    for (i=0; i<g_pIntr->nbGpioBank; i++)
    {
		INTR_GPIO_CTXT* pCurrGpioCtxt = &g_pIntr->pGpioCtxt[i];		

        // Write registers with the previously saved values
        OUTREG32(&pCurrGpioCtxt->pRegs->IRQENABLE1, pCurrGpioCtxt->restoreCtxt.IRQENABLE1);
        OUTREG32(&pCurrGpioCtxt->pRegs->WAKEUPENABLE, pCurrGpioCtxt->restoreCtxt.WAKEUPENABLE);

    }

    //-------------------------------------------------------
    // Enable all previously enabled IO PAD wakeups for GPIOs
    for (i = 0; i < g_pIntr->nbGpioBank; ++i) 
    {
		INTR_GPIO_CTXT* pCurrGpioCtxt = &g_pIntr->pGpioCtxt[i];

        irq = BSPGetGpioIrq(0) + (i * 32);
        mask = pCurrGpioCtxt->restoreCtxt.WAKEUPENABLE;
        while (mask != 0)
        {
            // If a GPIO was wakeup enabled, then clear the wakeup
            if (mask & 0x1)
            {
                OEMEnableIOPadWakeup((irq - BSPGetGpioIrq(0)), TRUE);
            }
            
            irq++;
            mask >>= 1;    
        }
    }

    //----------------------------------------------
    // Re-enable interrupts    
    OUTREG32(&g_pIntr->pICLRegs->INTC_MIR_CLEAR0, ~intr[0]);
    OUTREG32(&g_pIntr->pICLRegs->INTC_MIR_CLEAR1, ~intr[1]);
    OUTREG32(&g_pIntr->pICLRegs->INTC_MIR_CLEAR2, ~intr[2]);  
    
    //----------------------------------------------
    // Do board specific stuff    
    BSPPowerOn();   
        
    //Sync to Hardware RTC after suspend\resume
    OALIoCtlHalRtcTime( 0,  NULL, 0, NULL, 0, NULL);    

    // Enable GPTimer (used for high perf/monte carlo profiling)
    EnableDeviceClocks(BSPGetGPTPerfDevice(), TRUE);	
    //Restore Perf Timer
    OALContextRestorePerfTimer();
		
    // Reinitialize KITL
    bPowerOn = TRUE;
    KITLIoctl(IOCTL_KITL_POWER_CALL, &bPowerOn, sizeof(bPowerOn), NULL, 0, NULL);    
    
    // Enable hardware watchdog
    OALWatchdogEnable(TRUE);
	
#ifndef SHIP_BUILD
    if (g_PrcmDebugSuspendResume)
	{
        OALMSG(1, (L"Enabled wake sources:\r\n"));
        for (sysIntr = SYSINTR_FIRMWARE; sysIntr < SYSINTR_MAXIMUM; sysIntr++)
        {
            if (OALPowerWakeSource(sysIntr)) 
                OALMSG(1, (L"  SYSINTR %d\r\n", sysIntr));
        }

    	OALMSG(1, (L"\r\nWake due to SYSINTR %d\r\n", g_oalWakeSource));
        OALWakeupLatency_DumpSnapshot();
        PrcmDumpSavedRefCounts();
        DumpPrcmRegsSnapshot();
    }
#endif

    // restore interrupts
    INTERRUPTS_ENABLE(bPrevIntrState);
}