1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32 33 34
35
36 package ti.sysbios.family.arm.systimer;
37
38 import xdc.rov.ViewInfo;
39
40 import xdc.runtime.Error;
41 import xdc.runtime.Types;
42
43 import ti.sysbios.family.arm.gic.Hwi;
44 import ti.sysbios.interfaces.ITimer;
45
46 /*!
47 * ======== Timer ========
48 * Generic Timer Peripheral Manager for Arm v7A family prcoessors
49 *
50 * Generic Timer is an optional extension to an ARM v7A or v7R processor
51 * implementation. Generic Timer provides a system counter that measures
52 * the passing of time in real-time. This system counter is in a always-on
53 * power domain. The system counter is guaranteed to be atleast 56-bits
54 * wide. The timer increments at a frequency typically in the range 1-50MHz.
55 * On OMAP5, the Generic Timers increment at a frequency of 6.144 MHz.
56 * This timer is guaranteed to have a roll-over time of no less than
57 * 40 years.
58 *
59 * This module supports non-secure PL1 physical counter and virtual counter
60 * operating as 64-bit upcounters. The timer triggers when the appropriate
61 * counter reaches the programmed threshold value.
62 * Timer Triggered = ((Counter[63:0] - Threshold[63:0]) >= 0)
63 *
64 * For more information please refer the Generic Timer section on pg. B8-1929
65 * of ARM Architecture TRM for v7-AR.
66 *
67 * @p(html)
68 * <h3> Calling Context </h3>
69 * <table border="1" cellpadding="3">
70 * <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
71 *
72 * <tr><th> Function </th><th> Hwi </th><th> Swi </th><th> Task </th><th> Main </th><th> Startup </th></tr>
73 * <!-- -->
74 * <tr><td> {@link #getNumTimers} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
75 * <tr><td> {@link #getStatus} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
76 * <tr><td> {@link #Params_init} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
77 * <tr><td> {@link #construct} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
78 * <tr><td> {@link #create} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
79 * <tr><td> {@link #delete} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
80 * <tr><td> {@link #destruct} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
81 * <tr><td> {@link #getCount} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
82 * <tr><td> {@link #getCount64} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
83 * <tr><td> {@link #getFreq} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
84 * <tr><td> {@link #getPeriod} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
85 * <tr><td> {@link #getPeriod64} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
86 * <tr><td> {@link #reconfig} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
87 * <tr><td> {@link #setPeriod} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
88 * <tr><td> {@link #setPeriod64} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
89 * <tr><td> {@link #setPeriodMicroSecs} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
90 * <tr><td> {@link #setPeriodMicroSecs64} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
91 * <tr><td> {@link #start} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
92 * <tr><td> {@link #stop} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
93 * <tr><td colspan="6"> Definitions: <br />
94 * <ul>
95 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
96 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
97 * <li> <b>Task</b>: API is callable from a Task thread. </li>
98 * <li> <b>Main</b>: API is callable during any of these phases: </li>
99 * <ul>
100 * <li> In your module startup after this module is started (e.g. Timer_Module_startupDone() returns TRUE). </li>
101 * <li> During xdc.runtime.Startup.lastFxns. </li>
102 * <li> During main().</li>
103 * <li> During BIOS.startupFxns.</li>
104 * </ul>
105 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
106 * <ul>
107 * <li> During xdc.runtime.Startup.firstFxns.</li>
108 * <li> In your module startup before this module is started (e.g. Timer_Module_startupDone() returns FALSE).</li>
109 * </ul>
110 * </ul>
111 * </td></tr>
112 *
113 * </table>
114 * @p
115 *
116 */
117 @ModuleStartup
118 @InstanceInitStatic
119
120 module Timer inherits ti.sysbios.interfaces.ITimer
121 {
122 /*!
123 * Max value of Timer period for PeriodType_COUNTS
124 *
125 * The architecture guarantees the system counter is atleast
126 * 56-bits wide. Therefore, this module limits the maximum
127 * count to the largest 56 bit number.
128 */
129 const UInt64 MAX_PERIOD = 0x00FFFFFFFFFFFFFF;
130
131 /*! Number of timer peripherals on chip */
132 const Int NUM_TIMER_DEVICES = 2;
133
134 /*! override supportsDynamic - this Timer does support RunMode_DYNAMIC */
135 override metaonly config Bool supportsDynamic = true;
136
137 /*! @_nodoc */
138 @XmlDtd
139 metaonly struct BasicView {
140 Ptr halTimerHandle;
141 String label;
142 UInt id;
143 String startMode;
144 String runMode;
145 String period;
146 String periodType;
147 UInt intNum;
148 String tickFxn[];
149 UArg arg;
150 String extFreq;
151 String hwiHandle;
152 String prevThreshold;
153 String nextThreshold;
154 };
155
156 /*! @_nodoc */
157 metaonly struct ModuleView {
158 String availMask;
159 }
160
161 /*! @_nodoc */
162 @Facet
163 metaonly config ViewInfo.Instance rovViewInfo =
164 ViewInfo.create({
165 viewMap: [
166 [
167 'Basic',
168 {
169 type: ViewInfo.INSTANCE,
170 viewInitFxn: 'viewInitBasic',
171 structName: 'BasicView'
172 }
173 ],
174 [
175 'Module',
176 {
177 type: ViewInfo.MODULE,
178 viewInitFxn: 'viewInitModule',
179 structName: 'ModuleView'
180 }
181 ],
182 ]
183 });
184
185 /*!
186 * Error raised when timer id specified is not supported.
187 */
188 config Error.Id E_invalidTimer =
189 {msg: "E_invalidTimer: Invalid Timer Id %d"};
190
191 /*!
192 * Error raised when timer requested is in use
193 */
194 config Error.Id E_notAvailable =
195 {msg: "E_notAvailable: Timer not available %d"};
196
197 /*!
198 * Error raised when Hwi Params has mask where self is turned on.
199 *
200 * This is not allowed because the timers on this platform do not
201 * support one-shot mode and a stub is used to stop it.
202 * Another timer interrupt cannot go off when the ISR is running.
203 */
204 config Error.Id E_invalidHwiMask =
205 {msg: "E_InvalidMask: Mask in hwiParams cannot enable self"};
206
207 /*!
208 * Error raised when period requested is not supported
209 */
210 config Error.Id E_cannotSupport =
211 {msg: "E_cannotSupport: Timer cannot support requested period %d"};
212
213 /*!
214 * ======== intNumDef ========
215 * A15 Generic Timer interrupt numbers
216 *
217 * Generic Timer Interrupts are forwarded to GIC's private peripheral
218 * interrupts and have a architecture defined fixed mapping that should
219 * be same across all A15 variants.
220 *
221 * Non-secure physical timer -> PPI2 or Interrupt #30
222 * Virtual timer -> PPI4 or Interrupt #27
223 */
224 config UInt intNumDef[2];
225
226 /*!
227 * ======== anyMask ========
228 * Available mask to be used when select = Timer_ANY
229 */
230 config UInt anyMask = 0x3;
231
232 /*!
233 * ======== availMask ========
234 * Available mask tracks the available/free timer peripherals
235 */
236 config UInt availMask = 0x3;
237
238 /*!
239 * ======== intFreq ========
240 * Default internal timer input clock frequency.
241 *
242 * @a(NOTE)
243 * On OMAP5x, DRA7x and ADAS devices, the Generic Timer
244 * operates at a fixed frequency of 6144000 Hz.
245 *
246 * On Keystone 2 devices, the Genric Timer operates at
247 * Main PLL frequency /6. The default internal timer
248 * input frequency for Keystone 2 devices is 20480000 Hz
249 * which is derived from the Main PLL bypass clock fequency
250 * of 122.88 MHz. If the Main PLL is initialized to a different
251 * frequency then this config param should be updated accordigly.
252 *
253 * For instance, if Main PLL frequency is configured to be 614.4 MHz,
254 * the Timer operates at 102.4 MHz and Timer.intFreq should be set to
255 * this value.
256 *
257 * @p(code)
258 * var Timer = xdc.useModule('ti.sysbios.family.arm.systimer.Timer');
259 * Timer.intFreq.lo = 102400000; // = (Main PLL freq / 6)
260 * Timer.intFreq.hi = 0;
261 * @p
262 */
263 config Types.FreqHz intFreq;
264
265 /*!
266 * ======== oneShotStub ========
267 * @_nodoc
268 * This stub stops timer and disables its interrupt.
269 *
270 * @param(arg) Timer Handle.
271 */
272 Void oneShotStub(UArg arg);
273
274 /*!
275 * ======== periodicStub ========
276 * @_nodoc
277 * Cortex-A15 Generic timer does not support periodic mode. This
278 * function re-loads the timer with the desired period.
279 *
280 * @param(arg) Timer Handle.
281 */
282 Void periodicStub(UArg arg);
283
284 /*!
285 * ======== getHandle ========
286 * @_nodoc
287 * Used by TimestampProvider module to get hold of timer handle used by
288 * Clock.
289 *
290 * @param(id) timer Id.
291 */
292 Handle getHandle(UInt id);
293
294 instance:
295
296 /*! Hwi Params for Hwi Object. Default is null.*/
297 config Hwi.Params *hwiParams = null;
298
299 /*!
300 * ======== period64 ========
301 * Period of a tick
302 *
303 * The period can be specified in timer counts or microseconds and its
304 * default value is 0.
305 *
306 * This timer implementation supports a max period of UInt64 timer
307 * counts.
308 */
309 config UInt64 period64 = 0;
310
311 /*!
312 * ======== reconfig ========
313 * Used to modify static timer instances at runtime.
314 *
315 * @param(timerParams) timer Params
316 * @param(tickFxn) functions that runs when timer expires.
317 */
318 Void reconfig(FuncPtr tickFxn, const Params *timerParams, Error.Block *eb);
319
320 /*!
321 * ======== setPeriod64 ========
322 * Set timer period specified in timer counts
323 *
324 * Timer_setPeriod64() invokes Timer_stop() prior to setting the period
325 * and leaves the timer in the stopped state.
326 *
327 * A15 architecture guarantees a minimum timer counter width of 56 bits.
328 * Therefore, the period should be limited to a value no greater than
329 * 0xFFFFFFFFFFFFFF.
330 *
331 * To dynamically change the period of a timer you must
332 * protect against re-entrancy by disabling interrupts.
333 * Use the following call sequence to guarantee proper results:
334 *
335 * @p(code)
336 * // disable interrupts if an interrupt could lead to
337 * // another call to Timer_start().
338 * key = Hwi_disable();
339 * Timer_setPeriod64(period);
340 * Timer_start();
341 * Hwi_restore(key);
342 * @p
343 *
344 *
345 * @a(side effects)
346 * Calls Timer_stop(), and disables the timer's interrupt.
347 *
348 * @param(period) 64 bit period in timer counts
349 */
350 Void setPeriod64(UInt64 period);
351
352 /*!
353 * ======== setPeriodMicroSecs64 ========
354 * Set timer period specified in microseconds.
355 *
356 * A best-effort method will be used to set the period register.
357 * There might be a slight rounding error based on resolution of timer
358 * period register. If the timer frequency cannot support the requested
359 * period, i.e. the timer period register cannot support the requested
360 * period, then this function returns false.
361 *
362 * Timer_setPeriodMicroSecs() invokes Timer_stop() prior to setting
363 * the period and leaves the timer in the stopped state.
364 *
365 * To dynamically change the period of a timer you must
366 * protect against re-entrancy by disabling interrupts.
367 * Use the following call sequence to guarantee proper results:
368 *
369 * @p(code)
370 * // disable interrupts if an interrupt could lead to
371 * // another call to Timer_start().
372 * key = Hwi_disable();
373 * Timer_setPeriodMicroSecs(period);
374 * Timer_start();
375 * Hwi_restore(key);
376 * @p
377 *
378 * @param(period) period in microseconds
379 */
380 Bool setPeriodMicroSecs64(UInt64 microsecs);
381
382 /*!
383 * ======== getPeriod64 ========
384 * Get timer period in timer counts
385 *
386 * @b(returns) 64 bit period in timer counts
387 */
388 UInt64 getPeriod64();
389
390 /*!
391 * ======== getCount64 ========
392 * Read timer counter register
393 *
394 * @b(returns) 64 bit timer counter value
395 */
396 UInt64 getCount64();
397
398
399 internal:
400
401 /*!
402 * ======== startupNeeded ========
403 * Flag used to prevent misc code from being brought in
404 * un-necessarily
405 */
406 config UInt startupNeeded = false;
407
408 409 410 411
412 Void initDevice(Object *timer);
413
414 415 416 417
418 Int postInit(Object *timer, Error.Block *eb);
419
420 421 422
423 Bool checkOverflow(UInt64 a, UInt64 b);
424
425 /*!
426 * ======== readPhyCtrl ========
427 * @_nodoc
428 * Return PL1 Physical Timer Control register contents
429 */
430 UInt32 readPhyCtrl();
431
432 /*!
433 * ======== readPhyCnt ========
434 * @_nodoc
435 * Return PL1 Physical Timer Count
436 */
437 Void readPhyCnt(UInt64 *timerCount);
438
439 /*!
440 * ======== writePhyCtrl ========
441 * @_nodoc
442 * Write argument to PL1 Physical Timer Control register
443 */
444 Void writePhyCtrl(UInt32 arg0);
445
446 /*!
447 * ======== writePhyCmpVal ========
448 * @_nodoc
449 * Write argument to PL1 Physical Timer CompareValue register
450 */
451 Void writePhyCmpVal(UInt64 *compareVal);
452
453 /*!
454 * ======== readVirtCtrl ========
455 * @_nodoc
456 * Return Virtual Timer Control register contents
457 */
458 UInt32 readVirtCtrl();
459
460 /*!
461 * ======== readVirtCnt ========
462 * @_nodoc
463 * Return Virtual Timer Count
464 */
465 Void readVirtCnt(UInt64 *timerCount);
466
467 /*!
468 * ======== tickReconfigSmp ========
469 */
470 Void tickReconfigSmp(UArg arg);
471
472 /*!
473 * ======== writeVirtCtrl ========
474 * @_nodoc
475 * Write argument to Virtual Timer Control register
476 */
477 Void writeVirtCtrl(UInt32 arg0);
478
479 /*!
480 * ======== writeVirtCmpVal ========
481 * @_nodoc
482 * Write argument to Virtual Timer CompareValue register
483 */
484 Void writeVirtCmpVal(UInt64 *compareVal);
485
486 struct Instance_State {
487 Bool staticInst;
488 Int id;
489 ITimer.RunMode runMode;
490 ITimer.StartMode startMode;
491 UInt64 period;
492 ITimer.PeriodType periodType;
493 UInt intNum;
494 UArg arg;
495 Hwi.FuncPtr tickFxn;
496 Types.FreqHz extFreq;
497 Hwi.Handle hwi;
498 UInt64 prevThreshold;
499 UInt64 nextThreshold;
500 UInt64 savedCurrCount;
501 }
502
503 struct Module_State {
504 UInt availMask;
505 Handle handles[];
506 }
507 }