blob: dd0c11c53ce5a582aa5191218fb5bfc7a2e2839b [file] [log] [blame]
Deepa Dinamani1cc97642012-05-09 11:45:38 -07001/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
Deepa Dinamanidc036ae2011-12-20 18:19:52 -08002
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of Code Aurora Forum, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <debug.h>
30#include <reg.h>
Deepa Dinamani1cc97642012-05-09 11:45:38 -070031#include <compiler.h>
32#include <qtimer.h>
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080033#include <kernel/thread.h>
34
Deepa Dinamani1cc97642012-05-09 11:45:38 -070035static uint32_t ticks_per_sec;
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080036
37status_t platform_set_periodic_timer(platform_timer_callback callback,
38 void *arg, time_t interval)
39{
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080040
41 enter_critical_section();
42
Deepa Dinamani1cc97642012-05-09 11:45:38 -070043 qtimer_set_physical_timer(interval, callback, arg);
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080044
45 exit_critical_section();
46 return 0;
47}
48
49time_t current_time(void)
50{
Deepa Dinamani1cc97642012-05-09 11:45:38 -070051 return qtimer_current_time();
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080052}
53
Deepa Dinamani81eddd52012-05-31 11:18:50 -070054void qtimer_uninit()
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080055{
Deepa Dinamani1cc97642012-05-09 11:45:38 -070056 disable_qtimer();
57}
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080058
Deepa Dinamani1cc97642012-05-09 11:45:38 -070059/* Blocking function to wait until the specified ticks of the timer.
60 * Note: ticks to wait for cannot be more than 56 bit.
61 * Should be sufficient for all practical purposes.
62 */
63static void delay(uint64_t ticks)
64{
65 volatile uint64_t cnt;
66 uint64_t init_cnt;
67 uint64_t timeout = 0;
Deepa Dinamani7d6c8972011-12-14 15:16:56 -080068
Deepa Dinamani1cc97642012-05-09 11:45:38 -070069 cnt = qtimer_get_phy_timer_cnt();
70 init_cnt = cnt;
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080071
Deepa Dinamani1cc97642012-05-09 11:45:38 -070072 /* Calculate timeout = cnt + ticks (mod 2^56)
73 * to account for timer counter wrapping
74 */
75 timeout = (cnt + ticks) &
76 (uint64_t)(QTMR_PHY_CNT_MAX_VALUE);
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080077
Deepa Dinamani1cc97642012-05-09 11:45:38 -070078 /* Wait out till the counter wrapping occurs
79 * in cases where there is a wrapping.
80 */
81 while(timeout < cnt && init_cnt <= cnt)
82 /* read global counter */
83 cnt = qtimer_get_phy_timer_cnt();
84
85 /* Wait till the number of ticks is reached*/
86 while(timeout > cnt)
87 /* read global counter */
88 cnt = qtimer_get_phy_timer_cnt();
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080089
90}
91
Deepa Dinamani1cc97642012-05-09 11:45:38 -070092
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080093void mdelay(unsigned msecs)
94{
Deepa Dinamani1cc97642012-05-09 11:45:38 -070095 uint64_t ticks;
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080096
Deepa Dinamani1cc97642012-05-09 11:45:38 -070097 ticks = (msecs * ticks_per_sec) / 1000;
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080098
Deepa Dinamani1cc97642012-05-09 11:45:38 -070099 delay(ticks);
Deepa Dinamanidc036ae2011-12-20 18:19:52 -0800100}
101
102void udelay(unsigned usecs)
103{
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700104 uint64_t ticks;
Deepa Dinamanidc036ae2011-12-20 18:19:52 -0800105
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700106 ticks = (usecs * ticks_per_sec) / 1000000;
Deepa Dinamanidc036ae2011-12-20 18:19:52 -0800107
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700108 delay(ticks);
Deepa Dinamanidc036ae2011-12-20 18:19:52 -0800109}
110
111/* Return current time in micro seconds */
112bigtime_t current_time_hires(void)
113{
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700114 return qtimer_current_time() * 1000000ULL;
115}
116
117void qtimer_init()
118{
119 ticks_per_sec = qtimer_get_frequency();
120}
121
122uint32_t qtimer_tick_rate()
123{
124 return ticks_per_sec;
Deepa Dinamanidc036ae2011-12-20 18:19:52 -0800125}