navienginebsp/ne1_tb/inc/ne1_tb_power.h
changeset 0 5de814552237
equal deleted inserted replaced
-1:000000000000 0:5de814552237
       
     1 /*
       
     2 * Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 * ne1_tb\inc\ne1_tb_power.h
       
    16 * NE1_TBVariant Power Management Header
       
    17 * (see also assp.cpp for a discussion on Sleep modes and xyin.cpp for example
       
    18 * of usage of Resource Manager and Peripheral self power down and interaction
       
    19 * with Power Controller for Wakeup Events)
       
    20 *
       
    21 */
       
    22 
       
    23 
       
    24 
       
    25 #ifndef __PM_STD_H__
       
    26 #define __PM_STD_H__
       
    27 #include <kernel/kpower.h>
       
    28 #include "variant.h"
       
    29 #include <e32btrace.h>
       
    30 #ifdef __SMP__
       
    31 #include <arm_gic.h>
       
    32 #endif
       
    33 #include <upd35001_timer.h>
       
    34 #if defined (__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__)
       
    35 #include <smppower/idlehelper.h>
       
    36 #include "smpidlehandler.h"
       
    37 #endif
       
    38 
       
    39 #define __PM_ASSERT_ALWAYS(aCond) \
       
    40 	__ASSERT_ALWAYS( (aCond), \
       
    41 		( \
       
    42 			Kern::Printf("Assertion '" #aCond "' failed;\nFile: '" __FILE__ "' Line: %d\n", __LINE__), \
       
    43 			Kern::Fault("Power Management", 1) \
       
    44 		) )
       
    45 
       
    46 #define __PM_ASSERT_DEBUG(aCond) \
       
    47 	__ASSERT_DEBUG( (aCond), \
       
    48 		( \
       
    49 			Kern::Printf("Assertion '" #aCond "' failed;\nFile: '" __FILE__ "' Line: %d\n", __LINE__), \
       
    50 			Kern::Fault("Power Management", 1) \
       
    51 		) )
       
    52 
       
    53 class TNE1_TBPowerController;
       
    54 class DNE1_TBPowerController;
       
    55 
       
    56 struct TRetireEngageCb
       
    57     {
       
    58     TRetireEngageCb(TDfcFn aFunction, TAny* aPtr, TInt aPriority)
       
    59         :iDfc(aFunction,aPtr,aPriority)
       
    60             {};
       
    61     TRetireEngageCb(TDfcFn aFunction, TAny* aPtr, TDfcQue* aDfcQ, TInt aPriority)
       
    62         :iDfc(aFunction,aPtr,aDfcQ,aPriority)
       
    63             {};
       
    64     TDfc iDfc;
       
    65     TInt iResult;
       
    66     TAny* iParam;
       
    67     };    
       
    68 
       
    69 
       
    70 
       
    71 struct SRetireCall
       
    72     {
       
    73     SRetireCall(TInt aCpu,TRetireEngageCb& aCb);
       
    74 #if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__) && defined(SIMULATE_RETIREMENT)
       
    75     static void RetireCoreDfcFn(TAny*);
       
    76     void Call() { iTimer.OneShot(0);} // use a timer instead of Dfc as call can race with timer ISR
       
    77     NTimer iTimer;                    // by using a timer we are kinda sure we will run between ticks
       
    78     TInt iCpu;
       
    79     TRetireEngageCb& iCb;
       
    80     const TUint32 iAllCpusMask;
       
    81 #endif
       
    82     };
       
    83 
       
    84 
       
    85 struct SEngageCall
       
    86     {
       
    87     SEngageCall(TInt aCpu,TRetireEngageCb& aCb);
       
    88 #if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__) && defined(SIMULATE_RETIREMENT)
       
    89     static void EngageCoreDfcFn(TAny*);
       
    90     void Call() { iDfc.Enque();}
       
    91     TDfc iDfc;
       
    92     TInt iCpu;
       
    93     TRetireEngageCb& iCb;
       
    94 #endif
       
    95     };
       
    96 
       
    97 #if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__)
       
    98 
       
    99 class DNE1_TBPowerController;
       
   100 
       
   101 NONSHARABLE_CLASS(DNE1_SMPIdleHandler) : public DSMPIdleHandler
       
   102     {
       
   103 friend class SRetireCall;
       
   104 friend class SEngageCall;
       
   105 
       
   106 public:
       
   107     DNE1_SMPIdleHandler(DNE1_TBPowerController* aController);
       
   108     TInt Initialise();
       
   109     TBool DoEnterIdle(TInt aCpuMask, TInt aStage, volatile TAny* aU);
       
   110     TBool GetLowPowerMode(TInt aIdleTime, TInt &aLowPowerMode);
       
   111     TBool EnterLowPowerMode(TInt aMode, TInt aCpuMask, TBool aLastCpu);
       
   112 private:
       
   113     void DoRetireCore(TInt aCpu, TLinAddr aReturnPoint);
       
   114 #ifdef SIMULATE_RETIREMENT
       
   115     static void IdleSteal(TAny*);
       
   116 #endif
       
   117 
       
   118 private:
       
   119 #ifdef SIMULATE_RETIREMENT
       
   120     static volatile TUint32 iRetiredCores;
       
   121     //    static volatile TUint32 iEngagingCores;
       
   122     TDfcQue** iIdleStealers;
       
   123     TDfc**    iIdleStealDfcs;
       
   124     TDfcQue*  iRetireEngageQue;
       
   125 #endif
       
   126     DNE1_TBPowerController* iController;
       
   127     };
       
   128 
       
   129 #endif
       
   130 
       
   131 //
       
   132 // TO DO: (mandatory)
       
   133 //
       
   134 // Definition of the DPowerController derived class
       
   135 //
       
   136 NONSHARABLE_CLASS(DNE1_TBPowerController) : public DPowerController
       
   137 	{
       
   138 friend class TNE1_TBPowerController;
       
   139 
       
   140 public: // from DPowerController
       
   141 	void CpuIdle();
       
   142 	void EnableWakeupEvents();
       
   143 	void AbsoluteTimerExpired();
       
   144 	void DisableWakeupEvents();
       
   145 	void PowerDown(TTimeK aWakeupTime);
       
   146     void IdleTickSuppresionEntry(TUint32 aWakeDelay, TInt aNextTimer);
       
   147     void IdleTickSuppresionRestore();
       
   148 public:
       
   149 	DNE1_TBPowerController();
       
   150 private:
       
   151     static TInt ClearTimerInterrupt();      // return pending interrupt or 1023 if non pending
       
   152 	void DoStandby(TBool aTimed, TUint32 aWakeupRTC);
       
   153 public:
       
   154     static const TUint32 KCyclesPerTick;	// clock cycles per ms tick
       
   155     static const TInt KMaxSleepTicks;	// max number of ticks that can be slept
       
   156 	static const TUint32 KWakeUpBeforeTick;	// The time (in cycles) that we required to before next tick is due to expire (i.e. after idle tick suppression)
       
   157 	static const TUint32 KTooCloseToTick;	// In cycles abort idle tick suppresion if we very close current tick edge
       
   158 	static const TUint32 KMinTimeToTick;	// In cyles, if time to next interrupt is less than this value in wakeup
       
   159 											// ... we need to update tick in idle tick restore
       
   160 	static const TInt KMinIdleTicks;		// Minimum amount of ticks we wish to enter power saving mode				
       
   161 
       
   162 private:
       
   163 #if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__)
       
   164     DNE1_SMPIdleHandler iIdleHandler;
       
   165 #endif
       
   166 //     const TUint32 iNumCpus;
       
   167 // Idle tick supression related variables
       
   168 	TBool iWakeupEventsOn;
       
   169     TUint32 iNextInterrupt;
       
   170 	TUint32 iOriginalTimerExpire;
       
   171     TUint iIdleCount;                     // in SMP increased every time we do ITS
       
   172                                             // in unicore, updated on every entry to CpuIdle
       
   173     };
       
   174 
       
   175 
       
   176 //
       
   177 // If you need to access to the Power Controller from Drivers/Extensions/Variant 
       
   178 // or access to Resource Manager then define an accessor class as below
       
   179 //
       
   180 class TNE1_TBPowerController
       
   181 	{
       
   182 friend class SRetireCall;
       
   183 friend class SEngageCall;
       
   184 public:
       
   185 	// to allow Variant/Drivers/Extensions access to Resource Manager
       
   186 	// used by drivers/extensions to signal a wakeup event to Power Controller
       
   187 	IMPORT_C static void WakeupEvent();
       
   188     IMPORT_C static void RetireCore(TInt aCpu, TRetireEngageCb& aCb);
       
   189     IMPORT_C static void EngageCore(TInt aCpu, TRetireEngageCb& aCb);
       
   190     IMPORT_C static TUint IdleCount();
       
   191 
       
   192 	inline static void RegisterPowerController(DNE1_TBPowerController* aPowerController);
       
   193 private:
       
   194 	static DNE1_TBPowerController* iPowerController;
       
   195 #if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__)
       
   196     static DNE1_SMPIdleHandler* iIdleHandler;
       
   197 #endif
       
   198     };
       
   199 
       
   200 
       
   201 
       
   202 #include "ne1_tb_power.inl"
       
   203 
       
   204 #endif
       
   205