Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gptimers.c
Go to the documentation of this file.
1 /*
2  * gptimers.c - Blackfin General Purpose Timer core API
3  *
4  * Copyright (c) 2005-2008 Analog Devices Inc.
5  * Copyright (C) 2005 John DeHority
6  * Copyright (C) 2006 Hella Aglaia GmbH ([email protected])
7  *
8  * Licensed under the GPLv2.
9  */
10 
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/io.h>
14 
15 #include <asm/blackfin.h>
16 #include <asm/gptimers.h>
17 
18 #ifdef DEBUG
19 # define tassert(expr)
20 #else
21 # define tassert(expr) \
22  if (!(expr)) \
23  printk(KERN_DEBUG "%s:%s:%i: Assertion failed: " #expr "\n", __FILE__, __func__, __LINE__);
24 #endif
25 
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
31 
32 static struct bfin_gptimer_regs * const timer_regs[MAX_BLACKFIN_GPTIMERS] =
33 {
34  (void *)TIMER0_CONFIG,
35  (void *)TIMER1_CONFIG,
36  (void *)TIMER2_CONFIG,
37 #if (MAX_BLACKFIN_GPTIMERS > 3)
38  (void *)TIMER3_CONFIG,
39  (void *)TIMER4_CONFIG,
40  (void *)TIMER5_CONFIG,
41  (void *)TIMER6_CONFIG,
42  (void *)TIMER7_CONFIG,
43 # if (MAX_BLACKFIN_GPTIMERS > 8)
44  (void *)TIMER8_CONFIG,
45  (void *)TIMER9_CONFIG,
46  (void *)TIMER10_CONFIG,
47 # if (MAX_BLACKFIN_GPTIMERS > 11)
48  (void *)TIMER11_CONFIG,
49 # endif
50 # endif
51 #endif
52 };
53 
54 static struct bfin_gptimer_group_regs * const group_regs[BFIN_TIMER_NUM_GROUP] =
55 {
56  (void *)TIMER0_GROUP_REG,
57 #if (MAX_BLACKFIN_GPTIMERS > 8)
58  (void *)TIMER8_GROUP_REG,
59 #endif
60 };
61 
62 static uint32_t const trun_mask[MAX_BLACKFIN_GPTIMERS] =
63 {
67 #if (MAX_BLACKFIN_GPTIMERS > 3)
73 # if (MAX_BLACKFIN_GPTIMERS > 8)
77 # if (MAX_BLACKFIN_GPTIMERS > 11)
79 # endif
80 # endif
81 #endif
82 };
83 
84 static uint32_t const tovf_mask[MAX_BLACKFIN_GPTIMERS] =
85 {
89 #if (MAX_BLACKFIN_GPTIMERS > 3)
95 # if (MAX_BLACKFIN_GPTIMERS > 8)
99 # if (MAX_BLACKFIN_GPTIMERS > 11)
101 # endif
102 # endif
103 #endif
104 };
105 
106 static uint32_t const timil_mask[MAX_BLACKFIN_GPTIMERS] =
107 {
111 #if (MAX_BLACKFIN_GPTIMERS > 3)
117 # if (MAX_BLACKFIN_GPTIMERS > 8)
121 # if (MAX_BLACKFIN_GPTIMERS > 11)
123 # endif
124 # endif
125 #endif
126 };
127 
128 void set_gptimer_pwidth(unsigned int timer_id, uint32_t value)
129 {
130  tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
131  bfin_write(&timer_regs[timer_id]->width, value);
132  SSYNC();
133 }
135 
136 uint32_t get_gptimer_pwidth(unsigned int timer_id)
137 {
138  tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
139  return bfin_read(&timer_regs[timer_id]->width);
140 }
142 
143 void set_gptimer_period(unsigned int timer_id, uint32_t period)
144 {
145  tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
146  bfin_write(&timer_regs[timer_id]->period, period);
147  SSYNC();
148 }
150 
151 uint32_t get_gptimer_period(unsigned int timer_id)
152 {
153  tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
154  return bfin_read(&timer_regs[timer_id]->period);
155 }
157 
158 uint32_t get_gptimer_count(unsigned int timer_id)
159 {
160  tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
161  return bfin_read(&timer_regs[timer_id]->counter);
162 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
232 #else
234 {
235  tassert(group < BFIN_TIMER_NUM_GROUP);
236  return bfin_read(&group_regs[group]->status);
237 }
239 
241 {
242  tassert(group < BFIN_TIMER_NUM_GROUP);
243  bfin_write(&group_regs[group]->status, value);
244  SSYNC();
245 }
247 
248 static uint32_t read_gptimer_status(unsigned int timer_id)
249 {
250  return bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->status);
251 }
252 
253 int get_gptimer_intr(unsigned int timer_id)
254 {
255  tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
256  return !!(read_gptimer_status(timer_id) & timil_mask[timer_id]);
257 }
259 
260 void clear_gptimer_intr(unsigned int timer_id)
261 {
262  tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
263  bfin_write(&group_regs[BFIN_TIMER_OCTET(timer_id)]->status, timil_mask[timer_id]);
264 }
266 
267 int get_gptimer_over(unsigned int timer_id)
268 {
269  tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
270  return !!(read_gptimer_status(timer_id) & tovf_mask[timer_id]);
271 }
273 
274 void clear_gptimer_over(unsigned int timer_id)
275 {
276  tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
277  bfin_write(&group_regs[BFIN_TIMER_OCTET(timer_id)]->status, tovf_mask[timer_id]);
278 }
280 
281 int get_gptimer_run(unsigned int timer_id)
282 {
283  tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
284  return !!(read_gptimer_status(timer_id) & trun_mask[timer_id]);
285 }
287 #endif
288 
289 void set_gptimer_config(unsigned int timer_id, uint16_t config)
290 {
291  tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
292  bfin_write(&timer_regs[timer_id]->config, config);
293  SSYNC();
294 }
296 
297 uint16_t get_gptimer_config(unsigned int timer_id)
298 {
299  tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
300  return bfin_read(&timer_regs[timer_id]->config);
301 }
303 
305 {
306  int i;
307 #ifdef CONFIG_BF60x
308  uint16_t imask;
309  imask = bfin_read16(TIMER_DATA_IMSK);
310  imask &= ~mask;
312 #endif
313  tassert((mask & ~BLACKFIN_GPTIMER_IDMASK) == 0);
314  for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i) {
315  bfin_write(&group_regs[i]->enable, mask & 0xFF);
316  mask >>= 8;
317  }
318  SSYNC();
319 }
321 
322 static void _disable_gptimers(uint16_t mask)
323 {
324  int i;
325  uint16_t m = mask;
326  tassert((mask & ~BLACKFIN_GPTIMER_IDMASK) == 0);
327  for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i) {
328  bfin_write(&group_regs[i]->disable, m & 0xFF);
329  m >>= 8;
330  }
331 }
332 
334 {
335 #ifndef CONFIG_BF60x
336  int i;
337  _disable_gptimers(mask);
338  for (i = 0; i < MAX_BLACKFIN_GPTIMERS; ++i)
339  if (mask & (1 << i))
340  bfin_write(&group_regs[BFIN_TIMER_OCTET(i)]->status, trun_mask[i]);
341  SSYNC();
342 #else
343  _disable_gptimers(mask);
344 #endif
345 }
347 
349 {
350  _disable_gptimers(mask);
351  SSYNC();
352 }
354 
355 void set_gptimer_pulse_hi(unsigned int timer_id)
356 {
357  tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
358  bfin_write_or(&timer_regs[timer_id]->config, TIMER_PULSE_HI);
359  SSYNC();
360 }
362 
363 void clear_gptimer_pulse_hi(unsigned int timer_id)
364 {
365  tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
366  bfin_write_and(&timer_regs[timer_id]->config, ~TIMER_PULSE_HI);
367  SSYNC();
368 }
370 
372 {
373  int i;
374  uint16_t result = 0;
375  for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i)
376  result |= (bfin_read(&group_regs[i]->enable) << (i << 3));
377  return result;
378 }
380 
381 MODULE_AUTHOR("Axel Weiss ([email protected])");
382 MODULE_DESCRIPTION("Blackfin General Purpose Timers API");
383 MODULE_LICENSE("GPL");