blob: c8d6bd74cf4d9f9a778814cef7455ff39f000f72 [file] [log] [blame]
Deepa Dinamanib2a8a8b2013-07-18 14:13:08 -07001/* Copyright (c) 2012-2013, The Linux Foundation. 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.
Duy Truongf3ac7b32013-02-13 01:07:28 -080012 * * Neither the name of The Linux Foundation nor the names of its
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080013 * 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 Dinamanid642b802012-05-16 10:49:01 -070056 qtimer_disable();
Deepa Dinamani1cc97642012-05-09 11:45:38 -070057}
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 */
Deepa Dinamani1f01f192012-08-10 16:04:10 -070075 timeout = (cnt + ticks) & (uint64_t)(QTMR_PHY_CNT_MAX_VALUE);
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080076
Deepa Dinamanid642b802012-05-16 10:49:01 -070077 /* Wait out till the counter wrapping occurs
Deepa Dinamani1cc97642012-05-09 11:45:38 -070078 * in cases where there is a wrapping.
79 */
80 while(timeout < cnt && init_cnt <= cnt)
81 /* read global counter */
82 cnt = qtimer_get_phy_timer_cnt();
83
84 /* Wait till the number of ticks is reached*/
85 while(timeout > cnt)
86 /* read global counter */
87 cnt = qtimer_get_phy_timer_cnt();
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080088
89}
90
Deepa Dinamani1cc97642012-05-09 11:45:38 -070091
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080092void mdelay(unsigned msecs)
93{
Deepa Dinamani1cc97642012-05-09 11:45:38 -070094 uint64_t ticks;
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080095
Deepa Dinamanib2a8a8b2013-07-18 14:13:08 -070096 ticks = ((uint64_t) msecs * ticks_per_sec) / 1000;
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080097
Deepa Dinamani1cc97642012-05-09 11:45:38 -070098 delay(ticks);
Deepa Dinamanidc036ae2011-12-20 18:19:52 -080099}
100
101void udelay(unsigned usecs)
102{
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700103 uint64_t ticks;
Deepa Dinamanidc036ae2011-12-20 18:19:52 -0800104
Deepa Dinamanib2a8a8b2013-07-18 14:13:08 -0700105 ticks = ((uint64_t) usecs * ticks_per_sec) / 1000000;
Deepa Dinamanidc036ae2011-12-20 18:19:52 -0800106
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700107 delay(ticks);
Deepa Dinamanidc036ae2011-12-20 18:19:52 -0800108}
109
110/* Return current time in micro seconds */
111bigtime_t current_time_hires(void)
112{
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700113 return qtimer_current_time() * 1000000ULL;
114}
115
116void qtimer_init()
117{
118 ticks_per_sec = qtimer_get_frequency();
119}
120
121uint32_t qtimer_tick_rate()
122{
123 return ticks_per_sec;
Deepa Dinamanidc036ae2011-12-20 18:19:52 -0800124}