xref: /openbmc/linux/drivers/clocksource/sh_cmt.c (revision b04b4f78)
1 /*
2  * SuperH Timer Support - CMT
3  *
4  *  Copyright (C) 2008 Magnus Damm
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 
20 #include <linux/init.h>
21 #include <linux/bootmem.h>
22 #include <linux/platform_device.h>
23 #include <linux/spinlock.h>
24 #include <linux/interrupt.h>
25 #include <linux/ioport.h>
26 #include <linux/io.h>
27 #include <linux/clk.h>
28 #include <linux/irq.h>
29 #include <linux/err.h>
30 #include <linux/clocksource.h>
31 #include <linux/clockchips.h>
32 #include <linux/sh_cmt.h>
33 
34 struct sh_cmt_priv {
35 	void __iomem *mapbase;
36 	struct clk *clk;
37 	unsigned long width; /* 16 or 32 bit version of hardware block */
38 	unsigned long overflow_bit;
39 	unsigned long clear_bits;
40 	struct irqaction irqaction;
41 	struct platform_device *pdev;
42 
43 	unsigned long flags;
44 	unsigned long match_value;
45 	unsigned long next_match_value;
46 	unsigned long max_match_value;
47 	unsigned long rate;
48 	spinlock_t lock;
49 	struct clock_event_device ced;
50 	unsigned long total_cycles;
51 };
52 
53 static DEFINE_SPINLOCK(sh_cmt_lock);
54 
55 #define CMSTR -1 /* shared register */
56 #define CMCSR 0 /* channel register */
57 #define CMCNT 1 /* channel register */
58 #define CMCOR 2 /* channel register */
59 
60 static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr)
61 {
62 	struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
63 	void __iomem *base = p->mapbase;
64 	unsigned long offs;
65 
66 	if (reg_nr == CMSTR) {
67 		offs = 0;
68 		base -= cfg->channel_offset;
69 	} else
70 		offs = reg_nr;
71 
72 	if (p->width == 16)
73 		offs <<= 1;
74 	else {
75 		offs <<= 2;
76 		if ((reg_nr == CMCNT) || (reg_nr == CMCOR))
77 			return ioread32(base + offs);
78 	}
79 
80 	return ioread16(base + offs);
81 }
82 
83 static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr,
84 				unsigned long value)
85 {
86 	struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
87 	void __iomem *base = p->mapbase;
88 	unsigned long offs;
89 
90 	if (reg_nr == CMSTR) {
91 		offs = 0;
92 		base -= cfg->channel_offset;
93 	} else
94 		offs = reg_nr;
95 
96 	if (p->width == 16)
97 		offs <<= 1;
98 	else {
99 		offs <<= 2;
100 		if ((reg_nr == CMCNT) || (reg_nr == CMCOR)) {
101 			iowrite32(value, base + offs);
102 			return;
103 		}
104 	}
105 
106 	iowrite16(value, base + offs);
107 }
108 
109 static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
110 					int *has_wrapped)
111 {
112 	unsigned long v1, v2, v3;
113 
114 	/* Make sure the timer value is stable. Stolen from acpi_pm.c */
115 	do {
116 		v1 = sh_cmt_read(p, CMCNT);
117 		v2 = sh_cmt_read(p, CMCNT);
118 		v3 = sh_cmt_read(p, CMCNT);
119 	} while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
120 			  || (v3 > v1 && v3 < v2)));
121 
122 	*has_wrapped = sh_cmt_read(p, CMCSR) & p->overflow_bit;
123 	return v2;
124 }
125 
126 
127 static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start)
128 {
129 	struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
130 	unsigned long flags, value;
131 
132 	/* start stop register shared by multiple timer channels */
133 	spin_lock_irqsave(&sh_cmt_lock, flags);
134 	value = sh_cmt_read(p, CMSTR);
135 
136 	if (start)
137 		value |= 1 << cfg->timer_bit;
138 	else
139 		value &= ~(1 << cfg->timer_bit);
140 
141 	sh_cmt_write(p, CMSTR, value);
142 	spin_unlock_irqrestore(&sh_cmt_lock, flags);
143 }
144 
145 static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
146 {
147 	struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
148 	int ret;
149 
150 	/* enable clock */
151 	ret = clk_enable(p->clk);
152 	if (ret) {
153 		pr_err("sh_cmt: cannot enable clock \"%s\"\n", cfg->clk);
154 		return ret;
155 	}
156 	*rate = clk_get_rate(p->clk) / 8;
157 
158 	/* make sure channel is disabled */
159 	sh_cmt_start_stop_ch(p, 0);
160 
161 	/* configure channel, periodic mode and maximum timeout */
162 	if (p->width == 16)
163 		sh_cmt_write(p, CMCSR, 0);
164 	else
165 		sh_cmt_write(p, CMCSR, 0x01a4);
166 
167 	sh_cmt_write(p, CMCOR, 0xffffffff);
168 	sh_cmt_write(p, CMCNT, 0);
169 
170 	/* enable channel */
171 	sh_cmt_start_stop_ch(p, 1);
172 	return 0;
173 }
174 
175 static void sh_cmt_disable(struct sh_cmt_priv *p)
176 {
177 	/* disable channel */
178 	sh_cmt_start_stop_ch(p, 0);
179 
180 	/* stop clock */
181 	clk_disable(p->clk);
182 }
183 
184 /* private flags */
185 #define FLAG_CLOCKEVENT (1 << 0)
186 #define FLAG_CLOCKSOURCE (1 << 1)
187 #define FLAG_REPROGRAM (1 << 2)
188 #define FLAG_SKIPEVENT (1 << 3)
189 #define FLAG_IRQCONTEXT (1 << 4)
190 
191 static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
192 					      int absolute)
193 {
194 	unsigned long new_match;
195 	unsigned long value = p->next_match_value;
196 	unsigned long delay = 0;
197 	unsigned long now = 0;
198 	int has_wrapped;
199 
200 	now = sh_cmt_get_counter(p, &has_wrapped);
201 	p->flags |= FLAG_REPROGRAM; /* force reprogram */
202 
203 	if (has_wrapped) {
204 		/* we're competing with the interrupt handler.
205 		 *  -> let the interrupt handler reprogram the timer.
206 		 *  -> interrupt number two handles the event.
207 		 */
208 		p->flags |= FLAG_SKIPEVENT;
209 		return;
210 	}
211 
212 	if (absolute)
213 		now = 0;
214 
215 	do {
216 		/* reprogram the timer hardware,
217 		 * but don't save the new match value yet.
218 		 */
219 		new_match = now + value + delay;
220 		if (new_match > p->max_match_value)
221 			new_match = p->max_match_value;
222 
223 		sh_cmt_write(p, CMCOR, new_match);
224 
225 		now = sh_cmt_get_counter(p, &has_wrapped);
226 		if (has_wrapped && (new_match > p->match_value)) {
227 			/* we are changing to a greater match value,
228 			 * so this wrap must be caused by the counter
229 			 * matching the old value.
230 			 * -> first interrupt reprograms the timer.
231 			 * -> interrupt number two handles the event.
232 			 */
233 			p->flags |= FLAG_SKIPEVENT;
234 			break;
235 		}
236 
237 		if (has_wrapped) {
238 			/* we are changing to a smaller match value,
239 			 * so the wrap must be caused by the counter
240 			 * matching the new value.
241 			 * -> save programmed match value.
242 			 * -> let isr handle the event.
243 			 */
244 			p->match_value = new_match;
245 			break;
246 		}
247 
248 		/* be safe: verify hardware settings */
249 		if (now < new_match) {
250 			/* timer value is below match value, all good.
251 			 * this makes sure we won't miss any match events.
252 			 * -> save programmed match value.
253 			 * -> let isr handle the event.
254 			 */
255 			p->match_value = new_match;
256 			break;
257 		}
258 
259 		/* the counter has reached a value greater
260 		 * than our new match value. and since the
261 		 * has_wrapped flag isn't set we must have
262 		 * programmed a too close event.
263 		 * -> increase delay and retry.
264 		 */
265 		if (delay)
266 			delay <<= 1;
267 		else
268 			delay = 1;
269 
270 		if (!delay)
271 			pr_warning("sh_cmt: too long delay\n");
272 
273 	} while (delay);
274 }
275 
276 static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
277 {
278 	unsigned long flags;
279 
280 	if (delta > p->max_match_value)
281 		pr_warning("sh_cmt: delta out of range\n");
282 
283 	spin_lock_irqsave(&p->lock, flags);
284 	p->next_match_value = delta;
285 	sh_cmt_clock_event_program_verify(p, 0);
286 	spin_unlock_irqrestore(&p->lock, flags);
287 }
288 
289 static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
290 {
291 	struct sh_cmt_priv *p = dev_id;
292 
293 	/* clear flags */
294 	sh_cmt_write(p, CMCSR, sh_cmt_read(p, CMCSR) & p->clear_bits);
295 
296 	/* update clock source counter to begin with if enabled
297 	 * the wrap flag should be cleared by the timer specific
298 	 * isr before we end up here.
299 	 */
300 	if (p->flags & FLAG_CLOCKSOURCE)
301 		p->total_cycles += p->match_value;
302 
303 	if (!(p->flags & FLAG_REPROGRAM))
304 		p->next_match_value = p->max_match_value;
305 
306 	p->flags |= FLAG_IRQCONTEXT;
307 
308 	if (p->flags & FLAG_CLOCKEVENT) {
309 		if (!(p->flags & FLAG_SKIPEVENT)) {
310 			if (p->ced.mode == CLOCK_EVT_MODE_ONESHOT) {
311 				p->next_match_value = p->max_match_value;
312 				p->flags |= FLAG_REPROGRAM;
313 			}
314 
315 			p->ced.event_handler(&p->ced);
316 		}
317 	}
318 
319 	p->flags &= ~FLAG_SKIPEVENT;
320 
321 	if (p->flags & FLAG_REPROGRAM) {
322 		p->flags &= ~FLAG_REPROGRAM;
323 		sh_cmt_clock_event_program_verify(p, 1);
324 
325 		if (p->flags & FLAG_CLOCKEVENT)
326 			if ((p->ced.mode == CLOCK_EVT_MODE_SHUTDOWN)
327 			    || (p->match_value == p->next_match_value))
328 				p->flags &= ~FLAG_REPROGRAM;
329 	}
330 
331 	p->flags &= ~FLAG_IRQCONTEXT;
332 
333 	return IRQ_HANDLED;
334 }
335 
336 static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag)
337 {
338 	int ret = 0;
339 	unsigned long flags;
340 
341 	spin_lock_irqsave(&p->lock, flags);
342 
343 	if (!(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
344 		ret = sh_cmt_enable(p, &p->rate);
345 
346 	if (ret)
347 		goto out;
348 	p->flags |= flag;
349 
350 	/* setup timeout if no clockevent */
351 	if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT)))
352 		sh_cmt_set_next(p, p->max_match_value);
353  out:
354 	spin_unlock_irqrestore(&p->lock, flags);
355 
356 	return ret;
357 }
358 
359 static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag)
360 {
361 	unsigned long flags;
362 	unsigned long f;
363 
364 	spin_lock_irqsave(&p->lock, flags);
365 
366 	f = p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE);
367 	p->flags &= ~flag;
368 
369 	if (f && !(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
370 		sh_cmt_disable(p);
371 
372 	/* adjust the timeout to maximum if only clocksource left */
373 	if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE))
374 		sh_cmt_set_next(p, p->max_match_value);
375 
376 	spin_unlock_irqrestore(&p->lock, flags);
377 }
378 
379 static struct sh_cmt_priv *ced_to_sh_cmt(struct clock_event_device *ced)
380 {
381 	return container_of(ced, struct sh_cmt_priv, ced);
382 }
383 
384 static void sh_cmt_clock_event_start(struct sh_cmt_priv *p, int periodic)
385 {
386 	struct clock_event_device *ced = &p->ced;
387 
388 	sh_cmt_start(p, FLAG_CLOCKEVENT);
389 
390 	/* TODO: calculate good shift from rate and counter bit width */
391 
392 	ced->shift = 32;
393 	ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift);
394 	ced->max_delta_ns = clockevent_delta2ns(p->max_match_value, ced);
395 	ced->min_delta_ns = clockevent_delta2ns(0x1f, ced);
396 
397 	if (periodic)
398 		sh_cmt_set_next(p, (p->rate + HZ/2) / HZ);
399 	else
400 		sh_cmt_set_next(p, p->max_match_value);
401 }
402 
403 static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
404 				    struct clock_event_device *ced)
405 {
406 	struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
407 
408 	/* deal with old setting first */
409 	switch (ced->mode) {
410 	case CLOCK_EVT_MODE_PERIODIC:
411 	case CLOCK_EVT_MODE_ONESHOT:
412 		sh_cmt_stop(p, FLAG_CLOCKEVENT);
413 		break;
414 	default:
415 		break;
416 	}
417 
418 	switch (mode) {
419 	case CLOCK_EVT_MODE_PERIODIC:
420 		pr_info("sh_cmt: %s used for periodic clock events\n",
421 			ced->name);
422 		sh_cmt_clock_event_start(p, 1);
423 		break;
424 	case CLOCK_EVT_MODE_ONESHOT:
425 		pr_info("sh_cmt: %s used for oneshot clock events\n",
426 			ced->name);
427 		sh_cmt_clock_event_start(p, 0);
428 		break;
429 	case CLOCK_EVT_MODE_SHUTDOWN:
430 	case CLOCK_EVT_MODE_UNUSED:
431 		sh_cmt_stop(p, FLAG_CLOCKEVENT);
432 		break;
433 	default:
434 		break;
435 	}
436 }
437 
438 static int sh_cmt_clock_event_next(unsigned long delta,
439 				   struct clock_event_device *ced)
440 {
441 	struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
442 
443 	BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT);
444 	if (likely(p->flags & FLAG_IRQCONTEXT))
445 		p->next_match_value = delta;
446 	else
447 		sh_cmt_set_next(p, delta);
448 
449 	return 0;
450 }
451 
452 static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
453 				       char *name, unsigned long rating)
454 {
455 	struct clock_event_device *ced = &p->ced;
456 
457 	memset(ced, 0, sizeof(*ced));
458 
459 	ced->name = name;
460 	ced->features = CLOCK_EVT_FEAT_PERIODIC;
461 	ced->features |= CLOCK_EVT_FEAT_ONESHOT;
462 	ced->rating = rating;
463 	ced->cpumask = cpumask_of(0);
464 	ced->set_next_event = sh_cmt_clock_event_next;
465 	ced->set_mode = sh_cmt_clock_event_mode;
466 
467 	pr_info("sh_cmt: %s used for clock events\n", ced->name);
468 	clockevents_register_device(ced);
469 }
470 
471 int sh_cmt_register(struct sh_cmt_priv *p, char *name,
472 		    unsigned long clockevent_rating,
473 		    unsigned long clocksource_rating)
474 {
475 	if (p->width == (sizeof(p->max_match_value) * 8))
476 		p->max_match_value = ~0;
477 	else
478 		p->max_match_value = (1 << p->width) - 1;
479 
480 	p->match_value = p->max_match_value;
481 	spin_lock_init(&p->lock);
482 
483 	if (clockevent_rating)
484 		sh_cmt_register_clockevent(p, name, clockevent_rating);
485 
486 	return 0;
487 }
488 
489 static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
490 {
491 	struct sh_cmt_config *cfg = pdev->dev.platform_data;
492 	struct resource *res;
493 	int irq, ret;
494 	ret = -ENXIO;
495 
496 	memset(p, 0, sizeof(*p));
497 	p->pdev = pdev;
498 
499 	if (!cfg) {
500 		dev_err(&p->pdev->dev, "missing platform data\n");
501 		goto err0;
502 	}
503 
504 	platform_set_drvdata(pdev, p);
505 
506 	res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0);
507 	if (!res) {
508 		dev_err(&p->pdev->dev, "failed to get I/O memory\n");
509 		goto err0;
510 	}
511 
512 	irq = platform_get_irq(p->pdev, 0);
513 	if (irq < 0) {
514 		dev_err(&p->pdev->dev, "failed to get irq\n");
515 		goto err0;
516 	}
517 
518 	/* map memory, let mapbase point to our channel */
519 	p->mapbase = ioremap_nocache(res->start, resource_size(res));
520 	if (p->mapbase == NULL) {
521 		pr_err("sh_cmt: failed to remap I/O memory\n");
522 		goto err0;
523 	}
524 
525 	/* request irq using setup_irq() (too early for request_irq()) */
526 	p->irqaction.name = cfg->name;
527 	p->irqaction.handler = sh_cmt_interrupt;
528 	p->irqaction.dev_id = p;
529 	p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL;
530 	p->irqaction.mask = CPU_MASK_NONE;
531 	ret = setup_irq(irq, &p->irqaction);
532 	if (ret) {
533 		pr_err("sh_cmt: failed to request irq %d\n", irq);
534 		goto err1;
535 	}
536 
537 	/* get hold of clock */
538 	p->clk = clk_get(&p->pdev->dev, cfg->clk);
539 	if (IS_ERR(p->clk)) {
540 		pr_err("sh_cmt: cannot get clock \"%s\"\n", cfg->clk);
541 		ret = PTR_ERR(p->clk);
542 		goto err2;
543 	}
544 
545 	if (resource_size(res) == 6) {
546 		p->width = 16;
547 		p->overflow_bit = 0x80;
548 		p->clear_bits = ~0xc0;
549 	} else {
550 		p->width = 32;
551 		p->overflow_bit = 0x8000;
552 		p->clear_bits = ~0xc000;
553 	}
554 
555 	return sh_cmt_register(p, cfg->name,
556 			       cfg->clockevent_rating,
557 			       cfg->clocksource_rating);
558  err2:
559 	remove_irq(irq, &p->irqaction);
560  err1:
561 	iounmap(p->mapbase);
562  err0:
563 	return ret;
564 }
565 
566 static int __devinit sh_cmt_probe(struct platform_device *pdev)
567 {
568 	struct sh_cmt_priv *p = platform_get_drvdata(pdev);
569 	int ret;
570 
571 	p = kmalloc(sizeof(*p), GFP_KERNEL);
572 	if (p == NULL) {
573 		dev_err(&pdev->dev, "failed to allocate driver data\n");
574 		return -ENOMEM;
575 	}
576 
577 	ret = sh_cmt_setup(p, pdev);
578 	if (ret) {
579 		kfree(p);
580 
581 		platform_set_drvdata(pdev, NULL);
582 	}
583 	return ret;
584 }
585 
586 static int __devexit sh_cmt_remove(struct platform_device *pdev)
587 {
588 	return -EBUSY; /* cannot unregister clockevent and clocksource */
589 }
590 
591 static struct platform_driver sh_cmt_device_driver = {
592 	.probe		= sh_cmt_probe,
593 	.remove		= __devexit_p(sh_cmt_remove),
594 	.driver		= {
595 		.name	= "sh_cmt",
596 	}
597 };
598 
599 static int __init sh_cmt_init(void)
600 {
601 	return platform_driver_register(&sh_cmt_device_driver);
602 }
603 
604 static void __exit sh_cmt_exit(void)
605 {
606 	platform_driver_unregister(&sh_cmt_device_driver);
607 }
608 
609 module_init(sh_cmt_init);
610 module_exit(sh_cmt_exit);
611 
612 MODULE_AUTHOR("Magnus Damm");
613 MODULE_DESCRIPTION("SuperH CMT Timer Driver");
614 MODULE_LICENSE("GPL v2");
615