diff options
-rw-r--r-- | arch/arm/mach-omap2/timer.c | 23 | ||||
-rw-r--r-- | arch/arm/plat-omap/dmtimer.c | 32 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/dmtimer.h | 144 |
3 files changed, 123 insertions, 76 deletions
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index cf1de7d2630d..69466f388417 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c | |||
@@ -78,7 +78,7 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) | |||
78 | { | 78 | { |
79 | struct clock_event_device *evt = &clockevent_gpt; | 79 | struct clock_event_device *evt = &clockevent_gpt; |
80 | 80 | ||
81 | __omap_dm_timer_write_status(clkev.io_base, OMAP_TIMER_INT_OVERFLOW); | 81 | __omap_dm_timer_write_status(&clkev, OMAP_TIMER_INT_OVERFLOW); |
82 | 82 | ||
83 | evt->event_handler(evt); | 83 | evt->event_handler(evt); |
84 | return IRQ_HANDLED; | 84 | return IRQ_HANDLED; |
@@ -93,7 +93,7 @@ static struct irqaction omap2_gp_timer_irq = { | |||
93 | static int omap2_gp_timer_set_next_event(unsigned long cycles, | 93 | static int omap2_gp_timer_set_next_event(unsigned long cycles, |
94 | struct clock_event_device *evt) | 94 | struct clock_event_device *evt) |
95 | { | 95 | { |
96 | __omap_dm_timer_load_start(clkev.io_base, OMAP_TIMER_CTRL_ST, | 96 | __omap_dm_timer_load_start(&clkev, OMAP_TIMER_CTRL_ST, |
97 | 0xffffffff - cycles, 1); | 97 | 0xffffffff - cycles, 1); |
98 | 98 | ||
99 | return 0; | 99 | return 0; |
@@ -104,16 +104,16 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode, | |||
104 | { | 104 | { |
105 | u32 period; | 105 | u32 period; |
106 | 106 | ||
107 | __omap_dm_timer_stop(clkev.io_base, 1, clkev.rate); | 107 | __omap_dm_timer_stop(&clkev, 1, clkev.rate); |
108 | 108 | ||
109 | switch (mode) { | 109 | switch (mode) { |
110 | case CLOCK_EVT_MODE_PERIODIC: | 110 | case CLOCK_EVT_MODE_PERIODIC: |
111 | period = clkev.rate / HZ; | 111 | period = clkev.rate / HZ; |
112 | period -= 1; | 112 | period -= 1; |
113 | /* Looks like we need to first set the load value separately */ | 113 | /* Looks like we need to first set the load value separately */ |
114 | __omap_dm_timer_write(clkev.io_base, OMAP_TIMER_LOAD_REG, | 114 | __omap_dm_timer_write(&clkev, OMAP_TIMER_LOAD_REG, |
115 | 0xffffffff - period, 1); | 115 | 0xffffffff - period, 1); |
116 | __omap_dm_timer_load_start(clkev.io_base, | 116 | __omap_dm_timer_load_start(&clkev, |
117 | OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_ST, | 117 | OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_ST, |
118 | 0xffffffff - period, 1); | 118 | 0xffffffff - period, 1); |
119 | break; | 119 | break; |
@@ -189,7 +189,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, | |||
189 | clk_put(src); | 189 | clk_put(src); |
190 | } | 190 | } |
191 | } | 191 | } |
192 | __omap_dm_timer_reset(timer->io_base, 1, 1); | 192 | __omap_dm_timer_init_regs(timer); |
193 | __omap_dm_timer_reset(timer, 1, 1); | ||
193 | timer->posted = 1; | 194 | timer->posted = 1; |
194 | 195 | ||
195 | timer->rate = clk_get_rate(timer->fclk); | 196 | timer->rate = clk_get_rate(timer->fclk); |
@@ -210,7 +211,7 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, | |||
210 | omap2_gp_timer_irq.dev_id = (void *)&clkev; | 211 | omap2_gp_timer_irq.dev_id = (void *)&clkev; |
211 | setup_irq(clkev.irq, &omap2_gp_timer_irq); | 212 | setup_irq(clkev.irq, &omap2_gp_timer_irq); |
212 | 213 | ||
213 | __omap_dm_timer_int_enable(clkev.io_base, OMAP_TIMER_INT_OVERFLOW); | 214 | __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW); |
214 | 215 | ||
215 | clockevent_gpt.mult = div_sc(clkev.rate, NSEC_PER_SEC, | 216 | clockevent_gpt.mult = div_sc(clkev.rate, NSEC_PER_SEC, |
216 | clockevent_gpt.shift); | 217 | clockevent_gpt.shift); |
@@ -251,7 +252,7 @@ static struct omap_dm_timer clksrc; | |||
251 | static DEFINE_CLOCK_DATA(cd); | 252 | static DEFINE_CLOCK_DATA(cd); |
252 | static cycle_t clocksource_read_cycles(struct clocksource *cs) | 253 | static cycle_t clocksource_read_cycles(struct clocksource *cs) |
253 | { | 254 | { |
254 | return (cycle_t)__omap_dm_timer_read_counter(clksrc.io_base, 1); | 255 | return (cycle_t)__omap_dm_timer_read_counter(&clksrc, 1); |
255 | } | 256 | } |
256 | 257 | ||
257 | static struct clocksource clocksource_gpt = { | 258 | static struct clocksource clocksource_gpt = { |
@@ -266,7 +267,7 @@ static void notrace dmtimer_update_sched_clock(void) | |||
266 | { | 267 | { |
267 | u32 cyc; | 268 | u32 cyc; |
268 | 269 | ||
269 | cyc = __omap_dm_timer_read_counter(clksrc.io_base, 1); | 270 | cyc = __omap_dm_timer_read_counter(&clksrc, 1); |
270 | 271 | ||
271 | update_sched_clock(&cd, cyc, (u32)~0); | 272 | update_sched_clock(&cd, cyc, (u32)~0); |
272 | } | 273 | } |
@@ -276,7 +277,7 @@ unsigned long long notrace sched_clock(void) | |||
276 | u32 cyc = 0; | 277 | u32 cyc = 0; |
277 | 278 | ||
278 | if (clksrc.reserved) | 279 | if (clksrc.reserved) |
279 | cyc = __omap_dm_timer_read_counter(clksrc.io_base, 1); | 280 | cyc = __omap_dm_timer_read_counter(&clksrc, 1); |
280 | 281 | ||
281 | return cyc_to_sched_clock(&cd, cyc, (u32)~0); | 282 | return cyc_to_sched_clock(&cd, cyc, (u32)~0); |
282 | } | 283 | } |
@@ -293,7 +294,7 @@ static void __init omap2_gp_clocksource_init(int gptimer_id, | |||
293 | pr_info("OMAP clocksource: GPTIMER%d at %lu Hz\n", | 294 | pr_info("OMAP clocksource: GPTIMER%d at %lu Hz\n", |
294 | gptimer_id, clksrc.rate); | 295 | gptimer_id, clksrc.rate); |
295 | 296 | ||
296 | __omap_dm_timer_load_start(clksrc.io_base, | 297 | __omap_dm_timer_load_start(&clksrc, |
297 | OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1); | 298 | OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1); |
298 | init_sched_clock(&cd, dmtimer_update_sched_clock, 32, clksrc.rate); | 299 | init_sched_clock(&cd, dmtimer_update_sched_clock, 32, clksrc.rate); |
299 | 300 | ||
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 75a847dd776a..e23b7cf2b219 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c | |||
@@ -170,7 +170,8 @@ static spinlock_t dm_timer_lock; | |||
170 | */ | 170 | */ |
171 | static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg) | 171 | static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg) |
172 | { | 172 | { |
173 | return __omap_dm_timer_read(timer->io_base, reg, timer->posted); | 173 | WARN_ON((reg & 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET); |
174 | return __omap_dm_timer_read(timer, reg, timer->posted); | ||
174 | } | 175 | } |
175 | 176 | ||
176 | /* | 177 | /* |
@@ -182,15 +183,19 @@ static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg) | |||
182 | static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg, | 183 | static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg, |
183 | u32 value) | 184 | u32 value) |
184 | { | 185 | { |
185 | __omap_dm_timer_write(timer->io_base, reg, value, timer->posted); | 186 | WARN_ON((reg & 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET); |
187 | __omap_dm_timer_write(timer, reg, value, timer->posted); | ||
186 | } | 188 | } |
187 | 189 | ||
188 | static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer) | 190 | static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer) |
189 | { | 191 | { |
190 | int c; | 192 | int c; |
191 | 193 | ||
194 | if (!timer->sys_stat) | ||
195 | return; | ||
196 | |||
192 | c = 0; | 197 | c = 0; |
193 | while (!(omap_dm_timer_read_reg(timer, OMAP_TIMER_SYS_STAT_REG) & 1)) { | 198 | while (!(__raw_readl(timer->sys_stat) & 1)) { |
194 | c++; | 199 | c++; |
195 | if (c > 100000) { | 200 | if (c > 100000) { |
196 | printk(KERN_ERR "Timer failed to reset\n"); | 201 | printk(KERN_ERR "Timer failed to reset\n"); |
@@ -219,7 +224,7 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer) | |||
219 | if (cpu_class_is_omap2()) | 224 | if (cpu_class_is_omap2()) |
220 | wakeup = 1; | 225 | wakeup = 1; |
221 | 226 | ||
222 | __omap_dm_timer_reset(timer->io_base, autoidle, wakeup); | 227 | __omap_dm_timer_reset(timer, autoidle, wakeup); |
223 | timer->posted = 1; | 228 | timer->posted = 1; |
224 | } | 229 | } |
225 | 230 | ||
@@ -401,7 +406,7 @@ void omap_dm_timer_stop(struct omap_dm_timer *timer) | |||
401 | rate = clk_get_rate(timer->fclk); | 406 | rate = clk_get_rate(timer->fclk); |
402 | #endif | 407 | #endif |
403 | 408 | ||
404 | __omap_dm_timer_stop(timer->io_base, timer->posted, rate); | 409 | __omap_dm_timer_stop(timer, timer->posted, rate); |
405 | } | 410 | } |
406 | EXPORT_SYMBOL_GPL(omap_dm_timer_stop); | 411 | EXPORT_SYMBOL_GPL(omap_dm_timer_stop); |
407 | 412 | ||
@@ -466,7 +471,7 @@ void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, | |||
466 | } | 471 | } |
467 | l |= OMAP_TIMER_CTRL_ST; | 472 | l |= OMAP_TIMER_CTRL_ST; |
468 | 473 | ||
469 | __omap_dm_timer_load_start(timer->io_base, l, load, timer->posted); | 474 | __omap_dm_timer_load_start(timer, l, load, timer->posted); |
470 | } | 475 | } |
471 | EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start); | 476 | EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start); |
472 | 477 | ||
@@ -519,7 +524,7 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_set_prescaler); | |||
519 | void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, | 524 | void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, |
520 | unsigned int value) | 525 | unsigned int value) |
521 | { | 526 | { |
522 | __omap_dm_timer_int_enable(timer->io_base, value); | 527 | __omap_dm_timer_int_enable(timer, value); |
523 | } | 528 | } |
524 | EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable); | 529 | EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable); |
525 | 530 | ||
@@ -527,7 +532,7 @@ unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) | |||
527 | { | 532 | { |
528 | unsigned int l; | 533 | unsigned int l; |
529 | 534 | ||
530 | l = omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG); | 535 | l = __raw_readl(timer->irq_stat); |
531 | 536 | ||
532 | return l; | 537 | return l; |
533 | } | 538 | } |
@@ -535,13 +540,13 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_read_status); | |||
535 | 540 | ||
536 | void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) | 541 | void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) |
537 | { | 542 | { |
538 | __omap_dm_timer_write_status(timer->io_base, value); | 543 | __omap_dm_timer_write_status(timer, value); |
539 | } | 544 | } |
540 | EXPORT_SYMBOL_GPL(omap_dm_timer_write_status); | 545 | EXPORT_SYMBOL_GPL(omap_dm_timer_write_status); |
541 | 546 | ||
542 | unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) | 547 | unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) |
543 | { | 548 | { |
544 | return __omap_dm_timer_read_counter(timer->io_base, timer->posted); | 549 | return __omap_dm_timer_read_counter(timer, timer->posted); |
545 | } | 550 | } |
546 | EXPORT_SYMBOL_GPL(omap_dm_timer_read_counter); | 551 | EXPORT_SYMBOL_GPL(omap_dm_timer_read_counter); |
547 | 552 | ||
@@ -601,6 +606,9 @@ static int __init omap_dm_timer_init(void) | |||
601 | dm_timer_count = omap4_dm_timer_count; | 606 | dm_timer_count = omap4_dm_timer_count; |
602 | dm_source_names = omap4_dm_source_names; | 607 | dm_source_names = omap4_dm_source_names; |
603 | dm_source_clocks = omap4_dm_source_clocks; | 608 | dm_source_clocks = omap4_dm_source_clocks; |
609 | |||
610 | pr_err("dmtimers disabled for omap4 until hwmod conversion\n"); | ||
611 | return -ENODEV; | ||
604 | } | 612 | } |
605 | 613 | ||
606 | if (cpu_class_is_omap2()) | 614 | if (cpu_class_is_omap2()) |
@@ -630,8 +638,12 @@ static int __init omap_dm_timer_init(void) | |||
630 | if (sys_timer_reserved & (1 << i)) { | 638 | if (sys_timer_reserved & (1 << i)) { |
631 | timer->reserved = 1; | 639 | timer->reserved = 1; |
632 | timer->posted = 1; | 640 | timer->posted = 1; |
641 | continue; | ||
633 | } | 642 | } |
634 | #endif | 643 | #endif |
644 | omap_dm_timer_enable(timer); | ||
645 | __omap_dm_timer_init_regs(timer); | ||
646 | omap_dm_timer_disable(timer); | ||
635 | } | 647 | } |
636 | 648 | ||
637 | return 0; | 649 | return 0; |
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h index eb5d16c60cd9..ad554d36866d 100644 --- a/arch/arm/plat-omap/include/plat/dmtimer.h +++ b/arch/arm/plat-omap/include/plat/dmtimer.h | |||
@@ -98,12 +98,30 @@ int omap_dm_timers_active(void); | |||
98 | * used by dmtimer.c and sys_timer related code. | 98 | * used by dmtimer.c and sys_timer related code. |
99 | */ | 99 | */ |
100 | 100 | ||
101 | /* register offsets */ | 101 | /* |
102 | #define _OMAP_TIMER_ID_OFFSET 0x00 | 102 | * The interrupt registers are different between v1 and v2 ip. |
103 | #define _OMAP_TIMER_OCP_CFG_OFFSET 0x10 | 103 | * These registers are offsets from timer->iobase. |
104 | #define _OMAP_TIMER_SYS_STAT_OFFSET 0x14 | 104 | */ |
105 | #define _OMAP_TIMER_STAT_OFFSET 0x18 | 105 | #define OMAP_TIMER_ID_OFFSET 0x00 |
106 | #define _OMAP_TIMER_INT_EN_OFFSET 0x1c | 106 | #define OMAP_TIMER_OCP_CFG_OFFSET 0x10 |
107 | |||
108 | #define OMAP_TIMER_V1_SYS_STAT_OFFSET 0x14 | ||
109 | #define OMAP_TIMER_V1_STAT_OFFSET 0x18 | ||
110 | #define OMAP_TIMER_V1_INT_EN_OFFSET 0x1c | ||
111 | |||
112 | #define OMAP_TIMER_V2_IRQSTATUS_RAW 0x24 | ||
113 | #define OMAP_TIMER_V2_IRQSTATUS 0x28 | ||
114 | #define OMAP_TIMER_V2_IRQENABLE_SET 0x2c | ||
115 | #define OMAP_TIMER_V2_IRQENABLE_CLR 0x30 | ||
116 | |||
117 | /* | ||
118 | * The functional registers have a different base on v1 and v2 ip. | ||
119 | * These registers are offsets from timer->func_base. The func_base | ||
120 | * is samae as io_base for v1 and io_base + 0x14 for v2 ip. | ||
121 | * | ||
122 | */ | ||
123 | #define OMAP_TIMER_V2_FUNC_OFFSET 0x14 | ||
124 | |||
107 | #define _OMAP_TIMER_WAKEUP_EN_OFFSET 0x20 | 125 | #define _OMAP_TIMER_WAKEUP_EN_OFFSET 0x20 |
108 | #define _OMAP_TIMER_CTRL_OFFSET 0x24 | 126 | #define _OMAP_TIMER_CTRL_OFFSET 0x24 |
109 | #define OMAP_TIMER_CTRL_GPOCFG (1 << 14) | 127 | #define OMAP_TIMER_CTRL_GPOCFG (1 << 14) |
@@ -147,21 +165,6 @@ int omap_dm_timers_active(void); | |||
147 | /* register offsets with the write pending bit encoded */ | 165 | /* register offsets with the write pending bit encoded */ |
148 | #define WPSHIFT 16 | 166 | #define WPSHIFT 16 |
149 | 167 | ||
150 | #define OMAP_TIMER_ID_REG (_OMAP_TIMER_ID_OFFSET \ | ||
151 | | (WP_NONE << WPSHIFT)) | ||
152 | |||
153 | #define OMAP_TIMER_OCP_CFG_REG (_OMAP_TIMER_OCP_CFG_OFFSET \ | ||
154 | | (WP_NONE << WPSHIFT)) | ||
155 | |||
156 | #define OMAP_TIMER_SYS_STAT_REG (_OMAP_TIMER_SYS_STAT_OFFSET \ | ||
157 | | (WP_NONE << WPSHIFT)) | ||
158 | |||
159 | #define OMAP_TIMER_STAT_REG (_OMAP_TIMER_STAT_OFFSET \ | ||
160 | | (WP_NONE << WPSHIFT)) | ||
161 | |||
162 | #define OMAP_TIMER_INT_EN_REG (_OMAP_TIMER_INT_EN_OFFSET \ | ||
163 | | (WP_NONE << WPSHIFT)) | ||
164 | |||
165 | #define OMAP_TIMER_WAKEUP_EN_REG (_OMAP_TIMER_WAKEUP_EN_OFFSET \ | 168 | #define OMAP_TIMER_WAKEUP_EN_REG (_OMAP_TIMER_WAKEUP_EN_OFFSET \ |
166 | | (WP_NONE << WPSHIFT)) | 169 | | (WP_NONE << WPSHIFT)) |
167 | 170 | ||
@@ -213,7 +216,14 @@ struct omap_dm_timer { | |||
213 | #ifdef CONFIG_ARCH_OMAP2PLUS | 216 | #ifdef CONFIG_ARCH_OMAP2PLUS |
214 | struct clk *iclk, *fclk; | 217 | struct clk *iclk, *fclk; |
215 | #endif | 218 | #endif |
216 | void __iomem *io_base; | 219 | void __iomem *io_base; |
220 | void __iomem *sys_stat; /* TISTAT timer status */ | ||
221 | void __iomem *irq_stat; /* TISR/IRQSTATUS interrupt status */ | ||
222 | void __iomem *irq_ena; /* irq enable */ | ||
223 | void __iomem *irq_dis; /* irq disable, only on v2 ip */ | ||
224 | void __iomem *pend; /* write pending */ | ||
225 | void __iomem *func_base; /* function register base */ | ||
226 | |||
217 | unsigned long rate; | 227 | unsigned long rate; |
218 | unsigned reserved:1; | 228 | unsigned reserved:1; |
219 | unsigned enabled:1; | 229 | unsigned enabled:1; |
@@ -223,35 +233,59 @@ struct omap_dm_timer { | |||
223 | extern u32 sys_timer_reserved; | 233 | extern u32 sys_timer_reserved; |
224 | void omap_dm_timer_prepare(struct omap_dm_timer *timer); | 234 | void omap_dm_timer_prepare(struct omap_dm_timer *timer); |
225 | 235 | ||
226 | static inline u32 __omap_dm_timer_read(void __iomem *base, u32 reg, | 236 | static inline u32 __omap_dm_timer_read(struct omap_dm_timer *timer, u32 reg, |
227 | int posted) | 237 | int posted) |
228 | { | 238 | { |
229 | if (posted) | 239 | if (posted) |
230 | while (__raw_readl(base + (OMAP_TIMER_WRITE_PEND_REG & 0xff)) | 240 | while (__raw_readl(timer->pend) & (reg >> WPSHIFT)) |
231 | & (reg >> WPSHIFT)) | ||
232 | cpu_relax(); | 241 | cpu_relax(); |
233 | 242 | ||
234 | return __raw_readl(base + (reg & 0xff)); | 243 | return __raw_readl(timer->func_base + (reg & 0xff)); |
235 | } | 244 | } |
236 | 245 | ||
237 | static inline void __omap_dm_timer_write(void __iomem *base, u32 reg, u32 val, | 246 | static inline void __omap_dm_timer_write(struct omap_dm_timer *timer, |
238 | int posted) | 247 | u32 reg, u32 val, int posted) |
239 | { | 248 | { |
240 | if (posted) | 249 | if (posted) |
241 | while (__raw_readl(base + (OMAP_TIMER_WRITE_PEND_REG & 0xff)) | 250 | while (__raw_readl(timer->pend) & (reg >> WPSHIFT)) |
242 | & (reg >> WPSHIFT)) | ||
243 | cpu_relax(); | 251 | cpu_relax(); |
244 | 252 | ||
245 | __raw_writel(val, base + (reg & 0xff)); | 253 | __raw_writel(val, timer->func_base + (reg & 0xff)); |
254 | } | ||
255 | |||
256 | static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer) | ||
257 | { | ||
258 | u32 tidr; | ||
259 | |||
260 | /* Assume v1 ip if bits [31:16] are zero */ | ||
261 | tidr = __raw_readl(timer->io_base); | ||
262 | if (!(tidr >> 16)) { | ||
263 | timer->sys_stat = timer->io_base + | ||
264 | OMAP_TIMER_V1_SYS_STAT_OFFSET; | ||
265 | timer->irq_stat = timer->io_base + OMAP_TIMER_V1_STAT_OFFSET; | ||
266 | timer->irq_ena = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET; | ||
267 | timer->irq_dis = 0; | ||
268 | timer->pend = timer->io_base + _OMAP_TIMER_WRITE_PEND_OFFSET; | ||
269 | timer->func_base = timer->io_base; | ||
270 | } else { | ||
271 | timer->sys_stat = 0; | ||
272 | timer->irq_stat = timer->io_base + OMAP_TIMER_V2_IRQSTATUS; | ||
273 | timer->irq_ena = timer->io_base + OMAP_TIMER_V2_IRQENABLE_SET; | ||
274 | timer->irq_dis = timer->io_base + OMAP_TIMER_V2_IRQENABLE_CLR; | ||
275 | timer->pend = timer->io_base + | ||
276 | _OMAP_TIMER_WRITE_PEND_OFFSET + | ||
277 | OMAP_TIMER_V2_FUNC_OFFSET; | ||
278 | timer->func_base = timer->io_base + OMAP_TIMER_V2_FUNC_OFFSET; | ||
279 | } | ||
246 | } | 280 | } |
247 | 281 | ||
248 | /* Assumes the source clock has been set by caller */ | 282 | /* Assumes the source clock has been set by caller */ |
249 | static inline void __omap_dm_timer_reset(void __iomem *base, int autoidle, | 283 | static inline void __omap_dm_timer_reset(struct omap_dm_timer *timer, |
250 | int wakeup) | 284 | int autoidle, int wakeup) |
251 | { | 285 | { |
252 | u32 l; | 286 | u32 l; |
253 | 287 | ||
254 | l = __omap_dm_timer_read(base, OMAP_TIMER_OCP_CFG_REG, 0); | 288 | l = __raw_readl(timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET); |
255 | l |= 0x02 << 3; /* Set to smart-idle mode */ | 289 | l |= 0x02 << 3; /* Set to smart-idle mode */ |
256 | l |= 0x2 << 8; /* Set clock activity to perserve f-clock on idle */ | 290 | l |= 0x2 << 8; /* Set clock activity to perserve f-clock on idle */ |
257 | 291 | ||
@@ -261,10 +295,10 @@ static inline void __omap_dm_timer_reset(void __iomem *base, int autoidle, | |||
261 | if (wakeup) | 295 | if (wakeup) |
262 | l |= 1 << 2; | 296 | l |= 1 << 2; |
263 | 297 | ||
264 | __omap_dm_timer_write(base, OMAP_TIMER_OCP_CFG_REG, l, 0); | 298 | __raw_writel(l, timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET); |
265 | 299 | ||
266 | /* Match hardware reset default of posted mode */ | 300 | /* Match hardware reset default of posted mode */ |
267 | __omap_dm_timer_write(base, OMAP_TIMER_IF_CTRL_REG, | 301 | __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG, |
268 | OMAP_TIMER_CTRL_POSTED, 0); | 302 | OMAP_TIMER_CTRL_POSTED, 0); |
269 | } | 303 | } |
270 | 304 | ||
@@ -286,18 +320,18 @@ static inline int __omap_dm_timer_set_source(struct clk *timer_fck, | |||
286 | return ret; | 320 | return ret; |
287 | } | 321 | } |
288 | 322 | ||
289 | static inline void __omap_dm_timer_stop(void __iomem *base, int posted, | 323 | static inline void __omap_dm_timer_stop(struct omap_dm_timer *timer, |
290 | unsigned long rate) | 324 | int posted, unsigned long rate) |
291 | { | 325 | { |
292 | u32 l; | 326 | u32 l; |
293 | 327 | ||
294 | l = __omap_dm_timer_read(base, OMAP_TIMER_CTRL_REG, posted); | 328 | l = __omap_dm_timer_read(timer, OMAP_TIMER_CTRL_REG, posted); |
295 | if (l & OMAP_TIMER_CTRL_ST) { | 329 | if (l & OMAP_TIMER_CTRL_ST) { |
296 | l &= ~0x1; | 330 | l &= ~0x1; |
297 | __omap_dm_timer_write(base, OMAP_TIMER_CTRL_REG, l, posted); | 331 | __omap_dm_timer_write(timer, OMAP_TIMER_CTRL_REG, l, posted); |
298 | #ifdef CONFIG_ARCH_OMAP2PLUS | 332 | #ifdef CONFIG_ARCH_OMAP2PLUS |
299 | /* Readback to make sure write has completed */ | 333 | /* Readback to make sure write has completed */ |
300 | __omap_dm_timer_read(base, OMAP_TIMER_CTRL_REG, posted); | 334 | __omap_dm_timer_read(timer, OMAP_TIMER_CTRL_REG, posted); |
301 | /* | 335 | /* |
302 | * Wait for functional clock period x 3.5 to make sure that | 336 | * Wait for functional clock period x 3.5 to make sure that |
303 | * timer is stopped | 337 | * timer is stopped |
@@ -307,34 +341,34 @@ static inline void __omap_dm_timer_stop(void __iomem *base, int posted, | |||
307 | } | 341 | } |
308 | 342 | ||
309 | /* Ack possibly pending interrupt */ | 343 | /* Ack possibly pending interrupt */ |
310 | __omap_dm_timer_write(base, OMAP_TIMER_STAT_REG, | 344 | __raw_writel(OMAP_TIMER_INT_OVERFLOW, timer->irq_stat); |
311 | OMAP_TIMER_INT_OVERFLOW, 0); | ||
312 | } | 345 | } |
313 | 346 | ||
314 | static inline void __omap_dm_timer_load_start(void __iomem *base, u32 ctrl, | 347 | static inline void __omap_dm_timer_load_start(struct omap_dm_timer *timer, |
315 | unsigned int load, int posted) | 348 | u32 ctrl, unsigned int load, |
349 | int posted) | ||
316 | { | 350 | { |
317 | __omap_dm_timer_write(base, OMAP_TIMER_COUNTER_REG, load, posted); | 351 | __omap_dm_timer_write(timer, OMAP_TIMER_COUNTER_REG, load, posted); |
318 | __omap_dm_timer_write(base, OMAP_TIMER_CTRL_REG, ctrl, posted); | 352 | __omap_dm_timer_write(timer, OMAP_TIMER_CTRL_REG, ctrl, posted); |
319 | } | 353 | } |
320 | 354 | ||
321 | static inline void __omap_dm_timer_int_enable(void __iomem *base, | 355 | static inline void __omap_dm_timer_int_enable(struct omap_dm_timer *timer, |
322 | unsigned int value) | 356 | unsigned int value) |
323 | { | 357 | { |
324 | __omap_dm_timer_write(base, OMAP_TIMER_INT_EN_REG, value, 0); | 358 | __raw_writel(value, timer->irq_ena); |
325 | __omap_dm_timer_write(base, OMAP_TIMER_WAKEUP_EN_REG, value, 0); | 359 | __omap_dm_timer_write(timer, OMAP_TIMER_WAKEUP_EN_REG, value, 0); |
326 | } | 360 | } |
327 | 361 | ||
328 | static inline unsigned int __omap_dm_timer_read_counter(void __iomem *base, | 362 | static inline unsigned int |
329 | int posted) | 363 | __omap_dm_timer_read_counter(struct omap_dm_timer *timer, int posted) |
330 | { | 364 | { |
331 | return __omap_dm_timer_read(base, OMAP_TIMER_COUNTER_REG, posted); | 365 | return __omap_dm_timer_read(timer, OMAP_TIMER_COUNTER_REG, posted); |
332 | } | 366 | } |
333 | 367 | ||
334 | static inline void __omap_dm_timer_write_status(void __iomem *base, | 368 | static inline void __omap_dm_timer_write_status(struct omap_dm_timer *timer, |
335 | unsigned int value) | 369 | unsigned int value) |
336 | { | 370 | { |
337 | __omap_dm_timer_write(base, OMAP_TIMER_STAT_REG, value, 0); | 371 | __raw_writel(value, timer->irq_stat); |
338 | } | 372 | } |
339 | 373 | ||
340 | #endif /* __ASM_ARCH_DMTIMER_H */ | 374 | #endif /* __ASM_ARCH_DMTIMER_H */ |