1 /* 2 * Allwinner SoCs hstimer driver. 3 * 4 * Copyright (C) 2013 Maxime Ripard 5 * 6 * Maxime Ripard <maxime.ripard@free-electrons.com> 7 * 8 * This file is licensed under the terms of the GNU General Public 9 * License version 2. This program is licensed "as is" without any 10 * warranty of any kind, whether express or implied. 11 */ 12 13 #include <linux/clk.h> 14 #include <linux/clockchips.h> 15 #include <linux/clocksource.h> 16 #include <linux/delay.h> 17 #include <linux/interrupt.h> 18 #include <linux/irq.h> 19 #include <linux/irqreturn.h> 20 #include <linux/reset.h> 21 #include <linux/slab.h> 22 #include <linux/of.h> 23 #include <linux/of_address.h> 24 #include <linux/of_irq.h> 25 26 #define TIMER_IRQ_EN_REG 0x00 27 #define TIMER_IRQ_EN(val) BIT(val) 28 #define TIMER_IRQ_ST_REG 0x04 29 #define TIMER_CTL_REG(val) (0x20 * (val) + 0x10) 30 #define TIMER_CTL_ENABLE BIT(0) 31 #define TIMER_CTL_RELOAD BIT(1) 32 #define TIMER_CTL_CLK_PRES(val) (((val) & 0x7) << 4) 33 #define TIMER_CTL_ONESHOT BIT(7) 34 #define TIMER_INTVAL_LO_REG(val) (0x20 * (val) + 0x14) 35 #define TIMER_INTVAL_HI_REG(val) (0x20 * (val) + 0x18) 36 #define TIMER_CNTVAL_LO_REG(val) (0x20 * (val) + 0x1c) 37 #define TIMER_CNTVAL_HI_REG(val) (0x20 * (val) + 0x20) 38 39 #define TIMER_SYNC_TICKS 3 40 41 struct sun5i_timer { 42 void __iomem *base; 43 struct clk *clk; 44 struct notifier_block clk_rate_cb; 45 u32 ticks_per_jiffy; 46 }; 47 48 #define to_sun5i_timer(x) \ 49 container_of(x, struct sun5i_timer, clk_rate_cb) 50 51 struct sun5i_timer_clksrc { 52 struct sun5i_timer timer; 53 struct clocksource clksrc; 54 }; 55 56 #define to_sun5i_timer_clksrc(x) \ 57 container_of(x, struct sun5i_timer_clksrc, clksrc) 58 59 struct sun5i_timer_clkevt { 60 struct sun5i_timer timer; 61 struct clock_event_device clkevt; 62 }; 63 64 #define to_sun5i_timer_clkevt(x) \ 65 container_of(x, struct sun5i_timer_clkevt, clkevt) 66 67 /* 68 * When we disable a timer, we need to wait at least for 2 cycles of 69 * the timer source clock. We will use for that the clocksource timer 70 * that is already setup and runs at the same frequency than the other 71 * timers, and we never will be disabled. 72 */ 73 static void sun5i_clkevt_sync(struct sun5i_timer_clkevt *ce) 74 { 75 u32 old = readl(ce->timer.base + TIMER_CNTVAL_LO_REG(1)); 76 77 while ((old - readl(ce->timer.base + TIMER_CNTVAL_LO_REG(1))) < TIMER_SYNC_TICKS) 78 cpu_relax(); 79 } 80 81 static void sun5i_clkevt_time_stop(struct sun5i_timer_clkevt *ce, u8 timer) 82 { 83 u32 val = readl(ce->timer.base + TIMER_CTL_REG(timer)); 84 writel(val & ~TIMER_CTL_ENABLE, ce->timer.base + TIMER_CTL_REG(timer)); 85 86 sun5i_clkevt_sync(ce); 87 } 88 89 static void sun5i_clkevt_time_setup(struct sun5i_timer_clkevt *ce, u8 timer, u32 delay) 90 { 91 writel(delay, ce->timer.base + TIMER_INTVAL_LO_REG(timer)); 92 } 93 94 static void sun5i_clkevt_time_start(struct sun5i_timer_clkevt *ce, u8 timer, bool periodic) 95 { 96 u32 val = readl(ce->timer.base + TIMER_CTL_REG(timer)); 97 98 if (periodic) 99 val &= ~TIMER_CTL_ONESHOT; 100 else 101 val |= TIMER_CTL_ONESHOT; 102 103 writel(val | TIMER_CTL_ENABLE | TIMER_CTL_RELOAD, 104 ce->timer.base + TIMER_CTL_REG(timer)); 105 } 106 107 static int sun5i_clkevt_shutdown(struct clock_event_device *clkevt) 108 { 109 struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt); 110 111 sun5i_clkevt_time_stop(ce, 0); 112 return 0; 113 } 114 115 static int sun5i_clkevt_set_oneshot(struct clock_event_device *clkevt) 116 { 117 struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt); 118 119 sun5i_clkevt_time_stop(ce, 0); 120 sun5i_clkevt_time_start(ce, 0, false); 121 return 0; 122 } 123 124 static int sun5i_clkevt_set_periodic(struct clock_event_device *clkevt) 125 { 126 struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt); 127 128 sun5i_clkevt_time_stop(ce, 0); 129 sun5i_clkevt_time_setup(ce, 0, ce->timer.ticks_per_jiffy); 130 sun5i_clkevt_time_start(ce, 0, true); 131 return 0; 132 } 133 134 static int sun5i_clkevt_next_event(unsigned long evt, 135 struct clock_event_device *clkevt) 136 { 137 struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt); 138 139 sun5i_clkevt_time_stop(ce, 0); 140 sun5i_clkevt_time_setup(ce, 0, evt - TIMER_SYNC_TICKS); 141 sun5i_clkevt_time_start(ce, 0, false); 142 143 return 0; 144 } 145 146 static irqreturn_t sun5i_timer_interrupt(int irq, void *dev_id) 147 { 148 struct sun5i_timer_clkevt *ce = (struct sun5i_timer_clkevt *)dev_id; 149 150 writel(0x1, ce->timer.base + TIMER_IRQ_ST_REG); 151 ce->clkevt.event_handler(&ce->clkevt); 152 153 return IRQ_HANDLED; 154 } 155 156 static u64 sun5i_clksrc_read(struct clocksource *clksrc) 157 { 158 struct sun5i_timer_clksrc *cs = to_sun5i_timer_clksrc(clksrc); 159 160 return ~readl(cs->timer.base + TIMER_CNTVAL_LO_REG(1)); 161 } 162 163 static int sun5i_rate_cb_clksrc(struct notifier_block *nb, 164 unsigned long event, void *data) 165 { 166 struct clk_notifier_data *ndata = data; 167 struct sun5i_timer *timer = to_sun5i_timer(nb); 168 struct sun5i_timer_clksrc *cs = container_of(timer, struct sun5i_timer_clksrc, timer); 169 170 switch (event) { 171 case PRE_RATE_CHANGE: 172 clocksource_unregister(&cs->clksrc); 173 break; 174 175 case POST_RATE_CHANGE: 176 clocksource_register_hz(&cs->clksrc, ndata->new_rate); 177 break; 178 179 default: 180 break; 181 } 182 183 return NOTIFY_DONE; 184 } 185 186 static int __init sun5i_setup_clocksource(struct device_node *node, 187 void __iomem *base, 188 struct clk *clk, int irq) 189 { 190 struct sun5i_timer_clksrc *cs; 191 unsigned long rate; 192 int ret; 193 194 cs = kzalloc(sizeof(*cs), GFP_KERNEL); 195 if (!cs) 196 return -ENOMEM; 197 198 ret = clk_prepare_enable(clk); 199 if (ret) { 200 pr_err("Couldn't enable parent clock\n"); 201 goto err_free; 202 } 203 204 rate = clk_get_rate(clk); 205 if (!rate) { 206 pr_err("Couldn't get parent clock rate\n"); 207 ret = -EINVAL; 208 goto err_disable_clk; 209 } 210 211 cs->timer.base = base; 212 cs->timer.clk = clk; 213 cs->timer.clk_rate_cb.notifier_call = sun5i_rate_cb_clksrc; 214 cs->timer.clk_rate_cb.next = NULL; 215 216 ret = clk_notifier_register(clk, &cs->timer.clk_rate_cb); 217 if (ret) { 218 pr_err("Unable to register clock notifier.\n"); 219 goto err_disable_clk; 220 } 221 222 writel(~0, base + TIMER_INTVAL_LO_REG(1)); 223 writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD, 224 base + TIMER_CTL_REG(1)); 225 226 cs->clksrc.name = node->name; 227 cs->clksrc.rating = 340; 228 cs->clksrc.read = sun5i_clksrc_read; 229 cs->clksrc.mask = CLOCKSOURCE_MASK(32); 230 cs->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS; 231 232 ret = clocksource_register_hz(&cs->clksrc, rate); 233 if (ret) { 234 pr_err("Couldn't register clock source.\n"); 235 goto err_remove_notifier; 236 } 237 238 return 0; 239 240 err_remove_notifier: 241 clk_notifier_unregister(clk, &cs->timer.clk_rate_cb); 242 err_disable_clk: 243 clk_disable_unprepare(clk); 244 err_free: 245 kfree(cs); 246 return ret; 247 } 248 249 static int sun5i_rate_cb_clkevt(struct notifier_block *nb, 250 unsigned long event, void *data) 251 { 252 struct clk_notifier_data *ndata = data; 253 struct sun5i_timer *timer = to_sun5i_timer(nb); 254 struct sun5i_timer_clkevt *ce = container_of(timer, struct sun5i_timer_clkevt, timer); 255 256 if (event == POST_RATE_CHANGE) { 257 clockevents_update_freq(&ce->clkevt, ndata->new_rate); 258 ce->timer.ticks_per_jiffy = DIV_ROUND_UP(ndata->new_rate, HZ); 259 } 260 261 return NOTIFY_DONE; 262 } 263 264 static int __init sun5i_setup_clockevent(struct device_node *node, void __iomem *base, 265 struct clk *clk, int irq) 266 { 267 struct sun5i_timer_clkevt *ce; 268 unsigned long rate; 269 int ret; 270 u32 val; 271 272 ce = kzalloc(sizeof(*ce), GFP_KERNEL); 273 if (!ce) 274 return -ENOMEM; 275 276 ret = clk_prepare_enable(clk); 277 if (ret) { 278 pr_err("Couldn't enable parent clock\n"); 279 goto err_free; 280 } 281 282 rate = clk_get_rate(clk); 283 if (!rate) { 284 pr_err("Couldn't get parent clock rate\n"); 285 ret = -EINVAL; 286 goto err_disable_clk; 287 } 288 289 ce->timer.base = base; 290 ce->timer.ticks_per_jiffy = DIV_ROUND_UP(rate, HZ); 291 ce->timer.clk = clk; 292 ce->timer.clk_rate_cb.notifier_call = sun5i_rate_cb_clkevt; 293 ce->timer.clk_rate_cb.next = NULL; 294 295 ret = clk_notifier_register(clk, &ce->timer.clk_rate_cb); 296 if (ret) { 297 pr_err("Unable to register clock notifier.\n"); 298 goto err_disable_clk; 299 } 300 301 ce->clkevt.name = node->name; 302 ce->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 303 ce->clkevt.set_next_event = sun5i_clkevt_next_event; 304 ce->clkevt.set_state_shutdown = sun5i_clkevt_shutdown; 305 ce->clkevt.set_state_periodic = sun5i_clkevt_set_periodic; 306 ce->clkevt.set_state_oneshot = sun5i_clkevt_set_oneshot; 307 ce->clkevt.tick_resume = sun5i_clkevt_shutdown; 308 ce->clkevt.rating = 340; 309 ce->clkevt.irq = irq; 310 ce->clkevt.cpumask = cpu_possible_mask; 311 312 /* Enable timer0 interrupt */ 313 val = readl(base + TIMER_IRQ_EN_REG); 314 writel(val | TIMER_IRQ_EN(0), base + TIMER_IRQ_EN_REG); 315 316 clockevents_config_and_register(&ce->clkevt, rate, 317 TIMER_SYNC_TICKS, 0xffffffff); 318 319 ret = request_irq(irq, sun5i_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL, 320 "sun5i_timer0", ce); 321 if (ret) { 322 pr_err("Unable to register interrupt\n"); 323 goto err_remove_notifier; 324 } 325 326 return 0; 327 328 err_remove_notifier: 329 clk_notifier_unregister(clk, &ce->timer.clk_rate_cb); 330 err_disable_clk: 331 clk_disable_unprepare(clk); 332 err_free: 333 kfree(ce); 334 return ret; 335 } 336 337 static int __init sun5i_timer_init(struct device_node *node) 338 { 339 struct reset_control *rstc; 340 void __iomem *timer_base; 341 struct clk *clk; 342 int irq, ret; 343 344 timer_base = of_io_request_and_map(node, 0, of_node_full_name(node)); 345 if (IS_ERR(timer_base)) { 346 pr_err("Can't map registers\n"); 347 return PTR_ERR(timer_base); 348 } 349 350 irq = irq_of_parse_and_map(node, 0); 351 if (irq <= 0) { 352 pr_err("Can't parse IRQ\n"); 353 return -EINVAL; 354 } 355 356 clk = of_clk_get(node, 0); 357 if (IS_ERR(clk)) { 358 pr_err("Can't get timer clock\n"); 359 return PTR_ERR(clk); 360 } 361 362 rstc = of_reset_control_get(node, NULL); 363 if (!IS_ERR(rstc)) 364 reset_control_deassert(rstc); 365 366 ret = sun5i_setup_clocksource(node, timer_base, clk, irq); 367 if (ret) 368 return ret; 369 370 return sun5i_setup_clockevent(node, timer_base, clk, irq); 371 } 372 TIMER_OF_DECLARE(sun5i_a13, "allwinner,sun5i-a13-hstimer", 373 sun5i_timer_init); 374 TIMER_OF_DECLARE(sun7i_a20, "allwinner,sun7i-a20-hstimer", 375 sun5i_timer_init); 376