• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/clocksource/
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/platform_device.h>
22#include <linux/spinlock.h>
23#include <linux/interrupt.h>
24#include <linux/ioport.h>
25#include <linux/io.h>
26#include <linux/clk.h>
27#include <linux/irq.h>
28#include <linux/err.h>
29#include <linux/clocksource.h>
30#include <linux/clockchips.h>
31#include <linux/sh_timer.h>
32#include <linux/slab.h>
33
34struct 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	struct clocksource cs;
51	unsigned long total_cycles;
52};
53
54static DEFINE_SPINLOCK(sh_cmt_lock);
55
56#define CMSTR -1 /* shared register */
57#define CMCSR 0 /* channel register */
58#define CMCNT 1 /* channel register */
59#define CMCOR 2 /* channel register */
60
61static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr)
62{
63	struct sh_timer_config *cfg = p->pdev->dev.platform_data;
64	void __iomem *base = p->mapbase;
65	unsigned long offs;
66
67	if (reg_nr == CMSTR) {
68		offs = 0;
69		base -= cfg->channel_offset;
70	} else
71		offs = reg_nr;
72
73	if (p->width == 16)
74		offs <<= 1;
75	else {
76		offs <<= 2;
77		if ((reg_nr == CMCNT) || (reg_nr == CMCOR))
78			return ioread32(base + offs);
79	}
80
81	return ioread16(base + offs);
82}
83
84static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr,
85				unsigned long value)
86{
87	struct sh_timer_config *cfg = p->pdev->dev.platform_data;
88	void __iomem *base = p->mapbase;
89	unsigned long offs;
90
91	if (reg_nr == CMSTR) {
92		offs = 0;
93		base -= cfg->channel_offset;
94	} else
95		offs = reg_nr;
96
97	if (p->width == 16)
98		offs <<= 1;
99	else {
100		offs <<= 2;
101		if ((reg_nr == CMCNT) || (reg_nr == CMCOR)) {
102			iowrite32(value, base + offs);
103			return;
104		}
105	}
106
107	iowrite16(value, base + offs);
108}
109
110static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
111					int *has_wrapped)
112{
113	unsigned long v1, v2, v3;
114	int o1, o2;
115
116	o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit;
117
118	/* Make sure the timer value is stable. Stolen from acpi_pm.c */
119	do {
120		o2 = o1;
121		v1 = sh_cmt_read(p, CMCNT);
122		v2 = sh_cmt_read(p, CMCNT);
123		v3 = sh_cmt_read(p, CMCNT);
124		o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit;
125	} while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
126			  || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
127
128	*has_wrapped = o1;
129	return v2;
130}
131
132
133static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start)
134{
135	struct sh_timer_config *cfg = p->pdev->dev.platform_data;
136	unsigned long flags, value;
137
138	/* start stop register shared by multiple timer channels */
139	spin_lock_irqsave(&sh_cmt_lock, flags);
140	value = sh_cmt_read(p, CMSTR);
141
142	if (start)
143		value |= 1 << cfg->timer_bit;
144	else
145		value &= ~(1 << cfg->timer_bit);
146
147	sh_cmt_write(p, CMSTR, value);
148	spin_unlock_irqrestore(&sh_cmt_lock, flags);
149}
150
151static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
152{
153	int ret;
154
155	/* enable clock */
156	ret = clk_enable(p->clk);
157	if (ret) {
158		dev_err(&p->pdev->dev, "cannot enable clock\n");
159		return ret;
160	}
161
162	/* make sure channel is disabled */
163	sh_cmt_start_stop_ch(p, 0);
164
165	/* configure channel, periodic mode and maximum timeout */
166	if (p->width == 16) {
167		*rate = clk_get_rate(p->clk) / 512;
168		sh_cmt_write(p, CMCSR, 0x43);
169	} else {
170		*rate = clk_get_rate(p->clk) / 8;
171		sh_cmt_write(p, CMCSR, 0x01a4);
172	}
173
174	sh_cmt_write(p, CMCOR, 0xffffffff);
175	sh_cmt_write(p, CMCNT, 0);
176
177	/* enable channel */
178	sh_cmt_start_stop_ch(p, 1);
179	return 0;
180}
181
182static void sh_cmt_disable(struct sh_cmt_priv *p)
183{
184	/* disable channel */
185	sh_cmt_start_stop_ch(p, 0);
186
187	/* disable interrupts in CMT block */
188	sh_cmt_write(p, CMCSR, 0);
189
190	/* stop clock */
191	clk_disable(p->clk);
192}
193
194/* private flags */
195#define FLAG_CLOCKEVENT (1 << 0)
196#define FLAG_CLOCKSOURCE (1 << 1)
197#define FLAG_REPROGRAM (1 << 2)
198#define FLAG_SKIPEVENT (1 << 3)
199#define FLAG_IRQCONTEXT (1 << 4)
200
201static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
202					      int absolute)
203{
204	unsigned long new_match;
205	unsigned long value = p->next_match_value;
206	unsigned long delay = 0;
207	unsigned long now = 0;
208	int has_wrapped;
209
210	now = sh_cmt_get_counter(p, &has_wrapped);
211	p->flags |= FLAG_REPROGRAM; /* force reprogram */
212
213	if (has_wrapped) {
214		/* we're competing with the interrupt handler.
215		 *  -> let the interrupt handler reprogram the timer.
216		 *  -> interrupt number two handles the event.
217		 */
218		p->flags |= FLAG_SKIPEVENT;
219		return;
220	}
221
222	if (absolute)
223		now = 0;
224
225	do {
226		/* reprogram the timer hardware,
227		 * but don't save the new match value yet.
228		 */
229		new_match = now + value + delay;
230		if (new_match > p->max_match_value)
231			new_match = p->max_match_value;
232
233		sh_cmt_write(p, CMCOR, new_match);
234
235		now = sh_cmt_get_counter(p, &has_wrapped);
236		if (has_wrapped && (new_match > p->match_value)) {
237			/* we are changing to a greater match value,
238			 * so this wrap must be caused by the counter
239			 * matching the old value.
240			 * -> first interrupt reprograms the timer.
241			 * -> interrupt number two handles the event.
242			 */
243			p->flags |= FLAG_SKIPEVENT;
244			break;
245		}
246
247		if (has_wrapped) {
248			/* we are changing to a smaller match value,
249			 * so the wrap must be caused by the counter
250			 * matching the new value.
251			 * -> save programmed match value.
252			 * -> let isr handle the event.
253			 */
254			p->match_value = new_match;
255			break;
256		}
257
258		/* be safe: verify hardware settings */
259		if (now < new_match) {
260			/* timer value is below match value, all good.
261			 * this makes sure we won't miss any match events.
262			 * -> save programmed match value.
263			 * -> let isr handle the event.
264			 */
265			p->match_value = new_match;
266			break;
267		}
268
269		/* the counter has reached a value greater
270		 * than our new match value. and since the
271		 * has_wrapped flag isn't set we must have
272		 * programmed a too close event.
273		 * -> increase delay and retry.
274		 */
275		if (delay)
276			delay <<= 1;
277		else
278			delay = 1;
279
280		if (!delay)
281			dev_warn(&p->pdev->dev, "too long delay\n");
282
283	} while (delay);
284}
285
286static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
287{
288	unsigned long flags;
289
290	if (delta > p->max_match_value)
291		dev_warn(&p->pdev->dev, "delta out of range\n");
292
293	spin_lock_irqsave(&p->lock, flags);
294	p->next_match_value = delta;
295	sh_cmt_clock_event_program_verify(p, 0);
296	spin_unlock_irqrestore(&p->lock, flags);
297}
298
299static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
300{
301	struct sh_cmt_priv *p = dev_id;
302
303	/* clear flags */
304	sh_cmt_write(p, CMCSR, sh_cmt_read(p, CMCSR) & p->clear_bits);
305
306	/* update clock source counter to begin with if enabled
307	 * the wrap flag should be cleared by the timer specific
308	 * isr before we end up here.
309	 */
310	if (p->flags & FLAG_CLOCKSOURCE)
311		p->total_cycles += p->match_value;
312
313	if (!(p->flags & FLAG_REPROGRAM))
314		p->next_match_value = p->max_match_value;
315
316	p->flags |= FLAG_IRQCONTEXT;
317
318	if (p->flags & FLAG_CLOCKEVENT) {
319		if (!(p->flags & FLAG_SKIPEVENT)) {
320			if (p->ced.mode == CLOCK_EVT_MODE_ONESHOT) {
321				p->next_match_value = p->max_match_value;
322				p->flags |= FLAG_REPROGRAM;
323			}
324
325			p->ced.event_handler(&p->ced);
326		}
327	}
328
329	p->flags &= ~FLAG_SKIPEVENT;
330
331	if (p->flags & FLAG_REPROGRAM) {
332		p->flags &= ~FLAG_REPROGRAM;
333		sh_cmt_clock_event_program_verify(p, 1);
334
335		if (p->flags & FLAG_CLOCKEVENT)
336			if ((p->ced.mode == CLOCK_EVT_MODE_SHUTDOWN)
337			    || (p->match_value == p->next_match_value))
338				p->flags &= ~FLAG_REPROGRAM;
339	}
340
341	p->flags &= ~FLAG_IRQCONTEXT;
342
343	return IRQ_HANDLED;
344}
345
346static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag)
347{
348	int ret = 0;
349	unsigned long flags;
350
351	spin_lock_irqsave(&p->lock, flags);
352
353	if (!(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
354		ret = sh_cmt_enable(p, &p->rate);
355
356	if (ret)
357		goto out;
358	p->flags |= flag;
359
360	/* setup timeout if no clockevent */
361	if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT)))
362		sh_cmt_set_next(p, p->max_match_value);
363 out:
364	spin_unlock_irqrestore(&p->lock, flags);
365
366	return ret;
367}
368
369static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag)
370{
371	unsigned long flags;
372	unsigned long f;
373
374	spin_lock_irqsave(&p->lock, flags);
375
376	f = p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE);
377	p->flags &= ~flag;
378
379	if (f && !(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
380		sh_cmt_disable(p);
381
382	/* adjust the timeout to maximum if only clocksource left */
383	if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE))
384		sh_cmt_set_next(p, p->max_match_value);
385
386	spin_unlock_irqrestore(&p->lock, flags);
387}
388
389static struct sh_cmt_priv *cs_to_sh_cmt(struct clocksource *cs)
390{
391	return container_of(cs, struct sh_cmt_priv, cs);
392}
393
394static cycle_t sh_cmt_clocksource_read(struct clocksource *cs)
395{
396	struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
397	unsigned long flags, raw;
398	unsigned long value;
399	int has_wrapped;
400
401	spin_lock_irqsave(&p->lock, flags);
402	value = p->total_cycles;
403	raw = sh_cmt_get_counter(p, &has_wrapped);
404
405	if (unlikely(has_wrapped))
406		raw += p->match_value;
407	spin_unlock_irqrestore(&p->lock, flags);
408
409	return value + raw;
410}
411
412static int sh_cmt_clocksource_enable(struct clocksource *cs)
413{
414	struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
415
416	p->total_cycles = 0;
417
418	return sh_cmt_start(p, FLAG_CLOCKSOURCE);
419}
420
421static void sh_cmt_clocksource_disable(struct clocksource *cs)
422{
423	sh_cmt_stop(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE);
424}
425
426static void sh_cmt_clocksource_resume(struct clocksource *cs)
427{
428	sh_cmt_start(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE);
429}
430
431static int sh_cmt_register_clocksource(struct sh_cmt_priv *p,
432				       char *name, unsigned long rating)
433{
434	struct clocksource *cs = &p->cs;
435
436	cs->name = name;
437	cs->rating = rating;
438	cs->read = sh_cmt_clocksource_read;
439	cs->enable = sh_cmt_clocksource_enable;
440	cs->disable = sh_cmt_clocksource_disable;
441	cs->suspend = sh_cmt_clocksource_disable;
442	cs->resume = sh_cmt_clocksource_resume;
443	cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
444	cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
445
446	/* clk_get_rate() needs an enabled clock */
447	clk_enable(p->clk);
448	p->rate = clk_get_rate(p->clk) / (p->width == 16) ? 512 : 8;
449	clk_disable(p->clk);
450
451	/* TODO: calculate good shift from rate and counter bit width */
452	cs->shift = 0;
453	cs->mult = clocksource_hz2mult(p->rate, cs->shift);
454
455	dev_info(&p->pdev->dev, "used as clock source\n");
456
457	clocksource_register(cs);
458
459	return 0;
460}
461
462static struct sh_cmt_priv *ced_to_sh_cmt(struct clock_event_device *ced)
463{
464	return container_of(ced, struct sh_cmt_priv, ced);
465}
466
467static void sh_cmt_clock_event_start(struct sh_cmt_priv *p, int periodic)
468{
469	struct clock_event_device *ced = &p->ced;
470
471	sh_cmt_start(p, FLAG_CLOCKEVENT);
472
473	/* TODO: calculate good shift from rate and counter bit width */
474
475	ced->shift = 32;
476	ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift);
477	ced->max_delta_ns = clockevent_delta2ns(p->max_match_value, ced);
478	ced->min_delta_ns = clockevent_delta2ns(0x1f, ced);
479
480	if (periodic)
481		sh_cmt_set_next(p, (p->rate + HZ/2) / HZ);
482	else
483		sh_cmt_set_next(p, p->max_match_value);
484}
485
486static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
487				    struct clock_event_device *ced)
488{
489	struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
490
491	/* deal with old setting first */
492	switch (ced->mode) {
493	case CLOCK_EVT_MODE_PERIODIC:
494	case CLOCK_EVT_MODE_ONESHOT:
495		sh_cmt_stop(p, FLAG_CLOCKEVENT);
496		break;
497	default:
498		break;
499	}
500
501	switch (mode) {
502	case CLOCK_EVT_MODE_PERIODIC:
503		dev_info(&p->pdev->dev, "used for periodic clock events\n");
504		sh_cmt_clock_event_start(p, 1);
505		break;
506	case CLOCK_EVT_MODE_ONESHOT:
507		dev_info(&p->pdev->dev, "used for oneshot clock events\n");
508		sh_cmt_clock_event_start(p, 0);
509		break;
510	case CLOCK_EVT_MODE_SHUTDOWN:
511	case CLOCK_EVT_MODE_UNUSED:
512		sh_cmt_stop(p, FLAG_CLOCKEVENT);
513		break;
514	default:
515		break;
516	}
517}
518
519static int sh_cmt_clock_event_next(unsigned long delta,
520				   struct clock_event_device *ced)
521{
522	struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
523
524	BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT);
525	if (likely(p->flags & FLAG_IRQCONTEXT))
526		p->next_match_value = delta;
527	else
528		sh_cmt_set_next(p, delta);
529
530	return 0;
531}
532
533static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
534				       char *name, unsigned long rating)
535{
536	struct clock_event_device *ced = &p->ced;
537
538	memset(ced, 0, sizeof(*ced));
539
540	ced->name = name;
541	ced->features = CLOCK_EVT_FEAT_PERIODIC;
542	ced->features |= CLOCK_EVT_FEAT_ONESHOT;
543	ced->rating = rating;
544	ced->cpumask = cpumask_of(0);
545	ced->set_next_event = sh_cmt_clock_event_next;
546	ced->set_mode = sh_cmt_clock_event_mode;
547
548	dev_info(&p->pdev->dev, "used for clock events\n");
549	clockevents_register_device(ced);
550}
551
552static int sh_cmt_register(struct sh_cmt_priv *p, char *name,
553			   unsigned long clockevent_rating,
554			   unsigned long clocksource_rating)
555{
556	if (p->width == (sizeof(p->max_match_value) * 8))
557		p->max_match_value = ~0;
558	else
559		p->max_match_value = (1 << p->width) - 1;
560
561	p->match_value = p->max_match_value;
562	spin_lock_init(&p->lock);
563
564	if (clockevent_rating)
565		sh_cmt_register_clockevent(p, name, clockevent_rating);
566
567	if (clocksource_rating)
568		sh_cmt_register_clocksource(p, name, clocksource_rating);
569
570	return 0;
571}
572
573static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
574{
575	struct sh_timer_config *cfg = pdev->dev.platform_data;
576	struct resource *res;
577	int irq, ret;
578	ret = -ENXIO;
579
580	memset(p, 0, sizeof(*p));
581	p->pdev = pdev;
582
583	if (!cfg) {
584		dev_err(&p->pdev->dev, "missing platform data\n");
585		goto err0;
586	}
587
588	platform_set_drvdata(pdev, p);
589
590	res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0);
591	if (!res) {
592		dev_err(&p->pdev->dev, "failed to get I/O memory\n");
593		goto err0;
594	}
595
596	irq = platform_get_irq(p->pdev, 0);
597	if (irq < 0) {
598		dev_err(&p->pdev->dev, "failed to get irq\n");
599		goto err0;
600	}
601
602	/* map memory, let mapbase point to our channel */
603	p->mapbase = ioremap_nocache(res->start, resource_size(res));
604	if (p->mapbase == NULL) {
605		dev_err(&p->pdev->dev, "failed to remap I/O memory\n");
606		goto err0;
607	}
608
609	/* request irq using setup_irq() (too early for request_irq()) */
610	p->irqaction.name = dev_name(&p->pdev->dev);
611	p->irqaction.handler = sh_cmt_interrupt;
612	p->irqaction.dev_id = p;
613	p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | \
614			     IRQF_IRQPOLL  | IRQF_NOBALANCING;
615
616	/* get hold of clock */
617	p->clk = clk_get(&p->pdev->dev, "cmt_fck");
618	if (IS_ERR(p->clk)) {
619		dev_warn(&p->pdev->dev, "using deprecated clock lookup\n");
620		p->clk = clk_get(&p->pdev->dev, cfg->clk);
621		if (IS_ERR(p->clk)) {
622			dev_err(&p->pdev->dev, "cannot get clock\n");
623			ret = PTR_ERR(p->clk);
624			goto err1;
625		}
626	}
627
628	if (resource_size(res) == 6) {
629		p->width = 16;
630		p->overflow_bit = 0x80;
631		p->clear_bits = ~0x80;
632	} else {
633		p->width = 32;
634		p->overflow_bit = 0x8000;
635		p->clear_bits = ~0xc000;
636	}
637
638	ret = sh_cmt_register(p, (char *)dev_name(&p->pdev->dev),
639			      cfg->clockevent_rating,
640			      cfg->clocksource_rating);
641	if (ret) {
642		dev_err(&p->pdev->dev, "registration failed\n");
643		goto err1;
644	}
645
646	ret = setup_irq(irq, &p->irqaction);
647	if (ret) {
648		dev_err(&p->pdev->dev, "failed to request irq %d\n", irq);
649		goto err1;
650	}
651
652	return 0;
653
654err1:
655	iounmap(p->mapbase);
656err0:
657	return ret;
658}
659
660static int __devinit sh_cmt_probe(struct platform_device *pdev)
661{
662	struct sh_cmt_priv *p = platform_get_drvdata(pdev);
663	int ret;
664
665	if (p) {
666		dev_info(&pdev->dev, "kept as earlytimer\n");
667		return 0;
668	}
669
670	p = kmalloc(sizeof(*p), GFP_KERNEL);
671	if (p == NULL) {
672		dev_err(&pdev->dev, "failed to allocate driver data\n");
673		return -ENOMEM;
674	}
675
676	ret = sh_cmt_setup(p, pdev);
677	if (ret) {
678		kfree(p);
679		platform_set_drvdata(pdev, NULL);
680	}
681	return ret;
682}
683
684static int __devexit sh_cmt_remove(struct platform_device *pdev)
685{
686	return -EBUSY; /* cannot unregister clockevent and clocksource */
687}
688
689static struct platform_driver sh_cmt_device_driver = {
690	.probe		= sh_cmt_probe,
691	.remove		= __devexit_p(sh_cmt_remove),
692	.driver		= {
693		.name	= "sh_cmt",
694	}
695};
696
697static int __init sh_cmt_init(void)
698{
699	return platform_driver_register(&sh_cmt_device_driver);
700}
701
702static void __exit sh_cmt_exit(void)
703{
704	platform_driver_unregister(&sh_cmt_device_driver);
705}
706
707early_platform_init("earlytimer", &sh_cmt_device_driver);
708module_init(sh_cmt_init);
709module_exit(sh_cmt_exit);
710
711MODULE_AUTHOR("Magnus Damm");
712MODULE_DESCRIPTION("SuperH CMT Timer Driver");
713MODULE_LICENSE("GPL v2");
714