677 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * SuperH Timer Support - TMU4 *5 * Copyright (C) 2009 Magnus Damm6 */7 8#include <linux/clk.h>9#include <linux/clockchips.h>10#include <linux/clocksource.h>11#include <linux/delay.h>12#include <linux/err.h>13#include <linux/init.h>14#include <linux/interrupt.h>15#include <linux/io.h>16#include <linux/ioport.h>17#include <linux/irq.h>18#include <linux/module.h>19#include <linux/of.h>20#include <linux/platform_device.h>21#include <linux/pm_domain.h>22#include <linux/pm_runtime.h>23#include <linux/sh_timer.h>24#include <linux/slab.h>25#include <linux/spinlock.h>26 27#ifdef CONFIG_SUPERH28#include <asm/platform_early.h>29#endif30 31enum sh_tmu_model {32 SH_TMU,33 SH_TMU_SH3,34};35 36struct sh_tmu_device;37 38struct sh_tmu_channel {39 struct sh_tmu_device *tmu;40 unsigned int index;41 42 void __iomem *base;43 int irq;44 45 unsigned long periodic;46 struct clock_event_device ced;47 struct clocksource cs;48 bool cs_enabled;49 unsigned int enable_count;50};51 52struct sh_tmu_device {53 struct platform_device *pdev;54 55 void __iomem *mapbase;56 struct clk *clk;57 unsigned long rate;58 59 enum sh_tmu_model model;60 61 raw_spinlock_t lock; /* Protect the shared start/stop register */62 63 struct sh_tmu_channel *channels;64 unsigned int num_channels;65 66 bool has_clockevent;67 bool has_clocksource;68};69 70#define TSTR -1 /* shared register */71#define TCOR 0 /* channel register */72#define TCNT 1 /* channel register */73#define TCR 2 /* channel register */74 75#define TCR_UNF (1 << 8)76#define TCR_UNIE (1 << 5)77#define TCR_TPSC_CLK4 (0 << 0)78#define TCR_TPSC_CLK16 (1 << 0)79#define TCR_TPSC_CLK64 (2 << 0)80#define TCR_TPSC_CLK256 (3 << 0)81#define TCR_TPSC_CLK1024 (4 << 0)82#define TCR_TPSC_MASK (7 << 0)83 84static inline unsigned long sh_tmu_read(struct sh_tmu_channel *ch, int reg_nr)85{86 unsigned long offs;87 88 if (reg_nr == TSTR) {89 switch (ch->tmu->model) {90 case SH_TMU_SH3:91 return ioread8(ch->tmu->mapbase + 2);92 case SH_TMU:93 return ioread8(ch->tmu->mapbase + 4);94 }95 }96 97 offs = reg_nr << 2;98 99 if (reg_nr == TCR)100 return ioread16(ch->base + offs);101 else102 return ioread32(ch->base + offs);103}104 105static inline void sh_tmu_write(struct sh_tmu_channel *ch, int reg_nr,106 unsigned long value)107{108 unsigned long offs;109 110 if (reg_nr == TSTR) {111 switch (ch->tmu->model) {112 case SH_TMU_SH3:113 return iowrite8(value, ch->tmu->mapbase + 2);114 case SH_TMU:115 return iowrite8(value, ch->tmu->mapbase + 4);116 }117 }118 119 offs = reg_nr << 2;120 121 if (reg_nr == TCR)122 iowrite16(value, ch->base + offs);123 else124 iowrite32(value, ch->base + offs);125}126 127static void sh_tmu_start_stop_ch(struct sh_tmu_channel *ch, int start)128{129 unsigned long flags, value;130 131 /* start stop register shared by multiple timer channels */132 raw_spin_lock_irqsave(&ch->tmu->lock, flags);133 value = sh_tmu_read(ch, TSTR);134 135 if (start)136 value |= 1 << ch->index;137 else138 value &= ~(1 << ch->index);139 140 sh_tmu_write(ch, TSTR, value);141 raw_spin_unlock_irqrestore(&ch->tmu->lock, flags);142}143 144static int __sh_tmu_enable(struct sh_tmu_channel *ch)145{146 int ret;147 148 /* enable clock */149 ret = clk_enable(ch->tmu->clk);150 if (ret) {151 dev_err(&ch->tmu->pdev->dev, "ch%u: cannot enable clock\n",152 ch->index);153 return ret;154 }155 156 /* make sure channel is disabled */157 sh_tmu_start_stop_ch(ch, 0);158 159 /* maximum timeout */160 sh_tmu_write(ch, TCOR, 0xffffffff);161 sh_tmu_write(ch, TCNT, 0xffffffff);162 163 /* configure channel to parent clock / 4, irq off */164 sh_tmu_write(ch, TCR, TCR_TPSC_CLK4);165 166 /* enable channel */167 sh_tmu_start_stop_ch(ch, 1);168 169 return 0;170}171 172static int sh_tmu_enable(struct sh_tmu_channel *ch)173{174 if (ch->enable_count++ > 0)175 return 0;176 177 pm_runtime_get_sync(&ch->tmu->pdev->dev);178 dev_pm_syscore_device(&ch->tmu->pdev->dev, true);179 180 return __sh_tmu_enable(ch);181}182 183static void __sh_tmu_disable(struct sh_tmu_channel *ch)184{185 /* disable channel */186 sh_tmu_start_stop_ch(ch, 0);187 188 /* disable interrupts in TMU block */189 sh_tmu_write(ch, TCR, TCR_TPSC_CLK4);190 191 /* stop clock */192 clk_disable(ch->tmu->clk);193}194 195static void sh_tmu_disable(struct sh_tmu_channel *ch)196{197 if (WARN_ON(ch->enable_count == 0))198 return;199 200 if (--ch->enable_count > 0)201 return;202 203 __sh_tmu_disable(ch);204 205 dev_pm_syscore_device(&ch->tmu->pdev->dev, false);206 pm_runtime_put(&ch->tmu->pdev->dev);207}208 209static void sh_tmu_set_next(struct sh_tmu_channel *ch, unsigned long delta,210 int periodic)211{212 /* stop timer */213 sh_tmu_start_stop_ch(ch, 0);214 215 /* acknowledge interrupt */216 sh_tmu_read(ch, TCR);217 218 /* enable interrupt */219 sh_tmu_write(ch, TCR, TCR_UNIE | TCR_TPSC_CLK4);220 221 /* reload delta value in case of periodic timer */222 if (periodic)223 sh_tmu_write(ch, TCOR, delta);224 else225 sh_tmu_write(ch, TCOR, 0xffffffff);226 227 sh_tmu_write(ch, TCNT, delta);228 229 /* start timer */230 sh_tmu_start_stop_ch(ch, 1);231}232 233static irqreturn_t sh_tmu_interrupt(int irq, void *dev_id)234{235 struct sh_tmu_channel *ch = dev_id;236 237 /* disable or acknowledge interrupt */238 if (clockevent_state_oneshot(&ch->ced))239 sh_tmu_write(ch, TCR, TCR_TPSC_CLK4);240 else241 sh_tmu_write(ch, TCR, TCR_UNIE | TCR_TPSC_CLK4);242 243 /* notify clockevent layer */244 ch->ced.event_handler(&ch->ced);245 return IRQ_HANDLED;246}247 248static struct sh_tmu_channel *cs_to_sh_tmu(struct clocksource *cs)249{250 return container_of(cs, struct sh_tmu_channel, cs);251}252 253static u64 sh_tmu_clocksource_read(struct clocksource *cs)254{255 struct sh_tmu_channel *ch = cs_to_sh_tmu(cs);256 257 return sh_tmu_read(ch, TCNT) ^ 0xffffffff;258}259 260static int sh_tmu_clocksource_enable(struct clocksource *cs)261{262 struct sh_tmu_channel *ch = cs_to_sh_tmu(cs);263 int ret;264 265 if (WARN_ON(ch->cs_enabled))266 return 0;267 268 ret = sh_tmu_enable(ch);269 if (!ret)270 ch->cs_enabled = true;271 272 return ret;273}274 275static void sh_tmu_clocksource_disable(struct clocksource *cs)276{277 struct sh_tmu_channel *ch = cs_to_sh_tmu(cs);278 279 if (WARN_ON(!ch->cs_enabled))280 return;281 282 sh_tmu_disable(ch);283 ch->cs_enabled = false;284}285 286static void sh_tmu_clocksource_suspend(struct clocksource *cs)287{288 struct sh_tmu_channel *ch = cs_to_sh_tmu(cs);289 290 if (!ch->cs_enabled)291 return;292 293 if (--ch->enable_count == 0) {294 __sh_tmu_disable(ch);295 dev_pm_genpd_suspend(&ch->tmu->pdev->dev);296 }297}298 299static void sh_tmu_clocksource_resume(struct clocksource *cs)300{301 struct sh_tmu_channel *ch = cs_to_sh_tmu(cs);302 303 if (!ch->cs_enabled)304 return;305 306 if (ch->enable_count++ == 0) {307 dev_pm_genpd_resume(&ch->tmu->pdev->dev);308 __sh_tmu_enable(ch);309 }310}311 312static int sh_tmu_register_clocksource(struct sh_tmu_channel *ch,313 const char *name)314{315 struct clocksource *cs = &ch->cs;316 317 cs->name = name;318 cs->rating = 200;319 cs->read = sh_tmu_clocksource_read;320 cs->enable = sh_tmu_clocksource_enable;321 cs->disable = sh_tmu_clocksource_disable;322 cs->suspend = sh_tmu_clocksource_suspend;323 cs->resume = sh_tmu_clocksource_resume;324 cs->mask = CLOCKSOURCE_MASK(32);325 cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;326 327 dev_info(&ch->tmu->pdev->dev, "ch%u: used as clock source\n",328 ch->index);329 330 clocksource_register_hz(cs, ch->tmu->rate);331 return 0;332}333 334static struct sh_tmu_channel *ced_to_sh_tmu(struct clock_event_device *ced)335{336 return container_of(ced, struct sh_tmu_channel, ced);337}338 339static void sh_tmu_clock_event_start(struct sh_tmu_channel *ch, int periodic)340{341 sh_tmu_enable(ch);342 343 if (periodic) {344 ch->periodic = (ch->tmu->rate + HZ/2) / HZ;345 sh_tmu_set_next(ch, ch->periodic, 1);346 }347}348 349static int sh_tmu_clock_event_shutdown(struct clock_event_device *ced)350{351 struct sh_tmu_channel *ch = ced_to_sh_tmu(ced);352 353 if (clockevent_state_oneshot(ced) || clockevent_state_periodic(ced))354 sh_tmu_disable(ch);355 return 0;356}357 358static int sh_tmu_clock_event_set_state(struct clock_event_device *ced,359 int periodic)360{361 struct sh_tmu_channel *ch = ced_to_sh_tmu(ced);362 363 /* deal with old setting first */364 if (clockevent_state_oneshot(ced) || clockevent_state_periodic(ced))365 sh_tmu_disable(ch);366 367 dev_info(&ch->tmu->pdev->dev, "ch%u: used for %s clock events\n",368 ch->index, periodic ? "periodic" : "oneshot");369 sh_tmu_clock_event_start(ch, periodic);370 return 0;371}372 373static int sh_tmu_clock_event_set_oneshot(struct clock_event_device *ced)374{375 return sh_tmu_clock_event_set_state(ced, 0);376}377 378static int sh_tmu_clock_event_set_periodic(struct clock_event_device *ced)379{380 return sh_tmu_clock_event_set_state(ced, 1);381}382 383static int sh_tmu_clock_event_next(unsigned long delta,384 struct clock_event_device *ced)385{386 struct sh_tmu_channel *ch = ced_to_sh_tmu(ced);387 388 BUG_ON(!clockevent_state_oneshot(ced));389 390 /* program new delta value */391 sh_tmu_set_next(ch, delta, 0);392 return 0;393}394 395static void sh_tmu_clock_event_suspend(struct clock_event_device *ced)396{397 dev_pm_genpd_suspend(&ced_to_sh_tmu(ced)->tmu->pdev->dev);398}399 400static void sh_tmu_clock_event_resume(struct clock_event_device *ced)401{402 dev_pm_genpd_resume(&ced_to_sh_tmu(ced)->tmu->pdev->dev);403}404 405static void sh_tmu_register_clockevent(struct sh_tmu_channel *ch,406 const char *name)407{408 struct clock_event_device *ced = &ch->ced;409 int ret;410 411 ced->name = name;412 ced->features = CLOCK_EVT_FEAT_PERIODIC;413 ced->features |= CLOCK_EVT_FEAT_ONESHOT;414 ced->rating = 200;415 ced->cpumask = cpu_possible_mask;416 ced->set_next_event = sh_tmu_clock_event_next;417 ced->set_state_shutdown = sh_tmu_clock_event_shutdown;418 ced->set_state_periodic = sh_tmu_clock_event_set_periodic;419 ced->set_state_oneshot = sh_tmu_clock_event_set_oneshot;420 ced->suspend = sh_tmu_clock_event_suspend;421 ced->resume = sh_tmu_clock_event_resume;422 423 dev_info(&ch->tmu->pdev->dev, "ch%u: used for clock events\n",424 ch->index);425 426 clockevents_config_and_register(ced, ch->tmu->rate, 0x300, 0xffffffff);427 428 ret = request_irq(ch->irq, sh_tmu_interrupt,429 IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,430 dev_name(&ch->tmu->pdev->dev), ch);431 if (ret) {432 dev_err(&ch->tmu->pdev->dev, "ch%u: failed to request irq %d\n",433 ch->index, ch->irq);434 return;435 }436}437 438static int sh_tmu_register(struct sh_tmu_channel *ch, const char *name,439 bool clockevent, bool clocksource)440{441 if (clockevent) {442 ch->tmu->has_clockevent = true;443 sh_tmu_register_clockevent(ch, name);444 } else if (clocksource) {445 ch->tmu->has_clocksource = true;446 sh_tmu_register_clocksource(ch, name);447 }448 449 return 0;450}451 452static int sh_tmu_channel_setup(struct sh_tmu_channel *ch, unsigned int index,453 bool clockevent, bool clocksource,454 struct sh_tmu_device *tmu)455{456 /* Skip unused channels. */457 if (!clockevent && !clocksource)458 return 0;459 460 ch->tmu = tmu;461 ch->index = index;462 463 if (tmu->model == SH_TMU_SH3)464 ch->base = tmu->mapbase + 4 + ch->index * 12;465 else466 ch->base = tmu->mapbase + 8 + ch->index * 12;467 468 ch->irq = platform_get_irq(tmu->pdev, index);469 if (ch->irq < 0)470 return ch->irq;471 472 ch->cs_enabled = false;473 ch->enable_count = 0;474 475 return sh_tmu_register(ch, dev_name(&tmu->pdev->dev),476 clockevent, clocksource);477}478 479static int sh_tmu_map_memory(struct sh_tmu_device *tmu)480{481 struct resource *res;482 483 res = platform_get_resource(tmu->pdev, IORESOURCE_MEM, 0);484 if (!res) {485 dev_err(&tmu->pdev->dev, "failed to get I/O memory\n");486 return -ENXIO;487 }488 489 tmu->mapbase = ioremap(res->start, resource_size(res));490 if (tmu->mapbase == NULL)491 return -ENXIO;492 493 return 0;494}495 496static int sh_tmu_parse_dt(struct sh_tmu_device *tmu)497{498 struct device_node *np = tmu->pdev->dev.of_node;499 500 tmu->model = SH_TMU;501 tmu->num_channels = 3;502 503 of_property_read_u32(np, "#renesas,channels", &tmu->num_channels);504 505 if (tmu->num_channels != 2 && tmu->num_channels != 3) {506 dev_err(&tmu->pdev->dev, "invalid number of channels %u\n",507 tmu->num_channels);508 return -EINVAL;509 }510 511 return 0;512}513 514static int sh_tmu_setup(struct sh_tmu_device *tmu, struct platform_device *pdev)515{516 unsigned int i;517 int ret;518 519 tmu->pdev = pdev;520 521 raw_spin_lock_init(&tmu->lock);522 523 if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {524 ret = sh_tmu_parse_dt(tmu);525 if (ret < 0)526 return ret;527 } else if (pdev->dev.platform_data) {528 const struct platform_device_id *id = pdev->id_entry;529 struct sh_timer_config *cfg = pdev->dev.platform_data;530 531 tmu->model = id->driver_data;532 tmu->num_channels = hweight8(cfg->channels_mask);533 } else {534 dev_err(&tmu->pdev->dev, "missing platform data\n");535 return -ENXIO;536 }537 538 /* Get hold of clock. */539 tmu->clk = clk_get(&tmu->pdev->dev, "fck");540 if (IS_ERR(tmu->clk)) {541 dev_err(&tmu->pdev->dev, "cannot get clock\n");542 return PTR_ERR(tmu->clk);543 }544 545 ret = clk_prepare(tmu->clk);546 if (ret < 0)547 goto err_clk_put;548 549 /* Determine clock rate. */550 ret = clk_enable(tmu->clk);551 if (ret < 0)552 goto err_clk_unprepare;553 554 tmu->rate = clk_get_rate(tmu->clk) / 4;555 clk_disable(tmu->clk);556 557 /* Map the memory resource. */558 ret = sh_tmu_map_memory(tmu);559 if (ret < 0) {560 dev_err(&tmu->pdev->dev, "failed to remap I/O memory\n");561 goto err_clk_unprepare;562 }563 564 /* Allocate and setup the channels. */565 tmu->channels = kcalloc(tmu->num_channels, sizeof(*tmu->channels),566 GFP_KERNEL);567 if (tmu->channels == NULL) {568 ret = -ENOMEM;569 goto err_unmap;570 }571 572 /*573 * Use the first channel as a clock event device and the second channel574 * as a clock source.575 */576 for (i = 0; i < tmu->num_channels; ++i) {577 ret = sh_tmu_channel_setup(&tmu->channels[i], i,578 i == 0, i == 1, tmu);579 if (ret < 0)580 goto err_unmap;581 }582 583 platform_set_drvdata(pdev, tmu);584 585 return 0;586 587err_unmap:588 kfree(tmu->channels);589 iounmap(tmu->mapbase);590err_clk_unprepare:591 clk_unprepare(tmu->clk);592err_clk_put:593 clk_put(tmu->clk);594 return ret;595}596 597static int sh_tmu_probe(struct platform_device *pdev)598{599 struct sh_tmu_device *tmu = platform_get_drvdata(pdev);600 int ret;601 602 if (!is_sh_early_platform_device(pdev)) {603 pm_runtime_set_active(&pdev->dev);604 pm_runtime_enable(&pdev->dev);605 }606 607 if (tmu) {608 dev_info(&pdev->dev, "kept as earlytimer\n");609 goto out;610 }611 612 tmu = kzalloc(sizeof(*tmu), GFP_KERNEL);613 if (tmu == NULL)614 return -ENOMEM;615 616 ret = sh_tmu_setup(tmu, pdev);617 if (ret) {618 kfree(tmu);619 pm_runtime_idle(&pdev->dev);620 return ret;621 }622 623 if (is_sh_early_platform_device(pdev))624 return 0;625 626 out:627 if (tmu->has_clockevent || tmu->has_clocksource)628 pm_runtime_irq_safe(&pdev->dev);629 else630 pm_runtime_idle(&pdev->dev);631 632 return 0;633}634 635static const struct platform_device_id sh_tmu_id_table[] = {636 { "sh-tmu", SH_TMU },637 { "sh-tmu-sh3", SH_TMU_SH3 },638 { }639};640MODULE_DEVICE_TABLE(platform, sh_tmu_id_table);641 642static const struct of_device_id sh_tmu_of_table[] __maybe_unused = {643 { .compatible = "renesas,tmu" },644 { }645};646MODULE_DEVICE_TABLE(of, sh_tmu_of_table);647 648static struct platform_driver sh_tmu_device_driver = {649 .probe = sh_tmu_probe,650 .driver = {651 .name = "sh_tmu",652 .of_match_table = of_match_ptr(sh_tmu_of_table),653 .suppress_bind_attrs = true,654 },655 .id_table = sh_tmu_id_table,656};657 658static int __init sh_tmu_init(void)659{660 return platform_driver_register(&sh_tmu_device_driver);661}662 663static void __exit sh_tmu_exit(void)664{665 platform_driver_unregister(&sh_tmu_device_driver);666}667 668#ifdef CONFIG_SUPERH669sh_early_platform_init("earlytimer", &sh_tmu_device_driver);670#endif671 672subsys_initcall(sh_tmu_init);673module_exit(sh_tmu_exit);674 675MODULE_AUTHOR("Magnus Damm");676MODULE_DESCRIPTION("SuperH TMU Timer Driver");677