blob: bcd9a9a3be31fe548eadddcade660762bbaf1b80 [file] [log] [blame]
Duy Truongf3ac7b32013-02-13 01:07:28 -08001/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
Deepa Dinamanid642b802012-05-16 10:49:01 -07002
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 Dinamanid642b802012-05-16 10:49:01 -070013 * 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>
31#include <compiler.h>
32#include <qtimer.h>
Channagoud Kadabi6d6223c2013-08-05 15:27:55 -070033#include <arch/defines.h>
Deepa Dinamanid642b802012-05-16 10:49:01 -070034#include <platform/irqs.h>
35#include <platform/iomap.h>
36#include <platform/interrupts.h>
37#include <qtimer_mmap_hw.h>
38
39static platform_timer_callback timer_callback;
40static void *timer_arg;
41static time_t timer_interval;
42/* time in ms from start of LK. */
43static volatile uint32_t current_time;
44static uint32_t tick_count;
45
Deepa Dinamanid642b802012-05-16 10:49:01 -070046static void qtimer_enable();
47
48static enum handler_return qtimer_irq(void *arg)
49{
50 current_time += timer_interval;
51
52 /* Program the down counter again to get
53 * an interrupt after timer_interval msecs
54 */
Deepa Dinamanid642b802012-05-16 10:49:01 -070055 writel(tick_count, QTMR_V1_CNTP_TVAL);
Deepa Dinamanid642b802012-05-16 10:49:01 -070056 dsb();
57
58 return timer_callback(timer_arg, current_time);
59}
60
Amol Jadi42d7b5a2012-05-04 14:50:32 -070061
Deepa Dinamanid642b802012-05-16 10:49:01 -070062/* Programs the Physical Secure Down counter timer.
63 * interval : Counter ticks till expiry interrupt is fired.
64 */
65void qtimer_set_physical_timer(time_t msecs_interval,
Amol Jadi42d7b5a2012-05-04 14:50:32 -070066 platform_timer_callback tmr_callback,
67 void *tmr_arg)
Deepa Dinamanid642b802012-05-16 10:49:01 -070068{
Deepa Dinamanid642b802012-05-16 10:49:01 -070069 qtimer_disable();
70
71 /* Save the timer interval and call back data*/
72 tick_count = msecs_interval * qtimer_tick_rate() / 1000;;
73 timer_interval = msecs_interval;
74 timer_arg = tmr_arg;
75 timer_callback = tmr_callback;
76
77 /* Set Physical Down Counter */
78 writel(tick_count, QTMR_V1_CNTP_TVAL);
79 dsb();
80
Amol Jadi42d7b5a2012-05-04 14:50:32 -070081 register_int_handler(INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP, qtimer_irq, 0);
Deepa Dinamanid642b802012-05-16 10:49:01 -070082
Amol Jadi42d7b5a2012-05-04 14:50:32 -070083 unmask_interrupt(INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP);
84
85 qtimer_enable();
Deepa Dinamanid642b802012-05-16 10:49:01 -070086}
87
88
89/* Function to return the frequency of the timer */
90uint32_t qtimer_get_frequency()
91{
92 uint32_t freq;
93
94 /* Read the Global counter frequency */
Amol Jadi42d7b5a2012-05-04 14:50:32 -070095 /* freq = readl(QTMR_V1_CNTFRQ); */
96 /* TODO: remove this when bootchaint sets up the frequency. */
97 freq = 19200000;
Deepa Dinamanid642b802012-05-16 10:49:01 -070098
99 return freq;
Deepa Dinamanid642b802012-05-16 10:49:01 -0700100}
101
102static void qtimer_enable()
103{
104 uint32_t ctrl;
105
106 ctrl = readl(QTMR_V1_CNTP_CTL);
107
108 /* Program CTRL Register */
109 ctrl |= QTMR_TIMER_CTRL_ENABLE;
110 ctrl &= ~QTMR_TIMER_CTRL_INT_MASK;
111
112 writel(ctrl, QTMR_V1_CNTP_CTL);
Deepa Dinamanid642b802012-05-16 10:49:01 -0700113 dsb();
114}
115
116void qtimer_disable()
117{
118 uint32_t ctrl;
119
Deepa Dinamanid642b802012-05-16 10:49:01 -0700120 ctrl = readl(QTMR_V1_CNTP_CTL);
121
122 /* program cntrl register */
123 ctrl &= ~QTMR_TIMER_CTRL_ENABLE;
124 ctrl |= QTMR_TIMER_CTRL_INT_MASK;
125
126 writel(ctrl, QTMR_V1_CNTP_CTL);
Deepa Dinamanid642b802012-05-16 10:49:01 -0700127 dsb();
128}
129
130inline __ALWAYS_INLINE uint64_t qtimer_get_phy_timer_cnt()
131{
132 uint32_t phy_cnt_lo;
Deepa Dinamani1f01f192012-08-10 16:04:10 -0700133 uint32_t phy_cnt_hi_1;
134 uint32_t phy_cnt_hi_2;
Deepa Dinamanid642b802012-05-16 10:49:01 -0700135
Deepa Dinamani1f01f192012-08-10 16:04:10 -0700136 do {
137 phy_cnt_hi_1 = readl(QTMR_V1_CNTPCT_HI);
138 phy_cnt_lo = readl(QTMR_V1_CNTPCT_LO);
139 phy_cnt_hi_2 = readl(QTMR_V1_CNTPCT_HI);
140 } while (phy_cnt_hi_1 != phy_cnt_hi_2);
Deepa Dinamanid642b802012-05-16 10:49:01 -0700141
Deepa Dinamani6da49a82012-08-15 10:54:45 -0700142 return ((uint64_t)phy_cnt_hi_1 << 32) | phy_cnt_lo;
Deepa Dinamanid642b802012-05-16 10:49:01 -0700143}
144
145uint32_t qtimer_current_time()
146{
147 return current_time;
148}