blob: b30153a7d80cc29e84cd8a29094b35e6b55d28f3 [file] [log] [blame]
Brian Swetland2500aa12009-01-01 04:33:55 -08001/*
2 * Copyright (c) 2008, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google, Inc. nor the names of its contributors
15 * may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
25 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <debug.h>
33#include <reg.h>
34#include <sys/types.h>
35
36#include <platform/timer.h>
37#include <platform/irqs.h>
38#include <platform/iomap.h>
39#include <platform/interrupts.h>
40#include <kernel/thread.h>
41
Ajay Dudani232ce812009-12-02 00:14:11 -080042#ifdef PLATFORM_MSM7X30
43
44#define MSM_GPT_BASE (MSM_TMR_BASE + 0x4)
45#define MSM_DGT_BASE (MSM_TMR_BASE + 0x24)
46#define GPT_REG(off) (MSM_GPT_BASE + (off))
47#define DGT_REG(off) (MSM_DGT_BASE + (off))
48#define SPSS_TIMER_STATUS (MSM_TMR_BASE + 0x88)
49
50#define GPT_MATCH_VAL GPT_REG(0x0000)
51#define GPT_COUNT_VAL GPT_REG(0x0004)
52#define GPT_ENABLE GPT_REG(0x0008)
53#define GPT_ENABLE_CLR_ON_MATCH_EN 2
54#define GPT_ENABLE_EN 1
55#define GPT_CLEAR GPT_REG(0x000C)
56
57#define DGT_MATCH_VAL DGT_REG(0x0000)
58#define DGT_COUNT_VAL DGT_REG(0x0004)
59#define DGT_ENABLE DGT_REG(0x0008)
60#define DGT_ENABLE_CLR_ON_MATCH_EN 2
61#define DGT_ENABLE_EN 1
62#define DGT_CLEAR DGT_REG(0x000C)
Chandan Uddaraju037b2262010-01-13 15:21:27 -080063#define DGT_CLK_CTL DGT_REG(0x0010)
Ajay Dudani232ce812009-12-02 00:14:11 -080064
Ajay Dudanic51bf632010-04-15 10:41:23 -070065#define HW_REVISION_NUMBER 0xABC00270
66
67
Ajay Dudani232ce812009-12-02 00:14:11 -080068#else
Brian Swetland2500aa12009-01-01 04:33:55 -080069#define GPT_REG(off) (MSM_GPT_BASE + (off))
70
71#define GPT_MATCH_VAL GPT_REG(0x0000)
72#define GPT_COUNT_VAL GPT_REG(0x0004)
73#define GPT_ENABLE GPT_REG(0x0008)
74#define GPT_ENABLE_CLR_ON_MATCH_EN 2
75#define GPT_ENABLE_EN 1
76#define GPT_CLEAR GPT_REG(0x000C)
77
78#define DGT_MATCH_VAL GPT_REG(0x0010)
79#define DGT_COUNT_VAL GPT_REG(0x0014)
80#define DGT_ENABLE GPT_REG(0x0018)
81#define DGT_ENABLE_CLR_ON_MATCH_EN 2
82#define DGT_ENABLE_EN 1
83#define DGT_CLEAR GPT_REG(0x001C)
84
Brian Swetland0d7b1b82009-01-21 21:03:28 -080085#define SPSS_TIMER_STATUS GPT_REG(0x0034)
Ajay Dudani232ce812009-12-02 00:14:11 -080086#endif
87
Chandan Uddaraju1679e682010-03-19 16:40:44 -070088#if defined PLATFORM_QSD8K
89#define DGT_HZ 4800000 /* Uses TCXO/4 (19.2 MHz / 4) */
90#elif defined PLATFORM_MSM7X30
David Ng56936762010-03-25 19:50:32 -070091#if _EMMC_BOOT
92#define DGT_HZ 19200000 /* Uses TCXO (19.2 MHz) */
93#else
Chandan Uddaraju1679e682010-03-19 16:40:44 -070094#define DGT_HZ 6144000 /* Uses LPXO/4 (24.576 MHz / 4) */
David Ng56936762010-03-25 19:50:32 -070095#endif
Chandan Uddaraju1679e682010-03-19 16:40:44 -070096#else
97#define DGT_HZ 19200000 /* Uses TCXO (19.2 MHz) */
98#endif
99
Brian Swetland2500aa12009-01-01 04:33:55 -0800100
101static platform_timer_callback timer_callback;
102static void *timer_arg;
103static time_t timer_interval;
104
105static volatile uint32_t ticks;
106
107static enum handler_return timer_irq(void *arg)
108{
109 ticks += timer_interval;
110 return timer_callback(timer_arg, ticks);
111}
112
113status_t platform_set_periodic_timer(
114 platform_timer_callback callback,
115 void *arg, time_t interval)
116{
Chandan Uddaraju037b2262010-01-13 15:21:27 -0800117#ifdef PLATFORM_MSM7X30
118 unsigned val = 0;
119 unsigned mask = (0x1 << 28);
120 //Check for the hardware revision
121 val = readl(HW_REVISION_NUMBER);
122 if(val & mask)
123 writel(1, DGT_CLK_CTL);
124#endif
Brian Swetland2500aa12009-01-01 04:33:55 -0800125 enter_critical_section();
126
127 timer_callback = callback;
128 timer_arg = arg;
129 timer_interval = interval;
130
Chandan Uddaraju1679e682010-03-19 16:40:44 -0700131 writel(timer_interval * (DGT_HZ / 1000), DGT_MATCH_VAL);
Brian Swetland2500aa12009-01-01 04:33:55 -0800132 writel(0, DGT_CLEAR);
133 writel(DGT_ENABLE_EN | DGT_ENABLE_CLR_ON_MATCH_EN, DGT_ENABLE);
134
135 register_int_handler(INT_DEBUG_TIMER_EXP, timer_irq, 0);
136 unmask_interrupt(INT_DEBUG_TIMER_EXP);
137
138 exit_critical_section();
139 return 0;
140}
141
142
143time_t current_time(void)
144{
145 return ticks;
146}
147
148void platform_init_timer(void)
149{
150 writel(0, DGT_ENABLE);
151}
152
Brian Swetland0d7b1b82009-01-21 21:03:28 -0800153static void wait_for_timer_op(void)
154{
Ajay Dudani232ce812009-12-02 00:14:11 -0800155#if PLATFORM_QSD8K || PLATFORM_MSM7X30
Brian Swetland0d7b1b82009-01-21 21:03:28 -0800156 while(readl(SPSS_TIMER_STATUS)) ;
157#endif
158}
159
160void platform_uninit_timer(void)
161{
162 writel(0, DGT_ENABLE);
163 wait_for_timer_op();
164 writel(0, DGT_CLEAR);
165 wait_for_timer_op();
166}
Chandan Uddaraju852cd2c2009-12-17 14:28:28 -0800167
168void mdelay(unsigned msecs)
169{
170 msecs *= 33;
171
172 writel(0, GPT_CLEAR);
173 writel(0, GPT_ENABLE);
174 while(readl(GPT_COUNT_VAL) != 0) ;
175
176 writel(GPT_ENABLE_EN, GPT_ENABLE);
177 while(readl(GPT_COUNT_VAL) < msecs) ;
178
179 writel(0, GPT_ENABLE);
180 writel(0, GPT_CLEAR);
181}