• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/arch/arm/mach-tegra/
1/*
2 * arch/arch/mach-tegra/timer.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 *	Colin Cross <ccross@google.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#include <linux/init.h>
21#include <linux/time.h>
22#include <linux/interrupt.h>
23#include <linux/irq.h>
24#include <linux/clockchips.h>
25#include <linux/clocksource.h>
26#include <linux/clk.h>
27#include <linux/io.h>
28#include <linux/cnt32_to_63.h>
29
30#include <asm/mach/time.h>
31#include <asm/mach/time.h>
32#include <asm/localtimer.h>
33
34#include <mach/iomap.h>
35#include <mach/irqs.h>
36
37#include "board.h"
38#include "clock.h"
39
40#define TIMERUS_CNTR_1US 0x10
41#define TIMERUS_USEC_CFG 0x14
42#define TIMERUS_CNTR_FREEZE 0x4c
43
44#define TIMER1_BASE 0x0
45#define TIMER2_BASE 0x8
46#define TIMER3_BASE 0x50
47#define TIMER4_BASE 0x58
48
49#define TIMER_PTV 0x0
50#define TIMER_PCR 0x4
51
52struct tegra_timer;
53
54static void __iomem *timer_reg_base = IO_ADDRESS(TEGRA_TMR1_BASE);
55
56#define timer_writel(value, reg) \
57	__raw_writel(value, (u32)timer_reg_base + (reg))
58#define timer_readl(reg) \
59	__raw_readl((u32)timer_reg_base + (reg))
60
61static int tegra_timer_set_next_event(unsigned long cycles,
62					 struct clock_event_device *evt)
63{
64	u32 reg;
65
66	reg = 0x80000000 | ((cycles > 1) ? (cycles-1) : 0);
67	timer_writel(reg, TIMER3_BASE + TIMER_PTV);
68
69	return 0;
70}
71
72static void tegra_timer_set_mode(enum clock_event_mode mode,
73				    struct clock_event_device *evt)
74{
75	u32 reg;
76
77	timer_writel(0, TIMER3_BASE + TIMER_PTV);
78
79	switch (mode) {
80	case CLOCK_EVT_MODE_PERIODIC:
81		reg = 0xC0000000 | ((1000000/HZ)-1);
82		timer_writel(reg, TIMER3_BASE + TIMER_PTV);
83		break;
84	case CLOCK_EVT_MODE_ONESHOT:
85		break;
86	case CLOCK_EVT_MODE_UNUSED:
87	case CLOCK_EVT_MODE_SHUTDOWN:
88	case CLOCK_EVT_MODE_RESUME:
89		break;
90	}
91}
92
93static cycle_t tegra_clocksource_read(struct clocksource *cs)
94{
95	return cnt32_to_63(timer_readl(TIMERUS_CNTR_1US));
96}
97
98static struct clock_event_device tegra_clockevent = {
99	.name		= "timer0",
100	.rating		= 300,
101	.features	= CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
102	.set_next_event	= tegra_timer_set_next_event,
103	.set_mode	= tegra_timer_set_mode,
104};
105
106static struct clocksource tegra_clocksource = {
107	.name	= "timer_us",
108	.rating	= 300,
109	.read	= tegra_clocksource_read,
110	.mask	= 0x7FFFFFFFFFFFFFFFULL,
111	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
112};
113
114unsigned long long sched_clock(void)
115{
116	return clocksource_cyc2ns(tegra_clocksource.read(&tegra_clocksource),
117		tegra_clocksource.mult, tegra_clocksource.shift);
118}
119
120static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id)
121{
122	struct clock_event_device *evt = (struct clock_event_device *)dev_id;
123	timer_writel(1<<30, TIMER3_BASE + TIMER_PCR);
124	evt->event_handler(evt);
125	return IRQ_HANDLED;
126}
127
128static struct irqaction tegra_timer_irq = {
129	.name		= "timer0",
130	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_HIGH,
131	.handler	= tegra_timer_interrupt,
132	.dev_id		= &tegra_clockevent,
133	.irq		= INT_TMR3,
134};
135
136static void __init tegra_init_timer(void)
137{
138	unsigned long rate = clk_measure_input_freq();
139	int ret;
140
141#ifdef CONFIG_HAVE_ARM_TWD
142	twd_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x600);
143#endif
144
145	switch (rate) {
146	case 12000000:
147		timer_writel(0x000b, TIMERUS_USEC_CFG);
148		break;
149	case 13000000:
150		timer_writel(0x000c, TIMERUS_USEC_CFG);
151		break;
152	case 19200000:
153		timer_writel(0x045f, TIMERUS_USEC_CFG);
154		break;
155	case 26000000:
156		timer_writel(0x0019, TIMERUS_USEC_CFG);
157		break;
158	default:
159		WARN(1, "Unknown clock rate");
160	}
161
162	if (clocksource_register_hz(&tegra_clocksource, 1000000)) {
163		printk(KERN_ERR "Failed to register clocksource\n");
164		BUG();
165	}
166
167	ret = setup_irq(tegra_timer_irq.irq, &tegra_timer_irq);
168	if (ret) {
169		printk(KERN_ERR "Failed to register timer IRQ: %d\n", ret);
170		BUG();
171	}
172
173	clockevents_calc_mult_shift(&tegra_clockevent, 1000000, 5);
174	tegra_clockevent.max_delta_ns =
175		clockevent_delta2ns(0x1fffffff, &tegra_clockevent);
176	tegra_clockevent.min_delta_ns =
177		clockevent_delta2ns(0x1, &tegra_clockevent);
178	tegra_clockevent.cpumask = cpu_all_mask;
179	tegra_clockevent.irq = tegra_timer_irq.irq;
180	clockevents_register_device(&tegra_clockevent);
181
182	return;
183}
184
185struct sys_timer tegra_timer = {
186	.init = tegra_init_timer,
187};
188