wdenk | 32fe287 | 2002-10-11 07:57:01 +0000 | [diff] [blame] | 1 | /* |
Marek Vasut | ba2d9be | 2011-11-26 10:02:41 +0100 | [diff] [blame] | 2 | * Marvell PXA2xx/3xx timer driver |
wdenk | 32fe287 | 2002-10-11 07:57:01 +0000 | [diff] [blame] | 3 | * |
Marek Vasut | ba2d9be | 2011-11-26 10:02:41 +0100 | [diff] [blame] | 4 | * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> |
wdenk | 32fe287 | 2002-10-11 07:57:01 +0000 | [diff] [blame] | 5 | * |
Wolfgang Denk | d79de1d | 2013-07-08 09:37:19 +0200 | [diff] [blame] | 6 | * SPDX-License-Identifier: GPL-2.0+ |
wdenk | 32fe287 | 2002-10-11 07:57:01 +0000 | [diff] [blame] | 7 | */ |
8 | |||||
wdenk | 32fe287 | 2002-10-11 07:57:01 +0000 | [diff] [blame] | 9 | #include <asm/arch/pxa-regs.h> |
Marek Vasut | 2db1e96 | 2010-09-09 09:50:39 +0200 | [diff] [blame] | 10 | #include <asm/io.h> |
11 | #include <common.h> | ||||
Jean-Christophe PLAGNIOL-VILLARD | e90368d | 2009-02-24 06:13:10 +0100 | [diff] [blame] | 12 | #include <div64.h> |
wdenk | 32fe287 | 2002-10-11 07:57:01 +0000 | [diff] [blame] | 13 | |
Marek Vasut | ba2d9be | 2011-11-26 10:02:41 +0100 | [diff] [blame] | 14 | DECLARE_GLOBAL_DATA_PTR; |
15 | |||||
16 | #define TIMER_LOAD_VAL 0xffffffff | ||||
17 | |||||
Simon Glass | 2655ee1 | 2012-12-13 20:48:34 +0000 | [diff] [blame] | 18 | #define timestamp (gd->arch.tbl) |
Simon Glass | a848da5 | 2012-12-13 20:48:35 +0000 | [diff] [blame] | 19 | #define lastinc (gd->arch.lastinc) |
wdenk | 32fe287 | 2002-10-11 07:57:01 +0000 | [diff] [blame] | 20 | |
Marek Vasut | 85cc88a | 2011-11-26 07:20:07 +0100 | [diff] [blame] | 21 | #if defined(CONFIG_CPU_PXA27X) || defined(CONFIG_CPU_MONAHANS) |
Marek Vasut | ba2d9be | 2011-11-26 10:02:41 +0100 | [diff] [blame] | 22 | #define TIMER_FREQ_HZ 3250000 |
Marek Vasut | 85cc88a | 2011-11-26 07:20:07 +0100 | [diff] [blame] | 23 | #elif defined(CONFIG_CPU_PXA25X) |
Marek Vasut | ba2d9be | 2011-11-26 10:02:41 +0100 | [diff] [blame] | 24 | #define TIMER_FREQ_HZ 3686400 |
Micha Kalfon | 8a75a5b | 2009-02-11 19:50:11 +0200 | [diff] [blame] | 25 | #else |
26 | #error "Timer frequency unknown - please config PXA CPU type" | ||||
27 | #endif | ||||
28 | |||||
Marek Vasut | ba2d9be | 2011-11-26 10:02:41 +0100 | [diff] [blame] | 29 | static unsigned long long tick_to_time(unsigned long long tick) |
Jean-Christophe PLAGNIOL-VILLARD | e90368d | 2009-02-24 06:13:10 +0100 | [diff] [blame] | 30 | { |
Tom Rini | 8dccca2 | 2013-12-05 14:48:37 -0500 | [diff] [blame] | 31 | return lldiv(tick * CONFIG_SYS_HZ, TIMER_FREQ_HZ); |
Jean-Christophe PLAGNIOL-VILLARD | e90368d | 2009-02-24 06:13:10 +0100 | [diff] [blame] | 32 | } |
33 | |||||
Marek Vasut | ba2d9be | 2011-11-26 10:02:41 +0100 | [diff] [blame] | 34 | static unsigned long long us_to_tick(unsigned long long us) |
Jean-Christophe PLAGNIOL-VILLARD | e90368d | 2009-02-24 06:13:10 +0100 | [diff] [blame] | 35 | { |
Tom Rini | 8dccca2 | 2013-12-05 14:48:37 -0500 | [diff] [blame] | 36 | return lldiv(us * TIMER_FREQ_HZ, 1000000); |
Jean-Christophe PLAGNIOL-VILLARD | e90368d | 2009-02-24 06:13:10 +0100 | [diff] [blame] | 37 | } |
38 | |||||
Marek Vasut | ba2d9be | 2011-11-26 10:02:41 +0100 | [diff] [blame] | 39 | int timer_init(void) |
wdenk | 32fe287 | 2002-10-11 07:57:01 +0000 | [diff] [blame] | 40 | { |
Graeme Russ | 944a7fe | 2011-07-15 02:21:14 +0000 | [diff] [blame] | 41 | writel(0, OSCR); |
Jean-Christophe PLAGNIOL-VILLARD | 8c9fc00 | 2009-05-15 23:47:02 +0200 | [diff] [blame] | 42 | return 0; |
wdenk | 32fe287 | 2002-10-11 07:57:01 +0000 | [diff] [blame] | 43 | } |
44 | |||||
Marek Vasut | ba2d9be | 2011-11-26 10:02:41 +0100 | [diff] [blame] | 45 | unsigned long long get_ticks(void) |
wdenk | 32fe287 | 2002-10-11 07:57:01 +0000 | [diff] [blame] | 46 | { |
Marek Vasut | ba2d9be | 2011-11-26 10:02:41 +0100 | [diff] [blame] | 47 | /* Current tick value */ |
48 | uint32_t now = readl(OSCR); | ||||
wdenk | 32fe287 | 2002-10-11 07:57:01 +0000 | [diff] [blame] | 49 | |
Marek Vasut | ba2d9be | 2011-11-26 10:02:41 +0100 | [diff] [blame] | 50 | if (now >= lastinc) { |
51 | /* | ||||
52 | * Normal mode (non roll) | ||||
53 | * Move stamp forward with absolute diff ticks | ||||
54 | */ | ||||
55 | timestamp += (now - lastinc); | ||||
56 | } else { | ||||
57 | /* We have rollover of incrementer */ | ||||
58 | timestamp += (TIMER_LOAD_VAL - lastinc) + now; | ||||
59 | } | ||||
60 | |||||
61 | lastinc = now; | ||||
62 | return timestamp; | ||||
wdenk | 32fe287 | 2002-10-11 07:57:01 +0000 | [diff] [blame] | 63 | } |
64 | |||||
Marek Vasut | ba2d9be | 2011-11-26 10:02:41 +0100 | [diff] [blame] | 65 | ulong get_timer(ulong base) |
wdenk | 32fe287 | 2002-10-11 07:57:01 +0000 | [diff] [blame] | 66 | { |
Marek Vasut | ba2d9be | 2011-11-26 10:02:41 +0100 | [diff] [blame] | 67 | return tick_to_time(get_ticks()) - base; |
wdenk | 32fe287 | 2002-10-11 07:57:01 +0000 | [diff] [blame] | 68 | } |
69 | |||||
Marek Vasut | ba2d9be | 2011-11-26 10:02:41 +0100 | [diff] [blame] | 70 | void __udelay(unsigned long usec) |
wdenk | 32fe287 | 2002-10-11 07:57:01 +0000 | [diff] [blame] | 71 | { |
Jean-Christophe PLAGNIOL-VILLARD | e90368d | 2009-02-24 06:13:10 +0100 | [diff] [blame] | 72 | unsigned long long tmp; |
wdenk | 32fe287 | 2002-10-11 07:57:01 +0000 | [diff] [blame] | 73 | ulong tmo; |
74 | |||||
Jean-Christophe PLAGNIOL-VILLARD | e90368d | 2009-02-24 06:13:10 +0100 | [diff] [blame] | 75 | tmo = us_to_tick(usec); |
76 | tmp = get_ticks() + tmo; /* get current timestamp */ | ||||
wdenk | 32fe287 | 2002-10-11 07:57:01 +0000 | [diff] [blame] | 77 | |
Jean-Christophe PLAGNIOL-VILLARD | e90368d | 2009-02-24 06:13:10 +0100 | [diff] [blame] | 78 | while (get_ticks() < tmp) /* loop till event */ |
79 | /*NOP*/; | ||||
wdenk | 49c3f67 | 2003-10-08 22:33:00 +0000 | [diff] [blame] | 80 | } |
Marek Vasut | 454afe7 | 2012-02-27 13:59:47 +0100 | [diff] [blame] | 81 | |
82 | ulong get_tbclk(void) | ||||
83 | { | ||||
84 | return TIMER_FREQ_HZ; | ||||
85 | } |