|
1 // Copyright (c) 2003-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 // e32test\benchmark\bm_momap_pdd.cpp |
|
15 // |
|
16 // |
|
17 |
|
18 #include <kernel/kernel.h> |
|
19 #include <omap.h> |
|
20 #include <omap_plat.h> |
|
21 #include <omap_powerresources.h> // TResourceMgr methods |
|
22 #include <powerresources_assp.h> // ASSP resources |
|
23 #include "k32bm.h" |
|
24 |
|
25 // Note that this uses GPTimer2, these make it easy to swap around |
|
26 const TUint KGPTimerBase = KHwBaseGpTimer2Reg; |
|
27 const TUint KGPTimerClkSel = KHt_MOD_CONF_CTRL1_GPTIMER2_CLK_SEL; |
|
28 const TUint KGPTimerInt = EIrqLv1_GpTimer2; |
|
29 |
|
30 class DBmOmap : public DPhysicalDevice |
|
31 { |
|
32 public: |
|
33 DBmOmap(); |
|
34 ~DBmOmap(); |
|
35 virtual TInt Install(); |
|
36 virtual void GetCaps(TDes8& aDes) const; |
|
37 virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); |
|
38 virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); |
|
39 }; |
|
40 |
|
41 class DBmOmapChannel : public DBMPChannel |
|
42 { |
|
43 public: |
|
44 DBmOmapChannel(); |
|
45 ~DBmOmapChannel(); |
|
46 virtual TBMTicks TimerPeriod(); // Report timing spec |
|
47 virtual TBMTicks TimerStamp(); // Get current system timer tick time |
|
48 virtual TBMNs TimerTicksToNs(TBMTicks); // Tick/nS conversions |
|
49 virtual TBMTicks TimerNsToTicks(TBMNs); |
|
50 virtual TInt BindInterrupt(MBMIsr*); // Pass in client ISRs to invoke |
|
51 virtual TInt BindInterrupt(MBMInterruptLatencyIsr*); |
|
52 virtual void RequestInterrupt(); // Invoke an ISR |
|
53 virtual void CancelInterrupt(); |
|
54 |
|
55 private: |
|
56 TInt BindInterrupt(); // Attach to OST interrupt |
|
57 |
|
58 static const TInt KOmapOscFreqHz = 3000000; // 12Mhz / 4 = 3MHz |
|
59 static const TBMTicks KBMOmapPeriod = (((TBMTicks) 1) << 32); |
|
60 static const TBMNs KBMOmapNsPerTick = (1000*1000*1000) / KOmapOscFreqHz; |
|
61 |
|
62 // calculate 1ms in timer ticks |
|
63 static const TInt KBMOmapInterruptDelayTicks = KOmapOscFreqHz / 1000; |
|
64 |
|
65 static void Isr(TAny*); |
|
66 |
|
67 MBMIsr* iIsr; |
|
68 MBMInterruptLatencyIsr* iInterruptLatencyIsr; |
|
69 }; |
|
70 |
|
71 |
|
72 DECLARE_STANDARD_PDD() |
|
73 // |
|
74 // Create a new device |
|
75 // |
|
76 { |
|
77 __ASSERT_CRITICAL; |
|
78 return new DBmOmap; |
|
79 } |
|
80 |
|
81 DBmOmap::DBmOmap() |
|
82 // |
|
83 // Constructor |
|
84 // |
|
85 { |
|
86 //iUnitsMask=0; |
|
87 iVersion = TVersion(1,0,1); |
|
88 |
|
89 // place requirement on xor clock |
|
90 TResourceMgr::Request(KPowerArmEn_XorpCk); |
|
91 // Stop timer |
|
92 TOmap::ModifyRegister32(KGPTimerBase + KHoGpTimer_TCLR, KHtGpTimer_TCLR_St, KClear32); //Stop the timer |
|
93 |
|
94 // Drive this gptimer by the arm xor clock |
|
95 TOmapPlat::ModifyConfigReg(KHoBaseConfMOD_CONF_CTRL1, KGPTimerClkSel, 0); |
|
96 // Prescale enable = 12/4 = 3MHz |
|
97 TOmap::ModifyRegister32(KGPTimerBase + KHoGpTimer_TCLR, (KHmGpTimer_TCLR_PTV), (1 << KHsGpTimer_TCLR_PTV | KHtGpTimer_TCLR_PRE) ); |
|
98 |
|
99 // Enable "smart Idle mode" |
|
100 TOmap::SetRegister32(KGPTimerBase + KHoGpTimerTIOCP_CFG, (KHtGpTimer_TIOCP_CFG_SmartIdle << KHsGpTimer_TIOCP_CFG_IdleMode)); |
|
101 // Load TimerLoad register to zero so when overflow occurs the counter starts from zero again. |
|
102 TOmap::SetRegister32(KGPTimerBase + KHoGpTimer_TLDR, 0x0); |
|
103 // Load Timer Trig register which clears the prescale counter and loads the value in TLDR to TCRR |
|
104 TOmap::SetRegister32(KGPTimerBase + KHoGpTimer_TTGR, 0x1); |
|
105 |
|
106 // Start the GPTimer. This configuration will pause counting when stopped by the jtag |
|
107 TOmap::ModifyRegister32(KGPTimerBase + KHoGpTimer_TCLR, KClear32, (KHtGpTimer_TCLR_St|KHtGpTimer_TCLR_AR|KHtGpTimer_TCLR_CE)); |
|
108 while(TOmap::Register32(KGPTimerBase + KHoGpTimer_TWPS)); |
|
109 } |
|
110 |
|
111 DBmOmap::~DBmOmap() |
|
112 { |
|
113 // Stop timer |
|
114 TOmap::ModifyRegister32(KGPTimerBase + KHoGpTimer_TCLR, KHtGpTimer_TCLR_St, KClear32); |
|
115 while(TOmap::Register32(KGPTimerBase + KHoGpTimer_TWPS)); |
|
116 |
|
117 // Release requirement on xor clock |
|
118 TResourceMgr::Release(KPowerArmEn_XorpCk); |
|
119 } |
|
120 |
|
121 TInt DBmOmap::Install() |
|
122 // |
|
123 // Install the device driver. |
|
124 // |
|
125 { |
|
126 TInt r = SetName(&KBMPdName); |
|
127 return r; |
|
128 } |
|
129 |
|
130 void DBmOmap::GetCaps(TDes8& aDes) const |
|
131 // |
|
132 // Return the Comm capabilities. |
|
133 // |
|
134 { |
|
135 } |
|
136 |
|
137 TInt DBmOmap::Create(DBase*& aChannel, TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/) |
|
138 // |
|
139 // Create a channel on the device. |
|
140 // |
|
141 { |
|
142 __ASSERT_CRITICAL; |
|
143 aChannel = new DBmOmapChannel; |
|
144 return aChannel?KErrNone:KErrNoMemory; |
|
145 } |
|
146 |
|
147 TInt DBmOmap::Validate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer) |
|
148 { |
|
149 if (!Kern::QueryVersionSupported(iVersion,aVer)) |
|
150 { |
|
151 return KErrNotSupported; |
|
152 } |
|
153 return KErrNone; |
|
154 } |
|
155 |
|
156 // Note that the standard benchmark tests will expect to create >1 |
|
157 // channel (with the same LDD/PDD(unit)) hence this function must be |
|
158 // capable of being invoked multiple times. |
|
159 |
|
160 DBmOmapChannel::DBmOmapChannel() |
|
161 { |
|
162 // iIsr = NULL; |
|
163 // iInterruptLatencyIsr = NULL; |
|
164 } |
|
165 |
|
166 DBmOmapChannel::~DBmOmapChannel() |
|
167 { |
|
168 if (iIsr || iInterruptLatencyIsr) |
|
169 { |
|
170 // Leave timer running |
|
171 // TOmap::ModifyRegister32(KGPTimerBase + KHoGpTimer_TCLR, KHtGpTimer_TCLR_St, KClear32); //Stop the timer |
|
172 Interrupt::Disable(KGPTimerInt); |
|
173 Interrupt::Unbind(KGPTimerInt); |
|
174 } |
|
175 } |
|
176 |
|
177 TBMTicks DBmOmapChannel::TimerPeriod() |
|
178 { |
|
179 return KBMOmapPeriod; |
|
180 } |
|
181 |
|
182 TBMTicks DBmOmapChannel::TimerStamp() |
|
183 { |
|
184 return TUint(TOmap::Register32(KGPTimerBase + KHoGpTimer_TCRR)); |
|
185 } |
|
186 |
|
187 TBMNs DBmOmapChannel::TimerTicksToNs(TBMTicks ticks) |
|
188 { |
|
189 return ticks * KBMOmapNsPerTick; |
|
190 } |
|
191 |
|
192 TBMTicks DBmOmapChannel::TimerNsToTicks(TBMNs ns) |
|
193 { |
|
194 return ns / KBMOmapNsPerTick; |
|
195 } |
|
196 |
|
197 void DBmOmapChannel::Isr(TAny* ptr) |
|
198 { |
|
199 DBmOmapChannel* mCh = (DBmOmapChannel*) ptr; |
|
200 BM_ASSERT(mCh->iIsr || mCh->iInterruptLatencyIsr); |
|
201 if (mCh->iIsr) |
|
202 { |
|
203 mCh->iIsr->Isr(TUint(TOmap::Register32(KGPTimerBase + KHoGpTimer_TCRR))); |
|
204 } |
|
205 else |
|
206 { |
|
207 mCh->iInterruptLatencyIsr->InterruptLatencyIsr(TOmap::Register32(KGPTimerBase+KHoGpTimer_TCRR) - TOmap::Register32(KGPTimerBase+KHoGpTimer_TMAR)); |
|
208 } |
|
209 TOmap::ModifyRegister32(KGPTimerBase+KHoGpTimer_TIER, KHtGpTimer_TIER_Match, KClear32); |
|
210 } |
|
211 |
|
212 TInt DBmOmapChannel::BindInterrupt() |
|
213 { |
|
214 TInt r=Interrupt::Bind(KGPTimerInt, Isr, this); |
|
215 if (r != KErrNone) |
|
216 { |
|
217 return r; |
|
218 } |
|
219 // Clear Match interrupt status bit |
|
220 TOmap::SetRegister32(KGPTimerBase + KHoGpTimer_TISR, KHtGpTimer_TISR_Match); |
|
221 |
|
222 Interrupt::Enable(KGPTimerInt); |
|
223 return KErrNone; |
|
224 } |
|
225 |
|
226 TInt DBmOmapChannel::BindInterrupt(MBMIsr* aIsr) |
|
227 { |
|
228 BM_ASSERT(!iIsr); |
|
229 BM_ASSERT(!iInterruptLatencyIsr); |
|
230 iIsr = aIsr; |
|
231 return BindInterrupt(); |
|
232 } |
|
233 |
|
234 TInt DBmOmapChannel::BindInterrupt(MBMInterruptLatencyIsr* aIsr) |
|
235 { |
|
236 BM_ASSERT(!iIsr); |
|
237 BM_ASSERT(!iInterruptLatencyIsr); |
|
238 iInterruptLatencyIsr = aIsr; |
|
239 return BindInterrupt(); |
|
240 } |
|
241 |
|
242 |
|
243 void DBmOmapChannel::RequestInterrupt() |
|
244 { |
|
245 BM_ASSERT(iIsr || iInterruptLatencyIsr); |
|
246 TOmap::SetRegister32(KGPTimerBase+KHoGpTimer_TMAR, TOmap::Register32(KGPTimerBase+KHoGpTimer_TCRR) + KBMOmapInterruptDelayTicks); |
|
247 // Clear Match interrupt |
|
248 TOmap::SetRegister32(KGPTimerBase+KHoGpTimer_TISR, KHtGpTimer_TISR_Match); |
|
249 // Enable Match interrupt |
|
250 TOmap::SetRegister32(KGPTimerBase+KHoGpTimer_TIER, KHtGpTimer_TIER_Match); |
|
251 } |
|
252 |
|
253 void DBmOmapChannel::CancelInterrupt() |
|
254 { |
|
255 if (iIsr || iInterruptLatencyIsr) |
|
256 { |
|
257 // Disable Match interrupt |
|
258 TOmap::ModifyRegister32(KGPTimerBase+KHoGpTimer_TIER, KHtGpTimer_TIER_Match, KClear32); |
|
259 } |
|
260 } |