diff options
author | Steven Miao <realmz6@gmail.com> | 2012-05-16 06:11:10 -0400 |
---|---|---|
committer | Bob Liu <lliubbo@gmail.com> | 2012-05-21 02:54:20 -0400 |
commit | 2879bb30d788bb3841e2f1675ea7af5204eb171c (patch) | |
tree | a5d5eaca8faa37c95fda955c11a5c9d902bff7a5 /arch/blackfin/kernel | |
parent | e578bbdeb8db3656eff428f097d6c8ed2f3718a5 (diff) |
blackfin: bf60x: enable gptimer clock source
Signed-off-by: Steven Miao <realmz6@gmail.com>
Signed-off-by: Bob Liu <lliubbo@gmail.com>
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r-- | arch/blackfin/kernel/gptimers.c | 83 | ||||
-rw-r--r-- | arch/blackfin/kernel/time-ts.c | 27 |
2 files changed, 107 insertions, 3 deletions
diff --git a/arch/blackfin/kernel/gptimers.c b/arch/blackfin/kernel/gptimers.c index 06459f4bf43a..f7afe570f880 100644 --- a/arch/blackfin/kernel/gptimers.c +++ b/arch/blackfin/kernel/gptimers.c | |||
@@ -23,7 +23,11 @@ | |||
23 | printk(KERN_DEBUG "%s:%s:%i: Assertion failed: " #expr "\n", __FILE__, __func__, __LINE__); | 23 | printk(KERN_DEBUG "%s:%s:%i: Assertion failed: " #expr "\n", __FILE__, __func__, __LINE__); |
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | #define BFIN_TIMER_NUM_GROUP (BFIN_TIMER_OCTET(MAX_BLACKFIN_GPTIMERS - 1) + 1) | 26 | #ifndef CONFIG_BF60x |
27 | # define BFIN_TIMER_NUM_GROUP (BFIN_TIMER_OCTET(MAX_BLACKFIN_GPTIMERS - 1) + 1) | ||
28 | #else | ||
29 | # define BFIN_TIMER_NUM_GROUP 1 | ||
30 | #endif | ||
27 | 31 | ||
28 | static struct bfin_gptimer_regs * const timer_regs[MAX_BLACKFIN_GPTIMERS] = | 32 | static struct bfin_gptimer_regs * const timer_regs[MAX_BLACKFIN_GPTIMERS] = |
29 | { | 33 | { |
@@ -158,6 +162,74 @@ uint32_t get_gptimer_count(unsigned int timer_id) | |||
158 | } | 162 | } |
159 | EXPORT_SYMBOL(get_gptimer_count); | 163 | EXPORT_SYMBOL(get_gptimer_count); |
160 | 164 | ||
165 | #ifdef CONFIG_BF60x | ||
166 | void set_gptimer_delay(unsigned int timer_id, uint32_t delay) | ||
167 | { | ||
168 | tassert(timer_id < MAX_BLACKFIN_GPTIMERS); | ||
169 | bfin_write(&timer_regs[timer_id]->delay, delay); | ||
170 | SSYNC(); | ||
171 | } | ||
172 | EXPORT_SYMBOL(set_gptimer_delay); | ||
173 | |||
174 | uint32_t get_gptimer_delay(unsigned int timer_id) | ||
175 | { | ||
176 | tassert(timer_id < MAX_BLACKFIN_GPTIMERS); | ||
177 | return bfin_read(&timer_regs[timer_id]->delay); | ||
178 | } | ||
179 | EXPORT_SYMBOL(get_gptimer_delay); | ||
180 | #endif | ||
181 | |||
182 | #ifdef CONFIG_BF60x | ||
183 | int get_gptimer_intr(unsigned int timer_id) | ||
184 | { | ||
185 | tassert(timer_id < MAX_BLACKFIN_GPTIMERS); | ||
186 | return !!(bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->data_ilat) & timil_mask[timer_id]); | ||
187 | } | ||
188 | EXPORT_SYMBOL(get_gptimer_intr); | ||
189 | |||
190 | void clear_gptimer_intr(unsigned int timer_id) | ||
191 | { | ||
192 | tassert(timer_id < MAX_BLACKFIN_GPTIMERS); | ||
193 | bfin_write(&group_regs[BFIN_TIMER_OCTET(timer_id)]->data_ilat, timil_mask[timer_id]); | ||
194 | } | ||
195 | EXPORT_SYMBOL(clear_gptimer_intr); | ||
196 | |||
197 | int get_gptimer_over(unsigned int timer_id) | ||
198 | { | ||
199 | tassert(timer_id < MAX_BLACKFIN_GPTIMERS); | ||
200 | return !!(bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->stat_ilat) & tovf_mask[timer_id]); | ||
201 | } | ||
202 | EXPORT_SYMBOL(get_gptimer_over); | ||
203 | |||
204 | void clear_gptimer_over(unsigned int timer_id) | ||
205 | { | ||
206 | tassert(timer_id < MAX_BLACKFIN_GPTIMERS); | ||
207 | bfin_write(&group_regs[BFIN_TIMER_OCTET(timer_id)]->stat_ilat, tovf_mask[timer_id]); | ||
208 | } | ||
209 | EXPORT_SYMBOL(clear_gptimer_over); | ||
210 | |||
211 | int get_gptimer_run(unsigned int timer_id) | ||
212 | { | ||
213 | tassert(timer_id < MAX_BLACKFIN_GPTIMERS); | ||
214 | return !!(bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->run) & trun_mask[timer_id]); | ||
215 | } | ||
216 | EXPORT_SYMBOL(get_gptimer_run); | ||
217 | |||
218 | uint32_t get_gptimer_status(unsigned int group) | ||
219 | { | ||
220 | tassert(group < BFIN_TIMER_NUM_GROUP); | ||
221 | return bfin_read(&group_regs[group]->data_ilat); | ||
222 | } | ||
223 | EXPORT_SYMBOL(get_gptimer_status); | ||
224 | |||
225 | void set_gptimer_status(unsigned int group, uint32_t value) | ||
226 | { | ||
227 | tassert(group < BFIN_TIMER_NUM_GROUP); | ||
228 | bfin_write(&group_regs[group]->data_ilat, value); | ||
229 | SSYNC(); | ||
230 | } | ||
231 | EXPORT_SYMBOL(set_gptimer_status); | ||
232 | #else | ||
161 | uint32_t get_gptimer_status(unsigned int group) | 233 | uint32_t get_gptimer_status(unsigned int group) |
162 | { | 234 | { |
163 | tassert(group < BFIN_TIMER_NUM_GROUP); | 235 | tassert(group < BFIN_TIMER_NUM_GROUP); |
@@ -212,6 +284,7 @@ int get_gptimer_run(unsigned int timer_id) | |||
212 | return !!(read_gptimer_status(timer_id) & trun_mask[timer_id]); | 284 | return !!(read_gptimer_status(timer_id) & trun_mask[timer_id]); |
213 | } | 285 | } |
214 | EXPORT_SYMBOL(get_gptimer_run); | 286 | EXPORT_SYMBOL(get_gptimer_run); |
287 | #endif | ||
215 | 288 | ||
216 | void set_gptimer_config(unsigned int timer_id, uint16_t config) | 289 | void set_gptimer_config(unsigned int timer_id, uint16_t config) |
217 | { | 290 | { |
@@ -231,6 +304,12 @@ EXPORT_SYMBOL(get_gptimer_config); | |||
231 | void enable_gptimers(uint16_t mask) | 304 | void enable_gptimers(uint16_t mask) |
232 | { | 305 | { |
233 | int i; | 306 | int i; |
307 | #ifdef CONFIG_BF60x | ||
308 | uint16_t imask; | ||
309 | imask = bfin_read16(TIMER_DATA_IMSK); | ||
310 | imask &= ~mask; | ||
311 | bfin_write16(TIMER_DATA_IMSK, imask); | ||
312 | #endif | ||
234 | tassert((mask & ~BLACKFIN_GPTIMER_IDMASK) == 0); | 313 | tassert((mask & ~BLACKFIN_GPTIMER_IDMASK) == 0); |
235 | for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i) { | 314 | for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i) { |
236 | bfin_write(&group_regs[i]->enable, mask & 0xFF); | 315 | bfin_write(&group_regs[i]->enable, mask & 0xFF); |
@@ -255,10 +334,12 @@ void disable_gptimers(uint16_t mask) | |||
255 | { | 334 | { |
256 | int i; | 335 | int i; |
257 | _disable_gptimers(mask); | 336 | _disable_gptimers(mask); |
337 | #ifndef CONFIG_BF60x | ||
258 | for (i = 0; i < MAX_BLACKFIN_GPTIMERS; ++i) | 338 | for (i = 0; i < MAX_BLACKFIN_GPTIMERS; ++i) |
259 | if (mask & (1 << i)) | 339 | if (mask & (1 << i)) |
260 | bfin_write(&group_regs[BFIN_TIMER_OCTET(i)]->status, trun_mask[i]); | 340 | bfin_write(&group_regs[BFIN_TIMER_OCTET(i)]->status, trun_mask[i]); |
261 | SSYNC(); | 341 | SSYNC(); |
342 | #endif | ||
262 | } | 343 | } |
263 | EXPORT_SYMBOL(disable_gptimers); | 344 | EXPORT_SYMBOL(disable_gptimers); |
264 | 345 | ||
diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c index d98f2d69b0c4..f608f02f29a3 100644 --- a/arch/blackfin/kernel/time-ts.c +++ b/arch/blackfin/kernel/time-ts.c | |||
@@ -66,8 +66,14 @@ void __init setup_gptimer0(void) | |||
66 | { | 66 | { |
67 | disable_gptimers(TIMER0bit); | 67 | disable_gptimers(TIMER0bit); |
68 | 68 | ||
69 | #ifdef CONFIG_BF60x | ||
70 | bfin_write16(TIMER_DATA_IMSK, 0); | ||
71 | set_gptimer_config(TIMER0_id, TIMER_OUT_DIS | ||
72 | | TIMER_MODE_PWM_CONT | TIMER_PULSE_HI | TIMER_IRQ_PER); | ||
73 | #else | ||
69 | set_gptimer_config(TIMER0_id, \ | 74 | set_gptimer_config(TIMER0_id, \ |
70 | TIMER_OUT_DIS | TIMER_PERIOD_CNT | TIMER_MODE_PWM); | 75 | TIMER_OUT_DIS | TIMER_PERIOD_CNT | TIMER_MODE_PWM); |
76 | #endif | ||
71 | set_gptimer_period(TIMER0_id, -1); | 77 | set_gptimer_period(TIMER0_id, -1); |
72 | set_gptimer_pwidth(TIMER0_id, -2); | 78 | set_gptimer_pwidth(TIMER0_id, -2); |
73 | SSYNC(); | 79 | SSYNC(); |
@@ -135,9 +141,15 @@ static void bfin_gptmr0_set_mode(enum clock_event_mode mode, | |||
135 | { | 141 | { |
136 | switch (mode) { | 142 | switch (mode) { |
137 | case CLOCK_EVT_MODE_PERIODIC: { | 143 | case CLOCK_EVT_MODE_PERIODIC: { |
144 | #ifndef CONFIG_BF60x | ||
138 | set_gptimer_config(TIMER0_id, \ | 145 | set_gptimer_config(TIMER0_id, \ |
139 | TIMER_OUT_DIS | TIMER_IRQ_ENA | \ | 146 | TIMER_OUT_DIS | TIMER_IRQ_ENA | \ |
140 | TIMER_PERIOD_CNT | TIMER_MODE_PWM); | 147 | TIMER_PERIOD_CNT | TIMER_MODE_PWM); |
148 | #else | ||
149 | set_gptimer_config(TIMER0_id, TIMER_OUT_DIS | ||
150 | | TIMER_MODE_PWM_CONT | TIMER_PULSE_HI | TIMER_IRQ_PER); | ||
151 | #endif | ||
152 | |||
141 | set_gptimer_period(TIMER0_id, get_sclk() / HZ); | 153 | set_gptimer_period(TIMER0_id, get_sclk() / HZ); |
142 | set_gptimer_pwidth(TIMER0_id, get_sclk() / HZ - 1); | 154 | set_gptimer_pwidth(TIMER0_id, get_sclk() / HZ - 1); |
143 | enable_gptimers(TIMER0bit); | 155 | enable_gptimers(TIMER0bit); |
@@ -145,8 +157,14 @@ static void bfin_gptmr0_set_mode(enum clock_event_mode mode, | |||
145 | } | 157 | } |
146 | case CLOCK_EVT_MODE_ONESHOT: | 158 | case CLOCK_EVT_MODE_ONESHOT: |
147 | disable_gptimers(TIMER0bit); | 159 | disable_gptimers(TIMER0bit); |
160 | #ifndef CONFIG_BF60x | ||
148 | set_gptimer_config(TIMER0_id, \ | 161 | set_gptimer_config(TIMER0_id, \ |
149 | TIMER_OUT_DIS | TIMER_IRQ_ENA | TIMER_MODE_PWM); | 162 | TIMER_OUT_DIS | TIMER_IRQ_ENA | TIMER_MODE_PWM); |
163 | #else | ||
164 | set_gptimer_config(TIMER0_id, TIMER_OUT_DIS | TIMER_MODE_PWM | ||
165 | | TIMER_PULSE_HI | TIMER_IRQ_WID_DLY); | ||
166 | #endif | ||
167 | |||
150 | set_gptimer_period(TIMER0_id, 0); | 168 | set_gptimer_period(TIMER0_id, 0); |
151 | break; | 169 | break; |
152 | case CLOCK_EVT_MODE_UNUSED: | 170 | case CLOCK_EVT_MODE_UNUSED: |
@@ -160,7 +178,7 @@ static void bfin_gptmr0_set_mode(enum clock_event_mode mode, | |||
160 | 178 | ||
161 | static void bfin_gptmr0_ack(void) | 179 | static void bfin_gptmr0_ack(void) |
162 | { | 180 | { |
163 | set_gptimer_status(TIMER_GROUP1, TIMER_STATUS_TIMIL0); | 181 | clear_gptimer_intr(TIMER0_id); |
164 | } | 182 | } |
165 | 183 | ||
166 | static void __init bfin_gptmr0_init(void) | 184 | static void __init bfin_gptmr0_init(void) |
@@ -197,7 +215,7 @@ static struct clock_event_device clockevent_gptmr0 = { | |||
197 | .rating = 300, | 215 | .rating = 300, |
198 | .irq = IRQ_TIMER0, | 216 | .irq = IRQ_TIMER0, |
199 | .shift = 32, | 217 | .shift = 32, |
200 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 218 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
201 | .set_next_event = bfin_gptmr0_set_next_event, | 219 | .set_next_event = bfin_gptmr0_set_next_event, |
202 | .set_mode = bfin_gptmr0_set_mode, | 220 | .set_mode = bfin_gptmr0_set_mode, |
203 | }; | 221 | }; |
@@ -312,6 +330,11 @@ void bfin_coretmr_clockevent_init(void) | |||
312 | #endif | 330 | #endif |
313 | 331 | ||
314 | 332 | ||
333 | #ifdef CONFIG_SMP | ||
334 | evt->broadcast = smp_timer_broadcast; | ||
335 | #endif | ||
336 | |||
337 | |||
315 | evt->name = "bfin_core_timer"; | 338 | evt->name = "bfin_core_timer"; |
316 | evt->rating = 350; | 339 | evt->rating = 350; |
317 | evt->irq = -1; | 340 | evt->irq = -1; |