Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/clocksource/sh_cmt.c
15109 views
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
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
struct clocksource cs;
51
unsigned long total_cycles;
52
};
53
54
static 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
61
static 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
84
static 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
110
static 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
133
static 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
151
static 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
182
static 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
201
static 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
286
static void __sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
287
{
288
if (delta > p->max_match_value)
289
dev_warn(&p->pdev->dev, "delta out of range\n");
290
291
p->next_match_value = delta;
292
sh_cmt_clock_event_program_verify(p, 0);
293
}
294
295
static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
296
{
297
unsigned long flags;
298
299
spin_lock_irqsave(&p->lock, flags);
300
__sh_cmt_set_next(p, delta);
301
spin_unlock_irqrestore(&p->lock, flags);
302
}
303
304
static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
305
{
306
struct sh_cmt_priv *p = dev_id;
307
308
/* clear flags */
309
sh_cmt_write(p, CMCSR, sh_cmt_read(p, CMCSR) & p->clear_bits);
310
311
/* update clock source counter to begin with if enabled
312
* the wrap flag should be cleared by the timer specific
313
* isr before we end up here.
314
*/
315
if (p->flags & FLAG_CLOCKSOURCE)
316
p->total_cycles += p->match_value + 1;
317
318
if (!(p->flags & FLAG_REPROGRAM))
319
p->next_match_value = p->max_match_value;
320
321
p->flags |= FLAG_IRQCONTEXT;
322
323
if (p->flags & FLAG_CLOCKEVENT) {
324
if (!(p->flags & FLAG_SKIPEVENT)) {
325
if (p->ced.mode == CLOCK_EVT_MODE_ONESHOT) {
326
p->next_match_value = p->max_match_value;
327
p->flags |= FLAG_REPROGRAM;
328
}
329
330
p->ced.event_handler(&p->ced);
331
}
332
}
333
334
p->flags &= ~FLAG_SKIPEVENT;
335
336
if (p->flags & FLAG_REPROGRAM) {
337
p->flags &= ~FLAG_REPROGRAM;
338
sh_cmt_clock_event_program_verify(p, 1);
339
340
if (p->flags & FLAG_CLOCKEVENT)
341
if ((p->ced.mode == CLOCK_EVT_MODE_SHUTDOWN)
342
|| (p->match_value == p->next_match_value))
343
p->flags &= ~FLAG_REPROGRAM;
344
}
345
346
p->flags &= ~FLAG_IRQCONTEXT;
347
348
return IRQ_HANDLED;
349
}
350
351
static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag)
352
{
353
int ret = 0;
354
unsigned long flags;
355
356
spin_lock_irqsave(&p->lock, flags);
357
358
if (!(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
359
ret = sh_cmt_enable(p, &p->rate);
360
361
if (ret)
362
goto out;
363
p->flags |= flag;
364
365
/* setup timeout if no clockevent */
366
if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT)))
367
__sh_cmt_set_next(p, p->max_match_value);
368
out:
369
spin_unlock_irqrestore(&p->lock, flags);
370
371
return ret;
372
}
373
374
static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag)
375
{
376
unsigned long flags;
377
unsigned long f;
378
379
spin_lock_irqsave(&p->lock, flags);
380
381
f = p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE);
382
p->flags &= ~flag;
383
384
if (f && !(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
385
sh_cmt_disable(p);
386
387
/* adjust the timeout to maximum if only clocksource left */
388
if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE))
389
__sh_cmt_set_next(p, p->max_match_value);
390
391
spin_unlock_irqrestore(&p->lock, flags);
392
}
393
394
static struct sh_cmt_priv *cs_to_sh_cmt(struct clocksource *cs)
395
{
396
return container_of(cs, struct sh_cmt_priv, cs);
397
}
398
399
static cycle_t sh_cmt_clocksource_read(struct clocksource *cs)
400
{
401
struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
402
unsigned long flags, raw;
403
unsigned long value;
404
int has_wrapped;
405
406
spin_lock_irqsave(&p->lock, flags);
407
value = p->total_cycles;
408
raw = sh_cmt_get_counter(p, &has_wrapped);
409
410
if (unlikely(has_wrapped))
411
raw += p->match_value + 1;
412
spin_unlock_irqrestore(&p->lock, flags);
413
414
return value + raw;
415
}
416
417
static int sh_cmt_clocksource_enable(struct clocksource *cs)
418
{
419
int ret;
420
struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
421
422
p->total_cycles = 0;
423
424
ret = sh_cmt_start(p, FLAG_CLOCKSOURCE);
425
if (!ret)
426
__clocksource_updatefreq_hz(cs, p->rate);
427
return ret;
428
}
429
430
static void sh_cmt_clocksource_disable(struct clocksource *cs)
431
{
432
sh_cmt_stop(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE);
433
}
434
435
static void sh_cmt_clocksource_resume(struct clocksource *cs)
436
{
437
sh_cmt_start(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE);
438
}
439
440
static int sh_cmt_register_clocksource(struct sh_cmt_priv *p,
441
char *name, unsigned long rating)
442
{
443
struct clocksource *cs = &p->cs;
444
445
cs->name = name;
446
cs->rating = rating;
447
cs->read = sh_cmt_clocksource_read;
448
cs->enable = sh_cmt_clocksource_enable;
449
cs->disable = sh_cmt_clocksource_disable;
450
cs->suspend = sh_cmt_clocksource_disable;
451
cs->resume = sh_cmt_clocksource_resume;
452
cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
453
cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
454
455
dev_info(&p->pdev->dev, "used as clock source\n");
456
457
/* Register with dummy 1 Hz value, gets updated in ->enable() */
458
clocksource_register_hz(cs, 1);
459
return 0;
460
}
461
462
static 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
467
static 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) - 1);
482
else
483
sh_cmt_set_next(p, p->max_match_value);
484
}
485
486
static 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
519
static 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 - 1;
527
else
528
sh_cmt_set_next(p, delta - 1);
529
530
return 0;
531
}
532
533
static 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
552
static 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
573
static 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_err(&p->pdev->dev, "cannot get clock\n");
620
ret = PTR_ERR(p->clk);
621
goto err1;
622
}
623
624
if (resource_size(res) == 6) {
625
p->width = 16;
626
p->overflow_bit = 0x80;
627
p->clear_bits = ~0x80;
628
} else {
629
p->width = 32;
630
p->overflow_bit = 0x8000;
631
p->clear_bits = ~0xc000;
632
}
633
634
ret = sh_cmt_register(p, (char *)dev_name(&p->pdev->dev),
635
cfg->clockevent_rating,
636
cfg->clocksource_rating);
637
if (ret) {
638
dev_err(&p->pdev->dev, "registration failed\n");
639
goto err1;
640
}
641
642
ret = setup_irq(irq, &p->irqaction);
643
if (ret) {
644
dev_err(&p->pdev->dev, "failed to request irq %d\n", irq);
645
goto err1;
646
}
647
648
return 0;
649
650
err1:
651
iounmap(p->mapbase);
652
err0:
653
return ret;
654
}
655
656
static int __devinit sh_cmt_probe(struct platform_device *pdev)
657
{
658
struct sh_cmt_priv *p = platform_get_drvdata(pdev);
659
int ret;
660
661
if (p) {
662
dev_info(&pdev->dev, "kept as earlytimer\n");
663
return 0;
664
}
665
666
p = kmalloc(sizeof(*p), GFP_KERNEL);
667
if (p == NULL) {
668
dev_err(&pdev->dev, "failed to allocate driver data\n");
669
return -ENOMEM;
670
}
671
672
ret = sh_cmt_setup(p, pdev);
673
if (ret) {
674
kfree(p);
675
platform_set_drvdata(pdev, NULL);
676
}
677
return ret;
678
}
679
680
static int __devexit sh_cmt_remove(struct platform_device *pdev)
681
{
682
return -EBUSY; /* cannot unregister clockevent and clocksource */
683
}
684
685
static struct platform_driver sh_cmt_device_driver = {
686
.probe = sh_cmt_probe,
687
.remove = __devexit_p(sh_cmt_remove),
688
.driver = {
689
.name = "sh_cmt",
690
}
691
};
692
693
static int __init sh_cmt_init(void)
694
{
695
return platform_driver_register(&sh_cmt_device_driver);
696
}
697
698
static void __exit sh_cmt_exit(void)
699
{
700
platform_driver_unregister(&sh_cmt_device_driver);
701
}
702
703
early_platform_init("earlytimer", &sh_cmt_device_driver);
704
module_init(sh_cmt_init);
705
module_exit(sh_cmt_exit);
706
707
MODULE_AUTHOR("Magnus Damm");
708
MODULE_DESCRIPTION("SuperH CMT Timer Driver");
709
MODULE_LICENSE("GPL v2");
710
711