sl@0: // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32test\benchmark\bm_momap_pdd.cpp sl@0: // sl@0: // sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include // TResourceMgr methods sl@0: #include // ASSP resources sl@0: #include "k32bm.h" sl@0: sl@0: // Note that this uses GPTimer2, these make it easy to swap around sl@0: const TUint KGPTimerBase = KHwBaseGpTimer2Reg; sl@0: const TUint KGPTimerClkSel = KHt_MOD_CONF_CTRL1_GPTIMER2_CLK_SEL; sl@0: const TUint KGPTimerInt = EIrqLv1_GpTimer2; sl@0: sl@0: class DBmOmap : public DPhysicalDevice sl@0: { sl@0: public: sl@0: DBmOmap(); sl@0: ~DBmOmap(); sl@0: virtual TInt Install(); sl@0: virtual void GetCaps(TDes8& aDes) const; sl@0: virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); sl@0: virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); sl@0: }; sl@0: sl@0: class DBmOmapChannel : public DBMPChannel sl@0: { sl@0: public: sl@0: DBmOmapChannel(); sl@0: ~DBmOmapChannel(); sl@0: virtual TBMTicks TimerPeriod(); // Report timing spec sl@0: virtual TBMTicks TimerStamp(); // Get current system timer tick time sl@0: virtual TBMNs TimerTicksToNs(TBMTicks); // Tick/nS conversions sl@0: virtual TBMTicks TimerNsToTicks(TBMNs); sl@0: virtual TInt BindInterrupt(MBMIsr*); // Pass in client ISRs to invoke sl@0: virtual TInt BindInterrupt(MBMInterruptLatencyIsr*); sl@0: virtual void RequestInterrupt(); // Invoke an ISR sl@0: virtual void CancelInterrupt(); sl@0: sl@0: private: sl@0: TInt BindInterrupt(); // Attach to OST interrupt sl@0: sl@0: static const TInt KOmapOscFreqHz = 3000000; // 12Mhz / 4 = 3MHz sl@0: static const TBMTicks KBMOmapPeriod = (((TBMTicks) 1) << 32); sl@0: static const TBMNs KBMOmapNsPerTick = (1000*1000*1000) / KOmapOscFreqHz; sl@0: sl@0: // calculate 1ms in timer ticks sl@0: static const TInt KBMOmapInterruptDelayTicks = KOmapOscFreqHz / 1000; sl@0: sl@0: static void Isr(TAny*); sl@0: sl@0: MBMIsr* iIsr; sl@0: MBMInterruptLatencyIsr* iInterruptLatencyIsr; sl@0: }; sl@0: sl@0: sl@0: DECLARE_STANDARD_PDD() sl@0: // sl@0: // Create a new device sl@0: // sl@0: { sl@0: __ASSERT_CRITICAL; sl@0: return new DBmOmap; sl@0: } sl@0: sl@0: DBmOmap::DBmOmap() sl@0: // sl@0: // Constructor sl@0: // sl@0: { sl@0: //iUnitsMask=0; sl@0: iVersion = TVersion(1,0,1); sl@0: sl@0: // place requirement on xor clock sl@0: TResourceMgr::Request(KPowerArmEn_XorpCk); sl@0: // Stop timer sl@0: TOmap::ModifyRegister32(KGPTimerBase + KHoGpTimer_TCLR, KHtGpTimer_TCLR_St, KClear32); //Stop the timer sl@0: sl@0: // Drive this gptimer by the arm xor clock sl@0: TOmapPlat::ModifyConfigReg(KHoBaseConfMOD_CONF_CTRL1, KGPTimerClkSel, 0); sl@0: // Prescale enable = 12/4 = 3MHz sl@0: TOmap::ModifyRegister32(KGPTimerBase + KHoGpTimer_TCLR, (KHmGpTimer_TCLR_PTV), (1 << KHsGpTimer_TCLR_PTV | KHtGpTimer_TCLR_PRE) ); sl@0: sl@0: // Enable "smart Idle mode" sl@0: TOmap::SetRegister32(KGPTimerBase + KHoGpTimerTIOCP_CFG, (KHtGpTimer_TIOCP_CFG_SmartIdle << KHsGpTimer_TIOCP_CFG_IdleMode)); sl@0: // Load TimerLoad register to zero so when overflow occurs the counter starts from zero again. sl@0: TOmap::SetRegister32(KGPTimerBase + KHoGpTimer_TLDR, 0x0); sl@0: // Load Timer Trig register which clears the prescale counter and loads the value in TLDR to TCRR sl@0: TOmap::SetRegister32(KGPTimerBase + KHoGpTimer_TTGR, 0x1); sl@0: sl@0: // Start the GPTimer. This configuration will pause counting when stopped by the jtag sl@0: TOmap::ModifyRegister32(KGPTimerBase + KHoGpTimer_TCLR, KClear32, (KHtGpTimer_TCLR_St|KHtGpTimer_TCLR_AR|KHtGpTimer_TCLR_CE)); sl@0: while(TOmap::Register32(KGPTimerBase + KHoGpTimer_TWPS)); sl@0: } sl@0: sl@0: DBmOmap::~DBmOmap() sl@0: { sl@0: // Stop timer sl@0: TOmap::ModifyRegister32(KGPTimerBase + KHoGpTimer_TCLR, KHtGpTimer_TCLR_St, KClear32); sl@0: while(TOmap::Register32(KGPTimerBase + KHoGpTimer_TWPS)); sl@0: sl@0: // Release requirement on xor clock sl@0: TResourceMgr::Release(KPowerArmEn_XorpCk); sl@0: } sl@0: sl@0: TInt DBmOmap::Install() sl@0: // sl@0: // Install the device driver. sl@0: // sl@0: { sl@0: TInt r = SetName(&KBMPdName); sl@0: return r; sl@0: } sl@0: sl@0: void DBmOmap::GetCaps(TDes8& aDes) const sl@0: // sl@0: // Return the Comm capabilities. sl@0: // sl@0: { sl@0: } sl@0: sl@0: TInt DBmOmap::Create(DBase*& aChannel, TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/) sl@0: // sl@0: // Create a channel on the device. sl@0: // sl@0: { sl@0: __ASSERT_CRITICAL; sl@0: aChannel = new DBmOmapChannel; sl@0: return aChannel?KErrNone:KErrNoMemory; sl@0: } sl@0: sl@0: TInt DBmOmap::Validate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer) sl@0: { sl@0: if (!Kern::QueryVersionSupported(iVersion,aVer)) sl@0: { sl@0: return KErrNotSupported; sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: // Note that the standard benchmark tests will expect to create >1 sl@0: // channel (with the same LDD/PDD(unit)) hence this function must be sl@0: // capable of being invoked multiple times. sl@0: sl@0: DBmOmapChannel::DBmOmapChannel() sl@0: { sl@0: // iIsr = NULL; sl@0: // iInterruptLatencyIsr = NULL; sl@0: } sl@0: sl@0: DBmOmapChannel::~DBmOmapChannel() sl@0: { sl@0: if (iIsr || iInterruptLatencyIsr) sl@0: { sl@0: // Leave timer running sl@0: // TOmap::ModifyRegister32(KGPTimerBase + KHoGpTimer_TCLR, KHtGpTimer_TCLR_St, KClear32); //Stop the timer sl@0: Interrupt::Disable(KGPTimerInt); sl@0: Interrupt::Unbind(KGPTimerInt); sl@0: } sl@0: } sl@0: sl@0: TBMTicks DBmOmapChannel::TimerPeriod() sl@0: { sl@0: return KBMOmapPeriod; sl@0: } sl@0: sl@0: TBMTicks DBmOmapChannel::TimerStamp() sl@0: { sl@0: return TUint(TOmap::Register32(KGPTimerBase + KHoGpTimer_TCRR)); sl@0: } sl@0: sl@0: TBMNs DBmOmapChannel::TimerTicksToNs(TBMTicks ticks) sl@0: { sl@0: return ticks * KBMOmapNsPerTick; sl@0: } sl@0: sl@0: TBMTicks DBmOmapChannel::TimerNsToTicks(TBMNs ns) sl@0: { sl@0: return ns / KBMOmapNsPerTick; sl@0: } sl@0: sl@0: void DBmOmapChannel::Isr(TAny* ptr) sl@0: { sl@0: DBmOmapChannel* mCh = (DBmOmapChannel*) ptr; sl@0: BM_ASSERT(mCh->iIsr || mCh->iInterruptLatencyIsr); sl@0: if (mCh->iIsr) sl@0: { sl@0: mCh->iIsr->Isr(TUint(TOmap::Register32(KGPTimerBase + KHoGpTimer_TCRR))); sl@0: } sl@0: else sl@0: { sl@0: mCh->iInterruptLatencyIsr->InterruptLatencyIsr(TOmap::Register32(KGPTimerBase+KHoGpTimer_TCRR) - TOmap::Register32(KGPTimerBase+KHoGpTimer_TMAR)); sl@0: } sl@0: TOmap::ModifyRegister32(KGPTimerBase+KHoGpTimer_TIER, KHtGpTimer_TIER_Match, KClear32); sl@0: } sl@0: sl@0: TInt DBmOmapChannel::BindInterrupt() sl@0: { sl@0: TInt r=Interrupt::Bind(KGPTimerInt, Isr, this); sl@0: if (r != KErrNone) sl@0: { sl@0: return r; sl@0: } sl@0: // Clear Match interrupt status bit sl@0: TOmap::SetRegister32(KGPTimerBase + KHoGpTimer_TISR, KHtGpTimer_TISR_Match); sl@0: sl@0: Interrupt::Enable(KGPTimerInt); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt DBmOmapChannel::BindInterrupt(MBMIsr* aIsr) sl@0: { sl@0: BM_ASSERT(!iIsr); sl@0: BM_ASSERT(!iInterruptLatencyIsr); sl@0: iIsr = aIsr; sl@0: return BindInterrupt(); sl@0: } sl@0: sl@0: TInt DBmOmapChannel::BindInterrupt(MBMInterruptLatencyIsr* aIsr) sl@0: { sl@0: BM_ASSERT(!iIsr); sl@0: BM_ASSERT(!iInterruptLatencyIsr); sl@0: iInterruptLatencyIsr = aIsr; sl@0: return BindInterrupt(); sl@0: } sl@0: sl@0: sl@0: void DBmOmapChannel::RequestInterrupt() sl@0: { sl@0: BM_ASSERT(iIsr || iInterruptLatencyIsr); sl@0: TOmap::SetRegister32(KGPTimerBase+KHoGpTimer_TMAR, TOmap::Register32(KGPTimerBase+KHoGpTimer_TCRR) + KBMOmapInterruptDelayTicks); sl@0: // Clear Match interrupt sl@0: TOmap::SetRegister32(KGPTimerBase+KHoGpTimer_TISR, KHtGpTimer_TISR_Match); sl@0: // Enable Match interrupt sl@0: TOmap::SetRegister32(KGPTimerBase+KHoGpTimer_TIER, KHtGpTimer_TIER_Match); sl@0: } sl@0: sl@0: void DBmOmapChannel::CancelInterrupt() sl@0: { sl@0: if (iIsr || iInterruptLatencyIsr) sl@0: { sl@0: // Disable Match interrupt sl@0: TOmap::ModifyRegister32(KGPTimerBase+KHoGpTimer_TIER, KHtGpTimer_TIER_Match, KClear32); sl@0: } sl@0: }