omap3530/omap3530_drivers/prcm/prcm.cpp
changeset 0 6663340f3fc9
child 27 117faf51deac
equal deleted inserted replaced
-1:000000000000 0:6663340f3fc9
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // \omap3530\omap3530_assp\prcm.cpp
       
    15 // Access to PRCM. And implimentation of device driver's power and clock control API
       
    16 // This file is part of the Beagle Base port
       
    17 //
       
    18 
       
    19 #include <e32cmn.h>
       
    20 #include <assp/omap3530_assp/omap3530_prcm.h>
       
    21 #include <assp/omap3530_assp/omap3530_ktrace.h>
       
    22 #include <assp/omap3530_assp/omap3530_irqmap.h>
       
    23 #include <assp/omap3530_assp/omap3530_hardware_base.h>
       
    24 #include <assp/omap3530_assp/omap3530_assp_priv.h>
       
    25 #include <nkern.h>
       
    26 
       
    27 #include "prcm_regs.h"
       
    28 
       
    29 // Dummy location for redirecting writes which have no effect on a particular clock
       
    30 // More efficient than having to test for it in code
       
    31 TUint32 __dummypoke;
       
    32 #define	KDummy	(TUint32)&__dummypoke
       
    33 
       
    34 namespace
       
    35 {
       
    36 
       
    37 // PLL modes
       
    38 const TUint32 KPllModeStop	= 0x1;
       
    39 const TUint32 KPllModeBypass = 0x5;
       
    40 const TUint32 KPllModeFastRelock = 0x6;
       
    41 const TUint32 KPllModeLock = 0x7;
       
    42 const TUint32 KPllModeMask = 0x7;
       
    43 const TUint32 KPllAutoOff = 0x0;
       
    44 const TUint32 KPllAutoOn = 0x1;
       
    45 const TUint32 KPllAutoMask = 0x7;
       
    46 
       
    47 #ifdef _DEBUG	// to stop warings about unused definitions
       
    48 const TUint	KPllMaximumDivider		= 127;
       
    49 const TUint	KPllMaximumMultiplier	= 2047;
       
    50 #endif
       
    51 const TUint	KPllDividerMask		= 127;
       
    52 const TUint	KPllMultiplierMask	= 2047;
       
    53 const TUint	KPllFreqRangeMask	= 15;
       
    54 const TUint	KPllRampMask		= 3;
       
    55 
       
    56 const TUint KPllLpModeMaximumFrequency = 600000000;
       
    57 
       
    58 // TPll to TClock lookup table
       
    59 static const Prcm::TClock KPllToClock [] =
       
    60 	{
       
    61 	Prcm::EClkMpu,
       
    62 	Prcm::EClkIva2Pll,
       
    63 	Prcm::EClkCore,
       
    64 	Prcm::EClkPeriph,
       
    65 	Prcm::EClkPeriph2
       
    66 	};
       
    67 
       
    68 // struct of info on how to configure each PLL
       
    69 // this doesn't include settings which are the same for all PLLs
       
    70 struct TPllControlInfo
       
    71 	{
       
    72 	TUint32	iConfigRegister;		// register containing configuration settings
       
    73 	TUint32	iMulDivRegister;		// register containing multiplier and divider setting
       
    74 	TUint32	iStatusRegister;		// register containing PLL status
       
    75 	TUint	iMultShift;				// shift to move multiplier into position
       
    76 	TUint	iDivShift;				// shift to move divider into position
       
    77 	TUint	iFreqSelShift;			// shift to move frequency range selection into position
       
    78 	TUint	iRampShift;				// shift to move ramp bits into position
       
    79 	TUint	iDriftShift;			// shift to move driftsel into position
       
    80 	TUint	iLpShift;				// shift to move LP bit into position
       
    81 	TUint	iLockBit;				// bit number of lock flag in iStatusRegister
       
    82 	};
       
    83 
       
    84 static const TPllControlInfo KPllControlInfo[ Prcm::KSupportedPllCount ] =
       
    85 	{
       
    86 	//	ConfReg				MulDivReg			StatusReg				MulShift	DivShift	FreqShift	RampShift	DriftShift	LpShift	LockBit
       
    87 		{ KCM_CLKEN_PLL_MPU,  KCM_CLKSEL1_PLL_MPU,	KCM_IDLEST_PLL_MPU,		8,		0,			4,			8,			3,			10,		0 },		// DPLL1 (mpu)
       
    88 		{ KCM_CLKEN_PLL_IVA2, KCM_CLKSEL1_PLL_IVA2,	KCM_IDLEST_PLL_IVA2,	8,		0,			4,			8,			3,			10,		0 },		// DPLL2 (iva2)
       
    89 		{ KCM_CLKEN_PLL,	KCM_CLKSEL1_PLL,		KCM_IDLEST_CKGEN,		16,		8,			4,			8,			3,			10,		0 },		// DPLL3 (core)
       
    90 		{ KCM_CLKEN_PLL,	KCM_CLKSEL2_PLL,		KCM_IDLEST_CKGEN,		8,		0,			20,			24,			19,			26,		1 },		// DPLL4 (periph)
       
    91 		{ KCM_CLKEN2_PLL,	KCM_CLKSEL4_PLL,		KCM_IDLEST2_CKGEN,		8,		0,			4,			8,			3,			10,		0 }		// DPLL5 (periph2)
       
    92 	};
       
    93 __ASSERT_COMPILE( (sizeof(KPllControlInfo) / sizeof( KPllControlInfo[0] )) == Prcm::KSupportedPllCount );
       
    94 
       
    95 struct TPllModeInfo
       
    96 	{
       
    97 	TUint32		iModeRegister;
       
    98 	TUint32		iAutoRegister;
       
    99 	TUint8		iModeShift;
       
   100 	TUint8		iAutoShift;
       
   101 	TUint8		_spare[2];
       
   102 	};
       
   103 
       
   104 static const TPllModeInfo KPllMode[] =
       
   105 	{
       
   106 		// iModeRegister		iAutoRegister			iModeShift	iAutoShift
       
   107 		{ KCM_CLKEN_PLL_MPU,	KCM_AUTOIDLE_PLL_MPU,	0,			0 },
       
   108 		{ KCM_CLKEN_PLL_IVA2,	KCM_AUTOIDLE_PLL_IVA2,	0,			0 },
       
   109 		{ KCM_CLKEN_PLL,		KCM_AUTOIDLE_PLL,		0,			0 },
       
   110 		{ KCM_CLKEN_PLL,		KCM_AUTOIDLE_PLL,		16,			3 },
       
   111 		{ KCM_CLKEN2_PLL,		KCM_AUTOIDLE2_PLL,		0,			3 }
       
   112 	};
       
   113 __ASSERT_COMPILE( (sizeof(KPllMode) / sizeof( KPllMode[0] )) == Prcm::KSupportedPllCount );
       
   114 
       
   115 
       
   116 // All dividers in the PRCM fall into one of these classes
       
   117 // Some are unique to a particular peripheral but some
       
   118 // are used by multiple peripherals so we can share that implementation
       
   119 enum TDivType
       
   120 	{
       
   121 	EDivNotSupported,
       
   122 	EDiv_1_2,
       
   123 	EDivCore_1_2_4,
       
   124 	EDivCore_3_4_6_96M,
       
   125 	EDivPll_1_To_16,
       
   126 	EDivPll_1_To_31,
       
   127 	EDivUsimClk,
       
   128 	EDivClkOut_1_2_4_8_16,
       
   129 	};
       
   130 
       
   131 struct TDividerInfo
       
   132 	{
       
   133 	TUint32		iRegister;
       
   134 	TUint32		iMask;			// mask of bits to modify in register
       
   135 	TDivType	iDivType : 8;
       
   136 	TUint8		iShift;			// number of bits to shift to move divide value into position
       
   137 	};
       
   138 
       
   139 static const TDividerInfo KDividerInfo[] =
       
   140 	{
       
   141 		{ KCM_CLKSEL2_PLL_MPU,		0x1F,							EDivPll_1_To_16,	0 },	// EClkMpu,		///< DPLL1
       
   142 		{ KCM_CLKSEL2_PLL_IVA2,		0x1F,							EDivPll_1_To_16,	0 },
       
   143 		{ KCM_CLKSEL1_PLL,			0x1FU << 27,					EDivPll_1_To_31,	27 },	// EClkCore,		///< DPLL3
       
   144 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkPeriph,		///< DPLL4
       
   145 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkPeriph2,	///< DPLL5
       
   146 
       
   147 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkPrcmInterface,
       
   148 
       
   149 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkEmu,		///< Emulation clock
       
   150 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkNeon,
       
   151 
       
   152 		{ KCM_CLKSEL_CORE,			KBit0 | KBit1,					EDiv_1_2,			0 },	// EClkL3Domain,
       
   153 		{ KCM_CLKSEL_CORE,			KBit2 | KBit3,					EDiv_1_2,			2 },	// EClkL4Domain,
       
   154 
       
   155 		{ KCM_CLKSEL1_PLL_MPU,		KBit19 | KBit20 | KBit21,		EDivCore_1_2_4,		19 },	// EClkMpuPll_Bypass,	///< DPLL1 bypass frequency
       
   156 		{ KCM_CLKSEL1_PLL_IVA2,		KBit19 | KBit20 | KBit21,		EDivCore_1_2_4,		19 },	// EClkIva2Pll_Bypass,	///< DPLL2 bypass frequency
       
   157 		{ KCM_CLKSEL_WKUP,			KBit1 | KBit2,					EDiv_1_2,			1 },	// EClkRM_F,	///< Reset manager functional clock	
       
   158 		{ KCM_CLKSEL3_PLL,			0x1F,							EDivPll_1_To_16,	0 },	// EClk96M		///< 96MHz clock
       
   159 		{ KCM_CLKSEL5_PLL,			0x1F,							EDivPll_1_To_16,	0 },	// EClk120M		///< 120MHz clock
       
   160 		{ KCM_CLKOUT_CTRL,			KBit3 | KBit4 | KBit5,			EDivClkOut_1_2_4_8_16,	3 },	// EClkSysOut
       
   161 
       
   162 		// Functional clocks
       
   163 		{ KCM_CLKSEL_DSS,			0x1FU << 8,						EDivPll_1_To_16,	8 },	// EClkTv_F,
       
   164 		{ KCM_CLKSEL_DSS,			0x1F,							EDivPll_1_To_16,	0 },	// EClkDss1_F,
       
   165 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkDss2_F,
       
   166 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkCsi2_F,
       
   167 		{ KCM_CLKSEL_CAM,			0x1F,							EDivPll_1_To_16,	0 },	// EClkCam_F,
       
   168 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkIva2_F,
       
   169 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMmc1_F,
       
   170 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMmc2_F,
       
   171 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMmc3_F,
       
   172 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMsPro_F,
       
   173 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkHdq_F,
       
   174 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMcBsp1_F,
       
   175 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMcBsp2_F,
       
   176 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMcBsp3_F,
       
   177 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMcBsp4_F,
       
   178 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMcBsp5_F,
       
   179 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMcSpi1_F,
       
   180 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMcSpi2_F,
       
   181 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMcSpi3_F,
       
   182 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMcSpi4_F,
       
   183 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkI2c1_F,
       
   184 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkI2c2_F,
       
   185 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkI2c3_F,
       
   186 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkUart1_F,
       
   187 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkUart2_F,
       
   188 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkUart3_F,
       
   189 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt1_F,
       
   190 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt2_F,
       
   191 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt3_F,
       
   192 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt4_F,
       
   193 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt5_F,
       
   194 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt6_F,
       
   195 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt7_F,
       
   196 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt8_F,
       
   197 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt9_F,
       
   198 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt10_F,
       
   199 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt11_F,
       
   200 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkUsbTll_F,
       
   201 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkTs_F,
       
   202 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkCpeFuse_F,
       
   203 
       
   204 		{ KCM_CLKSEL_SGX,	KBit0 | KBit1 | KBit2,					EDivCore_3_4_6_96M, 0 },	// EClkSgx_F,
       
   205 
       
   206 		{ KCM_CLKSEL_WKUP,	KBit3 | KBit4 | KBit5 | KBit6,			EDivUsimClk,		3 },	// EClkUsim_F,
       
   207 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkSmartReflex2_F,
       
   208 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkSmartReflex1_F,
       
   209 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkWdt2_F,
       
   210 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkWdt3_F,
       
   211 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpio1_F,
       
   212 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpio2_F,
       
   213 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpio3_F,
       
   214 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpio4_F,
       
   215 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpio5_F,
       
   216 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpio6_F,
       
   217 
       
   218 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkUsb120_F,		///< USB host 120MHz functional clock
       
   219 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkUsb48_F,		///< USB host 48MHz functional clock
       
   220 
       
   221 
       
   222 	// Interface clocks
       
   223 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkDss_I,
       
   224 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkCam_I,
       
   225 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkIcr_I,
       
   226 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMmc1_I,
       
   227 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMmc2_I,
       
   228 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMmc3_I,
       
   229 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMsPro_I,
       
   230 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkHdq_I,
       
   231 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkAes1_I,
       
   232 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkAes2_I,
       
   233 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkSha11_I,
       
   234 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkSha12_I,
       
   235 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkDes1_I,
       
   236 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkDes2_I,
       
   237 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMcBsp1_I,
       
   238 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMcBsp2_I,
       
   239 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMcBsp3_I,
       
   240 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMcBsp4_I,
       
   241 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMcBsp5_I,
       
   242 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkI2c1_I,
       
   243 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkI2c2_I,
       
   244 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkI2c3_I,
       
   245 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkUart1_I,
       
   246 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkUart2_I,
       
   247 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkUart3_I,
       
   248 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMcSpi1_I,
       
   249 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMcSpi2_I,
       
   250 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMcSpi3_I,
       
   251 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMcSpi4_I,
       
   252 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt1_I,
       
   253 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt2_I,
       
   254 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt3_I,
       
   255 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt4_I,
       
   256 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt5_I,
       
   257 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt6_I,
       
   258 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt7_I,
       
   259 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt8_I,
       
   260 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt9_I,
       
   261 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt10_I,
       
   262 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt11_I,
       
   263 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpt12_I,
       
   264 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkMailboxes_I,
       
   265 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkOmapSCM_I,
       
   266 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkHsUsbOtg_I,
       
   267 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkSdrc_I,
       
   268 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkPka_I,
       
   269 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkRng_I,
       
   270 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkUsbTll_I,
       
   271 
       
   272 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkSgx_I,
       
   273 
       
   274 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkUsim_I,
       
   275 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkWdt1_I,
       
   276 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkWdt2_I,
       
   277 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkWdt3_I,
       
   278 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpio1_I,
       
   279 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpio2_I,
       
   280 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpio3_I,
       
   281 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpio4_I,
       
   282 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpio5_I,
       
   283 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkGpio6_I,
       
   284 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClk32Sync_I,
       
   285 
       
   286 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkUsb_I,			///< USB host interface clock
       
   287 
       
   288 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClk48M
       
   289 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClk12M
       
   290 
       
   291 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkSysClk,
       
   292 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkAltClk,
       
   293 		{ KDummy,					0,								EDivNotSupported,	0 },	// EClkSysClk32k,
       
   294 	};
       
   295 __ASSERT_COMPILE( (sizeof(KDividerInfo) / sizeof( KDividerInfo[0] )) == Prcm::KSupportedClockCount );
       
   296 
       
   297 // Special case divider and mux info for USIM
       
   298 struct TUsimDivMuxInfo
       
   299 	{
       
   300 	Prcm::TClock	iClock : 8;		// source clock
       
   301 	TUint8			iDivider;		// divider factor
       
   302 	};
       
   303 static const TUsimDivMuxInfo UsimDivMuxInfo[16] =
       
   304 	{
       
   305 		{ Prcm::EClkSysClk,		1 },	// 0x0
       
   306 		{ Prcm::EClkSysClk,		1 },	// 0x1
       
   307 		{ Prcm::EClkSysClk,		2 },	// 0x2
       
   308 		{ Prcm::EClk96M,		2 },	// 0x3
       
   309 		{ Prcm::EClk96M,		4 },	// 0x4
       
   310 		{ Prcm::EClk96M,		8 },	// 0x5
       
   311 		{ Prcm::EClk96M,		10 },	// 0x6
       
   312 		{ Prcm::EClk120M,		4 },	// 0x7
       
   313 		{ Prcm::EClk120M,		8 },	// 0x8
       
   314 		{ Prcm::EClk120M,		16 },	// 0x9
       
   315 		{ Prcm::EClk120M,		20 },	// 0xA
       
   316 		{ Prcm::EClkSysClk,		1 },	// 0xB
       
   317 		{ Prcm::EClkSysClk,		1 },	// 0xC
       
   318 		{ Prcm::EClkSysClk,		1 },	// 0xD
       
   319 		{ Prcm::EClkSysClk,		1 },	// 0xE
       
   320 		{ Prcm::EClkSysClk,		1 }		// 0xF
       
   321 	};
       
   322 
       
   323 // Structure representing a register, mask and enable/disable values
       
   324 struct TRegisterBitDef
       
   325 	{
       
   326 	TUint32	iRegister;
       
   327 	TUint32	iMask;
       
   328 	TUint32	iEnablePattern;
       
   329 	TUint32	iDisablePattern;
       
   330 	};
       
   331 
       
   332 // Structure for holding information on clock enable and auto mode
       
   333 struct TClockEnableAutoInfo
       
   334 	{
       
   335 	TRegisterBitDef	iGate;
       
   336 	TRegisterBitDef	iAuto;
       
   337 	};
       
   338 
       
   339 const TUint32 KDummyReadAsDisabled = 1;
       
   340 const TUint32 KDummyReadAsEnabled = 0;
       
   341 const TUint32 KBit012	= KBit0 | KBit1 | KBit2;
       
   342 const TUint32 KBit345	= KBit3 | KBit4 | KBit5;
       
   343 const TUint32 KBit16_17_18 = KBit16 | KBit17 | KBit18;
       
   344 
       
   345 // Table of bits to set to enable each clock
       
   346 // Note where a function doesn't exist, use { KDummy, 0, V, 0 } which will cause a write to harmlessly write
       
   347 // to __dummypoke and a read to find that the item is disabled if V==KDummyReadAsDisabled and enabled if V=KDummyReadAsEnabled
       
   348 static const TClockEnableAutoInfo KClockControlTable[] =
       
   349 	{
       
   350 		{ { KDummy, 0, 0, 0 },						{ KCM_AUTOIDLE_PLL_MPU, KBit012, 1, 0 } },					// EClkMpu,
       
   351 		{ { KCM_CLKEN_PLL_IVA2, KBit012, 7, 1 },	{ KCM_AUTOIDLE_PLL_IVA2, KBit0, 1, 0 } },					// EClkIva2Pll,
       
   352 		{ { KCM_CLKEN_PLL, KBit012, 0x7, 0x5 },						{ KCM_AUTOIDLE_PLL, KBit012, 1, 0 } },		// EClkCore,		///< DPLL3
       
   353 		{ { KCM_CLKEN_PLL, KBit16_17_18, KBit16_17_18, KBit16 },	{ KCM_AUTOIDLE_PLL, KBit345, KBit3, 0 } },	// EClkPeriph,		///< DPLL4
       
   354 		{ { KCM_CLKEN2_PLL, KBit012, 0x7, 0x1 },					{ KCM_AUTOIDLE2_PLL, KBit012, 1, 0 } },		// EClkPeriph2,	///< DPLL5
       
   355 
       
   356 		{ { KDummy, 0, 0, 0 },							{ KDummy, 0, KDummyReadAsEnabled, 0 } },		// EClkPrcmInterface,
       
   357 		{ { KDummy, 0, 0, 0 },							{ KCM_CLKSTCTRL_EMU, KBit0 | KBit1, 3, 2 } },		// EClkEmu,		///< Emulation clock
       
   358 		{ { KCM_IDLEST_NEON, KBit0, 0, 1 },				{ KCM_CLKSTCTRL_NEON, KBit0 | KBit1, 3, 2 } },		// EClkNeon,
       
   359 
       
   360 		{ { KDummy, 0, 0, 0 },							{ KCM_CLKSTCTRL_CORE, KBit0 | KBit1, KBit0 | KBit1, 0 } },		// EClkL3Domain,
       
   361 		{ { KDummy, 0, 0, 0 },							{ KCM_CLKSTCTRL_CORE, KBit2 | KBit3, KBit2 | KBit3, 0 } },	// EClkL4Domain,
       
   362 
       
   363 		{ { KDummy, 0, 0, 0 },							{ KDummy, 0, KDummyReadAsEnabled, 0 } },		// EClkMpuPll_Bypass,	///< DPLL1 bypass frequency
       
   364 		{ { KDummy, 0, 0, 0 },							{ KDummy, 0, KDummyReadAsEnabled, 0 } },		// EClkIva2Pll_Bypass,	///< DPLL2 bypass frequency
       
   365 		{ { KDummy, 0, 0, 0 },							{ KDummy, 0, KDummyReadAsEnabled, 0 } },		// EClkRM_F,			///< Reset manager functional clock	
       
   366 		{ { KDummy, 0, 0, 0 },							{ KDummy, 0, KDummyReadAsEnabled, 0 } },		// EClk96M,			///< 96MHz clock
       
   367 		{ { KDummy, 0, 0, 0 },							{ KDummy, 0, KDummyReadAsEnabled, 0 } },		// EClk120M,			///< 120MHz clock
       
   368 		{ { KDummy, 0, 0, 0 },							{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkSysOut,
       
   369 
       
   370 	// Functional clocks
       
   371 		{ { KCM_FCLKEN_DSS, KBit2, KBit2, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkTv_F,
       
   372 		{ { KCM_FCLKEN_DSS, KBit0, KBit0, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkDss1_F,
       
   373 		{ { KCM_FCLKEN_DSS, KBit1, KBit1, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkDss2_F,
       
   374 		{ { KCM_FCLKEN_CAM, KBit1, KBit1, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkCsi2_F,
       
   375 		{ { KCM_FCLKEN_CAM, KBit0, KBit0, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkCam_F,
       
   376 		{ { KCM_FCLKEN_IVA2, KBit0, KBit0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkIva2_F,
       
   377 		{ { KCM_FCLKEN1_CORE, KBit24, KBit24, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkMmc1_F,
       
   378 		{ { KCM_FCLKEN1_CORE, KBit25, KBit25, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkMmc2_F,
       
   379 		{ { KCM_FCLKEN1_CORE, KBit30, KBit30, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkMmc3_F,
       
   380 		{ { KCM_FCLKEN1_CORE, KBit23, KBit23, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkMsPro_F,
       
   381 		{ { KCM_FCLKEN1_CORE, KBit22, KBit22, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkHdq_F,
       
   382 		{ { KCM_FCLKEN1_CORE, KBit9, KBit9, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkMcBSP1_F,
       
   383 		{ { KCM_FCLKEN_PER, KBit0, KBit0, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkMcBSP2_F,
       
   384 		{ { KCM_FCLKEN_PER, KBit1, KBit1, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkMcBSP3_F,
       
   385 		{ { KCM_FCLKEN_PER, KBit2, KBit2, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkMcBSP4_F,
       
   386 		{ { KCM_FCLKEN1_CORE, KBit10, KBit10, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkMcBSP5_F,
       
   387 		{ { KCM_FCLKEN1_CORE, KBit18, KBit18, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkMcSpi1_F,
       
   388 		{ { KCM_FCLKEN1_CORE, KBit19, KBit19, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkMcSpi2_F,
       
   389 		{ { KCM_FCLKEN1_CORE, KBit20, KBit20, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkMcSpi3_F,
       
   390 		{ { KCM_FCLKEN1_CORE, KBit21, KBit21, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkMcSpi4_F,
       
   391 		{ { KCM_FCLKEN1_CORE, KBit15, KBit15, 0},	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkI2c1_F,
       
   392 		{ { KCM_FCLKEN1_CORE, KBit16, KBit16, 0},	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkI2c2_F,
       
   393 		{ { KCM_FCLKEN1_CORE, KBit17, KBit17, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkI2c3_F,
       
   394 		{ { KCM_FCLKEN1_CORE, KBit13, KBit13, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkUart1_F,
       
   395 		{ { KCM_FCLKEN1_CORE, KBit14, KBit14, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkUart2_F,
       
   396 		{ { KCM_FCLKEN_PER, KBit11, KBit11, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkUart3_F,
       
   397 		{ { KCM_FCLKEN_WKUP, KBit0, KBit0, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkGpt1_F,
       
   398 		{ { KCM_FCLKEN_PER, KBit3, KBit3, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkGpt2_F,
       
   399 		{ { KCM_FCLKEN_PER, KBit4, KBit4, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkGpt3_F,
       
   400 		{ { KCM_FCLKEN_PER, KBit5, KBit5, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkGpt4_F,
       
   401 		{ { KCM_FCLKEN_PER, KBit6, KBit6, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkGpt5_F,
       
   402 		{ { KCM_FCLKEN_PER, KBit7, KBit7, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkGpt6_F,
       
   403 		{ { KCM_FCLKEN_PER, KBit8, KBit8, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkGpt7_F,
       
   404 		{ { KCM_FCLKEN_PER, KBit9, KBit9, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkGpt8_F,
       
   405 		{ { KCM_FCLKEN_PER, KBit10, KBit10, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkGpt9_F,
       
   406 		{ { KCM_FCLKEN1_CORE, KBit11, KBit11, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkGpt10_F,
       
   407 		{ { KCM_FCLKEN1_CORE, KBit12, KBit12, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkGpt11_F,
       
   408 		{ { KCM_FCLKEN3_CORE, KBit2, KBit2, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkUsbTll_F,
       
   409 		{ { KCM_FCLKEN3_CORE, KBit1, KBit1, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkTs_F,
       
   410 		{ { KCM_FCLKEN3_CORE, KBit0, KBit0, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkCpeFuse_F,
       
   411 
       
   412 		{ { KCM_FCLKEN_SGX, KBit1, KBit1, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkSgx_F,
       
   413 
       
   414 		{ { KCM_FCLKEN_WKUP, KBit9, KBit9, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkUsim_F,
       
   415 		{ { KCM_FCLKEN_WKUP, KBit7, KBit7, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkSmartReflex2_F,
       
   416 		{ { KCM_FCLKEN_WKUP, KBit6, KBit6, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkSmartReflex1_F,
       
   417 		{ { KCM_FCLKEN_WKUP, KBit5, KBit5, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkWdt2_F,
       
   418 		{ { KCM_FCLKEN_PER, KBit12, KBit12, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkWdt3_F,
       
   419 		{ { KCM_FCLKEN_WKUP, KBit3, KBit3, 0 },		{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkGpio1_F,
       
   420 		{ { KCM_FCLKEN_PER, KBit13, KBit13, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkGpio2_F,
       
   421 		{ { KCM_FCLKEN_PER, KBit14, KBit14, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkGpio3_F,
       
   422 		{ { KCM_FCLKEN_PER, KBit15, KBit15, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkGpio4_F,
       
   423 		{ { KCM_FCLKEN_PER, KBit16, KBit16, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkGpio5_F,
       
   424 		{ { KCM_FCLKEN_PER, KBit17, KBit17, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkGpio6_F,
       
   425 
       
   426 		{ { KCM_FCLKEN_USBHOST, KBit1, KBit1, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkUsb120_F,
       
   427 		{ { KCM_FCLKEN_USBHOST, KBit0, KBit0, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },		// EClkUsb48_F,
       
   428 
       
   429 
       
   430 	// Interface clocks
       
   431 		{ { KCM_ICLKEN_DSS, KBit0, KBit0, 0 },		{ KCM_AUTOIDLE_DSS, KBit0, KBit0, 0 } },		// EClkDss_I,
       
   432 		{ { KCM_ICLKEN_CAM, KBit0,KBit0, 0 },		{ KCM_AUTOIDLE_CAM, KBit0, KBit0, 0 } },		// EClkCam_I,
       
   433 		{ { KCM_ICLKEN1_CORE, KBit29, KBit29, 0 },	{ KCM_AUTOIDLE1_CORE, KBit29, KBit29, 0 } },	// EClkIcr_I,
       
   434 		{ { KCM_ICLKEN1_CORE, KBit24, KBit24, 0 },	{ KCM_AUTOIDLE1_CORE, KBit24, KBit24, 0 } },	// EClkMmc1_I,
       
   435 		{ { KCM_ICLKEN1_CORE, KBit25, KBit25, 0 },	{ KCM_AUTOIDLE1_CORE, KBit25, KBit25, 0 } },	// EClkMmc2_I,
       
   436 		{ { KCM_ICLKEN1_CORE, KBit30, KBit30, 0 },	{ KCM_AUTOIDLE1_CORE, KBit30, KBit30, 0 } },	// EClkMmc3_I,
       
   437 		{ { KCM_ICLKEN1_CORE, KBit23, KBit23, 0 },	{ KCM_AUTOIDLE1_CORE, KBit23, KBit23, 0 } },	// EClkMsPro_I,
       
   438 		{ { KCM_ICLKEN1_CORE, KBit22, KBit22, 0 },	{ KCM_AUTOIDLE1_CORE, KBit22, KBit22, 0 } },	// EClkHdq_I,
       
   439 		{ { KCM_ICLKEN2_CORE, KBit3, KBit3, 0 },	{ KCM_AUTOIDLE2_CORE, KBit3, KBit3, 0 } },		// EClkAes1_I,
       
   440 		{ { KCM_ICLKEN1_CORE, KBit28, KBit28, 0 },	{ KCM_AUTOIDLE1_CORE, KBit28, KBit28, 0 } },	// EClkAes2_I,
       
   441 		{ { KCM_ICLKEN2_CORE, KBit1, KBit1, 0 },	{ KCM_AUTOIDLE2_CORE, KBit1, KBit1, 0 } },		// EClkSha11_I,
       
   442 		{ { KCM_ICLKEN1_CORE, KBit28, KBit27, 0 },	{ KCM_AUTOIDLE1_CORE, KBit27, KBit27, 0 } },	// EClkSha12_I,
       
   443 		{ { KCM_ICLKEN2_CORE, KBit0, KBit0, 0 },	{ KCM_AUTOIDLE2_CORE, KBit0, KBit0, 0 } },		// EClkDes1_I,
       
   444 		{ { KCM_ICLKEN1_CORE, KBit26, KBit26, 0 },	{ KCM_AUTOIDLE1_CORE, KBit26, KBit26, 0 } },	// EClkDes2_I,
       
   445 		{ { KCM_ICLKEN1_CORE, KBit9, KBit9, 0 },	{ KCM_AUTOIDLE1_CORE, KBit9, KBit9, 0 } },		// EClkMcBSP1_I,
       
   446 		{ { KCM_ICLKEN_PER, KBit0, KBit0, 0},		{ KCM_AUTOIDLE_PER, KBit0, KBit0, 0 } },		// EClkMcBSP2_I,
       
   447 		{ { KCM_ICLKEN_PER, KBit1, KBit1, 0 },		{ KCM_AUTOIDLE_PER, KBit1, KBit1, 0 } },		// EClkMcBSP3_I,
       
   448 		{ { KCM_ICLKEN_PER, KBit2, KBit2, 0 },		{ KCM_AUTOIDLE_PER, KBit2, KBit2, 0 } },		// EClkMcBSP4_I,
       
   449 		{ { KCM_ICLKEN1_CORE, KBit10, KBit10, 0 },	{ KCM_AUTOIDLE1_CORE, KBit10, KBit10, 0 } },	// EClkMcBSP5_I,
       
   450 		{ { KCM_ICLKEN1_CORE, KBit15, KBit15, 0 },	{ KCM_AUTOIDLE1_CORE, KBit15, KBit15, 0 } },	// EClkI2c1_I,
       
   451 		{ { KCM_ICLKEN1_CORE, KBit16, KBit16, 0 },	{ KCM_AUTOIDLE1_CORE, KBit16, KBit16, 0 } },	// EClkI2c2_I,
       
   452 		{ { KCM_ICLKEN1_CORE, KBit17, KBit17, 0 },	{ KCM_AUTOIDLE1_CORE, KBit17, KBit17, 0 } },	// EClkI2c3_I,
       
   453 		{ { KCM_ICLKEN1_CORE, KBit13, KBit13, 0 },	{ KCM_AUTOIDLE1_CORE, KBit13, KBit13, 0 } },	// EClkUart1_I,
       
   454 		{ { KCM_ICLKEN1_CORE, KBit14, KBit14, 0 },	{ KCM_AUTOIDLE1_CORE, KBit14, KBit14, 0 } },	// EClkUart2_I,
       
   455 		{ { KCM_ICLKEN_PER, KBit11, KBit11, 0 },	{ KCM_AUTOIDLE_PER, KBit11, KBit11, 0 } },		// EClkUart3_I,
       
   456 		{ { KCM_ICLKEN1_CORE, KBit18, KBit18, 0 },	{ KCM_AUTOIDLE1_CORE, KBit18, KBit18, 0 } },	// EClkMcSpi1_I,
       
   457 		{ { KCM_ICLKEN1_CORE, KBit19, KBit19, 0 },	{ KCM_AUTOIDLE1_CORE, KBit19, KBit19, 0 } },	// EClkMcSpi2_I,
       
   458 		{ { KCM_ICLKEN1_CORE, KBit20, KBit20, 0 },	{ KCM_AUTOIDLE1_CORE, KBit20, KBit20, 0 } },	// EClkMcSpi3_I,
       
   459 		{ { KCM_ICLKEN1_CORE, KBit21, KBit21, 0 },	{ KCM_AUTOIDLE1_CORE, KBit21, KBit21, 0 } },	// EClkMcSpi4_I,
       
   460 		{ { KCM_ICLKEN_WKUP, KBit0, KBit0, 0 },		{ KCM_AUTOIDLE_WKUP, KBit0, KBit0, 0 } },		// EClkGpt1_I,
       
   461 		{ { KCM_ICLKEN_PER, KBit3, KBit3, 0 },		{ KCM_AUTOIDLE_PER, KBit3, KBit3, 0 } },		// EClkGpt2_I,
       
   462 		{ { KCM_ICLKEN_PER, KBit4, KBit4, 0 },		{ KCM_AUTOIDLE_PER, KBit4, KBit4, 0 } },		// EClkGpt3_I,
       
   463 		{ { KCM_ICLKEN_PER, KBit5, KBit5, 0 },		{ KCM_AUTOIDLE_PER, KBit5, KBit5, 0 } },		// EClkGpt4_I,
       
   464 		{ { KCM_ICLKEN_PER, KBit6, KBit6, 0 },		{ KCM_AUTOIDLE_PER, KBit6, KBit6, 0 } },		// EClkGpt5_I,
       
   465 		{ { KCM_ICLKEN_PER, KBit7, KBit7, 0 },		{ KCM_AUTOIDLE_PER, KBit7, KBit7, 0 } },		// EClkGpt6_I,
       
   466 		{ { KCM_ICLKEN_PER, KBit8, KBit8, 0 },		{ KCM_AUTOIDLE_PER, KBit8, KBit8, 0 } },		// EClkGpt7_I,
       
   467 		{ { KCM_ICLKEN_PER, KBit9, KBit9, 0 },		{ KCM_AUTOIDLE_PER, KBit9, KBit9, 0 } },		// EClkGpt8_I,
       
   468 		{ { KCM_ICLKEN_PER, KBit10, KBit10, 0 },	{ KCM_AUTOIDLE_PER, KBit10, KBit10, 0 } },		// EClkGpt9_I,
       
   469 		{ { KCM_ICLKEN1_CORE, KBit11, KBit11, 0 },	{ KCM_AUTOIDLE1_CORE, KBit11, KBit11, 0 } },	// EClkGpt10_I,
       
   470 		{ { KCM_ICLKEN1_CORE, KBit12, KBit12, 0 },	{ KCM_AUTOIDLE1_CORE, KBit12, KBit12, 0 } },	// EClkGpt11_I,
       
   471 		{ { KDummy, 0, 0, 0 },						{ KDummy, 0, KDummyReadAsDisabled, 0 } },							// EClkGpt12_I,
       
   472 		{ { KCM_ICLKEN1_CORE, KBit7, KBit7, 0 },	{ KCM_AUTOIDLE1_CORE, KBit7, KBit7, 0 } },		// EClkMailboxes_I,
       
   473 		{ { KCM_ICLKEN1_CORE, KBit6, KBit6, 0 },	{ KCM_AUTOIDLE1_CORE, KBit6, KBit6, 0 } },		// EClkOmapSCM_I,
       
   474 		{ { KCM_ICLKEN1_CORE, KBit4, KBit4, 0 },	{ KCM_AUTOIDLE1_CORE, KBit4, KBit4, 0 } },		// EClkHsUsbOtg_I,
       
   475 		{ { KCM_ICLKEN1_CORE, KBit1, KBit1, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkSdrc_I,
       
   476 		{ { KCM_ICLKEN2_CORE, KBit4, KBit4, 0 },	{ KCM_AUTOIDLE2_CORE, KBit4, KBit4, 0 } },		// EClkPka_I,
       
   477 		{ { KCM_ICLKEN2_CORE, KBit2, KBit2, 0 },	{ KCM_AUTOIDLE2_CORE, KBit2, KBit2, 0 } },		// EClkRng_I,
       
   478 		{ { KCM_ICLKEN3_CORE, KBit2, KBit2, 0 },	{ KCM_AUTOIDLE3_CORE, KBit2, KBit2, 0 } },		// EClkUsbTll_I,
       
   479 
       
   480 		{ { KCM_ICLKEN_SGX, KBit0, KBit0, 0 },		{ KCM_CLKSTCTRL_SGX, KBit0 | KBit1, 0x3, 0x0 } },	// EClkSgx_I,
       
   481 
       
   482 		{ { KCM_ICLKEN_WKUP, KBit9, KBit9, 0 },		{ KCM_AUTOIDLE_WKUP, KBit9, KBit9, 0 } },		// EClkUsim_I,
       
   483 		{ { KCM_ICLKEN_WKUP, KBit4, KBit4, 0 },		{ KCM_AUTOIDLE_WKUP, KBit4, KBit4, 0 } },		// EClkWdt1_I,
       
   484 		{ { KCM_ICLKEN_WKUP, KBit5, KBit5, 0 },		{ KCM_AUTOIDLE_WKUP, KBit5, KBit5, 0 } },		// EClkWdt2_I,
       
   485 		{ { KCM_ICLKEN_PER, KBit12, KBit12, 0 },	{ KCM_AUTOIDLE_PER, KBit12, KBit12, 0 } },		// EClkWdt3_I,
       
   486 		{ { KCM_ICLKEN_WKUP, KBit3, KBit3, 0 },		{ KCM_AUTOIDLE_WKUP, KBit3, KBit3, 0 } },		// EClkGpio1_I,
       
   487 		{ { KCM_ICLKEN_PER, KBit13, KBit13, 0 },	{ KCM_AUTOIDLE_PER, KBit13, KBit13, 0 } },		// EClkGpio2_I,
       
   488 		{ { KCM_ICLKEN_PER, KBit14, KBit14, 0 },	{ KCM_AUTOIDLE_PER, KBit14, KBit14, 0 } },		// EClkGpio3_I,
       
   489 		{ { KCM_ICLKEN_PER, KBit15, KBit15, 0 },	{ KCM_AUTOIDLE_PER, KBit15, KBit15, 0 } },		// EClkGpio4_I,
       
   490 		{ { KCM_ICLKEN_PER, KBit16, KBit16, 0 },	{ KCM_AUTOIDLE_PER, KBit16, KBit16, 0 } },		// EClkGpio5_I,
       
   491 		{ { KCM_ICLKEN_PER, KBit17, KBit17, 0 },	{ KCM_AUTOIDLE_PER, KBit17, KBit17, 0 } },		// EClkGpio6_I,
       
   492 		{ { KCM_ICLKEN_WKUP, KBit2, KBit2, 0 },		{ KCM_AUTOIDLE_WKUP, KBit2, KBit2, 0 } },		// EClk32Sync_I,
       
   493 
       
   494 		{ { KCM_ICLKEN_USBHOST, KBit0, KBit0, 0 }, { KCM_AUTOIDLE_USBHOST, KBit0, KBit0, 0 } },		// EClkUsb_I,			///< USB host interface clock
       
   495 
       
   496 		{ { KDummy, 0, 0, 0 },							{ KDummy, 0, KDummyReadAsEnabled, 0 } },		// EClk48M
       
   497 		{ { KDummy, 0, 0, 0 },							{ KDummy, 0, KDummyReadAsEnabled, 0 } },		// EClk12M
       
   498 
       
   499 		{ { KDummy, 0, 0, 0 },							{ KDummy, 0, KDummyReadAsEnabled, 0 } },		// EClkSysClk
       
   500 		{ { KDummy, 0, 0, 0 },							{ KDummy, 0, KDummyReadAsEnabled, 0 } },		// EClkAltClk
       
   501 		{ { KDummy, 0, 0, 0 },							{ KDummy, 0, KDummyReadAsEnabled, 0 } },		// EClkSysClk32k
       
   502 	};
       
   503 __ASSERT_COMPILE( (sizeof(KClockControlTable) / sizeof( KClockControlTable[0] )) == Prcm::KSupportedClockCount );
       
   504 
       
   505 static const TRegisterBitDef KClockWakeupTable[] =
       
   506 	{
       
   507 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkMpu,		///< DPLL1
       
   508 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkIva2Pll,	///< DPLL2
       
   509 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkCore,		///< DPLL3
       
   510 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkPeriph,		///< DPLL4
       
   511 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkPeriph2,	///< DPLL5
       
   512 
       
   513 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkPrcmInterface,
       
   514 
       
   515 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkEmu,		///< Emulation clock
       
   516 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkNeon,
       
   517 
       
   518 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkL3Domain,
       
   519 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkL4Domain,
       
   520 
       
   521 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkMpuPll_Bypass,	///< DPLL1 bypass frequency
       
   522 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkIva2Pll_Bypass,	///< DPLL2 bypass frequency
       
   523 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkRM_F,			///< Reset manager functional clock	
       
   524 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClk96M,			///< 96MHz clock
       
   525 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClk120M,			///< 120MHz clock
       
   526 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkSysOut,
       
   527 
       
   528 	// Functional clocks
       
   529 	// NOTE - functional clocks aren't mapped to a wakeup event, these just clock the internals
       
   530 	// Use the interface clocks to register a wakeup
       
   531 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkTv_F,
       
   532 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkDss1_F,
       
   533 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkDss2_F,
       
   534 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkCsi2_F,
       
   535 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkCam_F,
       
   536 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkIva2_F,
       
   537 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkMmc1_F,
       
   538 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkMmc2_F,
       
   539 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkMmc3_F,
       
   540 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkMsPro_F,
       
   541 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkHdq_F,
       
   542 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkMcBSP1_F,
       
   543 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkMcBSP2_F,
       
   544 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkMcBSP3_F,
       
   545 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkMcBSP4_F,
       
   546 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkMcBSP5_F,
       
   547 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkMcSpi1_F
       
   548 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkMcSpi2_F
       
   549 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkMcSpi3_F
       
   550 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkMcSpi4_F
       
   551 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkI2c1_F,
       
   552 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkI2c2_F,
       
   553 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkI2c3_F,
       
   554 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkUart1_F,
       
   555 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkUart2_F,
       
   556 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkUart3_F,
       
   557 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkGpt1_F,
       
   558 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkGpt2_F,
       
   559 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkGpt3_F,
       
   560 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkGpt4_F,
       
   561 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkGpt5_F,
       
   562 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkGpt6_F,
       
   563 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkGpt7_F,
       
   564 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkGpt8_F,
       
   565 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkGpt9_F,
       
   566 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkGpt10_F,
       
   567 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkGpt11_F,
       
   568 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkUsbTll_F,
       
   569 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkTs_F,
       
   570 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkCpeFuse_F,
       
   571 
       
   572 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkSgx_F,
       
   573 
       
   574 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkUsim_F,
       
   575 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkSmartReflex2_F,
       
   576 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkSmartReflex1_F,
       
   577 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkWdt2_F,
       
   578 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkWdt3_F,
       
   579 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkGpio1_F,
       
   580 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkGpio2_F,
       
   581 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkGpio3_F,
       
   582 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkGpio4_F,
       
   583 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkGpio5_F,
       
   584 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkGpio6_F,
       
   585 
       
   586 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkUsb120_F,		///< USB host 120MHz functional clock
       
   587 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkUsb48_F,		///< USB host 48MHz functional clock
       
   588 
       
   589 
       
   590 	// Interface clocks
       
   591 		{ KPM_WKEN_DSS, KBit0, KBit0, 0 },	// EClkDss_I,
       
   592 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkCam_I,
       
   593 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkIcr_I,
       
   594 		{ KPM_WKEN1_CORE, KBit24, KBit24, 0 },	// EClkMmc1_I,
       
   595 		{ KPM_WKEN1_CORE, KBit25, KBit25, 0 },	// EClkMmc2_I,
       
   596 		{ KPM_WKEN1_CORE, KBit30, KBit30, 0 },	// EClkMmc3_I,
       
   597 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkMsPro_I,
       
   598 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkHdq_I,
       
   599 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkAes1_I,
       
   600 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkAes2_I,
       
   601 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkSha11_I,
       
   602 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkSha12_I,
       
   603 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkDes1_I,
       
   604 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkDes2_I,
       
   605 		{ KPM_WKEN1_CORE, KBit9, KBit9, 0 },	// EClkMcBSP1_I,
       
   606 		{ KPM_WKEN_PER, KBit0, KBit0, 0 },	// EClkMcBSP2_I,
       
   607 		{ KPM_WKEN_PER, KBit1, KBit1, 0 },	// EClkMcBSP3_I,
       
   608 		{ KPM_WKEN_PER, KBit2, KBit2, 0 },	// EClkMcBSP4_I,
       
   609 		{ KPM_WKEN1_CORE, KBit10, KBit10, 0 },	// EClkMcBSP5_I,
       
   610 		{ KPM_WKEN1_CORE, KBit15, KBit15, 0 },	// EClkI2c1_I,
       
   611 		{ KPM_WKEN1_CORE, KBit16, KBit16, 0 },	// EClkI2c2_I,
       
   612 		{ KPM_WKEN1_CORE, KBit17, KBit17, 0 },	// EClkI2c3_I,
       
   613 		{ KPM_WKEN1_CORE, KBit13, KBit13, 0 },	// EClkUart1_I,
       
   614 		{ KPM_WKEN1_CORE, KBit14, KBit14, 0 },	// EClkUart2_I,
       
   615 		{ KPM_WKEN_PER, KBit11, KBit11, 0 },	// EClkUart3_I,
       
   616 		{ KPM_WKEN1_CORE, KBit18, KBit18, 0 },	// EClkMcSpi1_I
       
   617 		{ KPM_WKEN1_CORE, KBit19, KBit19, 0 },	// EClkMcSpi2_I
       
   618 		{ KPM_WKEN1_CORE, KBit20, KBit20, 0 },	// EClkMcSpi3_I
       
   619 		{ KPM_WKEN1_CORE, KBit21, KBit21, 0 },	// EClkMcSpi4_I
       
   620 		{ KPM_WKEN_WKUP, KBit0, KBit0, 0 },	// EClkGpt1_I,
       
   621 		{ KPM_WKEN_PER, KBit3, KBit3, 0 },	// EClkGpt2_I,
       
   622 		{ KPM_WKEN_PER, KBit4, KBit4, 0 },	// EClkGpt3_I,
       
   623 		{ KPM_WKEN_PER, KBit5, KBit5, 0 },	// EClkGpt4_I,
       
   624 		{ KPM_WKEN_PER, KBit6, KBit6, 0 },	// EClkGpt5_I,
       
   625 		{ KPM_WKEN_PER, KBit7, KBit7, 0 },	// EClkGpt6_I,
       
   626 		{ KPM_WKEN_PER, KBit8, KBit8, 0 },	// EClkGpt7_I,
       
   627 		{ KPM_WKEN_PER, KBit9, KBit9, 0 },	// EClkGpt8_I,
       
   628 		{ KPM_WKEN_PER, KBit10, KBit10, 0 },	// EClkGpt9_I,
       
   629 		{ KPM_WKEN1_CORE, KBit11, KBit11, 0 },	// EClkGpt10_I,
       
   630 		{ KPM_WKEN1_CORE, KBit12, KBit12, 0 },	// EClkGpt11_I,
       
   631 		{ KPM_WKEN_WKUP, KBit1, KBit1, 0 },	// EClkGpt12_I,
       
   632 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkMailboxes_I,
       
   633 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkOmapSCM_I,
       
   634 		{ KPM_WKEN1_CORE, KBit4, KBit4, 0 },	// EClkHsUsbOtg_I,
       
   635 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkSdrc_I,
       
   636 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkPka_I,
       
   637 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkRng_I,
       
   638 		{ KPM_WKEN3_CORE, KBit2, KBit2, 0 },	// EClkUsbTll_I,
       
   639 
       
   640 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkSgx_I,
       
   641 
       
   642 		{ KPM_WKEN_WKUP, KBit9, KBit9, 0 },	// EClkUsim_I,
       
   643 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkWdt1_I,
       
   644 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkWdt2_I,
       
   645 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkWdt3_I,
       
   646 		{ KPM_WKEN_WKUP, KBit3, KBit3, 0 },	// EClkGpio1_I,
       
   647 		{ KPM_WKEN_PER, KBit13, KBit13, 0 },	// EClkGpio2_I,
       
   648 		{ KPM_WKEN_PER, KBit14, KBit14, 0 },	// EClkGpio3_I,
       
   649 		{ KPM_WKEN_PER, KBit15, KBit15, 0 },	// EClkGpio4_I,
       
   650 		{ KPM_WKEN_PER, KBit16, KBit16, 0 },	// EClkGpio5_I,
       
   651 		{ KPM_WKEN_PER, KBit17, KBit17, 0 },	// EClkGpio6_I,
       
   652 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClk32Sync_I,
       
   653 
       
   654 		{ KPM_WKEN_USBHOST, KBit0, KBit0, 0 },	// EClkUsb_I,			///< USB host interface clock
       
   655 
       
   656 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClk48M
       
   657 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClk12M
       
   658 
       
   659 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkSysClk
       
   660 		{ KDummy, 0, KDummyReadAsDisabled, 0 },	// EClkAltClk
       
   661 		{ KDummy, 0, KDummyReadAsDisabled, 0 }	// EClkSysClk32k
       
   662 
       
   663 	};
       
   664 __ASSERT_COMPILE( (sizeof(KClockWakeupTable) / sizeof( KClockWakeupTable[0] )) == Prcm::KSupportedClockCount );
       
   665 
       
   666 
       
   667 __ASSERT_COMPILE( Prcm::EWakeGroupMpu == 0 );
       
   668 __ASSERT_COMPILE( Prcm::EWakeGroupIva2 == 1 );
       
   669 static const TRegisterBitDef KClockWakeupGroupTable[ Prcm::KSupportedClockCount ][ Prcm::KSupportedWakeupGroupCount ] =
       
   670 	{
       
   671 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkMpu,		///< DPLL1
       
   672 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkIva2Pll,	///< DPLL2
       
   673 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkCore,		///< DPLL3
       
   674 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkPeriph,		///< DPLL4
       
   675 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkPeriph2,	///< DPLL5
       
   676 
       
   677 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkPrcmInterface,
       
   678 
       
   679 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkEmu,		///< Emulation clock
       
   680 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkNeon,
       
   681 
       
   682 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkL3Domain,
       
   683 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkL4Domain,
       
   684 
       
   685 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkMpuPll_Bypass,	///< DPLL1 bypass frequency
       
   686 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkIva2Pll_Bypass,	///< DPLL2 bypass frequency
       
   687 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkRM_F,			///< Reset manager functional clock	
       
   688 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClk96M,			///< 96MHz clock
       
   689 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClk120M,			///< 120MHz clock
       
   690 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkSysOut,
       
   691 
       
   692 	// Functional clocks
       
   693 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkTv_F,
       
   694 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkDss1_F,
       
   695 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkDss2_F,
       
   696 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkCsi2_F,
       
   697 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkCam_F,
       
   698 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkIva2_F,
       
   699 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkMmc1_F,
       
   700 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkMmc2_F,
       
   701 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkMmc3_F,
       
   702 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkMsPro_F,
       
   703 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkHdq_F,
       
   704 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkMcBsp1_F,
       
   705 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkMcBsp2_F,
       
   706 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkMcBsp3_F,
       
   707 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkMcBsp4_F,
       
   708 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkMcBsp5_F,
       
   709 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkMcSpi1_F,
       
   710 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkMcSpi2_F,
       
   711 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkMcSpi3_F,
       
   712 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkMcSpi4_F,
       
   713 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkI2c1_F,
       
   714 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkI2c2_F,
       
   715 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkI2c3_F,
       
   716 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkUart1_F,
       
   717 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkUart2_F,
       
   718 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkUart3_F,
       
   719 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkGpt1_F,
       
   720 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkGpt2_F,
       
   721 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkGpt3_F,
       
   722 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkGpt4_F,
       
   723 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkGpt5_F,
       
   724 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkGpt6_F,
       
   725 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkGpt7_F,
       
   726 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkGpt8_F,
       
   727 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkGpt9_F,
       
   728 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkGpt10_F,
       
   729 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkGpt11_F,
       
   730 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkUsbTll_F,
       
   731 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkTs_F,
       
   732 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkCpeFuse_F,
       
   733 
       
   734 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkSgx_F,
       
   735 
       
   736 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkUsim_F,
       
   737 		{ { KPM_MPUGRPSEL_WKUP, KBit7, KBit7, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkSmartReflex2_F,
       
   738 		{ { KPM_MPUGRPSEL_WKUP, KBit6, KBit6, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkSmartReflex1_F,
       
   739 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkWdt2_F,
       
   740 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkWdt3_F,
       
   741 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkGpio1_F,
       
   742 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkGpio2_F,
       
   743 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkGpio3_F,
       
   744 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkGpio4_F,
       
   745 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkGpio5_F,
       
   746 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkGpio6_F,
       
   747 
       
   748 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkUsb120_F,		///< USB host 120MHz functional clock
       
   749 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkUsb48_F,		///< USB host 48MHz functional clock
       
   750 
       
   751 
       
   752 	// Interface clocks
       
   753 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkDss_I,
       
   754 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkCam_I,
       
   755 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkIcr_I,
       
   756 		{ { KPM_MPUGRPSEL1_CORE, KBit24, KBit24, 0 },	{ KPM_IVA2GRPSEL1_CORE, KBit24, KBit24, 0 } },			// EClkMmc1_I,
       
   757 		{ { KPM_MPUGRPSEL1_CORE, KBit25, KBit25, 0 },	{ KPM_IVA2GRPSEL1_CORE, KBit25, KBit25, 0 } },			// EClkMmc2_I,
       
   758 		{ { KPM_MPUGRPSEL1_CORE, KBit30, KBit30, 0 },	{ KPM_IVA2GRPSEL1_CORE, KBit30, KBit30, 0 } },			// EClkMmc3_I,
       
   759 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkMsPro_I,
       
   760 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkHdq_I,
       
   761 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkAes1_I,
       
   762 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkAes2_I,
       
   763 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkSha11_I,
       
   764 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkSha12_I,
       
   765 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkDes1_I,
       
   766 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkDes2_I,
       
   767 		{ { KPM_MPUGRPSEL1_CORE, KBit9, KBit9, 0 },	{ KPM_IVA2GRPSEL1_CORE, KBit9, KBit9, 0 } },			// EClkMcBsp1_I,
       
   768 		{ { KPM_MPUGRPSEL_PER, KBit0, KBit0, 0 },	{ KPM_IVA2GRPSEL_PER, KBit0, KBit0, 0 } },			// EClkMcBsp2_I,
       
   769 		{ { KPM_MPUGRPSEL_PER, KBit1, KBit1, 0 },	{ KPM_IVA2GRPSEL_PER, KBit1, KBit1, 0 } },			// EClkMcBsp3_I,
       
   770 		{ { KPM_MPUGRPSEL_PER, KBit2, KBit2, 0 },	{ KPM_IVA2GRPSEL_PER, KBit2, KBit2, 0 } },			// EClkMcBsp4_I,
       
   771 		{ { KPM_MPUGRPSEL1_CORE, KBit10, KBit10, 0 },	{ KPM_IVA2GRPSEL1_CORE, KBit10, KBit10, 0 } },			// EClkMcBsp5_I,
       
   772 		{ { KPM_MPUGRPSEL1_CORE, KBit15, KBit15, 0 },	{ KPM_IVA2GRPSEL1_CORE, KBit15, KBit15, 0 } },			// EClkI2c1_I,
       
   773 		{ { KPM_MPUGRPSEL1_CORE, KBit16, KBit16, 0 },	{ KPM_IVA2GRPSEL1_CORE, KBit16, KBit16, 0 } },			// EClkI2c2_I,
       
   774 		{ { KPM_MPUGRPSEL1_CORE, KBit17, KBit17, 0 },	{ KPM_IVA2GRPSEL1_CORE, KBit17, KBit17, 0 } },			// EClkI2c3_I,
       
   775 		{ { KPM_MPUGRPSEL1_CORE, KBit13, KBit13, 0 },	{ KPM_IVA2GRPSEL1_CORE, KBit13, KBit13, 0 } },			// EClkUart1_I,
       
   776 		{ { KPM_MPUGRPSEL1_CORE, KBit14, KBit14, 0 },	{ KPM_IVA2GRPSEL1_CORE, KBit14, KBit14, 0 } },			// EClkUart2_I,
       
   777 		{ { KPM_MPUGRPSEL_PER, KBit11, KBit11, 0 },	{ KPM_IVA2GRPSEL_PER, KBit11, KBit11, 0 } },			// EClkUart3_I,
       
   778 		{ { KPM_MPUGRPSEL1_CORE, KBit18, KBit18, 0 },	{ KPM_IVA2GRPSEL1_CORE, KBit18, KBit18, 0 } },			// EClkMcSpi1_I,
       
   779 		{ { KPM_MPUGRPSEL1_CORE, KBit19, KBit19, 0 },	{ KPM_IVA2GRPSEL1_CORE, KBit19, KBit19, 0 } },			// EClkMcSpi2_I,
       
   780 		{ { KPM_MPUGRPSEL1_CORE, KBit20, KBit20, 0 },	{ KPM_IVA2GRPSEL1_CORE, KBit20, KBit20, 0 } },			// EClkMcSpi3_I,
       
   781 		{ { KPM_MPUGRPSEL1_CORE, KBit21, KBit21, 0 },	{ KPM_IVA2GRPSEL1_CORE, KBit21, KBit21, 0 } },			// EClkMcSpi4_I,
       
   782 		{ { KPM_MPUGRPSEL_WKUP, KBit0, KBit0, 0 },	{ KPM_IVA2GRPSEL_WKUP, KBit0, KBit0, 0 } },			// EClkGpt1_I,
       
   783 		{ { KPM_MPUGRPSEL_PER, KBit3, KBit3, 0 },	{ KPM_IVA2GRPSEL_PER, KBit3, KBit3, 0 } },			// EClkGpt2_I,
       
   784 		{ { KPM_MPUGRPSEL_PER, KBit4, KBit4, 0 },	{ KPM_IVA2GRPSEL_PER, KBit4, KBit4, 0 } },			// EClkGpt3_I,
       
   785 		{ { KPM_MPUGRPSEL_PER, KBit5, KBit5, 0 },	{ KPM_IVA2GRPSEL_PER, KBit5, KBit5, 0 } },			// EClkGpt4_I,
       
   786 		{ { KPM_MPUGRPSEL_PER, KBit6, KBit6, 0 },	{ KPM_IVA2GRPSEL_PER, KBit6, KBit6, 0 } },			// EClkGpt5_I,
       
   787 		{ { KPM_MPUGRPSEL_PER, KBit7, KBit7, 0 },	{ KPM_IVA2GRPSEL_PER, KBit7, KBit7, 0 } },			// EClkGpt6_I,
       
   788 		{ { KPM_MPUGRPSEL_PER, KBit8, KBit9, 0 },	{ KPM_IVA2GRPSEL_PER, KBit8, KBit8, 0 } },			// EClkGpt7_I,
       
   789 		{ { KPM_MPUGRPSEL_PER, KBit9, KBit9, 0 },	{ KPM_IVA2GRPSEL_PER, KBit9, KBit9, 0 } },			// EClkGpt8_I,
       
   790 		{ { KPM_MPUGRPSEL_PER, KBit10, KBit10, 0 },	{ KPM_IVA2GRPSEL_PER, KBit10, KBit10, 0 } },			// EClkGpt9_I,
       
   791 		{ { KPM_MPUGRPSEL1_CORE, KBit11, KBit11, 0 },	{ KPM_IVA2GRPSEL1_CORE, KBit11, KBit11, 0 } },			// EClkGpt10_I,
       
   792 		{ { KPM_MPUGRPSEL1_CORE, KBit12, KBit12, 0 },	{ KPM_IVA2GRPSEL1_CORE, KBit12, KBit12, 0 } },			// EClkGpt11_I,
       
   793 		{ { KPM_MPUGRPSEL_WKUP, KBit1, KBit1, 0 },	{ KPM_IVA2GRPSEL_WKUP, KBit1, KBit1, 0 } },			// EClkGpt12_I,
       
   794 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkMailboxes_I,
       
   795 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkOmapSCM_I,
       
   796 		{ { KPM_MPUGRPSEL1_CORE, KBit4, KBit4, 0 },	{ KPM_IVA2GRPSEL1_CORE, KBit4, KBit4, 0 } },			// EClkHsUsbOtg_I,
       
   797 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkSdrc_I,
       
   798 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkPka_I,
       
   799 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkRng_I,
       
   800 		{ { KPM_MPUGRPSEL3_CORE, KBit2, KBit2, 0 },	{ KPM_IVA2GRPSEL3_CORE, KBit2, KBit2, 0 } },			// EClkUsbTll_I,
       
   801 
       
   802 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkSgx_I,
       
   803 
       
   804 		{ { KPM_MPUGRPSEL_WKUP, KBit9, KBit9, 0 },	{ KPM_IVA2GRPSEL_WKUP, KBit9, KBit9, 0 } },			// EClkUsim_I,
       
   805 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkWdt1_I,
       
   806 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkWdt2_I,
       
   807 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkWdt3_I,
       
   808 		{ { KPM_MPUGRPSEL_WKUP, KBit3, KBit3, 0 },	{ KPM_IVA2GRPSEL_WKUP, KBit3, KBit3, 0 } },			// EClkGpio1_I,
       
   809 		{ { KPM_MPUGRPSEL_PER, KBit13, KBit13, 0 },	{ KPM_IVA2GRPSEL_PER, KBit13, KBit13, 0 } },			// EClkGpio2_I,
       
   810 		{ { KPM_MPUGRPSEL_PER, KBit14, KBit14, 0 },	{ KPM_IVA2GRPSEL_PER, KBit14, KBit14, 0 } },			// EClkGpio3_I,
       
   811 		{ { KPM_MPUGRPSEL_PER, KBit15, KBit15, 0 },	{ KPM_IVA2GRPSEL_PER, KBit15, KBit15, 0 } },			// EClkGpio4_I,
       
   812 		{ { KPM_MPUGRPSEL_PER, KBit16, KBit16, 0 },	{ KPM_IVA2GRPSEL_PER, KBit16, KBit16, 0 } },			// EClkGpio5_I,
       
   813 		{ { KPM_MPUGRPSEL_PER, KBit17, KBit17, 0 },	{ KPM_IVA2GRPSEL_PER, KBit17, KBit17, 0 } },			// EClkGpio6_I,
       
   814 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClk32Sync_I,
       
   815 
       
   816 		{ { KPM_MPUGRPSEL_USBHOST, KBit0, KBit0, 0 },	{ KPM_IVA2GRPSEL_USBHOST, KBit0, KBit0, 0 } },			// EClkUsb_I,			///< USB host interface clock
       
   817 
       
   818 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClk48M
       
   819 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClk12M
       
   820 
       
   821 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkSysClk
       
   822 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } },			// EClkAltClk
       
   823 		{ { KDummy, 0, KDummyReadAsDisabled, 0 },	{ KDummy, 0, KDummyReadAsDisabled, 0 } }			// EClkSysClk32k
       
   824 	};
       
   825 
       
   826 	__ASSERT_COMPILE( Prcm::EWakeDomainMpu == 0 );
       
   827 	__ASSERT_COMPILE( Prcm::EWakeDomainCore == 1 );
       
   828 	__ASSERT_COMPILE( Prcm::EWakeDomainIva2 == 2 );
       
   829 	__ASSERT_COMPILE( Prcm::EWakeDomainPeripheral == 3 );
       
   830 	__ASSERT_COMPILE( Prcm::EWakeDomainDss == 4 );
       
   831 	__ASSERT_COMPILE( Prcm::EWakeDomainWakeup == 5 );
       
   832 	__ASSERT_COMPILE( Prcm::KSupportedWakeupDomainCount == 6 );
       
   833 
       
   834 struct TWakeupDomainInfo
       
   835 	{
       
   836 	// To save space, there's an assumption here that all domain dependency configuration for
       
   837 	// a single clock is in one register, and a single bit defines the dependency,
       
   838 	// 1 = dependant, 0 = independant
       
   839 	// The bits are defined here by bit number rather than by mask
       
   840 	TUint32		iRegister;
       
   841 	TInt8		iBitNumber[ Prcm::KSupportedWakeupDomainCount ];	///< bit number to modify, -1 if not supported
       
   842 	};
       
   843 
       
   844 static const TWakeupDomainInfo KClockWakeupDomainTable[ Prcm::KSupportedClockCount ] =
       
   845 	{
       
   846 		// REGISTER			MPU		CORE	IVA2	PER		DSS		WAKE
       
   847 		{ KPM_WKDEP_MPU,	{-1,		0,		2,		7,		5,		-1 } },		// EClkMpu,		///< DPLL1
       
   848 		{ KPM_WKDEP_IVA2,	{1,			0,		-1,		7,		5,		4 } },		// EClkIva2Pll,	///< DPLL2
       
   849 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkCore,		///< DPLL3
       
   850 		{ KPM_WKDEP_PER,	{1,			0,		2,		-1,		-1,		4 } },		// EClkPeriph,		///< DPLL4
       
   851 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkPeriph2,	///< DPLL5
       
   852 
       
   853 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkPrcmInterface,
       
   854 
       
   855 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkEmu,		///< Emulation clock
       
   856 		{ KPM_WKDEP_NEON,	{1,			-1,		-1,		-1,		-1,		-1 } },		// EClkNeon,
       
   857 
       
   858 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkL3Domain,
       
   859 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkL4Domain,
       
   860 
       
   861 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMpuPll_Bypass,	///< DPLL1 bypass frequency
       
   862 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkIva2Pll_Bypass,	///< DPLL2 bypass frequency
       
   863 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkRM_F,			///< Reset manager functional clock	
       
   864 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClk96M,			///< 96MHz clock
       
   865 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClk120M,			///< 120MHz clock
       
   866 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkSysOut,
       
   867 
       
   868 	// Functional clocks
       
   869 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkTv_F,
       
   870 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkDss1_F,
       
   871 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkDss2_F,
       
   872 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkCsi2_F,
       
   873 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkCam_F,
       
   874 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkIva2_F,
       
   875 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMmc1_F,
       
   876 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMmc2_F,
       
   877 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMmc3_F,
       
   878 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMsPro_F,
       
   879 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkHdq_F,
       
   880 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMcBsp1_F,
       
   881 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMcBsp2_F,
       
   882 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMcBsp3_F,
       
   883 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMcBsp4_F,
       
   884 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMcBsp5_F,
       
   885 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMcSpi1_F,
       
   886 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMcSpi2_F,
       
   887 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMcSpi3_F,
       
   888 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMcSpi4_F,
       
   889 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkI2c1_F,
       
   890 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkI2c2_F,
       
   891 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkI2c3_F,
       
   892 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkUart1_F,
       
   893 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkUart2_F,
       
   894 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkUart3_F,
       
   895 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt1_F,
       
   896 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt2_F,
       
   897 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt3_F,
       
   898 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt4_F,
       
   899 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt5_F,
       
   900 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt6_F,
       
   901 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt7_F,
       
   902 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt8_F,
       
   903 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt9_F,
       
   904 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt10_F,
       
   905 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt11_F,
       
   906 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkUsbTll_F,
       
   907 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkTs_F,
       
   908 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkCpeFuse_F,
       
   909 
       
   910 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkSgx_F,
       
   911 
       
   912 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkUsim_F,
       
   913 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkSmartReflex2_F,
       
   914 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkSmartReflex1_F,
       
   915 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkWdt2_F,
       
   916 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkWdt3_F,
       
   917 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpio1_F,
       
   918 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpio2_F,
       
   919 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpio3_F,
       
   920 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpio4_F,
       
   921 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpio5_F,
       
   922 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpio6_F,
       
   923 
       
   924 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkUsb120_F,		///< USB host 120MHz functional clock
       
   925 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkUsb48_F,		///< USB host 48MHz functional clock
       
   926 
       
   927 
       
   928 	// Interface clocks
       
   929 		{ KPM_WKDEP_DSS,	{1,		-1,		2,		-1,		-1,		4 } },		// EClkDss_I,
       
   930 		{ KPM_WKDEP_CAM,	{1,		-1,		2,		-1,		-1,		4 } },		// EClkCam_I,
       
   931 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkIcr_I,
       
   932 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMmc1_I,
       
   933 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMmc2_I,
       
   934 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMmc3_I,
       
   935 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMsPro_I,
       
   936 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkHdq_I,
       
   937 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkAes1_I,
       
   938 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkAes2_I,
       
   939 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkSha11_I,
       
   940 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkSha12_I,
       
   941 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkDes1_I,
       
   942 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkDes2_I,
       
   943 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMcBsp1_I,
       
   944 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMcBsp2_I,
       
   945 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMcBsp3_I,
       
   946 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMcBsp4_I,
       
   947 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMcBsp5_I,
       
   948 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkI2c1_I,
       
   949 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkI2c2_I,
       
   950 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkI2c3_I,
       
   951 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkUart1_I,
       
   952 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkUart2_I,
       
   953 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkUart3_I,
       
   954 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMcSpi1_I,
       
   955 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMcSpi2_I,
       
   956 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMcSpi3_I,
       
   957 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMcSpi4_I,
       
   958 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt1_I,
       
   959 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt2_I,
       
   960 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt3_I,
       
   961 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt4_I,
       
   962 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt5_I,
       
   963 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt6_I,
       
   964 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt7_I,
       
   965 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt8_I,
       
   966 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt9_I,
       
   967 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt10_I,
       
   968 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt11_I,
       
   969 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpt12_I,
       
   970 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkMailboxes_I,
       
   971 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkOmapSCM_I,
       
   972 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkHsUsbOtg_I,
       
   973 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkSdrc_I,
       
   974 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkPka_I,
       
   975 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkRng_I,
       
   976 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkUsbTll_I,
       
   977 
       
   978 		{ KPM_WKDEP_SGX,	{1,		-1,		2,		-1,		-1,		4 } },		// EClkSgx_I,
       
   979 
       
   980 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkUsim_I,
       
   981 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkWdt1_I,
       
   982 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkWdt2_I,
       
   983 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkWdt3_I,
       
   984 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpio1_I,
       
   985 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpio2_I,
       
   986 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpio3_I,
       
   987 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpio4_I,
       
   988 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpio5_I,
       
   989 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkGpio6_I,
       
   990 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClk32Sync_I,
       
   991 
       
   992 		{ KPM_WKDEP_USBHOST,	{1,	0,		2,		-1,		-1,		4	} },		// EClkUsb_I,			///< USB host interface clock
       
   993 
       
   994 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClk48M
       
   995 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClk12M
       
   996 		
       
   997 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkSysClk
       
   998 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkAltClk
       
   999 		{ KDummy,		{-1,		-1,		-1,		-1,		-1,		-1 } },		// EClkSysClk32k
       
  1000 		// REGISTER			MPU		CORE	IVA2	PER		DSS		WAKE
       
  1001 	};
       
  1002 
       
  1003 struct TPowerDomainControl
       
  1004 	{
       
  1005 	TUint32		iRegister;
       
  1006 	TUint8		iShift;			///< shift to move bits into position
       
  1007 	TUint8		iAllowedMask;	///< mask of which modes are supported
       
  1008 	TUint8		__spare[2];
       
  1009 	};
       
  1010 
       
  1011 const TUint8	KPowerAllowedOff		= 1 << Prcm::EPowerOff;
       
  1012 const TUint8	KPowerAllowedOn			= 1 << Prcm::EPowerOn;
       
  1013 const TUint8	KPowerAllowedRetention	= 1 << Prcm::EPowerRetention;
       
  1014 const TUint8	KPowerAllowedOnOffRetention	=	(KPowerAllowedOff bitor KPowerAllowedOn bitor KPowerAllowedRetention);
       
  1015 const TUint8	KPowerModeMask			= 0x3;
       
  1016 
       
  1017 static const TPowerDomainControl KPowerDomainControl[] =
       
  1018 	{
       
  1019 		// iRegister			iShift	iAllowedMask
       
  1020 		{ KPM_PWSTCTRL_MPU,		0,		KPowerAllowedOnOffRetention	},	// EPowerDomainMpu,
       
  1021 		{ KPM_PWSTCTRL_IVA2,	0,		KPowerAllowedOnOffRetention	},	// EPowerDomainIva2,
       
  1022 		{ KPM_PWSTCTRL_NEON,	0,		KPowerAllowedOnOffRetention	},	// EPowerDomainNeon,
       
  1023 		{ KPM_PWSTCTRL_CORE,	0,		KPowerAllowedOnOffRetention },	// EPowerDomainCore,
       
  1024 		{ KPM_PWSTCTRL_SGX,		0,		KPowerAllowedOnOffRetention },	// EPowerDomainSgx,
       
  1025 		{ KPM_PWSTCTRL_DSS,		0,		KPowerAllowedOnOffRetention	},	// EPowerDomainDss,
       
  1026 		{ KPM_PWSTCTRL_CAM,		0,		KPowerAllowedOnOffRetention	},	// EPowerDomainCamera,
       
  1027 		{ KPM_PWSTCTRL_USBHOST,	0,		KPowerAllowedOnOffRetention	},	// EPowerDomainUsb,
       
  1028 		{ KPM_PWSTCTRL_PER,		0,		KPowerAllowedOnOffRetention	}	// EPowerDomainPer,
       
  1029 	};
       
  1030 __ASSERT_COMPILE( (sizeof(KPowerDomainControl) / sizeof( KPowerDomainControl[0] )) == Prcm::KSupportedPowerDomainCount );
       
  1031 
       
  1032 struct TGptClkSelInfo
       
  1033 	{
       
  1034 	TUint32	iRegister;
       
  1035 	TUint32	iMask;
       
  1036 	};
       
  1037 
       
  1038 static const TGptClkSelInfo KGptClockSourceInfo[ Prcm::KSupportedGptCount ] =
       
  1039 	{
       
  1040 		{ KCM_CLKSEL_WKUP, KBit0 },	//	EGpt1,
       
  1041 		{ KCM_CLKSEL_PER, KBit0 },	//	EGpt2,
       
  1042 		{ KCM_CLKSEL_PER, KBit1 },	//	EGpt3,
       
  1043 		{ KCM_CLKSEL_PER, KBit2 },	//	EGpt4,
       
  1044 		{ KCM_CLKSEL_PER, KBit3 },	//	EGpt5,
       
  1045 		{ KCM_CLKSEL_PER, KBit4 },	//	EGpt6,
       
  1046 		{ KCM_CLKSEL_PER, KBit5 },	//	EGpt7,
       
  1047 		{ KCM_CLKSEL_PER, KBit6 },	//	EGpt8,
       
  1048 		{ KCM_CLKSEL_PER, KBit7 },	//	EGpt9, 
       
  1049 		{ KCM_CLKSEL_CORE, KBit6 },	//	EGpt10,
       
  1050 		{ KCM_CLKSEL_CORE, KBit7 },	//	EGpt11,
       
  1051 		{ KDummy, 0 },			//	EGpt12	- clocked from security block
       
  1052 	};
       
  1053 
       
  1054 // This table is used to find the source clock for a given clock. That is, by looking up a
       
  1055 // specific clock in this table, you can find out which DPLL/divider it was derived from.
       
  1056 // Following the chain backwards to SYSCLK allows building of the total multiply and
       
  1057 // divide applied to SYSCLK to get the given clock
       
  1058 enum TClockSourceType
       
  1059 	{
       
  1060 	EIgnore,	// not implemented yet...
       
  1061 	EDpll,		// this clock is derived from a PLL
       
  1062 	EDivider,	// this clock is divied from a given clock
       
  1063 	EDivMux,	// divider fed by mux-selectable input clock
       
  1064 	EMux,		// fed by mux-selectable input clock
       
  1065 	EDuplicate,	// this clock is a duplicate of another clock
       
  1066 	E96MMux,	// 96MHz mux-selected clock source
       
  1067 	E54MMux,	// 54MHz mux-selected clock source
       
  1068 	E48MMux,	// 48MHz mux-selected clock source
       
  1069 	EDiv4,		// specified clock source divided by 4
       
  1070 	};
       
  1071 
       
  1072 struct TClockSourceInfo
       
  1073 	{
       
  1074 	TClockSourceType	iType : 8;	// type of the source for this clock
       
  1075 	union	{
       
  1076 		Prcm::TClock	iClock : 8;		// the clock that feeds this divider, or which this is a duplicate of
       
  1077 		Prcm::TPll		iPll : 8;		// the PLL that generates this clock
       
  1078 		Prcm::TGpt		iGpt : 8;		// conversion to TGpt type for the clock we are interested in
       
  1079 		};
       
  1080 	};
       
  1081 
       
  1082 static const TClockSourceInfo KClockSourceInfo[] =
       
  1083 	{
       
  1084 		{ EDpll,		(Prcm::TClock)Prcm::EDpll1 },			// EClkMpu,
       
  1085 		{ EDpll,		(Prcm::TClock)Prcm::EDpll2 },			// EClkIva2Pll,
       
  1086 		{ EDpll,		(Prcm::TClock)Prcm::EDpll3 },			// EClkCore,
       
  1087 		{ EDpll,		(Prcm::TClock)Prcm::EDpll4 },			// EClkPeriph,
       
  1088 		{ EDpll,		(Prcm::TClock)Prcm::EDpll5 },			// EClkPeriph2,
       
  1089 		{ EDuplicate,	Prcm::EClkSysClk },		// EClkPrcmInterface,
       
  1090 		{ EIgnore,		(Prcm::TClock)0 },		// EClkEmu,
       
  1091 		{ EDuplicate,	Prcm::EClkMpu },		// EClkNeon,
       
  1092 		{ EDivider,		Prcm::EClkCore },		// EClkL3Domain,
       
  1093 		{ EDivider,		Prcm::EClkL3Domain },	// EClkL4Domain,
       
  1094 		{ EDivider,		Prcm::EClkCore },		// EClkMpuPll_Bypass,
       
  1095 		{ EDivider,		Prcm::EClkCore },		// EClkIva2Pll_Bypass,
       
  1096 		{ EDivider,		Prcm::EClkL4Domain },	// EClkRM_F,
       
  1097 		{ E96MMux,		Prcm::EClkPeriph },		// EClk96M,
       
  1098 		{ EDivider,		Prcm::EClkPeriph2 },	// EClk120M,
       
  1099 		{ EDivMux,		(Prcm::TClock)0 },		// EClkSysOut,
       
  1100 
       
  1101 	// Functional clocks
       
  1102 		{ E54MMux,		Prcm::EClkPeriph },
       
  1103 		{ EDivider,		Prcm::EClkPeriph },		// EClkDss1_F,
       
  1104 		{ EDuplicate,	Prcm::EClkSysClk },		// EClkDss2_F,
       
  1105 		{ EDuplicate,	Prcm::EClk96M },		// EClkCsi2_F,
       
  1106 		{ EDivider,		Prcm::EClkPeriph },		// EClkCam_F,
       
  1107 		{ EDuplicate,	Prcm::EClkIva2Pll },	// EClkIva2_F,
       
  1108 		{ EDuplicate,	Prcm::EClk96M },		// EClkMmc1_F,
       
  1109 		{ EDuplicate,	Prcm::EClk96M },		// EClkMmc2_F,
       
  1110 		{ EDuplicate,	Prcm::EClk96M },		// EClkMmc3_F,
       
  1111 		{ EDuplicate,	Prcm::EClk96M },		// EClkMsPro_F,
       
  1112 		{ EDuplicate,	Prcm::EClk12M },		// EClkHdq_F,
       
  1113 		{ EDuplicate,	Prcm::EClk96M },		// EClkMcBsp1_F,
       
  1114 		{ EDuplicate,	Prcm::EClk96M },		// EClkMcBsp2_F,
       
  1115 		{ EDuplicate,	Prcm::EClk96M },		// EClkMcBsp3_F,
       
  1116 		{ EDuplicate,	Prcm::EClk96M },		// EClkMcBsp4_F,
       
  1117 		{ EDuplicate,	Prcm::EClk96M },		// EClkMcBsp5_F,
       
  1118 		{ EDuplicate,	Prcm::EClk48M },		// EClkMcSpi1_F,
       
  1119 		{ EDuplicate,	Prcm::EClk48M },		// EClkMcSpi2_F,
       
  1120 		{ EDuplicate,	Prcm::EClk48M },		// EClkMcSpi3_F,
       
  1121 		{ EDuplicate,	Prcm::EClk48M },		// EClkMcSpi4_F,
       
  1122 		{ EDuplicate,	Prcm::EClk96M },		// EClkI2c1_F,
       
  1123 		{ EDuplicate,	Prcm::EClk96M },		// EClkI2c2_F,
       
  1124 		{ EDuplicate,	Prcm::EClk96M },		// EClkI2c3_F,
       
  1125 		{ EDuplicate,	Prcm::EClk48M },		// EClkUart1_F,
       
  1126 		{ EDuplicate,	Prcm::EClk48M },		// EClkUart2_F,
       
  1127 		{ EDuplicate,	Prcm::EClk48M },		// EClkUart3_F,
       
  1128 		{ EMux,			(Prcm::TClock)Prcm::EGpt1 },			// EClkGpt1_F,
       
  1129 		{ EMux,			(Prcm::TClock)Prcm::EGpt2 },			// EClkGpt2_F,
       
  1130 		{ EMux,			(Prcm::TClock)Prcm::EGpt3 },			// EClkGpt3_F,
       
  1131 		{ EMux,			(Prcm::TClock)Prcm::EGpt4 },			// EClkGpt4_F,
       
  1132 		{ EMux,			(Prcm::TClock)Prcm::EGpt5 },			// EClkGpt5_F,
       
  1133 		{ EMux,			(Prcm::TClock)Prcm::EGpt6 },			// EClkGpt6_F,
       
  1134 		{ EMux,			(Prcm::TClock)Prcm::EGpt7 },			// EClkGpt7_F,
       
  1135 		{ EMux,			(Prcm::TClock)Prcm::EGpt8 },			// EClkGpt8_F,
       
  1136 		{ EMux,			(Prcm::TClock)Prcm::EGpt9 },			// EClkGpt9_F,
       
  1137 		{ EMux,			(Prcm::TClock)Prcm::EGpt10 },			// EClkGpt10_F,
       
  1138 		{ EMux,			(Prcm::TClock)Prcm::EGpt11 },			// EClkGpt11_F,
       
  1139 		{ EDuplicate,	Prcm::EClk120M },		// EClkUsbTll_F,
       
  1140 		{ EDuplicate,	Prcm::EClkSysClk32k },	// EClkTs_F,
       
  1141 		{ EDuplicate,	Prcm::EClkSysClk },		// EClkCpeFuse_F,
       
  1142 		{ EDivMux,		(Prcm::TClock)0 },					// EClkSgx_F,
       
  1143 		{ EDivMux,		Prcm::EClkSysClk },		// EClkUsim_F,
       
  1144 		{ EDuplicate,	Prcm::EClkSysClk },		// EClkSmartReflex2_F,
       
  1145 		{ EDuplicate,	Prcm::EClkSysClk },		// EClkSmartReflex1_F,
       
  1146 		{ EDuplicate,	Prcm::EClkSysClk32k },					// EClkWdt2_F,
       
  1147 		{ EDuplicate,	Prcm::EClkSysClk32k },					// EClkWdt3_F,
       
  1148 		{ EDuplicate,	Prcm::EClkSysClk32k },					// EClkGpio1_F,
       
  1149 		{ EDuplicate,	Prcm::EClkSysClk32k },					// EClkGpio2_F,
       
  1150 		{ EDuplicate,	Prcm::EClkSysClk32k },					// EClkGpio3_F,
       
  1151 		{ EDuplicate,	Prcm::EClkSysClk32k },					// EClkGpio4_F,
       
  1152 		{ EDuplicate,	Prcm::EClkSysClk32k },					// EClkGpio5_F,
       
  1153 		{ EDuplicate,	Prcm::EClkSysClk32k },					// EClkGpio6_F,
       
  1154 		{ EDuplicate,	Prcm::EClk120M },		// EClkUsb120_F,
       
  1155 		{ EDuplicate,	Prcm::EClk48M },		// EClkUsb48_F,	
       
  1156 
       
  1157 	// Interface clocks
       
  1158 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkDss_I,
       
  1159 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkCam_I,
       
  1160 		{ },					// EClkIcr_I,
       
  1161 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkMmc1_I,
       
  1162 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkMmc2_I,
       
  1163 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkMmc3_I,
       
  1164 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkMsPro_I,
       
  1165 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkHdq_I,
       
  1166 		{ EDuplicate,	Prcm::EClkL4Domain},		// EClkAes1_I,
       
  1167 		{ EDuplicate,	Prcm::EClkL4Domain},		// EClkAes2_I,
       
  1168 		{ EDuplicate,	Prcm::EClkL4Domain},		// EClkSha11_I,
       
  1169 		{ EDuplicate,	Prcm::EClkL4Domain},		// EClkSha12_I,
       
  1170 		{ EDuplicate,	Prcm::EClkL4Domain},		// EClkDes1_I,
       
  1171 		{ EDuplicate,	Prcm::EClkL4Domain},		// EClkDes2_I,
       
  1172 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkMcBsp1_I,
       
  1173 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkMcBsp2_I,
       
  1174 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkMcBsp3_I,
       
  1175 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkMcBsp4_I,
       
  1176 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkMcBsp5_I,
       
  1177 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkI2c1_I,
       
  1178 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkI2c2_I,
       
  1179 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkI2c3_I,
       
  1180 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkUart1_I,
       
  1181 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkUart2_I,
       
  1182 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkUart3_I,
       
  1183 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkMcSpi1_I,
       
  1184 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkMcSpi2_I,
       
  1185 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkMcSpi3_I,
       
  1186 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkMcSpi4_I,
       
  1187 		{ EDuplicate,	Prcm::EClkSysClk },			// EClkGpt1_I,
       
  1188 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkGpt2_I,
       
  1189 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkGpt3_I,
       
  1190 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkGpt4_I,
       
  1191 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkGpt5_I,
       
  1192 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkGpt6_I,
       
  1193 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkGpt7_I,
       
  1194 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkGpt8_I,
       
  1195 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkGpt9_I,
       
  1196 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkGpt10_I,
       
  1197 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkGpt11_I,
       
  1198 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkGpt12_I,
       
  1199 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkMailboxes_I,
       
  1200 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkOmapSCM_I,
       
  1201 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkHsUsbOtg_I,
       
  1202 		{ EDuplicate,	Prcm::EClkL3Domain },		// EClkSdrc_I,
       
  1203 		{ EDuplicate,	Prcm::EClkL3Domain },		// EClkPka_I,
       
  1204 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkRng_I,
       
  1205 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkUsbTll_I,
       
  1206 		{ EDuplicate,	Prcm::EClkL3Domain },		// EClkSgx_I,
       
  1207 		{ EDuplicate,	Prcm::EClkSysClk },			// EClkUsim_I,
       
  1208 		{ EDuplicate,	Prcm::EClkSysClk },			// EClkWdt1_I,
       
  1209 		{ EDuplicate,	Prcm::EClkSysClk },			// EClkWdt2_I,
       
  1210 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkWdt3_I,
       
  1211 		{ EDuplicate,	Prcm::EClkSysClk },			// EClkGpio1_I,
       
  1212 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkGpio2_I,
       
  1213 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkGpio3_I,
       
  1214 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkGpio4_I,
       
  1215 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkGpio5_I,
       
  1216 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkGpio6_I,
       
  1217 		{ EDuplicate,	Prcm::EClkSysClk },			// EClk32Sync_I,
       
  1218 		{ EDuplicate,	Prcm::EClkL4Domain },		// EClkUsb_I,
       
  1219 
       
  1220 		{ E48MMux,		Prcm::EClk96M },		// EClk48M,
       
  1221 		{ EDiv4,		Prcm::EClk48M },		// EClk12M,
       
  1222 
       
  1223 		{ EDuplicate,	Prcm::EClkSysClk },		// EClkSysClk
       
  1224 		{ EDuplicate,	Prcm::EClkAltClk },		// EClkAltClk
       
  1225 		{ EDuplicate,	Prcm::EClkSysClk32k },	// EClkSysClk32k
       
  1226 
       
  1227 	};
       
  1228 
       
  1229 __ASSERT_COMPILE( sizeof( KClockSourceInfo ) / sizeof( KClockSourceInfo[0] ) == Prcm::KSupportedClockCount );
       
  1230 
       
  1231 
       
  1232 // Bit of hackery to enable creation of a const table of pointer to _LITs.
       
  1233 // Taking the address of a _LIT will cause the compiler to invoke its operator&()
       
  1234 // function, which forces the compiler to generate the table in code. But hiding
       
  1235 // it inside a dummy struct allows taking of the address of the struct instead,
       
  1236 // avoiding the operator&() problem.
       
  1237 
       
  1238 template< TInt S >
       
  1239 struct THiddenLit8
       
  1240 	{
       
  1241 	TLitC8<S>	iLit;
       
  1242 	};
       
  1243 
       
  1244 #define __PLIT8(name,s) const static THiddenLit8<sizeof(s)> name={{sizeof(s)-1,s}};
       
  1245 
       
  1246 // List of identifer strings for each clock source - used for PRM
       
  1247 __PLIT8(KClkMpu,			"a.MPU" );
       
  1248 __PLIT8(KClkIva2Pll,		"a.IVA" );
       
  1249 __PLIT8(KClkCore,			"a.CORE" );
       
  1250 __PLIT8(KClkPeriph,			"a.PER" );
       
  1251 __PLIT8(KClkPeriph2,		"a.PER2" );
       
  1252 __PLIT8(KClkPrcmInterface,	"a.PRCM" );
       
  1253 __PLIT8(KClkEmu,			"a.EMU" );
       
  1254 __PLIT8(KClkNeon,			"a.NEON" );
       
  1255 __PLIT8(KClkL3Domain,		"a.L3" );
       
  1256 __PLIT8(KClkL4Domain,		"a.L4" );
       
  1257 __PLIT8(KClkMpuPll_Bypass,	"a.MPUB" );
       
  1258 __PLIT8(KClkIva2Pll_Bypass,	"a.IVAB" );
       
  1259 __PLIT8(KClkRM_F,			"a.RMf" );
       
  1260 __PLIT8(KClk96M,			"a.96" );
       
  1261 __PLIT8(KClk120M,			"a.120" );
       
  1262 __PLIT8(KClkSysOut,			"a.OUT" );
       
  1263 __PLIT8(KClkTv_F,			"a.TVf" );
       
  1264 __PLIT8(KClkDss1_F,			"a.DSS1f" );
       
  1265 __PLIT8(KClkDss2_F,			"a.DSS2f" );
       
  1266 __PLIT8(KClkCsi2_F,			"a.CSI2f" );
       
  1267 __PLIT8(KClkCam_F,			"a.CAMf" );
       
  1268 __PLIT8(KClkIva2_F,			"a.IVA2f" );
       
  1269 __PLIT8(KClkMmc1_F,			"a.MMC1f" );
       
  1270 __PLIT8(KClkMmc2_F,			"a.MMC2f" );
       
  1271 __PLIT8(KClkMmc3_F,			"a.MMC3f" );
       
  1272 __PLIT8(KClkMsPro_F,		"a.MSPf" );
       
  1273 __PLIT8(KClkHdq_F,			"a.HDQf" );
       
  1274 __PLIT8(KClkMcBsp1_F,		"a.BSP1f" );
       
  1275 __PLIT8(KClkMcBsp2_F,		"a.BSP2f" );
       
  1276 __PLIT8(KClkMcBsp3_F,		"a.BSP3f" );
       
  1277 __PLIT8(KClkMcBsp4_F,		"a.BSP4f" );
       
  1278 __PLIT8(KClkMcBsp5_F,		"a.BSP5f" );
       
  1279 __PLIT8(KClkMcSpi1_F,		"a.SPI1f" );
       
  1280 __PLIT8(KClkMcSpi2_F,		"a.SPI2f" );
       
  1281 __PLIT8(KClkMcSpi3_F,		"a.SPI3f" );
       
  1282 __PLIT8(KClkMcSpi4_F,		"a.SPI4f" );
       
  1283 __PLIT8(KClkI2c1_F,			"a.I2C1f" );
       
  1284 __PLIT8(KClkI2c2_F,			"a.I2C2f" );
       
  1285 __PLIT8(KClkI2c3_F,			"a.I2C3f" );
       
  1286 __PLIT8(KClkUart1_F,		"a.UART1f" );
       
  1287 __PLIT8(KClkUart2_F,		"a.UART2f" );
       
  1288 __PLIT8(KClkUart3_F,		"a.UART3f" );
       
  1289 __PLIT8(KClkGpt1_F,			"a.GPT1f" );
       
  1290 __PLIT8(KClkGpt2_F,			"a.GPT2f" );
       
  1291 __PLIT8(KClkGpt3_F,			"a.GPT3f" );
       
  1292 __PLIT8(KClkGpt4_F,			"a.GPT4f" );
       
  1293 __PLIT8(KClkGpt5_F,			"a.GPT5f" );
       
  1294 __PLIT8(KClkGpt6_F,			"a.GPT6f" );
       
  1295 __PLIT8(KClkGpt7_F,			"a.GPT7f" );
       
  1296 __PLIT8(KClkGpt8_F,			"a.GPT8f" );
       
  1297 __PLIT8(KClkGpt9_F,			"a.GPT9f" );
       
  1298 __PLIT8(KClkGpt10_F,		"a.GPTAf" );
       
  1299 __PLIT8(KClkGpt11_F,		"a.GPTBf" );
       
  1300 __PLIT8(KClkUsbTll_F,		"a.UTLLf" );
       
  1301 __PLIT8(KClkTs_F,			"a.TSf" );
       
  1302 __PLIT8(KClkCpeFuse_F,		"a.FUSEf" );
       
  1303 __PLIT8(KClkSgx_F,			"a.SGXf" );
       
  1304 __PLIT8(KClkUsim_F,			"a.USIMf" );
       
  1305 __PLIT8(KClkSmartReflex2_F,	"a.SMRF2f" );
       
  1306 __PLIT8(KClkSmartReflex1_F,	"a.SMRF1f" );
       
  1307 __PLIT8(KClkWdt2_F,			"a.WDT2f" );
       
  1308 __PLIT8(KClkWdt3_F,			"a.WDT3f" );
       
  1309 __PLIT8(KClkGpio1_F,		"a.GPIO1f" );
       
  1310 __PLIT8(KClkGpio2_F,		"a.GPIO2f" );
       
  1311 __PLIT8(KClkGpio3_F,		"a.GPIO3f" );
       
  1312 __PLIT8(KClkGpio4_F,		"a.GPIO4f" );
       
  1313 __PLIT8(KClkGpio5_F,		"a.GPIO5f" );
       
  1314 __PLIT8(KClkGpio6_F,		"a.GPIO6f" );
       
  1315 __PLIT8(KClkUsb120_F,		"a.U120f" );
       
  1316 __PLIT8(KClkUsb48_F,		"a.U48f" );
       
  1317 __PLIT8(KClkDss_I,			"a.DSSi" );
       
  1318 __PLIT8(KClkCam_I,			"a.CAMi" );
       
  1319 __PLIT8(KClkIcr_I,			"a.ICRi" );
       
  1320 __PLIT8(KClkMmc1_I,			"a.MMC1i" );
       
  1321 __PLIT8(KClkMmc2_I,			"a.MMC2i" );
       
  1322 __PLIT8(KClkMmc3_I,			"a.MMC3i" );
       
  1323 __PLIT8(KClkMsPro_I,		"a.MSi" );
       
  1324 __PLIT8(KClkHdq_I,			"a.HDQi" );
       
  1325 __PLIT8(KClkAes1_I,			"a.AES1i" );
       
  1326 __PLIT8(KClkAes2_I,			"a.AES2i" );
       
  1327 __PLIT8(KClkSha11_I,		"a.SHA1i" );
       
  1328 __PLIT8(KClkSha12_I,		"a.SHA2i" );
       
  1329 __PLIT8(KClkDes1_I,			"a.DES1i" );
       
  1330 __PLIT8(KClkDes2_I,			"a.DES2i" );
       
  1331 __PLIT8(KClkMcBsp1_I,		"a.BSP1i" );
       
  1332 __PLIT8(KClkMcBsp2_I,		"a.BSP2i" );
       
  1333 __PLIT8(KClkMcBsp3_I,		"a.BSP3i" );
       
  1334 __PLIT8(KClkMcBsp4_I,		"a.BSP4i" );
       
  1335 __PLIT8(KClkMcBsp5_I,		"a.BSP5i" );
       
  1336 __PLIT8(KClkI2c1_I,			"a.I2C1i" );
       
  1337 __PLIT8(KClkI2c2_I,			"a.I2C2i" );
       
  1338 __PLIT8(KClkI2c3_I,			"a.I2C3i" );
       
  1339 __PLIT8(KClkUart1_I,		"a.UART1i" );
       
  1340 __PLIT8(KClkUart2_I,		"a.UART2i" );
       
  1341 __PLIT8(KClkUart3_I,		"a.UART3i" );
       
  1342 __PLIT8(KClkMcSpi1_I,		"a.SPI1i" );
       
  1343 __PLIT8(KClkMcSpi2_I,		"a.SPI2i" );
       
  1344 __PLIT8(KClkMcSpi3_I,		"a.SPI3i" );
       
  1345 __PLIT8(KClkMcSpi4_I,		"a.SPI4i" );
       
  1346 __PLIT8(KClkGpt1_I,			"a.GPT1i" );
       
  1347 __PLIT8(KClkGpt2_I,			"a.GPT2i" );
       
  1348 __PLIT8(KClkGpt3_I,			"a.GPT3i" );
       
  1349 __PLIT8(KClkGpt4_I,			"a.GPT4i" );
       
  1350 __PLIT8(KClkGpt5_I,			"a.GPT5i" );
       
  1351 __PLIT8(KClkGpt6_I,			"a.GPT6i" );
       
  1352 __PLIT8(KClkGpt7_I,			"a.GPT7i" );
       
  1353 __PLIT8(KClkGpt8_I,			"a.GPT8i" );
       
  1354 __PLIT8(KClkGpt9_I,			"a.GPT9i" );
       
  1355 __PLIT8(KClkGpt10_I,		"a.GPTAi" );
       
  1356 __PLIT8(KClkGpt11_I,		"a.GPTBi" );
       
  1357 __PLIT8(KClkGpt12_I,		"a.GPTCi" );
       
  1358 __PLIT8(KClkMailboxes_I,	"a.MBi" );
       
  1359 __PLIT8(KClkOmapSCM_I,		"a.SCMi" );
       
  1360 __PLIT8(KClkHsUsbOtg_I,		"a.OTGi" );
       
  1361 __PLIT8(KClkSdrc_I,			"a.SDRCi" );
       
  1362 __PLIT8(KClkPka_I,			"a.PKAi" );
       
  1363 __PLIT8(KClkRng_I,			"a.RNGi" );
       
  1364 __PLIT8(KClkUsbTll_I,		"a.TLLi" );
       
  1365 __PLIT8(KClkSgx_I,			"a.SGXi" );
       
  1366 __PLIT8(KClkUsim_I,			"a.USIMi" );
       
  1367 __PLIT8(KClkWdt1_I,			"a.WDT1i" );
       
  1368 __PLIT8(KClkWdt2_I,			"a.WDT2i" );
       
  1369 __PLIT8(KClkWdt3_I,			"a.WDT3i" );
       
  1370 __PLIT8(KClkGpio1_I,		"a.GPIO1i" );
       
  1371 __PLIT8(KClkGpio2_I,		"a.GPIO2i" );
       
  1372 __PLIT8(KClkGpio3_I,		"a.GPIO3i" );
       
  1373 __PLIT8(KClkGpio4_I,		"a.GPIO4i" );
       
  1374 __PLIT8(KClkGpio5_I,		"a.GPIO5i" );
       
  1375 __PLIT8(KClkGpio6_I,		"a.GPIO6i" );
       
  1376 __PLIT8(KClk32Sync_I,		"a.32SYNi" );
       
  1377 __PLIT8(KClkUsb_I,			"a.USBi" );
       
  1378 __PLIT8(KClk48M,			"a.48" );
       
  1379 __PLIT8(KClk12M,			"a.12" );
       
  1380 __PLIT8(KClkSysClk,			"a.SYSCLK" );
       
  1381 __PLIT8(KClkAltClk,			"a.ALTCLK" );
       
  1382 __PLIT8(KClkSysClk32k,		"a.SYS32K" );
       
  1383 
       
  1384 
       
  1385 // Table converting clock sources to string identifiers for PRM
       
  1386 static const TDesC8* const KNames[] =
       
  1387 	{
       
  1388 	(const TDesC8*)( &KClkMpu ),				// EClkMpu
       
  1389 	(const TDesC8*)( &KClkIva2Pll ),			// EClkIva2Pll
       
  1390 	(const TDesC8*)( &KClkCore ),				// EClkCore
       
  1391 	(const TDesC8*)( &KClkPeriph ),			// EClkPeriph
       
  1392 	(const TDesC8*)( &KClkPeriph2 ),			// EClkPeriph2
       
  1393 	(const TDesC8*)( &KClkPrcmInterface ),		// EClkPrcmInterface
       
  1394 	(const TDesC8*)( &KClkEmu ),				// EClkEmu
       
  1395 	(const TDesC8*)( &KClkNeon ),				// EClkNeon
       
  1396 	(const TDesC8*)( &KClkL3Domain ),			// EClkL3Domain
       
  1397 	(const TDesC8*)( &KClkL4Domain ),			// EClkL4Domain
       
  1398 	(const TDesC8*)( &KClkMpuPll_Bypass ),		// EClkMpuPll_Bypass
       
  1399 	(const TDesC8*)( &KClkIva2Pll_Bypass ),	// EClkIva2Pll_Bypass
       
  1400 	(const TDesC8*)( &KClkRM_F ),				// EClkRM_F
       
  1401 	(const TDesC8*)( &KClk96M ),				// EClk96M
       
  1402 	(const TDesC8*)( &KClk120M ),				// EClk120M
       
  1403 	(const TDesC8*)( &KClkSysOut ),			// EClkSysOut
       
  1404 	(const TDesC8*)( &KClkTv_F ),				// EClkTv_F
       
  1405 	(const TDesC8*)( &KClkDss1_F ),			// EClkDss1_F
       
  1406 	(const TDesC8*)( &KClkDss2_F ),			// EClkDss2_F
       
  1407 	(const TDesC8*)( &KClkCsi2_F ),			// EClkCsi2_F
       
  1408 	(const TDesC8*)( &KClkCam_F ),				// EClkCam_F
       
  1409 	(const TDesC8*)( &KClkIva2_F ),			// EClkIva2_F
       
  1410 	(const TDesC8*)( &KClkMmc1_F ),			// EClkMmc1_F
       
  1411 	(const TDesC8*)( &KClkMmc2_F ),			// EClkMmc2_F
       
  1412 	(const TDesC8*)( &KClkMmc3_F ),			// EClkMmc3_F
       
  1413 	(const TDesC8*)( &KClkMsPro_F ),			// EClkMsPro_F
       
  1414 	(const TDesC8*)( &KClkHdq_F ),				// EClkHdq_F
       
  1415 	(const TDesC8*)( &KClkMcBsp1_F ),			// EClkMcBsp1_F
       
  1416 	(const TDesC8*)( &KClkMcBsp2_F ),			// EClkMcBsp2_F
       
  1417 	(const TDesC8*)( &KClkMcBsp3_F ),			// EClkMcBsp3_F
       
  1418 	(const TDesC8*)( &KClkMcBsp4_F ),			// EClkMcBsp4_F
       
  1419 	(const TDesC8*)( &KClkMcBsp5_F ),			// EClkMcBsp5_F
       
  1420 	(const TDesC8*)( &KClkMcSpi1_F ),			// EClkMcSpi1_F
       
  1421 	(const TDesC8*)( &KClkMcSpi2_F ),			// EClkMcSpi2_F
       
  1422 	(const TDesC8*)( &KClkMcSpi3_F ),			// EClkMcSpi3_F
       
  1423 	(const TDesC8*)( &KClkMcSpi4_F ),			// EClkMcSpi4_F
       
  1424 	(const TDesC8*)( &KClkI2c1_F ),			// EClkI2c1_F
       
  1425 	(const TDesC8*)( &KClkI2c2_F ),			// EClkI2c2_F
       
  1426 	(const TDesC8*)( &KClkI2c3_F ),			// EClkI2c3_F
       
  1427 	(const TDesC8*)( &KClkUart1_F ),			// EClkUart1_F
       
  1428 	(const TDesC8*)( &KClkUart2_F ),			// EClkUart2_F
       
  1429 	(const TDesC8*)( &KClkUart3_F ),			// EClkUart3_F
       
  1430 	(const TDesC8*)( &KClkGpt1_F ),			// EClkGpt1_F
       
  1431 	(const TDesC8*)( &KClkGpt2_F ),			// EClkGpt2_F
       
  1432 	(const TDesC8*)( &KClkGpt3_F ),			// EClkGpt3_F
       
  1433 	(const TDesC8*)( &KClkGpt4_F ),			// EClkGpt4_F
       
  1434 	(const TDesC8*)( &KClkGpt5_F ),			// EClkGpt5_F
       
  1435 	(const TDesC8*)( &KClkGpt6_F ),			// EClkGpt6_F
       
  1436 	(const TDesC8*)( &KClkGpt7_F ),			// EClkGpt7_F
       
  1437 	(const TDesC8*)( &KClkGpt8_F ),			// EClkGpt8_F
       
  1438 	(const TDesC8*)( &KClkGpt9_F ),			// EClkGpt9_F
       
  1439 	(const TDesC8*)( &KClkGpt10_F ),			// EClkGpt10_F
       
  1440 	(const TDesC8*)( &KClkGpt11_F ),			// EClkGpt11_F
       
  1441 	(const TDesC8*)( &KClkUsbTll_F ),			// EClkUsbTll_F
       
  1442 	(const TDesC8*)( &KClkTs_F ),				// EClkTs_F
       
  1443 	(const TDesC8*)( &KClkCpeFuse_F ),			// EClkCpeFuse_F
       
  1444 	(const TDesC8*)( &KClkSgx_F ),				// EClkSgx_F
       
  1445 	(const TDesC8*)( &KClkUsim_F ),			// EClkUsim_F
       
  1446 	(const TDesC8*)( &KClkSmartReflex2_F ),	// EClkSmartReflex2_F
       
  1447 	(const TDesC8*)( &KClkSmartReflex1_F ),	// EClkSmartReflex1_F
       
  1448 	(const TDesC8*)( &KClkWdt2_F ),			// EClkWdt2_F
       
  1449 	(const TDesC8*)( &KClkWdt3_F ),			// EClkWdt3_F
       
  1450 	(const TDesC8*)( &KClkGpio1_F ),			// EClkGpio1_F
       
  1451 	(const TDesC8*)( &KClkGpio2_F ),			// EClkGpio2_F
       
  1452 	(const TDesC8*)( &KClkGpio3_F ),			// EClkGpio3_F
       
  1453 	(const TDesC8*)( &KClkGpio4_F ),			// EClkGpio4_F
       
  1454 	(const TDesC8*)( &KClkGpio5_F ),			// EClkGpio5_F
       
  1455 	(const TDesC8*)( &KClkGpio6_F ),			// EClkGpio6_F
       
  1456 	(const TDesC8*)( &KClkUsb120_F ),			// EClkUsb120_F
       
  1457 	(const TDesC8*)( &KClkUsb48_F ),			// EClkUsb48_F
       
  1458 	(const TDesC8*)( &KClkDss_I ),				// EClkDss_I
       
  1459 	(const TDesC8*)( &KClkCam_I ),				// EClkCam_I
       
  1460 	(const TDesC8*)( &KClkIcr_I ),				// EClkIcr_I
       
  1461 	(const TDesC8*)( &KClkMmc1_I ),			// EClkMmc1_I
       
  1462 	(const TDesC8*)( &KClkMmc2_I ),			// EClkMmc2_I
       
  1463 	(const TDesC8*)( &KClkMmc3_I ),			// EClkMmc3_I
       
  1464 	(const TDesC8*)( &KClkMsPro_I ),			// EClkMsPro_I
       
  1465 	(const TDesC8*)( &KClkHdq_I ),				// EClkHdq_I
       
  1466 	(const TDesC8*)( &KClkAes1_I ),			// EClkAes1_I
       
  1467 	(const TDesC8*)( &KClkAes2_I ),			// EClkAes2_I
       
  1468 	(const TDesC8*)( &KClkSha11_I ),			// EClkSha11_I
       
  1469 	(const TDesC8*)( &KClkSha12_I ),			// EClkSha12_I
       
  1470 	(const TDesC8*)( &KClkDes1_I ),			// EClkDes1_I
       
  1471 	(const TDesC8*)( &KClkDes2_I ),			// EClkDes2_I
       
  1472 	(const TDesC8*)( &KClkMcBsp1_I ),			// EClkMcBsp1_I
       
  1473 	(const TDesC8*)( &KClkMcBsp2_I ),			// EClkMcBsp2_I
       
  1474 	(const TDesC8*)( &KClkMcBsp3_I ),			// EClkMcBsp3_I
       
  1475 	(const TDesC8*)( &KClkMcBsp4_I ),			// EClkMcBsp4_I
       
  1476 	(const TDesC8*)( &KClkMcBsp5_I ),			// EClkMcBsp5_I
       
  1477 	(const TDesC8*)( &KClkI2c1_I ),			// EClkI2c1_I
       
  1478 	(const TDesC8*)( &KClkI2c2_I ),			// EClkI2c2_I
       
  1479 	(const TDesC8*)( &KClkI2c3_I ),			// EClkI2c3_I
       
  1480 	(const TDesC8*)( &KClkUart1_I ),			// EClkUart1_I
       
  1481 	(const TDesC8*)( &KClkUart2_I ),			// EClkUart2_I
       
  1482 	(const TDesC8*)( &KClkUart3_I ),			// EClkUart3_I
       
  1483 	(const TDesC8*)( &KClkMcSpi1_I ),			// EClkMcSpi1_I
       
  1484 	(const TDesC8*)( &KClkMcSpi2_I ),			// EClkMcSpi2_I
       
  1485 	(const TDesC8*)( &KClkMcSpi3_I ),			// EClkMcSpi3_I
       
  1486 	(const TDesC8*)( &KClkMcSpi4_I ),			// EClkMcSpi4_I
       
  1487 	(const TDesC8*)( &KClkGpt1_I ),			// EClkGpt1_I
       
  1488 	(const TDesC8*)( &KClkGpt2_I ),			// EClkGpt2_I
       
  1489 	(const TDesC8*)( &KClkGpt3_I ),			// EClkGpt3_I
       
  1490 	(const TDesC8*)( &KClkGpt4_I ),			// EClkGpt4_I
       
  1491 	(const TDesC8*)( &KClkGpt5_I ),			// EClkGpt5_I
       
  1492 	(const TDesC8*)( &KClkGpt6_I ),			// EClkGpt6_I
       
  1493 	(const TDesC8*)( &KClkGpt7_I ),			// EClkGpt7_I
       
  1494 	(const TDesC8*)( &KClkGpt8_I ),			// EClkGpt8_I
       
  1495 	(const TDesC8*)( &KClkGpt9_I ),			// EClkGpt9_I
       
  1496 	(const TDesC8*)( &KClkGpt10_I ),			// EClkGpt10_I
       
  1497 	(const TDesC8*)( &KClkGpt11_I ),			// EClkGpt11_I
       
  1498 	(const TDesC8*)( &KClkGpt12_I ),			// EClkGpt12_I
       
  1499 	(const TDesC8*)( &KClkMailboxes_I ),		// EClkMailboxes_I
       
  1500 	(const TDesC8*)( &KClkOmapSCM_I ),			// EClkOmapSCM_I
       
  1501 	(const TDesC8*)( &KClkHsUsbOtg_I ),		// EClkHsUsbOtg_I
       
  1502 	(const TDesC8*)( &KClkSdrc_I ),			// EClkSdrc_I
       
  1503 	(const TDesC8*)( &KClkPka_I ),				// EClkPka_I
       
  1504 	(const TDesC8*)( &KClkRng_I ),				// EClkRng_I
       
  1505 	(const TDesC8*)( &KClkUsbTll_I ),			// EClkUsbTll_I
       
  1506 	(const TDesC8*)( &KClkSgx_I ),				// EClkSgx_I
       
  1507 	(const TDesC8*)( &KClkUsim_I ),			// EClkUsim_I
       
  1508 	(const TDesC8*)( &KClkWdt1_I ),			// EClkWdt1_I
       
  1509 	(const TDesC8*)( &KClkWdt2_I ),			// EClkWdt2_I
       
  1510 	(const TDesC8*)( &KClkWdt3_I ),			// EClkWdt3_I
       
  1511 	(const TDesC8*)( &KClkGpio1_I ),			// EClkGpio1_I
       
  1512 	(const TDesC8*)( &KClkGpio2_I ),			// EClkGpio2_I
       
  1513 	(const TDesC8*)( &KClkGpio3_I ),			// EClkGpio3_I
       
  1514 	(const TDesC8*)( &KClkGpio4_I ),			// EClkGpio4_I
       
  1515 	(const TDesC8*)( &KClkGpio5_I ),			// EClkGpio5_I
       
  1516 	(const TDesC8*)( &KClkGpio6_I ),			// EClkGpio6_I
       
  1517 	(const TDesC8*)( &KClk32Sync_I ),			// EClk32Sync_I
       
  1518 	(const TDesC8*)( &KClkUsb_I ),				// EClkUsb_I
       
  1519 	(const TDesC8*)( &KClk48M ),				// EClk48M
       
  1520 	(const TDesC8*)( &KClk12M ),				// EClk12M
       
  1521 	(const TDesC8*)( &KClkSysClk ),				// EClkSysClk
       
  1522 	(const TDesC8*)( &KClkAltClk ),				// EClkAltClk
       
  1523 	(const TDesC8*)( &KClkSysClk32k ),			// EClkSysClk32k
       
  1524 	};
       
  1525 
       
  1526 }
       
  1527 __ASSERT_COMPILE( (sizeof( KNames ) / sizeof( KNames[0] )) == Prcm::KSupportedClockCount );
       
  1528 
       
  1529 namespace Prcm
       
  1530 {
       
  1531 TSpinLock iLock(/*TSpinLock::EOrderGenericIrqLow0*/); // prevents concurrent access to the prcm hardware registers
       
  1532 
       
  1533 void Panic( TPanic aPanic )
       
  1534 	{
       
  1535 	Kern::Fault( "PRCM", aPanic );
       
  1536 	}
       
  1537 
       
  1538 void InternalPanic( TInt aLine )
       
  1539 	{
       
  1540 	Kern::Fault( "PRCMINT", aLine );
       
  1541 	}
       
  1542 
       
  1543 FORCE_INLINE void _BitClearSet( TUint32 aRegister, TUint32 aClearMask, TUint32 aSetMask )
       
  1544 	{
       
  1545 	volatile TUint32* pR = (volatile TUint32*)aRegister;
       
  1546 	*pR = (*pR & ~aClearMask) | aSetMask;
       
  1547 	}
       
  1548 
       
  1549 FORCE_INLINE void _LockedBitClearSet( TUint32 aRegister, TUint32 aClearMask, TUint32 aSetMask )
       
  1550 	{
       
  1551 	volatile TUint32* pR = (volatile TUint32*)aRegister;
       
  1552 	TInt irq = __SPIN_LOCK_IRQSAVE(iLock);
       
  1553 	*pR = (*pR & ~aClearMask) | aSetMask;
       
  1554 	__SPIN_UNLOCK_IRQRESTORE(iLock, irq);
       
  1555 	}
       
  1556 
       
  1557 
       
  1558 EXPORT_C void SetPllConfig( TPll aPll, const TPllConfiguration& aConfig  )
       
  1559 	{
       
  1560 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetPllConfig(%x)", aPll ) );
       
  1561 
       
  1562 	__ASSERT_DEBUG( (TUint)aPll < KSupportedPllCount, Panic( ESetPllConfigBadPll ) );
       
  1563 
       
  1564 	const TPllControlInfo& inf = KPllControlInfo[ aPll ];
       
  1565 
       
  1566 	__ASSERT_DEBUG( aConfig.iDivider <= KPllMaximumDivider,		Panic( ESetPllConfigBadDivider ) );
       
  1567 	__ASSERT_DEBUG( aConfig.iMultiplier <= KPllMaximumMultiplier,	Panic( ESetPllConfigBadMultiplier ) );
       
  1568 	__ASSERT_DEBUG( ((TUint)aConfig.iFreqRange <= EPllRange_1750_2100)
       
  1569 				&&  ((TUint)aConfig.iFreqRange >= EPllRange_075_100),	Panic( ESetPllConfigBadFreqRange ) );
       
  1570 	__ASSERT_DEBUG( ((TUint)aConfig.iRamp <= EPllRamp40us),	Panic( ESetPllConfigBadRamp ) );
       
  1571 	__ASSERT_DEBUG( (TUint)aConfig.iDrift <= EPllDriftGuardEnabled,	Panic( ESetPllConfigBadDrift ) );
       
  1572 
       
  1573 	TUint	mult = (aConfig.iMultiplier bitand KPllMultiplierMask) << inf.iMultShift;
       
  1574 	TUint	div = ((aConfig.iDivider - 1) bitand KPllDividerMask) << inf.iDivShift;
       
  1575 	TUint	range = (aConfig.iFreqRange bitand KPllFreqRangeMask) << inf.iFreqSelShift;
       
  1576 	TUint	ramp = (aConfig.iRamp bitand KPllRampMask) << inf.iRampShift;
       
  1577 	TUint	drift = (aConfig.iDrift == EPllDriftGuardEnabled) ? (1 << inf.iDriftShift) : 0;
       
  1578 
       
  1579 	TInt irq = __SPIN_LOCK_IRQSAVE(iLock);
       
  1580 	// We must apply frequency range setting before new multuplier and divider
       
  1581 	TUint clearMaskConfig =			(KPllFreqRangeMask << inf.iFreqSelShift)
       
  1582 							bitor	(KPllRampMask << inf.iRampShift)
       
  1583 							bitor	(1 << inf.iDriftShift);
       
  1584 	_BitClearSet( inf.iConfigRegister, clearMaskConfig, range | ramp | drift );
       
  1585 
       
  1586 	TUint clearMaskMulDiv =	(KPllMultiplierMask << inf.iMultShift) bitor (KPllDividerMask << inf.iDivShift);
       
  1587 	_BitClearSet( inf.iMulDivRegister, clearMaskMulDiv, mult | div );
       
  1588 	__SPIN_UNLOCK_IRQRESTORE(iLock, irq);
       
  1589 	}
       
  1590 
       
  1591 EXPORT_C void PllConfig( TPll aPll, TPllConfiguration& aConfigResult )
       
  1592 	{
       
  1593 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PllConfig(%x)", aPll ) );
       
  1594 
       
  1595 	__ASSERT_DEBUG( (TUint)aPll < KSupportedPllCount, Panic( EGetPllConfigBadPll ) );
       
  1596 
       
  1597 	const TPllControlInfo& inf = KPllControlInfo[ aPll ];
       
  1598 
       
  1599 	TUint32 config = AsspRegister::Read32( inf.iConfigRegister );
       
  1600 	TUint32 muldiv = AsspRegister::Read32( inf.iMulDivRegister );
       
  1601 
       
  1602 	aConfigResult.iMultiplier =	(muldiv >> inf.iMultShift) bitand KPllMultiplierMask;
       
  1603 	aConfigResult.iDivider =	1 + ((muldiv >> inf.iDivShift) bitand KPllDividerMask);
       
  1604 	aConfigResult.iFreqRange =	static_cast<TPllFrequencyRange>((config >> inf.iFreqSelShift) bitand KPllFreqRangeMask);
       
  1605 	aConfigResult.iRamp =		static_cast<TPllRamp>((config >> inf.iRampShift ) bitand KPllRampMask);
       
  1606 	aConfigResult.iDrift =		(config >> inf.iDriftShift ) bitand 1 ? EPllDriftGuardEnabled : EPllDriftGuardDisabled;
       
  1607 
       
  1608 	__KTRACE_OPT( KPRCM, Kern::Printf( "DPLL%d: m=%d, d=%d, fr=%d, r=%d, dr=%d",
       
  1609 						aPll + 1,
       
  1610 						aConfigResult.iMultiplier,
       
  1611 						aConfigResult.iDivider,
       
  1612 						aConfigResult.iFreqRange,
       
  1613 						aConfigResult.iRamp,
       
  1614 						aConfigResult.iDrift ) );
       
  1615 	}
       
  1616 
       
  1617 EXPORT_C void SetPllLp( TPll aPll, TLpMode aLpMode )
       
  1618 	{
       
  1619 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetPllLp(%x)", aPll ) );
       
  1620 
       
  1621 	__ASSERT_DEBUG( (TUint)aPll < KSupportedPllCount, Panic( ESetPllLpBadPll ) );
       
  1622 	__ASSERT_DEBUG( (aLpMode == ENormalMode)
       
  1623 					|| (aLpMode == ELpMode), Panic( ESetPllLpBadMode ) );
       
  1624 
       
  1625 	const TPllControlInfo& inf = KPllControlInfo[ aPll ];
       
  1626 
       
  1627 	TUint32 clear = 1 << inf.iLpShift;
       
  1628 	TUint32 set = 0;
       
  1629 
       
  1630 	if( ELpMode == aLpMode )
       
  1631 		{
       
  1632 		set = clear;
       
  1633 		clear = 0;
       
  1634 		}
       
  1635 
       
  1636 	_LockedBitClearSet( inf.iConfigRegister, clear, set );
       
  1637 	}
       
  1638 
       
  1639 EXPORT_C TLpMode PllLp( TPll aPll )
       
  1640 	{
       
  1641 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PllLp(%x)", aPll ) );
       
  1642 
       
  1643 	__ASSERT_DEBUG( (TUint)aPll < KSupportedPllCount, Panic( EGetPllLpBadPll ) );
       
  1644 
       
  1645 	const TPllControlInfo& inf = KPllControlInfo[ aPll ];
       
  1646 
       
  1647 	TUint32 config = AsspRegister::Read32( inf.iConfigRegister );
       
  1648 	if( 0 == ((config >> inf.iLpShift) bitand 1) )
       
  1649 		{
       
  1650 		return ENormalMode;
       
  1651 		}
       
  1652 	else
       
  1653 		{
       
  1654 		return ELpMode;
       
  1655 		}
       
  1656 	}
       
  1657 
       
  1658 
       
  1659 EXPORT_C void SetPllMode( TPll aPll, TPllMode aPllMode )
       
  1660 	{
       
  1661 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetPllMode(%x;%x)", aPll, aPllMode ) );
       
  1662 	__ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( ESetPllModeBadClock ) );
       
  1663 
       
  1664 	TUint32 newMode;
       
  1665 	TUint32 newAuto = KPllAutoOff;
       
  1666 
       
  1667 	switch( aPllMode )
       
  1668 		{
       
  1669 		default:
       
  1670 			__DEBUG_ONLY( Panic( ESetPllModeBadMode ) );
       
  1671 			return;
       
  1672 
       
  1673 		case EPllStop:
       
  1674 			newMode = KPllModeStop;
       
  1675 			break;
       
  1676 
       
  1677 		case EPllBypass:
       
  1678 			newMode = KPllModeBypass;
       
  1679 			break;
       
  1680 
       
  1681 		case EPllAuto:
       
  1682 			newAuto = KPllAutoOn;
       
  1683 			// fall through...
       
  1684 
       
  1685 		case EPllRun:
       
  1686 			newMode = KPllModeLock;
       
  1687 			break;
       
  1688 
       
  1689 		case EPllFastRelock:
       
  1690 			newMode = KPllModeFastRelock;
       
  1691 			break;
       
  1692 		}
       
  1693 
       
  1694 	TInt irq = __SPIN_LOCK_IRQSAVE(iLock);
       
  1695 	
       
  1696 	_BitClearSet(	KPllMode[ aPll ].iModeRegister,
       
  1697 					KPllModeMask << KPllMode[ aPll ].iModeShift,
       
  1698 					newMode << KPllMode[ aPll ].iModeShift );
       
  1699 
       
  1700 	_BitClearSet(	KPllMode[ aPll ].iAutoRegister,
       
  1701 					KPllAutoMask << KPllMode[ aPll ].iAutoShift,
       
  1702 					newAuto << KPllMode[ aPll ].iAutoShift );
       
  1703 	
       
  1704 	__SPIN_UNLOCK_IRQRESTORE(iLock, irq);
       
  1705 	}
       
  1706 
       
  1707 
       
  1708 EXPORT_C TPllMode PllMode( TPll aPll )
       
  1709 	{
       
  1710 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PllMode(%x)", aPll ) );
       
  1711 	__ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( ESetPllModeBadClock ) );
       
  1712 
       
  1713 	TUint32 mode = (AsspRegister::Read32( KPllMode[ aPll ].iModeRegister ) >> KPllMode[ aPll ].iModeShift) bitand KPllModeMask;
       
  1714 	TUint32 autoSet = (AsspRegister::Read32( KPllMode[ aPll ].iAutoRegister ) >> KPllMode[ aPll ].iAutoShift) bitand KPllAutoMask;
       
  1715 
       
  1716 	static const TPllMode modeTable[8][2] = 
       
  1717 		{	// auto disabled	auto enabled
       
  1718 			{ EPllStop,			EPllStop },	// not possible
       
  1719 			{ EPllStop,			EPllStop },
       
  1720 			{ EPllStop,			EPllStop },	// not possible
       
  1721 			{ EPllStop,			EPllStop },	// not possible
       
  1722 			{ EPllStop,			EPllStop },	// not possible
       
  1723 			{ EPllBypass,		EPllBypass },
       
  1724 			{ EPllFastRelock,	EPllAuto },
       
  1725 			{ EPllRun,			EPllAuto },
       
  1726 		};
       
  1727 	return modeTable[ mode ][ (KPllAutoOff == autoSet) ? 0 : 1 ];
       
  1728 	}
       
  1729 
       
  1730 EXPORT_C void CalcPllFrequencyRange( TPll aPll, TPllConfiguration& aConfig )
       
  1731 	{
       
  1732 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::CalcPllFrequencyRange(%x)", aPll ) );
       
  1733 
       
  1734 	struct TFreqSelRange
       
  1735 		{
       
  1736 		TUint	iMin;
       
  1737 		TUint	iMax;
       
  1738 		TPllFrequencyRange	iSetting;
       
  1739 		};
       
  1740 
       
  1741 	const TFreqSelRange KRanges[] =
       
  1742 		{
       
  1743 			{ 750000,	1000000,	EPllRange_075_100 },
       
  1744 			{ 1000001,	1250000,	EPllRange_100_125 },
       
  1745 			{ 1250001,	1500000,	EPllRange_125_150 },
       
  1746 			{ 1500001,	1750000,	EPllRange_150_175 },
       
  1747 			{ 1750001,	2100000,	EPllRange_175_210 },
       
  1748 			{ 7500000,	10000000,	EPllRange_750_1000 },
       
  1749 			{ 10000001,	12500000,	EPllRange_1000_1250 },
       
  1750 			{ 12500001,	15000000,	EPllRange_1250_1500 },
       
  1751 			{ 15000001,	17500000,	EPllRange_1500_1750 },
       
  1752 			{ 17500001,	21000000,	EPllRange_1750_2100 },
       
  1753 			{ 0,		0,			EPllRange_1750_2100	}
       
  1754 		};
       
  1755 
       
  1756 	// We have to work out the internal frequency from the source clock frequency and the
       
  1757 	// divider factor N
       
  1758 
       
  1759 	const TUint32 divider =	aConfig.iDivider;
       
  1760 
       
  1761 	TInt found = -1;
       
  1762 
       
  1763 	if( divider > 0 )
       
  1764 		{
       
  1765 		TUint fInternal = ClockFrequency( EClkSysClk ) / divider;
       
  1766 
       
  1767 		// Find an appropriate range
       
  1768 		for( TInt i = 0; KRanges[i].iMax > 0; ++i )
       
  1769 			{
       
  1770 			if( fInternal < KRanges[i].iMin )
       
  1771 				{
       
  1772 				// We've passed all possible ranges, work out whether current or previous is nearest
       
  1773 				__DEBUG_ONLY( Panic( EPllInternalFrequencyOutOfRange ) );
       
  1774 
       
  1775 				if( i > 0 )
       
  1776 					{
       
  1777 					// How near are we to minimum of current range?
       
  1778 					TUint currentDiff = KRanges[i].iMin - fInternal;
       
  1779 
       
  1780 					// How near are we to maximum of previous range?
       
  1781 					TUint prevDiff = fInternal - KRanges[i - 1].iMax;
       
  1782 
       
  1783 					found = (prevDiff < currentDiff) ? i - 1 : i;
       
  1784 					}
       
  1785 				else
       
  1786 					{
       
  1787 					// it's below minimum, so use minimum range
       
  1788 					found = 0;
       
  1789 					}
       
  1790 				break;
       
  1791 				}
       
  1792 			else if( (KRanges[i].iMin <= fInternal) && (KRanges[i].iMax >= fInternal) )
       
  1793 				{
       
  1794 				found = i;
       
  1795 				break;
       
  1796 				}
       
  1797 			}
       
  1798 
       
  1799 		}
       
  1800 	// If we've fallen off end of list, use maximum setting
       
  1801 	__ASSERT_DEBUG( found >= 0, Panic( EPllInternalFrequencyOutOfRange ) );
       
  1802 	aConfig.iFreqRange = (found >= 0) ? KRanges[ found ].iSetting : EPllRange_1750_2100;
       
  1803 	}
       
  1804 
       
  1805 
       
  1806 EXPORT_C void AutoSetPllLpMode( TPll aPll )
       
  1807 	{
       
  1808 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PllMode(%x)", aPll ) );
       
  1809 	__ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( ESetPllModeBadClock ) );
       
  1810 
       
  1811 	const TUint32 reg = KPllControlInfo[ aPll ].iConfigRegister;
       
  1812 	const TUint shift = KPllControlInfo[ aPll ].iLpShift;
       
  1813 
       
  1814 	TUint freq = ClockFrequency( KPllToClock[ aPll ] );
       
  1815 	TUint32 clear = 1 << shift;
       
  1816 	TUint32 set = 0;
       
  1817 	if( freq <= KPllLpModeMaximumFrequency )
       
  1818 		{
       
  1819 		// LP mode can be enabled
       
  1820 		set = clear;
       
  1821 		clear = 0;
       
  1822 		}
       
  1823 	_LockedBitClearSet( reg, clear, set );
       
  1824 	}
       
  1825 
       
  1826 EXPORT_C TBool PllIsLocked( TPll aPll )
       
  1827 	{
       
  1828 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PllIsLocked(%x)", aPll ) );
       
  1829 	__ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( EPllIsLockedBadPll ) );
       
  1830 
       
  1831 	TUint32 reg = KPllControlInfo[ aPll ].iStatusRegister;
       
  1832 	TUint32 lockMask = 1 << KPllControlInfo[ aPll ].iLockBit;
       
  1833 
       
  1834 	return ( 0 != (AsspRegister::Read32( reg ) bitand lockMask) );
       
  1835 	}
       
  1836 
       
  1837 EXPORT_C void WaitForPllLock( TPll aPll )
       
  1838 	{
       
  1839 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::WaitForPllLock(%x)", aPll ) );
       
  1840 	__ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( EWaitForPllLockBadPll ) );
       
  1841 
       
  1842 	TUint32 reg = KPllControlInfo[ aPll ].iStatusRegister;
       
  1843 	TUint32 lockMask = 1 << KPllControlInfo[ aPll ].iLockBit;
       
  1844 
       
  1845 	while( 0 == (AsspRegister::Read32( reg ) bitand lockMask) );
       
  1846 	}
       
  1847 
       
  1848 EXPORT_C void SetPllBypassDivider( TPll aPll, TBypassDivider aDivider )
       
  1849 	{
       
  1850 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetPllBypassDivider(%x;%x)", aPll, aDivider ) );
       
  1851 	__ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( ESetPllBypassDividerBadPll ) );
       
  1852 	__ASSERT_DEBUG( (TUint)aDivider <= EBypassDiv4, Panic( ESetPllBypassDividerBadDivider ) );
       
  1853 
       
  1854 	static const TUint8 KLookupTable[] =
       
  1855 		{
       
  1856 		1,	// EBypassDiv1
       
  1857 		2,	// EBypassDiv2
       
  1858 		4.	// EBypassDiv4
       
  1859 		};
       
  1860 
       
  1861 	TUint32 div = KLookupTable[ aDivider ];
       
  1862 
       
  1863 	switch( aPll )
       
  1864 		{
       
  1865 		case EDpll1:
       
  1866 			_LockedBitClearSet( KCM_CLKSEL1_PLL_MPU, KBit19 | KBit20 | KBit21, div << 19 );
       
  1867 			break;
       
  1868 
       
  1869 		case EDpll2:
       
  1870 			_LockedBitClearSet( KCM_CLKSEL1_PLL_IVA2, KBit19 | KBit20 | KBit21, div << 19 );
       
  1871 			break;
       
  1872 
       
  1873 		default:
       
  1874 			break;
       
  1875 		}
       
  1876 	}
       
  1877 
       
  1878 EXPORT_C TBypassDivider PllBypassDivider( TPll aPll )
       
  1879 	{
       
  1880 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PllBypassDivider(%x)", aPll ) );
       
  1881 	__ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( EPllBypassDividerBadPll ) );
       
  1882 	
       
  1883 	TUint div = 1;
       
  1884 
       
  1885 	switch( aPll )
       
  1886 		{
       
  1887 		case EDpll1:
       
  1888 			div = (AsspRegister::Read32( KCM_CLKSEL1_PLL_MPU ) >> 19) bitand 0x7;
       
  1889 			break;
       
  1890 
       
  1891 		case EDpll2:
       
  1892 			div = (AsspRegister::Read32( KCM_CLKSEL1_PLL_IVA2 ) >> 19) bitand 0x7;
       
  1893 			break;
       
  1894 
       
  1895 		default:
       
  1896 			break;
       
  1897 		}
       
  1898 
       
  1899 	TBypassDivider result = EBypassDiv1;
       
  1900 
       
  1901 	if( 2 == div )
       
  1902 		{
       
  1903 		result = EBypassDiv2;
       
  1904 		}
       
  1905 	else if( 4 == div )
       
  1906 		{
       
  1907 		result = EBypassDiv4;
       
  1908 		}
       
  1909 
       
  1910 	return result;
       
  1911 	}
       
  1912 
       
  1913 EXPORT_C void SetDivider( TClock aClock, TUint aDivide )
       
  1914 	{
       
  1915 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetDivider(%x;%x)", aClock, aDivide ) );
       
  1916 
       
  1917 	__ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( ESetDividerBadClock ) );
       
  1918 
       
  1919 	const TDividerInfo&	inf = KDividerInfo[ aClock ];
       
  1920 	
       
  1921 	TUint32 div = aDivide;	// most common case, special cases handled below
       
  1922 
       
  1923 	switch( inf.iDivType )
       
  1924 		{
       
  1925 		case EDivUsimClk:
       
  1926 			// Special case, not suppored by this function - use SetUsimClockDivider()
       
  1927 			return;
       
  1928 
       
  1929 		default:
       
  1930 		case EDivNotSupported:
       
  1931 			Panic( ESetDividerUnsupportedClock );
       
  1932 			return;
       
  1933 
       
  1934 		case EDiv_1_2:
       
  1935 			if( (1 != aDivide ) && (2 != aDivide ) )
       
  1936 				{
       
  1937 				__DEBUG_ONLY( Panic( ESetDividerBadDivider ) );
       
  1938 				return;
       
  1939 				}
       
  1940 			break;
       
  1941 
       
  1942 		case EDivCore_1_2_4:
       
  1943 			if( (1 != aDivide ) && (2 != aDivide ) && (3 != aDivide) )
       
  1944 				{
       
  1945 				__DEBUG_ONLY( Panic( ESetDividerBadDivider ) );
       
  1946 				return;
       
  1947 				}
       
  1948 			break;
       
  1949 
       
  1950 		case EDivCore_3_4_6_96M:
       
  1951 			{
       
  1952 			switch( aDivide )
       
  1953 				{
       
  1954 				default:
       
  1955 					__DEBUG_ONLY( Panic( ESetDividerBadDivider ) );
       
  1956 					return;
       
  1957 
       
  1958 				case 3:
       
  1959 					div = 0;
       
  1960 					break;
       
  1961 
       
  1962 				case 4:
       
  1963 					div = 1;
       
  1964 					break;
       
  1965 
       
  1966 				case 6:
       
  1967 					div = 2;
       
  1968 					break;
       
  1969 
       
  1970 				case 0:
       
  1971 					// Special-case, use 96MHz clock
       
  1972 					div = 3;
       
  1973 					break;
       
  1974 				}
       
  1975 			break;
       
  1976 			}
       
  1977 
       
  1978 		case EDivPll_1_To_16:
       
  1979 			if( (aDivide < 1) || (aDivide > 16) )
       
  1980 				{
       
  1981 				__DEBUG_ONLY( Panic( ESetDividerBadDivider ) );
       
  1982 				return;
       
  1983 				}
       
  1984 			break;
       
  1985 
       
  1986 		case EDivPll_1_To_31:
       
  1987 			if( (aDivide < 1) || (aDivide > 16) )
       
  1988 				{
       
  1989 				__DEBUG_ONLY( Panic( ESetDividerBadDivider ) );
       
  1990 				return;
       
  1991 				}
       
  1992 			break;
       
  1993 
       
  1994 
       
  1995 
       
  1996 		case EDivClkOut_1_2_4_8_16:
       
  1997 			{
       
  1998 			switch( aDivide )
       
  1999 				{
       
  2000 				default:
       
  2001 					__DEBUG_ONLY( Panic( ESetDividerBadDivider ) );
       
  2002 					return;
       
  2003 
       
  2004 				case 1:
       
  2005 					div = 0;
       
  2006 					break;
       
  2007 
       
  2008 				case 2:
       
  2009 					div = 1;
       
  2010 					break;
       
  2011 
       
  2012 				case 4:
       
  2013 					div = 2;
       
  2014 					break;
       
  2015 
       
  2016 				case 8:
       
  2017 					div = 3;
       
  2018 					break;
       
  2019 
       
  2020 				case 16:
       
  2021 					div = 4;
       
  2022 					break;
       
  2023 				}
       
  2024 			break;
       
  2025 			}
       
  2026 		}
       
  2027 
       
  2028 	// if we get here, we have a valid divider value
       
  2029 	
       
  2030 	_LockedBitClearSet( inf.iRegister, inf.iMask, div << inf.iShift );
       
  2031 	}
       
  2032 
       
  2033 EXPORT_C TUint Divider( TClock aClock )
       
  2034 	{
       
  2035 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::Divider(%x)", aClock ) );
       
  2036 
       
  2037 	__ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( EGetDividerBadClock ) );
       
  2038 
       
  2039 	const TDividerInfo&	inf = KDividerInfo[ aClock ];
       
  2040 	
       
  2041 	TUint32 div = ( AsspRegister::Read32( inf.iRegister ) bitand inf.iMask ) >> inf.iShift;
       
  2042 	TUint result = div;	// most common case
       
  2043 
       
  2044 	switch( inf.iDivType )
       
  2045 		{
       
  2046 		case EDivUsimClk:
       
  2047 			return UsimDivider();
       
  2048 
       
  2049 		default:
       
  2050 		case EDivNotSupported:
       
  2051 			Panic( ESetDividerUnsupportedClock );
       
  2052 			return 0xFFFFFFFF;
       
  2053 
       
  2054 		// These are all the standard case, where value in register is divide factor
       
  2055 		case EDiv_1_2:
       
  2056 		case EDivCore_1_2_4:
       
  2057 		case EDivPll_1_To_16:
       
  2058 		case EDivPll_1_To_31:
       
  2059 			break;
       
  2060 
       
  2061 		case EDivCore_3_4_6_96M:
       
  2062 			{
       
  2063 			switch( div )
       
  2064 				{
       
  2065 				default:
       
  2066 					// hardware value has unknown meaning
       
  2067 					result = 0xFFFFFFFF;
       
  2068 
       
  2069 				case 0:
       
  2070 					result = 3;
       
  2071 					break;
       
  2072 
       
  2073 				case 1:
       
  2074 					result = 4;
       
  2075 					break;
       
  2076 
       
  2077 				case 2:
       
  2078 					result = 6;
       
  2079 					break;
       
  2080 
       
  2081 				case 3:
       
  2082 					result = 0;
       
  2083 					break;
       
  2084 				}
       
  2085 			break;
       
  2086 			}
       
  2087 
       
  2088 		case EDivClkOut_1_2_4_8_16:
       
  2089 			{
       
  2090 			switch( div )
       
  2091 				{
       
  2092 				default:
       
  2093 					// hardware value has unknown meaning
       
  2094 					result = 0xFFFFFFFF;
       
  2095 
       
  2096 				case 0:
       
  2097 					result = 1;
       
  2098 					break;
       
  2099 
       
  2100 				case 1:
       
  2101 					result = 2;
       
  2102 					break;
       
  2103 
       
  2104 				case 2:
       
  2105 					result = 4;
       
  2106 					break;
       
  2107 
       
  2108 				case 3:
       
  2109 					result = 8;
       
  2110 					break;
       
  2111 
       
  2112 				case 4:
       
  2113 					result = 16;
       
  2114 					break;
       
  2115 				}
       
  2116 			break;
       
  2117 			}
       
  2118 		}
       
  2119 
       
  2120 	return result;
       
  2121 	}
       
  2122 
       
  2123 EXPORT_C void SetPowerDomainMode( TPowerDomain aDomain, TPowerDomainMode aMode )
       
  2124 	{
       
  2125 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetPowerDomainMode(%x;%x)", aDomain, aMode ) );
       
  2126 	__ASSERT_DEBUG( (TUint)aDomain < KSupportedPowerDomainCount, Panic( ESetDomainModeBadDomain ) );
       
  2127 	__ASSERT_DEBUG( (TUint)aMode <= EPowerOn, Panic( ESetDomainModeBadMode ) );
       
  2128 
       
  2129 	__ASSERT_DEBUG( 0 != (KPowerDomainControl[ aDomain ].iAllowedMask bitand (1 << aMode)), Panic( ESetDomainModeUnsupportedMode ) );
       
  2130 	
       
  2131 	TUint shift = KPowerDomainControl[ aDomain ].iShift;
       
  2132 
       
  2133 	_LockedBitClearSet( KPowerDomainControl[ aDomain ].iRegister,
       
  2134 						KPowerModeMask << shift,
       
  2135 						aMode << shift );
       
  2136 	}
       
  2137 
       
  2138 EXPORT_C TPowerDomainMode PowerDomainMode( TPowerDomain aDomain )
       
  2139 	{
       
  2140 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PowerDomainMode(%x)", aDomain ) );
       
  2141 	__ASSERT_DEBUG( (TUint)aDomain < KSupportedPowerDomainCount, Panic( EGetDomainModeBadDomain ) );
       
  2142 
       
  2143 	TUint32 m = (AsspRegister::Read32( KPowerDomainControl[ aDomain ].iRegister ) >> KPowerDomainControl[ aDomain ].iShift) bitand KPowerModeMask;
       
  2144 	return static_cast< TPowerDomainMode >( m );
       
  2145 	}
       
  2146 
       
  2147 EXPORT_C void SetClockState( TClock aClock, TClockState aState )
       
  2148 	{
       
  2149 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetClockState(%x;%x)", aClock, aState ) );
       
  2150 
       
  2151 	__ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( ESetStateBadClock ) );
       
  2152 
       
  2153 	const TClockEnableAutoInfo& def = KClockControlTable[ aClock ];
       
  2154 
       
  2155 	TUint32 reg = def.iGate.iRegister;
       
  2156 	TUint32 mask = def.iGate.iMask;
       
  2157 	TUint32 autoReg = def.iAuto.iRegister;
       
  2158 	TUint32 autoMask = def.iAuto.iMask;
       
  2159 
       
  2160 	TInt irq = __SPIN_LOCK_IRQSAVE(iLock);
       
  2161 
       
  2162 	if( EClkOn == aState )
       
  2163 		{
       
  2164 		_BitClearSet( reg, mask, def.iGate.iEnablePattern );
       
  2165 		_BitClearSet( autoReg, autoMask, def.iAuto.iDisablePattern );
       
  2166 		}
       
  2167 	else if( EClkOff == aState )
       
  2168 		{
       
  2169 		_BitClearSet( reg, mask, def.iGate.iDisablePattern );
       
  2170 		_BitClearSet( autoReg, autoMask, def.iAuto.iDisablePattern );
       
  2171 		}
       
  2172 	else if( EClkAuto == aState )
       
  2173 		{
       
  2174 		_BitClearSet( autoReg, autoMask, def.iAuto.iEnablePattern );
       
  2175 		_BitClearSet( reg, mask, def.iGate.iEnablePattern );
       
  2176 		}
       
  2177 
       
  2178 	__SPIN_UNLOCK_IRQRESTORE(iLock, irq);
       
  2179 	}
       
  2180 
       
  2181 EXPORT_C TClockState ClockState( TClock aClock )
       
  2182 	{
       
  2183 	__KTRACE_OPT( KPRCM, Kern::Printf( "+Prcm::ClockState(%x)", aClock ) );
       
  2184 
       
  2185 	__ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( EGetStateBadClock ) );
       
  2186 
       
  2187 	const TClockEnableAutoInfo& def = KClockControlTable[ aClock ];
       
  2188 
       
  2189 	TUint32 reg = def.iGate.iRegister;
       
  2190 	TUint32 mask = def.iGate.iMask;
       
  2191 	TUint32 autoReg = def.iAuto.iRegister;
       
  2192 	TUint32 autoMask = def.iAuto.iMask;
       
  2193 
       
  2194 	TUint32 enable = AsspRegister::Read32( reg ) bitand mask;
       
  2195 	TUint32 autoClock = AsspRegister::Read32( autoReg ) bitand autoMask;
       
  2196 
       
  2197 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::ClockState(%x):e:%x a:%x", aClock, enable, autoClock ) );
       
  2198 
       
  2199 	TClockState state = EClkAuto;
       
  2200 
       
  2201 	// OFF = OFF
       
  2202 	// ON + AUTO = AUTO
       
  2203 	// ON + !AUTO = ON
       
  2204 	if( def.iGate.iEnablePattern != enable )
       
  2205 		{
       
  2206 		state = EClkOff;
       
  2207 		}
       
  2208 	else if( def.iAuto.iEnablePattern != autoClock )
       
  2209 		{
       
  2210 		state = EClkOn;
       
  2211 		}
       
  2212 
       
  2213 	__KTRACE_OPT( KPRCM, Kern::Printf( "-Prcm::ClockState(%x):%d", aClock, state ) );
       
  2214 
       
  2215 	return state;
       
  2216 	}
       
  2217 
       
  2218 EXPORT_C void SetWakeupMode( TClock aClock, TWakeupMode aMode )
       
  2219 	{
       
  2220 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetWakeupMode(%x;%x)", aClock, aMode ) );
       
  2221 
       
  2222 	__ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( ESetWakeupBadClock ) );
       
  2223 
       
  2224 	const TRegisterBitDef& def = KClockWakeupTable[ aClock ];
       
  2225 
       
  2226 	TUint32 reg = def.iRegister;
       
  2227 	TUint32 mask = def.iMask;
       
  2228 
       
  2229 	TInt irq = __SPIN_LOCK_IRQSAVE(iLock);
       
  2230 
       
  2231 	if( EWakeupEnabled == aMode )
       
  2232 		{
       
  2233 		_BitClearSet( reg, mask, def.iEnablePattern );
       
  2234 		}
       
  2235 	else
       
  2236 		{
       
  2237 		_BitClearSet( reg, mask, def.iDisablePattern );
       
  2238 		}
       
  2239 
       
  2240 	__SPIN_UNLOCK_IRQRESTORE(iLock, irq);
       
  2241 	}
       
  2242 
       
  2243 EXPORT_C TWakeupMode WakeupMode( TClock aClock )
       
  2244 	{
       
  2245 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::WakeupMode(%x)", aClock ) );
       
  2246 
       
  2247 	__ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( EGetWakeupBadClock ) );
       
  2248 
       
  2249 	const TRegisterBitDef& def = KClockWakeupTable[ aClock ];
       
  2250 
       
  2251 	TUint32 reg = def.iRegister;
       
  2252 	TUint32 mask = def.iMask;
       
  2253 
       
  2254 	if( def.iEnablePattern == (AsspRegister::Read32( reg ) bitand mask) )
       
  2255 		{
       
  2256 		return EWakeupEnabled;
       
  2257 		}
       
  2258 	else
       
  2259 		{
       
  2260 		return EWakeupDisabled;
       
  2261 		}
       
  2262 	}
       
  2263 
       
  2264 EXPORT_C void AddToWakeupGroup( TClock aClock, TWakeupGroup aGroup )
       
  2265 	{
       
  2266 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::AddToWakeupGroup(%x;%x)", aClock, aGroup ) );
       
  2267 
       
  2268 	__ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( EAddWakeupGroupBadClock ) );
       
  2269 	__ASSERT_DEBUG( (TUint)aGroup < KSupportedWakeupGroupCount, Panic( EAddWakeupGroupBadGroup ) );
       
  2270 
       
  2271 	const TRegisterBitDef& def = KClockWakeupGroupTable[ aClock ][ aGroup ];
       
  2272 
       
  2273 	TUint32 reg = def.iRegister;
       
  2274 	TUint32 mask = def.iMask;
       
  2275 
       
  2276 	_LockedBitClearSet( reg, mask, def.iEnablePattern );
       
  2277 	}
       
  2278 
       
  2279 EXPORT_C void RemoveFromWakeupGroup( TClock aClock, TWakeupGroup aGroup )
       
  2280 	{
       
  2281 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::RemoveFromWakeupGroup(%x;%x)", aClock, aGroup ) );
       
  2282 
       
  2283 	__ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( ERemoveWakeupGroupBadClock ) );
       
  2284 	__ASSERT_DEBUG( (TUint)aGroup < KSupportedWakeupGroupCount, Panic( ERemoveWakeupGroupBadGroup ) );
       
  2285 
       
  2286 	const TRegisterBitDef& def = KClockWakeupGroupTable[ aClock ][ aGroup ];
       
  2287 
       
  2288 	TUint32 reg = def.iRegister;
       
  2289 	TUint32 mask = def.iMask;
       
  2290 
       
  2291 	_LockedBitClearSet( reg, mask, def.iDisablePattern );
       
  2292 	}
       
  2293 
       
  2294 EXPORT_C TBool IsInWakeupGroup( TClock aClock, TWakeupGroup aGroup )
       
  2295 	{
       
  2296 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::IsInWakeupGroup(%x)", aClock ) );
       
  2297 
       
  2298 	__ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( EGetWakeupGroupBadClock ) );
       
  2299 	__ASSERT_DEBUG( (TUint)aGroup < KSupportedWakeupGroupCount, Panic( EGetWakeupGroupBadGroup ) );
       
  2300 
       
  2301 	const TRegisterBitDef& def = KClockWakeupGroupTable[ aClock ][ aGroup ];
       
  2302 
       
  2303 	TUint32 reg = def.iRegister;
       
  2304 	TUint32 mask = def.iMask;
       
  2305 
       
  2306 	return( def.iEnablePattern == (AsspRegister::Read32( reg ) bitand mask) );
       
  2307 	}
       
  2308 
       
  2309 
       
  2310 EXPORT_C void AddToWakeupDomain( TClock aClock, TWakeupDomain aDomain )
       
  2311 	{
       
  2312 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::AddToWakeupDomain(%x;%x)", aClock, aDomain ) );
       
  2313 
       
  2314 	__ASSERT_DEBUG( (TUint)aClock <= (TUint)KSupportedClockCount, Panic( EAddDomainBadClock ) );
       
  2315 	__ASSERT_DEBUG( (TUint)aDomain <= (TUint)KSupportedWakeupDomainCount, Panic( EAddDomainBadDomain ) );
       
  2316 
       
  2317 	const TWakeupDomainInfo& inf = KClockWakeupDomainTable[ aClock ];
       
  2318 	TUint32 mask = 1 << (TUint)inf.iBitNumber[ aDomain ];	// unsupported bit numbers will result in a mask of 0x00000000
       
  2319 	
       
  2320 	_LockedBitClearSet( inf.iRegister, KClearNone, mask );
       
  2321 	}
       
  2322 
       
  2323 EXPORT_C void RemoveFromWakeupDomain( TClock aClock, TWakeupDomain aDomain )
       
  2324 	{
       
  2325 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::RemoveFromWakeupDomain(%x;%x)", aClock, aDomain ) );
       
  2326 
       
  2327 	__ASSERT_DEBUG( (TUint)aClock <= (TUint)KSupportedClockCount, Panic( ERemoveDomainBadClock ) );
       
  2328 	__ASSERT_DEBUG( (TUint)aDomain <= (TUint)KSupportedWakeupDomainCount, Panic( ERemoveDomainBadDomain ) );
       
  2329 
       
  2330 	const TWakeupDomainInfo& inf = KClockWakeupDomainTable[ aClock ];
       
  2331 	TUint32 mask = 1 << (TUint)inf.iBitNumber[ aDomain ];	// unsupported bit numbers will result in a mask of 0x00000000
       
  2332 	
       
  2333 	_LockedBitClearSet( inf.iRegister, mask, KSetNone );
       
  2334 	}
       
  2335 
       
  2336 EXPORT_C TBool IsInWakeupDomain( TClock aClock, TWakeupDomain aDomain )
       
  2337 	{
       
  2338 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::IsInWakeupDomain(%x;%x)", aClock, aDomain ) );
       
  2339 
       
  2340 	__ASSERT_DEBUG( (TUint)aClock <= (TUint)KSupportedClockCount, Panic( ECheckDomainBadClock ) );
       
  2341 	__ASSERT_DEBUG( (TUint)aDomain <= (TUint)KSupportedWakeupDomainCount, Panic( ECheckDomainBadDomain ) );
       
  2342 
       
  2343 	const TWakeupDomainInfo& inf = KClockWakeupDomainTable[ aClock ];
       
  2344 	TUint32 mask = 1 << (TUint)inf.iBitNumber[ aDomain ];	// unsupported bit numbers will result in a mask of 0x00000000
       
  2345 
       
  2346 	return ( 0 != (AsspRegister::Read32( inf.iRegister ) bitand mask) );
       
  2347 	}
       
  2348 
       
  2349 EXPORT_C void SetGptClockSource( TGpt aGpt, TGptClockSource aSource )
       
  2350 	{
       
  2351 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetGptClockSource(%x;%x)", aGpt, aSource ) );
       
  2352 
       
  2353 	__ASSERT_DEBUG( (TUint)aGpt <= (TUint)EGpt12, Panic( ESetGptClockBadGpt ) );
       
  2354 
       
  2355 
       
  2356 	TUint32 reg = KGptClockSourceInfo[ aGpt ].iRegister;
       
  2357 	TUint32 mask = KGptClockSourceInfo[ aGpt ].iMask;
       
  2358 	TUint32 setPattern = (EGptClockSysClk == aSource ) ? mask : 0;
       
  2359 
       
  2360 	_LockedBitClearSet( reg, mask, setPattern );
       
  2361 	}
       
  2362 
       
  2363 EXPORT_C TGptClockSource GptClockSource( TGpt aGpt )
       
  2364 	{
       
  2365 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::GptClockSource(%x)", aGpt ) );
       
  2366 
       
  2367 	__ASSERT_DEBUG( (TUint)aGpt <= (TUint)EGpt12, Panic( ESetGptClockBadGpt ) );
       
  2368 
       
  2369 	TUint32 reg = KGptClockSourceInfo[ aGpt ].iRegister;
       
  2370 	TUint32 mask = KGptClockSourceInfo[ aGpt ].iMask;
       
  2371 
       
  2372 	if( 0 == (AsspRegister::Read32( reg ) bitand mask) )
       
  2373 		{
       
  2374 		return EGptClock32k;
       
  2375 		}
       
  2376 	else
       
  2377 		{
       
  2378 		return EGptClockSysClk;
       
  2379 		}
       
  2380 	}
       
  2381 
       
  2382 EXPORT_C TUint UsimDivider()
       
  2383 	{
       
  2384 	const TDividerInfo& info = KDividerInfo[ EClkUsim_F ];
       
  2385 	TUint divmux = (AsspRegister::Read32( info.iRegister ) bitand info.iMask ) >> info.iShift;
       
  2386 	return UsimDivMuxInfo[ divmux ].iDivider;
       
  2387 	}
       
  2388 
       
  2389 EXPORT_C TClock UsimClockSource()
       
  2390 	{
       
  2391 	const TDividerInfo& info = KDividerInfo[ EClkUsim_F ];
       
  2392 	TUint divmux = (AsspRegister::Read32( info.iRegister ) bitand info.iMask ) >> info.iShift;
       
  2393 	return UsimDivMuxInfo[ divmux ].iClock;
       
  2394 	}
       
  2395 
       
  2396 EXPORT_C void SetClockMux( TClock aClock, TClock aSource )
       
  2397 	{
       
  2398 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetClockMux(%x;%x)", aClock, aSource ) );
       
  2399 
       
  2400 	switch( aClock )
       
  2401 		{
       
  2402 		case EClk96M:
       
  2403 			{
       
  2404 			TUint set = KBit6;
       
  2405 			TUint clear = 0;
       
  2406 
       
  2407 			switch( aSource )
       
  2408 				{
       
  2409 				case EClkPeriph:
       
  2410 					clear = KBit6;
       
  2411 					set = 0;
       
  2412 					// fall through...
       
  2413 
       
  2414 				case EClkSysClk:
       
  2415 					_LockedBitClearSet( KCM_CLKSEL1_PLL, clear, set );
       
  2416 					break;
       
  2417 
       
  2418 				default:
       
  2419 					Panic( ESetClockMuxBadSource );
       
  2420 				}
       
  2421 			break;
       
  2422 			}
       
  2423 
       
  2424 		case EClkSysOut:
       
  2425 			{
       
  2426 			TUint set;
       
  2427 			switch( aSource )
       
  2428 				{
       
  2429 				case EClkCore:
       
  2430 					set = 0;
       
  2431 					break;
       
  2432 
       
  2433 				case EClkSysClk:
       
  2434 					set = 1;
       
  2435 					break;
       
  2436 
       
  2437 				case EClkPeriph:
       
  2438 					set = 2;
       
  2439 					break;
       
  2440 
       
  2441 				case EClkTv_F:
       
  2442 					set = 3;
       
  2443 					break;
       
  2444 
       
  2445 				default:
       
  2446 					Panic( ESetClockMuxBadSource );
       
  2447 					return;
       
  2448 				}
       
  2449 
       
  2450 			_LockedBitClearSet( KCM_CLKOUT_CTRL, KBit1 | KBit0, set );
       
  2451 			break;
       
  2452 			}
       
  2453 
       
  2454 		case EClkTv_F:
       
  2455 			{
       
  2456 			TUint set = KBit5;
       
  2457 			TUint clear = 0;
       
  2458 
       
  2459 			switch( aSource )
       
  2460 				{
       
  2461 				case EClkPeriph:
       
  2462 					clear = KBit5;
       
  2463 					set = 0;
       
  2464 					// fall through...
       
  2465 
       
  2466 				case EClkAltClk:
       
  2467 					_LockedBitClearSet( KCM_CLKSEL1_PLL, clear, set );
       
  2468 					break;
       
  2469 
       
  2470 				default:
       
  2471 					Panic( ESetClockMuxBadSource );
       
  2472 					return;
       
  2473 				}
       
  2474 			break;
       
  2475 			}
       
  2476 
       
  2477 		case EClkGpt1_F:
       
  2478 		case EClkGpt2_F:
       
  2479 		case EClkGpt3_F:
       
  2480 		case EClkGpt4_F:
       
  2481 		case EClkGpt5_F:
       
  2482 		case EClkGpt6_F:
       
  2483 		case EClkGpt7_F:
       
  2484 		case EClkGpt8_F:
       
  2485 		case EClkGpt9_F:
       
  2486 			{
       
  2487 			TGptClockSource src = EGptClock32k;
       
  2488 
       
  2489 			switch( aSource )
       
  2490 				{
       
  2491 				case EClkSysClk:
       
  2492 					src = EGptClockSysClk;
       
  2493 				case EClkSysClk32k:
       
  2494 					break;
       
  2495 				default:
       
  2496 					Panic( ESetClockMuxBadSource );
       
  2497 					return;
       
  2498 				}
       
  2499 
       
  2500 			SetGptClockSource( KClockSourceInfo[ aClock ].iGpt, src );
       
  2501 			break;
       
  2502 			}
       
  2503 
       
  2504 		case EClkSgx_F:
       
  2505 			switch( aSource )
       
  2506 				{
       
  2507 				case EClk96M:
       
  2508 					SetDivider( EClkSgx_F, 0 );
       
  2509 					break;
       
  2510 
       
  2511 				case EClkCore:
       
  2512 					// Unfortunately the combined divider/mux means that switching from
       
  2513 					// CORE t 96M loses the old divider values
       
  2514 					if( 0 != Divider( EClkSgx_F ) )
       
  2515 						{
       
  2516 						// Not currently CORE, switch to default maximum divider
       
  2517 						SetDivider( EClkSgx_F, 6 );
       
  2518 						}
       
  2519 					break;
       
  2520 
       
  2521 				default:
       
  2522 					Panic( ESetClockMuxBadSource );
       
  2523 					return;
       
  2524 				}
       
  2525 			break;
       
  2526 
       
  2527 
       
  2528 		case EClk48M:
       
  2529 			{
       
  2530 			TUint set = KBit3;
       
  2531 			TUint clear = 0;
       
  2532 
       
  2533 			switch( aSource )
       
  2534 				{
       
  2535 				case EClkPeriph:
       
  2536 					clear = KBit3;
       
  2537 					set = 0;
       
  2538 					// fall through...
       
  2539 
       
  2540 				case EClkAltClk:
       
  2541 					_LockedBitClearSet( KCM_CLKSEL1_PLL, clear, set );
       
  2542 					break;
       
  2543 
       
  2544 				default:
       
  2545 					Panic( ESetClockMuxBadSource );
       
  2546 					return;
       
  2547 				}
       
  2548 			break;
       
  2549 			}
       
  2550 
       
  2551 		default:
       
  2552 			Panic( ESetClockMuxBadClock );
       
  2553 			return;
       
  2554 		}
       
  2555 	}
       
  2556 
       
  2557 EXPORT_C TClock ClockMux( TClock aClock )
       
  2558 	{
       
  2559 	__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::ClockMux(%x)", aClock ) );
       
  2560 
       
  2561 	TClock result;
       
  2562 
       
  2563 	switch( aClock )
       
  2564 		{
       
  2565 		case EClk96M:
       
  2566 			if( 0 == (AsspRegister::Read32( KCM_CLKSEL1_PLL ) bitand KBit6 ) )
       
  2567 				{
       
  2568 				result = EClkPeriph;
       
  2569 				}
       
  2570 			else
       
  2571 				{
       
  2572 				result = EClkSysClk;
       
  2573 				}
       
  2574 			break;
       
  2575 
       
  2576 		case EClkSysOut:
       
  2577 			switch( AsspRegister::Read32( KCM_CLKOUT_CTRL ) bitand (KBit1 | KBit0) )
       
  2578 				{
       
  2579 				default:
       
  2580 				case 0:
       
  2581 					result = EClkCore;
       
  2582 					break;
       
  2583 
       
  2584 				case 1:
       
  2585 					result = EClkSysClk;
       
  2586 					break;
       
  2587 
       
  2588 				case 2:
       
  2589 					result = EClkPeriph;
       
  2590 					break;
       
  2591 
       
  2592 				case 3:
       
  2593 					result = EClkTv_F;		// same as 54MHz clock
       
  2594 					break;
       
  2595 				}
       
  2596 			break;
       
  2597 
       
  2598 		case EClkTv_F:
       
  2599 			if( 0 == (AsspRegister::Read32( KCM_CLKSEL1_PLL ) bitand KBit5 ) )
       
  2600 				{
       
  2601 				result = EClkPeriph;
       
  2602 				}
       
  2603 			else
       
  2604 				{
       
  2605 				result = EClkAltClk;
       
  2606 				}
       
  2607 			break;
       
  2608 
       
  2609 		case EClkGpt1_F:
       
  2610 		case EClkGpt2_F:
       
  2611 		case EClkGpt3_F:
       
  2612 		case EClkGpt4_F:
       
  2613 		case EClkGpt5_F:
       
  2614 		case EClkGpt6_F:
       
  2615 		case EClkGpt7_F:
       
  2616 		case EClkGpt8_F:
       
  2617 		case EClkGpt9_F:
       
  2618 		case EClkGpt10_F:
       
  2619 		case EClkGpt11_F:
       
  2620 			// Redirect these to GptClockSource()
       
  2621 			if( EGptClockSysClk == GptClockSource( KClockSourceInfo[ aClock ].iGpt ) )
       
  2622 				{
       
  2623 				result = EClkSysClk;
       
  2624 				}
       
  2625 			else
       
  2626 				{
       
  2627 				result = EClkSysClk32k;
       
  2628 				}
       
  2629 			break;
       
  2630 
       
  2631 		case EClkSgx_F:
       
  2632 			if( Divider( EClkSgx_F ) == 0 )
       
  2633 				{
       
  2634 				result = EClk96M;
       
  2635 				}
       
  2636 			else
       
  2637 				{
       
  2638 				result = EClkCore;
       
  2639 				}
       
  2640 			break;
       
  2641 
       
  2642 		case EClkUsim_F:
       
  2643 			result = UsimClockSource();
       
  2644 			break;
       
  2645 
       
  2646 		case EClk48M:
       
  2647 			if( 0 == (AsspRegister::Read32( KCM_CLKSEL1_PLL ) bitand KBit3 ) )
       
  2648 				{
       
  2649 				result = EClk96M;
       
  2650 				}
       
  2651 			else
       
  2652 				{
       
  2653 				result = EClkAltClk;
       
  2654 				}
       
  2655 			break;
       
  2656 
       
  2657 		default:
       
  2658 			Panic( EGetClockMuxBadClock );
       
  2659 			return EClkAltClk;	// dumy to stop compiler warning
       
  2660 		}
       
  2661 
       
  2662 	return result;
       
  2663 	}
       
  2664 
       
  2665 EXPORT_C TUint ClockFrequency( TClock aClock )
       
  2666 	{
       
  2667 	// Works out the frequency by traversing backwards through the clock chain
       
  2668 	// assumulating a multply and divide factor until SYSCLK or SYSCLK32 is reached
       
  2669 	// Reaching a DPLL implicitly means SYSCLK has been reached
       
  2670 
       
  2671 	TUint mul = 1;
       
  2672 	TUint div = 1;
       
  2673 	TClock currentClock = aClock;
       
  2674 	__ASSERT_ALWAYS( currentClock < Prcm::KSupportedClockCount, Panic( EClockFrequencyBadClock ) );
       
  2675 
       
  2676 	// Ensure assumption that root clock range is >=EClkSysClk
       
  2677 	__ASSERT_COMPILE( EClkSysClk < EClkAltClk );
       
  2678 	__ASSERT_COMPILE( EClkAltClk < EClkSysClk32k );
       
  2679 	__ASSERT_COMPILE( (TUint)EClkSysClk32k == (TUint)KSupportedClockCount - 1 );
       
  2680 
       
  2681 	while( currentClock < EClkSysClk )
       
  2682 		{
       
  2683 		// Get previous clock in chain
       
  2684 		TClock prevClock = KClockSourceInfo[ currentClock ].iClock;
       
  2685 
       
  2686 		switch( KClockSourceInfo[ currentClock ].iType )
       
  2687 			{
       
  2688 			case EIgnore:
       
  2689 				return 0;	// unsupported clock
       
  2690 
       
  2691 			case EDpll:
       
  2692 				{
       
  2693 				TPll pll = KClockSourceInfo[ currentClock ].iPll;
       
  2694 
       
  2695 				if( PllMode( pll ) == EPllBypass )
       
  2696 					{
       
  2697 					if( EDpll1 == pll )
       
  2698 						{
       
  2699 						prevClock = Prcm::EClkMpuPll_Bypass;
       
  2700 						}
       
  2701 					else if( EDpll2 == pll )
       
  2702 						{
       
  2703 						prevClock = Prcm::EClkIva2Pll_Bypass;
       
  2704 						}
       
  2705 					else
       
  2706 						{
       
  2707 						// for all other DPLL1 the bypass clock is the input clock SYSCLK
       
  2708 						prevClock = EClkSysClk;
       
  2709 						}
       
  2710 					}
       
  2711 				else
       
  2712 					{
       
  2713 					TPllConfiguration pllCfg;
       
  2714 					PllConfig( pll, pllCfg );
       
  2715 					mul *= pllCfg.iMultiplier;
       
  2716 					div *= pllCfg.iDivider;
       
  2717 					if( EDpll4 == pll )
       
  2718 						{
       
  2719 						// Output is multiplied by 2 for DPLL4
       
  2720 						mul *= 2;
       
  2721 						}
       
  2722 					prevClock = EClkSysClk;
       
  2723 					}
       
  2724 				break;
       
  2725 				}
       
  2726 
       
  2727 			case EMux:
       
  2728 				prevClock = ClockMux( currentClock );
       
  2729 				break;
       
  2730 
       
  2731 			case EDivMux:
       
  2732 				// need to find what clock the divider is fed from
       
  2733 				prevClock = ClockMux( currentClock );
       
  2734 				// fall through to get divider..
       
  2735 
       
  2736 			case EDivider:
       
  2737 				{
       
  2738 				TUint selectedDiv = Divider( currentClock );
       
  2739 				// Special case for SGX - ignore a return of 0
       
  2740 				if( 0 != selectedDiv )
       
  2741 					{
       
  2742 					div *= selectedDiv;
       
  2743 					}
       
  2744 				break;
       
  2745 				}
       
  2746 
       
  2747 			case EDuplicate:
       
  2748 				// Nothing to do, we just follow to the next clock
       
  2749 				break;
       
  2750 
       
  2751 			case E48MMux:
       
  2752 				prevClock = ClockMux( currentClock );
       
  2753 				if( prevClock != EClkAltClk )
       
  2754 					{
       
  2755 					div *= 2;
       
  2756 					}
       
  2757 				break;
       
  2758 
       
  2759 			case E54MMux:
       
  2760 				prevClock = ClockMux( currentClock );
       
  2761 				if( prevClock != EClkAltClk )
       
  2762 					{
       
  2763 					div *= Divider( currentClock );
       
  2764 					}
       
  2765 				break;
       
  2766 
       
  2767 			case E96MMux:
       
  2768 				prevClock = ClockMux( currentClock );
       
  2769 				if( prevClock != EClkSysClk )
       
  2770 					{
       
  2771 					div *= Divider( currentClock );
       
  2772 					}
       
  2773 				break;
       
  2774 
       
  2775 			case EDiv4:
       
  2776 				div *= 4;
       
  2777 				break;
       
  2778 			}
       
  2779 		
       
  2780 		currentClock = prevClock;
       
  2781 		}	// end do
       
  2782 
       
  2783 	// When we reach here we have worked back to the origin clock
       
  2784 	
       
  2785 	TUint64 fSrc;
       
  2786 	const Omap3530Assp* variant = (Omap3530Assp*)Arch::TheAsic();
       
  2787 
       
  2788 	if( EClkSysClk == currentClock )
       
  2789 		{
       
  2790 		// input OSC_SYSCLK is always divided by 2 before being fed to SYS_CLK
       
  2791 		fSrc = variant->SysClkFrequency() / 2;
       
  2792 		}
       
  2793 	else if( EClkSysClk32k == currentClock )
       
  2794 		{
       
  2795 		fSrc = variant->SysClk32kFrequency();
       
  2796 		}
       
  2797 	else
       
  2798 		{
       
  2799 		fSrc = variant->AltClkFrequency();
       
  2800 		}
       
  2801 
       
  2802 	if( div == 0 )
       
  2803 		{
       
  2804 		// to account for any registers set at illegal values
       
  2805 		return 0;
       
  2806 		}
       
  2807 	else
       
  2808 		{
       
  2809 		return (TUint)((fSrc * mul) / div);
       
  2810 		}
       
  2811 	}
       
  2812 
       
  2813 EXPORT_C void SetSysClkFrequency( TSysClkFrequency aFrequency )
       
  2814 	{
       
  2815 	static const TUint8 KConfigValues[] =
       
  2816 		{
       
  2817 		0,	// ESysClk12MHz
       
  2818 		1,	// ESysClk13MHz
       
  2819 		5,	// ESysClk16_8MHz
       
  2820 		2,	// ESysClk19_2MHz
       
  2821 		3,	// ESysClk26MHz
       
  2822 		4	// ESysClk38_4MHz
       
  2823 		};
       
  2824 
       
  2825 	_LockedBitClearSet( KPRM_CLKSEL, KBit0 | KBit1 | KBit2, KConfigValues[ aFrequency ] );
       
  2826 	}
       
  2827 
       
  2828 /** Get the currently configured SysClk frequency */
       
  2829 EXPORT_C TSysClkFrequency SysClkFrequency()
       
  2830 	{
       
  2831 	
       
  2832 	switch( AsspRegister::Read32( KPRM_CLKSEL ) bitand (KBit0 | KBit1 | KBit2) )
       
  2833 		{
       
  2834 		case 0:
       
  2835 			return ESysClk12MHz;
       
  2836 		case 1:
       
  2837 			return ESysClk13MHz;
       
  2838 		case 2:
       
  2839 			return ESysClk19_2MHz;
       
  2840 		case 3:
       
  2841 			return ESysClk26MHz;
       
  2842 		case 4:
       
  2843 			return ESysClk38_4MHz;
       
  2844 		case 5:
       
  2845 			return ESysClk16_8MHz;
       
  2846 		default:
       
  2847 			__DEBUG_ONLY( InternalPanic( __LINE__ ) );
       
  2848 			return ESysClk13MHz;
       
  2849 		}
       
  2850 	}
       
  2851 
       
  2852 
       
  2853 EXPORT_C const TDesC& PrmName( TClock aClock )
       
  2854 	{
       
  2855 	__ASSERT_DEBUG( (TUint)aClock <= KSupportedClockCount, Panic( EGetNameBadClock ) );
       
  2856 	__ASSERT_DEBUG( KNames[ aClock ] != NULL, Kern::Fault( "PrmName", aClock ) );
       
  2857 
       
  2858 	return *KNames[ aClock ];
       
  2859 	}
       
  2860 
       
  2861 EXPORT_C void Init3()
       
  2862 	{
       
  2863 	// Enable LP mode if possible on MPU and CORE PLLs.
       
  2864 	// Don't enable on PERIPHERAL, IVA2 or USB because LP mode introduces jitter
       
  2865 	AutoSetPllLpMode( EDpll1 );
       
  2866 	AutoSetPllLpMode( EDpll3 );
       
  2867 
       
  2868 	TInt irq = __SPIN_LOCK_IRQSAVE(iLock);
       
  2869 	TUint32 r;
       
  2870 
       
  2871 	// IVA2
       
  2872 //	Not yet mapped! const TUint32 KPDCCMD = Omap3530HwBase::TVirtual<0x01810000>::Value;
       
  2873 //	r = AsspRegister::Read32(KPDCCMD);
       
  2874 //	AsspRegister::Modify32(KPDCCMD, 0, 1 << 16);
       
  2875 //	Set(KCM_FCLKEN_IVA2, 1 << 0, 0);
       
  2876 	// CAM
       
  2877 	const TUint32 KISP_CTRL = Omap3530HwBase::TVirtual<0x480BC040>::Value;
       
  2878 	r = AsspRegister::Read32(KISP_CTRL);
       
  2879 	_BitClearSet(KISP_CTRL, 0xf << 10, 0);
       
  2880 	_BitClearSet(KCM_FCLKEN_CAM, 1 << 0, 0);
       
  2881 	_BitClearSet(KCM_ICLKEN_CAM, 1 << 0, 0);
       
  2882 
       
  2883 	// MMC
       
  2884 	r = AsspRegister::Read32(KMMCHS1_SYSCONFIG);
       
  2885 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  2886 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  2887 	SetClockState( EClkMmc1_F, EClkOff );
       
  2888 	SetClockState( EClkMmc1_I, EClkOff );
       
  2889 	r = AsspRegister::Read32(KMMCHS2_SYSCONFIG);
       
  2890 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  2891 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  2892 	SetClockState( EClkMmc2_F, EClkOff );
       
  2893 	SetClockState( EClkMmc2_I, EClkOff );
       
  2894 /* There is no MMC3 on the beagle board
       
  2895 	r = AsspRegister::Read32(KMMCHS3_SYSCONFIG);
       
  2896 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  2897 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  2898 */
       
  2899 	SetClockState( EClkMmc3_F, EClkOff );
       
  2900 	SetClockState( EClkMmc3_I, EClkOff );
       
  2901 
       
  2902 	// McBSP
       
  2903 	r = AsspRegister::Read32(KMCBSPLP1_SYSCONFIG);
       
  2904 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  2905 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  2906 	SetClockState( EClkMcBsp1_F, EClkOff );
       
  2907 	SetClockState( EClkMcBsp1_I, EClkOff );
       
  2908 	const TUint32 KMCBSPLP2_SPCR1 = Omap3530HwBase::TVirtual<0x49022014>::Value;
       
  2909 	_BitClearSet(KMCBSPLP2_SPCR1, 1 << 0, 0); // RRST := 0
       
  2910 	const TUint32 KMCBSPLP2_SPCR2 = Omap3530HwBase::TVirtual<0x49022010>::Value;
       
  2911 	_BitClearSet(KMCBSPLP2_SPCR2, 1 << 7 | 1 << 0, 0); // FRST, XRST := 0
       
  2912 	_BitClearSet(KMCBSPLP2_SYSCONFIG, 0x3 << 8 | 0x3 << 3, 0); // CLOCKACTIVITY := can be switched off, SIDLEMODE := force idle
       
  2913 	r = AsspRegister::Read32(KMCBSPLP2_SYSCONFIG);
       
  2914 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  2915 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  2916 	SetClockState( EClkMcBsp2_F, EClkOff );
       
  2917 	SetClockState( EClkMcBsp2_I, EClkOff );
       
  2918 	r = AsspRegister::Read32(KMCBSPLP3_SYSCONFIG);
       
  2919 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  2920 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  2921 	SetClockState( EClkMcBsp3_F, EClkOff );
       
  2922 	SetClockState( EClkMcBsp3_I, EClkOff );
       
  2923 	r = AsspRegister::Read32(KMCBSPLP4_SYSCONFIG);
       
  2924 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  2925 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  2926 	SetClockState( EClkMcBsp4_F, EClkOff );
       
  2927 	SetClockState( EClkMcBsp4_I, EClkOff );
       
  2928 	r = AsspRegister::Read32(KMCBSPLP5_SYSCONFIG);
       
  2929 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  2930 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  2931 	SetClockState( EClkMcBsp5_F, EClkOff );
       
  2932 	SetClockState( EClkMcBsp5_I, EClkOff );
       
  2933 
       
  2934 	// McSPI
       
  2935 	r = AsspRegister::Read32(KMCSPI1_SYSCONFIG);
       
  2936 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  2937 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  2938 	SetClockState( EClkMcSpi1_F, EClkOff );
       
  2939 	SetClockState( EClkMcSpi1_I, EClkOff );
       
  2940 	r = AsspRegister::Read32(KMCSPI2_SYSCONFIG);
       
  2941 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  2942 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  2943 	SetClockState( EClkMcSpi2_F, EClkOff );
       
  2944 	SetClockState( EClkMcSpi2_I, EClkOff );
       
  2945 	r = AsspRegister::Read32(KMCSPI3_SYSCONFIG);
       
  2946 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  2947 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  2948 	SetClockState( EClkMcSpi3_F, EClkOff );
       
  2949 	SetClockState( EClkMcSpi3_I, EClkOff );
       
  2950 	r = AsspRegister::Read32(KMCSPI4_SYSCONFIG);
       
  2951 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  2952 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  2953 	SetClockState( EClkMcSpi4_F, EClkOff );
       
  2954 	SetClockState( EClkMcSpi4_I, EClkOff );
       
  2955 
       
  2956 	// UART
       
  2957 	TInt debugport = Kern::SuperPage().iDebugPort;
       
  2958 	if( debugport != 0 )
       
  2959 		{
       
  2960 		r = AsspRegister::Read32(KUART1_SYSC);
       
  2961 		__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  2962 		SetClockState( EClkUart1_F, EClkOff );
       
  2963 		SetClockState( EClkUart1_I, EClkOff );
       
  2964 		}
       
  2965 	if( debugport != 1 )
       
  2966 		{
       
  2967 		r = AsspRegister::Read32(KUART2_SYSC);
       
  2968 		__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  2969 		SetClockState( EClkUart2_F, EClkOff );
       
  2970 		SetClockState( EClkUart2_I, EClkOff );
       
  2971 		}
       
  2972 	if( debugport != 2 )
       
  2973 		{
       
  2974 		r = AsspRegister::Read32(KUART3_SYSC);
       
  2975 		__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  2976 		SetClockState( EClkUart3_F, EClkOff );
       
  2977 		SetClockState( EClkUart3_I, EClkOff );
       
  2978 		}
       
  2979 
       
  2980 	// I2C KI2C1_SYSC
       
  2981 	r = AsspRegister::Read32(KI2C1_SYSC);
       
  2982 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  2983 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  2984 	SetClockState( EClkI2c1_F, EClkOff );
       
  2985 	SetClockState( EClkI2c1_I, EClkOff );
       
  2986 	r = AsspRegister::Read32(KI2C2_SYSC);
       
  2987 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  2988 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  2989 	SetClockState( EClkI2c2_F, EClkOff );
       
  2990 	SetClockState( EClkI2c2_I, EClkOff );
       
  2991 	r = AsspRegister::Read32(KI2C3_SYSC);
       
  2992 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  2993 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  2994 	SetClockState( EClkI2c3_F, EClkOff );
       
  2995 	SetClockState( EClkI2c3_I, EClkOff );
       
  2996 
       
  2997 	// GPT
       
  2998 	r = AsspRegister::Read32(KTI1OCP_CFG);
       
  2999 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  3000 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  3001 	SetClockState( EClkGpt1_F, EClkOff );
       
  3002 	SetClockState( EClkGpt1_I, EClkOff );
       
  3003 	r = AsspRegister::Read32(KTI2OCP_CFG);
       
  3004 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  3005 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  3006 	SetClockState( EClkGpt2_F, EClkOff );
       
  3007 	SetClockState( EClkGpt2_I, EClkOff );
       
  3008 	r = AsspRegister::Read32(KTI3OCP_CFG);
       
  3009 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  3010 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  3011 	SetClockState( EClkGpt3_F, EClkOff );
       
  3012 	SetClockState( EClkGpt3_I, EClkOff );
       
  3013 	r = AsspRegister::Read32(KTI4OCP_CFG);
       
  3014 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  3015 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  3016 	SetClockState( EClkGpt4_F, EClkOff );
       
  3017 	SetClockState( EClkGpt4_I, EClkOff );
       
  3018 	r = AsspRegister::Read32(KTI5OCP_CFG);
       
  3019 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  3020 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  3021 	SetClockState( EClkGpt5_F, EClkOff );
       
  3022 	SetClockState( EClkGpt5_I, EClkOff );
       
  3023 	r = AsspRegister::Read32(KTI6OCP_CFG);
       
  3024 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  3025 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  3026 	SetClockState( EClkGpt6_F, EClkOff );
       
  3027 	SetClockState( EClkGpt6_I, EClkOff );
       
  3028 	r = AsspRegister::Read32(KTI7OCP_CFG);
       
  3029 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  3030 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  3031 	SetClockState( EClkGpt7_F, EClkOff );
       
  3032 	SetClockState( EClkGpt7_I, EClkOff );
       
  3033 	r = AsspRegister::Read32(KTI8OCP_CFG);
       
  3034 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  3035 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  3036 	SetClockState( EClkGpt8_F, EClkOff );
       
  3037 	SetClockState( EClkGpt8_I, EClkOff );
       
  3038 	r = AsspRegister::Read32(KTI9OCP_CFG);
       
  3039 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  3040 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  3041 	SetClockState( EClkGpt9_F, EClkOff );
       
  3042 	SetClockState( EClkGpt9_I, EClkOff );
       
  3043 	r = AsspRegister::Read32(KTI10OCP_CFG);
       
  3044 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  3045 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  3046 	SetClockState( EClkGpt10_F, EClkOff );
       
  3047 	SetClockState( EClkGpt10_I, EClkOff );
       
  3048 	r = AsspRegister::Read32(KTI11OCP_CFG);
       
  3049 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  3050 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  3051 	SetClockState( EClkGpt11_F, EClkOff );
       
  3052 	SetClockState( EClkGpt11_I, EClkOff );
       
  3053 
       
  3054 	// WDT
       
  3055 	r = AsspRegister::Read32(KWD2_SYSCONFIG);
       
  3056 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  3057 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  3058 	SetClockState( EClkWdt2_F, EClkOff );
       
  3059 	SetClockState( EClkWdt2_I, EClkOff );
       
  3060 	r = AsspRegister::Read32(KWD3_SYSCONFIG);
       
  3061 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  3062 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  3063 	SetClockState( EClkWdt3_F, EClkOff );
       
  3064 	SetClockState( EClkWdt3_I, EClkOff );
       
  3065 
       
  3066 	// GPIO
       
  3067 	/*
       
  3068 	r = AsspRegister::Read32(KGPIO1_SYSCONFIG);
       
  3069 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  3070 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  3071 	_BitClearSet(KCM_FCLKEN_WKUP, 1 << 3, 0);
       
  3072 	_BitClearSet(KCM_ICLKEN_WKUP, 1 << 3, 0);
       
  3073 	
       
  3074 	//r = AsspRegister::Read32(KGPIO2_SYSCONFIG);
       
  3075 	//__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  3076 	//__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  3077 	//_BitClearSet(KCM_FCLKEN_PER, 1 << 13, 0);
       
  3078 	//_BitClearSet(KCM_ICLKEN_PER, 1 << 13, 0);
       
  3079 	r = AsspRegister::Read32(KGPIO3_SYSCONFIG);
       
  3080 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  3081 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  3082 	_BitClearSet(KCM_FCLKEN_PER, 1 << 14, 0);
       
  3083 	_BitClearSet(KCM_ICLKEN_PER, 1 << 14, 0);
       
  3084 	r = AsspRegister::Read32(KGPIO4_SYSCONFIG);
       
  3085 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  3086 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  3087 	_BitClearSet(KCM_FCLKEN_PER, 1 << 15, 0);
       
  3088 	_BitClearSet(KCM_ICLKEN_PER, 1 << 15, 0);
       
  3089 	r = AsspRegister::Read32(KGPIO5_SYSCONFIG);
       
  3090 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  3091 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  3092 	_BitClearSet(KCM_FCLKEN_PER, 1 << 16, 0);
       
  3093 	_BitClearSet(KCM_ICLKEN_PER, 1 << 16, 0);
       
  3094 	r = AsspRegister::Read32(KGPIO6_SYSCONFIG);
       
  3095 	__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
       
  3096 	__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
       
  3097 	_BitClearSet(KCM_FCLKEN_PER, 1 << 17, 0);
       
  3098 	_BitClearSet(KCM_ICLKEN_PER, 1 << 17, 0);
       
  3099 	*/
       
  3100 	__SPIN_UNLOCK_IRQRESTORE(iLock, irq);
       
  3101 	}
       
  3102 
       
  3103 } // end namespace Prcm
       
  3104 
       
  3105 
       
  3106 NONSHARABLE_CLASS( TPrcmInterruptDispatch ): public MInterruptDispatcher
       
  3107 	{
       
  3108 	public:
       
  3109 		TInt Init();
       
  3110 		virtual TInt Bind(TInt aId, TIsr anIsr, TAny* aPtr) ;
       
  3111 		virtual TInt Unbind(TInt aId);
       
  3112 		virtual TInt Enable(TInt aId);
       
  3113 		virtual TInt Disable(TInt aId);
       
  3114 		virtual TInt Clear(TInt aId);
       
  3115 		virtual TInt SetPriority(TInt aId, TInt aPriority);
       
  3116 
       
  3117 	private:
       
  3118 		static void Spurious( TAny* aId );
       
  3119 		static void Dispatch( TAny* aParam );
       
  3120 	};
       
  3121 
       
  3122 SInterruptHandler Handlers[ Prcm::KInterruptCount ];
       
  3123 TInt TheRootInterruptEnable = 0;
       
  3124 TSpinLock iIntLock(/*TSpinLock::EOrderGenericIrqLow0*/);
       
  3125 TPrcmInterruptDispatch TheIntDispatcher;
       
  3126 
       
  3127 void TPrcmInterruptDispatch::Spurious( TAny* aId )
       
  3128 	{
       
  3129 	Kern::Fault( "PRCM:Spurious", (TInt)aId );
       
  3130 	}
       
  3131 
       
  3132 void TPrcmInterruptDispatch::Dispatch( TAny* /*aParam*/ )
       
  3133 	{
       
  3134 	TUint32 status = AsspRegister::Read32( KPRM_IRQSTATUS_MPU )
       
  3135 					bitand AsspRegister::Read32( KPRM_IRQENABLE_MPU );
       
  3136 
       
  3137 	for( TInt i = 0; (status) && (i < Prcm::KInterruptCount); ++i )
       
  3138 		{
       
  3139 		if( status bitand 1 )
       
  3140 			{
       
  3141 			(*Handlers[i].iIsr)( Handlers[i].iPtr );
       
  3142 			}
       
  3143 		status >>= 1;
       
  3144 		}
       
  3145 	}
       
  3146 
       
  3147 TInt TPrcmInterruptDispatch::Init()
       
  3148 	{
       
  3149 	// Disable all interrupts
       
  3150 	AsspRegister::Write32( KPRM_IRQENABLE_MPU, 0 );
       
  3151 	AsspRegister::Write32( KPRM_IRQSTATUS_MPU, KSetAll );
       
  3152 
       
  3153 	// Bind all to spurious handler
       
  3154 	for( TInt i = 0; i < Prcm::KInterruptCount; ++i )
       
  3155 		{
       
  3156 		Handlers[i].iIsr = TPrcmInterruptDispatch::Spurious;
       
  3157 		Handlers[i].iPtr = (TAny*)(i + (EIrqRangeBasePrcm << KIrqRangeIndexShift));
       
  3158 		}
       
  3159 
       
  3160 	TInt r = Interrupt::Bind( EOmap3530_IRQ11_PRCM_MPU_IRQ, TPrcmInterruptDispatch::Dispatch, this );
       
  3161 	if( KErrNone == r )
       
  3162 		{
       
  3163 		Register( EIrqRangeBasePrcm );
       
  3164 		}
       
  3165 	return r;
       
  3166 	}
       
  3167 
       
  3168 TInt TPrcmInterruptDispatch::Bind(TInt aId, TIsr aIsr, TAny* aPtr)
       
  3169 	{
       
  3170 	TUint id = aId bitand KIrqNumberMask;
       
  3171 	TInt r;
       
  3172 
       
  3173 	if( id < Prcm::KInterruptCount )
       
  3174 		{
       
  3175 		if( Handlers[ id ].iIsr != TPrcmInterruptDispatch::Spurious )
       
  3176 			{
       
  3177 			r = KErrInUse;
       
  3178 			}
       
  3179 		else
       
  3180 			{
       
  3181 			Handlers[ id ].iIsr = aIsr;
       
  3182 			Handlers[ id ].iPtr = aPtr;
       
  3183 			r = KErrNone;
       
  3184 			}
       
  3185 		}
       
  3186 	else
       
  3187 		{
       
  3188 		r = KErrArgument;
       
  3189 		}
       
  3190 	return r;
       
  3191 	}
       
  3192 
       
  3193 TInt TPrcmInterruptDispatch::Unbind(TInt aId)
       
  3194 	{
       
  3195 	TUint id = aId bitand KIrqNumberMask;
       
  3196 	TInt r;
       
  3197 
       
  3198 	if( id < Prcm::KInterruptCount )
       
  3199 		{
       
  3200 		if( Handlers[ id ].iIsr == TPrcmInterruptDispatch::Spurious )
       
  3201 			{
       
  3202 			r = KErrGeneral;
       
  3203 			}
       
  3204 		else
       
  3205 			{
       
  3206 			Handlers[ id ].iIsr = TPrcmInterruptDispatch::Spurious;
       
  3207 			r = KErrNone;
       
  3208 			}
       
  3209 		}
       
  3210 	else
       
  3211 		{
       
  3212 		r = KErrArgument;
       
  3213 		}
       
  3214 	return r;
       
  3215 	}
       
  3216 
       
  3217 TInt TPrcmInterruptDispatch::Enable(TInt aId)
       
  3218 	{
       
  3219 	TUint id = aId bitand KIrqNumberMask;
       
  3220 
       
  3221 	if( id < Prcm::KInterruptCount )
       
  3222 		{
       
  3223 		TInt irq = __SPIN_LOCK_IRQSAVE(iIntLock);
       
  3224 		if( ++TheRootInterruptEnable == 1 )
       
  3225 			{
       
  3226 			Interrupt::Enable( EOmap3530_IRQ11_PRCM_MPU_IRQ );
       
  3227 			}
       
  3228 		Prcm::_BitClearSet( KPRM_IRQENABLE_MPU, KClearNone, 1 << id );
       
  3229 		__SPIN_UNLOCK_IRQRESTORE(iIntLock, irq);
       
  3230 		return KErrNone;
       
  3231 		}
       
  3232 	else
       
  3233 		{
       
  3234 		return KErrArgument;
       
  3235 		}
       
  3236 	}
       
  3237 
       
  3238 TInt TPrcmInterruptDispatch::Disable(TInt aId)
       
  3239 	{
       
  3240 	TUint id = aId bitand KIrqNumberMask;
       
  3241 
       
  3242 	if( id < Prcm::KInterruptCount )
       
  3243 		{
       
  3244 		TInt irq = __SPIN_LOCK_IRQSAVE(iIntLock);
       
  3245 		if( --TheRootInterruptEnable == 0 )
       
  3246 			{
       
  3247 			Interrupt::Disable( EOmap3530_IRQ11_PRCM_MPU_IRQ );
       
  3248 			}
       
  3249 		Prcm::_BitClearSet( KPRM_IRQENABLE_MPU, 1 << id, KSetNone );
       
  3250 		__SPIN_UNLOCK_IRQRESTORE(iIntLock, irq);
       
  3251 		return KErrNone;
       
  3252 		}
       
  3253 	else
       
  3254 		{
       
  3255 		return KErrArgument;
       
  3256 		}
       
  3257 	}
       
  3258 
       
  3259 TInt TPrcmInterruptDispatch::Clear(TInt aId)
       
  3260 	{
       
  3261 	TUint id = aId bitand KIrqNumberMask;
       
  3262 	TInt r;
       
  3263 
       
  3264 	if( id < Prcm::KInterruptCount )
       
  3265 		{
       
  3266 		AsspRegister::Write32( KPRM_IRQSTATUS_MPU, 1 << id );
       
  3267 		r = KErrNone;
       
  3268 		}
       
  3269 	else
       
  3270 		{
       
  3271 		r = KErrArgument;
       
  3272 		}
       
  3273 	return r;
       
  3274 	}
       
  3275 
       
  3276 TInt TPrcmInterruptDispatch::SetPriority(TInt anId, TInt aPriority)
       
  3277 	{
       
  3278 	return KErrNotSupported;
       
  3279 	}
       
  3280 
       
  3281 
       
  3282 
       
  3283 DECLARE_STANDARD_EXTENSION()
       
  3284 	{
       
  3285 	return TheIntDispatcher.Init();
       
  3286 	}
       
  3287 
       
  3288 
       
  3289 
       
  3290 
       
  3291