static BOOL CheckUSBinUse(void) { // Check USB Device in Use if (*g_pOTGLinkReg & (0x3<<18)) { if (g_bDVSEN == TRUE) { #ifdef OMNIBOOK_VER if (g_CurrentLevel != SYS_L0) ChangeDVSLevel(SYS_L0); g_bDVSEN = FALSE; // Disable DVS #else //!OMNIBOOK_VER g_bDVSEN = FALSE; // Disable DVS if (g_CurrentLevel != SYS_L0) { ChangeDVSLevel(SYS_L0); } #endif OMNIBOOK_VER OALMSG(OAL_POWER && OAL_FUNC, (L"[DVS] DVS disabled by USB\r\n")); } return TRUE; // Do not apply DVS, when USB is in Use } else { if (g_bDVSEN == FALSE) { // Enable DVS after USB operation finished g_bDVSEN = TRUE; OALMSG(OAL_POWER && OAL_FUNC, (L"[DVS] DVS enabled\r\n")); } } return FALSE; }
//------------------------------------------------------------------------------ // // Function: OALIoCtlHalSetSystemLevel // // For Testing DVS level manually // NOTE!!! Remove UpdateDVS() in the OALTimerIntrHandler() function // static BOOL OALIoCtlHalSetSystemLevel( UINT32 dwIoControlCode, VOID *lpInBuf, UINT32 nInBufSize, VOID *lpOutBuf, UINT32 nOutBufSize, UINT32* lpBytesReturned) { DWORD dwErr = 0; DWORD dwTargetLevel; OALMSG(OAL_IOCTL&&OAL_FUNC, (TEXT("++OALIoCtlHalSetSystemLevel()\r\n"))); if (lpBytesReturned) { *lpBytesReturned = 0; } if (lpInBuf == NULL) { dwErr = ERROR_INVALID_PARAMETER; } else if (sizeof(DWORD) > nInBufSize) { dwErr = ERROR_INSUFFICIENT_BUFFER; } else { __try { dwTargetLevel = *((PDWORD)lpInBuf); if (dwTargetLevel >= SYS_LEVEL_MAX) { dwErr = ERROR_INVALID_PARAMETER; } else { ChangeDVSLevel((SYSTEM_ACTIVE_LEVEL)dwTargetLevel); } } __except (EXCEPTION_EXECUTE_HANDLER) { dwErr = ERROR_INVALID_PARAMETER; } } if (dwErr) { OALMSG(OAL_ERROR, (TEXT("[OAL:ERR] OALIoCtlHalSetSystemLevel() Failed dwErr = 0x%08x\r\n"), dwErr)); NKSetLastError(dwErr); } OALMSG(OAL_IOCTL&&OAL_FUNC, (TEXT("++OALIoCtlHalSetSystemLevel()\r\n"))); return !dwErr; }
//------------------------------------------------------------------------------ // // Function: OALIoCtlHalReboot // This function make a Warm Boot of the target device // static BOOL OALIoCtlHalReboot( UINT32 code, VOID *pInpBuffer, UINT32 inpSize, VOID *pOutBuffer, UINT32 outSize, UINT32 *pOutSize) { OALMSG(OAL_IOCTL&&OAL_FUNC, (TEXT("[OAL] ++OALIoCtlHalReboot()\r\n"))); //----------------------------- // Disable DVS and Set to Full Speed //----------------------------- ChangeDVSLevel(SYS_L0); OEMSWReset(); OALMSG(OAL_IOCTL&&OAL_FUNC, (TEXT("[OAL] --OALIoCtlHalReboot()\r\n"))); return TRUE; }
VOID BSPPowerOff() { volatile S3C6410_GPIO_REG *pGPIOReg; volatile S3C6410_ADC_REG *pADCReg; volatile S3C6410_RTC_REG *pRTCReg; volatile S3C6410_SYSCON_REG *pSysConReg; OALMSG(OAL_FUNC, (TEXT("++BSPPowerOff()\n"))); OALMSG(1, (TEXT("++BSPPowerOff()\n"))); pGPIOReg = (S3C6410_GPIO_REG*)OALPAtoVA(S3C6410_BASE_REG_PA_GPIO, FALSE); pADCReg = (S3C6410_ADC_REG*)OALPAtoVA(S3C6410_BASE_REG_PA_ADC, FALSE); pRTCReg = (S3C6410_RTC_REG*)OALPAtoVA(S3C6410_BASE_REG_PA_RTC, FALSE); pSysConReg = (S3C6410_SYSCON_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_SYSCON, FALSE); //----------------------------- // Wait till NAND Erase/Write operation is finished //----------------------------- VFL_Sync(); //----------------------------- // Disable DVS and Set to Full Speed //----------------------------- ChangeDVSLevel(SYS_L0); // RTC Control Disable pRTCReg->RTCCON = 0x0; // Subclk 32768 Hz, No Reset, Merged BCD counter, XTAL 2^-15, Control Disable //------------------------------- // GPIO Configuration for Sleep State //------------------------------- BSPConfigGPIOforPowerOff(); PWRCTL_Sleep(); // //CLRPORT32(&pIOPort->GPGDAT, 1 << 4); //---------------------------- // Wake Up Source Configuration //---------------------------- S3C6410_WakeUpSource_Configure(); OALMSG(OAL_FUNC, (TEXT("--BSPPowerOff()\n"))); OALMSG(1, (TEXT("--BSPPowerOff()\n"))); }
//------------------------------------------------------------------------------ // // 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()")); }
void UpdateDVS(void) { static IDLE_LOG tLastLogFine; //< This value must be retained to next Update static IDLE_LOG tLastLogCoarse; //< This value must be retained to next Update IDLE_LOG tCurLog; DWORD dwCurrentMSec; DWORD dwCurrentIdleMSec; DWORD dwIdleTick, dwActiveTick; //< This variables is used for profile if(!g_bBSP_DVSEN) { return; } if(CheckUSBinUse()) { return; } dwCurrentMSec = CurMSec; dwCurrentIdleMSec = g_dwCurrentIdleTime; if ( (dwCurrentMSec - tLastLogFine.dwTickCount) >= DVS_UPDATE_PERIOD_FINE ) { tCurLog.dwTickCount = dwCurrentMSec; tCurLog.dwIdleCount = g_dwCurrentIdleTime; tCurLog.dwIdleRate = (100*(dwCurrentIdleMSec-tLastLogFine.dwIdleCount))/(dwCurrentMSec-tLastLogFine.dwTickCount); dwIdleTick = dwCurrentIdleMSec-tLastLogFine.dwIdleCount; dwActiveTick = (dwCurrentMSec-tLastLogFine.dwTickCount)-dwIdleTick; tLastLogFine.dwTickCount = tCurLog.dwTickCount; tLastLogFine.dwIdleCount = tCurLog.dwIdleCount; tLastLogFine.dwIdleRate = tCurLog.dwIdleRate; if (tCurLog.dwIdleRate < ShiftUpRate) // Pump Up the Clock { if (g_bProfileDVS) { g_aDVFSProfileTable[g_CurrentLevel][0] += dwIdleTick; // Idle g_aDVFSProfileTable[g_CurrentLevel][1] += dwActiveTick; // Active g_aDVFSProfileTable[g_CurrentLevel][3] ++ ; // Shift up } OALMSG(OAL_POWER && OAL_FUNC, ((L"U[%d:%d]\r\n"), g_CurrentLevel, tCurLog.dwIdleRate)); ChangeDVSLevel(ShiftUpLevel); } else { if ( (dwCurrentMSec - tLastLogCoarse.dwTickCount) >= DVS_UPDATE_PERIOD_COARSE ) { tCurLog.dwIdleRate = (100*(dwCurrentIdleMSec-tLastLogCoarse.dwIdleCount))/(dwCurrentMSec-tLastLogCoarse.dwTickCount); if (g_bProfileDVS) { dwIdleTick = dwCurrentIdleMSec-tLastLogCoarse.dwIdleCount; dwActiveTick = (dwCurrentMSec-tLastLogCoarse.dwTickCount)-dwIdleTick; g_aDVFSProfileTable[g_CurrentLevel][0] += dwIdleTick; // Idle g_aDVFSProfileTable[g_CurrentLevel][1] += dwActiveTick; // Active g_aDVFSProfileTable[g_CurrentLevel][2] ++; // Shift down } tLastLogCoarse.dwTickCount = tCurLog.dwTickCount; tLastLogCoarse.dwIdleCount = tCurLog.dwIdleCount; tLastLogCoarse.dwIdleRate = tCurLog.dwIdleRate; OALMSG(OAL_POWER && OAL_FUNC, ((L"D[%d:%d]\r\n"), g_CurrentLevel, tCurLog.dwIdleRate)); if (tCurLog.dwIdleRate > ShiftDownRate) // Pump Down the Clock { ChangeDVSLevel(ShiftDownLevel); } } } } }