0
+ − 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"
59
+ − 28
#include "prcm.h"
0
+ − 29
+ − 30
+ − 31
+ − 32
namespace Prcm
+ − 33
{
+ − 34
TSpinLock iLock(/*TSpinLock::EOrderGenericIrqLow0*/); // prevents concurrent access to the prcm hardware registers
+ − 35
+ − 36
void Panic( TPanic aPanic )
+ − 37
{
+ − 38
Kern::Fault( "PRCM", aPanic );
+ − 39
}
+ − 40
+ − 41
void InternalPanic( TInt aLine )
+ − 42
{
+ − 43
Kern::Fault( "PRCMINT", aLine );
+ − 44
}
+ − 45
+ − 46
FORCE_INLINE void _BitClearSet( TUint32 aRegister, TUint32 aClearMask, TUint32 aSetMask )
+ − 47
{
+ − 48
volatile TUint32* pR = (volatile TUint32*)aRegister;
+ − 49
*pR = (*pR & ~aClearMask) | aSetMask;
+ − 50
}
+ − 51
+ − 52
FORCE_INLINE void _LockedBitClearSet( TUint32 aRegister, TUint32 aClearMask, TUint32 aSetMask )
+ − 53
{
+ − 54
volatile TUint32* pR = (volatile TUint32*)aRegister;
+ − 55
TInt irq = __SPIN_LOCK_IRQSAVE(iLock);
+ − 56
*pR = (*pR & ~aClearMask) | aSetMask;
+ − 57
__SPIN_UNLOCK_IRQRESTORE(iLock, irq);
+ − 58
}
+ − 59
+ − 60
+ − 61
EXPORT_C void SetPllConfig( TPll aPll, const TPllConfiguration& aConfig )
+ − 62
{
+ − 63
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetPllConfig(%x)", aPll ) );
+ − 64
+ − 65
__ASSERT_DEBUG( (TUint)aPll < KSupportedPllCount, Panic( ESetPllConfigBadPll ) );
+ − 66
+ − 67
const TPllControlInfo& inf = KPllControlInfo[ aPll ];
+ − 68
+ − 69
__ASSERT_DEBUG( aConfig.iDivider <= KPllMaximumDivider, Panic( ESetPllConfigBadDivider ) );
+ − 70
__ASSERT_DEBUG( aConfig.iMultiplier <= KPllMaximumMultiplier, Panic( ESetPllConfigBadMultiplier ) );
+ − 71
__ASSERT_DEBUG( ((TUint)aConfig.iFreqRange <= EPllRange_1750_2100)
+ − 72
&& ((TUint)aConfig.iFreqRange >= EPllRange_075_100), Panic( ESetPllConfigBadFreqRange ) );
+ − 73
__ASSERT_DEBUG( ((TUint)aConfig.iRamp <= EPllRamp40us), Panic( ESetPllConfigBadRamp ) );
+ − 74
__ASSERT_DEBUG( (TUint)aConfig.iDrift <= EPllDriftGuardEnabled, Panic( ESetPllConfigBadDrift ) );
+ − 75
+ − 76
TUint mult = (aConfig.iMultiplier bitand KPllMultiplierMask) << inf.iMultShift;
+ − 77
TUint div = ((aConfig.iDivider - 1) bitand KPllDividerMask) << inf.iDivShift;
+ − 78
TUint range = (aConfig.iFreqRange bitand KPllFreqRangeMask) << inf.iFreqSelShift;
+ − 79
TUint ramp = (aConfig.iRamp bitand KPllRampMask) << inf.iRampShift;
+ − 80
TUint drift = (aConfig.iDrift == EPllDriftGuardEnabled) ? (1 << inf.iDriftShift) : 0;
+ − 81
+ − 82
TInt irq = __SPIN_LOCK_IRQSAVE(iLock);
+ − 83
// We must apply frequency range setting before new multuplier and divider
+ − 84
TUint clearMaskConfig = (KPllFreqRangeMask << inf.iFreqSelShift)
+ − 85
bitor (KPllRampMask << inf.iRampShift)
+ − 86
bitor (1 << inf.iDriftShift);
+ − 87
_BitClearSet( inf.iConfigRegister, clearMaskConfig, range | ramp | drift );
+ − 88
+ − 89
TUint clearMaskMulDiv = (KPllMultiplierMask << inf.iMultShift) bitor (KPllDividerMask << inf.iDivShift);
+ − 90
_BitClearSet( inf.iMulDivRegister, clearMaskMulDiv, mult | div );
+ − 91
__SPIN_UNLOCK_IRQRESTORE(iLock, irq);
+ − 92
}
+ − 93
+ − 94
EXPORT_C void PllConfig( TPll aPll, TPllConfiguration& aConfigResult )
+ − 95
{
+ − 96
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PllConfig(%x)", aPll ) );
+ − 97
+ − 98
__ASSERT_DEBUG( (TUint)aPll < KSupportedPllCount, Panic( EGetPllConfigBadPll ) );
+ − 99
+ − 100
const TPllControlInfo& inf = KPllControlInfo[ aPll ];
+ − 101
+ − 102
TUint32 config = AsspRegister::Read32( inf.iConfigRegister );
+ − 103
TUint32 muldiv = AsspRegister::Read32( inf.iMulDivRegister );
+ − 104
+ − 105
aConfigResult.iMultiplier = (muldiv >> inf.iMultShift) bitand KPllMultiplierMask;
+ − 106
aConfigResult.iDivider = 1 + ((muldiv >> inf.iDivShift) bitand KPllDividerMask);
+ − 107
aConfigResult.iFreqRange = static_cast<TPllFrequencyRange>((config >> inf.iFreqSelShift) bitand KPllFreqRangeMask);
+ − 108
aConfigResult.iRamp = static_cast<TPllRamp>((config >> inf.iRampShift ) bitand KPllRampMask);
+ − 109
aConfigResult.iDrift = (config >> inf.iDriftShift ) bitand 1 ? EPllDriftGuardEnabled : EPllDriftGuardDisabled;
+ − 110
+ − 111
__KTRACE_OPT( KPRCM, Kern::Printf( "DPLL%d: m=%d, d=%d, fr=%d, r=%d, dr=%d",
+ − 112
aPll + 1,
+ − 113
aConfigResult.iMultiplier,
+ − 114
aConfigResult.iDivider,
+ − 115
aConfigResult.iFreqRange,
+ − 116
aConfigResult.iRamp,
+ − 117
aConfigResult.iDrift ) );
+ − 118
}
+ − 119
+ − 120
EXPORT_C void SetPllLp( TPll aPll, TLpMode aLpMode )
+ − 121
{
+ − 122
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetPllLp(%x)", aPll ) );
+ − 123
+ − 124
__ASSERT_DEBUG( (TUint)aPll < KSupportedPllCount, Panic( ESetPllLpBadPll ) );
+ − 125
__ASSERT_DEBUG( (aLpMode == ENormalMode)
+ − 126
|| (aLpMode == ELpMode), Panic( ESetPllLpBadMode ) );
+ − 127
+ − 128
const TPllControlInfo& inf = KPllControlInfo[ aPll ];
+ − 129
+ − 130
TUint32 clear = 1 << inf.iLpShift;
+ − 131
TUint32 set = 0;
+ − 132
+ − 133
if( ELpMode == aLpMode )
+ − 134
{
+ − 135
set = clear;
+ − 136
clear = 0;
+ − 137
}
+ − 138
+ − 139
_LockedBitClearSet( inf.iConfigRegister, clear, set );
+ − 140
}
+ − 141
+ − 142
EXPORT_C TLpMode PllLp( TPll aPll )
+ − 143
{
+ − 144
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PllLp(%x)", aPll ) );
+ − 145
+ − 146
__ASSERT_DEBUG( (TUint)aPll < KSupportedPllCount, Panic( EGetPllLpBadPll ) );
+ − 147
+ − 148
const TPllControlInfo& inf = KPllControlInfo[ aPll ];
+ − 149
+ − 150
TUint32 config = AsspRegister::Read32( inf.iConfigRegister );
+ − 151
if( 0 == ((config >> inf.iLpShift) bitand 1) )
+ − 152
{
+ − 153
return ENormalMode;
+ − 154
}
+ − 155
else
+ − 156
{
+ − 157
return ELpMode;
+ − 158
}
+ − 159
}
+ − 160
+ − 161
+ − 162
EXPORT_C void SetPllMode( TPll aPll, TPllMode aPllMode )
+ − 163
{
+ − 164
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetPllMode(%x;%x)", aPll, aPllMode ) );
+ − 165
__ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( ESetPllModeBadClock ) );
+ − 166
+ − 167
TUint32 newMode;
+ − 168
TUint32 newAuto = KPllAutoOff;
+ − 169
+ − 170
switch( aPllMode )
+ − 171
{
+ − 172
default:
+ − 173
__DEBUG_ONLY( Panic( ESetPllModeBadMode ) );
+ − 174
return;
+ − 175
+ − 176
case EPllStop:
+ − 177
newMode = KPllModeStop;
+ − 178
break;
+ − 179
+ − 180
case EPllBypass:
+ − 181
newMode = KPllModeBypass;
+ − 182
break;
+ − 183
+ − 184
case EPllAuto:
+ − 185
newAuto = KPllAutoOn;
+ − 186
// fall through...
+ − 187
+ − 188
case EPllRun:
+ − 189
newMode = KPllModeLock;
+ − 190
break;
+ − 191
+ − 192
case EPllFastRelock:
+ − 193
newMode = KPllModeFastRelock;
+ − 194
break;
+ − 195
}
+ − 196
+ − 197
TInt irq = __SPIN_LOCK_IRQSAVE(iLock);
23
+ − 198
0
+ − 199
_BitClearSet( KPllMode[ aPll ].iModeRegister,
+ − 200
KPllModeMask << KPllMode[ aPll ].iModeShift,
+ − 201
newMode << KPllMode[ aPll ].iModeShift );
+ − 202
+ − 203
_BitClearSet( KPllMode[ aPll ].iAutoRegister,
+ − 204
KPllAutoMask << KPllMode[ aPll ].iAutoShift,
+ − 205
newAuto << KPllMode[ aPll ].iAutoShift );
23
+ − 206
0
+ − 207
__SPIN_UNLOCK_IRQRESTORE(iLock, irq);
+ − 208
}
+ − 209
+ − 210
+ − 211
EXPORT_C TPllMode PllMode( TPll aPll )
+ − 212
{
+ − 213
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PllMode(%x)", aPll ) );
+ − 214
__ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( ESetPllModeBadClock ) );
+ − 215
+ − 216
TUint32 mode = (AsspRegister::Read32( KPllMode[ aPll ].iModeRegister ) >> KPllMode[ aPll ].iModeShift) bitand KPllModeMask;
+ − 217
TUint32 autoSet = (AsspRegister::Read32( KPllMode[ aPll ].iAutoRegister ) >> KPllMode[ aPll ].iAutoShift) bitand KPllAutoMask;
+ − 218
23
+ − 219
static const TPllMode modeTable[8][2] =
0
+ − 220
{ // auto disabled auto enabled
+ − 221
{ EPllStop, EPllStop }, // not possible
+ − 222
{ EPllStop, EPllStop },
+ − 223
{ EPllStop, EPllStop }, // not possible
+ − 224
{ EPllStop, EPllStop }, // not possible
+ − 225
{ EPllStop, EPllStop }, // not possible
+ − 226
{ EPllBypass, EPllBypass },
+ − 227
{ EPllFastRelock, EPllAuto },
+ − 228
{ EPllRun, EPllAuto },
+ − 229
};
+ − 230
return modeTable[ mode ][ (KPllAutoOff == autoSet) ? 0 : 1 ];
+ − 231
}
+ − 232
+ − 233
EXPORT_C void CalcPllFrequencyRange( TPll aPll, TPllConfiguration& aConfig )
+ − 234
{
+ − 235
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::CalcPllFrequencyRange(%x)", aPll ) );
+ − 236
+ − 237
struct TFreqSelRange
+ − 238
{
+ − 239
TUint iMin;
+ − 240
TUint iMax;
+ − 241
TPllFrequencyRange iSetting;
+ − 242
};
+ − 243
+ − 244
const TFreqSelRange KRanges[] =
+ − 245
{
+ − 246
{ 750000, 1000000, EPllRange_075_100 },
+ − 247
{ 1000001, 1250000, EPllRange_100_125 },
+ − 248
{ 1250001, 1500000, EPllRange_125_150 },
+ − 249
{ 1500001, 1750000, EPllRange_150_175 },
+ − 250
{ 1750001, 2100000, EPllRange_175_210 },
+ − 251
{ 7500000, 10000000, EPllRange_750_1000 },
+ − 252
{ 10000001, 12500000, EPllRange_1000_1250 },
+ − 253
{ 12500001, 15000000, EPllRange_1250_1500 },
+ − 254
{ 15000001, 17500000, EPllRange_1500_1750 },
+ − 255
{ 17500001, 21000000, EPllRange_1750_2100 },
+ − 256
{ 0, 0, EPllRange_1750_2100 }
+ − 257
};
+ − 258
+ − 259
// We have to work out the internal frequency from the source clock frequency and the
+ − 260
// divider factor N
+ − 261
+ − 262
const TUint32 divider = aConfig.iDivider;
+ − 263
+ − 264
TInt found = -1;
+ − 265
+ − 266
if( divider > 0 )
+ − 267
{
+ − 268
TUint fInternal = ClockFrequency( EClkSysClk ) / divider;
+ − 269
+ − 270
// Find an appropriate range
+ − 271
for( TInt i = 0; KRanges[i].iMax > 0; ++i )
+ − 272
{
+ − 273
if( fInternal < KRanges[i].iMin )
+ − 274
{
+ − 275
// We've passed all possible ranges, work out whether current or previous is nearest
+ − 276
__DEBUG_ONLY( Panic( EPllInternalFrequencyOutOfRange ) );
+ − 277
+ − 278
if( i > 0 )
+ − 279
{
+ − 280
// How near are we to minimum of current range?
+ − 281
TUint currentDiff = KRanges[i].iMin - fInternal;
+ − 282
+ − 283
// How near are we to maximum of previous range?
+ − 284
TUint prevDiff = fInternal - KRanges[i - 1].iMax;
+ − 285
+ − 286
found = (prevDiff < currentDiff) ? i - 1 : i;
+ − 287
}
+ − 288
else
+ − 289
{
+ − 290
// it's below minimum, so use minimum range
+ − 291
found = 0;
+ − 292
}
+ − 293
break;
+ − 294
}
+ − 295
else if( (KRanges[i].iMin <= fInternal) && (KRanges[i].iMax >= fInternal) )
+ − 296
{
+ − 297
found = i;
+ − 298
break;
+ − 299
}
+ − 300
}
+ − 301
+ − 302
}
+ − 303
// If we've fallen off end of list, use maximum setting
+ − 304
__ASSERT_DEBUG( found >= 0, Panic( EPllInternalFrequencyOutOfRange ) );
+ − 305
aConfig.iFreqRange = (found >= 0) ? KRanges[ found ].iSetting : EPllRange_1750_2100;
+ − 306
}
+ − 307
+ − 308
+ − 309
EXPORT_C void AutoSetPllLpMode( TPll aPll )
+ − 310
{
+ − 311
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PllMode(%x)", aPll ) );
+ − 312
__ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( ESetPllModeBadClock ) );
+ − 313
+ − 314
const TUint32 reg = KPllControlInfo[ aPll ].iConfigRegister;
+ − 315
const TUint shift = KPllControlInfo[ aPll ].iLpShift;
+ − 316
+ − 317
TUint freq = ClockFrequency( KPllToClock[ aPll ] );
+ − 318
TUint32 clear = 1 << shift;
+ − 319
TUint32 set = 0;
+ − 320
if( freq <= KPllLpModeMaximumFrequency )
+ − 321
{
+ − 322
// LP mode can be enabled
+ − 323
set = clear;
+ − 324
clear = 0;
+ − 325
}
+ − 326
_LockedBitClearSet( reg, clear, set );
+ − 327
}
+ − 328
+ − 329
EXPORT_C TBool PllIsLocked( TPll aPll )
+ − 330
{
+ − 331
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PllIsLocked(%x)", aPll ) );
+ − 332
__ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( EPllIsLockedBadPll ) );
+ − 333
+ − 334
TUint32 reg = KPllControlInfo[ aPll ].iStatusRegister;
+ − 335
TUint32 lockMask = 1 << KPllControlInfo[ aPll ].iLockBit;
+ − 336
+ − 337
return ( 0 != (AsspRegister::Read32( reg ) bitand lockMask) );
+ − 338
}
+ − 339
+ − 340
EXPORT_C void WaitForPllLock( TPll aPll )
+ − 341
{
+ − 342
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::WaitForPllLock(%x)", aPll ) );
+ − 343
__ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( EWaitForPllLockBadPll ) );
+ − 344
+ − 345
TUint32 reg = KPllControlInfo[ aPll ].iStatusRegister;
+ − 346
TUint32 lockMask = 1 << KPllControlInfo[ aPll ].iLockBit;
+ − 347
+ − 348
while( 0 == (AsspRegister::Read32( reg ) bitand lockMask) );
+ − 349
}
+ − 350
+ − 351
EXPORT_C void SetPllBypassDivider( TPll aPll, TBypassDivider aDivider )
+ − 352
{
+ − 353
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetPllBypassDivider(%x;%x)", aPll, aDivider ) );
+ − 354
__ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( ESetPllBypassDividerBadPll ) );
+ − 355
__ASSERT_DEBUG( (TUint)aDivider <= EBypassDiv4, Panic( ESetPllBypassDividerBadDivider ) );
+ − 356
+ − 357
static const TUint8 KLookupTable[] =
+ − 358
{
+ − 359
1, // EBypassDiv1
+ − 360
2, // EBypassDiv2
+ − 361
4. // EBypassDiv4
+ − 362
};
+ − 363
+ − 364
TUint32 div = KLookupTable[ aDivider ];
+ − 365
+ − 366
switch( aPll )
+ − 367
{
+ − 368
case EDpll1:
+ − 369
_LockedBitClearSet( KCM_CLKSEL1_PLL_MPU, KBit19 | KBit20 | KBit21, div << 19 );
+ − 370
break;
+ − 371
+ − 372
case EDpll2:
+ − 373
_LockedBitClearSet( KCM_CLKSEL1_PLL_IVA2, KBit19 | KBit20 | KBit21, div << 19 );
+ − 374
break;
+ − 375
+ − 376
default:
+ − 377
break;
+ − 378
}
+ − 379
}
+ − 380
+ − 381
EXPORT_C TBypassDivider PllBypassDivider( TPll aPll )
+ − 382
{
+ − 383
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PllBypassDivider(%x)", aPll ) );
+ − 384
__ASSERT_DEBUG( (TUint)aPll <= EDpll5, Panic( EPllBypassDividerBadPll ) );
23
+ − 385
0
+ − 386
TUint div = 1;
+ − 387
+ − 388
switch( aPll )
+ − 389
{
+ − 390
case EDpll1:
+ − 391
div = (AsspRegister::Read32( KCM_CLKSEL1_PLL_MPU ) >> 19) bitand 0x7;
+ − 392
break;
+ − 393
+ − 394
case EDpll2:
+ − 395
div = (AsspRegister::Read32( KCM_CLKSEL1_PLL_IVA2 ) >> 19) bitand 0x7;
+ − 396
break;
+ − 397
+ − 398
default:
+ − 399
break;
+ − 400
}
+ − 401
+ − 402
TBypassDivider result = EBypassDiv1;
+ − 403
+ − 404
if( 2 == div )
+ − 405
{
+ − 406
result = EBypassDiv2;
+ − 407
}
+ − 408
else if( 4 == div )
+ − 409
{
+ − 410
result = EBypassDiv4;
+ − 411
}
+ − 412
+ − 413
return result;
+ − 414
}
+ − 415
+ − 416
EXPORT_C void SetDivider( TClock aClock, TUint aDivide )
+ − 417
{
+ − 418
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetDivider(%x;%x)", aClock, aDivide ) );
+ − 419
+ − 420
__ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( ESetDividerBadClock ) );
+ − 421
+ − 422
const TDividerInfo& inf = KDividerInfo[ aClock ];
23
+ − 423
0
+ − 424
TUint32 div = aDivide; // most common case, special cases handled below
+ − 425
+ − 426
switch( inf.iDivType )
+ − 427
{
+ − 428
case EDivUsimClk:
+ − 429
// Special case, not suppored by this function - use SetUsimClockDivider()
+ − 430
return;
+ − 431
+ − 432
default:
+ − 433
case EDivNotSupported:
+ − 434
Panic( ESetDividerUnsupportedClock );
+ − 435
return;
+ − 436
+ − 437
case EDiv_1_2:
+ − 438
if( (1 != aDivide ) && (2 != aDivide ) )
+ − 439
{
+ − 440
__DEBUG_ONLY( Panic( ESetDividerBadDivider ) );
+ − 441
return;
+ − 442
}
+ − 443
break;
+ − 444
+ − 445
case EDivCore_1_2_4:
+ − 446
if( (1 != aDivide ) && (2 != aDivide ) && (3 != aDivide) )
+ − 447
{
+ − 448
__DEBUG_ONLY( Panic( ESetDividerBadDivider ) );
+ − 449
return;
+ − 450
}
+ − 451
break;
+ − 452
+ − 453
case EDivCore_3_4_6_96M:
+ − 454
{
+ − 455
switch( aDivide )
+ − 456
{
+ − 457
default:
+ − 458
__DEBUG_ONLY( Panic( ESetDividerBadDivider ) );
+ − 459
return;
+ − 460
+ − 461
case 3:
+ − 462
div = 0;
+ − 463
break;
+ − 464
+ − 465
case 4:
+ − 466
div = 1;
+ − 467
break;
+ − 468
+ − 469
case 6:
+ − 470
div = 2;
+ − 471
break;
+ − 472
+ − 473
case 0:
+ − 474
// Special-case, use 96MHz clock
+ − 475
div = 3;
+ − 476
break;
+ − 477
}
+ − 478
break;
+ − 479
}
+ − 480
+ − 481
case EDivPll_1_To_16:
+ − 482
if( (aDivide < 1) || (aDivide > 16) )
+ − 483
{
+ − 484
__DEBUG_ONLY( Panic( ESetDividerBadDivider ) );
+ − 485
return;
+ − 486
}
+ − 487
break;
+ − 488
+ − 489
case EDivPll_1_To_31:
+ − 490
if( (aDivide < 1) || (aDivide > 16) )
+ − 491
{
+ − 492
__DEBUG_ONLY( Panic( ESetDividerBadDivider ) );
+ − 493
return;
+ − 494
}
+ − 495
break;
+ − 496
+ − 497
+ − 498
+ − 499
case EDivClkOut_1_2_4_8_16:
+ − 500
{
+ − 501
switch( aDivide )
+ − 502
{
+ − 503
default:
+ − 504
__DEBUG_ONLY( Panic( ESetDividerBadDivider ) );
+ − 505
return;
+ − 506
+ − 507
case 1:
+ − 508
div = 0;
+ − 509
break;
+ − 510
+ − 511
case 2:
+ − 512
div = 1;
+ − 513
break;
+ − 514
+ − 515
case 4:
+ − 516
div = 2;
+ − 517
break;
+ − 518
+ − 519
case 8:
+ − 520
div = 3;
+ − 521
break;
+ − 522
+ − 523
case 16:
+ − 524
div = 4;
+ − 525
break;
+ − 526
}
+ − 527
break;
+ − 528
}
+ − 529
}
+ − 530
+ − 531
// if we get here, we have a valid divider value
23
+ − 532
0
+ − 533
_LockedBitClearSet( inf.iRegister, inf.iMask, div << inf.iShift );
+ − 534
}
+ − 535
+ − 536
EXPORT_C TUint Divider( TClock aClock )
+ − 537
{
+ − 538
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::Divider(%x)", aClock ) );
+ − 539
+ − 540
__ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( EGetDividerBadClock ) );
+ − 541
+ − 542
const TDividerInfo& inf = KDividerInfo[ aClock ];
23
+ − 543
0
+ − 544
TUint32 div = ( AsspRegister::Read32( inf.iRegister ) bitand inf.iMask ) >> inf.iShift;
+ − 545
TUint result = div; // most common case
+ − 546
+ − 547
switch( inf.iDivType )
+ − 548
{
+ − 549
case EDivUsimClk:
+ − 550
return UsimDivider();
+ − 551
+ − 552
default:
+ − 553
case EDivNotSupported:
+ − 554
Panic( ESetDividerUnsupportedClock );
+ − 555
return 0xFFFFFFFF;
+ − 556
+ − 557
// These are all the standard case, where value in register is divide factor
+ − 558
case EDiv_1_2:
+ − 559
case EDivCore_1_2_4:
+ − 560
case EDivPll_1_To_16:
+ − 561
case EDivPll_1_To_31:
+ − 562
break;
+ − 563
+ − 564
case EDivCore_3_4_6_96M:
+ − 565
{
+ − 566
switch( div )
+ − 567
{
+ − 568
default:
+ − 569
// hardware value has unknown meaning
+ − 570
result = 0xFFFFFFFF;
+ − 571
+ − 572
case 0:
+ − 573
result = 3;
+ − 574
break;
+ − 575
+ − 576
case 1:
+ − 577
result = 4;
+ − 578
break;
+ − 579
+ − 580
case 2:
+ − 581
result = 6;
+ − 582
break;
+ − 583
+ − 584
case 3:
+ − 585
result = 0;
+ − 586
break;
+ − 587
}
+ − 588
break;
+ − 589
}
+ − 590
+ − 591
case EDivClkOut_1_2_4_8_16:
+ − 592
{
+ − 593
switch( div )
+ − 594
{
+ − 595
default:
+ − 596
// hardware value has unknown meaning
+ − 597
result = 0xFFFFFFFF;
+ − 598
+ − 599
case 0:
+ − 600
result = 1;
+ − 601
break;
+ − 602
+ − 603
case 1:
+ − 604
result = 2;
+ − 605
break;
+ − 606
+ − 607
case 2:
+ − 608
result = 4;
+ − 609
break;
+ − 610
+ − 611
case 3:
+ − 612
result = 8;
+ − 613
break;
+ − 614
+ − 615
case 4:
+ − 616
result = 16;
+ − 617
break;
+ − 618
}
+ − 619
break;
+ − 620
}
+ − 621
}
+ − 622
+ − 623
return result;
+ − 624
}
+ − 625
+ − 626
EXPORT_C void SetPowerDomainMode( TPowerDomain aDomain, TPowerDomainMode aMode )
+ − 627
{
+ − 628
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetPowerDomainMode(%x;%x)", aDomain, aMode ) );
+ − 629
__ASSERT_DEBUG( (TUint)aDomain < KSupportedPowerDomainCount, Panic( ESetDomainModeBadDomain ) );
+ − 630
__ASSERT_DEBUG( (TUint)aMode <= EPowerOn, Panic( ESetDomainModeBadMode ) );
+ − 631
+ − 632
__ASSERT_DEBUG( 0 != (KPowerDomainControl[ aDomain ].iAllowedMask bitand (1 << aMode)), Panic( ESetDomainModeUnsupportedMode ) );
23
+ − 633
0
+ − 634
TUint shift = KPowerDomainControl[ aDomain ].iShift;
+ − 635
+ − 636
_LockedBitClearSet( KPowerDomainControl[ aDomain ].iRegister,
+ − 637
KPowerModeMask << shift,
+ − 638
aMode << shift );
+ − 639
}
+ − 640
+ − 641
EXPORT_C TPowerDomainMode PowerDomainMode( TPowerDomain aDomain )
+ − 642
{
+ − 643
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::PowerDomainMode(%x)", aDomain ) );
+ − 644
__ASSERT_DEBUG( (TUint)aDomain < KSupportedPowerDomainCount, Panic( EGetDomainModeBadDomain ) );
+ − 645
+ − 646
TUint32 m = (AsspRegister::Read32( KPowerDomainControl[ aDomain ].iRegister ) >> KPowerDomainControl[ aDomain ].iShift) bitand KPowerModeMask;
+ − 647
return static_cast< TPowerDomainMode >( m );
+ − 648
}
+ − 649
+ − 650
EXPORT_C void SetClockState( TClock aClock, TClockState aState )
+ − 651
{
+ − 652
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetClockState(%x;%x)", aClock, aState ) );
+ − 653
+ − 654
__ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( ESetStateBadClock ) );
+ − 655
+ − 656
const TClockEnableAutoInfo& def = KClockControlTable[ aClock ];
+ − 657
+ − 658
TUint32 reg = def.iGate.iRegister;
+ − 659
TUint32 mask = def.iGate.iMask;
+ − 660
TUint32 autoReg = def.iAuto.iRegister;
+ − 661
TUint32 autoMask = def.iAuto.iMask;
+ − 662
+ − 663
TInt irq = __SPIN_LOCK_IRQSAVE(iLock);
+ − 664
+ − 665
if( EClkOn == aState )
+ − 666
{
+ − 667
_BitClearSet( reg, mask, def.iGate.iEnablePattern );
+ − 668
_BitClearSet( autoReg, autoMask, def.iAuto.iDisablePattern );
+ − 669
}
+ − 670
else if( EClkOff == aState )
+ − 671
{
+ − 672
_BitClearSet( reg, mask, def.iGate.iDisablePattern );
+ − 673
_BitClearSet( autoReg, autoMask, def.iAuto.iDisablePattern );
+ − 674
}
+ − 675
else if( EClkAuto == aState )
+ − 676
{
+ − 677
_BitClearSet( autoReg, autoMask, def.iAuto.iEnablePattern );
+ − 678
_BitClearSet( reg, mask, def.iGate.iEnablePattern );
+ − 679
}
+ − 680
+ − 681
__SPIN_UNLOCK_IRQRESTORE(iLock, irq);
+ − 682
}
+ − 683
+ − 684
EXPORT_C TClockState ClockState( TClock aClock )
+ − 685
{
+ − 686
__KTRACE_OPT( KPRCM, Kern::Printf( "+Prcm::ClockState(%x)", aClock ) );
+ − 687
+ − 688
__ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( EGetStateBadClock ) );
+ − 689
+ − 690
const TClockEnableAutoInfo& def = KClockControlTable[ aClock ];
+ − 691
+ − 692
TUint32 reg = def.iGate.iRegister;
+ − 693
TUint32 mask = def.iGate.iMask;
+ − 694
TUint32 autoReg = def.iAuto.iRegister;
+ − 695
TUint32 autoMask = def.iAuto.iMask;
+ − 696
+ − 697
TUint32 enable = AsspRegister::Read32( reg ) bitand mask;
+ − 698
TUint32 autoClock = AsspRegister::Read32( autoReg ) bitand autoMask;
+ − 699
+ − 700
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::ClockState(%x):e:%x a:%x", aClock, enable, autoClock ) );
+ − 701
+ − 702
TClockState state = EClkAuto;
+ − 703
+ − 704
// OFF = OFF
+ − 705
// ON + AUTO = AUTO
+ − 706
// ON + !AUTO = ON
+ − 707
if( def.iGate.iEnablePattern != enable )
+ − 708
{
+ − 709
state = EClkOff;
+ − 710
}
+ − 711
else if( def.iAuto.iEnablePattern != autoClock )
+ − 712
{
+ − 713
state = EClkOn;
+ − 714
}
+ − 715
+ − 716
__KTRACE_OPT( KPRCM, Kern::Printf( "-Prcm::ClockState(%x):%d", aClock, state ) );
+ − 717
+ − 718
return state;
+ − 719
}
+ − 720
+ − 721
EXPORT_C void SetWakeupMode( TClock aClock, TWakeupMode aMode )
+ − 722
{
+ − 723
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetWakeupMode(%x;%x)", aClock, aMode ) );
+ − 724
+ − 725
__ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( ESetWakeupBadClock ) );
+ − 726
+ − 727
const TRegisterBitDef& def = KClockWakeupTable[ aClock ];
+ − 728
+ − 729
TUint32 reg = def.iRegister;
+ − 730
TUint32 mask = def.iMask;
+ − 731
+ − 732
TInt irq = __SPIN_LOCK_IRQSAVE(iLock);
+ − 733
+ − 734
if( EWakeupEnabled == aMode )
+ − 735
{
+ − 736
_BitClearSet( reg, mask, def.iEnablePattern );
+ − 737
}
+ − 738
else
+ − 739
{
+ − 740
_BitClearSet( reg, mask, def.iDisablePattern );
+ − 741
}
+ − 742
+ − 743
__SPIN_UNLOCK_IRQRESTORE(iLock, irq);
+ − 744
}
+ − 745
+ − 746
EXPORT_C TWakeupMode WakeupMode( TClock aClock )
+ − 747
{
+ − 748
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::WakeupMode(%x)", aClock ) );
+ − 749
+ − 750
__ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( EGetWakeupBadClock ) );
+ − 751
+ − 752
const TRegisterBitDef& def = KClockWakeupTable[ aClock ];
+ − 753
+ − 754
TUint32 reg = def.iRegister;
+ − 755
TUint32 mask = def.iMask;
+ − 756
+ − 757
if( def.iEnablePattern == (AsspRegister::Read32( reg ) bitand mask) )
+ − 758
{
+ − 759
return EWakeupEnabled;
+ − 760
}
+ − 761
else
+ − 762
{
+ − 763
return EWakeupDisabled;
+ − 764
}
+ − 765
}
+ − 766
+ − 767
EXPORT_C void AddToWakeupGroup( TClock aClock, TWakeupGroup aGroup )
+ − 768
{
+ − 769
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::AddToWakeupGroup(%x;%x)", aClock, aGroup ) );
+ − 770
+ − 771
__ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( EAddWakeupGroupBadClock ) );
+ − 772
__ASSERT_DEBUG( (TUint)aGroup < KSupportedWakeupGroupCount, Panic( EAddWakeupGroupBadGroup ) );
+ − 773
+ − 774
const TRegisterBitDef& def = KClockWakeupGroupTable[ aClock ][ aGroup ];
+ − 775
+ − 776
TUint32 reg = def.iRegister;
+ − 777
TUint32 mask = def.iMask;
+ − 778
+ − 779
_LockedBitClearSet( reg, mask, def.iEnablePattern );
+ − 780
}
+ − 781
+ − 782
EXPORT_C void RemoveFromWakeupGroup( TClock aClock, TWakeupGroup aGroup )
+ − 783
{
+ − 784
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::RemoveFromWakeupGroup(%x;%x)", aClock, aGroup ) );
+ − 785
+ − 786
__ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( ERemoveWakeupGroupBadClock ) );
+ − 787
__ASSERT_DEBUG( (TUint)aGroup < KSupportedWakeupGroupCount, Panic( ERemoveWakeupGroupBadGroup ) );
+ − 788
+ − 789
const TRegisterBitDef& def = KClockWakeupGroupTable[ aClock ][ aGroup ];
+ − 790
+ − 791
TUint32 reg = def.iRegister;
+ − 792
TUint32 mask = def.iMask;
+ − 793
+ − 794
_LockedBitClearSet( reg, mask, def.iDisablePattern );
+ − 795
}
+ − 796
+ − 797
EXPORT_C TBool IsInWakeupGroup( TClock aClock, TWakeupGroup aGroup )
+ − 798
{
+ − 799
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::IsInWakeupGroup(%x)", aClock ) );
+ − 800
+ − 801
__ASSERT_DEBUG( (TUint)aClock < KSupportedClockCount, Panic( EGetWakeupGroupBadClock ) );
+ − 802
__ASSERT_DEBUG( (TUint)aGroup < KSupportedWakeupGroupCount, Panic( EGetWakeupGroupBadGroup ) );
+ − 803
+ − 804
const TRegisterBitDef& def = KClockWakeupGroupTable[ aClock ][ aGroup ];
+ − 805
+ − 806
TUint32 reg = def.iRegister;
+ − 807
TUint32 mask = def.iMask;
+ − 808
+ − 809
return( def.iEnablePattern == (AsspRegister::Read32( reg ) bitand mask) );
+ − 810
}
+ − 811
+ − 812
+ − 813
EXPORT_C void AddToWakeupDomain( TClock aClock, TWakeupDomain aDomain )
+ − 814
{
+ − 815
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::AddToWakeupDomain(%x;%x)", aClock, aDomain ) );
+ − 816
+ − 817
__ASSERT_DEBUG( (TUint)aClock <= (TUint)KSupportedClockCount, Panic( EAddDomainBadClock ) );
+ − 818
__ASSERT_DEBUG( (TUint)aDomain <= (TUint)KSupportedWakeupDomainCount, Panic( EAddDomainBadDomain ) );
+ − 819
+ − 820
const TWakeupDomainInfo& inf = KClockWakeupDomainTable[ aClock ];
+ − 821
TUint32 mask = 1 << (TUint)inf.iBitNumber[ aDomain ]; // unsupported bit numbers will result in a mask of 0x00000000
23
+ − 822
0
+ − 823
_LockedBitClearSet( inf.iRegister, KClearNone, mask );
+ − 824
}
+ − 825
+ − 826
EXPORT_C void RemoveFromWakeupDomain( TClock aClock, TWakeupDomain aDomain )
+ − 827
{
+ − 828
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::RemoveFromWakeupDomain(%x;%x)", aClock, aDomain ) );
+ − 829
+ − 830
__ASSERT_DEBUG( (TUint)aClock <= (TUint)KSupportedClockCount, Panic( ERemoveDomainBadClock ) );
+ − 831
__ASSERT_DEBUG( (TUint)aDomain <= (TUint)KSupportedWakeupDomainCount, Panic( ERemoveDomainBadDomain ) );
+ − 832
+ − 833
const TWakeupDomainInfo& inf = KClockWakeupDomainTable[ aClock ];
+ − 834
TUint32 mask = 1 << (TUint)inf.iBitNumber[ aDomain ]; // unsupported bit numbers will result in a mask of 0x00000000
23
+ − 835
0
+ − 836
_LockedBitClearSet( inf.iRegister, mask, KSetNone );
+ − 837
}
+ − 838
+ − 839
EXPORT_C TBool IsInWakeupDomain( TClock aClock, TWakeupDomain aDomain )
+ − 840
{
+ − 841
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::IsInWakeupDomain(%x;%x)", aClock, aDomain ) );
+ − 842
+ − 843
__ASSERT_DEBUG( (TUint)aClock <= (TUint)KSupportedClockCount, Panic( ECheckDomainBadClock ) );
+ − 844
__ASSERT_DEBUG( (TUint)aDomain <= (TUint)KSupportedWakeupDomainCount, Panic( ECheckDomainBadDomain ) );
+ − 845
+ − 846
const TWakeupDomainInfo& inf = KClockWakeupDomainTable[ aClock ];
+ − 847
TUint32 mask = 1 << (TUint)inf.iBitNumber[ aDomain ]; // unsupported bit numbers will result in a mask of 0x00000000
+ − 848
+ − 849
return ( 0 != (AsspRegister::Read32( inf.iRegister ) bitand mask) );
+ − 850
}
+ − 851
+ − 852
EXPORT_C void SetGptClockSource( TGpt aGpt, TGptClockSource aSource )
+ − 853
{
+ − 854
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetGptClockSource(%x;%x)", aGpt, aSource ) );
+ − 855
+ − 856
__ASSERT_DEBUG( (TUint)aGpt <= (TUint)EGpt12, Panic( ESetGptClockBadGpt ) );
+ − 857
+ − 858
+ − 859
TUint32 reg = KGptClockSourceInfo[ aGpt ].iRegister;
+ − 860
TUint32 mask = KGptClockSourceInfo[ aGpt ].iMask;
+ − 861
TUint32 setPattern = (EGptClockSysClk == aSource ) ? mask : 0;
+ − 862
+ − 863
_LockedBitClearSet( reg, mask, setPattern );
+ − 864
}
+ − 865
+ − 866
EXPORT_C TGptClockSource GptClockSource( TGpt aGpt )
+ − 867
{
+ − 868
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::GptClockSource(%x)", aGpt ) );
+ − 869
+ − 870
__ASSERT_DEBUG( (TUint)aGpt <= (TUint)EGpt12, Panic( ESetGptClockBadGpt ) );
+ − 871
+ − 872
TUint32 reg = KGptClockSourceInfo[ aGpt ].iRegister;
+ − 873
TUint32 mask = KGptClockSourceInfo[ aGpt ].iMask;
+ − 874
+ − 875
if( 0 == (AsspRegister::Read32( reg ) bitand mask) )
+ − 876
{
+ − 877
return EGptClock32k;
+ − 878
}
+ − 879
else
+ − 880
{
+ − 881
return EGptClockSysClk;
+ − 882
}
+ − 883
}
+ − 884
+ − 885
EXPORT_C TUint UsimDivider()
+ − 886
{
+ − 887
const TDividerInfo& info = KDividerInfo[ EClkUsim_F ];
+ − 888
TUint divmux = (AsspRegister::Read32( info.iRegister ) bitand info.iMask ) >> info.iShift;
+ − 889
return UsimDivMuxInfo[ divmux ].iDivider;
+ − 890
}
+ − 891
+ − 892
EXPORT_C TClock UsimClockSource()
+ − 893
{
+ − 894
const TDividerInfo& info = KDividerInfo[ EClkUsim_F ];
+ − 895
TUint divmux = (AsspRegister::Read32( info.iRegister ) bitand info.iMask ) >> info.iShift;
+ − 896
return UsimDivMuxInfo[ divmux ].iClock;
+ − 897
}
+ − 898
+ − 899
EXPORT_C void SetClockMux( TClock aClock, TClock aSource )
+ − 900
{
+ − 901
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::SetClockMux(%x;%x)", aClock, aSource ) );
+ − 902
+ − 903
switch( aClock )
+ − 904
{
+ − 905
case EClk96M:
+ − 906
{
+ − 907
TUint set = KBit6;
+ − 908
TUint clear = 0;
+ − 909
+ − 910
switch( aSource )
+ − 911
{
+ − 912
case EClkPeriph:
+ − 913
clear = KBit6;
+ − 914
set = 0;
+ − 915
// fall through...
+ − 916
+ − 917
case EClkSysClk:
+ − 918
_LockedBitClearSet( KCM_CLKSEL1_PLL, clear, set );
+ − 919
break;
+ − 920
+ − 921
default:
+ − 922
Panic( ESetClockMuxBadSource );
+ − 923
}
+ − 924
break;
+ − 925
}
+ − 926
+ − 927
case EClkSysOut:
+ − 928
{
+ − 929
TUint set;
+ − 930
switch( aSource )
+ − 931
{
+ − 932
case EClkCore:
+ − 933
set = 0;
+ − 934
break;
+ − 935
+ − 936
case EClkSysClk:
+ − 937
set = 1;
+ − 938
break;
+ − 939
+ − 940
case EClkPeriph:
+ − 941
set = 2;
+ − 942
break;
+ − 943
+ − 944
case EClkTv_F:
+ − 945
set = 3;
+ − 946
break;
+ − 947
+ − 948
default:
+ − 949
Panic( ESetClockMuxBadSource );
+ − 950
return;
+ − 951
}
+ − 952
+ − 953
_LockedBitClearSet( KCM_CLKOUT_CTRL, KBit1 | KBit0, set );
+ − 954
break;
+ − 955
}
+ − 956
+ − 957
case EClkTv_F:
+ − 958
{
+ − 959
TUint set = KBit5;
+ − 960
TUint clear = 0;
+ − 961
+ − 962
switch( aSource )
+ − 963
{
+ − 964
case EClkPeriph:
+ − 965
clear = KBit5;
+ − 966
set = 0;
+ − 967
// fall through...
+ − 968
+ − 969
case EClkAltClk:
+ − 970
_LockedBitClearSet( KCM_CLKSEL1_PLL, clear, set );
+ − 971
break;
+ − 972
+ − 973
default:
+ − 974
Panic( ESetClockMuxBadSource );
+ − 975
return;
+ − 976
}
+ − 977
break;
+ − 978
}
+ − 979
+ − 980
case EClkGpt1_F:
+ − 981
case EClkGpt2_F:
+ − 982
case EClkGpt3_F:
+ − 983
case EClkGpt4_F:
+ − 984
case EClkGpt5_F:
+ − 985
case EClkGpt6_F:
+ − 986
case EClkGpt7_F:
+ − 987
case EClkGpt8_F:
+ − 988
case EClkGpt9_F:
+ − 989
{
+ − 990
TGptClockSource src = EGptClock32k;
+ − 991
+ − 992
switch( aSource )
+ − 993
{
+ − 994
case EClkSysClk:
+ − 995
src = EGptClockSysClk;
+ − 996
case EClkSysClk32k:
+ − 997
break;
+ − 998
default:
+ − 999
Panic( ESetClockMuxBadSource );
+ − 1000
return;
+ − 1001
}
+ − 1002
+ − 1003
SetGptClockSource( KClockSourceInfo[ aClock ].iGpt, src );
+ − 1004
break;
+ − 1005
}
+ − 1006
+ − 1007
case EClkSgx_F:
+ − 1008
switch( aSource )
+ − 1009
{
+ − 1010
case EClk96M:
+ − 1011
SetDivider( EClkSgx_F, 0 );
+ − 1012
break;
+ − 1013
+ − 1014
case EClkCore:
+ − 1015
// Unfortunately the combined divider/mux means that switching from
+ − 1016
// CORE t 96M loses the old divider values
+ − 1017
if( 0 != Divider( EClkSgx_F ) )
+ − 1018
{
+ − 1019
// Not currently CORE, switch to default maximum divider
+ − 1020
SetDivider( EClkSgx_F, 6 );
+ − 1021
}
+ − 1022
break;
+ − 1023
+ − 1024
default:
+ − 1025
Panic( ESetClockMuxBadSource );
+ − 1026
return;
+ − 1027
}
+ − 1028
break;
+ − 1029
+ − 1030
+ − 1031
case EClk48M:
+ − 1032
{
+ − 1033
TUint set = KBit3;
+ − 1034
TUint clear = 0;
+ − 1035
+ − 1036
switch( aSource )
+ − 1037
{
+ − 1038
case EClkPeriph:
+ − 1039
clear = KBit3;
+ − 1040
set = 0;
+ − 1041
// fall through...
+ − 1042
+ − 1043
case EClkAltClk:
+ − 1044
_LockedBitClearSet( KCM_CLKSEL1_PLL, clear, set );
+ − 1045
break;
+ − 1046
+ − 1047
default:
+ − 1048
Panic( ESetClockMuxBadSource );
+ − 1049
return;
+ − 1050
}
+ − 1051
break;
+ − 1052
}
+ − 1053
+ − 1054
default:
+ − 1055
Panic( ESetClockMuxBadClock );
+ − 1056
return;
+ − 1057
}
+ − 1058
}
+ − 1059
+ − 1060
EXPORT_C TClock ClockMux( TClock aClock )
+ − 1061
{
+ − 1062
__KTRACE_OPT( KPRCM, Kern::Printf( "Prcm::ClockMux(%x)", aClock ) );
+ − 1063
+ − 1064
TClock result;
+ − 1065
+ − 1066
switch( aClock )
+ − 1067
{
+ − 1068
case EClk96M:
+ − 1069
if( 0 == (AsspRegister::Read32( KCM_CLKSEL1_PLL ) bitand KBit6 ) )
+ − 1070
{
+ − 1071
result = EClkPeriph;
+ − 1072
}
+ − 1073
else
+ − 1074
{
+ − 1075
result = EClkSysClk;
+ − 1076
}
+ − 1077
break;
+ − 1078
+ − 1079
case EClkSysOut:
+ − 1080
switch( AsspRegister::Read32( KCM_CLKOUT_CTRL ) bitand (KBit1 | KBit0) )
+ − 1081
{
+ − 1082
default:
+ − 1083
case 0:
+ − 1084
result = EClkCore;
+ − 1085
break;
+ − 1086
+ − 1087
case 1:
+ − 1088
result = EClkSysClk;
+ − 1089
break;
+ − 1090
+ − 1091
case 2:
+ − 1092
result = EClkPeriph;
+ − 1093
break;
+ − 1094
+ − 1095
case 3:
+ − 1096
result = EClkTv_F; // same as 54MHz clock
+ − 1097
break;
+ − 1098
}
+ − 1099
break;
+ − 1100
+ − 1101
case EClkTv_F:
+ − 1102
if( 0 == (AsspRegister::Read32( KCM_CLKSEL1_PLL ) bitand KBit5 ) )
+ − 1103
{
+ − 1104
result = EClkPeriph;
+ − 1105
}
+ − 1106
else
+ − 1107
{
+ − 1108
result = EClkAltClk;
+ − 1109
}
+ − 1110
break;
+ − 1111
+ − 1112
case EClkGpt1_F:
+ − 1113
case EClkGpt2_F:
+ − 1114
case EClkGpt3_F:
+ − 1115
case EClkGpt4_F:
+ − 1116
case EClkGpt5_F:
+ − 1117
case EClkGpt6_F:
+ − 1118
case EClkGpt7_F:
+ − 1119
case EClkGpt8_F:
+ − 1120
case EClkGpt9_F:
+ − 1121
case EClkGpt10_F:
+ − 1122
case EClkGpt11_F:
+ − 1123
// Redirect these to GptClockSource()
+ − 1124
if( EGptClockSysClk == GptClockSource( KClockSourceInfo[ aClock ].iGpt ) )
+ − 1125
{
+ − 1126
result = EClkSysClk;
+ − 1127
}
+ − 1128
else
+ − 1129
{
+ − 1130
result = EClkSysClk32k;
+ − 1131
}
+ − 1132
break;
+ − 1133
+ − 1134
case EClkSgx_F:
+ − 1135
if( Divider( EClkSgx_F ) == 0 )
+ − 1136
{
+ − 1137
result = EClk96M;
+ − 1138
}
+ − 1139
else
+ − 1140
{
+ − 1141
result = EClkCore;
+ − 1142
}
+ − 1143
break;
+ − 1144
+ − 1145
case EClkUsim_F:
+ − 1146
result = UsimClockSource();
+ − 1147
break;
+ − 1148
+ − 1149
case EClk48M:
+ − 1150
if( 0 == (AsspRegister::Read32( KCM_CLKSEL1_PLL ) bitand KBit3 ) )
+ − 1151
{
+ − 1152
result = EClk96M;
+ − 1153
}
+ − 1154
else
+ − 1155
{
+ − 1156
result = EClkAltClk;
+ − 1157
}
+ − 1158
break;
+ − 1159
+ − 1160
default:
+ − 1161
Panic( EGetClockMuxBadClock );
+ − 1162
return EClkAltClk; // dumy to stop compiler warning
+ − 1163
}
+ − 1164
+ − 1165
return result;
+ − 1166
}
+ − 1167
+ − 1168
EXPORT_C TUint ClockFrequency( TClock aClock )
+ − 1169
{
+ − 1170
// Works out the frequency by traversing backwards through the clock chain
+ − 1171
// assumulating a multply and divide factor until SYSCLK or SYSCLK32 is reached
+ − 1172
// Reaching a DPLL implicitly means SYSCLK has been reached
+ − 1173
+ − 1174
TUint mul = 1;
+ − 1175
TUint div = 1;
+ − 1176
TClock currentClock = aClock;
+ − 1177
__ASSERT_ALWAYS( currentClock < Prcm::KSupportedClockCount, Panic( EClockFrequencyBadClock ) );
+ − 1178
+ − 1179
// Ensure assumption that root clock range is >=EClkSysClk
+ − 1180
__ASSERT_COMPILE( EClkSysClk < EClkAltClk );
+ − 1181
__ASSERT_COMPILE( EClkAltClk < EClkSysClk32k );
+ − 1182
__ASSERT_COMPILE( (TUint)EClkSysClk32k == (TUint)KSupportedClockCount - 1 );
+ − 1183
+ − 1184
while( currentClock < EClkSysClk )
+ − 1185
{
+ − 1186
// Get previous clock in chain
+ − 1187
TClock prevClock = KClockSourceInfo[ currentClock ].iClock;
+ − 1188
+ − 1189
switch( KClockSourceInfo[ currentClock ].iType )
+ − 1190
{
+ − 1191
case EIgnore:
+ − 1192
return 0; // unsupported clock
+ − 1193
+ − 1194
case EDpll:
+ − 1195
{
+ − 1196
TPll pll = KClockSourceInfo[ currentClock ].iPll;
+ − 1197
+ − 1198
if( PllMode( pll ) == EPllBypass )
+ − 1199
{
+ − 1200
if( EDpll1 == pll )
+ − 1201
{
+ − 1202
prevClock = Prcm::EClkMpuPll_Bypass;
+ − 1203
}
+ − 1204
else if( EDpll2 == pll )
+ − 1205
{
+ − 1206
prevClock = Prcm::EClkIva2Pll_Bypass;
+ − 1207
}
+ − 1208
else
+ − 1209
{
+ − 1210
// for all other DPLL1 the bypass clock is the input clock SYSCLK
+ − 1211
prevClock = EClkSysClk;
+ − 1212
}
+ − 1213
}
+ − 1214
else
+ − 1215
{
+ − 1216
TPllConfiguration pllCfg;
+ − 1217
PllConfig( pll, pllCfg );
+ − 1218
mul *= pllCfg.iMultiplier;
+ − 1219
div *= pllCfg.iDivider;
+ − 1220
if( EDpll4 == pll )
+ − 1221
{
+ − 1222
// Output is multiplied by 2 for DPLL4
+ − 1223
mul *= 2;
+ − 1224
}
+ − 1225
prevClock = EClkSysClk;
+ − 1226
}
+ − 1227
break;
+ − 1228
}
+ − 1229
+ − 1230
case EMux:
+ − 1231
prevClock = ClockMux( currentClock );
+ − 1232
break;
+ − 1233
+ − 1234
case EDivMux:
+ − 1235
// need to find what clock the divider is fed from
+ − 1236
prevClock = ClockMux( currentClock );
+ − 1237
// fall through to get divider..
+ − 1238
+ − 1239
case EDivider:
+ − 1240
{
+ − 1241
TUint selectedDiv = Divider( currentClock );
+ − 1242
// Special case for SGX - ignore a return of 0
+ − 1243
if( 0 != selectedDiv )
+ − 1244
{
+ − 1245
div *= selectedDiv;
+ − 1246
}
+ − 1247
break;
+ − 1248
}
+ − 1249
+ − 1250
case EDuplicate:
+ − 1251
// Nothing to do, we just follow to the next clock
+ − 1252
break;
+ − 1253
+ − 1254
case E48MMux:
+ − 1255
prevClock = ClockMux( currentClock );
+ − 1256
if( prevClock != EClkAltClk )
+ − 1257
{
+ − 1258
div *= 2;
+ − 1259
}
+ − 1260
break;
+ − 1261
+ − 1262
case E54MMux:
+ − 1263
prevClock = ClockMux( currentClock );
+ − 1264
if( prevClock != EClkAltClk )
+ − 1265
{
+ − 1266
div *= Divider( currentClock );
+ − 1267
}
+ − 1268
break;
+ − 1269
+ − 1270
case E96MMux:
+ − 1271
prevClock = ClockMux( currentClock );
+ − 1272
if( prevClock != EClkSysClk )
+ − 1273
{
+ − 1274
div *= Divider( currentClock );
+ − 1275
}
+ − 1276
break;
+ − 1277
+ − 1278
case EDiv4:
+ − 1279
div *= 4;
+ − 1280
break;
+ − 1281
}
23
+ − 1282
0
+ − 1283
currentClock = prevClock;
+ − 1284
} // end do
+ − 1285
+ − 1286
// When we reach here we have worked back to the origin clock
23
+ − 1287
0
+ − 1288
TUint64 fSrc;
+ − 1289
const Omap3530Assp* variant = (Omap3530Assp*)Arch::TheAsic();
+ − 1290
+ − 1291
if( EClkSysClk == currentClock )
+ − 1292
{
+ − 1293
// input OSC_SYSCLK is always divided by 2 before being fed to SYS_CLK
+ − 1294
fSrc = variant->SysClkFrequency() / 2;
+ − 1295
}
+ − 1296
else if( EClkSysClk32k == currentClock )
+ − 1297
{
+ − 1298
fSrc = variant->SysClk32kFrequency();
+ − 1299
}
+ − 1300
else
+ − 1301
{
+ − 1302
fSrc = variant->AltClkFrequency();
+ − 1303
}
+ − 1304
+ − 1305
if( div == 0 )
+ − 1306
{
+ − 1307
// to account for any registers set at illegal values
+ − 1308
return 0;
+ − 1309
}
+ − 1310
else
+ − 1311
{
+ − 1312
return (TUint)((fSrc * mul) / div);
+ − 1313
}
+ − 1314
}
+ − 1315
+ − 1316
EXPORT_C void SetSysClkFrequency( TSysClkFrequency aFrequency )
+ − 1317
{
+ − 1318
static const TUint8 KConfigValues[] =
+ − 1319
{
+ − 1320
0, // ESysClk12MHz
+ − 1321
1, // ESysClk13MHz
+ − 1322
5, // ESysClk16_8MHz
+ − 1323
2, // ESysClk19_2MHz
+ − 1324
3, // ESysClk26MHz
+ − 1325
4 // ESysClk38_4MHz
+ − 1326
};
+ − 1327
+ − 1328
_LockedBitClearSet( KPRM_CLKSEL, KBit0 | KBit1 | KBit2, KConfigValues[ aFrequency ] );
+ − 1329
}
+ − 1330
+ − 1331
/** Get the currently configured SysClk frequency */
+ − 1332
EXPORT_C TSysClkFrequency SysClkFrequency()
+ − 1333
{
23
+ − 1334
0
+ − 1335
switch( AsspRegister::Read32( KPRM_CLKSEL ) bitand (KBit0 | KBit1 | KBit2) )
+ − 1336
{
+ − 1337
case 0:
+ − 1338
return ESysClk12MHz;
+ − 1339
case 1:
+ − 1340
return ESysClk13MHz;
+ − 1341
case 2:
+ − 1342
return ESysClk19_2MHz;
+ − 1343
case 3:
+ − 1344
return ESysClk26MHz;
+ − 1345
case 4:
+ − 1346
return ESysClk38_4MHz;
+ − 1347
case 5:
+ − 1348
return ESysClk16_8MHz;
+ − 1349
default:
+ − 1350
__DEBUG_ONLY( InternalPanic( __LINE__ ) );
+ − 1351
return ESysClk13MHz;
+ − 1352
}
+ − 1353
}
+ − 1354
+ − 1355
+ − 1356
EXPORT_C const TDesC& PrmName( TClock aClock )
+ − 1357
{
+ − 1358
__ASSERT_DEBUG( (TUint)aClock <= KSupportedClockCount, Panic( EGetNameBadClock ) );
+ − 1359
__ASSERT_DEBUG( KNames[ aClock ] != NULL, Kern::Fault( "PrmName", aClock ) );
+ − 1360
+ − 1361
return *KNames[ aClock ];
+ − 1362
}
+ − 1363
+ − 1364
EXPORT_C void Init3()
+ − 1365
{
+ − 1366
// Enable LP mode if possible on MPU and CORE PLLs.
+ − 1367
// Don't enable on PERIPHERAL, IVA2 or USB because LP mode introduces jitter
+ − 1368
AutoSetPllLpMode( EDpll1 );
+ − 1369
AutoSetPllLpMode( EDpll3 );
+ − 1370
+ − 1371
TInt irq = __SPIN_LOCK_IRQSAVE(iLock);
+ − 1372
TUint32 r;
+ − 1373
+ − 1374
// IVA2
+ − 1375
// Not yet mapped! const TUint32 KPDCCMD = Omap3530HwBase::TVirtual<0x01810000>::Value;
+ − 1376
// r = AsspRegister::Read32(KPDCCMD);
+ − 1377
// AsspRegister::Modify32(KPDCCMD, 0, 1 << 16);
+ − 1378
// Set(KCM_FCLKEN_IVA2, 1 << 0, 0);
+ − 1379
// CAM
+ − 1380
const TUint32 KISP_CTRL = Omap3530HwBase::TVirtual<0x480BC040>::Value;
+ − 1381
r = AsspRegister::Read32(KISP_CTRL);
+ − 1382
_BitClearSet(KISP_CTRL, 0xf << 10, 0);
+ − 1383
_BitClearSet(KCM_FCLKEN_CAM, 1 << 0, 0);
+ − 1384
_BitClearSet(KCM_ICLKEN_CAM, 1 << 0, 0);
+ − 1385
+ − 1386
// MMC
+ − 1387
r = AsspRegister::Read32(KMMCHS1_SYSCONFIG);
+ − 1388
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1389
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1390
SetClockState( EClkMmc1_F, EClkOff );
+ − 1391
SetClockState( EClkMmc1_I, EClkOff );
+ − 1392
r = AsspRegister::Read32(KMMCHS2_SYSCONFIG);
+ − 1393
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1394
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1395
SetClockState( EClkMmc2_F, EClkOff );
+ − 1396
SetClockState( EClkMmc2_I, EClkOff );
+ − 1397
/* There is no MMC3 on the beagle board
+ − 1398
r = AsspRegister::Read32(KMMCHS3_SYSCONFIG);
+ − 1399
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1400
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1401
*/
+ − 1402
SetClockState( EClkMmc3_F, EClkOff );
+ − 1403
SetClockState( EClkMmc3_I, EClkOff );
+ − 1404
+ − 1405
// McBSP
+ − 1406
r = AsspRegister::Read32(KMCBSPLP1_SYSCONFIG);
+ − 1407
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1408
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1409
SetClockState( EClkMcBsp1_F, EClkOff );
+ − 1410
SetClockState( EClkMcBsp1_I, EClkOff );
+ − 1411
const TUint32 KMCBSPLP2_SPCR1 = Omap3530HwBase::TVirtual<0x49022014>::Value;
+ − 1412
_BitClearSet(KMCBSPLP2_SPCR1, 1 << 0, 0); // RRST := 0
+ − 1413
const TUint32 KMCBSPLP2_SPCR2 = Omap3530HwBase::TVirtual<0x49022010>::Value;
+ − 1414
_BitClearSet(KMCBSPLP2_SPCR2, 1 << 7 | 1 << 0, 0); // FRST, XRST := 0
+ − 1415
_BitClearSet(KMCBSPLP2_SYSCONFIG, 0x3 << 8 | 0x3 << 3, 0); // CLOCKACTIVITY := can be switched off, SIDLEMODE := force idle
+ − 1416
r = AsspRegister::Read32(KMCBSPLP2_SYSCONFIG);
+ − 1417
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1418
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1419
SetClockState( EClkMcBsp2_F, EClkOff );
+ − 1420
SetClockState( EClkMcBsp2_I, EClkOff );
+ − 1421
r = AsspRegister::Read32(KMCBSPLP3_SYSCONFIG);
+ − 1422
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1423
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1424
SetClockState( EClkMcBsp3_F, EClkOff );
+ − 1425
SetClockState( EClkMcBsp3_I, EClkOff );
+ − 1426
r = AsspRegister::Read32(KMCBSPLP4_SYSCONFIG);
+ − 1427
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1428
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1429
SetClockState( EClkMcBsp4_F, EClkOff );
+ − 1430
SetClockState( EClkMcBsp4_I, EClkOff );
+ − 1431
r = AsspRegister::Read32(KMCBSPLP5_SYSCONFIG);
+ − 1432
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1433
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1434
SetClockState( EClkMcBsp5_F, EClkOff );
+ − 1435
SetClockState( EClkMcBsp5_I, EClkOff );
+ − 1436
+ − 1437
// McSPI
+ − 1438
r = AsspRegister::Read32(KMCSPI1_SYSCONFIG);
+ − 1439
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1440
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1441
SetClockState( EClkMcSpi1_F, EClkOff );
+ − 1442
SetClockState( EClkMcSpi1_I, EClkOff );
+ − 1443
r = AsspRegister::Read32(KMCSPI2_SYSCONFIG);
+ − 1444
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1445
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1446
SetClockState( EClkMcSpi2_F, EClkOff );
+ − 1447
SetClockState( EClkMcSpi2_I, EClkOff );
+ − 1448
r = AsspRegister::Read32(KMCSPI3_SYSCONFIG);
+ − 1449
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1450
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
23
+ − 1451
/* nxz enable SPI 3
0
+ − 1452
SetClockState( EClkMcSpi3_F, EClkOff );
23
+ − 1453
SetClockState( EClkMcSpi3_I, EClkOff );*/
+ − 1454
SetClockState( EClkMcSpi3_F, EClkOn );
+ − 1455
SetClockState( EClkMcSpi3_I, EClkOn );
0
+ − 1456
r = AsspRegister::Read32(KMCSPI4_SYSCONFIG);
+ − 1457
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1458
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
23
+ − 1459
/* nxz enable SPI 4
0
+ − 1460
SetClockState( EClkMcSpi4_F, EClkOff );
23
+ − 1461
SetClockState( EClkMcSpi4_I, EClkOff );*/
+ − 1462
SetClockState( EClkMcSpi4_F, EClkOn );
+ − 1463
SetClockState( EClkMcSpi4_I, EClkOn );
0
+ − 1464
52
d2416cb47e12
Bug 3612 - Enable all uarts on the beagleboard , Bug 3612 - Unknown '#file' keyword in base_beagle.iby , Bug 3614 - Including medstaticcrd to the package builds
arunabha
diff
changeset
+ − 1465
/* BUG 3612 - We do not want to dissable all other UARTS
0
+ − 1466
// UART
+ − 1467
TInt debugport = Kern::SuperPage().iDebugPort;
+ − 1468
if( debugport != 0 )
+ − 1469
{
+ − 1470
r = AsspRegister::Read32(KUART1_SYSC);
+ − 1471
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1472
SetClockState( EClkUart1_F, EClkOff );
+ − 1473
SetClockState( EClkUart1_I, EClkOff );
+ − 1474
}
+ − 1475
if( debugport != 1 )
+ − 1476
{
+ − 1477
r = AsspRegister::Read32(KUART2_SYSC);
+ − 1478
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1479
SetClockState( EClkUart2_F, EClkOff );
+ − 1480
SetClockState( EClkUart2_I, EClkOff );
+ − 1481
}
+ − 1482
if( debugport != 2 )
+ − 1483
{
+ − 1484
r = AsspRegister::Read32(KUART3_SYSC);
+ − 1485
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1486
SetClockState( EClkUart3_F, EClkOff );
+ − 1487
SetClockState( EClkUart3_I, EClkOff );
+ − 1488
}
52
d2416cb47e12
Bug 3612 - Enable all uarts on the beagleboard , Bug 3612 - Unknown '#file' keyword in base_beagle.iby , Bug 3614 - Including medstaticcrd to the package builds
arunabha
diff
changeset
+ − 1489
*/
0
+ − 1490
+ − 1491
// I2C KI2C1_SYSC
+ − 1492
r = AsspRegister::Read32(KI2C1_SYSC);
+ − 1493
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1494
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1495
SetClockState( EClkI2c1_F, EClkOff );
+ − 1496
SetClockState( EClkI2c1_I, EClkOff );
+ − 1497
r = AsspRegister::Read32(KI2C2_SYSC);
+ − 1498
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1499
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1500
SetClockState( EClkI2c2_F, EClkOff );
+ − 1501
SetClockState( EClkI2c2_I, EClkOff );
+ − 1502
r = AsspRegister::Read32(KI2C3_SYSC);
+ − 1503
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1504
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1505
SetClockState( EClkI2c3_F, EClkOff );
+ − 1506
SetClockState( EClkI2c3_I, EClkOff );
+ − 1507
+ − 1508
// GPT
+ − 1509
r = AsspRegister::Read32(KTI1OCP_CFG);
+ − 1510
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1511
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1512
SetClockState( EClkGpt1_F, EClkOff );
+ − 1513
SetClockState( EClkGpt1_I, EClkOff );
+ − 1514
r = AsspRegister::Read32(KTI2OCP_CFG);
+ − 1515
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1516
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1517
SetClockState( EClkGpt2_F, EClkOff );
+ − 1518
SetClockState( EClkGpt2_I, EClkOff );
+ − 1519
r = AsspRegister::Read32(KTI3OCP_CFG);
+ − 1520
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1521
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1522
SetClockState( EClkGpt3_F, EClkOff );
+ − 1523
SetClockState( EClkGpt3_I, EClkOff );
+ − 1524
r = AsspRegister::Read32(KTI4OCP_CFG);
+ − 1525
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1526
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1527
SetClockState( EClkGpt4_F, EClkOff );
+ − 1528
SetClockState( EClkGpt4_I, EClkOff );
+ − 1529
r = AsspRegister::Read32(KTI5OCP_CFG);
+ − 1530
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1531
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1532
SetClockState( EClkGpt5_F, EClkOff );
+ − 1533
SetClockState( EClkGpt5_I, EClkOff );
+ − 1534
r = AsspRegister::Read32(KTI6OCP_CFG);
+ − 1535
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1536
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1537
SetClockState( EClkGpt6_F, EClkOff );
+ − 1538
SetClockState( EClkGpt6_I, EClkOff );
+ − 1539
r = AsspRegister::Read32(KTI7OCP_CFG);
+ − 1540
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1541
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1542
SetClockState( EClkGpt7_F, EClkOff );
+ − 1543
SetClockState( EClkGpt7_I, EClkOff );
+ − 1544
r = AsspRegister::Read32(KTI8OCP_CFG);
+ − 1545
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1546
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1547
SetClockState( EClkGpt8_F, EClkOff );
+ − 1548
SetClockState( EClkGpt8_I, EClkOff );
+ − 1549
r = AsspRegister::Read32(KTI9OCP_CFG);
+ − 1550
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1551
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1552
SetClockState( EClkGpt9_F, EClkOff );
+ − 1553
SetClockState( EClkGpt9_I, EClkOff );
+ − 1554
r = AsspRegister::Read32(KTI10OCP_CFG);
+ − 1555
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1556
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1557
SetClockState( EClkGpt10_F, EClkOff );
+ − 1558
SetClockState( EClkGpt10_I, EClkOff );
+ − 1559
r = AsspRegister::Read32(KTI11OCP_CFG);
+ − 1560
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1561
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1562
SetClockState( EClkGpt11_F, EClkOff );
+ − 1563
SetClockState( EClkGpt11_I, EClkOff );
+ − 1564
+ − 1565
// WDT
+ − 1566
r = AsspRegister::Read32(KWD2_SYSCONFIG);
+ − 1567
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1568
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1569
SetClockState( EClkWdt2_F, EClkOff );
+ − 1570
SetClockState( EClkWdt2_I, EClkOff );
+ − 1571
r = AsspRegister::Read32(KWD3_SYSCONFIG);
+ − 1572
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1573
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1574
SetClockState( EClkWdt3_F, EClkOff );
+ − 1575
SetClockState( EClkWdt3_I, EClkOff );
+ − 1576
+ − 1577
// GPIO
+ − 1578
/*
+ − 1579
r = AsspRegister::Read32(KGPIO1_SYSCONFIG);
+ − 1580
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1581
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1582
_BitClearSet(KCM_FCLKEN_WKUP, 1 << 3, 0);
+ − 1583
_BitClearSet(KCM_ICLKEN_WKUP, 1 << 3, 0);
23
+ − 1584
0
+ − 1585
//r = AsspRegister::Read32(KGPIO2_SYSCONFIG);
+ − 1586
//__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1587
//__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1588
//_BitClearSet(KCM_FCLKEN_PER, 1 << 13, 0);
+ − 1589
//_BitClearSet(KCM_ICLKEN_PER, 1 << 13, 0);
+ − 1590
r = AsspRegister::Read32(KGPIO3_SYSCONFIG);
+ − 1591
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1592
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1593
_BitClearSet(KCM_FCLKEN_PER, 1 << 14, 0);
+ − 1594
_BitClearSet(KCM_ICLKEN_PER, 1 << 14, 0);
+ − 1595
r = AsspRegister::Read32(KGPIO4_SYSCONFIG);
+ − 1596
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1597
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1598
_BitClearSet(KCM_FCLKEN_PER, 1 << 15, 0);
+ − 1599
_BitClearSet(KCM_ICLKEN_PER, 1 << 15, 0);
+ − 1600
r = AsspRegister::Read32(KGPIO5_SYSCONFIG);
+ − 1601
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1602
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1603
_BitClearSet(KCM_FCLKEN_PER, 1 << 16, 0);
+ − 1604
_BitClearSet(KCM_ICLKEN_PER, 1 << 16, 0);
+ − 1605
r = AsspRegister::Read32(KGPIO6_SYSCONFIG);
+ − 1606
__NK_ASSERT_ALWAYS((r & 1 << 3) == 0);
+ − 1607
__NK_ASSERT_ALWAYS((r & 1 << 8) == 0);
+ − 1608
_BitClearSet(KCM_FCLKEN_PER, 1 << 17, 0);
+ − 1609
_BitClearSet(KCM_ICLKEN_PER, 1 << 17, 0);
+ − 1610
*/
+ − 1611
__SPIN_UNLOCK_IRQRESTORE(iLock, irq);
+ − 1612
}
+ − 1613
+ − 1614
} // end namespace Prcm
+ − 1615
+ − 1616
+ − 1617
NONSHARABLE_CLASS( TPrcmInterruptDispatch ): public MInterruptDispatcher
+ − 1618
{
+ − 1619
public:
+ − 1620
TInt Init();
+ − 1621
virtual TInt Bind(TInt aId, TIsr anIsr, TAny* aPtr) ;
+ − 1622
virtual TInt Unbind(TInt aId);
+ − 1623
virtual TInt Enable(TInt aId);
+ − 1624
virtual TInt Disable(TInt aId);
+ − 1625
virtual TInt Clear(TInt aId);
+ − 1626
virtual TInt SetPriority(TInt aId, TInt aPriority);
+ − 1627
+ − 1628
private:
+ − 1629
static void Spurious( TAny* aId );
+ − 1630
static void Dispatch( TAny* aParam );
+ − 1631
};
+ − 1632
+ − 1633
SInterruptHandler Handlers[ Prcm::KInterruptCount ];
+ − 1634
TInt TheRootInterruptEnable = 0;
+ − 1635
TSpinLock iIntLock(/*TSpinLock::EOrderGenericIrqLow0*/);
+ − 1636
TPrcmInterruptDispatch TheIntDispatcher;
+ − 1637
+ − 1638
void TPrcmInterruptDispatch::Spurious( TAny* aId )
+ − 1639
{
+ − 1640
Kern::Fault( "PRCM:Spurious", (TInt)aId );
+ − 1641
}
+ − 1642
+ − 1643
void TPrcmInterruptDispatch::Dispatch( TAny* /*aParam*/ )
+ − 1644
{
+ − 1645
TUint32 status = AsspRegister::Read32( KPRM_IRQSTATUS_MPU )
+ − 1646
bitand AsspRegister::Read32( KPRM_IRQENABLE_MPU );
+ − 1647
+ − 1648
for( TInt i = 0; (status) && (i < Prcm::KInterruptCount); ++i )
+ − 1649
{
+ − 1650
if( status bitand 1 )
+ − 1651
{
+ − 1652
(*Handlers[i].iIsr)( Handlers[i].iPtr );
+ − 1653
}
+ − 1654
status >>= 1;
+ − 1655
}
+ − 1656
}
+ − 1657
+ − 1658
TInt TPrcmInterruptDispatch::Init()
+ − 1659
{
+ − 1660
// Disable all interrupts
+ − 1661
AsspRegister::Write32( KPRM_IRQENABLE_MPU, 0 );
+ − 1662
AsspRegister::Write32( KPRM_IRQSTATUS_MPU, KSetAll );
+ − 1663
+ − 1664
// Bind all to spurious handler
+ − 1665
for( TInt i = 0; i < Prcm::KInterruptCount; ++i )
+ − 1666
{
+ − 1667
Handlers[i].iIsr = TPrcmInterruptDispatch::Spurious;
+ − 1668
Handlers[i].iPtr = (TAny*)(i + (EIrqRangeBasePrcm << KIrqRangeIndexShift));
+ − 1669
}
+ − 1670
+ − 1671
TInt r = Interrupt::Bind( EOmap3530_IRQ11_PRCM_MPU_IRQ, TPrcmInterruptDispatch::Dispatch, this );
+ − 1672
if( KErrNone == r )
+ − 1673
{
+ − 1674
Register( EIrqRangeBasePrcm );
+ − 1675
}
+ − 1676
return r;
+ − 1677
}
+ − 1678
+ − 1679
TInt TPrcmInterruptDispatch::Bind(TInt aId, TIsr aIsr, TAny* aPtr)
+ − 1680
{
+ − 1681
TUint id = aId bitand KIrqNumberMask;
+ − 1682
TInt r;
+ − 1683
+ − 1684
if( id < Prcm::KInterruptCount )
+ − 1685
{
+ − 1686
if( Handlers[ id ].iIsr != TPrcmInterruptDispatch::Spurious )
+ − 1687
{
+ − 1688
r = KErrInUse;
+ − 1689
}
+ − 1690
else
+ − 1691
{
+ − 1692
Handlers[ id ].iIsr = aIsr;
+ − 1693
Handlers[ id ].iPtr = aPtr;
+ − 1694
r = KErrNone;
+ − 1695
}
+ − 1696
}
+ − 1697
else
+ − 1698
{
+ − 1699
r = KErrArgument;
+ − 1700
}
+ − 1701
return r;
+ − 1702
}
+ − 1703
+ − 1704
TInt TPrcmInterruptDispatch::Unbind(TInt aId)
+ − 1705
{
+ − 1706
TUint id = aId bitand KIrqNumberMask;
+ − 1707
TInt r;
+ − 1708
+ − 1709
if( id < Prcm::KInterruptCount )
+ − 1710
{
+ − 1711
if( Handlers[ id ].iIsr == TPrcmInterruptDispatch::Spurious )
+ − 1712
{
+ − 1713
r = KErrGeneral;
+ − 1714
}
+ − 1715
else
+ − 1716
{
+ − 1717
Handlers[ id ].iIsr = TPrcmInterruptDispatch::Spurious;
+ − 1718
r = KErrNone;
+ − 1719
}
+ − 1720
}
+ − 1721
else
+ − 1722
{
+ − 1723
r = KErrArgument;
+ − 1724
}
+ − 1725
return r;
+ − 1726
}
+ − 1727
+ − 1728
TInt TPrcmInterruptDispatch::Enable(TInt aId)
+ − 1729
{
+ − 1730
TUint id = aId bitand KIrqNumberMask;
+ − 1731
+ − 1732
if( id < Prcm::KInterruptCount )
+ − 1733
{
+ − 1734
TInt irq = __SPIN_LOCK_IRQSAVE(iIntLock);
+ − 1735
if( ++TheRootInterruptEnable == 1 )
+ − 1736
{
+ − 1737
Interrupt::Enable( EOmap3530_IRQ11_PRCM_MPU_IRQ );
+ − 1738
}
+ − 1739
Prcm::_BitClearSet( KPRM_IRQENABLE_MPU, KClearNone, 1 << id );
+ − 1740
__SPIN_UNLOCK_IRQRESTORE(iIntLock, irq);
+ − 1741
return KErrNone;
+ − 1742
}
+ − 1743
else
+ − 1744
{
+ − 1745
return KErrArgument;
+ − 1746
}
+ − 1747
}
+ − 1748
+ − 1749
TInt TPrcmInterruptDispatch::Disable(TInt aId)
+ − 1750
{
+ − 1751
TUint id = aId bitand KIrqNumberMask;
+ − 1752
+ − 1753
if( id < Prcm::KInterruptCount )
+ − 1754
{
+ − 1755
TInt irq = __SPIN_LOCK_IRQSAVE(iIntLock);
+ − 1756
if( --TheRootInterruptEnable == 0 )
+ − 1757
{
+ − 1758
Interrupt::Disable( EOmap3530_IRQ11_PRCM_MPU_IRQ );
+ − 1759
}
+ − 1760
Prcm::_BitClearSet( KPRM_IRQENABLE_MPU, 1 << id, KSetNone );
+ − 1761
__SPIN_UNLOCK_IRQRESTORE(iIntLock, irq);
+ − 1762
return KErrNone;
+ − 1763
}
+ − 1764
else
+ − 1765
{
+ − 1766
return KErrArgument;
+ − 1767
}
+ − 1768
}
+ − 1769
+ − 1770
TInt TPrcmInterruptDispatch::Clear(TInt aId)
+ − 1771
{
+ − 1772
TUint id = aId bitand KIrqNumberMask;
+ − 1773
TInt r;
+ − 1774
+ − 1775
if( id < Prcm::KInterruptCount )
+ − 1776
{
+ − 1777
AsspRegister::Write32( KPRM_IRQSTATUS_MPU, 1 << id );
+ − 1778
r = KErrNone;
+ − 1779
}
+ − 1780
else
+ − 1781
{
+ − 1782
r = KErrArgument;
+ − 1783
}
+ − 1784
return r;
+ − 1785
}
+ − 1786
+ − 1787
TInt TPrcmInterruptDispatch::SetPriority(TInt anId, TInt aPriority)
+ − 1788
{
+ − 1789
return KErrNotSupported;
+ − 1790
}
+ − 1791
+ − 1792
+ − 1793
+ − 1794
DECLARE_STANDARD_EXTENSION()
+ − 1795
{
+ − 1796
return TheIntDispatcher.Init();
+ − 1797
}
+ − 1798
+ − 1799
+ − 1800
+ − 1801
+ − 1802