clocksource: sh_mtu2: Hardcode MTU2 clock event rating to 200
[deliverable/linux.git] / drivers / clocksource / sh_mtu2.c
CommitLineData
d5ed4c2e
MD
1/*
2 * SuperH Timer Support - MTU2
3 *
4 * Copyright (C) 2009 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/delay.h>
26#include <linux/io.h>
27#include <linux/clk.h>
28#include <linux/irq.h>
29#include <linux/err.h>
30#include <linux/clockchips.h>
46a12f74 31#include <linux/sh_timer.h>
5a0e3ad6 32#include <linux/slab.h>
7deeab5d 33#include <linux/module.h>
57d13370 34#include <linux/pm_domain.h>
3cb6f10a 35#include <linux/pm_runtime.h>
d5ed4c2e 36
7dad72de 37struct sh_mtu2_device;
42752cc6
LP
38
39struct sh_mtu2_channel {
7dad72de 40 struct sh_mtu2_device *mtu;
d2b93177 41 unsigned int index;
da90a1c6
LP
42
43 void __iomem *base;
42752cc6 44 int irq;
da90a1c6 45
42752cc6
LP
46 struct clock_event_device ced;
47};
48
7dad72de 49struct sh_mtu2_device {
42752cc6
LP
50 struct platform_device *pdev;
51
d5ed4c2e
MD
52 void __iomem *mapbase;
53 struct clk *clk;
42752cc6 54
c54ccb43
LP
55 struct sh_mtu2_channel *channels;
56 unsigned int num_channels;
d5ed4c2e
MD
57};
58
50393a92 59static DEFINE_RAW_SPINLOCK(sh_mtu2_lock);
d5ed4c2e
MD
60
61#define TSTR -1 /* shared register */
62#define TCR 0 /* channel register */
63#define TMDR 1 /* channel register */
64#define TIOR 2 /* channel register */
65#define TIER 3 /* channel register */
66#define TSR 4 /* channel register */
67#define TCNT 5 /* channel register */
68#define TGR 6 /* channel register */
69
f992c241
LP
70#define TCR_CCLR_NONE (0 << 5)
71#define TCR_CCLR_TGRA (1 << 5)
72#define TCR_CCLR_TGRB (2 << 5)
73#define TCR_CCLR_SYNC (3 << 5)
74#define TCR_CCLR_TGRC (5 << 5)
75#define TCR_CCLR_TGRD (6 << 5)
76#define TCR_CCLR_MASK (7 << 5)
77#define TCR_CKEG_RISING (0 << 3)
78#define TCR_CKEG_FALLING (1 << 3)
79#define TCR_CKEG_BOTH (2 << 3)
80#define TCR_CKEG_MASK (3 << 3)
81/* Values 4 to 7 are channel-dependent */
82#define TCR_TPSC_P1 (0 << 0)
83#define TCR_TPSC_P4 (1 << 0)
84#define TCR_TPSC_P16 (2 << 0)
85#define TCR_TPSC_P64 (3 << 0)
86#define TCR_TPSC_CH0_TCLKA (4 << 0)
87#define TCR_TPSC_CH0_TCLKB (5 << 0)
88#define TCR_TPSC_CH0_TCLKC (6 << 0)
89#define TCR_TPSC_CH0_TCLKD (7 << 0)
90#define TCR_TPSC_CH1_TCLKA (4 << 0)
91#define TCR_TPSC_CH1_TCLKB (5 << 0)
92#define TCR_TPSC_CH1_P256 (6 << 0)
93#define TCR_TPSC_CH1_TCNT2 (7 << 0)
94#define TCR_TPSC_CH2_TCLKA (4 << 0)
95#define TCR_TPSC_CH2_TCLKB (5 << 0)
96#define TCR_TPSC_CH2_TCLKC (6 << 0)
97#define TCR_TPSC_CH2_P1024 (7 << 0)
98#define TCR_TPSC_CH34_P256 (4 << 0)
99#define TCR_TPSC_CH34_P1024 (5 << 0)
100#define TCR_TPSC_CH34_TCLKA (6 << 0)
101#define TCR_TPSC_CH34_TCLKB (7 << 0)
102#define TCR_TPSC_MASK (7 << 0)
103
104#define TMDR_BFE (1 << 6)
105#define TMDR_BFB (1 << 5)
106#define TMDR_BFA (1 << 4)
107#define TMDR_MD_NORMAL (0 << 0)
108#define TMDR_MD_PWM_1 (2 << 0)
109#define TMDR_MD_PWM_2 (3 << 0)
110#define TMDR_MD_PHASE_1 (4 << 0)
111#define TMDR_MD_PHASE_2 (5 << 0)
112#define TMDR_MD_PHASE_3 (6 << 0)
113#define TMDR_MD_PHASE_4 (7 << 0)
114#define TMDR_MD_PWM_SYNC (8 << 0)
115#define TMDR_MD_PWM_COMP_CREST (13 << 0)
116#define TMDR_MD_PWM_COMP_TROUGH (14 << 0)
117#define TMDR_MD_PWM_COMP_BOTH (15 << 0)
118#define TMDR_MD_MASK (15 << 0)
119
120#define TIOC_IOCH(n) ((n) << 4)
121#define TIOC_IOCL(n) ((n) << 0)
122#define TIOR_OC_RETAIN (0 << 0)
123#define TIOR_OC_0_CLEAR (1 << 0)
124#define TIOR_OC_0_SET (2 << 0)
125#define TIOR_OC_0_TOGGLE (3 << 0)
126#define TIOR_OC_1_CLEAR (5 << 0)
127#define TIOR_OC_1_SET (6 << 0)
128#define TIOR_OC_1_TOGGLE (7 << 0)
129#define TIOR_IC_RISING (8 << 0)
130#define TIOR_IC_FALLING (9 << 0)
131#define TIOR_IC_BOTH (10 << 0)
132#define TIOR_IC_TCNT (12 << 0)
133#define TIOR_MASK (15 << 0)
134
135#define TIER_TTGE (1 << 7)
136#define TIER_TTGE2 (1 << 6)
137#define TIER_TCIEU (1 << 5)
138#define TIER_TCIEV (1 << 4)
139#define TIER_TGIED (1 << 3)
140#define TIER_TGIEC (1 << 2)
141#define TIER_TGIEB (1 << 1)
142#define TIER_TGIEA (1 << 0)
143
144#define TSR_TCFD (1 << 7)
145#define TSR_TCFU (1 << 5)
146#define TSR_TCFV (1 << 4)
147#define TSR_TGFD (1 << 3)
148#define TSR_TGFC (1 << 2)
149#define TSR_TGFB (1 << 1)
150#define TSR_TGFA (1 << 0)
151
d5ed4c2e
MD
152static unsigned long mtu2_reg_offs[] = {
153 [TCR] = 0,
154 [TMDR] = 1,
155 [TIOR] = 2,
156 [TIER] = 4,
157 [TSR] = 5,
158 [TCNT] = 6,
159 [TGR] = 8,
160};
161
42752cc6 162static inline unsigned long sh_mtu2_read(struct sh_mtu2_channel *ch, int reg_nr)
d5ed4c2e 163{
d5ed4c2e
MD
164 unsigned long offs;
165
166 if (reg_nr == TSTR)
da90a1c6 167 return ioread8(ch->mtu->mapbase);
d5ed4c2e
MD
168
169 offs = mtu2_reg_offs[reg_nr];
170
171 if ((reg_nr == TCNT) || (reg_nr == TGR))
da90a1c6 172 return ioread16(ch->base + offs);
d5ed4c2e 173 else
da90a1c6 174 return ioread8(ch->base + offs);
d5ed4c2e
MD
175}
176
42752cc6 177static inline void sh_mtu2_write(struct sh_mtu2_channel *ch, int reg_nr,
d5ed4c2e
MD
178 unsigned long value)
179{
d5ed4c2e
MD
180 unsigned long offs;
181
182 if (reg_nr == TSTR) {
da90a1c6 183 iowrite8(value, ch->mtu->mapbase);
d5ed4c2e
MD
184 return;
185 }
186
187 offs = mtu2_reg_offs[reg_nr];
188
189 if ((reg_nr == TCNT) || (reg_nr == TGR))
da90a1c6 190 iowrite16(value, ch->base + offs);
d5ed4c2e 191 else
da90a1c6 192 iowrite8(value, ch->base + offs);
d5ed4c2e
MD
193}
194
42752cc6 195static void sh_mtu2_start_stop_ch(struct sh_mtu2_channel *ch, int start)
d5ed4c2e 196{
d5ed4c2e
MD
197 unsigned long flags, value;
198
199 /* start stop register shared by multiple timer channels */
50393a92 200 raw_spin_lock_irqsave(&sh_mtu2_lock, flags);
42752cc6 201 value = sh_mtu2_read(ch, TSTR);
d5ed4c2e
MD
202
203 if (start)
d2b93177 204 value |= 1 << ch->index;
d5ed4c2e 205 else
d2b93177 206 value &= ~(1 << ch->index);
d5ed4c2e 207
42752cc6 208 sh_mtu2_write(ch, TSTR, value);
50393a92 209 raw_spin_unlock_irqrestore(&sh_mtu2_lock, flags);
d5ed4c2e
MD
210}
211
42752cc6 212static int sh_mtu2_enable(struct sh_mtu2_channel *ch)
d5ed4c2e 213{
f92d62f5
LP
214 unsigned long periodic;
215 unsigned long rate;
d5ed4c2e
MD
216 int ret;
217
42752cc6
LP
218 pm_runtime_get_sync(&ch->mtu->pdev->dev);
219 dev_pm_syscore_device(&ch->mtu->pdev->dev, true);
3cb6f10a 220
d5ed4c2e 221 /* enable clock */
42752cc6 222 ret = clk_enable(ch->mtu->clk);
d5ed4c2e 223 if (ret) {
d2b93177
LP
224 dev_err(&ch->mtu->pdev->dev, "ch%u: cannot enable clock\n",
225 ch->index);
d5ed4c2e
MD
226 return ret;
227 }
228
229 /* make sure channel is disabled */
42752cc6 230 sh_mtu2_start_stop_ch(ch, 0);
d5ed4c2e 231
42752cc6 232 rate = clk_get_rate(ch->mtu->clk) / 64;
f92d62f5 233 periodic = (rate + HZ/2) / HZ;
d5ed4c2e 234
f992c241
LP
235 /*
236 * "Periodic Counter Operation"
237 * Clear on TGRA compare match, divide clock by 64.
238 */
239 sh_mtu2_write(ch, TCR, TCR_CCLR_TGRA | TCR_TPSC_P64);
240 sh_mtu2_write(ch, TIOR, TIOC_IOCH(TIOR_OC_0_CLEAR) |
241 TIOC_IOCL(TIOR_OC_0_CLEAR));
42752cc6
LP
242 sh_mtu2_write(ch, TGR, periodic);
243 sh_mtu2_write(ch, TCNT, 0);
f992c241
LP
244 sh_mtu2_write(ch, TMDR, TMDR_MD_NORMAL);
245 sh_mtu2_write(ch, TIER, TIER_TGIEA);
d5ed4c2e
MD
246
247 /* enable channel */
42752cc6 248 sh_mtu2_start_stop_ch(ch, 1);
d5ed4c2e
MD
249
250 return 0;
251}
252
42752cc6 253static void sh_mtu2_disable(struct sh_mtu2_channel *ch)
d5ed4c2e
MD
254{
255 /* disable channel */
42752cc6 256 sh_mtu2_start_stop_ch(ch, 0);
d5ed4c2e
MD
257
258 /* stop clock */
42752cc6 259 clk_disable(ch->mtu->clk);
3cb6f10a 260
42752cc6
LP
261 dev_pm_syscore_device(&ch->mtu->pdev->dev, false);
262 pm_runtime_put(&ch->mtu->pdev->dev);
d5ed4c2e
MD
263}
264
265static irqreturn_t sh_mtu2_interrupt(int irq, void *dev_id)
266{
42752cc6 267 struct sh_mtu2_channel *ch = dev_id;
d5ed4c2e
MD
268
269 /* acknowledge interrupt */
42752cc6 270 sh_mtu2_read(ch, TSR);
f992c241 271 sh_mtu2_write(ch, TSR, ~TSR_TGFA);
d5ed4c2e
MD
272
273 /* notify clockevent layer */
42752cc6 274 ch->ced.event_handler(&ch->ced);
d5ed4c2e
MD
275 return IRQ_HANDLED;
276}
277
42752cc6 278static struct sh_mtu2_channel *ced_to_sh_mtu2(struct clock_event_device *ced)
d5ed4c2e 279{
42752cc6 280 return container_of(ced, struct sh_mtu2_channel, ced);
d5ed4c2e
MD
281}
282
283static void sh_mtu2_clock_event_mode(enum clock_event_mode mode,
284 struct clock_event_device *ced)
285{
42752cc6 286 struct sh_mtu2_channel *ch = ced_to_sh_mtu2(ced);
d5ed4c2e
MD
287 int disabled = 0;
288
289 /* deal with old setting first */
290 switch (ced->mode) {
291 case CLOCK_EVT_MODE_PERIODIC:
42752cc6 292 sh_mtu2_disable(ch);
d5ed4c2e
MD
293 disabled = 1;
294 break;
295 default:
296 break;
297 }
298
299 switch (mode) {
300 case CLOCK_EVT_MODE_PERIODIC:
42752cc6 301 dev_info(&ch->mtu->pdev->dev,
d2b93177 302 "ch%u: used for periodic clock events\n", ch->index);
42752cc6 303 sh_mtu2_enable(ch);
d5ed4c2e
MD
304 break;
305 case CLOCK_EVT_MODE_UNUSED:
306 if (!disabled)
42752cc6 307 sh_mtu2_disable(ch);
d5ed4c2e
MD
308 break;
309 case CLOCK_EVT_MODE_SHUTDOWN:
310 default:
311 break;
312 }
313}
314
cc7ad456
RW
315static void sh_mtu2_clock_event_suspend(struct clock_event_device *ced)
316{
42752cc6 317 pm_genpd_syscore_poweroff(&ced_to_sh_mtu2(ced)->mtu->pdev->dev);
cc7ad456
RW
318}
319
320static void sh_mtu2_clock_event_resume(struct clock_event_device *ced)
321{
42752cc6 322 pm_genpd_syscore_poweron(&ced_to_sh_mtu2(ced)->mtu->pdev->dev);
cc7ad456
RW
323}
324
42752cc6 325static void sh_mtu2_register_clockevent(struct sh_mtu2_channel *ch,
207e21a9 326 const char *name)
d5ed4c2e 327{
42752cc6 328 struct clock_event_device *ced = &ch->ced;
d5ed4c2e
MD
329 int ret;
330
d5ed4c2e
MD
331 ced->name = name;
332 ced->features = CLOCK_EVT_FEAT_PERIODIC;
207e21a9 333 ced->rating = 200;
3cc95047 334 ced->cpumask = cpu_possible_mask;
d5ed4c2e 335 ced->set_mode = sh_mtu2_clock_event_mode;
cc7ad456
RW
336 ced->suspend = sh_mtu2_clock_event_suspend;
337 ced->resume = sh_mtu2_clock_event_resume;
d5ed4c2e 338
d2b93177
LP
339 dev_info(&ch->mtu->pdev->dev, "ch%u: used for clock events\n",
340 ch->index);
da64c2a8
PM
341 clockevents_register_device(ced);
342
42752cc6 343 ret = request_irq(ch->irq, sh_mtu2_interrupt,
276bee05 344 IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
42752cc6 345 dev_name(&ch->mtu->pdev->dev), ch);
d5ed4c2e 346 if (ret) {
d2b93177
LP
347 dev_err(&ch->mtu->pdev->dev, "ch%u: failed to request irq %d\n",
348 ch->index, ch->irq);
d5ed4c2e
MD
349 return;
350 }
d5ed4c2e
MD
351}
352
aa83804a 353static int sh_mtu2_register(struct sh_mtu2_channel *ch, const char *name,
207e21a9 354 bool clockevent)
d5ed4c2e 355{
207e21a9
LP
356 if (clockevent)
357 sh_mtu2_register_clockevent(ch, name);
d5ed4c2e
MD
358
359 return 0;
360}
361
2e1a5326
LP
362static int sh_mtu2_setup_channel(struct sh_mtu2_channel *ch,
363 struct sh_mtu2_device *mtu)
364{
365 struct sh_timer_config *cfg = mtu->pdev->dev.platform_data;
366
2e1a5326 367 ch->mtu = mtu;
d2b93177 368 ch->index = cfg->timer_bit;
2e1a5326
LP
369
370 ch->irq = platform_get_irq(mtu->pdev, 0);
371 if (ch->irq < 0) {
d2b93177
LP
372 dev_err(&mtu->pdev->dev, "ch%u: failed to get irq\n",
373 ch->index);
2e1a5326
LP
374 return ch->irq;
375 }
376
aa83804a 377 return sh_mtu2_register(ch, dev_name(&mtu->pdev->dev),
207e21a9 378 cfg->clockevent_rating != 0);
2e1a5326
LP
379}
380
7dad72de
LP
381static int sh_mtu2_setup(struct sh_mtu2_device *mtu,
382 struct platform_device *pdev)
d5ed4c2e 383{
46a12f74 384 struct sh_timer_config *cfg = pdev->dev.platform_data;
d5ed4c2e 385 struct resource *res;
c54ccb43 386 void __iomem *base;
276bee05 387 int ret;
d5ed4c2e
MD
388 ret = -ENXIO;
389
7dad72de 390 mtu->pdev = pdev;
d5ed4c2e
MD
391
392 if (!cfg) {
7dad72de 393 dev_err(&mtu->pdev->dev, "missing platform data\n");
d5ed4c2e
MD
394 goto err0;
395 }
396
7dad72de 397 platform_set_drvdata(pdev, mtu);
d5ed4c2e 398
7dad72de 399 res = platform_get_resource(mtu->pdev, IORESOURCE_MEM, 0);
d5ed4c2e 400 if (!res) {
7dad72de 401 dev_err(&mtu->pdev->dev, "failed to get I/O memory\n");
d5ed4c2e
MD
402 goto err0;
403 }
404
da90a1c6 405 /*
c54ccb43 406 * Map memory, let base point to our channel and mapbase to the
da90a1c6
LP
407 * start/stop shared register.
408 */
c54ccb43
LP
409 base = ioremap_nocache(res->start, resource_size(res));
410 if (base == NULL) {
7dad72de 411 dev_err(&mtu->pdev->dev, "failed to remap I/O memory\n");
d5ed4c2e
MD
412 goto err0;
413 }
414
c54ccb43 415 mtu->mapbase = base + cfg->channel_offset;
da90a1c6 416
d5ed4c2e 417 /* get hold of clock */
7dad72de
LP
418 mtu->clk = clk_get(&mtu->pdev->dev, "mtu2_fck");
419 if (IS_ERR(mtu->clk)) {
420 dev_err(&mtu->pdev->dev, "cannot get clock\n");
421 ret = PTR_ERR(mtu->clk);
03ff858c 422 goto err1;
d5ed4c2e
MD
423 }
424
7dad72de 425 ret = clk_prepare(mtu->clk);
bd754930
LP
426 if (ret < 0)
427 goto err2;
428
c54ccb43
LP
429 mtu->channels = kzalloc(sizeof(*mtu->channels), GFP_KERNEL);
430 if (mtu->channels == NULL) {
431 ret = -ENOMEM;
432 goto err3;
433 }
434
435 mtu->num_channels = 1;
436
437 mtu->channels[0].base = base;
438
439 ret = sh_mtu2_setup_channel(&mtu->channels[0], mtu);
a4a5fc3b 440 if (ret < 0)
bd754930 441 goto err3;
a4a5fc3b
LP
442
443 return 0;
bd754930 444 err3:
c54ccb43 445 kfree(mtu->channels);
7dad72de 446 clk_unprepare(mtu->clk);
a4a5fc3b 447 err2:
7dad72de 448 clk_put(mtu->clk);
d5ed4c2e 449 err1:
c54ccb43 450 iounmap(base);
d5ed4c2e
MD
451 err0:
452 return ret;
453}
454
1850514b 455static int sh_mtu2_probe(struct platform_device *pdev)
d5ed4c2e 456{
7dad72de 457 struct sh_mtu2_device *mtu = platform_get_drvdata(pdev);
3cb6f10a 458 struct sh_timer_config *cfg = pdev->dev.platform_data;
d5ed4c2e 459 int ret;
57d13370 460
cc7ad456 461 if (!is_early_platform_device(pdev)) {
3cb6f10a
RW
462 pm_runtime_set_active(&pdev->dev);
463 pm_runtime_enable(&pdev->dev);
cc7ad456 464 }
d5ed4c2e 465
7dad72de 466 if (mtu) {
214a607a 467 dev_info(&pdev->dev, "kept as earlytimer\n");
3cb6f10a 468 goto out;
d5ed4c2e
MD
469 }
470
810c6513 471 mtu = kzalloc(sizeof(*mtu), GFP_KERNEL);
7dad72de 472 if (mtu == NULL) {
d5ed4c2e
MD
473 dev_err(&pdev->dev, "failed to allocate driver data\n");
474 return -ENOMEM;
475 }
476
7dad72de 477 ret = sh_mtu2_setup(mtu, pdev);
d5ed4c2e 478 if (ret) {
7dad72de 479 kfree(mtu);
3cb6f10a
RW
480 pm_runtime_idle(&pdev->dev);
481 return ret;
d5ed4c2e 482 }
3cb6f10a
RW
483 if (is_early_platform_device(pdev))
484 return 0;
485
486 out:
487 if (cfg->clockevent_rating)
488 pm_runtime_irq_safe(&pdev->dev);
489 else
490 pm_runtime_idle(&pdev->dev);
491
492 return 0;
d5ed4c2e
MD
493}
494
1850514b 495static int sh_mtu2_remove(struct platform_device *pdev)
d5ed4c2e
MD
496{
497 return -EBUSY; /* cannot unregister clockevent */
498}
499
500static struct platform_driver sh_mtu2_device_driver = {
501 .probe = sh_mtu2_probe,
1850514b 502 .remove = sh_mtu2_remove,
d5ed4c2e
MD
503 .driver = {
504 .name = "sh_mtu2",
505 }
506};
507
508static int __init sh_mtu2_init(void)
509{
510 return platform_driver_register(&sh_mtu2_device_driver);
511}
512
513static void __exit sh_mtu2_exit(void)
514{
515 platform_driver_unregister(&sh_mtu2_device_driver);
516}
517
518early_platform_init("earlytimer", &sh_mtu2_device_driver);
342896a5 519subsys_initcall(sh_mtu2_init);
d5ed4c2e
MD
520module_exit(sh_mtu2_exit);
521
522MODULE_AUTHOR("Magnus Damm");
523MODULE_DESCRIPTION("SuperH MTU2 Timer Driver");
524MODULE_LICENSE("GPL v2");
This page took 0.391378 seconds and 5 git commands to generate.