diff options
Diffstat (limited to 'arch/arm/plat-omap/dmtimer.c')
-rw-r--r-- | arch/arm/plat-omap/dmtimer.c | 118 |
1 files changed, 89 insertions, 29 deletions
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 3856f5aedfc1..e719d0eeb5c8 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c | |||
@@ -48,7 +48,7 @@ | |||
48 | #define OMAP_TIMER_COUNTER_REG 0x28 | 48 | #define OMAP_TIMER_COUNTER_REG 0x28 |
49 | #define OMAP_TIMER_LOAD_REG 0x2c | 49 | #define OMAP_TIMER_LOAD_REG 0x2c |
50 | #define OMAP_TIMER_TRIGGER_REG 0x30 | 50 | #define OMAP_TIMER_TRIGGER_REG 0x30 |
51 | #define OMAP_TIMER_WRITE_PEND_REG 0x34 | 51 | #define OMAP_TIMER_WRITE_PEND_REG 0x34 |
52 | #define OMAP_TIMER_MATCH_REG 0x38 | 52 | #define OMAP_TIMER_MATCH_REG 0x38 |
53 | #define OMAP_TIMER_CAPTURE_REG 0x3c | 53 | #define OMAP_TIMER_CAPTURE_REG 0x3c |
54 | #define OMAP_TIMER_IF_CTRL_REG 0x40 | 54 | #define OMAP_TIMER_IF_CTRL_REG 0x40 |
@@ -70,7 +70,7 @@ | |||
70 | struct omap_dm_timer { | 70 | struct omap_dm_timer { |
71 | unsigned long phys_base; | 71 | unsigned long phys_base; |
72 | int irq; | 72 | int irq; |
73 | #ifdef CONFIG_ARCH_OMAP2 | 73 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) |
74 | struct clk *iclk, *fclk; | 74 | struct clk *iclk, *fclk; |
75 | #endif | 75 | #endif |
76 | void __iomem *io_base; | 76 | void __iomem *io_base; |
@@ -82,8 +82,14 @@ struct omap_dm_timer { | |||
82 | 82 | ||
83 | #define omap_dm_clk_enable(x) | 83 | #define omap_dm_clk_enable(x) |
84 | #define omap_dm_clk_disable(x) | 84 | #define omap_dm_clk_disable(x) |
85 | 85 | #define omap2_dm_timers NULL | |
86 | static struct omap_dm_timer dm_timers[] = { | 86 | #define omap2_dm_source_names NULL |
87 | #define omap2_dm_source_clocks NULL | ||
88 | #define omap3_dm_timers NULL | ||
89 | #define omap3_dm_source_names NULL | ||
90 | #define omap3_dm_source_clocks NULL | ||
91 | |||
92 | static struct omap_dm_timer omap1_dm_timers[] = { | ||
87 | { .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 }, | 93 | { .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 }, |
88 | { .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 }, | 94 | { .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 }, |
89 | { .phys_base = 0xfffb2400, .irq = INT_1610_GPTIMER3 }, | 95 | { .phys_base = 0xfffb2400, .irq = INT_1610_GPTIMER3 }, |
@@ -94,12 +100,18 @@ static struct omap_dm_timer dm_timers[] = { | |||
94 | { .phys_base = 0xfffbd400, .irq = INT_1610_GPTIMER8 }, | 100 | { .phys_base = 0xfffbd400, .irq = INT_1610_GPTIMER8 }, |
95 | }; | 101 | }; |
96 | 102 | ||
103 | static const int dm_timer_count = ARRAY_SIZE(omap1_dm_timers); | ||
104 | |||
97 | #elif defined(CONFIG_ARCH_OMAP2) | 105 | #elif defined(CONFIG_ARCH_OMAP2) |
98 | 106 | ||
99 | #define omap_dm_clk_enable(x) clk_enable(x) | 107 | #define omap_dm_clk_enable(x) clk_enable(x) |
100 | #define omap_dm_clk_disable(x) clk_disable(x) | 108 | #define omap_dm_clk_disable(x) clk_disable(x) |
109 | #define omap1_dm_timers NULL | ||
110 | #define omap3_dm_timers NULL | ||
111 | #define omap3_dm_source_names NULL | ||
112 | #define omap3_dm_source_clocks NULL | ||
101 | 113 | ||
102 | static struct omap_dm_timer dm_timers[] = { | 114 | static struct omap_dm_timer omap2_dm_timers[] = { |
103 | { .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 }, | 115 | { .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 }, |
104 | { .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 }, | 116 | { .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 }, |
105 | { .phys_base = 0x48078000, .irq = INT_24XX_GPTIMER3 }, | 117 | { .phys_base = 0x48078000, .irq = INT_24XX_GPTIMER3 }, |
@@ -114,13 +126,48 @@ static struct omap_dm_timer dm_timers[] = { | |||
114 | { .phys_base = 0x4808a000, .irq = INT_24XX_GPTIMER12 }, | 126 | { .phys_base = 0x4808a000, .irq = INT_24XX_GPTIMER12 }, |
115 | }; | 127 | }; |
116 | 128 | ||
117 | static const char *dm_source_names[] = { | 129 | static const char *omap2_dm_source_names[] __initdata = { |
118 | "sys_ck", | 130 | "sys_ck", |
119 | "func_32k_ck", | 131 | "func_32k_ck", |
120 | "alt_ck" | 132 | "alt_ck", |
133 | NULL | ||
134 | }; | ||
135 | |||
136 | static struct clk **omap2_dm_source_clocks[3]; | ||
137 | static const int dm_timer_count = ARRAY_SIZE(omap2_dm_timers); | ||
138 | |||
139 | #elif defined(CONFIG_ARCH_OMAP3) | ||
140 | |||
141 | #define omap_dm_clk_enable(x) clk_enable(x) | ||
142 | #define omap_dm_clk_disable(x) clk_disable(x) | ||
143 | #define omap1_dm_timers NULL | ||
144 | #define omap2_dm_timers NULL | ||
145 | #define omap2_dm_source_names NULL | ||
146 | #define omap2_dm_source_clocks NULL | ||
147 | |||
148 | static struct omap_dm_timer omap3_dm_timers[] = { | ||
149 | { .phys_base = 0x48318000, .irq = INT_24XX_GPTIMER1 }, | ||
150 | { .phys_base = 0x49032000, .irq = INT_24XX_GPTIMER2 }, | ||
151 | { .phys_base = 0x49034000, .irq = INT_24XX_GPTIMER3 }, | ||
152 | { .phys_base = 0x49036000, .irq = INT_24XX_GPTIMER4 }, | ||
153 | { .phys_base = 0x49038000, .irq = INT_24XX_GPTIMER5 }, | ||
154 | { .phys_base = 0x4903A000, .irq = INT_24XX_GPTIMER6 }, | ||
155 | { .phys_base = 0x4903C000, .irq = INT_24XX_GPTIMER7 }, | ||
156 | { .phys_base = 0x4903E000, .irq = INT_24XX_GPTIMER8 }, | ||
157 | { .phys_base = 0x49040000, .irq = INT_24XX_GPTIMER9 }, | ||
158 | { .phys_base = 0x48086000, .irq = INT_24XX_GPTIMER10 }, | ||
159 | { .phys_base = 0x48088000, .irq = INT_24XX_GPTIMER11 }, | ||
160 | { .phys_base = 0x48304000, .irq = INT_24XX_GPTIMER12 }, | ||
161 | }; | ||
162 | |||
163 | static const char *omap3_dm_source_names[] __initdata = { | ||
164 | "sys_ck", | ||
165 | "omap_32k_fck", | ||
166 | NULL | ||
121 | }; | 167 | }; |
122 | 168 | ||
123 | static struct clk *dm_source_clocks[3]; | 169 | static struct clk **omap3_dm_source_clocks[2]; |
170 | static const int dm_timer_count = ARRAY_SIZE(omap3_dm_timers); | ||
124 | 171 | ||
125 | #else | 172 | #else |
126 | 173 | ||
@@ -128,7 +175,10 @@ static struct clk *dm_source_clocks[3]; | |||
128 | 175 | ||
129 | #endif | 176 | #endif |
130 | 177 | ||
131 | static const int dm_timer_count = ARRAY_SIZE(dm_timers); | 178 | static struct omap_dm_timer *dm_timers; |
179 | static char **dm_source_names; | ||
180 | static struct clk **dm_source_clocks; | ||
181 | |||
132 | static spinlock_t dm_timer_lock; | 182 | static spinlock_t dm_timer_lock; |
133 | 183 | ||
134 | static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, int reg) | 184 | static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, int reg) |
@@ -299,7 +349,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) | |||
299 | return inputmask; | 349 | return inputmask; |
300 | } | 350 | } |
301 | 351 | ||
302 | #elif defined(CONFIG_ARCH_OMAP2) | 352 | #elif defined(CONFIG_ARCH_OMAP2) || defined (CONFIG_ARCH_OMAP3) |
303 | 353 | ||
304 | struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) | 354 | struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) |
305 | { | 355 | { |
@@ -486,36 +536,46 @@ int omap_dm_timers_active(void) | |||
486 | return 0; | 536 | return 0; |
487 | } | 537 | } |
488 | 538 | ||
489 | int omap_dm_timer_init(void) | 539 | int __init omap_dm_timer_init(void) |
490 | { | 540 | { |
491 | struct omap_dm_timer *timer; | 541 | struct omap_dm_timer *timer; |
492 | int i; | 542 | int i; |
493 | 543 | ||
494 | if (!(cpu_is_omap16xx() || cpu_is_omap24xx())) | 544 | if (!(cpu_is_omap16xx() || cpu_class_is_omap2())) |
495 | return -ENODEV; | 545 | return -ENODEV; |
496 | 546 | ||
497 | spin_lock_init(&dm_timer_lock); | 547 | spin_lock_init(&dm_timer_lock); |
498 | #ifdef CONFIG_ARCH_OMAP2 | 548 | |
499 | for (i = 0; i < ARRAY_SIZE(dm_source_names); i++) { | 549 | if (cpu_class_is_omap1()) |
500 | dm_source_clocks[i] = clk_get(NULL, dm_source_names[i]); | 550 | dm_timers = omap1_dm_timers; |
501 | BUG_ON(dm_source_clocks[i] == NULL); | 551 | else if (cpu_is_omap24xx()) { |
552 | dm_timers = omap2_dm_timers; | ||
553 | dm_source_names = (char **)omap2_dm_source_names; | ||
554 | dm_source_clocks = (struct clk **)omap2_dm_source_clocks; | ||
555 | } else if (cpu_is_omap34xx()) { | ||
556 | dm_timers = omap3_dm_timers; | ||
557 | dm_source_names = (char **)omap3_dm_source_names; | ||
558 | dm_source_clocks = (struct clk **)omap3_dm_source_clocks; | ||
502 | } | 559 | } |
503 | #endif | 560 | |
561 | if (cpu_class_is_omap2()) | ||
562 | for (i = 0; dm_source_names[i] != NULL; i++) | ||
563 | dm_source_clocks[i] = clk_get(NULL, dm_source_names[i]); | ||
564 | |||
504 | if (cpu_is_omap243x()) | 565 | if (cpu_is_omap243x()) |
505 | dm_timers[0].phys_base = 0x49018000; | 566 | dm_timers[0].phys_base = 0x49018000; |
506 | 567 | ||
507 | for (i = 0; i < dm_timer_count; i++) { | 568 | for (i = 0; i < dm_timer_count; i++) { |
508 | #ifdef CONFIG_ARCH_OMAP2 | ||
509 | char clk_name[16]; | ||
510 | #endif | ||
511 | |||
512 | timer = &dm_timers[i]; | 569 | timer = &dm_timers[i]; |
513 | timer->io_base = (void __iomem *) io_p2v(timer->phys_base); | 570 | timer->io_base = (void __iomem *)io_p2v(timer->phys_base); |
514 | #ifdef CONFIG_ARCH_OMAP2 | 571 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) |
515 | sprintf(clk_name, "gpt%d_ick", i + 1); | 572 | if (cpu_class_is_omap2()) { |
516 | timer->iclk = clk_get(NULL, clk_name); | 573 | char clk_name[16]; |
517 | sprintf(clk_name, "gpt%d_fck", i + 1); | 574 | sprintf(clk_name, "gpt%d_ick", i + 1); |
518 | timer->fclk = clk_get(NULL, clk_name); | 575 | timer->iclk = clk_get(NULL, clk_name); |
576 | sprintf(clk_name, "gpt%d_fck", i + 1); | ||
577 | timer->fclk = clk_get(NULL, clk_name); | ||
578 | } | ||
519 | #endif | 579 | #endif |
520 | } | 580 | } |
521 | 581 | ||