Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Allwinner SoCs hstimer driver.
0004  *
0005  * Copyright (C) 2013 Maxime Ripard
0006  *
0007  * Maxime Ripard <maxime.ripard@free-electrons.com>
0008  */
0009 
0010 #include <linux/clk.h>
0011 #include <linux/clockchips.h>
0012 #include <linux/clocksource.h>
0013 #include <linux/delay.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/irq.h>
0016 #include <linux/irqreturn.h>
0017 #include <linux/reset.h>
0018 #include <linux/slab.h>
0019 #include <linux/of.h>
0020 #include <linux/of_address.h>
0021 #include <linux/of_irq.h>
0022 
0023 #define TIMER_IRQ_EN_REG        0x00
0024 #define TIMER_IRQ_EN(val)           BIT(val)
0025 #define TIMER_IRQ_ST_REG        0x04
0026 #define TIMER_CTL_REG(val)      (0x20 * (val) + 0x10)
0027 #define TIMER_CTL_ENABLE            BIT(0)
0028 #define TIMER_CTL_RELOAD            BIT(1)
0029 #define TIMER_CTL_CLK_PRES(val)         (((val) & 0x7) << 4)
0030 #define TIMER_CTL_ONESHOT           BIT(7)
0031 #define TIMER_INTVAL_LO_REG(val)    (0x20 * (val) + 0x14)
0032 #define TIMER_INTVAL_HI_REG(val)    (0x20 * (val) + 0x18)
0033 #define TIMER_CNTVAL_LO_REG(val)    (0x20 * (val) + 0x1c)
0034 #define TIMER_CNTVAL_HI_REG(val)    (0x20 * (val) + 0x20)
0035 
0036 #define TIMER_SYNC_TICKS    3
0037 
0038 struct sun5i_timer {
0039     void __iomem        *base;
0040     struct clk      *clk;
0041     struct notifier_block   clk_rate_cb;
0042     u32         ticks_per_jiffy;
0043 };
0044 
0045 #define to_sun5i_timer(x) \
0046     container_of(x, struct sun5i_timer, clk_rate_cb)
0047 
0048 struct sun5i_timer_clksrc {
0049     struct sun5i_timer  timer;
0050     struct clocksource  clksrc;
0051 };
0052 
0053 #define to_sun5i_timer_clksrc(x) \
0054     container_of(x, struct sun5i_timer_clksrc, clksrc)
0055 
0056 struct sun5i_timer_clkevt {
0057     struct sun5i_timer      timer;
0058     struct clock_event_device   clkevt;
0059 };
0060 
0061 #define to_sun5i_timer_clkevt(x) \
0062     container_of(x, struct sun5i_timer_clkevt, clkevt)
0063 
0064 /*
0065  * When we disable a timer, we need to wait at least for 2 cycles of
0066  * the timer source clock. We will use for that the clocksource timer
0067  * that is already setup and runs at the same frequency than the other
0068  * timers, and we never will be disabled.
0069  */
0070 static void sun5i_clkevt_sync(struct sun5i_timer_clkevt *ce)
0071 {
0072     u32 old = readl(ce->timer.base + TIMER_CNTVAL_LO_REG(1));
0073 
0074     while ((old - readl(ce->timer.base + TIMER_CNTVAL_LO_REG(1))) < TIMER_SYNC_TICKS)
0075         cpu_relax();
0076 }
0077 
0078 static void sun5i_clkevt_time_stop(struct sun5i_timer_clkevt *ce, u8 timer)
0079 {
0080     u32 val = readl(ce->timer.base + TIMER_CTL_REG(timer));
0081     writel(val & ~TIMER_CTL_ENABLE, ce->timer.base + TIMER_CTL_REG(timer));
0082 
0083     sun5i_clkevt_sync(ce);
0084 }
0085 
0086 static void sun5i_clkevt_time_setup(struct sun5i_timer_clkevt *ce, u8 timer, u32 delay)
0087 {
0088     writel(delay, ce->timer.base + TIMER_INTVAL_LO_REG(timer));
0089 }
0090 
0091 static void sun5i_clkevt_time_start(struct sun5i_timer_clkevt *ce, u8 timer, bool periodic)
0092 {
0093     u32 val = readl(ce->timer.base + TIMER_CTL_REG(timer));
0094 
0095     if (periodic)
0096         val &= ~TIMER_CTL_ONESHOT;
0097     else
0098         val |= TIMER_CTL_ONESHOT;
0099 
0100     writel(val | TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
0101            ce->timer.base + TIMER_CTL_REG(timer));
0102 }
0103 
0104 static int sun5i_clkevt_shutdown(struct clock_event_device *clkevt)
0105 {
0106     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
0107 
0108     sun5i_clkevt_time_stop(ce, 0);
0109     return 0;
0110 }
0111 
0112 static int sun5i_clkevt_set_oneshot(struct clock_event_device *clkevt)
0113 {
0114     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
0115 
0116     sun5i_clkevt_time_stop(ce, 0);
0117     sun5i_clkevt_time_start(ce, 0, false);
0118     return 0;
0119 }
0120 
0121 static int sun5i_clkevt_set_periodic(struct clock_event_device *clkevt)
0122 {
0123     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
0124 
0125     sun5i_clkevt_time_stop(ce, 0);
0126     sun5i_clkevt_time_setup(ce, 0, ce->timer.ticks_per_jiffy);
0127     sun5i_clkevt_time_start(ce, 0, true);
0128     return 0;
0129 }
0130 
0131 static int sun5i_clkevt_next_event(unsigned long evt,
0132                    struct clock_event_device *clkevt)
0133 {
0134     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
0135 
0136     sun5i_clkevt_time_stop(ce, 0);
0137     sun5i_clkevt_time_setup(ce, 0, evt - TIMER_SYNC_TICKS);
0138     sun5i_clkevt_time_start(ce, 0, false);
0139 
0140     return 0;
0141 }
0142 
0143 static irqreturn_t sun5i_timer_interrupt(int irq, void *dev_id)
0144 {
0145     struct sun5i_timer_clkevt *ce = dev_id;
0146 
0147     writel(0x1, ce->timer.base + TIMER_IRQ_ST_REG);
0148     ce->clkevt.event_handler(&ce->clkevt);
0149 
0150     return IRQ_HANDLED;
0151 }
0152 
0153 static u64 sun5i_clksrc_read(struct clocksource *clksrc)
0154 {
0155     struct sun5i_timer_clksrc *cs = to_sun5i_timer_clksrc(clksrc);
0156 
0157     return ~readl(cs->timer.base + TIMER_CNTVAL_LO_REG(1));
0158 }
0159 
0160 static int sun5i_rate_cb_clksrc(struct notifier_block *nb,
0161                 unsigned long event, void *data)
0162 {
0163     struct clk_notifier_data *ndata = data;
0164     struct sun5i_timer *timer = to_sun5i_timer(nb);
0165     struct sun5i_timer_clksrc *cs = container_of(timer, struct sun5i_timer_clksrc, timer);
0166 
0167     switch (event) {
0168     case PRE_RATE_CHANGE:
0169         clocksource_unregister(&cs->clksrc);
0170         break;
0171 
0172     case POST_RATE_CHANGE:
0173         clocksource_register_hz(&cs->clksrc, ndata->new_rate);
0174         break;
0175 
0176     default:
0177         break;
0178     }
0179 
0180     return NOTIFY_DONE;
0181 }
0182 
0183 static int __init sun5i_setup_clocksource(struct device_node *node,
0184                       void __iomem *base,
0185                       struct clk *clk, int irq)
0186 {
0187     struct sun5i_timer_clksrc *cs;
0188     unsigned long rate;
0189     int ret;
0190 
0191     cs = kzalloc(sizeof(*cs), GFP_KERNEL);
0192     if (!cs)
0193         return -ENOMEM;
0194 
0195     ret = clk_prepare_enable(clk);
0196     if (ret) {
0197         pr_err("Couldn't enable parent clock\n");
0198         goto err_free;
0199     }
0200 
0201     rate = clk_get_rate(clk);
0202     if (!rate) {
0203         pr_err("Couldn't get parent clock rate\n");
0204         ret = -EINVAL;
0205         goto err_disable_clk;
0206     }
0207 
0208     cs->timer.base = base;
0209     cs->timer.clk = clk;
0210     cs->timer.clk_rate_cb.notifier_call = sun5i_rate_cb_clksrc;
0211     cs->timer.clk_rate_cb.next = NULL;
0212 
0213     ret = clk_notifier_register(clk, &cs->timer.clk_rate_cb);
0214     if (ret) {
0215         pr_err("Unable to register clock notifier.\n");
0216         goto err_disable_clk;
0217     }
0218 
0219     writel(~0, base + TIMER_INTVAL_LO_REG(1));
0220     writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
0221            base + TIMER_CTL_REG(1));
0222 
0223     cs->clksrc.name = node->name;
0224     cs->clksrc.rating = 340;
0225     cs->clksrc.read = sun5i_clksrc_read;
0226     cs->clksrc.mask = CLOCKSOURCE_MASK(32);
0227     cs->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
0228 
0229     ret = clocksource_register_hz(&cs->clksrc, rate);
0230     if (ret) {
0231         pr_err("Couldn't register clock source.\n");
0232         goto err_remove_notifier;
0233     }
0234 
0235     return 0;
0236 
0237 err_remove_notifier:
0238     clk_notifier_unregister(clk, &cs->timer.clk_rate_cb);
0239 err_disable_clk:
0240     clk_disable_unprepare(clk);
0241 err_free:
0242     kfree(cs);
0243     return ret;
0244 }
0245 
0246 static int sun5i_rate_cb_clkevt(struct notifier_block *nb,
0247                 unsigned long event, void *data)
0248 {
0249     struct clk_notifier_data *ndata = data;
0250     struct sun5i_timer *timer = to_sun5i_timer(nb);
0251     struct sun5i_timer_clkevt *ce = container_of(timer, struct sun5i_timer_clkevt, timer);
0252 
0253     if (event == POST_RATE_CHANGE) {
0254         clockevents_update_freq(&ce->clkevt, ndata->new_rate);
0255         ce->timer.ticks_per_jiffy = DIV_ROUND_UP(ndata->new_rate, HZ);
0256     }
0257 
0258     return NOTIFY_DONE;
0259 }
0260 
0261 static int __init sun5i_setup_clockevent(struct device_node *node, void __iomem *base,
0262                      struct clk *clk, int irq)
0263 {
0264     struct sun5i_timer_clkevt *ce;
0265     unsigned long rate;
0266     int ret;
0267     u32 val;
0268 
0269     ce = kzalloc(sizeof(*ce), GFP_KERNEL);
0270     if (!ce)
0271         return -ENOMEM;
0272 
0273     ret = clk_prepare_enable(clk);
0274     if (ret) {
0275         pr_err("Couldn't enable parent clock\n");
0276         goto err_free;
0277     }
0278 
0279     rate = clk_get_rate(clk);
0280     if (!rate) {
0281         pr_err("Couldn't get parent clock rate\n");
0282         ret = -EINVAL;
0283         goto err_disable_clk;
0284     }
0285 
0286     ce->timer.base = base;
0287     ce->timer.ticks_per_jiffy = DIV_ROUND_UP(rate, HZ);
0288     ce->timer.clk = clk;
0289     ce->timer.clk_rate_cb.notifier_call = sun5i_rate_cb_clkevt;
0290     ce->timer.clk_rate_cb.next = NULL;
0291 
0292     ret = clk_notifier_register(clk, &ce->timer.clk_rate_cb);
0293     if (ret) {
0294         pr_err("Unable to register clock notifier.\n");
0295         goto err_disable_clk;
0296     }
0297 
0298     ce->clkevt.name = node->name;
0299     ce->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
0300     ce->clkevt.set_next_event = sun5i_clkevt_next_event;
0301     ce->clkevt.set_state_shutdown = sun5i_clkevt_shutdown;
0302     ce->clkevt.set_state_periodic = sun5i_clkevt_set_periodic;
0303     ce->clkevt.set_state_oneshot = sun5i_clkevt_set_oneshot;
0304     ce->clkevt.tick_resume = sun5i_clkevt_shutdown;
0305     ce->clkevt.rating = 340;
0306     ce->clkevt.irq = irq;
0307     ce->clkevt.cpumask = cpu_possible_mask;
0308 
0309     /* Enable timer0 interrupt */
0310     val = readl(base + TIMER_IRQ_EN_REG);
0311     writel(val | TIMER_IRQ_EN(0), base + TIMER_IRQ_EN_REG);
0312 
0313     clockevents_config_and_register(&ce->clkevt, rate,
0314                     TIMER_SYNC_TICKS, 0xffffffff);
0315 
0316     ret = request_irq(irq, sun5i_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
0317               "sun5i_timer0", ce);
0318     if (ret) {
0319         pr_err("Unable to register interrupt\n");
0320         goto err_remove_notifier;
0321     }
0322 
0323     return 0;
0324 
0325 err_remove_notifier:
0326     clk_notifier_unregister(clk, &ce->timer.clk_rate_cb);
0327 err_disable_clk:
0328     clk_disable_unprepare(clk);
0329 err_free:
0330     kfree(ce);
0331     return ret;
0332 }
0333 
0334 static int __init sun5i_timer_init(struct device_node *node)
0335 {
0336     struct reset_control *rstc;
0337     void __iomem *timer_base;
0338     struct clk *clk;
0339     int irq, ret;
0340 
0341     timer_base = of_io_request_and_map(node, 0, of_node_full_name(node));
0342     if (IS_ERR(timer_base)) {
0343         pr_err("Can't map registers\n");
0344         return PTR_ERR(timer_base);
0345     }
0346 
0347     irq = irq_of_parse_and_map(node, 0);
0348     if (irq <= 0) {
0349         pr_err("Can't parse IRQ\n");
0350         return -EINVAL;
0351     }
0352 
0353     clk = of_clk_get(node, 0);
0354     if (IS_ERR(clk)) {
0355         pr_err("Can't get timer clock\n");
0356         return PTR_ERR(clk);
0357     }
0358 
0359     rstc = of_reset_control_get(node, NULL);
0360     if (!IS_ERR(rstc))
0361         reset_control_deassert(rstc);
0362 
0363     ret = sun5i_setup_clocksource(node, timer_base, clk, irq);
0364     if (ret)
0365         return ret;
0366 
0367     return sun5i_setup_clockevent(node, timer_base, clk, irq);
0368 }
0369 TIMER_OF_DECLARE(sun5i_a13, "allwinner,sun5i-a13-hstimer",
0370                sun5i_timer_init);
0371 TIMER_OF_DECLARE(sun7i_a20, "allwinner,sun7i-a20-hstimer",
0372                sun5i_timer_init);