summaryrefslogtreecommitdiffstats
path: root/drivers/clocksource
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clocksource')
-rw-r--r--drivers/clocksource/timer-tegra20.c120
1 files changed, 43 insertions, 77 deletions
diff --git a/drivers/clocksource/timer-tegra20.c b/drivers/clocksource/timer-tegra20.c
index 1e7ece279730..4b30ba6228c1 100644
--- a/drivers/clocksource/timer-tegra20.c
+++ b/drivers/clocksource/timer-tegra20.c
@@ -40,13 +40,18 @@
40#define TIMER_PCR_INTR_CLR BIT(30) 40#define TIMER_PCR_INTR_CLR BIT(30)
41 41
42#ifdef CONFIG_ARM 42#ifdef CONFIG_ARM
43#define TIMER_CPU0 0x50 /* TIMER3 */ 43#define TIMER_CPU0 0x00 /* TIMER1 */
44#define TIMER_CPU2 0x50 /* TIMER3 */
45#define TIMER1_IRQ_IDX 0
46#define IRQ_IDX_FOR_CPU(cpu) (TIMER1_IRQ_IDX + cpu)
47#define TIMER_BASE_FOR_CPU(cpu) \
48 (((cpu) & 1) * 8 + ((cpu) < 2 ? TIMER_CPU0 : TIMER_CPU2))
44#else 49#else
45#define TIMER_CPU0 0x90 /* TIMER10 */ 50#define TIMER_CPU0 0x90 /* TIMER10 */
46#define TIMER10_IRQ_IDX 10 51#define TIMER10_IRQ_IDX 10
47#define IRQ_IDX_FOR_CPU(cpu) (TIMER10_IRQ_IDX + cpu) 52#define IRQ_IDX_FOR_CPU(cpu) (TIMER10_IRQ_IDX + cpu)
48#endif
49#define TIMER_BASE_FOR_CPU(cpu) (TIMER_CPU0 + (cpu) * 8) 53#define TIMER_BASE_FOR_CPU(cpu) (TIMER_CPU0 + (cpu) * 8)
54#endif
50 55
51static u32 usec_config; 56static u32 usec_config;
52static void __iomem *timer_reg_base; 57static void __iomem *timer_reg_base;
@@ -109,7 +114,6 @@ static void tegra_timer_resume(struct clock_event_device *evt)
109 writel(usec_config, timer_reg_base + TIMERUS_USEC_CFG); 114 writel(usec_config, timer_reg_base + TIMERUS_USEC_CFG);
110} 115}
111 116
112#ifdef CONFIG_ARM64
113static DEFINE_PER_CPU(struct timer_of, tegra_to) = { 117static DEFINE_PER_CPU(struct timer_of, tegra_to) = {
114 .flags = TIMER_OF_CLOCK | TIMER_OF_BASE, 118 .flags = TIMER_OF_CLOCK | TIMER_OF_BASE,
115 119
@@ -150,33 +154,8 @@ static int tegra_timer_stop(unsigned int cpu)
150 154
151 return 0; 155 return 0;
152} 156}
153#else /* CONFIG_ARM */
154static struct timer_of tegra_to = {
155 .flags = TIMER_OF_CLOCK | TIMER_OF_BASE | TIMER_OF_IRQ,
156
157 .clkevt = {
158 .name = "tegra_timer",
159 .rating = 300,
160 .features = CLOCK_EVT_FEAT_ONESHOT |
161 CLOCK_EVT_FEAT_PERIODIC |
162 CLOCK_EVT_FEAT_DYNIRQ,
163 .set_next_event = tegra_timer_set_next_event,
164 .set_state_shutdown = tegra_timer_shutdown,
165 .set_state_periodic = tegra_timer_set_periodic,
166 .set_state_oneshot = tegra_timer_shutdown,
167 .tick_resume = tegra_timer_shutdown,
168 .suspend = tegra_timer_suspend,
169 .resume = tegra_timer_resume,
170 .cpumask = cpu_possible_mask,
171 },
172
173 .of_irq = {
174 .index = 2,
175 .flags = IRQF_TIMER | IRQF_TRIGGER_HIGH,
176 .handler = tegra_timer_isr,
177 },
178};
179 157
158#ifdef CONFIG_ARM
180static u64 notrace tegra_read_sched_clock(void) 159static u64 notrace tegra_read_sched_clock(void)
181{ 160{
182 return readl(timer_reg_base + TIMERUS_CNTR_1US); 161 return readl(timer_reg_base + TIMERUS_CNTR_1US);
@@ -213,10 +192,12 @@ static struct clocksource suspend_rtc_clocksource = {
213}; 192};
214#endif 193#endif
215 194
216static int tegra_timer_common_init(struct device_node *np, struct timer_of *to) 195static int tegra_init_timer(struct device_node *np, bool tegra20)
217{ 196{
218 int ret = 0; 197 struct timer_of *to;
198 int cpu, ret;
219 199
200 to = this_cpu_ptr(&tegra_to);
220 ret = timer_of_init(np, to); 201 ret = timer_of_init(np, to);
221 if (ret < 0) 202 if (ret < 0)
222 goto out; 203 goto out;
@@ -258,29 +239,19 @@ static int tegra_timer_common_init(struct device_node *np, struct timer_of *to)
258 goto out; 239 goto out;
259 } 240 }
260 241
261 writel(usec_config, timer_of_base(to) + TIMERUS_USEC_CFG); 242 writel(usec_config, timer_reg_base + TIMERUS_USEC_CFG);
262
263out:
264 return ret;
265}
266
267#ifdef CONFIG_ARM64
268static int __init tegra_init_timer(struct device_node *np)
269{
270 int cpu, ret = 0;
271 struct timer_of *to;
272
273 to = this_cpu_ptr(&tegra_to);
274 ret = tegra_timer_common_init(np, to);
275 if (ret < 0)
276 goto out;
277 243
278 for_each_possible_cpu(cpu) { 244 for_each_possible_cpu(cpu) {
279 struct timer_of *cpu_to; 245 struct timer_of *cpu_to = per_cpu_ptr(&tegra_to, cpu);
246
247 /*
248 * TIMER1-9 are fixed to 1MHz, TIMER10-13 are running off the
249 * parent clock.
250 */
251 if (tegra20)
252 cpu_to->of_clk.rate = 1000000;
280 253
281 cpu_to = per_cpu_ptr(&tegra_to, cpu);
282 cpu_to->of_base.base = timer_reg_base + TIMER_BASE_FOR_CPU(cpu); 254 cpu_to->of_base.base = timer_reg_base + TIMER_BASE_FOR_CPU(cpu);
283 cpu_to->of_clk.rate = timer_of_rate(to);
284 cpu_to->clkevt.cpumask = cpumask_of(cpu); 255 cpu_to->clkevt.cpumask = cpumask_of(cpu);
285 cpu_to->clkevt.irq = 256 cpu_to->clkevt.irq =
286 irq_of_parse_and_map(np, IRQ_IDX_FOR_CPU(cpu)); 257 irq_of_parse_and_map(np, IRQ_IDX_FOR_CPU(cpu));
@@ -322,43 +293,39 @@ out:
322 timer_of_cleanup(to); 293 timer_of_cleanup(to);
323 return ret; 294 return ret;
324} 295}
296
297#ifdef CONFIG_ARM64
298static int __init tegra210_init_timer(struct device_node *np)
299{
300 return tegra_init_timer(np, false);
301}
302TIMER_OF_DECLARE(tegra210_timer, "nvidia,tegra210-timer", tegra210_init_timer);
325#else /* CONFIG_ARM */ 303#else /* CONFIG_ARM */
326static int __init tegra_init_timer(struct device_node *np) 304static int __init tegra20_init_timer(struct device_node *np)
327{ 305{
328 int ret = 0; 306 struct timer_of *to;
307 int err;
329 308
330 ret = tegra_timer_common_init(np, &tegra_to); 309 err = tegra_init_timer(np, true);
331 if (ret < 0) 310 if (err)
332 goto out; 311 return err;
333 312
334 tegra_to.of_base.base = timer_reg_base + TIMER_BASE_FOR_CPU(0); 313 to = this_cpu_ptr(&tegra_to);
335 tegra_to.of_clk.rate = 1000000; /* microsecond timer */
336 314
337 sched_clock_register(tegra_read_sched_clock, 32, 315 sched_clock_register(tegra_read_sched_clock, 32,
338 timer_of_rate(&tegra_to)); 316 timer_of_rate(to));
339 ret = clocksource_mmio_init(timer_reg_base + TIMERUS_CNTR_1US, 317 err = clocksource_mmio_init(timer_reg_base + TIMERUS_CNTR_1US,
340 "timer_us", timer_of_rate(&tegra_to), 318 "timer_us", timer_of_rate(to),
341 300, 32, clocksource_mmio_readl_up); 319 300, 32, clocksource_mmio_readl_up);
342 if (ret) { 320 if (err)
343 pr_err("Failed to register clocksource\n"); 321 pr_err("Failed to register clocksource: %d\n", err);
344 goto out;
345 }
346 322
347 tegra_delay_timer.read_current_timer = 323 tegra_delay_timer.read_current_timer =
348 tegra_delay_timer_read_counter_long; 324 tegra_delay_timer_read_counter_long;
349 tegra_delay_timer.freq = timer_of_rate(&tegra_to); 325 tegra_delay_timer.freq = timer_of_rate(to);
350 register_current_timer_delay(&tegra_delay_timer); 326 register_current_timer_delay(&tegra_delay_timer);
351 327
352 clockevents_config_and_register(&tegra_to.clkevt, 328 return 0;
353 timer_of_rate(&tegra_to),
354 0x1,
355 0x1fffffff);
356
357 return ret;
358out:
359 timer_of_cleanup(&tegra_to);
360
361 return ret;
362} 329}
363 330
364static int __init tegra20_init_rtc(struct device_node *np) 331static int __init tegra20_init_rtc(struct device_node *np)
@@ -374,6 +341,5 @@ static int __init tegra20_init_rtc(struct device_node *np)
374 return 0; 341 return 0;
375} 342}
376TIMER_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc); 343TIMER_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc);
344TIMER_OF_DECLARE(tegra20_timer, "nvidia,tegra20-timer", tegra20_init_timer);
377#endif 345#endif
378TIMER_OF_DECLARE(tegra210_timer, "nvidia,tegra210-timer", tegra_init_timer);
379TIMER_OF_DECLARE(tegra20_timer, "nvidia,tegra20-timer", tegra_init_timer);