aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorTarun Kanti DebBarma <tarun.kanti@ti.com>2011-09-20 07:30:24 -0400
committerTony Lindgren <tony@atomide.com>2011-09-21 20:07:34 -0400
commitb481113a8af65f49afed46d4c9132b7af9426684 (patch)
treef468369003b3d0e70342aee8d0cce6b1c637e1a7 /arch
parent0dad9faeaeb0fa3524068a94e1745b91e5597c17 (diff)
ARM: OMAP: dmtimer: low-power mode support
Clock is enabled only when timer is started and disabled when the the timer is stopped. Therefore before accessing registers in functions clock is enabled and then disabled back at the end of access. Context save is done dynamically whenever the registers are modified. Context restore is called when context is lost. Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com> [tony@atomide.com: updated to use revision instead of tidr] Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/timer.c9
-rw-r--r--arch/arm/plat-omap/dmtimer.c110
-rw-r--r--arch/arm/plat-omap/include/plat/dmtimer.h35
3 files changed, 149 insertions, 5 deletions
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index f1e3ec1c16e1..1140e98c9773 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -44,6 +44,9 @@
44#include <plat/common.h> 44#include <plat/common.h>
45#include <plat/omap_hwmod.h> 45#include <plat/omap_hwmod.h>
46#include <plat/omap_device.h> 46#include <plat/omap_device.h>
47#include <plat/omap-pm.h>
48
49#include "powerdomain.h"
47 50
48/* Parent clocks, eventually these will come from the clock framework */ 51/* Parent clocks, eventually these will come from the clock framework */
49 52
@@ -433,6 +436,7 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
433 struct dmtimer_platform_data *pdata; 436 struct dmtimer_platform_data *pdata;
434 struct omap_device *od; 437 struct omap_device *od;
435 struct omap_timer_capability_dev_attr *timer_dev_attr; 438 struct omap_timer_capability_dev_attr *timer_dev_attr;
439 struct powerdomain *pwrdm;
436 440
437 pr_debug("%s: %s\n", __func__, oh->name); 441 pr_debug("%s: %s\n", __func__, oh->name);
438 442
@@ -467,6 +471,11 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
467 if ((sys_timer_reserved >> (id - 1)) & 0x1) 471 if ((sys_timer_reserved >> (id - 1)) & 0x1)
468 pdata->reserved = 1; 472 pdata->reserved = 1;
469 473
474 pwrdm = omap_hwmod_get_pwrdm(oh);
475 pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm);
476#ifdef CONFIG_PM
477 pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
478#endif
470 od = omap_device_build(name, id, oh, pdata, sizeof(*pdata), 479 od = omap_device_build(name, id, oh, pdata, sizeof(*pdata),
471 omap2_dmtimer_latency, 480 omap2_dmtimer_latency,
472 ARRAY_SIZE(omap2_dmtimer_latency), 481 ARRAY_SIZE(omap2_dmtimer_latency),
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index c8df3c36b3ad..43eb75038ba2 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -77,6 +77,29 @@ static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
77 __omap_dm_timer_write(timer, reg, value, timer->posted); 77 __omap_dm_timer_write(timer, reg, value, timer->posted);
78} 78}
79 79
80static void omap_timer_restore_context(struct omap_dm_timer *timer)
81{
82 omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_OFFSET,
83 timer->context.tiocp_cfg);
84 if (timer->revision > 1)
85 __raw_writel(timer->context.tistat, timer->sys_stat);
86
87 __raw_writel(timer->context.tisr, timer->irq_stat);
88 omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG,
89 timer->context.twer);
90 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG,
91 timer->context.tcrr);
92 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG,
93 timer->context.tldr);
94 omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG,
95 timer->context.tmar);
96 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
97 timer->context.tsicr);
98 __raw_writel(timer->context.tier, timer->irq_ena);
99 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG,
100 timer->context.tclr);
101}
102
80static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer) 103static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
81{ 104{
82 int c; 105 int c;
@@ -96,12 +119,14 @@ static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
96 119
97static void omap_dm_timer_reset(struct omap_dm_timer *timer) 120static void omap_dm_timer_reset(struct omap_dm_timer *timer)
98{ 121{
122 omap_dm_timer_enable(timer);
99 if (timer->pdev->id != 1) { 123 if (timer->pdev->id != 1) {
100 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); 124 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
101 omap_dm_timer_wait_for_reset(timer); 125 omap_dm_timer_wait_for_reset(timer);
102 } 126 }
103 127
104 __omap_dm_timer_reset(timer, 0, 0); 128 __omap_dm_timer_reset(timer, 0, 0);
129 omap_dm_timer_disable(timer);
105 timer->posted = 1; 130 timer->posted = 1;
106} 131}
107 132
@@ -117,8 +142,6 @@ int omap_dm_timer_prepare(struct omap_dm_timer *timer)
117 return -EINVAL; 142 return -EINVAL;
118 } 143 }
119 144
120 omap_dm_timer_enable(timer);
121
122 if (pdata->needs_manual_reset) 145 if (pdata->needs_manual_reset)
123 omap_dm_timer_reset(timer); 146 omap_dm_timer_reset(timer);
124 147
@@ -193,7 +216,6 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
193 216
194void omap_dm_timer_free(struct omap_dm_timer *timer) 217void omap_dm_timer_free(struct omap_dm_timer *timer)
195{ 218{
196 omap_dm_timer_disable(timer);
197 clk_put(timer->fclk); 219 clk_put(timer->fclk);
198 220
199 WARN_ON(!timer->reserved); 221 WARN_ON(!timer->reserved);
@@ -275,6 +297,11 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
275 297
276void omap_dm_timer_trigger(struct omap_dm_timer *timer) 298void omap_dm_timer_trigger(struct omap_dm_timer *timer)
277{ 299{
300 if (unlikely(pm_runtime_suspended(&timer->pdev->dev))) {
301 pr_err("%s: timer%d not enabled.\n", __func__, timer->id);
302 return;
303 }
304
278 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0); 305 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
279} 306}
280EXPORT_SYMBOL_GPL(omap_dm_timer_trigger); 307EXPORT_SYMBOL_GPL(omap_dm_timer_trigger);
@@ -283,11 +310,23 @@ void omap_dm_timer_start(struct omap_dm_timer *timer)
283{ 310{
284 u32 l; 311 u32 l;
285 312
313 omap_dm_timer_enable(timer);
314
315 if (timer->loses_context) {
316 u32 ctx_loss_cnt_after =
317 timer->get_context_loss_count(&timer->pdev->dev);
318 if (ctx_loss_cnt_after != timer->ctx_loss_count)
319 omap_timer_restore_context(timer);
320 }
321
286 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 322 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
287 if (!(l & OMAP_TIMER_CTRL_ST)) { 323 if (!(l & OMAP_TIMER_CTRL_ST)) {
288 l |= OMAP_TIMER_CTRL_ST; 324 l |= OMAP_TIMER_CTRL_ST;
289 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 325 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
290 } 326 }
327
328 /* Save the context */
329 timer->context.tclr = l;
291} 330}
292EXPORT_SYMBOL_GPL(omap_dm_timer_start); 331EXPORT_SYMBOL_GPL(omap_dm_timer_start);
293 332
@@ -311,9 +350,7 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
311 if (source < 0 || source >= 3) 350 if (source < 0 || source >= 3)
312 return -EINVAL; 351 return -EINVAL;
313 352
314 omap_dm_timer_disable(timer);
315 ret = pdata->set_timer_src(timer->pdev, source); 353 ret = pdata->set_timer_src(timer->pdev, source);
316 omap_dm_timer_enable(timer);
317 354
318 return ret; 355 return ret;
319} 356}
@@ -324,6 +361,7 @@ void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
324{ 361{
325 u32 l; 362 u32 l;
326 363
364 omap_dm_timer_enable(timer);
327 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 365 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
328 if (autoreload) 366 if (autoreload)
329 l |= OMAP_TIMER_CTRL_AR; 367 l |= OMAP_TIMER_CTRL_AR;
@@ -333,6 +371,10 @@ void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
333 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load); 371 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
334 372
335 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0); 373 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
374 /* Save the context */
375 timer->context.tclr = l;
376 timer->context.tldr = load;
377 omap_dm_timer_disable(timer);
336} 378}
337EXPORT_SYMBOL_GPL(omap_dm_timer_set_load); 379EXPORT_SYMBOL_GPL(omap_dm_timer_set_load);
338 380
@@ -342,6 +384,15 @@ void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
342{ 384{
343 u32 l; 385 u32 l;
344 386
387 omap_dm_timer_enable(timer);
388
389 if (timer->loses_context) {
390 u32 ctx_loss_cnt_after =
391 timer->get_context_loss_count(&timer->pdev->dev);
392 if (ctx_loss_cnt_after != timer->ctx_loss_count)
393 omap_timer_restore_context(timer);
394 }
395
345 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 396 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
346 if (autoreload) { 397 if (autoreload) {
347 l |= OMAP_TIMER_CTRL_AR; 398 l |= OMAP_TIMER_CTRL_AR;
@@ -352,6 +403,11 @@ void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
352 l |= OMAP_TIMER_CTRL_ST; 403 l |= OMAP_TIMER_CTRL_ST;
353 404
354 __omap_dm_timer_load_start(timer, l, load, timer->posted); 405 __omap_dm_timer_load_start(timer, l, load, timer->posted);
406
407 /* Save the context */
408 timer->context.tclr = l;
409 timer->context.tldr = load;
410 timer->context.tcrr = load;
355} 411}
356EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start); 412EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start);
357 413
@@ -360,6 +416,7 @@ void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
360{ 416{
361 u32 l; 417 u32 l;
362 418
419 omap_dm_timer_enable(timer);
363 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 420 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
364 if (enable) 421 if (enable)
365 l |= OMAP_TIMER_CTRL_CE; 422 l |= OMAP_TIMER_CTRL_CE;
@@ -367,6 +424,11 @@ void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
367 l &= ~OMAP_TIMER_CTRL_CE; 424 l &= ~OMAP_TIMER_CTRL_CE;
368 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 425 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
369 omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match); 426 omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
427
428 /* Save the context */
429 timer->context.tclr = l;
430 timer->context.tmar = match;
431 omap_dm_timer_disable(timer);
370} 432}
371EXPORT_SYMBOL_GPL(omap_dm_timer_set_match); 433EXPORT_SYMBOL_GPL(omap_dm_timer_set_match);
372 434
@@ -375,6 +437,7 @@ void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
375{ 437{
376 u32 l; 438 u32 l;
377 439
440 omap_dm_timer_enable(timer);
378 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 441 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
379 l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM | 442 l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM |
380 OMAP_TIMER_CTRL_PT | (0x03 << 10)); 443 OMAP_TIMER_CTRL_PT | (0x03 << 10));
@@ -384,6 +447,10 @@ void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
384 l |= OMAP_TIMER_CTRL_PT; 447 l |= OMAP_TIMER_CTRL_PT;
385 l |= trigger << 10; 448 l |= trigger << 10;
386 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 449 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
450
451 /* Save the context */
452 timer->context.tclr = l;
453 omap_dm_timer_disable(timer);
387} 454}
388EXPORT_SYMBOL_GPL(omap_dm_timer_set_pwm); 455EXPORT_SYMBOL_GPL(omap_dm_timer_set_pwm);
389 456
@@ -391,6 +458,7 @@ void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
391{ 458{
392 u32 l; 459 u32 l;
393 460
461 omap_dm_timer_enable(timer);
394 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 462 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
395 l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2)); 463 l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2));
396 if (prescaler >= 0x00 && prescaler <= 0x07) { 464 if (prescaler >= 0x00 && prescaler <= 0x07) {
@@ -398,13 +466,23 @@ void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
398 l |= prescaler << 2; 466 l |= prescaler << 2;
399 } 467 }
400 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); 468 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
469
470 /* Save the context */
471 timer->context.tclr = l;
472 omap_dm_timer_disable(timer);
401} 473}
402EXPORT_SYMBOL_GPL(omap_dm_timer_set_prescaler); 474EXPORT_SYMBOL_GPL(omap_dm_timer_set_prescaler);
403 475
404void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, 476void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
405 unsigned int value) 477 unsigned int value)
406{ 478{
479 omap_dm_timer_enable(timer);
407 __omap_dm_timer_int_enable(timer, value); 480 __omap_dm_timer_int_enable(timer, value);
481
482 /* Save the context */
483 timer->context.tier = value;
484 timer->context.twer = value;
485 omap_dm_timer_disable(timer);
408} 486}
409EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable); 487EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable);
410 488
@@ -412,6 +490,11 @@ unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
412{ 490{
413 unsigned int l; 491 unsigned int l;
414 492
493 if (unlikely(pm_runtime_suspended(&timer->pdev->dev))) {
494 pr_err("%s: timer%d not enabled.\n", __func__, timer->id);
495 return 0;
496 }
497
415 l = __raw_readl(timer->irq_stat); 498 l = __raw_readl(timer->irq_stat);
416 499
417 return l; 500 return l;
@@ -421,18 +504,33 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_read_status);
421void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) 504void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
422{ 505{
423 __omap_dm_timer_write_status(timer, value); 506 __omap_dm_timer_write_status(timer, value);
507 /* Save the context */
508 timer->context.tisr = value;
424} 509}
425EXPORT_SYMBOL_GPL(omap_dm_timer_write_status); 510EXPORT_SYMBOL_GPL(omap_dm_timer_write_status);
426 511
427unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) 512unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
428{ 513{
514 if (unlikely(pm_runtime_suspended(&timer->pdev->dev))) {
515 pr_err("%s: timer%d not enabled.\n", __func__, timer->id);
516 return 0;
517 }
518
429 return __omap_dm_timer_read_counter(timer, timer->posted); 519 return __omap_dm_timer_read_counter(timer, timer->posted);
430} 520}
431EXPORT_SYMBOL_GPL(omap_dm_timer_read_counter); 521EXPORT_SYMBOL_GPL(omap_dm_timer_read_counter);
432 522
433void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value) 523void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
434{ 524{
525 if (unlikely(pm_runtime_suspended(&timer->pdev->dev))) {
526 pr_err("%s: timer%d not enabled.\n", __func__, timer->id);
527 return;
528 }
529
435 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value); 530 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
531
532 /* Save the context */
533 timer->context.tcrr = value;
436} 534}
437EXPORT_SYMBOL_GPL(omap_dm_timer_write_counter); 535EXPORT_SYMBOL_GPL(omap_dm_timer_write_counter);
438 536
@@ -511,6 +609,8 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
511 timer->irq = irq->start; 609 timer->irq = irq->start;
512 timer->reserved = pdata->reserved; 610 timer->reserved = pdata->reserved;
513 timer->pdev = pdev; 611 timer->pdev = pdev;
612 timer->loses_context = pdata->loses_context;
613 timer->get_context_loss_count = pdata->get_context_loss_count;
514 614
515 /* Skip pm_runtime_enable for OMAP1 */ 615 /* Skip pm_runtime_enable for OMAP1 */
516 if (!pdata->needs_manual_reset) { 616 if (!pdata->needs_manual_reset) {
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index 29764c34f571..9519d87179e1 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -73,11 +73,38 @@ struct omap_timer_capability_dev_attr {
73struct omap_dm_timer; 73struct omap_dm_timer;
74struct clk; 74struct clk;
75 75
76struct timer_regs {
77 u32 tidr;
78 u32 tiocp_cfg;
79 u32 tistat;
80 u32 tisr;
81 u32 tier;
82 u32 twer;
83 u32 tclr;
84 u32 tcrr;
85 u32 tldr;
86 u32 ttrg;
87 u32 twps;
88 u32 tmar;
89 u32 tcar1;
90 u32 tsicr;
91 u32 tcar2;
92 u32 tpir;
93 u32 tnir;
94 u32 tcvr;
95 u32 tocr;
96 u32 towr;
97};
98
76struct dmtimer_platform_data { 99struct dmtimer_platform_data {
77 int (*set_timer_src)(struct platform_device *pdev, int source); 100 int (*set_timer_src)(struct platform_device *pdev, int source);
78 int timer_ip_version; 101 int timer_ip_version;
79 u32 needs_manual_reset:1; 102 u32 needs_manual_reset:1;
80 bool reserved; 103 bool reserved;
104
105 bool loses_context;
106
107 u32 (*get_context_loss_count)(struct device *dev);
81}; 108};
82 109
83struct omap_dm_timer *omap_dm_timer_request(void); 110struct omap_dm_timer *omap_dm_timer_request(void);
@@ -245,8 +272,14 @@ struct omap_dm_timer {
245 unsigned long rate; 272 unsigned long rate;
246 unsigned reserved:1; 273 unsigned reserved:1;
247 unsigned posted:1; 274 unsigned posted:1;
275 struct timer_regs context;
276 bool loses_context;
277 int ctx_loss_count;
278 int revision;
248 struct platform_device *pdev; 279 struct platform_device *pdev;
249 struct list_head node; 280 struct list_head node;
281
282 u32 (*get_context_loss_count)(struct device *dev);
250}; 283};
251 284
252int omap_dm_timer_prepare(struct omap_dm_timer *timer); 285int omap_dm_timer_prepare(struct omap_dm_timer *timer);
@@ -278,6 +311,7 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer)
278 /* Assume v1 ip if bits [31:16] are zero */ 311 /* Assume v1 ip if bits [31:16] are zero */
279 tidr = __raw_readl(timer->io_base); 312 tidr = __raw_readl(timer->io_base);
280 if (!(tidr >> 16)) { 313 if (!(tidr >> 16)) {
314 timer->revision = 1;
281 timer->sys_stat = timer->io_base + 315 timer->sys_stat = timer->io_base +
282 OMAP_TIMER_V1_SYS_STAT_OFFSET; 316 OMAP_TIMER_V1_SYS_STAT_OFFSET;
283 timer->irq_stat = timer->io_base + OMAP_TIMER_V1_STAT_OFFSET; 317 timer->irq_stat = timer->io_base + OMAP_TIMER_V1_STAT_OFFSET;
@@ -286,6 +320,7 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer)
286 timer->pend = timer->io_base + _OMAP_TIMER_WRITE_PEND_OFFSET; 320 timer->pend = timer->io_base + _OMAP_TIMER_WRITE_PEND_OFFSET;
287 timer->func_base = timer->io_base; 321 timer->func_base = timer->io_base;
288 } else { 322 } else {
323 timer->revision = 2;
289 timer->sys_stat = 0; 324 timer->sys_stat = 0;
290 timer->irq_stat = timer->io_base + OMAP_TIMER_V2_IRQSTATUS; 325 timer->irq_stat = timer->io_base + OMAP_TIMER_V2_IRQSTATUS;
291 timer->irq_ena = timer->io_base + OMAP_TIMER_V2_IRQENABLE_SET; 326 timer->irq_ena = timer->io_base + OMAP_TIMER_V2_IRQENABLE_SET;