diff options
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-bcmring/core.c | 108 |
2 files changed, 45 insertions, 64 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 43f003a5a0f4..903c9c4bd68e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -297,6 +297,7 @@ config ARCH_BCMRING | |||
297 | depends on MMU | 297 | depends on MMU |
298 | select CPU_V6 | 298 | select CPU_V6 |
299 | select ARM_AMBA | 299 | select ARM_AMBA |
300 | select ARM_TIMER_SP804 | ||
300 | select CLKDEV_LOOKUP | 301 | select CLKDEV_LOOKUP |
301 | select GENERIC_CLOCKEVENTS | 302 | select GENERIC_CLOCKEVENTS |
302 | select ARCH_WANT_OPTIONAL_GPIOLIB | 303 | select ARCH_WANT_OPTIONAL_GPIOLIB |
diff --git a/arch/arm/mach-bcmring/core.c b/arch/arm/mach-bcmring/core.c index eca20ed228b3..2cb39890256e 100644 --- a/arch/arm/mach-bcmring/core.c +++ b/arch/arm/mach-bcmring/core.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/io.h> | 37 | #include <linux/io.h> |
38 | #include <asm/irq.h> | 38 | #include <asm/irq.h> |
39 | #include <asm/hardware/arm_timer.h> | 39 | #include <asm/hardware/arm_timer.h> |
40 | #include <asm/hardware/timer-sp.h> | ||
40 | #include <asm/mach-types.h> | 41 | #include <asm/mach-types.h> |
41 | 42 | ||
42 | #include <asm/mach/arch.h> | 43 | #include <asm/mach/arch.h> |
@@ -97,6 +98,35 @@ static struct clk dummy_apb_pclk = { | |||
97 | .mode = CLK_MODE_XTAL, | 98 | .mode = CLK_MODE_XTAL, |
98 | }; | 99 | }; |
99 | 100 | ||
101 | /* Timer 0 - 25 MHz, Timer3 at bus clock rate, typically 150-166 MHz */ | ||
102 | #if defined(CONFIG_ARCH_FPGA11107) | ||
103 | /* fpga cpu/bus are currently 30 times slower so scale frequency as well to */ | ||
104 | /* slow down Linux's sense of time */ | ||
105 | #define TIMER0_FREQUENCY_MHZ (tmrHw_LOW_FREQUENCY_MHZ * 30) | ||
106 | #define TIMER1_FREQUENCY_MHZ (tmrHw_LOW_FREQUENCY_MHZ * 30) | ||
107 | #define TIMER3_FREQUENCY_MHZ (tmrHw_HIGH_FREQUENCY_MHZ * 30) | ||
108 | #define TIMER3_FREQUENCY_KHZ (tmrHw_HIGH_FREQUENCY_HZ / 1000 * 30) | ||
109 | #else | ||
110 | #define TIMER0_FREQUENCY_MHZ tmrHw_LOW_FREQUENCY_MHZ | ||
111 | #define TIMER1_FREQUENCY_MHZ tmrHw_LOW_FREQUENCY_MHZ | ||
112 | #define TIMER3_FREQUENCY_MHZ tmrHw_HIGH_FREQUENCY_MHZ | ||
113 | #define TIMER3_FREQUENCY_KHZ (tmrHw_HIGH_FREQUENCY_HZ / 1000) | ||
114 | #endif | ||
115 | |||
116 | static struct clk sp804_timer1_clk = { | ||
117 | .name = "sp804-timer-1", | ||
118 | .type = CLK_TYPE_PRIMARY, | ||
119 | .mode = CLK_MODE_XTAL, | ||
120 | .rate_hz = TIMER1_FREQUENCY_MHZ * 1000000, | ||
121 | }; | ||
122 | |||
123 | static struct clk sp804_timer3_clk = { | ||
124 | .name = "sp804-timer-3", | ||
125 | .type = CLK_TYPE_PRIMARY, | ||
126 | .mode = CLK_MODE_XTAL, | ||
127 | .rate_hz = TIMER3_FREQUENCY_KHZ * 1000, | ||
128 | }; | ||
129 | |||
100 | static struct clk_lookup lookups[] = { | 130 | static struct clk_lookup lookups[] = { |
101 | { /* Bus clock */ | 131 | { /* Bus clock */ |
102 | .con_id = "apb_pclk", | 132 | .con_id = "apb_pclk", |
@@ -107,6 +137,14 @@ static struct clk_lookup lookups[] = { | |||
107 | }, { /* UART1 */ | 137 | }, { /* UART1 */ |
108 | .dev_id = "uartb", | 138 | .dev_id = "uartb", |
109 | .clk = &uart_clk, | 139 | .clk = &uart_clk, |
140 | }, { /* SP804 timer 1 */ | ||
141 | .dev_id = "sp804", | ||
142 | .con_id = "timer1", | ||
143 | .clk = &sp804_timer1_clk, | ||
144 | }, { /* SP804 timer 3 */ | ||
145 | .dev_id = "sp804", | ||
146 | .con_id = "timer3", | ||
147 | .clk = &sp804_timer3_clk, | ||
110 | } | 148 | } |
111 | }; | 149 | }; |
112 | 150 | ||
@@ -160,25 +198,10 @@ void __init bcmring_amba_init(void) | |||
160 | /* | 198 | /* |
161 | * Where is the timer (VA)? | 199 | * Where is the timer (VA)? |
162 | */ | 200 | */ |
163 | #define TIMER0_VA_BASE MM_IO_BASE_TMR | 201 | #define TIMER0_VA_BASE ((void __iomem *)MM_IO_BASE_TMR) |
164 | #define TIMER1_VA_BASE (MM_IO_BASE_TMR + 0x20) | 202 | #define TIMER1_VA_BASE ((void __iomem *)(MM_IO_BASE_TMR + 0x20)) |
165 | #define TIMER2_VA_BASE (MM_IO_BASE_TMR + 0x40) | 203 | #define TIMER2_VA_BASE ((void __iomem *)(MM_IO_BASE_TMR + 0x40)) |
166 | #define TIMER3_VA_BASE (MM_IO_BASE_TMR + 0x60) | 204 | #define TIMER3_VA_BASE ((void __iomem *)(MM_IO_BASE_TMR + 0x60)) |
167 | |||
168 | /* Timer 0 - 25 MHz, Timer3 at bus clock rate, typically 150-166 MHz */ | ||
169 | #if defined(CONFIG_ARCH_FPGA11107) | ||
170 | /* fpga cpu/bus are currently 30 times slower so scale frequency as well to */ | ||
171 | /* slow down Linux's sense of time */ | ||
172 | #define TIMER0_FREQUENCY_MHZ (tmrHw_LOW_FREQUENCY_MHZ * 30) | ||
173 | #define TIMER1_FREQUENCY_MHZ (tmrHw_LOW_FREQUENCY_MHZ * 30) | ||
174 | #define TIMER3_FREQUENCY_MHZ (tmrHw_HIGH_FREQUENCY_MHZ * 30) | ||
175 | #define TIMER3_FREQUENCY_KHZ (tmrHw_HIGH_FREQUENCY_HZ / 1000 * 30) | ||
176 | #else | ||
177 | #define TIMER0_FREQUENCY_MHZ tmrHw_LOW_FREQUENCY_MHZ | ||
178 | #define TIMER1_FREQUENCY_MHZ tmrHw_LOW_FREQUENCY_MHZ | ||
179 | #define TIMER3_FREQUENCY_MHZ tmrHw_HIGH_FREQUENCY_MHZ | ||
180 | #define TIMER3_FREQUENCY_KHZ (tmrHw_HIGH_FREQUENCY_HZ / 1000) | ||
181 | #endif | ||
182 | 205 | ||
183 | #define TICKS_PER_uSEC TIMER0_FREQUENCY_MHZ | 206 | #define TICKS_PER_uSEC TIMER0_FREQUENCY_MHZ |
184 | 207 | ||
@@ -187,10 +210,7 @@ void __init bcmring_amba_init(void) | |||
187 | * | 210 | * |
188 | */ | 211 | */ |
189 | #define mSEC_1 1000 | 212 | #define mSEC_1 1000 |
190 | #define mSEC_5 (mSEC_1 * 5) | ||
191 | #define mSEC_10 (mSEC_1 * 10) | 213 | #define mSEC_10 (mSEC_1 * 10) |
192 | #define mSEC_25 (mSEC_1 * 25) | ||
193 | #define SEC_1 (mSEC_1 * 1000) | ||
194 | 214 | ||
195 | /* | 215 | /* |
196 | * How long is the timer interval? | 216 | * How long is the timer interval? |
@@ -277,53 +297,13 @@ static struct irqaction bcmring_timer_irq = { | |||
277 | .handler = bcmring_timer_interrupt, | 297 | .handler = bcmring_timer_interrupt, |
278 | }; | 298 | }; |
279 | 299 | ||
280 | static cycle_t bcmring_get_cycles_timer1(struct clocksource *cs) | ||
281 | { | ||
282 | return ~readl(TIMER1_VA_BASE + TIMER_VALUE); | ||
283 | } | ||
284 | |||
285 | static cycle_t bcmring_get_cycles_timer3(struct clocksource *cs) | ||
286 | { | ||
287 | return ~readl(TIMER3_VA_BASE + TIMER_VALUE); | ||
288 | } | ||
289 | |||
290 | static struct clocksource clocksource_bcmring_timer1 = { | ||
291 | .name = "timer1", | ||
292 | .rating = 200, | ||
293 | .read = bcmring_get_cycles_timer1, | ||
294 | .mask = CLOCKSOURCE_MASK(32), | ||
295 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
296 | }; | ||
297 | |||
298 | static struct clocksource clocksource_bcmring_timer3 = { | ||
299 | .name = "timer3", | ||
300 | .rating = 100, | ||
301 | .read = bcmring_get_cycles_timer3, | ||
302 | .mask = CLOCKSOURCE_MASK(32), | ||
303 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
304 | }; | ||
305 | |||
306 | static int __init bcmring_clocksource_init(void) | 300 | static int __init bcmring_clocksource_init(void) |
307 | { | 301 | { |
308 | /* setup timer1 as free-running clocksource */ | 302 | /* setup timer1 as free-running clocksource */ |
309 | writel(0, TIMER1_VA_BASE + TIMER_CTRL); | 303 | sp804_clocksource_init(TIMER1_VA_BASE, "timer1"); |
310 | writel(0xffffffff, TIMER1_VA_BASE + TIMER_LOAD); | ||
311 | writel(0xffffffff, TIMER1_VA_BASE + TIMER_VALUE); | ||
312 | writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, | ||
313 | TIMER1_VA_BASE + TIMER_CTRL); | ||
314 | |||
315 | clocksource_register_khz(&clocksource_bcmring_timer1, | ||
316 | TIMER1_FREQUENCY_MHZ * 1000); | ||
317 | 304 | ||
318 | /* setup timer3 as free-running clocksource */ | 305 | /* setup timer3 as free-running clocksource */ |
319 | writel(0, TIMER3_VA_BASE + TIMER_CTRL); | 306 | sp804_clocksource_init(TIMER3_VA_BASE, "timer3"); |
320 | writel(0xffffffff, TIMER3_VA_BASE + TIMER_LOAD); | ||
321 | writel(0xffffffff, TIMER3_VA_BASE + TIMER_VALUE); | ||
322 | writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, | ||
323 | TIMER3_VA_BASE + TIMER_CTRL); | ||
324 | |||
325 | clocksource_register_khz(&clocksource_bcmring_timer3, | ||
326 | TIMER3_FREQUENCY_KHZ); | ||
327 | 307 | ||
328 | return 0; | 308 | return 0; |
329 | } | 309 | } |