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 | } |
